summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cvsignore33
-rw-r--r--CHANGES.txt2406
-rw-r--r--CREDITS.txt26
-rw-r--r--ENCRYPTION.txt138
-rw-r--r--INSTALL.txt190
-rw-r--r--LICENSE.html957
-rw-r--r--LICENSE.txt861
-rw-r--r--Makedefs.in183
-rw-r--r--Makefile170
-rw-r--r--README.txt288
-rw-r--r--backend/.cvsignore7
-rw-r--r--backend/Dependencies15
-rw-r--r--backend/Makefile155
-rw-r--r--backend/betest.c87
-rw-r--r--backend/ipp.c892
-rw-r--r--backend/lpd.c895
-rw-r--r--backend/parallel.c662
-rw-r--r--backend/scsi-irix.c211
-rw-r--r--backend/scsi-linux.c228
-rw-r--r--backend/scsi.c206
-rw-r--r--backend/serial.c894
-rw-r--r--backend/socket.c353
-rw-r--r--backend/usb.c653
-rw-r--r--berkeley/.cvsignore4
-rw-r--r--berkeley/Dependencies11
-rw-r--r--berkeley/Makefile112
-rw-r--r--berkeley/lpc.c482
-rw-r--r--berkeley/lpq.c538
-rw-r--r--berkeley/lpr.c430
-rw-r--r--berkeley/lprm.c267
-rw-r--r--cgi-bin/.cvsignore5
-rw-r--r--cgi-bin/Dependencies20
-rw-r--r--cgi-bin/Makefile123
-rw-r--r--cgi-bin/admin.c1533
-rw-r--r--cgi-bin/cgi.h86
-rw-r--r--cgi-bin/classes.c360
-rw-r--r--cgi-bin/html.c89
-rw-r--r--cgi-bin/ipp-var.c300
-rw-r--r--cgi-bin/ipp-var.h55
-rw-r--r--cgi-bin/jobs.c260
-rw-r--r--cgi-bin/printers.c360
-rw-r--r--cgi-bin/template.c492
-rw-r--r--cgi-bin/var.c672
-rw-r--r--conf/Makefile76
-rw-r--r--conf/classes.conf89
-rw-r--r--conf/client.conf65
-rw-r--r--conf/cupsd.conf.in765
-rw-r--r--conf/mime.convs116
-rw-r--r--conf/mime.types157
-rw-r--r--conf/pam.conf.in2
-rw-r--r--conf/pam.irix3
-rw-r--r--conf/printcap2
-rw-r--r--conf/printers.conf96
-rw-r--r--config-scripts/cups-common.m4162
-rw-r--r--config-scripts/cups-compiler.m4194
-rw-r--r--config-scripts/cups-directories.m4238
-rw-r--r--config-scripts/cups-image.m482
-rw-r--r--config-scripts/cups-libtool.m449
-rw-r--r--config-scripts/cups-manpages.m4104
-rw-r--r--config-scripts/cups-network.m441
-rw-r--r--config-scripts/cups-openslp.m448
-rw-r--r--config-scripts/cups-openssl.m474
-rw-r--r--config-scripts/cups-opsys.m490
-rw-r--r--config-scripts/cups-pam.m471
-rw-r--r--config-scripts/cups-sharedlibs.m4149
-rw-r--r--config.h.in240
-rw-r--r--configure.in48
-rwxr-xr-xcups-config.in134
-rw-r--r--cups.dsw29
-rw-r--r--cups.list.in465
-rw-r--r--cups.plist7
-rwxr-xr-xcups.sh.in211
-rw-r--r--cups.spec207
-rw-r--r--cups.strings9
-rw-r--r--cups/.cvsignore11
-rw-r--r--cups/Dependencies26
-rw-r--r--cups/Makefile216
-rw-r--r--cups/cups.dsp188
-rw-r--r--cups/cups.h177
-rw-r--r--cups/cups_C.h135
-rw-r--r--cups/debug.h59
-rw-r--r--cups/dest.c798
-rw-r--r--cups/emit.c548
-rw-r--r--cups/encode.c383
-rw-r--r--cups/http-addr.c118
-rw-r--r--cups/http-support.c317
-rw-r--r--cups/http.c1954
-rw-r--r--cups/http.h353
-rw-r--r--cups/ipp-support.c175
-rw-r--r--cups/ipp.c2035
-rw-r--r--cups/ipp.h434
-rw-r--r--cups/language.c427
-rw-r--r--cups/language.h228
-rw-r--r--cups/mark.c443
-rw-r--r--cups/md5.c392
-rw-r--r--cups/md5.h94
-rw-r--r--cups/md5passwd.c150
-rw-r--r--cups/options.c432
-rw-r--r--cups/page.c191
-rw-r--r--cups/ppd.c2058
-rw-r--r--cups/ppd.h270
-rw-r--r--cups/snprintf.c306
-rw-r--r--cups/string.c210
-rw-r--r--cups/string.h128
-rw-r--r--cups/tempfile.c207
-rw-r--r--cups/testhttp.c126
-rw-r--r--cups/testlang.c96
-rw-r--r--cups/testmime.dsp102
-rw-r--r--cups/testppd.c197
-rw-r--r--cups/testppd.dsp102
-rw-r--r--cups/usersys.c441
-rw-r--r--cups/util.c1766
-rw-r--r--data/HPGLprolog37
-rw-r--r--data/Makefile104
-rw-r--r--data/classified277
-rw-r--r--data/confidential277
-rw-r--r--data/iso-8859-1251
-rw-r--r--data/iso-8859-10251
-rw-r--r--data/iso-8859-13251
-rw-r--r--data/iso-8859-14251
-rw-r--r--data/iso-8859-15251
-rw-r--r--data/iso-8859-2253
-rw-r--r--data/iso-8859-3244
-rw-r--r--data/iso-8859-4251
-rw-r--r--data/iso-8859-5251
-rw-r--r--data/iso-8859-6206
-rw-r--r--data/iso-8859-7246
-rw-r--r--data/iso-8859-8214
-rw-r--r--data/iso-8859-9251
-rw-r--r--data/koi8-r261
-rw-r--r--data/koi8-u259
-rw-r--r--data/psglyphs1051
-rw-r--r--data/secret277
-rw-r--r--data/standard261
-rw-r--r--data/testprint.ps522
-rw-r--r--data/topsecret277
-rw-r--r--data/unclassified277
-rw-r--r--data/utf-839
-rw-r--r--data/windows-1250254
-rw-r--r--data/windows-1251258
-rw-r--r--data/windows-1252254
-rw-r--r--data/windows-1253243
-rw-r--r--data/windows-1254252
-rw-r--r--data/windows-1255236
-rw-r--r--data/windows-1256259
-rw-r--r--data/windows-1257247
-rw-r--r--data/windows-1258250
-rw-r--r--data/windows-874228
-rw-r--r--doc/Makefile242
-rw-r--r--doc/cmp.html677
-rw-r--r--doc/cmp.pdfbin0 -> 54355 bytes
-rw-r--r--doc/cmp.shtml595
-rw-r--r--doc/cups.css4
-rw-r--r--doc/cupsdoc.css9
-rw-r--r--doc/documentation.html85
-rw-r--r--doc/figures.scbin0 -> 75144 bytes
-rw-r--r--doc/fr/Makefile190
-rw-r--r--doc/fr/cups.css4
-rw-r--r--doc/fr/cupsdoc.css9
-rw-r--r--doc/fr/documentation.html81
-rw-r--r--doc/fr/glossary.shtml73
-rw-r--r--doc/fr/images/accept-jobs.gifbin0 -> 295 bytes
-rw-r--r--doc/fr/images/add-class.gifbin0 -> 269 bytes
-rw-r--r--doc/fr/images/add-printer.gifbin0 -> 307 bytes
-rw-r--r--doc/fr/images/cancel-job.gifbin0 -> 272 bytes
-rw-r--r--doc/fr/images/cancel-jobs.gifbin0 -> 281 bytes
-rw-r--r--doc/fr/images/cancel.gifbin0 -> 212 bytes
-rw-r--r--doc/fr/images/config-printer.gifbin0 -> 334 bytes
-rw-r--r--doc/fr/images/continue.gifbin0 -> 229 bytes
-rw-r--r--doc/fr/images/delete-class.gifbin0 -> 293 bytes
-rw-r--r--doc/fr/images/delete-printer.gifbin0 -> 330 bytes
-rw-r--r--doc/fr/images/hold-job.gifbin0 -> 269 bytes
-rw-r--r--doc/fr/images/manage-classes.gifbin0 -> 312 bytes
-rw-r--r--doc/fr/images/manage-jobs.gifbin0 -> 316 bytes
-rw-r--r--doc/fr/images/manage-printers.gifbin0 -> 345 bytes
-rw-r--r--doc/fr/images/modify-class.gifbin0 -> 282 bytes
-rw-r--r--doc/fr/images/modify-printer.gifbin0 -> 316 bytes
-rw-r--r--doc/fr/images/navbar.gifbin0 -> 2429 bytes
-rw-r--r--doc/fr/images/print-test-page.gifbin0 -> 316 bytes
-rw-r--r--doc/fr/images/reject-jobs.gifbin0 -> 281 bytes
-rw-r--r--doc/fr/images/release-job.gifbin0 -> 271 bytes
-rw-r--r--doc/fr/images/restart-job.gifbin0 -> 312 bytes
-rw-r--r--doc/fr/images/show-active.gifbin0 -> 302 bytes
-rw-r--r--doc/fr/images/show-completed.gifbin0 -> 343 bytes
-rw-r--r--doc/fr/images/start-class.gifbin0 -> 282 bytes
-rw-r--r--doc/fr/images/start-printer.gifbin0 -> 324 bytes
-rw-r--r--doc/fr/images/stop-class.gifbin0 -> 260 bytes
-rw-r--r--doc/fr/images/stop-printer.gifbin0 -> 307 bytes
-rw-r--r--doc/fr/index.html36
-rw-r--r--doc/fr/overview.html503
-rw-r--r--doc/fr/overview.pdfbin0 -> 42834 bytes
-rw-r--r--doc/fr/printing-overview.shtml125
-rw-r--r--doc/fr/references.shtml42
-rw-r--r--doc/fr/sam.html5219
-rw-r--r--doc/fr/sam.pdfbin0 -> 263655 bytes
-rw-r--r--doc/fr/sam.shtml4953
-rw-r--r--doc/fr/sum.html1731
-rw-r--r--doc/fr/sum.pdfbin0 -> 98490 bytes
-rw-r--r--doc/fr/sum.shtml933
-rw-r--r--doc/fr/system-overview.shtml19
-rw-r--r--doc/glossary.shtml73
-rw-r--r--doc/idd.html1083
-rw-r--r--doc/idd.pdfbin0 -> 66499 bytes
-rw-r--r--doc/idd.shtml1431
-rw-r--r--doc/images/accept-jobs.gifbin0 -> 259 bytes
-rw-r--r--doc/images/add-class.gifbin0 -> 242 bytes
-rw-r--r--doc/images/add-printer.gifbin0 -> 252 bytes
-rw-r--r--doc/images/cancel-job.gifbin0 -> 248 bytes
-rw-r--r--doc/images/cancel-jobs.gifbin0 -> 255 bytes
-rw-r--r--doc/images/cancel.gifbin0 -> 210 bytes
-rw-r--r--doc/images/classes.gifbin0 -> 591 bytes
-rw-r--r--doc/images/config-printer.gifbin0 -> 296 bytes
-rw-r--r--doc/images/continue.gifbin0 -> 224 bytes
-rw-r--r--doc/images/cups-block-diagram.gifbin0 -> 11637 bytes
-rw-r--r--doc/images/cups-large.gifbin0 -> 7457 bytes
-rw-r--r--doc/images/cups-medium.gifbin0 -> 3163 bytes
-rw-r--r--doc/images/cups-small.gifbin0 -> 1266 bytes
-rw-r--r--doc/images/delete-class.gifbin0 -> 259 bytes
-rw-r--r--doc/images/delete-printer.gifbin0 -> 267 bytes
-rw-r--r--doc/images/draft.gifbin0 -> 926 bytes
-rw-r--r--doc/images/hold-job.gifbin0 -> 228 bytes
-rw-r--r--doc/images/left.gifbin0 -> 110 bytes
-rw-r--r--doc/images/logo.gifbin0 -> 1958 bytes
-rw-r--r--doc/images/manage-classes.gifbin0 -> 289 bytes
-rw-r--r--doc/images/manage-jobs.gifbin0 -> 266 bytes
-rw-r--r--doc/images/manage-printers.gifbin0 -> 296 bytes
-rw-r--r--doc/images/modify-class.gifbin0 -> 267 bytes
-rw-r--r--doc/images/modify-printer.gifbin0 -> 277 bytes
-rw-r--r--doc/images/navbar.gifbin0 -> 2869 bytes
-rw-r--r--doc/images/navbar.xcf.gzbin0 -> 4253 bytes
-rw-r--r--doc/images/print-test-page.gifbin0 -> 288 bytes
-rw-r--r--doc/images/printer-idle.gifbin0 -> 706 bytes
-rw-r--r--doc/images/printer-processing.gifbin0 -> 805 bytes
-rw-r--r--doc/images/printer-stopped.gifbin0 -> 794 bytes
-rw-r--r--doc/images/reject-jobs.gifbin0 -> 252 bytes
-rw-r--r--doc/images/release-job.gifbin0 -> 255 bytes
-rw-r--r--doc/images/restart-job.gifbin0 -> 249 bytes
-rw-r--r--doc/images/right.gifbin0 -> 145 bytes
-rw-r--r--doc/images/show-active.gifbin0 -> 303 bytes
-rw-r--r--doc/images/show-completed.gifbin0 -> 337 bytes
-rw-r--r--doc/images/start-class.gifbin0 -> 238 bytes
-rw-r--r--doc/images/start-printer.gifbin0 -> 255 bytes
-rw-r--r--doc/images/stop-class.gifbin0 -> 245 bytes
-rw-r--r--doc/images/stop-printer.gifbin0 -> 252 bytes
-rw-r--r--doc/index.html36
-rw-r--r--doc/ipp.html1478
-rw-r--r--doc/ipp.pdfbin0 -> 103426 bytes
-rw-r--r--doc/ipp.shtml1994
-rw-r--r--doc/overview.html500
-rw-r--r--doc/overview.pdfbin0 -> 37837 bytes
-rw-r--r--doc/printing-overview.shtml125
-rw-r--r--doc/references.shtml42
-rw-r--r--doc/sam.html5303
-rw-r--r--doc/sam.pdfbin0 -> 265221 bytes
-rw-r--r--doc/sam.shtml5048
-rw-r--r--doc/sdd.html591
-rw-r--r--doc/sdd.pdfbin0 -> 63309 bytes
-rw-r--r--doc/sdd.shtml564
-rw-r--r--doc/spm.html8920
-rw-r--r--doc/spm.pdfbin0 -> 682610 bytes
-rw-r--r--doc/spm.shtml10202
-rw-r--r--doc/sps.html297
-rw-r--r--doc/sps.pdfbin0 -> 32909 bytes
-rw-r--r--doc/sps.shtml457
-rw-r--r--doc/ssr.html275
-rw-r--r--doc/ssr.pdfbin0 -> 31607 bytes
-rw-r--r--doc/ssr.shtml167
-rw-r--r--doc/stp.html262
-rw-r--r--doc/stp.pdfbin0 -> 35084 bytes
-rw-r--r--doc/stp.shtml144
-rw-r--r--doc/sum.html1732
-rw-r--r--doc/sum.pdfbin0 -> 98486 bytes
-rw-r--r--doc/sum.shtml933
-rw-r--r--doc/svd.html296
-rw-r--r--doc/svd.pdfbin0 -> 37369 bytes
-rw-r--r--doc/svd.shtml212
-rw-r--r--doc/system-overview.shtml19
-rw-r--r--doc/translation.html605
-rw-r--r--doc/translation.pdfbin0 -> 42497 bytes
-rw-r--r--doc/translation.shtml734
-rw-r--r--filter/.cvsignore31
-rw-r--r--filter/Dependencies75
-rw-r--r--filter/Makefile253
-rw-r--r--filter/common.c443
-rw-r--r--filter/common.h92
-rw-r--r--filter/form-main.c62
-rw-r--r--filter/form-ps.c49
-rw-r--r--filter/form-tree.c624
-rw-r--r--filter/form.h177
-rw-r--r--filter/hpgl-attr.c454
-rw-r--r--filter/hpgl-char.c502
-rw-r--r--filter/hpgl-config.c643
-rw-r--r--filter/hpgl-input.c234
-rw-r--r--filter/hpgl-main.c267
-rw-r--r--filter/hpgl-polygon.c382
-rw-r--r--filter/hpgl-prolog.c408
-rw-r--r--filter/hpgl-vector.c733
-rw-r--r--filter/hpgltops.dsp130
-rw-r--r--filter/hpgltops.h235
-rw-r--r--filter/image-bmp.c512
-rw-r--r--filter/image-colorspace.c1485
-rw-r--r--filter/image-gif.c658
-rw-r--r--filter/image-jpeg.c296
-rw-r--r--filter/image-photocd.c325
-rw-r--r--filter/image-pix.c225
-rw-r--r--filter/image-png.c252
-rw-r--r--filter/image-pnm.c290
-rw-r--r--filter/image-sgi.c269
-rw-r--r--filter/image-sgi.h96
-rw-r--r--filter/image-sgilib.c859
-rw-r--r--filter/image-sun.c379
-rw-r--r--filter/image-tiff.c1720
-rw-r--r--filter/image-zoom.c329
-rw-r--r--filter/image.c775
-rw-r--r--filter/image.h243
-rw-r--r--filter/imagetops.c892
-rw-r--r--filter/imagetoraster.c4516
-rw-r--r--filter/pstops.c1671
-rw-r--r--filter/pstops.dsp107
-rw-r--r--filter/raster.c254
-rw-r--r--filter/raster.h263
-rw-r--r--filter/rastertodymo.c363
-rw-r--r--filter/rastertoepson.c1133
-rw-r--r--filter/rastertohp.c808
-rw-r--r--filter/textcommon.c1185
-rw-r--r--filter/textcommon.h122
-rw-r--r--filter/texttops.c1305
-rw-r--r--filter/texttops.dsp98
-rw-r--r--fonts/Courier1494
-rw-r--r--fonts/Courier-Bold1652
-rw-r--r--fonts/Courier-BoldOblique1686
-rw-r--r--fonts/Courier-Oblique1448
-rw-r--r--fonts/Makefile62
-rw-r--r--fonts/Symbol1150
-rwxr-xr-xinstall-sh251
-rw-r--r--locale/C/cups_C135
-rw-r--r--locale/Makefile77
-rw-r--r--locale/be/cups_be134
-rw-r--r--locale/cs/cups_cs135
-rw-r--r--locale/de/cups_de136
-rw-r--r--locale/en/cups_en135
-rw-r--r--locale/es/cups_es135
-rw-r--r--locale/fr/cups_fr135
-rw-r--r--locale/he/cups_he135
-rw-r--r--locale/it/cups_it135
-rw-r--r--locale/locale.txt32
-rw-r--r--locale/ru_RU.cp1251/cups_ru_RU.cp1251134
-rw-r--r--locale/ru_RU.koi8r/cups_ru_RU.koi8r134
-rw-r--r--locale/sv/cups_sv135
-rw-r--r--locale/translate.c259
-rw-r--r--locale/uk/cups_uk134
-rw-r--r--locale/uk_UA.cp1251/cups_uk_UA.cp1251134
-rw-r--r--locale/zh_CN/cups_zh_CN135
-rw-r--r--man/.cvsignore7
-rw-r--r--man/Makefile123
-rw-r--r--man/Makefile.common84
-rw-r--r--man/accept.man60
-rw-r--r--man/backend.man115
-rw-r--r--man/classes.conf.man72
-rw-r--r--man/cups-config.man95
-rw-r--r--man/cups-lpd.man107
-rw-r--r--man/cups-polld.man46
-rw-r--r--man/cupsaddsmb.man127
-rw-r--r--man/cupsd.conf.man359
-rw-r--r--man/cupsd.man61
-rw-r--r--man/enable.man67
-rw-r--r--man/filter.man122
-rw-r--r--man/fr/.cvsignore7
-rw-r--r--man/fr/Makefile111
-rw-r--r--man/fr/accept.man62
-rw-r--r--man/fr/backend.man113
-rw-r--r--man/fr/classes.conf.man75
-rw-r--r--man/fr/cups-config.man98
-rw-r--r--man/fr/cups-lpd.man94
-rw-r--r--man/fr/cups-polld.man49
-rw-r--r--man/fr/cupsaddsmb.man117
-rw-r--r--man/fr/cupsd.conf.man255
-rw-r--r--man/fr/cupsd.man49
-rw-r--r--man/fr/enable.man67
-rw-r--r--man/fr/filter.man119
-rw-r--r--man/fr/lp.man163
-rw-r--r--man/fr/lpadmin.man162
-rw-r--r--man/fr/lpc.man82
-rw-r--r--man/fr/lpinfo.man63
-rw-r--r--man/fr/lpmove.man57
-rw-r--r--man/fr/lpoptions.man117
-rw-r--r--man/fr/lppasswd.man63
-rw-r--r--man/fr/lpq.man59
-rw-r--r--man/fr/lpr.man106
-rw-r--r--man/fr/lprm.man56
-rw-r--r--man/fr/lpstat.man134
-rw-r--r--man/fr/mime.convs.man59
-rw-r--r--man/fr/mime.types.man104
-rw-r--r--man/fr/printers.conf.man75
-rw-r--r--man/lp.man168
-rw-r--r--man/lpadmin.man156
-rw-r--r--man/lpc.man80
-rw-r--r--man/lpinfo.man60
-rw-r--r--man/lpmove.man53
-rw-r--r--man/lpoptions.man115
-rw-r--r--man/lppasswd.man61
-rw-r--r--man/lpq.man57
-rw-r--r--man/lpr.man101
-rw-r--r--man/lprm.man54
-rw-r--r--man/lpstat.man130
-rw-r--r--man/mime.convs.man54
-rw-r--r--man/mime.types.man98
-rw-r--r--man/printers.conf.man73
-rw-r--r--pdftops/.cvsignore1
-rw-r--r--pdftops/Array.cxx52
-rw-r--r--pdftops/Array.h56
-rw-r--r--pdftops/CNS13CMapInfo.h47771
-rw-r--r--pdftops/COPYING339
-rw-r--r--pdftops/Catalog.cxx308
-rw-r--r--pdftops/Catalog.h76
-rw-r--r--pdftops/CompactFontInfo.h464
-rw-r--r--pdftops/Decrypt.cxx384
-rw-r--r--pdftops/Decrypt.h59
-rw-r--r--pdftops/Dependencies59
-rw-r--r--pdftops/Dict.cxx89
-rw-r--r--pdftops/Dict.h75
-rw-r--r--pdftops/Error.cxx47
-rw-r--r--pdftops/Error.h26
-rw-r--r--pdftops/FontEncoding.cxx143
-rw-r--r--pdftops/FontEncoding.h64
-rw-r--r--pdftops/FontFile.cxx2530
-rw-r--r--pdftops/FontFile.h170
-rw-r--r--pdftops/FontInfo.h2070
-rw-r--r--pdftops/FormWidget.cxx130
-rw-r--r--pdftops/FormWidget.h67
-rw-r--r--pdftops/Function.cxx1373
-rw-r--r--pdftops/Function.h157
-rw-r--r--pdftops/GB12CMapInfo.h50880
-rw-r--r--pdftops/GString.cxx223
-rw-r--r--pdftops/GString.h95
-rw-r--r--pdftops/Gfx.cxx2566
-rw-r--r--pdftops/Gfx.h244
-rw-r--r--pdftops/GfxFont.cxx1081
-rw-r--r--pdftops/GfxFont.h250
-rw-r--r--pdftops/GfxState.cxx2235
-rw-r--r--pdftops/GfxState.h958
-rw-r--r--pdftops/Japan12CMapInfo.h31362
-rw-r--r--pdftops/Japan12ToRKSJ.h1038
-rw-r--r--pdftops/Lexer.cxx472
-rw-r--r--pdftops/Lexer.h74
-rw-r--r--pdftops/Link.cxx633
-rw-r--r--pdftops/Link.h336
-rw-r--r--pdftops/Makefile87
-rw-r--r--pdftops/Object.cxx220
-rw-r--r--pdftops/Object.h299
-rw-r--r--pdftops/OutputDev.cxx94
-rw-r--r--pdftops/OutputDev.h140
-rw-r--r--pdftops/PDFDoc.cxx251
-rw-r--r--pdftops/PDFDoc.h135
-rw-r--r--pdftops/PSOutputDev.cxx2562
-rw-r--r--pdftops/PSOutputDev.h215
-rw-r--r--pdftops/Page.cxx268
-rw-r--r--pdftops/Page.h125
-rw-r--r--pdftops/Params.cxx90
-rw-r--r--pdftops/Params.h38
-rw-r--r--pdftops/Parser.cxx212
-rw-r--r--pdftops/Parser.h58
-rw-r--r--pdftops/README426
-rw-r--r--pdftops/SFont.h127
-rw-r--r--pdftops/StdFontInfo.h546
-rw-r--r--pdftops/Stream-CCITT.h459
-rw-r--r--pdftops/Stream.cxx3466
-rw-r--r--pdftops/Stream.h723
-rw-r--r--pdftops/T1Font.h102
-rw-r--r--pdftops/TTFont.h104
-rw-r--r--pdftops/XRef.cxx635
-rw-r--r--pdftops/XRef.h110
-rw-r--r--pdftops/config.h140
-rw-r--r--pdftops/gfile.cxx678
-rw-r--r--pdftops/gfile.h132
-rw-r--r--pdftops/gmem.c203
-rw-r--r--pdftops/gmem.h53
-rw-r--r--pdftops/gmempp.cxx31
-rw-r--r--pdftops/gtypes.h31
-rw-r--r--pdftops/parseargs.c190
-rw-r--r--pdftops/parseargs.h71
-rw-r--r--pdftops/pdftops.cxx157
-rw-r--r--ppd/Makefile63
-rw-r--r--ppd/deskjet.ppd198
-rw-r--r--ppd/deskjet2.ppd217
-rw-r--r--ppd/dymo.ppd155
-rw-r--r--ppd/epson24.ppd128
-rw-r--r--ppd/epson9.ppd126
-rw-r--r--ppd/laserjet.ppd200
-rw-r--r--ppd/okidat24.ppd128
-rw-r--r--ppd/okidata9.ppd126
-rw-r--r--ppd/stcolor.ppd132
-rw-r--r--ppd/stcolor2.ppd132
-rw-r--r--ppd/stphoto.ppd132
-rw-r--r--ppd/stphoto2.ppd132
-rw-r--r--pstoraster/.cvsignore3
-rw-r--r--pstoraster/README.pstoraster63
-rw-r--r--pstoraster/cups.mak48
-rw-r--r--pstoraster/gdevcups.c3457
-rw-r--r--pstoraster/ghostscript-705.patch4563
-rwxr-xr-xpstoraster/pstoraster52
-rw-r--r--pstoraster/pstoraster.convs29
-rwxr-xr-xpstoraster/pstoraster.in59
-rw-r--r--scheduler/.cvsignore5
-rw-r--r--scheduler/Dependencies95
-rw-r--r--scheduler/Makefile142
-rw-r--r--scheduler/auth.c1627
-rw-r--r--scheduler/auth.h139
-rw-r--r--scheduler/banners.c215
-rw-r--r--scheduler/banners.h57
-rw-r--r--scheduler/cert.c276
-rw-r--r--scheduler/cert.h60
-rw-r--r--scheduler/classes.c695
-rw-r--r--scheduler/classes.h43
-rw-r--r--scheduler/client.c2584
-rw-r--r--scheduler/client.h105
-rw-r--r--scheduler/conf.c1894
-rw-r--r--scheduler/conf.h183
-rw-r--r--scheduler/cups-lpd.c1293
-rw-r--r--scheduler/cups-polld.c383
-rw-r--r--scheduler/cups.pam2
-rw-r--r--scheduler/cupsd.dsp173
-rw-r--r--scheduler/cupsd.h177
-rw-r--r--scheduler/devices.c482
-rw-r--r--scheduler/dirsvc.c1828
-rw-r--r--scheduler/dirsvc.h143
-rw-r--r--scheduler/filter.c320
-rw-r--r--scheduler/ipp.c5983
-rw-r--r--scheduler/job.c3165
-rw-r--r--scheduler/job.h108
-rw-r--r--scheduler/listen.c222
-rw-r--r--scheduler/log.c445
-rw-r--r--scheduler/main.c885
-rw-r--r--scheduler/mime.c600
-rw-r--r--scheduler/mime.h143
-rw-r--r--scheduler/network.c476
-rw-r--r--scheduler/network.h63
-rw-r--r--scheduler/ppds.c896
-rw-r--r--scheduler/printers.c2081
-rw-r--r--scheduler/printers.h118
-rw-r--r--scheduler/quotas.c235
-rw-r--r--scheduler/server.c162
-rw-r--r--scheduler/testmime.c241
-rw-r--r--scheduler/testspeed.c126
-rw-r--r--scheduler/type.c1096
-rw-r--r--standards/draft-ietf-ipp-collection-04.txt2262
-rw-r--r--standards/draft-ietf-ipp-finishings-fold-trim-bale-00.txt585
-rw-r--r--standards/draft-ietf-ipp-implementers-guide-v11-02.txt5046
-rw-r--r--standards/draft-ietf-ipp-indp-method-04.txt1768
-rw-r--r--standards/draft-ietf-ipp-install-02.txt1426
-rw-r--r--standards/draft-ietf-ipp-job-printer-set-ops-03.txt3828
-rw-r--r--standards/draft-ietf-ipp-job-prog-02.txt986
-rw-r--r--standards/draft-ietf-ipp-ldap-printer-schema-04.txt1456
-rw-r--r--standards/draft-ietf-ipp-not-05.txt928
-rw-r--r--standards/draft-ietf-ipp-not-over-snmp-04.txt9
-rw-r--r--standards/draft-ietf-ipp-not-spec-06.txt4988
-rw-r--r--standards/draft-ietf-ipp-notify-get-02.txt1711
-rw-r--r--standards/draft-ietf-ipp-notify-mailto-03.txt1740
-rw-r--r--standards/draft-ietf-ipp-notify-poll-02.txt9
-rw-r--r--standards/draft-ietf-ipp-ops-admin-req-00.txt9
-rw-r--r--standards/draft-ietf-ipp-ops-set2-02.txt9
-rw-r--r--standards/draft-ietf-ipp-url-scheme-02.txt899
-rw-r--r--standards/pwg5100.1.pdfbin0 -> 37359 bytes
-rw-r--r--standards/pwg5100.2.pdfbin0 -> 37360 bytes
-rw-r--r--standards/pwg5100.3.pdfbin0 -> 262279 bytes
-rw-r--r--standards/pwg5100.4.pdfbin0 -> 150078 bytes
-rw-r--r--standards/rfc1179.txt787
-rw-r--r--standards/rfc1321.txt1179
-rw-r--r--standards/rfc2246.txt4483
-rw-r--r--standards/rfc2396.txt2243
-rw-r--r--standards/rfc2487.txt451
-rw-r--r--standards/rfc2565.txt2075
-rw-r--r--standards/rfc2566.txt9691
-rw-r--r--standards/rfc2567.txt2411
-rw-r--r--standards/rfc2568.txt563
-rw-r--r--standards/rfc2569.txt1571
-rw-r--r--standards/rfc2595.txt843
-rw-r--r--standards/rfc2616.txt9859
-rw-r--r--standards/rfc2617.txt1907
-rw-r--r--standards/rfc2639.txt3587
-rw-r--r--standards/rfc2712.txt395
-rw-r--r--standards/rfc2817.txt731
-rw-r--r--standards/rfc2818.txt395
-rw-r--r--standards/rfc2821.txt4427
-rw-r--r--standards/rfc2822.txt2859
-rw-r--r--standards/rfc2910.txt2579
-rw-r--r--standards/rfc2911.txt12547
-rw-r--r--systemv/.cvsignore10
-rw-r--r--systemv/Dependencies26
-rw-r--r--systemv/Makefile185
-rw-r--r--systemv/accept.c286
-rw-r--r--systemv/cancel.c291
-rw-r--r--systemv/cupsaddsmb.c528
-rw-r--r--systemv/lp.c659
-rw-r--r--systemv/lpadmin.c1872
-rw-r--r--systemv/lpinfo.c454
-rw-r--r--systemv/lpmove.c235
-rw-r--r--systemv/lpoptions.c451
-rw-r--r--systemv/lppasswd.c405
-rw-r--r--systemv/lpstat.c1937
-rw-r--r--templates/Makefile107
-rw-r--r--templates/add-class.tmpl33
-rw-r--r--templates/add-printer.tmpl33
-rw-r--r--templates/admin-op.tmpl1
-rw-r--r--templates/admin.tmpl57
-rw-r--r--templates/choose-device.tmpl32
-rw-r--r--templates/choose-make.tmpl35
-rw-r--r--templates/choose-members.tmpl30
-rw-r--r--templates/choose-model.tmpl35
-rw-r--r--templates/choose-serial.tmpl56
-rw-r--r--templates/choose-uri.tmpl43
-rw-r--r--templates/class-added.tmpl2
-rw-r--r--templates/class-confirm.tmpl6
-rw-r--r--templates/class-deleted.tmpl1
-rw-r--r--templates/class-modified.tmpl2
-rw-r--r--templates/classes.tmpl51
-rw-r--r--templates/config-printer.tmpl6
-rw-r--r--templates/config-printer2.tmpl2
-rw-r--r--templates/error.tmpl3
-rw-r--r--templates/fr/Makefile105
-rw-r--r--templates/fr/add-class.tmpl33
-rw-r--r--templates/fr/add-printer.tmpl33
-rw-r--r--templates/fr/admin-op.tmpl1
-rw-r--r--templates/fr/admin.tmpl57
-rw-r--r--templates/fr/choose-device.tmpl32
-rw-r--r--templates/fr/choose-make.tmpl35
-rw-r--r--templates/fr/choose-members.tmpl30
-rw-r--r--templates/fr/choose-model.tmpl35
-rw-r--r--templates/fr/choose-serial.tmpl56
-rw-r--r--templates/fr/choose-uri.tmpl43
-rw-r--r--templates/fr/class-added.tmpl2
-rw-r--r--templates/fr/class-confirm.tmpl6
-rw-r--r--templates/fr/class-deleted.tmpl1
-rw-r--r--templates/fr/class-modified.tmpl2
-rw-r--r--templates/fr/classes.tmpl51
-rw-r--r--templates/fr/config-printer.tmpl6
-rw-r--r--templates/fr/config-printer2.tmpl2
-rw-r--r--templates/fr/error.tmpl3
-rw-r--r--templates/fr/header.tmpl23
-rw-r--r--templates/fr/job-cancel.tmpl1
-rw-r--r--templates/fr/job-hold.tmpl1
-rw-r--r--templates/fr/job-op.tmpl1
-rw-r--r--templates/fr/job-release.tmpl2
-rw-r--r--templates/fr/job-restart.tmpl1
-rw-r--r--templates/fr/jobs.tmpl54
-rw-r--r--templates/fr/modify-class.tmpl34
-rw-r--r--templates/fr/modify-printer.tmpl36
-rw-r--r--templates/fr/option-boolean.tmpl7
-rw-r--r--templates/fr/option-header.tmpl8
-rw-r--r--templates/fr/option-pickmany.tmpl7
-rw-r--r--templates/fr/option-pickone.tmpl7
-rw-r--r--templates/fr/option-trailer.tmpl8
-rw-r--r--templates/fr/printer-accept.tmpl2
-rw-r--r--templates/fr/printer-added.tmpl1
-rw-r--r--templates/fr/printer-configured.tmpl2
-rw-r--r--templates/fr/printer-confirm.tmpl6
-rw-r--r--templates/fr/printer-deleted.tmpl1
-rw-r--r--templates/fr/printer-modified.tmpl1
-rw-r--r--templates/fr/printer-purge.tmpl1
-rw-r--r--templates/fr/printer-reject.tmpl1
-rw-r--r--templates/fr/printer-start.tmpl1
-rw-r--r--templates/fr/printer-stop.tmpl1
-rw-r--r--templates/fr/printers.tmpl57
-rw-r--r--templates/fr/test-page.tmpl2
-rw-r--r--templates/fr/trailer.tmpl7
-rw-r--r--templates/header.tmpl23
-rw-r--r--templates/job-cancel.tmpl1
-rw-r--r--templates/job-hold.tmpl1
-rw-r--r--templates/job-op.tmpl1
-rw-r--r--templates/job-release.tmpl1
-rw-r--r--templates/job-restart.tmpl1
-rw-r--r--templates/jobs.tmpl54
-rw-r--r--templates/modify-class.tmpl34
-rw-r--r--templates/modify-printer.tmpl36
-rw-r--r--templates/option-boolean.tmpl7
-rw-r--r--templates/option-conflict.tmpl7
-rw-r--r--templates/option-header.tmpl8
-rw-r--r--templates/option-pickmany.tmpl7
-rw-r--r--templates/option-pickone.tmpl7
-rw-r--r--templates/option-trailer.tmpl8
-rw-r--r--templates/printer-accept.tmpl1
-rw-r--r--templates/printer-added.tmpl2
-rw-r--r--templates/printer-configured.tmpl2
-rw-r--r--templates/printer-confirm.tmpl6
-rw-r--r--templates/printer-deleted.tmpl1
-rw-r--r--templates/printer-modified.tmpl2
-rw-r--r--templates/printer-purge.tmpl1
-rw-r--r--templates/printer-reject.tmpl1
-rw-r--r--templates/printer-start.tmpl2
-rw-r--r--templates/printer-stop.tmpl2
-rw-r--r--templates/printers.tmpl57
-rw-r--r--templates/test-page.tmpl2
-rw-r--r--templates/trailer.tmpl7
-rw-r--r--test/.cvsignore1
-rw-r--r--test/4.1-requests.test140
-rw-r--r--test/4.2-cups-printer-ops.test214
-rw-r--r--test/4.3-job-ops.test297
-rwxr-xr-xtest/5.1-lpadmin.sh64
-rwxr-xr-xtest/5.2-lpc.sh40
-rwxr-xr-xtest/5.3-lpq.sh40
-rwxr-xr-xtest/5.4-lpstat.sh40
-rwxr-xr-xtest/5.5-lp.sh52
-rwxr-xr-xtest/5.6-lpr.sh52
-rwxr-xr-xtest/5.7-lprm.sh52
-rwxr-xr-xtest/5.8-cancel.sh52
-rwxr-xr-xtest/5.9-lpinfo.sh52
-rw-r--r--test/Dependencies4
-rw-r--r--test/Makefile85
-rw-r--r--test/create-job-format.test56
-rw-r--r--test/create-job-sheets.test55
-rw-r--r--test/create-job-timeout.test55
-rw-r--r--test/create-job.test54
-rw-r--r--test/get-devices.test21
-rw-r--r--test/get-job-attributes.test27
-rw-r--r--test/get-job-attributes2.test29
-rw-r--r--test/get-ppds.test21
-rw-r--r--test/get-printer-attributes.test44
-rw-r--r--test/ipptest.c826
-rw-r--r--test/print-job-hold.test33
-rw-r--r--test/print-job.test33
-rwxr-xr-xtest/run-stp-tests.sh338
-rw-r--r--test/set-attrs-hold.test180
-rw-r--r--test/str-header.html35
-rw-r--r--test/str-trailer.html5
-rw-r--r--test/testfile.jpgbin0 -> 598930 bytes
-rw-r--r--test/testfile.pdfbin0 -> 36613 bytes
-rw-r--r--test/testfile.ps512
-rw-r--r--test/testfile.txt60
-rw-r--r--test/testhp.ppd195
-rw-r--r--test/testps.ppd192
-rw-r--r--visualc/config.h147
-rw-r--r--visualc/jpeg.dsp284
-rw-r--r--visualc/libpng.dsp149
-rw-r--r--visualc/zlib.dsp141
734 files changed, 457351 insertions, 0 deletions
diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 000000000..c0b24b8fd
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,33 @@
+config.cache
+config.h
+config.log
+config.status
+configure
+cups-config
+cups.list
+cups.sh
+make.log
+printpro.common
+printpro.version
+Makedefs
+aix-4.3-powerpc
+darwin-5.2-powerpc
+darwin-5.3-powerpc
+darwin-6.0-powerpc
+freebsd-4.5-intel
+hpux-10.20-hppa
+hpux-11.00-hppa
+irix-5.3-mips
+irix-6.5-mips
+linux-2.0-intel
+linux-2.2-intel
+linux-2.4-intel
+solaris-2.5-intel
+solaris-2.5-sparc
+solaris-2.7-intel
+solaris-2.7-sparc
+solaris-2.8-intel
+solaris-2.8-sparc
+solaris-2.9-intel
+solaris-2.9-sparc
+tru64-4.0-alpha
diff --git a/CHANGES.txt b/CHANGES.txt
new file mode 100644
index 000000000..4753fb5a3
--- /dev/null
+++ b/CHANGES.txt
@@ -0,0 +1,2406 @@
+CHANGES.txt - 09/06/2002
+------------------------
+
+CHANGES IN CUPS V1.1.16
+
+ - The scheduler no longer passes the page-border and
+ number-up-layout attributes to filters when printing
+ banner pages.
+ - The LPD backend now uses a 30-second timeout when
+ sending commands and control files, and a 30-second
+ timeout when retrieving responses from an LPD server.
+ If a timeout occurs, it retries up to 10 times. This
+ helps to make LPD printing over VPNs work more
+ reliably.
+ - The USB backend now supports device URIs based on the
+ printer serial number and/or model number under Linux.
+ This avoids the "wrong device filename" problem when
+ using more than one USB printer.
+ - Now just shutdown the receiving end of a client
+ connection when sending an error that requires the
+ server to disconnect from the client afterwards. This
+ fixes a problem when doing remote administration with
+ encryption enabled.
+ - The scheduler did not send a printer-state-message
+ attribute if the string was empty; it now always sends
+ this attribute. This caused the printer message to be
+ displayed for other printers in the web interface.
+ - The LPD backend now supports a "manual_copies" option,
+ e.g.: "lpd://server/queue?manual_copies=no", in order
+ to handle copies for raw jobs to printers that don't
+ implement the LPD protocol properly...
+ - The "mirror" option was not being handled by the
+ PostScript or image filters.
+ - Updated the cupsaddsmb command to support the new CUPS
+ driver for Windows NT/2k/XP.
+ - Filter status lines longer than 1023 characters could
+ cause the scheduler to get into an infinite loop.
+ - The scheduler didn't reset the job state to pending
+ when modifying an active printer.
+ - Now limit the maximum number of recursion steps when
+ searching for a filter for a job, in case a user
+ defines a circular filter rule.
+ - The PostScript filter would embed an invalid
+ requirements comment in some cases.
+ - Added support for embedded job tickets in PostScript
+ files.
+ - The PostScript filter now detects EPS files and should
+ better handle printing EPS files.
+ - The cancel command now ignores a trailing destination
+ name when cancelling a specific job ID (Solaris
+ compatibility).
+ - The scheduler now rejects jobs with copies outside the
+ range of 1 to MaxCopies, inclusive.
+ - Added new MaxCopies directive to set the maximum
+ number of copies that a user can request.
+ - The scheduler didn't block signals while it processed
+ others and when it forked processes.
+ - The scheduler checked for new jobs to print when
+ stopping a job. This caused jobs to restart before a
+ shutdown.
+ - Updated the CUPS startup script to better support
+ different timezones and to support the RedHat/Mandrake
+ init script functions, if available.
+ - The scheduler did not properly handle backslashes in
+ banner files; it incorrectly assumed that "\c" should
+ always be replaced by "c", instead of only looking for
+ "\{" and replacing it by "{".
+ - The texttops filter didn't handle prettyprint=no.
+ - The text and HP-GL/2 filters didn't check for other
+ common duplex option names like cupsMarkOptions() did.
+ - "lpoptions -x printer" no longer clears the "default
+ printer" status of the printer.
+ - cupsTempFd() now stops trying to create a temporary
+ file after 1000 tries, and aborts on any error other
+ than EEXIST. This should prevent lp/lpr hangs due to
+ a bad or missing temporary directory.
+ - The lpadmin command did not send the right URI to the
+ scheduler when setting options on classes. This
+ caused a client-error-bad-request error.
+ - The CUPS API convenience functions would attempt to
+ connect to the remote server name in a
+ "printer@server" printer name instead of dealing with
+ the default (usually local) server. Aside from
+ causing user confusion, the remote server name might
+ not be resolved properly, causing further problems.
+ - "lp -q" would cause the "lp" command to segfault, as
+ the program would try to print the option letter that
+ caused the error using the wrong index into the
+ command-line; bugfix from Debian.
+ - Fixed a minor inconsistancy in the encoding of boolean
+ attributes from printer options in
+ cupsEncodeOptions().
+ - Added a FilterNice directive which sets the priority
+ of job filter processes that are run by the scheduler.
+ - Added Solaris x86 USB printer support.
+ - The USB backend now reports both the ulpt and unlpt
+ devices under *BSD.
+ - The "lpstat -o" command would truncate the
+ "printer-jobid" string if it was longer than 21
+ characters.
+ - The PJL-based MIME type rules now look in the first
+ 1024 bytes instead of just the first 512 bytes to find
+ the language mode.
+ - The image file types are now listed explicitly in the
+ mime.convs file so that additional image file formats
+ do not use the standard CUPS image filters by default.
+ - Updated the Software Programmers Manual to include
+ all of the CUPS API functions.
+ - ppdOpen*() no longer sorts choices for an option.
+ - The web interface now enforces constraints in PPD
+ files when configuring a printer.
+ - When stopping a printer, the scheduler didn't set the
+ printer state before stopping the current job.
+ - The cupsaddsmb utility now lists all data files for
+ Win9x and WinMe clients when installing that Windows
+ driver.
+ - Jobs submitted to a class now bounce immediately to
+ the next available printer rather than waiting until
+ that printer is available.
+ - Filters and backends now also get the CLASS
+ environment variable set when a job is printed to a
+ printer class instead of a normal printer.
+ - Added French translations of the web interface, CUPS
+ Overview, Software Administrators Manual, and Software
+ Users Manual contributed by Marian REYT-LLABRES.
+ - Added several "hint" messages for common configuration
+ problems that are stored in the error_log file.
+ - httpSeparate() now unquotes %xx characters in the
+ username:password field of a URI.
+ - When starting the scheduler in daemon mode, the parent
+ process now waits for the child to signal it is ready
+ to accept connections.
+ - Added -F option to cupsd to run cupsd in the
+ foreground but detach from the controlling terminal
+ and current directory.
+ - The scheduler did not reload jobs when receiving a HUP
+ signal; this would cause problems since the pointers
+ into the file type database would no longer be valid
+ for existing jobs.
+ - The scheduler did not save the network interface list
+ update time, thus no caching of the network data was
+ actually provided.
+ - Updated the SuSE PAM configuration file.
+ - The LPD backend now supports a "reserve" option and no
+ longer reserves a priviledged port by default.
+ - The cupsaddsmb command now continues past printers
+ that do not have a PPD file to export.
+ - The lpstat command didn't treat printer names as
+ case-insensitive.
+ - The lpstat command now reports the printer location
+ attribute with "lpstat -l -p".
+ - Fixed a bug in the vsnprintf() emulation function,
+ which was used on old versions of HP-UX, IRIX, and
+ Solaris.
+ - The number-up option was incorrectly being used when
+ printing banner pages.
+ - Added support for Greek and Slovak PPD files.
+ - CUPS now supports printer names containing any
+ printable character, e.g. "123-abc", "foo-bar", etc.
+ - The null filter was not supported in mime.convs due to
+ a bug in the filter validation code.
+ - Changes in the default printer and printer attributes
+ were not always reflected in the generated printcap
+ file.
+ - Implicit classes did not inherit the location or
+ description from member printers.
+ - The httpGetHostByName() function did not handle
+ hostnames that started with a number.
+ - Updated the filters to use the %cupsRotation comment
+ instead of %%Orientation to auto-rotate pages, since
+ the use of %%Orientation is inconsistent.
+ - Added the RootCertDuration directive to control how
+ often the root authentication certificate is updated.
+ - Increased the size of the IPP write buffer to 32k to
+ allow for larger attribute values and to provide more
+ efficient output of large numbers of attributes.
+ - The polling daemon now retries the initial connection
+ to the remote server; this fixes a problem when the
+ remote server is unavailable when the scheduler starts
+ up...
+ - The scheduler didn't validate Digest users against the
+ system group(s), so Digest and BasicDigest
+ authentication didn't work for administration
+ operations.
+ - The scheduler now passes the SHLIB_PATH environment
+ variable to child processes (HP-UX shared libraries)
+ - The scheduler now maps accesses from the loopback
+ interface to "localhost".
+ - The cups-lpd mini-daemon sent a status code byte in
+ response to queue state commands, but those commands
+ only return textual data.
+
+
+CHANGES IN CUPS V1.1.15-1
+
+ - The lpc and lprm sources didn't include the CUPS
+ string function header, which is required on systems
+ that don't have their own snprintf() function.
+ - The French manpage Makefile tried to install the
+ language subdirectories when it (obviously) didn't
+ have to.
+
+
+CHANGES IN CUPS V1.1.15
+
+ - Updated the CUPS license agreement for the new MacOS
+ and OpenSSL license exceptions.
+ - The printer-info attribute now defaults to the printer
+ name if no value has been set.
+ - ppdOpen() and friends now add an "Auto" InputSlot
+ option if none is provided to automatically select the
+ correct tray.
+ - Updated the ppdEmit() and ppdEmitFd() functions to
+ (re)mark the correct PageSize or PageRegion option
+ depending on the selected ManualFeed or InputSlot
+ options.
+ - ppdEmitFd() didn't handle custom page sizes.
+ - Darwin uses <pam/pam_appl.h> instead of
+ <security/pam_appl.h>.
+ - The jobs.cgi web interface now handles all job
+ operations, allowing the administrator to allow "job
+ administrators" or operators to manage jobs (but not
+ queues) on the server.
+ - The cupsDoFileRequest() function now checks if the
+ filename passed into the function is a directory, and
+ returns the IPP_NOT_POSSIBLE error if so.
+ - New SCSI printer backend.
+ - Cleaned up handling of locales with trailing character
+ set definitions.
+ - Fixed handling of invalid PPD attributes inside
+ OpenUI/CloseUI.
+ - Fixed a problem with SSL and the job, printer, and
+ admin CGIs on ports other than 443.
+ - The scheduler didn't handle AuthClass properly.
+ - Added French translation of man pages.
+ - Updated the text filter to support the const_cast,
+ dynamic_cast, and static_cast keywords in ISO C++.
+ - Now use strlcat() and strlcpy() (or emulation
+ functions) for easier string/buffer protection.
+ - The auto-generated printcap/printers.conf files now
+ have a small comment header explaining where the file
+ comes from...
+ - The PostScript filter now supports 6, 9, and 16-up
+ output, as well as new page-border and
+ number-up-layout options.
+ - The lpoptions command didn't set options properly when
+ using the default printer.
+ - Added ConfigFilePerm and LogFilePerm directives.
+ - Increased maximum size of MIME types to IPP_MAX_NAME
+ to allow for longer printer names.
+ - No longer create remote printers when loading job
+ history data.
+ - The printer-make-and-model attribute wasn't set when
+ the PPD file didn't contain a NickName attribute.
+ - Now handle PPD files with translation strings longer
+ than 80 bytes - they are truncated if they go over...
+ - The scheduler didn't handle signals until after it
+ loaded the configuration files the first time; this
+ caused problems on some installations that would
+ restart the scheduler as the system booted into run
+ level 3.
+ - Now throttle broadcasts like we do for polling.
+ - Fixed a bug in the reading of PPD files using CR's
+ instead of CR LF's or LF's.
+ - The scheduler would crash if cupsd.conf contained a
+ BrowseProtocols line with no protocols listed.
+ - The HTML job operation templates now link back to the
+ destination printer or class.
+ - The serial backend now detects USB serial devices.
+ - The LPD mini-daemon (cups-lpd) now passes the
+ job-originating-host-name attribute to the scheduler
+ (cupsd).
+ - Updated the IPP backend to reconnect after downgrading
+ from IPP/1.1 to 1.0, and when sending requests to HP
+ JetDirect interfaces that don't support HTTP
+ Keep-Alive like they should.
+ - Now pass NLSPATH and DYLD_LIBRARY_PATH environment
+ variables, if defined, to CGI and job processes.
+ - Removed the pstoraster filter (based on GNU
+ Ghostscript 5.50) and now provide the raster "driver"
+ and patch file necessary to use the current GNU
+ Ghostscript 7.05 release.
+ - Removed unnecessary fonts and updated the Courier and
+ Symbol fonts to the latest versions to better support
+ non-ISOLatin1 text.
+ - The text filter now always embeds the Courier and
+ Symbol fonts to ensure that they contain the full set
+ of glyphs.
+ - The lp and lpr commands now only override the SIGINT
+ handler if it is not being ignored (patch from Robert
+ Ambrose for some interactive software that catches
+ SIGINT and will gracefully cancel the print...)
+ - The PostScript image filter (imagetops) now supports
+ printing CMYK images using the CMYK colorspace.
+ - The image filters now support CMYK JPEG files, and
+ correctly handles the inverted files from Photoshop
+ (which seems to save RGBW data, not CMYK...)
+ - Added a "check" target to the top-level makefile to
+ conform with GNU standards (same as "test").
+ - The IPP code didn't always map the POSIX locale "C" to
+ the proper IPP language code.
+ - The cupsaddsmb program was updated to use the
+ setdriver command instead of addprinter.
+ - Banner pages were not handled properly for implicit
+ classes.
+ - When tunneling to a remote system using SSH, the
+ printer URIs for local printers on the remote system
+ did not reflect the correct port number.
+ - The Allow, Deny, BrowseAllow, BrowseDeny, and
+ BrowseAddress directives now support the network
+ interface names "@LOCAL" and "@IF(name)" for access
+ control and browsing based on the current interface
+ addresses instead of fixed names or IP addresses.
+ - The texttops filter did not properly recognize the
+ "nowrap" (wrap=false) option.
+ - The InstallableOptions group name in a PPD file is now
+ translated separately (CUPS_MSG_OPTIONS_INSTALLED) so
+ that UIs can accurately detect the presence of this
+ group.
+ - The scheduler no longer keeps job history data for
+ remote printers on the client (just on the server.)
+ - The parallel and USB backends now retry if the backend
+ detects that the printer is not connected to the
+ system (rather than stopping the queue...)
+ - The network backends now retry if the backend detects
+ that the printer is not connected to the network or is
+ unreachable (rather than stopping the queue...)
+ - The cupsGetDests() function no longer lists options
+ and instances for printers that no longer exist.
+ - The scheduler now converts the document language to
+ the correct LANG string.
+ - The cupsaddsmb program now supports alternative CUPS
+ and SAMBA server names.
+ - The PostScript filter now supports the Orientation
+ comment and rotates the page as needed automatically.
+ - Revamped the makefiles slightly to use automatically
+ generated dependencies.
+ - Build fixes for OS X.
+ - The TIFF reading code depended on the newest version
+ of libtiff; now conditionally compile that portion of
+ the loader.
+ - The PPD code now decodes all JCL options in the
+ JCLSetup group, not just those options that start with
+ the prefix "JCL".
+ - The backends now read print data using the read()
+ system call to ensure that the current page is printed
+ while the next page is being processed.
+ - The pdftops filter did not support shading type 3
+ (radial fill) for the "sh" operator.
+ - The cups-polld program now throttles the local
+ broadcasts of polled printers and classes so that the
+ local system is not overwhelmed with hundreds of
+ printers and classes all at once.
+ - Updated the serial backend to support 230,400 baud for
+ the Linux PPC port.
+ - The cupsGetJobs() function wouldn't report completed
+ jobs that did not have a document-format attribute
+ value.
+ - The cupsEncodeOptions() function now maintains a table
+ of known boolean and numeric options, and encodes all
+ other options as strings.
+ - Now add a newline before the end-of-page code in the
+ PostScript filter; this fixes a problem with files
+ that don't end with a newline.
+ - The image filters looked for the "orientation" option
+ instead of the correctly named "orientation-requested"
+ option.
+ - The cupsEncodeOptions() function now handles mixed
+ integers and ranges.
+ - New translation guide for developers to provide native
+ language support for CUPS.
+
+
+CHANGES IN CUPS V1.1.14
+
+ - The ippRead() function did not verify that the
+ attribute name length or string with language value
+ was not larger than the read buffer.
+ - The scheduler set the signal handlers before loading
+ the configuration files the first time; this prevented
+ the RunAsUser directive from blocking server reloads.
+ - Added Swedish message catalog.
+ - The parallel backend now recognizes the /dev/printers
+ device directory under Linux 2.4.x.
+ - MacOS X fixes.
+ - The cupsaddsmb utility sent the server name after the
+ user information when executing the rpcclient program.
+ This caused problems with some versions of SAMBA
+ 2.2.x.
+ - The IPP backend did not pass the requesting user name
+ when checking on the print job status. This prevented
+ it from waiting for the job to complete when
+ communicating with some IPP implementations that
+ require it.
+
+
+CHANGES IN CUPS V1.1.13
+
+ - The lpstat command did not report jobs submitted to
+ regular printer classes.
+ - The texttops filter didn't use sufficient precision
+ when positioning text with some values of cpi and lpi.
+ This could cause the alignment of text to stray.
+ - cupsGetDests() didn't merge the options from the
+ /etc/cups/lpoptions file with ~/.lpoptions - options
+ in ~/.lpoptions overrode them completely.
+ - Added support for KOI8-R and KOI8-U character sets,
+ and added several Russian message catalogs.
+ - The scheduler put the wrong timezone offset in the log
+ files (e.g. +0500 instead of -0500 for EST...)
+ - The scheduler did not ignore trailing whitespace in
+ *.convs files.
+ - The scheduler now forces all processes to exit (kill
+ -9) when it is stopped. This prevents parallel and
+ USB devices from running in the background after cupsd
+ goes away.
+ - The cupsParseOptions() function didn't skip trailing
+ whitespace after quoted values.
+ - More changes to support CUPS on OS/2.
+ - Added Simplified Chinese message catalog.
+ - Added PAM support for IRIX.
+ - The cupsGetPPD() function didn't remove the @server
+ portion of the printer name, and since it would
+ connect immediately to the remote server instead of
+ the local server, the printer would not be found.
+ - Classification and page labels were not rotated to
+ match the page orientation.
+ - Now set the TCP "no delay" option on network
+ connections to improve performance/response time.
+ - Improved the IRIX printing tools support with patches
+ from Andrea Suatoni.
+ - Added a new PrintcapGUI directive to specify the GUI
+ option panel program to use for the IRIX printing
+ tools support.
+ - The cupsGetDests() function did not check to see if a
+ user-defined default printer (set via lpoptions) still
+ existed.
+ - The pstops filter no longer assumes that the default
+ dictionary is writable when doing N-up processing.
+ - The pstops filter now supports printing N-up with the
+ page-set option.
+ - The imagetoraster filter now supports direct printing
+ of CMYK image data without conversion/correction.
+ - The IPP backend now reports printer state/error
+ conditions when possible (toner low, media empty,
+ etc.)
+ - The lpstat command now supports the (undocumented)
+ IRIX -l option ("-lprintername") for a compact job
+ listing for a printer.
+ - The lpstat command now includes printer date/time
+ information in the output (always Jan 01 00:00) to
+ make third-party tools happy.
+ - The text filter now supports non-integer cpi and lpi
+ values.
+ - The Margins field in the CUPS raster header was not
+ initialized by the pstoraster filter.
+ - Added --with-optim="flags" option to configure script.
+ - Updated the Italian message translations.
+ - Updated the cups.list file to install the correct
+ files.
+ - The pstoraster filter accessed the third element of a
+ 2 element array.
+ - The scheduler did not setup a status pipe for polling
+ processes, so error messages went to whatever file
+ descriptor 2 was pointing to when they were started.
+ - The httpMD5Final() function didn't put a colon between
+ the password and nonce strings.
+ - The pstops filter did not default to Binary data for
+ "%%BeginData:".
+ - The pstops filter did not stop processing when a line
+ containing a CTRL-D is seen.
+ - The scheduler no longer replaces the JobSheets values
+ from the printers.conf and classes.conf files with the
+ classification level, if set. This way the original
+ banner settings are preserved when classification
+ levels are changed or turned off.
+ - The serial backend didn't drain the output queue, nor
+ did it restore the original settings.
+ - Updated the default system group under MacOS X.
+ - If no SystemGroup was defined in cupsd.conf, the
+ system default group was not used.
+ - The cups-lpd mini-daemon now supports LPD clients that
+ send multiple control files.
+ - httpConnectEncrypt() now always uses encryption for
+ connections on port 443, since port 443 is reserved
+ for the "https" scheme.
+ - Group authentication via certificates did not work
+ from the web interface for accounts other than
+ "root".
+ - The serial port backend did not clear the OPOST
+ option, which could cause problems with some printers.
+ - The cups-lpd mini-daemon didn't lookup the client IP
+ address properly.
+ - The parallel backend now identifies the polled and
+ interrupt-driven devices under *BSD.
+ - The scheduler allowed the "always" encryption mode
+ inside a Location, which is not valid.
+ - The CUPS startup script now checks for the timezone
+ information under Linux.
+ - Now also map the sides attribute to the JCLDuplex
+ option (if present) in PPD files.
+ - Updated pdftops to Xpdf 0.93a.
+ - Added support for MD5 passwords under Slackware.
+ - Added new AuthType BasicDigest that does Basic
+ authentication using the MD5 password file managed by
+ the lppasswd command.
+ - The banner page attribute substitution code now
+ retains {name} sequences in banner files when the
+ named attribute is undefined. Use {?name} to
+ conditionally substitute an IPP attribute.
+ - The scheduler now ensures that the ServerRoot
+ directory and configuration files are owned by and
+ writable by the User and Group in cupsd.conf.
+ - The USB backend now lists all USB printer devices
+ regardless of whether a printer is connected or not.
+ This allows new USB printers to be connected without
+ restarting cupsd.
+ - Added some more minor performance tweeks to the IPP
+ protocol code to reduce copying and array indexing.
+ - The cupsaddsmb utility now uses the -c option with
+ smbclient and rpcclient to avoid the read length limit
+ for commands on the standard input.
+ - Added an include file to the CRD handling code in
+ pstoraster so that it would compile properly on 64-bit
+ pointer platforms...
+ - The cups-config script reported the wrong version
+ number.
+ - The cups-config script was installed in $(bindir)
+ instead of $(BINDIR).
+ - The init script did not correctly check for a running
+ cupsd under IRIX 5.x.
+
+
+CHANGES IN CUPS V1.1.12
+
+ - Added "Polish" to the list of known languages for PPD
+ files.
+ - Added missing directory definition to cups-config.
+ - The CUPS-Move-Job operation did not set the
+ destination type for the new destination.
+ - The CUPS-Add-Printer operation did not support the
+ allow=all or deny=none values to clear the per-user
+ printer ACLs.
+ - The SetPrinterAttrs() function did not handle invalid
+ PPD files that were missing the required NickName
+ attribute. It now looks for NickName, ModelName, and
+ then substitutes the string "Bad PPD File" for the
+ printer-make-and-model attribute.
+
+
+CHANGES IN CUPS V1.1.11
+
+ - Added support for embedded TrueType fonts in PDF
+ files.
+ - Added support for PostScript functions in PDF
+ files.
+ - Added new "cupsaddsmb" utility for exporting
+ CUPS printer drivers to SAMBA/Windows clients.
+ - Added preliminary support for Darwin/MacOS X.
+ - The CUPS-Add-Printer operation no longer allows
+ arbitrary scheme names in device URIs to be used - it
+ now restricts the available schemes to those found in
+ the device list (lpinfo -m).
+ - The ippRead() and ipp_read_file() functions could not
+ handle more than IPP_MAX_VALUES (100) values in a
+ 1setOf attribute. These functions have been updated
+ to dynamically allocate more memory as needed, and the
+ IPP_MAX_VALUES constant now represents the allocation
+ increment. [this caused some versions of the
+ GIMP-print drivers to fail since the number of media
+ options exceeded 100...]
+ - The scheduler could crash when BrowseShortNames
+ was set to "No".
+ - The scheduler did not prevent MaxClients from being
+ set to 0, which could cause the scheduler to go in an
+ infinite loop when accepting a request.
+ - Made some performance optimizations in the ippRead()
+ functions to make IPP request/response processing
+ faster.
+ - The accept/reject/enable/disable command did not
+ support properly support the "-h" or default
+ server name.
+ - The scheduler did not save the quota configuration
+ when the job-quota-period attribute was set to 0.
+ - The LPDEST and PRINTER environment variables did not
+ support printer instances.
+ - The text filter now handles more types of boldface and
+ underline formatting.
+ - The cupsTempFd() function did not fail if the
+ temporary directory did not exist; this would cause it
+ to loop indefinitely instead of returning an error
+ (-1).
+ - Stopping (disabling) a printer class did not stop jobs
+ from printing to printers in that class.
+ - The cupsGetDests() function was sending the
+ requested-attributes attribute as a name instead of a
+ keyword; this caused a serious performance problem on
+ slower systems since more information had to be
+ transferred from server to client.
+ - The web interfaces did not always quote < and & in
+ things like the job title. This had the potential for
+ browser-based security violations (on the browser's
+ machine); bug report from SuSE.
+ - The scheduler now treats unauthenticated usernames as
+ case-insensitive when doing quota and allow/deny
+ processing.
+ - The lp command sent the "request ID is ..." message
+ to stderr instead of stdout...
+ - The PostScript filter (pstops) now handles EPS files,
+ adding a showpage command to the files as needed.
+ - The configure script checked for the <stdlib.h> header
+ file before the JPEG libraries; since the JPEG headers
+ can define HAVE_STDLIB_H, the configure check would
+ cause the JPEG check to fail on some systems.
+ - The scheduler now supports localized banner files,
+ using the subdirectory approach, e.g. the "es"
+ subdirectory under /usr/share/cups/banners is used for
+ the Spanish banner files.
+ - Updated the scheduler so it knows the correct
+ language abbreviation to use for all supported
+ PPD LanguageVersion values. The new code also
+ supports country codes as well, so "English-GB"
+ maps to the "en_GB" locale.
+ - The cups-lpd mini-daemon did not support
+ anonymous printing (no username specified).
+ While the username is REQUIRED by RFC-1179,
+ MacOS clients do not send the REQUIRED username
+ information when printing via LPD.
+ - Added many warning and informational messages
+ to cups-lpd where they were missing.
+ - Added Czech message file contributed by SuSE.
+ - The cups-lpd mini-daemon now returns a non-zero
+ status if an invalid destination or job ID is
+ provided.
+ - The scheduler did not honor the KeepAlive setting in
+ cupsd.conf.
+ - Increased the size of the file read/write buffers to
+ 32k.
+ - *BSD static library creation fixes.
+ - Use mkstemps() instead of tmpnam() in pdftops whenever
+ possible.
+ - Added httpGetHostByName() function as a wrapper around
+ gethostbyname() - some implementations of this
+ function do not support IP addresses (e.g. MacOS X.)
+ - Added casts to all printf's of file lengths, since
+ there is currently no standard way of formatting long
+ long values.
+ - The client filename field was not cleared in all
+ instances, resulting in old form data being submitted
+ to CGIs.
+ - The httpConnect*() functions now try all available
+ addresses for a host when connecting for the first
+ time.
+ - The pstoraster filter would "lose" all drawing
+ commands when the PageSize was set but the printer
+ bitmap was not reallocated. This was most noticeable
+ with the output from StarOffice 6 beta and would
+ result in a blank page being output...
+ - The IPP backend was sending a PAGE comment even when
+ printing the output from a filter (it should only send
+ page comments when printing files directly...)
+ - The pdftops filter didn't properly map glyph names of
+ embedded Asian TrueType fonts.
+ - Changed the CUPS startup script to look for a program
+ named "cupsd", not just any program with "cupsd" in
+ the name (this caused the apcupsd UPS monitoring
+ daemon to be stopped/restarted...)
+ - The CUPS-Move-Job operation did not change the
+ internal destination name for held jobs, so moved (but
+ held) jobs would still show up as queued on the
+ original destination.
+ - The cups-polld program didn't send the
+ requested-attributes attribute in the
+ CUPS-Get-Printers and CUPS-Get-Classes requests, which
+ made it use more CPU and bandwidth than required.
+ - The scheduler and CUPS API incorrectly added a
+ job-sheets-default attribute for remote printers. This
+ caused banner pages to be omitted from client system
+ prints.
+
+
+CHANGES IN CUPS V1.1.10-1
+
+ - Minor fixes to the filter, systemv, and template
+ makefiles to install files properly.
+
+
+CHANGES IN CUPS V1.1.10
+
+ - Added a driver for DYMO label printers.
+ - Added new ClassifyOverride directive to allow users
+ to override the classification of individual jobs.
+ - Added new BrowseProtocols directive to control which
+ browse protocols are used (currently CUPS and SLP).
+ - Added SLPv2 support (thanks to Matt Peterson for
+ contributing the initial implementation for CUPS.)
+ - Adding a raw printer on a remote CUPS server now
+ correctly redirects PPD file requests to the remote
+ server.
+ - The serial backend now limits writes to 1/10th
+ second worth of data to avoid buffer overflows
+ with some types of flow control.
+ - The scheduler did not properly process PUT requests,
+ so configuration files could not be uploaded to the
+ server.
+ - The scheduler did not strip trailing whitespace on
+ lines in the configuration files.
+ - The httpWrite() function did not transition the PUT
+ request to the HTTP_STATUS state to get the status
+ from the server.
+ - The scheduler did not properly handle trailing null
+ ("-") filters when testing a driver that sent data
+ to the file: pseudo-backend.
+ - The IPP backend now only sends a document-format of
+ "application/vnd.cups-raw" when printing to another
+ CUPS server using a local printer driver or interface
+ script. Previously the job's document format was
+ used, which was incorrect.
+ - The lpadmin command didn't use the ppd-name attribute
+ with the -m option; this prevented the use of the
+ "raw" model from the command-line.
+ - The pstoraster filter output draft (1-bit) 6-color
+ output in the wrong order; this resulted in yellow
+ being printed instead of black on Stylus Photo
+ printers.
+ - The pdftops filter did not have the Japanese and
+ Chinese text support compiled into it.
+ - The IPP and AppSocket backends did not clear the
+ "waiting for print job to complete" status message,
+ which caused some confusion... :)
+ - The serial backend now opens the port in "no delay"
+ mode to avoid DCD detection problems with some OS's.
+
+
+CHANGES IN CUPS V1.1.9-1
+
+ - The configure script did not substitute the
+ correct user and group names.
+ - The configure script did not use the full path
+ to the install-sh script when it was used.
+ - The pstoraster filter did not correctly support
+ DuplexTumble mode for printers that used flip
+ duplexing.
+ - The cups.list.in file was missing from the
+ distribution.
+ - The New DeskJet series driver did not use the
+ correct OrderDependency for the Duplex option.
+ - Use read() instead of fread() to read piped
+ print files in lpr/lp. This avoids a bug in the
+ HP-UX 10.20 fread() function.
+ - Updated the pstoraster filter to use the MIPS_FIXADE
+ system call under IRIX to fix bus error problems on
+ R12000 processors (Ghostscript is not 64-bit clean...)
+ - Some Xerox PPD files (most notably the Phaser 790)
+ have illegal whitespace in the option keyword in the
+ OpenUI line. This caused the PageRegion option to not
+ be recognized properly for the Phaser 790.
+
+
+CHANGES IN CUPS V1.1.9
+
+ - Revamped the configure script to use a modular
+ approach for the various tests.
+ - Added --with-openssl-* options to properly reference
+ the OpenSSL libraries in DSOs.
+ - Added --with-cups-user and --with-cups-group
+ options to specify the default user and group for
+ CUPS.
+ - Added AIX shared library support.
+ - Added AIX device discovery for the serial and
+ parallel ports.
+ - Now use install program or script to install
+ directories, files, and symlinks.
+ - Updated pstops filter to use strict handling of EPS
+ files embedded in a PostScript document. The %%EOF
+ handling in 1.1.8 caused some dvips files not to
+ print.
+ - Fixed yet another memory allocation bug in pstoraster
+ that would cause it to crash. This fix also ensures
+ that all memory allocations are done on (at least) a
+ 64-bit boundary.
+ - Fixed Digest authentication - httpGetSubField() didn't
+ skip the Digest keyword.
+ - The scheduler did not properly handle Digest
+ authentication with the new multiple-group support.
+ - The scheduler did not allow usernames that were
+ not in the UNIX password file to be used for Digest
+ authentication from passwd.md5.
+ - The scheduler could not scan PPD files that only used
+ a carriage return (i.e. MacOS PPD files); the new code
+ is also about 40% faster, so servers with thousands of
+ PPD files should start much faster now.
+ - The scheduler now stores the PPD file size and
+ modification times in the ppds.dat file, so it can now
+ incrementally update the PPD database from the model
+ directory, resulting in significantly faster startup
+ times.
+ - The lpinfo command did not return a non-zero status
+ code if an error occurred.
+ - Fixed a bug in the scheduler's UpdateJob() function.
+ Basically, all jobs shared the same status buffer, and
+ the "buffer start" pointer could point to 1 byte
+ before the beginning of the buffer. The new
+ implementation uses a separate buffer for each job and
+ eliminates the buffer start bug.
+ - The IPP backend would send N copies of a document if
+ the receiving device didn't support the copies
+ attribute, even if the upstream driver already added
+ the necessary commands to generate the copies. This
+ was most noticeable with HP printers where N * N
+ copies would come out instead of N.
+ - The PostScript filter (pstops) did not properly handle
+ duplex printing on inkjet printers that provide this
+ option. Copies would be put on the front and back
+ sides of the duplexed page, and the filter did not
+ output an even number of pages.
+ - The backends always caught SIGTERM after they
+ connected to the printer. This prevented raw jobs
+ from being cancelled early.
+ - The cupsSetDests() function now removes any printers,
+ instances, and options that are not defined by the
+ user or server. This should prevent old system-wide
+ options from being used in individual user accounts.
+ - Updated the EPSON printer driver and added PPDs for
+ the newer EPSON Stylus printers that only support the
+ "ESC i" graphics command.
+ - The lpadmin command didn't allow you to add remote
+ printers to a local class.
+ - The lpadmin command didn't allow you to set the
+ options (quotas, etc.) for a class.
+ - The scheduler did not load or save the
+ job-sheets-default attribute for classes.
+ - The scheduler did not automatically recreate remote
+ printers that were part of a class.
+ - It was possible for a printer class to list the same
+ printer more than once.
+ - The scheduler now makes a backup copy of classes.conf
+ and printers.conf before writing the new file.
+ - The lppasswd program incorrectly asked for a new
+ password when deleting an existing MD5 password
+ account.
+ - The scheduler did not match "/printers/name.ppd"
+ against a location of "/printers/name".
+ - The client code did not always handle HTTP encryption
+ upgrades properly.
+ - The client code now caches the last Digest password so
+ it can retry using a new resource path or nonce value,
+ which are included in the MD5 sum sent to the server.
+ This should eliminate unnecessary password prompts
+ when using Digest authentication.
+ - The lppasswd command didn't have a man page.
+ - Updated the PJL detection rules to allow the universal
+ escape to occur anywhere in the first 128 bytes of the
+ file.
+ - The cups-polld program would poll servers continuously
+ with no delay if there was an error contacting the
+ server.
+ - The IPP backend would send an empty job-name or
+ requesting-user-name attribute if the corresponding
+ job attribute was an empty string. While this is
+ allowed by the IPP specification, some HP JetDirect
+ implementations return a client-error-bad-request
+ error if an empty name attribute value is received.
+ The new code only sends these attributes if they are
+ not the empty string.
+ - At least some versions of the HP JetDirect firmware
+ do not correctly implement IPP. Added additional
+ checks to the IPP backend to eliminate extra,
+ unsupported attributes which should normally be
+ ignored by a compliant IPP device.
+ - The scheduler did not copy the complete list of
+ supported file types into the
+ document-format-supported attribute. This caused
+ clients to not send the local file type (such as
+ application/vnd.cups-raw for raw print files) and the
+ corresponding bad output in some cases.
+ - The scheduler did not fully copy attributes from a
+ set-job-attributes request - string attributes were
+ only referenced, which could cause cupsd to crash
+ or behave irratically.
+ - The lp command didn't send the right value for the
+ job-hold-until attribute when "-H resume" was
+ specified.
+ - The IPP backend now returns as soon as a job is
+ completed or reported as "pending-held".
+ - Added new ImplicitAnyClasses and HideImplicitMembers
+ directives to the cupsd.conf file to make implicit
+ classes more usable/transparent to the user.
+ - Clients can now (with the appropriate authentication)
+ retrieve and update the server configuration files
+ using HTTP GET and PUT requests.
+ - The web interface didn't allow you to modify the
+ location or description of the printer.
+ - The pdftops filter now uses its own temporary file
+ function to work with PDF files using LZW compression
+ (which use the uncompress program or gunzip)
+ - The SystemGroup directive now supports specification of
+ multiple groups.
+ - Added new Include directive to cupsd.conf, a la
+ Apache.
+ - Added new pseudo-driver/PPD called "raw" that can be
+ used to create/convert a raw queue. This also allows
+ raw queues to be created in the web interface.
+ - The pdftops filter didn't handle image objects that
+ used JPEG and Flate compression together.
+ - The pstops filter counted pages wrong when using the
+ N-up and even/odd printing options. This prevented
+ the page-ranges option from working properly.
+ - Added another fix to pstoraster for a bus error
+ condition caused by a lack of parenthesis in the
+ Ghostscript code.
+ - Added new "natural-scaling" option which scales the
+ natural size of the image (percent of natural image
+ size instead of percent of page size.)
+ - The lppasswd program is now setuid to the CUPS user
+ instead of root.
+ - The PPD functions did not allow for PPD files that
+ defined the page sizes and margins before the page
+ size options.
+ - The mime.types file now checks for the PJL "LANGUAGE =
+ Postscript" command for PostScript files.
+ - The scheduler did not truncate file: output files.
+ - The PPD file reading code did not handle options with
+ raw quotes (") in the human-readable names.
+ - The pdftops filter now remaps the space character when
+ (bad) PDF files contain a .notdef glyph for the space
+ character.
+
+
+CHANGES IN CUPS V1.1.8
+
+ - Updated configure script to check for /etc/pam.d and
+ to only set PAMDIR if it exists.
+ - Updated spec file to generate separate cups-pstoraster
+ package for pstoraster.
+ - The spec file wasn't setting LOGDIR in the install.
+ - The scheduler might restart a stopped printer after
+ stopping a print job. Thanks to Florent
+ Guiliani for finding this bug!
+ - The init script showed run level 0 for the Red Hat
+ chkconfig program. This is incorrect because Red Hat
+ doesn't use run level 0 for shutdown scripts.
+ - The IPP backend did not handle the
+ client-error-not-found error when checking the status
+ of the job that was sent. This caused remote queues
+ to stop on client machines when the server had job
+ history disabled.
+ - Added httpConnectEncrypt() function to avoid
+ performance penalty for setting up encrypted
+ connections initially.
+ - Use httpConnectEncrypt() in all client apps and in the
+ CUPS API to ensure consistent usage of encryption
+ throughout.
+ - Jobs weren't queued to remote classes (fix from
+ Richard Begg.)
+ - AIX changes from Richard Begg.
+ - Fixed the pstops fix for GNOME output - no longer use
+ the page numbers in the %%Page: comment since GNOME
+ puts a filename instead (!?@!#?!). There is still an
+ issue with N-up printing since GNOME defines its fonts
+ in the first page instead of the document setup section
+ (pages must be independent according to the DSC spec)
+ People with GNOME printing problems should consult bug
+ #54489...
+ - The imagetops filter produced PAGE: messages when
+ generating PostScript for a non-PostScript printer
+ (only affects page-label and Classification
+ options.)
+ - The updated pdftops filter was looking for an options
+ file called xpdf.conf instead of pdftops.conf.
+ - The scheduler would not force the default job sheets
+ for printers to the current classification setting.
+ - Added a new ippFindNextAttribute() function to the
+ CUPS API.
+ - ppdEmitJCL() now strips any leading path info from
+ the title string. This is only an issue for non-CUPS
+ clients that don't do this already...
+ - Other pstops fixed from Helge Blischke for printing
+ non-conforming documents.
+ - The MaxJobs parameter was not reset when loading the
+ cupsd.conf file.
+
+
+CHANGES IN CUPS V1.1.7
+
+ - Configuration script changes, including new
+ "--with-docdir=/dir" option to relocate CUPS
+ documentation and web content according to your
+ favorite version of the FHS.
+ - Documentation updates for encryption, SLP, etc.
+ - New Software Test Plan and automated test script to
+ test CUPS prior to installation.
+ - All scheduler configuration files are now case
+ insensitive to match Apache.
+ - Added support for Apache ListenBackLog, Require,
+ Satisfy, <Limit>, <LimitExcept>, and LimitRequestSize
+ directives.
+ - Added support for all Apache log levels...
+ - Added support for "double" HostNameLookups.
+ - Added new "RunAsUser" directive to support non-root
+ configurations on the standard (priviledged) ports.
+ - Added support for non-root invocation of the lpd
+ backend (does no reserve a priviledged port, which
+ might not work with some LPD servers...)
+ - Added new PrintcapFormat directive to control the
+ output format of the printcap file (BSD or Solaris
+ formats are supported at present.)
+ - The CUPS directory service routines now handle
+ ECONNREFUSED errors gracefully rather than shutting
+ all browsing off.
+ - ippErrorString() now returns the recommended error
+ messages from the IPP/1.1 Model and Semantics
+ document.
+ - Fixed a minor IPP compliance issue with responses
+ to requests without the attributes-charset or
+ attributes-natural-language attributes.
+ - Sun fix: need httpFlush() call for chunked IPP
+ requests in cupsDoFileRequest().
+ - httpConnect() now looks up "localhost" by name and
+ by address (127.0.0.1) for users the go to the
+ trouble of removing the required localhost entry
+ in /etc/hosts or on their DNS server...
+ - Added support for Linux 2.4.x devfs parallel port
+ filenames (/dev/parallel/N).
+ - cupsDo[File]Request() and cupsGetPPD() no longer
+ block trying to reconnect to a crashed or inaccessable
+ server.
+ - Added new ppdEmitJCL() function to better handle
+ PJL commands from PPD files.
+ - A bug in UpdateJob() would cause the scheduler to
+ consume 100% CPU until another request was submitted.
+ - The cancel command did not support the "-" option to
+ cancel all jobs on all printers.
+ - The cancel and lprm commands did not support cancelling
+ the next/current job in the queue.
+ - The pdftops and pstoraster filters were using unsafe
+ temporary file functions; while this is not a problem
+ in normal configurations (the CUPS temporary directory
+ is restricted), they now use the cupsTempFd() function.
+ - The mime.types file was missing the recognition rule
+ for Sun Raster images.
+ - The admin CGI was passing a printer make string to
+ ippSetCGIVars() that was being replaced in that
+ function.
+ - "lpoptions -l" would resave the options...
+ - The EPSON drivers now send the "end packet mode"
+ command when printing to USB devices.
+ - The scheduler initialized certificates before loading
+ the cupsd.conf file.
+ - The scheduler used /dev/random to collect random data,
+ which could block if insufficient entropy information
+ had been collected by the kernel. Now use
+ /dev/urandom.
+ - Fixed a bug in the whitespace skipping code in
+ httpGetSubField().
+ - The LPD backend now supports a new "order" option:
+ "lpd://server/queue?order=control,data" (default) and
+ "lpd://server/queue?order=data,control".
+ - The scheduler enforced a 30 second timeout on all
+ clients regardless of the Timeout directive and if a
+ CGI was currently running.
+ - cupsParseOptions() now sets boolean options to
+ option=true or option=false.
+ - The "percent complete" calculations in the LPD backend
+ could overflow on large files, causing the percentage
+ to wrap to 0 every 40MB or so.
+ - Fixed a memory reallocation bug in pstoraster that
+ could cause it to crash.
+ - The LPD backend now sanitizes the job title to avoid
+ potential problems on remote LPD servers.
+ - The lp command did not send the requesting-user-name
+ attribute when altering a job.
+ - The pstops filter did not handle PostScript files with
+ lines longer than 8191 bytes.
+ - The scheduler no longer uses inet_addr() to convert IP
+ addresses in dot format (mmm.nnn.ooo.ppp) to the
+ 32-bit format, since it will not work for IPv6
+ addresses.
+ - New "Classification" directive to force labeling of
+ the current classification on each page.
+ - New "page-label" attribute to add per-page labels
+ ("For Official Use Only", "Draft", etc.)
+ - The scheduler now sets the HTTPS environment variable
+ for CGI programs when a client connects using
+ encryption.
+ - Fixed a recursion bug in the scheduler that could
+ cause cupsd to crash when a printer was removed.
+ - The LPDEST and PRINTER environment variables didn't
+ support instances.
+ - Dropped the "file" backend from the device list that
+ is reported, since it is only available for *testing*
+ and should never be used in a production environment.
+ The file: device can still be used, but it won't show
+ up in the list of devices from lpinfo or the web
+ interface.
+ - Added support for /dev/lpa# parallel ports under *BSD.
+ - Added META variables to the CGI header template to
+ prevent caching of the results.
+ - Fixed an unaligned memory buffer for the pstoraster
+ clist states; this caused bus errors for some
+ combinations of printers, drivers, and options.
+ - Re-added black reduction for colorful colors; this
+ helps to prevent dark colors from getting desaturated.
+ (only used when converting RGB to CMYK)
+ - Added two new directives - MaxJobsPerPrinter and
+ MaxJobsPerUser - to allow an administrator to set
+ the maximum number of pending jobs in a queue or
+ submitted by a user.
+ - The scheduler no longer stops a printer if it can't
+ create the status pipe or run the filters or backend.
+ This will allow heavily loaded servers to service
+ clients or start print jobs as the load allows.
+ - Fixed a bug in the Set-Job-Attributes code that could
+ crash the scheduler (patch from Martin Zielinski)
+ - cupsSetDests() did not quote option values with
+ embedded spaces.
+ - Added support for the Enable-Printer and
+ Disable-Printer extension operations (same as
+ CUPS-Accept-Jobs and CUPS-Reject-Jobs.)
+ - The AppSocket and IPP backends now wait for the print
+ job to be finished before exiting; this should prevent
+ the loss of print jobs with older JetDirect firmware
+ and make consecutive print jobs print faster.
+ - The BMP loading code did not handle resolution values
+ of 0. This is a problem with BMP image files produced
+ by the GIMP.
+ - The HTTP Upgrade code (upgrade to TLS encryption)
+ bypassed the authentication checks.
+ - The HTTP Upgrade code did not send a 426 status code
+ to the client and end the current request. This caused
+ a race condition between the client and server for the
+ upgrade to TLS.
+ - Fixed a bug in the EOF and Trailer detection code in
+ the pstops filter.
+ - The imagetoraster filter did not add the margins to
+ the custom page size in the raster header.
+ - The imagetops filter did not adjust the custom page
+ size to the size of the printed image.
+ - The imagetops filter did not include DSC comments
+ which are required by some printers.
+ - The imagetops filter did not insert newlines in
+ Base85 encoded output, causing files to contain
+ lines longer than 255 characters (violation of the
+ DSC).
+ - Added support for the DeskJet 900 series duplexer
+ and CRET color modes in the HP driver.
+ - Added support for PPD-defined margins in the HP
+ driver.
+ - Fixed the debugging output from pstoraster - the
+ font list was not terminated by a newline.
+ - Some versions of the HP-UX pam_unix authentication
+ module apparently do not pass the appdata_ptr argument
+ to the conversation function, preventing the scheduler
+ from authenticating users using PAM under HP-UX. A
+ workaround using a static variable has been added to
+ address this problem.
+ - Fixed a bug in the scheduler SortPrinters() function
+ that could cause printers to disappear or the
+ scheduler to crash when adding a printer.
+ - Changed the pstops filter to not do per-page filtering
+ if the file does not conform to at least version 3.0
+ of the document structuring conventions. This seems
+ to "fix" printing with broken apps.
+ - The image filters did not handle older TIFF files that
+ lacked the samples-per-pixel and bits-per-pixel tags.
+ - Added new cupsGetJobs() and cupsFreeJobs() functions
+ to manage print jobs.
+ - cupsEncodeOptions() would encode names of 0 length and
+ cupsAddOption() and cupsParseOptions() would add names
+ of 0 length.
+ - The scheduler might block waiting for status messages
+ after starting a new print job. Thanks to Florent
+ Guiliani for finding this bug!
+
+
+CHANGES IN CUPS V1.1.6-3
+
+ - The configure script put the JPEG library before the
+ TIFF library; this caused problems in some
+ configurations since the TIFF library also supports
+ JPEG compression of TIFF images.
+ - Updated the configure script and makefiles to handle
+ admin man pages with the "1m" extension (HP-UX, IRIX,
+ Solaris, Tru64) and in odd directories (IRIX)
+ - The updated cupsTempFile() function did not return
+ the filename when called with a filename buffer of
+ NULL (previously it used a static buffer.)
+ - FreeBSD uses /dev/unlptN, but NetBSD and OpenBSD use
+ /dev/ulptN.
+ - DeletePrinter() didn't remove the printer from any
+ classes it was a member of.
+ - DeletePrinterFromClass() didn't preserve the
+ implicit status of a class.
+ - DeletePrinterFromClasses() didn't remove printers
+ from implicit classes.
+ - StartJob() didn't send the job-sheets, job-priority,
+ and job-hold-until attributes to remote printers.
+ - LoadAllJobs() was looking for job-sheets-completed
+ instead of job-media-sheets-completed. This would
+ prevent accumulation of page data after a restart
+ of the scheduler.
+ - The pstops and imagetops filters now generate copies
+ using the appropriate method for a Level 1, 2, or 3
+ printer since some Level 2/3 printers don't support
+ the /#copies variable anymore.
+ - The man page for cups-lpd did not mention the "-o"
+ option.
+ - The IPP backend didn't handle version-not-supported
+ errors and revert to IPP/1.0 (previously it only checked
+ for a bad-request error)
+ - Caldera fix: lpc now reports unimplemented commands as
+ unimplemented, not invalid.
+ - Caldera fix: lpq didn't recognize BSD lpq "-a" option.
+ - Caldera fix: lpr didn't recognize BSD lpr "-1", "-2",
+ "-3", "-4", "-q", or "-U" options.
+ - RedHat fixes: patches to GNU Ghostscript
+ - SuSE fix: temp file creation patch to GNU Ghostscript
+ (pstoraster).
+ - SuSE fix: remove cgi-bin/abort.c and cgi-bin/email.c,
+ which are not used.
+ - SuSE fix: missing NULL check in cgi_initialize_post().
+ - SuSE fix: potential buffer overflows in
+ cgi_initialize_string().
+ - SuSE fix: potential buffer overflows in
+ ippSetCGIVars()
+ - SuSE fix: more NULL checks in ppdOpen(); also make
+ sure that all memory is freed on error to avoid memory
+ leaks.
+ - SuSE fix: Exit from child if setgid() or setuid()
+ fails.
+ - SuSE fix: Added setgroups() calls after setgid() and
+ setuid() calls.
+ - SuSE fix: potential buffer overflows in httpEncode64()
+ calls.
+ - SuSE fix: potential buffer overflows in httpSeparate()
+ - SuSE fix: potential buffer overflows in ippWrite() for
+ bad input.
+ - SuSE fix: potential nul skip in ppd_decode() for
+ missing hex digits.
+
+
+CHANGES IN CUPS V1.1.6-2
+
+ - Added changes to support NetBSD startup scripts.
+ - Added separate compiler options for pstoraster
+ (Ghostscript) to avoid compiler-induced errors
+ from Ghostscript's twisted code.
+ - The mime.types file contained syntax errors.
+ - Updated the *BSD USB device filenames to use
+ the /dev/unlptN files so that the USB device
+ is not reset prior to printing (causes print
+ corruption on many printers)
+ - Added new cupsTempFd() function to avoid serious
+ security bug in glibc fopen() function. The glibc
+ fopen() function unlinks a file before creating it,
+ which opens up possible symlink attacks.
+ - Now reject 0-length names in add-printer and add-class
+ requests.
+ - Fix for pstoraster when ZLIB is not available.
+ - cupsGetPPD() didn't reconnect when a HTTP connection
+ was lost.
+ - SuSE fix: httpConnect() didn't check that the
+ value from gethostbyname() was a valid IPv4 address.
+ - SuSE fix: httpConnect() didn't allow file descriptor 0
+ to be used for a socket.
+ - SuSE fix: ippRead() didn't confirm that all values in
+ a set were numeric or string types.
+ - SuSE fix: lppasswd race condition fixes.
+ - SuSE fix: directive names could overflow buffer when
+ reading *.conf files.
+ - SuSE fix: HEAD requests for PPD files did not use the
+ same logic as GET requests.
+ - SuSE fix: possible buffer overflow when adding
+ /index.html to requested directory name.
+ - SuSE fix: possible buffer overflow when converting
+ IPP attributes to string options for filters.
+ - SuSE fix: creating file: device output with mode 0666
+ instead of mode 0600.
+ - SuSE fix: creating job info files with mode 0640
+ instead of 0600.
+ - SuSE fix: don't rely on snprintf() for including
+ system name in log filenames.
+ - SuSE fix: add bounds checking when copying quoted
+ and hex strings.
+
+
+CHANGES IN CUPS V1.1.6-1
+
+ - Added configure check for getting the correct
+ strftime() format string; %c is not Y2k safe,
+ and %KC and NULL are not universally supported.
+
+
+CHANGES IN CUPS V1.1.6
+
+ - Fixed another possible DoS attack in httpGets()
+ - Added check for "LANGUAGE = PCL" and "LANGUAGE =
+ POSTSCRIPT" in mime.types.
+ - Resolution options were not being passed into the
+ filter programs properly.
+ - The default compiler options for GCC no longer include
+ "-g3", which apparently is deprecated in newer
+ versions of GCC.
+ - CheckJobs() could cause cupsd to crash if a job is
+ cancelled in StartJob().
+ - The printers.conf and classes.conf files are now
+ written with restricted permissions.
+ - The round-robin algorithm used by FindAvailablePrinter()
+ had problems; fixes contributed by Joel Fredrikson.
+ - If LoadAllJobs() is unable to determine the file type
+ of a print job, assume "application/vnd.cups-raw".
+ - The web interface now provides a job_printer_name
+ value for any corresponding job_printer_uri value.
+ - The cups-lpd mini-daemon now logs the client address
+ and hostname as well as all commands and errors in the
+ syslog file.
+ - The IPP backend now detects the supported file formats
+ and only specifies the document format if it is
+ supported. This makes IPP printing to network print
+ servers and cards more reliable without affecting the
+ capabilities of CUPS servers.
+ - The time_at_xyz attributes are now converted to human-
+ readable dates and times for the web interfaces.
+ - The HP and EPSON sample drivers now correctly catch
+ signals and eject the current page when a job is
+ cancelled.
+ - Fixed bug in CGI code - did not ignore control
+ characters (e.g. newlines) in form data. This caused
+ sporatic web interface problems.
+ - The file type logging code in the scheduler referenced
+ the optional document-format attribute; the new code
+ uses the resolved MIME type instead.
+ - The client.conf parsing code now removes trailing
+ whitespace.
+ - The MaxJobs directive was being treated as a boolean
+ instead of an integer.
+ - The scheduler would not timeout remote printers if
+ BrowseInterval was set to 0.
+ - The lpadmin command now supports setting of options
+ and user-level access control.
+ - Added "-E" option to all printing commands to force
+ encryption.
+ - The client code did not consume the response to the
+ OPTIONS request when switching to secure mode.
+ - The scheduler did not output a Content-Length field
+ when responding to an OPTIONS request.
+ - Added documentation on using cups-lpd with xinetd
+ to the man page.
+ - The socket backend now starts retries at 5 seconds and
+ increases the interval to 30 seconds. This should
+ provide faster printing when multiple jobs/files are
+ queued for a printer.
+ - The filters and backends no longer buffer output to
+ stderr. This should provide much more accurate status
+ reporting.
+
+
+CHANGES IN CUPS V1.1.5-2
+
+ - Fixed configure check for OpenSSL to work with RSA
+ code.
+ - Added configure check for <sys/ioctl.h>, and use this
+ check in backend/serial.c.
+ - Updated configure script handling of data,
+ configuration, and state directories to use datadir,
+ sysconfdir, and localstatedir variables.
+ - NetBSD uses different serial port filenames than
+ FreeBSD and OpenBSD.
+ - The pdftops filter didn't need some X-specific files.
+ - The scheduler makefile doesn't do a chown anymore when
+ installing (cupsd did this automatically on startup
+ anyways)
+
+
+CHANGES IN CUPS V1.1.5-1
+
+ - There was a typo in the top-level Makefile
+ - The top-level Makefile did not install an init script
+ for run level 5.
+ - The configure script did not add the "crypto" library
+ when checking for the OpenSSL library.
+ - The OKIDATA PPD files were missing.
+ - The config.h.in file defined the wrong version number.
+ - The serial backend did not define "funky_hex" under *BSD.
+ - Updated the Visual C++ project files and some of the
+ CUPS API sources to compile under Windows again.
+
+
+CHANGES IN CUPS V1.1.5
+
+ - Security updates - new default configuration does
+ not broadcast printer information and only allows
+ access from the local system.
+ - EXPERIMENTAL encryption support - CUPS now optionally
+ supports TLS/SSL encryption via the OpenSSL library.
+ - Documentation updates.
+ - Makefile/configure script updates.
+ - The RPM spec file didn't work out-of-the-box under
+ RedHat or Mandrake.
+ - Minor code cleanup to remove extraneous compiler
+ warnings.
+ - cupsTempFile() was using %p for the temporary
+ filename; this should have been %08x (just 8 digit
+ hex)
+ - Deleting a printer with active print jobs would still
+ crash the server.
+ - ippWrite() and ipp_write_file() didn't send the
+ correct value length for name-with-language and
+ text-with-language attributes.
+ - Updated IPP code to support copied strings (that
+ should not be freed); this provides slightly more
+ efficient IPP server performance.
+ - Updated PDF filter to Xpdf 0.91.
+ - httpGets() could go into an infinite loop if a line
+ longer than the input buffer size was sent by a
+ client. This could be used in a Denial-of-Service
+ attack.
+ - The lpstat and CUPS API functions now request only the
+ data required when getting the list of printer or
+ class information. This should improve performance
+ with large numbers of printers on slower machines.
+ - The scheduler was always enforcing the FilterLimit,
+ even if FilterLimit was set to 0.
+ - Updated the Linux USB backend to support Mandrake's
+ /dev/usb/usblp# filenames.
+ - The PRINTER and LPDEST environment variables did not
+ override the lpoptions default printer.
+ - The PPD read functions incorrectly included trailing
+ characters (usually whitespace) after quoted string
+ attributes.
+ - The multiple-document-handling attribute handling code
+ did not check for the correct value for collated
+ copies (separate-documents-uncollated-copies).
+ - The EPSON driver did not work with OKIDATA printers in
+ EPSON emulation mode (needed change-emulation command)
+ - The HP-GL/2 filter did not scale the plot properly in
+ scale mode 2.
+ - Added PPD files for 9-pin and 24-pin OKIDATA printers.
+ - The httpSeparate() function didn't handle passwords
+ that started with a number.
+ - ippDelete() could free the character set string
+ multiple times in name-with-language and
+ text-with-language attributes.
+ - The scheduler would access freed memory right after
+ freeing it (for debug messages); these parts of the
+ code have been reordered to avoid this situation
+ which was causing sporatic errors and crashes.
+ - The ppdClose() function didn't free all of the strings
+ in the ppd_file_t structure.
+ - The LoadAllJobs() function in the scheduler did not
+ close the spool directory.
+ - Changed all sprintf's that use string formats to
+ snprintf's, even if the destination buffer is
+ larger than the source string(s); this protects
+ against buffer overflows caused outside of CUPS...
+ - Changed all strcpy's to strncpy's between local and
+ global variables, even if the destination buffer is
+ larger than the source string; this protects
+ against buffer overflows caused outside of CUPS...
+ - The CUPS certificate functions didn't use the
+ CUPS_SERVERROOT environment variable when set.
+ - The directory services code was copying instead of
+ comparing the remote printer info, resulting in
+ unnecessary updates of the printer attributes for
+ remote printers.
+ - Added new mime.types rules to allow automatic raw
+ printing of PCL and ESC/P files; PJL headers are
+ parsed to differentiate between PostScript and
+ PCL job files. This should eliminate a lot of
+ the reports of SAMBA printing problems due to
+ the missing "-oraw" or "-l" options.
+ - The mimeLoadType() function didn't handle the
+ 3-argument contains() function.
+ - The LoadPPDs() function in the scheduler didn't
+ properly set the alloc_ppds variable or handle a PPD
+ database containing 0 printers.
+ - The scheduler FindAvailablePrinter() function didn't
+ use the same queuing logic as the CheckJobs()
+ function. This caused classes to stall if a remote
+ printer was always busy.
+ - Jobs are now assigned to printers in a class
+ round-robin style. This should prevent the first
+ server in the class from bearing the brunt of the
+ jobs.
+ - The scheduler's LoadAllJobs() function didn't always
+ restore remote printers for queued jobs on startup.
+ - The serial backend didn't support the higher baud
+ rates with the old termios interface. It now supports
+ 57600 and 115200 baud.
+ - The serial backend now supports different types of
+ flow control; previously it ignored the flow=XYZ
+ option in the device URI.
+ - The serial backend now supports DTR/DSR flow control,
+ which is popular on dot-matrix printers (access with
+ "flow=dtrdsr" in the device URI)
+ - Added new job-originating-host-name attribute for
+ jobs. The new attribute provides the hostname or
+ IP address of the machine that submitted the job.
+ - The set-job-attributes code no longer allows read-only
+ job attributes to be changed.
+ - Expanded the click area for the navigation bar in the
+ web interface.
+ - Updated the lp and cancel commands to support all of
+ the Solaris print options (some are simply ignored
+ since they do not map)
+ - Updated the scheduler to limit the number of file
+ descriptors to the maximum select() set size. This
+ was causing problems on Solaris systems where the
+ max FD count was increased beyond 1024.
+ - The scheduler's LoadDevices() function was getting
+ interrupted by the SIGCHLD signal handler; now ignore
+ child signals while loading devices.
+ - Added quota and allow/deny user support for printers
+ and classes.
+ - Removed black/CMY adjustment code from the PS and
+ image file RIPs; it was interfering with some CUPS
+ driver dithering code.
+ - The lpc program stopped listing the queue statuses
+ after the first active printer.
+ - The cups-lpd program used an output format that the
+ Solaris printing system did not understand.
+ - Updated the lpq program to use the Solaris format
+ except under Tru64 UNIX.
+ - Some DEC PPD files incorrectly use "Off" for the null
+ value in UI constraints. Added "Off" to the list of
+ accepted null values.
+ - Changed the *BSD define constants to __*BSD__ in all
+ of the backends.
+ - Added support for "lpstat printername", which is an
+ undocumented feature in Solaris.
+ - The HP-GL/2 filter now only sets the plot size if it
+ is set in the plot file.
+ - The lpmove command wasn't sending the requesting
+ user name, causing it to always fail.
+ - Updated the cupsTempFile() code to use GetTempPath()
+ under Windows.
+ - The cups-lpd mini-daemon didn't limit the number of
+ data files accepted, didn't use cupsTempFile(),
+ didn't handle control file job information in any
+ order, and didn't free job options after printing
+ a file.
+ - The scheduler copy_banner() function did not
+ explicitly set the owner and permissions of the banner
+ files, which could prevent the banner pages from
+ printing on some systems.
+ - The lpstat program wasn't listing remote classes.
+ - The scheduler did not verify that the printer-uri
+ attribute was specified in all requests that required
+ it.
+
+
+CHANGES IN CUPS v1.1.4
+
+ - Makefile and configure script fixes.
+ - **** Changed the default Printcap setting **** to
+ /etc/printcap. There are just too many people asking
+ why application XYZ doesn't see their printers!
+ - The web admin interface now displays an error if it
+ can't get the list of printer drivers from cupsd.
+ - The IPP backend was putting the copies option before
+ the other job options were set. This caused the IPP
+ request to contain attribute groups in the wrong
+ order, which prevented remote printing.
+ - Added checks in scheduler to free memory used for
+ IPP requests and language information when closing
+ a client connection.
+ - Fixed the duplex option in the HP LaserJet driver. It
+ should now work with all LaserJet printers (and
+ compatibles)
+ - The add-printer web interface didn't initialize the
+ "old info" data pointer, which caused random crashes
+ on many OS's.
+ - Fixed many page sizes defined in the Level 1
+ compatibility file "gs_statd.ps" to match reality.
+ - Fixed another bug in the setpagedevice "code" in
+ Ghostscript. It should now accept all standard
+ Adobe attributes on all platforms.
+ - Fixed pstoraster so that it reallocates memory for
+ color depth changes as well as size/resolution
+ changes. This removes an ordering constraint on
+ the color, page size, and resolution options in
+ PPD files.
+ - The IPP backend didn't use the job's character set
+ when the destination printer supported it. This
+ caused problems when printing text files to other
+ CUPS servers.
+ - Updated the logic used to determine when to rebuild
+ the PPD file database. The scheduler now checks the
+ dates and the number of PPD files (was just checking
+ the dates.)
+ - Updated the ippSetCGIVars() function (used by the
+ web interfaces) to only filter valid string values.
+ - The PostScript filter was scaling 2-up pages
+ incorrectly. This caused the edges of some pages to
+ be clipped.
+
+
+CHANGES IN CUPS v1.1.3
+
+ - Makefile fixes.
+ - RPM spec file changes.
+ - Documentation updates.
+ - Enabled pstoraster debug messages for everything
+ (only logged when LogLevel set to "debug"...)
+ - Changed the Input/OutputAttributes fix in
+ pstoraster so that it works on all platforms.
+ - The HP-GL/2 filter didn't set the right green
+ color value in encoded polylines or text.
+ - Updated the "fitplot" code to handle plot sizes
+ specified as "PSwidth,length" and "PSlength,width".
+ - Updated the Linux parallel and USB backends to open
+ the device files prior to looking in /proc for
+ autoprobe info. This makes sure that loadable device
+ driver modules are in fact loaded...
+ - Added new FilterLimit directive to limit the number
+ of processing jobs/filters on a system.
+ - set-job-attributes didn't change the job-state to
+ held/pending when the job-hold-until attribute was
+ specified.
+ - set-job-attributes didn't save the new job attributes.
+ - Now change the "requesting-user-name" attribute in
+ requests from remote systems to "remroot" when an
+ unauthenticated "root" user is sent. This can be
+ changed using the new RemoteRoot directive in
+ cupsd.conf.
+ - The cancel-job, hold-job, release-job, and restart-job
+ operations didn't log the authenticated username.
+ - The cups-lpd mini-daemon now checks for a
+ document-format option before forcing raw mode with
+ filter mode 'l'.
+ - The cups-lpd mini-daemon now supports "-o" options
+ on the command-line (passed by inetd) to set global
+ defaults for all print queues.
+ - The pstops filter assumed that a file with a Trailer
+ comment would also have an EOF comment.
+ - Added new cupsSetPasswordCB(), cupsSetServer(),
+ cupsSetUser(), and ippSetPort() functions to better
+ support client applications (especially GUIs...)
+ - The CUPS-add-class and CUPS-add-printer operations
+ didn't reset the printer-name attribute on remote
+ print queues that had to be renamed when a local
+ printer was defined with the same name.
+ - The lpoptions command now supports a "-r" option to
+ remove options for a printer or instance.
+ - The lpadmin and admin.cgi programs no longer allow
+ class and printer names to begin with a number; this
+ caused the command-line utilities to become confused.
+ - The Linux USB backend now looks for both the parallel
+ and usblp driver names in the device list.
+ - Added a new FontPath directive to cupsd.conf, and also
+ a "--with-fontpath" option for the configure script to
+ specify alternate font paths for pstoraster.
+ - The CUPS-move-job operation didn't update the
+ job-printer-uri attribute.
+ - The scheduler only looked up printers and classes by
+ name in IPP requests, instead of using the full URI.
+ This caused problems with KUPS and friends with
+ remote printers.
+ - The scheduler now handles better localization of
+ hostnames (e.g. server is host.foo.com, remote is
+ host.subfoo.foo.com, localized is not host.subfoo...)
+ - The scheduler logging functions now use a common
+ log file checking/rotation function (courtesy of
+ Crutcher Dunnavant at Red Hat)
+ - The scheduler could accept more client connections
+ than it allocated for if more than one Port or Listen
+ line was present in cupsd.conf.
+ - Other minor scheduler performance tweeks.
+ - The lpq and lprm commands didn't support the default
+ printer set using lpoptions.
+ - The lpoptions command now supports a "-l" option to
+ list the printer-specific options and their current
+ settings.
+ - The web printer and class lists now show a link to the
+ default printer or class at the top of the page.
+ - The text filter now supports pretty printing of shell
+ and perl scripts as well as C/C++ source files.
+ - The top and bottom margins were reversed for landscape
+ text printing.
+ - The lpq and lprm commands didn't understand printer
+ instances.
+ - The scheduler only selected on the first 100 file
+ descriptors instead of the maximum file descriptor
+ limit.
+ - The scheduler client, listener, and mainline functions
+ now share code to disable and enable monitoring for
+ new client connections.
+ - The imagetoraster filter didn't support all of the
+ required pagedevice parameters.
+ - The serial backend now checks for 100 serial ports
+ under Linux.
+ - The scheduler used sscanf() to pull out the remote
+ printer location, description, and make/model strings,
+ but if any of these options was empty then sscanf()
+ would stop processing.
+ - Added "debug2" log level to provide a little less
+ verbose debugging information at the "debug" level.
+ - The scheduler would crash if you stopped a printer
+ that was currently printing a job.
+ - The scheduler incorrectly allowed jobs in the cancelled,
+ aborted, or completed state to be cancelled.
+ - The image filters did not load TIFF images properly
+ for bottom-to-top and right-to-left orientations.
+ - Added new cupsEncodeOptions() function to encode
+ CUPS options as IPP job attributes.
+ - The IPP backend, LPD mini-daemon, client commands,
+ and CUPS API did not properly encode multiple
+ option values separated by commas.
+ - Added new scheduler malloc logging in debug mode
+ (provides summary of total arena size, allocated,
+ and free bytes once a minute)
+ - The EPM-based distributions didn't install the
+ correct symlinks for a few man pages.
+ - Fixed a memory leak in the scheduler - wasn't
+ freeing old filters when deleting or renaming
+ printers.
+ - The scheduler now queries the primary IP address
+ for the name of the server and maps any incoming
+ requests from that address to the server name.
+ This fixes web admin mapping problems from
+ server.domain.com to localhost.
+ - The web printer modify interface now remembers
+ the previous device and driver settings (except
+ for serial ports.)
+ - The job-k-octets attribute is now stored as part of
+ the job attributes; this preserves the information
+ after a job is completed when job file history is
+ turned off.
+ - Dropped option sub-group parsing code for the moment,
+ since many Xerox PPD files abuse this feature in PPD
+ files and don't follow the hierarchy rules.
+ - Added new wrapper code around options so that duplex
+ options for some HP printers don't prevent prints.
+ - Added support for Digital UNIX/Tru64 UNIX/OSF/1 format
+ for "lpstat -v" output.
+ - Now show the URI for remote printers instead of
+ /dev/null in "lpstat -v" output.
+ - Creating classes and adding printers to a class with
+ the lpadmin command didn't work.
+ - The banner pages and test page should now format
+ correctly in both portrait and landscape orientations.
+ - Updated banner page substitution so that { can appear
+ by itself without quoting.
+
+
+CHANGES IN CUPS v1.1.2
+
+ - Makefile/configure fixes
+ - RPM spec file and EPM list file fixes
+ - The cupsTempFile() function now uses a different
+ algorithm for generating temp files and "reserves"
+ them to avoid possible security exploitation.
+ - Now use /dev/random (if available) to seed the random
+ number generator for certificates.
+ - The /var/spool/cups and /var/spool/cups/tmp directories
+ were incorrectly owned by root; they are now owned by
+ the filter user, typically "lp".
+ - The scheduler now resets the permissions on the spool
+ and temp directories as needed to match the filter
+ user.
+ - Now expose ppdCollect() as an externally callable
+ function.
+ - The image filters now support filtering from the
+ standard input.
+ - The imagetoraster filter now collects all printer
+ options and job patch files and applies them to the
+ page header as needed.
+ - Added format and banner options to LPD backend.
+ - The send-document operation didn't start a job
+ immediately when last-document was true.
+ - The set-job-attributes operation didn't correctly
+ replace the current job-hold-until value.
+ - Removed the option wrapper code from ppdEmit() and
+ friends since it caused problems with Ghostscript
+ and many PS printers.
+ - Was setting TZ environment variable twice for job
+ filters.
+ - Added syslog logging in cups-lpd to aide in
+ debugging problems.
+ - The HP-UX parallel port backend did not list the
+ available parallel ports on some systems (printf
+ calling problem...)
+ - The lp and lpr commands overrode user options if
+ -d/-P were specified after -o.
+ - The scheduler would crash with a */* filter.
+ - Added support for a "default" filter for unknown file
+ types. The example provided in the mime.types and
+ mime.convs file prints unknown files as if "-oraw" was
+ specified for the job. This functionality is disabled
+ by default.
+ - The "compatibility" mode fix for older backends did not
+ work for smbspool. Added a workaround for it.
+ - The HP-GL/2 filter didn't perform the right pen scaling
+ with some files and the "fitplot" option.
+ - New Software Performance Specification document that
+ describes the memory, disk, and CPU usage of all the
+ CUPS software.
+
+
+CHANGES IN CUPS v1.1.1
+
+ - The pstoraster Makefile still referenced one of the
+ old PDF filter files.
+ - The filter Makefile used INSTALL_DATA instead of
+ INSTALL_LIB to install the CUPS image library.
+ - The administration CGI didn't work properly with
+ network devices.
+ - The BrowseACL variable was not updated after the
+ cupsd.conf file was loaded.
+ - The lpd mini-daemon didn't support printer instances.
+ - Now use a default umask of 077 for child processes.
+ - Now put temp files in /var/spool/cups/tmp for child
+ processes and the root user, unless TMPDIR or TempDir
+ is defined otherwise.
+ - cupsGetPPD() no longer uses easy-to-guess filenames.
+ - The CUPS-Delete-Class and CUPS-Delete-Printer
+ operations now save classes.conf file as needed.
+ - The lppasswd command wouldn't add a user.
+ - The ppdOpen() function could cause a segfault if a
+ 0-length PPD file was read.
+ - The image filters were not handling images with
+ different X and Y resolutions properly.
+ - The imagetoraster filter defaulted to RGB output
+ instead of black output like pstoraster.
+ - The pstops filter didn't handle binary data properly.
+ - The pstops filter didn't handle copies properly for
+ PS files lacking DSC comments.
+ - The pstops filter now appends %%EOF to the end of
+ documents if they don't have it.
+ - The cupsGetPPD() function didn't work with remote
+ printers lacking the @server in the name.
+ - The configure script didn't work right when only
+ --prefix was specified.
+ - The ppdEmit() code now wraps all printer commands so
+ that buggy PostScript printers will still print a file
+ after receiving an option that isn't available.
+ - Fixed the DeskJet margin bug, and disabled 600dpi
+ color mode until it can be fixed.
+ - The cupsAddDest() function didn't sort instances
+ correctly in all cases.
+ - The time-at-xyz attributes now expand to the date and
+ time in banner files.
+
+
+CHANGES IN CUPS v1.1
+
+ - Documentation updates.
+ - Configuration script updates.
+ - Didn't map charset and language value strings to lowercase
+ and _ to - as required by SLP and IPP.
+ - ppdLoadXYZ() didn't add the list of available fonts to the
+ ppd_file_t structure.
+ - The text filter common code was freeing the PPD file data
+ before it was used.
+ - The text filter now embeds missing fonts.
+ - The CGI interface now maps local access to the server to
+ the localhost address.
+ - The HP-GL/2 filter didn't use the specified (or default)
+ color ranges, resulting in strange colors.
+ - The HP-GL/2 filter didn't default to no input window, which
+ caused unnecessary clipping of plots.
+ - Integrated Xpdf's pdftops filter into CUPS, which is a
+ lightweight and reliable replacement for Ghostscript's
+ PDF support.
+ - Removed all PDF support from Ghostscript.
+ - Updated HP driver to set top margin; this seems to fix
+ the offset problem seen on HP DeskJet printers.
+ - Fixed dependencies on the ZLIB and JPEG libraries in
+ pstoraster.
+ - The lpr command wasn't using the lpoptions defined by
+ the user.
+ - The lpr command would segfault if the CUPS server was
+ not running.
+ - The top-level makefile was not installing the CUPS
+ initialization script. It now does so if it sees there
+ is an init.d directory in /sbin, /etc/rc.d, or /etc.
+ - "lpstat -v all" didn't work.
+ - pstoraster would crash on some platforms doing the
+ setpagedevice operator.
+ - The web administration interface now allows you to set
+ the default banner pages.
+ - Images can now be positioned on the page using the new
+ "position" option.
+ - The AccessLog, ErrorLog, and PageLog directives now
+ support "%s" to insert the server name.
+ - Added a new BrowseShortNames directive to allow for
+ short remote printer names ("printer" instead of
+ "printer@server") when possible.
+ - The scheduler could crash if given an invalid PPD file
+ with no PageSize attributes.
+ - Updated the serial, parallel, and usb backends to do
+ multiple writes and ignore ioctl() errors as needed;
+ this should fix problems with serial printing on old
+ serial drivers and with the UltraSPARC parallel port
+ driver under Solaris 2.7.
+ - Now propagate LD_LIBRARY_PATH to child processes from
+ cupsd.
+ - New DataDir directive for installing in alternate
+ locations.
+ - New CUPS_SERVERROOT and CUPS_DATADIR environment
+ variables to specify installation directories as
+ needed.
+ - Queued remote jobs recreate remote printers as needed
+ when the scheduler is started.
+ - Deleting a printer also purges all jobs on that
+ printer.
+ - Old job and control files that don't belong to a
+ printer are automatically deleted.
+ - Wasn't updating time-at-processing and
+ time-at-completed attributes in job.
+ - Didn't send required multiple-operation-time-out
+ attribute in response to a get-printer-attributes
+ request.
+ - cups-lpd now supports options set with lpoptions.
+ - The job-hold-until attribute is now provided with all
+ jobs. For jobs that are not currently held the value
+ is "no-hold".
+ - The scheduler was not sending "unknown" values in IPP
+ responses.
+ - The lpoptions command now accumulates options from
+ previous runs rather than replacing all options for a
+ printer.
+ - The IPP backend now switches to IPP/1.0 if a 1.1
+ request fails.
+ - The lpadmin and admin.cgi programs now validate new
+ printer and class names.
+ - The access_log file now includes the number of IPP bytes
+ received in a POST request.
+
+
+CHANGES IN CUPS v1.1b5
+
+ - Documentation updates.
+ - The pstoraster filter didn't compile without the JPEG library.
+ - The cupsd server didn't support the HTTP OPTIONS request
+ method.
+ - Dropped the "CLOSE" method supported by the cupsd server.
+ (not defined in HTTP specification)
+ - Makefile/configure script fixes.
+ - Missing the job-restart template.
+ - Added IPP test suite for testing.
+ - Missing IPP documentation from binary distributions.
+ - Fixed multiple-document handling code when last-document
+ not specified.
+ - Added more checks to IPP requests to prevent bad requests
+ from getting through.
+ - Not all of the Ghostscript error output was being sent to
+ stderr.
+ - The PostScript filter now added PJL commands to set the
+ job name and display string, if supported.
+ - The scheduler would crash if the browse socket could not
+ be bound. Now disables browsing if port 631 (reserved for
+ IPP) is being used by a misbehaving daemon.
+ - The USB backend now looks for the older Linux 2.2.x USB
+ printer device filenames as well as the newer ones.
+ - The IPP backend now uses the UTF-8 charset exclusively,
+ since apparently only CUPS handles more than US-ASCII and
+ UTF-8...
+ - Wasn't quoting ( in PostScript banners...
+ - Send-document requests with no document-format attribute
+ could cause cupsd to crash.
+ - Old jobs in the spool directory might cause cupsd to
+ crash.
+ - CUPS now supports all of the recommended job-hold-until
+ keywords as well as name values of the form "HH:MM" and
+ "HH:MM:SS".
+ - Added placeholder pointer for TLS encryption to the HTTP
+ connection structure.
+ - Fixed the "fast poll" bug reported by DISA - the
+ status pipe wasn't being closed for multi-file jobs.
+ - Revamped put_params code in pstoraster to fix bitmap
+ allocation bug with FrameMaker output.
+ - Ripped out filename, etc. code from pstoraster as it
+ is a potential security hole.
+ - Added support for RIP_CACHE environment variable in the
+ new pstoraster.
+ - Fixed USB device filenames for Linux; now support new
+ pre-2.4 devices (/dev/usb/lp#) and 2.2 devices
+ (/dev/usblp#)
+ - Fixed accept-jobs crash with classes.
+ - Didn't include dot-matrix EPSON drivers in previous
+ release.
+
+
+CHANGES IN CUPS v1.1b4
+
+ - Documentation updates.
+ - Many makefile and configuration script fixes (should
+ now compile better under *BSD.)
+ - The MediaPosition attribute was being mishandled by
+ GhostScript, causing the RIP to fail whenever a paper
+ tray was selected.
+ - The scheduler now logs the final line of log information
+ from a filter, even if it doesn't end with a newline; this
+ primarily affects GhostScript error output.
+ - The scheduler was saving implicit classes, so after a few
+ restarts you'll end up with AnyPrinter, AnyAnyPrinter, etc.
+ - The JPEG autodetection didn't work with some JPEG files that
+ came from digital cameras (JPEG but not JFIF); the new
+ magic types should work with all images that the JPEG library
+ can handle.
+ - Fixed a bug in the new contains() MIME type rule that could
+ cause cupsd to crash.
+ - Switched to using strtol() in the MIME type code so that you
+ can use hex, octal, or decimal constants as desired in the
+ mime.types file.
+ - Banner files are now treated as templates, allowing any type
+ of file to be used as a banner.
+ - Added a 30-second timeout to backend device reports so that a
+ hung backend will not prevent the scheduler from starting.
+ - Backends are once again terminated when jobs are stopped; the
+ CUPS-supplied backends will stay alive until the downstream
+ filters have had a chance to clear out old page data.
+ - The charset lookup in the CUPS localization support was wrong
+ (iso8859-x instead of iso-8859-x)
+ - Changed the "cpNNNN" code page files to "windows-NNNN" to match
+ the IANA registrations.
+ - New PostScript banner pages.
+ - Added Windows BMP and Alias PIX image file support to the image
+ filter.
+ - The PNG reading coded didn't free all of its buffers.
+ - Added Digest authentication support to the client and server
+ code.
+ - Added Solaris options to System V commands.
+ - Now support the output-bin job template attribute.
+ - Now log the job-billing attribute in the page_log file, and
+ keep track of the total number of pages in the
+ job-media-sheets-completed attribute.
+ - The penwidth option is now in micrometers to support more
+ accurate width specification.
+ - The image filters now support interlaced and transparent PNG
+ files.
+ - Didn't handle Keep-Alive for HTTP/1.0 clients.
+ - The BrowsePoll support didn't handle when BrowseInterval
+ was set to 0 (now uses 30 seconds if BrowseInterval is 0)
+ - The DeskJet driver now supports 600 DPI color for printers
+ that support it.
+ - New lpinfo and lpmove commands.
+ - The lpq command now supports the Digital UNIX output format.
+ - The LPD mini-daemon now supports all required LPD operations.
+ - Implemented timeouts for multi-file documents.
+ - New cupsPrintFiles() function in the CUPS API library to
+ print multiple files using create-job and send-document
+ requests (1 job ID for multiple files)
+ - The lp command now sends multiple files as a single job,
+ matching the behavior of the System V command.
+ - The "cancel -a" command now purges job history files.
+
+
+CHANGES IN CUPS v1.1b3
+
+ - Documentation updates.
+ - The startup script redirected stderr before stdout,
+ which caused problems with some versions of Bourne
+ shell and Bash.
+ - Fixed a bug in the scheduler's PPD language reading
+ code.
+ - Fixed a bug in the scheduler's check for the
+ manufacturer in the PPD.
+ - The pstoraster filter didn't allow some input and
+ output attributes to be set.
+ - Added banner page support.
+ - Added missing PAM configuration file.
+ - Configuration script fixes for Linux and *BSD.
+ - The log file code was using the wrong sign for the
+ timezone offset.
+ - The default printcap file is now empty (no printcap
+ file is generated).
+ - The scheduler did not start jobs destined for remote
+ printers when they became available.
+ - The scheduler now sends jobs to remote printers
+ immediately. (when sending jobs to a class, the remote
+ printer is only used when it becomes available)
+ - The scheduler now supports printing of banner pages
+ via the job-sheets attribute (banner files go in
+ /usr/share/cups/banners)
+ - The cupsd process now forks itself into the background
+ (override with -f)
+ - Added several *BSD enhancements.
+ - Added UNSUPPORTED libtool option to configuration
+ script to allow the use of libtool. Note that this is
+ UNSUPPORTED by us, but added by request of the *BSD
+ folks.
+ - The parallel, serial, and usb backends now retry the
+ opening of their ports. This allows multiple print
+ queues to be associated with a single physical port,
+ and will allow CUPS to support several types of
+ parallel port auto-switches in the near future.
+ - Set-Job-Attributes now supports adding, changing, and
+ deleting job template attributes, and no longer allows
+ job-printer-uri to be set (see CUPS-Move-Job)
+ - Added CUPS-Move-Job operation to support moving of jobs.
+ - The CGI template functionality now supports multiple
+ languages (still only have templates for English)
+ - The CUPS-Get-Printers and CUPS-Get-Classes operations
+ now support filtering as defined in the IDD.
+ - The Get-Jobs, CUPS-Get-Printers, and CUPS-Get-Classes
+ operations no longer limit themselves to 1000 jobs,
+ printers, or classes (believe it or not, this is
+ needed for some sites)
+ - The web interfaces now support language-specific
+ templates.
+ - The web admin interface now supports class management.
+ - The web admin interface now shows a list of
+ manufacturers before selecting the PPD/driver for a
+ specific printer.
+ - The web admin interface now supports configuration of
+ the default printer options in the PPD file.
+ - The web interface now uses printer/class
+ authentication for the test page instead of admin
+ authentication.
+ - Updated the RPM spec file for the current release.
+ - Updated language support for Windows code pages.
+ - 8-bit character set files can now use multiple fonts
+ (needed for Arabic, Greek, Hebrew, etc.)
+ - Added basic right-to-left text support in the text
+ filter.
+ - The POSIX locale now uses ISO-8859-1 instead of
+ US-ASCII.
+ - Fixed PDF printing problems.
+ - Fixed PostScript RIP page device dictionary elements
+ that weren't getting passed in cups_get_params().
+ - Added a new "contains" rule for the magic file typing.
+ - The "printable" rule now accepts characters from 128 to 255
+ (needed for Microsoft character sets)
+ - Added support for ~/.cupsrc as well as /etc/cups/client.conf
+ so that the default server can be configured on a per-user
+ basis without environment variables.
+ - Added LPD mini-daemon to support incoming LPD jobs.
+
+
+CHANGES IN CUPS v1.1b2
+
+ - Documentation updates.
+ - The lp command didn't always load the user-defined
+ destinations, preventing it from seeing the default
+ printer.
+ - Many configure script and makefile fixes.
+ - The Microsoft code page files were missing from the
+ distribution.
+ - Added a workaround for the HP IPP client (which is sending
+ an invalid printer-uri in requests)
+ - Fixed the encoding of text-with-language and name-with-language
+ to match the IPP spec.
+ - Added support for unknown value tags in the IPP routines
+ (previously they would be ignored)
+ - Integrated GNU GhostScript 5.50 into the pstoraster filter.
+ - Client hostname resolution was broken on little-endian
+ machines.
+ - Now look at client.conf file for client's default server
+ and printer.
+ - The cupsServer() function did not close the client.conf file
+ if it contained a ServerName directive.
+ - Added BrowseAllow, BrowseDeny, BrowseOrder, BrowsePoll, and
+ BrowseRelay directives.
+ - BrowseInterval 0 disables advertising of local printers, but
+ still receives information on remote printers.
+ - New browse polling daemon (for polling servers on different
+ networks)
+ - New PPD cache file for faster startup times with large numbers
+ of PPD files.
+ - The Host: field was incorrectly required for HTTP/1.0 clients.
+ - New set-job-attributes operation now supported.
+ - The mime_load_types() and mime_load_convs() functions did not
+ close their input files.
+
+
+CHANGES IN CUPS v1.1b1
+
+ - NEW web-based administration interface.
+ - NEW EPSON printer drivers.
+ - NEW user-defined printers and options.
+ - NEW persistent jobs and job history
+ - NEW IPP/1.1 support
+ - NEW template-based web interfaces.
+ - NEW CUPS-get-devices and CUPS-get-ppds operations.
+ - NEW support for create-job and send-file operations.
+ - NEW certificate-based authentication for local
+ administration.
+ - NEW USB backend.
+ - The lpr command now produces human-readable error messages.
+ - The lpq command now produces BSD standard format output
+ instead of OSF/1 output. This should resolve the SAMBA
+ print queue problems that have been reported.
+ - The IPP backend did not always detect when the "raw" option
+ was being used.
+ - The "lpstat -p" command would stop after the first active
+ printer.
+ - The "lpstat -v" command would stop before the first remote
+ printer.
+
+
+CHANGES IN CUPS v1.0.5
+
+ - The HP-GL/2 filter did not correctly set the pen color
+ for pens other than #1.
+ - The scheduler would only accept 26 simultaneous jobs
+ under some OS releases (mkstemp() limitation.) It now
+ handles up to 2^32 simultaneous jobs.
+ - The PostScript filter loaded the printer's PPD file
+ twice.
+ - The PAM authentication code now uses pam_strerror() to
+ provide a textual error message in the error_log file.
+ - The scheduler now copies PPD and interface script
+ files instead of moving them; this fixes installations
+ with a separate requests directory.
+ - The PostScript RIP did not generate correct 6-color
+ output.
+ - Several filters were marking PPD options twice when
+ they didn't need to.
+ - The scheduler did not save the printer or class state
+ after an accept-jobs or reject-jobs operation.
+ - The cupsGetDefault() function now ignores the PRINTER
+ environment variable if it is set to "lp".
+ - New ippErrorString() function to get textual error
+ messages.
+ - Better error reporting in the System V commands.
+ - The lpadmin and lpstat commands always tried to
+ connect to the default server.
+ - The text filter didn't load the charset files from the
+ correct location.
+ - Wasn't sending a WWW-Authenticate: field to HTTP
+ clients when authentication was required.
+ - httpSeparate() didn't always set the default port
+ number for known methods.
+ - The HP-GL/2 filter now looks for "PSwidth,length"
+ instead of (the correct) "PSlength,width" as
+ documented by HP. It appears that many major CAD
+ applications are broken and this change allows the
+ auto-rotation to work with them.
+ - The IPP "printer-resolution" option was not being
+ translated.
+ - The charset files did not include the Microsoft
+ "standard" characters from 128 to 159 (unused by the
+ ISO-8859-x charsets)
+ - The scheduler was chunking the Content-Type field from
+ CGI programs; this problem was most noticeable with
+ Microsoft Internet Explorer 5.
+ - By popular demand, the printers, jobs, and classes
+ CGIs no longer force a reload of the page every 10/30
+ seconds.
+ - The scheduler incorrectly required that the IPP client
+ provide a document-format attribute for the
+ validate-job operation.
+ - Clients that sent bad IPP requests without the
+ required attributes-natural-language and
+ attributes-charset attributes would crash the
+ scheduler.
+
+
+CHANGES IN CUPS v1.0.4
+
+ - Documentation updates.
+ - Jobs would get stuck in the queue and wouldn't print
+ until you enabled the queue.
+ - The lp and lpr commands now catch SIGHUP and SIGINTR.
+ - The lp and lpr commands now use sigaction or sigset
+ when available.
+ - CUPS library updates for WIN32/OS-2
+
+
+CHANGES IN CUPS v1.0.3
+
+ - Documentation updates.
+ - The lpq man page was missing.
+ - The configure script was not properly detecting the
+ image libraries.
+ - The top-level makefile was calling "make" instead of
+ "$(MAKE)".
+ - PostScript filter fixes for number-up, OutputOrder,
+ and %Trailer.
+ - The imagetops filter didn't end the base-85 encoding
+ properly if the image data was not a multiple of 4
+ bytes in length.
+ - The imagetoraster filter didn't generate good banded
+ RGB or CMY data (was dividing the line width by 4
+ instead of 3...)
+ - The imagetoraster filter now records the bounding
+ box of the image on the page.
+ - The CUPS image library cache code wasn't working as
+ designed; images larger than the maximum RIP cache
+ would eventually thrash using the same cache tile.
+ - The CUPS image library TIFF loading code didn't
+ handle unknown resolution units properly; the fixed
+ code uses a default resolution of 128 PPI.
+ - cupsGetClasses() and cupsGetPrinters() did not free
+ existing strings if they ran out of memory.
+ - The scheduler logs incorrectly contained 3 digits for
+ the timezone offset instead of 4.
+ - The scheduler now does a lookup for the default user
+ and group ID; the previous hardcoded values caused
+ problems with the LPD backend.
+ - The cancel-job operation now allows any user in the
+ system group to cancel any job.
+ - The cancel-job operation stopped the print queue if
+ the job was being printed.
+ - Now only stop printers if the backend fails. If the
+ filter fails then the failure is noted in the
+ error_log and printing continues with the next file in
+ the queue.
+ - Now log whether a filter fails because of a signal
+ or because it returned a non-zero exit status.
+ - The root user now always passes the system group test.
+ - Printers with an interface script and remote printers
+ and classes didn't have a printer-make-and-model
+ attribute.
+ - Added logging of lost/timed-out remote printers.
+ - The HP-GL/2 filter was scaling the pen width twice.
+ - Updated the HP-GL/2 filter to use a single SP (Set
+ Pen) procedure. This makes the output smaller and is
+ more appropriate since the filter keeps track of the
+ pen states already.
+ - The scheduler didn't handle passwords with spaces.
+ - The IPP backend now does multiple copies and retries
+ if the destination server requires it (e.g. HP
+ JetDirect.)
+ - The disable command didn't implement the "-c" option
+ (cancel all jobs.)
+ - Changed the CMYK generation function for the image file
+ and PostScript RIPs.
+ - The lp command didn't support the "-h" option as
+ documented.
+ - The AppSocket, IPP, and LPD backends now retry on all
+ network errors. This should prevent stopped queues
+ caused by a printer being disconnected from the
+ network or powered off.
+ - The scheduler now restarts a job if the corresponding
+ printer is modified.
+ - The image RIPs now rotate the image if needed to fit
+ on the page.
+
+
+CHANGES IN CUPS v1.0.2
+
+ - The HP-GL/2 filter didn't always scale the output
+ correctly.
+ - The HP-GL/2 filter now supports changing the page size
+ automatically when the "fitplot" option is not used.
+ - The cancel-job operation was expecting a resource name
+ of the form "/job/#" instead of "/jobs/#"; this
+ prevented the cancel and lprm commands from working.
+ - The backends didn't log pages when files were printed
+ using the "-oraw" option.
+ - The authorization code did not work with the Slackware
+ long shadow password package because its crypt() can
+ return NULL.
+ - The chunking code didn't work for reading the response
+ of a POST request.
+ - cupsGetPPD() now does authentication as needed.
+ - The N-up code in the PostScript filter didn't work
+ with some printers (grestoreall would restore the
+ default blank page and device settings).
+ - The N-up code in the PostScript filter didn't scale
+ the pages to fit within the imageable area of the
+ page.
+ - Wasn't doing an fchown() on the request files. This
+ caused problems when the default root account group
+ and CUPS group were not the same.
+
+
+CHANGES IN CUPS v1.0.1
+
+ - Documentation updates.
+ - Fixed a bunch of possible buffer-overflow conditions.
+ - The scheduler now supports authentication using PAM.
+ - Updated the Italian message file.
+ - httpEncode64() didn't add an extra "=" if there was
+ only one byte in the last three-byte group.
+ - Now drop any trailing character set from the locale
+ string (e.g. "en_US.ISO_8859-1" becomes "en_US")
+ - Fixed "timezone" vs "tm_gmtoff" usage for BSD-based
+ operating systems.
+ - Updated IPP security so that "get" operations can be
+ done from any resource name; this allows the CGIs to
+ work with printer authentication enabled so long as
+ authentication isn't turned on for the whole "site".
+ - The IPP code didn't properly handle the "unsupported"
+ group; this caused problems with the HP JetDirect since
+ it doesn't seem to support the "copies" attribute.
+ - The HTTP chunking code was missing a CR LF pair at the
+ end of a 0-length chunk.
+ - The httpSeparate() function didn't handle embedded
+ usernames and passwords in the URI properly.
+ - Doing "lpadmin -p printer -E" didn't restart printing
+ if there were pending jobs.
+ - The cancel-job operation now requires either a
+ requesting-user-name attribute or an authenticated
+ username.
+ - The add-printer code did not report errors if the
+ interface script or PPD file could not be renamed.
+ - Request files are now created without world read
+ permissions.
+ - Added a cupsLastError() function to the CUPS API to
+ retrieve the IPP error code from the last request.
+ - Options are now case-insensitive.
+ - The lpq command now provides 10 characters for the
+ username instead of the original (Berkeley standard)
+ 7.
+ - The cancel command needed a local CUPS server to work
+ (or the appropriate ServerName in cupsd.conf)
+ - The cancel and lprm commands didn't report the IPP
+ error if the job could not be cancelled.
+ - The lp and lpr commands didn't intercept SIGTERM to
+ remove temporary files when printing from stdin.
+ - The lp and lpr commands didn't report the IPP error if
+ the job could not be printed.
diff --git a/CREDITS.txt b/CREDITS.txt
new file mode 100644
index 000000000..71bad1486
--- /dev/null
+++ b/CREDITS.txt
@@ -0,0 +1,26 @@
+CREDITS.txt - 01/27/2000
+------------------------
+
+Few projects are completed by one person, and CUPS is no exception. We'd
+like to thank the following individuals for their contributions:
+
+ Nathaniel Barbour - Lots of testing and feedback.
+ N. Becker - setsid().
+ Jean-Eric Cuendet - GhostScript filters for CUPS.
+ Van Dang - HTTP and IPP policeman.
+ Dr. ZP Han - setgid()/setuid().
+ Guy Harris - *BSD shared libraries and lots of other fixes.
+ Wang Jian - CUPS RPM corrections.
+ Roderick Johnstone - Beta tester of the millenium.
+ Sergey V. Kovalyov - ESP Print Pro and CUPS beta tester.
+ Mark Lawrence - Microsoft interoperability testing.
+ Jason McMullan - Original CUPS RPM distributions.
+ Wes Morgan - *BSD fixes.
+ Ulrich Oldendorf - German locale.
+ Petter Reinholdtsen - HP-UX compiler stuff.
+ Stuart Stevens - HP JetDirect IPP information.
+ Kiko - Bug fixes.
+ L. Peter Deutsch - MD5 code.
+
+If I've missed someone, please let me know by sending an email to
+"mike@easysw.com".
diff --git a/ENCRYPTION.txt b/ENCRYPTION.txt
new file mode 100644
index 000000000..5ec656ea5
--- /dev/null
+++ b/ENCRYPTION.txt
@@ -0,0 +1,138 @@
+ENCRYPTION - CUPS v1.1.7 - 02/21/2001
+-------------------------------------
+
+This file describes the encryption support provided by CUPS.
+
+WARNING: CLIENTS CURRENTLY TRUST ALL CERTIFICATES FROM SERVERS.
+This makes the CUPS client applications vulnerable to "man in
+the middle" attacks, so we don't recommend using this to do
+remote administration over WANs at this time.
+
+Future versions of CUPS will keep track of server certificates
+and provide a callback/confirmation interface for accepting new
+certificates and warning when a certificate has changed.
+
+
+LEGAL STUFF
+
+BEFORE USING THE ENCRYPTION SUPPORT, PLEASE VERIFY THAT IT IS
+LEGAL TO DO SO IN YOUR COUNTRY. CUPS by itself doesn't include
+any encryption code, but it can link against the OpenSSL library
+which does.
+
+
+OVERVIEW OF ENCRYPTION SUPPORT IN CUPS
+
+CUPS supports SSL/2.0, SSL/3.0, and TLS/1.0 encryption using
+keys as large as 128-bits. Encryption support is provided via
+the OpenSSL library and some new hooks in the CUPS code.
+
+CUPS provides support for dedicated (https) and "upgrade" (TLS)
+encryption of sessions. The "HTTP Upgrade" method is described
+in RFC 2817; basically, the client can be secure or unsecure,
+and the client or server initiates an upgrade to a secure
+connection via some new HTTP fields and status codes. The HTTP
+Upgrade method is new and no browsers we know of support it yet.
+Stick with "https" for web browsers.
+
+The current implementation is very basic. The CUPS client
+software (lp, lpr, etc.) uses encryption as requested by the
+user or server.
+
+The user can specify the "-E" option with the printing commands
+to force encryption of the connection. Encryption can also be
+specified using the Encryption directive in the client.conf file
+or in the CUPS_ENCRYPTION environment variable:
+
+ Never
+
+ Never do encryption.
+
+ Always
+
+ Always do SSL/TLS encryption using the https scheme.
+
+ IfRequested
+
+ Upgrade to TLS encryption if the server asks for it.
+ This is the default setting.
+
+ Required
+
+ Always upgrade to TLS encryption as soon as the
+ connection is made. This is different than the "Always"
+ mode above since the connection is initially unsecure
+ and the client initiates the upgrade to TLS encryption.
+ (same as using the "-E" option)
+
+These keywords are also used in the cupsd.conf file to secure
+particular locations. To secure all traffic on the server, listen
+on port 443 (https port) instead of port 631 and change the "ipp"
+service listing (or add it if you don't have one) in /etc/services
+to 443. To provide both secure and normal methods, add a line
+reading:
+
+ SSLPort 443
+
+to /etc/cups/cupsd.conf.
+
+
+BEFORE YOU BEGIN
+
+You'll need the OpenSSL library from:
+
+ http://www.openssl.org
+
+
+CONFIGURING WITH ENCRYPTION SUPPORT
+
+Once you have the OpenSSL library installed, you'll need to
+configure CUPS to use it with the "--enable-ssl" option:
+
+ ./configure --enable-ssl
+
+If the OpenSSL stuff is not in a standard location, make sure to
+define the CFLAGS, CXXFLAGS, and LDFLAGS environment variables
+with the appropriate compiler and linker options first.
+
+
+GENERATING A SERVER CERTIFICATE AND KEY
+
+The following OpenSSL command will generate a server certificate
+and key that you can play with. Since the certificate is not
+properly signed it will generate all kinds of warnings in
+Netscape and MSIE:
+
+ openssl req -new -x509 -keyout /etc/cups/ssl/server.key \
+ -out /etc/cups/ssl/server.crt -days 365 -nodes
+
+ chmod 600 /etc/cups/ssl/server.*
+
+The "-nodes" option prevents the certificate and key from being
+encrypted. The cupsd process runs in the background, detached
+from any input source; if you encrypt these files then cupsd
+will not be able to load them!
+
+Send all rants about non-encrypted certificate and key files to
+/dev/null. It makes sense to encrypt user files, but not for
+files used by system processes/daemons...
+
+
+REPORTING PROBLEMS
+
+If you have problems, READ THE DOCUMENTATION FIRST! If the
+documentation does not solve your problems please send an email
+to "cups-support@cups.org". Include your operating system and
+version, compiler and version, and any errors or problems you've
+run into. The "/var/log/cups/error_log" file should also be sent,
+as it often helps to determine the cause of your problem.
+
+If you are running a version of Linux, be sure to provide the
+Linux distribution you have, too.
+
+Please note that the "cups-support@cups.org" email address goes
+to the CUPS developers; they are busy people, so your email may
+go unanswered for days or weeks. In general, only general build
+or distribution problems will actually get answered - for
+end-user support see the "README.txt" for a summary of the
+resources available.
diff --git a/INSTALL.txt b/INSTALL.txt
new file mode 100644
index 000000000..c50d4edd6
--- /dev/null
+++ b/INSTALL.txt
@@ -0,0 +1,190 @@
+INSTALL - CUPS v1.1.16 - 07/02/2002
+-----------------------------------
+
+This file describes how to compile and install CUPS from source
+code. For more information on CUPS see the file called
+"README.txt". A complete change log can be found in
+"CHANGES.txt".
+
+**** IF YOU HAVE A NON-POSTSCRIPT PRINTER, YOU WILL ALSO ****
+**** NEED TO INSTALL ESP GHOSTSCRIPT OR A PATCHED VERSION ****
+**** OF THE STANDARD GHOSTSCRIPT RELEASES. ****
+
+
+BEFORE YOU BEGIN
+
+You'll need ANSI-compliant C and C++ compilers, plus a make
+program and Bourne shell. The GNU compiler tools work well -
+we've tested the current CUPS code against GCC 2.95.x with
+excellent results.
+
+The makefiles used by the project should work with all versions
+of make. We've tested them with GNU make as well as the make
+programs shipped by Compaq, HP, SGI, and Sun. FreeBSD users
+should use GNU make (gmake).
+
+Besides these tools you'll want the following libraries:
+
+ - JPEG 6b or higher
+ - PNG 1.0.6 or higher
+ - TIFF 3.4 or higher
+ - ZLIB 1.1.3 or higher
+
+CUPS will compile and run without these, however you'll miss out on
+many of the features provided by CUPS.
+
+Also, please note that CUPS no longer includes the Ghostscript-
+based pstoraster filter. You *must* download Ghostscript
+separately and patch it using the files in the pstoraster
+subdirectory, or download the ESP Ghostscript distribution from
+the CUPS web site. For more information see the README file in
+the pstoraster subdirectory.
+
+
+COMPILING FROM CVS
+
+The CUPS CVS repository doesn't hold a copy of the pre-built
+configure script. You'll need to run the GNU autoconf software
+(2.52 or higher) before compiling the software from CVS:
+
+ autoconf ENTER
+
+
+CONFIGURATION
+
+CUPS uses GNU autoconf, so you should find the usual "configure"
+script in the main CUPS source directory. To configure CUPS for
+your system, type:
+
+ ./configure ENTER
+
+The default installation will put the CUPS software in the
+"/etc", "/usr", and "/var" directories on your system, which
+will overwrite any existing printing commands on your system.
+Use the "--prefix" option to install the CUPS software in
+another location:
+
+ ./configure --prefix=/some/directory ENTER
+
+If the PNG, JPEG, TIFF, and ZLIB libraries are not installed in
+a system default location (typically "/usr/include" and
+"/usr/lib") you'll need to set the CFLAGS, CXXFLAGS, DSOFLAGS,
+and LDFLAGS environment variables prior to running configure:
+
+ setenv CFLAGS "-I/some/directory" ENTER
+ setenv CXXFLAGS "-I/some/directory" ENTER
+ setenv DSOFLAGS "-L/some/directory" ENTER
+ setenv LDFLAGS "-L/some/directory" ENTER
+ ./configure ... ENTER
+
+or:
+
+ CFLAGS="-I/some/directory"; export CFLAGS ENTER
+ CXXFLAGS="-I/some/directory"; export CXXFLAGS ENTER
+ DSOFLAGS="-L/some/directory"; export DSOFLAGS ENTER
+ LDFLAGS="-L/some/directory"; export LDFLAGS ENTER
+ ./configure ... ENTER
+
+To enable support for encryption, you'll also want to add the
+"--enable-ssl" option:
+
+ ./configure --enable-ssl
+
+SSL and TLS support require the OpenSSL library, available at:
+
+ http://www.openssl.org
+
+If the OpenSSL header files and libraries are not in a standard
+location, specify the locations of these files using the
+--with-openssl-includes and --with-openssl-libs directives:
+
+ ./configure --enable-ssl \
+ --with-openssl-includes=/foo/bar/include \
+ --with-openssl-libs=/foo/bar/lib
+
+See the file "ENCRYPTION.txt" for information on using the
+encryption support in CUPS.
+
+Once you have configured things, just type:
+
+ make ENTER
+
+or if you have FreeBSD, NetBSD, or OpenBSD type:
+
+ gmake ENTER
+
+to build the software.
+
+
+INSTALLING THE SOFTWARE
+
+Once you have built the software you need to install it. The
+"install" target provides a quick way to install the software on
+your local system:
+
+ make install ENTER
+
+or for FreeBSD, NetBSD, or OpenBSD:
+
+ gmake install ENTER
+
+You can also build binary packages that can be installed on other
+machines using the RPM spec file ("cups.spec") or EPM list file
+("cups.list"). The latter also supports building of binary RPMs,
+so it may be more convenient to use - we use EPM to build all of
+our binary distributions.
+
+You can find the RPM software at:
+
+ http://www.rpm.org
+
+The EPM software is at:
+
+ http://www.easysw.com/epm/
+
+
+CREATING BINARY DISTRIBUTIONS WITH EPM
+
+The top level makefile supports generation of many types of binary
+distributions using EPM. To build a binary distribution type:
+
+ make <format> ENTER
+
+or
+
+ gmake <format> ENTER
+
+for FreeBSD, NetBSD, and OpenBSD. The <format> target is one of
+the following:
+
+ epm - Builds a portable shell script and tar file based
+ distribution. This format will also backup your
+ existing printing system if you decide to remove
+ CUPS at some future time.
+ aix - Builds an AIX binary distribution.
+ bsd - Builds a *BSD binary distribution.
+ deb - Builds a Debian binary distribution.
+ depot - Builds a HP-UX binary distribution.
+ pkg - Builds a Solaris binary distribution.
+ rpm - Builds a RPM binary distribution.
+ tardist - Builds an IRIX binary distribution.
+
+
+REPORTING PROBLEMS
+
+If you have problems, READ THE DOCUMENTATION FIRST! If the
+documentation does not solve your problems please send an email
+to "cups-support@cups.org". Include your operating system and
+version, compiler and version, and any errors or problems you've
+run into. The "/var/log/cups/error_log" file should also be sent,
+as it often helps to determine the cause of your problem.
+
+If you are running a version of Linux, be sure to provide the
+Linux distribution you have, too.
+
+Please note that the "cups-support@cups.org" email address goes
+to the CUPS developers; they are busy people, so your email may
+go unanswered for days or weeks. In general, only general build
+or distribution problems will actually get answered - for
+end-user support see the "README.txt" for a summary of the
+resources available.
diff --git a/LICENSE.html b/LICENSE.html
new file mode 100644
index 000000000..ad9a570b0
--- /dev/null
+++ b/LICENSE.html
@@ -0,0 +1,957 @@
+<HTML>
+<HEAD>
+ <TITLE>Software License Agreement - Common UNIX Printing System</TITLE>
+</HEAD>
+
+<BODY BGCOLOR="#ffffff" TEXT="#000000">
+
+<H2 ALIGN="CENTER">Common UNIX Printing System License Agreement</H2>
+
+<P ALIGN="CENTER">Copyright 1997-2002 by Easy Software Products<BR>
+44141 AIRPORT VIEW DR STE 204<BR>
+HOLLYWOOD, MARYLAND 20636-3111 USA<BR>
+<BR>
+Voice: +1.301.373.9600<BR>
+Email: <A HREF="mailto:cups-info@cups.org">cups-info@cups.org</A><BR>
+WWW: <A HREF="http://www.cups.org">http://www.cups.org</A>
+
+<H3>Introduction</H3>
+
+<P>The Common UNIX Printing System<SUP>TM</SUP>,
+("CUPS<SUP>TM</SUP>"), is provided under the GNU General Public
+License ("GPL") and GNU Library General Public License ("LGPL"),
+Version 2, with exceptions for Apple operating systems and the
+OpenSSL toolkit. A copy of the exceptions and licenses follow
+this introduction.
+
+<P>The GNU LGPL applies to the CUPS API library, located in the
+"cups" subdirectory of the CUPS source distribution and in the
+"cups" include directory and library files in the binary
+distributions. The GNU GPL applies to the remainder of the CUPS
+distribution, including the "pdftops" filter which is based upon
+Xpdf and the CUPS imaging library.
+
+<P>For those not familiar with the GNU GPL, the license basically
+allows you to:
+
+<UL>
+
+ <LI>Use the CUPS software at no charge.</LI>
+
+ <LI>Distribute verbatim copies of the software in source
+ or binary form.</LI>
+
+ <LI>Sell verbatim copies of the software for a media
+ fee, or sell support for the software.</LI>
+
+ <LI>Distribute or sell printer drivers and filters that
+ use CUPS so long as source code is made available under
+ the GPL.</LI>
+
+</UL>
+
+<P>What this license <B>does not</B> allow you to do is make
+changes or add features to CUPS and then sell a binary
+distribution without source code. You must provide source for
+any new drivers, changes, or additions to the software, and all
+code must be provided under the GPL or LGPL as appropriate. The
+only exceptions to this are the portions of the CUPS software
+covered by the Apple operating system license exceptions
+outlined later in this license agreement.
+
+<P>The GNU LGPL relaxes the "link-to" restriction, allowing you
+to develop applications that use the CUPS API library under
+other licenses and/or conditions as appropriate for your
+application.
+
+<H3>License Exceptions</H3>
+
+<P>In addition, as the copyright holder of CUPS, Easy Software
+Products grants the following special exceptions:
+
+<OL>
+
+ <LI><B>Apple Operating System Development License
+ Exception</B>;
+
+ <OL TYPE="a">
+
+ <LI>Software that is developed by any person or
+ entity for an Apple Operating System ("Apple
+ OS-Developed Software"), including but not
+ limited to Apple and third party printer
+ drivers, filters, and backends for an Apple
+ Operating System, that is linked to the CUPS
+ imaging library or based on any sample filters
+ or backends provided with CUPS shall not be
+ considered to be a derivative work or collective
+ work based on the CUPS program and is exempt
+ from the mandatory source code release clauses
+ of the GNU GPL. You may therefore distribute
+ linked combinations of the CUPS imaging library
+ with Apple OS-Developed Software without
+ releasing the source code of the Apple
+ OS-Developed Software. You may also use sample
+ filters and backends provided with CUPS to
+ develop Apple OS-Developed Software without
+ releasing the source code of the Apple
+ OS-Developed Software.</LI>
+
+ <LI>An Apple Operating System means any
+ operating system software developed and/or
+ marketed by Apple Computer, Inc., including but
+ not limited to all existing releases and
+ versions of Apple's Darwin, Mac OS X, and Mac OS
+ X Server products and all follow-on releases and
+ future versions thereof.</LI>
+
+ <LI>This exception is only available for Apple
+ OS-Developed Software and does not apply to
+ software that is distributed for use on other
+ operating systems.</LI>
+
+ <LI>All CUPS software that falls under this
+ license exception have the following text at the
+ top of each source file:
+
+ <BLOCKQUOTE>This file is subject to the Apple
+ OS-Developed Software
+ exception.</BLOCKQUOTE></LI>
+
+ </OL>
+
+ <LI><B>OpenSSL Toolkit License Exception</B>;
+
+ <OL TYPE="a">
+
+ <LI>Easy Software Products explicitly allows the
+ compilation and distribution of the CUPS
+ software with the OpenSSL Toolkit.</LI>
+
+ </OL>
+
+</OL>
+
+<P>No developer is required to provide these exceptions in a
+derived work.
+
+<H3>Trademarks</H3>
+
+<P>Easy Software Products has trademarked the Common UNIX
+Printing System, CUPS, and CUPS logo. These names and logos may
+be used freely in any direct port or binary distribution of
+CUPS. Please contract Easy Software Products for written
+permission to use them in derivative products. Our intention is
+to protect the value of these trademarks and ensure that any
+derivative product meets the same high-quality standards as the
+original.
+
+<H3>Binary Distribution Rights</H3>
+
+<P>Easy Software Products also sells rights to the CUPS source
+code under a binary distribution license for vendors that are
+unable to release source code for their drivers, additions, and
+modifications to CUPS under the GNU GPL and LGPL. For
+information please contact us at the address shown above.
+
+<P>The Common UNIX Printing System provides a "pdftops" filter
+that is based on the Xpdf software. For binary distribution
+licensing of this software, please contact:
+
+<BLOCKQUOTE>
+Derek B. Noonburg<BR>
+Email: <A HREF="mailto:derekn@foolabs.com">derekn@foolabs.com</A><BR>
+WWW: <A HREF="http://www.foolabs.com/xpdf/">http://www.foolabs.com/xpdf/</A>
+</BLOCKQUOTE>
+
+<H3>Support</H3>
+
+<P>Easy Software Products sells software support for CUPS as
+well as a commercial printing product based on CUPS called ESP
+Print Pro. You can find out more at our web site:
+
+<UL><PRE>
+<A HREF="http://www.easysw.com/">http://www.easysw.com/</A>
+</PRE></UL>
+
+<!-- NEW PAGE -->
+<H2>GNU GENERAL PUBLIC LICENSE</H2>
+
+<P>Version 2, June 1991
+
+<PRE>
+Copyright 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim
+copies of this license document, but changing it is not allowed.
+</PRE>
+
+<H4>Preamble</H4>
+
+<P>The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+<P>When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+<P>To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+<P>For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+<P>We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+<P>Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+<P>Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+<P>The precise terms and conditions for copying, distribution and
+modification follow.
+
+<H4>GNU GENERAL PUBLIC LICENSE<BR>
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+
+<OL START="0">
+
+<LI>This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+<P>Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+<LI>You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+<P>You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+<LI>You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+<OL TYPE="a">
+
+<LI>You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+<LI>You must cause any work that you distribute or publish, that in
+whole or in part contains or is derived from the Program or any
+part thereof, to be licensed as a whole at no charge to all third
+parties under the terms of this License.
+
+<LI>if the modified program normally reads commands interactively
+when run, you must cause it, when started running for such
+interactive use in the most ordinary way, to print or display an
+announcement including an appropriate copyright notice and a
+notice that there is no warranty (or else, saying that you provide
+a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this
+License. (Exception: if the Program itself is interactive but
+does not normally print such an announcement, your work based on
+the Program is not required to print an announcement.)
+
+</OL>
+
+<P>These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+<P>Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+<P>In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+<LI>You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+<OL TYPE="a">
+
+<LI>Accompany it with the complete corresponding machine-readable
+source code, which must be distributed under the terms of Sections
+1 and 2 above on a medium customarily used for software interchange; or,
+
+<LI>Accompany it with a written offer, valid for at least three
+years, to give any third party, for a charge no more than your
+cost of physically performing source distribution, a complete
+machine-readable copy of the corresponding source code, to be
+distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
+
+<LI>Accompany it with the information you received as to the offer
+to distribute corresponding source code. (This alternative is
+allowed only for noncommercial distribution and only if you
+received the program in object code or executable form with such
+an offer, in accord with Subsection b above.)
+
+</OL>
+
+<P>The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+<P>If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+<LI>You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+<LI>You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+<LI>Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+<LI>If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+<P>If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+<P>It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+<P>This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+<LI>If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+<LI>The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+<P>Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+<LI>If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+</OL>
+
+<H4>NO WARRANTY</H4>
+
+<OL START="11">
+
+<LI>BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+<LI>IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+</OL>
+
+<H4>END OF TERMS AND CONDITIONS</H4>
+
+<!-- NEW PAGE -->
+<H2>GNU LIBRARY GENERAL PUBLIC LICENSE</H2>
+
+<P>Version 2, June 1991
+
+<PRE>
+Copyright (C) 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+</PRE>
+
+<H4>Preamble</H4>
+
+<P>The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+<P>This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+<P>When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+<P>To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+<P>For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+<P>Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+<P>Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+<P>Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+<P>Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+<P>The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+<P>Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+<P>However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+<P>The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+<P>Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+<H4>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+
+<P><STRONG>0.</STRONG>
+This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+<P>A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+<P>The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+<P>"Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+<P>Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+<P><STRONG>1.</STRONG>
+You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+<P>You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+<P><STRONG>2.</STRONG>
+You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+<OL TYPE="a">
+
+ <LI>The modified work must itself be a software library.
+
+ <P>
+ <LI>You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ <P>
+ <LI>You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ <P>
+ <LI>If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ <P>(For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+</OL>
+
+<P>These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+<P>Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+<P>In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+<P><STRONG>3.</STRONG>
+You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+<P>Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+<P>This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+<P><STRONG>4.</STRONG>
+You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+<P>If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+<P><STRONG>5.</STRONG>
+A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+<P>However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+<P>When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+<P>If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+<P>Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+<P><STRONG>6.</STRONG>
+As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+<P>You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+<OL TYPE="a">
+
+ <LI>Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ <P>
+ <LI>Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ <P>
+ <LI>If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ <P>
+ <LI>Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+</OL>
+
+<P>For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+<P>It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+<P><STRONG>7.</STRONG>
+You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+<OL TYPE="a">
+
+ <LI>Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ <P>
+ <LI>Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+</OL>
+
+<P><STRONG>8.</STRONG>
+You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+<P><STRONG>9.</STRONG>
+You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+<P><STRONG>10.</STRONG>
+Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+<P><STRONG>11.</STRONG>
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+<P>If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+<P>It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+<P>This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+<P><STRONG>12.</STRONG>
+If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+<P><STRONG>13.</STRONG>
+The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+<P>Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+<P><STRONG>14.</STRONG>
+If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+<P><STRONG>NO WARRANTY</STRONG>
+
+<P><STRONG>15.</STRONG>
+BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+<P><STRONG>16.</STRONG>
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+<H4>END OF TERMS AND CONDITIONS</H4>
+
+</BODY>
+</HTML>
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 000000000..c370d608f
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,861 @@
+ Common UNIX Printing System License Agreement
+
+ Copyright 1997-2002 by Easy Software Products
+ 44141 AIRPORT VIEW DR STE 204
+ HOLLYWOOD, MARYLAND 20636-3111 USA
+
+ Voice: +1.301.373.9600
+ Email: cups-info@cups.org
+ WWW: http://www.cups.org
+
+
+INTRODUCTION
+
+The Common UNIX Printing System(tm), ("CUPS(tm)"), is provided
+under the GNU General Public License ("GPL") and GNU Library
+General Public License ("LGPL"), Version 2, with exceptions for
+Apple operating systems and the OpenSSL toolkit. A copy of the
+exceptions and licenses follow this introduction.
+
+The GNU LGPL applies to the CUPS API library, located in the
+"cups" subdirectory of the CUPS source distribution and in the
+"cups" include directory and library files in the binary
+distributions. The GNU GPL applies to the remainder of the CUPS
+distribution, including the "pdftops" filter which is based upon
+Xpdf and the CUPS imaging library.
+
+For those not familiar with the GNU GPL, the license basically
+allows you to:
+
+ - Use the CUPS software at no charge.
+ - Distribute verbatim copies of the software in source or
+ binary form.
+ - Sell verbatim copies of the software for a media fee, or
+ sell support for the software.
+ - Distribute or sell printer drivers and filters that use
+ CUPS so long as source code is made available under the
+ GPL.
+
+What this license *does not* allow you to do is make changes or
+add features to CUPS and then sell a binary distribution without
+source code. You must provide source for any new drivers,
+changes, or additions to the software, and all code must be
+provided under the GPL or LGPL as appropriate. The only
+exceptions to this are the portions of the CUPS software covered
+by the Apple operating system license exceptions outlined later
+in this license agreement.
+
+The GNU LGPL relaxes the "link-to" restriction, allowing you to
+develop applications that use the CUPS API library under other
+licenses and/or conditions as appropriate for your application.
+
+
+LICENSE EXCEPTIONS
+
+In addition, as the copyright holder of CUPS, Easy Software
+Products grants the following special exceptions:
+
+ 1. Apple Operating System Development License Exception;
+
+ a. Software that is developed by any person or entity
+ for an Apple Operating System ("Apple OS-Developed
+ Software"), including but not limited to Apple and
+ third party printer drivers, filters, and backends
+ for an Apple Operating System, that is linked to the
+ CUPS imaging library or based on any sample filters
+ or backends provided with CUPS shall not be
+ considered to be a derivative work or collective work
+ based on the CUPS program and is exempt from the
+ mandatory source code release clauses of the GNU GPL.
+ You may therefore distribute linked combinations of
+ the CUPS imaging library with Apple OS-Developed
+ Software without releasing the source code of the
+ Apple OS-Developed Software. You may also use sample
+ filters and backends provided with CUPS to develop
+ Apple OS-Developed Software without releasing the
+ source code of the Apple OS-Developed Software.
+
+ b. An Apple Operating System means any operating system
+ software developed and/or marketed by Apple Computer,
+ Inc., including but not limited to all existing
+ releases and versions of Apple's Darwin, Mac OS X,
+ and Mac OS X Server products and all follow-on
+ releases and future versions thereof.
+
+ c. This exception is only available for Apple
+ OS-Developed Software and does not apply to software
+ that is distributed for use on other operating
+ systems.
+
+ d. All CUPS software that falls under this license
+ exception have the following text at the top of each
+ source file:
+
+ This file is subject to the Apple OS-Developed
+ Software exception.
+
+ 2. OpenSSL Toolkit License Exception;
+
+ a. Easy Software Products explicitly allows the
+ compilation and distribution of the CUPS software
+ with the OpenSSL Toolkit.
+
+No developer is required to provide these exceptions in a
+derived work.
+
+
+TRADEMARKS
+
+Easy Software Products has trademarked the Common UNIX Printing
+System, CUPS, and CUPS logo. These names and logos may be used
+freely in any direct port or binary distribution of CUPS. Please
+contract Easy Software Products for written permission to use
+them in derivative products. Our intention is to protect the
+value of these trademarks and ensure that any derivative product
+meets the same high-quality standards as the original.
+
+
+BINARY DISTRIBUTION RIGHTS
+
+Easy Software Products also sells rights to the CUPS source code
+under a binary distribution license for vendors that are unable
+to release source code for their drivers, additions, and
+modifications to CUPS under the GNU GPL and LGPL. For
+information please contact us at the address shown above.
+
+The Common UNIX Printing System provides a "pdftops" filter that
+is based on the Xpdf software. For binary distribution licensing
+of this software, please contact:
+
+ Derek B. Noonburg
+ Email: derekn@foolabs.com
+ WWW: http://www.foolabs.com/xpdf/
+
+
+SUPPORT
+
+Easy Software Products sells software support for CUPS as well
+as a commercial printing product based on CUPS called ESP Print
+Pro. You can find out more at our web site:
+
+ http://www.easysw.com/
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ [This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
diff --git a/Makedefs.in b/Makedefs.in
new file mode 100644
index 000000000..84f36665a
--- /dev/null
+++ b/Makedefs.in
@@ -0,0 +1,183 @@
+#
+# "$Id$"
+#
+# Common makefile definitions for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+#
+# Programs...
+#
+
+AR = @AR@
+AWK = @AWK@
+CC = @LIBTOOL@ @CC@
+CXX = @LIBTOOL@ @CXX@
+DSO = @DSO@
+HTMLDOC = @HTMLDOC@
+INSTALL = @INSTALL@
+LIBTOOL = @LIBTOOL@
+LN = /bin/ln -sf
+MV = @MV@
+NROFF = @NROFF@
+RANLIB = @RANLIB@
+RM = @RM@ -f
+SED = @SED@
+SHELL = /bin/sh
+STRIP = @STRIP@
+
+#
+# Installation programs...
+#
+
+INSTALL_BIN = $(LIBTOOL) $(INSTALL) -m 755 -s
+INSTALL_DATA = $(INSTALL) -m 644
+INSTALL_DIR = $(INSTALL) -d
+INSTALL_LIB = $(LIBTOOL) $(INSTALL) -m 755
+INSTALL_MAN = $(INSTALL) -m 644
+INSTALL_SCRIPT = $(INSTALL) -m 755
+
+#
+# Default user and group for the scheduler...
+#
+
+CUPS_USER = @CUPS_USER@
+CUPS_GROUP = @CUPS_GROUP@
+
+#
+# Libraries...
+#
+
+LIBCUPS = @LIBCUPS@
+LIBCUPSIMAGE = @LIBCUPSIMAGE@
+LIBJPEG = @LIBJPEG@
+LIBMALLOC = @LIBMALLOC@
+LIBPNG = @LIBPNG@
+LIBSLP = @LIBSLP@
+LIBTIFF = @LIBTIFF@
+LIBZ = @LIBZ@
+
+#
+# Program options...
+#
+# OPTIM defines the common compiler optimization/debugging options.
+# OPTIONS defines other compile-time options (currently only -dDEBUG for
+# extra debug info)
+#
+
+ARFLAGS = @ARFLAGS@
+CFLAGS = $(RC_CFLAGS) @CFLAGS@ -I.. $(OPTIONS)
+CXXFLAGS = $(RC_CFLAGS) @CXXFLAGS@ -I.. $(OPTIONS)
+CXXLIBS = @CXXLIBS@
+DSOFLAGS = @DSOFLAGS@
+DSOLIBS = @DSOLIBS@
+IMGLIBS = @IMGLIBS@ -lm
+LDFLAGS = -L../cups -L../filter $(RC_CFLAGS) @LDFLAGS@ $(OPTIM)
+LINKCUPS = @LINKCUPS@
+LINKCUPSIMAGE = @LINKCUPSIMAGE@
+LIBS = $(LINKCUPS) $(NETLIBS) @LIBS@
+NETLIBS = @NETLIBS@
+OPTIM = @OPTIM@
+OPTIONS =
+PAMLIBS = @PAMLIBS@
+SSLLIBS = @SSLLIBS@
+
+#
+# Directories...
+#
+# The first section uses the GNU names (which are *extremely*
+# difficult to find in a makefile because they are lowercase...)
+# We have to define these first because autoconf uses ${prefix}
+# and ${exec_prefix} for most of the other directories...
+#
+# This is immediately followed by definition in ALL CAPS for the
+# needed directories...
+#
+
+bindir = @bindir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+includedir = @includedir@
+infodir = @infodir@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+top_srcdir = @top_srcdir@
+
+BUILDROOT = $(DSTROOT)
+
+AMANDIR = $(BUILDROOT)@AMANDIR@
+BINDIR = $(BUILDROOT)@bindir@
+DATADIR = $(BUILDROOT)@CUPS_DATADIR@
+DOCDIR = $(BUILDROOT)@CUPS_DOCROOT@
+INCLUDEDIR = $(BUILDROOT)$(includedir)
+INITDIR = @INITDIR@
+INITDDIR = @INITDDIR@
+LIBDIR = $(BUILDROOT)$(libdir)
+LOCALEDIR = $(BUILDROOT)@CUPS_LOCALEDIR@
+LOGDIR = $(BUILDROOT)@CUPS_LOGDIR@
+MANDIR = $(BUILDROOT)@mandir@
+PAMDIR = $(BUILDROOT)@PAMDIR@
+PMANDIR = $(BUILDROOT)@PMANDIR@
+REQUESTS = $(BUILDROOT)@CUPS_REQUESTS@
+SBINDIR = $(BUILDROOT)@sbindir@
+SERVERBIN = $(BUILDROOT)@CUPS_SERVERBIN@
+SERVERROOT = $(BUILDROOT)@CUPS_SERVERROOT@
+
+CAT1EXT = @CAT1EXT@
+CAT3EXT = @CAT3EXT@
+CAT5EXT = @CAT5EXT@
+CAT8EXT = @CAT8EXT@
+MAN8EXT = @MAN8EXT@
+MAN8DIR = @MAN8DIR@
+
+#
+# Rules...
+#
+
+.SILENT:
+.SUFFIXES: .a .c .cxx .h .man .o .0 .1 .1m .3 .5 .8 .z
+.c.o:
+ echo Compiling $<...
+ $(CC) $(OPTIM) $(CFLAGS) -c $<
+.cxx.o:
+ echo Compiling $<...
+ $(CXX) $(OPTIM) $(CXXFLAGS) -c $<
+.man.0 .man.1 .man.1m .man.3 .man.5 .man.8:
+ echo Formatting $<...
+ $(RM) $@
+ -$(NROFF) -man $< >$@
+.man.z:
+ echo Formatting $<...
+ $(RM) $@ t.z
+ -$(NROFF) -man $< >t
+ pack -f t
+ $(MV) t.z $@
+
+#
+# End of "$Id$"
+#
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000..4ce49fae2
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,170 @@
+#
+# "$Id$"
+#
+# Top-level Makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include Makedefs
+
+#
+# Directories to make...
+#
+
+DIRS = cups backend berkeley cgi-bin filter man pdftops \
+ scheduler systemv
+
+#
+# Make all targets...
+#
+
+all:
+ chmod +x cups-config
+ for dir in $(DIRS); do\
+ echo Making all in $$dir... ;\
+ (cd $$dir ; $(MAKE) $(MFLAGS)) || exit 1;\
+ done
+
+#
+# Remove object and target files...
+#
+
+clean:
+ for dir in $(DIRS); do\
+ echo Cleaning in $$dir... ;\
+ (cd $$dir; $(MAKE) $(MFLAGS) clean) || exit 1;\
+ done
+
+#
+# Make dependencies
+#
+
+depend:
+ for dir in $(DIRS); do\
+ echo Making dependencies in $$dir... ;\
+ (cd $$dir; $(MAKE) $(MFLAGS) depend) || exit 1;\
+ done
+
+
+#
+# Install object and target files...
+#
+
+install: installhdrs
+ for dir in $(DIRS); do\
+ echo Installing in $$dir... ;\
+ (cd $$dir; $(MAKE) $(MFLAGS) install) || exit 1;\
+ done
+ echo Installing in conf...
+ (cd conf; $(MAKE) $(MFLAGS) install)
+ echo Installing in data...
+ (cd data; $(MAKE) $(MFLAGS) install)
+ echo Installing in doc...
+ (cd doc; $(MAKE) $(MFLAGS) install)
+ echo Installing in fonts...
+ (cd fonts; $(MAKE) $(MFLAGS) install)
+ echo Installing in locale...
+ (cd locale; $(MAKE) $(MFLAGS) install)
+ echo Installing in ppd...
+ (cd ppd; $(MAKE) $(MFLAGS) install)
+ echo Installing in templates...
+ (cd templates; $(MAKE) $(MFLAGS) install)
+ echo Installing cups-config script...
+ $(INSTALL_DIR) $(BINDIR)
+ $(INSTALL_SCRIPT) cups-config $(BINDIR)/cups-config
+ echo Installing startup script...
+ if test "x$(INITDIR)" != "x"; then \
+ $(INSTALL_DIR) $(BUILDROOT)$(INITDIR)/init.d; \
+ $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDIR)/init.d/cups; \
+ $(INSTALL_DIR) $(BUILDROOT)$(INITDIR)/rc0.d; \
+ $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDIR)/rc0.d/K00cups; \
+ $(INSTALL_DIR) $(BUILDROOT)$(INITDIR)/rc2.d; \
+ $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDIR)/rc2.d/S99cups; \
+ $(INSTALL_DIR) $(BUILDROOT)$(INITDIR)/rc3.d; \
+ $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDIR)/rc3.d/S99cups; \
+ $(INSTALL_DIR) $(BUILDROOT)$(INITDIR)/rc5.d; \
+ $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDIR)/rc5.d/S99cups; \
+ fi
+ if test "x$(INITDIR)" = "x" -a "x$(INITDDIR)" != "x"; then \
+ $(INSTALL_DIR) $(BUILDROOT)$(INITDDIR); \
+ if test "$(INITDDIR)" = "/System/Library/StartupItems/PrintingServices"; then \
+ $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDDIR)/PrintingServices; \
+ $(INSTALL_DATA) cups.plist $(BUILDROOT)$(INITDDIR)/StartupParameters.plist; \
+ $(INSTALL_DIR) $(BUILDROOT)$(INITDDIR)/Resources/English.lproj; \
+ $(INSTALL_DATA) cups.strings $(BUILDROOT)$(INITDDIR)/Resources/English.lproj/Localizable.strings; \
+ else \
+ $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDDIR)/cups; \
+ fi \
+ fi
+
+#
+# Install source and header files...
+#
+
+installsrc:
+ gnutar --dereference --exclude=CVS -cf - . | gnutar -C $(SRCROOT) -xf -
+
+installhdrs:
+ (cd cups ; $(MAKE) $(MFLAGS) installhdrs) || exit 1;\
+ (cd filter ; $(MAKE) $(MFLAGS) installhdrs) || exit 1;
+
+
+#
+# Run the test suite...
+#
+
+check test: all
+ echo Running CUPS test suite...
+ cd test; ./run-stp-tests.sh
+
+
+#
+# Make software distributions using EPM (http://www.easysw.com/epm)...
+#
+
+EPMFLAGS = -v
+
+aix:
+ epm $(EPMFLAGS) -f aix cups
+
+bsd:
+ epm $(EPMFLAGS) -f bsd cups
+
+epm:
+ epm $(EPMFLAGS) cups
+
+rpm:
+ epm $(EPMFLAGS) -f rpm cups
+
+deb:
+ epm $(EPMFLAGS) -f deb cups
+
+depot:
+ epm $(EPMFLAGS) -f depot cups
+
+pkg:
+ epm $(EPMFLAGS) -f pkg cups
+
+tardist:
+ epm $(EPMFLAGS) -f tardist cups
+
+#
+# End of "$Id$".
+#
diff --git a/README.txt b/README.txt
new file mode 100644
index 000000000..f594bd2b8
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,288 @@
+README - CUPS v1.1.16 - 07/02/2002
+----------------------------------
+
+Looking for compile instructions? Read the file "INSTALL.txt"
+instead...
+
+**** IF YOU HAVE A NON-POSTSCRIPT PRINTER, YOU WILL ALSO ****
+**** NEED TO INSTALL ESP GHOSTSCRIPT OR A PATCHED VERSION ****
+**** OF THE STANDARD GHOSTSCRIPT RELEASES. ****
+
+
+INTRODUCTION
+
+CUPS provides a portable printing layer for UNIX(r)-based
+operating systems. It has been developed by Easy Software
+Products to promote a standard printing solution for all UNIX
+vendors and users. CUPS provides the System V and Berkeley
+command-line interfaces.
+
+CUPS uses the Internet Printing Protocol ("IPP") as the basis
+for managing print jobs and queues. The Line Printer Daemon
+("LPD") Server Message Block ("SMB"), and AppSocket (a.k.a.
+JetDirect) protocols are also supported with reduced
+functionality. CUPS adds network printer browsing and
+PostScript Printer Description ("PPD") based printing options to
+support real-world printing under UNIX.
+
+CUPS includes an image file RIP that supports printing of image
+files to non-PostScript printers. A customized version of GNU
+Ghostscript 7.05 for CUPS called ESP Ghostscript is available
+separately to support printing of PostScript files within the
+CUPS driver framework. Sample drivers for Dymo, EPSON, HP, and
+OKIDATA printers are included that use these filters.
+
+Drivers for thousands of printers are provided with our ESP
+Print Pro software, available at:
+
+ http://www.easysw.com/printpro
+
+CUPS is licensed under the GNU General Public License and GNU
+Library General Public License. Please contact Easy Software
+Products for commercial support and "binary distribution"
+rights.
+
+
+SYSTEM REQUIREMENTS
+
+Binary distributions require a minimum of 10MB of free disk
+space. We do not recommend using CUPS on a workstation with less
+than 32MB of RAM or a PC with less than 16MB of RAM.
+
+If you are installing from source you'll need ANSI-compliant C
+and C++ compilers and optionally one or more image file support
+libraries. Complete source installation instructions can be
+found in the file "INSTALL.txt".
+
+
+SOFTWARE REQUIREMENTS
+
+The following operating system software is required to install
+one of the binary distributions from Easy Software Products:
+
+ - AIX 4.3 or higher
+ - Compaq Tru64 UNIX (aka OSF1 aka Digital UNIX) 4.0 or higher
+ - HP-UX 10.20 or higher
+ - IRIX 5.3 or higher
+ - Linux 2.0 with glibc2 or higher
+ - Solaris 2.5 or higher (SPARC or Intel)
+
+
+INSTALLING "PORTABLE" CUPS DISTRIBUTIONS
+
+We are currently distributing "portable" CUPS binary
+distributions in TAR format with installation and removal
+scripts generated by our ESP Package Manager (EPM) software,
+which is available from:
+
+ http://www.easysw.com/epm
+
+WARNING: Installing CUPS will overwrite your existing printing
+system. Backup files are made by the installation script and
+restored by the removal script, so if you experience problems
+you should be able to remove the CUPS software to restore your
+previous configuration. However, Easy Software Products makes
+no warranty for this and will not be liable for any lost
+revenues, etc.
+
+To install the CUPS software you will need to be logged in as
+root (doing an "su" is good enough). Once you are the root
+user, run the installation script with:
+
+ ./cups.install ENTER
+
+After asking you a few yes/no questions the CUPS software will
+be installed and the scheduler will be started automatically.
+
+
+INSTALLING HOST-SPECIFIC (RPM, DEBIAN, ETC.) DISTRIBUTIONS
+
+The host-specific distributions use the operating system
+software installation tools. To install a host-specific
+distribution please consult the CUPS Software Administrators
+Manual or your operating system documentation.
+
+
+READING THE DOCUMENTATION
+
+Once you have installed the software you can access the
+documentation (and a bunch of other stuff) on-line at:
+
+ http://localhost:631
+
+If you're having trouble getting that far, the documentation is
+located in the "/usr/share/doc/cups" directory in the binary
+distributions, and under the "doc" directory in the source
+archives.
+
+Please read the documentation before asking questions.
+
+
+GETTING SUPPORT AND OTHER RESOURCES
+
+If you have problems, READ THE DOCUMENTATION FIRST!
+
+You can subscribe to the CUPS mailing list by sending a message
+containing "subscribe cups" to majordomo@cups.org. This list is
+provided to discuss problems, questions, and improvements to the
+CUPS software. New releases of CUPS are announced to this list
+as well.
+
+Commercial support (with a guaranteed response time) is
+available from Easy Software Products. For more information
+see:
+
+ http://www.easysw.com/cups
+
+See the CUPS web site at "http://www.cups.org" for other site
+links.
+
+
+SETTING UP PRINTER QUEUES USING YOUR WEB BROWSER
+
+CUPS 1.1 includes a new web-based administration tool that
+allows you to manage printers, classes, and jobs on your
+server. To access the printer administration tools open the
+following URL in your browser:
+
+ http://localhost:631/admin
+
+You will be asked for the administration password (root or any
+other user in the sys/system/root group on your system) and then
+shown a menu of available functions.
+
+DO NOT use the hostname for your machine - it will not work with
+the default CUPS configuration. To enable administration access
+on other addresses, consult the CUPS Software Administrators
+Manual.
+
+
+SETTING UP PRINTER QUEUES FROM THE COMMAND-LINE
+
+CUPS works best with PPD (PostScript Printer Description)
+files. In a pinch you can also use System V style printer
+interface scripts.
+
+Six sample PPD files are provided with this distribution that
+utilize the PostScript and image file RIPs and the sample EPSON
+and HP printer drivers. To add the sample DeskJet driver to the
+system for a printer connected to the parallel port, use one of
+the following commands:
+
+ Digital UNIX:
+
+ /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/lp0 -E
+
+ HP-UX:
+
+ /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/c2t0d0_lp -E
+
+ IRIX:
+
+ /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/plp -E
+
+ Linux:
+
+ /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/lp0 -E
+ /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/lp1 -E
+ /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/lp2 -E
+
+ Solaris:
+
+ /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/bpp0 -E
+ /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/ecpp0 -E
+
+Similarly, for the other sample drivers you can use:
+
+ Driver PPD File
+ ----------------------------- ------------
+ Dymo Label Printers dymo.ppd
+ EPSON Stylus Color Series stcolor.ppd
+ EPSON Stylus Photo Series stphoto.ppd
+ EPSON Stylus New Color Series stcolor2.ppd
+ EPSON Stylus New Photo Series stphoto2.ppd
+ EPSON 9-pin Series epson9.ppd
+ EPSON 24-pin Series epson24.ppd
+ HP DeskJet Series deskjet.ppd
+ HP New DeskJet Series deskjet2.ppd
+ HP LaserJet Series laserjet.ppd
+ OKIDATA 9-Pin Series okidata9.ppd
+ OKIDATA 24-Pin Series okidat24.ppd
+
+These sample drivers provide basic printing capabilities, but
+generally do not exercise the full potential of the printers or
+CUPS. For commercial printer drivers check out our ESP Print
+Pro software at:
+
+ http://www.easysw.com/printpro
+
+
+PRINTING FILES
+
+CUPS provides both the System V "lp" and Berkeley "lpr" commands
+for printing:
+
+ lp filename
+ lpr filename
+
+Both the "lp" and "lpr" commands support printing options for
+the driver:
+
+ lp -omedia=A4 -oresolution=600dpi filename
+ lpr -omedia=A4 -oresolution=600dpi filename
+
+CUPS recognizes many types of images files as well as PDF,
+PostScript, HP-GL/2, and text files, so you can print those
+files directly rather than through an application.
+
+If you have an application that generates output specifically
+for your printer then you need to use the "-oraw" or "-l"
+options:
+
+ lp -oraw filename
+ lpr -l filename
+
+This will prevent the filters from misinterpreting your print
+file.
+
+
+LEGAL STUFF
+
+CUPS is Copyright 1993-2002 by Easy Software Products. CUPS,
+the CUPS logo, and the Common UNIX Printing System are the
+trademark property of Easy Software Products.
+
+The MD5 Digest code is Copyright 1999 Aladdin Enterprises.
+
+The PostScript RIP software (pstoraster) is based on the GNU
+Ghostscript 5.50 core, Copyright 1986-1998 by Aladdin
+Enterprises.
+
+The PDF filter (pdftops) is based on the Xpdf 0.92 software,
+Copyright 1996-2002 by Derek B. Noonburg.
+
+This software is based in part on the work of the Independent
+JPEG Group.
+
+CUPS is provided under the terms of the GNU General Public
+License and GNU Library General Public License. This program is
+distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the "LICENSE.html",
+"LICENSE.txt", or "cups.license" files for more information.
+
+For commercial licensing information, please contact:
+
+ Attn: CUPS Licensing Information
+ Easy Software Products
+ 44141 Airport View Drive, Suite 204
+ Hollywood, Maryland 20636-3111 USA
+
+ Voice: +1.301.373.9600
+ Email: cups-info@cups.org
+ WWW: http://www.cups.org
+
+Note that commercial licensors may also require a license from
+Artifex Software Inc. which handles commercial licensing of the
+Ghostscript software, and from Derek B. Noonburg who developed
+the Xpdf software used to print PDF files.
diff --git a/backend/.cvsignore b/backend/.cvsignore
new file mode 100644
index 000000000..e78e89c08
--- /dev/null
+++ b/backend/.cvsignore
@@ -0,0 +1,7 @@
+ipp
+lpd
+usb
+parallel
+betest
+serial
+socket
diff --git a/backend/Dependencies b/backend/Dependencies
new file mode 100644
index 000000000..17c91750e
--- /dev/null
+++ b/backend/Dependencies
@@ -0,0 +1,15 @@
+# DO NOT DELETE
+
+betest.o: ../cups/string.h ../config.h
+ipp.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+ipp.o: ../cups/ppd.h ../cups/language.h ../cups/string.h ../config.h
+lpd.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lpd.o: ../cups/ppd.h ../cups/string.h ../config.h
+parallel.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+parallel.o: ../cups/ppd.h ../cups/string.h ../config.h
+serial.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+serial.o: ../cups/ppd.h ../cups/string.h ../config.h
+socket.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+socket.o: ../cups/ppd.h ../cups/string.h ../config.h
+usb.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+usb.o: ../cups/ppd.h ../cups/string.h ../config.h
diff --git a/backend/Makefile b/backend/Makefile
new file mode 100644
index 000000000..9d14174c4
--- /dev/null
+++ b/backend/Makefile
@@ -0,0 +1,155 @@
+#
+# "$Id$"
+#
+# Backend makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+# This file is subject to the Apple OS-Developed Software exception.
+#
+
+include ../Makedefs
+
+BACKENDS = ipp lpd parallel scsi serial socket usb
+TARGETS = betest $(BACKENDS)
+OBJS = betest.o ipp.o lpd.o parallel.o scsi.o serial.o socket.o usb.o
+
+
+#
+# Make all targets...
+#
+
+all: $(TARGETS)
+
+
+#
+# Clean all object files...
+#
+
+clean:
+ $(RM) $(OBJS) $(TARGETS) http
+
+
+#
+# Update dependencies (without system header dependencies...)
+#
+
+depend:
+ makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1
+
+
+#
+# Install all targets...
+#
+
+install: all
+ $(INSTALL_DIR) $(SERVERBIN)/backend
+ for file in $(BACKENDS); do \
+ $(INSTALL_BIN) $$file $(SERVERBIN)/backend; \
+ done
+ $(RM) $(SERVERBIN)/backend/http
+ $(LN) ipp $(SERVERBIN)/backend/http
+
+
+#
+# betest
+#
+
+betest: betest.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o betest betest.o $(LIBS)
+
+
+#
+# ipp
+#
+
+ipp: ipp.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o ipp ipp.o $(LIBS)
+ $(RM) http
+ $(LN) ipp http
+
+
+#
+# lpd
+#
+
+lpd: lpd.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpd lpd.o $(LIBS)
+
+
+#
+# parallel
+#
+
+parallel: parallel.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o parallel parallel.o $(LIBS)
+
+
+#
+# scsi
+#
+
+scsi: scsi.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o scsi scsi.o $(LIBS)
+
+scsi.o: scsi.c scsi-irix.c scsi-linux.c
+
+
+#
+# serial
+#
+
+serial: serial.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o serial serial.o $(LIBS)
+
+
+#
+# socket
+#
+
+socket: socket.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o socket socket.o $(LIBS)
+
+
+#
+# usb
+#
+
+usb: usb.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o usb usb.o $(LIBS)
+
+
+#
+# Dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id$".
+#
diff --git a/backend/betest.c b/backend/betest.c
new file mode 100644
index 000000000..7215eb97d
--- /dev/null
+++ b/backend/betest.c
@@ -0,0 +1,87 @@
+/*
+ * "$Id$"
+ *
+ * Backend test program for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Run the named backend.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cups/string.h>
+#include <unistd.h>
+
+
+/*
+ * 'main()' - Run the named backend.
+ *
+ * Usage:
+ *
+ * betest device-uri job-id user title copies options [file]
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments (7 or 8) */
+ char *argv[]) /* I - Command-line arguments */
+{
+ char backend[255]; /* Method in URI */
+
+
+ if (argc < 7 || argc > 8)
+ {
+ fputs("Usage: betest device-uri job-id user title copies options [file]\n",
+ stderr);
+ return (1);
+ }
+
+ /*
+ * Extract the method from the device-uri - that's the program we want to
+ * execute.
+ */
+
+ if (sscanf(argv[1], "%254[^:]", backend) != 1)
+ {
+ fputs("betest: Bad device-uri - no colon!\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Execute and return
+ */
+
+ execl(backend, argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7],
+ NULL);
+
+ return (1);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/backend/ipp.c b/backend/ipp.c
new file mode 100644
index 000000000..992f59b05
--- /dev/null
+++ b/backend/ipp.c
@@ -0,0 +1,892 @@
+/*
+ * "$Id$"
+ *
+ * IPP backend for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Send a file to the printer or server.
+ * password_cb() - Disable the password prompt for
+ * cupsDoFileRequest().
+ * report_printer_state() - Report the printer state.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <cups/string.h>
+#include <signal.h>
+
+
+/*
+ * Local functions...
+ */
+
+const char *password_cb(const char *);
+int report_printer_state(ipp_t *ipp);
+
+
+/*
+ * Local globals...
+ */
+
+char *password = NULL;
+
+
+/*
+ * 'main()' - Send a file to the printer or server.
+ *
+ * Usage:
+ *
+ * printer-uri job-id user title copies options [file]
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments (6 or 7) */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ int num_options; /* Number of printer options */
+ cups_option_t *options; /* Printer options */
+ char method[255], /* Method in URI */
+ hostname[1024], /* Hostname */
+ username[255], /* Username info */
+ resource[1024], /* Resource info (printer name) */
+ filename[1024]; /* File to print */
+ int port; /* Port number (not used) */
+ char uri[HTTP_MAX_URI];/* Updated URI without user/pass */
+ ipp_status_t ipp_status; /* Status of IPP request */
+ http_t *http; /* HTTP connection */
+ ipp_t *request, /* IPP request */
+ *response, /* IPP response */
+ *supported; /* get-printer-attributes response */
+ ipp_attribute_t *job_id_attr; /* job-id attribute */
+ int job_id; /* job-id value */
+ ipp_attribute_t *job_state; /* job-state attribute */
+ ipp_attribute_t *copies_sup; /* copies-supported attribute */
+ ipp_attribute_t *charset_sup; /* charset-supported attribute */
+ ipp_attribute_t *format_sup; /* document-format-supported attribute */
+ ipp_attribute_t *printer_state;
+ /* printer-state attribute */
+ ipp_attribute_t *printer_accepting;
+ /* printer-is-accepting-jobs attribute */
+ const char *charset; /* Character set to use */
+ cups_lang_t *language; /* Default language */
+ int copies; /* Number of copies remaining */
+ const char *content_type; /* CONTENT_TYPE environment variable */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+ int version; /* IPP version */
+ int reasons; /* Number of printer-state-reasons shown */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc == 1)
+ {
+ char *s;
+
+ if ((s = strrchr(argv[0], '/')) != NULL)
+ s ++;
+ else
+ s = argv[0];
+
+ printf("network %s \"Unknown\" \"Internet Printing Protocol (%s)\"\n", s, s);
+ return (0);
+ }
+ else if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
+ argv[0]);
+ return (1);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, copy stdin to a temporary file and print the temporary
+ * file.
+ */
+
+ if (argc == 6)
+ {
+ /*
+ * Copy stdin to a temporary file...
+ */
+
+ int fd; /* Temporary file */
+ char buffer[8192]; /* Buffer for copying */
+ int bytes; /* Number of bytes read */
+
+
+ if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
+ {
+ perror("ERROR: unable to create temporary file");
+ return (1);
+ }
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ if (write(fd, buffer, bytes) < bytes)
+ {
+ perror("ERROR: unable to write to temporary file");
+ close(fd);
+ unlink(filename);
+ return (1);
+ }
+
+ close(fd);
+ }
+ else
+ strlcpy(filename, argv[6], sizeof(filename));
+
+ /*
+ * Extract the hostname and printer name from the URI...
+ */
+
+ httpSeparate(argv[0], method, username, hostname, &port, resource);
+
+ /*
+ * Set the authentication info, if any...
+ */
+
+ cupsSetPasswordCB(password_cb);
+
+ if (username[0])
+ {
+ if ((password = strchr(username, ':')) != NULL)
+ *password++ = '\0';
+
+ cupsSetUser(username);
+ }
+
+ /*
+ * Try connecting to the remote server...
+ */
+
+ do
+ {
+ fprintf(stderr, "INFO: Connecting to %s on port %d...\n", hostname, port);
+
+ if ((http = httpConnect(hostname, port)) == NULL)
+ {
+ if (getenv("CLASS") != NULL)
+ {
+ /*
+ * If the CLASS environment variable is set, the job was submitted
+ * to a class and not to a specific queue. In this case, we want
+ * to abort immediately so that the job can be requeued on the next
+ * available printer in the class.
+ */
+
+ fprintf(stderr, "INFO: Unable to queue job on %s, queuing on next printer in class...\n",
+ hostname);
+
+ if (argc == 6)
+ unlink(filename);
+
+ /*
+ * Sleep 5 seconds to keep the job from requeuing too rapidly...
+ */
+
+ sleep(5);
+
+ return (1);
+ }
+
+ if (errno == ECONNREFUSED || errno == EHOSTDOWN ||
+ errno == EHOSTUNREACH)
+ {
+ fprintf(stderr, "INFO: Network host \'%s\' is busy; will retry in 30 seconds...",
+ hostname);
+ sleep(30);
+ }
+ else
+ {
+ perror("ERROR: Unable to connect to IPP host");
+ sleep(30);
+ }
+ }
+ }
+ while (http == NULL);
+
+ fprintf(stderr, "INFO: Connected to %s...\n", hostname);
+
+ /*
+ * Build a URI for the printer and fill the standard IPP attributes for
+ * an IPP_PRINT_FILE request. We can't use the URI in argv[0] because it
+ * might contain username:password information...
+ */
+
+ snprintf(uri, sizeof(uri), "%s://%s:%d%s", method, hostname, port, resource);
+
+ /*
+ * First validate the destination and see if the device supports multiple
+ * copies. We have to do this because some IPP servers (e.g. HP JetDirect)
+ * don't support the copies attribute...
+ */
+
+ language = cupsLangDefault();
+ charset_sup = NULL;
+ copies_sup = NULL;
+ format_sup = NULL;
+ version = 1;
+ supported = NULL;
+
+ do
+ {
+ /*
+ * Build the IPP request...
+ */
+
+ request = ippNew();
+ request->request.op.version[1] = version;
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, "utf-8");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language != NULL ? language->language : "en");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request...
+ */
+
+ fputs("DEBUG: Getting supported attributes...\n", stderr);
+
+ if ((supported = cupsDoRequest(http, request, resource)) == NULL)
+ ipp_status = cupsLastError();
+ else
+ ipp_status = supported->request.status.status_code;
+
+ if (ipp_status > IPP_OK_CONFLICT)
+ {
+ if (ipp_status == IPP_PRINTER_BUSY ||
+ ipp_status == IPP_SERVICE_UNAVAILABLE)
+ {
+ fputs("INFO: Printer busy; will retry in 10 seconds...\n", stderr);
+ report_printer_state(supported);
+ sleep(10);
+ }
+ else if ((ipp_status == IPP_BAD_REQUEST ||
+ ipp_status == IPP_VERSION_NOT_SUPPORTED) && version == 1)
+ {
+ /*
+ * Switch to IPP/1.0...
+ */
+
+ fputs("INFO: Printer does not support IPP/1.1, trying IPP/1.0...\n", stderr);
+ version = 0;
+ httpReconnect(http);
+ }
+ else
+ fprintf(stderr, "ERROR: Unable to get printer status (%s)!\n",
+ ippErrorString(ipp_status));
+
+ if (supported)
+ ippDelete(supported);
+
+ continue;
+ }
+ else if ((copies_sup = ippFindAttribute(supported, "copies-supported",
+ IPP_TAG_RANGE)) != NULL)
+ {
+ /*
+ * Has the "copies-supported" attribute - does it have an upper
+ * bound > 1?
+ */
+
+ if (copies_sup->values[0].range.upper <= 1)
+ copies_sup = NULL; /* No */
+ }
+
+ charset_sup = ippFindAttribute(supported, "charset-supported",
+ IPP_TAG_CHARSET);
+ format_sup = ippFindAttribute(supported, "document-format-supported",
+ IPP_TAG_MIMETYPE);
+
+ if (format_sup)
+ {
+ fprintf(stderr, "DEBUG: document-format-supported (%d values)\n",
+ format_sup->num_values);
+ for (i = 0; i < format_sup->num_values; i ++)
+ fprintf(stderr, "DEBUG: [%d] = \"%s\"\n", i,
+ format_sup->values[i].string.text);
+ }
+
+ report_printer_state(supported);
+ }
+ while (ipp_status > IPP_OK_CONFLICT);
+
+ /*
+ * See if the printer is accepting jobs and is not stopped; if either
+ * condition is true and we are printing to a class, requeue the job...
+ */
+
+ if (getenv("CLASS") != NULL)
+ {
+ printer_state = ippFindAttribute(supported, "printer-state",
+ IPP_TAG_ENUM);
+ printer_accepting = ippFindAttribute(supported, "printer-is-accepting-jobs",
+ IPP_TAG_BOOLEAN);
+
+ if (printer_state == NULL ||
+ printer_state->values[0].integer > IPP_PRINTER_PROCESSING ||
+ printer_accepting == NULL ||
+ !printer_accepting->values[0].boolean)
+ {
+ /*
+ * If the CLASS environment variable is set, the job was submitted
+ * to a class and not to a specific queue. In this case, we want
+ * to abort immediately so that the job can be requeued on the next
+ * available printer in the class.
+ */
+
+ fprintf(stderr, "INFO: Unable to queue job on %s, queuing on next printer in class...\n",
+ hostname);
+
+ ippDelete(supported);
+ httpClose(http);
+
+ if (argc == 6)
+ unlink(filename);
+
+ /*
+ * Sleep 5 seconds to keep the job from requeuing too rapidly...
+ */
+
+ sleep(5);
+
+ return (1);
+ }
+ }
+
+ /*
+ * Now that we are "connected" to the port, ignore SIGTERM so that we
+ * can finish out any page data the driver sends (e.g. to eject the
+ * current page... Only ignore SIGTERM if we are printing data from
+ * stdin (otherwise you can't cancel raw jobs...)
+ */
+
+ if (argc < 7)
+ {
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+ }
+
+ /*
+ * See if the printer supports multiple copies...
+ */
+
+ if (copies_sup || argc < 7)
+ copies = 1;
+ else
+ copies = atoi(argv[4]);
+
+ /*
+ * Figure out the character set to use...
+ */
+
+ charset = language ? cupsLangEncoding(language) : "us-ascii";
+
+ if (charset_sup)
+ {
+ /*
+ * See if IPP server supports the requested character set...
+ */
+
+ for (i = 0; i < charset_sup->num_values; i ++)
+ if (strcasecmp(charset, charset_sup->values[i].string.text) == 0)
+ break;
+
+ /*
+ * If not, choose us-ascii or utf-8...
+ */
+
+ if (i >= charset_sup->num_values)
+ {
+ /*
+ * See if us-ascii is supported...
+ */
+
+ for (i = 0; i < charset_sup->num_values; i ++)
+ if (strcasecmp("us-ascii", charset_sup->values[i].string.text) == 0)
+ break;
+
+ if (i < charset_sup->num_values)
+ charset = "us-ascii";
+ else
+ charset = "utf-8";
+ }
+ }
+
+ /*
+ * Then issue the print-job request...
+ */
+
+ reasons = 0;
+
+ while (copies > 0)
+ {
+ /*
+ * Build the IPP request...
+ */
+
+ request = ippNew();
+ request->request.op.version[1] = version;
+ request->request.op.operation_id = IPP_PRINT_JOB;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, charset);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language != NULL ? language->language : "en");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ fprintf(stderr, "DEBUG: printer-uri = \"%s\"\n", uri);
+
+ if (argv[2][0])
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, argv[2]);
+
+ fprintf(stderr, "DEBUG: requesting-user-name = \"%s\"\n", argv[2]);
+
+ if (argv[3][0])
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
+ argv[3]);
+
+ fprintf(stderr, "DEBUG: job-name = \"%s\"\n", argv[3]);
+
+ /*
+ * Handle options on the command-line...
+ */
+
+ options = NULL;
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ if (argc > 6)
+ content_type = getenv("CONTENT_TYPE");
+ else
+ content_type = "application/vnd.cups-raw";
+
+ if (content_type != NULL && format_sup != NULL)
+ {
+ for (i = 0; i < format_sup->num_values; i ++)
+ if (strcasecmp(content_type, format_sup->values[i].string.text) == 0)
+ break;
+
+ if (i < format_sup->num_values)
+ num_options = cupsAddOption("document-format", content_type,
+ num_options, &options);
+ }
+
+ if (copies_sup)
+ {
+ /*
+ * Only send options if the destination printer supports the copies
+ * attribute. This is a hack for the HP JetDirect implementation of
+ * IPP, which does not accept extension attributes and incorrectly
+ * reports a client-error-bad-request error instead of the
+ * successful-ok-unsupported-attributes status. In short, at least
+ * some HP implementations of IPP are non-compliant.
+ */
+
+ cupsEncodeOptions(request, num_options, options);
+ ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "copies",
+ atoi(argv[4]));
+ }
+
+ cupsFreeOptions(num_options, options);
+
+ /*
+ * If copies aren't supported, then we are likely dealing with an HP
+ * JetDirect. The HP IPP implementation seems to close the connection
+ * after every request (that is, it does *not* implement HTTP Keep-
+ * Alive, which is REQUIRED by HTTP/1.1...
+ */
+
+ if (!copies_sup)
+ httpReconnect(http);
+
+ /*
+ * Do the request...
+ */
+
+ if ((response = cupsDoFileRequest(http, request, resource, filename)) == NULL)
+ ipp_status = cupsLastError();
+ else
+ ipp_status = response->request.status.status_code;
+
+ if (ipp_status > IPP_OK_CONFLICT)
+ {
+ job_id = 0;
+
+ if (ipp_status == IPP_SERVICE_UNAVAILABLE ||
+ ipp_status == IPP_PRINTER_BUSY)
+ {
+ fputs("INFO: Printer is busy; retrying print job...\n", stderr);
+ sleep(10);
+ }
+ else
+ fprintf(stderr, "ERROR: Print file was not accepted (%s)!\n",
+ ippErrorString(ipp_status));
+ }
+ else if ((job_id_attr = ippFindAttribute(response, "job-id",
+ IPP_TAG_INTEGER)) == NULL)
+ {
+ fputs("INFO: Print file accepted - job ID unknown.\n", stderr);
+ job_id = 0;
+ }
+ else
+ {
+ job_id = job_id_attr->values[0].integer;
+ fprintf(stderr, "INFO: Print file accepted - job ID %d.\n", job_id);
+ }
+
+ if (response)
+ ippDelete(response);
+
+ if (ipp_status <= IPP_OK_CONFLICT && argc > 6)
+ {
+ fprintf(stderr, "PAGE: 1 %d\n", copies_sup ? atoi(argv[4]) : 1);
+ copies --;
+ }
+ else if (ipp_status != IPP_SERVICE_UNAVAILABLE &&
+ ipp_status != IPP_PRINTER_BUSY)
+ break;
+
+ /*
+ * Wait for the job to complete...
+ */
+
+ if (!job_id)
+ continue;
+
+ fputs("INFO: Waiting for job to complete...\n", stderr);
+
+ for (;;)
+ {
+ /*
+ * Build an IPP_GET_JOB_ATTRIBUTES request...
+ */
+
+ request = ippNew();
+ request->request.op.version[1] = version;
+ request->request.op.operation_id = IPP_GET_JOB_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, charset);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language != NULL ? language->language : "en");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
+ job_id);
+
+ if (argv[2][0])
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, argv[2]);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", NULL, "job-state");
+
+ /*
+ * Do the request...
+ */
+
+ if (!copies_sup)
+ httpReconnect(http);
+
+ if ((response = cupsDoRequest(http, request, resource)) == NULL)
+ ipp_status = cupsLastError();
+ else
+ ipp_status = response->request.status.status_code;
+
+ if (ipp_status == IPP_NOT_FOUND)
+ {
+ /*
+ * Job has gone away and/or the server has no job history...
+ */
+
+ ippDelete(response);
+
+ ipp_status = IPP_OK;
+ break;
+ }
+
+ if (ipp_status > IPP_OK_CONFLICT)
+ {
+ if (ipp_status != IPP_SERVICE_UNAVAILABLE &&
+ ipp_status != IPP_PRINTER_BUSY)
+ {
+ if (response)
+ ippDelete(response);
+
+ fprintf(stderr, "ERROR: Unable to get job %d attributes (%s)!\n",
+ job_id, ippErrorString(ipp_status));
+ break;
+ }
+ }
+ else if ((job_state = ippFindAttribute(response, "job-state", IPP_TAG_ENUM)) != NULL)
+ {
+ /*
+ * Stop polling if the job is finished or pending-held...
+ */
+
+ if (job_state->values[0].integer > IPP_JOB_PROCESSING ||
+ job_state->values[0].integer == IPP_JOB_HELD)
+ {
+ ippDelete(response);
+ break;
+ }
+ }
+
+ if (response)
+ ippDelete(response);
+
+ /*
+ * Now check on the printer state...
+ */
+
+ request = ippNew();
+ request->request.op.version[1] = version;
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, charset);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language != NULL ? language->language : "en");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ if (argv[2][0])
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, argv[2]);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", NULL, "printer-state-reasons");
+
+ /*
+ * Do the request...
+ */
+
+ if (!copies_sup)
+ httpReconnect(http);
+
+ if ((response = cupsDoRequest(http, request, resource)) != NULL)
+ {
+ reasons = report_printer_state(response);
+ ippDelete(response);
+ }
+
+ /*
+ * Wait 10 seconds before polling again...
+ */
+
+ sleep(10);
+ }
+ }
+
+ /*
+ * Free memory...
+ */
+
+ httpClose(http);
+
+ if (supported)
+ ippDelete(supported);
+
+ /*
+ * Close and remove the temporary file if necessary...
+ */
+
+ if (argc < 7)
+ unlink(filename);
+
+ /*
+ * Return the queue status...
+ */
+
+ if (ipp_status <= IPP_OK_CONFLICT && reasons == 0)
+ fputs("INFO: Ready to print.\n", stderr);
+
+ return (ipp_status > IPP_OK_CONFLICT);
+}
+
+
+/*
+ * 'password_cb()' - Disable the password prompt for cupsDoFileRequest().
+ */
+
+const char * /* O - Password */
+password_cb(const char *prompt) /* I - Prompt (not used) */
+{
+ (void)prompt;
+
+ return (password);
+}
+
+
+/*
+ * 'report_printer_state()' - Report the printer state.
+ */
+
+int /* O - Number of reasons shown */
+report_printer_state(ipp_t *ipp) /* I - IPP response */
+{
+ int i; /* Looping var */
+ int count; /* Count of reasons shown... */
+ ipp_attribute_t *reasons; /* printer-state-reasons */
+ const char *message; /* Message to show */
+ char unknown[1024]; /* Unknown message string */
+
+
+ if ((reasons = ippFindAttribute(ipp, "printer-state-reasons",
+ IPP_TAG_KEYWORD)) == NULL)
+ return (0);
+
+ for (i = 0, count = 0; i < reasons->num_values; i ++)
+ {
+ message = NULL;
+
+ if (strncmp(reasons->values[i].string.text, "media-needed", 12) == 0)
+ message = "Media tray needs to be filled.";
+ else if (strncmp(reasons->values[i].string.text, "media-jam", 9) == 0)
+ message = "Media jam!";
+ else if (strncmp(reasons->values[i].string.text, "moving-to-paused", 16) == 0 ||
+ strncmp(reasons->values[i].string.text, "paused", 6) == 0 ||
+ strncmp(reasons->values[i].string.text, "shutdown", 8) == 0)
+ message = "Printer off-line.";
+ else if (strncmp(reasons->values[i].string.text, "toner-low", 9) == 0)
+ message = "Toner low.";
+ else if (strncmp(reasons->values[i].string.text, "toner-empty", 11) == 0)
+ message = "Out of toner!";
+ else if (strncmp(reasons->values[i].string.text, "cover-open", 10) == 0)
+ message = "Cover open.";
+ else if (strncmp(reasons->values[i].string.text, "interlock-open", 14) == 0)
+ message = "Interlock open.";
+ else if (strncmp(reasons->values[i].string.text, "door-open", 9) == 0)
+ message = "Door open.";
+ else if (strncmp(reasons->values[i].string.text, "input-tray-missing", 18) == 0)
+ message = "Media tray missing!";
+ else if (strncmp(reasons->values[i].string.text, "media-low", 9) == 0)
+ message = "Media tray almost empty.";
+ else if (strncmp(reasons->values[i].string.text, "media-empty", 11) == 0)
+ message = "Media tray empty!";
+ else if (strncmp(reasons->values[i].string.text, "output-tray-missing", 19) == 0)
+ message = "Output tray missing!";
+ else if (strncmp(reasons->values[i].string.text, "output-area-almost-full", 23) == 0)
+ message = "Output bin almost full.";
+ else if (strncmp(reasons->values[i].string.text, "output-area-full", 16) == 0)
+ message = "Output bin full!";
+ else if (strncmp(reasons->values[i].string.text, "marker-supply-low", 17) == 0)
+ message = "Ink/toner almost empty.";
+ else if (strncmp(reasons->values[i].string.text, "marker-supply-empty", 19) == 0)
+ message = "Ink/toner empty!";
+ else if (strncmp(reasons->values[i].string.text, "marker-waste-almost-full", 24) == 0)
+ message = "Ink/toner waste bin almost full.";
+ else if (strncmp(reasons->values[i].string.text, "marker-waste-full", 17) == 0)
+ message = "Ink/toner waste bin full!";
+ else if (strncmp(reasons->values[i].string.text, "fuser-over-temp", 15) == 0)
+ message = "Fuser temperature high!";
+ else if (strncmp(reasons->values[i].string.text, "fuser-under-temp", 16) == 0)
+ message = "Fuser temperature low!";
+ else if (strncmp(reasons->values[i].string.text, "opc-near-eol", 12) == 0)
+ message = "OPC almost at end-of-life.";
+ else if (strncmp(reasons->values[i].string.text, "opc-life-over", 13) == 0)
+ message = "OPC at end-of-life!";
+ else if (strncmp(reasons->values[i].string.text, "developer-low", 13) == 0)
+ message = "Developer almost empty.";
+ else if (strncmp(reasons->values[i].string.text, "developer-empty", 15) == 0)
+ message = "Developer empty!";
+ else if (strstr(reasons->values[i].string.text, "error") != NULL)
+ {
+ message = unknown;
+
+ snprintf(unknown, sizeof(unknown), "Unknown printer error (%s)!",
+ reasons->values[i].string.text);
+ }
+
+ if (message)
+ {
+ count ++;
+ if (strstr(reasons->values[i].string.text, "error"))
+ fprintf(stderr, "ERROR: %s\n", message);
+ else if (strstr(reasons->values[i].string.text, "warning"))
+ fprintf(stderr, "WARNING: %s\n", message);
+ else
+ fprintf(stderr, "INFO: %s\n", message);
+ }
+ }
+
+ return (count);
+}
+
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/backend/lpd.c b/backend/lpd.c
new file mode 100644
index 000000000..7663c503e
--- /dev/null
+++ b/backend/lpd.c
@@ -0,0 +1,895 @@
+/*
+ * "$Id$"
+ *
+ * Line Printer Daemon backend for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Send a file to the printer or server.
+ * lpd_command() - Send an LPR command sequence and wait for a reply.
+ * lpd_queue() - Queue a file using the Line Printer Daemon protocol.
+ * lpd_timeout() - Handle timeout alarms...
+ * lpd_write() - Write a buffer of data to an LPD server.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <cups/cups.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <cups/string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#ifdef WIN32
+# include <winsock.h>
+#else
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+#endif /* WIN32 */
+
+
+/*
+ * The order for control and data files in LPD requests...
+ */
+
+#define ORDER_CONTROL_DATA 0
+#define ORDER_DATA_CONTROL 1
+
+
+/*
+ * It appears that rresvport() is never declared on most systems...
+ */
+
+extern int rresvport(int *port);
+
+
+/*
+ * Local functions...
+ */
+
+static int lpd_command(int lpd_fd, char *format, ...);
+static int lpd_queue(char *hostname, char *printer, char *filename,
+ int fromstdin, char *user, char *title, int copies,
+ int banner, int format, int order, int reserve,
+ int manual_copies);
+static void lpd_timeout(int sig);
+static int lpd_write(int lpd_fd, char *buffer, int length);
+
+
+/*
+ * 'main()' - Send a file to the printer or server.
+ *
+ * Usage:
+ *
+ * printer-uri job-id user title copies options [file]
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments (6 or 7) */
+ char *argv[]) /* I - Command-line arguments */
+{
+ char method[255], /* Method in URI */
+ hostname[1024], /* Hostname */
+ username[255], /* Username info (not used) */
+ resource[1024], /* Resource info (printer name) */
+ *options, /* Pointer to options */
+ name[255], /* Name of option */
+ value[255], /* Value of option */
+ *ptr, /* Pointer into name or value */
+ filename[1024], /* File to print */
+ title[256]; /* Title string */
+ int port; /* Port number (not used) */
+ int status; /* Status of LPD job */
+ int banner; /* Print banner page? */
+ int format; /* Print format */
+ int order; /* Order of control/data files */
+ int reserve; /* Reserve priviledged port? */
+ int manual_copies, /* Do manual copies? */
+ copies; /* Number of copies */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc == 1)
+ {
+ puts("network lpd \"Unknown\" \"LPD/LPR Host or Printer\"");
+ return (0);
+ }
+ else if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
+ argv[0]);
+ return (1);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, copy stdin to a temporary file and print the temporary
+ * file.
+ */
+
+ if (argc == 6)
+ {
+ /*
+ * Copy stdin to a temporary file...
+ */
+
+ int fd; /* Temporary file */
+ char buffer[8192]; /* Buffer for copying */
+ int bytes; /* Number of bytes read */
+
+
+ if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
+ {
+ perror("ERROR: unable to create temporary file");
+ return (1);
+ }
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ if (write(fd, buffer, bytes) < bytes)
+ {
+ perror("ERROR: unable to write to temporary file");
+ close(fd);
+ unlink(filename);
+ return (1);
+ }
+
+ close(fd);
+ }
+ else
+ strlcpy(filename, argv[6], sizeof(filename));
+
+ /*
+ * Extract the hostname and printer name from the URI...
+ */
+
+ httpSeparate(argv[0], method, username, hostname, &port, resource);
+
+ /*
+ * See if there are any options...
+ */
+
+ banner = 0;
+ format = 'l';
+ order = ORDER_CONTROL_DATA;
+ reserve = 0;
+ manual_copies = 1;
+
+ if ((options = strchr(resource, '?')) != NULL)
+ {
+ /*
+ * Yup, terminate the device name string and move to the first
+ * character of the options...
+ */
+
+ *options++ = '\0';
+
+ /*
+ * Parse options...
+ */
+
+ while (*options)
+ {
+ /*
+ * Get the name...
+ */
+
+ for (ptr = name; *options && *options != '=';)
+ *ptr++ = *options++;
+ *ptr = '\0';
+
+ if (*options == '=')
+ {
+ /*
+ * Get the value...
+ */
+
+ options ++;
+
+ for (ptr = value; *options && *options != '+';)
+ *ptr++ = *options++;
+ *ptr = '\0';
+
+ if (*options == '+')
+ options ++;
+ }
+ else
+ value[0] = '\0';
+
+ /*
+ * Process the option...
+ */
+
+ if (strcasecmp(name, "banner") == 0)
+ {
+ /*
+ * Set the banner...
+ */
+
+ banner = !value[0] ||
+ strcasecmp(value, "on") == 0 ||
+ strcasecmp(value, "yes") == 0 ||
+ strcasecmp(value, "true") == 0;
+ }
+ else if (strcasecmp(name, "format") == 0 && value[0])
+ {
+ /*
+ * Set output format...
+ */
+
+ if (strchr("cdfglnoprtv", value[0]) != NULL)
+ format = value[0];
+ else
+ fprintf(stderr, "ERROR: Unknown format character \"%c\"\n", value[0]);
+ }
+ else if (strcasecmp(name, "order") == 0 && value[0])
+ {
+ /*
+ * Set control/data order...
+ */
+
+ if (strcasecmp(value, "control,data") == 0)
+ order = ORDER_CONTROL_DATA;
+ else if (strcasecmp(value, "data,control") == 0)
+ order = ORDER_DATA_CONTROL;
+ else
+ fprintf(stderr, "ERROR: Unknown file order \"%s\"\n", value);
+ }
+ else if (strcasecmp(name, "reserve") == 0)
+ {
+ /*
+ * Set port reservation mode...
+ */
+
+ reserve = !value[0] ||
+ strcasecmp(value, "on") == 0 ||
+ strcasecmp(value, "yes") == 0 ||
+ strcasecmp(value, "true") == 0;
+ }
+ else if (strcasecmp(name, "manual_copies") == 0)
+ {
+ /*
+ * Set port reservation mode...
+ */
+
+ manual_copies = !value[0] ||
+ strcasecmp(value, "on") == 0 ||
+ strcasecmp(value, "yes") == 0 ||
+ strcasecmp(value, "true") == 0;
+ }
+ }
+ }
+
+ /*
+ * Sanitize the document title...
+ */
+
+ strlcpy(title, argv[3], sizeof(title));
+
+ for (ptr = title; *ptr; ptr ++)
+ if (!isalnum(*ptr) && !isspace(*ptr))
+ *ptr = '_';
+
+ /*
+ * Queue the job...
+ */
+
+ if (argc > 6)
+ {
+ if (manual_copies)
+ {
+ manual_copies = atoi(argv[4]);
+ copies = 1;
+ }
+ else
+ {
+ manual_copies = 1;
+ copies = atoi(argv[4]);
+ }
+
+ status = lpd_queue(hostname, resource + 1, filename, 0,
+ argv[2] /* user */, title, copies,
+ banner, format, order, reserve, manual_copies);
+
+ if (!status)
+ fprintf(stderr, "PAGE: 1 %d\n", atoi(argv[4]));
+ }
+ else
+ status = lpd_queue(hostname, resource + 1, filename, 1,
+ argv[2] /* user */, title, 1,
+ banner, format, order, reserve, 1);
+
+ /*
+ * Remove the temporary file if necessary...
+ */
+
+ if (argc < 7)
+ unlink(filename);
+
+ /*
+ * Return the queue status...
+ */
+
+ return (status);
+}
+
+
+/*
+ * 'lpd_command()' - Send an LPR command sequence and wait for a reply.
+ */
+
+static int /* O - Status of command */
+lpd_command(int fd, /* I - Socket connection to LPD host */
+ char *format, /* I - printf()-style format string */
+ ...) /* I - Additional args as necessary */
+{
+ va_list ap; /* Argument pointer */
+ char buf[1024]; /* Output buffer */
+ int bytes; /* Number of bytes to output */
+ char status; /* Status from command */
+
+
+ /*
+ * Format the string...
+ */
+
+ va_start(ap, format);
+ bytes = vsnprintf(buf, sizeof(buf), format, ap);
+ va_end(ap);
+
+ fprintf(stderr, "DEBUG: lpd_command %2.2x %s", buf[0], buf + 1);
+
+ /*
+ * Send the command...
+ */
+
+ fprintf(stderr, "DEBUG: Sending command string (%d bytes)...\n", bytes);
+
+ alarm(30);
+
+ if (lpd_write(fd, buf, bytes) < bytes)
+ return (-1);
+
+ /*
+ * Read back the status from the command and return it...
+ */
+
+ fprintf(stderr, "DEBUG: Reading command status...\n");
+
+ alarm(30);
+
+ if (recv(fd, &status, 1, 0) < 1)
+ return (-1);
+
+ alarm(0);
+
+ fprintf(stderr, "DEBUG: lpd_command returning %d\n", status);
+
+ return (status);
+}
+
+
+/*
+ * 'lpd_queue()' - Queue a file using the Line Printer Daemon protocol.
+ */
+
+static int /* O - Zero on success, non-zero on failure */
+lpd_queue(char *hostname, /* I - Host to connect to */
+ char *printer, /* I - Printer/queue name */
+ char *filename, /* I - File to print */
+ int fromstdin, /* I - Printing from stdin? */
+ char *user, /* I - Requesting user */
+ char *title, /* I - Job title */
+ int copies, /* I - Number of copies */
+ int banner, /* I - Print LPD banner? */
+ int format, /* I - Format specifier */
+ int order, /* I - Order of data/control files */
+ int reserve, /* I - Reserve ports? */
+ int manual_copies) /* I - Do copies by hand... */
+{
+ int tries; /* Number of tries */
+ FILE *fp; /* Job file */
+ char localhost[255]; /* Local host name */
+ int error; /* Error number */
+ struct stat filestats; /* File statistics */
+ int port; /* LPD connection port */
+ int fd; /* LPD socket */
+ char control[10240], /* LPD control 'file' */
+ *cptr; /* Pointer into control file string */
+ char status; /* Status byte from command */
+ struct sockaddr_in addr; /* Socket address */
+ struct hostent *hostaddr; /* Host address */
+ size_t nbytes, /* Number of bytes written */
+ tbytes; /* Total bytes written */
+ char buffer[8192]; /* Output buffer */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+
+ for (tries = 0; tries < 10; tries ++)
+ {
+ /*
+ * First try to reserve a port for this connection...
+ */
+
+ if ((hostaddr = httpGetHostByName(hostname)) == NULL)
+ {
+ fprintf(stderr, "ERROR: Unable to locate printer \'%s\' - %s",
+ hostname, strerror(errno));
+ return (1);
+ }
+
+ fprintf(stderr, "INFO: Attempting to connect to host %s for printer %s\n",
+ hostname, printer);
+
+ memset(&addr, 0, sizeof(addr));
+ memcpy(&(addr.sin_addr), hostaddr->h_addr, hostaddr->h_length);
+ addr.sin_family = hostaddr->h_addrtype;
+ addr.sin_port = htons(515); /* LPD/printer service */
+
+ for (port = 732;;)
+ {
+ if (getuid() || !reserve)
+ {
+ /*
+ * Just create a regular socket...
+ */
+
+ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ perror("ERROR: Unable to create socket");
+ return (1);
+ }
+ }
+ else
+ {
+ /*
+ * We're running as root and want to comply with RFC 1179. Reserve a
+ * priviledged port between 721 and 732...
+ */
+
+ if ((fd = rresvport(&port)) < 0)
+ {
+ perror("ERROR: Unable to reserve port");
+ sleep(30);
+ continue;
+ }
+ }
+
+ if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+ {
+ error = errno;
+ close(fd);
+ fd = -1;
+
+ if (error == ECONNREFUSED || error == EHOSTDOWN ||
+ error == EHOSTUNREACH)
+ {
+ fprintf(stderr, "INFO: Network host \'%s\' is busy; will retry in 30 seconds...",
+ hostname);
+ sleep(30);
+ }
+ else if (error == EADDRINUSE)
+ {
+ port --;
+ if (port < 721)
+ port = 732;
+ }
+ else
+ {
+ perror("ERROR: Unable to connect to printer");
+ sleep(30);
+ }
+ }
+ else
+ break;
+ }
+
+ fprintf(stderr, "INFO: Connected from port %d...\n", port);
+
+ /*
+ * Now that we are "connected" to the port, ignore SIGTERM so that we
+ * can finish out any page data the driver sends (e.g. to eject the
+ * current page... Only ignore SIGTERM if we are printing data from
+ * stdin (otherwise you can't cancel raw jobs...)
+ */
+
+ if (fromstdin)
+ {
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+ }
+
+ /*
+ * Setup an alarm handler for timeouts...
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGALRM, lpd_timeout);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = lpd_timeout;
+ sigaction(SIGALRM, &action, NULL);
+#else
+ signal(SIGALRM, lpd_timeout);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Next, open the print file and figure out its size...
+ */
+
+ if (stat(filename, &filestats))
+ {
+ perror("ERROR: unable to stat print file");
+ return (1);
+ }
+
+ filestats.st_size *= manual_copies;
+
+ if ((fp = fopen(filename, "rb")) == NULL)
+ {
+ perror("ERROR: unable to open print file for reading");
+ return (1);
+ }
+
+ /*
+ * Send a job header to the printer, specifying no banner page and
+ * literal output...
+ */
+
+ lpd_command(fd, "\002%s\n", printer); /* Receive print job(s) */
+
+ gethostname(localhost, sizeof(localhost));
+ localhost[31] = '\0'; /* RFC 1179, Section 7.2 - host name < 32 chars */
+
+ snprintf(control, sizeof(control), "H%s\nP%s\nJ%s\n", localhost, user, title);
+ cptr = control + strlen(control);
+
+ if (banner)
+ {
+ snprintf(cptr, sizeof(control) - (cptr - control), "L%s\n", user);
+ cptr += strlen(cptr);
+ }
+
+ while (copies > 0)
+ {
+ snprintf(cptr, sizeof(control) - (cptr - control), "%cdfA%03d%s\n", format,
+ getpid() % 1000, localhost);
+ cptr += strlen(cptr);
+ copies --;
+ }
+
+ snprintf(cptr, sizeof(control) - (cptr - control),
+ "UdfA%03d%s\nNdfA%03d%s\n",
+ getpid() % 1000, localhost,
+ getpid() % 1000, localhost);
+
+ fprintf(stderr, "DEBUG: Control file is:\n%s", control);
+
+ if (order == ORDER_CONTROL_DATA)
+ {
+ lpd_command(fd, "\002%d cfA%03.3d%s\n", strlen(control), getpid() % 1000,
+ localhost);
+
+ fprintf(stderr, "INFO: Sending control file (%lu bytes)\n", (unsigned long)strlen(control));
+
+ alarm(30);
+
+ if (lpd_write(fd, control, strlen(control) + 1) < (strlen(control) + 1))
+ {
+ status = errno;
+ perror("ERROR: Unable to write control file");
+ }
+ else
+ {
+ alarm(30);
+
+ if (read(fd, &status, 1) < 1)
+ status = errno;
+
+ alarm(0);
+ }
+
+ if (status != 0)
+ fprintf(stderr, "ERROR: Remote host did not accept control file (%d)\n",
+ status);
+ else
+ fputs("INFO: Control file sent successfully\n", stderr);
+ }
+ else
+ status = 0;
+
+ if (status == 0)
+ {
+ /*
+ * Send the print file...
+ */
+
+ lpd_command(fd, "\003%u dfA%03.3d%s\n", (unsigned)filestats.st_size,
+ getpid() % 1000, localhost);
+
+ fprintf(stderr, "INFO: Sending data file (%u bytes)\n",
+ (unsigned)filestats.st_size);
+
+ tbytes = 0;
+ while (manual_copies > 0)
+ {
+ rewind(fp);
+
+ while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
+ {
+ fprintf(stderr, "INFO: Spooling LPR job, %u%% complete...\n",
+ (unsigned)(100.0f * tbytes / filestats.st_size));
+
+ if (lpd_write(fd, buffer, nbytes) < nbytes)
+ {
+ perror("ERROR: Unable to send print file to printer");
+ break;
+ }
+ else
+ tbytes += nbytes;
+ }
+
+ manual_copies --;
+ }
+
+ if (tbytes < filestats.st_size)
+ status = errno;
+ else if (lpd_write(fd, "", 1) < 1)
+ status = errno;
+ else
+ {
+ alarm(30);
+
+ if (recv(fd, &status, 1, 0) < 1)
+ status = errno;
+
+ alarm(0);
+ }
+
+ if (status != 0)
+ fprintf(stderr, "ERROR: Remote host did not accept data file (%d)\n",
+ status);
+ else
+ fputs("INFO: Data file sent successfully\n", stderr);
+ }
+
+ if (status == 0 && order == ORDER_DATA_CONTROL)
+ {
+ lpd_command(fd, "\002%d cfA%03.3d%s\n", strlen(control), getpid() % 1000,
+ localhost);
+
+ fprintf(stderr, "INFO: Sending control file (%lu bytes)\n", (unsigned long)strlen(control));
+
+ alarm(30);
+
+ if (lpd_write(fd, control, strlen(control) + 1) < (strlen(control) + 1))
+ {
+ status = errno;
+ perror("ERROR: Unable to write control file");
+ }
+ else
+ {
+ alarm(30);
+
+ if (read(fd, &status, 1) < 1)
+ status = errno;
+
+ alarm(0);
+ }
+
+ if (status != 0)
+ fprintf(stderr, "ERROR: Remote host did not accept control file (%d)\n",
+ status);
+ else
+ fputs("INFO: Control file sent successfully\n", stderr);
+ }
+
+ /*
+ * Close the socket connection and input file...
+ */
+
+ close(fd);
+ fclose(fp);
+
+ if (status == 0)
+ break;
+ }
+
+ if (status)
+ {
+ fputs("ERROR: Unable to queue job on remote printer after 10 "
+ "connections - aborting!\n", stderr);
+
+ return (status);
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'lpd_timeout()' - Handle timeout alarms...
+ */
+
+static void
+lpd_timeout(int sig) /* I - Signal number */
+{
+ (void)sig;
+
+#if !defined(HAVE_SIGSET) && !defined(HAVE_SIGACTION)
+ signal(SIGALRM, lpd_timeout);
+#endif /* !HAVE_SIGSET && !HAVE_SIGACTION */
+}
+
+
+/*
+ * 'lpd_write()' - Write a buffer of data to an LPD server.
+ */
+
+static int /* O - Number of bytes written or -1 on error */
+lpd_write(int lpd_fd, /* I - LPD socket */
+ char *buffer, /* I - Buffer to write */
+ int length) /* I - Number of bytes to write */
+{
+ int bytes, /* Number of bytes written */
+ total; /* Total number of bytes written */
+
+
+ total = 0;
+ while ((bytes = send(lpd_fd, buffer, length - total, 0)) >= 0)
+ {
+ total += bytes;
+ buffer += bytes;
+
+ if (total == length)
+ break;
+ }
+
+ if (bytes < 0)
+ return (-1);
+ else
+ return (length);
+}
+
+
+#ifndef HAVE_RRESVPORT
+/*
+ * 'rresvport()' - A simple implementation of rresvport().
+ */
+
+int /* O - Socket or -1 on error */
+rresvport(int *port) /* IO - Port number to bind to */
+{
+ struct sockaddr_in addr; /* Socket address */
+ int fd; /* Socket file descriptor */
+
+
+ /*
+ * Try to create an IPv4 socket...
+ */
+
+ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ return (-1);
+
+ /*
+ * Initialize the address buffer...
+ */
+
+ memset(&addr, 0, sizeof(addr));
+
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ /*
+ * Try to bind the socket to a reserved port; unlike the standard
+ * BSD rresvport(), we limit the port number to 721 through 732
+ * (instead of 512 to 1023) since RFC 1179 defines the local port
+ * number between 721 and 732...
+ */
+
+ while (*port > 720)
+ {
+ /*
+ * Set the port number...
+ */
+
+ addr.sin_port = htons(*port);
+
+ /*
+ * Try binding the port to the socket; return if all is OK...
+ */
+
+ if (!bind(fd, (struct sockaddr *)&addr, sizeof(addr)))
+ return (fd);
+
+ /*
+ * Stop if we have any error other than "address already in use"...
+ */
+
+ if (errno != EADDRINUSE)
+ {
+# ifdef WIN32
+ closesocket(fd);
+# else
+ close(fd);
+# endif /* WIN32 */
+
+ return (-1);
+ }
+
+ /*
+ * Try the next port...
+ */
+
+ (*port)--;
+ }
+
+ /*
+ * Wasn't able to bind to a reserved port, so close the socket and return
+ * -1...
+ */
+
+# ifdef WIN32
+ closesocket(fd);
+# else
+ close(fd);
+# endif /* WIN32 */
+
+ return (-1);
+}
+#endif /* !HAVE_RRESVPORT */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/backend/parallel.c b/backend/parallel.c
new file mode 100644
index 000000000..fd83b9b14
--- /dev/null
+++ b/backend/parallel.c
@@ -0,0 +1,662 @@
+/*
+ * "$Id$"
+ *
+ * Parallel port backend for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Send a file to the specified parallel port.
+ * list_devices() - List all parallel devices.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <cups/cups.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <cups/string.h>
+#include <signal.h>
+
+#ifdef WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+# include <fcntl.h>
+# include <termios.h>
+#endif /* WIN32 */
+
+#ifdef __sgi
+# include <invent.h>
+# ifndef INV_EPP_ECP_PLP
+# define INV_EPP_ECP_PLP 6 /* From 6.3/6.4/6.5 sys/invent.h */
+# define INV_ASO_SERIAL 14 /* serial portion of SGI ASO board */
+# define INV_IOC3_DMA 16 /* DMA mode IOC3 serial */
+# define INV_IOC3_PIO 17 /* PIO mode IOC3 serial */
+# define INV_ISA_DMA 19 /* DMA mode ISA serial -- O2 */
+# endif /* !INV_EPP_ECP_PLP */
+#endif /* __sgi */
+
+
+/*
+ * Local functions...
+ */
+
+void list_devices(void);
+
+
+/*
+ * 'main()' - Send a file to the specified parallel port.
+ *
+ * Usage:
+ *
+ * printer-uri job-id user title copies options [file]
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments (6 or 7) */
+ char *argv[]) /* I - Command-line arguments */
+{
+ char method[255], /* Method in URI */
+ hostname[1024], /* Hostname */
+ username[255], /* Username info (not used) */
+ resource[1024], /* Resource info (device and options) */
+ *options; /* Pointer to options */
+ int port; /* Port number (not used) */
+ int fp; /* Print file */
+ int copies; /* Number of copies to print */
+ int fd; /* Parallel device */
+ int wbytes; /* Number of bytes written */
+ size_t nbytes, /* Number of bytes read */
+ tbytes; /* Total number of bytes written */
+ char buffer[8192], /* Output buffer */
+ *bufptr; /* Pointer into buffer */
+ struct termios opts; /* Parallel port options */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc == 1)
+ {
+ list_devices();
+ return (0);
+ }
+ else if (argc < 6 || argc > 7)
+ {
+ fputs("Usage: parallel job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+ if (argc == 6)
+ {
+ fp = 0;
+ copies = 1;
+ }
+ else
+ {
+ /*
+ * Try to open the print file...
+ */
+
+ if ((fp = open(argv[6], O_RDONLY)) < 0)
+ {
+ perror("ERROR: unable to open print file");
+ return (1);
+ }
+
+ copies = atoi(argv[4]);
+ }
+
+ /*
+ * Extract the device name and options from the URI...
+ */
+
+ httpSeparate(argv[0], method, username, hostname, &port, resource);
+
+ /*
+ * See if there are any options...
+ */
+
+ if ((options = strchr(resource, '?')) != NULL)
+ {
+ /*
+ * Yup, terminate the device name string and move to the first
+ * character of the options...
+ */
+
+ *options++ = '\0';
+ }
+
+ /*
+ * Open the parallel port device...
+ */
+
+ do
+ {
+ if ((fd = open(resource, O_WRONLY | O_EXCL)) == -1)
+ {
+ if (errno == EBUSY)
+ {
+ fputs("INFO: Parallel port busy; will retry in 30 seconds...\n", stderr);
+ sleep(30);
+ }
+ else if (errno == ENXIO || errno == EIO || errno == ENOENT)
+ {
+ fputs("INFO: Printer not connected; will retry in 30 seconds...\n", stderr);
+ sleep(30);
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Unable to open parallel port device file \"%s\": %s\n",
+ resource, strerror(errno));
+ return (1);
+ }
+ }
+ }
+ while (fd < 0);
+
+ /*
+ * Set any options provided...
+ */
+
+ tcgetattr(fd, &opts);
+
+ opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */
+
+ /**** No options supported yet ****/
+
+ tcsetattr(fd, TCSANOW, &opts);
+
+ /*
+ * Now that we are "connected" to the port, ignore SIGTERM so that we
+ * can finish out any page data the driver sends (e.g. to eject the
+ * current page... Only ignore SIGTERM if we are printing data from
+ * stdin (otherwise you can't cancel raw jobs...)
+ */
+
+ if (argc < 7)
+ {
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+ }
+
+ /*
+ * Finally, send the print file...
+ */
+
+ while (copies > 0)
+ {
+ copies --;
+
+ if (fp != 0)
+ {
+ fputs("PAGE: 1 1\n", stderr);
+ lseek(fp, 0, SEEK_SET);
+ }
+
+ tbytes = 0;
+ while ((nbytes = read(fp, buffer, sizeof(buffer))) > 0)
+ {
+ /*
+ * Write the print data to the printer...
+ */
+
+ tbytes += nbytes;
+ bufptr = buffer;
+
+ while (nbytes > 0)
+ {
+ if ((wbytes = write(fd, bufptr, nbytes)) < 0)
+ if (errno == ENOTTY)
+ wbytes = write(fd, bufptr, nbytes);
+
+ if (wbytes < 0)
+ {
+ perror("ERROR: Unable to send print file to printer");
+ break;
+ }
+
+ nbytes -= wbytes;
+ bufptr += wbytes;
+ }
+
+ if (argc > 6)
+ fprintf(stderr, "INFO: Sending print file, %lu bytes...\n",
+ (unsigned long)tbytes);
+ }
+ }
+
+ /*
+ * Close the socket connection and input file and return...
+ */
+
+ close(fd);
+ if (fp != 0)
+ close(fp);
+
+ fputs("INFO: Ready to print.\n", stderr);
+
+ return (0);
+}
+
+
+/*
+ * 'list_devices()' - List all parallel devices.
+ */
+
+void
+list_devices(void)
+{
+#if defined(__hpux) || defined(__sgi) || defined(__sun)
+ static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz";
+ /* Funky hex numbering used for some devices */
+#endif /* __hpux || __sgi || __sun */
+
+#ifdef __linux
+ int i; /* Looping var */
+ int fd; /* File descriptor */
+ char device[255], /* Device filename */
+ probefile[255], /* Probe filename */
+ basedevice[255]; /* Base device filename for ports */
+ FILE *probe; /* /proc/parport/n/autoprobe file */
+ char line[1024], /* Line from file */
+ *delim, /* Delimiter in file */
+ make[IPP_MAX_NAME], /* Make from file */
+ model[IPP_MAX_NAME]; /* Model from file */
+
+
+ for (i = 0; i < 4; i ++)
+ {
+ /*
+ * First open the device to make sure the driver module is loaded...
+ */
+
+ if ((fd = open("/dev/parallel/0", O_WRONLY)) >= 0)
+ {
+ close(fd);
+ strcpy(basedevice, "/dev/parallel/");
+ }
+ else
+ {
+ sprintf(device, "/dev/lp%d", i);
+ if ((fd = open(device, O_WRONLY)) >= 0)
+ {
+ close(fd);
+ strcpy(basedevice, "/dev/lp");
+ }
+ else
+ {
+ sprintf(device, "/dev/par%d", i);
+ if ((fd = open(device, O_WRONLY)) >= 0)
+ {
+ close(fd);
+ strcpy(basedevice, "/dev/par");
+ }
+ else
+ {
+ sprintf(device, "/dev/printers/%d", i);
+ if ((fd = open(device, O_WRONLY)) >= 0)
+ {
+ close(fd);
+ strcpy(basedevice, "/dev/printers/");
+ }
+ else
+ strcpy(basedevice, "/dev/unknown-parallel");
+ }
+ }
+ }
+
+ /*
+ * Then try looking at the probe file...
+ */
+
+ sprintf(probefile, "/proc/parport/%d/autoprobe", i);
+ if ((probe = fopen(probefile, "r")) == NULL)
+ {
+ /*
+ * Linux 2.4 kernel has different path...
+ */
+
+ sprintf(probefile, "/proc/sys/dev/parport/parport%d/autoprobe", i);
+ probe = fopen(probefile, "r");
+ }
+
+ if (probe != NULL)
+ {
+ /*
+ * Found a probe file!
+ */
+
+ memset(make, 0, sizeof(make));
+ memset(model, 0, sizeof(model));
+ strcpy(model, "Unknown");
+
+ while (fgets(line, sizeof(line), probe) != NULL)
+ {
+ /*
+ * Strip trailing ; and/or newline.
+ */
+
+ if ((delim = strrchr(line, ';')) != NULL)
+ *delim = '\0';
+ else if ((delim = strrchr(line, '\n')) != NULL)
+ *delim = '\0';
+
+ /*
+ * Look for MODEL and MANUFACTURER lines...
+ */
+
+ if (strncmp(line, "MODEL:", 6) == 0 &&
+ strncmp(line, "MODEL:Unknown", 13) != 0)
+ strlcpy(model, line + 6, sizeof(model));
+ else if (strncmp(line, "MANUFACTURER:", 13) == 0 &&
+ strncmp(line, "MANUFACTURER:Unknown", 20) != 0)
+ strlcpy(make, line + 13, sizeof(make));
+ }
+
+ fclose(probe);
+
+ if (make[0])
+ printf("direct parallel:%s%d \"%s %s\" \"Parallel Port #%d\"\n",
+ basedevice, i, make, model, i + 1);
+ else
+ printf("direct parallel:%s%d \"%s\" \"Parallel Port #%d\"\n",
+ basedevice, i, model, i + 1);
+ }
+ else if (fd >= 0)
+ {
+ /*
+ * No probe file, but we know the port is there...
+ */
+
+ printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1);
+ }
+ }
+#elif defined(__sgi)
+ int i, j, n; /* Looping vars */
+ char device[255]; /* Device filename */
+ inventory_t *inv; /* Hardware inventory info */
+
+
+ /*
+ * IRIX maintains a hardware inventory of most devices...
+ */
+
+ setinvent();
+
+ while ((inv = getinvent()) != NULL)
+ {
+ if (inv->inv_class == INV_PARALLEL &&
+ (inv->inv_type == INV_ONBOARD_PLP ||
+ inv->inv_type == INV_EPP_ECP_PLP))
+ {
+ /*
+ * Standard parallel port...
+ */
+
+ puts("direct parallel:/dev/plp \"Unknown\" \"Onboard Parallel Port\"");
+ }
+ else if (inv->inv_class == INV_PARALLEL &&
+ inv->inv_type == INV_EPC_PLP)
+ {
+ /*
+ * EPC parallel port...
+ */
+
+ printf("direct parallel:/dev/plp%d \"Unknown\" \"Integral EPC parallel port, Ebus slot %d\"\n",
+ inv->inv_controller, inv->inv_controller);
+ }
+ }
+
+ endinvent();
+
+ /*
+ * Central Data makes serial and parallel "servers" that can be
+ * connected in a number of ways. Look for ports...
+ */
+
+ for (i = 0; i < 10; i ++)
+ for (j = 0; j < 8; j ++)
+ for (n = 0; n < 32; n ++)
+ {
+ if (i == 8) /* EtherLite */
+ sprintf(device, "/dev/lpn%d%c", j, funky_hex[n]);
+ else if (i == 9) /* PCI */
+ sprintf(device, "/dev/lpp%d%c", j, funky_hex[n]);
+ else /* SCSI */
+ sprintf(device, "/dev/lp%d%d%c", i, j, funky_hex[n]);
+
+ if (access(device, 0) == 0)
+ {
+ if (i == 8)
+ printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n",
+ device, j, n);
+ else if (i == 9)
+ printf("direct parallel:%s \"Unknown\" \"Central Data PCI Parallel Port, ID %d, port %d\"\n",
+ device, j, n);
+ else
+ printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n",
+ device, i, j, n);
+ }
+ }
+#elif defined(__sun)
+ int i, j, n; /* Looping vars */
+ char device[255]; /* Device filename */
+
+
+ /*
+ * Standard parallel ports...
+ */
+
+ for (i = 0; i < 10; i ++)
+ {
+ sprintf(device, "/dev/ecpp%d", i);
+ if (access(device, 0) == 0)
+ printf("direct parallel:%s \"Unknown\" \"Sun IEEE-1284 Parallel Port #%d\"\n",
+ device, i + 1);
+ }
+
+ for (i = 0; i < 10; i ++)
+ {
+ sprintf(device, "/dev/bpp%d", i);
+ if (access(device, 0) == 0)
+ printf("direct parallel:%s \"Unknown\" \"Sun Standard Parallel Port #%d\"\n",
+ device, i + 1);
+ }
+
+ for (i = 0; i < 3; i ++)
+ {
+ sprintf(device, "/dev/lp%d", i);
+
+ if (access(device, 0) == 0)
+ printf("direct parallel:%s \"Unknown\" \"PC Parallel Port #%d\"\n",
+ device, i + 1);
+ }
+
+ /*
+ * MAGMA parallel ports...
+ */
+
+ for (i = 0; i < 40; i ++)
+ {
+ sprintf(device, "/dev/pm%02d", i);
+ if (access(device, 0) == 0)
+ printf("direct parallel:%s \"Unknown\" \"MAGMA Parallel Board #%d Port #%d\"\n",
+ device, (i / 10) + 1, (i % 10) + 1);
+ }
+
+ /*
+ * Central Data parallel ports...
+ */
+
+ for (i = 0; i < 9; i ++)
+ for (j = 0; j < 8; j ++)
+ for (n = 0; n < 32; n ++)
+ {
+ if (i == 8) /* EtherLite */
+ sprintf(device, "/dev/sts/lpN%d%c", j, funky_hex[n]);
+ else
+ sprintf(device, "/dev/sts/lp%c%d%c", i + 'C', j,
+ funky_hex[n]);
+
+ if (access(device, 0) == 0)
+ {
+ if (i == 8)
+ printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n",
+ device, j, n);
+ else
+ printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n",
+ device, i, j, n);
+ }
+ }
+#elif defined(__hpux)
+ int i, j, n; /* Looping vars */
+ char device[255]; /* Device filename */
+
+
+ /*
+ * Standard parallel ports...
+ */
+
+ if (access("/dev/rlp", 0) == 0)
+ puts("direct parallel:/dev/rlp \"Unknown\" \"Standard Parallel Port (/dev/rlp)\"");
+
+ for (i = 0; i < 7; i ++)
+ for (j = 0; j < 7; j ++)
+ {
+ sprintf(device, "/dev/c%dt%dd0_lp", i, j);
+ if (access(device, 0) == 0)
+ printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d,%d\"\n",
+ device, i, j);
+ }
+
+ /*
+ * Central Data parallel ports...
+ */
+
+ for (i = 0; i < 9; i ++)
+ for (j = 0; j < 8; j ++)
+ for (n = 0; n < 32; n ++)
+ {
+ if (i == 8) /* EtherLite */
+ sprintf(device, "/dev/lpN%d%c", j, funky_hex[n]);
+ else
+ sprintf(device, "/dev/lp%c%d%c", i + 'C', j,
+ funky_hex[n]);
+
+ if (access(device, 0) == 0)
+ {
+ if (i == 8)
+ printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n",
+ device, j, n);
+ else
+ printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n",
+ device, i, j, n);
+ }
+ }
+#elif defined(__osf__)
+ int i; /* Looping var */
+ int fd; /* File descriptor */
+ char device[255]; /* Device filename */
+
+
+ for (i = 0; i < 3; i ++)
+ {
+ sprintf(device, "/dev/lp%d", i);
+ if ((fd = open(device, O_WRONLY)) >= 0)
+ {
+ close(fd);
+ printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1);
+ }
+ }
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+ int i; /* Looping var */
+ int fd; /* File descriptor */
+ char device[255]; /* Device filename */
+
+
+ for (i = 0; i < 3; i ++)
+ {
+ sprintf(device, "/dev/lpt%d", i);
+ if ((fd = open(device, O_WRONLY)) >= 0)
+ {
+ close(fd);
+ printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (interrupt-driven)\"\n", device, i + 1);
+ }
+
+ sprintf(device, "/dev/lpa%d", i);
+ if ((fd = open(device, O_WRONLY)) >= 0)
+ {
+ close(fd);
+ printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (polled)\"\n", device, i + 1);
+ }
+ }
+#elif defined(_AIX)
+ int i; /* Looping var */
+ int fd; /* File descriptor */
+ char device[255]; /* Device filename */
+
+
+ for (i = 0; i < 8; i ++)
+ {
+ sprintf(device, "/dev/lp%d", i);
+ if ((fd = open(device, O_WRONLY)) >= 0)
+ {
+ close(fd);
+ printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1);
+ }
+ }
+#endif
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/backend/scsi-irix.c b/backend/scsi-irix.c
new file mode 100644
index 000000000..1c2f9943c
--- /dev/null
+++ b/backend/scsi-irix.c
@@ -0,0 +1,211 @@
+/*
+ * "$Id$"
+ *
+ * IRIX SCSI printer support for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 2002 by Easy Software Products, all rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use
+ * of this software must display the following
+ * acknowledgement:
+ *
+ * This product includes software developed by Easy
+ * Software Products.
+ *
+ * 4. The name of Easy Software Products may not be used to
+ * endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Contents:
+ *
+ * list_devices() - List the available SCSI printer devices.
+ * print_device() - Print a file to a SCSI device.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <bstring.h> /* memcpy() and friends */
+#include <sys/dsreq.h> /* SCSI interface stuff */
+
+
+/*
+ * 'list_devices()' - List the available SCSI printer devices.
+ */
+
+void
+list_devices(void)
+{
+ puts("direct scsi \"Unknown\" \"SCSI Printer\"");
+}
+
+
+/*
+ * 'print_device()' - Print a file to a SCSI device.
+ */
+
+int /* O - Print status */
+print_device(const char *resource, /* I - SCSI device */
+ int fd, /* I - File to print */
+ int copies) /* I - Number of copies to print */
+{
+ int scsi_fd; /* SCSI file descriptor */
+ char buffer[8192]; /* Data buffer */
+ int bytes; /* Number of bytes */
+ int try; /* Current try */
+ dsreq_t scsi_req; /* SCSI request */
+ char scsi_cmd[6], /* SCSI command data */
+ scsi_sense[32]; /* SCSI sense data */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Make sure we have a valid resource name...
+ */
+
+ if (strncmp(resource, "/dev/scsi/", 10) != 0)
+ {
+ fprintf(stderr, "ERROR: Bad SCSI device file \"%s\"!\n", resource);
+ return (1);
+ }
+
+ /*
+ * Open the SCSI device file...
+ */
+
+ do
+ {
+ if ((scsi_fd = open(resource, O_RDWR | O_EXCL)) == -1)
+ {
+ if (errno != EAGAIN && errno != EBUSY)
+ {
+ fprintf(stderr, "ERROR: Unable to open SCSI device \"%s\" - %s\n",
+ resource, strerror(errno));
+ return (1);
+ }
+ else
+ {
+ fprintf(stderr, "INFO: SCSI device \"%s\" busy; retrying...\n",
+ resource);
+ sleep(30);
+ }
+ }
+ }
+ while (scsi_fd == -1);
+
+ /*
+ * Now that we are "connected" to the port, ignore SIGTERM so that we
+ * can finish out any page data the driver sends (e.g. to eject the
+ * current page... Only ignore SIGTERM if we are printing data from
+ * stdin (otherwise you can't cancel raw jobs...)
+ */
+
+ if (fd != 0)
+ {
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+ }
+
+ /*
+ * Copy the print file to the device...
+ */
+
+ while (copies > 0)
+ {
+ if (fd != 0)
+ lseek(fd, 0, SEEK_SET);
+
+ while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
+ {
+ memset(&scsi_req, 0, sizeof(scsi_req));
+
+ scsi_req.ds_flags = DSRQ_WRITE;
+ scsi_req.ds_time = 60 * 1000;
+ scsi_req.ds_cmdbuf = scsi_cmd;
+ scsi_req.ds_cmdlen = 6;
+ scsi_req.ds_databuf = buffer;
+ scsi_req.ds_datalen = bytes;
+
+ scsi_cmd[0] = 0x0a; /* Group 0 print command */
+ scsi_cmd[1] = 0x00;
+ scsi_cmd[2] = bytes / 65536;
+ scsi_cmd[3] = bytes / 256;
+ scsi_cmd[4] = bytes;
+ scsi_cmd[5] = 0x00;
+
+ for (try = 0; try < 10; try ++)
+ if (ioctl(scsi_fd, DS_ENTER, &scsi_req) < 0 ||
+ scsi_req.ds_status != 0)
+ {
+ fprintf(stderr, "WARNING: SCSI command timed out (%d); retrying...\n",
+ scsi_req.ds_status);
+ sleep(try + 1);
+ }
+ else
+ break;
+
+ if (try >= 10)
+ {
+ fprintf(stderr, "ERROR: Unable to send print data (%d)\n",
+ scsi_req.ds_status);
+ close(scsi_fd);
+ return (1);
+ }
+ }
+
+ copies --;
+ }
+
+ /*
+ * Close the device and return...
+ */
+
+ close(fd);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/backend/scsi-linux.c b/backend/scsi-linux.c
new file mode 100644
index 000000000..66fdd9c88
--- /dev/null
+++ b/backend/scsi-linux.c
@@ -0,0 +1,228 @@
+/*
+ * "$Id$"
+ *
+ * Linux SCSI printer support for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 2002 by Easy Software Products, all rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use
+ * of this software must display the following
+ * acknowledgement:
+ *
+ * This product includes software developed by Easy
+ * Software Products.
+ *
+ * 4. The name of Easy Software Products may not be used to
+ * endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Contents:
+ *
+ * list_devices() - List the available SCSI printer devices.
+ * print_device() - Print a file to a SCSI device.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <scsi/sg.h>
+
+
+/*
+ * We currently only support the Linux 2.4 generic SCSI interface.
+ */
+
+#ifndef SG_DXFER_TO_DEV
+/*
+ * Dummy functions that do nothing on unsupported platforms...
+ */
+void list_devices(void) {}
+int print_device(const char *resource, int fd, int copies) { return (1); }
+#else
+
+
+/*
+ * 'list_devices()' - List the available SCSI printer devices.
+ */
+
+void
+list_devices(void)
+{
+ puts("direct scsi \"Unknown\" \"SCSI Printer\"");
+}
+
+
+/*
+ * 'print_device()' - Print a file to a SCSI device.
+ */
+
+int /* O - Print status */
+print_device(const char *resource, /* I - SCSI device */
+ int fd, /* I - File to print */
+ int copies) /* I - Number of copies to print */
+{
+ int scsi_fd; /* SCSI file descriptor */
+ char buffer[8192]; /* Data buffer */
+ int bytes; /* Number of bytes */
+ int try; /* Current try */
+ sg_io_hdr_t scsi_req; /* SCSI request */
+ char scsi_cmd[6], /* SCSI command data */
+ scsi_sense[32]; /* SCSI sense data */
+# if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+# endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Make sure we have a valid resource name...
+ */
+
+ if (strncmp(resource, "/dev/sg", 7) != 0)
+ {
+ fprintf(stderr, "ERROR: Bad SCSI device file \"%s\"!\n", resource);
+ return (1);
+ }
+
+ /*
+ * Open the SCSI device file...
+ */
+
+ do
+ {
+ if ((scsi_fd = open(resource, O_RDWR | O_EXCL)) == -1)
+ {
+ if (errno != EAGAIN && errno != EBUSY)
+ {
+ fprintf(stderr, "ERROR: Unable to open SCSI device \"%s\" - %s\n",
+ resource, strerror(errno));
+ return (1);
+ }
+ else
+ {
+ fprintf(stderr, "INFO: SCSI device \"%s\" busy; retrying...\n",
+ resource);
+ sleep(30);
+ }
+ }
+ }
+ while (scsi_fd == -1);
+
+ /*
+ * Now that we are "connected" to the port, ignore SIGTERM so that we
+ * can finish out any page data the driver sends (e.g. to eject the
+ * current page... Only ignore SIGTERM if we are printing data from
+ * stdin (otherwise you can't cancel raw jobs...)
+ */
+
+ if (fd != 0)
+ {
+# ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+# elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+# else
+ signal(SIGTERM, SIG_IGN);
+# endif /* HAVE_SIGSET */
+ }
+
+ /*
+ * Copy the print file to the device...
+ */
+
+ while (copies > 0)
+ {
+ if (fd != 0)
+ lseek(fd, 0, SEEK_SET);
+
+ while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
+ {
+ memset(&scsi_req, 0, sizeof(scsi_req));
+
+ scsi_req.interface_id = 'S';
+ scsi_req.dxfer_direction = SG_DXFER_TO_DEV;
+ scsi_req.cmd_len = 6;
+ scsi_req.mx_sb_len = sizeof(scsi_sense);
+ scsi_req.iovec_count = 0;
+ scsi_req.dxfer_len = bytes;
+ scsi_req.dxferp = buffer;
+ scsi_req.cmdp = scsi_cmd;
+ scsi_req.sbp = scsi_sense;
+ scsi_req.timeout = 60 * 1000;
+
+ scsi_cmd[0] = 0x0a; /* Group 0 print command */
+ scsi_cmd[1] = 0x00;
+ scsi_cmd[2] = bytes / 65536;
+ scsi_cmd[3] = bytes / 256;
+ scsi_cmd[4] = bytes;
+ scsi_cmd[5] = 0x00;
+
+ for (try = 0; try < 10; try ++)
+ if (ioctl(scsi_fd, SG_IO, &scsi_req) < 0 ||
+ scsi_req.status != 0)
+ {
+ fprintf(stderr, "WARNING: SCSI command timed out (%d); retrying...\n",
+ scsi_req.status);
+ sleep(try + 1);
+ }
+ else
+ break;
+
+ if (try >= 10)
+ {
+ fprintf(stderr, "ERROR: Unable to send print data (%d)\n",
+ scsi_req.status);
+ close(scsi_fd);
+ return (1);
+ }
+ }
+
+ copies --;
+ }
+
+ /*
+ * Close the device and return...
+ */
+
+ close(fd);
+
+ return (0);
+}
+#endif /* !SG_DXFER_TO_DEV */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/backend/scsi.c b/backend/scsi.c
new file mode 100644
index 000000000..9f72ce54c
--- /dev/null
+++ b/backend/scsi.c
@@ -0,0 +1,206 @@
+/*
+ * "$Id$"
+ *
+ * SCSI printer backend for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 2002 by Easy Software Products, all rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use
+ * of this software must display the following
+ * acknowledgement:
+ *
+ * This product includes software developed by Easy
+ * Software Products.
+ *
+ * 4. The name of Easy Software Products may not be used to
+ * endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Contents:
+ *
+ * main() - Send a file to the specified SCSI printer.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <cups/cups.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <cups/string.h>
+#include <signal.h>
+
+#ifdef WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+# include <fcntl.h>
+# ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+# endif /* HAVE_SYS_IOCTL_H */
+#endif /* WIN32 */
+
+
+/*
+ * Local functions...
+ */
+
+void list_devices(void);
+int print_device(const char *resource, int fd, int copies);
+
+
+#ifdef __linux__
+# include "scsi-linux.c"
+#elif defined(__sgi)
+# include "scsi-irix.c"
+#else
+/*
+ * Dummy functions that do nothing on unsupported platforms...
+ */
+void list_devices(void) {}
+int print_device(const char *resource, int fd, int copies) { return (1); }
+#endif /* __linux */
+
+
+/*
+ * 'main()' - Send a file to the specified SCSI printer.
+ *
+ * Usage:
+ *
+ * printer-uri job-id user title copies options [file]
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments (6 or 7) */
+ char *argv[]) /* I - Command-line arguments */
+{
+ char method[255], /* Method in URI */
+ hostname[1024], /* Hostname */
+ username[255], /* Username info (not used) */
+ resource[1024], /* Resource info (device and options) */
+ *options; /* Pointer to options */
+ int port; /* Port number (not used) */
+ int fp; /* Print file */
+ int copies; /* Number of copies to print */
+ int status; /* Exit status */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc == 1)
+ {
+ list_devices();
+ return (0);
+ }
+ else if (argc < 6 || argc > 7)
+ {
+ fputs("Usage: scsi:/dev/file job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+ if (argc == 6)
+ {
+ fp = 0;
+ copies = 1;
+ }
+ else
+ {
+ /*
+ * Try to open the print file...
+ */
+
+ if ((fp = open(argv[6], O_RDONLY)) < 0)
+ {
+ perror("ERROR: unable to open print file");
+ return (1);
+ }
+
+ copies = atoi(argv[4]);
+ }
+
+ /*
+ * Extract the device name and options from the URI...
+ */
+
+ httpSeparate(argv[0], method, username, hostname, &port, resource);
+
+ /*
+ * See if there are any options...
+ */
+
+ if ((options = strchr(resource, '?')) != NULL)
+ {
+ /*
+ * Yup, terminate the device name string and move to the first
+ * character of the options...
+ */
+
+ *options++ = '\0';
+ }
+
+ /*
+ * Finally, send the print file...
+ */
+
+ status = print_device(resource, fp, copies);
+
+ /*
+ * Close input file and return...
+ */
+
+ if (fp != 0)
+ close(fp);
+
+ if (!status)
+ fputs("INFO: Ready to print.\n", stderr);
+
+ return (status);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/backend/serial.c b/backend/serial.c
new file mode 100644
index 000000000..19c9ec8c1
--- /dev/null
+++ b/backend/serial.c
@@ -0,0 +1,894 @@
+/*
+ * "$Id$"
+ *
+ * Serial port backend for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Send a file to the printer or server.
+ * list_devices() - List all serial devices.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <cups/cups.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <cups/string.h>
+#include <signal.h>
+
+#ifdef __hpux
+# include <sys/modem.h>
+#endif /* __hpux */
+
+#ifdef WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+# include <fcntl.h>
+# include <termios.h>
+# ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+# endif /* HAVE_SYS_IOCTL_H */
+#endif /* WIN32 */
+
+#ifdef __sgi
+# include <invent.h>
+# ifndef INV_EPP_ECP_PLP
+# define INV_EPP_ECP_PLP 6 /* From 6.3/6.4/6.5 sys/invent.h */
+# define INV_ASO_SERIAL 14 /* serial portion of SGI ASO board */
+# define INV_IOC3_DMA 16 /* DMA mode IOC3 serial */
+# define INV_IOC3_PIO 17 /* PIO mode IOC3 serial */
+# define INV_ISA_DMA 19 /* DMA mode ISA serial -- O2 */
+# endif /* !INV_EPP_ECP_PLP */
+#endif /* __sgi */
+
+#ifndef CRTSCTS
+# ifdef CNEW_RTSCTS
+# define CRTSCTS CNEW_RTSCTS
+# else
+# define CRTSCTS 0
+# endif /* CNEW_RTSCTS */
+#endif /* !CRTSCTS */
+
+
+/*
+ * Local functions...
+ */
+
+void list_devices(void);
+
+
+/*
+ * 'main()' - Send a file to the printer or server.
+ *
+ * Usage:
+ *
+ * printer-uri job-id user title copies options [file]
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments (6 or 7) */
+ char *argv[]) /* I - Command-line arguments */
+{
+ char method[255], /* Method in URI */
+ hostname[1024], /* Hostname */
+ username[255], /* Username info (not used) */
+ resource[1024], /* Resource info (device and options) */
+ *options, /* Pointer to options */
+ name[255], /* Name of option */
+ value[255], /* Value of option */
+ *ptr; /* Pointer into name or value */
+ int port; /* Port number (not used) */
+ int fp; /* Print file */
+ int copies; /* Number of copies to print */
+ int fd; /* Parallel device */
+ int wbytes; /* Number of bytes written */
+ size_t nbytes, /* Number of bytes read */
+ tbytes; /* Total number of bytes written */
+ int dtrdsr; /* Do dtr/dsr flow control? */
+ int bufsize; /* Size of output buffer for writes */
+ char buffer[8192], /* Output buffer */
+ *bufptr; /* Pointer into buffer */
+ struct termios opts; /* Serial port options */
+ struct termios origopts; /* Original port options */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc == 1)
+ {
+ list_devices();
+ return (0);
+ }
+ else if (argc < 6 || argc > 7)
+ {
+ fputs("Usage: serial job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+ if (argc == 6)
+ {
+ fp = 0;
+ copies = 1;
+ }
+ else
+ {
+ /*
+ * Try to open the print file...
+ */
+
+ if ((fp = open(argv[6], O_RDONLY)) < 0)
+ {
+ perror("ERROR: unable to open print file");
+ return (1);
+ }
+
+ copies = atoi(argv[4]);
+ }
+
+ /*
+ * Extract the device name and options from the URI...
+ */
+
+ httpSeparate(argv[0], method, username, hostname, &port, resource);
+
+ /*
+ * See if there are any options...
+ */
+
+ if ((options = strchr(resource, '?')) != NULL)
+ {
+ /*
+ * Yup, terminate the device name string and move to the first
+ * character of the options...
+ */
+
+ *options++ = '\0';
+ }
+
+ /*
+ * Open the serial port device...
+ */
+
+ do
+ {
+ if ((fd = open(resource, O_WRONLY | O_NOCTTY | O_EXCL | O_NDELAY)) == -1)
+ {
+ if (errno == EBUSY)
+ {
+ fputs("INFO: Serial port busy; will retry in 30 seconds...\n", stderr);
+ sleep(30);
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Unable to open serial port device file \"%s\": %s\n",
+ resource, strerror(errno));
+ return (1);
+ }
+ }
+ }
+ while (fd < 0);
+
+ /*
+ * Set any options provided...
+ */
+
+ tcgetattr(fd, &origopts);
+ tcgetattr(fd, &opts);
+
+ opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */
+ opts.c_oflag &= ~OPOST; /* Don't post-process */
+
+ bufsize = 96; /* 9600 baud / 10 bits/char / 10Hz */
+ dtrdsr = 0; /* No dtr/dsr flow control */
+
+ if (options != NULL)
+ while (*options)
+ {
+ /*
+ * Get the name...
+ */
+
+ for (ptr = name; *options && *options != '=';)
+ *ptr++ = *options++;
+ *ptr = '\0';
+
+ if (*options == '=')
+ {
+ /*
+ * Get the value...
+ */
+
+ options ++;
+
+ for (ptr = value; *options && *options != '+';)
+ *ptr++ = *options++;
+ *ptr = '\0';
+
+ if (*options == '+')
+ options ++;
+ }
+ else
+ value[0] = '\0';
+
+ /*
+ * Process the option...
+ */
+
+ if (strcasecmp(name, "baud") == 0)
+ {
+ /*
+ * Set the baud rate...
+ */
+
+ bufsize = atoi(value) / 100;
+
+#if B19200 == 19200
+ cfsetispeed(&opts, atoi(value));
+ cfsetospeed(&opts, atoi(value));
+#else
+ switch (atoi(value))
+ {
+ case 1200 :
+ cfsetispeed(&opts, B1200);
+ cfsetospeed(&opts, B1200);
+ break;
+ case 2400 :
+ cfsetispeed(&opts, B2400);
+ cfsetospeed(&opts, B2400);
+ break;
+ case 4800 :
+ cfsetispeed(&opts, B4800);
+ cfsetospeed(&opts, B4800);
+ break;
+ case 9600 :
+ cfsetispeed(&opts, B9600);
+ cfsetospeed(&opts, B9600);
+ break;
+ case 19200 :
+ cfsetispeed(&opts, B19200);
+ cfsetospeed(&opts, B19200);
+ break;
+ case 38400 :
+ cfsetispeed(&opts, B38400);
+ cfsetospeed(&opts, B38400);
+ break;
+# ifdef B57600
+ case 57600 :
+ cfsetispeed(&opts, B57600);
+ cfsetospeed(&opts, B57600);
+ break;
+# endif /* B57600 */
+# ifdef B115200
+ case 115200 :
+ cfsetispeed(&opts, B115200);
+ cfsetospeed(&opts, B115200);
+ break;
+# endif /* B115200 */
+# ifdef B230400
+ case 230400 :
+ cfsetispeed(&opts, B230400);
+ cfsetospeed(&opts, B230400);
+ break;
+# endif /* B230400 */
+ default :
+ fprintf(stderr, "WARNING: Unsupported baud rate %s!\n", value);
+ break;
+ }
+#endif /* B19200 == 19200 */
+ }
+ else if (strcasecmp(name, "bits") == 0)
+ {
+ /*
+ * Set number of data bits...
+ */
+
+ switch (atoi(value))
+ {
+ case 7 :
+ opts.c_cflag &= ~CSIZE;
+ opts.c_cflag |= CS7;
+ opts.c_cflag |= PARENB;
+ opts.c_cflag &= ~PARODD;
+ break;
+ case 8 :
+ opts.c_cflag &= ~CSIZE;
+ opts.c_cflag |= CS8;
+ opts.c_cflag &= ~PARENB;
+ break;
+ }
+ }
+ else if (strcasecmp(name, "parity") == 0)
+ {
+ /*
+ * Set parity checking...
+ */
+
+ if (strcasecmp(value, "even") == 0)
+ {
+ opts.c_cflag |= PARENB;
+ opts.c_cflag &= ~PARODD;
+ }
+ else if (strcasecmp(value, "odd") == 0)
+ {
+ opts.c_cflag |= PARENB;
+ opts.c_cflag |= PARODD;
+ }
+ else if (strcasecmp(value, "none") == 0)
+ opts.c_cflag &= ~PARENB;
+ }
+ else if (strcasecmp(name, "flow") == 0)
+ {
+ /*
+ * Set flow control...
+ */
+
+ if (strcasecmp(value, "none") == 0)
+ {
+ opts.c_iflag &= ~(IXON | IXOFF | IXANY);
+ opts.c_cflag &= ~CRTSCTS;
+ }
+ else if (strcasecmp(value, "soft") == 0)
+ {
+ opts.c_iflag |= IXON | IXOFF | IXANY;
+ opts.c_cflag &= ~CRTSCTS;
+ }
+ else if (strcasecmp(value, "hard") == 0 ||
+ strcasecmp(value, "rtscts") == 0)
+ {
+ opts.c_iflag &= ~(IXON | IXOFF | IXANY);
+ opts.c_cflag |= CRTSCTS;
+ }
+ else if (strcasecmp(value, "dtrdsr") == 0)
+ {
+ opts.c_iflag &= ~(IXON | IXOFF | IXANY);
+ opts.c_cflag &= ~CRTSCTS;
+
+ dtrdsr = 1;
+ }
+ }
+ }
+
+ tcsetattr(fd, TCSANOW, &opts);
+ fcntl(fd, F_SETFL, 0);
+
+ /*
+ * Now that we are "connected" to the port, ignore SIGTERM so that we
+ * can finish out any page data the driver sends (e.g. to eject the
+ * current page... Only ignore SIGTERM if we are printing data from
+ * stdin (otherwise you can't cancel raw jobs...)
+ */
+
+ if (argc < 7)
+ {
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+ }
+
+ /*
+ * Finally, send the print file...
+ */
+
+ if (bufsize > sizeof(buffer))
+ bufsize = sizeof(buffer);
+
+ while (copies > 0)
+ {
+ copies --;
+
+ if (fp != 0)
+ {
+ fputs("PAGE: 1 1\n", stderr);
+ lseek(fp, 0, SEEK_SET);
+ }
+
+ if (dtrdsr)
+ {
+ /*
+ * Check the port and sleep until DSR is set...
+ */
+
+ int status;
+
+
+ if (!ioctl(fd, TIOCMGET, &status))
+ if (!(status & TIOCM_DSR))
+ {
+ /*
+ * Wait for DSR to go high...
+ */
+
+ fputs("DEBUG: DSR is low; waiting for device...\n", stderr);
+
+ do
+ {
+ sleep(1);
+ if (ioctl(fd, TIOCMGET, &status))
+ break;
+ }
+ while (!(status & TIOCM_DSR));
+
+ fputs("DEBUG: DSR is high; writing to device...\n", stderr);
+ }
+ }
+
+ tbytes = 0;
+ while ((nbytes = read(fp, buffer, bufsize)) > 0)
+ {
+ /*
+ * Write the print data to the printer...
+ */
+
+ tbytes += nbytes;
+ bufptr = buffer;
+
+ while (nbytes > 0)
+ {
+ if ((wbytes = write(fd, bufptr, nbytes)) < 0)
+ if (errno == ENOTTY)
+ wbytes = write(fd, bufptr, nbytes);
+
+ if (wbytes < 0)
+ {
+ perror("ERROR: Unable to send print file to printer");
+ break;
+ }
+
+ nbytes -= wbytes;
+ bufptr += wbytes;
+ }
+
+ if (argc > 6)
+ fprintf(stderr, "INFO: Sending print file, %lu bytes...\n",
+ (unsigned long)tbytes);
+ }
+ }
+
+ /*
+ * Close the serial port and input file and return...
+ */
+
+ tcsetattr(fd, TCSADRAIN, &origopts);
+
+ close(fd);
+ if (fp != 0)
+ close(fp);
+
+ fputs("INFO: Ready to print.\n", stderr);
+
+ return (0);
+}
+
+
+/*
+ * 'list_devices()' - List all serial devices.
+ */
+
+void
+list_devices(void)
+{
+#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__)
+ static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz";
+ /* Funky hex numbering used for some devices */
+#endif /* __hpux || __sgi || __sun || __FreeBSD__ || __OpenBSD__ */
+
+#if defined(__linux) || defined(linux) || defined(__linux__)
+ int i; /* Looping var */
+ int fd; /* File descriptor */
+ char device[255]; /* Device filename */
+
+
+ for (i = 0; i < 100; i ++)
+ {
+ sprintf(device, "/dev/ttyS%d", i);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+# if defined(_ARCH_PPC) || defined(powerpc) || defined(__powerpc)
+ printf("serial serial:%s?baud=230400 \"Unknown\" \"Serial Port #%d\"\n",
+ device, i + 1);
+# else
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Serial Port #%d\"\n",
+ device, i + 1);
+# endif // _ARCH_PPC || powerpc || __powerpc
+ }
+ }
+
+ for (i = 0; i < 16; i ++)
+ {
+ sprintf(device, "/dev/usb/ttyUSB%d", i);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=230400 \"Unknown\" \"USB Serial Port #%d\"\n",
+ device, i + 1);
+ }
+ }
+#elif defined(__sgi)
+ int i, j, n; /* Looping vars */
+ char device[255]; /* Device filename */
+ inventory_t *inv; /* Hardware inventory info */
+
+
+ /*
+ * IRIX maintains a hardware inventory of most devices...
+ */
+
+ setinvent();
+
+ while ((inv = getinvent()) != NULL)
+ {
+ if (inv->inv_class == INV_SERIAL)
+ {
+ /*
+ * Some sort of serial port...
+ */
+
+ if (inv->inv_type == INV_CDSIO || inv->inv_type == INV_CDSIO_E)
+ {
+ /*
+ * CDSIO port...
+ */
+
+ for (n = 0; n < 6; n ++)
+ printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"CDSIO Board %d Serial Port #%d\"\n",
+ n + 5 + 8 * inv->inv_controller, inv->inv_controller, n + 1);
+ }
+ else if (inv->inv_type == INV_EPC_SERIAL)
+ {
+ /*
+ * Everest serial port...
+ */
+
+ if (inv->inv_unit == 0)
+ i = 1;
+ else
+ i = 41 + 4 * (int)inv->inv_controller;
+
+ for (n = 0; n < (int)inv->inv_state; n ++)
+ printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"EPC Serial Port %d, Ebus slot %d\"\n",
+ n + i, n + 1, (int)inv->inv_controller);
+ }
+ else if (inv->inv_state > 1)
+ {
+ /*
+ * Standard serial port under IRIX 6.4 and earlier...
+ */
+
+ for (n = 0; n < (int)inv->inv_state; n ++)
+ printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"Onboard Serial Port %d\"\n",
+ n + (int)inv->inv_unit + 1, n + (int)inv->inv_unit + 1);
+ }
+ else
+ {
+ /*
+ * Standard serial port under IRIX 6.5 and beyond...
+ */
+
+ printf("serial serial:/dev/ttyd%d?baud=115200 \"Unknown\" \"Onboard Serial Port %d\"\n",
+ (int)inv->inv_controller, (int)inv->inv_controller);
+ }
+ }
+ }
+
+ endinvent();
+
+ /*
+ * Central Data makes serial and parallel "servers" that can be
+ * connected in a number of ways. Look for ports...
+ */
+
+ for (i = 0; i < 10; i ++)
+ for (j = 0; j < 8; j ++)
+ for (n = 0; n < 32; n ++)
+ {
+ if (i == 8) /* EtherLite */
+ sprintf(device, "/dev/ttydn%d%c", j, funky_hex[n]);
+ else if (i == 9) /* PCI */
+ sprintf(device, "/dev/ttydp%d%c", j, funky_hex[n]);
+ else /* SCSI */
+ sprintf(device, "/dev/ttyd%d%d%c", i, j, funky_hex[n]);
+
+ if (access(device, 0) == 0)
+ {
+ if (i == 8)
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n",
+ device, j, n);
+ else if (i == 9)
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data PCI Serial Port, ID %d, port %d\"\n",
+ device, j, n);
+ else
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n",
+ device, i, j, n);
+ }
+ }
+#elif defined(__sun)
+ int i, j, n; /* Looping vars */
+ char device[255]; /* Device filename */
+
+
+ /*
+ * Standard serial ports...
+ */
+
+ for (i = 0; i < 26; i ++)
+ {
+ sprintf(device, "/dev/cua/%c", 'a' + i);
+ if (access(device, 0) == 0)
+#ifdef B115200
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Serial Port #%d\"\n",
+ device, i + 1);
+#else
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n",
+ device, i + 1);
+#endif /* B115200 */
+ }
+
+ /*
+ * MAGMA serial ports...
+ */
+
+ for (i = 0; i < 40; i ++)
+ {
+ sprintf(device, "/dev/term/%02d", i);
+ if (access(device, 0) == 0)
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"MAGMA Serial Board #%d Port #%d\"\n",
+ device, (i / 10) + 1, (i % 10) + 1);
+ }
+
+ /*
+ * Central Data serial ports...
+ */
+
+ for (i = 0; i < 9; i ++)
+ for (j = 0; j < 8; j ++)
+ for (n = 0; n < 32; n ++)
+ {
+ if (i == 8) /* EtherLite */
+ sprintf(device, "/dev/sts/ttyN%d%c", j, funky_hex[n]);
+ else
+ sprintf(device, "/dev/sts/tty%c%d%c", i + 'C', j,
+ funky_hex[n]);
+
+ if (access(device, 0) == 0)
+ {
+ if (i == 8)
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n",
+ device, j, n);
+ else
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n",
+ device, i, j, n);
+ }
+ }
+#elif defined(__hpux)
+ int i, j, n; /* Looping vars */
+ char device[255]; /* Device filename */
+
+
+ /*
+ * Standard serial ports...
+ */
+
+ for (i = 0; i < 10; i ++)
+ {
+ sprintf(device, "/dev/tty%dp0", i);
+ if (access(device, 0) == 0)
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n",
+ device, i + 1);
+ }
+
+ /*
+ * Central Data serial ports...
+ */
+
+ for (i = 0; i < 9; i ++)
+ for (j = 0; j < 8; j ++)
+ for (n = 0; n < 32; n ++)
+ {
+ if (i == 8) /* EtherLite */
+ sprintf(device, "/dev/ttyN%d%c", j, funky_hex[n]);
+ else
+ sprintf(device, "/dev/tty%c%d%c", i + 'C', j,
+ funky_hex[n]);
+
+ if (access(device, 0) == 0)
+ {
+ if (i == 8)
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n",
+ device, j, n);
+ else
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n",
+ device, i, j, n);
+ }
+ }
+#elif defined(__osf__)
+ int i; /* Looping var */
+ char device[255]; /* Device filename */
+
+
+ /*
+ * Standard serial ports...
+ */
+
+ for (i = 0; i < 100; i ++)
+ {
+ sprintf(device, "/dev/tty%02d", i);
+ if (access(device, 0) == 0)
+ printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n",
+ device, i + 1);
+ }
+#elif defined(__FreeBSD__) || defined(__OpenBSD__)
+ int i, j; /* Looping vars */
+ int fd; /* File descriptor */
+ char device[255]; /* Device filename */
+
+
+ /*
+ * SIO ports...
+ */
+
+ for (i = 0; i < 32; i ++)
+ {
+ sprintf(device, "/dev/ttyd%c", funky_hex[i]);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Standard Serial Port #%d\"\n",
+ device, i + 1);
+ }
+ }
+
+ /*
+ * Cyclades ports...
+ */
+
+ for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */
+ for (j = 0; j < 32; j ++)
+ {
+ sprintf(device, "/dev/ttyc%d%c", i, funky_hex[j]);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Port #%d\"\n",
+ device, i, j + 1);
+ }
+ }
+
+ /*
+ * Digiboard ports...
+ */
+
+ for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */
+ for (j = 0; j < 32; j ++)
+ {
+ sprintf(device, "/dev/ttyD%d%c", i, funky_hex[j]);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Digiboard #%d Serial Port #%d\"\n",
+ device, i, j + 1);
+ }
+ }
+
+ /*
+ * Stallion ports...
+ */
+
+ for (i = 0; i < 32; i ++)
+ {
+ sprintf(device, "/dev/ttyE%c", funky_hex[i]);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Stallion Serial Port #%d\"\n",
+ device, i + 1);
+ }
+ }
+
+ /*
+ * SX ports...
+ */
+
+ for (i = 0; i < 128; i ++)
+ {
+ sprintf(device, "/dev/ttyA%d", i + 1);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"SX Serial Port #%d\"\n",
+ device, i + 1);
+ }
+ }
+#elif defined(__NetBSD__)
+ int i, j; /* Looping vars */
+ int fd; /* File descriptor */
+ char device[255]; /* Device filename */
+
+
+ /*
+ * Standard serial ports...
+ */
+
+ for (i = 0; i < 4; i ++)
+ {
+ sprintf(device, "/dev/tty%02d", i);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Serial Port #%d\"\n",
+ device, i + 1);
+ }
+ }
+
+ /*
+ * Cyclades-Z ports...
+ */
+
+ for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */
+ for (j = 0; j < 64; j ++)
+ {
+ sprintf(device, "/dev/ttyCZ%02d%02d", i, j);
+ if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
+ {
+ close(fd);
+ printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Prt #%d\"\n",
+ device, i, j + 1);
+ }
+ }
+
+#endif
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/backend/socket.c b/backend/socket.c
new file mode 100644
index 000000000..aedfc2651
--- /dev/null
+++ b/backend/socket.c
@@ -0,0 +1,353 @@
+/*
+ * "$Id$"
+ *
+ * AppSocket backend for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Send a file to the printer or server.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <cups/cups.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <cups/string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#ifdef WIN32
+# include <winsock.h>
+#else
+# include <unistd.h>
+# include <fcntl.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+#endif /* WIN32 */
+
+
+/*
+ * 'main()' - Send a file to the printer or server.
+ *
+ * Usage:
+ *
+ * printer-uri job-id user title copies options [file]
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments (6 or 7) */
+ char *argv[]) /* I - Command-line arguments */
+{
+ char method[255], /* Method in URI */
+ hostname[1024], /* Hostname */
+ username[255], /* Username info (not used) */
+ resource[1024]; /* Resource info (not used) */
+ int fp; /* Print file */
+ int copies; /* Number of copies to print */
+ int port; /* Port number */
+ int delay; /* Delay for retries... */
+ int fd; /* AppSocket */
+ int error; /* Error code (if any) */
+ struct sockaddr_in addr; /* Socket address */
+ struct hostent *hostaddr; /* Host address */
+ int wbytes; /* Number of bytes written */
+ size_t nbytes, /* Number of bytes read */
+ tbytes; /* Total number of bytes written */
+ char buffer[8192], /* Output buffer */
+ *bufptr; /* Pointer into buffer */
+ struct timeval timeout; /* Timeout for select() */
+ fd_set input; /* Input set for select() */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc == 1)
+ {
+ puts("network socket \"Unknown\" \"AppSocket/HP JetDirect\"");
+ return (0);
+ }
+ else if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
+ argv[0]);
+ return (1);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+ if (argc == 6)
+ {
+ fp = 0;
+ copies = 1;
+ }
+ else
+ {
+ /*
+ * Try to open the print file...
+ */
+
+ if ((fp = open(argv[6], O_RDONLY)) < 0)
+ {
+ perror("ERROR: unable to open print file");
+ return (1);
+ }
+
+ copies = atoi(argv[4]);
+ }
+
+ /*
+ * Extract the hostname and port number from the URI...
+ */
+
+ httpSeparate(argv[0], method, username, hostname, &port, resource);
+
+ if (port == 0)
+ port = 9100; /* Default to HP JetDirect/Tektronix PhaserShare */
+
+ /*
+ * Then try to connect to the remote host...
+ */
+
+ if ((hostaddr = httpGetHostByName(hostname)) == NULL)
+ {
+ fprintf(stderr, "ERROR: Unable to locate printer \'%s\' - %s\n",
+ hostname, strerror(errno));
+ return (1);
+ }
+
+ fprintf(stderr, "INFO: Attempting to connect to host %s on port %d\n",
+ hostname, port);
+
+ memset(&addr, 0, sizeof(addr));
+ memcpy(&(addr.sin_addr), hostaddr->h_addr, hostaddr->h_length);
+ addr.sin_family = hostaddr->h_addrtype;
+ addr.sin_port = htons(port);
+
+ while (copies > 0)
+ {
+ for (delay = 5;;)
+ {
+ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ perror("ERROR: Unable to create socket");
+ return (1);
+ }
+
+ if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+ {
+ error = errno;
+ close(fd);
+ fd = -1;
+
+ if (error == ECONNREFUSED || error == EHOSTDOWN ||
+ error == EHOSTUNREACH)
+ {
+ fprintf(stderr, "INFO: Network host \'%s\' is busy; will retry in %d seconds...\n",
+ hostname, delay);
+ sleep(delay);
+
+ if (delay < 30)
+ delay += 5;
+ }
+ else
+ {
+ perror("ERROR: Unable to connect to printer (retrying in 30 seconds)");
+ sleep(30);
+ }
+ }
+ else
+ break;
+ }
+
+ /*
+ * Now that we are "connected" to the port, ignore SIGTERM so that we
+ * can finish out any page data the driver sends (e.g. to eject the
+ * current page... Only ignore SIGTERM if we are printing data from
+ * stdin (otherwise you can't cancel raw jobs...)
+ */
+
+ if (argc < 7)
+ {
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+ }
+
+ /*
+ * Finally, send the print file...
+ */
+
+ copies --;
+
+ if (fp != 0)
+ {
+ fputs("PAGE: 1 1\n", stderr);
+ lseek(fp, 0, SEEK_SET);
+ }
+
+ fputs("INFO: Connected to host, sending print job...\n", stderr);
+
+ tbytes = 0;
+ while ((nbytes = read(fp, buffer, sizeof(buffer))) > 0)
+ {
+ /*
+ * Write the print data to the printer...
+ */
+
+ tbytes += nbytes;
+ bufptr = buffer;
+
+ while (nbytes > 0)
+ {
+ if ((wbytes = send(fd, bufptr, nbytes, 0)) < 0)
+ {
+ perror("ERROR: Unable to send print file to printer");
+ break;
+ }
+
+ nbytes -= wbytes;
+ bufptr += wbytes;
+ }
+
+ /*
+ * Check for possible data coming back from the printer...
+ */
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ FD_ZERO(&input);
+ FD_SET(fd, &input);
+#ifdef __hpux
+ if (select(fd + 1, (int *)&input, NULL, NULL, &timeout) > 0)
+#else
+ if (select(fd + 1, &input, NULL, NULL, &timeout) > 0)
+#endif /* __hpux */
+ {
+ /*
+ * Grab the data coming back and spit it out to stderr...
+ */
+
+ if ((nbytes = recv(fd, buffer, sizeof(buffer), 0)) > 0)
+ fprintf(stderr, "INFO: Received %lu bytes of back-channel data!\n",
+ (unsigned long)nbytes);
+ }
+ else if (argc > 6)
+ fprintf(stderr, "INFO: Sending print file, %lu bytes...\n",
+ (unsigned long)tbytes);
+ }
+
+ /*
+ * Shutdown the socket and wait for the other end to finish...
+ */
+
+ fputs("INFO: Print file sent, waiting for printer to finish...\n", stderr);
+
+ shutdown(fd, 1);
+
+ for (;;)
+ {
+ /*
+ * Wait a maximum of 90 seconds for backchannel data or a closed
+ * connection...
+ */
+
+ timeout.tv_sec = 90;
+ timeout.tv_usec = 0;
+
+ FD_ZERO(&input);
+ FD_SET(fd, &input);
+
+#ifdef __hpux
+ if (select(fd + 1, (int *)&input, NULL, NULL, &timeout) > 0)
+#else
+ if (select(fd + 1, &input, NULL, NULL, &timeout) > 0)
+#endif /* __hpux */
+ {
+ /*
+ * Grab the data coming back and spit it out to stderr...
+ */
+
+ if ((nbytes = recv(fd, buffer, sizeof(buffer), 0)) > 0)
+ fprintf(stderr, "INFO: Received %lu bytes of back-channel data!\n",
+ (unsigned long)nbytes);
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ /*
+ * Close the socket connection...
+ */
+
+ close(fd);
+ }
+
+ /*
+ * Close the input file and return...
+ */
+
+ if (fp != 0)
+ close(fp);
+
+ fputs("INFO: Ready to print.\n", stderr);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/backend/usb.c b/backend/usb.c
new file mode 100644
index 000000000..4af85cbda
--- /dev/null
+++ b/backend/usb.c
@@ -0,0 +1,653 @@
+/*
+ * "$Id$"
+ *
+ * USB port backend for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Send a file to the specified USB port.
+ * list_devices() - List all USB devices.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <cups/cups.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <cups/string.h>
+#include <signal.h>
+
+#ifdef WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+# include <fcntl.h>
+# include <termios.h>
+#endif /* WIN32 */
+
+#ifdef __linux
+# include <sys/ioctl.h>
+# include <linux/lp.h>
+# define IOCNR_GET_DEVICE_ID 1
+
+/*
+ * Get device_id string
+ */
+# define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
+#endif /* __linux */
+
+
+/*
+ * Local functions...
+ */
+
+void decode_device_id(int port, const char *device_id,
+ char *make_model, int mmsize,
+ char *uri, int urisize);
+void list_devices(void);
+int open_device(const char *uri);
+
+
+/*
+ * 'main()' - Send a file to the specified USB port.
+ *
+ * Usage:
+ *
+ * printer-uri job-id user title copies options [file]
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments (6 or 7) */
+ char *argv[]) /* I - Command-line arguments */
+{
+ char uri[HTTP_MAX_URI],
+ /* Copy of device URI */
+ *options; /* Pointer to options in URI */
+ int fp; /* Print file */
+ int copies; /* Number of copies to print */
+ int fd; /* Parallel device */
+ int wbytes; /* Number of bytes written */
+ size_t nbytes, /* Number of bytes read */
+ tbytes; /* Total number of bytes written */
+ char buffer[8192], /* Output buffer */
+ *bufptr; /* Pointer into buffer */
+ struct termios opts; /* Parallel port options */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+#ifdef __linux
+ unsigned char status; /* Port status (off-line, out-of-paper, etc.) */
+#endif /* __linux */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc == 1)
+ {
+ list_devices();
+ return (0);
+ }
+ else if (argc < 6 || argc > 7)
+ {
+ fputs("Usage: USB job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+ if (argc == 6)
+ {
+ fp = 0;
+ copies = 1;
+ }
+ else
+ {
+ /*
+ * Try to open the print file...
+ */
+
+ if ((fp = open(argv[6], O_RDONLY)) < 0)
+ {
+ perror("ERROR: unable to open print file");
+ return (1);
+ }
+
+ copies = atoi(argv[4]);
+ }
+
+ /*
+ * Copy the device URI and remove any options...
+ */
+
+ strlcpy(uri, argv[0], sizeof(uri));
+
+ /*
+ * See if there are any options...
+ */
+
+ if ((options = strchr(uri, '?')) != NULL)
+ {
+ /*
+ * Yup, terminate the device name string and move to the first
+ * character of the options...
+ */
+
+ *options++ = '\0';
+ }
+
+ /*
+ * Open the USB port device...
+ */
+
+ do
+ {
+ if ((fd = open_device(uri)) == -1)
+ {
+ if (errno == EBUSY)
+ {
+ fputs("INFO: USB port busy; will retry in 30 seconds...\n", stderr);
+ sleep(30);
+ }
+ else if (errno == ENXIO || errno == EIO || errno == ENOENT)
+ {
+ fputs("INFO: Printer not connected; will retry in 30 seconds...\n", stderr);
+ sleep(30);
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Unable to open USB device \"%s\": %s\n",
+ uri, strerror(errno));
+ return (1);
+ }
+ }
+ }
+ while (fd < 0);
+
+ /*
+ * Set any options provided...
+ */
+
+ tcgetattr(fd, &opts);
+
+ opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */
+
+ /**** No options supported yet ****/
+
+ tcsetattr(fd, TCSANOW, &opts);
+
+ /*
+ * Now that we are "connected" to the port, ignore SIGTERM so that we
+ * can finish out any page data the driver sends (e.g. to eject the
+ * current page... Only ignore SIGTERM if we are printing data from
+ * stdin (otherwise you can't cancel raw jobs...)
+ */
+
+ if (argc < 7)
+ {
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+ }
+
+ /*
+ * Finally, send the print file...
+ */
+
+ while (copies > 0)
+ {
+ copies --;
+
+ if (fp != 0)
+ {
+ fputs("PAGE: 1 1\n", stderr);
+ lseek(fp, 0, SEEK_SET);
+ }
+
+ tbytes = 0;
+ while ((nbytes = read(fp, buffer, sizeof(buffer))) > 0)
+ {
+ /*
+ * Write the print data to the printer...
+ */
+
+ tbytes += nbytes;
+ bufptr = buffer;
+
+ while (nbytes > 0)
+ {
+#ifdef __linux
+ if (ioctl(fd, LPGETSTATUS, &status) == 0)
+ {
+ fprintf(stderr, "DEBUG: LPGETSTATUS returned %02X...\n", status);
+
+ if (status & LP_NOPA)
+ fputs("INFO: Media tray empty!\n", stderr);
+ else if (status & LP_ERR)
+ fputs("INFO: Printer fault!\n", stderr);
+ else if (status & LP_OFFL)
+ fputs("INFO: Printer off-line.\n", stderr);
+ }
+#endif /* __linux */
+
+ if ((wbytes = write(fd, bufptr, nbytes)) < 0)
+ if (errno == ENOTTY)
+ wbytes = write(fd, bufptr, nbytes);
+
+ if (wbytes < 0)
+ {
+ perror("ERROR: Unable to send print file to printer");
+ break;
+ }
+
+ nbytes -= wbytes;
+ bufptr += wbytes;
+ }
+
+ if (argc > 6)
+ fprintf(stderr, "INFO: Sending print file, %lu bytes...\n",
+ (unsigned long)tbytes);
+ }
+ }
+
+ /*
+ * Close the socket connection and input file and return...
+ */
+
+ close(fd);
+ if (fp != 0)
+ close(fp);
+
+ fputs("INFO: Ready to print.\n", stderr);
+
+ return (0);
+}
+
+
+/*
+ * 'decode_device_id()' - Decode the IEEE-1284 device ID string.
+ */
+
+void
+decode_device_id(int port, /* I - Port number */
+ const char *device_id, /* I - 1284 device ID string */
+ char *make_model, /* O - Make/model */
+ int mmsize, /* I - Size of buffer */
+ char *uri, /* O - Device URI */
+ int urisize) /* I - Size of buffer */
+{
+ char *attr, /* 1284 attribute */
+ *delim, /* 1284 delimiter */
+ *uriptr, /* Pointer into URI */
+ line[1024]; /* Line from devices file */
+ FILE *fp; /* /proc/bus/usb/devices file */
+ int current; /* Current printer port */
+ char serial_number[1024], /* Serial number string */
+ temp[1024]; /* Temporary string */
+
+
+ /*
+ * Look for the description field...
+ */
+
+ if ((attr = strstr(device_id, "DES:")) != NULL)
+ attr += 4;
+ else if ((attr = strstr(device_id, "DESCRIPTION:")) != NULL)
+ attr += 12;
+
+ if (attr)
+ {
+ if (strncasecmp(attr, "Hewlett-Packard ", 16) == 0)
+ {
+ strlcpy(make_model, "HP ", mmsize);
+ strlcpy(make_model + 3, attr + 16, mmsize - 3);
+ }
+ else
+ {
+ strlcpy(make_model, attr, mmsize);
+ }
+
+ if ((delim = strchr(make_model, ';')) != NULL)
+ *delim = '\0';
+ }
+ else
+ strlcpy(make_model, "Unknown", mmsize);
+
+ /*
+ * Look for the serial number field...
+ */
+
+ if ((attr = strstr(device_id, "SERN:")) != NULL)
+ attr += 5;
+ else if ((attr = strstr(device_id, "SERIALNUMBER:")) != NULL)
+ attr += 13;
+
+ if (attr)
+ {
+ strlcpy(serial_number, attr, sizeof(serial_number));
+
+ if ((delim = strchr(serial_number, ';')) != NULL)
+ *delim = '\0';
+ }
+ else if ((fp = fopen("/proc/bus/usb/devices", "r")) != NULL)
+ {
+ serial_number[0] = '\0';
+
+ for (current = 0; fgets(line, sizeof(line), fp) != NULL;)
+ {
+ if (line[0] == 'S' && (attr = strstr(line, "SerialNumber=")) != NULL)
+ {
+ /*
+ * Copy serial number from line...
+ */
+
+ strlcpy(temp, attr + 13, sizeof(temp));
+ if ((delim = strchr(temp, '\n')) != NULL)
+ *delim = '\0';
+ }
+ else if (line[0] == 'I' && strstr(line, "Driver=usblp") != NULL &&
+ strstr(line, "Prot=02") != NULL)
+ {
+ /*
+ * Found printer device; if current == port, then use it!
+ */
+
+ if (current == port)
+ {
+ strlcpy(serial_number, temp, sizeof(serial_number));
+ break;
+ }
+
+ current ++;
+ }
+ }
+
+ fclose(fp);
+ }
+
+ /*
+ * Generate the device URI from the make_model and serial number strings.
+ */
+
+ strlcpy(uri, "usb://", urisize);
+ for (uriptr = uri + 6, delim = make_model;
+ *delim && uriptr < (uri + urisize - 1);
+ delim ++)
+ if (*delim == ' ')
+ {
+ delim ++;
+ *uriptr++ = '/';
+ break;
+ }
+ else
+ *uriptr++ = *delim;
+
+ for (; *delim && uriptr < (uri + urisize - 3); delim ++)
+ if (*delim == ' ')
+ {
+ *uriptr++ = '%';
+ *uriptr++ = '2';
+ *uriptr++ = '0';
+ }
+ else
+ *uriptr++ = *delim;
+
+ *uriptr = '\0';
+
+ if (serial_number[0])
+ {
+ /*
+ * Add the serial number to the URI...
+ */
+
+ strlcat(uri, "?serial=", urisize);
+ strlcat(uri, serial_number, urisize);
+ }
+}
+
+
+/*
+ * 'list_devices()' - List all USB devices.
+ */
+
+void
+list_devices(void)
+{
+#ifdef __linux
+ int i; /* Looping var */
+ int length; /* Length of device ID info */
+ int fd; /* File descriptor */
+ char format[255], /* Format for device filename */
+ device[255], /* Device filename */
+ device_id[1024], /* Device ID string */
+ device_uri[1024], /* Device URI string */
+ make_model[1024]; /* Make and model */
+
+
+ /*
+ * First figure out which USB printer filename to use...
+ */
+
+ if (access("/dev/usb/lp0", 0) == 0)
+ strcpy(format, "/dev/usb/lp%d");
+ else if (access("/dev/usb/usblp0", 0) == 0)
+ strcpy(format, "/dev/usb/usblp%d");
+ else
+ strcpy(format, "/dev/usblp%d");
+
+ /*
+ * Then open each USB device...
+ */
+
+ for (i = 0; i < 16; i ++)
+ {
+ sprintf(device, format, i);
+
+ if ((fd = open(device, O_RDWR | O_EXCL)) >= 0)
+ {
+ if (ioctl(fd, LPIOC_GET_DEVICE_ID(sizeof(device_id)), device_id) == 0)
+ {
+ length = (((unsigned)device_id[0] & 255) << 8) +
+ ((unsigned)device_id[1] & 255);
+ memcpy(device_id, device_id + 2, length);
+ device_id[length] = '\0';
+ }
+ else
+ device_id[0] = '\0';
+
+ close(fd);
+ }
+ else
+ device_id[0] = '\0';
+
+ if (device_id[0])
+ {
+ decode_device_id(i, device_id, make_model, sizeof(make_model),
+ device_uri, sizeof(device_uri));
+
+ printf("direct %s \"%s\" \"USB Printer #%d\"\n", device_uri,
+ make_model, i + 1);
+ }
+ else
+ printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1);
+ }
+#elif defined(__sgi)
+#elif defined(__sun)
+ int i; /* Looping var */
+ char device[255]; /* Device filename */
+
+
+ for (i = 0; i < 8; i ++)
+ {
+ sprintf(device, "/dev/usb/printer%d", i);
+ if (!access(device, 0))
+ printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1);
+ }
+#elif defined(__hpux)
+#elif defined(__osf)
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+ int i; /* Looping var */
+ char device[255]; /* Device filename */
+
+
+ for (i = 0; i < 8; i ++)
+ {
+ sprintf(device, "/dev/ulpt%d", i);
+ if (!access(device, 0))
+ printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1);
+
+ sprintf(device, "/dev/unlpt%d", i);
+ if (!access(device, 0))
+ printf("direct usb:%s \"Unknown\" \"USB Printer #%d (no reset)\"\n", device, i + 1);
+ }
+#endif
+}
+
+
+/*
+ * 'open_device()' - Open a USB device...
+ */
+
+int /* O - File descriptor or -1 on error */
+open_device(const char *uri) /* I - Device URI */
+{
+ /*
+ * The generic implementation just treats the URI as a device filename...
+ * Specific operating systems may also support using the device serial
+ * number and/or make/model.
+ */
+
+ if (strncmp(uri, "usb:/dev/", 9) == 0)
+ return (open(uri + 4, O_RDWR | O_EXCL));
+#ifdef __linux
+ else if (strncmp(uri, "usb://", 6) == 0)
+ {
+ /*
+ * For Linux, try looking up the device serial number or model...
+ */
+
+ int i; /* Looping var */
+ int length; /* Length of device ID info */
+ int fd; /* File descriptor */
+ char format[255], /* Format for device filename */
+ device[255], /* Device filename */
+ device_id[1024], /* Device ID string */
+ make_model[1024], /* Make and model */
+ device_uri[1024]; /* Device URI string */
+
+
+ /*
+ * First figure out which USB printer filename to use...
+ */
+
+ if (access("/dev/usb/lp0", 0) == 0)
+ strcpy(format, "/dev/usb/lp%d");
+ else if (access("/dev/usb/usblp0", 0) == 0)
+ strcpy(format, "/dev/usb/usblp%d");
+ else
+ strcpy(format, "/dev/usblp%d");
+
+ /*
+ * Then find the correct USB device...
+ */
+
+ for (i = 0; i < 16; i ++)
+ {
+ sprintf(device, format, i);
+
+ if ((fd = open(device, O_RDWR | O_EXCL)) >= 0)
+ {
+ if (ioctl(fd, LPIOC_GET_DEVICE_ID(sizeof(device_id)), device_id) == 0)
+ {
+ length = (((unsigned)device_id[0] & 255) << 8) +
+ ((unsigned)device_id[1] & 255);
+ memcpy(device_id, device_id + 2, length);
+ device_id[length] = '\0';
+ }
+ else
+ device_id[0] = '\0';
+ }
+ else
+ device_id[0] = '\0';
+
+ if (device_id[0])
+ {
+ /*
+ * Got the device ID - is this the one?
+ */
+
+ decode_device_id(i, device_id, make_model, sizeof(make_model),
+ device_uri, sizeof(device_uri));
+
+ if (strcmp(uri, device_uri) == 0)
+ return (fd); /* Yes, return this file descriptor... */
+ }
+
+ /*
+ * This wasn't the one...
+ */
+
+ close(fd);
+ }
+
+ /*
+ * Couldn't find the printer, return "no such device or address"...
+ */
+
+ errno = ENODEV;
+
+ return (-1);
+ }
+#endif /* __linux */
+ else
+ {
+ errno = ENODEV;
+ return (-1);
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/berkeley/.cvsignore b/berkeley/.cvsignore
new file mode 100644
index 000000000..3ff70bf38
--- /dev/null
+++ b/berkeley/.cvsignore
@@ -0,0 +1,4 @@
+lpc
+lpq
+lpr
+lprm
diff --git a/berkeley/Dependencies b/berkeley/Dependencies
new file mode 100644
index 000000000..0915065b5
--- /dev/null
+++ b/berkeley/Dependencies
@@ -0,0 +1,11 @@
+# DO NOT DELETE
+
+lpc.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lpc.o: ../cups/ppd.h ../cups/language.h ../cups/debug.h
+lpq.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+lpq.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/language.h
+lpq.o: ../cups/debug.h
+lpr.o: ../config.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lpr.o: ../cups/ppd.h
+lprm.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lprm.o: ../cups/ppd.h ../cups/language.h
diff --git a/berkeley/Makefile b/berkeley/Makefile
new file mode 100644
index 000000000..07d05243c
--- /dev/null
+++ b/berkeley/Makefile
@@ -0,0 +1,112 @@
+#
+# "$Id$"
+#
+# Berkeley commands makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+TARGETS = lpc lpq lpr lprm
+OBJS = lpc.o lpq.o lpr.o lprm.o
+
+
+#
+# Make all targets...
+#
+
+all: $(TARGETS)
+
+
+#
+# Clean all object files...
+#
+
+clean:
+ $(RM) $(OBJS) $(TARGETS)
+
+
+#
+# Update dependencies (without system header dependencies...)
+#
+
+depend:
+ makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1
+
+
+#
+# Install all targets...
+#
+
+install: all
+ $(INSTALL_DIR) $(BINDIR)
+ $(INSTALL_BIN) lpq $(BINDIR)
+ $(INSTALL_BIN) lpr $(BINDIR)
+ $(INSTALL_BIN) lprm $(BINDIR)
+ $(INSTALL_DIR) $(SBINDIR)
+ $(INSTALL_BIN) lpc $(SBINDIR)
+
+
+#
+# lpc
+#
+
+lpc: lpc.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpc lpc.o $(LIBS)
+
+
+#
+# lpq
+#
+
+lpq: lpq.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpq lpq.o $(LIBS)
+
+
+#
+# lpr
+#
+
+lpr: lpr.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpr lpr.o $(LIBS)
+
+
+#
+# lprm
+#
+
+lprm: lprm.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lprm lprm.o $(LIBS)
+
+
+#
+# Dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id$".
+#
diff --git a/berkeley/lpc.c b/berkeley/lpc.c
new file mode 100644
index 000000000..e027db846
--- /dev/null
+++ b/berkeley/lpc.c
@@ -0,0 +1,482 @@
+/*
+ * "$Id$"
+ *
+ * "lpc" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and commands.
+ * compare_strings() - Compare two command-line strings.
+ * do_command() - Do an lpc command...
+ * show_help() - Show help messages.
+ * show_status() - Show printers.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <cups/debug.h>
+#include <cups/string.h>
+
+
+/*
+ * Local functions...
+ */
+
+static int compare_strings(char *, char *, int);
+static void do_command(http_t *, char *, char *);
+static void show_help(char *);
+static void show_status(http_t *, char *);
+
+
+/*
+ * 'main()' - Parse options and commands.
+ */
+
+int
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ http_t *http; /* Connection to server */
+ char line[1024], /* Input line from user */
+ *params; /* Pointer to parameters */
+
+
+ /*
+ * Connect to the scheduler...
+ */
+
+ http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
+
+ if (argc > 1)
+ {
+ /*
+ * Process a single command on the command-line...
+ */
+
+ do_command(http, argv[1], argv[2]);
+ }
+ else
+ {
+ /*
+ * Do the command prompt thing...
+ */
+
+ printf("lpc> ");
+ while (fgets(line, sizeof(line), stdin) != NULL)
+ {
+ /*
+ * Strip the trailing newline...
+ */
+
+ line[strlen(line) - 1] = '\0';
+
+ /*
+ * Find any options in the string...
+ */
+
+ while (isspace(line[0]))
+ strcpy(line, line + 1);
+
+ for (params = line; *params != '\0'; params ++)
+ if (isspace(*params))
+ break;
+
+ /*
+ * Remove whitespace between the command and parameters...
+ */
+
+ while (isspace(*params))
+ *params++ = '\0';
+
+ /*
+ * The "quit" and "exit" commands exit; otherwise, process as needed...
+ */
+
+ if (compare_strings(line, "quit", 1) == 0 ||
+ compare_strings(line, "exit", 2) == 0)
+ break;
+
+ if (*params == '\0')
+ do_command(http, line, NULL);
+ else
+ do_command(http, line, params);
+
+ /*
+ * Put another prompt out to the user...
+ */
+
+ printf("lpc> ");
+ }
+ }
+
+ /*
+ * Close the connection to the server and return...
+ */
+
+ httpClose(http);
+
+ return (0);
+}
+
+
+/*
+ * 'compare_strings()' - Compare two command-line strings.
+ */
+
+static int /* O - -1 or 1 = no match, 0 = match */
+compare_strings(char *s, /* I - Command-line string */
+ char *t, /* I - Option string */
+ int tmin) /* I - Minimum number of unique chars in option */
+{
+ int slen; /* Length of command-line string */
+
+
+ slen = strlen(s);
+ if (slen < tmin)
+ return (-1);
+ else
+ return (strncmp(s, t, slen));
+}
+
+
+/*
+ * 'do_command()' - Do an lpc command...
+ */
+
+static void
+do_command(http_t *http, /* I - HTTP connection to server */
+ char *command, /* I - Command string */
+ char *params) /* I - Parameters for command */
+{
+ if (compare_strings(command, "status", 4) == 0)
+ show_status(http, params);
+ else if (compare_strings(command, "help", 1) == 0 ||
+ strcmp(command, "?") == 0)
+ show_help(params);
+ else
+ printf("%s is not implemented by the CUPS version of lpc.\n", command);
+}
+
+
+/*
+ * 'show_help()' - Show help messages.
+ */
+
+static void
+show_help(char *command) /* I - Command to describe or NULL */
+{
+ if (command == NULL)
+ {
+ puts("Commands may be abbreviated. Commands are:");
+ puts("");
+ puts("exit help quit status ?");
+ }
+ else if (compare_strings(command, "help", 1) == 0 ||
+ strcmp(command, "?") == 0)
+ puts("help\t\tget help on commands");
+ else if (compare_strings(command, "status", 4) == 0)
+ puts("status\t\tshow status of daemon and queue");
+ else
+ puts("?Invalid help command unknown");
+}
+
+
+/*
+ * 'show_status()' - Show printers.
+ */
+
+static void
+show_status(http_t *http, /* I - HTTP connection to server */
+ char *dests) /* I - Destinations */
+{
+ ipp_t *request, /* IPP Request */
+ *response, /* IPP Response */
+ *jobs; /* IPP Get Jobs response */
+ ipp_attribute_t *attr, /* Current attribute */
+ *jattr; /* Current job attribute */
+ cups_lang_t *language; /* Default language */
+ char *printer, /* Printer name */
+ *device; /* Device URI */
+ ipp_pstate_t pstate; /* Printer state */
+ int accepting; /* Is printer accepting jobs? */
+ int jobcount; /* Count of current jobs */
+ char *dptr, /* Pointer into destination list */
+ *ptr; /* Pointer into printer name */
+ int match; /* Non-zero if this job matches */
+ char printer_uri[HTTP_MAX_URI];
+ /* Printer URI */
+ static const char *requested[] =
+ { /* Requested attributes */
+ "printer-name",
+ "device-uri",
+ "printer-state",
+ "printer-is-accepting-jobs"
+ };
+
+
+ DEBUG_printf(("show_status(%08x, %08x)\n", http, dests));
+
+ if (http == NULL)
+ return;
+
+ /*
+ * Build a CUPS_GET_PRINTERS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_PRINTERS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(requested) / sizeof(requested[0]),
+ NULL, requested);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/printers/")) != NULL)
+ {
+ DEBUG_puts("show_status: request succeeded...");
+
+ /*
+ * Loop through the printers returned in the list and display
+ * their status...
+ */
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a job...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this job...
+ */
+
+ printer = NULL;
+ device = "file:/dev/null";
+ pstate = IPP_PRINTER_IDLE;
+ jobcount = 0;
+ accepting = 1;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
+ {
+ if (strcmp(attr->name, "printer-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ printer = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "device-uri") == 0 &&
+ attr->value_tag == IPP_TAG_URI)
+ device = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-state") == 0 &&
+ attr->value_tag == IPP_TAG_ENUM)
+ pstate = (ipp_pstate_t)attr->values[0].integer;
+
+ if (strcmp(attr->name, "printer-is-accepting-jobs") == 0 &&
+ attr->value_tag == IPP_TAG_BOOLEAN)
+ accepting = attr->values[0].boolean;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (printer == NULL)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ /*
+ * See if this is a printer we're interested in...
+ */
+
+ match = dests == NULL;
+
+ if (dests != NULL)
+ {
+ for (dptr = dests; *dptr != '\0';)
+ {
+ /*
+ * Skip leading whitespace and commas...
+ */
+
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+
+ /*
+ * Compare names...
+ */
+
+ for (ptr = printer;
+ *ptr != '\0' && *dptr != '\0' && *ptr == *dptr;
+ ptr ++, dptr ++);
+
+ if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr)))
+ {
+ match = 1;
+ break;
+ }
+
+ /*
+ * Skip trailing junk...
+ */
+
+ while (!isspace(*dptr) && *dptr != '\0')
+ dptr ++;
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+ }
+ }
+
+ /*
+ * Display the printer entry if needed...
+ */
+
+ if (match)
+ {
+ /*
+ * If the printer state is "IPP_PRINTER_PROCESSING", then grab the
+ * current job for the printer.
+ */
+
+ if (pstate == IPP_PRINTER_PROCESSING)
+ {
+ /*
+ * Build an IPP_GET_JOBS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * limit
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_JOBS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL,
+ cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language->language);
+
+ snprintf(printer_uri, sizeof(printer_uri),
+ "ipp://localhost/printers/%s", printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, printer_uri);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", NULL, "job-id");
+
+ if ((jobs = cupsDoRequest(http, request, "/jobs/")) != NULL)
+ {
+ for (jattr = jobs->attrs; jattr != NULL; jattr = jattr->next)
+ if (jattr->name && strcmp(jattr->name, "job-id") == 0)
+ jobcount ++;
+
+ ippDelete(jobs);
+ }
+ }
+
+ /*
+ * Display it...
+ */
+
+ printf("%s:\n", printer);
+ if (strncmp(device, "file:", 5) == 0)
+ printf("\tprinter is on device \'%s\' speed -1\n", device + 5);
+ else
+ {
+ /*
+ * Just show the method...
+ */
+
+ *strchr(device, ':') = '\0';
+ printf("\tprinter is on device \'%s\' speed -1\n", device);
+ }
+
+ printf("\tqueuing is %sabled\n", accepting ? "en" : "dis");
+ printf("\tprinting is %sabled\n",
+ pstate == IPP_PRINTER_STOPPED ? "dis" : "en");
+ if (jobcount == 0)
+ puts("\tno entries");
+ else
+ printf("\t%d entries\n", jobcount);
+ puts("\tdaemon present");
+ }
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/berkeley/lpq.c b/berkeley/lpq.c
new file mode 100644
index 000000000..197f9f50a
--- /dev/null
+++ b/berkeley/lpq.c
@@ -0,0 +1,538 @@
+/*
+ * "$Id$"
+ *
+ * "lpq" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and commands.
+ * show_jobs() - Show jobs.
+ * show_printer() - Show printer status.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cups/string.h>
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <cups/debug.h>
+
+
+/*
+ * Local functions...
+ */
+
+static int show_jobs(http_t *, const char *, const char *, const int,
+ const int);
+static void show_printer(http_t *, const char *);
+
+
+/*
+ * 'main()' - Parse options and commands.
+ */
+
+int
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ http_t *http; /* Connection to server */
+ const char *dest, /* Desired printer */
+ *user; /* Desired user */
+ char *instance; /* Printer instance */
+ int id, /* Desired job ID */
+ interval, /* Reporting interval */
+ longstatus; /* Show file details */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dests; /* Destinations */
+#ifdef HAVE_LIBSSL
+ http_encryption_t encryption; /* Encryption? */
+#endif /* HAVE_LIBSSL */
+
+
+ /*
+ * Connect to the scheduler...
+ */
+
+ if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption())) == NULL)
+ {
+ fputs("lpq: Unable to contact server!\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Check for command-line options...
+ */
+
+ dest = NULL;
+ user = NULL;
+ id = 0;
+ interval = 0;
+ longstatus = 0;
+
+ num_dests = cupsGetDests(&dests);
+
+ for (i = 0; i < num_dests; i ++)
+ if (dests[i].is_default)
+ dest = dests[i].name;
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '+')
+ interval = atoi(argv[i] + 1);
+ else if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'E' : /* Encrypt */
+#ifdef HAVE_LIBSSL
+ encryption = HTTP_ENCRYPT_REQUIRED;
+
+ if (http)
+ httpEncryption(http, encryption);
+#else
+ fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
+ argv[0]);
+#endif /* HAVE_LIBSSL */
+ break;
+
+ case 'P' : /* Printer */
+ if (argv[i][2])
+ dest = argv[i] + 2;
+ else
+ {
+ i ++;
+ dest = argv[i];
+ }
+
+ if ((instance = strchr(dest, '/')) != NULL)
+ *instance = '\0';
+ break;
+
+ case 'a' : /* All printers */
+ dest = NULL;
+ break;
+
+ case 'l' : /* Long status */
+ longstatus = 1;
+ break;
+
+ default :
+ fputs("Usage: lpq [-P dest] [-l] [+interval]\n", stderr);
+ httpClose(http);
+ cupsFreeDests(num_dests, dests);
+ return (1);
+ }
+ }
+ else if (isdigit(argv[i][0]))
+ id = atoi(argv[i]);
+ else
+ user = argv[i];
+
+ /*
+ * Show the status in a loop...
+ */
+
+ for (;;)
+ {
+ if (dest)
+ show_printer(http, dest);
+
+ i = show_jobs(http, dest, user, id, longstatus);
+
+ if (i && interval)
+ {
+ fflush(stdout);
+ sleep(interval);
+ }
+ else
+ break;
+ }
+
+ /*
+ * Close the connection to the server and return...
+ */
+
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+
+ return (0);
+}
+
+
+/*
+ * 'show_jobs()' - Show jobs.
+ */
+
+static int /* O - Number of jobs in queue */
+show_jobs(http_t *http, /* I - HTTP connection to server */
+ const char *dest, /* I - Destination */
+ const char *user, /* I - User */
+ const int id, /* I - Job ID */
+ const int longstatus)/* I - 1 if long report desired */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ const char *jobdest, /* Pointer into job-printer-uri */
+ *jobuser, /* Pointer to job-originating-user-name */
+ *jobname; /* Pointer to job-name */
+ ipp_jstate_t jobstate; /* job-state */
+ int jobid, /* job-id */
+ jobsize, /* job-k-octets */
+#ifdef __osf__
+ jobpriority, /* job-priority */
+#endif /* __osf__ */
+ jobcount, /* Number of jobs */
+ jobcopies, /* Number of copies */
+ rank; /* Rank of job */
+ char resource[1024]; /* Resource string */
+ char rankstr[255]; /* Rank string */
+ char namestr[1024]; /* Job name string */
+ static const char *ranks[10] =/* Ranking strings */
+ {
+ "th",
+ "st",
+ "nd",
+ "rd",
+ "th",
+ "th",
+ "th",
+ "th",
+ "th",
+ "th"
+ };
+
+
+ DEBUG_printf(("show_jobs(%08x, %08x, %08x, %d, %d)\n", http, dest, user, id,
+ longstatus));
+
+ if (http == NULL)
+ return (0);
+
+ /*
+ * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires
+ * the following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * job-uri or printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ if (dest == NULL)
+ {
+ if (id)
+ sprintf(resource, "ipp://localhost/jobs/%d", id);
+ else
+ strcpy(resource, "ipp://localhost/jobs");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
+ NULL, resource);
+ }
+ else
+ {
+ snprintf(resource, sizeof(resource), "ipp://localhost/printers/%s", dest);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, resource);
+ }
+
+ if (user)
+ {
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, user);
+ ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
+ }
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ jobcount = 0;
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "lpq: get-jobs failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return (0);
+ }
+
+ rank = 1;
+
+ /*
+ * Loop through the job list and display them...
+ */
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a job...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this job...
+ */
+
+ jobid = 0;
+ jobsize = 0;
+#ifdef __osf__
+ jobpriority = 50;
+#endif /* __osf__ */
+ jobstate = IPP_JOB_PENDING;
+ jobname = "untitled";
+ jobuser = NULL;
+ jobdest = NULL;
+ jobcopies = 1;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
+ {
+ if (strcmp(attr->name, "job-id") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobid = attr->values[0].integer;
+
+ if (strcmp(attr->name, "job-k-octets") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobsize = attr->values[0].integer * 1024;
+
+#ifdef __osf__
+ if (strcmp(attr->name, "job-priority") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobpriority = attr->values[0].integer;
+#endif /* __osf__ */
+
+ if (strcmp(attr->name, "job-state") == 0 &&
+ attr->value_tag == IPP_TAG_ENUM)
+ jobstate = (ipp_jstate_t)attr->values[0].integer;
+
+ if (strcmp(attr->name, "job-printer-uri") == 0 &&
+ attr->value_tag == IPP_TAG_URI)
+ if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL)
+ jobdest ++;
+
+ if (strcmp(attr->name, "job-originating-user-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ jobuser = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "job-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ jobname = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "copies") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobcopies = attr->values[0].integer;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (jobdest == NULL || jobid == 0)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ if (!longstatus && jobcount == 0)
+#ifdef __osf__
+ puts("Rank Owner Pri Job Files Total Size");
+#else
+ puts("Rank Owner Job File(s) Total Size");
+#endif /* __osf__ */
+
+ jobcount ++;
+
+ /*
+ * Display the job...
+ */
+
+ if (jobstate == IPP_JOB_PROCESSING)
+ strcpy(rankstr, "active");
+ else
+ {
+ snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]);
+ rank ++;
+ }
+
+ if (longstatus)
+ {
+ puts("");
+
+ if (jobcopies > 1)
+ snprintf(namestr, sizeof(namestr), "%d copies of %s", jobcopies,
+ jobname);
+ else
+ strlcpy(namestr, jobname, sizeof(namestr));
+
+ printf("%s: %-34.34s[job %d localhost]\n", jobuser, rankstr, jobid);
+ printf(" %-40.40s%d bytes\n", namestr, jobsize);
+ }
+ else
+#ifdef __osf__
+ printf("%-6s %-10.10s %-4d %-10d %-27.27s %d bytes\n", rankstr, jobuser,
+ jobpriority, jobid, jobname, jobsize);
+#else
+ printf("%-7s %-8.8s%-8d%-32.32s%d bytes\n", rankstr, jobuser,
+ jobid, jobname, jobsize);
+#endif /* __osf */
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ fprintf(stderr, "lpq: get-jobs failed: %s\n", ippErrorString(cupsLastError()));
+ return (0);
+ }
+
+ if (jobcount == 0)
+ puts("no entries");
+
+ return (jobcount);
+}
+
+
+/*
+ * 'show_printer()' - Show printer status.
+ */
+
+static void
+show_printer(http_t *http, /* I - HTTP connection to server */
+ const char *dest) /* I - Destination */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ ipp_pstate_t state; /* Printer state */
+ char uri[HTTP_MAX_URI];
+ /* Printer URI */
+
+
+ if (http == NULL)
+ return;
+
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", dest);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "lpq: get-printer-attributes failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return;
+ }
+
+ if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
+ state = (ipp_pstate_t)attr->values[0].integer;
+ else
+ state = IPP_PRINTER_STOPPED;
+
+ switch (state)
+ {
+ case IPP_PRINTER_IDLE :
+ printf("%s is ready\n", dest);
+ break;
+ case IPP_PRINTER_PROCESSING :
+ printf("%s is ready and printing\n", dest);
+ break;
+ case IPP_PRINTER_STOPPED :
+ printf("%s is not ready\n", dest);
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ fprintf(stderr, "lpq: get-printer-attributes failed: %s\n",
+ ippErrorString(cupsLastError()));
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/berkeley/lpr.c b/berkeley/lpr.c
new file mode 100644
index 000000000..dc3206091
--- /dev/null
+++ b/berkeley/lpr.c
@@ -0,0 +1,430 @@
+/*
+ * "$Id$"
+ *
+ * "lpr" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and send files for printing.
+ * sighandler() - Signal catcher for when we print from stdin...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <config.h>
+#include <cups/cups.h>
+
+
+#ifndef WIN32
+# include <signal.h>
+
+
+/*
+ * Local functions.
+ */
+
+void sighandler(int);
+#endif /* !WIN32 */
+
+
+/*
+ * Globals...
+ */
+
+char tempfile[1024]; /* Temporary file for printing from stdin */
+
+
+/*
+ * 'main()' - Parse options and send files for printing.
+ */
+
+int
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i, j; /* Looping var */
+ int job_id; /* Job ID */
+ char ch; /* Option character */
+ char *printer, /* Destination printer or class */
+ *instance; /* Instance */
+ const char *title; /* Job title */
+ int num_copies; /* Number of copies per file */
+ int num_files; /* Number of files to print */
+ const char *files[1000]; /* Files to print */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dests, /* Destinations */
+ *dest; /* Selected destination */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ int deletefile; /* Delete file after print? */
+ char buffer[8192]; /* Copy buffer */
+ int temp; /* Temporary file descriptor */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Signal action */
+ struct sigaction oldaction; /* Old signal action */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ deletefile = 0;
+ printer = NULL;
+ num_dests = 0;
+ dests = NULL;
+ num_options = 0;
+ options = NULL;
+ num_files = 0;
+ title = NULL;
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ switch (ch = argv[i][1])
+ {
+ case 'E' : /* Encrypt */
+#ifdef HAVE_LIBSSL
+ cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+#else
+ fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
+ argv[0]);
+#endif /* HAVE_LIBSSL */
+ break;
+
+ case '1' : /* TROFF font set 1 */
+ case '2' : /* TROFF font set 2 */
+ case '3' : /* TROFF font set 3 */
+ case '4' : /* TROFF font set 4 */
+ case 'i' : /* indent */
+ case 'w' : /* width */
+ if (argv[i][2] == '\0')
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fprintf(stderr, "lpr: Expected value after -%c option!\n", ch);
+ return (1);
+ }
+ }
+
+ case 'c' : /* CIFPLOT */
+ case 'd' : /* DVI */
+ case 'f' : /* FORTRAN */
+ case 'g' : /* plot */
+ case 'n' : /* Ditroff */
+ case 't' : /* Troff */
+ case 'v' : /* Raster image */
+ fprintf(stderr, "Warning: \'%c\' format modifier not supported - output may not be correct!\n",
+ ch);
+ break;
+
+ case 'o' : /* Option */
+ if (argv[i][2] != '\0')
+ num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ fputs("lpr: Expected option=value after -o option!\n", stderr);
+ return (1);
+ }
+
+ num_options = cupsParseOptions(argv[i], num_options, &options);
+ }
+ break;
+
+ case 'l' : /* Literal/raw */
+ num_options = cupsAddOption("raw", "", num_options, &options);
+ break;
+
+ case 'p' : /* Prettyprint */
+ num_options = cupsAddOption("prettyprint", "", num_options, &options);
+ break;
+
+ case 'h' : /* Suppress burst page */
+ num_options = cupsAddOption("job-sheets", "none", num_options, &options);
+ break;
+
+ case 's' : /* Don't use symlinks */
+ break;
+
+ case 'm' : /* Mail on completion */
+ fputs("Warning: email notification is not supported!\n", stderr);
+ break;
+
+ case 'q' : /* Queue file but don't print */
+ num_options = cupsAddOption("job-hold-until", "indefinite",
+ num_options, &options);
+ break;
+
+ case 'r' : /* Remove file after printing */
+ deletefile = 1;
+ break;
+
+ case 'P' : /* Destination printer or class */
+ if (argv[i][2] != '\0')
+ printer = argv[i] + 2;
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ fputs("lpr: Expected destination after -P option!\n", stderr);
+ return (1);
+ }
+
+ printer = argv[i];
+ }
+
+ if ((instance = strrchr(printer, '/')) != NULL)
+ *instance++ = '\0';
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != NULL)
+ {
+ for (j = 0; j < dest->num_options; j ++)
+ if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
+ num_options = cupsAddOption(dest->options[j].name,
+ dest->options[j].value,
+ num_options, &options);
+ }
+ break;
+
+ case '#' : /* Number of copies */
+ if (argv[i][2] != '\0')
+ num_copies = atoi(argv[i] + 2);
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ fputs("lpr: Expected copy count after -# option!\n", stderr);
+ return (1);
+ }
+
+ num_copies = atoi(argv[i]);
+ }
+
+ if (num_copies < 1 || num_copies > 100)
+ {
+ fputs("lpr: Number copies must be between 1 and 100.\n", stderr);
+ return (1);
+ }
+
+ sprintf(buffer, "%d", num_copies);
+ num_options = cupsAddOption("copies", buffer, num_options, &options);
+ break;
+
+ case 'C' : /* Class */
+ case 'J' : /* Job name */
+ case 'T' : /* Title */
+ if (argv[i][2] != '\0')
+ title = argv[i] + 2;
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ fprintf(stderr, "lpr: Expected name after -%c option!\n", ch);
+ return (1);
+ }
+
+ title = argv[i];
+ }
+ break;
+
+ case 'U' : /* User */
+ if (argv[i][2] != '\0')
+ cupsSetUser(argv[i] + 2);
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ fputs("lpr: Expected username after -U option!\n", stderr);
+ return (1);
+ }
+
+ cupsSetUser(argv[i]);
+ }
+ break;
+
+ default :
+ fprintf(stderr, "lpr: Unknown option \'%c\'!\n", argv[i][1]);
+ return (1);
+ }
+ else if (num_files < 1000)
+ {
+ /*
+ * Print a file...
+ */
+
+ files[num_files] = argv[i];
+ num_files ++;
+
+ if (title == NULL)
+ {
+ if ((title = strrchr(argv[i], '/')) != NULL)
+ title ++;
+ else
+ title = argv[i];
+ }
+ }
+ else
+ fprintf(stderr, "lpr: Too many files - \"%s\"\n", argv[i]);
+ /*
+ * See if we have any files to print; if not, print from stdin...
+ */
+
+ if (printer == NULL)
+ {
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ for (j = 0, dest = dests; j < num_dests; j ++, dest ++)
+ if (dest->is_default)
+ {
+ printer = dests[j].name;
+
+ for (j = 0; j < dest->num_options; j ++)
+ if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
+ num_options = cupsAddOption(dest->options[j].name,
+ dest->options[j].value,
+ num_options, &options);
+ break;
+ }
+ }
+
+ if (printer == NULL)
+ {
+ fputs("lpr: error - no default destination available.\n", stderr);
+ return (1);
+ }
+
+ if (num_files > 0)
+ {
+ job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options);
+
+ if (deletefile)
+ {
+ /*
+ * Delete print files after printing...
+ */
+
+ for (i = 0; i < num_files; i ++)
+ unlink(files[i]);
+ }
+ }
+ else
+ {
+ num_files = 1;
+
+#ifndef WIN32
+# if defined(HAVE_SIGSET)
+ sigset(SIGHUP, sighandler);
+ if (sigset(SIGINT, sighandler) == SIG_IGN)
+ sigset(SIGINT, SIG_IGN);
+ sigset(SIGTERM, sighandler);
+# elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = sighandler;
+
+ sigaction(SIGHUP, &action, NULL);
+ sigaction(SIGINT, NULL, &oldaction);
+ if (oldaction.sa_handler != SIG_IGN)
+ sigaction(SIGINT, &action, NULL);
+ sigaction(SIGTERM, &action, NULL);
+# else
+ signal(SIGHUP, sighandler);
+ if (signal(SIGINT, sighandler) == SIG_IGN)
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, sighandler);
+# endif
+#endif /* !WIN32 */
+
+ if ((temp = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
+ {
+ fputs("lpr: unable to create temporary file.\n", stderr);
+ return (1);
+ }
+
+ while ((i = read(0, buffer, sizeof(buffer))) > 0)
+ write(temp, buffer, i);
+
+ i = lseek(temp, 0, SEEK_CUR);
+ close(temp);
+
+ if (i == 0)
+ {
+ fputs("lpr: stdin is empty, so no job has been sent.\n", stderr);
+ return (1);
+ }
+
+ if (title)
+ job_id = cupsPrintFile(printer, tempfile, title, num_options, options);
+ else
+ job_id = cupsPrintFile(printer, tempfile, "(stdin)", num_options, options);
+
+ unlink(tempfile);
+ }
+
+ if (job_id < 1)
+ {
+ fprintf(stderr, "lpr: unable to print file: %s\n",
+ ippErrorString(cupsLastError()));
+ return (1);
+ }
+
+ return (0);
+}
+
+
+#ifndef WIN32
+/*
+ * 'sighandler()' - Signal catcher for when we print from stdin...
+ */
+
+void
+sighandler(int s) /* I - Signal number */
+{
+ /*
+ * Remove the temporary file we're using to print from stdin...
+ */
+
+ unlink(tempfile);
+
+ /*
+ * Exit...
+ */
+
+ exit(s);
+}
+#endif /* !WIN32 */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/berkeley/lprm.c b/berkeley/lprm.c
new file mode 100644
index 000000000..363fc2ecd
--- /dev/null
+++ b/berkeley/lprm.c
@@ -0,0 +1,267 @@
+/*
+ * "$Id$"
+ *
+ * "lprm" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and cancel jobs.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <cups/string.h>
+
+
+/*
+ * 'main()' - Parse options and cancel jobs.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ http_t *http; /* HTTP connection to server */
+ int i; /* Looping var */
+ int job_id; /* Job ID */
+ const char *dest; /* Destination printer */
+ char *instance; /* Pointer to instance name */
+ char uri[1024]; /* Printer or job URI */
+ ipp_t *request; /* IPP request */
+ ipp_t *response; /* IPP response */
+ ipp_op_t op; /* Operation */
+ cups_lang_t *language; /* Language */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dests; /* Destinations */
+ http_encryption_t encryption; /* Encryption? */
+
+
+ /*
+ * Setup to cancel individual print jobs...
+ */
+
+ op = IPP_CANCEL_JOB;
+ job_id = 0;
+ dest = NULL;
+ response = NULL;
+ http = NULL;
+ encryption = cupsEncryption();
+
+ num_dests = cupsGetDests(&dests);
+
+ for (i = 0; i < num_dests; i ++)
+ if (dests[i].is_default)
+ dest = dests[i].name;
+
+ /*
+ * Open a connection to the server...
+ */
+
+ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), encryption)) == NULL)
+ {
+ fputs("lprm: Unable to contact server!\n", stderr);
+ cupsFreeDests(num_dests, dests);
+ return (1);
+ }
+
+ /*
+ * Process command-line arguments...
+ */
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-' && argv[i][1] != '\0')
+ switch (argv[i][1])
+ {
+ case 'E' : /* Encrypt */
+#ifdef HAVE_LIBSSL
+ encryption = HTTP_ENCRYPT_REQUIRED;
+
+ httpEncryption(http, encryption);
+#else
+ fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
+ argv[0]);
+#endif /* HAVE_LIBSSL */
+ break;
+
+ case 'P' : /* Cancel jobs on a printer */
+ if (argv[i][2])
+ dest = argv[i] + 2;
+ else
+ {
+ i ++;
+ dest = argv[i];
+ }
+
+ if ((instance = strchr(dest, '/')) != NULL)
+ *instance = '\0';
+ break;
+
+ default :
+ fprintf(stderr, "lprm: Unknown option \'%c\'!\n", argv[i][1]);
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+ return (1);
+ }
+ else
+ {
+ /*
+ * Cancel a job or printer...
+ */
+
+ if (isdigit(argv[i][0]) && cupsGetDest(argv[i], NULL, num_dests, dests) == NULL)
+ {
+ dest = NULL;
+ op = IPP_CANCEL_JOB;
+ job_id = atoi(argv[i]);
+ }
+ else if (strcmp(argv[i], "-") == 0)
+ {
+ /*
+ * Cancel all jobs
+ */
+
+ op = IPP_PURGE_JOBS;
+ }
+ else
+ {
+ dest = argv[i];
+ job_id = 0;
+ }
+
+ /*
+ * Build an IPP request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri + job-id *or* job-uri
+ * [requesting-user-name]
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = op;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ if (dest)
+ {
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", dest);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
+ job_id);
+ }
+ else
+ {
+ sprintf(uri, "ipp://localhost/jobs/%d", job_id);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
+ uri);
+ }
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if (op == IPP_PURGE_JOBS)
+ response = cupsDoRequest(http, request, "/admin/");
+ else
+ response = cupsDoRequest(http, request, "/jobs/");
+
+ if (response != NULL)
+ {
+ switch (response->request.status.status_code)
+ {
+ case IPP_NOT_FOUND :
+ fputs("lprm: Job or printer not found!\n", stderr);
+ break;
+ case IPP_NOT_AUTHORIZED :
+ fputs("lprm: Not authorized to lprm job(s)!\n", stderr);
+ break;
+ case IPP_FORBIDDEN :
+ fprintf(stderr, "lprm: You don't own job ID %d!\n", job_id);
+ break;
+ default :
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fputs("lprm: Unable to lprm job(s)!\n", stderr);
+ break;
+ }
+
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ ippDelete(response);
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+ return (1);
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ fputs("lprm: Unable to cancel job(s)!\n", stderr);
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+ return (1);
+ }
+ }
+
+ /*
+ * If nothing has been cancelled yet, cancel the current job on the specified
+ * (or default) printer...
+ */
+
+ if (response == NULL)
+ if (!cupsCancelJob(dest, 0))
+ {
+ fputs("lprm: Unable to cancel job(s)!\n", stderr);
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+ return (1);
+ }
+
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cgi-bin/.cvsignore b/cgi-bin/.cvsignore
new file mode 100644
index 000000000..77c74e433
--- /dev/null
+++ b/cgi-bin/.cvsignore
@@ -0,0 +1,5 @@
+admin.cgi
+classes.cgi
+jobs.cgi
+libcgi.a
+printers.cgi
diff --git a/cgi-bin/Dependencies b/cgi-bin/Dependencies
new file mode 100644
index 000000000..d69abebfa
--- /dev/null
+++ b/cgi-bin/Dependencies
@@ -0,0 +1,20 @@
+# DO NOT DELETE
+
+html.o: cgi.h ../cups/string.h ../config.h
+ipp-var.o: ipp-var.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+ipp-var.o: ../cups/md5.h ../cups/ppd.h ../cups/debug.h ../cups/language.h
+ipp-var.o: ../cups/string.h ../config.h cgi.h
+template.o: cgi.h ../cups/string.h ../config.h
+var.o: cgi.h ../cups/string.h ../config.h
+admin.o: ipp-var.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+admin.o: ../cups/ppd.h ../cups/debug.h ../cups/language.h ../cups/string.h
+admin.o: ../config.h cgi.h
+classes.o: ipp-var.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+classes.o: ../cups/md5.h ../cups/ppd.h ../cups/debug.h ../cups/language.h
+classes.o: ../cups/string.h ../config.h cgi.h
+jobs.o: ipp-var.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+jobs.o: ../cups/ppd.h ../cups/debug.h ../cups/language.h ../cups/string.h
+jobs.o: ../config.h cgi.h
+printers.o: ipp-var.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+printers.o: ../cups/md5.h ../cups/ppd.h ../cups/debug.h ../cups/language.h
+printers.o: ../cups/string.h ../config.h cgi.h
diff --git a/cgi-bin/Makefile b/cgi-bin/Makefile
new file mode 100644
index 000000000..85237077d
--- /dev/null
+++ b/cgi-bin/Makefile
@@ -0,0 +1,123 @@
+#
+# "$Id$"
+#
+# CGI makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+CGIS = admin.cgi classes.cgi jobs.cgi printers.cgi
+TARGETS = libcgi.a $(CGIS)
+LIBOBJS = html.o ipp-var.o template.o var.o
+OBJS = $(LIBOBJS) admin.o classes.o jobs.o printers.o
+
+
+#
+# Make all targets...
+#
+
+all: $(TARGETS)
+
+
+#
+# Clean all object files...
+#
+
+clean:
+ $(RM) $(OBJS) $(TARGETS)
+
+
+#
+# Update dependencies (without system header dependencies...)
+#
+
+depend:
+ makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1
+
+
+#
+# Install all targets...
+#
+
+install: all
+ $(INSTALL_DIR) $(SERVERBIN)/cgi-bin
+ for file in $(CGIS); do \
+ $(INSTALL_BIN) $$file $(SERVERBIN)/cgi-bin; \
+ done
+
+
+#
+# libcgi.a
+#
+
+libcgi.a: $(LIBOBJS)
+ echo Archiving $@...
+ $(RM) $@
+ $(AR) $(ARFLAGS) $@ $(LIBOBJS)
+ $(RANLIB) $@
+
+
+#
+# admin.cgi
+#
+
+admin.cgi: admin.o ../Makedefs ../cups/$(LIBCUPS) libcgi.a
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ admin.o libcgi.a $(LIBS)
+
+
+#
+# classes.cgi
+#
+
+classes.cgi: classes.o ../Makedefs ../cups/$(LIBCUPS) libcgi.a
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ classes.o libcgi.a $(LIBS)
+
+
+#
+# jobs.cgi
+#
+
+jobs.cgi: jobs.o ../Makedefs ../cups/$(LIBCUPS) libcgi.a
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ jobs.o libcgi.a $(LIBS)
+
+
+#
+# printers.cgi
+#
+
+printers.cgi: printers.o ../Makedefs ../cups/$(LIBCUPS) libcgi.a
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ printers.o libcgi.a $(LIBS)
+
+
+#
+# Dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id$".
+#
diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c
new file mode 100644
index 000000000..f64ad8c60
--- /dev/null
+++ b/cgi-bin/admin.c
@@ -0,0 +1,1533 @@
+/*
+ * "$Id$"
+ *
+ * Administration CGI for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Main entry for CGI.
+ * do_am_class() - Add or modify a class.
+ * do_am_printer() - Add or modify a printer.
+ * do_config_printer() - Configure the default options for a printer.
+ * do_delete_class() - Delete a class...
+ * do_delete_printer() - Delete a printer...
+ * do_printer_op() - Do a printer operation.
+ * get_line() - Get a line that is terminated by a LF, CR, or CR LF.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "ipp-var.h"
+#include <ctype.h>
+#include <errno.h>
+
+
+/*
+ * Local functions...
+ */
+
+static void do_am_class(http_t *http, cups_lang_t *language, int modify);
+static void do_am_printer(http_t *http, cups_lang_t *language, int modify);
+static void do_config_printer(http_t *http, cups_lang_t *language);
+static void do_delete_class(http_t *http, cups_lang_t *language);
+static void do_delete_printer(http_t *http, cups_lang_t *language);
+static void do_printer_op(http_t *http, cups_lang_t *language, ipp_op_t op);
+static char *get_line(char *buf, int length, FILE *fp);
+
+
+/*
+ * 'main()' - Main entry for CGI.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ cups_lang_t *language; /* Language information */
+ http_t *http; /* Connection to the server */
+ const char *op; /* Operation name */
+
+
+ /*
+ * Get the request language...
+ */
+
+ language = cupsLangDefault();
+
+ /*
+ * Send a standard header...
+ */
+
+ printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language));
+
+ cgiSetVariable("TITLE", "Admin");
+ ippSetServerVersion();
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "header.tmpl", getenv("LANG"));
+
+ /*
+ * See if we have form data...
+ */
+
+ if (!cgiInitialize())
+ {
+ /*
+ * Nope, send the administration menu...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "admin.tmpl", getenv("LANG"));
+ }
+ else if ((op = cgiGetVariable("OP")) != NULL)
+ {
+ /*
+ * Connect to the HTTP server...
+ */
+
+ http = httpConnectEncrypt("localhost", ippPort(), cupsEncryption());
+
+ /*
+ * Do the operation...
+ */
+
+ if (strcmp(op, "start-printer") == 0)
+ do_printer_op(http, language, IPP_RESUME_PRINTER);
+ else if (strcmp(op, "stop-printer") == 0)
+ do_printer_op(http, language, IPP_PAUSE_PRINTER);
+ else if (strcmp(op, "accept-jobs") == 0)
+ do_printer_op(http, language, CUPS_ACCEPT_JOBS);
+ else if (strcmp(op, "reject-jobs") == 0)
+ do_printer_op(http, language, CUPS_REJECT_JOBS);
+ else if (strcmp(op, "purge-jobs") == 0)
+ do_printer_op(http, language, IPP_PURGE_JOBS);
+ else if (strcmp(op, "add-class") == 0)
+ do_am_class(http, language, 0);
+ else if (strcmp(op, "add-printer") == 0)
+ do_am_printer(http, language, 0);
+ else if (strcmp(op, "modify-class") == 0)
+ do_am_class(http, language, 1);
+ else if (strcmp(op, "modify-printer") == 0)
+ do_am_printer(http, language, 1);
+ else if (strcmp(op, "delete-class") == 0)
+ do_delete_class(http, language);
+ else if (strcmp(op, "delete-printer") == 0)
+ do_delete_printer(http, language);
+ else if (strcmp(op, "config-printer") == 0)
+ do_config_printer(http, language);
+ else
+ {
+ /*
+ * Bad operation code... Display an error...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "admin-op.tmpl", getenv("LANG"));
+ }
+
+ /*
+ * Close the HTTP server connection...
+ */
+
+ httpClose(http);
+ }
+ else
+ {
+ /*
+ * Form data but no operation code... Display an error...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "admin-op.tmpl", getenv("LANG"));
+ }
+
+ /*
+ * Send the standard trailer...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "trailer.tmpl", getenv("LANG"));
+
+ /*
+ * Free the request language...
+ */
+
+ cupsLangFree(language);
+
+ /*
+ * Return with no errors...
+ */
+
+ return (0);
+}
+
+
+/*
+ * 'do_am_class()' - Add or modify a class.
+ */
+
+static void
+do_am_class(http_t *http, /* I - HTTP connection */
+ cups_lang_t *language, /* I - Client's language */
+ int modify) /* I - Modify the printer? */
+{
+ int i, j; /* Looping vars */
+ int element; /* Element number */
+ int num_printers; /* Number of printers */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ ipp_attribute_t *attr; /* member-uris attribute */
+ ipp_status_t status; /* Request status */
+ char uri[HTTP_MAX_URI]; /* Device or printer URI */
+ const char *name, /* Pointer to class name */
+ *ptr; /* Pointer to CGI variable */
+
+
+ if (cgiGetVariable("PRINTER_LOCATION") == NULL)
+ {
+ if (modify)
+ {
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
+ * following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s",
+ cgiGetVariable("PRINTER_NAME"));
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ ippSetCGIVars(response, NULL, NULL);
+ ippDelete(response);
+ }
+
+ /*
+ * Update the location and description of an existing printer...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "modify-class.tmpl", getenv("LANG"));
+ }
+ else
+ {
+ /*
+ * Get the name, location, and description for a new printer...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "add-class.tmpl", getenv("LANG"));
+ }
+
+ return;
+ }
+
+ name = cgiGetVariable("PRINTER_NAME");
+ for (ptr = name; *ptr; ptr ++)
+ if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/')
+ break;
+
+ if (*ptr || ptr == name || strlen(name) > 127)
+ {
+ cgiSetVariable("ERROR", "The class name may only contain up to 127 printable "
+ "characters.");
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ return;
+ }
+
+ if (cgiGetVariable("MEMBER_URIS") == NULL)
+ {
+ /*
+ * Build a CUPS_GET_PRINTERS request, which requires the
+ * following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_PRINTERS;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://localhost/printers");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ /*
+ * Create MEMBER_URIS and MEMBER_NAMES arrays...
+ */
+
+ for (element = 0, attr = response->attrs;
+ attr != NULL;
+ attr = attr->next)
+ if (attr->name && strcmp(attr->name, "printer-uri-supported") == 0)
+ {
+ cgiSetArray("MEMBER_URIS", element, attr->values[0].string.text);
+ element ++;
+ }
+
+ for (element = 0, attr = response->attrs;
+ attr != NULL;
+ attr = attr->next)
+ if (attr->name && strcmp(attr->name, "printer-name") == 0)
+ {
+ cgiSetArray("MEMBER_NAMES", element, attr->values[0].string.text);
+ element ++;
+ }
+
+ num_printers = cgiGetSize("MEMBER_URIS");
+
+ ippDelete(response);
+ }
+ else
+ num_printers = 0;
+
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
+ * following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s",
+ cgiGetVariable("PRINTER_NAME"));
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL)
+ {
+ /*
+ * Mark any current members in the class...
+ */
+
+ for (j = 0; j < num_printers; j ++)
+ cgiSetArray("MEMBER_SELECTED", j, "");
+
+ for (i = 0; i < attr->num_values; i ++)
+ for (j = 0; j < num_printers; j ++)
+ if (strcmp(attr->values[i].string.text, cgiGetArray("MEMBER_URIS", j)) == 0)
+ {
+ cgiSetArray("MEMBER_SELECTED", j, "SELECTED");
+ break;
+ }
+ }
+
+ ippDelete(response);
+ }
+
+ /*
+ * Let the user choose...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "choose-members.tmpl", getenv("LANG"));
+ }
+ else
+ {
+ /*
+ * Build a CUPS_ADD_CLASS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * printer-location
+ * printer-info
+ * printer-is-accepting-jobs
+ * printer-state
+ * member-uris
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_ADD_CLASS;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s",
+ cgiGetVariable("PRINTER_NAME"));
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
+ NULL, cgiGetVariable("PRINTER_LOCATION"));
+
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
+ NULL, cgiGetVariable("PRINTER_INFO"));
+
+ ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
+
+ ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
+ IPP_PRINTER_IDLE);
+
+ if ((num_printers = cgiGetSize("MEMBER_URIS")) > 0)
+ {
+ attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris",
+ num_printers, NULL, NULL);
+ for (i = 0; i < num_printers; i ++)
+ attr->values[i].string.text = strdup(cgiGetArray("MEMBER_URIS", i));
+ }
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
+ {
+ status = response->request.status.status_code;
+ ippDelete(response);
+ }
+ else
+ status = IPP_NOT_AUTHORIZED;
+
+ if (status > IPP_OK_CONFLICT)
+ {
+ cgiSetVariable("ERROR", ippErrorString(status));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ }
+ else if (modify)
+ cgiCopyTemplateLang(stdout, TEMPLATES, "class-modified.tmpl", getenv("LANG"));
+ else
+ cgiCopyTemplateLang(stdout, TEMPLATES, "class-added.tmpl", getenv("LANG"));
+ }
+}
+
+
+/*
+ * 'do_am_printer()' - Add or modify a printer.
+ */
+
+static void
+do_am_printer(http_t *http, /* I - HTTP connection */
+ cups_lang_t *language, /* I - Client's language */
+ int modify) /* I - Modify the printer? */
+{
+ int i; /* Looping var */
+ int element; /* Element number */
+ ipp_attribute_t *attr, /* Current attribute */
+ *last; /* Last attribute */
+ ipp_t *request, /* IPP request */
+ *response, /* IPP response */
+ *oldinfo; /* Old printer information */
+ ipp_status_t status; /* Request status */
+ const char *var; /* CGI variable */
+ char uri[HTTP_MAX_URI], /* Device or printer URI */
+ *uriptr; /* Pointer into URI */
+ int maxrate; /* Maximum baud rate */
+ char baudrate[255]; /* Baud rate string */
+ char make[255]; /* Make string */
+ const char *name, /* Pointer to class name */
+ *ptr; /* Pointer to CGI variable */
+ static int baudrates[] = /* Baud rates */
+ {
+ 1200,
+ 2400,
+ 4800,
+ 9600,
+ 19200,
+ 38400,
+ 57600,
+ 115200,
+ 230400,
+ 460800
+ };
+
+
+ if (modify)
+ {
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
+ * following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
+ cgiGetVariable("PRINTER_NAME"));
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ oldinfo = cupsDoRequest(http, request, "/");
+ }
+ else
+ oldinfo = NULL;
+
+ if ((name = cgiGetVariable("PRINTER_NAME")) == NULL ||
+ cgiGetVariable("PRINTER_LOCATION") == NULL)
+ {
+ if (modify)
+ {
+ /*
+ * Update the location and description of an existing printer...
+ */
+
+ if (oldinfo)
+ ippSetCGIVars(oldinfo, NULL, NULL);
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "modify-printer.tmpl", getenv("LANG"));
+ }
+ else
+ {
+ /*
+ * Get the name, location, and description for a new printer...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "add-printer.tmpl", getenv("LANG"));
+ }
+
+ if (oldinfo)
+ ippDelete(oldinfo);
+
+ return;
+ }
+
+ for (ptr = name; *ptr; ptr ++)
+ if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/')
+ break;
+
+ if (*ptr || ptr == name || strlen(name) > 127)
+ {
+ cgiSetVariable("ERROR", "The printer name may only contain up to 127 printable "
+ "characters.");
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ return;
+ }
+
+ if ((var = cgiGetVariable("DEVICE_URI")) == NULL)
+ {
+ /*
+ * Build a CUPS_GET_DEVICES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_DEVICES;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://localhost/printers/");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ ippSetCGIVars(response, NULL, NULL);
+ ippDelete(response);
+ }
+
+ /*
+ * Let the user choose...
+ */
+
+ if (oldinfo &&
+ (attr = ippFindAttribute(oldinfo, "device-uri", IPP_TAG_URI)) != NULL)
+ {
+ strlcpy(uri, attr->values[0].string.text, sizeof(uri));
+ if ((uriptr = strchr(uri, ':')) != NULL && strncmp(uriptr, "://", 3) == 0)
+ *uriptr = '\0';
+
+ cgiSetVariable("CURRENT_DEVICE_URI", uri);
+ }
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "choose-device.tmpl", getenv("LANG"));
+ }
+ else if (strchr(var, '/') == NULL)
+ {
+ if (oldinfo &&
+ (attr = ippFindAttribute(oldinfo, "device-uri", IPP_TAG_URI)) != NULL)
+ {
+ /*
+ * Set the current device URI for the form to the old one...
+ */
+
+ if (strncmp(attr->values[0].string.text, var, strlen(var)) == 0)
+ cgiSetVariable("DEVICE_URI", attr->values[0].string.text);
+ }
+
+ /*
+ * User needs to set the full URI...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "choose-uri.tmpl", getenv("LANG"));
+ }
+ else if (strncmp(var, "serial:", 7) == 0 && cgiGetVariable("BAUDRATE") == NULL)
+ {
+ /*
+ * Need baud rate, parity, etc.
+ */
+
+ if ((var = strchr(var, '?')) != NULL &&
+ strncmp(var, "?baud=", 6) == 0)
+ maxrate = atoi(var + 6);
+ else
+ maxrate = 19200;
+
+ for (i = 0; i < 10; i ++)
+ if (baudrates[i] > maxrate)
+ break;
+ else
+ {
+ sprintf(baudrate, "%d", baudrates[i]);
+ cgiSetArray("BAUDRATES", i, baudrate);
+ }
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "choose-serial.tmpl", getenv("LANG"));
+ }
+ else if ((var = cgiGetVariable("PPD_NAME")) == NULL)
+ {
+ if (modify)
+ {
+ /*
+ * Get the PPD file...
+ */
+
+ int fd; /* PPD file */
+ char filename[1024]; /* PPD filename */
+ ppd_file_t *ppd; /* PPD information */
+ char buffer[1024]; /* Buffer */
+ int bytes; /* Number of bytes */
+
+
+ snprintf(uri, sizeof(uri), "/printers/%s.ppd", name);
+
+ if (httpGet(http, uri))
+ httpGet(http, uri);
+
+ while (httpUpdate(http) == HTTP_CONTINUE);
+
+ if ((fd = cupsTempFd(filename, sizeof(filename))) >= 0)
+ {
+ while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0)
+ write(fd, buffer, bytes);
+
+ close(fd);
+
+ if ((ppd = ppdOpenFile(filename)) != NULL)
+ {
+ if (ppd->manufacturer)
+ cgiSetVariable("CURRENT_MAKE", ppd->manufacturer);
+ if (ppd->nickname)
+ cgiSetVariable("CURRENT_MAKE_AND_MODEL", ppd->nickname);
+
+ ppdClose(ppd);
+ }
+
+ unlink(filename);
+ }
+ else
+ httpFlush(http);
+ }
+
+ /*
+ * Build a CUPS_GET_PPDS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_PPDS;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://localhost/printers/");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if ((var = cgiGetVariable("PPD_MAKE")) == NULL)
+ {
+ /*
+ * Let the user choose a make...
+ */
+
+ for (element = 0, attr = response->attrs, last = NULL;
+ attr != NULL;
+ attr = attr->next)
+ if (attr->name && strcmp(attr->name, "ppd-make") == 0)
+ if (last == NULL ||
+ strcasecmp(last->values[0].string.text,
+ attr->values[0].string.text) != 0)
+ {
+ cgiSetArray("PPD_MAKE", element, attr->values[0].string.text);
+ element ++;
+ last = attr;
+ }
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "choose-make.tmpl",
+ getenv("LANG"));
+ }
+ else
+ {
+ /*
+ * Let the user choose a model...
+ */
+
+ strlcpy(make, var, sizeof(make));
+
+ ippSetCGIVars(response, "ppd-make", make);
+ cgiCopyTemplateLang(stdout, TEMPLATES, "choose-model.tmpl",
+ getenv("LANG"));
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ char message[1024];
+
+
+ snprintf(message, sizeof(message), "Unable to get list of printer drivers: %s",
+ ippErrorString(cupsLastError()));
+ cgiSetVariable("ERROR", message);
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ }
+ }
+ else
+ {
+ /*
+ * Build a CUPS_ADD_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * printer-location
+ * printer-info
+ * ppd-name
+ * device-uri
+ * printer-is-accepting-jobs
+ * printer-state
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_ADD_PRINTER;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
+ cgiGetVariable("PRINTER_NAME"));
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
+ NULL, cgiGetVariable("PRINTER_LOCATION"));
+
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
+ NULL, cgiGetVariable("PRINTER_INFO"));
+
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "ppd-name",
+ NULL, cgiGetVariable("PPD_NAME"));
+
+ strlcpy(uri, cgiGetVariable("DEVICE_URI"), sizeof(uri));
+ if (strncmp(uri, "serial:", 7) == 0)
+ {
+ /*
+ * Update serial port URI to include baud rate, etc.
+ */
+
+ if ((uriptr = strchr(uri, '?')) == NULL)
+ uriptr = uri + strlen(uri);
+
+ snprintf(uriptr, sizeof(uri) - (uriptr - uri),
+ "?baud=%s+bits=%s+parity=%s+flow=%s",
+ cgiGetVariable("BAUDRATE"), cgiGetVariable("BITS"),
+ cgiGetVariable("PARITY"), cgiGetVariable("FLOW"));
+ }
+
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri",
+ NULL, uri);
+
+ ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
+
+ ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
+ IPP_PRINTER_IDLE);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
+ {
+ status = response->request.status.status_code;
+ ippDelete(response);
+ }
+ else
+ status = IPP_NOT_AUTHORIZED;
+
+ if (status > IPP_OK_CONFLICT)
+ {
+ cgiSetVariable("ERROR", ippErrorString(status));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ }
+ else if (modify)
+ cgiCopyTemplateLang(stdout, TEMPLATES, "printer-modified.tmpl", getenv("LANG"));
+ else
+ cgiCopyTemplateLang(stdout, TEMPLATES, "printer-added.tmpl", getenv("LANG"));
+ }
+
+ if (oldinfo)
+ ippDelete(oldinfo);
+}
+
+
+/*
+ * 'do_config_printer()' - Configure the default options for a printer.
+ */
+
+static void
+do_config_printer(http_t *http, /* I - HTTP connection */
+ cups_lang_t *language)/* I - Client's language */
+{
+ int i, j, k; /* Looping vars */
+ int have_options; /* Have options? */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ ipp_attribute_t *attr; /* IPP attribute */
+ char uri[HTTP_MAX_URI]; /* Job URI */
+ const char *var; /* Variable value */
+ const char *printer; /* Printer printer name */
+ ipp_status_t status; /* Operation status... */
+ const char *filename; /* PPD filename */
+ char tempfile[1024]; /* Temporary filename */
+ FILE *in, /* Input file */
+ *out; /* Output file */
+ int outfd; /* Output file descriptor */
+ char line[1024]; /* Line from PPD file */
+ char keyword[1024], /* Keyword from Default line */
+ *keyptr; /* Pointer into keyword... */
+ ppd_file_t *ppd; /* PPD file */
+ ppd_group_t *group; /* Option group */
+ ppd_option_t *option; /* Option */
+
+
+ /*
+ * Get the printer name...
+ */
+
+ if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+ else
+ {
+ cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ return;
+ }
+
+ /*
+ * Get the PPD file...
+ */
+
+ if ((filename = cupsGetPPD(printer)) == NULL)
+ {
+ cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ return;
+ }
+
+ ppd = ppdOpenFile(filename);
+
+ if (cgiGetVariable("job_sheets_start") != NULL ||
+ cgiGetVariable("job_sheets_end") != NULL)
+ have_options = 1;
+ else
+ have_options = 0;
+
+ ppdMarkDefaults(ppd);
+
+ DEBUG_printf(("<P>ppd->num_groups = %d\n"
+ "<UL>\n", ppd->num_groups));
+
+ for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
+ {
+ DEBUG_printf(("<LI>%s<UL>\n", group->text));
+
+ for (j = group->num_options, option = group->options; j > 0; j --, option ++)
+ if ((var = cgiGetVariable(option->keyword)) != NULL)
+ {
+ DEBUG_printf(("<LI>%s = \"%s\"</LI>\n", option->keyword, var));
+ have_options = 1;
+ ppdMarkOption(ppd, option->keyword, var);
+ }
+#ifdef DEBUG
+ else
+ printf("<LI>%s not defined!</LI>\n", option->keyword);
+#endif /* DEBUG */
+
+ DEBUG_puts("</UL></LI>");
+ }
+
+ DEBUG_printf(("</UL>\n"
+ "<P>ppdConflicts(ppd) = %d\n", ppdConflicts(ppd)));
+
+ if (!have_options || ppdConflicts(ppd))
+ {
+ /*
+ * Show the options to the user...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "config-printer.tmpl",
+ getenv("LANG"));
+
+ if (ppdConflicts(ppd))
+ {
+ for (i = ppd->num_groups, k = 0, group = ppd->groups; i > 0; i --, group ++)
+ for (j = group->num_options, option = group->options; j > 0; j --, option ++)
+ if (option->conflicted)
+ {
+ cgiSetArray("ckeyword", k, option->keyword);
+ cgiSetArray("ckeytext", k, option->text);
+ k ++;
+ }
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "option-conflict.tmpl",
+ getenv("LANG"));
+ }
+
+ for (i = ppd->num_groups, group = ppd->groups;
+ i > 0;
+ i --, group ++)
+ {
+ if (strcmp(group->text, "InstallableOptions") == 0)
+ cgiSetVariable("GROUP",
+ cupsLangString(language, CUPS_MSG_OPTIONS_INSTALLED));
+ else
+ cgiSetVariable("GROUP", group->text);
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "option-header.tmpl",
+ getenv("LANG"));
+
+ for (j = group->num_options, option = group->options;
+ j > 0;
+ j --, option ++)
+ {
+ if (strcmp(option->keyword, "PageRegion") == 0)
+ continue;
+
+ cgiSetVariable("KEYWORD", option->keyword);
+ cgiSetVariable("KEYTEXT", option->text);
+
+ if (option->conflicted)
+ cgiSetVariable("CONFLICTED", "1");
+ else
+ cgiSetVariable("CONFLICTED", "0");
+
+ cgiSetSize("CHOICES", option->num_choices);
+ cgiSetSize("TEXT", option->num_choices);
+ for (k = 0; k < option->num_choices; k ++)
+ {
+ cgiSetArray("CHOICES", k, option->choices[k].choice);
+ cgiSetArray("TEXT", k, option->choices[k].text);
+
+ if (option->choices[k].marked)
+ cgiSetVariable("DEFCHOICE", option->choices[k].choice);
+ }
+
+ switch (option->ui)
+ {
+ case PPD_UI_BOOLEAN :
+ cgiCopyTemplateLang(stdout, TEMPLATES, "option-boolean.tmpl",
+ getenv("LANG"));
+ break;
+ case PPD_UI_PICKONE :
+ cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl",
+ getenv("LANG"));
+ break;
+ case PPD_UI_PICKMANY :
+ cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickmany.tmpl",
+ getenv("LANG"));
+ break;
+ }
+ }
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "option-trailer.tmpl",
+ getenv("LANG"));
+ }
+
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
+ * following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
+ cgiGetVariable("PRINTER_NAME"));
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if ((attr = ippFindAttribute(response, "job-sheets-supported", IPP_TAG_ZERO)) != NULL)
+ {
+ /*
+ * Add the job sheets options...
+ */
+
+ cgiSetVariable("GROUP", "Banners");
+ cgiCopyTemplateLang(stdout, TEMPLATES, "option-header.tmpl",
+ getenv("LANG"));
+
+ cgiSetSize("CHOICES", attr->num_values);
+ cgiSetSize("TEXT", attr->num_values);
+ for (k = 0; k < attr->num_values; k ++)
+ {
+ cgiSetArray("CHOICES", k, attr->values[k].string.text);
+ cgiSetArray("TEXT", k, attr->values[k].string.text);
+ }
+
+ attr = ippFindAttribute(response, "job-sheets-default", IPP_TAG_ZERO);
+
+ cgiSetVariable("KEYWORD", "job_sheets_start");
+ cgiSetVariable("KEYTEXT", "Starting Banner");
+ cgiSetVariable("DEFCHOICE", attr == NULL ?
+ "" : attr->values[0].string.text);
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl",
+ getenv("LANG"));
+
+ cgiSetVariable("KEYWORD", "job_sheets_end");
+ cgiSetVariable("KEYTEXT", "Ending Banner");
+ cgiSetVariable("DEFCHOICE", attr == NULL && attr->num_values > 1 ?
+ "" : attr->values[1].string.text);
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl",
+ getenv("LANG"));
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "option-trailer.tmpl",
+ getenv("LANG"));
+ }
+
+ ippDelete(response);
+ }
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "config-printer2.tmpl",
+ getenv("LANG"));
+ }
+ else
+ {
+ /*
+ * Set default options...
+ */
+
+ outfd = cupsTempFd(tempfile, sizeof(tempfile));
+ in = fopen(filename, "rb");
+ out = fdopen(outfd, "wb");
+
+ if (outfd < 0 || in == NULL || out == NULL)
+ {
+ cgiSetVariable("ERROR", strerror(errno));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ unlink(filename);
+ return;
+ }
+
+ while (get_line(line, sizeof(line), in) != NULL)
+ {
+ if (strncmp(line, "*Default", 8) != 0)
+ fprintf(out, "%s\n", line);
+ else
+ {
+ /*
+ * Get default option name...
+ */
+
+ strlcpy(keyword, line + 8, sizeof(keyword));
+
+ for (keyptr = keyword; *keyptr; keyptr ++)
+ if (*keyptr == ':' || isspace(*keyptr))
+ break;
+
+ *keyptr = '\0';
+
+ if (strcmp(keyword, "PageRegion") == 0)
+ var = cgiGetVariable("PageSize");
+ else
+ var = cgiGetVariable(keyword);
+
+ if (var != NULL)
+ fprintf(out, "*Default%s: %s\n", keyword, var);
+ else
+ fprintf(out, "%s\n", line);
+ }
+ }
+
+ fclose(in);
+ fclose(out);
+ close(outfd);
+
+ /*
+ * Build a CUPS_ADD_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * job-sheets-default
+ * [ppd file]
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_ADD_PRINTER;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
+ cgiGetVariable("PRINTER_NAME"));
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "job-sheets-default", 2, NULL, NULL);
+ attr->values[0].string.text = strdup(cgiGetVariable("job_sheets_start"));
+ attr->values[1].string.text = strdup(cgiGetVariable("job_sheets_end"));
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoFileRequest(http, request, "/admin/", tempfile)) != NULL)
+ {
+ status = response->request.status.status_code;
+ ippDelete(response);
+ }
+ else
+ status = IPP_NOT_AUTHORIZED;
+
+ if (status > IPP_OK_CONFLICT)
+ {
+ cgiSetVariable("ERROR", ippErrorString(status));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ }
+ else
+ cgiCopyTemplateLang(stdout, TEMPLATES, "printer-configured.tmpl", getenv("LANG"));
+
+ unlink(tempfile);
+ }
+
+ unlink(filename);
+}
+
+
+/*
+ * 'do_delete_class()' - Delete a class...
+ */
+
+static void
+do_delete_class(http_t *http, /* I - HTTP connection */
+ cups_lang_t *language) /* I - Client's language */
+{
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ char uri[HTTP_MAX_URI]; /* Job URI */
+ const char *pclass; /* Printer class name */
+ ipp_status_t status; /* Operation status... */
+
+
+ if (cgiGetVariable("CONFIRM") == NULL)
+ {
+ cgiCopyTemplateLang(stdout, TEMPLATES, "class-confirm.tmpl", getenv("LANG"));
+ return;
+ }
+
+ if ((pclass = cgiGetVariable("PRINTER_NAME")) != NULL)
+ snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", pclass);
+ else
+ {
+ cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ return;
+ }
+
+ /*
+ * Build a CUPS_DELETE_CLASS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_DELETE_CLASS;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
+ {
+ status = response->request.status.status_code;
+
+ ippDelete(response);
+ }
+ else
+ status = IPP_GONE;
+
+ if (status > IPP_OK_CONFLICT)
+ {
+ cgiSetVariable("ERROR", ippErrorString(status));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ }
+ else
+ cgiCopyTemplateLang(stdout, TEMPLATES, "class-deleted.tmpl", getenv("LANG"));
+}
+
+
+/*
+ * 'do_delete_printer()' - Delete a printer...
+ */
+
+static void
+do_delete_printer(http_t *http, /* I - HTTP connection */
+ cups_lang_t *language)/* I - Client's language */
+{
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ char uri[HTTP_MAX_URI]; /* Job URI */
+ const char *printer; /* Printer printer name */
+ ipp_status_t status; /* Operation status... */
+
+
+ if (cgiGetVariable("CONFIRM") == NULL)
+ {
+ cgiCopyTemplateLang(stdout, TEMPLATES, "printer-confirm.tmpl", getenv("LANG"));
+ return;
+ }
+
+ if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+ else
+ {
+ cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ return;
+ }
+
+ /*
+ * Build a CUPS_DELETE_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_DELETE_PRINTER;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
+ {
+ status = response->request.status.status_code;
+
+ ippDelete(response);
+ }
+ else
+ status = IPP_GONE;
+
+ if (status > IPP_OK_CONFLICT)
+ {
+ cgiSetVariable("ERROR", ippErrorString(status));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ }
+ else
+ cgiCopyTemplateLang(stdout, TEMPLATES, "printer-deleted.tmpl", getenv("LANG"));
+}
+
+
+/*
+ * 'do_printer_op()' - Do a printer operation.
+ */
+
+static void
+do_printer_op(http_t *http, /* I - HTTP connection */
+ cups_lang_t *language, /* I - Client's language */
+ ipp_op_t op) /* I - Operation to perform */
+{
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ char uri[HTTP_MAX_URI]; /* Printer URI */
+ const char *printer; /* Printer name (purge-jobs) */
+ ipp_status_t status; /* Operation status... */
+
+
+ if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+ else
+ {
+ cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ return;
+ }
+
+ /*
+ * Build a printer request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = op;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
+ {
+ status = response->request.status.status_code;
+
+ ippDelete(response);
+ }
+ else
+ status = IPP_GONE;
+
+ if (status > IPP_OK_CONFLICT)
+ {
+ cgiSetVariable("ERROR", ippErrorString(status));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ }
+ else if (op == IPP_PAUSE_PRINTER)
+ cgiCopyTemplateLang(stdout, TEMPLATES, "printer-stop.tmpl", getenv("LANG"));
+ else if (op == IPP_RESUME_PRINTER)
+ cgiCopyTemplateLang(stdout, TEMPLATES, "printer-start.tmpl", getenv("LANG"));
+ else if (op == CUPS_ACCEPT_JOBS)
+ cgiCopyTemplateLang(stdout, TEMPLATES, "printer-accept.tmpl", getenv("LANG"));
+ else if (op == CUPS_REJECT_JOBS)
+ cgiCopyTemplateLang(stdout, TEMPLATES, "printer-reject.tmpl", getenv("LANG"));
+ else if (op == IPP_PURGE_JOBS)
+ cgiCopyTemplateLang(stdout, TEMPLATES, "printer-purge.tmpl", getenv("LANG"));
+}
+
+
+/*
+ * 'get_line()' - Get a line that is terminated by a LF, CR, or CR LF.
+ */
+
+static char * /* O - Pointer to buf or NULL on EOF */
+get_line(char *buf, /* I - Line buffer */
+ int length, /* I - Length of buffer */
+ FILE *fp) /* I - File to read from */
+{
+ char *bufptr; /* Pointer into buffer */
+ int ch; /* Character from file */
+
+
+ length --;
+ bufptr = buf;
+
+ while ((ch = getc(fp)) != EOF)
+ {
+ if (ch == '\n')
+ break;
+ else if (ch == '\r')
+ {
+ /*
+ * Look for LF...
+ */
+
+ ch = getc(fp);
+ if (ch != '\n' && ch != EOF)
+ ungetc(ch, fp);
+
+ break;
+ }
+
+ *bufptr++ = ch;
+ length --;
+ if (length == 0)
+ break;
+ }
+
+ *bufptr = '\0';
+
+ if (ch == EOF)
+ return (NULL);
+ else
+ return (buf);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cgi-bin/cgi.h b/cgi-bin/cgi.h
new file mode 100644
index 000000000..14c41f3df
--- /dev/null
+++ b/cgi-bin/cgi.h
@@ -0,0 +1,86 @@
+/*
+ * "$Id$"
+ *
+ * CGI support library definitions.
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CGI_H_
+# define _CGI_H_
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <time.h>
+
+# include <cups/string.h>
+
+# ifdef WIN32
+# include <direct.h>
+# include <io.h>
+# include <malloc.h>
+# else
+# include <unistd.h>
+# endif /* WIN32 */
+
+
+/*
+ * Prototypes...
+ */
+
+extern int cgiInitialize(void);
+extern void cgiAbort(const char *title, const char *stylesheet,
+ const char *format, ...);
+extern int cgiCheckVariables(const char *names);
+extern const char *cgiGetArray(const char *name, int element);
+extern int cgiGetSize(const char *name);
+extern void cgiSetSize(const char *name, int size);
+extern const char *cgiGetVariable(const char *name);
+extern void cgiSetArray(const char *name, int element,
+ const char *value);
+extern void cgiSetVariable(const char *name, const char *value);
+extern void cgiCopyTemplateFile(FILE *out, const char *tmpl);
+extern void cgiCopyTemplateLang(FILE *out, const char *directory,
+ const char *tmpl, const char *lang);
+
+extern void cgiStartHTML(FILE *out, const char *author,
+ const char *stylesheet,
+ const char *keywords,
+ const char *description,
+ const char *title, ...);
+extern void cgiEndHTML(FILE *out);
+
+extern FILE *cgiEMailOpen(const char *from, const char *to,
+ const char *cc, const char *subject,
+ int multipart);
+extern void cgiEMailPart(FILE *mail, const char *type,
+ const char *charset, const char *encoding);
+extern void cgiEMailClose(FILE *mail);
+
+extern char *cgiGetCookie(const char *name, char *buf, int buflen);
+extern void cgiSetCookie(const char *name, const char *value,
+ const char *path, const char *domain,
+ time_t expires, int secure);
+
+# define cgiGetUser() getenv("REMOTE_USER")
+# define cgiGetHost() (getenv("REMOTE_HOST") == NULL ? getenv("REMOTE_ADDR") : getenv("REMOTE_HOST"))
+
+#endif /* !_CGI_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cgi-bin/classes.c b/cgi-bin/classes.c
new file mode 100644
index 000000000..16a17b18c
--- /dev/null
+++ b/cgi-bin/classes.c
@@ -0,0 +1,360 @@
+/*
+ * "$Id$"
+ *
+ * Class status CGI for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Main entry for CGI.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "ipp-var.h"
+
+
+/*
+ * 'main()' - Main entry for CGI.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ cups_lang_t *language; /* Language information */
+ char *pclass; /* Printer class name */
+ http_t *http; /* Connection to the server */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ ipp_attribute_t *attr; /* IPP attribute */
+ ipp_status_t status; /* Operation status... */
+ char uri[HTTP_MAX_URI];
+ /* Printer URI */
+ const char *which_jobs; /* Which jobs to show */
+ const char *op; /* Operation to perform, if any */
+
+
+ /*
+ * Get any form variables...
+ */
+
+ cgiInitialize();
+ op = cgiGetVariable("OP");
+
+ /*
+ * Get the request language...
+ */
+
+ language = cupsLangDefault();
+
+ /*
+ * Connect to the HTTP server...
+ */
+
+ http = httpConnectEncrypt("localhost", ippPort(), cupsEncryption());
+
+ /*
+ * Tell the client to expect HTML...
+ */
+
+ printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language));
+
+ /*
+ * See if we need to show a list of printers or the status of a
+ * single printer...
+ */
+
+ ippSetServerVersion();
+
+ pclass = argv[0];
+ if (strcmp(pclass, "/") == 0 || strcmp(pclass, "classes.cgi") == 0)
+ {
+ pclass = NULL;
+ cgiSetVariable("TITLE", cupsLangString(language, CUPS_MSG_CLASS));
+ }
+ else
+ cgiSetVariable("TITLE", pclass);
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "header.tmpl", getenv("LANG"));
+
+ if (op == NULL || strcasecmp(op, "print-test-page") != 0)
+ {
+ /*
+ * Get the default destination...
+ */
+
+ request = ippNew();
+ request->request.op.operation_id = CUPS_GET_DEFAULT;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
+ cgiSetVariable("DEFAULT_NAME", attr->values[0].string.text);
+
+ if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
+ {
+ char method[HTTP_MAX_URI],
+ username[HTTP_MAX_URI],
+ hostname[HTTP_MAX_URI],
+ resource[HTTP_MAX_URI],
+ uri[HTTP_MAX_URI];
+ int port; /* URI data */
+ const char *server; /* Name of server */
+
+
+ /*
+ * Map localhost access to localhost...
+ */
+
+ server = getenv("SERVER_NAME");
+
+ httpSeparate(attr->values[0].string.text, method, username,
+ hostname, &port, resource);
+
+ if (strcasecmp(hostname, server) == 0 &&
+ (strcmp(getenv("REMOTE_HOST"), "127.0.0.1") == 0 ||
+ strcmp(getenv("REMOTE_HOST"), "localhost") == 0 ||
+ strcmp(getenv("REMOTE_HOST"), server) == 0))
+ strcpy(hostname, "localhost");
+
+ /*
+ * Rewrite URI with HTTP address...
+ */
+
+ snprintf(uri, sizeof(uri), "http://%s:%d%s", hostname, port,
+ resource);
+
+ cgiSetVariable("DEFAULT_URI", uri);
+ }
+
+ ippDelete(response);
+ }
+
+ /*
+ * Get the class info...
+ */
+
+ request = ippNew();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ if (pclass == NULL)
+ {
+ /*
+ * Build a CUPS_GET_CLASSES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ */
+
+ request->request.op.operation_id = CUPS_GET_CLASSES;
+ request->request.op.request_id = 1;
+ }
+ else
+ {
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ snprintf(uri, sizeof(uri), "ipp://%s/classes/%s", getenv("SERVER_NAME"),
+ pclass);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+ uri);
+ }
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ ippSetCGIVars(response, NULL, NULL);
+ ippDelete(response);
+ }
+
+ /*
+ * Write the report...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "classes.tmpl", getenv("LANG"));
+
+ /*
+ * Get jobs for the specified class if a class has been chosen...
+ */
+
+ if (pclass != NULL)
+ {
+ /*
+ * Build an IPP_GET_JOBS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ request->request.op.operation_id = IPP_GET_JOBS;
+ request->request.op.request_id = 1;
+
+ snprintf(uri, sizeof(uri), "ipp://%s/classes/%s", getenv("SERVER_NAME"),
+ pclass);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+ uri);
+
+ if ((which_jobs = cgiGetVariable("which_jobs")) != NULL)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs",
+ NULL, which_jobs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ ippSetCGIVars(response, NULL, NULL);
+ ippDelete(response);
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "jobs.tmpl", getenv("LANG"));
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Print a test page...
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", pclass);
+
+ /*
+ * Build an IPP_PRINT_JOB request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * requesting-user-name
+ * document-format
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_PRINT_JOB;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ if (getenv("REMOTE_USER") != NULL)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, getenv("REMOTE_USER"));
+ else
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, "root");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
+ NULL, "Test Page");
+
+ ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
+ NULL, "application/postscript");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoFileRequest(http, request, uri + 15,
+ CUPS_DATADIR "/data/testprint.ps")) != NULL)
+ {
+ status = response->request.status.status_code;
+ ippSetCGIVars(response, NULL, NULL);
+
+ ippDelete(response);
+ }
+ else
+ status = IPP_GONE;
+
+ cgiSetVariable("PRINTER_NAME", pclass);
+
+ if (status > IPP_OK_CONFLICT)
+ {
+ cgiSetVariable("ERROR", ippErrorString(status));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ }
+ else
+ cgiCopyTemplateLang(stdout, TEMPLATES, "test-page.tmpl", getenv("LANG"));
+ }
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "trailer.tmpl", getenv("LANG"));
+
+ /*
+ * Close the HTTP server connection...
+ */
+
+ httpClose(http);
+ cupsLangFree(language);
+
+ /*
+ * Return with no errors...
+ */
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cgi-bin/html.c b/cgi-bin/html.c
new file mode 100644
index 000000000..ac2291ee4
--- /dev/null
+++ b/cgi-bin/html.c
@@ -0,0 +1,89 @@
+/*
+ * "$Id$"
+ *
+ * CGI HTML functions.
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contents:
+ *
+ * cgiStartHTML() - Start an HTML document stream.
+ * cgiEndHTML() - End an HTML document stream.
+ */
+
+#include "cgi.h"
+#include <stdarg.h>
+
+
+/*
+ * 'cgiStartHTML()' - Start an HTML document stream.
+ */
+
+void
+cgiStartHTML(FILE *out, /* I - Output file to use */
+ const char *stylesheet, /* I - Stylesheet to use */
+ const char *author, /* I - Author name */
+ const char *keywords, /* I - Search keywords */
+ const char *description, /* I - Description of document */
+ const char *title, /* I - Title for page */
+ ...) /* I - Any addition args for title */
+{
+ va_list ap; /* Argument pointer */
+
+
+ fputs("Content-type: text/html\n\n", out);
+ fputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" "
+ "\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n", out);
+ fputs("<HTML>\n", out);
+ fputs("<HEAD>\n", out);
+
+ fputs("\t<TITLE>\n", out);
+ va_start(ap, title);
+ vfprintf(out, title, ap);
+ va_end(ap);
+ fputs("</TITLE>\n", out);
+
+ if (stylesheet)
+ fprintf(out, "\t<LINK REL=\"STYLESHEET\" TYPE=\"text/css\" HREF=\"%s\">\n",
+ stylesheet);
+ if (author)
+ fprintf(out, "\t<META NAME=\"AUTHOR\" CONTENT=\"%s\">\n", author);
+ if (keywords)
+ fprintf(out, "\t<META NAME=\"KEYWORDS\" CONTENT=\"%s\">\n", keywords);
+ if (description)
+ fprintf(out, "\t<META NAME=\"DESCRIPTION\" CONTENT=\"%s\">\n", description);
+
+ fputs("</HEAD>\n", out);
+ fputs("<BODY>\n", out);
+}
+
+
+/*
+ * 'cgiEndHTML()' - End an HTML document stream.
+ */
+
+void
+cgiEndHTML(FILE *out) /* I - Output file to use */
+{
+ fputs("</BODY>\n", out);
+ fputs("</HTML>\n", out);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c
new file mode 100644
index 000000000..122500fd0
--- /dev/null
+++ b/cgi-bin/ipp-var.c
@@ -0,0 +1,300 @@
+/*
+ * "$Id$"
+ *
+ * IPP variable routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * ippGetTemplateDir() - Get the templates directory...
+ * ippSetServerVersion() - Set the server name and CUPS version...
+ * ippSetCGIVars() - Set CGI variables from an IPP response.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "ipp-var.h"
+
+
+/*
+ * 'ippGetTemplateDir()' - Get the templates directory...
+ */
+
+char * /* O - Template directory */
+ippGetTemplateDir(void)
+{
+ const char *datadir; /* CUPS_DATADIR env var */
+ static char templates[1024] = ""; /* Template directory */
+
+
+ if (!templates[0])
+ {
+ /*
+ * Build the template directory pathname...
+ */
+
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+ datadir = CUPS_DATADIR;
+
+ snprintf(templates, sizeof(templates), "%s/templates", datadir);
+ }
+
+ return (templates);
+}
+
+
+/*
+ * 'ippSetServerVersion()' - Set the server name and CUPS version...
+ */
+
+void
+ippSetServerVersion(void)
+{
+ cgiSetVariable("SERVER_NAME", getenv("SERVER_NAME"));
+ cgiSetVariable("REMOTE_USER", getenv("REMOTE_USER"));
+ cgiSetVariable("CUPS_VERSION", CUPS_SVERSION);
+}
+
+
+/*
+ * 'ippSetCGIVars()' - Set CGI variables from an IPP response.
+ */
+
+void
+ippSetCGIVars(ipp_t *response, /* I - Response data to be copied... */
+ const char *filter_name, /* I - Filter name */
+ const char *filter_value) /* I - Filter value */
+{
+ int element; /* Element in CGI array */
+ ipp_attribute_t *attr, /* Attribute in response... */
+ *filter; /* Filtering attribute */
+ int i; /* Looping var */
+ char name[1024], /* Name of attribute */
+ value[16384], /* Value(s) */
+ *valptr; /* Pointer into value */
+ char method[HTTP_MAX_URI],
+ username[HTTP_MAX_URI],
+ hostname[HTTP_MAX_URI],
+ resource[HTTP_MAX_URI],
+ uri[HTTP_MAX_URI];
+ int port; /* URI data */
+ int ishttps; /* Using encryption? */
+ const char *server; /* Name of server */
+ struct tm *date; /* Date information */
+
+
+ ippSetServerVersion();
+
+ server = getenv("SERVER_NAME");
+ ishttps = getenv("HTTPS") != NULL;
+
+ for (attr = response->attrs;
+ attr && attr->group_tag == IPP_TAG_OPERATION;
+ attr = attr->next);
+
+ for (element = 0; attr != NULL; attr = attr->next, element ++)
+ {
+ /*
+ * Copy attributes to a separator...
+ */
+
+ if (filter_name)
+ {
+ for (filter = attr;
+ filter != NULL && filter->group_tag != IPP_TAG_ZERO;
+ filter = filter->next)
+ if (filter->name && strcmp(filter->name, filter_name) == 0 &&
+ (filter->value_tag == IPP_TAG_STRING ||
+ (filter->value_tag >= IPP_TAG_TEXTLANG &&
+ filter->value_tag <= IPP_TAG_MIMETYPE)) &&
+ filter->values[0].string.text != NULL &&
+ strcasecmp(filter->values[0].string.text, filter_value) == 0)
+ break;
+
+ if (!filter)
+ return;
+
+ if (filter->group_tag == IPP_TAG_ZERO)
+ {
+ attr = filter;
+ element --;
+ continue;
+ }
+ }
+
+ for (; attr != NULL && attr->group_tag != IPP_TAG_ZERO; attr = attr->next)
+ {
+ /*
+ * Copy the attribute name, substituting "_" for "-"...
+ */
+
+ if (attr->name == NULL)
+ continue;
+
+ for (i = 0; attr->name[i]; i ++)
+ if (attr->name[i] == '-')
+ name[i] = '_';
+ else
+ name[i] = attr->name[i];
+
+ name[i] = '\0';
+
+ /*
+ * Add "job_printer_name" variable if we have a "job_printer_uri"
+ * attribute...
+ */
+
+ if (strcmp(name, "job_printer_uri") == 0)
+ {
+ if ((valptr = strrchr(attr->values[0].string.text, '/')) == NULL)
+ valptr = "unknown";
+ else
+ valptr ++;
+
+ cgiSetArray("job_printer_name", element, valptr);
+ }
+
+ /*
+ * Copy values...
+ */
+
+ value[0] = '\0'; /* Initially an empty string */
+ valptr = value; /* Start at the beginning */
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if (i)
+ strlcat(valptr, ",", sizeof(value) - (valptr - value));
+
+ valptr += strlen(valptr);
+
+ switch (attr->value_tag)
+ {
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ if (strncmp(name, "time_at_", 8) == 0)
+ {
+ date = localtime((time_t *)&(attr->values[i].integer));
+ strftime(valptr, sizeof(value) - (valptr - value),
+ CUPS_STRFTIME_FORMAT, date);
+ }
+ else
+ snprintf(valptr, sizeof(value) - (valptr - value),
+ "%d", attr->values[i].integer);
+ break;
+
+ case IPP_TAG_BOOLEAN :
+ snprintf(valptr, sizeof(value) - (valptr - value),
+ "%d", attr->values[i].boolean);
+ break;
+
+ case IPP_TAG_NOVALUE :
+ strlcat(valptr, "novalue", sizeof(value) - (valptr - value));
+ break;
+
+ case IPP_TAG_RANGE :
+ snprintf(valptr, sizeof(value) - (valptr - value),
+ "%d-%d", attr->values[i].range.lower,
+ attr->values[i].range.upper);
+ break;
+
+ case IPP_TAG_RESOLUTION :
+ snprintf(valptr, sizeof(value) - (valptr - value),
+ "%dx%d%s", attr->values[i].resolution.xres,
+ attr->values[i].resolution.yres,
+ attr->values[i].resolution.units == IPP_RES_PER_INCH ?
+ "dpi" : "dpc");
+ break;
+
+ case IPP_TAG_URI :
+ if (strchr(attr->values[i].string.text, ':') != NULL)
+ {
+ httpSeparate(attr->values[i].string.text, method, username,
+ hostname, &port, resource);
+
+ if (strcmp(method, "ipp") == 0 ||
+ strcmp(method, "http") == 0)
+ {
+ /*
+ * Map localhost access to localhost and local port...
+ */
+
+ if (strcasecmp(hostname, server) == 0)
+ {
+ /*
+ * Make URI relative to the current server...
+ */
+
+ strlcpy(uri, resource, sizeof(uri));
+ }
+ else
+ {
+ /*
+ * Rewrite URI with HTTP address...
+ */
+
+ if (username[0])
+ snprintf(uri, sizeof(uri), "%s://%s@%s:%d%s",
+ ishttps ? "https" : "http",
+ username, hostname, port, resource);
+ else
+ snprintf(uri, sizeof(uri), "%s://%s:%d%s",
+ ishttps ? "https" : "http",
+ hostname, port, resource);
+ }
+
+ strlcat(valptr, uri, sizeof(value) - (valptr - value));
+ break;
+ }
+ }
+
+ case IPP_TAG_STRING :
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ strlcat(valptr, attr->values[i].string.text,
+ sizeof(value) - (valptr - value));
+ break;
+
+ default :
+ break; /* anti-compiler-warning-code */
+ }
+ }
+
+ /*
+ * Add the element...
+ */
+
+ cgiSetArray(name, element, value);
+ }
+
+ if (attr == NULL)
+ break;
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cgi-bin/ipp-var.h b/cgi-bin/ipp-var.h
new file mode 100644
index 000000000..0ce4163a9
--- /dev/null
+++ b/cgi-bin/ipp-var.h
@@ -0,0 +1,55 @@
+/*
+ * "$Id$"
+ *
+ * IPP variable definitions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <ctype.h>
+#include <cups/cups.h>
+#include <cups/debug.h>
+#include <cups/language.h>
+#include <cups/string.h>
+#include "cgi.h"
+
+
+/*
+ * Definitions...
+ */
+
+#define TEMPLATES ippGetTemplateDir()
+
+
+/*
+ * Prototype...
+ */
+
+extern char *ippGetTemplateDir(void);
+extern void ippSetServerVersion(void);
+extern void ippSetCGIVars(ipp_t *, const char *, const char *);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cgi-bin/jobs.c b/cgi-bin/jobs.c
new file mode 100644
index 000000000..b368d5640
--- /dev/null
+++ b/cgi-bin/jobs.c
@@ -0,0 +1,260 @@
+/*
+ * "$Id$"
+ *
+ * Job status CGI for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Main entry for CGI.
+ * do_job_op() - Do a job operation.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "ipp-var.h"
+
+
+/*
+ * Local functions...
+ */
+
+static void do_job_op(http_t *http, cups_lang_t *language, ipp_op_t op);
+
+
+/*
+ * 'main()' - Main entry for CGI.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ cups_lang_t *language; /* Language information */
+ http_t *http; /* Connection to the server */
+ const char *which_jobs; /* Which jobs to show */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ const char *op; /* Operation name */
+
+
+ /*
+ * Get any form variables...
+ */
+
+ cgiInitialize();
+
+ /*
+ * Get the request language...
+ */
+
+ language = cupsLangDefault();
+
+ /*
+ * Connect to the HTTP server...
+ */
+
+ http = httpConnectEncrypt("localhost", ippPort(), cupsEncryption());
+
+ /*
+ * Tell the client to expect HTML...
+ */
+
+ printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language));
+
+ cgiSetVariable("TITLE", "Jobs");
+
+ ippSetServerVersion();
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "header.tmpl", getenv("LANG"));
+
+ if ((op = cgiGetVariable("OP")) != NULL)
+ {
+ /*
+ * Do the operation...
+ */
+
+ if (strcmp(op, "cancel-job") == 0)
+ do_job_op(http, language, IPP_CANCEL_JOB);
+ else if (strcmp(op, "hold-job") == 0)
+ do_job_op(http, language, IPP_HOLD_JOB);
+ else if (strcmp(op, "release-job") == 0)
+ do_job_op(http, language, IPP_RELEASE_JOB);
+ else if (strcmp(op, "restart-job") == 0)
+ do_job_op(http, language, IPP_RESTART_JOB);
+ else
+ {
+ /*
+ * Bad operation code... Display an error...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "job-op.tmpl", getenv("LANG"));
+ }
+ }
+ else
+ {
+ /*
+ * Build an IPP_GET_JOBS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ request->request.op.operation_id = IPP_GET_JOBS;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
+ "ipp://localhost/jobs");
+
+ if ((which_jobs = cgiGetVariable("which_jobs")) != NULL)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs",
+ NULL, which_jobs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ ippSetCGIVars(response, NULL, NULL);
+ ippDelete(response);
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "jobs.tmpl", getenv("LANG"));
+ }
+ }
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "trailer.tmpl", getenv("LANG"));
+
+ /*
+ * Close the HTTP server connection...
+ */
+
+ httpClose(http);
+ cupsLangFree(language);
+
+ /*
+ * Return with no errors...
+ */
+
+ return (0);
+}
+
+
+/*
+ * 'do_job_op()' - Do a job operation.
+ */
+
+static void
+do_job_op(http_t *http, /* I - HTTP connection */
+ cups_lang_t *language, /* I - Client's language */
+ ipp_op_t op) /* I - Operation to perform */
+{
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ char uri[HTTP_MAX_URI]; /* Job URI */
+ const char *job; /* Job ID */
+ const char *printer; /* Printer name (purge-jobs) */
+ ipp_status_t status; /* Operation status... */
+
+
+ if ((job = cgiGetVariable("JOB_ID")) != NULL)
+ snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%s", job);
+ else
+ {
+ cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ return;
+ }
+
+ /*
+ * Build a job request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * job-uri or printer-uri (purge-jobs)
+ * requesting-user-name
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = op;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
+ NULL, uri);
+
+ if (getenv("REMOTE_USER") != NULL)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, getenv("REMOTE_USER"));
+ else
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, "unknown");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
+ {
+ status = response->request.status.status_code;
+
+ ippDelete(response);
+ }
+ else
+ status = IPP_GONE;
+
+ if (status > IPP_OK_CONFLICT)
+ {
+ cgiSetVariable("ERROR", ippErrorString(status));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ }
+ else if (op == IPP_CANCEL_JOB)
+ cgiCopyTemplateLang(stdout, TEMPLATES, "job-cancel.tmpl", getenv("LANG"));
+ else if (op == IPP_HOLD_JOB)
+ cgiCopyTemplateLang(stdout, TEMPLATES, "job-hold.tmpl", getenv("LANG"));
+ else if (op == IPP_RELEASE_JOB)
+ cgiCopyTemplateLang(stdout, TEMPLATES, "job-release.tmpl", getenv("LANG"));
+ else if (op == IPP_RESTART_JOB)
+ cgiCopyTemplateLang(stdout, TEMPLATES, "job-restart.tmpl", getenv("LANG"));
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cgi-bin/printers.c b/cgi-bin/printers.c
new file mode 100644
index 000000000..1bdaad10a
--- /dev/null
+++ b/cgi-bin/printers.c
@@ -0,0 +1,360 @@
+/*
+ * "$Id$"
+ *
+ * Printer status CGI for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Main entry for CGI.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "ipp-var.h"
+
+
+/*
+ * 'main()' - Main entry for CGI.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ cups_lang_t *language; /* Language information */
+ char *printer; /* Printer name */
+ http_t *http; /* Connection to the server */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ ipp_attribute_t *attr; /* IPP attribute */
+ ipp_status_t status; /* Operation status... */
+ char uri[HTTP_MAX_URI];
+ /* Printer URI */
+ const char *which_jobs; /* Which jobs to show */
+ const char *op; /* Operation to perform, if any */
+
+
+ /*
+ * Get any form variables...
+ */
+
+ cgiInitialize();
+ op = cgiGetVariable("OP");
+
+ /*
+ * Get the request language...
+ */
+
+ language = cupsLangDefault();
+
+ /*
+ * Connect to the HTTP server...
+ */
+
+ http = httpConnectEncrypt("localhost", ippPort(), cupsEncryption());
+
+ /*
+ * Tell the client to expect HTML...
+ */
+
+ printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language));
+
+ /*
+ * See if we need to show a list of printers or the status of a
+ * single printer...
+ */
+
+ ippSetServerVersion();
+
+ printer = argv[0];
+ if (strcmp(printer, "/") == 0 || strstr(printer, "printers.cgi") != NULL)
+ {
+ printer = NULL;
+ cgiSetVariable("TITLE", cupsLangString(language, CUPS_MSG_PRINTER));
+ }
+ else
+ cgiSetVariable("TITLE", printer);
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "header.tmpl", getenv("LANG"));
+
+ if (op == NULL || strcasecmp(op, "print-test-page") != 0)
+ {
+ /*
+ * Get the default destination...
+ */
+
+ request = ippNew();
+ request->request.op.operation_id = CUPS_GET_DEFAULT;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
+ cgiSetVariable("DEFAULT_NAME", attr->values[0].string.text);
+
+ if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
+ {
+ char method[HTTP_MAX_URI],
+ username[HTTP_MAX_URI],
+ hostname[HTTP_MAX_URI],
+ resource[HTTP_MAX_URI],
+ uri[HTTP_MAX_URI];
+ int port; /* URI data */
+ const char *server; /* Name of server */
+
+
+ /*
+ * Map localhost access to localhost...
+ */
+
+ server = getenv("SERVER_NAME");
+
+ httpSeparate(attr->values[0].string.text, method, username,
+ hostname, &port, resource);
+
+ if (strcasecmp(hostname, server) == 0 &&
+ (strcmp(getenv("REMOTE_HOST"), "127.0.0.1") == 0 ||
+ strcmp(getenv("REMOTE_HOST"), "localhost") == 0 ||
+ strcmp(getenv("REMOTE_HOST"), server) == 0))
+ strcpy(hostname, "localhost");
+
+ /*
+ * Rewrite URI with HTTP address...
+ */
+
+ snprintf(uri, sizeof(uri), "http://%s:%d%s", hostname, port,
+ resource);
+
+ cgiSetVariable("DEFAULT_URI", uri);
+ }
+
+ ippDelete(response);
+ }
+
+ /*
+ * Get the printer info...
+ */
+
+ request = ippNew();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ if (printer == NULL)
+ {
+ /*
+ * Build a CUPS_GET_PRINTERS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ */
+
+ request->request.op.operation_id = CUPS_GET_PRINTERS;
+ request->request.op.request_id = 1;
+ }
+ else
+ {
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ snprintf(uri, sizeof(uri), "ipp://%s/printers/%s", getenv("SERVER_NAME"),
+ printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+ uri);
+ }
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ ippSetCGIVars(response, NULL, NULL);
+ ippDelete(response);
+ }
+
+ /*
+ * Write the report...
+ */
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "printers.tmpl", getenv("LANG"));
+
+ /*
+ * Get jobs for the specified printer if a printer has been chosen...
+ */
+
+ if (printer != NULL)
+ {
+ /*
+ * Build an IPP_GET_JOBS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ request->request.op.operation_id = IPP_GET_JOBS;
+ request->request.op.request_id = 1;
+
+ snprintf(uri, sizeof(uri), "ipp://%s/printers/%s", getenv("SERVER_NAME"),
+ printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+ uri);
+
+ if ((which_jobs = cgiGetVariable("which_jobs")) != NULL)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs",
+ NULL, which_jobs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ ippSetCGIVars(response, NULL, NULL);
+ ippDelete(response);
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "jobs.tmpl", getenv("LANG"));
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Print a test page...
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+
+ /*
+ * Build an IPP_PRINT_JOB request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * requesting-user-name
+ * document-format
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_PRINT_JOB;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ if (getenv("REMOTE_USER") != NULL)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, getenv("REMOTE_USER"));
+ else
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, "root");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
+ NULL, "Test Page");
+
+ ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
+ NULL, "application/postscript");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoFileRequest(http, request, uri + 15,
+ CUPS_DATADIR "/data/testprint.ps")) != NULL)
+ {
+ status = response->request.status.status_code;
+ ippSetCGIVars(response, NULL, NULL);
+
+ ippDelete(response);
+ }
+ else
+ status = IPP_GONE;
+
+ cgiSetVariable("PRINTER_NAME", printer);
+
+ if (status > IPP_OK_CONFLICT)
+ {
+ cgiSetVariable("ERROR", ippErrorString(status));
+ cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
+ }
+ else
+ cgiCopyTemplateLang(stdout, TEMPLATES, "test-page.tmpl", getenv("LANG"));
+ }
+
+ cgiCopyTemplateLang(stdout, TEMPLATES, "trailer.tmpl", getenv("LANG"));
+
+ /*
+ * Close the HTTP server connection...
+ */
+
+ httpClose(http);
+ cupsLangFree(language);
+
+ /*
+ * Return with no errors...
+ */
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cgi-bin/template.c b/cgi-bin/template.c
new file mode 100644
index 000000000..598cc5235
--- /dev/null
+++ b/cgi-bin/template.c
@@ -0,0 +1,492 @@
+/*
+ * "$Id$"
+ *
+ * CGI template function.
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contents:
+ *
+ * cgiCopyTemplateFile() - Copy a template file and replace all the
+ * '{variable}' strings with the variable value.
+ * cgiCopyTemplateLang() - Copy a template file using a language...
+ * cgi_copy() - Copy the template file, substituting as needed...
+ * cgi_puts() - Put a string to the output file, quoting as
+ * needed...
+ */
+
+#include "cgi.h"
+
+
+/*
+ * Local functions...
+ */
+
+static void cgi_copy(FILE *out, FILE *in, int element, char term);
+static void cgi_puts(const char *s, FILE *out);
+
+
+/*
+ * 'cgiCopyTemplateFile()' - Copy a template file and replace all the
+ * '{variable}' strings with the variable value.
+ */
+
+void
+cgiCopyTemplateFile(FILE *out, /* I - Output file */
+ const char *tmpl) /* I - Template file to read */
+{
+ FILE *in; /* Input file */
+
+
+ /*
+ * Open the template file...
+ */
+
+ if ((in = fopen(tmpl, "r")) == NULL)
+ return;
+
+ /*
+ * Parse the file to the end...
+ */
+
+ cgi_copy(out, in, 0, 0);
+
+ /*
+ * Close the template file and return...
+ */
+
+ fclose(in);
+}
+
+
+/*
+ * 'cgiCopyTemplateLang()' - Copy a template file using a language...
+ */
+
+void
+cgiCopyTemplateLang(FILE *out, /* I - Output file */
+ const char *directory, /* I - Directory */
+ const char *tmpl, /* I - Base filename */
+ const char *lang) /* I - Language */
+{
+ int i; /* Looping var */
+ char filename[1024], /* Filename */
+ locale[16]; /* Locale name */
+ FILE *in; /* Input file */
+
+
+ /*
+ * Convert the language to a locale name...
+ */
+
+ if (lang != NULL)
+ {
+ for (i = 0; lang[i] && i < 15; i ++)
+ if (isalnum(lang[i]))
+ locale[i] = tolower(lang[i]);
+ else
+ locale[i] = '_';
+
+ locale[i] = '\0';
+ }
+ else
+ locale[0] = '\0';
+
+ /*
+ * See if we have a template file for this language...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl);
+ if (access(filename, 0))
+ {
+ locale[2] = '\0';
+
+ snprintf(filename, sizeof(filename), "%s/%s/%s", directory, locale, tmpl);
+ if (access(filename, 0))
+ snprintf(filename, sizeof(filename), "%s/%s", directory, tmpl);
+ }
+
+ /*
+ * Open the template file...
+ */
+
+ if ((in = fopen(filename, "r")) == NULL)
+ return;
+
+ /*
+ * Parse the file to the end...
+ */
+
+ cgi_copy(out, in, 0, 0);
+
+ /*
+ * Close the template file and return...
+ */
+
+ fclose(in);
+}
+
+
+/*
+ * 'cgi_copy()' - Copy the template file, substituting as needed...
+ */
+
+static void
+cgi_copy(FILE *out, /* I - Output file */
+ FILE *in, /* I - Input file */
+ int element, /* I - Element number (0 to N) */
+ char term) /* I - Terminating character */
+{
+ int ch; /* Character from file */
+ char op; /* Operation */
+ char name[255], /* Name of variable */
+ *nameptr, /* Pointer into name */
+ innername[255], /* Inner comparison name */
+ *innerptr, /* Pointer into inner name */
+ *s; /* String pointer */
+ const char *value; /* Value of variable */
+ const char *innerval; /* Inner value */
+ const char *outptr; /* Output string pointer */
+ char outval[1024], /* Formatted output string */
+ compare[1024]; /* Comparison string */
+ int result; /* Result of comparison */
+
+
+ /*
+ * Parse the file to the end...
+ */
+
+ while ((ch = getc(in)) != EOF)
+ if (ch == term)
+ break;
+ else if (ch == '{')
+ {
+ /*
+ * Get a variable name...
+ */
+
+ for (s = name; (ch = getc(in)) != EOF;)
+ if (strchr("}]<>=! \t\n", ch))
+ break;
+ else if (s > name && ch == '?')
+ break;
+ else if (s < (name + sizeof(name) - 1))
+ *s++ = ch;
+
+ *s = '\0';
+
+ if (s == name && isspace(ch))
+ {
+ if (out)
+ {
+ putc('{', out);
+ putc(ch, out);
+ }
+
+ continue;
+ }
+
+ /*
+ * See if it has a value...
+ */
+
+ if (name[0] == '?')
+ {
+ /*
+ * Insert value only if it exists...
+ */
+
+ if ((nameptr = strrchr(name, '-')) != NULL && isdigit(nameptr[1]))
+ {
+ *nameptr++ = '\0';
+
+ if ((value = cgiGetArray(name + 1, atoi(nameptr) - 1)) != NULL)
+ outptr = value;
+ else
+ {
+ outval[0] = '\0';
+ outptr = outval;
+ }
+ }
+ if ((value = cgiGetArray(name + 1, element)) != NULL)
+ outptr = value;
+ else
+ {
+ outval[0] = '\0';
+ outptr = outval;
+ }
+ }
+ else if (name[0] == '#')
+ {
+ /*
+ * Insert count...
+ */
+
+ if (name[1])
+ sprintf(outval, "%d", cgiGetSize(name + 1));
+ else
+ sprintf(outval, "%d", element + 1);
+
+ outptr = outval;
+ }
+ else if (name[0] == '[')
+ {
+ /*
+ * Loop for # of elements...
+ */
+
+ int i; /* Looping var */
+ long pos; /* File position */
+ int count; /* Number of elements */
+
+
+ if (isdigit(name[1]))
+ count = atoi(name + 1);
+ else
+ count = cgiGetSize(name + 1);
+
+ pos = ftell(in);
+
+ if (count > 0)
+ {
+ for (i = 0; i < count; i ++)
+ {
+ fseek(in, pos, SEEK_SET);
+ cgi_copy(out, in, i, '}');
+ }
+ }
+ else
+ cgi_copy(NULL, in, 0, '}');
+
+ continue;
+ }
+ else
+ {
+ /*
+ * Insert variable or variable name (if element is NULL)...
+ */
+
+ if ((nameptr = strrchr(name, '-')) != NULL && isdigit(nameptr[1]))
+ {
+ *nameptr++ = '\0';
+ if ((value = cgiGetArray(name, atoi(nameptr) - 1)) == NULL)
+ {
+ snprintf(outval, sizeof(outval), "{%s}", name);
+ outptr = outval;
+ }
+ else
+ outptr = value;
+ }
+ else if ((value = cgiGetArray(name, element)) == NULL)
+ {
+ snprintf(outval, sizeof(outval), "{%s}", name);
+ outptr = outval;
+ }
+ else
+ outptr = value;
+ }
+
+ /*
+ * See if the terminating character requires another test...
+ */
+
+ if (ch == '}')
+ {
+ /*
+ * End of substitution...
+ */
+
+ if (out)
+ cgi_puts(outptr, out);
+
+ continue;
+ }
+
+ /*
+ * OK, process one of the following checks:
+ *
+ * {name?exist:not-exist} Exists?
+ * {name=value?true:false} Equal
+ * {name<value?true:false} Less than
+ * {name>value?true:false} Greater than
+ * {name!value?true:false} Not equal
+ */
+
+ if (ch == '?')
+ {
+ /*
+ * Test for existance...
+ */
+
+ result = cgiGetArray(name, element) != NULL && outval[0];
+ }
+ else
+ {
+ /*
+ * Compare to a string...
+ */
+
+ op = ch;
+
+ for (s = compare; (ch = getc(in)) != EOF;)
+ if (ch == '?')
+ break;
+ else if (s >= (compare + sizeof(compare) - 1))
+ continue;
+ else if (ch == '#')
+ {
+ sprintf(s, "%d", element + 1);
+ s += strlen(s);
+ }
+ else if (ch == '{')
+ {
+ /*
+ * Grab the value of a variable...
+ */
+
+ innerptr = innername;
+ while ((ch = getc(in)) != EOF && ch != '}')
+ if (innerptr < (innername + sizeof(innername) - 1))
+ *innerptr++ = ch;
+ *innerptr = '\0';
+
+ if (innername[0] == '#')
+ sprintf(s, "%d", cgiGetSize(innername + 1));
+ else if ((innerptr = strrchr(innername, '-')) != NULL &&
+ isdigit(innerptr[1]))
+ {
+ *innerptr++ = '\0';
+ if ((innerval = cgiGetArray(innername, atoi(innerptr) - 1)) == NULL)
+ *s = '\0';
+ else
+ strlcpy(s, innerval, sizeof(compare) - (s - compare));
+ }
+ else if (innername[0] == '?')
+ {
+ if ((innerval = cgiGetArray(innername + 1, element)) == NULL)
+ *s = '\0';
+ else
+ strlcpy(s, innerval, sizeof(compare) - (s - compare));
+ }
+ else if ((innerval = cgiGetArray(innername, element)) == NULL)
+ snprintf(s, sizeof(s), "{%s}", innername);
+ else
+ strlcpy(s, innerval, sizeof(compare) - (s - compare));
+
+ s += strlen(s);
+ }
+ else if (ch == '\\')
+ *s++ = getc(in);
+ else
+ *s++ = ch;
+
+ *s = '\0';
+
+ if (ch != '?')
+ return;
+
+ /*
+ * Do the comparison...
+ */
+
+ switch (op)
+ {
+ case '<' :
+ result = strcasecmp(outptr, compare) < 0;
+ break;
+ case '>' :
+ result = strcasecmp(outptr, compare) > 0;
+ break;
+ case '=' :
+ result = strcasecmp(outptr, compare) == 0;
+ break;
+ case '!' :
+ result = strcasecmp(outptr, compare) != 0;
+ break;
+ default :
+ result = 1;
+ break;
+ }
+ }
+
+ if (result)
+ {
+ /*
+ * Comparison true; output first part and ignore second...
+ */
+
+ cgi_copy(out, in, element, ':');
+ cgi_copy(NULL, in, element, '}');
+ }
+ else
+ {
+ /*
+ * Comparison false; ignore first part and output second...
+ */
+
+ cgi_copy(NULL, in, element, ':');
+ cgi_copy(out, in, element, '}');
+ }
+ }
+ else if (ch == '\\') /* Quoted char */
+ {
+ if (out)
+ putc(getc(in), out);
+ else
+ getc(in);
+ }
+ else if (out)
+ putc(ch, out);
+
+ /*
+ * Flush any pending output...
+ */
+
+ if (out)
+ fflush(out);
+}
+
+
+/*
+ * 'cgi_puts()' - Put a string to the output file, quoting as needed...
+ */
+
+static void
+cgi_puts(const char *s,
+ FILE *out)
+{
+ while (*s)
+ {
+ if (s[0] == '<')
+ fputs("&lt;", out);
+ else if (s[0] == '>')
+ fputs("&gt;", out);
+ else if (*s == '\"')
+ fputs("&quot;", out);
+ else if (s[0] == '&')
+ fputs("&amp;", out);
+ else
+ putc(*s, out);
+
+ s ++;
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cgi-bin/var.c b/cgi-bin/var.c
new file mode 100644
index 000000000..0c291a26e
--- /dev/null
+++ b/cgi-bin/var.c
@@ -0,0 +1,672 @@
+/*
+ * "$Id$"
+ *
+ * CGI form variable and array functions.
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contents:
+ *
+ * cgiInitialize() - Initialize the CGI variable "database"...
+ * cgiCheckVariables() - Check for the presence of "required" variables.
+ * cgiGetArray() - Get an element from a form array...
+ * cgiGetSize() - Get the size of a form array value.
+ * cgiGetVariable() - Get a CGI variable from the database...
+ * cgiSetArray() - Set array element N to the specified string.
+ * cgiSetVariable() - Set a CGI variable in the database...
+ * cgi_add_variable() - Add a form variable.
+ * cgi_compare_variables() - Compare two variables.
+ * cgi_find_variable() - Find a variable...
+ * cgi_initialize_get() - Initialize form variables using the GET method.
+ * cgi_initialize_post() - Initialize variables using the POST method.
+ * cgi_initialize_string() - Initialize form variables from a string.
+ * cgi_sort_variables() - Sort all form variables for faster lookup.
+ */
+
+/*#define DEBUG*/
+#include "cgi.h"
+#include <errno.h>
+#include <syslog.h>
+
+
+/*
+ * Data structure to hold all the CGI form variables and arrays...
+ */
+
+typedef struct
+{
+ const char *name; /* Name of variable */
+ int nvalues, /* Number of values */
+ avalues; /* Number of values allocated */
+ const char **values; /* Value(s) of variable */
+} var_t;
+
+
+/*
+ * Local globals...
+ */
+
+static int form_count = 0, /* Form variable count */
+ form_alloc = 0; /* Number of variables allocated */
+static var_t *form_vars = NULL; /* Form variables */
+
+
+/*
+ * Local functions...
+ */
+
+static void cgi_add_variable(const char *name, int element,
+ const char *value);
+static int cgi_compare_variables(const var_t *v1, const var_t *v2);
+static var_t *cgi_find_variable(const char *name);
+static int cgi_initialize_get(void);
+static int cgi_initialize_post(void);
+static int cgi_initialize_string(const char *data);
+static void cgi_sort_variables(void);
+
+
+/*
+ * 'cgiInitialize()' - Initialize the CGI variable "database"...
+ */
+
+int /* O - Non-zero if there was form data */
+cgiInitialize(void)
+{
+ char *method; /* Form posting method */
+
+
+#ifdef DEBUG
+ setbuf(stdout, NULL);
+ puts("Content-type: text/plain\n");
+#endif /* DEBUG */
+
+ method = getenv("REQUEST_METHOD");
+
+ if (method == NULL)
+ return (0);
+
+ if (strcasecmp(method, "GET") == 0)
+ return (cgi_initialize_get());
+ else if (strcasecmp(method, "POST") == 0)
+ return (cgi_initialize_post());
+ else
+ return (0);
+}
+
+
+/*
+ * 'cgiCheckVariables()' - Check for the presence of "required" variables.
+ *
+ * Names may be separated by spaces and/or commas.
+ */
+
+int /* O - 1 if all variables present, 0 otherwise */
+cgiCheckVariables(const char *names) /* I - Variables to look for */
+{
+ char name[255], /* Current variable name */
+ *s; /* Pointer in string */
+ const char *val; /* Value of variable */
+ int element; /* Array element number */
+
+
+ if (names == NULL)
+ return (1);
+
+ while (*names != '\0')
+ {
+ while (*names == ' ' || *names == ',')
+ names ++;
+
+ for (s = name; *names != '\0' && *names != ' ' && *names != ','; s ++, names ++)
+ *s = *names;
+
+ *s = 0;
+ if (name[0] == '\0')
+ break;
+
+ if ((s = strrchr(name, '-')) != NULL)
+ {
+ *s = '\0';
+ element = atoi(s + 1) - 1;
+ val = cgiGetArray(name, element);
+ }
+ else
+ val = cgiGetVariable(name);
+
+ if (val == NULL)
+ return (0);
+
+ if (*val == '\0')
+ return (0); /* Can't be blank, either! */
+ }
+
+ return (1);
+}
+
+
+/*
+ * 'cgiGetArray()' - Get an element from a form array...
+ */
+
+const char * /* O - Element value or NULL */
+cgiGetArray(const char *name, /* I - Name of array variable */
+ int element) /* I - Element number (0 to N) */
+{
+ var_t *var; /* Pointer to variable */
+
+
+ if ((var = cgi_find_variable(name)) == NULL)
+ return (NULL);
+
+ if (var->nvalues == 1)
+ return (var->values[0]);
+
+ if (element < 0 || element >= var->nvalues)
+ return (NULL);
+
+ return (var->values[element]);
+}
+
+
+/*
+ * 'cgiGetSize()' - Get the size of a form array value.
+ */
+
+int /* O - Number of elements */
+cgiGetSize(const char *name) /* I - Name of variable */
+{
+ var_t *var; /* Pointer to variable */
+
+
+ if ((var = cgi_find_variable(name)) == NULL)
+ return (0);
+
+ return (var->nvalues);
+}
+
+
+/*
+ * 'cgiGetVariable()' - Get a CGI variable from the database...
+ *
+ * Returns NULL if the variable doesn't exist... If the variable is an
+ * array of values, returns the last element...
+ */
+
+const char * /* O - Value of variable */
+cgiGetVariable(const char *name)/* I - Name of variable */
+{
+ const var_t *var; /* Returned variable */
+
+
+ var = cgi_find_variable(name);
+
+#ifdef DEBUG
+ if (var == NULL)
+ printf("cgiGetVariable(\"%s\") is returning NULL...\n", name);
+ else
+ printf("cgiGetVariable(\"%s\") is returning \"%s\"...\n", name,
+ var->values[var->nvalues - 1]);
+#endif /* DEBUG */
+
+ return ((var == NULL) ? NULL : var->values[var->nvalues - 1]);
+}
+
+
+/*
+ * 'cgiSetArray()' - Set array element N to the specified string.
+ *
+ * If the variable array is smaller than (element + 1), the intervening
+ * elements are set to NULL.
+ */
+
+void
+cgiSetArray(const char *name, /* I - Name of variable */
+ int element, /* I - Element number (0 to N) */
+ const char *value) /* I - Value of variable */
+{
+ int i; /* Looping var */
+ var_t *var; /* Returned variable */
+
+
+ if (name == NULL || value == NULL || element < 0)
+ return;
+
+ if ((var = cgi_find_variable(name)) == NULL)
+ {
+ cgi_add_variable(name, element, value);
+ cgi_sort_variables();
+ }
+ else
+ {
+ if (element >= var->avalues)
+ {
+ var->avalues = element + 16;
+ var->values = (const char **)realloc((void *)(var->values),
+ sizeof(char *) * var->avalues);
+ }
+
+ if (element >= var->nvalues)
+ {
+ for (i = var->nvalues; i < element; i ++)
+ var->values[i] = NULL;
+
+ var->nvalues = element + 1;
+ }
+ else if (var->values[element])
+ free((char *)var->values[element]);
+
+ var->values[element] = strdup(value);
+ }
+}
+
+
+/*
+ * 'cgiSetSize()' - Set the array size.
+ */
+
+void
+cgiSetSize(const char *name, /* I - Name of variable */
+ int size) /* I - Number of elements (0 to N) */
+{
+ int i; /* Looping var */
+ var_t *var; /* Returned variable */
+
+
+ if (name == NULL || size < 0)
+ return;
+
+ if ((var = cgi_find_variable(name)) == NULL)
+ return;
+
+ if (size >= var->avalues)
+ {
+ var->avalues = size + 16;
+ var->values = (const char **)realloc((void *)(var->values),
+ sizeof(char *) * var->avalues);
+ }
+
+ if (size > var->nvalues)
+ {
+ for (i = var->nvalues; i < size; i ++)
+ var->values[i] = NULL;
+ }
+ else if (size < var->nvalues)
+ {
+ for (i = size; i < var->nvalues; i ++)
+ if (var->values[i])
+ free((void *)(var->values[i]));
+ }
+
+ var->nvalues = size;
+}
+
+
+/*
+ * 'cgiSetVariable()' - Set a CGI variable in the database...
+ *
+ * If the variable is an array, this truncates the array to a single element.
+ */
+
+void
+cgiSetVariable(const char *name, /* I - Name of variable */
+ const char *value) /* I - Value of variable */
+{
+ int i; /* Looping var */
+ var_t *var; /* Returned variable */
+
+
+ if (name == NULL || value == NULL)
+ return;
+
+ if ((var = cgi_find_variable(name)) == NULL)
+ {
+ cgi_add_variable(name, 0, value);
+ cgi_sort_variables();
+ }
+ else
+ {
+ for (i = 0; i < var->nvalues; i ++)
+ if (var->values[i])
+ free((char *)var->values[i]);
+
+ var->values[0] = strdup(value);
+ var->nvalues = 1;
+ }
+}
+
+
+/*
+ * 'cgi_add_variable()' - Add a form variable.
+ */
+
+static void
+cgi_add_variable(const char *name, /* I - Variable name */
+ int element, /* I - Array element number */
+ const char *value) /* I - Variable value */
+{
+ var_t *var; /* New variable */
+
+
+ if (name == NULL || value == NULL)
+ return;
+
+#ifdef DEBUG
+ printf("Adding variable \'%s\' with value \'%s\'...\n", name, value);
+#endif /* DEBUG */
+
+ if (form_count >= form_alloc)
+ {
+ if (form_alloc == 0)
+ form_vars = malloc(sizeof(var_t) * 16);
+ else
+ form_vars = realloc(form_vars, (form_alloc + 16) * sizeof(var_t));
+
+ form_alloc += 16;
+ }
+
+ var = form_vars + form_count;
+ var->name = strdup(name);
+ var->nvalues = element + 1;
+ var->avalues = element + 1;
+ var->values = calloc(element + 1, sizeof(char *));
+ var->values[element] = strdup(value);
+
+ form_count ++;
+}
+
+
+/*
+ * 'cgi_compare_variables()' - Compare two variables.
+ */
+
+static int /* O - Result of comparison */
+cgi_compare_variables(const var_t *v1, /* I - First variable */
+ const var_t *v2) /* I - Second variable */
+{
+ return (strcasecmp(v1->name, v2->name));
+}
+
+
+/*
+ * 'cgi_find_variable()' - Find a variable...
+ */
+
+static var_t * /* O - Variable pointer or NULL */
+cgi_find_variable(const char *name) /* I - Name of variable */
+{
+ var_t key; /* Search key */
+
+
+ if (form_count < 1 || name == NULL)
+ return (NULL);
+
+ key.name = name;
+
+ return ((var_t *)bsearch(&key, form_vars, form_count, sizeof(var_t),
+ (int (*)(const void *, const void *))cgi_compare_variables));
+}
+
+
+/*
+ * 'cgi_initialize_get()' - Initialize form variables using the GET method.
+ */
+
+static int /* O - 1 if form data read */
+cgi_initialize_get(void)
+{
+ char *data; /* Pointer to form data string */
+
+
+#ifdef DEBUG
+ puts("Initializing variables using GET method...");
+#endif /* DEBUG */
+
+ /*
+ * Check to see if there is anything for us to read...
+ */
+
+ data = getenv("QUERY_STRING");
+ if (data == NULL || strlen(data) == 0)
+ return (0);
+
+ /*
+ * Parse it out and return...
+ */
+
+ return (cgi_initialize_string(data));
+}
+
+
+/*
+ * 'cgi_initialize_post()' - Initialize variables using the POST method.
+ */
+
+static int /* O - 1 if form data was read */
+cgi_initialize_post(void)
+{
+ char *content_length, /* Length of input data (string) */
+ *data; /* Pointer to form data string */
+ int length, /* Length of input data */
+ nbytes, /* Number of bytes read this read() */
+ tbytes, /* Total number of bytes read */
+ status; /* Return status */
+
+
+#ifdef DEBUG
+ puts("Initializing variables using POST method...");
+#endif /* DEBUG */
+
+ /*
+ * Check to see if there is anything for us to read...
+ */
+
+ content_length = getenv("CONTENT_LENGTH");
+ if (content_length == NULL || atoi(content_length) <= 0)
+ return (0);
+
+ /*
+ * Get the length of the input stream and allocate a buffer for it...
+ */
+
+ length = atoi(content_length);
+ data = malloc(length + 1);
+
+ if (data == NULL)
+ return (0);
+
+ /*
+ * Read the data into the buffer...
+ */
+
+ for (tbytes = 0; tbytes < length; tbytes += nbytes)
+ if ((nbytes = read(0, data + tbytes, length - tbytes)) < 0)
+ if (errno != EAGAIN)
+ {
+ free(data);
+ return (0);
+ }
+
+ data[length] = '\0';
+
+ /*
+ * Parse it out...
+ */
+
+ status = cgi_initialize_string(data);
+
+ /*
+ * Free the data and return...
+ */
+
+ free(data);
+
+ return (status);
+}
+
+
+/*
+ * 'cgi_initialize_string()' - Initialize form variables from a string.
+ */
+
+static int
+cgi_initialize_string(const char *data) /* I - Form data string */
+{
+ int done; /* True if we're done reading a form variable */
+ char *s, /* Pointer to current form string */
+ ch, /* Temporary character */
+ name[255], /* Name of form variable */
+ value[65536]; /* Variable value... */
+
+
+ /*
+ * Check input...
+ */
+
+ if (data == NULL)
+ return (0);
+
+ /*
+ * Loop until we've read all the form data...
+ */
+
+ while (*data != '\0')
+ {
+ /*
+ * Get the variable name...
+ */
+
+ for (s = name; *data != '\0'; data ++)
+ if (*data == '=')
+ break;
+ else if (*data >= ' ' && s < (name + sizeof(name) - 1))
+ *s++ = *data;
+
+ *s = '\0';
+ if (*data == '=')
+ data ++;
+ else
+ return (0);
+
+ /*
+ * Read the variable value...
+ */
+
+ for (s = value, done = 0; !done && *data != '\0'; data ++)
+ switch (*data)
+ {
+ case '&' : /* End of data... */
+ done = 1;
+ break;
+
+ case '+' : /* Escaped space character */
+ if (s < (value + sizeof(value) - 1))
+ *s++ = ' ';
+ break;
+
+ case '%' : /* Escaped control character */
+ /*
+ * Read the hex code...
+ */
+
+ if (s < (value + sizeof(value) - 1))
+ {
+ data ++;
+ ch = *data - '0';
+ if (ch > 9)
+ ch -= 7;
+ *s = ch << 4;
+
+ data ++;
+ ch = *data - '0';
+ if (ch > 9)
+ ch -= 7;
+ *s++ |= ch;
+ }
+ else
+ data += 2;
+ break;
+
+ default : /* Other characters come straight through */
+ if (*data >= ' ' && s < (value + sizeof(value) - 1))
+ *s++ = *data;
+ break;
+ }
+
+ *s = '\0'; /* nul terminate the string */
+
+ /*
+ * Remove trailing whitespace...
+ */
+
+ if (s > value)
+ s --;
+
+ while (s >= value && *s == ' ')
+ *s-- = '\0';
+
+ /*
+ * Add the string to the variable "database"...
+ */
+
+ if ((s = strrchr(name, '-')) != NULL && isdigit(s[1]))
+ {
+ *s++ = '\0';
+ if (value[0])
+ cgiSetArray(name, atoi(s) - 1, value);
+ }
+ else if (cgiGetVariable(name) != NULL)
+ cgiSetArray(name, cgiGetSize(name), value);
+ else
+ cgiSetVariable(name, value);
+ }
+
+ return (1);
+}
+
+
+/*
+ * 'cgi_sort_variables()' - Sort all form variables for faster lookup.
+ */
+
+static void
+cgi_sort_variables(void)
+{
+#ifdef DEBUG
+ int i;
+
+
+ puts("Sorting variables...");
+#endif /* DEBUG */
+
+ if (form_count < 2)
+ return;
+
+ qsort(form_vars, form_count, sizeof(var_t),
+ (int (*)(const void *, const void *))cgi_compare_variables);
+
+#ifdef DEBUG
+ puts("Sorted variable list is:");
+ for (i = 0; i < form_count; i ++)
+ printf("%d: %s (%d) = \"%s\" ...\n", i, form_vars[i].name,
+ form_vars[i].nvalues, form_vars[i].values[0]);
+#endif /* DEBUG */
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/conf/Makefile b/conf/Makefile
new file mode 100644
index 000000000..22d98771f
--- /dev/null
+++ b/conf/Makefile
@@ -0,0 +1,76 @@
+#
+# "$Id$"
+#
+# Configuration file makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+#
+# Config files...
+#
+
+KEEP = classes.conf client.conf cupsd.conf printers.conf
+REPLACE = mime.convs mime.types
+
+
+#
+# Make everything...
+#
+
+all:
+
+
+#
+# Clean all config and object files...
+#
+
+clean:
+
+
+#
+# Install files...
+#
+
+install:
+ $(INSTALL_DIR) $(SERVERROOT)
+ for file in $(KEEP); do \
+ if test -r $(SERVERROOT)/$$file ; then \
+ $(INSTALL_DATA) $$file $(SERVERROOT)/$$file.N ; \
+ else \
+ $(INSTALL_DATA) $$file $(SERVERROOT) ; \
+ fi ; \
+ done
+ for file in $(REPLACE); do \
+ if test -r $(SERVERROOT)/$$file ; then \
+ $(MV) $(SERVERROOT)/$$file $(SERVERROOT)/$$file.O ; \
+ fi ; \
+ $(INSTALL_DATA) $$file $(SERVERROOT) ; \
+ done
+ -if test x$(PAMDIR) != x$(BUILDROOT); then \
+ $(INSTALL_DIR) $(PAMDIR); \
+ $(INSTALL_DATA) pam.conf $(PAMDIR)/cups; \
+ fi
+
+
+#
+# End of "$Id$".
+#
diff --git a/conf/classes.conf b/conf/classes.conf
new file mode 100644
index 000000000..05526a605
--- /dev/null
+++ b/conf/classes.conf
@@ -0,0 +1,89 @@
+#
+# "$Id: classes.conf 2010 2002-01-02 17:59:21Z mike $"
+#
+# Sample class configuration file for the Common UNIX Printing System
+# (CUPS) scheduler.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+########################################################################
+# #
+# This is a sample class configuration file. This file is included #
+# from the main configuration file (cups.conf) and lists all of the #
+# printer classes known to the system. #
+# #
+########################################################################
+
+#
+# Each class starts with a <Class name> definition. Class names
+# can be up to 128 characters in length and are *not* case sensitive.
+#
+# One <DefaultClass name> entry can appear in this file; if you don't
+# define a default destination, the first printer or class becomes
+# the default.
+#
+
+#<Class sample>
+#
+# Info: the description for the class.
+#
+
+#Info Acme LaserPrint 1000 Printers
+
+#
+# Location: the location of the printer.
+#
+
+#Location Room 101 in the activities building
+
+#
+# State: sets the initial state of the class. Can be one of the
+# following:
+#
+# Idle - Class is available to print new jobs.
+# Stopped - Class is disabled but accepting new jobs.
+#
+
+#State Idle
+
+#
+# StateMessage: sets the printer-state-message attribute for the class.
+#
+
+#StateMessage Class is idle.
+
+#
+# Accepting: is the class accepting jobs?
+#
+#Accepting Yes
+#Accepting No
+#
+
+#
+# Printer: adds a printer to the class.
+#
+
+#Printer sample
+#Printer sample@host2
+#</Class>
+
+#
+# End of "$Id: classes.conf 2010 2002-01-02 17:59:21Z mike $".
+#
diff --git a/conf/client.conf b/conf/client.conf
new file mode 100644
index 000000000..244b5e1fe
--- /dev/null
+++ b/conf/client.conf
@@ -0,0 +1,65 @@
+#
+# "$Id: client.conf 2010 2002-01-02 17:59:21Z mike $"
+#
+# Sample client configuration file for the Common UNIX Printing System
+# (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+########################################################################
+# #
+# This is the CUPS client configuration file. This file is used to #
+# define client-specific parameters, such as the default server or #
+# default encryption settings. #
+# #
+########################################################################
+
+#
+# ServerName: the hostname of your server. By default CUPS will use the
+# hostname of the system or the value of the CUPS_SERVER environment
+# variable.
+#
+
+#ServerName myhost.domain.com
+
+#
+# Encryption: whether or not to use encryption; this depends on having
+# the OpenSSL library linked into the CUPS library.
+#
+# Possible values:
+#
+# Always - Always use encryption (SSL)
+# Never - Never use encryption
+# Required - Use TLS encryption upgrade
+# IfRequested - Use encryption if the server requests it
+#
+# The default value is "IfRequested". This parameter can also be set
+# using the CUPS_ENCRYPTION environment variable.
+#
+
+#Encryption Always
+#Encryption Never
+#Encryption Required
+#Encryption IfRequested
+
+
+#
+# End of "$Id: client.conf 2010 2002-01-02 17:59:21Z mike $".
+#
diff --git a/conf/cupsd.conf.in b/conf/cupsd.conf.in
new file mode 100644
index 000000000..46723336d
--- /dev/null
+++ b/conf/cupsd.conf.in
@@ -0,0 +1,765 @@
+#
+# "$Id$"
+#
+# Sample configuration file for the Common UNIX Printing System (CUPS)
+# scheduler.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+########################################################################
+# #
+# This is the CUPS configuration file. If you are familiar with #
+# Apache or any of the other popular web servers, we've followed the #
+# same format. Any configuration variable used here has the same #
+# semantics as the corresponding variable in Apache. If we need #
+# different functionality then a different name is used to avoid #
+# confusion... #
+# #
+########################################################################
+
+
+########
+######## Server Identity
+########
+
+#
+# ServerName: the hostname of your server, as advertised to the world.
+# By default CUPS will use the hostname of the system.
+#
+# To set the default server used by clients, see the client.conf file.
+#
+
+#ServerName myhost.domain.com
+
+#
+# ServerAdmin: the email address to send all complaints/problems to.
+# By default CUPS will use "root@hostname".
+#
+
+#ServerAdmin root@your.domain.com
+
+
+########
+######## Server Options
+########
+
+#
+# AccessLog: the access log file; if this does not start with a leading /
+# then it is assumed to be relative to ServerRoot. By default set to
+# "@CUPS_LOGDIR@/access_log"
+#
+# You can also use the special name "syslog" to send the output to the
+# syslog file or daemon.
+#
+
+#AccessLog @CUPS_LOGDIR@/access_log
+
+#
+# Classification: the classification level of the server. If set, this
+# classification is displayed on all pages, and raw printing is disabled.
+# The default is the empty string.
+#
+
+#Classification classified
+#Classification confidential
+#Classification secret
+#Classification topsecret
+#Classification unclassified
+
+#
+# ClassifyOverride: whether to allow users to override the classification
+# on printouts. If enabled, users can limit banner pages to before or
+# after the job, and can change the classification of a job, but cannot
+# completely eliminate the classification or banners.
+#
+# The default is off.
+#
+
+#ClassifyOverride off
+
+#
+# DataDir: the root directory for the CUPS data files.
+# By default "@CUPS_DATADIR@".
+#
+
+#DataDir @CUPS_DATADIR@
+
+#
+# DefaultCharset: the default character set to use. If not specified,
+# defaults to "utf-8". Note that this can also be overridden in
+# HTML documents...
+#
+
+#DefaultCharset utf-8
+
+#
+# DefaultLanguage: the default language if not specified by the browser.
+# If not specified, the current locale is used.
+#
+
+#DefaultLanguage en
+
+#
+# DocumentRoot: the root directory for HTTP documents that are served.
+# By default "@CUPS_DOCROOT@".
+#
+
+#DocumentRoot @CUPS_DOCROOT@
+
+#
+# ErrorLog: the error log file; if this does not start with a leading /
+# then it is assumed to be relative to ServerRoot. By default set to
+# "@CUPS_LOGDIR@/error_log"
+#
+# You can also use the special name "syslog" to send the output to the
+# syslog file or daemon.
+#
+
+#ErrorLog @CUPS_LOGDIR@/error_log
+
+#
+# FontPath: the path to locate all font files (currently only for pstoraster)
+# By default "@CUPS_FONTPATH@".
+#
+
+#FontPath @CUPS_FONTPATH@
+
+#
+# LogLevel: controls the number of messages logged to the ErrorLog
+# file and can be one of the following:
+#
+# debug2 Log everything.
+# debug Log almost everything.
+# info Log all requests and state changes.
+# warn Log errors and warnings.
+# error Log only errors.
+# none Log nothing.
+#
+
+LogLevel info
+
+#
+# MaxLogSize: controls the maximum size of each log file before they are
+# rotated. Defaults to 1048576 (1MB). Set to 0 to disable log rotating.
+#
+
+#MaxLogSize 0
+
+#
+# PageLog: the page log file; if this does not start with a leading /
+# then it is assumed to be relative to ServerRoot. By default set to
+# "@CUPS_LOGDIR@/page_log"
+#
+# You can also use the special name "syslog" to send the output to the
+# syslog file or daemon.
+#
+
+#PageLog @CUPS_LOGDIR@/page_log
+
+#
+# PreserveJobHistory: whether or not to preserve the job history after a
+# job is completed, cancelled, or stopped. Default is Yes.
+#
+
+#PreserveJobHistory Yes
+
+#
+# PreserveJobFiles: whether or not to preserve the job files after a
+# job is completed, cancelled, or stopped. Default is No.
+#
+
+#PreserveJobFiles No
+
+#
+# AutoPurgeJobs: automatically purge jobs when not needed for quotas.
+# Default is No.
+#
+
+#AutoPurgeJobs No
+
+#
+# MaxCopies: maximum number of copies that a user can request. Default is
+# 100.
+#
+
+#MaxCopies 100
+
+#
+# MaxJobs: maximum number of jobs to keep in memory (active and completed.)
+# Default is 500; the value 0 is used for no limit.
+#
+
+#MaxJobs 500
+
+#
+# Printcap: the name of the printcap file. Default is /etc/printcap.
+# Leave blank to disable printcap file generation.
+#
+
+#Printcap /etc/printcap
+
+#
+# PrintcapFormat: the format of the printcap file, currently either
+# BSD or Solaris. The default is "BSD".
+#
+
+#PrintcapFormat BSD
+#PrintcapFormat Solaris
+
+#
+# PrintcapGUI: the name of the GUI options panel program to associate
+# with print queues under IRIX. The default is "/usr/bin/glpoptions"
+# from ESP Print Pro.
+#
+# This option is only used under IRIX; the options panel program
+# must accept the "-d printer" and "-o options" options and write
+# the selected printer options back to stdout on completion.
+#
+
+#PrintcapGUI /usr/bin/glpoptions
+
+#
+# RequestRoot: the directory where request files are stored.
+# By default "@CUPS_REQUESTS@".
+#
+
+#RequestRoot @CUPS_REQUESTS@
+
+#
+# RemoteRoot: the name of the user assigned to unauthenticated accesses
+# from remote systems. By default "remroot".
+#
+
+#RemoteRoot remroot
+
+#
+# ServerBin: the root directory for the scheduler executables.
+# By default "@CUPS_SERVERBIN@".
+#
+
+#ServerBin @CUPS_SERVERBIN@
+
+#
+# ServerRoot: the root directory for the scheduler.
+# By default "@CUPS_SERVERROOT@".
+#
+
+#ServerRoot @CUPS_SERVERROOT@
+
+
+########
+######## Encryption Support
+########
+
+#
+# ServerCertificate: the file to read containing the server's certificate.
+# Defaults to "@CUPS_SERVERROOT@/ssl/server.crt".
+#
+
+#ServerCertificate @CUPS_SERVERROOT@/ssl/server.crt
+
+#
+# ServerKey: the file to read containing the server's key.
+# Defaults to "@CUPS_SERVERROOT@/ssl/server.key".
+#
+
+#ServerKey @CUPS_SERVERROOT@/ssl/server.key
+
+
+########
+######## Filter Options
+########
+
+#
+# User/Group: the user and group the server runs under. Normally this
+# must be @CUPS_USER@ and @CUPS_GROUP@, however you can configure things for another
+# user or group as needed.
+#
+# Note: the server must be run initially as root to support the
+# default IPP port of 631. It changes users whenever an external
+# program is run, or if the RunAsUser directive is specified...
+#
+
+#User @CUPS_USER@
+#Group @CUPS_GROUP@
+
+#
+# RIPCache: the amount of memory that each RIP should use to cache
+# bitmaps. The value can be any real number followed by "k" for
+# kilobytes, "m" for megabytes, "g" for gigabytes, or "t" for tiles
+# (1 tile = 256x256 pixels.) Defaults to "8m" (8 megabytes).
+#
+
+#RIPCache 8m
+
+#
+# TempDir: the directory to put temporary files in. This directory must be
+# writable by the user defined above! Defaults to "@CUPS_REQUESTS@/tmp" or
+# the value of the TMPDIR environment variable.
+#
+
+#TempDir @CUPS_REQUESTS@/tmp
+
+#
+# FilterLimit: sets the maximum cost of all job filters that can be run
+# at the same time. A limit of 0 means no limit. A typical job may need
+# a filter limit of at least 200; limits less than the minimum required
+# by a job force a single job to be printed at any time.
+#
+# The default limit is 0 (unlimited).
+#
+
+#FilterLimit 0
+
+########
+######## Network Options
+########
+
+#
+# Ports/addresses that we listen to. The default port 631 is reserved
+# for the Internet Printing Protocol (IPP) and is what we use here.
+#
+# You can have multiple Port/Listen lines to listen to more than one
+# port or address, or to restrict access:
+#
+# Port 80
+# Port 631
+# Listen hostname
+# Listen hostname:80
+# Listen hostname:631
+# Listen 1.2.3.4
+# Listen 1.2.3.4:631
+#
+# NOTE: Unfortunately, most web browsers don't support TLS or HTTP Upgrades
+# for encryption. If you want to support web-based encryption you'll
+# probably need to listen on port 443 (the "https" port...)
+#
+
+#Port 80
+#Port 443
+Port 631
+
+#
+# HostNameLookups: whether or not to do lookups on IP addresses to get a
+# fully-qualified hostname. This defaults to Off for performance reasons...
+#
+
+#HostNameLookups On
+
+#
+# KeepAlive: whether or not to support the Keep-Alive connection
+# option. Default is on.
+#
+
+#KeepAlive On
+
+#
+# KeepAliveTimeout: the timeout before Keep-Alive connections are
+# automatically closed. Default is 60 seconds.
+#
+
+#KeepAliveTimeout 60
+
+#
+# MaxClients: controls the maximum number of simultaneous clients that
+# will be handled. Defaults to 100.
+#
+
+#MaxClients 100
+
+#
+# MaxRequestSize: controls the maximum size of HTTP requests and print files.
+# Set to 0 to disable this feature (defaults to 0.)
+#
+
+#MaxRequestSize 0
+
+#
+# Timeout: the timeout before requests time out. Default is 300 seconds.
+#
+
+#Timeout 300
+
+
+########
+######## Browsing Options
+########
+
+#
+# Browsing: whether or not to broadcast and/or listen for CUPS printer
+# information on the network. Enabled by default.
+#
+
+#Browsing On
+
+#
+# BrowseProtocols: which protocols to use for browsing. Can be
+# any of the following separated by whitespace and/or commas:
+#
+# all - Use all supported protocols.
+# cups - Use the CUPS browse protocol.
+# slp - Use the SLPv2 protocol.
+#
+# The default is "cups".
+#
+# NOTE: If you choose to use SLPv2, it is *strongly* recommended that
+# you have at least one SLP Directory Agent (DA) on your
+# network. Otherwise, browse updates can take several seconds,
+# during which the scheduler will not response to client
+# requests.
+#
+
+#BrowseProtocols cups
+
+#
+# BrowseAddress: specifies a broadcast address to be used. By
+# default browsing information is not sent!
+#
+# Note: HP-UX does not properly handle broadcast unless you have a
+# Class A, B, C, or D netmask (i.e. no CIDR support).
+#
+# Note: Using the "global" broadcast address (255.255.255.255) will
+# activate a Linux demand-dial link with the default configuration.
+# If you have a LAN as well as the dial-up link, use the LAN's
+# broadcast address.
+#
+# The @LOCAL address broadcasts to all non point-to-point interfaces.
+# For example, if you have a LAN and a dial-up link, @LOCAL would
+# send printer updates to the LAN but not to the dial-up link.
+# Similarly, the @IF(name) address sends to the named network
+# interface, e.g. @IF(eth0) under Linux. Interfaces are refreshed
+# automatically (no more than once every 60 seconds), so they can
+# be used on dynamically-configured interfaces, e.g. PPP, 802.11, etc.
+#
+
+#BrowseAddress x.y.z.255
+#BrowseAddress x.y.255.255
+#BrowseAddress x.255.255.255
+#BrowseAddress 255.255.255.255
+#BrowseAddress @LOCAL
+#BrowseAddress @IF(name)
+
+#
+# BrowseShortNames: whether or not to use "short" names for remote printers
+# when possible (e.g. "printer" instead of "printer@host".) Enabled by
+# default.
+#
+
+#BrowseShortNames Yes
+
+#
+# BrowseAllow: specifies an address mask to allow for incoming browser
+# packets. The default is to allow packets from all addresses.
+#
+# BrowseDeny: specifies an address mask to deny for incoming browser
+# packets. The default is to deny packets from no addresses.
+#
+# Both "BrowseAllow" and "BrowseDeny" accept the following notations for
+# addresses:
+#
+# All
+# None
+# *.domain.com
+# .domain.com
+# host.domain.com
+# nnn.*
+# nnn.nnn.*
+# nnn.nnn.nnn.*
+# nnn.nnn.nnn.nnn
+# nnn.nnn.nnn.nnn/mm
+# nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+# @LOCAL
+# @IF(name)
+#
+# The hostname/domainname restrictions only work if you have turned hostname
+# lookups on!
+#
+
+#BrowseAllow address
+#BrowseDeny address
+
+#
+# BrowseInterval: the time between browsing updates in seconds. Default
+# is 30 seconds.
+#
+# Note that browsing information is sent whenever a printer's state changes
+# as well, so this represents the maximum time between updates.
+#
+# Set this to 0 to disable outgoing broadcasts so your local printers are
+# not advertised but you can still see printers on other hosts.
+#
+
+#BrowseInterval 30
+
+#
+# BrowseOrder: specifies the order of BrowseAllow/BrowseDeny comparisons.
+#
+
+#BrowseOrder allow,deny
+#BrowseOrder deny,allow
+
+#
+# BrowsePoll: poll the named server(s) for printers
+#
+
+#BrowsePoll address:port
+
+#
+# BrowsePort: the port used for UDP broadcasts. By default this is
+# the IPP port; if you change this you need to do it on all servers.
+# Only one BrowsePort is recognized.
+#
+
+#BrowsePort 631
+
+#
+# BrowseRelay: relay browser packets from one address/network to another.
+#
+
+#BrowseRelay source-address destination-address
+#BrowseRelay @IF(src) @IF(dst)
+
+#
+# BrowseTimeout: the timeout for network printers - if we don't
+# get an update within this time the printer will be removed
+# from the printer list. This number definitely should not be
+# less the BrowseInterval value for obvious reasons. Defaults
+# to 300 seconds.
+#
+
+#BrowseTimeout 300
+
+#
+# ImplicitClasses: whether or not to use implicit classes.
+#
+# Printer classes can be specified explicitly in the classes.conf
+# file, implicitly based upon the printers available on the LAN, or
+# both.
+#
+# When ImplicitClasses is On, printers on the LAN with the same name
+# (e.g. Acme-LaserPrint-1000) will be put into a class with the same
+# name. This allows you to setup multiple redundant queues on a LAN
+# without a lot of administrative difficulties. If a user sends a
+# job to Acme-LaserPrint-1000, the job will go to the first available
+# queue.
+#
+# Enabled by default.
+#
+
+#ImplicitClasses On
+
+#
+# ImplicitAnyClasses: whether or not to create "AnyPrinter" implicit
+# classes.
+#
+# When ImplicitAnyClasses is On and a local queue of the same name
+# exists, e.g. "printer", "printer@server1", "printer@server1", then
+# an implicit class called "Anyprinter" is created instead.
+#
+# When ImplicitAnyClasses is Off, implicit classes are not created
+# when there is a local queue of the same name.
+#
+# Disabled by default.
+#
+
+#ImplicitAnyCLasses Off
+
+#
+# HideImplicitMembers: whether or not to show the members of an
+# implicit class.
+#
+# When HideImplicitMembers is On, any remote printers that are
+# part of an implicit class are hidden from the user, who will
+# then only see a single queue even though many queues will be
+# supporting the implicit class.
+#
+# Enabled by default.
+#
+
+#HideImplicitMembers On
+
+
+########
+######## Security Options
+########
+
+#
+# SystemGroup: the group name for "System" (printer administration)
+# access. The default varies depending on the operating system, but
+# will be "sys", "system", or "root" (checked for in that order.)
+#
+
+#SystemGroup @CUPS_GROUP@
+
+#
+# RootCertDuration: How frequently the root certificate is regenerated.
+# Defaults to 300 seconds.
+#
+
+#RootCertDuration 300
+
+#
+# Access permissions for each directory served by the scheduler.
+# Locations are relative to DocumentRoot...
+#
+# AuthType: the authorization to use:
+#
+# None - Perform no authentication
+# Basic - Perform authentication using the HTTP Basic method.
+# Digest - Perform authentication using the HTTP Digest method.
+#
+# (Note: local certificate authentication can be substituted by
+# the client for Basic or Digest when connecting to the
+# localhost interface)
+#
+# AuthClass: the authorization class; currently only "Anonymous", "User",
+# "System" (valid user belonging to group SystemGroup), and "Group"
+# (valid user belonging to the specified group) are supported.
+#
+# AuthGroupName: the group name for "Group" authorization.
+#
+# Order: the order of Allow/Deny processing.
+#
+# Allow: allows access from the specified hostname, domain, IP address,
+# network, or interface.
+#
+# Deny: denies access from the specified hostname, domain, IP address,
+# network, or interface.
+#
+# Both "Allow" and "Deny" accept the following notations for addresses:
+#
+# All
+# None
+# *.domain.com
+# .domain.com
+# host.domain.com
+# nnn.*
+# nnn.nnn.*
+# nnn.nnn.nnn.*
+# nnn.nnn.nnn.nnn
+# nnn.nnn.nnn.nnn/mm
+# nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+# @LOCAL
+# @IF(name)
+#
+# The host and domain address require that you enable hostname lookups
+# with "HostNameLookups On" above.
+#
+# The @LOCAL address allows or denies from all non point-to-point
+# interfaces. For example, if you have a LAN and a dial-up link,
+# @LOCAL could allow connections from the LAN but not from the dial-up
+# link. Similarly, the @IF(name) address allows or denies from the
+# named network interface, e.g. @IF(eth0) under Linux. Interfaces are
+# refreshed automatically (no more than once every 60 seconds), so
+# they can be used on dynamically-configured interfaces, e.g. PPP,
+# 802.11, etc.
+#
+# Encryption: whether or not to use encryption; this depends on having
+# the OpenSSL library linked into the CUPS library and scheduler.
+#
+# Possible values:
+#
+# Always - Always use encryption (SSL)
+# Never - Never use encryption
+# Required - Use TLS encryption upgrade
+# IfRequested - Use encryption if the server requests it
+#
+# The default value is "IfRequested".
+#
+
+<Location />
+Order Deny,Allow
+Deny From All
+Allow From 127.0.0.1
+</Location>
+
+#<Location /classes>
+#
+# You may wish to limit access to printers and classes, either with Allow
+# and Deny lines, or by requiring a username and password.
+#
+#</Location>
+
+#<Location /classes/name>
+#
+# You may wish to limit access to printers and classes, either with Allow
+# and Deny lines, or by requiring a username and password.
+#
+#</Location>
+
+#<Location /jobs>
+#
+# You may wish to limit access to job operations, either with Allow
+# and Deny lines, or by requiring a username and password.
+#
+#</Location>
+
+#<Location /printers>
+#
+# You may wish to limit access to printers and classes, either with Allow
+# and Deny lines, or by requiring a username and password.
+#
+#</Location>
+
+#<Location /printers/name>
+#
+# You may wish to limit access to printers and classes, either with Allow
+# and Deny lines, or by requiring a username and password.
+#
+
+## Anonymous access (default)
+#AuthType None
+
+## Require a username and password (Basic authentication)
+#AuthType Basic
+#AuthClass User
+
+## Require a username and password (Digest/MD5 authentication)
+#AuthType Digest
+#AuthClass User
+
+## Restrict access to local domain
+#Order Deny,Allow
+#Deny From All
+#Allow From .mydomain.com
+#</Location>
+
+<Location /admin>
+#
+# You definitely will want to limit access to the administration functions.
+# The default configuration requires a local connection from a user who
+# is a member of the system group to do any admin tasks. You can change
+# the group name using the SystemGroup directive.
+#
+
+AuthType Basic
+AuthClass System
+
+## Restrict access to local domain
+Order Deny,Allow
+Deny From All
+Allow From 127.0.0.1
+
+#Encryption Required
+</Location>
+
+#
+# End of "$Id$".
+#
diff --git a/conf/mime.convs b/conf/mime.convs
new file mode 100644
index 000000000..07ececd38
--- /dev/null
+++ b/conf/mime.convs
@@ -0,0 +1,116 @@
+#
+# "$Id: mime.convs 2599 2002-08-09 00:00:55Z mike $"
+#
+# MIME converts file for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+########################################################################
+#
+# Format of Lines:
+#
+# source/type destination/type cost filter
+#
+# General Notes:
+#
+# The "cost" field is used to find the least costly filters to run
+# when converting a job file to a printable format.
+#
+# All filters *must* accept the standard command-line arguments
+# (job-id, user, title, copies, options, [filename or stdin]) to
+# work with CUPS.
+#
+
+########################################################################
+#
+# PostScript filters
+#
+
+application/pdf application/postscript 33 pdftops
+application/postscript application/vnd.cups-postscript 66 pstops
+application/vnd.hp-HPGL application/postscript 66 hpgltops
+application/x-cshell application/postscript 33 texttops
+application/x-perl application/postscript 33 texttops
+application/x-shell application/postscript 33 texttops
+text/plain application/postscript 33 texttops
+text/html application/postscript 33 texttops
+image/gif application/vnd.cups-postscript 66 imagetops
+image/png application/vnd.cups-postscript 66 imagetops
+image/jpeg application/vnd.cups-postscript 66 imagetops
+image/tiff application/vnd.cups-postscript 66 imagetops
+image/x-photocd application/vnd.cups-postscript 66 imagetops
+image/x-portable-anymap application/vnd.cups-postscript 66 imagetops
+image/x-portable-bitmap application/vnd.cups-postscript 66 imagetops
+image/x-portable-graymap application/vnd.cups-postscript 66 imagetops
+image/x-portable-pixmap application/vnd.cups-postscript 66 imagetops
+image/x-sgi-rgb application/vnd.cups-postscript 66 imagetops
+image/x-xbitmap application/vnd.cups-postscript 66 imagetops
+image/x-xpixmap application/vnd.cups-postscript 66 imagetops
+image/x-xwindowdump application/vnd.cups-postscript 66 imagetops
+image/x-sun-raster application/vnd.cups-postscript 66 imagetops
+
+
+########################################################################
+#
+# Form filter...
+#
+# This filter does not currently exist, but the file format is defined
+# in the IDD and registered with the IANA for future use...
+#
+
+#application/vnd.cups-form application/vnd.cups-postscript 33 formtops
+
+########################################################################
+#
+# Raster filters...
+#
+
+image/gif application/vnd.cups-raster 100 imagetoraster
+image/png application/vnd.cups-raster 100 imagetoraster
+image/jpeg application/vnd.cups-raster 100 imagetoraster
+image/tiff application/vnd.cups-raster 100 imagetoraster
+image/x-photocd application/vnd.cups-raster 100 imagetoraster
+image/x-portable-anymap application/vnd.cups-raster 100 imagetoraster
+image/x-portable-bitmap application/vnd.cups-raster 100 imagetoraster
+image/x-portable-graymap application/vnd.cups-raster 100 imagetoraster
+image/x-portable-pixmap application/vnd.cups-raster 100 imagetoraster
+image/x-sgi-rgb application/vnd.cups-raster 100 imagetoraster
+image/x-xbitmap application/vnd.cups-raster 100 imagetoraster
+image/x-xpixmap application/vnd.cups-raster 100 imagetoraster
+image/x-xwindowdump application/vnd.cups-raster 100 imagetoraster
+image/x-sun-raster application/vnd.cups-raster 100 imagetoraster
+
+# pstoraster is now part of ESP Ghostscript...
+#application/vnd.cups-postscript application/vnd.cups-raster 100 pstoraster
+
+########################################################################
+#
+# Raw filter...
+#
+# Uncomment the following filter and the application/octet-stream type
+# in mime.types to allow printing of arbitrary files without the -oraw
+# option.
+#
+
+#application/octet-stream application/vnd.cups-raw 0 -
+
+#
+# End of "$Id: mime.convs 2599 2002-08-09 00:00:55Z mike $".
+#
diff --git a/conf/mime.types b/conf/mime.types
new file mode 100644
index 000000000..7740722ff
--- /dev/null
+++ b/conf/mime.types
@@ -0,0 +1,157 @@
+#
+# "$Id: mime.types 2599 2002-08-09 00:00:55Z mike $"
+#
+# MIME types file for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+########################################################################
+#
+# Format of Lines:
+#
+# super/type rules
+#
+# "rules" can be any combination of:
+#
+# ( expr ) Parenthesis for expression grouping
+# + Logical AND
+# , or whitespace Logical OR
+# ! Logical NOT
+# match("pattern") Pattern match on filename
+# extension Pattern match on "*.extension"
+# ascii(offset,length) True if bytes are valid printable ASCII
+# (CR, NL, TAB, BS, 32-126)
+# printable(offset,length) True if bytes are printable 8-bit chars
+# (CR, NL, TAB, BS, 32-126, 128-254)
+# string(offset,"string") True if bytes are identical to string
+# char(offset,value) True if byte is identical
+# short(offset,value) True if 16-bit integer is identical
+# int(offset,value) True if 32-bit integer is identical
+# locale("string") True if current locale matches string
+# contains(offset,range,"string") True if the range contains the string
+#
+# General Notes:
+#
+# MIME type names are case-insensitive. Internally they are converted
+# to lowercase. Multiple occurrences of a type will cause the provided
+# rules to be appended to the existing definition. Type names are sorted
+# in ascending order, so if two types use the same rules to resolve a type
+# (e.g. doc extension for two types), the returned type will be the first
+# type in the sorted list.
+#
+# The "printable" rule differs from the "ascii" rule in that it also
+# accepts 8-bit characters in the range 128-255.
+#
+# String constants must be surrounded by "" if they contain whitespace.
+# To insert binary data into a string, use the <hex> notation.
+#
+
+########################################################################
+#
+# Application-generated files...
+#
+
+application/msword doc string(0,<D0CF11E0A1B11AE1>)
+application/pdf pdf string(0,%PDF)
+application/postscript ai eps ps string(0,%!) string(0,<04>%!)
+application/vnd.hp-HPGL hpgl string(0,<1B>&)\
+ string(0,<1B>E<1B>%0B) \
+ string(0,<1B>%-1B) string(0,<201B>)\
+ string(0,BP;) string(0,IN;) string(0,DF;) \
+ string(0,BPINPS;) \
+ (contains(0,128,<1B>%-12345X) + \
+ (contains(0,1024,"LANGUAGE=HPGL") \
+ contains(0,1024,"LANGUAGE = HPGL")))
+
+########################################################################
+#
+# Image files...
+#
+
+image/gif gif string(0,GIF87a) string(0,GIF89a)
+image/png png string(0,<89>PNG)
+image/jpeg jpeg jpg jpe string(0,<FFD8FF>) &&\
+ (char(3,0xe0) char(3,0xe1) char(3,0xe2) char(3,0xe3)\
+ char(3,0xe4) char(3,0xe5) char(3,0xe6) char(3,0xe7)\
+ char(3,0xe8) char(3,0xe9) char(3,0xea) char(3,0xeb)\
+ char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef))
+image/tiff tiff tif string(0,MM) string(0,II)
+image/x-photocd pcd string(2048,PCD_IPI)
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm string(0,P1) string(0,P4)
+image/x-portable-graymap pgm string(0,P2) string(0,P5)
+image/x-portable-pixmap ppm string(0,P3) string(0,P6)
+image/x-sgi-rgb rgb sgi bw icon short(0,474)
+image/x-xbitmap xbm
+image/x-xpixmap xpm ascii(0,1024) + string(3,"XPM")
+image/x-xwindowdump xwd
+image/x-sun-raster ras string(0,<59a66a95>)
+
+#image/fpx fpx
+image/x-alias pix short(8,8) short(8,24)
+image/x-bitmap bmp string(0,BM) && !printable(2,14)
+
+########################################################################
+#
+# Text files...
+#
+
+text/html html htm printable(0,1024) +\
+ (string(0,"<HTML>") string(0,"<!DOCTYPE"))
+application/x-cshell csh printable(0,1024) + string(0,#!) +\
+ (contains(2,80,/csh) contains(2,80,/tcsh))
+application/x-perl pl printable(0,1024) + string(0,#!) +\
+ contains(2,80,/perl)
+application/x-shell sh printable(0,1024) + string(0,#!) +\
+ (contains(2,80,/bash) contains(2,80,/ksh)\
+ contains(2,80,/sh) contains(2,80,/zsh))
+text/plain txt printable(0,1024)
+
+########################################################################
+#
+# CUPS-specific types...
+#
+
+application/vnd.cups-form string(0,"<CUPSFORM>")
+application/vnd.cups-postscript contains(0,128,<1B>%-12345X) + \
+ (contains(0,1024,"LANGUAGE=POSTSCRIPT") \
+ contains(0,1024,"LANGUAGE = Postscript") \
+ contains(0,1024,"LANGUAGE = POSTSCRIPT"))
+application/vnd.cups-raster string(0,"RaSt") string(0,"tSaR")
+application/vnd.cups-raw (string(0,<1B>E) + !string(2,<1B>%0B)) \
+ string(0,<1B>@) \
+ (contains(0,128,<1B>%-12345X) + \
+ (contains(0,1024,"LANGUAGE=PCL") \
+ contains(0,1024,"LANGUAGE = PCL")))
+
+########################################################################
+#
+# Raw print file support...
+#
+# Uncomment the following type and the application/octet-stream
+# filter line in mime.convs to allow raw file printing without the
+# -oraw option.
+#
+
+#application/octet-stream
+
+#
+# End of "$Id: mime.types 2599 2002-08-09 00:00:55Z mike $".
+#
diff --git a/conf/pam.conf.in b/conf/pam.conf.in
new file mode 100644
index 000000000..3ddcdd0d3
--- /dev/null
+++ b/conf/pam.conf.in
@@ -0,0 +1,2 @@
+auth required @PAMMOD@ nullok shadow
+account required @PAMMOD@
diff --git a/conf/pam.irix b/conf/pam.irix
new file mode 100644
index 000000000..476383acb
--- /dev/null
+++ b/conf/pam.irix
@@ -0,0 +1,3 @@
+#%PAM-1.0
+auth required pam_unix.so shadow nodelay nullok
+account required pam_unix.so
diff --git a/conf/printcap b/conf/printcap
new file mode 100644
index 000000000..230c3017d
--- /dev/null
+++ b/conf/printcap
@@ -0,0 +1,2 @@
+# This is a dummy printcap file that is automatically generated by the
+# CUPS software for old applications that rely on it.
diff --git a/conf/printers.conf b/conf/printers.conf
new file mode 100644
index 000000000..c69067569
--- /dev/null
+++ b/conf/printers.conf
@@ -0,0 +1,96 @@
+#
+# "$Id: printers.conf 2010 2002-01-02 17:59:21Z mike $"
+#
+# Sample printer configuration file for the Common UNIX Printing System
+# (CUPS) scheduler.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+########################################################################
+# #
+# This is a sample printer configuration file. This file is included #
+# from the main configuration file (cups.conf) and lists all of the #
+# printers known to the system. #
+# #
+########################################################################
+
+#
+# Each printer starts with a <Printer name> definition. Printer names
+# can be up to 128 characters in length and are *not* case sensitive.
+#
+# One <DefaultPrinter name> entry can appear in this file; if you don't
+# define a default destination, the first printer or class becomes the
+# default.
+#
+
+#<Printer sample>
+#
+# Info: the description for the printer.
+#
+
+#Info Acme LaserPrint 1000
+
+#
+# Location: the location of the printer.
+#
+
+#Location Room 101 in the activities building
+
+#
+# DeviceURI: the device URI for this printer.
+#
+
+#DeviceURI parallel:/dev/plp
+#DeviceURI serial:/dev/ttyd1?baud=38400+size=8+parity=none+flow=soft
+#DeviceURI scsi:/dev/scsi/sc1d6l0
+#DeviceURI socket://hostname:port
+#DeviceURI tftp://hostname/path
+#DeviceURI ftp://hostname/path
+#DeviceURI http://hostname[:port]/path
+#DeviceURI ipp://hostname/path
+#DeviceURI smb://hostname/printer
+
+#
+# State: sets the initial state of the printer. Can be one of the
+# following:
+#
+# Idle - Printer is available to print new jobs.
+# Stopped - Printer is disabled but accepting new jobs.
+#
+
+#State Idle
+
+#
+# StateMessage: sets the printer-state-message attribute for the printer.
+#
+
+#StateMessage Printer is idle.
+
+#
+# Accepting: is the printer accepting jobs?
+#
+#Accepting Yes
+#Accepting No
+
+#</Printer>
+
+#
+# End of "$Id: printers.conf 2010 2002-01-02 17:59:21Z mike $".
+#
diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4
new file mode 100644
index 000000000..834d44e31
--- /dev/null
+++ b/config-scripts/cups-common.m4
@@ -0,0 +1,162 @@
+dnl
+dnl "$Id: cups-common.m4 2509 2002-06-12 11:29:48Z mike $"
+dnl
+dnl Common configuration stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+dnl We need at least autoconf 2.50...
+AC_PREREQ(2.50)
+
+dnl Set the name of the config header file...
+AC_CONFIG_HEADER(config.h)
+
+dnl Default compiler flags...
+CFLAGS="${CFLAGS:=}"
+CPPFLAGS="${CPPFLAGS:=}"
+CXXFLAGS="${CXXFLAGS:=}"
+LDFLAGS="${LDFLAGS:=}"
+
+dnl Checks for programs...
+AC_PROG_AWK
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_CPP
+AC_PROG_INSTALL
+if test "$INSTALL" = "$ac_install_sh"; then
+ # Use full path to install-sh script...
+ INSTALL="`pwd`/install-sh -c"
+fi
+AC_PROG_RANLIB
+AC_PATH_PROG(AR,ar)
+AC_PATH_PROG(HTMLDOC,htmldoc)
+AC_PATH_PROG(MV,mv)
+AC_PATH_PROG(NROFF,nroff)
+if test "$NROFF" = ""; then
+ AC_PATH_PROG(GROFF,groff)
+ if test "$GROFF" = ""; then
+ NROFF="echo"
+ else
+ NROFF="$GROFF -T ascii"
+ fi
+fi
+AC_PATH_PROG(RM,rm)
+AC_PATH_PROG(SED,sed)
+AC_PATH_PROG(STRIP,strip)
+
+dnl Architecture checks...
+AC_C_BIGENDIAN
+
+dnl Check for libraries...
+AC_SEARCH_LIBS(crypt, crypt)
+AC_SEARCH_LIBS(getspent, sec gen)
+
+LIBMALLOC=""
+AC_ARG_ENABLE(mallinfo, [ --enable-mallinfo turn on malloc debug information, default=no])
+
+if test x$enable_mallinfo = xyes; then
+ AC_CHECK_LIB(c,mallinfo,LIBS="$LIBS"; AC_DEFINE(HAVE_MALLINFO),LIBS="$LIBS")
+ if test "$ac_cv_lib_c_mallinfo" = "no"; then
+ AC_CHECK_LIB(malloc,mallinfo,
+ LIBS="$LIBS"
+ LIBMALLOC="-lmalloc"
+ AC_DEFINE(HAVE_MALLINFO),
+ LIBS="$LIBS")
+ fi
+fi
+
+AC_SUBST(LIBMALLOC)
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_DIRENT
+AC_CHECK_HEADER(crypt.h,AC_DEFINE(HAVE_CRYPT_H))
+AC_CHECK_HEADER(malloc.h,AC_DEFINE(HAVE_MALLOC_H))
+AC_CHECK_HEADER(shadow.h,AC_DEFINE(HAVE_SHADOW_H))
+AC_CHECK_HEADER(string.h,AC_DEFINE(HAVE_STRING_H))
+AC_CHECK_HEADER(strings.h,AC_DEFINE(HAVE_STRINGS_H))
+AC_CHECK_HEADER(bstring.h,AC_DEFINE(HAVE_BSTRING_H))
+AC_CHECK_HEADER(usersec.h,AC_DEFINE(HAVE_USERSEC_H))
+AC_CHECK_HEADER(sys/ioctl.h,AC_DEFINE(HAVE_SYS_IOCTL_H))
+
+dnl Checks for string functions.
+AC_CHECK_FUNCS(strdup strcasecmp strncasecmp strlcat strlcpy)
+if test "$uname" = "HP-UX" -a "$uversion" = "1020"; then
+ echo Forcing snprintf emulation for HP-UX.
+else
+ AC_CHECK_FUNCS(snprintf vsnprintf)
+fi
+
+dnl Check OS version and use appropriate format string for strftime...
+AC_MSG_CHECKING(for correct format string to use with strftime)
+
+case "$uname" in
+ IRIX* | SunOS*)
+ # IRIX and SunOS
+ AC_MSG_RESULT(NULL)
+ AC_DEFINE(CUPS_STRFTIME_FORMAT, NULL)
+ ;;
+ *)
+ # All others
+ AC_MSG_RESULT("%c")
+ AC_DEFINE(CUPS_STRFTIME_FORMAT, "%c")
+ ;;
+esac
+
+dnl Checks for mkstemp and mkstemps functions.
+AC_CHECK_FUNCS(mkstemp mkstemps)
+
+dnl Checks for vsyslog function.
+AC_CHECK_FUNCS(vsyslog)
+
+dnl Checks for signal functions.
+if test "$uname" != "Linux"; then
+ AC_CHECK_FUNCS(sigset)
+fi
+
+AC_CHECK_FUNCS(sigaction)
+
+dnl Checks for wait functions.
+AC_CHECK_FUNCS(waitpid)
+AC_CHECK_FUNCS(wait3)
+
+dnl See if the tm structure has the tm_gmtoff member...
+AC_MSG_CHECKING(for tm_gmtoff member in tm structure)
+AC_TRY_COMPILE([#include <time.h>],[struct tm t;
+ int o = t.tm_gmtoff;],
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_TM_GMTOFF),
+ AC_MSG_RESULT(no))
+
+dnl Flags for "ar" command...
+case $uname in
+ Darwin* | *BSD*)
+ ARFLAGS="-rcv"
+ ;;
+ *)
+ ARFLAGS="crvs"
+ ;;
+esac
+
+AC_SUBST(ARFLAGS)
+
+dnl
+dnl End of "$Id: cups-common.m4 2509 2002-06-12 11:29:48Z mike $".
+dnl
diff --git a/config-scripts/cups-compiler.m4 b/config-scripts/cups-compiler.m4
new file mode 100644
index 000000000..05ccc6864
--- /dev/null
+++ b/config-scripts/cups-compiler.m4
@@ -0,0 +1,194 @@
+dnl
+dnl "$Id: cups-compiler.m4 2564 2002-07-17 17:30:13Z mike $"
+dnl
+dnl Common configuration stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+dnl Clear the debugging and non-shared library options unless the user asks
+dnl for them...
+
+OPTIM=""
+AC_SUBST(OPTIM)
+
+AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging, default=no],
+ [if test x$enable_debug = xyes; then
+ OPTIM="-g"
+ fi])
+
+AC_ARG_WITH(optim, [ --with-optim="flags" set optimization flags ])
+
+dnl Update compiler options...
+CXXLIBS=""
+AC_SUBST(CXXLIBS)
+
+if test -n "$GCC"; then
+ # Starting with GCC 3.0, you must link C++ programs against either
+ # libstdc++ (shared by default), or libsupc++ (always static). If
+ # you care about binary portability between Linux distributions,
+ # you need to either 1) build your own GCC with static C++ libraries
+ # or 2) link using gcc and libsupc++. We choose the latter since
+ # CUPS doesn't (currently) use any of the stdc++ library.
+ #
+ # Also, GCC 3.0.x still has problems compiling some code. You may
+ # or may not have success with it. USE 3.0.x WITH EXTREME CAUTION!
+ #
+ # Previous versions of GCC do not have the reliance on the stdc++
+ # or g++ libraries, so the extra supc++ library is not needed.
+
+ AC_MSG_CHECKING(if libsupc++ is required)
+
+ SUPC="`$CXX -print-file-name=libsupc++.a 2>/dev/null`"
+ case "$SUPC" in
+ libsupc++.a*)
+ # Library not found, so this is and older GCC...
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ # This is gcc 3.x, and it knows of libsupc++, so we need it
+ LIBS="$LIBS -lsupc++"
+ AC_MSG_RESULT(yes)
+ ;;
+ esac
+
+ CXX="$CC"
+
+ if test -z "$OPTIM"; then
+ if test "x$with_optim" = x; then
+ if test $uname = HP-UX; then
+ # GCC under HP-UX has bugs with -O2
+ OPTIM="-O1"
+ else
+ OPTIM="-O2"
+ fi
+ else
+ OPTIM="$with_optim $OPTIM"
+ fi
+ fi
+
+ if test $PICFLAG = 1 -a $uname != AIX; then
+ OPTIM="-fPIC $OPTIM"
+ fi
+
+ if test "x$with_optim" = x; then
+ OPTIM="-Wall $OPTIM"
+ fi
+else
+ case $uname in
+ AIX*)
+ if test -z "$OPTIM"; then
+ if test "x$with_optim" = x; then
+ OPTIM="-O2 -qmaxmem=6000"
+ else
+ OPTIM="$with_optim $OPTIM"
+ fi
+ fi
+ ;;
+ HP-UX*)
+ if test -z "$OPTIM"; then
+ if test "x$with_optim" = x; then
+ OPTIM="+O2"
+ else
+ OPTIM="$with_optim $OPTIM"
+ fi
+ fi
+
+ CFLAGS="-Ae $CFLAGS"
+
+ if test "x$with_optim" = x; then
+ OPTIM="+DAportable $OPTIM"
+ fi
+
+ if test $PICFLAG = 1; then
+ OPTIM="+z $OPTIM"
+ fi
+ ;;
+ IRIX*)
+ if test -z "$OPTIM"; then
+ if test "x$with_optim" = x; then
+ OPTIM="-O2"
+ else
+ OPTIM="$with_optim $OPTIM"
+ fi
+ fi
+
+ if test $uversion -ge 62 -a "x$with_optim" = x; then
+ OPTIM="$OPTIM -n32 -mips3"
+ fi
+
+ if test "x$with_optim" = x; then
+ OPTIM="-fullwarn $OPTIM"
+ fi
+ ;;
+ SunOS*)
+ # Solaris
+ if test -z "$OPTIM"; then
+ if test "x$with_optim" = x; then
+ OPTIM="-xO4"
+ else
+ OPTIM="$with_optim $OPTIM"
+ fi
+ fi
+
+ if test "x$with_optim" = x; then
+ OPTIM="$OPTIM -xarch=generic"
+ fi
+
+ if test $PICFLAG = 1; then
+ OPTIM="-KPIC $OPTIM"
+ fi
+ ;;
+ UNIX_SVR*)
+ # UnixWare
+ if test -z "$OPTIM"; then
+ if test "x$with_optim" = x; then
+ OPTIM="-O"
+ else
+ OPTIM="$with_optim $OPTIM"
+ fi
+ fi
+
+ if test $PICFLAG = 1; then
+ OPTIM="-KPIC $OPTIM"
+ fi
+ ;;
+ *)
+ # Running some other operating system; inform the user they
+ # should contribute the necessary options to
+ # cups-support@cups.org...
+ echo "Building CUPS with default compiler optimizations; contact"
+ echo "cups-bugs@cups.org with uname and compiler options needed"
+ echo "for your platform, or set the CFLAGS and CXXFLAGS"
+ echo "environment variable before running configure."
+ ;;
+ esac
+fi
+
+case $uname in
+ *BSD | Darwin*)
+ ARFLAGS="-rcv"
+ ;;
+ *)
+ ARFLAGS="crvs"
+ ;;
+esac
+
+dnl
+dnl End of "$Id: cups-compiler.m4 2564 2002-07-17 17:30:13Z mike $".
+dnl
diff --git a/config-scripts/cups-directories.m4 b/config-scripts/cups-directories.m4
new file mode 100644
index 000000000..2fb63459f
--- /dev/null
+++ b/config-scripts/cups-directories.m4
@@ -0,0 +1,238 @@
+dnl
+dnl "$Id: cups-directories.m4 2138 2002-02-12 19:05:39Z mike $"
+dnl
+dnl Directory stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+AC_PREFIX_DEFAULT(/)
+
+AC_ARG_WITH(fontpath, [ --with-fontpath set font path for pstoraster],fontpath="$withval",fontpath="")
+AC_ARG_WITH(docdir, [ --with-docdir set path for documentation],docdir="$withval",docdir="")
+AC_ARG_WITH(logdir, [ --with-logdir set path for log files],logdir="$withval",logdir="")
+AC_ARG_WITH(rcdir, [ --with-rcdir set path for rc scripts],rcdir="$withval",rcdir="")
+
+dnl Fix "prefix" variable if it hasn't been specified...
+if test "$prefix" = "NONE"; then
+ prefix="/"
+fi
+
+dnl Fix "exec_prefix" variable if it hasn't been specified...
+if test "$exec_prefix" = "NONE"; then
+ if test "$prefix" = "/"; then
+ exec_prefix="/usr"
+ else
+ exec_prefix="$prefix"
+ fi
+fi
+
+dnl Fix "sharedstatedir" variable if it hasn't been specified...
+if test "$sharedstatedir" = "\${prefix}/com" -a "$prefix" = "/"; then
+ sharedstatedir="/usr/com"
+fi
+
+dnl Fix "datadir" variable if it hasn't been specified...
+if test "$datadir" = "\${prefix}/share"; then
+ if test "$prefix" = "/"; then
+ datadir="/usr/share"
+ else
+ datadir="$prefix/share"
+ fi
+fi
+
+dnl Fix "includedir" variable if it hasn't been specified...
+if test "$includedir" = "\${prefix}/include" -a "$prefix" = "/"; then
+ includedir="/usr/include"
+fi
+
+dnl Fix "localstatedir" variable if it hasn't been specified...
+if test "$localstatedir" = "\${prefix}/var"; then
+ if test "$prefix" = "/"; then
+ localstatedir="/var"
+ else
+ localstatedir="$prefix/var"
+ fi
+fi
+
+dnl Fix "sysconfdir" variable if it hasn't been specified...
+if test "$sysconfdir" = "\${prefix}/etc"; then
+ if test "$prefix" = "/"; then
+ sysconfdir="/etc"
+ else
+ sysconfdir="$prefix/etc"
+ fi
+fi
+
+dnl Fix "libdir" variable for IRIX 6.x...
+if test "$uname" = "IRIX" -a $uversion -ge 62; then
+ libdir="$exec_prefix/lib32"
+fi
+
+dnl Fix "fontpath" variable...
+if test "x$fontpath" = "x"; then
+ fontpath="$datadir/cups/fonts"
+fi
+
+dnl Setup init.d locations...
+if test x$rcdir = x; then
+ case "$uname" in
+ FreeBSD* | OpenBSD*)
+ # FreeBSD and OpenBSD
+ INITDIR=""
+ INITDDIR=""
+ ;;
+
+ NetBSD*)
+ # NetBSD
+ INITDIR=""
+ INITDDIR="/etc/rc.d"
+ ;;
+
+ Darwin*)
+ # Darwin and MacOS X...
+ INITDIR=""
+ INITDDIR="/System/Library/StartupItems/PrintingServices"
+ ;;
+
+ Linux*)
+ # Linux seems to choose an init.d directory at random...
+ if test -d /sbin/init.d; then
+ # SuSE
+ INITDIR="/sbin/init.d"
+ INITDDIR=".."
+ else
+ if test -d /etc/rc.d; then
+ # RedHat
+ INITDIR="/etc/rc.d"
+ INITDDIR="../init.d"
+ else
+ # Others
+ INITDIR="/etc"
+ INITDDIR="../init.d"
+ fi
+ fi
+ ;;
+
+ OSF1* | HP-UX*)
+ INITDIR="/sbin"
+ INITDDIR="../init.d"
+ ;;
+
+ AIX*)
+ INITDIR="/etc/rc.d"
+ INITDDIR=".."
+ ;;
+
+ *)
+ INITDIR="/etc"
+ INITDDIR="../init.d"
+ ;;
+
+ esac
+else
+ INITDIR=""
+ INITDDIR="$rcdir"
+fi
+
+AC_SUBST(INITDIR)
+AC_SUBST(INITDDIR)
+
+dnl Setup default locations...
+CUPS_SERVERROOT="$sysconfdir/cups"
+CUPS_REQUESTS="$localstatedir/spool/cups"
+
+AC_DEFINE_UNQUOTED(CUPS_SERVERROOT, "$sysconfdir/cups")
+AC_DEFINE_UNQUOTED(CUPS_REQUESTS, "$localstatedir/spool/cups")
+
+if test x$logdir = x; then
+ CUPS_LOGDIR="$localstatedir/log/cups"
+ AC_DEFINE_UNQUOTED(CUPS_LOGDIR, "$localstatedir/log/cups")
+else
+ CUPS_LOGDIR="$logdir"
+ AC_DEFINE_UNQUOTED(CUPS_LOGDIR, "$logdir")
+fi
+
+dnl See what directory to put server executables...
+case "$uname" in
+ *BSD* | Darwin*)
+ # *BSD and Darwin (MacOS X)
+ INSTALL_SYSV=""
+ CUPS_SERVERBIN="$exec_prefix/libexec/cups"
+ AC_DEFINE_UNQUOTED(CUPS_SERVERBIN, "$exec_prefix/libexec/cups")
+ ;;
+ *)
+ # All others
+ INSTALL_SYSV="install-sysv"
+ CUPS_SERVERBIN="$exec_prefix/lib/cups"
+ AC_DEFINE_UNQUOTED(CUPS_SERVERBIN, "$exec_prefix/lib/cups")
+ ;;
+esac
+
+AC_SUBST(INSTALL_SYSV)
+AC_SUBST(CUPS_SERVERROOT)
+AC_SUBST(CUPS_SERVERBIN)
+AC_SUBST(CUPS_LOGDIR)
+AC_SUBST(CUPS_REQUESTS)
+
+dnl Set the CUPS_LOCALE directory...
+case "$uname" in
+ Linux* | *BSD* | Darwin*)
+ CUPS_LOCALEDIR="$datadir/locale"
+ AC_DEFINE_UNQUOTED(CUPS_LOCALEDIR, "$datadir/locale")
+ ;;
+
+ OSF1* | AIX*)
+ CUPS_LOCALEDIR="$exec_prefix/lib/nls/msg"
+ AC_DEFINE_UNQUOTED(CUPS_LOCALEDIR, "$exec_prefix/lib/nls/msg")
+ ;;
+
+ *)
+ # This is the standard System V location...
+ CUPS_LOCALEDIR="$exec_prefix/lib/locale"
+ AC_DEFINE_UNQUOTED(CUPS_LOCALEDIR, "$exec_prefix/lib/locale")
+ ;;
+esac
+
+AC_SUBST(CUPS_LOCALEDIR)
+
+dnl Set the CUPS_DATADIR directory...
+CUPS_DATADIR="$datadir/cups"
+AC_DEFINE_UNQUOTED(CUPS_DATADIR, "$datadir/cups")
+AC_SUBST(CUPS_DATADIR)
+
+dnl Set the CUPS_DOCROOT directory...
+if test x$docdir = x; then
+ CUPS_DOCROOT="$datadir/doc/cups"
+ docdir="$datadir/doc/cups"
+else
+ CUPS_DOCROOT="$docdir"
+fi
+
+AC_DEFINE_UNQUOTED(CUPS_DOCROOT, "$docdir")
+AC_SUBST(CUPS_DOCROOT)
+
+dnl Set the CUPS_FONTPATH directory...
+CUPS_FONTPATH="$fontpath"
+AC_SUBST(CUPS_FONTPATH)
+AC_DEFINE_UNQUOTED(CUPS_FONTPATH, "$fontpath")
+
+dnl
+dnl End of "$Id: cups-directories.m4 2138 2002-02-12 19:05:39Z mike $".
+dnl
diff --git a/config-scripts/cups-image.m4 b/config-scripts/cups-image.m4
new file mode 100644
index 000000000..8c2d6a948
--- /dev/null
+++ b/config-scripts/cups-image.m4
@@ -0,0 +1,82 @@
+dnl
+dnl "$Id: cups-image.m4 2491 2002-06-06 19:39:37Z mike $"
+dnl
+dnl Image library stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+dnl Save the current libraries since we don't want the image libraries
+dnl included with every program...
+SAVELIBS="$LIBS"
+
+dnl Check for image libraries...
+LIBJPEG=""
+LIBPNG=""
+LIBTIFF=""
+LIBZ=""
+
+AC_SUBST(LIBJPEG)
+AC_SUBST(LIBPNG)
+AC_SUBST(LIBTIFF)
+AC_SUBST(LIBZ)
+
+AC_CHECK_HEADER(jpeglib.h,
+ AC_CHECK_LIB(jpeg, jpeg_destroy_decompress,
+ AC_DEFINE(HAVE_LIBJPEG)
+ LIBJPEG="-ljpeg"
+ LIBS="$LIBS -ljpeg"))
+
+AC_CHECK_HEADER(zlib.h,
+ AC_CHECK_LIB(z, gzgets,
+ AC_DEFINE(HAVE_LIBZ)
+ LIBZ="-lz"
+ LIBS="$LIBS -lz"))
+
+dnl PNG library uses math library functions...
+AC_CHECK_LIB(m, pow)
+
+AC_CHECK_HEADER(png.h,
+ AC_CHECK_LIB(png, png_set_tRNS_to_alpha,
+ AC_DEFINE(HAVE_LIBPNG)
+ LIBPNG="-lpng -lm"))
+
+AC_CHECK_HEADER(tiff.h,
+ AC_CHECK_LIB(tiff, TIFFReadScanline,
+ AC_DEFINE(HAVE_LIBTIFF)
+ LIBTIFF="-ltiff"))
+
+dnl Restore original LIBS settings...
+LIBS="$SAVELIBS"
+
+EXPORT_LIBJPEG="$LIBJPEG"
+EXPORT_LIBPNG="$LIBPNG"
+EXPORT_LIBTIFF="$LIBTIFF"
+EXPORT_LIBZ="$LIBZ"
+
+AC_SUBST(EXPORT_LIBJPEG)
+AC_SUBST(EXPORT_LIBPNG)
+AC_SUBST(EXPORT_LIBTIFF)
+AC_SUBST(EXPORT_LIBZ)
+
+AC_CHECK_HEADER(stdlib.h,AC_DEFINE(HAVE_STDLIB_H))
+
+dnl
+dnl End of "$Id: cups-image.m4 2491 2002-06-06 19:39:37Z mike $".
+dnl
diff --git a/config-scripts/cups-libtool.m4 b/config-scripts/cups-libtool.m4
new file mode 100644
index 000000000..a9cc37967
--- /dev/null
+++ b/config-scripts/cups-libtool.m4
@@ -0,0 +1,49 @@
+dnl
+dnl "$Id: cups-libtool.m4 2476 2002-06-04 20:58:55Z mike $"
+dnl
+dnl Libtool stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+AC_ARG_ENABLE(libtool_unsupported, [ --enable-libtool-unsupported=LIBTOOL_PATH
+ turn on building with libtool (UNSUPPORTED!), default=no],
+ [if test x$enable_libtool_unsupported != xno; then
+ LIBTOOL="$enable_libtool_unsupported"
+ enable_shared=no
+ echo "WARNING: libtool is not supported or endorsed by Easy Software Products."
+ echo " WE DO NOT PROVIDE TECHNICAL SUPPORT FOR LIBTOOL PROBLEMS."
+ echo " (even if you have a support contract)"
+ else
+ LIBTOOL=""
+ fi])
+
+AC_SUBST(LIBTOOL)
+
+if test x$LIBTOOL != x; then
+ LIBCUPS="libcups.la"
+ LIBCUPSIMAGE="libcupsimage.la"
+ LINKCUPS="../cups/\$(LIBCUPS)"
+ LINKCUPSIMAGE="../filter/\$(LIBCUPSIMAGE)"
+ DSO="\$(CC)"
+fi
+
+dnl
+dnl End of "$Id: cups-libtool.m4 2476 2002-06-04 20:58:55Z mike $".
+dnl
diff --git a/config-scripts/cups-manpages.m4 b/config-scripts/cups-manpages.m4
new file mode 100644
index 000000000..9253d1305
--- /dev/null
+++ b/config-scripts/cups-manpages.m4
@@ -0,0 +1,104 @@
+dnl
+dnl "$Id: cups-manpages.m4 2013 2002-01-02 18:50:43Z mike $"
+dnl
+dnl Manpage stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+dnl Fix "mandir" variable...
+if test "$mandir" = "\${prefix}/man" -a "$prefix" = "/"; then
+ case "$uname" in
+ Darwin* | Linux* | *BSD* | AIX*)
+ # Darwin, MacOS X, Linux, *BSD, and AIX
+ mandir="/usr/share/man"
+ AMANDIR="/usr/share/man"
+ PMANDIR="/usr/share/man"
+ ;;
+ IRIX*)
+ # SGI IRIX
+ mandir="/usr/share/catman/u_man"
+ AMANDIR="/usr/share/catman/a_man"
+ PMANDIR="/usr/share/catman/p_man"
+ ;;
+ *)
+ # All others
+ mandir="/usr/man"
+ AMANDIR="/usr/man"
+ PMANDIR="/usr/man"
+ ;;
+ esac
+else
+ AMANDIR="$mandir"
+ PMANDIR="$mandir"
+fi
+
+AC_SUBST(AMANDIR)
+AC_SUBST(PMANDIR)
+
+dnl Setup manpage extensions...
+case "$uname" in
+ *BSD* | Darwin*)
+ # *BSD
+ CAT1EXT=0
+ CAT3EXT=0
+ CAT5EXT=0
+ CAT8EXT=0
+ MAN8EXT=8
+ MAN8DIR=8
+ ;;
+ IRIX*)
+ # SGI IRIX
+ CAT1EXT=z
+ CAT3EXT=z
+ CAT5EXT=z
+ CAT8EXT=z
+ MAN8EXT=1m
+ MAN8DIR=1
+ ;;
+ SunOS* | HP-UX*)
+ # Solaris and HP-UX
+ CAT1EXT=1
+ CAT3EXT=3
+ CAT5EXT=5
+ CAT8EXT=1m
+ MAN8EXT=1m
+ MAN8DIR=1m
+ ;;
+ *)
+ # All others
+ CAT1EXT=1
+ CAT3EXT=3
+ CAT5EXT=5
+ CAT8EXT=8
+ MAN8EXT=8
+ MAN8DIR=8
+ ;;
+esac
+
+AC_SUBST(CAT1EXT)
+AC_SUBST(CAT3EXT)
+AC_SUBST(CAT5EXT)
+AC_SUBST(CAT8EXT)
+AC_SUBST(MAN8EXT)
+AC_SUBST(MAN8DIR)
+
+dnl
+dnl End of "$Id: cups-manpages.m4 2013 2002-01-02 18:50:43Z mike $".
+dnl
diff --git a/config-scripts/cups-network.m4 b/config-scripts/cups-network.m4
new file mode 100644
index 000000000..dcd86a8e2
--- /dev/null
+++ b/config-scripts/cups-network.m4
@@ -0,0 +1,41 @@
+dnl
+dnl "$Id: cups-network.m4 2309 2002-03-28 22:13:20Z mike $"
+dnl
+dnl Networking stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+NETLIBS=""
+
+if test "$uname" != "IRIX"; then
+ AC_CHECK_LIB(socket,socket,NETLIBS="-lsocket")
+ AC_CHECK_LIB(nsl,gethostbyaddr,NETLIBS="$NETLIBS -lnsl")
+fi
+
+AC_CHECK_FUNCS(rresvport getifaddrs)
+
+AC_CHECK_MEMBER(struct sockaddr.sa_len,,,[#include <sys/socket.h>])
+AC_CHECK_HEADER(sys/sockio.h,AC_DEFINE(HAVE_SYS_SOCKIO_H))
+
+AC_SUBST(NETLIBS)
+
+dnl
+dnl End of "$Id: cups-network.m4 2309 2002-03-28 22:13:20Z mike $".
+dnl
diff --git a/config-scripts/cups-openslp.m4 b/config-scripts/cups-openslp.m4
new file mode 100644
index 000000000..8126e5923
--- /dev/null
+++ b/config-scripts/cups-openslp.m4
@@ -0,0 +1,48 @@
+dnl
+dnl "$Id: cups-openslp.m4 2476 2002-06-04 20:58:55Z mike $"
+dnl
+dnl OpenSLP configuration stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+AC_ARG_ENABLE(slp, [ --enable-slp turn on SLP support, default=yes])
+AC_ARG_WITH(openslp-libs, [ --with-openslp-libs set directory for OpenSLP library],
+ LDFLAGS="-L$withval $LDFLAGS"
+ DSOFLAGS="-L$withval $DSOFLAGS",)
+AC_ARG_WITH(openslp-includes, [ --with-openslp-includes set directory for OpenSLP includes],
+ CFLAGS="-I$withval $CFLAGS"
+ CXXFLAGS="-I$withval $CXXFLAGS"
+ CPPFLAGS="-I$withval $CPPFLAGS",)
+
+LIBSLP=""
+
+if test x$enable_slp != xno; then
+ AC_CHECK_HEADER(slp.h,
+ AC_CHECK_LIB(slp, SLPOpen,
+ AC_DEFINE(HAVE_LIBSLP)
+ LIBSLP="-lslp"))
+fi
+
+AC_SUBST(LIBSLP)
+
+
+dnl
+dnl End of "$Id: cups-openslp.m4 2476 2002-06-04 20:58:55Z mike $".
+dnl
diff --git a/config-scripts/cups-openssl.m4 b/config-scripts/cups-openssl.m4
new file mode 100644
index 000000000..58e382400
--- /dev/null
+++ b/config-scripts/cups-openssl.m4
@@ -0,0 +1,74 @@
+dnl
+dnl "$Id: cups-openssl.m4 2491 2002-06-06 19:39:37Z mike $"
+dnl
+dnl OpenSSL stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+AC_ARG_ENABLE(ssl, [ --enable-ssl turn on SSL/TLS support, default=yes])
+AC_ARG_WITH(openssl-libs, [ --with-openssl-libs set directory for OpenSSL library],
+ LDFLAGS="-L$withval $LDFLAGS"
+ DSOFLAGS="-L$withval $DSOFLAGS",)
+AC_ARG_WITH(openssl-includes, [ --with-openssl-includes set directory for OpenSSL includes],
+ CFLAGS="-I$withval $CFLAGS"
+ CXXFLAGS="-I$withval $CXXFLAGS"
+ CPPFLAGS="-I$withval $CPPFLAGS",)
+
+SSLLIBS=""
+
+if test x$enable_ssl != xno; then
+ AC_CHECK_HEADER(openssl/ssl.h,
+ dnl Save the current libraries so the crypto stuff isn't always
+ dnl included...
+ SAVELIBS="$LIBS"
+
+ dnl Some ELF systems can't resolve all the symbols in libcrypto
+ dnl if libcrypto was linked against RSAREF, and fail to link the
+ dnl test program correctly, even though a correct installation
+ dnl of OpenSSL exists. So we test the linking three times in
+ dnl case the RSAREF libraries are needed.
+
+ for libcrypto in \
+ "-lcrypto" \
+ "-lcrypto -lrsaref" \
+ "-lcrypto -lRSAglue -lrsaref"
+ do
+ AC_CHECK_LIB(ssl,SSL_new,
+ [SSLLIBS="-lssl $libcrypto"
+ AC_DEFINE(HAVE_LIBSSL)],,
+ $libcrypto)
+
+ if test "x${SSLLIBS}" != "x"; then
+ break
+ fi
+ done
+
+ LIBS="$SAVELIBS")
+fi
+
+AC_SUBST(SSLLIBS)
+
+EXPORT_SSLLIBS="$SSLLIBS"
+AC_SUBST(EXPORT_SSLLIBS)
+
+
+dnl
+dnl End of "$Id: cups-openssl.m4 2491 2002-06-06 19:39:37Z mike $".
+dnl
diff --git a/config-scripts/cups-opsys.m4 b/config-scripts/cups-opsys.m4
new file mode 100644
index 000000000..61bb266a3
--- /dev/null
+++ b/config-scripts/cups-opsys.m4
@@ -0,0 +1,90 @@
+dnl
+dnl "$Id: cups-opsys.m4 2193 2002-03-08 19:49:00Z mike $"
+dnl
+dnl Operating system stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+dnl Get the operating system and version number...
+uname=`uname`
+uversion=`uname -r | sed -e '1,$s/[[^0-9]]//g'`
+if test x$uname = xIRIX64; then
+ uname="IRIX"
+fi
+
+dnl Determine the correct username and group for this OS...
+AC_ARG_WITH(cups-user, [ --with-cups-user set default user for CUPS],
+ CUPS_USER="$withval",
+ AC_MSG_CHECKING(for default print user)
+ if test -f /etc/passwd; then
+ CUPS_USER=""
+ for user in lp lpd guest daemon nobody; do
+ if test "`grep \^${user}: /etc/passwd`" != ""; then
+ CUPS_USER="$user"
+ AC_MSG_RESULT($user)
+ break;
+ fi
+ done
+
+ if test x$CUPS_USER = x; then
+ CUPS_USER="${USER:=nobody}"
+ AC_MSG_RESULT(not found, using "$CUPS_USER")
+ fi
+ else
+ CUPS_USER="${USER:=nobody}"
+ AC_MSG_RESULT(no password file, using "$CUPS_USER")
+ fi)
+
+AC_ARG_WITH(cups-group, [ --with-cups-group set default group for CUPS],
+ CUPS_GROUP="$withval",
+ AC_MSG_CHECKING(for default print group)
+ if test x$uname = xDarwin; then
+ CUPS_GROUP="admin"
+ AC_MSG_RESULT(Darwin, using "$CUPS_GROUP")
+ else
+ if test -f /etc/group; then
+ CUPS_GROUP=""
+ for group in sys system root; do
+ if test "`grep \^${group}: /etc/group`" != ""; then
+ CUPS_GROUP="$group"
+ AC_MSG_RESULT($group)
+ break;
+ fi
+ done
+
+ if test x$CUPS_GROUP = x; then
+ CUPS_GROUP="${GROUP:=nobody}"
+ AC_MSG_RESULT(not found, using "$CUPS_GROUP")
+ fi
+ else
+ CUPS_GROUP="${GROUP:=nobody}"
+ AC_MSG_RESULT(no group file, using "$CUPS_GROUP")
+ fi
+ fi)
+
+AC_SUBST(CUPS_USER)
+AC_SUBST(CUPS_GROUP)
+
+AC_DEFINE_UNQUOTED(CUPS_DEFAULT_USER, "$CUPS_USER")
+AC_DEFINE_UNQUOTED(CUPS_DEFAULT_GROUP, "$CUPS_GROUP")
+
+dnl
+dnl "$Id: cups-opsys.m4 2193 2002-03-08 19:49:00Z mike $"
+dnl
diff --git a/config-scripts/cups-pam.m4 b/config-scripts/cups-pam.m4
new file mode 100644
index 000000000..636680bab
--- /dev/null
+++ b/config-scripts/cups-pam.m4
@@ -0,0 +1,71 @@
+dnl
+dnl "$Id: cups-pam.m4 2756 2002-08-30 20:56:45Z mike $"
+dnl
+dnl PAM stuff for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+AC_ARG_ENABLE(pam, [ --enable-pam turn on PAM support, default=yes])
+
+dnl Don't use PAM with AIX...
+if test $uname = AIX; then
+ enable_pam=no
+fi
+
+PAMDIR=""
+PAMLIBS=""
+PAMMOD="pam_unknown.so"
+
+if test x$enable_pam != xno; then
+ SAVELIBS="$LIBS"
+
+ AC_CHECK_LIB(dl,dlopen)
+ AC_CHECK_LIB(pam,pam_start)
+ AC_CHECK_HEADER(pam/pam_appl.h,AC_DEFINE(HAVE_PAM_PAM_APPL_H))
+
+ if test x$ac_cv_lib_pam_pam_start != xno; then
+ if test x$ac_cv_lib_dl_dlopen != xno; then
+ PAMLIBS="-lpam -ldl"
+ else
+ PAMLIBS="-lpam"
+ fi
+ if test -d /etc/pam.d; then
+ PAMDIR="/etc/pam.d"
+ fi
+ fi
+
+ LIBS="$SAVELIBS"
+
+ # This test might need to be updated as Linux distributors move
+ # things around...
+ for mod in pam_unix2.so pam_unix.so pam_pwdb.so; do
+ if test -f /lib/security/$mod; then
+ PAMMOD="$mod"
+ fi
+ done
+fi
+
+AC_SUBST(PAMDIR)
+AC_SUBST(PAMLIBS)
+AC_SUBST(PAMMOD)
+
+dnl
+dnl End of "$Id: cups-pam.m4 2756 2002-08-30 20:56:45Z mike $".
+dnl
diff --git a/config-scripts/cups-sharedlibs.m4 b/config-scripts/cups-sharedlibs.m4
new file mode 100644
index 000000000..8e351c165
--- /dev/null
+++ b/config-scripts/cups-sharedlibs.m4
@@ -0,0 +1,149 @@
+dnl
+dnl "$Id: cups-sharedlibs.m4 2501 2002-06-07 21:02:33Z mike $"
+dnl
+dnl Shared library support for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+PICFLAG=1
+DSOFLAGS="${DSOFLAGS:=}"
+
+AC_ARG_ENABLE(shared, [ --enable-shared turn on shared libraries, default=yes])
+
+if test x$enable_shared != xno; then
+ case "$uname" in
+ SunOS* | UNIX_S*)
+ LIBCUPS="libcups.so.2"
+ LIBCUPSIMAGE="libcupsimage.so.2"
+ DSO="\$(CC)"
+ DSOFLAGS="$DSOFLAGS -Wl,-h,\$@ -G \$(OPTIM)"
+ ;;
+ HP-UX*)
+ LIBCUPS="libcups.sl.2"
+ LIBCUPSIMAGE="libcupsimage.sl.2"
+ DSO="ld"
+ DSOFLAGS="$DSOFLAGS -b -z +h \$@"
+ ;;
+ IRIX*)
+ LIBCUPS="libcups.so.2"
+ LIBCUPSIMAGE="libcupsimage.so.2"
+ DSO="\$(CC)"
+ DSOFLAGS="$DSOFLAGS -Wl,-rpath,\$(libdir),-set_version,sgi2.4,-soname,\$@ -shared \$(OPTIM)"
+ ;;
+ OSF1* | Linux* | *BSD*)
+ LIBCUPS="libcups.so.2"
+ LIBCUPSIMAGE="libcupsimage.so.2"
+ DSO="\$(CC)"
+ DSOFLAGS="$DSOFLAGS -Wl,-soname,\$@ -shared \$(OPTIM)"
+ ;;
+ Darwin*)
+ LIBCUPS="libcups.2.dylib"
+ LIBCUPSIMAGE="libcupsimage.2.dylib"
+ DSO="\$(CC)"
+ DSOFLAGS="$DSOFLAGS \$(RC_CFLAGS) -dynamiclib -lc"
+ ;;
+ AIX*)
+ LIBCUPS="libcups_s.a"
+ LIBCUPSIMAGE="libcupsimage_s.a"
+ DSO="\$(CC)"
+ DSOFLAGS="$DSOFLAGS -Wl,-bexpall,-bM:SRE,-bnoentry"
+ ;;
+ *)
+ echo "Warning: shared libraries may not be supported. Trying -shared"
+ echo " option with compiler."
+ LIBCUPS="libcups.so.2"
+ LIBCUPSIMAGE="libcupsimage.so.2"
+ DSO="\$(CC)"
+ DSOFLAGS="$DSOFLAGS -Wl,-soname,\$@ -shared \$(OPTIM)"
+ ;;
+ esac
+else
+ PICFLAG=0
+ LIBCUPS="libcups.a"
+ LIBCUPSIMAGE="libcupsimage.a"
+ DSO=":"
+fi
+
+AC_SUBST(DSO)
+AC_SUBST(DSOFLAGS)
+AC_SUBST(LIBCUPS)
+AC_SUBST(LIBCUPSIMAGE)
+
+if test x$enable_shared = xno; then
+ LINKCUPS="-lcups \$(SSLLIBS)"
+ LINKCUPSIMAGE="-lcupsimage"
+else
+ if test $uname = AIX; then
+ LINKCUPS="-lcups_s"
+ LINKCUPSIMAGE="-lcupsimage_s"
+ else
+ LINKCUPS="-lcups"
+ LINKCUPSIMAGE="-lcupsimage"
+ fi
+fi
+
+AC_SUBST(LINKCUPS)
+AC_SUBST(LINKCUPSIMAGE)
+
+dnl Update libraries for DSOs...
+if test "$DSO" != ":"; then
+ # When using DSOs the image libraries are linked to libcupsimage.so
+ # rather than to the executables. This makes things smaller if you
+ # are using any static libraries, and it also allows us to distribute
+ # a single DSO rather than a bunch...
+ DSOLIBS="\$(LIBPNG) \$(LIBTIFF) \$(LIBJPEG) \$(LIBZ)"
+ IMGLIBS=""
+
+ # The *BSD, HP-UX, and Solaris run-time linkers need help when
+ # deciding where to find a DSO. Add linker options to tell them
+ # where to find the DSO (usually in /usr/lib... duh!)
+ case $uname in
+ HP-UX*)
+ # HP-UX
+ DSOFLAGS="+s +b $libdir $DSOFLAGS"
+ LDFLAGS="$LDFLAGS -Wl,+s,+b,$libdir"
+ ;;
+ SunOS*)
+ # Solaris
+ DSOFLAGS="-R$libdir $DSOFLAGS"
+ LDFLAGS="$LDFLAGS -R$libdir"
+ ;;
+ *BSD*)
+ # *BSD
+ DSOFLAGS="-Wl,-R$libdir $DSOFLAGS"
+ LDFLAGS="$LDFLAGS -Wl,-R$libdir"
+ ;;
+ Linux*)
+ # Linux
+ DSOFLAGS="-Wl,-rpath,$libdir $DSOFLAGS"
+ LDFLAGS="$LDFLAGS -Wl,-rpath,$libdir"
+ ;;
+ esac
+else
+ DSOLIBS=""
+ IMGLIBS="\$(LIBPNG) \$(LIBTIFF) \$(LIBJPEG) \$(LIBZ)"
+fi
+
+AC_SUBST(DSOLIBS)
+AC_SUBST(IMGLIBS)
+
+dnl
+dnl End of "$Id: cups-sharedlibs.m4 2501 2002-06-07 21:02:33Z mike $".
+dnl
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 000000000..8bb2bc0be
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,240 @@
+/*
+ * "$Id$"
+ *
+ * Configuration file for the Common UNIX Printing System (CUPS).
+ *
+ * @configure_input@
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Version of software...
+ */
+
+#define CUPS_SVERSION "CUPS v1.1.16"
+
+
+/*
+ * Default user and group...
+ */
+
+#define CUPS_DEFAULT_USER "lp"
+#define CUPS_DEFAULT_GROUP "sys"
+
+
+/*
+ * Where are files stored?
+ */
+
+#define CUPS_LOCALEDIR "/usr/share/locale"
+#define CUPS_SERVERROOT "/etc/cups"
+#define CUPS_SERVERBIN "/usr/lib/cups"
+#define CUPS_DOCROOT "/usr/share/doc/cups"
+#define CUPS_REQUESTS "/var/spool/cups"
+#define CUPS_LOGDIR "/var/logs/cups"
+#define CUPS_DATADIR "/usr/share/cups"
+#define CUPS_FONTPATH "/usr/share/cups/fonts"
+
+
+/*
+ * What is the format string for strftime?
+ */
+
+#define CUPS_STRFTIME_FORMAT NULL
+
+
+/*
+ * Do we have various image libraries?
+ */
+
+#undef HAVE_LIBPNG
+#undef HAVE_LIBZ
+#undef HAVE_LIBJPEG
+#undef HAVE_LIBTIFF
+
+
+/*
+ * Does this machine store words in big-endian (MSB-first) order?
+ */
+
+#undef WORDS_BIGENDIAN
+
+
+/*
+ * Which directory functions and headers do we use?
+ */
+
+#undef HAVE_DIRENT_H
+#undef HAVE_SYS_DIR_H
+#undef HAVE_SYS_NDIR_H
+#undef HAVE_NDIR_H
+
+
+/*
+ * Do we have PAM stuff?
+ */
+
+#ifndef HAVE_LIBPAM
+#define HAVE_LIBPAM 0
+#endif /* !HAVE_LIBPAM */
+
+#undef HAVE_PAM_PAM_APPL_H
+
+
+/*
+ * Do we have <shadow.h>?
+ */
+
+#undef HAVE_SHADOW_H
+
+
+/*
+ * Do we have <crypt.h>?
+ */
+
+#undef HAVE_CRYPT_H
+
+
+/*
+ * Use <string.h>, <strings.h>, and/or <bstring.h>?
+ */
+
+#undef HAVE_STRING_H
+#undef HAVE_STRINGS_H
+#undef HAVE_BSTRING_H
+
+
+/*
+ * Do we have the strXXX() functions?
+ */
+
+#undef HAVE_STRDUP
+#undef HAVE_STRCASECMP
+#undef HAVE_STRNCASECMP
+#undef HAVE_STRLCAT
+#undef HAVE_STRLCPY
+
+
+/*
+ * Do we have the vsyslog() function?
+ */
+
+#undef HAVE_VSYSLOG
+
+
+/*
+ * Do we have the (v)snprintf() functions?
+ */
+
+#undef HAVE_SNPRINTF
+#undef HAVE_VSNPRINTF
+
+
+/*
+ * What signal functions to use?
+ */
+
+#undef HAVE_SIGSET
+#undef HAVE_SIGACTION
+
+
+/*
+ * What wait functions to use?
+ */
+
+#undef HAVE_WAITPID
+#undef HAVE_WAIT3
+
+
+/*
+ * Do we have the mallinfo function and malloc.h?
+ */
+
+#undef HAVE_MALLINFO
+#undef HAVE_MALLOC_H
+
+
+/*
+ * Do we have the OpenSSL library?
+ */
+
+#undef HAVE_LIBSSL
+
+
+/*
+ * Do we have the OpenSLP library?
+ */
+
+#undef HAVE_LIBSLP
+
+
+/*
+ * Do we have <sys/ioctl.h>?
+ */
+
+#undef HAVE_SYS_IOCTL_H
+
+
+/*
+ * Do we have mkstemp() and/or mkstemps()?
+ */
+
+#undef HAVE_MKSTEMP
+#undef HAVE_MKSTEMPS
+
+
+/*
+ * Does the "tm" structure contain the "tm_gmtoff" member?
+ */
+
+#undef HAVE_TM_GMTOFF
+
+
+/*
+ * Do we have rresvport()?
+ */
+
+#undef HAVE_RRESVPORT
+
+
+/*
+ * Do we have getifaddrs()?
+ */
+
+#undef HAVE_GETIFADDRS
+
+
+/*
+ * Do we have the <sys/sockio.h> header file?
+ */
+
+#undef HAVE_SYS_SOCKIO_H
+
+
+/*
+ * Does the sockaddr structure contain an sa_len parameter?
+ */
+
+#undef HAVE_STRUCT_SOCKADDR_SA_LEN
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/configure.in b/configure.in
new file mode 100644
index 000000000..7755aa33f
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,48 @@
+dnl
+dnl "$Id$"
+dnl
+dnl Configuration script for the Common UNIX Printing System (CUPS).
+dnl
+dnl Copyright 1997-2002 by Easy Software Products, all rights reserved.
+dnl
+dnl These coded instructions, statements, and computer programs are the
+dnl property of Easy Software Products and are protected by Federal
+dnl copyright law. Distribution and use rights are outlined in the file
+dnl "LICENSE.txt" which should have been included with this file. If this
+dnl file is missing or damaged please contact Easy Software Products
+dnl at:
+dnl
+dnl Attn: CUPS Licensing Information
+dnl Easy Software Products
+dnl 44141 Airport View Drive, Suite 204
+dnl Hollywood, Maryland 20636-3111 USA
+dnl
+dnl Voice: (301) 373-9603
+dnl EMail: cups-info@cups.org
+dnl WWW: http://www.cups.org
+dnl
+
+AC_INIT(cups/cups.h)
+
+sinclude(config-scripts/cups-opsys.m4)
+sinclude(config-scripts/cups-common.m4)
+sinclude(config-scripts/cups-directories.m4)
+sinclude(config-scripts/cups-manpages.m4)
+
+sinclude(config-scripts/cups-sharedlibs.m4)
+sinclude(config-scripts/cups-libtool.m4)
+sinclude(config-scripts/cups-compiler.m4)
+
+sinclude(config-scripts/cups-image.m4)
+sinclude(config-scripts/cups-network.m4)
+sinclude(config-scripts/cups-openslp.m4)
+sinclude(config-scripts/cups-openssl.m4)
+sinclude(config-scripts/cups-pam.m4)
+
+AC_OUTPUT(Makedefs cups.list cups.sh cups-config conf/cupsd.conf conf/pam.conf)
+
+chmod +x cups-config
+
+dnl
+dnl End of "$Id$".
+dnl
diff --git a/cups-config.in b/cups-config.in
new file mode 100755
index 000000000..63af443ad
--- /dev/null
+++ b/cups-config.in
@@ -0,0 +1,134 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# CUPS configuration utility.
+#
+# Copyright 2001 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+VERSION="1.1.16"
+APIVERSION="1.1"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+includedir=@includedir@
+libdir=@libdir@
+datadir=@datadir@
+sysconfdir=@sysconfdir@
+cups_datadir=@CUPS_DATADIR@
+cups_serverbin=@CUPS_SERVERBIN@
+cups_serverroot=@CUPS_SERVERROOT@
+
+# flags for C++ compiler:
+CFLAGS=""
+LDFLAGS=""
+LIBS="@EXPORT_SSLLIBS@ @NETLIBS@"
+IMGLIBS="@EXPORT_LIBTIFF@ @EXPORT_LIBJPEG@ @EXPORT_LIBPNG@ @EXPORT_LIBZ@"
+
+if test $includedir != /usr/include; then
+ CFLAGS="$CFLAGS -I$includedir"
+fi
+
+if test $libdir != /usr/lib -a $libdir != /usr/lib32; then
+ LDFLAGS="$LDFLAGS -L$libdir"
+fi
+
+usage ()
+{
+ echo "Usage: cups-config --api-version"
+ echo " cups-config --cflags"
+ echo " cups-config --datadir"
+ echo " cups-config --help"
+ echo " cups-config --ldflags"
+ echo " cups-config [--image] [--static] --libs"
+ echo " cups-config --serverbin"
+ echo " cups-config --serverroot"
+ echo " cups-config --version"
+
+ exit $1
+}
+
+if test $# -eq 0; then
+ usage 1
+fi
+
+# Parse command line options
+static=no
+image=no
+
+while test $# -gt 0; do
+ case $1 in
+ --api-version)
+ echo $APIVERSION
+ ;;
+ --cflags)
+ echo $CFLAGS
+ ;;
+ --datadir)
+ echo $cups_datadir
+ ;;
+ --help)
+ usage 0
+ ;;
+ --image)
+ image=yes
+ ;;
+ --ldflags)
+ echo $LDFLAGS
+ ;;
+ --libs)
+ if test $static = no; then
+ if test $image = no; then
+ echo -lcups $LIBS
+ else
+ echo -lcupsimage $IMGLIBS -lcups $LIBS
+ fi
+ else
+ if test $image = no; then
+ echo $libdir/libcups.a $LIBS
+ else
+ echo $libdir/libcupsimage.a $IMGLIBS $libdir/libcups.a $LIBS
+ fi
+ fi
+ ;;
+ --serverbin)
+ echo $cups_serverbin
+ ;;
+ --serverroot)
+ echo $cups_serverroot
+ ;;
+ --static)
+ static=yes
+ ;;
+ --version)
+ echo $VERSION
+ ;;
+ *)
+ usage 1
+ ;;
+ esac
+
+ shift
+done
+
+#
+# End of "$Id$".
+#
diff --git a/cups.dsw b/cups.dsw
new file mode 100644
index 000000000..28bdbaa89
--- /dev/null
+++ b/cups.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "cups"=.\cups\cups.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/cups.list.in b/cups.list.in
new file mode 100644
index 000000000..6a4d8d8d1
--- /dev/null
+++ b/cups.list.in
@@ -0,0 +1,465 @@
+#
+# "$Id$"
+#
+# ESP Package Manager (EPM) file list for the Common UNIX Printing
+# System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+# Product information
+%product Common UNIX Printing System
+%copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+%vendor Easy Software Products
+%license LICENSE.txt
+%readme README.txt
+%version 1.1.16
+%provides cupsys
+%provides cups-devel
+%provides cupsys-devel
+%provides libcups1
+%provides libcups.so.2
+
+#
+# GNU variables...
+#
+
+$prefix=@prefix@
+$exec_prefix=@exec_prefix@
+$bindir=@bindir@
+$datadir=@datadir@
+$includedir=@includedir@
+$infodir=@infodir@
+$libdir=@libdir@
+$libexecdir=@libexecdir@
+$localstatedir=@localstatedir@
+$mandir=@mandir@
+$oldincludedir=@oldincludedir@
+$sbindir=@sbindir@
+$sharedstatedir=@sharedstatedir@
+$srcdir=@srcdir@
+$sysconfdir=@sysconfdir@
+$top_srcdir=@top_srcdir@
+
+#
+# ESP variables...
+#
+
+$AMANDIR=@AMANDIR@
+$BINDIR=@bindir@
+$DATADIR=@CUPS_DATADIR@
+$DOCDIR=@CUPS_DOCROOT@
+$INCLUDEDIR=${includedir}
+$INITDIR=@INITDIR@
+$INITDDIR=@INITDDIR@
+$LIBDIR=${libdir}
+$LOCALEDIR=@CUPS_LOCALEDIR@
+$LOGDIR=@CUPS_LOGDIR@
+$MANDIR=@mandir@
+$PAMDIR=@PAMDIR@
+$PMANDIR=@PMANDIR@
+$REQUESTS=@CUPS_REQUESTS@
+$SBINDIR=@sbindir@
+$SERVERBIN=@CUPS_SERVERBIN@
+$SERVERROOT=@CUPS_SERVERROOT@
+
+$CUPS_USER=@CUPS_USER@
+$CUPS_GROUP=@CUPS_GROUP@
+
+$CAT1EXT=@CAT1EXT@
+$CAT3EXT=@CAT3EXT@
+$CAT5EXT=@CAT5EXT@
+$CAT8EXT=@CAT8EXT@
+$MAN8EXT=@MAN8EXT@
+$MAN8DIR=@MAN8DIR@
+
+# Make sure the MD5 password file is now owned by CUPS_USER...
+%postinstall if test -f $SERVERROOT/passwd.md5; then
+%postinstall chown $CUPS_USER $SERVERROOT/passwd.md5
+%postinstall fi
+
+# Make sure the shared libraries are refreshed...
+%system linux
+%postinstall ldconfig
+%system all
+
+# Server programs
+%system all
+# Server files
+f 0555 root sys $SBINDIR/cupsd scheduler/cupsd
+
+d 0555 root sys $SERVERBIN -
+d 0555 root sys $SERVERBIN/backend -
+f 0555 root sys $SERVERBIN/backend/ipp backend/ipp
+l 0555 root sys $SERVERBIN/backend/http ipp
+f 0555 root sys $SERVERBIN/backend/lpd backend/lpd
+f 0555 root sys $SERVERBIN/backend/parallel backend/parallel
+f 0555 root sys $SERVERBIN/backend/scsi backend/scsi
+f 0555 root sys $SERVERBIN/backend/serial backend/serial
+f 0555 root sys $SERVERBIN/backend/socket backend/socket
+f 0555 root sys $SERVERBIN/backend/usb backend/usb
+d 0555 root sys $SERVERBIN/cgi-bin -
+f 0555 root sys $SERVERBIN/cgi-bin/admin.cgi cgi-bin/admin.cgi
+f 0555 root sys $SERVERBIN/cgi-bin/classes.cgi cgi-bin/classes.cgi
+f 0555 root sys $SERVERBIN/cgi-bin/jobs.cgi cgi-bin/jobs.cgi
+f 0555 root sys $SERVERBIN/cgi-bin/printers.cgi cgi-bin/printers.cgi
+d 0555 root sys $SERVERBIN/daemon -
+f 0555 root sys $SERVERBIN/daemon/cups-lpd scheduler/cups-lpd
+f 0555 root sys $SERVERBIN/daemon/cups-polld scheduler/cups-polld
+d 0555 root sys $SERVERBIN/filter -
+f 0555 root sys $SERVERBIN/filter/pdftops pdftops/pdftops
+f 0555 root sys $SERVERBIN/filter/imagetops filter/imagetops
+f 0555 root sys $SERVERBIN/filter/pstops filter/pstops
+f 0555 root sys $SERVERBIN/filter/texttops filter/texttops
+f 0555 root sys $SERVERBIN/filter/rastertodymo filter/rastertodymo
+f 0555 root sys $SERVERBIN/filter/rastertoepson filter/rastertoepson
+f 0555 root sys $SERVERBIN/filter/rastertohp filter/rastertohp
+f 0555 root sys $SERVERBIN/filter/hpgltops filter/hpgltops
+f 0555 root sys $SERVERBIN/filter/imagetoraster filter/imagetoraster
+
+# Admin commands
+l 0555 root sys $BINDIR/disable $SBINDIR/accept
+l 0555 root sys $BINDIR/enable $SBINDIR/accept
+l 0555 root sys $LIBDIR/accept $SBINDIR/accept
+l 0555 root sys $LIBDIR/lpadmin $SBINDIR/lpadmin
+l 0555 root sys $LIBDIR/reject accept
+f 0555 root sys $SBINDIR/accept systemv/accept
+f 0555 root sys $SBINDIR/cupsaddsmb systemv/cupsaddsmb
+f 0555 root sys $SBINDIR/lpadmin systemv/lpadmin
+f 0555 root sys $SBINDIR/lpc berkeley/lpc
+f 0555 root sys $SBINDIR/lpinfo systemv/lpinfo
+f 0555 root sys $SBINDIR/lpmove systemv/lpmove
+l 0555 root sys $SBINDIR/reject accept
+
+%system irix
+l 0555 root sys /usr/etc/lpc $SBINDIR/lpc
+%system all
+
+# User commands
+f 0555 root sys $BINDIR/cancel systemv/cancel
+f 0555 root sys $BINDIR/lp systemv/lp
+f 0555 root sys $BINDIR/lpoptions systemv/lpoptions
+f 4555 $CUPS_USER sys $BINDIR/lppasswd systemv/lppasswd
+f 0555 root sys $BINDIR/lpq berkeley/lpq
+f 0555 root sys $BINDIR/lpr berkeley/lpr
+f 0555 root sys $BINDIR/lprm berkeley/lprm
+f 0555 root sys $BINDIR/lpstat systemv/lpstat
+
+%system irix
+l 0555 root sys /usr/bsd/lpq $BINDIR/lpq
+l 0555 root sys /usr/bsd/lpr $BINDIR/lpr
+l 0555 root sys /usr/bsd/lprm $BINDIR/lprm
+%system all
+
+# DSOs
+%system hpux
+f 0555 root sys $LIBDIR/libcups.sl.2 cups/libcups.sl.2
+l 0555 root sys $LIBDIR/libcups.sl libcups.sl.2
+f 0555 root sys $LIBDIR/libcupsimage.sl.2 filter/libcupsimage.sl.2
+l 0555 root sys $LIBDIR/libcupsimage.sl libcupsimage.sl.2
+%system aix
+f 0555 root sys $LIBDIR/libcups_s.a cups/libcups_s.a
+f 0555 root sys $LIBDIR/libcupsimage_s.a filter/libcupsimage_s.a
+%system darwin
+f 0555 root sys $LIBDIR/libcups.2.dylib cups/libcups.2.dylib
+l 0555 root sys $LIBDIR/libcups.dylib libcups.2.dylib
+f 0555 root sys $LIBDIR/libcupsimage.2.dylib filter/libcupsimage.2.dylib
+l 0555 root sys $LIBDIR/libcupsimage.dylib libcupsimage.2.dylib
+%system !hpux !aix !darwin
+f 0555 root sys $LIBDIR/libcups.so.2 cups/libcups.so.2
+l 0555 root sys $LIBDIR/libcups.so libcups.so.2
+f 0555 root sys $LIBDIR/libcupsimage.so.2 filter/libcupsimage.so.2
+l 0555 root sys $LIBDIR/libcupsimage.so libcupsimage.so.2
+%system all
+
+# Directories
+d 0755 root sys $LOGDIR -
+d 0700 $CUPS_USER sys $REQUESTS -
+d 1700 $CUPS_USER sys $REQUESTS/tmp -
+
+# Data files
+f 0444 root sys $LOCALEDIR/C/cups_C locale/C/cups_C
+f 0444 root sys $LOCALEDIR/be/cups_be locale/be/cups_be
+f 0444 root sys $LOCALEDIR/cs/cups_cs locale/cs/cups_cs
+f 0444 root sys $LOCALEDIR/de/cups_de locale/de/cups_de
+f 0444 root sys $LOCALEDIR/en/cups_en locale/en/cups_en
+f 0444 root sys $LOCALEDIR/es/cups_es locale/es/cups_es
+f 0444 root sys $LOCALEDIR/fr/cups_fr locale/fr/cups_fr
+f 0444 root sys $LOCALEDIR/it/cups_it locale/it/cups_it
+f 0444 root sys $LOCALEDIR/ru_RU.cp1251/cups_ru_RU.cp1251 locale/ru_RU.cp1251/cups_ru_RU.cp1251
+f 0444 root sys $LOCALEDIR/ru_RU.koi8r/cups_ru_RU.koi8r locale/ru_RU.koi8r/cups_ru_RU.koi8r
+f 0444 root sys $LOCALEDIR/sv/cups_sv locale/sv/cups_sv
+f 0444 root sys $LOCALEDIR/uk/cups_uk locale/uk/cups_uk
+f 0444 root sys $LOCALEDIR/uk_UA.cp1251/cups_uk_UA.cp1251 locale/uk_UA.cp1251/cups_uk_UA.cp1251
+f 0444 root sys $LOCALEDIR/zh_CN/cups_zh_CN locale/zh_CN/cups_zh_CN
+
+d 0555 root sys $DATADIR -
+
+d 0555 root sys $DATADIR/banners -
+f 0444 root sys $DATADIR/banners/classified data/classified
+f 0444 root sys $DATADIR/banners/confidential data/confidential
+f 0444 root sys $DATADIR/banners/secret data/secret
+f 0444 root sys $DATADIR/banners/standard data/standard
+f 0444 root sys $DATADIR/banners/topsecret data/topsecret
+f 0444 root sys $DATADIR/banners/unclassified data/unclassified
+
+d 0555 root sys $DATADIR/charsets -
+f 0444 root sys $DATADIR/charsets/windows-874 data/windows-874
+f 0444 root sys $DATADIR/charsets/windows-1250 data/windows-1250
+f 0444 root sys $DATADIR/charsets/windows-1251 data/windows-1251
+f 0444 root sys $DATADIR/charsets/windows-1252 data/windows-1252
+f 0444 root sys $DATADIR/charsets/windows-1253 data/windows-1253
+f 0444 root sys $DATADIR/charsets/windows-1254 data/windows-1254
+f 0444 root sys $DATADIR/charsets/windows-1255 data/windows-1255
+f 0444 root sys $DATADIR/charsets/windows-1256 data/windows-1256
+f 0444 root sys $DATADIR/charsets/windows-1257 data/windows-1257
+f 0444 root sys $DATADIR/charsets/windows-1258 data/windows-1258
+f 0444 root sys $DATADIR/charsets/iso-8859-1 data/iso-8859-1
+f 0444 root sys $DATADIR/charsets/iso-8859-2 data/iso-8859-2
+f 0444 root sys $DATADIR/charsets/iso-8859-3 data/iso-8859-3
+f 0444 root sys $DATADIR/charsets/iso-8859-4 data/iso-8859-4
+f 0444 root sys $DATADIR/charsets/iso-8859-5 data/iso-8859-5
+f 0444 root sys $DATADIR/charsets/iso-8859-6 data/iso-8859-6
+f 0444 root sys $DATADIR/charsets/iso-8859-7 data/iso-8859-7
+f 0444 root sys $DATADIR/charsets/iso-8859-8 data/iso-8859-8
+f 0444 root sys $DATADIR/charsets/iso-8859-9 data/iso-8859-9
+f 0444 root sys $DATADIR/charsets/iso-8859-10 data/iso-8859-10
+f 0444 root sys $DATADIR/charsets/iso-8859-13 data/iso-8859-13
+f 0444 root sys $DATADIR/charsets/iso-8859-14 data/iso-8859-14
+f 0444 root sys $DATADIR/charsets/iso-8859-15 data/iso-8859-15
+f 0444 root sys $DATADIR/charsets/utf-8 data/utf-8
+
+d 0555 root sys $DATADIR/data -
+f 0444 root sys $DATADIR/data/HPGLprolog data/HPGLprolog
+f 0444 root sys $DATADIR/data/psglyphs data/psglyphs
+f 0444 root sys $DATADIR/data/testprint.ps data/testprint.ps
+
+d 0555 root sys $DATADIR/fonts -
+f 0444 root sys $DATADIR/fonts fonts/Courier*
+f 0444 root sys $DATADIR/fonts/Symbol fonts/Symbol
+
+d 0555 root sys $DATADIR/model -
+f 0444 root sys $DATADIR/model ppd/*.ppd
+
+d 0555 root sys $DATADIR/templates -
+c 0444 root sys $DATADIR/templates templates/*.tmpl
+
+# Config files
+d 0555 root sys $SERVERROOT -
+d 0711 $CUPS_USER $CUPS_GROUP $SERVERROOT/certs -
+d 0755 root sys $SERVERROOT/interfaces -
+d 0755 root sys $SERVERROOT/ppd -
+c 0600 root sys $SERVERROOT conf/*.conf
+c 0600 root sys $SERVERROOT/mime.convs conf/mime.convs
+c 0600 root sys $SERVERROOT/mime.types conf/mime.types
+
+%system linux
+d 0555 root sys $PAMDIR -
+c 0644 root sys $PAMDIR/cups conf/pam.conf
+
+# IRIX doesn't normally support PAM, but the freeware project
+# includes a version of PAM that can be used...
+%system irix
+d 0555 root sys $PAMDIR -
+c 0644 root sys $PAMDIR/cups data/cups.irix
+
+%system all
+
+# Developer files
+f 0555 root sys $BINDIR/cups-config cups-config
+d 0555 root sys $INCLUDEDIR/cups -
+f 0444 root sys $INCLUDEDIR/cups/cups.h cups/cups.h
+f 0444 root sys $INCLUDEDIR/cups/http.h cups/http.h
+f 0444 root sys $INCLUDEDIR/cups/image.h filter/image.h
+f 0444 root sys $INCLUDEDIR/cups/ipp.h cups/ipp.h
+f 0444 root sys $INCLUDEDIR/cups/language.h cups/language.h
+f 0444 root sys $INCLUDEDIR/cups/md5.h cups/md5.h
+f 0444 root sys $INCLUDEDIR/cups/ppd.h cups/ppd.h
+f 0444 root sys $INCLUDEDIR/cups/raster.h filter/raster.h
+
+f 0444 root sys $LIBDIR/libcups.a cups/libcups.a
+
+# Documentation files
+d 0555 root sys $DOCDIR -
+f 0444 root sys $DOCDIR doc/*.css
+f 0444 root sys $DOCDIR doc/*.html
+f 0444 root sys $DOCDIR doc/*.pdf
+d 0555 root sys $DOCDIR/images -
+f 0444 root sys $DOCDIR/images doc/images/*.gif
+
+# Man pages
+d 0555 root sys $AMANDIR -
+d 0555 root sys $AMANDIR/cat$MAN8DIR -
+d 0555 root sys $AMANDIR/man$MAN8DIR -
+d 0555 root sys $MANDIR -
+d 0555 root sys $MANDIR/cat1 -
+d 0555 root sys $MANDIR/cat5 -
+d 0555 root sys $MANDIR/man1 -
+d 0555 root sys $MANDIR/man5 -
+d 0555 root sys $PMANDIR -
+d 0555 root sys $PMANDIR/cat3 -
+d 0555 root sys $PMANDIR/man3 -
+
+f 0444 root sys $MANDIR/cat1/backend.$CAT1EXT man/backend.$CAT1EXT
+f 0444 root sys $MANDIR/cat1/filter.$CAT1EXT man/filter.$CAT1EXT
+f 0444 root sys $MANDIR/cat1/lpoptions.$CAT1EXT man/lpoptions.$CAT1EXT
+f 0444 root sys $MANDIR/cat1/lppasswd.$CAT1EXT man/lppasswd.$CAT1EXT
+f 0444 root sys $MANDIR/cat1/lpq.$CAT1EXT man/lpq.$CAT1EXT
+f 0444 root sys $MANDIR/cat1/lprm.$CAT1EXT man/lprm.$CAT1EXT
+f 0444 root sys $MANDIR/cat1/lpr.$CAT1EXT man/lpr.$CAT1EXT
+f 0444 root sys $MANDIR/cat1/lpstat.$CAT1EXT man/lpstat.$CAT1EXT
+f 0444 root sys $MANDIR/cat1/lp.$CAT1EXT man/lp.$CAT1EXT
+l 0444 root sys $MANDIR/cat1/cancel.$CAT1EXT lp.$CAT1EXT
+
+f 0444 root sys $PMANDIR/cat3/cups-config.$CAT3EXT man/cups-config.$CAT3EXT
+
+f 0444 root sys $MANDIR/cat5/classes.conf.$CAT5EXT man/classes.conf.$CAT5EXT
+f 0444 root sys $MANDIR/cat5/cupsd.conf.$CAT5EXT man/cupsd.conf.$CAT5EXT
+f 0444 root sys $MANDIR/cat5/mime.convs.$CAT5EXT man/mime.convs.$CAT5EXT
+f 0444 root sys $MANDIR/cat5/mime.types.$CAT5EXT man/mime.types.$CAT5EXT
+f 0444 root sys $MANDIR/cat5/printers.conf.$CAT5EXT man/printers.conf.$CAT5EXT
+
+f 0444 root sys $AMANDIR/cat$MAN8DIR/accept.$CAT8EXT man/accept.$CAT8EXT
+l 0444 root sys $AMANDIR/cat$MAN8DIR/reject.$CAT8EXT accept.$CAT8EXT
+f 0444 root sys $AMANDIR/cat$MAN8DIR/cupsaddsmb.$CAT8EXT man/cupsaddsmb.$CAT8EXT
+f 0444 root sys $AMANDIR/cat$MAN8DIR/cups-lpd.$CAT8EXT man/cups-lpd.$CAT8EXT
+f 0444 root sys $AMANDIR/cat$MAN8DIR/cups-polld.$CAT8EXT man/cups-polld.$CAT8EXT
+f 0444 root sys $AMANDIR/cat$MAN8DIR/cupsd.$CAT8EXT man/cupsd.$CAT8EXT
+f 0444 root sys $AMANDIR/cat$MAN8DIR/enable.$CAT8EXT man/enable.$CAT8EXT
+l 0444 root sys $AMANDIR/cat$MAN8DIR/disable.$CAT8EXT enable.$CAT8EXT
+f 0444 root sys $AMANDIR/cat$MAN8DIR/lpadmin.$CAT8EXT man/lpadmin.$CAT8EXT
+f 0444 root sys $AMANDIR/cat$MAN8DIR/lpc.$CAT8EXT man/lpc.$CAT8EXT
+f 0444 root sys $AMANDIR/cat$MAN8DIR/lpinfo.$CAT8EXT man/lpinfo.$CAT8EXT
+f 0444 root sys $AMANDIR/cat$MAN8DIR/lpmove.$CAT8EXT man/lpmove.$CAT8EXT
+
+f 0444 root sys $MANDIR/man1/backend.$MAN1EXT man/backend.man
+f 0444 root sys $MANDIR/man1/filter.$MAN1EXT man/filter.man
+f 0444 root sys $MANDIR/man1/lpoptions.$MAN1EXT man/lpoptions.man
+f 0444 root sys $MANDIR/man1/lppasswd.$MAN1EXT man/lppasswd.man
+f 0444 root sys $MANDIR/man1/lpq.$MAN1EXT man/lpq.man
+f 0444 root sys $MANDIR/man1/lprm.$MAN1EXT man/lprm.man
+f 0444 root sys $MANDIR/man1/lpr.$MAN1EXT man/lpr.man
+f 0444 root sys $MANDIR/man1/lpstat.$MAN1EXT man/lpstat.man
+f 0444 root sys $MANDIR/man1/lp.$MAN1EXT man/lp.man
+l 0444 root sys $MANDIR/man1/cancel.$MAN1EXT lp.$MAN1EXT
+
+f 0444 root sys $PMANDIR/man3/cups-config.$MAN3EXT man/cups-config.man
+
+f 0444 root sys $MANDIR/man5/classes.conf.$MAN5EXT man/classes.conf.man
+f 0444 root sys $MANDIR/man5/cupsd.conf.$MAN5EXT man/cupsd.conf.man
+f 0444 root sys $MANDIR/man5/mime.convs.$MAN5EXT man/mime.convs.man
+f 0444 root sys $MANDIR/man5/mime.types.$MAN5EXT man/mime.types.man
+f 0444 root sys $MANDIR/man5/printers.conf.$MAN5EXT man/printers.conf.man
+
+f 0444 root sys $AMANDIR/man$MAN8DIR/accept.$MAN8EXT man/accept.man
+l 0444 root sys $AMANDIR/man$MAN8DIR/reject.$MAN8EXT accept.$MAN8EXT
+f 0444 root sys $AMANDIR/man$MAN8DIR/cupsaddsmb.$MAN8EXT man/cupsaddsmb.man
+f 0444 root sys $AMANDIR/man$MAN8DIR/cups-lpd.$MAN8EXT man/cups-lpd.man
+f 0444 root sys $AMANDIR/man$MAN8DIR/cups-polld.$MAN8EXT man/cups-polld.man
+f 0444 root sys $AMANDIR/man$MAN8DIR/cupsd.$MAN8EXT man/cupsd.man
+f 0444 root sys $AMANDIR/man$MAN8DIR/enable.$MAN8EXT man/enable.man
+l 0444 root sys $AMANDIR/man$MAN8DIR/disable.$MAN8EXT enable.$MAN8EXT
+f 0444 root sys $AMANDIR/man$MAN8DIR/lpadmin.$MAN8EXT man/lpadmin.man
+f 0444 root sys $AMANDIR/man$MAN8DIR/lpc.$MAN8EXT man/lpc.man
+f 0444 root sys $AMANDIR/man$MAN8DIR/lpinfo.$MAN8EXT man/lpinfo.man
+f 0444 root sys $AMANDIR/man$MAN8DIR/lpmove.$MAN8EXT man/lpmove.man
+
+d 0555 root sys $AMANDIR/fr -
+d 0555 root sys $AMANDIR/fr/cat$MAN8DIR -
+d 0555 root sys $AMANDIR/fr/man$MAN8DIR -
+d 0555 root sys $MANDIR/fr -
+d 0555 root sys $MANDIR/fr/cat1 -
+d 0555 root sys $MANDIR/fr/cat5 -
+d 0555 root sys $MANDIR/fr/man1 -
+d 0555 root sys $MANDIR/fr/man5 -
+d 0555 root sys $PMANDIR/fr -
+d 0555 root sys $PMANDIR/fr/cat3 -
+d 0555 root sys $PMANDIR/fr/man3 -
+
+f 0444 root sys $MANDIR/fr/cat1/backend.$CAT1EXT man/backend.$CAT1EXT
+f 0444 root sys $MANDIR/fr/cat1/filter.$CAT1EXT man/filter.$CAT1EXT
+f 0444 root sys $MANDIR/fr/cat1/lpoptions.$CAT1EXT man/lpoptions.$CAT1EXT
+f 0444 root sys $MANDIR/fr/cat1/lppasswd.$CAT1EXT man/lppasswd.$CAT1EXT
+f 0444 root sys $MANDIR/fr/cat1/lpq.$CAT1EXT man/lpq.$CAT1EXT
+f 0444 root sys $MANDIR/fr/cat1/lprm.$CAT1EXT man/lprm.$CAT1EXT
+f 0444 root sys $MANDIR/fr/cat1/lpr.$CAT1EXT man/lpr.$CAT1EXT
+f 0444 root sys $MANDIR/fr/cat1/lpstat.$CAT1EXT man/lpstat.$CAT1EXT
+f 0444 root sys $MANDIR/fr/cat1/lp.$CAT1EXT man/lp.$CAT1EXT
+l 0444 root sys $MANDIR/fr/cat1/cancel.$CAT1EXT lp.$CAT1EXT
+
+f 0444 root sys $PMANDIR/fr/cat3/cups-config.$CAT3EXT man/cups-config.$CAT3EXT
+
+f 0444 root sys $MANDIR/fr/cat5/classes.conf.$CAT5EXT man/classes.conf.$CAT5EXT
+f 0444 root sys $MANDIR/fr/cat5/cupsd.conf.$CAT5EXT man/cupsd.conf.$CAT5EXT
+f 0444 root sys $MANDIR/fr/cat5/mime.convs.$CAT5EXT man/mime.convs.$CAT5EXT
+f 0444 root sys $MANDIR/fr/cat5/mime.types.$CAT5EXT man/mime.types.$CAT5EXT
+f 0444 root sys $MANDIR/fr/cat5/printers.conf.$CAT5EXT man/printers.conf.$CAT5EXT
+
+f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/accept.$CAT8EXT man/accept.$CAT8EXT
+l 0444 root sys $AMANDIR/fr/cat$MAN8DIR/reject.$CAT8EXT accept.$CAT8EXT
+f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/cupsaddsmb.$CAT8EXT man/cupsaddsmb.$CAT8EXT
+f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/cups-lpd.$CAT8EXT man/cups-lpd.$CAT8EXT
+f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/cups-polld.$CAT8EXT man/cups-polld.$CAT8EXT
+f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/cupsd.$CAT8EXT man/cupsd.$CAT8EXT
+f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/enable.$CAT8EXT man/enable.$CAT8EXT
+l 0444 root sys $AMANDIR/fr/cat$MAN8DIR/disable.$CAT8EXT enable.$CAT8EXT
+f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/lpadmin.$CAT8EXT man/lpadmin.$CAT8EXT
+f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/lpc.$CAT8EXT man/lpc.$CAT8EXT
+f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/lpinfo.$CAT8EXT man/lpinfo.$CAT8EXT
+f 0444 root sys $AMANDIR/fr/cat$MAN8DIR/lpmove.$CAT8EXT man/lpmove.$CAT8EXT
+
+f 0444 root sys $MANDIR/fr/man1/backend.$MAN1EXT man/backend.man
+f 0444 root sys $MANDIR/fr/man1/filter.$MAN1EXT man/filter.man
+f 0444 root sys $MANDIR/fr/man1/lpoptions.$MAN1EXT man/lpoptions.man
+f 0444 root sys $MANDIR/fr/man1/lppasswd.$MAN1EXT man/lppasswd.man
+f 0444 root sys $MANDIR/fr/man1/lpq.$MAN1EXT man/lpq.man
+f 0444 root sys $MANDIR/fr/man1/lprm.$MAN1EXT man/lprm.man
+f 0444 root sys $MANDIR/fr/man1/lpr.$MAN1EXT man/lpr.man
+f 0444 root sys $MANDIR/fr/man1/lpstat.$MAN1EXT man/lpstat.man
+f 0444 root sys $MANDIR/fr/man1/lp.$MAN1EXT man/lp.man
+l 0444 root sys $MANDIR/fr/man1/cancel.$MAN1EXT lp.$MAN1EXT
+
+f 0444 root sys $PMANDIR/fr/man3/cups-config.$MAN3EXT man/cups-config.man
+
+f 0444 root sys $MANDIR/fr/man5/classes.conf.$MAN5EXT man/classes.conf.man
+f 0444 root sys $MANDIR/fr/man5/cupsd.conf.$MAN5EXT man/cupsd.conf.man
+f 0444 root sys $MANDIR/fr/man5/mime.convs.$MAN5EXT man/mime.convs.man
+f 0444 root sys $MANDIR/fr/man5/mime.types.$MAN5EXT man/mime.types.man
+f 0444 root sys $MANDIR/fr/man5/printers.conf.$MAN5EXT man/printers.conf.man
+
+f 0444 root sys $AMANDIR/fr/man$MAN8DIR/accept.$MAN8EXT man/accept.man
+l 0444 root sys $AMANDIR/fr/man$MAN8DIR/reject.$MAN8EXT accept.$MAN8EXT
+f 0444 root sys $AMANDIR/fr/man$MAN8DIR/cupsaddsmb.$MAN8EXT man/cupsaddsmb.man
+f 0444 root sys $AMANDIR/fr/man$MAN8DIR/cups-lpd.$MAN8EXT man/cups-lpd.man
+f 0444 root sys $AMANDIR/fr/man$MAN8DIR/cups-polld.$MAN8EXT man/cups-polld.man
+f 0444 root sys $AMANDIR/fr/man$MAN8DIR/cupsd.$MAN8EXT man/cupsd.man
+f 0444 root sys $AMANDIR/fr/man$MAN8DIR/enable.$MAN8EXT man/enable.man
+l 0444 root sys $AMANDIR/fr/man$MAN8DIR/disable.$MAN8EXT enable.$MAN8EXT
+f 0444 root sys $AMANDIR/fr/man$MAN8DIR/lpadmin.$MAN8EXT man/lpadmin.man
+f 0444 root sys $AMANDIR/fr/man$MAN8DIR/lpc.$MAN8EXT man/lpc.man
+f 0444 root sys $AMANDIR/fr/man$MAN8DIR/lpinfo.$MAN8EXT man/lpinfo.man
+f 0444 root sys $AMANDIR/fr/man$MAN8DIR/lpmove.$MAN8EXT man/lpmove.man
+
+# Startup script
+%system all
+i 0555 root sys cups cups.sh
+
+#
+# End of "$Id$".
+#
diff --git a/cups.plist b/cups.plist
new file mode 100644
index 000000000..a5b989b58
--- /dev/null
+++ b/cups.plist
@@ -0,0 +1,7 @@
+{
+ Description = "Printing Services";
+ Provides = ("Printing");
+ Requires = ("Resolver");
+ Uses = ("Network Time");
+ OrderPreference = "Late";
+}
diff --git a/cups.sh.in b/cups.sh.in
new file mode 100755
index 000000000..30272c6e9
--- /dev/null
+++ b/cups.sh.in
@@ -0,0 +1,211 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Startup/shutdown script for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+#### OS-Dependent Information
+
+#
+# Linux chkconfig stuff:
+#
+# chkconfig: 235 99 00
+# description: Startup/shutdown script for the Common UNIX \
+# Printing System (CUPS).
+#
+
+#
+# NetBSD 1.5+ rcorder script lines. The format of the following two
+# lines is very strict -- please don't add additional spaces!
+#
+# PROVIDE: cups
+# REQUIRE: DAEMON
+#
+
+
+#### OS-Dependent Configuration
+
+case "`uname`" in
+ IRIX*)
+ IS_ON=/sbin/chkconfig
+
+ if $IS_ON verbose; then
+ ECHO=echo
+ else
+ ECHO=:
+ fi
+ ECHO_OK=:
+ ECHO_ERROR=:
+ ;;
+
+ *BSD*)
+ IS_ON=:
+ ECHO=echo
+ ECHO_OK=:
+ ECHO_ERROR=:
+ ;;
+
+ Darwin*)
+ . /etc/rc.common
+
+ if test "${CUPS:=-YES-}" = "-NO-"; then
+ exit 0
+ fi
+
+ IS_ON=:
+ ECHO=ConsoleMessage
+ ECHO_OK=:
+ ECHO_ERROR=:
+ ;;
+
+ Linux*)
+ IS_ON=/bin/true
+ if test -f /etc/init.d/functions; then
+ . /etc/init.d/functions
+ ECHO=echo
+ ECHO_OK="echo_success"
+ ECHO_ERROR="echo_failure"
+ else
+ ECHO=echo
+ ECHO_OK=:
+ ECHO_ERROR=:
+ fi
+ ;;
+
+ *)
+ IS_ON=/bin/true
+ ECHO=echo
+ ECHO_OK=:
+ ECHO_ERROR=:
+ ;;
+esac
+
+#### OS-Independent Stuff
+
+#
+# Set the timezone, if possible... This allows the
+# scheduler and all child processes to know the local
+# timezone when reporting dates and times to the user.
+# If no timezone information is found, then Greenwich
+# Mean Time (GMT) will probably be used.
+#
+
+for file in /etc/TIMEZONE /etc/rc.config /etc/sysconfig/clock; do
+ if test -f $file; then
+ . $file
+ fi
+done
+
+if test "x$ZONE" != x; then
+ TZ="$ZONE"
+fi
+
+if test "x$TIMEZONE" != x; then
+ TZ="$TIMEZONE"
+fi
+
+if test "x$TZ" != x; then
+ export TZ
+fi
+
+#
+# See if the CUPS server (cupsd) is running...
+#
+
+case "`uname`" in
+ HP-UX* | AIX* | SINIX*)
+ pid=`ps -e | awk '{if (match($4, ".*/cupsd$") || $4 == "cupsd") print $1}'`
+ ;;
+ IRIX* | SunOS*)
+ pid=`ps -e | nawk '{if (match($4, ".*/cupsd$") || $4 == "cupsd") print $1}'`
+ ;;
+ UnixWare*)
+ pid=`ps -e | awk '{if (match($6, ".*/cupsd$") || $6 == "cupsd") print $1}'`
+ . /etc/TIMEZONE
+ ;;
+ OSF1*)
+ pid=`ps -e | awk '{if (match($5, ".*/cupsd$") || $5 == "cupsd") print $1}'`
+ ;;
+ Linux* | *BSD* | Darwin*)
+ pid=`ps ax | awk '{if (match($5, ".*/cupsd$") || $5 == "cupsd") print $1}'`
+ ;;
+ *)
+ pid=""
+ ;;
+esac
+
+#
+# Start or stop the CUPS server based upon the first argument to the script.
+#
+
+case $1 in
+ start | restart | reload)
+ if $IS_ON cups; then
+ if test "$pid" != ""; then
+ kill -HUP $pid
+ else
+ prefix=@prefix@
+ exec_prefix=@exec_prefix@
+ @sbindir@/cupsd
+ if test $? != 0; then
+ $ECHO_FAIL
+ $ECHO "cups: unable to $1 scheduler."
+ exit 1
+ fi
+ fi
+ $ECHO_OK
+ $ECHO "cups: ${1}ed scheduler."
+ fi
+ ;;
+
+ stop)
+ if test "$pid" != ""; then
+ kill $pid
+ $ECHO_OK
+ $ECHO "cups: stopped scheduler."
+ fi
+ ;;
+
+ status)
+ if test "$pid" != ""; then
+ echo "cups: scheduler is running."
+ else
+ echo "cups: scheduler is not running."
+ fi
+ ;;
+
+ *)
+ echo "Usage: cups {reload|restart|start|status|stop}"
+ exit 1
+ ;;
+esac
+
+#
+# Exit with no errors.
+#
+
+exit 0
+
+
+#
+# End of "$Id$".
+#
diff --git a/cups.spec b/cups.spec
new file mode 100644
index 000000000..791a86588
--- /dev/null
+++ b/cups.spec
@@ -0,0 +1,207 @@
+#
+# "$Id: cups.spec 2779 2002-09-06 16:11:46Z mike $"
+#
+# RPM "spec" file for the Common UNIX Printing System (CUPS).
+#
+# Original version by Jason McMullan <jmcc@ontv.com>.
+#
+# Copyright 1999-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+Summary: Common Unix Printing System
+Name: cups
+Version: 1.1.16pre1
+Release: 1
+Copyright: GPL
+Group: System Environment/Daemons
+Source: ftp://ftp.easysw.com/pub/cups/%{version}/cups-%{version}-source.tar.gz
+Url: http://www.cups.org
+Packager: Anonymous <anonymous@foo.com>
+Vendor: Easy Software Products
+
+# Use buildroot so as not to disturb the version already installed
+BuildRoot: /var/tmp/%{name}-root
+
+# Dependencies...
+Conflicts: lpr, LPRng
+Provides: libcups.so.2
+Provides: libcupsimage.so.2
+
+%package devel
+Summary: Common Unix Printing System - development environment
+Group: Development/Libraries
+Provides: libcups1
+
+%description
+The Common UNIX Printing System provides a portable printing layer for
+UNIX® operating systems. It has been developed by Easy Software Products
+to promote a standard printing solution for all UNIX vendors and users.
+CUPS provides the System V and Berkeley command-line interfaces.
+
+%description devel
+The Common UNIX Printing System provides a portable printing layer for
+UNIX® operating systems. This is the development package for creating
+additional printer drivers and other CUPS services.
+
+%prep
+%setup
+
+%build
+CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" ./configure
+
+# If we got this far, all prerequisite libraries must be here.
+make
+
+%install
+# Make sure the RPM_BUILD_ROOT directory exists.
+rm -rf $RPM_BUILD_ROOT
+
+make BUILDROOT=$RPM_BUILD_ROOT install
+
+%post
+ldconfig
+
+if test -x /sbin/chkconfig; then
+ /sbin/chkconfig --add cups
+ /sbin/chkconfig cups on
+fi
+
+# these lines automatically start cupsd after installation; commented out
+# by request...
+#if test -f /sbin/init.d/cups; then
+# /sbin/init.d/cups start
+#fi
+#if test -f /etc/rc.d/init.d/cups; then
+# /etc/rc.d/init.d/cups start
+#fi
+#if test -f /etc/init.d/cups; then
+# /etc/init.d/cups start
+#fi
+
+%preun
+if test -f /sbin/init.d/cups; then
+ /sbin/init.d/cups stop
+fi
+if test -f /etc/rc.d/init.d/cups; then
+ /etc/rc.d/init.d/cups stop
+fi
+if test -f /etc/init.d/cups; then
+ /etc/init.d/cups stop
+fi
+
+if test -x /sbin/chkconfig; then
+ /sbin/chkconfig --del cups
+fi
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+%dir /etc/cups
+%config(noreplace) /etc/cups/*.conf
+%dir /etc/cups/certs
+%dir /etc/cups/interfaces
+/etc/cups/mime.types
+/etc/cups/mime.convs
+%dir /etc/cups/ppd
+%dir /etc/pam.d
+/etc/pam.d/*
+
+# RC dirs are a pain under Linux... Uncomment the appropriate ones if you
+# don't use Red Hat or Mandrake...
+
+/etc/rc.d/init.d/*
+/etc/rc.d/rc0.d/*
+/etc/rc.d/rc3.d/*
+/etc/rc.d/rc5.d/*
+
+#/etc/init.d/*
+#/etc/rc0.d/*
+#/etc/rc3.d/*
+#/etc/rc5.d/*
+
+#/sbin/rc.d/*
+#/sbin/rc.d/rc0.d/*
+#/sbin/rc.d/rc3.d/*
+#/sbin/rc.d/rc5.d/*
+
+/usr/bin/cancel
+/usr/bin/disable
+/usr/bin/enable
+/usr/bin/lp*
+/usr/lib/*.so*
+%dir /usr/lib/cups
+/usr/lib/cups/*
+/usr/sbin/*
+%dir /usr/share/cups
+/usr/share/cups/*
+%dir /usr/share/doc/cups
+/usr/share/doc/cups/*
+%dir /usr/share/locale
+/usr/share/locale/*
+
+%dir /usr/share/man/cat1
+/usr/share/man/cat1/*
+%dir /usr/share/man/cat5
+/usr/share/man/cat5/*
+%dir /usr/share/man/cat8
+/usr/share/man/cat8/*
+%dir /usr/share/man/man1
+/usr/share/man/man1/*
+%dir /usr/share/man/man5
+/usr/share/man/man5/*
+%dir /usr/share/man/man8
+/usr/share/man/man8/*
+
+%dir /usr/share/man/fr/cat1
+/usr/share/man/fr/cat1/*
+%dir /usr/share/man/fr/cat5
+/usr/share/man/fr/cat5/*
+%dir /usr/share/man/fr/cat8
+/usr/share/man/fr/cat8/*
+%dir /usr/share/man/fr/man1
+/usr/share/man/fr/man1/*
+%dir /usr/share/man/fr/man5
+/usr/share/man/fr/man5/*
+%dir /usr/share/man/fr/man8
+/usr/share/man/fr/man8/*
+
+%attr(0700,lp,root) %dir /var/spool/cups
+%attr(1700,lp,root) %dir /var/spool/cups/tmp
+
+%files devel
+/usr/bin/cups-config
+%dir /usr/include/cups
+/usr/include/cups/*
+/usr/lib/*.a
+
+%dir /usr/share/man/cat3
+/usr/share/man/cat3/*
+%dir /usr/share/man/man3
+/usr/share/man/man3/*
+
+%dir /usr/share/man/fr/cat3
+/usr/share/man/fr/cat3/*
+%dir /usr/share/man/fr/man3
+/usr/share/man/fr/man3/*
+
+#
+# End of "$Id: cups.spec 2779 2002-09-06 16:11:46Z mike $".
+#
diff --git a/cups.strings b/cups.strings
new file mode 100644
index 000000000..d08f91972
--- /dev/null
+++ b/cups.strings
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>Starting printing services</key>
+ <string>Starting printing services</string>
+</dict>
+</plist>
+
diff --git a/cups/.cvsignore b/cups/.cvsignore
new file mode 100644
index 000000000..2a1918bf9
--- /dev/null
+++ b/cups/.cvsignore
@@ -0,0 +1,11 @@
+libcups.a
+libcups.la
+libcups.sl
+libcups.sl.2
+libcups.so
+libcups.so.2
+libcups_s.a
+libcups.2.dylib
+libcups.dylib
+testhttp
+testppd
diff --git a/cups/Dependencies b/cups/Dependencies
new file mode 100644
index 000000000..eb43c56e7
--- /dev/null
+++ b/cups/Dependencies
@@ -0,0 +1,26 @@
+# DO NOT DELETE
+
+dest.o: cups.h ipp.h http.h md5.h ppd.h language.h string.h ../config.h
+emit.o: ppd.h string.h ../config.h
+encode.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h debug.h
+http.o: string.h ../config.h http.h md5.h debug.h
+http-addr.o: string.h ../config.h http.h md5.h
+http-support.o: string.h ../config.h http.h md5.h ipp.h
+ipp.o: string.h ../config.h language.h ipp.h http.h md5.h debug.h
+ipp-support.o: string.h ../config.h language.h ipp.h http.h md5.h debug.h
+language.o: string.h ../config.h language.h cups_C.h
+mark.o: ppd.h string.h ../config.h debug.h
+md5.o: md5.h string.h ../config.h
+md5passwd.o: http.h md5.h string.h ../config.h
+options.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h debug.h
+page.o: ppd.h string.h ../config.h
+ppd.o: ppd.h string.h ../config.h language.h debug.h
+snprintf.o: string.h ../config.h
+string.o: string.h ../config.h
+tempfile.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h debug.h
+usersys.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h
+util.o: cups.h ipp.h http.h md5.h ppd.h language.h string.h ../config.h
+util.o: debug.h
+testhttp.o: http.h md5.h
+testlang.o: language.h
+testppd.o: cups.h ipp.h http.h md5.h ppd.h string.h ../config.h
diff --git a/cups/Makefile b/cups/Makefile
new file mode 100644
index 000000000..08cc2ddda
--- /dev/null
+++ b/cups/Makefile
@@ -0,0 +1,216 @@
+#
+# "$Id$"
+#
+# Support library Makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+# This file is subject to the Apple OS-Developed Software exception.
+#
+
+include ../Makedefs
+
+#
+# Object files...
+#
+
+LIBOBJS = dest.o emit.o encode.o http.o http-addr.o http-support.o \
+ ipp.o ipp-support.o language.o mark.o md5.o md5passwd.o \
+ options.o page.o ppd.o snprintf.o string.o tempfile.o \
+ usersys.o util.o
+OBJS = $(LIBOBJS) testhttp.o testlang.o testppd.o ppd-debug.o
+
+
+#
+# Header files to install...
+#
+
+HEADERS = cups.h http.h ipp.h language.h md5.h ppd.h
+
+
+#
+# Targets in this directory...
+#
+
+TARGETS = $(LIBCUPS) libcups.a
+
+
+#
+# Make all targets...
+#
+
+all: $(TARGETS)
+
+
+#
+# Remove object and target files...
+#
+
+clean:
+ $(RM) $(OBJS) $(TARGETS) `basename $(LIBCUPS) .2` libcups.dylib
+
+
+#
+# Update dependencies (without system header dependencies...)
+#
+
+depend:
+ makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1
+
+
+#
+# Install object and target files...
+#
+
+install: all installhdrs
+ $(INSTALL_DIR) $(LIBDIR)
+ $(INSTALL_LIB) $(LIBCUPS) $(LIBDIR)
+ if test $(LIBCUPS) = "libcups.so.2" -o $(LIBCUPS) = "libcups.sl.2"; then \
+ $(RM) $(LIBDIR)/`basename $(LIBCUPS) .2`; \
+ $(LN) $(LIBCUPS) $(LIBDIR)/`basename $(LIBCUPS) .2`; \
+ fi
+ if test $(LIBCUPS) = "libcups.2.dylib"; then \
+ $(STRIP) -x $(LIBDIR)/$(LIBCUPS); \
+ $(RM) $(LIBDIR)/libcups.dylib; \
+ $(LN) $(LIBCUPS) $(LIBDIR)/libcups.dylib; \
+ fi
+ if test $(LIBCUPS) != "libcups.a"; then \
+ $(INSTALL_LIB) libcups.a $(LIBDIR); \
+ fi
+ $(RANLIB) $(LIBDIR)/libcups.a
+
+installhdrs:
+ $(INSTALL_DIR) $(INCLUDEDIR)/cups
+ for file in $(HEADERS); do \
+ $(INSTALL_DATA) $$file $(INCLUDEDIR)/cups; \
+ done
+
+
+#
+# libcups.so.2, libcups.sl.2
+#
+
+libcups.so.2 libcups.sl.2: $(LIBOBJS) ../Makedefs
+ echo Linking $@...
+ $(DSO) $(DSOFLAGS) -o $@ $(LIBOBJS) $(SSLLIBS)
+ $(RM) `basename $@ .2`
+ $(LN) $@ `basename $@ .2`
+
+
+#
+# libcups.2.dylib
+#
+
+libcups.2.dylib: $(LIBOBJS) ../Makedefs
+ echo Linking $@...
+ $(DSO) $(DSOFLAGS) -o $@ \
+ -install_name $(libdir)/$@ \
+ -current_version 2.0.4 \
+ -compatibility_version 2.0.0 \
+ $(LIBOBJS) $(SSLLIBS)
+ $(RM) libcups.dylib
+ $(LN) $@ libcups.dylib
+
+
+#
+# libcups_s.a
+#
+
+libcups_s.a: $(LIBOBJS) ../Makedefs
+ echo Creating $@...
+ $(RM) libcups_s.exp
+ (echo _ipp_add_attr; echo _ipp_free_attr) >libcups_s.exp
+ $(DSO) $(DSOFLAGS) -Wl,-bexport:libcups_s.exp -o libcups_s.o $(LIBOBJS) $(SSLLIBS) -lm
+ $(RM) $@
+ $(AR) $(ARFLAGS) $@ libcups_s.o
+
+
+#
+# libcups.la
+#
+
+libcups.la: $(LIBOBJS) ../Makedefs
+ echo Linking $@...
+ $(DSO) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) -rpath $(LIBDIR) \
+ -version-info 2:4 $(SSLLIBS)
+
+
+#
+# libcups.a
+#
+
+libcups.a: $(LIBOBJS)
+ echo Archiving $@...
+ $(RM) $@
+ $(AR) $(ARFLAGS) $@ $(LIBOBJS)
+ $(RANLIB) $@
+
+
+#
+# cups_C.h - the default POSIX locale that is compiled in.
+#
+
+cups_C.h: ../locale/C/cups_C
+ echo Generating $@...
+ $(RM) cups_C.h
+ $(AWK) '{print "\"" $$0 "\","}' < ../locale/C/cups_C > cups_C.h
+
+
+#
+# testhttp (dependency on static CUPS library is intentional)
+#
+
+testhttp: testhttp.o libcups.a
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ testhttp.o libcups.a $(NETLIBS) $(SSLLIBS)
+
+
+#
+# testlang (dependency on static CUPS library is intentional)
+#
+
+testlang: testlang.o libcups.a
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ testlang.o libcups.a $(NETLIBS) $(SSLLIBS)
+
+
+#
+# testppd
+#
+
+testppd: testppd.o ppd-debug.o language.o mark.o page.o string.o
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ testppd.o ppd-debug.o language.o mark.o page.o \
+ string.o
+
+ppd-debug.o: ppd.c ppd.h string.h ../config.h language.h debug.h
+ echo Compiling $< with debugging...
+ $(CC) $(OPTIM) $(CFLAGS) -DDEBUG -c -o $@ $<
+
+
+#
+# Dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id$".
+#
diff --git a/cups/cups.dsp b/cups/cups.dsp
new file mode 100644
index 000000000..8822fdbe0
--- /dev/null
+++ b/cups/cups.dsp
@@ -0,0 +1,188 @@
+# Microsoft Developer Studio Project File - Name="cups" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=cups - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "cups.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "cups.mak" CFG="cups - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "cups - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "cups - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "cups - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\visualc" /I ".." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"cups.lib"
+
+!ELSEIF "$(CFG)" == "cups - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\visualc" /I ".." /I "../visualc" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"cupsd.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "cups - Win32 Release"
+# Name "cups - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\dest.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\emit.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\http.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ipp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\language.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mark.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\md5.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\md5passwd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\page.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ppd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\snprintf.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\string.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\usersys.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\util.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\cups.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\cups_C.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\debug.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\http.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ipp.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\language.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\md5.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ppd.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\string.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cups/cups.h b/cups/cups.h
new file mode 100644
index 000000000..fb973049b
--- /dev/null
+++ b/cups/cups.h
@@ -0,0 +1,177 @@
+/*
+ * "$Id$"
+ *
+ * API definitions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _CUPS_CUPS_H_
+# define _CUPS_CUPS_H_
+
+/*
+ * Include necessary headers...
+ */
+
+# include "ipp.h"
+# include "ppd.h"
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+
+/*
+ * Constants...
+ */
+
+# define CUPS_VERSION 1.0116
+# define CUPS_DATE_ANY -1
+
+
+/*
+ * Types and structures...
+ */
+
+typedef unsigned cups_ptype_t; /**** Printer Type/Capability Bits ****/
+enum /* Not a typedef'd enum so we can OR */
+{
+ CUPS_PRINTER_LOCAL = 0x0000, /* Local printer or class */
+ CUPS_PRINTER_CLASS = 0x0001, /* Printer class */
+ CUPS_PRINTER_REMOTE = 0x0002, /* Remote printer or class */
+ CUPS_PRINTER_BW = 0x0004, /* Can do B&W printing */
+ CUPS_PRINTER_COLOR = 0x0008, /* Can do color printing */
+ CUPS_PRINTER_DUPLEX = 0x0010, /* Can do duplexing */
+ CUPS_PRINTER_STAPLE = 0x0020, /* Can staple output */
+ CUPS_PRINTER_COPIES = 0x0040, /* Can do copies */
+ CUPS_PRINTER_COLLATE = 0x0080, /* Can collage copies */
+ CUPS_PRINTER_PUNCH = 0x0100, /* Can punch output */
+ CUPS_PRINTER_COVER = 0x0200, /* Can cover output */
+ CUPS_PRINTER_BIND = 0x0400, /* Can bind output */
+ CUPS_PRINTER_SORT = 0x0800, /* Can sort output */
+ CUPS_PRINTER_SMALL = 0x1000, /* Can do Letter/Legal/A4 */
+ CUPS_PRINTER_MEDIUM = 0x2000, /* Can do Tabloid/B/C/A3/A2 */
+ CUPS_PRINTER_LARGE = 0x4000, /* Can do D/E/A1/A0 */
+ CUPS_PRINTER_VARIABLE = 0x8000, /* Can do variable sizes */
+ CUPS_PRINTER_IMPLICIT = 0x10000, /* Implicit class */
+ CUPS_PRINTER_DEFAULT = 0x20000, /* Default printer on network */
+ CUPS_PRINTER_OPTIONS = 0xfffc /* ~(CLASS | REMOTE | IMPLICIT) */
+};
+
+typedef struct /**** Printer Options ****/
+{
+ char *name; /* Name of option */
+ char *value; /* Value of option */
+} cups_option_t;
+
+typedef struct /**** Destination ****/
+{
+ char *name, /* Printer or class name */
+ *instance; /* Local instance name or NULL */
+ int is_default; /* Is this printer the default? */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+} cups_dest_t;
+
+typedef struct /**** Job ****/
+{
+ int id; /* The job ID */
+ char *dest, /* Printer or class name */
+ *title, /* Title/job name */
+ *user, /* User the submitted the job */
+ *format; /* Document format */
+ ipp_jstate_t state; /* Job state */
+ int size, /* Size in kilobytes */
+ priority; /* Priority (1-100) */
+ time_t completed_time, /* Time the job was completed */
+ creation_time, /* Time the job was created */
+ processing_time; /* Time the job was processed */
+} cups_job_t;
+
+
+/*
+ * Functions...
+ */
+
+extern int cupsCancelJob(const char *printer, int job);
+#define cupsDoRequest(http,request,resource) cupsDoFileRequest((http),(request),(resource),NULL)
+extern ipp_t *cupsDoFileRequest(http_t *http, ipp_t *request,
+ const char *resource, const char *filename);
+extern http_encryption_t cupsEncryption(void);
+extern void cupsFreeJobs(int num_jobs, cups_job_t *jobs);
+extern int cupsGetClasses(char ***classes);
+extern const char *cupsGetDefault(void);
+extern int cupsGetJobs(cups_job_t **jobs, const char *dest,
+ int myjobs, int completed);
+extern const char *cupsGetPPD(const char *printer);
+extern int cupsGetPrinters(char ***printers);
+extern ipp_status_t cupsLastError(void);
+extern int cupsPrintFile(const char *printer, const char *filename,
+ const char *title, int num_options,
+ cups_option_t *options);
+extern int cupsPrintFiles(const char *printer, int num_files,
+ const char **files, const char *title,
+ int num_options, cups_option_t *options);
+extern char *cupsTempFile(char *filename, int len);
+extern int cupsTempFd(char *filename, int len);
+
+extern int cupsAddDest(const char *name, const char *instance,
+ int num_dests, cups_dest_t **dests);
+extern void cupsFreeDests(int num_dests, cups_dest_t *dests);
+extern cups_dest_t *cupsGetDest(const char *name, const char *instance,
+ int num_dests, cups_dest_t *dests);
+extern int cupsGetDests(cups_dest_t **dests);
+extern void cupsSetDests(int num_dests, cups_dest_t *dests);
+
+extern int cupsAddOption(const char *name, const char *value,
+ int num_options, cups_option_t **options);
+extern void cupsEncodeOptions(ipp_t *ipp, int num_options,
+ cups_option_t *options);
+extern void cupsFreeOptions(int num_options, cups_option_t *options);
+extern const char *cupsGetOption(const char *name, int num_options,
+ cups_option_t *options);
+extern int cupsParseOptions(const char *arg, int num_options,
+ cups_option_t **options);
+extern int cupsMarkOptions(ppd_file_t *ppd, int num_options,
+ cups_option_t *options);
+
+extern const char *cupsGetPassword(const char *prompt);
+extern const char *cupsServer(void);
+extern void cupsSetEncryption(http_encryption_t e);
+extern void cupsSetPasswordCB(const char *(*cb)(const char *));
+extern void cupsSetServer(const char *server);
+extern void cupsSetUser(const char *user);
+extern const char *cupsUser(void);
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !_CUPS_CUPS_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/cups_C.h b/cups/cups_C.h
new file mode 100644
index 000000000..32e1fa6b5
--- /dev/null
+++ b/cups/cups_C.h
@@ -0,0 +1,135 @@
+"iso-8859-1",
+"OK",
+"Cancel",
+"Help",
+"Quit",
+"Close",
+"Yes",
+"No",
+"On",
+"Off",
+"Save",
+"Discard",
+"Default",
+"Options",
+"More Info",
+"Black",
+"Color",
+"Cyan",
+"Magenta",
+"Yellow",
+"Copyright 1993-2002 by Easy Software Products, All Rights Reserved.",
+"General",
+"Printer",
+"Image",
+"HP-GL/2",
+"Extra",
+"Document",
+"Other",
+"Print Pages: ",
+"Entire Document",
+"Page Range:",
+"Reverse Order: ",
+"Page Format: ",
+" 1-Up",
+" 2-Up",
+" 4-Up",
+"Image Scaling: ",
+"Use Natural Image Size",
+"Zoom by Percent",
+"Zoom by PPI",
+"Mirror Image: ",
+"Color Saturation: ",
+"Color Hue: ",
+"Fit to Page: ",
+"Shading: ",
+"Pen Width: ",
+"Gamma Correction: ",
+"Brightness: ",
+"Add",
+"Delete",
+"Modify",
+"Printer URI",
+"Printer Name",
+"Printer Location",
+"Printer Info",
+"Printer Make and Model",
+"Device URI",
+"Formatting Page",
+"Printing Page",
+"Initializing Printer",
+"Printer State",
+"Accepting Jobs",
+"Not Accepting Jobs",
+"Print Jobs",
+"Class",
+"Local",
+"Remote",
+"Duplexing",
+"Stapling",
+"Fast Copies",
+"Collated Copies",
+"Hole Punching",
+"Covering",
+"Binding",
+"Sorting",
+"Small (up to 9.5x14in)",
+"Medium (9.5x14in to 13x19in)",
+"Large (13x19in and larger)",
+"Custom Size",
+"Idle",
+"Processing",
+"Stopped",
+"All",
+"Odd",
+"Even",
+"Darker Lighter",
+"Media Size",
+"Media Type",
+"Media Source",
+"Orientation: ",
+"Portrait",
+"Landscape",
+"Job State",
+"Job Name",
+"User Name",
+"Priority",
+"Copies",
+"File Size",
+"Pending",
+"Output Mode",
+"Resolution",
+"Text",
+"Pretty Print",
+"Margins",
+"Left",
+"Right",
+"Bottom",
+"Top",
+"Filename(s)",
+"Print",
+"Options Installed",
+"Auto",
+"400 Your browser sent a request that this server could not understand.",
+"This server could not verify that you are authorized to access the resource.",
+"You must pay to access this server.",
+"You don't have permission to access the resource on this server.",
+"The requested resource was not found on this server.",
+"The requested method is not allowed with the resource.",
+"An appropriate representation for the resource was not found on this server.",
+"You don't have permission to use this server as a proxy host.",
+"The request has taken too long to complete and has been aborted.",
+"The requested resource has more than one value.",
+"The requested resource is gone and has not been replaced.",
+"The requested method requires a valid Content-Length.",
+"The precondition on the request evaluated to false.",
+"The request is too large for this server to process.",
+"The request URI is too large for this server to process.",
+"The request format is not understood by this server.",
+"426 An upgrade to a secure connection is required. If you are seeing this message in a web browser then it does not support HTTP encryption upgrades.",
+"500 The server has detected an unrecoverable error and cannot process your request.",
+"The requested method is not implemented by this server.",
+"The proxy server received an invalid response from an upstream server.",
+"The requested resource is currently unavailable on this server.",
+"The proxy server has taken too long to respond to this server.",
+"This server does not support the HTTP version required by your browser.",
diff --git a/cups/debug.h b/cups/debug.h
new file mode 100644
index 000000000..4e160ff37
--- /dev/null
+++ b/cups/debug.h
@@ -0,0 +1,59 @@
+/*
+ * "$Id$"
+ *
+ * Debugging macros for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _CUPS_DEBUG_H_
+# define _CUPS_DEBUG_H_
+
+/*
+ * Include necessary headers...
+ */
+
+# include <stdio.h>
+
+/*
+ * The debug macros are used if you compile with DEBUG defined.
+ *
+ * Usage:
+ *
+ * DEBUG_puts("string")
+ * DEBUG_printf(("format string", arg, arg, ...));
+ *
+ * Note the extra parenthesis around the DEBUG_printf macro...
+ */
+
+# ifdef DEBUG
+# define DEBUG_puts(x) puts(x)
+# define DEBUG_printf(x) printf x
+# else
+# define DEBUG_puts(x)
+# define DEBUG_printf(x)
+# endif /* DEBUG */
+
+#endif /* !_CUPS_DEBUG_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/dest.c b/cups/dest.c
new file mode 100644
index 000000000..30b95e7a6
--- /dev/null
+++ b/cups/dest.c
@@ -0,0 +1,798 @@
+/*
+ * "$Id$"
+ *
+ * User-defined destination (and option) support for the Common UNIX
+ * Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * cupsAddDest() - Add a destination to the list of destinations.
+ * cupsFreeDests() - Free the memory used by the list of destinations.
+ * cupsGetDest() - Get the named destination from the list.
+ * cupsGetDests() - Get the list of destinations.
+ * cupsSetDests() - Set the list of destinations.
+ * cups_get_dests() - Get destinations from a file.
+ * cups_get_sdests() - Get destinations from a server.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups.h"
+#include "language.h"
+#include "string.h"
+#include <stdlib.h>
+#include <ctype.h>
+
+
+/*
+ * Local functions...
+ */
+
+static int cups_get_dests(const char *filename, int num_dests,
+ cups_dest_t **dests);
+static int cups_get_sdests(ipp_op_t op, int num_dests,
+ cups_dest_t **dests);
+
+
+/*
+ * 'cupsAddDest()' - Add a destination to the list of destinations.
+ */
+
+int /* O - New number of destinations */
+cupsAddDest(const char *name, /* I - Name of destination */
+ const char *instance, /* I - Instance of destination */
+ int num_dests, /* I - Number of destinations */
+ cups_dest_t **dests) /* IO - Destinations */
+{
+ int i; /* Looping var */
+ cups_dest_t *dest; /* Destination pointer */
+
+
+ if (name == NULL || dests == NULL)
+ return (0);
+
+ if ((dest = cupsGetDest(name, instance, num_dests, *dests)) != NULL)
+ return (num_dests);
+
+ /*
+ * Add new destination...
+ */
+
+ if (num_dests == 0)
+ dest = malloc(sizeof(cups_dest_t));
+ else
+ dest = realloc(*dests, sizeof(cups_dest_t) * (num_dests + 1));
+
+ if (dest == NULL)
+ return (num_dests);
+
+ *dests = dest;
+
+ for (i = num_dests; i > 0; i --, dest ++)
+ if (strcasecmp(name, dest->name) < 0)
+ break;
+ else if (strcasecmp(name, dest->name) == 0 &&
+ instance != NULL && dest->instance != NULL &&
+ strcasecmp(instance, dest->instance) < 0)
+ break;
+
+ if (i > 0)
+ memmove(dest + 1, dest, i * sizeof(cups_dest_t));
+
+ dest->name = strdup(name);
+ dest->is_default = 0;
+ dest->num_options = 0;
+ dest->options = (cups_option_t *)0;
+
+ if (instance == NULL)
+ dest->instance = NULL;
+ else
+ dest->instance = strdup(instance);
+
+ return (num_dests + 1);
+}
+
+
+/*
+ * 'cupsFreeDests()' - Free the memory used by the list of destinations.
+ */
+
+void
+cupsFreeDests(int num_dests, /* I - Number of destinations */
+ cups_dest_t *dests) /* I - Destinations */
+{
+ int i; /* Looping var */
+ cups_dest_t *dest; /* Current destination */
+
+
+ if (num_dests == 0 || dests == NULL)
+ return;
+
+ for (i = num_dests, dest = dests; i > 0; i --, dest ++)
+ {
+ free(dest->name);
+
+ if (dest->instance)
+ free(dest->instance);
+
+ cupsFreeOptions(dest->num_options, dest->options);
+ }
+
+ free(dests);
+}
+
+
+/*
+ * 'cupsGetDest()' - Get the named destination from the list.
+ */
+
+cups_dest_t * /* O - Destination pointer or NULL */
+cupsGetDest(const char *name, /* I - Name of destination */
+ const char *instance, /* I - Instance of destination */
+ int num_dests, /* I - Number of destinations */
+ cups_dest_t *dests) /* I - Destinations */
+{
+ int comp; /* Result of comparison */
+
+
+ if (num_dests == 0 || dests == NULL)
+ return (NULL);
+
+ if (name == NULL)
+ {
+ /*
+ * NULL name for default printer.
+ */
+
+ while (num_dests > 0)
+ {
+ if (dests->is_default)
+ return (dests);
+
+ num_dests --;
+ dests ++;
+ }
+ }
+ else
+ {
+ /*
+ * Lookup name and optionally the instance...
+ */
+
+ while (num_dests > 0)
+ {
+ if ((comp = strcasecmp(name, dests->name)) < 0)
+ return (NULL);
+ else if (comp == 0)
+ {
+ if ((instance == NULL && dests->instance == NULL) ||
+ (instance != NULL && dests->instance != NULL &&
+ strcasecmp(instance, dests->instance) == 0))
+ return (dests);
+ }
+
+ num_dests --;
+ dests ++;
+ }
+ }
+
+ return (NULL);
+}
+
+
+/*
+ * 'cupsGetDests()' - Get the list of destinations.
+ */
+
+int /* O - Number of destinations */
+cupsGetDests(cups_dest_t **dests) /* O - Destinations */
+{
+ int i; /* Looping var */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dest; /* Destination pointer */
+ const char *home; /* HOME environment variable */
+ char filename[1024]; /* Local ~/.lpoptions file */
+ const char *defprinter; /* Default printer */
+ char name[1024], /* Copy of printer name */
+ *instance; /* Pointer to instance name */
+ int num_reals; /* Number of real queues */
+ cups_dest_t *reals; /* Real queues */
+
+
+ /*
+ * Initialize destination array...
+ */
+
+ num_dests = 0;
+ *dests = (cups_dest_t *)0;
+
+ /*
+ * Grab the printers and classes...
+ */
+
+ num_dests = cups_get_sdests(CUPS_GET_PRINTERS, num_dests, dests);
+ num_dests = cups_get_sdests(CUPS_GET_CLASSES, num_dests, dests);
+
+ /*
+ * Make a copy of the "real" queues for a later sanity check...
+ */
+
+ if (num_dests > 0)
+ {
+ num_reals = num_dests;
+ reals = calloc(num_reals, sizeof(cups_dest_t));
+
+ if (reals)
+ memcpy(reals, *dests, num_reals * sizeof(cups_dest_t));
+ else
+ num_reals = 0;
+ }
+ else
+ {
+ num_reals = 0;
+ reals = NULL;
+ }
+
+ /*
+ * Grab the default destination...
+ */
+
+ if ((defprinter = cupsGetDefault()) != NULL)
+ {
+ /*
+ * Grab printer and instance name...
+ */
+
+ strlcpy(name, defprinter, sizeof(name));
+
+ if ((instance = strchr(name, '/')) != NULL)
+ *instance++ = '\0';
+
+ /*
+ * Lookup the printer and instance and make it the default...
+ */
+
+ if ((dest = cupsGetDest(name, instance, num_dests, *dests)) != NULL)
+ dest->is_default = 1;
+ }
+ else
+ {
+ /*
+ * This initialization of "instance" is unnecessary, but avoids a
+ * compiler warning...
+ */
+
+ instance = NULL;
+ }
+
+ /*
+ * Load the /etc/cups/lpoptions and ~/.lpoptions files...
+ */
+
+ if ((home = getenv("CUPS_SERVERROOT")) != NULL)
+ {
+ snprintf(filename, sizeof(filename), "%s/lpoptions", home);
+ num_dests = cups_get_dests(filename, num_dests, dests);
+ }
+ else
+ num_dests = cups_get_dests(CUPS_SERVERROOT "/lpoptions", num_dests, dests);
+
+ if ((home = getenv("HOME")) != NULL)
+ {
+ snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
+ num_dests = cups_get_dests(filename, num_dests, dests);
+ }
+
+ /*
+ * Validate the current default destination - this prevents old
+ * Default lines in /etc/cups/lpoptions and ~/.lpoptions from
+ * pointing to a non-existent printer or class...
+ */
+
+ if (num_reals)
+ {
+ /*
+ * See if we have a default printer...
+ */
+
+ if ((dest = cupsGetDest(NULL, NULL, num_dests, *dests)) != NULL)
+ {
+ /*
+ * Have a default; see if it is real...
+ */
+
+ dest = cupsGetDest(dest->name, NULL, num_reals, reals);
+ }
+
+ /*
+ * If dest is NULL, then no default (that exists) is set, so we
+ * need to set a default if one exists...
+ */
+
+ if (dest == NULL && defprinter != NULL)
+ {
+ for (i = 0; i < num_dests; i ++)
+ (*dests)[i].is_default = 0;
+
+ if ((dest = cupsGetDest(name, instance, num_dests, *dests)) != NULL)
+ dest->is_default = 1;
+ }
+
+ /*
+ * Free memory...
+ */
+
+ free(reals);
+ }
+
+ /*
+ * Return the number of destinations...
+ */
+
+ return (num_dests);
+}
+
+
+/*
+ * 'cupsSetDests()' - Set the list of destinations.
+ */
+
+void
+cupsSetDests(int num_dests, /* I - Number of destinations */
+ cups_dest_t *dests) /* I - Destinations */
+{
+ int i, j; /* Looping vars */
+ int wrote; /* Wrote definition? */
+ cups_dest_t *dest; /* Current destination */
+ cups_option_t *option; /* Current option */
+ FILE *fp; /* File pointer */
+ const char *home; /* HOME environment variable */
+ char filename[1024]; /* lpoptions file */
+ int num_temps; /* Number of temporary destinations */
+ cups_dest_t *temps, /* Temporary destinations */
+ *temp; /* Current temporary dest */
+ const char *val; /* Value of temporary option */
+
+
+ /*
+ * Get the server destinations...
+ */
+
+ num_temps = cups_get_sdests(CUPS_GET_PRINTERS, 0, &temps);
+ num_temps = cups_get_sdests(CUPS_GET_CLASSES, num_temps, &temps);
+
+ /*
+ * Figure out which file to write to...
+ */
+
+ if ((home = getenv("CUPS_SERVERROOT")) != NULL)
+ snprintf(filename, sizeof(filename), "%s/lpoptions", home);
+ else
+ strcpy(filename, CUPS_SERVERROOT "/lpoptions");
+
+#ifndef WIN32
+ if (getuid())
+ {
+ /*
+ * Merge in server defaults...
+ */
+
+ num_temps = cups_get_dests(filename, num_temps, &temps);
+
+ /*
+ * Point to user defaults...
+ */
+
+ if ((home = getenv("HOME")) != NULL)
+ snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
+ }
+#endif /* !WIN32 */
+
+ /*
+ * Try to open the file...
+ */
+
+ if ((fp = fopen(filename, "w")) == NULL)
+ {
+ cupsFreeDests(num_temps, temps);
+ return;
+ }
+
+ /*
+ * Write each printer; each line looks like:
+ *
+ * Dest name[/instance] options
+ * Default name[/instance] options
+ */
+
+ for (i = num_dests, dest = dests; i > 0; i --, dest ++)
+ if (dest->instance != NULL || dest->num_options != 0 || dest->is_default)
+ {
+ if (dest->is_default)
+ {
+ fprintf(fp, "Default %s", dest->name);
+ if (dest->instance)
+ fprintf(fp, "/%s", dest->instance);
+
+ wrote = 1;
+ }
+ else
+ wrote = 0;
+
+ if ((temp = cupsGetDest(dest->name, dest->instance, num_temps, temps)) == NULL)
+ temp = cupsGetDest(dest->name, NULL, num_temps, temps);
+
+ for (j = dest->num_options, option = dest->options; j > 0; j --, option ++)
+ {
+ /*
+ * See if the server/global options match these; if so, don't
+ * write 'em.
+ */
+
+ if (temp && (val = cupsGetOption(option->name, temp->num_options,
+ temp->options)) != NULL)
+ {
+ if (strcasecmp(val, option->value) == 0)
+ continue;
+ }
+
+ /*
+ * Options don't match, write to the file...
+ */
+
+ if (!wrote)
+ {
+ fprintf(fp, "Dest %s", dest->name);
+ if (dest->instance)
+ fprintf(fp, "/%s", dest->instance);
+ wrote = 1;
+ }
+
+ if (option->value[0])
+ {
+ if (strchr(option->value, ' ') != NULL)
+ fprintf(fp, " %s=\"%s\"", option->name, option->value);
+ else
+ fprintf(fp, " %s=%s", option->name, option->value);
+ }
+ else
+ fprintf(fp, " %s", option->name);
+ }
+
+ if (wrote)
+ fputs("\n", fp);
+ }
+
+ /*
+ * Free the temporary destinations...
+ */
+
+ cupsFreeDests(num_temps, temps);
+
+ /*
+ * Close the file and return...
+ */
+
+ fclose(fp);
+}
+
+
+/*
+ * 'cups_get_dests()' - Get destinations from a file.
+ */
+
+static int /* O - Number of destinations */
+cups_get_dests(const char *filename, /* I - File to read from */
+ int num_dests, /* I - Number of destinations */
+ cups_dest_t **dests) /* IO - Destinations */
+{
+ int i; /* Looping var */
+ cups_dest_t *dest; /* Current destination */
+ FILE *fp; /* File pointer */
+ char line[8192], /* Line from file */
+ *lineptr, /* Pointer into line */
+ *name, /* Name of destination/option */
+ *instance; /* Instance of destination */
+ const char *printer; /* PRINTER or LPDEST */
+
+
+ /*
+ * Check environment variables...
+ */
+
+ if ((printer = getenv("LPDEST")) == NULL)
+ if ((printer = getenv("PRINTER")) != NULL)
+ if (strcmp(printer, "lp") == 0)
+ printer = NULL;
+
+ /*
+ * Try to open the file...
+ */
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ return (num_dests);
+
+ /*
+ * Read each printer; each line looks like:
+ *
+ * Dest name[/instance] options
+ * Default name[/instance] options
+ */
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * See what type of line it is...
+ */
+
+ if (strncasecmp(line, "dest", 4) == 0 && isspace(line[4]))
+ lineptr = line + 4;
+ else if (strncasecmp(line, "default", 7) == 0 && isspace(line[7]))
+ lineptr = line + 7;
+ else
+ continue;
+
+ /*
+ * Skip leading whitespace...
+ */
+
+ while (isspace(*lineptr))
+ lineptr ++;
+
+ if (!*lineptr)
+ continue;
+
+ name = lineptr;
+
+ /*
+ * Search for an instance...
+ */
+
+ while (!isspace(*lineptr) && *lineptr && *lineptr != '/')
+ lineptr ++;
+
+ if (!*lineptr)
+ continue;
+
+ if (*lineptr == '/')
+ {
+ /*
+ * Found an instance...
+ */
+
+ *lineptr++ = '\0';
+ instance = lineptr;
+
+ /*
+ * Search for an instance...
+ */
+
+ while (!isspace(*lineptr) && *lineptr)
+ lineptr ++;
+ }
+ else
+ instance = NULL;
+
+ *lineptr++ = '\0';
+
+ /*
+ * See if the primary instance of the destination exists; if not,
+ * ignore this entry and move on...
+ */
+
+ if (cupsGetDest(name, NULL, num_dests, *dests) == NULL)
+ continue;
+
+ /*
+ * Add the destination...
+ */
+
+ num_dests = cupsAddDest(name, instance, num_dests, dests);
+
+ if ((dest = cupsGetDest(name, instance, num_dests, *dests)) == NULL)
+ {
+ /*
+ * Out of memory!
+ */
+
+ fclose(fp);
+ return (num_dests);
+ }
+
+ /*
+ * Add options until we hit the end of the line...
+ */
+
+ dest->num_options = cupsParseOptions(lineptr, dest->num_options,
+ &(dest->options));
+
+ /*
+ * Set this as default if needed...
+ */
+
+ if (strncasecmp(line, "default", 7) == 0 && printer == NULL)
+ {
+ for (i = 0; i < num_dests; i ++)
+ (*dests)[i].is_default = 0;
+
+ dest->is_default = 1;
+ }
+ }
+
+ /*
+ * Close the file and return...
+ */
+
+ fclose(fp);
+
+ return (num_dests);
+}
+
+
+/*
+ * 'cups_get_sdests()' - Get destinations from a server.
+ */
+
+static int /* O - Number of destinations */
+cups_get_sdests(ipp_op_t op, /* I - get-printers or get-classes */
+ int num_dests, /* I - Number of destinations */
+ cups_dest_t **dests) /* IO - Destinations */
+{
+ cups_dest_t *dest; /* Current destination */
+ http_t *http; /* HTTP connection */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ const char *name; /* printer-name attribute */
+ char job_sheets[1024]; /* job-sheets option */
+ static const char *pattrs[] = /* Attributes we're interested in */
+ {
+ "printer-name",
+ "job-sheets-default"
+ };
+
+
+ /*
+ * Connect to the CUPS server...
+ */
+
+ if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
+ return (num_dests);
+
+ /*
+ * Build a CUPS_GET_PRINTERS or CUPS_GET_CLASSES request, which require
+ * the following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = op;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
+ NULL, pattrs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a printer...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this job...
+ */
+
+ name = NULL;
+
+ strcpy(job_sheets, "");
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
+ {
+ if (strcmp(attr->name, "printer-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ name = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "job-sheets-default") == 0 &&
+ (attr->value_tag == IPP_TAG_KEYWORD ||
+ attr->value_tag == IPP_TAG_NAME))
+ {
+ if (attr->num_values == 2)
+ snprintf(job_sheets, sizeof(job_sheets), "%s,%s",
+ attr->values[0].string.text, attr->values[1].string.text);
+ else
+ strcpy(job_sheets, attr->values[0].string.text);
+ }
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (!name)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ num_dests = cupsAddDest(name, NULL, num_dests, dests);
+
+ if ((dest = cupsGetDest(name, NULL, num_dests, *dests)) != NULL)
+ if (job_sheets[0])
+ dest->num_options = cupsAddOption("job-sheets", job_sheets, 0,
+ &(dest->options));
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+
+ /*
+ * Close the server connection...
+ */
+
+ httpClose(http);
+
+ /*
+ * Return the count...
+ */
+
+ return (num_dests);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/emit.c b/cups/emit.c
new file mode 100644
index 000000000..6c6486e7f
--- /dev/null
+++ b/cups/emit.c
@@ -0,0 +1,548 @@
+/*
+ * "$Id$"
+ *
+ * PPD code emission routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * PostScript is a trademark of Adobe Systems, Inc.
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ppdCollect() - Collect all marked options that reside in the
+ * specified section.
+ * ppdEmit() - Emit code for marked options to a file.
+ * ppdEmitFd() - Emit code for marked options to a file.
+ * ppdEmitJCL() - Emit code for JCL options to a file.
+ * ppd_handle_media() - Handle media selection...
+ * ppd_sort() - Sort options by ordering numbers...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "ppd.h"
+#include <stdlib.h>
+#include "string.h"
+
+#if defined(WIN32) || defined(__EMX__)
+# include <io.h>
+#else
+# include <unistd.h>
+#endif /* WIN32 || __EMX__ */
+
+
+/*
+ * Local functions...
+ */
+
+static void ppd_handle_media(ppd_file_t *ppd);
+static int ppd_sort(ppd_choice_t **c1, ppd_choice_t **c2);
+
+
+/*
+ * Local globals...
+ */
+
+static const char *ppd_custom_code =
+ "pop pop pop\n"
+ "<</PageSize[5 -2 roll]/ImagingBBox null>>setpagedevice\n";
+
+
+/*
+ * 'ppdCollect()' - Collect all marked options that reside in the specified
+ * section.
+ */
+
+int /* O - Number of options marked */
+ppdCollect(ppd_file_t *ppd, /* I - PPD file data */
+ ppd_section_t section, /* I - Section to collect */
+ ppd_choice_t ***choices) /* O - Pointers to choices */
+{
+ int i, j, k, m; /* Looping vars */
+ ppd_group_t *g, /* Current group */
+ *sg; /* Current sub-group */
+ ppd_option_t *o; /* Current option */
+ ppd_choice_t *c; /* Current choice */
+ int count; /* Number of choices collected */
+ ppd_choice_t **collect; /* Collected choices */
+
+
+ if (ppd == NULL)
+ return (0);
+
+ /*
+ * Allocate memory for up to 1000 selected choices...
+ */
+
+ count = 0;
+ collect = calloc(sizeof(ppd_choice_t *), 1000);
+
+ /*
+ * Loop through all options and add choices as needed...
+ */
+
+ for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++)
+ {
+ for (j = g->num_options, o = g->options; j > 0; j --, o ++)
+ if (o->section == section)
+ for (k = o->num_choices, c = o->choices; k > 0; k --, c ++)
+ if (c->marked && count < 1000)
+ {
+ collect[count] = c;
+ count ++;
+ }
+
+ for (j = g->num_subgroups, sg = g->subgroups; j > 0; j --, sg ++)
+ for (k = sg->num_options, o = sg->options; k > 0; k --, o ++)
+ if (o->section == section)
+ for (m = o->num_choices, c = o->choices; m > 0; m --, c ++)
+ if (c->marked && count < 1000)
+ {
+ collect[count] = c;
+ count ++;
+ }
+ }
+
+ /*
+ * If we have more than 1 marked choice, sort them...
+ */
+
+ if (count > 1)
+ qsort(collect, count, sizeof(ppd_choice_t *),
+ (int (*)(const void *, const void *))ppd_sort);
+
+ /*
+ * Return the array and number of choices; if 0, free the array since
+ * it isn't needed.
+ */
+
+ if (count > 0)
+ {
+ *choices = collect;
+ return (count);
+ }
+ else
+ {
+ *choices = NULL;
+ free(collect);
+ return (0);
+ }
+}
+
+
+/*
+ * 'ppdEmit()' - Emit code for marked options to a file.
+ */
+
+int /* O - 0 on success, -1 on failure */
+ppdEmit(ppd_file_t *ppd, /* I - PPD file record */
+ FILE *fp, /* I - File to write to */
+ ppd_section_t section) /* I - Section to write */
+{
+ int i, /* Looping var */
+ count; /* Number of choices */
+ ppd_choice_t **choices; /* Choices */
+ ppd_size_t *size; /* Custom page size */
+
+
+ /*
+ * Use PageSize or PageRegion as required...
+ */
+
+ ppd_handle_media(ppd);
+
+ /*
+ * Collect the options we need to emit and emit them!
+ */
+
+ if ((count = ppdCollect(ppd, section, &choices)) == 0)
+ return (0);
+
+ for (i = 0; i < count; i ++)
+ if (section != PPD_ORDER_EXIT && section != PPD_ORDER_JCL)
+ {
+ /*
+ * Send wrapper commands to prevent printer errors for unsupported
+ * options...
+ */
+
+ if (fputs("[{\n", fp) < 0)
+ {
+ free(choices);
+ return (-1);
+ }
+
+ /*
+ * Send DSC comments with option...
+ */
+
+ if (fprintf(fp, "%%%%BeginFeature: *%s %s\n",
+ ((ppd_option_t *)choices[i]->option)->keyword,
+ choices[i]->choice) < 0)
+ {
+ free(choices);
+ return (-1);
+ }
+
+ if ((strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageSize") == 0 ||
+ strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageRegion") == 0) &&
+ strcasecmp(choices[i]->choice, "Custom") == 0)
+ {
+ /*
+ * Variable size; write out standard size options (this should
+ * eventually be changed to use the parameter positions defined
+ * in the PPD file...)
+ */
+
+ size = ppdPageSize(ppd, "Custom");
+ fprintf(fp, "%.0f %.0f 0 0 0\n", size->width, size->length);
+
+ if (choices[i]->code == NULL)
+ {
+ /*
+ * This can happen with certain buggy PPD files that don't include
+ * a CustomPageSize command sequence... We just use a generic
+ * Level 2 command sequence...
+ */
+
+ fputs(ppd_custom_code, fp);
+ }
+ }
+
+ if (choices[i]->code != NULL && choices[i]->code[0] != '\0')
+ {
+ if (fputs(choices[i]->code, fp) < 0)
+ {
+ free(choices);
+ return (-1);
+ }
+
+ if (choices[i]->code[strlen(choices[i]->code) - 1] != '\n')
+ putc('\n', fp);
+ }
+
+ if (fputs("%%EndFeature\n", fp) < 0)
+ {
+ free(choices);
+ return (-1);
+ }
+
+ if (fputs("} stopped cleartomark\n", fp) < 0)
+ {
+ free(choices);
+ return (-1);
+ }
+ }
+ else if (fputs(choices[i]->code, fp) < 0)
+ {
+ free(choices);
+ return (-1);
+ }
+
+ free(choices);
+ return (0);
+}
+
+
+/*
+ * 'ppdEmitFd()' - Emit code for marked options to a file.
+ */
+
+int /* O - 0 on success, -1 on failure */
+ppdEmitFd(ppd_file_t *ppd, /* I - PPD file record */
+ int fd, /* I - File to write to */
+ ppd_section_t section) /* I - Section to write */
+{
+ int i, /* Looping var */
+ count; /* Number of choices */
+ ppd_choice_t **choices; /* Choices */
+ ppd_size_t *size; /* Custom page size */
+ char buf[1024]; /* Output buffer for feature */
+
+
+ /*
+ * Use PageSize or PageRegion as required...
+ */
+
+ ppd_handle_media(ppd);
+
+ /*
+ * Collect the options we need to emit and emit them!
+ */
+
+ if ((count = ppdCollect(ppd, section, &choices)) == 0)
+ return (0);
+
+ for (i = 0; i < count; i ++)
+ if (section != PPD_ORDER_EXIT && section != PPD_ORDER_JCL)
+ {
+ /*
+ * Send wrapper commands to prevent printer errors for unsupported
+ * options...
+ */
+
+ if (write(fd, "[{\n", 3) < 1)
+ {
+ free(choices);
+ return (-1);
+ }
+
+ /*
+ * Send DSC comments with option...
+ */
+
+ snprintf(buf, sizeof(buf), "%%%%BeginFeature: *%s %s\n",
+ ((ppd_option_t *)choices[i]->option)->keyword,
+ choices[i]->choice);
+
+ if (write(fd, buf, strlen(buf)) < 1)
+ {
+ free(choices);
+ return (-1);
+ }
+
+ if ((strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageSize") == 0 ||
+ strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageRegion") == 0) &&
+ strcasecmp(choices[i]->choice, "Custom") == 0)
+ {
+ /*
+ * Variable size; write out standard size options (this should
+ * eventually be changed to use the parameter positions defined
+ * in the PPD file...)
+ */
+
+ size = ppdPageSize(ppd, "Custom");
+ snprintf(buf, sizeof(buf), "%.0f %.0f 0 0 0\n", size->width,
+ size->length);
+
+ if (write(fd, buf, strlen(buf)) < 1)
+ {
+ free(choices);
+ return (-1);
+ }
+
+ if (choices[i]->code == NULL)
+ {
+ /*
+ * This can happen with certain buggy PPD files that don't include
+ * a CustomPageSize command sequence... We just use a generic
+ * Level 2 command sequence...
+ */
+
+ if (write(fd, ppd_custom_code, strlen(ppd_custom_code)) < 1)
+ {
+ free(choices);
+ return (-1);
+ }
+ }
+ }
+
+ if (choices[i]->code != NULL && choices[i]->code[0] != '\0')
+ {
+ if (write(fd, choices[i]->code, strlen(choices[i]->code)) < 1)
+ {
+ free(choices);
+ return (-1);
+ }
+ }
+
+ if (write(fd, "%%EndFeature\n", 13) < 1)
+ {
+ free(choices);
+ return (-1);
+ }
+
+ if (write(fd, "} stopped cleartomark\n", 22) < 1)
+ {
+ free(choices);
+ return (-1);
+ }
+ }
+ else if (write(fd, choices[i]->code, strlen(choices[i]->code)) < 1)
+ {
+ free(choices);
+ return (-1);
+ }
+
+ free(choices);
+ return (0);
+}
+
+
+/*
+ * 'ppdEmitJCL()' - Emit code for JCL options to a file.
+ */
+
+int /* O - 0 on success, -1 on failure */
+ppdEmitJCL(ppd_file_t *ppd, /* I - PPD file record */
+ FILE *fp, /* I - File to write to */
+ int job_id, /* I - Job ID */
+ const char *user, /* I - Username */
+ const char *title) /* I - Title */
+{
+ const char *ptr; /* Pointer into JCL string */
+
+
+ /*
+ * Range check the input...
+ */
+
+ if (ppd == NULL || ppd->jcl_begin == NULL || ppd->jcl_ps == NULL)
+ return (0);
+
+ /*
+ * See if the printer supports HP PJL...
+ */
+
+ if (strncmp(ppd->jcl_begin, "\033%-12345X@", 10) == 0)
+ {
+ /*
+ * This printer uses HP PJL commands for output; filter the output
+ * so that we only have a single "@PJL JOB" command in the header...
+ */
+
+ fputs("\033%-12345X", fp);
+ for (ptr = ppd->jcl_begin + 9; *ptr;)
+ if (strncmp(ptr, "@PJL JOB", 8) == 0)
+ {
+ /*
+ * Skip job command...
+ */
+
+ for (;*ptr; ptr ++)
+ if (*ptr == '\n')
+ break;
+
+ if (*ptr)
+ ptr ++;
+ }
+ else
+ {
+ /*
+ * Copy line...
+ */
+
+ for (;*ptr; ptr ++)
+ {
+ putc(*ptr, fp);
+ if (*ptr == '\n')
+ break;
+ }
+
+ if (*ptr)
+ ptr ++;
+ }
+
+ /*
+ * Eliminate any path info from the job title...
+ */
+
+ if ((ptr = strrchr(title, '/')) != NULL)
+ title = ptr + 1;
+
+ /*
+ * Send PJL JOB command before we enter PostScript mode...
+ */
+
+ fprintf(fp, "@PJL JOB NAME = \"%s\" DISPLAY = \"%d %s %s\"\n", title,
+ job_id, user, title);
+ }
+ else
+ fputs(ppd->jcl_begin, stdout);
+
+ ppdEmit(ppd, stdout, PPD_ORDER_JCL);
+ fputs(ppd->jcl_ps, stdout);
+
+ return (0);
+}
+
+
+/*
+ * 'ppd_handle_media()' - Handle media selection...
+ */
+
+static void
+ppd_handle_media(ppd_file_t *ppd)
+{
+ ppd_choice_t *manual_feed, /* ManualFeed choice, if any */
+ *input_slot; /* InputSlot choice, if any */
+ ppd_size_t *size; /* Current media size */
+
+
+ /*
+ * This function determines if the user has selected a media source
+ * via the InputSlot or ManualFeed options; if so, it marks the
+ * PageRegion option corresponding to the current media size.
+ * Otherwise it marks the PageSize option.
+ */
+
+ if ((size = ppdPageSize(ppd, NULL)) == NULL)
+ return;
+
+ manual_feed = ppdFindMarkedChoice(ppd, "ManualFeed");
+ input_slot = ppdFindMarkedChoice(ppd, "InputSlot");
+
+ if (strcasecmp(size->name, "Custom") == 0 ||
+ (manual_feed == NULL && input_slot == NULL) ||
+ (manual_feed != NULL && strcasecmp(manual_feed->choice, "False") == 0) ||
+ (input_slot != NULL && (input_slot->code == NULL || !input_slot->code[0])))
+ {
+ /*
+ * Manual feed was not selected and/or the input slot selection does
+ * not contain any PostScript code. Use the PageSize option...
+ */
+
+ ppdMarkOption(ppd, "PageSize", size->name);
+ }
+ else
+ {
+ /*
+ * Manual feed was selected and/or the input slot selection contains
+ * PostScript code. Use the PageRegion option...
+ */
+
+ ppdMarkOption(ppd, "PageRegion", size->name);
+ }
+}
+
+
+/*
+ * 'ppd_sort()' - Sort options by ordering numbers...
+ */
+
+static int /* O - -1 if c1 < c2, 0 if equal, 1 otherwise */
+ppd_sort(ppd_choice_t **c1, /* I - First choice */
+ ppd_choice_t **c2) /* I - Second choice */
+{
+ if (((ppd_option_t *)(*c1)->option)->order < ((ppd_option_t *)(*c2)->option)->order)
+ return (-1);
+ else if (((ppd_option_t *)(*c1)->option)->order > ((ppd_option_t *)(*c2)->option)->order)
+ return (1);
+ else
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/encode.c b/cups/encode.c
new file mode 100644
index 000000000..c86548f1d
--- /dev/null
+++ b/cups/encode.c
@@ -0,0 +1,383 @@
+/*
+ * "$Id$"
+ *
+ * Option encoding routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * cupsEncodeOptions() - Encode printer options into IPP attributes.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include "string.h"
+#include "debug.h"
+
+
+/*
+ * Local list of option names and the value tags they should use...
+ */
+
+typedef struct
+{
+ const char *name;
+ ipp_tag_t value_tag;
+} ipp_option_t;
+
+static ipp_option_t ipp_options[] =
+ {
+ { "blackplot", IPP_TAG_BOOLEAN },
+ { "brightness", IPP_TAG_INTEGER },
+ { "columns", IPP_TAG_INTEGER },
+ { "copies", IPP_TAG_INTEGER },
+ { "finishings", IPP_TAG_ENUM },
+ { "fitplot", IPP_TAG_BOOLEAN },
+ { "gamma", IPP_TAG_INTEGER },
+ { "hue", IPP_TAG_INTEGER },
+ { "job-priority", IPP_TAG_INTEGER },
+ { "landscape", IPP_TAG_BOOLEAN },
+ { "mirror", IPP_TAG_BOOLEAN },
+ { "natural-scaling", IPP_TAG_INTEGER },
+ { "number-up", IPP_TAG_INTEGER },
+ { "orientation-requested", IPP_TAG_ENUM },
+ { "page-bottom", IPP_TAG_INTEGER },
+ { "page-left", IPP_TAG_INTEGER },
+ { "page-ranges", IPP_TAG_RANGE },
+ { "page-right", IPP_TAG_INTEGER },
+ { "page-top", IPP_TAG_INTEGER },
+ { "penwidth", IPP_TAG_INTEGER },
+ { "ppi", IPP_TAG_INTEGER },
+ { "prettyprint", IPP_TAG_BOOLEAN },
+ { "printer-resolution", IPP_TAG_RESOLUTION },
+ { "print-quality", IPP_TAG_ENUM },
+ { "saturation", IPP_TAG_INTEGER },
+ { "scaling", IPP_TAG_INTEGER },
+ { "wrap", IPP_TAG_BOOLEAN }
+ };
+
+
+/*
+ * 'cupsEncodeOptions()' - Encode printer options into IPP attributes.
+ */
+
+void
+cupsEncodeOptions(ipp_t *ipp, /* I - Request to add to */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ int i, j; /* Looping vars */
+ int count; /* Number of values */
+ char *s, /* Pointer into option value */
+ *val, /* Pointer to option value */
+ *copy, /* Copy of option value */
+ *sep; /* Option separator */
+ ipp_attribute_t *attr; /* IPP job-id attribute */
+
+
+ DEBUG_printf(("cupsEncodeOptions(%p, %d, %p)\n", ipp, num_options, options));
+
+ if (ipp == NULL || num_options < 1 || options == NULL)
+ return;
+
+ /*
+ * Handle the document format stuff first...
+ */
+
+ if ((val = (char *)cupsGetOption("document-format", num_options, options)) != NULL)
+ ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
+ NULL, val);
+ else if (cupsGetOption("raw", num_options, options))
+ ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
+ NULL, "application/vnd.cups-raw");
+ else
+ ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
+ NULL, "application/octet-stream");
+
+ /*
+ * Then add all other options...
+ */
+
+ for (i = 0; i < num_options; i ++)
+ {
+ /*
+ * Skip document format options - handled above...
+ */
+
+ if (strcasecmp(options[i].name, "raw") == 0 ||
+ strcasecmp(options[i].name, "document-format") == 0 ||
+ !options[i].name[0])
+ continue;
+
+ /*
+ * Count the number of values...
+ */
+
+ for (count = 1, sep = options[i].value; *sep; sep ++)
+ {
+ if (*sep == '\'')
+ {
+ /*
+ * Skip quoted option value...
+ */
+
+ sep ++;
+
+ while (*sep && *sep != '\'')
+ sep ++;
+
+ if (!*sep)
+ sep --;
+ }
+ else if (*sep == '\"')
+ {
+ /*
+ * Skip quoted option value...
+ */
+
+ sep ++;
+
+ while (*sep && *sep != '\"')
+ sep ++;
+
+ if (!*sep)
+ sep --;
+ }
+ else if (*sep == ',')
+ count ++;
+ else if (*sep == '\\' && sep[1])
+ sep ++;
+ }
+
+ DEBUG_printf(("cupsEncodeOptions: option = \'%s\', count = %d\n",
+ options[i].name, count));
+
+ /*
+ * Allocate memory for the attribute values...
+ */
+
+ if ((attr = _ipp_add_attr(ipp, count)) == NULL)
+ {
+ /*
+ * Ran out of memory!
+ */
+
+ DEBUG_puts("cupsEncodeOptions: Ran out of memory for attributes!");
+ return;
+ }
+
+ /*
+ * Now figure out what type of value we have...
+ */
+
+ attr->group_tag = IPP_TAG_JOB;
+
+ if (strcasecmp(options[i].value, "true") == 0 ||
+ strcasecmp(options[i].value, "false") == 0 ||
+ strcasecmp(options[i].value, "yes") == 0 ||
+ strcasecmp(options[i].value, "no") == 0)
+ attr->value_tag = IPP_TAG_BOOLEAN;
+ else
+ attr->value_tag = IPP_TAG_NAME;
+
+ for (j = 0; j < (int)(sizeof(ipp_options) / sizeof(ipp_options[0])); j ++)
+ if (strcasecmp(options[i].name, ipp_options[j].name) == 0)
+ {
+ attr->value_tag = ipp_options[j].value_tag;
+ break;
+ }
+
+ /*
+ * Copy the name over...
+ */
+
+ if ((attr->name = strdup(options[i].name)) == NULL)
+ {
+ /*
+ * Ran out of memory!
+ */
+
+ DEBUG_puts("cupsEncodeOptions: Ran out of memory for name!");
+ return;
+ }
+
+ if (count > 1)
+ {
+ /*
+ * Make a copy of the value we can fiddle with...
+ */
+
+ if ((copy = strdup(options[i].value)) == NULL)
+ {
+ /*
+ * Ran out of memory!
+ */
+
+ DEBUG_puts("cupsEncodeOptions: Ran out of memory for value copy!");
+ return;
+ }
+
+ val = copy;
+ }
+ else
+ {
+ /*
+ * Since we have a single value, use the value directly...
+ */
+
+ val = options[i].value;
+ copy = NULL;
+ }
+
+ /*
+ * Scan the value string for values...
+ */
+
+ for (j = 0; *val != '\0' || j == 0; val = sep, j ++)
+ {
+ /*
+ * Find the end of this value and mark it if needed...
+ */
+
+ if ((sep = strchr(val, ',')) != NULL)
+ *sep++ = '\0';
+ else
+ sep = val + strlen(val);
+
+ /*
+ * Copy the option value(s) over as needed by the type...
+ */
+
+ switch (attr->value_tag)
+ {
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ /*
+ * Integer/enumeration value...
+ */
+
+ attr->values[j].integer = strtol(val, &s, 0);
+
+ DEBUG_printf(("cupsEncodeOptions: Adding integer option value %d...\n",
+ attr->values[j].integer));
+ break;
+
+ case IPP_TAG_BOOLEAN :
+ if (strcasecmp(val, "true") == 0 || strcasecmp(val, "yes") == 0)
+ {
+ /*
+ * Boolean value - true...
+ */
+
+ attr->values[j].boolean = 1;
+
+ DEBUG_puts("cupsEncodeOptions: Added boolean true value...");
+ }
+ else
+ {
+ /*
+ * Boolean value - false...
+ */
+
+ attr->values[j].boolean = 0;
+
+ DEBUG_puts("cupsEncodeOptions: Added boolean false value...");
+ }
+ break;
+
+ case IPP_TAG_RANGE :
+ /*
+ * Range...
+ */
+
+ if (*val == '-')
+ {
+ attr->values[j].range.lower = 1;
+ s = val;
+ }
+ else
+ attr->values[j].range.lower = strtol(val, &s, 0);
+
+ if (*s == '-')
+ {
+ if (s[1])
+ attr->values[j].range.upper = strtol(s + 1, NULL, 0);
+ else
+ attr->values[j].range.upper = 2147483647;
+ }
+ else
+ attr->values[j].range.upper = attr->values[j].range.lower;
+
+ DEBUG_printf(("cupsEncodeOptions: Added range option value %d-%d...\n",
+ attr->values[j].range.lower,
+ attr->values[j].range.upper));
+ break;
+
+ case IPP_TAG_RESOLUTION :
+ /*
+ * Resolution...
+ */
+
+ attr->values[j].resolution.xres = strtol(val, &s, 0);
+
+ if (*s == 'x')
+ attr->values[j].resolution.yres = strtol(s + 1, &s, 0);
+ else
+ attr->values[j].resolution.yres = attr->values[j].resolution.xres;
+
+ if (strcasecmp(s, "dpc") == 0)
+ attr->values[j].resolution.units = IPP_RES_PER_CM;
+ else
+ attr->values[j].resolution.units = IPP_RES_PER_INCH;
+
+ DEBUG_printf(("cupsEncodeOptions: Adding resolution option value %s...\n",
+ val));
+ break;
+
+ default :
+ if ((attr->values[j].string.text = strdup(val)) == NULL)
+ {
+ /*
+ * Ran out of memory!
+ */
+
+ DEBUG_puts("cupsEncodeOptions: Ran out of memory for string!");
+ return;
+ }
+
+ DEBUG_printf(("cupsEncodeOptions: Added string value \'%s\'...\n",
+ val));
+ break;
+ }
+ }
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/http-addr.c b/cups/http-addr.c
new file mode 100644
index 000000000..7abb1a67d
--- /dev/null
+++ b/cups/http-addr.c
@@ -0,0 +1,118 @@
+/*
+ * "$Id$"
+ *
+ * HTTP host/address routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * httpGetHostByName() - Lookup a hostname or IP address, and return
+ * address records for the specified name.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "string.h"
+
+#include "http.h"
+
+
+/*
+ * 'httpGetHostByName()' - Lookup a hostname or IP address, and return
+ * address records for the specified name.
+ */
+
+struct hostent * /* O - Host entry */
+httpGetHostByName(const char *name) /* I - Hostname or IP address */
+{
+ const char *nameptr; /* Pointer into name */
+ unsigned ip[4]; /* IP address components */
+ static unsigned packed_ip; /* Packed IPv4 address */
+ static char *packed_ptr[2]; /* Pointer to packed address */
+ static struct hostent host_ip; /* Host entry for IP address */
+
+#if defined(__APPLE__)
+ /* OS X hack to avoid it's ocassional long delay in lookupd */
+ static char sLoopback[] = "127.0.0.1";
+ if (strcmp(name, "localhost") == 0)
+ name = sLoopback;
+#endif /* __APPLE__ */
+
+ /*
+ * This function is needed because some operating systems have a
+ * buggy implementation of httpGetHostByName() that does not support
+ * IP addresses. If the first character of the name string is a
+ * number, then sscanf() is used to extract the IP components.
+ * We then pack the components into an IPv4 address manually,
+ * since the inet_aton() function is deprecated. We use the
+ * htonl() macro to get the right byte order for the address.
+ */
+
+ for (nameptr = name; isdigit(*nameptr) || *nameptr == '.'; nameptr ++);
+
+ if (!*nameptr)
+ {
+ /*
+ * We have an IP address; break it up and provide the host entry
+ * to the caller. Currently only supports IPv4 addresses, although
+ * it should be trivial to support IPv6 in CUPS 1.2.
+ */
+
+ if (sscanf(name, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) != 4)
+ return (NULL); /* Must have 4 numbers */
+
+ packed_ip = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | ip[3]));
+
+ /*
+ * Fill in the host entry and return it...
+ */
+
+ host_ip.h_name = (char *)name;
+ host_ip.h_aliases = NULL;
+ host_ip.h_addrtype = AF_INET;
+ host_ip.h_length = 4;
+ host_ip.h_addr_list = packed_ptr;
+ packed_ptr[0] = (char *)(&packed_ip);
+ packed_ptr[1] = NULL;
+
+ return (&host_ip);
+ }
+ else
+ {
+ /*
+ * Use the gethostbyname() function to get the IP address for
+ * the name...
+ */
+
+ return (gethostbyname(name));
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/http-support.c b/cups/http-support.c
new file mode 100644
index 000000000..36632ed79
--- /dev/null
+++ b/cups/http-support.c
@@ -0,0 +1,317 @@
+/*
+ * "$Id$"
+ *
+ * HTTP support routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * httpSeparate() - Separate a Universal Resource Identifier into its
+ * components.
+ * httpStatus() - Return a short string describing a HTTP status code.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include "string.h"
+
+#include "http.h"
+#include "ipp.h"
+
+
+/*
+ * 'httpSeparate()' - Separate a Universal Resource Identifier into its
+ * components.
+ */
+
+void
+httpSeparate(const char *uri, /* I - Universal Resource Identifier */
+ char *method, /* O - Method [32] (http, https, etc.) */
+ char *username, /* O - Username [32] */
+ char *host, /* O - Hostname [32] */
+ int *port, /* O - Port number to use */
+ char *resource) /* O - Resource/filename [1024] */
+{
+ char *ptr; /* Pointer into string... */
+ const char *atsign, /* @ sign */
+ *slash; /* Separator */
+ char safeuri[HTTP_MAX_URI]; /* "Safe" local copy of URI */
+ char quoted; /* Quoted character */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (uri == NULL || method == NULL || username == NULL || host == NULL ||
+ port == NULL || resource == NULL)
+ return;
+
+ /*
+ * Copy the URL to a local string to make sure we don't have a URL
+ * longer than HTTP_MAX_URI characters long...
+ */
+
+ strlcpy(safeuri, uri, sizeof(safeuri));
+
+ uri = safeuri;
+
+ /*
+ * Grab the method portion of the URI...
+ */
+
+ if (strncmp(uri, "//", 2) == 0)
+ {
+ /*
+ * Workaround for HP IPP client bug...
+ */
+
+ strcpy(method, "ipp");
+ }
+ else
+ {
+ /*
+ * Standard URI with method...
+ */
+
+ for (ptr = host; *uri != ':' && *uri != '\0'; uri ++)
+ if (ptr < (host + HTTP_MAX_URI - 1))
+ *ptr++ = *uri;
+
+ *ptr = '\0';
+ if (*uri == ':')
+ uri ++;
+
+ /*
+ * If the method contains a period or slash, then it's probably
+ * hostname/filename...
+ */
+
+ if (strchr(host, '.') != NULL || strchr(host, '/') != NULL || *uri == '\0')
+ {
+ if ((ptr = strchr(host, '/')) != NULL)
+ {
+ strlcpy(resource, ptr, HTTP_MAX_URI);
+ *ptr = '\0';
+ }
+ else
+ resource[0] = '\0';
+
+ if (isdigit(*uri))
+ {
+ /*
+ * OK, we have "hostname:port[/resource]"...
+ */
+
+ *port = strtol(uri, (char **)&uri, 10);
+
+ if (*uri == '/')
+ strlcpy(resource, uri, HTTP_MAX_URI);
+ }
+ else
+ *port = 631;
+
+ strcpy(method, "http");
+ username[0] = '\0';
+ return;
+ }
+ else
+ strlcpy(method, host, 32);
+ }
+
+ /*
+ * If the method starts with less than 2 slashes then it is a local resource...
+ */
+
+ if (strncmp(uri, "//", 2) != 0)
+ {
+ strlcpy(resource, uri, HTTP_MAX_URI);
+
+ username[0] = '\0';
+ host[0] = '\0';
+ *port = 0;
+ return;
+ }
+
+ /*
+ * Grab the username, if any...
+ */
+
+ while (*uri == '/')
+ uri ++;
+
+ if ((slash = strchr(uri, '/')) == NULL)
+ slash = uri + strlen(uri);
+
+ if ((atsign = strchr(uri, '@')) != NULL && atsign < slash)
+ {
+ /*
+ * Got a username:password combo...
+ */
+
+ for (ptr = username; uri < atsign; uri ++)
+ if (ptr < (username + HTTP_MAX_URI - 1))
+ {
+ if (*uri == '%' && isxdigit(uri[1]) && isxdigit(uri[2]))
+ {
+ /*
+ * Grab a hex-encoded username and password...
+ */
+
+ uri ++;
+ if (isalpha(*uri))
+ quoted = (tolower(*uri) - 'a' + 10) << 4;
+ else
+ quoted = (*uri - '0') << 4;
+
+ uri ++;
+ if (isalpha(*uri))
+ quoted |= tolower(*uri) - 'a' + 10;
+ else
+ quoted |= *uri - '0';
+
+ *ptr++ = quoted;
+ }
+ else
+ *ptr++ = *uri;
+ }
+
+ *ptr = '\0';
+
+ uri = atsign + 1;
+ }
+ else
+ username[0] = '\0';
+
+ /*
+ * Grab the hostname...
+ */
+
+ for (ptr = host; *uri != ':' && *uri != '/' && *uri != '\0'; uri ++)
+ if (ptr < (host + HTTP_MAX_URI - 1))
+ *ptr++ = *uri;
+
+ *ptr = '\0';
+
+ if (*uri != ':')
+ {
+ if (strcasecmp(method, "http") == 0)
+ *port = 80;
+ else if (strcasecmp(method, "https") == 0)
+ *port = 443;
+ else if (strcasecmp(method, "ipp") == 0)
+ *port = ippPort();
+ else if (strcasecmp(method, "socket") == 0) /* Not registered yet... */
+ *port = 9100;
+ else
+ *port = 0;
+ }
+ else
+ {
+ /*
+ * Parse port number...
+ */
+
+ *port = 0;
+ uri ++;
+ while (isdigit(*uri))
+ {
+ *port = (*port * 10) + *uri - '0';
+ uri ++;
+ }
+ }
+
+ if (*uri == '\0')
+ {
+ /*
+ * Hostname but no port or path...
+ */
+
+ resource[0] = '/';
+ resource[1] = '\0';
+ return;
+ }
+
+ /*
+ * The remaining portion is the resource string...
+ */
+
+ strlcpy(resource, uri, HTTP_MAX_URI);
+}
+
+
+/*
+ * 'httpStatus()' - Return a short string describing a HTTP status code.
+ */
+
+const char * /* O - String or NULL */
+httpStatus(http_status_t status) /* I - HTTP status code */
+{
+ switch (status)
+ {
+ case HTTP_CONTINUE :
+ return ("Continue");
+ case HTTP_SWITCHING_PROTOCOLS :
+ return ("Switching Protocols");
+ case HTTP_OK :
+ return ("OK");
+ case HTTP_CREATED :
+ return ("Created");
+ case HTTP_ACCEPTED :
+ return ("Accepted");
+ case HTTP_NO_CONTENT :
+ return ("No Content");
+ case HTTP_NOT_MODIFIED :
+ return ("Not Modified");
+ case HTTP_BAD_REQUEST :
+ return ("Bad Request");
+ case HTTP_UNAUTHORIZED :
+ return ("Unauthorized");
+ case HTTP_FORBIDDEN :
+ return ("Forbidden");
+ case HTTP_NOT_FOUND :
+ return ("Not Found");
+ case HTTP_REQUEST_TOO_LARGE :
+ return ("Request Entity Too Large");
+ case HTTP_URI_TOO_LONG :
+ return ("URI Too Long");
+ case HTTP_UPGRADE_REQUIRED :
+ return ("Upgrade Required");
+ case HTTP_NOT_IMPLEMENTED :
+ return ("Not Implemented");
+ case HTTP_NOT_SUPPORTED :
+ return ("Not Supported");
+ default :
+ return ("Unknown");
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/http.c b/cups/http.c
new file mode 100644
index 000000000..5705dabc2
--- /dev/null
+++ b/cups/http.c
@@ -0,0 +1,1954 @@
+/*
+ * "$Id$"
+ *
+ * HTTP routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * httpInitialize() - Initialize the HTTP interface library and set the
+ * default HTTP proxy (if any).
+ * httpCheck() - Check to see if there is a pending response from
+ * the server.
+ * httpClose() - Close an HTTP connection...
+ * httpConnect() - Connect to a HTTP server.
+ * httpConnectEncrypt() - Connect to a HTTP server using encryption.
+ * httpEncryption() - Set the required encryption on the link.
+ * httpReconnect() - Reconnect to a HTTP server...
+ * httpGetSubField() - Get a sub-field value.
+ * httpSetField() - Set the value of an HTTP header.
+ * httpDelete() - Send a DELETE request to the server.
+ * httpGet() - Send a GET request to the server.
+ * httpHead() - Send a HEAD request to the server.
+ * httpOptions() - Send an OPTIONS request to the server.
+ * httpPost() - Send a POST request to the server.
+ * httpPut() - Send a PUT request to the server.
+ * httpTrace() - Send an TRACE request to the server.
+ * httpFlush() - Flush data from a HTTP connection.
+ * httpRead() - Read data from a HTTP connection.
+ * httpWrite() - Write data to a HTTP connection.
+ * httpGets() - Get a line of text from a HTTP connection.
+ * httpPrintf() - Print a formatted string to a HTTP connection.
+ * httpGetDateString() - Get a formatted date/time string from a time value.
+ * httpGetDateTime() - Get a time value from a formatted date/time string.
+ * httpUpdate() - Update the current HTTP state for incoming data.
+ * httpDecode64() - Base64-decode a string.
+ * httpEncode64() - Base64-encode a string.
+ * httpGetLength() - Get the amount of data remaining from the
+ * content-length or transfer-encoding fields.
+ * http_field() - Return the field index for a field name.
+ * http_send() - Send a request with all fields and the trailing
+ * blank line.
+ * http_upgrade() - Force upgrade to TLS encryption.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include "string.h"
+#include <fcntl.h>
+#include <errno.h>
+
+#include "http.h"
+#include "debug.h"
+
+#ifndef WIN32
+# include <signal.h>
+#endif /* !WIN32 */
+
+#ifdef HAVE_LIBSSL
+# include <openssl/err.h>
+# include <openssl/rand.h>
+# include <openssl/ssl.h>
+#endif /* HAVE_LIBSSL */
+
+
+/*
+ * Some operating systems have done away with the Fxxxx constants for
+ * the fcntl() call; this works around that "feature"...
+ */
+
+#ifndef FNONBLK
+# define FNONBLK O_NONBLOCK
+#endif /* !FNONBLK */
+
+
+/*
+ * Local functions...
+ */
+
+static http_field_t http_field(const char *name);
+static int http_send(http_t *http, http_state_t request,
+ const char *uri);
+#ifdef HAVE_LIBSSL
+static int http_upgrade(http_t *http);
+#endif /* HAVE_LIBSSL */
+
+
+/*
+ * Local globals...
+ */
+
+static const char *http_fields[] =
+ {
+ "Accept-Language",
+ "Accept-Ranges",
+ "Authorization",
+ "Connection",
+ "Content-Encoding",
+ "Content-Language",
+ "Content-Length",
+ "Content-Location",
+ "Content-MD5",
+ "Content-Range",
+ "Content-Type",
+ "Content-Version",
+ "Date",
+ "Host",
+ "If-Modified-Since",
+ "If-Unmodified-since",
+ "Keep-Alive",
+ "Last-Modified",
+ "Link",
+ "Location",
+ "Range",
+ "Referer",
+ "Retry-After",
+ "Transfer-Encoding",
+ "Upgrade",
+ "User-Agent",
+ "WWW-Authenticate"
+ };
+static const char *days[7] =
+ {
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ };
+static const char *months[12] =
+ {
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ };
+
+
+/*
+ * 'httpInitialize()' - Initialize the HTTP interface library and set the
+ * default HTTP proxy (if any).
+ */
+
+void
+httpInitialize(void)
+{
+#ifdef HAVE_LIBSSL
+ struct timeval curtime; /* Current time in microseconds */
+ int i; /* Looping var */
+ unsigned char data[1024]; /* Seed data */
+#endif /* HAVE_LIBSSL */
+
+#ifdef WIN32
+ WSADATA winsockdata; /* WinSock data */
+ static int initialized = 0;/* Has WinSock been initialized? */
+
+
+ if (!initialized)
+ WSAStartup(MAKEWORD(1,1), &winsockdata);
+#elif defined(HAVE_SIGSET)
+ sigset(SIGPIPE, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ struct sigaction action; /* POSIX sigaction data */
+
+
+ /*
+ * Ignore SIGPIPE signals...
+ */
+
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &action, NULL);
+#else
+ signal(SIGPIPE, SIG_IGN);
+#endif /* WIN32 */
+
+#ifdef HAVE_LIBSSL
+ SSL_load_error_strings();
+ SSL_library_init();
+
+ /*
+ * Using the current time is a dubious random seed, but on some systems
+ * it is the best we can do (on others, this seed isn't even used...)
+ */
+
+ gettimeofday(&curtime, NULL);
+ srand(curtime.tv_sec + curtime.tv_usec);
+
+ for (i = 0; i < sizeof(data); i ++)
+ data[i] = rand(); /* Yes, this is a poor source of random data... */
+
+ RAND_seed(&data, sizeof(data));
+#endif /* HAVE_LIBSSL */
+}
+
+
+/*
+ * 'httpCheck()' - Check to see if there is a pending response from the server.
+ */
+
+int /* O - 0 = no data, 1 = data available */
+httpCheck(http_t *http) /* I - HTTP connection */
+{
+ fd_set input; /* Input set for select() */
+ struct timeval timeout; /* Timeout */
+
+
+ /*
+ * First see if there is data in the buffer...
+ */
+
+ if (http == NULL)
+ return (0);
+
+ if (http->used)
+ return (1);
+
+ /*
+ * Then try doing a select() to poll the socket...
+ */
+
+ FD_ZERO(&input);
+ FD_SET(http->fd, &input);
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ return (select(http->fd + 1, &input, NULL, NULL, &timeout) > 0);
+}
+
+
+/*
+ * 'httpClose()' - Close an HTTP connection...
+ */
+
+void
+httpClose(http_t *http) /* I - Connection to close */
+{
+#ifdef HAVE_LIBSSL
+ SSL_CTX *context; /* Context for encryption */
+ SSL *conn; /* Connection for encryption */
+#endif /* HAVE_LIBSSL */
+
+
+ if (!http)
+ return;
+
+#ifdef HAVE_LIBSSL
+ if (http->tls)
+ {
+ conn = (SSL *)(http->tls);
+ context = SSL_get_SSL_CTX(conn);
+
+ SSL_shutdown(conn);
+ SSL_CTX_free(context);
+ SSL_free(conn);
+
+ http->tls = NULL;
+ }
+#endif /* HAVE_LIBSSL */
+
+#ifdef WIN32
+ closesocket(http->fd);
+#else
+ close(http->fd);
+#endif /* WIN32 */
+
+ free(http);
+}
+
+
+/*
+ * 'httpConnect()' - Connect to a HTTP server.
+ */
+
+http_t * /* O - New HTTP connection */
+httpConnect(const char *host, /* I - Host to connect to */
+ int port) /* I - Port number */
+{
+ http_encryption_t encrypt;/* Type of encryption to use */
+
+
+ /*
+ * Set the default encryption status...
+ */
+
+ if (port == 443)
+ encrypt = HTTP_ENCRYPT_ALWAYS;
+ else
+ encrypt = HTTP_ENCRYPT_IF_REQUESTED;
+
+ return (httpConnectEncrypt(host, port, encrypt));
+}
+
+
+/*
+ * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption.
+ */
+
+http_t * /* O - New HTTP connection */
+httpConnectEncrypt(const char *host, /* I - Host to connect to */
+ int port, /* I - Port number */
+ http_encryption_t encrypt)
+ /* I - Type of encryption to use */
+{
+ int i; /* Looping var */
+ http_t *http; /* New HTTP connection */
+ struct hostent *hostaddr; /* Host address data */
+
+
+ if (host == NULL)
+ return (NULL);
+
+ httpInitialize();
+
+ /*
+ * Lookup the host...
+ */
+
+ if ((hostaddr = httpGetHostByName(host)) == NULL)
+ {
+ /*
+ * This hack to make users that don't have a localhost entry in
+ * their hosts file or DNS happy...
+ */
+
+ if (strcasecmp(host, "localhost") != 0)
+ return (NULL);
+ else if ((hostaddr = httpGetHostByName("127.0.0.1")) == NULL)
+ return (NULL);
+ }
+
+ /*
+ * Verify that it is an IPv4 address (IPv6 support will come in CUPS 1.2...)
+ */
+
+ if (hostaddr->h_addrtype != AF_INET || hostaddr->h_length != 4)
+ return (NULL);
+
+ /*
+ * Allocate memory for the structure...
+ */
+
+ http = calloc(sizeof(http_t), 1);
+ if (http == NULL)
+ return (NULL);
+
+ http->version = HTTP_1_1;
+ http->blocking = 1;
+ http->activity = time(NULL);
+ http->fd = -1;
+
+ /*
+ * Copy the hostname and port and then "reconnect"...
+ */
+
+ strlcpy(http->hostname, host, sizeof(http->hostname));
+ http->hostaddr.sin_family = hostaddr->h_addrtype;
+#ifdef WIN32
+ http->hostaddr.sin_port = htons((u_short)port);
+#else
+ http->hostaddr.sin_port = htons(port);
+#endif /* WIN32 */
+
+ /*
+ * Set the encryption status...
+ */
+
+ if (port == 443) /* Always use encryption for https */
+ http->encryption = HTTP_ENCRYPT_ALWAYS;
+ else
+ http->encryption = encrypt;
+
+ /*
+ * Loop through the addresses we have until one of them connects...
+ */
+
+ strlcpy(http->hostname, host, sizeof(http->hostname));
+
+ for (i = 0; hostaddr->h_addr_list[i]; i ++)
+ {
+ /*
+ * Load the address...
+ */
+
+ memcpy((char *)&(http->hostaddr.sin_addr), hostaddr->h_addr_list[i],
+ hostaddr->h_length);
+
+ /*
+ * Connect to the remote system...
+ */
+
+ if (!httpReconnect(http))
+ return (http);
+ }
+
+ /*
+ * Could not connect to any known address - bail out!
+ */
+
+ free(http);
+ return (NULL);
+}
+
+
+/*
+ * 'httpEncryption()' - Set the required encryption on the link.
+ */
+
+int /* O - -1 on error, 0 on success */
+httpEncryption(http_t *http, /* I - HTTP data */
+ http_encryption_t e) /* I - New encryption preference */
+{
+#ifdef HAVE_LIBSSL
+ if (!http)
+ return (0);
+
+ http->encryption = e;
+
+ if ((http->encryption == HTTP_ENCRYPT_ALWAYS && !http->tls) ||
+ (http->encryption == HTTP_ENCRYPT_NEVER && http->tls))
+ return (httpReconnect(http));
+ else if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
+ return (http_upgrade(http));
+ else
+ return (0);
+#else
+ if (e == HTTP_ENCRYPT_ALWAYS || e == HTTP_ENCRYPT_REQUIRED)
+ return (-1);
+ else
+ return (0);
+#endif /* HAVE_LIBSSL */
+}
+
+
+/*
+ * 'httpReconnect()' - Reconnect to a HTTP server...
+ */
+
+int /* O - 0 on success, non-zero on failure */
+httpReconnect(http_t *http) /* I - HTTP data */
+{
+ int val; /* Socket option value */
+#ifdef HAVE_LIBSSL
+ SSL_CTX *context; /* Context for encryption */
+ SSL *conn; /* Connection for encryption */
+
+
+ if (http->tls)
+ {
+ conn = (SSL *)(http->tls);
+ context = SSL_get_SSL_CTX(conn);
+
+ SSL_shutdown(conn);
+ SSL_CTX_free(context);
+ SSL_free(conn);
+
+ http->tls = NULL;
+ }
+#endif /* HAVE_LIBSSL */
+
+ /*
+ * Close any previously open socket...
+ */
+
+ if (http->fd >= 0)
+#ifdef WIN32
+ closesocket(http->fd);
+#else
+ close(http->fd);
+#endif /* WIN32 */
+
+ /*
+ * Create the socket and set options to allow reuse.
+ */
+
+ if ((http->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+#ifdef WIN32
+ http->error = WSAGetLastError();
+#else
+ http->error = errno;
+#endif /* WIN32 */
+ http->status = HTTP_ERROR;
+ return (-1);
+ }
+
+#ifdef FD_CLOEXEC
+ fcntl(http->fd, F_SETFD, FD_CLOEXEC); /* Close this socket when starting *
+ * other processes... */
+#endif /* FD_CLOEXEC */
+
+ val = 1;
+ setsockopt(http->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
+
+#ifdef SO_REUSEPORT
+ val = 1;
+ setsockopt(http->fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
+#endif /* SO_REUSEPORT */
+
+ /*
+ * Using TCP_NODELAY improves responsiveness, especially on systems
+ * with a slow loopback interface... Since we write large buffers
+ * when sending print files and requests, there shouldn't be any
+ * performance penalty for this...
+ */
+
+ val = 1;
+ setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
+
+ /*
+ * Connect to the server...
+ */
+
+ if (connect(http->fd, (struct sockaddr *)&(http->hostaddr),
+ sizeof(http->hostaddr)) < 0)
+ {
+#ifdef WIN32
+ http->error = WSAGetLastError();
+#else
+ http->error = errno;
+#endif /* WIN32 */
+ http->status = HTTP_ERROR;
+
+#ifdef WIN32
+ closesocket(http->fd);
+#else
+ close(http->fd);
+#endif
+
+ http->fd = -1;
+
+ return (-1);
+ }
+
+ http->error = 0;
+ http->status = HTTP_CONTINUE;
+
+#ifdef HAVE_LIBSSL
+ if (http->encryption == HTTP_ENCRYPT_ALWAYS)
+ {
+ /*
+ * Always do encryption via SSL.
+ */
+
+ context = SSL_CTX_new(SSLv23_method());
+ conn = SSL_new(context);
+
+ SSL_set_fd(conn, http->fd);
+ if (SSL_connect(conn) != 1)
+ {
+ SSL_CTX_free(context);
+ SSL_free(conn);
+
+#ifdef WIN32
+ http->error = WSAGetLastError();
+#else
+ http->error = errno;
+#endif /* WIN32 */
+ http->status = HTTP_ERROR;
+
+#ifdef WIN32
+ closesocket(http->fd);
+#else
+ close(http->fd);
+#endif
+
+ return (-1);
+ }
+
+ http->tls = conn;
+ }
+ else if (http->encryption == HTTP_ENCRYPT_REQUIRED)
+ return (http_upgrade(http));
+#endif /* HAVE_LIBSSL */
+
+ return (0);
+}
+
+
+/*
+ * 'httpGetSubField()' - Get a sub-field value.
+ */
+
+char * /* O - Value or NULL */
+httpGetSubField(http_t *http, /* I - HTTP data */
+ http_field_t field, /* I - Field index */
+ const char *name, /* I - Name of sub-field */
+ char *value) /* O - Value string */
+{
+ const char *fptr; /* Pointer into field */
+ char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */
+ *ptr; /* Pointer into string buffer */
+
+
+ if (http == NULL ||
+ field < HTTP_FIELD_ACCEPT_LANGUAGE ||
+ field > HTTP_FIELD_WWW_AUTHENTICATE ||
+ name == NULL || value == NULL)
+ return (NULL);
+
+ DEBUG_printf(("httpGetSubField(%p, %d, \"%s\", %p)\n",
+ http, field, name, value));
+
+ for (fptr = http->fields[field]; *fptr;)
+ {
+ /*
+ * Skip leading whitespace...
+ */
+
+ while (isspace(*fptr))
+ fptr ++;
+
+ if (*fptr == ',')
+ {
+ fptr ++;
+ continue;
+ }
+
+ /*
+ * Get the sub-field name...
+ */
+
+ for (ptr = temp;
+ *fptr && *fptr != '=' && !isspace(*fptr) && ptr < (temp + sizeof(temp) - 1);
+ *ptr++ = *fptr++);
+
+ *ptr = '\0';
+
+ DEBUG_printf(("name = \"%s\"\n", temp));
+
+ /*
+ * Skip trailing chars up to the '='...
+ */
+
+ while (isspace(*fptr))
+ fptr ++;
+
+ if (!*fptr)
+ break;
+
+ if (*fptr != '=')
+ continue;
+
+ /*
+ * Skip = and leading whitespace...
+ */
+
+ fptr ++;
+
+ while (isspace(*fptr))
+ fptr ++;
+
+ if (*fptr == '\"')
+ {
+ /*
+ * Read quoted string...
+ */
+
+ for (ptr = value, fptr ++;
+ *fptr && *fptr != '\"' && ptr < (value + HTTP_MAX_VALUE - 1);
+ *ptr++ = *fptr++);
+
+ *ptr = '\0';
+
+ while (*fptr && *fptr != '\"')
+ fptr ++;
+
+ if (*fptr)
+ fptr ++;
+ }
+ else
+ {
+ /*
+ * Read unquoted string...
+ */
+
+ for (ptr = value;
+ *fptr && !isspace(*fptr) && *fptr != ',' && ptr < (value + HTTP_MAX_VALUE - 1);
+ *ptr++ = *fptr++);
+
+ *ptr = '\0';
+
+ while (*fptr && !isspace(*fptr) && *fptr != ',')
+ fptr ++;
+ }
+
+ DEBUG_printf(("value = \"%s\"\n", value));
+
+ /*
+ * See if this is the one...
+ */
+
+ if (strcmp(name, temp) == 0)
+ return (value);
+ }
+
+ value[0] = '\0';
+
+ return (NULL);
+}
+
+
+/*
+ * 'httpSetField()' - Set the value of an HTTP header.
+ */
+
+void
+httpSetField(http_t *http, /* I - HTTP data */
+ http_field_t field, /* I - Field index */
+ const char *value) /* I - Value */
+{
+ if (http == NULL ||
+ field < HTTP_FIELD_ACCEPT_LANGUAGE ||
+ field > HTTP_FIELD_WWW_AUTHENTICATE ||
+ value == NULL)
+ return;
+
+ strlcpy(http->fields[field], value, HTTP_MAX_VALUE);
+}
+
+
+/*
+ * 'httpDelete()' - Send a DELETE request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpDelete(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI to delete */
+{
+ return (http_send(http, HTTP_DELETE, uri));
+}
+
+
+/*
+ * 'httpGet()' - Send a GET request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpGet(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI to get */
+{
+ return (http_send(http, HTTP_GET, uri));
+}
+
+
+/*
+ * 'httpHead()' - Send a HEAD request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpHead(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI for head */
+{
+ return (http_send(http, HTTP_HEAD, uri));
+}
+
+
+/*
+ * 'httpOptions()' - Send an OPTIONS request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpOptions(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI for options */
+{
+ return (http_send(http, HTTP_OPTIONS, uri));
+}
+
+
+/*
+ * 'httpPost()' - Send a POST request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpPost(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI for post */
+{
+ httpGetLength(http);
+
+ return (http_send(http, HTTP_POST, uri));
+}
+
+
+/*
+ * 'httpPut()' - Send a PUT request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpPut(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI to put */
+{
+ httpGetLength(http);
+
+ return (http_send(http, HTTP_PUT, uri));
+}
+
+
+/*
+ * 'httpTrace()' - Send an TRACE request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpTrace(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI for trace */
+{
+ return (http_send(http, HTTP_TRACE, uri));
+}
+
+
+/*
+ * 'httpFlush()' - Flush data from a HTTP connection.
+ */
+
+void
+httpFlush(http_t *http) /* I - HTTP data */
+{
+ char buffer[8192]; /* Junk buffer */
+
+
+ while (httpRead(http, buffer, sizeof(buffer)) > 0);
+}
+
+
+/*
+ * 'httpRead()' - Read data from a HTTP connection.
+ */
+
+int /* O - Number of bytes read */
+httpRead(http_t *http, /* I - HTTP data */
+ char *buffer, /* I - Buffer for data */
+ int length) /* I - Maximum number of bytes */
+{
+ int bytes; /* Bytes read */
+ char len[32]; /* Length string */
+
+
+ DEBUG_printf(("httpRead(%p, %p, %d)\n", http, buffer, length));
+
+ if (http == NULL || buffer == NULL)
+ return (-1);
+
+ http->activity = time(NULL);
+
+ if (length <= 0)
+ return (0);
+
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED &&
+ http->data_remaining <= 0)
+ {
+ DEBUG_puts("httpRead: Getting chunk length...");
+
+ if (httpGets(len, sizeof(len), http) == NULL)
+ {
+ DEBUG_puts("httpRead: Could not get length!");
+ return (0);
+ }
+
+ http->data_remaining = strtol(len, NULL, 16);
+ }
+
+ DEBUG_printf(("httpRead: data_remaining = %d\n", http->data_remaining));
+
+ if (http->data_remaining == 0)
+ {
+ /*
+ * A zero-length chunk ends a transfer; unless we are reading POST
+ * data, go idle...
+ */
+
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED)
+ httpGets(len, sizeof(len), http);
+
+ if (http->state == HTTP_POST_RECV)
+ http->state ++;
+ else
+ http->state = HTTP_WAITING;
+
+ return (0);
+ }
+ else if (length > http->data_remaining)
+ length = http->data_remaining;
+
+ if (http->used == 0 && length <= 256)
+ {
+ /*
+ * Buffer small reads for better performance...
+ */
+
+ if (http->data_remaining > sizeof(http->buffer))
+ bytes = sizeof(http->buffer);
+ else
+ bytes = http->data_remaining;
+
+#ifdef HAVE_LIBSSL
+ if (http->tls)
+ bytes = SSL_read((SSL *)(http->tls), http->buffer, bytes);
+ else
+#endif /* HAVE_LIBSSL */
+ {
+ DEBUG_printf(("httpRead: reading %d bytes from socket into buffer...\n",
+ bytes));
+
+ bytes = recv(http->fd, http->buffer, bytes, 0);
+
+ DEBUG_printf(("httpRead: read %d bytes from socket into buffer...\n",
+ bytes));
+ }
+
+ if (bytes > 0)
+ http->used = bytes;
+ else if (bytes < 0)
+ {
+#ifdef WIN32
+ http->error = WSAGetLastError();
+#else
+ http->error = errno;
+#endif /* WIN32 */
+ return (-1);
+ }
+ else
+ return (0);
+ }
+
+ if (http->used > 0)
+ {
+ if (length > http->used)
+ length = http->used;
+
+ bytes = length;
+
+ DEBUG_printf(("httpRead: grabbing %d bytes from input buffer...\n", bytes));
+
+ memcpy(buffer, http->buffer, length);
+ http->used -= length;
+
+ if (http->used > 0)
+ memcpy(http->buffer, http->buffer + length, http->used);
+ }
+#ifdef HAVE_LIBSSL
+ else if (http->tls)
+ bytes = SSL_read((SSL *)(http->tls), buffer, length);
+#endif /* HAVE_LIBSSL */
+ else
+ {
+ DEBUG_printf(("httpRead: reading %d bytes from socket...\n", length));
+ bytes = recv(http->fd, buffer, length, 0);
+ DEBUG_printf(("httpRead: read %d bytes from socket...\n", bytes));
+ }
+
+ if (bytes > 0)
+ http->data_remaining -= bytes;
+ else if (bytes < 0)
+#ifdef WIN32
+ http->error = WSAGetLastError();
+#else
+ http->error = errno;
+#endif /* WIN32 */
+
+ if (http->data_remaining == 0)
+ {
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED)
+ httpGets(len, sizeof(len), http);
+
+ if (http->data_encoding != HTTP_ENCODE_CHUNKED)
+ {
+ if (http->state == HTTP_POST_RECV)
+ http->state ++;
+ else
+ http->state = HTTP_WAITING;
+ }
+ }
+
+#ifdef DEBUG
+ {
+ int i, j, ch;
+ printf("httpRead: Read %d bytes:\n", bytes);
+ for (i = 0; i < bytes; i += 16)
+ {
+ printf(" ");
+
+ for (j = 0; j < 16 && (i + j) < bytes; j ++)
+ printf(" %02X", buffer[i + j] & 255);
+
+ while (j < 16)
+ {
+ printf(" ");
+ j ++;
+ }
+
+ printf(" ");
+ for (j = 0; j < 16 && (i + j) < bytes; j ++)
+ {
+ ch = buffer[i + j] & 255;
+
+ if (ch < ' ' || ch == 127)
+ ch = '.';
+
+ putchar(ch);
+ }
+ putchar('\n');
+ }
+ }
+#endif /* DEBUG */
+
+ return (bytes);
+}
+
+
+/*
+ * 'httpWrite()' - Write data to a HTTP connection.
+ */
+
+int /* O - Number of bytes written */
+httpWrite(http_t *http, /* I - HTTP data */
+ const char *buffer, /* I - Buffer for data */
+ int length) /* I - Number of bytes to write */
+{
+ int tbytes, /* Total bytes sent */
+ bytes; /* Bytes sent */
+
+
+ if (http == NULL || buffer == NULL)
+ return (-1);
+
+ http->activity = time(NULL);
+
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED)
+ {
+ if (httpPrintf(http, "%x\r\n", length) < 0)
+ return (-1);
+
+ if (length == 0)
+ {
+ /*
+ * A zero-length chunk ends a transfer; unless we are sending POST
+ * data, go idle...
+ */
+
+ DEBUG_puts("httpWrite: changing states...");
+
+ if (http->state == HTTP_POST_RECV)
+ http->state ++;
+ else if (http->state == HTTP_PUT_RECV)
+ http->state = HTTP_STATUS;
+ else
+ http->state = HTTP_WAITING;
+
+ if (httpPrintf(http, "\r\n") < 0)
+ return (-1);
+
+ return (0);
+ }
+ }
+
+ tbytes = 0;
+
+ while (length > 0)
+ {
+#ifdef HAVE_LIBSSL
+ if (http->tls)
+ bytes = SSL_write((SSL *)(http->tls), buffer, length);
+ else
+#endif /* HAVE_LIBSSL */
+ bytes = send(http->fd, buffer, length, 0);
+
+ if (bytes < 0)
+ {
+ DEBUG_puts("httpWrite: error writing data...\n");
+
+ return (-1);
+ }
+
+ buffer += bytes;
+ tbytes += bytes;
+ length -= bytes;
+ if (http->data_encoding == HTTP_ENCODE_LENGTH)
+ http->data_remaining -= bytes;
+ }
+
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED)
+ if (httpPrintf(http, "\r\n") < 0)
+ return (-1);
+
+ if (http->data_remaining == 0 && http->data_encoding == HTTP_ENCODE_LENGTH)
+ {
+ /*
+ * Finished with the transfer; unless we are sending POST data, go idle...
+ */
+
+ DEBUG_puts("httpWrite: changing states...");
+
+ if (http->state == HTTP_POST_RECV)
+ http->state ++;
+ else
+ http->state = HTTP_WAITING;
+ }
+
+#ifdef DEBUG
+ {
+ int i, j, ch;
+ printf("httpWrite: wrote %d bytes: \n", tbytes);
+ for (i = 0, buffer -= tbytes; i < tbytes; i += 16)
+ {
+ printf(" ");
+
+ for (j = 0; j < 16 && (i + j) < tbytes; j ++)
+ printf(" %02X", buffer[i + j] & 255);
+
+ while (j < 16)
+ {
+ printf(" ");
+ j ++;
+ }
+
+ printf(" ");
+ for (j = 0; j < 16 && (i + j) < tbytes; j ++)
+ {
+ ch = buffer[i + j] & 255;
+
+ if (ch < ' ' || ch == 127)
+ ch = '.';
+
+ putchar(ch);
+ }
+ putchar('\n');
+ }
+ }
+#endif /* DEBUG */
+ return (tbytes);
+}
+
+
+/*
+ * 'httpGets()' - Get a line of text from a HTTP connection.
+ */
+
+char * /* O - Line or NULL */
+httpGets(char *line, /* I - Line to read into */
+ int length, /* I - Max length of buffer */
+ http_t *http) /* I - HTTP data */
+{
+ char *lineptr, /* Pointer into line */
+ *bufptr, /* Pointer into input buffer */
+ *bufend; /* Pointer to end of buffer */
+ int bytes; /* Number of bytes read */
+
+
+ DEBUG_printf(("httpGets(%p, %d, %p)\n", line, length, http));
+
+ if (http == NULL || line == NULL)
+ return (NULL);
+
+ /*
+ * Pre-scan the buffer and see if there is a newline in there...
+ */
+
+#ifdef WIN32
+ WSASetLastError(0);
+#else
+ errno = 0;
+#endif /* WIN32 */
+
+ do
+ {
+ bufptr = http->buffer;
+ bufend = http->buffer + http->used;
+
+ while (bufptr < bufend)
+ if (*bufptr == 0x0a)
+ break;
+ else
+ bufptr ++;
+
+ if (bufptr >= bufend && http->used < HTTP_MAX_BUFFER)
+ {
+ /*
+ * No newline; see if there is more data to be read...
+ */
+
+#ifdef HAVE_LIBSSL
+ if (http->tls)
+ bytes = SSL_read((SSL *)(http->tls), bufend,
+ HTTP_MAX_BUFFER - http->used);
+ else
+#endif /* HAVE_LIBSSL */
+ bytes = recv(http->fd, bufend, HTTP_MAX_BUFFER - http->used, 0);
+
+ if (bytes < 0)
+ {
+ /*
+ * Nope, can't get a line this time...
+ */
+
+#ifdef WIN32
+ if (WSAGetLastError() != http->error)
+ {
+ http->error = WSAGetLastError();
+ continue;
+ }
+
+ DEBUG_printf(("httpGets(): recv() error %d!\n", WSAGetLastError()));
+#else
+ if (errno != http->error)
+ {
+ http->error = errno;
+ continue;
+ }
+
+ DEBUG_printf(("httpGets(): recv() error %d!\n", errno));
+#endif /* WIN32 */
+
+ return (NULL);
+ }
+ else if (bytes == 0)
+ {
+ if (http->blocking)
+ http->error = EPIPE;
+
+ return (NULL);
+ }
+
+ /*
+ * Yup, update the amount used and the end pointer...
+ */
+
+ http->used += bytes;
+ bufend += bytes;
+ }
+ }
+ while (bufptr >= bufend && http->used < HTTP_MAX_BUFFER);
+
+ http->activity = time(NULL);
+
+ /*
+ * Read a line from the buffer...
+ */
+
+ lineptr = line;
+ bufptr = http->buffer;
+ bytes = 0;
+ length --;
+
+ while (bufptr < bufend && bytes < length)
+ {
+ bytes ++;
+
+ if (*bufptr == 0x0a)
+ {
+ bufptr ++;
+ break;
+ }
+ else if (*bufptr == 0x0d)
+ bufptr ++;
+ else
+ *lineptr++ = *bufptr++;
+ }
+
+ if (bytes > 0)
+ {
+ *lineptr = '\0';
+
+ http->used -= bytes;
+ if (http->used > 0)
+ memcpy(http->buffer, bufptr, http->used);
+
+ DEBUG_printf(("httpGets(): Returning \"%s\"\n", line));
+ return (line);
+ }
+
+ DEBUG_puts("httpGets(): No new line available!");
+
+ return (NULL);
+}
+
+
+/*
+ * 'httpPrintf()' - Print a formatted string to a HTTP connection.
+ */
+
+int /* O - Number of bytes written */
+httpPrintf(http_t *http, /* I - HTTP data */
+ const char *format, /* I - printf-style format string */
+ ...) /* I - Additional args as needed */
+{
+ int bytes, /* Number of bytes to write */
+ nbytes, /* Number of bytes written */
+ tbytes; /* Number of bytes all together */
+ char buf[HTTP_MAX_BUFFER], /* Buffer for formatted string */
+ *bufptr; /* Pointer into buffer */
+ va_list ap; /* Variable argument pointer */
+
+
+ va_start(ap, format);
+ bytes = vsnprintf(buf, sizeof(buf), format, ap);
+ va_end(ap);
+
+ DEBUG_printf(("httpPrintf: %s", buf));
+
+ for (tbytes = 0, bufptr = buf; tbytes < bytes; tbytes += nbytes, bufptr += nbytes)
+ {
+#ifdef HAVE_LIBSSL
+ if (http->tls)
+ nbytes = SSL_write((SSL *)(http->tls), bufptr, bytes - tbytes);
+ else
+#endif /* HAVE_LIBSSL */
+ nbytes = send(http->fd, bufptr, bytes - tbytes, 0);
+
+ if (nbytes < 0)
+ return (-1);
+ }
+
+ return (bytes);
+}
+
+
+/*
+ * 'httpGetDateString()' - Get a formatted date/time string from a time value.
+ */
+
+const char * /* O - Date/time string */
+httpGetDateString(time_t t) /* I - UNIX time */
+{
+ struct tm *tdate;
+ static char datetime[256];
+
+
+ tdate = gmtime(&t);
+ snprintf(datetime, sizeof(datetime), "%s, %02d %s %d %02d:%02d:%02d GMT",
+ days[tdate->tm_wday], tdate->tm_mday, months[tdate->tm_mon],
+ tdate->tm_year + 1900, tdate->tm_hour, tdate->tm_min, tdate->tm_sec);
+
+ return (datetime);
+}
+
+
+/*
+ * 'httpGetDateTime()' - Get a time value from a formatted date/time string.
+ */
+
+time_t /* O - UNIX time */
+httpGetDateTime(const char *s) /* I - Date/time string */
+{
+ int i; /* Looping var */
+ struct tm tdate; /* Time/date structure */
+ char mon[16]; /* Abbreviated month name */
+ int day, year; /* Day of month and year */
+ int hour, min, sec; /* Time */
+
+
+ if (sscanf(s, "%*s%d%15s%d%d:%d:%d", &day, mon, &year, &hour, &min, &sec) < 6)
+ return (0);
+
+ for (i = 0; i < 12; i ++)
+ if (strcasecmp(mon, months[i]) == 0)
+ break;
+
+ if (i >= 12)
+ return (0);
+
+ tdate.tm_mon = i;
+ tdate.tm_mday = day;
+ tdate.tm_year = year - 1900;
+ tdate.tm_hour = hour;
+ tdate.tm_min = min;
+ tdate.tm_sec = sec;
+ tdate.tm_isdst = 0;
+
+ return (mktime(&tdate));
+}
+
+
+/*
+ * 'httpUpdate()' - Update the current HTTP state for incoming data.
+ */
+
+http_status_t /* O - HTTP status */
+httpUpdate(http_t *http) /* I - HTTP data */
+{
+ char line[1024], /* Line from connection... */
+ *value; /* Pointer to value on line */
+ http_field_t field; /* Field index */
+ int major, minor; /* HTTP version numbers */
+ http_status_t status; /* Authorization status */
+#ifdef HAVE_LIBSSL
+ SSL_CTX *context; /* Context for encryption */
+ SSL *conn; /* Connection for encryption */
+#endif /* HAVE_LIBSSL */
+
+
+ DEBUG_printf(("httpUpdate(%p)\n", http));
+
+ /*
+ * If we haven't issued any commands, then there is nothing to "update"...
+ */
+
+ if (http->state == HTTP_WAITING)
+ return (HTTP_CONTINUE);
+
+ /*
+ * Grab all of the lines we can from the connection...
+ */
+
+ while (httpGets(line, sizeof(line), http) != NULL)
+ {
+ DEBUG_puts(line);
+
+ if (line[0] == '\0')
+ {
+ /*
+ * Blank line means the start of the data section (if any). Return
+ * the result code, too...
+ *
+ * If we get status 100 (HTTP_CONTINUE), then we *don't* change states.
+ * Instead, we just return HTTP_CONTINUE to the caller and keep on
+ * tryin'...
+ */
+
+ if (http->status == HTTP_CONTINUE)
+ return (http->status);
+
+#ifdef HAVE_LIBSSL
+ if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls)
+ {
+ context = SSL_CTX_new(SSLv23_method());
+ conn = SSL_new(context);
+
+ SSL_set_fd(conn, http->fd);
+ if (SSL_connect(conn) != 1)
+ {
+ SSL_CTX_free(context);
+ SSL_free(conn);
+
+#ifdef WIN32
+ http->error = WSAGetLastError();
+#else
+ http->error = errno;
+#endif /* WIN32 */
+ http->status = HTTP_ERROR;
+
+#ifdef WIN32
+ closesocket(http->fd);
+#else
+ close(http->fd);
+#endif
+
+ return (HTTP_ERROR);
+ }
+
+ http->tls = conn;
+
+ return (HTTP_CONTINUE);
+ }
+#endif /* HAVE_LIBSSL */
+
+ httpGetLength(http);
+
+ switch (http->state)
+ {
+ case HTTP_GET :
+ case HTTP_POST :
+ case HTTP_POST_RECV :
+ case HTTP_PUT :
+ http->state ++;
+ break;
+
+ default :
+ http->state = HTTP_WAITING;
+ break;
+ }
+
+ return (http->status);
+ }
+ else if (strncmp(line, "HTTP/", 5) == 0)
+ {
+ /*
+ * Got the beginning of a response...
+ */
+
+ if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, (int *)&status) != 3)
+ return (HTTP_ERROR);
+
+ http->version = (http_version_t)(major * 100 + minor);
+ http->status = status;
+ }
+ else if ((value = strchr(line, ':')) != NULL)
+ {
+ /*
+ * Got a value...
+ */
+
+ *value++ = '\0';
+ while (isspace(*value))
+ value ++;
+
+ /*
+ * Be tolerants of servers that send unknown attribute fields...
+ */
+
+ if ((field = http_field(line)) == HTTP_FIELD_UNKNOWN)
+ {
+ DEBUG_printf(("httpUpdate: unknown field %s seen!\n", line));
+ continue;
+ }
+
+ httpSetField(http, field, value);
+ }
+ else
+ {
+ http->status = HTTP_ERROR;
+ return (HTTP_ERROR);
+ }
+ }
+
+ /*
+ * See if there was an error...
+ */
+
+ if (http->error)
+ {
+ http->status = HTTP_ERROR;
+ return (HTTP_ERROR);
+ }
+
+ /*
+ * If we haven't already returned, then there is nothing new...
+ */
+
+ return (HTTP_CONTINUE);
+}
+
+
+/*
+ * 'httpDecode64()' - Base64-decode a string.
+ */
+
+char * /* O - Decoded string */
+httpDecode64(char *out, /* I - String to write to */
+ const char *in) /* I - String to read from */
+{
+ int pos, /* Bit position */
+ base64; /* Value of this character */
+ char *outptr; /* Output pointer */
+
+
+ for (outptr = out, pos = 0; *in != '\0'; in ++)
+ {
+ /*
+ * Decode this character into a number from 0 to 63...
+ */
+
+ if (*in >= 'A' && *in <= 'Z')
+ base64 = *in - 'A';
+ else if (*in >= 'a' && *in <= 'z')
+ base64 = *in - 'a' + 26;
+ else if (*in >= '0' && *in <= '9')
+ base64 = *in - '0' + 52;
+ else if (*in == '+')
+ base64 = 62;
+ else if (*in == '/')
+ base64 = 63;
+ else if (*in == '=')
+ break;
+ else
+ continue;
+
+ /*
+ * Store the result in the appropriate chars...
+ */
+
+ switch (pos)
+ {
+ case 0 :
+ *outptr = base64 << 2;
+ pos ++;
+ break;
+ case 1 :
+ *outptr++ |= (base64 >> 4) & 3;
+ *outptr = (base64 << 4) & 255;
+ pos ++;
+ break;
+ case 2 :
+ *outptr++ |= (base64 >> 2) & 15;
+ *outptr = (base64 << 6) & 255;
+ pos ++;
+ break;
+ case 3 :
+ *outptr++ |= base64;
+ pos = 0;
+ break;
+ }
+ }
+
+ *outptr = '\0';
+
+ /*
+ * Return the decoded string...
+ */
+
+ return (out);
+}
+
+
+/*
+ * 'httpEncode64()' - Base64-encode a string.
+ */
+
+char * /* O - Encoded string */
+httpEncode64(char *out, /* I - String to write to */
+ const char *in) /* I - String to read from */
+{
+ char *outptr; /* Output pointer */
+ static char base64[] = /* Base64 characters... */
+ {
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789"
+ "+/"
+ };
+
+
+ for (outptr = out; *in != '\0'; in ++)
+ {
+ /*
+ * Encode the up to 3 characters as 4 Base64 numbers...
+ */
+
+ *outptr ++ = base64[in[0] >> 2];
+ *outptr ++ = base64[((in[0] << 4) | (in[1] >> 4)) & 63];
+
+ in ++;
+ if (*in == '\0')
+ {
+ *outptr ++ = '=';
+ break;
+ }
+
+ *outptr ++ = base64[((in[0] << 2) | (in[1] >> 6)) & 63];
+
+ in ++;
+ if (*in == '\0')
+ break;
+
+ *outptr ++ = base64[in[0] & 63];
+ }
+
+ *outptr ++ = '=';
+ *outptr = '\0';
+
+ /*
+ * Return the encoded string...
+ */
+
+ return (out);
+}
+
+
+/*
+ * 'httpGetLength()' - Get the amount of data remaining from the
+ * content-length or transfer-encoding fields.
+ */
+
+int /* O - Content length */
+httpGetLength(http_t *http) /* I - HTTP data */
+{
+ DEBUG_printf(("httpGetLength(%p)\n", http));
+
+ if (strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked") == 0)
+ {
+ DEBUG_puts("httpGetLength: chunked request!");
+
+ http->data_encoding = HTTP_ENCODE_CHUNKED;
+ http->data_remaining = 0;
+ }
+ else
+ {
+ http->data_encoding = HTTP_ENCODE_LENGTH;
+
+ /*
+ * The following is a hack for HTTP servers that don't send a
+ * content-length or transfer-encoding field...
+ *
+ * If there is no content-length then the connection must close
+ * after the transfer is complete...
+ */
+
+ if (http->fields[HTTP_FIELD_CONTENT_LENGTH][0] == '\0')
+ http->data_remaining = 2147483647;
+ else
+ http->data_remaining = atoi(http->fields[HTTP_FIELD_CONTENT_LENGTH]);
+
+ DEBUG_printf(("httpGetLength: content_length = %d\n", http->data_remaining));
+ }
+
+ return (http->data_remaining);
+}
+
+
+/*
+ * 'http_field()' - Return the field index for a field name.
+ */
+
+static http_field_t /* O - Field index */
+http_field(const char *name) /* I - String name */
+{
+ int i; /* Looping var */
+
+
+ for (i = 0; i < HTTP_FIELD_MAX; i ++)
+ if (strcasecmp(name, http_fields[i]) == 0)
+ return ((http_field_t)i);
+
+ return (HTTP_FIELD_UNKNOWN);
+}
+
+
+/*
+ * 'http_send()' - Send a request with all fields and the trailing blank line.
+ */
+
+static int /* O - 0 on success, non-zero on error */
+http_send(http_t *http, /* I - HTTP data */
+ http_state_t request, /* I - Request code */
+ const char *uri) /* I - URI */
+{
+ int i; /* Looping var */
+ char *ptr, /* Pointer in buffer */
+ buf[1024]; /* Encoded URI buffer */
+ static const char *codes[] = /* Request code strings */
+ {
+ NULL,
+ "OPTIONS",
+ "GET",
+ NULL,
+ "HEAD",
+ "POST",
+ NULL,
+ NULL,
+ "PUT",
+ NULL,
+ "DELETE",
+ "TRACE",
+ "CLOSE"
+ };
+ static const char *hex = "0123456789ABCDEF";
+ /* Hex digits */
+
+
+ if (http == NULL || uri == NULL)
+ return (-1);
+
+ /*
+ * Encode the URI as needed...
+ */
+
+ for (ptr = buf; *uri != '\0' && ptr < (buf + sizeof(buf) - 1); uri ++)
+ if (*uri <= ' ' || *uri >= 127)
+ {
+ if (ptr < (buf + sizeof(buf) - 1))
+ *ptr ++ = '%';
+ if (ptr < (buf + sizeof(buf) - 1))
+ *ptr ++ = hex[(*uri >> 4) & 15];
+ if (ptr < (buf + sizeof(buf) - 1))
+ *ptr ++ = hex[*uri & 15];
+ }
+ else
+ *ptr ++ = *uri;
+
+ *ptr = '\0';
+
+ /*
+ * See if we had an error the last time around; if so, reconnect...
+ */
+
+ if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST)
+ httpReconnect(http);
+
+ /*
+ * Send the request header...
+ */
+
+ http->state = request;
+ if (request == HTTP_POST || request == HTTP_PUT)
+ http->state ++;
+
+ http->status = HTTP_CONTINUE;
+
+#ifdef HAVE_LIBSSL
+ if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
+ {
+ httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
+ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");
+ }
+#endif /* HAVE_LIBSSL */
+
+ if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)
+ {
+ http->status = HTTP_ERROR;
+ return (-1);
+ }
+
+ for (i = 0; i < HTTP_FIELD_MAX; i ++)
+ if (http->fields[i][0] != '\0')
+ {
+ DEBUG_printf(("%s: %s\n", http_fields[i], http->fields[i]));
+
+ if (httpPrintf(http, "%s: %s\r\n", http_fields[i], http->fields[i]) < 1)
+ {
+ http->status = HTTP_ERROR;
+ return (-1);
+ }
+ }
+
+ if (httpPrintf(http, "\r\n") < 1)
+ {
+ http->status = HTTP_ERROR;
+ return (-1);
+ }
+
+ httpClearFields(http);
+
+ return (0);
+}
+
+
+#ifdef HAVE_LIBSSL
+/*
+ * 'http_upgrade()' - Force upgrade to TLS encryption.
+ */
+
+static int /* O - Status of connection */
+http_upgrade(http_t *http) /* I - HTTP data */
+{
+ int ret; /* Return value */
+ http_t myhttp; /* Local copy of HTTP data */
+
+
+ DEBUG_printf(("http_upgrade(%p)\n", http));
+
+ /*
+ * Copy the HTTP data to a local variable so we can do the OPTIONS
+ * request without interfering with the existing request data...
+ */
+
+ memcpy(&myhttp, http, sizeof(myhttp));
+
+ /*
+ * Send an OPTIONS request to the server, requiring SSL or TLS
+ * encryption on the link...
+ */
+
+ httpClearFields(&myhttp);
+ httpSetField(&myhttp, HTTP_FIELD_CONNECTION, "upgrade");
+ httpSetField(&myhttp, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0");
+
+ if ((ret = httpOptions(&myhttp, "*")) == 0)
+ {
+ /*
+ * Wait for the secure connection...
+ */
+
+ while (httpUpdate(&myhttp) == HTTP_CONTINUE);
+ }
+
+ httpFlush(&myhttp);
+
+ /*
+ * Copy the HTTP data back over, if any...
+ */
+
+ http->fd = myhttp.fd;
+ http->error = myhttp.error;
+ http->activity = myhttp.activity;
+ http->status = myhttp.status;
+ http->version = myhttp.version;
+ http->keep_alive = myhttp.keep_alive;
+ http->used = myhttp.used;
+
+ if (http->used)
+ memcpy(http->buffer, myhttp.buffer, http->used);
+
+ http->auth_type = myhttp.auth_type;
+ http->nonce_count = myhttp.nonce_count;
+
+ memcpy(http->nonce, myhttp.nonce, sizeof(http->nonce));
+
+ http->tls = myhttp.tls;
+ http->encryption = myhttp.encryption;
+
+ /*
+ * See if we actually went secure...
+ */
+
+ if (!http->tls)
+ {
+ /*
+ * Server does not support HTTP upgrade...
+ */
+
+ DEBUG_puts("Server does not support HTTP upgrade!");
+
+#ifdef WIN32
+ closesocket(http->fd);
+#else
+ close(http->fd);
+#endif
+
+ http->fd = -1;
+
+ return (-1);
+ }
+ else
+ return (ret);
+}
+#endif /* HAVE_LIBSSL */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/http.h b/cups/http.h
new file mode 100644
index 000000000..a27673668
--- /dev/null
+++ b/cups/http.h
@@ -0,0 +1,353 @@
+/*
+ * "$Id$"
+ *
+ * Hyper-Text Transport Protocol definitions for the Common UNIX Printing
+ * System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _CUPS_HTTP_H_
+# define _CUPS_HTTP_H_
+
+/*
+ * Include necessary headers...
+ */
+
+# include <string.h>
+# include <time.h>
+# ifdef WIN32
+# include <winsock.h>
+# else
+# include <unistd.h>
+# include <sys/time.h>
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netinet/in_systm.h>
+# include <netinet/ip.h>
+# if !defined(__APPLE__) || !defined(TCP_NODELAY)
+# include <netinet/tcp.h>
+# endif /* !__APPLE__ || !TCP_NODELAY */
+# endif /* WIN32 */
+
+# include "md5.h"
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+
+/*
+ * Limits...
+ */
+
+# define HTTP_MAX_URI 1024 /* Max length of URI string */
+# define HTTP_MAX_HOST 256 /* Max length of hostname string */
+# define HTTP_MAX_BUFFER 2048 /* Max length of data buffer */
+# define HTTP_MAX_VALUE 256 /* Max header field value length */
+
+
+/*
+ * HTTP state values...
+ */
+
+typedef enum /* States are server-oriented */
+{
+ HTTP_WAITING, /* Waiting for command */
+ HTTP_OPTIONS, /* OPTIONS command, waiting for blank line */
+ HTTP_GET, /* GET command, waiting for blank line */
+ HTTP_GET_SEND, /* GET command, sending data */
+ HTTP_HEAD, /* HEAD command, waiting for blank line */
+ HTTP_POST, /* POST command, waiting for blank line */
+ HTTP_POST_RECV, /* POST command, receiving data */
+ HTTP_POST_SEND, /* POST command, sending data */
+ HTTP_PUT, /* PUT command, waiting for blank line */
+ HTTP_PUT_RECV, /* PUT command, receiving data */
+ HTTP_DELETE, /* DELETE command, waiting for blank line */
+ HTTP_TRACE, /* TRACE command, waiting for blank line */
+ HTTP_CLOSE, /* CLOSE command, waiting for blank line */
+ HTTP_STATUS /* Command complete, sending status */
+} http_state_t;
+
+
+/*
+ * HTTP version numbers...
+ */
+
+typedef enum
+{
+ HTTP_0_9 = 9, /* HTTP/0.9 */
+ HTTP_1_0 = 100, /* HTTP/1.0 */
+ HTTP_1_1 = 101 /* HTTP/1.1 */
+} http_version_t;
+
+
+/*
+ * HTTP keep-alive values...
+ */
+
+typedef enum
+{
+ HTTP_KEEPALIVE_OFF = 0,
+ HTTP_KEEPALIVE_ON
+} http_keepalive_t;
+
+
+/*
+ * HTTP transfer encoding values...
+ */
+
+typedef enum
+{
+ HTTP_ENCODE_LENGTH, /* Data is sent with Content-Length */
+ HTTP_ENCODE_CHUNKED /* Data is chunked */
+} http_encoding_t;
+
+
+/*
+ * HTTP encryption values...
+ */
+
+typedef enum
+{
+ HTTP_ENCRYPT_IF_REQUESTED, /* Encrypt if requested (TLS upgrade) */
+ HTTP_ENCRYPT_NEVER, /* Never encrypt */
+ HTTP_ENCRYPT_REQUIRED, /* Encryption is required (TLS upgrade) */
+ HTTP_ENCRYPT_ALWAYS /* Always encrypt (SSL) */
+} http_encryption_t;
+
+
+/*
+ * HTTP authentication types...
+ */
+
+typedef enum
+{
+ HTTP_AUTH_NONE, /* No authentication in use */
+ HTTP_AUTH_BASIC, /* Basic authentication in use */
+ HTTP_AUTH_MD5, /* Digest authentication in use */
+ HTTP_AUTH_MD5_SESS, /* MD5-session authentication in use */
+ HTTP_AUTH_MD5_INT, /* Digest authentication in use for body */
+ HTTP_AUTH_MD5_SESS_INT /* MD5-session authentication in use for body */
+} http_auth_t;
+
+
+/*
+ * HTTP status codes...
+ */
+
+typedef enum
+{
+ HTTP_ERROR = -1, /* An error response from httpXxxx() */
+
+ HTTP_CONTINUE = 100, /* Everything OK, keep going... */
+ HTTP_SWITCHING_PROTOCOLS, /* HTTP upgrade to TLS/SSL */
+
+ HTTP_OK = 200, /* OPTIONS/GET/HEAD/POST/TRACE command was successful */
+ HTTP_CREATED, /* PUT command was successful */
+ HTTP_ACCEPTED, /* DELETE command was successful */
+ HTTP_NOT_AUTHORITATIVE, /* Information isn't authoritative */
+ HTTP_NO_CONTENT, /* Successful command, no new data */
+ HTTP_RESET_CONTENT, /* Content was reset/recreated */
+ HTTP_PARTIAL_CONTENT, /* Only a partial file was recieved/sent */
+
+ HTTP_MULTIPLE_CHOICES = 300, /* Multiple files match request */
+ HTTP_MOVED_PERMANENTLY, /* Document has moved permanently */
+ HTTP_MOVED_TEMPORARILY, /* Document has moved temporarily */
+ HTTP_SEE_OTHER, /* See this other link... */
+ HTTP_NOT_MODIFIED, /* File not modified */
+ HTTP_USE_PROXY, /* Must use a proxy to access this URI */
+
+ HTTP_BAD_REQUEST = 400, /* Bad request */
+ HTTP_UNAUTHORIZED, /* Unauthorized to access host */
+ HTTP_PAYMENT_REQUIRED, /* Payment required */
+ HTTP_FORBIDDEN, /* Forbidden to access this URI */
+ HTTP_NOT_FOUND, /* URI was not found */
+ HTTP_METHOD_NOT_ALLOWED, /* Method is not allowed */
+ HTTP_NOT_ACCEPTABLE, /* Not Acceptable */
+ HTTP_PROXY_AUTHENTICATION, /* Proxy Authentication is Required */
+ HTTP_REQUEST_TIMEOUT, /* Request timed out */
+ HTTP_CONFLICT, /* Request is self-conflicting */
+ HTTP_GONE, /* Server has gone away */
+ HTTP_LENGTH_REQUIRED, /* A content length or encoding is required */
+ HTTP_PRECONDITION, /* Precondition failed */
+ HTTP_REQUEST_TOO_LARGE, /* Request entity too large */
+ HTTP_URI_TOO_LONG, /* URI too long */
+ HTTP_UNSUPPORTED_MEDIATYPE, /* The requested media type is unsupported */
+ HTTP_UPGRADE_REQUIRED = 426, /* Upgrade to SSL/TLS required */
+
+ HTTP_SERVER_ERROR = 500, /* Internal server error */
+ HTTP_NOT_IMPLEMENTED, /* Feature not implemented */
+ HTTP_BAD_GATEWAY, /* Bad gateway */
+ HTTP_SERVICE_UNAVAILABLE, /* Service is unavailable */
+ HTTP_GATEWAY_TIMEOUT, /* Gateway connection timed out */
+ HTTP_NOT_SUPPORTED /* HTTP version not supported */
+} http_status_t;
+
+
+/*
+ * HTTP field names...
+ */
+
+typedef enum
+{
+ HTTP_FIELD_UNKNOWN = -1,
+ HTTP_FIELD_ACCEPT_LANGUAGE,
+ HTTP_FIELD_ACCEPT_RANGES,
+ HTTP_FIELD_AUTHORIZATION,
+ HTTP_FIELD_CONNECTION,
+ HTTP_FIELD_CONTENT_ENCODING,
+ HTTP_FIELD_CONTENT_LANGUAGE,
+ HTTP_FIELD_CONTENT_LENGTH,
+ HTTP_FIELD_CONTENT_LOCATION,
+ HTTP_FIELD_CONTENT_MD5,
+ HTTP_FIELD_CONTENT_RANGE,
+ HTTP_FIELD_CONTENT_TYPE,
+ HTTP_FIELD_CONTENT_VERSION,
+ HTTP_FIELD_DATE,
+ HTTP_FIELD_HOST,
+ HTTP_FIELD_IF_MODIFIED_SINCE,
+ HTTP_FIELD_IF_UNMODIFIED_SINCE,
+ HTTP_FIELD_KEEP_ALIVE,
+ HTTP_FIELD_LAST_MODIFIED,
+ HTTP_FIELD_LINK,
+ HTTP_FIELD_LOCATION,
+ HTTP_FIELD_RANGE,
+ HTTP_FIELD_REFERER,
+ HTTP_FIELD_RETRY_AFTER,
+ HTTP_FIELD_TRANSFER_ENCODING,
+ HTTP_FIELD_UPGRADE,
+ HTTP_FIELD_USER_AGENT,
+ HTTP_FIELD_WWW_AUTHENTICATE,
+ HTTP_FIELD_MAX
+} http_field_t;
+
+
+/*
+ * HTTP connection structure...
+ */
+
+typedef struct
+{
+ int fd; /* File descriptor for this socket */
+ int blocking; /* To block or not to block */
+ int error; /* Last error on read */
+ time_t activity; /* Time since last read/write */
+ http_state_t state; /* State of client */
+ http_status_t status; /* Status of last request */
+ http_version_t version; /* Protocol version */
+ http_keepalive_t keep_alive; /* Keep-alive supported? */
+ struct sockaddr_in hostaddr; /* Address of connected host */
+ char hostname[HTTP_MAX_HOST],
+ /* Name of connected host */
+ fields[HTTP_FIELD_MAX][HTTP_MAX_VALUE];
+ /* Field values */
+ char *data; /* Pointer to data buffer */
+ http_encoding_t data_encoding; /* Chunked or not */
+ int data_remaining; /* Number of bytes left */
+ int used; /* Number of bytes used in buffer */
+ char buffer[HTTP_MAX_BUFFER];
+ /* Buffer for messages */
+ int auth_type; /* Authentication in use */
+ md5_state_t md5_state; /* MD5 state */
+ char nonce[HTTP_MAX_VALUE];
+ /* Nonce value */
+ int nonce_count; /* Nonce count */
+ void *tls; /* TLS state information */
+ http_encryption_t encryption; /* Encryption requirements */
+} http_t;
+
+
+/*
+ * Prototypes...
+ */
+
+# define httpBlocking(http,b) (http)->blocking = (b)
+extern int httpCheck(http_t *http);
+# define httpClearFields(http) memset((http)->fields, 0, sizeof((http)->fields)),\
+ httpSetField((http), HTTP_FIELD_HOST, (http)->hostname)
+extern void httpClose(http_t *http);
+extern http_t *httpConnect(const char *host, int port);
+extern http_t *httpConnectEncrypt(const char *host, int port,
+ http_encryption_t encrypt);
+extern int httpDelete(http_t *http, const char *uri);
+extern int httpEncryption(http_t *http, http_encryption_t e);
+# define httpError(http) ((http)->error)
+extern void httpFlush(http_t *http);
+extern int httpGet(http_t *http, const char *uri);
+extern char *httpGets(char *line, int length, http_t *http);
+extern const char *httpGetDateString(time_t t);
+extern time_t httpGetDateTime(const char *s);
+# define httpGetField(http,field) (http)->fields[field]
+extern struct hostent *httpGetHostByName(const char *name);
+extern char *httpGetSubField(http_t *http, http_field_t field,
+ const char *name, char *value);
+extern int httpHead(http_t *http, const char *uri);
+extern void httpInitialize(void);
+extern int httpOptions(http_t *http, const char *uri);
+extern int httpPost(http_t *http, const char *uri);
+extern int httpPrintf(http_t *http, const char *format, ...)
+# ifdef __GNUC__
+__attribute__ ((__format__ (__printf__, 2, 3)))
+# endif /* __GNUC__ */
+;
+extern int httpPut(http_t *http, const char *uri);
+extern int httpRead(http_t *http, char *buffer, int length);
+extern int httpReconnect(http_t *http);
+extern void httpSeparate(const char *uri, char *method,
+ char *username, char *host, int *port,
+ char *resource);
+extern void httpSetField(http_t *http, http_field_t field,
+ const char *value);
+extern const char *httpStatus(http_status_t status);
+extern int httpTrace(http_t *http, const char *uri);
+extern http_status_t httpUpdate(http_t *http);
+extern int httpWrite(http_t *http, const char *buffer, int length);
+extern char *httpEncode64(char *out, const char *in);
+extern char *httpDecode64(char *out, const char *in);
+extern int httpGetLength(http_t *http);
+extern char *httpMD5(const char *, const char *, const char *,
+ char [33]);
+extern char *httpMD5Final(const char *, const char *, const char *,
+ char [33]);
+extern char *httpMD5String(const md5_byte_t *, char [33]);
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+#endif /* !_CUPS_HTTP_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/ipp-support.c b/cups/ipp-support.c
new file mode 100644
index 000000000..515a807ef
--- /dev/null
+++ b/cups/ipp-support.c
@@ -0,0 +1,175 @@
+/*
+ * "$Id$"
+ *
+ * Internet Printing Protocol support functions for the Common UNIX
+ * Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ippErrorString() - Return a textual message for the given error
+ * message.
+ * ippPort() - Return the default IPP port number.
+ * ippSetPort() - Set the default port number.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "string.h"
+#include "language.h"
+
+#include "ipp.h"
+#include "debug.h"
+#include <ctype.h>
+
+
+/*
+ * Local globals...
+ */
+
+static int ipp_port = 0;
+
+
+/*
+ * 'ippErrorString()' - Return a textual message for the given error message.
+ */
+
+const char * /* O - Text string */
+ippErrorString(ipp_status_t error) /* I - Error status */
+{
+ static char unknown[255]; /* Unknown error statuses */
+ static const char *status_oks[] = /* "OK" status codes */
+ {
+ "successful-ok",
+ "successful-ok-ignored-or-substituted-attributes",
+ "successful-ok-conflicting-attributes",
+ "successful-ok-ignored-subscriptions",
+ "successful-ok-ignored-notifications",
+ "successful-ok-too-many-events",
+ "successful-ok-but-cancel-subscription"
+ },
+ *status_400s[] = /* Client errors */
+ {
+ "client-error-bad-request",
+ "client-error-forbidden",
+ "client-error-not-authenticated",
+ "client-error-not-authorized",
+ "client-error-not-possible",
+ "client-error-timeout",
+ "client-error-not-found",
+ "client-error-gone",
+ "client-error-request-entity-too-large",
+ "client-error-request-value-too-long",
+ "client-error-document-format-not-supported",
+ "client-error-attributes-or-values-not-supported",
+ "client-error-uri-scheme-not-supported",
+ "client-error-charset-not-supported",
+ "client-error-conflicting-attributes",
+ "client-error-compression-not-supported",
+ "client-error-compression-error",
+ "client-error-document-format-error",
+ "client-error-document-access-error",
+ "client-error-attributes-not-settable",
+ "client-error-ignored-all-subscriptions",
+ "client-error-too-many-subscriptions",
+ "client-error-ignored-all-notifications",
+ "client-error-print-support-file-not-found"
+ },
+ *status_500s[] = /* Server errors */
+ {
+ "server-error-internal-error",
+ "server-error-operation-not-supported",
+ "server-error-service-unavailable",
+ "server-error-version-not-supported",
+ "server-error-device-error",
+ "server-error-temporary-error",
+ "server-error-not-accepting-jobs",
+ "server-error-busy",
+ "server-error-job-canceled",
+ "server-error-multiple-document-jobs-not-supported",
+ "server-error-printer-is-deactivated"
+ };
+
+
+ /*
+ * See if the error code is a known value...
+ */
+
+ if (error >= IPP_OK && error <= IPP_OK_BUT_CANCEL_SUBSCRIPTION)
+ return (status_oks[error]);
+ else if (error == IPP_REDIRECTION_OTHER_SITE)
+ return ("redirection-other-site");
+ else if (error >= IPP_BAD_REQUEST && error <= IPP_PRINT_SUPPORT_FILE_NOT_FOUND)
+ return (status_400s[error - IPP_BAD_REQUEST]);
+ else if (error >= IPP_INTERNAL_ERROR && error <= IPP_PRINTER_IS_DEACTIVATED)
+ return (status_500s[error - IPP_INTERNAL_ERROR]);
+
+ /*
+ * No, build an "unknown-xxxx" error string...
+ */
+
+ sprintf(unknown, "unknown-%04x", error);
+
+ return (unknown);
+}
+
+
+/*
+ * 'ippPort()' - Return the default IPP port number.
+ */
+
+int /* O - Port number */
+ippPort(void)
+{
+ const char *server_port; /* SERVER_PORT environment variable */
+ struct servent *port; /* Port number info */
+
+
+ if (ipp_port)
+ return (ipp_port);
+ else if ((server_port = getenv("IPP_PORT")) != NULL)
+ return (ipp_port = atoi(server_port));
+ else if ((port = getservbyname("ipp", NULL)) == NULL)
+ return (ipp_port = IPP_PORT);
+ else
+ return (ipp_port = ntohs(port->s_port));
+}
+
+
+/*
+ * 'ippSetPort()' - Set the default port number.
+ */
+
+void
+ippSetPort(int p) /* I - Port number to use */
+{
+ ipp_port = p;
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/ipp.c b/cups/ipp.c
new file mode 100644
index 000000000..024a69980
--- /dev/null
+++ b/cups/ipp.c
@@ -0,0 +1,2035 @@
+/*
+ * "$Id$"
+ *
+ * Internet Printing Protocol object functions for the Common UNIX
+ * Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ippAddBoolean() - Add a boolean attribute to an IPP request.
+ * ippAddBooleans() - Add an array of boolean values.
+ * ippAddDate() - Add a date attribute to an IPP request.
+ * ippAddInteger() - Add a integer attribute to an IPP request.
+ * ippAddIntegers() - Add an array of integer values.
+ * ippAddString() - Add a language-encoded string to an IPP request.
+ * ippAddStrings() - Add language-encoded strings to an IPP request.
+ * ippAddRange() - Add a range of values to an IPP request.
+ * ippAddRanges() - Add ranges of values to an IPP request.
+ * ippAddResolution() - Add a resolution value to an IPP request.
+ * ippAddResolutions() - Add resolution values to an IPP request.
+ * ippAddSeparator() - Add a group separator to an IPP request.
+ * ippDateToTime() - Convert from RFC 1903 Date/Time format to UNIX
+ * time in seconds.
+ * ippDelete() - Delete an IPP request.
+ * ippFindAttribute() - Find a named attribute in a request...
+ * ippFindNextAttribute() - Find the next named attribute in a request...
+ * ippLength() - Compute the length of an IPP request.
+ * ippNew() - Allocate a new IPP request.
+ * ippRead() - Read data for an IPP request.
+ * ippTimeToDate() - Convert from UNIX time to RFC 1903 format.
+ * ippWrite() - Write data for an IPP request.
+ * _ipp_add_attr() - Add a new attribute to the request.
+ * _ipp_free_attr() - Free an attribute.
+ * ipp_read() - Semi-blocking read on a HTTP connection...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "string.h"
+#include "language.h"
+
+#include "ipp.h"
+#include "debug.h"
+#include <ctype.h>
+
+
+/*
+ * Local functions...
+ */
+
+static int ipp_read(http_t *http, unsigned char *buffer, int length);
+
+
+/*
+ * 'ippAddBoolean()' - Add a boolean attribute to an IPP request.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddBoolean(ipp_t *ipp, /* I - IPP request */
+ ipp_tag_t group, /* I - IPP group */
+ const char *name, /* I - Name of attribute */
+ char value) /* I - Value of attribute */
+{
+ ipp_attribute_t *attr; /* New attribute */
+
+
+ DEBUG_printf(("ippAddBoolean(%p, %02x, \'%s\', %d)\n", ipp, group, name, value));
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
+ return (NULL);
+
+ attr->name = strdup(name);
+ attr->group_tag = group;
+ attr->value_tag = IPP_TAG_BOOLEAN;
+ attr->values[0].boolean = value;
+
+ return (attr);
+}
+
+
+/*
+ * 'ippAddBooleans()' - Add an array of boolean values.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddBooleans(ipp_t *ipp, /* I - IPP request */
+ ipp_tag_t group, /* I - IPP group */
+ const char *name, /* I - Name of attribute */
+ int num_values, /* I - Number of values */
+ const char *values) /* I - Values */
+{
+ int i; /* Looping var */
+ ipp_attribute_t *attr; /* New attribute */
+ ipp_value_t *value; /* Current value */
+
+
+ DEBUG_printf(("ippAddBooleans(%p, %02x, \'%s\', %d, %p)\n", ipp,
+ group, name, num_values, values));
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, num_values)) == NULL)
+ return (NULL);
+
+ attr->name = strdup(name);
+ attr->group_tag = group;
+ attr->value_tag = IPP_TAG_BOOLEAN;
+
+ if (values != NULL)
+ for (i = 0, value = attr->values;
+ i < num_values;
+ i ++, value ++)
+ value->boolean = values[i];
+
+ return (attr);
+}
+
+
+/*
+ * 'ippAddDate()' - Add a date attribute to an IPP request.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddDate(ipp_t *ipp, /* I - IPP request */
+ ipp_tag_t group, /* I - IPP group */
+ const char *name, /* I - Name of attribute */
+ const ipp_uchar_t *value) /* I - Value */
+{
+ ipp_attribute_t *attr; /* New attribute */
+
+
+ DEBUG_printf(("ippAddDate(%p, %02x, \'%s\', %p)\n", ipp, group, name,
+ value));
+
+ if (ipp == NULL || name == NULL || value == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
+ return (NULL);
+
+ attr->name = strdup(name);
+ attr->group_tag = group;
+ attr->value_tag = IPP_TAG_DATE;
+ memcpy(attr->values[0].date, value, 11);
+
+ return (attr);
+}
+
+
+/*
+ * 'ippAddInteger()' - Add a integer attribute to an IPP request.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddInteger(ipp_t *ipp, /* I - IPP request */
+ ipp_tag_t group, /* I - IPP group */
+ ipp_tag_t type, /* I - Type of attribute */
+ const char *name, /* I - Name of attribute */
+ int value) /* I - Value of attribute */
+{
+ ipp_attribute_t *attr; /* New attribute */
+
+
+ DEBUG_printf(("ippAddInteger(%p, %d, \'%s\', %d)\n", ipp, group, name,
+ value));
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
+ return (NULL);
+
+ attr->name = strdup(name);
+ attr->group_tag = group;
+ attr->value_tag = type;
+ attr->values[0].integer = value;
+
+ return (attr);
+}
+
+
+/*
+ * 'ippAddIntegers()' - Add an array of integer values.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddIntegers(ipp_t *ipp, /* I - IPP request */
+ ipp_tag_t group, /* I - IPP group */
+ ipp_tag_t type, /* I - Type of attribute */
+ const char *name, /* I - Name of attribute */
+ int num_values, /* I - Number of values */
+ const int *values) /* I - Values */
+{
+ int i; /* Looping var */
+ ipp_attribute_t *attr; /* New attribute */
+ ipp_value_t *value; /* Current value */
+
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, num_values)) == NULL)
+ return (NULL);
+
+ attr->name = strdup(name);
+ attr->group_tag = group;
+ attr->value_tag = type;
+
+ if (values != NULL)
+ for (i = 0, value = attr->values;
+ i < num_values;
+ i ++, value ++)
+ value->integer = values[i];
+
+ return (attr);
+}
+
+
+/*
+ * 'ippAddString()' - Add a language-encoded string to an IPP request.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddString(ipp_t *ipp, /* I - IPP request */
+ ipp_tag_t group, /* I - IPP group */
+ ipp_tag_t type, /* I - Type of attribute */
+ const char *name, /* I - Name of attribute */
+ const char *charset, /* I - Character set */
+ const char *value) /* I - Value */
+{
+ ipp_attribute_t *attr; /* New attribute */
+
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
+ return (NULL);
+
+ /*
+ * Force value to be English for the POSIX locale...
+ */
+
+ if (type == IPP_TAG_LANGUAGE && strcasecmp(value, "C") == 0)
+ value = "en";
+
+ /*
+ * Initialize the attribute data...
+ */
+
+ attr->name = strdup(name);
+ attr->group_tag = group;
+ attr->value_tag = type;
+ attr->values[0].string.charset = ((int)type & IPP_TAG_COPY) ? (char *)charset :
+ charset ? strdup(charset) : NULL;
+ attr->values[0].string.text = ((int)type & IPP_TAG_COPY) ? (char *)value :
+ value ? strdup(value) : NULL;
+
+ /*
+ * Convert language values to lowercase and change _ to - as needed...
+ */
+
+ if ((type == IPP_TAG_LANGUAGE || type == IPP_TAG_CHARSET) &&
+ attr->values[0].string.text)
+ {
+ char *p;
+
+
+ for (p = attr->values[0].string.text; *p; p ++)
+ if (*p == '_')
+ *p = '-';
+ else
+ *p = tolower(*p);
+ }
+
+ return (attr);
+}
+
+
+/*
+ * 'ippAddStrings()' - Add language-encoded strings to an IPP request.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddStrings(ipp_t *ipp, /* I - IPP request */
+ ipp_tag_t group, /* I - IPP group */
+ ipp_tag_t type, /* I - Type of attribute */
+ const char *name, /* I - Name of attribute */
+ int num_values, /* I - Number of values */
+ const char *charset, /* I - Character set */
+ const char **values) /* I - Values */
+{
+ int i; /* Looping var */
+ ipp_attribute_t *attr; /* New attribute */
+ ipp_value_t *value; /* Current value */
+
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, num_values)) == NULL)
+ return (NULL);
+
+ /*
+ * Initialize the attribute data...
+ */
+
+ attr->name = strdup(name);
+ attr->group_tag = group;
+ attr->value_tag = type;
+
+ for (i = 0, value = attr->values;
+ i < num_values;
+ i ++, value ++)
+ {
+ if (i == 0)
+ value->string.charset = ((int)type & IPP_TAG_COPY) ? (char *)charset :
+ charset ? strdup(charset) : NULL;
+ else
+ value->string.charset = attr->values[0].string.charset;
+
+ if (values != NULL)
+ {
+ /*
+ * Force language to be English for the POSIX locale...
+ */
+
+ if (type == IPP_TAG_LANGUAGE && strcasecmp(values[i], "C") == 0)
+ value->string.text = ((int)type & IPP_TAG_COPY) ? "en" :
+ strdup("en");
+ else
+ value->string.text = ((int)type & IPP_TAG_COPY) ? (char *)values[i] :
+ strdup(values[i]);
+ }
+ }
+
+ return (attr);
+}
+
+
+/*
+ * 'ippAddRange()' - Add a range of values to an IPP request.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddRange(ipp_t *ipp, /* I - IPP request */
+ ipp_tag_t group, /* I - IPP group */
+ const char *name, /* I - Name of attribute */
+ int lower, /* I - Lower value */
+ int upper) /* I - Upper value */
+{
+ ipp_attribute_t *attr; /* New attribute */
+
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
+ return (NULL);
+
+ attr->name = strdup(name);
+ attr->group_tag = group;
+ attr->value_tag = IPP_TAG_RANGE;
+ attr->values[0].range.lower = lower;
+ attr->values[0].range.upper = upper;
+
+ return (attr);
+}
+
+
+/*
+ * 'ippAddRanges()' - Add ranges of values to an IPP request.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddRanges(ipp_t *ipp, /* I - IPP request */
+ ipp_tag_t group, /* I - IPP group */
+ const char *name, /* I - Name of attribute */
+ int num_values, /* I - Number of values */
+ const int *lower, /* I - Lower values */
+ const int *upper) /* I - Upper values */
+{
+ int i; /* Looping var */
+ ipp_attribute_t *attr; /* New attribute */
+ ipp_value_t *value; /* Current value */
+
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, num_values)) == NULL)
+ return (NULL);
+
+ attr->name = strdup(name);
+ attr->group_tag = group;
+ attr->value_tag = IPP_TAG_RANGE;
+
+ if (lower != NULL && upper != NULL)
+ for (i = 0, value = attr->values;
+ i < num_values;
+ i ++, value ++)
+ {
+ value->range.lower = lower[i];
+ value->range.upper = upper[i];
+ }
+
+ return (attr);
+}
+
+
+/*
+ * 'ippAddResolution()' - Add a resolution value to an IPP request.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddResolution(ipp_t *ipp, /* I - IPP request */
+ ipp_tag_t group, /* I - IPP group */
+ const char *name, /* I - Name of attribute */
+ ipp_res_t units, /* I - Units for resolution */
+ int xres, /* I - X resolution */
+ int yres) /* I - Y resolution */
+{
+ ipp_attribute_t *attr; /* New attribute */
+
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, 1)) == NULL)
+ return (NULL);
+
+ attr->name = strdup(name);
+ attr->group_tag = group;
+ attr->value_tag = IPP_TAG_RESOLUTION;
+ attr->values[0].resolution.xres = xres;
+ attr->values[0].resolution.yres = yres;
+ attr->values[0].resolution.units = units;
+
+ return (attr);
+}
+
+
+/*
+ * 'ippAddResolutions()' - Add resolution values to an IPP request.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddResolutions(ipp_t *ipp, /* I - IPP request */
+ ipp_tag_t group, /* I - IPP group */
+ const char *name, /* I - Name of attribute */
+ int num_values,/* I - Number of values */
+ ipp_res_t units, /* I - Units for resolution */
+ const int *xres, /* I - X resolutions */
+ const int *yres) /* I - Y resolutions */
+{
+ int i; /* Looping var */
+ ipp_attribute_t *attr; /* New attribute */
+ ipp_value_t *value; /* Current value */
+
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, num_values)) == NULL)
+ return (NULL);
+
+ attr->name = strdup(name);
+ attr->group_tag = group;
+ attr->value_tag = IPP_TAG_RESOLUTION;
+
+ if (xres != NULL && yres != NULL)
+ for (i = 0, value = attr->values;
+ i < num_values;
+ i ++, value ++)
+ {
+ value->resolution.xres = xres[i];
+ value->resolution.yres = yres[i];
+ value->resolution.units = units;
+ }
+
+ return (attr);
+}
+
+
+/*
+ * 'ippAddSeparator()' - Add a group separator to an IPP request.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+ippAddSeparator(ipp_t *ipp) /* I - IPP request */
+{
+ ipp_attribute_t *attr; /* New attribute */
+
+
+ DEBUG_printf(("ippAddSeparator(%p)\n", ipp));
+
+ if (ipp == NULL)
+ return (NULL);
+
+ if ((attr = _ipp_add_attr(ipp, 0)) == NULL)
+ return (NULL);
+
+ attr->group_tag = IPP_TAG_ZERO;
+ attr->value_tag = IPP_TAG_ZERO;
+
+ return (attr);
+}
+
+
+/*
+ * 'ippDateToTime()' - Convert from RFC 1903 Date/Time format to UNIX time
+ * in seconds.
+ */
+
+time_t /* O - UNIX time value */
+ippDateToTime(const ipp_uchar_t *date) /* I - RFC 1903 date info */
+{
+ struct tm unixdate; /* UNIX date/time info */
+ time_t t; /* Computed time */
+
+
+ memset(&unixdate, 0, sizeof(unixdate));
+
+ /*
+ * RFC-1903 date/time format is:
+ *
+ * Byte(s) Description
+ * ------- -----------
+ * 0-1 Year (0 to 65535)
+ * 2 Month (1 to 12)
+ * 3 Day (1 to 31)
+ * 4 Hours (0 to 23)
+ * 5 Minutes (0 to 59)
+ * 6 Seconds (0 to 60, 60 = "leap second")
+ * 7 Deciseconds (0 to 9)
+ * 8 +/- UTC
+ * 9 UTC hours (0 to 11)
+ * 10 UTC minutes (0 to 59)
+ */
+
+ unixdate.tm_year = ((date[0] << 8) | date[1]) - 1900;
+ unixdate.tm_mon = date[2] - 1;
+ unixdate.tm_mday = date[3];
+ unixdate.tm_hour = date[4];
+ unixdate.tm_min = date[5];
+ unixdate.tm_sec = date[6];
+
+ t = mktime(&unixdate);
+
+ if (date[8] == '-')
+ t += date[9] * 3600 + date[10] * 60;
+ else
+ t -= date[9] * 3600 + date[10] * 60;
+
+ return (t);
+}
+
+
+/*
+ * 'ippDelete()' - Delete an IPP request.
+ */
+
+void
+ippDelete(ipp_t *ipp) /* I - IPP request */
+{
+ ipp_attribute_t *attr, /* Current attribute */
+ *next; /* Next attribute */
+
+
+ DEBUG_printf(("ippDelete(): %p\n", ipp));
+
+ if (ipp == NULL)
+ return;
+
+ for (attr = ipp->attrs; attr != NULL; attr = next)
+ {
+ next = attr->next;
+ _ipp_free_attr(attr);
+ }
+
+ free(ipp);
+}
+
+
+/*
+ * 'ippFindAttribute()' - Find a named attribute in a request...
+ */
+
+ipp_attribute_t * /* O - Matching attribute */
+ippFindAttribute(ipp_t *ipp, /* I - IPP request */
+ const char *name, /* I - Name of attribute */
+ ipp_tag_t type) /* I - Type of attribute */
+{
+ DEBUG_printf(("ippFindAttribute(%p, \'%s\')\n", ipp, name));
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ /*
+ * Reset the current pointer...
+ */
+
+ ipp->current = NULL;
+
+ /*
+ * Search for the attribute...
+ */
+
+ return (ippFindNextAttribute(ipp, name, type));
+}
+
+
+/*
+ * 'ippFindNextAttribute()' - Find the next named attribute in a request...
+ */
+
+ipp_attribute_t * /* O - Matching attribute */
+ippFindNextAttribute(ipp_t *ipp, /* I - IPP request */
+ const char *name, /* I - Name of attribute */
+ ipp_tag_t type) /* I - Type of attribute */
+{
+ ipp_attribute_t *attr; /* Current atttribute */
+ ipp_tag_t value_tag; /* Value tag */
+
+
+ DEBUG_printf(("ippFindNextAttribute(%p, \'%s\')\n", ipp, name));
+
+ if (ipp == NULL || name == NULL)
+ return (NULL);
+
+ if (ipp->current)
+ attr = ipp->current->next;
+ else
+ attr = ipp->attrs;
+
+ for (; attr != NULL; attr = attr->next)
+ {
+ DEBUG_printf(("ippFindAttribute: attr = %p, name = \'%s\'\n", attr,
+ attr->name));
+
+ value_tag = (ipp_tag_t)(attr->value_tag & IPP_TAG_MASK);
+
+ if (attr->name != NULL && strcasecmp(attr->name, name) == 0 &&
+ (value_tag == type || type == IPP_TAG_ZERO ||
+ (value_tag == IPP_TAG_TEXTLANG && type == IPP_TAG_TEXT) ||
+ (value_tag == IPP_TAG_NAMELANG && type == IPP_TAG_NAME)))
+ {
+ ipp->current = attr;
+
+ return (attr);
+ }
+ }
+
+ ipp->current = NULL;
+
+ return (NULL);
+}
+
+
+/*
+ * 'ippLength()' - Compute the length of an IPP request.
+ */
+
+size_t /* O - Size of IPP request */
+ippLength(ipp_t *ipp) /* I - IPP request */
+{
+ int i; /* Looping var */
+ int bytes; /* Number of bytes */
+ ipp_attribute_t *attr; /* Current attribute */
+ ipp_tag_t group; /* Current group */
+ ipp_value_t *value; /* Current value */
+
+
+ if (ipp == NULL)
+ return (0);
+
+ /*
+ * Start with 8 bytes for the IPP request or status header...
+ */
+
+ bytes = 8;
+
+ /*
+ * Then add the lengths of each attribute...
+ */
+
+ group = IPP_TAG_ZERO;
+
+ for (attr = ipp->attrs; attr != NULL; attr = attr->next)
+ {
+ if (attr->group_tag != group)
+ {
+ group = attr->group_tag;
+ if (group == IPP_TAG_ZERO)
+ continue;
+
+ bytes ++; /* Group tag */
+ }
+
+ DEBUG_printf(("attr->name = %s, attr->num_values = %d, bytes = %d\n",
+ attr->name, attr->num_values, bytes));
+
+ bytes += strlen(attr->name); /* Name */
+ bytes += attr->num_values; /* Value tag for each value */
+ bytes += 2 * attr->num_values; /* Name lengths */
+ bytes += 2 * attr->num_values; /* Value lengths */
+
+ switch (attr->value_tag & ~IPP_TAG_COPY)
+ {
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ bytes += 4 * attr->num_values;
+ break;
+
+ case IPP_TAG_BOOLEAN :
+ bytes += attr->num_values;
+ break;
+
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_STRING :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ bytes += strlen(value->string.text);
+ break;
+
+ case IPP_TAG_DATE :
+ bytes += 11 * attr->num_values;
+ break;
+
+ case IPP_TAG_RESOLUTION :
+ bytes += 9 * attr->num_values;
+ break;
+
+ case IPP_TAG_RANGE :
+ bytes += 8 * attr->num_values;
+ break;
+
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ bytes += 4 * attr->num_values;/* Charset + text length */
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ bytes += strlen(value->string.charset) +
+ strlen(value->string.text);
+ break;
+
+ default :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ bytes += attr->values[0].unknown.length;
+ break;
+ }
+ }
+
+ /*
+ * Finally, add 1 byte for the "end of attributes" tag and return...
+ */
+
+ DEBUG_printf(("bytes = %d\n", bytes + 1));
+
+ return (bytes + 1);
+}
+
+
+/*
+ * 'ippNew()' - Allocate a new IPP request.
+ */
+
+ipp_t * /* O - New IPP request */
+ippNew(void)
+{
+ ipp_t *temp; /* New IPP request */
+
+
+ if ((temp = (ipp_t *)calloc(1, sizeof(ipp_t))) != NULL)
+ {
+ /*
+ * Default to IPP 1.1...
+ */
+
+ temp->request.any.version[0] = 1;
+ temp->request.any.version[1] = 1;
+ }
+
+ DEBUG_printf(("ippNew(): %p\n", temp));
+
+ return (temp);
+}
+
+
+/*
+ * 'ippRead()' - Read data for an IPP request.
+ */
+
+ipp_state_t /* O - Current state */
+ippRead(http_t *http, /* I - HTTP data */
+ ipp_t *ipp) /* I - IPP data */
+{
+ int n; /* Length of data */
+ unsigned char buffer[32768], /* Data buffer */
+ *bufptr; /* Pointer into buffer */
+ ipp_attribute_t *attr; /* Current attribute */
+ ipp_tag_t tag; /* Current tag */
+ ipp_value_t *value; /* Current value */
+
+
+ DEBUG_printf(("ippRead(%p, %p)\n", http, ipp));
+
+ if (http == NULL || ipp == NULL)
+ return (IPP_ERROR);
+
+ switch (ipp->state)
+ {
+ case IPP_IDLE :
+ ipp->state ++; /* Avoid common problem... */
+
+ case IPP_HEADER :
+ /*
+ * Get the request header...
+ */
+
+ if ((n = ipp_read(http, buffer, 8)) < 8)
+ {
+ DEBUG_printf(("ippRead: Unable to read header (%d bytes read)!\n", n));
+ return (n == 0 ? IPP_IDLE : IPP_ERROR);
+ }
+
+ /*
+ * Verify the major version number...
+ */
+
+ if (buffer[0] != 1)
+ {
+ DEBUG_printf(("ippRead: version number (%d.%d) is bad.\n", buffer[0],
+ buffer[1]));
+ return (IPP_ERROR);
+ }
+
+ /*
+ * Then copy the request header over...
+ */
+
+ ipp->request.any.version[0] = buffer[0];
+ ipp->request.any.version[1] = buffer[1];
+ ipp->request.any.op_status = (buffer[2] << 8) | buffer[3];
+ ipp->request.any.request_id = (((((buffer[4] << 8) | buffer[5]) << 8) |
+ buffer[6]) << 8) | buffer[7];
+
+ ipp->state = IPP_ATTRIBUTE;
+ ipp->current = NULL;
+ ipp->curtag = IPP_TAG_ZERO;
+
+ DEBUG_printf(("ippRead: version=%d.%d\n", buffer[0], buffer[1]));
+ DEBUG_printf(("ippRead: op_status=%04x\n", ipp->request.any.op_status));
+ DEBUG_printf(("ippRead: request_id=%d\n", ipp->request.any.request_id));
+
+ /*
+ * If blocking is disabled, stop here...
+ */
+
+ if (!http->blocking && http->used == 0)
+ break;
+
+ case IPP_ATTRIBUTE :
+ while (ipp_read(http, buffer, 1) > 0)
+ {
+ /*
+ * Read this attribute...
+ */
+
+ tag = (ipp_tag_t)buffer[0];
+
+ if (tag == IPP_TAG_END)
+ {
+ /*
+ * No more attributes left...
+ */
+
+ DEBUG_puts("ippRead: IPP_TAG_END!");
+
+ ipp->state = IPP_DATA;
+ break;
+ }
+ else if (tag < IPP_TAG_UNSUPPORTED_VALUE)
+ {
+ /*
+ * Group tag... Set the current group and continue...
+ */
+
+ if (ipp->curtag == tag)
+ ippAddSeparator(ipp);
+
+ ipp->curtag = tag;
+ ipp->current = NULL;
+ DEBUG_printf(("ippRead: group tag = %x\n", tag));
+ continue;
+ }
+
+ DEBUG_printf(("ippRead: value tag = %x\n", tag));
+
+ /*
+ * Get the name...
+ */
+
+ if (ipp_read(http, buffer, 2) < 2)
+ {
+ DEBUG_puts("ippRead: unable to read name length!");
+ return (IPP_ERROR);
+ }
+
+ n = (buffer[0] << 8) | buffer[1];
+
+ if (n > (sizeof(buffer) - 1))
+ {
+ DEBUG_printf(("ippRead: bad name length %d!\n", n));
+ return (IPP_ERROR);
+ }
+
+ DEBUG_printf(("ippRead: name length = %d\n", n));
+
+ if (n == 0)
+ {
+ /*
+ * More values for current attribute...
+ */
+
+ if (ipp->current == NULL)
+ return (IPP_ERROR);
+
+ attr = ipp->current;
+
+ /*
+ * Make sure we aren't adding a new value of a different
+ * type...
+ */
+
+ if (attr->value_tag == IPP_TAG_STRING ||
+ (attr->value_tag >= IPP_TAG_TEXTLANG &&
+ attr->value_tag <= IPP_TAG_MIMETYPE))
+ {
+ /*
+ * String values can sometimes come across in different
+ * forms; accept sets of differing values...
+ */
+
+ if (tag != IPP_TAG_STRING &&
+ (tag < IPP_TAG_TEXTLANG || tag > IPP_TAG_MIMETYPE))
+ return (IPP_ERROR);
+ }
+ else if (attr->value_tag != tag)
+ return (IPP_ERROR);
+
+ /*
+ * Finally, reallocate the attribute array as needed...
+ */
+
+ if ((attr->num_values % IPP_MAX_VALUES) == 0)
+ {
+ ipp_attribute_t *temp, /* Pointer to new buffer */
+ *ptr; /* Pointer in attribute list */
+
+
+ /*
+ * Reallocate memory...
+ */
+
+ if ((temp = realloc(attr, sizeof(ipp_attribute_t) +
+ (attr->num_values + IPP_MAX_VALUES - 1) *
+ sizeof(ipp_value_t))) == NULL)
+ return (IPP_ERROR);
+
+ /*
+ * Reset pointers in the list...
+ */
+
+ for (ptr = ipp->attrs; ptr && ptr->next != attr; ptr = ptr->next);
+
+ if (ptr)
+ ptr->next = temp;
+ else
+ ipp->attrs = temp;
+
+ attr = ipp->current = ipp->last = temp;
+ }
+ }
+ else
+ {
+ /*
+ * New attribute; read the name and add it...
+ */
+
+ if (ipp_read(http, buffer, n) < n)
+ {
+ DEBUG_puts("ippRead: unable to read name!");
+ return (IPP_ERROR);
+ }
+
+ buffer[n] = '\0';
+ DEBUG_printf(("ippRead: name = \'%s\'\n", buffer));
+
+ attr = ipp->current = _ipp_add_attr(ipp, IPP_MAX_VALUES);
+
+ attr->group_tag = ipp->curtag;
+ attr->value_tag = tag;
+ attr->name = strdup((char *)buffer);
+ attr->num_values = 0;
+ }
+
+ value = attr->values + attr->num_values;
+
+ if (ipp_read(http, buffer, 2) < 2)
+ {
+ DEBUG_puts("ippRead: unable to read value length!");
+ return (IPP_ERROR);
+ }
+
+ n = (buffer[0] << 8) | buffer[1];
+ DEBUG_printf(("ippRead: value length = %d\n", n));
+
+ switch (tag)
+ {
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ if (ipp_read(http, buffer, 4) < 4)
+ return (IPP_ERROR);
+
+ n = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) |
+ buffer[3];
+
+ value->integer = n;
+ break;
+ case IPP_TAG_BOOLEAN :
+ if (ipp_read(http, buffer, 1) < 1)
+ return (IPP_ERROR);
+
+ value->boolean = buffer[0];
+ break;
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_STRING :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ value->string.text = calloc(n + 1, 1);
+
+ if (ipp_read(http, value->string.text, n) < n)
+ return (IPP_ERROR);
+
+ DEBUG_printf(("ippRead: value = \'%s\'\n",
+ value->string.text));
+ break;
+ case IPP_TAG_DATE :
+ if (ipp_read(http, value->date, 11) < 11)
+ return (IPP_ERROR);
+ break;
+ case IPP_TAG_RESOLUTION :
+ if (ipp_read(http, buffer, 9) < 9)
+ return (IPP_ERROR);
+
+ value->resolution.xres =
+ (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) |
+ buffer[3];
+ value->resolution.yres =
+ (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) |
+ buffer[7];
+ value->resolution.units =
+ (ipp_res_t)buffer[8];
+ break;
+ case IPP_TAG_RANGE :
+ if (ipp_read(http, buffer, 8) < 8)
+ return (IPP_ERROR);
+
+ value->range.lower =
+ (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) |
+ buffer[3];
+ value->range.upper =
+ (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) |
+ buffer[7];
+ break;
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ if (n > sizeof(buffer) || n < 4)
+ {
+ DEBUG_printf(("ippRead: bad value length %d!\n", n));
+ return (IPP_ERROR);
+ }
+
+ if (ipp_read(http, buffer, n) < n)
+ return (IPP_ERROR);
+
+ bufptr = buffer;
+
+ /*
+ * text-with-language and name-with-language are composite
+ * values:
+ *
+ * charset-length
+ * charset
+ * text-length
+ * text
+ */
+
+ n = (bufptr[0] << 8) | bufptr[1];
+
+ value->string.charset = calloc(n + 1, 1);
+
+ memcpy(value->string.charset,
+ bufptr + 2, n);
+
+ bufptr += 2 + n;
+ n = (bufptr[0] << 8) | bufptr[1];
+
+ value->string.text = calloc(n + 1, 1);
+
+ memcpy(value->string.text,
+ bufptr + 2, n);
+ break;
+
+ default : /* Other unsupported values */
+ value->unknown.length = n;
+ if (n > 0)
+ {
+ value->unknown.data = malloc(n);
+ if (ipp_read(http, value->unknown.data, n) < n)
+ return (IPP_ERROR);
+ }
+ else
+ value->unknown.data = NULL;
+ break;
+ }
+
+ attr->num_values ++;
+
+ /*
+ * If blocking is disabled, stop here...
+ */
+
+ if (!http->blocking && http->used == 0)
+ break;
+ }
+ break;
+
+ case IPP_DATA :
+ break;
+
+ default :
+ break; /* anti-compiler-warning-code */
+ }
+
+ return (ipp->state);
+}
+
+
+/*
+ * 'ippTimeToDate()' - Convert from UNIX time to RFC 1903 format.
+ */
+
+const ipp_uchar_t * /* O - RFC-1903 date/time data */
+ippTimeToDate(time_t t) /* I - UNIX time value */
+{
+ struct tm *unixdate; /* UNIX unixdate/time info */
+ static ipp_uchar_t date[11]; /* RFC-1903 date/time data */
+
+
+ /*
+ * RFC-1903 date/time format is:
+ *
+ * Byte(s) Description
+ * ------- -----------
+ * 0-1 Year (0 to 65535)
+ * 2 Month (1 to 12)
+ * 3 Day (1 to 31)
+ * 4 Hours (0 to 23)
+ * 5 Minutes (0 to 59)
+ * 6 Seconds (0 to 60, 60 = "leap second")
+ * 7 Deciseconds (0 to 9)
+ * 8 +/- UTC
+ * 9 UTC hours (0 to 11)
+ * 10 UTC minutes (0 to 59)
+ */
+
+ unixdate = gmtime(&t);
+ unixdate->tm_year += 1900;
+
+ date[0] = unixdate->tm_year >> 8;
+ date[1] = unixdate->tm_year;
+ date[2] = unixdate->tm_mon + 1;
+ date[3] = unixdate->tm_mday;
+ date[4] = unixdate->tm_hour;
+ date[5] = unixdate->tm_min;
+ date[6] = unixdate->tm_sec;
+ date[7] = 0;
+ date[8] = '+';
+ date[9] = 0;
+ date[10] = 0;
+
+ return (date);
+}
+
+
+/*
+ * 'ippWrite()' - Write data for an IPP request.
+ */
+
+ipp_state_t /* O - Current state */
+ippWrite(http_t *http, /* I - HTTP data */
+ ipp_t *ipp) /* I - IPP data */
+{
+ int i; /* Looping var */
+ int n; /* Length of data */
+ unsigned char buffer[32768], /* Data buffer */
+ *bufptr; /* Pointer into buffer */
+ ipp_attribute_t *attr; /* Current attribute */
+ ipp_value_t *value; /* Current value */
+
+
+ if (http == NULL || ipp == NULL)
+ return (IPP_ERROR);
+
+ switch (ipp->state)
+ {
+ case IPP_IDLE :
+ ipp->state ++; /* Avoid common problem... */
+
+ case IPP_HEADER :
+ /*
+ * Send the request header:
+ *
+ * Version = 2 bytes
+ * Operation/Status Code = 2 bytes
+ * Request ID = 4 bytes
+ * Total = 8 bytes
+ */
+
+ bufptr = buffer;
+
+ *bufptr++ = ipp->request.any.version[0];
+ *bufptr++ = ipp->request.any.version[1];
+ *bufptr++ = ipp->request.any.op_status >> 8;
+ *bufptr++ = ipp->request.any.op_status;
+ *bufptr++ = ipp->request.any.request_id >> 24;
+ *bufptr++ = ipp->request.any.request_id >> 16;
+ *bufptr++ = ipp->request.any.request_id >> 8;
+ *bufptr++ = ipp->request.any.request_id;
+
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP header...");
+ return (IPP_ERROR);
+ }
+
+ /*
+ * Reset the state engine to point to the first attribute
+ * in the request/response, with no current group.
+ */
+
+ ipp->state = IPP_ATTRIBUTE;
+ ipp->current = ipp->attrs;
+ ipp->curtag = IPP_TAG_ZERO;
+
+ DEBUG_printf(("ippWrite: version=%d.%d\n", buffer[0], buffer[1]));
+ DEBUG_printf(("ippWrite: op_status=%04x\n", ipp->request.any.op_status));
+ DEBUG_printf(("ippWrite: request_id=%d\n", ipp->request.any.request_id));
+
+ /*
+ * If blocking is disabled, stop here...
+ */
+
+ if (!http->blocking)
+ break;
+
+ case IPP_ATTRIBUTE :
+ while (ipp->current != NULL)
+ {
+ /*
+ * Write this attribute...
+ */
+
+ bufptr = buffer;
+ attr = ipp->current;
+
+ ipp->current = ipp->current->next;
+
+ if (ipp->curtag != attr->group_tag)
+ {
+ /*
+ * Send a group tag byte...
+ */
+
+ ipp->curtag = attr->group_tag;
+
+ if (attr->group_tag == IPP_TAG_ZERO)
+ continue;
+
+ DEBUG_printf(("ippWrite: wrote group tag = %x\n", attr->group_tag));
+ *bufptr++ = attr->group_tag;
+ }
+
+ /*
+ * Get the length of the attribute name, and make sure it won't
+ * overflow the buffer...
+ */
+
+ if ((n = strlen(attr->name)) > (sizeof(buffer) - 4))
+ return (IPP_ERROR);
+
+ DEBUG_printf(("ippWrite: writing value tag = %x\n", attr->value_tag));
+ DEBUG_printf(("ippWrite: writing name = %d, \'%s\'\n", n, attr->name));
+
+ /*
+ * Write the attribute tag and name. The current implementation
+ * does not support the extension value tags above 0x7f, so all
+ * value tags are 1 byte.
+ *
+ * The attribute name length does not include the trailing nul
+ * character in the source string.
+ */
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+ memcpy(bufptr, attr->name, n);
+ bufptr += n;
+
+ /*
+ * Now write the attribute value(s)...
+ */
+
+ switch (attr->value_tag & ~IPP_TAG_COPY)
+ {
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ {
+ if ((sizeof(buffer) - (bufptr - buffer)) < 9)
+ {
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ /*
+ * Integers and enumerations are both 4-byte signed
+ * (twos-complement) values.
+ *
+ * Put the 2-byte length and 4-byte value into the buffer...
+ */
+
+ *bufptr++ = 0;
+ *bufptr++ = 4;
+ *bufptr++ = value->integer >> 24;
+ *bufptr++ = value->integer >> 16;
+ *bufptr++ = value->integer >> 8;
+ *bufptr++ = value->integer;
+ }
+ break;
+
+ case IPP_TAG_BOOLEAN :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ {
+ if ((sizeof(buffer) - (bufptr - buffer)) < 6)
+ {
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ /*
+ * Boolean values are 1-byte; 0 = false, 1 = true.
+ *
+ * Put the 2-byte length and 1-byte value into the buffer...
+ */
+
+ *bufptr++ = 0;
+ *bufptr++ = 1;
+ *bufptr++ = value->boolean;
+ }
+ break;
+
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_STRING :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ {
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ DEBUG_printf(("ippWrite: writing value tag = %x\n",
+ attr->value_tag));
+ DEBUG_printf(("ippWrite: writing name = 0, \'\'\n"));
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < 3)
+ {
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ /*
+ * All simple strings consist of the 2-byte length and
+ * character data without the trailing nul normally found
+ * in C strings. Also, strings cannot be longer than 32767
+ * bytes since the 2-byte length is a signed (twos-complement)
+ * value.
+ */
+
+ n = strlen(value->string.text);
+
+ if (n > (sizeof(buffer) - 2))
+ return (IPP_ERROR);
+
+ DEBUG_printf(("ippWrite: writing string = %d, \'%s\'\n", n,
+ value->string.text));
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2))
+ {
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ /*
+ * Put the 2-byte length and string characters in the
+ * buffer.
+ */
+
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+ memcpy(bufptr, value->string.text, n);
+ bufptr += n;
+ }
+ break;
+
+ case IPP_TAG_DATE :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ {
+ if ((sizeof(buffer) - (bufptr - buffer)) < 16)
+ {
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ /*
+ * Date values consist of a 2-byte length and an
+ * 11-byte date/time structure defined by RFC 1903.
+ *
+ * Put the 2-byte length and 11-byte date/time
+ * structure in the buffer.
+ */
+
+ *bufptr++ = 0;
+ *bufptr++ = 11;
+ memcpy(bufptr, value->date, 11);
+ bufptr += 11;
+ }
+ break;
+
+ case IPP_TAG_RESOLUTION :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ {
+ if ((sizeof(buffer) - (bufptr - buffer)) < 14)
+ {
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ /*
+ * Resolution values consist of a 2-byte length,
+ * 4-byte horizontal resolution value, 4-byte vertical
+ * resolution value, and a 1-byte units value.
+ *
+ * Put the 2-byte length and resolution value data
+ * into the buffer.
+ */
+
+ *bufptr++ = 0;
+ *bufptr++ = 9;
+ *bufptr++ = value->resolution.xres >> 24;
+ *bufptr++ = value->resolution.xres >> 16;
+ *bufptr++ = value->resolution.xres >> 8;
+ *bufptr++ = value->resolution.xres;
+ *bufptr++ = value->resolution.yres >> 24;
+ *bufptr++ = value->resolution.yres >> 16;
+ *bufptr++ = value->resolution.yres >> 8;
+ *bufptr++ = value->resolution.yres;
+ *bufptr++ = value->resolution.units;
+ }
+ break;
+
+ case IPP_TAG_RANGE :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ {
+ if ((sizeof(buffer) - (bufptr - buffer)) < 13)
+ {
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ /*
+ * Range values consist of a 2-byte length,
+ * 4-byte lower value, and 4-byte upper value.
+ *
+ * Put the 2-byte length and range value data
+ * into the buffer.
+ */
+
+ *bufptr++ = 0;
+ *bufptr++ = 8;
+ *bufptr++ = value->range.lower >> 24;
+ *bufptr++ = value->range.lower >> 16;
+ *bufptr++ = value->range.lower >> 8;
+ *bufptr++ = value->range.lower;
+ *bufptr++ = value->range.upper >> 24;
+ *bufptr++ = value->range.upper >> 16;
+ *bufptr++ = value->range.upper >> 8;
+ *bufptr++ = value->range.upper;
+ }
+ break;
+
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ {
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < 3)
+ {
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ /*
+ * textWithLanguage and nameWithLanguage values consist
+ * of a 2-byte length for both strings and their
+ * individual lengths, a 2-byte length for the
+ * character string, the character string without the
+ * trailing nul, a 2-byte length for the character
+ * set string, and the character set string without
+ * the trailing nul.
+ */
+
+ n = strlen(value->string.charset) +
+ strlen(value->string.text) +
+ 4;
+
+ if (n > (sizeof(buffer) - 2))
+ return (IPP_ERROR);
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2))
+ {
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ /* Length of entire value */
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+
+ /* Length of charset */
+ n = strlen(value->string.charset);
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+
+ /* Charset */
+ memcpy(bufptr, value->string.charset, n);
+ bufptr += n;
+
+ /* Length of text */
+ n = strlen(value->string.text);
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+
+ /* Text */
+ memcpy(bufptr, value->string.text, n);
+ bufptr += n;
+ }
+ break;
+
+ default :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ {
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < 3)
+ {
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ /*
+ * An unknown value might just be a collection value,
+ * or some new value that a vendor has come up with.
+ * It consists of a 2-byte length and the bytes in
+ * the unknown value buffer.
+ */
+
+ n = value->unknown.length;
+
+ if (n > (sizeof(buffer) - 2))
+ return (IPP_ERROR);
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2))
+ {
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ /* Length of unknown value */
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+
+ /* Value */
+ if (n > 0)
+ {
+ memcpy(bufptr, value->unknown.data, n);
+ bufptr += n;
+ }
+ }
+ break;
+ }
+
+ /*
+ * Write the data out...
+ */
+
+ if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ DEBUG_printf(("ippWrite: wrote %d bytes\n", bufptr - buffer));
+
+ /*
+ * If blocking is disabled, stop here...
+ */
+
+ if (!http->blocking)
+ break;
+ }
+
+ if (ipp->current == NULL)
+ {
+ /*
+ * Done with all of the attributes; add the end-of-attributes tag...
+ */
+
+ buffer[0] = IPP_TAG_END;
+ if (httpWrite(http, (char *)buffer, 1) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP end-tag...");
+ return (IPP_ERROR);
+ }
+
+ ipp->state = IPP_DATA;
+ }
+ break;
+
+ case IPP_DATA :
+ break;
+
+ default :
+ break; /* anti-compiler-warning-code */
+ }
+
+ return (ipp->state);
+}
+
+
+/*
+ * '_ipp_add_attr()' - Add a new attribute to the request.
+ */
+
+ipp_attribute_t * /* O - New attribute */
+_ipp_add_attr(ipp_t *ipp, /* I - IPP request */
+ int num_values) /* I - Number of values */
+{
+ ipp_attribute_t *attr; /* New attribute */
+
+
+ DEBUG_printf(("_ipp_add_attr(%p, %d)\n", ipp, num_values));
+
+ if (ipp == NULL || num_values < 0)
+ return (NULL);
+
+ attr = calloc(sizeof(ipp_attribute_t) +
+ (num_values - 1) * sizeof(ipp_value_t), 1);
+
+ attr->num_values = num_values;
+
+ if (attr == NULL)
+ return (NULL);
+
+ if (ipp->last == NULL)
+ ipp->attrs = attr;
+ else
+ ipp->last->next = attr;
+
+ ipp->last = attr;
+
+ DEBUG_printf(("_ipp_add_attr(): %p\n", attr));
+
+ return (attr);
+}
+
+
+/*
+ * '_ipp_free_attr()' - Free an attribute.
+ */
+
+void
+_ipp_free_attr(ipp_attribute_t *attr) /* I - Attribute to free */
+{
+ int i; /* Looping var */
+ ipp_value_t *value; /* Current value */
+
+
+ DEBUG_printf(("_ipp_free_attr(): %p\n", attr));
+
+ switch (attr->value_tag)
+ {
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_STRING :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ free(value->string.text);
+ break;
+
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ for (i = 0, value = attr->values;
+ i < attr->num_values;
+ i ++, value ++)
+ {
+ if (value->string.charset && i == 0)
+ free(value->string.charset);
+ free(value->string.text);
+ }
+ break;
+
+ default :
+ break; /* anti-compiler-warning-code */
+ }
+
+ if (attr->name != NULL)
+ free(attr->name);
+
+ free(attr);
+}
+
+
+/*
+ * 'ipp_read()' - Semi-blocking read on a HTTP connection...
+ */
+
+static int /* O - Number of bytes read */
+ipp_read(http_t *http, /* I - Client connection */
+ unsigned char *buffer, /* O - Buffer for data */
+ int length) /* I - Total length */
+{
+ int tbytes, /* Total bytes read */
+ bytes; /* Bytes read this pass */
+ char len[32]; /* Length string */
+
+
+ /*
+ * Loop until all bytes are read...
+ */
+
+ for (tbytes = 0, bytes = 0; tbytes < length; tbytes += bytes, buffer += bytes)
+ {
+ if (http->used > 0)
+ {
+ /*
+ * Do "fast read" from HTTP buffer directly...
+ */
+
+ if (http->used > (length - tbytes))
+ bytes = length - tbytes;
+ else
+ bytes = http->used;
+
+ if (bytes == 1)
+ buffer[0] = http->buffer[0];
+ else
+ memcpy(buffer, http->buffer, bytes);
+
+ http->used -= bytes;
+ http->data_remaining -= bytes;
+
+ if (http->used > 0)
+ memcpy(http->buffer, http->buffer + bytes, http->used);
+
+ if (http->data_remaining == 0)
+ {
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED)
+ httpGets(len, sizeof(len), http);
+
+ if (http->data_encoding != HTTP_ENCODE_CHUNKED)
+ {
+ if (http->state == HTTP_POST_RECV)
+ http->state ++;
+ else
+ http->state = HTTP_WAITING;
+ }
+ }
+ }
+ else if ((bytes = httpRead(http, (char *)buffer, length - tbytes)) <= 0)
+ break;
+ }
+
+ /*
+ * Return the number of bytes read...
+ */
+
+ if (tbytes == 0 && bytes < 0)
+ return (-1);
+ else
+ return (tbytes);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/ipp.h b/cups/ipp.h
new file mode 100644
index 000000000..cbf1c2ee9
--- /dev/null
+++ b/cups/ipp.h
@@ -0,0 +1,434 @@
+/*
+ * "$Id$"
+ *
+ * Internet Printing Protocol definitions for the Common UNIX Printing
+ * System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _CUPS_IPP_H_
+# define _CUPS_IPP_H_
+
+/*
+ * Include necessary headers...
+ */
+
+# include "http.h"
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+
+/*
+ * IPP version string...
+ */
+
+# define IPP_VERSION "\001\001"
+
+/*
+ * IPP registered port number... This is the default value - applications
+ * should use the ippPort() function so that you can customize things in
+ * /etc/services if needed!
+ */
+
+# define IPP_PORT 631
+
+/*
+ * Common limits...
+ */
+
+# define IPP_MAX_NAME 256
+# define IPP_MAX_VALUES 10 /* Now just an allocation increment */
+
+
+/*
+ * Types and structures...
+ */
+
+typedef enum /**** Format tags for attribute formats... ****/
+{
+ IPP_TAG_ZERO = 0x00,
+ IPP_TAG_OPERATION,
+ IPP_TAG_JOB,
+ IPP_TAG_END,
+ IPP_TAG_PRINTER,
+ IPP_TAG_UNSUPPORTED_GROUP,
+ IPP_TAG_SUBSCRIPTION,
+ IPP_TAG_EVENT_NOTIFICATION,
+ IPP_TAG_UNSUPPORTED_VALUE = 0x10,
+ IPP_TAG_DEFAULT,
+ IPP_TAG_UNKNOWN,
+ IPP_TAG_NOVALUE,
+ IPP_TAG_NOTSETTABLE = 0x15,
+ IPP_TAG_DELETEATTR,
+ IPP_TAG_ADMINDEFINE,
+ IPP_TAG_INTEGER = 0x21,
+ IPP_TAG_BOOLEAN,
+ IPP_TAG_ENUM,
+ IPP_TAG_STRING = 0x30,
+ IPP_TAG_DATE,
+ IPP_TAG_RESOLUTION,
+ IPP_TAG_RANGE,
+ IPP_TAG_BEGIN_COLLECTION,
+ IPP_TAG_TEXTLANG,
+ IPP_TAG_NAMELANG,
+ IPP_TAG_END_COLLECTION,
+ IPP_TAG_TEXT = 0x41,
+ IPP_TAG_NAME,
+ IPP_TAG_KEYWORD = 0x44,
+ IPP_TAG_URI,
+ IPP_TAG_URISCHEME,
+ IPP_TAG_CHARSET,
+ IPP_TAG_LANGUAGE,
+ IPP_TAG_MIMETYPE,
+ IPP_TAG_MEMBERNAME,
+ IPP_TAG_MASK = 0x7fffffff, /* Mask for copied attribute values */
+ IPP_TAG_COPY = -0x7fffffff-1 /* Bitflag for copied attribute values */
+} ipp_tag_t;
+
+typedef enum /**** Resolution units... ****/
+{
+ IPP_RES_PER_INCH = 3,
+ IPP_RES_PER_CM
+} ipp_res_t;
+
+typedef enum /**** Finishings... ****/
+{
+ IPP_FINISHINGS_NONE = 3,
+ IPP_FINISHINGS_STAPLE,
+ IPP_FINISHINGS_PUNCH,
+ IPP_FINISHINGS_COVER,
+ IPP_FINISHINGS_BIND,
+ IPP_FINISHINGS_SADDLE_STITCH,
+ IPP_FINISHINGS_EDGE_STITCH,
+ IPP_FINISHINGS_FOLD,
+ IPP_FINISHINGS_TRIM,
+ IPP_FINISHINGS_BALE,
+ IPP_FINISHINGS_BOOKLET_MAKER,
+ IPP_FINISHINGS_JOB_OFFSET,
+ IPP_FINISHINGS_STAPLE_TOP_LEFT = 20,
+ IPP_FINISHINGS_STAPLE_BOTTOM_LEFT,
+ IPP_FINISHINGS_STAPLE_TOP_RIGHT,
+ IPP_FINISHINGS_STAPLE_BOTTOM_RIGHT,
+ IPP_FINISHINGS_EDGE_STITCH_LEFT,
+ IPP_FINISHINGS_EDGE_STITCH_TOP,
+ IPP_FINISHINGS_EDGE_STITCH_RIGHT,
+ IPP_FINISHINGS_EDGE_STITCH_BOTTOM,
+ IPP_FINISHINGS_STAPLE_DUAL_LEFT,
+ IPP_FINISHINGS_STAPLE_DUAL_TOP,
+ IPP_FINISHINGS_STAPLE_DUAL_RIGHT,
+ IPP_FINISHINGS_STAPLE_DUAL_BOTTOM,
+ IPP_FINISHINGS_BIND_LEFT = 50,
+ IPP_FINISHINGS_BIND_TOP,
+ IPP_FINISHINGS_BIND_RIGHT,
+ IPP_FINISHINGS_BIND_BOTTOM
+} ipp_finish_t;
+
+typedef enum /**** Orientation... ****/
+{
+ IPP_PORTRAIT = 3, /* No rotation */
+ IPP_LANDSCAPE, /* 90 degrees counter-clockwise */
+ IPP_REVERSE_LANDSCAPE, /* 90 degrees clockwise */
+ IPP_REVERSE_PORTRAIT /* 180 degrees */
+} ipp_orient_t;
+
+typedef enum /**** Qualities... ****/
+{
+ IPP_QUALITY_DRAFT = 3,
+ IPP_QUALITY_NORMAL,
+ IPP_QUALITY_HIGH
+} ipp_quality_t;
+
+typedef enum /**** Job States.... */
+{
+ IPP_JOB_PENDING = 3,
+ IPP_JOB_HELD,
+ IPP_JOB_PROCESSING,
+ IPP_JOB_STOPPED,
+ IPP_JOB_CANCELLED,
+ IPP_JOB_ABORTED,
+ IPP_JOB_COMPLETED
+} ipp_jstate_t;
+
+typedef enum /**** Printer States.... */
+{
+ IPP_PRINTER_IDLE = 3,
+ IPP_PRINTER_PROCESSING,
+ IPP_PRINTER_STOPPED
+} ipp_pstate_t;
+
+typedef enum /**** IPP states... ****/
+{
+ IPP_ERROR = -1, /* An error occurred */
+ IPP_IDLE, /* Nothing is happening/request completed */
+ IPP_HEADER, /* The request header needs to be sent/received */
+ IPP_ATTRIBUTE, /* One or more attributes need to be sent/received */
+ IPP_DATA /* IPP request data needs to be sent/received */
+} ipp_state_t;
+
+typedef enum /**** IPP operations... ****/
+{
+ IPP_PRINT_JOB = 0x0002,
+ IPP_PRINT_URI,
+ IPP_VALIDATE_JOB,
+ IPP_CREATE_JOB,
+ IPP_SEND_DOCUMENT,
+ IPP_SEND_URI,
+ IPP_CANCEL_JOB,
+ IPP_GET_JOB_ATTRIBUTES,
+ IPP_GET_JOBS,
+ IPP_GET_PRINTER_ATTRIBUTES,
+ IPP_HOLD_JOB,
+ IPP_RELEASE_JOB,
+ IPP_RESTART_JOB,
+ IPP_PAUSE_PRINTER = 0x0010,
+ IPP_RESUME_PRINTER,
+ IPP_PURGE_JOBS,
+ IPP_SET_PRINTER_ATTRIBUTES,
+ IPP_SET_JOB_ATTRIBUTES,
+ IPP_GET_PRINTER_SUPPORTED_VALUES,
+ IPP_CREATE_PRINTER_SUBSCRIPTION,
+ IPP_CREATE_JOB_SUBSCRIPTION,
+ IPP_GET_SUBSCRIPTION_ATTRIBUTES,
+ IPP_GET_SUBSCRIPTIONS,
+ IPP_RENEW_SUBSCRIPTION,
+ IPP_CANCEL_SUBSCRIPTION,
+ IPP_GET_NOTIFICATIONS,
+ IPP_SEND_NOTIFICATIONS,
+ IPP_GET_PRINT_SUPPORT_FILES = 0x0021,
+ IPP_ENABLE_PRINTER,
+ IPP_DISABLE_PRINTER,
+ IPP_PAUSE_PRINTER_AFTER_CURRENT_JOB,
+ IPP_HOLD_NEW_JOBS,
+ IPP_RELEASE_HELD_NEW_JOBS,
+ IPP_DEACTIVATE_PRINTER,
+ IPP_ACTIVATE_PRINTER,
+ IPP_RESTART_PRINTER,
+ IPP_SHUTDOWN_PRINTER,
+ IPP_STARTUP_PRINTER,
+ IPP_REPROCESS_JOB,
+ IPP_CANCEL_CURRENT_JOB,
+ IPP_SUSPEND_CURRENT_JOB,
+ IPP_RESUME_JOB,
+ IPP_PROMOTE_JOB,
+ IPP_SCHEDULE_JOB_AFTER,
+ IPP_PRIVATE = 0x4000,
+ CUPS_GET_DEFAULT,
+ CUPS_GET_PRINTERS,
+ CUPS_ADD_PRINTER,
+ CUPS_DELETE_PRINTER,
+ CUPS_GET_CLASSES,
+ CUPS_ADD_CLASS,
+ CUPS_DELETE_CLASS,
+ CUPS_ACCEPT_JOBS,
+ CUPS_REJECT_JOBS,
+ CUPS_SET_DEFAULT,
+ CUPS_GET_DEVICES,
+ CUPS_GET_PPDS,
+ CUPS_MOVE_JOB,
+ CUPS_ADD_DEVICE,
+ CUPS_DELETE_DEVICE
+} ipp_op_t;
+
+typedef enum /**** IPP status codes... ****/
+{
+ IPP_OK = 0x0000,
+ IPP_OK_SUBST,
+ IPP_OK_CONFLICT,
+ IPP_OK_IGNORED_SUBSCRIPTIONS,
+ IPP_OK_IGNORED_NOTIFICATIONS,
+ IPP_OK_TOO_MANY_EVENTS,
+ IPP_OK_BUT_CANCEL_SUBSCRIPTION,
+ IPP_REDIRECTION_OTHER_SITE = 0x300,
+ IPP_BAD_REQUEST = 0x0400,
+ IPP_FORBIDDEN,
+ IPP_NOT_AUTHENTICATED,
+ IPP_NOT_AUTHORIZED,
+ IPP_NOT_POSSIBLE,
+ IPP_TIMEOUT,
+ IPP_NOT_FOUND,
+ IPP_GONE,
+ IPP_REQUEST_ENTITY,
+ IPP_REQUEST_VALUE,
+ IPP_DOCUMENT_FORMAT,
+ IPP_ATTRIBUTES,
+ IPP_URI_SCHEME,
+ IPP_CHARSET,
+ IPP_CONFLICT,
+ IPP_COMPRESSION_NOT_SUPPORTED,
+ IPP_COMPRESSION_ERROR,
+ IPP_DOCUMENT_FORMAT_ERROR,
+ IPP_DOCUMENT_ACCESS_ERROR,
+ IPP_ATTRIBUTES_NOT_SETTABLE,
+ IPP_IGNORED_ALL_SUBSCRIPTIONS,
+ IPP_TOO_MANY_SUBSCRIPTIONS,
+ IPP_IGNORED_ALL_NOTIFICATIONS,
+ IPP_PRINT_SUPPORT_FILE_NOT_FOUND,
+
+ IPP_INTERNAL_ERROR = 0x0500,
+ IPP_OPERATION_NOT_SUPPORTED,
+ IPP_SERVICE_UNAVAILABLE,
+ IPP_VERSION_NOT_SUPPORTED,
+ IPP_DEVICE_ERROR,
+ IPP_TEMPORARY_ERROR,
+ IPP_NOT_ACCEPTING,
+ IPP_PRINTER_BUSY,
+ IPP_ERROR_JOB_CANCELLED,
+ IPP_MULTIPLE_JOBS_NOT_SUPPORTED,
+ IPP_PRINTER_IS_DEACTIVATED
+} ipp_status_t;
+
+typedef unsigned char ipp_uchar_t;/**** Unsigned 8-bit integer/character ****/
+
+typedef union /**** Request Header ****/
+{
+ struct /* Any Header */
+ {
+ ipp_uchar_t version[2]; /* Protocol version number */
+ int op_status; /* Operation ID or status code*/
+ int request_id; /* Request ID */
+ } any;
+
+ struct /* Operation Header */
+ {
+ ipp_uchar_t version[2]; /* Protocol version number */
+ ipp_op_t operation_id; /* Operation ID */
+ int request_id; /* Request ID */
+ } op;
+
+ struct /* Status Header */
+ {
+ ipp_uchar_t version[2]; /* Protocol version number */
+ ipp_status_t status_code; /* Status code */
+ int request_id; /* Request ID */
+ } status;
+} ipp_request_t;
+
+
+typedef union /**** Attribute Value ****/
+{
+ int integer; /* Integer/enumerated value */
+
+ char boolean; /* Boolean value */
+
+ ipp_uchar_t date[11]; /* Date/time value */
+
+ struct
+ {
+ int xres, /* Horizontal resolution */
+ yres; /* Vertical resolution */
+ ipp_res_t units; /* Resolution units */
+ } resolution; /* Resolution value */
+
+ struct
+ {
+ int lower, /* Lower value */
+ upper; /* Upper value */
+ } range; /* Range of integers value */
+
+ struct
+ {
+ char *charset; /* Character set */
+ char *text; /* String */
+ } string; /* String with language value */
+
+ struct
+ {
+ int length; /* Length of attribute */
+ void *data; /* Data in attribute */
+ } unknown; /* Unknown attribute type */
+} ipp_value_t;
+
+typedef struct ipp_attribute_s /**** Attribute ****/
+{
+ struct ipp_attribute_s *next; /* Next attribute in list */
+ ipp_tag_t group_tag, /* Job/Printer/Operation group tag */
+ value_tag; /* What type of value is it? */
+ char *name; /* Name of attribute */
+ int num_values; /* Number of values */
+ ipp_value_t values[1]; /* Values */
+} ipp_attribute_t;
+
+typedef struct /**** Request State ****/
+{
+ ipp_state_t state; /* State of request */
+ ipp_request_t request; /* Request header */
+ ipp_attribute_t *attrs, /* Attributes */
+ *last, /* Last attribute in list */
+ *current; /* Current attribute (for read/write) */
+ ipp_tag_t curtag; /* Current attribute group tag */
+} ipp_t;
+
+
+/*
+ * Prototypes...
+ */
+
+extern ipp_attribute_t *ippAddBoolean(ipp_t *ipp, ipp_tag_t group, const char *name, char value);
+extern ipp_attribute_t *ippAddBooleans(ipp_t *ipp, ipp_tag_t group, const char *name, int num_values, const char *values);
+extern ipp_attribute_t *ippAddDate(ipp_t *ipp, ipp_tag_t group, const char *name, const ipp_uchar_t *value);
+extern ipp_attribute_t *ippAddInteger(ipp_t *ipp, ipp_tag_t group, ipp_tag_t type, const char *name, int value);
+extern ipp_attribute_t *ippAddIntegers(ipp_t *ipp, ipp_tag_t group, ipp_tag_t type, const char *name, int num_values, const int *values);
+extern ipp_attribute_t *ippAddRange(ipp_t *ipp, ipp_tag_t group, const char *name, int lower, int upper);
+extern ipp_attribute_t *ippAddRanges(ipp_t *ipp, ipp_tag_t group, const char *name, int num_values, const int *lower, const int *upper);
+extern ipp_attribute_t *ippAddResolution(ipp_t *ipp, ipp_tag_t group, const char *name, ipp_res_t units, int xres, int yres);
+extern ipp_attribute_t *ippAddResolutions(ipp_t *ipp, ipp_tag_t group, const char *name, int num_values, ipp_res_t units, const int *xres, const int *yres);
+extern ipp_attribute_t *ippAddSeparator(ipp_t *ipp);
+extern ipp_attribute_t *ippAddString(ipp_t *ipp, ipp_tag_t group, ipp_tag_t type, const char *name, const char *charset, const char *value);
+extern ipp_attribute_t *ippAddStrings(ipp_t *ipp, ipp_tag_t group, ipp_tag_t type, const char *name, int num_values, const char *charset, const char **values);
+extern time_t ippDateToTime(const ipp_uchar_t *date);
+extern void ippDelete(ipp_t *ipp);
+extern const char *ippErrorString(ipp_status_t error);
+extern ipp_attribute_t *ippFindAttribute(ipp_t *ipp, const char *name,
+ ipp_tag_t type);
+extern ipp_attribute_t *ippFindNextAttribute(ipp_t *ipp, const char *name,
+ ipp_tag_t type);
+extern size_t ippLength(ipp_t *ipp);
+extern ipp_t *ippNew(void);
+extern ipp_state_t ippRead(http_t *http, ipp_t *ipp);
+extern const ipp_uchar_t *ippTimeToDate(time_t t);
+extern ipp_state_t ippWrite(http_t *http, ipp_t *ipp);
+extern int ippPort(void);
+extern void ippSetPort(int p);
+
+extern ipp_attribute_t *_ipp_add_attr(ipp_t *, int);
+extern void _ipp_free_attr(ipp_attribute_t *);
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+#endif /* !_CUPS_IPP_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/language.c b/cups/language.c
new file mode 100644
index 000000000..fc5431656
--- /dev/null
+++ b/cups/language.c
@@ -0,0 +1,427 @@
+/*
+ * "$Id$"
+ *
+ * I18N/language support for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * cupsLangEncoding() - Return the character encoding (us-ascii, etc.)
+ * for the given language.
+ * cupsLangFlush() - Flush all language data out of the cache.
+ * cupsLangFree() - Free language data.
+ * cupsLangGet() - Get a language.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "string.h"
+#include "language.h"
+
+
+/*
+ * Local globals...
+ */
+
+static cups_lang_t *lang_cache = NULL; /* Language string cache */
+static char *lang_blank = ""; /* Blank constant string */
+static char *lang_encodings[] = /* Encoding strings */
+ {
+ "us-ascii",
+ "iso-8859-1",
+ "iso-8859-2",
+ "iso-8859-3",
+ "iso-8859-4",
+ "iso-8859-5",
+ "iso-8859-6",
+ "iso-8859-7",
+ "iso-8859-8",
+ "iso-8859-9",
+ "iso-8859-10",
+ "utf-8",
+ "iso-8859-13",
+ "iso-8859-14",
+ "iso-8859-15",
+ "windows-874",
+ "windows-1250",
+ "windows-1251",
+ "windows-1252",
+ "windows-1253",
+ "windows-1254",
+ "windows-1255",
+ "windows-1256",
+ "windows-1257",
+ "windows-1258",
+ "koi8-r",
+ "koi8-u"
+ };
+static char *lang_default[] = /* Default POSIX locale */
+ {
+#include "cups_C.h"
+ NULL
+ };
+
+
+/*
+ * 'cupsLangEncoding()' - Return the character encoding (us-ascii, etc.)
+ * for the given language.
+ */
+
+char * /* O - Character encoding */
+cupsLangEncoding(cups_lang_t *lang) /* I - Language data */
+{
+ if (lang == NULL)
+ return (lang_encodings[0]);
+ else
+ return (lang_encodings[lang->encoding]);
+}
+
+
+/*
+ * 'cupsLangFlush()' - Flush all language data out of the cache.
+ */
+
+void
+cupsLangFlush(void)
+{
+ int i; /* Looping var */
+ cups_lang_t *lang, /* Current language */
+ *next; /* Next language */
+
+
+ for (lang = lang_cache; lang != NULL; lang = next)
+ {
+ for (i = 0; i < CUPS_MSG_MAX; i ++)
+ if (lang->messages[i] != NULL && lang->messages[i] != lang_blank)
+ free(lang->messages[i]);
+
+ next = lang->next;
+ free(lang);
+ }
+}
+
+
+/*
+ * 'cupsLangFree()' - Free language data.
+ *
+ * This does not actually free anything; use cupsLangFlush() for that.
+ */
+
+void
+cupsLangFree(cups_lang_t *lang) /* I - Language to free */
+{
+ if (lang != NULL && lang->used > 0)
+ lang->used --;
+}
+
+
+/*
+ * 'cupsLangGet()' - Get a language.
+ */
+
+cups_lang_t * /* O - Language data */
+cupsLangGet(const char *language) /* I - Language or locale */
+{
+ int i, count; /* Looping vars */
+ char langname[32], /* Requested language name */
+ *langptr, /* Pointer into language name */
+ real[32], /* Real language name */
+ *realptr, /* Pointer into real language name */
+ filename[1024], /* Filename for language locale file */
+ *localedir; /* Directory for locale files */
+ FILE *fp; /* Language locale file pointer */
+ char line[1024]; /* Line from file */
+ cups_msg_t msg; /* Message number */
+ char *text; /* Message text */
+ cups_lang_t *lang; /* Current language... */
+
+
+ /*
+ * Convert the language string passed in to a locale string. "C" is the
+ * standard POSIX locale and is copied unchanged. Otherwise the
+ * language string is converted from ll-cc (language-country) to ll_cc
+ * to match the file naming convention used by all POSIX-compliant
+ * operating systems.
+ */
+
+ if (language == NULL || language[0] == '\0' ||
+ strcmp(language, "POSIX") == 0)
+ strcpy(langname, "C");
+ else
+ {
+ /*
+ * Copy the locale string over safely...
+ */
+
+ strlcpy(langname, language, sizeof(langname));
+ }
+
+ if (strlen(langname) < 2)
+ strcpy(real, "C");
+ else
+ {
+ /*
+ * Convert the language name to a normalized form, e.g.:
+ *
+ * ll[_CC[.charset]]
+ */
+
+ real[0] = tolower(langname[0]);
+ real[1] = tolower(langname[1]);
+ realptr = real + 2;
+ langptr = langname + 2;
+
+ if (*langptr == '_' || *langptr == '-')
+ {
+ /*
+ * Add country code...
+ */
+
+ *realptr++ = '_';
+ langptr ++;
+
+ *realptr++ = toupper(*langptr++);
+ *realptr++ = toupper(*langptr++);
+ }
+
+ if (*langptr == '.')
+ {
+ /*
+ * Add charset...
+ */
+
+ *langptr++ = '\0';
+ *realptr++ = '.';
+
+ while (*langptr)
+ {
+ if ((realptr - real) < (sizeof(real) - 1) &&
+ *langptr != '-' && *langptr != '_')
+ *realptr++ = tolower(*langptr++);
+ else
+ langptr ++;
+ }
+ }
+
+ *realptr = '\0';
+ }
+
+ /*
+ * See if we already have this language loaded...
+ */
+
+ for (lang = lang_cache; lang != NULL; lang = lang->next)
+ if (strcmp(lang->language, langname) == 0)
+ {
+ lang->used ++;
+
+ return (lang);
+ }
+
+
+ /*
+ * Next try to open a locale file; we will try the charset-localized
+ * file first, then the country-localized file, and finally look for
+ * a generic language file. If all else fails we will use the POSIX
+ * locale.
+ */
+
+ if ((localedir = getenv("LOCALEDIR")) == NULL)
+ localedir = CUPS_LOCALEDIR;
+
+ for (fp = NULL; fp == NULL;)
+ {
+ snprintf(filename, sizeof(filename), "%s/%s/cups_%s", localedir,
+ real, real);
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ {
+ if ((realptr = strchr(real, '.')) != NULL)
+ *realptr = '\0';
+ else if ((realptr = strchr(real, '_')) != NULL)
+ *realptr = '\0';
+ else
+ break;
+ }
+ }
+
+ /*
+ * OK, we have an open messages file; the first line will contain the
+ * language encoding (us-ascii, iso-8859-1, etc.), and the rest will
+ * be messages consisting of:
+ *
+ * #### SP message text
+ *
+ * or:
+ *
+ * message text
+ *
+ * If the line starts with a number, then message processing picks up
+ * where the number indicates. Otherwise the last message number is
+ * incremented.
+ *
+ * All leading whitespace is deleted.
+ */
+
+ if (fp == NULL)
+ strlcpy(line, lang_default[0], sizeof(line));
+ else if (fgets(line, sizeof(line), fp) == NULL)
+ {
+ /*
+ * Can't read encoding!
+ */
+
+ fclose(fp);
+ return (NULL);
+ }
+
+ i = strlen(line) - 1;
+ if (line[i] == '\n')
+ line[i] = '\0'; /* Strip LF */
+
+ /*
+ * See if there is a free language available; if so, use that
+ * record...
+ */
+
+ for (lang = lang_cache; lang != NULL; lang = lang->next)
+ if (lang->used == 0)
+ break;
+
+ if (lang == NULL)
+ {
+ /*
+ * Allocate memory for the language and add it to the cache.
+ */
+
+ if ((lang = calloc(sizeof(cups_lang_t), 1)) == NULL)
+ {
+ fclose(fp);
+ return (NULL);
+ }
+
+ lang->next = lang_cache;
+ lang_cache = lang;
+ }
+
+ /*
+ * Free all old strings as needed...
+ */
+
+ for (i = 0; i < CUPS_MSG_MAX; i ++)
+ {
+ if (lang->messages[i] != NULL && lang->messages[i] != lang_blank)
+ free(lang->messages[i]);
+
+ lang->messages[i] = lang_blank;
+ }
+
+ /*
+ * Then assign the language and encoding fields...
+ */
+
+ lang->used ++;
+ strlcpy(lang->language, langname, sizeof(lang->language));
+
+ for (i = 0; i < (sizeof(lang_encodings) / sizeof(lang_encodings[0])); i ++)
+ if (strcmp(lang_encodings[i], line) == 0)
+ {
+ lang->encoding = (cups_encoding_t)i;
+ break;
+ }
+
+ /*
+ * Read the strings from the file...
+ */
+
+ msg = (cups_msg_t)-1;
+ count = 1;
+
+ for (;;)
+ {
+ /*
+ * Read a line from memory or from a file...
+ */
+
+ if (fp == NULL)
+ {
+ if (lang_default[count] == NULL)
+ break;
+
+ strlcpy(line, lang_default[count], sizeof(line));
+ }
+ else if (fgets(line, sizeof(line), fp) == NULL)
+ break;
+
+ count ++;
+
+ /*
+ * Ignore blank lines...
+ */
+
+ i = strlen(line) - 1;
+ if (line[i] == '\n')
+ line[i] = '\0'; /* Strip LF */
+
+ if (line[0] == '\0')
+ continue;
+
+ /*
+ * Grab the message number and text...
+ */
+
+ if (isdigit(line[0]))
+ msg = (cups_msg_t)atoi(line);
+ else
+ msg ++;
+
+ if (msg < 0 || msg >= CUPS_MSG_MAX)
+ continue;
+
+ text = line;
+ while (isdigit(*text))
+ text ++;
+ while (isspace(*text))
+ text ++;
+
+ lang->messages[msg] = strdup(text);
+ }
+
+ /*
+ * Close the file and return...
+ */
+
+ if (fp != NULL)
+ fclose(fp);
+
+ return (lang);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/language.h b/cups/language.h
new file mode 100644
index 000000000..d636d5802
--- /dev/null
+++ b/cups/language.h
@@ -0,0 +1,228 @@
+/*
+ * "$Id$"
+ *
+ * Multi-language support for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _CUPS_LANGUAGE_H_
+# define _CUPS_LANGUAGE_H_
+
+/*
+ * Include necessary headers...
+ */
+
+# include <locale.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+/*
+ * Messages...
+ */
+
+typedef enum /**** Message Indices ****/
+{
+ CUPS_MSG_OK,
+ CUPS_MSG_CANCEL,
+ CUPS_MSG_HELP,
+ CUPS_MSG_QUIT,
+ CUPS_MSG_CLOSE,
+ CUPS_MSG_YES,
+ CUPS_MSG_NO,
+ CUPS_MSG_ON,
+ CUPS_MSG_OFF,
+ CUPS_MSG_SAVE,
+ CUPS_MSG_DISCARD,
+ CUPS_MSG_DEFAULT,
+ CUPS_MSG_OPTIONS,
+ CUPS_MSG_MORE_INFO,
+ CUPS_MSG_BLACK,
+ CUPS_MSG_COLOR,
+ CUPS_MSG_CYAN,
+ CUPS_MSG_MAGENTA,
+ CUPS_MSG_YELLOW,
+ CUPS_MSG_COPYRIGHT,
+ CUPS_MSG_GENERAL,
+ CUPS_MSG_PRINTER,
+ CUPS_MSG_IMAGE,
+ CUPS_MSG_HPGL2,
+ CUPS_MSG_EXTRA,
+ CUPS_MSG_DOCUMENT,
+ CUPS_MSG_OTHER,
+ CUPS_MSG_PRINT_PAGES,
+ CUPS_MSG_ENTIRE_DOCUMENT,
+ CUPS_MSG_PAGE_RANGE,
+ CUPS_MSG_REVERSE_ORDER,
+ CUPS_MSG_PAGE_FORMAT,
+ CUPS_MSG_1_UP,
+ CUPS_MSG_2_UP,
+ CUPS_MSG_4_UP,
+ CUPS_MSG_IMAGE_SCALING,
+ CUPS_MSG_USE_NATURAL_IMAGE_SIZE,
+ CUPS_MSG_ZOOM_BY_PERCENT,
+ CUPS_MSG_ZOOM_BY_PPI,
+ CUPS_MSG_MIRROR_IMAGE,
+ CUPS_MSG_COLOR_SATURATION,
+ CUPS_MSG_COLOR_HUE,
+ CUPS_MSG_FIT_TO_PAGE,
+ CUPS_MSG_SHADING,
+ CUPS_MSG_DEFAULT_PEN_WIDTH,
+ CUPS_MSG_GAMMA_CORRECTION,
+ CUPS_MSG_BRIGHTNESS,
+ CUPS_MSG_ADD,
+ CUPS_MSG_DELETE,
+ CUPS_MSG_MODIFY,
+ CUPS_MSG_PRINTER_URI,
+ CUPS_MSG_PRINTER_NAME,
+ CUPS_MSG_PRINTER_LOCATION,
+ CUPS_MSG_PRINTER_INFO,
+ CUPS_MSG_PRINTER_MAKE_AND_MODEL,
+ CUPS_MSG_DEVICE_URI,
+ CUPS_MSG_FORMATTING_PAGE,
+ CUPS_MSG_PRINTING_PAGE,
+ CUPS_MSG_INITIALIZING_PRINTER,
+ CUPS_MSG_PRINTER_STATE,
+ CUPS_MSG_ACCEPTING_JOBS,
+ CUPS_MSG_NOT_ACCEPTING_JOBS,
+ CUPS_MSG_PRINT_JOBS,
+ CUPS_MSG_CLASS,
+ CUPS_MSG_LOCAL,
+ CUPS_MSG_REMOTE,
+ CUPS_MSG_DUPLEXING,
+ CUPS_MSG_STAPLING,
+ CUPS_MSG_FAST_COPIES,
+ CUPS_MSG_COLLATED_COPIES,
+ CUPS_MSG_PUNCHING,
+ CUPS_MSG_COVERING,
+ CUPS_MSG_BINDING,
+ CUPS_MSG_SORTING,
+ CUPS_MSG_SMALL,
+ CUPS_MSG_MEDIUM,
+ CUPS_MSG_LARGE,
+ CUPS_MSG_VARIABLE,
+ CUPS_MSG_IDLE,
+ CUPS_MSG_PROCESSING,
+ CUPS_MSG_STOPPED,
+ CUPS_MSG_ALL,
+ CUPS_MSG_ODD,
+ CUPS_MSG_EVEN_PAGES,
+ CUPS_MSG_DARKER_LIGHTER,
+ CUPS_MSG_MEDIA_SIZE,
+ CUPS_MSG_MEDIA_TYPE,
+ CUPS_MSG_MEDIA_SOURCE,
+ CUPS_MSG_ORIENTATION,
+ CUPS_MSG_PORTRAIT,
+ CUPS_MSG_LANDSCAPE,
+ CUPS_MSG_JOB_STATE,
+ CUPS_MSG_JOB_NAME,
+ CUPS_MSG_USER_NAME,
+ CUPS_MSG_PRIORITY,
+ CUPS_MSG_COPIES,
+ CUPS_MSG_FILE_SIZE,
+ CUPS_MSG_PENDING,
+ CUPS_MSG_OUTPUT_MODE,
+ CUPS_MSG_RESOLUTION,
+ CUPS_MSG_TEXT,
+ CUPS_MSG_PRETTYPRINT,
+ CUPS_MSG_MARGINS,
+ CUPS_MSG_LEFT,
+ CUPS_MSG_RIGHT,
+ CUPS_MSG_BOTTOM,
+ CUPS_MSG_TOP,
+ CUPS_MSG_FILENAME,
+ CUPS_MSG_PRINT,
+ CUPS_MSG_OPTIONS_INSTALLED,
+ CUPS_MSG_AUTO,
+ CUPS_MSG_HTTP_BASE = 200,
+ CUPS_MSG_HTTP_END = 505,
+ CUPS_MSG_MAX
+} cups_msg_t;
+
+typedef enum /**** Language Encodings ****/
+{
+ CUPS_US_ASCII,
+ CUPS_ISO8859_1,
+ CUPS_ISO8859_2,
+ CUPS_ISO8859_3,
+ CUPS_ISO8859_4,
+ CUPS_ISO8859_5,
+ CUPS_ISO8859_6,
+ CUPS_ISO8859_7,
+ CUPS_ISO8859_8,
+ CUPS_ISO8859_9,
+ CUPS_ISO8859_10,
+ CUPS_UTF8,
+ CUPS_ISO8859_13,
+ CUPS_ISO8859_14,
+ CUPS_ISO8859_15,
+ CUPS_WINDOWS_874,
+ CUPS_WINDOWS_1250,
+ CUPS_WINDOWS_1251,
+ CUPS_WINDOWS_1252,
+ CUPS_WINDOWS_1253,
+ CUPS_WINDOWS_1254,
+ CUPS_WINDOWS_1255,
+ CUPS_WINDOWS_1256,
+ CUPS_WINDOWS_1257,
+ CUPS_WINDOWS_1258,
+ CUPS_KOI8_R,
+ CUPS_KOI8_U
+} cups_encoding_t;
+
+typedef struct cups_lang_str /**** Language Cache Structure ****/
+{
+ struct cups_lang_str *next; /* Next language in cache */
+ int used; /* Number of times this entry has been used. */
+ cups_encoding_t encoding; /* Text encoding */
+ char language[16]; /* Language/locale name */
+ char *messages[CUPS_MSG_MAX];
+ /* Message array */
+} cups_lang_t;
+
+
+/*
+ * Prototypes...
+ */
+
+# if defined(WIN32) || defined(__EMX__) || defined(__APPLE__)
+# define cupsLangDefault() cupsLangGet(setlocale(LC_ALL, ""))
+# else
+# define cupsLangDefault() cupsLangGet(setlocale(LC_MESSAGES, ""))
+# endif /* WIN32 || __EMX__ || __APPLE__ */
+
+extern char *cupsLangEncoding(cups_lang_t *lang);
+extern void cupsLangFlush(void);
+extern void cupsLangFree(cups_lang_t *lang);
+extern cups_lang_t *cupsLangGet(const char *language);
+# define cupsLangString(lang,msg) (lang)->messages[(msg)]
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !_CUPS_LANGUAGE_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/mark.c b/cups/mark.c
new file mode 100644
index 000000000..04937c430
--- /dev/null
+++ b/cups/mark.c
@@ -0,0 +1,443 @@
+/*
+ * "$Id$"
+ *
+ * Option marking routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * PostScript is a trademark of Adobe Systems, Inc.
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ppdConflicts() - Check to see if there are any conflicts.
+ * ppdFindChoice() - Return a pointer to an option choice.
+ * ppdFindMarkedChoice() - Return the marked choice for the specified option.
+ * ppdFindOption() - Return a pointer to the specified option.
+ * ppdIsMarked() - Check to see if an option is marked...
+ * ppdMarkDefaults() - Mark all default options in the PPD file.
+ * ppdMarkOption() - Mark an option in a PPD file.
+ * ppd_defaults() - Set the defaults for this group and all sub-groups.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "ppd.h"
+#include "string.h"
+#include "debug.h"
+
+
+/*
+ * Local functions...
+ */
+
+static void ppd_defaults(ppd_file_t *ppd, ppd_group_t *g);
+
+
+/*
+ * 'ppdConflicts()' - Check to see if there are any conflicts.
+ */
+
+int /* O - Number of conflicts found */
+ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */
+{
+ int i, j, k, /* Looping variables */
+ conflicts; /* Number of conflicts */
+ ppd_const_t *c; /* Current constraint */
+ ppd_group_t *g, *sg; /* Groups */
+ ppd_option_t *o1, *o2; /* Options */
+ ppd_choice_t *c1, *c2; /* Choices */
+
+
+ if (ppd == NULL)
+ return (0);
+
+ /*
+ * Clear all conflicts...
+ */
+
+ conflicts = 0;
+
+ for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++)
+ {
+ for (j = g->num_options, o1 = g->options; j > 0; j --, o1 ++)
+ o1->conflicted = 0;
+
+ for (j = g->num_subgroups, sg = g->subgroups; j > 0; j --, sg ++)
+ for (k = sg->num_options, o1 = sg->options; k > 0; k --, o1 ++)
+ o1->conflicted = 0;
+ }
+
+ /*
+ * Loop through all of the UI constraints and flag any options
+ * that conflict...
+ */
+
+ for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
+ {
+ /*
+ * Grab pointers to the first option...
+ */
+
+ o1 = ppdFindOption(ppd, c->option1);
+
+ if (o1 == NULL)
+ continue;
+ else if (c->choice1[0] != '\0')
+ {
+ /*
+ * This constraint maps to a specific choice.
+ */
+
+ c1 = ppdFindChoice(o1, c->choice1);
+ }
+ else
+ {
+ /*
+ * This constraint applies to any choice for this option.
+ */
+
+ for (j = o1->num_choices, c1 = o1->choices; j > 0; j --, c1 ++)
+ if (c1->marked)
+ break;
+
+ if (j == 0 ||
+ strcasecmp(c1->choice, "None") == 0 ||
+ strcasecmp(c1->choice, "Off") == 0 ||
+ strcasecmp(c1->choice, "False") == 0)
+ c1 = NULL;
+ }
+
+ /*
+ * Grab pointers to the second option...
+ */
+
+ o2 = ppdFindOption(ppd, c->option2);
+
+ if (o2 == NULL)
+ continue;
+ else if (c->choice2[0] != '\0')
+ {
+ /*
+ * This constraint maps to a specific choice.
+ */
+
+ c2 = ppdFindChoice(o2, c->choice2);
+ }
+ else
+ {
+ /*
+ * This constraint applies to any choice for this option.
+ */
+
+ for (j = o2->num_choices, c2 = o2->choices; j > 0; j --, c2 ++)
+ if (c2->marked)
+ break;
+
+ if (j == 0 ||
+ strcasecmp(c2->choice, "None") == 0 ||
+ strcasecmp(c2->choice, "Off") == 0 ||
+ strcasecmp(c2->choice, "False") == 0)
+ c2 = NULL;
+ }
+
+ /*
+ * If both options are marked then there is a conflict...
+ */
+
+ if (c1 != NULL && c1->marked &&
+ c2 != NULL && c2->marked)
+ {
+ DEBUG_printf(("%s->%s conflicts with %s->%s (%s %s %s %s)\n",
+ o1->keyword, c1->choice, o2->keyword, c2->choice,
+ c->option1, c->choice1, c->option2, c->choice2));
+ conflicts ++;
+ o1->conflicted = 1;
+ o2->conflicted = 1;
+ }
+ }
+
+ /*
+ * Return the number of conflicts found...
+ */
+
+ return (conflicts);
+}
+
+
+/*
+ * 'ppdFindChoice()' - Return a pointer to an option choice.
+ */
+
+ppd_choice_t * /* O - Choice pointer or NULL */
+ppdFindChoice(ppd_option_t *o, /* I - Pointer to option */
+ const char *choice) /* I - Name of choice */
+{
+ int i; /* Looping var */
+ ppd_choice_t *c; /* Current choice */
+
+
+ if (o == NULL || choice == NULL)
+ return (NULL);
+
+ for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
+ if (strcasecmp(c->choice, choice) == 0)
+ return (c);
+
+ return (NULL);
+}
+
+
+/*
+ * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option.
+ */
+
+ppd_choice_t * /* O - Pointer to choice or NULL */
+ppdFindMarkedChoice(ppd_file_t *ppd, /* I - PPD file */
+ const char *option) /* I - Keyword/option name */
+{
+ int i; /* Looping var */
+ ppd_option_t *o; /* Pointer to option */
+ ppd_choice_t *c; /* Pointer to choice */
+
+
+ if ((o = ppdFindOption(ppd, option)) == NULL)
+ return (NULL);
+
+ for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
+ if (c->marked)
+ return (c);
+
+ return (NULL);
+}
+
+
+/*
+ * 'ppdFindOption()' - Return a pointer to the specified option.
+ */
+
+ppd_option_t * /* O - Pointer to option or NULL */
+ppdFindOption(ppd_file_t *ppd, /* I - PPD file data */
+ const char *option) /* I - Option/Keyword name */
+{
+ int i, j, k; /* Looping vars */
+ ppd_option_t *o; /* Pointer to option */
+ ppd_group_t *g, /* Pointer to group */
+ *sg; /* Pointer to subgroup */
+
+
+ if (ppd == NULL || option == NULL)
+ return (NULL);
+
+ for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++)
+ {
+ for (j = g->num_options, o = g->options; j > 0; j --, o ++)
+ if (strcasecmp(o->keyword, option) == 0)
+ return (o);
+
+ for (j = g->num_subgroups, sg = g->subgroups; j > 0; j --, sg ++)
+ for (k = sg->num_options, o = sg->options; k > 0; k --, o ++)
+ if (strcasecmp(o->keyword, option) == 0)
+ return (o);
+ }
+
+ return (NULL);
+}
+
+
+/*
+ * 'ppdIsMarked()' - Check to see if an option is marked...
+ */
+
+int /* O - Non-zero if option is marked */
+ppdIsMarked(ppd_file_t *ppd, /* I - PPD file data */
+ const char *option, /* I - Option/Keyword name */
+ const char *choice) /* I - Choice name */
+{
+ ppd_option_t *o; /* Option pointer */
+ ppd_choice_t *c; /* Choice pointer */
+
+
+ if (ppd == NULL)
+ return (0);
+
+ if ((o = ppdFindOption(ppd, option)) == NULL)
+ return (0);
+
+ if ((c = ppdFindChoice(o, choice)) == NULL)
+ return (0);
+
+ return (c->marked);
+}
+
+
+/*
+ * 'ppdMarkDefaults()' - Mark all default options in the PPD file.
+ */
+
+void
+ppdMarkDefaults(ppd_file_t *ppd)/* I - PPD file record */
+{
+ int i; /* Looping variables */
+ ppd_group_t *g; /* Current group */
+
+
+ if (ppd == NULL)
+ return;
+
+ for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++)
+ ppd_defaults(ppd, g);
+}
+
+
+/*
+ * 'ppdMarkOption()' - Mark an option in a PPD file.
+ *
+ * Notes:
+ *
+ * -1 is returned if the given option would conflict with any currently
+ * selected option.
+ */
+
+int /* O - Number of conflicts */
+ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */
+ const char *option, /* I - Keyword */
+ const char *choice) /* I - Option name */
+{
+ int i; /* Looping var */
+ ppd_option_t *o; /* Option pointer */
+ ppd_choice_t *c; /* Choice pointer */
+
+
+ if (ppd == NULL)
+ return (0);
+
+ if (strcasecmp(option, "PageSize") == 0 && strncasecmp(choice, "Custom.", 7) == 0)
+ {
+ /*
+ * Handle variable page sizes...
+ */
+
+ ppdPageSize(ppd, choice);
+ choice = "Custom";
+ }
+
+ if ((o = ppdFindOption(ppd, option)) == NULL)
+ return (0);
+
+ for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
+ if (strcasecmp(c->choice, choice) == 0)
+ break;
+
+ if (i)
+ {
+ /*
+ * Option found; mark it and then handle unmarking any other options.
+ */
+
+ c->marked = 1;
+
+ if (o->ui != PPD_UI_PICKMANY)
+ for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
+ if (strcasecmp(c->choice, choice) != 0)
+ c->marked = 0;
+
+ if (strcasecmp(option, "PageSize") == 0 || strcasecmp(option, "PageRegion") == 0)
+ {
+ /*
+ * Mark current page size...
+ */
+
+ for (i = 0; i < ppd->num_sizes; i ++)
+ ppd->sizes[i].marked = strcasecmp(ppd->sizes[i].name, choice) == 0;
+
+ /*
+ * Unmark the current PageSize or PageRegion setting, as appropriate...
+ */
+
+ if (strcasecmp(option, "PageSize") == 0)
+ {
+ if ((o = ppdFindOption(ppd, "PageRegion")) != NULL)
+ for (i = 0; i < o->num_choices; i ++)
+ o->choices[i].marked = 0;
+ }
+ else
+ {
+ if ((o = ppdFindOption(ppd, "PageSize")) != NULL)
+ for (i = 0; i < o->num_choices; i ++)
+ o->choices[i].marked = 0;
+ }
+ }
+ else if (strcasecmp(option, "InputSlot") == 0)
+ {
+ /*
+ * Unmark ManualFeed option...
+ */
+
+ if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL)
+ for (i = 0; i < o->num_choices; i ++)
+ o->choices[i].marked = 0;
+ }
+ else if (strcasecmp(option, "ManualFeed") == 0)
+ {
+ /*
+ * Unmark InputSlot option...
+ */
+
+ if ((o = ppdFindOption(ppd, "InputSlot")) != NULL)
+ for (i = 0; i < o->num_choices; i ++)
+ o->choices[i].marked = 0;
+ }
+ }
+
+ return (ppdConflicts(ppd));
+}
+
+
+/*
+ * 'ppd_defaults()' - Set the defaults for this group and all sub-groups.
+ */
+
+static void
+ppd_defaults(ppd_file_t *ppd, /* I - PPD file */
+ ppd_group_t *g) /* I - Group to default */
+{
+ int i; /* Looping var */
+ ppd_option_t *o; /* Current option */
+ ppd_group_t *sg; /* Current sub-group */
+
+
+ if (g == NULL)
+ return;
+
+ for (i = g->num_options, o = g->options; i > 0; i --, o ++)
+ if (strcasecmp(o->keyword, "PageRegion") != 0)
+ ppdMarkOption(ppd, o->keyword, o->defchoice);
+
+ for (i = g->num_subgroups, sg = g->subgroups; i > 0; i --, sg ++)
+ ppd_defaults(ppd, sg);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/md5.c b/cups/md5.c
new file mode 100644
index 000000000..5db868858
--- /dev/null
+++ b/cups/md5.c
@@ -0,0 +1,392 @@
+/*
+ Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/*$Id$ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321.
+ It is derived directly from the text of the RFC and not from the
+ reference implementation.
+
+ The original and principal author of md5.c is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+ 1999-05-03 lpd Original version.
+ */
+
+#include "md5.h"
+#include "string.h"
+
+#ifdef TEST
+/*
+ * Compile with -DTEST to create a self-contained executable test program.
+ * The test program should print out the same values as given in section
+ * A.5 of RFC 1321, reproduced below.
+ */
+main()
+{
+ static const char *const test[7] = {
+ "", /*d41d8cd98f00b204e9800998ecf8427e*/
+ "a", /*0cc175b9c0f1b6a831c399e269772661*/
+ "abc", /*900150983cd24fb0d6963f7d28e17f72*/
+ "message digest", /*f96b697d7cb7938d525a2f31aaf161d0*/
+ "abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b*/
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ /*d174ab98d277d9f5a5611c2c9f419d9f*/
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a*/
+ };
+ int i;
+
+ for (i = 0; i < 7; ++i) {
+ md5_state_t state;
+ md5_byte_t digest[16];
+ int di;
+
+ md5_init(&state);
+ md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i]));
+ md5_finish(&state, digest);
+ printf("MD5 (\"%s\") = ", test[i]);
+ for (di = 0; di < 16; ++di)
+ printf("%02x", digest[di]);
+ printf("\n");
+ }
+ return 0;
+}
+#endif /* TEST */
+
+
+/*
+ * For reference, here is the program that computed the T values.
+ */
+#if 0
+#include <math.h>
+main()
+{
+ int i;
+ for (i = 1; i <= 64; ++i) {
+ unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));
+ printf("#define T%d 0x%08lx\n", i, v);
+ }
+ return 0;
+}
+#endif
+/*
+ * End of T computation program.
+ */
+#define T1 0xd76aa478
+#define T2 0xe8c7b756
+#define T3 0x242070db
+#define T4 0xc1bdceee
+#define T5 0xf57c0faf
+#define T6 0x4787c62a
+#define T7 0xa8304613
+#define T8 0xfd469501
+#define T9 0x698098d8
+#define T10 0x8b44f7af
+#define T11 0xffff5bb1
+#define T12 0x895cd7be
+#define T13 0x6b901122
+#define T14 0xfd987193
+#define T15 0xa679438e
+#define T16 0x49b40821
+#define T17 0xf61e2562
+#define T18 0xc040b340
+#define T19 0x265e5a51
+#define T20 0xe9b6c7aa
+#define T21 0xd62f105d
+#define T22 0x02441453
+#define T23 0xd8a1e681
+#define T24 0xe7d3fbc8
+#define T25 0x21e1cde6
+#define T26 0xc33707d6
+#define T27 0xf4d50d87
+#define T28 0x455a14ed
+#define T29 0xa9e3e905
+#define T30 0xfcefa3f8
+#define T31 0x676f02d9
+#define T32 0x8d2a4c8a
+#define T33 0xfffa3942
+#define T34 0x8771f681
+#define T35 0x6d9d6122
+#define T36 0xfde5380c
+#define T37 0xa4beea44
+#define T38 0x4bdecfa9
+#define T39 0xf6bb4b60
+#define T40 0xbebfbc70
+#define T41 0x289b7ec6
+#define T42 0xeaa127fa
+#define T43 0xd4ef3085
+#define T44 0x04881d05
+#define T45 0xd9d4d039
+#define T46 0xe6db99e5
+#define T47 0x1fa27cf8
+#define T48 0xc4ac5665
+#define T49 0xf4292244
+#define T50 0x432aff97
+#define T51 0xab9423a7
+#define T52 0xfc93a039
+#define T53 0x655b59c3
+#define T54 0x8f0ccc92
+#define T55 0xffeff47d
+#define T56 0x85845dd1
+#define T57 0x6fa87e4f
+#define T58 0xfe2ce6e0
+#define T59 0xa3014314
+#define T60 0x4e0811a1
+#define T61 0xf7537e82
+#define T62 0xbd3af235
+#define T63 0x2ad7d2bb
+#define T64 0xeb86d391
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+ md5_word_t
+ a = pms->abcd[0], b = pms->abcd[1],
+ c = pms->abcd[2], d = pms->abcd[3];
+ md5_word_t t;
+
+#ifndef ARCH_IS_BIG_ENDIAN
+# define ARCH_IS_BIG_ENDIAN 1 /* slower, default implementation */
+#endif
+#if ARCH_IS_BIG_ENDIAN
+
+ /*
+ * On big-endian machines, we must arrange the bytes in the right
+ * order. (This also works on machines of unknown byte order.)
+ */
+ md5_word_t X[16];
+ const md5_byte_t *xp = data;
+ int i;
+
+ for (i = 0; i < 16; ++i, xp += 4)
+ X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+
+#else /* !ARCH_IS_BIG_ENDIAN */
+
+ /*
+ * On little-endian machines, we can process properly aligned data
+ * without copying it.
+ */
+ md5_word_t xbuf[16];
+ const md5_word_t *X;
+
+ if (!((data - (const md5_byte_t *)0) & 3)) {
+ /* data are properly aligned */
+ X = (const md5_word_t *)data;
+ } else {
+ /* not aligned */
+ memcpy(xbuf, data, 64);
+ X = xbuf;
+ }
+#endif
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + F(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 7, T1);
+ SET(d, a, b, c, 1, 12, T2);
+ SET(c, d, a, b, 2, 17, T3);
+ SET(b, c, d, a, 3, 22, T4);
+ SET(a, b, c, d, 4, 7, T5);
+ SET(d, a, b, c, 5, 12, T6);
+ SET(c, d, a, b, 6, 17, T7);
+ SET(b, c, d, a, 7, 22, T8);
+ SET(a, b, c, d, 8, 7, T9);
+ SET(d, a, b, c, 9, 12, T10);
+ SET(c, d, a, b, 10, 17, T11);
+ SET(b, c, d, a, 11, 22, T12);
+ SET(a, b, c, d, 12, 7, T13);
+ SET(d, a, b, c, 13, 12, T14);
+ SET(c, d, a, b, 14, 17, T15);
+ SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + G(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 1, 5, T17);
+ SET(d, a, b, c, 6, 9, T18);
+ SET(c, d, a, b, 11, 14, T19);
+ SET(b, c, d, a, 0, 20, T20);
+ SET(a, b, c, d, 5, 5, T21);
+ SET(d, a, b, c, 10, 9, T22);
+ SET(c, d, a, b, 15, 14, T23);
+ SET(b, c, d, a, 4, 20, T24);
+ SET(a, b, c, d, 9, 5, T25);
+ SET(d, a, b, c, 14, 9, T26);
+ SET(c, d, a, b, 3, 14, T27);
+ SET(b, c, d, a, 8, 20, T28);
+ SET(a, b, c, d, 13, 5, T29);
+ SET(d, a, b, c, 2, 9, T30);
+ SET(c, d, a, b, 7, 14, T31);
+ SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + H(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 5, 4, T33);
+ SET(d, a, b, c, 8, 11, T34);
+ SET(c, d, a, b, 11, 16, T35);
+ SET(b, c, d, a, 14, 23, T36);
+ SET(a, b, c, d, 1, 4, T37);
+ SET(d, a, b, c, 4, 11, T38);
+ SET(c, d, a, b, 7, 16, T39);
+ SET(b, c, d, a, 10, 23, T40);
+ SET(a, b, c, d, 13, 4, T41);
+ SET(d, a, b, c, 0, 11, T42);
+ SET(c, d, a, b, 3, 16, T43);
+ SET(b, c, d, a, 6, 23, T44);
+ SET(a, b, c, d, 9, 4, T45);
+ SET(d, a, b, c, 12, 11, T46);
+ SET(c, d, a, b, 15, 16, T47);
+ SET(b, c, d, a, 2, 23, T48);
+#undef SET
+
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + I(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 6, T49);
+ SET(d, a, b, c, 7, 10, T50);
+ SET(c, d, a, b, 14, 15, T51);
+ SET(b, c, d, a, 5, 21, T52);
+ SET(a, b, c, d, 12, 6, T53);
+ SET(d, a, b, c, 3, 10, T54);
+ SET(c, d, a, b, 10, 15, T55);
+ SET(b, c, d, a, 1, 21, T56);
+ SET(a, b, c, d, 8, 6, T57);
+ SET(d, a, b, c, 15, 10, T58);
+ SET(c, d, a, b, 6, 15, T59);
+ SET(b, c, d, a, 13, 21, T60);
+ SET(a, b, c, d, 4, 6, T61);
+ SET(d, a, b, c, 11, 10, T62);
+ SET(c, d, a, b, 2, 15, T63);
+ SET(b, c, d, a, 9, 21, T64);
+#undef SET
+
+ /* Then perform the following additions. (That is increment each
+ of the four registers by the value it had before this block
+ was started.) */
+ pms->abcd[0] += a;
+ pms->abcd[1] += b;
+ pms->abcd[2] += c;
+ pms->abcd[3] += d;
+}
+
+void
+md5_init(md5_state_t *pms)
+{
+ pms->count[0] = pms->count[1] = 0;
+ pms->abcd[0] = 0x67452301;
+ pms->abcd[1] = 0xefcdab89;
+ pms->abcd[2] = 0x98badcfe;
+ pms->abcd[3] = 0x10325476;
+}
+
+void
+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
+{
+ const md5_byte_t *p = data;
+ int left = nbytes;
+ int offset = (pms->count[0] >> 3) & 63;
+ md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+ if (nbytes <= 0)
+ return;
+
+ /* Update the message length. */
+ pms->count[1] += nbytes >> 29;
+ pms->count[0] += nbits;
+ if (pms->count[0] < nbits)
+ pms->count[1]++;
+
+ /* Process an initial partial block. */
+ if (offset) {
+ int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+ memcpy(pms->buf + offset, p, copy);
+ if (offset + copy < 64)
+ return;
+ p += copy;
+ left -= copy;
+ md5_process(pms, pms->buf);
+ }
+
+ /* Process full blocks. */
+ for (; left >= 64; p += 64, left -= 64)
+ md5_process(pms, p);
+
+ /* Process a final partial block. */
+ if (left)
+ memcpy(pms->buf, p, left);
+}
+
+void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+ static const md5_byte_t pad[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ md5_byte_t data[8];
+ int i;
+
+ /* Save the length before padding. */
+ for (i = 0; i < 8; ++i)
+ data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+ /* Pad to 56 bytes mod 64. */
+ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+ /* Append the length. */
+ md5_append(pms, data, 8);
+ for (i = 0; i < 16; ++i)
+ digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
diff --git a/cups/md5.h b/cups/md5.h
new file mode 100644
index 000000000..a2d7b3415
--- /dev/null
+++ b/cups/md5.h
@@ -0,0 +1,94 @@
+/*
+ Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/*$Id$ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321.
+ It is derived directly from the text of the RFC and not from the
+ reference implementation.
+
+ The original and principal author of md5.h is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+ added conditionalization for C++ compilation from Martin
+ Purschke <purschke@bnl.gov>.
+ 1999-05-03 lpd Original version.
+ */
+
+#ifndef md5_INCLUDED
+# define md5_INCLUDED
+
+/*
+ * This code has some adaptations for the Ghostscript environment, but it
+ * will compile and run correctly in any environment with 8-bit chars and
+ * 32-bit ints. Specifically, it assumes that if the following are
+ * defined, they have the same meaning as in Ghostscript: P1, P2, P3,
+ * ARCH_IS_BIG_ENDIAN.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+ md5_word_t count[2]; /* message length in bits, lsw first */
+ md5_word_t abcd[4]; /* digest buffer */
+ md5_byte_t buf[64]; /* accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Initialize the algorithm. */
+#ifdef P1
+void md5_init(P1(md5_state_t *pms));
+#else
+void md5_init(md5_state_t *pms);
+#endif
+
+/* Append a string to the message. */
+#ifdef P3
+void md5_append(P3(md5_state_t *pms, const md5_byte_t *data, int nbytes));
+#else
+void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
+#endif
+
+/* Finish the message and return the digest. */
+#ifdef P2
+void md5_finish(P2(md5_state_t *pms, md5_byte_t digest[16]));
+#else
+void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+#endif
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */
diff --git a/cups/md5passwd.c b/cups/md5passwd.c
new file mode 100644
index 000000000..6cb6b3aa0
--- /dev/null
+++ b/cups/md5passwd.c
@@ -0,0 +1,150 @@
+/*
+ * "$Id$"
+ *
+ * MD5 password support for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * httpMD5() - Compute the MD5 sum of the username:group:password.
+ * httpMD5Nonce() - Combine the MD5 sum of the username, group, and password
+ * with the server-supplied nonce value.
+ * httpMD5String() - Convert an MD5 sum to a character string.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "http.h"
+#include "string.h"
+
+
+/*
+ * 'httpMD5()' - Compute the MD5 sum of the username:group:password.
+ */
+
+char * /* O - MD5 sum */
+httpMD5(const char *username, /* I - User name */
+ const char *realm, /* I - Realm name */
+ const char *passwd, /* I - Password string */
+ char md5[33]) /* O - MD5 string */
+{
+ md5_state_t state; /* MD5 state info */
+ md5_byte_t sum[16]; /* Sum data */
+ char line[256]; /* Line to sum */
+
+
+ /*
+ * Compute the MD5 sum of the user name, group name, and password.
+ */
+
+ snprintf(line, sizeof(line), "%s:%s:%s", username, realm, passwd);
+ md5_init(&state);
+ md5_append(&state, (md5_byte_t *)line, strlen(line));
+ md5_finish(&state, sum);
+
+ /*
+ * Return the sum...
+ */
+
+ return (httpMD5String(sum, md5));
+}
+
+
+/*
+ * 'httpMD5Final()' - Combine the MD5 sum of the username, group, and password
+ * with the server-supplied nonce value, method, and
+ * request-uri.
+ */
+
+char * /* O - New sum */
+httpMD5Final(const char *nonce, /* I - Server nonce value */
+ const char *method, /* I - METHOD (GET, POST, etc.) */
+ const char *resource, /* I - Resource path */
+ char md5[33]) /* IO - MD5 sum */
+{
+ md5_state_t state; /* MD5 state info */
+ md5_byte_t sum[16]; /* Sum data */
+ char line[1024]; /* Line of data */
+ char a2[33]; /* Hash of method and resource */
+
+
+ /*
+ * First compute the MD5 sum of the method and resource...
+ */
+
+ snprintf(line, sizeof(line), "%s:%s", method, resource);
+ md5_init(&state);
+ md5_append(&state, (md5_byte_t *)line, strlen(line));
+ md5_finish(&state, sum);
+ httpMD5String(sum, a2);
+
+ /*
+ * Then combine A1 (MD5 of username, realm, and password) with the nonce
+ * and A2 (method + resource) values to get the final MD5 sum for the
+ * request...
+ */
+
+ snprintf(line, sizeof(line), "%s:%s:%s", md5, nonce, a2);
+
+ md5_init(&state);
+ md5_append(&state, (md5_byte_t *)line, strlen(line));
+ md5_finish(&state, sum);
+
+ return (httpMD5String(sum, md5));
+}
+
+
+/*
+ * 'httpMD5String()' - Convert an MD5 sum to a character string.
+ */
+
+char * /* O - MD5 sum in hex */
+httpMD5String(const md5_byte_t *sum, /* I - MD5 sum data */
+ char md5[33]) /* O - MD5 sum in hex */
+{
+ int i; /* Looping var */
+ char *md5ptr; /* Pointer into MD5 string */
+ static char *hex = "0123456789abcdef";
+ /* Hex digits */
+
+
+ /*
+ * Convert the MD5 sum to hexadecimal...
+ */
+
+ for (i = 16, md5ptr = md5; i > 0; i --, sum ++)
+ {
+ *md5ptr++ = hex[*sum >> 4];
+ *md5ptr++ = hex[*sum & 15];
+ }
+
+ *md5ptr = '\0';
+
+ return (md5);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/options.c b/cups/options.c
new file mode 100644
index 000000000..37d3ab3c7
--- /dev/null
+++ b/cups/options.c
@@ -0,0 +1,432 @@
+/*
+ * "$Id$"
+ *
+ * Option routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * cupsAddOption() - Add an option to an option array.
+ * cupsFreeOptions() - Free all memory used by options.
+ * cupsGetOption() - Get an option value.
+ * cupsParseOptions() - Parse options from a command-line argument.
+ * cupsMarkOptions() - Mark command-line options in a PPD file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include "string.h"
+#include "debug.h"
+
+
+/*
+ * 'cupsAddOption()' - Add an option to an option array.
+ */
+
+int /* O - Number of options */
+cupsAddOption(const char *name, /* I - Name of option */
+ const char *value, /* I - Value of option */
+ int num_options, /* I - Number of options */
+ cups_option_t **options) /* IO - Pointer to options */
+{
+ int i; /* Looping var */
+ cups_option_t *temp; /* Pointer to new option */
+
+
+ if (name == NULL || !name[0] || value == NULL ||
+ options == NULL || num_options < 0)
+ return (num_options);
+
+ /*
+ * Look for an existing option with the same name...
+ */
+
+ for (i = 0, temp = *options; i < num_options; i ++, temp ++)
+ if (strcasecmp(temp->name, name) == 0)
+ break;
+
+ if (i >= num_options)
+ {
+ /*
+ * No matching option name...
+ */
+
+ if (num_options == 0)
+ temp = (cups_option_t *)malloc(sizeof(cups_option_t));
+ else
+ temp = (cups_option_t *)realloc(*options, sizeof(cups_option_t) *
+ (num_options + 1));
+
+ if (temp == NULL)
+ return (0);
+
+ *options = temp;
+ temp += num_options;
+ temp->name = strdup(name);
+ num_options ++;
+ }
+ else
+ {
+ /*
+ * Match found; free the old value...
+ */
+
+ free(temp->value);
+ }
+
+ temp->value = strdup(value);
+
+ return (num_options);
+}
+
+
+/*
+ * 'cupsFreeOptions()' - Free all memory used by options.
+ */
+
+void
+cupsFreeOptions(int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Pointer to options */
+{
+ int i; /* Looping var */
+
+
+ if (num_options <= 0 || options == NULL)
+ return;
+
+ for (i = 0; i < num_options; i ++)
+ {
+ free(options[i].name);
+ free(options[i].value);
+ }
+
+ free(options);
+}
+
+
+/*
+ * 'cupsGetOption()' - Get an option value.
+ */
+
+const char * /* O - Option value or NULL */
+cupsGetOption(const char *name, /* I - Name of option */
+ int num_options,/* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ int i; /* Looping var */
+
+
+ if (name == NULL || num_options <= 0 || options == NULL)
+ return (NULL);
+
+ for (i = 0; i < num_options; i ++)
+ if (strcasecmp(options[i].name, name) == 0)
+ return (options[i].value);
+
+ return (NULL);
+}
+
+
+/*
+ * 'cupsParseOptions()' - Parse options from a command-line argument.
+ */
+
+int /* O - Number of options found */
+cupsParseOptions(const char *arg, /* I - Argument to parse */
+ int num_options, /* I - Number of options */
+ cups_option_t **options) /* O - Options found */
+{
+ char *copyarg, /* Copy of input string */
+ *ptr, /* Pointer into string */
+ *name, /* Pointer to name */
+ *value; /* Pointer to value */
+
+
+ if (arg == NULL || options == NULL || num_options < 0)
+ return (0);
+
+ /*
+ * Make a copy of the argument string and then divide it up...
+ */
+
+ copyarg = strdup(arg);
+ ptr = copyarg;
+
+ /*
+ * Skip leading spaces...
+ */
+
+ while (isspace(*ptr))
+ ptr ++;
+
+ /*
+ * Loop through the string...
+ */
+
+ while (*ptr != '\0')
+ {
+ /*
+ * Get the name up to a SPACE, =, or end-of-string...
+ */
+
+ name = ptr;
+ while (!isspace(*ptr) && *ptr != '=' && *ptr != '\0')
+ ptr ++;
+
+ /*
+ * Avoid an empty name...
+ */
+
+ if (ptr == name)
+ break;
+
+ /*
+ * Skip trailing spaces...
+ */
+
+ while (isspace(*ptr))
+ *ptr++ = '\0';
+
+ if (*ptr != '=')
+ {
+ /*
+ * Start of another option...
+ */
+
+ if (strncasecmp(name, "no", 2) == 0)
+ num_options = cupsAddOption(name + 2, "false", num_options,
+ options);
+ else
+ num_options = cupsAddOption(name, "true", num_options, options);
+
+ continue;
+ }
+
+ /*
+ * Remove = and parse the value...
+ */
+
+ *ptr++ = '\0';
+
+ if (*ptr == '\'')
+ {
+ /*
+ * Quoted string constant...
+ */
+
+ ptr ++;
+ value = ptr;
+
+ while (*ptr != '\'' && *ptr != '\0')
+ ptr ++;
+
+ if (*ptr != '\0')
+ *ptr++ = '\0';
+ }
+ else if (*ptr == '\"')
+ {
+ /*
+ * Double-quoted string constant...
+ */
+
+ ptr ++;
+ value = ptr;
+
+ while (*ptr != '\"' && *ptr != '\0')
+ ptr ++;
+
+ if (*ptr != '\0')
+ *ptr++ = '\0';
+ }
+ else
+ {
+ /*
+ * Normal space-delimited string...
+ */
+
+ value = ptr;
+
+ while (!isspace(*ptr) && *ptr != '\0')
+ ptr ++;
+ }
+
+ /*
+ * Skip trailing whitespace...
+ */
+
+ while (isspace(*ptr))
+ *ptr++ = '\0';
+
+ /*
+ * Add the string value...
+ */
+
+ num_options = cupsAddOption(name, value, num_options, options);
+ }
+
+ /*
+ * Free the copy of the argument we made and return the number of options
+ * found.
+ */
+
+ free(copyarg);
+
+ return (num_options);
+}
+
+
+/*
+ * 'cupsMarkOptions()' - Mark command-line options in a PPD file.
+ */
+
+int /* O - 1 if conflicting */
+cupsMarkOptions(ppd_file_t *ppd, /* I - PPD file */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ int i; /* Looping var */
+ int conflict; /* Option conflicts */
+ char *val, /* Pointer into value */
+ *ptr, /* Pointer into string */
+ s[255]; /* Temporary string */
+
+
+ /*
+ * Check arguments...
+ */
+
+ if (ppd == NULL || num_options <= 0 || options == NULL)
+ return (0);
+
+ /*
+ * Mark options...
+ */
+
+ conflict = 0;
+
+ for (i = num_options; i > 0; i --, options ++)
+ if (strcasecmp(options->name, "media") == 0)
+ {
+ /*
+ * Loop through the option string, separating it at commas and
+ * marking each individual option.
+ */
+
+ for (val = options->value; *val;)
+ {
+ /*
+ * Extract the sub-option from the string...
+ */
+
+ for (ptr = s; *val && *val != ',' && (ptr - s) < (sizeof(s) - 1);)
+ *ptr++ = *val++;
+ *ptr++ = '\0';
+
+ if (*val == ',')
+ val ++;
+
+ /*
+ * Mark it...
+ */
+
+ if (ppdMarkOption(ppd, "PageSize", s))
+ conflict = 1;
+ if (ppdMarkOption(ppd, "InputSlot", s))
+ conflict = 1;
+ if (ppdMarkOption(ppd, "MediaType", s))
+ conflict = 1;
+ if (ppdMarkOption(ppd, "EFMediaQualityMode", s)) /* EFI */
+ conflict = 1;
+ if (strcasecmp(s, "manual") == 0)
+ if (ppdMarkOption(ppd, "ManualFeed", "True"))
+ conflict = 1;
+ }
+ }
+ else if (strcasecmp(options->name, "sides") == 0)
+ {
+ if (strcasecmp(options->value, "one-sided") == 0)
+ {
+ if (ppdMarkOption(ppd, "Duplex", "None"))
+ conflict = 1;
+ if (ppdMarkOption(ppd, "JCLDuplex", "None")) /* Samsung */
+ conflict = 1;
+ if (ppdMarkOption(ppd, "EFDuplex", "None")) /* EFI */
+ conflict = 1;
+ if (ppdMarkOption(ppd, "KD03Duplex", "None")) /* Kodak */
+ conflict = 1;
+ }
+ else if (strcasecmp(options->value, "two-sided-long-edge") == 0)
+ {
+ if (ppdMarkOption(ppd, "Duplex", "DuplexNoTumble"))
+ conflict = 1;
+ if (ppdMarkOption(ppd, "JCLDuplex", "DuplexNoTumble")) /* Samsung */
+ conflict = 1;
+ if (ppdMarkOption(ppd, "EFDuplex", "DuplexNoTumble")) /* EFI */
+ conflict = 1;
+ if (ppdMarkOption(ppd, "KD03Duplex", "DuplexNoTumble")) /* Kodak */
+ conflict = 1;
+ }
+ else if (strcasecmp(options->value, "two-sided-short-edge") == 0)
+ {
+ if (ppdMarkOption(ppd, "Duplex", "DuplexTumble"))
+ conflict = 1;
+ if (ppdMarkOption(ppd, "JCLDuplex", "DuplexTumble")) /* Samsung */
+ conflict = 1;
+ if (ppdMarkOption(ppd, "EFDuplex", "DuplexTumble")) /* EFI */
+ conflict = 1;
+ if (ppdMarkOption(ppd, "KD03Duplex", "DuplexTumble")) /* Kodak */
+ conflict = 1;
+ }
+ }
+ else if (strcasecmp(options->name, "resolution") == 0 ||
+ strcasecmp(options->name, "printer-resolution") == 0)
+ {
+ if (ppdMarkOption(ppd, "Resolution", options->value))
+ conflict = 1;
+ if (ppdMarkOption(ppd, "SetResolution", options->value))
+ /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */
+ conflict = 1;
+ if (ppdMarkOption(ppd, "JCLResolution", options->value)) /* HP */
+ conflict = 1;
+ if (ppdMarkOption(ppd, "CNRes_PGP", options->value)) /* Canon */
+ conflict = 1;
+ }
+ else if (strcasecmp(options->name, "output-bin") == 0)
+ {
+ if (ppdMarkOption(ppd, "OutputBin", options->value))
+ conflict = 1;
+ }
+ else if (ppdMarkOption(ppd, options->name, options->value))
+ conflict = 1;
+
+ return (conflict);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/page.c b/cups/page.c
new file mode 100644
index 000000000..ca3f26233
--- /dev/null
+++ b/cups/page.c
@@ -0,0 +1,191 @@
+/*
+ * "$Id$"
+ *
+ * Page size functions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * PostScript is a trademark of Adobe Systems, Inc.
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ppdPageSize() - Get the page size record for the given size.
+ * ppdPageWidth() - Get the page width for the given size.
+ * ppdPageLength() - Get the page length for the given size.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "ppd.h"
+#include "string.h"
+#include <ctype.h>
+
+
+/*
+ * 'ppdPageSize()' - Get the page size record for the given size.
+ */
+
+ppd_size_t * /* O - Size record for page or NULL */
+ppdPageSize(ppd_file_t *ppd, /* I - PPD file record */
+ const char *name) /* I - Size name */
+{
+ int i; /* Looping var */
+ float w, l; /* Width and length of page */
+ char units[255]; /* Page size units... */
+
+
+ if (ppd == NULL)
+ return (NULL);
+
+ if (name != NULL)
+ {
+ if (strncmp(name, "Custom.", 7) == 0 && ppd->variable_sizes)
+ {
+ /*
+ * Find the custom page size...
+ */
+
+ for (i = 0; i < ppd->num_sizes; i ++)
+ if (strcmp("Custom", ppd->sizes[i].name) == 0)
+ break;
+
+ if (i == ppd->num_sizes)
+ return (NULL);
+
+ /*
+ * Variable size; size name can be one of the following:
+ *
+ * Custom.WIDTHxLENGTHin - Size in inches
+ * Custom.WIDTHxLENGTHcm - Size in centimeters
+ * Custom.WIDTHxLENGTHmm - Size in millimeters
+ * Custom.WIDTHxLENGTH[pt] - Size in points
+ */
+
+ units[0] = '\0';
+ if (sscanf(name + 7, "%fx%f%254s", &w, &l, units) < 2)
+ return (NULL);
+
+ if (strcasecmp(units, "in") == 0)
+ {
+ ppd->sizes[i].width = w * 72.0f;
+ ppd->sizes[i].length = l * 72.0f;
+ ppd->sizes[i].left = ppd->custom_margins[0];
+ ppd->sizes[i].bottom = ppd->custom_margins[1];
+ ppd->sizes[i].right = w * 72.0f - ppd->custom_margins[2];
+ ppd->sizes[i].top = l * 72.0f - ppd->custom_margins[3];
+ }
+ else if (strcasecmp(units, "cm") == 0)
+ {
+ ppd->sizes[i].width = w / 2.54f * 72.0f;
+ ppd->sizes[i].length = l / 2.54f * 72.0f;
+ ppd->sizes[i].left = ppd->custom_margins[0];
+ ppd->sizes[i].bottom = ppd->custom_margins[1];
+ ppd->sizes[i].right = w / 2.54f * 72.0f - ppd->custom_margins[2];
+ ppd->sizes[i].top = l / 2.54f * 72.0f - ppd->custom_margins[3];
+ }
+ else if (strcasecmp(units, "mm") == 0)
+ {
+ ppd->sizes[i].width = w / 25.4f * 72.0f;
+ ppd->sizes[i].length = l / 25.4f * 72.0f;
+ ppd->sizes[i].left = ppd->custom_margins[0];
+ ppd->sizes[i].bottom = ppd->custom_margins[1];
+ ppd->sizes[i].right = w / 25.4f * 72.0f - ppd->custom_margins[2];
+ ppd->sizes[i].top = l / 25.4f * 72.0f - ppd->custom_margins[3];
+ }
+ else
+ {
+ ppd->sizes[i].width = w;
+ ppd->sizes[i].length = l;
+ ppd->sizes[i].left = ppd->custom_margins[0];
+ ppd->sizes[i].bottom = ppd->custom_margins[1];
+ ppd->sizes[i].right = w - ppd->custom_margins[2];
+ ppd->sizes[i].top = l - ppd->custom_margins[3];
+ }
+
+ return (ppd->sizes + i);
+ }
+ else
+ {
+ /*
+ * Lookup by name...
+ */
+
+ for (i = 0; i < ppd->num_sizes; i ++)
+ if (strcmp(name, ppd->sizes[i].name) == 0)
+ return (ppd->sizes + i);
+ }
+ }
+ else
+ {
+ /*
+ * Find default...
+ */
+
+ for (i = 0; i < ppd->num_sizes; i ++)
+ if (ppd->sizes[i].marked)
+ return (ppd->sizes + i);
+ }
+
+ return (NULL);
+}
+
+
+/*
+ * 'ppdPageWidth()' - Get the page width for the given size.
+ */
+
+float /* O - Width of page in points or 0.0 */
+ppdPageWidth(ppd_file_t *ppd, /* I - PPD file record */
+ const char *name) /* I - Size name */
+{
+ ppd_size_t *size; /* Page size */
+
+
+ if ((size = ppdPageSize(ppd, name)) == NULL)
+ return (0.0);
+ else
+ return (size->width);
+}
+
+
+/*
+ * 'ppdPageLength()' - Get the page length for the given size.
+ */
+
+float /* O - Length of page in points or 0.0 */
+ppdPageLength(ppd_file_t *ppd, /* I - PPD file */
+ const char *name) /* I - Size name */
+{
+ ppd_size_t *size; /* Page size */
+
+
+ if ((size = ppdPageSize(ppd, name)) == NULL)
+ return (0.0);
+ else
+ return (size->length);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/ppd.c b/cups/ppd.c
new file mode 100644
index 000000000..5159b4f1c
--- /dev/null
+++ b/cups/ppd.c
@@ -0,0 +1,2058 @@
+/*
+ * "$Id$"
+ *
+ * PPD file routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * PostScript is a trademark of Adobe Systems, Inc.
+ *
+ * This code and any derivative of it may be used and distributed
+ * freely under the terms of the GNU General Public License when
+ * used with GNU Ghostscript or its derivatives. Use of the code
+ * (or any derivative of it) with software other than GNU
+ * GhostScript (or its derivatives) is governed by the CUPS license
+ * agreement.
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ppdClose() - Free all memory used by the PPD file.
+ * ppd_free_group() - Free a single UI group.
+ * ppd_free_option() - Free a single option.
+ * ppdOpen() - Read a PPD file into memory.
+ * ppdOpenFd() - Read a PPD file into memory.
+ * ppdOpenFile() - Read a PPD file into memory.
+ * ppd_read() - Read a line from a PPD file, skipping comment lines
+ * as necessary.
+ * compare_strings() - Compare two strings.
+ * compare_groups() - Compare two groups.
+ * compare_options() - Compare two options.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "ppd.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include "string.h"
+#include "language.h"
+#include "debug.h"
+
+
+/*
+ * Definitions...
+ */
+
+#if defined(WIN32) || defined(__EMX__)
+# define READ_BINARY "rb" /* Open a binary file for reading */
+# define WRITE_BINARY "wb" /* Open a binary file for writing */
+#else
+# define READ_BINARY "r" /* Open a binary file for reading */
+# define WRITE_BINARY "w" /* Open a binary file for writing */
+#endif /* WIN32 || __EMX__ */
+
+#define safe_free(p) if (p) free(p) /* Safe free macro */
+
+#define PPD_KEYWORD 1 /* Line contained a keyword */
+#define PPD_OPTION 2 /* Line contained an option name */
+#define PPD_TEXT 4 /* Line contained human-readable text */
+#define PPD_STRING 8 /* Line contained a string or code */
+
+
+/*
+ * Local functions...
+ */
+
+#ifndef __APPLE__
+static int compare_strings(char *s, char *t);
+static int compare_groups(ppd_group_t *g0, ppd_group_t *g1);
+static int compare_options(ppd_option_t *o0, ppd_option_t *o1);
+#endif /* !__APPLE__ */
+static int ppd_read(FILE *fp, char *keyword, char *option,
+ char *text, char **string);
+static void ppd_decode(char *string);
+#ifdef __APPLE__
+# define ppd_fix(s)
+#else
+static void ppd_fix(char *string);
+#endif /* __APPLE__ */
+static void ppd_free_group(ppd_group_t *group);
+static void ppd_free_option(ppd_option_t *option);
+static ppd_group_t *ppd_get_group(ppd_file_t *ppd, char *name);
+static ppd_option_t *ppd_get_option(ppd_group_t *group, char *name);
+static ppd_choice_t *ppd_add_choice(ppd_option_t *option, char *name);
+
+
+/*
+ * 'ppdClose()' - Free all memory used by the PPD file.
+ */
+
+void
+ppdClose(ppd_file_t *ppd) /* I - PPD file record */
+{
+ int i; /* Looping var */
+ ppd_emul_t *emul; /* Current emulation */
+ ppd_group_t *group; /* Current group */
+ char **font; /* Current font */
+ char **filter; /* Current filter */
+
+
+ /*
+ * Range check the PPD file record...
+ */
+
+ if (ppd == NULL)
+ return;
+
+ /*
+ * Free all strings at the top level...
+ */
+
+ safe_free(ppd->patches);
+ safe_free(ppd->jcl_begin);
+ safe_free(ppd->jcl_ps);
+ safe_free(ppd->jcl_end);
+ safe_free(ppd->lang_encoding);
+ safe_free(ppd->lang_version);
+ safe_free(ppd->modelname);
+ safe_free(ppd->ttrasterizer);
+ safe_free(ppd->manufacturer);
+ safe_free(ppd->product);
+ safe_free(ppd->nickname);
+ safe_free(ppd->shortnickname);
+
+ /*
+ * Free any emulations...
+ */
+
+ if (ppd->num_emulations > 0)
+ {
+ for (i = ppd->num_emulations, emul = ppd->emulations; i > 0; i --, emul ++)
+ {
+ safe_free(emul->start);
+ safe_free(emul->stop);
+ }
+
+ safe_free(ppd->emulations);
+ }
+
+ /*
+ * Free any UI groups, subgroups, and options...
+ */
+
+ if (ppd->num_groups > 0)
+ {
+ for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
+ ppd_free_group(group);
+
+ safe_free(ppd->groups);
+ }
+
+ /*
+ * Free any page sizes...
+ */
+
+ if (ppd->num_sizes > 0)
+ safe_free(ppd->sizes);
+
+ /*
+ * Free any constraints...
+ */
+
+ if (ppd->num_consts > 0)
+ safe_free(ppd->consts);
+
+ /*
+ * Free any filters...
+ */
+
+ if (ppd->num_filters > 0)
+ {
+ for (i = ppd->num_filters, filter = ppd->filters; i > 0; i --, filter ++)
+ safe_free(*filter);
+
+ safe_free(ppd->filters);
+ }
+
+ /*
+ * Free any fonts...
+ */
+
+ if (ppd->num_fonts > 0)
+ {
+ for (i = ppd->num_fonts, font = ppd->fonts; i > 0; i --, font ++)
+ safe_free(*font);
+
+ safe_free(ppd->fonts);
+ }
+
+ /*
+ * Free any profiles...
+ */
+
+ if (ppd->num_profiles > 0)
+ safe_free(ppd->profiles);
+
+ /*
+ * Free the whole record...
+ */
+
+ safe_free(ppd);
+}
+
+
+/*
+ * 'ppd_free_group()' - Free a single UI group.
+ */
+
+static void
+ppd_free_group(ppd_group_t *group) /* I - Group to free */
+{
+ int i; /* Looping var */
+ ppd_option_t *option; /* Current option */
+ ppd_group_t *subgroup; /* Current sub-group */
+
+
+ if (group->num_options > 0)
+ {
+ for (i = group->num_options, option = group->options;
+ i > 0;
+ i --, option ++)
+ ppd_free_option(option);
+
+ safe_free(group->options);
+ }
+
+ if (group->num_subgroups > 0)
+ {
+ for (i = group->num_subgroups, subgroup = group->subgroups;
+ i > 0;
+ i --, subgroup ++)
+ ppd_free_group(subgroup);
+
+ safe_free(group->subgroups);
+ }
+}
+
+
+/*
+ * 'ppd_free_option()' - Free a single option.
+ */
+
+static void
+ppd_free_option(ppd_option_t *option) /* I - Option to free */
+{
+ int i; /* Looping var */
+ ppd_choice_t *choice; /* Current choice */
+
+
+ if (option->num_choices > 0)
+ {
+ for (i = option->num_choices, choice = option->choices;
+ i > 0;
+ i --, choice ++)
+ safe_free(choice->code);
+
+ safe_free(option->choices);
+ }
+}
+
+
+/*
+ * 'ppd_get_group()' - Find or create the named group as needed.
+ */
+
+static ppd_group_t * /* O - Named group */
+ppd_get_group(ppd_file_t *ppd, /* I - PPD file */
+ char *name) /* I - Name of group */
+{
+ int i; /* Looping var */
+ ppd_group_t *group; /* Group */
+
+
+ DEBUG_printf(("ppd_get_group(%p, \"%s\")\n", ppd, name));
+
+ for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
+ if (strcmp(group->text, name) == 0)
+ break;
+
+ if (i == 0)
+ {
+ DEBUG_printf(("Adding group %s...\n", name));
+
+ if (ppd->num_groups == 0)
+ group = malloc(sizeof(ppd_group_t));
+ else
+ group = realloc(ppd->groups,
+ (ppd->num_groups + 1) * sizeof(ppd_group_t));
+
+ if (group == NULL)
+ return (NULL);
+
+ ppd->groups = group;
+ group += ppd->num_groups;
+ ppd->num_groups ++;
+
+ memset(group, 0, sizeof(ppd_group_t));
+ strlcpy(group->text, name, sizeof(group->text));
+ }
+
+ return (group);
+}
+
+
+/*
+ * 'ppd_get_option()' - Find or create the named option as needed.
+ */
+
+static ppd_option_t * /* O - Named option */
+ppd_get_option(ppd_group_t *group, /* I - Group */
+ char *name) /* I - Name of option */
+{
+ int i; /* Looping var */
+ ppd_option_t *option; /* Option */
+
+
+ for (i = group->num_options, option = group->options; i > 0; i --, option ++)
+ if (strcmp(option->keyword, name) == 0)
+ break;
+
+ if (i == 0)
+ {
+ if (group->num_options == 0)
+ option = malloc(sizeof(ppd_option_t));
+ else
+ option = realloc(group->options,
+ (group->num_options + 1) * sizeof(ppd_option_t));
+
+ if (option == NULL)
+ return (NULL);
+
+ group->options = option;
+ option += group->num_options;
+ group->num_options ++;
+
+ memset(option, 0, sizeof(ppd_option_t));
+ strlcpy(option->keyword, name, sizeof(option->keyword));
+ }
+
+ return (option);
+}
+
+
+/*
+ * 'ppd_add_choice()' - Add a choice to an option.
+ */
+
+static ppd_choice_t * /* O - Named choice */
+ppd_add_choice(ppd_option_t *option, /* I - Option */
+ char *name) /* I - Name of choice */
+{
+ ppd_choice_t *choice; /* Choice */
+
+
+ if (option->num_choices == 0)
+ choice = malloc(sizeof(ppd_choice_t));
+ else
+ choice = realloc(option->choices,
+ sizeof(ppd_choice_t) * (option->num_choices + 1));
+
+ if (choice == NULL)
+ return (NULL);
+
+ option->choices = choice;
+ choice += option->num_choices;
+ option->num_choices ++;
+
+ memset(choice, 0, sizeof(ppd_choice_t));
+ strlcpy(choice->choice, name, sizeof(choice->choice));
+
+ return (choice);
+}
+
+
+/*
+ * 'ppd_add_size()' - Add a page size.
+ */
+
+static ppd_size_t * /* O - Named size */
+ppd_add_size(ppd_file_t *ppd, /* I - PPD file */
+ char *name) /* I - Name of size */
+{
+ ppd_size_t *size; /* Size */
+
+
+ if (ppd->num_sizes == 0)
+ size = malloc(sizeof(ppd_size_t));
+ else
+ size = realloc(ppd->sizes, sizeof(ppd_size_t) * (ppd->num_sizes + 1));
+
+ if (size == NULL)
+ return (NULL);
+
+ ppd->sizes = size;
+ size += ppd->num_sizes;
+ ppd->num_sizes ++;
+
+ memset(size, 0, sizeof(ppd_size_t));
+ strlcpy(size->name, name, sizeof(size->name));
+
+ return (size);
+}
+
+
+/*
+ * 'ppdOpen()' - Read a PPD file into memory.
+ */
+
+ppd_file_t * /* O - PPD file record */
+ppdOpen(FILE *fp) /* I - File to read from */
+{
+ int i, j, k, m; /* Looping vars */
+ int count; /* Temporary count */
+ ppd_file_t *ppd; /* PPD file record */
+ ppd_group_t *group, /* Current group */
+ *subgroup; /* Current sub-group */
+ ppd_option_t *option; /* Current option */
+ ppd_choice_t *choice; /* Current choice */
+ ppd_const_t *constraint; /* Current constraint */
+ ppd_size_t *size; /* Current page size */
+ int mask; /* Line data mask */
+ char keyword[PPD_MAX_NAME],
+ /* Keyword from file */
+ name[PPD_MAX_NAME],
+ /* Option from file */
+ text[PPD_MAX_LINE],
+ /* Human-readable text from file */
+ *string, /* Code/text from file */
+ *sptr, /* Pointer into string */
+ *nameptr, /* Pointer into name */
+ *temp, /* Temporary string pointer */
+ **tempfonts; /* Temporary fonts pointer */
+ float order; /* Order dependency number */
+ ppd_section_t section; /* Order dependency section */
+ ppd_profile_t *profile; /* Pointer to color profile */
+ char **filter; /* Pointer to filter */
+ cups_lang_t *language; /* Default language */
+
+
+ /*
+ * Get the default language for the user...
+ */
+
+ language = cupsLangDefault();
+
+ /*
+ * Range check input...
+ */
+
+ if (fp == NULL)
+ return (NULL);
+
+ /*
+ * Grab the first line and make sure it reads '*PPD-Adobe: "major.minor"'...
+ */
+
+ mask = ppd_read(fp, keyword, name, text, &string);
+
+ if (mask == 0 ||
+ strcmp(keyword, "PPD-Adobe") != 0 ||
+ string == NULL || string[0] != '4')
+ {
+ /*
+ * Either this is not a PPD file, or it is not a 4.x PPD file.
+ */
+
+ safe_free(string);
+
+ return (NULL);
+ }
+
+ DEBUG_printf(("ppdOpen: keyword = %s, string = %p\n", keyword, string));
+
+ safe_free(string);
+
+ /*
+ * Allocate memory for the PPD file record...
+ */
+
+ if ((ppd = calloc(sizeof(ppd_file_t), 1)) == NULL)
+ return (NULL);
+
+ ppd->language_level = 1;
+ ppd->color_device = 0;
+ ppd->colorspace = PPD_CS_GRAY;
+ ppd->landscape = -90;
+
+ /*
+ * Read lines from the PPD file and add them to the file record...
+ */
+
+ group = NULL;
+ subgroup = NULL;
+ option = NULL;
+ choice = NULL;
+
+ while ((mask = ppd_read(fp, keyword, name, text, &string)) != 0)
+ {
+#ifdef DEBUG
+ printf("mask = %x, keyword = \"%s\"", mask, keyword);
+
+ if (name[0] != '\0')
+ printf(", name = \"%s\"", name);
+
+ if (text[0] != '\0')
+ printf(", text = \"%s\"", text);
+
+ if (string != NULL)
+ {
+ if (strlen(string) > 40)
+ printf(", string = %p", string);
+ else
+ printf(", string = \"%s\"", string);
+ }
+
+ puts("");
+#endif /* DEBUG */
+
+ if (strcmp(keyword, "CloseUI") != 0 &&
+ strcmp(keyword, "JCLCloseUI") != 0 &&
+ strcmp(keyword, "CloseGroup") != 0 &&
+ strcmp(keyword, "CloseSubGroup") != 0 &&
+ strncmp(keyword, "Default", 7) != 0 &&
+ string == NULL)
+ {
+ /*
+ * Need a string value!
+ */
+
+ ppdClose(ppd);
+ return (NULL);
+ }
+
+ if (strcmp(keyword, "LanguageLevel") == 0)
+ ppd->language_level = atoi(string);
+ else if (strcmp(keyword, "LanguageEncoding") == 0)
+ {
+ ppd->lang_encoding = string;
+ string = NULL; /* Don't free this string below */
+ }
+ else if (strcmp(keyword, "LanguageVersion") == 0)
+ {
+ ppd->lang_version = string;
+ string = NULL; /* Don't free this string below */
+ }
+ else if (strcmp(keyword, "Manufacturer") == 0)
+ {
+ ppd->manufacturer = string;
+ string = NULL; /* Don't free this string below */
+ }
+ else if (strcmp(keyword, "ModelName") == 0)
+ {
+ ppd->modelname = string;
+ string = NULL; /* Don't free this string below */
+ }
+ else if (strcmp(keyword, "NickName") == 0)
+ {
+ ppd->nickname = string;
+ string = NULL; /* Don't free this string below */
+ }
+ else if (strcmp(keyword, "Product") == 0)
+ {
+ ppd->product = string;
+ string = NULL; /* Don't free this string below */
+ }
+ else if (strcmp(keyword, "ShortNickName") == 0)
+ {
+ ppd->shortnickname = string;
+ string = NULL; /* Don't free this string below */
+ }
+ else if (strcmp(keyword, "TTRasterizer") == 0)
+ {
+ ppd->ttrasterizer = string;
+ string = NULL; /* Don't free this string below */
+ }
+ else if (strcmp(keyword, "JCLBegin") == 0)
+ {
+ ppd_decode(string); /* Decode quoted string */
+ ppd->jcl_begin = string;
+ string = NULL; /* Don't free this string below */
+ }
+ else if (strcmp(keyword, "JCLEnd") == 0)
+ {
+ ppd_decode(string); /* Decode quoted string */
+ ppd->jcl_end = string;
+ string = NULL; /* Don't free this string below */
+ }
+ else if (strcmp(keyword, "JCLToPSInterpreter") == 0)
+ {
+ ppd_decode(string); /* Decode quoted string */
+ ppd->jcl_ps = string;
+ string = NULL; /* Don't free this string below */
+ }
+ else if (strcmp(keyword, "AccurateScreensSupport") == 0)
+ ppd->accurate_screens = strcmp(string, "True") == 0;
+ else if (strcmp(keyword, "ColorDevice") == 0)
+ ppd->color_device = strcmp(string, "True") == 0;
+ else if (strcmp(keyword, "ContoneOnly") == 0)
+ ppd->contone_only = strcmp(string, "True") == 0;
+ else if (strcmp(keyword, "DefaultColorSpace") == 0)
+ {
+ if (strcmp(string, "CMY") == 0)
+ ppd->colorspace = PPD_CS_CMY;
+ else if (strcmp(string, "CMYK") == 0)
+ ppd->colorspace = PPD_CS_CMYK;
+ else if (strcmp(string, "RGB") == 0)
+ ppd->colorspace = PPD_CS_RGB;
+ else if (strcmp(string, "RGBK") == 0)
+ ppd->colorspace = PPD_CS_RGBK;
+ else if (strcmp(string, "N") == 0)
+ ppd->colorspace = PPD_CS_N;
+ else
+ ppd->colorspace = PPD_CS_GRAY;
+ }
+ else if (strcmp(keyword, "cupsFlipDuplex") == 0)
+ ppd->flip_duplex = strcmp(string, "True") == 0;
+ else if (strcmp(keyword, "cupsManualCopies") == 0)
+ ppd->manual_copies = strcmp(string, "True") == 0;
+ else if (strcmp(keyword, "cupsModelNumber") == 0)
+ ppd->model_number = atoi(string);
+ else if (strcmp(keyword, "cupsColorProfile") == 0)
+ {
+ if (ppd->num_profiles == 0)
+ profile = malloc(sizeof(ppd_profile_t));
+ else
+ profile = realloc(ppd->profiles, sizeof(ppd_profile_t) *
+ (ppd->num_profiles + 1));
+
+ ppd->profiles = profile;
+ profile += ppd->num_profiles;
+ ppd->num_profiles ++;
+
+ memset(profile, 0, sizeof(ppd_profile_t));
+ strlcpy(profile->resolution, name, sizeof(profile->resolution));
+ strlcpy(profile->media_type, text, sizeof(profile->media_type));
+ sscanf(string, "%f%f%f%f%f%f%f%f%f%f%f", &(profile->density),
+ &(profile->gamma),
+ profile->matrix[0] + 0, profile->matrix[0] + 1,
+ profile->matrix[0] + 2, profile->matrix[1] + 0,
+ profile->matrix[1] + 1, profile->matrix[1] + 2,
+ profile->matrix[2] + 0, profile->matrix[2] + 1,
+ profile->matrix[2] + 2);
+ }
+ else if (strcmp(keyword, "cupsFilter") == 0)
+ {
+ if (ppd->num_filters == 0)
+ filter = malloc(sizeof(char *));
+ else
+ filter = realloc(ppd->filters, sizeof(char *) * (ppd->num_filters + 1));
+
+ if (filter == NULL)
+ {
+ safe_free(filter);
+ ppdClose(ppd);
+ return (NULL);
+ }
+
+ ppd->filters = filter;
+ filter += ppd->num_filters;
+ ppd->num_filters ++;
+
+ /*
+ * Copy filter string and prevent it from being freed below...
+ */
+
+ *filter = string;
+ string = NULL;
+ }
+ else if (strcmp(keyword, "Throughput") == 0)
+ ppd->throughput = atoi(string);
+ else if (strcmp(keyword, "Font") == 0)
+ {
+ /*
+ * Add this font to the list of available fonts...
+ */
+
+ if (ppd->num_fonts == 0)
+ tempfonts = (char **)malloc(sizeof(char *));
+ else
+ tempfonts = (char **)realloc(ppd->fonts,
+ sizeof(char *) * (ppd->num_fonts + 1));
+
+ if (tempfonts == NULL)
+ {
+ safe_free(string);
+ ppdClose(ppd);
+ return (NULL);
+ }
+
+ ppd->fonts = tempfonts;
+ ppd->fonts[ppd->num_fonts] = strdup(name);
+ ppd->num_fonts ++;
+ }
+ else if (strcmp(keyword, "VariablePaperSize") == 0 &&
+ strcmp(string, "True") == 0 &&
+ !ppd->variable_sizes)
+ {
+ ppd->variable_sizes = 1;
+
+ /*
+ * Add a "Custom" page size entry...
+ */
+
+ ppd_add_size(ppd, "Custom");
+
+ /*
+ * Add a "Custom" page size option...
+ */
+
+ if ((option = ppdFindOption(ppd, "PageSize")) == NULL)
+ {
+ ppd_group_t *temp;
+
+
+ if ((temp = ppd_get_group(ppd,
+ cupsLangString(language,
+ CUPS_MSG_GENERAL))) == NULL)
+ {
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ if ((option = ppd_get_option(temp, "PageSize")) == NULL)
+ {
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+ }
+
+ if ((choice = ppd_add_choice(option, "Custom")) == NULL)
+ {
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ strlcpy(choice->text, cupsLangString(language, CUPS_MSG_VARIABLE),
+ sizeof(choice->text));
+ option = NULL;
+ }
+ else if (strcmp(keyword, "MaxMediaWidth") == 0)
+ ppd->custom_max[0] = (float)atof(string);
+ else if (strcmp(keyword, "MaxMediaHeight") == 0)
+ ppd->custom_max[1] = (float)atof(string);
+ else if (strcmp(keyword, "ParamCustomPageSize") == 0)
+ {
+ if (strcmp(name, "Width") == 0)
+ sscanf(string, "%*s%*s%f%f", ppd->custom_min + 0,
+ ppd->custom_max + 0);
+ else if (strcmp(name, "Height") == 0)
+ sscanf(string, "%*s%*s%f%f", ppd->custom_min + 1,
+ ppd->custom_max + 1);
+ }
+ else if (strcmp(keyword, "HWMargins") == 0)
+ sscanf(string, "%f%f%f%f", ppd->custom_margins + 0,
+ ppd->custom_margins + 1, ppd->custom_margins + 2,
+ ppd->custom_margins + 3);
+ else if (strcmp(keyword, "CustomPageSize") == 0 &&
+ strcmp(name, "True") == 0)
+ {
+ if (!ppd->variable_sizes)
+ {
+ ppd->variable_sizes = 1;
+
+ /*
+ * Add a "Custom" page size entry...
+ */
+
+ ppd_add_size(ppd, "Custom");
+
+ /*
+ * Add a "Custom" page size option...
+ */
+
+ if ((option = ppdFindOption(ppd, "PageSize")) == NULL)
+ {
+ ppd_group_t *temp;
+
+
+ if ((temp = ppd_get_group(ppd,
+ cupsLangString(language,
+ CUPS_MSG_GENERAL))) == NULL)
+ {
+ DEBUG_puts("Unable to get general group!");
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ if ((option = ppd_get_option(temp, "PageSize")) == NULL)
+ {
+ DEBUG_puts("Unable to get PageSize option!");
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+ }
+
+ if ((choice = ppd_add_choice(option, "Custom")) == NULL)
+ {
+ DEBUG_puts("Unable to add Custom choice!");
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ strlcpy(choice->text, cupsLangString(language, CUPS_MSG_VARIABLE),
+ sizeof(choice->text));
+ option = NULL;
+ }
+
+ if ((option = ppdFindOption(ppd, "PageSize")) == NULL)
+ {
+ DEBUG_puts("Unable to find PageSize option!");
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ if ((choice = ppdFindChoice(option, "Custom")) == NULL)
+ {
+ DEBUG_puts("Unable to find Custom choice!");
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ choice->code = string;
+ string = NULL;
+ option = NULL;
+ }
+ else if (strcmp(keyword, "LandscapeOrientation") == 0)
+ {
+ if (strcmp(string, "Minus90") == 0)
+ ppd->landscape = -90;
+ else if (strcmp(string, "Plus90") == 0)
+ ppd->landscape = 90;
+ }
+ else if (strcmp(keyword, "Emulators") == 0)
+ {
+ for (count = 1, sptr = string; sptr != NULL;)
+ if ((sptr = strchr(sptr, ' ')) != NULL)
+ {
+ count ++;
+ while (*sptr == ' ')
+ sptr ++;
+ }
+
+ ppd->num_emulations = count;
+ ppd->emulations = calloc(sizeof(ppd_emul_t), count);
+
+ for (i = 0, sptr = string; i < count; i ++)
+ {
+ for (nameptr = ppd->emulations[i].name;
+ *sptr != '\0' && *sptr != ' ';
+ sptr ++)
+ if (nameptr < (ppd->emulations[i].name + sizeof(ppd->emulations[i].name) - 1))
+ *nameptr++ = *sptr;
+
+ *nameptr = '\0';
+
+ while (*sptr == ' ')
+ sptr ++;
+ }
+ }
+ else if (strncmp(keyword, "StartEmulator_", 14) == 0)
+ {
+ ppd_decode(string);
+
+ for (i = 0; i < ppd->num_emulations; i ++)
+ if (strcmp(keyword + 14, ppd->emulations[i].name) == 0)
+ {
+ ppd->emulations[i].start = string;
+ string = NULL;
+ }
+ }
+ else if (strncmp(keyword, "StopEmulator_", 13) == 0)
+ {
+ ppd_decode(string);
+
+ for (i = 0; i < ppd->num_emulations; i ++)
+ if (strcmp(keyword + 13, ppd->emulations[i].name) == 0)
+ {
+ ppd->emulations[i].stop = string;
+ string = NULL;
+ }
+ }
+ else if (strcmp(keyword, "JobPatchFile") == 0)
+ {
+ if (ppd->patches == NULL)
+ {
+ ppd->patches = string;
+ string = NULL;
+ }
+ else
+ {
+ temp = realloc(ppd->patches, strlen(ppd->patches) +
+ strlen(string) + 1);
+ if (temp == NULL)
+ {
+ safe_free(string);
+ ppdClose(ppd);
+ return (NULL);
+ }
+
+ ppd->patches = temp;
+
+ strcpy(ppd->patches + strlen(ppd->patches), string);
+ }
+ }
+ else if (strcmp(keyword, "OpenUI") == 0)
+ {
+ /*
+ * Add an option record to the current sub-group, group, or file...
+ */
+
+ if (name[0] == '*')
+ strcpy(name, name + 1); /* Eliminate leading asterisk */
+
+ for (i = strlen(name) - 1; i > 0 && isspace(name[i]); i --)
+ name[i] = '\0'; /* Eliminate trailing spaces */
+
+ DEBUG_printf(("OpenUI of %s in group %s...\n", name,
+ group ? group->text : "(null)"));
+
+ if (subgroup != NULL)
+ option = ppd_get_option(subgroup, name);
+ else if (group == NULL)
+ {
+ if (strcmp(name, "Collate") != 0 &&
+ strcmp(name, "Duplex") != 0 &&
+ strcmp(name, "InputSlot") != 0 &&
+ strcmp(name, "ManualFeed") != 0 &&
+ strcmp(name, "MediaType") != 0 &&
+ strcmp(name, "MediaColor") != 0 &&
+ strcmp(name, "MediaWeight") != 0 &&
+ strcmp(name, "OutputBin") != 0 &&
+ strcmp(name, "OutputMode") != 0 &&
+ strcmp(name, "OutputOrder") != 0 &&
+ strcmp(name, "PageSize") != 0 &&
+ strcmp(name, "PageRegion") != 0)
+ group = ppd_get_group(ppd, cupsLangString(language, CUPS_MSG_EXTRA));
+ else
+ group = ppd_get_group(ppd, cupsLangString(language, CUPS_MSG_GENERAL));
+
+ if (group == NULL)
+ {
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ DEBUG_printf(("Adding to group %s...\n", group->text));
+ option = ppd_get_option(group, name);
+ group = NULL;
+ }
+ else
+ option = ppd_get_option(group, name);
+
+ if (option == NULL)
+ {
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ /*
+ * Now fill in the initial information for the option...
+ */
+
+ if (strcmp(string, "PickMany") == 0)
+ option->ui = PPD_UI_PICKMANY;
+ else if (strcmp(string, "Boolean") == 0)
+ option->ui = PPD_UI_BOOLEAN;
+ else
+ option->ui = PPD_UI_PICKONE;
+
+ if (text[0])
+ {
+ strlcpy(option->text, text, sizeof(option->text));
+ ppd_fix(option->text);
+ }
+ else
+ {
+ if (strcmp(name, "PageSize") == 0)
+ strlcpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_SIZE),
+ sizeof(option->text));
+ else if (strcmp(name, "MediaType") == 0)
+ strlcpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_TYPE),
+ sizeof(option->text));
+ else if (strcmp(name, "InputSlot") == 0)
+ strlcpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_SOURCE),
+ sizeof(option->text));
+ else if (strcmp(name, "ColorModel") == 0)
+ strlcpy(option->text, cupsLangString(language, CUPS_MSG_OUTPUT_MODE),
+ sizeof(option->text));
+ else if (strcmp(name, "Resolution") == 0)
+ strlcpy(option->text, cupsLangString(language, CUPS_MSG_RESOLUTION),
+ sizeof(option->text));
+ else
+ strlcpy(option->text, name, sizeof(option->text));
+ }
+
+ option->section = PPD_ORDER_ANY;
+ }
+ else if (strcmp(keyword, "JCLOpenUI") == 0)
+ {
+ /*
+ * Find the JCL group, and add if needed...
+ */
+
+ group = ppd_get_group(ppd, "JCL");
+
+ if (group == NULL)
+ {
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ /*
+ * Add an option record to the current JCLs...
+ */
+
+ if (name[0] == '*')
+ strcpy(name, name + 1);
+
+ option = ppd_get_option(group, name);
+
+ if (option == NULL)
+ {
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ /*
+ * Now fill in the initial information for the option...
+ */
+
+ if (strcmp(string, "PickMany") == 0)
+ option->ui = PPD_UI_PICKMANY;
+ else if (strcmp(string, "Boolean") == 0)
+ option->ui = PPD_UI_BOOLEAN;
+ else
+ option->ui = PPD_UI_PICKONE;
+
+ strlcpy(option->text, text, sizeof(option->text));
+
+ option->section = PPD_ORDER_JCL;
+ group = NULL;
+ }
+ else if (strcmp(keyword, "CloseUI") == 0 ||
+ strcmp(keyword, "JCLCloseUI") == 0)
+ option = NULL;
+ else if (strcmp(keyword, "OpenGroup") == 0)
+ {
+ /*
+ * Open a new group...
+ */
+
+ if (group != NULL)
+ {
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ if (strncasecmp(string, "InstallableOptions", 18) == 0)
+ {
+ /*
+ * Handle the InstallableOptions group differently than other
+ * groups; this is necessary so that UIs can correctly
+ * isolate them from normal user options.
+ *
+ * In CUPS 1.2 we have separate text and keyword fields,
+ * so this "hack" won't be needed...
+ */
+
+ group = ppd_get_group(ppd, "InstallableOptions");
+ }
+ else
+ {
+ /*
+ * For all other groups, just use the human readable text...
+ */
+
+ if (strchr(string, '/') != NULL)
+ strcpy(string, strchr(string, '/') + 1);
+
+ ppd_decode(string);
+ ppd_fix(string);
+
+ group = ppd_get_group(ppd, string);
+ }
+ }
+ else if (strcmp(keyword, "CloseGroup") == 0)
+ group = NULL;
+ else if (strcmp(keyword, "OrderDependency") == 0 ||
+ strcmp(keyword, "NonUIOrderDependency") == 0)
+ {
+ if (sscanf(string, "%f%40s%40s", &order, name, keyword) != 3)
+ {
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ if (keyword[0] == '*')
+ strcpy(keyword, keyword + 1);
+
+ if (strcmp(name, "ExitServer") == 0)
+ section = PPD_ORDER_EXIT;
+ else if (strcmp(name, "Prolog") == 0)
+ section = PPD_ORDER_PROLOG;
+ else if (strcmp(name, "DocumentSetup") == 0)
+ section = PPD_ORDER_DOCUMENT;
+ else if (strcmp(name, "PageSetup") == 0)
+ section = PPD_ORDER_PAGE;
+ else if (strcmp(name, "JCLSetup") == 0)
+ section = PPD_ORDER_JCL;
+ else
+ section = PPD_ORDER_ANY;
+
+ if (option == NULL)
+ {
+ ppd_group_t *temp;
+
+
+ /*
+ * Only valid for Non-UI options...
+ */
+
+ for (i = ppd->num_groups, temp = ppd->groups; i > 0; i --, temp ++)
+ if (temp->text[0] == '\0')
+ break;
+
+ if (i > 0)
+ for (i = 0; i < temp->num_options; i ++)
+ if (strcmp(keyword, temp->options[i].keyword) == 0)
+ {
+ temp->options[i].section = section;
+ temp->options[i].order = order;
+ break;
+ }
+ }
+ else
+ {
+ option->section = section;
+ option->order = order;
+ }
+ }
+ else if (strncmp(keyword, "Default", 7) == 0)
+ {
+ if (string == NULL)
+ continue;
+
+ if (strchr(string, '/') != NULL)
+ *strchr(string, '/') = '\0';
+
+ if (option == NULL)
+ {
+ ppd_group_t *temp;
+
+
+ /*
+ * Only valid for Non-UI options...
+ */
+
+ for (i = ppd->num_groups, temp = ppd->groups; i > 0; i --, temp ++)
+ if (temp->text[0] == '\0')
+ break;
+
+ if (i > 0)
+ for (i = 0; i < temp->num_options; i ++)
+ if (strcmp(keyword, temp->options[i].keyword) == 0)
+ {
+ strlcpy(temp->options[i].defchoice, string,
+ sizeof(temp->options[i].defchoice));
+ break;
+ }
+ }
+ else if (strcmp(keyword + 7, option->keyword) == 0)
+ strlcpy(option->defchoice, string, sizeof(option->defchoice));
+ }
+ else if (strcmp(keyword, "UIConstraints") == 0 ||
+ strcmp(keyword, "NonUIConstraints") == 0)
+ {
+ if (ppd->num_consts == 0)
+ constraint = calloc(sizeof(ppd_const_t), 1);
+ else
+ constraint = realloc(ppd->consts,
+ (ppd->num_consts + 1) * sizeof(ppd_const_t));
+
+ if (constraint == NULL)
+ {
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ ppd->consts = constraint;
+ constraint += ppd->num_consts;
+ ppd->num_consts ++;
+
+ switch (sscanf(string, "%40s%40s%40s%40s", constraint->option1,
+ constraint->choice1, constraint->option2,
+ constraint->choice2))
+ {
+ case 0 : /* Error */
+ case 1 : /* Error */
+ ppdClose(ppd);
+ safe_free(string);
+ break;
+
+ case 2 : /* Two options... */
+ /*
+ * The following strcpy's are safe, as optionN and
+ * choiceN are all the same size (size defined by PPD spec...)
+ */
+
+ if (constraint->option1[0] == '*')
+ strcpy(constraint->option1, constraint->option1 + 1);
+
+ if (constraint->choice1[0] == '*')
+ strcpy(constraint->option2, constraint->choice1 + 1);
+ else
+ strcpy(constraint->option2, constraint->choice1);
+
+ constraint->choice1[0] = '\0';
+ constraint->choice2[0] = '\0';
+ break;
+
+ case 3 : /* Two options, one choice... */
+ /*
+ * The following strcpy's are safe, as optionN and
+ * choiceN are all the same size (size defined by PPD spec...)
+ */
+
+ if (constraint->option1[0] == '*')
+ strcpy(constraint->option1, constraint->option1 + 1);
+
+ if (constraint->choice1[0] == '*')
+ {
+ strcpy(constraint->choice2, constraint->option2);
+ strcpy(constraint->option2, constraint->choice1 + 1);
+ constraint->choice1[0] = '\0';
+ }
+ else
+ {
+ if (constraint->option2[0] == '*')
+ strcpy(constraint->option2, constraint->option2 + 1);
+
+ constraint->choice2[0] = '\0';
+ }
+ break;
+
+ case 4 : /* Two options, two choices... */
+ if (constraint->option1[0] == '*')
+ strcpy(constraint->option1, constraint->option1 + 1);
+
+ if (constraint->option2[0] == '*')
+ strcpy(constraint->option2, constraint->option2 + 1);
+ break;
+ }
+ }
+ else if (strcmp(keyword, "PaperDimension") == 0)
+ {
+ if ((size = ppdPageSize(ppd, name)) == NULL)
+ size = ppd_add_size(ppd, name);
+
+ if (size == NULL)
+ {
+ /*
+ * Unable to add or find size!
+ */
+
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ sscanf(string, "%f%f", &(size->width), &(size->length));
+ }
+ else if (strcmp(keyword, "ImageableArea") == 0)
+ {
+ if ((size = ppdPageSize(ppd, name)) == NULL)
+ size = ppd_add_size(ppd, name);
+
+ if (size == NULL)
+ {
+ /*
+ * Unable to add or find size!
+ */
+
+ ppdClose(ppd);
+ safe_free(string);
+ return (NULL);
+ }
+
+ sscanf(string, "%f%f%f%f", &(size->left), &(size->bottom),
+ &(size->right), &(size->top));
+ }
+ else if (option != NULL &&
+ (mask & (PPD_KEYWORD | PPD_OPTION | PPD_STRING)) ==
+ (PPD_KEYWORD | PPD_OPTION | PPD_STRING) &&
+ strcmp(keyword, option->keyword) == 0)
+ {
+ DEBUG_printf(("group = %p, subgroup = %p\n", group, subgroup));
+
+ if (strcmp(keyword, "PageSize") == 0)
+ {
+ /*
+ * Add a page size...
+ */
+
+ if (ppdPageSize(ppd, name) == NULL)
+ ppd_add_size(ppd, name);
+ }
+
+ /*
+ * Add the option choice...
+ */
+
+ choice = ppd_add_choice(option, name);
+
+ if (mask & PPD_TEXT)
+ {
+ strlcpy(choice->text, text, sizeof(choice->text));
+ ppd_fix(choice->text);
+ }
+ else if (strcmp(name, "True") == 0)
+ strcpy(choice->text, "Yes");
+ else if (strcmp(name, "False") == 0)
+ strcpy(choice->text, "No");
+ else
+ strlcpy(choice->text, name, sizeof(choice->text));
+
+ if (option->section == PPD_ORDER_JCL)
+ ppd_decode(string); /* Decode quoted string */
+
+ choice->code = string;
+ string = NULL; /* Don't free this string below */
+ }
+
+ safe_free(string);
+ }
+
+#ifdef DEBUG
+ if (!feof(fp))
+ printf("Premature EOF at %lu...\n", (unsigned long)ftell(fp));
+#endif /* DEBUG */
+
+#ifndef __APPLE__
+ /*
+ * Make sure that all PPD files with an InputSlot option have an
+ * "auto" choice that maps to no specific tray or media type.
+ */
+
+ if ((option = ppdFindOption(ppd, "InputSlot")) != NULL)
+ {
+ for (i = 0; i < option->num_choices; i ++)
+ if (option->choices[i].code == NULL || !option->choices[i].code[0])
+ break;
+
+ if (i >= option->num_choices)
+ {
+ /*
+ * No "auto" input slot, add one...
+ */
+
+ choice = ppd_add_choice(option, "Auto");
+
+ strlcpy(choice->text, cupsLangString(language, CUPS_MSG_AUTO),
+ sizeof(choice->text));
+ choice->code = NULL;
+ }
+ }
+#endif /* !__APPLE__ */
+
+ /*
+ * Set the option back-pointer for each choice...
+ */
+
+#ifndef __APPLE__
+ qsort(ppd->groups, ppd->num_groups, sizeof(ppd_group_t),
+ (int (*)(const void *, const void *))compare_groups);
+#endif /* !__APPLE__ */
+
+ for (i = ppd->num_groups, group = ppd->groups;
+ i > 0;
+ i --, group ++)
+ {
+#ifndef __APPLE__
+ qsort(group->options, group->num_options, sizeof(ppd_option_t),
+ (int (*)(const void *, const void *))compare_options);
+#endif /* !__APPLE__ */
+
+ for (j = group->num_options, option = group->options;
+ j > 0;
+ j --, option ++)
+ {
+ for (k = 0; k < option->num_choices; k ++)
+ option->choices[k].option = (void *)option;
+ }
+
+#ifndef __APPLE__
+ qsort(group->subgroups, group->num_subgroups, sizeof(ppd_group_t),
+ (int (*)(const void *, const void *))compare_groups);
+#endif /* !__APPLE__ */
+
+ for (j = group->num_subgroups, subgroup = group->subgroups;
+ j > 0;
+ j --, subgroup ++)
+ {
+#ifndef __APPLE__
+ qsort(subgroup->options, subgroup->num_options, sizeof(ppd_option_t),
+ (int (*)(const void *, const void *))compare_options);
+#endif /* !__APPLE__ */
+
+ for (k = group->num_options, option = group->options;
+ k > 0;
+ k --, option ++)
+ {
+ for (m = 0; m < option->num_choices; m ++)
+ option->choices[m].option = (void *)option;
+ }
+ }
+ }
+
+ return (ppd);
+}
+
+
+/*
+ * 'ppdOpenFd()' - Read a PPD file into memory.
+ */
+
+ppd_file_t * /* O - PPD file record */
+ppdOpenFd(int fd) /* I - File to read from */
+{
+ FILE *fp; /* File pointer */
+ ppd_file_t *ppd; /* PPD file record */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (fd < 0)
+ return (NULL);
+
+ /*
+ * Try to open the file and parse it...
+ */
+
+ if ((fp = fdopen(fd, "r")) != NULL)
+ {
+ setbuf(fp, NULL);
+
+ ppd = ppdOpen(fp);
+
+ safe_free(fp);
+ }
+ else
+ ppd = NULL;
+
+ return (ppd);
+}
+
+
+/*
+ * 'ppdOpenFile()' - Read a PPD file into memory.
+ */
+
+ppd_file_t * /* O - PPD file record */
+ppdOpenFile(const char *filename) /* I - File to read from */
+{
+ FILE *fp; /* File pointer */
+ ppd_file_t *ppd; /* PPD file record */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (filename == NULL)
+ return (NULL);
+
+ /*
+ * Try to open the file and parse it...
+ */
+
+ if ((fp = fopen(filename, "r")) != NULL)
+ {
+ ppd = ppdOpen(fp);
+
+ fclose(fp);
+ }
+ else
+ ppd = NULL;
+
+ return (ppd);
+}
+
+
+#ifndef __APPLE__
+/*
+ * 'compare_strings()' - Compare two strings.
+ */
+
+static int /* O - Result of comparison */
+compare_strings(char *s, /* I - First string */
+ char *t) /* I - Second string */
+{
+ int diff, /* Difference between digits */
+ digits; /* Number of digits */
+
+
+ /*
+ * Loop through both strings, returning only when a difference is
+ * seen. Also, compare whole numbers rather than just characters, too!
+ */
+
+ while (*s && *t)
+ {
+ if (isdigit(*s) && isdigit(*t))
+ {
+ /*
+ * Got a number; start by skipping leading 0's...
+ */
+
+ while (*s == '0')
+ s ++;
+ while (*t == '0')
+ t ++;
+
+ /*
+ * Skip equal digits...
+ */
+
+ while (isdigit(*s) && *s == *t)
+ {
+ s ++;
+ t ++;
+ }
+
+ /*
+ * Bounce out if *s and *t aren't both digits...
+ */
+
+ if (isdigit(*s) && !isdigit(*t))
+ return (1);
+ else if (!isdigit(*s) && isdigit(*t))
+ return (-1);
+ else if (!isdigit(*s) || !isdigit(*t))
+ continue;
+
+ if (*s < *t)
+ diff = -1;
+ else
+ diff = 1;
+
+ /*
+ * Figure out how many more digits there are...
+ */
+
+ digits = 0;
+
+ while (isdigit(*s))
+ {
+ digits ++;
+ s ++;
+ }
+
+ while (isdigit(*t))
+ {
+ digits --;
+ t ++;
+ }
+
+ /*
+ * Return if the number or value of the digits is different...
+ */
+
+ if (digits < 0)
+ return (-1);
+ else if (digits > 0)
+ return (1);
+ else
+ return (diff);
+ }
+ else if (tolower(*s) < tolower(*t))
+ return (-1);
+ else if (tolower(*s) > tolower(*t))
+ return (1);
+ else
+ {
+ s ++;
+ t ++;
+ }
+ }
+
+ /*
+ * Return the results of the final comparison...
+ */
+
+ if (*s)
+ return (1);
+ else if (*t)
+ return (-1);
+ else
+ return (0);
+}
+
+
+/*
+ * 'compare_groups()' - Compare two groups.
+ */
+
+static int /* O - Result of comparison */
+compare_groups(ppd_group_t *g0, /* I - First group */
+ ppd_group_t *g1) /* I - Second group */
+{
+ return (compare_strings(g0->text, g1->text));
+}
+
+
+/*
+ * 'compare_options()' - Compare two options.
+ */
+
+static int /* O - Result of comparison */
+compare_options(ppd_option_t *o0,/* I - First option */
+ ppd_option_t *o1)/* I - Second option */
+{
+ return (compare_strings(o0->text, o1->text));
+}
+#endif /* !__APPLE__ */
+
+
+/*
+ * 'ppd_read()' - Read a line from a PPD file, skipping comment lines as
+ * necessary.
+ */
+
+static int /* O - Bitmask of fields read */
+ppd_read(FILE *fp, /* I - File to read from */
+ char *keyword, /* O - Keyword from line */
+ char *option, /* O - Option from line */
+ char *text, /* O - Human-readable text from line */
+ char **string) /* O - Code/string data */
+{
+ int ch, /* Character from file */
+ colon, /* Colon seen? */
+ endquote, /* Waiting for an end quote */
+ mask; /* Mask to be returned */
+ char *keyptr, /* Keyword pointer */
+ *optptr, /* Option pointer */
+ *textptr, /* Text pointer */
+ *strptr, /* Pointer into string */
+ *lineptr, /* Current position in line buffer */
+ line[65536]; /* Line buffer (64k) */
+
+
+ /*
+ * Range check everything...
+ */
+
+ if (fp == NULL || keyword == NULL || option == NULL || text == NULL ||
+ string == NULL)
+ return (0);
+
+ /*
+ * Now loop until we have a valid line...
+ */
+
+ *string = NULL;
+
+ do
+ {
+ /*
+ * Read the line...
+ */
+
+ lineptr = line;
+ endquote = 0;
+ colon = 0;
+
+ while ((ch = getc(fp)) != EOF &&
+ (lineptr - line) < (sizeof(line) - 1))
+ {
+ if (ch == '\r' || ch == '\n')
+ {
+ /*
+ * Line feed or carriage return...
+ */
+
+ if (lineptr == line) /* Skip blank lines */
+ continue;
+
+ if (ch == '\r')
+ {
+ /*
+ * Check for a trailing line feed...
+ */
+
+ if ((ch = getc(fp)) == EOF)
+ break;
+ if (ch != 0x0a)
+ ungetc(ch, fp);
+ }
+
+ ch = '\n';
+
+ if (!endquote) /* Continue for multi-line text */
+ break;
+
+ *lineptr++ = '\n';
+ }
+ else
+ {
+ /*
+ * Any other character...
+ */
+
+ *lineptr++ = ch;
+
+ if (ch == ':' && strncmp(line, "*%", 2) != 0)
+ colon = 1;
+
+ if (ch == '\"' && colon)
+ {
+ endquote = !endquote;
+
+ if (!endquote)
+ {
+ /*
+ * End of quoted string; ignore trailing characters...
+ */
+
+ while ((ch = getc(fp)) != EOF)
+ if (ch == '\n')
+ break;
+ else if (ch == '\r')
+ {
+ ch = getc(fp);
+ if (ch != '\n')
+ ungetc(ch, fp);
+
+ ch = '\n';
+ break;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ if (endquote)
+ {
+ /*
+ * Didn't finish this quoted string...
+ */
+
+ while ((ch = getc(fp)) != EOF)
+ if (ch == '\"')
+ break;
+ }
+
+ if (ch != '\n')
+ {
+ /*
+ * Didn't finish this line...
+ */
+
+ while ((ch = getc(fp)) != EOF)
+ if (ch == '\r' || ch == '\n')
+ {
+ /*
+ * Line feed or carriage return...
+ */
+
+ if (ch == '\r')
+ {
+ /*
+ * Check for a trailing line feed...
+ */
+
+ if ((ch = getc(fp)) == EOF)
+ break;
+ if (ch != 0x0a)
+ ungetc(ch, fp);
+ }
+
+ break;
+ }
+ }
+
+ if (lineptr > line && lineptr[-1] == '\n')
+ lineptr --;
+
+ *lineptr = '\0';
+
+/* DEBUG_printf(("LINE = \"%s\"\n", line));*/
+
+ if (ch == EOF && lineptr == line)
+ return (0);
+
+ /*
+ * Now parse it...
+ */
+
+ mask = 0;
+ lineptr = line + 1;
+
+ keyword[0] = '\0';
+ option[0] = '\0';
+ text[0] = '\0';
+ *string = NULL;
+
+ if (line[0] != '*') /* All lines start with an asterisk */
+ continue;
+
+ if (strcmp(line, "*") == 0 || /* (Bad) comment line */
+ strncmp(line, "*%", 2) == 0 || /* Comment line */
+ strncmp(line, "*?", 2) == 0 || /* Query line */
+ strcmp(line, "*End") == 0) /* End of multi-line string */
+ continue;
+
+ /*
+ * Get a keyword...
+ */
+
+ keyptr = keyword;
+
+ while (*lineptr != '\0' && *lineptr != ':' && !isspace(*lineptr))
+ if ((keyptr - keyword) < (PPD_MAX_NAME - 1))
+ *keyptr++ = *lineptr++;
+
+ *keyptr = '\0';
+
+ if (strcmp(keyword, "End") == 0)
+ continue;
+
+ mask |= PPD_KEYWORD;
+
+/* DEBUG_printf(("keyword = \"%s\", lineptr = \"%s\"\n", keyword, lineptr));*/
+
+ if (isspace(*lineptr))
+ {
+ /*
+ * Get an option name...
+ */
+
+ while (isspace(*lineptr))
+ lineptr ++;
+
+ optptr = option;
+
+ while (*lineptr != '\0' && *lineptr != '\n' && *lineptr != ':' &&
+ *lineptr != '/')
+ if ((optptr - option) < (PPD_MAX_NAME - 1))
+ *optptr++ = *lineptr++;
+
+ *optptr = '\0';
+ mask |= PPD_OPTION;
+
+/* DEBUG_printf(("option = \"%s\", lineptr = \"%s\"\n", option, lineptr));*/
+
+ if (*lineptr == '/')
+ {
+ /*
+ * Get human-readable text...
+ */
+
+ lineptr ++;
+
+ textptr = text;
+
+ while (*lineptr != '\0' && *lineptr != '\n' && *lineptr != ':')
+ if ((textptr - text) < (PPD_MAX_LINE - 1))
+ *textptr++ = *lineptr++;
+
+ *textptr = '\0';
+ ppd_decode(text);
+
+ mask |= PPD_TEXT;
+ }
+
+/* DEBUG_printf(("text = \"%s\", lineptr = \"%s\"\n", text, lineptr));*/
+ }
+
+ if (*lineptr == ':')
+ {
+ /*
+ * Get string...
+ */
+
+ *string = malloc(strlen(lineptr) + 1);
+
+ while (*lineptr == ':' || isspace(*lineptr))
+ lineptr ++;
+
+ strptr = *string;
+
+ while (*lineptr != '\0')
+ {
+ if (*lineptr != '\"')
+ *strptr++ = *lineptr++;
+ else
+ lineptr ++;
+ }
+
+ *strptr = '\0';
+
+/* DEBUG_printf(("string = \"%s\", lineptr = \"%s\"\n", *string, lineptr));*/
+
+ mask |= PPD_STRING;
+ }
+ }
+ while (mask == 0);
+
+ return (mask);
+}
+
+
+/*
+ * 'ppd_decode()' - Decode a string value...
+ */
+
+static void
+ppd_decode(char *string) /* I - String to decode */
+{
+ char *inptr, /* Input pointer */
+ *outptr; /* Output pointer */
+
+
+ inptr = string;
+ outptr = string;
+
+ while (*inptr != '\0')
+ if (*inptr == '<' && isxdigit(inptr[1]))
+ {
+ /*
+ * Convert hex to 8-bit values...
+ */
+
+ inptr ++;
+ while (isxdigit(*inptr))
+ {
+ if (isalpha(*inptr))
+ *outptr = (tolower(*inptr) - 'a' + 10) << 4;
+ else
+ *outptr = (*inptr - '0') << 4;
+
+ inptr ++;
+
+ if (isalpha(*inptr))
+ *outptr |= tolower(*inptr) - 'a' + 10;
+ else
+ *outptr |= *inptr - '0';
+
+ inptr ++;
+ outptr ++;
+ }
+
+ while (*inptr != '>' && *inptr != '\0')
+ inptr ++;
+ while (*inptr == '>')
+ inptr ++;
+ }
+ else
+ *outptr++ = *inptr++;
+
+ *outptr = '\0';
+}
+
+
+#ifndef __APPLE__
+/*
+ * 'ppd_fix()' - Fix WinANSI characters in the range 0x80 to 0x9f to be
+ * valid ISO-8859-1 characters...
+ */
+
+static void
+ppd_fix(char *string) /* IO - String to fix */
+{
+ unsigned char *p; /* Pointer into string */
+ static unsigned char lut[32] =/* Lookup table for characters */
+ {
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 'l',
+ '`',
+ '\'',
+ '^',
+ '~',
+ 0x20, /* bar */
+ 0x20, /* circumflex */
+ 0x20, /* dot */
+ 0x20, /* double dot */
+ 0x20,
+ 0x20, /* circle */
+ 0x20, /* ??? */
+ 0x20,
+ '\"', /* should be right quotes */
+ 0x20, /* ??? */
+ 0x20 /* accent */
+ };
+
+
+ for (p = (unsigned char *)string; *p; p ++)
+ if (*p >= 0x80 && *p < 0xa0)
+ *p = lut[*p - 0x80];
+}
+#endif /* !__APPLE__ */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/ppd.h b/cups/ppd.h
new file mode 100644
index 000000000..88d4aaca5
--- /dev/null
+++ b/cups/ppd.h
@@ -0,0 +1,270 @@
+/*
+ * "$Id$"
+ *
+ * PostScript Printer Description definitions for the Common UNIX Printing
+ * System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * PostScript is a trademark of Adobe Systems, Inc.
+ *
+ * This code and any derivative of it may be used and distributed
+ * freely under the terms of the GNU General Public License when
+ * used with GNU Ghostscript or its derivatives. Use of the code
+ * (or any derivative of it) with software other than GNU
+ * GhostScript (or its derivatives) is governed by the CUPS license
+ * agreement.
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _CUPS_PPD_H_
+# define _CUPS_PPD_H_
+
+/*
+ * Include necessary headers...
+ */
+
+# include <stdio.h>
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+
+/*
+ * PPD version...
+ */
+
+# define PPD_VERSION 4.3 /* Kept in sync with Adobe version number */
+
+
+/*
+ * PPD size limits (defined in Adobe spec)
+ */
+
+# define PPD_MAX_NAME 41 /* Maximum size of name + 1 for nul */
+# define PPD_MAX_TEXT 81 /* Maximum size of text + 1 for nul */
+# define PPD_MAX_LINE 256 /* Maximum size of line + 1 for nul */
+
+
+/*
+ * Types and structures...
+ */
+
+typedef enum /**** UI types ****/
+{
+ PPD_UI_BOOLEAN, /* True or False option */
+ PPD_UI_PICKONE, /* Pick one from a list */
+ PPD_UI_PICKMANY /* Pick zero or more from a list */
+} ppd_ui_t;
+
+typedef enum /**** Order dependency sections ****/
+{
+ PPD_ORDER_ANY, /* Option code can be anywhere in the file */
+ PPD_ORDER_DOCUMENT, /* ... must be in the DocumentSetup section */
+ PPD_ORDER_EXIT, /* ... must be sent prior to the document */
+ PPD_ORDER_JCL, /* ... must be sent as a JCL command */
+ PPD_ORDER_PAGE, /* ... must be in the PageSetup section */
+ PPD_ORDER_PROLOG /* ... must be in the Prolog section */
+} ppd_section_t;
+
+typedef enum /**** Colorspaces ****/
+{
+ PPD_CS_CMYK = -4, /* CMYK colorspace */
+ PPD_CS_CMY, /* CMY colorspace */
+ PPD_CS_GRAY = 1, /* Grayscale colorspace */
+ PPD_CS_RGB = 3, /* RGB colorspace */
+ PPD_CS_RGBK, /* RGBK (K = gray) colorspace */
+ PPD_CS_N /* DeviceN colorspace */
+} ppd_cs_t;
+
+typedef struct /**** Option choices ****/
+{
+ char marked, /* 0 if not selected, 1 otherwise */
+ choice[PPD_MAX_NAME],
+ /* Computer-readable option name */
+ text[PPD_MAX_TEXT],
+ /* Human-readable option name */
+ *code; /* Code to send for this option */
+ void *option; /* Pointer to parent option structure */
+} ppd_choice_t;
+
+typedef struct /**** Options ****/
+{
+ char conflicted, /* 0 if no conflicts exist, 1 otherwise */
+ keyword[PPD_MAX_NAME],
+ /* Option keyword name ("PageSize", etc.) */
+ defchoice[PPD_MAX_NAME],
+ /* Default option choice */
+ text[PPD_MAX_TEXT];
+ /* Human-readable text */
+ ppd_ui_t ui; /* Type of UI option */
+ ppd_section_t section; /* Section for command */
+ float order; /* Order number */
+ int num_choices; /* Number of option choices */
+ ppd_choice_t *choices; /* Option choices */
+} ppd_option_t;
+
+typedef struct ppd_group_str /**** Groups ****/
+{
+ char text[PPD_MAX_TEXT];
+ /* Human-readable group name */
+ int num_options; /* Number of options */
+ ppd_option_t *options; /* Options */
+ int num_subgroups; /* Number of sub-groups */
+ struct ppd_group_str *subgroups;
+ /* Sub-groups (max depth = 1) */
+} ppd_group_t;
+
+typedef struct /**** Constraints ****/
+{
+ char option1[PPD_MAX_NAME],
+ /* First keyword */
+ choice1[PPD_MAX_NAME],
+ /* First option/choice (blank for all) */
+ option2[PPD_MAX_NAME],
+ /* Second keyword */
+ choice2[PPD_MAX_NAME];
+ /* Second option/choice (blank for all) */
+} ppd_const_t;
+
+typedef struct /**** Page Sizes ****/
+{
+ int marked; /* Page size selected? */
+ char name[PPD_MAX_NAME];
+ /* Media size option */
+ float width, /* Width of media in points */
+ length, /* Length of media in points */
+ left, /* Left printable margin in points */
+ bottom, /* Bottom printable margin in points */
+ right, /* Right printable margin in points */
+ top; /* Top printable margin in points */
+} ppd_size_t;
+
+typedef struct /**** Emulators ****/
+{
+ char name[PPD_MAX_NAME],
+ /* Emulator name */
+ *start, /* Code to switch to this emulation */
+ *stop; /* Code to stop this emulation */
+} ppd_emul_t;
+
+typedef struct /**** sRGB Color Profiles ****/
+{
+ char resolution[PPD_MAX_NAME],
+ /* Resolution or "-" */
+ media_type[PPD_MAX_NAME];
+ /* Media type of "-" */
+ float density, /* Ink density to use */
+ gamma, /* Gamma correction to use */
+ matrix[3][3]; /* Transform matrix */
+} ppd_profile_t;
+
+typedef struct /**** Files ****/
+{
+ int language_level, /* Language level of device */
+ color_device, /* 1 = color device, 0 = grayscale */
+ variable_sizes, /* 1 = supports variable sizes, 0 = doesn't */
+ accurate_screens,/* 1 = supports accurate screens, 0 = not */
+ contone_only, /* 1 = continuous tone only, 0 = not */
+ landscape, /* -90 or 90 */
+ model_number, /* Device-specific model number */
+ manual_copies, /* 1 = Copies done manually, 0 = hardware */
+ throughput; /* Pages per minute */
+ ppd_cs_t colorspace; /* Default colorspace */
+ char *patches; /* Patch commands to be sent to printer */
+ int num_emulations; /* Number of emulations supported */
+ ppd_emul_t *emulations; /* Emulations and the code to invoke them */
+ char *jcl_begin, /* Start JCL commands */
+ *jcl_ps, /* Enter PostScript interpreter */
+ *jcl_end, /* End JCL commands */
+ *lang_encoding, /* Language encoding */
+ *lang_version, /* Language version (English, Spanish, etc.) */
+ *modelname, /* Model name (general) */
+ *ttrasterizer, /* Truetype rasterizer */
+ *manufacturer, /* Manufacturer name */
+ *product, /* Product name (from PS RIP/interpreter) */
+ *nickname, /* Nickname (specific) */
+ *shortnickname; /* Short version of nickname */
+ int num_groups; /* Number of UI groups */
+ ppd_group_t *groups; /* UI groups */
+ int num_sizes; /* Number of page sizes */
+ ppd_size_t *sizes; /* Page sizes */
+ float custom_min[2], /* Minimum variable page size */
+ custom_max[2], /* Maximum variable page size */
+ custom_margins[4];/* Margins around page */
+ int num_consts; /* Number of UI/Non-UI constraints */
+ ppd_const_t *consts; /* UI/Non-UI constraints */
+ int num_fonts; /* Number of pre-loaded fonts */
+ char **fonts; /* Pre-loaded fonts */
+ int num_profiles; /* Number of sRGB color profiles */
+ ppd_profile_t *profiles; /* sRGB color profiles */
+ int num_filters; /* Number of filters */
+ char **filters; /* Filter strings... */
+ int flip_duplex; /* 1 = Flip page for back sides */
+} ppd_file_t;
+
+
+/*
+ * Prototypes...
+ */
+
+extern void ppdClose(ppd_file_t *ppd);
+extern int ppdCollect(ppd_file_t *ppd, ppd_section_t section,
+ ppd_choice_t ***choices);
+extern int ppdConflicts(ppd_file_t *ppd);
+extern int ppdEmit(ppd_file_t *ppd, FILE *fp,
+ ppd_section_t section);
+extern int ppdEmitFd(ppd_file_t *ppd, int fd,
+ ppd_section_t section);
+extern int ppdEmitJCL(ppd_file_t *ppd, FILE *fp, int job_id,
+ const char *user, const char *title);
+extern int ppdIsMarked(ppd_file_t *ppd, const char *keyword,
+ const char *option);
+extern void ppdMarkDefaults(ppd_file_t *ppd);
+extern int ppdMarkOption(ppd_file_t *ppd, const char *keyword,
+ const char *option);
+extern ppd_choice_t *ppdFindChoice(ppd_option_t *o, const char *option);
+extern ppd_choice_t *ppdFindMarkedChoice(ppd_file_t *ppd, const char *keyword);
+extern ppd_option_t *ppdFindOption(ppd_file_t *ppd, const char *keyword);
+extern ppd_file_t *ppdOpen(FILE *fp);
+extern ppd_file_t *ppdOpenFd(int fd);
+extern ppd_file_t *ppdOpenFile(const char *filename);
+extern float ppdPageLength(ppd_file_t *ppd, const char *name);
+extern ppd_size_t *ppdPageSize(ppd_file_t *ppd, const char *name);
+extern float ppdPageWidth(ppd_file_t *ppd, const char *name);
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+#endif /* !_CUPS_PPD_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/snprintf.c b/cups/snprintf.c
new file mode 100644
index 000000000..61853b2b0
--- /dev/null
+++ b/cups/snprintf.c
@@ -0,0 +1,306 @@
+/*
+ * "$Id$"
+ *
+ * snprintf functions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * cups_vsnprintf() - Format a string into a fixed size buffer.
+ * cups_snprintf() - Format a string into a fixed size buffer.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "string.h"
+
+
+#ifndef HAVE_VSNPRINTF
+/*
+ * 'cups_vsnprintf()' - Format a string into a fixed size buffer.
+ */
+
+int /* O - Number of bytes formatted */
+cups_vsnprintf(char *buffer, /* O - Output buffer */
+ size_t bufsize, /* O - Size of output buffer */
+ const char *format, /* I - printf-style format string */
+ va_list ap) /* I - Pointer to additional arguments */
+{
+ char *bufptr, /* Pointer to position in buffer */
+ *bufend, /* Pointer to end of buffer */
+ sign, /* Sign of format width */
+ size, /* Size character (h, l, L) */
+ type; /* Format type character */
+ const char *bufformat; /* Start of format */
+ int width, /* Width of field */
+ prec; /* Number of characters of precision */
+ char tformat[100], /* Temporary format string for sprintf() */
+ temp[1024]; /* Buffer for formatted numbers */
+ char *s; /* Pointer to string */
+ int slen; /* Length of string */
+
+
+ /*
+ * Loop through the format string, formatting as needed...
+ */
+
+ bufptr = buffer;
+ bufend = buffer + bufsize - 1;
+
+ while (*format && bufptr < bufend)
+ {
+ if (*format == '%')
+ {
+ bufformat = format;
+ format ++;
+
+ if (*format == '%')
+ {
+ *bufptr++ = *format++;
+ continue;
+ }
+ else if (strchr(" -+#\'", *format))
+ sign = *format++;
+ else
+ sign = 0;
+
+ width = 0;
+ while (isdigit(*format))
+ width = width * 10 + *format++ - '0';
+
+ if (*format == '.')
+ {
+ format ++;
+ prec = 0;
+
+ while (isdigit(*format))
+ prec = prec * 10 + *format++ - '0';
+ }
+ else
+ prec = -1;
+
+ if (*format == 'l' && format[1] == 'l')
+ {
+ size = 'L';
+ format += 2;
+ }
+ else if (*format == 'h' || *format == 'l' || *format == 'L')
+ size = *format++;
+
+ if (!*format)
+ break;
+
+ type = *format++;
+
+ switch (type)
+ {
+ case 'E' : /* Floating point formats */
+ case 'G' :
+ case 'e' :
+ case 'f' :
+ case 'g' :
+ if ((format - bufformat + 1) > sizeof(tformat) ||
+ (width + 2) > sizeof(temp))
+ break;
+
+ strncpy(tformat, bufformat, format - bufformat);
+ tformat[format - bufformat] = '\0';
+
+ sprintf(temp, tformat, va_arg(ap, double));
+
+ if ((bufptr + strlen(temp)) > bufend)
+ {
+ strncpy(bufptr, temp, bufend - bufptr);
+ bufptr = bufend;
+ break;
+ }
+ else
+ {
+ strcpy(bufptr, temp);
+ bufptr += strlen(temp);
+ }
+ break;
+
+ case 'B' : /* Integer formats */
+ case 'X' :
+ case 'b' :
+ case 'd' :
+ case 'i' :
+ case 'o' :
+ case 'u' :
+ case 'x' :
+ if ((format - bufformat + 1) > sizeof(tformat) ||
+ (width + 2) > sizeof(temp))
+ break;
+
+ strncpy(tformat, bufformat, format - bufformat);
+ tformat[format - bufformat] = '\0';
+
+ sprintf(temp, tformat, va_arg(ap, int));
+
+ if ((bufptr + strlen(temp)) > bufend)
+ {
+ strncpy(bufptr, temp, bufend - bufptr);
+ bufptr = bufend;
+ break;
+ }
+ else
+ {
+ strcpy(bufptr, temp);
+ bufptr += strlen(temp);
+ }
+ break;
+
+ case 'p' : /* Pointer value */
+ if ((format - bufformat + 1) > sizeof(tformat) ||
+ (width + 2) > sizeof(temp))
+ break;
+
+ strncpy(tformat, bufformat, format - bufformat);
+ tformat[format - bufformat] = '\0';
+
+ sprintf(temp, tformat, va_arg(ap, void *));
+
+ if ((bufptr + strlen(temp)) > bufend)
+ {
+ strncpy(bufptr, temp, bufend - bufptr);
+ bufptr = bufend;
+ break;
+ }
+ else
+ {
+ strcpy(bufptr, temp);
+ bufptr += strlen(temp);
+ }
+ break;
+
+ case 'c' : /* Character or character array */
+ if (width <= 1)
+ *bufptr++ = va_arg(ap, int);
+ else
+ {
+ if ((bufptr + width) > bufend)
+ width = bufend - bufptr;
+
+ memcpy(bufptr, va_arg(ap, char *), width);
+ bufptr += width;
+ }
+ break;
+
+ case 's' : /* String */
+ if ((s = va_arg(ap, char *)) == NULL)
+ s = "(null)";
+
+ slen = strlen(s);
+ if (slen > width && prec != width)
+ width = slen;
+
+ if ((bufptr + width) > bufend)
+ width = bufend - bufptr;
+
+ if (slen > width)
+ slen = width;
+
+ if (sign == '-')
+ {
+ strncpy(bufptr, s, slen);
+ memset(bufptr + slen, ' ', width - slen);
+ }
+ else
+ {
+ memset(bufptr, ' ', width - slen);
+ strncpy(bufptr + width - slen, s, slen);
+ }
+
+ bufptr += width;
+ break;
+
+ case 'n' : /* Output number of chars so far */
+ if ((format - bufformat + 1) > sizeof(tformat) ||
+ (width + 2) > sizeof(temp))
+ break;
+
+ strncpy(tformat, bufformat, format - bufformat);
+ tformat[format - bufformat] = '\0';
+
+ sprintf(temp, tformat, va_arg(ap, int));
+
+ if ((bufptr + strlen(temp)) > bufend)
+ {
+ strncpy(bufptr, temp, bufend - bufptr);
+ bufptr = bufend;
+ break;
+ }
+ else
+ {
+ strcpy(bufptr, temp);
+ bufptr += strlen(temp);
+ }
+ break;
+ }
+ }
+ else
+ *bufptr++ = *format++;
+ }
+
+ /*
+ * Nul-terminate the string and return the number of characters in it.
+ */
+
+ *bufptr = '\0';
+ return (bufptr - buffer);
+}
+#endif /* !HAVE_VSNPRINT */
+
+
+#ifndef HAVE_SNPRINTF
+/*
+ * 'cups_snprintf()' - Format a string into a fixed size buffer.
+ */
+
+int /* O - Number of bytes formatted */
+cups_snprintf(char *buffer, /* O - Output buffer */
+ size_t bufsize, /* O - Size of output buffer */
+ const char *format, /* I - printf-style format string */
+ ...) /* I - Additional arguments as needed */
+{
+ int bytes; /* Number of bytes formatted */
+ va_list ap; /* Pointer to additional arguments */
+
+
+ va_start(ap, format);
+ bytes = vsnprintf(buffer, bufsize, format, ap);
+ va_end(ap);
+
+ return (bytes);
+}
+#endif /* !HAVE_SNPRINTF */
+
+
+/*
+ * End of "$Id$".
+ */
+
diff --git a/cups/string.c b/cups/string.c
new file mode 100644
index 000000000..4d97525fd
--- /dev/null
+++ b/cups/string.c
@@ -0,0 +1,210 @@
+/*
+ * "$Id$"
+ *
+ * String functions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * cups_strdup() - Duplicate a string.
+ * cups_strcasecmp() - Do a case-insensitive comparison.
+ * cups_strncasecmp() - Do a case-insensitive comparison on up to N chars.
+ * cups_strlcat() - Safely concatenate two strings.
+ * cups_strlcpy() - Safely copy two strings.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "string.h"
+
+
+/*
+ * 'cups_strdup()' - Duplicate a string.
+ */
+
+#ifndef HAVE_STRDUP
+char * /* O - New string pointer */
+cups_strdup(const char *s) /* I - String to duplicate */
+{
+ char *t; /* New string pointer */
+
+
+ if (s == NULL)
+ return (NULL);
+
+ if ((t = malloc(strlen(s) + 1)) == NULL)
+ return (NULL);
+
+ return (strcpy(t, s));
+}
+#endif /* !HAVE_STRDUP */
+
+
+/*
+ * 'cups_strcasecmp()' - Do a case-insensitive comparison.
+ */
+
+#ifndef HAVE_STRCASECMP
+int /* O - Result of comparison (-1, 0, or 1) */
+cups_strcasecmp(const char *s, /* I - First string */
+ const char *t) /* I - Second string */
+{
+ while (*s != '\0' && *t != '\0')
+ {
+ if (tolower(*s) < tolower(*t))
+ return (-1);
+ else if (tolower(*s) > tolower(*t))
+ return (1);
+
+ s ++;
+ t ++;
+ }
+
+ if (*s == '\0' && *t == '\0')
+ return (0);
+ else if (*s != '\0')
+ return (1);
+ else
+ return (-1);
+}
+#endif /* !HAVE_STRCASECMP */
+
+/*
+ * 'cups_strncasecmp()' - Do a case-insensitive comparison on up to N chars.
+ */
+
+#ifndef HAVE_STRNCASECMP
+int /* O - Result of comparison (-1, 0, or 1) */
+cups_strncasecmp(const char *s, /* I - First string */
+ const char *t, /* I - Second string */
+ size_t n) /* I - Maximum number of characters to compare */
+{
+ while (*s != '\0' && *t != '\0' && n > 0)
+ {
+ if (tolower(*s) < tolower(*t))
+ return (-1);
+ else if (tolower(*s) > tolower(*t))
+ return (1);
+
+ s ++;
+ t ++;
+ n --;
+ }
+
+ if (n == 0)
+ return (0);
+ else if (*s == '\0' && *t == '\0')
+ return (0);
+ else if (*s != '\0')
+ return (1);
+ else
+ return (-1);
+}
+#endif /* !HAVE_STRNCASECMP */
+
+
+#ifndef HAVE_STRLCAT
+/*
+ * 'cups_strlcat()' - Safely concatenate two strings.
+ */
+
+size_t /* O - Length of string */
+cups_strlcat(char *dst, /* O - Destination string */
+ const char *src, /* I - Source string */
+ size_t size) /* I - Size of destination string buffer */
+{
+ size_t srclen; /* Length of source string */
+ size_t dstlen; /* Length of destination string */
+
+
+ /*
+ * Figure out how much room is left...
+ */
+
+ dstlen = strlen(dst);
+ size -= dstlen + 1;
+
+ if (!size)
+ return (dstlen); /* No room, return immediately... */
+
+ /*
+ * Figure out how much room is needed...
+ */
+
+ srclen = strlen(src);
+
+ /*
+ * Copy the appropriate amount...
+ */
+
+ if (srclen > size)
+ srclen = size;
+
+ memcpy(dst + dstlen, src, srclen);
+ dst[dstlen + srclen] = '\0';
+
+ return (dstlen + srclen);
+}
+#endif /* !HAVE_STRLCAT */
+
+
+#ifndef HAVE_STRLCPY
+/*
+ * 'cups_strlcpy()' - Safely copy two strings.
+ */
+
+size_t /* O - Length of string */
+cups_strlcpy(char *dst, /* O - Destination string */
+ const char *src, /* I - Source string */
+ size_t size) /* I - Size of destination string buffer */
+{
+ size_t srclen; /* Length of source string */
+
+
+ /*
+ * Figure out how much room is needed...
+ */
+
+ size --;
+
+ srclen = strlen(src);
+
+ /*
+ * Copy the appropriate amount...
+ */
+
+ if (srclen > size)
+ srclen = size;
+
+ memcpy(dst, src, srclen);
+ dst[srclen] = '\0';
+
+ return (srclen);
+}
+#endif /* !HAVE_STRLCPY */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/string.h b/cups/string.h
new file mode 100644
index 000000000..996b4a273
--- /dev/null
+++ b/cups/string.h
@@ -0,0 +1,128 @@
+/*
+ * "$Id$"
+ *
+ * String definitions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _CUPS_STRING_H_
+# define _CUPS_STRING_H_
+
+/*
+ * Include necessary headers...
+ */
+
+# include <config.h>
+
+# include <stdio.h>
+# include <stdarg.h>
+# include <ctype.h>
+
+# ifdef HAVE_STRING_H
+# include <string.h>
+# endif /* HAVE_STRING_H */
+
+# ifdef HAVE_STRINGS_H
+# include <strings.h>
+# endif /* HAVE_STRINGS_H */
+
+# ifdef HAVE_BSTRING_H
+# include <bstring.h>
+# endif /* HAVE_BSTRING_H */
+
+
+/*
+ * Stuff for WIN32 and OS/2...
+ */
+
+# if defined(WIN32) || defined(__EMX__)
+# define strcasecmp stricmp
+# define strncasecmp strnicmp
+# endif /* WIN32 || __EMX__ */
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+
+/*
+ * Prototypes...
+ */
+
+# ifndef HAVE_STRDUP
+extern char *cups_strdup(const char *);
+# define strdup cups_strdup
+# endif /* !HAVE_STRDUP */
+
+# ifndef HAVE_STRCASECMP
+extern int cups_strcasecmp(const char *, const char *);
+# define strcasecmp cups_strcasecmp
+# endif /* !HAVE_STRCASECMP */
+
+# ifndef HAVE_STRNCASECMP
+extern int cups_strncasecmp(const char *, const char *, size_t n);
+# define strncasecmp cups_strncasecmp
+# endif /* !HAVE_STRNCASECMP */
+
+# ifndef HAVE_STRLCAT
+extern size_t cups_strlcat(char *, const char *, size_t);
+# define strlcat cups_strlcat
+# endif /* !HAVE_STRLCAT */
+
+# ifndef HAVE_STRLCPY
+extern size_t cups_strlcpy(char *, const char *, size_t);
+# define strlcpy cups_strlcpy
+# endif /* !HAVE_STRLCPY */
+
+# ifndef HAVE_SNPRINTF
+extern int cups_snprintf(char *, size_t, const char *, ...)
+# ifdef __GNUC__
+__attribute__ ((__format__ (__printf__, 3, 4)))
+# endif /* __GNUC__ */
+;
+# define snprintf cups_snprintf
+# endif /* !HAVE_SNPRINTF */
+
+# ifndef HAVE_VSNPRINTF
+extern int cups_vsnprintf(char *, size_t, const char *, va_list);
+# define vsnprintf cups_vsnprintf
+# endif /* !HAVE_VSNPRINTF */
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !_CUPS_STRING_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/tempfile.c b/cups/tempfile.c
new file mode 100644
index 000000000..31788d623
--- /dev/null
+++ b/cups/tempfile.c
@@ -0,0 +1,207 @@
+/*
+ * "$Id$"
+ *
+ * Temp file utilities for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * cupsTempFd() - Create a temporary file.
+ * cupsTempFile() - Generate a temporary filename.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups.h"
+#include "string.h"
+#include "debug.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#if defined(WIN32) || defined(__EMX__)
+# include <io.h>
+#else
+# include <unistd.h>
+#endif /* WIN32 || __EMX__ */
+
+
+/*
+ * 'cupsTempFd()' - Create a temporary file.
+ */
+
+int /* O - New file descriptor */
+cupsTempFd(char *filename, /* I - Pointer to buffer */
+ int len) /* I - Size of buffer */
+{
+ int fd; /* File descriptor for temp file */
+ int tries; /* Number of tries */
+#ifdef WIN32
+ char tmpdir[1024]; /* Windows temporary directory */
+ DWORD curtime; /* Current time */
+#else
+ char *tmpdir; /* TMPDIR environment var */
+ struct timeval curtime; /* Current time */
+#endif /* WIN32 */
+ static char buf[1024] = ""; /* Buffer if you pass in NULL and 0 */
+
+
+ /*
+ * See if a filename was specified...
+ */
+
+ if (filename == NULL)
+ {
+ filename = buf;
+ len = sizeof(buf);
+ }
+
+ /*
+ * See if TMPDIR is defined...
+ */
+
+#ifdef WIN32
+ GetTempPath(sizeof(tmpdir), tmpdir);
+#else
+ if ((tmpdir = getenv("TMPDIR")) == NULL)
+ {
+ /*
+ * Put root temp files in restricted temp directory...
+ */
+
+ if (getuid() == 0)
+ tmpdir = CUPS_REQUESTS "/tmp";
+ else
+ tmpdir = "/var/tmp";
+ }
+#endif /* WIN32 */
+
+ /*
+ * Make the temporary name using the specified directory...
+ */
+
+ tries = 0;
+
+ do
+ {
+#ifdef WIN32
+ /*
+ * Get the current time of day...
+ */
+
+ curtime = GetTickCount();
+
+ /*
+ * Format a string using the hex time values...
+ */
+
+ snprintf(filename, len - 1, "%s/%08lx", tmpdir, curtime);
+#else
+ /*
+ * Get the current time of day...
+ */
+
+ gettimeofday(&curtime, NULL);
+
+ /*
+ * Format a string using the hex time values...
+ */
+
+ snprintf(filename, len - 1, "%s/%08lx%05lx", tmpdir,
+ (unsigned long)curtime.tv_sec, (unsigned long)curtime.tv_usec);
+#endif /* WIN32 */
+
+ /*
+ * Open the file in "exclusive" mode, making sure that we don't
+ * stomp on an existing file or someone's symlink crack...
+ */
+
+#ifdef O_NOFOLLOW
+ fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
+#else
+ fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
+#endif /* O_NOFOLLOW */
+
+ if (fd < 0 && errno != EEXIST)
+ break;
+
+ tries ++;
+ }
+ while (fd < 0 && tries < 1000);
+
+ /*
+ * Return the file descriptor...
+ */
+
+ return (fd);
+}
+
+
+/*
+ * 'cupsTempFile()' - Generate a temporary filename.
+ */
+
+char * /* O - Filename */
+cupsTempFile(char *filename, /* I - Pointer to buffer */
+ int len) /* I - Size of buffer */
+{
+ int fd; /* File descriptor for temp file */
+ static char buf[1024] = ""; /* Buffer if you pass in NULL and 0 */
+
+
+ /*
+ * See if a filename was specified...
+ */
+
+ if (filename == NULL)
+ {
+ filename = buf;
+ len = sizeof(buf);
+ }
+
+ /*
+ * Create the temporary file...
+ */
+
+ if ((fd = cupsTempFd(filename, len)) < 0)
+ return (NULL);
+
+ /*
+ * Close the temp file - it'll be reopened later as needed...
+ */
+
+ close(fd);
+
+ /*
+ * Return the temp filename...
+ */
+
+ return (filename);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/testhttp.c b/cups/testhttp.c
new file mode 100644
index 000000000..baffbcb28
--- /dev/null
+++ b/cups/testhttp.c
@@ -0,0 +1,126 @@
+/*
+ * "$Id$"
+ *
+ * HTTP test program for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Main entry.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include "http.h"
+
+
+/*
+ * 'main()' - Main entry.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ http_t *http; /* HTTP connection */
+ http_status_t status; /* Status of GET command */
+ char buffer[8192]; /* Input buffer */
+ long bytes; /* Number of bytes read */
+ FILE *out; /* Output file */
+ char host[HTTP_MAX_URI],
+ method[HTTP_MAX_URI],
+ username[HTTP_MAX_URI],
+ resource[HTTP_MAX_URI];
+ int port;
+ long length, total;
+ time_t start, current;
+
+
+
+ http = NULL;
+ out = stdout;
+
+ for (i = 1; i < argc; i ++)
+ {
+ if (strcmp(argv[i], "-o") == 0)
+ {
+ i ++;
+ out = fopen(argv[i], "wb");
+ continue;
+ }
+
+ httpSeparate(argv[i], method, username, host, &port, resource);
+
+ http = httpConnect(host, port);
+ if (http == NULL)
+ {
+ perror(host);
+ continue;
+ }
+ printf("Requesting file \"%s\"...\n", resource);
+ httpClearFields(http);
+ httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en");
+ httpGet(http, resource);
+ while ((status = httpUpdate(http)) == HTTP_CONTINUE);
+
+ if (status == HTTP_OK)
+ puts("GET OK:");
+ else
+ printf("GET failed with status %d...\n", status);
+
+
+ start = time(NULL);
+ length = atoi(httpGetField(http, HTTP_FIELD_CONTENT_LENGTH));
+ total = 0;
+
+ while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0)
+ {
+ total += bytes;
+ fwrite(buffer, bytes, 1, out);
+ if (out != stdout)
+ {
+ current = time(NULL);
+ if (current == start) current ++;
+ printf("\r%ld/%ld bytes (%ld bytes/sec) ", total, length,
+ total / (current - start));
+ fflush(stdout);
+ }
+ }
+ }
+
+ puts("Closing connection to server...");
+ httpClose(http);
+
+ if (out != stdout)
+ fclose(out);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/testlang.c b/cups/testlang.c
new file mode 100644
index 000000000..4ac708b58
--- /dev/null
+++ b/cups/testlang.c
@@ -0,0 +1,96 @@
+/*
+ * "$Id$"
+ *
+ * HTTP test program for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Load the specified language and show the strings for yes and no.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include "language.h"
+
+
+/*
+ * 'main()' - Load the specified language and show the strings for yes and no.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ cups_lang_t *language; /* Message catalog */
+ static const char *charsets[] = /* Character sets */
+ {
+ "us-ascii",
+ "iso-8859-1",
+ "iso-8859-2",
+ "iso-8859-3",
+ "iso-8859-4",
+ "iso-8859-5",
+ "iso-8859-6",
+ "iso-8859-7",
+ "iso-8859-8",
+ "iso-8859-9",
+ "iso-8859-10",
+ "utf-8",
+ "iso8859-13",
+ "iso8859-14",
+ "iso8859-15",
+ "windows-874",
+ "windows-1250",
+ "windows-1251",
+ "windows-1252",
+ "windows-1253",
+ "windows-1254",
+ "windows-1255",
+ "windows-1256",
+ "windows-1257",
+ "windows-1258",
+ "koi8-r",
+ "koi8-u"
+ };
+
+
+ if (argc == 1)
+ language = cupsLangDefault();
+ else
+ language = cupsLangGet(argv[1]);
+
+ printf("Language = \"%s\"\n", language->language);
+ printf("Encoding = \"%s\"\n", charsets[language->encoding]);
+ printf("No = \"%s\"\n", cupsLangString(language, CUPS_MSG_NO));
+ printf("Yes = \"%s\"\n", cupsLangString(language, CUPS_MSG_YES));
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/testmime.dsp b/cups/testmime.dsp
new file mode 100644
index 000000000..33fbd301a
--- /dev/null
+++ b/cups/testmime.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="testmime" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=testmime - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "testmime.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "testmime.mak" CFG="testmime - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "testmime - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "testmime - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "testmime - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 cups.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"testmime.exe"
+
+!ELSEIF "$(CFG)" == "testmime - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "testmime___Win32_Debug"
+# PROP BASE Intermediate_Dir "testmime___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /I "../visualc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 cupsd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"testmimed.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "testmime - Win32 Release"
+# Name "testmime - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\testmime.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\mime.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cups/testppd.c b/cups/testppd.c
new file mode 100644
index 000000000..249851029
--- /dev/null
+++ b/cups/testppd.c
@@ -0,0 +1,197 @@
+/*
+ * "$Id$"
+ *
+ * PPD test program for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * PostScript is a trademark of Adobe Systems, Inc.
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Main entry for test program.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups.h"
+#include "string.h"
+
+
+/*
+ * 'main()' - Main entry for test program.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i, j, k, m; /* Looping vars */
+ ppd_file_t *ppd; /* PPD file record */
+ ppd_size_t *size; /* Size record */
+ ppd_group_t *group; /* UI group */
+ ppd_option_t *option; /* Standard UI option */
+ ppd_choice_t *choice; /* Standard UI option choice */
+ static char *uis[] = { "BOOLEAN", "PICKONE", "PICKMANY" };
+ static char *sections[] = { "ANY", "DOCUMENT", "EXIT",
+ "JCL", "PAGE", "PROLOG" };
+
+
+ setbuf(stdout, NULL);
+
+ /*
+ * Display PPD files for each file listed on the command-line...
+ */
+
+ if (argc == 1)
+ {
+ fputs("Usage: ppdtest filename1.ppd [... filenameN.ppd]\n", stderr);
+ return (1);
+ }
+
+ for (i = 1; i < argc; i ++)
+ {
+ if ((ppd = ppdOpenFile(argv[i])) == NULL)
+ {
+ fprintf(stderr, "Unable to open \'%s\' as a PPD file!\n", argv[i]);
+ continue;
+ }
+
+ printf("FILE: %s\n", argv[i]);
+ printf(" language_level = %d\n", ppd->language_level);
+ printf(" color_device = %s\n", ppd->color_device ? "TRUE" : "FALSE");
+ printf(" variable_sizes = %s\n", ppd->variable_sizes ? "TRUE" : "FALSE");
+ printf(" landscape = %d\n", ppd->landscape);
+
+ switch (ppd->colorspace)
+ {
+ case PPD_CS_CMYK :
+ puts(" colorspace = PPD_CS_CMYK");
+ break;
+ case PPD_CS_CMY :
+ puts(" colorspace = PPD_CS_CMY");
+ break;
+ case PPD_CS_GRAY :
+ puts(" colorspace = PPD_CS_GRAY");
+ break;
+ case PPD_CS_RGB :
+ puts(" colorspace = PPD_CS_RGB");
+ break;
+ default :
+ puts(" colorspace = <unknown>");
+ break;
+ }
+
+ printf(" num_emulations = %d\n", ppd->num_emulations);
+ for (j = 0; j < ppd->num_emulations; j ++)
+ printf(" emulations[%d] = %s\n", j, ppd->emulations[j].name);
+
+ printf(" lang_encoding = %s\n", ppd->lang_encoding);
+ printf(" lang_version = %s\n", ppd->lang_version);
+ printf(" modelname = %s\n", ppd->modelname);
+ printf(" ttrasterizer = %s\n",
+ ppd->ttrasterizer == NULL ? "None" : ppd->ttrasterizer);
+ printf(" manufacturer = %s\n", ppd->manufacturer);
+ printf(" product = %s\n", ppd->product);
+ printf(" nickname = %s\n", ppd->nickname);
+ printf(" shortnickname = %s\n", ppd->shortnickname);
+ printf(" patches = %d bytes\n",
+ ppd->patches == NULL ? 0 : (int)strlen(ppd->patches));
+
+ printf(" num_groups = %d\n", ppd->num_groups);
+ for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++)
+ {
+ printf(" group[%d] = %s\n", j, group->text);
+
+ for (k = 0, option = group->options; k < group->num_options; k ++, option ++)
+ {
+ printf(" options[%d] = %s (%s) %s %s %.0f (%d choices)\n", k,
+ option->keyword, option->text, uis[option->ui],
+ sections[option->section], option->order,
+ option->num_choices);
+
+ if (strcmp(option->keyword, "PageSize") == 0 ||
+ strcmp(option->keyword, "PageRegion") == 0)
+ {
+ for (m = option->num_choices, choice = option->choices;
+ m > 0;
+ m --, choice ++)
+ {
+ size = ppdPageSize(ppd, choice->choice);
+
+ if (size == NULL)
+ printf(" %s (%s) = ERROR", choice->choice, choice->text);
+ else
+ printf(" %s (%s) = %.2fx%.2fin (%.1f,%.1f,%.1f,%.1f)", choice->choice,
+ choice->text, size->width / 72.0, size->length / 72.0,
+ size->left / 72.0, size->bottom / 72.0,
+ size->right / 72.0, size->top / 72.0);
+
+ if (strcmp(option->defchoice, choice->choice) == 0)
+ puts(" *");
+ else
+ putchar('\n');
+ }
+ }
+ else
+ {
+ for (m = option->num_choices, choice = option->choices;
+ m > 0;
+ m --, choice ++)
+ {
+ printf(" %s (%s)", choice->choice, choice->text);
+
+ if (strcmp(option->defchoice, choice->choice) == 0)
+ puts(" *");
+ else
+ putchar('\n');
+ }
+ }
+ }
+ }
+
+ printf(" num_profiles = %d\n", ppd->num_profiles);
+ for (j = 0; j < ppd->num_profiles; j ++)
+ printf(" profiles[%d] = %s/%s %.3f %.3f [ %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f ]\n",
+ j, ppd->profiles[j].resolution, ppd->profiles[j].media_type,
+ ppd->profiles[j].gamma, ppd->profiles[j].density,
+ ppd->profiles[j].matrix[0][0], ppd->profiles[j].matrix[0][1],
+ ppd->profiles[j].matrix[0][2], ppd->profiles[j].matrix[1][0],
+ ppd->profiles[j].matrix[1][1], ppd->profiles[j].matrix[1][2],
+ ppd->profiles[j].matrix[2][0], ppd->profiles[j].matrix[2][1],
+ ppd->profiles[j].matrix[2][2]);
+
+ printf(" num_fonts = %d\n", ppd->num_fonts);
+ for (j = 0; j < ppd->num_fonts; j ++)
+ printf(" fonts[%d] = %s\n", j, ppd->fonts[j]);
+
+ ppdClose(ppd);
+ }
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/testppd.dsp b/cups/testppd.dsp
new file mode 100644
index 000000000..27d4f035c
--- /dev/null
+++ b/cups/testppd.dsp
@@ -0,0 +1,102 @@
+# Microsoft Developer Studio Project File - Name="testppd" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=testppd - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "testppd.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "testppd.mak" CFG="testppd - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "testppd - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "testppd - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "testppd - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 cups.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"testppd.exe"
+
+!ELSEIF "$(CFG)" == "testppd - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "testppd___Win32_Debug"
+# PROP BASE Intermediate_Dir "testppd___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /I "../visualc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 cupsd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"testppdd.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "testppd - Win32 Release"
+# Name "testppd - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\testppd.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\ppd.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cups/usersys.c b/cups/usersys.c
new file mode 100644
index 000000000..30e920d38
--- /dev/null
+++ b/cups/usersys.c
@@ -0,0 +1,441 @@
+/*
+ * "$Id$"
+ *
+ * User, system, and password routines for the Common UNIX Printing
+ * System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * cupsEncryption() - Get the default encryption settings...
+ * cupsGetPassword() - Get a password from the user...
+ * cupsServer() - Return the hostname of the default server...
+ * cupsSetEncryption() - Set the encryption preference.
+ * cupsSetPasswordCB() - Set the password callback for CUPS.
+ * cupsSetServer() - Set the default server name...
+ * cupsSetUser() - Set the default user name...
+ * cupsUser() - Return the current users name.
+ * cups_get_password() - Get a password from the user...
+ * cups_get_line() - Get a line from a file...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups.h"
+#include "string.h"
+#include <stdlib.h>
+#include <ctype.h>
+
+
+/*
+ * Local functions...
+ */
+
+static const char *cups_get_password(const char *prompt);
+static char *cups_get_line(char *buf, int buflen, FILE *fp);
+
+
+/*
+ * Local globals...
+ */
+
+static http_encryption_t cups_encryption = (http_encryption_t)-1;
+static char cups_user[65] = "",
+ cups_server[256] = "";
+static const char *(*cups_pwdcb)(const char *) = cups_get_password;
+
+
+/*
+ * 'cupsEncryption()' - Get the default encryption settings...
+ */
+
+http_encryption_t
+cupsEncryption(void)
+{
+ FILE *fp; /* client.conf file */
+ char *encryption; /* CUPS_ENCRYPTION variable */
+ const char *home; /* Home directory of user */
+ static char line[1024]; /* Line from file */
+
+
+ /*
+ * First see if we have already set the encryption stuff...
+ */
+
+ if (cups_encryption == (http_encryption_t)-1)
+ {
+ /*
+ * Then see if the CUPS_ENCRYPTION environment variable is set...
+ */
+
+ if ((encryption = getenv("CUPS_ENCRYPTION")) == NULL)
+ {
+ /*
+ * Next check to see if we have a $HOME/.cupsrc or client.conf file...
+ */
+
+ if ((home = getenv("HOME")) != NULL)
+ {
+ snprintf(line, sizeof(line), "%s/.cupsrc", home);
+ fp = fopen(line, "r");
+ }
+ else
+ fp = NULL;
+
+ if (fp == NULL)
+ {
+ if ((home = getenv("CUPS_SERVERROOT")) != NULL)
+ {
+ snprintf(line, sizeof(line), "%s/client.conf", home);
+ fp = fopen(line, "r");
+ }
+ else
+ fp = fopen(CUPS_SERVERROOT "/client.conf", "r");
+ }
+
+ encryption = "IfRequested";
+
+ if (fp != NULL)
+ {
+ /*
+ * Read the config file and look for a ServerName line...
+ */
+
+ while (cups_get_line(line, sizeof(line), fp) != NULL)
+ if (strncmp(line, "Encryption ", 11) == 0)
+ {
+ /*
+ * Got it! Drop any trailing newline and find the name...
+ */
+
+ encryption = line + strlen(line) - 1;
+ if (*encryption == '\n')
+ *encryption = '\0';
+
+ for (encryption = line + 11; isspace(*encryption); encryption ++);
+ break;
+ }
+
+ fclose(fp);
+ }
+ }
+
+ /*
+ * Set the encryption preference...
+ */
+
+ if (strcasecmp(encryption, "never") == 0)
+ cups_encryption = HTTP_ENCRYPT_NEVER;
+ else if (strcasecmp(encryption, "always") == 0)
+ cups_encryption = HTTP_ENCRYPT_ALWAYS;
+ else if (strcasecmp(encryption, "required") == 0)
+ cups_encryption = HTTP_ENCRYPT_REQUIRED;
+ else
+ cups_encryption = HTTP_ENCRYPT_IF_REQUESTED;
+ }
+
+ return (cups_encryption);
+}
+
+
+/*
+ * 'cupsGetPassword()' - Get a password from the user...
+ */
+
+const char * /* O - Password */
+cupsGetPassword(const char *prompt) /* I - Prompt string */
+{
+ return ((*cups_pwdcb)(prompt));
+}
+
+
+/*
+ * 'cupsSetEncryption()' - Set the encryption preference.
+ */
+
+void
+cupsSetEncryption(http_encryption_t e) /* I - New encryption preference */
+{
+ cups_encryption = e;
+}
+
+
+/*
+ * 'cupsServer()' - Return the hostname of the default server...
+ */
+
+const char * /* O - Server name */
+cupsServer(void)
+{
+ FILE *fp; /* client.conf file */
+ char *server; /* Pointer to server name */
+ const char *home; /* Home directory of user */
+ static char line[1024]; /* Line from file */
+
+
+ /*
+ * First see if we have already set the server name...
+ */
+
+ if (!cups_server[0])
+ {
+ /*
+ * Then see if the CUPS_SERVER environment variable is set...
+ */
+
+ if ((server = getenv("CUPS_SERVER")) == NULL)
+ {
+ /*
+ * Next check to see if we have a $HOME/.cupsrc or client.conf file...
+ */
+
+ if ((home = getenv("HOME")) != NULL)
+ {
+ snprintf(line, sizeof(line), "%s/.cupsrc", home);
+ fp = fopen(line, "r");
+ }
+ else
+ fp = NULL;
+
+ if (fp == NULL)
+ {
+ if ((home = getenv("CUPS_SERVERROOT")) != NULL)
+ {
+ snprintf(line, sizeof(line), "%s/client.conf", home);
+ fp = fopen(line, "r");
+ }
+ else
+ fp = fopen(CUPS_SERVERROOT "/client.conf", "r");
+ }
+
+ server = "localhost";
+
+ if (fp != NULL)
+ {
+ /*
+ * Read the config file and look for a ServerName line...
+ */
+
+ while (cups_get_line(line, sizeof(line), fp) != NULL)
+ if (strncmp(line, "ServerName ", 11) == 0)
+ {
+ /*
+ * Got it! Drop any trailing newline and find the name...
+ */
+
+ server = line + strlen(line) - 1;
+ if (*server == '\n')
+ *server = '\0';
+
+ for (server = line + 11; isspace(*server); server ++);
+ break;
+ }
+
+ fclose(fp);
+ }
+ }
+
+ /*
+ * Copy the server name over...
+ */
+
+ strlcpy(cups_server, server, sizeof(cups_server));
+ }
+
+ return (cups_server);
+}
+
+
+/*
+ * 'cupsSetPasswordCB()' - Set the password callback for CUPS.
+ */
+
+void
+cupsSetPasswordCB(const char *(*cb)(const char *)) /* I - Callback function */
+{
+ if (cb == (const char *(*)(const char *))0)
+ cups_pwdcb = cups_get_password;
+ else
+ cups_pwdcb = cb;
+}
+
+
+/*
+ * 'cupsSetServer()' - Set the default server name...
+ */
+
+void
+cupsSetServer(const char *server) /* I - Server name */
+{
+ if (server)
+ strlcpy(cups_server, server, sizeof(cups_server));
+ else
+ cups_server[0] = '\0';
+}
+
+
+/*
+ * 'cupsSetUser()' - Set the default user name...
+ */
+
+void
+cupsSetUser(const char *user) /* I - User name */
+{
+ if (user)
+ strlcpy(cups_user, user, sizeof(cups_user));
+ else
+ cups_user[0] = '\0';
+}
+
+
+#if defined(WIN32) || defined(__EMX__)
+/*
+ * WIN32 and OS/2 username and password stuff...
+ */
+
+/*
+ * 'cupsUser()' - Return the current user's name.
+ */
+
+const char * /* O - User name */
+cupsUser(void)
+{
+ if (!cups_user[0])
+ strcpy(cups_user, "WindowsUser");
+
+ return (cups_user);
+}
+
+
+/*
+ * 'cups_get_password()' - Get a password from the user...
+ */
+
+static const char * /* O - Password */
+cups_get_password(const char *prompt) /* I - Prompt string */
+{
+ return (NULL);
+}
+#else
+/*
+ * UNIX username and password stuff...
+ */
+
+# include <pwd.h>
+
+/*
+ * 'cupsUser()' - Return the current user's name.
+ */
+
+const char * /* O - User name */
+cupsUser(void)
+{
+ struct passwd *pwd; /* User/password entry */
+
+
+ if (!cups_user[0])
+ {
+ /*
+ * Rewind the password file...
+ */
+
+ setpwent();
+
+ /*
+ * Lookup the password entry for the current user.
+ */
+
+ if ((pwd = getpwuid(getuid())) == NULL)
+ strcpy(cups_user, "unknown"); /* Unknown user! */
+ else
+ {
+ /*
+ * Copy the username...
+ */
+
+ setpwent();
+
+ strlcpy(cups_user, pwd->pw_name, sizeof(cups_user));
+ }
+
+ /*
+ * Rewind the password file again...
+ */
+
+ setpwent();
+ }
+
+ return (cups_user);
+}
+
+
+/*
+ * 'cups_get_password()' - Get a password from the user...
+ */
+
+static const char * /* O - Password */
+cups_get_password(const char *prompt) /* I - Prompt string */
+{
+ return (getpass(prompt));
+}
+#endif /* WIN32 || __EMX__ */
+
+
+/*
+ * 'cups_get_line()' - Get a line from a file.
+ */
+
+static char * /* O - Line from file */
+cups_get_line(char *buf, /* I - Line buffer */
+ int buflen, /* I - Size of line buffer */
+ FILE *fp) /* I - File to read from */
+{
+ char *bufptr; /* Pointer to end of buffer */
+
+
+ /*
+ * Get the line from a file...
+ */
+
+ if (fgets(buf, buflen, fp) == NULL)
+ return (NULL);
+
+ /*
+ * Remove all trailing whitespace...
+ */
+
+ bufptr = buf + strlen(buf) - 1;
+ if (bufptr < buf)
+ return (NULL);
+
+ while (isspace(*bufptr) && bufptr >= buf)
+ *bufptr-- = '\0';
+
+ return (buf);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/cups/util.c b/cups/util.c
new file mode 100644
index 000000000..586ebd081
--- /dev/null
+++ b/cups/util.c
@@ -0,0 +1,1766 @@
+/*
+ * "$Id$"
+ *
+ * Printing utilities for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * cupsCancelJob() - Cancel a print job.
+ * cupsDoFileRequest() - Do an IPP request...
+ * cupsFreeJobs() - Free memory used by job data.
+ * cupsGetClasses() - Get a list of printer classes.
+ * cupsGetDefault() - Get the default printer or class.
+ * cupsGetJobs() - Get the jobs from the server.
+ * cupsGetPPD() - Get the PPD file for a printer.
+ * cupsGetPrinters() - Get a list of printers.
+ * cupsLastError() - Return the last IPP error that occurred.
+ * cupsPrintFile() - Print a file to a printer or class.
+ * cupsPrintFiles() - Print one or more files to a printer or class.
+ * cups_connect() - Connect to the specified host...
+ * cups_local_auth() - Get the local authorization certificate if
+ * available/applicable...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups.h"
+#include "ipp.h"
+#include "language.h"
+#include "string.h"
+#include "debug.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#if defined(WIN32) || defined(__EMX__)
+# include <io.h>
+#else
+# include <unistd.h>
+#endif /* WIN32 || __EMX__ */
+
+
+/*
+ * Local globals...
+ */
+
+static http_t *cups_server = NULL; /* Current server connection */
+static ipp_status_t last_error = IPP_OK; /* Last IPP error */
+static char authstring[HTTP_MAX_VALUE] = "";
+ /* Authorization string */
+static char pwdstring[33] = ""; /* Last password string */
+
+
+/*
+ * Local functions...
+ */
+
+static char *cups_connect(const char *name, char *printer, char *hostname);
+static int cups_local_auth(http_t *http);
+
+
+/*
+ * 'cupsCancelJob()' - Cancel a print job.
+ */
+
+int /* O - 1 on success, 0 on failure */
+cupsCancelJob(const char *name, /* I - Name of printer or class */
+ int job) /* I - Job ID */
+{
+ char printer[HTTP_MAX_URI], /* Printer name */
+ hostname[HTTP_MAX_URI], /* Hostname */
+ uri[HTTP_MAX_URI]; /* Printer URI */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ cups_lang_t *language; /* Language info */
+
+
+ /*
+ * See if we can connect to the server...
+ */
+
+ if (!cups_connect(name, printer, hostname))
+ {
+ last_error = IPP_SERVICE_UNAVAILABLE;
+ return (0);
+ }
+
+ /*
+ * Build an IPP_CANCEL_JOB request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * job-id
+ * [requesting-user-name]
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_CANCEL_JOB;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language != NULL ? language->language : "C");
+
+ snprintf(uri, sizeof(uri), "ipp://%s:%d/printers/%s", hostname, ippPort(), printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, cupsUser());
+
+ /*
+ * Do the request...
+ */
+
+ if ((response = cupsDoRequest(cups_server, request, "/jobs/")) == NULL)
+ {
+ last_error = IPP_BAD_REQUEST;
+ return (0);
+ }
+ else
+ {
+ last_error = response->request.status.status_code;
+ ippDelete(response);
+
+ return (1);
+ }
+}
+
+
+/*
+ * 'cupsDoFileRequest()' - Do an IPP request...
+ */
+
+ipp_t * /* O - Response data */
+cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
+ ipp_t *request, /* I - IPP request */
+ const char *resource, /* I - HTTP resource for POST */
+ const char *filename) /* I - File to send or NULL */
+{
+ ipp_t *response; /* IPP response data */
+ char length[255]; /* Content-Length field */
+ http_status_t status; /* Status of HTTP request */
+ FILE *file; /* File to send */
+ struct stat fileinfo; /* File information */
+ int bytes; /* Number of bytes read/written */
+ char buffer[32768]; /* Output buffer */
+ const char *password; /* Password string */
+ char realm[HTTP_MAX_VALUE], /* realm="xyz" string */
+ nonce[HTTP_MAX_VALUE], /* nonce="xyz" string */
+ plain[255], /* Plaintext username:password */
+ encode[512]; /* Encoded username:password */
+ char prompt[1024]; /* Prompt string */
+ int digest_tries; /* Number of tries with Digest */
+
+
+ if (http == NULL || request == NULL || resource == NULL)
+ {
+ if (request != NULL)
+ ippDelete(request);
+
+ last_error = IPP_INTERNAL_ERROR;
+ return (NULL);
+ }
+
+ DEBUG_printf(("cupsDoFileRequest(%p, %p, \'%s\', \'%s\')\n",
+ http, request, resource, filename ? filename : "(null)"));
+
+ /*
+ * See if we have a file to send...
+ */
+
+ if (filename != NULL)
+ {
+ if (stat(filename, &fileinfo))
+ {
+ /*
+ * Can't get file information!
+ */
+
+ ippDelete(request);
+ last_error = IPP_NOT_FOUND;
+ return (NULL);
+ }
+
+ if (S_ISDIR(fileinfo.st_mode))
+ {
+ /*
+ * Can't send a directory...
+ */
+
+ ippDelete(request);
+ last_error = IPP_NOT_POSSIBLE;
+ return (NULL);
+ }
+
+ if ((file = fopen(filename, "rb")) == NULL)
+ {
+ /*
+ * Can't open file!
+ */
+
+ ippDelete(request);
+ last_error = IPP_NOT_FOUND;
+ return (NULL);
+ }
+ }
+ else
+ file = NULL;
+
+ /*
+ * Loop until we can send the request without authorization problems.
+ */
+
+ response = NULL;
+ status = HTTP_ERROR;
+ digest_tries = 0;
+
+ while (response == NULL)
+ {
+ DEBUG_puts("cupsDoFileRequest: setup...");
+
+ /*
+ * Setup the HTTP variables needed...
+ */
+
+ if (filename != NULL)
+ sprintf(length, "%lu", (unsigned long)(ippLength(request) +
+ (size_t)fileinfo.st_size));
+ else
+ sprintf(length, "%lu", (unsigned long)ippLength(request));
+
+ httpClearFields(http);
+ httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length);
+ httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
+ httpSetField(http, HTTP_FIELD_AUTHORIZATION, authstring);
+
+ DEBUG_printf(("cupsDoFileRequest: authstring=\"%s\"\n", authstring));
+
+ /*
+ * Try the request...
+ */
+
+ DEBUG_puts("cupsDoFileRequest: post...");
+
+ if (httpPost(http, resource))
+ {
+ if (httpReconnect(http))
+ {
+ status = HTTP_ERROR;
+ break;
+ }
+ else
+ continue;
+ }
+
+ /*
+ * Send the IPP data and wait for the response...
+ */
+
+ DEBUG_puts("cupsDoFileRequest: ipp write...");
+
+ request->state = IPP_IDLE;
+ if (ippWrite(http, request) != IPP_ERROR)
+ if (filename != NULL)
+ {
+ DEBUG_puts("cupsDoFileRequest: file write...");
+
+ /*
+ * Send the file...
+ */
+
+ rewind(file);
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), file)) > 0)
+ if (httpWrite(http, buffer, bytes) < bytes)
+ break;
+ }
+
+ /*
+ * Get the server's return status...
+ */
+
+ DEBUG_puts("cupsDoFileRequest: update...");
+
+ while ((status = httpUpdate(http)) == HTTP_CONTINUE);
+
+ DEBUG_printf(("cupsDoFileRequest: status = %d\n", status));
+
+ if (status == HTTP_UNAUTHORIZED)
+ {
+ DEBUG_puts("cupsDoFileRequest: unauthorized...");
+
+ /*
+ * Flush any error message...
+ */
+
+ httpFlush(http);
+
+ /*
+ * See if we can do local authentication...
+ */
+
+ if (cups_local_auth(http))
+ continue;
+
+ /*
+ * See if we should retry the current digest password...
+ */
+
+ if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0 ||
+ digest_tries > 1 || !pwdstring[0])
+ {
+ /*
+ * Nope - get a password from the user...
+ */
+
+ snprintf(prompt, sizeof(prompt), "Password for %s on %s? ", cupsUser(),
+ http->hostname);
+
+ if ((password = cupsGetPassword(prompt)) == NULL)
+ break;
+ if (!password[0])
+ break;
+
+ strlcpy(pwdstring, password, sizeof(pwdstring));
+
+ digest_tries = 0;
+ }
+ else
+ digest_tries ++;
+
+ /*
+ * Got a password; encode it for the server...
+ */
+
+ if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0)
+ {
+ /*
+ * Basic authentication...
+ */
+
+ snprintf(plain, sizeof(plain), "%s:%s", cupsUser(), pwdstring);
+ httpEncode64(encode, plain);
+ snprintf(authstring, sizeof(authstring), "Basic %s", encode);
+ }
+ else
+ {
+ /*
+ * Digest authentication...
+ */
+
+ httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm);
+ httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce);
+
+ httpMD5(cupsUser(), realm, pwdstring, encode);
+ httpMD5Final(nonce, "POST", resource, encode);
+ snprintf(authstring, sizeof(authstring),
+ "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", "
+ "response=\"%s\"", cupsUser(), realm, nonce, encode);
+ }
+
+ continue;
+ }
+ else if (status == HTTP_ERROR)
+ {
+#ifdef WIN32
+ if (http->error != WSAENETDOWN && http->error != WSAENETUNREACH)
+#else
+ if (http->error != ENETDOWN && http->error != ENETUNREACH)
+#endif /* WIN32 */
+ continue;
+ else
+ break;
+ }
+#ifdef HAVE_LIBSSL
+ else if (status == HTTP_UPGRADE_REQUIRED)
+ {
+ /*
+ * Flush any error message...
+ */
+
+ httpFlush(http);
+
+ /*
+ * Upgrade with encryption...
+ */
+
+ httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+
+ /*
+ * Try again, this time with encryption enabled...
+ */
+
+ continue;
+ }
+#endif /* HAVE_LIBSSL */
+ else if (status != HTTP_OK)
+ {
+ DEBUG_printf(("cupsDoFileRequest: error %d...\n", status));
+
+ /*
+ * Flush any error message...
+ */
+
+ httpFlush(http);
+ break;
+ }
+ else
+ {
+ /*
+ * Read the response...
+ */
+
+ DEBUG_puts("cupsDoFileRequest: response...");
+
+ response = ippNew();
+
+ if (ippRead(http, response) == IPP_ERROR)
+ {
+ /*
+ * Delete the response...
+ */
+
+ ippDelete(response);
+ response = NULL;
+
+ last_error = IPP_SERVICE_UNAVAILABLE;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Close the file if needed...
+ */
+
+ if (filename != NULL)
+ fclose(file);
+
+ /*
+ * Flush any remaining data...
+ */
+
+ httpFlush(http);
+
+ /*
+ * Delete the original request and return the response...
+ */
+
+ ippDelete(request);
+
+ if (response)
+ last_error = response->request.status.status_code;
+ else if (status == HTTP_NOT_FOUND)
+ last_error = IPP_NOT_FOUND;
+ else if (status == HTTP_UNAUTHORIZED)
+ last_error = IPP_NOT_AUTHORIZED;
+ else if (status != HTTP_OK)
+ last_error = IPP_SERVICE_UNAVAILABLE;
+
+ return (response);
+}
+
+
+/*
+ * 'cupsFreeJobs()' - Free memory used by job data.
+ */
+
+void
+cupsFreeJobs(int num_jobs,/* I - Number of jobs */
+ cups_job_t *jobs) /* I - Jobs */
+{
+ int i; /* Looping var */
+
+
+ if (num_jobs <= 0 || jobs == NULL)
+ return;
+
+ for (i = 0; i < num_jobs; i ++)
+ {
+ free(jobs[i].dest);
+ free(jobs[i].user);
+ free(jobs[i].format);
+ free(jobs[i].title);
+ }
+
+ free(jobs);
+}
+
+
+/*
+ * 'cupsGetClasses()' - Get a list of printer classes.
+ */
+
+int /* O - Number of classes */
+cupsGetClasses(char ***classes) /* O - Classes */
+{
+ int n; /* Number of classes */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ char **temp; /* Temporary pointer */
+
+
+ if (classes == NULL)
+ {
+ last_error = IPP_INTERNAL_ERROR;
+ return (0);
+ }
+
+ /*
+ * Try to connect to the server...
+ */
+
+ if (!cups_connect("default", NULL, NULL))
+ {
+ last_error = IPP_SERVICE_UNAVAILABLE;
+ return (0);
+ }
+
+ /*
+ * Build a CUPS_GET_CLASSES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_CLASSES;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", NULL, "printer-name");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ n = 0;
+ *classes = NULL;
+
+ if ((response = cupsDoRequest(cups_server, request, "/")) != NULL)
+ {
+ last_error = response->request.status.status_code;
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ if (attr->name != NULL &&
+ strcasecmp(attr->name, "printer-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ {
+ if (n == 0)
+ temp = malloc(sizeof(char *));
+ else
+ temp = realloc(*classes, sizeof(char *) * (n + 1));
+
+ if (temp == NULL)
+ {
+ /*
+ * Ran out of memory!
+ */
+
+ while (n > 0)
+ {
+ n --;
+ free((*classes)[n]);
+ }
+
+ free(*classes);
+ ippDelete(response);
+ return (0);
+ }
+
+ *classes = temp;
+ temp[n] = strdup(attr->values[0].string.text);
+ n ++;
+ }
+
+ ippDelete(response);
+ }
+ else
+ last_error = IPP_BAD_REQUEST;
+
+ return (n);
+}
+
+
+/*
+ * 'cupsGetDefault()' - Get the default printer or class.
+ */
+
+const char * /* O - Default printer or NULL */
+cupsGetDefault(void)
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ const char *var; /* Environment variable */
+ static char def_printer[256];/* Default printer */
+
+
+ /*
+ * First see if the LPDEST or PRINTER environment variables are
+ * set... However, if PRINTER is set to "lp", ignore it to work
+ * around a "feature" in most Linux distributions - the default
+ * user login scripts set PRINTER to "lp"...
+ */
+
+ if ((var = getenv("LPDEST")) != NULL)
+ return (var);
+ else if ((var = getenv("PRINTER")) != NULL && strcmp(var, "lp") != 0)
+ return (var);
+
+ /*
+ * Try to connect to the server...
+ */
+
+ if (!cups_connect("default", NULL, NULL))
+ {
+ last_error = IPP_SERVICE_UNAVAILABLE;
+ return (NULL);
+ }
+
+ /*
+ * Build a CUPS_GET_DEFAULT request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_DEFAULT;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(cups_server, request, "/")) != NULL)
+ {
+ last_error = response->request.status.status_code;
+
+ if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
+ {
+ strlcpy(def_printer, attr->values[0].string.text, sizeof(def_printer));
+ ippDelete(response);
+ return (def_printer);
+ }
+
+ ippDelete(response);
+ }
+ else
+ last_error = IPP_BAD_REQUEST;
+
+ return (NULL);
+}
+
+
+/*
+ * 'cupsGetJobs()' - Get the jobs from the server.
+ */
+
+int /* O - Number of jobs */
+cupsGetJobs(cups_job_t **jobs, /* O - Job data */
+ const char *mydest, /* I - Only show jobs for dest? */
+ int myjobs, /* I - Only show my jobs? */
+ int completed) /* I - Only show completed jobs? */
+{
+ int n; /* Number of jobs */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ cups_job_t *temp; /* Temporary pointer */
+ int id, /* job-id */
+ priority, /* job-priority */
+ size; /* job-k-octets */
+ ipp_jstate_t state; /* job-state */
+ time_t completed_time, /* time-at-completed */
+ creation_time, /* time-at-creation */
+ processing_time; /* time-at-processing */
+ const char *dest, /* job-printer-uri */
+ *format, /* document-format */
+ *title, /* job-name */
+ *user; /* job-originating-user-name */
+ char uri[HTTP_MAX_URI]; /* URI for jobs */
+ static const char *attrs[] = /* Requested attributes */
+ {
+ "job-id",
+ "job-priority",
+ "job-k-octets",
+ "job-state",
+ "time-at-completed",
+ "time-at-creation",
+ "time-at-processing",
+ "job-printer-uri",
+ "document-format",
+ "job-name",
+ "job-originating-user-name"
+ };
+
+
+ if (jobs == NULL)
+ {
+ last_error = IPP_INTERNAL_ERROR;
+ return (0);
+ }
+
+ /*
+ * Try to connect to the server...
+ */
+
+ if (!cups_connect("default", NULL, NULL))
+ {
+ last_error = IPP_SERVICE_UNAVAILABLE;
+ return (0);
+ }
+
+ /*
+ * Build an IPP_GET_JOBS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * requesting-user-name
+ * which-jobs
+ * my-jobs
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_JOBS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ if (mydest)
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", mydest);
+ else
+ strcpy(uri, "ipp://localhost/jobs");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+
+ if (myjobs)
+ ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
+
+ if (completed)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "which-jobs", NULL, "completed");
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(attrs) / sizeof(attrs[0]),
+ NULL, attrs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ n = 0;
+ *jobs = NULL;
+
+ if ((response = cupsDoRequest(cups_server, request, "/")) != NULL)
+ {
+ last_error = response->request.status.status_code;
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a job...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this job...
+ */
+
+ id = 0;
+ size = 0;
+ priority = 50;
+ state = IPP_JOB_PENDING;
+ user = "unknown";
+ dest = NULL;
+ format = "application/octet-stream";
+ title = "untitled";
+ creation_time = 0;
+ completed_time = 0;
+ processing_time = 0;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
+ {
+ if (strcmp(attr->name, "job-id") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ id = attr->values[0].integer;
+ else if (strcmp(attr->name, "job-state") == 0 &&
+ attr->value_tag == IPP_TAG_ENUM)
+ state = (ipp_jstate_t)attr->values[0].integer;
+ else if (strcmp(attr->name, "job-priority") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ priority = attr->values[0].integer;
+ else if (strcmp(attr->name, "job-k-octets") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ size = attr->values[0].integer;
+ else if (strcmp(attr->name, "time-at-completed") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ completed_time = attr->values[0].integer;
+ else if (strcmp(attr->name, "time-at-creation") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ creation_time = attr->values[0].integer;
+ else if (strcmp(attr->name, "time-at-processing") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ processing_time = attr->values[0].integer;
+ else if (strcmp(attr->name, "job-printer-uri") == 0 &&
+ attr->value_tag == IPP_TAG_URI)
+ {
+ if ((dest = strrchr(attr->values[0].string.text, '/')) != NULL)
+ dest ++;
+ }
+ else if (strcmp(attr->name, "job-originating-user-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ user = attr->values[0].string.text;
+ else if (strcmp(attr->name, "document-format") == 0 &&
+ attr->value_tag == IPP_TAG_MIMETYPE)
+ format = attr->values[0].string.text;
+ else if (strcmp(attr->name, "job-name") == 0 &&
+ (attr->value_tag == IPP_TAG_TEXT ||
+ attr->value_tag == IPP_TAG_NAME))
+ title = attr->values[0].string.text;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (dest == NULL || id == 0)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ /*
+ * Allocate memory for the job...
+ */
+
+ if (n == 0)
+ temp = malloc(sizeof(cups_job_t));
+ else
+ temp = realloc(*jobs, sizeof(cups_job_t) * (n + 1));
+
+ if (temp == NULL)
+ {
+ /*
+ * Ran out of memory!
+ */
+
+ cupsFreeJobs(n, *jobs);
+ *jobs = NULL;
+
+ ippDelete(response);
+ return (0);
+ }
+
+ *jobs = temp;
+ temp += n;
+ n ++;
+
+ /*
+ * Copy the data over...
+ */
+
+ temp->dest = strdup(dest);
+ temp->user = strdup(user);
+ temp->format = strdup(format);
+ temp->title = strdup(title);
+ temp->id = id;
+ temp->priority = priority;
+ temp->state = state;
+ temp->size = size;
+ temp->completed_time = completed_time;
+ temp->creation_time = creation_time;
+ temp->processing_time = processing_time;
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ last_error = IPP_BAD_REQUEST;
+
+ return (n);
+}
+
+
+/*
+ * 'cupsGetPPD()' - Get the PPD file for a printer.
+ */
+
+const char * /* O - Filename for PPD file */
+cupsGetPPD(const char *name) /* I - Printer name */
+{
+ int i; /* Looping var */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Local language */
+ int fd; /* PPD file */
+ int bytes; /* Number of bytes read */
+ char buffer[8192]; /* Buffer for file */
+ char printer[HTTP_MAX_URI], /* Printer name */
+ method[HTTP_MAX_URI], /* Method/scheme name */
+ username[HTTP_MAX_URI], /* Username:password */
+ hostname[HTTP_MAX_URI], /* Hostname */
+ resource[HTTP_MAX_URI]; /* Resource name */
+ int port; /* Port number */
+ const char *password; /* Password string */
+ char realm[HTTP_MAX_VALUE], /* realm="xyz" string */
+ nonce[HTTP_MAX_VALUE], /* nonce="xyz" string */
+ plain[255], /* Plaintext username:password */
+ encode[512]; /* Encoded username:password */
+ http_status_t status; /* HTTP status from server */
+ char prompt[1024]; /* Prompt string */
+ int digest_tries; /* Number of tries with Digest */
+ static char filename[HTTP_MAX_URI]; /* Local filename */
+ static const char *requested_attrs[] =/* Requested attributes */
+ {
+ "printer-uri-supported",
+ "printer-type",
+ "member-uris"
+ };
+
+
+ if (name == NULL)
+ {
+ last_error = IPP_INTERNAL_ERROR;
+ return (NULL);
+ }
+
+ /*
+ * See if we can connect to the server...
+ */
+
+ if (!cups_connect(name, printer, hostname))
+ {
+ last_error = IPP_SERVICE_UNAVAILABLE;
+ return (NULL);
+ }
+
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(buffer, sizeof(buffer), "ipp://localhost/printers/%s", printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, buffer);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requested-attributes",
+ sizeof(requested_attrs) / sizeof(requested_attrs[0]),
+ NULL, requested_attrs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(cups_server, request, "/")) != NULL)
+ {
+ last_error = response->request.status.status_code;
+ printer[0] = '\0';
+ hostname[0] = '\0';
+
+ if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL)
+ {
+ /*
+ * Get the first actual server and printer name in the class...
+ */
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ httpSeparate(attr->values[0].string.text, method, username, hostname,
+ &port, resource);
+ if (strncmp(resource, "/printers/", 10) == 0)
+ {
+ /*
+ * Found a printer!
+ */
+
+ strlcpy(printer, resource + 10, sizeof(printer));
+ break;
+ }
+ }
+ }
+ else if ((attr = ippFindAttribute(response, "printer-uri-supported",
+ IPP_TAG_URI)) != NULL)
+ {
+ /*
+ * Get the actual server and printer names...
+ */
+
+ httpSeparate(attr->values[0].string.text, method, username, hostname,
+ &port, resource);
+ strlcpy(printer, strrchr(resource, '/') + 1, sizeof(printer));
+ }
+
+ ippDelete(response);
+
+ /*
+ * Remap local hostname to localhost...
+ */
+
+ gethostname(buffer, sizeof(buffer));
+
+ if (strcasecmp(buffer, hostname) == 0)
+ strcpy(hostname, "localhost");
+ }
+
+ cupsLangFree(language);
+
+ if (!printer[0])
+ return (NULL);
+
+ /*
+ * Reconnect to the correct server as needed...
+ */
+
+ if (strcasecmp(cups_server->hostname, hostname) != 0)
+ {
+ httpClose(cups_server);
+
+ if ((cups_server = httpConnectEncrypt(hostname, ippPort(),
+ cupsEncryption())) == NULL)
+ {
+ last_error = IPP_SERVICE_UNAVAILABLE;
+ return (NULL);
+ }
+ }
+
+ /*
+ * Get a temp file...
+ */
+
+ if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
+ {
+ /*
+ * Can't open file; close the server connection and return NULL...
+ */
+
+ httpFlush(cups_server);
+ httpClose(cups_server);
+ cups_server = NULL;
+ return (NULL);
+ }
+
+ /*
+ * And send a request to the HTTP server...
+ */
+
+ snprintf(resource, sizeof(resource), "/printers/%s.ppd", printer);
+
+ digest_tries = 0;
+
+ do
+ {
+ httpClearFields(cups_server);
+ httpSetField(cups_server, HTTP_FIELD_HOST, hostname);
+ httpSetField(cups_server, HTTP_FIELD_AUTHORIZATION, authstring);
+
+ if (httpGet(cups_server, resource))
+ {
+ if (httpReconnect(cups_server))
+ {
+ status = HTTP_ERROR;
+ break;
+ }
+ else
+ {
+ status = HTTP_UNAUTHORIZED;
+ continue;
+ }
+ }
+
+ while ((status = httpUpdate(cups_server)) == HTTP_CONTINUE);
+
+ if (status == HTTP_UNAUTHORIZED)
+ {
+ DEBUG_puts("cupsGetPPD: unauthorized...");
+
+ /*
+ * Flush any error message...
+ */
+
+ httpFlush(cups_server);
+
+ /*
+ * See if we can do local authentication...
+ */
+
+ if (cups_local_auth(cups_server))
+ continue;
+
+ /*
+ * See if we should retry the current digest password...
+ */
+
+ if (strncmp(cups_server->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0 ||
+ digest_tries > 1 || !pwdstring[0])
+ {
+ /*
+ * Nope - get a password from the user...
+ */
+
+ snprintf(prompt, sizeof(prompt), "Password for %s on %s? ", cupsUser(),
+ cups_server->hostname);
+
+ if ((password = cupsGetPassword(prompt)) == NULL)
+ break;
+ if (!password[0])
+ break;
+
+ strlcpy(pwdstring, password, sizeof(pwdstring));
+
+ digest_tries = 0;
+ }
+ else
+ digest_tries ++;
+
+ /*
+ * Got a password; encode it for the server...
+ */
+
+ if (strncmp(cups_server->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0)
+ {
+ /*
+ * Basic authentication...
+ */
+
+ snprintf(plain, sizeof(plain), "%s:%s", cupsUser(), pwdstring);
+ httpEncode64(encode, plain);
+ snprintf(authstring, sizeof(authstring), "Basic %s", encode);
+ }
+ else
+ {
+ /*
+ * Digest authentication...
+ */
+
+ httpGetSubField(cups_server, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm);
+ httpGetSubField(cups_server, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce);
+
+ httpMD5(cupsUser(), realm, pwdstring, encode);
+ httpMD5Final(nonce, "GET", resource, encode);
+ snprintf(authstring, sizeof(authstring),
+ "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", "
+ "response=\"%s\"", cupsUser(), realm, nonce, encode);
+ }
+
+ continue;
+ }
+#ifdef HAVE_LIBSSL
+ else if (status == HTTP_UPGRADE_REQUIRED)
+ {
+ /*
+ * Flush any error message...
+ */
+
+ httpFlush(cups_server);
+
+ /*
+ * Upgrade with encryption...
+ */
+
+ httpEncryption(cups_server, HTTP_ENCRYPT_REQUIRED);
+
+ /*
+ * Try again, this time with encryption enabled...
+ */
+
+ continue;
+ }
+#endif /* HAVE_LIBSSL */
+ }
+ while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED);
+
+ /*
+ * See if we actually got the file or an error...
+ */
+
+ if (status != HTTP_OK)
+ {
+ unlink(filename);
+ httpFlush(cups_server);
+ httpClose(cups_server);
+ cups_server = NULL;
+ return (NULL);
+ }
+
+ /*
+ * OK, we need to copy the file...
+ */
+
+ while ((bytes = httpRead(cups_server, buffer, sizeof(buffer))) > 0)
+ write(fd, buffer, bytes);
+
+ close(fd);
+
+ return (filename);
+}
+
+
+/*
+ * 'cupsGetPrinters()' - Get a list of printers.
+ */
+
+int /* O - Number of printers */
+cupsGetPrinters(char ***printers) /* O - Printers */
+{
+ int n; /* Number of printers */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ char **temp; /* Temporary pointer */
+
+
+ if (printers == NULL)
+ {
+ last_error = IPP_INTERNAL_ERROR;
+ return (0);
+ }
+
+ /*
+ * Try to connect to the server...
+ */
+
+ if (!cups_connect("default", NULL, NULL))
+ {
+ last_error = IPP_SERVICE_UNAVAILABLE;
+ return (0);
+ }
+
+ /*
+ * Build a CUPS_GET_PRINTERS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_PRINTERS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", NULL, "printer-name");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ n = 0;
+ *printers = NULL;
+
+ if ((response = cupsDoRequest(cups_server, request, "/")) != NULL)
+ {
+ last_error = response->request.status.status_code;
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ if (attr->name != NULL &&
+ strcasecmp(attr->name, "printer-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ {
+ if (n == 0)
+ temp = malloc(sizeof(char *));
+ else
+ temp = realloc(*printers, sizeof(char *) * (n + 1));
+
+ if (temp == NULL)
+ {
+ /*
+ * Ran out of memory!
+ */
+
+ while (n > 0)
+ {
+ n --;
+ free((*printers)[n]);
+ }
+
+ free(*printers);
+ ippDelete(response);
+ return (0);
+ }
+
+ *printers = temp;
+ temp[n] = strdup(attr->values[0].string.text);
+ n ++;
+ }
+
+ ippDelete(response);
+ }
+ else
+ last_error = IPP_BAD_REQUEST;
+
+ return (n);
+}
+
+
+/*
+ * 'cupsLastError()' - Return the last IPP error that occurred.
+ */
+
+ipp_status_t /* O - IPP error code */
+cupsLastError(void)
+{
+ return (last_error);
+}
+
+
+/*
+ * 'cupsPrintFile()' - Print a file to a printer or class.
+ */
+
+int /* O - Job ID */
+cupsPrintFile(const char *name, /* I - Printer or class name */
+ const char *filename, /* I - File to print */
+ const char *title, /* I - Title of job */
+ int num_options,/* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ DEBUG_printf(("cupsPrintFile(\'%s\', \'%s\', %d, %p)\n",
+ name, filename, num_options, options));
+
+ return (cupsPrintFiles(name, 1, &filename, title, num_options, options));
+}
+
+
+/*
+ * 'cupsPrintFiles()' - Print one or more files to a printer or class.
+ */
+
+int /* O - Job ID */
+cupsPrintFiles(const char *name, /* I - Printer or class name */
+ int num_files, /* I - Number of files */
+ const char **files, /* I - File(s) to print */
+ const char *title, /* I - Title of job */
+ int num_options,/* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ int i; /* Looping var */
+ const char *val; /* Pointer to option value */
+ ipp_t *request; /* IPP request */
+ ipp_t *response; /* IPP response */
+ ipp_attribute_t *attr; /* IPP job-id attribute */
+ char hostname[HTTP_MAX_URI], /* Hostname */
+ printer[HTTP_MAX_URI], /* Printer or class name */
+ uri[HTTP_MAX_URI]; /* Printer URI */
+ cups_lang_t *language; /* Language to use */
+ int jobid; /* New job ID */
+
+
+ DEBUG_printf(("cupsPrintFiles(\'%s\', %d, %p, %d, %p)\n",
+ name, num_files, files, num_options, options));
+
+ if (name == NULL || num_files < 1 || files == NULL)
+ return (0);
+
+ /*
+ * Setup a connection and request data...
+ */
+
+ if (!cups_connect(name, printer, hostname))
+ {
+ DEBUG_printf(("cupsPrintFile: Unable to open connection - %s.\n",
+ strerror(errno)));
+ last_error = IPP_SERVICE_UNAVAILABLE;
+ return (0);
+ }
+
+ language = cupsLangDefault();
+
+ /*
+ * Build a standard CUPS URI for the printer and fill the standard IPP
+ * attributes...
+ */
+
+ if ((request = ippNew()) == NULL)
+ return (0);
+
+ request->request.op.operation_id = num_files == 1 ? IPP_PRINT_JOB :
+ IPP_CREATE_JOB;
+ request->request.op.request_id = 1;
+
+ snprintf(uri, sizeof(uri), "ipp://%s:%d/printers/%s", hostname, ippPort(), printer);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language != NULL ? language->language : "C");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, cupsUser());
+
+ if (title)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, title);
+
+ /*
+ * Then add all options...
+ */
+
+ cupsEncodeOptions(request, num_options, options);
+
+ /*
+ * Do the request...
+ */
+
+ snprintf(uri, sizeof(uri), "/printers/%s", printer);
+
+ if (num_files == 1)
+ response = cupsDoFileRequest(cups_server, request, uri, *files);
+ else
+ response = cupsDoRequest(cups_server, request, uri);
+
+ if (response == NULL)
+ jobid = 0;
+ else if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ DEBUG_printf(("IPP response code was 0x%x!\n",
+ response->request.status.status_code));
+ jobid = 0;
+ }
+ else if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL)
+ {
+ DEBUG_puts("No job ID!");
+ jobid = 0;
+ }
+ else
+ jobid = attr->values[0].integer;
+
+ if (response != NULL)
+ ippDelete(response);
+
+ /*
+ * Handle multiple file jobs if the create-job operation worked...
+ */
+
+ if (jobid > 0 && num_files > 1)
+ for (i = 0; i < num_files; i ++)
+ {
+ /*
+ * Build a standard CUPS URI for the job and fill the standard IPP
+ * attributes...
+ */
+
+ if ((request = ippNew()) == NULL)
+ return (0);
+
+ request->request.op.operation_id = IPP_SEND_DOCUMENT;
+ request->request.op.request_id = 1;
+
+ snprintf(uri, sizeof(uri), "ipp://%s:%d/jobs/%d", hostname, ippPort(),
+ jobid);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language != NULL ? language->language : "C");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
+ NULL, uri);
+
+ /*
+ * Handle raw print files...
+ */
+
+ if (cupsGetOption("raw", num_options, options))
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
+ NULL, "application/vnd.cups-raw");
+ else if ((val = cupsGetOption("document-format", num_options, options)) != NULL)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
+ NULL, val);
+ else
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
+ NULL, "application/octet-stream");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, cupsUser());
+
+ /*
+ * Is this the last document?
+ */
+
+ if (i == (num_files - 1))
+ ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1);
+
+ /*
+ * Send the file...
+ */
+
+ snprintf(uri, sizeof(uri), "/printers/%s", printer);
+
+ if ((response = cupsDoFileRequest(cups_server, request, uri,
+ files[i])) != NULL)
+ ippDelete(response);
+ }
+
+ return (jobid);
+}
+
+
+/*
+ * 'cups_connect()' - Connect to the specified host...
+ */
+
+static char * /* I - Printer name or NULL */
+cups_connect(const char *name, /* I - Destination (printer[@host]) */
+ char *printer, /* O - Printer name [HTTP_MAX_URI] */
+ char *hostname) /* O - Hostname [HTTP_MAX_URI] */
+{
+ char hostbuf[HTTP_MAX_URI]; /* Name of host */
+
+
+ DEBUG_printf(("cups_connect(\"%s\", %p, %p)\n", name, printer, hostname));
+
+ if (name == NULL)
+ {
+ last_error = IPP_BAD_REQUEST;
+ return (NULL);
+ }
+
+ /*
+ * All jobs are now queued to cupsServer() to avoid hostname
+ * resolution problems and to ensure that the user sees all
+ * locally queued jobs locally.
+ */
+
+ strlcpy(hostbuf, cupsServer(), sizeof(hostbuf));
+
+ if (hostname != NULL)
+ strlcpy(hostname, hostbuf, HTTP_MAX_URI);
+ else
+ hostname = hostbuf;
+
+ if (printer != NULL)
+ strlcpy(printer, name, HTTP_MAX_URI);
+ else
+ printer = (char *)name;
+
+ if (cups_server != NULL)
+ {
+ if (strcasecmp(cups_server->hostname, hostname) == 0)
+ return (printer);
+
+ httpClose(cups_server);
+ }
+
+ DEBUG_printf(("connecting to %s on port %d...\n", hostname, ippPort()));
+
+ if ((cups_server = httpConnectEncrypt(hostname, ippPort(),
+ cupsEncryption())) == NULL)
+ {
+ last_error = IPP_SERVICE_UNAVAILABLE;
+ return (NULL);
+ }
+ else
+ return (printer);
+}
+
+
+/*
+ * 'cups_local_auth()' - Get the local authorization certificate if
+ * available/applicable...
+ */
+
+static int /* O - 1 if available, 0 if not */
+cups_local_auth(http_t *http) /* I - Connection */
+{
+#if defined(WIN32) || defined(__EMX__)
+ /*
+ * Currently WIN32 and OS-2 do not support the CUPS server...
+ */
+
+ return (0);
+#else
+ int pid; /* Current process ID */
+ FILE *fp; /* Certificate file */
+ char filename[1024], /* Certificate filename */
+ certificate[33];/* Certificate string */
+ const char *root; /* Server root directory */
+
+
+ DEBUG_printf(("cups_local_auth(http=%p) hostaddr=%08x, hostname=\"%s\"\n",
+ http, ntohl(http->hostaddr.sin_addr.s_addr), http->hostname));
+
+ /*
+ * See if we are accessing localhost...
+ */
+
+ if (ntohl(http->hostaddr.sin_addr.s_addr) != 0x7f000001 &&
+ strcasecmp(http->hostname, "localhost") != 0)
+ {
+ DEBUG_puts("cups_local_auth: Not a local connection!");
+ return (0);
+ }
+
+ /*
+ * Try opening a certificate file for this PID. If that fails,
+ * try the root certificate...
+ */
+
+ if ((root = getenv("CUPS_SERVERROOT")) == NULL)
+ root = CUPS_SERVERROOT;
+
+ pid = getpid();
+ snprintf(filename, sizeof(filename), "%s/certs/%d", root, pid);
+ if ((fp = fopen(filename, "r")) == NULL && pid > 0)
+ {
+ DEBUG_printf(("cups_local_auth: Unable to open file %s: %s\n",
+ filename, strerror(errno)));
+
+ snprintf(filename, sizeof(filename), "%s/certs/0", root);
+ fp = fopen(filename, "r");
+ }
+
+ if (fp == NULL)
+ {
+ DEBUG_printf(("cups_local_auth: Unable to open file %s: %s\n",
+ filename, strerror(errno)));
+ return (0);
+ }
+
+ /*
+ * Read the certificate from the file...
+ */
+
+ fgets(certificate, sizeof(certificate), fp);
+ fclose(fp);
+
+ /*
+ * Set the authorization string and return...
+ */
+
+ snprintf(authstring, sizeof(authstring), "Local %s", certificate);
+
+ DEBUG_printf(("cups_local_auth: Returning authstring = \"%s\"\n",
+ authstring));
+
+ return (1);
+#endif /* WIN32 || __EMX__ */
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/data/HPGLprolog b/data/HPGLprolog
new file mode 100644
index 000000000..830458243
--- /dev/null
+++ b/data/HPGLprolog
@@ -0,0 +1,37 @@
+%%BeginResource: procset hpgltops 1.1 0
+%
+% "$Id: HPGLprolog 2010 2002-01-02 17:59:21Z mike $"
+%
+% HP-GL/2 filter procset for the Common UNIX Printing System (CUPS).
+%
+% This procset contains the basic drawing commands that are used to
+% reduce output size. Note the 'MP' (make newpath) definition - this
+% should be called 'NP' (newpath), but GhostScript uses the 'NP' name
+% for 'noaccess put' in some of its font files...
+%
+% Copyright 1993-2002 Easy Software Products
+%
+% These coded instructions, statements, and computer programs are the
+% property of Easy Software Products and are protected by Federal
+% copyright law. Distribution and use rights are outlined in the file
+% "LICENSE.txt" which should have been included with this file. If this
+% file is missing or damaged please contact Easy Software Products
+% at:
+%
+% Attn: CUPS Licensing Information
+% Easy Software Products
+% 44141 Airport View Drive, Suite 204
+% Hollywood, Maryland 20636-3111 USA
+%
+% Voice: (301) 373-9603
+% EMail: cups-info@cups.org
+% WWW: http://www.cups.org
+%
+/MO { moveto } bind def
+/LI { lineto } bind def
+/FI { fill } bind def
+/ST { stroke } bind def
+/CP { closepath } bind def
+/MP { newpath } bind def
+/SP { setlinewidth setrgbcolor } bind def
+%%EndResource
diff --git a/data/Makefile b/data/Makefile
new file mode 100644
index 000000000..e4499e684
--- /dev/null
+++ b/data/Makefile
@@ -0,0 +1,104 @@
+#
+# "$Id$"
+#
+# Datafile makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+#
+# Data files...
+#
+
+BANNERS = classified \
+ confidential \
+ secret \
+ standard \
+ topsecret \
+ unclassified
+
+CHARSETS = windows-874 \
+ windows-1250 \
+ windows-1251 \
+ windows-1252 \
+ windows-1253 \
+ windows-1254 \
+ windows-1255 \
+ windows-1256 \
+ windows-1257 \
+ windows-1258 \
+ koi8-r \
+ koi8-u \
+ iso-8859-1 \
+ iso-8859-2 \
+ iso-8859-3 \
+ iso-8859-4 \
+ iso-8859-5 \
+ iso-8859-6 \
+ iso-8859-7 \
+ iso-8859-8 \
+ iso-8859-9 \
+ iso-8859-10 \
+ iso-8859-13 \
+ iso-8859-14 \
+ iso-8859-15 \
+ koi8-r \
+ koi8-u \
+ utf-8
+DATAFILES = HPGLprolog psglyphs testprint.ps
+
+
+#
+# Make everything...
+#
+
+all:
+
+
+#
+# Clean all config and object files...
+#
+
+clean:
+
+
+#
+# Install files...
+#
+
+install:
+ $(INSTALL_DIR) $(DATADIR)/banners
+ for file in $(BANNERS); do \
+ $(INSTALL_DATA) $$file $(DATADIR)/banners; \
+ done
+ $(INSTALL_DIR) $(DATADIR)/charsets
+ for file in $(CHARSETS); do \
+ $(INSTALL_DATA) $$file $(DATADIR)/charsets; \
+ done
+ $(INSTALL_DIR) $(DATADIR)/data
+ for file in $(DATAFILES); do \
+ $(INSTALL_DATA) $$file $(DATADIR)/data; \
+ done
+
+
+#
+# End of "$Id$".
+#
diff --git a/data/classified b/data/classified
new file mode 100644
index 000000000..df921456f
--- /dev/null
+++ b/data/classified
@@ -0,0 +1,277 @@
+%!PS-Adobe-3.0
+%%BoundingBox: 0 0 612 792
+%%Pages: 1
+%%LanguageLevel: 1
+%%DocumentData: Clean7Bit
+%%DocumentSuppliedResources: procset bannerprint/1.0
+%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
+%%Creator: Michael Sweet, Easy Software Products
+%%CreationDate: May 10, 2000
+%%Title: Test Page
+%%EndComments
+%%BeginProlog
+%%BeginResource procset bannerprint 1.1 0
+%
+% PostScript banner page for the Common UNIX Printing System ("CUPS").
+%
+% Copyright 1993-2002 Easy Software Products
+%
+% These coded instructions, statements, and computer programs are the
+% property of Easy Software Products and are protected by Federal
+% copyright law. Distribution and use rights are outlined in the file
+% "LICENSE.txt" which should have been included with this file. If this
+% file is missing or damaged please contact Easy Software Products
+% at:
+%
+% Attn: CUPS Licensing Information
+% Easy Software Products
+% 44141 Airport View Drive, Suite 204
+% Hollywood, Maryland 20636-3111 USA
+%
+% Voice: (301) 373-9603
+% EMail: cups-info@cups.org
+% WWW: http://www.cups.org
+%
+/CENTER { % Draw centered text
+ % (name) CENTER -
+ dup stringwidth pop % Get the width of the string
+ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
+ show % Show the string
+} bind def
+/RIGHT { % Draw right-justified text
+ % (name) RIGHT -
+ dup stringwidth pop % Get the width of the string
+ neg 0 rmoveto % Shift left the entire distance
+ show % Show the string
+} bind def
+/NUMBER { % Draw a number
+ % power n NUMBER -
+ 1 index 1 eq { % power == 1?
+ round cvi exch pop % Convert "n" to integer
+ } {
+ 1 index mul round exch div % Truncate extra decimal places
+ } ifelse
+ 100 string cvs show % Convert to a string and show it...
+} bind def
+/CUPSLOGO { % Draw the CUPS logo
+ % height CUPSLOGO
+ % Start with a big C...
+ /Helvetica findfont 1 index scalefont setfont
+ 0 setgray
+ 0 0 moveto
+ (C) show
+
+ % Then "UNIX Printing System" much smaller...
+ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
+ 0.25 mul
+ dup dup 2.0 mul moveto
+ (UNIX) show
+ dup dup 1.6 mul moveto
+ (Printing) show
+ dup 1.2 mul moveto
+ (System) show
+} bind def
+/ESPLOGO { % Draw the ESP logo
+ % height ESPLOGO
+ % Compute the size of the logo...
+ 0 0
+ 2 index 1.5 mul 3 index
+
+ % Do the "metallic" fill from 10% black to 40% black...
+ 1 -0.001 0 {
+ dup % loopval
+ -0.15 mul % loopval * -0.15
+ 0.9 add % 0.9 - loopval * 0.15
+ setgray % set gray shade
+
+ 0 % x
+ 1 index neg % loopval
+ 1 add % 1 - loopval
+ 3 index % height
+ mul % height * (1 - loopval)
+ moveto % starting point
+
+ dup % loopval
+ 3 index % width
+ mul % loopval * width
+ 2 index % height
+ lineto % Next point
+
+ 0 % x
+ 2 index % height
+ lineto % Next point
+
+ closepath
+ fill
+
+ dup % loopval
+ 0.15 mul % loopval * 0.15
+ 0.6 add % 0.6 + loopval * 0.15
+ setgray
+
+ dup % loopval
+ neg 1 add % 1 - loopval
+ 3 index % width
+ mul % (1 - loopval) * width
+ 0 % y
+ moveto % Starting point
+
+ 2 index % width
+ exch % loopval
+ 2 index % height
+ mul % loopval * height
+ lineto % Next point
+
+ 1 index % width
+ 0 % y
+ lineto % Next point
+
+ closepath
+ fill
+ } for
+
+ 0 setgray rectstroke
+
+ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
+ dup 40 div
+
+ dup 4 mul 1 index 25 mul moveto (E) show
+ dup 10 mul 1 index 15 mul moveto (S) show
+ dup 16 mul 1 index 5 mul moveto (P) show
+
+ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
+ dup 14 mul 1 index 29 mul moveto (asy) show
+ dup 20 mul 1 index 19 mul moveto (oftware) show
+ dup 26 mul 1 index 9 mul moveto (roducts) show
+
+ pop
+} bind def
+%%EndResource
+%%EndProlog
+%%Page: 1 1
+gsave
+
+ % Determine the imageable area and device resolution...
+ initclip newpath clippath pathbbox % Get bounding rectangle
+ 72 div /pageTop exch def % Get top margin in inches
+ 72 div /pageRight exch def % Get right margin in inches
+ 72 div /pageBottom exch def % Get bottom margin in inches
+ 72 div /pageLeft exch def % Get left margin in inches
+
+ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
+ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
+
+ /boxWidth % width of text box
+ pageWidth pageHeight lt
+ { pageWidth 54 mul }
+ { pageHeight 42 mul }
+ ifelse def
+
+ newpath % Clear bounding path
+
+ % Create fonts...
+ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
+ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
+
+ /mediumFont /Helvetica findfont % mediumFont = Helvetica
+ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
+
+ % Offset page to account for lower-left margin...
+ pageLeft 72 mul
+ pageBottom 72 mul
+ translate
+
+ % Draw the label at the top and bottom...
+ 0 setgray % Color
+
+ pageWidth 36 mul % Center of page
+ pageHeight 72 mul % Top of page
+ pageWidth -7 mul add % - 2 lines
+ moveto % Position text
+ bigFont setfont % Font
+ (Classified) CENTER % Show text centered
+
+ pageWidth 36 mul % Center of page
+ pageHeight 6 mul % Bottom of page
+ moveto % Position text
+ bigFont setfont % Font
+ (Classified) CENTER % Show text centered
+
+ % Job information box...
+ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+ 0.5 setgray rectfill % Draw a shadow
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul % y = pageHeight * 1/4 * 72
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+
+ 4 copy 1 setgray rectfill % Clear the box to white
+ 0 setgray rectstroke % Draw a black box around it...
+
+ % Job information text...
+ mediumFont setfont % Medium sized font
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 5 mul add % y += 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Job ID: ) RIGHT
+ moveto
+ ({printer-name}-{job-id}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 2 mul add % y += 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Title: ) RIGHT
+ moveto
+ ({job-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -1 mul add % y -= 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Requesting User: ) RIGHT
+ moveto
+ ({job-originating-user-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -4 mul add % y -= 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Billing Info: ) RIGHT
+ moveto
+ ({?job-billing}) show
+
+ % Then the CUPS logo....
+ gsave
+ pageWidth 4 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 9 mul CUPSLOGO
+ grestore
+
+ % And the ESP logo....
+ gsave
+ pageWidth 59 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 6 mul ESPLOGO
+ grestore
+% Show the page...
+grestore
+showpage
+%
+% End of "$Id: classified 2122 2002-01-31 14:19:37Z mike $".
+%
+%%EOF
diff --git a/data/confidential b/data/confidential
new file mode 100644
index 000000000..48744d6ef
--- /dev/null
+++ b/data/confidential
@@ -0,0 +1,277 @@
+%!PS-Adobe-3.0
+%%BoundingBox: 0 0 612 792
+%%Pages: 1
+%%LanguageLevel: 1
+%%DocumentData: Clean7Bit
+%%DocumentSuppliedResources: procset bannerprint/1.0
+%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
+%%Creator: Michael Sweet, Easy Software Products
+%%CreationDate: May 10, 2000
+%%Title: Test Page
+%%EndComments
+%%BeginProlog
+%%BeginResource procset bannerprint 1.1 0
+%
+% PostScript banner page for the Common UNIX Printing System ("CUPS").
+%
+% Copyright 1993-2002 Easy Software Products
+%
+% These coded instructions, statements, and computer programs are the
+% property of Easy Software Products and are protected by Federal
+% copyright law. Distribution and use rights are outlined in the file
+% "LICENSE.txt" which should have been included with this file. If this
+% file is missing or damaged please contact Easy Software Products
+% at:
+%
+% Attn: CUPS Licensing Information
+% Easy Software Products
+% 44141 Airport View Drive, Suite 204
+% Hollywood, Maryland 20636-3111 USA
+%
+% Voice: (301) 373-9603
+% EMail: cups-info@cups.org
+% WWW: http://www.cups.org
+%
+/CENTER { % Draw centered text
+ % (name) CENTER -
+ dup stringwidth pop % Get the width of the string
+ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
+ show % Show the string
+} bind def
+/RIGHT { % Draw right-justified text
+ % (name) RIGHT -
+ dup stringwidth pop % Get the width of the string
+ neg 0 rmoveto % Shift left the entire distance
+ show % Show the string
+} bind def
+/NUMBER { % Draw a number
+ % power n NUMBER -
+ 1 index 1 eq { % power == 1?
+ round cvi exch pop % Convert "n" to integer
+ } {
+ 1 index mul round exch div % Truncate extra decimal places
+ } ifelse
+ 100 string cvs show % Convert to a string and show it...
+} bind def
+/CUPSLOGO { % Draw the CUPS logo
+ % height CUPSLOGO
+ % Start with a big C...
+ /Helvetica findfont 1 index scalefont setfont
+ 0 setgray
+ 0 0 moveto
+ (C) show
+
+ % Then "UNIX Printing System" much smaller...
+ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
+ 0.25 mul
+ dup dup 2.0 mul moveto
+ (UNIX) show
+ dup dup 1.6 mul moveto
+ (Printing) show
+ dup 1.2 mul moveto
+ (System) show
+} bind def
+/ESPLOGO { % Draw the ESP logo
+ % height ESPLOGO
+ % Compute the size of the logo...
+ 0 0
+ 2 index 1.5 mul 3 index
+
+ % Do the "metallic" fill from 10% black to 40% black...
+ 1 -0.001 0 {
+ dup % loopval
+ -0.15 mul % loopval * -0.15
+ 0.9 add % 0.9 - loopval * 0.15
+ setgray % set gray shade
+
+ 0 % x
+ 1 index neg % loopval
+ 1 add % 1 - loopval
+ 3 index % height
+ mul % height * (1 - loopval)
+ moveto % starting point
+
+ dup % loopval
+ 3 index % width
+ mul % loopval * width
+ 2 index % height
+ lineto % Next point
+
+ 0 % x
+ 2 index % height
+ lineto % Next point
+
+ closepath
+ fill
+
+ dup % loopval
+ 0.15 mul % loopval * 0.15
+ 0.6 add % 0.6 + loopval * 0.15
+ setgray
+
+ dup % loopval
+ neg 1 add % 1 - loopval
+ 3 index % width
+ mul % (1 - loopval) * width
+ 0 % y
+ moveto % Starting point
+
+ 2 index % width
+ exch % loopval
+ 2 index % height
+ mul % loopval * height
+ lineto % Next point
+
+ 1 index % width
+ 0 % y
+ lineto % Next point
+
+ closepath
+ fill
+ } for
+
+ 0 setgray rectstroke
+
+ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
+ dup 40 div
+
+ dup 4 mul 1 index 25 mul moveto (E) show
+ dup 10 mul 1 index 15 mul moveto (S) show
+ dup 16 mul 1 index 5 mul moveto (P) show
+
+ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
+ dup 14 mul 1 index 29 mul moveto (asy) show
+ dup 20 mul 1 index 19 mul moveto (oftware) show
+ dup 26 mul 1 index 9 mul moveto (roducts) show
+
+ pop
+} bind def
+%%EndResource
+%%EndProlog
+%%Page: 1 1
+gsave
+
+ % Determine the imageable area and device resolution...
+ initclip newpath clippath pathbbox % Get bounding rectangle
+ 72 div /pageTop exch def % Get top margin in inches
+ 72 div /pageRight exch def % Get right margin in inches
+ 72 div /pageBottom exch def % Get bottom margin in inches
+ 72 div /pageLeft exch def % Get left margin in inches
+
+ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
+ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
+
+ /boxWidth % width of text box
+ pageWidth pageHeight lt
+ { pageWidth 54 mul }
+ { pageHeight 42 mul }
+ ifelse def
+
+ newpath % Clear bounding path
+
+ % Create fonts...
+ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
+ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
+
+ /mediumFont /Helvetica findfont % mediumFont = Helvetica
+ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
+
+ % Offset page to account for lower-left margin...
+ pageLeft 72 mul
+ pageBottom 72 mul
+ translate
+
+ % Draw the label at the top and bottom...
+ 0 setgray % Color
+
+ pageWidth 36 mul % Center of page
+ pageHeight 72 mul % Top of page
+ pageWidth -7 mul add % - 2 lines
+ moveto % Position text
+ bigFont setfont % Font
+ (Confidential) CENTER % Show text centered
+
+ pageWidth 36 mul % Center of page
+ pageHeight 6 mul % Bottom of page
+ moveto % Position text
+ bigFont setfont % Font
+ (Confidential) CENTER % Show text centered
+
+ % Job information box...
+ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+ 0.5 setgray rectfill % Draw a shadow
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul % y = pageHeight * 1/4 * 72
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+
+ 4 copy 1 setgray rectfill % Clear the box to white
+ 0 setgray rectstroke % Draw a black box around it...
+
+ % Job information text...
+ mediumFont setfont % Medium sized font
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 5 mul add % y += 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Job ID: ) RIGHT
+ moveto
+ ({printer-name}-{job-id}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 2 mul add % y += 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Title: ) RIGHT
+ moveto
+ ({job-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -1 mul add % y -= 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Requesting User: ) RIGHT
+ moveto
+ ({job-originating-user-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -4 mul add % y -= 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Billing Info: ) RIGHT
+ moveto
+ ({?job-billing}) show
+
+ % Then the CUPS logo....
+ gsave
+ pageWidth 4 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 9 mul CUPSLOGO
+ grestore
+
+ % And the ESP logo....
+ gsave
+ pageWidth 59 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 6 mul ESPLOGO
+ grestore
+% Show the page...
+grestore
+showpage
+%
+% End of "$Id: confidential 2122 2002-01-31 14:19:37Z mike $".
+%
+%%EOF
diff --git a/data/iso-8859-1 b/data/iso-8859-1
new file mode 100644
index 000000000..057d8aee3
--- /dev/null
+++ b/data/iso-8859-1
@@ -0,0 +1,251 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-1
+# (Latin1/West European) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 00A1
+A2 00A2
+A3 00A3
+A4 00A4
+A5 00A5
+A6 00A6
+A7 00A7
+A8 00A8
+A9 00A9
+AA 00AA
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 00AF
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 00B4
+B5 00B5
+B6 00B6
+B7 00B7
+B8 00B8
+B9 00B9
+BA 00BA
+BB 00BB
+BC 00BC
+BD 00BD
+BE 00BE
+BF 00BF
+C0 00C0
+C1 00C1
+C2 00C2
+C3 00C3
+C4 00C4
+C5 00C5
+C6 00C6
+C7 00C7
+C8 00C8
+C9 00C9
+CA 00CA
+CB 00CB
+CC 00CC
+CD 00CD
+CE 00CE
+CF 00CF
+D0 00D0
+D1 00D1
+D2 00D2
+D3 00D3
+D4 00D4
+D5 00D5
+D6 00D6
+D7 00D7
+D8 00D8
+D9 00D9
+DA 00DA
+DB 00DB
+DC 00DC
+DD 00DD
+DE 00DE
+DF 00DF
+E0 00E0
+E1 00E1
+E2 00E2
+E3 00E3
+E4 00E4
+E5 00E5
+E6 00E6
+E7 00E7
+E8 00E8
+E9 00E9
+EA 00EA
+EB 00EB
+EC 00EC
+ED 00ED
+EE 00EE
+EF 00EF
+F0 00F0
+F1 00F1
+F2 00F2
+F3 00F3
+F4 00F4
+F5 00F5
+F6 00F6
+F7 00F7
+F8 00F8
+F9 00F9
+FA 00FA
+FB 00FB
+FC 00FC
+FD 00FD
+FE 00FE
+FF 00FF
diff --git a/data/iso-8859-10 b/data/iso-8859-10
new file mode 100644
index 000000000..31f55552e
--- /dev/null
+++ b/data/iso-8859-10
@@ -0,0 +1,251 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-10
+# (Latin6/Nordic) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 0104
+A2 0112
+A3 0122
+A4 012A
+A5 0128
+A6 0136
+A7 00A7
+A8 013B
+A9 0110
+AA 0160
+AB 0166
+AC 017D
+AD 00AD
+AE 016A
+AF 014A
+B0 00B0
+B1 0105
+B2 0113
+B3 0123
+B4 012B
+B5 0129
+B6 0137
+B7 00B7
+B8 013C
+B9 0111
+BA 0161
+BB 0167
+BC 017E
+BD 2015
+BE 016B
+BF 014B
+C0 0100
+C1 00C1
+C2 00C2
+C3 00C3
+C4 00C4
+C5 00C5
+C6 00C6
+C7 012E
+C8 010C
+C9 00C9
+CA 0118
+CB 00CB
+CC 0116
+CD 00CD
+CE 00CE
+CF 00CF
+D0 0110
+D1 0145
+D2 014C
+D3 00D3
+D4 00D4
+D5 00D5
+D6 00D6
+D7 0168
+D8 00D8
+D9 0172
+DA 00DA
+DB 00DB
+DC 00DC
+DD 00DD
+DE 00DE
+DF 00DF
+E0 0101
+E1 00E1
+E2 00E2
+E3 00E3
+E4 00E4
+E5 00E5
+E6 00E6
+E7 012F
+E8 010D
+E9 00E9
+EA 0119
+EB 00EB
+EC 0117
+ED 00ED
+EE 00EE
+EF 00EF
+F0 00F0
+F1 0146
+F2 014D
+F3 00F3
+F4 00F4
+F5 00F5
+F6 00F6
+F7 0169
+F8 00F8
+F9 0173
+FA 00FA
+FB 00FB
+FC 00FC
+FD 00FD
+FE 00FD
+FF 0138
diff --git a/data/iso-8859-13 b/data/iso-8859-13
new file mode 100644
index 000000000..dcfacca9d
--- /dev/null
+++ b/data/iso-8859-13
@@ -0,0 +1,251 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-13
+# (Latin7/Baltic Rim) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 201D
+A2 00A2
+A3 00A3
+A4 00A4
+A5 201E
+A6 00A6
+A7 00A7
+A8 00D8
+A9 00A9
+AA 0156
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 00C6
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 201C
+B5 00B5
+B6 00B6
+B7 00B7
+B8 00F8
+B9 00B9
+BA 0157
+BB 00BB
+BC 00BC
+BD 00BD
+BE 00BE
+BF 00E6
+C0 0104
+C1 012E
+C2 0100
+C3 0106
+C4 00C4
+C5 00C5
+C6 0118
+C7 0112
+C8 010C
+C9 00C9
+CA 0179
+CB 0116
+CC 0122
+CD 0136
+CE 012A
+CF 013B
+D0 0160
+D1 0143
+D2 0145
+D3 00D3
+D4 014C
+D5 00D5
+D6 00D6
+D7 00D7
+D8 0172
+D9 0141
+DA 015A
+DB 016A
+DC 00DC
+DD 017B
+DE 017D
+DF 00DF
+E0 0105
+E1 012F
+E2 0101
+E3 0107
+E4 00E4
+E5 00E5
+E6 0119
+E7 0113
+E8 010D
+E9 00E9
+EA 017A
+EB 0117
+EC 0123
+ED 0137
+EE 012B
+EF 013C
+F0 0161
+F1 0144
+F2 0146
+F3 00F3
+F4 014D
+F5 00F5
+F6 00F6
+F7 00F7
+F8 0173
+F9 0142
+FA 015B
+FB 016B
+FC 00FC
+FD 017C
+FE 017E
+FF 2019
diff --git a/data/iso-8859-14 b/data/iso-8859-14
new file mode 100644
index 000000000..ca0097a47
--- /dev/null
+++ b/data/iso-8859-14
@@ -0,0 +1,251 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-14
+# (Latin8/Celtic) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 1E02
+A2 1E03
+A3 00A3
+A4 010A
+A5 010B
+A6 1E0A
+A7 00A7
+A8 1E80
+A9 00A9
+AA 1E82
+AB 1E0B
+AC 1EF2
+AD 00AD
+AE 00AE
+AF 0178
+B0 1E1E
+B1 1E1F
+B2 0120
+B3 0121
+B4 1E40
+B5 1E41
+B6 00B6
+B7 1E56
+B8 1E81
+B9 1E57
+BA 1E83
+BB 1E60
+BC 1EF3
+BD 1E84
+BE 1E85
+BF 1E61
+C0 00C0
+C1 00C1
+C2 00C2
+C3 00C3
+C4 00C4
+C5 00C5
+C6 00C6
+C7 00C7
+C8 00C8
+C9 00C9
+CA 00CA
+CB 00CB
+CC 00CC
+CD 00CD
+CE 00CE
+CF 00CF
+D0 0174
+D1 00D1
+D2 00D2
+D3 00D3
+D4 00D4
+D5 00D5
+D6 00D6
+D7 1E6A
+D8 00D8
+D9 00D9
+DA 00DA
+DB 00DB
+DC 00DC
+DD 00DD
+DE 0176
+DF 00DF
+E0 00E0
+E1 00E1
+E2 00E2
+E3 00E3
+E4 00E4
+E5 00E5
+E6 00E6
+E7 00E7
+E8 00E8
+E9 00E9
+EA 00EA
+EB 00EB
+EC 00EC
+ED 00ED
+EE 00EE
+EF 00EF
+F0 0175
+F1 00F1
+F2 00F2
+F3 00F3
+F4 00F4
+F5 00F5
+F6 00F6
+F7 1E6B
+F8 00F8
+F9 00F9
+FA 00FA
+FB 00FB
+FC 00FC
+FD 00FD
+FE 0177
+FF 00FF
diff --git a/data/iso-8859-15 b/data/iso-8859-15
new file mode 100644
index 000000000..334160f4f
--- /dev/null
+++ b/data/iso-8859-15
@@ -0,0 +1,251 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-15
+# (Latin9/West Europe + Euro) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 00A1
+A2 00A2
+A3 00A3
+A4 20AC
+A5 00A5
+A6 0160
+A7 00A7
+A8 0161
+A9 00A9
+AA 00AA
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 00AF
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 017D
+B5 00B5
+B6 00B6
+B7 00B7
+B8 017E
+B9 00B9
+BA 00BA
+BB 00BB
+BC 0152
+BD 0153
+BE 0178
+BF 00BF
+C0 00C0
+C1 00C1
+C2 00C2
+C3 00C3
+C4 00C4
+C5 00C5
+C6 00C6
+C7 00C7
+C8 00C8
+C9 00C9
+CA 00CA
+CB 00CB
+CC 00CC
+CD 00CD
+CE 00CE
+CF 00CF
+D0 00D0
+D1 00D1
+D2 00D2
+D3 00D3
+D4 00D4
+D5 00D5
+D6 00D6
+D7 00D7
+D8 00D8
+D9 00D9
+DA 00DA
+DB 00DB
+DC 00DC
+DD 00DD
+DE 00DE
+DF 00DF
+E0 00E0
+E1 00E1
+E2 00E2
+E3 00E3
+E4 00E4
+E5 00E5
+E6 00E6
+E7 00E7
+E8 00E8
+E9 00E9
+EA 00EA
+EB 00EB
+EC 00EC
+ED 00ED
+EE 00EE
+EF 00EF
+F0 00F0
+F1 00F1
+F2 00F2
+F3 00F3
+F4 00F4
+F5 00F5
+F6 00F6
+F7 00F7
+F8 00F8
+F9 00F9
+FA 00FA
+FB 00FB
+FC 00FC
+FD 00FD
+FE 00FE
+FF 00FF
diff --git a/data/iso-8859-2 b/data/iso-8859-2
new file mode 100644
index 000000000..19b77878d
--- /dev/null
+++ b/data/iso-8859-2
@@ -0,0 +1,253 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-2
+# (Latin2/East European) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+84 201E
+85 2026
+86 2020
+87 2021
+89 2030
+8A 0160
+8B 2039
+8C 015A
+8D 0164
+8E 017D
+8F 0179
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+99 2122
+9A 0161
+9B 203A
+8C 015B
+8D 0165
+8E 017E
+8F 017A
+A0 00A0
+A1 0104
+A2 02D8
+A3 0141
+A4 00A4
+A5 013D
+A6 015A
+A7 00A7
+A8 00A8
+A9 0160
+AA 015E
+AB 0164
+AC 0179
+AD 00AD
+AE 017D
+AF 017B
+B0 00B0
+B1 0105
+B2 02DB
+B3 0142
+B4 00B4
+B5 013E
+B6 015B
+B7 02C7
+B8 00B8
+B9 0161
+BA 015F
+BB 0165
+BC 017A
+BD 02DD
+BE 017E
+BF 017C
+C0 0154
+C1 00C1
+C2 00C2
+C3 0102
+C4 00C4
+C5 0139
+C6 0106
+C7 00C7
+C8 010C
+C9 00C9
+CA 0118
+CB 00CB
+CC 011A
+CD 00CD
+CE 00CE
+CF 010E
+D0 0110
+D1 0143
+D2 0147
+D3 00D3
+D4 00D4
+D5 0150
+D6 00D6
+D7 00D7
+D8 0158
+D9 016E
+DA 00DA
+DB 0170
+DC 00DC
+DD 00DD
+DE 0162
+DF 00DF
+E0 0155
+E1 00E1
+E2 00E2
+E3 0103
+E4 00E4
+E5 013A
+E6 0107
+E7 00E7
+E8 010D
+E9 00E9
+EA 0119
+EB 00EB
+EC 011B
+ED 00ED
+EE 00EE
+EF 010F
+F0 0111
+F1 0144
+F2 0148
+F3 00F3
+F4 00F4
+F5 0151
+F6 00F6
+F7 00F7
+F8 0159
+F9 016F
+FA 00FA
+FB 0171
+FC 00FC
+FD 00FD
+FE 0163
+FF 02D9
diff --git a/data/iso-8859-3 b/data/iso-8859-3
new file mode 100644
index 000000000..efc4529ed
--- /dev/null
+++ b/data/iso-8859-3
@@ -0,0 +1,244 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-3
+# (Latin3/South European) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 0126
+A2 02D8
+A3 00A3
+A4 00A4
+A6 0124
+A7 00A7
+A8 00A8
+A9 0130
+AA 015E
+AB 011E
+AC 0134
+AD 00AD
+AF 017B
+B0 00B0
+B1 0127
+B2 00B2
+B3 00B3
+B4 00B4
+B5 00B5
+B6 0125
+B7 00B7
+B8 00B8
+B9 0131
+BA 015F
+BB 011F
+BC 0135
+BD 00BD
+BF 017C
+C0 00C0
+C1 00C1
+C2 00C2
+C4 00C4
+C5 010A
+C6 0108
+C7 00C7
+C8 00C8
+C9 00C9
+CA 00CA
+CB 00CB
+CC 00CC
+CD 00CD
+CE 00CE
+CF 00CF
+D1 00D1
+D2 00D2
+D3 00D3
+D4 00D4
+D5 0120
+D6 00D6
+D7 00D7
+D8 011C
+D9 00D9
+DA 00DA
+DB 00DB
+DC 00DC
+DD 016C
+DE 015C
+DF 00DF
+E0 00E0
+E1 00E1
+E2 00E2
+E4 00E4
+E5 010B
+E6 0109
+E7 00E7
+E8 00E8
+E9 00E9
+EA 00EA
+EB 00EB
+EC 00EC
+ED 00ED
+EE 00EE
+EF 00EF
+F1 00F1
+F2 00F2
+F3 00F3
+F4 00F4
+F5 0121
+F6 00F6
+F7 00F7
+F8 011D
+F9 00F9
+FA 00FA
+FB 00FB
+FC 00FC
+FD 016D
+FE 015D
+FF 02D9
diff --git a/data/iso-8859-4 b/data/iso-8859-4
new file mode 100644
index 000000000..5c93156eb
--- /dev/null
+++ b/data/iso-8859-4
@@ -0,0 +1,251 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-4
+# (Latin4/North European) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 0104
+A2 0138
+A3 0156
+A4 00A4
+A5 0128
+A6 013B
+A7 00A7
+A8 00A8
+A9 0160
+AA 0112
+AB 0122
+AC 0166
+AD 00AD
+AE 017D
+AF 00AF
+B0 00B0
+B1 0105
+B2 02DB
+B3 0157
+B4 00B4
+B5 0129
+B6 013C
+B7 02C7
+B8 00B8
+B9 0161
+BA 0113
+BB 0123
+BC 0167
+BD 014A
+BE 017E
+BF 014B
+C0 0100
+C1 00C1
+C2 00C2
+C3 00C3
+C4 00C4
+C5 00C5
+C6 00C6
+C7 012E
+C8 010C
+C9 00C9
+CA 0118
+CB 00CB
+CC 0116
+CD 00CD
+CE 00CE
+CF 012A
+D0 0110
+D1 0145
+D2 014C
+D3 0136
+D4 00D4
+D5 00D5
+D6 00D6
+D7 00D7
+D8 00D8
+D9 0172
+DA 00DA
+DB 00DB
+DC 00DC
+DD 0168
+DE 016A
+DF 00DF
+E0 0101
+E1 00E1
+E2 00E2
+E3 00E3
+E4 00E4
+E5 00E5
+E6 00E6
+E7 012F
+E8 010D
+E9 00E9
+EA 0119
+EB 00EB
+EC 0117
+ED 00ED
+EE 00EE
+EF 012B
+F0 0111
+F1 0146
+F2 014D
+F3 0137
+F4 00F4
+F5 00F5
+F6 00F6
+F7 00F7
+F8 00F8
+F9 0173
+FA 00FA
+FB 00FB
+FC 00FC
+FD 0169
+FE 016B
+FF 02D9
diff --git a/data/iso-8859-5 b/data/iso-8859-5
new file mode 100644
index 000000000..59ee84d57
--- /dev/null
+++ b/data/iso-8859-5
@@ -0,0 +1,251 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-5
+# (Cyrillic) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 0401
+A2 0402
+A3 0403
+A4 0404
+A5 0405
+A6 0406
+A7 0407
+A8 0408
+A9 0409
+AA 040A
+AB 040B
+AC 040C
+AD 00AD
+AE 040E
+AF 040F
+B0 0410
+B1 0411
+B2 0412
+B3 0413
+B4 0414
+B5 0415
+B6 0416
+B7 0417
+B8 0418
+B9 0419
+BA 041A
+BB 041B
+BC 041C
+BD 041D
+BE 041E
+BF 041F
+C0 0420
+C1 0421
+C2 0422
+C3 0423
+C4 0424
+C5 0425
+C6 0426
+C7 0427
+C8 0428
+C9 0429
+CA 042A
+CB 042B
+CC 042C
+CD 042D
+CE 042E
+CF 042F
+D0 0430
+D1 0431
+D2 0432
+D3 0433
+D4 0434
+D5 0435
+D6 0436
+D7 0437
+D8 0438
+D9 0439
+DA 043A
+DB 043B
+DC 043C
+DD 043D
+DE 043E
+DF 043F
+E0 0440
+E1 0441
+E2 0442
+E3 0443
+E4 0444
+E5 0445
+E6 0446
+E7 0447
+E8 0448
+E9 0449
+EA 044A
+EB 044B
+EC 044C
+ED 044D
+EE 044E
+EF 044F
+F0 2116
+F1 0451
+F2 0452
+F3 0453
+F4 0454
+F5 0455
+F6 0456
+F7 0457
+F8 0458
+F9 0459
+FA 045A
+FB 045B
+FC 045C
+FD 00A7
+FE 045E
+FF 045F
diff --git a/data/iso-8859-6 b/data/iso-8859-6
new file mode 100644
index 000000000..356fe72e3
--- /dev/null
+++ b/data/iso-8859-6
@@ -0,0 +1,206 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-6
+# (Arabic) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff rtol single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0660
+31 0661
+32 0662
+33 0663
+34 0664
+35 0665
+36 0666
+37 0667
+38 0668
+39 0669
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A4 00A4
+AC 060C
+AD 00AD
+BB 061B
+BF 061F
+C1 0621
+C2 0622
+C3 0623
+C4 0624
+C5 0625
+C6 0626
+C7 0627
+C8 0628
+C9 0629
+CA 062A
+CB 062B
+CC 062C
+CD 062D
+CE 062E
+CF 062F
+D0 0630
+D1 0631
+D2 0632
+D3 0633
+D4 0634
+D5 0635
+D6 0636
+D7 0637
+D8 0638
+D9 0639
+DA 063A
+E0 0640
+E1 0641
+E2 0642
+E3 0643
+E4 0644
+E5 0645
+E6 0646
+E7 0647
+E8 0648
+E9 0649
+EA 064A
+EB 064B
+EC 064C
+ED 064D
+EE 064E
+EF 064F
+F0 0650
+F1 0651
+F2 0652
diff --git a/data/iso-8859-7 b/data/iso-8859-7
new file mode 100644
index 000000000..57647841c
--- /dev/null
+++ b/data/iso-8859-7
@@ -0,0 +1,246 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-7
+# (Greek) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 9f ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+a0 ff ltor single Symbol
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 02BD
+A2 02BC
+A3 00A3
+A6 00A6
+A7 00A7
+A8 00A8
+A9 00A9
+AB 00AB
+AC 00AC
+AD 00AD
+AF 2015
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 0384
+B5 0385
+B6 0386
+B7 00B7
+B8 0388
+B9 0389
+BA 038A
+BB 00BB
+BC 038C
+BD 00BD
+BE 038E
+BF 038F
+C0 0390
+C1 0391
+C2 0392
+C3 0393
+C4 0394
+C5 0395
+C6 0396
+C7 0397
+C8 0398
+C9 0399
+CA 039A
+CB 039B
+CC 039C
+CD 039D
+CE 039E
+CF 039F
+D0 03A0
+D1 03A1
+D3 03A3
+D4 03A4
+D5 03A5
+D6 03A6
+D7 03A7
+D8 03A8
+D9 03A9
+DA 03AA
+DB 03AB
+DC 03AC
+DD 03AD
+DE 03AE
+DF 03AF
+E0 03B0
+E1 03B1
+E2 03B2
+E3 03B3
+E4 03B4
+E5 03B5
+E6 03B6
+E7 03B7
+E8 03B8
+E9 03B9
+EA 03BA
+EB 03BB
+EC 03BC
+ED 03BD
+EE 03BE
+EF 03BF
+F0 03C0
+F1 03C1
+F2 03C2
+F3 03C3
+F4 03C4
+F5 03C5
+F6 03C6
+F7 03C7
+F8 03C8
+F9 03C9
+FA 03CA
+FB 03CB
+FC 03CC
+FD 03CD
+FE 03CE
diff --git a/data/iso-8859-8 b/data/iso-8859-8
new file mode 100644
index 000000000..660122d6a
--- /dev/null
+++ b/data/iso-8859-8
@@ -0,0 +1,214 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-8
+# (Hebrew) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 7f ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+80 ff rtol single Courier
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A2 00A2
+A3 00A3
+A4 00A4
+A5 00A5
+A6 00A6
+A7 00A7
+A8 00A8
+A9 00A9
+AA 00D7
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 203E
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 00B4
+B5 00B5
+B6 00B6
+B7 00B7
+B8 00B8
+B9 00B9
+BA 00F7
+BB 00BB
+BC 00BC
+BD 00BD
+BE 00BE
+DF 2017
+E0 05D0
+E1 05D1
+E2 05D2
+E3 05D3
+E4 05D4
+E5 05D5
+E6 05D6
+E7 05D7
+E8 05D8
+E9 05D9
+EA 05DA
+EB 05DB
+EC 05DC
+ED 05DD
+EE 05DE
+EF 05DF
+F0 05E0
+F1 05E1
+F2 05E2
+F3 05E3
+F4 05E4
+F5 05E5
+F6 05E6
+F7 05E7
+F8 05E8
+F9 05E9
+FA 05EA
diff --git a/data/iso-8859-9 b/data/iso-8859-9
new file mode 100644
index 000000000..83a661edc
--- /dev/null
+++ b/data/iso-8859-9
@@ -0,0 +1,251 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for ISO-8859-9
+# (Latin5/Turkish) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 00A1
+A2 00A2
+A3 00A3
+A4 00A4
+A5 00A5
+A6 00A6
+A7 00A7
+A8 00A8
+A9 00A9
+AA 00AA
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 00AF
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 00B4
+B5 00B5
+B6 00B6
+B7 00B7
+B8 00B8
+B9 00B9
+BA 00BA
+BB 00BB
+BC 00BC
+BD 00BD
+BE 00BE
+BF 00BF
+C0 00C0
+C1 00C1
+C2 00C2
+C3 00C3
+C4 00C4
+C5 00C5
+C6 00C6
+C7 00C7
+C8 00C8
+C9 00C9
+CA 00CA
+CB 00CB
+CC 00CC
+CD 00CD
+CE 00CE
+CF 00CF
+D0 011E
+D1 00D1
+D2 00D2
+D3 00D3
+D4 00D4
+D5 00D5
+D6 00D6
+D7 00D7
+D8 00D8
+D9 00D9
+DA 00DA
+DB 00DB
+DC 00DC
+DD 0130
+DE 015E
+DF 00DF
+E0 00E0
+E1 00E1
+E2 00E2
+E3 00E3
+E4 00E4
+E5 00E5
+E6 00E6
+E7 00E7
+E8 00E8
+E9 00E9
+EA 00EA
+EB 00EB
+EC 00EC
+ED 00ED
+EE 00EE
+EF 00EF
+F0 011F
+F1 00F1
+F2 00F2
+F3 00F3
+F4 00F4
+F5 00F5
+F6 00F6
+F7 00F7
+F8 00F8
+F9 00F9
+FA 00FA
+FB 00FB
+FC 00FC
+FD 0131
+FE 015F
+FF 00FF
diff --git a/data/koi8-r b/data/koi8-r
new file mode 100644
index 000000000..7d6816b07
--- /dev/null
+++ b/data/koi8-r
@@ -0,0 +1,261 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Russian
+# Code Page KOI8-R text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 2500
+81 2502
+82 250C
+83 2510
+84 2514
+85 2518
+86 251C
+87 2524
+88 252C
+89 2534
+8A 253C
+8B 2580
+8C 2584
+8D 2588
+8E 258C
+8F 2590
+90 2591
+91 2592
+92 2593
+93 2320
+94 25A0
+95 2219
+96 221A
+97 2248
+98 2264
+99 2265
+9A 00A0
+9B 2321
+9C 00B0
+9D 00B2
+9E 00B7
+9F 00F7
+A0 2550
+A1 2551
+A2 2552
+A3 0451
+A4 2553
+A5 2554
+A6 2555
+A7 2556
+A8 2557
+A9 2558
+AA 2559
+AB 255A
+AC 255B
+AD 255C
+AE 255D
+AF 255E
+B0 255F
+B1 2560
+B2 2561
+B3 0401
+B4 2562
+B5 2563
+B6 2564
+B7 2565
+B8 2566
+B9 2567
+BA 2568
+BB 2569
+BC 256A
+BD 256B
+BE 256C
+BF 00A9
+C0 044E
+C1 0430
+C2 0431
+C3 0446
+C4 0434
+C5 0435
+C6 0444
+C7 0433
+C8 0445
+C9 0438
+CA 0439
+CB 043A
+CC 043B
+CD 043C
+CE 043D
+CF 043E
+D0 043F
+D1 044F
+D2 0440
+D3 0441
+D4 0442
+D5 0443
+D6 0436
+D7 0432
+D8 044C
+D9 044B
+DA 0437
+DB 0448
+DC 044D
+DD 0449
+DE 0447
+DF 044A
+E0 042E
+E1 0410
+E2 0411
+E3 0426
+E4 0414
+E5 0415
+E6 0424
+E7 0413
+E8 0425
+E9 0418
+EA 0419
+EB 041A
+EC 041B
+ED 041C
+EE 041D
+EF 041E
+F0 041F
+F1 042F
+F2 0420
+F3 0421
+F4 0422
+F5 0423
+F6 0416
+F7 0412
+F8 042C
+F9 042B
+FA 0417
+FB 0428
+FC 042D
+FD 0429
+FE 0427
+FF 042A
+
+
diff --git a/data/koi8-u b/data/koi8-u
new file mode 100644
index 000000000..c90c543d9
--- /dev/null
+++ b/data/koi8-u
@@ -0,0 +1,259 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Ukrainian
+# Code Page KOI8-U text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 2500
+81 2502
+82 250C
+83 2510
+84 2514
+85 2518
+86 251C
+87 2524
+88 252C
+89 2534
+8A 253C
+8B 2580
+8C 2584
+8D 2588
+8E 258C
+8F 2590
+90 2591
+91 2592
+92 2593
+93 2320
+94 25A0
+95 2219
+96 221A
+97 2248
+98 2264
+99 2265
+9A 00A0
+9B 2321
+9C 00B0
+9D 00B2
+9E 00B7
+9F 00F7
+A0 2550
+A1 2551
+A2 2552
+A3 0451
+A4 0454
+A5 2554
+A6 0456
+A7 0457
+A8 2557
+A9 2558
+AA 2559
+AB 255A
+AC 255B
+AD 0491
+AE 255D
+AF 255E
+B0 255F
+B1 2560
+B2 2561
+B3 0401
+B4 0404
+B5 2563
+B6 0406
+B7 0407
+B8 2566
+B9 2567
+BA 2568
+BB 2569
+BC 256A
+BD 0490
+BE 256C
+BF 00A9
+C0 044E
+C1 0430
+C2 0431
+C3 0446
+C4 0434
+C5 0435
+C6 0444
+C7 0433
+C8 0445
+C9 0438
+CA 0439
+CB 043A
+CC 043B
+CD 043C
+CE 043D
+CF 043E
+D0 043F
+D1 044F
+D2 0440
+D3 0441
+D4 0442
+D5 0443
+D6 0436
+D7 0432
+D8 044C
+D9 044B
+DA 0437
+DB 0448
+DC 044D
+DD 0449
+DE 0447
+DF 044A
+E0 042E
+E1 0410
+E2 0411
+E3 0426
+E4 0414
+E5 0415
+E6 0424
+E7 0413
+E8 0425
+E9 0418
+EA 0419
+EB 041A
+EC 041B
+ED 041C
+EE 041D
+EF 041E
+F0 041F
+F1 042F
+F2 0420
+F3 0421
+F4 0422
+F5 0423
+F6 0416
+F7 0412
+F8 042C
+F9 042B
+FA 0417
+FB 0428
+FC 042D
+FD 0429
+FE 0427
+FF 042A
diff --git a/data/psglyphs b/data/psglyphs
new file mode 100644
index 000000000..392e782c0
--- /dev/null
+++ b/data/psglyphs
@@ -0,0 +1,1051 @@
+0020 space
+0021 exclam
+0022 quotedbl
+0023 numbersign
+0024 dollar
+0025 percent
+0026 ampersand
+0027 quotesingle
+0028 parenleft
+0029 parenright
+002a asterisk
+002b plus
+002c comma
+002d hyphen
+002e period
+002f slash
+0030 zero
+0031 one
+0032 two
+0033 three
+0034 four
+0035 five
+0036 six
+0037 seven
+0038 eight
+0039 nine
+003a colon
+003b semicolon
+003c less
+003d equal
+003e greater
+003f question
+0040 at
+0041 A
+0042 B
+0043 C
+0044 D
+0045 E
+0046 F
+0047 G
+0048 H
+0049 I
+004a J
+004b K
+004c L
+004d M
+004e N
+004f O
+0050 P
+0051 Q
+0052 R
+0053 S
+0054 T
+0055 U
+0056 V
+0057 W
+0058 X
+0059 Y
+005a Z
+005b bracketleft
+005c backslash
+005d bracketright
+005e asciicircum
+005f underscore
+0060 grave
+0061 a
+0062 b
+0063 c
+0064 d
+0065 e
+0066 f
+0067 g
+0068 h
+0069 i
+006a j
+006b k
+006c l
+006d m
+006e n
+006f o
+0070 p
+0071 q
+0072 r
+0073 s
+0074 t
+0075 u
+0076 v
+0077 w
+0078 x
+0079 y
+007a z
+007b braceleft
+007c bar
+007d braceright
+007e asciitilde
+00a0 space
+00a1 exclamdown
+00a2 cent
+00a3 sterling
+00a4 currency
+00a5 yen
+00a6 brokenbar
+00a7 section
+00a8 dieresis
+00a9 copyright
+00aa ordfeminine
+00ab guillemotleft
+00ac logicalnot
+00ad minus
+00ae registered
+00af macron
+00b0 degree
+00b1 plusminus
+00b2 twosuperior
+00b3 threesuperior
+00b4 acute
+00b5 mu
+00b6 paragraph
+00b7 periodcentered
+00b8 cedilla
+00b9 onesuperior
+00ba ordmasculine
+00bb guillemotright
+00bc onequarter
+00bd onehalf
+00be threequarters
+00bf questiondown
+00c0 Agrave
+00c1 Aacute
+00c2 Acircumflex
+00c3 Atilde
+00c4 Adieresis
+00c5 Aring
+00c6 AE
+00c7 Ccedilla
+00c8 Egrave
+00c9 Eacute
+00ca Ecircumflex
+00cb Edieresis
+00cc Igrave
+00cd Iacute
+00ce Icircumflex
+00cf Idieresis
+00d0 Eth
+00d1 Ntilde
+00d2 Ograve
+00d3 Oacute
+00d4 Ocircumflex
+00d5 Otilde
+00d6 Odieresis
+00d7 multiply
+00d8 Oslash
+00d9 Ugrave
+00da Uacute
+00db Ucircumflex
+00dc Udieresis
+00dd Yacute
+00de Thorn
+00df germandbls
+00e0 agrave
+00e1 aacute
+00e2 acircumflex
+00e3 atilde
+00e4 adieresis
+00e5 aring
+00e6 ae
+00e7 ccedilla
+00e8 egrave
+00e9 eacute
+00ea ecircumflex
+00eb edieresis
+00ec igrave
+00ed iacute
+00ee icircumflex
+00ef idieresis
+00f0 eth
+00f1 ntilde
+00f2 ograve
+00f3 oacute
+00f4 ocircumflex
+00f5 otilde
+00f6 odieresis
+00f7 divide
+00f8 oslash
+00f9 ugrave
+00fa uacute
+00fb ucircumflex
+00fc udieresis
+00fd yacute
+00fe thorn
+00ff ydieresis
+0100 Amacron
+0101 amacron
+0102 Abreve
+0103 abreve
+0104 Aogonek
+0105 aogonek
+0106 Cacute
+0107 cacute
+0108 Ccircumflex
+0109 ccircumflex
+010a Cdotaccent
+010b cdotaccent
+010c Ccaron
+010d ccaron
+010e Dcaron
+010f dcaron
+0110 Dcroat
+0111 dcroat
+0112 Emacron
+0113 emacron
+0114 Ebreve
+0115 ebreve
+0116 Edotaccent
+0117 edotaccent
+0118 Eogonek
+0119 eogonek
+011a Ecaron
+011b ecaron
+011c Gcircumflex
+011d gcircumflex
+011e Gbreve
+011f gbreve
+0120 Gdotaccent
+0121 gdotaccent
+0122 Gcommaaccent
+0123 gcommaaccent
+0124 Hcircumflex
+0125 hcircumflex
+0126 Hbar
+0127 hbar
+0128 Itilde
+0129 itilde
+012a Imacron
+012b imacron
+012c Ibreve
+012d ibreve
+012e Iogonek
+012f iogonek
+0130 Idotaccent
+0131 dotlessi
+0132 IJ
+0133 ij
+0134 Jcircumflex
+0135 jcircumflex
+0136 Kcommaaccent
+0137 kcommaaccent
+0138 kgreenlandic
+0139 Lacute
+013a lacute
+013b Lcommaaccent
+013c lcommaaccent
+013d Lcaron
+013e lcaron
+013f Ldot
+0140 ldot
+0141 Lslash
+0142 lslash
+0143 Nacute
+0144 nacute
+0145 Ncommaaccent
+0146 ncommaaccent
+0147 Ncaron
+0148 ncaron
+0149 napostrophe
+014a Eng
+014b eng
+014c Omacron
+014d omacron
+014e Obreve
+014f obreve
+0150 Ohungarumlaut
+0151 ohungarumlaut
+0152 OE
+0153 oe
+0154 Racute
+0155 racute
+0156 Rcommaaccent
+0157 rcommaaccent
+0158 Rcaron
+0159 rcaron
+015a Sacute
+015b sacute
+015c Scircumflex
+015d scircumflex
+015e Scedilla
+015f scedilla
+0160 Scaron
+0161 scaron
+0162 Tcommaaccent
+0163 tcommaaccent
+0164 Tcaron
+0165 tcaron
+0166 Tbar
+0167 tbar
+0168 Utilde
+0169 utilde
+016a Umacron
+016b umacron
+016c Ubreve
+016d ubreve
+016e Uring
+016f uring
+0170 Uhungarumlaut
+0171 uhungarumlaut
+0172 Uogonek
+0173 uogonek
+0174 Wcircumflex
+0175 wcircumflex
+0176 Ycircumflex
+0177 ycircumflex
+0178 Ydieresis
+0179 Zacute
+017a zacute
+017b Zdotaccent
+017c zdotaccent
+017d Zcaron
+017e zcaron
+017f longs
+0192 florin
+01a0 Ohorn
+01a1 ohorn
+01af Uhorn
+01b0 uhorn
+01e6 Gcaron
+01e7 gcaron
+01fa Aringacute
+01fb aringacute
+01fc AEacute
+01fd aeacute
+01fe Oslashacute
+01ff oslashacute
+0218 Scommaaccent
+0219 scommaaccent
+021a Tcommaaccent
+021b tcommaaccent
+02bc afii57929
+02bd afii64937
+02c6 circumflex
+02c7 caron
+02c9 macron
+02d8 breve
+02d9 dotaccent
+02da ring
+02db ogonek
+02dc tilde
+02dd hungarumlaut
+0300 gravecomb
+0301 acutecomb
+0303 tildecomb
+0309 hookabovecomb
+0323 dotbelowcomb
+0384 tonos
+0385 dieresistonos
+0386 Alphatonos
+0387 anoteleia
+0388 Epsilontonos
+0389 Etatonos
+038a Iotatonos
+038c Omicrontonos
+038e Upsilontonos
+038f Omegatonos
+0390 iotadieresistonos
+0391 Alpha
+0392 Beta
+0393 Gamma
+0394 Delta
+0395 Epsilon
+0396 Zeta
+0397 Eta
+0398 Theta
+0399 Iota
+039a Kappa
+039b Lambda
+039c Mu
+039d Nu
+039e Xi
+039f Omicron
+03a0 Pi
+03a1 Rho
+03a3 Sigma
+03a4 Tau
+03a5 Upsilon
+03a6 Phi
+03a7 Chi
+03a8 Psi
+03a9 Omega
+03aa Iotadieresis
+03ab Upsilondieresis
+03ac alphatonos
+03ad epsilontonos
+03ae etatonos
+03af iotatonos
+03b0 upsilondieresistonos
+03b1 alpha
+03b2 beta
+03b3 gamma
+03b4 delta
+03b5 epsilon
+03b6 zeta
+03b7 eta
+03b8 theta
+03b9 iota
+03ba kappa
+03bb lambda
+03bc mu
+03bd nu
+03be xi
+03bf omicron
+03c0 pi
+03c1 rho
+03c2 sigma1
+03c3 sigma
+03c4 tau
+03c5 upsilon
+03c6 phi
+03c7 chi
+03c8 psi
+03c9 omega
+03ca iotadieresis
+03cb upsilondieresis
+03cc omicrontonos
+03cd upsilontonos
+03ce omegatonos
+03d1 theta1
+03d2 Upsilon1
+03d5 phi1
+03d6 omega1
+0401 afii10023
+0402 afii10051
+0403 afii10052
+0404 afii10053
+0405 afii10054
+0406 afii10055
+0407 afii10056
+0408 afii10057
+0409 afii10058
+040a afii10059
+040b afii10060
+040c afii10061
+040e afii10062
+040f afii10145
+0410 afii10017
+0411 afii10018
+0412 afii10019
+0413 afii10020
+0414 afii10021
+0415 afii10022
+0416 afii10024
+0417 afii10025
+0418 afii10026
+0419 afii10027
+041a afii10028
+041b afii10029
+041c afii10030
+041d afii10031
+041e afii10032
+041f afii10033
+0420 afii10034
+0421 afii10035
+0422 afii10036
+0423 afii10037
+0424 afii10038
+0425 afii10039
+0426 afii10040
+0427 afii10041
+0428 afii10042
+0429 afii10043
+042a afii10044
+042b afii10045
+042c afii10046
+042d afii10047
+042e afii10048
+042f afii10049
+0430 afii10065
+0431 afii10066
+0432 afii10067
+0433 afii10068
+0434 afii10069
+0435 afii10070
+0436 afii10072
+0437 afii10073
+0438 afii10074
+0439 afii10075
+043a afii10076
+043b afii10077
+043c afii10078
+043d afii10079
+043e afii10080
+043f afii10081
+0440 afii10082
+0441 afii10083
+0442 afii10084
+0443 afii10085
+0444 afii10086
+0445 afii10087
+0446 afii10088
+0447 afii10089
+0448 afii10090
+0449 afii10091
+044a afii10092
+044b afii10093
+044c afii10094
+044d afii10095
+044e afii10096
+044f afii10097
+0451 afii10071
+0452 afii10099
+0453 afii10100
+0454 afii10101
+0455 afii10102
+0456 afii10103
+0457 afii10104
+0458 afii10105
+0459 afii10106
+045a afii10107
+045b afii10108
+045c afii10109
+045e afii10110
+045f afii10193
+0462 afii10146
+0463 afii10194
+0472 afii10147
+0473 afii10195
+0474 afii10148
+0475 afii10196
+0490 afii10050
+0491 afii10098
+04d9 afii10846
+05b0 afii57799
+05b1 afii57801
+05b2 afii57800
+05b3 afii57802
+05b4 afii57793
+05b5 afii57794
+05b6 afii57795
+05b7 afii57798
+05b8 afii57797
+05b9 afii57806
+05bb afii57796
+05bc afii57807
+05bd afii57839
+05be afii57645
+05bf afii57841
+05c0 afii57842
+05c1 afii57804
+05c2 afii57803
+05c3 afii57658
+05d0 afii57664
+05d1 afii57665
+05d2 afii57666
+05d3 afii57667
+05d4 afii57668
+05d5 afii57669
+05d6 afii57670
+05d7 afii57671
+05d8 afii57672
+05d9 afii57673
+05da afii57674
+05db afii57675
+05dc afii57676
+05dd afii57677
+05de afii57678
+05df afii57679
+05e0 afii57680
+05e1 afii57681
+05e2 afii57682
+05e3 afii57683
+05e4 afii57684
+05e5 afii57685
+05e6 afii57686
+05e7 afii57687
+05e8 afii57688
+05e9 afii57689
+05ea afii57690
+05f0 afii57716
+05f1 afii57717
+05f2 afii57718
+060c afii57388
+061b afii57403
+061f afii57407
+0621 afii57409
+0622 afii57410
+0623 afii57411
+0624 afii57412
+0625 afii57413
+0626 afii57414
+0627 afii57415
+0628 afii57416
+0629 afii57417
+062a afii57418
+062b afii57419
+062c afii57420
+062d afii57421
+062e afii57422
+062f afii57423
+0630 afii57424
+0631 afii57425
+0632 afii57426
+0633 afii57427
+0634 afii57428
+0635 afii57429
+0636 afii57430
+0637 afii57431
+0638 afii57432
+0639 afii57433
+063a afii57434
+0640 afii57440
+0641 afii57441
+0642 afii57442
+0643 afii57443
+0644 afii57444
+0645 afii57445
+0646 afii57446
+0647 afii57470
+0648 afii57448
+0649 afii57449
+064a afii57450
+064b afii57451
+064c afii57452
+064d afii57453
+064e afii57454
+064f afii57455
+0650 afii57456
+0651 afii57457
+0652 afii57458
+0660 afii57392
+0661 afii57393
+0662 afii57394
+0663 afii57395
+0664 afii57396
+0665 afii57397
+0666 afii57398
+0667 afii57399
+0668 afii57400
+0669 afii57401
+066a afii57381
+066d afii63167
+0679 afii57511
+067e afii57506
+0686 afii57507
+0688 afii57512
+0691 afii57513
+0698 afii57508
+06a4 afii57505
+06af afii57509
+06ba afii57514
+06d2 afii57519
+06d5 afii57534
+1e80 Wgrave
+1e81 wgrave
+1e82 Wacute
+1e83 wacute
+1e84 Wdieresis
+1e85 wdieresis
+1ef2 Ygrave
+1ef3 ygrave
+200c afii61664
+200d afii301
+200e afii299
+200f afii300
+2012 figuredash
+2013 endash
+2014 emdash
+2015 afii00208
+2017 underscoredbl
+2018 quoteleft
+2019 quoteright
+201a quotesinglbase
+201b quotereversed
+201c quotedblleft
+201d quotedblright
+201e quotedblbase
+2020 dagger
+2021 daggerdbl
+2022 bullet
+2024 onedotenleader
+2025 twodotenleader
+2026 ellipsis
+202c afii61573
+202d afii61574
+202e afii61575
+2030 perthousand
+2032 minute
+2033 second
+2039 guilsinglleft
+203a guilsinglright
+203c exclamdbl
+2044 fraction
+2070 zerosuperior
+2074 foursuperior
+2075 fivesuperior
+2076 sixsuperior
+2077 sevensuperior
+2078 eightsuperior
+2079 ninesuperior
+207d parenleftsuperior
+207e parenrightsuperior
+207f nsuperior
+2080 zeroinferior
+2081 oneinferior
+2082 twoinferior
+2083 threeinferior
+2084 fourinferior
+2085 fiveinferior
+2086 sixinferior
+2087 seveninferior
+2088 eightinferior
+2089 nineinferior
+208d parenleftinferior
+208e parenrightinferior
+20a1 colonmonetary
+20a3 franc
+20a4 lira
+20a7 peseta
+20aa afii57636
+20ab dong
+20ac Euro
+2105 afii61248
+2111 Ifraktur
+2113 afii61289
+2116 afii61352
+2118 weierstrass
+211c Rfraktur
+211e prescription
+2122 trademark
+2126 Omega
+212e estimated
+2135 aleph
+2153 onethird
+2154 twothirds
+215b oneeighth
+215c threeeighths
+215d fiveeighths
+215e seveneighths
+2190 arrowleft
+2191 arrowup
+2192 arrowright
+2193 arrowdown
+2194 arrowboth
+2195 arrowupdn
+21a8 arrowupdnbse
+21b5 carriagereturn
+21d0 arrowdblleft
+21d1 arrowdblup
+21d2 arrowdblright
+21d3 arrowdbldown
+21d4 arrowdblboth
+2200 universal
+2202 partialdiff
+2203 existential
+2205 emptyset
+2206 Delta
+2207 gradient
+2208 element
+2209 notelement
+220b suchthat
+220f product
+2211 summation
+2212 minus
+2215 fraction
+2217 asteriskmath
+2219 periodcentered
+221a radical
+221d proportional
+221e infinity
+221f orthogonal
+2220 angle
+2227 logicaland
+2228 logicalor
+2229 intersection
+222a union
+222b integral
+2234 therefore
+223c similar
+2245 congruent
+2248 approxequal
+2260 notequal
+2261 equivalence
+2264 lessequal
+2265 greaterequal
+2282 propersubset
+2283 propersuperset
+2284 notsubset
+2286 reflexsubset
+2287 reflexsuperset
+2295 circleplus
+2297 circlemultiply
+22a5 perpendicular
+22c5 dotmath
+2302 house
+2310 revlogicalnot
+2320 integraltp
+2321 integralbt
+2329 angleleft
+232a angleright
+2500 SF100000
+2502 SF110000
+250c SF010000
+2510 SF030000
+2514 SF020000
+2518 SF040000
+251c SF080000
+2524 SF090000
+252c SF060000
+2534 SF070000
+253c SF050000
+2550 SF430000
+2551 SF240000
+2552 SF510000
+2553 SF520000
+2554 SF390000
+2555 SF220000
+2556 SF210000
+2557 SF250000
+2558 SF500000
+2559 SF490000
+255a SF380000
+255b SF280000
+255c SF270000
+255d SF260000
+255e SF360000
+255f SF370000
+2560 SF420000
+2561 SF190000
+2562 SF200000
+2563 SF230000
+2564 SF470000
+2565 SF480000
+2566 SF410000
+2567 SF450000
+2568 SF460000
+2569 SF400000
+256a SF540000
+256b SF530000
+256c SF440000
+2580 upblock
+2584 dnblock
+2588 block
+258c lfblock
+2590 rtblock
+2591 ltshade
+2592 shade
+2593 dkshade
+25a0 filledbox
+25a1 H22073
+25aa H18543
+25ab H18551
+25ac filledrect
+25b2 triagup
+25ba triagrt
+25bc triagdn
+25c4 triaglf
+25ca lozenge
+25cb circle
+25cf H18533
+25d8 invbullet
+25d9 invcircle
+25e6 openbullet
+263a smileface
+263b invsmileface
+263c sun
+2640 female
+2642 male
+2660 spade
+2663 club
+2665 heart
+2666 diamond
+266a musicalnote
+266b musicalnotedbl
+f6be dotlessj
+f6bf LL
+f6c0 ll
+f6c1 Scedilla
+f6c2 scedilla
+f6c3 commaaccent
+f6c4 afii10063
+f6c5 afii10064
+f6c6 afii10192
+f6c7 afii10831
+f6c8 afii10832
+f6c9 Acute
+f6ca Caron
+f6cb Dieresis
+f6cc DieresisAcute
+f6cd DieresisGrave
+f6ce Grave
+f6cf Hungarumlaut
+f6d0 Macron
+f6d1 cyrBreve
+f6d2 cyrFlex
+f6d3 dblGrave
+f6d4 cyrbreve
+f6d5 cyrflex
+f6d6 dblgrave
+f6d7 dieresisacute
+f6d8 dieresisgrave
+f6d9 copyrightserif
+f6da registerserif
+f6db trademarkserif
+f6dc onefitted
+f6dd rupiah
+f6de threequartersemdash
+f6df centinferior
+f6e0 centsuperior
+f6e1 commainferior
+f6e2 commasuperior
+f6e3 dollarinferior
+f6e4 dollarsuperior
+f6e5 hypheninferior
+f6e6 hyphensuperior
+f6e7 periodinferior
+f6e8 periodsuperior
+f6e9 asuperior
+f6ea bsuperior
+f6eb dsuperior
+f6ec esuperior
+f6ed isuperior
+f6ee lsuperior
+f6ef msuperior
+f6f0 osuperior
+f6f1 rsuperior
+f6f2 ssuperior
+f6f3 tsuperior
+f6f4 Brevesmall
+f6f5 Caronsmall
+f6f6 Circumflexsmall
+f6f7 Dotaccentsmall
+f6f8 Hungarumlautsmall
+f6f9 Lslashsmall
+f6fa OEsmall
+f6fb Ogoneksmall
+f6fc Ringsmall
+f6fd Scaronsmall
+f6fe Tildesmall
+f6ff Zcaronsmall
+f721 exclamsmall
+f724 dollaroldstyle
+f726 ampersandsmall
+f730 zerooldstyle
+f731 oneoldstyle
+f732 twooldstyle
+f733 threeoldstyle
+f734 fouroldstyle
+f735 fiveoldstyle
+f736 sixoldstyle
+f737 sevenoldstyle
+f738 eightoldstyle
+f739 nineoldstyle
+f73f questionsmall
+f760 Gravesmall
+f761 Asmall
+f762 Bsmall
+f763 Csmall
+f764 Dsmall
+f765 Esmall
+f766 Fsmall
+f767 Gsmall
+f768 Hsmall
+f769 Ismall
+f76a Jsmall
+f76b Ksmall
+f76c Lsmall
+f76d Msmall
+f76e Nsmall
+f76f Osmall
+f770 Psmall
+f771 Qsmall
+f772 Rsmall
+f773 Ssmall
+f774 Tsmall
+f775 Usmall
+f776 Vsmall
+f777 Wsmall
+f778 Xsmall
+f779 Ysmall
+f77a Zsmall
+f7a1 exclamdownsmall
+f7a2 centoldstyle
+f7a8 Dieresissmall
+f7af Macronsmall
+f7b4 Acutesmall
+f7b8 Cedillasmall
+f7bf questiondownsmall
+f7e0 Agravesmall
+f7e1 Aacutesmall
+f7e2 Acircumflexsmall
+f7e3 Atildesmall
+f7e4 Adieresissmall
+f7e5 Aringsmall
+f7e6 AEsmall
+f7e7 Ccedillasmall
+f7e8 Egravesmall
+f7e9 Eacutesmall
+f7ea Ecircumflexsmall
+f7eb Edieresissmall
+f7ec Igravesmall
+f7ed Iacutesmall
+f7ee Icircumflexsmall
+f7ef Idieresissmall
+f7f0 Ethsmall
+f7f1 Ntildesmall
+f7f2 Ogravesmall
+f7f3 Oacutesmall
+f7f4 Ocircumflexsmall
+f7f5 Otildesmall
+f7f6 Odieresissmall
+f7f8 Oslashsmall
+f7f9 Ugravesmall
+f7fa Uacutesmall
+f7fb Ucircumflexsmall
+f7fc Udieresissmall
+f7fd Yacutesmall
+f7fe Thornsmall
+f7ff Ydieresissmall
+f8e5 radicalex
+f8e6 arrowvertex
+f8e7 arrowhorizex
+f8e8 registersans
+f8e9 copyrightsans
+f8ea trademarksans
+f8eb parenlefttp
+f8ec parenleftex
+f8ed parenleftbt
+f8ee bracketlefttp
+f8ef bracketleftex
+f8f0 bracketleftbt
+f8f1 bracelefttp
+f8f2 braceleftmid
+f8f3 braceleftbt
+f8f4 braceex
+f8f5 integralex
+f8f6 parenrighttp
+f8f7 parenrightex
+f8f8 parenrightbt
+f8f9 bracketrighttp
+f8fa bracketrightex
+f8fb bracketrightbt
+f8fc bracerighttp
+f8fd bracerightmid
+f8fe bracerightbt
+fb00 ff
+fb01 fi
+fb02 fl
+fb03 ffi
+fb04 ffl
+fb1f afii57705
+fb2a afii57694
+fb2b afii57695
+fb35 afii57723
+fb4b afii57700
diff --git a/data/secret b/data/secret
new file mode 100644
index 000000000..1f8751430
--- /dev/null
+++ b/data/secret
@@ -0,0 +1,277 @@
+%!PS-Adobe-3.0
+%%BoundingBox: 0 0 612 792
+%%Pages: 1
+%%LanguageLevel: 1
+%%DocumentData: Clean7Bit
+%%DocumentSuppliedResources: procset bannerprint/1.0
+%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
+%%Creator: Michael Sweet, Easy Software Products
+%%CreationDate: May 10, 2000
+%%Title: Test Page
+%%EndComments
+%%BeginProlog
+%%BeginResource procset bannerprint 1.1 0
+%
+% PostScript banner page for the Common UNIX Printing System ("CUPS").
+%
+% Copyright 1993-2002 Easy Software Products
+%
+% These coded instructions, statements, and computer programs are the
+% property of Easy Software Products and are protected by Federal
+% copyright law. Distribution and use rights are outlined in the file
+% "LICENSE.txt" which should have been included with this file. If this
+% file is missing or damaged please contact Easy Software Products
+% at:
+%
+% Attn: CUPS Licensing Information
+% Easy Software Products
+% 44141 Airport View Drive, Suite 204
+% Hollywood, Maryland 20636-3111 USA
+%
+% Voice: (301) 373-9603
+% EMail: cups-info@cups.org
+% WWW: http://www.cups.org
+%
+/CENTER { % Draw centered text
+ % (name) CENTER -
+ dup stringwidth pop % Get the width of the string
+ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
+ show % Show the string
+} bind def
+/RIGHT { % Draw right-justified text
+ % (name) RIGHT -
+ dup stringwidth pop % Get the width of the string
+ neg 0 rmoveto % Shift left the entire distance
+ show % Show the string
+} bind def
+/NUMBER { % Draw a number
+ % power n NUMBER -
+ 1 index 1 eq { % power == 1?
+ round cvi exch pop % Convert "n" to integer
+ } {
+ 1 index mul round exch div % Truncate extra decimal places
+ } ifelse
+ 100 string cvs show % Convert to a string and show it...
+} bind def
+/CUPSLOGO { % Draw the CUPS logo
+ % height CUPSLOGO
+ % Start with a big C...
+ /Helvetica findfont 1 index scalefont setfont
+ 0 setgray
+ 0 0 moveto
+ (C) show
+
+ % Then "UNIX Printing System" much smaller...
+ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
+ 0.25 mul
+ dup dup 2.0 mul moveto
+ (UNIX) show
+ dup dup 1.6 mul moveto
+ (Printing) show
+ dup 1.2 mul moveto
+ (System) show
+} bind def
+/ESPLOGO { % Draw the ESP logo
+ % height ESPLOGO
+ % Compute the size of the logo...
+ 0 0
+ 2 index 1.5 mul 3 index
+
+ % Do the "metallic" fill from 10% black to 40% black...
+ 1 -0.001 0 {
+ dup % loopval
+ -0.15 mul % loopval * -0.15
+ 0.9 add % 0.9 - loopval * 0.15
+ setgray % set gray shade
+
+ 0 % x
+ 1 index neg % loopval
+ 1 add % 1 - loopval
+ 3 index % height
+ mul % height * (1 - loopval)
+ moveto % starting point
+
+ dup % loopval
+ 3 index % width
+ mul % loopval * width
+ 2 index % height
+ lineto % Next point
+
+ 0 % x
+ 2 index % height
+ lineto % Next point
+
+ closepath
+ fill
+
+ dup % loopval
+ 0.15 mul % loopval * 0.15
+ 0.6 add % 0.6 + loopval * 0.15
+ setgray
+
+ dup % loopval
+ neg 1 add % 1 - loopval
+ 3 index % width
+ mul % (1 - loopval) * width
+ 0 % y
+ moveto % Starting point
+
+ 2 index % width
+ exch % loopval
+ 2 index % height
+ mul % loopval * height
+ lineto % Next point
+
+ 1 index % width
+ 0 % y
+ lineto % Next point
+
+ closepath
+ fill
+ } for
+
+ 0 setgray rectstroke
+
+ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
+ dup 40 div
+
+ dup 4 mul 1 index 25 mul moveto (E) show
+ dup 10 mul 1 index 15 mul moveto (S) show
+ dup 16 mul 1 index 5 mul moveto (P) show
+
+ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
+ dup 14 mul 1 index 29 mul moveto (asy) show
+ dup 20 mul 1 index 19 mul moveto (oftware) show
+ dup 26 mul 1 index 9 mul moveto (roducts) show
+
+ pop
+} bind def
+%%EndResource
+%%EndProlog
+%%Page: 1 1
+gsave
+
+ % Determine the imageable area and device resolution...
+ initclip newpath clippath pathbbox % Get bounding rectangle
+ 72 div /pageTop exch def % Get top margin in inches
+ 72 div /pageRight exch def % Get right margin in inches
+ 72 div /pageBottom exch def % Get bottom margin in inches
+ 72 div /pageLeft exch def % Get left margin in inches
+
+ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
+ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
+
+ /boxWidth % width of text box
+ pageWidth pageHeight lt
+ { pageWidth 54 mul }
+ { pageHeight 42 mul }
+ ifelse def
+
+ newpath % Clear bounding path
+
+ % Create fonts...
+ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
+ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
+
+ /mediumFont /Helvetica findfont % mediumFont = Helvetica
+ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
+
+ % Offset page to account for lower-left margin...
+ pageLeft 72 mul
+ pageBottom 72 mul
+ translate
+
+ % Draw the label at the top and bottom...
+ 0 setgray % Color
+
+ pageWidth 36 mul % Center of page
+ pageHeight 72 mul % Top of page
+ pageWidth -7 mul add % - 2 lines
+ moveto % Position text
+ bigFont setfont % Font
+ (Secret) CENTER % Show text centered
+
+ pageWidth 36 mul % Center of page
+ pageHeight 6 mul % Bottom of page
+ moveto % Position text
+ bigFont setfont % Font
+ (Secret) CENTER % Show text centered
+
+ % Job information box...
+ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+ 0.5 setgray rectfill % Draw a shadow
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul % y = pageHeight * 1/4 * 72
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+
+ 4 copy 1 setgray rectfill % Clear the box to white
+ 0 setgray rectstroke % Draw a black box around it...
+
+ % Job information text...
+ mediumFont setfont % Medium sized font
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 5 mul add % y += 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Job ID: ) RIGHT
+ moveto
+ ({printer-name}-{job-id}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 2 mul add % y += 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Title: ) RIGHT
+ moveto
+ ({job-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -1 mul add % y -= 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Requesting User: ) RIGHT
+ moveto
+ ({job-originating-user-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -4 mul add % y -= 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Billing Info: ) RIGHT
+ moveto
+ ({?job-billing}) show
+
+ % Then the CUPS logo....
+ gsave
+ pageWidth 4 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 9 mul CUPSLOGO
+ grestore
+
+ % And the ESP logo....
+ gsave
+ pageWidth 59 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 6 mul ESPLOGO
+ grestore
+% Show the page...
+grestore
+showpage
+%
+% End of "$Id: secret 2122 2002-01-31 14:19:37Z mike $".
+%
+%%EOF
diff --git a/data/standard b/data/standard
new file mode 100644
index 000000000..ca0edb037
--- /dev/null
+++ b/data/standard
@@ -0,0 +1,261 @@
+%!PS-Adobe-3.0
+%%BoundingBox: 0 0 612 792
+%%Pages: 1
+%%LanguageLevel: 1
+%%DocumentData: Clean7Bit
+%%DocumentSuppliedResources: procset bannerprint/1.0
+%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
+%%Creator: Michael Sweet, Easy Software Products
+%%CreationDate: May 10, 2000
+%%Title: Test Page
+%%EndComments
+%%BeginProlog
+%%BeginResource procset bannerprint 1.1 0
+%
+% PostScript banner page for the Common UNIX Printing System ("CUPS").
+%
+% Copyright 1993-2002 Easy Software Products
+%
+% These coded instructions, statements, and computer programs are the
+% property of Easy Software Products and are protected by Federal
+% copyright law. Distribution and use rights are outlined in the file
+% "LICENSE.txt" which should have been included with this file. If this
+% file is missing or damaged please contact Easy Software Products
+% at:
+%
+% Attn: CUPS Licensing Information
+% Easy Software Products
+% 44141 Airport View Drive, Suite 204
+% Hollywood, Maryland 20636-3111 USA
+%
+% Voice: (301) 373-9603
+% EMail: cups-info@cups.org
+% WWW: http://www.cups.org
+%
+/CENTER { % Draw centered text
+ % (name) CENTER -
+ dup stringwidth pop % Get the width of the string
+ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
+ show % Show the string
+} bind def
+/RIGHT { % Draw right-justified text
+ % (name) RIGHT -
+ dup stringwidth pop % Get the width of the string
+ neg 0 rmoveto % Shift left the entire distance
+ show % Show the string
+} bind def
+/NUMBER { % Draw a number
+ % power n NUMBER -
+ 1 index 1 eq { % power == 1?
+ round cvi exch pop % Convert "n" to integer
+ } {
+ 1 index mul round exch div % Truncate extra decimal places
+ } ifelse
+ 100 string cvs show % Convert to a string and show it...
+} bind def
+/CUPSLOGO { % Draw the CUPS logo
+ % height CUPSLOGO
+ % Start with a big C...
+ /Helvetica findfont 1 index scalefont setfont
+ 0 setgray
+ 0 0 moveto
+ (C) show
+
+ % Then "UNIX Printing System" much smaller...
+ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
+ 0.25 mul
+ dup dup 2.0 mul moveto
+ (UNIX) show
+ dup dup 1.6 mul moveto
+ (Printing) show
+ dup 1.2 mul moveto
+ (System) show
+} bind def
+/ESPLOGO { % Draw the ESP logo
+ % height ESPLOGO
+ % Compute the size of the logo...
+ 0 0
+ 2 index 1.5 mul 3 index
+
+ % Do the "metallic" fill from 10% black to 40% black...
+ 1 -0.001 0 {
+ dup % loopval
+ -0.15 mul % loopval * -0.15
+ 0.9 add % 0.9 - loopval * 0.15
+ setgray % set gray shade
+
+ 0 % x
+ 1 index neg % loopval
+ 1 add % 1 - loopval
+ 3 index % height
+ mul % height * (1 - loopval)
+ moveto % starting point
+
+ dup % loopval
+ 3 index % width
+ mul % loopval * width
+ 2 index % height
+ lineto % Next point
+
+ 0 % x
+ 2 index % height
+ lineto % Next point
+
+ closepath
+ fill
+
+ dup % loopval
+ 0.15 mul % loopval * 0.15
+ 0.6 add % 0.6 + loopval * 0.15
+ setgray
+
+ dup % loopval
+ neg 1 add % 1 - loopval
+ 3 index % width
+ mul % (1 - loopval) * width
+ 0 % y
+ moveto % Starting point
+
+ 2 index % width
+ exch % loopval
+ 2 index % height
+ mul % loopval * height
+ lineto % Next point
+
+ 1 index % width
+ 0 % y
+ lineto % Next point
+
+ closepath
+ fill
+ } for
+
+ 0 setgray rectstroke
+
+ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
+ dup 40 div
+
+ dup 4 mul 1 index 25 mul moveto (E) show
+ dup 10 mul 1 index 15 mul moveto (S) show
+ dup 16 mul 1 index 5 mul moveto (P) show
+
+ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
+ dup 14 mul 1 index 29 mul moveto (asy) show
+ dup 20 mul 1 index 19 mul moveto (oftware) show
+ dup 26 mul 1 index 9 mul moveto (roducts) show
+
+ pop
+} bind def
+%%EndResource
+%%EndProlog
+%%Page: 1 1
+gsave
+
+ % Determine the imageable area and device resolution...
+ initclip newpath clippath pathbbox % Get bounding rectangle
+ 72 div /pageTop exch def % Get top margin in inches
+ 72 div /pageRight exch def % Get right margin in inches
+ 72 div /pageBottom exch def % Get bottom margin in inches
+ 72 div /pageLeft exch def % Get left margin in inches
+
+ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
+ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
+
+ /boxWidth % width of text box
+ pageWidth pageHeight lt
+ { pageWidth 54 mul }
+ { pageHeight 42 mul }
+ ifelse def
+
+ newpath % Clear bounding path
+
+ % Create fonts...
+ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
+ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
+
+ /mediumFont /Helvetica findfont % mediumFont = Helvetica
+ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
+
+ % Offset page to account for lower-left margin...
+ pageLeft 72 mul
+ pageBottom 72 mul
+ translate
+
+ % Job information box...
+ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+ 0.5 setgray rectfill % Draw a shadow
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul % y = pageHeight * 1/4 * 72
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+
+ 4 copy 1 setgray rectfill % Clear the box to white
+ 0 setgray rectstroke % Draw a black box around it...
+
+ % Job information text...
+ mediumFont setfont % Medium sized font
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 5 mul add % y += 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Job ID: ) RIGHT
+ moveto
+ ({printer-name}-{job-id}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 2 mul add % y += 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Title: ) RIGHT
+ moveto
+ ({job-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -1 mul add % y -= 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Requesting User: ) RIGHT
+ moveto
+ ({job-originating-user-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -4 mul add % y -= 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Billing Info: ) RIGHT
+ moveto
+ ({?job-billing}) show
+
+ % Then the CUPS logo....
+ gsave
+ pageWidth 4 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 9 mul CUPSLOGO
+ grestore
+
+ % And the ESP logo....
+ gsave
+ pageWidth 59 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 6 mul ESPLOGO
+ grestore
+% Show the page...
+grestore
+showpage
+%
+% End of "$Id: standard 2122 2002-01-31 14:19:37Z mike $".
+%
+%%EOF
diff --git a/data/testprint.ps b/data/testprint.ps
new file mode 100644
index 000000000..a70de15d4
--- /dev/null
+++ b/data/testprint.ps
@@ -0,0 +1,522 @@
+%!PS-Adobe-3.0
+%%BoundingBox: 0 0 612 792
+%%Pages: 1
+%%LanguageLevel: 1
+%%DocumentData: Clean7Bit
+%%DocumentSuppliedResources: procset testprint/1.0
+%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
+%%Creator: Michael Sweet, Easy Software Products
+%%CreationDate: May 11, 1999
+%%Title: Test Page
+%%EndComments
+%%BeginProlog
+%%BeginResource procset testprint 1.1 0
+%
+% PostScript test page for the Common UNIX Printing System ("CUPS").
+%
+% Copyright 1993-2002 Easy Software Products
+%
+% These coded instructions, statements, and computer programs are the
+% property of Easy Software Products and are protected by Federal
+% copyright law. Distribution and use rights are outlined in the file
+% "LICENSE.txt" which should have been included with this file. If this
+% file is missing or damaged please contact Easy Software Products
+% at:
+%
+% Attn: CUPS Licensing Information
+% Easy Software Products
+% 44141 Airport View Drive, Suite 204
+% Hollywood, Maryland 20636-3111 USA
+%
+% Voice: (301) 373-9603
+% EMail: cups-info@cups.org
+% WWW: http://www.cups.org
+%
+/OCTANT { % Draw a color wheel OCTANT...
+ % (name) radius r g b OCTANT -
+ % Loop through 100 shades...
+ 0 0.010101 0.98 {
+ % Set the color...
+ 3 index 1 eq % R == 1?
+ 3 index 1 eq % G == 1?
+ 3 index 1 eq % B == 1?
+ and and {
+ 0 index 4 index mul % R * val
+ 1 index 4 index mul % G * val
+ 2 index 4 index mul % B * val
+ } {
+ 0 index 4 index mul % R * val
+ 1 index neg 1 add add % + (1 - val)
+ 1 index 4 index mul % G * val
+ 2 index neg 1 add add % + (1 - val)
+ 2 index 4 index mul % B * val
+ 3 index neg 1 add add % + (1 - val)
+ } ifelse
+ setrgbcolor
+
+ % Draw a polygon...
+ dup 5 index mul dup 0 % x1, y1
+ moveto
+ 0.707106781 mul dup lineto % x2, y2
+
+ 0.010101 add 4 index mul dup % x3
+ 0.707106781 mul dup lineto % x3, y3
+ 0 lineto % x4, y4
+ closepath
+ fill
+ } for
+
+ % Draw a line around the polygons...
+ pop pop pop dup
+ 0 setgray
+ 0 0 moveto
+ dup 0 lineto
+ 0.707106781 mul dup lineto
+ closepath
+ stroke
+
+ % Draw the label...
+ 0 exch dup -9 div exch % text offset = 0, -radius/9
+ dup 0.923879532 mul % x = radius * cos(22.5)
+ exch 0.382683432 mul % y = radius * cos(22.5)
+ moveto % position label
+ gsave
+ 22.5 rotate % rotate label
+ rmoveto % offset label
+ show % show label
+ grestore
+} bind def
+/CENTER { % Draw centered text
+ % (name) CENTER -
+ dup stringwidth pop % Get the width of the string
+ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
+ show % Show the string
+} bind def
+/RIGHT { % Draw right-justified text
+ % (name) RIGHT -
+ dup stringwidth pop % Get the width of the string
+ neg 0 rmoveto % Shift left the entire distance
+ show % Show the string
+} bind def
+/NUMBER { % Draw a number
+ % power n NUMBER -
+ 1 index 1 eq { % power == 1?
+ round cvi exch pop % Convert "n" to integer
+ } {
+ 1 index mul round exch div % Truncate extra decimal places
+ } ifelse
+ 100 string cvs show % Convert to a string and show it...
+} bind def
+/CUPSLOGO { % Draw the CUPS logo
+ % height CUPSLOGO
+ % Start with a big C...
+ /Helvetica findfont 1 index scalefont setfont
+ 0 setgray
+ 0 0 moveto
+ (C) show
+
+ % Then "UNIX Printing System" much smaller...
+ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
+ 0.25 mul
+ dup dup 2.0 mul moveto
+ (UNIX) show
+ dup dup 1.6 mul moveto
+ (Printing) show
+ dup 1.2 mul moveto
+ (System) show
+} bind def
+/ESPLOGO { % Draw the ESP logo
+ % height ESPLOGO
+ % Compute the size of the logo...
+ 0 0
+ 2 index 1.5 mul 3 index
+
+ % Do the "metallic" fill from 10% black to 40% black...
+ 1 -0.001 0 {
+ dup % loopval
+ -0.15 mul % loopval * -0.15
+ 0.9 add % 0.9 - loopval * 0.15
+ setgray % set gray shade
+
+ 0 % x
+ 1 index neg % loopval
+ 1 add % 1 - loopval
+ 3 index % height
+ mul % height * (1 - loopval)
+ moveto % starting point
+
+ dup % loopval
+ 3 index % width
+ mul % loopval * width
+ 2 index % height
+ lineto % Next point
+
+ 0 % x
+ 2 index % height
+ lineto % Next point
+
+ closepath
+ fill
+
+ dup % loopval
+ 0.15 mul % loopval * 0.15
+ 0.6 add % 0.6 + loopval * 0.15
+ setgray
+
+ dup % loopval
+ neg 1 add % 1 - loopval
+ 3 index % width
+ mul % (1 - loopval) * width
+ 0 % y
+ moveto % Starting point
+
+ 2 index % width
+ exch % loopval
+ 2 index % height
+ mul % loopval * height
+ lineto % Next point
+
+ 1 index % width
+ 0 % y
+ lineto % Next point
+
+ closepath
+ fill
+ } for
+
+ 0 setgray rectstroke
+
+ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
+ dup 40 div
+
+ dup 4 mul 1 index 25 mul moveto (E) show
+ dup 10 mul 1 index 15 mul moveto (S) show
+ dup 16 mul 1 index 5 mul moveto (P) show
+
+ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
+ dup 14 mul 1 index 29 mul moveto (asy) show
+ dup 20 mul 1 index 19 mul moveto (oftware) show
+ dup 26 mul 1 index 9 mul moveto (roducts) show
+
+ pop
+} bind def
+%%EndResource
+%%EndProlog
+%%Page: 1 1
+gsave
+
+ % Determine the imageable area and device resolution...
+ initclip newpath clippath pathbbox % Get bounding rectangle
+ 72 div /pageTop exch def % Get top margin in inches
+ 72 div /pageRight exch def % Get right margin in inches
+ 72 div /pageBottom exch def % Get bottom margin in inches
+ 72 div /pageLeft exch def % Get left margin in inches
+
+ 4 setlinewidth % Draw wide lines
+ 0 setgray closepath stroke % Draw a clipping rectangle
+ 1 setlinewidth % Draw normal lines
+
+ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
+ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
+
+ 72 72 dtransform % Get device resolution per inch
+ /yResolution exch abs def % yResolution = abs(yres)
+ /xResolution exch abs def % xResolution = abs(xres)
+
+ % Figure out the sizes of things...
+ /wheelSize % size of wheels
+ pageWidth pageHeight lt
+ { pageWidth 9 mul }
+ { pageHeight 7 mul }
+ ifelse def
+
+ % Create fonts...
+ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
+ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
+
+ /mediumFont /Helvetica findfont % mediumFont = Helvetica
+ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
+
+ /smallFont /Times-Roman findfont % smallFont = Times-Roman
+ pageHeight scalefont def % size = pageHeight (nominally 11)
+
+ % Offset page to account for lower-left margin...
+ pageLeft 72 mul
+ pageBottom 72 mul
+ translate
+
+ % Draw the color wheel...
+ mediumFont setfont % Font
+ 0 setgray % Color
+
+ gsave
+ % Position the wheel on the left side...
+ pageWidth 18 mul % x = pageWidth * 1/4 * 72
+ pageHeight 54 mul % y = pageHeight * 3/4 * 72
+ translate
+
+ % Size the wheel...
+ wheelSize
+
+ % Draw the colors...
+ dup (C) exch 0 1 1 OCTANT 45 rotate
+ dup (M) exch 1 0 1 OCTANT 45 rotate
+ dup (Y) exch 1 1 0 OCTANT 45 rotate
+ dup (K) exch 0 0 0 OCTANT 45 rotate
+ dup (R) exch 1 0 0 OCTANT 45 rotate
+ dup (G) exch 0 1 0 OCTANT 45 rotate
+ dup (B) exch 0 0 1 OCTANT 45 rotate
+ (W) exch 1 1 1 OCTANT 45 rotate
+ grestore
+
+ % Label the color wheel...
+ pageWidth 18 mul % x = pageWidth * 1/4 * 72
+ pageHeight 44 mul % y = pageHeight * 19/32 * 72
+ moveto % Position the text
+ (Color Wheel) CENTER % Show the text centered
+
+ % Draw radial lines...
+ gsave
+ 0 setlinewidth % 1 pixel lines
+
+ % Position the lines on the left side...
+ pageWidth 54 mul % x = pageWidth * 3/4 * 72
+ pageHeight 54 mul % y = pageHeight * 3/4 * 72
+ translate
+
+ % Size the wheel...
+ wheelSize
+
+ % Loop at 1 degree increments
+ 0 1 359 {
+ pop % Discard angle - not used
+ 0 0 moveto % Start line at the center
+ dup 0 lineto % Draw to the radius
+ 1 rotate % Rotate 1 degree
+ } for
+
+ pop % Discard radius - not needed anymore
+ stroke % Draw lines...
+
+ grestore
+
+ % Label the lines...
+ pageWidth 54 mul % x = pageWidth * 3/4 * 72
+ pageHeight 44 mul % y = pageHeight * 19/32 * 72
+ moveto % Position the text
+ (1 Degree Radial Lines) CENTER % Show the text centered
+
+ % Imageable area...
+ pageHeight 15 mul % Height of imageable area
+
+ pageWidth 4.5 mul % x = pageWidth * 1/16 * 72
+ pageHeight 35.5 mul % y = pageHeight * 1/2 * 72
+ 2 index sub % y -= height
+ pageWidth 28 mul % width = pageWidth * 1/4 * 72
+ 3 index % height
+ 0.5 setgray rectfill % Draw a shadow
+
+ pageWidth 4 mul % x = pageWidth * 1/16 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ 2 index sub % y -= height
+ pageWidth 28 mul % width = pageWidth * 3/8 * 72
+ 3 index % height
+ 4 copy 1 setgray rectfill % Clear the box to white
+ 0 setgray rectstroke % Draw a black box around it...
+
+ pop % Discard height
+
+ % Label the imageable area...
+ pageWidth 4 mul % x = pageWidth * 1/16 * 72
+ pageHeight 37 mul % y = pageHeight * 1/2 * 72
+ moveto % Position the text
+ mediumFont setfont % Font
+ (Imageable Area) show % Show the text
+
+ smallFont setfont % Font
+ pageWidth 14 mul % x = pageWidth * 3/16 * 72
+ pageHeight 36 mul % y = pageWidth * 1/2 * 72
+ pageHeight -2 mul add % y -= 2 * smallFont height
+
+ % Page Size inches
+ 2 copy moveto % Move to x & y
+ (Page Size: ) RIGHT % Label
+ 100 pageWidth NUMBER % pageWidth
+ (x) show % "x"
+ 100 pageHeight NUMBER % pageHeight
+ (in) show % "in"
+
+ % Page Size millimeters
+ pageHeight sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ 10 pageWidth 25.4 mul NUMBER % pageWidth
+ (x) show % "x"
+ 10 pageHeight 25.4 mul NUMBER % pageHeight
+ (mm) show % "mm"
+
+ % Lower-left inches
+ pageHeight 2 mul sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ (Lower-Left: ) RIGHT % Label
+ 100 pageLeft NUMBER % pageLeft
+ (x) show % "x"
+ 100 pageBottom NUMBER % pageBottom
+ (in) show % "in"
+
+ % Lower-left millimeters
+ pageHeight sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ 10 pageLeft 25.4 mul NUMBER % pageLeft
+ (x) show % "x"
+ 10 pageBottom 25.4 mul NUMBER % pageBottom
+ (mm) show % "mm"
+
+ % Upper-right inches
+ pageHeight 2 mul sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ (Upper-Right: ) RIGHT % Label
+ 100 pageRight NUMBER % pageRight
+ (x) show % "x"
+ 100 pageTop NUMBER % pageTop
+ (in) show % "in"
+
+ % Upper-right millimeters
+ pageHeight sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ 10 pageRight 25.4 mul NUMBER % pageRight
+ (x) show % "x"
+ 10 pageTop 25.4 mul NUMBER % pageTop
+ (mm) show % "mm"
+
+ % Resolution dots-per-inch
+ pageHeight 2 mul sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ (Resolution: ) RIGHT % Label
+ 1 xResolution NUMBER % xResolution
+ (x) show % "x"
+ 1 yResolution NUMBER % yResolution
+ (dpi) show % "dpi"
+
+ % Resolution dots-per-meter
+ pageHeight sub % Move down...
+
+ moveto % Move to x & y
+ 1 xResolution 39.27 mul NUMBER % xResolution
+ (x) show % "x"
+ 1 yResolution 39.27 mul NUMBER % yResolution
+ (dpm) show % "dpm"
+
+ % Interpreter Information...
+ pageHeight 15 mul % Height of interpreter information
+
+ pageWidth 40.5 mul % x = pageWidth * 9/16 * 72
+ pageHeight 35.5 mul % y = pageHeight * 1/2 * 72
+ 2 index sub % y -= height
+ pageWidth 28 mul % width = pageWidth * 1/4 * 72
+ 3 index % height
+ 0.5 setgray rectfill % Draw a shadow
+
+ pageWidth 40 mul % x = pageWidth * 9/16 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ 2 index sub % y -= height
+ pageWidth 28 mul % width = pageWidth * 3/8 * 72
+ 3 index % height
+ 4 copy 1 setgray rectfill % Clear the box to white
+ 0 setgray rectstroke % Draw a black box around it...
+
+ pop % Discard height
+
+ % Label the interpreter info...
+ pageWidth 40 mul % x = pageWidth * 9/16 * 72
+ pageHeight 37 mul % y = pageHeight * 1/2 * 72
+ moveto % Position the text
+ mediumFont setfont % Font
+ (Interpreter Information) show % Show the text
+
+ smallFont setfont % Font
+ pageWidth 49 mul % x = pageWidth * 11/16 * 72
+ pageHeight 36 mul % y = pageWidth * 1/2 * 72
+ pageHeight 2 mul sub % y -= 2 * smallFont height
+
+ % Language level
+ 2 copy moveto % Move to x & y
+ (PostScript: ) RIGHT % Label
+ (Level ) show % "Level "
+ 1 languagelevel NUMBER % Language level
+
+ % Version
+ pageHeight 2 mul sub % Move down...
+ 2 copy moveto % Move to x & y
+ (Version: ) RIGHT % Label
+ version show % Version
+ ( \() show % " ("
+ 1 revision NUMBER % Revision
+ (\)) show % ")"
+
+ % Product
+ pageHeight 2 mul sub % Move down...
+ 2 copy moveto % Move to x & y
+ (Product: ) RIGHT % Label
+ product show % Product name
+
+ % Serial Number
+ pageHeight 2 mul sub % Move down...
+ 2 copy moveto % Move to x & y
+ (Serial #: ) RIGHT % Label
+ 1 serialnumber NUMBER % S/N
+
+ % Draw the label at the top...
+ pageWidth 36 mul % Center of page
+ pageHeight 68 mul % Top of page (15/16ths)
+ 2 copy moveto % Position text
+ bigFont setfont % Font
+ (Printer Test Page) CENTER % Show text centered
+
+ % Draw the copyright notice at the bottom...
+ pageWidth 36 mul % Center of page
+ pageHeight 10 mul % Bottom of page
+ 2 copy moveto % Position text
+ (Printed Using CUPS v1.1.x) CENTER % Show text centered
+
+ pageHeight 2 mul sub % Move down...
+ 2 copy moveto % Position text
+ smallFont setfont % Font
+ (Copyright 1993-2002 Easy Software Products, All Rights Reserved.) CENTER
+ pageHeight sub % Move down...
+ 2 copy moveto % Position text
+ (CUPS, Easy Software Products and their logos are the trademark property of) CENTER
+ pageHeight sub % Move down...
+ 2 copy moveto % Position text
+ (Easy Software Products, 44141 Airport View Drive, Suite 204,) CENTER
+ pageHeight sub % Move down...
+ 2 copy moveto % Position text
+ (Hollywood, Maryland, 20636-3111, USA.) CENTER
+
+ % Then the CUPS logo....
+ gsave
+ pageWidth 4 mul
+ pageHeight 4 mul
+ translate
+ pageWidth 9 mul CUPSLOGO
+ grestore
+
+ % And the ESP logo....
+ gsave
+ pageWidth 59 mul
+ pageHeight 4 mul
+ translate
+ pageWidth 6 mul ESPLOGO
+ grestore
+% Show the page...
+grestore
+showpage
+%
+% End of "$Id: testprint.ps 2362 2002-04-26 19:58:42Z swdev $".
+%
+%%EOF
diff --git a/data/topsecret b/data/topsecret
new file mode 100644
index 000000000..c5c77c340
--- /dev/null
+++ b/data/topsecret
@@ -0,0 +1,277 @@
+%!PS-Adobe-3.0
+%%BoundingBox: 0 0 612 792
+%%Pages: 1
+%%LanguageLevel: 1
+%%DocumentData: Clean7Bit
+%%DocumentSuppliedResources: procset bannerprint/1.0
+%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
+%%Creator: Michael Sweet, Easy Software Products
+%%CreationDate: May 10, 2000
+%%Title: Test Page
+%%EndComments
+%%BeginProlog
+%%BeginResource procset bannerprint 1.1 0
+%
+% PostScript banner page for the Common UNIX Printing System ("CUPS").
+%
+% Copyright 1993-2002 Easy Software Products
+%
+% These coded instructions, statements, and computer programs are the
+% property of Easy Software Products and are protected by Federal
+% copyright law. Distribution and use rights are outlined in the file
+% "LICENSE.txt" which should have been included with this file. If this
+% file is missing or damaged please contact Easy Software Products
+% at:
+%
+% Attn: CUPS Licensing Information
+% Easy Software Products
+% 44141 Airport View Drive, Suite 204
+% Hollywood, Maryland 20636-3111 USA
+%
+% Voice: (301) 373-9603
+% EMail: cups-info@cups.org
+% WWW: http://www.cups.org
+%
+/CENTER { % Draw centered text
+ % (name) CENTER -
+ dup stringwidth pop % Get the width of the string
+ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
+ show % Show the string
+} bind def
+/RIGHT { % Draw right-justified text
+ % (name) RIGHT -
+ dup stringwidth pop % Get the width of the string
+ neg 0 rmoveto % Shift left the entire distance
+ show % Show the string
+} bind def
+/NUMBER { % Draw a number
+ % power n NUMBER -
+ 1 index 1 eq { % power == 1?
+ round cvi exch pop % Convert "n" to integer
+ } {
+ 1 index mul round exch div % Truncate extra decimal places
+ } ifelse
+ 100 string cvs show % Convert to a string and show it...
+} bind def
+/CUPSLOGO { % Draw the CUPS logo
+ % height CUPSLOGO
+ % Start with a big C...
+ /Helvetica findfont 1 index scalefont setfont
+ 0 setgray
+ 0 0 moveto
+ (C) show
+
+ % Then "UNIX Printing System" much smaller...
+ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
+ 0.25 mul
+ dup dup 2.0 mul moveto
+ (UNIX) show
+ dup dup 1.6 mul moveto
+ (Printing) show
+ dup 1.2 mul moveto
+ (System) show
+} bind def
+/ESPLOGO { % Draw the ESP logo
+ % height ESPLOGO
+ % Compute the size of the logo...
+ 0 0
+ 2 index 1.5 mul 3 index
+
+ % Do the "metallic" fill from 10% black to 40% black...
+ 1 -0.001 0 {
+ dup % loopval
+ -0.15 mul % loopval * -0.15
+ 0.9 add % 0.9 - loopval * 0.15
+ setgray % set gray shade
+
+ 0 % x
+ 1 index neg % loopval
+ 1 add % 1 - loopval
+ 3 index % height
+ mul % height * (1 - loopval)
+ moveto % starting point
+
+ dup % loopval
+ 3 index % width
+ mul % loopval * width
+ 2 index % height
+ lineto % Next point
+
+ 0 % x
+ 2 index % height
+ lineto % Next point
+
+ closepath
+ fill
+
+ dup % loopval
+ 0.15 mul % loopval * 0.15
+ 0.6 add % 0.6 + loopval * 0.15
+ setgray
+
+ dup % loopval
+ neg 1 add % 1 - loopval
+ 3 index % width
+ mul % (1 - loopval) * width
+ 0 % y
+ moveto % Starting point
+
+ 2 index % width
+ exch % loopval
+ 2 index % height
+ mul % loopval * height
+ lineto % Next point
+
+ 1 index % width
+ 0 % y
+ lineto % Next point
+
+ closepath
+ fill
+ } for
+
+ 0 setgray rectstroke
+
+ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
+ dup 40 div
+
+ dup 4 mul 1 index 25 mul moveto (E) show
+ dup 10 mul 1 index 15 mul moveto (S) show
+ dup 16 mul 1 index 5 mul moveto (P) show
+
+ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
+ dup 14 mul 1 index 29 mul moveto (asy) show
+ dup 20 mul 1 index 19 mul moveto (oftware) show
+ dup 26 mul 1 index 9 mul moveto (roducts) show
+
+ pop
+} bind def
+%%EndResource
+%%EndProlog
+%%Page: 1 1
+gsave
+
+ % Determine the imageable area and device resolution...
+ initclip newpath clippath pathbbox % Get bounding rectangle
+ 72 div /pageTop exch def % Get top margin in inches
+ 72 div /pageRight exch def % Get right margin in inches
+ 72 div /pageBottom exch def % Get bottom margin in inches
+ 72 div /pageLeft exch def % Get left margin in inches
+
+ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
+ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
+
+ /boxWidth % width of text box
+ pageWidth pageHeight lt
+ { pageWidth 54 mul }
+ { pageHeight 42 mul }
+ ifelse def
+
+ newpath % Clear bounding path
+
+ % Create fonts...
+ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
+ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
+
+ /mediumFont /Helvetica findfont % mediumFont = Helvetica
+ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
+
+ % Offset page to account for lower-left margin...
+ pageLeft 72 mul
+ pageBottom 72 mul
+ translate
+
+ % Draw the label at the top and bottom...
+ 0 setgray % Color
+
+ pageWidth 36 mul % Center of page
+ pageHeight 72 mul % Top of page
+ pageWidth -7 mul add % - 2 lines
+ moveto % Position text
+ bigFont setfont % Font
+ (Top Secret) CENTER % Show text centered
+
+ pageWidth 36 mul % Center of page
+ pageHeight 6 mul % Bottom of page
+ moveto % Position text
+ bigFont setfont % Font
+ (Top Secret) CENTER % Show text centered
+
+ % Job information box...
+ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+ 0.5 setgray rectfill % Draw a shadow
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul % y = pageHeight * 1/4 * 72
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+
+ 4 copy 1 setgray rectfill % Clear the box to white
+ 0 setgray rectstroke % Draw a black box around it...
+
+ % Job information text...
+ mediumFont setfont % Medium sized font
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 5 mul add % y += 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Job ID: ) RIGHT
+ moveto
+ ({printer-name}-{job-id}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 2 mul add % y += 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Title: ) RIGHT
+ moveto
+ ({job-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -1 mul add % y -= 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Requesting User: ) RIGHT
+ moveto
+ ({job-originating-user-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -4 mul add % y -= 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Billing Info: ) RIGHT
+ moveto
+ ({?job-billing}) show
+
+ % Then the CUPS logo....
+ gsave
+ pageWidth 4 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 9 mul CUPSLOGO
+ grestore
+
+ % And the ESP logo....
+ gsave
+ pageWidth 59 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 6 mul ESPLOGO
+ grestore
+% Show the page...
+grestore
+showpage
+%
+% End of "$Id: topsecret 2122 2002-01-31 14:19:37Z mike $".
+%
+%%EOF
diff --git a/data/unclassified b/data/unclassified
new file mode 100644
index 000000000..d53190841
--- /dev/null
+++ b/data/unclassified
@@ -0,0 +1,277 @@
+%!PS-Adobe-3.0
+%%BoundingBox: 0 0 612 792
+%%Pages: 1
+%%LanguageLevel: 1
+%%DocumentData: Clean7Bit
+%%DocumentSuppliedResources: procset bannerprint/1.0
+%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
+%%Creator: Michael Sweet, Easy Software Products
+%%CreationDate: May 10, 2000
+%%Title: Test Page
+%%EndComments
+%%BeginProlog
+%%BeginResource procset bannerprint 1.1 0
+%
+% PostScript banner page for the Common UNIX Printing System ("CUPS").
+%
+% Copyright 1993-2002 Easy Software Products
+%
+% These coded instructions, statements, and computer programs are the
+% property of Easy Software Products and are protected by Federal
+% copyright law. Distribution and use rights are outlined in the file
+% "LICENSE.txt" which should have been included with this file. If this
+% file is missing or damaged please contact Easy Software Products
+% at:
+%
+% Attn: CUPS Licensing Information
+% Easy Software Products
+% 44141 Airport View Drive, Suite 204
+% Hollywood, Maryland 20636-3111 USA
+%
+% Voice: (301) 373-9603
+% EMail: cups-info@cups.org
+% WWW: http://www.cups.org
+%
+/CENTER { % Draw centered text
+ % (name) CENTER -
+ dup stringwidth pop % Get the width of the string
+ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
+ show % Show the string
+} bind def
+/RIGHT { % Draw right-justified text
+ % (name) RIGHT -
+ dup stringwidth pop % Get the width of the string
+ neg 0 rmoveto % Shift left the entire distance
+ show % Show the string
+} bind def
+/NUMBER { % Draw a number
+ % power n NUMBER -
+ 1 index 1 eq { % power == 1?
+ round cvi exch pop % Convert "n" to integer
+ } {
+ 1 index mul round exch div % Truncate extra decimal places
+ } ifelse
+ 100 string cvs show % Convert to a string and show it...
+} bind def
+/CUPSLOGO { % Draw the CUPS logo
+ % height CUPSLOGO
+ % Start with a big C...
+ /Helvetica findfont 1 index scalefont setfont
+ 0 setgray
+ 0 0 moveto
+ (C) show
+
+ % Then "UNIX Printing System" much smaller...
+ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
+ 0.25 mul
+ dup dup 2.0 mul moveto
+ (UNIX) show
+ dup dup 1.6 mul moveto
+ (Printing) show
+ dup 1.2 mul moveto
+ (System) show
+} bind def
+/ESPLOGO { % Draw the ESP logo
+ % height ESPLOGO
+ % Compute the size of the logo...
+ 0 0
+ 2 index 1.5 mul 3 index
+
+ % Do the "metallic" fill from 10% black to 40% black...
+ 1 -0.001 0 {
+ dup % loopval
+ -0.15 mul % loopval * -0.15
+ 0.9 add % 0.9 - loopval * 0.15
+ setgray % set gray shade
+
+ 0 % x
+ 1 index neg % loopval
+ 1 add % 1 - loopval
+ 3 index % height
+ mul % height * (1 - loopval)
+ moveto % starting point
+
+ dup % loopval
+ 3 index % width
+ mul % loopval * width
+ 2 index % height
+ lineto % Next point
+
+ 0 % x
+ 2 index % height
+ lineto % Next point
+
+ closepath
+ fill
+
+ dup % loopval
+ 0.15 mul % loopval * 0.15
+ 0.6 add % 0.6 + loopval * 0.15
+ setgray
+
+ dup % loopval
+ neg 1 add % 1 - loopval
+ 3 index % width
+ mul % (1 - loopval) * width
+ 0 % y
+ moveto % Starting point
+
+ 2 index % width
+ exch % loopval
+ 2 index % height
+ mul % loopval * height
+ lineto % Next point
+
+ 1 index % width
+ 0 % y
+ lineto % Next point
+
+ closepath
+ fill
+ } for
+
+ 0 setgray rectstroke
+
+ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
+ dup 40 div
+
+ dup 4 mul 1 index 25 mul moveto (E) show
+ dup 10 mul 1 index 15 mul moveto (S) show
+ dup 16 mul 1 index 5 mul moveto (P) show
+
+ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
+ dup 14 mul 1 index 29 mul moveto (asy) show
+ dup 20 mul 1 index 19 mul moveto (oftware) show
+ dup 26 mul 1 index 9 mul moveto (roducts) show
+
+ pop
+} bind def
+%%EndResource
+%%EndProlog
+%%Page: 1 1
+gsave
+
+ % Determine the imageable area and device resolution...
+ initclip newpath clippath pathbbox % Get bounding rectangle
+ 72 div /pageTop exch def % Get top margin in inches
+ 72 div /pageRight exch def % Get right margin in inches
+ 72 div /pageBottom exch def % Get bottom margin in inches
+ 72 div /pageLeft exch def % Get left margin in inches
+
+ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
+ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
+
+ /boxWidth % width of text box
+ pageWidth pageHeight lt
+ { pageWidth 54 mul }
+ { pageHeight 42 mul }
+ ifelse def
+
+ newpath % Clear bounding path
+
+ % Create fonts...
+ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
+ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
+
+ /mediumFont /Helvetica findfont % mediumFont = Helvetica
+ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
+
+ % Offset page to account for lower-left margin...
+ pageLeft 72 mul
+ pageBottom 72 mul
+ translate
+
+ % Draw the label at the top and bottom...
+ 0 setgray % Color
+
+ pageWidth 36 mul % Center of page
+ pageHeight 72 mul % Top of page
+ pageWidth -7 mul add % - 2 lines
+ moveto % Position text
+ bigFont setfont % Font
+ (Unclassified) CENTER % Show text centered
+
+ pageWidth 36 mul % Center of page
+ pageHeight 6 mul % Bottom of page
+ moveto % Position text
+ bigFont setfont % Font
+ (Unclassified) CENTER % Show text centered
+
+ % Job information box...
+ pageWidth 36 mul 9 add % x = pageWidth * 1/2 * 72 + 9
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul 9 sub % y = pageHeight * 1/2 * 72 - 9
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+ 0.5 setgray rectfill % Draw a shadow
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ boxWidth 0.5 mul sub % x-= 1/2 box width
+ pageHeight 30 mul % y = pageHeight * 1/4 * 72
+ boxWidth % w = box width
+ pageHeight 14 mul % h = pageHeight * 1/2 * 72
+
+ 4 copy 1 setgray rectfill % Clear the box to white
+ 0 setgray rectstroke % Draw a black box around it...
+
+ % Job information text...
+ mediumFont setfont % Medium sized font
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 5 mul add % y += 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Job ID: ) RIGHT
+ moveto
+ ({printer-name}-{job-id}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight 2 mul add % y += 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Title: ) RIGHT
+ moveto
+ ({job-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -1 mul add % y -= 1 line
+ 2 copy % Copy X & Y
+ moveto
+ (Requesting User: ) RIGHT
+ moveto
+ ({job-originating-user-name}) show
+
+ pageWidth 36 mul % x = pageWidth * 1/2 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ pageHeight -4 mul add % y -= 2 lines
+ 2 copy % Copy X & Y
+ moveto
+ (Billing Info: ) RIGHT
+ moveto
+ ({?job-billing}) show
+
+ % Then the CUPS logo....
+ gsave
+ pageWidth 4 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 9 mul CUPSLOGO
+ grestore
+
+ % And the ESP logo....
+ gsave
+ pageWidth 59 mul
+ pageWidth 6 mul
+ translate
+ pageWidth 6 mul ESPLOGO
+ grestore
+% Show the page...
+grestore
+showpage
+%
+% End of "$Id: unclassified 2122 2002-01-31 14:19:37Z mike $".
+%
+%%EOF
diff --git a/data/utf-8 b/data/utf-8
new file mode 100644
index 000000000..b73eb9667
--- /dev/null
+++ b/data/utf-8
@@ -0,0 +1,39 @@
+charset utf8
+
+#
+# This file defines the font mappings used for Unicode/UTF-8 text printing.
+#
+# Each line consists of:
+#
+# first last direction width normal bold italic bold-italic
+#
+# First and last are the first and last glyphs in the font mapping
+# that correspond to that font; a maximum of 256 characters can be
+# mapped within each group, with a maximum of 256 mappings (this is a
+# PostScript limitation.) The glyph values are hexadecimal.
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+0000 00FF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic
+0100 01FF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic
+0200 02FF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic
+0300 03FF ltor single Symbol
+0400 04FF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic
+0500 05FF rtol single Courier
+1E00 1EFF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic
+2000 20FF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic
+2100 21FF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic
+2200 22FF ltor single Symbol
+2300 23FF ltor single Symbol
diff --git a/data/windows-1250 b/data/windows-1250
new file mode 100644
index 000000000..afcc62ed5
--- /dev/null
+++ b/data/windows-1250
@@ -0,0 +1,254 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Windows
+# Code Page 1250 (WinLatin2) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 20AC
+82 201A
+84 201E
+85 2026
+86 2020
+87 2021
+89 2030
+8A 0160
+8B 2039
+8C 015A
+8D 0164
+8E 017D
+8F 0179
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+99 2122
+9A 0161
+9B 203A
+9C 015B
+9D 0165
+9E 017E
+9F 017A
+A0 00A0
+A1 02C7
+A2 02D8
+A3 0141
+A4 00A4
+A5 0104
+A6 00A6
+A7 00A7
+A8 00A8
+A9 00A9
+AA 015E
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 017B
+B0 00B0
+B1 00B1
+B2 02DB
+B3 0142
+B4 00B4
+B5 00B5
+B6 00B6
+B7 00B7
+B8 00B8
+B9 0105
+BA 015F
+BB 00BB
+BC 013D
+BD 02DD
+BE 013E
+BF 017C
+C0 0154
+C1 00C1
+C2 00C2
+C3 0102
+C4 00C4
+C5 0139
+C6 0106
+C7 00C7
+C8 010C
+C9 00C9
+CA 0118
+CB 00CB
+CC 011A
+CD 00CD
+CE 00CE
+CF 010E
+D0 0110
+D1 0143
+D2 0147
+D3 00D3
+D4 00D4
+D5 0150
+D6 00D6
+D7 00D7
+D8 0158
+D9 016E
+DA 00DA
+DB 0170
+DC 00DC
+DD 00DD
+DE 0162
+DF 00DF
+E0 0155
+E1 00E1
+E2 00E2
+E3 0103
+E4 00E4
+E5 013A
+E6 0107
+E7 00E7
+E8 010D
+E9 00E9
+EA 0119
+EB 00EB
+EC 011B
+ED 00ED
+EE 00EE
+EF 010F
+F0 0111
+F1 0144
+F2 0148
+F3 00F3
+F4 00F4
+F5 0151
+F6 00F6
+F7 00F7
+F8 0159
+F9 016F
+FA 00FA
+FB 0171
+FC 00FC
+FD 00FD
+FE 0163
+FF 02D9
diff --git a/data/windows-1251 b/data/windows-1251
new file mode 100644
index 000000000..6d31dee09
--- /dev/null
+++ b/data/windows-1251
@@ -0,0 +1,258 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Windows
+# Code Page 1251 (WinCyrillic) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 0402
+81 0403
+82 201A
+83 0453
+84 201E
+85 2026
+86 2020
+87 2021
+88 20AC
+89 2030
+8A 0409
+8B 2039
+8C 040A
+8D 040C
+8E 040B
+8F 040F
+90 0452
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+99 2122
+9A 0459
+9B 203A
+9C 045A
+9D 045C
+9E 045B
+9F 045F
+A0 00A0
+A1 040E
+A2 045E
+A3 0408
+A4 00A4
+A5 0490
+A6 00A6
+A7 00A7
+A8 0401
+A9 00A9
+AA 0404
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 0407
+B0 00B0
+B1 00B1
+B2 0406
+B3 0456
+B4 0491
+B5 00B5
+B6 00B6
+B7 00B7
+B8 0451
+B9 2116
+BA 0454
+BB 00BB
+BC 0458
+BD 0405
+BE 0455
+BF 0457
+C0 0410
+C1 0411
+C2 0412
+C3 0413
+C4 0414
+C5 0415
+C6 0416
+C7 0417
+C8 0418
+C9 0419
+CA 041A
+CB 041B
+CC 041C
+CD 041D
+CE 041E
+CF 041F
+D0 0420
+D1 0421
+D2 0422
+D3 0423
+D4 0424
+D5 0425
+D6 0426
+D7 0427
+D8 0428
+D9 0429
+DA 042A
+DB 042B
+DC 042C
+DD 042D
+DE 042E
+DF 042F
+E0 0430
+E1 0431
+E2 0432
+E3 0433
+E4 0434
+E5 0435
+E6 0436
+E7 0437
+E8 0438
+E9 0439
+EA 043A
+EB 043B
+EC 043C
+ED 043D
+EE 043E
+EF 043F
+F0 0440
+F1 0441
+F2 0442
+F3 0443
+F4 0444
+F5 0445
+F6 0446
+F7 0447
+F8 0448
+F9 0449
+FA 044A
+FB 044B
+FC 044C
+FD 044D
+FE 044E
+FF 044F
diff --git a/data/windows-1252 b/data/windows-1252
new file mode 100644
index 000000000..a98595874
--- /dev/null
+++ b/data/windows-1252
@@ -0,0 +1,254 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Windows
+# Code Page 1252 (WinLatin1) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+8E 017D
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9E 017E
+9F 0178
+A0 00A0
+A1 00A1
+A2 00A2
+A3 00A3
+A4 00A4
+A5 00A5
+A6 00A6
+A7 00A7
+A8 00A8
+A9 00A9
+AA 00AA
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 00AF
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 00B4
+B5 00B5
+B6 00B6
+B7 00B7
+B8 00B8
+B9 00B9
+BA 00BA
+BB 00BB
+BC 00BC
+BD 00BD
+BE 00BE
+BF 00BF
+C0 00C0
+C1 00C1
+C2 00C2
+C3 00C3
+C4 00C4
+C5 00C5
+C6 00C6
+C7 00C7
+C8 00C8
+C9 00C9
+CA 00CA
+CB 00CB
+CC 00CC
+CD 00CD
+CE 00CE
+CF 00CF
+D0 00D0
+D1 00D1
+D2 00D2
+D3 00D3
+D4 00D4
+D5 00D5
+D6 00D6
+D7 00D7
+D8 00D8
+D9 00D9
+DA 00DA
+DB 00DB
+DC 00DC
+DD 00DD
+DE 00DE
+DF 00DF
+E0 00E0
+E1 00E1
+E2 00E2
+E3 00E3
+E4 00E4
+E5 00E5
+E6 00E6
+E7 00E7
+E8 00E8
+E9 00E9
+EA 00EA
+EB 00EB
+EC 00EC
+ED 00ED
+EE 00EE
+EF 00EF
+F0 00F0
+F1 00F1
+F2 00F2
+F3 00F3
+F4 00F4
+F5 00F5
+F6 00F6
+F7 00F7
+F8 00F8
+F9 00F9
+FA 00FA
+FB 00FB
+FC 00FC
+FD 00FD
+FE 00FE
+FF 00FF
diff --git a/data/windows-1253 b/data/windows-1253
new file mode 100644
index 000000000..c736ecd6c
--- /dev/null
+++ b/data/windows-1253
@@ -0,0 +1,243 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Windows
+# Code Page 1253 (WinGreek) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 9f ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+a0 ff ltor single Symbol
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+89 2030
+8B 2039
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+99 2122
+9B 203A
+A0 00A0
+A1 0385
+A2 0386
+A3 00A3
+A4 00A4
+A5 00A5
+A6 00A6
+A7 00A7
+A8 00A8
+A9 00A9
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 2015
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 0384
+B5 00B5
+B6 00B6
+B7 00B7
+B8 0388
+B9 0389
+BA 038A
+BB 00BB
+BC 038C
+BD 00BD
+BE 038E
+BF 038F
+C0 0390
+C1 0391
+C2 0392
+C3 0393
+C4 0394
+C5 0395
+C6 0396
+C7 0397
+C8 0398
+C9 0399
+CA 039A
+CB 039B
+CC 039C
+CD 039D
+CE 039E
+CF 039F
+D0 03A0
+D1 03A1
+D3 03A3
+D4 03A4
+D5 03A5
+D6 03A6
+D7 03A7
+D8 03A8
+D9 03A9
+DA 03AA
+DB 03AB
+DC 03AC
+DD 03AD
+DE 03AE
+DF 03AF
+E0 03B0
+E1 03B1
+E2 03B2
+E3 03B3
+E4 03B4
+E5 03B5
+E6 03B6
+E7 03B7
+E8 03B8
+E9 03B9
+EA 03BA
+EB 03BB
+EC 03BC
+ED 03BD
+EE 03BE
+EF 03BF
+F0 03C0
+F1 03C1
+F2 03C2
+F3 03C3
+F4 03C4
+F5 03C5
+F6 03C6
+F7 03C7
+F8 03C8
+F9 03C9
+FA 03CA
+FB 03CB
+FC 03CC
+FD 03CD
+FE 03CE
diff --git a/data/windows-1254 b/data/windows-1254
new file mode 100644
index 000000000..87fff2db7
--- /dev/null
+++ b/data/windows-1254
@@ -0,0 +1,252 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Windows
+# Code Page 1254 (WinTurkish) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0160
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9A 0161
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 00A1
+A2 00A2
+A3 00A3
+A4 00A4
+A5 00A5
+A6 00A6
+A7 00A7
+A8 00A8
+A9 00A9
+AA 00AA
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 00AF
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 00B4
+B5 00B5
+B6 00B6
+B7 00B7
+B8 00B8
+B9 00B9
+BA 00BA
+BB 00BB
+BC 00BC
+BD 00BD
+BE 00BE
+BF 00BF
+C0 00C0
+C1 00C1
+C2 00C2
+C3 00C3
+C4 00C4
+C5 00C5
+C6 00C6
+C7 00C7
+C8 00C8
+C9 00C9
+CA 00CA
+CB 00CB
+CC 00CC
+CD 00CD
+CE 00CE
+CF 00CF
+D0 011E
+D1 00D1
+D2 00D2
+D3 00D3
+D4 00D4
+D5 00D5
+D6 00D6
+D7 00D7
+D8 00D8
+D9 00D9
+DA 00DA
+DB 00DB
+DC 00DC
+DD 0130
+DE 015E
+DF 00DF
+E0 00E0
+E1 00E1
+E2 00E2
+E3 00E3
+E4 00E4
+E5 00E5
+E6 00E6
+E7 00E7
+E8 00E8
+E9 00E9
+EA 00EA
+EB 00EB
+EC 00EC
+ED 00ED
+EE 00EE
+EF 00EF
+F0 011F
+F1 00F1
+F2 00F2
+F3 00F3
+F4 00F4
+F5 00F5
+F6 00F6
+F7 00F7
+F8 00F8
+F9 00F9
+FA 00FA
+FB 00FB
+FC 00FC
+FD 0131
+FE 015F
+FF 00FF
diff --git a/data/windows-1255 b/data/windows-1255
new file mode 100644
index 000000000..a8b26a85d
--- /dev/null
+++ b/data/windows-1255
@@ -0,0 +1,236 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Windows
+# Code Page 1255 (WinHebrew) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff rtol single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8B 2039
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9B 203A
+A0 00A0
+A1 00A1
+A2 00A2
+A3 00A3
+A4 20AA
+A5 00A5
+A6 00A6
+A7 00A7
+A8 00A8
+A9 00A9
+AA 00D7
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 00AF
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 00B4
+B5 00B5
+B6 00B6
+B7 00B7
+B8 00B8
+B9 00B9
+BA 00F7
+BB 00BB
+BC 00BC
+BD 00BD
+BE 00BE
+BF 00BF
+C0 05B0
+C1 05B1
+C2 05B2
+C3 05B3
+C4 05B4
+C5 05B5
+C6 05B6
+C7 05B7
+C8 05B8
+C9 05B9
+CB 05BB
+CC 05BC
+CD 05BD
+CE 05BE
+CF 05BF
+D0 05C0
+D1 05C1
+D2 05C2
+D3 05C3
+D4 05F0
+D5 05F1
+D6 05F2
+D7 05F3
+D8 05F4
+E0 05D0
+E1 05D1
+E2 05D2
+E3 05D3
+E4 05D4
+E5 05D5
+E6 05D6
+E7 05D7
+E8 05D8
+E9 05D9
+EA 05DA
+EB 05DB
+EC 05DC
+ED 05DD
+EE 05DE
+EF 05DF
+F0 05E0
+F1 05E1
+F2 05E2
+F3 05E3
+F4 05E4
+F5 05E5
+F6 05E6
+F7 05E7
+F8 05E8
+F9 05E9
+FA 05EA
+FD 200E
+FE 200F
diff --git a/data/windows-1256 b/data/windows-1256
new file mode 100644
index 000000000..6908f1eb5
--- /dev/null
+++ b/data/windows-1256
@@ -0,0 +1,259 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Windows
+# Code Page 1256 (WinArabic) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff rtol single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 20AC
+81 067E
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8A 0679
+8B 2039
+8C 0152
+8D 0686
+8E 0698
+8F 0688
+90 06AF
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 06A9
+99 2122
+9A 0691
+9B 203A
+9C 0153
+9D 200C
+9E 200D
+9F 06BA
+A0 00A0
+A1 060C
+A2 00A2
+A3 00A3
+A4 00A4
+A5 00A5
+A6 00A6
+A7 00A7
+A8 00A8
+A9 00A9
+AA 06BE
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 00AF
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 00B4
+B5 00B5
+B6 00B6
+B7 00B7
+B8 00B8
+B9 00B9
+BA 061B
+BB 00BB
+BC 00BC
+BD 00BD
+BE 00BE
+BF 061F
+C0 06C1
+C1 0621
+C2 0622
+C3 0623
+C4 0624
+C5 0625
+C6 0626
+C7 0627
+C8 0628
+C9 0629
+CA 062A
+CB 062B
+CC 062C
+CD 062D
+CE 062E
+CF 062F
+D0 0630
+D1 0631
+D2 0632
+D3 0633
+D4 0634
+D5 0635
+D6 0636
+D7 00D7
+D8 0637
+D9 0638
+DA 0639
+DB 063A
+DC 0640
+DD 0641
+DE 0642
+DF 0643
+E0 00E0
+E1 0644
+E2 00E2
+E3 0645
+E4 0646
+E5 0647
+E6 0648
+E7 00E7
+E8 00E8
+E9 00E9
+EA 00EA
+EB 00EB
+EC 0649
+ED 064A
+EE 00EE
+EF 00EF
+F0 064B
+F1 064C
+F2 064D
+F3 064E
+F4 00F4
+F5 064F
+F6 0650
+F7 00F7
+F8 0651
+F9 00F9
+FA 0652
+FB 00FB
+FC 00FC
+FD 200E
+FE 200F
+FF 06D2
diff --git a/data/windows-1257 b/data/windows-1257
new file mode 100644
index 000000000..ac5f8e0b7
--- /dev/null
+++ b/data/windows-1257
@@ -0,0 +1,247 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Windows
+# Code Page 1257 (WinBaltic) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 20AC
+82 201A
+84 201E
+85 2026
+86 2020
+87 2021
+89 2030
+8B 2039
+8D 00A8
+8E 02C7
+8F 00B8
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+99 2122
+9B 203A
+9D 00AF
+9E 02DB
+A0 00A0
+A2 00A2
+A3 00A3
+A4 00A4
+A6 00A6
+A7 00A7
+A8 00D8
+A9 00A9
+AA 0156
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 00C6
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 00B4
+B5 00B5
+B6 00B6
+B7 00B7
+B8 00F8
+B9 00B9
+BA 0157
+BB 00BB
+BC 00BC
+BD 00BD
+BE 00BE
+BF 00E6
+C0 0104
+C1 012E
+C2 0100
+C3 0106
+C4 00C4
+C5 00C5
+C6 0118
+C7 0112
+C8 010C
+C9 00C9
+CA 0179
+CB 0116
+CC 0122
+CD 0136
+CE 012A
+CF 013B
+D0 0160
+D1 0143
+D2 0145
+D3 00D3
+D4 014C
+D5 00D5
+D6 00D6
+D7 00D7
+D8 0172
+D9 0141
+DA 015A
+DB 016A
+DC 00DC
+DD 017B
+DE 017D
+DF 00DF
+E0 0105
+E1 012F
+E2 0101
+E3 0107
+E4 00E4
+E5 00E5
+E6 0119
+E7 0113
+E8 010D
+E9 00E9
+EA 017A
+EB 0117
+EC 0123
+ED 0137
+EE 012B
+EF 013C
+F0 0161
+F1 0144
+F2 0146
+F3 00F3
+F4 014D
+F5 00F5
+F6 00F6
+F7 00F7
+F8 0173
+F9 0142
+FA 015B
+FB 016B
+FC 00FC
+FD 017C
+FE 017E
+FF 02D9
diff --git a/data/windows-1258 b/data/windows-1258
new file mode 100644
index 000000000..f7721c51b
--- /dev/null
+++ b/data/windows-1258
@@ -0,0 +1,250 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Windows
+# Code Page 1258 (WinVietnamese) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 20AC
+82 201A
+83 0192
+84 201E
+85 2026
+86 2020
+87 2021
+88 02C6
+89 2030
+8B 2039
+8C 0152
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+98 02DC
+99 2122
+9B 203A
+9C 0153
+9F 0178
+A0 00A0
+A1 00A1
+A2 00A2
+A3 00A3
+A4 00A4
+A5 00A5
+A6 00A6
+A7 00A7
+A8 00A8
+A9 00A9
+AA 00AA
+AB 00AB
+AC 00AC
+AD 00AD
+AE 00AE
+AF 00AF
+B0 00B0
+B1 00B1
+B2 00B2
+B3 00B3
+B4 00B4
+B5 00B5
+B6 00B6
+B7 00B7
+B8 00B8
+B9 00B9
+BA 00BA
+BB 00BB
+BC 00BC
+BD 00BD
+BE 00BE
+BF 00BF
+C0 00C0
+C1 00C1
+C2 00C2
+C3 0102
+C4 00C4
+C5 00C5
+C6 00C6
+C7 00C7
+C8 00C8
+C9 00C9
+CA 00CA
+CB 00CB
+CC 0300
+CD 00CD
+CE 00CE
+CF 00CF
+D0 0110
+D1 00D1
+D2 0309
+D3 00D3
+D4 00D4
+D5 01A0
+D6 00D6
+D7 00D7
+D8 00D8
+D9 00D9
+DA 00DA
+DB 00DB
+DC 00DC
+DD 01AF
+DE 0303
+DF 00DF
+E0 00E0
+E1 00E1
+E2 00E2
+E3 0103
+E4 00E4
+E5 00E5
+E6 00E6
+E7 00E7
+E8 00E8
+E9 00E9
+EA 00EA
+EB 00EB
+EC 0301
+ED 00ED
+EE 00EE
+EF 00EF
+F0 0111
+F1 00F1
+F2 0323
+F3 00F3
+F4 00F4
+F5 01A1
+F6 00F6
+F7 00F7
+F8 00F8
+F9 00F9
+FA 00FA
+FB 00FB
+FC 00FC
+FD 01B0
+FE 20AB
+FF 00FF
diff --git a/data/windows-874 b/data/windows-874
new file mode 100644
index 000000000..886e46a4b
--- /dev/null
+++ b/data/windows-874
@@ -0,0 +1,228 @@
+charset 8bit
+
+#
+# This file defines the font and character mappings used for Windows
+# Code Page 874 (Thai) text printing.
+#
+# The first line consists of:
+#
+# direction width normal bold italic bold-italic
+#
+# Direction is the string "ltor" or "rtol", indicating left-to-right or
+# right-to-left text.
+#
+# Width is the string "single" or "double"; double means that the glyphs
+# are twice as wide as ASCII characters in the Courier typeface.
+#
+# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use
+# for each presentation. If characters are only available in a single
+# style then only one typeface should be listed (e.g. "Symbol")
+#
+# Each font that is listed will be used (and downloaded if needed) when
+# printing.
+#
+
+00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic
+
+#
+# The following lines define the mapping from the 8-bit character set to
+# the Unicode glyphs for each character:
+#
+# char glyph
+#
+# "Char" and "glyph" are hexadecimal values.
+#
+
+20 0020
+21 0021
+22 0022
+23 0023
+24 0024
+25 0025
+26 0026
+27 0027
+28 0028
+29 0029
+2A 002A
+2B 002B
+2C 002C
+2D 002D
+2E 002E
+2F 002F
+30 0030
+31 0031
+32 0032
+33 0033
+34 0034
+35 0035
+36 0036
+37 0037
+38 0038
+39 0039
+3A 003A
+3B 003B
+3C 003C
+3D 003D
+3E 003E
+3F 003F
+40 0040
+41 0041
+42 0042
+43 0043
+44 0044
+45 0045
+46 0046
+47 0047
+48 0048
+49 0049
+4A 004A
+4B 004B
+4C 004C
+4D 004D
+4E 004E
+4F 004F
+50 0050
+51 0051
+52 0052
+53 0053
+54 0054
+55 0055
+56 0056
+57 0057
+58 0058
+59 0059
+5A 005A
+5B 005B
+5C 005C
+5D 005D
+5E 005E
+5F 005F
+60 0060
+61 0061
+62 0062
+63 0063
+64 0064
+65 0065
+66 0066
+67 0067
+68 0068
+69 0069
+6A 006A
+6B 006B
+6C 006C
+6D 006D
+6E 006E
+6F 006F
+70 0070
+71 0071
+72 0072
+73 0073
+74 0074
+75 0075
+76 0076
+77 0077
+78 0078
+79 0079
+7A 007A
+7B 007B
+7C 007C
+7D 007D
+7E 007E
+7F 007F
+80 20AC
+85 2026
+91 2018
+92 2019
+93 201C
+94 201D
+95 2022
+96 2013
+97 2014
+A0 00A0
+A1 0E01
+A2 0E02
+A3 0E03
+A4 0E04
+A5 0E05
+A6 0E06
+A7 0E07
+A8 0E08
+A9 0E09
+AA 0E0A
+AB 0E0B
+AC 0E0C
+AD 0E0D
+AE 0E0E
+AF 0E0F
+B0 0E10
+B1 0E11
+B2 0E12
+B3 0E13
+B4 0E14
+B5 0E15
+B6 0E16
+B7 0E17
+B8 0E18
+B9 0E19
+BA 0E1A
+BB 0E1B
+BC 0E1C
+BD 0E1D
+BE 0E1E
+BF 0E1F
+C0 0E20
+C1 0E21
+C2 0E22
+C3 0E23
+C4 0E24
+C5 0E25
+C6 0E26
+C7 0E27
+C8 0E28
+C9 0E29
+CA 0E2A
+CB 0E2B
+CC 0E2C
+CD 0E2D
+CE 0E2E
+CF 0E2F
+D0 0E30
+D1 0E31
+D2 0E32
+D3 0E33
+D4 0E34
+D5 0E35
+D6 0E36
+D7 0E37
+D8 0E38
+D9 0E39
+DA 0E3A
+DF 0E3F
+E0 0E40
+E1 0E41
+E2 0E42
+E3 0E43
+E4 0E44
+E5 0E45
+E6 0E46
+E7 0E47
+E8 0E48
+E9 0E49
+EA 0E4A
+EB 0E4B
+EC 0E4C
+ED 0E4D
+EE 0E4E
+EF 0E4F
+F0 0E50
+F1 0E51
+F2 0E52
+F3 0E53
+F4 0E54
+F5 0E55
+F6 0E56
+F7 0E57
+F8 0E58
+F9 0E59
+FA 0E5A
+FB 0E5B
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 000000000..7606216fe
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,242 @@
+#
+# "$Id$"
+#
+# Documentation makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9600
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+#
+# HTMLDOC generation rules...
+#
+
+.SUFFIXES: .html .pdf .ps .shtml
+.shtml.html:
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --numbered -f $@ $<
+.shtml.pdf:
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --compression=9 \
+ --numbered --jpeg -f $@ $<
+.shtml.ps:
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --numbered \
+ --jpeg -f $@ $<
+
+HTMLDOC = htmldoc --strict
+
+
+#
+# Document files...
+#
+
+DOCUMENTS = cmp.shtml idd.shtml ipp.shtml sam.shtml sdd.shtml \
+ spm.shtml sps.shtml ssr.shtml stp.shtml sum.shtml \
+ svd.shtml translation.shtml
+DOCIMAGES = images/cups-block-diagram.gif images/cups-large.gif \
+ images/cups-medium.gif images/cups-small.gif
+WEBPAGES = cups.css cupsdoc.css index.html documentation.html
+WEBIMAGES = images/accept-jobs.gif \
+ images/add-class.gif \
+ images/add-printer.gif \
+ images/cancel-job.gif \
+ images/cancel-jobs.gif \
+ images/cancel.gif \
+ images/classes.gif \
+ images/config-printer.gif \
+ images/continue.gif \
+ images/delete-class.gif \
+ images/delete-printer.gif \
+ images/draft.gif \
+ images/hold-job.gif \
+ images/left.gif \
+ images/logo.gif \
+ images/manage-classes.gif \
+ images/manage-jobs.gif \
+ images/manage-printers.gif \
+ images/modify-class.gif \
+ images/modify-printer.gif \
+ images/navbar.gif \
+ images/print-test-page.gif \
+ images/printer-idle.gif \
+ images/printer-processing.gif \
+ images/printer-stopped.gif \
+ images/reject-jobs.gif \
+ images/release-job.gif \
+ images/restart-job.gif \
+ images/right.gif \
+ images/show-active.gif \
+ images/show-completed.gif \
+ images/start-class.gif \
+ images/start-printer.gif \
+ images/stop-class.gif \
+ images/stop-printer.gif
+
+
+#
+# Make all documents...
+#
+
+all: $(DOCUMENTS:.shtml=.pdf) $(DOCUMENTS:.shtml=.html) overview.pdf
+ cd fr; make all
+
+
+#
+# Make PS files...
+#
+
+ps: $(DOCUMENTS:.shtml=.ps) overview.ps
+ cd fr; make ps
+
+
+#
+# Remove all generated files...
+#
+
+clean:
+ $(RM) $(DOCUMENTS:.shtml=.pdf)
+ $(RM) $(DOCUMENTS:.shtml=.html)
+ $(RM) overview.pdf
+ cd fr; make clean
+
+
+#
+# Install all documentation files...
+#
+
+install:
+ $(INSTALL_DIR) $(DOCDIR)
+ for file in $(WEBPAGES); do \
+ $(INSTALL_MAN) $$file $(DOCDIR); \
+ done
+ $(INSTALL_MAN) overview.html $(DOCDIR)
+ $(INSTALL_MAN) overview.pdf $(DOCDIR)
+ for file in $(DOCUMENTS:.shtml=.html); do \
+ $(INSTALL_MAN) $$file $(DOCDIR); \
+ done
+ for file in $(DOCUMENTS:.shtml=.pdf); do \
+ $(INSTALL_MAN) $$file $(DOCDIR); \
+ done
+ $(INSTALL_DIR) $(DOCDIR)/images
+ for file in $(WEBIMAGES) $(DOCIMAGES); do \
+ $(INSTALL_MAN) $$file $(DOCDIR)/images; \
+ done
+ cd fr; make install
+
+
+#
+# The overview, admin manual, programmers manual, and users manual get
+# special attention...
+#
+
+overview.pdf: overview.html
+ echo Formatting $@...
+ $(HTMLDOC) --duplex --compression=9 --jpeg --webpage -f overview.pdf overview.html
+overview.ps: overview.html
+ echo Formatting $@...
+ $(HTMLDOC) --duplex --jpeg --webpage -f overview.ps overview.html
+
+sam.html: sam.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif -f $@ $<
+sam.pdf: sam.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --compression=9 \
+ --jpeg -f $@ $<
+sam.ps: sam.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --jpeg -f $@ $<
+
+spm.html: spm.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif -f $@ $<
+spm.pdf: spm.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --compression=9 \
+ --jpeg -f $@ $<
+spm.ps: spm.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --jpeg -f $@ $<
+
+sum.html: sum.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif -f $@ $<
+sum.pdf: sum.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --compression=9 \
+ --jpeg -f $@ $<
+sum.ps: sum.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --jpeg -f $@ $<
+
+sam-7x8.pdf: sam.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --compression=9 \
+ --pagelayout tworight --pagemode document \
+ --jpeg --size 7x8.5in --left 0.5in --right 0.25in \
+ --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ sam.shtml
+sam-7x8.ps: sam.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --jpeg \
+ --size 7x8.5in --left 0.5in --right 0.25in \
+ --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ sam.shtml
+spm-7x8.pdf: spm.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --compression=9 \
+ --pagelayout tworight --pagemode document \
+ --jpeg --size 7x8.5in --left 0.5in --right 0.25in \
+ --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ spm.shtml
+spm-7x8.ps: spm.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --jpeg \
+ --size 7x8.5in --left 0.5in --right 0.25in \
+ --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ spm.shtml
+sum-7x8.pdf: sum.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --compression=9 \
+ --pagelayout tworight --pagemode document \
+ --jpeg --size 7x8.5in --left 0.5in --right 0.25in \
+ --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ sum.shtml
+sum-7x8.ps: sum.shtml
+ echo Formatting $@...
+ $(HTMLDOC) --titleimage images/cups-large.gif --duplex --jpeg \
+ --size 7x8.5in --left 0.5in --right 0.25in \
+ --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ sum.shtml
+
+$(DOCUMENTS:.shtml=.html): \
+ glossary.shtml printing-overview.shtml \
+ references.shtml system-overview.shtml \
+ ../LICENSE.html
+
+$(DOCUMENTS:.shtml=.pdf): \
+ glossary.shtml printing-overview.shtml \
+ references.shtml system-overview.shtml \
+ ../LICENSE.html
+
+$(DOCUMENTS:.shtml=.ps): \
+ glossary.shtml printing-overview.shtml \
+ references.shtml system-overview.shtml \
+ ../LICENSE.html
+
+
+#
+# End of Makefile.
+#
diff --git a/doc/cmp.html b/doc/cmp.html
new file mode 100644
index 000000000..a7d0c3856
--- /dev/null
+++ b/doc/cmp.html
@@ -0,0 +1,677 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Configuration Management Plan</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-CMP-1.1">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY>
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Configuration Management Plan</H1></A><BR>
+CUPS-CMP-1.1<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">1 Scope</A></B>
+<UL>
+<LI><A HREF="#1_1">1.1 Identification</A></LI>
+<LI><A HREF="#1_2">1.2 System Overview</A></LI>
+<LI><A HREF="#1_3">1.3 Document Overview</A></LI>
+</UL>
+<B><A HREF="#2">2 References</A></B>
+<UL>
+<LI><A HREF="#2_1">2.1 CUPS Documentation</A></LI>
+<LI><A HREF="#2_2">2.2 Other Documents</A></LI>
+</UL>
+<B><A HREF="#3">3 File Management</A></B>
+<UL>
+<LI><A HREF="#3_1">3.1 Directory Structure</A></LI>
+<LI><A HREF="#3_2">3.2 Source Files</A></LI>
+<LI><A HREF="#3_3">3.3 Configuration Management</A></LI>
+</UL>
+<B><A HREF="#4">4 Trouble Report Processing</A></B>
+<UL>
+<LI><A HREF="#4_1">4.1 Classification</A></LI>
+<LI><A HREF="#4_2">4.2 Identification</A></LI>
+<LI><A HREF="#4_3">4.3 Correction</A></LI>
+<LI><A HREF="#4_4">4.4 Notification</A></LI>
+</UL>
+<B><A HREF="#5">5 Software Releases</A></B>
+<UL>
+<LI><A HREF="#5_1">5.1 Version Numbering</A></LI>
+<LI><A HREF="#5_2">5.2 Generation</A></LI>
+<LI><A HREF="#5_3">5.3 Testing</A></LI>
+<LI><A HREF="#5_4">5.4 Release</A></LI>
+</UL>
+<B><A HREF="#6">A Glossary</A></B>
+<UL>
+<LI><A HREF="#6_1">A.1 Terms</A></LI>
+<LI><A HREF="#6_2">A.2 Acronyms</A></LI>
+</UL>
+<B><A HREF="#7">B Coding Requirements</A></B>
+<UL>
+<LI><A HREF="#7_1">B.1 Source Files</A></LI>
+<UL>
+<LI><A HREF="#7_1_1">B.1.1 Naming</A></LI>
+<LI><A HREF="#7_1_2">B.1.2 Documentation</A></LI>
+</UL>
+<LI><A HREF="#7_2">B.2 Functions</A></LI>
+<UL>
+<LI><A HREF="#7_2_1">B.2.1 Naming</A></LI>
+<LI><A HREF="#7_2_2">B.2.2 Documentation</A></LI>
+</UL>
+<LI><A HREF="#7_3">B.3 Methods</A></LI>
+<UL>
+<LI><A HREF="#7_3_1">B.3.1 Naming</A></LI>
+<LI><A HREF="#7_3_2">B.3.2 Documentation</A></LI>
+</UL>
+<LI><A HREF="#7_4">B.4 Variables</A></LI>
+<UL>
+<LI><A HREF="#7_4_1">B.4.1 Naming</A></LI>
+<LI><A HREF="#7_4_2">B.4.2 Documentation</A></LI>
+</UL>
+<LI><A HREF="#7_5">B.5 Types</A></LI>
+<UL>
+<LI><A HREF="#7_5_1">B.5.1 Naming</A></LI>
+<LI><A HREF="#7_5_2">B.5.2 Documentation</A></LI>
+</UL>
+<LI><A HREF="#7_6">B.6 Structures</A></LI>
+<UL>
+<LI><A HREF="#7_6_1">B.6.1 Naming</A></LI>
+<LI><A HREF="#7_6_2">B.6.2 Documentation</A></LI>
+</UL>
+<LI><A HREF="#7_7">B.7 Classes</A></LI>
+<UL>
+<LI><A HREF="#7_7_1">B.7.1 Naming</A></LI>
+<LI><A HREF="#7_7_2">B.7.2 Documentation</A></LI>
+</UL>
+<LI><A HREF="#7_8">B.8 Constants</A></LI>
+<UL>
+<LI><A HREF="#7_8_1">B.8.1 Naming</A></LI>
+<LI><A HREF="#7_8_2">B.8.2 Documentation</A></LI>
+</UL>
+<LI><A HREF="#7_9">B.9 Code</A></LI>
+<UL>
+<LI><A HREF="#7_9_1">B.9.1 Documentation</A></LI>
+<LI><A HREF="#7_9_2">B.9.2 Style</A></LI>
+</UL>
+</UL>
+<B><A HREF="#8">C Software Trouble Report Form</A></B><HR>
+<H1><A NAME="1">1 Scope</A></H1>
+<H2><A NAME="1_1">1.1 Identification</A></H2>
+ This configuration management plan document provides the guidelines for
+ development and maintenance of the Common UNIX Printing System (&quot;CUPS&quot;)
+ Version 1.1 software.
+<H2><A NAME="1_2">1.2 System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+<H2><A NAME="1_3">1.3 Document Overview</A></H2>
+ This configuration management document is organized into the following
+ sections:
+<UL>
+<LI>1 - Scope</LI>
+<LI>2 - References</LI>
+<LI>3 - File Management</LI>
+<LI>4 - Trouble Report Processing</LI>
+<LI>5 - Software Releases</LI>
+<LI>A - Glossary</LI>
+<LI>B - Coding Requirements</LI>
+</UL>
+<H1><A NAME="2">2 References</A></H1>
+<H2><A NAME="2_1">2.1 CUPS Documentation</A></H2>
+<P>The following CUPS documentation is referenced by this document:</P>
+<UL>
+<LI>CUPS-CMP-1.1: CUPS Configuration Management Plan</LI>
+<LI>CUPS-IDD-1.1: CUPS System Interface Design Description</LI>
+<LI>CUPS-IPP-1.1: CUPS Implementation of IPP</LI>
+<LI>CUPS-SAM-1.1.x: CUPS Software Administrators Manual</LI>
+<LI>CUPS-SDD-1.1: CUPS Software Design Description</LI>
+<LI>CUPS-SPM-1.1.x: CUPS Software Programming Manual</LI>
+<LI>CUPS-SSR-1.1: CUPS Software Security Report</LI>
+<LI>CUPS-STP-1.1: CUPS Software Test Plan</LI>
+<LI>CUPS-SUM-1.1.x: CUPS Software Users Manual</LI>
+<LI>CUPS-SVD-1.1: CUPS Software Version Description</LI>
+</UL>
+<H2><A NAME="2_2">2.2 Other Documents</A></H2>
+<P>The following non-CUPS documents are referenced by this document:</P>
+<UL>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">
+Adobe PostScript Printer Description File Format Specification, Version
+ 4.3.</A></LI>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
+Adobe PostScript Language Reference, Third Edition.</A></LI>
+<LI>IPP: Job and Printer Set Operations</LI>
+<LI>IPP/1.1: Encoding and Transport</LI>
+<LI>IPP/1.1: Implementers Guide</LI>
+<LI>IPP/1.1: Model and Semantics</LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179, Line Printer
+ Daemon Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2567.txt">RFC 2567, Design Goals
+ for an Internet Printing Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2568.txt">RFC 2568, Rationale
+ for the Structure of the Model and Protocol for the Internet Printing
+ Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2569.txt">RFC 2569, Mapping
+ between LPD and IPP Protocols</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616, Hypertext
+ Transfer Protocol -- HTTP/1.1</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617, HTTP
+ Authentication: Basic and Digest Access</A> Authentication</LI>
+</UL>
+<H1><A NAME="3">3 File Management</A></H1>
+<H2><A NAME="3_1">3.1 Directory Structure</A></H2>
+ Each source file shall be placed a sub-directory corresponding to the
+ software sub-system it belongs to (&quot;scheduler&quot;, &quot;cups&quot;, etc.) To remain
+ compatible with older UNIX filesystems, directory names shall not
+ exceed 16 characters in length.
+<H2><A NAME="3_2">3.2 Source Files</A></H2>
+ Source files shall be documented and formatted as described in Appendix
+ B, Coding Requirements.
+<H2><A NAME="3_3">3.3 Configuration Management</A></H2>
+ Source files shall be placed under the control of the Concurrent
+ Versions System (&quot;CVS&quot;) software. Source files shall be &quot;checked in&quot;
+ with each change so that modifications can be tracked.
+<P>Documentation on the CVS software is included with the whitepaper,
+ &quot;CVS II: Parallelizing Software Development&quot;.</P>
+<H1><A NAME="4">4 Trouble Report Processing</A></H1>
+ A Software Trouble Report (&quot;STR&quot;) shall be submitted every time a user
+ or vendor experiences a problem with the CUPS software. Trouble reports
+ are maintained in a database with one of the following states:
+<OL>
+<LI>STR is closed with complete resolution</LI>
+<LI>STR is closed without resolution</LI>
+<LI>STR is active</LI>
+<LI>STR is pending (new STR or additional information available)</LI>
+</OL>
+ Trouble reports shall be processed using the following steps.
+<H2><A NAME="4_1">4.1 Classification</A></H2>
+ When a trouble report is received it must be classified at one of the
+ following levels:
+<OL>
+<LI>Request for enhancement</LI>
+<LI>Documentation error</LI>
+<LI>Unable to print a file</LI>
+<LI>Unable to print to a printer</LI>
+<LI>Unable to print at all</LI>
+</OL>
+ The scope of the problem should also be determined as:
+<OL>
+<LI>Specific to a machine</LI>
+<LI>Specific to an operating system</LI>
+<LI>Applies to all machines and operating systems</LI>
+</OL>
+<H2><A NAME="4_2">4.2 Identification</A></H2>
+ Once the level and scope of the trouble report is determined the
+ software sub-system(s) involved with the problem are determined. This
+ may involve additional communication with the user or vendor to isolate
+ the problem to a specific cause.
+<P>When the sub-system(s) involved have been identified, an engineer
+ will then determine the change(s) needed and estimate the time required
+ for the change(s).</P>
+<H2><A NAME="4_3">4.3 Correction</A></H2>
+ Corrections are scheduled based upon the severity and complexity of the
+ problem. Once all changes have been made, documented, and tested
+ successfully a new software release snapshot is generated. Additional
+ tests are added as necessary for proper testing of the changes.
+<H2><A NAME="4_4">4.4 Notification</A></H2>
+ The user or vendor is notified when the fix is available or if the
+ problem was caused by user error.
+<H1><A NAME="5">5 Software Releases</A></H1>
+<H2><A NAME="5_1">5.1 Version Numbering</A></H2>
+ CUPS uses a three-part version number separated by periods to represent
+ the major, minor, and patch release numbers:
+<UL>
+<PRE>
+major.minor.patch
+1.1.0
+</PRE>
+</UL>
+ Beta-test releases are indentified by appending the letter B followed
+ by the build number:
+<UL>
+<PRE>
+major.minor.patchbbuild
+1.1.0b1
+</PRE>
+</UL>
+ A CVS snapshot is generated for every beta and final release and uses
+ the version number preceded by the letter &quot;v&quot; and with the decimal
+ points replaced by underscores:
+<UL>
+<PRE>
+v1_0_0b1
+v1_0_0
+</PRE>
+</UL>
+ Each change that corrects a fault in a software sub-system increments
+ the patch release number. If a change affects the software design of
+ CUPS then the minor release number will be incremented and the patch
+ release number reset to 0. If CUPS is completely redesigned the major
+ release number will be incremented and the minor and patch release
+ numbers reset to 0:
+<UL>
+<PRE>
+1.1.0b1 First beta release
+1.1.0b2 Second beta release
+1.1.0 First production release
+1.1.1b1 First beta of 1.1.1
+1.1.1 Production release of 1.1.1
+1.1.1b1 First beta of 1.1.1
+1.1.1 Production release of 1.1.1
+2.0.0b1 First beta of 2.0.0
+2.0.0 Production release of 2.0.0
+</PRE>
+</UL>
+<H2><A NAME="5_2">5.2 Generation</A></H2>
+ Software releases shall be generated for each successfully completed
+ software trouble report. All object and executable files shall be
+ deleted prior to performing a full build to ensure that source files
+ are recompiled.
+<H2><A NAME="5_3">5.3 Testing</A></H2>
+ Software testing shall be conducted according to the CUPS Software Test
+ Plan, CUPS-STP-1.1. Failed tests cause STRs to be generated to correct
+ the problems found.
+<H2><A NAME="5_4">5.4 Release</A></H2>
+ When testing has been completed successfully a new distribution image
+ is created from the current CVS code &quot;snapshot&quot;. No production release
+ shall contain software that has not passed the appropriate software
+ tests.
+<H1 TYPE="A" VALUE="1"><A NAME="6">A Glossary</A></H1>
+<H2><A NAME="6_1">A.1 Terms</A></H2>
+<DL>
+<DT>C</DT>
+<DD>A computer language.</DD>
+<DT>parallel</DT>
+<DD>Sending or receiving data more than 1 bit at a time.</DD>
+<DT>pipe</DT>
+<DD>A one-way communications channel between two programs.</DD>
+<DT>serial</DT>
+<DD>Sending or receiving data 1 bit at a time.</DD>
+<DT>socket</DT>
+<DD>A two-way network communications channel.</DD>
+</DL>
+<H2><A NAME="6_2">A.2 Acronyms</A></H2>
+<DL>
+<DT>ASCII</DT>
+<DD>American Standard Code for Information Interchange</DD>
+<DT>CUPS</DT>
+<DD>Common UNIX Printing System</DD>
+<DT>ESC/P</DT>
+<DD>EPSON Standard Code for Printers</DD>
+<DT>FTP</DT>
+<DD>File Transfer Protocol</DD>
+<DT>HP-GL</DT>
+<DD>Hewlett-Packard Graphics Language</DD>
+<DT>HP-PCL</DT>
+<DD>Hewlett-Packard Page Control Language</DD>
+<DT>HP-PJL</DT>
+<DD>Hewlett-Packard Printer Job Language</DD>
+<DT>IETF</DT>
+<DD>Internet Engineering Task Force</DD>
+<DT>IPP</DT>
+<DD>Internet Printing Protocol</DD>
+<DT>ISO</DT>
+<DD>International Standards Organization</DD>
+<DT>LPD</DT>
+<DD>Line Printer Daemon</DD>
+<DT>MIME</DT>
+<DD>Multimedia Internet Mail Exchange</DD>
+<DT>PPD</DT>
+<DD>PostScript Printer Description</DD>
+<DT>SMB</DT>
+<DD>Server Message Block</DD>
+<DT>TFTP</DT>
+<DD>Trivial File Transfer Protocol</DD>
+</DL>
+<H1><A NAME="7">B Coding Requirements</A></H1>
+ These coding requirements provide detailed information on source file
+ formatting and documentation content. These guidelines shall be applied
+ to all C and C++ source files provided with CUPS.
+<H2><A NAME="7_1">B.1 Source Files</A></H2>
+<H3><A NAME="7_1_1">B.1.1 Naming</A></H3>
+ All source files names shall be 16 characters or less in length to
+ ensure compatibility with older UNIX filesystems. Source files
+ containing functions shall have an extension of &quot;.c&quot; for ANSI C and
+ &quot;.cxx&quot; for C++ source files. All other &quot;include&quot; files shall have an
+ extension of &quot;.h&quot;.
+<H3><A NAME="7_1_2">B.1.2 Documentation</A></H3>
+ The top of each source file shall contain a header giving the name of
+ the file, the purpose or nature of the source file, the copyright and
+ licensing notice, and the functions contained in the file. The file
+ name and revision information is provided by the CVS &quot;$Id$&quot; tag:
+<UL>
+<PRE>
+/*
+ * &quot;$Id$&quot;
+ *
+ * Description of file contents.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights
+ * reserved.
+ *
+ * These coded instructions, statements, and computer programs are
+ * the property of Easy Software Products and are protected by
+ * Federal copyright law. Distribution and use rights are outlined
+ * in the file &quot;LICENSE.txt&quot; which should have been included with
+ * this file. If this file is missing or damaged please contact
+ * Easy Software Products at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * function1() - Description 1.
+ * function2() - Description 2.
+ * function3() - Description 3.
+ */
+</PRE>
+</UL>
+ The bottom of each source file shall contain a trailer giving the name
+ of the file using the CVS &quot;$Id$&quot; tag. The primary purpose of this is to
+ mark the end of a source file; if the trailer is missing it is possible
+ that code has been lost near the end of the file:
+<UL>
+<PRE>
+/*
+ * End of &quot;$Id$&quot;.
+ */
+</PRE>
+</UL>
+<H2><A NAME="7_2">B.2 Functions</A></H2>
+<H3><A NAME="7_2_1">B.2.1 Naming</A></H3>
+ Functions with a global scope shall be capitalized (&quot;DoThis&quot;, &quot;DoThat&quot;,
+ &quot;DoSomethingElse&quot;, etc.) The only exception to this rule shall be the
+ CUPS interface library functions which may begin with a prefix word in
+ lowercase (&quot;cupsDoThis&quot;, &quot;cupsDoThat&quot;, etc.)
+<P>Functions with a local scope shall be declared &quot;static&quot; and be
+ lowercase with underscores between words (&quot;do_this&quot;, &quot;do_that&quot;,
+ &quot;do_something_else&quot;, etc.)</P>
+<H3><A NAME="7_2_2">B.2.2 Documentation</A></H3>
+ Each function shall begin with a comment header describing what the
+ function does, the possible input limits (if any), and the possible
+ output values (if any), and any special information needed:
+<UL>
+<PRE>
+/*
+ * 'do_this()' - Compute y = this(x).
+ *
+ * Notes: none.
+ */
+
+static float /* O - Inverse power value, 0.0 &lt;= y &lt;= 1.1 */
+do_this(float x) /* I - Power value (0.0 &lt;= x &lt;= 1.1) */
+{
+ ...
+ return (y);
+}
+</PRE>
+</UL>
+<H2><A NAME="7_3">B.3 Methods</A></H2>
+<H3><A NAME="7_3_1">B.3.1 Naming</A></H3>
+ Methods shall be in lowercase with underscores between words
+ (&quot;do_this&quot;, &quot;do_that&quot;, &quot;do_something_else&quot;, etc.)
+<H3><A NAME="7_3_2">B.3.2 Documentation</A></H3>
+ Each method shall begin with a comment header describing what the
+ method does, the possible input limits (if any), and the possible
+ output values (if any), and any special information needed:
+<UL>
+<PRE>
+/*
+ * 'class::do_this()' - Compute y = this(x).
+ *
+ * Notes: none.
+ */
+
+float /* O - Inverse power value, 0.0 &lt;= y &lt;= 1.0 */
+class::do_this(float x) /* I - Power value (0.0 &lt;= x &lt;= 1.0) */
+{
+ ...
+ return (y);
+}
+</PRE>
+</UL>
+<H2><A NAME="7_4">B.4 Variables</A></H2>
+<H3><A NAME="7_4_1">B.4.1 Naming</A></H3>
+ Variables with a global scope shall be capitalized (&quot;ThisVariable&quot;,
+ &quot;ThatVariable&quot;, &quot;ThisStateVariable&quot;, etc.) The only exception to this
+ rule shall be the CUPS interface library global variables which must
+ begin with the prefix &quot;cups&quot; (&quot;cupsThisVariable&quot;, &quot;cupsThatVariable&quot;,
+ etc.) Global variables shall be replaced by function arguments whenever
+ possible.
+<P>Variables with a local scope shall be lowercase with underscores
+ between words (&quot;this_variable&quot;, &quot;that_variable&quot;, etc.) Any local
+ variables shared by functions within a source file shall be declared
+ &quot;static&quot;.</P>
+<H3><A NAME="7_4_2">B.4.2 Documentation</A></H3>
+ Each variable shall be declared on a separate line and shall be
+ immediately followed by a comment block describing the variable:
+<UL>
+<PRE>
+int this_variable; /* The current state of this */
+int that_variable; /* The current state of that */
+</PRE>
+</UL>
+<H2><A NAME="7_5">B.5 Types</A></H2>
+<H3><A NAME="7_5_1">B.5.1 Naming</A></H3>
+ All type names shall be lowercase with underscores between words and
+ &quot;_t&quot; appended to the end of the name (&quot;this_type_t&quot;, &quot;that_type_t&quot;,
+ etc.)
+<H3><A NAME="7_5_2">B.5.2 Documentation</A></H3>
+ Each type shall have a comment block immediately before the typedef:
+<UL>
+<PRE>
+/*
+ * This type is for CUPS foobar options.
+ */
+typedef int cups_this_type_t;
+</PRE>
+</UL>
+<H2><A NAME="7_6">B.6 Structures</A></H2>
+<H3><A NAME="7_6_1">B.6.1 Naming</A></H3>
+ All structure names shall be lowercase with underscores between words
+ and &quot;_str&quot; appended to the end of the name (&quot;this_struct_str&quot;,
+ &quot;that_struct_str&quot;, etc.)
+<H3><A NAME="7_6_2">B.6.2 Documentation</A></H3>
+ Each structure shall have a comment block immediately before the struct
+ and each member shall be documented in accordance with the variable
+ naming policy above:
+<UL>
+<PRE>
+/*
+ * This structure is for CUPS foobar options.
+ */
+struct cups_this_struct_str
+{
+ int this_member; /* Current state for this */
+ int that_member; /* Current state for that */
+};
+</PRE>
+</UL>
+<H2><A NAME="7_7">B.7 Classes</A></H2>
+<H3><A NAME="7_7_1">B.7.1 Naming</A></H3>
+ All class names shall be lowercase with underscores between words
+ (&quot;this_class&quot;, &quot;that_class&quot;, etc.)
+<H3><A NAME="7_7_2">B.7.2 Documentation</A></H3>
+ Each class shall have a comment block immediately before the class and
+ each member shall be documented in accordance with the variable naming
+ policy above:
+<UL>
+<PRE>
+/*
+ * This class is for CUPS foobar options.
+ */
+class cups_this_class
+{
+ int this_member; /* Current state for this */
+ int that_member; /* Current state for that */
+};
+</PRE>
+</UL>
+<H2><A NAME="7_8">B.8 Constants</A></H2>
+<H3><A NAME="7_8_1">B.8.1 Naming</A></H3>
+ All constant names shall be uppercase with underscored between words
+ (&quot;THIS_CONSTANT&quot;, &quot;THAT_CONSTANT&quot;, etc.) Constants defined for the CUPS
+ interface library must begin with an uppercase prefix
+ (&quot;CUPS_THIS_CONSTANT&quot;, &quot;CUPS_THAT_CONSTANT&quot;, etc.)
+<P>Typed enumerations shall be used whenever possible to allow for type
+ checking by the compiler.</P>
+<H3><A NAME="7_8_2">B.8.2 Documentation</A></H3>
+ Comment blocks shall immediately follow each constant:
+<UL>
+<PRE>
+enum
+{
+ CUPS_THIS_TRAY, /* This tray */
+ CUPS_THAT_TRAY /* That tray */
+};
+</PRE>
+</UL>
+<H2><A NAME="7_9">B.9 Code</A></H2>
+<H3><A NAME="7_9_1">B.9.1 Documentation</A></H3>
+ All source code shall utilize block comments within functions to
+ describe the operations being performed by a group of statements:
+<UL>
+<PRE>
+/*
+ * Clear the state array before we begin...
+ */
+
+for (i = 0; i &lt; (sizeof(array) / sizeof(sizeof(array[0])); i ++)
+ array[i] = STATE_IDLE;
+
+/*
+ * Wait for state changes...
+ */
+
+do
+{
+ for (i = 0; i &lt; (sizeof(array) / sizeof(sizeof(array[0])); i ++)
+ if (array[i] != STATE_IDLE)
+ break;
+
+ if (i == (sizeof(array) / sizeof(array[0])))
+ sleep(1);
+} while (i == (sizeof(array) / sizeof(array[0])));
+</PRE>
+</UL>
+<H3><A NAME="7_9_2">B.9.2 Style</A></H3>
+<H4 TYPE="a">B.9.2.a Indentation</H4>
+ All code blocks enclosed by brackets shall begin with the opening brace
+ on a new line. The code then follows starting on a new line after the
+ brace and is indented 2 spaces. The closing brace is then placed on a
+ new line following the code at the original indentation:
+<UL>
+<PRE>
+{
+ int i; /* Looping var */
+
+ /*
+ * Process foobar values from 0 to 999...
+ */
+
+ for (i = 0; i &lt; 1000; i ++)
+ {
+ do_this(i);
+ do_that(i);
+ }
+}
+</PRE>
+</UL>
+ Single-line statements following &quot;do&quot;, &quot;else&quot;, &quot;for&quot;, &quot;if&quot;, and &quot;while&quot;
+ shall be indented 2 spaces as well. Blocks of code in a &quot;switch&quot; block
+ shall be indented 4 spaces after each &quot;case&quot; and &quot;default&quot; case:
+<UL>
+<PRE>
+switch (array[i])
+{
+ case STATE_IDLE :
+ do_this(i);
+ do_that(i);
+ break;
+ default :
+ do_nothing(i);
+ break;
+}
+</PRE>
+</UL>
+<H4>B.9.2.b Spacing</H4>
+ A space shall follow each reserved word (&quot;if&quot;, &quot;while&quot;, etc.) Spaces
+ shall not be inserted between a function name and the arguments in
+ parenthesis.
+<H4>B.9.2.c Return Values</H4>
+ Parenthesis shall surround values returned from a function using
+ &quot;return&quot;:
+<UL>
+<PRE>
+return (STATE_IDLE);
+</PRE>
+</UL>
+<H4>B.9.2.d Loops</H4>
+ Whenever convenient loops should count downward to zero to improve
+ program performance:
+<UL>
+<PRE>
+for (i = sizeof(array) / sizeof(array[0]) - 1; i &gt;= 0; i --)
+ array[i] = STATE_IDLE;
+</PRE>
+</UL>
+<H1 ALIGN="RIGHT"><A NAME="8">C Software Trouble Report Form</A></H1>
+<CENTER>
+<TABLE WIDTH="80%">
+<TR><TH ALIGN="RIGHT">Summary of Problem:</TH><TD ALIGN="LEFT">
+________________________________________</TD></TR>
+<TR><TH ALIGN="RIGHT">Problem Severity:</TH><TD ALIGN="LEFT">__1=RFE
+<BR> __2=Documentation-Error
+<BR> __3=Unable-to-Print-a-File
+<BR> __4=Unable-to-Print-to-a-Printer
+<BR> __5=Unable-to-Print-at-All</TD></TR>
+<TR><TH ALIGN="RIGHT">Problem Scope:</TH><TD ALIGN="LEFT">__1=Machine
+ __2=Operating-System __3=All</TD></TR>
+<TR><TH ALIGN="RIGHT" VALIGN="TOP">Detailed Description of Problem:</TH><TD
+ALIGN="LEFT">________________________________________
+<BR> ________________________________________
+<BR> ________________________________________
+<BR> ________________________________________
+<BR> ________________________________________
+<BR> ________________________________________</TD></TR>
+</TABLE>
+</CENTER>
+</BODY>
+</HTML>
diff --git a/doc/cmp.pdf b/doc/cmp.pdf
new file mode 100644
index 000000000..e71051fcd
--- /dev/null
+++ b/doc/cmp.pdf
Binary files differ
diff --git a/doc/cmp.shtml b/doc/cmp.shtml
new file mode 100644
index 000000000..1e7d42cff
--- /dev/null
+++ b/doc/cmp.shtml
@@ -0,0 +1,595 @@
+<HTML>
+<HEAD>
+ <META NAME="DOCNUMBER" CONTENT="CUPS-CMP-1.1">
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Configuration Management Plan</TITLE>
+</HEAD>
+<BODY>
+
+<H1>Scope</H1>
+
+<H2>Identification</H2>
+
+This configuration management plan document provides the guidelines for
+development and maintenance of the Common UNIX Printing System ("CUPS")
+Version 1.1 software.
+
+<EMBED SRC="system-overview.shtml">
+
+<H2>Document Overview</H2>
+
+This configuration management document is organized into the following
+sections:
+
+<UL>
+ <LI>1 - Scope</LI>
+ <LI>2 - References</LI>
+ <LI>3 - File Management</LI>
+ <LI>4 - Trouble Report Processing</LI>
+ <LI>5 - Software Releases</LI>
+ <LI>A - Glossary</LI>
+ <LI>B - Coding Requirements</LI>
+</UL>
+
+<EMBED SRC="references.shtml">
+
+<H1>File Management</H1>
+
+<H2>Directory Structure</H2>
+
+Each source file shall be placed a sub-directory corresponding to the software
+sub-system it belongs to ("scheduler", "cups", etc.) To remain compatible
+with older UNIX filesystems, directory names shall not exceed 16 characters
+in length.
+
+<H2>Source Files</H2>
+
+Source files shall be documented and formatted as described in Appendix
+B, Coding Requirements.
+
+<H2>Configuration Management</H2>
+
+Source files shall be placed under the control of the Concurrent Versions
+System ("CVS") software. Source files shall be "checked in" with each change
+so that modifications can be tracked.
+
+<P>Documentation on the CVS software is included with the whitepaper, "CVS
+II: Parallelizing Software Development".
+
+<H1>Trouble Report Processing</H1>
+
+A Software Trouble Report ("STR") shall be submitted every time a user
+or vendor experiences a problem with the CUPS software. Trouble reports
+are maintained in a database with one of the following states:
+
+<OL>
+ <LI>STR is closed with complete resolution</LI>
+ <LI>STR is closed without resolution</LI>
+ <LI>STR is active</LI>
+ <LI>STR is pending (new STR or additional information available)</LI>
+</OL>
+
+Trouble reports shall be processed using the following steps.
+
+<H2>Classification</H2>
+
+When a trouble report is received it must be classified at one of the following
+levels:
+
+<OL>
+ <LI>Request for enhancement</LI>
+ <LI>Documentation error</LI>
+ <LI>Unable to print a file</LI>
+ <LI>Unable to print to a printer</LI>
+ <LI>Unable to print at all</LI>
+</OL>
+
+The scope of the problem should also be determined as:
+
+<OL>
+ <LI>Specific to a machine</LI>
+ <LI>Specific to an operating system</LI>
+ <LI>Applies to all machines and operating systems</LI>
+</OL>
+
+<H2>Identification</H2>
+
+Once the level and scope of the trouble report is determined the software
+sub-system(s) involved with the problem are determined. This may involve
+additional communication with the user or vendor to isolate the problem
+to a specific cause.
+
+<P>When the sub-system(s) involved have been identified, an engineer will
+then determine the change(s) needed and estimate the time required for
+the change(s).
+
+<H2>Correction</H2>
+
+Corrections are scheduled based upon the severity and complexity of the
+problem. Once all changes have been made, documented, and tested successfully
+a new software release snapshot is generated. Additional tests are added
+as necessary for proper testing of the changes.
+
+<H2>Notification</H2>
+
+The user or vendor is notified when the fix is available or if the problem
+was caused by user error.
+
+<H1>Software Releases</H1>
+
+<H2>Version Numbering</H2>
+
+CUPS uses a three-part version number separated by periods to represent
+the major, minor, and patch release numbers:
+
+<UL>
+<PRE>
+major.minor.patch
+1.1.0
+</PRE>
+</UL>
+
+Beta-test releases are indentified by appending the letter B followed by
+the build number:
+
+<UL>
+<PRE>
+major.minor.patchbbuild
+1.1.0b1
+</PRE>
+</UL>
+
+A CVS snapshot is generated for every beta and final release and uses
+the version number preceded by the letter "v" and with the decimal
+points replaced by underscores:
+
+<UL>
+<PRE>
+v1_0_0b1
+v1_0_0
+</PRE>
+</UL>
+
+Each change that corrects a fault in a software sub-system increments the
+patch release number. If a change affects the software design of CUPS then
+the minor release number will be incremented and the patch release number
+reset to 0. If CUPS is completely redesigned the major release number will
+be incremented and the minor and patch release numbers reset to 0:
+
+<UL>
+<PRE>
+1.1.0b1 First beta release
+1.1.0b2 Second beta release
+1.1.0 First production release
+1.1.1b1 First beta of 1.1.1
+1.1.1 Production release of 1.1.1
+1.1.1b1 First beta of 1.1.1
+1.1.1 Production release of 1.1.1
+2.0.0b1 First beta of 2.0.0
+2.0.0 Production release of 2.0.0
+</PRE>
+</UL>
+
+<H2>Generation</H2>
+
+Software releases shall be generated for each successfully completed software
+trouble report. All object and executable files shall be deleted prior
+to performing a full build to ensure that source files are recompiled.
+
+<H2>Testing</H2>
+
+Software testing shall be conducted according to the CUPS Software Test
+Plan, CUPS-STP-1.1. Failed tests cause STRs to be generated to correct
+the problems found.
+
+<H2>Release</H2>
+
+When testing has been completed successfully a new distribution image is
+created from the current CVS code "snapshot". No production release shall
+contain software that has not passed the appropriate software tests.
+
+<EMBED SRC="glossary.shtml">
+
+<H1>Coding Requirements</H1>
+
+These coding requirements provide detailed information on source file
+formatting and documentation content. These guidelines shall be applied
+to all C and C++ source files provided with CUPS.
+
+<H2>Source Files</H2>
+
+<H3>Naming</H3>
+
+All source files names shall be 16 characters or less in length to
+ensure compatibility with older UNIX filesystems. Source files
+containing functions shall have an extension of ".c" for ANSI C and
+".cxx" for C++ source files. All other "include" files shall have an
+extension of ".h".
+
+<H3>Documentation</H3>
+
+The top of each source file shall contain a header giving the name of the
+file, the purpose or nature of the source file, the copyright and licensing
+notice, and the functions contained in the file. The file name and revision
+information is provided by the CVS "&#36;Id$" tag:
+
+<UL>
+<PRE>
+/*
+ * "&#36;Id$"
+ *
+ * Description of file contents.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights
+ * reserved.
+ *
+ * These coded instructions, statements, and computer programs are
+ * the property of Easy Software Products and are protected by
+ * Federal copyright law. Distribution and use rights are outlined
+ * in the file "LICENSE.txt" which should have been included with
+ * this file. If this file is missing or damaged please contact
+ * Easy Software Products at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * function1() - Description 1.
+ * function2() - Description 2.
+ * function3() - Description 3.
+ */
+</PRE>
+</UL>
+
+The bottom of each source file shall contain a trailer giving the name
+of the file using the CVS "&#36;Id$" tag. The primary purpose of this is to
+mark the end of a source file; if the trailer is missing it is possible
+that code has been lost near the end of the file:
+
+<UL>
+<PRE>
+/*
+ * End of "&#36;Id$".
+ */
+</PRE>
+</UL>
+
+<H2>Functions</H2>
+
+<H3>Naming</H3>
+
+Functions with a global scope shall be capitalized ("DoThis", "DoThat",
+"DoSomethingElse", etc.) The only exception to this rule shall be the
+CUPS interface library functions which may begin with a prefix word in
+lowercase ("cupsDoThis", "cupsDoThat", etc.)
+
+<P>Functions with a local scope shall be declared "static" and be lowercase
+with underscores between words ("do_this", "do_that", "do_something_else",
+etc.)
+
+<H3>Documentation</H3>
+
+Each function shall begin with a comment header describing what the function
+does, the possible input limits (if any), and the possible output values
+(if any), and any special information needed:
+
+<UL>
+<PRE>
+/*
+ * 'do_this()' - Compute y = this(x).
+ *
+ * Notes: none.
+ */
+
+static float /* O - Inverse power value, 0.0 &lt;= y &lt;= 1.1 */
+do_this(float x) /* I - Power value (0.0 &lt;= x &lt;= 1.1) */
+{
+ ...
+ return (y);
+}
+</PRE>
+</UL>
+
+<H2>Methods</H2>
+
+<H3>Naming</H3>
+
+Methods shall be in lowercase with underscores between words ("do_this",
+"do_that", "do_something_else", etc.)
+
+<H3>Documentation</H3>
+
+Each method shall begin with a comment header describing what the method
+does, the possible input limits (if any), and the possible output values
+(if any), and any special information needed:
+
+<UL>
+<PRE>
+/*
+ * 'class::do_this()' - Compute y = this(x).
+ *
+ * Notes: none.
+ */
+
+float /* O - Inverse power value, 0.0 &lt;= y &lt;= 1.0 */
+class::do_this(float x) /* I - Power value (0.0 &lt;= x &lt;= 1.0) */
+{
+ ...
+ return (y);
+}
+</PRE>
+</UL>
+
+<H2>Variables</H2>
+
+<H3>Naming</H3>
+
+Variables with a global scope shall be capitalized ("ThisVariable",
+"ThatVariable", "ThisStateVariable", etc.) The only exception to this
+rule shall be the CUPS interface library global variables which must
+begin with the prefix "cups" ("cupsThisVariable", "cupsThatVariable",
+etc.) Global variables shall be replaced by function arguments whenever
+possible.
+
+<P>Variables with a local scope shall be lowercase with underscores between
+words ("this_variable", "that_variable", etc.) Any local variables shared
+by functions within a source file shall be declared "static".
+
+<H3>Documentation</H3>
+
+Each variable shall be declared on a separate line and shall be immediately
+followed by a comment block describing the variable:
+
+<UL><PRE>
+int this_variable; /* The current state of this */
+int that_variable; /* The current state of that */
+</PRE></UL>
+
+<H2>Types</H2>
+
+<H3>Naming</H3>
+
+All type names shall be lowercase with underscores between words and
+"_t" appended to the end of the name ("this_type_t", "that_type_t",
+etc.)
+
+<H3>Documentation</H3>
+
+Each type shall have a comment block immediately before the typedef:
+
+<UL>
+<PRE>
+/*
+ * This type is for CUPS foobar options.
+ */
+typedef int cups_this_type_t;
+</PRE>
+</UL>
+
+<H2>Structures</H2>
+
+<H3>Naming</H3>
+
+All structure names shall be lowercase with underscores between words and
+"_str" appended to the end of the name ("this_struct_str", "that_struct_str",
+etc.)
+
+<H3>Documentation</H3>
+
+Each structure shall have a comment block immediately before the struct
+and each member shall be documented in accordance with the variable naming
+policy above:
+
+<UL>
+<PRE>
+/*
+ * This structure is for CUPS foobar options.
+ */
+struct cups_this_struct_str
+{
+ int this_member; /* Current state for this */
+ int that_member; /* Current state for that */
+};
+</PRE>
+</UL>
+
+<H2>Classes</H2>
+
+<H3>Naming</H3>
+
+All class names shall be lowercase with underscores between words
+("this_class", "that_class", etc.)
+
+<H3>Documentation</H3>
+
+Each class shall have a comment block immediately before the class
+and each member shall be documented in accordance with the variable naming
+policy above:
+
+<UL>
+<PRE>
+/*
+ * This class is for CUPS foobar options.
+ */
+class cups_this_class
+{
+ int this_member; /* Current state for this */
+ int that_member; /* Current state for that */
+};
+</PRE>
+</UL>
+
+<H2>Constants</H2>
+
+<H3>Naming</H3>
+
+All constant names shall be uppercase with underscored between words
+("THIS_CONSTANT", "THAT_CONSTANT", etc.) Constants defined for the CUPS
+interface library must begin with an uppercase prefix
+("CUPS_THIS_CONSTANT", "CUPS_THAT_CONSTANT", etc.)
+
+<P>Typed enumerations shall be used whenever possible to allow for type
+checking by the compiler.
+
+<H3>Documentation</H3>
+
+Comment blocks shall immediately follow each constant:
+
+<UL>
+<PRE>
+enum
+{
+ CUPS_THIS_TRAY, /* This tray */
+ CUPS_THAT_TRAY /* That tray */
+};
+</PRE>
+</UL>
+
+<H2>Code</H2>
+
+<H3>Documentation</H3>
+
+All source code shall utilize block comments within functions to describe
+the operations being performed by a group of statements:
+
+<UL>
+<PRE>
+/*
+ * Clear the state array before we begin...
+ */
+
+for (i = 0; i &lt; (sizeof(array) / sizeof(sizeof(array[0])); i ++)
+ array[i] = STATE_IDLE;
+
+/*
+ * Wait for state changes...
+ */
+
+do
+{
+ for (i = 0; i &lt; (sizeof(array) / sizeof(sizeof(array[0])); i ++)
+ if (array[i] != STATE_IDLE)
+ break;
+
+ if (i == (sizeof(array) / sizeof(array[0])))
+ sleep(1);
+} while (i == (sizeof(array) / sizeof(array[0])));
+</PRE>
+</UL>
+
+<H3>Style</H3>
+
+<H4 TYPE="a">Indentation</H4>
+
+All code blocks enclosed by brackets shall begin with the opening brace
+on a new line. The code then follows starting on a new line after the brace
+and is indented 2 spaces. The closing brace is then placed on a new line
+following the code at the original indentation:
+
+<UL>
+<PRE>
+{
+ int i; /* Looping var */
+
+ /*
+ * Process foobar values from 0 to 999...
+ */
+
+ for (i = 0; i &lt; 1000; i ++)
+ {
+ do_this(i);
+ do_that(i);
+ }
+}
+</PRE>
+</UL>
+
+Single-line statements following "do", "else", "for", "if", and "while"
+shall be indented 2 spaces as well. Blocks of code in a "switch" block
+shall be indented 4 spaces after each "case" and "default" case:
+
+<UL>
+<PRE>
+switch (array[i])
+{
+ case STATE_IDLE :
+ do_this(i);
+ do_that(i);
+ break;
+ default :
+ do_nothing(i);
+ break;
+}
+</PRE>
+</UL>
+
+<H4>Spacing</H4>
+
+A space shall follow each reserved word ("if", "while", etc.) Spaces shall
+not be inserted between a function name and the arguments in parenthesis.
+
+<H4>Return Values</H4>
+
+Parenthesis shall surround values returned from a function using "return":
+
+<UL>
+<PRE>
+return (STATE_IDLE);
+</PRE>
+</UL>
+
+<H4>Loops</H4>
+
+Whenever convenient loops should count downward to zero to improve program
+performance:
+
+<UL>
+<PRE>
+for (i = sizeof(array) / sizeof(array[0]) - 1; i >= 0; i --)
+ array[i] = STATE_IDLE;
+</PRE>
+</UL>
+
+<H1 ALIGN=RIGHT>Software Trouble Report Form</H1>
+
+<CENTER><TABLE WIDTH="80%">
+<TR>
+ <TH ALIGN=RIGHT>Summary of Problem:</TH>
+ <TD ALIGN=LEFT>________________________________________</TD>
+</TR>
+
+<TR>
+ <TH ALIGN=RIGHT>Problem Severity:</TH>
+ <TD ALIGN=LEFT>__1=RFE
+ <BR>__2=Documentation-Error
+ <BR>__3=Unable-to-Print-a-File
+ <BR>__4=Unable-to-Print-to-a-Printer
+ <BR>__5=Unable-to-Print-at-All</TD>
+</TR>
+
+<TR>
+ <TH ALIGN=RIGHT>Problem Scope:</TH>
+ <TD ALIGN=LEFT>__1=Machine __2=Operating-System __3=All</TD>
+</TR>
+
+<TR>
+ <TH ALIGN=RIGHT VALIGN=TOP>Detailed Description of Problem:</TH>
+ <TD ALIGN=LEFT>________________________________________
+ <BR>________________________________________
+ <BR>________________________________________
+ <BR>________________________________________
+ <BR>________________________________________
+ <BR>________________________________________</TD>
+</TR>
+</TABLE></CENTER>
+
+</BODY>
+</HTML>
diff --git a/doc/cups.css b/doc/cups.css
new file mode 100644
index 000000000..9285a5b5e
--- /dev/null
+++ b/doc/cups.css
@@ -0,0 +1,4 @@
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+TH { text-align: left }
+
diff --git a/doc/cupsdoc.css b/doc/cupsdoc.css
new file mode 100644
index 000000000..333f20144
--- /dev/null
+++ b/doc/cupsdoc.css
@@ -0,0 +1,9 @@
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUP { font-family: sans-serif; font-size: 6pt }
+PRE { margin-left: 2em }
+CODE { font-weight: bold }
diff --git a/doc/documentation.html b/doc/documentation.html
new file mode 100644
index 000000000..bace11440
--- /dev/null
+++ b/doc/documentation.html
@@ -0,0 +1,85 @@
+<HTML>
+<HEAD>
+ <TITLE>Documentation - Common UNIX Printing System</TITLE>
+ <LINK REL=STYLESHEET TYPE="text/css" HREF="cups.css">
+ <MAP NAME="navbar">
+ <AREA SHAPE="RECT" COORDS="12,10,50,20" HREF="http://www.easysw.com" ALT="Easy Software Products Home Page">
+ <AREA SHAPE="RECT" COORDS="82,10,196,20" HREF="/admin" ALT="Do Administration Tasks">
+ <AREA SHAPE="RECT" COORDS="216,10,280,20" HREF="/classes" ALT="Manage Printer Classes Status">
+ <AREA SHAPE="RECT" COORDS="300,10,336,20" HREF="/documentation.html" ALT="On-Line Help">
+ <AREA SHAPE="RECT" COORDS="356,10,394,20" HREF="/jobs" ALT="Manage Jobs">
+ <AREA SHAPE="RECT" COORDS="414,10,476,20" HREF="/printers" ALT="Manage Printers">
+ <AREA SHAPE="RECT" COORDS="496,10,568,20" HREF="http://www.cups.org" ALT="Download the Current CUPS Software">
+ </MAP>
+</HEAD>
+
+<BODY BGCOLOR="#cccc99" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF">
+<CENTER>
+<IMG SRC="/images/navbar.gif" WIDTH="583" HEIGHT="30" USEMAP="#navbar" BORDER="0" ALT="Common UNIX Printing System">
+</CENTER>
+
+<H1>Documentation</H1>
+
+The following documentation for CUPS is available on this server:
+
+<UL>
+
+ <LI>Whitepaper - An Overview of the Common UNIX Printing System (
+ <A HREF="overview.html">HTML</A> |
+ <A HREF="overview.pdf">PDF</A> )
+
+ <LI>Software Users Manual (
+ <A HREF="sum.html">HTML</A> |
+ <A HREF="sum.pdf">PDF</A> )
+
+ <LI>Software Administrators Manual (
+ <A HREF="sam.html">HTML</A> |
+ <A HREF="sam.pdf">PDF</A> )
+
+ <LI>Software Programmers Manual (
+ <A HREF="spm.html">HTML</A> |
+ <A HREF="spm.pdf">PDF</A> )
+
+ <LI>Configuration Management Plan (
+ <A HREF="cmp.html">HTML</A> |
+ <A HREF="cmp.pdf">PDF</A> )
+
+ <LI>CUPS Implementation of IPP (
+ <A HREF="ipp.html">HTML</A> |
+ <A HREF="ipp.pdf">PDF</A> )
+
+ <LI>Interface Design Description (
+ <A HREF="idd.html">HTML</A> |
+ <A HREF="idd.pdf">PDF</A> )
+
+ <LI>Software Design Description (
+ <A HREF="sdd.html">HTML</A> |
+ <A HREF="sdd.pdf">PDF</A> )
+
+ <LI>Software Performance Specification (
+ <A HREF="sps.html">HTML</A> |
+ <A HREF="sps.pdf">PDF</A> )
+
+ <LI>Software Version Description (
+ <A HREF="svd.html">HTML</A> |
+ <A HREF="svd.pdf">PDF</A> )
+
+ <LI>Software Security Report (
+ <A HREF="ssr.html">HTML</A> |
+ <A HREF="ssr.pdf">PDF</A> )
+
+ <LI>Software Translation Guide (
+ <A HREF="translation.html">HTML</A> |
+ <A HREF="translation.pdf">PDF</A> )
+
+</UL>
+
+<HR>
+
+<P>The Common UNIX Printing System, CUPS, and the CUPS logo are the
+trademark property of <A HREF="http://www.easysw.com">Easy Software
+Products</A>. CUPS is copyright 1997-2002 by Easy Software Products,
+All Rights Reserved.
+
+</BODY>
+</HTML>
diff --git a/doc/figures.sc b/doc/figures.sc
new file mode 100644
index 000000000..f51e814a6
--- /dev/null
+++ b/doc/figures.sc
Binary files differ
diff --git a/doc/fr/Makefile b/doc/fr/Makefile
new file mode 100644
index 000000000..54f7d9f39
--- /dev/null
+++ b/doc/fr/Makefile
@@ -0,0 +1,190 @@
+#
+# "$Id$"
+#
+# Documentation makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9600
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../../Makedefs
+
+#
+# HTMLDOC generation rules...
+#
+
+.SUFFIXES: .html .pdf .ps .shtml
+.shtml.html:
+ echo Formatting $@...
+ htmldoc --titleimage images/cups-large.gif --numbered -f $@ $<
+.shtml.pdf:
+ echo Formatting $@...
+ htmldoc --titleimage images/cups-large.gif --duplex --compression=9 \
+ --numbered --jpeg -f $@ $<
+.shtml.ps:
+ echo Formatting $@...
+ htmldoc --titleimage images/cups-large.gif --duplex --numbered \
+ --jpeg -f $@ $<
+
+
+#
+# Document files...
+#
+
+DOCUMENTS = sam.shtml sum.shtml
+WEBPAGES = cups.css cupsdoc.css index.html documentation.html
+WEBIMAGES = images/accept-jobs.gif \
+ images/add-class.gif \
+ images/add-printer.gif \
+ images/cancel.gif \
+ images/cancel-job.gif \
+ images/cancel-jobs.gif \
+ images/config-printer.gif \
+ images/continue.gif \
+ images/delete-class.gif \
+ images/delete-printer.gif \
+ images/hold-job.gif \
+ images/manage-classes.gif \
+ images/manage-jobs.gif \
+ images/manage-printers.gif \
+ images/modify-class.gif \
+ images/modify-printer.gif \
+ images/navbar.gif \
+ images/print-test-page.gif \
+ images/reject-jobs.gif \
+ images/release-job.gif \
+ images/restart-job.gif \
+ images/show-active.gif \
+ images/show-completed.gif \
+ images/start-class.gif \
+ images/start-printer.gif \
+ images/stop-class.gif \
+ images/stop-printer.gif
+
+
+#
+# Make all documents...
+#
+
+all: $(DOCUMENTS:.shtml=.pdf) $(DOCUMENTS:.shtml=.html) overview.pdf
+
+
+#
+# Make PS files...
+#
+
+ps: $(DOCUMENTS:.shtml=.ps) overview.ps
+
+
+#
+# Remove all generated files...
+#
+
+clean:
+ $(RM) $(DOCUMENTS:.shtml=.pdf)
+ $(RM) $(DOCUMENTS:.shtml=.html)
+ $(RM) overview.pdf
+
+
+#
+# Install all documentation files...
+#
+
+install:
+ $(INSTALL_DIR) $(DOCDIR)/fr
+ for file in $(WEBPAGES); do \
+ $(INSTALL_MAN) $$file $(DOCDIR)/fr; \
+ done
+ $(INSTALL_MAN) overview.html $(DOCDIR)/fr
+ $(INSTALL_MAN) overview.pdf $(DOCDIR)/fr
+ for file in $(DOCUMENTS:.shtml=.html); do \
+ $(INSTALL_MAN) $$file $(DOCDIR)/fr; \
+ done
+ for file in $(DOCUMENTS:.shtml=.pdf); do \
+ $(INSTALL_MAN) $$file $(DOCDIR)/fr; \
+ done
+ $(INSTALL_DIR) $(DOCDIR)/fr/images
+ for file in $(WEBIMAGES); do \
+ $(INSTALL_MAN) $$file $(DOCDIR)/fr/images; \
+ done
+
+
+#
+# The overview, admin manual, programmers manual, and users manual get
+# special attention...
+#
+
+overview.pdf: overview.html
+ echo Formatting $@...
+ htmldoc --path ".;.." --duplex --compression=9 --jpeg --webpage -f overview.pdf overview.html
+overview.ps: overview.html
+ echo Formatting $@...
+ htmldoc --path ".;.." --duplex --jpeg --webpage -f overview.ps overview.html
+
+sam.html: sam.shtml
+ echo Formatting $@...
+ htmldoc --path ".;.." --titleimage images/cups-large.gif -f $@ $<
+sam.pdf: sam.shtml
+ echo Formatting $@...
+ htmldoc --path ".;.." --titleimage images/cups-large.gif --duplex --compression=9 \
+ --jpeg -f $@ $<
+sam.ps: sam.shtml
+ echo Formatting $@...
+ htmldoc --path ".;.." --titleimage images/cups-large.gif --duplex --jpeg -f $@ $<
+
+spm.html: spm.shtml
+ echo Formatting $@...
+ htmldoc --path ".;.." --titleimage images/cups-large.gif -f $@ $<
+spm.pdf: spm.shtml
+ echo Formatting $@...
+ htmldoc --path ".;.." --titleimage images/cups-large.gif --duplex --compression=9 \
+ --jpeg -f $@ $<
+spm.ps: spm.shtml
+ echo Formatting $@...
+ htmldoc --path ".;.." --titleimage images/cups-large.gif --duplex --jpeg -f $@ $<
+
+sum.html: sum.shtml
+ echo Formatting $@...
+ htmldoc --path ".;.." --titleimage images/cups-large.gif -f $@ $<
+sum.pdf: sum.shtml
+ echo Formatting $@...
+ htmldoc --path ".;.." --titleimage images/cups-large.gif --duplex --compression=9 \
+ --jpeg -f $@ $<
+sum.ps: sum.shtml
+ echo Formatting $@...
+ htmldoc --path ".;.." --titleimage images/cups-large.gif --duplex --jpeg -f $@ $<
+
+$(DOCUMENTS:.shtml=.html): \
+ glossary.shtml printing-overview.shtml \
+ references.shtml system-overview.shtml \
+ ../../LICENSE.html
+
+$(DOCUMENTS:.shtml=.pdf): \
+ glossary.shtml printing-overview.shtml \
+ references.shtml system-overview.shtml \
+ ../../LICENSE.html
+
+$(DOCUMENTS:.shtml=.ps): \
+ glossary.shtml printing-overview.shtml \
+ references.shtml system-overview.shtml \
+ ../../LICENSE.html
+
+
+#
+# End of Makefile.
+#
diff --git a/doc/fr/cups.css b/doc/fr/cups.css
new file mode 100644
index 000000000..9285a5b5e
--- /dev/null
+++ b/doc/fr/cups.css
@@ -0,0 +1,4 @@
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+TH { text-align: left }
+
diff --git a/doc/fr/cupsdoc.css b/doc/fr/cupsdoc.css
new file mode 100644
index 000000000..333f20144
--- /dev/null
+++ b/doc/fr/cupsdoc.css
@@ -0,0 +1,9 @@
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUP { font-family: sans-serif; font-size: 6pt }
+PRE { margin-left: 2em }
+CODE { font-weight: bold }
diff --git a/doc/fr/documentation.html b/doc/fr/documentation.html
new file mode 100644
index 000000000..2eece414f
--- /dev/null
+++ b/doc/fr/documentation.html
@@ -0,0 +1,81 @@
+<HTML>
+<HEAD>
+ <TITLE>Documentation CUPS (Common UNIX Printing System)</TITLE>
+ <LINK REL=STYLESHEET TYPE="text/css" HREF="cups.css">
+ <MAP NAME="navbar">
+ <AREA SHAPE="RECT" COORDS="14,8,50,22" HREF="http://www.easysw.com" ALT="Page d'accueil Easy Software Products">
+ <AREA SHAPE="RECT" COORDS="76,8,182,22" HREF="admin" ALT="Accès aux tâches d'administration">
+ <AREA SHAPE="RECT" COORDS="202,8,260,22" HREF="classes" ALT="Administrer l'état des classes d'imprimantes">
+ <AREA SHAPE="RECT" COORDS="280,8,316,22" HREF="documentation.html" ALT="Aide électronique en ligne">
+ <AREA SHAPE="RECT" COORDS="334,8,394,22" HREF="jobs" ALT="Administrer les travaux d'impression">
+ <AREA SHAPE="RECT" COORDS="416,8,506,22" HREF="printers" ALT="Administrer les imprimantes">
+ <AREA SHAPE="RECT" COORDS="526,8,582,22" HREF="http://www.cups.org" ALT="Télécharger la dernière version du logiciel CUPS">
+ </MAP>
+</HEAD>
+
+<BODY BGCOLOR="#cccc99" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF">
+<CENTER>
+<IMG SRC="/images/navbar.gif" WIDTH="596" HEIGHT="28" USEMAP="#navbar" BORDER="0" ALT="CUPS (Common UNIX Printing System)">
+</CENTER>
+
+<H1>Documentation</H1>
+
+La documentation CUPS suivante est disponible sur ce serveur:
+
+<UL>
+
+ <LI>Aperçu du logiciel CUPS - Common UNIX Printing System (français) (
+ <A HREF="overview.html">HTML</A> |
+ <A HREF="overview.pdf">PDF</A> )
+
+ <LI>Manuel de l'utilisateur (français) (
+ <A HREF="sum.html">HTML</A> |
+ <A HREF="sum.pdf">PDF</A> )
+
+ <LI>Manuel de l'administrateur (français) (
+ <A HREF="sam.html">HTML</A> |
+ <A HREF="sam.pdf">PDF</A> )
+
+ <LI>Manuel du programmeur (anglais) (
+ <A HREF="spm.html">HTML</A> |
+ <A HREF="spm.pdf">PDF</A> )
+
+ <LI>Plan d'organisation de la configuration (anglais) (
+ <A HREF="cmp.html">HTML</A> |
+ <A HREF="cmp.pdf">PDF</A> )
+
+ <LI>Implémentation du protocole IPP (Internet Printing Protocol) dans CUPS (anglais) (
+ <A HREF="ipp.html">HTML</A> |
+ <A HREF="ipp.pdf">PDF</A> )
+
+ <LI>Description de conception de l'interface (anglais) (
+ <A HREF="idd.html">HTML</A> |
+ <A HREF="idd.pdf">PDF</A> )
+
+ <LI>Description de conception logicielle (anglais) (
+ <A HREF="sdd.html">HTML</A> |
+ <A HREF="sdd.pdf">PDF</A> )
+
+ <LI>Spécification des capacités du logiciel (anglais) (
+ <A HREF="sps.html">HTML</A> |
+ <A HREF="sps.pdf">PDF</A> )
+
+ <LI>Description de la version du logiciel (anglais) (
+ <A HREF="svd.html">HTML</A> |
+ <A HREF="svd.pdf">PDF</A> )
+
+ <LI>Rapport de sécurité du logiciel (anglais) (
+ <A HREF="ssr.html">HTML</A> |
+ <A HREF="ssr.pdf">PDF</A> )
+
+</UL>
+
+<HR>
+
+<P>Common UNIX Printing System, CUPS, et le logo CUPS sont des marques déposées
+appartenant à <A HREF="http://www.easysw.com">Easy Software
+Products</A>. CUPS copyright 1997-2002 Easy Software Products,
+Tous droits réservés.
+
+</BODY>
+</HTML>
diff --git a/doc/fr/glossary.shtml b/doc/fr/glossary.shtml
new file mode 100644
index 000000000..2cc0c1c89
--- /dev/null
+++ b/doc/fr/glossary.shtml
@@ -0,0 +1,73 @@
+<H1 TYPE="A" VALUE="1">Glossary</H1>
+
+<H2>Terms</H2>
+
+<DL>
+
+ <DT>C
+ <DD>A computer language.
+
+ <DT>parallel
+ <DD>Sending or receiving data more than 1 bit at a time.
+
+ <DT>pipe
+ <DD>A one-way communications channel between two programs.
+
+ <DT>serial
+ <DD>Sending or receiving data 1 bit at a time.
+
+ <DT>socket
+ <DD>A two-way network communications channel.
+
+</DL>
+
+<H2>Acronyms</H2>
+
+<DL>
+
+ <DT>ASCII
+ <DD>American Standard Code for Information Interchange
+
+ <DT>CUPS
+ <DD>Common UNIX Printing System
+
+ <DT>ESC/P
+ <DD>EPSON Standard Code for Printers
+
+ <DT>FTP
+ <DD>File Transfer Protocol
+
+ <DT>HP-GL
+ <DD>Hewlett-Packard Graphics Language
+
+ <DT>HP-PCL
+ <DD>Hewlett-Packard Page Control Language
+
+ <DT>HP-PJL
+ <DD>Hewlett-Packard Printer Job Language
+
+ <DT>IETF
+ <DD>Internet Engineering Task Force
+
+ <DT>IPP
+ <DD>Internet Printing Protocol
+
+ <DT>ISO
+ <DD>International Standards Organization
+
+ <DT>LPD
+ <DD>Line Printer Daemon
+
+ <DT>MIME
+ <DD>Multimedia Internet Mail Exchange
+
+ <DT>PPD
+ <DD>PostScript Printer Description
+
+ <DT>SMB
+ <DD>Server Message Block
+
+ <DT>TFTP
+ <DD>Trivial File Transfer Protocol
+
+</DL>
diff --git a/doc/fr/images/accept-jobs.gif b/doc/fr/images/accept-jobs.gif
new file mode 100644
index 000000000..99a4446e8
--- /dev/null
+++ b/doc/fr/images/accept-jobs.gif
Binary files differ
diff --git a/doc/fr/images/add-class.gif b/doc/fr/images/add-class.gif
new file mode 100644
index 000000000..b3a9fd980
--- /dev/null
+++ b/doc/fr/images/add-class.gif
Binary files differ
diff --git a/doc/fr/images/add-printer.gif b/doc/fr/images/add-printer.gif
new file mode 100644
index 000000000..0369a0e55
--- /dev/null
+++ b/doc/fr/images/add-printer.gif
Binary files differ
diff --git a/doc/fr/images/cancel-job.gif b/doc/fr/images/cancel-job.gif
new file mode 100644
index 000000000..b8f580011
--- /dev/null
+++ b/doc/fr/images/cancel-job.gif
Binary files differ
diff --git a/doc/fr/images/cancel-jobs.gif b/doc/fr/images/cancel-jobs.gif
new file mode 100644
index 000000000..6a0825e64
--- /dev/null
+++ b/doc/fr/images/cancel-jobs.gif
Binary files differ
diff --git a/doc/fr/images/cancel.gif b/doc/fr/images/cancel.gif
new file mode 100644
index 000000000..6c2c62b4f
--- /dev/null
+++ b/doc/fr/images/cancel.gif
Binary files differ
diff --git a/doc/fr/images/config-printer.gif b/doc/fr/images/config-printer.gif
new file mode 100644
index 000000000..7e09990fe
--- /dev/null
+++ b/doc/fr/images/config-printer.gif
Binary files differ
diff --git a/doc/fr/images/continue.gif b/doc/fr/images/continue.gif
new file mode 100644
index 000000000..09a0dd48b
--- /dev/null
+++ b/doc/fr/images/continue.gif
Binary files differ
diff --git a/doc/fr/images/delete-class.gif b/doc/fr/images/delete-class.gif
new file mode 100644
index 000000000..19331087a
--- /dev/null
+++ b/doc/fr/images/delete-class.gif
Binary files differ
diff --git a/doc/fr/images/delete-printer.gif b/doc/fr/images/delete-printer.gif
new file mode 100644
index 000000000..7a358d0db
--- /dev/null
+++ b/doc/fr/images/delete-printer.gif
Binary files differ
diff --git a/doc/fr/images/hold-job.gif b/doc/fr/images/hold-job.gif
new file mode 100644
index 000000000..6cf473cd9
--- /dev/null
+++ b/doc/fr/images/hold-job.gif
Binary files differ
diff --git a/doc/fr/images/manage-classes.gif b/doc/fr/images/manage-classes.gif
new file mode 100644
index 000000000..30ead441e
--- /dev/null
+++ b/doc/fr/images/manage-classes.gif
Binary files differ
diff --git a/doc/fr/images/manage-jobs.gif b/doc/fr/images/manage-jobs.gif
new file mode 100644
index 000000000..c968698d5
--- /dev/null
+++ b/doc/fr/images/manage-jobs.gif
Binary files differ
diff --git a/doc/fr/images/manage-printers.gif b/doc/fr/images/manage-printers.gif
new file mode 100644
index 000000000..3cd147748
--- /dev/null
+++ b/doc/fr/images/manage-printers.gif
Binary files differ
diff --git a/doc/fr/images/modify-class.gif b/doc/fr/images/modify-class.gif
new file mode 100644
index 000000000..2774a6532
--- /dev/null
+++ b/doc/fr/images/modify-class.gif
Binary files differ
diff --git a/doc/fr/images/modify-printer.gif b/doc/fr/images/modify-printer.gif
new file mode 100644
index 000000000..b9b6e0a98
--- /dev/null
+++ b/doc/fr/images/modify-printer.gif
Binary files differ
diff --git a/doc/fr/images/navbar.gif b/doc/fr/images/navbar.gif
new file mode 100644
index 000000000..9de54be18
--- /dev/null
+++ b/doc/fr/images/navbar.gif
Binary files differ
diff --git a/doc/fr/images/print-test-page.gif b/doc/fr/images/print-test-page.gif
new file mode 100644
index 000000000..cd214cf78
--- /dev/null
+++ b/doc/fr/images/print-test-page.gif
Binary files differ
diff --git a/doc/fr/images/reject-jobs.gif b/doc/fr/images/reject-jobs.gif
new file mode 100644
index 000000000..39ee3092f
--- /dev/null
+++ b/doc/fr/images/reject-jobs.gif
Binary files differ
diff --git a/doc/fr/images/release-job.gif b/doc/fr/images/release-job.gif
new file mode 100644
index 000000000..59e9c6347
--- /dev/null
+++ b/doc/fr/images/release-job.gif
Binary files differ
diff --git a/doc/fr/images/restart-job.gif b/doc/fr/images/restart-job.gif
new file mode 100644
index 000000000..86c654471
--- /dev/null
+++ b/doc/fr/images/restart-job.gif
Binary files differ
diff --git a/doc/fr/images/show-active.gif b/doc/fr/images/show-active.gif
new file mode 100644
index 000000000..36388e72a
--- /dev/null
+++ b/doc/fr/images/show-active.gif
Binary files differ
diff --git a/doc/fr/images/show-completed.gif b/doc/fr/images/show-completed.gif
new file mode 100644
index 000000000..9685dbe93
--- /dev/null
+++ b/doc/fr/images/show-completed.gif
Binary files differ
diff --git a/doc/fr/images/start-class.gif b/doc/fr/images/start-class.gif
new file mode 100644
index 000000000..ca6cfc890
--- /dev/null
+++ b/doc/fr/images/start-class.gif
Binary files differ
diff --git a/doc/fr/images/start-printer.gif b/doc/fr/images/start-printer.gif
new file mode 100644
index 000000000..be66c5b1d
--- /dev/null
+++ b/doc/fr/images/start-printer.gif
Binary files differ
diff --git a/doc/fr/images/stop-class.gif b/doc/fr/images/stop-class.gif
new file mode 100644
index 000000000..828b98a51
--- /dev/null
+++ b/doc/fr/images/stop-class.gif
Binary files differ
diff --git a/doc/fr/images/stop-printer.gif b/doc/fr/images/stop-printer.gif
new file mode 100644
index 000000000..24c5b1e7b
--- /dev/null
+++ b/doc/fr/images/stop-printer.gif
Binary files differ
diff --git a/doc/fr/index.html b/doc/fr/index.html
new file mode 100644
index 000000000..17d4ffdcf
--- /dev/null
+++ b/doc/fr/index.html
@@ -0,0 +1,36 @@
+<HTML>
+<HEAD>
+ <TITLE>CUPS (Common UNIX Printing System)</TITLE>
+ <LINK REL=STYLESHEET TYPE="text/css" HREF="cups.css">
+ <MAP NAME="navbar">
+ <AREA SHAPE="RECT" COORDS="14,8,50,22" HREF="http://www.easysw.com" ALT="Page d'accueil Easy Software Products">
+ <AREA SHAPE="RECT" COORDS="76,8,182,22" HREF="admin" ALT="Tâches d'administration">
+ <AREA SHAPE="RECT" COORDS="202,8,260,22" HREF="classes" ALT="Etat des classes d'imprimantes">
+ <AREA SHAPE="RECT" COORDS="280,8,316,22" HREF="documentation.html" ALT="Aide électronique en ligne">
+ <AREA SHAPE="RECT" COORDS="334,8,394,22" HREF="jobs" ALT="Etat des travaux d'impression">
+ <AREA SHAPE="RECT" COORDS="416,8,506,22" HREF="printers" ALT="Etat des imprimantes">
+ <AREA SHAPE="RECT" COORDS="526,8,582,22" HREF="http://www.cups.org" ALT="Télécharger la dernière version du logiciel CUPS">
+ </MAP>
+</HEAD>
+
+<BODY BGCOLOR="#cccc99" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF">
+<CENTER>
+<IMG SRC="/images/navbar.gif" WIDTH="596" HEIGHT="28" USEMAP="#navbar" BORDER="0" ALT="CUPS (Common UNIX Printing System)">
+</CENTER>
+
+<H1><A HREF="admin">Tâches d'administration</A></H1>
+<H1><A HREF="classes">Administrer les classes d'imprimantes</A></H1>
+<H1><A HREF="documentation.html">Aide électronique en ligne</A></H1>
+<H1><A HREF="jobs">Administrer les travaux d'impression</A></H1>
+<H1><A HREF="printers">Administrer les imprimantes</A></H1>
+<H1><A HREF="http://www.cups.org">Télécharger la dernière version du logiciel CUPS</A></H1>
+
+<HR>
+<P>Common UNIX Printing System, CUPS, et le logo CUPS sont des marques déposées
+appartenant à <A HREF="http://www.easysw.com">Easy Software
+Products</A>. CUPS copyright 1997-2002 Easy Software Products,
+Tous droits réservés.
+
+
+</BODY>
+</HTML>
diff --git a/doc/fr/overview.html b/doc/fr/overview.html
new file mode 100644
index 000000000..ca80a45d2
--- /dev/null
+++ b/doc/fr/overview.html
@@ -0,0 +1,503 @@
+<HTML>
+<HEAD>
+ <META NAME="Author" CONTENT="Michael Sweet">
+ <META NAME="Translator" CONTENT="Marian REYT-LLABRES">
+ <TITLE>Un aperçu de CUPS (Common UNIX Printing System)</TITLE>
+ <LINK REL=STYLESHEET TYPE="text/css" HREF="cupsdoc.css">
+</HEAD>
+<BODY>
+<TABLE WIDTH="100%">
+<TR VALIGN=TOP>
+ <TD><IMG SRC="images/cups-large.gif" WIDTH="103" HEIGHT="120"></TD>
+ <TD><H1 ALIGN="RIGHT">Un aperçu de CUPS <BR>
+ (Common UNIX Printing System),<BR>
+ Version 1.1</H1>
+
+ <P ALIGN="RIGHT">July 10, 2000<BR>
+ Michael Sweet, Easy Software Products<BR>
+ Copyright 1998-2002, All Rights Reserved.</P>
+ <P ALIGN="RIGHT">Traduction française - 27/06/2002 : Marian REYT-LLABRES (mrl21_pub <i>at</i> netcourrier.com).</P>
+ </TD>
+</TR>
+</TABLE>
+
+<P>Ce document décrit le logiciel CUPS<SUP>TM</SUP> (Common UNIX Printing
+System<SUP>TM</SUP>), un système d'impression portable et extensible pour UNIX<SUP>&reg;</SUP>.
+CUPS est développé par
+<A HREF="http://www.easysw.com">Easy Software Products</A>, un éditeur logiciel
+implanté à Hollywood, Maryland qui vend des logiciels commerciaux pour UNIX depuis 1993
+par le biais de plus de 40 distributeurs répartis dans plus de 80 pays de par le monde.
+
+<P>Des informations supplémentaires sur CUPS sont disponibles sur le Web à l'adresse "<A HREF="http://www.cups.org">http://www.cups.org</A>".
+
+<H2>Avant-propos</H2>
+
+<P><hr width="50%" size="1px" color="#000000"><I><b>Note du traducteur : </b>Amies lectrices, amis lecteurs, j'ai fait le choix de <b>ne pas traduire</b> l'expression anglaise <b>"default"</b> par la
+version française
+habituellent utilisée <b>"par défaut"</b> que l'on doit, entre autres, à la documentation d'un célèbre système d'exploitation "ouvert à tous vents".
+<br /><br />
+En effet, l'expression "par défaut" est normalement utilisée en mathématiques (arrondi "par défaut" ou "par excès",
+personnellement je cherche encore mon "imprimante par excès" !)
+mais elle est abusivement employée en informatique pour signifier "donnée/comportement qui s'applique si l'on n'en
+précise pas <b>explicitement</b> la valeur/nature/teneur".
+<br /><br />
+Or la langue française possède justement un mot pout exprimer ce concept
+: "implicite" (Larousse 1998 : "Qui est contenu dans une proposition sans être exprimé en termes précis formels; qui est la
+conséquence nécessaire."). Dans la mesure du possible, j'utiliserai
+cet adjectif sauf dans les cas où son emploi n'est pas suffisamment <b>explicite</b> (sic !). Je lui
+préfèrerai alors l'expression "... de base ..." ou l'adjectif "standard".
+<br /><br />
+Ce choix est totalement personnel et le fait que j'ai fait l'effort (non négligeable) de traduire ces lignes pour vos yeux délicats suffit à le justifier! Si, par malheur, ma prose vous est insupportable,
+je ne vous empêche aucunement de vous reporter à la version originale où vous retrouverez "default" entouré de tout le
+reste... en anglais, bien sûr. Enfin, si vous avez une meilleure traduction, je suis preneur !
+<br /><br />
+Malgré les très nombreuses relectures et corrections, certaines fautes de frappe, d'orthographe ou de grammaire ont pu échapper à ma vigilance (ou à celles de mes relecteurs/correcteurs). Merci de me les signaler afin de contribuer à
+l'amélioration constante de la qualité du présent manuel.
+<br /><br />
+Bonne lecture !
+</I><hr width="50%" size="1px" color="#000000"></P>
+
+
+<P>
+Historiquement, l'impression sous UNIX a toujours été réalisée en utilisant
+un des deux systèmes d'impression - le Berkeley Line Printer Daemon ("LPD") [RFC1179]
+et l'AT&amp;T Line Printer. Ces systèmes d'impression ont été conçus dans les années 70 pour
+imprimer du texte sur des imprimantes matricielles à aiguilles; les constructeurs ont
+depuis ajouté divers systèmes de pilotage sur bien d'autres types d'imprimantes.
+
+<P>
+Des remplaçants pour ces systèmes d'impression ont émergé [LPRng,
+Palladin, PLP], cependant aucun d'eux n'a fondamentalement changé les capacités de ces systèmes historiques.
+
+<P>
+Au cours des dernières années, plusieurs tentatives de développement
+d'une interface d'impression standard ont été faites, celles-ci incluant le projet
+de standard d'impression POSIX développé par l'IEEE (Institute of Electrical and Electronics
+Engineers, Inc.) [IEEE-1387.4] ainsi que le protocole IPP (Internet Printing
+Protocol) développé par l'IETF (Internet Engineering Task Force) par le biais du PWG
+(Printer Working Group) [IETF-IPP]. Le standard d'impression POSIX définit un ensemble commun
+d'outils en ligne de commande ainsi qu'une interface C pour l'administration des
+imprimantes et des travaux d'impression, mais il a été abandonné par l'IEEE.
+
+<P>Le protocole IPP définit des extensions au protocole HTTP 1.1 (Hypertext Transport Protocol)
+[RFC2616] afin de fournir le support pour un service d'impression à distance.
+IPP/1.0 a été accepté par l'IETF comme une RFC (Request For Comments - Requête pour commentaires )
+expérimentale en octobre 1999. Depuis lors, le PWG (Printing Working Group) a développé un jeu
+de spécifications mises à jour pour IPP/1.1 qui a été accepté par l'IETF et attendent leur publication
+en tant que proposition de standard. Contrairement au système d'impression POSIX, IPP enthousiasme les
+acteurs de l'industrie et est en passe de devenir la solution standard d'impression via réseau pour tous
+les systèmes d'exploitation.
+
+<P>CUPS utilise le protocole IPP/1.1 pour fournir un système d'impression complet et moderne
+pour UNIX qui peut être étendu pour prendre en charge d'autres imprimantes, périphériques et protocoles tout
+en fournissant une compatibilité avec les applications UNIX existantes. CUPS est un logiciel libre distribué
+conformément aux termes de la licence GPL (General Public License).
+
+<H2>Historique</H2>
+
+
+<P>La première version de production de CUPS (basée sur le protocole IPP/1.0) a été réalisée
+en octobre 1999. Depuis ce jour, nous avons réalisé diverses mises à jour du produit original CUPS 1.0 qui
+concernaient la sécurité, la portabilité et des corrections de bogues, mais aucune nouvelle fonctionnalité n'a été
+ajoutée, ceci afin de garantir la stabilité du code de CUPS
+
+<P>CUPS 1.1 est basé sur IPP/1.1 et ajoute nombre des améliorations fonctionnelles qui ont été demandées
+par les utilsateurs. Comme pour la version 1.0, CUPS 1.1 sera suivie de mises à jour qui résoudront tout
+problème découvert sur le logiciel, mais elles n'ajouteront aucune nouvelle fonctionnalité.
+
+<H2>Aperçu de l'architecture</H2>
+
+<P>Comme la plupart des systèmes d'impression, CUPS est conçu autour d'un processus d'ordonnancement central qui
+répartit les travaux d'impression, exécute des tâches d'administration, fournit des informations sur l'état des imprimantes
+aux programmes locaux et distants, et informe les utilisateurs si nécessaire. La Figure 1 montre la base de l'organisation de CUPS.
+
+<CENTER><IMG SRC="images/cups-block-diagram.gif" WIDTH="470" HEIGHT="170"></CENTER>
+<P ALIGN="CENTER">Figure 1 - Diagramme de l'architecture globale de CUPS</P>
+
+<H3>L'ordonnanceur (Scheduler)</H3>
+
+<P>L'ordonnanceur est une application serveur HTTP 1.1 qui traite les requêtes HTTP. En plus de
+traiter les demandes reçues par le biais de requêtes IPP POST, l'ordonnanceur agit également comme un serveur
+"web" totalement fonctionnel qui ouvre l'accès à la documentation, à la surveillance de l'état du système et
+ à son administration.
+
+
+<P>L'ordonnanceur maintient également une liste des imprimantes disponibles sur le réseau local (LAN) et répartit
+les travaux d'impression si nécessaire en employant les filtres ou les programmes appropriés.
+
+<H3>Fichiers de configuration</H3>
+
+Les fichiers se répartissent de la manière suivante :
+
+<UL>
+
+ <LI>Le fichier de configuration du serveur HTTP.
+
+ <LI>Les fichiers de définition des imprimantes et des classes d'imprimantes.
+
+ <LI>Les fichiers décrivant les règles de conversion des types MIME.
+
+ <LI>Les fichiers PPD (PostScript Printer Description).
+
+</UL>
+
+<P>Le fichier de configuration du serveur HTTP est conçu dans la même optique que celle du fichier de configuration du serveur Apache et
+définit toutes les règles de contrôle d'accès pour le serveur.
+
+<P>Les fichiers de définition des imprimantes et des classes d'imprimantes listent les classes d'imprimantes et les
+files d'impression disponibles. Les classes d'imprimantes sont des collections d'imprimantes. Les travaux
+d'impression envoyés à une classe sont transmis à la première imprimante disponible de la classe selon un méthode de type "round-robin".
+
+<P>Les fichiers de définition des types MIME listent les différents types MIME pris en charge (texte simple, postscript, etc...)
+et des règles "magiques" pour détecter automatiquement le format d'un fichier. Ils sont utilisés par le serveur
+HTTP pour renseigner le champ <I>Content-Type</I> des requêtes <I>GET</I> et <I>HEAD</I>, et par le
+gestionnaire de requêtes IPP pour déterminer le type de fichier lorsqu'une requête <I>Print-Job</I> ou <I>Send-File</I>
+est reçue avec un champ <I>document-format</I> contenant la valeur <I>application/octet-stream</I>.
+
+<P>Les fichiers de règles de conversion MIME listent les filtres disponibles. Les filtres sont utilisés
+quand un travail d'impression est soumis, de sorte qu'une application puisse envoyer un format de fichier
+adapté au système d'impression qui convertit alors le document dans un format imprimable. Chaque filtre a un
+coût relatif associé, et l'algorithme de filtrage choisit le jeu de filtres qui permettra de convertir le
+fichier avec un coût minimal.
+
+<P>Les fichiers PPD décrivent les capacités de toutes les imprimantes, pas seulement celles de type PostScript.
+Il y a un fichier PPD pour chaque imprimante. Les fichier PPD pour les imprimantes non-PostScript définissent des
+filtres additionnels au moyen des attributs <I>cupsFilter</I> afin de prendre en charge les pilotes d'imprimantes.
+
+<H3>L'API CUPS</H3>
+
+<P>L'API CUPS contient des fonctions spécifiques à CUPS pour mettre en file d'attente les travaux
+d'impression, récupérer de l'information sur les imprimantes, accéder aux ressources via les
+protocoles HTTP et IPP, manipuler les fichiers PPD. Contrairement au reste de CUPS, l'API CUPS
+est distribuée conformément aux termes de la licence LGPL ainsi elle peut être utilisée par des
+applications non-GPL.
+
+<H3>Commandes de type Berkeley et System V</H3>
+
+<P>CUPS fournit une interface en ligne de commande de type System V et Berkeley pour soumettre des travaux
+d'impression et vérifier l'état des imprimantes. Les commandes <CODE>lpstat</CODE> et <CODE>lpc status</CODE>
+affichent aussi les imprimantes réseau ("imprimante@serveur") lorsque l'exploration réseau des imprimantes ("printer browsing") est activée.
+
+<P>Les commandes d'administration de type System V sont fournies pour administrer les imprimantes et les classes
+d'imprimantes. L'outil d'administration d'imrpimante Berkeley <CODE>lpc</CODE> est uniquement pris en charge en mode
+"lecture seule" pour vérifier l'état actuel des files d'impression et de l'ordonnanceur.
+
+<H3>Filtres</H3>
+
+<P>Un programme de filtrage lit les données depuis l'entrée standard ou depuis un fichier si un nom de fichier est indiqué.
+Tous les filtres doivent prendre en charge un jeu commun d'options incluant le nom d'imprimante, ne n°
+d'identification du travail d'impression (ID), le nom de l'utilisateur, le nombre de copies,
+et des options pour le travail d'impression. Toute sortie est envoyée vers la sortie standard.
+
+<P>Des filtres sont fournis pour de nombreux formats de fichiers y compris les fichiers image et des filtres
+PostScript "matriciels" <i>(NdT : "raster" = au sens où le document imprimé est en fait une image générée par une trame de points,
+par exemple une imprimante à jet d'encre est de type "matriciel" même si l'impression ne se fait pas au moyen
+d'aiguilles venant frapper un ruban et déposer de l'encre sur le papier, souvenirs, souvenirs...)</i> qui prennent
+en charge les
+imprimantes non-PostScript <i>(NdT : par opposition, le langage PostScript est un langage de description de
+page de type vectoriel)</i>. Plusieurs filtres sont exécutés
+en parallèle pour produire le format de sortie désiré.
+
+<P>Le filtre PostScript "matriciel" est basé sur le coeur du logiciel GNU Ghostscript 5.50. Au lieu
+d'utiliser l'application d'arrière-plan et les pilotes d'imprimantes Ghostscript, le filtre CUPS utilise un
+pilote "matriciel" d'imprimante générique et une application d'arrière-plan compatible CUPS pour prendre en
+compte toute imprimante de type "matriciel". Ceci permet d'employer le même filtre de pilote d'impression
+pour imprimer des données de type "matriciel" provenant de n'importe quel filtre. <i>(NdT : je suis preneur de toute information ou tout éclaircissement qui pourrait me permettre de produire une
+meilleure traduction pour les trois paragraphes précédents.)</i>
+
+<H3>Rendu d'image dans CUPS</H3>
+
+<P>La librairie de rendu d'image de CUPS fournit des fonctions pour manipuler
+des images de grande taille, faire des conversions de palettes et des manipulations
+sur les couleurs, dimensionner les images en vue de l'impression et administrer les flux de données
+pour les pages de type "matriciel". Elle est utilisée par les filtres de fichiers image de CUPS,
+et tous les pilotes d'imprimantes de type "matriciel".
+
+<H3>Programmes d'arrière-plan (Backends)</H3>
+
+<P>Un programme d'arrière-plan est programme qui envoie des données d'impression à un périphérique ou
+à une connexion réseau. Des programmes d'arrière-plan pour port parallèle, port série, USB, LPD, IPP,
+et les connexions AppSocket (JetDirect) sont fournis dans CUPS 1.1.
+
+<P>Les versions de SAMBA commençant à partir de la version 2.0.6. incluent un programme d'arrière-plan SMB
+(<CODE>smbspool(1)</CODE>) qui peut être employé avec CUPS 1.0 ou 1.1 pour imprimer vers des
+machines Windows.
+
+<H2>Impression réseau</H2>
+
+<P>Traditionnellement, l'impression réseau a toujour été l'une des choses les plus difficiles à faire
+fonctionner sous UNIX. Une des raisons est que chaque fabricant ou vendeur a ajouté ses propres extensions
+au protocol LPD (le standard précédent pour l'impression réseau), rendant l'impression inter-plateformes difficile
+voire impossible.
+
+<P>Une autre raison est que vous devez administrer chaque imprimante réseau sur chaque machine cliente.
+Dans certains cas, vous pouvez clôner la configuration à partir d'un original pour tous les autres postes, mais
+même cette méthode peut être une perte de temps et une source d'erreur. Quelque chose de mieux est nécessaire.
+
+<P>CUPS fournit l'exploration des imprimantes réseau ("printer browsing") qui autorise les clients à
+voir et utiliser automatiquement les imprimantes de tout serveur sur le réseau local (LAN). Cela signifie que
+vous devez seulement configurer le serveur et les clients verront automatiquement les imprimantes et les classes
+d'imprimantes définies sur celui-ci.
+
+<P>En plus de cela, CUPS peut automatiquement fusionner plusieurs imprimantes réseau identiques en des
+classes implicites <i>(NdT : le terme "implicite" est ici la traduction littérale du même mot anglais "implicit" et non celle de l'expression "default". Cf. ma note en tête du présent manuel.)</i>. Cela permet aux clients de soumettre des travaux d'impression à une classe implicite et que
+ceux-ci soient imprimés sur la première imprimante ou le premier serveur disponible. En plus de cela, des fonctions de
+répartition de charge et de tolérance de panne sont activées en définissant simplement la même imprimante sur plusieurs serveurs!
+
+<H2>Nouvelles fonctionnalités dans CUPS 1.1</H2>
+
+<P>CUPS 1.1 inclut de nombreuses nouvelles fonctionnalités et caractéristiques:
+
+<OL>
+
+ <LI><A HREF="#BACKENDS">Programmes d'arrière-plan (Backends)</A>
+
+ <LI><A HREF="#BANNERS">Support des pages de garde (Banner Page)</A>
+
+ <LI><A HREF="#DIGEST">Authentication "Digest"</A>
+
+ <LI><A HREF="#DIRSVC">Services d'annuaires</A>
+
+ <LI><A HREF="#FHS2">Changement de stucture des répertoires</A>
+
+ <LI><A HREF="#DOCOS">Documentation</A>
+
+ <LI><A HREF="#DRIVERS">Pilotes</A>
+
+ <LI><A HREF="#FILTERS">Filtres</A>
+
+ <LI><A HREF="#IPP">Prise en charge IPP</A>
+
+ <LI><A HREF="#PERSISTENCE">Persistance des travaux d'impression</A>
+
+ <LI><A HREF="#LPD">Prise en charge des clients LPD</A>
+
+ <LI><A HREF="#USEROPTS">Imprimantes et options définies par l'utilisateur</A>
+
+ <LI><A HREF="#WEB">Interface d'administration "web"</A>
+
+</OL>
+
+<H3><A NAME="BACKENDS">1. Programmes d'arrière-plan (Backends)</A></H3>
+
+<P>CUPS 1.1 implémente une nouvelle interface pour les programmes d'arrière-plan afin de récupérer
+la liste des périphériques disponibles pour les clients CUPS. Ceci permet aux interfaces d'administration
+d'interroger l'ordonnanceur CUPS pour obtenir une liste des périphériques disponibles, configurer automatiquement
+les imprimante si les informations d'identification du périphérique sont disponibles, et présenter une liste à
+l'utilisateur plutôt que compter sur celui-ci pour savoir quels périphériques sont réellement disponibles sur son système.
+
+
+<P>La nouvelle version inclut un programme d'arrière-plan pour les imprimantes USB sous
+*BSD et GNU/Linux. La prise en charge USB sous Solaris 8 sera fournie dans une prochaine mise à
+jour du produit.
+
+<H3><A NAME="BANNERS">2. Pages de garde (Banner Page)</A></H3>
+
+<P>CUPS 1.1 inclut la prise en charge des page de garde au début et à la fin d'un travail d'impression. Les
+pages de garde peuvent être dans n'importe quel format de fichier et prennent en charge la substitution de
+variable pour le titre des travaux d'impression, les noms d'utilisateurs, etc. Des pages de garde implicites
+("par défaut") peuvent être associées à chaque imprimante et peuvent être outrepassées par l'utilisateur
+au moyen des options sur la ligne de commande.
+
+<H3><A NAME="DIGEST">3. Authentification "Digest"</A></H3>
+
+<P>L'authentification "Digest" fournit une méthode plus sécurisée pour
+accéder au système d'impression. Contrairement à l'authentification "Basic", l'authentification "Digest"
+n'envoie pas de mots de passe en clair sur le réseau ainsi il est plus difficile d'avoir un accès non
+autorisé à votre système.
+
+<P>CUPS 1.1 implémente l'authentification "Digest" en utilisant un fichier de mot de passe MD5 spécial
+au lieu du fichier de mots de passe UNIX. Ce fichier est administré au moyen de la commande <CODE>lppasswd</CODE>.
+
+<H3><A NAME="DIRSVC">4. Services d'annuaires</A></H3>
+
+<P>CUPS 1.1 ajoute une nouvelle fonctionnalité de service d'annuaire ("printer browsing" = exploration des
+imprimantes) pour permettre d'employer plus facilement CUPS sur de grands réseaux locaux (LAN) ou des réseaux WAN.
+Vous pouvez maintenant surveiller un serveur distant pour obtenir des informations d'impression et les relayer
+sur le LAN, ainsi que limiter les informations d'impression qui sont traitées (par exemple, cacher des serveurs,
+des domaines ou des réseaux que vous ne voulez pas voir).
+
+<H3><A NAME="FHS2">5. Changement de structure de répertoires</A></H3>
+
+<P>CUPS 1.1 utilise désormais une structure de répertoire conforme à la version 2.0 des recommandations FHS ("Filesystem Hierarchy Standard")
+Ceci devrait rendre son intégration dans des distributions *BSD ou GNU/Linux plus facile.
+
+<H3><A NAME="DOCOS">6. Documentation</A></H3>
+
+<P>La documentation de CUPS 1.1 a subi de nombreuses révisions incluant une réécriture complète du guide de
+l'administrateur, un nouveau guide du programmeur et un manuel de référence de l'implémentation du protocole IPP.
+<i>(NdT : ...et maintenant, une traduction française d'une partie celle-ci... ;o)</i>
+
+<H3><A NAME="DRIVERS">7. Pilotes</A></H3>
+
+<P>CUPS 1.1 inclut des pilotes pour imprimantes matricielles à aiguilles et jet d'encre EPSON.
+Comme pour les pilots HP PCL, les pilotes EPSON ne fournissent pas forcément la meilleure sortie possible pour
+chaque imprimante mais devrait produire une qualité suffisante pour les impressions de la vie courante.
+
+<H3><A NAME="FILTERS">8. Filtres</A></H3>
+
+<P>CUPS 1.1 inclut de nouveaux filtres image, PostScript, PDF et texte. Les filtres image ont
+été mis à jour pour prendre en charge les fichiers Windows BMP et Alias PIX.
+
+<P>Le filtre PostScript est maintenant basé sur GNU/Ghostscript 5.50. Le nouveau filtre fournit des performances
+bien meilleures avec les imprimantes haute résolution et prend en charge la plupart des caractéristiques du
+langage PostScript 3.
+
+<P>Le nouveau filtre PDF est basé sur l'excellent programme Xpdf de Derek Noonburg et prend en charge la mise
+à l'échelle automatique de page. Le nouveau filtre est plus rapide, plus petit, un remplaçant plus avantageux
+pour le filtre PDF GNU/Ghostscript qui était utilisé dans CUPS 1.0.
+
+<P>Le nouveau filtre texte prend à présent en charge le texte bidirectionnel et peut encapsuler les polices
+de caractères si nécessaire.
+
+<H3><A NAME="IPP">9. Support IPP</A></H3>
+
+<P>La partie la moins visible de CUPS est probablement le support IPP. CUPS 1.1 implémente toutes les opérations
+et attributs requis dans le protocole IPP/1.1 et la plupart de ceux qui sont facultatifs.Les opérations optionnelles
+Create-Job et Send-File sont maintenant implémentées, permettant une meilleur compatibilité avec les systèmes
+d'impression de type System V (un n° de travail d'impression par commande <CODE>lp</CODE>) et le support des pages
+de garde.
+
+<H3><A NAME="PERSISTENCE">10. Persistance des travaux d'impression</A></H3>
+
+<P>CUPS 1.1 supporte la persistance des travaux d'impression. Cela signifie que les travaux d'impression sont
+préservés même après un redémarrage du système, une fonctionnalité qui était malheureusement absente de CUPS 1.0.
+
+<P>En plus de cela, CUPS 1.1 vous permet de conserver des informations sur un travail d'impression après que le
+travail ait été imprimé. Le mode de base de persistance de travaux d'impression fournit un historique des travaux
+(nombre de pages imprimées, heure de soumission du travail, etc...) mais ne conserve pas les fichiers réels du
+travail d'impression. Cela peut être changé pour supprimer toute information sur les travaux d'impression après
+qu'ils aient été imprimés ou pour conserver les fichiers réels des travaux d'impression de manière à pouvoir
+les resoumettre ultérieurement.
+
+<H3><A NAME="LPD">11. Support de clients LPD</A></H3>
+
+<P>A la demande générale, CUPS 1.1 prend en charge les client basés sur LPD au moyen d'un nouveu mini démon qui
+traite les requêtes LPD et les transmet au serveur principal.
+
+<H3><A NAME="USEROPTS">12. Imprimantes et options définies par l'utilisateur</A></H3>
+
+<P>CUPS 1.1 inclut la prise en charge d'imprimantes et d'options définies par l'utilisateur via une nouvelle
+commande <CODE>lpoptions</CODE>. Les imprimantes définies par l'utilisateur sont des instances spéciales
+d'imprimantes disponibles (par exemple "imprimante/instance" ou "imprimante@serveur/instance") qui peuvent avoir
+leur propre options de base telles la taille du papier, la résolution, et ainsi de suite.
+La commande <CODE>lpoptions</CODE> peut également être utilisée pour définir une autre file d'impression implicite.
+
+<H3><A NAME="WEB">13. Interface d'administration "web"</A></H3>
+
+<P>CUPS 1.0 fournissait une interface très limitée pour la surveillance des classes d'imprimantes, des travaux
+d'impression et des imprimantes au moyen des navigateurs web. CUPS 1.1 remplace cette interface par une interface
+d'administration améliorée qui vous permet d'ajouter, modifier, supprimer, configurer et contrôler les classes
+d'imprimantes, les travaux d'impression et les imprimantes.
+
+<H2>Logiciels utilisant CUPS</H2>
+
+<P>Il s'est passé beaucoup de choses depuis que CUPS 1.0 est sorti, et beaucoup de produits logiciels prennent en
+charge CUPS. Nous avons contribué au code de l'équipe SAMBA pour prendre en charge CUPS, et une partie de cela
+est déjà disponible dans SAMBA 2.0.6 et 2.0.7. Avec un peu de chance, les pièces finales qui fournissent une
+complète intégration dans SAMBA seront disponibles dans la prochaine version de SAMBA.
+
+<P>Deux interfaces graphiques utilisant CUPS ont également vu le jour. Le projet KUPS fournit une interface
+pour CUPS basée sur KDE et peut être trouvée à l'adresse :
+
+<UL><PRE>
+<A HREF="http://kups.sourceforge.net">http://kups.sourceforge.net</A>
+</PRE></UL>
+
+<P>Le projet XPP ("X Printing Panel") fournit une interface graphique de panneau d'impression pour CUPS et
+peut être trouvé à l'adresse:
+
+<UL><PRE>r
+<A HREF="http://www.phy.uni-bayreuth.de/till/xpp">http://www.phy.uni-bayreuth.de/till/xpp/</A>
+</PRE></UL>
+
+<P>De nombreux autres filtres, pilotes et tutoriels, etc ont été rendus disponibles dans le "bazaar" CUPS à
+l'adresse:
+
+<UL><PRE>
+<A HREF="http://www.cups.org/bazaar.cgi">http://www.cups.org/bazaar.cgi</A>
+</PRE></UL>
+
+<P>Finalement, notre propre logiciel ESP Print Pro utilise CUPS pour fournir des pilotes pour des milliers
+d'imprimantes et peut être trouvé à l'adresse:
+
+<UL><PRE>
+<A HREF="http://www.easysw.com/printpro">http://www.easysw.com/printpro</A>
+</PRE></UL>
+
+<H2>Systèmes d'exploitation utilisant CUPS</H2>
+
+<P>Un de nos buts a toujours été d'amener autant de distributions UNIX et GNU/Linux que possible à utiliser CUPS.
+Debian fournit actuellement CUPS dans sa distribution stable, et beaucoup d'autres distributions projettent
+d'en faire autant dans leurs prochaines versions.
+
+<H2>Résumé</H2>
+
+<P>Le système CUPS fournit une interface d'impression moderne pour les applications UNIX qui est à la fois
+flexible et ergonomique. Le logiciel fournit des interfaces sur ligne de commande compatibles avec System V et Berkeley pour
+assurer la compatibilité avec les applications existantes. CUPS 1.1 ajoute de nombreuses nouvelles fonctionnalités
+qui en font encore plus un excellent choix pour imprimer sous UNIX.
+
+<H2>Qui contacter ?</H2>
+
+<P>Pour de plus amples informations, contactez-nous à:
+
+<UL><PRE>
+Attn: CUPS Information
+Easy Software Products
+44141 Airport View Drive Suite 204
+Hollywood, Maryland 20636-3111 USA
+
++1.301.373.9600
+
+<A HREF="mailto:cups-info@cups.org">cups-info@cups.org</A>
+</PRE></UL>
+
+<H2>Références</H2>
+
+<DL>
+
+ <DT>IEEE-1387.4</DT>
+
+ <DD>System Administration - Part 4: Printing Interfaces (draft)</DD>
+
+ <DT><A HREF="http://www.pwg.org/ipp/index.html">IETF-IPP</A></DT>
+
+ <DD>Internet Printing Protocol/1.1</DD>
+
+ <DT><A HREF="http://www.astart.com/lprng.html">LPRng</A></DT>
+
+ <DD>An enhanced, extended, and portable implementation of the
+ Berkeley LPR print spooler functionality</DD>
+
+ <DT>Palladin</DT>
+
+ <DD>A printing system developed at the Massachussetts Institute
+ of Technology</DD>
+
+ <DT><A HREF="http://www-usa.iona.com//hyplan/jmason/plp.html">PLP</A></DT>
+
+ <DD>The Portable Line Printer spooler system</DD>
+
+ <DT><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC1179</A></DT>
+
+ <DD>Line Printer Daemon Protocol</DD>
+
+ <DT><A HREF="http://www.ietf.org/rfc/rfc2046.txt">RFC2046</A></DT>
+
+ <DD>Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types</DD>
+
+ <DT><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</A></DT>
+
+ <DD>Hypertext Transfer Protocol -- HTTP/1.1</DD>
+
+</DL>
+
+<H2>Trademarks</H2>
+
+<P>The Common UNIX Printing System, CUPS, and the CUPS logo are the
+trademark property of Easy Software Products. All other trademarks are
+the property of their respective owners.
+
+</BODY>
+</HTML>
diff --git a/doc/fr/overview.pdf b/doc/fr/overview.pdf
new file mode 100644
index 000000000..78b269384
--- /dev/null
+++ b/doc/fr/overview.pdf
Binary files differ
diff --git a/doc/fr/printing-overview.shtml b/doc/fr/printing-overview.shtml
new file mode 100644
index 000000000..1682dae7f
--- /dev/null
+++ b/doc/fr/printing-overview.shtml
@@ -0,0 +1,125 @@
+<H1 ALIGN="RIGHT"><A NAME="OVERVIEW">1 - Printing System Overview</A></H1>
+
+<P>This chapter provides an overview of how the Common UNIX Printing System
+works.
+
+<H2>The Printing Problem</H2>
+
+<P>For years <I>the printing problem</I> has plagued UNIX. Unlike
+Microsoft&reg; Windows&reg; or Mac OS, UNIX has no standard interface or
+system in place for supporting printers. Among the solutions currently
+available, the Berkeley and System V printing systems are the most
+prevalent.
+
+<P>These printing systems support line printers (text only) or
+PostScript printers (text and graphics), and with some coaxing they can
+be made to support a full range of printers and file formats. However,
+because each varient of the UNIX operating system uses a different
+printing system than the next developing printer drivers for a wide
+range of printers and operating systems is extremely difficult. That
+combined with the limited volume of customers for each UNIX varient has
+forced most printer vendors to give up supporting UNIX entirely.
+
+<P>CUPS is designed to eliminate <I>the printing problem</I>. One
+common printing system can be used by all UNIX varients to support the
+printing needs of users. Printer vendors can use its modular filter
+interface to develop a single driver program that supports a wide range
+of file formats with little or no effort. Since CUPS provides both the
+System V and Berkeley printing commands, users (and applications) can
+reap the benefits of this new technology with no changes.
+
+<H2>The Technology</H2>
+
+<P>CUPS is based upon an emerging Internet standard called the Internet
+Printing Protocol. IPP has been embraced by dozens of printer and
+printer server manufacturers and is supported by Microsoft Windows
+2000.
+
+<P>IPP defines a standard protocol for printing as well as managing
+print jobs and printer options like media size, resolution, and so
+forth. Like all IP-based protocols, IPP can be used locally or over the
+Internet to printers hundreds or thousands of miles away. Unlike other
+protocols, however, IPP also supports access control, authentication,
+and encryption, making it a much more capable and secure printing
+solution than older ones.
+
+<P>IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP")
+which is the basis of web servers on the Internet. This allows users
+to view documentation, check status information on a printer or server,
+and manage their printers, classes, and jobs using their web browser.
+
+<P>CUPS provides a complete IPP/1.1 based printing system that provides
+Basic, Digest, and local certificate authentication and user, domain,
+or IP-based access control. TLS encryption will be available in future
+versions of CUPS.
+
+<H2>Jobs</H2>
+
+<P>Each file or set of files that is submitted for printing is called a
+<I>job</I>. Jobs are identified by a unique number starting at 1 and
+are assigned to a particular destination, usually a printer. Jobs can
+also have options associated with them such as media size, number of
+copies, and priority.
+
+<H2>Classes</H2>
+
+<P>CUPS supports collections of printers known as <I>classes</I>. Jobs
+sent to a class are forwarded to the first available printer in the
+class.
+
+<H2>Filters</H2>
+
+<P>Filters allow a user or application to print many types of files
+without extra effort. Print jobs sent to a CUPS server are filtered
+before sending them to a printer. Some filters convert job files to
+different formats that the printer can understand. Others perform page
+selection and ordering tasks.
+
+<P>CUPS provides filters for printing many types of image files,
+HP-GL/2 files, PDF files, and text files. CUPS also supplies PostScript
+and image file Raster Image Processor ("RIP") filters that convert
+PostScript or image files into bitmaps that can be sent to a raster
+printer.
+
+<H2>Backends</H2>
+
+<P>Backends perform the most important task of all - they send the
+filtered print data to the printer.
+
+<P>CUPS provides backends for printing over parallel, serial, and USB
+ports, and over the network via the IPP, JetDirect (AppSocket), and
+Line Printer Daemon ("LPD") protocols. Additional backends are
+available in network service packages such as the SMB backend
+included with the popular SAMBA software.
+
+<P>Backends are also used to determine the available devices. On
+startup each backend is asked for a list of devices it supports,
+and any information that is available. This allows the parallel
+backend to tell CUPS that an EPSON Stylus Color 600 printer is
+attached to parallel port 1, for example.
+
+<H2>Printer Drivers</H2>
+
+<P>Printer drivers in CUPS consist of one of more filters specific to a
+printer. CUPS includes sample printer drivers for Hewlett-Packard
+LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color,
+and Stylus Photo printers. While these drivers do not generate optimal
+output for the different printer models, they do provide basic printing
+and demonstrate how you can write your own printer drivers and
+incorporate them into CUPS.
+
+<H2>Networking</H2>
+
+<P>Printers and classes on the local system are automatically shared
+with other systems on the network. This allows you to setup one system
+to print to a printer and use this system as a printer server or spool
+host for all of the others. Users may then select a local printer by
+name or a remote printer using "name@server".
+
+<P>CUPS also provides <I>implicit classes</I>, which are collections of
+printers and/or classes with the same name. This allows you to setup
+multiple servers pointing to the same physical network printer, for
+example, so that you aren't relying on a single system for printing.
+Because this also works with printer classes, you can setup multiple
+servers and printers and never worry about a single point of failure
+unless all of the printers and servers go down!
diff --git a/doc/fr/references.shtml b/doc/fr/references.shtml
new file mode 100644
index 000000000..4b4930e57
--- /dev/null
+++ b/doc/fr/references.shtml
@@ -0,0 +1,42 @@
+<H1>References</H1>
+
+<H2>CUPS Documentation</H2>
+
+<P>The following CUPS documentation is referenced by this document:
+
+<UL>
+ <LI>CUPS-CMP-1.1: CUPS Configuration Management Plan
+ <LI>CUPS-IDD-1.1: CUPS System Interface Design Description
+ <LI>CUPS-IPP-1.1: CUPS Implementation of IPP
+ <LI>CUPS-SAM-1.1.x: CUPS Software Administrators Manual
+ <LI>CUPS-SDD-1.1: CUPS Software Design Description
+ <LI>CUPS-SPM-1.1.x: CUPS Software Programming Manual
+ <LI>CUPS-SSR-1.1: CUPS Software Security Report
+ <LI>CUPS-STP-1.1: CUPS Software Test Plan
+ <LI>CUPS-SUM-1.1.x: CUPS Software Users Manual
+ <LI>CUPS-SVD-1.1: CUPS Software Version Description
+</UL>
+
+<H2>Other Documents</H2>
+
+<P>The following non-CUPS documents are referenced by this document:
+
+<UL>
+ <LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">Adobe
+ PostScript Printer Description File Format Specification,
+ Version 4.3.</A>
+ <LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">Adobe
+ PostScript Language Reference, Third Edition.</A>
+ <LI>IPP: Job and Printer Set Operations
+ <LI>IPP/1.1: Encoding and Transport
+ <LI>IPP/1.1: Implementers Guide
+ <LI>IPP/1.1: Model and Semantics
+ <LI><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179, Line Printer Daemon Protocol</A>
+ <LI><A HREF="http://www.ietf.org/rfc/rfc2567.txt">RFC 2567, Design Goals for an Internet Printing Protocol</A>
+ <LI><A HREF="http://www.ietf.org/rfc/rfc2568.txt">RFC 2568, Rationale for the Structure of the Model and Protocol</A>
+ for the Internet Printing Protocol</A>
+ <LI><A HREF="http://www.ietf.org/rfc/rfc2569.txt">RFC 2569, Mapping between LPD and IPP Protocols</A>
+ <LI><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616, Hypertext Transfer Protocol -- HTTP/1.1</A>
+ <LI><A HREF="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617, HTTP Authentication: Basic and Digest Access</A>
+ Authentication
+</UL>
diff --git a/doc/fr/sam.html b/doc/fr/sam.html
new file mode 100644
index 000000000..889c3a5b6
--- /dev/null
+++ b/doc/fr/sam.html
@@ -0,0 +1,5219 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Software Administrators Manual</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-SAM-1.1.15">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY BGCOLOR="#ffffff">
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Software Administrators Manual</H1></A><BR>
+CUPS-SAM-1.1.15<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">Preface</A></B>
+<UL>
+<LI><A HREF="#1_1">System Overview</A></LI>
+<LI><A HREF="#1_2">Document Overview</A></LI>
+<LI><A HREF="#1_3">Notation Conventions</A></LI>
+<LI><A HREF="#1_4">Abbreviations</A></LI>
+<LI><A HREF="#1_5">Other References</A></LI>
+</UL>
+<B><A HREF="#OVERVIEW">1 - Printing System Overview</A></B>
+<UL>
+<LI><A HREF="#2_1">The Printing Problem</A></LI>
+<LI><A HREF="#2_2">The Technology</A></LI>
+<LI><A HREF="#2_3">Jobs</A></LI>
+<LI><A HREF="#2_4">Classes</A></LI>
+<LI><A HREF="#2_5">Filters</A></LI>
+<LI><A HREF="#2_6">Backends</A></LI>
+<LI><A HREF="#2_7">Printer Drivers</A></LI>
+<LI><A HREF="#2_8">Networking</A></LI>
+</UL>
+<B><A HREF="#BUILDING_INSTALLING">2 - Building and Installing CUPS</A></B>
+<UL>
+<LI><A HREF="#3_1">Installing a Source Distribution</A></LI>
+<UL>
+<LI><A HREF="#REQUIREMENTS">Requirements</A></LI>
+<LI><A HREF="#COMPILING">Compiling CUPS</A></LI>
+<LI><A HREF="#INSTALLING">Installing the Software</A></LI>
+<LI><A HREF="#RUNNING">Running the Software</A></LI>
+</UL>
+<LI><A HREF="#BINARY">Installing a Binary Distribution</A></LI>
+<UL>
+<LI><A HREF="#PORTABLE-BINARY">Installing a Portable Distribution</A></LI>
+<LI><A HREF="#RPM-BINARY">Installing an RPM Distribution</A></LI>
+<LI><A HREF="#DPKG-BINARY">Installing an Debian Distribution</A></LI>
+</UL>
+</UL>
+<B><A HREF="#MANAGING_PRINTERS">3 - Managing Printers</A></B>
+<UL>
+<LI><A HREF="#4_1">The Basics</A></LI>
+<LI><A HREF="#4_2">Adding Your First Printer</A></LI>
+<UL>
+<LI><A HREF="#4_2_1">Adding Your First Printer from the Command-Line</A></LI>
+<LI><A HREF="#ADD_WEB">Adding Your First Printer from the Web</A></LI>
+</UL>
+<LI><A HREF="#4_3">Managing Printers from the Command-Line</A></LI>
+<UL>
+<LI><A HREF="#4_3_1">Adding and Modifying Printers</A></LI>
+<LI><A HREF="#4_3_2">Deleting Printers</A></LI>
+<LI><A HREF="#4_3_3">Setting the Default Printer</A></LI>
+<LI><A HREF="#4_3_4">Starting and Stopping Printers</A></LI>
+<LI><A HREF="#4_3_5">Accepting and Rejecting Print Jobs</A></LI>
+<LI><A HREF="#4_3_6">Setting Quotas on a Printer</A></LI>
+<LI><A HREF="#4_3_7">Restricting User Access to a Printer</A></LI>
+</UL>
+<LI><A HREF="#4_4">Managing Printers from the Web</A></LI>
+</UL>
+<B><A HREF="#PRINTER_CLASSES">4 - Printer Classes</A></B>
+<UL>
+<LI><A HREF="#5_1">The Basics</A></LI>
+<LI><A HREF="#5_2">Managing Printer Classes from the Command-Line</A></LI>
+<LI><A HREF="#5_3">Managing Printer Classes from the Web Interface</A></LI>
+<LI><A HREF="#5_4">Implicit Classes</A></LI>
+</UL>
+<B><A HREF="#CLIENT_SETUP">5 - Client Setup</A></B>
+<UL>
+<LI><A HREF="#6_1">The Basics</A></LI>
+<UL>
+<LI><A HREF="#CLIENT_MANUAL">Manual Configuration of Print Queues</A></LI>
+<LI><A HREF="#CLIENT_SERVER">Specifying a Single Server for Printing</A></LI>
+<LI><A HREF="#CLIENT_AUTO">Automatic Configuration of Print Queues</A></LI>
+<LI><A HREF="#CLIENT_POLL">Specifying Multiple Servers for Printing</A></LI>
+<LI><A HREF="#CLIENT_RELAY">Relaying Printers to Other Clients</A></LI>
+</UL>
+<LI><A HREF="#6_2">Load Balancing and Failsafe Operation</A></LI>
+</UL>
+<B><A HREF="#PRINTING_MANAGEMENT">6 - Printing System Management</A></B>
+<UL>
+<LI><A HREF="#7_1">The Basics</A></LI>
+<LI><A HREF="#RESTARTING">Restarting the CUPS Server</A></LI>
+<LI><A HREF="#7_3">Changing the Server Configuration</A></LI>
+<LI><A HREF="#7_4">Server Directives</A></LI>
+<UL>
+<LI><A HREF="#AccessLog">AccessLog</A></LI>
+<LI><A HREF="#Allow">Allow</A></LI>
+<LI><A HREF="#AuthClass">AuthClass</A></LI>
+<LI><A HREF="#AuthGroupName">AuthGroupName</A></LI>
+<LI><A HREF="#AuthType">AuthType</A></LI>
+<LI><A HREF="#AutoPurgeJobs">AutoPurgeJobs</A></LI>
+<LI><A HREF="#BrowseAddress">BrowseAddress</A></LI>
+<LI><A HREF="#BrowseAllow">BrowseAllow</A></LI>
+<LI><A HREF="#BrowseDeny">BrowseDeny</A></LI>
+<LI><A HREF="#BrowseOrder">BrowseOrder</A></LI>
+<LI><A HREF="#BrowseInterval">BrowseInterval</A></LI>
+<LI><A HREF="#BrowsePoll">BrowsePoll</A></LI>
+<LI><A HREF="#BrowsePort">BrowsePort</A></LI>
+<LI><A HREF="#BrowseProtocols">BrowseProtocols</A></LI>
+<LI><A HREF="#BrowseRelay">BrowseRelay</A></LI>
+<LI><A HREF="#BrowseShortNames">BrowseShortNames</A></LI>
+<LI><A HREF="#BrowseTimeout">BrowseTimeout</A></LI>
+<LI><A HREF="#Browsing">Browsing</A></LI>
+<LI><A HREF="#Classification">Classification</A></LI>
+<LI><A HREF="#ClassifyOverride">ClassifyOverride</A></LI>
+<LI><A HREF="#ConfigFilePerm">ConfigFilePerm</A></LI>
+<LI><A HREF="#DataDir">DataDir</A></LI>
+<LI><A HREF="#DefaultCharset">DefaultCharset</A></LI>
+<LI><A HREF="#DefaultLanguage">DefaultLanguage</A></LI>
+<LI><A HREF="#Deny">Deny</A></LI>
+<LI><A HREF="#DocumentRoot">DocumentRoot</A></LI>
+<LI><A HREF="#Encryption">Encryption</A></LI>
+<LI><A HREF="#ErrorLog">ErrorLog</A></LI>
+<LI><A HREF="#FilterLimit">FilterLimit</A></LI>
+<LI><A HREF="#FontPath">FontPath</A></LI>
+<LI><A HREF="#Group">Group</A></LI>
+<LI><A HREF="#HideImplicitMembers">HideImplicitMembers</A></LI>
+<LI><A HREF="#HostNameLookups">HostNameLookups</A></LI>
+<LI><A HREF="#ImplicitClasses">ImplicitClasses</A></LI>
+<LI><A HREF="#ImplicitAnyClasses">ImplicitAnyClasses</A></LI>
+<LI><A HREF="#Include">Include</A></LI>
+<LI><A HREF="#KeepAlive">KeepAlive</A></LI>
+<LI><A HREF="#KeepAliveTimeout">KeepAliveTimeout</A></LI>
+<LI><A HREF="#Limit">Limit</A></LI>
+<LI><A HREF="#LimitExcept">LimitExcept</A></LI>
+<LI><A HREF="#LimitRequestBody">LimitRequestBody</A></LI>
+<LI><A HREF="#Listen">Listen</A></LI>
+<LI><A HREF="#Location">Location</A></LI>
+<LI><A HREF="#LogFilePerm">LogFilePerm</A></LI>
+<LI><A HREF="#LogLevel">LogLevel</A></LI>
+<LI><A HREF="#MaxClients">MaxClients</A></LI>
+<LI><A HREF="#MaxJobs">MaxJobs</A></LI>
+<LI><A HREF="#MaxJobsPerPrinter">MaxJobsPerPrinter</A></LI>
+<LI><A HREF="#MaxJobsPerUser">MaxJobsPerUser</A></LI>
+<LI><A HREF="#MaxLogSize">MaxLogSize</A></LI>
+<LI><A HREF="#MaxRequestSize">MaxRequestSize</A></LI>
+<LI><A HREF="#Order">Order</A></LI>
+<LI><A HREF="#PageLog">PageLog</A></LI>
+<LI><A HREF="#Port">Port</A></LI>
+<LI><A HREF="#PreserveJobHistory">PreserveJobHistory</A></LI>
+<LI><A HREF="#PreserveJobFiles">PreserveJobFiles</A></LI>
+<LI><A HREF="#Printcap">Printcap</A></LI>
+<LI><A HREF="#PrintcapFormat">PrintcapFormat</A></LI>
+<LI><A HREF="#PrintcapGUI">PrintcapGUI</A></LI>
+<LI><A HREF="#RemoteRoot">RemoteRoot</A></LI>
+<LI><A HREF="#RequestRoot">RequestRoot</A></LI>
+<LI><A HREF="#Require">Require</A></LI>
+<LI><A HREF="#RIPCache">RIPCache</A></LI>
+<LI><A HREF="#RunAsUser">RunAsUser</A></LI>
+<LI><A HREF="#Satisfy">Satisfy</A></LI>
+<LI><A HREF="#ServerAdmin">ServerAdmin</A></LI>
+<LI><A HREF="#ServerBin">ServerBin</A></LI>
+<LI><A HREF="#ServerCertificate">ServerCertificate</A></LI>
+<LI><A HREF="#ServerKey">ServerKey</A></LI>
+<LI><A HREF="#ServerName">ServerName</A></LI>
+<LI><A HREF="#ServerRoot">ServerRoot</A></LI>
+<LI><A HREF="#SSLListen">SSLListen</A></LI>
+<LI><A HREF="#SSLPort">SSLPort</A></LI>
+<LI><A HREF="#SystemGroup">SystemGroup</A></LI>
+<LI><A HREF="#TempDir">TempDir</A></LI>
+<LI><A HREF="#Timeout">Timeout</A></LI>
+<LI><A HREF="#User">User</A></LI>
+</UL>
+<LI><A HREF="#PRINTING_SECURITY">Printing System Security</A></LI>
+<UL>
+<LI><A HREF="#CERTIFICATES">Authentication Using Certificates</A></LI>
+<LI><A HREF="#7_5_2">Using Basic Authentication</A></LI>
+<LI><A HREF="#7_5_3">Using Digest Authentication</A></LI>
+<LI><A HREF="#7_5_4">System and Group Authentication</A></LI>
+</UL>
+<LI><A HREF="#PRINTER_ACCOUNTING">Printer Accounting</A></LI>
+<UL>
+<LI><A HREF="#7_6_1">The access_log File</A></LI>
+<LI><A HREF="#7_6_2">The error_log File</A></LI>
+<LI><A HREF="#7_6_3">The page_log File</A></LI>
+</UL>
+<LI><A HREF="#FILE_TYPING_FILTERING">File Typing and Filtering</A></LI>
+<UL>
+<LI><A HREF="#7_7_1">mime.types</A></LI>
+<LI><A HREF="#7_7_2">mime.convs</A></LI>
+<LI><A HREF="#7_7_3">Adding Filetypes and Filters</A></LI>
+<LI><A HREF="#7_7_4">Printer Drivers and PPD Files</A></LI>
+<LI><A HREF="#7_7_5">Writing Your Own Filter or Printer Driver</A></LI>
+</UL>
+</UL>
+<B><A HREF="#PRINTING_OTHER">7 - Printing with Other Systems</A></B>
+<UL>
+<LI><A HREF="#8_1">The Basics</A></LI>
+<LI><A HREF="#8_2">Printing from LPD Clients</A></LI>
+<LI><A HREF="#8_3">Printing to LPD Servers</A></LI>
+<LI><A HREF="#8_4">Printing from Mac OS Clients</A></LI>
+<UL>
+<LI><A HREF="#8_4_1">Columbia Appletalk Package (CAP)</A></LI>
+<LI><A HREF="#8_4_2">XINET KA/Spool</A></LI>
+<LI><A HREF="#8_4_3">NetATalk</A></LI>
+</UL>
+<LI><A HREF="#8_5">Printing to Mac OS Servers</A></LI>
+<LI><A HREF="#8_6">Printing from Windows Clients</A></LI>
+<UL>
+<LI><A HREF="#8_6_1">Exporting Printer Drivers</A></LI>
+</UL>
+<LI><A HREF="#8_7">Printing to Windows Servers</A></LI>
+</UL>
+<B><A HREF="#LICENSE">A - Software License Agreement</A></B>
+<UL>
+<LI><A HREF="#9_1">Common UNIX Printing System License Agreement</A></LI>
+<UL>
+<LI><A HREF="#9_1_1">Introduction</A></LI>
+<LI><A HREF="#9_1_2">License Exceptions</A></LI>
+<LI><A HREF="#9_1_3">Trademarks</A></LI>
+<LI><A HREF="#9_1_4">Binary Distribution Rights</A></LI>
+<LI><A HREF="#9_1_5">Support</A></LI>
+</UL>
+<LI><A HREF="#9_2">GNU GENERAL PUBLIC LICENSE</A></LI>
+<LI><A HREF="#9_3">GNU LIBRARY GENERAL PUBLIC LICENSE</A></LI>
+</UL>
+<B><A HREF="#COMMON_NETWORK">B - Common Network Settings</A></B>
+<UL>
+<LI><A HREF="#10_1">Configuring a Network Interface</A></LI>
+<UL>
+<LI><A HREF="#10_1_1">Configuring the IP Address Using ARP</A></LI>
+<LI><A HREF="#10_1_2">Configuring the IP Address Using RARP</A></LI>
+<LI><A HREF="#10_1_3">Configuring the IP Address Using BOOTP</A></LI>
+</UL>
+<LI><A HREF="#10_2">Verifying the Printer Connection</A></LI>
+<LI><A HREF="#10_3">Common Network Interface Settings</A></LI>
+<LI><A HREF="#AXIS">Configuring Axis Print Servers</A></LI>
+<LI><A HREF="#LINKSYS">Configuring Linksys Print Servers</A></LI>
+</UL>
+<B><A HREF="#PRINTER_DRIVERS">C - Printer Drivers</A></B>
+<UL>
+<LI><A HREF="#11_1">Printer Drivers</A></LI>
+<LI><A HREF="#EPSON9">EPSON 9-pin Dot Matrix</A></LI>
+<LI><A HREF="#EPSON24">EPSON 24-pin Dot Matrix</A></LI>
+<LI><A HREF="#STCOLOR">EPSON Stylus Color</A></LI>
+<LI><A HREF="#STPHOTO">EPSON Stylus Photo</A></LI>
+<LI><A HREF="#DESKJET">HP DeskJet</A></LI>
+<LI><A HREF="#LASERJET">HP LaserJet</A></LI>
+</UL>
+<B><A HREF="#FILES">D - List of Files</A></B>
+<BR>
+<BR><B><A HREF="#FAQ">E - Troubleshooting Common Problems</A></B>
+<UL>
+<LI><A HREF="#13_1">My Applications Don't See the Available Printers</A></LI>
+<LI><A HREF="#13_2">CUPS Doesn't Recognize My Username or Password!</A></LI>
+<LI><A HREF="#ALLOW_REMOTE">I Can't Do Administration Tasks from Another
+ Machine!</A></LI>
+<LI><A HREF="#13_4">I Can't Do Administration Tasks from My Web Browser!</A>
+</LI>
+<LI><A HREF="#13_5">Connection Refused Messages</A></LI>
+<LI><A HREF="#13_6">Write Error Messages</A></LI>
+</UL>
+<HR>
+<H1 ALIGN="RIGHT"><A NAME="1">Preface</A></H1>
+<P>This software administrators manual provides printer administration
+ information for the Common UNIX Printing System<SUP>TM</SUP> (&quot;CUPS<SUP>
+TM</SUP>&quot;), version 1.1.15.</P>
+<H2><A NAME="1_1">System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+
+<!-- NEED 3in -->
+<H2><A NAME="1_2">Document Overview</A></H2>
+<P>This software administrators manual is organized into the following
+ sections:</P>
+<UL>
+<LI><A HREF="#OVERVIEW">1 - Printing System Overview</A></LI>
+<LI><A HREF="#BUILDING_INSTALLING">2 - Building and Installing CUPS</A></LI>
+<LI><A HREF="#MANAGING_PRINTERS">3 - Managing Printers</A></LI>
+<LI><A HREF="#PRINTER_CLASSES">4 - Printer Classes</A></LI>
+<LI><A HREF="#CLIENT_SETUP">5 - Client Setup</A></LI>
+<LI><A HREF="#PRINTING_MANAGEMENT">6 - Printing System Management</A></LI>
+<LI><A HREF="#PRINTING_OTHER">7 - Printing with Other Systems</A></LI>
+<LI><A HREF="#LICENSE">A - Software License Agreement</A></LI>
+<LI><A HREF="#COMMON_NETWORK">B - Common Network Settings</A></LI>
+<LI><A HREF="#PRINTER_DRIVERS">C - Printer Drivers</A></LI>
+<LI><A HREF="#FILES">D - List of Files</A></LI>
+<LI><A HREF="#FAQ">E - Troubleshooting Common Problems</A></LI>
+</UL>
+<H2><A NAME="1_3">Notation Conventions</A></H2>
+<P>Various font and syntax conventions are used in this guide. Examples
+ and their meanings and uses are explained below:
+<CENTER>
+<TABLE WIDTH="80%">
+<TR><TH>Example</TH><TD>&nbsp;&nbsp;&nbsp;</TD><TH>Description</TH></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD><CODE>lpstat</CODE>
+<BR> <CODE>lpstat(1)</CODE></TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>The names of commands;
+ the first mention of a command or function in a chapter is followed by
+ a manual page section number.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD><VAR>/var</VAR>
+<BR><VAR> /usr/share/cups/data/testprint.ps</VAR></TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>
+File and directory names.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD NOWRAP><TT>Request ID is Printer-123</TT></TD><TD>
+&nbsp;&nbsp;&nbsp;</TD><TD>Screen output.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD NOWRAP><KBD>lp -d printer filename ENTER</KBD></TD><TD>
+&nbsp;&nbsp;&nbsp;</TD><TD>Literal user input; special keys like <KBD>ENTER</KBD> are
+ in ALL CAPS.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD>12.3</TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>Numbers in the text are
+ written using the period (.) to indicate the decimal point.</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+</P>
+<H2><A NAME="1_4">Abbreviations</A></H2>
+ The following abbreviations are used throughout this manual:
+<UL>
+<DL>
+<DT>kb</DT>
+<DD>Kilobytes, or 1024 bytes
+<BR>&nbsp;</DD>
+<DT>Mb</DT>
+<DD>Megabytes, or 1048576 bytes
+<BR>&nbsp;</DD>
+<DT>Gb</DT>
+<DD>Gigabytes, or 1073741824 bytes
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H2><A NAME="1_5">Other References</A></H2>
+<UL>
+<DL>
+<DT>CUPS Software Programmers Manual</DT>
+<DD>A programmer guide for interfacing with and/or extending the CUPS
+ software.
+<BR>&nbsp;</DD>
+<DT>CUPS Software Users Manual</DT>
+<DD>An end-user guide for using the CUPS software.
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H1 ALIGN="RIGHT"><A NAME="OVERVIEW">1 - Printing System Overview</A></H1>
+<P>This chapter provides an overview of how the Common UNIX Printing
+ System works.</P>
+<H2><A NAME="2_1">The Printing Problem</A></H2>
+<P>For years<I> the printing problem</I> has plagued UNIX. Unlike
+ Microsoft&reg; Windows&reg; or Mac OS, UNIX has no standard interface or system
+ in place for supporting printers. Among the solutions currently
+ available, the Berkeley and System V printing systems are the most
+ prevalent.</P>
+<P>These printing systems support line printers (text only) or
+ PostScript printers (text and graphics), and with some coaxing they can
+ be made to support a full range of printers and file formats. However,
+ because each varient of the UNIX operating system uses a different
+ printing system than the next developing printer drivers for a wide
+ range of printers and operating systems is extremely difficult. That
+ combined with the limited volume of customers for each UNIX varient has
+ forced most printer vendors to give up supporting UNIX entirely.</P>
+<P>CUPS is designed to eliminate<I> the printing problem</I>. One common
+ printing system can be used by all UNIX varients to support the
+ printing needs of users. Printer vendors can use its modular filter
+ interface to develop a single driver program that supports a wide range
+ of file formats with little or no effort. Since CUPS provides both the
+ System V and Berkeley printing commands, users (and applications) can
+ reap the benefits of this new technology with no changes.</P>
+<H2><A NAME="2_2">The Technology</A></H2>
+<P>CUPS is based upon an emerging Internet standard called the Internet
+ Printing Protocol. IPP has been embraced by dozens of printer and
+ printer server manufacturers and is supported by Microsoft Windows
+ 2000.</P>
+<P>IPP defines a standard protocol for printing as well as managing
+ print jobs and printer options like media size, resolution, and so
+ forth. Like all IP-based protocols, IPP can be used locally or over the
+ Internet to printers hundreds or thousands of miles away. Unlike other
+ protocols, however, IPP also supports access control, authentication,
+ and encryption, making it a much more capable and secure printing
+ solution than older ones.</P>
+<P>IPP is layered on top of the Hyper-Text Transport Protocol (&quot;HTTP&quot;)
+ which is the basis of web servers on the Internet. This allows users to
+ view documentation, check status information on a printer or server,
+ and manage their printers, classes, and jobs using their web browser.</P>
+<P>CUPS provides a complete IPP/1.1 based printing system that provides
+ Basic, Digest, and local certificate authentication and user, domain,
+ or IP-based access control. TLS encryption will be available in future
+ versions of CUPS.</P>
+<H2><A NAME="2_3">Jobs</A></H2>
+<P>Each file or set of files that is submitted for printing is called a<I>
+ job</I>. Jobs are identified by a unique number starting at 1 and are
+ assigned to a particular destination, usually a printer. Jobs can also
+ have options associated with them such as media size, number of copies,
+ and priority.</P>
+<H2><A NAME="2_4">Classes</A></H2>
+<P>CUPS supports collections of printers known as<I> classes</I>. Jobs
+ sent to a class are forwarded to the first available printer in the
+ class.</P>
+<H2><A NAME="2_5">Filters</A></H2>
+<P>Filters allow a user or application to print many types of files
+ without extra effort. Print jobs sent to a CUPS server are filtered
+ before sending them to a printer. Some filters convert job files to
+ different formats that the printer can understand. Others perform page
+ selection and ordering tasks.</P>
+<P>CUPS provides filters for printing many types of image files, HP-GL/2
+ files, PDF files, and text files. CUPS also supplies PostScript and
+ image file Raster Image Processor (&quot;RIP&quot;) filters that convert
+ PostScript or image files into bitmaps that can be sent to a raster
+ printer.</P>
+<H2><A NAME="2_6">Backends</A></H2>
+<P>Backends perform the most important task of all - they send the
+ filtered print data to the printer.</P>
+<P>CUPS provides backends for printing over parallel, serial, and USB
+ ports, and over the network via the IPP, JetDirect (AppSocket), and
+ Line Printer Daemon (&quot;LPD&quot;) protocols. Additional backends are
+ available in network service packages such as the SMB backend included
+ with the popular SAMBA software.</P>
+<P>Backends are also used to determine the available devices. On startup
+ each backend is asked for a list of devices it supports, and any
+ information that is available. This allows the parallel backend to tell
+ CUPS that an EPSON Stylus Color 600 printer is attached to parallel
+ port 1, for example.</P>
+<H2><A NAME="2_7">Printer Drivers</A></H2>
+<P>Printer drivers in CUPS consist of one of more filters specific to a
+ printer. CUPS includes sample printer drivers for Hewlett-Packard
+ LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color,
+ and Stylus Photo printers. While these drivers do not generate optimal
+ output for the different printer models, they do provide basic printing
+ and demonstrate how you can write your own printer drivers and
+ incorporate them into CUPS.</P>
+<H2><A NAME="2_8">Networking</A></H2>
+<P>Printers and classes on the local system are automatically shared
+ with other systems on the network. This allows you to setup one system
+ to print to a printer and use this system as a printer server or spool
+ host for all of the others. Users may then select a local printer by
+ name or a remote printer using &quot;name@server&quot;.</P>
+<P>CUPS also provides<I> implicit classes</I>, which are collections of
+ printers and/or classes with the same name. This allows you to setup
+ multiple servers pointing to the same physical network printer, for
+ example, so that you aren't relying on a single system for printing.
+ Because this also works with printer classes, you can setup multiple
+ servers and printers and never worry about a single point of failure
+ unless all of the printers and servers go down!</P>
+<H1 ALIGN="RIGHT"><A NAME="BUILDING_INSTALLING">2 - Building and
+ Installing CUPS</A></H1>
+<P>This chapter shows how to build and install the Common UNIX Printing
+ System. If you are installing a binary distribution from the CUPS web
+ site, proceed to the section titled,<A HREF="#BINARY"> Installing a
+ Binary Distribution</A>.</P>
+<H2><A NAME="3_1">Installing a Source Distribution</A></H2>
+<P>This section describes how to compile and install CUPS on your system
+ from the source code.</P>
+<H3><A NAME="REQUIREMENTS">Requirements</A></H3>
+<P>You'll need ANSI-compliant C and C++ compilers to build CUPS on your
+ system. As its name implies, CUPS is designed to run on the UNIX
+ operating system, however the CUPS interface library and most of the
+ filters and backends supplied with CUPS should also compile and run
+ under Microsoft Windows.</P>
+<P>For the image file filters and PostScript RIP, you'll need the JPEG,
+ PNG, TIFF, and ZLIB libraries. CUPS will build without these, but with
+ significantly reduced functionality. Easy Software Products maintains a
+ mirror of the current versions of these libraries at:</P>
+<UL>
+<PRE>
+<A HREF="ftp://ftp.easysw.com/pub/libraries">ftp://ftp.easysw.com/pub/libraries</A>
+</PRE>
+</UL>
+<P>If you make changes to the man pages you'll need GNU groff or another
+ nroff-like package. GNU groff is available from:</P>
+<UL>
+<PRE>
+<A HREF="ftp://ftp.gnu.org/pub/groff">ftp://ftp.gnu.org/pub/groff</A>
+</PRE>
+</UL>
+<P>The documentation is formatted using the HTMLDOC software. If you
+ need to make changes you can get the HTMLDOC software from:</P>
+<UL>
+<PRE>
+<A HREF="http://www.easysw.com/htmldoc">http://www.easysw.com/htmldoc</A>
+</PRE>
+</UL>
+<P>Finally, you'll need a <CODE>make</CODE> program that understands the
+ <CODE>include</CODE> directive - FreeBSD, NetBSD, and OpenBSD
+ developers should use the <CODE>gmake</CODE> program.</P>
+<H3><A NAME="COMPILING">Compiling CUPS</A></H3>
+<P>CUPS uses GNU autoconf to configure the makefiles and source code for
+ your system. Type the following command to configure CUPS for your
+ system:</P>
+<UL>
+<PRE>
+<B>./configure ENTER</B>
+</PRE>
+</UL>
+<P>The default installation will put the CUPS software in the<VAR> /etc</VAR>
+,<VAR> /usr</VAR>, and<VAR> /var</VAR> directories on your system, which
+ will overwrite any existing printing commands on your system. Use the <CODE>
+--prefix</CODE> option to install the CUPS software in another location:</P>
+<UL>
+<PRE>
+<B>./configure --prefix=/some/directory ENTER</B>
+</PRE>
+</UL>
+<P>If the PNG, JPEG, TIFF, and ZLIB libraries are not installed in a
+ system default location (typically<VAR> /usr/include</VAR> and<VAR>
+ /usr/lib</VAR>) you'll need to set the <CODE>CFLAGS</CODE>, <CODE>
+CXXFLAGS</CODE>, and <CODE>LDFLAGS</CODE> environment variables prior to
+ running configure:</P>
+<UL>
+<PRE>
+<B>setenv CFLAGS &quot;-I/some/directory&quot; ENTER</B>
+<B>setenv CXXFLAGS &quot;-I/some/directory&quot; ENTER</B>
+<B>setenv LDFLAGS &quot;-L/some/directory&quot; ENTER</B>
+<B>setenv DSOFLAGS &quot;-L/some/directory&quot; ENTER</B>
+<B>./configure ... ENTER</B>
+</PRE>
+</UL>
+<P>or:</P>
+<UL>
+<PRE>
+<B>CFLAGS=&quot;-I/some/directory&quot;; export CFLAGS ENTER</B>
+<B>CXXFLAGS=&quot;-I/some/directory&quot;; export CXXFLAGS ENTER</B>
+<B>LDFLAGS=&quot;-L/some/directory&quot;; export LDFLAGS ENTER</B>
+<B>DSOFLAGS=&quot;-L/some/directory&quot;; export DSOFLAGS ENTER</B>
+<B>./configure ... ENTER</B>
+</PRE>
+</UL>
+<P>To enable support for encryption, you'll also want to add the
+ &quot;--enable-ssl&quot; option:</P>
+<UL>
+<PRE>
+./configure --enable-ssl
+</PRE>
+</UL>
+<P>SSL and TLS support require the OpenSSL library, available at:</P>
+<UL>
+<PRE>
+<A HREF="http://www.openssl.org">http://www.openssl.org</A>
+</PRE>
+</UL>
+<P>If the OpenSSL headers and libraries are not installed in the
+ standard directories, use the <CODE>--with-openssl-includes</CODE> and <CODE>
+--with-openssl-libs</CODE> options:</P>
+<UL>
+<PRE>
+./configure --enable-ssl \
+ --with-openssl-includes=/foo/bar/include \
+ --with-openssl-libs=/foo/bar/lib
+</PRE>
+</UL>
+<P>Once you have configured things, just type:</P>
+<UL>
+<PRE>
+<B>make ENTER</B>
+</PRE>
+</UL>
+<P>to build the software.
+<!-- NEED 4in -->
+</P>
+<H3><A NAME="INSTALLING">Installing the Software</A></H3>
+<P>Use the &quot;install&quot; target to install the software:</P>
+<UL>
+<PRE>
+<B>make install ENTER</B>
+</PRE>
+</UL>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> WARNING:</B>
+<P>Installing CUPS will overwrite your existing printing system. If you
+ experience difficulties with the CUPS software and need to go back to
+ your old printing system, you will need to reinstall the old printing
+ system from your operating system CDs.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="RUNNING">Running the Software</A></H3>
+<P>Once you have installed the software you can start the CUPS server by
+ typing:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/cupsd ENTER</B>
+</PRE>
+</UL>
+
+<!-- NEED 4in -->
+<H2><A NAME="BINARY">Installing a Binary Distribution</A></H2>
+<P>CUPS comes in a variety of binary distribution formats. Easy Software
+ Products provides binaries in TAR format with installation and removal
+ scripts (&quot;portable&quot; distributions), and in RPM and DPKG formats for Red
+ Hat and Debian-based distributions. Portable distributions are
+ available for all platforms, while the RPM and DPKG distributions are
+ only available for Linux.
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> WARNING:</B>
+<P>Installing CUPS will overwrite your existing printing system. If you
+ experience difficulties with the CUPS software and need to go back to
+ your old printing system, you will need to remove the CUPS software
+ with the provided script and/or reinstall the old printing system from
+ your operating system CDs.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="PORTABLE-BINARY">Installing a Portable Distribution</A></H3>
+<P>To install the CUPS software from a portable distribution you will
+ need to be logged in as root; doing an <CODE>su</CODE> is good enough.
+ Once you are the root user, run the installation script with:</P>
+<UL>
+<PRE>
+<B>./cups.install ENTER</B>
+</PRE>
+</UL>
+<P>After asking you a few yes/no questions the CUPS software will be
+ installed and the scheduler will be started automatically.
+<!-- NEED 2in -->
+</P>
+<H3><A NAME="RPM-BINARY">Installing an RPM Distribution</A></H3>
+<P>To install the CUPS software from an RPM distribution you will need
+ to be logged in as root; doing an <CODE>su</CODE> is good enough. Once
+ you are the root user, run RPM with:</P>
+<UL>
+<PRE>
+<B>rpm -e lpr</B>
+<B>rpm -i cups-1.1-linux-M.m.n-intel.rpm ENTER</B>
+</PRE>
+</UL>
+<P>After a short delay the CUPS software will be installed and the
+ scheduler will be started automatically.</P>
+<H3><A NAME="DPKG-BINARY">Installing an Debian Distribution</A></H3>
+<P>To install the CUPS software from a Debian distribution you will need
+ to be logged in as root; doing an <CODE>su</CODE> is good enough. Once
+ you are the root user, run dpkg with:</P>
+<UL>
+<PRE>
+<B>dpkg -i cups-1.1-linux-M.m.n-intel.deb ENTER</B>
+</PRE>
+</UL>
+<P>After a short delay the CUPS software will be installed and the
+ scheduler will be started automatically.</P>
+<H1 ALIGN="RIGHT"><A NAME="MANAGING_PRINTERS">3 - Managing Printers</A></H1>
+<P>This chapter describes how to add your first printer and how to
+ manage your printers.</P>
+<H2><A NAME="4_1">The Basics</A></H2>
+<P>Each printer queue has a name associated with it; the printer name
+ must start with a letter and can contain up to 127 letters, numbers,
+ and the underscore (_). Case is not significant, e.g. &quot;PRINTER&quot;,
+ &quot;Printer&quot;, and &quot;printer&quot; are considered to be the same name.</P>
+<P>Printer queues also have a device associated with them. The device
+ can be a parallel port, a network interface, and so forth. Devices
+ within CUPS use Uniform Resource Identifiers (&quot;URIs&quot;) which are a more
+ general form of Uniform Resource Locators (&quot;URLs&quot;) that are used in
+ your web browser. For example, the first parallel port in Linux usually
+ uses a device URI of <CODE>parallel:/dev/lp1</CODE>.
+<!-- NEED 2.5in -->
+</P>
+<P>You can see a complete list of supported devices by running the <CODE>
+lpinfo(8)</CODE> command:</P>
+<UL>
+<PRE>
+<B>lpinfo -v ENTER</B>
+file file
+network socket
+network http
+network ipp
+network lpd
+direct parallel:/dev/lp1
+serial serial:/dev/ttyS1?baud=115200
+serial serial:/dev/ttyS2?baud=115200
+direct usb:/dev/usb/lp0
+network smb
+</PRE>
+</UL>
+<P>The <CODE>-v</CODE> option specifies that you want a list of
+ available devices. The first word in each line is the type of device
+ (direct, file, network, or serial) and is followed by the device URI or
+ method name for that device. File devices have device URIs of the form <CODE>
+file:/directory/filename</CODE> while network devices use the more
+ familiar <CODE>method://server</CODE> or <CODE>method://server/path</CODE>
+ format.</P>
+<P>Finally, printer queues usually have a PostScript Printer Description
+ (&quot;PPD&quot;) file associated with them. PPD files describe the capabilities
+ of each printer, the page sizes supported, etc., and are used for
+ PostScript and non-PostScript printers. CUPS includes PPD files for HP
+ LaserJet, HP DeskJet, EPSON 9-pin, EPSON 24-pin, and EPSON Stylus
+ printers.</P>
+<H2><A NAME="4_2">Adding Your First Printer</A></H2>
+<P>CUPS provides two methods for adding printers: a command-line program
+ called <CODE>lpadmin(8)</CODE> and a Web interface. The <CODE>lpadmin</CODE>
+ command allows you to perform most printer administration tasks from
+ the command-line and is located in<VAR> /usr/sbin</VAR>. The Web
+ interface is located at:</P>
+<UL>
+<PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE>
+</UL>
+<P>and steps you through printer configuration. If you don't like
+ command-line interfaces, try the<A HREF="#ADD_WEB"> Web interface</A>
+ instead.</P>
+<H3><A NAME="4_2_1">Adding Your First Printer from the Command-Line</A></H3>
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> option
+ to add a printer to CUPS:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -E -v <I>device</I> -m <I>ppd</I> ENTER</B>
+</PRE>
+</UL>
+<P>For a HP DeskJet printer connected to the parallel port this would
+ look like:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p DeskJet -E -v parallel:/dev/lp1 -m deskjet.ppd ENTER</B>
+</PRE>
+</UL>
+<P>Similarly, a HP LaserJet printer using a JetDirect network interface
+ at IP address 11.22.33.44 would be added with the command:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p LaserJet -E -v socket://11.22.33.44 -m laserjet.ppd ENTER</B>
+</PRE>
+</UL>
+<P>As you can see, <CODE>deskjet.ppd</CODE> and <CODE>laserjet.ppd</CODE>
+ are the PPD files for the HP DeskJet and HP LaserJet drivers included
+ with CUPS. You'll find a complete list of PPD files and the printers
+ they will work with in<A HREF="#PRINTER_DRIVERS"> Appendix C, &quot;Printer
+ Drivers&quot;</A>.</P>
+<P>For a dot matrix printer connected to the serial port this would
+ might look like:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p DotMatrix -E -v serial:/dev/ttyS0?baud=9600+size=8+parity=none+flow=soft deskjet.ppd ENTER</B>
+</PRE>
+</UL>
+<P>Here you specify the serial port (e.g. S0,S1, d0, d1), baud rate
+ (e.g. 9600, 19200, 38400, 115200, etc.), number of bits, parity, and
+ flow control. If you do not need flow control, delete the &quot;+flow=soft&quot;
+ portion.</P>
+<H3><A NAME="ADD_WEB">Adding Your First Printer from the Web</A></H3>
+<P>The CUPS web server provides a user-friendly &quot;wizard&quot; interface for
+ adding your printers. Rather than figuring out which device URI and PPD
+ file to use, you can instead click on the appropriate listings and fill
+ in some simple information. Enter the following URL in your web browser
+ to begin:</P>
+<UL>
+<PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE>
+</UL>
+<P>Click on the<VAR> Add Printer</VAR> button to add a printer.</P>
+<H2><A NAME="4_3">Managing Printers from the Command-Line</A></H2>
+<P>The <CODE>lpadmin</CODE> command enables you to perform most printer
+ administration tasks from the command-line. You'll find <CODE>lpadmin</CODE>
+ in the<VAR> /usr/sbin</VAR> directory.</P>
+<H3><A NAME="4_3_1">Adding and Modifying Printers</A></H3>
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> option
+ to add or modify a printer:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> <I>options</I> ENTER</B>
+</PRE>
+</UL>
+<P>The<I> options</I> arguments can be any of the following:</P>
+<UL>
+<DL>
+<DT>-c<I> class</I></DT>
+<DD>Adds the named printer to printer class<VAR> class</VAR>. If the
+ class does not exist then it is created.</DD>
+<DT>-i<I> interface</I></DT>
+<DD>Copies the named<VAR> interface</VAR> script to the printer.
+ Interface scripts are used by System V printer drivers. Since all
+ filtering is disabled when using an interface script, scripts generally
+ should not be used unless there is no other driver for a printer.</DD>
+<DT>-m<I> model</I></DT>
+<DD>Specifies a standard printer driver which is usually a PPD file. A
+ list of all available models can be displayed using the <CODE>lpinfo</CODE>
+ command with the <CODE>-m</CODE> option. A list of printer drivers
+ included with CUPS can be found in<A HREF="#PRINTER_DRIVERS"> Appendix
+ C, &quot;Printer Drivers&quot;</A>.</DD>
+<DT>-r<I> class</I></DT>
+<DD>Removes the named printer from printer class<VAR> class. If the
+ resulting class becomes empty then it is removed.</VAR></DD>
+<DT>-v<I> device-uri</I></DT>
+<DD>Sets the device for communicating with the printer. If a job is
+ currently printing on the named printer then the job will be restarted
+ and sent to the new device.</DD>
+<DT>-D<I> info</I></DT>
+<DD>Provides a textual description of the printer, e.g. &quot;John's Personal
+ Printer&quot;.</DD>
+<DT>-E</DT>
+<DD>Enables the printer and accepts job. This option is equivalent to
+ running the <CODE>enable(1)</CODE> and <CODE>accept(8)</CODE> commands
+ on the printer.</DD>
+<DT>-L<I> location</I></DT>
+<DD>Provides a textual location for the printer, e.g. &quot;Computer Lab 5&quot;.</DD>
+<DT>-P<I> ppd-file</I></DT>
+<DD>Specifies a local PPD file for the printer driver.</DD>
+</DL>
+</UL>
+<H3><A NAME="4_3_2">Deleting Printers</A></H3>
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-x</CODE> option
+ to delete a printer:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -x <I>printer</I> ENTER</B>
+</PRE>
+</UL>
+<H3><A NAME="4_3_3">Setting the Default Printer</A></H3>
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-d</CODE> option
+ to set a default printer:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -d <I>printer</I> ENTER</B>
+</PRE>
+</UL>
+<P>The default printer can be overridden by the user using the <CODE>
+lpoptions(1)</CODE> command.</P>
+<H3><A NAME="4_3_4">Starting and Stopping Printers</A></H3>
+<P>The <CODE>enable</CODE> and <CODE>disable</CODE> commands start and
+ stop printer queues, respectively:</P>
+<UL>
+<PRE>
+<B>/usr/bin/enable <I>printer</I> ENTER</B>
+<B>/usr/bin/disable <I>printer</I> ENTER</B>
+</PRE>
+</UL>
+<P>Printers that are disabled may still accept jobs for printing, but
+ won't actually print any files until they are restarted. This is useful
+ if the printer malfunctions and you need time to correct the problem.
+ Any queued jobs are printed after the printer is enabled (started).</P>
+<H3><A NAME="4_3_5">Accepting and Rejecting Print Jobs</A></H3>
+<P>The <CODE>accept</CODE> and <CODE>reject</CODE> commands accept and
+ reject print jobs for the named printer, respectively:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/accept <I>printer</I> ENTER</B>
+<B>/usr/sbin/reject <I>printer</I> ENTER</B>
+</PRE>
+</UL>
+<P>As noted above, a printer can be stopped but accepting new print
+ jobs. A printer can also be rejecting new print jobs while it finishes
+ those that have been queued. This is useful for when you must perform
+ maintenance on the printer and will not have it available to users for
+ a long period of time.</P>
+<H3><A NAME="4_3_6">Setting Quotas on a Printer</A></H3>
+<P>CUPS supports page and size-based quotas for each printer. The quotas
+ are tracked individually for each user, but a single set of limits
+ applies to all users for a partiuclar printer. For example, you can
+ limit every user to 5 pages per day on an expensive printer, but you
+ cannot limit every user except Johnny.</P>
+<P>The<I> job-k-limit</I>,<I> job-page-limit</I>, and<I> job-quota-peiod</I>
+ options determine whether and how quotas are enforced for a printer.
+ The<I> job-quota-period</I> option determines the time interval for
+ quota tracking. The interval is expressed in seconds, so a day is
+ 86,400, a week is 604,800 and a month is 2,592,000 seconds. The<I>
+ job-k-limit</I> option specifies the job size limit in killobytes. The<I>
+ job-page-limit</I> option specifies the number of pages limit.</P>
+<P>For quotas to be enforced, the period and at least one of the limits
+ must be set to a non-zero value. The following options will enable
+ quotas:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -o job-quota-period=604800 -o job-k-limit=1024 <I>ENTER</I></B>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -o job-quota-period=604800 -o job-page-limit=100 <I>ENTER</I></B>
+</PRE>
+</UL>
+<P>Or, you can combine all three options on the same line.</P>
+<H3><A NAME="4_3_7">Restricting User Access to a Printer</A></H3>
+<P>The <CODE>-u</CODE> option of the <CODE>lpadmin</CODE> command
+ controls which users can print to a printer. The default configuration
+ allows all users to print to a printer:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u allow:all <I>ENTER</I></B>
+</PRE>
+</UL>
+<P>CUPS supports allow and deny lists so that you can specify a list of
+ users who are allowed to print or not allowed to print. Along with your
+ list of users, you can specify whether they are allowed or not allowed
+ to use the printer:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u allow:peter,paul,mary <I>ENTER</I></B>
+</PRE>
+</UL>
+<P>This command allows peter, paul, and mary to print to the named
+ printer, but all other users cannot print. The command:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u deny:peter,paul,mary <I>ENTER</I></B>
+</PRE>
+</UL>
+<P>has the opposite effect. All users except peter, paul, and mary will
+ be able to print to the named printer.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B>NOTE:</B>
+<P>The<I> allow</I> and<I> deny</I> options are not cummulative. That
+ is, you must provide the complete list of users to allow or deny each
+ time.</P>
+<P>Also, CUPS only maintains one list of users - the list can allow or
+ deny users from printing. If you specify an allow list and then specify
+ a deny list, the deny list will replace the allow list - only one list
+ is active at any time.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H2><A NAME="4_4">Managing Printers from the Web</A></H2>
+<P>The Web interface is located at:</P>
+<UL>
+<PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE>
+</UL>
+<P>From there you can perform all printer management tasks with a few
+ simple mouse clicks.</P>
+<H1 ALIGN="RIGHT"><A NAME="PRINTER_CLASSES">4 - Printer Classes</A></H1>
+<P>This chapter describes what printer classes are and how to manage
+ them.</P>
+<H2><A NAME="5_1">The Basics</A></H2>
+<P>CUPS provides collections of printers called<I> printer classes</I>.
+ Jobs sent to a class are forwarded to the first available printer in
+ the class. Classes can themselves be members of other classes, so it is
+ possible for you to define very large, distributed printer classes for
+ high-availability printing.</P>
+<P>CUPS also supports<I> implicit classes</I>. Implicit classes work
+ just like printer classes, but they are created automatically based
+ upon the available printers and classes on the network. This allows you
+ to setup multiple print servers with identical printer configurations
+ and have the client machines send their print jobs to the first
+ available server. If one or more servers go down, the jobs are
+ automatically redirected to the servers that are running, providing
+ fail-safe printing.</P>
+<H2><A NAME="5_2">Managing Printer Classes from the Command-Line</A></H2>
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> and <CODE>
+-c</CODE> options to add a printer to a class:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -c <I>class</I> ENTER</B>
+</PRE>
+</UL>
+<P>The<I> class</I> is created automatically if it doesn't exist. To
+ remove a printer from a class use the <CODE>-r</CODE> option:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -r <I>class</I> ENTER</B>
+</PRE>
+</UL>
+<P>To remove the entire class just use the <CODE>-x</CODE> option:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -x <I>class</I> ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="5_3">Managing Printer Classes from the Web Interface</A></H2>
+<P>The Web interface is located at:</P>
+<UL>
+<PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE>
+</UL>
+<P>The<VAR> Add Class</VAR> and<VAR> Modify Class</VAR> interfaces
+ provide a list of available printers; click on the printers of interest
+ to add them to the class.</P>
+<H2><A NAME="5_4">Implicit Classes</A></H2>
+<P>A noted earlier, implicit classes are created automatically from the
+ available network printers and classes. To disable this functionality,
+ set the<A HREF="#ImplicitClasses"> <CODE>ImplicitClasses</CODE></A>
+ directive to <CODE>Off</CODE> in the <CODE>cupsd.conf</CODE> file. You
+ will find more information on doing this in<A HREF="#PRINTING_MANAGEMENT">
+ Chapter 6, &quot;Printing System Management&quot;</A>.</P>
+<H1 ALIGN="RIGHT"><A NAME="CLIENT_SETUP">5 - Client Setup</A></H1>
+<P>This chapter discusses several ways to configure CUPS clients for
+ printing.</P>
+<H2><A NAME="6_1">The Basics</A></H2>
+<P>A client is any machine that sends print jobs to another machine for
+ final printing. Clients can also be servers if they communicate
+ directly with any printers of their own.</P>
+<P>CUPS supports several methods of configuring client machines:</P>
+<UL>
+<LI><A HREF="#CLIENT_MANUAL">Manual configuration of print queues.</A></LI>
+<LI><A HREF="#CLIENT_SERVER">Specifying a single server for printing.</A>
+</LI>
+<LI><A HREF="#CLIENT_AUTO">Automatic configuration of print queues.</A></LI>
+<LI><A HREF="#CLIENT_POLL">Specifying multiple servers for printing.</A></LI>
+<LI><A HREF="#CLIENT_RELAY">Relaying printers to other clients.</A></LI>
+</UL>
+<H3><A NAME="CLIENT_MANUAL">Manual Configuration of Print Queues</A></H3>
+<P>The most tedious method of configuring client machines is to
+ configure each remote queue by hand using the <CODE>lpadmin</CODE>
+ command:</P>
+<UL>
+<PRE>
+<B>lpadmin -p <I>printer</I> -E -v ipp://<I>server</I>/printers/<I>printer</I> ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>printer</CODE> name is the name of the printer on the
+ server machine. The <CODE>server</CODE> name is the hostname or IP
+ address of the server machine. Repeat the <CODE>lpadmin</CODE> command
+ for each remote printer you wish to use.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Manual configuration of print queues is not recommended for large
+ numbers of client machines because of the administration nightmare it
+ creates. For busy networks, consider subnetting groups of clients and
+ polling and relaying printer information instead.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="CLIENT_SERVER">Specifying a Single Server for Printing</A></H3>
+<P>CUPS can be configured to run without a local spooler and send all
+ jobs to a single server. However, if that server goes down then all
+ printing will be disabled. Use this configuration only as absolutely
+ needed.</P>
+<P>The default server is normally &quot;localhost&quot;. To override the default
+ server create a file named<VAR> /etc/cups/client.conf</VAR> and add a
+ line reading:</P>
+<UL>
+<PRE>
+ServerName <I>server</I>
+</PRE>
+</UL>
+<P>to the file. The<VAR> server</VAR> name can be the hostname or IP
+ address of the default server.</P>
+<P>The default server can also be customized on a per-user basis. To set
+ a user-specific server create a file named<VAR> ~/.cupsrc</VAR> and add
+ a line reading:</P>
+<UL>
+<PRE>
+ServerName <I>server</I>
+</PRE>
+</UL>
+<P>to the file. The<VAR> server</VAR> name can be the hostname or IP
+ address of the default server.</P>
+<H3><A NAME="CLIENT_AUTO">Automatic Configuration of Print Queues</A></H3>
+<P>CUPS supports automatic client configuration of printers on the same
+ subnet. To configure printers on the same subnet,<I> do nothing</I>.
+ Each client should see the available printers within 30 seconds
+ automatically. The printer and class lists are updated automatically as
+ printers and servers are added or removed.</P>
+<P>If you want to see printers on other subnets as well, use the<A HREF="#BrowsePoll">
+ <CODE>BrowsePoll</CODE></A> directive as described next.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>The<A HREF="#BrowseAddress"> <CODE>BrowseAddress</CODE></A> directive
+ enables broadcast traffic from your server. The default configuration
+ braodcasts printer information every 30 seconds. Although this printer
+ information does not use much bandwidth, typically about 80 bytes per
+ printer, it can add up with large numbers of servers and printers.</P>
+<P>Use the<A HREF="#BrowseInterval"> <CODE>BrowseInterval</CODE></A> and<A
+HREF="#BrowseTimeout"> <CODE>BrowseTimeout</CODE></A> directives to tune
+ the amount of data that is added to your network load. In addition,
+ subnets can be used to minimize the amount of traffic that is carried
+ by the &quot;backbone&quot; of your large network.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="CLIENT_POLL">Specifying Multiple Servers for Printing</A></H3>
+<P>If you have CUPS servers on different subnets, then you should
+ configure CUPS to poll those servers. Polling provides the benefits of
+ automatic configuration without significant configuration on the
+ clients, and multiple clients on the same subnet can share the same
+ configuration information.</P>
+<P>Polling is enabled by specifying one or more<A HREF="#BrowsePoll"> <CODE>
+BrowsePoll</CODE></A> directives in the<VAR> /etc/cups/cupsd.conf</VAR>
+ file. For information on making these changes, see<A HREF="#PRINTING_MANAGEMENT">
+ Chapter 6, &quot;Printing System Management&quot;</A>.</P>
+<P>Multiple<A HREF="#BrowsePoll"> <CODE>BrowsePoll</CODE></A> lines can
+ be used to poll multiple CUPS servers. To limit the amount of polling
+ you do from client machines, you can have only one of the clients do
+ the polling and relay that information to the others on the same subnet
+ (described next).</P>
+<H3><A NAME="CLIENT_RELAY">Relaying Printers to Other Clients</A></H3>
+<P>When you have clients and servers spread across multiple subnets, the
+ polling method is inefficient. CUPS provides a<A HREF="#BrowseRelay"> <CODE>
+BrowseRelay</CODE></A> directive that enables a single client to relay
+ (broadcast) the polled printer information to the local subnet.</P>
+<P>For example, Server A and Server B are on subnet 1 and subnet 2,
+ while the clients are on subnet 3. To provide printers to all of the
+ clients in subnet 3, client C will be configured with the following
+ directives in<VAR> /etc/cups/cupsd.conf</VAR>:</P>
+<UL>
+<PRE>
+# Poll the two servers
+<B>
+BrowsePoll ServerA ENTER
+BrowsePoll ServerB ENTER
+</B>
+
+# Relay the printers to the local subnet
+<B>
+BrowseRelay 127.0.0.1 192.168.3.255 ENTER
+</B></PRE>
+</UL>
+<P>The<A HREF="#BrowseRelay"> <CODE>BrowseRelay</CODE></A> line
+ specifies a source address and mask. Any browse packets coming from a
+ matching address wil be sent to the given broadcast address. In this
+ case, we want the packets from the local machine (127.0.0.1) relayed to
+ the other clients.</P>
+<P>As printers are found using polling, they are relayed from client C
+ to the rest of the clients through a broadcast on subnet 3. The rest of
+ the clients can use the standard<VAR> cupsd.conf</VAR> configuration.</P>
+<P>The<A HREF="#BrowseRelay"> <CODE>BrowseRelay</CODE></A> directive can
+ also be used to relay browsing packets from one network interface to
+ another. For example, if client C in the previous example had network
+ interfaces attaches to both subnet 1 and subnet 2, it could use the<A HREF="#BrowseRelay">
+ <CODE>BrowseRelay</CODE></A> directive exclusively:</P>
+<UL>
+<PRE>
+# Relay the printers from subnet 1 and 2 to subnet 3
+<B>
+BrowseRelay 192.168.1 192.168.3.255 ENTER
+BrowseRelay 192.168.2 192.168.3.255 ENTER
+</B></PRE>
+</UL>
+<H2><A NAME="6_2">Load Balancing and Failsafe Operation</A></H2>
+<P>When using server polling or broadcasting, CUPS clients can
+ automatically merge identical printers on multiple servers into a
+ single<I> implicit class</I> queue. Clients assume that printers with
+ the same name on multiple servers are in fact the same printer or type
+ of printer being served by multiple machines.</P>
+<P>If you have two printers, LaserJet@ServerA and LaserJet@ServerB, a
+ third implicit class called<I> LaserJet</I> will be created
+ automatically on the client that refers to both printers. If the client
+ also has a local printer with the name LaserJet then an implicit class
+ named<I> AnyLaserJet</I> will be created instead.</P>
+<P>The client will alternate between servers and automatically stop
+ sending jobs to a server if it goes down, providing a load-balancing
+ effect and fail-safe operation with automatic switchover.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Note that implicit classes (<A HREF="#ImplicitClasses"><CODE>
+ImplicitClasses</CODE></A>) are enabled by default.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H1 ALIGN="RIGHT"><A NAME="PRINTING_MANAGEMENT">6 - Printing System
+ Management</A></H1>
+<P>This chapter shows how you can configure the CUPS server.</P>
+<H2><A NAME="7_1">The Basics</A></H2>
+<P>Several text files are used to configure CUPS. All of the server
+ configuration files are located in the<VAR> /etc/cups</VAR> directory:</P>
+<UL>
+<DL>
+<!-- NEED 1in -->
+
+<DT>classes.conf</DT>
+<DD>This file contains information on each printer class. Normally you
+ manipulate this file using the <CODE>lpadmin</CODE> command or the Web
+ interface.
+<BR>&nbsp;
+<!-- NEED 1in -->
+</DD>
+<DT>client.conf</DT>
+<DD>This file provides the default server name for client machines. See<A
+HREF="#CLIENT_SETUP"> Chapter 5, &quot;Client Setup&quot;</A> for more
+ information.
+<BR>&nbsp;
+<!-- NEED 1in -->
+</DD>
+<DT>cupsd.conf</DT>
+<DD>This file controls how the CUPS server (<VAR>/usr/sbin/cupsd</VAR>)
+ operates and is normally edited by hand.
+<BR>&nbsp;
+<!-- NEED 1in -->
+</DD>
+<DT>mime.convs</DT>
+<DD>This file contains a list of standard file conversion filters and
+ their costs. You normally do not edit this file.
+<BR>&nbsp;
+<!-- NEED 1in -->
+</DD>
+<DT>mime.types</DT>
+<DD>This file contains a list of standard file formats and how to
+ recognize them. You normally do not edit this file.
+<BR>&nbsp;
+<!-- NEED 1in -->
+</DD>
+<DT>printers.conf</DT>
+<DD>This file contains information on each printer. Normally you
+ manipulate this file using the <CODE>lpadmin</CODE> command or the Web
+ Interface.
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H2><A NAME="RESTARTING">Restarting the CUPS Server</A></H2>
+<P>Once you have made a change to a configuration file you need to
+ restart the CUPS server by sending it a <CODE>HUP</CODE> signal or
+ using the supplied initialization script. The CUPS distributions
+ install the script in the<VAR> init.d</VAR> directory with the name<VAR>
+ cups</VAR>. The location varies based upon the operating system:</P>
+<UL>
+<PRE>
+<B>/etc/software/init.d/cups restart ENTER</B>
+<B>/etc/rc.d/init.d/cups restart ENTER</B>
+<B>/etc/init.d/cups restart ENTER</B>
+<B>/sbin/init.d/cups restart ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="7_3">Changing the Server Configuration</A></H2>
+<P>The<VAR> /etc/cups/cupsd.conf</VAR> file contains configuration<I>
+ directives</I> that control how the server functions. Each directive is
+ listed on a line by itself followed by its value. Comments are
+ introduced using the number sign (&quot;#&quot;) character at the beginning of a
+ line. Since the server configuration file consists of plain text, you
+ can use your favorite text editor to make changes to it.
+<!-- NEED 4in -->
+</P>
+<H2><A NAME="7_4">Server Directives</A></H2>
+<P>The<VAR> cupsd.conf</VAR> file contains many directives that
+ determine how the server operates:</P>
+<UL>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0">
+<TR><TD VALIGN="TOP">
+<LI><A HREF="#AccessLog"><CODE>AccessLog</CODE></A></LI>
+<LI><A HREF="#Allow"><CODE>Allow</CODE></A></LI>
+<LI><A HREF="#AuthClass"><CODE>AuthClass</CODE></A></LI>
+<LI><A HREF="#AuthGroupName"><CODE>AuthGroupName</CODE></A></LI>
+<LI><A HREF="#AuthType"><CODE>AuthType</CODE></A></LI>
+<LI><A HREF="#AutoPurgeJobs"><CODE>AutoPurgeJobs</CODE></A></LI>
+<LI><A HREF="#BrowseAddress"><CODE>BrowseAddress</CODE></A></LI>
+<LI><A HREF="#BrowseAllow"><CODE>BrowseAllow</CODE></A></LI>
+<LI><A HREF="#BrowseDeny"><CODE>BrowseDeny</CODE></A></LI>
+<LI><A HREF="#BrowseInterval"><CODE>BrowseInterval</CODE></A></LI>
+<LI><A HREF="#BrowseOrder"><CODE>BrowseOrder</CODE></A></LI>
+<LI><A HREF="#BrowsePoll"><CODE>BrowsePoll</CODE></A></LI>
+<LI><A HREF="#BrowsePort"><CODE>BrowsePort</CODE></A></LI>
+<LI><A HREF="#BrowseProtocols"><CODE>BrowseProtocols</CODE></A></LI>
+<LI><A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A></LI>
+<LI><A HREF="#BrowseShortNames"><CODE>BrowseShortNames</CODE></A></LI>
+<LI><A HREF="#BrowseTimeout"><CODE>BrowseTimeout</CODE></A></LI>
+<LI><A HREF="#Browsing"><CODE>Browsing</CODE></A></LI>
+<LI><A HREF="#Classification"><CODE>Classification</CODE></A></LI>
+<LI><A HREF="#ClassifyOverride"><CODE>ClassifyOverride</CODE></A></LI>
+<LI><A HREF="#ConfigFilePerm"><CODE>ConfigFilePerm</CODE></A></LI>
+<LI><A HREF="#DataDir"><CODE>DataDir</CODE></A></LI>
+<LI><A HREF="#DefaultCharset"><CODE>DefaultCharset</CODE></A></LI>
+<LI><A HREF="#DefaultLanguage"><CODE>DefaultLanguage</CODE></A></LI>
+<LI><A HREF="#Deny"><CODE>Deny</CODE></A></LI>
+<LI><A HREF="#DocumentRoot"><CODE>DocumentRoot</CODE></A></LI>
+<LI><A HREF="#Encryption"><CODE>Encryption</CODE></A></LI>
+</TD><TD VALIGN="TOP"> &nbsp;&nbsp;&nbsp;</TD><TD VALIGN="TOP">
+<LI><A HREF="#ErrorLog"><CODE>ErrorLog</CODE></A></LI>
+<LI><A HREF="#FilterLimit"><CODE>FilterLimit</CODE></A></LI>
+<LI><A HREF="#FontPath"><CODE>FontPath</CODE></A></LI>
+<LI><A HREF="#Group"><CODE>Group</CODE></A></LI>
+<LI><A HREF="#HideImplicitMembers"><CODE>HideImplicitMembers</CODE></A></LI>
+<LI><A HREF="#HostNameLookups"><CODE>HostNameLookups</CODE></A></LI>
+<LI><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A></LI>
+<LI><A HREF="#ImplicitAnyClasses"><CODE>ImplicitAnyClasses</CODE></A></LI>
+<LI><A HREF="#Include"><CODE>Include</CODE></A></LI>
+<LI><A HREF="#KeepAliveTimeout"><CODE>KeepAliveTimeout</CODE></A></LI>
+<LI><A HREF="#KeepAlive"><CODE>KeepAlive</CODE></A></LI>
+<LI><A HREF="#Limit"><CODE>Limit</CODE></A></LI>
+<LI><A HREF="#LimitExcept"><CODE>LimitExcept</CODE></A></LI>
+<LI><A HREF="#LimitRequestBody"><CODE>LimitRequestBody</CODE></A></LI>
+<LI><A HREF="#Listen"><CODE>Listen</CODE></A></LI>
+<LI><A HREF="#Location"><CODE>Location</CODE></A></LI>
+<LI><A HREF="#LogFilePerm"><CODE>LogFilePerm</CODE></A></LI>
+<LI><A HREF="#LogLevel"><CODE>LogLevel</CODE></A></LI>
+<LI><A HREF="#MaxClients"><CODE>MaxClients</CODE></A></LI>
+<LI><A HREF="#MaxJobs"><CODE>MaxJobs</CODE></A></LI>
+<LI><A HREF="#MaxJobsPerPrinter"><CODE>MaxJobsPerPrinter</CODE></A></LI>
+<LI><A HREF="#MaxJobsPerUser"><CODE>MaxJobsPerUser</CODE></A></LI>
+<LI><A HREF="#MaxLogSize"><CODE>MaxLogSize</CODE></A></LI>
+<LI><A HREF="#MaxRequestSize"><CODE>MaxRequestSize</CODE></A></LI>
+<LI><A HREF="#Order"><CODE>Order</CODE></A></LI>
+<LI><A HREF="#PageLog"><CODE>PageLog</CODE></A></LI>
+</TD><TD VALIGN="TOP"> &nbsp;&nbsp;&nbsp;</TD><TD VALIGN="TOP">
+<LI><A HREF="#Port"><CODE>Port</CODE></A></LI>
+<LI><A HREF="#PreserveJobFiles"><CODE>PreserveJobFiles</CODE></A></LI>
+<LI><A HREF="#PreserveJobHistory"><CODE>PreserveJobHistory</CODE></A></LI>
+<LI><A HREF="#Printcap"><CODE>Printcap</CODE></A></LI>
+<LI><A HREF="#PrintcapFormat"><CODE>PrintcapFormat</CODE></A></LI>
+<LI><A HREF="#PrintcapGUI"><CODE>PrintcapGUI</CODE></A></LI>
+<LI><A HREF="#RemoteRoot"><CODE>RemoteRoot</CODE></A></LI>
+<LI><A HREF="#RequestRoot"><CODE>RequestRoot</CODE></A></LI>
+<LI><A HREF="#Require"><CODE>Require</CODE></A></LI>
+<LI><A HREF="#RIPCache"><CODE>RIPCache</CODE></A></LI>
+<LI><A HREF="#RunAsUser"><CODE>RunAsUser</CODE></A></LI>
+<LI><A HREF="#Satisfy"><CODE>Satisfy</CODE></A></LI>
+<LI><A HREF="#ServerAdmin"><CODE>ServerAdmin</CODE></A></LI>
+<LI><A HREF="#ServerBin"><CODE>ServerBin</CODE></A></LI>
+<LI><A HREF="#ServerCertificate"><CODE>ServerCertificate</CODE></A></LI>
+<LI><A HREF="#ServerKey"><CODE>ServerKey</CODE></A></LI>
+<LI><A HREF="#ServerName"><CODE>ServerName</CODE></A></LI>
+<LI><A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A></LI>
+<LI><A HREF="#SSLListen"><CODE>SSLListen</CODE></A></LI>
+<LI><A HREF="#SSLPort"><CODE>SSLPort</CODE></A></LI>
+<LI><A HREF="#SystemGroup"><CODE>SystemGroup</CODE></A></LI>
+<LI><A HREF="#TempDir"><CODE>TempDir</CODE></A></LI>
+<LI><A HREF="#Timeout"><CODE>Timeout</CODE></A></LI>
+<LI><A HREF="#User"><CODE>User</CODE></A></LI>
+</TD></TR>
+</TABLE>
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="AccessLog">AccessLog</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+AccessLog /var/log/cups/access_log
+AccessLog /var/log/cups/access_log-%s
+AccessLog syslog
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>AccessLog</CODE> directive sets the name of the access log
+ file. If the filename is not absolute then it is assumed to be relative
+ to the<A HREF="#ServerRoot"> <CODE>ServerRoot</CODE></A> directory. The
+ access log file is stored in &quot;common log format&quot; and can be used by any
+ web access reporting tool to generate a report on CUPS server activity.</P>
+<P>The server name can be included in the filename by using <CODE>%s</CODE>
+ in the name.</P>
+<P>The special name &quot;syslog&quot; can be used to send the access information
+ to the system log instead of a plain file.</P>
+<P>The default access log file is<VAR> /var/log/cups/access_log</VAR>.
+<!-- NEED 6in -->
+</P>
+<H3><A NAME="Allow">Allow</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Allow from All
+Allow from None
+Allow from *.domain.com
+Allow from .domain.com
+Allow from host.domain.com
+Allow from nnn.*
+Allow from nnn.nnn.*
+Allow from nnn.nnn.nnn.*
+Allow from nnn.nnn.nnn.nnn
+Allow from nnn.nnn.nnn.nnn/mm
+Allow from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+Allow from @LOCAL
+Allow from @IF(name)
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Allow</CODE> directive specifies a hostname, IP address, or
+ network that is allowed access to the server. <CODE>Allow</CODE>
+ directives are cummulative, so multiple <CODE>Allow</CODE> directives
+ can be used to allow access for multiple hosts or networks. The <CODE>
+/mm</CODE> notation specifies a CIDR netmask:
+<CENTER>
+<TABLE BORDER="1">
+<TR><TH WIDTH="10%">mm</TH><TH WIDTH="20%">netmask</TH><TH WIDTH="10%">
+mm</TH><TH WIDTH="20%">netmask</TH></TR>
+<TR><TD ALIGN="CENTER">0</TD><TD ALIGN="CENTER">0.0.0.0</TD><TD ALIGN="CENTER">
+8</TD><TD ALIGN="CENTER">255.0.0.0</TD></TR>
+<TR><TD ALIGN="CENTER">1</TD><TD ALIGN="CENTER">128.0.0.0</TD><TD ALIGN="CENTER">
+16</TD><TD ALIGN="CENTER">255.255.0.0</TD></TR>
+<TR><TD ALIGN="CENTER">2</TD><TD ALIGN="CENTER">192.0.0.0</TD><TD ALIGN="CENTER">
+24</TD><TD ALIGN="CENTER">255.255.255.0</TD></TR>
+<TR><TD ALIGN="CENTER">...</TD><TD ALIGN="CENTER">...</TD><TD ALIGN="CENTER">
+32</TD><TD ALIGN="CENTER">255.255.255.255</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<P>The <CODE>@LOCAL</CODE> name will allow access from all local network
+ interfaces, but not remote point-to-point interfaces. The <CODE>
+@IF(name)</CODE> name will allow access from the named interface.</P>
+<P>The <CODE>Allow</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="AuthClass">AuthClass</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+AuthClass Anonymous
+AuthClass User
+AuthClass System
+AuthClass Group
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>AuthClass</CODE> directive defines what level of
+ authentication is required:</P>
+<UL>
+<LI><CODE>Anonymous</CODE> - No authentication should be performed
+ (default.)</LI>
+<LI><CODE>User</CODE> - A valid username and password is required.</LI>
+<LI><CODE>System</CODE> - A valid username and password is required, and
+ the username must belong to the &quot;sys&quot; group; this can be changed using
+ the<A HREF="#SystemGroup"> <CODE>SystemGroup</CODE></A> directive.</LI>
+<LI><CODE>Group</CODE> - A valid username and password is required, and
+ the username must belong to the group named by the <CODE>AuthGroupName</CODE>
+ directive.</LI>
+</UL>
+<P>The <CODE>AuthClass</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="AuthGroupName">AuthGroupName</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+AuthGroupName mygroup
+AuthGroupName lp
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>AuthGroupName</CODE> directive sets the group to use for <CODE>
+Group</CODE> authentication.</P>
+<P>The <CODE>AuthGroupName</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="AuthType">AuthType</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+AuthType None
+AuthType Basic
+AuthType Digest
+AuthType BasicDigest
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>AuthType</CODE> directive defines the type of
+ authentication to perform:</P>
+<UL>
+<LI><CODE>None</CODE> - No authentication should be performed (default.)</LI>
+<LI><CODE>Basic</CODE> - Basic authentication should be performed using
+ the UNIX password and group files.</LI>
+<LI><CODE>Digest</CODE> - Digest authentication should be performed
+ using the<VAR> /etc/cups/passwd.md5</VAR> file.</LI>
+<LI><CODE>BasicDigest</CODE> - Basic authentication should be performed
+ using the<VAR> /etc/cups/passwd.md5</VAR> file.</LI>
+</UL>
+<P>When using <CODE>Basic</CODE>, <CODE>Digest</CODE>, or <CODE>
+BasicDigest</CODE> authentication, clients connecting through the <CODE>
+localhost</CODE> interface can also authenticate using<A HREF="#CERTIFICATES">
+ certificates</A>.</P>
+<P>The <CODE>AuthType</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="AutoPurgeJobs">AutoPurgeJobs</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+AutoPurgeJobs Yes
+AutoPurgeJobs No
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>AutoPurgeJobs</CODE> directive specifies whether or not to
+ purge completed jobs once they are no longer required for quotas. This
+ option has no effect if quotas are not enabled. The default setting is <CODE>
+No</CODE>.
+<!-- NEED 5in -->
+</P>
+<H3><A NAME="BrowseAddress">BrowseAddress</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseAddress 255.255.255.255:631
+BrowseAddress 192.0.2.255:631
+BrowseAddress host.domain.com:631
+BrowseAddress @LOCAL
+BrowseAddress @IF(name)
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseAddress</CODE> directive specifies an address to send
+ browsing information to. Multiple <CODE>BrowseAddress</CODE> directives
+ can be specified to send browsing information to different networks or
+ systems.</P>
+<P>The <CODE>@LOCAL</CODE> name will broadcast printer information to
+ all local interfaces. The <CODE>@IF(name)</CODE> name will broadcast to
+ the named interface.</P>
+<P>No browse addresses are set by default.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>If you are using HP-UX 10.20 and a subnet that is not 24, 16, or 8
+ bits, printer browsing (and in fact all broadcast reception) will not
+ work. This problem appears to be fixed in HP-UX 11.0.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 4in -->
+<H3><A NAME="BrowseAllow">BrowseAllow</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseAllow from all
+BrowseAllow from none
+BrowseAllow from 192.0.2
+BrowseAllow from 192.0.2.0/24
+BrowseAllow from 192.0.2.0/255.255.255.0
+BrowseAllow from *.domain.com
+BrowseAllow from @LOCAL
+BrowseAllow from @IF(name)
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseAllow</CODE> directive specifies a system or network
+ to accept browse packets from. The default is to accept browse packets
+ from all hosts.</P>
+<P>Host and domain name matching require that you enable the<A HREF="#HostNameLookups">
+ <CODE>HostNameLookups</CODE></A> directive.</P>
+<P>IP address matching supports exact matches, partial addresses that
+ match networks using netmasks of 255.0.0.0, 255.255.0.0, and
+ 255.255.255.0, or network addresses using the specified netmask or bit
+ count.</P>
+<P>The <CODE>@LOCAL</CODE> name will allow browse data from all local
+ network interfaces, but not remote point-to-point interfaces. The <CODE>
+@IF(name)</CODE> name will allow browse data from the named interface.
+<!-- NEED 4in -->
+</P>
+<H3><A NAME="BrowseDeny">BrowseDeny</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseDeny from all
+BrowseDeny from none
+BrowseDeny from 192.0.2
+BrowseDeny from 192.0.2.0/24
+BrowseDeny from 192.0.2.0/255.255.255.0
+BrowseDeny from *.domain.com
+BrowseDeny from @LOCAL
+BrowseDeny from @IF(name)
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseDeny</CODE> directive specifies a system or network
+ to reject browse packets from. The default is to deny browse packets
+ from no hosts.</P>
+<P>Host and domain name matching require that you enable the<A HREF="#HostNameLookups">
+ <CODE>HostNameLookups</CODE></A> directive.</P>
+<P>IP address matching supports exact matches, partial addresses that
+ match networks using netmasks of 255.0.0.0, 255.255.0.0, and
+ 255.255.255.0, or network addresses using the specified netmask or bit
+ count.</P>
+<P>The <CODE>@LOCAL</CODE> name will block browse data from all local
+ network interfaces, but not remote point-to-point interfaces. The <CODE>
+@IF(name)</CODE> name will block browse data from the named interface.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="BrowseOrder">BrowseOrder</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseOrder allow,deny
+BrowseOrder deny,allow
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseOrder</CODE> directive specifies the order of
+ allow/deny processing. The default order is <CODE>deny,allow</CODE>:</P>
+<UL>
+<LI><CODE>allow,deny</CODE> - Browse packets are accepted unless
+ specifically denied.</LI>
+<LI><CODE>deny,allow</CODE> - Browse packets are rejected unless
+ specifically allowed.</LI>
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseInterval">BrowseInterval</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseInterval 0
+BrowseInterval 30
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseInterval</CODE> directive specifies the maximum
+ amount of time between browsing updates. Specifying a value of 0
+ seconds disables outgoing browse updates but allows a server to receive
+ printer information from other hosts.</P>
+<P>The <CODE>BrowseInterval</CODE> value should always be less than the<A
+HREF="#BrowseTimeout"> <CODE>BrowseTimeout</CODE></A> value. Otherwise
+ printers and classes will disappear from client systems between
+ updates.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="BrowsePoll">BrowsePoll</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowsePoll 192.0.2.2:631
+BrowsePoll host.domain.com:631
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowsePoll</CODE> directive polls a server for available
+ printers once every<A HREF="#BrowseInterval"> <CODE>BrowseInterval</CODE>
+</A> seconds. Multiple <CODE>BrowsePoll</CODE> directives can be
+ specified to poll multiple servers.</P>
+<P>If <CODE>BrowseInterval</CODE> is set to 0 then the server is polled
+ once every 30 seconds.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="BrowsePort">BrowsePort</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowsePort 631
+BrowsePort 9999
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowsePort</CODE> directive specifies the UDP port number
+ used for browse packets. The default port number is 631.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>You must set the <CODE>BrowsePort</CODE> to the same value on all of
+ the systems that you want to see.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseProtocols">BrowseProtocols</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseProtocols CUPS
+BrowseProtocols SLP
+BrowseProtocols CUPS SLP
+BrowseProtocols all
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseProtocols</CODE> directive specifies the protocols to
+ use when collecting and distributing shared printers on the local
+ network. The default protocol is <CODE>CUPS</CODE>, which is a
+ broadcast-based protocol.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>When using the <CODE>SLP</CODE> protocol, you must have at least one
+ Directory Agent (DA) server on your network. Otherwise the CUPS
+ scheduler (<CODE>cupsd</CODE>) will not respond to client requests for
+ several seconds while polling the network.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 4in -->
+<H3><A NAME="BrowseRelay">BrowseRelay</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseRelay 193.0.2.1 192.0.2.255
+BrowseRelay 193.0.2.0/255.255.255.0 192.0.2.255
+BrowseRelay 193.0.2.0/24 192.0.2.255
+BrowseRelay *.domain.com 192.0.2.255
+BrowseRelay host.domain.com 192.0.2.255
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseRelay</CODE> directive specifies source and
+ destination addresses for relaying browsing information from one host
+ or network to another. Multiple <CODE>BrowseRelay</CODE> directives can
+ be specified as needed.</P>
+<P><CODE>BrowseRelay</CODE> is typically used on systems that bridge
+ multiple subnets using one or more network interfaces. It can also be
+ used to relay printer information from polled servers with the line:</P>
+<UL>
+<PRE>
+BrowseRelay 127.0.0.1 255.255.255.255
+</PRE>
+</UL>
+<P>This effectively provides access to printers on a WAN for all clients
+ on the LAN(s).
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="BrowseShortNames">BrowseShortNames</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseShortNames Yes
+BrowseShortNames No
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseShortNames</CODE> directive specifies whether or not
+ short names are used for remote printers when possible. Short names are
+ just the remote printer name, without the server (&quot;printer&quot;). If more
+ than one remote printer is detected with the same name, the printers
+ will have long names (&quot;printer@server1&quot;, &quot;printer@server2&quot;.)</P>
+<P>The default value for this option is <CODE>Yes</CODE>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="BrowseTimeout">BrowseTimeout</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseTimeout 300
+BrowseTimeout 60
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseTimeout</CODE> directive sets the timeout for printer
+ or class information that is received in browse packets. Once a printer
+ or class times out it is removed from the list of available
+ destinations.</P>
+<P>The <CODE>BrowseTimeout</CODE> value should always be greater than
+ the<A HREF="#BrowseInterval"> <CODE>BrowseInterval</CODE></A> value.
+ Otherwise printers and classes will disappear from client systems
+ between updates.
+<!-- NEED 4in -->
+</P>
+<H3><A NAME="Browsing">Browsing</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Browsing On
+Browsing Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Browsing</CODE> directive controls whether or not network
+ printer browsing is enabled. The default setting is <CODE>On</CODE>.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>If you are using HP-UX 10.20 and a subnet that is not 24, 16, or 8
+ bits, printer browsing (and in fact all broadcast reception) will not
+ work. This problem appears to be fixed in HP-UX 11.0.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="Classification">Classification</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Classification
+Classification classified
+Classification confidential
+Classification secret
+Classification topsecret
+Classification unclassified
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Classification</CODE> directive sets the classification
+ level on the server. When this option is set, at least one of the
+ banner pages is forced to the classification level, and the
+ classification is placed on each page of output. The default is no
+ classification level.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ClassifyOverride">ClassifyOverride</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ClassifyOverride Yes
+ClassifyOverride No
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ClassifyOverride</CODE> directive specifies whether users
+ can override the default classification level on the server. When the
+ server classification is set, users can change the classification using
+ the <CODE>job-sheets</CODE> option and can choose to only print one
+ security banner before or after the job. If the <CODE>job-sheets</CODE>
+ option is set to <CODE>none</CODE> then the server default
+ classification is used.</P>
+<P>The default is to not allow classification overrides.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ConfigFilePerm">ConfigFilePerm</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ConfigFilePerm 0644
+ConfigFilePerm 0600
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ConfigFilePerm</CODE> directive specifies the permissions
+ to use when writing configuration files. The default is 0600.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="DataDir">DataDir</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+DataDir /usr/share/cups
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>DataDir</CODE> directive sets the directory to use for data
+ files.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="DefaultCharset">DefaultCharset</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+DefaultCharset utf-8
+DefaultCharset iso-8859-1
+DefaultCharset windows-1251
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>DefaultCharset</CODE> directive sets the default character
+ set to use for client connections. The default character set is <CODE>
+utf-8</CODE> but is overridden by the character set for the language
+ specified by the client or the <CODE>DefaultLanguage</CODE> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="DefaultLanguage">DefaultLanguage</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+DefaultLanguage de
+DefaultLanguage en
+DefaultLanguage es
+DefaultLanguage fr
+DefaultLanguage it
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>DefaultLanguage</CODE> directive specifies the default
+ language to use for client connections. Setting the default language
+ also sets the default character set if a language localization file
+ exists for it. The default language is &quot;en&quot; for English.
+<!-- NEED 5in -->
+</P>
+<H3><A NAME="Deny">Deny</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Deny from All
+Deny from None
+Deny from *.domain.com
+Deny from .domain.com
+Deny from host.domain.com
+Deny from nnn.*
+Deny from nnn.nnn.*
+Deny from nnn.nnn.nnn.*
+Deny from nnn.nnn.nnn.nnn
+Deny from nnn.nnn.nnn.nnn/mm
+Deny from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+Deny from @LOCAL
+Deny from @IF(name)
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Deny</CODE> directive specifies a hostname, IP address, or
+ network that is allowed access to the server. <CODE>Deny</CODE>
+ directives are cummulative, so multiple <CODE>Deny</CODE> directives
+ can be used to allow access for multiple hosts or networks. The <CODE>
+/mm</CODE> notation specifies a CIDR netmask:
+<CENTER>
+<TABLE BORDER="1">
+<TR><TH WIDTH="10%">mm</TH><TH WIDTH="20%">netmask</TH><TH WIDTH="10%">
+mm</TH><TH WIDTH="20%">netmask</TH></TR>
+<TR><TD ALIGN="CENTER">0</TD><TD ALIGN="CENTER">0.0.0.0</TD><TD ALIGN="CENTER">
+8</TD><TD ALIGN="CENTER">255.0.0.0</TD></TR>
+<TR><TD ALIGN="CENTER">1</TD><TD ALIGN="CENTER">128.0.0.0</TD><TD ALIGN="CENTER">
+16</TD><TD ALIGN="CENTER">255.255.0.0</TD></TR>
+<TR><TD ALIGN="CENTER">2</TD><TD ALIGN="CENTER">192.0.0.0</TD><TD ALIGN="CENTER">
+24</TD><TD ALIGN="CENTER">255.255.255.0</TD></TR>
+<TR><TD ALIGN="CENTER">...</TD><TD ALIGN="CENTER">...</TD><TD ALIGN="CENTER">
+32</TD><TD ALIGN="CENTER">255.255.255.255</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<P>The <CODE>@LOCAL</CODE> name will deny access from all local network
+ interfaces, but not remote point-to-point interfaces. The <CODE>
+@IF(name)</CODE> name will deny access from the named interface.</P>
+<P>The <CODE>Deny</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="DocumentRoot">DocumentRoot</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+DocumentRoot /usr/share/doc/cups
+DocumentRoot /foo/bar/doc/cups
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>DocumentRoot</CODE> directive specifies the location of web
+ content for the HTTP server in CUPS. If an absolute path is not
+ specified then it is assumed to be relative to the<A HREF="#ServerRoot">
+ <CODE>ServerRoot</CODE></A> directory. The default directory is<VAR>
+ /usr/share/doc/cups</VAR>.</P>
+<P>Documents are first looked up in a sub-directory for the primary
+ language requested by the client (e.g.<VAR> /usr/share/doc/cups/fr/...</VAR>
+) and then directly under the <CODE>DocumentRoot</CODE> directory (e.g.<VAR>
+ /usr/share/doc/cups/...</VAR>), so it is possible to localize the web
+ content by providing subdirectories for each language needed.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Encryption">Encryption</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Encryption Never
+Encryption IfRequested
+Encryption Required
+Encryption Always
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Encryption</CODE> directive must appear instead a<A HREF="#Location">
+ <CODE>Location</CODE></A> section and specifies the encryption settings
+ for that location. The default setting is <CODE>IfRequested</CODE> for
+ all locations.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ErrorLog">ErrorLog</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ErrorLog /var/log/cups/error_log
+ErrorLog /var/log/cups/error_log-%s
+ErrorLog syslog
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ErrorLog</CODE> directive sets the name of the error log
+ file. If the filename is not absolute then it is assumed to be relative
+ to the<A HREF="#ServerRoot"> <CODE>ServerRoot</CODE></A> directory. The
+ default error log file is<VAR> /var/log/cups/error_log</VAR>.</P>
+<P>The server name can be included in the filename by using <CODE>%s</CODE>
+ in the name.</P>
+<P>The special name &quot;syslog&quot; can be used to send the error information
+ to the system log instead of a plain file.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="FilterLimit">FilterLimit</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+FilterLimit 0
+FilterLimit 200
+FilterLimit 1000
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>FilterLimit</CODE> directive sets the maximum cost of all
+ running job filters. It can be used to limit the number of filter
+ programs that are run on a server to minimize disk, memory, and CPU
+ resource problems. A limit of 0 disables filter limiting.</P>
+<P>An average print to a non-PostScript printer needs a filter limit of
+ about 200. A PostScript printer needs about half that (100). Setting
+ the limit below these thresholds will effectively limit the scheduler
+ to printing a single job at any time.</P>
+<P>The default limit is 0.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="FontPath">FontPath</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+FontPath /foo/bar/fonts
+FontPath /usr/share/cups/fonts:/foo/bar/fonts
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>FontPath</CODE> directive specifies the font path to use
+ when searching for fonts. The default font path is <CODE>
+/usr/share/cups/fonts</CODE>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Group">Group</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Group sys
+Group system
+Group root
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Group</CODE> directive specifies the UNIX group that filter
+ and CGI programs run as. The default group is <CODE>sys</CODE>, <CODE>
+system</CODE>, or <CODE>root</CODE> depending on the operating system.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="HideImplicitMembers">HideImplicitMembers</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+HideImplicitMembers Yes
+HideImplicitMembers No
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>HideImplicitMembers</CODE> directive controls whether the
+ individual printers in an implicit class are shown to the user. The
+ default is <CODE>No</CODE>.</P>
+<P><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A> must be
+ enabled for this directive to have any effect.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="HostNameLookups">HostNameLookups</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+HostNameLookups On
+HostNameLookups Off
+HostNameLookups Double
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>HostNameLookups</CODE> directive controls whether or not
+ CUPS looks up the hostname for connecting clients. The <CODE>Double</CODE>
+ setting causes CUPS to verify that the hostname resolved from the
+ address matches one of the addresses returned for that hostname. <CODE>
+Double</CODE> lookups also prevent clients with unregistered addresses
+ from connecting to your server. The default is <CODE>Off</CODE> to
+ avoid the potential server performance problems with hostname lookups.
+ Set this option to <CODE>On</CODE> or <CODE>Double</CODE> only if
+ absolutely required.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ImplicitClasses">ImplicitClasses</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ImplicitClasses On
+ImplicitClasses Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ImplicitClasses</CODE> directive controls whether implicit
+ classes are created based upon the available network printers and
+ classes. The default setting is <CODE>On</CODE> but is automatically
+ turned <CODE>Off</CODE> if<A HREF="#Browsing"> <CODE>Browsing</CODE></A>
+ is turned <CODE>Off</CODE>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ImplicitAnyClasses">ImplicitAnyClasses</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ImplicitAnyClasses On
+ImplicitAnyClasses Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ImplicitAnyClasses</CODE> directive controls whether
+ implicit classes for local and remote printers are created with the
+ name <CODE>AnyPrinter</CODE>. The default setting is <CODE>Off</CODE>.</P>
+<P><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A> must be
+ enabled for this directive to have any effect.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="Include">Include</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Include filename
+Include /foo/bar/filename
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Include</CODE> directive includes the named file in the <CODE>
+cupsd.conf</CODE> file. If no leading path is provided, the file is
+ assumed to be relative to the<A HREF="#ServerRoot"> <CODE>ServerRoot</CODE>
+</A> directory.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="KeepAlive">KeepAlive</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+KeepAlive On
+KeepAlive Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>KeepAlive</CODE> directive controls whether or not to
+ support persistent HTTP connections. The default is <CODE>On</CODE>.</P>
+<P>HTTP/1.1 clients automatically support persistent connections, while
+ HTTP/1.0 clients must specifically request them using the <CODE>
+Keep-Alive</CODE> attribute in the <CODE>Connection:</CODE> field of
+ each request.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="KeepAliveTimeout">KeepAliveTimeout</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+KeepAliveTimeout 60
+KeepAliveTimeout 30
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>KeepAliveTimeout</CODE> directive controls how long a
+ persistent HTTP connection will remain open after the last request. The
+ default is 60 seconds.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Limit">Limit</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+&lt;Limit GET POST&gt;
+...
+&lt;/Limit&gt;
+
+&lt;Limit ALL&gt;
+...
+&lt;/Limit&gt;
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Limit</CODE> directive groups access control directives for
+ specific types of HTTP requests and must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> section. Access can be limited for individual
+ request types (<CODE>DELETE</CODE>, <CODE>GET</CODE>, <CODE>HEAD</CODE>
+, <CODE>OPTIONS</CODE>, <CODE>POST</CODE>, <CODE>PUT</CODE>, and <CODE>
+TRACE</CODE>) or for all request types (<CODE>ALL</CODE>). The request
+ type names are case-sensitive for compatibility with Apache.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="LimitExcept">LimitExcept</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+&lt;LimitExcept GET POST&gt;
+...
+&lt;/LimitExcept&gt;
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>LimitExcept</CODE> directive groups access control
+ directives for specific types of HTTP requests and must appear inside a<A
+HREF="#Location"> <CODE>Location</CODE></A> section. Unlike the<A HREF="#Limit">
+ <CODE>Limit</CODE></A> directive, <CODE>LimitExcept</CODE> restricts
+ access for all requests<I> except</I> those listed on the <CODE>
+LimitExcept</CODE> line.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="LimitRequestBody">LimitRequestBody</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+LimitRequestBody 10485760
+LimitRequestBody 10m
+LimitRequestBody 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>LimitRequestBody</CODE> directive controls the maximum size
+ of print files, IPP requests, and HTML form data in HTTP POST requests.
+ The default limit is 0 which disables the limit check.</P>
+<P>Also see the identical<A HREF="#MaxRequestSize"> <CODE>MaxRequestSize</CODE>
+</A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Listen">Listen</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Listen 127.0.0.1:631
+Listen 192.0.2.1:631
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Listen</CODE> directive specifies a network address and
+ port to listen for connections. Multiple <CODE>Listen</CODE> directives
+ can be provided to listen on multiple addresses.</P>
+<P>The <CODE>Listen</CODE> directive is similar to the<A HREF="#Port"> <CODE>
+Port</CODE></A> directive but allows you to restrict access to specific
+ interfaces or networks.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Location">Location</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+&lt;Location /&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /admin&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /printers&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /printers/name&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /classes&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /classes/name&gt;
+...
+&lt;/Location&gt;
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Location</CODE> directive specifies access control and
+ authentication options for the specified HTTP resource or path. The<A HREF="#Allow">
+ <CODE>Allow</CODE></A>,<A HREF="#AuthClass"> <CODE>AuthClass</CODE></A>
+,<A HREF="#AuthGroupName"> <CODE>AuthGroupName</CODE></A>,<A HREF="#AuthType">
+ <CODE>AuthType</CODE></A>,<A HREF="#Deny"> <CODE>Deny</CODE></A>,<A HREF="#Encryption">
+ <CODE>Encryption</CODE></A>,<A HREF="#Limit"> <CODE>Limit</CODE></A>,<A HREF="#LimitExcept">
+ <CODE>LimitExcept</CODE></A>,<A HREF="#Order"> <CODE>Order</CODE></A>,<A
+HREF="#Require"> <CODE>Require</CODE></A>, and<A HREF="#Satisfy"> <CODE>
+Satisfy</CODE></A> directives may all appear inside a location.
+<CENTER>
+<TABLE BORDER="1"><CAPTION>Locations on the Server.</CAPTION>
+<TR><TH>Location</TH><TH>Description</TH></TR>
+<TR><TD>/</TD><TD>The path for all get operations (get-printers,
+ get-jobs, etc.)</TD></TR>
+<TR><TD>/admin</TD><TD>The path for all administration operations
+ (add-printer, delete-printer, start-printer, etc.)</TD></TR>
+<TR><TD>/admin/conf</TD><TD>The path for access to the ESP Print Pro
+ configuration files (cupsd.conf, client.conf, etc.)</TD></TR>
+<TR><TD>/classes</TD><TD>The path for all classes</TD></TR>
+<TR><TD>/classes/name</TD><TD>The resource for class <CODE>name</CODE></TD>
+</TR>
+<TR><TD>/jobs</TD><TD>The path for all jobs (hold-job, release-job,
+ etc.)</TD></TR>
+<TR><TD>/jobs/id</TD><TD>The resource for job <CODE>id</CODE></TD></TR>
+<TR><TD>/printers</TD><TD>The path for all printers</TD></TR>
+<TR><TD>/printers/name</TD><TD>The path for printer <CODE>name</CODE></TD>
+</TR>
+<TR><TD>/printers/name.ppd</TD><TD>The PPD file path for printer <CODE>
+name</CODE></TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<P>Note that more specific resources override the less specific ones. So
+ the directives inside the <CODE>/printers/name</CODE> location will
+ override ones from <CODE>/printers</CODE>. Directives inside <CODE>
+/printers</CODE> will override ones from <CODE>/</CODE>. &nbsp; None of the
+ directives are inherited. More information can be found in section<A HREF="#PRINTING_SECURITY">
+ &quot;Printing System Security&quot;</A>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="LogFilePerm">LogFilePerm</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+LogFilePerm 0644
+LogFilePerm 0600
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>LogFilePerm</CODE> directive specifies the permissions to
+ use when writing configuration files. The default is 0644.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="LogLevel">LogLevel</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+LogLevel none
+LogLevel emerg
+LogLevel alert
+LogLevel crit
+LogLevel error
+LogLevel warn
+LogLevel notice
+LogLevel info
+LogLevel debug
+LogLevel debug2
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>LogLevel</CODE> directive specifies the level of logging
+ for the<A HREF="#ErrorLog"> <CODE>ErrorLog</CODE></A> file. The
+ following values are recognized (each level logs everything under the
+ preceding levels):</P>
+<UL>
+<LI><CODE>none</CODE> - Log nothing.</LI>
+<LI><CODE>emerg</CODE> - Log emergency conditions that prevent the
+ server from running.</LI>
+<LI><CODE>alert</CODE> - Log alerts that must be handled immediately.</LI>
+<LI><CODE>crit</CODE> - Log critical errors that don't prevent the
+ server from running.</LI>
+<LI><CODE>error</CODE> - Log general errors.</LI>
+<LI><CODE>warn</CODE> - Log errors and warnings.</LI>
+<LI><CODE>notice</CODE> - Log temporary error conditions.</LI>
+<LI><CODE>info</CODE> - Log all requests and state changes (default).</LI>
+<LI><CODE>debug</CODE> - Log basic debugging information.</LI>
+<LI><CODE>debug2</CODE> - Log all debugging information.</LI>
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxClients">MaxClients</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxClients 100
+MaxClients 1024
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxClients</CODE> directive controls the maximum number of
+ simultaneous clients that will be allowed by the server. The default is
+ 100 clients.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Since each print job requires a file descriptor for the status pipe,
+ the CUPS server internally limits the <CODE>MaxClients</CODE> value to
+ 1/3 of the available file descriptors to avoid possible problems when
+ printing large numbers of jobs.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxJobs">MaxJobs</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxJobs 100
+MaxJobs 9999
+MaxJobs 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxJobs</CODE> directive controls the maximum number of
+ jobs that are kept in memory. Once the number of jobs reaches the
+ limit, the oldest completed job is automatically purged from the system
+ to make room for the new one. If all of the known jobs are still
+ pending or active then the new job will be rejected.</P>
+<P>Setting the maximum to 0 disables this functionality. The default
+ setting is 0.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="MaxJobsPerPrinter">MaxJobsPerPrinter</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxJobsPerPrinter 100
+MaxJobsPerPrinter 9999
+MaxJobsPerPrinter 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxJobsPerPrinter</CODE> directive controls the maximum
+ number of active jobs that are allowed for each printer or class. Once
+ a printer or class reaches the limit, new jobs will be rejected until
+ one of the active jobs is completed, stopped, aborted, or cancelled.</P>
+<P>Setting the maximum to 0 disables this functionality. The default
+ setting is 0.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="MaxJobsPerUser">MaxJobsPerUser</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxJobsPerUser 100
+MaxJobsPerUser 9999
+MaxJobsPerUser 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxJobsPerUser</CODE> directive controls the maximum number
+ of active jobs that are allowed for each user. Once a user reaches the
+ limit, new jobs will be rejected until one of the active jobs is
+ completed, stopped, aborted, or cancelled.</P>
+<P>Setting the maximum to 0 disables this functionality. The default
+ setting is 0.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="MaxLogSize">MaxLogSize</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxLogSize 1048576
+MaxLogSize 1m
+MaxLogSize 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxLogSize</CODE> directive controls the maximum size of
+ each log file. Once a log file reaches or exceeds the maximum size it
+ is closed and renamed to<VAR> filename.O</VAR>. This allows you to
+ rotate the logs automatically. The default size is 1048576 bytes (1MB).</P>
+<P>Setting the maximum size to 0 disables log rotation.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="MaxRequestSize">MaxRequestSize</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxRequestSize 10485760
+MaxRequestSize 10m
+MaxRequestSize 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxRequestSize</CODE> directive controls the maximum size
+ of print files, IPP requests, and HTML form data in HTTP POST requests.
+ The default limit is 0 which disables the limit check.</P>
+<P>Also see the identical<A HREF="#LimitRequestBody"> <CODE>
+LimitRequestBody</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Order">Order</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Order Allow,Deny
+Order Deny,Allow
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Order</CODE> directive defines the default access control.
+ The following values are supported:</P>
+<UL>
+<LI><CODE>Allow,Deny</CODE> - Allow requests from all systems<I> except</I>
+ for those listed in a <CODE>Deny</CODE> directive.</LI>
+<LI><CODE>Deny,Allow</CODE> - Allow requests only from those listed in
+ an <CODE>Allow</CODE> directive.</LI>
+</UL>
+<P>The <CODE>Order</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="PageLog">PageLog</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+PageLog /var/log/cups/page_log
+PageLog /var/log/cups/page_log-%s
+PageLog syslog
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>PageLog</CODE> directive sets the name of the page log
+ file. If the filename is not absolute then it is assumed to be relative
+ to the<A HREF="#ServerRoot"> <CODE>ServerRoot</CODE></A> directory. The
+ default page log file is<VAR> /var/log/cups/page_log</VAR>.</P>
+<P>The server name can be included in the filename by using <CODE>%s</CODE>
+ in the name.</P>
+<P>The special name &quot;syslog&quot; can be used to send the page information to
+ the system log instead of a plain file.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Port">Port</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Port 631
+Port 80
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Port</CODE> directive specifies a port to listen on.
+ Multiple <CODE>Port</CODE> lines can be specified to listen on multiple
+ ports. The default port is 631.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="PreserveJobHistory">PreserveJobHistory</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+PreserveJobHistory On
+PreserveJobHistory Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>PreserveJobHistory</CODE> directive controls whether the
+ history of completed, cancelled, or aborted print jobs is stored on
+ disk.</P>
+<P>A value of <CODE>On</CODE> (the default) preserves job information
+ until the administrator purges it with the <CODE>cancel</CODE> command.</P>
+<P>A value of <CODE>Off</CODE> removes the job information as soon as
+ each job is completed, cancelled, or aborted.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="PreserveJobFiles">PreserveJobFiles</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+PreserveJobFiles On
+PreserveJobFiles Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>PreserveJobFiles</CODE> directive controls whether the
+ document files of completed, cancelled, or aborted print jobs are
+ stored on disk.</P>
+<P>A value of <CODE>On</CODE> preserves job files until the
+ administrator purges them with the <CODE>cancel</CODE> command. Jobs
+ can be restarted (and reprinted) as desired until they are purged.</P>
+<P>A value of <CODE>Off</CODE> (the default) removes the job files as
+ soon as each job is completed, cancelled, or aborted.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Printcap">Printcap</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Printcap
+Printcap /etc/printcap
+Printcap /etc/printers.conf
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Printcap</CODE> directive controls whether or not a
+ printcap file is automatically generated and updated with a list of
+ available printers. If specified with no value, then no printcap file
+ will be generated. The default is to generate a file named<VAR>
+ /etc/printcap</VAR>.</P>
+<P>When a filename is specified (e.g.<VAR> /etc/printcap</VAR>), the
+ printcap file is written whenever a printer is added or removed. The
+ printcap file can then be used by applications that are hardcoded to
+ look at the printcap file for the available printers.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="PrintcapFormat">PrintcapFormat</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+PrintcapFormat BSD
+PrintcapFormat Solaris
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>PrintcapFormat</CODE> directive controls the output format
+ of the printcap file. The default is to generate a BSD printcap file.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="PrintcapGUI">PrintcapGUI</A></H3>
+<HR>
+<H4>Example</H4>
+<UL>
+<PRE>
+PrintcapGUI /usr/bin/glpoptions
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>PrintcapGUI</CODE> directive sets the program to use when
+ displaying an option panel from an IRIX application that uses the
+ Impressario print API. The default program is the ESP Print Pro
+ &quot;glpoptions&quot; GUI.</P>
+<P>The program must accept the <CODE>-d</CODE> option to specify a
+ printer and the <CODE>-o</CODE> option to specify one or more options.
+ After allowing the user to select/change options, the program must then
+ write the list of printing options without the <CODE>-o</CODE> to the
+ standard output.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="RemoteRoot">RemoteRoot</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+RemoteRoot remroot
+RemoteRoot root
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>RemoteRoot</CODE> directive sets the username for
+ unauthenticated root requests from remote hosts. The default username
+ is<VAR> remroot</VAR>. Setting <CODE>RemoteRoot</CODE> to<VAR> root</VAR>
+ effectively disables this security mechanism.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="RequestRoot">RequestRoot</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+RequestRoot /var/spool/cups
+RequestRoot /foo/bar/spool/cups
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>RequestRoot</CODE> directive sets the directory for
+ incoming IPP requests and HTML forms. If an absolute path is not
+ provided then it is assumed to be relative to the<A HREF="#ServerRoot">
+ <CODE>ServerRoot</CODE></A> directory. The default request directory is<VAR>
+ /var/spool/cups</VAR>.
+<!-- NEED 4in -->
+</P>
+<H3><A NAME="Require">Require</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Require group foo bar
+Require user john mary
+Require valid-user
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Require</CODE> directive specifies that authentication is
+ required for the resource. The <CODE>group</CODE> keyword specifies
+ that the authenticated user must be a member of one or more of the
+ named groups that follow.</P>
+<P>The <CODE>user</CODE> keyboard specifies that the authenticated user
+ must be one of the named users that follow.</P>
+<P>The <CODE>valid-user</CODE> keyword specifies that any authenticated
+ user may access the resource.</P>
+<P>The default is to do no authentication. This directive must appear
+ inside a<A HREF="#Location"> <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="RIPCache">RIPCache</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+RIPCache 8m
+RIPCache 1g
+RIPCache 2048k
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>RIPCache</CODE> directive sets the size of the memory cache
+ used by Raster Image Processor (&quot;RIP&quot;) filters such as <CODE>
+imagetoraster</CODE> and <CODE>pstoraster</CODE>. The size can be
+ suffixed with a &quot;k&quot; for kilobytes, &quot;m&quot; for megabytes, or &quot;g&quot; for
+ gigabytes. The default cache size is &quot;8m&quot;, or 8 megabytes.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="RunAsUser">RunAsUser</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+RunAsUser Yes
+RunAsUser No
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>RunAsUser</CODE> directive controls whether the scheduler
+ runs as the unpriviledged user account (usually <CODE>lp</CODE>). The
+ default is <CODE>No</CODE> which leaves the scheduler running as the <CODE>
+root</CODE> user.</P>
+<P><B>Note:</B> Running as a non-priviledged user may prevent LPD and
+ locally connected printers from working due to permission problems. The
+ <CODE>lpd</CODE> backend will automatically use a non-priviledged mode
+ that is not 100% compliant with RFC 1179. The <CODE>parallel</CODE>, <CODE>
+serial</CODE>, and <CODE>usb</CODE> backends will need write access to
+ the corresponding device files.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Satisfy">Satisfy</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Satisfy all
+Satisfy any
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Satisfy</CODE> directive specifies whether all conditions
+ must be satisfied to allow access to the resource. If set to <CODE>all</CODE>
+, then all authentication and access control conditions must be satified
+ to allow access.</P>
+<P>Setting <CODE>Satisfy</CODE> to <CODE>any</CODE> allows a user to
+ gain access if the authentication or access control requirements are
+ satisfied. For example, you might require authentication for remote
+ access, but allow local access without authentication.</P>
+<P>The default is <CODE>all</CODE>. This directive must appear inside a<A
+HREF="#Location"> <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerAdmin">ServerAdmin</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerAdmin user@host
+ServerAdmin root@foo.bar.com
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerAdmin</CODE> directive identifies the email address
+ for the administrator on the system. By default the administrator email
+ address is <CODE>root@server</CODE>, where <CODE>server</CODE> is the
+ server name.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerBin">ServerBin</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerBin /usr/lib/cups
+ServerBin /foo/bar/lib/cups
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerBin</CODE> directive sets the directory for
+ server-run executables. If an absolute path is not provided then it is
+ assumed to be relative to the<A HREF="#ServerRoot"> <CODE>ServerRoot</CODE>
+</A> directory. The default executable directory is<VAR> /usr/lib/cups</VAR>
+.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerCertificate">ServerCertificate</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerCertificate /etc/cups/ssl/server.crt
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerCertificate</CODE> directive specifies the location
+ of the SSL certificate file used by the server when negotiating
+ encrypted connections. The certificate must not be encrypted (password
+ protected) since the scheduler normally runs in the background and will
+ be unable to ask for a password. The default certificate file is<VAR>
+ /etc/cups/ssl/server.crt</VAR>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerKey">ServerKey</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerKey /etc/cups/ssl/server.key
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerKey</CODE> directive specifies the location of the
+ SSL private key file used by the server when negotiating encrypted
+ connections. The default key file is<VAR> /etc/cups/ssl/server.crt</VAR>
+.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerName"></A>ServerName</H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerName foo.domain.com
+ServerName myserver.domain.com
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerName</CODE> directive specifies the hostname that is
+ reported to clients. By default the server name is the hostname.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerRoot">ServerRoot</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerRoot /etc/cups
+ServerRoot /foo/bar/cups
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerRoot</CODE> directive specifies the absolute path to
+ the server configuration and state files. It is also used to resolve
+ relative paths in the<VAR> cupsd.conf</VAR> file. The default server
+ directory is<VAR> /etc/cups</VAR>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="SSLListen">SSLListen</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+SSLListen 127.0.0.1:443
+SSLListen 192.0.2.1:443
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>SSLListen</CODE> directive specifies a network address and
+ port to listen for secure connections. Multiple <CODE>SSLListen</CODE>
+ directives can be provided to listen on multiple addresses.</P>
+<P>The <CODE>SSLListen</CODE> directive is similar to the<A HREF="#SSLPort">
+ <CODE>SSLPort</CODE></A> directive but allows you to restrict access to
+ specific interfaces or networks.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="SSLPort">SSLPort</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+SSLPort 443
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>SSLPort</CODE> directive specifies a port to listen on for
+ secure connections. Multiple <CODE>SSLPort</CODE> lines can be
+ specified to listen on multiple ports.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="SystemGroup">SystemGroup</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+SystemGroup sys
+SystemGroup system
+SystemGroup root
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>SystemGroup</CODE> directive specifies the system
+ administration group for <CODE>System</CODE> authentication. More
+ information can be found later in this chapter in<A HREF="#PRINTING_SECURITY">
+ &quot;Printing System Security&quot;</A>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="TempDir">TempDir</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+TempDir /var/tmp
+TempDir /foo/bar/tmp
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>TempDir</CODE> directive specifies an absolute path for the
+ directory to use for temporary files. The default directory is<VAR>
+ /var/tmp</VAR>.</P>
+<P>Temporary directories must be world-writable and should have the
+ &quot;sticky&quot; permission bit enabled so that other users cannot delete
+ filter temporary files. The following commands will create an
+ appropriate temporary directory called<VAR> /foo/bar/tmp</VAR>:</P>
+<UL>
+<PRE>
+<B>mkdir /foo/bar/tmp ENTER</B>
+<B>chmod a+rwxt /foo/bar/tmp ENTER</B>
+</PRE>
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="Timeout">Timeout</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Timeout 300
+Timeout 90
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Timeout</CODE> directive controls the amount of time to
+ wait before an active HTTP or IPP request times out. The default
+ timeout is 300 seconds.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="User">User</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+User lp
+User guest
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>User</CODE> directive specifies the UNIX user that filter
+ and CGI programs run as. The default user is <CODE>lp</CODE>.
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="PRINTING_SECURITY">Printing System Security</A></H2>
+<P>CUPS provides support for address, certificate, and password (Basic
+ and Digest) based authentication and access control. Certificate and
+ password authentication provide ways to limit access to individual
+ people or groups.</P>
+<P>Address based access control allows you to limit access to specific
+ systems, networks, or domains. While this does not provide
+ authentication, it does allow you to limit the potential users of your
+ system efficiently.</P>
+<P>CUPS maintains a list of locations that have access control and/or
+ authentication enabled. Locations are specified using the<A HREF="#Location">
+ <CODE>Location</CODE></A> directive:</P>
+<UL>
+<PRE>
+&lt;Location /resource&gt;
+<A HREF="#AuthClass">AuthClass</A> ...
+<A HREF="#AuthGroupName">AuthGroupName</A> ...
+<A HREF="#AuthType">AuthType</A> ...
+
+<A HREF="#Order">Order</A> ...
+<A HREF="#Allow">Allow</A> from ...
+<A HREF="#Deny">Deny</A> from ...
+&lt;/Location&gt;
+</PRE>
+</UL>
+<P>Locations generally follow the directory structure of the<A HREF="#DocumentRoot">
+ <CODE>DocumentRoot</CODE></A> directory, however CUPS does have several
+ virtual locations for administration, classes, jobs, and printers:
+<CENTER>
+<TABLE BORDER="1">
+<TR><TH>Location</TH><TH>Description</TH></TR>
+<TR><TD>/admin</TD><TD>The path for all administration operations.</TD></TR>
+<TR><TD>/classes</TD><TD>The path for all classes.</TD></TR>
+<TR><TD>/classes/name</TD><TD>The resource for class <CODE>name</CODE>.</TD>
+</TR>
+<TR><TD>/jobs</TD><TD>The path for all jobs.</TD></TR>
+<TR><TD>/jobs/id</TD><TD>The resource for job <CODE>id</CODE>.</TD></TR>
+<TR><TD>/printers</TD><TD>The path for all printers.</TD></TR>
+<TR><TD>/printers/name</TD><TD>The path for printer <CODE>name</CODE>.</TD>
+</TR>
+<TR><TD>/printers/name.ppd</TD><TD>The PPD file path for printer <CODE>
+name</CODE>.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="CERTIFICATES">Authentication Using Certificates</A></H3>
+<P>CUPS supports a local certificate-based authentication scheme that
+ can be used in place of <CODE>Basic</CODE> or <CODE>Digest</CODE>
+ authentication by clients connecting through the <CODE>localhost</CODE>
+ interface. Certificate authentication is not supported or allowed from
+ clients on any other interface.</P>
+<P>Certificates are 128-bit random numbers that refer to an internal
+ authentication record in the server. A client connecting via the <CODE>
+localhost</CODE> interface sends a request with an authorization header
+ of:</P>
+<UL>
+<PRE>
+Authorization: Local 0123456789ABCDEF0123456789ABCDEF
+</PRE>
+</UL>
+<P>The server then looks up the local certificate and authenticates
+ using the username associated with it.</P>
+<P>Certificates are generated by the server automatically and stored in
+ the<VAR> /etc/cups/certs</VAR> directory using the process ID of the
+ CGI program started by the server. Certificate files are only readable
+ by the<A HREF="#User"> <CODE>User</CODE></A> and<A HREF="#Group"> <CODE>
+Group</CODE></A> defined in the<VAR> cupsd.conf</VAR> file. When the CGI
+ program ends the certificate is removed and invalidated automatically.</P>
+<P>The special file<VAR> /etc/cups/certs/0</VAR> defines the<I> root
+ certificate</I> which can be used by any client running as the
+ super-user or another user that is part of the group defined by the<A HREF="#SystemGroup">
+ <CODE>SystemGroup</CODE></A> directive. The root certificate is
+ automatically regenerated every 5 minutes.</P>
+<H3><A NAME="7_5_2">Using Basic Authentication</A></H3>
+<P>Basic authentication uses UNIX users and passwords to authenticate
+ access to resources such as printers and classes, and to limit access
+ to administrative functions.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Basic authentication sends the username and password Base64 encoded
+ from the client to the server, so it offers no protection against
+ eavesdropping. This means that a malicious user can monitor network
+ packets and discover valid users and passwords that could result in a
+ serious compromise in network security. Use Basic authentication with
+ extreme care.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<P>The CUPS implementation of Basic authentication does not allow access
+ through user accounts without a password. If you try to authenticate
+ using an account without a password, your access will be immediately
+ blocked.</P>
+<P>Once a valid username and password is authenticated by CUPS, any
+ additional group membership requirements are checked.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>The root user is considered by CUPS to be a member of every group.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 1in -->
+<P>Use the <CODE>AuthType</CODE> directive to enable Basic
+ authentication:</P>
+<UL>
+<PRE>
+AuthType Basic
+</PRE>
+</UL>
+
+<!-- NEED 7in -->
+<H3><A NAME="7_5_3">Using Digest Authentication</A></H3>
+<P>Digest authentication uses users and passwords defined in the<VAR>
+ /etc/cups/passwd.md5</VAR> file to authenticate access to resources
+ such as printers and classes, and to limit access to administrative
+ functions.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Unlike Basic authentication, Digest passes the MD5 sum (basically a
+ complicated checksum) of the username and password instead of the
+ strings themselves. Also, Digest authentication does not use the UNIX
+ password file, so if an attacker does discover the original password it
+ is less likely to result in a serious security problem so long as you
+ use a different UNIX password than the corresponding Digest password.</P>
+<P>The current CUPS implementation of Digest authentication uses the
+ client's hostname or IP address for the &quot;nonce&quot; value. The nonce value
+ is an additional string added to the username and password to make
+ guessing the password more difficult. The server checks that the nonce
+ value matches the client's hostname or address and rejects the MD5 sum
+ if it doesn't. Future versions of CUPS will support Digest &quot;session&quot;
+ authentication which adds the request data to the MD5 sum, providing
+ even better authentication and security.</P>
+<P>Digest authentication does not guarantee that an attacker cannot gain
+ unauthorized access, but it is safer than Basic authentication and
+ should be used in place of Basic authentication whenever possible.<B>
+ Support for Digest authentication in web browsers is not yet
+ universally available.</B></P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 2in -->
+<P>The <CODE>lppasswd(1)</CODE> command is used to add, change, or
+ remove accounts from the<VAR> passwd.md5</VAR> file. To add a user to
+ the default system group, type:</P>
+<UL>
+<PRE>
+<B>lppasswd -a user ENTER</B>
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<P>Once added, a user can change his/her password by typing:</P>
+<UL>
+<PRE>
+<B>lppasswd ENTER</B>
+Old password: <B>(password) ENTER</B> [password is not echoed]
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE>
+</UL>
+
+<!-- NEED 1in -->
+<P>To remove a user from the password file, type:</P>
+<UL>
+<PRE>
+<B>lppasswd -x user ENTER</B>
+</PRE>
+</UL>
+<P>Once a valid username and password is authenticated by CUPS, any
+ additional group membership requirements are checked.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>The root user is considered by CUPS to be a member of every group.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<P>Use the <CODE>AuthType</CODE> directive to enable Digest
+ authentication:</P>
+<UL>
+<PRE>
+AuthType Digest
+</PRE>
+</UL>
+<H3><A NAME="7_5_4">System and Group Authentication</A></H3>
+<P>The<A HREF="#AuthClass"> <CODE>AuthClass</CODE></A> directive
+ controls the level of authentication to perform. <CODE>System</CODE>
+ and <CODE>Group</CODE> authentication extend the normal user-based
+ authentication to require membership in a UNIX group. For <CODE>System</CODE>
+ authentication each user must belong to the <CODE>sys</CODE>, <CODE>
+system</CODE>, or <CODE>root</CODE> group; the actual group depends on
+ the operating system.</P>
+<P>For <CODE>Group</CODE> authentication each user must belong to the
+ group named by the<A HREF="#AuthGroupName"> <CODE>AuthGroupName</CODE></A>
+ directive:</P>
+<UL>
+<PRE>
+&lt;Location /path&gt;
+AuthType Digest
+AuthClass Group
+AuthGroupName mygroup
+&lt;/Location&gt;
+</PRE>
+</UL>
+<P>The named group must be a valid UNIX user group, usually defined in
+ the<VAR> /etc/group</VAR> or<VAR> /etc/netgroup</VAR> files.
+ Additionally, when using Digest authentication you need to create user
+ accounts with the named group:</P>
+<UL>
+<PRE>
+<B>lppasswd -g mygroup -a user ENTER</B>
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE>
+</UL>
+
+<!-- NEW PAGE -->
+<H2><A NAME="PRINTER_ACCOUNTING">Printer Accounting</A></H2>
+<P>CUPS maintains a log of all accesses, errors, and pages that are
+ printed. The log files are normally stored in the<VAR> /var/log/cups</VAR>
+ directory. You can change this by editing the<VAR> /etc/cups/cupsd.conf</VAR>
+ configuration file.</P>
+<H3><A NAME="7_6_1">The access_log File</A></H3>
+<P>The<VAR> access_log</VAR> file lists each HTTP resource that is
+ accessed by a web browser or CUPS/IPP client. Each line is in the
+ so-called &quot;Common Log Format&quot; used by many web servers and web
+ reporting tools:</P>
+<UL>
+<PRE>
+host group user date-time \&quot;method resource version\&quot; status bytes
+
+127.0.0.1 - - [20/May/1999:19:20:29 +0000] &quot;POST /admin/ HTTP/1.1&quot; 401 0
+127.0.0.1 - mike [20/May/1999:19:20:31 +0000] &quot;POST /admin/ HTTP/1.1&quot; 200 0
+</PRE>
+</UL>
+<P>The<I> host</I> field will normally only be an IP address unless you
+ have enabled the<A HREF="#HostNameLookups"> <CODE>HostNameLookups</CODE>
+</A> directive in the<VAR> cupsd.conf</VAR> file.</P>
+<P>The<I> group</I> field always contains &quot;-&quot; in CUPS.</P>
+<P>The<I> user</I> field is the authenticated username of the requesting
+ user. If no username and password is supplied for the request then this
+ field contains &quot;-&quot;.</P>
+<P>The<I> date-time</I> field is the date and time of the request in
+ local time and is in the format:</P>
+<UL>
+<PRE>
+[DD/MON/YYYY:HH:MM:SS +ZZZZ]
+</PRE>
+</UL>
+<P>where<I> ZZZZ</I> is the timezone offset in hours and minutes from
+ Greenwich Mean Time (a.k.a. GMT a.k.a. ZULU.)</P>
+<P>The<I> method</I> field is the HTTP method used (&quot;GET&quot;, &quot;PUT&quot;,
+ &quot;POST&quot;, etc.)</P>
+<P>The<I> resource</I> field is the filename of the requested resource.</P>
+<P>The<I> version</I> field is the HTTP specification version used by
+ the client. For CUPS clients this will always be &quot;HTTP/1.1&quot;.</P>
+<P>The<I> status</I> field contains the HTTP result status of the
+ request. Usually it is &quot;200&quot;, but other HTTP status codes are possible.
+ For example, 401 is the &quot;unauthorized access&quot; status in the example
+ above.</P>
+<P>The<I> bytes</I> field contains the number of bytes in the request.
+ For POST requests the<I> bytes</I> field contains the number of bytes
+ that was received from the client.</P>
+<H3><A NAME="7_6_2">The error_log File</A></H3>
+<P>The<VAR> error_log</VAR> file lists messages from the scheduler
+ (errors, warnings, etc.):</P>
+<UL>
+<PRE>
+level date-time message
+
+I [20/May/1999:19:18:28 +0000] Job 1 queued on 'DeskJet' by 'mike'.
+I [20/May/1999:19:21:02 +0000] Job 2 queued on 'DeskJet' by 'mike'.
+I [20/May/1999:19:22:24 +0000] Job 2 was cancelled by 'mike'.
+</PRE>
+</UL>
+<P>The<I> level</I> field contains the type of message:</P>
+<UL>
+<LI><CODE>E</CODE> - An error occurred.</LI>
+<LI><CODE>W</CODE> - The server was unable to perform some action.</LI>
+<LI><CODE>I</CODE> - Informational message.</LI>
+<LI><CODE>D</CODE> - Debugging message.</LI>
+</UL>
+<P>The<I> date-time</I> field contains the date and time of when the
+ page started printing. The format of this field is identical to the<I>
+ data-time</I> field in the<VAR> access_log</VAR> file.</P>
+<P>The<I> message</I> fields contains a free-form textual message.</P>
+<H3><A NAME="7_6_3">The page_log File</A></H3>
+<P>The<VAR> page_log</VAR> file lists each page that is sent to a
+ printer. Each line contains the following information:</P>
+<UL>
+<PRE>
+printer user job-id date-time page-number num-copies job-billing
+
+DeskJet root 2 [20/May/1999:19:21:05 +0000] 1 0 acme-123
+</PRE>
+</UL>
+<P>The<I> printer</I> field contains the name of the printer that
+ printed the page. If you send a job to a printer class, this field will
+ contain the name of the printer that was assigned the job.</P>
+<P>The<I> user</I> field contains the name of the user (the IPP <CODE>
+requesting-user-name</CODE> attribute) that submitted this file for
+ printing.</P>
+<P>The<I> job-id</I> field contains the job number of the page being
+ printed. Job numbers are reset to 1 whenever the CUPS server is
+ started, so don't depend on this number being unique!</P>
+<P>The<I> date-time</I> field contains the date and time of when the
+ page started printing. The format of this field is identical to the<I>
+ data-time</I> field in the<VAR> access_log</VAR> file.</P>
+<P>The<I> page-number</I> and<I> num-pages</I> fields contain the page
+ number and number of copies being printed of that page. For printer
+ that can not produce copies on their own, the<I> num-pages</I> field
+ will always be 1.</P>
+<P>The<I> job-billing</I> field contains a copy of the <CODE>job-billing</CODE>
+ attribute provided with the IPP <CODE>create-job</CODE> or <CODE>
+print-job</CODE> requests or &quot;-&quot; if none was provided.
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="FILE_TYPING_FILTERING">File Typing and Filtering</A></H2>
+<P>CUPS provides a MIME-based file typing and filtering mechanism to
+ convert files to a printable format for each printer. On startup the
+ CUPS server reads MIME database files from the<VAR> /etc/cups</VAR>
+ directory (or a directory specified by the<A HREF="#ServerRoot"> <CODE>
+ServerRoot</CODE></A> directive) to build a file type and conversion
+ database in memory. These database files are plain ASCII text and can
+ be edited with your favorite text editor.</P>
+<P>The<VAR> mime.types</VAR> and<VAR> mime.convs</VAR> files define the
+ standard file types and filters that are available on the system.</P>
+<H3><A NAME="7_7_1">mime.types</A></H3>
+<P>The<VAR> mime.types</VAR> file defines the known file types. Each
+ line of the file starts with the MIME type and may be followed by one
+ or more file type recognition rules. For example, the <CODE>text/html</CODE>
+ file type is defined as:</P>
+<UL>
+<PRE>
+text/html html htm \
+ printable(0,1024) + \
+ (string(0,&quot;&lt;HTML&gt;&quot;) string(0,&quot;&lt;!DOCTYPE&quot;))
+</PRE>
+</UL>
+<P>The first two rules say that any file with an extension of<VAR> .html</VAR>
+ or<VAR> .htm</VAR> is a HTML file. The third rule says that any file
+ whose first 1024 characters are printable text and starts with the
+ strings <CODE>&lt;HTML&gt;</CODE> or <CODE>&lt;!DOCTYPE</CODE> is a HTML file as
+ well.</P>
+<P>The first two rules deal solely with the name of the file being
+ typed. This is useful when the original filename is known, however for
+ print files the server doesn't have a filename to work with. The third
+ rule takes care of this possibility and automatically figures out the
+ file type based upon the contents of the file instead.</P>
+<P>The available tests are:</P>
+<UL>
+<LI><CODE>( expr )</CODE> - Parenthesis for expression grouping</LI>
+<LI><CODE>+</CODE> - Logical AND</LI>
+<LI><CODE>,</CODE> or whitespace - Logical OR</LI>
+<LI><CODE>!</CODE> - Logical NOT</LI>
+<LI><CODE>match(&quot;pattern&quot;)</CODE> - Pattern match on filename</LI>
+<LI><CODE>extension</CODE> - Pattern match on &quot;*.extension&quot;</LI>
+<LI><CODE>ascii(offset,length)</CODE> - True if bytes are valid
+ printable ASCII (CR, NL, TAB, BS, 32-126)</LI>
+<LI><CODE>printable(offset,length)</CODE> - True if bytes are printable
+ 8-bit chars (CR, NL, TAB, BS, 32-126, 160-254)</LI>
+<LI><CODE>string(offset,&quot;string&quot;)</CODE> - True if bytes are identical
+ to string</LI>
+<LI><CODE>contains(offset,range,&quot;string&quot;)</CODE> - True if the range of
+ bytes contains the string</LI>
+<LI><CODE>char(offset,value)</CODE> - True if byte is identical</LI>
+<LI><CODE>short(offset,value)</CODE> - True if 16-bit integer is
+ identical (network or &quot;big-endian&quot; byte order)</LI>
+<LI><CODE>int(offset,value)</CODE> - True if 32-bit integer is identical
+ (network or &quot;big-endian&quot; byte order)</LI>
+<LI><CODE>locale(&quot;string&quot;)</CODE> - True if current locale matches
+ string</LI>
+</UL>
+<P>All numeric values can be in decimal (123), octal (0123), or
+ hexadecimal (0x123) as desired.
+<!-- NEED 2.5in -->
+</P>
+<P>Strings can be in quotes, all by themselves, as a string of
+ hexadecimal values, or some combination:</P>
+<UL>
+<PRE>
+&quot;string&quot;
+'string'
+string
+&lt;737472696e67&gt;
+&lt;7374&gt;ring
+</PRE>
+</UL>
+<P>As shown in the <CODE>text/html</CODE> example, rules can continue on
+ multiple lines using the backslash (\) character. A more complex
+ example is the <CODE>image/jpeg</CODE> rules:</P>
+<UL>
+<PRE>
+image/jpeg jpeg jpg jpe string(0,&lt;FFD8FF&gt;) &amp;&amp;\
+ (char(3,0xe0) char(3,0xe1) char(3,0xe2) char(3,0xe3)\
+ char(3,0xe4) char(3,0xe5) char(3,0xe6) char(3,0xe7)\
+ char(3,0xe8) char(3,0xe9) char(3,0xea) char(3,0xeb)\
+ char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef))
+</PRE>
+</UL>
+<P>This rule states that any file with an extension of<VAR> .jpeg</VAR>,<VAR>
+ .jpg</VAR>, or<VAR> .jpe</VAR> is a JPEG file. In addition, any file
+ starting with the hexadecimal string <CODE>&lt;FFD8FF&gt;</CODE> (JPEG
+ Start-Of-Image) followed by a character between and including <CODE>
+0xe0</CODE> and <CODE>0xef</CODE> (JPEG APPn markers) is also a JPEG
+ file.</P>
+<H3><A NAME="7_7_2">mime.convs</A></H3>
+<P>The<VAR> mime.convs</VAR> file defines all of the filter programs
+ that are known to the system. Each line consists of:</P>
+<UL>
+<PRE>
+source destination cost program
+
+text/plain application/postscript 50 texttops
+application/vnd.cups-postscript application/vnd.cups-raster 50 pstoraster
+image/* application/vnd.cups-postscript 50 imagetops
+image/* application/vnd.cups-raster 50 imagetoraster
+</PRE>
+</UL>
+<P>The<I> source</I> field is a MIME type, optionally using a wildcard
+ for the super-type or sub-type (e.g. &quot;text/plain&quot;, &quot;image/*&quot;,
+ &quot;*/postscript&quot;).</P>
+<P>The<I> destination</I> field is a MIME type defined in the<VAR>
+ mime.types</VAR> file.</P>
+<P>The<I> cost</I> field defines a relative cost for the filtering
+ operation from 1 to 100. The cost is used to choose between two
+ different sets of filters when converting a file. For example, to
+ convert from <CODE>image/jpeg</CODE> to <CODE>
+application/vnd.cups-raster</CODE>, you could use the <CODE>imagetops</CODE>
+ and <CODE>pstoraster</CODE> filters for a total cost of 100, or the <CODE>
+imagetoraster</CODE> filter for a total cost of 50.</P>
+<P>The<I> program</I> field defines the filter program to run; the
+ special program &quot;-&quot; can be used to make two file types equivalent. The
+ program must accept the standard filter arguments and environment
+ variables described in the CUPS Interface Design Description and CUPS
+ Software Programmers Manual:</P>
+<UL>
+<PRE>
+program job user title options [filename]
+</PRE>
+</UL>
+<P>If specified, the<I> filename</I> argument defines a file to read
+ when filtering, otherwise the filter must read from the standard input.
+ All filtered output must go to the standard output.
+<!-- NEED 4in -->
+</P>
+<H3><A NAME="7_7_3">Adding Filetypes and Filters</A></H3>
+<P>Adding a new file type or filter is fairly straight-forward. Rather
+ than adding the new type and filter to the<VAR> mime.types</VAR> and<VAR>
+ mime.convs</VAR> files which are overwritten when you upgrade to a new
+ version of CUPS, you simple need to create new files with<VAR> .types</VAR>
+ and<VAR> .convs</VAR> extensions in the<VAR> /etc/cups</VAR> directory.
+ We recommend that you use the product or format name, e.g.:</P>
+<UL>
+<PRE>
+myproduct.types
+myproduct.convs
+</PRE>
+</UL>
+<P>If you are providing a filter for a common file format or printer,
+ add the company or author name:</P>
+<UL>
+<PRE>
+acme-msword.types
+acme.msword.convs
+</PRE>
+</UL>
+<P>This will help to prevent name collisions if you install many
+ different file types and filters.</P>
+<P>Once you choose the names for these files, create them using your
+ favorite text editor as described earlier in this chapter. Once you
+ have created the files, restart the <CODE>cupsd</CODE> process as
+ described earlier in<A HREF="#RESTARTING"> &quot;Restarting the CUPS Server&quot;</A>
+.</P>
+<H3><A NAME="7_7_4">Printer Drivers and PPD Files</A></H3>
+<P>Most CUPS printer drivers utilize one or more printer-specific
+ filters and a PPD file for each printer model. Printer driver filters
+ are registered via the PPD file using <CODE>cupsFilter</CODE>
+ attributes:</P>
+<UL>
+<PRE>
+*cupsFilter: &quot;application/vnd.cups-raster 0 rastertohp&quot;
+</PRE>
+</UL>
+<P>The filter is specified using the source file type only; the
+ destination file type is assumed to be <CODE>printer/name</CODE> -
+ suitable for sending to the printer.</P>
+<H3><A NAME="7_7_5">Writing Your Own Filter or Printer Driver</A></H3>
+<P>CUPS supports an unlimited number of file formats and filters, and
+ can handle any printer. If you'd like to write a filter or printer
+ driver for your favorite file format or printer, consult the CUPS
+ Software Programmers Manual for step-by-step instructions.</P>
+<H1 ALIGN="RIGHT"><A NAME="PRINTING_OTHER">7 - Printing with Other
+ Systems</A></H1>
+<P>This chapter describes how to print from client systems that use the
+ LPD, Mac OS, or Windows printing protocols.</P>
+<H2><A NAME="8_1">The Basics</A></H2>
+<P>CUPS is based on the IPP protocol, so any system that supports IPP
+ can send jobs to and receive jobs from CUPS automatically. However, not
+ all systems support IPP yet. This chapter will show you how to connect
+ these systems to your CUPS server, either to accept jobs from your
+ server for printing, or to send jobs to your server.</P>
+<H2><A NAME="8_2">Printing from LPD Clients</A></H2>
+<P>CUPS supports limited functionality for LPD-based clients. With LPD
+ you can print files to specific printers, list the queue status, and so
+ forth. However, the automatic client configuration and printer options
+ are not supported by the LPD protocol, so you must manually configure
+ each client for the printers it needs to access.</P>
+<P>The <CODE>cups-lpd(8)</CODE> program provides support for LPD clients
+ and can be used from either the <CODE>inetd(8)</CODE> or <CODE>
+xinetd(8)</CODE> programs. Add the following line to the<VAR>
+ /etc/inetd.conf</VAR> file to enable LPD support on your server through
+ the <CODE>inetd</CODE> program:</P>
+<UL>
+<PRE>
+printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd
+</PRE>
+</UL>
+<P>The path to the <CODE>cups-lpd</CODE> may vary depending on your
+ installation.</P>
+<P>Once you have added this line, send the <CODE>inetd</CODE> process a <CODE>
+HUP</CODE> signal or reboot the system:</P>
+<UL>
+<PRE>
+<B>killall -HUP inetd ENTER</B> [IRIX and some versions of Linux]
+<B>kill -HUP <I>pid</I> ENTER [Others]</B>
+<B>reboot ENTER [For all systems if the HUP signal fails]</B>
+</PRE>
+</UL>
+<P>If you are using the <CODE>xinetd</CODE> program, create a file named<VAR>
+ /etc/xinetd.d/printer</VAR> containing the following lines:</P>
+<UL>
+<PRE>
+service printer
+{
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ user = lp
+ server = /usr/lib/cups/daemon/cups-lpd
+}
+</PRE>
+</UL>
+<P>The <CODE>xinetd</CODE> program automatically reads the new
+ configuration file and enables LPD printing support.
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B>Warning:</B>
+<P><CODE>cups-lpd</CODE> currently does not perform any access control
+ based on the settings in<VAR> cupsd.conf</VAR> or in the<VAR>
+ hosts.allow</VAR> or<VAR> hosts.deny</VAR> files used by TCP wrappers.
+ Therefore, running <CODE>cups-lpd</CODE> on your server will allow any
+ computer on your network (and perhaps the entire Internet) to print to
+ your server.</P>
+<P>While <CODE>xinetd</CODE> has built-in access control support, you
+ should use the TCP wrappers package with <CODE>inetd</CODE> to limit
+ access to only those computers that should be able to print through
+ your server.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H2><A NAME="8_3">Printing to LPD Servers</A></H2>
+<P>CUPS provides the <CODE>lpd</CODE> backend for printing to LPD-based
+ servers and printers. Use a device URI of <CODE>lpd://server/name</CODE>
+ to print to a printer on an LPD server, where <CODE>server</CODE> is
+ the hostname or IP address of the server and <CODE>name</CODE> is the
+ queue name.</P>
+<P>Microsoft Windows NT provides an LPD service under the name &quot;TCP/IP
+ Printing Services&quot;. To enable LPD printing on NT, open the &quot;Services&quot;
+ control panel, select the &quot;TCP/IP Printing Services&quot; service, and click
+ on the &quot;Start&quot; button. Any shared printer will then be available via
+ the LPD protocol.</P>
+<H2><A NAME="8_4">Printing from Mac OS Clients</A></H2>
+<P>CUPS does not provide Mac OS support directly. However, there are
+ several free and commercial software packages that do.</P>
+<H3><A NAME="8_4_1">Columbia Appletalk Package (CAP)</A></H3>
+<P>Because the CAP LaserWriter server (<CODE>lwsrv(8)</CODE>) does not
+ support specification of PPD files, we do not recommend that you use
+ CAP with CUPS. However, you can run the <CODE>lpsrv</CODE> program for
+ limited printing with the command:</P>
+<UL>
+<PRE>
+lwsrv -n &quot;<I>Name</I>&quot; -p <I>printer</I> -a /usr/lib/adicts -f /usr/lib/LW+Fonts
+</PRE>
+</UL>
+<P>where <CODE>Name</CODE> is the name you want to use when sharing the
+ printer, and <CODE>printer</CODE> is the name of the CUPS print queue.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="8_4_2">XINET KA/Spool</A></H3>
+<P>To use your system as a print server for Mac OS clients, configure
+ each printer using a <CODE>papserver(8)</CODE> in the<VAR>
+ /usr/adm/appletalk/services</VAR> file, specifying the corresponding
+ PPD file in the<VAR> /etc/cups/ppd</VAR> directory for each printer.
+ For a printer named <CODE>MyPrinter</CODE> the entry would look like:</P>
+<UL>
+<PRE>
+/usr/etc/appletalk/papserver -I -L -P /etc/cups/ppd/MyPrinter.ppd \
+&quot;Printer Description&quot; MyPrinter
+</PRE>
+</UL>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Enter the text above on a single line without the backslash (\)
+ character.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="8_4_3">NetATalk</A></H3>
+<P>To use your system as a print server for Mac OS clients, configure
+ each printer in the<VAR> papd.conf</VAR> file, specifying the
+ corresponding PPD file in the<VAR> /etc/cups/ppd</VAR> directory for
+ each printer. For a printer named <CODE>MyPrinter</CODE> the entry
+ would look like:</P>
+<UL>
+<PRE>
+Printer Description:MyPrinter@MyServer:\
+ :pr=|/usr/bin/lp -d MyPrinter:\
+ :op=daemon:\
+ :pd=/etc/cups/ppd/MyPrinter.ppd:
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<H2><A NAME="8_5">Printing to Mac OS Servers</A></H2>
+<P>CUPS currently does not provide a backend to communicate with a Mac
+ OS server. However, you can write and install a short shell script in
+ the<VAR> /usr/lib/cups/backend</VAR> directory that sends a print file
+ using the appropriate command. The following is a short script that
+ will run the <CODE>papif</CODE> command provided with CAP.</P>
+<P>After copying this script to<VAR> /usr/lib/cups/backend/cap</VAR>,
+ specify a device URI of <CODE>cap://server/printer</CODE> to use this
+ backend with a print queue.
+<!-- NEED 8in -->
+</P>
+<UL>
+<PRE>
+<I>&quot;/usr/lib/cups/backend/cap&quot;</I>
+#!/bin/sh
+#
+# Usage: cap job user title copies options [filename]
+#
+
+# No arguments means show available devices...
+
+if test ${#argv} = 0; then
+ echo &quot;network cap \&quot;Unknown\&quot; \&quot;Mac OS Printer via CAP\&quot;&quot;
+ exit 0
+fi
+
+# Collect arguments...
+
+user=$2
+copies=$4
+
+if test ${#argv} = 5; then
+ # Get print file from stdin; copies have already been handled...
+ file=/var/tmp/$$.prn
+ copies=1
+ cat &gt; $file
+else
+ # Print file is on command-line...
+ file=$6
+fi
+
+# Create a dummy cap.printers file for this printer based
+# upon a device URI of &quot;cap://server/printer&quot;...
+
+echo $PRINTER/$DEVICE_URI | \
+ awk -F/ '{print $1 &quot;=&quot; $5 &quot;:LaserWriter@&quot; $4}' &gt; /var/tmp/$$.cap
+
+CAPPRINTERS=/var/tmp/$$.cap; export CAPPRINTERS
+
+# Send the file to the printer, once for each copy. This assumes that you
+# have properly initialized the cap.printers file...
+
+while [ $copies -gt 0 ]; do
+ papif -n $user &lt; $file
+
+ copies=`expr $copies - 1`
+done
+
+# Remove any temporary files...
+if test ${#argv} = 5; then
+ /bin/rm -f $file
+fi
+
+/bin/rm -f /var/tmp/$$.cap
+
+exit 0
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<H2><A NAME="8_6">Printing from Windows Clients</A></H2>
+<P>While CUPS does not provide Windows support directly, the free SAMBA
+ software package does. SAMBA version 2.0.6 is the first release of
+ SAMBA that supports CUPS. You can download SAMBA from:</P>
+<UL>
+<PRE>
+<A HREF="http://www.samba.org">http://www.samba.org</A>
+</PRE>
+</UL>
+<P>To configure SAMBA for CUPS, edit the<VAR> smb.conf</VAR> file and
+ replace the existing printing commands and options with the line:</P>
+<UL>
+<PRE>
+printing = cups
+printcap name = cups
+</PRE>
+</UL>
+<P>That's all there is to it! Remote users will now be able to browse
+ and print to printers on your system.</P>
+<H3><A NAME="8_6_1">Exporting Printer Drivers</A></H3>
+<P>You can optionally export printer drivers from your CUPS server using
+ the <CODE>cupsaddsmb</CODE> command and the SAMBA 2.2.0 or higher
+ software.</P>
+<P>Before you can export the printers you must download the current
+ Adobe PostScript printer drivers from the Adobe web site (<A HREF="http://www.adobe.com/">
+http://www.adobe.com/</A>). Use the free <CODE>unzip</CODE> software to
+ extract the files from the self-extracting ZIP file containing the
+ drivers; you will need the following files:</P>
+<UL>
+<PRE>
+ADFONTS.MFM
+ADOBEPS4.DRV
+ADOBEPS4.HLP
+ADOBEPS5.DLL
+ADOBEPSU.DLL
+ADOBEPSU.HLP
+DEFPRTR2.PPD
+ICONLIB.DLL
+PSMON.DLL
+</PRE>
+</UL>
+<P>Copy these files to the<VAR> /usr/share/cups/drivers</VAR> directory
+ - you may need to rename some of the files so the filenames are all
+ UPPERCASE.</P>
+<P>Next, add a <CODE>print$</CODE> share for the printer drivers to your<VAR>
+ smb.conf</VAR> file:</P>
+<UL>
+<PRE>
+[print$]
+ comment = Printer Drivers
+ path = /etc/samba/drivers
+ browseable = yes
+ guest ok = no
+ read only = yes
+ write list = root
+</PRE>
+</UL>
+<P>The directory for your printer drivers can be anywhere on the system;
+ just make sure it is writable by the users specified by the <CODE>write
+ list</CODE> directive. Also, make sure that you have SAMBA passwords
+ defined for each user in the <CODE>write list</CODE> using the <CODE>
+smbpasswd(1)</CODE> command. Otherwise you will not be able to
+ authenticate</P>
+<P>Finally, run the <CODE>cupsaddsmb</CODE> command to export the
+ printer drivers for one or more queues:</P>
+<UL>
+<PRE>
+<B>cupsaddsmb -U root printer1 ... printerN <I>ENTER</I></B>
+</PRE>
+</UL>
+<P>Running <CODE>cupsaddsmb</CODE> with the <CODE>-a</CODE> option will
+ export all printers:</P>
+<UL>
+<PRE>
+<B>cupsaddsmb -U root -a <I>ENTER</I></B>
+</PRE>
+</UL>
+<H2><A NAME="8_7">Printing to Windows Servers</A></H2>
+<P>CUPS can print to Windows servers in one of two ways. The first way
+ uses the LPD protocol on the CUPS system and the &quot;TCP/IP Printing
+ Services&quot; on the Windows system. You can find out more about this
+ configuration in the<A HREF="#LPD"> LPD</A> section earlier in this
+ chapter.</P>
+<P>The second way is through the Microsoft Server Message Block (&quot;SMB&quot;)
+ protocol. Support for this protocol is provided with the free SAMBA
+ software package. You can download SAMBA from:</P>
+<UL>
+<PRE>
+<A HREF="http://www.samba.org">http://www.samba.org</A>
+</PRE>
+</UL>
+<P>To configure CUPS for SAMBA, run the following command:</P>
+<UL>
+<PRE>
+<B>ln -s `which smbspool` /usr/lib/cups/backend/smb ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>smbspool(1)</CODE> program is provided with SAMBA starting
+ with SAMBA 2.0.6. Once you have made the link you can configure your
+ printers with one of the following device URIs:</P>
+<UL>
+<PRE>
+smb://workgroup/server/sharename
+smb://server/sharename
+smb://user:pass@workgroup/server/sharename
+smb://user:pass@server/sharename
+</PRE>
+</UL>
+<P>The <CODE>workgroup</CODE> name need only be specified if your system
+ is using a different workgroup. The <CODE>user:pass</CODE> strings are
+ required when printing to Windows NT servers or to shares with
+ passwords enabled under Windows 95 and 98.</P>
+<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - Software License Agreement</A></H1>
+<H2 ALIGN="CENTER"><A NAME="9_1">Common UNIX Printing System License
+ Agreement</A></H2>
+<P ALIGN="CENTER">Copyright 1997-2002 by Easy Software Products
+<BR> 44141 AIRPORT VIEW DR STE 204
+<BR> HOLLYWOOD, MARYLAND 20636-3111 USA
+<BR>
+<BR> Voice: +1.301.373.9600
+<BR> Email:<A HREF="mailto:cups-info@cups.org"> cups-info@cups.org</A>
+<BR> WWW:<A HREF="http://www.cups.org"> http://www.cups.org</A></P>
+<H3><A NAME="9_1_1">Introduction</A></H3>
+<P>The Common UNIX Printing System<SUP>TM</SUP>, (&quot;CUPS<SUP>TM</SUP>&quot;),
+ is provided under the GNU General Public License (&quot;GPL&quot;) and GNU
+ Library General Public License (&quot;LGPL&quot;), Version 2, with exceptions for
+ Apple operating systems and the OpenSSL toolkit. A copy of the
+ exceptions and licenses follow this introduction.</P>
+<P>The GNU LGPL applies to the CUPS API library, located in the &quot;cups&quot;
+ subdirectory of the CUPS source distribution and in the &quot;cups&quot; include
+ directory and library files in the binary distributions. The GNU GPL
+ applies to the remainder of the CUPS distribution, including the
+ &quot;pdftops&quot; filter which is based upon Xpdf and the CUPS imaging library.</P>
+<P>For those not familiar with the GNU GPL, the license basically allows
+ you to:</P>
+<UL>
+<LI>Use the CUPS software at no charge.</LI>
+<LI>Distribute verbatim copies of the software in source or binary form.</LI>
+<LI>Sell verbatim copies of the software for a media fee, or sell
+ support for the software.</LI>
+<LI>Distribute or sell printer drivers and filters that use CUPS so long
+ as source code is made available under the GPL.</LI>
+</UL>
+<P>What this license<B> does not</B> allow you to do is make changes or
+ add features to CUPS and then sell a binary distribution without source
+ code. You must provide source for any new drivers, changes, or
+ additions to the software, and all code must be provided under the GPL
+ or LGPL as appropriate. The only exceptions to this are the portions of
+ the CUPS software covered by the Apple operating system license
+ exceptions outlined later in this license agreement.</P>
+<P>The GNU LGPL relaxes the &quot;link-to&quot; restriction, allowing you to
+ develop applications that use the CUPS API library under other licenses
+ and/or conditions as appropriate for your application.</P>
+<H3><A NAME="9_1_2">License Exceptions</A></H3>
+<P>In addition, as the copyright holder of CUPS, Easy Software Products
+ grants the following special exceptions:</P>
+<OL>
+<LI><B>Apple Operating System Development License Exception</B>;
+<OL TYPE="a">
+<LI>Software that is developed by any person or entity for an Apple
+ Operating System (&quot;Apple OS-Developed Software&quot;), including but not
+ limited to Apple and third party printer drivers, filters, and backends
+ for an Apple Operating System, that is linked to the CUPS imaging
+ library or based on any sample filters or backends provided with CUPS
+ shall not be considered to be a derivative work or collective work
+ based on the CUPS program and is exempt from the mandatory source code
+ release clauses of the GNU GPL. You may therefore distribute linked
+ combinations of the CUPS imaging library with Apple OS-Developed
+ Software without releasing the source code of the Apple OS-Developed
+ Software. You may also use sample filters and backends provided with
+ CUPS to develop Apple OS-Developed Software without releasing the
+ source code of the Apple OS-Developed Software.</LI>
+<LI>An Apple Operating System means any operating system software
+ developed and/or marketed by Apple Computer, Inc., including but not
+ limited to all existing releases and versions of Apple's Darwin, Mac OS
+ X, and Mac OS X Server products and all follow-on releases and future
+ versions thereof.</LI>
+<LI>This exception is only available for Apple OS-Developed Software and
+ does not apply to software that is distributed for use on other
+ operating systems.</LI>
+<LI>All CUPS software that falls under this license exception have the
+ following text at the top of each source file:<BLOCKQUOTE>This file is
+ subject to the Apple OS-Developed Software exception.</BLOCKQUOTE></LI>
+</OL>
+</LI>
+<LI><B>OpenSSL Toolkit License Exception</B>;
+<OL TYPE="a">
+<LI>Easy Software Products explicitly allows the compilation and
+ distribution of the CUPS software with the OpenSSL Toolkit.</LI>
+</OL>
+</LI>
+</OL>
+<P>No developer is required to provide these exceptions in a derived
+ work.</P>
+<H3><A NAME="9_1_3">Trademarks</A></H3>
+<P>Easy Software Products has trademarked the Common UNIX Printing
+ System, CUPS, and CUPS logo. These names and logos may be used freely
+ in any direct port or binary distribution of CUPS. Please contract Easy
+ Software Products for written permission to use them in derivative
+ products. Our intention is to protect the value of these trademarks and
+ ensure that any derivative product meets the same high-quality
+ standards as the original.</P>
+<H3><A NAME="9_1_4">Binary Distribution Rights</A></H3>
+<P>Easy Software Products also sells rights to the CUPS source code
+ under a binary distribution license for vendors that are unable to
+ release source code for their drivers, additions, and modifications to
+ CUPS under the GNU GPL and LGPL. For information please contact us at
+ the address shown above.</P>
+<P>The Common UNIX Printing System provides a &quot;pdftops&quot; filter that is
+ based on the Xpdf software. For binary distribution licensing of this
+ software, please contact:<BLOCKQUOTE> Derek B. Noonburg
+<BR> Email:<A HREF="mailto:derekn@foolabs.com"> derekn@foolabs.com</A>
+<BR> WWW:<A HREF="http://www.foolabs.com/xpdf/">
+ http://www.foolabs.com/xpdf/</A></BLOCKQUOTE></P>
+<H3><A NAME="9_1_5">Support</A></H3>
+<P>Easy Software Products sells software support for CUPS as well as a
+ commercial printing product based on CUPS called ESP Print Pro. You can
+ find out more at our web site:</P>
+<UL>
+<PRE>
+<A HREF="http://www.easysw.com/">http://www.easysw.com/</A>
+</PRE>
+</UL>
+
+<!-- NEW PAGE -->
+<H2><A NAME="9_2">GNU GENERAL PUBLIC LICENSE</A></H2>
+<P>Version 2, June 1991</P>
+<PRE>
+Copyright 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim
+copies of this license document, but changing it is not allowed.
+</PRE>
+<H4>Preamble</H4>
+<P>The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public License is
+ intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users. This
+ General Public License applies to most of the Free Software
+ Foundation's software and to any other program whose authors commit to
+ using it. (Some other Free Software Foundation software is covered by
+ the GNU Library General Public License instead.) You can apply it to
+ your programs, too.</P>
+<P>When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it in
+ new free programs; and that you know you can do these things.</P>
+<P>To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the software, or if you modify it.</P>
+<P>For example, if you distribute copies of such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have. You must make sure that they, too, receive or can get the
+ source code. And you must show them these terms so they know their
+ rights.</P>
+<P>We protect your rights with two steps: (1) copyright the software,
+ and (2) offer you this license which gives you legal permission to
+ copy, distribute and/or modify the software.</P>
+<P>Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software. If the software is modified by someone else and passed on, we
+ want its recipients to know that what they have is not the original, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.</P>
+<P>Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that redistributors of a free
+ program will individually obtain patent licenses, in effect making the
+ program proprietary. To prevent this, we have made it clear that any
+ patent must be licensed for everyone's free use or not licensed at all.</P>
+<P>The precise terms and conditions for copying, distribution and
+ modification follow.</P>
+<H4>GNU GENERAL PUBLIC LICENSE
+<BR> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+<OL START="0">
+<LI>This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The &quot;Program&quot;, below,
+ refers to any such program or work, and a &quot;work based on the Program&quot;
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language. (Hereinafter, translation is included without limitation in
+ the term &quot;modification&quot;.) Each licensee is addressed as &quot;you&quot;.
+<P>Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ the Program is not restricted, and the output from the Program is
+ covered only if its contents constitute a work based on the Program
+ (independent of having been made by running the Program). Whether that
+ is true depends on what the Program does.</P>
+<LI>You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you conspicuously
+ and appropriately publish on each copy an appropriate copyright notice
+ and disclaimer of warranty; keep intact all the notices that refer to
+ this License and to the absence of any warranty; and give any other
+ recipients of the Program a copy of this License along with the
+ Program.
+<P>You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.</P>
+<LI>You may modify your copy or copies of the Program or any portion of
+ it, thus forming a work based on the Program, and copy and distribute
+ such modifications or work under the terms of Section 1 above, provided
+ that you also meet all of these conditions:
+<OL TYPE="a">
+<LI>You must cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change.</LI>
+<LI>You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any part
+ thereof, to be licensed as a whole at no charge to all third parties
+ under the terms of this License.</LI>
+<LI>if the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the most ordinary way, to print or display an announcement including
+ an appropriate copyright notice and a notice that there is no warranty
+ (or else, saying that you provide a warranty) and that users may
+ redistribute the program under these conditions, and telling the user
+ how to view a copy of this License. (Exception: if the Program itself
+ is interactive but does not normally print such an announcement, your
+ work based on the Program is not required to print an announcement.)</LI>
+</OL>
+<P>These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Program,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Program, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.</P>
+<P>Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.</P>
+<P>In addition, mere aggregation of another work not based on the
+ Program with the Program (or with a work based on the Program) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.</P>
+<LI>You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+<OL TYPE="a">
+<LI>Accompany it with the complete corresponding machine-readable source
+ code, which must be distributed under the terms of Sections 1 and 2
+ above on a medium customarily used for software interchange; or,</LI>
+<LI>Accompany it with a written offer, valid for at least three years,
+ to give any third party, for a charge no more than your cost of
+ physically performing source distribution, a complete machine-readable
+ copy of the corresponding source code, to be distributed under the
+ terms of Sections 1 and 2 above on a medium customarily used for
+ software interchange; or,</LI>
+<LI>Accompany it with the information you received as to the offer to
+ distribute corresponding source code. (This alternative is allowed only
+ for noncommercial distribution and only if you received the program in
+ object code or executable form with such an offer, in accord with
+ Subsection b above.)</LI>
+</OL>
+<P>The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to control
+ compilation and installation of the executable. However, as a special
+ exception, the source code distributed need not include anything that
+ is normally distributed (in either source or binary form) with the
+ major components (compiler, kernel, and so on) of the operating system
+ on which the executable runs, unless that component itself accompanies
+ the executable.</P>
+<P>If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent access
+ to copy the source code from the same place counts as distribution of
+ the source code, even though third parties are not compelled to copy
+ the source along with the object code.</P>
+<LI>You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt otherwise
+ to copy, modify, sublicense or distribute the Program is void, and will
+ automatically terminate your rights under this License. However,
+ parties who have received copies, or rights, from you under this
+ License will not have their licenses terminated so long as such parties
+ remain in full compliance.</LI>
+<LI>You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying the
+ Program or works based on it.</LI>
+<LI>Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject to
+ these terms and conditions. You may not impose any further restrictions
+ on the recipients' exercise of the rights granted herein. You are not
+ responsible for enforcing compliance by third parties to this License.</LI>
+<LI>If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all. For example, if a patent license
+ would not permit royalty-free redistribution of the Program by all
+ those who receive copies directly or indirectly through you, then the
+ only way you could satisfy both it and this License would be to refrain
+ entirely from distribution of the Program.
+<P>If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.</P>
+<P>It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.</P>
+<P>This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.</P>
+<LI>If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License may
+ add an explicit geographical distribution limitation excluding those
+ countries, so that distribution is permitted only in or among countries
+ not thus excluded. In such case, this License incorporates the
+ limitation as if written in the body of this License.</LI>
+<LI>The Free Software Foundation may publish revised and/or new versions
+ of the General Public License from time to time. Such new versions will
+ be similar in spirit to the present version, but may differ in detail
+ to address new problems or concerns.
+<P>Each version is given a distinguishing version number. If the Program
+ specifies a version number of this License which applies to it and &quot;any
+ later version&quot;, you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Program does not specify a version
+ number of this License, you may choose any version ever published by
+ the Free Software Foundation.</P>
+<LI>If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted by the
+ Free Software Foundation, write to the Free Software Foundation; we
+ sometimes make exceptions for this. Our decision will be guided by the
+ two goals of preserving the free status of all derivatives of our free
+ software and of promoting the sharing and reuse of software generally.</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<H4>NO WARRANTY</H4>
+<OL START="11">
+<LI>BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER
+ EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
+ YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+ NECESSARY SERVICING, REPAIR OR CORRECTION.</LI>
+<LI>IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+ AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
+ FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.</LI>
+</OL>
+<H4>END OF TERMS AND CONDITIONS</H4>
+
+<!-- NEW PAGE -->
+<H2><A NAME="9_3">GNU LIBRARY GENERAL PUBLIC LICENSE</A></H2>
+<P>Version 2, June 1991</P>
+<PRE>
+Copyright (C) 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+</PRE>
+<H4>Preamble</H4>
+<P>The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public Licenses
+ are intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users.</P>
+<P>This license, the Library General Public License, applies to some
+ specially designated Free Software Foundation software, and to any
+ other libraries whose authors decide to use it. You can use it for your
+ libraries, too.</P>
+<P>When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it in
+ new free programs; and that you know you can do these things.</P>
+<P>To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the library, or if you modify it.</P>
+<P>For example, if you distribute copies of the library, whether gratis
+ or for a fee, you must give the recipients all the rights that we gave
+ you. You must make sure that they, too, receive or can get the source
+ code. If you link a program with the library, you must provide complete
+ object files to the recipients so that they can relink them with the
+ library, after making changes to the library and recompiling it. And
+ you must show them these terms so they know their rights.</P>
+<P>Our method of protecting your rights has two steps: (1) copyright the
+ library, and (2) offer you this license which gives you legal
+ permission to copy, distribute and/or modify the library.</P>
+<P>Also, for each distributor's protection, we want to make certain that
+ everyone understands that there is no warranty for this free library.
+ If the library is modified by someone else and passed on, we want its
+ recipients to know that what they have is not the original version, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.</P>
+<P>Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that companies distributing free
+ software will individually obtain patent licenses, thus in effect
+ transforming the program into proprietary software. To prevent this, we
+ have made it clear that any patent must be licensed for everyone's free
+ use or not licensed at all.</P>
+<P>Most GNU software, including some libraries, is covered by the
+ ordinary GNU General Public License, which was designed for utility
+ programs. This license, the GNU Library General Public License, applies
+ to certain designated libraries. This license is quite different from
+ the ordinary one; be sure to read it in full, and don't assume that
+ anything in it is the same as in the ordinary license.</P>
+<P>The reason we have a separate public license for some libraries is
+ that they blur the distinction we usually make between modifying or
+ adding to a program and simply using it. Linking a program with a
+ library, without changing the library, is in some sense simply using
+ the library, and is analogous to running a utility program or
+ application program. However, in a textual and legal sense, the linked
+ executable is a combined work, a derivative of the original library,
+ and the ordinary General Public License treats it as such.</P>
+<P>Because of this blurred distinction, using the ordinary General
+ Public License for libraries did not effectively promote software
+ sharing, because most developers did not use the libraries. We
+ concluded that weaker conditions might promote sharing better.</P>
+<P>However, unrestricted linking of non-free programs would deprive the
+ users of those programs of all benefit from the free status of the
+ libraries themselves. This Library General Public License is intended
+ to permit developers of non-free programs to use free libraries, while
+ preserving your freedom as a user of such programs to change the free
+ libraries that are incorporated in them. (We have not seen how to
+ achieve this as regards changes in header files, but we have achieved
+ it as regards changes in the actual functions of the Library.) The hope
+ is that this will lead to faster development of free libraries.</P>
+<P>The precise terms and conditions for copying, distribution and
+ modification follow. Pay close attention to the difference between a
+ &quot;work based on the library&quot; and a &quot;work that uses the library&quot;. The
+ former contains code derived from the library, while the latter only
+ works together with the library.</P>
+<P>Note that it is possible for a library to be covered by the ordinary
+ General Public License rather than by this special one.</P>
+<H4>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+<P><STRONG>0.</STRONG> This License Agreement applies to any software
+ library which contains a notice placed by the copyright holder or other
+ authorized party saying it may be distributed under the terms of this
+ Library General Public License (also called &quot;this License&quot;). Each
+ licensee is addressed as &quot;you&quot;.</P>
+<P>A &quot;library&quot; means a collection of software functions and/or data
+ prepared so as to be conveniently linked with application programs
+ (which use some of those functions and data) to form executables.</P>
+<P>The &quot;Library&quot;, below, refers to any such software library or work
+ which has been distributed under these terms. A &quot;work based on the
+ Library&quot; means either the Library or any derivative work under
+ copyright law: that is to say, a work containing the Library or a
+ portion of it, either verbatim or with modifications and/or translated
+ straightforwardly into another language. (Hereinafter, translation is
+ included without limitation in the term &quot;modification&quot;.)</P>
+<P>&quot;Source code&quot; for a work means the preferred form of the work for
+ making modifications to it. For a library, complete source code means
+ all the source code for all modules it contains, plus any associated
+ interface definition files, plus the scripts used to control
+ compilation and installation of the library.</P>
+<P>Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ a program using the Library is not restricted, and output from such a
+ program is covered only if its contents constitute a work based on the
+ Library (independent of the use of the Library in a tool for writing
+ it). Whether that is true depends on what the Library does and what the
+ program that uses the Library does.</P>
+<P><STRONG>1.</STRONG> You may copy and distribute verbatim copies of
+ the Library's complete source code as you receive it, in any medium,
+ provided that you conspicuously and appropriately publish on each copy
+ an appropriate copyright notice and disclaimer of warranty; keep intact
+ all the notices that refer to this License and to the absence of any
+ warranty; and distribute a copy of this License along with the Library.</P>
+<P>You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.</P>
+<P><STRONG>2.</STRONG> You may modify your copy or copies of the Library
+ or any portion of it, thus forming a work based on the Library, and
+ copy and distribute such modifications or work under the terms of
+ Section 1 above, provided that you also meet all of these conditions:</P>
+<OL TYPE="a">
+<LI>The modified work must itself be a software library.
+<P></P>
+<LI>You must cause the files modified to carry prominent notices stating
+ that you changed the files and the date of any change.
+<P></P>
+<LI>You must cause the whole of the work to be licensed at no charge to
+ all third parties under the terms of this License.
+<P></P>
+<LI>If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses the
+ facility, other than as an argument passed when the facility is
+ invoked, then you must make a good faith effort to ensure that, in the
+ event an application does not supply such function or table, the
+ facility still operates, and performs whatever part of its purpose
+ remains meaningful.
+<P>(For example, a function in a library to compute square roots has a
+ purpose that is entirely well-defined independent of the application.
+ Therefore, Subsection 2d requires that any application-supplied
+ function or table used by this function must be optional: if the
+ application does not supply it, the square root function must still
+ compute square roots.)</P>
+</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<P>These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Library,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Library, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.</P>
+<P>Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Library.</P>
+<P>In addition, mere aggregation of another work not based on the
+ Library with the Library (or with a work based on the Library) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.</P>
+<P><STRONG>3.</STRONG> You may opt to apply the terms of the ordinary
+ GNU General Public License instead of this License to a given copy of
+ the Library. To do this, you must alter all the notices that refer to
+ this License, so that they refer to the ordinary GNU General Public
+ License, version 2, instead of to this License. (If a newer version
+ than version 2 of the ordinary GNU General Public License has appeared,
+ then you can specify that version instead if you wish.) Do not make any
+ other change in these notices.</P>
+<P>Once this change is made in a given copy, it is irreversible for that
+ copy, so the ordinary GNU General Public License applies to all
+ subsequent copies and derivative works made from that copy.</P>
+<P>This option is useful when you wish to copy part of the code of the
+ Library into a program that is not a library.</P>
+<P><STRONG>4.</STRONG> You may copy and distribute the Library (or a
+ portion or derivative of it, under Section 2) in object code or
+ executable form under the terms of Sections 1 and 2 above provided that
+ you accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections 1
+ and 2 above on a medium customarily used for software interchange.</P>
+<P>If distribution of object code is made by offering access to copy
+ from a designated place, then offering equivalent access to copy the
+ source code from the same place satisfies the requirement to distribute
+ the source code, even though third parties are not compelled to copy
+ the source along with the object code.</P>
+<P><STRONG>5.</STRONG> A program that contains no derivative of any
+ portion of the Library, but is designed to work with the Library by
+ being compiled or linked with it, is called a &quot;work that uses the
+ Library&quot;. Such a work, in isolation, is not a derivative work of the
+ Library, and therefore falls outside the scope of this License.</P>
+<P>However, linking a &quot;work that uses the Library&quot; with the Library
+ creates an executable that is a derivative of the Library (because it
+ contains portions of the Library), rather than a &quot;work that uses the
+ library&quot;. The executable is therefore covered by this License. Section
+ 6 states terms for distribution of such executables.</P>
+<P>When a &quot;work that uses the Library&quot; uses material from a header file
+ that is part of the Library, the object code for the work may be a
+ derivative work of the Library even though the source code is not.
+ Whether this is true is especially significant if the work can be
+ linked without the Library, or if the work is itself a library. The
+ threshold for this to be true is not precisely defined by law.</P>
+<P>If such an object file uses only numerical parameters, data structure
+ layouts and accessors, and small macros and small inline functions (ten
+ lines or less in length), then the use of the object file is
+ unrestricted, regardless of whether it is legally a derivative work.
+ (Executables containing this object code plus portions of the Library
+ will still fall under Section 6.)</P>
+<P>Otherwise, if the work is a derivative of the Library, you may
+ distribute the object code for the work under the terms of Section 6.
+ Any executables containing that work also fall under Section 6, whether
+ or not they are linked directly with the Library itself.</P>
+<P><STRONG>6.</STRONG> As an exception to the Sections above, you may
+ also compile or link a &quot;work that uses the Library&quot; with the Library to
+ produce a work containing portions of the Library, and distribute that
+ work under terms of your choice, provided that the terms permit
+ modification of the work for the customer's own use and reverse
+ engineering for debugging such modifications.</P>
+<P>You must give prominent notice with each copy of the work that the
+ Library is used in it and that the Library and its use are covered by
+ this License. You must supply a copy of this License. If the work
+ during execution displays copyright notices, you must include the
+ copyright notice for the Library among them, as well as a reference
+ directing the user to the copy of this License. Also, you must do one
+ of these things:</P>
+<OL TYPE="a">
+<LI>Accompany the work with the complete corresponding machine-readable
+ source code for the Library including whatever changes were used in the
+ work (which must be distributed under Sections 1 and 2 above); and, if
+ the work is an executable linked with the Library, with the complete
+ machine-readable &quot;work that uses the Library&quot;, as object code and/or
+ source code, so that the user can modify the Library and then relink to
+ produce a modified executable containing the modified Library. (It is
+ understood that the user who changes the contents of definitions files
+ in the Library will not necessarily be able to recompile the
+ application to use the modified definitions.)
+<P></P>
+<LI>Accompany the work with a written offer, valid for at least three
+ years, to give the same user the materials specified in Subsection 6a,
+ above, for a charge no more than the cost of performing this
+ distribution.
+<P></P>
+<LI>If distribution of the work is made by offering access to copy from
+ a designated place, offer equivalent access to copy the above specified
+ materials from the same place.
+<P></P>
+<LI>Verify that the user has already received a copy of these materials
+ or that you have already sent this user a copy.</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<P>For an executable, the required form of the &quot;work that uses the
+ Library&quot; must include any data and utility programs needed for
+ reproducing the executable from it. However, as a special exception,
+ the source code distributed need not include anything that is normally
+ distributed (in either source or binary form) with the major components
+ (compiler, kernel, and so on) of the operating system on which the
+ executable runs, unless that component itself accompanies the
+ executable.</P>
+<P>It may happen that this requirement contradicts the license
+ restrictions of other proprietary libraries that do not normally
+ accompany the operating system. Such a contradiction means you cannot
+ use both them and the Library together in an executable that you
+ distribute.</P>
+<P><STRONG>7.</STRONG> You may place library facilities that are a work
+ based on the Library side-by-side in a single library together with
+ other library facilities not covered by this License, and distribute
+ such a combined library, provided that the separate distribution of the
+ work based on the Library and of the other library facilities is
+ otherwise permitted, and provided that you do these two things:</P>
+<OL TYPE="a">
+<LI>Accompany the combined library with a copy of the same work based on
+ the Library, uncombined with any other library facilities. This must be
+ distributed under the terms of the Sections above.
+<P></P>
+<LI>Give prominent notice with the combined library of the fact that
+ part of it is a work based on the Library, and explaining where to find
+ the accompanying uncombined form of the same work.</LI>
+</LI>
+</OL>
+<P><STRONG>8.</STRONG> You may not copy, modify, sublicense, link with,
+ or distribute the Library except as expressly provided under this
+ License. Any attempt otherwise to copy, modify, sublicense, link with,
+ or distribute the Library is void, and will automatically terminate
+ your rights under this License. However, parties who have received
+ copies, or rights, from you under this License will not have their
+ licenses terminated so long as such parties remain in full compliance.</P>
+<P><STRONG>9.</STRONG> You are not required to accept this License,
+ since you have not signed it. However, nothing else grants you
+ permission to modify or distribute the Library or its derivative works.
+ These actions are prohibited by law if you do not accept this License.
+ Therefore, by modifying or distributing the Library (or any work based
+ on the Library), you indicate your acceptance of this License to do so,
+ and all its terms and conditions for copying, distributing or modifying
+ the Library or works based on it.</P>
+<P><STRONG>10.</STRONG> Each time you redistribute the Library (or any
+ work based on the Library), the recipient automatically receives a
+ license from the original licensor to copy, distribute, link with or
+ modify the Library subject to these terms and conditions. You may not
+ impose any further restrictions on the recipients' exercise of the
+ rights granted herein. You are not responsible for enforcing compliance
+ by third parties to this License.</P>
+<P><STRONG>11.</STRONG> If, as a consequence of a court judgment or
+ allegation of patent infringement or for any other reason (not limited
+ to patent issues), conditions are imposed on you (whether by court
+ order, agreement or otherwise) that contradict the conditions of this
+ License, they do not excuse you from the conditions of this License. If
+ you cannot distribute so as to satisfy simultaneously your obligations
+ under this License and any other pertinent obligations, then as a
+ consequence you may not distribute the Library at all. For example, if
+ a patent license would not permit royalty-free redistribution of the
+ Library by all those who receive copies directly or indirectly through
+ you, then the only way you could satisfy both it and this License would
+ be to refrain entirely from distribution of the Library.</P>
+<P>If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply, and the section as a whole is intended to apply in other
+ circumstances.</P>
+<P>It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system which is implemented
+ by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.</P>
+<P>This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.</P>
+<P><STRONG>12.</STRONG> If the distribution and/or use of the Library is
+ restricted in certain countries either by patents or by copyrighted
+ interfaces, the original copyright holder who places the Library under
+ this License may add an explicit geographical distribution limitation
+ excluding those countries, so that distribution is permitted only in or
+ among countries not thus excluded. In such case, this License
+ incorporates the limitation as if written in the body of this License.</P>
+<P><STRONG>13.</STRONG> The Free Software Foundation may publish revised
+ and/or new versions of the Library General Public License from time to
+ time. Such new versions will be similar in spirit to the present
+ version, but may differ in detail to address new problems or concerns.</P>
+<P>Each version is given a distinguishing version number. If the Library
+ specifies a version number of this License which applies to it and &quot;any
+ later version&quot;, you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Library does not specify a license
+ version number, you may choose any version ever published by the Free
+ Software Foundation.</P>
+<P><STRONG>14.</STRONG> If you wish to incorporate parts of the Library
+ into other free programs whose distribution conditions are incompatible
+ with these, write to the author to ask for permission. For software
+ which is copyrighted by the Free Software Foundation, write to the Free
+ Software Foundation; we sometimes make exceptions for this. Our
+ decision will be guided by the two goals of preserving the free status
+ of all derivatives of our free software and of promoting the sharing
+ and reuse of software generally.</P>
+<P><STRONG>NO WARRANTY</STRONG></P>
+<P><STRONG>15.</STRONG> BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE,
+ THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY &quot;AS IS&quot; WITHOUT
+ WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
+ OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU
+ ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</P>
+<P><STRONG>16.</STRONG> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
+ AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO
+ MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.</P>
+<H4>END OF TERMS AND CONDITIONS</H4>
+<H1 ALIGN="RIGHT"><A NAME="COMMON_NETWORK">B - Common Network Settings</A>
+</H1>
+<P>This appendix covers many of the popular TCP/IP network interfaces
+ and printer servers available on the market today.</P>
+<H2><A NAME="10_1">Configuring a Network Interface</A></H2>
+<P>When you first install a network printer or print server on your LAN,
+ you need to set the Internet Protocol (&quot;IP&quot;) address. On most
+ higher-end &quot;workgroup&quot; printers, you can set the address through the
+ printer control panel. However, in most cases you will want to assign
+ the addresses remotely from your workstation. This makes administration
+ a bit easier and avoids assigning duplicate addresses accidentally.</P>
+<P>To setup your printer or print server for remote address assignment,
+ you'll need the Ethernet Media Access Control (&quot;MAC&quot;) address, also
+ sometimes called a node address, and the IP address you want to use for
+ the device. The Ethernet MAC address can often be found on the printer
+ test page or bottom of the print server.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="10_1_1">Configuring the IP Address Using ARP</A></H3>
+<P>The easiest way to set the IP address of a network device is to use
+ the <CODE>arp(8)</CODE> command. The <CODE>arp</CODE> sends an Address
+ Resolution Protocol (&quot;ARP&quot;) packet to the specified Ethernet MAC
+ address, setting the network device's IP address:</P>
+<UL>
+<PRE>
+<B>arp -s ip-address ethernet-address ENTER</B>
+<B>arp -s host.domain.com 08:00:69:00:12:34 ENTER</B>
+<B>arp -s 192.0.2.2 08:00:69:00:12:34 ENTER</B>
+</PRE>
+</UL>
+<H3><A NAME="10_1_2">Configuring the IP Address Using RARP</A></H3>
+<P>The most flexible way to remotely assign IP addresses under UNIX is
+ through the Reverse Address Resolution Protocol (&quot;RARP&quot;). RARP allows a
+ network device to request an IP address using its Ethernet MAC address,
+ and one or more RARP servers on the network will respond with an ARP
+ packet with the IP address the device can use.</P>
+<P>RARP should be used when you have to manage many printers or print
+ servers, or when you have a network device that does not remember its
+ IP address after a power cycle. If you just have a single printer or
+ print server, the <CODE>arp</CODE> command is the way to go.</P>
+<P>Some UNIX operating systems use a program called <CODE>rarpd(8)</CODE>
+ to manage RARP. Others, like Linux, support this protocol in the
+ kernel. For systems that provide the <CODE>rarpd</CODE> program you
+ will need to start it before RARP lookups will work:</P>
+<UL>
+<PRE>
+<B>rarpd ENTER</B>
+</PRE>
+</UL>
+<P>Under IRIX you can enable this functionality by default using:</P>
+<UL>
+<PRE>
+<B>chkconfig rarpd on ENTER</B>
+</PRE>
+</UL>
+<P>Both the <CODE>rarpd</CODE> program and kernel RARP support read a
+ list of Ethernet and IP addresses from the file<VAR> /etc/ethers</VAR>.
+ Each line contains the Ethernet address (colon delimited) followed by
+ an IP address or hostname like:</P>
+<UL>
+<PRE>
+08:00:69:00:12:34 myprinter.mydomain.com
+08:00:69:00:12:34 192.0.2.2
+</PRE>
+</UL>
+<P>Add a line to this file and cycle the power on the printer or print
+ server to set its address.
+<!-- NEED 2in -->
+</P>
+<H3><A NAME="10_1_3">Configuring the IP Address Using BOOTP</A></H3>
+<P>The BOOTP protocol is used when you need to provide additional
+ information such as the location of a configuration file to the network
+ interface. Using the standard <CODE>bootpd(8)</CODE> program supplied
+ with UNIX you simply need to add a line to the<VAR> /etc/bootptab</VAR>
+ file; for IRIX:</P>
+<UL>
+<PRE>
+myprinter 08:00:69:00:12:34 192.0.2.2 <VAR>myprinter.boot</VAR>
+</PRE>
+</UL>
+
+<!-- NEED 1in -->
+<P>Newer versions of <CODE>bootpd</CODE> use a different format:</P>
+<UL>
+<PRE>
+myprinter:ha=080069001234:ip=192.0.2.2:<VAR>t144=myprinter.boot</VAR>
+</PRE>
+</UL>
+<P>The<VAR> myprinter.boot</VAR> file resides in the<VAR>
+ /usr/local/boot</VAR> directory by default. If you do not need to
+ provide a boot file you may leave the last part of the line blank.</P>
+
+<!-- NEED 2in -->
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Some versions of UNIX do not enable the BOOTP service by default. The<VAR>
+ /etc/inetd.conf</VAR> usually contains a line for the BOOTP service
+ that can be uncommented if needed.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H2><A NAME="10_2">Verifying the Printer Connection</A></H2>
+<P>To test that the IP address has been successfully assigned and that
+ the printer is properly connected to your LAN, type:</P>
+<UL>
+<PRE>
+<B>ping ip-address ENTER</B>
+</PRE>
+</UL>
+<P>If the connection is working properly you will see something like:</P>
+<UL>
+<PRE>
+<B>ping myprinter ENTER</B>
+PING myprinter (192.0.2.2): 56 data bytes
+64 bytes from 192.0.2.2: icmp_seq=0 ttl=15 time=5 ms
+64 bytes from 192.0.2.2: icmp_seq=1 ttl=15 time=3 ms
+64 bytes from 192.0.2.2: icmp_seq=2 ttl=15 time=3 ms
+64 bytes from 192.0.2.2: icmp_seq=3 ttl=15 time=3 ms
+</PRE>
+</UL>
+<P>If not, verify that the printer or print server is connected to the
+ LAN, it is powered on, the LAN cabling is good, and the IP address is
+ set correctly. You can usually see the current IP address and network
+ status by printing a configuration or test page on the device.
+<!-- NEED 4in -->
+</P>
+<H2><A NAME="10_3">Common Network Interface Settings</A></H2>
+<P>Once you have set the IP address you can access the printer or print
+ server using the <CODE>ipp</CODE>, <CODE>lpd</CODE>, or <CODE>socket</CODE>
+ backends. The following is a list of common network interfaces and
+ printer servers and the settings you should use with CUPS:
+<CENTER>
+<TABLE BORDER="1">
+<TR ALIGN="LEFT" VALIGN="TOP"><TH>Model/Manufacturer</TH><TH>Device
+ URI(s)</TH></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Apple LaserWriter</TD><TD>lpd://<I>
+address</I>/PASSTHRU</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Axis w/o IPP
+<BR><A HREF="#AXIS"> (see directions)</A></TD><TD>socket://<I>address</I>
+:9100
+<BR> socket://<I>address</I>:9101
+<BR> socket://<I>address</I>:9102</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Axis w/IPP</TD><TD>ipp://<I>address</I>
+/LPT1
+<BR> ipp://<I>address</I>/LPT2
+<BR> ipp://<I>address</I>/COM1</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Castelle LANpress<SUP>TM</SUP></TD><TD>
+lpd://<I>address</I>/pr1
+<BR> lpd://<I>address</I>/pr2
+<BR> lpd://<I>address</I>/pr3</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>DPI NETPrint</TD><TD>lpd://<I>address</I>
+/pr1
+<BR> lpd://<I>address</I>/pr2
+<BR> lpd://<I>address</I>/pr3</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>EFI&reg; Fiery&reg; RIP</TD><TD>lpd://<I>
+address</I>/print</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>EPSON&reg; Multiprotocol Ethernet
+ Interface Board</TD><TD>socket://<I>address</I></TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Extended System ExtendNET</TD><TD>
+lpd://<I>address</I>/pr1
+<BR> lpd://<I>address</I>/pr2
+<BR> lpd://<I>address</I>/pr3</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Hewlett Packard JetDirect w/o IPP</TD><TD>
+socket://<I>address</I>:9100
+<BR> socket://<I>address</I>:9101
+<BR> socket://<I>address</I>:9102</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Hewlett Packard JetDirect w/IPP</TD><TD>
+ipp://<I>address</I>/ipp
+<BR> ipp://<I>address</I>/ipp/port1
+<BR> ipp://<I>address</I>/ipp/port2
+<BR> ipp://<I>address</I>/ipp/port3</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Intel&reg; NetportExpress XL, PRO/100</TD><TD>
+lpd://<I>address</I>/LPT1_PASSTHRU
+<BR> lpd://<I>address</I>/LPT2_PASSTHRU
+<BR> lpd://<I>address</I>/COM1_PASSTHRU</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Lexmark<SUP>TM</SUP> MarkNet</TD><TD>
+lpd://<I>address</I>/ps</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Linksys EtherFast&reg;
+<BR><A HREF="#LINKSYS"> (see directions)</A></TD><TD>socket://<I>address</I>
+:4010
+<BR> socket://<I>address</I>:4020
+<BR> socket://<I>address</I>:4030</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Kodak&reg;</TD><TD>lpd://<I>address</I>/ps</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>QMS&reg; CrownNet<SUP>TM</SUP></TD><TD>
+lpd://<I>address</I>/ps</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Tektronix&reg; PhaserShare<SUP>TM</SUP></TD><TD>
+socket://<I>address</I>:9100</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>XEROX&reg; 4512 NIC</TD><TD>lpd://<I>
+address</I>/PORT1</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>XEROX&reg; XNIC</TD><TD>lpd://<I>address</I>
+/PASSTHRU</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>XEROX&reg; (most others)</TD><TD>socket://<I>
+address</I>:5503</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H2><A NAME="AXIS">Configuring Axis Print Servers</A></H2>
+<P>The Axis print servers can be configured using ARP, RARP, or BOOTP.
+ However, on models that do not provide IPP support an additional step
+ must be performed to configure the TCP/IP portion of the print server
+ for use with CUPS.
+<!-- NEED 3in -->
+</P>
+<P>Each print server contains a configuration file named<VAR> config</VAR>
+ that contains a list of network parameters used by the server. To
+ modify this file you must first download it from the print server using
+ the <CODE>ftp(1)</CODE> program:</P>
+<UL>
+<PRE>
+<B>ftp ip-address ENTER</B>
+Connected to ip-address.
+220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
+ftp&gt; <B>user root ENTER</B>
+331 User name ok, need password
+Password: <B>pass ENTER</B> <I>(this is not echoed)</I>
+230 User logged in
+ftp&gt; <B>get config ENTER</B>
+local: config remote: config
+200 PORT command successful.
+150 Opening data connection for config (192,0,2,2),
+(mode ascii).
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp&gt; <B>quit ENTER</B>
+221 Goodbye.
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<P>Next, edit the file with your favorite text editor and locate the
+ lines beginning with:</P>
+<UL>
+<PRE>
+RTN_OPT. : YES
+RTEL_PR1. : 0
+RTEL_PR2. : 0
+RTEL_PR3. : 0
+RTEL_PR4. : 0
+RTEL_PR5. : 0
+RTEL_PR6. : 0
+RTEL_PR7. : 0
+RTEL_PR8. : 0
+</PRE>
+</UL>
+
+<!-- NEED 1in -->
+ Change the <CODE>RTN_OPT</CODE> line to read:
+<UL>
+<PRE>
+RTN_OPT. : <B>NO</B>
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<P>This disables the Reverse TELNET protocol and enables the standard
+ TELNET protocol on the print server. Next, assign a port number for
+ each parallel and serial port on the server as follows:</P>
+<UL>
+<PRE>
+RTEL_PR1. : <B>9100</B>
+RTEL_PR2. : <B>9101</B>
+RTEL_PR3. : <B>9102</B>
+RTEL_PR4. : <B>9103</B>
+RTEL_PR5. : <B>9104</B>
+RTEL_PR6. : <B>9105</B>
+RTEL_PR7. : <B>9106</B>
+RTEL_PR8. : <B>9107</B>
+</PRE>
+</UL>
+
+<!-- NEED 4in -->
+<P>This essentially makes the Axis print server look like a Hewlett
+ Packard JetDirect EX print server. Save the file and then upload the
+ new<VAR> config</VAR> file using the <CODE>ftp</CODE> command:</P>
+<UL>
+<PRE>
+<B>ftp ip-address ENTER</B>
+Connected to ip-address.
+220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
+ftp&gt; <B>user root ENTER</B>
+331 User name ok, need password
+Password: <B>pass ENTER</B> <I>(this is not echoed)</I>
+230 User logged in
+ftp&gt; <B>put config CONFIG ENTER</B>
+local: config remote: CONFIG
+200 PORT command successful.
+150 Opening data connection for config (192,0,2,2), (mode ascii).
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp&gt; <B>get hardreset ENTER</B>
+local: hardreset remote: hardreset
+200 PORT command successful.
+421 Axis NPS ### hard reset, closing connection.
+ftp&gt; <B>quit ENTER</B>
+221 Goodbye.
+</PRE>
+</UL>
+<P>Your Axis print server is now ready for use!</P>
+<H2><A NAME="LINKSYS">Configuring Linksys Print Servers</A></H2>
+<P>The Linksys print servers can be configured using ARP, RARP, or
+ BOOTP. Like older Axis print servers, an additional step must be
+ performed to configure the TCP/IP portion of the print server for use
+ with CUPS.
+<!-- NEED 3in -->
+</P>
+<P>Each print server contains a configuration file named<VAR> CONFIG</VAR>
+ that contains a list of network parameters used by the server. To
+ modify this file you must first download it from the print server using
+ the <CODE>ftp(1)</CODE> program:</P>
+<UL>
+<PRE>
+<B>ftp -n ip-address ENTER</B>
+Connected to ip-address.
+220 Print Server Ready.
+Remote system type is Print.
+ftp&gt; <B>get CONFIG ENTER</B>
+local: CONFIG remote: CONFIG
+200 Command OK.
+150 Open ASCII Mode Connection.
+WARNING! 68 bare linefeeds received in ASCII mode
+File may not have transferred correctly.
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp&gt; <B>quit ENTER</B>
+221 Goodbye.
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<P>Next, edit the file with your favorite text editor and locate the
+ lines beginning with:</P>
+<UL>
+<PRE>
+0100 L1_PROUT:P1
+0120 L2_PROUT:P1
+0140 L3_PROUT:P1
+</PRE>
+</UL>
+<P>Change the port number for each parallel and serial port on the
+ server as follows:</P>
+<UL>
+<PRE>
+0100 L1_PROUT:<B>P1</B>
+0120 L2_PROUT:<B>P2</B>
+0140 L3_PROUT:<B>P3</B>
+</PRE>
+</UL>
+
+<!-- NEED 4in -->
+<P>This maps each virtual printer with a physical port. Save the file
+ and then upload the new<VAR> CONFIG</VAR> file using the <CODE>ftp</CODE>
+ command:</P>
+<UL>
+<PRE>
+<B>ftp -n ip-address ENTER</B>
+Connected to ip-address.
+220 Print Server Ready.
+Remote system type is Print.
+ftp&gt; <B>put CONFIG ENTER</B>
+local: CONFIG remote: CONFIG
+200 Command OK.
+150 Open ASCII Mode Connection.
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp&gt; <B>quit ENTER</B>
+221 Goodbye.
+</PRE>
+</UL>
+<P>Your Linksys print server is now ready for use!</P>
+<H1 ALIGN="RIGHT"><A NAME="PRINTER_DRIVERS">C - Printer Drivers</A></H1>
+<P>This appendix lists the printer drivers that are provided with CUPS.</P>
+<H2><A NAME="11_1">Printer Drivers</A></H2>
+<P>CUPS includes the following printer drivers:</P>
+<UL>
+<LI><A HREF="#EPSON9">EPSON 9-pin Dot Matrix</A>,<VAR> epson9.ppd</VAR></LI>
+<LI><A HREF="#EPSON24">EPSON 24-pin Dot Matrix</A>,<VAR> epson24.ppd</VAR>
+</LI>
+<LI><A HREF="#STCOLOR">EPSON Stylus Color</A>,<VAR> stcolor.ppd</VAR></LI>
+<LI><A HREF="#STPHOTO">EPSON Stylus Photo</A>,<VAR> stphoto.ppd</VAR></LI>
+<LI><A HREF="#DESKJET">HP DeskJet</A>,<VAR> deskjet.ppd</VAR></LI>
+<LI><A HREF="#LASERJET">HP LaserJet</A>,<VAR> laserjet.ppd</VAR></LI>
+</UL>
+<H2><A NAME="EPSON9">EPSON 9-pin Dot Matrix</A></H2>
+<P>The EPSON 9-pin Dot Matrix driver (<VAR>epson9.ppd</VAR>) supports
+ 9-pin dot matrix printers that implement the ESC/P command set. It
+ provides 60x72, 120x72, and 240x72 DPI output in black only.</P>
+<H2><A NAME="EPSON24">EPSON 24-pin Dot Matrix</A></H2>
+<P>The EPSON 24-pin Dot Matrix driver (<VAR>epson9.ppd</VAR>) supports
+ 24-pin dot matrix printers that implement the ESC/P command set. It
+ provides 120x180, 180x180, 360x180, and 360x360 DPI output in black
+ only.</P>
+<H2><A NAME="STCOLOR">EPSON Stylus Color</A></H2>
+<P>The EPSON Stylus Color driver (<VAR>stcolor.ppd</VAR>) supports EPSON
+ Stylus Color printers that implement the ESC/P2 command set. It
+ provides 180, 360, and 720 DPI output in black and color (CMYK).</P>
+<H2><A NAME="STPHOTO">EPSON Stylus Photo</A></H2>
+<P>The EPSON Stylus Photo driver (<VAR>stphoto.ppd</VAR>) supports EPSON
+ Stylus Photo printers that implement the ESC/P2 command set. It
+ provides 180, 360, and 720 DPI output in black and color (CMYKcm).</P>
+<H2><A NAME="DESKJET">HP DeskJet</A></H2>
+<P>The HP DeskJet driver (<VAR>deskjet.ppd</VAR>) supports HP DeskJet
+ printers that implement the PCL command set. It provides 150, 300, and
+ 600 DPI output in black and color (CMYK).</P>
+<P>The DeskJet printers that implement the HP-PPA command set (720C,
+ 722C, 820C, and 1100C) are<B> not</B> supported due to a complete lack
+ of documentation and support from Hewlett Packard.</P>
+<P>The duplexer provided with the HP DeskJet 900 series printers is also
+ not supported for similar reasons.</P>
+<H2><A NAME="LASERJET">HP LaserJet</A></H2>
+<P>The HP LaserJet driver (<VAR>laserjet.ppd</VAR>) supports HP LaserJet
+ printers that implement the PCL command set. It provides 150, 300, and
+ 600 DPI output in black only and supports the duplexer if installed.</P>
+<P>LaserJet printers that do not implement PCL (3100, 3150) are not
+ supported due to a complete lack of documentation and support from
+ Hewlett Packard.</P>
+<H1 ALIGN="RIGHT"><A NAME="FILES">D - List of Files</A></H1>
+<P>This appendix lists the files and directories that are installed for
+ the Common UNIX Printing System.
+<CENTER>
+<TABLE BORDER="1" WIDTH="80%">
+<TR VALIGN="TOP"><TH>Pathname</TH><TH>Description</TH></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/certs/</TD><TD>The location of
+ authentication certificate files for local HTTP clients.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/classes.conf</TD><TD>The printer classes
+ configuration file for the scheduler.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/cupsd.conf</TD><TD>The scheduler
+ configuration file.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/interfaces/</TD><TD>The location of
+ System V interface scripts for printers.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/mime.convs</TD><TD>The list of standard
+ file filters included with CUPS.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/mime.types</TD><TD>The list of recognized
+ file types for CUPS.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/ppd/</TD><TD>The location of PostScript
+ Printer Description (&quot;PPD&quot;) files for printers.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/printers.conf</TD><TD>The printer
+ configuration file for the scheduler.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/cancel</TD><TD>The System V cancel job(s)
+ command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/disable</TD><TD>The System V disable
+ printer command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/enable</TD><TD>The System V enable printer
+ command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lp</TD><TD>The System V print command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lpoptions</TD><TD>Sets user-defined
+ printing options and defaults.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lppasswd</TD><TD>Adds, changes, or removes
+ Digest password accounts.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lpq</TD><TD>The Berkeley status command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lpr</TD><TD>The Berkeley print command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lprm</TD><TD>The Berkeley cancel job(s)
+ command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lpstat</TD><TD>The System V status
+ command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/include/cups/</TD><TD>CUPS API header files.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/lib32/libcups.a
+<BR> /usr/lib32/libcupsimage.a</TD><TD>Static libraries (IRIX 6.5)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/libcups.a
+<BR> /usr/lib/libcupsimage.a</TD><TD>Static libraries (all others)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/libcups.sl.2
+<BR> /usr/lib/libcupsimage.sl.2</TD><TD>Shared libraries (HP-UX)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib32/libcups.so.2
+<BR> /usr/lib32/libcupsimage.so.2</TD><TD>Shared libraries (IRIX 6.5)</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/lib/libcups.so.2
+<BR> /usr/lib/libcupsimage.so.2</TD><TD>Shared libraries (all others)</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/lib/cups/backend/</TD><TD>Backends for various
+ types of printer connections.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/cups/cgi-bin/</TD><TD>CGI programs for the
+ scheduler.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/cups/daemon/</TD><TD>Daemons for polling
+ and LPD support.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/cups/filter/</TD><TD>Filters for various
+ types of files.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/locale/</TD><TD>The location of
+ language-specific message files. (System V)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/nls/msg/</TD><TD>The location of
+ language-specific message files. (Compaq Tru64 UNIX)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/locale/</TD><TD>The location of
+ language-specific message files. (Linux, *BSD)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/accept</TD><TD>The accept-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/cupsd</TD><TD>The CUPS print scheduler.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/lpadmin</TD><TD>The System V printer
+ administration tool.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/lpc</TD><TD>The Berkeley printer
+ administration tool.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/lpinfo</TD><TD>The get-devices and
+ get-ppds command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/lpmove</TD><TD>The move-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/reject</TD><TD>The reject-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/share/catman/a_man/
+<BR> /usr/share/catman/u_man/</TD><TD>Man pages (IRIX)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/man/</TD><TD>Man pages (Compaq Tru64
+ UNIX, HP-UX, Solaris)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/man/</TD><TD>Man pages (all others)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/data/</TD><TD>The location of
+ filter data files.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/data/testprint.ps</TD><TD>The
+ PostScript test page file.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/fonts/</TD><TD>The location of
+ PostScript fonts for the PostScript RIP.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/model/</TD><TD>The location of
+ PostScript Printer Description (&quot;PPD&quot;) files and interface scripts that
+ may be used to setup a printer queue.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/pstoraster/</TD><TD>Other
+ PostScript RIP initialization files.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/pstoraster/Fontmap</TD><TD>The font
+ mapping file (converts filenames to fontnames)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/templates/</TD><TD>The location of
+ HTML template files for the web interfaces.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/doc/cups/</TD><TD>Documentation and web
+ page data for the scheduler.</TD></TR>
+<TR VALIGN="TOP"><TD>/var/log/cups/</TD><TD>The location of scheduler
+ log files.</TD></TR>
+<TR VALIGN="TOP"><TD>/var/spool/cups/</TD><TD>The location of print
+ files waiting to be printed.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H1 ALIGN="RIGHT"><A NAME="FAQ">E - Troubleshooting Common Problems</A></H1>
+<P>This appendix covers some of the common problems first-time users
+ encounter when installing and configuring CUPS.</P>
+<P>Commercial support for CUPS is available from Easy Software Products.
+ For more information please contact us at:</P>
+<UL>
+<LI>WWW:<A HREF="http://www.easysw.com"> <CODE>http://www.easysw.com</CODE>
+</A></LI>
+<LI>EMail:<A HREF="mailto:info@easysw.com"> info@easysw.com</A></LI>
+<LI>Telephone (M-F, 9-5 EST): +1.301.373.9600</LI>
+</UL>
+<H2><A NAME="13_1">My Applications Don't See the Available Printers</A></H2>
+<P>Many applications read the<VAR> /etc/printcap</VAR> file to get a
+ list of available printers.</P>
+<P>The default CUPS configuration does not create the<VAR> /etc/printcap</VAR>
+ file automatically. To enable automatic creation and updating of this
+ file, use the<A HREF="#Printcap"> <CODE>Printcap</CODE></A> directive
+ described in<A HREF="#PRINTING_MANAGEMENT"> Chapter 6, &quot;Printing System
+ Management&quot;</A>.</P>
+<H2><A NAME="13_2">CUPS Doesn't Recognize My Username or Password!</A></H2>
+<P>CUPS will ask you for a UNIX username and password when you perform
+ printer administration tasks remotely or via a web browser. The default
+ configuration requires that you use the <CODE>root</CODE> username and
+ the corresponding password to authenticate the request.</P>
+<P>CUPS does not allow you to authenticate an administration request
+ with an account that has no password for security reasons. If you do
+ not have a password on your <CODE>root</CODE> account then you won't be
+ able to add printers remotely or via the web interface!
+<!-- NEED 2in -->
+</P>
+<P>To disable password authentication you need to edit the<VAR>
+ /etc/cups/cupsd.conf</VAR> file and comment out the lines reading:</P>
+<UL>
+<PRE>
+AuthType Basic
+AuthClass System
+</PRE>
+</UL>
+ for the<VAR> /admin</VAR> location. Then restart the CUPS server as
+ described in<A HREF="#PRINTING_MANAGEMENT"> Chapter 6, &quot;Printing System
+ Management&quot;</A>.
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Disabling password checks will allow any local user to change your
+ printer and class configuration, but remote administration from another
+ machine will still not be allowed.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H2><A NAME="ALLOW_REMOTE">I Can't Do Administration Tasks from Another
+ Machine!</A></H2>
+<P>The default CUPS configuration limits administration to the local
+ machine. To open up access, edit the<VAR> /etc/cups/cupsd.conf</VAR>
+ and comment out the lines reading:</P>
+<UL>
+<PRE>
+Order deny,allow
+Deny from all
+Allow from 127.0.0.1
+</PRE>
+</UL>
+ for the<VAR> /admin</VAR> location. Then restart the CUPS server as
+ described in<A HREF="#PRINTING_MANAGEMENT"> Chapter 6, &quot;Printing System
+ Management&quot;</A>.
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Allowing administration access from all hosts is a potential security
+ risk. Please read<A HREF="#PRINTING_SECURITY"> Chapter 6, &quot;Printing
+ System Management&quot;</A> for a description of these risks and ways to
+ minimize them.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 4in -->
+<H2><A NAME="13_4">I Can't Do Administration Tasks from My Web Browser!</A>
+</H2>
+<P>This problem is usually caused by:</P>
+<OL>
+<LI>not specifying the correct password for the root account.</LI>
+<LI>accessing the CUPS server using the hostname or IP address of the
+ server without enabling remote access for administration functions.
+ This can be corrected by following the instructions in the<A HREF="#ALLOW_REMOTE">
+ &quot;I Can't Do Administration Tasks from Another Machine!&quot;</A> section
+ earlier in this appendix.</LI>
+<LI>not setting a password on the root account. CUPS will not
+ authenticate a user account that does not have a password for security
+ reasons.</LI>
+<LI>authenticating using an account other than root, but the account you
+ are using is not a member of the system group.</LI>
+<LI>configuring CUPS to use Digest authentication, but your web browser
+ does not support Digest authentication.</LI>
+</OL>
+<H2><A NAME="13_5">Connection Refused Messages</A></H2>
+<P>Under normal circumstances, &quot;connection refused&quot; messages for a
+ networked printer should be expected from time to time. Most network
+ interfaces only allow a single connection to be made at any given time
+ (one job at a time) and will refuse access to all other systems while
+ the first connection is active. CUPS automatically retries the
+ connection once every 30 seconds.</P>
+<P>If the problem persists and you are unable to print any jobs to the
+ printer, verify that another machine is not maintaining a connection
+ with the printer, and that you have selected the proper port or printer
+ name for the printer.</P>
+<P>Also, most external print servers will refuse connections if the
+ connected printer is turned off or is off-line. Verify that the
+ affected printer is turned on and is online.</P>
+<H2><A NAME="13_6">Write Error Messages</A></H2>
+<P>If you get &quot;write error&quot; messages on a printer queue the printer
+ interface (usually a Hewlett Packard JetDirect interface) has timed out
+ and reset the network connection from your workstation.</P>
+<P>The error is caused by that startup delay between the initial setup
+ of the printer or plotter and the first page of print data that is
+ sent.
+<!-- NEED 3in -->
+</P>
+<P>To correct the problem, change the idle timeout on the interface to
+ at least 180 seconds or 3 minutes. To change the timeout on a Hewlett
+ Packard JetDirect interface, type:</P>
+<UL>
+<PRE>
+<B>telnet ip-address ENTER</B>
+
+Trying ip-address...
+Connected to ip-address.
+Escape character is `^]'.
+
+Please type [Return] two times, to initialize telnet configuration
+For HELP type &quot;?&quot;
+&gt; <B>idle-timeout: 180 ENTER</B>
+&gt; <B>quit ENTER</B>
+</PRE>
+</UL>
+</BODY>
+</HTML>
diff --git a/doc/fr/sam.pdf b/doc/fr/sam.pdf
new file mode 100644
index 000000000..9435fc284
--- /dev/null
+++ b/doc/fr/sam.pdf
Binary files differ
diff --git a/doc/fr/sam.shtml b/doc/fr/sam.shtml
new file mode 100644
index 000000000..89231a628
--- /dev/null
+++ b/doc/fr/sam.shtml
@@ -0,0 +1,4953 @@
+<HTML>
+<HEAD>
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-SAM-1.1.15">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Software Administrators Manual</TITLE>
+</HEAD>
+<BODY>
+
+<H1 ALIGN="RIGHT">Preface</H1>
+
+<P>This software administrators manual provides printer administration
+information for the Common UNIX Printing System<SUP>TM</SUP>
+("CUPS<SUP>TM</SUP>"), version 1.1.15.
+
+<EMBED SRC="system-overview.shtml">
+
+<!-- NEED 3in -->
+<H2>Document Overview</H2>
+
+<P>This software administrators manual is organized into the following sections:</P>
+
+<UL>
+ <LI><A HREF="#OVERVIEW">1 - Printing System Overview</A>
+ <LI><A HREF="#BUILDING_INSTALLING">2 - Building and Installing CUPS</A>
+ <LI><A HREF="#MANAGING_PRINTERS">3 - Managing Printers</A>
+ <LI><A HREF="#PRINTER_CLASSES">4 - Printer Classes</A>
+ <LI><A HREF="#CLIENT_SETUP">5 - Client Setup</A>
+ <LI><A HREF="#PRINTING_MANAGEMENT">6 - Printing System Management</A>
+ <LI><A HREF="#PRINTING_OTHER">7 - Printing with Other Systems</A>
+ <LI><A HREF="#LICENSE">A - Software License Agreement</A>
+ <LI><A HREF="#COMMON_NETWORK">B - Common Network Settings</A>
+ <LI><A HREF="#PRINTER_DRIVERS">C - Printer Drivers</A>
+ <LI><A HREF="#FILES">D - List of Files</A>
+ <LI><A HREF="#FAQ">E - Troubleshooting Common Problems</A>
+</UL>
+
+<H2>Notation Conventions</H2>
+
+<P>Various font and syntax conventions are used in this guide. Examples and
+their meanings and uses are explained below:
+
+<CENTER><TABLE WIDTH="80%">
+<TR>
+ <TH>Example</TH>
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+ <TH>Description</TH>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD><CODE>lpstat</CODE><BR>
+ <CODE>lpstat(1)</CODE></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>The names of commands; the first mention of a command or
+ function in a chapter is followed by a manual page section
+ number.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD><VAR>/var</VAR><BR>
+ <VAR>/usr/share/cups/data/testprint.ps</VAR></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>File and directory names.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD NOWRAP><TT>Request ID is Printer-123</TT></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Screen output.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD NOWRAP><KBD>lp -d printer filename ENTER</KBD></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Literal user input; special keys like <KBD>ENTER</B></KBD> are
+ in ALL CAPS.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD>12.3</TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Numbers in the text are written using the period (.) to indicate
+ the decimal point.</TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H2>Abbreviations</H2>
+
+The following abbreviations are used throughout this manual:
+
+<UL>
+<DL>
+
+ <DT>kb
+ <DD>Kilobytes, or 1024 bytes<BR>&nbsp;
+
+ <DT>Mb
+ <DD>Megabytes, or 1048576 bytes<BR>&nbsp;
+
+ <DT>Gb
+ <DD>Gigabytes, or 1073741824 bytes<BR>&nbsp;
+
+</DL>
+</UL>
+
+<H2>Other References</H2>
+
+<UL>
+<DL>
+
+ <DT>CUPS Software Programmers Manual
+
+ <DD>A programmer guide for interfacing with and/or extending the CUPS
+ software.<BR>&nbsp;
+
+ <DT>CUPS Software Users Manual
+
+ <DD>An end-user guide for using the CUPS software.<BR>&nbsp;
+
+</DL>
+</UL>
+
+
+<EMBED SRC="printing-overview.shtml">
+
+
+<H1 ALIGN="RIGHT"><A NAME="BUILDING_INSTALLING">2 - Building and Installing CUPS</A></H1>
+
+<P>This chapter shows how to build and install the Common UNIX Printing System.
+If you are installing a binary distribution from the CUPS web site, proceed to
+the section titled, <A HREF="#BINARY">Installing a Binary Distribution</A>.
+
+<H2>Installing a Source Distribution</H2>
+
+<P>This section describes how to compile and install CUPS on your system
+from the source code.
+
+<H3><A NAME="REQUIREMENTS">Requirements</A></H3>
+
+<P>You'll need ANSI-compliant C and C++ compilers to build CUPS on your
+system. As its name implies, CUPS is designed to run on the UNIX
+operating system, however the CUPS interface library and most of the
+filters and backends supplied with CUPS should also compile and run
+under Microsoft Windows.
+
+<P>For the image file filters and PostScript RIP, you'll need the JPEG,
+PNG, TIFF, and ZLIB libraries. CUPS will build without these, but with
+significantly reduced functionality. Easy Software Products maintains a
+mirror of the current versions of these libraries at:
+
+<UL><PRE>
+<A HREF="ftp://ftp.easysw.com/pub/libraries">ftp://ftp.easysw.com/pub/libraries</A>
+</PRE></UL>
+
+<P>If you make changes to the man pages you'll need GNU groff or another
+nroff-like package. GNU groff is available from:
+
+<UL><PRE>
+<A HREF="ftp://ftp.gnu.org/pub/groff">ftp://ftp.gnu.org/pub/groff</A>
+</PRE></UL>
+
+<P>The documentation is formatted using the HTMLDOC software. If you need to
+make changes you can get the HTMLDOC software from:
+
+<UL><PRE>
+<A HREF="http://www.easysw.com/htmldoc">http://www.easysw.com/htmldoc</A>
+</PRE></UL>
+
+<P>Finally, you'll need a <CODE>make</CODE> program that
+understands the <CODE>include</CODE> directive - FreeBSD,
+NetBSD, and OpenBSD developers should use the <CODE>gmake</CODE>
+program.
+
+<H3><A NAME="COMPILING">Compiling CUPS</A></H3>
+
+<P>CUPS uses GNU autoconf to configure the makefiles and source code
+for your system. Type the following command to configure CUPS for your
+system:
+
+<UL><PRE>
+<B>./configure ENTER</B>
+</PRE></UL>
+
+<P>The default installation will put the CUPS software in the
+<VAR>/etc</VAR>, <VAR>/usr</VAR>, and <VAR>/var</VAR> directories on
+your system, which will overwrite any existing printing commands on
+your system. Use the <CODE>--prefix</CODE> option to install the CUPS
+software in another location:
+
+<UL><PRE>
+<B>./configure --prefix=/some/directory ENTER</B>
+</PRE></UL>
+
+<P>If the PNG, JPEG, TIFF, and ZLIB libraries are not installed in a
+system default location (typically <VAR>/usr/include</VAR> and
+<VAR>/usr/lib</VAR>) you'll need to set the <CODE>CFLAGS</CODE>,
+<CODE>CXXFLAGS</CODE>, and <CODE>LDFLAGS</CODE> environment variables
+prior to running configure:
+
+<UL><PRE>
+<B>setenv CFLAGS "-I/some/directory" ENTER</B>
+<B>setenv CXXFLAGS "-I/some/directory" ENTER</B>
+<B>setenv LDFLAGS "-L/some/directory" ENTER</B>
+<B>setenv DSOFLAGS "-L/some/directory" ENTER</B>
+<B>./configure ... ENTER</B>
+</PRE></UL>
+
+<P>or:
+
+<UL><PRE>
+<B>CFLAGS="-I/some/directory"; export CFLAGS ENTER</B>
+<B>CXXFLAGS="-I/some/directory"; export CXXFLAGS ENTER</B>
+<B>LDFLAGS="-L/some/directory"; export LDFLAGS ENTER</B>
+<B>DSOFLAGS="-L/some/directory"; export DSOFLAGS ENTER</B>
+<B>./configure ... ENTER</B>
+</PRE></UL>
+
+<P>To enable support for encryption, you'll also want to add the
+"--enable-ssl" option:
+
+<UL><PRE>
+./configure --enable-ssl
+</PRE></UL>
+
+<P>SSL and TLS support require the OpenSSL library, available at:
+
+<UL><PRE>
+<A HREF="http://www.openssl.org">http://www.openssl.org</A>
+</PRE></UL>
+
+<P>If the OpenSSL headers and libraries are not installed in the
+standard directories, use the <CODE>--with-openssl-includes</CODE>
+and <CODE>--with-openssl-libs</CODE> options:</P>
+
+<UL><PRE>
+./configure --enable-ssl \
+ --with-openssl-includes=/foo/bar/include \
+ --with-openssl-libs=/foo/bar/lib
+</PRE></UL>
+
+<P>Once you have configured things, just type:
+
+<UL><PRE>
+<B>make ENTER</B>
+</PRE></UL>
+
+<P>to build the software.
+
+<!-- NEED 4in -->
+<H3><A NAME="INSTALLING">Installing the Software</A></H3>
+
+<P>Use the "install" target to install the software:
+
+<UL><PRE>
+<B>make install ENTER</B>
+</PRE></UL>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" BGCOLOR="#cccccc" CELLPADDING="5">
+<TR>
+ <TD>
+ <B>WARNING:</B>
+
+ <P>Installing CUPS will overwrite your existing printing
+ system. If you experience difficulties with the CUPS software
+ and need to go back to your old printing system, you will need
+ to reinstall the old printing system from your operating system CDs.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H3><A NAME="RUNNING">Running the Software</A></A></H3>
+
+<P>Once you have installed the software you can start the CUPS server by
+typing:
+
+<UL><PRE>
+<B>/usr/sbin/cupsd ENTER</B>
+</PRE></UL>
+
+<!-- NEED 4in -->
+<H2><A NAME="BINARY">Installing a Binary Distribution</A></H2>
+
+<P>CUPS comes in a variety of binary distribution formats. Easy
+Software Products provides binaries in TAR format with installation and
+removal scripts ("portable" distributions), and in RPM and DPKG formats
+for Red Hat and Debian-based distributions. Portable distributions are
+available for all platforms, while the RPM and DPKG distributions are
+only available for Linux.
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" BGCOLOR="#cccccc" CELLPADDING="5">
+<TR>
+ <TD>
+ <B>WARNING:</B>
+
+ <P>Installing CUPS will overwrite your existing printing
+ system. If you experience difficulties with the CUPS software
+ and need to go back to your old printing system, you will need
+ to remove the CUPS software with the provided script and/or
+ reinstall the old printing system from your operating system CDs.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+
+<H3><A NAME="PORTABLE-BINARY">Installing a Portable Distribution</A></H3>
+
+<P>To install the CUPS software from a portable distribution you will
+need to be logged in as root; doing an <CODE>su</CODE> is good enough.
+Once you are the root user, run the installation script with:
+
+<UL><PRE>
+<B>./cups.install ENTER</B>
+</PRE></UL>
+
+<P>After asking you a few yes/no questions the CUPS software will be
+installed and the scheduler will be started automatically.
+
+<!-- NEED 2in -->
+<H3><A NAME="RPM-BINARY">Installing an RPM Distribution</A></H3>
+
+<P>To install the CUPS software from an RPM distribution you will need
+to be logged in as root; doing an <CODE>su</CODE> is good enough. Once
+you are the root user, run RPM with:
+
+<UL><PRE>
+<B>rpm -e lpr</B>
+<B>rpm -i cups-1.1-linux-M.m.n-intel.rpm ENTER</B>
+</PRE></UL>
+
+<P>After a short delay the CUPS software will be
+installed and the scheduler will be started automatically.
+
+<H3><A NAME="DPKG-BINARY">Installing an Debian Distribution</A></H3>
+
+<P>To install the CUPS software from a Debian distribution you will
+need to be logged in as root; doing an <CODE>su</CODE> is good enough.
+Once you are the root user, run dpkg with:
+
+<UL><PRE>
+<B>dpkg -i cups-1.1-linux-M.m.n-intel.deb ENTER</B>
+</PRE></UL>
+
+<P>After a short delay the CUPS software will be installed and the
+scheduler will be started automatically.
+
+
+<H1 ALIGN="RIGHT"><A NAME="MANAGING_PRINTERS">3 - Managing Printers</A></H1>
+
+<P>This chapter describes how to add your first printer and how to
+manage your printers.
+
+<H2>The Basics</H2>
+
+<P>Each printer queue has a name associated with it; the printer name
+must start with a letter and can contain up to 127 letters, numbers,
+and the underscore (_). Case is not significant, e.g. "PRINTER", "Printer",
+and "printer" are considered to be the same name.
+
+<P>Printer queues also have a device associated with them. The device can be
+a parallel port, a network interface, and so forth. Devices within CUPS use
+Uniform Resource Identifiers ("URIs") which are a more general form of
+Uniform Resource Locators ("URLs") that are used in your web browser. For
+example, the first parallel port in Linux usually uses a device URI of
+<CODE>parallel:/dev/lp1</CODE>.
+
+<!-- NEED 2.5in -->
+<P>You can see a complete list of supported devices by running the
+<CODE>lpinfo(8)</CODE> command:
+
+<UL><PRE>
+<B>lpinfo -v ENTER</B>
+file file
+network socket
+network http
+network ipp
+network lpd
+direct parallel:/dev/lp1
+serial serial:/dev/ttyS1?baud=115200
+serial serial:/dev/ttyS2?baud=115200
+direct usb:/dev/usb/lp0
+network smb
+</PRE></UL>
+
+<P>The <CODE>-v</CODE> option specifies that you want a list of available
+devices. The first word in each line is the type of device (direct, file,
+network, or serial) and is followed by the device URI or method name for
+that device. File devices have device URIs of the form
+<CODE>file:/directory/filename</CODE> while network devices use the more
+familiar <CODE>method://server</CODE> or <CODE>method://server/path</CODE>
+format.
+
+<P>Finally, printer queues usually have a PostScript Printer Description
+("PPD") file associated with them. PPD files describe the capabilities of
+each printer, the page sizes supported, etc., and are used for PostScript
+and non-PostScript printers. CUPS includes PPD files for HP LaserJet, HP
+DeskJet, EPSON 9-pin, EPSON 24-pin, and EPSON Stylus printers.
+
+<H2>Adding Your First Printer</H2>
+
+<P>CUPS provides two methods for adding printers: a command-line
+program called <CODE>lpadmin(8)</CODE> and a Web interface. The
+<CODE>lpadmin</CODE> command allows you to perform most printer
+administration tasks from the command-line and is located in
+<VAR>/usr/sbin</VAR>. The Web interface is located at:
+
+<UL><PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE></UL>
+
+<P>and steps you through printer configuration. If you don't like
+command-line interfaces, try the <A HREF="#ADD_WEB">Web interface</A> instead.
+
+<H3>Adding Your First Printer from the Command-Line</H3>
+
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> option to add a
+printer to CUPS:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -E -v <I>device</I> -m <I>ppd</I> ENTER</B>
+</PRE></UL>
+
+<P>For a HP DeskJet printer connected to the parallel port this would look
+like:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p DeskJet -E -v parallel:/dev/lp1 -m deskjet.ppd ENTER</B>
+</PRE></UL>
+
+<P>Similarly, a HP LaserJet printer using a JetDirect network interface at
+IP address 11.22.33.44 would be added with the command:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p LaserJet -E -v socket://11.22.33.44 -m laserjet.ppd ENTER</B>
+</PRE></UL>
+
+<P>As you can see, <CODE>deskjet.ppd</CODE> and <CODE>laserjet.ppd</CODE> are
+the PPD files for the HP DeskJet and HP LaserJet drivers included with CUPS.
+You'll find a complete list of PPD files and the printers they will work with
+in <A HREF="#PRINTER_DRIVERS">Appendix C, "Printer Drivers"</A>.
+
+
+<P>For a dot matrix printer connected to the serial port this would might look like:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p DotMatrix -E -v serial:/dev/ttyS0?baud=9600+size=8+parity=none+flow=soft deskjet.ppd ENTER</B>
+</PRE></UL>
+
+<P>Here you specify the serial port (e.g. S0,S1, d0, d1), baud rate
+(e.g. 9600, 19200, 38400, 115200, etc.), number of bits, parity, and flow control.
+If you do not need flow control, delete the "+flow=soft" portion.
+
+
+<H3><A NAME="ADD_WEB">Adding Your First Printer from the Web</A></H3>
+
+<P>The CUPS web server provides a user-friendly "wizard" interface for
+adding your printers. Rather than figuring out which device URI and PPD file
+to use, you can instead click on the appropriate listings and fill in some
+simple information. Enter the following URL in your web browser to begin:
+
+<UL><PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE></UL>
+
+<P>Click on the <VAR>Add Printer</VAR> button to add a printer.
+
+<H2>Managing Printers from the Command-Line</H2>
+
+<P>The <CODE>lpadmin</CODE> command enables you to perform most printer
+administration tasks from the command-line. You'll find <CODE>lpadmin</CODE>
+in the <VAR>/usr/sbin</VAR> directory.
+
+<H3>Adding and Modifying Printers</H3>
+
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> option
+to add or modify a printer:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> <I>options</I> ENTER</B>
+</PRE></UL>
+
+<P>The <I>options</I> arguments can be any of the following:
+
+<UL>
+<DL>
+
+ <DT>-c <I>class</I>
+
+ <DD>Adds the named printer to printer class <VAR>class</VAR>.
+ If the class does not exist then it is created.
+
+ <DT>-i <I>interface</I>
+
+ <DD>Copies the named <VAR>interface</VAR> script to the printer.
+ Interface scripts are used by System V printer drivers. Since
+ all filtering is disabled when using an interface script, scripts
+ generally should not be used unless there is no other driver for
+ a printer.
+
+ <DT>-m <I>model</I>
+
+ <DD>Specifies a standard printer driver which is usually a PPD
+ file. A list of all available models can be displayed using the
+ <CODE>lpinfo</CODE> command with the <CODE>-m</CODE> option. A
+ list of printer drivers included with CUPS can be found in
+ <A HREF="#PRINTER_DRIVERS">Appendix C, "Printer Drivers"</A>.
+
+ <DT>-r <I>class</I>
+
+ <DD>Removes the named printer from printer class <VAR>class</CODE>.
+ If the resulting class becomes empty then it is removed.
+
+ <DT>-v <I>device-uri</I>
+
+ <DD>Sets the device for communicating with the printer. If a
+ job is currently printing on the named printer then the job
+ will be restarted and sent to the new device.
+
+ <DT>-D <I>info</I>
+
+ <DD>Provides a textual description of the printer, e.g.
+ "John's Personal Printer".
+
+ <DT>-E
+
+ <DD>Enables the printer and accepts job. This option is
+ equivalent to running the <CODE>enable(1)</CODE> and
+ <CODE>accept(8)</CODE> commands on the printer.
+
+ <DT>-L <I>location</I>
+
+ <DD>Provides a textual location for the printer, e.g.
+ "Computer Lab 5".
+
+ <DT>-P <I>ppd-file</I>
+
+ <DD>Specifies a local PPD file for the printer driver.
+
+</DL>
+</UL>
+
+<H3>Deleting Printers</H3>
+
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-x</CODE> option
+to delete a printer:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -x <I>printer</I> ENTER</B>
+</PRE></UL>
+
+<H3>Setting the Default Printer</H3>
+
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-d</CODE> option
+to set a default printer:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -d <I>printer</I> ENTER</B>
+</PRE></UL>
+
+<P>The default printer can be overridden by the user using the
+<CODE>lpoptions(1)</CODE> command.
+
+<H3>Starting and Stopping Printers</H3>
+
+<P>The <CODE>enable</CODE> and <CODE>disable</CODE> commands start and stop
+printer queues, respectively:
+
+<UL><PRE>
+<B>/usr/bin/enable <I>printer</I> ENTER</B>
+<B>/usr/bin/disable <I>printer</I> ENTER</B>
+</PRE></UL>
+
+<P>Printers that are disabled may still accept jobs for printing, but won't
+actually print any files until they are restarted. This is useful if the
+printer malfunctions and you need time to correct the problem. Any queued
+jobs are printed after the printer is enabled (started).
+
+<H3>Accepting and Rejecting Print Jobs</H3>
+
+<P>The <CODE>accept</CODE> and <CODE>reject</CODE> commands accept and reject
+print jobs for the named printer, respectively:
+
+<UL><PRE>
+<B>/usr/sbin/accept <I>printer</I> ENTER</B>
+<B>/usr/sbin/reject <I>printer</I> ENTER</B>
+</PRE></UL>
+
+<P>As noted above, a printer can be stopped but accepting new print
+jobs. A printer can also be rejecting new print jobs while it finishes
+those that have been queued. This is useful for when you must perform
+maintenance on the printer and will not have it available to users for
+a long period of time.
+
+<H3>Setting Quotas on a Printer</A></H3>
+
+<P>CUPS supports page and size-based quotas for each printer.
+The quotas are tracked individually for each user, but a single set of
+limits applies to all users for a partiuclar printer. For example, you
+can limit every user to 5 pages per day on an expensive printer, but
+you cannot limit every user except Johnny.</P>
+
+<P>The <I>job-k-limit</I>, <I>job-page-limit</I>, and <I>job-quota-peiod</I>
+options determine whether and how quotas are enforced for a printer.
+The <I>job-quota-period</I> option determines the time interval for
+quota tracking. The interval is expressed in seconds, so a day is
+86,400, a week is 604,800 and a month is 2,592,000 seconds. The
+<I>job-k-limit</I> option specifies the job size limit in killobytes. The
+<I>job-page-limit</I> option specifies the number of pages limit.</P>
+
+<P>For quotas to be enforced, the period and at least one of the limits
+must be set to a non-zero value. The following options will enable
+quotas:</P>
+
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -o job-quota-period=604800 -o job-k-limit=1024 <I>ENTER</I></B>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -o job-quota-period=604800 -o job-page-limit=100 <I>ENTER</I></B>
+</PRE>
+</UL>
+
+<P>Or, you can combine all three options on the same line.</P>
+
+<H3>Restricting User Access to a Printer</A></H3>
+
+<P>The <CODE>-u</CODE> option of the <CODE>lpadmin</CODE> command controls which users can
+print to a printer. The default configuration allows all users to print
+to a printer:</P>
+
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u allow:all <I>ENTER</I></B>
+</PRE>
+</UL>
+
+<P>CUPS supports allow and deny lists so that you can specify a
+list of users who are allowed to print or not allowed to print. Along
+with your list of users, you can specify whether they are allowed or
+not allowed to use the printer:</P>
+
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u allow:peter,paul,mary <I>ENTER</I></B>
+</PRE>
+</UL>
+
+<P>This command allows peter, paul, and mary to print to the named
+printer, but all other users cannot print. The command:</P>
+
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u deny:peter,paul,mary <I>ENTER</I></B>
+</PRE>
+</UL>
+
+<P>has the opposite effect. All users except peter, paul, and mary will
+be able to print to the named printer.</P>
+
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR>
+ <TD><B>NOTE:</B>
+
+ <P>The <I>allow</I> and <I>deny</I> options are not cummulative. That
+ is, you must provide the complete list of users to allow or deny each
+ time.</P>
+
+ <P>Also, CUPS only maintains one list of users - the list can
+ allow or deny users from printing. If you specify an allow list and
+ then specify a deny list, the deny list will replace the allow list -
+ only one list is active at any time.</P>
+
+ </TD>
+</TR>
+</TABLE>
+</CENTER>
+
+<H2>Managing Printers from the Web</H2>
+
+<P>The Web interface is located at:
+
+<UL><PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE></UL>
+
+<P>From there you can perform all printer management tasks with a few
+simple mouse clicks.
+
+
+<H1 ALIGN="RIGHT"><A NAME="PRINTER_CLASSES">4 - Printer Classes</A></H1>
+
+<P>This chapter describes what printer classes are and how to manage them.
+
+<H2>The Basics</H2>
+
+<P>CUPS provides collections of printers called <I>printer classes</I>. Jobs
+sent to a class are forwarded to the first available printer in the class.
+Classes can themselves be members of other classes, so it is possible for
+you to define very large, distributed printer classes for high-availability
+printing.
+
+<P>CUPS also supports <I>implicit classes</I>. Implicit classes work just
+like printer classes, but they are created automatically based upon the
+available printers and classes on the network. This allows you to setup
+multiple print servers with identical printer configurations and have the
+client machines send their print jobs to the first available server. If
+one or more servers go down, the jobs are automatically redirected to the
+servers that are running, providing fail-safe printing.
+
+<H2>Managing Printer Classes from the Command-Line</H2>
+
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> and <CODE>-c</CODE> options
+to add a printer to a class:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -c <I>class</I> ENTER</B>
+</PRE></UL>
+
+<P>The <I>class</I> is created automatically if it doesn't exist. To remove a
+printer from a class use the <CODE>-r</CODE> option:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -r <I>class</I> ENTER</B>
+</PRE></UL>
+
+<P>To remove the entire class just use the <CODE>-x</CODE> option:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -x <I>class</I> ENTER</B>
+</PRE></UL>
+
+<H2>Managing Printer Classes from the Web Interface</H2>
+
+<P>The Web interface is located at:
+
+<UL><PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE></UL>
+
+<P>The <VAR>Add Class</VAR> and <VAR>Modify Class</VAR> interfaces provide a
+list of available printers; click on the printers of interest to add them to
+the class.
+
+<H2>Implicit Classes</H2>
+
+<P>A noted earlier, implicit classes are created automatically from the
+available network printers and classes. To disable this functionality,
+set the <A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A>
+directive to <CODE>Off</CODE> in the <CODE>cupsd.conf</CODE> file. You
+will find more information on doing this in
+<A HREF="#PRINTING_MANAGEMENT">Chapter 6, "Printing System
+Management"</A>.
+
+
+<H1 ALIGN="RIGHT"><A NAME="CLIENT_SETUP">5 - Client Setup</A></H1>
+
+<P>This chapter discusses several ways to configure CUPS clients for
+printing.
+
+<H2>The Basics</H2>
+
+<P>A client is any machine that sends print jobs to another machine for
+final printing. Clients can also be servers if they communicate directly with
+any printers of their own.
+
+<P>CUPS supports several methods of configuring client machines:
+
+<UL>
+ <LI><A HREF="#CLIENT_MANUAL">Manual configuration of print queues.</A>
+ <LI><A HREF="#CLIENT_SERVER">Specifying a single server for printing.</A>
+ <LI><A HREF="#CLIENT_AUTO">Automatic configuration of print queues.</A>
+ <LI><A HREF="#CLIENT_POLL">Specifying multiple servers for printing.</A>
+ <LI><A HREF="#CLIENT_RELAY">Relaying printers to other clients.</A>
+</UL>
+
+<H3><A NAME="CLIENT_MANUAL">Manual Configuration of Print Queues</A></H3>
+
+<P>The most tedious method of configuring client machines is to configure
+each remote queue by hand using the <CODE>lpadmin</CODE> command:
+
+<UL><PRE>
+<B>lpadmin -p <I>printer</I> -E -v ipp://<I>server</I>/printers/<I>printer</I> ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>printer</CODE> name is the name of the printer on the server
+machine. The <CODE>server</CODE> name is the hostname or IP address of the
+server machine. Repeat the <CODE>lpadmin</CODE> command for each remote
+printer you wish to use.</P>
+
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+ <TR>
+ <TD><B> NOTE:</B>
+ <P>Manual configuration of print queues is not recommended for large
+ numbers of client machines because of the administration nightmare it
+ creates. For busy networks, consider subnetting groups of clients and
+ polling and relaying printer information instead.</P>
+ </TD>
+ </TR>
+</TABLE>
+</CENTER>
+
+<H3><A NAME="CLIENT_SERVER">Specifying a Single Server for Printing</A></H3>
+
+<P>CUPS can be configured to run without a local spooler and send all
+jobs to a single server. However, if that server goes down then all
+printing will be disabled. Use this configuration only as absolutely needed.
+
+<P>The default server is normally "localhost". To override the default
+server create a file named <VAR>/etc/cups/client.conf</VAR> and add
+a line reading:
+
+<UL><PRE>
+ServerName <I>server</I>
+</PRE></UL>
+
+<P>to the file. The <VAR>server</VAR> name can be the hostname or IP address
+of the default server.
+
+<P>The default server can also be customized on a per-user basis. To set a
+user-specific server create a file named <VAR>~/.cupsrc</VAR> and add a line
+reading:
+
+<UL><PRE>
+ServerName <I>server</I>
+</PRE></UL>
+
+<P>to the file. The <VAR>server</VAR> name can be the hostname or IP
+address of the default server.
+
+<H3><A NAME="CLIENT_AUTO">Automatic Configuration of Print Queues</A></H3>
+
+<P>CUPS supports automatic client configuration of printers on the same
+subnet. To configure printers on the same subnet, <I>do nothing</I>.
+Each client should see the available printers within 30 seconds
+automatically. The printer and class lists are updated automatically as
+printers and servers are added or removed.
+
+<P>If you want to see printers on other subnets as well, use the
+<A HREF="#BrowsePoll"><CODE>BrowsePoll</CODE></A>
+directive as described next.</P>
+
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+ <TR>
+ <TD><B> NOTE:</B>
+ <P>The<A HREF="#BrowseAddress"> <CODE>BrowseAddress</CODE></A> directive
+ enables broadcast traffic from your server. The default configuration
+ braodcasts printer information every 30 seconds. Although this printer
+ information does not use much bandwidth, typically about 80 bytes per
+ printer, it can add up with large numbers of servers and printers.</P>
+ <P>Use the <A HREF="#BrowseInterval"><CODE>BrowseInterval</CODE></A>
+ and <A HREF="#BrowseTimeout"><CODE>BrowseTimeout</CODE></A> directives to tune
+ the amount of data that is added to your network load. In addition,
+ subnets can be used to minimize the amount of traffic that is carried
+ by the &quot;backbone&quot; of your large network.</P>
+ </TD>
+ </TR>
+</TABLE>
+</CENTER>
+
+<H3><A NAME="CLIENT_POLL">Specifying Multiple Servers for Printing</A></H3>
+
+<P>If you have CUPS servers on different subnets, then you should configure
+CUPS to poll those servers. Polling provides the benefits of automatic
+configuration without significant configuration on the clients, and multiple
+clients on the same subnet can share the same configuration information.
+
+<P>Polling is enabled by specifying one or more
+<A HREF="#BrowsePoll"><CODE>BrowsePoll</CODE></A>
+directives in the <VAR>/etc/cups/cupsd.conf</VAR> file.
+For information on making these changes, see
+<A HREF="#PRINTING_MANAGEMENT">Chapter 6, "Printing System Management"</A>.
+
+<P>Multiple <A HREF="#BrowsePoll"><CODE>BrowsePoll</CODE></A> lines can
+be used to poll multiple CUPS servers. To limit the amount of
+polling you do from client machines, you can have only one of the
+clients do the polling and relay that information to the others on the
+same subnet (described next).</P>
+
+<H3><A NAME="CLIENT_RELAY">Relaying Printers to Other Clients</A></H3>
+
+<P>When you have clients and servers spread across multiple subnets, the
+polling method is inefficient. CUPS provides a
+<A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A> directive that enables a
+single client to relay (broadcast) the polled printer information to the local subnet.</P>
+
+<P>For example, Server A and Server B are on subnet 1 and subnet 2,
+while the clients are on subnet 3.
+To provide printers to all of the clients in subnet 3,
+client C will be configured with the following directives in <VAR>/etc/cups/cupsd.conf</VAR>:</P>
+
+<UL><PRE>
+# Poll the two servers
+<B>
+BrowsePoll ServerA ENTER
+BrowsePoll ServerB ENTER
+</B>
+
+# Relay the printers to the local subnet
+<B>
+BrowseRelay 127.0.0.1 192.168.3.255 ENTER
+</B></PRE></UL>
+
+<P>The <A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A> line specifies a source address and mask.
+Any browse packets coming from a matching address wil be sent to the given broadcast address.
+In this case, we want the packets from the local machine (127.0.0.1) relayed to the other clients.</P>
+
+<P>As printers are found using polling,
+they are relayed from client C to the rest of the clients through a broadcast on subnet 3.
+The rest of the clients can use the standard <VAR>cupsd.conf</VAR> configuration.</P>
+
+<P>The <A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A> directive can also be used to relay
+browsing packets from one network interface to another.
+For example, if client C in the previous example had network interfaces attaches to both
+subnet 1 and subnet 2, it could use the <A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A> directive exclusively:
+
+<UL><PRE>
+# Relay the printers from subnet 1 and 2 to subnet 3
+<B>
+BrowseRelay 192.168.1 192.168.3.255 ENTER
+BrowseRelay 192.168.2 192.168.3.255 ENTER
+</B></PRE></UL>
+
+<H2>Load Balancing and Failsafe Operation</H2>
+
+<P>When using server polling or broadcasting, CUPS clients can
+automatically merge identical printers on multiple servers into a
+single <I>implicit class</I> queue. Clients assume that printers with
+the same name on multiple servers are in fact the same printer or type
+of printer being served by multiple machines.</P>
+
+<P>If you have two printers, LaserJet@ServerA and LaserJet@ServerB, a
+third implicit class called <I>LaserJet</I> will be created
+automatically on the client that refers to both printers. If the client
+also has a local printer with the name LaserJet then an implicit class
+named <I>AnyLaserJet</I> will be created instead.</P>
+
+<P>The client will alternate between servers and automatically stop
+sending jobs to a server if it goes down, providing a load-balancing
+effect and fail-safe operation with automatic switchover.</P>
+
+<CENTER><TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+ <TR>
+ <TD><B> NOTE:</B>
+ <P>Note that implicit classes (<A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A>)
+ are enabled by default.</P>
+ </TD>
+ </TR>
+</TABLE></CENTER>
+
+<H1 ALIGN="RIGHT"><A NAME="PRINTING_MANAGEMENT">6 - Printing System Management</A></H1>
+
+<P>This chapter shows how you can configure the CUPS server.
+
+<H2>The Basics</H2>
+
+<P>Several text files are used to configure CUPS. All of the server
+configuration files are located in the <VAR>/etc/cups</VAR> directory:
+
+<UL>
+<DL>
+
+ <!-- NEED 1in -->
+ <DT>classes.conf
+
+ <DD>This file contains information on each printer class.
+ Normally you manipulate this file using the
+ <CODE>lpadmin</CODE> command or the Web interface.<BR>&nbsp;
+
+ <!-- NEED 1in -->
+ <DT>client.conf
+
+ <DD>This file provides the default server name for client
+ machines. See <A HREF="#CLIENT_SETUP">Chapter 5, "Client
+ Setup"</A> for more information.<BR>&nbsp;
+
+ <!-- NEED 1in -->
+ <DT>cupsd.conf
+
+ <DD>This file controls how the CUPS server
+ (<VAR>/usr/sbin/cupsd</VAR>) operates and is normally edited by
+ hand.<BR>&nbsp;
+
+ <!-- NEED 1in -->
+ <DT>mime.convs
+
+ <DD>This file contains a list of standard file conversion filters
+ and their costs. You normally do not edit this file.<BR>&nbsp;
+
+ <!-- NEED 1in -->
+ <DT>mime.types
+
+ <DD>This file contains a list of standard file formats and how to
+ recognize them. You normally do not edit this file.<BR>&nbsp;
+
+ <!-- NEED 1in -->
+ <DT>printers.conf
+
+ <DD>This file contains information on each printer. Normally
+ you manipulate this file using the <CODE>lpadmin</CODE> command
+ or the Web Interface.<BR>&nbsp;
+
+</DL>
+</UL>
+
+<H2><A NAME="RESTARTING">Restarting the CUPS Server</A></H2>
+
+<P>Once you have made a change to a configuration file you need to
+restart the CUPS server by sending it a <CODE>HUP</CODE> signal or using the
+supplied initialization script. The CUPS distributions install the
+script in the <VAR>init.d</VAR> directory with the name
+<VAR>cups</VAR>. The location varies based upon the operating system:
+
+<UL><PRE>
+<B>/etc/software/init.d/cups restart ENTER</B>
+<B>/etc/rc.d/init.d/cups restart ENTER</B>
+<B>/etc/init.d/cups restart ENTER</B>
+<B>/sbin/init.d/cups restart ENTER</B>
+</PRE></UL>
+
+<H2>Changing the Server Configuration</H2>
+
+<P>The <VAR>/etc/cups/cupsd.conf</VAR> file contains configuration
+<I>directives</I> that control how the server functions. Each directive
+is listed on a line by itself followed by its value. Comments are
+introduced using the number sign ("#") character at the beginning of a
+line. Since the server configuration file consists of plain text, you
+can use your favorite text editor to make changes to it.
+
+<!-- NEED 4in -->
+<H2>Server Directives</H2>
+
+<P>The <VAR>cupsd.conf</VAR> file contains many directives that
+determine how the server operates:
+
+<UL>
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0">
+<TR>
+<TD VALIGN="TOP">
+
+ <LI><A HREF="#AccessLog"><CODE>AccessLog</CODE></A>
+ <LI><A HREF="#Allow"><CODE>Allow</CODE></A>
+ <LI><A HREF="#AuthClass"><CODE>AuthClass</CODE></A>
+ <LI><A HREF="#AuthGroupName"><CODE>AuthGroupName</CODE></A>
+ <LI><A HREF="#AuthType"><CODE>AuthType</CODE></A>
+ <LI><A HREF="#AutoPurgeJobs"><CODE>AutoPurgeJobs</CODE></A>
+ <LI><A HREF="#BrowseAddress"><CODE>BrowseAddress</CODE></A>
+ <LI><A HREF="#BrowseAllow"><CODE>BrowseAllow</CODE></A>
+ <LI><A HREF="#BrowseDeny"><CODE>BrowseDeny</CODE></A>
+ <LI><A HREF="#BrowseInterval"><CODE>BrowseInterval</CODE></A>
+ <LI><A HREF="#BrowseOrder"><CODE>BrowseOrder</CODE></A>
+ <LI><A HREF="#BrowsePoll"><CODE>BrowsePoll</CODE></A>
+ <LI><A HREF="#BrowsePort"><CODE>BrowsePort</CODE></A>
+ <LI><A HREF="#BrowseProtocols"><CODE>BrowseProtocols</CODE></A>
+ <LI><A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A>
+ <LI><A HREF="#BrowseShortNames"><CODE>BrowseShortNames</CODE></A>
+ <LI><A HREF="#BrowseTimeout"><CODE>BrowseTimeout</CODE></A>
+ <LI><A HREF="#Browsing"><CODE>Browsing</CODE></A>
+ <LI><A HREF="#Classification"><CODE>Classification</CODE></A>
+ <LI><A HREF="#ClassifyOverride"><CODE>ClassifyOverride</CODE></A>
+ <LI><A HREF="#ConfigFilePerm"><CODE>ConfigFilePerm</CODE></A>
+ <LI><A HREF="#DataDir"><CODE>DataDir</CODE></A>
+ <LI><A HREF="#DefaultCharset"><CODE>DefaultCharset</CODE></A>
+ <LI><A HREF="#DefaultLanguage"><CODE>DefaultLanguage</CODE></A>
+ <LI><A HREF="#Deny"><CODE>Deny</CODE></A>
+ <LI><A HREF="#DocumentRoot"><CODE>DocumentRoot</CODE></A>
+ <LI><A HREF="#Encryption"><CODE>Encryption</CODE></A>
+
+</TD>
+<TD VALIGN="TOP">
+&nbsp;&nbsp;&nbsp;
+</TD>
+<TD VALIGN="TOP">
+
+ <LI><A HREF="#ErrorLog"><CODE>ErrorLog</CODE></A>
+ <LI><A HREF="#FilterLimit"><CODE>FilterLimit</CODE></A>
+ <LI><A HREF="#FontPath"><CODE>FontPath</CODE></A>
+ <LI><A HREF="#Group"><CODE>Group</CODE></A>
+ <LI><A HREF="#HideImplicitMembers"><CODE>HideImplicitMembers</CODE></A>
+ <LI><A HREF="#HostNameLookups"><CODE>HostNameLookups</CODE></A>
+ <LI><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A>
+ <LI><A HREF="#ImplicitAnyClasses"><CODE>ImplicitAnyClasses</CODE></A>
+ <LI><A HREF="#Include"><CODE>Include</CODE></A>
+ <LI><A HREF="#KeepAliveTimeout"><CODE>KeepAliveTimeout</CODE></A>
+ <LI><A HREF="#KeepAlive"><CODE>KeepAlive</CODE></A>
+ <LI><A HREF="#Limit"><CODE>Limit</CODE></A>
+ <LI><A HREF="#LimitExcept"><CODE>LimitExcept</CODE></A>
+ <LI><A HREF="#LimitRequestBody"><CODE>LimitRequestBody</CODE></A>
+ <LI><A HREF="#Listen"><CODE>Listen</CODE></A>
+ <LI><A HREF="#Location"><CODE>Location</CODE></A>
+ <LI><A HREF="#LogFilePerm"><CODE>LogFilePerm</CODE></A>
+ <LI><A HREF="#LogLevel"><CODE>LogLevel</CODE></A>
+ <LI><A HREF="#MaxClients"><CODE>MaxClients</CODE></A>
+ <LI><A HREF="#MaxJobs"><CODE>MaxJobs</CODE></A>
+ <LI><A HREF="#MaxJobsPerPrinter"><CODE>MaxJobsPerPrinter</CODE></A>
+ <LI><A HREF="#MaxJobsPerUser"><CODE>MaxJobsPerUser</CODE></A>
+ <LI><A HREF="#MaxLogSize"><CODE>MaxLogSize</CODE></A>
+ <LI><A HREF="#MaxRequestSize"><CODE>MaxRequestSize</CODE></A>
+ <LI><A HREF="#Order"><CODE>Order</CODE></A>
+ <LI><A HREF="#PageLog"><CODE>PageLog</CODE></A>
+
+</TD>
+<TD VALIGN="TOP">
+&nbsp;&nbsp;&nbsp;
+</TD>
+<TD VALIGN="TOP">
+
+ <LI><A HREF="#Port"><CODE>Port</CODE></A>
+ <LI><A HREF="#PreserveJobFiles"><CODE>PreserveJobFiles</CODE></A>
+ <LI><A HREF="#PreserveJobHistory"><CODE>PreserveJobHistory</CODE></A>
+ <LI><A HREF="#Printcap"><CODE>Printcap</CODE></A>
+ <LI><A HREF="#PrintcapFormat"><CODE>PrintcapFormat</CODE></A>
+ <LI><A HREF="#PrintcapGUI"><CODE>PrintcapGUI</CODE></A>
+ <LI><A HREF="#RemoteRoot"><CODE>RemoteRoot</CODE></A>
+ <LI><A HREF="#RequestRoot"><CODE>RequestRoot</CODE></A>
+ <LI><A HREF="#Require"><CODE>Require</CODE></A>
+ <LI><A HREF="#RIPCache"><CODE>RIPCache</CODE></A>
+ <LI><A HREF="#RunAsUser"><CODE>RunAsUser</CODE></A>
+ <LI><A HREF="#Satisfy"><CODE>Satisfy</CODE></A>
+ <LI><A HREF="#ServerAdmin"><CODE>ServerAdmin</CODE></A>
+ <LI><A HREF="#ServerBin"><CODE>ServerBin</CODE></A>
+ <LI><A HREF="#ServerCertificate"><CODE>ServerCertificate</CODE></A>
+ <LI><A HREF="#ServerKey"><CODE>ServerKey</CODE></A>
+ <LI><A HREF="#ServerName"><CODE>ServerName</CODE></A>
+ <LI><A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A>
+ <LI><A HREF="#SSLListen"><CODE>SSLListen</CODE></A>
+ <LI><A HREF="#SSLPort"><CODE>SSLPort</CODE></A>
+ <LI><A HREF="#SystemGroup"><CODE>SystemGroup</CODE></A>
+ <LI><A HREF="#TempDir"><CODE>TempDir</CODE></A>
+ <LI><A HREF="#Timeout"><CODE>Timeout</CODE></A>
+ <LI><A HREF="#User"><CODE>User</CODE></A>
+
+</TD>
+</TR>
+</TABLE>
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="AccessLog">AccessLog</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+AccessLog /var/log/cups/access_log
+AccessLog /var/log/cups/access_log-%s
+AccessLog syslog
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>AccessLog</CODE> directive sets the name of the access log
+file. If the filename is not absolute then it is assumed to be relative
+to the <A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+access log file is stored in "common log format" and can be used by any
+web access reporting tool to generate a report on CUPS server activity.
+
+<P>The server name can be included in the filename by using
+<CODE>%s</CODE> in the name.
+
+<P>The special name "syslog" can be used to send the access information
+to the system log instead of a plain file.
+
+<P>The default access log file is <VAR>/var/log/cups/access_log</VAR>.
+
+<!-- NEED 6in -->
+<H3><A NAME="Allow">Allow</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Allow from All
+Allow from None
+Allow from *.domain.com
+Allow from .domain.com
+Allow from host.domain.com
+Allow from nnn.*
+Allow from nnn.nnn.*
+Allow from nnn.nnn.nnn.*
+Allow from nnn.nnn.nnn.nnn
+Allow from nnn.nnn.nnn.nnn/mm
+Allow from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+Allow from @LOCAL
+Allow from @IF(name)
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Allow</CODE> directive specifies a hostname, IP address,
+or network that is allowed access to the server. <CODE>Allow</CODE>
+directives are cummulative, so multiple <CODE>Allow</CODE> directives
+can be used to allow access for multiple hosts or networks. The
+<CODE>/mm</CODE> notation specifies a CIDR netmask:
+
+<CENTER><TABLE BORDER="1">
+<TR>
+ <TH WIDTH="10%">mm</TH>
+ <TH WIDTH="20%">netmask</TH>
+ <TH WIDTH="10%">mm</TH>
+ <TH WIDTH="20%">netmask</TH>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">0</TD>
+ <TD ALIGN="CENTER">0.0.0.0</TD>
+ <TD ALIGN="CENTER">8</TD>
+ <TD ALIGN="CENTER">255.0.0.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">1</TD>
+ <TD ALIGN="CENTER">128.0.0.0</TD>
+ <TD ALIGN="CENTER">16</TD>
+ <TD ALIGN="CENTER">255.255.0.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">2</TD>
+ <TD ALIGN="CENTER">192.0.0.0</TD>
+ <TD ALIGN="CENTER">24</TD>
+ <TD ALIGN="CENTER">255.255.255.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">...</TD>
+ <TD ALIGN="CENTER">...</TD>
+ <TD ALIGN="CENTER">32</TD>
+ <TD ALIGN="CENTER">255.255.255.255</TD>
+</TR>
+</TABLE></CENTER>
+
+<P>The <CODE>@LOCAL</CODE> name will allow access from all local
+network interfaces, but not remote point-to-point interfaces. The
+<CODE>@IF(name)</CODE> name will allow access from the named
+interface.
+
+<P>The <CODE>Allow</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="AuthClass">AuthClass</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+AuthClass Anonymous
+AuthClass User
+AuthClass System
+AuthClass Group
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>AuthClass</CODE> directive defines what level of authentication
+is required:
+
+<UL>
+
+ <LI><CODE>Anonymous</CODE> - No authentication should be performed
+ (default.)
+
+ <LI><CODE>User</CODE> - A valid username and password is required.
+
+ <LI><CODE>System</CODE> - A valid username and password is
+ required, and the username must belong to the "sys" group; this
+ can be changed using the
+ <A HREF="#SystemGroup"><CODE>SystemGroup</CODE></A> directive.
+
+ <LI><CODE>Group</CODE> - A valid username and password is
+ required, and the username must belong to the group named by
+ the <CODE>AuthGroupName</CODE> directive.
+
+</UL>
+
+<P>The <CODE>AuthClass</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="AuthGroupName">AuthGroupName</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+AuthGroupName mygroup
+AuthGroupName lp
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>AuthGroupName</CODE> directive sets the group to use for
+<CODE>Group</CODE> authentication.
+
+<P>The <CODE>AuthGroupName</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="AuthType">AuthType</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+AuthType None
+AuthType Basic
+AuthType Digest
+AuthType BasicDigest
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>AuthType</CODE> directive defines the type of authentication to
+perform:
+
+<UL>
+
+ <LI><CODE>None</CODE> - No authentication should be performed
+ (default.)
+
+ <LI><CODE>Basic</CODE> - Basic authentication should be
+ performed using the UNIX password and group files.
+
+ <LI><CODE>Digest</CODE> - Digest authentication should be
+ performed using the <VAR>/etc/cups/passwd.md5</VAR> file.
+
+ <LI><CODE>BasicDigest</CODE> - Basic authentication should be
+ performed using the <VAR>/etc/cups/passwd.md5</VAR> file.
+
+</UL>
+
+<P>When using <CODE>Basic</CODE>, <CODE>Digest</CODE>, or
+<CODE>BasicDigest</CODE> authentication, clients connecting
+through the <CODE>localhost</CODE> interface can also
+authenticate using <A HREF="#CERTIFICATES">certificates</A>.
+
+<P>The <CODE>AuthType</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="AutoPurgeJobs">AutoPurgeJobs</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+AutoPurgeJobs Yes
+AutoPurgeJobs No
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>AutoPurgeJobs</CODE> directive specifies whether or not to purge
+completed jobs once they are no longer required for quotas. This option has
+no effect if quotas are not enabled. The default setting is <CODE>No</CODE>.
+
+<!-- NEED 5in -->
+<H3><A NAME="BrowseAddress">BrowseAddress</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseAddress 255.255.255.255:631
+BrowseAddress 192.0.2.255:631
+BrowseAddress host.domain.com:631
+BrowseAddress @LOCAL
+BrowseAddress @IF(name)
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseAddress</CODE> directive specifies an address to
+send browsing information to. Multiple <CODE>BrowseAddress</CODE>
+directives can be specified to send browsing information to different
+networks or systems.
+
+<P>The <CODE>@LOCAL</CODE> name will broadcast printer
+information to all local interfaces. The <CODE>@IF(name)</CODE>
+name will broadcast to the named interface.
+
+<P>No browse addresses are set by default.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>If you are using HP-UX 10.20 and a subnet that is not 24,
+ 16, or 8 bits, printer browsing (and in fact all broadcast
+ reception) will not work. This problem appears to be fixed in
+ HP-UX 11.0.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 4in -->
+<H3><A NAME="BrowseAllow">BrowseAllow</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseAllow from all
+BrowseAllow from none
+BrowseAllow from 192.0.2
+BrowseAllow from 192.0.2.0/24
+BrowseAllow from 192.0.2.0/255.255.255.0
+BrowseAllow from *.domain.com
+BrowseAllow from @LOCAL
+BrowseAllow from @IF(name)
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseAllow</CODE> directive specifies a system or network
+to accept browse packets from. The default is to accept browse packets
+from all hosts.
+
+<P>Host and domain name matching require that you enable the
+<A HREF="#HostNameLookups"><CODE>HostNameLookups</CODE></A> directive.
+
+<P>IP address matching supports exact matches, partial addresses that
+match networks using netmasks of 255.0.0.0, 255.255.0.0, and 255.255.255.0,
+or network addresses using the specified netmask or bit count.
+
+<P>The <CODE>@LOCAL</CODE> name will allow browse data from all
+local network interfaces, but not remote point-to-point
+interfaces. The <CODE>@IF(name)</CODE> name will allow browse
+data from the named interface.
+
+
+<!-- NEED 4in -->
+<H3><A NAME="BrowseDeny">BrowseDeny</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseDeny from all
+BrowseDeny from none
+BrowseDeny from 192.0.2
+BrowseDeny from 192.0.2.0/24
+BrowseDeny from 192.0.2.0/255.255.255.0
+BrowseDeny from *.domain.com
+BrowseDeny from @LOCAL
+BrowseDeny from @IF(name)
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseDeny</CODE> directive specifies a system or network
+to reject browse packets from. The default is to deny browse packets
+from no hosts.
+
+<P>Host and domain name matching require that you enable the
+<A HREF="#HostNameLookups"><CODE>HostNameLookups</CODE></A> directive.
+
+<P>IP address matching supports exact matches, partial addresses that
+match networks using netmasks of 255.0.0.0, 255.255.0.0, and 255.255.255.0,
+or network addresses using the specified netmask or bit count.
+
+<P>The <CODE>@LOCAL</CODE> name will block browse data from all
+local network interfaces, but not remote point-to-point
+interfaces. The <CODE>@IF(name)</CODE> name will block browse
+data from the named interface.
+
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseOrder">BrowseOrder</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseOrder allow,deny
+BrowseOrder deny,allow
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseOrder</CODE> directive specifies the order of allow/deny
+processing. The default order is <CODE>deny,allow</CODE>:
+
+<UL>
+
+ <LI><CODE>allow,deny</CODE> - Browse packets are accepted unless
+ specifically denied.
+
+ <LI><CODE>deny,allow</CODE> - Browse packets are rejected unless
+ specifically allowed.
+
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseInterval">BrowseInterval</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseInterval 0
+BrowseInterval 30
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseInterval</CODE> directive specifies the maximum amount of
+time between browsing updates. Specifying a value of 0 seconds disables
+outgoing browse updates but allows a server to receive printer information
+from other hosts.
+
+<P>The <CODE>BrowseInterval</CODE> value should always be less than the
+<A HREF="#BrowseTimeout"><CODE>BrowseTimeout</CODE></A> value. Otherwise
+printers and classes will disappear from client systems between updates.
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowsePoll">BrowsePoll</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowsePoll 192.0.2.2:631
+BrowsePoll host.domain.com:631
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowsePoll</CODE> directive polls a server for available
+printers once every
+<A HREF="#BrowseInterval"><CODE>BrowseInterval</CODE></A> seconds.
+Multiple <CODE>BrowsePoll</CODE> directives can be specified to poll
+multiple servers.
+
+<P>If <CODE>BrowseInterval</CODE> is set to 0 then the server is polled
+once every 30 seconds.
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowsePort">BrowsePort</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowsePort 631
+BrowsePort 9999
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowsePort</CODE> directive specifies the UDP port number
+used for browse packets. The default port number is 631.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>You must set the <CODE>BrowsePort</CODE> to the same value
+ on all of the systems that you want to see.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseProtocols">BrowseProtocols</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseProtocols CUPS
+BrowseProtocols SLP
+BrowseProtocols CUPS SLP
+BrowseProtocols all
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseProtocols</CODE> directive specifies the protocols to
+use when collecting and distributing shared printers on the local network.
+The default protocol is <CODE>CUPS</CODE>, which is a broadcast-based
+protocol.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>When using the <CODE>SLP</CODE> protocol, you must have at least
+ one Directory Agent (DA) server on your network. Otherwise the
+ CUPS scheduler (<CODE>cupsd</CODE>) will not respond to client
+ requests for several seconds while polling the network.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 4in -->
+<H3><A NAME="BrowseRelay">BrowseRelay</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseRelay 193.0.2.1 192.0.2.255
+BrowseRelay 193.0.2.0/255.255.255.0 192.0.2.255
+BrowseRelay 193.0.2.0/24 192.0.2.255
+BrowseRelay *.domain.com 192.0.2.255
+BrowseRelay host.domain.com 192.0.2.255
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseRelay</CODE> directive specifies source and destination
+addresses for relaying browsing information from one host or network to
+another. Multiple <CODE>BrowseRelay</CODE> directives can be specified
+as needed.
+
+<P><CODE>BrowseRelay</CODE> is typically used on systems that bridge
+multiple subnets using one or more network interfaces. It can also be
+used to relay printer information from polled servers with the line:
+
+<UL><PRE>
+BrowseRelay 127.0.0.1 255.255.255.255
+</PRE></UL>
+
+<P>This effectively provides access to printers on a WAN for all clients
+on the LAN(s).
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseShortNames">BrowseShortNames</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseShortNames Yes
+BrowseShortNames No
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseShortNames</CODE> directive specifies whether or not
+short names are used for remote printers when possible. Short names are
+just the remote printer name, without the server ("printer"). If more than
+one remote printer is detected with the same name, the printers will have
+long names ("printer@server1", "printer@server2".)
+
+<P>The default value for this option is <CODE>Yes</CODE>.
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseTimeout">BrowseTimeout</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseTimeout 300
+BrowseTimeout 60
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseTimeout</CODE> directive sets the timeout for
+printer or class information that is received in browse packets. Once a
+printer or class times out it is removed from the list of available
+destinations.
+
+<P>The <CODE>BrowseTimeout</CODE> value should always be greater than the
+<A HREF="#BrowseInterval"><CODE>BrowseInterval</CODE></A> value. Otherwise
+printers and classes will disappear from client systems between updates.
+
+<!-- NEED 4in -->
+<H3><A NAME="Browsing">Browsing</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Browsing On
+Browsing Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Browsing</CODE> directive controls whether or not network printer
+browsing is enabled. The default setting is <CODE>On</CODE>.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>If you are using HP-UX 10.20 and a subnet that is not 24,
+ 16, or 8 bits, printer browsing (and in fact all broadcast
+ reception) will not work. This problem appears to be fixed in
+ HP-UX 11.0.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="Classification">Classification</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Classification
+Classification classified
+Classification confidential
+Classification secret
+Classification topsecret
+Classification unclassified
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Classification</CODE> directive sets the classification level
+on the server. When this option is set, at least one of the banner pages
+is forced to the classification level, and the classification is placed
+on each page of output. The default is no classification level.
+
+<!-- NEED 3in -->
+<H3><A NAME="ClassifyOverride">ClassifyOverride</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ClassifyOverride Yes
+ClassifyOverride No
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ClassifyOverride</CODE> directive specifies whether users
+can override the default classification level on the server. When the
+server classification is set, users can change the classification using
+the <CODE>job-sheets</CODE> option and can choose to only print one
+security banner before or after the job. If the <CODE>job-sheets</CODE>
+option is set to <CODE>none</CODE> then the server default classification
+is used.
+
+<P>The default is to not allow classification overrides.
+
+<!-- NEED 3in -->
+<H3><A NAME="ConfigFilePerm">ConfigFilePerm</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ConfigFilePerm 0644
+ConfigFilePerm 0600
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ConfigFilePerm</CODE> directive specifies the permissions
+to use when writing configuration files. The default is 0600.
+
+<!-- NEED 3in -->
+<H3><A NAME="DataDir">DataDir</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+DataDir /usr/share/cups
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>DataDir</CODE> directive sets the directory to use for data
+files.
+
+<!-- NEED 3in -->
+<H3><A NAME="DefaultCharset">DefaultCharset</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+DefaultCharset utf-8
+DefaultCharset iso-8859-1
+DefaultCharset windows-1251
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>DefaultCharset</CODE> directive sets the default character set
+to use for client connections. The default character set is
+<CODE>utf-8</CODE> but is overridden by the character set for the language
+specified by the client or the <CODE>DefaultLanguage</CODE> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="DefaultLanguage">DefaultLanguage</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+DefaultLanguage de
+DefaultLanguage en
+DefaultLanguage es
+DefaultLanguage fr
+DefaultLanguage it
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>DefaultLanguage</CODE> directive specifies the default language
+to use for client connections. Setting the default language also sets the
+default character set if a language localization file exists for it. The
+default language is "en" for English.
+
+<!-- NEED 5in -->
+<H3><A NAME="Deny">Deny</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Deny from All
+Deny from None
+Deny from *.domain.com
+Deny from .domain.com
+Deny from host.domain.com
+Deny from nnn.*
+Deny from nnn.nnn.*
+Deny from nnn.nnn.nnn.*
+Deny from nnn.nnn.nnn.nnn
+Deny from nnn.nnn.nnn.nnn/mm
+Deny from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+Deny from @LOCAL
+Deny from @IF(name)
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Deny</CODE> directive specifies a hostname, IP address, or
+network that is allowed access to the server. <CODE>Deny</CODE>
+directives are cummulative, so multiple <CODE>Deny</CODE> directives
+can be used to allow access for multiple hosts or networks. The
+<CODE>/mm</CODE> notation specifies a CIDR netmask:
+
+<CENTER><TABLE BORDER="1">
+<TR>
+ <TH WIDTH="10%">mm</TH>
+ <TH WIDTH="20%">netmask</TH>
+ <TH WIDTH="10%">mm</TH>
+ <TH WIDTH="20%">netmask</TH>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">0</TD>
+ <TD ALIGN="CENTER">0.0.0.0</TD>
+ <TD ALIGN="CENTER">8</TD>
+ <TD ALIGN="CENTER">255.0.0.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">1</TD>
+ <TD ALIGN="CENTER">128.0.0.0</TD>
+ <TD ALIGN="CENTER">16</TD>
+ <TD ALIGN="CENTER">255.255.0.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">2</TD>
+ <TD ALIGN="CENTER">192.0.0.0</TD>
+ <TD ALIGN="CENTER">24</TD>
+ <TD ALIGN="CENTER">255.255.255.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">...</TD>
+ <TD ALIGN="CENTER">...</TD>
+ <TD ALIGN="CENTER">32</TD>
+ <TD ALIGN="CENTER">255.255.255.255</TD>
+</TR>
+</TABLE></CENTER>
+
+<P>The <CODE>@LOCAL</CODE> name will deny access from all local
+network interfaces, but not remote point-to-point interfaces. The
+<CODE>@IF(name)</CODE> name will deny access from the named
+interface.
+
+<P>The <CODE>Deny</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="DocumentRoot">DocumentRoot</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+DocumentRoot /usr/share/doc/cups
+DocumentRoot /foo/bar/doc/cups
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>DocumentRoot</CODE> directive specifies the location of
+web content for the HTTP server in CUPS. If an absolute path is not
+specified then it is assumed to be relative to the
+<A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+default directory is <VAR>/usr/share/doc/cups</VAR>.
+
+<P>Documents are first looked up in a sub-directory for the primary
+language requested by the client (e.g. <VAR>/usr/share/doc/cups/fr/...</VAR>)
+and then directly under the <CODE>DocumentRoot</CODE> directory
+(e.g. <VAR>/usr/share/doc/cups/...</VAR>), so it is possible to localize
+the web content by providing subdirectories for each language needed.
+
+<!-- NEED 3in -->
+<H3><A NAME="Encryption">Encryption</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Encryption Never
+Encryption IfRequested
+Encryption Required
+Encryption Always
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Encryption</CODE> directive must appear instead a
+<A HREF="#Location"><CODE>Location</CODE></A>
+section and specifies the encryption settings for that location.
+The default setting is <CODE>IfRequested</CODE> for all locations.
+
+<!-- NEED 3in -->
+<H3><A NAME="ErrorLog">ErrorLog</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ErrorLog /var/log/cups/error_log
+ErrorLog /var/log/cups/error_log-%s
+ErrorLog syslog
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ErrorLog</CODE> directive sets the name of the error log
+file. If the filename is not absolute then it is assumed to be relative
+to the <A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+default error log file is <VAR>/var/log/cups/error_log</VAR>.
+
+<P>The server name can be included in the filename by using
+<CODE>%s</CODE> in the name.
+
+<P>The special name "syslog" can be used to send the error information
+to the system log instead of a plain file.
+
+<!-- NEED 3in -->
+<H3><A NAME="FilterLimit">FilterLimit</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+FilterLimit 0
+FilterLimit 200
+FilterLimit 1000
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>FilterLimit</CODE> directive sets the maximum cost
+of all running job filters. It can be used to limit the number
+of filter programs that are run on a server to minimize disk,
+memory, and CPU resource problems. A limit of 0 disables filter
+limiting.
+
+<P>An average print to a non-PostScript printer needs a filter
+limit of about 200. A PostScript printer needs about half that
+(100). Setting the limit below these thresholds will effectively
+limit the scheduler to printing a single job at any time.
+
+<P>The default limit is 0.
+
+<!-- NEED 3in -->
+<H3><A NAME="FontPath">FontPath</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+FontPath /foo/bar/fonts
+FontPath /usr/share/cups/fonts:/foo/bar/fonts
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>FontPath</CODE> directive specifies the font path to use when
+searching for fonts. The default font path is
+<CODE>/usr/share/cups/fonts</CODE>.
+
+<!-- NEED 3in -->
+<H3><A NAME="Group">Group</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Group sys
+Group system
+Group root
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Group</CODE> directive specifies the UNIX group that
+filter and CGI programs run as. The default group is <CODE>sys</CODE>,
+<CODE>system</CODE>, or <CODE>root</CODE> depending on the operating
+system.
+
+<!-- NEED 3in -->
+<H3><A NAME="HideImplicitMembers">HideImplicitMembers</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+HideImplicitMembers Yes
+HideImplicitMembers No
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>HideImplicitMembers</CODE> directive controls
+whether the individual printers in an implicit class are shown
+to the user. The default is <CODE>No</CODE>.</P>
+
+<P><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A>
+must be enabled for this directive to have any effect.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="HostNameLookups">HostNameLookups</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+HostNameLookups On
+HostNameLookups Off
+HostNameLookups Double
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>HostNameLookups</CODE> directive controls whether
+or not CUPS looks up the hostname for connecting clients. The
+<CODE>Double</CODE> setting causes CUPS to verify that the
+hostname resolved from the address matches one of the addresses
+returned for that hostname. <CODE>Double</CODE> lookups also
+prevent clients with unregistered addresses from connecting
+to your server.
+
+The default is <CODE>Off</CODE> to avoid the potential server
+performance problems with hostname lookups. Set this option to
+<CODE>On</CODE> or <CODE>Double</CODE> only if absolutely
+required.
+
+<!-- NEED 3in -->
+<H3><A NAME="ImplicitClasses">ImplicitClasses</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ImplicitClasses On
+ImplicitClasses Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ImplicitClasses</CODE> directive controls whether implicit
+classes are created based upon the available network printers and classes.
+The default setting is <CODE>On</CODE> but is automatically turned
+<CODE>Off</CODE> if <A HREF="#Browsing"><CODE>Browsing</CODE></A> is
+turned <CODE>Off</CODE>.
+
+<!-- NEED 3in -->
+<H3><A NAME="ImplicitAnyClasses">ImplicitAnyClasses</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ImplicitAnyClasses On
+ImplicitAnyClasses Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ImplicitAnyClasses</CODE> directive controls
+whether implicit classes for local and remote printers are
+created with the name <CODE>AnyPrinter</CODE>. The default
+setting is <CODE>Off</CODE>.</P>
+
+<P><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A>
+must be enabled for this directive to have any effect.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="Include">Include</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Include filename
+Include /foo/bar/filename
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Include</CODE> directive includes the named file in
+the <CODE>cupsd.conf</CODE> file. If no leading path is
+provided, the file is assumed to be relative to the
+<A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="KeepAlive">KeepAlive</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+KeepAlive On
+KeepAlive Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>KeepAlive</CODE> directive controls whether or not to support
+persistent HTTP connections. The default is <CODE>On</CODE>.
+
+<P>HTTP/1.1 clients automatically support persistent connections, while
+HTTP/1.0 clients must specifically request them using the
+<CODE>Keep-Alive</CODE> attribute in the <CODE>Connection:</CODE>
+field of each request.
+
+<!-- NEED 3in -->
+<H3><A NAME="KeepAliveTimeout">KeepAliveTimeout</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+KeepAliveTimeout 60
+KeepAliveTimeout 30
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>KeepAliveTimeout</CODE> directive controls how long a
+persistent HTTP connection will remain open after the last request. The
+default is 60 seconds.
+
+<!-- NEED 3in -->
+<H3><A NAME="Limit">Limit</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+&lt;Limit GET POST&gt;
+...
+&lt;/Limit&gt;
+
+&lt;Limit ALL&gt;
+...
+&lt;/Limit&gt;
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Limit</CODE> directive groups access control directives for
+specific types of HTTP requests and must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> section. Access can be limited
+for individual request types (<CODE>DELETE</CODE>, <CODE>GET</CODE>,
+<CODE>HEAD</CODE>, <CODE>OPTIONS</CODE>, <CODE>POST</CODE>, <CODE>PUT</CODE>,
+and <CODE>TRACE</CODE>) or for all request types (<CODE>ALL</CODE>). The
+request type names are case-sensitive for compatibility with Apache.
+
+<!-- NEED 3in -->
+<H3><A NAME="LimitExcept">LimitExcept</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+&lt;LimitExcept GET POST&gt;
+...
+&lt;/LimitExcept&gt;
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>LimitExcept</CODE> directive groups access control directives for
+specific types of HTTP requests and must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> section. Unlike the
+<A HREF="#Limit"><CODE>Limit</CODE></A> directive, <CODE>LimitExcept</CODE>
+restricts access for all requests <I>except</I> those listed on the
+<CODE>LimitExcept</CODE> line.
+
+<!-- NEED 3in -->
+<H3><A NAME="LimitRequestBody">LimitRequestBody</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+LimitRequestBody 10485760
+LimitRequestBody 10m
+LimitRequestBody 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>LimitRequestBody</CODE> directive controls the maximum size of
+print files, IPP requests, and HTML form data in HTTP POST requests. The
+default limit is 0 which disables the limit check.
+
+<P>Also see the identical
+<A HREF="#MaxRequestSize"><CODE>MaxRequestSize</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="Listen">Listen</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Listen 127.0.0.1:631
+Listen 192.0.2.1:631
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Listen</CODE> directive specifies a network address and port
+to listen for connections. Multiple <CODE>Listen</CODE> directives can be
+provided to listen on multiple addresses.
+
+<P>The <CODE>Listen</CODE> directive is similar to the
+<A HREF="#Port"><CODE>Port</CODE></A> directive but allows you to restrict
+access to specific interfaces or networks.
+
+<!-- NEED 3in -->
+<H3><A NAME="Location">Location</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+&lt;Location /&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /admin&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /printers&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /printers/name&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /classes&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /classes/name&gt;
+...
+&lt;/Location&gt;
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Location</CODE> directive specifies access control and
+authentication options for the specified HTTP resource or path.
+The
+<A HREF="#Allow"><CODE>Allow</CODE></A>,
+<A HREF="#AuthClass"><CODE>AuthClass</CODE></A>,
+<A HREF="#AuthGroupName"><CODE>AuthGroupName</CODE></A>,
+<A HREF="#AuthType"><CODE>AuthType</CODE></A>,
+<A HREF="#Deny"><CODE>Deny</CODE></A>,
+<A HREF="#Encryption"><CODE>Encryption</CODE></A>,
+<A HREF="#Limit"><CODE>Limit</CODE></A>,
+<A HREF="#LimitExcept"><CODE>LimitExcept</CODE></A>,
+<A HREF="#Order"><CODE>Order</CODE></A>,
+<A HREF="#Require"><CODE>Require</CODE></A>, and
+<A HREF="#Satisfy"><CODE>Satisfy</CODE></A>
+directives may all appear inside a location.
+
+<CENTER><TABLE BORDER="1"><CAPTION>Locations on the Server.</CAPTION>
+<TR><TH>Location</TH><TH>Description</TH></TR>
+<TR><TD>/</TD><TD>The path for all get operations (get-printers, get-jobs, etc.)</TD></TR>
+<TR><TD>/admin</TD><TD>The path for all administration operations (add-printer, delete-printer, start-printer, etc.)</TD></TR>
+<TR><TD>/admin/conf</TD><TD>The path for access to the ESP Print Pro configuration files (cupsd.conf, client.conf, etc.)</TD></TR>
+<TR><TD>/classes</TD><TD>The path for all classes</TD></TR>
+<TR><TD>/classes/name</TD><TD>The resource for class <CODE>name</CODE></TD></TR>
+<TR><TD>/jobs</TD><TD>The path for all jobs (hold-job, release-job, etc.)</TD></TR>
+<TR><TD>/jobs/id</TD><TD>The resource for job <CODE>id</CODE></TD></TR>
+<TR><TD>/printers</TD><TD>The path for all printers</TD></TR>
+<TR><TD>/printers/name</TD><TD>The path for printer <CODE>name</CODE></TD></TR>
+<TR><TD>/printers/name.ppd</TD><TD>The PPD file path for printer <CODE>name</CODE></TD></TR>
+</TABLE></CENTER>
+
+<P>Note that more specific resources override the less specific ones.
+So the directives inside the <CODE>/printers/name</CODE> location will override ones from <CODE>/printers</CODE>.
+Directives inside <CODE>/printers</CODE> will override ones from <CODE>/</CODE>. &nbsp;
+None of the directives are inherited.
+More information can be found in section <A HREF="#PRINTING_SECURITY">"Printing System Security"</A>.
+
+<!-- NEED 3in -->
+<H3><A NAME="LogFilePerm">LogFilePerm</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+LogFilePerm 0644
+LogFilePerm 0600
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>LogFilePerm</CODE> directive specifies the permissions
+to use when writing configuration files. The default is 0644.
+
+<!-- NEED 3in -->
+<H3><A NAME="LogLevel">LogLevel</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+LogLevel none
+LogLevel emerg
+LogLevel alert
+LogLevel crit
+LogLevel error
+LogLevel warn
+LogLevel notice
+LogLevel info
+LogLevel debug
+LogLevel debug2
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>LogLevel</CODE> directive specifies the level of logging
+for the <A HREF="#ErrorLog"><CODE>ErrorLog</CODE></A> file. The
+following values are recognized (each level logs everything under the
+preceding levels):
+
+<UL>
+
+ <LI><CODE>none</CODE> - Log nothing.
+
+ <LI><CODE>emerg</CODE> - Log emergency conditions that prevent the
+ server from running.
+
+ <LI><CODE>alert</CODE> - Log alerts that must be handled immediately.
+
+ <LI><CODE>crit</CODE> - Log critical errors that don't prevent
+ the server from running.
+
+ <LI><CODE>error</CODE> - Log general errors.
+
+ <LI><CODE>warn</CODE> - Log errors and warnings.
+
+ <LI><CODE>notice</CODE> - Log temporary error conditions.
+
+ <LI><CODE>info</CODE> - Log all requests and state changes (default).
+
+ <LI><CODE>debug</CODE> - Log basic debugging information.
+
+ <LI><CODE>debug2</CODE> - Log all debugging information.
+
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxClients">MaxClients</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxClients 100
+MaxClients 1024
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxClients</CODE> directive controls the maximum number of
+simultaneous clients that will be allowed by the server. The default is
+100 clients.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Since each print job requires a file descriptor for the
+ status pipe, the CUPS server internally limits the
+ <CODE>MaxClients</CODE> value to 1/3 of the available file descriptors
+ to avoid possible problems when printing large numbers of jobs.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxJobs">MaxJobs</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxJobs 100
+MaxJobs 9999
+MaxJobs 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxJobs</CODE> directive controls the maximum number of jobs
+that are kept in memory. Once the number of jobs reaches the limit, the
+oldest completed job is automatically purged from the system to make room
+for the new one. If all of the known jobs are still pending or active then
+the new job will be rejected.
+
+<P>Setting the maximum to 0 disables this functionality. The default
+setting is 0.
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxJobsPerPrinter">MaxJobsPerPrinter</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxJobsPerPrinter 100
+MaxJobsPerPrinter 9999
+MaxJobsPerPrinter 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxJobsPerPrinter</CODE> directive controls the maximum number of active jobs
+that are allowed for each printer or class. Once a printer or class reaches the limit, new jobs will be
+rejected until one of the active jobs is completed, stopped, aborted, or cancelled.
+
+<P>Setting the maximum to 0 disables this functionality. The default
+setting is 0.
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxJobsPerUser">MaxJobsPerUser</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxJobsPerUser 100
+MaxJobsPerUser 9999
+MaxJobsPerUser 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxJobsPerUser</CODE> directive controls the maximum number of active jobs
+that are allowed for each user. Once a user reaches the limit, new jobs will be
+rejected until one of the active jobs is completed, stopped, aborted, or cancelled.
+
+<P>Setting the maximum to 0 disables this functionality. The default
+setting is 0.
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxLogSize">MaxLogSize</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxLogSize 1048576
+MaxLogSize 1m
+MaxLogSize 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxLogSize</CODE> directive controls the maximum size of each
+log file. Once a log file reaches or exceeds the maximum size it is closed
+and renamed to <VAR>filename.O</VAR>. This allows you to rotate the logs
+automatically. The default size is 1048576 bytes (1MB).
+
+<P>Setting the maximum size to 0 disables log rotation.
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxRequestSize">MaxRequestSize</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxRequestSize 10485760
+MaxRequestSize 10m
+MaxRequestSize 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxRequestSize</CODE> directive controls the maximum size of
+print files, IPP requests, and HTML form data in HTTP POST requests. The
+default limit is 0 which disables the limit check.
+
+<P>Also see the identical
+<A HREF="#LimitRequestBody"><CODE>LimitRequestBody</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="Order">Order</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Order Allow,Deny
+Order Deny,Allow
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Order</CODE> directive defines the default access control.
+The following values are supported:
+
+<UL>
+
+ <LI><CODE>Allow,Deny</CODE> - Allow requests from all
+ systems <I>except</I> for those listed in a <CODE>Deny</CODE>
+ directive.
+
+ <LI><CODE>Deny,Allow</CODE> - Allow requests only from
+ those listed in an <CODE>Allow</CODE> directive.
+
+</UL>
+
+<P>The <CODE>Order</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="PageLog">PageLog</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+PageLog /var/log/cups/page_log
+PageLog /var/log/cups/page_log-%s
+PageLog syslog
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>PageLog</CODE> directive sets the name of the page log
+file. If the filename is not absolute then it is assumed to be relative
+to the <A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+default page log file is <VAR>/var/log/cups/page_log</VAR>.
+
+<P>The server name can be included in the filename by using
+<CODE>%s</CODE> in the name.
+
+<P>The special name "syslog" can be used to send the page information
+to the system log instead of a plain file.
+
+<!-- NEED 3in -->
+<H3><A NAME="Port">Port</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Port 631
+Port 80
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Port</CODE> directive specifies a port to listen on.
+Multiple <CODE>Port</CODE> lines can be specified to listen on multiple
+ports. The default port is 631.
+
+<!-- NEED 3in -->
+<H3><A NAME="PreserveJobHistory">PreserveJobHistory</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+PreserveJobHistory On
+PreserveJobHistory Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>PreserveJobHistory</CODE> directive controls whether
+the history of completed, cancelled, or aborted print jobs is stored
+on disk.
+
+<P>A value of <CODE>On</CODE> (the default) preserves job information
+until the administrator purges it with the <CODE>cancel</CODE>
+command.
+
+<P>A value of <CODE>Off</CODE> removes the job information as soon as
+each job is completed, cancelled, or aborted.
+
+<!-- NEED 3in -->
+<H3><A NAME="PreserveJobFiles">PreserveJobFiles</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+PreserveJobFiles On
+PreserveJobFiles Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>PreserveJobFiles</CODE> directive controls whether the
+document files of completed, cancelled, or aborted print jobs are
+stored on disk.
+
+<P>A value of <CODE>On</CODE> preserves job files until the
+administrator purges them with the <CODE>cancel</CODE> command. Jobs
+can be restarted (and reprinted) as desired until they are purged.
+
+<P>A value of <CODE>Off</CODE> (the default) removes the job files as
+soon as each job is completed, cancelled, or aborted.
+
+<!-- NEED 3in -->
+<H3><A NAME="Printcap">Printcap</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Printcap
+Printcap /etc/printcap
+Printcap /etc/printers.conf
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Printcap</CODE> directive controls whether or not a
+printcap file is automatically generated and updated with a list
+of available printers. If specified with no value, then no
+printcap file will be generated. The default is to generate a
+file named <VAR>/etc/printcap</VAR>.
+
+<P>When a filename is specified (e.g. <VAR>/etc/printcap</VAR>), the
+printcap file is written whenever a printer is added or removed. The
+printcap file can then be used by applications that are hardcoded to
+look at the printcap file for the available printers.
+
+<!-- NEED 3in -->
+<H3><A NAME="PrintcapFormat">PrintcapFormat</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+PrintcapFormat BSD
+PrintcapFormat Solaris
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>PrintcapFormat</CODE> directive controls the output
+format of the printcap file. The default is to generate a BSD
+printcap file.
+
+<!-- NEED 3in -->
+<H3><A NAME="PrintcapGUI">PrintcapGUI</A></H3>
+<HR>
+
+<H4>Example</H4>
+
+<UL><PRE>
+PrintcapGUI /usr/bin/glpoptions
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>PrintcapGUI</CODE> directive sets the program to
+use when displaying an option panel from an IRIX application
+that uses the Impressario print API. The default program is the
+ESP Print Pro "glpoptions" GUI.
+
+<P>The program must accept the <CODE>-d</CODE> option to specify
+a printer and the <CODE>-o</CODE> option to specify one or more
+options. After allowing the user to select/change options, the
+program must then write the list of printing options without the
+<CODE>-o</CODE> to the standard output.
+
+<!-- NEED 3in -->
+<H3><A NAME="RemoteRoot">RemoteRoot</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+RemoteRoot remroot
+RemoteRoot root
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>RemoteRoot</CODE> directive sets the username for
+unauthenticated root requests from remote hosts. The default
+username is <VAR>remroot</VAR>. Setting <CODE>RemoteRoot</CODE>
+to <VAR>root</VAR> effectively disables this security mechanism.
+
+<!-- NEED 3in -->
+<H3><A NAME="RequestRoot">RequestRoot</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+RequestRoot /var/spool/cups
+RequestRoot /foo/bar/spool/cups
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>RequestRoot</CODE> directive sets the directory for
+incoming IPP requests and HTML forms. If an absolute path is not
+provided then it is assumed to be relative to the
+<A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+default request directory is <VAR>/var/spool/cups</VAR>.
+
+<!-- NEED 4in -->
+<H3><A NAME="Require">Require</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Require group foo bar
+Require user john mary
+Require valid-user
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Require</CODE> directive specifies that
+authentication is required for the resource. The
+<CODE>group</CODE> keyword specifies that the authenticated user
+must be a member of one or more of the named groups that follow.
+
+<P>The <CODE>user</CODE> keyboard specifies that the
+authenticated user must be one of the named users that follow.
+
+<P>The <CODE>valid-user</CODE> keyword specifies that any
+authenticated user may access the resource.
+
+<P>The default is to do no authentication. This directive must
+appear inside a <A HREF="#Location"><CODE>Location</CODE></A>
+directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="RIPCache">RIPCache</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+RIPCache 8m
+RIPCache 1g
+RIPCache 2048k
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>RIPCache</CODE> directive sets the size of the memory
+cache used by Raster Image Processor ("RIP") filters such as
+<CODE>imagetoraster</CODE> and <CODE>pstoraster</CODE>. The size can
+be suffixed with a "k" for kilobytes, "m" for megabytes, or
+"g" for gigabytes. The default cache size is "8m", or 8 megabytes.
+
+<!-- NEED 3in -->
+<H3><A NAME="RunAsUser">RunAsUser</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+RunAsUser Yes
+RunAsUser No
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>RunAsUser</CODE> directive controls whether the
+scheduler runs as the unpriviledged user account (usually <CODE>lp</CODE>).
+The default is <CODE>No</CODE> which leaves the scheduler running as
+the <CODE>root</CODE> user.
+
+<P><B>Note:</B> Running as a non-priviledged user may prevent
+LPD and locally connected printers from working due to
+permission problems. The <CODE>lpd</CODE> backend will
+automatically use a non-priviledged mode that is not 100%
+compliant with RFC 1179. The <CODE>parallel</CODE>,
+<CODE>serial</CODE>, and <CODE>usb</CODE> backends will need
+write access to the corresponding device files.
+
+<!-- NEED 3in -->
+<H3><A NAME="Satisfy">Satisfy</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Satisfy all
+Satisfy any
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Satisfy</CODE> directive specifies whether all
+conditions must be satisfied to allow access to the resource. If
+set to <CODE>all</CODE>, then all authentication and access
+control conditions must be satified to allow access.
+
+<P>Setting <CODE>Satisfy</CODE> to <CODE>any</CODE> allows a user to
+gain access if the authentication or access control requirements are
+satisfied. For example, you might require authentication for remote
+access, but allow local access without authentication.
+
+<P>The default is <CODE>all</CODE>. This directive must appear
+inside a <A HREF="#Location"><CODE>Location</CODE></A>
+directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerAdmin">ServerAdmin</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerAdmin user@host
+ServerAdmin root@foo.bar.com
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerAdmin</CODE> directive identifies the email address for the
+administrator on the system. By default the administrator email address is
+<CODE>root@server</CODE>, where <CODE>server</CODE> is the server name.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerBin">ServerBin</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerBin /usr/lib/cups
+ServerBin /foo/bar/lib/cups
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerBin</CODE> directive sets the directory for
+server-run executables. If an absolute path is not provided then it is
+assumed to be relative to the
+<A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+default executable directory is <VAR>/usr/lib/cups</VAR>.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerCertificate">ServerCertificate</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerCertificate /etc/cups/ssl/server.crt
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerCertificate</CODE> directive specifies the
+location of the SSL certificate file used by the server when
+negotiating encrypted connections. The certificate must not be
+encrypted (password protected) since the scheduler normally runs
+in the background and will be unable to ask for a password.
+The default certificate file is <VAR>/etc/cups/ssl/server.crt</VAR>.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerKey">ServerKey</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerKey /etc/cups/ssl/server.key
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerKey</CODE> directive specifies the location
+of the SSL private key file used by the server when negotiating
+encrypted connections. The default key file is
+<VAR>/etc/cups/ssl/server.crt</VAR>.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerName"></A>ServerName</H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerName foo.domain.com
+ServerName myserver.domain.com
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerName</CODE> directive specifies the hostname that is
+reported to clients. By default the server name is the hostname.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerRoot">ServerRoot</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerRoot /etc/cups
+ServerRoot /foo/bar/cups
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerRoot</CODE> directive specifies the absolute path to
+the server configuration and state files. It is also used to resolve
+relative paths in the <VAR>cupsd.conf</VAR> file. The default server
+directory is <VAR>/etc/cups</VAR>.
+
+<!-- NEED 3in -->
+<H3><A NAME="SSLListen">SSLListen</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+SSLListen 127.0.0.1:443
+SSLListen 192.0.2.1:443
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>SSLListen</CODE> directive specifies a network
+address and port to listen for secure connections. Multiple
+<CODE>SSLListen</CODE> directives can be provided to listen on
+multiple addresses.
+
+<P>The <CODE>SSLListen</CODE> directive is similar to the
+<A HREF="#SSLPort"><CODE>SSLPort</CODE></A> directive but allows
+you to restrict access to specific interfaces or networks.
+
+<!-- NEED 3in -->
+<H3><A NAME="SSLPort">SSLPort</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+SSLPort 443
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>SSLPort</CODE> directive specifies a port to listen
+on for secure connections. Multiple <CODE>SSLPort</CODE> lines
+can be specified to listen on multiple ports.
+
+<!-- NEED 3in -->
+<H3><A NAME="SystemGroup">SystemGroup</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+SystemGroup sys
+SystemGroup system
+SystemGroup root
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>SystemGroup</CODE> directive specifies the system
+administration group for <CODE>System</CODE> authentication. More
+information can be found later in this chapter in
+<A HREF="#PRINTING_SECURITY">"Printing System Security"</A>.
+
+<!-- NEED 3in -->
+<H3><A NAME="TempDir">TempDir</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+TempDir /var/tmp
+TempDir /foo/bar/tmp
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>TempDir</CODE> directive specifies an absolute path for
+the directory to use for temporary files. The default directory is
+<VAR>/var/tmp</VAR>.
+
+<P>Temporary directories must be world-writable and should have the
+"sticky" permission bit enabled so that other users cannot delete
+filter temporary files. The following commands will create an
+appropriate temporary directory called <VAR>/foo/bar/tmp</VAR>:
+
+<UL><PRE>
+<B>mkdir /foo/bar/tmp ENTER</B>
+<B>chmod a+rwxt /foo/bar/tmp ENTER</B>
+</PRE></UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="Timeout">Timeout</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Timeout 300
+Timeout 90
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Timeout</CODE> directive controls the amount of time to
+wait before an active HTTP or IPP request times out. The default
+timeout is 300 seconds.
+
+<!-- NEED 3in -->
+<H3><A NAME="User">User</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+User lp
+User guest
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>User</CODE> directive specifies the UNIX user that
+filter and CGI programs run as. The default user is <CODE>lp</CODE>.
+
+<!-- NEW PAGE -->
+<H2><A NAME="PRINTING_SECURITY">Printing System Security</A></H2>
+
+<P>CUPS provides support for address, certificate, and password (Basic
+and Digest) based authentication and access control. Certificate and
+password authentication provide ways to limit access to individual
+people or groups.
+
+<P>Address based access control allows you to limit access to specific
+systems, networks, or domains. While this does not provide authentication,
+it does allow you to limit the potential users of your system efficiently.
+
+<P>CUPS maintains a list of locations that have access control and/or
+authentication enabled. Locations are specified using the
+<A HREF="#Location"><CODE>Location</CODE></A> directive:
+
+<UL><PRE>
+&lt;Location /resource&gt;
+<A HREF="#AuthClass">AuthClass</A> ...
+<A HREF="#AuthGroupName">AuthGroupName</A> ...
+<A HREF="#AuthType">AuthType</A> ...
+
+<A HREF="#Order">Order</A> ...
+<A HREF="#Allow">Allow</A> from ...
+<A HREF="#Deny">Deny</A> from ...
+&lt;/Location&gt;
+</PRE></UL>
+
+<P>Locations generally follow the directory structure of the
+<A HREF="#DocumentRoot"><CODE>DocumentRoot</CODE></A> directory, however
+CUPS does have several virtual locations for administration, classes, jobs,
+and printers:
+
+<CENTER><TABLE BORDER="1">
+<TR>
+ <TH>Location</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>/admin</TD>
+ <TD>The path for all administration operations.</TD>
+</TR>
+<TR>
+ <TD>/classes</TD>
+ <TD>The path for all classes.</TD>
+</TR>
+<TR>
+ <TD>/classes/name</TD>
+ <TD>The resource for class <CODE>name</CODE>.</TD>
+</TR>
+<TR>
+ <TD>/jobs</TD>
+ <TD>The path for all jobs.</TD>
+</TR>
+<TR>
+ <TD>/jobs/id</TD>
+ <TD>The resource for job <CODE>id</CODE>.</TD>
+</TR>
+<TR>
+ <TD>/printers</TD>
+ <TD>The path for all printers.</TD>
+</TR>
+<TR>
+ <TD>/printers/name</TD>
+ <TD>The path for printer <CODE>name</CODE>.</TD>
+</TR>
+<TR>
+ <TD>/printers/name.ppd</TD>
+ <TD>The PPD file path for printer <CODE>name</CODE>.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3><A NAME="CERTIFICATES">Authentication Using Certificates</A></H3>
+
+<P>CUPS supports a local certificate-based authentication scheme that
+can be used in place of <CODE>Basic</CODE> or <CODE>Digest</CODE>
+authentication by clients connecting through the <CODE>localhost</CODE>
+interface. Certificate authentication is not supported or allowed from
+clients on any other interface.
+
+<P>Certificates are 128-bit random numbers that refer to an internal
+authentication record in the server. A client connecting via the
+<CODE>localhost</CODE> interface sends a request with an
+authorization header of:
+
+<UL><PRE>
+Authorization: Local 0123456789ABCDEF0123456789ABCDEF
+</PRE></UL>
+
+<P>The server then looks up the local certificate and authenticates
+using the username associated with it.
+
+<P>Certificates are generated by the server automatically and stored in
+the <VAR>/etc/cups/certs</VAR> directory using the process ID of the
+CGI program started by the server. Certificate files are only readable
+by the <A HREF="#User"><CODE>User</CODE></A> and
+<A HREF="#Group"><CODE>Group</CODE></A> defined in the
+<VAR>cupsd.conf</VAR> file. When the CGI program ends the certificate
+is removed and invalidated automatically.
+
+<P>The special file <VAR>/etc/cups/certs/0</VAR> defines the <I>root
+certificate</I> which can be used by any client running as the super-user
+or another user that is part of the group defined by the
+<A HREF="#SystemGroup"><CODE>SystemGroup</CODE></A> directive. The
+root certificate is automatically regenerated every 5 minutes.
+
+<H3>Using Basic Authentication</H3>
+
+<P>Basic authentication uses UNIX users and passwords to authenticate
+access to resources such as printers and classes, and to limit access
+to administrative functions.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Basic authentication sends the username and password Base64
+ encoded from the client to the server, so it offers no
+ protection against eavesdropping. This means that a malicious
+ user can monitor network packets and discover valid users and
+ passwords that could result in a serious compromise in network
+ security. Use Basic authentication with extreme care.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<P>The CUPS implementation of Basic authentication does not allow access
+through user accounts without a password. If you try to authenticate
+using an account without a password, your access will be immediately
+blocked.
+
+<P>Once a valid username and password is authenticated by CUPS, any
+additional group membership requirements are checked.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>The root user is considered by CUPS to be a member of every
+ group.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 1in -->
+<P>Use the <CODE>AuthType</CODE> directive to enable Basic authentication:
+
+<UL><PRE>
+AuthType Basic
+</PRE></UL>
+
+<!-- NEED 7in -->
+<H3>Using Digest Authentication</H3>
+
+<P>Digest authentication uses users and passwords defined in the
+<VAR>/etc/cups/passwd.md5</VAR> file to authenticate access to
+resources such as printers and classes, and to limit access to
+administrative functions.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Unlike Basic authentication, Digest passes the MD5 sum
+ (basically a complicated checksum) of the username and password
+ instead of the strings themselves. Also, Digest authentication
+ does not use the UNIX password file, so if an attacker does
+ discover the original password it is less likely to result in a
+ serious security problem so long as you use a different UNIX
+ password than the corresponding Digest password.
+
+ <P>The current CUPS implementation of Digest authentication
+ uses the client's hostname or IP address for the "nonce" value.
+ The nonce value is an additional string added to the username
+ and password to make guessing the password more difficult. The
+ server checks that the nonce value matches the client's hostname
+ or address and rejects the MD5 sum if it doesn't. Future versions
+ of CUPS will support Digest "session" authentication which adds
+ the request data to the MD5 sum, providing even better
+ authentication and security.
+
+ <P>Digest authentication does not guarantee that an attacker
+ cannot gain unauthorized access, but it is safer than Basic
+ authentication and should be used in place of Basic
+ authentication whenever possible. <B>Support for Digest
+ authentication in web browsers is not yet universally
+ available.</B>
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 2in -->
+<P>The <CODE>lppasswd(1)</CODE> command is used to add, change, or
+remove accounts from the <VAR>passwd.md5</VAR> file. To add a
+user to the default system group, type:
+
+<UL><PRE>
+<B>lppasswd -a user ENTER</B>
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE></UL>
+
+<!-- NEED 2in -->
+<P>Once added, a user can change his/her password by typing:
+
+<UL><PRE>
+<B>lppasswd ENTER</B>
+Old password: <B>(password) ENTER</B> [password is not echoed]
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE></UL>
+
+<!-- NEED 1in -->
+<P>To remove a user from the password file, type:
+
+<UL><PRE>
+<B>lppasswd -x user ENTER</B>
+</PRE></UL>
+
+<P>Once a valid username and password is authenticated by CUPS, any
+additional group membership requirements are checked.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>The root user is considered by CUPS to be a member of every
+ group.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<P>Use the <CODE>AuthType</CODE> directive to enable Digest authentication:
+
+<UL><PRE>
+AuthType Digest
+</PRE></UL>
+
+<H3>System and Group Authentication</H3>
+
+<P>The <A HREF="#AuthClass"><CODE>AuthClass</CODE></A> directive controls
+the level of authentication to perform. <CODE>System</CODE> and
+<CODE>Group</CODE> authentication extend the normal user-based authentication
+to require membership in a UNIX group. For <CODE>System</CODE> authentication
+each user must belong to the <CODE>sys</CODE>, <CODE>system</CODE>, or
+<CODE>root</CODE> group; the actual group depends on the operating system.
+
+<P>For <CODE>Group</CODE> authentication each user must belong to the
+group named by the <A HREF="#AuthGroupName"><CODE>AuthGroupName</CODE></A>
+directive:
+
+<UL><PRE>
+&lt;Location /path&gt;
+AuthType Digest
+AuthClass Group
+AuthGroupName mygroup
+&lt;/Location&gt;
+</PRE></UL>
+
+<P>The named group must be a valid UNIX user group, usually defined in the
+<VAR>/etc/group</VAR> or <VAR>/etc/netgroup</VAR> files. Additionally, when
+using Digest authentication you need to create user accounts with the named
+group:
+
+<UL><PRE>
+<B>lppasswd -g mygroup -a user ENTER</B>
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE></UL>
+
+<!-- NEW PAGE -->
+<H2><A NAME="PRINTER_ACCOUNTING">Printer Accounting</A></H2>
+
+<P>CUPS maintains a log of all accesses, errors, and
+pages that are printed. The log files are normally stored in the
+<VAR>/var/log/cups</VAR> directory. You can change this by
+editing the <VAR>/etc/cups/cupsd.conf</VAR> configuration file.
+
+<H3>The access_log File</H3>
+
+<P>The <VAR>access_log</VAR> file lists each HTTP resource that is accessed
+by a web browser or CUPS/IPP client. Each line is in the so-called "Common
+Log Format" used by many web servers and web reporting tools:
+
+<UL><PRE>
+host group user date-time \"method resource version\" status bytes
+
+127.0.0.1 - - [20/May/1999:19:20:29 +0000] "POST /admin/ HTTP/1.1" 401 0
+127.0.0.1 - mike [20/May/1999:19:20:31 +0000] "POST /admin/ HTTP/1.1" 200 0
+</PRE></UL>
+
+<P>The <I>host</I> field will normally only be an IP address unless you
+have enabled the <A HREF="#HostNameLookups"><CODE>HostNameLookups</CODE></A>
+directive in the <VAR>cupsd.conf</VAR> file.
+
+<P>The <I>group</I> field always contains "-" in CUPS.
+
+<P>The <I>user</I> field is the authenticated username of the requesting user.
+If no username and password is supplied for the request then this field
+contains "-".
+
+<P>The <I>date-time</I> field is the date and time of the request in local time
+and is in the format:
+
+<UL><PRE>
+[DD/MON/YYYY:HH:MM:SS +ZZZZ]
+</PRE></UL>
+
+<P>where <I>ZZZZ</I> is the timezone offset in hours and minutes from Greenwich
+Mean Time (a.k.a. GMT a.k.a. ZULU.)
+
+<P>The <I>method</I> field is the HTTP method used ("GET", "PUT", "POST", etc.)
+
+<P>The <I>resource</I> field is the filename of the requested resource.
+
+<P>The <I>version</I> field is the HTTP specification version used by the
+client. For CUPS clients this will always be "HTTP/1.1".
+
+<P>The <I>status</I> field contains the HTTP result status of the
+request. Usually it is "200", but other HTTP status codes are possible.
+For example, 401 is the "unauthorized access" status in the example
+above.
+
+<P>The <I>bytes</I> field contains the number of bytes in the request.
+For POST requests the <I>bytes</I> field contains the number of bytes
+that was received from the client.
+
+<H3>The error_log File</H3>
+
+<P>The <VAR>error_log</VAR> file lists messages from the scheduler (errors,
+warnings, etc.):
+
+<UL><PRE>
+level date-time message
+
+I [20/May/1999:19:18:28 +0000] Job 1 queued on 'DeskJet' by 'mike'.
+I [20/May/1999:19:21:02 +0000] Job 2 queued on 'DeskJet' by 'mike'.
+I [20/May/1999:19:22:24 +0000] Job 2 was cancelled by 'mike'.
+</PRE></UL>
+
+<P>The <I>level</I> field contains the type of message:
+
+<UL>
+
+ <LI><CODE>E</CODE> - An error occurred.
+
+ <LI><CODE>W</CODE> - The server was unable to perform some action.
+
+ <LI><CODE>I</CODE> - Informational message.
+
+ <LI><CODE>D</CODE> - Debugging message.
+
+</UL>
+
+<P>The <I>date-time</I> field contains the date and time of when the page
+started printing. The format of this field is identical to the <I>data-time</I>
+field in the <VAR>access_log</VAR> file.
+
+<P>The <I>message</I> fields contains a free-form textual message.
+
+<H3>The page_log File</H3>
+
+<P>The <VAR>page_log</VAR> file lists each page that is sent to a printer.
+Each line contains the following information:
+
+<UL><PRE>
+printer user job-id date-time page-number num-copies job-billing
+
+DeskJet root 2 [20/May/1999:19:21:05 +0000] 1 0 acme-123
+</PRE></UL>
+
+<P>The <I>printer</I> field contains the name of the printer that
+printed the page. If you send a job to a printer class, this field will
+contain the name of the printer that was assigned the job.
+
+<P>The <I>user</I> field contains the name of the user (the IPP
+<CODE>requesting-user-name</CODE> attribute) that submitted this file for
+printing.
+
+<P>The <I>job-id</I> field contains the job number of the page being printed.
+Job numbers are reset to 1 whenever the CUPS server is started, so don't depend
+on this number being unique!
+
+<P>The <I>date-time</I> field contains the date and time of when the page
+started printing. The format of this field is identical to the <I>data-time</I>
+field in the <VAR>access_log</VAR> file.
+
+<P>The <I>page-number</I> and <I>num-pages</I> fields contain the page number
+and number of copies being printed of that page. For printer that can not
+produce copies on their own, the <I>num-pages</I> field will always be 1.
+
+<P>The <I>job-billing</I> field contains a copy of the
+<CODE>job-billing</CODE> attribute provided with the IPP
+<CODE>create-job</CODE> or <CODE>print-job</CODE> requests or "-" if none
+was provided.
+
+<!-- NEW PAGE -->
+<H2><A NAME="FILE_TYPING_FILTERING">File Typing and Filtering</A></H2>
+
+<P>CUPS provides a MIME-based file typing and filtering mechanism to
+convert files to a printable format for each printer. On startup the
+CUPS server reads MIME database files from the <VAR>/etc/cups</VAR>
+directory (or a directory specified by the
+<A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directive) to build
+a file type and conversion database in memory. These database files are
+plain ASCII text and can be edited with your favorite text editor.
+
+<P>The <VAR>mime.types</VAR> and <VAR>mime.convs</VAR> files define the
+standard file types and filters that are available on the system.
+
+<H3>mime.types</H3>
+
+<P>The <VAR>mime.types</VAR> file defines the known file types. Each line
+of the file starts with the MIME type and may be followed by one or
+more file type recognition rules. For example, the
+<CODE>text/html</CODE> file type is defined as:
+
+<UL><PRE>
+text/html html htm \
+ printable(0,1024) + \
+ (string(0,"&lt;HTML&gt;") string(0,"&lt;!DOCTYPE"))
+</PRE></UL>
+
+<P>The first two rules say that any file with an extension of
+<VAR>.html</VAR> or <VAR>.htm</VAR> is a HTML file. The third rule
+says that any file whose first 1024 characters are printable text and
+starts with the strings <CODE>&lt;HTML&gt;</CODE> or
+<CODE>&lt;!DOCTYPE</CODE> is a HTML file as well.
+
+<P>The first two rules deal solely with the name of the file being
+typed. This is useful when the original filename is known, however for
+print files the server doesn't have a filename to work with. The third
+rule takes care of this possibility and automatically figures out the
+file type based upon the contents of the file instead.
+
+<P>The available tests are:
+
+<UL>
+
+ <LI><CODE>( expr )</CODE> - Parenthesis for expression grouping
+
+ <LI><CODE>+</CODE> - Logical AND
+
+ <LI><CODE>,</CODE> or whitespace - Logical OR
+
+ <LI><CODE>!</CODE> - Logical NOT
+
+ <LI><CODE>match("pattern")</CODE> - Pattern match on filename
+
+ <LI><CODE>extension</CODE> - Pattern match on "*.extension"
+
+ <LI><CODE>ascii(offset,length)</CODE> - True if bytes are valid
+ printable ASCII (CR, NL, TAB, BS, 32-126)
+
+ <LI><CODE>printable(offset,length)</CODE> - True if bytes are
+ printable 8-bit chars (CR, NL, TAB, BS, 32-126, 160-254)
+
+ <LI><CODE>string(offset,"string")</CODE> - True if bytes are
+ identical to string
+
+ <LI><CODE>contains(offset,range,"string")</CODE> - True if the
+ range of bytes contains the string
+
+ <LI><CODE>char(offset,value)</CODE> - True if byte is identical
+
+ <LI><CODE>short(offset,value)</CODE> - True if 16-bit integer
+ is identical (network or "big-endian" byte order)
+
+ <LI><CODE>int(offset,value)</CODE> - True if 32-bit integer is
+ identical (network or "big-endian" byte order)
+
+ <LI><CODE>locale("string")</CODE> - True if current locale
+ matches string
+
+</UL>
+
+<P>All numeric values can be in decimal (123), octal (0123), or hexadecimal
+(0x123) as desired.
+
+<!-- NEED 2.5in -->
+<P>Strings can be in quotes, all by themselves, as a string
+of hexadecimal values, or some combination:
+
+<UL><PRE>
+"string"
+'string'
+string
+&lt;737472696e67&gt;
+&lt;7374&gt;ring
+</PRE></UL>
+
+<P>As shown in the <CODE>text/html</CODE> example, rules can continue on
+multiple lines using the backslash (\) character. A more complex example is
+the <CODE>image/jpeg</CODE> rules:
+
+<UL><PRE>
+image/jpeg jpeg jpg jpe string(0,&lt;FFD8FF&gt;) &amp;&amp;\
+ (char(3,0xe0) char(3,0xe1) char(3,0xe2) char(3,0xe3)\
+ char(3,0xe4) char(3,0xe5) char(3,0xe6) char(3,0xe7)\
+ char(3,0xe8) char(3,0xe9) char(3,0xea) char(3,0xeb)\
+ char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef))
+</PRE></UL>
+
+<P>This rule states that any file with an extension of
+<VAR>.jpeg</VAR>, <VAR>.jpg</VAR>, or <VAR>.jpe</VAR> is a JPEG file.
+In addition, any file starting with the hexadecimal string
+<CODE>&lt;FFD8FF&gt;</CODE> (JPEG Start-Of-Image) followed by a
+character between and including <CODE>0xe0</CODE> and <CODE>0xef</CODE>
+(JPEG APPn markers) is also a JPEG file.
+
+<H3>mime.convs</A></H3>
+
+<P>The <VAR>mime.convs</VAR> file defines all of the filter programs that
+are known to the system. Each line consists of:
+
+<UL><PRE>
+source destination cost program
+
+text/plain application/postscript 50 texttops
+application/vnd.cups-postscript application/vnd.cups-raster 50 pstoraster
+image/* application/vnd.cups-postscript 50 imagetops
+image/* application/vnd.cups-raster 50 imagetoraster
+</PRE></UL>
+
+<P>The <I>source</I> field is a MIME type, optionally using a wildcard for
+the super-type or sub-type (e.g. "text/plain", "image/*", "*/postscript").
+
+<P>The <I>destination</I> field is a MIME type defined in the
+<VAR>mime.types</VAR> file.
+
+<P>The <I>cost</I> field defines a relative cost for the filtering
+operation from 1 to 100. The cost is used to choose between two
+different sets of filters when converting a file. For example, to convert
+from <CODE>image/jpeg</CODE> to <CODE>application/vnd.cups-raster</CODE>,
+you could use the <CODE>imagetops</CODE> and <CODE>pstoraster</CODE>
+filters for a total cost of 100, or the <CODE>imagetoraster</CODE> filter
+for a total cost of 50.
+
+<P>The <I>program</I> field defines the filter program to run; the
+special program "-" can be used to make two file types equivalent. The
+program must accept the standard filter arguments and environment
+variables described in the CUPS Interface Design Description and CUPS
+Software Programmers Manual:
+
+<UL><PRE>
+program job user title options [filename]
+</PRE></UL>
+
+<P>If specified, the <I>filename</I> argument defines a file to read
+when filtering, otherwise the filter must read from the standard input.
+All filtered output must go to the standard output.
+
+<!-- NEED 4in -->
+<H3>Adding Filetypes and Filters</H3>
+
+<P>Adding a new file type or filter is fairly straight-forward. Rather
+than adding the new type and filter to the <VAR>mime.types</VAR> and
+<VAR>mime.convs</VAR> files which are overwritten when you upgrade to a
+new version of CUPS, you simple need to create new files with
+<VAR>.types</VAR> and <VAR>.convs</VAR> extensions in the
+<VAR>/etc/cups</VAR> directory. We recommend that you use the product
+or format name, e.g.:
+
+<UL><PRE>
+myproduct.types
+myproduct.convs
+</PRE></UL>
+
+<P>If you are providing a filter for a common file format or printer,
+add the company or author name:
+
+<UL><PRE>
+acme-msword.types
+acme.msword.convs
+</PRE></UL>
+
+<P>This will help to prevent name collisions if you install many
+different file types and filters.
+
+<P>Once you choose the names for these files, create them using your
+favorite text editor as described earlier in this chapter. Once you
+have created the files, restart the <CODE>cupsd</CODE> process as
+described earlier in <A HREF="#RESTARTING">"Restarting the CUPS Server"</A>.
+
+<H3>Printer Drivers and PPD Files</H3>
+
+<P>Most CUPS printer drivers utilize one or more printer-specific filters
+and a PPD file for each printer model. Printer driver filters are registered
+via the PPD file using <CODE>cupsFilter</CODE> attributes:
+
+<UL><PRE>
+*cupsFilter: "application/vnd.cups-raster 0 rastertohp"
+</PRE></UL>
+
+<P>The filter is specified using the source file type only; the destination
+file type is assumed to be <CODE>printer/name</CODE> - suitable for sending
+to the printer.
+
+<H3>Writing Your Own Filter or Printer Driver</H3>
+
+<P>CUPS supports an unlimited number of file formats and filters, and can
+handle any printer. If you'd like to write a filter or printer driver for
+your favorite file format or printer, consult the CUPS Software Programmers
+Manual for step-by-step instructions.
+
+
+<H1 ALIGN="RIGHT"><A NAME="PRINTING_OTHER">7 - Printing with Other Systems</A></H1>
+
+<P>This chapter describes how to print from client systems that use the
+LPD, Mac OS, or Windows printing protocols.
+
+<H2>The Basics</H2>
+
+<P>CUPS is based on the IPP protocol, so any system that supports IPP
+can send jobs to and receive jobs from CUPS automatically. However, not
+all systems support IPP yet. This chapter will show you how to connect
+these systems to your CUPS server, either to accept jobs from your
+server for printing, or to send jobs to your server.
+
+<H2>Printing from LPD Clients</H2>
+
+<P>CUPS supports limited functionality for LPD-based clients. With LPD you can
+print files to specific printers, list the queue status, and so forth. However,
+the automatic client configuration and printer options are not supported by
+the LPD protocol, so you must manually configure each client for the printers
+it needs to access.
+
+<P>The <CODE>cups-lpd(8)</CODE> program provides support for LPD
+clients and can be used from either the <CODE>inetd(8)</CODE> or
+<CODE>xinetd(8)</CODE> programs. Add the following line to the
+<VAR>/etc/inetd.conf</VAR> file to enable LPD support on your
+server through the <CODE>inetd</CODE> program:
+
+<UL><PRE>
+printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd
+</PRE></UL>
+
+<P>The path to the <CODE>cups-lpd</CODE> may vary depending on your
+installation.
+
+<P>Once you have added this line, send the <CODE>inetd</CODE>
+process a <CODE>HUP</CODE> signal or reboot the system:
+
+<UL><PRE>
+<B>killall -HUP inetd ENTER</B> [IRIX and some versions of Linux]
+<B>kill -HUP <I>pid</I> ENTER [Others]</B>
+<B>reboot ENTER [For all systems if the HUP signal fails]</B>
+</PRE></UL>
+
+<P>If you are using the <CODE>xinetd</CODE> program, create a
+file named <VAR>/etc/xinetd.d/printer</VAR> containing the
+following lines:
+
+<UL><PRE>
+service printer
+{
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ user = lp
+ server = /usr/lib/cups/daemon/cups-lpd
+}
+</PRE></UL>
+
+<P>The <CODE>xinetd</CODE> program automatically reads the new
+configuration file and enables LPD printing support.
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD><B>Warning:</B>
+
+ <P><CODE>cups-lpd</CODE> currently does not perform any
+ access control based on the settings in
+ <VAR>cupsd.conf</VAR> or in the <VAR>hosts.allow</VAR>
+ or <VAR>hosts.deny</VAR> files used by TCP wrappers.
+ Therefore, running <CODE>cups-lpd</CODE> on your server
+ will allow any computer on your network (and perhaps the
+ entire Internet) to print to your server.
+
+ <P>While <CODE>xinetd</CODE> has built-in access control
+ support, you should use the TCP wrappers package with
+ <CODE>inetd</CODE> to limit access to only those
+ computers that should be able to print through your
+ server.
+
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H2>Printing to LPD Servers</H2>
+
+<P>CUPS provides the <CODE>lpd</CODE> backend for printing to LPD-based
+servers and printers. Use a device URI of <CODE>lpd://server/name</CODE>
+to print to a printer on an LPD server, where <CODE>server</CODE>
+is the hostname or IP address of the server and <CODE>name</CODE> is
+the queue name.
+
+<P>Microsoft Windows NT provides an LPD service under the name "TCP/IP
+Printing Services". To enable LPD printing on NT, open the "Services"
+control panel, select the "TCP/IP Printing Services" service, and click
+on the "Start" button. Any shared printer will then be available via
+the LPD protocol.
+
+<H2>Printing from Mac OS Clients</H2>
+
+<P>CUPS does not provide Mac OS support directly. However, there are several
+free and commercial software packages that do.
+
+<H3>Columbia Appletalk Package (CAP)</H3>
+
+<P>Because the CAP LaserWriter server (<CODE>lwsrv(8)</CODE>) does
+not support specification of PPD files, we do not recommend that you
+use CAP with CUPS. However, you can run the <CODE>lpsrv</CODE> program
+for limited printing with the command:
+
+<UL><PRE>
+lwsrv -n "<I>Name</I>" -p <I>printer</I> -a /usr/lib/adicts -f /usr/lib/LW+Fonts
+</PRE></UL>
+
+<P>where <CODE>Name</CODE> is the name you want to use when sharing the
+printer, and <CODE>printer</CODE> is the name of the CUPS print queue.
+
+<!-- NEED 3in -->
+<H3>XINET KA/Spool</H3>
+
+<P>To use your system as a print server for Mac OS clients,
+configure each printer using a <CODE>papserver(8)</CODE> in the
+<VAR>/usr/adm/appletalk/services</VAR> file, specifying the
+corresponding PPD file in the <VAR>/etc/cups/ppd</VAR> directory for
+each printer. For a printer named <CODE>MyPrinter</CODE> the entry
+would look like:
+
+<UL><PRE>
+/usr/etc/appletalk/papserver -I -L -P /etc/cups/ppd/MyPrinter.ppd \
+"Printer Description" MyPrinter
+</PRE></UL>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Enter the text above on a single line without the backslash (\)
+ character.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>NetATalk</H3>
+
+<P>To use your system as a print server for Mac OS clients,
+configure each printer in the <VAR>papd.conf</VAR> file, specifying the
+corresponding PPD file in the <VAR>/etc/cups/ppd</VAR> directory for
+each printer. For a printer named <CODE>MyPrinter</CODE> the entry
+would look like:
+
+<UL><PRE>
+Printer Description:MyPrinter@MyServer:\
+ :pr=|/usr/bin/lp -d MyPrinter:\
+ :op=daemon:\
+ :pd=/etc/cups/ppd/MyPrinter.ppd:
+</PRE></UL>
+
+<!-- NEED 2in -->
+
+<H2>Printing to Mac OS Servers</H2>
+
+<P>CUPS currently does not provide a backend to communicate with a Mac OS
+server. However, you can write and install a short shell script
+in the <VAR>/usr/lib/cups/backend</VAR> directory that sends a print file
+using the appropriate command. The following is a short script that will
+run the <CODE>papif</CODE> command provided with CAP.
+
+<P>After copying this script to <VAR>/usr/lib/cups/backend/cap</VAR>,
+specify a device URI of <CODE>cap://server/printer</CODE> to use this
+backend with a print queue.
+
+<!-- NEED 8in -->
+<UL>
+<PRE>
+<I>"/usr/lib/cups/backend/cap"</I>
+#!/bin/sh
+#
+# Usage: cap job user title copies options [filename]
+#
+
+# No arguments means show available devices...
+
+if test ${#argv} = 0; then
+ echo "network cap \"Unknown\" \"Mac OS Printer via CAP\""
+ exit 0
+fi
+
+# Collect arguments...
+
+user=$2
+copies=$4
+
+if test ${#argv} = 5; then
+ # Get print file from stdin; copies have already been handled...
+ file=/var/tmp/$$.prn
+ copies=1
+ cat &gt; $file
+else
+ # Print file is on command-line...
+ file=$6
+fi
+
+# Create a dummy cap.printers file for this printer based
+# upon a device URI of "cap://server/printer"...
+
+echo $PRINTER/$DEVICE_URI | \
+ awk -F/ '{print $1 "=" $5 ":LaserWriter@" $4}' &gt; /var/tmp/$$.cap
+
+CAPPRINTERS=/var/tmp/$$.cap; export CAPPRINTERS
+
+# Send the file to the printer, once for each copy. This assumes that you
+# have properly initialized the cap.printers file...
+
+while [ $copies -gt 0 ]; do
+ papif -n $user &lt; $file
+
+ copies=`expr $copies - 1`
+done
+
+# Remove any temporary files...
+if test ${#argv} = 5; then
+ /bin/rm -f $file
+fi
+
+/bin/rm -f /var/tmp/$$.cap
+
+exit 0
+</PRE></UL>
+
+<!-- NEED 2in -->
+<H2>Printing from Windows Clients</H2>
+
+<P>While CUPS does not provide Windows support directly, the free
+SAMBA software package does. SAMBA version 2.0.6 is the first release
+of SAMBA that supports CUPS. You can download SAMBA from:
+
+<UL><PRE>
+<A HREF="http://www.samba.org">http://www.samba.org</A>
+</PRE></UL>
+
+<P>To configure SAMBA for CUPS, edit the <VAR>smb.conf</VAR> file and
+replace the existing printing commands and options with the line:
+
+<UL><PRE>
+printing = cups
+printcap name = cups
+</PRE></UL>
+
+<P>That's all there is to it! Remote users will now be able to browse and
+print to printers on your system.
+
+<H3>Exporting Printer Drivers</H3>
+
+<P>You can optionally export printer drivers from your CUPS
+server using the <CODE>cupsaddsmb</CODE> command and the SAMBA
+2.2.0 or higher software.
+
+<P>Before you can export the printers you must download the
+current Adobe PostScript printer drivers from the Adobe web
+site (<A HREF="http://www.adobe.com/">http://www.adobe.com/</A>).
+Use the free <CODE>unzip</CODE> software to extract the files
+from the self-extracting ZIP file containing the drivers; you
+will need the following files:
+
+<UL><PRE>
+ADFONTS.MFM
+ADOBEPS4.DRV
+ADOBEPS4.HLP
+ADOBEPS5.DLL
+ADOBEPSU.DLL
+ADOBEPSU.HLP
+DEFPRTR2.PPD
+ICONLIB.DLL
+PSMON.DLL
+</PRE></UL>
+
+<P>Copy these files to the <VAR>/usr/share/cups/drivers</VAR>
+directory - you may need to rename some of the files so the
+filenames are all UPPERCASE.
+
+<P>Next, add a <CODE>print$</CODE> share for the printer
+drivers to your <VAR>smb.conf</VAR> file:
+
+<UL><PRE>
+[print$]
+ comment = Printer Drivers
+ path = /etc/samba/drivers
+ browseable = yes
+ guest ok = no
+ read only = yes
+ write list = root
+</PRE></UL>
+
+<P>The directory for your printer drivers can be anywhere on the
+system; just make sure it is writable by the users specified by
+the <CODE>write list</CODE> directive. Also, make sure that you
+have SAMBA passwords defined for each user in the <CODE>write
+list</CODE> using the <CODE>smbpasswd(1)</CODE> command.
+Otherwise you will not be able to authenticate
+
+<P>Finally, run the <CODE>cupsaddsmb</CODE> command to export
+the printer drivers for one or more queues:
+
+<UL><PRE>
+<B>cupsaddsmb -U root printer1 ... printerN <I>ENTER</I></B>
+</PRE></UL>
+
+<P>Running <CODE>cupsaddsmb</CODE> with the <CODE>-a</CODE> option
+will export all printers:
+
+<UL><PRE>
+<B>cupsaddsmb -U root -a <I>ENTER</I></B>
+</PRE></UL>
+
+<H2>Printing to Windows Servers</H2>
+
+<P>CUPS can print to Windows servers in one of two ways. The first way uses
+the LPD protocol on the CUPS system and the "TCP/IP Printing Services" on
+the Windows system. You can find out more about this configuration in the
+<A HREF="#LPD">LPD</A> section earlier in this chapter.
+
+<P>The second way is through the Microsoft Server Message Block ("SMB")
+protocol. Support for this protocol is provided with the free SAMBA
+software package. You can download SAMBA from:
+
+<UL><PRE>
+<A HREF="http://www.samba.org">http://www.samba.org</A>
+</PRE></UL>
+
+<P>To configure CUPS for SAMBA, run the following command:
+
+<UL><PRE>
+<B>ln -s `which smbspool` /usr/lib/cups/backend/smb ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>smbspool(1)</CODE> program is provided with SAMBA starting
+with SAMBA 2.0.6. Once you have made the link you can configure your
+printers with one of the following device URIs:
+
+<UL><PRE>
+smb://workgroup/server/sharename
+smb://server/sharename
+smb://user:pass@workgroup/server/sharename
+smb://user:pass@server/sharename
+</PRE></UL>
+
+<P>The <CODE>workgroup</CODE> name need only be specified if your
+system is using a different workgroup. The <CODE>user:pass</CODE>
+strings are required when printing to Windows NT servers or to shares
+with passwords enabled under Windows 95 and 98.
+
+
+<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - Software License Agreement</A></H1>
+
+<EMBED SRC="../LICENSE.html">
+
+
+<H1 ALIGN="RIGHT"><A NAME="COMMON_NETWORK">B - Common Network Settings</A></H1>
+
+<P>This appendix covers many of the popular TCP/IP network interfaces
+and printer servers available on the market today.
+
+<H2>Configuring a Network Interface</H2>
+
+<P>When you first install a network printer or print server on your
+LAN, you need to set the Internet Protocol ("IP") address. On most
+higher-end "workgroup" printers, you can set the address through the
+printer control panel. However, in most cases you will want to assign
+the addresses remotely from your workstation. This makes administration
+a bit easier and avoids assigning duplicate addresses accidentally.
+
+<P>To setup your printer or print server for remote address assignment,
+you'll need the Ethernet Media Access Control ("MAC") address, also
+sometimes called a node address, and the IP address you want to use for
+the device. The Ethernet MAC address can often be found on the printer
+test page or bottom of the print server.
+
+<!-- NEED 3in -->
+<H3>Configuring the IP Address Using ARP</H3>
+
+<P>The easiest way to set the IP address of a network device is to use
+the <CODE>arp(8)</CODE> command. The <CODE>arp</CODE> sends an Address
+Resolution Protocol ("ARP") packet to the specified Ethernet MAC address,
+setting the network device's IP address:
+
+<UL><PRE>
+<B>arp -s ip-address ethernet-address ENTER</B>
+<B>arp -s host.domain.com 08:00:69:00:12:34 ENTER</B>
+<B>arp -s 192.0.2.2 08:00:69:00:12:34 ENTER</B>
+</PRE></UL>
+
+<H3>Configuring the IP Address Using RARP</H3>
+
+<P>The most flexible way to remotely assign IP addresses under UNIX
+is through the Reverse Address Resolution Protocol ("RARP"). RARP
+allows a network device to request an IP address using its Ethernet
+MAC address, and one or more RARP servers on the network will
+respond with an ARP packet with the IP address the device can use.
+
+<P>RARP should be used when you have to manage many printers or print
+servers, or when you have a network device that does not remember its
+IP address after a power cycle. If you just have a single printer or
+print server, the <CODE>arp</CODE> command is the way to go.
+
+<P>Some UNIX operating systems use a program called
+<CODE>rarpd(8)</CODE> to manage RARP. Others, like Linux, support this
+protocol in the kernel. For systems that provide the <CODE>rarpd</CODE>
+program you will need to start it before RARP lookups will work:
+
+<UL><PRE>
+<B>rarpd ENTER</B>
+</PRE></UL>
+
+<P>Under IRIX you can enable this functionality by default using:
+
+<UL><PRE>
+<B>chkconfig rarpd on ENTER</B>
+</PRE></UL>
+
+<P>Both the <CODE>rarpd</CODE> program and kernel RARP support read a
+list of Ethernet and IP addresses from the file <VAR>/etc/ethers</VAR>.
+Each line contains the Ethernet address (colon delimited) followed by
+an IP address or hostname like:
+
+<UL><PRE>
+08:00:69:00:12:34 myprinter.mydomain.com
+08:00:69:00:12:34 192.0.2.2
+</PRE></UL>
+
+<P>Add a line to this file and cycle the power on the printer or print
+server to set its address.
+
+<!-- NEED 2in -->
+<H3>Configuring the IP Address Using BOOTP</H3>
+
+<P>The BOOTP protocol is used when you need to provide additional information
+such as the location of a configuration file to the network interface. Using
+the standard <CODE>bootpd(8)</CODE> program supplied with UNIX you simply need to
+add a line to the <VAR>/etc/bootptab</VAR> file; for IRIX:
+
+<UL><PRE>
+myprinter 08:00:69:00:12:34 192.0.2.2 <VAR>myprinter.boot</VAR>
+</PRE></UL>
+
+<!-- NEED 1in -->
+<P>Newer versions of <CODE>bootpd</CODE> use a different format:
+
+<UL><PRE>
+myprinter:ha=080069001234:ip=192.0.2.2:<VAR>t144=myprinter.boot</VAR>
+</PRE></UL>
+
+<P>The <VAR>myprinter.boot</VAR> file resides in the <VAR>/usr/local/boot</VAR>
+directory by default. If you do not need to provide a boot file you may leave
+the last part of the line blank.</P>
+
+<!-- NEED 2in -->
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Some versions of UNIX do not enable the BOOTP service by
+ default. The <VAR>/etc/inetd.conf</VAR> usually contains a
+ line for the BOOTP service that can be uncommented if
+ needed.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H2>Verifying the Printer Connection</H2>
+
+<P>To test that the IP address has been successfully assigned and that the
+printer is properly connected to your LAN, type:
+
+<UL><PRE>
+<B>ping ip-address ENTER</B>
+</PRE></UL>
+
+<P>If the connection is working properly you will see something like:
+
+<UL><PRE>
+<B>ping myprinter ENTER</B>
+PING myprinter (192.0.2.2): 56 data bytes
+64 bytes from 192.0.2.2: icmp_seq=0 ttl=15 time=5 ms
+64 bytes from 192.0.2.2: icmp_seq=1 ttl=15 time=3 ms
+64 bytes from 192.0.2.2: icmp_seq=2 ttl=15 time=3 ms
+64 bytes from 192.0.2.2: icmp_seq=3 ttl=15 time=3 ms
+</PRE></UL>
+
+<P>If not, verify that the printer or print server is connected to the
+LAN, it is powered on, the LAN cabling is good, and the IP address is
+set correctly. You can usually see the current IP address and network
+status by printing a configuration or test page on the device.
+
+<!-- NEED 4in -->
+<H2>Common Network Interface Settings</H2>
+
+<P>Once you have set the IP address you can access the printer or print
+server using the <CODE>ipp</CODE>, <CODE>lpd</CODE>, or
+<CODE>socket</CODE> backends. The following is a list of common network
+interfaces and printer servers and the settings you should use with
+CUPS:
+
+<CENTER><TABLE BORDER="1">
+<TR VALIGN="TOP" ALIGN="LEFT">
+ <TH>Model/Manufacturer</TH>
+ <TH>Device URI(s)</TH>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Apple LaserWriter</TD>
+ <TD>lpd://<I>address</I>/PASSTHRU</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Axis w/o IPP<BR>
+ <A HREF="#AXIS">(see directions)</A></TD>
+ <TD>socket://<I>address</I>:9100<BR>
+ socket://<I>address</I>:9101<BR>
+ socket://<I>address</I>:9102</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Axis w/IPP</TD>
+ <TD>ipp://<I>address</I>/LPT1<BR>
+ ipp://<I>address</I>/LPT2<BR>
+ ipp://<I>address</I>/COM1</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Castelle LANpress<SUP>TM</SUP></TD>
+ <TD>lpd://<I>address</I>/pr1<BR>
+ lpd://<I>address</I>/pr2<BR>
+ lpd://<I>address</I>/pr3</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>DPI NETPrint</TD>
+ <TD>lpd://<I>address</I>/pr1<BR>
+ lpd://<I>address</I>/pr2<BR>
+ lpd://<I>address</I>/pr3</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>EFI&reg; Fiery&reg; RIP</TD>
+ <TD>lpd://<I>address</I>/print</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>EPSON&reg; Multiprotocol Ethernet Interface Board</TD>
+ <TD>socket://<I>address</I></TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Extended System ExtendNET</TD>
+ <TD>lpd://<I>address</I>/pr1<BR>
+ lpd://<I>address</I>/pr2<BR>
+ lpd://<I>address</I>/pr3</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Hewlett Packard JetDirect w/o IPP</TD>
+ <TD>socket://<I>address</I>:9100<BR>
+ socket://<I>address</I>:9101<BR>
+ socket://<I>address</I>:9102</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Hewlett Packard JetDirect w/IPP</TD>
+ <TD>ipp://<I>address</I>/ipp<BR>
+ ipp://<I>address</I>/ipp/port1<BR>
+ ipp://<I>address</I>/ipp/port2<BR>
+ ipp://<I>address</I>/ipp/port3</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Intel® NetportExpress XL, PRO/100</TD>
+ <TD>lpd://<I>address</I>/LPT1_PASSTHRU<BR>
+ lpd://<I>address</I>/LPT2_PASSTHRU<BR>
+ lpd://<I>address</I>/COM1_PASSTHRU</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Lexmark<SUP>TM</SUP> MarkNet</TD>
+ <TD>lpd://<I>address</I>/ps</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Linksys EtherFast&reg;<BR>
+ <A HREF="#LINKSYS">(see directions)</A></TD>
+ <TD>socket://<I>address</I>:4010<BR>
+ socket://<I>address</I>:4020<BR>
+ socket://<I>address</I>:4030</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Kodak&reg;</TD>
+ <TD>lpd://<I>address</I>/ps</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>QMS&reg; CrownNet<SUP>TM</SUP></TD>
+ <TD>lpd://<I>address</I>/ps</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Tektronix&reg; PhaserShare<SUP>TM</SUP></TD>
+ <TD>socket://<I>address</I>:9100</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>XEROX&reg; 4512 NIC</TD>
+ <TD>lpd://<I>address</I>/PORT1</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>XEROX&reg; XNIC</TD>
+ <TD>lpd://<I>address</I>/PASSTHRU</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>XEROX&reg; (most others)</TD>
+ <TD>socket://<I>address</I>:5503</TD>
+</TR>
+</TABLE></CENTER>
+
+<H2><A NAME="AXIS">Configuring Axis Print Servers</A></H2>
+
+<P>The Axis print servers can be configured using ARP, RARP, or BOOTP.
+However, on models that do not provide IPP support an additional step
+must be performed to configure the TCP/IP portion of the print server
+for use with CUPS.
+
+<!-- NEED 3in -->
+<P>Each print server contains a configuration file named
+<VAR>config</VAR> that contains a list of network parameters used by
+the server. To modify this file you must first download it from the
+print server using the <CODE>ftp(1)</CODE> program:
+
+<UL><PRE>
+<B>ftp ip-address ENTER</B>
+Connected to ip-address.
+220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
+ftp> <B>user root ENTER</B>
+331 User name ok, need password
+Password: <B>pass ENTER</B> <I>(this is not echoed)</I>
+230 User logged in
+ftp> <B>get config ENTER</B>
+local: config remote: config
+200 PORT command successful.
+150 Opening data connection for config (192,0,2,2),
+(mode ascii).
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp> <B>quit ENTER</B>
+221 Goodbye.
+</PRE></UL>
+
+<!-- NEED 2in -->
+<P>Next, edit the file with your favorite text editor and locate the
+lines beginning with:
+
+<UL><PRE>
+RTN_OPT. : YES
+RTEL_PR1. : 0
+RTEL_PR2. : 0
+RTEL_PR3. : 0
+RTEL_PR4. : 0
+RTEL_PR5. : 0
+RTEL_PR6. : 0
+RTEL_PR7. : 0
+RTEL_PR8. : 0
+</PRE></UL>
+
+<!-- NEED 1in -->
+Change the <CODE>RTN_OPT</CODE> line to read:
+
+<UL><PRE>
+RTN_OPT. : <B>NO</B>
+</PRE></UL>
+
+<!-- NEED 2in -->
+<P>This disables the Reverse TELNET protocol and enables the standard
+TELNET protocol on the print server. Next, assign a port number for
+each parallel and serial port on the server as follows:
+
+<UL><PRE>
+RTEL_PR1. : <B>9100</B>
+RTEL_PR2. : <B>9101</B>
+RTEL_PR3. : <B>9102</B>
+RTEL_PR4. : <B>9103</B>
+RTEL_PR5. : <B>9104</B>
+RTEL_PR6. : <B>9105</B>
+RTEL_PR7. : <B>9106</B>
+RTEL_PR8. : <B>9107</B>
+</PRE></UL>
+
+<!-- NEED 4in -->
+<P>This essentially makes the Axis print server look like a Hewlett
+Packard JetDirect EX print server. Save the file and then upload the
+new <VAR>config</VAR> file using the <CODE>ftp</CODE> command:
+
+<UL><PRE>
+<B>ftp ip-address ENTER</B>
+Connected to ip-address.
+220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
+ftp> <B>user root ENTER</B>
+331 User name ok, need password
+Password: <B>pass ENTER</B> <I>(this is not echoed)</I>
+230 User logged in
+ftp> <B>put config CONFIG ENTER</B>
+local: config remote: CONFIG
+200 PORT command successful.
+150 Opening data connection for config (192,0,2,2), (mode ascii).
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp> <B>get hardreset ENTER</B>
+local: hardreset remote: hardreset
+200 PORT command successful.
+421 Axis NPS ### hard reset, closing connection.
+ftp> <B>quit ENTER</B>
+221 Goodbye.
+</PRE></UL>
+
+<P>Your Axis print server is now ready for use!
+
+<H2><A NAME="LINKSYS">Configuring Linksys Print Servers</A></H2>
+
+<P>The Linksys print servers can be configured using ARP, RARP, or
+BOOTP. Like older Axis print servers, an additional step must be
+performed to configure the TCP/IP portion of the print server for use
+with CUPS.
+
+<!-- NEED 3in -->
+<P>Each print server contains a configuration file named
+<VAR>CONFIG</VAR> that contains a list of network parameters used by
+the server. To modify this file you must first download it from the
+print server using the <CODE>ftp(1)</CODE> program:
+
+<UL><PRE>
+<B>ftp -n ip-address ENTER</B>
+Connected to ip-address.
+220 Print Server Ready.
+Remote system type is Print.
+ftp> <B>get CONFIG ENTER</B>
+local: CONFIG remote: CONFIG
+200 Command OK.
+150 Open ASCII Mode Connection.
+WARNING! 68 bare linefeeds received in ASCII mode
+File may not have transferred correctly.
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp> <B>quit ENTER</B>
+221 Goodbye.
+</PRE></UL>
+
+<!-- NEED 2in -->
+<P>Next, edit the file with your favorite text editor and locate the
+lines beginning with:
+
+<UL><PRE>
+0100 L1_PROUT:P1
+0120 L2_PROUT:P1
+0140 L3_PROUT:P1
+</PRE></UL>
+
+<P>Change the port number for
+each parallel and serial port on the server as follows:
+
+<UL><PRE>
+0100 L1_PROUT:<B>P1</B>
+0120 L2_PROUT:<B>P2</B>
+0140 L3_PROUT:<B>P3</B>
+</PRE></UL>
+
+<!-- NEED 4in -->
+<P>This maps each virtual printer with a physical port. Save the file and then upload the
+new <VAR>CONFIG</VAR> file using the <CODE>ftp</CODE> command:
+
+<UL><PRE>
+<B>ftp -n ip-address ENTER</B>
+Connected to ip-address.
+220 Print Server Ready.
+Remote system type is Print.
+ftp> <B>put CONFIG ENTER</B>
+local: CONFIG remote: CONFIG
+200 Command OK.
+150 Open ASCII Mode Connection.
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp> <B>quit ENTER</B>
+221 Goodbye.
+</PRE></UL>
+
+<P>Your Linksys print server is now ready for use!
+
+
+<H1 ALIGN="RIGHT"><A NAME="PRINTER_DRIVERS">C - Printer Drivers</A></H1>
+
+<P>This appendix lists the printer drivers that are provided with CUPS.
+
+<H2>Printer Drivers</H2>
+
+<P>CUPS includes the following printer drivers:
+
+<UL>
+
+ <LI><A HREF="#EPSON9">EPSON 9-pin Dot Matrix</A>, <VAR>epson9.ppd</VAR>
+
+ <LI><A HREF="#EPSON24">EPSON 24-pin Dot Matrix</A>, <VAR>epson24.ppd</VAR>
+
+ <LI><A HREF="#STCOLOR">EPSON Stylus Color</A>, <VAR>stcolor.ppd</VAR>
+
+ <LI><A HREF="#STPHOTO">EPSON Stylus Photo</A>, <VAR>stphoto.ppd</VAR>
+
+ <LI><A HREF="#DESKJET">HP DeskJet</A>, <VAR>deskjet.ppd</VAR>
+
+ <LI><A HREF="#LASERJET">HP LaserJet</A>, <VAR>laserjet.ppd</VAR>
+
+</UL>
+
+<H2><A NAME="EPSON9">EPSON 9-pin Dot Matrix</A></H2>
+
+<P>The EPSON 9-pin Dot Matrix driver (<VAR>epson9.ppd</VAR>) supports
+9-pin dot matrix printers that implement the ESC/P command set. It
+provides 60x72, 120x72, and 240x72 DPI output in black only.
+
+<H2><A NAME="EPSON24">EPSON 24-pin Dot Matrix</A></H2>
+
+<P>The EPSON 24-pin Dot Matrix driver (<VAR>epson9.ppd</VAR>) supports
+24-pin dot matrix printers that implement the ESC/P command set. It
+provides 120x180, 180x180, 360x180, and 360x360 DPI output in black
+only.
+
+<H2><A NAME="STCOLOR">EPSON Stylus Color</A></H2>
+
+<P>The EPSON Stylus Color driver (<VAR>stcolor.ppd</VAR>) supports
+EPSON Stylus Color printers that implement the ESC/P2 command set. It
+provides 180, 360, and 720 DPI output in black and color (CMYK).
+
+<H2><A NAME="STPHOTO">EPSON Stylus Photo</A></H2>
+
+<P>The EPSON Stylus Photo driver (<VAR>stphoto.ppd</VAR>) supports
+EPSON Stylus Photo printers that implement the ESC/P2 command set. It
+provides 180, 360, and 720 DPI output in black and color (CMYKcm).
+
+<H2><A NAME="DESKJET">HP DeskJet</A></H2>
+
+<P>The HP DeskJet driver (<VAR>deskjet.ppd</VAR>) supports HP DeskJet
+printers that implement the PCL command set. It provides 150, 300, and
+600 DPI output in black and color (CMYK).
+
+<P>The DeskJet printers that implement the HP-PPA command set (720C,
+722C, 820C, and 1100C) are <B>not</B> supported due to a complete lack
+of documentation and support from Hewlett Packard.
+
+<P>The duplexer provided with the HP DeskJet 900 series printers is also
+not supported for similar reasons.
+
+<H2><A NAME="LASERJET">HP LaserJet</A></H2>
+
+<P>The HP LaserJet driver (<VAR>laserjet.ppd</VAR>) supports HP
+LaserJet printers that implement the PCL command set. It provides 150,
+300, and 600 DPI output in black only and supports the duplexer if
+installed.
+
+<P>LaserJet printers that do not implement PCL (3100, 3150) are not
+supported due to a complete lack of documentation and support from
+Hewlett Packard.
+
+
+<H1 ALIGN="RIGHT"><A NAME="FILES">D - List of Files</A></H1>
+
+<P>This appendix lists the files and directories that are installed for
+the Common UNIX Printing System.
+
+<CENTER><TABLE BORDER="1" WIDTH="80%">
+<TR VALIGN="TOP">
+ <TH>Pathname</TH>
+ <TH>Description</TH>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/certs/</TD>
+ <TD>The location of authentication certificate files for local
+ HTTP clients.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/classes.conf</TD>
+ <TD>The printer classes configuration file for the scheduler.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/cupsd.conf</TD>
+ <TD>The scheduler configuration file.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/interfaces/</TD>
+ <TD>The location of System V interface scripts for printers.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/mime.convs</TD>
+ <TD>The list of standard file filters included with CUPS.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/mime.types</TD>
+ <TD>The list of recognized file types for CUPS.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/ppd/</TD>
+ <TD>The location of PostScript Printer Description ("PPD") files for
+ printers.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/printers.conf</TD>
+ <TD>The printer configuration file for the scheduler.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/cancel</TD>
+ <TD>The System V cancel job(s) command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/disable</TD>
+ <TD>The System V disable printer command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/enable</TD>
+ <TD>The System V enable printer command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lp</TD>
+ <TD>The System V print command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lpoptions</TD>
+ <TD>Sets user-defined printing options and defaults.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lppasswd</TD>
+ <TD>Adds, changes, or removes Digest password accounts.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lpq</TD>
+ <TD>The Berkeley status command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lpr</TD>
+ <TD>The Berkeley print command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lprm</TD>
+ <TD>The Berkeley cancel job(s) command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lpstat</TD>
+ <TD>The System V status command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/include/cups/</TD>
+ <TD>CUPS API header files.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib32/libcups.a<BR>
+ /usr/lib32/libcupsimage.a</TD>
+ <TD>Static libraries (IRIX 6.5)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/libcups.a<BR>
+ /usr/lib/libcupsimage.a</TD>
+ <TD>Static libraries (all others)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/libcups.sl.2<BR>
+ /usr/lib/libcupsimage.sl.2</TD>
+ <TD>Shared libraries (HP-UX)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib32/libcups.so.2<BR>
+ /usr/lib32/libcupsimage.so.2</TD>
+ <TD>Shared libraries (IRIX 6.5)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/libcups.so.2<BR>
+ /usr/lib/libcupsimage.so.2</TD>
+ <TD>Shared libraries (all others)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/cups/backend/</TD>
+ <TD>Backends for various types of printer connections.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/cups/cgi-bin/</TD>
+ <TD>CGI programs for the scheduler.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/cups/daemon/</TD>
+ <TD>Daemons for polling and LPD support.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/cups/filter/</TD>
+ <TD>Filters for various types of files.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/locale/</TD>
+ <TD>The location of language-specific message files. (System V)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/nls/msg/</TD>
+ <TD>The location of language-specific message files. (Compaq Tru64 UNIX)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/locale/</TD>
+ <TD>The location of language-specific message files. (Linux, *BSD)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/accept</TD>
+ <TD>The accept-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/cupsd</TD>
+ <TD>The CUPS print scheduler.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/lpadmin</TD>
+ <TD>The System V printer administration tool.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/lpc</TD>
+ <TD>The Berkeley printer administration tool.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/lpinfo</TD>
+ <TD>The get-devices and get-ppds command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/lpmove</TD>
+ <TD>The move-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/reject</TD>
+ <TD>The reject-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/catman/a_man/<BR>
+ /usr/share/catman/u_man/</TD>
+ <TD>Man pages (IRIX)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/man/</TD>
+ <TD>Man pages (Compaq Tru64 UNIX, HP-UX, Solaris)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/man/</TD>
+ <TD>Man pages (all others)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/data/</TD>
+ <TD>The location of filter data files.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/data/testprint.ps</TD>
+ <TD>The PostScript test page file.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/fonts/</TD>
+ <TD>The location of PostScript fonts for the PostScript RIP.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/model/</TD>
+ <TD>The location of PostScript Printer Description ("PPD") files and
+ interface scripts that may be used to setup a printer queue.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/pstoraster/</TD>
+ <TD>Other PostScript RIP initialization files.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/pstoraster/Fontmap</TD>
+ <TD>The font mapping file (converts filenames to fontnames)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/templates/</TD>
+ <TD>The location of HTML template files for the web interfaces.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/doc/cups/</TD>
+ <TD>Documentation and web page data for the scheduler.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/var/log/cups/</TD>
+ <TD>The location of scheduler log files.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/var/spool/cups/</TD>
+ <TD>The location of print files waiting to be printed.</TD>
+</TR>
+</TABLE></CENTER>
+
+
+<H1 ALIGN="RIGHT"><A NAME="FAQ">E - Troubleshooting Common Problems</A></H1>
+
+<P>This appendix covers some of the common problems first-time users
+encounter when installing and configuring CUPS.
+
+<P>Commercial support for CUPS is available from Easy Software Products.
+For more information please contact us at:
+
+<UL>
+
+ <LI>WWW: <A HREF="http://www.easysw.com">
+ <CODE>http://www.easysw.com</CODE></A>
+
+ <LI>EMail: <A HREF="mailto:info@easysw.com">info@easysw.com</A>
+
+ <LI>Telephone (M-F, 9-5 EST): +1.301.373.9600
+
+</UL>
+
+<H2>My Applications Don't See the Available Printers</H1>
+
+<P>Many applications read the <VAR>/etc/printcap</VAR> file to
+get a list of available printers.
+
+<P>The default CUPS configuration does not create the
+<VAR>/etc/printcap</VAR> file automatically. To enable automatic
+creation and updating of this file, use the
+<A HREF="#Printcap"><CODE>Printcap</CODE></A> directive described in
+<A HREF="#PRINTING_MANAGEMENT">Chapter 6, "Printing System Management"</A>.
+
+<H2>CUPS Doesn't Recognize My Username or Password!</H2>
+
+<P>CUPS will ask you for a UNIX username and password when you perform
+printer administration tasks remotely or via a web browser. The default
+configuration requires that you use the <CODE>root</CODE> username and
+the corresponding password to authenticate the request.
+
+<P>CUPS does not allow you to authenticate an administration request
+with an account that has no password for security reasons. If you do
+not have a password on your <CODE>root</CODE> account then you won't be
+able to add printers remotely or via the web interface!
+
+<!-- NEED 2in -->
+<P>To disable password authentication you need to edit the
+<VAR>/etc/cups/cupsd.conf</VAR> file and comment out the
+lines reading:
+
+<UL><PRE>
+AuthType Basic
+AuthClass System
+</UL></PRE>
+
+for the <VAR>/admin</VAR> location. Then restart the CUPS server as
+described in <A HREF="#PRINTING_MANAGEMENT">Chapter 6, "Printing System
+Management"</A>.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Disabling password checks will allow any local user to
+ change your printer and class configuration, but remote
+ administration from another machine will still not be allowed.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H2><A NAME="ALLOW_REMOTE">I Can't Do Administration Tasks from Another Machine!</A></H2>
+
+<P>The default CUPS configuration limits administration to the local
+machine. To open up access, edit the <VAR>/etc/cups/cupsd.conf</VAR>
+and comment out the lines reading:
+
+<UL><PRE>
+Order deny,allow
+Deny from all
+Allow from 127.0.0.1
+</PRE></UL>
+
+for the <VAR>/admin</VAR> location. Then restart the CUPS server as
+described in <A HREF="#PRINTING_MANAGEMENT">Chapter 6, "Printing System
+Management"</A>.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Allowing administration access from all hosts is a potential
+ security risk. Please read <A HREF="#PRINTING_SECURITY">Chapter
+ 6, "Printing System Management"</A> for a description of these
+ risks and ways to minimize them.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 4in -->
+<H2>I Can't Do Administration Tasks from My Web Browser!</H2>
+
+<P>This problem is usually caused by:
+
+<OL>
+
+ <LI>not specifying the correct password for the
+ root account.
+
+ <LI>accessing the CUPS server using the hostname or IP
+ address of the server without enabling remote access for
+ administration functions. This can be corrected by following
+ the instructions in the <A HREF="#ALLOW_REMOTE">"I Can't Do
+ Administration Tasks from Another Machine!"</A> section earlier
+ in this appendix.
+
+ <LI>not setting a password on the root account. CUPS will not
+ authenticate a user account that does not have a password for
+ security reasons.
+
+ <LI>authenticating using an account other than root, but the
+ account you are using is not a member of the system group.
+
+ <LI>configuring CUPS to use Digest authentication, but
+ your web browser does not support Digest authentication.
+
+</OL>
+
+<H2>Connection Refused Messages</H2>
+
+<P>Under normal circumstances, "connection refused" messages for a
+networked printer should be expected from time to time. Most network
+interfaces only allow a single connection to be made at any given time
+(one job at a time) and will refuse access to all other systems while
+the first connection is active. CUPS automatically retries the
+connection once every 30 seconds.
+
+<P>If the problem persists and you are unable to print any jobs to the printer,
+verify that another machine is not maintaining a connection with the printer,
+and that you have selected the proper port or printer name for the printer.
+
+<P>Also, most external print servers will refuse connections if the connected
+printer is turned off or is off-line. Verify that the affected printer is
+turned on and is online.
+
+<H2>Write Error Messages</H2>
+
+<P>If you get "write error" messages on a printer queue the printer
+interface (usually a Hewlett Packard JetDirect interface) has timed out
+and reset the network connection from your workstation.
+
+<P>The error is caused by that startup delay between the initial setup
+of the printer or plotter and the first page of print data that is
+sent.
+
+<!-- NEED 3in -->
+<P>To correct the problem, change the idle timeout on the interface to at least
+180 seconds or 3 minutes. To change the timeout on a Hewlett Packard
+JetDirect interface, type:
+
+<UL><PRE>
+<B>telnet ip-address ENTER</B>
+
+Trying ip-address...
+Connected to ip-address.
+Escape character is `^]'.
+
+Please type [Return] two times, to initialize telnet configuration
+For HELP type "?"
+> <B>idle-timeout: 180 ENTER</B>
+> <B>quit ENTER</B>
+</PRE></UL>
+
+</BODY>
+</HTML>
diff --git a/doc/fr/sum.html b/doc/fr/sum.html
new file mode 100644
index 000000000..e237bd6ca
--- /dev/null
+++ b/doc/fr/sum.html
@@ -0,0 +1,1731 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Software Users Manual</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-SUM-1.1.15">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY BGCOLOR="#ffffff">
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Software Users Manual</H1></A><BR>
+CUPS-SUM-1.1.15<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">Preface</A></B>
+<UL>
+<LI><A HREF="#1_1">System Overview</A></LI>
+<LI><A HREF="#1_2">Document Overview</A></LI>
+<LI><A HREF="#1_3">Notation Conventions</A></LI>
+<LI><A HREF="#1_4">Abbreviations</A></LI>
+<LI><A HREF="#1_5">Other References</A></LI>
+</UL>
+<B><A HREF="#OVERVIEW">1 - Printing System Overview</A></B>
+<UL>
+<LI><A HREF="#2_1">The Printing Problem</A></LI>
+<LI><A HREF="#2_2">The Technology</A></LI>
+<LI><A HREF="#2_3">Jobs</A></LI>
+<LI><A HREF="#2_4">Classes</A></LI>
+<LI><A HREF="#2_5">Filters</A></LI>
+<LI><A HREF="#2_6">Backends</A></LI>
+<LI><A HREF="#2_7">Printer Drivers</A></LI>
+<LI><A HREF="#2_8">Networking</A></LI>
+</UL>
+<B><A HREF="#USING_SYSTEM">2 - Using the Printing System</A></B>
+<UL>
+<LI><A HREF="#3_1">Submitting Files for Printing</A></LI>
+<LI><A HREF="#3_2">Choosing a Printer</A></LI>
+<LI><A HREF="#3_3">Setting Printer Options</A></LI>
+<LI><A HREF="#3_4">Printing Multiple Copies</A></LI>
+<LI><A HREF="#3_5">Checking the Printer Status from the Command-Line</A></LI>
+<LI><A HREF="#3_6">Checking the Printer Status from the Web</A></LI>
+<LI><A HREF="#3_7">Canceling a Print Job</A></LI>
+</UL>
+<B><A HREF="#STANDARD_OPTIONS">3 - Standard Printer Options</A></B>
+<UL>
+<LI><A HREF="#4_1">General Options</A></LI>
+<UL>
+<LI><A HREF="#4_1_1">Selecting the Media Size, Type, and Source</A></LI>
+<LI><A HREF="#4_1_2">Setting the Orientation</A></LI>
+<LI><A HREF="#4_1_3">Printing On Both Sides of the Paper</A></LI>
+</UL>
+<LI><A HREF="#4_2">Banner Options</A></LI>
+<UL>
+<LI><A HREF="#4_2_1">Selecting the Banner Page(s)</A></LI>
+</UL>
+<LI><A HREF="#4_3">Document Options</A></LI>
+<UL>
+<LI><A HREF="#4_3_1">Selecting a Range of Pages</A></LI>
+<LI><A HREF="#4_3_2">Selecting Even or Odd Pages</A></LI>
+<LI><A HREF="#4_3_3">N-Up Printing</A></LI>
+<LI><A HREF="#4_3_4">Setting the Brightness</A></LI>
+<LI><A HREF="#4_3_5">Setting the Gamma Correction</A></LI>
+</UL>
+<LI><A HREF="#4_4">Text Options</A></LI>
+<UL>
+<LI><A HREF="#4_4_1">Setting the Number of Characters Per Inch</A></LI>
+<LI><A HREF="#4_4_2">Setting the Number of Lines Per Inch</A></LI>
+<LI><A HREF="#4_4_3">Setting the Number of Columns</A></LI>
+<LI><A HREF="#4_4_4">Setting the Page Margins</A></LI>
+<LI><A HREF="#4_4_5">Pretty Printing</A></LI>
+</UL>
+<LI><A HREF="#4_5">Image Options</A></LI>
+<UL>
+<LI><A HREF="#4_5_1">Positioning the Image</A></LI>
+<LI><A HREF="#4_5_2">Scaling the Image</A></LI>
+<LI><A HREF="#4_5_3">Adjusting the Hue (Tint) of an Image</A></LI>
+<LI><A HREF="#4_5_4">Adjusting the Saturation (Color) of an Image</A></LI>
+</UL>
+<LI><A HREF="#4_6">HP-GL/2 Options</A></LI>
+<UL>
+<LI><A HREF="#4_6_1">Printing in Black</A></LI>
+<LI><A HREF="#4_6_2">Fitting the Plot on the Page</A></LI>
+<LI><A HREF="#4_6_3">Setting the Default Pen Width</A></LI>
+</UL>
+<LI><A HREF="#4_7">Raw or Unfiltered Output</A></LI>
+</UL>
+<B><A HREF="#SAVING_OPTIONS">4 - Saving Printer Options and Defaults</A></B>
+<UL>
+<LI><A HREF="#5_1">Printer Options</A></LI>
+<LI><A HREF="#5_2">Setting Options for a Specific Printer</A></LI>
+<LI><A HREF="#5_3">Removing Options</A></LI>
+<LI><A HREF="#5_4">Viewing the Current Defaults</A></LI>
+<LI><A HREF="#5_5">Viewing Options for a Specific Printer</A></LI>
+<LI><A HREF="#5_6">Setting the Default Printer</A></LI>
+<LI><A HREF="#5_7">Printer Instances</A></LI>
+<LI><A HREF="#5_8">Removing Instances</A></LI>
+</UL>
+<B><A HREF="#LICENSE">A - Software License Agreement</A></B>
+<UL>
+<LI><A HREF="#6_1">Common UNIX Printing System License Agreement</A></LI>
+<UL>
+<LI><A HREF="#6_1_1">Introduction</A></LI>
+<LI><A HREF="#6_1_2">License Exceptions</A></LI>
+<LI><A HREF="#6_1_3">Trademarks</A></LI>
+<LI><A HREF="#6_1_4">Binary Distribution Rights</A></LI>
+<LI><A HREF="#6_1_5">Support</A></LI>
+</UL>
+<LI><A HREF="#6_2">GNU GENERAL PUBLIC LICENSE</A></LI>
+<LI><A HREF="#6_3">GNU LIBRARY GENERAL PUBLIC LICENSE</A></LI>
+</UL>
+<HR>
+<H1 ALIGN="RIGHT"><A NAME="1">Preface</A></H1>
+<P>This software users manual describes how to use the Common UNIX
+ Printing System<SUP>TM</SUP> (&quot;CUPS<SUP>TM</SUP>&quot;) Version 1.1.15.</P>
+<H2><A NAME="1_1">System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+
+<!-- NEED 2in -->
+<H2><A NAME="1_2">Document Overview</A></H2>
+<P>This software users manual is organized into the following sections:</P>
+<UL>
+<LI><A HREF="#OVERVIEW">1 - Printing System Overview</A></LI>
+<LI><A HREF="#USING_SYSTEM">2 - Using the Printing System</A></LI>
+<LI><A HREF="#STANDARD_OPTIONS">3 - Standard Printer Options</A></LI>
+<LI><A HREF="#SAVING_OPTIONS">4 - Saving Printer Options and Defaults</A>
+</LI>
+<LI><A HREF="#LICENSE">A - Software License Agreement</A></LI>
+</UL>
+<H2><A NAME="1_3">Notation Conventions</A></H2>
+<P>Various font and syntax conventions are used in this guide. Examples
+ and their meanings and uses are explained below:
+<CENTER>
+<TABLE WIDTH="80%">
+<TR><TH>Example</TH><TD>&nbsp;&nbsp;&nbsp;</TD><TH>Description</TH></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD><CODE>lpstat</CODE>
+<BR> <CODE>lpstat(1)</CODE></TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>The names of commands;
+ the first mention of a command or function in a chapter is followed by
+ a manual page section number.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD><VAR>/var</VAR>
+<BR><VAR> /usr/share/cups/data/testprint.ps</VAR></TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>
+File and directory names.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD NOWRAP><TT>Request ID is Printer-123</TT></TD><TD>
+&nbsp;&nbsp;&nbsp;</TD><TD>Screen output.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD NOWRAP><KBD>lp -d printer filename ENTER</KBD></TD><TD>
+&nbsp;&nbsp;&nbsp;</TD><TD>Literal user input; special keys like <KBD>ENTER</KBD> are
+ in ALL CAPS.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD>12.3</TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>Numbers in the text are
+ written using the period (.) to indicate the decimal point.</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+</P>
+<H2><A NAME="1_4">Abbreviations</A></H2>
+ The following abbreviations are used throughout this manual:
+<UL>
+<DL>
+<DT>kb</DT>
+<DD>Kilobytes, or 1024 bytes
+<BR>&nbsp;</DD>
+<DT>Mb</DT>
+<DD>Megabytes, or 1048576 bytes
+<BR>&nbsp;</DD>
+<DT>Gb</DT>
+<DD>Gigabytes, or 1073741824 bytes
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H2><A NAME="1_5">Other References</A></H2>
+<UL>
+<DL>
+<DT>CUPS Software Administrators Manual</DT>
+<DD>An administration guide for the CUPS software.
+<BR>&nbsp;</DD>
+<DT>CUPS Software Programmers Manual</DT>
+<DD>A programmer guide for interfacing with and/or extending the CUPS
+ software.
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H1 ALIGN="RIGHT"><A NAME="OVERVIEW">1 - Printing System Overview</A></H1>
+<P>This chapter provides an overview of how the Common UNIX Printing
+ System works.</P>
+<H2><A NAME="2_1">The Printing Problem</A></H2>
+<P>For years<I> the printing problem</I> has plagued UNIX. Unlike
+ Microsoft&reg; Windows&reg; or Mac OS, UNIX has no standard interface or system
+ in place for supporting printers. Among the solutions currently
+ available, the Berkeley and System V printing systems are the most
+ prevalent.</P>
+<P>These printing systems support line printers (text only) or
+ PostScript printers (text and graphics), and with some coaxing they can
+ be made to support a full range of printers and file formats. However,
+ because each varient of the UNIX operating system uses a different
+ printing system than the next developing printer drivers for a wide
+ range of printers and operating systems is extremely difficult. That
+ combined with the limited volume of customers for each UNIX varient has
+ forced most printer vendors to give up supporting UNIX entirely.</P>
+<P>CUPS is designed to eliminate<I> the printing problem</I>. One common
+ printing system can be used by all UNIX varients to support the
+ printing needs of users. Printer vendors can use its modular filter
+ interface to develop a single driver program that supports a wide range
+ of file formats with little or no effort. Since CUPS provides both the
+ System V and Berkeley printing commands, users (and applications) can
+ reap the benefits of this new technology with no changes.</P>
+<H2><A NAME="2_2">The Technology</A></H2>
+<P>CUPS is based upon an emerging Internet standard called the Internet
+ Printing Protocol. IPP has been embraced by dozens of printer and
+ printer server manufacturers and is supported by Microsoft Windows
+ 2000.</P>
+<P>IPP defines a standard protocol for printing as well as managing
+ print jobs and printer options like media size, resolution, and so
+ forth. Like all IP-based protocols, IPP can be used locally or over the
+ Internet to printers hundreds or thousands of miles away. Unlike other
+ protocols, however, IPP also supports access control, authentication,
+ and encryption, making it a much more capable and secure printing
+ solution than older ones.</P>
+<P>IPP is layered on top of the Hyper-Text Transport Protocol (&quot;HTTP&quot;)
+ which is the basis of web servers on the Internet. This allows users to
+ view documentation, check status information on a printer or server,
+ and manage their printers, classes, and jobs using their web browser.</P>
+<P>CUPS provides a complete IPP/1.1 based printing system that provides
+ Basic, Digest, and local certificate authentication and user, domain,
+ or IP-based access control. TLS encryption will be available in future
+ versions of CUPS.</P>
+<H2><A NAME="2_3">Jobs</A></H2>
+<P>Each file or set of files that is submitted for printing is called a<I>
+ job</I>. Jobs are identified by a unique number starting at 1 and are
+ assigned to a particular destination, usually a printer. Jobs can also
+ have options associated with them such as media size, number of copies,
+ and priority.</P>
+<H2><A NAME="2_4">Classes</A></H2>
+<P>CUPS supports collections of printers known as<I> classes</I>. Jobs
+ sent to a class are forwarded to the first available printer in the
+ class.</P>
+<H2><A NAME="2_5">Filters</A></H2>
+<P>Filters allow a user or application to print many types of files
+ without extra effort. Print jobs sent to a CUPS server are filtered
+ before sending them to a printer. Some filters convert job files to
+ different formats that the printer can understand. Others perform page
+ selection and ordering tasks.</P>
+<P>CUPS provides filters for printing many types of image files, HP-GL/2
+ files, PDF files, and text files. CUPS also supplies PostScript and
+ image file Raster Image Processor (&quot;RIP&quot;) filters that convert
+ PostScript or image files into bitmaps that can be sent to a raster
+ printer.</P>
+<H2><A NAME="2_6">Backends</A></H2>
+<P>Backends perform the most important task of all - they send the
+ filtered print data to the printer.</P>
+<P>CUPS provides backends for printing over parallel, serial, and USB
+ ports, and over the network via the IPP, JetDirect (AppSocket), and
+ Line Printer Daemon (&quot;LPD&quot;) protocols. Additional backends are
+ available in network service packages such as the SMB backend included
+ with the popular SAMBA software.</P>
+<P>Backends are also used to determine the available devices. On startup
+ each backend is asked for a list of devices it supports, and any
+ information that is available. This allows the parallel backend to tell
+ CUPS that an EPSON Stylus Color 600 printer is attached to parallel
+ port 1, for example.</P>
+<H2><A NAME="2_7">Printer Drivers</A></H2>
+<P>Printer drivers in CUPS consist of one of more filters specific to a
+ printer. CUPS includes sample printer drivers for Hewlett-Packard
+ LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color,
+ and Stylus Photo printers. While these drivers do not generate optimal
+ output for the different printer models, they do provide basic printing
+ and demonstrate how you can write your own printer drivers and
+ incorporate them into CUPS.</P>
+<H2><A NAME="2_8">Networking</A></H2>
+<P>Printers and classes on the local system are automatically shared
+ with other systems on the network. This allows you to setup one system
+ to print to a printer and use this system as a printer server or spool
+ host for all of the others. Users may then select a local printer by
+ name or a remote printer using &quot;name@server&quot;.</P>
+<P>CUPS also provides<I> implicit classes</I>, which are collections of
+ printers and/or classes with the same name. This allows you to setup
+ multiple servers pointing to the same physical network printer, for
+ example, so that you aren't relying on a single system for printing.
+ Because this also works with printer classes, you can setup multiple
+ servers and printers and never worry about a single point of failure
+ unless all of the printers and servers go down!</P>
+<H1 ALIGN="RIGHT"><A NAME="USING_SYSTEM">2 - Using the Printing System</A>
+</H1>
+<P>This chapter shows you how to submit, query, and cancel print jobs to
+ different printers.</P>
+<H2><A NAME="3_1">Submitting Files for Printing</A></H2>
+<P>CUPS provides both the System V (<CODE>lp(1)</CODE>) and Berkeley (<CODE>
+lpr(1)</CODE>) printing commands. Type the following command to print a
+ file to the default (or only) printer on the system:</P>
+<UL>
+<PRE>
+<B>lp filename ENTER</B>
+</PRE>
+</UL>
+<P>or:</P>
+<UL>
+<PRE>
+<B>lpr filename ENTER</B>
+</PRE>
+</UL>
+<P>CUPS understands many different types of files directly, including
+ PostScript and image files. This allows you to print from inside your
+ applications or at the command-line, whichever is most convenient!</P>
+<H2><A NAME="3_2">Choosing a Printer</A></H2>
+<P>Many systems will have more than one printer available to the user.
+ These printers can be attached to the local system via a parallel,
+ serial, or USB port, or available over the network.</P>
+<P>Use the <CODE>lpstat(1)</CODE> command to see a list of available
+ printers:</P>
+<UL>
+<PRE>
+<B>lpstat -p -d ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>-p</CODE> option specifies that you want to see a list of
+ printers, and the <CODE>-d</CODE> option reports the current system
+ default printer or class.</P>
+<P>Use the <CODE>-d</CODE> option with the <CODE>lp</CODE> command to
+ print to a specific printer:</P>
+<UL>
+<PRE>
+<B>lp -d printer filename ENTER</B>
+</PRE>
+</UL>
+<P>or the <CODE>-P</CODE> option with the <CODE>lpr</CODE> command:</P>
+<UL>
+<PRE>
+<B>lpr -P printer filename ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="3_3">Setting Printer Options</A></H2>
+<P>For many types of files, the default printer options may be
+ sufficient for your needs. However, there may be times when you need to
+ change the options for a particular file you are printing.</P>
+<P>The <CODE>lp</CODE> and <CODE>lpr</CODE> commands allow you to pass
+ printer options using the <CODE>-o</CODE> option:</P>
+<UL>
+<PRE>
+<B>lp -o landscape -o scaling=75 -o media=A4 filename.jpg
+<B>lpr -o landscape -o scaling=75 -o media=A4 filename.jpg
+</B></B></PRE>
+</UL>
+<P>The available printer options vary depending on the printer. The
+ standard options are described in<A HREF="#STANDARD_OPTIONS"> Chapter
+ 3, &quot;Standard Printing Options&quot;</A>.</P>
+<H2><A NAME="3_4">Printing Multiple Copies</A></H2>
+<P>Both the <CODE>lp</CODE> and <CODE>lpr</CODE> commands have options
+ for printing more than one copy of a file:</P>
+<UL>
+<PRE>
+<B>lp -n <I>num-copies</I> filename ENTER</B>
+<B>lpr -#<I>num-copies</I> filename ENTER</B>
+</PRE>
+</UL>
+<P>Copies are normally<I> not</I> collated for you. Use the <CODE>-o
+ Collate=True</CODE> option to get collated copies :</P>
+<UL>
+<PRE>
+<B>lp -n <I>num-copies</I> -o Collate=True filename ENTER</B>
+<B>lpr -#<I>num-copies</I> -o Collate=True filename ENTER</B>
+</PRE>
+</UL>
+
+<!-- NEED 3in -->
+<H2><A NAME="3_5">Checking the Printer Status from the Command-Line</A></H2>
+<P>The <CODE>lpstat</CODE> command can be used to check for jobs that
+ you have submitted for printing:</P>
+<UL>
+<PRE>
+<B>lpstat ENTER</B>
+Printer-1 johndoe 4427776
+Printer-2 johndoe 15786
+Printer-3 johndoe 372842
+</PRE>
+</UL>
+<P>The jobs are listed in the order they will be printed. Use the <CODE>
+-p</CODE> option to see which files and printers are active:</P>
+<UL>
+<PRE>
+<B>lpstat -p ENTER</B>
+printer DeskJet now printing DeskJet-1.
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<P>Use the <CODE>-o</CODE> and <CODE>-p</CODE> options together to show
+ the jobs and the printers:</P>
+<UL>
+<PRE>
+<B>lpstat -o -p ENTER</B>
+Printer-1 johndoe 4427776
+Printer-2 johndoe 15786
+Printer-3 johndoe 372842
+printer DeskJet now printing DeskJet-1.
+</PRE>
+</UL>
+<H2><A NAME="3_6">Checking the Printer Status from the Web</A></H2>
+<P>Since CUPS uses the Internet Printing Protocol, it is also a
+ fully-functional web server. To use your web browser to monitor the
+ printers on your system, open the URL:</P>
+<UL>
+<PRE>
+<A HREF="http://localhost:631">http://localhost:631</A>
+</PRE>
+</UL>
+<P>From there you can view the status of classes, jobs, and printers
+ with the click of a button!</P>
+<H2><A NAME="3_7">Canceling a Print Job</A></H2>
+<P>The <CODE>cancel(1)</CODE> and <CODE>lprm(1)</CODE> commands cancel a
+ print job:</P>
+<UL>
+<PRE>
+<B>cancel <I>job-id</I> ENTER</B>
+<B>lprm <I>job-id</I> ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>job-id</CODE> is the number that was reported to you by the
+ <CODE>lp</CODE> or <CODE>lpstat</CODE> commands.</P>
+<H1 ALIGN="RIGHT"><A NAME="STANDARD_OPTIONS">3 - Standard Printer
+ Options</A></H1>
+<P>This chapter describes the standard printer options that are
+ available when printing with the <CODE>lp</CODE> and <CODE>lpr</CODE>
+ commands.</P>
+<H2><A NAME="4_1">General Options</A></H2>
+<P>The following options apply when printing all types of files.
+<!-- NEED 2in -->
+</P>
+<H3><A NAME="4_1_1">Selecting the Media Size, Type, and Source</A></H3>
+<P>The <CODE>-o media=xyz</CODE> option sets the media size, type,
+ and/or source:</P>
+<UL>
+<PRE>
+<B>lp -o media=Letter filename ENTER</B>
+<B>lp -o media=Letter,MultiPurpose filename ENTER</B>
+<B>lpr -o media=Letter,Transparency filename ENTER</B>
+<B>lpr -o media=Letter,MultiPurpose,Transparency filename ENTER</B>
+</PRE>
+</UL>
+
+<!-- NEED 3in -->
+<P>The available media sizes, types, and sources depend on the printer,
+ but most support the following options (case is not significant):</P>
+<UL>
+<LI><CODE>Letter</CODE> - US Letter (8.5x11 inches, or 216x279mm)</LI>
+<LI><CODE>Legal</CODE> - US Legal (8.5x14 inches, or 216x356mm)</LI>
+<LI><CODE>A4</CODE> - ISO A4 (8.27x11.69 inches, or 210x297mm)</LI>
+<LI><CODE>COM10</CODE> - US #10 Envelope (9.5x4.125 inches, or
+ 241x105mm)</LI>
+<LI><CODE>DL</CODE> - ISO DL Envelope (8.66x4.33 inches, or 220x110mm)</LI>
+<LI><CODE>Transparency</CODE> - Transparency media type or source</LI>
+<LI><CODE>Upper</CODE> - Upper paper tray</LI>
+<LI><CODE>Lower</CODE> - Lower paper tray</LI>
+<LI><CODE>MultiPurpose</CODE> - Multi-purpose paper tray</LI>
+<LI><CODE>LargeCapacity</CODE> - Large capacity paper tray</LI>
+</UL>
+<P>The actual options supported are defined in the printer's PPD file in
+ the <CODE>PageSize</CODE>, <CODE>InputSlot</CODE>, and <CODE>MediaType</CODE>
+ options.</P>
+<H3><A NAME="4_1_2">Setting the Orientation</A></H3>
+<P>The <CODE>-o landscape</CODE> option will rotate the page 90 degrees
+ to print in landscape orientation:</P>
+<UL>
+<PRE>
+<B>lp -o landscape filename ENTER</B>
+<B>lpr -o landscape filename ENTER</B>
+</PRE>
+</UL>
+<H3><A NAME="4_1_3">Printing On Both Sides of the Paper</A></H3>
+<P>The <CODE>-o sides=two-sided-short-edge</CODE> and <CODE>-o
+ sides=two-sided-long-edge</CODE> options will enable duplexing on the
+ printer, if the printer supports it. The <CODE>-o
+ sides=two-sided-short-edge</CODE> option is suitable for landscape
+ pages, while the <CODE>-o sides=two-sided-long-edge</CODE> option is
+ suitable for portrait pages:</P>
+<UL>
+<PRE>
+<B>lp -o sides=two-sided-short-edge filename ENTER</B>
+<B>lp -o sides=two-sided-long-edge filename ENTER</B>
+<B>lpr -o sides=two-sided-long-edge filename ENTER</B>
+</PRE>
+</UL>
+<P>The default is to print single-sided:</P>
+<UL>
+<PRE>
+<B>lp -o sides=one-sided filename ENTER</B>
+<B>lpr -o sides=one-sided filename ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="4_2">Banner Options</A></H2>
+<P>The following options apply when printing all types of files.</P>
+<H3><A NAME="4_2_1">Selecting the Banner Page(s)</A></H3>
+<P>The <CODE>-o jobsheets=start,end</CODE> option sets the banner
+ page(s) to use for a job:</P>
+<UL>
+<PRE>
+<B>lp -o job-sheets=none filename ENTER</B>
+<B>lp -o job-sheets=standard filename ENTER</B>
+<B>lpr -o job-sheets=classified,classified filename ENTER</B>
+</PRE>
+</UL>
+<P>If only one banner file is specified, it will be printed before the
+ files in the job. If a second banner file is specified, it is printed
+ after the files in the job.</P>
+<P>The available banner pages depend on the local system configuration;
+ CUPS includes the following banner files:</P>
+<UL>
+<LI><CODE>none</CODE> - Do not produce a banner page.</LI>
+<LI><CODE>classified</CODE> - A banner page with a &quot;classified&quot; label at
+ the top and bottom.</LI>
+<LI><CODE>confidential</CODE> - A banner page with a &quot;confidential&quot;
+ label at the top and bottom.</LI>
+<LI><CODE>secret</CODE> - A banner page with a &quot;secret&quot; label at the top
+ and bottom.</LI>
+<LI><CODE>standard</CODE> - A banner page with no label at the top and
+ bottom.</LI>
+<LI><CODE>topsecret</CODE> - A banner page with a &quot;top secret&quot; label at
+ the top and bottom.</LI>
+<LI><CODE>unclassified</CODE> - A banner page with an &quot;unclassified&quot;
+ label at the top and bottom.</LI>
+</UL>
+<H2><A NAME="4_3">Document Options</A></H2>
+<P>The following options apply when printing all types of files.</P>
+<H3><A NAME="4_3_1">Selecting a Range of Pages</A></H3>
+<P>The <CODE>-o page-ranges=pages</CODE> option selects a range of pages
+ for printing:</P>
+<UL>
+<PRE>
+<B>lp -o page-ranges=1 filename ENTER</B>
+<B>lp -o page-ranges=1-4 filename ENTER</B>
+<B>lp -o page-ranges=1-4,7,9-12 filename ENTER</B>
+<B>lpr -o page-ranges=1-4,7,9-12 filename ENTER</B>
+</PRE>
+</UL>
+<P>As shown above, the <CODE>pages</CODE> value can be a single page, a
+ range of pages, or a collection of page numbers and ranges separated by
+ commas. The pages will always be printed in ascending order, regardless
+ of the order of the pages in the <CODE>page-ranges</CODE> option.</P>
+<P>The default is to print all pages.</P>
+<H3><A NAME="4_3_2">Selecting Even or Odd Pages</A></H3>
+<P>Use the <CODE>-o page-set=set</CODE> option to select the even or odd
+ pages:</P>
+<UL>
+<PRE>
+<B>lp -o page-set=odd filename ENTER</B>
+<B>lp -o page-set=even filename ENTER</B>
+<B>lpr -o page-set=even filename ENTER</B>
+</PRE>
+</UL>
+<P>The default is to print all pages.</P>
+<H3><A NAME="4_3_3">N-Up Printing</A></H3>
+<P>The <CODE>-o number-up=value</CODE> option selects N-Up printing.
+ N-Up printing places multiple document pages on a single printed page.
+ CUPS supports 1, 2, 4, 6, 9, and 16-Up formats; the default format is
+ 1-Up:</P>
+<UL>
+<PRE>
+<B>lp -o number-up=1 filename ENTER</B>
+<B>lp -o number-up=2 filename ENTER</B>
+<B>lp -o number-up=4 filename ENTER</B>
+<B>lpr -o number-up=16 filename ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>-o page-border=value</CODE> option chooses the border to
+ draw around each page:</P>
+<UL>
+<LI><CODE>-o page-border=double</CODE>; draw two hairline borders around
+ each page</LI>
+<LI><CODE>-o page-border=double-thick</CODE>; draw two 1pt borders
+ around each page</LI>
+<LI><CODE>-o page-border=none</CODE>; do not draw a border (default)</LI>
+<LI><CODE>-o page-border=single</CODE>; draw one hairline border around
+ each page</LI>
+<LI><CODE>-o page-border=single-thick</CODE>; draw one 1pt border around
+ each page</LI>
+</UL>
+<P>The <CODE>-o number-up-layout=value</CODE> option chooses the layout
+ of the pages on each output page:</P>
+<UL>
+<LI><CODE>-o number-up-layout=btlr</CODE>; Bottom to top, left to right</LI>
+<LI><CODE>-o number-up-layout=btrl</CODE>; Bottom to top, right to left</LI>
+<LI><CODE>-o number-up-layout=lrbt</CODE>; Left to right, bottom to top</LI>
+<LI><CODE>-o number-up-layout=lrtb</CODE>; Left to right, top to bottom
+ (default)</LI>
+<LI><CODE>-o number-up-layout=rlbt</CODE>; Right to left, bottom to top</LI>
+<LI><CODE>-o number-up-layout=rltb</CODE>; Right to left, top to bottom</LI>
+<LI><CODE>-o number-up-layout=tblr</CODE>; Top to bottom, left to right</LI>
+<LI><CODE>-o number-up-layout=tbrl</CODE>; Top to bottom, right to left</LI>
+</UL>
+<H3><A NAME="4_3_4">Setting the Brightness</A></H3>
+<P>You can control the overall brightness of the printed output using
+ the <CODE>-o brightness=percent</CODE> option:</P>
+<UL>
+<PRE>
+<B>lp -o brightness=120 filename ENTER</B>
+<B>lpr -o brightness=120 filename ENTER</B>
+</PRE>
+</UL>
+<P>Values greater than 100 will lighten the print, while values less
+ than 100 will darken it.</P>
+<H3><A NAME="4_3_5">Setting the Gamma Correction</A></H3>
+<P>You can control the overall gamma correction of the printed output
+ using the <CODE>-o gamma=value</CODE> option:</P>
+<UL>
+<PRE>
+<B>lp -o gamma=1700 filename ENTER</B>
+<B>lpr -o gamma=1700 filename ENTER</B>
+</PRE>
+</UL>
+<P>Values greater than 1000 will lighten the print, while values less
+ than 1000 will darken it. The default gamma is 1000.</P>
+<H2><A NAME="4_4">Text Options</A></H2>
+<P>The following options apply when printing text files.</P>
+<H3><A NAME="4_4_1">Setting the Number of Characters Per Inch</A></H3>
+<P>The <CODE>-o cpi=value</CODE> option sets the number of characters
+ per inch:</P>
+<UL>
+<PRE>
+<B>lp -o cpi=10 filename ENTER</B>
+<B>lp -o cpi=12 filename ENTER</B>
+<B>lpr -o cpi=17 filename ENTER</B>
+</PRE>
+</UL>
+<P>The default characters per inch is 10.</P>
+<H3><A NAME="4_4_2">Setting the Number of Lines Per Inch</A></H3>
+<P>The <CODE>-o lpi=value</CODE> option sets the number of lines per
+ inch:</P>
+<UL>
+<PRE>
+<B>lp -o lpi=6 filename ENTER</B>
+<B>lpr -o lpi=8 filename ENTER</B>
+</PRE>
+</UL>
+<P>The default lines per inch is 6.</P>
+<H3><A NAME="4_4_3">Setting the Number of Columns</A></H3>
+<P>The <CODE>-o columns=value</CODE> option sets the number of text
+ columns:</P>
+<UL>
+<PRE>
+<B>lp -o columns=2 filename ENTER</B>
+<B>lpr -o columns=3 filename ENTER</B>
+</PRE>
+</UL>
+<P>The default number of columns is 1.</P>
+<H3><A NAME="4_4_4">Setting the Page Margins</A></H3>
+<P>Normally the page margins are set to the hard limits of the printer.
+ Use the <CODE>-o page-left=value</CODE>, <CODE>-o page-right=value</CODE>
+, <CODE>-o page-top=value</CODE>, and <CODE>-o page-bottom=value</CODE>
+ options to adjust the page margins:</P>
+<UL>
+<PRE>
+<B>lp -o page-left=<I>value</I> filename ENTER</B>
+<B>lp -o page-right=<I>value</I> filename ENTER</B>
+<B>lp -o page-top=<I>value</I> filename ENTER</B>
+<B>lp -o page-bottom=<I>value</I> filename ENTER</B>
+<B>lpr -o page-bottom=<I>value</I> filename ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>value</CODE> argument is the margin in points; each point
+ is 1/72 inch or 0.35mm.</P>
+<H3><A NAME="4_4_5">Pretty Printing</A></H3>
+<P>The <CODE>-o prettyprint</CODE> option puts a header at the top of
+ each page with the page number, job title (usually the filename), and
+ the date. Also, C and C++ keywords are highlighted, and comment lines
+ are italicized:</P>
+<UL>
+<PRE>
+<B>lp -o prettyprint filename ENTER</B>
+<B>lpr -o prettyprint filename ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="4_5">Image Options</A></H2>
+<P>The following options apply when printing image files.</P>
+<H3><A NAME="4_5_1">Positioning the Image</A></H3>
+<P>The <CODE>-o position=name</CODE> option specifies the position of
+ the image on the page:</P>
+<UL>
+<LI><CODE>center</CODE> - Center the image on the page (default)</LI>
+<LI><CODE>top</CODE> - Print the image centered at the top of the page</LI>
+<LI><CODE>left</CODE> - Print the image centered on the left of page</LI>
+<LI><CODE>right</CODE> - Print the image centered on the right of the
+ page</LI>
+<LI><CODE>top-left</CODE> - Print the image at the top left corner of
+ the page</LI>
+<LI><CODE>top-right</CODE> - Print the image at the top right corner of
+ the page</LI>
+<LI><CODE>bottom</CODE> - Print the image centered at the bottom of the
+ page</LI>
+<LI><CODE>bottom-left</CODE> - Print the image at the bottom left corner
+ of the page</LI>
+<LI><CODE>bottom-right</CODE> - Print the image at the bottom right
+ corner of the page</LI>
+</UL>
+<H3><A NAME="4_5_2">Scaling the Image</A></H3>
+<P>The <CODE>-o scaling=percent</CODE>, <CODE>-o ppi=value</CODE>, and <CODE>
+-o natural-scaling=percent</CODE> options change the size of a printed
+ image:</P>
+<UL>
+<PRE>
+<B>lp -o scaling=<I>percent</I> filename ENTER</B>
+<B>lp -o ppi=<I>value</I> filename ENTER</B>
+<B>lpr -o natural-scaling=<I>percent</I> filename ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>scaling=percent</CODE> value is a number from 1 to 800
+ specifying the size in relation to the page (<I>not</I> the image.) A
+ scaling of 100 percent will fill the page as completely as the image
+ aspect ratio allows. A scaling of 200 percent will print on up to 4
+ pages.</P>
+<P>The <CODE>ppi=value</CODE> value is a number from 1 to 1200
+ specifying the resolution of the image in pixels per inch. An image
+ that is 3000x2400 pixels will print 10x8 inches at 300 pixels per inch,
+ for example. If the specified resolution makes the image larger than
+ the page, multiple pages will be printed to satisfy the request.</P>
+<P>The <CODE>natural-scaling=percent</CODE> value is a number from 1 to
+ 800 specifying the size in relation to the natural image size. A
+ scaling of 100 percent will print the image at its natural size, while
+ a scaling of 50 percent will print the image at half its natural size.
+ If the specified scaling makes the image larger than the page, multiple
+ pages will be printed to satisfy the request.</P>
+<H3><A NAME="4_5_3">Adjusting the Hue (Tint) of an Image</A></H3>
+<P>The <CODE>-o hue=value</CODE> option will adjust the hue of the
+ printed image, much like the tint control on your television:</P>
+<UL>
+<PRE>
+<B>lp -o hue=<I>value</I> filename ENTER</B>
+<B>lpr -o hue=<I>value</I> filename ENTER</B>
+</PRE>
+</UL>
+
+<!-- NEED 3in -->
+<P>The <CODE>value</CODE> argument is a number from -360 to 360 and
+ represents the color hue rotation. The following table summarizes the
+ change you'll see with different colors:
+<CENTER>
+<TABLE BORDER="1" WIDTH="50%">
+<TR><TH>Original</TH><TH>hue=-45</TH><TH>hue=45</TH></TR>
+<TR><TD>Red</TD><TD>Purple</TD><TD>Yellow-orange</TD></TR>
+<TR><TD>Green</TD><TD>Yellow-green</TD><TD>Blue-green</TD></TR>
+<TR><TD>Yellow</TD><TD>Orange</TD><TD>Green-yellow</TD></TR>
+<TR><TD>Blue</TD><TD>Sky-blue</TD><TD>Purple</TD></TR>
+<TR><TD>Magenta</TD><TD>Indigo</TD><TD>Crimson</TD></TR>
+<TR><TD>Cyan</TD><TD>Blue-green</TD><TD>Light-navy-blue</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<P>The default hue adjustment is 0.</P>
+<H3><A NAME="4_5_4">Adjusting the Saturation (Color) of an Image</A></H3>
+<P>The <CODE>-o saturation=percent</CODE> option adjusts the saturation
+ of the colors in an image, much like the color knob on your television:</P>
+<UL>
+<PRE>
+<B>lp -o saturation=<I>percent</I> filename ENTER</B>
+<B>lpr -o saturation=<I>percent</I> filename ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>percent</CODE> argument specifies the color saturation from
+ 0 to 200. A color saturation of 0 produces a black-and-white print,
+ while a value of 200 will make the colors extremely intense.</P>
+<P>The default saturation is 100.
+<!-- NEED 4in -->
+</P>
+<H2><A NAME="4_6">HP-GL/2 Options</A></H2>
+<P>The following options apply to HP-GL/2 files.</P>
+<H3><A NAME="4_6_1">Printing in Black</A></H3>
+<P>The <CODE>-o blackplot</CODE> option specifies that all pens should
+ plot in black:</P>
+<UL>
+<PRE>
+<B>lp -o blackplot filename ENTER</B>
+<B>lpr -o blackplot filename ENTER</B>
+</PRE>
+</UL>
+<P>The default is to use the colors defined in the plot file or the
+ standard pen colors defined in the HP-GL/2 reference manual from
+ Hewlett Packard.</P>
+<H3><A NAME="4_6_2">Fitting the Plot on the Page</A></H3>
+<P>The <CODE>-o fitplot</CODE> option specifies that the plot should be
+ scaled to fit on the page:</P>
+<UL>
+<PRE>
+<B>lp -o fitplot filename ENTER</B>
+<B>lpr -o fitplot filename ENTER</B>
+</PRE>
+</UL>
+<P>The default is to use the absolute distances specified in the plot
+ file.
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>This feature depends upon an accurate plot size (<CODE>PS</CODE>)
+ command in the HP-GL/2 file. If no plot size is given in the file than
+ the HP-GL/2 filter assumes the plot is ANSI E size.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="4_6_3">Setting the Default Pen Width</A></H3>
+<P>The <CODE>-o penwidth=value</CODE> option specifies the default pen
+ width for HP-GL/2 files:</P>
+<UL>
+<PRE>
+<B>lp -o penwidth=<I>value</I> filename ENTER</B>
+<B>lpr -o penwidth=<I>value</I> filename ENTER</B>
+</PRE>
+</UL>
+<P>The pen width <CODE>value</CODE> specifies the pen width in
+ micrometers. The default value of 1000 produces lines that are 1
+ millimeter in width. Specifying a pen width of 0 produces lines that
+ are exactly 1 pixel wide.
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>This option is ignored when the pen widths are set in the plot file.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H2><A NAME="4_7">Raw or Unfiltered Output</A></H2>
+<P>The <CODE>-o raw</CODE> option allows you to send files directly to a
+ printer without filtering. This is sometimes required when printing
+ from applications that provide their own &quot;printer drivers&quot; for your
+ printer:</P>
+<UL>
+<PRE>
+<B>lp -o raw filename ENTER</B>
+<B>lpr -o raw filename ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>-l</CODE> option can also be used with the <CODE>lpr</CODE>
+ command to send files directly to a printer:</P>
+<UL>
+<PRE>
+<B>lpr -l filename ENTER</B>
+</PRE>
+</UL>
+<H1 ALIGN="RIGHT"><A NAME="SAVING_OPTIONS">4 - Saving Printer Options
+ and Defaults</A></H1>
+<P>This chapter describes how to save printer options for your printer
+ and set your own default printer.</P>
+<H2><A NAME="5_1">Printer Options</A></H2>
+<P>Each printer supports a large number of options, which you learned
+ about in<A HREF="#STANDARD_OPTIONS"> Chapter 3, &quot;Standard Printer
+ Options&quot;</A>. Rather than specifying these options each time you print
+ a file, CUPS allows you to save them as &quot;default&quot; options for the
+ printer.</P>
+<P>The <CODE>lpoptions(1)</CODE> command saves the options for your
+ printers. Like the <CODE>lp</CODE> and <CODE>lpr</CODE> commands, it
+ accepts printer options using the <CODE>-o</CODE> argument:</P>
+<UL>
+<PRE>
+<B>lpoptions -o prettyprint ENTER</B>
+<B>lpoptions -o media=A4 -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -o media=Legal -o scaling=100 ENTER</B>
+</PRE>
+</UL>
+<P>Once saved, any <CODE>lp</CODE> or <CODE>lpr</CODE> command will use
+ them when you print.</P>
+<H2><A NAME="5_2">Setting Options for a Specific Printer</A></H2>
+<P>The previous example shows how to set the options for the default
+ printer. The <CODE>-p printer</CODE> option specifies the options are
+ for another printer:</P>
+<UL>
+<PRE>
+<B>lpoptions -p laserjet -o prettyprint ENTER</B>
+<B>lpoptions -p laserjet -o media=A4 -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -p deskjet -o media=Legal -o scaling=100 ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="5_3">Removing Options</A></H2>
+<P>The previous two examples shows how to set options for the default
+ and a specific printer. Below, shows you how to remove the saved option
+ using the <CODE>-r</CODE> argument:</P>
+<UL>
+<PRE>
+<KBD>lpoptions -r prettyprint <I>ENTER</I></KBD>
+<KBD>lpoptions -p laserjet -r prettyprint <I>ENTER</I></KBD>
+</PRE>
+</UL>
+<H2><A NAME="5_4">Viewing the Current Defaults</A></H2>
+<P>The <CODE>lpoptions</CODE> command can also be used to show the
+ current options by not specifying any new options on the command-line:</P>
+<UL>
+<PRE>
+<B>lpoptions ENTER</B>
+media=A4 sides=two-sided-long-edge
+<B>lpoptions -p deskjet ENTER</B>
+media=Legal scaling=100
+</PRE>
+</UL>
+<H2><A NAME="5_5">Viewing Options for a Specific Printer</A></H2>
+<P>You can display the supported options using the <CODE>lpoptions</CODE>
+ command with the <CODE>-l</CODE> option, as follows:</P>
+<UL>
+<PRE>
+<B>lpoptions -p laserjet -l ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="5_6">Setting the Default Printer</A></H2>
+<P>The administrator normally will set a system-wide default printer
+ that is normally used as the default printer by everyone. Use the <CODE>
+-d printer</CODE> option to set your own default printer:</P>
+<UL>
+<PRE>
+<B>lpoptions -d deskjet ENTER</B>
+</PRE>
+</UL>
+<P>The printer can be local (<CODE>deskjet</CODE>) or remote (<CODE>
+deskjet@server</CODE>).</P>
+<H2><A NAME="5_7">Printer Instances</A></H2>
+<P>Besides setting options for each print queue, CUPS supports<I>
+ printer instances</I> which allow you to define several different sets
+ of options for each printer. You specify a printer instance using the
+ slash (<CODE>/</CODE>) character:</P>
+<UL>
+<PRE>
+<B>lpoptions -p laserjet/duplex -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -p laserjet/legal -o media=Legal ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>lp</CODE> and lpr commands also understand this notation:</P>
+<UL>
+<PRE>
+<B>lp -d laserjet/duplex filename ENTER</B>
+<B>lpr -P laserjet/legal filename ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="5_8">Removing Instances</A></H2>
+<P>Use the <CODE>-x printer/instance</CODE> option to remove a printer
+ instance that you no longer need:</P>
+<UL>
+<PRE>
+<B>lpoptions -x laserjet ENTER</B>
+<B>lpoptions -x laserjet/duplex ENTER</B>
+<B>lpoptions -x laserjet/legal ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>-x</CODE> option only removes the default options for that
+ printer and instance; the original print queue will remain until
+ deleted with the <CODE>lpadmin(8)</CODE> command by the administrator.</P>
+<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - Software License Agreement</A></H1>
+<H2 ALIGN="CENTER"><A NAME="6_1">Common UNIX Printing System License
+ Agreement</A></H2>
+<P ALIGN="CENTER">Copyright 1997-2002 by Easy Software Products
+<BR> 44141 AIRPORT VIEW DR STE 204
+<BR> HOLLYWOOD, MARYLAND 20636-3111 USA
+<BR>
+<BR> Voice: +1.301.373.9600
+<BR> Email:<A HREF="mailto:cups-info@cups.org"> cups-info@cups.org</A>
+<BR> WWW:<A HREF="http://www.cups.org"> http://www.cups.org</A></P>
+<H3><A NAME="6_1_1">Introduction</A></H3>
+<P>The Common UNIX Printing System<SUP>TM</SUP>, (&quot;CUPS<SUP>TM</SUP>&quot;),
+ is provided under the GNU General Public License (&quot;GPL&quot;) and GNU
+ Library General Public License (&quot;LGPL&quot;), Version 2, with exceptions for
+ Apple operating systems and the OpenSSL toolkit. A copy of the
+ exceptions and licenses follow this introduction.</P>
+<P>The GNU LGPL applies to the CUPS API library, located in the &quot;cups&quot;
+ subdirectory of the CUPS source distribution and in the &quot;cups&quot; include
+ directory and library files in the binary distributions. The GNU GPL
+ applies to the remainder of the CUPS distribution, including the
+ &quot;pdftops&quot; filter which is based upon Xpdf and the CUPS imaging library.</P>
+<P>For those not familiar with the GNU GPL, the license basically allows
+ you to:</P>
+<UL>
+<LI>Use the CUPS software at no charge.</LI>
+<LI>Distribute verbatim copies of the software in source or binary form.</LI>
+<LI>Sell verbatim copies of the software for a media fee, or sell
+ support for the software.</LI>
+<LI>Distribute or sell printer drivers and filters that use CUPS so long
+ as source code is made available under the GPL.</LI>
+</UL>
+<P>What this license<B> does not</B> allow you to do is make changes or
+ add features to CUPS and then sell a binary distribution without source
+ code. You must provide source for any new drivers, changes, or
+ additions to the software, and all code must be provided under the GPL
+ or LGPL as appropriate. The only exceptions to this are the portions of
+ the CUPS software covered by the Apple operating system license
+ exceptions outlined later in this license agreement.</P>
+<P>The GNU LGPL relaxes the &quot;link-to&quot; restriction, allowing you to
+ develop applications that use the CUPS API library under other licenses
+ and/or conditions as appropriate for your application.</P>
+<H3><A NAME="6_1_2">License Exceptions</A></H3>
+<P>In addition, as the copyright holder of CUPS, Easy Software Products
+ grants the following special exceptions:</P>
+<OL>
+<LI><B>Apple Operating System Development License Exception</B>;
+<OL TYPE="a">
+<LI>Software that is developed by any person or entity for an Apple
+ Operating System (&quot;Apple OS-Developed Software&quot;), including but not
+ limited to Apple and third party printer drivers, filters, and backends
+ for an Apple Operating System, that is linked to the CUPS imaging
+ library or based on any sample filters or backends provided with CUPS
+ shall not be considered to be a derivative work or collective work
+ based on the CUPS program and is exempt from the mandatory source code
+ release clauses of the GNU GPL. You may therefore distribute linked
+ combinations of the CUPS imaging library with Apple OS-Developed
+ Software without releasing the source code of the Apple OS-Developed
+ Software. You may also use sample filters and backends provided with
+ CUPS to develop Apple OS-Developed Software without releasing the
+ source code of the Apple OS-Developed Software.</LI>
+<LI>An Apple Operating System means any operating system software
+ developed and/or marketed by Apple Computer, Inc., including but not
+ limited to all existing releases and versions of Apple's Darwin, Mac OS
+ X, and Mac OS X Server products and all follow-on releases and future
+ versions thereof.</LI>
+<LI>This exception is only available for Apple OS-Developed Software and
+ does not apply to software that is distributed for use on other
+ operating systems.</LI>
+<LI>All CUPS software that falls under this license exception have the
+ following text at the top of each source file:<BLOCKQUOTE>This file is
+ subject to the Apple OS-Developed Software exception.</BLOCKQUOTE></LI>
+</OL>
+</LI>
+<LI><B>OpenSSL Toolkit License Exception</B>;
+<OL TYPE="a">
+<LI>Easy Software Products explicitly allows the compilation and
+ distribution of the CUPS software with the OpenSSL Toolkit.</LI>
+</OL>
+</LI>
+</OL>
+<P>No developer is required to provide these exceptions in a derived
+ work.</P>
+<H3><A NAME="6_1_3">Trademarks</A></H3>
+<P>Easy Software Products has trademarked the Common UNIX Printing
+ System, CUPS, and CUPS logo. These names and logos may be used freely
+ in any direct port or binary distribution of CUPS. Please contract Easy
+ Software Products for written permission to use them in derivative
+ products. Our intention is to protect the value of these trademarks and
+ ensure that any derivative product meets the same high-quality
+ standards as the original.</P>
+<H3><A NAME="6_1_4">Binary Distribution Rights</A></H3>
+<P>Easy Software Products also sells rights to the CUPS source code
+ under a binary distribution license for vendors that are unable to
+ release source code for their drivers, additions, and modifications to
+ CUPS under the GNU GPL and LGPL. For information please contact us at
+ the address shown above.</P>
+<P>The Common UNIX Printing System provides a &quot;pdftops&quot; filter that is
+ based on the Xpdf software. For binary distribution licensing of this
+ software, please contact:<BLOCKQUOTE> Derek B. Noonburg
+<BR> Email:<A HREF="mailto:derekn@foolabs.com"> derekn@foolabs.com</A>
+<BR> WWW:<A HREF="http://www.foolabs.com/xpdf/">
+ http://www.foolabs.com/xpdf/</A></BLOCKQUOTE></P>
+<H3><A NAME="6_1_5">Support</A></H3>
+<P>Easy Software Products sells software support for CUPS as well as a
+ commercial printing product based on CUPS called ESP Print Pro. You can
+ find out more at our web site:</P>
+<UL>
+<PRE>
+<A HREF="http://www.easysw.com/">http://www.easysw.com/</A>
+</PRE>
+</UL>
+
+<!-- NEW PAGE -->
+<H2><A NAME="6_2">GNU GENERAL PUBLIC LICENSE</A></H2>
+<P>Version 2, June 1991</P>
+<PRE>
+Copyright 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim
+copies of this license document, but changing it is not allowed.
+</PRE>
+<H4>Preamble</H4>
+<P>The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public License is
+ intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users. This
+ General Public License applies to most of the Free Software
+ Foundation's software and to any other program whose authors commit to
+ using it. (Some other Free Software Foundation software is covered by
+ the GNU Library General Public License instead.) You can apply it to
+ your programs, too.</P>
+<P>When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it in
+ new free programs; and that you know you can do these things.</P>
+<P>To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the software, or if you modify it.</P>
+<P>For example, if you distribute copies of such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have. You must make sure that they, too, receive or can get the
+ source code. And you must show them these terms so they know their
+ rights.</P>
+<P>We protect your rights with two steps: (1) copyright the software,
+ and (2) offer you this license which gives you legal permission to
+ copy, distribute and/or modify the software.</P>
+<P>Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software. If the software is modified by someone else and passed on, we
+ want its recipients to know that what they have is not the original, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.</P>
+<P>Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that redistributors of a free
+ program will individually obtain patent licenses, in effect making the
+ program proprietary. To prevent this, we have made it clear that any
+ patent must be licensed for everyone's free use or not licensed at all.</P>
+<P>The precise terms and conditions for copying, distribution and
+ modification follow.</P>
+<H4>GNU GENERAL PUBLIC LICENSE
+<BR> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+<OL START="0">
+<LI>This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The &quot;Program&quot;, below,
+ refers to any such program or work, and a &quot;work based on the Program&quot;
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language. (Hereinafter, translation is included without limitation in
+ the term &quot;modification&quot;.) Each licensee is addressed as &quot;you&quot;.
+<P>Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ the Program is not restricted, and the output from the Program is
+ covered only if its contents constitute a work based on the Program
+ (independent of having been made by running the Program). Whether that
+ is true depends on what the Program does.</P>
+<LI>You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you conspicuously
+ and appropriately publish on each copy an appropriate copyright notice
+ and disclaimer of warranty; keep intact all the notices that refer to
+ this License and to the absence of any warranty; and give any other
+ recipients of the Program a copy of this License along with the
+ Program.
+<P>You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.</P>
+<LI>You may modify your copy or copies of the Program or any portion of
+ it, thus forming a work based on the Program, and copy and distribute
+ such modifications or work under the terms of Section 1 above, provided
+ that you also meet all of these conditions:
+<OL TYPE="a">
+<LI>You must cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change.</LI>
+<LI>You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any part
+ thereof, to be licensed as a whole at no charge to all third parties
+ under the terms of this License.</LI>
+<LI>if the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the most ordinary way, to print or display an announcement including
+ an appropriate copyright notice and a notice that there is no warranty
+ (or else, saying that you provide a warranty) and that users may
+ redistribute the program under these conditions, and telling the user
+ how to view a copy of this License. (Exception: if the Program itself
+ is interactive but does not normally print such an announcement, your
+ work based on the Program is not required to print an announcement.)</LI>
+</OL>
+<P>These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Program,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Program, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.</P>
+<P>Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.</P>
+<P>In addition, mere aggregation of another work not based on the
+ Program with the Program (or with a work based on the Program) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.</P>
+<LI>You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+<OL TYPE="a">
+<LI>Accompany it with the complete corresponding machine-readable source
+ code, which must be distributed under the terms of Sections 1 and 2
+ above on a medium customarily used for software interchange; or,</LI>
+<LI>Accompany it with a written offer, valid for at least three years,
+ to give any third party, for a charge no more than your cost of
+ physically performing source distribution, a complete machine-readable
+ copy of the corresponding source code, to be distributed under the
+ terms of Sections 1 and 2 above on a medium customarily used for
+ software interchange; or,</LI>
+<LI>Accompany it with the information you received as to the offer to
+ distribute corresponding source code. (This alternative is allowed only
+ for noncommercial distribution and only if you received the program in
+ object code or executable form with such an offer, in accord with
+ Subsection b above.)</LI>
+</OL>
+<P>The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to control
+ compilation and installation of the executable. However, as a special
+ exception, the source code distributed need not include anything that
+ is normally distributed (in either source or binary form) with the
+ major components (compiler, kernel, and so on) of the operating system
+ on which the executable runs, unless that component itself accompanies
+ the executable.</P>
+<P>If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent access
+ to copy the source code from the same place counts as distribution of
+ the source code, even though third parties are not compelled to copy
+ the source along with the object code.</P>
+<LI>You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt otherwise
+ to copy, modify, sublicense or distribute the Program is void, and will
+ automatically terminate your rights under this License. However,
+ parties who have received copies, or rights, from you under this
+ License will not have their licenses terminated so long as such parties
+ remain in full compliance.</LI>
+<LI>You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying the
+ Program or works based on it.</LI>
+<LI>Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject to
+ these terms and conditions. You may not impose any further restrictions
+ on the recipients' exercise of the rights granted herein. You are not
+ responsible for enforcing compliance by third parties to this License.</LI>
+<LI>If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all. For example, if a patent license
+ would not permit royalty-free redistribution of the Program by all
+ those who receive copies directly or indirectly through you, then the
+ only way you could satisfy both it and this License would be to refrain
+ entirely from distribution of the Program.
+<P>If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.</P>
+<P>It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.</P>
+<P>This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.</P>
+<LI>If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License may
+ add an explicit geographical distribution limitation excluding those
+ countries, so that distribution is permitted only in or among countries
+ not thus excluded. In such case, this License incorporates the
+ limitation as if written in the body of this License.</LI>
+<LI>The Free Software Foundation may publish revised and/or new versions
+ of the General Public License from time to time. Such new versions will
+ be similar in spirit to the present version, but may differ in detail
+ to address new problems or concerns.
+<P>Each version is given a distinguishing version number. If the Program
+ specifies a version number of this License which applies to it and &quot;any
+ later version&quot;, you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Program does not specify a version
+ number of this License, you may choose any version ever published by
+ the Free Software Foundation.</P>
+<LI>If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted by the
+ Free Software Foundation, write to the Free Software Foundation; we
+ sometimes make exceptions for this. Our decision will be guided by the
+ two goals of preserving the free status of all derivatives of our free
+ software and of promoting the sharing and reuse of software generally.</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<H4>NO WARRANTY</H4>
+<OL START="11">
+<LI>BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER
+ EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
+ YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+ NECESSARY SERVICING, REPAIR OR CORRECTION.</LI>
+<LI>IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+ AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
+ FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.</LI>
+</OL>
+<H4>END OF TERMS AND CONDITIONS</H4>
+
+<!-- NEW PAGE -->
+<H2><A NAME="6_3">GNU LIBRARY GENERAL PUBLIC LICENSE</A></H2>
+<P>Version 2, June 1991</P>
+<PRE>
+Copyright (C) 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+</PRE>
+<H4>Preamble</H4>
+<P>The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public Licenses
+ are intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users.</P>
+<P>This license, the Library General Public License, applies to some
+ specially designated Free Software Foundation software, and to any
+ other libraries whose authors decide to use it. You can use it for your
+ libraries, too.</P>
+<P>When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it in
+ new free programs; and that you know you can do these things.</P>
+<P>To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the library, or if you modify it.</P>
+<P>For example, if you distribute copies of the library, whether gratis
+ or for a fee, you must give the recipients all the rights that we gave
+ you. You must make sure that they, too, receive or can get the source
+ code. If you link a program with the library, you must provide complete
+ object files to the recipients so that they can relink them with the
+ library, after making changes to the library and recompiling it. And
+ you must show them these terms so they know their rights.</P>
+<P>Our method of protecting your rights has two steps: (1) copyright the
+ library, and (2) offer you this license which gives you legal
+ permission to copy, distribute and/or modify the library.</P>
+<P>Also, for each distributor's protection, we want to make certain that
+ everyone understands that there is no warranty for this free library.
+ If the library is modified by someone else and passed on, we want its
+ recipients to know that what they have is not the original version, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.</P>
+<P>Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that companies distributing free
+ software will individually obtain patent licenses, thus in effect
+ transforming the program into proprietary software. To prevent this, we
+ have made it clear that any patent must be licensed for everyone's free
+ use or not licensed at all.</P>
+<P>Most GNU software, including some libraries, is covered by the
+ ordinary GNU General Public License, which was designed for utility
+ programs. This license, the GNU Library General Public License, applies
+ to certain designated libraries. This license is quite different from
+ the ordinary one; be sure to read it in full, and don't assume that
+ anything in it is the same as in the ordinary license.</P>
+<P>The reason we have a separate public license for some libraries is
+ that they blur the distinction we usually make between modifying or
+ adding to a program and simply using it. Linking a program with a
+ library, without changing the library, is in some sense simply using
+ the library, and is analogous to running a utility program or
+ application program. However, in a textual and legal sense, the linked
+ executable is a combined work, a derivative of the original library,
+ and the ordinary General Public License treats it as such.</P>
+<P>Because of this blurred distinction, using the ordinary General
+ Public License for libraries did not effectively promote software
+ sharing, because most developers did not use the libraries. We
+ concluded that weaker conditions might promote sharing better.</P>
+<P>However, unrestricted linking of non-free programs would deprive the
+ users of those programs of all benefit from the free status of the
+ libraries themselves. This Library General Public License is intended
+ to permit developers of non-free programs to use free libraries, while
+ preserving your freedom as a user of such programs to change the free
+ libraries that are incorporated in them. (We have not seen how to
+ achieve this as regards changes in header files, but we have achieved
+ it as regards changes in the actual functions of the Library.) The hope
+ is that this will lead to faster development of free libraries.</P>
+<P>The precise terms and conditions for copying, distribution and
+ modification follow. Pay close attention to the difference between a
+ &quot;work based on the library&quot; and a &quot;work that uses the library&quot;. The
+ former contains code derived from the library, while the latter only
+ works together with the library.</P>
+<P>Note that it is possible for a library to be covered by the ordinary
+ General Public License rather than by this special one.</P>
+<H4>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+<P><STRONG>0.</STRONG> This License Agreement applies to any software
+ library which contains a notice placed by the copyright holder or other
+ authorized party saying it may be distributed under the terms of this
+ Library General Public License (also called &quot;this License&quot;). Each
+ licensee is addressed as &quot;you&quot;.</P>
+<P>A &quot;library&quot; means a collection of software functions and/or data
+ prepared so as to be conveniently linked with application programs
+ (which use some of those functions and data) to form executables.</P>
+<P>The &quot;Library&quot;, below, refers to any such software library or work
+ which has been distributed under these terms. A &quot;work based on the
+ Library&quot; means either the Library or any derivative work under
+ copyright law: that is to say, a work containing the Library or a
+ portion of it, either verbatim or with modifications and/or translated
+ straightforwardly into another language. (Hereinafter, translation is
+ included without limitation in the term &quot;modification&quot;.)</P>
+<P>&quot;Source code&quot; for a work means the preferred form of the work for
+ making modifications to it. For a library, complete source code means
+ all the source code for all modules it contains, plus any associated
+ interface definition files, plus the scripts used to control
+ compilation and installation of the library.</P>
+<P>Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ a program using the Library is not restricted, and output from such a
+ program is covered only if its contents constitute a work based on the
+ Library (independent of the use of the Library in a tool for writing
+ it). Whether that is true depends on what the Library does and what the
+ program that uses the Library does.</P>
+<P><STRONG>1.</STRONG> You may copy and distribute verbatim copies of
+ the Library's complete source code as you receive it, in any medium,
+ provided that you conspicuously and appropriately publish on each copy
+ an appropriate copyright notice and disclaimer of warranty; keep intact
+ all the notices that refer to this License and to the absence of any
+ warranty; and distribute a copy of this License along with the Library.</P>
+<P>You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.</P>
+<P><STRONG>2.</STRONG> You may modify your copy or copies of the Library
+ or any portion of it, thus forming a work based on the Library, and
+ copy and distribute such modifications or work under the terms of
+ Section 1 above, provided that you also meet all of these conditions:</P>
+<OL TYPE="a">
+<LI>The modified work must itself be a software library.
+<P></P>
+<LI>You must cause the files modified to carry prominent notices stating
+ that you changed the files and the date of any change.
+<P></P>
+<LI>You must cause the whole of the work to be licensed at no charge to
+ all third parties under the terms of this License.
+<P></P>
+<LI>If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses the
+ facility, other than as an argument passed when the facility is
+ invoked, then you must make a good faith effort to ensure that, in the
+ event an application does not supply such function or table, the
+ facility still operates, and performs whatever part of its purpose
+ remains meaningful.
+<P>(For example, a function in a library to compute square roots has a
+ purpose that is entirely well-defined independent of the application.
+ Therefore, Subsection 2d requires that any application-supplied
+ function or table used by this function must be optional: if the
+ application does not supply it, the square root function must still
+ compute square roots.)</P>
+</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<P>These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Library,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Library, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.</P>
+<P>Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Library.</P>
+<P>In addition, mere aggregation of another work not based on the
+ Library with the Library (or with a work based on the Library) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.</P>
+<P><STRONG>3.</STRONG> You may opt to apply the terms of the ordinary
+ GNU General Public License instead of this License to a given copy of
+ the Library. To do this, you must alter all the notices that refer to
+ this License, so that they refer to the ordinary GNU General Public
+ License, version 2, instead of to this License. (If a newer version
+ than version 2 of the ordinary GNU General Public License has appeared,
+ then you can specify that version instead if you wish.) Do not make any
+ other change in these notices.</P>
+<P>Once this change is made in a given copy, it is irreversible for that
+ copy, so the ordinary GNU General Public License applies to all
+ subsequent copies and derivative works made from that copy.</P>
+<P>This option is useful when you wish to copy part of the code of the
+ Library into a program that is not a library.</P>
+<P><STRONG>4.</STRONG> You may copy and distribute the Library (or a
+ portion or derivative of it, under Section 2) in object code or
+ executable form under the terms of Sections 1 and 2 above provided that
+ you accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections 1
+ and 2 above on a medium customarily used for software interchange.</P>
+<P>If distribution of object code is made by offering access to copy
+ from a designated place, then offering equivalent access to copy the
+ source code from the same place satisfies the requirement to distribute
+ the source code, even though third parties are not compelled to copy
+ the source along with the object code.</P>
+<P><STRONG>5.</STRONG> A program that contains no derivative of any
+ portion of the Library, but is designed to work with the Library by
+ being compiled or linked with it, is called a &quot;work that uses the
+ Library&quot;. Such a work, in isolation, is not a derivative work of the
+ Library, and therefore falls outside the scope of this License.</P>
+<P>However, linking a &quot;work that uses the Library&quot; with the Library
+ creates an executable that is a derivative of the Library (because it
+ contains portions of the Library), rather than a &quot;work that uses the
+ library&quot;. The executable is therefore covered by this License. Section
+ 6 states terms for distribution of such executables.</P>
+<P>When a &quot;work that uses the Library&quot; uses material from a header file
+ that is part of the Library, the object code for the work may be a
+ derivative work of the Library even though the source code is not.
+ Whether this is true is especially significant if the work can be
+ linked without the Library, or if the work is itself a library. The
+ threshold for this to be true is not precisely defined by law.</P>
+<P>If such an object file uses only numerical parameters, data structure
+ layouts and accessors, and small macros and small inline functions (ten
+ lines or less in length), then the use of the object file is
+ unrestricted, regardless of whether it is legally a derivative work.
+ (Executables containing this object code plus portions of the Library
+ will still fall under Section 6.)</P>
+<P>Otherwise, if the work is a derivative of the Library, you may
+ distribute the object code for the work under the terms of Section 6.
+ Any executables containing that work also fall under Section 6, whether
+ or not they are linked directly with the Library itself.</P>
+<P><STRONG>6.</STRONG> As an exception to the Sections above, you may
+ also compile or link a &quot;work that uses the Library&quot; with the Library to
+ produce a work containing portions of the Library, and distribute that
+ work under terms of your choice, provided that the terms permit
+ modification of the work for the customer's own use and reverse
+ engineering for debugging such modifications.</P>
+<P>You must give prominent notice with each copy of the work that the
+ Library is used in it and that the Library and its use are covered by
+ this License. You must supply a copy of this License. If the work
+ during execution displays copyright notices, you must include the
+ copyright notice for the Library among them, as well as a reference
+ directing the user to the copy of this License. Also, you must do one
+ of these things:</P>
+<OL TYPE="a">
+<LI>Accompany the work with the complete corresponding machine-readable
+ source code for the Library including whatever changes were used in the
+ work (which must be distributed under Sections 1 and 2 above); and, if
+ the work is an executable linked with the Library, with the complete
+ machine-readable &quot;work that uses the Library&quot;, as object code and/or
+ source code, so that the user can modify the Library and then relink to
+ produce a modified executable containing the modified Library. (It is
+ understood that the user who changes the contents of definitions files
+ in the Library will not necessarily be able to recompile the
+ application to use the modified definitions.)
+<P></P>
+<LI>Accompany the work with a written offer, valid for at least three
+ years, to give the same user the materials specified in Subsection 6a,
+ above, for a charge no more than the cost of performing this
+ distribution.
+<P></P>
+<LI>If distribution of the work is made by offering access to copy from
+ a designated place, offer equivalent access to copy the above specified
+ materials from the same place.
+<P></P>
+<LI>Verify that the user has already received a copy of these materials
+ or that you have already sent this user a copy.</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<P>For an executable, the required form of the &quot;work that uses the
+ Library&quot; must include any data and utility programs needed for
+ reproducing the executable from it. However, as a special exception,
+ the source code distributed need not include anything that is normally
+ distributed (in either source or binary form) with the major components
+ (compiler, kernel, and so on) of the operating system on which the
+ executable runs, unless that component itself accompanies the
+ executable.</P>
+<P>It may happen that this requirement contradicts the license
+ restrictions of other proprietary libraries that do not normally
+ accompany the operating system. Such a contradiction means you cannot
+ use both them and the Library together in an executable that you
+ distribute.</P>
+<P><STRONG>7.</STRONG> You may place library facilities that are a work
+ based on the Library side-by-side in a single library together with
+ other library facilities not covered by this License, and distribute
+ such a combined library, provided that the separate distribution of the
+ work based on the Library and of the other library facilities is
+ otherwise permitted, and provided that you do these two things:</P>
+<OL TYPE="a">
+<LI>Accompany the combined library with a copy of the same work based on
+ the Library, uncombined with any other library facilities. This must be
+ distributed under the terms of the Sections above.
+<P></P>
+<LI>Give prominent notice with the combined library of the fact that
+ part of it is a work based on the Library, and explaining where to find
+ the accompanying uncombined form of the same work.</LI>
+</LI>
+</OL>
+<P><STRONG>8.</STRONG> You may not copy, modify, sublicense, link with,
+ or distribute the Library except as expressly provided under this
+ License. Any attempt otherwise to copy, modify, sublicense, link with,
+ or distribute the Library is void, and will automatically terminate
+ your rights under this License. However, parties who have received
+ copies, or rights, from you under this License will not have their
+ licenses terminated so long as such parties remain in full compliance.</P>
+<P><STRONG>9.</STRONG> You are not required to accept this License,
+ since you have not signed it. However, nothing else grants you
+ permission to modify or distribute the Library or its derivative works.
+ These actions are prohibited by law if you do not accept this License.
+ Therefore, by modifying or distributing the Library (or any work based
+ on the Library), you indicate your acceptance of this License to do so,
+ and all its terms and conditions for copying, distributing or modifying
+ the Library or works based on it.</P>
+<P><STRONG>10.</STRONG> Each time you redistribute the Library (or any
+ work based on the Library), the recipient automatically receives a
+ license from the original licensor to copy, distribute, link with or
+ modify the Library subject to these terms and conditions. You may not
+ impose any further restrictions on the recipients' exercise of the
+ rights granted herein. You are not responsible for enforcing compliance
+ by third parties to this License.</P>
+<P><STRONG>11.</STRONG> If, as a consequence of a court judgment or
+ allegation of patent infringement or for any other reason (not limited
+ to patent issues), conditions are imposed on you (whether by court
+ order, agreement or otherwise) that contradict the conditions of this
+ License, they do not excuse you from the conditions of this License. If
+ you cannot distribute so as to satisfy simultaneously your obligations
+ under this License and any other pertinent obligations, then as a
+ consequence you may not distribute the Library at all. For example, if
+ a patent license would not permit royalty-free redistribution of the
+ Library by all those who receive copies directly or indirectly through
+ you, then the only way you could satisfy both it and this License would
+ be to refrain entirely from distribution of the Library.</P>
+<P>If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply, and the section as a whole is intended to apply in other
+ circumstances.</P>
+<P>It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system which is implemented
+ by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.</P>
+<P>This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.</P>
+<P><STRONG>12.</STRONG> If the distribution and/or use of the Library is
+ restricted in certain countries either by patents or by copyrighted
+ interfaces, the original copyright holder who places the Library under
+ this License may add an explicit geographical distribution limitation
+ excluding those countries, so that distribution is permitted only in or
+ among countries not thus excluded. In such case, this License
+ incorporates the limitation as if written in the body of this License.</P>
+<P><STRONG>13.</STRONG> The Free Software Foundation may publish revised
+ and/or new versions of the Library General Public License from time to
+ time. Such new versions will be similar in spirit to the present
+ version, but may differ in detail to address new problems or concerns.</P>
+<P>Each version is given a distinguishing version number. If the Library
+ specifies a version number of this License which applies to it and &quot;any
+ later version&quot;, you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Library does not specify a license
+ version number, you may choose any version ever published by the Free
+ Software Foundation.</P>
+<P><STRONG>14.</STRONG> If you wish to incorporate parts of the Library
+ into other free programs whose distribution conditions are incompatible
+ with these, write to the author to ask for permission. For software
+ which is copyrighted by the Free Software Foundation, write to the Free
+ Software Foundation; we sometimes make exceptions for this. Our
+ decision will be guided by the two goals of preserving the free status
+ of all derivatives of our free software and of promoting the sharing
+ and reuse of software generally.</P>
+<P><STRONG>NO WARRANTY</STRONG></P>
+<P><STRONG>15.</STRONG> BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE,
+ THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY &quot;AS IS&quot; WITHOUT
+ WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
+ OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU
+ ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</P>
+<P><STRONG>16.</STRONG> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
+ AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO
+ MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.</P>
+<H4>END OF TERMS AND CONDITIONS</H4>
+</BODY>
+</HTML>
diff --git a/doc/fr/sum.pdf b/doc/fr/sum.pdf
new file mode 100644
index 000000000..c80557a3b
--- /dev/null
+++ b/doc/fr/sum.pdf
Binary files differ
diff --git a/doc/fr/sum.shtml b/doc/fr/sum.shtml
new file mode 100644
index 000000000..5f0fca630
--- /dev/null
+++ b/doc/fr/sum.shtml
@@ -0,0 +1,933 @@
+<HTML>
+<HEAD>
+ <META NAME="Description" CONTENT="Common UNIX Printing System Software Users Manual">
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-SUM-1.1.15">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Software Users Manual</TITLE>
+</HEAD>
+<BODY>
+
+<H1 ALIGN="RIGHT">Preface</H1>
+
+<P>This software users manual describes how to use the Common UNIX Printing
+System<SUP>TM</SUP> ("CUPS<SUP>TM</SUP>") Version 1.1.15.
+
+<EMBED SRC="system-overview.shtml">
+
+<!-- NEED 2in -->
+<H2>Document Overview</H2>
+
+<P>This software users manual is organized into the following sections:</P>
+
+<UL>
+ <LI><A HREF="#OVERVIEW">1 - Printing System Overview</A>
+ <LI><A HREF="#USING_SYSTEM">2 - Using the Printing System</A>
+ <LI><A HREF="#STANDARD_OPTIONS">3 - Standard Printer Options</A>
+ <LI><A HREF="#SAVING_OPTIONS">4 - Saving Printer Options and Defaults</A>
+ <LI><A HREF="#LICENSE">A - Software License Agreement</A>
+</UL>
+
+<H2>Notation Conventions</H2>
+
+<P>Various font and syntax conventions are used in this guide. Examples and
+their meanings and uses are explained below:
+
+<CENTER><TABLE WIDTH="80%">
+<TR>
+ <TH>Example</TH>
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+ <TH>Description</TH>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD><CODE>lpstat</CODE><BR>
+ <CODE>lpstat(1)</CODE></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>The names of commands; the first mention of a command or
+ function in a chapter is followed by a manual page section
+ number.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD><VAR>/var</VAR><BR>
+ <VAR>/usr/share/cups/data/testprint.ps</VAR></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>File and directory names.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD NOWRAP><TT>Request ID is Printer-123</TT></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Screen output.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD NOWRAP><KBD>lp -d printer filename ENTER</KBD></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Literal user input; special keys like <KBD>ENTER</B></KBD> are
+ in ALL CAPS.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD>12.3</TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Numbers in the text are written using the period (.) to indicate
+ the decimal point.</TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H2>Abbreviations</H2>
+
+The following abbreviations are used throughout this manual:
+
+<UL>
+<DL>
+
+ <DT>kb
+ <DD>Kilobytes, or 1024 bytes<BR>&nbsp;
+
+ <DT>Mb
+ <DD>Megabytes, or 1048576 bytes<BR>&nbsp;
+
+ <DT>Gb
+ <DD>Gigabytes, or 1073741824 bytes<BR>&nbsp;
+
+</DL>
+</UL>
+
+<H2>Other References</H2>
+
+<UL>
+<DL>
+
+ <DT>CUPS Software Administrators Manual
+
+ <DD>An administration guide for the CUPS software.<BR>&nbsp;
+
+ <DT>CUPS Software Programmers Manual
+
+ <DD>A programmer guide for interfacing with and/or extending the CUPS
+ software.<BR>&nbsp;
+
+</DL>
+</UL>
+
+
+<EMBED SRC="printing-overview.shtml">
+
+
+<H1 ALIGN="RIGHT"><A NAME="USING_SYSTEM">2 - Using the Printing System</A></H1>
+
+<P>This chapter shows you how to submit, query, and cancel print jobs to
+different printers.
+
+<H2>Submitting Files for Printing</H2>
+
+<P>CUPS provides both the System V (<CODE>lp(1)</CODE>) and Berkeley
+(<CODE>lpr(1)</CODE>) printing commands. Type the following command to
+print a file to the default (or only) printer on the system:
+
+<UL><PRE>
+<B>lp filename ENTER</B>
+</PRE></UL>
+
+<P>or:
+
+<UL><PRE>
+<B>lpr filename ENTER</B>
+</PRE></UL>
+
+<P>CUPS understands many different types of files directly, including
+PostScript and image files. This allows you to print from inside your
+applications or at the command-line, whichever is most convenient!
+
+<H2>Choosing a Printer</H2>
+
+<P>Many systems will have more than one printer available to the user. These
+printers can be attached to the local system via a parallel, serial, or USB
+port, or available over the network.
+
+<P>Use the <CODE>lpstat(1)</CODE> command to see a list of available printers:
+
+<UL><PRE>
+<B>lpstat -p -d ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>-p</CODE> option specifies that you want to see a list of
+printers, and the <CODE>-d</CODE> option reports the current system
+default printer or class.
+
+<P>Use the <CODE>-d</CODE> option with the <CODE>lp</CODE> command to
+print to a specific printer:
+
+<UL><PRE>
+<B>lp -d printer filename ENTER</B>
+</PRE></UL>
+
+<P>or the <CODE>-P</CODE> option with the <CODE>lpr</CODE> command:
+
+<UL><PRE>
+<B>lpr -P printer filename ENTER</B>
+</PRE></UL>
+
+<H2>Setting Printer Options</H2>
+
+<P>For many types of files, the default printer options may be sufficient for
+your needs. However, there may be times when you need to change the options
+for a particular file you are printing.
+
+<P>The <CODE>lp</CODE> and <CODE>lpr</CODE> commands allow you to pass
+printer options using the <CODE>-o</CODE> option:
+
+<UL><PRE>
+<B>lp -o landscape -o scaling=75 -o media=A4 filename.jpg
+<B>lpr -o landscape -o scaling=75 -o media=A4 filename.jpg
+</PRE></UL>
+
+<P>The available printer options vary depending on the printer. The standard
+options are described in <A HREF="#STANDARD_OPTIONS">Chapter 3, "Standard
+Printing Options"</A>.
+
+<H2>Printing Multiple Copies</H2>
+
+<P>Both the <CODE>lp</CODE> and <CODE>lpr</CODE> commands have options for
+printing more than one copy of a file:
+
+<UL><PRE>
+<B>lp -n <I>num-copies</I> filename ENTER</B>
+<B>lpr -#<I>num-copies</I> filename ENTER</B>
+</PRE></UL>
+
+<P>Copies are normally <I>not</I> collated for you. Use the <CODE>-o
+Collate=True</CODE> option to get collated copies :
+
+<UL><PRE>
+<B>lp -n <I>num-copies</I> -o Collate=True filename ENTER</B>
+<B>lpr -#<I>num-copies</I> -o Collate=True filename ENTER</B>
+</PRE></UL>
+
+<!-- NEED 3in -->
+<H2>Checking the Printer Status from the Command-Line</H2>
+
+<P>The <CODE>lpstat</CODE> command can be used to check for jobs that you
+have submitted for printing:
+
+<UL><PRE>
+<B>lpstat ENTER</B>
+Printer-1 johndoe 4427776
+Printer-2 johndoe 15786
+Printer-3 johndoe 372842
+</PRE></UL>
+
+<P>The jobs are listed in the order they will be printed. Use the
+<CODE>-p</CODE> option to see which files and printers are active:
+
+<UL><PRE>
+<B>lpstat -p ENTER</B>
+printer DeskJet now printing DeskJet-1.
+</PRE></UL>
+
+<!-- NEED 2in -->
+<P>Use the <CODE>-o</CODE> and <CODE>-p</CODE> options together to show
+the jobs and the printers:
+
+<UL><PRE>
+<B>lpstat -o -p ENTER</B>
+Printer-1 johndoe 4427776
+Printer-2 johndoe 15786
+Printer-3 johndoe 372842
+printer DeskJet now printing DeskJet-1.
+</PRE></UL>
+
+<H2>Checking the Printer Status from the Web</H2>
+
+<P>Since CUPS uses the Internet Printing Protocol, it is also a
+fully-functional web server. To use your web browser to monitor the
+printers on your system, open the URL:
+
+<UL><PRE>
+<A HREF="http://localhost:631">http://localhost:631</A>
+</PRE></UL>
+
+<P>From there you can view the status of classes, jobs, and printers
+with the click of a button!
+
+<H2>Canceling a Print Job</H2>
+
+<P>The <CODE>cancel(1)</CODE> and <CODE>lprm(1)</CODE> commands cancel
+a print job:
+
+<UL><PRE>
+<B>cancel <I>job-id</I> ENTER</B>
+<B>lprm <I>job-id</I> ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>job-id</CODE> is the number that was reported to you by
+the <CODE>lp</CODE> or <CODE>lpstat</CODE> commands.
+
+
+<H1 ALIGN="RIGHT"><A NAME="STANDARD_OPTIONS">3 - Standard Printer Options</A></H1>
+
+<P>This chapter describes the standard printer options that are available
+when printing with the <CODE>lp</CODE> and <CODE>lpr</CODE> commands.
+
+<H2>General Options</H2>
+
+<P>The following options apply when printing all types of files.
+
+<!-- NEED 2in -->
+<H3>Selecting the Media Size, Type, and Source</H3>
+
+<P>The <CODE>-o media=xyz</CODE> option sets the media size, type,
+and/or source:
+
+<UL><PRE>
+<B>lp -o media=Letter filename ENTER</B>
+<B>lp -o media=Letter,MultiPurpose filename ENTER</B>
+<B>lpr -o media=Letter,Transparency filename ENTER</B>
+<B>lpr -o media=Letter,MultiPurpose,Transparency filename ENTER</B>
+</PRE></UL>
+
+<!-- NEED 3in -->
+<P>The available media sizes, types, and sources depend on the printer, but
+most support the following options (case is not significant):
+
+<UL>
+
+ <LI><CODE>Letter</CODE> - US Letter (8.5x11 inches, or 216x279mm)
+
+ <LI><CODE>Legal</CODE> - US Legal (8.5x14 inches, or 216x356mm)
+
+ <LI><CODE>A4</CODE> - ISO A4 (8.27x11.69 inches, or 210x297mm)
+
+ <LI><CODE>COM10</CODE> - US #10 Envelope (9.5x4.125 inches, or
+ 241x105mm)
+
+ <LI><CODE>DL</CODE> - ISO DL Envelope (8.66x4.33 inches, or 220x110mm)
+
+ <LI><CODE>Transparency</CODE> - Transparency media type or source
+
+ <LI><CODE>Upper</CODE> - Upper paper tray
+
+ <LI><CODE>Lower</CODE> - Lower paper tray
+
+ <LI><CODE>MultiPurpose</CODE> - Multi-purpose paper tray
+
+ <LI><CODE>LargeCapacity</CODE> - Large capacity paper tray
+
+</UL>
+
+<P>The actual options supported are defined in the printer's PPD file
+in the <CODE>PageSize</CODE>, <CODE>InputSlot</CODE>, and
+<CODE>MediaType</CODE> options.
+
+<H3>Setting the Orientation</H3>
+
+<P>The <CODE>-o landscape</CODE> option will rotate the page 90 degrees
+to print in landscape orientation:
+
+<UL><PRE>
+<B>lp -o landscape filename ENTER</B>
+<B>lpr -o landscape filename ENTER</B>
+</PRE></UL>
+
+<H3>Printing On Both Sides of the Paper</H3>
+
+<P>The <CODE>-o sides=two-sided-short-edge</CODE> and <CODE>-o
+sides=two-sided-long-edge</CODE> options will enable duplexing on the
+printer, if the printer supports it. The <CODE>-o
+sides=two-sided-short-edge</CODE> option is suitable for landscape
+pages, while the <CODE>-o sides=two-sided-long-edge</CODE> option is
+suitable for portrait pages:
+
+<UL><PRE>
+<B>lp -o sides=two-sided-short-edge filename ENTER</B>
+<B>lp -o sides=two-sided-long-edge filename ENTER</B>
+<B>lpr -o sides=two-sided-long-edge filename ENTER</B>
+</PRE></UL>
+
+<P>The default is to print single-sided:
+
+<UL><PRE>
+<B>lp -o sides=one-sided filename ENTER</B>
+<B>lpr -o sides=one-sided filename ENTER</B>
+</PRE></UL>
+
+<H2>Banner Options</H2>
+
+<P>The following options apply when printing all types of files.
+
+<H3>Selecting the Banner Page(s)</H3>
+
+<P>The <CODE>-o jobsheets=start,end</CODE> option sets the banner page(s) to
+use for a job:
+
+<UL><PRE>
+<B>lp -o job-sheets=none filename ENTER</B>
+<B>lp -o job-sheets=standard filename ENTER</B>
+<B>lpr -o job-sheets=classified,classified filename ENTER</B>
+</PRE></UL>
+
+<P>If only one banner file is specified, it will be printed before the
+files in the job. If a second banner file is specified, it is printed after
+the files in the job.
+
+<P>The available banner pages depend on the local system configuration; CUPS
+includes the following banner files:
+
+<UL>
+
+ <LI><CODE>none</CODE> - Do not produce a banner page.
+
+ <LI><CODE>classified</CODE> - A banner page with a "classified"
+ label at the top and bottom.
+
+ <LI><CODE>confidential</CODE> - A banner page with a
+ "confidential" label at the top and bottom.
+
+ <LI><CODE>secret</CODE> - A banner page with a "secret" label
+ at the top and bottom.
+
+ <LI><CODE>standard</CODE> - A banner page with no label at the
+ top and bottom.
+
+ <LI><CODE>topsecret</CODE> - A banner page with a "top secret"
+ label at the top and bottom.
+
+ <LI><CODE>unclassified</CODE> - A banner page with an
+ "unclassified" label at the top and bottom.
+
+</UL>
+
+<H2>Document Options</H2>
+
+<P>The following options apply when printing all types of files.
+
+<H3>Selecting a Range of Pages</H3>
+
+<P>The <CODE>-o page-ranges=pages</CODE> option selects a range of
+pages for printing:
+
+<UL><PRE>
+<B>lp -o page-ranges=1 filename ENTER</B>
+<B>lp -o page-ranges=1-4 filename ENTER</B>
+<B>lp -o page-ranges=1-4,7,9-12 filename ENTER</B>
+<B>lpr -o page-ranges=1-4,7,9-12 filename ENTER</B>
+</PRE></UL>
+
+<P>As shown above, the <CODE>pages</CODE> value can be a single page, a
+range of pages, or a collection of page numbers and ranges separated by
+commas. The pages will always be printed in ascending order, regardless
+of the order of the pages in the <CODE>page-ranges</CODE> option.
+
+<P>The default is to print all pages.
+
+<H3>Selecting Even or Odd Pages</H3>
+
+<P>Use the <CODE>-o page-set=set</CODE> option to select the even or odd pages:
+
+<UL><PRE>
+<B>lp -o page-set=odd filename ENTER</B>
+<B>lp -o page-set=even filename ENTER</B>
+<B>lpr -o page-set=even filename ENTER</B>
+</PRE></UL>
+
+<P>The default is to print all pages.
+
+<H3>N-Up Printing</H3>
+
+<P>The <CODE>-o number-up=value</CODE> option selects N-Up printing.
+N-Up printing places multiple document pages on a single printed page.
+CUPS supports 1, 2, 4, 6, 9, and 16-Up formats; the default format is
+1-Up:
+
+<UL><PRE>
+<B>lp -o number-up=1 filename ENTER</B>
+<B>lp -o number-up=2 filename ENTER</B>
+<B>lp -o number-up=4 filename ENTER</B>
+<B>lpr -o number-up=16 filename ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>-o page-border=value</CODE> option chooses the border
+to draw around each page:
+
+<UL>
+ <LI><CODE>-o page-border=double</CODE>; draw two hairline borders around each page</LI>
+ <LI><CODE>-o page-border=double-thick</CODE>; draw two 1pt borders around each page</LI>
+ <LI><CODE>-o page-border=none</CODE>; do not draw a border (default)</LI>
+ <LI><CODE>-o page-border=single</CODE>; draw one hairline border around each page</LI>
+ <LI><CODE>-o page-border=single-thick</CODE>; draw one 1pt border around each page</LI>
+</UL>
+
+<P>The <CODE>-o number-up-layout=value</CODE> option chooses the layout
+of the pages on each output page:
+
+<UL>
+ <LI><CODE>-o number-up-layout=btlr</CODE>; Bottom to top, left to right</LI>
+ <LI><CODE>-o number-up-layout=btrl</CODE>; Bottom to top, right to left</LI>
+ <LI><CODE>-o number-up-layout=lrbt</CODE>; Left to right, bottom to top</LI>
+ <LI><CODE>-o number-up-layout=lrtb</CODE>; Left to right, top to bottom (default)</LI>
+ <LI><CODE>-o number-up-layout=rlbt</CODE>; Right to left, bottom to top</LI>
+ <LI><CODE>-o number-up-layout=rltb</CODE>; Right to left, top to bottom</LI>
+ <LI><CODE>-o number-up-layout=tblr</CODE>; Top to bottom, left to right</LI>
+ <LI><CODE>-o number-up-layout=tbrl</CODE>; Top to bottom, right to left</LI>
+</UL>
+
+<H3>Setting the Brightness</H3>
+
+<P>You can control the overall brightness of the printed output using the
+<CODE>-o brightness=percent</CODE> option:
+
+<UL><PRE>
+<B>lp -o brightness=120 filename ENTER</B>
+<B>lpr -o brightness=120 filename ENTER</B>
+</PRE></UL>
+
+<P>Values greater than 100 will lighten the print, while values less than
+100 will darken it.
+
+<H3>Setting the Gamma Correction</H3>
+
+<P>You can control the overall gamma correction of the printed output
+using the <CODE>-o gamma=value</CODE> option:
+
+<UL><PRE>
+<B>lp -o gamma=1700 filename ENTER</B>
+<B>lpr -o gamma=1700 filename ENTER</B>
+</PRE></UL>
+
+<P>Values greater than 1000 will lighten the print, while values less
+than 1000 will darken it. The default gamma is 1000.
+
+<H2>Text Options</H2>
+
+<P>The following options apply when printing text files.
+
+<H3>Setting the Number of Characters Per Inch</H3>
+
+<P>The <CODE>-o cpi=value</CODE> option sets the number of characters per inch:
+
+<UL><PRE>
+<B>lp -o cpi=10 filename ENTER</B>
+<B>lp -o cpi=12 filename ENTER</B>
+<B>lpr -o cpi=17 filename ENTER</B>
+</PRE></UL>
+
+<P>The default characters per inch is 10.
+
+<H3>Setting the Number of Lines Per Inch</H3>
+
+<P>The <CODE>-o lpi=value</CODE> option sets the number of lines per inch:
+
+<UL><PRE>
+<B>lp -o lpi=6 filename ENTER</B>
+<B>lpr -o lpi=8 filename ENTER</B>
+</PRE></UL>
+
+<P>The default lines per inch is 6.
+
+<H3>Setting the Number of Columns</H3>
+
+<P>The <CODE>-o columns=value</CODE> option sets the number of text columns:
+
+<UL><PRE>
+<B>lp -o columns=2 filename ENTER</B>
+<B>lpr -o columns=3 filename ENTER</B>
+</PRE></UL>
+
+<P>The default number of columns is 1.
+
+<H3>Setting the Page Margins</H3>
+
+<P>Normally the page margins are set to the hard limits of the printer.
+Use the <CODE>-o page-left=value</CODE>, <CODE>-o
+page-right=value</CODE>, <CODE>-o page-top=value</CODE>, and <CODE>-o
+page-bottom=value</CODE> options to adjust the page margins:
+
+<UL><PRE>
+<B>lp -o page-left=<I>value</I> filename ENTER</B>
+<B>lp -o page-right=<I>value</I> filename ENTER</B>
+<B>lp -o page-top=<I>value</I> filename ENTER</B>
+<B>lp -o page-bottom=<I>value</I> filename ENTER</B>
+<B>lpr -o page-bottom=<I>value</I> filename ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>value</CODE> argument is the margin in points; each point is 1/72 inch
+or 0.35mm.
+
+<H3>Pretty Printing</H3>
+
+<P>The <CODE>-o prettyprint</CODE> option puts a header at the top of each page with the
+page number, job title (usually the filename), and the date. Also, C and C++
+keywords are highlighted, and comment lines are italicized:
+
+<UL><PRE>
+<B>lp -o prettyprint filename ENTER</B>
+<B>lpr -o prettyprint filename ENTER</B>
+</PRE></UL>
+
+<H2>Image Options</H2>
+
+<P>The following options apply when printing image files.
+
+<H3>Positioning the Image</H3>
+
+<P>The <CODE>-o position=name</CODE> option specifies the position of the
+image on the page:
+
+<UL>
+
+ <LI><CODE>center</CODE> - Center the image on the page (default)
+
+ <LI><CODE>top</CODE> - Print the image centered at the top of the page
+
+ <LI><CODE>left</CODE> - Print the image centered on the left of page
+
+ <LI><CODE>right</CODE> - Print the image centered on the right of the page
+
+ <LI><CODE>top-left</CODE> - Print the image at the top left corner of
+ the page
+
+ <LI><CODE>top-right</CODE> - Print the image at the top right corner of
+ the page
+
+ <LI><CODE>bottom</CODE> - Print the image centered at the bottom of
+ the page
+
+ <LI><CODE>bottom-left</CODE> - Print the image at the bottom left
+ corner of the page
+
+ <LI><CODE>bottom-right</CODE> - Print the image at the bottom right
+ corner of the page
+
+</UL>
+
+<H3>Scaling the Image</H3>
+
+<P>The <CODE>-o scaling=percent</CODE>, <CODE>-o
+ppi=value</CODE>, and <CODE>-o natural-scaling=percent</CODE>
+options change the size of a printed image:
+
+<UL><PRE>
+<B>lp -o scaling=<I>percent</I> filename ENTER</B>
+<B>lp -o ppi=<I>value</I> filename ENTER</B>
+<B>lpr -o natural-scaling=<I>percent</I> filename ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>scaling=percent</CODE> value is a number from 1 to 800
+specifying the size in relation to the page (<I>not</I> the image.) A
+scaling of 100 percent will fill the page as completely as the image
+aspect ratio allows. A scaling of 200 percent will print on up to 4
+pages.
+
+<P>The <CODE>ppi=value</CODE> value is a number from 1 to 1200 specifying the
+resolution of the image in pixels per inch. An image that is 3000x2400
+pixels will print 10x8 inches at 300 pixels per inch, for example. If
+the specified resolution makes the image larger than the page, multiple
+pages will be printed to satisfy the request.
+
+<P>The <CODE>natural-scaling=percent</CODE> value is a number
+from 1 to 800 specifying the size in relation to the natural
+image size. A scaling of 100 percent will print the image at its
+natural size, while a scaling of 50 percent will print the image
+at half its natural size. If the specified scaling makes the
+image larger than the page, multiple pages will be printed to
+satisfy the request.
+
+<H3>Adjusting the Hue (Tint) of an Image</H3>
+
+<P>The <CODE>-o hue=value</CODE> option will adjust the hue of the
+printed image, much like the tint control on your television:
+
+<UL><PRE>
+<B>lp -o hue=<I>value</I> filename ENTER</B>
+<B>lpr -o hue=<I>value</I> filename ENTER</B>
+</PRE></UL>
+
+<!-- NEED 3in -->
+<P>The <CODE>value</CODE> argument is a number from -360 to 360 and represents the
+color hue rotation. The following table summarizes the change you'll see with
+different colors:
+
+<CENTER><TABLE WIDTH="50%" BORDER="1">
+<TR>
+ <TH>Original</TH>
+ <TH>hue=-45</TH>
+ <TH>hue=45</TH>
+</TR>
+<TR>
+ <TD>Red</TD>
+ <TD>Purple</TD>
+ <TD>Yellow-orange</TD>
+</TR>
+<TR>
+ <TD>Green</TD>
+ <TD>Yellow-green</TD>
+ <TD>Blue-green</TD>
+</TR>
+<TR>
+ <TD>Yellow</TD>
+ <TD>Orange</TD>
+ <TD>Green-yellow</TD>
+</TR>
+<TR>
+ <TD>Blue</TD>
+ <TD>Sky-blue</TD>
+ <TD>Purple</TD>
+</TR>
+<TR>
+ <TD>Magenta</TD>
+ <TD>Indigo</TD>
+ <TD>Crimson</TD>
+</TR>
+<TR>
+ <TD>Cyan</TD>
+ <TD>Blue-green</TD>
+ <TD>Light-navy-blue</TD>
+</TR>
+</TABLE></CENTER>
+
+<P>The default hue adjustment is 0.
+
+<H3>Adjusting the Saturation (Color) of an Image</H3>
+
+<P>The <CODE>-o saturation=percent</CODE> option adjusts the saturation
+of the colors in an image, much like the color knob on your television:
+
+<UL><PRE>
+<B>lp -o saturation=<I>percent</I> filename ENTER</B>
+<B>lpr -o saturation=<I>percent</I> filename ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>percent</CODE> argument specifies the color saturation
+from 0 to 200. A color saturation of 0 produces a black-and-white
+print, while a value of 200 will make the colors extremely intense.
+
+<P>The default saturation is 100.
+
+<!-- NEED 4in -->
+<H2>HP-GL/2 Options</H2>
+
+<P>The following options apply to HP-GL/2 files.
+
+<H3>Printing in Black</H3>
+
+<P>The <CODE>-o blackplot</CODE> option specifies that all pens should
+plot in black:
+
+<UL><PRE>
+<B>lp -o blackplot filename ENTER</B>
+<B>lpr -o blackplot filename ENTER</B>
+</PRE></UL>
+
+<P>The default is to use the colors defined in the plot file or the
+standard pen colors defined in the HP-GL/2 reference manual from
+Hewlett Packard.
+
+<H3>Fitting the Plot on the Page</H3>
+
+<P>The <CODE>-o fitplot</CODE> option specifies that the plot should be
+scaled to fit on the page:
+
+<UL><PRE>
+<B>lp -o fitplot filename ENTER</B>
+<B>lpr -o fitplot filename ENTER</B>
+</PRE></UL>
+
+<P>The default is to use the absolute distances specified in the plot
+file.
+
+<CENTER><TABLE WIDTH="80%" CELLPADDING="5" BORDER="1" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>This feature depends upon an accurate plot size (<CODE>PS</CODE>)
+ command in the HP-GL/2 file. If no plot size is given in the file
+ than the HP-GL/2 filter assumes the plot is ANSI E size.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Setting the Default Pen Width</H3>
+
+<P>The <CODE>-o penwidth=value</CODE> option specifies the default pen
+width for HP-GL/2 files:
+
+<UL><PRE>
+<B>lp -o penwidth=<I>value</I> filename ENTER</B>
+<B>lpr -o penwidth=<I>value</I> filename ENTER</B>
+</PRE></UL>
+
+<P>The pen width <CODE>value</CODE> specifies the pen width in micrometers.
+The default value of 1000 produces lines that are 1 millimeter in width.
+Specifying a pen width of 0 produces lines that are exactly 1 pixel wide.
+
+<CENTER><TABLE WIDTH="80%" CELLPADDING="5" BORDER="1" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>This option is ignored when the pen widths are set in the
+ plot file.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H2>Raw or Unfiltered Output</H2>
+
+<P>The <CODE>-o raw</CODE> option allows you to send files directly to
+a printer without filtering. This is sometimes required when printing
+from applications that provide their own "printer drivers" for your
+printer:
+
+<UL><PRE>
+<B>lp -o raw filename ENTER</B>
+<B>lpr -o raw filename ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>-l</CODE> option can also be used with the
+<CODE>lpr</CODE> command to send files directly to a printer:
+
+<UL><PRE>
+<B>lpr -l filename ENTER</B>
+</PRE></UL>
+
+
+<H1 ALIGN="RIGHT"><A NAME="SAVING_OPTIONS">4 - Saving Printer Options and Defaults</A></H1>
+
+<P>This chapter describes how to save printer options for your printer and
+set your own default printer.
+
+<H2>Printer Options</H2>
+
+<P>Each printer supports a large number of options, which you learned about
+in <A HREF="#STANDARD_OPTIONS">Chapter 3, "Standard Printer Options"</A>.
+Rather than specifying these options each time you print a file, CUPS allows
+you to save them as "default" options for the printer.
+
+<P>The <CODE>lpoptions(1)</CODE> command saves the options for your printers.
+Like the <CODE>lp</CODE> and <CODE>lpr</CODE> commands, it accepts printer
+options using the <CODE>-o</CODE> argument:
+
+<UL><PRE>
+<B>lpoptions -o prettyprint ENTER</B>
+<B>lpoptions -o media=A4 -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -o media=Legal -o scaling=100 ENTER</B>
+</PRE></UL>
+
+<P>Once saved, any <CODE>lp</CODE> or <CODE>lpr</CODE> command will
+use them when you print.
+
+<H2>Setting Options for a Specific Printer</H2>
+
+<P>The previous example shows how to set the options for the default
+printer. The <CODE>-p printer</CODE> option specifies the options are
+for another printer:
+
+<UL><PRE>
+<B>lpoptions -p laserjet -o prettyprint ENTER</B>
+<B>lpoptions -p laserjet -o media=A4 -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -p deskjet -o media=Legal -o scaling=100 ENTER</B>
+</PRE></UL>
+
+<H2>Removing Options</H2>
+
+<P>The previous two examples shows how to set options for the default
+and a specific printer. Below, shows you how to remove the saved
+option using the <CODE>-r</CODE> argument:
+
+<UL><PRE>
+<KBD>lpoptions -r prettyprint <I>ENTER</I></KBD>
+<KBD>lpoptions -p laserjet -r prettyprint <I>ENTER</I></KBD>
+</PRE></UL>
+
+<H2>Viewing the Current Defaults</H2>
+
+<P>The <CODE>lpoptions</CODE> command can also be used to show the current
+options by not specifying any new options on the command-line:
+
+<UL><PRE>
+<B>lpoptions ENTER</B>
+media=A4 sides=two-sided-long-edge
+<B>lpoptions -p deskjet ENTER</B>
+media=Legal scaling=100
+</PRE></UL>
+
+<H2>Viewing Options for a Specific Printer</H2>
+
+<P>You can display the supported options using the <CODE>lpoptions</CODE>
+command with the <CODE>-l</CODE> option, as follows:
+
+<UL><PRE>
+<B>lpoptions -p laserjet -l ENTER</B>
+</UL></PRE>
+
+<H2>Setting the Default Printer</H2>
+
+<P>The administrator normally will set a system-wide default printer
+that is normally used as the default printer by everyone. Use the
+<CODE>-d printer</CODE> option to set your own default printer:
+
+<UL><PRE>
+<B>lpoptions -d deskjet ENTER</B>
+</PRE></UL>
+
+<P>The printer can be local (<CODE>deskjet</CODE>) or remote
+(<CODE>deskjet@server</CODE>).
+
+<H2>Printer Instances</H2>
+
+<P>Besides setting options for each print queue, CUPS supports
+<I>printer instances</I> which allow you to define several different
+sets of options for each printer. You specify a printer instance using
+the slash (<CODE>/</CODE>) character:
+
+<UL><PRE>
+<B>lpoptions -p laserjet/duplex -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -p laserjet/legal -o media=Legal ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>lp</CODE> and </CODE>lpr</CODE> commands also understand
+this notation:
+
+<UL><PRE>
+<B>lp -d laserjet/duplex filename ENTER</B>
+<B>lpr -P laserjet/legal filename ENTER</B>
+</PRE></UL>
+
+<H2>Removing Instances</H2>
+
+<P>Use the <CODE>-x printer/instance</CODE> option to remove a printer
+instance that you no longer need:
+
+<UL><PRE>
+<B>lpoptions -x laserjet ENTER</B>
+<B>lpoptions -x laserjet/duplex ENTER</B>
+<B>lpoptions -x laserjet/legal ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>-x</CODE> option only removes the default options for that
+printer and instance; the original print queue will remain until deleted
+with the <CODE>lpadmin(8)</CODE> command by the administrator.
+
+
+<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - Software License
+Agreement</A></H1>
+
+<EMBED SRC="../LICENSE.html">
+
+</BODY>
+</HTML>
diff --git a/doc/fr/system-overview.shtml b/doc/fr/system-overview.shtml
new file mode 100644
index 000000000..54b7df5e9
--- /dev/null
+++ b/doc/fr/system-overview.shtml
@@ -0,0 +1,19 @@
+<H2>System Overview</H2>
+
+<P>CUPS provides a portable printing layer for UNIX&reg;-based
+operating systems. It has been developed by
+<A HREF="http://www.easysw.com">Easy Software Products</A> to promote a
+standard printing solution for all UNIX vendors and users. CUPS
+provides the System V and Berkeley command-line interfaces.
+
+<P>CUPS uses the Internet Printing Protocol ("IPP") as the basis for
+managing print jobs and queues. The Line Printer Daemon ("LPD") Server
+Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are
+also supported with reduced functionality. CUPS adds network printer
+browsing and PostScript Printer Description ("PPD") based
+printing options to support real-world printing under UNIX.
+
+<P>CUPS also includes a customized version of GNU Ghostscript
+(currently based off GNU Ghostscript 5.50) and an image file RIP that
+are used to support non-PostScript printers. Sample drivers for HP and
+EPSON printers are included that use these filters.
diff --git a/doc/glossary.shtml b/doc/glossary.shtml
new file mode 100644
index 000000000..2cc0c1c89
--- /dev/null
+++ b/doc/glossary.shtml
@@ -0,0 +1,73 @@
+<H1 TYPE="A" VALUE="1">Glossary</H1>
+
+<H2>Terms</H2>
+
+<DL>
+
+ <DT>C
+ <DD>A computer language.
+
+ <DT>parallel
+ <DD>Sending or receiving data more than 1 bit at a time.
+
+ <DT>pipe
+ <DD>A one-way communications channel between two programs.
+
+ <DT>serial
+ <DD>Sending or receiving data 1 bit at a time.
+
+ <DT>socket
+ <DD>A two-way network communications channel.
+
+</DL>
+
+<H2>Acronyms</H2>
+
+<DL>
+
+ <DT>ASCII
+ <DD>American Standard Code for Information Interchange
+
+ <DT>CUPS
+ <DD>Common UNIX Printing System
+
+ <DT>ESC/P
+ <DD>EPSON Standard Code for Printers
+
+ <DT>FTP
+ <DD>File Transfer Protocol
+
+ <DT>HP-GL
+ <DD>Hewlett-Packard Graphics Language
+
+ <DT>HP-PCL
+ <DD>Hewlett-Packard Page Control Language
+
+ <DT>HP-PJL
+ <DD>Hewlett-Packard Printer Job Language
+
+ <DT>IETF
+ <DD>Internet Engineering Task Force
+
+ <DT>IPP
+ <DD>Internet Printing Protocol
+
+ <DT>ISO
+ <DD>International Standards Organization
+
+ <DT>LPD
+ <DD>Line Printer Daemon
+
+ <DT>MIME
+ <DD>Multimedia Internet Mail Exchange
+
+ <DT>PPD
+ <DD>PostScript Printer Description
+
+ <DT>SMB
+ <DD>Server Message Block
+
+ <DT>TFTP
+ <DD>Trivial File Transfer Protocol
+
+</DL>
diff --git a/doc/idd.html b/doc/idd.html
new file mode 100644
index 000000000..9650025e4
--- /dev/null
+++ b/doc/idd.html
@@ -0,0 +1,1083 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Interface Design Description</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-IDD-1.1">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY>
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Interface Design Description</H1></A><BR>
+CUPS-IDD-1.1<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">1 Scope</A></B>
+<UL>
+<LI><A HREF="#1_1">1.1 Identification</A></LI>
+<LI><A HREF="#1_2">1.2 System Overview</A></LI>
+<LI><A HREF="#1_3">1.3 Document Overview</A></LI>
+</UL>
+<B><A HREF="#2">2 References</A></B>
+<UL>
+<LI><A HREF="#2_1">2.1 CUPS Documentation</A></LI>
+<LI><A HREF="#2_2">2.2 Other Documents</A></LI>
+</UL>
+<B><A HREF="#3">3 Internal Interfaces</A></B>
+<UL>
+<LI><A HREF="#3_1">3.1 Character Set Files</A></LI>
+<UL>
+<LI><A HREF="#3_1_1">3.1.1 8-Bit Character Set Files</A></LI>
+<LI><A HREF="#3_1_2">3.1.2 Unicode Character Set Files</A></LI>
+</UL>
+<LI><A HREF="#3_2">3.2 Language Files</A></LI>
+<LI><A HREF="#3_3">3.3 MIME Files</A></LI>
+<UL>
+<LI><A HREF="#3_3_1">3.3.1 mime.types</A></LI>
+<LI><A HREF="#3_3_2">3.3.2 mime.convs</A></LI>
+</UL>
+<LI><A HREF="#3_4">3.4 Option Files</A></LI>
+<LI><A HREF="#3_5">3.5 PostScript Printer Description Files</A></LI>
+<UL>
+<LI><A HREF="#3_5_1">3.5.1 PPD Specification</A></LI>
+<LI><A HREF="#3_5_2">3.5.2 CUPS Extensions to PPD Files</A></LI>
+</UL>
+<LI><A HREF="#3_6">3.6 Scheduler Configuration Files</A></LI>
+<UL>
+<LI><A HREF="#3_6_1">3.6.1 classes.conf</A></LI>
+<LI><A HREF="#3_6_2">3.6.2 cupsd.conf</A></LI>
+<LI><A HREF="#3_6_3">3.6.3 printers.conf</A></LI>
+</UL>
+</UL>
+<B><A HREF="#4">4 External Interfaces</A></B>
+<UL>
+<LI><A HREF="#4_1">4.1 AppSocket Protocol</A></LI>
+<LI><A HREF="#4_2">4.2 CUPS Browsing Protocol</A></LI>
+<LI><A HREF="#4_3">4.3 CUPS Form File</A></LI>
+<UL>
+<LI><A HREF="#4_3_1">4.3.1 CUPS Form DTD</A></LI>
+</UL>
+<LI><A HREF="#4_4">4.4 CUPS PostScript File</A></LI>
+<LI><A HREF="#4_5">4.5 CUPS Raster File</A></LI>
+<LI><A HREF="#4_6">4.6 CUPS Raw Files</A></LI>
+<LI><A HREF="#4_7">4.7 Internet Printing Protocol</A></LI>
+<LI><A HREF="#4_8">4.8 Line Printer Daemon Protocol</A></LI>
+<LI><A HREF="#4_9">4.9 Server Message Block Protocol</A></LI>
+</UL>
+<B><A HREF="#5">5 Directories</A></B>
+<BR>
+<BR><B><A HREF="#6">A Glossary</A></B>
+<UL>
+<LI><A HREF="#6_1">A.1 Terms</A></LI>
+<LI><A HREF="#6_2">A.2 Acronyms</A></LI>
+</UL>
+<HR>
+<H1><A NAME="1">1 Scope</A></H1>
+<H2><A NAME="1_1">1.1 Identification</A></H2>
+<P>This interface design description document provides detailed file
+ formats, message formats, and program conventions for the Common UNIX
+ Printing System (&quot;CUPS&quot;) Version 1.1.</P>
+<H2><A NAME="1_2">1.2 System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+<H2><A NAME="1_3">1.3 Document Overview</A></H2>
+<P>This interface design description document is organized into the
+ following sections:</P>
+<UL>
+<LI>1 - Scope</LI>
+<LI>2 - References</LI>
+<LI>3 - Internal Interfaces</LI>
+<LI>4 - External Interfaces</LI>
+<LI>5 - Directories</LI>
+<LI>A - Glossary</LI>
+</UL>
+<H1><A NAME="2">2 References</A></H1>
+<H2><A NAME="2_1">2.1 CUPS Documentation</A></H2>
+<P>The following CUPS documentation is referenced by this document:</P>
+<UL>
+<LI>CUPS-CMP-1.1: CUPS Configuration Management Plan</LI>
+<LI>CUPS-IDD-1.1: CUPS System Interface Design Description</LI>
+<LI>CUPS-IPP-1.1: CUPS Implementation of IPP</LI>
+<LI>CUPS-SAM-1.1.x: CUPS Software Administrators Manual</LI>
+<LI>CUPS-SDD-1.1: CUPS Software Design Description</LI>
+<LI>CUPS-SPM-1.1.x: CUPS Software Programming Manual</LI>
+<LI>CUPS-SSR-1.1: CUPS Software Security Report</LI>
+<LI>CUPS-STP-1.1: CUPS Software Test Plan</LI>
+<LI>CUPS-SUM-1.1.x: CUPS Software Users Manual</LI>
+<LI>CUPS-SVD-1.1: CUPS Software Version Description</LI>
+</UL>
+<H2><A NAME="2_2">2.2 Other Documents</A></H2>
+<P>The following non-CUPS documents are referenced by this document:</P>
+<UL>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">
+Adobe PostScript Printer Description File Format Specification, Version
+ 4.3.</A></LI>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
+Adobe PostScript Language Reference, Third Edition.</A></LI>
+<LI>IPP: Job and Printer Set Operations</LI>
+<LI>IPP/1.1: Encoding and Transport</LI>
+<LI>IPP/1.1: Implementers Guide</LI>
+<LI>IPP/1.1: Model and Semantics</LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179, Line Printer
+ Daemon Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2567.txt">RFC 2567, Design Goals
+ for an Internet Printing Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2568.txt">RFC 2568, Rationale
+ for the Structure of the Model and Protocol for the Internet Printing
+ Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2569.txt">RFC 2569, Mapping
+ between LPD and IPP Protocols</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616, Hypertext
+ Transfer Protocol -- HTTP/1.1</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617, HTTP
+ Authentication: Basic and Digest Access</A> Authentication</LI>
+</UL>
+<H1><A NAME="3">3 Internal Interfaces</A></H1>
+<H2><A NAME="3_1">3.1 Character Set Files</A></H2>
+<P>The character set files define a mapping between 8-bit characters and
+ the Unicode character set, or between Unicode and printer fonts. They
+ are named using the IETF charset names defined in RFCnnnn. These files
+ are ASCII text, the content of which is described below. Comments can
+ be included by using the <TT>#</TT> character in the first column of a
+ line.</P>
+<H3><A NAME="3_1_1">3.1.1 8-Bit Character Set Files</A></H3>
+<P>8-bit character set files start with a line reading:</P>
+<UL>
+<PRE>
+charset 8bit
+</PRE>
+</UL>
+<P>Following this are lines that define the font information:</P>
+<UL>
+<PRE>
+first last direction width normal bold italic bold-italic
+</PRE>
+</UL>
+<P><VAR>First</VAR> and<VAR> last</VAR> are the first and last glyphs in
+ the font mapping that correspond to that font; a maximum of 256
+ characters can be mapped within each group, with a maximum of 256
+ mappings (this is a PostScript limitation.) The glyph values are
+ hexadecimal.</P>
+<P><VAR>Direction</VAR> is the string &quot;ltor&quot;, &quot;rtol&quot;, or &quot;rtola&quot;
+ indicating left-to-right, right-to-left, or right-to-left Arabic text.</P>
+<P><VAR>Width</VAR> is the string &quot;single&quot; or &quot;double&quot;; double means
+ that the glyphs are twice as wide as ASCII characters in the Courier
+ typeface.</P>
+<P><VAR>Normal, bold, italic</VAR>, and<VAR> bold-italic</VAR> are the
+ typefaces to use for each presentation. If characters are only
+ available in a single style then only one typeface should be listed
+ (e.g. &quot;Symbol&quot;.) Each font that is listed will be used (and downloaded
+ if needed) when printing.</P>
+<P>The remaining lines define a character to Unicode glyph mapping for
+ the character set. The character and glyph values are hexadecimal:</P>
+<UL>
+<PRE>
+xx yyyy
+</PRE>
+</UL>
+<H3><A NAME="3_1_2">3.1.2 Unicode Character Set Files</A></H3>
+<P>Unicode character set files start with a line reading:</P>
+<UL>
+<PRE>
+charset encoding
+</PRE>
+</UL>
+<P><VAR>Encoding</VAR> is the encoding to use for the text; currently
+ only the string &quot;utf8&quot; is supported.</P>
+<P>Following this are lines defining the font information:</P>
+<UL>
+<PRE>
+first last direction width normal bold italic bold-italic
+</PRE>
+</UL>
+<P><VAR>First</VAR> and<VAR> last</VAR> are the first and last glyphs in
+ the font mapping that correspond to that font; a maximum of 256
+ characters can be mapped within each group, with a maximum of 256
+ mappings (this is a PostScript limitation.) The glyph values are
+ hexadecimal.</P>
+<P><VAR>Direction</VAR> is the string &quot;ltor&quot;, &quot;rtol&quot;, or &quot;rtola&quot;
+ indicating left-to-right, right-to-left, or right-to-left Arabic text.</P>
+<P><VAR>Width</VAR> is the string &quot;single&quot; or &quot;double&quot;; double means
+ that the glyphs are twice as wide as ASCII characters in the Courier
+ typeface.</P>
+<P><VAR>Normal, bold, italic</VAR>, and<VAR> bold-italic</VAR> are the
+ typefaces to use for each presentation. If characters are only
+ available in a single style then only one typeface should be listed
+ (e.g. &quot;Symbol&quot;.) Each font that is listed will be used (and downloaded
+ if needed) when printing.</P>
+<H2><A NAME="3_2">3.2 Language Files</A></H2>
+<P>The language files define the default character set and a collection
+ of text messages in that language. They are named by prefixing the
+ string &quot;cups_&quot; to the front of the language specifier (e.g. &quot;cups_en&quot;,
+ &quot;cups_fr&quot;, etc.) Each file consists of two or more lines of ASCII text.</P>
+<P>The first line identifies the character set to be used for the
+ messages. The currently recognized values are:</P>
+<UL>
+<LI>iso-8859-1</LI>
+<LI>iso-8859-2</LI>
+<LI>iso-8859-3</LI>
+<LI>iso-8859-4</LI>
+<LI>iso-8859-5</LI>
+<LI>iso-8859-6</LI>
+<LI>iso-8859-7</LI>
+<LI>iso-8859-8</LI>
+<LI>iso-8859-9</LI>
+<LI>iso-8859-10</LI>
+<LI>iso-8859-13</LI>
+<LI>iso-8859-14</LI>
+<LI>iso-8859-15</LI>
+<LI>us-ascii</LI>
+<LI>utf-8</LI>
+<LI>windows-874</LI>
+<LI>windows-1250</LI>
+<LI>windows-1251</LI>
+<LI>windows-1252</LI>
+<LI>windows-1253</LI>
+<LI>windows-1254</LI>
+<LI>windows-1255</LI>
+<LI>windows-1256</LI>
+<LI>windows-1257</LI>
+<LI>windows-1258</LI>
+<LI>koi8-r</LI>
+<LI>koi8-u</LI>
+</UL>
+<P>The second and succeeding lines define text messages. If the message
+ text is preceded by a number, then the current message number is
+ updated and the text after the number is used.</P>
+<H2><A NAME="3_3">3.3 MIME Files</A></H2>
+<P>CUPS uses two MIME files in its standard configuration.</P>
+<H3><A NAME="3_3_1">3.3.1 mime.types</A></H3>
+<P>The mime.types file defines the recognized file types and consists of
+ 1 or more lines of ASCII text. Comment lines start with the pound (&quot;#&quot;)
+ character. The backslash (&quot;\&quot;) character can be used at the end of a
+ line to continue that line to the next.</P>
+<P>Each non-blank line starts with a MIME type identifier (&quot;super/type&quot;)
+ as registered with the IANA. All text following the MIME type is
+ treated as a series of type recognition rules:</P>
+<UL>
+<PRE>
+mime-type := super &quot;/&quot; type { SP rule }*
+super := { &quot;a-z&quot; | &quot;A-Z&quot; }*
+type := { &quot;a-z&quot; | &quot;A-Z&quot; | &quot;-&quot; | &quot;.&quot; | &quot;0-9&quot; }*
+rule := { extension | match | operator | &quot;(&quot; rule &quot;)&quot; }*
+extension := { &quot;a-z&quot; | &quot;A-Z&quot; | &quot;0-9&quot; }*
+match := &quot;match(&quot; regexp &quot;)&quot; |
+ &quot;ascii(&quot; offset &quot;,&quot; length &quot;)&quot; |
+ &quot;printable(&quot; offset &quot;,&quot; length &quot;)&quot; |
+ &quot;string(&quot; offset &quot;,&quot; string &quot;)&quot; |
+ &quot;contains(&quot; offset &quot;,&quot; length &quot;,&quot; string &quot;)&quot; |
+ &quot;char(&quot; offset &quot;,&quot; value &quot;)&quot; |
+ &quot;short(&quot; offset &quot;,&quot; value &quot;)&quot; |
+ &quot;int(&quot; offset &quot;,&quot; value &quot;)&quot; |
+ &quot;locale(&quot; string &quot;)&quot;
+operator := &quot;+&quot; | [ logical AND ]
+ &quot;,&quot; | SP [ logical OR ]
+ &quot;!&quot; [ unary NOT ]
+</PRE>
+</UL>
+<P>The <CODE>int</CODE> and <CODE>short</CODE> rules match look for
+ integers in network byte order (a.k.a. big-endian) with the
+ most-significant byte first.</P>
+<H3><A NAME="3_3_2">3.3.2 mime.convs</A></H3>
+<P>The mime.types file defines the recognized file filters and consists
+ of 1 or more lines of ASCII text. Comment lines start with the pound
+ (&quot;#&quot;) character.</P>
+<P>Each non-blank line starts with two MIME type identifiers
+ (&quot;super/type&quot;) representing the source and destination types. Following
+ the MIME types are a cost value (0 to 100) and the filter program to
+ use. If the filter program is not specified using the full path then it
+ must reside in the CUPS filter directory:</P>
+<UL>
+<PRE>
+super/type SP super/type2 SP cost SP program
+</PRE>
+</UL>
+<H2><A NAME="3_4">3.4 Option Files</A></H2>
+<P>CUPS maintains user-defined printer and option files for each printer
+ and user on the system. The printers and options defined in the system
+ option file (<CODE>/etc/cups/lpoptions</CODE>) are loaded first,
+ followed by the user option file (<CODE>$HOME/.lpoptions</CODE>).
+ Options in the user file replace those defined in the system file for
+ the same destination. Each line in the files can be one of the
+ following:</P>
+<UL>
+<PRE>
+Dest name option=value option=value ... option=value
+Dest name/instance option=value option=value ... option=value
+Default name option=value option=value ... option=value
+Default name/instance option=value option=value ... option=value
+</PRE>
+</UL>
+<P>The line beginning with &quot;Default&quot; indicates the default destination
+ for print jobs; a default line in the user option file overrides the
+ default defined in the system option file.</P>
+<P><VAR>Name</VAR> is the name of a printer known to the local server.</P>
+<P><VAR>Instance</VAR> can be any string of letters, numbers, and the
+ underscore up to 127 characters in length.</P>
+<P>The remainder of the line contains a list of space-separated options
+ and their values.</P>
+<H2><A NAME="3_5">3.5 PostScript Printer Description Files</A></H2>
+<P>PostScript Printer Description (&quot;PPD&quot;) files describe the
+ capabilities of each printer and are used by CUPS to support
+ printer-specific features and intelligent filtering.</P>
+<H3><A NAME="3_5_1">3.5.1 PPD Specification</A></H3>
+<P>The PPD file format is described in<A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">
+ Adobe TechNote #5003: PostScript Printer Description File Format
+ Specification Version 4.3</A>.</P>
+<H3><A NAME="3_5_2">3.5.2 CUPS Extensions to PPD Files</A></H3>
+<P>CUPS adds several new attributes that are described below.</P>
+<H4>3.5.2.1 cupsFilter</H4>
+<P>This string attribute provides a conversion rule of the form:</P>
+<UL>
+<PRE>
+source/type cost program
+</PRE>
+</UL>
+<P>The destination type is assumed to the printer's type. If a printer
+ supports the source type directly the special filter program &quot;-&quot; may be
+ specified.</P>
+<H4>3.5.2.2 cupsManualCopies</H4>
+<P>This boolean attribute notifies the RIP filters that the destination
+ printer does not support copy generation in hardware. The default value
+ is false.</P>
+<H4>3.5.2.3 cupsModelNumber</H4>
+<P>This integer attribute specifies a printer-specific model number.
+ This number can be used by a filter program to adjust the output for a
+ specific model of printer.</P>
+<H4>3.5.2.4 cupsProfile</H4>
+<P>This string attribute specifies a color profile of the form:</P>
+<UL>
+<PRE>
+resolution/type density gamma m00 m01 m02 m10 m11 m12 m20 m21 m22
+</PRE>
+</UL>
+<P>The<I> resolution</I> and<I> type</I> values may be &quot;-&quot; to act as a
+ wildcard. Otherwise they must match one of the <CODE>Resolution</CODE>
+ or <CODE>MediaType</CODE> attributes defined in the PPD file.</P>
+<P>The<I> density</I> and<I> gamma</I> values define gamma and density
+ adjustment function such that:</P>
+<UL>
+<PRE>
+f(x) = density * x<SUP>gamma</SUP>
+</PRE>
+</UL>
+<P>The<I> m00</I> through<I> m22</I> values define a 3x3 transformation
+ matrix for the CMY color values. The density function is applied<I>
+ after</I> the CMY transformation.</P>
+<H4>3.5.2.5 cupsVersion</H4>
+<P>This required attribute describes which version of the CUPS IDD was
+ used for the PPD file extensions. Currently it must be the string &quot;1.0&quot;
+ or &quot;1.1&quot;.</P>
+<H2><A NAME="3_6">3.6 Scheduler Configuration Files</A></H2>
+<P>The scheduler reads three configuration files that define the
+ available printers, classes, and services:</P>
+<DL>
+<DT>classes.conf</DT>
+<DD>This file defines all of the printer classes known to the system.</DD>
+<DT>cupsd.conf</DT>
+<DD>This file defines the files, directories, passwords, etc. used by
+ the scheduler.</DD>
+<DT>printers.conf</DT>
+<DD>This file defines all of the printers known to the system.</DD>
+</DL>
+<H3><A NAME="3_6_1">3.6.1 classes.conf</A></H3>
+<P>The classes.conf file consists of 1 or more lines of ASCII text.
+ Comment lines start with the pound (&quot;#&quot;) character.</P>
+<P>Each non-blank line starts with the name of a configuration directive
+ followed by its value. The following directives are understood:
+<CENTER>
+<TABLE BORDER="1" WIDTH="90%">
+<TR><TH WIDTH="25%">Directive</TH><TH>Description</TH></TR>
+<TR><TD>&lt;Class name&gt;
+<BR> &lt;/Class&gt;</TD><TD>Surrounds a class definition.</TD></TR>
+<TR><TD>&lt;DefaultClass name&gt;
+<BR> &lt;/Class&gt;</TD><TD>Surrounds a class definition for the default
+ destination.</TD></TR>
+<TR><TD>Accepting</TD><TD>Specifies whether the class is accepting new
+ jobs. May be the names &quot;Yes&quot; or &quot;No&quot;.</TD></TR>
+<TR><TD>AllowUsers</TD><TD>Specifies a list of users that are allowed to
+ access the class.</TD></TR>
+<TR><TD>BannerStart</TD><TD>Specifies the banner that is printed before
+ other files in a job.</TD></TR>
+<TR><TD>BannerEnd</TD><TD>Specifies the banner that is printed after
+ other files in a job.</TD></TR>
+<TR><TD>DenyUsers</TD><TD>Specifies a list of users that are not allowed
+ to access the class.</TD></TR>
+<TR><TD>Info</TD><TD>A textual description of the class.</TD></TR>
+<TR><TD>Location</TD><TD>A textual location of the class.</TD></TR>
+<TR><TD>Printer</TD><TD>Specifies a printer that is a member of the
+ class.</TD></TR>
+<TR><TD>State</TD><TD>Specifies the initial state of the class; can be
+ &quot;Idle&quot; or &quot;Stopped&quot;.</TD></TR>
+<TR><TD>StateMessage</TD><TD>Specifies a textual message for the current
+ class state.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="3_6_2">3.6.2 cupsd.conf</A></H3>
+<P>The cupsd.conf file consists of 1 or more lines of ASCII text.
+ Comment lines start with the pound (&quot;#&quot;) character.</P>
+<P>Each non-blank line starts with the name of a configuration directive
+ followed by its value. The following directives are understood:
+<CENTER>
+<TABLE BORDER="1" WIDTH="90%">
+<TR><TH WIDTH="25%">Directive</TH><TH>Default</TH><TH>Description</TH></TR>
+<TR><TD>AccessLog</TD><TD>access_log</TD><TD>Specifies the location of
+ the access log file. The special name &quot;syslog&quot; can be used to send
+ access log information to the system log.</TD></TR>
+<TR><TD>Allow</TD><TD>-</TD><TD>Allows connections from the specified
+ host, network, or domain.</TD></TR>
+<TR><TD>AuthClass</TD><TD>-</TD><TD>Specifies what level of
+ authentication is required; may be &quot;User&quot;, &quot;System&quot;, or &quot;Group&quot;.</TD></TR>
+<TR><TD>AuthType</TD><TD>None</TD><TD>Specifies the type of
+ authentication to perform; may be &quot;None&quot;, &quot;Basic&quot;, or &quot;Digest&quot;.</TD></TR>
+<TR><TD>BrowseAddress</TD><TD>255.255.255.255</TD><TD>Specifies a
+ broadcast address to send CUPS browsing packets to.</TD></TR>
+<TR><TD>BrowseAllow</TD><TD>-</TD><TD>Specifies hosts or addresses from
+ which browsing information should be used.</TD></TR>
+<TR><TD>BrowseDeny</TD><TD>-</TD><TD>Specifies hosts or addresses from
+ which browsing information should not be used.</TD></TR>
+<TR><TD>BrowseInterval</TD><TD>30</TD><TD>Specifies the number of
+ seconds between browsing updates. A browse interval of 0 seconds
+ disables outgoing packets.</TD></TR>
+<TR><TD>BrowseOrder</TD><TD>Allow,Deny</TD><TD>Specifies the order of
+ BrowseAllow and BrowseDeny directive processing; can be &quot;Deny,Allow&quot; to
+ implicitly deny hosts unless they are allowed by a BrowseAllow line, or
+ &quot;Allow,Deny&quot; to implicitly allow hosts unless they are denied by a
+ BrowseDeny line.</TD></TR>
+<TR><TD>BrowsePoll</TD><TD>-</TD><TD>Specifies a server to poll for
+ available printers and classes.</TD></TR>
+<TR><TD>BrowsePort</TD><TD>631</TD><TD>Specifies the UDP port number to
+ use for browse packets.</TD></TR>
+<TR><TD>BrowseRelay</TD><TD>-</TD><TD>Specifies a source and destination
+ address for relaying browser information from one subnet to another.</TD>
+</TR>
+<TR><TD>BrowseShortNames</TD><TD>yes</TD><TD>Specifies whether or not to
+ provide short names (without the &quot;@server&quot; part) for remote printers.</TD>
+</TR>
+<TR><TD>BrowseTimeout</TD><TD>300</TD><TD>Specifies the number of
+ seconds to wait until remote destinations are removed from the local
+ destination list.</TD></TR>
+<TR><TD>Browsing</TD><TD>On</TD><TD>Specifies whether or not printer and
+ class browsing is enabled; can be &quot;On&quot; or &quot;Off&quot;.</TD></TR>
+<TR><TD>DataDir</TD><TD>/usr/share/cups</TD><TD>Specifies the directory
+ where CUPS data files are stored.</TD></TR>
+<TR><TD>DefaultCharset</TD><TD>iso-8859-1</TD><TD>Specifies the default
+ character set.</TD></TR>
+<TR><TD>DefaultLanguage</TD><TD>current locale</TD><TD>Specifies the
+ default language.</TD></TR>
+<TR><TD>Deny</TD><TD>-</TD><TD>Refuses connections from the specified
+ host, network, or domain.</TD></TR>
+<TR><TD>DocumentRoot</TD><TD>/usr/share/doc/cups</TD><TD>Specifies the
+ document data root directory.</TD></TR>
+<TR><TD>ErrorLog</TD><TD>error_log</TD><TD>Specifies the error log file
+ location. The special name &quot;syslog&quot; can be used to send error log
+ information to the system log.</TD></TR>
+<TR><TD>Group</TD><TD>root, sys, system</TD><TD>Specifies the group name
+ or ID that is used when running external programs.</TD></TR>
+<TR><TD>HostNameLookups</TD><TD>Off</TD><TD>Specifies whether or not to
+ perform reverse IP address lookups to get the actual hostname; may be
+ &quot;On&quot; or &quot;Off&quot;. Hostname lookups can significantly degrade the
+ performance of the CUPS server if one or more DNS servers is not
+ functioning properly.</TD></TR>
+<TR><TD>ImplicitClasses</TD><TD>On</TD><TD>Specifies whether or not to
+ automatically create printer classes when more than one printer or
+ class of the same name is detected on the network; may be &quot;On&quot; or
+ &quot;Off&quot;.</TD></TR>
+<TR><TD>KeepAlive</TD><TD>On</TD><TD>Specifies whether or not to use the
+ HTTP Keep-Alive feature; may be &quot;On&quot; or &quot;Off&quot;.</TD></TR>
+<TR><TD>KeepAliveTimeout</TD><TD>30</TD><TD>Specifies the amount of time
+ to keep the HTTP connection alive before closing it.</TD></TR>
+<TR><TD>&lt;Location path&gt;
+<BR> &lt;/Location&gt;</TD><TD>-</TD><TD>Specifies a location to restrict
+ access to.</TD></TR>
+<TR><TD>LogLevel</TD><TD>info</TD><TD>Controls the amount of information
+ that is logged in the error log file. Can be one of &quot;debug&quot;, &quot;info&quot;,
+ &quot;warn&quot;, &quot;error&quot;, or &quot;none&quot;, in decreasing order or verbosity.</TD></TR>
+<TR><TD>MaxClients</TD><TD>100</TD><TD>Specifies the maximum number of
+ simultaneous active clients. This value is internally limited to 1/3 of
+ the total number of available file descriptors.</TD></TR>
+<TR><TD>MaxLogSize</TD><TD>0</TD><TD>Specifies the maximum size of the
+ access, error, and page log files in bytes. If set to 0 then no maximum
+ size is set. Log files are rotated automatically when this size is
+ exceeded.</TD></TR>
+<TR><TD>MaxRequestSize</TD><TD>0</TD><TD>Specifies the maximum size of
+ HTTP requests in bytes. If set to 0 then there is no maximum.</TD></TR>
+<TR><TD>Order</TD><TD>Allow,Deny</TD><TD>Specifies the order of Allow
+ and Deny directive processing; can be &quot;Deny,Allow&quot; to implicitly deny
+ hosts unless they are allowed by an Allow line, or &quot;Allow,Deny&quot; to
+ implicitly allow hosts unless they are denied by a Deny line.</TD></TR>
+<TR><TD>PageLog</TD><TD>page_log</TD><TD>Specifies the location of the
+ page log file. The special name &quot;syslog&quot; can be used to send page log
+ information to the system log.</TD></TR>
+<TR><TD>Port</TD><TD>631</TD><TD>Specifies a port number to listen to
+ for HTTP connections.</TD></TR>
+<TR><TD>Printcap</TD><TD>/etc/printcap</TD><TD>Specifies the location of
+ a Berkeley printcap file to update with a list of current printers and
+ classes. If no filename is supplied then this automatic generation is
+ disabled.</TD></TR>
+<TR><TD>RequestRoot</TD><TD>/var/spool/cups</TD><TD>Specifies the
+ location of request files.</TD></TR>
+<TR><TD>RIPCache</TD><TD>8m</TD><TD>Specifies the size of the memory
+ cache in bytes that is used by RIP filters.</TD></TR>
+<TR><TD>ServerAdmin</TD><TD>root@ServerName</TD><TD>Specifies the person
+ to contact with problems.</TD></TR>
+<TR><TD>ServerName</TD><TD>hostname</TD><TD>Specifies the hostname that
+ is supplied to HTTP clients. This is also used to determine the default
+ CUPS server for the CUPS IPP client applications.</TD></TR>
+<TR><TD>ServerRoot</TD><TD>/etc/cups</TD><TD>Specifies the root
+ directory for server configuration files.</TD></TR>
+<TR><TD>SystemGroup</TD><TD>root, sys, system</TD><TD>Specifies the
+ group name used for System class authentication.</TD></TR>
+<TR><TD>TempDir</TD><TD>/var/tmp</TD><TD>Specifies the temporary
+ directory to use.</TD></TR>
+<TR><TD>Timeout</TD><TD>300</TD><TD>The timeout in seconds before client
+ connections are closed in the middle of a request.</TD></TR>
+<TR><TD>User</TD><TD>lp</TD><TD>Specifies the user that is used when
+ running external programs.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="3_6_3">3.6.3 printers.conf</A></H3>
+<P>The printers.conf file consists of 1 or more lines of ASCII text.
+ Comment lines start with the pound (&quot;#&quot;) character.</P>
+<P>Each non-blank line starts with the name of a configuration directive
+ followed by its value. The following directives are understood:
+<CENTER>
+<TABLE BORDER="1" WIDTH="90%">
+<TR><TH WIDTH="25%">Directive</TH><TH>Description</TH></TR>
+<TR><TD>Accepting</TD><TD>Specifies whether the printer is accepting new
+ jobs. May be the names &quot;Yes&quot; or &quot;No&quot;.</TD></TR>
+<TR><TD>&lt;DefaultPrinter name&gt;
+<BR> &lt;/Printer&gt;</TD><TD>Surrounds the printer definition for a default
+ destination.</TD></TR>
+<TR><TD>AllowUsers</TD><TD>Specifies a list of users that are allowed to
+ access the printer.</TD></TR>
+<TR><TD>BannerStart</TD><TD>Specifies the banner that is printed before
+ other files in a job.</TD></TR>
+<TR><TD>BannerEnd</TD><TD>Specifies the banner that is printed after
+ other files in a job.</TD></TR>
+<TR><TD>DenyUsers</TD><TD>Specifies a list of users that are not allowed
+ to access the printer.</TD></TR>
+<TR><TD>DeviceURI</TD><TD>Specifies the device-uri attribute for the
+ printer.</TD></TR>
+<TR><TD>Info</TD><TD>A textual description of the printer.</TD></TR>
+<TR><TD>Location</TD><TD>A textual location of the printer.</TD></TR>
+<TR><TD>&lt;Printer name&gt;
+<BR> &lt;/Printer&gt;</TD><TD>Surrounds the printer definition.</TD></TR>
+<TR><TD>State</TD><TD>Specifies the initial state of the printer; can be
+ &quot;Idle&quot; or &quot;Stopped&quot;.</TD></TR>
+<TR><TD>StateMessage</TD><TD>Specifies a textual message for the current
+ printer state.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H1><A NAME="4">4 External Interfaces</A></H1>
+<H2><A NAME="4_1">4.1 AppSocket Protocol</A></H2>
+<P>The AppSocket protocol is an 8-bit clean TCP/IP socket connection.
+ The default IP service port is 9100. The URI method name is &quot;socket&quot;.</P>
+<P>The AppSocket protocol is used by the Hewlett Packard JetDirect
+ network interfaces and print servers, as well as many other vendors'
+ products. See the CUPS Software Administrators Manual for a list of
+ supported products.</P>
+<H2><A NAME="4_2">4.2 CUPS Browsing Protocol</A></H2>
+<P>The CUPS Browsing Protocol is a UDP/IP-based broadcast service. By
+ default this service operates on IP service port 631.</P>
+<P>Each broadcast packet describes the state of a single printer or
+ class and is an ASCII text string of up to 1450 bytes ending with a
+ newline (0x0a). The string is formatted as follows:</P>
+<UL>
+<PRE>
+type SP state SP uri SP &quot;location&quot; SP &quot;info&quot; SP &quot;make-and-model&quot; NL
+</PRE>
+</UL>
+<P><VAR>State, uri, location, info</VAR>, and<VAR> make-and-model</VAR>,
+ correspond to the IPP <CODE>printer-state</CODE>, <CODE>
+printer-uri-supported</CODE>, <CODE>printer-location</CODE>, <CODE>
+printer-info</CODE>, and <CODE>printer-make-and-model</CODE> attributes.</P>
+<P><VAR>Type</VAR> is a hexadecimal number string representing
+ capability/type bits:
+<CENTER>
+<TABLE BORDER="1" WIDTH="40%">
+<TR><TH WIDTH="8%">Bit</TH><TH>Description</TH></TR>
+<TR><TD>0</TD><TD>0 = printer
+<BR> 1 = class</TD></TR>
+<TR><TD>1</TD><TD>0 = local
+<BR> 1 = remote
+<BR> (always 1)</TD></TR>
+<TR><TD>2</TD><TD>1 = can print B</TD></TR>
+<TR><TD>3</TD><TD>1 = can print color</TD></TR>
+<TR><TD>4</TD><TD>1 = can duplex</TD></TR>
+<TR><TD>5</TD><TD>1 = can staple</TD></TR>
+<TR><TD>6</TD><TD>1 = can do fast copies</TD></TR>
+<TR><TD>7</TD><TD>1 = can do fast collating</TD></TR>
+<TR><TD>8</TD><TD>1 = can punch holes</TD></TR>
+<TR><TD>9</TD><TD>1 = can cover</TD></TR>
+<TR><TD>10</TD><TD>1 = can bind</TD></TR>
+<TR><TD>11</TD><TD>1 = can sort</TD></TR>
+<TR><TD>12</TD><TD>1 = can print up to 9x14 inches</TD></TR>
+<TR><TD>13</TD><TD>1 = can print up to 18x24 inches</TD></TR>
+<TR><TD>14</TD><TD>1 = can print up to 36x48 inches</TD></TR>
+<TR><TD>15</TD><TD>1 = can print variable sizes</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H2><A NAME="4_3">4.3 CUPS Form File</A></H2>
+<P>CUPS Form files are XML files used by the CUPS <CODE>formtops</CODE>
+ filter to produce dynamic banner pages and support preprinted forms.</P>
+<P>The MIME type for CUPS Form files is <CODE>application/vnd.cups-form</CODE>
+.</P>
+<H3><A NAME="4_3_1">4.3.1 CUPS Form DTD</A></H3>
+<P>The following DTD describes the available elements and attributes in
+ a CUPS Form file:
+<CENTER>
+<TABLE BORDER>
+<TR><TD>
+<PRE>
+&lt;!ENTITY % Angle &quot;CDATA&quot; -- angle in degrees --&gt;
+
+&lt;!ENTITY % Color &quot;CDATA&quot; -- a color using sRGB: #RRGGBB as Hex values --&gt;
+
+&lt;!ENTITY % Length &quot;CDATA&quot; -- nn for pixels or nn% for percentage length --&gt;
+
+&lt;!ENTITY % Lengths &quot;CDATA&quot; -- comma-separated Length values --&gt;
+
+&lt;!ENTITY % Text &quot;CDATA&quot;&gt;
+
+&lt;!ENTITY % heading &quot;H1|H2|H3|H4|H5|H6&quot;&gt;
+
+&lt;!ENTITY % preformatted &quot;PRE&quot;&gt;
+
+&lt;!ENTITY % i18n
+ &quot;lang %LanguageCode; #IMPLIED -- language code --
+ dir (ltr|rtl) #IMPLIED -- direction for weak/neutral text --&quot;
+ &gt;
+
+&lt;!ENTITY % attrs &quot;%i18n;&quot;&gt;
+
+&lt;!ENTITY % fontstyle
+ &quot;B | FONT | I | TT&quot;&gt;
+
+&lt;!ENTITY % graphics
+ &quot;BOX | RECT | LINE | POLY | ARC | PIE | TEXT&quot;&gt;
+
+&lt;!ENTITY % insert
+ &quot;IMG | VAR&quot;&gt;
+
+&lt;!-- %inline; covers inline or &quot;text-level&quot; elements --&gt;
+&lt;!ENTITY % inline &quot;#PCDATA | %fontstyle; | %graphics; | %insert;&quot;&gt;
+
+&lt;!ELEMENT (%fontstyle;) - - (%inline;)*&gt;
+&lt;!ATTLIST (%fontstyle;)
+ %attrs; -- %i18n --
+ &gt;
+
+&lt;!ELEMENT BR - O EMPTY -- forced line break --&gt;
+&lt;!ATTLIST BR
+ %attrs; -- %i18n --
+ &gt;
+
+&lt;!ENTITY % block
+ &quot;P | %heading; | %preformatted;&quot;&gt;
+
+&lt;!ENTITY % flow &quot;%block; | %inline;&quot;&gt;
+
+&lt;!ELEMENT PAGE O O (%flow;)+ -- document body --&gt;
+&lt;!ATTLIST PAGE
+ %attrs; -- %i18n --
+ align (left|center|right) #IMPLIED -- horizontal alignment --
+ valign (top|middle|center|bottom) #IMPLIED -- vertical alignment --
+ &gt;
+
+&lt;!ELEMENT P - O (%inline;)* -- paragraph --&gt;
+&lt;!ATTLIST P
+ %attrs; -- %i18n --
+ align (left|center|right) #IMPLIED -- horizontal alignment --
+ &gt;
+
+&lt;!ELEMENT (%heading;) - - (%inline;)* -- heading --&gt;
+&lt;!ATTLIST (%heading;)
+ %attrs; -- %i18n --
+ align (left|center|right) #IMPLIED -- horizontal alignment --
+ &gt;
+
+&lt;!ELEMENT PRE - - (%inline;)* -- preformatted text --&gt;
+&lt;!ATTLIST PRE
+ %attrs; -- %i18n --
+ align (left|center|right) #IMPLIED -- horizontal alignment --
+ &gt;
+
+&lt;!ELEMENT BOX - O EMPTY -- unfilled box --&gt;
+&lt;!ATTLIST BOX
+ color %Color; #IMPLIED -- override color --
+ height %Length; #REQUIRED -- height of box --
+ thickness %Length; #IMPLIED -- override line thickness --
+ width %Length; #REQUIRED -- width of box --
+ x %Length; #REQUIRED -- horizontal position --
+ y %Length; #REQUIRED -- vertical position --
+ &gt;
+
+&lt;!ELEMENT RECT - O EMPTY -- filled box --&gt;
+&lt;!ATTLIST RECT
+ color %Color; #IMPLIED -- override color --
+ height %Length; #REQUIRED -- height of box --
+ width %Length; #REQUIRED -- width of box --
+ x %Length; #REQUIRED -- horizontal position --
+ y %Length; #REQUIRED -- vertical position --
+ &gt;
+
+&lt;!ELEMENT LINE - O EMPTY -- polyline --&gt;
+&lt;!ATTLIST LINE
+ color %Color; #IMPLIED -- override color --
+ thickness %Length; #IMPLIED -- override line thickness --
+ x %Lengths; #REQUIRED -- horizontal positions --
+ y %Lengths; #REQUIRED -- vertical positions --
+ &gt;
+
+&lt;!ELEMENT POLY - O EMPTY -- polygon (filled) --&gt;
+&lt;!ATTLIST POLY
+ color %Color; #IMPLIED -- override color --
+ x %Lengths; #REQUIRED -- horizontal positions --
+ y %Lengths; #REQUIRED -- vertical positions --
+ &gt;
+
+&lt;!ELEMENT ARC - O EMPTY -- unfilled arc --&gt;
+&lt;!ATTLIST ARC
+ color %Color; #IMPLIED -- override color --
+ end %Angle; #IMPLIED -- override end angle --
+ height %Length; #REQUIRED -- height of arc --
+ start %Angle; #IMPLIED -- override start angle --
+ thickness %Length; #IMPLIED -- override line thickness --
+ width %Length; #REQUIRED -- width of arc --
+ x %Length; #REQUIRED -- horizontal position --
+ y %Length; #REQUIRED -- vertical position --
+ &gt;
+
+&lt;!ELEMENT PIE - O EMPTY -- filled arc --&gt;
+&lt;!ATTLIST PIE
+ color %Color; #IMPLIED -- override color --
+ end %Angle; #IMPLIED -- override end angle --
+ height %Length; #REQUIRED -- height of arc --
+ start %Angle; #IMPLIED -- override start angle --
+ width %Length; #REQUIRED -- width of arc --
+ x %Length; #REQUIRED -- horizontal position --
+ y %Length; #REQUIRED -- vertical position --
+ &gt;
+
+&lt;!ELEMENT TEXT - - (%flow;)* -- text box --&gt;
+&lt;!ATTLIST RECT
+ align (left|center|right) #IMPLIED -- horizontal alignment --
+ height %Length; #REQUIRED -- height of box --
+ valign (top|middle|center|bottom) #IMPLIED -- vertical alignment --
+ width %Length; #REQUIRED -- width of box --
+ x %Length; #REQUIRED -- horizontal position --
+ y %Length; #REQUIRED -- vertical position --
+ &gt;
+
+
+&lt;!ELEMENT IMG - O EMPTY -- Embedded image --&gt;
+&lt;!ATTLIST IMG
+ %attrs; -- %coreattrs, %i18n, %events --
+ src %URI; #REQUIRED -- URI of image to embed --
+ height %Length; #IMPLIED -- override height --
+ width %Length; #IMPLIED -- override width --
+ &gt;
+
+&lt;!ELEMENT HEAD O O (DEFVAR)* -- document head --&gt;
+&lt;!ATTLIST HEAD
+ %i18n; -- lang, dir --
+ &gt;
+
+&lt;!ELEMENT DEFVAR - O EMPTY -- variable definition --&gt;
+&lt;!ATTLIST DEFVAR
+ name CDATA #REQUIRED -- name
+ value CDATA #REQUIRED -- value
+ &gt;
+
+
+&lt;!ENTITY % html.content &quot;HEAD, PAGE&quot;&gt;
+
+&lt;!ELEMENT CUPSFORM - - (HEAD) (PAGE)+ -- document root element --&gt;
+&lt;!ATTLIST CUPSFORM
+ %i18n; -- lang, dir --
+ &gt;
+</PRE>
+</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H2><A NAME="4_4">4.4 CUPS PostScript File</A></H2>
+<P>CUPS PostScript files are device-dependent Adobe PostScript program
+ files. The PostScript language is described in the<A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
+ Adobe PostScript Language Reference Manual, Third Edition</A>.</P>
+<P>The MIME type for CUPS PostScript files is <CODE>
+application/vnd.cups-postscript</CODE>.</P>
+<H2><A NAME="4_5">4.5 CUPS Raster File</A></H2>
+<P>CUPS raster files are device-dependent raster image files that
+ contain a PostScript page device dictionary and device-dependent raster
+ imagery for each page in the document. These files are used to transfer
+ raster data from the PostScript and image file RIPs to device-dependent
+ filters that convert the raster data to a printable format.</P>
+<P>A raster file begins with a four byte synchronization word:
+ 0x52615374 (&quot;RaSt&quot;) for big-endian architectures and 0x74536152
+ (&quot;tSaR&quot;) for little-endian architectures. The writer of the raster file
+ will use the native word order, and the reader is responsible for
+ detecting a reversed word order file and swapping bytes as needed. The
+ CUPS Image Library raster functions perform this function
+ automatically.</P>
+<P>Following the synchronization word are a series of raster pages. Each
+ page starts with a page device dictionary header and is followed
+ immediately by the raster data for that page.
+<CENTER>
+<TABLE BORDER="1" WIDTH="80%">
+<TR><TH WIDTH="10%">Bytes</TH><TH WIDTH="20%">Description</TH><TH>Values</TH>
+</TR>
+<TR><TD>0-63</TD><TD>MediaClass</TD><TD>Nul-terminated ASCII string</TD></TR>
+<TR><TD>64-127</TD><TD>MediaColor</TD><TD>Nul-terminated ASCII string</TD>
+</TR>
+<TR><TD>128-191</TD><TD>MediaType</TD><TD>Nul-terminated ASCII string</TD>
+</TR>
+<TR><TD>192-255</TD><TD>OutputType</TD><TD>Nul-terminated ASCII string</TD>
+</TR>
+<TR><TD>256-259</TD><TD>AdvanceDistance</TD><TD>0 to 2<SUP>32</SUP> - 1
+ points</TD></TR>
+<TR><TD>260-263</TD><TD>AdvanceMedia</TD><TD>0 = Never advance roll
+<BR> 1 = Advance roll after file
+<BR> 2 = Advance roll after job
+<BR> 3 = Advance roll after set
+<BR> 4 = Advance roll after page</TD></TR>
+<TR><TD>264-267</TD><TD>Collate</TD><TD>0 = do not collate copies
+<BR> 1 = collate copies</TD></TR>
+<TR><TD>268-271</TD><TD>CutMedia</TD><TD>0 = Never cut media
+<BR> 1 = Cut roll after file
+<BR> 2 = Cut roll after job
+<BR> 3 = Cut roll after set
+<BR> 4 = Cut roll after page</TD></TR>
+<TR><TD>272-275</TD><TD>Duplex</TD><TD>0 = Print single-sided
+<BR> 1 = Print double-sided</TD></TR>
+<TR><TD>276-283</TD><TD>HWResolution</TD><TD>Horizontal and vertical
+ resolution in dots-per-inch.</TD></TR>
+<TR><TD>284-299</TD><TD>ImagingBoundingBox</TD><TD>Four integers giving
+ the left, bottom, right, and top positions of the page bounding box in
+ points</TD></TR>
+<TR><TD>300-303</TD><TD>InsertSheet</TD><TD>0 = Do not insert separator
+ sheets
+<BR> 1 = Insert separator sheets</TD></TR>
+<TR><TD>304-307</TD><TD>Jog</TD><TD>0 = Do no jog pages
+<BR> 1 = Jog pages after file
+<BR> 2 = Jog pages after job
+<BR> 3 = Jog pages after set</TD></TR>
+<TR><TD>308-311</TD><TD>LeadingEdge</TD><TD>0 = Top edge is first
+<BR> 1 = Right edge is first
+<BR> 2 = Bottom edge is first
+<BR> 3 = Left edge is first</TD></TR>
+<TR><TD>312-319</TD><TD>Margins</TD><TD>Left and bottom origin of image
+ in points</TD></TR>
+<TR><TD>320-323</TD><TD>ManualFeed</TD><TD>0 = Do not manually feed
+ media
+<BR> 1 = Manually feed media</TD></TR>
+<TR><TD>324-327</TD><TD>MediaPosition</TD><TD>Input slot position from 0
+ to N</TD></TR>
+<TR><TD>328-331</TD><TD>MediaWeight</TD><TD>Media weight in grams per
+ meter squared</TD></TR>
+<TR><TD>332-335</TD><TD>MirrorPrint</TD><TD>0 = Do not mirror prints
+<BR> 1 = Mirror prints</TD></TR>
+<TR><TD>336-339</TD><TD>NegativePrint</TD><TD>0 = Do not invert prints
+<BR> 1 = Invert prints</TD></TR>
+<TR><TD>340-343</TD><TD>NumCopies</TD><TD>1 to 2<SUP>32</SUP> - 1</TD></TR>
+<TR><TD>344-347</TD><TD>Orientation</TD><TD>0 = Do not rotate page
+<BR> 1 = Rotate page counter-clockwise
+<BR> 2 = Turn page upside down
+<BR> 3 = Rotate page clockwise</TD></TR>
+<TR><TD>348-351</TD><TD>OutputFaceUp</TD><TD>0 = Output face down
+<BR> 1 = Output face up</TD></TR>
+<TR><TD>352-359</TD><TD>PageSize</TD><TD>Width and length in points</TD></TR>
+<TR><TD>360-363</TD><TD>Separations</TD><TD>0 = Print composite image
+<BR> 1 = Print color separations</TD></TR>
+<TR><TD>364-367</TD><TD>TraySwitch</TD><TD>0 = Do not change trays if
+ selected tray is empty
+<BR> 1 = Change trays if selected tray is empty</TD></TR>
+<TR><TD>368-371</TD><TD>Tumble</TD><TD>0 = Do not rotate even pages when
+ duplexing
+<BR> 1 = Rotate even pages when duplexing</TD></TR>
+<TR><TD>372-375</TD><TD>cupsWidth</TD><TD>Width of page image in pixels</TD>
+</TR>
+<TR><TD>376-379</TD><TD>cupsHeight</TD><TD>Height of page image in
+ pixels</TD></TR>
+<TR><TD>380-383</TD><TD>cupsMediaType</TD><TD>Driver-specific 0 to 2<SUP>
+32</SUP> - 1</TD></TR>
+<TR><TD>384-387</TD><TD>cupsBitsPerColor</TD><TD>1, 2, 4, 8 bits</TD></TR>
+<TR><TD>388-391</TD><TD>cupsBitsPerPixel</TD><TD>1 to 32 bits</TD></TR>
+<TR><TD>392-395</TD><TD>cupsBytesPerLine</TD><TD>1 to 2<SUP>32</SUP> - 1
+ bytes</TD></TR>
+<TR><TD>396-399</TD><TD>cupsColorOrder</TD><TD>0 = chunky pixels (CMYK
+ CMYK CMYK)
+<BR> 1 = banded pixels (CCC MMM YYY KKK)
+<BR> 2 = planar pixels (CCC... MMM... YYY... KKK...)</TD></TR>
+<TR><TD>400-403</TD><TD>cupsColorSpace</TD><TD>0 = white
+<BR> 1 = RGB
+<BR> 2 = RGBA
+<BR> 3 = black
+<BR> 4 = CMY
+<BR> 5 = YMC
+<BR> 6 = CMYK
+<BR> 7 = YMCK
+<BR> 8 = KCMY
+<BR> 9 = KCMYcm</TD></TR>
+<TR><TD>404-407</TD><TD>cupsCompression</TD><TD>Driver-specific 0 to 2<SUP>
+32</SUP> - 1</TD></TR>
+<TR><TD>408-411</TD><TD>cupsRowCount</TD><TD>Driver-specific 0 to 2<SUP>
+32</SUP> - 1</TD></TR>
+<TR><TD>412-415</TD><TD>cupsRowFeed</TD><TD>Driver-specific 0 to 2<SUP>
+32</SUP> - 1</TD></TR>
+<TR><TD>416-419</TD><TD>cupsRowStep</TD><TD>Driver-specific 0 to 2<SUP>
+32</SUP> - 1</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<P>The MIME type for CUPS Raster files is <CODE>
+application/vnd.cups-raster</CODE>.</P>
+<H2><A NAME="4_6">4.6 CUPS Raw Files</A></H2>
+<P>Raw files are printer-dependent print files that are in a format
+ suitable to the destination printer (e.g. HP-PCL, HP-RTL, etc.) The
+ MIME type for CUPS Raw files is <CODE>application/vnd.cups-raw</CODE>.</P>
+<H2><A NAME="4_7">4.7 Internet Printing Protocol</A></H2>
+<P>The Internet Printing Protocol and the CUPS extensions to it are
+ described in the CUPS Implementation of IPP document.</P>
+<H2><A NAME="4_8">4.8 Line Printer Daemon Protocol</A></H2>
+<P>The Line Printer Daemon (LPD) protocol is described by<A HREF="http://www.ietf.org/rfc/rfc1179.txt">
+ RFC 1179: Line Printer Daemon Protocol</A>.</P>
+<P>The URI method name for LPD is &quot;lpd&quot;.</P>
+<H2><A NAME="4_9">4.9 Server Message Block Protocol</A></H2>
+<P>The Server Message Block (SMB) and related Common Internet File
+ System (CIFS) protocols are described at<A HREF="http://anu.samba.org/cifs">
+ http://anu.samba.org/cifs</A>.</P>
+<P>The URI method name for SMB is &quot;smb&quot;. Support for this protocol is
+ provided via the SAMBA <CODE>smbspool(1)</CODE> program provided with
+ SAMBA 2.0.6 and higher.</P>
+<H1><A NAME="5">5 Directories</A></H1>
+<DL>
+<DT>/etc/cups</DT>
+<DD>The scheduler configuration and MIME files reside here.</DD>
+<DT>/etc/cups/certs</DT>
+<DD>The authentication certificates reside here.</DD>
+<DT>/etc/cups/interfaces</DT>
+<DD>System V interface scripts reside here.</DD>
+<DT>/etc/cups/ppd</DT>
+<DD>This directory contains PPD files for each printer.</DD>
+<DT>/usr/bin</DT>
+<DD>The <CODE>cancel</CODE>, <CODE>lp</CODE>, <CODE>lpq</CODE>, <CODE>
+lpr</CODE>, <CODE>lprm</CODE>, and <CODE>lpstat</CODE> commands reside
+ here.</DD>
+<DT>/usr/lib, /usr/lib32</DT>
+<DD>The shared libraries (DSOs) reside here.</DD>
+<DT>/usr/lib/cups/backend</DT>
+<DD>The backend filters reside here.</DD>
+<DT>/usr/lib/cups/cgi-bin</DT>
+<DD>The CGI programs reside here.</DD>
+<DT>/usr/lib/cups/daemon</DT>
+<DD>The polling and LPD daemons reside here.</DD>
+<DT>/usr/lib/cups/filter</DT>
+<DD>The file filters reside here.</DD>
+<DT>/usr/sbin</DT>
+<DD>The <CODE>accept</CODE>, <CODE>cupsd</CODE>, <CODE>lpadmin</CODE>, <CODE>
+lpc</CODE>, and <CODE>reject</CODE> commands reside here.</DD>
+<DT>/usr/share/cups</DT>
+<DD>This is the root directory of the CUPS static data.</DD>
+<DT>/usr/share/cups/charsets</DT>
+<DD>The character set files reside here.</DD>
+<DT>/usr/share/cups/data</DT>
+<DD>The filter data files reside here.</DD>
+<DT>/usr/share/cups/fonts</DT>
+<DD>The <CODE>pstoraster</CODE> font files reside here.</DD>
+<DT>/usr/share/cups/model</DT>
+<DD>The sample PPD files reside here.</DD>
+<DT>/usr/share/cups/pstoraster</DT>
+<DD>The <CODE>pstoraster</CODE> data files reside here.</DD>
+<DT>/usr/share/doc/cups</DT>
+<DD>The scheduler documentation files reside here.</DD>
+<DT>/var/log/cups</DT>
+<DD>The <CODE>access_log</CODE>, <CODE>error_log</CODE>, and <CODE>
+page_log</CODE> files reside here.</DD>
+<DT>/var/spool/cups</DT>
+<DD>This directory contains print job files.</DD>
+</DL>
+<H1 TYPE="A" VALUE="1"><A NAME="6">A Glossary</A></H1>
+<H2><A NAME="6_1">A.1 Terms</A></H2>
+<DL>
+<DT>C</DT>
+<DD>A computer language.</DD>
+<DT>parallel</DT>
+<DD>Sending or receiving data more than 1 bit at a time.</DD>
+<DT>pipe</DT>
+<DD>A one-way communications channel between two programs.</DD>
+<DT>serial</DT>
+<DD>Sending or receiving data 1 bit at a time.</DD>
+<DT>socket</DT>
+<DD>A two-way network communications channel.</DD>
+</DL>
+<H2><A NAME="6_2">A.2 Acronyms</A></H2>
+<DL>
+<DT>ASCII</DT>
+<DD>American Standard Code for Information Interchange</DD>
+<DT>CUPS</DT>
+<DD>Common UNIX Printing System</DD>
+<DT>ESC/P</DT>
+<DD>EPSON Standard Code for Printers</DD>
+<DT>FTP</DT>
+<DD>File Transfer Protocol</DD>
+<DT>HP-GL</DT>
+<DD>Hewlett-Packard Graphics Language</DD>
+<DT>HP-PCL</DT>
+<DD>Hewlett-Packard Page Control Language</DD>
+<DT>HP-PJL</DT>
+<DD>Hewlett-Packard Printer Job Language</DD>
+<DT>IETF</DT>
+<DD>Internet Engineering Task Force</DD>
+<DT>IPP</DT>
+<DD>Internet Printing Protocol</DD>
+<DT>ISO</DT>
+<DD>International Standards Organization</DD>
+<DT>LPD</DT>
+<DD>Line Printer Daemon</DD>
+<DT>MIME</DT>
+<DD>Multimedia Internet Mail Exchange</DD>
+<DT>PPD</DT>
+<DD>PostScript Printer Description</DD>
+<DT>SMB</DT>
+<DD>Server Message Block</DD>
+<DT>TFTP</DT>
+<DD>Trivial File Transfer Protocol</DD>
+</DL>
+</BODY>
+</HTML>
diff --git a/doc/idd.pdf b/doc/idd.pdf
new file mode 100644
index 000000000..38dd84fde
--- /dev/null
+++ b/doc/idd.pdf
Binary files differ
diff --git a/doc/idd.shtml b/doc/idd.shtml
new file mode 100644
index 000000000..d6c4f510a
--- /dev/null
+++ b/doc/idd.shtml
@@ -0,0 +1,1431 @@
+<HTML>
+<HEAD>
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-IDD-1.1">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Interface Design Description</TITLE>
+</HEAD>
+<BODY>
+
+<H1>Scope</H1>
+
+<H2>Identification</H2>
+
+<P>This interface design description document provides detailed file
+formats, message formats, and program conventions for the Common UNIX
+Printing System ("CUPS") Version 1.1.
+
+<EMBED SRC="system-overview.shtml">
+
+<H2>Document Overview</H2>
+
+<P>This interface design description document is organized into the following
+sections:
+
+<UL>
+ <LI>1 - Scope
+ <LI>2 - References
+ <LI>3 - Internal Interfaces
+ <LI>4 - External Interfaces
+ <LI>5 - Directories
+ <LI>A - Glossary
+</UL>
+
+<EMBED SRC="references.shtml">
+
+<H1>Internal Interfaces</H1>
+
+<H2>Character Set Files</H2>
+
+<P>The character set files define a mapping between 8-bit characters
+and the Unicode character set, or between Unicode and printer fonts.
+They are named using the IETF charset names defined in RFCnnnn. These
+files are ASCII text, the content of which is described below. Comments
+can be included by using the <TT>#</TT> character in the first column
+of a line.
+
+<H3>8-Bit Character Set Files</H3>
+
+<P>8-bit character set files start with a line reading:
+
+<UL><PRE>
+charset 8bit
+</PRE></UL>
+
+<P>Following this are lines that define the font information:
+
+<UL><PRE>
+first last direction width normal bold italic bold-italic
+</PRE></UL>
+
+<P><VAR>First</VAR> and <VAR>last</VAR> are the first and last glyphs
+in the font mapping that correspond to that font; a maximum of 256
+characters can be mapped within each group, with a maximum of 256
+mappings (this is a PostScript limitation.) The glyph values are
+hexadecimal.
+
+<P><VAR>Direction</VAR> is the string "ltor", "rtol", or "rtola" indicating
+left-to-right, right-to-left, or right-to-left Arabic text.
+
+<P><VAR>Width</VAR> is the string "single" or "double"; double means that the
+glyphs are twice as wide as ASCII characters in the Courier typeface.
+
+<P><VAR>Normal, bold, italic</VAR>, and <VAR>bold-italic</VAR> are the
+typefaces to use for each presentation. If characters are only available in
+a single style then only one typeface should be listed (e.g. "Symbol".)
+Each font that is listed will be used (and downloaded if needed) when
+printing.
+
+<P>The remaining lines define a character to Unicode glyph mapping for the
+character set. The character and glyph values are hexadecimal:
+
+<UL><PRE>
+xx yyyy
+</PRE></UL>
+
+<H3>Unicode Character Set Files</H3>
+
+<P>Unicode character set files start with a line reading:
+
+<UL><PRE>
+charset encoding
+</PRE></UL>
+
+<P><VAR>Encoding</VAR> is the encoding to use for the text; currently only
+the string "utf8" is supported.
+
+<P>Following this are lines defining the font information:
+
+<UL><PRE>
+first last direction width normal bold italic bold-italic
+</PRE></UL>
+
+<P><VAR>First</VAR> and <VAR>last</VAR> are the first and last glyphs
+in the font mapping that correspond to that font; a maximum of 256
+characters can be mapped within each group, with a maximum of 256
+mappings (this is a PostScript limitation.) The glyph values are
+hexadecimal.
+
+<P><VAR>Direction</VAR> is the string "ltor", "rtol", or "rtola" indicating
+left-to-right, right-to-left, or right-to-left Arabic text.
+
+<P><VAR>Width</VAR> is the string "single" or "double"; double means that the
+glyphs are twice as wide as ASCII characters in the Courier typeface.
+
+<P><VAR>Normal, bold, italic</VAR>, and <VAR>bold-italic</VAR> are the
+typefaces to use for each presentation. If characters are only available in
+a single style then only one typeface should be listed (e.g. "Symbol".)
+Each font that is listed will be used (and downloaded if needed) when
+printing.
+
+<H2>Language Files</H2>
+
+<P>The language files define the default character set and a collection of
+text messages in that language. They are named by prefixing the string "cups_"
+to the front of the language specifier (e.g. "cups_en", "cups_fr", etc.) Each
+file consists of two or more lines of ASCII text.
+
+<P>The first line identifies the character set to be used for the messages.
+The currently recognized values are:
+
+<UL>
+ <LI>iso-8859-1
+ <LI>iso-8859-2
+ <LI>iso-8859-3
+ <LI>iso-8859-4
+ <LI>iso-8859-5
+ <LI>iso-8859-6
+ <LI>iso-8859-7
+ <LI>iso-8859-8
+ <LI>iso-8859-9
+ <LI>iso-8859-10
+ <LI>iso-8859-13
+ <LI>iso-8859-14
+ <LI>iso-8859-15
+ <LI>us-ascii
+ <LI>utf-8
+ <LI>windows-874
+ <LI>windows-1250
+ <LI>windows-1251
+ <LI>windows-1252
+ <LI>windows-1253
+ <LI>windows-1254
+ <LI>windows-1255
+ <LI>windows-1256
+ <LI>windows-1257
+ <LI>windows-1258
+ <LI>koi8-r
+ <LI>koi8-u
+</UL>
+
+<P>The second and succeeding lines define text messages. If the message text
+is preceded by a number, then the current message number is updated and the
+text after the number is used.
+
+<H2>MIME Files</H2>
+
+<P>CUPS uses two MIME files in its standard configuration.
+
+<H3>mime.types</H3>
+
+<P>The mime.types file defines the recognized file types and consists
+of 1 or more lines of ASCII text. Comment lines start with the pound
+("#") character. The backslash ("\") character can be used at the end
+of a line to continue that line to the next.
+
+<P>Each non-blank line starts with a MIME type identifier ("super/type")
+as registered with the IANA. All text following the MIME type is treated as
+a series of type recognition rules:
+
+<UL><PRE>
+mime-type := super "/" type { SP rule }*
+super := { "a-z" | "A-Z" }*
+type := { "a-z" | "A-Z" | "-" | "." | "0-9" }*
+rule := { extension | match | operator | "(" rule ")" }*
+extension := { "a-z" | "A-Z" | "0-9" }*
+match := "match(" regexp ")" |
+ "ascii(" offset "," length ")" |
+ "printable(" offset "," length ")" |
+ "string(" offset "," string ")" |
+ "contains(" offset "," length "," string ")" |
+ "char(" offset "," value ")" |
+ "short(" offset "," value ")" |
+ "int(" offset "," value ")" |
+ "locale(" string ")"
+operator := "+" | [ logical AND ]
+ "," | SP [ logical OR ]
+ "!" [ unary NOT ]
+</PRE></UL>
+
+<P>The <CODE>int</CODE> and <CODE>short</CODE> rules match look for integers
+in network byte order (a.k.a. big-endian) with the most-significant byte first.
+
+<H3>mime.convs</H3>
+
+<P>The mime.types file defines the recognized file filters and consists
+of 1 or more lines of ASCII text. Comment lines start with the pound
+("#") character.
+
+<P>Each non-blank line starts with two MIME type identifiers ("super/type")
+representing the source and destination types. Following the MIME types are
+a cost value (0 to 100) and the filter program to use. If the filter program
+is not specified using the full path then it must reside in the CUPS filter
+directory:
+
+<UL><PRE>
+super/type SP super/type2 SP cost SP program
+</PRE></UL>
+
+<H2>Option Files</H2>
+
+<P>CUPS maintains user-defined printer and option files for each
+printer and user on the system. The printers and options defined in the
+system option file (<CODE>/etc/cups/lpoptions</CODE>) are loaded first,
+followed by the user option file (<CODE>$HOME/.lpoptions</CODE>).
+Options in the user file replace those defined in the system file for
+the same destination. Each line in the files can be one of the
+following:
+
+<UL><PRE>
+Dest name option=value option=value ... option=value
+Dest name/instance option=value option=value ... option=value
+Default name option=value option=value ... option=value
+Default name/instance option=value option=value ... option=value
+</PRE></UL>
+
+<P>The line beginning with "Default" indicates the default destination for
+print jobs; a default line in the user option file overrides the default
+defined in the system option file.
+
+<P><VAR>Name</VAR> is the name of a printer known to the local server.
+
+<P><VAR>Instance</VAR> can be any string of letters, numbers, and the underscore
+up to 127 characters in length.
+
+<P>The remainder of the line contains a list of space-separated options
+and their values.
+
+<H2>PostScript Printer Description Files</H2>
+
+<P>PostScript Printer Description ("PPD") files describe the capabilities
+of each printer and are used by CUPS to support printer-specific features
+and intelligent filtering.
+
+<H3>PPD Specification</H3>
+
+<P>The PPD file format is described in
+<A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">
+Adobe TechNote #5003: PostScript Printer Description File Format
+Specification Version 4.3</A>.
+
+<H3>CUPS Extensions to PPD Files</H3>
+
+<P>CUPS adds several new attributes that are described below.
+
+<H4>cupsFilter</H4>
+
+<P>This string attribute provides a conversion rule of the form:
+
+<UL><PRE>
+source/type cost program
+</PRE></UL>
+
+<P>The destination type is assumed to the printer's type. If a printer
+supports the source type directly the special filter program "-" may be
+specified.
+
+<H4>cupsManualCopies</H4>
+
+<P>This boolean attribute notifies the RIP filters that the destination printer
+does not support copy generation in hardware. The default value is false.
+
+<H4>cupsModelNumber</H4>
+
+<P>This integer attribute specifies a printer-specific model number. This number
+can be used by a filter program to adjust the output for a specific model of
+printer.
+
+<H4>cupsProfile</H4>
+
+<P>This string attribute specifies a color profile of the form:
+
+<UL><PRE>
+resolution/type density gamma m00 m01 m02 m10 m11 m12 m20 m21 m22
+</PRE></UL>
+
+<P>The <I>resolution</I> and <I>type</I> values may be "-" to act as a
+wildcard. Otherwise they must match one of the <CODE>Resolution</CODE> or
+<CODE>MediaType</CODE> attributes defined in the PPD file.
+
+<P>The <I>density</I> and <I>gamma</I> values define gamma and density
+adjustment function such that:
+
+<UL><PRE>
+f(x) = density * x<SUP>gamma</SUP>
+</PRE></UL>
+
+<P>The <I>m00</I> through <I>m22</I> values define a 3x3 transformation
+matrix for the CMY color values. The density function is applied <I>after</I>
+the CMY transformation.
+
+<H4>cupsVersion</H4>
+
+<P>This required attribute describes which version of the CUPS IDD was used
+for the PPD file extensions. Currently it must be the string "1.0" or "1.1".
+
+<H2>Scheduler Configuration Files</H2>
+
+<P>The scheduler reads three configuration files that define the available
+printers, classes, and services:
+
+<DL>
+
+ <DT>classes.conf
+ <DD>This file defines all of the printer classes known to the
+ system.
+
+ <DT>cupsd.conf
+ <DD>This file defines the files, directories, passwords, etc.
+ used by the scheduler.
+
+ <DT>printers.conf
+ <DD>This file defines all of the printers known to the system.
+
+</DL>
+
+<H3>classes.conf</H3>
+
+<P>The classes.conf file consists of 1 or more lines of ASCII text.
+Comment lines start with the pound ("#") character.
+
+<P>Each non-blank line starts with the name of a configuration directive
+followed by its value. The following directives are understood:
+
+<CENTER><TABLE WIDTH="90%" BORDER="1">
+<TR>
+ <TH WIDTH="25%">Directive</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>&lt;Class name&gt;<BR>
+ &lt;/Class&gt;</TD>
+ <TD>Surrounds a class definition.</TD>
+</TR>
+<TR>
+ <TD>&lt;DefaultClass name&gt;<BR>
+ &lt;/Class&gt;</TD>
+ <TD>Surrounds a class definition for the default destination.</TD>
+</TR>
+<TR>
+ <TD>Accepting</TD>
+ <TD>Specifies whether the class is accepting new jobs. May be
+ the names "Yes" or "No".</TD>
+</TR>
+<TR>
+ <TD>AllowUsers</TD>
+ <TD>Specifies a list of users that are allowed to access the class.</TD>
+</TR>
+<TR>
+ <TD>BannerStart</TD>
+ <TD>Specifies the banner that is printed before other files in a
+ job.</TD>
+</TR>
+<TR>
+ <TD>BannerEnd</TD>
+ <TD>Specifies the banner that is printed after other files in a
+ job.</TD>
+</TR>
+<TR>
+ <TD>DenyUsers</TD>
+ <TD>Specifies a list of users that are not allowed to access the
+ class.</TD>
+</TR>
+<TR>
+ <TD>Info</TD>
+ <TD>A textual description of the class.</TD>
+</TR>
+<TR>
+ <TD>Location</TD>
+ <TD>A textual location of the class.</TD>
+</TR>
+<TR>
+ <TD>Printer</TD>
+ <TD>Specifies a printer that is a member of the class.</TD>
+</TR>
+<TR>
+ <TD>State</TD>
+ <TD>Specifies the initial state of the class; can be "Idle" or
+ "Stopped".</TD>
+</TR>
+<TR>
+ <TD>StateMessage</TD>
+ <TD>Specifies a textual message for the current class state.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>cupsd.conf</H3>
+
+<P>The cupsd.conf file consists of 1 or more lines of ASCII text.
+Comment lines start with the pound ("#") character.
+
+<P>Each non-blank line starts with the name of a configuration directive
+followed by its value. The following directives are understood:
+
+<CENTER><TABLE WIDTH="90%" BORDER="1">
+<TR>
+ <TH WIDTH="25%">Directive</TH>
+ <TH>Default</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>AccessLog</TD>
+ <TD>access_log</TD>
+ <TD>Specifies the location of the access log file. The special name
+ "syslog" can be used to send access log information to the system
+ log.</TD>
+</TR>
+<TR>
+ <TD>Allow</TD>
+ <TD>-</TD>
+ <TD>Allows connections from the specified host, network, or
+ domain.</TD>
+</TR>
+<TR>
+ <TD>AuthClass</TD>
+ <TD>-</TD>
+ <TD>Specifies what level of authentication is required; may be
+ "User", "System", or "Group".</TD>
+</TR>
+<TR>
+ <TD>AuthType</TD>
+ <TD>None</TD>
+ <TD>Specifies the type of authentication to perform; may be
+ "None", "Basic", or "Digest".</TD>
+</TR>
+<TR>
+ <TD>BrowseAddress</TD>
+ <TD>255.255.255.255</TD>
+ <TD>Specifies a broadcast address to send CUPS browsing packets to.</TD>
+</TR>
+<TR>
+ <TD>BrowseAllow</TD>
+ <TD>-</TD>
+ <TD>Specifies hosts or addresses from which browsing information
+ should be used.</TD>
+</TR>
+<TR>
+ <TD>BrowseDeny</TD>
+ <TD>-</TD>
+ <TD>Specifies hosts or addresses from which browsing information
+ should not be used.</TD>
+</TR>
+<TR>
+ <TD>BrowseInterval</TD>
+ <TD>30</TD>
+ <TD>Specifies the number of seconds between browsing updates. A
+ browse interval of 0 seconds disables outgoing packets.</TD>
+</TR>
+<TR>
+ <TD>BrowseOrder</TD>
+ <TD>Allow,Deny</TD>
+ <TD>Specifies the order of BrowseAllow and BrowseDeny directive
+ processing; can be "Deny,Allow" to implicitly deny hosts unless
+ they are allowed by a BrowseAllow line, or "Allow,Deny" to
+ implicitly allow hosts unless they are denied by a BrowseDeny
+ line.</TD>
+</TR>
+<TR>
+ <TD>BrowsePoll</TD>
+ <TD>-</TD>
+ <TD>Specifies a server to poll for available printers and classes.</TD>
+</TR>
+<TR>
+ <TD>BrowsePort</TD>
+ <TD>631</TD>
+ <TD>Specifies the UDP port number to use for browse packets.</TD>
+</TR>
+<TR>
+ <TD>BrowseRelay</TD>
+ <TD>-</TD>
+ <TD>Specifies a source and destination address for relaying browser
+ information from one subnet to another.</TD>
+</TR>
+<TR>
+ <TD>BrowseShortNames</TD>
+ <TD>yes</TD>
+ <TD>Specifies whether or not to provide short names (without the
+ "@server" part) for remote printers.</TD>
+</TR>
+<TR>
+ <TD>BrowseTimeout</TD>
+ <TD>300</TD>
+ <TD>Specifies the number of seconds to wait until remote destinations
+ are removed from the local destination list.</TD>
+</TR>
+<TR>
+ <TD>Browsing</TD>
+ <TD>On</TD>
+ <TD>Specifies whether or not printer and class browsing is enabled; can
+ be "On" or "Off".</TD>
+</TR>
+<TR>
+ <TD>DataDir</TD>
+ <TD>/usr/share/cups</TD>
+ <TD>Specifies the directory where CUPS data files are stored.</TD>
+</TR>
+<TR>
+ <TD>DefaultCharset</TD>
+ <TD>iso-8859-1</TD>
+ <TD>Specifies the default character set.</TD>
+</TR>
+<TR>
+ <TD>DefaultLanguage</TD>
+ <TD>current locale</TD>
+ <TD>Specifies the default language.</TD>
+</TR>
+<TR>
+ <TD>Deny</TD>
+ <TD>-</TD>
+ <TD>Refuses connections from the specified host, network, or
+ domain.</TD>
+</TR>
+<TR>
+ <TD>DocumentRoot</TD>
+ <TD>/usr/share/doc/cups</TD>
+ <TD>Specifies the document data root directory.</TD>
+</TR>
+<TR>
+ <TD>ErrorLog</TD>
+ <TD>error_log</TD>
+ <TD>Specifies the error log file location. The special name
+ "syslog" can be used to send error log information to the system
+ log.</TD>
+</TR>
+<TR>
+ <TD>Group</TD>
+ <TD>root, sys, system</TD>
+ <TD>Specifies the group name or ID that is used when running
+ external programs.</TD>
+</TR>
+<TR>
+ <TD>HostNameLookups</TD>
+ <TD>Off</TD>
+ <TD>Specifies whether or not to perform reverse IP address lookups to
+ get the actual hostname; may be "On" or "Off". Hostname lookups can
+ significantly degrade the performance of the CUPS server if one or
+ more DNS servers is not functioning properly.</TD>
+</TR>
+<TR>
+ <TD>ImplicitClasses</TD>
+ <TD>On</TD>
+ <TD>Specifies whether or not to automatically create printer classes
+ when more than one printer or class of the same name is detected on
+ the network; may be "On" or "Off".</TD>
+</TR>
+<TR>
+ <TD>KeepAlive</TD>
+ <TD>On</TD>
+ <TD>Specifies whether or not to use the HTTP Keep-Alive feature; may
+ be "On" or "Off".</TD>
+</TR>
+<TR>
+ <TD>KeepAliveTimeout</TD>
+ <TD>30</TD>
+ <TD>Specifies the amount of time to keep the HTTP connection alive
+ before closing it.</TD>
+</TR>
+<TR>
+ <TD>&lt;Location path&gt;<BR>
+ &lt;/Location&gt;</TD>
+ <TD>-</TD>
+ <TD>Specifies a location to restrict access to.</TD>
+</TR>
+<TR>
+ <TD>LogLevel</TD>
+ <TD>info</TD>
+ <TD>Controls the amount of information that is logged in the
+ error log file. Can be one of "debug", "info", "warn", "error",
+ or "none", in decreasing order or verbosity.</TD>
+</TR>
+<TR>
+ <TD>MaxClients</TD>
+ <TD>100</TD>
+ <TD>Specifies the maximum number of simultaneous active clients.
+ This value is internally limited to 1/3 of the total number of
+ available file descriptors.</TD>
+</TR>
+<TR>
+ <TD>MaxLogSize</TD>
+ <TD>0</TD>
+ <TD>Specifies the maximum size of the access, error, and page
+ log files in bytes. If set to 0 then no maximum size is set.
+ Log files are rotated automatically when this size is
+ exceeded.</TD>
+</TR>
+<TR>
+ <TD>MaxRequestSize</TD>
+ <TD>0</TD>
+ <TD>Specifies the maximum size of HTTP requests in bytes. If set to 0
+ then there is no maximum.</TD>
+</TR>
+<TR>
+ <TD>Order</TD>
+ <TD>Allow,Deny</TD>
+ <TD>Specifies the order of Allow and Deny directive processing; can
+ be "Deny,Allow" to implicitly deny hosts unless they are allowed by
+ an Allow line, or "Allow,Deny" to implicitly allow hosts unless they
+ are denied by a Deny line.</TD>
+</TR>
+<TR>
+ <TD>PageLog</TD>
+ <TD>page_log</TD>
+ <TD>Specifies the location of the page log file. The special name
+ "syslog" can be used to send page log information to the system
+ log.</TD>
+</TR>
+<TR>
+ <TD>Port</TD>
+ <TD>631</TD>
+ <TD>Specifies a port number to listen to for HTTP connections.</TD>
+</TR>
+<TR>
+ <TD>Printcap</TD>
+ <TD>/etc/printcap</TD>
+ <TD>Specifies the location of a Berkeley printcap file to update
+ with a list of current printers and classes. If no filename is
+ supplied then this automatic generation is disabled.</TD>
+</TR>
+<TR>
+ <TD>RequestRoot</TD>
+ <TD>/var/spool/cups</TD>
+ <TD>Specifies the location of request files.</TD>
+</TR>
+<TR>
+ <TD>RIPCache</TD>
+ <TD>8m</TD>
+ <TD>Specifies the size of the memory cache in bytes that is used by
+ RIP filters.</TD>
+</TR>
+<TR>
+ <TD>ServerAdmin</TD>
+ <TD>root@ServerName</TD>
+ <TD>Specifies the person to contact with problems.</TD>
+</TR>
+<TR>
+ <TD>ServerName</TD>
+ <TD>hostname</TD>
+ <TD>Specifies the hostname that is supplied to HTTP clients. This
+ is also used to determine the default CUPS server for the CUPS IPP
+ client applications.</TD>
+</TR>
+<TR>
+ <TD>ServerRoot</TD>
+ <TD>/etc/cups</TD>
+ <TD>Specifies the root directory for server configuration files.</TD>
+</TR>
+<TR>
+ <TD>SystemGroup</TD>
+ <TD>root, sys, system</TD>
+ <TD>Specifies the group name used for System class authentication.</TD>
+</TR>
+<TR>
+ <TD>TempDir</TD>
+ <TD>/var/tmp</TD>
+ <TD>Specifies the temporary directory to use.</TD>
+</TR>
+<TR>
+ <TD>Timeout</TD>
+ <TD>300</TD>
+ <TD>The timeout in seconds before client connections are closed
+ in the middle of a request.</TD>
+</TR>
+<TR>
+ <TD>User</TD>
+ <TD>lp</TD>
+ <TD>Specifies the user that is used when running external programs.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>printers.conf</H3>
+
+<P>The printers.conf file consists of 1 or more lines of ASCII text.
+Comment lines start with the pound ("#") character.
+
+<P>Each non-blank line starts with the name of a configuration directive
+followed by its value. The following directives are understood:
+
+<CENTER><TABLE WIDTH="90%" BORDER="1">
+<TR>
+ <TH WIDTH="25%">Directive</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>Accepting</TD>
+ <TD>Specifies whether the printer is accepting new jobs. May be
+ the names "Yes" or "No".</TD>
+</TR>
+<TR>
+ <TD>&lt;DefaultPrinter name&gt;<BR>
+ &lt;/Printer&gt;</TD>
+ <TD>Surrounds the printer definition for a default destination.</TD>
+</TR>
+<TR>
+ <TD>AllowUsers</TD>
+ <TD>Specifies a list of users that are allowed to access the printer.</TD>
+</TR>
+<TR>
+ <TD>BannerStart</TD>
+ <TD>Specifies the banner that is printed before other files in a
+ job.</TD>
+</TR>
+<TR>
+ <TD>BannerEnd</TD>
+ <TD>Specifies the banner that is printed after other files in a
+ job.</TD>
+</TR>
+<TR>
+ <TD>DenyUsers</TD>
+ <TD>Specifies a list of users that are not allowed to access the
+ printer.</TD>
+</TR>
+<TR>
+ <TD>DeviceURI</TD>
+ <TD>Specifies the device-uri attribute for the printer.</TD>
+</TR>
+<TR>
+ <TD>Info</TD>
+ <TD>A textual description of the printer.</TD>
+</TR>
+<TR>
+ <TD>Location</TD>
+ <TD>A textual location of the printer.</TD>
+</TR>
+<TR>
+ <TD>&lt;Printer name&gt;<BR>
+ &lt;/Printer&gt;</TD>
+ <TD>Surrounds the printer definition.</TD>
+</TR>
+<TR>
+ <TD>State</TD>
+ <TD>Specifies the initial state of the printer; can be "Idle" or
+ "Stopped".</TD>
+</TR>
+<TR>
+ <TD>StateMessage</TD>
+ <TD>Specifies a textual message for the current printer state.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H1>External Interfaces</H1>
+
+<H2>AppSocket Protocol</H2>
+
+<P>The AppSocket protocol is an 8-bit clean TCP/IP socket connection.
+The default IP service port is 9100. The URI method name is "socket".
+
+<P>The AppSocket protocol is used by the Hewlett Packard JetDirect
+network interfaces and print servers, as well as many other vendors'
+products. See the CUPS Software Administrators Manual for a list of
+supported products.
+
+<H2>CUPS Browsing Protocol</H2>
+
+<P>The CUPS Browsing Protocol is a UDP/IP-based broadcast service. By default
+this service operates on IP service port 631.
+
+<P>Each broadcast packet describes the state of a single printer or class and
+is an ASCII text string of up to 1450 bytes ending with a newline (0x0a). The
+string is formatted as follows:
+
+<UL><PRE>
+type SP state SP uri SP "location" SP "info" SP "make-and-model" NL
+</PRE></UL>
+
+<P><VAR>State, uri, location, info</VAR>, and <VAR>make-and-model</VAR>,
+correspond to the IPP <CODE>printer-state</CODE>,
+<CODE>printer-uri-supported</CODE>, <CODE>printer-location</CODE>,
+<CODE>printer-info</CODE>, and <CODE>printer-make-and-model</CODE>
+attributes.
+
+<P><VAR>Type</VAR> is a hexadecimal number string representing
+capability/type bits:
+
+<CENTER><TABLE WIDTH="40%" BORDER="1">
+<TR>
+ <TH WIDTH="8%">Bit</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>0</TD>
+ <TD>0 = printer<BR>
+ 1 = class</TD>
+</TR>
+<TR>
+ <TD>1</TD>
+ <TD>0 = local<BR>
+ 1 = remote<BR>
+ (always 1)</TD>
+</TR>
+<TR>
+ <TD>2</TD>
+ <TD>1 = can print B&W</TD>
+</TR>
+<TR>
+ <TD>3</TD>
+ <TD>1 = can print color</TD>
+</TR>
+<TR>
+ <TD>4</TD>
+ <TD>1 = can duplex</TD>
+</TR>
+<TR>
+ <TD>5</TD>
+ <TD>1 = can staple</TD>
+</TR>
+<TR>
+ <TD>6</TD>
+ <TD>1 = can do fast copies</TD>
+</TR>
+<TR>
+ <TD>7</TD>
+ <TD>1 = can do fast collating</TD>
+</TR>
+<TR>
+ <TD>8</TD>
+ <TD>1 = can punch holes</TD>
+</TR>
+<TR>
+ <TD>9</TD>
+ <TD>1 = can cover</TD>
+</TR>
+<TR>
+ <TD>10</TD>
+ <TD>1 = can bind</TD>
+</TR>
+<TR>
+ <TD>11</TD>
+ <TD>1 = can sort</TD>
+</TR>
+<TR>
+ <TD>12</TD>
+ <TD>1 = can print up to 9x14 inches</TD>
+</TR>
+<TR>
+ <TD>13</TD>
+ <TD>1 = can print up to 18x24 inches</TD>
+</TR>
+<TR>
+ <TD>14</TD>
+ <TD>1 = can print up to 36x48 inches</TD>
+</TR>
+<TR>
+ <TD>15</TD>
+ <TD>1 = can print variable sizes</TD>
+</TR>
+</TABLE></CENTER>
+
+<H2>CUPS Form File</H2>
+
+<P>CUPS Form files are XML files used by the CUPS <CODE>formtops</CODE>
+filter to produce dynamic banner pages and support preprinted forms.
+
+<P>The MIME type for CUPS Form files is
+<CODE>application/vnd.cups-form</CODE>.
+
+<H3>CUPS Form DTD</H3>
+
+<P>The following DTD describes the available elements and attributes in
+a CUPS Form file:
+
+<CENTER><TABLE BORDER>
+<TR>
+<TD><PRE>
+&lt;!ENTITY % Angle "CDATA" -- angle in degrees -->
+
+&lt;!ENTITY % Color "CDATA" -- a color using sRGB: #RRGGBB as Hex values -->
+
+&lt;!ENTITY % Length "CDATA" -- nn for pixels or nn% for percentage length -->
+
+&lt;!ENTITY % Lengths "CDATA" -- comma-separated Length values -->
+
+&lt;!ENTITY % Text "CDATA">
+
+&lt;!ENTITY % heading "H1|H2|H3|H4|H5|H6">
+
+&lt;!ENTITY % preformatted "PRE">
+
+&lt;!ENTITY % i18n
+ "lang %LanguageCode; #IMPLIED -- language code --
+ dir (ltr|rtl) #IMPLIED -- direction for weak/neutral text --"
+ >
+
+&lt;!ENTITY % attrs "%i18n;">
+
+&lt;!ENTITY % fontstyle
+ "B | FONT | I | TT">
+
+&lt;!ENTITY % graphics
+ "BOX | RECT | LINE | POLY | ARC | PIE | TEXT">
+
+&lt;!ENTITY % insert
+ "IMG | VAR">
+
+&lt;!-- %inline; covers inline or "text-level" elements -->
+&lt;!ENTITY % inline "#PCDATA | %fontstyle; | %graphics; | %insert;">
+
+&lt;!ELEMENT (%fontstyle;) - - (%inline;)*>
+&lt;!ATTLIST (%fontstyle;)
+ %attrs; -- %i18n --
+ >
+
+&lt;!ELEMENT BR - O EMPTY -- forced line break -->
+&lt;!ATTLIST BR
+ %attrs; -- %i18n --
+ >
+
+&lt;!ENTITY % block
+ "P | %heading; | %preformatted;">
+
+&lt;!ENTITY % flow "%block; | %inline;">
+
+&lt;!ELEMENT PAGE O O (%flow;)+ -- document body -->
+&lt;!ATTLIST PAGE
+ %attrs; -- %i18n --
+ align (left|center|right) #IMPLIED -- horizontal alignment --
+ valign (top|middle|center|bottom) #IMPLIED -- vertical alignment --
+ >
+
+&lt;!ELEMENT P - O (%inline;)* -- paragraph -->
+&lt;!ATTLIST P
+ %attrs; -- %i18n --
+ align (left|center|right) #IMPLIED -- horizontal alignment --
+ >
+
+&lt;!ELEMENT (%heading;) - - (%inline;)* -- heading -->
+&lt;!ATTLIST (%heading;)
+ %attrs; -- %i18n --
+ align (left|center|right) #IMPLIED -- horizontal alignment --
+ >
+
+&lt;!ELEMENT PRE - - (%inline;)* -- preformatted text -->
+&lt;!ATTLIST PRE
+ %attrs; -- %i18n --
+ align (left|center|right) #IMPLIED -- horizontal alignment --
+ >
+
+&lt;!ELEMENT BOX - O EMPTY -- unfilled box -->
+&lt;!ATTLIST BOX
+ color %Color; #IMPLIED -- override color --
+ height %Length; #REQUIRED -- height of box --
+ thickness %Length; #IMPLIED -- override line thickness --
+ width %Length; #REQUIRED -- width of box --
+ x %Length; #REQUIRED -- horizontal position --
+ y %Length; #REQUIRED -- vertical position --
+ >
+
+&lt;!ELEMENT RECT - O EMPTY -- filled box -->
+&lt;!ATTLIST RECT
+ color %Color; #IMPLIED -- override color --
+ height %Length; #REQUIRED -- height of box --
+ width %Length; #REQUIRED -- width of box --
+ x %Length; #REQUIRED -- horizontal position --
+ y %Length; #REQUIRED -- vertical position --
+ >
+
+&lt;!ELEMENT LINE - O EMPTY -- polyline -->
+&lt;!ATTLIST LINE
+ color %Color; #IMPLIED -- override color --
+ thickness %Length; #IMPLIED -- override line thickness --
+ x %Lengths; #REQUIRED -- horizontal positions --
+ y %Lengths; #REQUIRED -- vertical positions --
+ >
+
+&lt;!ELEMENT POLY - O EMPTY -- polygon (filled) -->
+&lt;!ATTLIST POLY
+ color %Color; #IMPLIED -- override color --
+ x %Lengths; #REQUIRED -- horizontal positions --
+ y %Lengths; #REQUIRED -- vertical positions --
+ >
+
+&lt;!ELEMENT ARC - O EMPTY -- unfilled arc -->
+&lt;!ATTLIST ARC
+ color %Color; #IMPLIED -- override color --
+ end %Angle; #IMPLIED -- override end angle --
+ height %Length; #REQUIRED -- height of arc --
+ start %Angle; #IMPLIED -- override start angle --
+ thickness %Length; #IMPLIED -- override line thickness --
+ width %Length; #REQUIRED -- width of arc --
+ x %Length; #REQUIRED -- horizontal position --
+ y %Length; #REQUIRED -- vertical position --
+ >
+
+&lt;!ELEMENT PIE - O EMPTY -- filled arc -->
+&lt;!ATTLIST PIE
+ color %Color; #IMPLIED -- override color --
+ end %Angle; #IMPLIED -- override end angle --
+ height %Length; #REQUIRED -- height of arc --
+ start %Angle; #IMPLIED -- override start angle --
+ width %Length; #REQUIRED -- width of arc --
+ x %Length; #REQUIRED -- horizontal position --
+ y %Length; #REQUIRED -- vertical position --
+ >
+
+&lt;!ELEMENT TEXT - - (%flow;)* -- text box -->
+&lt;!ATTLIST RECT
+ align (left|center|right) #IMPLIED -- horizontal alignment --
+ height %Length; #REQUIRED -- height of box --
+ valign (top|middle|center|bottom) #IMPLIED -- vertical alignment --
+ width %Length; #REQUIRED -- width of box --
+ x %Length; #REQUIRED -- horizontal position --
+ y %Length; #REQUIRED -- vertical position --
+ >
+
+
+&lt;!ELEMENT IMG - O EMPTY -- Embedded image -->
+&lt;!ATTLIST IMG
+ %attrs; -- %coreattrs, %i18n, %events --
+ src %URI; #REQUIRED -- URI of image to embed --
+ height %Length; #IMPLIED -- override height --
+ width %Length; #IMPLIED -- override width --
+ >
+
+&lt;!ELEMENT HEAD O O (DEFVAR)* -- document head -->
+&lt;!ATTLIST HEAD
+ %i18n; -- lang, dir --
+ >
+
+&lt;!ELEMENT DEFVAR - O EMPTY -- variable definition -->
+&lt;!ATTLIST DEFVAR
+ name CDATA #REQUIRED -- name
+ value CDATA #REQUIRED -- value
+ >
+
+
+&lt;!ENTITY % html.content "HEAD, PAGE">
+
+&lt;!ELEMENT CUPSFORM - - (HEAD) (PAGE)+ -- document root element -->
+&lt;!ATTLIST CUPSFORM
+ %i18n; -- lang, dir --
+ >
+</PRE></TD>
+</TR>
+</TABLE></CENTER>
+
+<H2>CUPS PostScript File</H2>
+
+<P>CUPS PostScript files are device-dependent Adobe PostScript program files.
+The PostScript language is described in the
+<A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
+Adobe PostScript Language Reference Manual, Third Edition</A>.
+
+<P>The MIME type for CUPS PostScript files is
+<CODE>application/vnd.cups-postscript</CODE>.
+
+<H2>CUPS Raster File</H2>
+
+<P>CUPS raster files are device-dependent raster image files that contain a
+PostScript page device dictionary and device-dependent raster imagery for
+each page in the document. These files are used to transfer raster data
+from the PostScript and image file RIPs to device-dependent filters that
+convert the raster data to a printable format.
+
+<P>A raster file begins with a four byte synchronization word: 0x52615374
+("RaSt") for big-endian architectures and 0x74536152 ("tSaR") for little-endian
+architectures. The writer of the raster file will use the native word order,
+and the reader is responsible for detecting a reversed word order file and
+swapping bytes as needed. The CUPS Image Library raster functions perform
+this function automatically.
+
+<P>Following the synchronization word are a series of raster pages. Each page
+starts with a page device dictionary header and is followed immediately by the
+raster data for that page.
+
+<CENTER><TABLE WIDTH="80%" BORDER="1">
+<TR>
+ <TH WIDTH="10%">Bytes</TH>
+ <TH WIDTH="20%">Description</TH>
+ <TH>Values</TH>
+</TR>
+<TR>
+ <TD>0-63</TD>
+ <TD>MediaClass</TD>
+ <TD>Nul-terminated ASCII string</TD>
+</TR>
+<TR>
+ <TD>64-127</TD>
+ <TD>MediaColor</TD>
+ <TD>Nul-terminated ASCII string</TD>
+</TR>
+<TR>
+ <TD>128-191</TD>
+ <TD>MediaType</TD>
+ <TD>Nul-terminated ASCII string</TD>
+</TR>
+<TR>
+ <TD>192-255</TD>
+ <TD>OutputType</TD>
+ <TD>Nul-terminated ASCII string</TD>
+</TR>
+<TR>
+ <TD>256-259</TD>
+ <TD>AdvanceDistance</TD>
+ <TD>0 to 2<SUP>32</SUP> - 1 points</TD>
+</TR>
+<TR>
+ <TD>260-263</TD>
+ <TD>AdvanceMedia</TD>
+ <TD>0 = Never advance roll<BR>
+ 1 = Advance roll after file<BR>
+ 2 = Advance roll after job<BR>
+ 3 = Advance roll after set<BR>
+ 4 = Advance roll after page</TD>
+</TR>
+<TR>
+ <TD>264-267</TD>
+ <TD>Collate</TD>
+ <TD>0 = do not collate copies<BR>
+ 1 = collate copies</TD>
+</TR>
+<TR>
+ <TD>268-271</TD>
+ <TD>CutMedia</TD>
+ <TD>0 = Never cut media<BR>
+ 1 = Cut roll after file<BR>
+ 2 = Cut roll after job<BR>
+ 3 = Cut roll after set<BR>
+ 4 = Cut roll after page</TD>
+</TR>
+<TR>
+ <TD>272-275</TD>
+ <TD>Duplex</TD>
+ <TD>0 = Print single-sided<BR>
+ 1 = Print double-sided</TD>
+</TR>
+<TR>
+ <TD>276-283</TD>
+ <TD>HWResolution</TD>
+ <TD>Horizontal and vertical resolution in dots-per-inch.</TD>
+</TR>
+<TR>
+ <TD>284-299</TD>
+ <TD>ImagingBoundingBox</TD>
+ <TD>Four integers giving the left, bottom, right, and top positions
+ of the page bounding box in points</TD>
+</TR>
+<TR>
+ <TD>300-303</TD>
+ <TD>InsertSheet</TD>
+ <TD>0 = Do not insert separator sheets<BR>
+ 1 = Insert separator sheets</TD>
+</TR>
+<TR>
+ <TD>304-307</TD>
+ <TD>Jog</TD>
+ <TD>0 = Do no jog pages<BR>
+ 1 = Jog pages after file<BR>
+ 2 = Jog pages after job<BR>
+ 3 = Jog pages after set</TD>
+</TR>
+<TR>
+ <TD>308-311</TD>
+ <TD>LeadingEdge</TD>
+ <TD>0 = Top edge is first<BR>
+ 1 = Right edge is first<BR>
+ 2 = Bottom edge is first<BR>
+ 3 = Left edge is first</TD>
+</TR>
+<TR>
+ <TD>312-319</TD>
+ <TD>Margins</TD>
+ <TD>Left and bottom origin of image in points</TD>
+</TR>
+<TR>
+ <TD>320-323</TD>
+ <TD>ManualFeed</TD>
+ <TD>0 = Do not manually feed media<BR>
+ 1 = Manually feed media</TD>
+</TR>
+<TR>
+ <TD>324-327</TD>
+ <TD>MediaPosition</TD>
+ <TD>Input slot position from 0 to N</TD>
+</TR>
+<TR>
+ <TD>328-331</TD>
+ <TD>MediaWeight</TD>
+ <TD>Media weight in grams per meter squared</TD>
+</TR>
+<TR>
+ <TD>332-335</TD>
+ <TD>MirrorPrint</TD>
+ <TD>0 = Do not mirror prints<BR>
+ 1 = Mirror prints</TD>
+</TR>
+<TR>
+ <TD>336-339</TD>
+ <TD>NegativePrint</TD>
+ <TD>0 = Do not invert prints<BR>
+ 1 = Invert prints</TD>
+</TR>
+<TR>
+ <TD>340-343</TD>
+ <TD>NumCopies</TD>
+ <TD>1 to 2<SUP>32</SUP> - 1</TD>
+</TR>
+<TR>
+ <TD>344-347</TD>
+ <TD>Orientation</TD>
+ <TD>0 = Do not rotate page<BR>
+ 1 = Rotate page counter-clockwise<BR>
+ 2 = Turn page upside down<BR>
+ 3 = Rotate page clockwise</TD>
+</TR>
+<TR>
+ <TD>348-351</TD>
+ <TD>OutputFaceUp</TD>
+ <TD>0 = Output face down<BR>
+ 1 = Output face up</TD>
+</TR>
+<TR>
+ <TD>352-359</TD>
+ <TD>PageSize</TD>
+ <TD>Width and length in points</TD>
+</TR>
+<TR>
+ <TD>360-363</TD>
+ <TD>Separations</TD>
+ <TD>0 = Print composite image<BR>
+ 1 = Print color separations</TD>
+</TR>
+<TR>
+ <TD>364-367</TD>
+ <TD>TraySwitch</TD>
+ <TD>0 = Do not change trays if selected tray is empty<BR>
+ 1 = Change trays if selected tray is empty</TD>
+</TR>
+<TR>
+ <TD>368-371</TD>
+ <TD>Tumble</TD>
+ <TD>0 = Do not rotate even pages when duplexing<BR>
+ 1 = Rotate even pages when duplexing</TD>
+</TR>
+<TR>
+ <TD>372-375</TD>
+ <TD>cupsWidth</TD>
+ <TD>Width of page image in pixels</TD>
+</TR>
+<TR>
+ <TD>376-379</TD>
+ <TD>cupsHeight</TD>
+ <TD>Height of page image in pixels</TD>
+</TR>
+<TR>
+ <TD>380-383</TD>
+ <TD>cupsMediaType</TD>
+ <TD>Driver-specific 0 to 2<SUP>32</SUP> - 1</TD>
+</TR>
+<TR>
+ <TD>384-387</TD>
+ <TD>cupsBitsPerColor</TD>
+ <TD>1, 2, 4, 8 bits</TD>
+</TR>
+<TR>
+ <TD>388-391</TD>
+ <TD>cupsBitsPerPixel</TD>
+ <TD>1 to 32 bits</TD>
+</TR>
+<TR>
+ <TD>392-395</TD>
+ <TD>cupsBytesPerLine</TD>
+ <TD>1 to 2<SUP>32</SUP> - 1 bytes</TD>
+</TR>
+<TR>
+ <TD>396-399</TD>
+ <TD>cupsColorOrder</TD>
+ <TD>0 = chunky pixels (CMYK CMYK CMYK)<BR>
+ 1 = banded pixels (CCC MMM YYY KKK)<BR>
+ 2 = planar pixels (CCC... MMM... YYY... KKK...)</TD>
+</TR>
+<TR>
+ <TD>400-403</TD>
+ <TD>cupsColorSpace</TD>
+ <TD>0 = white<BR>
+ 1 = RGB<BR>
+ 2 = RGBA<BR>
+ 3 = black<BR>
+ 4 = CMY<BR>
+ 5 = YMC<BR>
+ 6 = CMYK<BR>
+ 7 = YMCK<BR>
+ 8 = KCMY<BR>
+ 9 = KCMYcm</TD>
+</TR>
+<TR>
+ <TD>404-407</TD>
+ <TD>cupsCompression</TD>
+ <TD>Driver-specific 0 to 2<SUP>32</SUP> - 1</TD>
+</TR>
+<TR>
+ <TD>408-411</TD>
+ <TD>cupsRowCount</TD>
+ <TD>Driver-specific 0 to 2<SUP>32</SUP> - 1</TD>
+</TR>
+<TR>
+ <TD>412-415</TD>
+ <TD>cupsRowFeed</TD>
+ <TD>Driver-specific 0 to 2<SUP>32</SUP> - 1</TD>
+</TR>
+<TR>
+ <TD>416-419</TD>
+ <TD>cupsRowStep</TD>
+ <TD>Driver-specific 0 to 2<SUP>32</SUP> - 1</TD>
+</TR>
+</TABLE></CENTER>
+
+<P>The MIME type for CUPS Raster files is
+<CODE>application/vnd.cups-raster</CODE>.
+
+<H2>CUPS Raw Files</H2>
+
+<P>Raw files are printer-dependent print files that are in a format suitable
+to the destination printer (e.g. HP-PCL, HP-RTL, etc.) The MIME type for CUPS
+Raw files is <CODE>application/vnd.cups-raw</CODE>.
+
+<H2>Internet Printing Protocol</H2>
+
+<P>The Internet Printing Protocol and the CUPS extensions to it are
+described in the CUPS Implementation of IPP document.
+
+<H2>Line Printer Daemon Protocol</H2>
+
+<P>The Line Printer Daemon (LPD) protocol is described by
+<A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179: Line Printer Daemon
+Protocol</A>.
+
+<P>The URI method name for LPD is "lpd".
+
+<H2>Server Message Block Protocol</H2>
+
+<P>The Server Message Block (SMB) and related Common Internet File
+System (CIFS) protocols are described at
+<A HREF="http://anu.samba.org/cifs">http://anu.samba.org/cifs</A>.
+
+<P>The URI method name for SMB is "smb". Support for this protocol is
+provided via the SAMBA <CODE>smbspool(1)</CODE> program provided with
+SAMBA 2.0.6 and higher.
+
+<H1>Directories</H1>
+
+<DL>
+
+ <DT>/etc/cups
+ <DD>The scheduler configuration and MIME files reside here.
+
+ <DT>/etc/cups/certs
+ <DD>The authentication certificates reside here.
+
+ <DT>/etc/cups/interfaces
+ <DD>System V interface scripts reside here.
+
+ <DT>/etc/cups/ppd
+ <DD>This directory contains PPD files for each printer.
+
+ <DT>/usr/bin
+ <DD>The <CODE>cancel</CODE>, <CODE>lp</CODE>, <CODE>lpq</CODE>,
+ <CODE>lpr</CODE>, <CODE>lprm</CODE>, and <CODE>lpstat</CODE> commands
+ reside here.
+
+ <DT>/usr/lib, /usr/lib32
+ <DD>The shared libraries (DSOs) reside here.
+
+ <DT>/usr/lib/cups/backend
+ <DD>The backend filters reside here.
+
+ <DT>/usr/lib/cups/cgi-bin
+ <DD>The CGI programs reside here.
+
+ <DT>/usr/lib/cups/daemon
+ <DD>The polling and LPD daemons reside here.
+
+ <DT>/usr/lib/cups/filter
+ <DD>The file filters reside here.
+
+ <DT>/usr/sbin
+ <DD>The <CODE>accept</CODE>, <CODE>cupsd</CODE>,
+ <CODE>lpadmin</CODE>, <CODE>lpc</CODE>, and <CODE>reject</CODE>
+ commands reside here.
+
+ <DT>/usr/share/cups
+ <DD>This is the root directory of the CUPS static data.
+
+ <DT>/usr/share/cups/charsets
+ <DD>The character set files reside here.
+
+ <DT>/usr/share/cups/data
+ <DD>The filter data files reside here.
+
+ <DT>/usr/share/cups/fonts
+ <DD>The <CODE>pstoraster</CODE> font files reside here.
+
+ <DT>/usr/share/cups/model
+ <DD>The sample PPD files reside here.
+
+ <DT>/usr/share/cups/pstoraster
+ <DD>The <CODE>pstoraster</CODE> data files reside here.
+
+ <DT>/usr/share/doc/cups
+ <DD>The scheduler documentation files reside here.
+
+ <DT>/var/log/cups
+ <DD>The <CODE>access_log</CODE>, <CODE>error_log</CODE>, and
+ <CODE>page_log</CODE> files reside here.
+
+ <DT>/var/spool/cups
+ <DD>This directory contains print job files.
+
+</DL>
+
+<EMBED SRC="glossary.shtml">
+
+</BODY>
+</HTML>
diff --git a/doc/images/accept-jobs.gif b/doc/images/accept-jobs.gif
new file mode 100644
index 000000000..9da7a0dce
--- /dev/null
+++ b/doc/images/accept-jobs.gif
Binary files differ
diff --git a/doc/images/add-class.gif b/doc/images/add-class.gif
new file mode 100644
index 000000000..0f43a6fcd
--- /dev/null
+++ b/doc/images/add-class.gif
Binary files differ
diff --git a/doc/images/add-printer.gif b/doc/images/add-printer.gif
new file mode 100644
index 000000000..90d17eb3f
--- /dev/null
+++ b/doc/images/add-printer.gif
Binary files differ
diff --git a/doc/images/cancel-job.gif b/doc/images/cancel-job.gif
new file mode 100644
index 000000000..3cc1e23bc
--- /dev/null
+++ b/doc/images/cancel-job.gif
Binary files differ
diff --git a/doc/images/cancel-jobs.gif b/doc/images/cancel-jobs.gif
new file mode 100644
index 000000000..2384b903c
--- /dev/null
+++ b/doc/images/cancel-jobs.gif
Binary files differ
diff --git a/doc/images/cancel.gif b/doc/images/cancel.gif
new file mode 100644
index 000000000..e99460678
--- /dev/null
+++ b/doc/images/cancel.gif
Binary files differ
diff --git a/doc/images/classes.gif b/doc/images/classes.gif
new file mode 100644
index 000000000..ace15df98
--- /dev/null
+++ b/doc/images/classes.gif
Binary files differ
diff --git a/doc/images/config-printer.gif b/doc/images/config-printer.gif
new file mode 100644
index 000000000..22849db7d
--- /dev/null
+++ b/doc/images/config-printer.gif
Binary files differ
diff --git a/doc/images/continue.gif b/doc/images/continue.gif
new file mode 100644
index 000000000..ff774adb3
--- /dev/null
+++ b/doc/images/continue.gif
Binary files differ
diff --git a/doc/images/cups-block-diagram.gif b/doc/images/cups-block-diagram.gif
new file mode 100644
index 000000000..2fe505e44
--- /dev/null
+++ b/doc/images/cups-block-diagram.gif
Binary files differ
diff --git a/doc/images/cups-large.gif b/doc/images/cups-large.gif
new file mode 100644
index 000000000..fc66ef07c
--- /dev/null
+++ b/doc/images/cups-large.gif
Binary files differ
diff --git a/doc/images/cups-medium.gif b/doc/images/cups-medium.gif
new file mode 100644
index 000000000..c45ed6ab9
--- /dev/null
+++ b/doc/images/cups-medium.gif
Binary files differ
diff --git a/doc/images/cups-small.gif b/doc/images/cups-small.gif
new file mode 100644
index 000000000..6adb4a29f
--- /dev/null
+++ b/doc/images/cups-small.gif
Binary files differ
diff --git a/doc/images/delete-class.gif b/doc/images/delete-class.gif
new file mode 100644
index 000000000..81b1465ac
--- /dev/null
+++ b/doc/images/delete-class.gif
Binary files differ
diff --git a/doc/images/delete-printer.gif b/doc/images/delete-printer.gif
new file mode 100644
index 000000000..41ce85d78
--- /dev/null
+++ b/doc/images/delete-printer.gif
Binary files differ
diff --git a/doc/images/draft.gif b/doc/images/draft.gif
new file mode 100644
index 000000000..77d9716ab
--- /dev/null
+++ b/doc/images/draft.gif
Binary files differ
diff --git a/doc/images/hold-job.gif b/doc/images/hold-job.gif
new file mode 100644
index 000000000..ebd448ae9
--- /dev/null
+++ b/doc/images/hold-job.gif
Binary files differ
diff --git a/doc/images/left.gif b/doc/images/left.gif
new file mode 100644
index 000000000..fd7b04104
--- /dev/null
+++ b/doc/images/left.gif
Binary files differ
diff --git a/doc/images/logo.gif b/doc/images/logo.gif
new file mode 100644
index 000000000..9999795ca
--- /dev/null
+++ b/doc/images/logo.gif
Binary files differ
diff --git a/doc/images/manage-classes.gif b/doc/images/manage-classes.gif
new file mode 100644
index 000000000..69d5b0147
--- /dev/null
+++ b/doc/images/manage-classes.gif
Binary files differ
diff --git a/doc/images/manage-jobs.gif b/doc/images/manage-jobs.gif
new file mode 100644
index 000000000..adaff856f
--- /dev/null
+++ b/doc/images/manage-jobs.gif
Binary files differ
diff --git a/doc/images/manage-printers.gif b/doc/images/manage-printers.gif
new file mode 100644
index 000000000..cd897291d
--- /dev/null
+++ b/doc/images/manage-printers.gif
Binary files differ
diff --git a/doc/images/modify-class.gif b/doc/images/modify-class.gif
new file mode 100644
index 000000000..58a0ead82
--- /dev/null
+++ b/doc/images/modify-class.gif
Binary files differ
diff --git a/doc/images/modify-printer.gif b/doc/images/modify-printer.gif
new file mode 100644
index 000000000..593b5f881
--- /dev/null
+++ b/doc/images/modify-printer.gif
Binary files differ
diff --git a/doc/images/navbar.gif b/doc/images/navbar.gif
new file mode 100644
index 000000000..c19f634c0
--- /dev/null
+++ b/doc/images/navbar.gif
Binary files differ
diff --git a/doc/images/navbar.xcf.gz b/doc/images/navbar.xcf.gz
new file mode 100644
index 000000000..28438a6bb
--- /dev/null
+++ b/doc/images/navbar.xcf.gz
Binary files differ
diff --git a/doc/images/print-test-page.gif b/doc/images/print-test-page.gif
new file mode 100644
index 000000000..807dca10e
--- /dev/null
+++ b/doc/images/print-test-page.gif
Binary files differ
diff --git a/doc/images/printer-idle.gif b/doc/images/printer-idle.gif
new file mode 100644
index 000000000..68d990c62
--- /dev/null
+++ b/doc/images/printer-idle.gif
Binary files differ
diff --git a/doc/images/printer-processing.gif b/doc/images/printer-processing.gif
new file mode 100644
index 000000000..a9a23f795
--- /dev/null
+++ b/doc/images/printer-processing.gif
Binary files differ
diff --git a/doc/images/printer-stopped.gif b/doc/images/printer-stopped.gif
new file mode 100644
index 000000000..76f45649b
--- /dev/null
+++ b/doc/images/printer-stopped.gif
Binary files differ
diff --git a/doc/images/reject-jobs.gif b/doc/images/reject-jobs.gif
new file mode 100644
index 000000000..6d938e308
--- /dev/null
+++ b/doc/images/reject-jobs.gif
Binary files differ
diff --git a/doc/images/release-job.gif b/doc/images/release-job.gif
new file mode 100644
index 000000000..a05cd9cc7
--- /dev/null
+++ b/doc/images/release-job.gif
Binary files differ
diff --git a/doc/images/restart-job.gif b/doc/images/restart-job.gif
new file mode 100644
index 000000000..a007efc5b
--- /dev/null
+++ b/doc/images/restart-job.gif
Binary files differ
diff --git a/doc/images/right.gif b/doc/images/right.gif
new file mode 100644
index 000000000..8ae8213ce
--- /dev/null
+++ b/doc/images/right.gif
Binary files differ
diff --git a/doc/images/show-active.gif b/doc/images/show-active.gif
new file mode 100644
index 000000000..d232ef9f8
--- /dev/null
+++ b/doc/images/show-active.gif
Binary files differ
diff --git a/doc/images/show-completed.gif b/doc/images/show-completed.gif
new file mode 100644
index 000000000..efd206cd5
--- /dev/null
+++ b/doc/images/show-completed.gif
Binary files differ
diff --git a/doc/images/start-class.gif b/doc/images/start-class.gif
new file mode 100644
index 000000000..2b6f43fad
--- /dev/null
+++ b/doc/images/start-class.gif
Binary files differ
diff --git a/doc/images/start-printer.gif b/doc/images/start-printer.gif
new file mode 100644
index 000000000..017bb394a
--- /dev/null
+++ b/doc/images/start-printer.gif
Binary files differ
diff --git a/doc/images/stop-class.gif b/doc/images/stop-class.gif
new file mode 100644
index 000000000..5cb7adfd8
--- /dev/null
+++ b/doc/images/stop-class.gif
Binary files differ
diff --git a/doc/images/stop-printer.gif b/doc/images/stop-printer.gif
new file mode 100644
index 000000000..b3accf3df
--- /dev/null
+++ b/doc/images/stop-printer.gif
Binary files differ
diff --git a/doc/index.html b/doc/index.html
new file mode 100644
index 000000000..051abb5b8
--- /dev/null
+++ b/doc/index.html
@@ -0,0 +1,36 @@
+<HTML>
+<HEAD>
+ <TITLE>Common UNIX Printing System</TITLE>
+ <LINK REL=STYLESHEET TYPE="text/css" HREF="cups.css">
+ <MAP NAME="navbar">
+ <AREA SHAPE="RECT" COORDS="12,10,50,20" HREF="http://www.easysw.com" ALT="Easy Software Products Home Page">
+ <AREA SHAPE="RECT" COORDS="82,10,196,20" HREF="/admin" ALT="Do Administration Tasks">
+ <AREA SHAPE="RECT" COORDS="216,10,280,20" HREF="/classes" ALT="Manage Printer Classes Status">
+ <AREA SHAPE="RECT" COORDS="300,10,336,20" HREF="/documentation.html" ALT="On-Line Help">
+ <AREA SHAPE="RECT" COORDS="356,10,394,20" HREF="/jobs" ALT="Manage Jobs">
+ <AREA SHAPE="RECT" COORDS="414,10,476,20" HREF="/printers" ALT="Manage Printers">
+ <AREA SHAPE="RECT" COORDS="496,10,568,20" HREF="http://www.cups.org" ALT="Download the Current CUPS Software">
+ </MAP>
+</HEAD>
+
+<BODY BGCOLOR="#cccc99" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF">
+<CENTER>
+<IMG SRC="/images/navbar.gif" WIDTH="583" HEIGHT="30" USEMAP="#navbar" BORDER="0" ALT="Common UNIX Printing System">
+</CENTER>
+
+<H1><A HREF="admin">Do Administration Tasks</A></H1>
+<H1><A HREF="classes">Manage Printer Classes</A></H1>
+<H1><A HREF="documentation.html">On-Line Help</A></H1>
+<H1><A HREF="jobs">Manage Jobs</A></H1>
+<H1><A HREF="printers">Manage Printers</A></H1>
+<H1><A HREF="http://www.cups.org">Download the Current CUPS Software</A></H1>
+
+<HR>
+
+<P>The Common UNIX Printing System, CUPS, and the CUPS logo are the
+trademark property of <A HREF="http://www.easysw.com">Easy Software
+Products</A>. CUPS is copyright 1997-2002 by Easy Software Products,
+All Rights Reserved.
+
+</BODY>
+</HTML>
diff --git a/doc/ipp.html b/doc/ipp.html
new file mode 100644
index 000000000..c5a4ee8ce
--- /dev/null
+++ b/doc/ipp.html
@@ -0,0 +1,1478 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Implementation of IPP</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002 All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-IPP-1.1">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY>
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Implementation of IPP</H1></A><BR>
+CUPS-IPP-1.1<BR>
+Easy Software Products<BR>
+Copyright 1997-2002 All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">1 Scope</A></B>
+<UL>
+<LI><A HREF="#1_1">1.1 Identification</A></LI>
+<LI><A HREF="#1_2">1.2 System Overview</A></LI>
+<LI><A HREF="#1_3">1.3 Document Overview</A></LI>
+</UL>
+<B><A HREF="#2">2 References</A></B>
+<UL>
+<LI><A HREF="#2_1">2.1 CUPS Documentation</A></LI>
+<LI><A HREF="#2_2">2.2 Other Documents</A></LI>
+</UL>
+<B><A HREF="#3">3 Overview</A></B>
+<UL>
+<LI><A HREF="#3_1">3.1 IPP URIs</A></LI>
+<LI><A HREF="#3_2">3.2 CUPS IPP Operations</A></LI>
+</UL>
+<B><A HREF="#4">4 Operations</A></B>
+<UL>
+<LI><A HREF="#4_1">4.1 Print-Job Operation</A></LI>
+<UL>
+<LI><A HREF="#4_1_1">4.1.1 Print-Job Request</A></LI>
+<LI><A HREF="#4_1_2">4.1.2 Print-Job Response</A></LI>
+</UL>
+<LI><A HREF="#4_2">4.2 Create-Job Operation</A></LI>
+<UL>
+<LI><A HREF="#4_2_1">4.2.1 Create-Job Request</A></LI>
+<LI><A HREF="#4_2_2">4.2.2 Create-Job Response</A></LI>
+</UL>
+<LI><A HREF="#4_3">4.3 Set-Job-Attributes Operation</A></LI>
+<UL>
+<LI><A HREF="#4_3_1">4.3.1 Set-Job-Attributes Request</A></LI>
+<LI><A HREF="#4_3_2">4.3.2 Set-Job-Attributes Response</A></LI>
+</UL>
+<LI><A HREF="#4_4">4.4 CUPS-Get-Default Operation</A></LI>
+<UL>
+<LI><A HREF="#4_4_1">4.4.1 CUPS-Get-Default Request</A></LI>
+<LI><A HREF="#4_4_2">4.4.2 CUPS-Get-Default Response</A></LI>
+</UL>
+<LI><A HREF="#4_5">4.5 CUPS-Get-Printers Operation</A></LI>
+<UL>
+<LI><A HREF="#4_5_1">4.5.1 CUPS-Get-Printers Request</A></LI>
+<LI><A HREF="#4_5_2">4.5.2 CUPS-Get-Printers Response</A></LI>
+</UL>
+<LI><A HREF="#4_6">4.6 CUPS-Add-Modify-Printer Operation</A></LI>
+<UL>
+<LI><A HREF="#4_6_1">4.6.1 CUPS-Add-Modify-Printer Request</A></LI>
+<LI><A HREF="#4_6_2">4.6.2 CUPS-Add-Modify-Printer Response</A></LI>
+</UL>
+<LI><A HREF="#4_7">4.7 CUPS-Delete-Printer Operation</A></LI>
+<UL>
+<LI><A HREF="#4_7_1">4.7.1 CUPS-Delete-Printer Request</A></LI>
+<LI><A HREF="#4_7_2">4.7.2 CUPS-Delete-Printer Response</A></LI>
+</UL>
+<LI><A HREF="#4_8">4.8 CUPS-Get-Classes Operation</A></LI>
+<UL>
+<LI><A HREF="#4_8_1">4.8.1 CUPS-Get-Classes Request</A></LI>
+<LI><A HREF="#4_8_2">4.8.2 CUPS-Get-Classes Response</A></LI>
+</UL>
+<LI><A HREF="#4_9">4.9 CUPS-Add-Modify-Class Operation</A></LI>
+<UL>
+<LI><A HREF="#4_9_1">4.9.1 CUPS-Add-Modify-Class Request</A></LI>
+<LI><A HREF="#4_9_2">4.9.2 CUPS-Add-Modify-Class Response</A></LI>
+</UL>
+<LI><A HREF="#4_10">4.10 CUPS-Delete-Class Operation</A></LI>
+<UL>
+<LI><A HREF="#4_10_1">4.10.1 CUPS-Delete-Class Request</A></LI>
+<LI><A HREF="#4_10_2">4.10.2 CUPS-Delete-Class Response</A></LI>
+</UL>
+<LI><A HREF="#4_11">4.11 CUPS-Accept-Jobs Operation</A></LI>
+<UL>
+<LI><A HREF="#4_11_1">4.11.1 CUPS-Accept-Jobs Request</A></LI>
+<LI><A HREF="#4_11_2">4.11.2 CUPS-Accept-Jobs Response</A></LI>
+</UL>
+<LI><A HREF="#4_12">4.12 CUPS-Reject-Jobs Operation</A></LI>
+<UL>
+<LI><A HREF="#4_12_1">4.12.1 CUPS-Reject-Jobs Request</A></LI>
+<LI><A HREF="#4_12_2">4.12.2 CUPS-Reject-Jobs Response</A></LI>
+</UL>
+<LI><A HREF="#4_13">4.13 CUPS-Set-Default Operation</A></LI>
+<UL>
+<LI><A HREF="#4_13_1">4.13.1 CUPS-Set-Default Request</A></LI>
+<LI><A HREF="#4_13_2">4.13.2 CUPS-Set-Default Response</A></LI>
+</UL>
+<LI><A HREF="#4_14">4.14 CUPS-Get-Devices Operation</A></LI>
+<UL>
+<LI><A HREF="#4_14_1">4.14.1 CUPS-Get-Devices Request</A></LI>
+<LI><A HREF="#4_14_2">4.14.2 CUPS-Get-Devices Response</A></LI>
+</UL>
+<LI><A HREF="#4_15">4.15 CUPS-Get-PPDs Operation</A></LI>
+<UL>
+<LI><A HREF="#4_15_1">4.15.1 CUPS-Get-PPDs Request</A></LI>
+<LI><A HREF="#4_15_2">4.15.2 CUPS-Get-PPDs Response</A></LI>
+</UL>
+<LI><A HREF="#4_16">4.16 CUPS-Move-Job Operation</A></LI>
+<UL>
+<LI><A HREF="#4_16_1">4.16.1 CUPS-Move-Job Request</A></LI>
+<LI><A HREF="#4_16_2">4.16.2 CUPS-Move-Job Response</A></LI>
+</UL>
+</UL>
+<B><A HREF="#5">5 Attributes</A></B>
+<UL>
+<LI><A HREF="#5_1">5.1 Device Attributes</A></LI>
+<UL>
+<LI><A HREF="#5_1_1">5.1.1 device-class (type2 keyword)</A></LI>
+<LI><A HREF="#5_1_2">5.1.2 device-info (text(127))</A></LI>
+<LI><A HREF="#5_1_3">5.1.3 device-make-and-model (text(127))</A></LI>
+<LI><A HREF="#5_1_4">5.1.4 device-uri (uri)</A></LI>
+</UL>
+<LI><A HREF="#5_2">5.2 Job Template Attributes</A></LI>
+<UL>
+<LI><A HREF="#5_2_1">5.2.1 blackplot (boolean)</A></LI>
+<LI><A HREF="#5_2_2">5.2.2 brightness (integer(0:200))</A></LI>
+<LI><A HREF="#5_2_3">5.2.3 columns (integer(1:4))</A></LI>
+<LI><A HREF="#5_2_4">5.2.4 cpi (type2 enum)</A></LI>
+<LI><A HREF="#5_2_5">5.2.5 fitplot (boolean)</A></LI>
+<LI><A HREF="#5_2_6">5.2.6 gamma (integer(1:10000))</A></LI>
+<LI><A HREF="#5_2_7">5.2.7 hue (integer(-180:180))</A></LI>
+<LI><A HREF="#5_2_8">5.2.8 job-billing (text(MAX))</A></LI>
+<LI><A HREF="#5_2_9">5.2.9 job-hold-until (keyword | name(MAX))</A></LI>
+<LI><A HREF="#5_2_10">5.2.10 job-sheets (1setof type3 keyword |
+ name(MAX))</A></LI>
+<LI><A HREF="#5_2_11">5.2.11 job-originating-host-name (name(MAX))</A></LI>
+<LI><A HREF="#5_2_12">5.2.12 lpi (type2 enum)</A></LI>
+<LI><A HREF="#5_2_13">5.2.13 mirror (boolean)</A></LI>
+<LI><A HREF="#5_2_14">5.2.14 natural-scaling (integer(1:1000))</A></LI>
+<LI><A HREF="#5_2_15">5.2.15 number-up-layout (type2 keyword)</A></LI>
+<LI><A HREF="#5_2_16">5.2.16 page-border (type2 keyword)</A></LI>
+<LI><A HREF="#5_2_17">5.2.17 page-bottom (integer(0:MAX))</A></LI>
+<LI><A HREF="#5_2_18">5.2.18 page-label (text(MAX))</A></LI>
+<LI><A HREF="#5_2_19">5.2.19 page-left (integer(0:MAX))</A></LI>
+<LI><A HREF="#5_2_20">5.2.20 page-right (integer(0:MAX))</A></LI>
+<LI><A HREF="#5_2_21">5.2.21 page-set (type2 keyword)</A></LI>
+<LI><A HREF="#5_2_22">5.2.22 page-top (integer(0:MAX))</A></LI>
+<LI><A HREF="#5_2_23">5.2.23 penwidth (integer(0:MAX))</A></LI>
+<LI><A HREF="#5_2_24">5.2.24 position (type2 keyword)</A></LI>
+<LI><A HREF="#5_2_25">5.2.25 ppi (integer(1:MAX))</A></LI>
+<LI><A HREF="#5_2_26">5.2.26 prettyprint (boolean)</A></LI>
+<LI><A HREF="#5_2_27">5.2.27 saturation (integer(0:200))</A></LI>
+<LI><A HREF="#5_2_28">5.2.28 scaling (integer(1:1000))</A></LI>
+<LI><A HREF="#5_2_29">5.2.29 wrap (boolean)</A></LI>
+</UL>
+<LI><A HREF="#5_3">5.3 PPD Attributes</A></LI>
+<UL>
+<LI><A HREF="#5_3_1">5.3.1 ppd-natural-language (naturalLanguage)</A></LI>
+<LI><A HREF="#5_3_2">5.3.2 ppd-make (text(127))</A></LI>
+<LI><A HREF="#5_3_3">5.3.3 ppd-make-and-model (text(127))</A></LI>
+<LI><A HREF="#5_3_4">5.3.4 ppd-name (name(255))</A></LI>
+</UL>
+<LI><A HREF="#5_4">5.4 Printer Attributes</A></LI>
+<UL>
+<LI><A HREF="#5_4_1">5.4.1 job-k-limit (integer)</A></LI>
+<LI><A HREF="#5_4_2">5.4.2 job-page-limit (integer)</A></LI>
+<LI><A HREF="#5_4_3">5.4.3 job-quota-period (integer)</A></LI>
+<LI><A HREF="#5_4_4">5.4.4 job-sheets-supported (1setof type3 keyword |
+ name(MAX))</A></LI>
+<LI><A HREF="#5_4_5">5.4.5 printer-type (type2 enum)</A></LI>
+<LI><A HREF="#5_4_6">5.4.6 printer-type-mask (type2 enum)</A></LI>
+<LI><A HREF="#5_4_7">5.4.7 requesting-user-name-allowed (1setof
+ name(127))</A></LI>
+<LI><A HREF="#5_4_8">5.4.8 requesting-user-name-denied (1setof
+ name(127))</A></LI>
+</UL>
+<LI><A HREF="#5_5">5.5 Printer Class Attributes</A></LI>
+<UL>
+<LI><A HREF="#5_5_1">5.5.1 member-names (1setof name(127))</A></LI>
+<LI><A HREF="#5_5_2">5.5.2 member-uris (1setof uri)</A></LI>
+</UL>
+</UL>
+<B><A HREF="#6">A Glossary</A></B>
+<UL>
+<LI><A HREF="#6_1">A.1 Terms</A></LI>
+<LI><A HREF="#6_2">A.2 Acronyms</A></LI>
+</UL>
+<HR>
+<H1><A NAME="1">1 Scope</A></H1>
+<H2><A NAME="1_1">1.1 Identification</A></H2>
+<P>This document provides an overview of the Internet Printing Protocol
+ (&quot;IPP&quot;) version 1.1 as implemented in the Common UNIX Printing System
+ (&quot;CUPS&quot;) version 1.1.</P>
+<H2><A NAME="1_2">1.2 System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+<H2><A NAME="1_3">1.3 Document Overview</A></H2>
+<P>This document is organized into the following sections:</P>
+<UL>
+<LI><A HREF="#1">1 - Scope</A></LI>
+<LI><A HREF="#2">2 - References</A></LI>
+<LI><A HREF="#3">3 - Overview</A></LI>
+<LI><A HREF="#4">4 - Operations</A></LI>
+<LI><A HREF="#5">5 - Attributes</A></LI>
+<LI><A HREF="#6">A - Glossary</A></LI>
+</UL>
+<H1><A NAME="2">2 References</A></H1>
+<H2><A NAME="2_1">2.1 CUPS Documentation</A></H2>
+<P>The following CUPS documentation is referenced by this document:</P>
+<UL>
+<LI>CUPS-CMP-1.1: CUPS Configuration Management Plan</LI>
+<LI>CUPS-IDD-1.1: CUPS System Interface Design Description</LI>
+<LI>CUPS-IPP-1.1: CUPS Implementation of IPP</LI>
+<LI>CUPS-SAM-1.1.x: CUPS Software Administrators Manual</LI>
+<LI>CUPS-SDD-1.1: CUPS Software Design Description</LI>
+<LI>CUPS-SPM-1.1.x: CUPS Software Programming Manual</LI>
+<LI>CUPS-SSR-1.1: CUPS Software Security Report</LI>
+<LI>CUPS-STP-1.1: CUPS Software Test Plan</LI>
+<LI>CUPS-SUM-1.1.x: CUPS Software Users Manual</LI>
+<LI>CUPS-SVD-1.1: CUPS Software Version Description</LI>
+</UL>
+<H2><A NAME="2_2">2.2 Other Documents</A></H2>
+<P>The following non-CUPS documents are referenced by this document:</P>
+<UL>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">
+Adobe PostScript Printer Description File Format Specification, Version
+ 4.3.</A></LI>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
+Adobe PostScript Language Reference, Third Edition.</A></LI>
+<LI>IPP: Job and Printer Set Operations</LI>
+<LI>IPP/1.1: Encoding and Transport</LI>
+<LI>IPP/1.1: Implementers Guide</LI>
+<LI>IPP/1.1: Model and Semantics</LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179, Line Printer
+ Daemon Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2567.txt">RFC 2567, Design Goals
+ for an Internet Printing Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2568.txt">RFC 2568, Rationale
+ for the Structure of the Model and Protocol for the Internet Printing
+ Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2569.txt">RFC 2569, Mapping
+ between LPD and IPP Protocols</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616, Hypertext
+ Transfer Protocol -- HTTP/1.1</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617, HTTP
+ Authentication: Basic and Digest Access</A> Authentication</LI>
+</UL>
+<H1><A NAME="3">3 Overview</A></H1>
+<P>CUPS 1.1 implements IPP/1.1 and the operations and attributes defined
+ in the &quot;IPP: Job and Printer Set Operations&quot;, &quot;IPP/1.1: Output-bin
+ Attribute Extension&quot;, and &quot;IPP/1.1: finishings 'fold',' trim', and
+ 'bale' attribute values extension&quot; specifications.</P>
+<P>CUPS also provides 13 new operations and many new attributes to
+ support multiple IPP printers and printer classes on a single host.</P>
+<H2><A NAME="3_1">3.1 IPP URIs</A></H2>
+<P>CUPS supports both the &quot;http&quot; and &quot;ipp&quot; methods. The following
+ resource names are used:</P>
+<DL>
+<DT>method://hostname:port/</DT>
+<DD>Can be used for all &quot;get&quot; operations.</DD>
+<DT>method://hostname:port/admin</DT>
+<DD>Used for all administrative operations.</DD>
+<DT>method://hostname:port/classes/name</DT>
+<DD>Specifies a printer class.</DD>
+<DT>method://hostname:port/jobs/id</DT>
+<DD>Specifies a job.</DD>
+<DT>method://hostname:port/printers/name</DT>
+<DD>Specifies a printer.</DD>
+</DL>
+<P>So a typical printer URI would be
+ &quot;ipp://foo.bar.com/printers/LaserJet&quot;.</P>
+<P>In addition, the CUPS server also supports normal browser access to
+ &quot;method://hostname:port/admin/&quot;, &quot;method://hostname:port/classes/&quot;,
+ &quot;method://hostname:port/jobs/&quot;, and &quot;method://hostname:port/printers/&quot;
+ to view and manage resources on the server dynamically.</P>
+<H2><A NAME="3_2">3.2 CUPS IPP Operations</A></H2>
+<P>CUPS provides 13 extension operations in addition to most of the
+ standard IPP and registered extension operations:
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH VALIGN="TOP">Operation Name</TH><TH VALIGN="TOP">CUPS</TH><TH VALIGN="TOP">
+Code</TH><TH VALIGN="TOP">Brief Description</TH></TR>
+<TR><TD VALIGN="TOP">Print-Job</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x0002</TD><TD VALIGN="TOP">Print a file.</TD></TR>
+<TR><TD VALIGN="TOP">Validate-Job</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x0004</TD><TD VALIGN="TOP">Validate job attributes.</TD></TR>
+<TR><TD VALIGN="TOP">Create-Job</TD><TD VALIGN="TOP">1.1</TD><TD VALIGN="TOP">
+0x0005</TD><TD VALIGN="TOP">Create a print job.</TD></TR>
+<TR><TD VALIGN="TOP">Send-Document</TD><TD VALIGN="TOP">1.1</TD><TD VALIGN="TOP">
+0x0006</TD><TD VALIGN="TOP">Send a file for a print job.</TD></TR>
+<TR><TD VALIGN="TOP">Cancel-Job</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x0008</TD><TD VALIGN="TOP">Cancel a print job.</TD></TR>
+<TR><TD VALIGN="TOP">Get-Job-Attributes</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x0009</TD><TD VALIGN="TOP">Get job attributes.</TD></TR>
+<TR><TD VALIGN="TOP">Get-Jobs</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x000A</TD><TD VALIGN="TOP">Get all jobs.</TD></TR>
+<TR><TD VALIGN="TOP">Get-Printer-Attributes</TD><TD VALIGN="TOP">1.0</TD><TD
+VALIGN="TOP">0x000B</TD><TD VALIGN="TOP">Get printer attributes.</TD></TR>
+<TR><TD VALIGN="TOP">Hold-Job</TD><TD VALIGN="TOP">1.1</TD><TD VALIGN="TOP">
+0x000C</TD><TD VALIGN="TOP">Hold a job for printing.</TD></TR>
+<TR><TD VALIGN="TOP">Release-Job</TD><TD VALIGN="TOP">1.1</TD><TD VALIGN="TOP">
+0x000D</TD><TD VALIGN="TOP">Release a job for printing.</TD></TR>
+<TR><TD VALIGN="TOP">Pause-Printer</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x0010</TD><TD VALIGN="TOP">Pause printing on a printer.</TD></TR>
+<TR><TD VALIGN="TOP">Resume-Printer</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x0011</TD><TD VALIGN="TOP">Resume printing on a printer.</TD></TR>
+<TR><TD VALIGN="TOP">Purge-Jobs</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x0012</TD><TD VALIGN="TOP">Purge all jobs.</TD></TR>
+<TR><TD VALIGN="TOP">Set-Job-Attributes</TD><TD VALIGN="TOP">1.1</TD><TD VALIGN="TOP">
+0x0014</TD><TD VALIGN="TOP">Set attributes for a pending or held job.</TD>
+</TR>
+<TR><TD VALIGN="TOP">CUPS-Get-Default</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x4001</TD><TD VALIGN="TOP">Get the default destination.</TD></TR>
+<TR><TD VALIGN="TOP">CUPS-Get-Printers</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x4002</TD><TD VALIGN="TOP">Get all of the available printers.</TD></TR>
+<TR><TD VALIGN="TOP">CUPS-Add-Modify-Printer</TD><TD VALIGN="TOP">1.0</TD><TD
+VALIGN="TOP">0x4003</TD><TD VALIGN="TOP">Add or modify a printer.</TD></TR>
+<TR><TD VALIGN="TOP">CUPS-Delete-Printer</TD><TD VALIGN="TOP">1.0</TD><TD
+VALIGN="TOP">0x4004</TD><TD VALIGN="TOP">Delete a printer.</TD></TR>
+<TR><TD VALIGN="TOP">CUPS-Get-Classes</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x4005</TD><TD VALIGN="TOP">Get all of the available printer classes.</TD>
+</TR>
+<TR><TD VALIGN="TOP">CUPS-Add-Modify-Class</TD><TD VALIGN="TOP">1.0</TD><TD
+VALIGN="TOP">0x4006</TD><TD VALIGN="TOP">Add or modify a printer class.</TD>
+</TR>
+<TR><TD VALIGN="TOP">CUPS-Delete-Class</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x4007</TD><TD VALIGN="TOP">Delete a printer class.</TD></TR>
+<TR><TD VALIGN="TOP">CUPS-Accept-Jobs</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x4008</TD><TD VALIGN="TOP">Accept jobs on a printer or printer class.</TD>
+</TR>
+<TR><TD VALIGN="TOP">CUPS-Reject-Jobs</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x4009</TD><TD VALIGN="TOP">Reject jobs on a printer or printer class.</TD>
+</TR>
+<TR><TD VALIGN="TOP">CUPS-Set-Default</TD><TD VALIGN="TOP">1.0</TD><TD VALIGN="TOP">
+0x400A</TD><TD VALIGN="TOP">Set the default destination.</TD></TR>
+<TR><TD VALIGN="TOP">CUPS-Get-Devices</TD><TD VALIGN="TOP">1.1</TD><TD VALIGN="TOP">
+0x400B</TD><TD VALIGN="TOP">Get all of the available devices.</TD></TR>
+<TR><TD VALIGN="TOP">CUPS-Get-PPDs</TD><TD VALIGN="TOP">1.1</TD><TD VALIGN="TOP">
+0x400C</TD><TD VALIGN="TOP">Get all of the available PPDs.</TD></TR>
+<TR><TD VALIGN="TOP">CUPS-Move-Job</TD><TD VALIGN="TOP">1.1</TD><TD VALIGN="TOP">
+0x400D</TD><TD VALIGN="TOP">Move a job to a different printer.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H1><A NAME="4">4 Operations</A></H1>
+<P>The following sections describe the operations supported by CUPS. In
+ the interest of brevity, operations which use only the standard IPP
+ attributes are not described.</P>
+<H2><A NAME="4_1">4.1 Print-Job Operation</A></H2>
+<P>The Print-Job operation (0x0002) prints a file.</P>
+<H3><A NAME="4_1_1">4.1.1 Print-Job Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ Print-Job request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;printer-uri&quot; (uri):</P>
+<P>The client MUST supply a URI for the specified printer.</P>
+</UL>
+<P>Group 2: Job Template Attributes</P>
+<UL>
+<P>&quot;job-billing&quot; (text(MAX)):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies a billing string that is logged with
+ the page accounting information.</P>
+<P>&quot;job-sheets&quot; (1setof type3 keyword | name(MAX)):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies one or two banner pages that are
+ printed before and after any files in the print job. The name of &quot;none&quot;
+ is reserved to indicate that no banner page should be printed. If the
+ client does not specify this attribute then the value of the
+ &quot;job-sheets-default&quot; printer object attribute is used.</P>
+<P><B>Note:</B> Standard IPP only allows specification of a single
+ job-sheets attribute value.</P>
+<P>&quot;media&quot; (1setof type3 keyword | name(MAX)):</P>
+<P>The client OPTIONALLY supplies one or more media attributes
+ specifying the size, type, source, and color of the output media. If
+ the client does not specify this attribute then the value of the
+ &quot;media-default&quot; printer object attribute is used.</P>
+<P><B>Note:</B> Standard IPP only allows specification of a single media
+ attribute value.</P>
+<P>Other Job Template Attributes</P>
+</UL>
+<P>The Print-Job request is followed by a file to be printed.</P>
+<H3><A NAME="4_1_2">4.1.2 Print-Job Response</A></H3>
+<P>The following groups of attributes are send as part of the Print-Job
+ Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<P>Group 2: Job Attributes</P>
+<UL>
+<P>Standard Job Attributes</P>
+</UL>
+<H2><A NAME="4_2">4.2 Create-Job Operation</A></H2>
+<P>The Create-Job operation (0x0005) creates a new, empty print job.</P>
+<H3><A NAME="4_2_1">4.2.1 Create-Job Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ Create-Job request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;printer-uri&quot; (uri):</P>
+<P>The client MUST supply a URI for the specified printer.</P>
+</UL>
+<P>Group 2: Job Template Attributes</P>
+<UL>
+<P>&quot;job-billing&quot; (text(MAX)):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies a billing string that is logged with
+ the page accounting information.</P>
+<P>&quot;job-sheets&quot; (1setof type3 keyword | name(MAX)):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies one or two banner pages that are
+ printed before and after any files in the print job. The name of &quot;none&quot;
+ is reserved to indicate that no banner page should be printed. If the
+ client does not specify this attribute then the value of the
+ &quot;job-sheets-default&quot; printer object attribute is used.</P>
+<P><B>Note:</B> Standard IPP only allows specification of a single
+ job-sheets attribute value.</P>
+<P>&quot;media&quot; (1setof type3 keyword | name(MAX)):</P>
+<P>The client OPTIONALLY supplies one or more media attributes
+ specifying the size, type, source, and color of the output media. If
+ the client does not specify this attribute then the value of the
+ &quot;media-default&quot; printer object attribute is used.</P>
+<P><B>Note:</B> Standard IPP only allows specification of a single media
+ attribute value.</P>
+<P>Standard Job Template Attributes</P>
+</UL>
+<H3><A NAME="4_2_2">4.2.2 Create-Job Response</A></H3>
+<P>The following groups of attributes are send as part of the Create-Job
+ Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<P>Group 2: Job Attributes</P>
+<UL>
+<P>Standard Job Attributes</P>
+</UL>
+<H2><A NAME="4_3">4.3 Set-Job-Attributes Operation</A></H2>
+<P>The Set-Job-Attributes operation (0x0014) changes the attributes of
+ an active (not completed) job.</P>
+<H3><A NAME="4_3_1">4.3.1 Set-Job-Attributes Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ Set-Job-Attributes request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;printer-uri&quot; (uri) and &quot;job-id&quot; (integer)</P>
+<P><I>OR</I></P>
+<P>&quot;job-uri&quot;:</P>
+<P>The client MUST supply a URI for the specified printer and a job ID
+ number, or the job URI.</P>
+</UL>
+<P>Group 2: Job Template Attributes</P>
+<UL>
+<P>&quot;job-sheets&quot; (1setof type3 keyword | name(MAX)):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies one or two banner pages that are
+ printed before and after any files in the print job. The name of &quot;none&quot;
+ is reserved to indicate that no banner page should be printed. If the
+ client does not specify this attribute then the value of the
+ &quot;job-sheets-default&quot; printer object attribute is used.</P>
+<P><B>Note:</B> Standard IPP only allows specification of a single
+ job-sheets attribute value.</P>
+<P>&quot;media&quot; (1setof type3 keyword | name(MAX)):</P>
+<P>The client OPTIONALLY supplies one or more media attributes
+ specifying the size, type, source, and color of the output media. If
+ the client does not specify this attribute then the value of the
+ &quot;media-default&quot; printer object attribute is used.</P>
+<P><B>Note:</B> Standard IPP only allows specification of a single media
+ attribute value.</P>
+<P>Other Job Template Attributes</P>
+</UL>
+<H3><A NAME="4_3_2">4.3.2 Set-Job-Attributes Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ Set-Job-Attributes Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<H2><A NAME="4_4">4.4 CUPS-Get-Default Operation</A></H2>
+<P>The CUPS-Get-Default operation (0x4001) returns the default printer
+ URI and attributes.</P>
+<H3><A NAME="4_4_1">4.4.1 CUPS-Get-Default Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Get-Default request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;requested-attributes&quot; (1setOf keyword) :</P>
+<P>The client OPTIONALLY supplies a set of attribute names and/or
+ attribute group names in whose values the requester is interested. If
+ the client omits this attribute, the server responds as if this
+ attribute had been supplied with a value of 'all'.</P>
+</UL>
+<H3><A NAME="4_4_2">4.4.2 CUPS-Get-Default Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Get-Default Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<P>Group 2: Printer Object Attributes</P>
+<UL>
+<P>The set of requested attributes and their current values.</P>
+</UL>
+<H2><A NAME="4_5">4.5 CUPS-Get-Printers Operation</A></H2>
+<P>The CUPS-Get-Printers operation (0x4002) returns the printer
+ attributes for every printer known to the system. This may include
+ printers that are not served directly by the server.</P>
+<H3><A NAME="4_5_1">4.5.1 CUPS-Get-Printers Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Get-Printers request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;limit&quot; (integer (1:MAX)):</P>
+<P>The client OPTIONALLY supplies this attribute limiting the number of
+ printers that are returned.</P>
+<P>&quot;printer-info&quot; (text(127)):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies this attribute to select which
+ printers are returned.</P>
+<P>&quot;printer-location&quot; (text(127)):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies this attribute to select which
+ printers are returned.</P>
+<P>&quot;printer-type&quot; (type2 enum):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies a printer type enumeration to select
+ which printers are returned.</P>
+<P>&quot;printer-type-mask&quot; (type2 enum):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies a printer type mask enumeration to
+ select which bits are used in the &quot;printer-type&quot; attribute.</P>
+<P>&quot;requested-attributes&quot; (1setOf keyword) :</P>
+<P>The client OPTIONALLY supplies a set of attribute names and/or
+ attribute group names in whose values the requester is interested. If
+ the client omits this attribute, the server responds as if this
+ attribute had been supplied with a value of 'all'.</P>
+</UL>
+<H3><A NAME="4_5_2">4.5.2 CUPS-Get-Printers Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Get-Printers Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<P>Group 2: Printer Object Attributes</P>
+<UL>
+<P>The set of requested attributes and their current values for each
+ printer.</P>
+</UL>
+<H2><A NAME="4_6">4.6 CUPS-Add-Modify-Printer Operation</A></H2>
+<P>The CUPS-Add-Modify-Printer operation (0x4003) adds a new printer or
+ modifies an existing printer on the system.</P>
+<H3><A NAME="4_6_1">4.6.1 CUPS-Add-Modify-Printer Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Add-Modify-Printer request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;printer-uri&quot; (uri):</P>
+<P>The client MUST supply a URI for the specified printer.</P>
+</UL>
+<P>Group 2: Printer Object Attributes</P>
+<UL>
+<P>&quot;banner-end-default&quot; (name(127)):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies a banner page name that is printed
+ after files in a job. The reserved name &quot;none&quot; is used to specify that
+ no banner page should be printed.</P>
+<P>&quot;banner-start-default&quot; (name(127)):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies a banner page name that is printed
+ before files in a job. The reserved name &quot;none&quot; is used to specify that
+ no banner page should be printed.</P>
+<P>&quot;device-uri&quot; (uri):</P>
+<P>The client OPTIONALLY supplies a device URI for the specified
+ printer.</P>
+<P>&quot;ppd-name&quot; (name(127)):</P>
+<P>The client OPTIONALLY supplies a PPD name for the specified printer.</P>
+<P>&quot;printer-is-accepting-jobs&quot; (boolean):</P>
+<P>The client OPTIONALLY supplies this boolean attribute indicating
+ whether or not the printer object should accept new jobs.</P>
+<P>&quot;printer-info&quot; (text(127)):</P>
+<P>The client OPTIONALLY supplies this attribute indicating the printer
+ information string.</P>
+<P>&quot;printer-location&quot; (text(127)):</P>
+<P>The client OPTIONALLY supplies this attribute indicating a textual
+ location of the printer.</P>
+<P>&quot;printer-more-info&quot; (uri):</P>
+<P>The client OPTIONALLY supplies this attribute indicating a URI for
+ additional printer information.</P>
+<P>&quot;printer-state&quot; (type2 enum):</P>
+<P>The client OPTIONALLY supplies this attribute indicating the
+ initial/current state of the printer. Only the &quot;idle&quot; and &quot;stopped&quot;
+ enumerations are recognized.</P>
+<P>&quot;printer-state-message&quot; (text(MAX)):</P>
+<P>The client OPTIONALLY supplies this attribute indicating a textual
+ reason for the current printer state.</P>
+<P>&quot;requesting-user-name-allowed&quot; (1setof name(127) | delete)</P>
+<P><I>OR</I></P>
+<P>&quot;requesting-user-name-denied&quot; (1setof name(127) | delete):</P>
+<P>The client OPTIONALLY supplies one of these attributes to specify an
+ access control list for incoming print jobs. To allow all users access
+ to a printer, use the delete tag for the attribute value.</P>
+</UL>
+<P>The CUPS-Add-Modify-Printer request can optionally be followed by a
+ PPD file or System V interface script to be used for the printer. The
+ &quot;ppd-name&quot; attribute overrides any file that is attached to the end of
+ the request with a local CUPS PPD file.</P>
+<H3><A NAME="4_6_2">4.6.2 CUPS-Add-Modify-Printer Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Add-Modify-Printer Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<H2><A NAME="4_7">4.7 CUPS-Delete-Printer Operation</A></H2>
+<P>The CUPS-Delete-Printer operation (0x4004) removes an existing
+ printer from the system.</P>
+<H3><A NAME="4_7_1">4.7.1 CUPS-Delete-Printer Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Delete-Printer request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;printer-uri&quot; (uri):</P>
+<P>The client MUST supply a URI for the specified printer.</P>
+</UL>
+<H3><A NAME="4_7_2">4.7.2 CUPS-Delete-Printer Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Delete-Printer Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<H2><A NAME="4_8">4.8 CUPS-Get-Classes Operation</A></H2>
+<P>The CUPS-Get-Classes operation (0x4005) returns the printer
+ attributes for every printer class known to the system. This may
+ include printer classes that are not served directly by the server.</P>
+<H3><A NAME="4_8_1">4.8.1 CUPS-Get-Classes Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Get-Classes request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;limit&quot; (integer (1:MAX)):</P>
+<P>The client OPTIONALLY supplies this attribute limiting the number of
+ printer classes that are returned.</P>
+<P>&quot;printer-info&quot; (text(127)):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies this attribute to select which printer
+ classes are returned.</P>
+<P>&quot;printer-location&quot; (text(127)):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies this attribute to select which printer
+ classes are returned.</P>
+<P>&quot;printer-type&quot; (type2 enum):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies a printer type enumeration to select
+ which printer classes are returned.</P>
+<P>&quot;printer-type-mask&quot; (type2 enum):</P>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The client OPTIONALLY supplies a printer type mask enumeration to
+ select which bits are used in the &quot;printer-type&quot; attribute.</P>
+<P>&quot;requested-attributes&quot; (1setOf keyword) :</P>
+<P>The client OPTIONALLY supplies a set of attribute names and/or
+ attribute group names in whose values the requester is interested. If
+ the client omits this attribute, the server responds as if this
+ attribute had been supplied with a value of 'all'.</P>
+</UL>
+<H3><A NAME="4_8_2">4.8.2 CUPS-Get-Classes Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Get-Classes Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<P>Group 2: Printer Class Object Attributes</P>
+<UL>
+<P>The set of requested attributes and their current values for each
+ printer class.</P>
+</UL>
+<H2><A NAME="4_9">4.9 CUPS-Add-Modify-Class Operation</A></H2>
+<P>The CUPS-Add-Modify-Class operation (0x4006) adds a new printer class
+ or modifies and existing printer class on the system.</P>
+<H3><A NAME="4_9_1">4.9.1 CUPS-Add-Modify-Class Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Add-Modify-Class request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;printer-uri&quot; (uri):</P>
+<P>The client MUST supply a URI for the specified printer class.</P>
+</UL>
+<P>Group 2: Printer Object Attributes</P>
+<UL>
+<P>&quot;member-uris&quot; (1setof uri):</P>
+<P>The client OPTIONALLY supplies the &quot;member-uris&quot; set specifying the
+ printers and printer classes that are part of the class.</P>
+<P>&quot;printer-is-accepting-jobs&quot; (boolean):</P>
+<P>The client OPTIONALLY supplies this boolean attribute indicating
+ whether or not the class object should accept new jobs.</P>
+<P>&quot;printer-info&quot; (text(127)):</P>
+<P>The client OPTIONALLY supplies this attribute indicating the printer
+ information string.</P>
+<P>&quot;printer-location&quot; (text(127)):</P>
+<P>The client OPTIONALLY supplies this attribute indicating a textual
+ location of the class.</P>
+<P>&quot;printer-more-info&quot; (uri):</P>
+<P>The client OPTIONALLY supplies this attribute indicating a URI for
+ additional class information.</P>
+<P>&quot;printer-state&quot; (type2 enum):</P>
+<P>The client OPTIONALLY supplies this attribute indicating the
+ initial/current state of the class. Only the &quot;idle&quot; and &quot;stopped&quot;
+ enumerations are recognized.</P>
+<P>&quot;printer-state-message&quot; (text(MAX)):</P>
+<P>The client OPTIONALLY supplies this attribute indicating a textual
+ reason for the current class state.</P>
+<P>&quot;requesting-user-name-allowed&quot; (1setof name(127))</P>
+<P><I>OR</I></P>
+<P>&quot;requesting-user-name-denied&quot; (1setof name(127)):</P>
+<P>The client OPTIONALLY supplies one of these attributes to specify an
+ access control list for incoming print jobs. To allow all users access
+ to a class, use the delete tag for the attribute value.</P>
+</UL>
+<H3><A NAME="4_9_2">4.9.2 CUPS-Add-Modify-Class Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Add-Modify-Class Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<H2><A NAME="4_10">4.10 CUPS-Delete-Class Operation</A></H2>
+<P>The CUPS-Delete-Class operation (0x4007) removes an existing printer
+ class from the system.</P>
+<H3><A NAME="4_10_1">4.10.1 CUPS-Delete-Class Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Delete-Class request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;printer-uri&quot; (uri):</P>
+<P>The client MUST supply a URI for the specified printer class.</P>
+</UL>
+<H3><A NAME="4_10_2">4.10.2 CUPS-Delete-Class Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Delete-Class Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<H2><A NAME="4_11">4.11 CUPS-Accept-Jobs Operation</A></H2>
+<P>The CUPS-Accept-Jobs operation (0x4008) sets the
+ &quot;printer-is-accepting-jobs&quot; attribute to true for the specified printer
+ or printer class.</P>
+<H3><A NAME="4_11_1">4.11.1 CUPS-Accept-Jobs Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Accept-Jobs request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;printer-uri&quot; (uri):</P>
+<P>The client MUST supply a URI for the specified printer or printer
+ class.</P>
+</UL>
+<H3><A NAME="4_11_2">4.11.2 CUPS-Accept-Jobs Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Accept-Jobs Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<H2><A NAME="4_12">4.12 CUPS-Reject-Jobs Operation</A></H2>
+<P>The CUPS-Reject-Jobs operation (0x4009) sets
+ the&quot;printer-is-accepting-jobs&quot; attribute to false for the specified
+ printer or printer class.</P>
+<H3><A NAME="4_12_1">4.12.1 CUPS-Reject-Jobs Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Reject-Jobs request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;printer-uri&quot; (uri):</P>
+<P>The client MUST supply a URI for the specified printer or printer
+ class.</P>
+</UL>
+<P>Group 2: Printer Object Attributes</P>
+<UL>
+<P>&quot;printer-state-message&quot; (text(MAX)):</P>
+<P>The client OPTIONALLY supplies this attribute indicating a textual
+ reason for the current printer state.</P>
+</UL>
+<H3><A NAME="4_12_2">4.12.2 CUPS-Reject-Jobs Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Reject-Jobs Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<H2><A NAME="4_13">4.13 CUPS-Set-Default Operation</A></H2>
+<P>The CUPS-Set-Default operation (0x400A) sets the default printer
+ destination for all clients when a resource name of &quot;/printers&quot; is
+ specified.</P>
+<H3><A NAME="4_13_1">4.13.1 CUPS-Set-Default Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Set-Default request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;printer-uri&quot; (uri):</P>
+<P>The client MUST supply a URI for the specified printer or printer
+ class.</P>
+</UL>
+<H3><A NAME="4_13_2">4.13.2 CUPS-Set-Default Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Set-Default Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<H2><A NAME="4_14">4.14 CUPS-Get-Devices Operation</A></H2>
+<P>The CUPS-Get-Devices operation (0x400B) returns all of the supported
+ device-uri's for the server (CUPS 1.1 and higher).</P>
+<H3><A NAME="4_14_1">4.14.1 CUPS-Get-Devices Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Get-Devices request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;device-class&quot; (type1 keyword):</P>
+<P>The client OPTIONALLY supplies a device class keyword to select which
+ devices are returned.</P>
+<P>&quot;limit&quot; (integer (1:MAX)):</P>
+<P>The client OPTIONALLY supplies this attribute limiting the number of
+ devices that are returned.</P>
+<P>&quot;requested-attributes&quot; (1setOf keyword) :</P>
+<P>The client OPTIONALLY supplies a set of attribute names and/or
+ attribute group names in whose values the requester is interested. If
+ the client omits this attribute, the server responds as if this
+ attribute had been supplied with a value of 'all'.</P>
+</UL>
+<H3><A NAME="4_14_2">4.14.2 CUPS-Get-Devices Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Get-Devices Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<P>Group 2: Device Object Attributes</P>
+<UL>
+<P>The set of requested attributes and their current values for each
+ device.</P>
+</UL>
+<H2><A NAME="4_15">4.15 CUPS-Get-PPDs Operation</A></H2>
+<P>The CUPS-Get-PPDs operation (0x400C) returns all of the locally
+ available PPD files on the system (CUPS 1.1 and higher).</P>
+<H3><A NAME="4_15_1">4.15.1 CUPS-Get-PPDs Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Get-PPDs request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;limit&quot; (integer (1:MAX)):</P>
+<P>The client OPTIONALLY supplies this attribute limiting the number of
+ PPDs that are returned.</P>
+<P>&quot;ppd-make&quot; (text(127)):</P>
+<P>The client OPTIONALLY supplies a printer manufacturer to select which
+ PPDs are returned.</P>
+<P>&quot;requested-attributes&quot; (1setOf keyword) :</P>
+<P>The client OPTIONALLY supplies a set of attribute names and/or
+ attribute group names in whose values the requester is interested. If
+ the client omits this attribute, the server responds as if this
+ attribute had been supplied with a value of 'all'.</P>
+</UL>
+<H3><A NAME="4_15_2">4.15.2 CUPS-Get-PPDs Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Get-PPDs Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<P>Group 2: PPD Attributes</P>
+<UL>
+<P>The set of requested attributes and their current values for each PPD
+ file.</P>
+</UL>
+<H2><A NAME="4_16">4.16 CUPS-Move-Job Operation</A></H2>
+<P>The CUPS-Move-Job operation (0x400D) moves an active print job to a
+ different printer (CUPS 1.1 and higher).</P>
+<H3><A NAME="4_16_1">4.16.1 CUPS-Move-Job Request</A></H3>
+<P>The following groups of attributes are supplied as part of the
+ CUPS-Move-Job request:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.1 of the IPP Model and Semantics
+ document.</P>
+<P>&quot;printer-uri&quot; (uri) and &quot;job-id&quot; (integer)</P>
+<P><I>OR</I></P>
+<P>&quot;job-uri&quot;:</P>
+<P>The client MUST supply a URI for the specified printer and a job ID
+ number, or the job URI.</P>
+</UL>
+<P>Group 2: Job Template Attributes</P>
+<UL>
+<P>&quot;job-printer-uri&quot; (uri)</P>
+<P>The client MUST supply a URI for a printer on the same server.</P>
+</UL>
+<H3><A NAME="4_16_2">4.16.2 CUPS-Move-Job Response</A></H3>
+<P>The following groups of attributes are send as part of the
+ CUPS-Move-Job Response:</P>
+<P>Group 1: Operation Attributes</P>
+<UL>
+<P>Status Message:</P>
+<P>The standard response status message.</P>
+<P>Natural Language and Character Set:</P>
+<P>The &quot;attributes-charset&quot; and &quot;attributes-natural-language&quot; attributes
+ as described in section 3.1.4.2 of the IPP Model and Semantics
+ document.</P>
+</UL>
+<H1><A NAME="5">5 Attributes</A></H1>
+<P>CUPS provides many extension attributes to support multiple devices,
+ PPD files, standard job filters, printers, and printer classes.</P>
+<H2><A NAME="5_1">5.1 Device Attributes</A></H2>
+<P>Device attributes are returned by the CUPS-Get-Devices operation and
+ enumerate all of the available hardware devices and network protocols
+ that are supported by the server.</P>
+<H3><A NAME="5_1_1">5.1.1 device-class (type2 keyword)</A></H3>
+<P>The device-class attribute specifies the class of device and can be
+ one of the following:</P>
+<UL>
+<LI>&quot;file&quot; - a disk file.</LI>
+<LI>&quot;direct&quot; - a parallel or fixed-rate serial data port, currently used
+ for Centronics, IEEE-1284, and USB printer ports.</LI>
+<LI>&quot;serial&quot; - a variable-rate serial port.</LI>
+<LI>&quot;network&quot; - a network connection, typically via AppSocket, HTTP,
+ IPP, LPD, or SMB/CIFS protocols.</LI>
+</UL>
+<H3><A NAME="5_1_2">5.1.2 device-info (text(127))</A></H3>
+<P>The device-info attribute specifies a human-readable string
+ describing the device, e.g. &quot;Parallel Port #1&quot;.</P>
+<H3><A NAME="5_1_3">5.1.3 device-make-and-model (text(127))</A></H3>
+<P>The device-makr-and-model attribute specifies a device identification
+ string provided by the printer connected to the device. If the device
+ or printer does not support identification then this attribute contains
+ the string &quot;unknown&quot;.</P>
+<H3><A NAME="5_1_4">5.1.4 device-uri (uri)</A></H3>
+<P>The device-uri attribute specifies a unique identifier for the
+ device. The actual format of the device-uri string depends on the value
+ of the device-class attribute:</P>
+<UL>
+<LI>&quot;file&quot; - The device-uri will be of the form
+ &quot;file:/path/to/filename&quot;.</LI>
+<LI>&quot;direct&quot; - The device-uri will be of the form
+ &quot;method:/dev/filename&quot;, where method may be &quot;parallel&quot; or &quot;usb&quot; in the
+ current implementation.</LI>
+<LI>&quot;serial&quot; - The device-uri will be of the form
+ &quot;serial:/dev/filename?baud=value+parity=value+flow=value&quot;. The baud
+ value is the data rate in bits per second; the supported values depend
+ on the underlying hardware. The parity value can be one of &quot;none&quot;,
+ &quot;even&quot;, or &quot;odd&quot;. The flow value can be one of &quot;none&quot;, &quot;soft&quot; (XON/XOFF
+ handshaking), &quot;hard&quot; or &quot;rts/cts&quot; (RTS/CTS handshaking), or &quot;dtrdsr&quot;
+ (DTR/DSR handshaking).
+<P>The URI returned by CUPS-Get-Devices will contain the maximum baud
+ rate supported by the device and the best type of flow control
+ available (&quot;soft&quot; or &quot;hard&quot;).</P>
+<LI>&quot;network&quot; - The device-uri will be of the form
+ &quot;method://[username:password@]hostname[:port]/[resource]&quot;, where method
+ may be &quot;http&quot;, &quot;ipp&quot;, &quot;lpd&quot;, &quot;smb&quot;, or &quot;socket&quot; in the current
+ implementation.
+<P>The URI returned by CUPS-Get-Devices will only contain the method
+ name followed by two slashes (&quot;method://&quot;). It is up to the client
+ application to add the appropriate host and other information when
+ adding a new printer.</P>
+<P>The URI returned by Get-Printer-Attributes and CUPS-Get-Printers has
+ any username and password information stripped; the information is
+ still stored and used by the server internally to perform any needed
+ authentication.</P>
+</LI>
+</LI>
+</UL>
+<H2><A NAME="5_2">5.2 Job Template Attributes</A></H2>
+<H3><A NAME="5_2_1">5.2.1 blackplot (boolean)</A></H3>
+<P>The blackplot attribute specifies whether HP-GL/2 plot files should
+ be rendered entirely in black ink (blackplot=true) or using the colors
+ and shades specified in the file (blackplot=false). The default value
+ is false.</P>
+<H3><A NAME="5_2_2">5.2.2 brightness (integer(0:200))</A></H3>
+<P>The brightness attribute specifies the overall brightness of the
+ printed output in percent. A brightness of 100 is normal, while 200 is
+ twice as bright and 50 is half as bright. The default value is 100.</P>
+<P>Brightness is applied to the Cyan, Magenta, Yellow, and Black values
+ using the function &quot;f(x) = brightness / 100 * x&quot;.</P>
+<H3><A NAME="5_2_3">5.2.3 columns (integer(1:4))</A></H3>
+<P>The columns attribute specifies the number of columns to generate
+ when printing text files. The default value is 1.</P>
+<H3><A NAME="5_2_4">5.2.4 cpi (type2 enum)</A></H3>
+<P>The cpi attribute specifies the number of characters per inch when
+ printing text files. Only the values 10, 12, and 17 are currently
+ supported. The default value is 10.</P>
+<H3><A NAME="5_2_5">5.2.5 fitplot (boolean)</A></H3>
+<P>The fitplot attribute specifies whether to scale HP-GL/2 plot files
+ to fit on the selected media (fitplot=true) or use the physical scale
+ specified in the plot file (fitplot=false). The default value is false.</P>
+<H3><A NAME="5_2_6">5.2.6 gamma (integer(1:10000))</A></H3>
+<P>The gamma attribute specifies the luminance correction for the
+ output. A value of 1000 specifies no correction, while values of 2000
+ and 500 will generate lighter and darker output, respectively. The
+ default value is 1000.</P>
+<P>Gamma is applied to the Red, Green, and Blue values (or luminance for
+ grayscale output) using the function &quot;f(x) = x<SUP>(1000/gamma)</SUP>&quot;.</P>
+<H3><A NAME="5_2_7">5.2.7 hue (integer(-180:180))</A></H3>
+<P>The hue attribute specifies a color hue rotation when printing image
+ files. The default value is 0.</P>
+<H3><A NAME="5_2_8">5.2.8 job-billing (text(MAX))</A></H3>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The job-billing attribute provides a text value to associate with a
+ job for billing purposes.</P>
+<H3><A NAME="5_2_9">5.2.9 job-hold-until (keyword | name(MAX))</A></H3>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The job-hold-until attribute specifies a hold time. In addition to
+ the standard IPP/1.1 keyword names, CUPS supports name values of the
+ form &quot;HH:MM&quot; and &quot;HH:MM:SS&quot; that specify a hold time. The hold time is
+ in Greenwich Mean Time (GMT) and<I> not</I> in the local time zone. If
+ the specified time is less than the current time, the job is held until
+ the next day.</P>
+<H3><A NAME="5_2_10">5.2.10 job-sheets (1setof type3 keyword |
+ name(MAX))</A></H3>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The job-sheets attribute specifies one or two banner files that are
+ printed before and after a job. The reserved value of &quot;none&quot; disables
+ banner printing. The default value is stored in the job-sheets-default
+ attribute.</P>
+<P>If only one value is supplied, the banner file is printed before the
+ job. If two values are supplied, the first value is used as the
+ starting banner file and the second as the ending banner file.</P>
+<H3><A NAME="5_2_11">5.2.11 job-originating-host-name (name(MAX))</A></H3>
+<P><I>(CUPS 1.1.5 and higher)</I></P>
+<P>The job-originating-host-name attribute specifies the host from which
+ the job was queued. The value will be the hostname or IP address of the
+ client depending on whether hostname resolution is enabled. The
+ localhost address (127.0.0.1) is<B> always</B> resolved to the name
+ &quot;localhost&quot;.</P>
+<P>This attribute is read-only.</P>
+<H3><A NAME="5_2_12">5.2.12 lpi (type2 enum)</A></H3>
+<P>The lpi attribute specifies the number of lines per inch when
+ printing text files. Only the values 6 and 8 are currently supported.
+ The default value is 6.</P>
+<H3><A NAME="5_2_13">5.2.13 mirror (boolean)</A></H3>
+<P>The mirror attribute specifies whether pages are mirrored on their X
+ axis, which is useful for printing transfer images on special media.
+ The default value is false.</P>
+<H3><A NAME="5_2_14">5.2.14 natural-scaling (integer(1:1000))</A></H3>
+<P><I>(CUPS 1.1.9 and higher)</I></P>
+<P>The natural-scaling attribute specifies the scaling of image files
+ with respect to the natural image size. A value of 100 specifies that
+ the image file should exactly the natural size, while 50 is half the
+ natural size and 200 is twice the natural size. The default value is
+ 100.</P>
+<P>The ppi option can be used to override the natural resolution of the
+ image, which controls the natural size.</P>
+<H3><A NAME="5_2_15">5.2.15 number-up-layout (type2 keyword)</A></H3>
+<P><I>(CUPS 1.1.15 and higher)</I></P>
+<P>The number-up-layout attribute specifies the order each input page is
+ placed on each output page. The following keywords are presently
+ defined:</P>
+<UL>
+<LI><CODE>btlr</CODE> - Bottom to top, left to right</LI>
+<LI><CODE>btrl</CODE> - Bottom to top, right to left</LI>
+<LI><CODE>lrbt</CODE> - Left to right, bottom to top</LI>
+<LI><CODE>lrtb</CODE> - Left to right, top to bottom (default)</LI>
+<LI><CODE>rlbt</CODE> - Right to left, bottom to top</LI>
+<LI><CODE>rltb</CODE> - Right to left, top to bottom</LI>
+<LI><CODE>tblr</CODE> - Top to bottom, left to right</LI>
+<LI><CODE>tbrl</CODE> - Top to bottom, right to left</LI>
+</UL>
+<H3><A NAME="5_2_16">5.2.16 page-border (type2 keyword)</A></H3>
+<P><I>(CUPS 1.1.15 and higher)</I></P>
+<P>The page-border attribute specifies whether a border is draw around
+ each page. The following keywords are presently defined:</P>
+<UL>
+<LI><CODE>double</CODE> - Two hairline borders are drawn</LI>
+<LI><CODE>double-thick</CODE> - Two 1pt borders are drawn</LI>
+<LI><CODE>none</CODE> - No border is drawn (default)</LI>
+<LI><CODE>single</CODE> - A single hairline border is drawn</LI>
+<LI><CODE>single-thick</CODE> - A single 1pt border is drawn</LI>
+</UL>
+<H3><A NAME="5_2_17">5.2.17 page-bottom (integer(0:MAX))</A></H3>
+<P>The page-bottom attribute specifies the bottom margin in points (72
+ points equals 1 inch). The default value is the device physical margin.</P>
+<H3><A NAME="5_2_18">5.2.18 page-label (text(MAX))</A></H3>
+<P><I>(CUPS 1.1.7 and higher)</I></P>
+<P>The page-label attribute provides a text value to place in the header
+ and footer on each page. If a classification level is set on the
+ server, then this classification is printed before the page label.</P>
+<H3><A NAME="5_2_19">5.2.19 page-left (integer(0:MAX))</A></H3>
+<P>The page-left attribute specifies the left margin in points (72
+ points equals 1 inch). The default value is the device physical margin.</P>
+<H3><A NAME="5_2_20">5.2.20 page-right (integer(0:MAX))</A></H3>
+<P>The page-right attribute specifies the right margin in points (72
+ points equals 1 inch). The default value is the device physical margin.</P>
+<H3><A NAME="5_2_21">5.2.21 page-set (type2 keyword)</A></H3>
+<P>The page-set attribute specifies which pages to print in a file. The
+ supported keywords are &quot;all&quot;, &quot;even&quot;, and &quot;odd&quot;. The default value is
+ &quot;all&quot;.</P>
+<H3><A NAME="5_2_22">5.2.22 page-top (integer(0:MAX))</A></H3>
+<P>The page-top attribute specifies the top margin in points (72 points
+ equals 1 inch). The default value is the device physical margin.</P>
+<H3><A NAME="5_2_23">5.2.23 penwidth (integer(0:MAX))</A></H3>
+<P>The penwidth attribute specifies the default pen width in micrometers
+ when printing HP-GL/2 plot files. The default value is 1000 (1
+ millimeter).</P>
+<H3><A NAME="5_2_24">5.2.24 position (type2 keyword)</A></H3>
+<P>The position attribute specifies the location of image files on the
+ media. The following keyword values are recognized:</P>
+<UL>
+<LI><CODE>center</CODE> - Center the image on the page (default)</LI>
+<LI><CODE>top</CODE> - Print the image centered at the top of the page</LI>
+<LI><CODE>left</CODE> - Print the image centered on the left of page</LI>
+<LI><CODE>right</CODE> - Print the image centered on the right of the
+ page</LI>
+<LI><CODE>top-left</CODE> - Print the image at the top left corner of
+ the page</LI>
+<LI><CODE>top-right</CODE> - Print the image at the top right corner of
+ the page</LI>
+<LI><CODE>bottom</CODE> - Print the image centered at the bottom of the
+ page</LI>
+<LI><CODE>bottom-left</CODE> - Print the image at the bottom left corner
+ of the page</LI>
+<LI><CODE>bottom-right</CODE> - Print the image at the bottom right
+ corner of the page</LI>
+</UL>
+<H3><A NAME="5_2_25">5.2.25 ppi (integer(1:MAX))</A></H3>
+<P>The ppi attribute specifies the resolution of an image file in pixels
+ per inch. The default value is the resolution included with the file or
+ 128 if no resolution information is available.</P>
+<H3><A NAME="5_2_26">5.2.26 prettyprint (boolean)</A></H3>
+<P>The prettyprint attribute specifies whether text files should be
+ printed with a shaded header and keyword highlighting
+ (prettyprint=true) or without additional formatting
+ (prettyprint=false). The default value is false.</P>
+<H3><A NAME="5_2_27">5.2.27 saturation (integer(0:200))</A></H3>
+<P>The saturation attribute specifies the color saturation when printing
+ image files. A saturation of 100 is normal, while values of 50 and 200
+ will be half and twice as colorful, respectively. The default value is
+ 100.</P>
+<H3><A NAME="5_2_28">5.2.28 scaling (integer(1:1000))</A></H3>
+<P>The scaling attribute specifies the scaling of image files with
+ respect to the selected media. A value of 100 specifies that the image
+ file should fit 100% of the page, or as much as possible given the
+ image dimensions. The default value is unspecified.</P>
+<P>The scaling attribute overrides the ppi attribute if specified.</P>
+<H3><A NAME="5_2_29">5.2.29 wrap (boolean)</A></H3>
+<P>The wrap attribute specifies whether long lines should be wrapped
+ (wrap=true) or not (wrap=false) when printing text files. The default
+ value is true.</P>
+<H2><A NAME="5_3">5.3 PPD Attributes</A></H2>
+<H3><A NAME="5_3_1">5.3.1 ppd-natural-language (naturalLanguage)</A></H3>
+<P>The ppd-natural-language attribute specifies the language encoding of
+ the PPD file (the LanguageVersion attribute in the PPD file). If the
+ language is unknown or undefined then &quot;en&quot; (English) is assumed.</P>
+<H3><A NAME="5_3_2">5.3.2 ppd-make (text(127))</A></H3>
+<P>The ppd-make attribute specifies the manufacturer of the printer (the
+ Manufacturer attribute in the PPD file). If the manufacturer is not
+ specified in the PPD file then an educated guess is made using the
+ NickName attribute in the PPD file.</P>
+<H3><A NAME="5_3_3">5.3.3 ppd-make-and-model (text(127))</A></H3>
+<P>The ppd-make-and-model attribute specifies the manufacturer and model
+ name of the PPD file (the NickName attribute in the PPD file). If the
+ make and model is not specified in the PPD file then the ModelName or
+ ShortNickName attributes are used instead.</P>
+<H3><A NAME="5_3_4">5.3.4 ppd-name (name(255))</A></H3>
+<P>The ppd-name attribute specifies the PPD filename on the server
+ relative to the model directory. The forward slash (/) is used to
+ delineate directories.</P>
+<H2><A NAME="5_4">5.4 Printer Attributes</A></H2>
+<H3><A NAME="5_4_1">5.4.1 job-k-limit (integer)</A></H3>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The job-k-limit attribute specifies the maximum number of kilobytes
+ that may be printed by a user, including banner files. The default
+ value of 0 specifies that there is no limit.</P>
+<H3><A NAME="5_4_2">5.4.2 job-page-limit (integer)</A></H3>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The job-page-limit attribute specifies the maximum number of pages
+ that may be printed by a user, including banner files. The default
+ value of 0 specifies that there is no limit.</P>
+<H3><A NAME="5_4_3">5.4.3 job-quota-period (integer)</A></H3>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The job-quota-period attribute specifies the time period used for
+ quota calculations, in seconds. The default value of 0 specifies that
+ the limits apply to all jobs that have been printed by a user that are
+ still known to the system.</P>
+<H3><A NAME="5_4_4">5.4.4 job-sheets-supported (1setof type3 keyword |
+ name(MAX))</A></H3>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The job-sheets-supported attribute specifies the available banner
+ files. There will always be at least one banner file available called
+ &quot;none&quot;.</P>
+<H3><A NAME="5_4_5">5.4.5 printer-type (type2 enum)</A></H3>
+<P>The printer-type attribute specifies printer type and capability bits
+ for the printer or class. The default value is computed from internal
+ state information and the PPD file for the printer. The following bits
+ are defined:
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Bit</TH><TH>Description</TH></TR>
+<TR><TD VALIGN="TOP">0x00000001</TD><TD VALIGN="TOP">Is a printer class.</TD>
+</TR>
+<TR><TD VALIGN="TOP">0x00000002</TD><TD VALIGN="TOP">Is a remote
+ destination.</TD></TR>
+<TR><TD VALIGN="TOP">0x00000004</TD><TD VALIGN="TOP">Can print in black.</TD>
+</TR>
+<TR><TD VALIGN="TOP">0x00000008</TD><TD VALIGN="TOP">Can print in color.</TD>
+</TR>
+<TR><TD VALIGN="TOP">0x00000010</TD><TD VALIGN="TOP">Can print on both
+ sides of the page in hardware.</TD></TR>
+<TR><TD VALIGN="TOP">0x00000020</TD><TD VALIGN="TOP">Can staple output.</TD>
+</TR>
+<TR><TD VALIGN="TOP">0x00000040</TD><TD VALIGN="TOP">Can do fast copies
+ in hardware.</TD></TR>
+<TR><TD VALIGN="TOP">0x00000080</TD><TD VALIGN="TOP">Can do fast copy
+ collation in hardware.</TD></TR>
+<TR><TD VALIGN="TOP">0x00000100</TD><TD VALIGN="TOP">Can punch output.</TD>
+</TR>
+<TR><TD VALIGN="TOP">0x00000200</TD><TD VALIGN="TOP">Can cover output.</TD>
+</TR>
+<TR><TD VALIGN="TOP">0x00000400</TD><TD VALIGN="TOP">Can bind output.</TD>
+</TR>
+<TR><TD VALIGN="TOP">0x00000800</TD><TD VALIGN="TOP">Can sort output.</TD>
+</TR>
+<TR><TD VALIGN="TOP">0x00001000</TD><TD VALIGN="TOP">Can handle media up
+ to US-Legal/A4.</TD></TR>
+<TR><TD VALIGN="TOP">0x00002000</TD><TD VALIGN="TOP">Can handle media
+ from US-Legal/A4 to ISO-C/A2.</TD></TR>
+<TR><TD VALIGN="TOP">0x00004000</TD><TD VALIGN="TOP">Can handle media
+ larger than ISO-C/A2.</TD></TR>
+<TR><TD VALIGN="TOP">0x00008000</TD><TD VALIGN="TOP">Can handle
+ user-defined media sizes.</TD></TR>
+<TR><TD VALIGN="TOP">0x00010000</TD><TD VALIGN="TOP">Is an implicit
+ (server-generated) class.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="5_4_6">5.4.6 printer-type-mask (type2 enum)</A></H3>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The printer-type-mask attribute is used to choose printers or classes
+ with the CUPS-Get-Printers and CUPS-Get-Classes operations. The bits
+ are defined identically to the printer-type attribute and default to
+ all 1's.</P>
+<H3><A NAME="5_4_7">5.4.7 requesting-user-name-allowed (1setof
+ name(127))</A></H3>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The requesting-user-name-allowed attribute lists all of the users
+ that are allowed to access a printer or class. Either this attribute or
+ the requesting-user-name-denied attribute will be defined, but not
+ both.</P>
+<H3><A NAME="5_4_8">5.4.8 requesting-user-name-denied (1setof name(127))</A>
+</H3>
+<P><I>(CUPS 1.1 and higher)</I></P>
+<P>The requesting-user-name-denied attribute lists all of the users that
+ are not allowed to access a printer or class. Either this attribute or
+ the requesting-user-name-allowed attribute will be defined, but not
+ both.</P>
+<H2><A NAME="5_5">5.5 Printer Class Attributes</A></H2>
+<H3><A NAME="5_5_1">5.5.1 member-names (1setof name(127))</A></H3>
+<P>The member-names attribute specifies each of the printer-name
+ attributes of the member printers and classes. Each name corresponds to
+ the same element of the member-uris attribute.</P>
+<H3><A NAME="5_5_2">5.5.2 member-uris (1setof uri)</A></H3>
+<P>The member-uris attribute specifies each of the printer-uri
+ attributes of the member printers and classes. Each URI corresponds to
+ the same element of the member-names attribute.</P>
+<H1 TYPE="A" VALUE="1"><A NAME="6">A Glossary</A></H1>
+<H2><A NAME="6_1">A.1 Terms</A></H2>
+<DL>
+<DT>C</DT>
+<DD>A computer language.</DD>
+<DT>parallel</DT>
+<DD>Sending or receiving data more than 1 bit at a time.</DD>
+<DT>pipe</DT>
+<DD>A one-way communications channel between two programs.</DD>
+<DT>serial</DT>
+<DD>Sending or receiving data 1 bit at a time.</DD>
+<DT>socket</DT>
+<DD>A two-way network communications channel.</DD>
+</DL>
+<H2><A NAME="6_2">A.2 Acronyms</A></H2>
+<DL>
+<DT>ASCII</DT>
+<DD>American Standard Code for Information Interchange</DD>
+<DT>CUPS</DT>
+<DD>Common UNIX Printing System</DD>
+<DT>ESC/P</DT>
+<DD>EPSON Standard Code for Printers</DD>
+<DT>FTP</DT>
+<DD>File Transfer Protocol</DD>
+<DT>HP-GL</DT>
+<DD>Hewlett-Packard Graphics Language</DD>
+<DT>HP-PCL</DT>
+<DD>Hewlett-Packard Page Control Language</DD>
+<DT>HP-PJL</DT>
+<DD>Hewlett-Packard Printer Job Language</DD>
+<DT>IETF</DT>
+<DD>Internet Engineering Task Force</DD>
+<DT>IPP</DT>
+<DD>Internet Printing Protocol</DD>
+<DT>ISO</DT>
+<DD>International Standards Organization</DD>
+<DT>LPD</DT>
+<DD>Line Printer Daemon</DD>
+<DT>MIME</DT>
+<DD>Multimedia Internet Mail Exchange</DD>
+<DT>PPD</DT>
+<DD>PostScript Printer Description</DD>
+<DT>SMB</DT>
+<DD>Server Message Block</DD>
+<DT>TFTP</DT>
+<DD>Trivial File Transfer Protocol</DD>
+</DL>
+</BODY>
+</HTML>
diff --git a/doc/ipp.pdf b/doc/ipp.pdf
new file mode 100644
index 000000000..f8c9ba5e8
--- /dev/null
+++ b/doc/ipp.pdf
Binary files differ
diff --git a/doc/ipp.shtml b/doc/ipp.shtml
new file mode 100644
index 000000000..0ed8c71d8
--- /dev/null
+++ b/doc/ipp.shtml
@@ -0,0 +1,1994 @@
+<HTML>
+<HEAD>
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002 All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-IPP-1.1">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Implementation of IPP</TITLE>
+</HEAD>
+<BODY>
+
+<H1>Scope</H1>
+
+<H2>Identification</H2>
+
+<P>This document provides an overview of the Internet Printing Protocol
+("IPP") version 1.1 as implemented in the Common UNIX Printing System
+("CUPS") version 1.1.
+
+<EMBED SRC="system-overview.shtml">
+
+<H2>Document Overview</H2>
+
+<P>This document is organized into the following sections:
+
+<UL>
+ <LI><A HREF="#1">1 - Scope</A>
+ <LI><A HREF="#2">2 - References</A>
+ <LI><A HREF="#3">3 - Overview</A>
+ <LI><A HREF="#4">4 - Operations</A>
+ <LI><A HREF="#5">5 - Attributes</A>
+ <LI><A HREF="#6">A - Glossary</A>
+</UL>
+
+<EMBED SRC="references.shtml">
+
+<H1>Overview</H1>
+
+<P>CUPS 1.1 implements IPP/1.1 and the operations and attributes
+defined in the "IPP: Job and Printer Set Operations",
+"IPP/1.1: Output-bin Attribute Extension", and "IPP/1.1: finishings
+'fold',' trim', and 'bale' attribute values extension" specifications.
+
+<P>CUPS also provides 13 new operations and many new attributes to
+support multiple IPP printers and printer classes on a single host.
+
+<H2>IPP URIs</H2>
+
+<P>CUPS supports both the "http" and "ipp" methods. The following
+resource names are used:
+
+<DL>
+
+ <DT>method://hostname:port/
+
+ <DD>Can be used for all "get" operations.
+
+ <DT>method://hostname:port/admin
+
+ <DD>Used for all administrative operations.
+
+ <DT>method://hostname:port/classes/name
+
+ <DD>Specifies a printer class.
+
+ <DT>method://hostname:port/jobs/id
+
+ <DD>Specifies a job.
+
+ <DT>method://hostname:port/printers/name
+
+ <DD>Specifies a printer.
+
+</DL>
+
+<P>So a typical printer URI would be "ipp://foo.bar.com/printers/LaserJet".
+
+<P>In addition, the CUPS server also supports normal browser access to
+"method://hostname:port/admin/", "method://hostname:port/classes/",
+"method://hostname:port/jobs/", and "method://hostname:port/printers/"
+to view and manage resources on the server dynamically.
+
+<H2>CUPS IPP Operations</H2>
+
+<P>CUPS provides 13 extension operations in addition to most of the
+standard IPP and registered extension operations:
+
+<CENTER><TABLE BORDER WIDTH="80%">
+<TR>
+ <TH VALIGN="TOP">Operation Name</TH>
+ <TH VALIGN="TOP">CUPS</TH>
+ <TH VALIGN="TOP">Code</TH>
+ <TH VALIGN="TOP">Brief Description</TH>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Print-Job</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x0002</TD>
+ <TD VALIGN="TOP">Print a file.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Validate-Job</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x0004</TD>
+ <TD VALIGN="TOP">Validate job attributes.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Create-Job</TD>
+ <TD VALIGN="TOP">1.1</TD>
+ <TD VALIGN="TOP">0x0005</TD>
+ <TD VALIGN="TOP">Create a print job.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Send-Document</TD>
+ <TD VALIGN="TOP">1.1</TD>
+ <TD VALIGN="TOP">0x0006</TD>
+ <TD VALIGN="TOP">Send a file for a print job.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Cancel-Job</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x0008</TD>
+ <TD VALIGN="TOP">Cancel a print job.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Get-Job-Attributes</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x0009</TD>
+ <TD VALIGN="TOP">Get job attributes.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Get-Jobs</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x000A</TD>
+ <TD VALIGN="TOP">Get all jobs.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Get-Printer-Attributes</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x000B</TD>
+ <TD VALIGN="TOP">Get printer attributes.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Hold-Job</TD>
+ <TD VALIGN="TOP">1.1</TD>
+ <TD VALIGN="TOP">0x000C</TD>
+ <TD VALIGN="TOP">Hold a job for printing.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Release-Job</TD>
+ <TD VALIGN="TOP">1.1</TD>
+ <TD VALIGN="TOP">0x000D</TD>
+ <TD VALIGN="TOP">Release a job for printing.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Pause-Printer</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x0010</TD>
+ <TD VALIGN="TOP">Pause printing on a printer.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Resume-Printer</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x0011</TD>
+ <TD VALIGN="TOP">Resume printing on a printer.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Purge-Jobs</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x0012</TD>
+ <TD VALIGN="TOP">Purge all jobs.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">Set-Job-Attributes</TD>
+ <TD VALIGN="TOP">1.1</TD>
+ <TD VALIGN="TOP">0x0014</TD>
+ <TD VALIGN="TOP">Set attributes for a pending or held job.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Get-Default</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x4001</TD>
+ <TD VALIGN="TOP">Get the default destination.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Get-Printers</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x4002</TD>
+ <TD VALIGN="TOP">Get all of the available printers.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Add-Modify-Printer</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x4003</TD>
+ <TD VALIGN="TOP">Add or modify a printer.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Delete-Printer</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x4004</TD>
+ <TD VALIGN="TOP">Delete a printer.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Get-Classes</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x4005</TD>
+ <TD VALIGN="TOP">Get all of the available printer classes.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Add-Modify-Class</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x4006</TD>
+ <TD VALIGN="TOP">Add or modify a printer class.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Delete-Class</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x4007</TD>
+ <TD VALIGN="TOP">Delete a printer class.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Accept-Jobs</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x4008</TD>
+ <TD VALIGN="TOP">Accept jobs on a printer or printer class.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Reject-Jobs</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x4009</TD>
+ <TD VALIGN="TOP">Reject jobs on a printer or printer class.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Set-Default</TD>
+ <TD VALIGN="TOP">1.0</TD>
+ <TD VALIGN="TOP">0x400A</TD>
+ <TD VALIGN="TOP">Set the default destination.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Get-Devices</TD>
+ <TD VALIGN="TOP">1.1</TD>
+ <TD VALIGN="TOP">0x400B</TD>
+ <TD VALIGN="TOP">Get all of the available devices.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Get-PPDs</TD>
+ <TD VALIGN="TOP">1.1</TD>
+ <TD VALIGN="TOP">0x400C</TD>
+ <TD VALIGN="TOP">Get all of the available PPDs.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">CUPS-Move-Job</TD>
+ <TD VALIGN="TOP">1.1</TD>
+ <TD VALIGN="TOP">0x400D</TD>
+ <TD VALIGN="TOP">Move a job to a different printer.</TD>
+</TR>
+</TABLE>
+</CENTER>
+
+<H1>Operations</H1>
+
+<P>The following sections describe the operations supported by CUPS.
+In the interest of brevity, operations which use only the standard
+IPP attributes are not described.
+
+<H2>Print-Job Operation</H2>
+
+<P>The Print-Job operation (0x0002) prints a file.
+
+<H3>Print-Job Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+Print-Job request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"printer-uri" (uri):
+
+ <P>The client MUST supply a URI for the specified printer.
+
+</UL>
+
+<P>Group 2: Job Template Attributes
+
+<UL>
+
+ <P>"job-billing" (text(MAX)):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies a billing string that is logged
+ with the page accounting information.
+
+ <P>"job-sheets" (1setof type3 keyword | name(MAX)):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies one or two banner pages that
+ are printed before and after any files in the print job. The
+ name of "none" is reserved to indicate that no banner page
+ should be printed. If the client does not specify this
+ attribute then the value of the "job-sheets-default" printer
+ object attribute is used.
+
+ <P><B>Note:</B> Standard IPP only allows specification of a single
+ job-sheets attribute value.
+
+ <P>"media" (1setof type3 keyword | name(MAX)):
+
+ <P>The client OPTIONALLY supplies one or more media attributes
+ specifying the size, type, source, and color of the output
+ media. If the client does not specify this attribute then the
+ value of the "media-default" printer object attribute is used.
+
+ <P><B>Note:</B> Standard IPP only allows specification of a single
+ media attribute value.
+
+ <P>Other Job Template Attributes
+
+</UL>
+
+<P>The Print-Job request is followed by a file to be printed.
+
+<H3>Print-Job Response</H3>
+
+<P>The following groups of attributes are send as part of the Print-Job
+Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<P>Group 2: Job Attributes
+
+<UL>
+
+ <P>Standard Job Attributes
+
+</UL>
+
+<H2>Create-Job Operation</H2>
+
+<P>The Create-Job operation (0x0005) creates a new, empty print job.
+
+<H3>Create-Job Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+Create-Job request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"printer-uri" (uri):
+
+ <P>The client MUST supply a URI for the specified printer.
+
+</UL>
+
+<P>Group 2: Job Template Attributes
+
+<UL>
+
+ <P>"job-billing" (text(MAX)):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies a billing string that is logged
+ with the page accounting information.
+
+ <P>"job-sheets" (1setof type3 keyword | name(MAX)):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies one or two banner pages that
+ are printed before and after any files in the print job. The
+ name of "none" is reserved to indicate that no banner page
+ should be printed. If the client does not specify this
+ attribute then the value of the "job-sheets-default" printer
+ object attribute is used.
+
+ <P><B>Note:</B> Standard IPP only allows specification of a single
+ job-sheets attribute value.
+
+ <P>"media" (1setof type3 keyword | name(MAX)):
+
+ <P>The client OPTIONALLY supplies one or more media attributes
+ specifying the size, type, source, and color of the output
+ media. If the client does not specify this attribute then the
+ value of the "media-default" printer object attribute is used.
+
+ <P><B>Note:</B> Standard IPP only allows specification of a single
+ media attribute value.
+
+ <P>Standard Job Template Attributes
+
+</UL>
+
+<H3>Create-Job Response</H3>
+
+<P>The following groups of attributes are send as part of the
+Create-Job Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<P>Group 2: Job Attributes
+
+<UL>
+
+ <P>Standard Job Attributes
+
+</UL>
+
+<H2>Set-Job-Attributes Operation</H2>
+
+<P>The Set-Job-Attributes operation (0x0014) changes the attributes of
+an active (not completed) job.
+
+<H3>Set-Job-Attributes Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+Set-Job-Attributes request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"printer-uri" (uri) and "job-id" (integer)
+ <P><I>OR</I>
+ <P>"job-uri":
+
+ <P>The client MUST supply a URI for the specified printer and
+ a job ID number, or the job URI.
+
+</UL>
+
+<P>Group 2: Job Template Attributes
+
+<UL>
+
+ <P>"job-sheets" (1setof type3 keyword | name(MAX)):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies one or two banner pages that
+ are printed before and after any files in the print job. The
+ name of "none" is reserved to indicate that no banner page
+ should be printed. If the client does not specify this
+ attribute then the value of the "job-sheets-default" printer
+ object attribute is used.
+
+ <P><B>Note:</B> Standard IPP only allows specification of a single
+ job-sheets attribute value.
+
+ <P>"media" (1setof type3 keyword | name(MAX)):
+
+ <P>The client OPTIONALLY supplies one or more media attributes
+ specifying the size, type, source, and color of the output
+ media. If the client does not specify this attribute then the
+ value of the "media-default" printer object attribute is used.
+
+ <P><B>Note:</B> Standard IPP only allows specification of a single
+ media attribute value.
+
+ <P>Other Job Template Attributes
+
+</UL>
+
+<H3>Set-Job-Attributes Response</H3>
+
+<P>The following groups of attributes are send as part of the Set-Job-Attributes
+Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<H2>CUPS-Get-Default Operation</H2>
+
+<P>The CUPS-Get-Default operation (0x4001) returns the default printer
+URI and attributes.
+
+<H3>CUPS-Get-Default Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Get-Default request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"requested-attributes" (1setOf keyword) :
+
+ <P>The client OPTIONALLY supplies a set of attribute names
+ and/or attribute group names in whose values the requester is
+ interested. If the client omits this attribute, the server
+ responds as if this attribute had been supplied with a value of
+ 'all'.
+
+</UL>
+
+<H3>CUPS-Get-Default Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Get-Default Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<P>Group 2: Printer Object Attributes
+
+<UL>
+
+ <P>The set of requested attributes and their current values.
+
+</UL>
+
+<H2>CUPS-Get-Printers Operation</H2>
+
+<P>The CUPS-Get-Printers operation (0x4002) returns the printer
+attributes for every printer known to the system. This may include
+printers that are not served directly by the server.
+
+<H3>CUPS-Get-Printers Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Get-Printers request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"limit" (integer (1:MAX)):
+
+ <P>The client OPTIONALLY supplies this attribute limiting the
+ number of printers that are returned.
+
+ <P>"printer-info" (text(127)):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies this attribute to
+ select which printers are returned.
+
+ <P>"printer-location" (text(127)):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies this attribute to
+ select which printers are returned.
+
+ <P>"printer-type" (type2 enum):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies a printer type enumeration to
+ select which printers are returned.
+
+ <P>"printer-type-mask" (type2 enum):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies a printer type mask
+ enumeration to select which bits are used in the "printer-type"
+ attribute.
+
+ <P>"requested-attributes" (1setOf keyword) :
+
+ <P>The client OPTIONALLY supplies a set of attribute names
+ and/or attribute group names in whose values the requester is
+ interested. If the client omits this attribute, the server
+ responds as if this attribute had been supplied with a value of
+ 'all'.
+
+</UL>
+
+<H3>CUPS-Get-Printers Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Get-Printers Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<P>Group 2: Printer Object Attributes
+
+<UL>
+
+ <P>The set of requested attributes and their current values for
+ each printer.
+
+</UL>
+
+<H2>CUPS-Add-Modify-Printer Operation</H2>
+
+<P>The CUPS-Add-Modify-Printer operation (0x4003) adds a new printer or
+modifies an existing printer on the system.
+
+<H3>CUPS-Add-Modify-Printer Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Add-Modify-Printer request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"printer-uri" (uri):
+
+ <P>The client MUST supply a URI for the specified printer.
+
+</UL>
+
+<P>Group 2: Printer Object Attributes
+
+<UL>
+
+ <P>"banner-end-default" (name(127)):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies a banner page name that is
+ printed after files in a job. The reserved name "none" is used to
+ specify that no banner page should be printed.
+
+ <P>"banner-start-default" (name(127)):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies a banner page name that is
+ printed before files in a job. The reserved name "none" is used to
+ specify that no banner page should be printed.
+
+ <P>"device-uri" (uri):
+
+ <P>The client OPTIONALLY supplies a device URI for the
+ specified printer.
+
+ <P>"ppd-name" (name(127)):
+
+ <P>The client OPTIONALLY supplies a PPD name for the specified
+ printer.
+
+ <P>"printer-is-accepting-jobs" (boolean):
+
+ <P>The client OPTIONALLY supplies this boolean attribute
+ indicating whether or not the printer object should accept new jobs.
+
+ <P>"printer-info" (text(127)):
+
+ <P>The client OPTIONALLY supplies this attribute indicating the
+ printer information string.
+
+ <P>"printer-location" (text(127)):
+
+ <P>The client OPTIONALLY supplies this attribute indicating a
+ textual location of the printer.
+
+ <P>"printer-more-info" (uri):
+
+ <P>The client OPTIONALLY supplies this attribute indicating a
+ URI for additional printer information.
+
+ <P>"printer-state" (type2 enum):
+
+ <P>The client OPTIONALLY supplies this attribute indicating the
+ initial/current state of the printer. Only the "idle" and "stopped"
+ enumerations are recognized.
+
+ <P>"printer-state-message" (text(MAX)):
+
+ <P>The client OPTIONALLY supplies this attribute indicating a
+ textual reason for the current printer state.
+
+ <P>"requesting-user-name-allowed" (1setof name(127) | delete)
+ <P><I>OR</I>
+ <P>"requesting-user-name-denied" (1setof name(127) | delete):
+
+ <P>The client OPTIONALLY supplies one of these attributes to
+ specify an access control list for incoming print jobs. To allow
+ all users access to a printer, use the delete tag for the
+ attribute value.
+
+</UL>
+
+<P>The CUPS-Add-Modify-Printer request can optionally be followed by a PPD
+file or System V interface script to be used for the printer. The
+"ppd-name" attribute overrides any file that is attached to the end of
+the request with a local CUPS PPD file.
+
+<H3>CUPS-Add-Modify-Printer Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Add-Modify-Printer Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<H2>CUPS-Delete-Printer Operation</H2>
+
+<P>The CUPS-Delete-Printer operation (0x4004) removes an existing
+printer from the system.
+
+<H3>CUPS-Delete-Printer Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Delete-Printer request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"printer-uri" (uri):
+
+ <P>The client MUST supply a URI for the specified printer.
+
+</UL>
+
+<H3>CUPS-Delete-Printer Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Delete-Printer Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<H2>CUPS-Get-Classes Operation</H2>
+
+<P>The CUPS-Get-Classes operation (0x4005) returns the printer
+attributes for every printer class known to the system. This may
+include printer classes that are not served directly by the server.
+
+<H3>CUPS-Get-Classes Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Get-Classes request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"limit" (integer (1:MAX)):
+
+ <P>The client OPTIONALLY supplies this attribute limiting the
+ number of printer classes that are returned.
+
+ <P>"printer-info" (text(127)):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies this attribute to
+ select which printer classes are returned.
+
+ <P>"printer-location" (text(127)):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies this attribute to
+ select which printer classes are returned.
+
+ <P>"printer-type" (type2 enum):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies a printer type enumeration to
+ select which printer classes are returned.
+
+ <P>"printer-type-mask" (type2 enum):
+
+ <P><I>(CUPS 1.1 and higher)</I>
+
+ <P>The client OPTIONALLY supplies a printer type mask
+ enumeration to select which bits are used in the "printer-type"
+ attribute.
+
+ <P>"requested-attributes" (1setOf keyword) :
+
+ <P>The client OPTIONALLY supplies a set of attribute names
+ and/or attribute group names in whose values the requester is
+ interested. If the client omits this attribute, the server responds as
+ if this attribute had been supplied with a value of 'all'.
+
+</UL>
+
+<H3>CUPS-Get-Classes Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Get-Classes Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<P>Group 2: Printer Class Object Attributes
+
+<UL>
+
+ <P>The set of requested attributes and their current values for
+ each printer class.
+
+</UL>
+
+<H2>CUPS-Add-Modify-Class Operation</H2>
+
+<P>The CUPS-Add-Modify-Class operation (0x4006) adds a new printer class or
+modifies and existing printer class on the system.
+
+<H3>CUPS-Add-Modify-Class Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Add-Modify-Class request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"printer-uri" (uri):
+
+ <P>The client MUST supply a URI for the specified printer class.
+
+</UL>
+
+<P>Group 2: Printer Object Attributes
+
+<UL>
+
+ <P>"member-uris" (1setof uri):
+
+ <P>The client OPTIONALLY supplies the "member-uris" set
+ specifying the printers and printer classes that are part of the class.
+
+ <P>"printer-is-accepting-jobs" (boolean):
+
+ <P>The client OPTIONALLY supplies this boolean attribute
+ indicating whether or not the class object should accept new jobs.
+
+ <P>"printer-info" (text(127)):
+
+ <P>The client OPTIONALLY supplies this attribute indicating the
+ printer information string.
+
+ <P>"printer-location" (text(127)):
+
+ <P>The client OPTIONALLY supplies this attribute indicating a
+ textual location of the class.
+
+ <P>"printer-more-info" (uri):
+
+ <P>The client OPTIONALLY supplies this attribute indicating a
+ URI for additional class information.
+
+ <P>"printer-state" (type2 enum):
+
+ <P>The client OPTIONALLY supplies this attribute indicating the
+ initial/current state of the class. Only the "idle" and "stopped"
+ enumerations are recognized.
+
+ <P>"printer-state-message" (text(MAX)):
+
+ <P>The client OPTIONALLY supplies this attribute indicating a
+ textual reason for the current class state.
+
+ <P>"requesting-user-name-allowed" (1setof name(127))
+ <P><I>OR</I>
+ <P>"requesting-user-name-denied" (1setof name(127)):
+
+ <P>The client OPTIONALLY supplies one of these attributes to
+ specify an access control list for incoming print jobs. To allow
+ all users access to a class, use the delete tag for the
+ attribute value.
+
+</UL>
+
+<H3>CUPS-Add-Modify-Class Response</H3>
+
+<P>The following groups of attributes are send as part of the CUPS-Add-Modify-Class Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<H2>CUPS-Delete-Class Operation</H2>
+
+<P>The CUPS-Delete-Class operation (0x4007) removes an existing printer
+class from the system.
+
+<H3>CUPS-Delete-Class Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Delete-Class request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"printer-uri" (uri):
+
+ <P>The client MUST supply a URI for the specified printer class.
+
+</UL>
+
+<H3>CUPS-Delete-Class Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Delete-Class Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<H2>CUPS-Accept-Jobs Operation</H2>
+
+<P>The CUPS-Accept-Jobs operation (0x4008) sets the
+"printer-is-accepting-jobs" attribute to true for the specified printer
+or printer class.
+
+<H3>CUPS-Accept-Jobs Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Accept-Jobs request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"printer-uri" (uri):
+
+ <P>The client MUST supply a URI for the specified printer or printer class.
+
+</UL>
+
+<H3>CUPS-Accept-Jobs Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Accept-Jobs Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<H2>CUPS-Reject-Jobs Operation</H2>
+
+<P>The CUPS-Reject-Jobs operation (0x4009) sets
+the"printer-is-accepting-jobs" attribute to false for the specified
+printer or printer class.
+
+<H3>CUPS-Reject-Jobs Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Reject-Jobs request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"printer-uri" (uri):
+
+ <P>The client MUST supply a URI for the specified printer or printer class.
+
+</UL>
+
+<P>Group 2: Printer Object Attributes
+
+<UL>
+
+ <P>"printer-state-message" (text(MAX)):
+
+ <P>The client OPTIONALLY supplies this attribute indicating a
+ textual reason for the current printer state.
+
+</UL>
+
+<H3>CUPS-Reject-Jobs Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Reject-Jobs Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<H2>CUPS-Set-Default Operation</H2>
+
+<P>The CUPS-Set-Default operation (0x400A) sets the default printer
+destination for all clients when a resource name of "/printers" is
+specified.
+
+<H3>CUPS-Set-Default Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Set-Default request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"printer-uri" (uri):
+
+ <P>The client MUST supply a URI for the specified printer or
+ printer class.
+
+</UL>
+
+<H3>CUPS-Set-Default Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Set-Default Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<H2>CUPS-Get-Devices Operation</H2>
+
+<P>The CUPS-Get-Devices operation (0x400B) returns all of the supported
+device-uri's for the server (CUPS 1.1 and higher).
+
+<H3>CUPS-Get-Devices Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Get-Devices request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"device-class" (type1 keyword):
+
+ <P>The client OPTIONALLY supplies a device class keyword to select
+ which devices are returned.
+
+ <P>"limit" (integer (1:MAX)):
+
+ <P>The client OPTIONALLY supplies this attribute limiting the number of
+ devices that are returned.
+
+ <P>"requested-attributes" (1setOf keyword) :
+
+ <P>The client OPTIONALLY supplies a set of attribute names and/or
+ attribute group names in whose values the requester is interested. If
+ the client omits this attribute, the server responds as if this
+ attribute had been supplied with a value of 'all'.
+
+</UL>
+
+<H3>CUPS-Get-Devices Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Get-Devices Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<P>Group 2: Device Object Attributes
+
+<UL>
+
+ <P>The set of requested attributes and their current values for
+ each device.
+
+</UL>
+
+<H2>CUPS-Get-PPDs Operation</H2>
+
+<P>The CUPS-Get-PPDs operation (0x400C) returns all of the locally
+available PPD files on the system (CUPS 1.1 and higher).
+
+<H3>CUPS-Get-PPDs Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Get-PPDs request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"limit" (integer (1:MAX)):
+
+ <P>The client OPTIONALLY supplies this attribute limiting the number of
+ PPDs that are returned.
+
+ <P>"ppd-make" (text(127)):
+
+ <P>The client OPTIONALLY supplies a printer manufacturer to select
+ which PPDs are returned.
+
+ <P>"requested-attributes" (1setOf keyword) :
+
+ <P>The client OPTIONALLY supplies a set of attribute names and/or
+ attribute group names in whose values the requester is interested. If
+ the client omits this attribute, the server responds as if this
+ attribute had been supplied with a value of 'all'.
+
+</UL>
+
+<H3>CUPS-Get-PPDs Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Get-PPDs Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<P>Group 2: PPD Attributes
+
+<UL>
+
+ <P>The set of requested attributes and their current values for each
+ PPD file.
+
+</UL>
+
+<H2>CUPS-Move-Job Operation</H2>
+
+<P>The CUPS-Move-Job operation (0x400D) moves an active print job to a
+different printer (CUPS 1.1 and higher).
+
+<H3>CUPS-Move-Job Request</H3>
+
+<P>The following groups of attributes are supplied as part of the
+CUPS-Move-Job request:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1 of the IPP Model and
+ Semantics document.
+
+ <P>"printer-uri" (uri) and "job-id" (integer)
+ <P><I>OR</I>
+ <P>"job-uri":
+
+ <P>The client MUST supply a URI for the specified printer and
+ a job ID number, or the job URI.
+
+</UL>
+
+<P>Group 2: Job Template Attributes
+
+<UL>
+
+ <P>"job-printer-uri" (uri)
+
+ <P>The client MUST supply a URI for a printer on the same server.
+
+</UL>
+
+<H3>CUPS-Move-Job Response</H3>
+
+<P>The following groups of attributes are send as part of the
+CUPS-Move-Job Response:
+
+<P>Group 1: Operation Attributes
+
+<UL>
+
+ <P>Status Message:
+
+ <P>The standard response status message.
+
+ <P>Natural Language and Character Set:
+
+ <P>The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2 of the IPP Model and
+ Semantics document.
+
+</UL>
+
+<H1>Attributes</H1>
+
+<P>CUPS provides many extension attributes to support multiple devices,
+PPD files, standard job filters, printers, and printer classes.
+
+<H2>Device Attributes</H2>
+
+<P>Device attributes are returned by the CUPS-Get-Devices operation and
+enumerate all of the available hardware devices and network protocols
+that are supported by the server.
+
+<H3>device-class (type2 keyword)</H3>
+
+<P>The device-class attribute specifies the class of device and can be
+one of the following:
+
+<UL>
+
+ <LI>"file" - a disk file.
+
+ <LI>"direct" - a parallel or fixed-rate serial data port,
+ currently used for Centronics, IEEE-1284, and USB printer
+ ports.
+
+ <LI>"serial" - a variable-rate serial port.
+
+ <LI>"network" - a network connection, typically via AppSocket,
+ HTTP, IPP, LPD, or SMB/CIFS protocols.
+
+</UL>
+
+<H3>device-info (text(127))</H3>
+
+<P>The device-info attribute specifies a human-readable string describing
+the device, e.g. "Parallel Port #1".
+
+<H3>device-make-and-model (text(127))</H3>
+
+<P>The device-makr-and-model attribute specifies a device
+identification string provided by the printer connected to the device.
+If the device or printer does not support identification then this
+attribute contains the string "unknown".
+
+<H3>device-uri (uri)</H3>
+
+<P>The device-uri attribute specifies a unique identifier for the
+device. The actual format of the device-uri string depends on the value
+of the device-class attribute:
+
+<UL>
+
+ <LI>"file" - The device-uri will be of the form
+ "file:/path/to/filename".
+
+ <LI>"direct" - The device-uri will be of the form
+ "method:/dev/filename", where method may be "parallel" or "usb"
+ in the current implementation.
+
+ <LI>"serial" - The device-uri will be of the form
+ "serial:/dev/filename?baud=value+parity=value+flow=value".
+ The baud value is the data rate in bits per second; the
+ supported values depend on the underlying hardware.
+ The parity value can be one of "none", "even", or "odd".
+ The flow value can be one of "none", "soft" (XON/XOFF
+ handshaking), "hard" or "rts/cts" (RTS/CTS handshaking),
+ or "dtrdsr" (DTR/DSR handshaking).
+
+ <P>The URI returned by CUPS-Get-Devices will contain the
+ maximum baud rate supported by the device and the best
+ type of flow control available ("soft" or "hard").
+
+ <LI>"network" - The device-uri will be of the form
+ "method://[username:password@]hostname[:port]/[resource]",
+ where method may be "http", "ipp", "lpd", "smb", or
+ "socket" in the current implementation.
+
+ <P>The URI returned by CUPS-Get-Devices will only contain
+ the method name followed by two slashes ("method://").
+ It is up to the client application to add the appropriate
+ host and other information when adding a new printer.
+
+ <P>The URI returned by Get-Printer-Attributes and
+ CUPS-Get-Printers has any username and password information
+ stripped; the information is still stored and used by the
+ server internally to perform any needed authentication.
+
+</UL>
+
+<H2>Job Template Attributes</H2>
+
+<H3>blackplot (boolean)</H3>
+
+<P>The blackplot attribute specifies whether HP-GL/2 plot files should be
+rendered entirely in black ink (blackplot=true) or using the colors and shades
+specified in the file (blackplot=false). The default value is false.
+
+<H3>brightness (integer(0:200))</H3>
+
+<P>The brightness attribute specifies the overall brightness of the printed
+output in percent. A brightness of 100 is normal, while 200 is twice as
+bright and 50 is half as bright. The default value is 100.
+
+<P>Brightness is applied to the Cyan, Magenta, Yellow, and Black values using
+the function "f(x) = brightness / 100 * x".
+
+<H3>columns (integer(1:4))</H3>
+
+<P>The columns attribute specifies the number of columns to generate when
+printing text files. The default value is 1.
+
+<H3>cpi (type2 enum)</H3>
+
+<P>The cpi attribute specifies the number of characters per inch when
+printing text files. Only the values 10, 12, and 17 are currently
+supported. The default value is 10.
+
+<H3>fitplot (boolean)</H3>
+
+<P>The fitplot attribute specifies whether to scale HP-GL/2 plot files to
+fit on the selected media (fitplot=true) or use the physical scale specified
+in the plot file (fitplot=false). The default value is false.
+
+<H3>gamma (integer(1:10000))</H3>
+
+<P>The gamma attribute specifies the luminance correction for the output.
+A value of 1000 specifies no correction, while values of 2000 and 500 will
+generate lighter and darker output, respectively. The default value is
+1000.
+
+<P>Gamma is applied to the Red, Green, and Blue values (or luminance for
+grayscale output) using the function "f(x) = x<SUP>(1000/gamma)</SUP>".
+
+<H3>hue (integer(-180:180))</H3>
+
+<P>The hue attribute specifies a color hue rotation when printing image
+files. The default value is 0.
+
+<H3>job-billing (text(MAX))</H3>
+
+<P><I>(CUPS 1.1 and higher)</I>
+
+<P>The job-billing attribute provides a text value to associate with a job
+for billing purposes.
+
+<H3>job-hold-until (keyword | name(MAX))</H3>
+
+<P><I>(CUPS 1.1 and higher)</I>
+
+<P>The job-hold-until attribute specifies a hold time. In addition to the
+standard IPP/1.1 keyword names, CUPS supports name values of the form
+"HH:MM" and "HH:MM:SS" that specify a hold time. The hold time is in
+Greenwich Mean Time (GMT) and <I>not</I> in the local time zone. If the
+specified time is less than the current time, the job is held until the
+next day.
+
+<H3>job-sheets (1setof type3 keyword | name(MAX))</H3>
+
+<P><I>(CUPS 1.1 and higher)</I>
+
+<P>The job-sheets attribute specifies one or two banner files that are printed
+before and after a job. The reserved value of "none" disables banner printing.
+The default value is stored in the job-sheets-default attribute.
+
+<P>If only one value is supplied, the banner file is printed before the job.
+If two values are supplied, the first value is used as the starting banner
+file and the second as the ending banner file.
+
+<H3>job-originating-host-name (name(MAX))</H3>
+
+<P><I>(CUPS 1.1.5 and higher)</I>
+
+<P>The job-originating-host-name attribute specifies the host
+from which the job was queued. The value will be the hostname or
+IP address of the client depending on whether hostname
+resolution is enabled. The localhost address (127.0.0.1) is
+<B>always</B> resolved to the name "localhost".
+
+<P>This attribute is read-only.
+
+<H3>lpi (type2 enum)</H3>
+
+<P>The lpi attribute specifies the number of lines per inch when
+printing text files. Only the values 6 and 8 are currently supported.
+The default value is 6.
+
+<H3>mirror (boolean)</H3>
+
+<P>The mirror attribute specifies whether pages are mirrored on
+their X axis, which is useful for printing transfer images on
+special media. The default value is false.
+
+<H3>natural-scaling (integer(1:1000))</H3>
+
+<P><I>(CUPS 1.1.9 and higher)</I>
+
+<P>The natural-scaling attribute specifies the scaling of image files with
+respect to the natural image size. A value of 100 specifies that the image
+file should exactly the natural size, while 50 is half the natural size
+and 200 is twice the natural size. The default value is 100.
+
+<P>The ppi option can be used to override the natural resolution of the
+image, which controls the natural size.
+
+<H3>number-up-layout (type2 keyword)</H3>
+
+<P><I>(CUPS 1.1.15 and higher)</I>
+
+<P>The number-up-layout attribute specifies the order each input
+page is placed on each output page. The following keywords are
+presently defined:
+
+<UL>
+
+ <LI><CODE>btlr</CODE> - Bottom to top, left to right</LI>
+
+ <LI><CODE>btrl</CODE> - Bottom to top, right to left</LI>
+
+ <LI><CODE>lrbt</CODE> - Left to right, bottom to top</LI>
+
+ <LI><CODE>lrtb</CODE> - Left to right, top to bottom (default)</LI>
+
+ <LI><CODE>rlbt</CODE> - Right to left, bottom to top</LI>
+
+ <LI><CODE>rltb</CODE> - Right to left, top to bottom</LI>
+
+ <LI><CODE>tblr</CODE> - Top to bottom, left to right</LI>
+
+ <LI><CODE>tbrl</CODE> - Top to bottom, right to left</LI>
+
+</UL>
+
+<H3>page-border (type2 keyword)</H3>
+
+<P><I>(CUPS 1.1.15 and higher)</I>
+
+<P>The page-border attribute specifies whether a border is
+draw around each page. The following keywords are presently
+defined:
+
+<UL>
+
+ <LI><CODE>double</CODE> - Two hairline borders are drawn</LI>
+
+ <LI><CODE>double-thick</CODE> - Two 1pt borders are drawn</LI>
+
+ <LI><CODE>none</CODE> - No border is drawn (default)</LI>
+
+ <LI><CODE>single</CODE> - A single hairline border is drawn</LI>
+
+ <LI><CODE>single-thick</CODE> - A single 1pt border is drawn</LI>
+
+</UL>
+
+<H3>page-bottom (integer(0:MAX))</H3>
+
+<P>The page-bottom attribute specifies the bottom margin in points (72 points
+equals 1 inch). The default value is the device physical margin.
+
+<H3>page-label (text(MAX))</H3>
+
+<P><I>(CUPS 1.1.7 and higher)</I>
+
+<P>The page-label attribute provides a text value to place in
+the header and footer on each page. If a classification level is
+set on the server, then this classification is printed before
+the page label.
+
+<H3>page-left (integer(0:MAX))</H3>
+
+<P>The page-left attribute specifies the left margin in points (72 points
+equals 1 inch). The default value is the device physical margin.
+
+<H3>page-right (integer(0:MAX))</H3>
+
+<P>The page-right attribute specifies the right margin in points (72 points
+equals 1 inch). The default value is the device physical margin.
+
+<H3>page-set (type2 keyword)</H3>
+
+<P>The page-set attribute specifies which pages to print in a file. The
+supported keywords are "all", "even", and "odd". The default value is
+"all".
+
+<H3>page-top (integer(0:MAX))</H3>
+
+<P>The page-top attribute specifies the top margin in points (72 points
+equals 1 inch). The default value is the device physical margin.
+
+<H3>penwidth (integer(0:MAX))</H3>
+
+<P>The penwidth attribute specifies the default pen width in micrometers
+when printing HP-GL/2 plot files. The default value is 1000 (1 millimeter).
+
+<H3>position (type2 keyword)</H3>
+
+<P>The position attribute specifies the location of image files on the
+media. The following keyword values are recognized:
+
+<UL>
+
+ <LI><CODE>center</CODE> - Center the image on the page (default)
+
+ <LI><CODE>top</CODE> - Print the image centered at the top of the page
+
+ <LI><CODE>left</CODE> - Print the image centered on the left of page
+
+ <LI><CODE>right</CODE> - Print the image centered on the right of the page
+
+ <LI><CODE>top-left</CODE> - Print the image at the top left corner of
+ the page
+
+ <LI><CODE>top-right</CODE> - Print the image at the top right corner of
+ the page
+
+ <LI><CODE>bottom</CODE> - Print the image centered at the bottom of
+ the page
+
+ <LI><CODE>bottom-left</CODE> - Print the image at the bottom left
+ corner of the page
+
+ <LI><CODE>bottom-right</CODE> - Print the image at the bottom right
+ corner of the page
+
+</UL>
+
+<H3>ppi (integer(1:MAX))</H3>
+
+<P>The ppi attribute specifies the resolution of an image file in pixels
+per inch. The default value is the resolution included with the file or
+128 if no resolution information is available.
+
+<H3>prettyprint (boolean)</H3>
+
+<P>The prettyprint attribute specifies whether text files should be printed
+with a shaded header and keyword highlighting (prettyprint=true) or without
+additional formatting (prettyprint=false). The default value is false.
+
+<H3>saturation (integer(0:200))</H3>
+
+<P>The saturation attribute specifies the color saturation when
+printing image files. A saturation of 100 is normal, while values of 50
+and 200 will be half and twice as colorful, respectively. The default
+value is 100.
+
+<H3>scaling (integer(1:1000))</H3>
+
+<P>The scaling attribute specifies the scaling of image files with
+respect to the selected media. A value of 100 specifies that the image
+file should fit 100% of the page, or as much as possible given the
+image dimensions. The default value is unspecified.
+
+<P>The scaling attribute overrides the ppi attribute if specified.
+
+<H3>wrap (boolean)</H3>
+
+<P>The wrap attribute specifies whether long lines should be wrapped
+(wrap=true) or not (wrap=false) when printing text files. The default
+value is true.
+
+<H2>PPD Attributes</H2>
+
+<H3>ppd-natural-language (naturalLanguage)</H3>
+
+<P>The ppd-natural-language attribute specifies the language encoding
+of the PPD file (the LanguageVersion attribute in the PPD file). If the
+language is unknown or undefined then "en" (English) is assumed.
+
+<H3>ppd-make (text(127))</H3>
+
+<P>The ppd-make attribute specifies the manufacturer of the printer
+(the Manufacturer attribute in the PPD file). If the manufacturer
+is not specified in the PPD file then an educated guess is made using
+the NickName attribute in the PPD file.
+
+<H3>ppd-make-and-model (text(127))</H3>
+
+<P>The ppd-make-and-model attribute specifies the manufacturer and model
+name of the PPD file (the NickName attribute in the PPD file). If the
+make and model is not specified in the PPD file then the ModelName or
+ShortNickName attributes are used instead.
+
+<H3>ppd-name (name(255))</H3>
+
+<P>The ppd-name attribute specifies the PPD filename on the server
+relative to the model directory. The forward slash (/) is used to
+delineate directories.
+
+<H2>Printer Attributes</H2>
+
+<H3>job-k-limit (integer)</H3>
+
+<P><I>(CUPS 1.1 and higher)</I>
+
+<P>The job-k-limit attribute specifies the maximum number of kilobytes that
+may be printed by a user, including banner files. The default value of 0
+specifies that there is no limit.
+
+<H3>job-page-limit (integer)</H3>
+
+<P><I>(CUPS 1.1 and higher)</I>
+
+<P>The job-page-limit attribute specifies the maximum number of pages that
+may be printed by a user, including banner files. The default value of 0
+specifies that there is no limit.
+
+<H3>job-quota-period (integer)</H3>
+
+<P><I>(CUPS 1.1 and higher)</I>
+
+<P>The job-quota-period attribute specifies the time period used for quota
+calculations, in seconds. The default value of 0 specifies that the limits
+apply to all jobs that have been printed by a user that are still known to
+the system.
+
+<H3>job-sheets-supported (1setof type3 keyword | name(MAX))</H3>
+
+<P><I>(CUPS 1.1 and higher)</I>
+
+<P>The job-sheets-supported attribute specifies the available banner files.
+There will always be at least one banner file available called "none".
+
+<H3>printer-type (type2 enum)</H3>
+
+<P>The printer-type attribute specifies printer type and capability bits for
+the printer or class. The default value is computed from internal state
+information and the PPD file for the printer. The following bits are defined:
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Bit</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000001</TD>
+ <TD VALIGN="TOP">Is a printer class.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000002</TD>
+ <TD VALIGN="TOP">Is a remote destination.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000004</TD>
+ <TD VALIGN="TOP">Can print in black.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000008</TD>
+ <TD VALIGN="TOP">Can print in color.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000010</TD>
+ <TD VALIGN="TOP">Can print on both sides of the page in hardware.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000020</TD>
+ <TD VALIGN="TOP">Can staple output.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000040</TD>
+ <TD VALIGN="TOP">Can do fast copies in hardware.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000080</TD>
+ <TD VALIGN="TOP">Can do fast copy collation in hardware.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000100</TD>
+ <TD VALIGN="TOP">Can punch output.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000200</TD>
+ <TD VALIGN="TOP">Can cover output.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000400</TD>
+ <TD VALIGN="TOP">Can bind output.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00000800</TD>
+ <TD VALIGN="TOP">Can sort output.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00001000</TD>
+ <TD VALIGN="TOP">Can handle media up to US-Legal/A4.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00002000</TD>
+ <TD VALIGN="TOP">Can handle media from US-Legal/A4 to ISO-C/A2.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00004000</TD>
+ <TD VALIGN="TOP">Can handle media larger than ISO-C/A2.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00008000</TD>
+ <TD VALIGN="TOP">Can handle user-defined media sizes.</TD>
+</TR>
+<TR>
+ <TD VALIGN="TOP">0x00010000</TD>
+ <TD VALIGN="TOP">Is an implicit (server-generated) class.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>printer-type-mask (type2 enum)</H3>
+
+<P><I>(CUPS 1.1 and higher)</I>
+
+<P>The printer-type-mask attribute is used to choose printers or classes with
+the CUPS-Get-Printers and CUPS-Get-Classes operations. The bits are defined
+identically to the printer-type attribute and default to all 1's.
+
+<H3>requesting-user-name-allowed (1setof name(127))</H3>
+
+<P><I>(CUPS 1.1 and higher)</I>
+
+<P>The requesting-user-name-allowed attribute lists all of the users that are
+allowed to access a printer or class. Either this attribute or the
+requesting-user-name-denied attribute will be defined, but not both.
+
+<H3>requesting-user-name-denied (1setof name(127))</H3>
+
+<P><I>(CUPS 1.1 and higher)</I>
+
+<P>The requesting-user-name-denied attribute lists all of the users that are
+not allowed to access a printer or class. Either this attribute or the
+requesting-user-name-allowed attribute will be defined, but not both.
+
+<H2>Printer Class Attributes</H2>
+
+<H3>member-names (1setof name(127))</H3>
+
+<P>The member-names attribute specifies each of the printer-name attributes of
+the member printers and classes. Each name corresponds to the same element of
+the member-uris attribute.
+
+<H3>member-uris (1setof uri)</H3>
+
+<P>The member-uris attribute specifies each of the printer-uri attributes of
+the member printers and classes. Each URI corresponds to the same element of
+the member-names attribute.
+
+<EMBED SRC="glossary.shtml">
+
+</BODY>
+</HTML>
diff --git a/doc/overview.html b/doc/overview.html
new file mode 100644
index 000000000..754e55d6f
--- /dev/null
+++ b/doc/overview.html
@@ -0,0 +1,500 @@
+<HTML>
+<HEAD>
+ <META NAME="Author" CONTENT="Michael Sweet">
+ <TITLE>An Overview of the Common UNIX Printing System</TITLE>
+ <LINK REL=STYLESHEET TYPE="text/css" HREF="cupsdoc.css">
+</HEAD>
+<BODY>
+<TABLE WIDTH="100%">
+<TR VALIGN=TOP>
+ <TD><IMG SRC="images/cups-large.gif" WIDTH="103" HEIGHT="120"></TD>
+ <TD><H1 ALIGN="RIGHT">An Overview of the<BR>
+ Common UNIX Printing System,<BR>
+ Version 1.1</H1>
+
+ <P ALIGN="RIGHT">July 10, 2000<BR>
+ Michael Sweet, Easy Software Products<BR>
+ Copyright 1998-2002, All Rights Reserved.</P>
+ </TD>
+</TR>
+</TABLE>
+
+<P>This whitepaper describes the Common UNIX Printing
+System<SUP>TM</SUP> ("CUPS<SUP>TM</SUP>"), a portable and extensible
+printing system for UNIX<SUP>&reg;</SUP>. CUPS is being developed by
+<A HREF="http://www.easysw.com">Easy Software Products</A>, a software
+firm located in Hollywood, Maryland that has been selling commercial
+software for UNIX since 1993 through more than 40 distributors serving
+over 80 countries worldwide.
+
+<P>Additional information on CUPS is available on the World Wide Web at
+"<A HREF="http://www.cups.org">http://www.cups.org</A>".
+
+<H2>Background</H2>
+
+<P>Printing within UNIX has historically been done using one of two
+printing systems - the Berkeley Line Printer Daemon ("LPD") [RFC1179]
+and the AT&amp;T Line Printer system. These printing systems were
+designed in the 70's for printing text to line printers; vendors have
+since added varying levels of support for other types of printers.
+
+<P>Replacements for these printing systems have emerged [LPRng,
+Palladin, PLP], however none of the replacements change the fundamental
+capabilities of these systems.
+
+<P>Over the last few years several attempts at developing a standard
+printing interface have been made, including the draft POSIX Printing
+standard developed by the Institute of Electrical and Electronics
+Engineers, Inc. ("IEEE") [IEEE-1387.4] and Internet Printing Protocol
+("IPP") developed by the Internet Engineering Task Force ("IETF")
+through the Printer Working Group ("PWG") [IETF-IPP]. The POSIX
+printing standard defines a common set of command-line tools as well as
+a C interface for printer administration and print jobs, but has been
+shelved by the IEEE.
+
+<P>The Internet Printing Protocol defines extensions to the HyperText
+Transport Protocol 1.1 [RFC2616] to provide support for remote printing
+services. IPP/1.0 was accepted by the IETF as an experimental Request
+For Comments [RFC] document in October of 1999. Since then the Printer
+Working Group has developed an updated set of specifications for
+IPP/1.1 which have been accepted by the IETF and are awaiting
+publication as proposed standards. Unlike POSIX Printing, IPP enjoys
+widespread industry support and is poised to become the standard
+network printing solution for all operating systems.
+
+<P>CUPS uses IPP/1.1 to provide a complete, modern printing system for
+UNIX that can be extended to support new printers, devices, and
+protocols while providing compatibility with existing UNIX
+applications. CUPS is free software provided under the terms of the
+GNU General Public License and GNU Library General Public License.
+
+<H2>History</H2>
+
+<P>The first production release of CUPS (based on IPP/1.0) was released
+in October of 1999. Since then, we have released several patch updates
+to the original CUPS 1.0 release that addressed security, portability,
+and bugs found, but no new functionality was added to improve the
+stability of the CUPS code.
+
+<P>CUPS 1.1 is based on IPP/1.1 and adds many of the functional
+enhancements that have been requested by our users. As with 1.0, CUPS
+1.1 will be followed by patch releases that address any problems found
+with the software but add no new features.
+
+<H2>Design Overview</H2>
+
+<P>Like most printing systems, CUPS is designed around a central print
+scheduling process that dispatches print jobs, processes administrative
+commands, provides printer status information to local and remote
+programs, and informs users as needed. Figure 1 shows the basic
+organization of CUPS.
+
+<CENTER><IMG SRC="images/cups-block-diagram.gif" WIDTH="470" HEIGHT="170"></CENTER>
+<P ALIGN="CENTER">Figure 1 - CUPS Block Diagram</P>
+
+<H3>Scheduler</H3>
+
+<P>The scheduler is a HTTP/1.1 server application that handles HTTP
+requests. Besides handling printer requests via IPP POST requests, the
+scheduler also acts as a full-featured web server for documentation,
+status monitoring, and administration.
+
+<P>The scheduler also manages a list of available printers on the LAN
+and dispatches print jobs as needed using the appropriate filters and
+backends.
+
+<H3>Configuration Files</H3>
+
+The configuration files consist of:
+
+<UL>
+
+ <LI>The HTTP server configuration file.
+
+ <LI>Printer and class definition files.
+
+ <LI>MIME type and conversion rule files.
+
+ <LI>PostScript Printer Description ("PPD") files.
+
+</UL>
+
+<P>The HTTP server configuration file is purposely similar to the
+Apache server configuration file and defines all of the access control
+properties for the server.
+
+<P>The printer and class definition files list the available printer
+queues and classes. Printer classes are collections of printers. Jobs
+sent to a class are forwarded to the first available printer in the
+class, round-robin fashion.
+
+<P>The MIME type files list the supported MIME types (text/plain,
+application/postscript, etc.) and "magic" rules for automatically
+detecting the format of a file. These are used by the HTTP server to
+determine the <I>Content-Type</I> field for <I>GET</I> and <I>HEAD</I>
+requests and by the IPP request handler to determine the file type
+when a <I>Print-Job</I> or <I>Send-File</I> request is received with a
+<I>document-format</I> of <I>application/octet-stream</I>.
+
+<P>The MIME conversion rule files list the available filters. The
+filters are used when a job is dispatched so that an application can
+send a convenient file format to the printing system which then
+converts the document into a printable format as needed. Each filter
+has a relative cost associated with it, and the filtering algorithm
+chooses the set of filters that will convert the file to the needed
+format with the lowest total "cost".
+
+<P>The PPD files describe the capabilities of all printers, not just
+PostScript printers. There is one PPD file for each printer. PPD files
+for non-PostScript printers define additional filters through
+<I>cupsFilter</I> attributes to support printer drivers.
+
+<H3>CUPS API</H3>
+
+<P>The CUPS API contains CUPS-specific convenience functions for queuing
+print jobs, getting printer information, accessing resources via HTTP
+and IPP, and manipulating PPD files. Unlike the rest of CUPS, the CUPS
+API is provided under the terms of the GNU LGPL so it may be used by
+non-GPL applications.
+
+<H3>Berkeley and System V Commands</H3>
+
+<P>CUPS provides the System V and Berkeley command-line interfaces for
+submitting jobs and checking the printer status. The
+<CODE>lpstat</CODE> and <CODE>lpc status</CODE> commands also show
+network printers ("printer@server") when printer browsing is enabled.
+
+<P>The System V administation commands are supplied for managing
+printers and classes. The Berkeley printer administration tool
+(<CODE>lpc</CODE>) is only supported in a "read-only" mode to check the
+current status of the printer queues and scheduler.
+
+<H3>Filters</H3>
+
+<P>A filter program reads from the standard input or from a file if a
+filename is supplied. All filters must support a common set of options
+including printer name, job ID, username, job title, number of copies,
+and job options. All output is sent to the standard output.
+
+<P>Filters are provided for many file formats and include image file
+and PostScript raster filters that support non-PostScript printers. Multiple
+filters are run in parallel to produce the required output format.
+
+<P>The PostScript raster filter is based on the GNU Ghostscript 5.50
+core. Instead of using the Ghostscript printer drivers and front-end,
+the CUPS filter uses a generic raster printer driver and CUPS-compliant
+front-end to support any kind of raster printer. This allows the same
+printer driver filter to be used for printing raster data from any
+filter.
+
+<H3>CUPS Imaging</H3>
+
+<P>The CUPS Imaging library provides functions for managing large
+images, doing colorspace conversion and color management, scaling
+images for printing, and managing raster page streams. It is used by
+the CUPS image file filters, the PostScript RIP, and all raster
+printers drivers.
+
+<H3>Backends</H3>
+
+<P>A backend program is a special filter that sends print data to a
+device or network connection. Backends for parallel, serial, USB, LPD, IPP,
+and AppSocket (JetDirect) connections are provided in CUPS 1.1.
+
+<P>SAMBA version 2.0.6 and higher includes a SMB backend
+(<CODE>smbspool(1)</CODE>) that can be used with CUPS 1.0 or 1.1 for
+printing to Windows.
+
+<H2>Network Printing</H2>
+
+<P>Traditionally, network printing has been one of the hardest things to
+get working under UNIX. One reason is because each vendor added their
+own extensions to the LPD protocol (the previous standard for network
+printing), making cross-platform printing difficult if not impossible.
+
+<P>Another reason is that you have to administer every network printer
+on every client machine. In some cases you can "clone" the printer
+configuration from a "master" client to each of the others, but even
+that can be time-consuming and error-prone. Something better is needed.
+
+<P>CUPS provides "printer browsing", which allows clients to
+automatically see and use printers from any server on a LAN. This means
+that you only need to configure the server and the clients will
+automatically see the printers and classes on it.
+
+<P>In addition, CUPS can automatically merge multiple identical network
+printers into "implicit classes". This allows clients to send jobs to
+the implicit class and have them print on the first available printer
+or server. In addition, failsafe and load-balancing functions are
+enabled simply by defining the same printer on multiple servers!
+
+<H2>New Features in CUPS 1.1</H2>
+
+<P>CUPS 1.1 includes many new features and capabilities:
+
+<OL>
+
+ <LI><A HREF="#BACKENDS">Backends</A>
+
+ <LI><A HREF="#BANNERS">Banner Page Support</A>
+
+ <LI><A HREF="#DIGEST">Digest Authentication</A>
+
+ <LI><A HREF="#DIRSVC">Directory Services</A>
+
+ <LI><A HREF="#FHS2">Directory Structure Changes</A>
+
+ <LI><A HREF="#DOCOS">Documentation</A>
+
+ <LI><A HREF="#DRIVERS">Drivers</A>
+
+ <LI><A HREF="#FILTERS">Filters</A>
+
+ <LI><A HREF="#IPP">IPP Support</A>
+
+ <LI><A HREF="#PERSISTENCE">Job Persistence</A>
+
+ <LI><A HREF="#LPD">LPD Client Support</A>
+
+ <LI><A HREF="#USEROPTS">User-Defined Printers and Options</A>
+
+ <LI><A HREF="#WEB">Web Administration Interface</A>
+
+</OL>
+
+<H3><A NAME="BACKENDS">1. Backends</A></H3>
+
+<P>CUPS 1.1 implements a new backend interface for retrieving a list of
+available devices for CUPS clients. This allows administration
+interfaces to query the CUPS scheduler for a list of available devices,
+automatically configure printers if the device identification
+information is available, and present the user with a list of available
+devices rather than relying on the user to know what devices are
+configured on the system.
+
+<P>The new release also includes a backend for USB printers under
+*BSD and Linux. Support for USB under Solaris 8 will be provided in
+a subsequent patch release.
+
+<H3><A NAME="BANNERS">2. Banner Page Support</A></H3>
+
+<P>CUPS 1.1 includes support for banner pages at the beginning and end
+of a job. Banner pages may be of any file format and support variable
+substitution for job titles, usernames, etc. Default banner pages are
+associated with each printer and can be overridden with command-line
+options by the user.
+
+<H3><A NAME="DIGEST">3. Digest Authentication</A></H3>
+
+<P>Digest authentication provides a more secure method of authenticating
+access to the printing system. Unlike Basic authentication, Digest
+authentication does not send passwords "in the clear" so it is more
+difficult to gain unauthorized access to your system.
+
+<P>CUPS 1.1 implements Digest authentication using a special MD5
+password file instead of the UNIX password file. This file is managed
+using the new <CODE>lppasswd</CODE> command.
+
+<H3><A NAME="DIRSVC">4. Directory Services</A></H3>
+
+<P>CUPS 1.1 adds new directory service ("printer browsing") features to
+make using CUPS on large LANs and WANs easier. You can now poll a
+remote server for printer information and relay it to the LAN as well
+as restrict what printer information is processed (e.g. to "hide"
+servers, domains, or networks that you don't want to see.)
+
+<H3><A NAME="FHS2">5. Directory Structure Changes</A></H3>
+
+<P>CUPS 1.1 now uses a directory structure that complies with the
+Filesystem Hierarchy Standard ("FHS"), version 2.0. This should make
+integration into existing Linux and *BSD distributions a lot easier.
+
+<H3><A NAME="DOCOS">6. Documentation</A></H3>
+
+<P>The CUPS 1.1 documentation has gone through many revisions,
+including a completely rewritten administrators manual, a new
+programmers manual, and an IPP implementation reference manual.
+
+<H3><A NAME="DRIVERS">7. Drivers</A></H3>
+
+<P>CUPS 1.1 includes drivers for EPSON dot-matrix and inkjet printers.
+As with the HP PCL drivers, the EPSON drivers don't necessarily provide
+the best possible output for each printer but should provide adequate
+printing quality for general day-to-day printing.
+
+<H3><A NAME="FILTERS">8. Filters</A></H3>
+
+<P>CUPS 1.1 includes new image, PostScript, PDF, and text filters. The image
+filters have been upgraded to support Windows BMP and Alias PIX files.
+
+<P>The PostScript filter is now based off GNU Ghostscript 5.50. The new
+filter provides much better performance with higher-resolution printers
+and supports most Level 3 PostScript language features.
+
+<P>The new PDF filter is based off the excellent Xpdf software from
+Derek Noonburg and supports automatic page scaling. The new filter is a
+faster, smaller, more reliable replacement for the GNU Ghostscript PDF
+filtering that was used in CUPS 1.0.
+
+<P>The new text filter now supports bidirectional text and can embed
+fonts as needed.
+
+<H3><A NAME="IPP">9. IPP Support</A></H3>
+
+<P>Probably the least visible portion of CUPS is the IPP support. CUPS
+1.1 implements all of the required IPP/1.1 operations and attributes
+and most of the optional ones. The optional Create-Job and Send-File
+operations are now implemented, allowing for better System V printing
+system compatibility (one job ID per <CODE>lp</CODE> command) and
+support for banner pages.
+
+<H3><A NAME="PERSISTENCE">10. Job Persistence</A></H3>
+
+<P>CUPS 1.1 supports job persistence. This means that jobs are preserved
+even after a reboot, a feature that was sorely missing from CUPS 1.0.
+
+<P>In addition, CUPS 1.1 allows you to keep job information after the
+job has printed. The basic post-job persistence mode provides a job
+history (number of pages printed, time job was printed, etc.) but does
+not preserve the actual job files. This can be changed to discard all
+information after a job is printed or keep the job files after printing
+so you can reprint a job at some later time.
+
+<H3><A NAME="LPD">11. LPD Client Support</A></H3>
+
+<P>By popular request, CUPS 1.1 supports LPD-based clients using a new
+mini-daemon that handles LPD requests and passes them on to the main
+server.
+
+<H3><A NAME="USEROPTS">12. User-Defined Printers and Options</A></H3>
+
+<P>CUPS 1.1 includes support for user-defined printers and options via
+a new <CODE>lpoptions</CODE> command. User-defined printers are special
+instances of the available printers (e.g. "printer/instance" or
+"printer@server/instance") that can have their own default options such
+as media size, resolution, and so forth. The <CODE>lpoptions</CODE>
+command can also be used to set a different default printer queue.
+
+<H3><A NAME="WEB">13. Web Administration Interface</A></H3>
+
+<P>CUPS 1.0 provided a simple class, job, and printer monitoring
+interface for web browsers. CUPS 1.1 replaces this interface with an
+enhanced administration interface that allows you to add, modify,
+delete, configure, and control classes, jobs, and printers.
+
+<H2>Software Using CUPS</H2>
+
+<P>A lot has happened since CUPS 1.0 came out, and many software packages
+are supporting CUPS. We have contributed code to the SAMBA team to support
+CUPS, and parts of that are already available in SAMBA 2.0.6 and 2.0.7.
+With any luck the final pieces that provide a complete integration with
+SAMBA will be available in the next release of SAMBA.
+
+<P>Two graphical interfaces have appeared on the scene that use CUPS as
+well. The KUPS project provides a KDE-based interface for CUPS and can be
+found at:
+
+<UL><PRE>
+<A HREF="http://kups.sourceforge.net">http://kups.sourceforge.net</A>
+</PRE></UL>
+
+<P>The X Printing Panel ("XPP") project provides a graphical printing
+panel for CUPS and can be found at:
+
+<UL><PRE>
+<A HREF="http://www.phy.uni-bayreuth.de/till/xpp">http://www.phy.uni-bayreuth.de/till/xpp/</A>
+</PRE></UL>
+
+<P>Numerous other filters, drivers, tutorials, etc. have been made available
+on the CUPS Links web page, available at:
+
+<UL><PRE>
+<A HREF="http://www.cups.org/links.php">http://www.cups.org/links.php</A>
+</PRE></UL>
+
+<P>Finally, our own ESP Print Pro software uses CUPS to provide drivers
+for thousands of printers and can be found at:
+
+<UL><PRE>
+<A HREF="http://www.easysw.com/printpro">http://www.easysw.com/printpro</A>
+</PRE></UL>
+
+<H2>Operating Systems Using CUPS</H2>
+
+<P>One of our goals has always been to get as many UNIX/Linux
+distributions using CUPS as possible. Debian is currently providing
+CUPS as part of its stable distribution, and many other distributions
+are considering it in their next releases.
+
+<H2>Summary</H2>
+
+<P>The Common UNIX Printing System provides a modern printing interface
+for UNIX applications that is both flexible and user-friendly. The
+software provides System V and Berkeley compatible command-line
+interfaces to ensure compatibility with existing applications. CUPS 1.1
+adds many new features that make it an even better choice for printing
+under UNIX.
+
+<H2>Who to Contact</H2>
+
+<P>For more information on CUPS please contact us at:
+
+<UL><PRE>
+Attn: CUPS Information
+Easy Software Products
+44141 Airport View Drive Suite 204
+Hollywood, Maryland 20636-3111 USA
+
++1.301.373.9600
+
+<A HREF="mailto:cups-info@cups.org">cups-info@cups.org</A>
+</PRE></UL>
+
+<H2>References</H2>
+
+<DL>
+
+ <DT>IEEE-1387.4</DT>
+
+ <DD>System Administration - Part 4: Printing Interfaces (draft)</DD>
+
+ <DT><A HREF="http://www.pwg.org/ipp/index.html">IETF-IPP</A></DT>
+
+ <DD>Internet Printing Protocol/1.1</DD>
+
+ <DT><A HREF="http://www.astart.com/lprng.html">LPRng</A></DT>
+
+ <DD>An enhanced, extended, and portable implementation of the
+ Berkeley LPR print spooler functionality</DD>
+
+ <DT>Palladin</DT>
+
+ <DD>A printing system developed at the Massachussetts Institute
+ of Technology</DD>
+
+ <DT><A HREF="http://www-usa.iona.com//hyplan/jmason/plp.html">PLP</A></DT>
+
+ <DD>The Portable Line Printer spooler system</DD>
+
+ <DT><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC1179</A></DT>
+
+ <DD>Line Printer Daemon Protocol</DD>
+
+ <DT><A HREF="http://www.ietf.org/rfc/rfc2046.txt">RFC2046</A></DT>
+
+ <DD>Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types</DD>
+
+ <DT><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</A></DT>
+
+ <DD>Hypertext Transfer Protocol -- HTTP/1.1</DD>
+
+</DL>
+
+<H2>Trademarks</H2>
+
+<P>The Common UNIX Printing System, CUPS, and the CUPS logo are the
+trademark property of Easy Software Products. All other trademarks are
+the property of their respective owners.
+
+</BODY>
+</HTML>
diff --git a/doc/overview.pdf b/doc/overview.pdf
new file mode 100644
index 000000000..93af94cde
--- /dev/null
+++ b/doc/overview.pdf
Binary files differ
diff --git a/doc/printing-overview.shtml b/doc/printing-overview.shtml
new file mode 100644
index 000000000..1682dae7f
--- /dev/null
+++ b/doc/printing-overview.shtml
@@ -0,0 +1,125 @@
+<H1 ALIGN="RIGHT"><A NAME="OVERVIEW">1 - Printing System Overview</A></H1>
+
+<P>This chapter provides an overview of how the Common UNIX Printing System
+works.
+
+<H2>The Printing Problem</H2>
+
+<P>For years <I>the printing problem</I> has plagued UNIX. Unlike
+Microsoft&reg; Windows&reg; or Mac OS, UNIX has no standard interface or
+system in place for supporting printers. Among the solutions currently
+available, the Berkeley and System V printing systems are the most
+prevalent.
+
+<P>These printing systems support line printers (text only) or
+PostScript printers (text and graphics), and with some coaxing they can
+be made to support a full range of printers and file formats. However,
+because each varient of the UNIX operating system uses a different
+printing system than the next developing printer drivers for a wide
+range of printers and operating systems is extremely difficult. That
+combined with the limited volume of customers for each UNIX varient has
+forced most printer vendors to give up supporting UNIX entirely.
+
+<P>CUPS is designed to eliminate <I>the printing problem</I>. One
+common printing system can be used by all UNIX varients to support the
+printing needs of users. Printer vendors can use its modular filter
+interface to develop a single driver program that supports a wide range
+of file formats with little or no effort. Since CUPS provides both the
+System V and Berkeley printing commands, users (and applications) can
+reap the benefits of this new technology with no changes.
+
+<H2>The Technology</H2>
+
+<P>CUPS is based upon an emerging Internet standard called the Internet
+Printing Protocol. IPP has been embraced by dozens of printer and
+printer server manufacturers and is supported by Microsoft Windows
+2000.
+
+<P>IPP defines a standard protocol for printing as well as managing
+print jobs and printer options like media size, resolution, and so
+forth. Like all IP-based protocols, IPP can be used locally or over the
+Internet to printers hundreds or thousands of miles away. Unlike other
+protocols, however, IPP also supports access control, authentication,
+and encryption, making it a much more capable and secure printing
+solution than older ones.
+
+<P>IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP")
+which is the basis of web servers on the Internet. This allows users
+to view documentation, check status information on a printer or server,
+and manage their printers, classes, and jobs using their web browser.
+
+<P>CUPS provides a complete IPP/1.1 based printing system that provides
+Basic, Digest, and local certificate authentication and user, domain,
+or IP-based access control. TLS encryption will be available in future
+versions of CUPS.
+
+<H2>Jobs</H2>
+
+<P>Each file or set of files that is submitted for printing is called a
+<I>job</I>. Jobs are identified by a unique number starting at 1 and
+are assigned to a particular destination, usually a printer. Jobs can
+also have options associated with them such as media size, number of
+copies, and priority.
+
+<H2>Classes</H2>
+
+<P>CUPS supports collections of printers known as <I>classes</I>. Jobs
+sent to a class are forwarded to the first available printer in the
+class.
+
+<H2>Filters</H2>
+
+<P>Filters allow a user or application to print many types of files
+without extra effort. Print jobs sent to a CUPS server are filtered
+before sending them to a printer. Some filters convert job files to
+different formats that the printer can understand. Others perform page
+selection and ordering tasks.
+
+<P>CUPS provides filters for printing many types of image files,
+HP-GL/2 files, PDF files, and text files. CUPS also supplies PostScript
+and image file Raster Image Processor ("RIP") filters that convert
+PostScript or image files into bitmaps that can be sent to a raster
+printer.
+
+<H2>Backends</H2>
+
+<P>Backends perform the most important task of all - they send the
+filtered print data to the printer.
+
+<P>CUPS provides backends for printing over parallel, serial, and USB
+ports, and over the network via the IPP, JetDirect (AppSocket), and
+Line Printer Daemon ("LPD") protocols. Additional backends are
+available in network service packages such as the SMB backend
+included with the popular SAMBA software.
+
+<P>Backends are also used to determine the available devices. On
+startup each backend is asked for a list of devices it supports,
+and any information that is available. This allows the parallel
+backend to tell CUPS that an EPSON Stylus Color 600 printer is
+attached to parallel port 1, for example.
+
+<H2>Printer Drivers</H2>
+
+<P>Printer drivers in CUPS consist of one of more filters specific to a
+printer. CUPS includes sample printer drivers for Hewlett-Packard
+LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color,
+and Stylus Photo printers. While these drivers do not generate optimal
+output for the different printer models, they do provide basic printing
+and demonstrate how you can write your own printer drivers and
+incorporate them into CUPS.
+
+<H2>Networking</H2>
+
+<P>Printers and classes on the local system are automatically shared
+with other systems on the network. This allows you to setup one system
+to print to a printer and use this system as a printer server or spool
+host for all of the others. Users may then select a local printer by
+name or a remote printer using "name@server".
+
+<P>CUPS also provides <I>implicit classes</I>, which are collections of
+printers and/or classes with the same name. This allows you to setup
+multiple servers pointing to the same physical network printer, for
+example, so that you aren't relying on a single system for printing.
+Because this also works with printer classes, you can setup multiple
+servers and printers and never worry about a single point of failure
+unless all of the printers and servers go down!
diff --git a/doc/references.shtml b/doc/references.shtml
new file mode 100644
index 000000000..e81cac3c9
--- /dev/null
+++ b/doc/references.shtml
@@ -0,0 +1,42 @@
+<H1>References</H1>
+
+<H2>CUPS Documentation</H2>
+
+<P>The following CUPS documentation is referenced by this document:
+
+<UL>
+ <LI>CUPS-CMP-1.1: CUPS Configuration Management Plan
+ <LI>CUPS-IDD-1.1: CUPS System Interface Design Description
+ <LI>CUPS-IPP-1.1: CUPS Implementation of IPP
+ <LI>CUPS-SAM-1.1.x: CUPS Software Administrators Manual
+ <LI>CUPS-SDD-1.1: CUPS Software Design Description
+ <LI>CUPS-SPM-1.1.x: CUPS Software Programming Manual
+ <LI>CUPS-SSR-1.1: CUPS Software Security Report
+ <LI>CUPS-STP-1.1: CUPS Software Test Plan
+ <LI>CUPS-SUM-1.1.x: CUPS Software Users Manual
+ <LI>CUPS-SVD-1.1: CUPS Software Version Description
+</UL>
+
+<H2>Other Documents</H2>
+
+<P>The following non-CUPS documents are referenced by this document:
+
+<UL>
+ <LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">Adobe
+ PostScript Printer Description File Format Specification,
+ Version 4.3.</A>
+ <LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">Adobe
+ PostScript Language Reference, Third Edition.</A>
+ <LI>IPP: Job and Printer Set Operations
+ <LI>IPP/1.1: Encoding and Transport
+ <LI>IPP/1.1: Implementers Guide
+ <LI>IPP/1.1: Model and Semantics
+ <LI><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179, Line Printer Daemon Protocol</A>
+ <LI><A HREF="http://www.ietf.org/rfc/rfc2567.txt">RFC 2567, Design Goals for an Internet Printing Protocol</A>
+ <LI><A HREF="http://www.ietf.org/rfc/rfc2568.txt">RFC 2568, Rationale for the Structure of the Model and Protocol
+ for the Internet Printing Protocol</A>
+ <LI><A HREF="http://www.ietf.org/rfc/rfc2569.txt">RFC 2569, Mapping between LPD and IPP Protocols</A>
+ <LI><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616, Hypertext Transfer Protocol -- HTTP/1.1</A>
+ <LI><A HREF="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617, HTTP Authentication: Basic and Digest Access</A>
+ Authentication
+</UL>
diff --git a/doc/sam.html b/doc/sam.html
new file mode 100644
index 000000000..6d3a1daa6
--- /dev/null
+++ b/doc/sam.html
@@ -0,0 +1,5303 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Software Administrators Manual</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-SAM-1.1.16">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY BGCOLOR="#ffffff">
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Software Administrators Manual</H1></A><BR>
+CUPS-SAM-1.1.16<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">Preface</A></B>
+<UL>
+<LI><A HREF="#1_1">System Overview</A></LI>
+<LI><A HREF="#1_2">Document Overview</A></LI>
+<LI><A HREF="#1_3">Notation Conventions</A></LI>
+<LI><A HREF="#1_4">Abbreviations</A></LI>
+<LI><A HREF="#1_5">Other References</A></LI>
+</UL>
+<B><A HREF="#OVERVIEW">1 - Printing System Overview</A></B>
+<UL>
+<LI><A HREF="#2_1">The Printing Problem</A></LI>
+<LI><A HREF="#2_2">The Technology</A></LI>
+<LI><A HREF="#2_3">Jobs</A></LI>
+<LI><A HREF="#2_4">Classes</A></LI>
+<LI><A HREF="#2_5">Filters</A></LI>
+<LI><A HREF="#2_6">Backends</A></LI>
+<LI><A HREF="#2_7">Printer Drivers</A></LI>
+<LI><A HREF="#2_8">Networking</A></LI>
+</UL>
+<B><A HREF="#BUILDING_INSTALLING">2 - Building and Installing CUPS</A></B>
+<UL>
+<LI><A HREF="#3_1">Installing a Source Distribution</A></LI>
+<UL>
+<LI><A HREF="#REQUIREMENTS">Requirements</A></LI>
+<LI><A HREF="#COMPILING">Compiling CUPS</A></LI>
+<LI><A HREF="#INSTALLING">Installing the Software</A></LI>
+<LI><A HREF="#RUNNING">Running the Software</A></LI>
+</UL>
+<LI><A HREF="#BINARY">Installing a Binary Distribution</A></LI>
+<UL>
+<LI><A HREF="#PORTABLE-BINARY">Installing a Portable Distribution</A></LI>
+<LI><A HREF="#RPM-BINARY">Installing an RPM Distribution</A></LI>
+<LI><A HREF="#DPKG-BINARY">Installing an Debian Distribution</A></LI>
+</UL>
+</UL>
+<B><A HREF="#MANAGING_PRINTERS">3 - Managing Printers</A></B>
+<UL>
+<LI><A HREF="#4_1">The Basics</A></LI>
+<LI><A HREF="#4_2">Adding Your First Printer</A></LI>
+<UL>
+<LI><A HREF="#4_2_1">Adding Your First Printer from the Command-Line</A></LI>
+<LI><A HREF="#ADD_WEB">Adding Your First Printer from the Web</A></LI>
+</UL>
+<LI><A HREF="#4_3">Managing Printers from the Command-Line</A></LI>
+<UL>
+<LI><A HREF="#4_3_1">Adding and Modifying Printers</A></LI>
+<LI><A HREF="#4_3_2">Deleting Printers</A></LI>
+<LI><A HREF="#4_3_3">Setting the Default Printer</A></LI>
+<LI><A HREF="#4_3_4">Starting and Stopping Printers</A></LI>
+<LI><A HREF="#4_3_5">Accepting and Rejecting Print Jobs</A></LI>
+<LI><A HREF="#4_3_6">Setting Quotas on a Printer</A></LI>
+<LI><A HREF="#4_3_7">Restricting User Access to a Printer</A></LI>
+</UL>
+<LI><A HREF="#4_4">Managing Printers from the Web</A></LI>
+</UL>
+<B><A HREF="#PRINTER_CLASSES">4 - Printer Classes</A></B>
+<UL>
+<LI><A HREF="#5_1">The Basics</A></LI>
+<LI><A HREF="#5_2">Managing Printer Classes from the Command-Line</A></LI>
+<LI><A HREF="#5_3">Managing Printer Classes from the Web Interface</A></LI>
+<LI><A HREF="#5_4">Implicit Classes</A></LI>
+</UL>
+<B><A HREF="#CLIENT_SETUP">5 - Client Setup</A></B>
+<UL>
+<LI><A HREF="#6_1">The Basics</A></LI>
+<UL>
+<LI><A HREF="#CLIENT_MANUAL">Manual Configuration of Print Queues</A></LI>
+<LI><A HREF="#CLIENT_SERVER">Specifying a Single Server for Printing</A></LI>
+<LI><A HREF="#CLIENT_AUTO">Automatic Configuration of Print Queues</A></LI>
+<LI><A HREF="#CLIENT_POLL">Specifying Multiple Servers for Printing</A></LI>
+<LI><A HREF="#CLIENT_RELAY">Relaying Printers to Other Clients</A></LI>
+</UL>
+<LI><A HREF="#6_2">Load Balancing and Failsafe Operation</A></LI>
+</UL>
+<B><A HREF="#PRINTING_MANAGEMENT">6 - Printing System Management</A></B>
+<UL>
+<LI><A HREF="#7_1">The Basics</A></LI>
+<LI><A HREF="#RESTARTING">Restarting the CUPS Server</A></LI>
+<LI><A HREF="#7_3">Changing the Server Configuration</A></LI>
+<LI><A HREF="#7_4">Server Directives</A></LI>
+<UL>
+<LI><A HREF="#AccessLog">AccessLog</A></LI>
+<LI><A HREF="#Allow">Allow</A></LI>
+<LI><A HREF="#AuthClass">AuthClass</A></LI>
+<LI><A HREF="#AuthGroupName">AuthGroupName</A></LI>
+<LI><A HREF="#AuthType">AuthType</A></LI>
+<LI><A HREF="#AutoPurgeJobs">AutoPurgeJobs</A></LI>
+<LI><A HREF="#BrowseAddress">BrowseAddress</A></LI>
+<LI><A HREF="#BrowseAllow">BrowseAllow</A></LI>
+<LI><A HREF="#BrowseDeny">BrowseDeny</A></LI>
+<LI><A HREF="#BrowseOrder">BrowseOrder</A></LI>
+<LI><A HREF="#BrowseInterval">BrowseInterval</A></LI>
+<LI><A HREF="#BrowsePoll">BrowsePoll</A></LI>
+<LI><A HREF="#BrowsePort">BrowsePort</A></LI>
+<LI><A HREF="#BrowseProtocols">BrowseProtocols</A></LI>
+<LI><A HREF="#BrowseRelay">BrowseRelay</A></LI>
+<LI><A HREF="#BrowseShortNames">BrowseShortNames</A></LI>
+<LI><A HREF="#BrowseTimeout">BrowseTimeout</A></LI>
+<LI><A HREF="#Browsing">Browsing</A></LI>
+<LI><A HREF="#Classification">Classification</A></LI>
+<LI><A HREF="#ClassifyOverride">ClassifyOverride</A></LI>
+<LI><A HREF="#ConfigFilePerm">ConfigFilePerm</A></LI>
+<LI><A HREF="#DataDir">DataDir</A></LI>
+<LI><A HREF="#DefaultCharset">DefaultCharset</A></LI>
+<LI><A HREF="#DefaultLanguage">DefaultLanguage</A></LI>
+<LI><A HREF="#Deny">Deny</A></LI>
+<LI><A HREF="#DocumentRoot">DocumentRoot</A></LI>
+<LI><A HREF="#Encryption">Encryption</A></LI>
+<LI><A HREF="#ErrorLog">ErrorLog</A></LI>
+<LI><A HREF="#FilterLimit">FilterLimit</A></LI>
+<LI><A HREF="#FilterNice">FilterNice</A></LI>
+<LI><A HREF="#FontPath">FontPath</A></LI>
+<LI><A HREF="#Group">Group</A></LI>
+<LI><A HREF="#HideImplicitMembers">HideImplicitMembers</A></LI>
+<LI><A HREF="#HostNameLookups">HostNameLookups</A></LI>
+<LI><A HREF="#ImplicitClasses">ImplicitClasses</A></LI>
+<LI><A HREF="#ImplicitAnyClasses">ImplicitAnyClasses</A></LI>
+<LI><A HREF="#Include">Include</A></LI>
+<LI><A HREF="#KeepAlive">KeepAlive</A></LI>
+<LI><A HREF="#KeepAliveTimeout">KeepAliveTimeout</A></LI>
+<LI><A HREF="#Limit">Limit</A></LI>
+<LI><A HREF="#LimitExcept">LimitExcept</A></LI>
+<LI><A HREF="#LimitRequestBody">LimitRequestBody</A></LI>
+<LI><A HREF="#Listen">Listen</A></LI>
+<LI><A HREF="#Location">Location</A></LI>
+<LI><A HREF="#LogFilePerm">LogFilePerm</A></LI>
+<LI><A HREF="#LogLevel">LogLevel</A></LI>
+<LI><A HREF="#MaxClients">MaxClients</A></LI>
+<LI><A HREF="#MaxCopies">MaxCopies</A></LI>
+<LI><A HREF="#MaxJobs">MaxJobs</A></LI>
+<LI><A HREF="#MaxJobsPerPrinter">MaxJobsPerPrinter</A></LI>
+<LI><A HREF="#MaxJobsPerUser">MaxJobsPerUser</A></LI>
+<LI><A HREF="#MaxLogSize">MaxLogSize</A></LI>
+<LI><A HREF="#MaxRequestSize">MaxRequestSize</A></LI>
+<LI><A HREF="#Order">Order</A></LI>
+<LI><A HREF="#PageLog">PageLog</A></LI>
+<LI><A HREF="#Port">Port</A></LI>
+<LI><A HREF="#PreserveJobHistory">PreserveJobHistory</A></LI>
+<LI><A HREF="#PreserveJobFiles">PreserveJobFiles</A></LI>
+<LI><A HREF="#Printcap">Printcap</A></LI>
+<LI><A HREF="#PrintcapFormat">PrintcapFormat</A></LI>
+<LI><A HREF="#PrintcapGUI">PrintcapGUI</A></LI>
+<LI><A HREF="#RemoteRoot">RemoteRoot</A></LI>
+<LI><A HREF="#RequestRoot">RequestRoot</A></LI>
+<LI><A HREF="#Require">Require</A></LI>
+<LI><A HREF="#RIPCache">RIPCache</A></LI>
+<LI><A HREF="#RootCertDuration">RootCertDuration</A></LI>
+<LI><A HREF="#RunAsUser">RunAsUser</A></LI>
+<LI><A HREF="#Satisfy">Satisfy</A></LI>
+<LI><A HREF="#ServerAdmin">ServerAdmin</A></LI>
+<LI><A HREF="#ServerBin">ServerBin</A></LI>
+<LI><A HREF="#ServerCertificate">ServerCertificate</A></LI>
+<LI><A HREF="#ServerKey">ServerKey</A></LI>
+<LI><A HREF="#ServerName">ServerName</A></LI>
+<LI><A HREF="#ServerRoot">ServerRoot</A></LI>
+<LI><A HREF="#SSLListen">SSLListen</A></LI>
+<LI><A HREF="#SSLPort">SSLPort</A></LI>
+<LI><A HREF="#SystemGroup">SystemGroup</A></LI>
+<LI><A HREF="#TempDir">TempDir</A></LI>
+<LI><A HREF="#Timeout">Timeout</A></LI>
+<LI><A HREF="#User">User</A></LI>
+</UL>
+<LI><A HREF="#PRINTING_SECURITY">Printing System Security</A></LI>
+<UL>
+<LI><A HREF="#CERTIFICATES">Authentication Using Certificates</A></LI>
+<LI><A HREF="#7_5_2">Using Basic Authentication</A></LI>
+<LI><A HREF="#7_5_3">Using Digest Authentication</A></LI>
+<LI><A HREF="#7_5_4">System and Group Authentication</A></LI>
+</UL>
+<LI><A HREF="#PRINTER_ACCOUNTING">Printer Accounting</A></LI>
+<UL>
+<LI><A HREF="#7_6_1">The access_log File</A></LI>
+<LI><A HREF="#7_6_2">The error_log File</A></LI>
+<LI><A HREF="#7_6_3">The page_log File</A></LI>
+</UL>
+<LI><A HREF="#FILE_TYPING_FILTERING">File Typing and Filtering</A></LI>
+<UL>
+<LI><A HREF="#7_7_1">mime.types</A></LI>
+<LI><A HREF="#7_7_2">mime.convs</A></LI>
+<LI><A HREF="#7_7_3">Adding Filetypes and Filters</A></LI>
+<LI><A HREF="#7_7_4">Printer Drivers and PPD Files</A></LI>
+<LI><A HREF="#7_7_5">Writing Your Own Filter or Printer Driver</A></LI>
+</UL>
+</UL>
+<B><A HREF="#PRINTING_OTHER">7 - Printing with Other Systems</A></B>
+<UL>
+<LI><A HREF="#8_1">The Basics</A></LI>
+<LI><A HREF="#8_2">Printing from LPD Clients</A></LI>
+<LI><A HREF="#8_3">Printing to LPD Servers</A></LI>
+<LI><A HREF="#8_4">Printing from Mac OS Clients</A></LI>
+<UL>
+<LI><A HREF="#8_4_1">Columbia Appletalk Package (CAP)</A></LI>
+<LI><A HREF="#8_4_2">XINET KA/Spool</A></LI>
+<LI><A HREF="#8_4_3">NetATalk</A></LI>
+</UL>
+<LI><A HREF="#8_5">Printing to Mac OS Servers</A></LI>
+<LI><A HREF="#8_6">Printing from Windows Clients</A></LI>
+<UL>
+<LI><A HREF="#8_6_1">Exporting Printer Drivers</A></LI>
+</UL>
+<LI><A HREF="#8_7">Printing to Windows Servers</A></LI>
+</UL>
+<B><A HREF="#LICENSE">A - Software License Agreement</A></B>
+<UL>
+<LI><A HREF="#9_1">Common UNIX Printing System License Agreement</A></LI>
+<UL>
+<LI><A HREF="#9_1_1">Introduction</A></LI>
+<LI><A HREF="#9_1_2">License Exceptions</A></LI>
+<LI><A HREF="#9_1_3">Trademarks</A></LI>
+<LI><A HREF="#9_1_4">Binary Distribution Rights</A></LI>
+<LI><A HREF="#9_1_5">Support</A></LI>
+</UL>
+<LI><A HREF="#9_2">GNU GENERAL PUBLIC LICENSE</A></LI>
+<LI><A HREF="#9_3">GNU LIBRARY GENERAL PUBLIC LICENSE</A></LI>
+</UL>
+<B><A HREF="#COMMON_NETWORK">B - Common Network Settings</A></B>
+<UL>
+<LI><A HREF="#10_1">Configuring a Network Interface</A></LI>
+<UL>
+<LI><A HREF="#10_1_1">Configuring the IP Address Using ARP</A></LI>
+<LI><A HREF="#10_1_2">Configuring the IP Address Using RARP</A></LI>
+<LI><A HREF="#10_1_3">Configuring the IP Address Using BOOTP</A></LI>
+</UL>
+<LI><A HREF="#10_2">Verifying the Printer Connection</A></LI>
+<LI><A HREF="#10_3">Common Network Interface Settings</A></LI>
+<LI><A HREF="#AXIS">Configuring Axis Print Servers</A></LI>
+<LI><A HREF="#LINKSYS">Configuring Linksys Print Servers</A></LI>
+</UL>
+<B><A HREF="#PRINTER_DRIVERS">C - Printer Drivers</A></B>
+<UL>
+<LI><A HREF="#11_1">Printer Drivers</A></LI>
+<LI><A HREF="#EPSON9">EPSON 9-pin Dot Matrix</A></LI>
+<LI><A HREF="#EPSON24">EPSON 24-pin Dot Matrix</A></LI>
+<LI><A HREF="#STCOLOR">EPSON Stylus Color</A></LI>
+<LI><A HREF="#STPHOTO">EPSON Stylus Photo</A></LI>
+<LI><A HREF="#DESKJET">HP DeskJet</A></LI>
+<LI><A HREF="#LASERJET">HP LaserJet</A></LI>
+</UL>
+<B><A HREF="#FILES">D - List of Files</A></B>
+<BR>
+<BR><B><A HREF="#FAQ">E - Troubleshooting Common Problems</A></B>
+<UL>
+<LI><A HREF="#13_1">My Applications Don't See the Available Printers</A></LI>
+<LI><A HREF="#13_2">CUPS Doesn't Recognize My Username or Password!</A></LI>
+<LI><A HREF="#ALLOW_REMOTE">I Can't Do Administration Tasks from Another
+ Machine!</A></LI>
+<LI><A HREF="#13_4">I Can't Do Administration Tasks from My Web Browser!</A>
+</LI>
+<LI><A HREF="#13_5">Connection Refused Messages</A></LI>
+<LI><A HREF="#13_6">Write Error Messages</A></LI>
+</UL>
+<HR>
+<H1 ALIGN="RIGHT"><A NAME="1">Preface</A></H1>
+<P>This software administrators manual provides printer administration
+ information for the Common UNIX Printing System<SUP>TM</SUP> (&quot;CUPS<SUP>
+TM</SUP>&quot;), version 1.1.16.</P>
+<H2><A NAME="1_1">System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+
+<!-- NEED 3in -->
+<H2><A NAME="1_2">Document Overview</A></H2>
+<P>This software administrators manual is organized into the following
+ sections:</P>
+<UL>
+<LI><A HREF="#OVERVIEW">1 - Printing System Overview</A></LI>
+<LI><A HREF="#BUILDING_INSTALLING">2 - Building and Installing CUPS</A></LI>
+<LI><A HREF="#MANAGING_PRINTERS">3 - Managing Printers</A></LI>
+<LI><A HREF="#PRINTER_CLASSES">4 - Printer Classes</A></LI>
+<LI><A HREF="#CLIENT_SETUP">5 - Client Setup</A></LI>
+<LI><A HREF="#PRINTING_MANAGEMENT">6 - Printing System Management</A></LI>
+<LI><A HREF="#PRINTING_OTHER">7 - Printing with Other Systems</A></LI>
+<LI><A HREF="#LICENSE">A - Software License Agreement</A></LI>
+<LI><A HREF="#COMMON_NETWORK">B - Common Network Settings</A></LI>
+<LI><A HREF="#PRINTER_DRIVERS">C - Printer Drivers</A></LI>
+<LI><A HREF="#FILES">D - List of Files</A></LI>
+<LI><A HREF="#FAQ">E - Troubleshooting Common Problems</A></LI>
+</UL>
+<H2><A NAME="1_3">Notation Conventions</A></H2>
+<P>Various font and syntax conventions are used in this guide. Examples
+ and their meanings and uses are explained below:
+<CENTER>
+<TABLE WIDTH="80%">
+<TR><TH>Example</TH><TD>&nbsp;&nbsp;&nbsp;</TD><TH>Description</TH></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD><CODE>lpstat</CODE>
+<BR> <CODE>lpstat(1)</CODE></TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>The names of commands;
+ the first mention of a command or function in a chapter is followed by
+ a manual page section number.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD><VAR>/var</VAR>
+<BR><VAR> /usr/share/cups/data/testprint.ps</VAR></TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>
+File and directory names.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD NOWRAP><TT>Request ID is Printer-123</TT></TD><TD>
+&nbsp;&nbsp;&nbsp;</TD><TD>Screen output.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD NOWRAP><KBD>lp -d printer filename ENTER</KBD></TD><TD>
+&nbsp;&nbsp;&nbsp;</TD><TD>Literal user input; special keys like <KBD>ENTER</KBD> are
+ in ALL CAPS.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD>12.3</TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>Numbers in the text are
+ written using the period (.) to indicate the decimal point.</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+</P>
+<H2><A NAME="1_4">Abbreviations</A></H2>
+ The following abbreviations are used throughout this manual:
+<UL>
+<DL>
+<DT>kb</DT>
+<DD>Kilobytes, or 1024 bytes
+<BR>&nbsp;</DD>
+<DT>Mb</DT>
+<DD>Megabytes, or 1048576 bytes
+<BR>&nbsp;</DD>
+<DT>Gb</DT>
+<DD>Gigabytes, or 1073741824 bytes
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H2><A NAME="1_5">Other References</A></H2>
+<UL>
+<DL>
+<DT>CUPS Software Programmers Manual</DT>
+<DD>A programmer guide for interfacing with and/or extending the CUPS
+ software.
+<BR>&nbsp;</DD>
+<DT>CUPS Software Users Manual</DT>
+<DD>An end-user guide for using the CUPS software.
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H1 ALIGN="RIGHT"><A NAME="OVERVIEW">1 - Printing System Overview</A></H1>
+<P>This chapter provides an overview of how the Common UNIX Printing
+ System works.</P>
+<H2><A NAME="2_1">The Printing Problem</A></H2>
+<P>For years<I> the printing problem</I> has plagued UNIX. Unlike
+ Microsoft&reg; Windows&reg; or Mac OS, UNIX has no standard interface or system
+ in place for supporting printers. Among the solutions currently
+ available, the Berkeley and System V printing systems are the most
+ prevalent.</P>
+<P>These printing systems support line printers (text only) or
+ PostScript printers (text and graphics), and with some coaxing they can
+ be made to support a full range of printers and file formats. However,
+ because each varient of the UNIX operating system uses a different
+ printing system than the next developing printer drivers for a wide
+ range of printers and operating systems is extremely difficult. That
+ combined with the limited volume of customers for each UNIX varient has
+ forced most printer vendors to give up supporting UNIX entirely.</P>
+<P>CUPS is designed to eliminate<I> the printing problem</I>. One common
+ printing system can be used by all UNIX varients to support the
+ printing needs of users. Printer vendors can use its modular filter
+ interface to develop a single driver program that supports a wide range
+ of file formats with little or no effort. Since CUPS provides both the
+ System V and Berkeley printing commands, users (and applications) can
+ reap the benefits of this new technology with no changes.</P>
+<H2><A NAME="2_2">The Technology</A></H2>
+<P>CUPS is based upon an emerging Internet standard called the Internet
+ Printing Protocol. IPP has been embraced by dozens of printer and
+ printer server manufacturers and is supported by Microsoft Windows
+ 2000.</P>
+<P>IPP defines a standard protocol for printing as well as managing
+ print jobs and printer options like media size, resolution, and so
+ forth. Like all IP-based protocols, IPP can be used locally or over the
+ Internet to printers hundreds or thousands of miles away. Unlike other
+ protocols, however, IPP also supports access control, authentication,
+ and encryption, making it a much more capable and secure printing
+ solution than older ones.</P>
+<P>IPP is layered on top of the Hyper-Text Transport Protocol (&quot;HTTP&quot;)
+ which is the basis of web servers on the Internet. This allows users to
+ view documentation, check status information on a printer or server,
+ and manage their printers, classes, and jobs using their web browser.</P>
+<P>CUPS provides a complete IPP/1.1 based printing system that provides
+ Basic, Digest, and local certificate authentication and user, domain,
+ or IP-based access control. TLS encryption will be available in future
+ versions of CUPS.</P>
+<H2><A NAME="2_3">Jobs</A></H2>
+<P>Each file or set of files that is submitted for printing is called a<I>
+ job</I>. Jobs are identified by a unique number starting at 1 and are
+ assigned to a particular destination, usually a printer. Jobs can also
+ have options associated with them such as media size, number of copies,
+ and priority.</P>
+<H2><A NAME="2_4">Classes</A></H2>
+<P>CUPS supports collections of printers known as<I> classes</I>. Jobs
+ sent to a class are forwarded to the first available printer in the
+ class.</P>
+<H2><A NAME="2_5">Filters</A></H2>
+<P>Filters allow a user or application to print many types of files
+ without extra effort. Print jobs sent to a CUPS server are filtered
+ before sending them to a printer. Some filters convert job files to
+ different formats that the printer can understand. Others perform page
+ selection and ordering tasks.</P>
+<P>CUPS provides filters for printing many types of image files, HP-GL/2
+ files, PDF files, and text files. CUPS also supplies PostScript and
+ image file Raster Image Processor (&quot;RIP&quot;) filters that convert
+ PostScript or image files into bitmaps that can be sent to a raster
+ printer.</P>
+<H2><A NAME="2_6">Backends</A></H2>
+<P>Backends perform the most important task of all - they send the
+ filtered print data to the printer.</P>
+<P>CUPS provides backends for printing over parallel, serial, and USB
+ ports, and over the network via the IPP, JetDirect (AppSocket), and
+ Line Printer Daemon (&quot;LPD&quot;) protocols. Additional backends are
+ available in network service packages such as the SMB backend included
+ with the popular SAMBA software.</P>
+<P>Backends are also used to determine the available devices. On startup
+ each backend is asked for a list of devices it supports, and any
+ information that is available. This allows the parallel backend to tell
+ CUPS that an EPSON Stylus Color 600 printer is attached to parallel
+ port 1, for example.</P>
+<H2><A NAME="2_7">Printer Drivers</A></H2>
+<P>Printer drivers in CUPS consist of one of more filters specific to a
+ printer. CUPS includes sample printer drivers for Hewlett-Packard
+ LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color,
+ and Stylus Photo printers. While these drivers do not generate optimal
+ output for the different printer models, they do provide basic printing
+ and demonstrate how you can write your own printer drivers and
+ incorporate them into CUPS.</P>
+<H2><A NAME="2_8">Networking</A></H2>
+<P>Printers and classes on the local system are automatically shared
+ with other systems on the network. This allows you to setup one system
+ to print to a printer and use this system as a printer server or spool
+ host for all of the others. Users may then select a local printer by
+ name or a remote printer using &quot;name@server&quot;.</P>
+<P>CUPS also provides<I> implicit classes</I>, which are collections of
+ printers and/or classes with the same name. This allows you to setup
+ multiple servers pointing to the same physical network printer, for
+ example, so that you aren't relying on a single system for printing.
+ Because this also works with printer classes, you can setup multiple
+ servers and printers and never worry about a single point of failure
+ unless all of the printers and servers go down!</P>
+<H1 ALIGN="RIGHT"><A NAME="BUILDING_INSTALLING">2 - Building and
+ Installing CUPS</A></H1>
+<P>This chapter shows how to build and install the Common UNIX Printing
+ System. If you are installing a binary distribution from the CUPS web
+ site, proceed to the section titled,<A HREF="#BINARY"> Installing a
+ Binary Distribution</A>.</P>
+<H2><A NAME="3_1">Installing a Source Distribution</A></H2>
+<P>This section describes how to compile and install CUPS on your system
+ from the source code.</P>
+<H3><A NAME="REQUIREMENTS">Requirements</A></H3>
+<P>You'll need ANSI-compliant C and C++ compilers to build CUPS on your
+ system. As its name implies, CUPS is designed to run on the UNIX
+ operating system, however the CUPS interface library and most of the
+ filters and backends supplied with CUPS should also compile and run
+ under Microsoft Windows.</P>
+<P>For the image file filters and PostScript RIP, you'll need the JPEG,
+ PNG, TIFF, and ZLIB libraries. CUPS will build without these, but with
+ significantly reduced functionality. Easy Software Products maintains a
+ mirror of the current versions of these libraries at:</P>
+<UL>
+<PRE>
+<A HREF="ftp://ftp.easysw.com/pub/libraries">ftp://ftp.easysw.com/pub/libraries</A>
+</PRE>
+</UL>
+<P>If you make changes to the man pages you'll need GNU groff or another
+ nroff-like package. GNU groff is available from:</P>
+<UL>
+<PRE>
+<A HREF="ftp://ftp.gnu.org/pub/groff">ftp://ftp.gnu.org/pub/groff</A>
+</PRE>
+</UL>
+<P>The documentation is formatted using the HTMLDOC software. If you
+ need to make changes you can get the HTMLDOC software from:</P>
+<UL>
+<PRE>
+<A HREF="http://www.easysw.com/htmldoc">http://www.easysw.com/htmldoc</A>
+</PRE>
+</UL>
+<P>Finally, you'll need a <CODE>make</CODE> program that understands the
+ <CODE>include</CODE> directive - FreeBSD, NetBSD, and OpenBSD
+ developers should use the <CODE>gmake</CODE> program.</P>
+<H3><A NAME="COMPILING">Compiling CUPS</A></H3>
+<P>CUPS uses GNU autoconf to configure the makefiles and source code for
+ your system. Type the following command to configure CUPS for your
+ system:</P>
+<UL>
+<PRE>
+<B>./configure ENTER</B>
+</PRE>
+</UL>
+<P>The default installation will put the CUPS software in the<VAR> /etc</VAR>
+,<VAR> /usr</VAR>, and<VAR> /var</VAR> directories on your system, which
+ will overwrite any existing printing commands on your system. Use the <CODE>
+--prefix</CODE> option to install the CUPS software in another location:</P>
+<UL>
+<PRE>
+<B>./configure --prefix=/some/directory ENTER</B>
+</PRE>
+</UL>
+<P>If the PNG, JPEG, TIFF, and ZLIB libraries are not installed in a
+ system default location (typically<VAR> /usr/include</VAR> and<VAR>
+ /usr/lib</VAR>) you'll need to set the <CODE>CFLAGS</CODE>, <CODE>
+CXXFLAGS</CODE>, and <CODE>LDFLAGS</CODE> environment variables prior to
+ running configure:</P>
+<UL>
+<PRE>
+<B>setenv CFLAGS &quot;-I/some/directory&quot; ENTER</B>
+<B>setenv CXXFLAGS &quot;-I/some/directory&quot; ENTER</B>
+<B>setenv LDFLAGS &quot;-L/some/directory&quot; ENTER</B>
+<B>setenv DSOFLAGS &quot;-L/some/directory&quot; ENTER</B>
+<B>./configure ... ENTER</B>
+</PRE>
+</UL>
+<P>or:</P>
+<UL>
+<PRE>
+<B>CFLAGS=&quot;-I/some/directory&quot;; export CFLAGS ENTER</B>
+<B>CXXFLAGS=&quot;-I/some/directory&quot;; export CXXFLAGS ENTER</B>
+<B>LDFLAGS=&quot;-L/some/directory&quot;; export LDFLAGS ENTER</B>
+<B>DSOFLAGS=&quot;-L/some/directory&quot;; export DSOFLAGS ENTER</B>
+<B>./configure ... ENTER</B>
+</PRE>
+</UL>
+<P>To enable support for encryption, you'll also want to add the
+ &quot;--enable-ssl&quot; option:</P>
+<UL>
+<PRE>
+./configure --enable-ssl
+</PRE>
+</UL>
+<P>SSL and TLS support require the OpenSSL library, available at:</P>
+<UL>
+<PRE>
+<A HREF="http://www.openssl.org">http://www.openssl.org</A>
+</PRE>
+</UL>
+<P>If the OpenSSL headers and libraries are not installed in the
+ standard directories, use the <CODE>--with-openssl-includes</CODE> and <CODE>
+--with-openssl-libs</CODE> options:</P>
+<UL>
+<PRE>
+./configure --enable-ssl \
+ --with-openssl-includes=/foo/bar/include \
+ --with-openssl-libs=/foo/bar/lib
+</PRE>
+</UL>
+<P>Once you have configured things, just type:</P>
+<UL>
+<PRE>
+<B>make ENTER</B>
+</PRE>
+</UL>
+<P>to build the software.
+<!-- NEED 4in -->
+</P>
+<H3><A NAME="INSTALLING">Installing the Software</A></H3>
+<P>Use the &quot;install&quot; target to install the software:</P>
+<UL>
+<PRE>
+<B>make install ENTER</B>
+</PRE>
+</UL>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> WARNING:</B>
+<P>Installing CUPS will overwrite your existing printing system. If you
+ experience difficulties with the CUPS software and need to go back to
+ your old printing system, you will need to reinstall the old printing
+ system from your operating system CDs.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="RUNNING">Running the Software</A></H3>
+<P>Once you have installed the software you can start the CUPS server by
+ typing:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/cupsd ENTER</B>
+</PRE>
+</UL>
+
+<!-- NEED 4in -->
+<H2><A NAME="BINARY">Installing a Binary Distribution</A></H2>
+<P>CUPS comes in a variety of binary distribution formats. Easy Software
+ Products provides binaries in TAR format with installation and removal
+ scripts (&quot;portable&quot; distributions), and in RPM and DPKG formats for Red
+ Hat and Debian-based distributions. Portable distributions are
+ available for all platforms, while the RPM and DPKG distributions are
+ only available for Linux.
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> WARNING:</B>
+<P>Installing CUPS will overwrite your existing printing system. If you
+ experience difficulties with the CUPS software and need to go back to
+ your old printing system, you will need to remove the CUPS software
+ with the provided script and/or reinstall the old printing system from
+ your operating system CDs.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="PORTABLE-BINARY">Installing a Portable Distribution</A></H3>
+<P>To install the CUPS software from a portable distribution you will
+ need to be logged in as root; doing an <CODE>su</CODE> is good enough.
+ Once you are the root user, run the installation script with:</P>
+<UL>
+<PRE>
+<B>./cups.install ENTER</B>
+</PRE>
+</UL>
+<P>After asking you a few yes/no questions the CUPS software will be
+ installed and the scheduler will be started automatically.
+<!-- NEED 2in -->
+</P>
+<H3><A NAME="RPM-BINARY">Installing an RPM Distribution</A></H3>
+<P>To install the CUPS software from an RPM distribution you will need
+ to be logged in as root; doing an <CODE>su</CODE> is good enough. Once
+ you are the root user, run RPM with:</P>
+<UL>
+<PRE>
+<B>rpm -e lpr</B>
+<B>rpm -i cups-1.1-linux-M.m.n-intel.rpm ENTER</B>
+</PRE>
+</UL>
+<P>After a short delay the CUPS software will be installed and the
+ scheduler will be started automatically.</P>
+<H3><A NAME="DPKG-BINARY">Installing an Debian Distribution</A></H3>
+<P>To install the CUPS software from a Debian distribution you will need
+ to be logged in as root; doing an <CODE>su</CODE> is good enough. Once
+ you are the root user, run dpkg with:</P>
+<UL>
+<PRE>
+<B>dpkg -i cups-1.1-linux-M.m.n-intel.deb ENTER</B>
+</PRE>
+</UL>
+<P>After a short delay the CUPS software will be installed and the
+ scheduler will be started automatically.</P>
+<H1 ALIGN="RIGHT"><A NAME="MANAGING_PRINTERS">3 - Managing Printers</A></H1>
+<P>This chapter describes how to add your first printer and how to
+ manage your printers.</P>
+<H2><A NAME="4_1">The Basics</A></H2>
+<P>Each printer queue has a name associated with it; the printer name
+ must start with a letter and can contain up to 127 letters, numbers,
+ and the underscore (_). Case is not significant, e.g. &quot;PRINTER&quot;,
+ &quot;Printer&quot;, and &quot;printer&quot; are considered to be the same name.</P>
+<P>Printer queues also have a device associated with them. The device
+ can be a parallel port, a network interface, and so forth. Devices
+ within CUPS use Uniform Resource Identifiers (&quot;URIs&quot;) which are a more
+ general form of Uniform Resource Locators (&quot;URLs&quot;) that are used in
+ your web browser. For example, the first parallel port in Linux usually
+ uses a device URI of <CODE>parallel:/dev/lp1</CODE>.
+<!-- NEED 2.5in -->
+</P>
+<P>You can see a complete list of supported devices by running the <CODE>
+lpinfo(8)</CODE> command:</P>
+<UL>
+<PRE>
+<B>lpinfo -v ENTER</B>
+network socket
+network http
+network ipp
+network lpd
+direct parallel:/dev/lp1
+serial serial:/dev/ttyS1?baud=115200
+serial serial:/dev/ttyS2?baud=115200
+direct usb:/dev/usb/lp0
+network smb
+</PRE>
+</UL>
+<P>The <CODE>-v</CODE> option specifies that you want a list of
+ available devices. The first word in each line is the type of device
+ (direct, file, network, or serial) and is followed by the device URI or
+ method name for that device. File devices have device URIs of the form <CODE>
+file:/directory/filename</CODE> while network devices use the more
+ familiar <CODE>method://server</CODE> or <CODE>method://server/path</CODE>
+ format.</P>
+<P>Finally, printer queues usually have a PostScript Printer Description
+ (&quot;PPD&quot;) file associated with them. PPD files describe the capabilities
+ of each printer, the page sizes supported, etc., and are used for
+ PostScript and non-PostScript printers. CUPS includes PPD files for HP
+ LaserJet, HP DeskJet, EPSON 9-pin, EPSON 24-pin, and EPSON Stylus
+ printers.</P>
+<H2><A NAME="4_2">Adding Your First Printer</A></H2>
+<P>CUPS provides two methods for adding printers: a command-line program
+ called <CODE>lpadmin(8)</CODE> and a Web interface. The <CODE>lpadmin</CODE>
+ command allows you to perform most printer administration tasks from
+ the command-line and is located in<VAR> /usr/sbin</VAR>. The Web
+ interface is located at:</P>
+<UL>
+<PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE>
+</UL>
+<P>and steps you through printer configuration. If you don't like
+ command-line interfaces, try the<A HREF="#ADD_WEB"> Web interface</A>
+ instead.</P>
+<H3><A NAME="4_2_1">Adding Your First Printer from the Command-Line</A></H3>
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> option
+ to add a printer to CUPS:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -E -v <I>device</I> -m <I>ppd</I> ENTER</B>
+</PRE>
+</UL>
+<P>For a HP DeskJet printer connected to the parallel port this would
+ look like:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p DeskJet -E -v parallel:/dev/lp1 -m deskjet.ppd ENTER</B>
+</PRE>
+</UL>
+<P>Similarly, a HP LaserJet printer using a JetDirect network interface
+ at IP address 11.22.33.44 would be added with the command:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p LaserJet -E -v socket://11.22.33.44 -m laserjet.ppd ENTER</B>
+</PRE>
+</UL>
+<P>As you can see, <CODE>deskjet.ppd</CODE> and <CODE>laserjet.ppd</CODE>
+ are the PPD files for the HP DeskJet and HP LaserJet drivers included
+ with CUPS. You'll find a complete list of PPD files and the printers
+ they will work with in<A HREF="#PRINTER_DRIVERS"> Appendix C, &quot;Printer
+ Drivers&quot;</A>.</P>
+<P>For a dot matrix printer connected to the serial port this would
+ might look like:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p DotMatrix -E -v serial:/dev/ttyS0?baud=9600+size=8+parity=none+flow=soft deskjet.ppd ENTER</B>
+</PRE>
+</UL>
+<P>Here you specify the serial port (e.g. S0,S1, d0, d1), baud rate
+ (e.g. 9600, 19200, 38400, 115200, etc.), number of bits, parity, and
+ flow control. If you do not need flow control, delete the &quot;+flow=soft&quot;
+ portion.</P>
+<H3><A NAME="ADD_WEB">Adding Your First Printer from the Web</A></H3>
+<P>The CUPS web server provides a user-friendly &quot;wizard&quot; interface for
+ adding your printers. Rather than figuring out which device URI and PPD
+ file to use, you can instead click on the appropriate listings and fill
+ in some simple information. Enter the following URL in your web browser
+ to begin:</P>
+<UL>
+<PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE>
+</UL>
+<P>Click on the<VAR> Add Printer</VAR> button to add a printer.</P>
+<H2><A NAME="4_3">Managing Printers from the Command-Line</A></H2>
+<P>The <CODE>lpadmin</CODE> command enables you to perform most printer
+ administration tasks from the command-line. You'll find <CODE>lpadmin</CODE>
+ in the<VAR> /usr/sbin</VAR> directory.</P>
+<H3><A NAME="4_3_1">Adding and Modifying Printers</A></H3>
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> option
+ to add or modify a printer:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> <I>options</I> ENTER</B>
+</PRE>
+</UL>
+<P>The<I> options</I> arguments can be any of the following:</P>
+<UL>
+<DL>
+<DT>-c<I> class</I></DT>
+<DD>Adds the named printer to printer class<VAR> class</VAR>. If the
+ class does not exist then it is created.</DD>
+<DT>-i<I> interface</I></DT>
+<DD>Copies the named<VAR> interface</VAR> script to the printer.
+ Interface scripts are used by System V printer drivers. Since all
+ filtering is disabled when using an interface script, scripts generally
+ should not be used unless there is no other driver for a printer.</DD>
+<DT>-m<I> model</I></DT>
+<DD>Specifies a standard printer driver which is usually a PPD file. A
+ list of all available models can be displayed using the <CODE>lpinfo</CODE>
+ command with the <CODE>-m</CODE> option. A list of printer drivers
+ included with CUPS can be found in<A HREF="#PRINTER_DRIVERS"> Appendix
+ C, &quot;Printer Drivers&quot;</A>.</DD>
+<DT>-r<I> class</I></DT>
+<DD>Removes the named printer from printer class<VAR> class</VAR>. If
+ the resulting class becomes empty then it is removed.</DD>
+<DT>-v<I> device-uri</I></DT>
+<DD>Sets the device for communicating with the printer. If a job is
+ currently printing on the named printer then the job will be restarted
+ and sent to the new device.</DD>
+<DT>-D<I> info</I></DT>
+<DD>Provides a textual description of the printer, e.g. &quot;John's Personal
+ Printer&quot;.</DD>
+<DT>-E</DT>
+<DD>Enables the printer and accepts job. This option is equivalent to
+ running the <CODE>enable(1)</CODE> and <CODE>accept(8)</CODE> commands
+ on the printer.</DD>
+<DT>-L<I> location</I></DT>
+<DD>Provides a textual location for the printer, e.g. &quot;Computer Lab 5&quot;.</DD>
+<DT>-P<I> ppd-file</I></DT>
+<DD>Specifies a local PPD file for the printer driver.</DD>
+</DL>
+</UL>
+<H3><A NAME="4_3_2">Deleting Printers</A></H3>
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-x</CODE> option
+ to delete a printer:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -x <I>printer</I> ENTER</B>
+</PRE>
+</UL>
+<H3><A NAME="4_3_3">Setting the Default Printer</A></H3>
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-d</CODE> option
+ to set a default printer:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -d <I>printer</I> ENTER</B>
+</PRE>
+</UL>
+<P>The default printer can be overridden by the user using the <CODE>
+lpoptions(1)</CODE> command.</P>
+<H3><A NAME="4_3_4">Starting and Stopping Printers</A></H3>
+<P>The <CODE>enable</CODE> and <CODE>disable</CODE> commands start and
+ stop printer queues, respectively:</P>
+<UL>
+<PRE>
+<B>/usr/bin/enable <I>printer</I> ENTER</B>
+<B>/usr/bin/disable <I>printer</I> ENTER</B>
+</PRE>
+</UL>
+<P>Printers that are disabled may still accept jobs for printing, but
+ won't actually print any files until they are restarted. This is useful
+ if the printer malfunctions and you need time to correct the problem.
+ Any queued jobs are printed after the printer is enabled (started).</P>
+<H3><A NAME="4_3_5">Accepting and Rejecting Print Jobs</A></H3>
+<P>The <CODE>accept</CODE> and <CODE>reject</CODE> commands accept and
+ reject print jobs for the named printer, respectively:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/accept <I>printer</I> ENTER</B>
+<B>/usr/sbin/reject <I>printer</I> ENTER</B>
+</PRE>
+</UL>
+<P>As noted above, a printer can be stopped but accepting new print
+ jobs. A printer can also be rejecting new print jobs while it finishes
+ those that have been queued. This is useful for when you must perform
+ maintenance on the printer and will not have it available to users for
+ a long period of time.</P>
+<H3><A NAME="4_3_6">Setting Quotas on a Printer</A></H3>
+<P>CUPS supports page and size-based quotas for each printer. The quotas
+ are tracked individually for each user, but a single set of limits
+ applies to all users for a partiuclar printer. For example, you can
+ limit every user to 5 pages per day on an expensive printer, but you
+ cannot limit every user except Johnny.</P>
+<P>The<I> job-k-limit</I>,<I> job-page-limit</I>, and<I> job-quota-peiod</I>
+ options determine whether and how quotas are enforced for a printer.
+ The<I> job-quota-period</I> option determines the time interval for
+ quota tracking. The interval is expressed in seconds, so a day is
+ 86,400, a week is 604,800 and a month is 2,592,000 seconds. The<I>
+ job-k-limit</I> option specifies the job size limit in killobytes. The<I>
+ job-page-limit</I> option specifies the number of pages limit.</P>
+<P>For quotas to be enforced, the period and at least one of the limits
+ must be set to a non-zero value. The following options will enable
+ quotas:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -o job-quota-period=604800 -o job-k-limit=1024 <I>ENTER</I></B>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -o job-quota-period=604800 -o job-page-limit=100 <I>ENTER</I></B>
+</PRE>
+</UL>
+<P>Or, you can combine all three options on the same line.</P>
+<H3><A NAME="4_3_7">Restricting User Access to a Printer</A></H3>
+<P>The <CODE>-u</CODE> option of the <CODE>lpadmin</CODE> command
+ controls which users can print to a printer. The default configuration
+ allows all users to print to a printer:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u allow:all <I>ENTER</I></B>
+</PRE>
+</UL>
+<P>CUPS supports allow and deny lists so that you can specify a list of
+ users who are allowed to print or not allowed to print. Along with your
+ list of users, you can specify whether they are allowed or not allowed
+ to use the printer:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u allow:peter,paul,mary <I>ENTER</I></B>
+</PRE>
+</UL>
+<P>This command allows peter, paul, and mary to print to the named
+ printer, but all other users cannot print. The command:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u deny:peter,paul,mary <I>ENTER</I></B>
+</PRE>
+</UL>
+<P>has the opposite effect. All users except peter, paul, and mary will
+ be able to print to the named printer.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B>NOTE:</B>
+<P>The<I> allow</I> and<I> deny</I> options are not cummulative. That
+ is, you must provide the complete list of users to allow or deny each
+ time.</P>
+<P>Also, CUPS only maintains one list of users - the list can allow or
+ deny users from printing. If you specify an allow list and then specify
+ a deny list, the deny list will replace the allow list - only one list
+ is active at any time.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H2><A NAME="4_4">Managing Printers from the Web</A></H2>
+<P>The Web interface is located at:</P>
+<UL>
+<PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE>
+</UL>
+<P>From there you can perform all printer management tasks with a few
+ simple mouse clicks.</P>
+<H1 ALIGN="RIGHT"><A NAME="PRINTER_CLASSES">4 - Printer Classes</A></H1>
+<P>This chapter describes what printer classes are and how to manage
+ them.</P>
+<H2><A NAME="5_1">The Basics</A></H2>
+<P>CUPS provides collections of printers called<I> printer classes</I>.
+ Jobs sent to a class are forwarded to the first available printer in
+ the class. Classes can themselves be members of other classes, so it is
+ possible for you to define very large, distributed printer classes for
+ high-availability printing.</P>
+<P>CUPS also supports<I> implicit classes</I>. Implicit classes work
+ just like printer classes, but they are created automatically based
+ upon the available printers and classes on the network. This allows you
+ to setup multiple print servers with identical printer configurations
+ and have the client machines send their print jobs to the first
+ available server. If one or more servers go down, the jobs are
+ automatically redirected to the servers that are running, providing
+ fail-safe printing.</P>
+<H2><A NAME="5_2">Managing Printer Classes from the Command-Line</A></H2>
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> and <CODE>
+-c</CODE> options to add a printer to a class:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -c <I>class</I> ENTER</B>
+</PRE>
+</UL>
+<P>The<I> class</I> is created automatically if it doesn't exist. To
+ remove a printer from a class use the <CODE>-r</CODE> option:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -r <I>class</I> ENTER</B>
+</PRE>
+</UL>
+<P>To remove the entire class just use the <CODE>-x</CODE> option:</P>
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -x <I>class</I> ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="5_3">Managing Printer Classes from the Web Interface</A></H2>
+<P>The Web interface is located at:</P>
+<UL>
+<PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE>
+</UL>
+<P>The<VAR> Add Class</VAR> and<VAR> Modify Class</VAR> interfaces
+ provide a list of available printers; click on the printers of interest
+ to add them to the class.</P>
+<H2><A NAME="5_4">Implicit Classes</A></H2>
+<P>A noted earlier, implicit classes are created automatically from the
+ available network printers and classes. To disable this functionality,
+ set the<A HREF="#ImplicitClasses"> <CODE>ImplicitClasses</CODE></A>
+ directive to <CODE>Off</CODE> in the <CODE>cupsd.conf</CODE> file. You
+ will find more information on doing this in<A HREF="#PRINTING_MANAGEMENT">
+ Chapter 6, &quot;Printing System Management&quot;</A>.</P>
+<H1 ALIGN="RIGHT"><A NAME="CLIENT_SETUP">5 - Client Setup</A></H1>
+<P>This chapter discusses several ways to configure CUPS clients for
+ printing.</P>
+<H2><A NAME="6_1">The Basics</A></H2>
+<P>A client is any machine that sends print jobs to another machine for
+ final printing. Clients can also be servers if they communicate
+ directly with any printers of their own.</P>
+<P>CUPS supports several methods of configuring client machines:</P>
+<UL>
+<LI><A HREF="#CLIENT_MANUAL">Manual configuration of print queues.</A></LI>
+<LI><A HREF="#CLIENT_SERVER">Specifying a single server for printing.</A>
+</LI>
+<LI><A HREF="#CLIENT_AUTO">Automatic configuration of print queues.</A></LI>
+<LI><A HREF="#CLIENT_POLL">Specifying multiple servers for printing.</A></LI>
+<LI><A HREF="#CLIENT_RELAY">Relaying printers to other clients.</A></LI>
+</UL>
+<H3><A NAME="CLIENT_MANUAL">Manual Configuration of Print Queues</A></H3>
+<P>The most tedious method of configuring client machines is to
+ configure each remote queue by hand using the <CODE>lpadmin</CODE>
+ command:</P>
+<UL>
+<PRE>
+<B>lpadmin -p <I>printer</I> -E -v ipp://<I>server</I>/printers/<I>printer</I> ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>printer</CODE> name is the name of the printer on the
+ server machine. The <CODE>server</CODE> name is the hostname or IP
+ address of the server machine. Repeat the <CODE>lpadmin</CODE> command
+ for each remote printer you wish to use.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Manual configuration of print queues is not recommended for large
+ numbers of client machines because of the administration nightmare it
+ creates. For busy networks, consider subnetting groups of clients and
+ polling and relaying printer information instead.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="CLIENT_SERVER">Specifying a Single Server for Printing</A></H3>
+<P>CUPS can be configured to run without a local spooler and send all
+ jobs to a single server. However, if that server goes down then all
+ printing will be disabled. Use this configuration only as absolutely
+ needed.</P>
+<P>The default server is normally &quot;localhost&quot;. To override the default
+ server create a file named<VAR> /etc/cups/client.conf</VAR> and add a
+ line reading:</P>
+<UL>
+<PRE>
+ServerName <I>server</I>
+</PRE>
+</UL>
+<P>to the file. The<VAR> server</VAR> name can be the hostname or IP
+ address of the default server.</P>
+<P>The default server can also be customized on a per-user basis. To set
+ a user-specific server create a file named<VAR> ~/.cupsrc</VAR> and add
+ a line reading:</P>
+<UL>
+<PRE>
+ServerName <I>server</I>
+</PRE>
+</UL>
+<P>to the file. The<VAR> server</VAR> name can be the hostname or IP
+ address of the default server.</P>
+<H3><A NAME="CLIENT_AUTO">Automatic Configuration of Print Queues</A></H3>
+<P>CUPS supports automatic client configuration of printers on the same
+ subnet. To configure printers on the same subnet,<I> do nothing</I>.
+ Each client should see the available printers within 30 seconds
+ automatically. The printer and class lists are updated automatically as
+ printers and servers are added or removed.</P>
+<P>If you want to see printers on other subnets as well, use the<A HREF="#BrowsePoll">
+ <CODE>BrowsePoll</CODE></A> directive as described next.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>The<A HREF="#BrowseAddress"> <CODE>BrowseAddress</CODE></A> directive
+ enables broadcast traffic from your server. The default configuration
+ braodcasts printer information every 30 seconds. Although this printer
+ information does not use much bandwidth, typically about 80 bytes per
+ printer, it can add up with large numbers of servers and printers.</P>
+<P>Use the<A HREF="#BrowseInterval"> <CODE>BrowseInterval</CODE></A> and<A
+HREF="#BrowseTimeout"> <CODE>BrowseTimeout</CODE></A> directives to tune
+ the amount of data that is added to your network load. In addition,
+ subnets can be used to minimize the amount of traffic that is carried
+ by the &quot;backbone&quot; of your large network.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="CLIENT_POLL">Specifying Multiple Servers for Printing</A></H3>
+<P>If you have CUPS servers on different subnets, then you should
+ configure CUPS to poll those servers. Polling provides the benefits of
+ automatic configuration without significant configuration on the
+ clients, and multiple clients on the same subnet can share the same
+ configuration information.</P>
+<P>Polling is enabled by specifying one or more<A HREF="#BrowsePoll"> <CODE>
+BrowsePoll</CODE></A> directives in the<VAR> /etc/cups/cupsd.conf</VAR>
+ file. For information on making these changes, see<A HREF="#PRINTING_MANAGEMENT">
+ Chapter 6, &quot;Printing System Management&quot;</A>.</P>
+<P>Multiple<A HREF="#BrowsePoll"> <CODE>BrowsePoll</CODE></A> lines can
+ be used to poll multiple CUPS servers. To limit the amount of polling
+ you do from client machines, you can have only one of the clients do
+ the polling and relay that information to the others on the same subnet
+ (described next).</P>
+<H3><A NAME="CLIENT_RELAY">Relaying Printers to Other Clients</A></H3>
+<P>When you have clients and servers spread across multiple subnets, the
+ polling method is inefficient. CUPS provides a<A HREF="#BrowseRelay"> <CODE>
+BrowseRelay</CODE></A> directive that enables a single client to relay
+ (broadcast) the polled printer information to the local subnet.</P>
+<P>For example, Server A and Server B are on subnet 1 and subnet 2,
+ while the clients are on subnet 3. To provide printers to all of the
+ clients in subnet 3, client C will be configured with the following
+ directives in<VAR> /etc/cups/cupsd.conf</VAR>:</P>
+<UL>
+<PRE>
+# Poll the two servers
+<B>
+BrowsePoll ServerA ENTER
+BrowsePoll ServerB ENTER
+</B>
+
+# Relay the printers to the local subnet
+<B>
+BrowseRelay 127.0.0.1 192.168.3.255 ENTER
+</B></PRE>
+</UL>
+<P>The<A HREF="#BrowseRelay"> <CODE>BrowseRelay</CODE></A> line
+ specifies a source address and mask. Any browse packets coming from a
+ matching address wil be sent to the given broadcast address. In this
+ case, we want the packets from the local machine (127.0.0.1) relayed to
+ the other clients.</P>
+<P>As printers are found using polling, they are relayed from client C
+ to the rest of the clients through a broadcast on subnet 3. The rest of
+ the clients can use the standard<VAR> cupsd.conf</VAR> configuration.</P>
+<P>The<A HREF="#BrowseRelay"> <CODE>BrowseRelay</CODE></A> directive can
+ also be used to relay browsing packets from one network interface to
+ another. For example, if client C in the previous example had network
+ interfaces attaches to both subnet 1 and subnet 2, it could use the<A HREF="#BrowseRelay">
+ <CODE>BrowseRelay</CODE></A> directive exclusively:</P>
+<UL>
+<PRE>
+# Relay the printers from subnet 1 and 2 to subnet 3
+<B>
+BrowseRelay 192.168.1 192.168.3.255 ENTER
+BrowseRelay 192.168.2 192.168.3.255 ENTER
+</B></PRE>
+</UL>
+<H2><A NAME="6_2">Load Balancing and Failsafe Operation</A></H2>
+<P>When using server polling or broadcasting, CUPS clients can
+ automatically merge identical printers on multiple servers into a
+ single<I> implicit class</I> queue. Clients assume that printers with
+ the same name on multiple servers are in fact the same printer or type
+ of printer being served by multiple machines.</P>
+<P>If you have two printers, LaserJet@ServerA and LaserJet@ServerB, a
+ third implicit class called<I> LaserJet</I> will be created
+ automatically on the client that refers to both printers. If the client
+ also has a local printer with the name LaserJet then an implicit class
+ named<I> AnyLaserJet</I> will be created instead.</P>
+<P>The client will alternate between servers and automatically stop
+ sending jobs to a server if it goes down, providing a load-balancing
+ effect and fail-safe operation with automatic switchover.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Note that implicit classes (<A HREF="#ImplicitClasses"><CODE>
+ImplicitClasses</CODE></A>) are enabled by default.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H1 ALIGN="RIGHT"><A NAME="PRINTING_MANAGEMENT">6 - Printing System
+ Management</A></H1>
+<P>This chapter shows how you can configure the CUPS server.</P>
+<H2><A NAME="7_1">The Basics</A></H2>
+<P>Several text files are used to configure CUPS. All of the server
+ configuration files are located in the<VAR> /etc/cups</VAR> directory:</P>
+<UL>
+<DL>
+<!-- NEED 1in -->
+
+<DT>classes.conf</DT>
+<DD>This file contains information on each printer class. Normally you
+ manipulate this file using the <CODE>lpadmin</CODE> command or the Web
+ interface.
+<BR>&nbsp;
+<!-- NEED 1in -->
+</DD>
+<DT>client.conf</DT>
+<DD>This file provides the default server name for client machines. See<A
+HREF="#CLIENT_SETUP"> Chapter 5, &quot;Client Setup&quot;</A> for more
+ information.
+<BR>&nbsp;
+<!-- NEED 1in -->
+</DD>
+<DT>cupsd.conf</DT>
+<DD>This file controls how the CUPS server (<VAR>/usr/sbin/cupsd</VAR>)
+ operates and is normally edited by hand.
+<BR>&nbsp;
+<!-- NEED 1in -->
+</DD>
+<DT>mime.convs</DT>
+<DD>This file contains a list of standard file conversion filters and
+ their costs. You normally do not edit this file.
+<BR>&nbsp;
+<!-- NEED 1in -->
+</DD>
+<DT>mime.types</DT>
+<DD>This file contains a list of standard file formats and how to
+ recognize them. You normally do not edit this file.
+<BR>&nbsp;
+<!-- NEED 1in -->
+</DD>
+<DT>printers.conf</DT>
+<DD>This file contains information on each printer. Normally you
+ manipulate this file using the <CODE>lpadmin</CODE> command or the Web
+ Interface.
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H2><A NAME="RESTARTING">Restarting the CUPS Server</A></H2>
+<P>Once you have made a change to a configuration file you need to
+ restart the CUPS server by sending it a <CODE>HUP</CODE> signal or
+ using the supplied initialization script. The CUPS distributions
+ install the script in the<VAR> init.d</VAR> directory with the name<VAR>
+ cups</VAR>. The location varies based upon the operating system:</P>
+<UL>
+<PRE>
+<B>/etc/software/init.d/cups restart ENTER</B>
+<B>/etc/rc.d/init.d/cups restart ENTER</B>
+<B>/etc/init.d/cups restart ENTER</B>
+<B>/sbin/init.d/cups restart ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="7_3">Changing the Server Configuration</A></H2>
+<P>The<VAR> /etc/cups/cupsd.conf</VAR> file contains configuration<I>
+ directives</I> that control how the server functions. Each directive is
+ listed on a line by itself followed by its value. Comments are
+ introduced using the number sign (&quot;#&quot;) character at the beginning of a
+ line. Since the server configuration file consists of plain text, you
+ can use your favorite text editor to make changes to it.
+<!-- NEED 4in -->
+</P>
+<H2><A NAME="7_4">Server Directives</A></H2>
+<P>The<VAR> cupsd.conf</VAR> file contains many directives that
+ determine how the server operates:</P>
+<UL>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0">
+<TR><TD VALIGN="TOP">
+<LI><A HREF="#AccessLog"><CODE>AccessLog</CODE></A></LI>
+<LI><A HREF="#Allow"><CODE>Allow</CODE></A></LI>
+<LI><A HREF="#AuthClass"><CODE>AuthClass</CODE></A></LI>
+<LI><A HREF="#AuthGroupName"><CODE>AuthGroupName</CODE></A></LI>
+<LI><A HREF="#AuthType"><CODE>AuthType</CODE></A></LI>
+<LI><A HREF="#AutoPurgeJobs"><CODE>AutoPurgeJobs</CODE></A></LI>
+<LI><A HREF="#BrowseAddress"><CODE>BrowseAddress</CODE></A></LI>
+<LI><A HREF="#BrowseAllow"><CODE>BrowseAllow</CODE></A></LI>
+<LI><A HREF="#BrowseDeny"><CODE>BrowseDeny</CODE></A></LI>
+<LI><A HREF="#BrowseInterval"><CODE>BrowseInterval</CODE></A></LI>
+<LI><A HREF="#BrowseOrder"><CODE>BrowseOrder</CODE></A></LI>
+<LI><A HREF="#BrowsePoll"><CODE>BrowsePoll</CODE></A></LI>
+<LI><A HREF="#BrowsePort"><CODE>BrowsePort</CODE></A></LI>
+<LI><A HREF="#BrowseProtocols"><CODE>BrowseProtocols</CODE></A></LI>
+<LI><A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A></LI>
+<LI><A HREF="#BrowseShortNames"><CODE>BrowseShortNames</CODE></A></LI>
+<LI><A HREF="#BrowseTimeout"><CODE>BrowseTimeout</CODE></A></LI>
+<LI><A HREF="#Browsing"><CODE>Browsing</CODE></A></LI>
+<LI><A HREF="#Classification"><CODE>Classification</CODE></A></LI>
+<LI><A HREF="#ClassifyOverride"><CODE>ClassifyOverride</CODE></A></LI>
+<LI><A HREF="#ConfigFilePerm"><CODE>ConfigFilePerm</CODE></A></LI>
+<LI><A HREF="#DataDir"><CODE>DataDir</CODE></A></LI>
+<LI><A HREF="#DefaultCharset"><CODE>DefaultCharset</CODE></A></LI>
+<LI><A HREF="#DefaultLanguage"><CODE>DefaultLanguage</CODE></A></LI>
+<LI><A HREF="#Deny"><CODE>Deny</CODE></A></LI>
+<LI><A HREF="#DocumentRoot"><CODE>DocumentRoot</CODE></A></LI>
+<LI><A HREF="#Encryption"><CODE>Encryption</CODE></A></LI>
+</TD><TD VALIGN="TOP"> &nbsp;&nbsp;&nbsp;</TD><TD VALIGN="TOP">
+<LI><A HREF="#ErrorLog"><CODE>ErrorLog</CODE></A></LI>
+<LI><A HREF="#FilterLimit"><CODE>FilterLimit</CODE></A></LI>
+<LI><A HREF="#FilterNice"><CODE>FilterNice</CODE></A></LI>
+<LI><A HREF="#FontPath"><CODE>FontPath</CODE></A></LI>
+<LI><A HREF="#Group"><CODE>Group</CODE></A></LI>
+<LI><A HREF="#HideImplicitMembers"><CODE>HideImplicitMembers</CODE></A></LI>
+<LI><A HREF="#HostNameLookups"><CODE>HostNameLookups</CODE></A></LI>
+<LI><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A></LI>
+<LI><A HREF="#ImplicitAnyClasses"><CODE>ImplicitAnyClasses</CODE></A></LI>
+<LI><A HREF="#Include"><CODE>Include</CODE></A></LI>
+<LI><A HREF="#KeepAliveTimeout"><CODE>KeepAliveTimeout</CODE></A></LI>
+<LI><A HREF="#KeepAlive"><CODE>KeepAlive</CODE></A></LI>
+<LI><A HREF="#Limit"><CODE>Limit</CODE></A></LI>
+<LI><A HREF="#LimitExcept"><CODE>LimitExcept</CODE></A></LI>
+<LI><A HREF="#LimitRequestBody"><CODE>LimitRequestBody</CODE></A></LI>
+<LI><A HREF="#Listen"><CODE>Listen</CODE></A></LI>
+<LI><A HREF="#Location"><CODE>Location</CODE></A></LI>
+<LI><A HREF="#LogFilePerm"><CODE>LogFilePerm</CODE></A></LI>
+<LI><A HREF="#LogLevel"><CODE>LogLevel</CODE></A></LI>
+<LI><A HREF="#MaxClients"><CODE>MaxClients</CODE></A></LI>
+<LI><A HREF="#MaxCopies"><CODE>MaxCopies</CODE></A></LI>
+<LI><A HREF="#MaxJobs"><CODE>MaxJobs</CODE></A></LI>
+<LI><A HREF="#MaxJobsPerPrinter"><CODE>MaxJobsPerPrinter</CODE></A></LI>
+<LI><A HREF="#MaxJobsPerUser"><CODE>MaxJobsPerUser</CODE></A></LI>
+<LI><A HREF="#MaxLogSize"><CODE>MaxLogSize</CODE></A></LI>
+<LI><A HREF="#MaxRequestSize"><CODE>MaxRequestSize</CODE></A></LI>
+<LI><A HREF="#Order"><CODE>Order</CODE></A></LI>
+<LI><A HREF="#PageLog"><CODE>PageLog</CODE></A></LI>
+</TD><TD VALIGN="TOP"> &nbsp;&nbsp;&nbsp;</TD><TD VALIGN="TOP">
+<LI><A HREF="#Port"><CODE>Port</CODE></A></LI>
+<LI><A HREF="#PreserveJobFiles"><CODE>PreserveJobFiles</CODE></A></LI>
+<LI><A HREF="#PreserveJobHistory"><CODE>PreserveJobHistory</CODE></A></LI>
+<LI><A HREF="#Printcap"><CODE>Printcap</CODE></A></LI>
+<LI><A HREF="#PrintcapFormat"><CODE>PrintcapFormat</CODE></A></LI>
+<LI><A HREF="#PrintcapGUI"><CODE>PrintcapGUI</CODE></A></LI>
+<LI><A HREF="#RemoteRoot"><CODE>RemoteRoot</CODE></A></LI>
+<LI><A HREF="#RequestRoot"><CODE>RequestRoot</CODE></A></LI>
+<LI><A HREF="#Require"><CODE>Require</CODE></A></LI>
+<LI><A HREF="#RIPCache"><CODE>RIPCache</CODE></A></LI>
+<LI><A HREF="#RootCertDuration"><CODE>RootCertDuration</CODE></A></LI>
+<LI><A HREF="#RunAsUser"><CODE>RunAsUser</CODE></A></LI>
+<LI><A HREF="#Satisfy"><CODE>Satisfy</CODE></A></LI>
+<LI><A HREF="#ServerAdmin"><CODE>ServerAdmin</CODE></A></LI>
+<LI><A HREF="#ServerBin"><CODE>ServerBin</CODE></A></LI>
+<LI><A HREF="#ServerCertificate"><CODE>ServerCertificate</CODE></A></LI>
+<LI><A HREF="#ServerKey"><CODE>ServerKey</CODE></A></LI>
+<LI><A HREF="#ServerName"><CODE>ServerName</CODE></A></LI>
+<LI><A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A></LI>
+<LI><A HREF="#SSLListen"><CODE>SSLListen</CODE></A></LI>
+<LI><A HREF="#SSLPort"><CODE>SSLPort</CODE></A></LI>
+<LI><A HREF="#SystemGroup"><CODE>SystemGroup</CODE></A></LI>
+<LI><A HREF="#TempDir"><CODE>TempDir</CODE></A></LI>
+<LI><A HREF="#Timeout"><CODE>Timeout</CODE></A></LI>
+<LI><A HREF="#User"><CODE>User</CODE></A></LI>
+</TD></TR>
+</TABLE>
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="AccessLog">AccessLog</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+AccessLog /var/log/cups/access_log
+AccessLog /var/log/cups/access_log-%s
+AccessLog syslog
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>AccessLog</CODE> directive sets the name of the access log
+ file. If the filename is not absolute then it is assumed to be relative
+ to the<A HREF="#ServerRoot"> <CODE>ServerRoot</CODE></A> directory. The
+ access log file is stored in &quot;common log format&quot; and can be used by any
+ web access reporting tool to generate a report on CUPS server activity.</P>
+<P>The server name can be included in the filename by using <CODE>%s</CODE>
+ in the name.</P>
+<P>The special name &quot;syslog&quot; can be used to send the access information
+ to the system log instead of a plain file.</P>
+<P>The default access log file is<VAR> /var/log/cups/access_log</VAR>.
+<!-- NEED 6in -->
+</P>
+<H3><A NAME="Allow">Allow</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Allow from All
+Allow from None
+Allow from *.domain.com
+Allow from .domain.com
+Allow from host.domain.com
+Allow from nnn.*
+Allow from nnn.nnn.*
+Allow from nnn.nnn.nnn.*
+Allow from nnn.nnn.nnn.nnn
+Allow from nnn.nnn.nnn.nnn/mm
+Allow from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+Allow from @LOCAL
+Allow from @IF(name)
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Allow</CODE> directive specifies a hostname, IP address, or
+ network that is allowed access to the server. <CODE>Allow</CODE>
+ directives are cummulative, so multiple <CODE>Allow</CODE> directives
+ can be used to allow access for multiple hosts or networks. The <CODE>
+/mm</CODE> notation specifies a CIDR netmask:
+<CENTER>
+<TABLE BORDER="1">
+<TR><TH WIDTH="10%">mm</TH><TH WIDTH="20%">netmask</TH><TH WIDTH="10%">
+mm</TH><TH WIDTH="20%">netmask</TH></TR>
+<TR><TD ALIGN="CENTER">0</TD><TD ALIGN="CENTER">0.0.0.0</TD><TD ALIGN="CENTER">
+8</TD><TD ALIGN="CENTER">255.0.0.0</TD></TR>
+<TR><TD ALIGN="CENTER">1</TD><TD ALIGN="CENTER">128.0.0.0</TD><TD ALIGN="CENTER">
+16</TD><TD ALIGN="CENTER">255.255.0.0</TD></TR>
+<TR><TD ALIGN="CENTER">2</TD><TD ALIGN="CENTER">192.0.0.0</TD><TD ALIGN="CENTER">
+24</TD><TD ALIGN="CENTER">255.255.255.0</TD></TR>
+<TR><TD ALIGN="CENTER">...</TD><TD ALIGN="CENTER">...</TD><TD ALIGN="CENTER">
+32</TD><TD ALIGN="CENTER">255.255.255.255</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<P>The <CODE>@LOCAL</CODE> name will allow access from all local network
+ interfaces, but not remote point-to-point interfaces. The <CODE>
+@IF(name)</CODE> name will allow access from the named interface.</P>
+<P>The <CODE>Allow</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="AuthClass">AuthClass</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+AuthClass Anonymous
+AuthClass User
+AuthClass System
+AuthClass Group
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>AuthClass</CODE> directive defines what level of
+ authentication is required:</P>
+<UL>
+<LI><CODE>Anonymous</CODE> - No authentication should be performed
+ (default.)</LI>
+<LI><CODE>User</CODE> - A valid username and password is required.</LI>
+<LI><CODE>System</CODE> - A valid username and password is required, and
+ the username must belong to the &quot;sys&quot; group; this can be changed using
+ the<A HREF="#SystemGroup"> <CODE>SystemGroup</CODE></A> directive.</LI>
+<LI><CODE>Group</CODE> - A valid username and password is required, and
+ the username must belong to the group named by the <CODE>AuthGroupName</CODE>
+ directive.</LI>
+</UL>
+<P>The <CODE>AuthClass</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="AuthGroupName">AuthGroupName</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+AuthGroupName mygroup
+AuthGroupName lp
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>AuthGroupName</CODE> directive sets the group to use for <CODE>
+Group</CODE> authentication.</P>
+<P>The <CODE>AuthGroupName</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="AuthType">AuthType</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+AuthType None
+AuthType Basic
+AuthType Digest
+AuthType BasicDigest
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>AuthType</CODE> directive defines the type of
+ authentication to perform:</P>
+<UL>
+<LI><CODE>None</CODE> - No authentication should be performed (default.)</LI>
+<LI><CODE>Basic</CODE> - Basic authentication should be performed using
+ the UNIX password and group files.</LI>
+<LI><CODE>Digest</CODE> - Digest authentication should be performed
+ using the<VAR> /etc/cups/passwd.md5</VAR> file.</LI>
+<LI><CODE>BasicDigest</CODE> - Basic authentication should be performed
+ using the<VAR> /etc/cups/passwd.md5</VAR> file.</LI>
+</UL>
+<P>When using <CODE>Basic</CODE>, <CODE>Digest</CODE>, or <CODE>
+BasicDigest</CODE> authentication, clients connecting through the <CODE>
+localhost</CODE> interface can also authenticate using<A HREF="#CERTIFICATES">
+ certificates</A>.</P>
+<P>The <CODE>AuthType</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="AutoPurgeJobs">AutoPurgeJobs</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+AutoPurgeJobs Yes
+AutoPurgeJobs No
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>AutoPurgeJobs</CODE> directive specifies whether or not to
+ purge completed jobs once they are no longer required for quotas. This
+ option has no effect if quotas are not enabled. The default setting is <CODE>
+No</CODE>.
+<!-- NEED 5in -->
+</P>
+<H3><A NAME="BrowseAddress">BrowseAddress</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseAddress 255.255.255.255:631
+BrowseAddress 192.0.2.255:631
+BrowseAddress host.domain.com:631
+BrowseAddress @LOCAL
+BrowseAddress @IF(name)
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseAddress</CODE> directive specifies an address to send
+ browsing information to. Multiple <CODE>BrowseAddress</CODE> directives
+ can be specified to send browsing information to different networks or
+ systems.</P>
+<P>The <CODE>@LOCAL</CODE> name will broadcast printer information to
+ all local interfaces. The <CODE>@IF(name)</CODE> name will broadcast to
+ the named interface.</P>
+<P>No browse addresses are set by default.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>If you are using HP-UX 10.20 and a subnet that is not 24, 16, or 8
+ bits, printer browsing (and in fact all broadcast reception) will not
+ work. This problem appears to be fixed in HP-UX 11.0.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 4in -->
+<H3><A NAME="BrowseAllow">BrowseAllow</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseAllow from all
+BrowseAllow from none
+BrowseAllow from 192.0.2
+BrowseAllow from 192.0.2.0/24
+BrowseAllow from 192.0.2.0/255.255.255.0
+BrowseAllow from *.domain.com
+BrowseAllow from @LOCAL
+BrowseAllow from @IF(name)
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseAllow</CODE> directive specifies a system or network
+ to accept browse packets from. The default is to accept browse packets
+ from all hosts.</P>
+<P>Host and domain name matching require that you enable the<A HREF="#HostNameLookups">
+ <CODE>HostNameLookups</CODE></A> directive.</P>
+<P>IP address matching supports exact matches, partial addresses that
+ match networks using netmasks of 255.0.0.0, 255.255.0.0, and
+ 255.255.255.0, or network addresses using the specified netmask or bit
+ count.</P>
+<P>The <CODE>@LOCAL</CODE> name will allow browse data from all local
+ network interfaces, but not remote point-to-point interfaces. The <CODE>
+@IF(name)</CODE> name will allow browse data from the named interface.
+<!-- NEED 4in -->
+</P>
+<H3><A NAME="BrowseDeny">BrowseDeny</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseDeny from all
+BrowseDeny from none
+BrowseDeny from 192.0.2
+BrowseDeny from 192.0.2.0/24
+BrowseDeny from 192.0.2.0/255.255.255.0
+BrowseDeny from *.domain.com
+BrowseDeny from @LOCAL
+BrowseDeny from @IF(name)
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseDeny</CODE> directive specifies a system or network
+ to reject browse packets from. The default is to deny browse packets
+ from no hosts.</P>
+<P>Host and domain name matching require that you enable the<A HREF="#HostNameLookups">
+ <CODE>HostNameLookups</CODE></A> directive.</P>
+<P>IP address matching supports exact matches, partial addresses that
+ match networks using netmasks of 255.0.0.0, 255.255.0.0, and
+ 255.255.255.0, or network addresses using the specified netmask or bit
+ count.</P>
+<P>The <CODE>@LOCAL</CODE> name will block browse data from all local
+ network interfaces, but not remote point-to-point interfaces. The <CODE>
+@IF(name)</CODE> name will block browse data from the named interface.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="BrowseOrder">BrowseOrder</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseOrder allow,deny
+BrowseOrder deny,allow
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseOrder</CODE> directive specifies the order of
+ allow/deny processing. The default order is <CODE>deny,allow</CODE>:</P>
+<UL>
+<LI><CODE>allow,deny</CODE> - Browse packets are accepted unless
+ specifically denied.</LI>
+<LI><CODE>deny,allow</CODE> - Browse packets are rejected unless
+ specifically allowed.</LI>
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseInterval">BrowseInterval</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseInterval 0
+BrowseInterval 30
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseInterval</CODE> directive specifies the maximum
+ amount of time between browsing updates. Specifying a value of 0
+ seconds disables outgoing browse updates but allows a server to receive
+ printer information from other hosts.</P>
+<P>The <CODE>BrowseInterval</CODE> value should always be less than the<A
+HREF="#BrowseTimeout"> <CODE>BrowseTimeout</CODE></A> value. Otherwise
+ printers and classes will disappear from client systems between
+ updates.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="BrowsePoll">BrowsePoll</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowsePoll 192.0.2.2:631
+BrowsePoll host.domain.com:631
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowsePoll</CODE> directive polls a server for available
+ printers once every<A HREF="#BrowseInterval"> <CODE>BrowseInterval</CODE>
+</A> seconds. Multiple <CODE>BrowsePoll</CODE> directives can be
+ specified to poll multiple servers.</P>
+<P>If <CODE>BrowseInterval</CODE> is set to 0 then the server is polled
+ once every 30 seconds.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="BrowsePort">BrowsePort</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowsePort 631
+BrowsePort 9999
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowsePort</CODE> directive specifies the UDP port number
+ used for browse packets. The default port number is 631.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>You must set the <CODE>BrowsePort</CODE> to the same value on all of
+ the systems that you want to see.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseProtocols">BrowseProtocols</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseProtocols CUPS
+BrowseProtocols SLP
+BrowseProtocols CUPS SLP
+BrowseProtocols all
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseProtocols</CODE> directive specifies the protocols to
+ use when collecting and distributing shared printers on the local
+ network. The default protocol is <CODE>CUPS</CODE>, which is a
+ broadcast-based protocol.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>When using the <CODE>SLP</CODE> protocol, you must have at least one
+ Directory Agent (DA) server on your network. Otherwise the CUPS
+ scheduler (<CODE>cupsd</CODE>) will not respond to client requests for
+ several seconds while polling the network.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 4in -->
+<H3><A NAME="BrowseRelay">BrowseRelay</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseRelay 193.0.2.1 192.0.2.255
+BrowseRelay 193.0.2.0/255.255.255.0 192.0.2.255
+BrowseRelay 193.0.2.0/24 192.0.2.255
+BrowseRelay *.domain.com 192.0.2.255
+BrowseRelay host.domain.com 192.0.2.255
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseRelay</CODE> directive specifies source and
+ destination addresses for relaying browsing information from one host
+ or network to another. Multiple <CODE>BrowseRelay</CODE> directives can
+ be specified as needed.</P>
+<P><CODE>BrowseRelay</CODE> is typically used on systems that bridge
+ multiple subnets using one or more network interfaces. It can also be
+ used to relay printer information from polled servers with the line:</P>
+<UL>
+<PRE>
+BrowseRelay 127.0.0.1 255.255.255.255
+</PRE>
+</UL>
+<P>This effectively provides access to printers on a WAN for all clients
+ on the LAN(s).
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="BrowseShortNames">BrowseShortNames</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseShortNames Yes
+BrowseShortNames No
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseShortNames</CODE> directive specifies whether or not
+ short names are used for remote printers when possible. Short names are
+ just the remote printer name, without the server (&quot;printer&quot;). If more
+ than one remote printer is detected with the same name, the printers
+ will have long names (&quot;printer@server1&quot;, &quot;printer@server2&quot;.)</P>
+<P>The default value for this option is <CODE>Yes</CODE>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="BrowseTimeout">BrowseTimeout</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+BrowseTimeout 300
+BrowseTimeout 60
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>BrowseTimeout</CODE> directive sets the timeout for printer
+ or class information that is received in browse packets. Once a printer
+ or class times out it is removed from the list of available
+ destinations.</P>
+<P>The <CODE>BrowseTimeout</CODE> value should always be greater than
+ the<A HREF="#BrowseInterval"> <CODE>BrowseInterval</CODE></A> value.
+ Otherwise printers and classes will disappear from client systems
+ between updates.
+<!-- NEED 4in -->
+</P>
+<H3><A NAME="Browsing">Browsing</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Browsing On
+Browsing Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Browsing</CODE> directive controls whether or not network
+ printer browsing is enabled. The default setting is <CODE>On</CODE>.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>If you are using HP-UX 10.20 and a subnet that is not 24, 16, or 8
+ bits, printer browsing (and in fact all broadcast reception) will not
+ work. This problem appears to be fixed in HP-UX 11.0.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="Classification">Classification</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Classification
+Classification classified
+Classification confidential
+Classification secret
+Classification topsecret
+Classification unclassified
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Classification</CODE> directive sets the classification
+ level on the server. When this option is set, at least one of the
+ banner pages is forced to the classification level, and the
+ classification is placed on each page of output. The default is no
+ classification level.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ClassifyOverride">ClassifyOverride</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ClassifyOverride Yes
+ClassifyOverride No
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ClassifyOverride</CODE> directive specifies whether users
+ can override the default classification level on the server. When the
+ server classification is set, users can change the classification using
+ the <CODE>job-sheets</CODE> option and can choose to only print one
+ security banner before or after the job. If the <CODE>job-sheets</CODE>
+ option is set to <CODE>none</CODE> then the server default
+ classification is used.</P>
+<P>The default is to not allow classification overrides.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ConfigFilePerm">ConfigFilePerm</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ConfigFilePerm 0644
+ConfigFilePerm 0600
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ConfigFilePerm</CODE> directive specifies the permissions
+ to use when writing configuration files. The default is 0600.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="DataDir">DataDir</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+DataDir /usr/share/cups
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>DataDir</CODE> directive sets the directory to use for data
+ files.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="DefaultCharset">DefaultCharset</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+DefaultCharset utf-8
+DefaultCharset iso-8859-1
+DefaultCharset windows-1251
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>DefaultCharset</CODE> directive sets the default character
+ set to use for client connections. The default character set is <CODE>
+utf-8</CODE> but is overridden by the character set for the language
+ specified by the client or the <CODE>DefaultLanguage</CODE> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="DefaultLanguage">DefaultLanguage</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+DefaultLanguage de
+DefaultLanguage en
+DefaultLanguage es
+DefaultLanguage fr
+DefaultLanguage it
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>DefaultLanguage</CODE> directive specifies the default
+ language to use for client connections. Setting the default language
+ also sets the default character set if a language localization file
+ exists for it. The default language is &quot;en&quot; for English.
+<!-- NEED 5in -->
+</P>
+<H3><A NAME="Deny">Deny</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Deny from All
+Deny from None
+Deny from *.domain.com
+Deny from .domain.com
+Deny from host.domain.com
+Deny from nnn.*
+Deny from nnn.nnn.*
+Deny from nnn.nnn.nnn.*
+Deny from nnn.nnn.nnn.nnn
+Deny from nnn.nnn.nnn.nnn/mm
+Deny from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+Deny from @LOCAL
+Deny from @IF(name)
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Deny</CODE> directive specifies a hostname, IP address, or
+ network that is allowed access to the server. <CODE>Deny</CODE>
+ directives are cummulative, so multiple <CODE>Deny</CODE> directives
+ can be used to allow access for multiple hosts or networks. The <CODE>
+/mm</CODE> notation specifies a CIDR netmask:
+<CENTER>
+<TABLE BORDER="1">
+<TR><TH WIDTH="10%">mm</TH><TH WIDTH="20%">netmask</TH><TH WIDTH="10%">
+mm</TH><TH WIDTH="20%">netmask</TH></TR>
+<TR><TD ALIGN="CENTER">0</TD><TD ALIGN="CENTER">0.0.0.0</TD><TD ALIGN="CENTER">
+8</TD><TD ALIGN="CENTER">255.0.0.0</TD></TR>
+<TR><TD ALIGN="CENTER">1</TD><TD ALIGN="CENTER">128.0.0.0</TD><TD ALIGN="CENTER">
+16</TD><TD ALIGN="CENTER">255.255.0.0</TD></TR>
+<TR><TD ALIGN="CENTER">2</TD><TD ALIGN="CENTER">192.0.0.0</TD><TD ALIGN="CENTER">
+24</TD><TD ALIGN="CENTER">255.255.255.0</TD></TR>
+<TR><TD ALIGN="CENTER">...</TD><TD ALIGN="CENTER">...</TD><TD ALIGN="CENTER">
+32</TD><TD ALIGN="CENTER">255.255.255.255</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<P>The <CODE>@LOCAL</CODE> name will deny access from all local network
+ interfaces, but not remote point-to-point interfaces. The <CODE>
+@IF(name)</CODE> name will deny access from the named interface.</P>
+<P>The <CODE>Deny</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="DocumentRoot">DocumentRoot</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+DocumentRoot /usr/share/doc/cups
+DocumentRoot /foo/bar/doc/cups
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>DocumentRoot</CODE> directive specifies the location of web
+ content for the HTTP server in CUPS. If an absolute path is not
+ specified then it is assumed to be relative to the<A HREF="#ServerRoot">
+ <CODE>ServerRoot</CODE></A> directory. The default directory is<VAR>
+ /usr/share/doc/cups</VAR>.</P>
+<P>Documents are first looked up in a sub-directory for the primary
+ language requested by the client (e.g.<VAR> /usr/share/doc/cups/fr/...</VAR>
+) and then directly under the <CODE>DocumentRoot</CODE> directory (e.g.<VAR>
+ /usr/share/doc/cups/...</VAR>), so it is possible to localize the web
+ content by providing subdirectories for each language needed.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Encryption">Encryption</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Encryption Never
+Encryption IfRequested
+Encryption Required
+Encryption Always
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Encryption</CODE> directive must appear instead a<A HREF="#Location">
+ <CODE>Location</CODE></A> section and specifies the encryption settings
+ for that location. The default setting is <CODE>IfRequested</CODE> for
+ all locations.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ErrorLog">ErrorLog</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ErrorLog /var/log/cups/error_log
+ErrorLog /var/log/cups/error_log-%s
+ErrorLog syslog
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ErrorLog</CODE> directive sets the name of the error log
+ file. If the filename is not absolute then it is assumed to be relative
+ to the<A HREF="#ServerRoot"> <CODE>ServerRoot</CODE></A> directory. The
+ default error log file is<VAR> /var/log/cups/error_log</VAR>.</P>
+<P>The server name can be included in the filename by using <CODE>%s</CODE>
+ in the name.</P>
+<P>The special name &quot;syslog&quot; can be used to send the error information
+ to the system log instead of a plain file.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="FilterLimit">FilterLimit</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+FilterLimit 0
+FilterLimit 200
+FilterLimit 1000
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>FilterLimit</CODE> directive sets the maximum cost of all
+ running job filters. It can be used to limit the number of filter
+ programs that are run on a server to minimize disk, memory, and CPU
+ resource problems. A limit of 0 disables filter limiting.</P>
+<P>An average print to a non-PostScript printer needs a filter limit of
+ about 200. A PostScript printer needs about half that (100). Setting
+ the limit below these thresholds will effectively limit the scheduler
+ to printing a single job at any time.</P>
+<P>The default limit is 0.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="FilterNice">FilterNice</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+FilterNice 0
+FilterNice 39
+FilterNice -10
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>FilterNice</CODE> directive sets the scheduling priority of
+ job filters. Values larger than 0 give filters a lower priority while
+ values smaller than 0 give filters a higher priority. The <CODE>
+FilterNice</CODE> value does not affect the priority of job backends.</P>
+<P>The default priority is 0.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="FontPath">FontPath</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+FontPath /foo/bar/fonts
+FontPath /usr/share/cups/fonts:/foo/bar/fonts
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>FontPath</CODE> directive specifies the font path to use
+ when searching for fonts. The default font path is <CODE>
+/usr/share/cups/fonts</CODE>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Group">Group</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Group sys
+Group system
+Group root
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Group</CODE> directive specifies the UNIX group that filter
+ and CGI programs run as. The default group is <CODE>sys</CODE>, <CODE>
+system</CODE>, or <CODE>root</CODE> depending on the operating system.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="HideImplicitMembers">HideImplicitMembers</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+HideImplicitMembers Yes
+HideImplicitMembers No
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>HideImplicitMembers</CODE> directive controls whether the
+ individual printers in an implicit class are shown to the user. The
+ default is <CODE>No</CODE>.</P>
+<P><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A> must be
+ enabled for this directive to have any effect.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="HostNameLookups">HostNameLookups</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+HostNameLookups On
+HostNameLookups Off
+HostNameLookups Double
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>HostNameLookups</CODE> directive controls whether or not
+ CUPS looks up the hostname for connecting clients. The <CODE>Double</CODE>
+ setting causes CUPS to verify that the hostname resolved from the
+ address matches one of the addresses returned for that hostname. <CODE>
+Double</CODE> lookups also prevent clients with unregistered addresses
+ from connecting to your server. The default is <CODE>Off</CODE> to
+ avoid the potential server performance problems with hostname lookups.
+ Set this option to <CODE>On</CODE> or <CODE>Double</CODE> only if
+ absolutely required.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ImplicitClasses">ImplicitClasses</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ImplicitClasses On
+ImplicitClasses Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ImplicitClasses</CODE> directive controls whether implicit
+ classes are created based upon the available network printers and
+ classes. The default setting is <CODE>On</CODE> but is automatically
+ turned <CODE>Off</CODE> if<A HREF="#Browsing"> <CODE>Browsing</CODE></A>
+ is turned <CODE>Off</CODE>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ImplicitAnyClasses">ImplicitAnyClasses</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ImplicitAnyClasses On
+ImplicitAnyClasses Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ImplicitAnyClasses</CODE> directive controls whether
+ implicit classes for local and remote printers are created with the
+ name <CODE>AnyPrinter</CODE>. The default setting is <CODE>Off</CODE>.</P>
+<P><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A> must be
+ enabled for this directive to have any effect.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="Include">Include</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Include filename
+Include /foo/bar/filename
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Include</CODE> directive includes the named file in the <CODE>
+cupsd.conf</CODE> file. If no leading path is provided, the file is
+ assumed to be relative to the<A HREF="#ServerRoot"> <CODE>ServerRoot</CODE>
+</A> directory.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="KeepAlive">KeepAlive</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+KeepAlive On
+KeepAlive Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>KeepAlive</CODE> directive controls whether or not to
+ support persistent HTTP connections. The default is <CODE>On</CODE>.</P>
+<P>HTTP/1.1 clients automatically support persistent connections, while
+ HTTP/1.0 clients must specifically request them using the <CODE>
+Keep-Alive</CODE> attribute in the <CODE>Connection:</CODE> field of
+ each request.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="KeepAliveTimeout">KeepAliveTimeout</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+KeepAliveTimeout 60
+KeepAliveTimeout 30
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>KeepAliveTimeout</CODE> directive controls how long a
+ persistent HTTP connection will remain open after the last request. The
+ default is 60 seconds.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Limit">Limit</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+&lt;Limit GET POST&gt;
+...
+&lt;/Limit&gt;
+
+&lt;Limit ALL&gt;
+...
+&lt;/Limit&gt;
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Limit</CODE> directive groups access control directives for
+ specific types of HTTP requests and must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> section. Access can be limited for individual
+ request types (<CODE>DELETE</CODE>, <CODE>GET</CODE>, <CODE>HEAD</CODE>
+, <CODE>OPTIONS</CODE>, <CODE>POST</CODE>, <CODE>PUT</CODE>, and <CODE>
+TRACE</CODE>) or for all request types (<CODE>ALL</CODE>). The request
+ type names are case-sensitive for compatibility with Apache.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="LimitExcept">LimitExcept</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+&lt;LimitExcept GET POST&gt;
+...
+&lt;/LimitExcept&gt;
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>LimitExcept</CODE> directive groups access control
+ directives for specific types of HTTP requests and must appear inside a<A
+HREF="#Location"> <CODE>Location</CODE></A> section. Unlike the<A HREF="#Limit">
+ <CODE>Limit</CODE></A> directive, <CODE>LimitExcept</CODE> restricts
+ access for all requests<I> except</I> those listed on the <CODE>
+LimitExcept</CODE> line.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="LimitRequestBody">LimitRequestBody</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+LimitRequestBody 10485760
+LimitRequestBody 10m
+LimitRequestBody 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>LimitRequestBody</CODE> directive controls the maximum size
+ of print files, IPP requests, and HTML form data in HTTP POST requests.
+ The default limit is 0 which disables the limit check.</P>
+<P>Also see the identical<A HREF="#MaxRequestSize"> <CODE>MaxRequestSize</CODE>
+</A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Listen">Listen</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Listen 127.0.0.1:631
+Listen 192.0.2.1:631
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Listen</CODE> directive specifies a network address and
+ port to listen for connections. Multiple <CODE>Listen</CODE> directives
+ can be provided to listen on multiple addresses.</P>
+<P>The <CODE>Listen</CODE> directive is similar to the<A HREF="#Port"> <CODE>
+Port</CODE></A> directive but allows you to restrict access to specific
+ interfaces or networks.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Location">Location</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+&lt;Location /&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /admin&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /printers&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /printers/name&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /classes&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /classes/name&gt;
+...
+&lt;/Location&gt;
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Location</CODE> directive specifies access control and
+ authentication options for the specified HTTP resource or path. The<A HREF="#Allow">
+ <CODE>Allow</CODE></A>,<A HREF="#AuthClass"> <CODE>AuthClass</CODE></A>
+,<A HREF="#AuthGroupName"> <CODE>AuthGroupName</CODE></A>,<A HREF="#AuthType">
+ <CODE>AuthType</CODE></A>,<A HREF="#Deny"> <CODE>Deny</CODE></A>,<A HREF="#Encryption">
+ <CODE>Encryption</CODE></A>,<A HREF="#Limit"> <CODE>Limit</CODE></A>,<A HREF="#LimitExcept">
+ <CODE>LimitExcept</CODE></A>,<A HREF="#Order"> <CODE>Order</CODE></A>,<A
+HREF="#Require"> <CODE>Require</CODE></A>, and<A HREF="#Satisfy"> <CODE>
+Satisfy</CODE></A> directives may all appear inside a location.
+<CENTER>
+<TABLE BORDER="1"><CAPTION>Locations on the Server.</CAPTION>
+<TR><TH>Location</TH><TH>Description</TH></TR>
+<TR><TD>/</TD><TD>The path for all get operations (get-printers,
+ get-jobs, etc.)</TD></TR>
+<TR><TD>/admin</TD><TD>The path for all administration operations
+ (add-printer, delete-printer, start-printer, etc.)</TD></TR>
+<TR><TD>/admin/conf</TD><TD>The path for access to the ESP Print Pro
+ configuration files (cupsd.conf, client.conf, etc.)</TD></TR>
+<TR><TD>/classes</TD><TD>The path for all classes</TD></TR>
+<TR><TD>/classes/name</TD><TD>The resource for class <CODE>name</CODE></TD>
+</TR>
+<TR><TD>/jobs</TD><TD>The path for all jobs (hold-job, release-job,
+ etc.)</TD></TR>
+<TR><TD>/jobs/id</TD><TD>The resource for job <CODE>id</CODE></TD></TR>
+<TR><TD>/printers</TD><TD>The path for all printers</TD></TR>
+<TR><TD>/printers/name</TD><TD>The path for printer <CODE>name</CODE></TD>
+</TR>
+<TR><TD>/printers/name.ppd</TD><TD>The PPD file path for printer <CODE>
+name</CODE></TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<P>Note that more specific resources override the less specific ones. So
+ the directives inside the <CODE>/printers/name</CODE> location will
+ override ones from <CODE>/printers</CODE>. Directives inside <CODE>
+/printers</CODE> will override ones from <CODE>/</CODE>. &nbsp; None of the
+ directives are inherited. More information can be found in section<A HREF="#PRINTING_SECURITY">
+ &quot;Printing System Security&quot;</A>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="LogFilePerm">LogFilePerm</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+LogFilePerm 0644
+LogFilePerm 0600
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>LogFilePerm</CODE> directive specifies the permissions to
+ use when writing configuration files. The default is 0644.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="LogLevel">LogLevel</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+LogLevel none
+LogLevel emerg
+LogLevel alert
+LogLevel crit
+LogLevel error
+LogLevel warn
+LogLevel notice
+LogLevel info
+LogLevel debug
+LogLevel debug2
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>LogLevel</CODE> directive specifies the level of logging
+ for the<A HREF="#ErrorLog"> <CODE>ErrorLog</CODE></A> file. The
+ following values are recognized (each level logs everything under the
+ preceding levels):</P>
+<UL>
+<LI><CODE>none</CODE> - Log nothing.</LI>
+<LI><CODE>emerg</CODE> - Log emergency conditions that prevent the
+ server from running.</LI>
+<LI><CODE>alert</CODE> - Log alerts that must be handled immediately.</LI>
+<LI><CODE>crit</CODE> - Log critical errors that don't prevent the
+ server from running.</LI>
+<LI><CODE>error</CODE> - Log general errors.</LI>
+<LI><CODE>warn</CODE> - Log errors and warnings.</LI>
+<LI><CODE>notice</CODE> - Log temporary error conditions.</LI>
+<LI><CODE>info</CODE> - Log all requests and state changes (default).</LI>
+<LI><CODE>debug</CODE> - Log basic debugging information.</LI>
+<LI><CODE>debug2</CODE> - Log all debugging information.</LI>
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxClients">MaxClients</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxClients 100
+MaxClients 1024
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxClients</CODE> directive controls the maximum number of
+ simultaneous clients that will be allowed by the server. The default is
+ 100 clients.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Since each print job requires a file descriptor for the status pipe,
+ the CUPS server internally limits the <CODE>MaxClients</CODE> value to
+ 1/3 of the available file descriptors to avoid possible problems when
+ printing large numbers of jobs.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxCopies">MaxCopies</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxCopies 100
+MaxCopies 65535
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxCopies</CODE> directive controls the maximum number of
+ copies that a user can print of a job. The default is 100 copies.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Most HP PCL laser printers internally limit the number of copies to
+ 100.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxJobs">MaxJobs</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxJobs 100
+MaxJobs 9999
+MaxJobs 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxJobs</CODE> directive controls the maximum number of
+ jobs that are kept in memory. Once the number of jobs reaches the
+ limit, the oldest completed job is automatically purged from the system
+ to make room for the new one. If all of the known jobs are still
+ pending or active then the new job will be rejected.</P>
+<P>Setting the maximum to 0 disables this functionality. The default
+ setting is 0.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="MaxJobsPerPrinter">MaxJobsPerPrinter</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxJobsPerPrinter 100
+MaxJobsPerPrinter 9999
+MaxJobsPerPrinter 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxJobsPerPrinter</CODE> directive controls the maximum
+ number of active jobs that are allowed for each printer or class. Once
+ a printer or class reaches the limit, new jobs will be rejected until
+ one of the active jobs is completed, stopped, aborted, or cancelled.</P>
+<P>Setting the maximum to 0 disables this functionality. The default
+ setting is 0.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="MaxJobsPerUser">MaxJobsPerUser</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxJobsPerUser 100
+MaxJobsPerUser 9999
+MaxJobsPerUser 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxJobsPerUser</CODE> directive controls the maximum number
+ of active jobs that are allowed for each user. Once a user reaches the
+ limit, new jobs will be rejected until one of the active jobs is
+ completed, stopped, aborted, or cancelled.</P>
+<P>Setting the maximum to 0 disables this functionality. The default
+ setting is 0.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="MaxLogSize">MaxLogSize</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxLogSize 1048576
+MaxLogSize 1m
+MaxLogSize 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxLogSize</CODE> directive controls the maximum size of
+ each log file. Once a log file reaches or exceeds the maximum size it
+ is closed and renamed to<VAR> filename.O</VAR>. This allows you to
+ rotate the logs automatically. The default size is 1048576 bytes (1MB).</P>
+<P>Setting the maximum size to 0 disables log rotation.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="MaxRequestSize">MaxRequestSize</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+MaxRequestSize 10485760
+MaxRequestSize 10m
+MaxRequestSize 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>MaxRequestSize</CODE> directive controls the maximum size
+ of print files, IPP requests, and HTML form data in HTTP POST requests.
+ The default limit is 0 which disables the limit check.</P>
+<P>Also see the identical<A HREF="#LimitRequestBody"> <CODE>
+LimitRequestBody</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Order">Order</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Order Allow,Deny
+Order Deny,Allow
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Order</CODE> directive defines the default access control.
+ The following values are supported:</P>
+<UL>
+<LI><CODE>Allow,Deny</CODE> - Allow requests from all systems<I> except</I>
+ for those listed in a <CODE>Deny</CODE> directive.</LI>
+<LI><CODE>Deny,Allow</CODE> - Allow requests only from those listed in
+ an <CODE>Allow</CODE> directive.</LI>
+</UL>
+<P>The <CODE>Order</CODE> directive must appear inside a<A HREF="#Location">
+ <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="PageLog">PageLog</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+PageLog /var/log/cups/page_log
+PageLog /var/log/cups/page_log-%s
+PageLog syslog
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>PageLog</CODE> directive sets the name of the page log
+ file. If the filename is not absolute then it is assumed to be relative
+ to the<A HREF="#ServerRoot"> <CODE>ServerRoot</CODE></A> directory. The
+ default page log file is<VAR> /var/log/cups/page_log</VAR>.</P>
+<P>The server name can be included in the filename by using <CODE>%s</CODE>
+ in the name.</P>
+<P>The special name &quot;syslog&quot; can be used to send the page information to
+ the system log instead of a plain file.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Port">Port</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Port 631
+Port 80
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Port</CODE> directive specifies a port to listen on.
+ Multiple <CODE>Port</CODE> lines can be specified to listen on multiple
+ ports. The default port is 631.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="PreserveJobHistory">PreserveJobHistory</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+PreserveJobHistory On
+PreserveJobHistory Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>PreserveJobHistory</CODE> directive controls whether the
+ history of completed, cancelled, or aborted print jobs is stored on
+ disk.</P>
+<P>A value of <CODE>On</CODE> (the default) preserves job information
+ until the administrator purges it with the <CODE>cancel</CODE> command.</P>
+<P>A value of <CODE>Off</CODE> removes the job information as soon as
+ each job is completed, cancelled, or aborted.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="PreserveJobFiles">PreserveJobFiles</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+PreserveJobFiles On
+PreserveJobFiles Off
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>PreserveJobFiles</CODE> directive controls whether the
+ document files of completed, cancelled, or aborted print jobs are
+ stored on disk.</P>
+<P>A value of <CODE>On</CODE> preserves job files until the
+ administrator purges them with the <CODE>cancel</CODE> command. Jobs
+ can be restarted (and reprinted) as desired until they are purged.</P>
+<P>A value of <CODE>Off</CODE> (the default) removes the job files as
+ soon as each job is completed, cancelled, or aborted.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Printcap">Printcap</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Printcap
+Printcap /etc/printcap
+Printcap /etc/printers.conf
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Printcap</CODE> directive controls whether or not a
+ printcap file is automatically generated and updated with a list of
+ available printers. If specified with no value, then no printcap file
+ will be generated. The default is to generate a file named<VAR>
+ /etc/printcap</VAR>.</P>
+<P>When a filename is specified (e.g.<VAR> /etc/printcap</VAR>), the
+ printcap file is written whenever a printer is added or removed. The
+ printcap file can then be used by applications that are hardcoded to
+ look at the printcap file for the available printers.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="PrintcapFormat">PrintcapFormat</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+PrintcapFormat BSD
+PrintcapFormat Solaris
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>PrintcapFormat</CODE> directive controls the output format
+ of the printcap file. The default is to generate a BSD printcap file.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="PrintcapGUI">PrintcapGUI</A></H3>
+<HR>
+<H4>Example</H4>
+<UL>
+<PRE>
+PrintcapGUI /usr/bin/glpoptions
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>PrintcapGUI</CODE> directive sets the program to use when
+ displaying an option panel from an IRIX application that uses the
+ Impressario print API. The default program is the ESP Print Pro
+ &quot;glpoptions&quot; GUI.</P>
+<P>The program must accept the <CODE>-d</CODE> option to specify a
+ printer and the <CODE>-o</CODE> option to specify one or more options.
+ After allowing the user to select/change options, the program must then
+ write the list of printing options without the <CODE>-o</CODE> to the
+ standard output.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="RemoteRoot">RemoteRoot</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+RemoteRoot remroot
+RemoteRoot root
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>RemoteRoot</CODE> directive sets the username for
+ unauthenticated root requests from remote hosts. The default username
+ is<VAR> remroot</VAR>. Setting <CODE>RemoteRoot</CODE> to<VAR> root</VAR>
+ effectively disables this security mechanism.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="RequestRoot">RequestRoot</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+RequestRoot /var/spool/cups
+RequestRoot /foo/bar/spool/cups
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>RequestRoot</CODE> directive sets the directory for
+ incoming IPP requests and HTML forms. If an absolute path is not
+ provided then it is assumed to be relative to the<A HREF="#ServerRoot">
+ <CODE>ServerRoot</CODE></A> directory. The default request directory is<VAR>
+ /var/spool/cups</VAR>.
+<!-- NEED 4in -->
+</P>
+<H3><A NAME="Require">Require</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Require group foo bar
+Require user john mary
+Require valid-user
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Require</CODE> directive specifies that authentication is
+ required for the resource. The <CODE>group</CODE> keyword specifies
+ that the authenticated user must be a member of one or more of the
+ named groups that follow.</P>
+<P>The <CODE>user</CODE> keyboard specifies that the authenticated user
+ must be one of the named users that follow.</P>
+<P>The <CODE>valid-user</CODE> keyword specifies that any authenticated
+ user may access the resource.</P>
+<P>The default is to do no authentication. This directive must appear
+ inside a<A HREF="#Location"> <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="RIPCache">RIPCache</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+RIPCache 8m
+RIPCache 1g
+RIPCache 2048k
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>RIPCache</CODE> directive sets the size of the memory cache
+ used by Raster Image Processor (&quot;RIP&quot;) filters such as <CODE>
+imagetoraster</CODE> and <CODE>pstoraster</CODE>. The size can be
+ suffixed with a &quot;k&quot; for kilobytes, &quot;m&quot; for megabytes, or &quot;g&quot; for
+ gigabytes. The default cache size is &quot;8m&quot;, or 8 megabytes.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="RootCertDuration">RootCertDuration</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+RootCertDuration 300
+RootCertDuration 0
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>RootCertDuration</CODE> directive controls the interval
+ between updates of the root authentication certificate. The default is <CODE>
+300</CODE> seconds which updates the root certificate approximately once
+ every 5 minutes. Set the interval to 0 to disable certificate updates
+ entirely.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="RunAsUser">RunAsUser</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+RunAsUser Yes
+RunAsUser No
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>RunAsUser</CODE> directive controls whether the scheduler
+ runs as the unpriviledged user account (usually <CODE>lp</CODE>). The
+ default is <CODE>No</CODE> which leaves the scheduler running as the <CODE>
+root</CODE> user.</P>
+<P><B>Note:</B> Running as a non-priviledged user may prevent LPD and
+ locally connected printers from working due to permission problems. The
+ <CODE>lpd</CODE> backend will automatically use a non-priviledged mode
+ that is not 100% compliant with RFC 1179. The <CODE>parallel</CODE>, <CODE>
+serial</CODE>, and <CODE>usb</CODE> backends will need write access to
+ the corresponding device files.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="Satisfy">Satisfy</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Satisfy all
+Satisfy any
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Satisfy</CODE> directive specifies whether all conditions
+ must be satisfied to allow access to the resource. If set to <CODE>all</CODE>
+, then all authentication and access control conditions must be satified
+ to allow access.</P>
+<P>Setting <CODE>Satisfy</CODE> to <CODE>any</CODE> allows a user to
+ gain access if the authentication or access control requirements are
+ satisfied. For example, you might require authentication for remote
+ access, but allow local access without authentication.</P>
+<P>The default is <CODE>all</CODE>. This directive must appear inside a<A
+HREF="#Location"> <CODE>Location</CODE></A> directive.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerAdmin">ServerAdmin</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerAdmin user@host
+ServerAdmin root@foo.bar.com
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerAdmin</CODE> directive identifies the email address
+ for the administrator on the system. By default the administrator email
+ address is <CODE>root@server</CODE>, where <CODE>server</CODE> is the
+ server name.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerBin">ServerBin</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerBin /usr/lib/cups
+ServerBin /foo/bar/lib/cups
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerBin</CODE> directive sets the directory for
+ server-run executables. If an absolute path is not provided then it is
+ assumed to be relative to the<A HREF="#ServerRoot"> <CODE>ServerRoot</CODE>
+</A> directory. The default executable directory is<VAR> /usr/lib/cups</VAR>
+.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerCertificate">ServerCertificate</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerCertificate /etc/cups/ssl/server.crt
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerCertificate</CODE> directive specifies the location
+ of the SSL certificate file used by the server when negotiating
+ encrypted connections. The certificate must not be encrypted (password
+ protected) since the scheduler normally runs in the background and will
+ be unable to ask for a password. The default certificate file is<VAR>
+ /etc/cups/ssl/server.crt</VAR>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerKey">ServerKey</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerKey /etc/cups/ssl/server.key
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerKey</CODE> directive specifies the location of the
+ SSL private key file used by the server when negotiating encrypted
+ connections. The default key file is<VAR> /etc/cups/ssl/server.crt</VAR>
+.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerName"></A>ServerName</H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerName foo.domain.com
+ServerName myserver.domain.com
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerName</CODE> directive specifies the hostname that is
+ reported to clients. By default the server name is the hostname.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="ServerRoot">ServerRoot</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+ServerRoot /etc/cups
+ServerRoot /foo/bar/cups
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>ServerRoot</CODE> directive specifies the absolute path to
+ the server configuration and state files. It is also used to resolve
+ relative paths in the<VAR> cupsd.conf</VAR> file. The default server
+ directory is<VAR> /etc/cups</VAR>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="SSLListen">SSLListen</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+SSLListen 127.0.0.1:443
+SSLListen 192.0.2.1:443
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>SSLListen</CODE> directive specifies a network address and
+ port to listen for secure connections. Multiple <CODE>SSLListen</CODE>
+ directives can be provided to listen on multiple addresses.</P>
+<P>The <CODE>SSLListen</CODE> directive is similar to the<A HREF="#SSLPort">
+ <CODE>SSLPort</CODE></A> directive but allows you to restrict access to
+ specific interfaces or networks.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="SSLPort">SSLPort</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+SSLPort 443
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>SSLPort</CODE> directive specifies a port to listen on for
+ secure connections. Multiple <CODE>SSLPort</CODE> lines can be
+ specified to listen on multiple ports.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="SystemGroup">SystemGroup</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+SystemGroup sys
+SystemGroup system
+SystemGroup root
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>SystemGroup</CODE> directive specifies the system
+ administration group for <CODE>System</CODE> authentication. More
+ information can be found later in this chapter in<A HREF="#PRINTING_SECURITY">
+ &quot;Printing System Security&quot;</A>.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="TempDir">TempDir</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+TempDir /var/tmp
+TempDir /foo/bar/tmp
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>TempDir</CODE> directive specifies an absolute path for the
+ directory to use for temporary files. The default directory is<VAR>
+ /var/tmp</VAR>.</P>
+<P>Temporary directories must be world-writable and should have the
+ &quot;sticky&quot; permission bit enabled so that other users cannot delete
+ filter temporary files. The following commands will create an
+ appropriate temporary directory called<VAR> /foo/bar/tmp</VAR>:</P>
+<UL>
+<PRE>
+<B>mkdir /foo/bar/tmp ENTER</B>
+<B>chmod a+rwxt /foo/bar/tmp ENTER</B>
+</PRE>
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="Timeout">Timeout</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+Timeout 300
+Timeout 90
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>Timeout</CODE> directive controls the amount of time to
+ wait before an active HTTP or IPP request times out. The default
+ timeout is 300 seconds.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="User">User</A></H3>
+<HR>
+<H4>Examples</H4>
+<UL>
+<PRE>
+User lp
+User guest
+</PRE>
+</UL>
+<H4>Description</H4>
+<P>The <CODE>User</CODE> directive specifies the UNIX user that filter
+ and CGI programs run as. The default user is <CODE>lp</CODE>.
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="PRINTING_SECURITY">Printing System Security</A></H2>
+<P>CUPS provides support for address, certificate, and password (Basic
+ and Digest) based authentication and access control. Certificate and
+ password authentication provide ways to limit access to individual
+ people or groups.</P>
+<P>Address based access control allows you to limit access to specific
+ systems, networks, or domains. While this does not provide
+ authentication, it does allow you to limit the potential users of your
+ system efficiently.</P>
+<P>CUPS maintains a list of locations that have access control and/or
+ authentication enabled. Locations are specified using the<A HREF="#Location">
+ <CODE>Location</CODE></A> directive:</P>
+<UL>
+<PRE>
+&lt;Location /resource&gt;
+<A HREF="#AuthClass">AuthClass</A> ...
+<A HREF="#AuthGroupName">AuthGroupName</A> ...
+<A HREF="#AuthType">AuthType</A> ...
+
+<A HREF="#Order">Order</A> ...
+<A HREF="#Allow">Allow</A> from ...
+<A HREF="#Deny">Deny</A> from ...
+&lt;/Location&gt;
+</PRE>
+</UL>
+<P>Locations generally follow the directory structure of the<A HREF="#DocumentRoot">
+ <CODE>DocumentRoot</CODE></A> directory, however CUPS does have several
+ virtual locations for administration, classes, jobs, and printers:
+<CENTER>
+<TABLE BORDER="1">
+<TR><TH>Location</TH><TH>Description</TH></TR>
+<TR><TD>/admin</TD><TD>The path for all administration operations.</TD></TR>
+<TR><TD>/classes</TD><TD>The path for all classes.</TD></TR>
+<TR><TD>/classes/name</TD><TD>The resource for class <CODE>name</CODE>.</TD>
+</TR>
+<TR><TD>/jobs</TD><TD>The path for all jobs.</TD></TR>
+<TR><TD>/jobs/id</TD><TD>The resource for job <CODE>id</CODE>.</TD></TR>
+<TR><TD>/printers</TD><TD>The path for all printers.</TD></TR>
+<TR><TD>/printers/name</TD><TD>The path for printer <CODE>name</CODE>.</TD>
+</TR>
+<TR><TD>/printers/name.ppd</TD><TD>The PPD file path for printer <CODE>
+name</CODE>.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="CERTIFICATES">Authentication Using Certificates</A></H3>
+<P>CUPS supports a local certificate-based authentication scheme that
+ can be used in place of <CODE>Basic</CODE> or <CODE>Digest</CODE>
+ authentication by clients connecting through the <CODE>localhost</CODE>
+ interface. Certificate authentication is not supported or allowed from
+ clients on any other interface.</P>
+<P>Certificates are 128-bit random numbers that refer to an internal
+ authentication record in the server. A client connecting via the <CODE>
+localhost</CODE> interface sends a request with an authorization header
+ of:</P>
+<UL>
+<PRE>
+Authorization: Local 0123456789ABCDEF0123456789ABCDEF
+</PRE>
+</UL>
+<P>The server then looks up the local certificate and authenticates
+ using the username associated with it.</P>
+<P>Certificates are generated by the server automatically and stored in
+ the<VAR> /etc/cups/certs</VAR> directory using the process ID of the
+ CGI program started by the server. Certificate files are only readable
+ by the<A HREF="#User"> <CODE>User</CODE></A> and<A HREF="#Group"> <CODE>
+Group</CODE></A> defined in the<VAR> cupsd.conf</VAR> file. When the CGI
+ program ends the certificate is removed and invalidated automatically.</P>
+<P>The special file<VAR> /etc/cups/certs/0</VAR> defines the<I> root
+ certificate</I> which can be used by any client running as the
+ super-user or another user that is part of the group defined by the<A HREF="#SystemGroup">
+ <CODE>SystemGroup</CODE></A> directive. The root certificate is
+ automatically regenerated every 5 minutes.</P>
+<H3><A NAME="7_5_2">Using Basic Authentication</A></H3>
+<P>Basic authentication uses UNIX users and passwords to authenticate
+ access to resources such as printers and classes, and to limit access
+ to administrative functions.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Basic authentication sends the username and password Base64 encoded
+ from the client to the server, so it offers no protection against
+ eavesdropping. This means that a malicious user can monitor network
+ packets and discover valid users and passwords that could result in a
+ serious compromise in network security. Use Basic authentication with
+ extreme care.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<P>The CUPS implementation of Basic authentication does not allow access
+ through user accounts without a password. If you try to authenticate
+ using an account without a password, your access will be immediately
+ blocked.</P>
+<P>Once a valid username and password is authenticated by CUPS, any
+ additional group membership requirements are checked.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>The root user is considered by CUPS to be a member of every group.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 1in -->
+<P>Use the <CODE>AuthType</CODE> directive to enable Basic
+ authentication:</P>
+<UL>
+<PRE>
+AuthType Basic
+</PRE>
+</UL>
+
+<!-- NEED 7in -->
+<H3><A NAME="7_5_3">Using Digest Authentication</A></H3>
+<P>Digest authentication uses users and passwords defined in the<VAR>
+ /etc/cups/passwd.md5</VAR> file to authenticate access to resources
+ such as printers and classes, and to limit access to administrative
+ functions.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Unlike Basic authentication, Digest passes the MD5 sum (basically a
+ complicated checksum) of the username and password instead of the
+ strings themselves. Also, Digest authentication does not use the UNIX
+ password file, so if an attacker does discover the original password it
+ is less likely to result in a serious security problem so long as you
+ use a different UNIX password than the corresponding Digest password.</P>
+<P>The current CUPS implementation of Digest authentication uses the
+ client's hostname or IP address for the &quot;nonce&quot; value. The nonce value
+ is an additional string added to the username and password to make
+ guessing the password more difficult. The server checks that the nonce
+ value matches the client's hostname or address and rejects the MD5 sum
+ if it doesn't. Future versions of CUPS will support Digest &quot;session&quot;
+ authentication which adds the request data to the MD5 sum, providing
+ even better authentication and security.</P>
+<P>Digest authentication does not guarantee that an attacker cannot gain
+ unauthorized access, but it is safer than Basic authentication and
+ should be used in place of Basic authentication whenever possible.<B>
+ Support for Digest authentication in web browsers is not yet
+ universally available.</B></P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 2in -->
+<P>The <CODE>lppasswd(1)</CODE> command is used to add, change, or
+ remove accounts from the<VAR> passwd.md5</VAR> file. To add a user to
+ the default system group, type:</P>
+<UL>
+<PRE>
+<B>lppasswd -a user ENTER</B>
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<P>Once added, a user can change his/her password by typing:</P>
+<UL>
+<PRE>
+<B>lppasswd ENTER</B>
+Old password: <B>(password) ENTER</B> [password is not echoed]
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE>
+</UL>
+
+<!-- NEED 1in -->
+<P>To remove a user from the password file, type:</P>
+<UL>
+<PRE>
+<B>lppasswd -x user ENTER</B>
+</PRE>
+</UL>
+<P>Once a valid username and password is authenticated by CUPS, any
+ additional group membership requirements are checked.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>The root user is considered by CUPS to be a member of every group.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<P>Use the <CODE>AuthType</CODE> directive to enable Digest
+ authentication:</P>
+<UL>
+<PRE>
+AuthType Digest
+</PRE>
+</UL>
+<H3><A NAME="7_5_4">System and Group Authentication</A></H3>
+<P>The<A HREF="#AuthClass"> <CODE>AuthClass</CODE></A> directive
+ controls the level of authentication to perform. <CODE>System</CODE>
+ and <CODE>Group</CODE> authentication extend the normal user-based
+ authentication to require membership in a UNIX group. For <CODE>System</CODE>
+ authentication each user must belong to the <CODE>sys</CODE>, <CODE>
+system</CODE>, or <CODE>root</CODE> group; the actual group depends on
+ the operating system.</P>
+<P>For <CODE>Group</CODE> authentication each user must belong to the
+ group named by the<A HREF="#AuthGroupName"> <CODE>AuthGroupName</CODE></A>
+ directive:</P>
+<UL>
+<PRE>
+&lt;Location /path&gt;
+AuthType Digest
+AuthClass Group
+AuthGroupName mygroup
+&lt;/Location&gt;
+</PRE>
+</UL>
+<P>The named group must be a valid UNIX user group, usually defined in
+ the<VAR> /etc/group</VAR> or<VAR> /etc/netgroup</VAR> files.
+ Additionally, when using Digest authentication you need to create user
+ accounts with the named group:</P>
+<UL>
+<PRE>
+<B>lppasswd -g mygroup -a user ENTER</B>
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE>
+</UL>
+
+<!-- NEW PAGE -->
+<H2><A NAME="PRINTER_ACCOUNTING">Printer Accounting</A></H2>
+<P>CUPS maintains a log of all accesses, errors, and pages that are
+ printed. The log files are normally stored in the<VAR> /var/log/cups</VAR>
+ directory. You can change this by editing the<VAR> /etc/cups/cupsd.conf</VAR>
+ configuration file.</P>
+<H3><A NAME="7_6_1">The access_log File</A></H3>
+<P>The<VAR> access_log</VAR> file lists each HTTP resource that is
+ accessed by a web browser or CUPS/IPP client. Each line is in the
+ so-called &quot;Common Log Format&quot; used by many web servers and web
+ reporting tools:</P>
+<UL>
+<PRE>
+host group user date-time \&quot;method resource version\&quot; status bytes
+
+127.0.0.1 - - [20/May/1999:19:20:29 +0000] &quot;POST /admin/ HTTP/1.1&quot; 401 0
+127.0.0.1 - mike [20/May/1999:19:20:31 +0000] &quot;POST /admin/ HTTP/1.1&quot; 200 0
+</PRE>
+</UL>
+<P>The<I> host</I> field will normally only be an IP address unless you
+ have enabled the<A HREF="#HostNameLookups"> <CODE>HostNameLookups</CODE>
+</A> directive in the<VAR> cupsd.conf</VAR> file.</P>
+<P>The<I> group</I> field always contains &quot;-&quot; in CUPS.</P>
+<P>The<I> user</I> field is the authenticated username of the requesting
+ user. If no username and password is supplied for the request then this
+ field contains &quot;-&quot;.</P>
+<P>The<I> date-time</I> field is the date and time of the request in
+ local time and is in the format:</P>
+<UL>
+<PRE>
+[DD/MON/YYYY:HH:MM:SS +ZZZZ]
+</PRE>
+</UL>
+<P>where<I> ZZZZ</I> is the timezone offset in hours and minutes from
+ Greenwich Mean Time (a.k.a. GMT a.k.a. ZULU.)</P>
+<P>The<I> method</I> field is the HTTP method used (&quot;GET&quot;, &quot;PUT&quot;,
+ &quot;POST&quot;, etc.)</P>
+<P>The<I> resource</I> field is the filename of the requested resource.</P>
+<P>The<I> version</I> field is the HTTP specification version used by
+ the client. For CUPS clients this will always be &quot;HTTP/1.1&quot;.</P>
+<P>The<I> status</I> field contains the HTTP result status of the
+ request. Usually it is &quot;200&quot;, but other HTTP status codes are possible.
+ For example, 401 is the &quot;unauthorized access&quot; status in the example
+ above.</P>
+<P>The<I> bytes</I> field contains the number of bytes in the request.
+ For POST requests the<I> bytes</I> field contains the number of bytes
+ that was received from the client.</P>
+<H3><A NAME="7_6_2">The error_log File</A></H3>
+<P>The<VAR> error_log</VAR> file lists messages from the scheduler
+ (errors, warnings, etc.):</P>
+<UL>
+<PRE>
+level date-time message
+
+I [20/May/1999:19:18:28 +0000] Job 1 queued on 'DeskJet' by 'mike'.
+I [20/May/1999:19:21:02 +0000] Job 2 queued on 'DeskJet' by 'mike'.
+I [20/May/1999:19:22:24 +0000] Job 2 was cancelled by 'mike'.
+</PRE>
+</UL>
+<P>The<I> level</I> field contains the type of message:</P>
+<UL>
+<LI><CODE>E</CODE> - An error occurred.</LI>
+<LI><CODE>W</CODE> - The server was unable to perform some action.</LI>
+<LI><CODE>I</CODE> - Informational message.</LI>
+<LI><CODE>D</CODE> - Debugging message.</LI>
+</UL>
+<P>The<I> date-time</I> field contains the date and time of when the
+ page started printing. The format of this field is identical to the<I>
+ data-time</I> field in the<VAR> access_log</VAR> file.</P>
+<P>The<I> message</I> fields contains a free-form textual message.</P>
+<H3><A NAME="7_6_3">The page_log File</A></H3>
+<P>The<VAR> page_log</VAR> file lists each page that is sent to a
+ printer. Each line contains the following information:</P>
+<UL>
+<PRE>
+printer user job-id date-time page-number num-copies job-billing
+
+DeskJet root 2 [20/May/1999:19:21:05 +0000] 1 0 acme-123
+</PRE>
+</UL>
+<P>The<I> printer</I> field contains the name of the printer that
+ printed the page. If you send a job to a printer class, this field will
+ contain the name of the printer that was assigned the job.</P>
+<P>The<I> user</I> field contains the name of the user (the IPP <CODE>
+requesting-user-name</CODE> attribute) that submitted this file for
+ printing.</P>
+<P>The<I> job-id</I> field contains the job number of the page being
+ printed. Job numbers are reset to 1 whenever the CUPS server is
+ started, so don't depend on this number being unique!</P>
+<P>The<I> date-time</I> field contains the date and time of when the
+ page started printing. The format of this field is identical to the<I>
+ data-time</I> field in the<VAR> access_log</VAR> file.</P>
+<P>The<I> page-number</I> and<I> num-pages</I> fields contain the page
+ number and number of copies being printed of that page. For printer
+ that can not produce copies on their own, the<I> num-pages</I> field
+ will always be 1.</P>
+<P>The<I> job-billing</I> field contains a copy of the <CODE>job-billing</CODE>
+ attribute provided with the IPP <CODE>create-job</CODE> or <CODE>
+print-job</CODE> requests or &quot;-&quot; if none was provided.
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="FILE_TYPING_FILTERING">File Typing and Filtering</A></H2>
+<P>CUPS provides a MIME-based file typing and filtering mechanism to
+ convert files to a printable format for each printer. On startup the
+ CUPS server reads MIME database files from the<VAR> /etc/cups</VAR>
+ directory (or a directory specified by the<A HREF="#ServerRoot"> <CODE>
+ServerRoot</CODE></A> directive) to build a file type and conversion
+ database in memory. These database files are plain ASCII text and can
+ be edited with your favorite text editor.</P>
+<P>The<VAR> mime.types</VAR> and<VAR> mime.convs</VAR> files define the
+ standard file types and filters that are available on the system.</P>
+<H3><A NAME="7_7_1">mime.types</A></H3>
+<P>The<VAR> mime.types</VAR> file defines the known file types. Each
+ line of the file starts with the MIME type and may be followed by one
+ or more file type recognition rules. For example, the <CODE>text/html</CODE>
+ file type is defined as:</P>
+<UL>
+<PRE>
+text/html html htm \
+ printable(0,1024) + \
+ (string(0,&quot;&lt;HTML&gt;&quot;) string(0,&quot;&lt;!DOCTYPE&quot;))
+</PRE>
+</UL>
+<P>The first two rules say that any file with an extension of<VAR> .html</VAR>
+ or<VAR> .htm</VAR> is a HTML file. The third rule says that any file
+ whose first 1024 characters are printable text and starts with the
+ strings <CODE>&lt;HTML&gt;</CODE> or <CODE>&lt;!DOCTYPE</CODE> is a HTML file as
+ well.</P>
+<P>The first two rules deal solely with the name of the file being
+ typed. This is useful when the original filename is known, however for
+ print files the server doesn't have a filename to work with. The third
+ rule takes care of this possibility and automatically figures out the
+ file type based upon the contents of the file instead.</P>
+<P>The available tests are:</P>
+<UL>
+<LI><CODE>( expr )</CODE> - Parenthesis for expression grouping</LI>
+<LI><CODE>+</CODE> - Logical AND</LI>
+<LI><CODE>,</CODE> or whitespace - Logical OR</LI>
+<LI><CODE>!</CODE> - Logical NOT</LI>
+<LI><CODE>match(&quot;pattern&quot;)</CODE> - Pattern match on filename</LI>
+<LI><CODE>extension</CODE> - Pattern match on &quot;*.extension&quot;</LI>
+<LI><CODE>ascii(offset,length)</CODE> - True if bytes are valid
+ printable ASCII (CR, NL, TAB, BS, 32-126)</LI>
+<LI><CODE>printable(offset,length)</CODE> - True if bytes are printable
+ 8-bit chars (CR, NL, TAB, BS, 32-126, 160-254)</LI>
+<LI><CODE>string(offset,&quot;string&quot;)</CODE> - True if bytes are identical
+ to string</LI>
+<LI><CODE>contains(offset,range,&quot;string&quot;)</CODE> - True if the range of
+ bytes contains the string</LI>
+<LI><CODE>char(offset,value)</CODE> - True if byte is identical</LI>
+<LI><CODE>short(offset,value)</CODE> - True if 16-bit integer is
+ identical (network or &quot;big-endian&quot; byte order)</LI>
+<LI><CODE>int(offset,value)</CODE> - True if 32-bit integer is identical
+ (network or &quot;big-endian&quot; byte order)</LI>
+<LI><CODE>locale(&quot;string&quot;)</CODE> - True if current locale matches
+ string</LI>
+</UL>
+<P>All numeric values can be in decimal (123), octal (0123), or
+ hexadecimal (0x123) as desired.
+<!-- NEED 2.5in -->
+</P>
+<P>Strings can be in quotes, all by themselves, as a string of
+ hexadecimal values, or some combination:</P>
+<UL>
+<PRE>
+&quot;string&quot;
+'string'
+string
+&lt;737472696e67&gt;
+&lt;7374&gt;ring
+</PRE>
+</UL>
+<P>As shown in the <CODE>text/html</CODE> example, rules can continue on
+ multiple lines using the backslash (\) character. A more complex
+ example is the <CODE>image/jpeg</CODE> rules:</P>
+<UL>
+<PRE>
+image/jpeg jpeg jpg jpe string(0,&lt;FFD8FF&gt;) &amp;&amp;\
+ (char(3,0xe0) char(3,0xe1) char(3,0xe2) char(3,0xe3)\
+ char(3,0xe4) char(3,0xe5) char(3,0xe6) char(3,0xe7)\
+ char(3,0xe8) char(3,0xe9) char(3,0xea) char(3,0xeb)\
+ char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef))
+</PRE>
+</UL>
+<P>This rule states that any file with an extension of<VAR> .jpeg</VAR>,<VAR>
+ .jpg</VAR>, or<VAR> .jpe</VAR> is a JPEG file. In addition, any file
+ starting with the hexadecimal string <CODE>&lt;FFD8FF&gt;</CODE> (JPEG
+ Start-Of-Image) followed by a character between and including <CODE>
+0xe0</CODE> and <CODE>0xef</CODE> (JPEG APPn markers) is also a JPEG
+ file.</P>
+<H3><A NAME="7_7_2">mime.convs</A></H3>
+<P>The<VAR> mime.convs</VAR> file defines all of the filter programs
+ that are known to the system. Each line consists of:</P>
+<UL>
+<PRE>
+source destination cost program
+
+text/plain application/postscript 50 texttops
+application/vnd.cups-postscript application/vnd.cups-raster 50 pstoraster
+image/* application/vnd.cups-postscript 50 imagetops
+image/* application/vnd.cups-raster 50 imagetoraster
+</PRE>
+</UL>
+<P>The<I> source</I> field is a MIME type, optionally using a wildcard
+ for the super-type or sub-type (e.g. &quot;text/plain&quot;, &quot;image/*&quot;,
+ &quot;*/postscript&quot;).</P>
+<P>The<I> destination</I> field is a MIME type defined in the<VAR>
+ mime.types</VAR> file.</P>
+<P>The<I> cost</I> field defines a relative cost for the filtering
+ operation from 1 to 100. The cost is used to choose between two
+ different sets of filters when converting a file. For example, to
+ convert from <CODE>image/jpeg</CODE> to <CODE>
+application/vnd.cups-raster</CODE>, you could use the <CODE>imagetops</CODE>
+ and <CODE>pstoraster</CODE> filters for a total cost of 100, or the <CODE>
+imagetoraster</CODE> filter for a total cost of 50.</P>
+<P>The<I> program</I> field defines the filter program to run; the
+ special program &quot;-&quot; can be used to make two file types equivalent. The
+ program must accept the standard filter arguments and environment
+ variables described in the CUPS Interface Design Description and CUPS
+ Software Programmers Manual:</P>
+<UL>
+<PRE>
+program job user title options [filename]
+</PRE>
+</UL>
+<P>If specified, the<I> filename</I> argument defines a file to read
+ when filtering, otherwise the filter must read from the standard input.
+ All filtered output must go to the standard output.
+<!-- NEED 4in -->
+</P>
+<H3><A NAME="7_7_3">Adding Filetypes and Filters</A></H3>
+<P>Adding a new file type or filter is fairly straight-forward. Rather
+ than adding the new type and filter to the<VAR> mime.types</VAR> and<VAR>
+ mime.convs</VAR> files which are overwritten when you upgrade to a new
+ version of CUPS, you simple need to create new files with<VAR> .types</VAR>
+ and<VAR> .convs</VAR> extensions in the<VAR> /etc/cups</VAR> directory.
+ We recommend that you use the product or format name, e.g.:</P>
+<UL>
+<PRE>
+myproduct.types
+myproduct.convs
+</PRE>
+</UL>
+<P>If you are providing a filter for a common file format or printer,
+ add the company or author name:</P>
+<UL>
+<PRE>
+acme-msword.types
+acme.msword.convs
+</PRE>
+</UL>
+<P>This will help to prevent name collisions if you install many
+ different file types and filters.</P>
+<P>Once you choose the names for these files, create them using your
+ favorite text editor as described earlier in this chapter. Once you
+ have created the files, restart the <CODE>cupsd</CODE> process as
+ described earlier in<A HREF="#RESTARTING"> &quot;Restarting the CUPS Server&quot;</A>
+.</P>
+<H3><A NAME="7_7_4">Printer Drivers and PPD Files</A></H3>
+<P>Most CUPS printer drivers utilize one or more printer-specific
+ filters and a PPD file for each printer model. Printer driver filters
+ are registered via the PPD file using <CODE>cupsFilter</CODE>
+ attributes:</P>
+<UL>
+<PRE>
+*cupsFilter: &quot;application/vnd.cups-raster 0 rastertohp&quot;
+</PRE>
+</UL>
+<P>The filter is specified using the source file type only; the
+ destination file type is assumed to be <CODE>printer/name</CODE> -
+ suitable for sending to the printer.</P>
+<H3><A NAME="7_7_5">Writing Your Own Filter or Printer Driver</A></H3>
+<P>CUPS supports an unlimited number of file formats and filters, and
+ can handle any printer. If you'd like to write a filter or printer
+ driver for your favorite file format or printer, consult the CUPS
+ Software Programmers Manual for step-by-step instructions.</P>
+<H1 ALIGN="RIGHT"><A NAME="PRINTING_OTHER">7 - Printing with Other
+ Systems</A></H1>
+<P>This chapter describes how to print from client systems that use the
+ LPD, Mac OS, or Windows printing protocols.</P>
+<H2><A NAME="8_1">The Basics</A></H2>
+<P>CUPS is based on the IPP protocol, so any system that supports IPP
+ can send jobs to and receive jobs from CUPS automatically. However, not
+ all systems support IPP yet. This chapter will show you how to connect
+ these systems to your CUPS server, either to accept jobs from your
+ server for printing, or to send jobs to your server.</P>
+<H2><A NAME="8_2">Printing from LPD Clients</A></H2>
+<P>CUPS supports limited functionality for LPD-based clients. With LPD
+ you can print files to specific printers, list the queue status, and so
+ forth. However, the automatic client configuration and printer options
+ are not supported by the LPD protocol, so you must manually configure
+ each client for the printers it needs to access.</P>
+<P>The <CODE>cups-lpd(8)</CODE> program provides support for LPD clients
+ and can be used from either the <CODE>inetd(8)</CODE> or <CODE>
+xinetd(8)</CODE> programs. Add the following line to the<VAR>
+ /etc/inetd.conf</VAR> file to enable LPD support on your server through
+ the <CODE>inetd</CODE> program:</P>
+<UL>
+<PRE>
+printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd
+</PRE>
+</UL>
+<P>The path to the <CODE>cups-lpd</CODE> may vary depending on your
+ installation.</P>
+<P>Once you have added this line, send the <CODE>inetd</CODE> process a <CODE>
+HUP</CODE> signal or reboot the system:</P>
+<UL>
+<PRE>
+<B>killall -HUP inetd ENTER</B> [IRIX and some versions of Linux]
+<B>kill -HUP <I>pid</I> ENTER [Others]</B>
+<B>reboot ENTER [For all systems if the HUP signal fails]</B>
+</PRE>
+</UL>
+<P>If you are using the <CODE>xinetd</CODE> program, create a file named<VAR>
+ /etc/xinetd.d/printer</VAR> containing the following lines:</P>
+<UL>
+<PRE>
+service printer
+{
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ user = lp
+ server = /usr/lib/cups/daemon/cups-lpd
+}
+</PRE>
+</UL>
+<P>The <CODE>xinetd</CODE> program automatically reads the new
+ configuration file and enables LPD printing support.
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B>Warning:</B>
+<P><CODE>cups-lpd</CODE> currently does not perform any access control
+ based on the settings in<VAR> cupsd.conf</VAR> or in the<VAR>
+ hosts.allow</VAR> or<VAR> hosts.deny</VAR> files used by TCP wrappers.
+ Therefore, running <CODE>cups-lpd</CODE> on your server will allow any
+ computer on your network (and perhaps the entire Internet) to print to
+ your server.</P>
+<P>While <CODE>xinetd</CODE> has built-in access control support, you
+ should use the TCP wrappers package with <CODE>inetd</CODE> to limit
+ access to only those computers that should be able to print through
+ your server.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H2><A NAME="8_3">Printing to LPD Servers</A></H2>
+<P>CUPS provides the <CODE>lpd</CODE> backend for printing to LPD-based
+ servers and printers. Use a device URI of <CODE>lpd://server/name</CODE>
+ to print to a printer on an LPD server, where <CODE>server</CODE> is
+ the hostname or IP address of the server and <CODE>name</CODE> is the
+ queue name.</P>
+<P>Microsoft Windows NT provides an LPD service under the name &quot;TCP/IP
+ Printing Services&quot;. To enable LPD printing on NT, open the &quot;Services&quot;
+ control panel, select the &quot;TCP/IP Printing Services&quot; service, and click
+ on the &quot;Start&quot; button. Any shared printer will then be available via
+ the LPD protocol.</P>
+<H2><A NAME="8_4">Printing from Mac OS Clients</A></H2>
+<P>CUPS does not provide Mac OS support directly. However, there are
+ several free and commercial software packages that do.</P>
+<H3><A NAME="8_4_1">Columbia Appletalk Package (CAP)</A></H3>
+<P>Because the CAP LaserWriter server (<CODE>lwsrv(8)</CODE>) does not
+ support specification of PPD files, we do not recommend that you use
+ CAP with CUPS. However, you can run the <CODE>lpsrv</CODE> program for
+ limited printing with the command:</P>
+<UL>
+<PRE>
+lwsrv -n &quot;<I>Name</I>&quot; -p <I>printer</I> -a /usr/lib/adicts -f /usr/lib/LW+Fonts
+</PRE>
+</UL>
+<P>where <CODE>Name</CODE> is the name you want to use when sharing the
+ printer, and <CODE>printer</CODE> is the name of the CUPS print queue.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="8_4_2">XINET KA/Spool</A></H3>
+<P>To use your system as a print server for Mac OS clients, configure
+ each printer using a <CODE>papserver(8)</CODE> in the<VAR>
+ /usr/adm/appletalk/services</VAR> file, specifying the corresponding
+ PPD file in the<VAR> /etc/cups/ppd</VAR> directory for each printer.
+ For a printer named <CODE>MyPrinter</CODE> the entry would look like:</P>
+<UL>
+<PRE>
+/usr/etc/appletalk/papserver -I -L -P /etc/cups/ppd/MyPrinter.ppd \
+&quot;Printer Description&quot; MyPrinter
+</PRE>
+</UL>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Enter the text above on a single line without the backslash (\)
+ character.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="8_4_3">NetATalk</A></H3>
+<P>To use your system as a print server for Mac OS clients, configure
+ each printer in the<VAR> papd.conf</VAR> file, specifying the
+ corresponding PPD file in the<VAR> /etc/cups/ppd</VAR> directory for
+ each printer. For a printer named <CODE>MyPrinter</CODE> the entry
+ would look like:</P>
+<UL>
+<PRE>
+Printer Description:MyPrinter@MyServer:\
+ :pr=|/usr/bin/lp -d MyPrinter:\
+ :op=daemon:\
+ :pd=/etc/cups/ppd/MyPrinter.ppd:
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<H2><A NAME="8_5">Printing to Mac OS Servers</A></H2>
+<P>CUPS currently does not provide a backend to communicate with a Mac
+ OS server. However, you can write and install a short shell script in
+ the<VAR> /usr/lib/cups/backend</VAR> directory that sends a print file
+ using the appropriate command. The following is a short script that
+ will run the <CODE>papif</CODE> command provided with CAP.</P>
+<P>After copying this script to<VAR> /usr/lib/cups/backend/cap</VAR>,
+ specify a device URI of <CODE>cap://server/printer</CODE> to use this
+ backend with a print queue.
+<!-- NEED 8in -->
+</P>
+<UL>
+<PRE>
+<I>&quot;/usr/lib/cups/backend/cap&quot;</I>
+#!/bin/sh
+#
+# Usage: cap job user title copies options [filename]
+#
+
+# No arguments means show available devices...
+
+if test ${#argv} = 0; then
+ echo &quot;network cap \&quot;Unknown\&quot; \&quot;Mac OS Printer via CAP\&quot;&quot;
+ exit 0
+fi
+
+# Collect arguments...
+
+user=$2
+copies=$4
+
+if test ${#argv} = 5; then
+ # Get print file from stdin; copies have already been handled...
+ file=/var/tmp/$$.prn
+ copies=1
+ cat &gt; $file
+else
+ # Print file is on command-line...
+ file=$6
+fi
+
+# Create a dummy cap.printers file for this printer based
+# upon a device URI of &quot;cap://server/printer&quot;...
+
+echo $PRINTER/$DEVICE_URI | \
+ awk -F/ '{print $1 &quot;=&quot; $5 &quot;:LaserWriter@&quot; $4}' &gt; /var/tmp/$$.cap
+
+CAPPRINTERS=/var/tmp/$$.cap; export CAPPRINTERS
+
+# Send the file to the printer, once for each copy. This assumes that you
+# have properly initialized the cap.printers file...
+
+while [ $copies -gt 0 ]; do
+ papif -n $user &lt; $file
+
+ copies=`expr $copies - 1`
+done
+
+# Remove any temporary files...
+if test ${#argv} = 5; then
+ /bin/rm -f $file
+fi
+
+/bin/rm -f /var/tmp/$$.cap
+
+exit 0
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<H2><A NAME="8_6">Printing from Windows Clients</A></H2>
+<P>While CUPS does not provide Windows support directly, the free SAMBA
+ software package does. SAMBA version 2.0.6 is the first release of
+ SAMBA that supports CUPS. You can download SAMBA from:</P>
+<UL>
+<PRE>
+<A HREF="http://www.samba.org">http://www.samba.org</A>
+</PRE>
+</UL>
+<P>To configure SAMBA for CUPS, edit the<VAR> smb.conf</VAR> file and
+ replace the existing printing commands and options with the line:</P>
+<UL>
+<PRE>
+printing = cups
+printcap name = cups
+</PRE>
+</UL>
+<P>That's all there is to it! Remote users will now be able to browse
+ and print to printers on your system.</P>
+<H3><A NAME="8_6_1">Exporting Printer Drivers</A></H3>
+<P>You can optionally export printer drivers from your CUPS server using
+ the <CODE>cupsaddsmb</CODE> command and the SAMBA 2.2.0 or higher
+ software.</P>
+<P>Before you can export the printers you must download the current
+ Adobe PostScript printer drivers from the Adobe web site (<A HREF="http://www.adobe.com/">
+http://www.adobe.com/</A>). Use the free <CODE>unzip</CODE> software to
+ extract the files from the self-extracting ZIP file containing the
+ drivers; you will need the following files:</P>
+<UL>
+<PRE>
+ADFONTS.MFM
+ADOBEPS4.DRV
+ADOBEPS4.HLP
+ADOBEPS5.DLL
+ADOBEPSU.DLL
+ADOBEPSU.HLP
+DEFPRTR2.PPD
+ICONLIB.DLL
+PSMON.DLL
+</PRE>
+</UL>
+<P>Copy these files to the<VAR> /usr/share/cups/drivers</VAR> directory
+ - you may need to rename some of the files so the filenames are all
+ UPPERCASE.</P>
+<P>Next, configure SAMBA (via the<VAR> smb.conf</VAR> file) to support
+ printing through CUPS and provide a printer driver download share, as
+ follows:</P>
+<UL>
+<PRE>
+[global]
+ load printers = yes
+ printing = cups
+ printcap name = cups
+
+[printers]
+ comment = All Printers
+ path = /var/spool/samba
+ browseable = no
+ public = yes
+ guest ok = yes
+ writable = no
+ printable = yes
+ printer admin = root
+
+[print$]
+ comment = Printer Drivers
+ path = /etc/samba/drivers
+ browseable = yes
+ guest ok = no
+ read only = yes
+ write list = root
+</PRE>
+</UL>
+<P>This configuration assumes a FHS-compliant installation of SAMBA;
+ adjust the [printers] and [print$] share paths accordingly on your
+ system as needed. That is, the directory for your printer drivers can
+ be anywhere on the system; just make sure it is writable by the users
+ specified by the <CODE>write list</CODE> directive plus readable and
+ executable by all users. Also, make sure that you have SAMBA passwords
+ defined for each user in the <CODE>write list</CODE> using SAMBA's <CODE>
+smbpasswd(1)</CODE> command. Otherwise you will not be able to
+ authenticate.</P>
+<P>Finally, run the <CODE>cupsaddsmb</CODE> command to export the
+ printer drivers for one or more queues:</P>
+<UL>
+<PRE>
+<B>cupsaddsmb -U root printer1 ... printerN <I>ENTER</I></B>
+</PRE>
+</UL>
+<P>Running <CODE>cupsaddsmb</CODE> with the <CODE>-a</CODE> option will
+ export all printers:</P>
+<UL>
+<PRE>
+<B>cupsaddsmb -U root -a <I>ENTER</I></B>
+</PRE>
+</UL>
+<P>Notice in the above examples that the user <CODE>root</CODE> was used
+ which was defined in the <CODE>write list</CODE> of the<VAR> smb.conf</VAR>
+ file.</P>
+<H2><A NAME="8_7">Printing to Windows Servers</A></H2>
+<P>CUPS can print to Windows servers in one of two ways. The first way
+ uses the LPD protocol on the CUPS system and the &quot;TCP/IP Printing
+ Services&quot; on the Windows system. You can find out more about this
+ configuration in the<A HREF="#LPD"> LPD</A> section earlier in this
+ chapter.</P>
+<P>The second way is through the Microsoft Server Message Block (&quot;SMB&quot;)
+ protocol. Support for this protocol is provided with the free SAMBA
+ software package. You can download SAMBA from:</P>
+<UL>
+<PRE>
+<A HREF="http://www.samba.org">http://www.samba.org</A>
+</PRE>
+</UL>
+<P>To configure CUPS for SAMBA, run the following command:</P>
+<UL>
+<PRE>
+<B>ln -s `which smbspool` /usr/lib/cups/backend/smb ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>smbspool(1)</CODE> program is provided with SAMBA starting
+ with SAMBA 2.0.6. Once you have made the link you can configure your
+ printers with one of the following device URIs:</P>
+<UL>
+<PRE>
+smb://workgroup/server/sharename
+smb://server/sharename
+smb://user:pass@workgroup/server/sharename
+smb://user:pass@server/sharename
+</PRE>
+</UL>
+<P>The <CODE>workgroup</CODE> name need only be specified if your system
+ is using a different workgroup. The <CODE>user:pass</CODE> strings are
+ required when printing to Windows NT servers or to shares with
+ passwords enabled under Windows 95 and 98.</P>
+<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - Software License Agreement</A></H1>
+<H2 ALIGN="CENTER"><A NAME="9_1">Common UNIX Printing System License
+ Agreement</A></H2>
+<P ALIGN="CENTER">Copyright 1997-2002 by Easy Software Products
+<BR> 44141 AIRPORT VIEW DR STE 204
+<BR> HOLLYWOOD, MARYLAND 20636-3111 USA
+<BR>
+<BR> Voice: +1.301.373.9600
+<BR> Email:<A HREF="mailto:cups-info@cups.org"> cups-info@cups.org</A>
+<BR> WWW:<A HREF="http://www.cups.org"> http://www.cups.org</A></P>
+<H3><A NAME="9_1_1">Introduction</A></H3>
+<P>The Common UNIX Printing System<SUP>TM</SUP>, (&quot;CUPS<SUP>TM</SUP>&quot;),
+ is provided under the GNU General Public License (&quot;GPL&quot;) and GNU
+ Library General Public License (&quot;LGPL&quot;), Version 2, with exceptions for
+ Apple operating systems and the OpenSSL toolkit. A copy of the
+ exceptions and licenses follow this introduction.</P>
+<P>The GNU LGPL applies to the CUPS API library, located in the &quot;cups&quot;
+ subdirectory of the CUPS source distribution and in the &quot;cups&quot; include
+ directory and library files in the binary distributions. The GNU GPL
+ applies to the remainder of the CUPS distribution, including the
+ &quot;pdftops&quot; filter which is based upon Xpdf and the CUPS imaging library.</P>
+<P>For those not familiar with the GNU GPL, the license basically allows
+ you to:</P>
+<UL>
+<LI>Use the CUPS software at no charge.</LI>
+<LI>Distribute verbatim copies of the software in source or binary form.</LI>
+<LI>Sell verbatim copies of the software for a media fee, or sell
+ support for the software.</LI>
+<LI>Distribute or sell printer drivers and filters that use CUPS so long
+ as source code is made available under the GPL.</LI>
+</UL>
+<P>What this license<B> does not</B> allow you to do is make changes or
+ add features to CUPS and then sell a binary distribution without source
+ code. You must provide source for any new drivers, changes, or
+ additions to the software, and all code must be provided under the GPL
+ or LGPL as appropriate. The only exceptions to this are the portions of
+ the CUPS software covered by the Apple operating system license
+ exceptions outlined later in this license agreement.</P>
+<P>The GNU LGPL relaxes the &quot;link-to&quot; restriction, allowing you to
+ develop applications that use the CUPS API library under other licenses
+ and/or conditions as appropriate for your application.</P>
+<H3><A NAME="9_1_2">License Exceptions</A></H3>
+<P>In addition, as the copyright holder of CUPS, Easy Software Products
+ grants the following special exceptions:</P>
+<OL>
+<LI><B>Apple Operating System Development License Exception</B>;
+<OL TYPE="a">
+<LI>Software that is developed by any person or entity for an Apple
+ Operating System (&quot;Apple OS-Developed Software&quot;), including but not
+ limited to Apple and third party printer drivers, filters, and backends
+ for an Apple Operating System, that is linked to the CUPS imaging
+ library or based on any sample filters or backends provided with CUPS
+ shall not be considered to be a derivative work or collective work
+ based on the CUPS program and is exempt from the mandatory source code
+ release clauses of the GNU GPL. You may therefore distribute linked
+ combinations of the CUPS imaging library with Apple OS-Developed
+ Software without releasing the source code of the Apple OS-Developed
+ Software. You may also use sample filters and backends provided with
+ CUPS to develop Apple OS-Developed Software without releasing the
+ source code of the Apple OS-Developed Software.</LI>
+<LI>An Apple Operating System means any operating system software
+ developed and/or marketed by Apple Computer, Inc., including but not
+ limited to all existing releases and versions of Apple's Darwin, Mac OS
+ X, and Mac OS X Server products and all follow-on releases and future
+ versions thereof.</LI>
+<LI>This exception is only available for Apple OS-Developed Software and
+ does not apply to software that is distributed for use on other
+ operating systems.</LI>
+<LI>All CUPS software that falls under this license exception have the
+ following text at the top of each source file:<BLOCKQUOTE>This file is
+ subject to the Apple OS-Developed Software exception.</BLOCKQUOTE></LI>
+</OL>
+</LI>
+<LI><B>OpenSSL Toolkit License Exception</B>;
+<OL TYPE="a">
+<LI>Easy Software Products explicitly allows the compilation and
+ distribution of the CUPS software with the OpenSSL Toolkit.</LI>
+</OL>
+</LI>
+</OL>
+<P>No developer is required to provide these exceptions in a derived
+ work.</P>
+<H3><A NAME="9_1_3">Trademarks</A></H3>
+<P>Easy Software Products has trademarked the Common UNIX Printing
+ System, CUPS, and CUPS logo. These names and logos may be used freely
+ in any direct port or binary distribution of CUPS. Please contract Easy
+ Software Products for written permission to use them in derivative
+ products. Our intention is to protect the value of these trademarks and
+ ensure that any derivative product meets the same high-quality
+ standards as the original.</P>
+<H3><A NAME="9_1_4">Binary Distribution Rights</A></H3>
+<P>Easy Software Products also sells rights to the CUPS source code
+ under a binary distribution license for vendors that are unable to
+ release source code for their drivers, additions, and modifications to
+ CUPS under the GNU GPL and LGPL. For information please contact us at
+ the address shown above.</P>
+<P>The Common UNIX Printing System provides a &quot;pdftops&quot; filter that is
+ based on the Xpdf software. For binary distribution licensing of this
+ software, please contact:<BLOCKQUOTE> Derek B. Noonburg
+<BR> Email:<A HREF="mailto:derekn@foolabs.com"> derekn@foolabs.com</A>
+<BR> WWW:<A HREF="http://www.foolabs.com/xpdf/">
+ http://www.foolabs.com/xpdf/</A></BLOCKQUOTE></P>
+<H3><A NAME="9_1_5">Support</A></H3>
+<P>Easy Software Products sells software support for CUPS as well as a
+ commercial printing product based on CUPS called ESP Print Pro. You can
+ find out more at our web site:</P>
+<UL>
+<PRE>
+<A HREF="http://www.easysw.com/">http://www.easysw.com/</A>
+</PRE>
+</UL>
+
+<!-- NEW PAGE -->
+<H2><A NAME="9_2">GNU GENERAL PUBLIC LICENSE</A></H2>
+<P>Version 2, June 1991</P>
+<PRE>
+Copyright 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim
+copies of this license document, but changing it is not allowed.
+</PRE>
+<H4>Preamble</H4>
+<P>The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public License is
+ intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users. This
+ General Public License applies to most of the Free Software
+ Foundation's software and to any other program whose authors commit to
+ using it. (Some other Free Software Foundation software is covered by
+ the GNU Library General Public License instead.) You can apply it to
+ your programs, too.</P>
+<P>When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it in
+ new free programs; and that you know you can do these things.</P>
+<P>To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the software, or if you modify it.</P>
+<P>For example, if you distribute copies of such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have. You must make sure that they, too, receive or can get the
+ source code. And you must show them these terms so they know their
+ rights.</P>
+<P>We protect your rights with two steps: (1) copyright the software,
+ and (2) offer you this license which gives you legal permission to
+ copy, distribute and/or modify the software.</P>
+<P>Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software. If the software is modified by someone else and passed on, we
+ want its recipients to know that what they have is not the original, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.</P>
+<P>Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that redistributors of a free
+ program will individually obtain patent licenses, in effect making the
+ program proprietary. To prevent this, we have made it clear that any
+ patent must be licensed for everyone's free use or not licensed at all.</P>
+<P>The precise terms and conditions for copying, distribution and
+ modification follow.</P>
+<H4>GNU GENERAL PUBLIC LICENSE
+<BR> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+<OL START="0">
+<LI>This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The &quot;Program&quot;, below,
+ refers to any such program or work, and a &quot;work based on the Program&quot;
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language. (Hereinafter, translation is included without limitation in
+ the term &quot;modification&quot;.) Each licensee is addressed as &quot;you&quot;.
+<P>Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ the Program is not restricted, and the output from the Program is
+ covered only if its contents constitute a work based on the Program
+ (independent of having been made by running the Program). Whether that
+ is true depends on what the Program does.</P>
+<LI>You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you conspicuously
+ and appropriately publish on each copy an appropriate copyright notice
+ and disclaimer of warranty; keep intact all the notices that refer to
+ this License and to the absence of any warranty; and give any other
+ recipients of the Program a copy of this License along with the
+ Program.
+<P>You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.</P>
+<LI>You may modify your copy or copies of the Program or any portion of
+ it, thus forming a work based on the Program, and copy and distribute
+ such modifications or work under the terms of Section 1 above, provided
+ that you also meet all of these conditions:
+<OL TYPE="a">
+<LI>You must cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change.</LI>
+<LI>You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any part
+ thereof, to be licensed as a whole at no charge to all third parties
+ under the terms of this License.</LI>
+<LI>if the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the most ordinary way, to print or display an announcement including
+ an appropriate copyright notice and a notice that there is no warranty
+ (or else, saying that you provide a warranty) and that users may
+ redistribute the program under these conditions, and telling the user
+ how to view a copy of this License. (Exception: if the Program itself
+ is interactive but does not normally print such an announcement, your
+ work based on the Program is not required to print an announcement.)</LI>
+</OL>
+<P>These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Program,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Program, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.</P>
+<P>Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.</P>
+<P>In addition, mere aggregation of another work not based on the
+ Program with the Program (or with a work based on the Program) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.</P>
+<LI>You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+<OL TYPE="a">
+<LI>Accompany it with the complete corresponding machine-readable source
+ code, which must be distributed under the terms of Sections 1 and 2
+ above on a medium customarily used for software interchange; or,</LI>
+<LI>Accompany it with a written offer, valid for at least three years,
+ to give any third party, for a charge no more than your cost of
+ physically performing source distribution, a complete machine-readable
+ copy of the corresponding source code, to be distributed under the
+ terms of Sections 1 and 2 above on a medium customarily used for
+ software interchange; or,</LI>
+<LI>Accompany it with the information you received as to the offer to
+ distribute corresponding source code. (This alternative is allowed only
+ for noncommercial distribution and only if you received the program in
+ object code or executable form with such an offer, in accord with
+ Subsection b above.)</LI>
+</OL>
+<P>The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to control
+ compilation and installation of the executable. However, as a special
+ exception, the source code distributed need not include anything that
+ is normally distributed (in either source or binary form) with the
+ major components (compiler, kernel, and so on) of the operating system
+ on which the executable runs, unless that component itself accompanies
+ the executable.</P>
+<P>If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent access
+ to copy the source code from the same place counts as distribution of
+ the source code, even though third parties are not compelled to copy
+ the source along with the object code.</P>
+<LI>You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt otherwise
+ to copy, modify, sublicense or distribute the Program is void, and will
+ automatically terminate your rights under this License. However,
+ parties who have received copies, or rights, from you under this
+ License will not have their licenses terminated so long as such parties
+ remain in full compliance.</LI>
+<LI>You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying the
+ Program or works based on it.</LI>
+<LI>Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject to
+ these terms and conditions. You may not impose any further restrictions
+ on the recipients' exercise of the rights granted herein. You are not
+ responsible for enforcing compliance by third parties to this License.</LI>
+<LI>If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all. For example, if a patent license
+ would not permit royalty-free redistribution of the Program by all
+ those who receive copies directly or indirectly through you, then the
+ only way you could satisfy both it and this License would be to refrain
+ entirely from distribution of the Program.
+<P>If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.</P>
+<P>It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.</P>
+<P>This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.</P>
+<LI>If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License may
+ add an explicit geographical distribution limitation excluding those
+ countries, so that distribution is permitted only in or among countries
+ not thus excluded. In such case, this License incorporates the
+ limitation as if written in the body of this License.</LI>
+<LI>The Free Software Foundation may publish revised and/or new versions
+ of the General Public License from time to time. Such new versions will
+ be similar in spirit to the present version, but may differ in detail
+ to address new problems or concerns.
+<P>Each version is given a distinguishing version number. If the Program
+ specifies a version number of this License which applies to it and &quot;any
+ later version&quot;, you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Program does not specify a version
+ number of this License, you may choose any version ever published by
+ the Free Software Foundation.</P>
+<LI>If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted by the
+ Free Software Foundation, write to the Free Software Foundation; we
+ sometimes make exceptions for this. Our decision will be guided by the
+ two goals of preserving the free status of all derivatives of our free
+ software and of promoting the sharing and reuse of software generally.</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<H4>NO WARRANTY</H4>
+<OL START="11">
+<LI>BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER
+ EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
+ YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+ NECESSARY SERVICING, REPAIR OR CORRECTION.</LI>
+<LI>IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+ AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
+ FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.</LI>
+</OL>
+<H4>END OF TERMS AND CONDITIONS</H4>
+
+<!-- NEW PAGE -->
+<H2><A NAME="9_3">GNU LIBRARY GENERAL PUBLIC LICENSE</A></H2>
+<P>Version 2, June 1991</P>
+<PRE>
+Copyright (C) 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+</PRE>
+<H4>Preamble</H4>
+<P>The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public Licenses
+ are intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users.</P>
+<P>This license, the Library General Public License, applies to some
+ specially designated Free Software Foundation software, and to any
+ other libraries whose authors decide to use it. You can use it for your
+ libraries, too.</P>
+<P>When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it in
+ new free programs; and that you know you can do these things.</P>
+<P>To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the library, or if you modify it.</P>
+<P>For example, if you distribute copies of the library, whether gratis
+ or for a fee, you must give the recipients all the rights that we gave
+ you. You must make sure that they, too, receive or can get the source
+ code. If you link a program with the library, you must provide complete
+ object files to the recipients so that they can relink them with the
+ library, after making changes to the library and recompiling it. And
+ you must show them these terms so they know their rights.</P>
+<P>Our method of protecting your rights has two steps: (1) copyright the
+ library, and (2) offer you this license which gives you legal
+ permission to copy, distribute and/or modify the library.</P>
+<P>Also, for each distributor's protection, we want to make certain that
+ everyone understands that there is no warranty for this free library.
+ If the library is modified by someone else and passed on, we want its
+ recipients to know that what they have is not the original version, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.</P>
+<P>Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that companies distributing free
+ software will individually obtain patent licenses, thus in effect
+ transforming the program into proprietary software. To prevent this, we
+ have made it clear that any patent must be licensed for everyone's free
+ use or not licensed at all.</P>
+<P>Most GNU software, including some libraries, is covered by the
+ ordinary GNU General Public License, which was designed for utility
+ programs. This license, the GNU Library General Public License, applies
+ to certain designated libraries. This license is quite different from
+ the ordinary one; be sure to read it in full, and don't assume that
+ anything in it is the same as in the ordinary license.</P>
+<P>The reason we have a separate public license for some libraries is
+ that they blur the distinction we usually make between modifying or
+ adding to a program and simply using it. Linking a program with a
+ library, without changing the library, is in some sense simply using
+ the library, and is analogous to running a utility program or
+ application program. However, in a textual and legal sense, the linked
+ executable is a combined work, a derivative of the original library,
+ and the ordinary General Public License treats it as such.</P>
+<P>Because of this blurred distinction, using the ordinary General
+ Public License for libraries did not effectively promote software
+ sharing, because most developers did not use the libraries. We
+ concluded that weaker conditions might promote sharing better.</P>
+<P>However, unrestricted linking of non-free programs would deprive the
+ users of those programs of all benefit from the free status of the
+ libraries themselves. This Library General Public License is intended
+ to permit developers of non-free programs to use free libraries, while
+ preserving your freedom as a user of such programs to change the free
+ libraries that are incorporated in them. (We have not seen how to
+ achieve this as regards changes in header files, but we have achieved
+ it as regards changes in the actual functions of the Library.) The hope
+ is that this will lead to faster development of free libraries.</P>
+<P>The precise terms and conditions for copying, distribution and
+ modification follow. Pay close attention to the difference between a
+ &quot;work based on the library&quot; and a &quot;work that uses the library&quot;. The
+ former contains code derived from the library, while the latter only
+ works together with the library.</P>
+<P>Note that it is possible for a library to be covered by the ordinary
+ General Public License rather than by this special one.</P>
+<H4>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+<P><STRONG>0.</STRONG> This License Agreement applies to any software
+ library which contains a notice placed by the copyright holder or other
+ authorized party saying it may be distributed under the terms of this
+ Library General Public License (also called &quot;this License&quot;). Each
+ licensee is addressed as &quot;you&quot;.</P>
+<P>A &quot;library&quot; means a collection of software functions and/or data
+ prepared so as to be conveniently linked with application programs
+ (which use some of those functions and data) to form executables.</P>
+<P>The &quot;Library&quot;, below, refers to any such software library or work
+ which has been distributed under these terms. A &quot;work based on the
+ Library&quot; means either the Library or any derivative work under
+ copyright law: that is to say, a work containing the Library or a
+ portion of it, either verbatim or with modifications and/or translated
+ straightforwardly into another language. (Hereinafter, translation is
+ included without limitation in the term &quot;modification&quot;.)</P>
+<P>&quot;Source code&quot; for a work means the preferred form of the work for
+ making modifications to it. For a library, complete source code means
+ all the source code for all modules it contains, plus any associated
+ interface definition files, plus the scripts used to control
+ compilation and installation of the library.</P>
+<P>Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ a program using the Library is not restricted, and output from such a
+ program is covered only if its contents constitute a work based on the
+ Library (independent of the use of the Library in a tool for writing
+ it). Whether that is true depends on what the Library does and what the
+ program that uses the Library does.</P>
+<P><STRONG>1.</STRONG> You may copy and distribute verbatim copies of
+ the Library's complete source code as you receive it, in any medium,
+ provided that you conspicuously and appropriately publish on each copy
+ an appropriate copyright notice and disclaimer of warranty; keep intact
+ all the notices that refer to this License and to the absence of any
+ warranty; and distribute a copy of this License along with the Library.</P>
+<P>You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.</P>
+<P><STRONG>2.</STRONG> You may modify your copy or copies of the Library
+ or any portion of it, thus forming a work based on the Library, and
+ copy and distribute such modifications or work under the terms of
+ Section 1 above, provided that you also meet all of these conditions:</P>
+<OL TYPE="a">
+<LI>The modified work must itself be a software library.
+<P></P>
+<LI>You must cause the files modified to carry prominent notices stating
+ that you changed the files and the date of any change.
+<P></P>
+<LI>You must cause the whole of the work to be licensed at no charge to
+ all third parties under the terms of this License.
+<P></P>
+<LI>If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses the
+ facility, other than as an argument passed when the facility is
+ invoked, then you must make a good faith effort to ensure that, in the
+ event an application does not supply such function or table, the
+ facility still operates, and performs whatever part of its purpose
+ remains meaningful.
+<P>(For example, a function in a library to compute square roots has a
+ purpose that is entirely well-defined independent of the application.
+ Therefore, Subsection 2d requires that any application-supplied
+ function or table used by this function must be optional: if the
+ application does not supply it, the square root function must still
+ compute square roots.)</P>
+</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<P>These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Library,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Library, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.</P>
+<P>Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Library.</P>
+<P>In addition, mere aggregation of another work not based on the
+ Library with the Library (or with a work based on the Library) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.</P>
+<P><STRONG>3.</STRONG> You may opt to apply the terms of the ordinary
+ GNU General Public License instead of this License to a given copy of
+ the Library. To do this, you must alter all the notices that refer to
+ this License, so that they refer to the ordinary GNU General Public
+ License, version 2, instead of to this License. (If a newer version
+ than version 2 of the ordinary GNU General Public License has appeared,
+ then you can specify that version instead if you wish.) Do not make any
+ other change in these notices.</P>
+<P>Once this change is made in a given copy, it is irreversible for that
+ copy, so the ordinary GNU General Public License applies to all
+ subsequent copies and derivative works made from that copy.</P>
+<P>This option is useful when you wish to copy part of the code of the
+ Library into a program that is not a library.</P>
+<P><STRONG>4.</STRONG> You may copy and distribute the Library (or a
+ portion or derivative of it, under Section 2) in object code or
+ executable form under the terms of Sections 1 and 2 above provided that
+ you accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections 1
+ and 2 above on a medium customarily used for software interchange.</P>
+<P>If distribution of object code is made by offering access to copy
+ from a designated place, then offering equivalent access to copy the
+ source code from the same place satisfies the requirement to distribute
+ the source code, even though third parties are not compelled to copy
+ the source along with the object code.</P>
+<P><STRONG>5.</STRONG> A program that contains no derivative of any
+ portion of the Library, but is designed to work with the Library by
+ being compiled or linked with it, is called a &quot;work that uses the
+ Library&quot;. Such a work, in isolation, is not a derivative work of the
+ Library, and therefore falls outside the scope of this License.</P>
+<P>However, linking a &quot;work that uses the Library&quot; with the Library
+ creates an executable that is a derivative of the Library (because it
+ contains portions of the Library), rather than a &quot;work that uses the
+ library&quot;. The executable is therefore covered by this License. Section
+ 6 states terms for distribution of such executables.</P>
+<P>When a &quot;work that uses the Library&quot; uses material from a header file
+ that is part of the Library, the object code for the work may be a
+ derivative work of the Library even though the source code is not.
+ Whether this is true is especially significant if the work can be
+ linked without the Library, or if the work is itself a library. The
+ threshold for this to be true is not precisely defined by law.</P>
+<P>If such an object file uses only numerical parameters, data structure
+ layouts and accessors, and small macros and small inline functions (ten
+ lines or less in length), then the use of the object file is
+ unrestricted, regardless of whether it is legally a derivative work.
+ (Executables containing this object code plus portions of the Library
+ will still fall under Section 6.)</P>
+<P>Otherwise, if the work is a derivative of the Library, you may
+ distribute the object code for the work under the terms of Section 6.
+ Any executables containing that work also fall under Section 6, whether
+ or not they are linked directly with the Library itself.</P>
+<P><STRONG>6.</STRONG> As an exception to the Sections above, you may
+ also compile or link a &quot;work that uses the Library&quot; with the Library to
+ produce a work containing portions of the Library, and distribute that
+ work under terms of your choice, provided that the terms permit
+ modification of the work for the customer's own use and reverse
+ engineering for debugging such modifications.</P>
+<P>You must give prominent notice with each copy of the work that the
+ Library is used in it and that the Library and its use are covered by
+ this License. You must supply a copy of this License. If the work
+ during execution displays copyright notices, you must include the
+ copyright notice for the Library among them, as well as a reference
+ directing the user to the copy of this License. Also, you must do one
+ of these things:</P>
+<OL TYPE="a">
+<LI>Accompany the work with the complete corresponding machine-readable
+ source code for the Library including whatever changes were used in the
+ work (which must be distributed under Sections 1 and 2 above); and, if
+ the work is an executable linked with the Library, with the complete
+ machine-readable &quot;work that uses the Library&quot;, as object code and/or
+ source code, so that the user can modify the Library and then relink to
+ produce a modified executable containing the modified Library. (It is
+ understood that the user who changes the contents of definitions files
+ in the Library will not necessarily be able to recompile the
+ application to use the modified definitions.)
+<P></P>
+<LI>Accompany the work with a written offer, valid for at least three
+ years, to give the same user the materials specified in Subsection 6a,
+ above, for a charge no more than the cost of performing this
+ distribution.
+<P></P>
+<LI>If distribution of the work is made by offering access to copy from
+ a designated place, offer equivalent access to copy the above specified
+ materials from the same place.
+<P></P>
+<LI>Verify that the user has already received a copy of these materials
+ or that you have already sent this user a copy.</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<P>For an executable, the required form of the &quot;work that uses the
+ Library&quot; must include any data and utility programs needed for
+ reproducing the executable from it. However, as a special exception,
+ the source code distributed need not include anything that is normally
+ distributed (in either source or binary form) with the major components
+ (compiler, kernel, and so on) of the operating system on which the
+ executable runs, unless that component itself accompanies the
+ executable.</P>
+<P>It may happen that this requirement contradicts the license
+ restrictions of other proprietary libraries that do not normally
+ accompany the operating system. Such a contradiction means you cannot
+ use both them and the Library together in an executable that you
+ distribute.</P>
+<P><STRONG>7.</STRONG> You may place library facilities that are a work
+ based on the Library side-by-side in a single library together with
+ other library facilities not covered by this License, and distribute
+ such a combined library, provided that the separate distribution of the
+ work based on the Library and of the other library facilities is
+ otherwise permitted, and provided that you do these two things:</P>
+<OL TYPE="a">
+<LI>Accompany the combined library with a copy of the same work based on
+ the Library, uncombined with any other library facilities. This must be
+ distributed under the terms of the Sections above.
+<P></P>
+<LI>Give prominent notice with the combined library of the fact that
+ part of it is a work based on the Library, and explaining where to find
+ the accompanying uncombined form of the same work.</LI>
+</LI>
+</OL>
+<P><STRONG>8.</STRONG> You may not copy, modify, sublicense, link with,
+ or distribute the Library except as expressly provided under this
+ License. Any attempt otherwise to copy, modify, sublicense, link with,
+ or distribute the Library is void, and will automatically terminate
+ your rights under this License. However, parties who have received
+ copies, or rights, from you under this License will not have their
+ licenses terminated so long as such parties remain in full compliance.</P>
+<P><STRONG>9.</STRONG> You are not required to accept this License,
+ since you have not signed it. However, nothing else grants you
+ permission to modify or distribute the Library or its derivative works.
+ These actions are prohibited by law if you do not accept this License.
+ Therefore, by modifying or distributing the Library (or any work based
+ on the Library), you indicate your acceptance of this License to do so,
+ and all its terms and conditions for copying, distributing or modifying
+ the Library or works based on it.</P>
+<P><STRONG>10.</STRONG> Each time you redistribute the Library (or any
+ work based on the Library), the recipient automatically receives a
+ license from the original licensor to copy, distribute, link with or
+ modify the Library subject to these terms and conditions. You may not
+ impose any further restrictions on the recipients' exercise of the
+ rights granted herein. You are not responsible for enforcing compliance
+ by third parties to this License.</P>
+<P><STRONG>11.</STRONG> If, as a consequence of a court judgment or
+ allegation of patent infringement or for any other reason (not limited
+ to patent issues), conditions are imposed on you (whether by court
+ order, agreement or otherwise) that contradict the conditions of this
+ License, they do not excuse you from the conditions of this License. If
+ you cannot distribute so as to satisfy simultaneously your obligations
+ under this License and any other pertinent obligations, then as a
+ consequence you may not distribute the Library at all. For example, if
+ a patent license would not permit royalty-free redistribution of the
+ Library by all those who receive copies directly or indirectly through
+ you, then the only way you could satisfy both it and this License would
+ be to refrain entirely from distribution of the Library.</P>
+<P>If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply, and the section as a whole is intended to apply in other
+ circumstances.</P>
+<P>It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system which is implemented
+ by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.</P>
+<P>This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.</P>
+<P><STRONG>12.</STRONG> If the distribution and/or use of the Library is
+ restricted in certain countries either by patents or by copyrighted
+ interfaces, the original copyright holder who places the Library under
+ this License may add an explicit geographical distribution limitation
+ excluding those countries, so that distribution is permitted only in or
+ among countries not thus excluded. In such case, this License
+ incorporates the limitation as if written in the body of this License.</P>
+<P><STRONG>13.</STRONG> The Free Software Foundation may publish revised
+ and/or new versions of the Library General Public License from time to
+ time. Such new versions will be similar in spirit to the present
+ version, but may differ in detail to address new problems or concerns.</P>
+<P>Each version is given a distinguishing version number. If the Library
+ specifies a version number of this License which applies to it and &quot;any
+ later version&quot;, you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Library does not specify a license
+ version number, you may choose any version ever published by the Free
+ Software Foundation.</P>
+<P><STRONG>14.</STRONG> If you wish to incorporate parts of the Library
+ into other free programs whose distribution conditions are incompatible
+ with these, write to the author to ask for permission. For software
+ which is copyrighted by the Free Software Foundation, write to the Free
+ Software Foundation; we sometimes make exceptions for this. Our
+ decision will be guided by the two goals of preserving the free status
+ of all derivatives of our free software and of promoting the sharing
+ and reuse of software generally.</P>
+<P><STRONG>NO WARRANTY</STRONG></P>
+<P><STRONG>15.</STRONG> BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE,
+ THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY &quot;AS IS&quot; WITHOUT
+ WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
+ OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU
+ ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</P>
+<P><STRONG>16.</STRONG> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
+ AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO
+ MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.</P>
+<H4>END OF TERMS AND CONDITIONS</H4>
+<H1 ALIGN="RIGHT"><A NAME="COMMON_NETWORK">B - Common Network Settings</A>
+</H1>
+<P>This appendix covers many of the popular TCP/IP network interfaces
+ and printer servers available on the market today.</P>
+<H2><A NAME="10_1">Configuring a Network Interface</A></H2>
+<P>When you first install a network printer or print server on your LAN,
+ you need to set the Internet Protocol (&quot;IP&quot;) address. On most
+ higher-end &quot;workgroup&quot; printers, you can set the address through the
+ printer control panel. However, in most cases you will want to assign
+ the addresses remotely from your workstation. This makes administration
+ a bit easier and avoids assigning duplicate addresses accidentally.</P>
+<P>To setup your printer or print server for remote address assignment,
+ you'll need the Ethernet Media Access Control (&quot;MAC&quot;) address, also
+ sometimes called a node address, and the IP address you want to use for
+ the device. The Ethernet MAC address can often be found on the printer
+ test page or bottom of the print server.
+<!-- NEED 3in -->
+</P>
+<H3><A NAME="10_1_1">Configuring the IP Address Using ARP</A></H3>
+<P>The easiest way to set the IP address of a network device is to use
+ the <CODE>arp(8)</CODE> command. The <CODE>arp</CODE> sends an Address
+ Resolution Protocol (&quot;ARP&quot;) packet to the specified Ethernet MAC
+ address, setting the network device's IP address:</P>
+<UL>
+<PRE>
+<B>arp -s ip-address ethernet-address ENTER</B>
+<B>arp -s host.domain.com 08:00:69:00:12:34 ENTER</B>
+<B>arp -s 192.0.2.2 08:00:69:00:12:34 ENTER</B>
+</PRE>
+</UL>
+<H3><A NAME="10_1_2">Configuring the IP Address Using RARP</A></H3>
+<P>The most flexible way to remotely assign IP addresses under UNIX is
+ through the Reverse Address Resolution Protocol (&quot;RARP&quot;). RARP allows a
+ network device to request an IP address using its Ethernet MAC address,
+ and one or more RARP servers on the network will respond with an ARP
+ packet with the IP address the device can use.</P>
+<P>RARP should be used when you have to manage many printers or print
+ servers, or when you have a network device that does not remember its
+ IP address after a power cycle. If you just have a single printer or
+ print server, the <CODE>arp</CODE> command is the way to go.</P>
+<P>Some UNIX operating systems use a program called <CODE>rarpd(8)</CODE>
+ to manage RARP. Others, like Linux, support this protocol in the
+ kernel. For systems that provide the <CODE>rarpd</CODE> program you
+ will need to start it before RARP lookups will work:</P>
+<UL>
+<PRE>
+<B>rarpd ENTER</B>
+</PRE>
+</UL>
+<P>Under IRIX you can enable this functionality by default using:</P>
+<UL>
+<PRE>
+<B>chkconfig rarpd on ENTER</B>
+</PRE>
+</UL>
+<P>Both the <CODE>rarpd</CODE> program and kernel RARP support read a
+ list of Ethernet and IP addresses from the file<VAR> /etc/ethers</VAR>.
+ Each line contains the Ethernet address (colon delimited) followed by
+ an IP address or hostname like:</P>
+<UL>
+<PRE>
+08:00:69:00:12:34 myprinter.mydomain.com
+08:00:69:00:12:34 192.0.2.2
+</PRE>
+</UL>
+<P>Add a line to this file and cycle the power on the printer or print
+ server to set its address.
+<!-- NEED 2in -->
+</P>
+<H3><A NAME="10_1_3">Configuring the IP Address Using BOOTP</A></H3>
+<P>The BOOTP protocol is used when you need to provide additional
+ information such as the location of a configuration file to the network
+ interface. Using the standard <CODE>bootpd(8)</CODE> program supplied
+ with UNIX you simply need to add a line to the<VAR> /etc/bootptab</VAR>
+ file; for IRIX:</P>
+<UL>
+<PRE>
+myprinter 08:00:69:00:12:34 192.0.2.2 <VAR>myprinter.boot</VAR>
+</PRE>
+</UL>
+
+<!-- NEED 1in -->
+<P>Newer versions of <CODE>bootpd</CODE> use a different format:</P>
+<UL>
+<PRE>
+myprinter:ha=080069001234:ip=192.0.2.2:<VAR>t144=myprinter.boot</VAR>
+</PRE>
+</UL>
+<P>The<VAR> myprinter.boot</VAR> file resides in the<VAR>
+ /usr/local/boot</VAR> directory by default. If you do not need to
+ provide a boot file you may leave the last part of the line blank.</P>
+
+<!-- NEED 2in -->
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Some versions of UNIX do not enable the BOOTP service by default. The<VAR>
+ /etc/inetd.conf</VAR> usually contains a line for the BOOTP service
+ that can be uncommented if needed.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H2><A NAME="10_2">Verifying the Printer Connection</A></H2>
+<P>To test that the IP address has been successfully assigned and that
+ the printer is properly connected to your LAN, type:</P>
+<UL>
+<PRE>
+<B>ping ip-address ENTER</B>
+</PRE>
+</UL>
+<P>If the connection is working properly you will see something like:</P>
+<UL>
+<PRE>
+<B>ping myprinter ENTER</B>
+PING myprinter (192.0.2.2): 56 data bytes
+64 bytes from 192.0.2.2: icmp_seq=0 ttl=15 time=5 ms
+64 bytes from 192.0.2.2: icmp_seq=1 ttl=15 time=3 ms
+64 bytes from 192.0.2.2: icmp_seq=2 ttl=15 time=3 ms
+64 bytes from 192.0.2.2: icmp_seq=3 ttl=15 time=3 ms
+</PRE>
+</UL>
+<P>If not, verify that the printer or print server is connected to the
+ LAN, it is powered on, the LAN cabling is good, and the IP address is
+ set correctly. You can usually see the current IP address and network
+ status by printing a configuration or test page on the device.
+<!-- NEED 4in -->
+</P>
+<H2><A NAME="10_3">Common Network Interface Settings</A></H2>
+<P>Once you have set the IP address you can access the printer or print
+ server using the <CODE>ipp</CODE>, <CODE>lpd</CODE>, or <CODE>socket</CODE>
+ backends. The following is a list of common network interfaces and
+ printer servers and the settings you should use with CUPS:
+<CENTER>
+<TABLE BORDER="1">
+<TR ALIGN="LEFT" VALIGN="TOP"><TH>Model/Manufacturer</TH><TH>Device
+ URI(s)</TH></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Apple LaserWriter</TD><TD>lpd://<I>
+address</I>/PASSTHRU</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Axis w/o IPP
+<BR><A HREF="#AXIS"> (see directions)</A></TD><TD>socket://<I>address</I>
+:9100
+<BR> socket://<I>address</I>:9101
+<BR> socket://<I>address</I>:9102</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Axis w/IPP</TD><TD>ipp://<I>address</I>
+/LPT1
+<BR> ipp://<I>address</I>/LPT2
+<BR> ipp://<I>address</I>/COM1</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Castelle LANpress<SUP>TM</SUP></TD><TD>
+lpd://<I>address</I>/pr1
+<BR> lpd://<I>address</I>/pr2
+<BR> lpd://<I>address</I>/pr3</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>DPI NETPrint</TD><TD>lpd://<I>address</I>
+/pr1
+<BR> lpd://<I>address</I>/pr2
+<BR> lpd://<I>address</I>/pr3</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>EFI&reg; Fiery&reg; RIP</TD><TD>lpd://<I>
+address</I>/print</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>EPSON&reg; Multiprotocol Ethernet
+ Interface Board</TD><TD>socket://<I>address</I></TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Extended System ExtendNET</TD><TD>
+lpd://<I>address</I>/pr1
+<BR> lpd://<I>address</I>/pr2
+<BR> lpd://<I>address</I>/pr3</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Hewlett Packard JetDirect w/o IPP</TD><TD>
+socket://<I>address</I>:9100
+<BR> socket://<I>address</I>:9101
+<BR> socket://<I>address</I>:9102</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Hewlett Packard JetDirect w/IPP</TD><TD>
+ipp://<I>address</I>/ipp
+<BR> ipp://<I>address</I>/ipp/port1
+<BR> ipp://<I>address</I>/ipp/port2
+<BR> ipp://<I>address</I>/ipp/port3</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Intel&reg; NetportExpress XL, PRO/100</TD><TD>
+lpd://<I>address</I>/LPT1_PASSTHRU
+<BR> lpd://<I>address</I>/LPT2_PASSTHRU
+<BR> lpd://<I>address</I>/COM1_PASSTHRU</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Lexmark<SUP>TM</SUP> MarkNet</TD><TD>
+lpd://<I>address</I>/ps</TD></TR>
+
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Linksys EtherFast&reg;
+<BR><A HREF="#LINKSYS"> (see directions)</A></TD><TD>socket://<I>address</I>
+:4010
+<BR> socket://<I>address</I>:4020
+<BR> socket://<I>address</I>:4030</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Kodak&reg;</TD><TD>lpd://<I>address</I>/ps</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>QMS&reg; CrownNet<SUP>TM</SUP></TD><TD>
+lpd://<I>address</I>/ps</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>Tektronix&reg; PhaserShare<SUP>TM</SUP></TD><TD>
+socket://<I>address</I>:9100</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>XEROX&reg; 4512 NIC</TD><TD>lpd://<I>
+address</I>/PORT1</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>XEROX&reg; XNIC</TD><TD>lpd://<I>address</I>
+/PASSTHRU</TD></TR>
+<TR ALIGN="LEFT" VALIGN="TOP"><TD>XEROX&reg; (most others)</TD><TD>socket://<I>
+address</I>:5503</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H2><A NAME="AXIS">Configuring Axis Print Servers</A></H2>
+<P>The Axis print servers can be configured using ARP, RARP, or BOOTP.
+ However, on models that do not provide IPP support an additional step
+ must be performed to configure the TCP/IP portion of the print server
+ for use with CUPS.
+<!-- NEED 3in -->
+</P>
+<P>Each print server contains a configuration file named<VAR> config</VAR>
+ that contains a list of network parameters used by the server. To
+ modify this file you must first download it from the print server using
+ the <CODE>ftp(1)</CODE> program:</P>
+<UL>
+<PRE>
+<B>ftp ip-address ENTER</B>
+Connected to ip-address.
+220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
+ftp&gt; <B>user root ENTER</B>
+331 User name ok, need password
+Password: <B>pass ENTER</B> <I>(this is not echoed)</I>
+230 User logged in
+ftp&gt; <B>get config ENTER</B>
+local: config remote: config
+200 PORT command successful.
+150 Opening data connection for config (192,0,2,2),
+(mode ascii).
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp&gt; <B>quit ENTER</B>
+221 Goodbye.
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<P>Next, edit the file with your favorite text editor and locate the
+ lines beginning with:</P>
+<UL>
+<PRE>
+RTN_OPT. : YES
+RTEL_PR1. : 0
+RTEL_PR2. : 0
+RTEL_PR3. : 0
+RTEL_PR4. : 0
+RTEL_PR5. : 0
+RTEL_PR6. : 0
+RTEL_PR7. : 0
+RTEL_PR8. : 0
+</PRE>
+</UL>
+
+<!-- NEED 1in -->
+ Change the <CODE>RTN_OPT</CODE> line to read:
+<UL>
+<PRE>
+RTN_OPT. : <B>NO</B>
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<P>This disables the Reverse TELNET protocol and enables the standard
+ TELNET protocol on the print server. Next, assign a port number for
+ each parallel and serial port on the server as follows:</P>
+<UL>
+<PRE>
+RTEL_PR1. : <B>9100</B>
+RTEL_PR2. : <B>9101</B>
+RTEL_PR3. : <B>9102</B>
+RTEL_PR4. : <B>9103</B>
+RTEL_PR5. : <B>9104</B>
+RTEL_PR6. : <B>9105</B>
+RTEL_PR7. : <B>9106</B>
+RTEL_PR8. : <B>9107</B>
+</PRE>
+</UL>
+
+<!-- NEED 4in -->
+<P>This essentially makes the Axis print server look like a Hewlett
+ Packard JetDirect EX print server. Save the file and then upload the
+ new<VAR> config</VAR> file using the <CODE>ftp</CODE> command:</P>
+<UL>
+<PRE>
+<B>ftp ip-address ENTER</B>
+Connected to ip-address.
+220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
+ftp&gt; <B>user root ENTER</B>
+331 User name ok, need password
+Password: <B>pass ENTER</B> <I>(this is not echoed)</I>
+230 User logged in
+ftp&gt; <B>put config CONFIG ENTER</B>
+local: config remote: CONFIG
+200 PORT command successful.
+150 Opening data connection for config (192,0,2,2), (mode ascii).
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp&gt; <B>get hardreset ENTER</B>
+local: hardreset remote: hardreset
+200 PORT command successful.
+421 Axis NPS ### hard reset, closing connection.
+ftp&gt; <B>quit ENTER</B>
+221 Goodbye.
+</PRE>
+</UL>
+<P>Your Axis print server is now ready for use!</P>
+<H2><A NAME="LINKSYS">Configuring Linksys Print Servers</A></H2>
+<P>The Linksys print servers can be configured using ARP, RARP, or
+ BOOTP. Like older Axis print servers, an additional step must be
+ performed to configure the TCP/IP portion of the print server for use
+ with CUPS.
+<!-- NEED 3in -->
+</P>
+<P>Each print server contains a configuration file named<VAR> CONFIG</VAR>
+ that contains a list of network parameters used by the server. To
+ modify this file you must first download it from the print server using
+ the <CODE>ftp(1)</CODE> program:</P>
+<UL>
+<PRE>
+<B>ftp -n ip-address ENTER</B>
+Connected to ip-address.
+220 Print Server Ready.
+Remote system type is Print.
+ftp&gt; <B>get CONFIG ENTER</B>
+local: CONFIG remote: CONFIG
+200 Command OK.
+150 Open ASCII Mode Connection.
+WARNING! 68 bare linefeeds received in ASCII mode
+File may not have transferred correctly.
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp&gt; <B>quit ENTER</B>
+221 Goodbye.
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<P>Next, edit the file with your favorite text editor and locate the
+ lines beginning with:</P>
+<UL>
+<PRE>
+0100 L1_PROUT:P1
+0120 L2_PROUT:P1
+0140 L3_PROUT:P1
+</PRE>
+</UL>
+<P>Change the port number for each parallel and serial port on the
+ server as follows:</P>
+<UL>
+<PRE>
+0100 L1_PROUT:<B>P1</B>
+0120 L2_PROUT:<B>P2</B>
+0140 L3_PROUT:<B>P3</B>
+</PRE>
+</UL>
+
+<!-- NEED 4in -->
+<P>This maps each virtual printer with a physical port. Save the file
+ and then upload the new<VAR> CONFIG</VAR> file using the <CODE>ftp</CODE>
+ command:</P>
+<UL>
+<PRE>
+<B>ftp -n ip-address ENTER</B>
+Connected to ip-address.
+220 Print Server Ready.
+Remote system type is Print.
+ftp&gt; <B>put CONFIG ENTER</B>
+local: CONFIG remote: CONFIG
+200 Command OK.
+150 Open ASCII Mode Connection.
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp&gt; <B>quit ENTER</B>
+221 Goodbye.
+</PRE>
+</UL>
+<P>Your Linksys print server is now ready for use!</P>
+<H1 ALIGN="RIGHT"><A NAME="PRINTER_DRIVERS">C - Printer Drivers</A></H1>
+<P>This appendix lists the printer drivers that are provided with CUPS.</P>
+<H2><A NAME="11_1">Printer Drivers</A></H2>
+<P>CUPS includes the following printer drivers:</P>
+<UL>
+<LI><A HREF="#EPSON9">EPSON 9-pin Dot Matrix</A>,<VAR> epson9.ppd</VAR></LI>
+<LI><A HREF="#EPSON24">EPSON 24-pin Dot Matrix</A>,<VAR> epson24.ppd</VAR>
+</LI>
+<LI><A HREF="#STCOLOR">EPSON Stylus Color</A>,<VAR> stcolor.ppd</VAR></LI>
+<LI><A HREF="#STPHOTO">EPSON Stylus Photo</A>,<VAR> stphoto.ppd</VAR></LI>
+<LI><A HREF="#DESKJET">HP DeskJet</A>,<VAR> deskjet.ppd</VAR></LI>
+<LI><A HREF="#LASERJET">HP LaserJet</A>,<VAR> laserjet.ppd</VAR></LI>
+</UL>
+<H2><A NAME="EPSON9">EPSON 9-pin Dot Matrix</A></H2>
+<P>The EPSON 9-pin Dot Matrix driver (<VAR>epson9.ppd</VAR>) supports
+ 9-pin dot matrix printers that implement the ESC/P command set. It
+ provides 60x72, 120x72, and 240x72 DPI output in black only.</P>
+<H2><A NAME="EPSON24">EPSON 24-pin Dot Matrix</A></H2>
+<P>The EPSON 24-pin Dot Matrix driver (<VAR>epson9.ppd</VAR>) supports
+ 24-pin dot matrix printers that implement the ESC/P command set. It
+ provides 120x180, 180x180, 360x180, and 360x360 DPI output in black
+ only.</P>
+<H2><A NAME="STCOLOR">EPSON Stylus Color</A></H2>
+<P>The EPSON Stylus Color driver (<VAR>stcolor.ppd</VAR>) supports EPSON
+ Stylus Color printers that implement the ESC/P2 command set. It
+ provides 180, 360, and 720 DPI output in black and color (CMYK).</P>
+<H2><A NAME="STPHOTO">EPSON Stylus Photo</A></H2>
+<P>The EPSON Stylus Photo driver (<VAR>stphoto.ppd</VAR>) supports EPSON
+ Stylus Photo printers that implement the ESC/P2 command set. It
+ provides 180, 360, and 720 DPI output in black and color (CMYKcm).</P>
+<H2><A NAME="DESKJET">HP DeskJet</A></H2>
+<P>The HP DeskJet driver (<VAR>deskjet.ppd</VAR>) supports HP DeskJet
+ printers that implement the PCL command set. It provides 150, 300, and
+ 600 DPI output in black and color (CMYK).</P>
+<P>The DeskJet printers that implement the HP-PPA command set (720C,
+ 722C, 820C, and 1100C) are<B> not</B> supported due to a complete lack
+ of documentation and support from Hewlett Packard.</P>
+<P>The duplexer provided with the HP DeskJet 900 series printers is also
+ not supported for similar reasons.</P>
+<H2><A NAME="LASERJET">HP LaserJet</A></H2>
+<P>The HP LaserJet driver (<VAR>laserjet.ppd</VAR>) supports HP LaserJet
+ printers that implement the PCL command set. It provides 150, 300, and
+ 600 DPI output in black only and supports the duplexer if installed.</P>
+<P>LaserJet printers that do not implement PCL (3100, 3150) are not
+ supported due to a complete lack of documentation and support from
+ Hewlett Packard.</P>
+<H1 ALIGN="RIGHT"><A NAME="FILES">D - List of Files</A></H1>
+<P>This appendix lists the files and directories that are installed for
+ the Common UNIX Printing System.
+<CENTER>
+<TABLE BORDER="1" WIDTH="80%">
+<TR VALIGN="TOP"><TH>Pathname</TH><TH>Description</TH></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/certs/</TD><TD>The location of
+ authentication certificate files for local HTTP clients.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/classes.conf</TD><TD>The printer classes
+ configuration file for the scheduler.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/cupsd.conf</TD><TD>The scheduler
+ configuration file.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/interfaces/</TD><TD>The location of
+ System V interface scripts for printers.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/mime.convs</TD><TD>The list of standard
+ file filters included with CUPS.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/mime.types</TD><TD>The list of recognized
+ file types for CUPS.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/ppd/</TD><TD>The location of PostScript
+ Printer Description (&quot;PPD&quot;) files for printers.</TD></TR>
+<TR VALIGN="TOP"><TD>/etc/cups/printers.conf</TD><TD>The printer
+ configuration file for the scheduler.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/cancel</TD><TD>The System V cancel job(s)
+ command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/disable</TD><TD>The System V disable
+ printer command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/enable</TD><TD>The System V enable printer
+ command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lp</TD><TD>The System V print command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lpoptions</TD><TD>Sets user-defined
+ printing options and defaults.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lppasswd</TD><TD>Adds, changes, or removes
+ Digest password accounts.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lpq</TD><TD>The Berkeley status command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lpr</TD><TD>The Berkeley print command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lprm</TD><TD>The Berkeley cancel job(s)
+ command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/bin/lpstat</TD><TD>The System V status
+ command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/include/cups/</TD><TD>CUPS API header files.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/lib32/libcups.a
+<BR> /usr/lib32/libcupsimage.a</TD><TD>Static libraries (IRIX 6.5)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/libcups.a
+<BR> /usr/lib/libcupsimage.a</TD><TD>Static libraries (all others)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/libcups.sl.2
+<BR> /usr/lib/libcupsimage.sl.2</TD><TD>Shared libraries (HP-UX)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib32/libcups.so.2
+<BR> /usr/lib32/libcupsimage.so.2</TD><TD>Shared libraries (IRIX 6.5)</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/lib/libcups.so.2
+<BR> /usr/lib/libcupsimage.so.2</TD><TD>Shared libraries (all others)</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/lib/cups/backend/</TD><TD>Backends for various
+ types of printer connections.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/cups/cgi-bin/</TD><TD>CGI programs for the
+ scheduler.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/cups/daemon/</TD><TD>Daemons for polling
+ and LPD support.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/cups/filter/</TD><TD>Filters for various
+ types of files.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/locale/</TD><TD>The location of
+ language-specific message files. (System V)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/lib/nls/msg/</TD><TD>The location of
+ language-specific message files. (Compaq Tru64 UNIX)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/locale/</TD><TD>The location of
+ language-specific message files. (Linux, *BSD)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/accept</TD><TD>The accept-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/cupsd</TD><TD>The CUPS print scheduler.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/lpadmin</TD><TD>The System V printer
+ administration tool.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/lpc</TD><TD>The Berkeley printer
+ administration tool.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/lpinfo</TD><TD>The get-devices and
+ get-ppds command.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/lpmove</TD><TD>The move-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/sbin/reject</TD><TD>The reject-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP"><TD>/usr/share/catman/a_man/
+<BR> /usr/share/catman/u_man/</TD><TD>Man pages (IRIX)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/man/</TD><TD>Man pages (Compaq Tru64
+ UNIX, HP-UX, Solaris)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/man/</TD><TD>Man pages (all others)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/data/</TD><TD>The location of
+ filter data files.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/data/testprint.ps</TD><TD>The
+ PostScript test page file.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/fonts/</TD><TD>The location of
+ PostScript fonts for the PostScript RIP.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/model/</TD><TD>The location of
+ PostScript Printer Description (&quot;PPD&quot;) files and interface scripts that
+ may be used to setup a printer queue.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/pstoraster/</TD><TD>Other
+ PostScript RIP initialization files.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/pstoraster/Fontmap</TD><TD>The font
+ mapping file (converts filenames to fontnames)</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/cups/templates/</TD><TD>The location of
+ HTML template files for the web interfaces.</TD></TR>
+<TR VALIGN="TOP"><TD>/usr/share/doc/cups/</TD><TD>Documentation and web
+ page data for the scheduler.</TD></TR>
+<TR VALIGN="TOP"><TD>/var/log/cups/</TD><TD>The location of scheduler
+ log files.</TD></TR>
+<TR VALIGN="TOP"><TD>/var/spool/cups/</TD><TD>The location of print
+ files waiting to be printed.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H1 ALIGN="RIGHT"><A NAME="FAQ">E - Troubleshooting Common Problems</A></H1>
+<P>This appendix covers some of the common problems first-time users
+ encounter when installing and configuring CUPS.</P>
+<P>Commercial support for CUPS is available from Easy Software Products.
+ For more information please contact us at:</P>
+<UL>
+<LI>WWW:<A HREF="http://www.easysw.com"> <CODE>http://www.easysw.com</CODE>
+</A></LI>
+<LI>EMail:<A HREF="mailto:info@easysw.com"> info@easysw.com</A></LI>
+<LI>Telephone (M-F, 9-5 EST): +1.301.373.9600</LI>
+</UL>
+<H2><A NAME="13_1">My Applications Don't See the Available Printers</A></H2>
+<P>Many applications read the<VAR> /etc/printcap</VAR> file to get a
+ list of available printers.</P>
+<P>The default CUPS configuration creates the<VAR> /etc/printcap</VAR>
+ file automatically. To enable or disable automatic creation and
+ updating of this file, use the<A HREF="#Printcap"> <CODE>Printcap</CODE>
+</A> directive described in<A HREF="#PRINTING_MANAGEMENT"> Chapter 6,
+ &quot;Printing System Management&quot;</A>.</P>
+<H2><A NAME="13_2">CUPS Doesn't Recognize My Username or Password!</A></H2>
+<P>CUPS will ask you for a UNIX username and password when you perform
+ printer administration tasks remotely or via a web browser. The default
+ configuration requires that you use the <CODE>root</CODE> username and
+ the corresponding password to authenticate the request.</P>
+<P>CUPS does not allow you to authenticate an administration request
+ with an account that has no password for security reasons. If you do
+ not have a password on your <CODE>root</CODE> account then you won't be
+ able to add printers remotely or via the web interface!
+<!-- NEED 2in -->
+</P>
+<P>To disable password authentication you need to edit the<VAR>
+ /etc/cups/cupsd.conf</VAR> file and comment out the lines reading:</P>
+<UL>
+<PRE>
+AuthType Basic
+AuthClass System
+</PRE>
+</UL>
+<P>for the<VAR> /admin</VAR> location. Then restart the CUPS server as
+ described in<A HREF="#PRINTING_MANAGEMENT"> Chapter 6, &quot;Printing System
+ Management&quot;</A>.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Disabling password checks will allow any local user to change your
+ printer and class configuration, but remote administration from another
+ machine will still not be allowed.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+<H2><A NAME="ALLOW_REMOTE">I Can't Do Administration Tasks from Another
+ Machine!</A></H2>
+<P>The default CUPS configuration limits administration to the local
+ machine. To open up access, edit the<VAR> /etc/cups/cupsd.conf</VAR>
+ and comment out the lines reading:</P>
+<UL>
+<PRE>
+Order deny,allow
+Deny from all
+Allow from 127.0.0.1
+</PRE>
+</UL>
+<P>for the<VAR> /admin</VAR> location. Then restart the CUPS server as
+ described in<A HREF="#PRINTING_MANAGEMENT"> Chapter 6, &quot;Printing System
+ Management&quot;</A>.</P>
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>Allowing administration access from all hosts is a potential security
+ risk. Please read<A HREF="#PRINTING_SECURITY"> Chapter 6, &quot;Printing
+ System Management&quot;</A> for a description of these risks and ways to
+ minimize them.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 4in -->
+<H2><A NAME="13_4">I Can't Do Administration Tasks from My Web Browser!</A>
+</H2>
+<P>This problem is usually caused by:</P>
+<OL>
+<LI>not specifying the correct password for the root account.</LI>
+<LI>accessing the CUPS server using the hostname or IP address of the
+ server without enabling remote access for administration functions.
+ This can be corrected by following the instructions in the<A HREF="#ALLOW_REMOTE">
+ &quot;I Can't Do Administration Tasks from Another Machine!&quot;</A> section
+ earlier in this appendix.</LI>
+<LI>not setting a password on the root account. CUPS will not
+ authenticate a user account that does not have a password for security
+ reasons.</LI>
+<LI>authenticating using an account other than root, but the account you
+ are using is not a member of the system group.</LI>
+<LI>configuring CUPS to use Digest authentication, but your web browser
+ does not support Digest authentication.</LI>
+</OL>
+<H2><A NAME="13_5">Connection Refused Messages</A></H2>
+<P>Under normal circumstances, &quot;connection refused&quot; messages for a
+ networked printer should be expected from time to time. Most network
+ interfaces only allow a single connection to be made at any given time
+ (one job at a time) and will refuse access to all other systems while
+ the first connection is active. CUPS automatically retries the
+ connection once every 30 seconds.</P>
+<P>If the problem persists and you are unable to print any jobs to the
+ printer, verify that another machine is not maintaining a connection
+ with the printer, and that you have selected the proper port or printer
+ name for the printer.</P>
+<P>Also, most external print servers will refuse connections if the
+ connected printer is turned off or is off-line. Verify that the
+ affected printer is turned on and is online.</P>
+<H2><A NAME="13_6">Write Error Messages</A></H2>
+<P>If you get &quot;write error&quot; messages on a printer queue the printer
+ interface (usually a Hewlett Packard JetDirect interface) has timed out
+ and reset the network connection from your workstation.</P>
+<P>The error is caused by that startup delay between the initial setup
+ of the printer or plotter and the first page of print data that is
+ sent.
+<!-- NEED 3in -->
+</P>
+<P>To correct the problem, change the idle timeout on the interface to
+ at least 180 seconds or 3 minutes. To change the timeout on a Hewlett
+ Packard JetDirect interface, type:</P>
+<UL>
+<PRE>
+<B>telnet ip-address ENTER</B>
+
+Trying ip-address...
+Connected to ip-address.
+Escape character is `^]'.
+
+Please type [Return] two times, to initialize telnet configuration
+For HELP type &quot;?&quot;
+&gt; <B>idle-timeout: 180 ENTER</B>
+&gt; <B>quit ENTER</B>
+</PRE>
+</UL>
+</BODY>
+</HTML>
diff --git a/doc/sam.pdf b/doc/sam.pdf
new file mode 100644
index 000000000..25f3632d3
--- /dev/null
+++ b/doc/sam.pdf
Binary files differ
diff --git a/doc/sam.shtml b/doc/sam.shtml
new file mode 100644
index 000000000..1ca5b49b6
--- /dev/null
+++ b/doc/sam.shtml
@@ -0,0 +1,5048 @@
+<HTML>
+<HEAD>
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-SAM-1.1.16">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Software Administrators Manual</TITLE>
+</HEAD>
+<BODY>
+
+<H1 ALIGN="RIGHT">Preface</H1>
+
+<P>This software administrators manual provides printer administration
+information for the Common UNIX Printing System<SUP>TM</SUP>
+("CUPS<SUP>TM</SUP>"), version 1.1.16.
+
+<EMBED SRC="system-overview.shtml">
+
+<!-- NEED 3in -->
+<H2>Document Overview</H2>
+
+<P>This software administrators manual is organized into the following sections:</P>
+
+<UL>
+ <LI><A HREF="#OVERVIEW">1 - Printing System Overview</A>
+ <LI><A HREF="#BUILDING_INSTALLING">2 - Building and Installing CUPS</A>
+ <LI><A HREF="#MANAGING_PRINTERS">3 - Managing Printers</A>
+ <LI><A HREF="#PRINTER_CLASSES">4 - Printer Classes</A>
+ <LI><A HREF="#CLIENT_SETUP">5 - Client Setup</A>
+ <LI><A HREF="#PRINTING_MANAGEMENT">6 - Printing System Management</A>
+ <LI><A HREF="#PRINTING_OTHER">7 - Printing with Other Systems</A>
+ <LI><A HREF="#LICENSE">A - Software License Agreement</A>
+ <LI><A HREF="#COMMON_NETWORK">B - Common Network Settings</A>
+ <LI><A HREF="#PRINTER_DRIVERS">C - Printer Drivers</A>
+ <LI><A HREF="#FILES">D - List of Files</A>
+ <LI><A HREF="#FAQ">E - Troubleshooting Common Problems</A>
+</UL>
+
+<H2>Notation Conventions</H2>
+
+<P>Various font and syntax conventions are used in this guide. Examples and
+their meanings and uses are explained below:
+
+<CENTER><TABLE WIDTH="80%">
+<TR>
+ <TH>Example</TH>
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+ <TH>Description</TH>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD><CODE>lpstat</CODE><BR>
+ <CODE>lpstat(1)</CODE></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>The names of commands; the first mention of a command or
+ function in a chapter is followed by a manual page section
+ number.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD><VAR>/var</VAR><BR>
+ <VAR>/usr/share/cups/data/testprint.ps</VAR></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>File and directory names.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD NOWRAP><TT>Request ID is Printer-123</TT></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Screen output.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD NOWRAP><KBD>lp -d printer filename ENTER</KBD></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Literal user input; special keys like <KBD>ENTER</KBD> are
+ in ALL CAPS.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD>12.3</TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Numbers in the text are written using the period (.) to indicate
+ the decimal point.</TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H2>Abbreviations</H2>
+
+The following abbreviations are used throughout this manual:
+
+<UL>
+<DL>
+
+ <DT>kb
+ <DD>Kilobytes, or 1024 bytes<BR>&nbsp;
+
+ <DT>Mb
+ <DD>Megabytes, or 1048576 bytes<BR>&nbsp;
+
+ <DT>Gb
+ <DD>Gigabytes, or 1073741824 bytes<BR>&nbsp;
+
+</DL>
+</UL>
+
+<H2>Other References</H2>
+
+<UL>
+<DL>
+
+ <DT>CUPS Software Programmers Manual
+
+ <DD>A programmer guide for interfacing with and/or extending the CUPS
+ software.<BR>&nbsp;
+
+ <DT>CUPS Software Users Manual
+
+ <DD>An end-user guide for using the CUPS software.<BR>&nbsp;
+
+</DL>
+</UL>
+
+
+<EMBED SRC="printing-overview.shtml">
+
+
+<H1 ALIGN="RIGHT"><A NAME="BUILDING_INSTALLING">2 - Building and Installing CUPS</A></H1>
+
+<P>This chapter shows how to build and install the Common UNIX Printing System.
+If you are installing a binary distribution from the CUPS web site, proceed to
+the section titled, <A HREF="#BINARY">Installing a Binary Distribution</A>.
+
+<H2>Installing a Source Distribution</H2>
+
+<P>This section describes how to compile and install CUPS on your system
+from the source code.
+
+<H3><A NAME="REQUIREMENTS">Requirements</A></H3>
+
+<P>You'll need ANSI-compliant C and C++ compilers to build CUPS on your
+system. As its name implies, CUPS is designed to run on the UNIX
+operating system, however the CUPS interface library and most of the
+filters and backends supplied with CUPS should also compile and run
+under Microsoft Windows.
+
+<P>For the image file filters and PostScript RIP, you'll need the JPEG,
+PNG, TIFF, and ZLIB libraries. CUPS will build without these, but with
+significantly reduced functionality. Easy Software Products maintains a
+mirror of the current versions of these libraries at:
+
+<UL><PRE>
+<A HREF="ftp://ftp.easysw.com/pub/libraries">ftp://ftp.easysw.com/pub/libraries</A>
+</PRE></UL>
+
+<P>If you make changes to the man pages you'll need GNU groff or another
+nroff-like package. GNU groff is available from:
+
+<UL><PRE>
+<A HREF="ftp://ftp.gnu.org/pub/groff">ftp://ftp.gnu.org/pub/groff</A>
+</PRE></UL>
+
+<P>The documentation is formatted using the HTMLDOC software. If you need to
+make changes you can get the HTMLDOC software from:
+
+<UL><PRE>
+<A HREF="http://www.easysw.com/htmldoc">http://www.easysw.com/htmldoc</A>
+</PRE></UL>
+
+<P>Finally, you'll need a <CODE>make</CODE> program that
+understands the <CODE>include</CODE> directive - FreeBSD,
+NetBSD, and OpenBSD developers should use the <CODE>gmake</CODE>
+program.
+
+<H3><A NAME="COMPILING">Compiling CUPS</A></H3>
+
+<P>CUPS uses GNU autoconf to configure the makefiles and source code
+for your system. Type the following command to configure CUPS for your
+system:
+
+<UL><PRE>
+<B>./configure ENTER</B>
+</PRE></UL>
+
+<P>The default installation will put the CUPS software in the
+<VAR>/etc</VAR>, <VAR>/usr</VAR>, and <VAR>/var</VAR> directories on
+your system, which will overwrite any existing printing commands on
+your system. Use the <CODE>--prefix</CODE> option to install the CUPS
+software in another location:
+
+<UL><PRE>
+<B>./configure --prefix=/some/directory ENTER</B>
+</PRE></UL>
+
+<P>If the PNG, JPEG, TIFF, and ZLIB libraries are not installed in a
+system default location (typically <VAR>/usr/include</VAR> and
+<VAR>/usr/lib</VAR>) you'll need to set the <CODE>CFLAGS</CODE>,
+<CODE>CXXFLAGS</CODE>, and <CODE>LDFLAGS</CODE> environment variables
+prior to running configure:
+
+<UL><PRE>
+<B>setenv CFLAGS "-I/some/directory" ENTER</B>
+<B>setenv CXXFLAGS "-I/some/directory" ENTER</B>
+<B>setenv LDFLAGS "-L/some/directory" ENTER</B>
+<B>setenv DSOFLAGS "-L/some/directory" ENTER</B>
+<B>./configure ... ENTER</B>
+</PRE></UL>
+
+<P>or:
+
+<UL><PRE>
+<B>CFLAGS="-I/some/directory"; export CFLAGS ENTER</B>
+<B>CXXFLAGS="-I/some/directory"; export CXXFLAGS ENTER</B>
+<B>LDFLAGS="-L/some/directory"; export LDFLAGS ENTER</B>
+<B>DSOFLAGS="-L/some/directory"; export DSOFLAGS ENTER</B>
+<B>./configure ... ENTER</B>
+</PRE></UL>
+
+<P>To enable support for encryption, you'll also want to add the
+"--enable-ssl" option:
+
+<UL><PRE>
+./configure --enable-ssl
+</PRE></UL>
+
+<P>SSL and TLS support require the OpenSSL library, available at:
+
+<UL><PRE>
+<A HREF="http://www.openssl.org">http://www.openssl.org</A>
+</PRE></UL>
+
+<P>If the OpenSSL headers and libraries are not installed in the
+standard directories, use the <CODE>--with-openssl-includes</CODE>
+and <CODE>--with-openssl-libs</CODE> options:</P>
+
+<UL><PRE>
+./configure --enable-ssl \
+ --with-openssl-includes=/foo/bar/include \
+ --with-openssl-libs=/foo/bar/lib
+</PRE></UL>
+
+<P>Once you have configured things, just type:
+
+<UL><PRE>
+<B>make ENTER</B>
+</PRE></UL>
+
+<P>to build the software.
+
+<!-- NEED 4in -->
+<H3><A NAME="INSTALLING">Installing the Software</A></H3>
+
+<P>Use the "install" target to install the software:
+
+<UL><PRE>
+<B>make install ENTER</B>
+</PRE></UL>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" BGCOLOR="#cccccc" CELLPADDING="5">
+<TR>
+ <TD>
+ <B>WARNING:</B>
+
+ <P>Installing CUPS will overwrite your existing printing
+ system. If you experience difficulties with the CUPS software
+ and need to go back to your old printing system, you will need
+ to reinstall the old printing system from your operating system CDs.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H3><A NAME="RUNNING">Running the Software</A></H3>
+
+<P>Once you have installed the software you can start the CUPS server by
+typing:
+
+<UL><PRE>
+<B>/usr/sbin/cupsd ENTER</B>
+</PRE></UL>
+
+<!-- NEED 4in -->
+<H2><A NAME="BINARY">Installing a Binary Distribution</A></H2>
+
+<P>CUPS comes in a variety of binary distribution formats. Easy
+Software Products provides binaries in TAR format with installation and
+removal scripts ("portable" distributions), and in RPM and DPKG formats
+for Red Hat and Debian-based distributions. Portable distributions are
+available for all platforms, while the RPM and DPKG distributions are
+only available for Linux.
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" BGCOLOR="#cccccc" CELLPADDING="5">
+<TR>
+ <TD>
+ <B>WARNING:</B>
+
+ <P>Installing CUPS will overwrite your existing printing
+ system. If you experience difficulties with the CUPS software
+ and need to go back to your old printing system, you will need
+ to remove the CUPS software with the provided script and/or
+ reinstall the old printing system from your operating system CDs.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+
+<H3><A NAME="PORTABLE-BINARY">Installing a Portable Distribution</A></H3>
+
+<P>To install the CUPS software from a portable distribution you will
+need to be logged in as root; doing an <CODE>su</CODE> is good enough.
+Once you are the root user, run the installation script with:
+
+<UL><PRE>
+<B>./cups.install ENTER</B>
+</PRE></UL>
+
+<P>After asking you a few yes/no questions the CUPS software will be
+installed and the scheduler will be started automatically.
+
+<!-- NEED 2in -->
+<H3><A NAME="RPM-BINARY">Installing an RPM Distribution</A></H3>
+
+<P>To install the CUPS software from an RPM distribution you will need
+to be logged in as root; doing an <CODE>su</CODE> is good enough. Once
+you are the root user, run RPM with:
+
+<UL><PRE>
+<B>rpm -e lpr</B>
+<B>rpm -i cups-1.1-linux-M.m.n-intel.rpm ENTER</B>
+</PRE></UL>
+
+<P>After a short delay the CUPS software will be
+installed and the scheduler will be started automatically.
+
+<H3><A NAME="DPKG-BINARY">Installing an Debian Distribution</A></H3>
+
+<P>To install the CUPS software from a Debian distribution you will
+need to be logged in as root; doing an <CODE>su</CODE> is good enough.
+Once you are the root user, run dpkg with:
+
+<UL><PRE>
+<B>dpkg -i cups-1.1-linux-M.m.n-intel.deb ENTER</B>
+</PRE></UL>
+
+<P>After a short delay the CUPS software will be installed and the
+scheduler will be started automatically.
+
+
+<H1 ALIGN="RIGHT"><A NAME="MANAGING_PRINTERS">3 - Managing Printers</A></H1>
+
+<P>This chapter describes how to add your first printer and how to
+manage your printers.
+
+<H2>The Basics</H2>
+
+<P>Each printer queue has a name associated with it; the printer name
+must start with a letter and can contain up to 127 letters, numbers,
+and the underscore (_). Case is not significant, e.g. "PRINTER", "Printer",
+and "printer" are considered to be the same name.
+
+<P>Printer queues also have a device associated with them. The device can be
+a parallel port, a network interface, and so forth. Devices within CUPS use
+Uniform Resource Identifiers ("URIs") which are a more general form of
+Uniform Resource Locators ("URLs") that are used in your web browser. For
+example, the first parallel port in Linux usually uses a device URI of
+<CODE>parallel:/dev/lp1</CODE>.
+
+<!-- NEED 2.5in -->
+<P>You can see a complete list of supported devices by running the
+<CODE>lpinfo(8)</CODE> command:
+
+<UL><PRE>
+<B>lpinfo -v ENTER</B>
+network socket
+network http
+network ipp
+network lpd
+direct parallel:/dev/lp1
+serial serial:/dev/ttyS1?baud=115200
+serial serial:/dev/ttyS2?baud=115200
+direct usb:/dev/usb/lp0
+network smb
+</PRE></UL>
+
+<P>The <CODE>-v</CODE> option specifies that you want a list of available
+devices. The first word in each line is the type of device (direct, file,
+network, or serial) and is followed by the device URI or method name for
+that device. File devices have device URIs of the form
+<CODE>file:/directory/filename</CODE> while network devices use the more
+familiar <CODE>method://server</CODE> or <CODE>method://server/path</CODE>
+format.
+
+<P>Finally, printer queues usually have a PostScript Printer Description
+("PPD") file associated with them. PPD files describe the capabilities of
+each printer, the page sizes supported, etc., and are used for PostScript
+and non-PostScript printers. CUPS includes PPD files for HP LaserJet, HP
+DeskJet, EPSON 9-pin, EPSON 24-pin, and EPSON Stylus printers.
+
+<H2>Adding Your First Printer</H2>
+
+<P>CUPS provides two methods for adding printers: a command-line
+program called <CODE>lpadmin(8)</CODE> and a Web interface. The
+<CODE>lpadmin</CODE> command allows you to perform most printer
+administration tasks from the command-line and is located in
+<VAR>/usr/sbin</VAR>. The Web interface is located at:
+
+<UL><PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE></UL>
+
+<P>and steps you through printer configuration. If you don't like
+command-line interfaces, try the <A HREF="#ADD_WEB">Web interface</A> instead.
+
+<H3>Adding Your First Printer from the Command-Line</H3>
+
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> option to add a
+printer to CUPS:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -E -v <I>device</I> -m <I>ppd</I> ENTER</B>
+</PRE></UL>
+
+<P>For a HP DeskJet printer connected to the parallel port this would look
+like:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p DeskJet -E -v parallel:/dev/lp1 -m deskjet.ppd ENTER</B>
+</PRE></UL>
+
+<P>Similarly, a HP LaserJet printer using a JetDirect network interface at
+IP address 11.22.33.44 would be added with the command:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p LaserJet -E -v socket://11.22.33.44 -m laserjet.ppd ENTER</B>
+</PRE></UL>
+
+<P>As you can see, <CODE>deskjet.ppd</CODE> and <CODE>laserjet.ppd</CODE> are
+the PPD files for the HP DeskJet and HP LaserJet drivers included with CUPS.
+You'll find a complete list of PPD files and the printers they will work with
+in <A HREF="#PRINTER_DRIVERS">Appendix C, "Printer Drivers"</A>.
+
+
+<P>For a dot matrix printer connected to the serial port this would might look like:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p DotMatrix -E -v serial:/dev/ttyS0?baud=9600+size=8+parity=none+flow=soft deskjet.ppd ENTER</B>
+</PRE></UL>
+
+<P>Here you specify the serial port (e.g. S0,S1, d0, d1), baud rate
+(e.g. 9600, 19200, 38400, 115200, etc.), number of bits, parity, and flow control.
+If you do not need flow control, delete the "+flow=soft" portion.
+
+
+<H3><A NAME="ADD_WEB">Adding Your First Printer from the Web</A></H3>
+
+<P>The CUPS web server provides a user-friendly "wizard" interface for
+adding your printers. Rather than figuring out which device URI and PPD file
+to use, you can instead click on the appropriate listings and fill in some
+simple information. Enter the following URL in your web browser to begin:
+
+<UL><PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE></UL>
+
+<P>Click on the <VAR>Add Printer</VAR> button to add a printer.
+
+<H2>Managing Printers from the Command-Line</H2>
+
+<P>The <CODE>lpadmin</CODE> command enables you to perform most printer
+administration tasks from the command-line. You'll find <CODE>lpadmin</CODE>
+in the <VAR>/usr/sbin</VAR> directory.
+
+<H3>Adding and Modifying Printers</H3>
+
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> option
+to add or modify a printer:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> <I>options</I> ENTER</B>
+</PRE></UL>
+
+<P>The <I>options</I> arguments can be any of the following:
+
+<UL>
+<DL>
+
+ <DT>-c <I>class</I>
+
+ <DD>Adds the named printer to printer class <VAR>class</VAR>.
+ If the class does not exist then it is created.
+
+ <DT>-i <I>interface</I>
+
+ <DD>Copies the named <VAR>interface</VAR> script to the printer.
+ Interface scripts are used by System V printer drivers. Since
+ all filtering is disabled when using an interface script, scripts
+ generally should not be used unless there is no other driver for
+ a printer.
+
+ <DT>-m <I>model</I>
+
+ <DD>Specifies a standard printer driver which is usually a PPD
+ file. A list of all available models can be displayed using the
+ <CODE>lpinfo</CODE> command with the <CODE>-m</CODE> option. A
+ list of printer drivers included with CUPS can be found in
+ <A HREF="#PRINTER_DRIVERS">Appendix C, "Printer Drivers"</A>.
+
+ <DT>-r <I>class</I>
+
+ <DD>Removes the named printer from printer class <VAR>class</VAR>.
+ If the resulting class becomes empty then it is removed.
+
+ <DT>-v <I>device-uri</I>
+
+ <DD>Sets the device for communicating with the printer. If a
+ job is currently printing on the named printer then the job
+ will be restarted and sent to the new device.
+
+ <DT>-D <I>info</I>
+
+ <DD>Provides a textual description of the printer, e.g.
+ "John's Personal Printer".
+
+ <DT>-E
+
+ <DD>Enables the printer and accepts job. This option is
+ equivalent to running the <CODE>enable(1)</CODE> and
+ <CODE>accept(8)</CODE> commands on the printer.
+
+ <DT>-L <I>location</I>
+
+ <DD>Provides a textual location for the printer, e.g.
+ "Computer Lab 5".
+
+ <DT>-P <I>ppd-file</I>
+
+ <DD>Specifies a local PPD file for the printer driver.
+
+</DL>
+</UL>
+
+<H3>Deleting Printers</H3>
+
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-x</CODE> option
+to delete a printer:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -x <I>printer</I> ENTER</B>
+</PRE></UL>
+
+<H3>Setting the Default Printer</H3>
+
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-d</CODE> option
+to set a default printer:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -d <I>printer</I> ENTER</B>
+</PRE></UL>
+
+<P>The default printer can be overridden by the user using the
+<CODE>lpoptions(1)</CODE> command.
+
+<H3>Starting and Stopping Printers</H3>
+
+<P>The <CODE>enable</CODE> and <CODE>disable</CODE> commands start and stop
+printer queues, respectively:
+
+<UL><PRE>
+<B>/usr/bin/enable <I>printer</I> ENTER</B>
+<B>/usr/bin/disable <I>printer</I> ENTER</B>
+</PRE></UL>
+
+<P>Printers that are disabled may still accept jobs for printing, but won't
+actually print any files until they are restarted. This is useful if the
+printer malfunctions and you need time to correct the problem. Any queued
+jobs are printed after the printer is enabled (started).
+
+<H3>Accepting and Rejecting Print Jobs</H3>
+
+<P>The <CODE>accept</CODE> and <CODE>reject</CODE> commands accept and reject
+print jobs for the named printer, respectively:
+
+<UL><PRE>
+<B>/usr/sbin/accept <I>printer</I> ENTER</B>
+<B>/usr/sbin/reject <I>printer</I> ENTER</B>
+</PRE></UL>
+
+<P>As noted above, a printer can be stopped but accepting new print
+jobs. A printer can also be rejecting new print jobs while it finishes
+those that have been queued. This is useful for when you must perform
+maintenance on the printer and will not have it available to users for
+a long period of time.
+
+<H3>Setting Quotas on a Printer</H3>
+
+<P>CUPS supports page and size-based quotas for each printer.
+The quotas are tracked individually for each user, but a single set of
+limits applies to all users for a partiuclar printer. For example, you
+can limit every user to 5 pages per day on an expensive printer, but
+you cannot limit every user except Johnny.</P>
+
+<P>The <I>job-k-limit</I>, <I>job-page-limit</I>, and <I>job-quota-peiod</I>
+options determine whether and how quotas are enforced for a printer.
+The <I>job-quota-period</I> option determines the time interval for
+quota tracking. The interval is expressed in seconds, so a day is
+86,400, a week is 604,800 and a month is 2,592,000 seconds. The
+<I>job-k-limit</I> option specifies the job size limit in killobytes. The
+<I>job-page-limit</I> option specifies the number of pages limit.</P>
+
+<P>For quotas to be enforced, the period and at least one of the limits
+must be set to a non-zero value. The following options will enable
+quotas:</P>
+
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -o job-quota-period=604800 -o job-k-limit=1024 <I>ENTER</I></B>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -o job-quota-period=604800 -o job-page-limit=100 <I>ENTER</I></B>
+</PRE>
+</UL>
+
+<P>Or, you can combine all three options on the same line.</P>
+
+<H3>Restricting User Access to a Printer</H3>
+
+<P>The <CODE>-u</CODE> option of the <CODE>lpadmin</CODE> command controls which users can
+print to a printer. The default configuration allows all users to print
+to a printer:</P>
+
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u allow:all <I>ENTER</I></B>
+</PRE>
+</UL>
+
+<P>CUPS supports allow and deny lists so that you can specify a
+list of users who are allowed to print or not allowed to print. Along
+with your list of users, you can specify whether they are allowed or
+not allowed to use the printer:</P>
+
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u allow:peter,paul,mary <I>ENTER</I></B>
+</PRE>
+</UL>
+
+<P>This command allows peter, paul, and mary to print to the named
+printer, but all other users cannot print. The command:</P>
+
+<UL>
+<PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -u deny:peter,paul,mary <I>ENTER</I></B>
+</PRE>
+</UL>
+
+<P>has the opposite effect. All users except peter, paul, and mary will
+be able to print to the named printer.</P>
+
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR>
+ <TD><B>NOTE:</B>
+
+ <P>The <I>allow</I> and <I>deny</I> options are not cummulative. That
+ is, you must provide the complete list of users to allow or deny each
+ time.</P>
+
+ <P>Also, CUPS only maintains one list of users - the list can
+ allow or deny users from printing. If you specify an allow list and
+ then specify a deny list, the deny list will replace the allow list -
+ only one list is active at any time.</P>
+
+ </TD>
+</TR>
+</TABLE>
+</CENTER>
+
+<H2>Managing Printers from the Web</H2>
+
+<P>The Web interface is located at:
+
+<UL><PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE></UL>
+
+<P>From there you can perform all printer management tasks with a few
+simple mouse clicks.
+
+
+<H1 ALIGN="RIGHT"><A NAME="PRINTER_CLASSES">4 - Printer Classes</A></H1>
+
+<P>This chapter describes what printer classes are and how to manage them.
+
+<H2>The Basics</H2>
+
+<P>CUPS provides collections of printers called <I>printer classes</I>. Jobs
+sent to a class are forwarded to the first available printer in the class.
+Classes can themselves be members of other classes, so it is possible for
+you to define very large, distributed printer classes for high-availability
+printing.
+
+<P>CUPS also supports <I>implicit classes</I>. Implicit classes work just
+like printer classes, but they are created automatically based upon the
+available printers and classes on the network. This allows you to setup
+multiple print servers with identical printer configurations and have the
+client machines send their print jobs to the first available server. If
+one or more servers go down, the jobs are automatically redirected to the
+servers that are running, providing fail-safe printing.
+
+<H2>Managing Printer Classes from the Command-Line</H2>
+
+<P>Run the <CODE>lpadmin</CODE> command with the <CODE>-p</CODE> and <CODE>-c</CODE> options
+to add a printer to a class:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -c <I>class</I> ENTER</B>
+</PRE></UL>
+
+<P>The <I>class</I> is created automatically if it doesn't exist. To remove a
+printer from a class use the <CODE>-r</CODE> option:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -p <I>printer</I> -r <I>class</I> ENTER</B>
+</PRE></UL>
+
+<P>To remove the entire class just use the <CODE>-x</CODE> option:
+
+<UL><PRE>
+<B>/usr/sbin/lpadmin -x <I>class</I> ENTER</B>
+</PRE></UL>
+
+<H2>Managing Printer Classes from the Web Interface</H2>
+
+<P>The Web interface is located at:
+
+<UL><PRE>
+<A HREF="http://localhost:631/admin">http://localhost:631/admin</A>
+</PRE></UL>
+
+<P>The <VAR>Add Class</VAR> and <VAR>Modify Class</VAR> interfaces provide a
+list of available printers; click on the printers of interest to add them to
+the class.
+
+<H2>Implicit Classes</H2>
+
+<P>A noted earlier, implicit classes are created automatically from the
+available network printers and classes. To disable this functionality,
+set the <A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A>
+directive to <CODE>Off</CODE> in the <CODE>cupsd.conf</CODE> file. You
+will find more information on doing this in
+<A HREF="#PRINTING_MANAGEMENT">Chapter 6, "Printing System
+Management"</A>.
+
+
+<H1 ALIGN="RIGHT"><A NAME="CLIENT_SETUP">5 - Client Setup</A></H1>
+
+<P>This chapter discusses several ways to configure CUPS clients for
+printing.
+
+<H2>The Basics</H2>
+
+<P>A client is any machine that sends print jobs to another machine for
+final printing. Clients can also be servers if they communicate directly with
+any printers of their own.
+
+<P>CUPS supports several methods of configuring client machines:
+
+<UL>
+ <LI><A HREF="#CLIENT_MANUAL">Manual configuration of print queues.</A>
+ <LI><A HREF="#CLIENT_SERVER">Specifying a single server for printing.</A>
+ <LI><A HREF="#CLIENT_AUTO">Automatic configuration of print queues.</A>
+ <LI><A HREF="#CLIENT_POLL">Specifying multiple servers for printing.</A>
+ <LI><A HREF="#CLIENT_RELAY">Relaying printers to other clients.</A>
+</UL>
+
+<H3><A NAME="CLIENT_MANUAL">Manual Configuration of Print Queues</A></H3>
+
+<P>The most tedious method of configuring client machines is to configure
+each remote queue by hand using the <CODE>lpadmin</CODE> command:
+
+<UL><PRE>
+<B>lpadmin -p <I>printer</I> -E -v ipp://<I>server</I>/printers/<I>printer</I> ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>printer</CODE> name is the name of the printer on the server
+machine. The <CODE>server</CODE> name is the hostname or IP address of the
+server machine. Repeat the <CODE>lpadmin</CODE> command for each remote
+printer you wish to use.</P>
+
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+ <TR>
+ <TD><B> NOTE:</B>
+ <P>Manual configuration of print queues is not recommended for large
+ numbers of client machines because of the administration nightmare it
+ creates. For busy networks, consider subnetting groups of clients and
+ polling and relaying printer information instead.</P>
+ </TD>
+ </TR>
+</TABLE>
+</CENTER>
+
+<H3><A NAME="CLIENT_SERVER">Specifying a Single Server for Printing</A></H3>
+
+<P>CUPS can be configured to run without a local spooler and send all
+jobs to a single server. However, if that server goes down then all
+printing will be disabled. Use this configuration only as absolutely needed.
+
+<P>The default server is normally "localhost". To override the default
+server create a file named <VAR>/etc/cups/client.conf</VAR> and add
+a line reading:
+
+<UL><PRE>
+ServerName <I>server</I>
+</PRE></UL>
+
+<P>to the file. The <VAR>server</VAR> name can be the hostname or IP address
+of the default server.
+
+<P>The default server can also be customized on a per-user basis. To set a
+user-specific server create a file named <VAR>~/.cupsrc</VAR> and add a line
+reading:
+
+<UL><PRE>
+ServerName <I>server</I>
+</PRE></UL>
+
+<P>to the file. The <VAR>server</VAR> name can be the hostname or IP
+address of the default server.
+
+<H3><A NAME="CLIENT_AUTO">Automatic Configuration of Print Queues</A></H3>
+
+<P>CUPS supports automatic client configuration of printers on the same
+subnet. To configure printers on the same subnet, <I>do nothing</I>.
+Each client should see the available printers within 30 seconds
+automatically. The printer and class lists are updated automatically as
+printers and servers are added or removed.
+
+<P>If you want to see printers on other subnets as well, use the
+<A HREF="#BrowsePoll"><CODE>BrowsePoll</CODE></A>
+directive as described next.</P>
+
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+ <TR>
+ <TD><B> NOTE:</B>
+ <P>The<A HREF="#BrowseAddress"> <CODE>BrowseAddress</CODE></A> directive
+ enables broadcast traffic from your server. The default configuration
+ braodcasts printer information every 30 seconds. Although this printer
+ information does not use much bandwidth, typically about 80 bytes per
+ printer, it can add up with large numbers of servers and printers.</P>
+ <P>Use the <A HREF="#BrowseInterval"><CODE>BrowseInterval</CODE></A>
+ and <A HREF="#BrowseTimeout"><CODE>BrowseTimeout</CODE></A> directives to tune
+ the amount of data that is added to your network load. In addition,
+ subnets can be used to minimize the amount of traffic that is carried
+ by the &quot;backbone&quot; of your large network.</P>
+ </TD>
+ </TR>
+</TABLE>
+</CENTER>
+
+<H3><A NAME="CLIENT_POLL">Specifying Multiple Servers for Printing</A></H3>
+
+<P>If you have CUPS servers on different subnets, then you should configure
+CUPS to poll those servers. Polling provides the benefits of automatic
+configuration without significant configuration on the clients, and multiple
+clients on the same subnet can share the same configuration information.
+
+<P>Polling is enabled by specifying one or more
+<A HREF="#BrowsePoll"><CODE>BrowsePoll</CODE></A>
+directives in the <VAR>/etc/cups/cupsd.conf</VAR> file.
+For information on making these changes, see
+<A HREF="#PRINTING_MANAGEMENT">Chapter 6, "Printing System Management"</A>.
+
+<P>Multiple <A HREF="#BrowsePoll"><CODE>BrowsePoll</CODE></A> lines can
+be used to poll multiple CUPS servers. To limit the amount of
+polling you do from client machines, you can have only one of the
+clients do the polling and relay that information to the others on the
+same subnet (described next).</P>
+
+<H3><A NAME="CLIENT_RELAY">Relaying Printers to Other Clients</A></H3>
+
+<P>When you have clients and servers spread across multiple subnets, the
+polling method is inefficient. CUPS provides a
+<A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A> directive that enables a
+single client to relay (broadcast) the polled printer information to the local subnet.</P>
+
+<P>For example, Server A and Server B are on subnet 1 and subnet 2,
+while the clients are on subnet 3.
+To provide printers to all of the clients in subnet 3,
+client C will be configured with the following directives in <VAR>/etc/cups/cupsd.conf</VAR>:</P>
+
+<UL><PRE>
+# Poll the two servers
+<B>
+BrowsePoll ServerA ENTER
+BrowsePoll ServerB ENTER
+</B>
+
+# Relay the printers to the local subnet
+<B>
+BrowseRelay 127.0.0.1 192.168.3.255 ENTER
+</B></PRE></UL>
+
+<P>The <A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A> line specifies a source address and mask.
+Any browse packets coming from a matching address wil be sent to the given broadcast address.
+In this case, we want the packets from the local machine (127.0.0.1) relayed to the other clients.</P>
+
+<P>As printers are found using polling,
+they are relayed from client C to the rest of the clients through a broadcast on subnet 3.
+The rest of the clients can use the standard <VAR>cupsd.conf</VAR> configuration.</P>
+
+<P>The <A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A> directive can also be used to relay
+browsing packets from one network interface to another.
+For example, if client C in the previous example had network interfaces attaches to both
+subnet 1 and subnet 2, it could use the <A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A> directive exclusively:
+
+<UL><PRE>
+# Relay the printers from subnet 1 and 2 to subnet 3
+<B>
+BrowseRelay 192.168.1 192.168.3.255 ENTER
+BrowseRelay 192.168.2 192.168.3.255 ENTER
+</B></PRE></UL>
+
+<H2>Load Balancing and Failsafe Operation</H2>
+
+<P>When using server polling or broadcasting, CUPS clients can
+automatically merge identical printers on multiple servers into a
+single <I>implicit class</I> queue. Clients assume that printers with
+the same name on multiple servers are in fact the same printer or type
+of printer being served by multiple machines.</P>
+
+<P>If you have two printers, LaserJet@ServerA and LaserJet@ServerB, a
+third implicit class called <I>LaserJet</I> will be created
+automatically on the client that refers to both printers. If the client
+also has a local printer with the name LaserJet then an implicit class
+named <I>AnyLaserJet</I> will be created instead.</P>
+
+<P>The client will alternate between servers and automatically stop
+sending jobs to a server if it goes down, providing a load-balancing
+effect and fail-safe operation with automatic switchover.</P>
+
+<CENTER><TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+ <TR>
+ <TD><B> NOTE:</B>
+ <P>Note that implicit classes (<A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A>)
+ are enabled by default.</P>
+ </TD>
+ </TR>
+</TABLE></CENTER>
+
+<H1 ALIGN="RIGHT"><A NAME="PRINTING_MANAGEMENT">6 - Printing System Management</A></H1>
+
+<P>This chapter shows how you can configure the CUPS server.
+
+<H2>The Basics</H2>
+
+<P>Several text files are used to configure CUPS. All of the server
+configuration files are located in the <VAR>/etc/cups</VAR> directory:
+
+<UL>
+<DL>
+
+ <!-- NEED 1in -->
+ <DT>classes.conf
+
+ <DD>This file contains information on each printer class.
+ Normally you manipulate this file using the
+ <CODE>lpadmin</CODE> command or the Web interface.<BR>&nbsp;
+
+ <!-- NEED 1in -->
+ <DT>client.conf
+
+ <DD>This file provides the default server name for client
+ machines. See <A HREF="#CLIENT_SETUP">Chapter 5, "Client
+ Setup"</A> for more information.<BR>&nbsp;
+
+ <!-- NEED 1in -->
+ <DT>cupsd.conf
+
+ <DD>This file controls how the CUPS server
+ (<VAR>/usr/sbin/cupsd</VAR>) operates and is normally edited by
+ hand.<BR>&nbsp;
+
+ <!-- NEED 1in -->
+ <DT>mime.convs
+
+ <DD>This file contains a list of standard file conversion filters
+ and their costs. You normally do not edit this file.<BR>&nbsp;
+
+ <!-- NEED 1in -->
+ <DT>mime.types
+
+ <DD>This file contains a list of standard file formats and how to
+ recognize them. You normally do not edit this file.<BR>&nbsp;
+
+ <!-- NEED 1in -->
+ <DT>printers.conf
+
+ <DD>This file contains information on each printer. Normally
+ you manipulate this file using the <CODE>lpadmin</CODE> command
+ or the Web Interface.<BR>&nbsp;
+
+</DL>
+</UL>
+
+<H2><A NAME="RESTARTING">Restarting the CUPS Server</A></H2>
+
+<P>Once you have made a change to a configuration file you need to
+restart the CUPS server by sending it a <CODE>HUP</CODE> signal or using the
+supplied initialization script. The CUPS distributions install the
+script in the <VAR>init.d</VAR> directory with the name
+<VAR>cups</VAR>. The location varies based upon the operating system:
+
+<UL><PRE>
+<B>/etc/software/init.d/cups restart ENTER</B>
+<B>/etc/rc.d/init.d/cups restart ENTER</B>
+<B>/etc/init.d/cups restart ENTER</B>
+<B>/sbin/init.d/cups restart ENTER</B>
+</PRE></UL>
+
+<H2>Changing the Server Configuration</H2>
+
+<P>The <VAR>/etc/cups/cupsd.conf</VAR> file contains configuration
+<I>directives</I> that control how the server functions. Each directive
+is listed on a line by itself followed by its value. Comments are
+introduced using the number sign ("#") character at the beginning of a
+line. Since the server configuration file consists of plain text, you
+can use your favorite text editor to make changes to it.
+
+<!-- NEED 4in -->
+<H2>Server Directives</H2>
+
+<P>The <VAR>cupsd.conf</VAR> file contains many directives that
+determine how the server operates:
+
+<UL>
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0">
+<TR>
+<TD VALIGN="TOP">
+
+ <LI><A HREF="#AccessLog"><CODE>AccessLog</CODE></A>
+ <LI><A HREF="#Allow"><CODE>Allow</CODE></A>
+ <LI><A HREF="#AuthClass"><CODE>AuthClass</CODE></A>
+ <LI><A HREF="#AuthGroupName"><CODE>AuthGroupName</CODE></A>
+ <LI><A HREF="#AuthType"><CODE>AuthType</CODE></A>
+ <LI><A HREF="#AutoPurgeJobs"><CODE>AutoPurgeJobs</CODE></A>
+ <LI><A HREF="#BrowseAddress"><CODE>BrowseAddress</CODE></A>
+ <LI><A HREF="#BrowseAllow"><CODE>BrowseAllow</CODE></A>
+ <LI><A HREF="#BrowseDeny"><CODE>BrowseDeny</CODE></A>
+ <LI><A HREF="#BrowseInterval"><CODE>BrowseInterval</CODE></A>
+ <LI><A HREF="#BrowseOrder"><CODE>BrowseOrder</CODE></A>
+ <LI><A HREF="#BrowsePoll"><CODE>BrowsePoll</CODE></A>
+ <LI><A HREF="#BrowsePort"><CODE>BrowsePort</CODE></A>
+ <LI><A HREF="#BrowseProtocols"><CODE>BrowseProtocols</CODE></A>
+ <LI><A HREF="#BrowseRelay"><CODE>BrowseRelay</CODE></A>
+ <LI><A HREF="#BrowseShortNames"><CODE>BrowseShortNames</CODE></A>
+ <LI><A HREF="#BrowseTimeout"><CODE>BrowseTimeout</CODE></A>
+ <LI><A HREF="#Browsing"><CODE>Browsing</CODE></A>
+ <LI><A HREF="#Classification"><CODE>Classification</CODE></A>
+ <LI><A HREF="#ClassifyOverride"><CODE>ClassifyOverride</CODE></A>
+ <LI><A HREF="#ConfigFilePerm"><CODE>ConfigFilePerm</CODE></A>
+ <LI><A HREF="#DataDir"><CODE>DataDir</CODE></A>
+ <LI><A HREF="#DefaultCharset"><CODE>DefaultCharset</CODE></A>
+ <LI><A HREF="#DefaultLanguage"><CODE>DefaultLanguage</CODE></A>
+ <LI><A HREF="#Deny"><CODE>Deny</CODE></A>
+ <LI><A HREF="#DocumentRoot"><CODE>DocumentRoot</CODE></A>
+ <LI><A HREF="#Encryption"><CODE>Encryption</CODE></A>
+
+</TD>
+<TD VALIGN="TOP">
+&nbsp;&nbsp;&nbsp;
+</TD>
+<TD VALIGN="TOP">
+
+ <LI><A HREF="#ErrorLog"><CODE>ErrorLog</CODE></A>
+ <LI><A HREF="#FilterLimit"><CODE>FilterLimit</CODE></A>
+ <LI><A HREF="#FilterNice"><CODE>FilterNice</CODE></A>
+ <LI><A HREF="#FontPath"><CODE>FontPath</CODE></A>
+ <LI><A HREF="#Group"><CODE>Group</CODE></A>
+ <LI><A HREF="#HideImplicitMembers"><CODE>HideImplicitMembers</CODE></A>
+ <LI><A HREF="#HostNameLookups"><CODE>HostNameLookups</CODE></A>
+ <LI><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A>
+ <LI><A HREF="#ImplicitAnyClasses"><CODE>ImplicitAnyClasses</CODE></A>
+ <LI><A HREF="#Include"><CODE>Include</CODE></A>
+ <LI><A HREF="#KeepAliveTimeout"><CODE>KeepAliveTimeout</CODE></A>
+ <LI><A HREF="#KeepAlive"><CODE>KeepAlive</CODE></A>
+ <LI><A HREF="#Limit"><CODE>Limit</CODE></A>
+ <LI><A HREF="#LimitExcept"><CODE>LimitExcept</CODE></A>
+ <LI><A HREF="#LimitRequestBody"><CODE>LimitRequestBody</CODE></A>
+ <LI><A HREF="#Listen"><CODE>Listen</CODE></A>
+ <LI><A HREF="#Location"><CODE>Location</CODE></A>
+ <LI><A HREF="#LogFilePerm"><CODE>LogFilePerm</CODE></A>
+ <LI><A HREF="#LogLevel"><CODE>LogLevel</CODE></A>
+ <LI><A HREF="#MaxClients"><CODE>MaxClients</CODE></A>
+ <LI><A HREF="#MaxCopies"><CODE>MaxCopies</CODE></A>
+ <LI><A HREF="#MaxJobs"><CODE>MaxJobs</CODE></A>
+ <LI><A HREF="#MaxJobsPerPrinter"><CODE>MaxJobsPerPrinter</CODE></A>
+ <LI><A HREF="#MaxJobsPerUser"><CODE>MaxJobsPerUser</CODE></A>
+ <LI><A HREF="#MaxLogSize"><CODE>MaxLogSize</CODE></A>
+ <LI><A HREF="#MaxRequestSize"><CODE>MaxRequestSize</CODE></A>
+ <LI><A HREF="#Order"><CODE>Order</CODE></A>
+ <LI><A HREF="#PageLog"><CODE>PageLog</CODE></A>
+
+</TD>
+<TD VALIGN="TOP">
+&nbsp;&nbsp;&nbsp;
+</TD>
+<TD VALIGN="TOP">
+
+ <LI><A HREF="#Port"><CODE>Port</CODE></A>
+ <LI><A HREF="#PreserveJobFiles"><CODE>PreserveJobFiles</CODE></A>
+ <LI><A HREF="#PreserveJobHistory"><CODE>PreserveJobHistory</CODE></A>
+ <LI><A HREF="#Printcap"><CODE>Printcap</CODE></A>
+ <LI><A HREF="#PrintcapFormat"><CODE>PrintcapFormat</CODE></A>
+ <LI><A HREF="#PrintcapGUI"><CODE>PrintcapGUI</CODE></A>
+ <LI><A HREF="#RemoteRoot"><CODE>RemoteRoot</CODE></A>
+ <LI><A HREF="#RequestRoot"><CODE>RequestRoot</CODE></A>
+ <LI><A HREF="#Require"><CODE>Require</CODE></A>
+ <LI><A HREF="#RIPCache"><CODE>RIPCache</CODE></A>
+ <LI><A HREF="#RootCertDuration"><CODE>RootCertDuration</CODE></A>
+ <LI><A HREF="#RunAsUser"><CODE>RunAsUser</CODE></A>
+ <LI><A HREF="#Satisfy"><CODE>Satisfy</CODE></A>
+ <LI><A HREF="#ServerAdmin"><CODE>ServerAdmin</CODE></A>
+ <LI><A HREF="#ServerBin"><CODE>ServerBin</CODE></A>
+ <LI><A HREF="#ServerCertificate"><CODE>ServerCertificate</CODE></A>
+ <LI><A HREF="#ServerKey"><CODE>ServerKey</CODE></A>
+ <LI><A HREF="#ServerName"><CODE>ServerName</CODE></A>
+ <LI><A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A>
+ <LI><A HREF="#SSLListen"><CODE>SSLListen</CODE></A>
+ <LI><A HREF="#SSLPort"><CODE>SSLPort</CODE></A>
+ <LI><A HREF="#SystemGroup"><CODE>SystemGroup</CODE></A>
+ <LI><A HREF="#TempDir"><CODE>TempDir</CODE></A>
+ <LI><A HREF="#Timeout"><CODE>Timeout</CODE></A>
+ <LI><A HREF="#User"><CODE>User</CODE></A>
+
+</TD>
+</TR>
+</TABLE>
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="AccessLog">AccessLog</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+AccessLog /var/log/cups/access_log
+AccessLog /var/log/cups/access_log-%s
+AccessLog syslog
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>AccessLog</CODE> directive sets the name of the access log
+file. If the filename is not absolute then it is assumed to be relative
+to the <A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+access log file is stored in "common log format" and can be used by any
+web access reporting tool to generate a report on CUPS server activity.
+
+<P>The server name can be included in the filename by using
+<CODE>%s</CODE> in the name.
+
+<P>The special name "syslog" can be used to send the access information
+to the system log instead of a plain file.
+
+<P>The default access log file is <VAR>/var/log/cups/access_log</VAR>.
+
+<!-- NEED 6in -->
+<H3><A NAME="Allow">Allow</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Allow from All
+Allow from None
+Allow from *.domain.com
+Allow from .domain.com
+Allow from host.domain.com
+Allow from nnn.*
+Allow from nnn.nnn.*
+Allow from nnn.nnn.nnn.*
+Allow from nnn.nnn.nnn.nnn
+Allow from nnn.nnn.nnn.nnn/mm
+Allow from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+Allow from @LOCAL
+Allow from @IF(name)
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Allow</CODE> directive specifies a hostname, IP address,
+or network that is allowed access to the server. <CODE>Allow</CODE>
+directives are cummulative, so multiple <CODE>Allow</CODE> directives
+can be used to allow access for multiple hosts or networks. The
+<CODE>/mm</CODE> notation specifies a CIDR netmask:
+
+<CENTER><TABLE BORDER="1">
+<TR>
+ <TH WIDTH="10%">mm</TH>
+ <TH WIDTH="20%">netmask</TH>
+ <TH WIDTH="10%">mm</TH>
+ <TH WIDTH="20%">netmask</TH>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">0</TD>
+ <TD ALIGN="CENTER">0.0.0.0</TD>
+ <TD ALIGN="CENTER">8</TD>
+ <TD ALIGN="CENTER">255.0.0.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">1</TD>
+ <TD ALIGN="CENTER">128.0.0.0</TD>
+ <TD ALIGN="CENTER">16</TD>
+ <TD ALIGN="CENTER">255.255.0.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">2</TD>
+ <TD ALIGN="CENTER">192.0.0.0</TD>
+ <TD ALIGN="CENTER">24</TD>
+ <TD ALIGN="CENTER">255.255.255.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">...</TD>
+ <TD ALIGN="CENTER">...</TD>
+ <TD ALIGN="CENTER">32</TD>
+ <TD ALIGN="CENTER">255.255.255.255</TD>
+</TR>
+</TABLE></CENTER>
+
+<P>The <CODE>@LOCAL</CODE> name will allow access from all local
+network interfaces, but not remote point-to-point interfaces. The
+<CODE>@IF(name)</CODE> name will allow access from the named
+interface.
+
+<P>The <CODE>Allow</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="AuthClass">AuthClass</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+AuthClass Anonymous
+AuthClass User
+AuthClass System
+AuthClass Group
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>AuthClass</CODE> directive defines what level of authentication
+is required:
+
+<UL>
+
+ <LI><CODE>Anonymous</CODE> - No authentication should be performed
+ (default.)
+
+ <LI><CODE>User</CODE> - A valid username and password is required.
+
+ <LI><CODE>System</CODE> - A valid username and password is
+ required, and the username must belong to the "sys" group; this
+ can be changed using the
+ <A HREF="#SystemGroup"><CODE>SystemGroup</CODE></A> directive.
+
+ <LI><CODE>Group</CODE> - A valid username and password is
+ required, and the username must belong to the group named by
+ the <CODE>AuthGroupName</CODE> directive.
+
+</UL>
+
+<P>The <CODE>AuthClass</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="AuthGroupName">AuthGroupName</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+AuthGroupName mygroup
+AuthGroupName lp
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>AuthGroupName</CODE> directive sets the group to use for
+<CODE>Group</CODE> authentication.
+
+<P>The <CODE>AuthGroupName</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="AuthType">AuthType</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+AuthType None
+AuthType Basic
+AuthType Digest
+AuthType BasicDigest
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>AuthType</CODE> directive defines the type of authentication to
+perform:
+
+<UL>
+
+ <LI><CODE>None</CODE> - No authentication should be performed
+ (default.)
+
+ <LI><CODE>Basic</CODE> - Basic authentication should be
+ performed using the UNIX password and group files.
+
+ <LI><CODE>Digest</CODE> - Digest authentication should be
+ performed using the <VAR>/etc/cups/passwd.md5</VAR> file.
+
+ <LI><CODE>BasicDigest</CODE> - Basic authentication should be
+ performed using the <VAR>/etc/cups/passwd.md5</VAR> file.
+
+</UL>
+
+<P>When using <CODE>Basic</CODE>, <CODE>Digest</CODE>, or
+<CODE>BasicDigest</CODE> authentication, clients connecting
+through the <CODE>localhost</CODE> interface can also
+authenticate using <A HREF="#CERTIFICATES">certificates</A>.
+
+<P>The <CODE>AuthType</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="AutoPurgeJobs">AutoPurgeJobs</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+AutoPurgeJobs Yes
+AutoPurgeJobs No
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>AutoPurgeJobs</CODE> directive specifies whether or not to purge
+completed jobs once they are no longer required for quotas. This option has
+no effect if quotas are not enabled. The default setting is <CODE>No</CODE>.
+
+<!-- NEED 5in -->
+<H3><A NAME="BrowseAddress">BrowseAddress</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseAddress 255.255.255.255:631
+BrowseAddress 192.0.2.255:631
+BrowseAddress host.domain.com:631
+BrowseAddress @LOCAL
+BrowseAddress @IF(name)
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseAddress</CODE> directive specifies an address to
+send browsing information to. Multiple <CODE>BrowseAddress</CODE>
+directives can be specified to send browsing information to different
+networks or systems.
+
+<P>The <CODE>@LOCAL</CODE> name will broadcast printer
+information to all local interfaces. The <CODE>@IF(name)</CODE>
+name will broadcast to the named interface.
+
+<P>No browse addresses are set by default.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>If you are using HP-UX 10.20 and a subnet that is not 24,
+ 16, or 8 bits, printer browsing (and in fact all broadcast
+ reception) will not work. This problem appears to be fixed in
+ HP-UX 11.0.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 4in -->
+<H3><A NAME="BrowseAllow">BrowseAllow</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseAllow from all
+BrowseAllow from none
+BrowseAllow from 192.0.2
+BrowseAllow from 192.0.2.0/24
+BrowseAllow from 192.0.2.0/255.255.255.0
+BrowseAllow from *.domain.com
+BrowseAllow from @LOCAL
+BrowseAllow from @IF(name)
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseAllow</CODE> directive specifies a system or network
+to accept browse packets from. The default is to accept browse packets
+from all hosts.
+
+<P>Host and domain name matching require that you enable the
+<A HREF="#HostNameLookups"><CODE>HostNameLookups</CODE></A> directive.
+
+<P>IP address matching supports exact matches, partial addresses that
+match networks using netmasks of 255.0.0.0, 255.255.0.0, and 255.255.255.0,
+or network addresses using the specified netmask or bit count.
+
+<P>The <CODE>@LOCAL</CODE> name will allow browse data from all
+local network interfaces, but not remote point-to-point
+interfaces. The <CODE>@IF(name)</CODE> name will allow browse
+data from the named interface.
+
+
+<!-- NEED 4in -->
+<H3><A NAME="BrowseDeny">BrowseDeny</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseDeny from all
+BrowseDeny from none
+BrowseDeny from 192.0.2
+BrowseDeny from 192.0.2.0/24
+BrowseDeny from 192.0.2.0/255.255.255.0
+BrowseDeny from *.domain.com
+BrowseDeny from @LOCAL
+BrowseDeny from @IF(name)
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseDeny</CODE> directive specifies a system or network
+to reject browse packets from. The default is to deny browse packets
+from no hosts.
+
+<P>Host and domain name matching require that you enable the
+<A HREF="#HostNameLookups"><CODE>HostNameLookups</CODE></A> directive.
+
+<P>IP address matching supports exact matches, partial addresses that
+match networks using netmasks of 255.0.0.0, 255.255.0.0, and 255.255.255.0,
+or network addresses using the specified netmask or bit count.
+
+<P>The <CODE>@LOCAL</CODE> name will block browse data from all
+local network interfaces, but not remote point-to-point
+interfaces. The <CODE>@IF(name)</CODE> name will block browse
+data from the named interface.
+
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseOrder">BrowseOrder</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseOrder allow,deny
+BrowseOrder deny,allow
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseOrder</CODE> directive specifies the order of allow/deny
+processing. The default order is <CODE>deny,allow</CODE>:
+
+<UL>
+
+ <LI><CODE>allow,deny</CODE> - Browse packets are accepted unless
+ specifically denied.
+
+ <LI><CODE>deny,allow</CODE> - Browse packets are rejected unless
+ specifically allowed.
+
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseInterval">BrowseInterval</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseInterval 0
+BrowseInterval 30
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseInterval</CODE> directive specifies the maximum amount of
+time between browsing updates. Specifying a value of 0 seconds disables
+outgoing browse updates but allows a server to receive printer information
+from other hosts.
+
+<P>The <CODE>BrowseInterval</CODE> value should always be less than the
+<A HREF="#BrowseTimeout"><CODE>BrowseTimeout</CODE></A> value. Otherwise
+printers and classes will disappear from client systems between updates.
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowsePoll">BrowsePoll</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowsePoll 192.0.2.2:631
+BrowsePoll host.domain.com:631
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowsePoll</CODE> directive polls a server for available
+printers once every
+<A HREF="#BrowseInterval"><CODE>BrowseInterval</CODE></A> seconds.
+Multiple <CODE>BrowsePoll</CODE> directives can be specified to poll
+multiple servers.
+
+<P>If <CODE>BrowseInterval</CODE> is set to 0 then the server is polled
+once every 30 seconds.
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowsePort">BrowsePort</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowsePort 631
+BrowsePort 9999
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowsePort</CODE> directive specifies the UDP port number
+used for browse packets. The default port number is 631.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>You must set the <CODE>BrowsePort</CODE> to the same value
+ on all of the systems that you want to see.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseProtocols">BrowseProtocols</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseProtocols CUPS
+BrowseProtocols SLP
+BrowseProtocols CUPS SLP
+BrowseProtocols all
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseProtocols</CODE> directive specifies the protocols to
+use when collecting and distributing shared printers on the local network.
+The default protocol is <CODE>CUPS</CODE>, which is a broadcast-based
+protocol.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>When using the <CODE>SLP</CODE> protocol, you must have at least
+ one Directory Agent (DA) server on your network. Otherwise the
+ CUPS scheduler (<CODE>cupsd</CODE>) will not respond to client
+ requests for several seconds while polling the network.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 4in -->
+<H3><A NAME="BrowseRelay">BrowseRelay</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseRelay 193.0.2.1 192.0.2.255
+BrowseRelay 193.0.2.0/255.255.255.0 192.0.2.255
+BrowseRelay 193.0.2.0/24 192.0.2.255
+BrowseRelay *.domain.com 192.0.2.255
+BrowseRelay host.domain.com 192.0.2.255
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseRelay</CODE> directive specifies source and destination
+addresses for relaying browsing information from one host or network to
+another. Multiple <CODE>BrowseRelay</CODE> directives can be specified
+as needed.
+
+<P><CODE>BrowseRelay</CODE> is typically used on systems that bridge
+multiple subnets using one or more network interfaces. It can also be
+used to relay printer information from polled servers with the line:
+
+<UL><PRE>
+BrowseRelay 127.0.0.1 255.255.255.255
+</PRE></UL>
+
+<P>This effectively provides access to printers on a WAN for all clients
+on the LAN(s).
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseShortNames">BrowseShortNames</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseShortNames Yes
+BrowseShortNames No
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseShortNames</CODE> directive specifies whether or not
+short names are used for remote printers when possible. Short names are
+just the remote printer name, without the server ("printer"). If more than
+one remote printer is detected with the same name, the printers will have
+long names ("printer@server1", "printer@server2".)
+
+<P>The default value for this option is <CODE>Yes</CODE>.
+
+<!-- NEED 3in -->
+<H3><A NAME="BrowseTimeout">BrowseTimeout</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+BrowseTimeout 300
+BrowseTimeout 60
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>BrowseTimeout</CODE> directive sets the timeout for
+printer or class information that is received in browse packets. Once a
+printer or class times out it is removed from the list of available
+destinations.
+
+<P>The <CODE>BrowseTimeout</CODE> value should always be greater than the
+<A HREF="#BrowseInterval"><CODE>BrowseInterval</CODE></A> value. Otherwise
+printers and classes will disappear from client systems between updates.
+
+<!-- NEED 4in -->
+<H3><A NAME="Browsing">Browsing</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Browsing On
+Browsing Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Browsing</CODE> directive controls whether or not network printer
+browsing is enabled. The default setting is <CODE>On</CODE>.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>If you are using HP-UX 10.20 and a subnet that is not 24,
+ 16, or 8 bits, printer browsing (and in fact all broadcast
+ reception) will not work. This problem appears to be fixed in
+ HP-UX 11.0.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="Classification">Classification</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Classification
+Classification classified
+Classification confidential
+Classification secret
+Classification topsecret
+Classification unclassified
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Classification</CODE> directive sets the classification level
+on the server. When this option is set, at least one of the banner pages
+is forced to the classification level, and the classification is placed
+on each page of output. The default is no classification level.
+
+<!-- NEED 3in -->
+<H3><A NAME="ClassifyOverride">ClassifyOverride</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ClassifyOverride Yes
+ClassifyOverride No
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ClassifyOverride</CODE> directive specifies whether users
+can override the default classification level on the server. When the
+server classification is set, users can change the classification using
+the <CODE>job-sheets</CODE> option and can choose to only print one
+security banner before or after the job. If the <CODE>job-sheets</CODE>
+option is set to <CODE>none</CODE> then the server default classification
+is used.
+
+<P>The default is to not allow classification overrides.
+
+<!-- NEED 3in -->
+<H3><A NAME="ConfigFilePerm">ConfigFilePerm</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ConfigFilePerm 0644
+ConfigFilePerm 0600
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ConfigFilePerm</CODE> directive specifies the permissions
+to use when writing configuration files. The default is 0600.
+
+<!-- NEED 3in -->
+<H3><A NAME="DataDir">DataDir</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+DataDir /usr/share/cups
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>DataDir</CODE> directive sets the directory to use for data
+files.
+
+<!-- NEED 3in -->
+<H3><A NAME="DefaultCharset">DefaultCharset</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+DefaultCharset utf-8
+DefaultCharset iso-8859-1
+DefaultCharset windows-1251
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>DefaultCharset</CODE> directive sets the default character set
+to use for client connections. The default character set is
+<CODE>utf-8</CODE> but is overridden by the character set for the language
+specified by the client or the <CODE>DefaultLanguage</CODE> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="DefaultLanguage">DefaultLanguage</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+DefaultLanguage de
+DefaultLanguage en
+DefaultLanguage es
+DefaultLanguage fr
+DefaultLanguage it
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>DefaultLanguage</CODE> directive specifies the default language
+to use for client connections. Setting the default language also sets the
+default character set if a language localization file exists for it. The
+default language is "en" for English.
+
+<!-- NEED 5in -->
+<H3><A NAME="Deny">Deny</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Deny from All
+Deny from None
+Deny from *.domain.com
+Deny from .domain.com
+Deny from host.domain.com
+Deny from nnn.*
+Deny from nnn.nnn.*
+Deny from nnn.nnn.nnn.*
+Deny from nnn.nnn.nnn.nnn
+Deny from nnn.nnn.nnn.nnn/mm
+Deny from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+Deny from @LOCAL
+Deny from @IF(name)
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Deny</CODE> directive specifies a hostname, IP address, or
+network that is allowed access to the server. <CODE>Deny</CODE>
+directives are cummulative, so multiple <CODE>Deny</CODE> directives
+can be used to allow access for multiple hosts or networks. The
+<CODE>/mm</CODE> notation specifies a CIDR netmask:
+
+<CENTER><TABLE BORDER="1">
+<TR>
+ <TH WIDTH="10%">mm</TH>
+ <TH WIDTH="20%">netmask</TH>
+ <TH WIDTH="10%">mm</TH>
+ <TH WIDTH="20%">netmask</TH>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">0</TD>
+ <TD ALIGN="CENTER">0.0.0.0</TD>
+ <TD ALIGN="CENTER">8</TD>
+ <TD ALIGN="CENTER">255.0.0.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">1</TD>
+ <TD ALIGN="CENTER">128.0.0.0</TD>
+ <TD ALIGN="CENTER">16</TD>
+ <TD ALIGN="CENTER">255.255.0.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">2</TD>
+ <TD ALIGN="CENTER">192.0.0.0</TD>
+ <TD ALIGN="CENTER">24</TD>
+ <TD ALIGN="CENTER">255.255.255.0</TD>
+</TR>
+<TR>
+ <TD ALIGN="CENTER">...</TD>
+ <TD ALIGN="CENTER">...</TD>
+ <TD ALIGN="CENTER">32</TD>
+ <TD ALIGN="CENTER">255.255.255.255</TD>
+</TR>
+</TABLE></CENTER>
+
+<P>The <CODE>@LOCAL</CODE> name will deny access from all local
+network interfaces, but not remote point-to-point interfaces. The
+<CODE>@IF(name)</CODE> name will deny access from the named
+interface.
+
+<P>The <CODE>Deny</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="DocumentRoot">DocumentRoot</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+DocumentRoot /usr/share/doc/cups
+DocumentRoot /foo/bar/doc/cups
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>DocumentRoot</CODE> directive specifies the location of
+web content for the HTTP server in CUPS. If an absolute path is not
+specified then it is assumed to be relative to the
+<A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+default directory is <VAR>/usr/share/doc/cups</VAR>.
+
+<P>Documents are first looked up in a sub-directory for the primary
+language requested by the client (e.g. <VAR>/usr/share/doc/cups/fr/...</VAR>)
+and then directly under the <CODE>DocumentRoot</CODE> directory
+(e.g. <VAR>/usr/share/doc/cups/...</VAR>), so it is possible to localize
+the web content by providing subdirectories for each language needed.
+
+<!-- NEED 3in -->
+<H3><A NAME="Encryption">Encryption</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Encryption Never
+Encryption IfRequested
+Encryption Required
+Encryption Always
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Encryption</CODE> directive must appear instead a
+<A HREF="#Location"><CODE>Location</CODE></A>
+section and specifies the encryption settings for that location.
+The default setting is <CODE>IfRequested</CODE> for all locations.
+
+<!-- NEED 3in -->
+<H3><A NAME="ErrorLog">ErrorLog</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ErrorLog /var/log/cups/error_log
+ErrorLog /var/log/cups/error_log-%s
+ErrorLog syslog
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ErrorLog</CODE> directive sets the name of the error log
+file. If the filename is not absolute then it is assumed to be relative
+to the <A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+default error log file is <VAR>/var/log/cups/error_log</VAR>.
+
+<P>The server name can be included in the filename by using
+<CODE>%s</CODE> in the name.
+
+<P>The special name "syslog" can be used to send the error information
+to the system log instead of a plain file.
+
+<!-- NEED 3in -->
+<H3><A NAME="FilterLimit">FilterLimit</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+FilterLimit 0
+FilterLimit 200
+FilterLimit 1000
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>FilterLimit</CODE> directive sets the maximum cost
+of all running job filters. It can be used to limit the number
+of filter programs that are run on a server to minimize disk,
+memory, and CPU resource problems. A limit of 0 disables filter
+limiting.
+
+<P>An average print to a non-PostScript printer needs a filter
+limit of about 200. A PostScript printer needs about half that
+(100). Setting the limit below these thresholds will effectively
+limit the scheduler to printing a single job at any time.
+
+<P>The default limit is 0.
+
+<!-- NEED 3in -->
+<H3><A NAME="FilterNice">FilterNice</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+FilterNice 0
+FilterNice 39
+FilterNice -10
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>FilterNice</CODE> directive sets the scheduling
+priority of job filters. Values larger than 0 give filters a
+lower priority while values smaller than 0 give filters a higher
+priority. The <CODE>FilterNice</CODE> value does not affect the
+priority of job backends.
+
+<P>The default priority is 0.
+
+<!-- NEED 3in -->
+<H3><A NAME="FontPath">FontPath</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+FontPath /foo/bar/fonts
+FontPath /usr/share/cups/fonts:/foo/bar/fonts
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>FontPath</CODE> directive specifies the font path to use when
+searching for fonts. The default font path is
+<CODE>/usr/share/cups/fonts</CODE>.
+
+<!-- NEED 3in -->
+<H3><A NAME="Group">Group</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Group sys
+Group system
+Group root
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Group</CODE> directive specifies the UNIX group that
+filter and CGI programs run as. The default group is <CODE>sys</CODE>,
+<CODE>system</CODE>, or <CODE>root</CODE> depending on the operating
+system.
+
+<!-- NEED 3in -->
+<H3><A NAME="HideImplicitMembers">HideImplicitMembers</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+HideImplicitMembers Yes
+HideImplicitMembers No
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>HideImplicitMembers</CODE> directive controls
+whether the individual printers in an implicit class are shown
+to the user. The default is <CODE>No</CODE>.</P>
+
+<P><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A>
+must be enabled for this directive to have any effect.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="HostNameLookups">HostNameLookups</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+HostNameLookups On
+HostNameLookups Off
+HostNameLookups Double
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>HostNameLookups</CODE> directive controls whether
+or not CUPS looks up the hostname for connecting clients. The
+<CODE>Double</CODE> setting causes CUPS to verify that the
+hostname resolved from the address matches one of the addresses
+returned for that hostname. <CODE>Double</CODE> lookups also
+prevent clients with unregistered addresses from connecting
+to your server.
+
+The default is <CODE>Off</CODE> to avoid the potential server
+performance problems with hostname lookups. Set this option to
+<CODE>On</CODE> or <CODE>Double</CODE> only if absolutely
+required.
+
+<!-- NEED 3in -->
+<H3><A NAME="ImplicitClasses">ImplicitClasses</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ImplicitClasses On
+ImplicitClasses Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ImplicitClasses</CODE> directive controls whether implicit
+classes are created based upon the available network printers and classes.
+The default setting is <CODE>On</CODE> but is automatically turned
+<CODE>Off</CODE> if <A HREF="#Browsing"><CODE>Browsing</CODE></A> is
+turned <CODE>Off</CODE>.
+
+<!-- NEED 3in -->
+<H3><A NAME="ImplicitAnyClasses">ImplicitAnyClasses</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ImplicitAnyClasses On
+ImplicitAnyClasses Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ImplicitAnyClasses</CODE> directive controls
+whether implicit classes for local and remote printers are
+created with the name <CODE>AnyPrinter</CODE>. The default
+setting is <CODE>Off</CODE>.</P>
+
+<P><A HREF="#ImplicitClasses"><CODE>ImplicitClasses</CODE></A>
+must be enabled for this directive to have any effect.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="Include">Include</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Include filename
+Include /foo/bar/filename
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Include</CODE> directive includes the named file in
+the <CODE>cupsd.conf</CODE> file. If no leading path is
+provided, the file is assumed to be relative to the
+<A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory.</P>
+
+<!-- NEED 3in -->
+<H3><A NAME="KeepAlive">KeepAlive</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+KeepAlive On
+KeepAlive Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>KeepAlive</CODE> directive controls whether or not to support
+persistent HTTP connections. The default is <CODE>On</CODE>.
+
+<P>HTTP/1.1 clients automatically support persistent connections, while
+HTTP/1.0 clients must specifically request them using the
+<CODE>Keep-Alive</CODE> attribute in the <CODE>Connection:</CODE>
+field of each request.
+
+<!-- NEED 3in -->
+<H3><A NAME="KeepAliveTimeout">KeepAliveTimeout</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+KeepAliveTimeout 60
+KeepAliveTimeout 30
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>KeepAliveTimeout</CODE> directive controls how long a
+persistent HTTP connection will remain open after the last request. The
+default is 60 seconds.
+
+<!-- NEED 3in -->
+<H3><A NAME="Limit">Limit</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+&lt;Limit GET POST&gt;
+...
+&lt;/Limit&gt;
+
+&lt;Limit ALL&gt;
+...
+&lt;/Limit&gt;
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Limit</CODE> directive groups access control directives for
+specific types of HTTP requests and must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> section. Access can be limited
+for individual request types (<CODE>DELETE</CODE>, <CODE>GET</CODE>,
+<CODE>HEAD</CODE>, <CODE>OPTIONS</CODE>, <CODE>POST</CODE>, <CODE>PUT</CODE>,
+and <CODE>TRACE</CODE>) or for all request types (<CODE>ALL</CODE>). The
+request type names are case-sensitive for compatibility with Apache.
+
+<!-- NEED 3in -->
+<H3><A NAME="LimitExcept">LimitExcept</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+&lt;LimitExcept GET POST&gt;
+...
+&lt;/LimitExcept&gt;
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>LimitExcept</CODE> directive groups access control directives for
+specific types of HTTP requests and must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> section. Unlike the
+<A HREF="#Limit"><CODE>Limit</CODE></A> directive, <CODE>LimitExcept</CODE>
+restricts access for all requests <I>except</I> those listed on the
+<CODE>LimitExcept</CODE> line.
+
+<!-- NEED 3in -->
+<H3><A NAME="LimitRequestBody">LimitRequestBody</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+LimitRequestBody 10485760
+LimitRequestBody 10m
+LimitRequestBody 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>LimitRequestBody</CODE> directive controls the maximum size of
+print files, IPP requests, and HTML form data in HTTP POST requests. The
+default limit is 0 which disables the limit check.
+
+<P>Also see the identical
+<A HREF="#MaxRequestSize"><CODE>MaxRequestSize</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="Listen">Listen</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Listen 127.0.0.1:631
+Listen 192.0.2.1:631
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Listen</CODE> directive specifies a network address and port
+to listen for connections. Multiple <CODE>Listen</CODE> directives can be
+provided to listen on multiple addresses.
+
+<P>The <CODE>Listen</CODE> directive is similar to the
+<A HREF="#Port"><CODE>Port</CODE></A> directive but allows you to restrict
+access to specific interfaces or networks.
+
+<!-- NEED 3in -->
+<H3><A NAME="Location">Location</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+&lt;Location /&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /admin&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /printers&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /printers/name&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /classes&gt;
+...
+&lt;/Location&gt;
+
+&lt;Location /classes/name&gt;
+...
+&lt;/Location&gt;
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Location</CODE> directive specifies access control and
+authentication options for the specified HTTP resource or path.
+The
+<A HREF="#Allow"><CODE>Allow</CODE></A>,
+<A HREF="#AuthClass"><CODE>AuthClass</CODE></A>,
+<A HREF="#AuthGroupName"><CODE>AuthGroupName</CODE></A>,
+<A HREF="#AuthType"><CODE>AuthType</CODE></A>,
+<A HREF="#Deny"><CODE>Deny</CODE></A>,
+<A HREF="#Encryption"><CODE>Encryption</CODE></A>,
+<A HREF="#Limit"><CODE>Limit</CODE></A>,
+<A HREF="#LimitExcept"><CODE>LimitExcept</CODE></A>,
+<A HREF="#Order"><CODE>Order</CODE></A>,
+<A HREF="#Require"><CODE>Require</CODE></A>, and
+<A HREF="#Satisfy"><CODE>Satisfy</CODE></A>
+directives may all appear inside a location.
+
+<CENTER><TABLE BORDER="1"><CAPTION>Locations on the Server.</CAPTION>
+<TR><TH>Location</TH><TH>Description</TH></TR>
+<TR><TD>/</TD><TD>The path for all get operations (get-printers, get-jobs, etc.)</TD></TR>
+<TR><TD>/admin</TD><TD>The path for all administration operations (add-printer, delete-printer, start-printer, etc.)</TD></TR>
+<TR><TD>/admin/conf</TD><TD>The path for access to the ESP Print Pro configuration files (cupsd.conf, client.conf, etc.)</TD></TR>
+<TR><TD>/classes</TD><TD>The path for all classes</TD></TR>
+<TR><TD>/classes/name</TD><TD>The resource for class <CODE>name</CODE></TD></TR>
+<TR><TD>/jobs</TD><TD>The path for all jobs (hold-job, release-job, etc.)</TD></TR>
+<TR><TD>/jobs/id</TD><TD>The resource for job <CODE>id</CODE></TD></TR>
+<TR><TD>/printers</TD><TD>The path for all printers</TD></TR>
+<TR><TD>/printers/name</TD><TD>The path for printer <CODE>name</CODE></TD></TR>
+<TR><TD>/printers/name.ppd</TD><TD>The PPD file path for printer <CODE>name</CODE></TD></TR>
+</TABLE></CENTER>
+
+<P>Note that more specific resources override the less specific ones.
+So the directives inside the <CODE>/printers/name</CODE> location will override ones from <CODE>/printers</CODE>.
+Directives inside <CODE>/printers</CODE> will override ones from <CODE>/</CODE>. &nbsp;
+None of the directives are inherited.
+More information can be found in section <A HREF="#PRINTING_SECURITY">"Printing System Security"</A>.
+
+<!-- NEED 3in -->
+<H3><A NAME="LogFilePerm">LogFilePerm</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+LogFilePerm 0644
+LogFilePerm 0600
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>LogFilePerm</CODE> directive specifies the permissions
+to use when writing configuration files. The default is 0644.
+
+<!-- NEED 3in -->
+<H3><A NAME="LogLevel">LogLevel</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+LogLevel none
+LogLevel emerg
+LogLevel alert
+LogLevel crit
+LogLevel error
+LogLevel warn
+LogLevel notice
+LogLevel info
+LogLevel debug
+LogLevel debug2
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>LogLevel</CODE> directive specifies the level of logging
+for the <A HREF="#ErrorLog"><CODE>ErrorLog</CODE></A> file. The
+following values are recognized (each level logs everything under the
+preceding levels):
+
+<UL>
+
+ <LI><CODE>none</CODE> - Log nothing.
+
+ <LI><CODE>emerg</CODE> - Log emergency conditions that prevent the
+ server from running.
+
+ <LI><CODE>alert</CODE> - Log alerts that must be handled immediately.
+
+ <LI><CODE>crit</CODE> - Log critical errors that don't prevent
+ the server from running.
+
+ <LI><CODE>error</CODE> - Log general errors.
+
+ <LI><CODE>warn</CODE> - Log errors and warnings.
+
+ <LI><CODE>notice</CODE> - Log temporary error conditions.
+
+ <LI><CODE>info</CODE> - Log all requests and state changes (default).
+
+ <LI><CODE>debug</CODE> - Log basic debugging information.
+
+ <LI><CODE>debug2</CODE> - Log all debugging information.
+
+</UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxClients">MaxClients</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxClients 100
+MaxClients 1024
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxClients</CODE> directive controls the maximum number of
+simultaneous clients that will be allowed by the server. The default is
+100 clients.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Since each print job requires a file descriptor for the
+ status pipe, the CUPS server internally limits the
+ <CODE>MaxClients</CODE> value to 1/3 of the available file descriptors
+ to avoid possible problems when printing large numbers of jobs.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxCopies">MaxCopies</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxCopies 100
+MaxCopies 65535
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxCopies</CODE> directive controls the maximum
+number of copies that a user can print of a job. The default is
+100 copies.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Most HP PCL laser printers internally limit the
+ number of copies to 100.
+
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxJobs">MaxJobs</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxJobs 100
+MaxJobs 9999
+MaxJobs 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxJobs</CODE> directive controls the maximum number of jobs
+that are kept in memory. Once the number of jobs reaches the limit, the
+oldest completed job is automatically purged from the system to make room
+for the new one. If all of the known jobs are still pending or active then
+the new job will be rejected.
+
+<P>Setting the maximum to 0 disables this functionality. The default
+setting is 0.
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxJobsPerPrinter">MaxJobsPerPrinter</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxJobsPerPrinter 100
+MaxJobsPerPrinter 9999
+MaxJobsPerPrinter 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxJobsPerPrinter</CODE> directive controls the maximum number of active jobs
+that are allowed for each printer or class. Once a printer or class reaches the limit, new jobs will be
+rejected until one of the active jobs is completed, stopped, aborted, or cancelled.
+
+<P>Setting the maximum to 0 disables this functionality. The default
+setting is 0.
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxJobsPerUser">MaxJobsPerUser</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxJobsPerUser 100
+MaxJobsPerUser 9999
+MaxJobsPerUser 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxJobsPerUser</CODE> directive controls the maximum number of active jobs
+that are allowed for each user. Once a user reaches the limit, new jobs will be
+rejected until one of the active jobs is completed, stopped, aborted, or cancelled.
+
+<P>Setting the maximum to 0 disables this functionality. The default
+setting is 0.
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxLogSize">MaxLogSize</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxLogSize 1048576
+MaxLogSize 1m
+MaxLogSize 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxLogSize</CODE> directive controls the maximum size of each
+log file. Once a log file reaches or exceeds the maximum size it is closed
+and renamed to <VAR>filename.O</VAR>. This allows you to rotate the logs
+automatically. The default size is 1048576 bytes (1MB).
+
+<P>Setting the maximum size to 0 disables log rotation.
+
+<!-- NEED 3in -->
+<H3><A NAME="MaxRequestSize">MaxRequestSize</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+MaxRequestSize 10485760
+MaxRequestSize 10m
+MaxRequestSize 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>MaxRequestSize</CODE> directive controls the maximum size of
+print files, IPP requests, and HTML form data in HTTP POST requests. The
+default limit is 0 which disables the limit check.
+
+<P>Also see the identical
+<A HREF="#LimitRequestBody"><CODE>LimitRequestBody</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="Order">Order</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Order Allow,Deny
+Order Deny,Allow
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Order</CODE> directive defines the default access control.
+The following values are supported:
+
+<UL>
+
+ <LI><CODE>Allow,Deny</CODE> - Allow requests from all
+ systems <I>except</I> for those listed in a <CODE>Deny</CODE>
+ directive.
+
+ <LI><CODE>Deny,Allow</CODE> - Allow requests only from
+ those listed in an <CODE>Allow</CODE> directive.
+
+</UL>
+
+<P>The <CODE>Order</CODE> directive must appear inside a
+<A HREF="#Location"><CODE>Location</CODE></A> directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="PageLog">PageLog</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+PageLog /var/log/cups/page_log
+PageLog /var/log/cups/page_log-%s
+PageLog syslog
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>PageLog</CODE> directive sets the name of the page log
+file. If the filename is not absolute then it is assumed to be relative
+to the <A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+default page log file is <VAR>/var/log/cups/page_log</VAR>.
+
+<P>The server name can be included in the filename by using
+<CODE>%s</CODE> in the name.
+
+<P>The special name "syslog" can be used to send the page information
+to the system log instead of a plain file.
+
+<!-- NEED 3in -->
+<H3><A NAME="Port">Port</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Port 631
+Port 80
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Port</CODE> directive specifies a port to listen on.
+Multiple <CODE>Port</CODE> lines can be specified to listen on multiple
+ports. The default port is 631.
+
+<!-- NEED 3in -->
+<H3><A NAME="PreserveJobHistory">PreserveJobHistory</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+PreserveJobHistory On
+PreserveJobHistory Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>PreserveJobHistory</CODE> directive controls whether
+the history of completed, cancelled, or aborted print jobs is stored
+on disk.
+
+<P>A value of <CODE>On</CODE> (the default) preserves job information
+until the administrator purges it with the <CODE>cancel</CODE>
+command.
+
+<P>A value of <CODE>Off</CODE> removes the job information as soon as
+each job is completed, cancelled, or aborted.
+
+<!-- NEED 3in -->
+<H3><A NAME="PreserveJobFiles">PreserveJobFiles</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+PreserveJobFiles On
+PreserveJobFiles Off
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>PreserveJobFiles</CODE> directive controls whether the
+document files of completed, cancelled, or aborted print jobs are
+stored on disk.
+
+<P>A value of <CODE>On</CODE> preserves job files until the
+administrator purges them with the <CODE>cancel</CODE> command. Jobs
+can be restarted (and reprinted) as desired until they are purged.
+
+<P>A value of <CODE>Off</CODE> (the default) removes the job files as
+soon as each job is completed, cancelled, or aborted.
+
+<!-- NEED 3in -->
+<H3><A NAME="Printcap">Printcap</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Printcap
+Printcap /etc/printcap
+Printcap /etc/printers.conf
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Printcap</CODE> directive controls whether or not a
+printcap file is automatically generated and updated with a list
+of available printers. If specified with no value, then no
+printcap file will be generated. The default is to generate a
+file named <VAR>/etc/printcap</VAR>.
+
+<P>When a filename is specified (e.g. <VAR>/etc/printcap</VAR>), the
+printcap file is written whenever a printer is added or removed. The
+printcap file can then be used by applications that are hardcoded to
+look at the printcap file for the available printers.
+
+<!-- NEED 3in -->
+<H3><A NAME="PrintcapFormat">PrintcapFormat</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+PrintcapFormat BSD
+PrintcapFormat Solaris
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>PrintcapFormat</CODE> directive controls the output
+format of the printcap file. The default is to generate a BSD
+printcap file.
+
+<!-- NEED 3in -->
+<H3><A NAME="PrintcapGUI">PrintcapGUI</A></H3>
+<HR>
+
+<H4>Example</H4>
+
+<UL><PRE>
+PrintcapGUI /usr/bin/glpoptions
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>PrintcapGUI</CODE> directive sets the program to
+use when displaying an option panel from an IRIX application
+that uses the Impressario print API. The default program is the
+ESP Print Pro "glpoptions" GUI.
+
+<P>The program must accept the <CODE>-d</CODE> option to specify
+a printer and the <CODE>-o</CODE> option to specify one or more
+options. After allowing the user to select/change options, the
+program must then write the list of printing options without the
+<CODE>-o</CODE> to the standard output.
+
+<!-- NEED 3in -->
+<H3><A NAME="RemoteRoot">RemoteRoot</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+RemoteRoot remroot
+RemoteRoot root
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>RemoteRoot</CODE> directive sets the username for
+unauthenticated root requests from remote hosts. The default
+username is <VAR>remroot</VAR>. Setting <CODE>RemoteRoot</CODE>
+to <VAR>root</VAR> effectively disables this security mechanism.
+
+<!-- NEED 3in -->
+<H3><A NAME="RequestRoot">RequestRoot</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+RequestRoot /var/spool/cups
+RequestRoot /foo/bar/spool/cups
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>RequestRoot</CODE> directive sets the directory for
+incoming IPP requests and HTML forms. If an absolute path is not
+provided then it is assumed to be relative to the
+<A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+default request directory is <VAR>/var/spool/cups</VAR>.
+
+<!-- NEED 4in -->
+<H3><A NAME="Require">Require</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Require group foo bar
+Require user john mary
+Require valid-user
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Require</CODE> directive specifies that
+authentication is required for the resource. The
+<CODE>group</CODE> keyword specifies that the authenticated user
+must be a member of one or more of the named groups that follow.
+
+<P>The <CODE>user</CODE> keyboard specifies that the
+authenticated user must be one of the named users that follow.
+
+<P>The <CODE>valid-user</CODE> keyword specifies that any
+authenticated user may access the resource.
+
+<P>The default is to do no authentication. This directive must
+appear inside a <A HREF="#Location"><CODE>Location</CODE></A>
+directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="RIPCache">RIPCache</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+RIPCache 8m
+RIPCache 1g
+RIPCache 2048k
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>RIPCache</CODE> directive sets the size of the memory
+cache used by Raster Image Processor ("RIP") filters such as
+<CODE>imagetoraster</CODE> and <CODE>pstoraster</CODE>. The size can
+be suffixed with a "k" for kilobytes, "m" for megabytes, or
+"g" for gigabytes. The default cache size is "8m", or 8 megabytes.
+
+<!-- NEED 3in -->
+<H3><A NAME="RootCertDuration">RootCertDuration</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+RootCertDuration 300
+RootCertDuration 0
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>RootCertDuration</CODE> directive controls the
+interval between updates of the root authentication certificate.
+The default is <CODE>300</CODE> seconds which updates the root
+certificate approximately once every 5 minutes. Set the interval
+to 0 to disable certificate updates entirely.
+
+
+<!-- NEED 3in -->
+<H3><A NAME="RunAsUser">RunAsUser</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+RunAsUser Yes
+RunAsUser No
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>RunAsUser</CODE> directive controls whether the
+scheduler runs as the unpriviledged user account (usually <CODE>lp</CODE>).
+The default is <CODE>No</CODE> which leaves the scheduler running as
+the <CODE>root</CODE> user.
+
+<P><B>Note:</B> Running as a non-priviledged user may prevent
+LPD and locally connected printers from working due to
+permission problems. The <CODE>lpd</CODE> backend will
+automatically use a non-priviledged mode that is not 100%
+compliant with RFC 1179. The <CODE>parallel</CODE>,
+<CODE>serial</CODE>, and <CODE>usb</CODE> backends will need
+write access to the corresponding device files.
+
+<!-- NEED 3in -->
+<H3><A NAME="Satisfy">Satisfy</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Satisfy all
+Satisfy any
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Satisfy</CODE> directive specifies whether all
+conditions must be satisfied to allow access to the resource. If
+set to <CODE>all</CODE>, then all authentication and access
+control conditions must be satified to allow access.
+
+<P>Setting <CODE>Satisfy</CODE> to <CODE>any</CODE> allows a user to
+gain access if the authentication or access control requirements are
+satisfied. For example, you might require authentication for remote
+access, but allow local access without authentication.
+
+<P>The default is <CODE>all</CODE>. This directive must appear
+inside a <A HREF="#Location"><CODE>Location</CODE></A>
+directive.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerAdmin">ServerAdmin</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerAdmin user@host
+ServerAdmin root@foo.bar.com
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerAdmin</CODE> directive identifies the email address for the
+administrator on the system. By default the administrator email address is
+<CODE>root@server</CODE>, where <CODE>server</CODE> is the server name.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerBin">ServerBin</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerBin /usr/lib/cups
+ServerBin /foo/bar/lib/cups
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerBin</CODE> directive sets the directory for
+server-run executables. If an absolute path is not provided then it is
+assumed to be relative to the
+<A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+default executable directory is <VAR>/usr/lib/cups</VAR>.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerCertificate">ServerCertificate</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerCertificate /etc/cups/ssl/server.crt
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerCertificate</CODE> directive specifies the
+location of the SSL certificate file used by the server when
+negotiating encrypted connections. The certificate must not be
+encrypted (password protected) since the scheduler normally runs
+in the background and will be unable to ask for a password.
+The default certificate file is <VAR>/etc/cups/ssl/server.crt</VAR>.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerKey">ServerKey</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerKey /etc/cups/ssl/server.key
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerKey</CODE> directive specifies the location
+of the SSL private key file used by the server when negotiating
+encrypted connections. The default key file is
+<VAR>/etc/cups/ssl/server.crt</VAR>.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerName"></A>ServerName</H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerName foo.domain.com
+ServerName myserver.domain.com
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerName</CODE> directive specifies the hostname that is
+reported to clients. By default the server name is the hostname.
+
+<!-- NEED 3in -->
+<H3><A NAME="ServerRoot">ServerRoot</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+ServerRoot /etc/cups
+ServerRoot /foo/bar/cups
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>ServerRoot</CODE> directive specifies the absolute path to
+the server configuration and state files. It is also used to resolve
+relative paths in the <VAR>cupsd.conf</VAR> file. The default server
+directory is <VAR>/etc/cups</VAR>.
+
+<!-- NEED 3in -->
+<H3><A NAME="SSLListen">SSLListen</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+SSLListen 127.0.0.1:443
+SSLListen 192.0.2.1:443
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>SSLListen</CODE> directive specifies a network
+address and port to listen for secure connections. Multiple
+<CODE>SSLListen</CODE> directives can be provided to listen on
+multiple addresses.
+
+<P>The <CODE>SSLListen</CODE> directive is similar to the
+<A HREF="#SSLPort"><CODE>SSLPort</CODE></A> directive but allows
+you to restrict access to specific interfaces or networks.
+
+<!-- NEED 3in -->
+<H3><A NAME="SSLPort">SSLPort</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+SSLPort 443
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>SSLPort</CODE> directive specifies a port to listen
+on for secure connections. Multiple <CODE>SSLPort</CODE> lines
+can be specified to listen on multiple ports.
+
+<!-- NEED 3in -->
+<H3><A NAME="SystemGroup">SystemGroup</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+SystemGroup sys
+SystemGroup system
+SystemGroup root
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>SystemGroup</CODE> directive specifies the system
+administration group for <CODE>System</CODE> authentication. More
+information can be found later in this chapter in
+<A HREF="#PRINTING_SECURITY">"Printing System Security"</A>.
+
+<!-- NEED 3in -->
+<H3><A NAME="TempDir">TempDir</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+TempDir /var/tmp
+TempDir /foo/bar/tmp
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>TempDir</CODE> directive specifies an absolute path for
+the directory to use for temporary files. The default directory is
+<VAR>/var/tmp</VAR>.
+
+<P>Temporary directories must be world-writable and should have the
+"sticky" permission bit enabled so that other users cannot delete
+filter temporary files. The following commands will create an
+appropriate temporary directory called <VAR>/foo/bar/tmp</VAR>:
+
+<UL><PRE>
+<B>mkdir /foo/bar/tmp ENTER</B>
+<B>chmod a+rwxt /foo/bar/tmp ENTER</B>
+</PRE></UL>
+
+<!-- NEED 3in -->
+<H3><A NAME="Timeout">Timeout</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+Timeout 300
+Timeout 90
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>Timeout</CODE> directive controls the amount of time to
+wait before an active HTTP or IPP request times out. The default
+timeout is 300 seconds.
+
+<!-- NEED 3in -->
+<H3><A NAME="User">User</A></H3>
+<HR>
+
+<H4>Examples</H4>
+
+<UL><PRE>
+User lp
+User guest
+</PRE></UL>
+
+<H4>Description</H4>
+
+<P>The <CODE>User</CODE> directive specifies the UNIX user that
+filter and CGI programs run as. The default user is <CODE>lp</CODE>.
+
+<!-- NEW PAGE -->
+<H2><A NAME="PRINTING_SECURITY">Printing System Security</A></H2>
+
+<P>CUPS provides support for address, certificate, and password (Basic
+and Digest) based authentication and access control. Certificate and
+password authentication provide ways to limit access to individual
+people or groups.
+
+<P>Address based access control allows you to limit access to specific
+systems, networks, or domains. While this does not provide authentication,
+it does allow you to limit the potential users of your system efficiently.
+
+<P>CUPS maintains a list of locations that have access control and/or
+authentication enabled. Locations are specified using the
+<A HREF="#Location"><CODE>Location</CODE></A> directive:
+
+<UL><PRE>
+&lt;Location /resource&gt;
+<A HREF="#AuthClass">AuthClass</A> ...
+<A HREF="#AuthGroupName">AuthGroupName</A> ...
+<A HREF="#AuthType">AuthType</A> ...
+
+<A HREF="#Order">Order</A> ...
+<A HREF="#Allow">Allow</A> from ...
+<A HREF="#Deny">Deny</A> from ...
+&lt;/Location&gt;
+</PRE></UL>
+
+<P>Locations generally follow the directory structure of the
+<A HREF="#DocumentRoot"><CODE>DocumentRoot</CODE></A> directory, however
+CUPS does have several virtual locations for administration, classes, jobs,
+and printers:
+
+<CENTER><TABLE BORDER="1">
+<TR>
+ <TH>Location</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>/admin</TD>
+ <TD>The path for all administration operations.</TD>
+</TR>
+<TR>
+ <TD>/classes</TD>
+ <TD>The path for all classes.</TD>
+</TR>
+<TR>
+ <TD>/classes/name</TD>
+ <TD>The resource for class <CODE>name</CODE>.</TD>
+</TR>
+<TR>
+ <TD>/jobs</TD>
+ <TD>The path for all jobs.</TD>
+</TR>
+<TR>
+ <TD>/jobs/id</TD>
+ <TD>The resource for job <CODE>id</CODE>.</TD>
+</TR>
+<TR>
+ <TD>/printers</TD>
+ <TD>The path for all printers.</TD>
+</TR>
+<TR>
+ <TD>/printers/name</TD>
+ <TD>The path for printer <CODE>name</CODE>.</TD>
+</TR>
+<TR>
+ <TD>/printers/name.ppd</TD>
+ <TD>The PPD file path for printer <CODE>name</CODE>.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3><A NAME="CERTIFICATES">Authentication Using Certificates</A></H3>
+
+<P>CUPS supports a local certificate-based authentication scheme that
+can be used in place of <CODE>Basic</CODE> or <CODE>Digest</CODE>
+authentication by clients connecting through the <CODE>localhost</CODE>
+interface. Certificate authentication is not supported or allowed from
+clients on any other interface.
+
+<P>Certificates are 128-bit random numbers that refer to an internal
+authentication record in the server. A client connecting via the
+<CODE>localhost</CODE> interface sends a request with an
+authorization header of:
+
+<UL><PRE>
+Authorization: Local 0123456789ABCDEF0123456789ABCDEF
+</PRE></UL>
+
+<P>The server then looks up the local certificate and authenticates
+using the username associated with it.
+
+<P>Certificates are generated by the server automatically and stored in
+the <VAR>/etc/cups/certs</VAR> directory using the process ID of the
+CGI program started by the server. Certificate files are only readable
+by the <A HREF="#User"><CODE>User</CODE></A> and
+<A HREF="#Group"><CODE>Group</CODE></A> defined in the
+<VAR>cupsd.conf</VAR> file. When the CGI program ends the certificate
+is removed and invalidated automatically.
+
+<P>The special file <VAR>/etc/cups/certs/0</VAR> defines the <I>root
+certificate</I> which can be used by any client running as the super-user
+or another user that is part of the group defined by the
+<A HREF="#SystemGroup"><CODE>SystemGroup</CODE></A> directive. The
+root certificate is automatically regenerated every 5 minutes.
+
+<H3>Using Basic Authentication</H3>
+
+<P>Basic authentication uses UNIX users and passwords to authenticate
+access to resources such as printers and classes, and to limit access
+to administrative functions.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Basic authentication sends the username and password Base64
+ encoded from the client to the server, so it offers no
+ protection against eavesdropping. This means that a malicious
+ user can monitor network packets and discover valid users and
+ passwords that could result in a serious compromise in network
+ security. Use Basic authentication with extreme care.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<P>The CUPS implementation of Basic authentication does not allow access
+through user accounts without a password. If you try to authenticate
+using an account without a password, your access will be immediately
+blocked.
+
+<P>Once a valid username and password is authenticated by CUPS, any
+additional group membership requirements are checked.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>The root user is considered by CUPS to be a member of every
+ group.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 1in -->
+<P>Use the <CODE>AuthType</CODE> directive to enable Basic authentication:
+
+<UL><PRE>
+AuthType Basic
+</PRE></UL>
+
+<!-- NEED 7in -->
+<H3>Using Digest Authentication</H3>
+
+<P>Digest authentication uses users and passwords defined in the
+<VAR>/etc/cups/passwd.md5</VAR> file to authenticate access to
+resources such as printers and classes, and to limit access to
+administrative functions.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Unlike Basic authentication, Digest passes the MD5 sum
+ (basically a complicated checksum) of the username and password
+ instead of the strings themselves. Also, Digest authentication
+ does not use the UNIX password file, so if an attacker does
+ discover the original password it is less likely to result in a
+ serious security problem so long as you use a different UNIX
+ password than the corresponding Digest password.
+
+ <P>The current CUPS implementation of Digest authentication
+ uses the client's hostname or IP address for the "nonce" value.
+ The nonce value is an additional string added to the username
+ and password to make guessing the password more difficult. The
+ server checks that the nonce value matches the client's hostname
+ or address and rejects the MD5 sum if it doesn't. Future versions
+ of CUPS will support Digest "session" authentication which adds
+ the request data to the MD5 sum, providing even better
+ authentication and security.
+
+ <P>Digest authentication does not guarantee that an attacker
+ cannot gain unauthorized access, but it is safer than Basic
+ authentication and should be used in place of Basic
+ authentication whenever possible. <B>Support for Digest
+ authentication in web browsers is not yet universally
+ available.</B>
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 2in -->
+<P>The <CODE>lppasswd(1)</CODE> command is used to add, change, or
+remove accounts from the <VAR>passwd.md5</VAR> file. To add a
+user to the default system group, type:
+
+<UL><PRE>
+<B>lppasswd -a user ENTER</B>
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE></UL>
+
+<!-- NEED 2in -->
+<P>Once added, a user can change his/her password by typing:
+
+<UL><PRE>
+<B>lppasswd ENTER</B>
+Old password: <B>(password) ENTER</B> [password is not echoed]
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE></UL>
+
+<!-- NEED 1in -->
+<P>To remove a user from the password file, type:
+
+<UL><PRE>
+<B>lppasswd -x user ENTER</B>
+</PRE></UL>
+
+<P>Once a valid username and password is authenticated by CUPS, any
+additional group membership requirements are checked.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>The root user is considered by CUPS to be a member of every
+ group.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<P>Use the <CODE>AuthType</CODE> directive to enable Digest authentication:
+
+<UL><PRE>
+AuthType Digest
+</PRE></UL>
+
+<H3>System and Group Authentication</H3>
+
+<P>The <A HREF="#AuthClass"><CODE>AuthClass</CODE></A> directive controls
+the level of authentication to perform. <CODE>System</CODE> and
+<CODE>Group</CODE> authentication extend the normal user-based authentication
+to require membership in a UNIX group. For <CODE>System</CODE> authentication
+each user must belong to the <CODE>sys</CODE>, <CODE>system</CODE>, or
+<CODE>root</CODE> group; the actual group depends on the operating system.
+
+<P>For <CODE>Group</CODE> authentication each user must belong to the
+group named by the <A HREF="#AuthGroupName"><CODE>AuthGroupName</CODE></A>
+directive:
+
+<UL><PRE>
+&lt;Location /path&gt;
+AuthType Digest
+AuthClass Group
+AuthGroupName mygroup
+&lt;/Location&gt;
+</PRE></UL>
+
+<P>The named group must be a valid UNIX user group, usually defined in the
+<VAR>/etc/group</VAR> or <VAR>/etc/netgroup</VAR> files. Additionally, when
+using Digest authentication you need to create user accounts with the named
+group:
+
+<UL><PRE>
+<B>lppasswd -g mygroup -a user ENTER</B>
+Password: <B>(password) ENTER</B> [password is not echoed]
+Password again: <B>(password) ENTER</B> [password is not echoed]
+</PRE></UL>
+
+<!-- NEW PAGE -->
+<H2><A NAME="PRINTER_ACCOUNTING">Printer Accounting</A></H2>
+
+<P>CUPS maintains a log of all accesses, errors, and
+pages that are printed. The log files are normally stored in the
+<VAR>/var/log/cups</VAR> directory. You can change this by
+editing the <VAR>/etc/cups/cupsd.conf</VAR> configuration file.
+
+<H3>The access_log File</H3>
+
+<P>The <VAR>access_log</VAR> file lists each HTTP resource that is accessed
+by a web browser or CUPS/IPP client. Each line is in the so-called "Common
+Log Format" used by many web servers and web reporting tools:
+
+<UL><PRE>
+host group user date-time \"method resource version\" status bytes
+
+127.0.0.1 - - [20/May/1999:19:20:29 +0000] "POST /admin/ HTTP/1.1" 401 0
+127.0.0.1 - mike [20/May/1999:19:20:31 +0000] "POST /admin/ HTTP/1.1" 200 0
+</PRE></UL>
+
+<P>The <I>host</I> field will normally only be an IP address unless you
+have enabled the <A HREF="#HostNameLookups"><CODE>HostNameLookups</CODE></A>
+directive in the <VAR>cupsd.conf</VAR> file.
+
+<P>The <I>group</I> field always contains "-" in CUPS.
+
+<P>The <I>user</I> field is the authenticated username of the requesting user.
+If no username and password is supplied for the request then this field
+contains "-".
+
+<P>The <I>date-time</I> field is the date and time of the request in local time
+and is in the format:
+
+<UL><PRE>
+[DD/MON/YYYY:HH:MM:SS +ZZZZ]
+</PRE></UL>
+
+<P>where <I>ZZZZ</I> is the timezone offset in hours and minutes from Greenwich
+Mean Time (a.k.a. GMT a.k.a. ZULU.)
+
+<P>The <I>method</I> field is the HTTP method used ("GET", "PUT", "POST", etc.)
+
+<P>The <I>resource</I> field is the filename of the requested resource.
+
+<P>The <I>version</I> field is the HTTP specification version used by the
+client. For CUPS clients this will always be "HTTP/1.1".
+
+<P>The <I>status</I> field contains the HTTP result status of the
+request. Usually it is "200", but other HTTP status codes are possible.
+For example, 401 is the "unauthorized access" status in the example
+above.
+
+<P>The <I>bytes</I> field contains the number of bytes in the request.
+For POST requests the <I>bytes</I> field contains the number of bytes
+that was received from the client.
+
+<H3>The error_log File</H3>
+
+<P>The <VAR>error_log</VAR> file lists messages from the scheduler (errors,
+warnings, etc.):
+
+<UL><PRE>
+level date-time message
+
+I [20/May/1999:19:18:28 +0000] Job 1 queued on 'DeskJet' by 'mike'.
+I [20/May/1999:19:21:02 +0000] Job 2 queued on 'DeskJet' by 'mike'.
+I [20/May/1999:19:22:24 +0000] Job 2 was cancelled by 'mike'.
+</PRE></UL>
+
+<P>The <I>level</I> field contains the type of message:
+
+<UL>
+
+ <LI><CODE>E</CODE> - An error occurred.
+
+ <LI><CODE>W</CODE> - The server was unable to perform some action.
+
+ <LI><CODE>I</CODE> - Informational message.
+
+ <LI><CODE>D</CODE> - Debugging message.
+
+</UL>
+
+<P>The <I>date-time</I> field contains the date and time of when the page
+started printing. The format of this field is identical to the <I>data-time</I>
+field in the <VAR>access_log</VAR> file.
+
+<P>The <I>message</I> fields contains a free-form textual message.
+
+<H3>The page_log File</H3>
+
+<P>The <VAR>page_log</VAR> file lists each page that is sent to a printer.
+Each line contains the following information:
+
+<UL><PRE>
+printer user job-id date-time page-number num-copies job-billing
+
+DeskJet root 2 [20/May/1999:19:21:05 +0000] 1 0 acme-123
+</PRE></UL>
+
+<P>The <I>printer</I> field contains the name of the printer that
+printed the page. If you send a job to a printer class, this field will
+contain the name of the printer that was assigned the job.
+
+<P>The <I>user</I> field contains the name of the user (the IPP
+<CODE>requesting-user-name</CODE> attribute) that submitted this file for
+printing.
+
+<P>The <I>job-id</I> field contains the job number of the page being printed.
+Job numbers are reset to 1 whenever the CUPS server is started, so don't depend
+on this number being unique!
+
+<P>The <I>date-time</I> field contains the date and time of when the page
+started printing. The format of this field is identical to the <I>data-time</I>
+field in the <VAR>access_log</VAR> file.
+
+<P>The <I>page-number</I> and <I>num-pages</I> fields contain the page number
+and number of copies being printed of that page. For printer that can not
+produce copies on their own, the <I>num-pages</I> field will always be 1.
+
+<P>The <I>job-billing</I> field contains a copy of the
+<CODE>job-billing</CODE> attribute provided with the IPP
+<CODE>create-job</CODE> or <CODE>print-job</CODE> requests or "-" if none
+was provided.
+
+<!-- NEW PAGE -->
+<H2><A NAME="FILE_TYPING_FILTERING">File Typing and Filtering</A></H2>
+
+<P>CUPS provides a MIME-based file typing and filtering mechanism to
+convert files to a printable format for each printer. On startup the
+CUPS server reads MIME database files from the <VAR>/etc/cups</VAR>
+directory (or a directory specified by the
+<A HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directive) to build
+a file type and conversion database in memory. These database files are
+plain ASCII text and can be edited with your favorite text editor.
+
+<P>The <VAR>mime.types</VAR> and <VAR>mime.convs</VAR> files define the
+standard file types and filters that are available on the system.
+
+<H3>mime.types</H3>
+
+<P>The <VAR>mime.types</VAR> file defines the known file types. Each line
+of the file starts with the MIME type and may be followed by one or
+more file type recognition rules. For example, the
+<CODE>text/html</CODE> file type is defined as:
+
+<UL><PRE>
+text/html html htm \
+ printable(0,1024) + \
+ (string(0,"&lt;HTML&gt;") string(0,"&lt;!DOCTYPE"))
+</PRE></UL>
+
+<P>The first two rules say that any file with an extension of
+<VAR>.html</VAR> or <VAR>.htm</VAR> is a HTML file. The third rule
+says that any file whose first 1024 characters are printable text and
+starts with the strings <CODE>&lt;HTML&gt;</CODE> or
+<CODE>&lt;!DOCTYPE</CODE> is a HTML file as well.
+
+<P>The first two rules deal solely with the name of the file being
+typed. This is useful when the original filename is known, however for
+print files the server doesn't have a filename to work with. The third
+rule takes care of this possibility and automatically figures out the
+file type based upon the contents of the file instead.
+
+<P>The available tests are:
+
+<UL>
+
+ <LI><CODE>( expr )</CODE> - Parenthesis for expression grouping
+
+ <LI><CODE>+</CODE> - Logical AND
+
+ <LI><CODE>,</CODE> or whitespace - Logical OR
+
+ <LI><CODE>!</CODE> - Logical NOT
+
+ <LI><CODE>match("pattern")</CODE> - Pattern match on filename
+
+ <LI><CODE>extension</CODE> - Pattern match on "*.extension"
+
+ <LI><CODE>ascii(offset,length)</CODE> - True if bytes are valid
+ printable ASCII (CR, NL, TAB, BS, 32-126)
+
+ <LI><CODE>printable(offset,length)</CODE> - True if bytes are
+ printable 8-bit chars (CR, NL, TAB, BS, 32-126, 160-254)
+
+ <LI><CODE>string(offset,"string")</CODE> - True if bytes are
+ identical to string
+
+ <LI><CODE>contains(offset,range,"string")</CODE> - True if the
+ range of bytes contains the string
+
+ <LI><CODE>char(offset,value)</CODE> - True if byte is identical
+
+ <LI><CODE>short(offset,value)</CODE> - True if 16-bit integer
+ is identical (network or "big-endian" byte order)
+
+ <LI><CODE>int(offset,value)</CODE> - True if 32-bit integer is
+ identical (network or "big-endian" byte order)
+
+ <LI><CODE>locale("string")</CODE> - True if current locale
+ matches string
+
+</UL>
+
+<P>All numeric values can be in decimal (123), octal (0123), or hexadecimal
+(0x123) as desired.
+
+<!-- NEED 2.5in -->
+<P>Strings can be in quotes, all by themselves, as a string
+of hexadecimal values, or some combination:
+
+<UL><PRE>
+"string"
+'string'
+string
+&lt;737472696e67&gt;
+&lt;7374&gt;ring
+</PRE></UL>
+
+<P>As shown in the <CODE>text/html</CODE> example, rules can continue on
+multiple lines using the backslash (\) character. A more complex example is
+the <CODE>image/jpeg</CODE> rules:
+
+<UL><PRE>
+image/jpeg jpeg jpg jpe string(0,&lt;FFD8FF&gt;) &amp;&amp;\
+ (char(3,0xe0) char(3,0xe1) char(3,0xe2) char(3,0xe3)\
+ char(3,0xe4) char(3,0xe5) char(3,0xe6) char(3,0xe7)\
+ char(3,0xe8) char(3,0xe9) char(3,0xea) char(3,0xeb)\
+ char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef))
+</PRE></UL>
+
+<P>This rule states that any file with an extension of
+<VAR>.jpeg</VAR>, <VAR>.jpg</VAR>, or <VAR>.jpe</VAR> is a JPEG file.
+In addition, any file starting with the hexadecimal string
+<CODE>&lt;FFD8FF&gt;</CODE> (JPEG Start-Of-Image) followed by a
+character between and including <CODE>0xe0</CODE> and <CODE>0xef</CODE>
+(JPEG APPn markers) is also a JPEG file.
+
+<H3>mime.convs</H3>
+
+<P>The <VAR>mime.convs</VAR> file defines all of the filter programs that
+are known to the system. Each line consists of:
+
+<UL><PRE>
+source destination cost program
+
+text/plain application/postscript 50 texttops
+application/vnd.cups-postscript application/vnd.cups-raster 50 pstoraster
+image/* application/vnd.cups-postscript 50 imagetops
+image/* application/vnd.cups-raster 50 imagetoraster
+</PRE></UL>
+
+<P>The <I>source</I> field is a MIME type, optionally using a wildcard for
+the super-type or sub-type (e.g. "text/plain", "image/*", "*/postscript").
+
+<P>The <I>destination</I> field is a MIME type defined in the
+<VAR>mime.types</VAR> file.
+
+<P>The <I>cost</I> field defines a relative cost for the filtering
+operation from 1 to 100. The cost is used to choose between two
+different sets of filters when converting a file. For example, to convert
+from <CODE>image/jpeg</CODE> to <CODE>application/vnd.cups-raster</CODE>,
+you could use the <CODE>imagetops</CODE> and <CODE>pstoraster</CODE>
+filters for a total cost of 100, or the <CODE>imagetoraster</CODE> filter
+for a total cost of 50.
+
+<P>The <I>program</I> field defines the filter program to run; the
+special program "-" can be used to make two file types equivalent. The
+program must accept the standard filter arguments and environment
+variables described in the CUPS Interface Design Description and CUPS
+Software Programmers Manual:
+
+<UL><PRE>
+program job user title options [filename]
+</PRE></UL>
+
+<P>If specified, the <I>filename</I> argument defines a file to read
+when filtering, otherwise the filter must read from the standard input.
+All filtered output must go to the standard output.
+
+<!-- NEED 4in -->
+<H3>Adding Filetypes and Filters</H3>
+
+<P>Adding a new file type or filter is fairly straight-forward. Rather
+than adding the new type and filter to the <VAR>mime.types</VAR> and
+<VAR>mime.convs</VAR> files which are overwritten when you upgrade to a
+new version of CUPS, you simple need to create new files with
+<VAR>.types</VAR> and <VAR>.convs</VAR> extensions in the
+<VAR>/etc/cups</VAR> directory. We recommend that you use the product
+or format name, e.g.:
+
+<UL><PRE>
+myproduct.types
+myproduct.convs
+</PRE></UL>
+
+<P>If you are providing a filter for a common file format or printer,
+add the company or author name:
+
+<UL><PRE>
+acme-msword.types
+acme.msword.convs
+</PRE></UL>
+
+<P>This will help to prevent name collisions if you install many
+different file types and filters.
+
+<P>Once you choose the names for these files, create them using your
+favorite text editor as described earlier in this chapter. Once you
+have created the files, restart the <CODE>cupsd</CODE> process as
+described earlier in <A HREF="#RESTARTING">"Restarting the CUPS Server"</A>.
+
+<H3>Printer Drivers and PPD Files</H3>
+
+<P>Most CUPS printer drivers utilize one or more printer-specific filters
+and a PPD file for each printer model. Printer driver filters are registered
+via the PPD file using <CODE>cupsFilter</CODE> attributes:
+
+<UL><PRE>
+*cupsFilter: "application/vnd.cups-raster 0 rastertohp"
+</PRE></UL>
+
+<P>The filter is specified using the source file type only; the destination
+file type is assumed to be <CODE>printer/name</CODE> - suitable for sending
+to the printer.
+
+<H3>Writing Your Own Filter or Printer Driver</H3>
+
+<P>CUPS supports an unlimited number of file formats and filters, and can
+handle any printer. If you'd like to write a filter or printer driver for
+your favorite file format or printer, consult the CUPS Software Programmers
+Manual for step-by-step instructions.
+
+
+<H1 ALIGN="RIGHT"><A NAME="PRINTING_OTHER">7 - Printing with Other Systems</A></H1>
+
+<P>This chapter describes how to print from client systems that use the
+LPD, Mac OS, or Windows printing protocols.
+
+<H2>The Basics</H2>
+
+<P>CUPS is based on the IPP protocol, so any system that supports IPP
+can send jobs to and receive jobs from CUPS automatically. However, not
+all systems support IPP yet. This chapter will show you how to connect
+these systems to your CUPS server, either to accept jobs from your
+server for printing, or to send jobs to your server.
+
+<H2>Printing from LPD Clients</H2>
+
+<P>CUPS supports limited functionality for LPD-based clients. With LPD you can
+print files to specific printers, list the queue status, and so forth. However,
+the automatic client configuration and printer options are not supported by
+the LPD protocol, so you must manually configure each client for the printers
+it needs to access.
+
+<P>The <CODE>cups-lpd(8)</CODE> program provides support for LPD
+clients and can be used from either the <CODE>inetd(8)</CODE> or
+<CODE>xinetd(8)</CODE> programs. Add the following line to the
+<VAR>/etc/inetd.conf</VAR> file to enable LPD support on your
+server through the <CODE>inetd</CODE> program:
+
+<UL><PRE>
+printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd
+</PRE></UL>
+
+<P>The path to the <CODE>cups-lpd</CODE> may vary depending on your
+installation.
+
+<P>Once you have added this line, send the <CODE>inetd</CODE>
+process a <CODE>HUP</CODE> signal or reboot the system:
+
+<UL><PRE>
+<B>killall -HUP inetd ENTER</B> [IRIX and some versions of Linux]
+<B>kill -HUP <I>pid</I> ENTER [Others]</B>
+<B>reboot ENTER [For all systems if the HUP signal fails]</B>
+</PRE></UL>
+
+<P>If you are using the <CODE>xinetd</CODE> program, create a
+file named <VAR>/etc/xinetd.d/printer</VAR> containing the
+following lines:
+
+<UL><PRE>
+service printer
+{
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ user = lp
+ server = /usr/lib/cups/daemon/cups-lpd
+}
+</PRE></UL>
+
+<P>The <CODE>xinetd</CODE> program automatically reads the new
+configuration file and enables LPD printing support.
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD><B>Warning:</B>
+
+ <P><CODE>cups-lpd</CODE> currently does not perform any
+ access control based on the settings in
+ <VAR>cupsd.conf</VAR> or in the <VAR>hosts.allow</VAR>
+ or <VAR>hosts.deny</VAR> files used by TCP wrappers.
+ Therefore, running <CODE>cups-lpd</CODE> on your server
+ will allow any computer on your network (and perhaps the
+ entire Internet) to print to your server.
+
+ <P>While <CODE>xinetd</CODE> has built-in access control
+ support, you should use the TCP wrappers package with
+ <CODE>inetd</CODE> to limit access to only those
+ computers that should be able to print through your
+ server.
+
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H2>Printing to LPD Servers</H2>
+
+<P>CUPS provides the <CODE>lpd</CODE> backend for printing to LPD-based
+servers and printers. Use a device URI of <CODE>lpd://server/name</CODE>
+to print to a printer on an LPD server, where <CODE>server</CODE>
+is the hostname or IP address of the server and <CODE>name</CODE> is
+the queue name.
+
+<P>Microsoft Windows NT provides an LPD service under the name "TCP/IP
+Printing Services". To enable LPD printing on NT, open the "Services"
+control panel, select the "TCP/IP Printing Services" service, and click
+on the "Start" button. Any shared printer will then be available via
+the LPD protocol.
+
+<H2>Printing from Mac OS Clients</H2>
+
+<P>CUPS does not provide Mac OS support directly. However, there are several
+free and commercial software packages that do.
+
+<H3>Columbia Appletalk Package (CAP)</H3>
+
+<P>Because the CAP LaserWriter server (<CODE>lwsrv(8)</CODE>) does
+not support specification of PPD files, we do not recommend that you
+use CAP with CUPS. However, you can run the <CODE>lpsrv</CODE> program
+for limited printing with the command:
+
+<UL><PRE>
+lwsrv -n "<I>Name</I>" -p <I>printer</I> -a /usr/lib/adicts -f /usr/lib/LW+Fonts
+</PRE></UL>
+
+<P>where <CODE>Name</CODE> is the name you want to use when sharing the
+printer, and <CODE>printer</CODE> is the name of the CUPS print queue.
+
+<!-- NEED 3in -->
+<H3>XINET KA/Spool</H3>
+
+<P>To use your system as a print server for Mac OS clients,
+configure each printer using a <CODE>papserver(8)</CODE> in the
+<VAR>/usr/adm/appletalk/services</VAR> file, specifying the
+corresponding PPD file in the <VAR>/etc/cups/ppd</VAR> directory for
+each printer. For a printer named <CODE>MyPrinter</CODE> the entry
+would look like:
+
+<UL><PRE>
+/usr/etc/appletalk/papserver -I -L -P /etc/cups/ppd/MyPrinter.ppd \
+"Printer Description" MyPrinter
+</PRE></UL>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Enter the text above on a single line without the backslash (\)
+ character.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>NetATalk</H3>
+
+<P>To use your system as a print server for Mac OS clients,
+configure each printer in the <VAR>papd.conf</VAR> file, specifying the
+corresponding PPD file in the <VAR>/etc/cups/ppd</VAR> directory for
+each printer. For a printer named <CODE>MyPrinter</CODE> the entry
+would look like:
+
+<UL><PRE>
+Printer Description:MyPrinter@MyServer:\
+ :pr=|/usr/bin/lp -d MyPrinter:\
+ :op=daemon:\
+ :pd=/etc/cups/ppd/MyPrinter.ppd:
+</PRE></UL>
+
+<!-- NEED 2in -->
+
+<H2>Printing to Mac OS Servers</H2>
+
+<P>CUPS currently does not provide a backend to communicate with a Mac OS
+server. However, you can write and install a short shell script
+in the <VAR>/usr/lib/cups/backend</VAR> directory that sends a print file
+using the appropriate command. The following is a short script that will
+run the <CODE>papif</CODE> command provided with CAP.
+
+<P>After copying this script to <VAR>/usr/lib/cups/backend/cap</VAR>,
+specify a device URI of <CODE>cap://server/printer</CODE> to use this
+backend with a print queue.
+
+<!-- NEED 8in -->
+<UL>
+<PRE>
+<I>"/usr/lib/cups/backend/cap"</I>
+#!/bin/sh
+#
+# Usage: cap job user title copies options [filename]
+#
+
+# No arguments means show available devices...
+
+if test ${#argv} = 0; then
+ echo "network cap \"Unknown\" \"Mac OS Printer via CAP\""
+ exit 0
+fi
+
+# Collect arguments...
+
+user=$2
+copies=$4
+
+if test ${#argv} = 5; then
+ # Get print file from stdin; copies have already been handled...
+ file=/var/tmp/$$.prn
+ copies=1
+ cat &gt; $file
+else
+ # Print file is on command-line...
+ file=$6
+fi
+
+# Create a dummy cap.printers file for this printer based
+# upon a device URI of "cap://server/printer"...
+
+echo $PRINTER/$DEVICE_URI | \
+ awk -F/ '{print $1 "=" $5 ":LaserWriter@" $4}' &gt; /var/tmp/$$.cap
+
+CAPPRINTERS=/var/tmp/$$.cap; export CAPPRINTERS
+
+# Send the file to the printer, once for each copy. This assumes that you
+# have properly initialized the cap.printers file...
+
+while [ $copies -gt 0 ]; do
+ papif -n $user &lt; $file
+
+ copies=`expr $copies - 1`
+done
+
+# Remove any temporary files...
+if test ${#argv} = 5; then
+ /bin/rm -f $file
+fi
+
+/bin/rm -f /var/tmp/$$.cap
+
+exit 0
+</PRE></UL>
+
+<!-- NEED 2in -->
+<H2>Printing from Windows Clients</H2>
+
+<P>While CUPS does not provide Windows support directly, the free
+SAMBA software package does. SAMBA version 2.0.6 is the first release
+of SAMBA that supports CUPS. You can download SAMBA from:
+
+<UL><PRE>
+<A HREF="http://www.samba.org">http://www.samba.org</A>
+</PRE></UL>
+
+<P>To configure SAMBA for CUPS, edit the <VAR>smb.conf</VAR> file and
+replace the existing printing commands and options with the line:
+
+<UL><PRE>
+printing = cups
+printcap name = cups
+</PRE></UL>
+
+<P>That's all there is to it! Remote users will now be able to browse and
+print to printers on your system.
+
+<H3>Exporting Printer Drivers</H3>
+
+<P>You can optionally export printer drivers from your CUPS
+server using the <CODE>cupsaddsmb</CODE> command and the SAMBA
+2.2.0 or higher software.
+
+<P>Before you can export the printers you must download the
+current Adobe PostScript printer drivers from the Adobe web
+site (<A HREF="http://www.adobe.com/">http://www.adobe.com/</A>).
+Use the free <CODE>unzip</CODE> software to extract the files
+from the self-extracting ZIP file containing the drivers; you
+will need the following files:
+
+<UL><PRE>
+ADFONTS.MFM
+ADOBEPS4.DRV
+ADOBEPS4.HLP
+ADOBEPS5.DLL
+ADOBEPSU.DLL
+ADOBEPSU.HLP
+DEFPRTR2.PPD
+ICONLIB.DLL
+PSMON.DLL
+</PRE></UL>
+
+<P>Copy these files to the <VAR>/usr/share/cups/drivers</VAR>
+directory - you may need to rename some of the files so the
+filenames are all UPPERCASE.
+
+<P>Next, configure SAMBA (via the <VAR>smb.conf</VAR> file) to support printing
+through CUPS and provide a printer driver download share, as follows:
+
+<UL><PRE>
+[global]
+ load printers = yes
+ printing = cups
+ printcap name = cups
+
+[printers]
+ comment = All Printers
+ path = /var/spool/samba
+ browseable = no
+ public = yes
+ guest ok = yes
+ writable = no
+ printable = yes
+ printer admin = root
+
+[print$]
+ comment = Printer Drivers
+ path = /etc/samba/drivers
+ browseable = yes
+ guest ok = no
+ read only = yes
+ write list = root
+</PRE></UL>
+
+<P>This configuration assumes a FHS-compliant installation of SAMBA;
+adjust the [printers] and [print$] share paths accordingly on your system as needed.
+That is, the directory for your printer drivers can be anywhere on the
+system; just make sure it is writable by the users specified by
+the <CODE>write list</CODE> directive plus readable and executable by all users.
+Also, make sure that you have SAMBA passwords defined for each user in the
+<CODE>write list</CODE> using SAMBA's <CODE>smbpasswd(1)</CODE> command.
+Otherwise you will not be able to authenticate.
+
+<P>Finally, run the <CODE>cupsaddsmb</CODE> command to export
+the printer drivers for one or more queues:
+
+<UL><PRE>
+<B>cupsaddsmb -U root printer1 ... printerN <I>ENTER</I></B>
+</PRE></UL>
+
+
+<P>Running <CODE>cupsaddsmb</CODE> with the <CODE>-a</CODE> option
+will export all printers:
+
+<UL><PRE>
+<B>cupsaddsmb -U root -a <I>ENTER</I></B>
+</PRE></UL>
+
+<P>Notice in the above examples that the user <CODE>root</CODE> was used
+which was defined in the <CODE>write list</CODE> of the <VAR>smb.conf</VAR> file.
+
+<H2>Printing to Windows Servers</H2>
+
+<P>CUPS can print to Windows servers in one of two ways. The first way uses
+the LPD protocol on the CUPS system and the "TCP/IP Printing Services" on
+the Windows system. You can find out more about this configuration in the
+<A HREF="#LPD">LPD</A> section earlier in this chapter.
+
+<P>The second way is through the Microsoft Server Message Block ("SMB")
+protocol. Support for this protocol is provided with the free SAMBA
+software package. You can download SAMBA from:
+
+<UL><PRE>
+<A HREF="http://www.samba.org">http://www.samba.org</A>
+</PRE></UL>
+
+<P>To configure CUPS for SAMBA, run the following command:
+
+<UL><PRE>
+<B>ln -s `which smbspool` /usr/lib/cups/backend/smb ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>smbspool(1)</CODE> program is provided with SAMBA starting
+with SAMBA 2.0.6. Once you have made the link you can configure your
+printers with one of the following device URIs:
+
+<UL><PRE>
+smb://workgroup/server/sharename
+smb://server/sharename
+smb://user:pass@workgroup/server/sharename
+smb://user:pass@server/sharename
+</PRE></UL>
+
+<P>The <CODE>workgroup</CODE> name need only be specified if your
+system is using a different workgroup. The <CODE>user:pass</CODE>
+strings are required when printing to Windows NT servers or to shares
+with passwords enabled under Windows 95 and 98.
+
+
+<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - Software License Agreement</A></H1>
+
+<EMBED SRC="../LICENSE.html">
+
+
+<H1 ALIGN="RIGHT"><A NAME="COMMON_NETWORK">B - Common Network Settings</A></H1>
+
+<P>This appendix covers many of the popular TCP/IP network interfaces
+and printer servers available on the market today.
+
+<H2>Configuring a Network Interface</H2>
+
+<P>When you first install a network printer or print server on your
+LAN, you need to set the Internet Protocol ("IP") address. On most
+higher-end "workgroup" printers, you can set the address through the
+printer control panel. However, in most cases you will want to assign
+the addresses remotely from your workstation. This makes administration
+a bit easier and avoids assigning duplicate addresses accidentally.
+
+<P>To setup your printer or print server for remote address assignment,
+you'll need the Ethernet Media Access Control ("MAC") address, also
+sometimes called a node address, and the IP address you want to use for
+the device. The Ethernet MAC address can often be found on the printer
+test page or bottom of the print server.
+
+<!-- NEED 3in -->
+<H3>Configuring the IP Address Using ARP</H3>
+
+<P>The easiest way to set the IP address of a network device is to use
+the <CODE>arp(8)</CODE> command. The <CODE>arp</CODE> sends an Address
+Resolution Protocol ("ARP") packet to the specified Ethernet MAC address,
+setting the network device's IP address:
+
+<UL><PRE>
+<B>arp -s ip-address ethernet-address ENTER</B>
+<B>arp -s host.domain.com 08:00:69:00:12:34 ENTER</B>
+<B>arp -s 192.0.2.2 08:00:69:00:12:34 ENTER</B>
+</PRE></UL>
+
+<H3>Configuring the IP Address Using RARP</H3>
+
+<P>The most flexible way to remotely assign IP addresses under UNIX
+is through the Reverse Address Resolution Protocol ("RARP"). RARP
+allows a network device to request an IP address using its Ethernet
+MAC address, and one or more RARP servers on the network will
+respond with an ARP packet with the IP address the device can use.
+
+<P>RARP should be used when you have to manage many printers or print
+servers, or when you have a network device that does not remember its
+IP address after a power cycle. If you just have a single printer or
+print server, the <CODE>arp</CODE> command is the way to go.
+
+<P>Some UNIX operating systems use a program called
+<CODE>rarpd(8)</CODE> to manage RARP. Others, like Linux, support this
+protocol in the kernel. For systems that provide the <CODE>rarpd</CODE>
+program you will need to start it before RARP lookups will work:
+
+<UL><PRE>
+<B>rarpd ENTER</B>
+</PRE></UL>
+
+<P>Under IRIX you can enable this functionality by default using:
+
+<UL><PRE>
+<B>chkconfig rarpd on ENTER</B>
+</PRE></UL>
+
+<P>Both the <CODE>rarpd</CODE> program and kernel RARP support read a
+list of Ethernet and IP addresses from the file <VAR>/etc/ethers</VAR>.
+Each line contains the Ethernet address (colon delimited) followed by
+an IP address or hostname like:
+
+<UL><PRE>
+08:00:69:00:12:34 myprinter.mydomain.com
+08:00:69:00:12:34 192.0.2.2
+</PRE></UL>
+
+<P>Add a line to this file and cycle the power on the printer or print
+server to set its address.
+
+<!-- NEED 2in -->
+<H3>Configuring the IP Address Using BOOTP</H3>
+
+<P>The BOOTP protocol is used when you need to provide additional information
+such as the location of a configuration file to the network interface. Using
+the standard <CODE>bootpd(8)</CODE> program supplied with UNIX you simply need to
+add a line to the <VAR>/etc/bootptab</VAR> file; for IRIX:
+
+<UL><PRE>
+myprinter 08:00:69:00:12:34 192.0.2.2 <VAR>myprinter.boot</VAR>
+</PRE></UL>
+
+<!-- NEED 1in -->
+<P>Newer versions of <CODE>bootpd</CODE> use a different format:
+
+<UL><PRE>
+myprinter:ha=080069001234:ip=192.0.2.2:<VAR>t144=myprinter.boot</VAR>
+</PRE></UL>
+
+<P>The <VAR>myprinter.boot</VAR> file resides in the <VAR>/usr/local/boot</VAR>
+directory by default. If you do not need to provide a boot file you may leave
+the last part of the line blank.</P>
+
+<!-- NEED 2in -->
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Some versions of UNIX do not enable the BOOTP service by
+ default. The <VAR>/etc/inetd.conf</VAR> usually contains a
+ line for the BOOTP service that can be uncommented if
+ needed.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H2>Verifying the Printer Connection</H2>
+
+<P>To test that the IP address has been successfully assigned and that the
+printer is properly connected to your LAN, type:
+
+<UL><PRE>
+<B>ping ip-address ENTER</B>
+</PRE></UL>
+
+<P>If the connection is working properly you will see something like:
+
+<UL><PRE>
+<B>ping myprinter ENTER</B>
+PING myprinter (192.0.2.2): 56 data bytes
+64 bytes from 192.0.2.2: icmp_seq=0 ttl=15 time=5 ms
+64 bytes from 192.0.2.2: icmp_seq=1 ttl=15 time=3 ms
+64 bytes from 192.0.2.2: icmp_seq=2 ttl=15 time=3 ms
+64 bytes from 192.0.2.2: icmp_seq=3 ttl=15 time=3 ms
+</PRE></UL>
+
+<P>If not, verify that the printer or print server is connected to the
+LAN, it is powered on, the LAN cabling is good, and the IP address is
+set correctly. You can usually see the current IP address and network
+status by printing a configuration or test page on the device.
+
+<!-- NEED 4in -->
+<H2>Common Network Interface Settings</H2>
+
+<P>Once you have set the IP address you can access the printer or print
+server using the <CODE>ipp</CODE>, <CODE>lpd</CODE>, or
+<CODE>socket</CODE> backends. The following is a list of common network
+interfaces and printer servers and the settings you should use with
+CUPS:
+
+<CENTER><TABLE BORDER="1">
+<TR VALIGN="TOP" ALIGN="LEFT">
+ <TH>Model/Manufacturer</TH>
+ <TH>Device URI(s)</TH>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Apple LaserWriter</TD>
+ <TD>lpd://<I>address</I>/PASSTHRU</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Axis w/o IPP<BR>
+ <A HREF="#AXIS">(see directions)</A></TD>
+ <TD>socket://<I>address</I>:9100<BR>
+ socket://<I>address</I>:9101<BR>
+ socket://<I>address</I>:9102</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Axis w/IPP</TD>
+ <TD>ipp://<I>address</I>/LPT1<BR>
+ ipp://<I>address</I>/LPT2<BR>
+ ipp://<I>address</I>/COM1</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Castelle LANpress<SUP>TM</SUP></TD>
+ <TD>lpd://<I>address</I>/pr1<BR>
+ lpd://<I>address</I>/pr2<BR>
+ lpd://<I>address</I>/pr3</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>DPI NETPrint</TD>
+ <TD>lpd://<I>address</I>/pr1<BR>
+ lpd://<I>address</I>/pr2<BR>
+ lpd://<I>address</I>/pr3</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>EFI&reg; Fiery&reg; RIP</TD>
+ <TD>lpd://<I>address</I>/print</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>EPSON&reg; Multiprotocol Ethernet Interface Board</TD>
+ <TD>socket://<I>address</I></TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Extended System ExtendNET</TD>
+ <TD>lpd://<I>address</I>/pr1<BR>
+ lpd://<I>address</I>/pr2<BR>
+ lpd://<I>address</I>/pr3</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Hewlett Packard JetDirect w/o IPP</TD>
+ <TD>socket://<I>address</I>:9100<BR>
+ socket://<I>address</I>:9101<BR>
+ socket://<I>address</I>:9102</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Hewlett Packard JetDirect w/IPP</TD>
+ <TD>ipp://<I>address</I>/ipp<BR>
+ ipp://<I>address</I>/ipp/port1<BR>
+ ipp://<I>address</I>/ipp/port2<BR>
+ ipp://<I>address</I>/ipp/port3</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Intel® NetportExpress XL, PRO/100</TD>
+ <TD>lpd://<I>address</I>/LPT1_PASSTHRU<BR>
+ lpd://<I>address</I>/LPT2_PASSTHRU<BR>
+ lpd://<I>address</I>/COM1_PASSTHRU</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Lexmark<SUP>TM</SUP> MarkNet</TD>
+ <TD>lpd://<I>address</I>/ps</TD>
+</TR>
+<!-- NEED 1in -->
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Linksys EtherFast&reg;<BR>
+ <A HREF="#LINKSYS">(see directions)</A></TD>
+ <TD>socket://<I>address</I>:4010<BR>
+ socket://<I>address</I>:4020<BR>
+ socket://<I>address</I>:4030</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Kodak&reg;</TD>
+ <TD>lpd://<I>address</I>/ps</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>QMS&reg; CrownNet<SUP>TM</SUP></TD>
+ <TD>lpd://<I>address</I>/ps</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>Tektronix&reg; PhaserShare<SUP>TM</SUP></TD>
+ <TD>socket://<I>address</I>:9100</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>XEROX&reg; 4512 NIC</TD>
+ <TD>lpd://<I>address</I>/PORT1</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>XEROX&reg; XNIC</TD>
+ <TD>lpd://<I>address</I>/PASSTHRU</TD>
+</TR>
+<TR ALIGN="LEFT" VALIGN="TOP">
+ <TD>XEROX&reg; (most others)</TD>
+ <TD>socket://<I>address</I>:5503</TD>
+</TR>
+</TABLE></CENTER>
+
+<H2><A NAME="AXIS">Configuring Axis Print Servers</A></H2>
+
+<P>The Axis print servers can be configured using ARP, RARP, or BOOTP.
+However, on models that do not provide IPP support an additional step
+must be performed to configure the TCP/IP portion of the print server
+for use with CUPS.
+
+<!-- NEED 3in -->
+<P>Each print server contains a configuration file named
+<VAR>config</VAR> that contains a list of network parameters used by
+the server. To modify this file you must first download it from the
+print server using the <CODE>ftp(1)</CODE> program:
+
+<UL><PRE>
+<B>ftp ip-address ENTER</B>
+Connected to ip-address.
+220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
+ftp> <B>user root ENTER</B>
+331 User name ok, need password
+Password: <B>pass ENTER</B> <I>(this is not echoed)</I>
+230 User logged in
+ftp> <B>get config ENTER</B>
+local: config remote: config
+200 PORT command successful.
+150 Opening data connection for config (192,0,2,2),
+(mode ascii).
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp> <B>quit ENTER</B>
+221 Goodbye.
+</PRE></UL>
+
+<!-- NEED 2in -->
+<P>Next, edit the file with your favorite text editor and locate the
+lines beginning with:
+
+<UL><PRE>
+RTN_OPT. : YES
+RTEL_PR1. : 0
+RTEL_PR2. : 0
+RTEL_PR3. : 0
+RTEL_PR4. : 0
+RTEL_PR5. : 0
+RTEL_PR6. : 0
+RTEL_PR7. : 0
+RTEL_PR8. : 0
+</PRE></UL>
+
+<!-- NEED 1in -->
+Change the <CODE>RTN_OPT</CODE> line to read:
+
+<UL><PRE>
+RTN_OPT. : <B>NO</B>
+</PRE></UL>
+
+<!-- NEED 2in -->
+<P>This disables the Reverse TELNET protocol and enables the standard
+TELNET protocol on the print server. Next, assign a port number for
+each parallel and serial port on the server as follows:
+
+<UL><PRE>
+RTEL_PR1. : <B>9100</B>
+RTEL_PR2. : <B>9101</B>
+RTEL_PR3. : <B>9102</B>
+RTEL_PR4. : <B>9103</B>
+RTEL_PR5. : <B>9104</B>
+RTEL_PR6. : <B>9105</B>
+RTEL_PR7. : <B>9106</B>
+RTEL_PR8. : <B>9107</B>
+</PRE></UL>
+
+<!-- NEED 4in -->
+<P>This essentially makes the Axis print server look like a Hewlett
+Packard JetDirect EX print server. Save the file and then upload the
+new <VAR>config</VAR> file using the <CODE>ftp</CODE> command:
+
+<UL><PRE>
+<B>ftp ip-address ENTER</B>
+Connected to ip-address.
+220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
+ftp> <B>user root ENTER</B>
+331 User name ok, need password
+Password: <B>pass ENTER</B> <I>(this is not echoed)</I>
+230 User logged in
+ftp> <B>put config CONFIG ENTER</B>
+local: config remote: CONFIG
+200 PORT command successful.
+150 Opening data connection for config (192,0,2,2), (mode ascii).
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp> <B>get hardreset ENTER</B>
+local: hardreset remote: hardreset
+200 PORT command successful.
+421 Axis NPS ### hard reset, closing connection.
+ftp> <B>quit ENTER</B>
+221 Goodbye.
+</PRE></UL>
+
+<P>Your Axis print server is now ready for use!
+
+<H2><A NAME="LINKSYS">Configuring Linksys Print Servers</A></H2>
+
+<P>The Linksys print servers can be configured using ARP, RARP, or
+BOOTP. Like older Axis print servers, an additional step must be
+performed to configure the TCP/IP portion of the print server for use
+with CUPS.
+
+<!-- NEED 3in -->
+<P>Each print server contains a configuration file named
+<VAR>CONFIG</VAR> that contains a list of network parameters used by
+the server. To modify this file you must first download it from the
+print server using the <CODE>ftp(1)</CODE> program:
+
+<UL><PRE>
+<B>ftp -n ip-address ENTER</B>
+Connected to ip-address.
+220 Print Server Ready.
+Remote system type is Print.
+ftp> <B>get CONFIG ENTER</B>
+local: CONFIG remote: CONFIG
+200 Command OK.
+150 Open ASCII Mode Connection.
+WARNING! 68 bare linefeeds received in ASCII mode
+File may not have transferred correctly.
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp> <B>quit ENTER</B>
+221 Goodbye.
+</PRE></UL>
+
+<!-- NEED 2in -->
+<P>Next, edit the file with your favorite text editor and locate the
+lines beginning with:
+
+<UL><PRE>
+0100 L1_PROUT:P1
+0120 L2_PROUT:P1
+0140 L3_PROUT:P1
+</PRE></UL>
+
+<P>Change the port number for
+each parallel and serial port on the server as follows:
+
+<UL><PRE>
+0100 L1_PROUT:<B>P1</B>
+0120 L2_PROUT:<B>P2</B>
+0140 L3_PROUT:<B>P3</B>
+</PRE></UL>
+
+<!-- NEED 4in -->
+<P>This maps each virtual printer with a physical port. Save the file and then upload the
+new <VAR>CONFIG</VAR> file using the <CODE>ftp</CODE> command:
+
+<UL><PRE>
+<B>ftp -n ip-address ENTER</B>
+Connected to ip-address.
+220 Print Server Ready.
+Remote system type is Print.
+ftp> <B>put CONFIG ENTER</B>
+local: CONFIG remote: CONFIG
+200 Command OK.
+150 Open ASCII Mode Connection.
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp> <B>quit ENTER</B>
+221 Goodbye.
+</PRE></UL>
+
+<P>Your Linksys print server is now ready for use!
+
+
+<H1 ALIGN="RIGHT"><A NAME="PRINTER_DRIVERS">C - Printer Drivers</A></H1>
+
+<P>This appendix lists the printer drivers that are provided with CUPS.
+
+<H2>Printer Drivers</H2>
+
+<P>CUPS includes the following printer drivers:
+
+<UL>
+
+ <LI><A HREF="#EPSON9">EPSON 9-pin Dot Matrix</A>, <VAR>epson9.ppd</VAR>
+
+ <LI><A HREF="#EPSON24">EPSON 24-pin Dot Matrix</A>, <VAR>epson24.ppd</VAR>
+
+ <LI><A HREF="#STCOLOR">EPSON Stylus Color</A>, <VAR>stcolor.ppd</VAR>
+
+ <LI><A HREF="#STPHOTO">EPSON Stylus Photo</A>, <VAR>stphoto.ppd</VAR>
+
+ <LI><A HREF="#DESKJET">HP DeskJet</A>, <VAR>deskjet.ppd</VAR>
+
+ <LI><A HREF="#LASERJET">HP LaserJet</A>, <VAR>laserjet.ppd</VAR>
+
+</UL>
+
+<H2><A NAME="EPSON9">EPSON 9-pin Dot Matrix</A></H2>
+
+<P>The EPSON 9-pin Dot Matrix driver (<VAR>epson9.ppd</VAR>) supports
+9-pin dot matrix printers that implement the ESC/P command set. It
+provides 60x72, 120x72, and 240x72 DPI output in black only.
+
+<H2><A NAME="EPSON24">EPSON 24-pin Dot Matrix</A></H2>
+
+<P>The EPSON 24-pin Dot Matrix driver (<VAR>epson9.ppd</VAR>) supports
+24-pin dot matrix printers that implement the ESC/P command set. It
+provides 120x180, 180x180, 360x180, and 360x360 DPI output in black
+only.
+
+<H2><A NAME="STCOLOR">EPSON Stylus Color</A></H2>
+
+<P>The EPSON Stylus Color driver (<VAR>stcolor.ppd</VAR>) supports
+EPSON Stylus Color printers that implement the ESC/P2 command set. It
+provides 180, 360, and 720 DPI output in black and color (CMYK).
+
+<H2><A NAME="STPHOTO">EPSON Stylus Photo</A></H2>
+
+<P>The EPSON Stylus Photo driver (<VAR>stphoto.ppd</VAR>) supports
+EPSON Stylus Photo printers that implement the ESC/P2 command set. It
+provides 180, 360, and 720 DPI output in black and color (CMYKcm).
+
+<H2><A NAME="DESKJET">HP DeskJet</A></H2>
+
+<P>The HP DeskJet driver (<VAR>deskjet.ppd</VAR>) supports HP DeskJet
+printers that implement the PCL command set. It provides 150, 300, and
+600 DPI output in black and color (CMYK).
+
+<P>The DeskJet printers that implement the HP-PPA command set (720C,
+722C, 820C, and 1100C) are <B>not</B> supported due to a complete lack
+of documentation and support from Hewlett Packard.
+
+<P>The duplexer provided with the HP DeskJet 900 series printers is also
+not supported for similar reasons.
+
+<H2><A NAME="LASERJET">HP LaserJet</A></H2>
+
+<P>The HP LaserJet driver (<VAR>laserjet.ppd</VAR>) supports HP
+LaserJet printers that implement the PCL command set. It provides 150,
+300, and 600 DPI output in black only and supports the duplexer if
+installed.
+
+<P>LaserJet printers that do not implement PCL (3100, 3150) are not
+supported due to a complete lack of documentation and support from
+Hewlett Packard.
+
+
+<H1 ALIGN="RIGHT"><A NAME="FILES">D - List of Files</A></H1>
+
+<P>This appendix lists the files and directories that are installed for
+the Common UNIX Printing System.
+
+<CENTER><TABLE BORDER="1" WIDTH="80%">
+<TR VALIGN="TOP">
+ <TH>Pathname</TH>
+ <TH>Description</TH>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/certs/</TD>
+ <TD>The location of authentication certificate files for local
+ HTTP clients.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/classes.conf</TD>
+ <TD>The printer classes configuration file for the scheduler.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/cupsd.conf</TD>
+ <TD>The scheduler configuration file.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/interfaces/</TD>
+ <TD>The location of System V interface scripts for printers.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/mime.convs</TD>
+ <TD>The list of standard file filters included with CUPS.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/mime.types</TD>
+ <TD>The list of recognized file types for CUPS.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/ppd/</TD>
+ <TD>The location of PostScript Printer Description ("PPD") files for
+ printers.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/etc/cups/printers.conf</TD>
+ <TD>The printer configuration file for the scheduler.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/cancel</TD>
+ <TD>The System V cancel job(s) command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/disable</TD>
+ <TD>The System V disable printer command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/enable</TD>
+ <TD>The System V enable printer command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lp</TD>
+ <TD>The System V print command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lpoptions</TD>
+ <TD>Sets user-defined printing options and defaults.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lppasswd</TD>
+ <TD>Adds, changes, or removes Digest password accounts.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lpq</TD>
+ <TD>The Berkeley status command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lpr</TD>
+ <TD>The Berkeley print command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lprm</TD>
+ <TD>The Berkeley cancel job(s) command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/bin/lpstat</TD>
+ <TD>The System V status command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/include/cups/</TD>
+ <TD>CUPS API header files.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib32/libcups.a<BR>
+ /usr/lib32/libcupsimage.a</TD>
+ <TD>Static libraries (IRIX 6.5)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/libcups.a<BR>
+ /usr/lib/libcupsimage.a</TD>
+ <TD>Static libraries (all others)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/libcups.sl.2<BR>
+ /usr/lib/libcupsimage.sl.2</TD>
+ <TD>Shared libraries (HP-UX)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib32/libcups.so.2<BR>
+ /usr/lib32/libcupsimage.so.2</TD>
+ <TD>Shared libraries (IRIX 6.5)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/libcups.so.2<BR>
+ /usr/lib/libcupsimage.so.2</TD>
+ <TD>Shared libraries (all others)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/cups/backend/</TD>
+ <TD>Backends for various types of printer connections.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/cups/cgi-bin/</TD>
+ <TD>CGI programs for the scheduler.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/cups/daemon/</TD>
+ <TD>Daemons for polling and LPD support.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/cups/filter/</TD>
+ <TD>Filters for various types of files.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/locale/</TD>
+ <TD>The location of language-specific message files. (System V)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/lib/nls/msg/</TD>
+ <TD>The location of language-specific message files. (Compaq Tru64 UNIX)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/locale/</TD>
+ <TD>The location of language-specific message files. (Linux, *BSD)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/accept</TD>
+ <TD>The accept-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/cupsd</TD>
+ <TD>The CUPS print scheduler.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/lpadmin</TD>
+ <TD>The System V printer administration tool.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/lpc</TD>
+ <TD>The Berkeley printer administration tool.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/lpinfo</TD>
+ <TD>The get-devices and get-ppds command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/lpmove</TD>
+ <TD>The move-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/sbin/reject</TD>
+ <TD>The reject-jobs command.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/catman/a_man/<BR>
+ /usr/share/catman/u_man/</TD>
+ <TD>Man pages (IRIX)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/man/</TD>
+ <TD>Man pages (Compaq Tru64 UNIX, HP-UX, Solaris)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/man/</TD>
+ <TD>Man pages (all others)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/data/</TD>
+ <TD>The location of filter data files.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/data/testprint.ps</TD>
+ <TD>The PostScript test page file.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/fonts/</TD>
+ <TD>The location of PostScript fonts for the PostScript RIP.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/model/</TD>
+ <TD>The location of PostScript Printer Description ("PPD") files and
+ interface scripts that may be used to setup a printer queue.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/pstoraster/</TD>
+ <TD>Other PostScript RIP initialization files.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/pstoraster/Fontmap</TD>
+ <TD>The font mapping file (converts filenames to fontnames)</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/cups/templates/</TD>
+ <TD>The location of HTML template files for the web interfaces.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/usr/share/doc/cups/</TD>
+ <TD>Documentation and web page data for the scheduler.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/var/log/cups/</TD>
+ <TD>The location of scheduler log files.</TD>
+</TR>
+<TR VALIGN="TOP">
+ <TD>/var/spool/cups/</TD>
+ <TD>The location of print files waiting to be printed.</TD>
+</TR>
+</TABLE></CENTER>
+
+
+<H1 ALIGN="RIGHT"><A NAME="FAQ">E - Troubleshooting Common Problems</A></H1>
+
+<P>This appendix covers some of the common problems first-time users
+encounter when installing and configuring CUPS.
+
+<P>Commercial support for CUPS is available from Easy Software Products.
+For more information please contact us at:
+
+<UL>
+
+ <LI>WWW: <A HREF="http://www.easysw.com">
+ <CODE>http://www.easysw.com</CODE></A>
+
+ <LI>EMail: <A HREF="mailto:info@easysw.com">info@easysw.com</A>
+
+ <LI>Telephone (M-F, 9-5 EST): +1.301.373.9600
+
+</UL>
+
+<H2>My Applications Don't See the Available Printers</H2>
+
+<P>Many applications read the <VAR>/etc/printcap</VAR> file to
+get a list of available printers.
+
+<P>The default CUPS configuration creates the
+<VAR>/etc/printcap</VAR> file automatically. To enable or
+disable automatic creation and updating of this file, use the <A
+HREF="#Printcap"><CODE>Printcap</CODE></A> directive described
+in <A HREF="#PRINTING_MANAGEMENT">Chapter 6, "Printing System
+Management"</A>.
+
+<H2>CUPS Doesn't Recognize My Username or Password!</H2>
+
+<P>CUPS will ask you for a UNIX username and password when you perform
+printer administration tasks remotely or via a web browser. The default
+configuration requires that you use the <CODE>root</CODE> username and
+the corresponding password to authenticate the request.
+
+<P>CUPS does not allow you to authenticate an administration request
+with an account that has no password for security reasons. If you do
+not have a password on your <CODE>root</CODE> account then you won't be
+able to add printers remotely or via the web interface!
+
+<!-- NEED 2in -->
+<P>To disable password authentication you need to edit the
+<VAR>/etc/cups/cupsd.conf</VAR> file and comment out the
+lines reading:
+
+<UL><PRE>
+AuthType Basic
+AuthClass System
+</PRE></UL>
+
+<P>for the <VAR>/admin</VAR> location. Then restart the CUPS server as
+described in <A HREF="#PRINTING_MANAGEMENT">Chapter 6, "Printing System
+Management"</A>.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Disabling password checks will allow any local user to
+ change your printer and class configuration, but remote
+ administration from another machine will still not be allowed.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H2><A NAME="ALLOW_REMOTE">I Can't Do Administration Tasks from Another Machine!</A></H2>
+
+<P>The default CUPS configuration limits administration to the local
+machine. To open up access, edit the <VAR>/etc/cups/cupsd.conf</VAR>
+and comment out the lines reading:
+
+<UL><PRE>
+Order deny,allow
+Deny from all
+Allow from 127.0.0.1
+</PRE></UL>
+
+<P>for the <VAR>/admin</VAR> location. Then restart the CUPS server as
+described in <A HREF="#PRINTING_MANAGEMENT">Chapter 6, "Printing System
+Management"</A>.</P>
+
+<CENTER><TABLE WIDTH="80%" BORDER="1" CELLPADDING="5" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>Allowing administration access from all hosts is a potential
+ security risk. Please read <A HREF="#PRINTING_SECURITY">Chapter
+ 6, "Printing System Management"</A> for a description of these
+ risks and ways to minimize them.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 4in -->
+<H2>I Can't Do Administration Tasks from My Web Browser!</H2>
+
+<P>This problem is usually caused by:
+
+<OL>
+
+ <LI>not specifying the correct password for the
+ root account.
+
+ <LI>accessing the CUPS server using the hostname or IP
+ address of the server without enabling remote access for
+ administration functions. This can be corrected by following
+ the instructions in the <A HREF="#ALLOW_REMOTE">"I Can't Do
+ Administration Tasks from Another Machine!"</A> section earlier
+ in this appendix.
+
+ <LI>not setting a password on the root account. CUPS will not
+ authenticate a user account that does not have a password for
+ security reasons.
+
+ <LI>authenticating using an account other than root, but the
+ account you are using is not a member of the system group.
+
+ <LI>configuring CUPS to use Digest authentication, but
+ your web browser does not support Digest authentication.
+
+</OL>
+
+<H2>Connection Refused Messages</H2>
+
+<P>Under normal circumstances, "connection refused" messages for a
+networked printer should be expected from time to time. Most network
+interfaces only allow a single connection to be made at any given time
+(one job at a time) and will refuse access to all other systems while
+the first connection is active. CUPS automatically retries the
+connection once every 30 seconds.
+
+<P>If the problem persists and you are unable to print any jobs to the printer,
+verify that another machine is not maintaining a connection with the printer,
+and that you have selected the proper port or printer name for the printer.
+
+<P>Also, most external print servers will refuse connections if the connected
+printer is turned off or is off-line. Verify that the affected printer is
+turned on and is online.
+
+<H2>Write Error Messages</H2>
+
+<P>If you get "write error" messages on a printer queue the printer
+interface (usually a Hewlett Packard JetDirect interface) has timed out
+and reset the network connection from your workstation.
+
+<P>The error is caused by that startup delay between the initial setup
+of the printer or plotter and the first page of print data that is
+sent.
+
+<!-- NEED 3in -->
+<P>To correct the problem, change the idle timeout on the interface to at least
+180 seconds or 3 minutes. To change the timeout on a Hewlett Packard
+JetDirect interface, type:
+
+<UL><PRE>
+<B>telnet ip-address ENTER</B>
+
+Trying ip-address...
+Connected to ip-address.
+Escape character is `^]'.
+
+Please type [Return] two times, to initialize telnet configuration
+For HELP type "?"
+> <B>idle-timeout: 180 ENTER</B>
+> <B>quit ENTER</B>
+</PRE></UL>
+
+</BODY>
+</HTML>
diff --git a/doc/sdd.html b/doc/sdd.html
new file mode 100644
index 000000000..3e3e6aca5
--- /dev/null
+++ b/doc/sdd.html
@@ -0,0 +1,591 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Software Design Description</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-SDD-1.1">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY>
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Software Design Description</H1></A><BR>
+CUPS-SDD-1.1<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">1 Scope</A></B>
+<UL>
+<LI><A HREF="#1_1">1.1 Identification</A></LI>
+<LI><A HREF="#1_2">1.2 System Overview</A></LI>
+<LI><A HREF="#1_3">1.3 Document Overview</A></LI>
+</UL>
+<B><A HREF="#2">2 References</A></B>
+<UL>
+<LI><A HREF="#2_1">2.1 CUPS Documentation</A></LI>
+<LI><A HREF="#2_2">2.2 Other Documents</A></LI>
+</UL>
+<B><A HREF="#3">3 Design Overview</A></B>
+<UL>
+<LI><A HREF="#3_1">3.1 Backends</A></LI>
+<UL>
+<LI><A HREF="#3_1_1">3.1.1 ipp</A></LI>
+<LI><A HREF="#3_1_2">3.1.2 lpd</A></LI>
+<LI><A HREF="#3_1_3">3.1.3 parallel</A></LI>
+<LI><A HREF="#3_1_4">3.1.4 serial</A></LI>
+<LI><A HREF="#3_1_5">3.1.5 socket</A></LI>
+<LI><A HREF="#3_1_6">3.1.6 usb</A></LI>
+</UL>
+<LI><A HREF="#3_2">3.2 Berkeley Commands</A></LI>
+<UL>
+<LI><A HREF="#3_2_1">3.2.1 lpc</A></LI>
+<LI><A HREF="#3_2_2">3.2.2 lpq</A></LI>
+<LI><A HREF="#3_2_3">3.2.3 lpr</A></LI>
+<LI><A HREF="#3_2_4">3.2.4 lprm</A></LI>
+</UL>
+<LI><A HREF="#3_3">3.3 CGI</A></LI>
+<UL>
+<LI><A HREF="#3_3_1">3.3.1 admin.cgi</A></LI>
+<LI><A HREF="#3_3_2">3.3.2 classes.cgi</A></LI>
+<LI><A HREF="#3_3_3">3.3.3 jobs.cgi</A></LI>
+<LI><A HREF="#3_3_4">3.3.4 printers.cgi</A></LI>
+</UL>
+<LI><A HREF="#3_4">3.4 CUPS Application Programmers Interface</A></LI>
+<UL>
+<LI><A HREF="#3_4_1">3.4.1 Convenience Functions</A></LI>
+<LI><A HREF="#3_4_2">3.4.2 HTTP Functions</A></LI>
+<LI><A HREF="#3_4_3">3.4.3 IPP Functions</A></LI>
+<LI><A HREF="#3_4_4">3.4.4 Language Functions</A></LI>
+<LI><A HREF="#3_4_5">3.4.5 PPD Functions</A></LI>
+</UL>
+<LI><A HREF="#3_5">3.5 CUPS Imaging Library</A></LI>
+<UL>
+<LI><A HREF="#3_5_1">3.5.1 Colorspace Conversion Functions</A></LI>
+<LI><A HREF="#3_5_2">3.5.2 Color Management Functions</A></LI>
+<LI><A HREF="#3_5_3">3.5.3 Image Management Functions</A></LI>
+<LI><A HREF="#3_5_4">3.5.4 Scaling Functions</A></LI>
+<LI><A HREF="#3_5_5">3.5.5 Image File Functions</A></LI>
+<LI><A HREF="#3_5_6">3.5.6 Raster Functions</A></LI>
+</UL>
+<LI><A HREF="#3_6">3.6 Daemons</A></LI>
+<UL>
+<LI><A HREF="#3_6_1">3.6.1 Line Printer Daemon</A></LI>
+<LI><A HREF="#3_6_2">3.6.2 Polling Daemon</A></LI>
+</UL>
+<LI><A HREF="#3_7">3.7 Filters</A></LI>
+<UL>
+<LI><A HREF="#3_7_1">3.7.1 hpgltops</A></LI>
+<LI><A HREF="#3_7_2">3.7.2 imagetops</A></LI>
+<LI><A HREF="#3_7_3">3.7.3 imagetoraster</A></LI>
+<LI><A HREF="#3_7_4">3.7.4 pdftops</A></LI>
+<LI><A HREF="#3_7_5">3.7.5 pstops</A></LI>
+<LI><A HREF="#3_7_6">3.7.6 pstoraster</A></LI>
+<LI><A HREF="#3_7_7">3.7.7 rastertoepson</A></LI>
+<LI><A HREF="#3_7_8">3.7.8 rastertohp</A></LI>
+<LI><A HREF="#3_7_9">3.7.9 texttops</A></LI>
+</UL>
+<LI><A HREF="#3_8">3.8 Scheduler</A></LI>
+<UL>
+<LI><A HREF="#3_8_1">3.8.1 Authorization</A></LI>
+<LI><A HREF="#3_8_2">3.8.2 Classes</A></LI>
+<LI><A HREF="#3_8_3">3.8.3 Client</A></LI>
+<LI><A HREF="#3_8_4">3.8.4 Configuration</A></LI>
+<LI><A HREF="#3_8_5">3.8.5 Devices</A></LI>
+<LI><A HREF="#3_8_6">3.8.6 Directory Services</A></LI>
+<LI><A HREF="#3_8_7">3.8.7 IPP</A></LI>
+<LI><A HREF="#3_8_8">3.8.8 Jobs</A></LI>
+<LI><A HREF="#3_8_9">3.8.9 Logging</A></LI>
+<LI><A HREF="#3_8_10">3.8.10 Main</A></LI>
+<LI><A HREF="#3_8_11">3.8.11 MIME</A></LI>
+<LI><A HREF="#3_8_12">3.8.12 PPDs</A></LI>
+<LI><A HREF="#3_8_13">3.8.13 Printers</A></LI>
+</UL>
+<LI><A HREF="#3_9">3.9 System V Commands</A></LI>
+<UL>
+<LI><A HREF="#3_9_1">3.9.1 accept</A></LI>
+<LI><A HREF="#3_9_2">3.9.2 cancel</A></LI>
+<LI><A HREF="#3_9_3">3.9.3 disable</A></LI>
+<LI><A HREF="#3_9_4">3.9.4 enable</A></LI>
+<LI><A HREF="#3_9_5">3.9.5 lp</A></LI>
+<LI><A HREF="#3_9_6">3.9.6 lpadmin</A></LI>
+<LI><A HREF="#3_9_7">3.9.7 lpinfo</A></LI>
+<LI><A HREF="#3_9_8">3.9.8 lpmove</A></LI>
+<LI><A HREF="#3_9_9">3.9.9 lpoptions</A></LI>
+<LI><A HREF="#3_9_10">3.9.10 lpstat</A></LI>
+<LI><A HREF="#3_9_11">3.9.11 reject</A></LI>
+</UL>
+</UL>
+<B><A HREF="#4">A Glossary</A></B>
+<UL>
+<LI><A HREF="#4_1">A.1 Terms</A></LI>
+<LI><A HREF="#4_2">A.2 Acronyms</A></LI>
+</UL>
+<HR>
+<H1><A NAME="1">1 Scope</A></H1>
+<H2><A NAME="1_1">1.1 Identification</A></H2>
+ This software design description document provides general information
+ on the architecture and coding of the Common UNIX Printing System
+ (&quot;CUPS&quot;) Version 1.1.
+<H2><A NAME="1_2">1.2 System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+<H2><A NAME="1_3">1.3 Document Overview</A></H2>
+ This software design description document is organized into the
+ following sections:
+<UL>
+<LI>1 - Scope</LI>
+<LI>2 - References</LI>
+<LI>3 - Design Overview</LI>
+<LI>A - Glossary</LI>
+</UL>
+<H1><A NAME="2">2 References</A></H1>
+<H2><A NAME="2_1">2.1 CUPS Documentation</A></H2>
+<P>The following CUPS documentation is referenced by this document:</P>
+<UL>
+<LI>CUPS-CMP-1.1: CUPS Configuration Management Plan</LI>
+<LI>CUPS-IDD-1.1: CUPS System Interface Design Description</LI>
+<LI>CUPS-IPP-1.1: CUPS Implementation of IPP</LI>
+<LI>CUPS-SAM-1.1.x: CUPS Software Administrators Manual</LI>
+<LI>CUPS-SDD-1.1: CUPS Software Design Description</LI>
+<LI>CUPS-SPM-1.1.x: CUPS Software Programming Manual</LI>
+<LI>CUPS-SSR-1.1: CUPS Software Security Report</LI>
+<LI>CUPS-STP-1.1: CUPS Software Test Plan</LI>
+<LI>CUPS-SUM-1.1.x: CUPS Software Users Manual</LI>
+<LI>CUPS-SVD-1.1: CUPS Software Version Description</LI>
+</UL>
+<H2><A NAME="2_2">2.2 Other Documents</A></H2>
+<P>The following non-CUPS documents are referenced by this document:</P>
+<UL>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">
+Adobe PostScript Printer Description File Format Specification, Version
+ 4.3.</A></LI>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
+Adobe PostScript Language Reference, Third Edition.</A></LI>
+<LI>IPP: Job and Printer Set Operations</LI>
+<LI>IPP/1.1: Encoding and Transport</LI>
+<LI>IPP/1.1: Implementers Guide</LI>
+<LI>IPP/1.1: Model and Semantics</LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179, Line Printer
+ Daemon Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2567.txt">RFC 2567, Design Goals
+ for an Internet Printing Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2568.txt">RFC 2568, Rationale
+ for the Structure of the Model and Protocol for the Internet Printing
+ Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2569.txt">RFC 2569, Mapping
+ between LPD and IPP Protocols</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616, Hypertext
+ Transfer Protocol -- HTTP/1.1</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617, HTTP
+ Authentication: Basic and Digest Access</A> Authentication</LI>
+</UL>
+<H1><A NAME="3">3 Design Overview</A></H1>
+ CUPS is composed of 9 software sub-systems that operate together to
+ perform common printing tasks:
+<UL>
+<LI>Backends</LI>
+<LI>Berkeley Commands</LI>
+<LI>CGI</LI>
+<LI>CUPS Application Programmers Interface</LI>
+<LI>CUPS Imaging Library</LI>
+<LI>Daemons</LI>
+<LI>Filters</LI>
+<LI>Scheduler</LI>
+<LI>System V Commands</LI>
+</UL>
+<H2><A NAME="3_1">3.1 Backends</A></H2>
+ The backends implement communications over a number of different
+ interfaces. All backends are called with a common set of arguments:
+<UL>
+<LI>Device URI - the Uniform Resource Identifier for the output device
+ (e.g. <CODE>parallel:/dev/plp</CODE>, <CODE>ipp://hostname/resource</CODE>
+).</LI>
+<LI>Job Identifier - the job identifier for this job (integer).</LI>
+<LI>User Name - the user associated with this job (name string).</LI>
+<LI>Title - the title/job-name associated with this job (name string).</LI>
+<LI>Copies - the number of copies required (integer).</LI>
+<LI>Options - the options associated with this job (space separated
+ option strings).</LI>
+<LI>Filename (optional) - the file to print; if this option is not
+ specified, the backend must read the print file from the standard
+ input.</LI>
+</UL>
+<P>Backends are named using the scheme of the URI, so a URI of
+ &quot;ipp://hostname/resource&quot; would be processed by the &quot;ipp&quot; backend.</P>
+<H3><A NAME="3_1_1">3.1.1 ipp</A></H3>
+<P>The ipp backend sends the specified job to a network printer or host
+ using the Internet Printing Protocol. The URI is as specified by the <CODE>
+printer-uri-supported</CODE> attribute from the printer or host.</P>
+<H3><A NAME="3_1_2">3.1.2 lpd</A></H3>
+<P>The lpd backend sends the specified job to a network printer or host
+ using the Line Printer Daemon protocol. The URI is of the form:</P>
+<UL>
+<PRE>lpd://hostname/queue
+</PRE>
+</UL>
+<H3><A NAME="3_1_3">3.1.3 parallel</A></H3>
+<P>The parallel backend sends the specified job to a local printer
+ connected via the specified parallel port device. The URI is of the
+ form:</P>
+<UL>
+<PRE>parallel:/dev/file
+</PRE>
+</UL>
+<H3><A NAME="3_1_4">3.1.4 serial</A></H3>
+<P>The serial backend sends the specified job to a local printer
+ connected via the specified serial port device. The URI is of the form:</P>
+<UL>
+<PRE>serial:/dev/file?option[+option+...]
+</PRE>
+</UL>
+ The options can be any combination of the following:
+<UL>
+<LI><CODE>baud=<I>rate</I></CODE> - Sets the baud rate for the device.</LI>
+<LI><CODE>bits=<I>7 or 8</I></CODE> - Sets the number of data bits.</LI>
+<LI><CODE>parity=<I>even</I></CODE> - Sets even parity checking.</LI>
+<LI><CODE>parity=<I>odd</I></CODE> - Sets odd parity checking.</LI>
+<LI><CODE>parity=<I>none</I></CODE> - Turns parity checking off.</LI>
+<LI><CODE>flow=dtrdsr<I></I></CODE> - Turns DTR/DSR (hardware) flow
+ control on.</LI>
+<LI><CODE>flow=hard<I></I></CODE> - Turns RTS/CTS (hardware) flow
+ control on.</LI>
+<LI><CODE>flow=none<I></I></CODE> - Turns flow control off.</LI>
+<LI><CODE>flow=rtscts<I></I></CODE> - Turns RTS/CTS (hardware) flow
+ control on.</LI>
+<LI><CODE>flow=xonxoff<I></I></CODE> - Turns XON/XOFF (software) flow
+ control on.</LI>
+</UL>
+<H3><A NAME="3_1_5">3.1.5 socket</A></H3>
+<P>The socket backend sends the specified job to a network host using
+ the AppSocket protocol commonly used by Hewlett-Packard and Tektronix
+ printers. The URI is of the form:</P>
+<UL>
+<PRE>socket://hostname[:port]
+</PRE>
+</UL>
+ The default port number is 9100.
+<H3><A NAME="3_1_6">3.1.6 usb</A></H3>
+<P>The usb backend sends the specified job to a local printer connected
+ via the specified usb port device. The URI is of the form:</P>
+<UL>
+<PRE>usb:/dev/file
+</PRE>
+</UL>
+<H2><A NAME="3_2">3.2 Berkeley Commands</A></H2>
+<P>The Berkeley commands provide a simple command-line interface to CUPS
+ to submit and control print jobs. It is provided for compatibility with
+ existing software that is hardcoded to use the Berkeley commands.</P>
+<H3><A NAME="3_2_1">3.2.1 lpc</A></H3>
+ The lpc command allows users and administrators to check the status and
+ control print queues. The version provided with CUPS supports the
+ following commands:
+<UL>
+<LI>quit - Quits the lpc command.</LI>
+<LI>status - Shows the status of printers and jobs in the queue.</LI>
+</UL>
+<H3><A NAME="3_2_2">3.2.2 lpq</A></H3>
+<P>The lpq command shows the current queue status.</P>
+<H3><A NAME="3_2_3">3.2.3 lpr</A></H3>
+<P>The lpr command submits a job for printing. The CUPS version of lpr
+ silently ignores the &quot;i&quot;, &quot;t&quot;, &quot;m&quot;, &quot;h&quot;, and &quot;s&quot; options.</P>
+<H3><A NAME="3_2_4">3.2.4 lprm</A></H3>
+<P>The lprm removes one or more print jobs.</P>
+<H2><A NAME="3_3">3.3 CGI</A></H2>
+<P>The Common Gateway Interface (CGI) programs provide a web-based
+ status interface to monitor the status of printers, classes, and jobs.
+ Each of the CGIs utilize HTML template files that can be customized to
+ provide alternate appearances.</P>
+<H3><A NAME="3_3_1">3.3.1 admin.cgi</A></H3>
+<P>The admin CGI provides administration interfaces for printers and
+ classes. The user can add, modify, delete, start, stop, and configure
+ printers and classes using &quot;wizard&quot; interfaces.</P>
+<H3><A NAME="3_3_2">3.3.2 classes.cgi</A></H3>
+<P>The classes CGI lists the available printer classes and any pending
+ jobs for the class. The user can click on individual classes to limit
+ the display and click on jobs to see the job status.</P>
+<H3><A NAME="3_3_3">3.3.3 jobs.cgi</A></H3>
+<P>The jobs CGI lists the queued print jobs in order of priority. The
+ list can be limited by printer or job.</P>
+<H3><A NAME="3_3_4">3.3.4 printers.cgi</A></H3>
+<P>The printers CGI lists the available printer queues and any pending
+ jobs for the printer. The user can click on individual printers to
+ limit the display and click on jobs to see the job status.</P>
+<H2><A NAME="3_4">3.4 CUPS Application Programmers Interface</A></H2>
+<P>The CUPS Application Programmers Interface (&quot;API&quot;) provides common
+ convenience, HTTP, IPP, language, and PPD functions used by the CUPS
+ software.</P>
+<H3><A NAME="3_4_1">3.4.1 Convenience Functions</A></H3>
+<P>Convenience functions are provided to submit an IPP request, send a
+ print file, cancel a job, get a list of available printers, get a list
+ of available classes, get the default printer or class, get the default
+ server name, get the local username, and get a password string.</P>
+<H3><A NAME="3_4_2">3.4.2 HTTP Functions</A></H3>
+<P>The HTTP functions provide functions to connect to HTTP servers,
+ issue requests, read data from a server, and write data to a server.</P>
+<H3><A NAME="3_4_3">3.4.3 IPP Functions</A></H3>
+<P>The IPP function provide functions to manage IPP request data and
+ attributes, read IPP responses from a server, and write IPP requests to
+ a server.</P>
+<H3><A NAME="3_4_4">3.4.4 Language Functions</A></H3>
+<P>The language functions provide a standard interface for retrieving
+ common textual messages for a particular locale and determining the
+ correct encoding (e.g. US ASCII, UTF-8, ISO-8859-1, etc.)</P>
+<H3><A NAME="3_4_5">3.4.5 PPD Functions</A></H3>
+<P>The PostScript Printer Description functions manage PPD files, select
+ options, check for option conflicts, and emit selected options in the
+ correct order.</P>
+<H2><A NAME="3_5">3.5 CUPS Imaging Library</A></H2>
+<P>The CUPS imaging library provides colorspace conversion, color
+ management, image management, scaling, image file, and raster functions
+ used by the CUPS raster filters.</P>
+<H3><A NAME="3_5_1">3.5.1 Colorspace Conversion Functions</A></H3>
+<P>The colorspace conversion functions handle conversion of grayscale
+ and RGB colors to grayscale, RGB, K, CMY, CMYK, and CMYKcm colorspaces.</P>
+<H3><A NAME="3_5_2">3.5.2 Color Management Functions</A></H3>
+<P>The color management functions handle gamut mapping and density
+ correction. These are integrated with the colorspace conversion
+ functions so that colorspace conversion and color management are
+ processed in a single step.</P>
+<H3><A NAME="3_5_3">3.5.3 Image Management Functions</A></H3>
+<P>The image management functions manage a tiled image database that is
+ swapped to/from disk as needed.</P>
+<H3><A NAME="3_5_4">3.5.4 Scaling Functions</A></H3>
+<P>The scaling functions provide image scaling services using
+ nearest-neighbor sampling and bilinear interpolation as appropriate.</P>
+<H3><A NAME="3_5_5">3.5.5 Image File Functions</A></H3>
+<P>The image file functions handle loading of all image file formats.</P>
+<H3><A NAME="3_5_6">3.5.6 Raster Functions</A></H3>
+<P>The raster functions manage streams of CUPS raster data (described in
+ the Interface Design Document) used by non-PostScript printer drivers
+ and raster filters.</P>
+<H2><A NAME="3_6">3.6 Daemons</A></H2>
+<P>The daemons provide additional network functions for the scheduler.
+ Currently only two daemons are provided with CUPS.</P>
+<H3><A NAME="3_6_1">3.6.1 Line Printer Daemon</A></H3>
+<P>The line printer daemon provides remote LPD client support and is run
+ by the <CODE>inetd(8)</CODE> daemon as needed.</P>
+<H3><A NAME="3_6_2">3.6.2 Polling Daemon</A></H3>
+<P>The polling daemon is used to poll a remote server for a list of
+ available printers and provide it to the scheduler for addition. A
+ separate polling daemon is run by the scheduler for every remote system
+ listed for polling in the scheduler configuration file.</P>
+<H2><A NAME="3_7">3.7 Filters</A></H2>
+<P>The filters implement file conversion services for CUPS. All filters
+ are called with a common set of arguments:</P>
+<UL>
+<LI>Printer name - the name of the destination printer (name string).</LI>
+<LI>Job Identifier - the job identifier for this job (integer).</LI>
+<LI>User Name - the user associated with this job (name string).</LI>
+<LI>Title - the title/job-name associated with this job (name string).</LI>
+<LI>Copies - the number of copies required (integer).</LI>
+<LI>Options - the options associated with this job (space separated
+ option strings).</LI>
+<LI>Filename (optional) - the file to print; if this option is not
+ specified, the filter must read the input file from the standard input.</LI>
+</UL>
+<P>Filters are added to the MIME conversion data file and implement all
+ necessary conversions from one file type to another.</P>
+<H3><A NAME="3_7_1">3.7.1 hpgltops</A></H3>
+<P>The hpgltops filter converts HP-GL/2 files into PostScript.</P>
+<H3><A NAME="3_7_2">3.7.2 imagetops</A></H3>
+<P>The imagetops filter converts image files into PostScript.</P>
+<H3><A NAME="3_7_3">3.7.3 imagetoraster</A></H3>
+<P>The imagetoraster filter converts image files into CUPS raster data.</P>
+<H3><A NAME="3_7_4">3.7.4 pdftops</A></H3>
+<P>The pdftops filter converts PDF files into PostScript.</P>
+<H3><A NAME="3_7_5">3.7.5 pstops</A></H3>
+<P>The pstops filter inserts printer-specific commands from PPD files
+ and performs page filtering as requested by the user.</P>
+<H3><A NAME="3_7_6">3.7.6 pstoraster</A></H3>
+<P>The pstoraster filter converts PostScript program data into CUPS
+ raster data.</P>
+<H3><A NAME="3_7_7">3.7.7 rastertoepson</A></H3>
+<P>The rastertoepson filter handles converting CUPS raster data to ESC/P
+ and supports both color and black-and-white printers.</P>
+<H3><A NAME="3_7_8">3.7.8 rastertohp</A></H3>
+<P>The rastertohp filter handles converting CUPS raster data to HP-PCL
+ and supports both color and black-and-white printers.</P>
+<H3><A NAME="3_7_9">3.7.9 texttops</A></H3>
+<P>The texttops filter converts text files into PostScript.</P>
+<H2><A NAME="3_8">3.8 Scheduler</A></H2>
+<P>The scheduler is a fully-functional HTTP/1.1 and IPP/1.1 server that
+ manages the printers, classes, and jobs in the system. It also handles
+ a simple broadcast-based directory service so that remote print queues
+ and classes can be accessed transparently from the local system.</P>
+<H3><A NAME="3_8_1">3.8.1 Authorization</A></H3>
+<P>The authorization module is responsible for performing access control
+ and authentication for all HTTP and IPP requests entering the system.</P>
+<H3><A NAME="3_8_2">3.8.2 Classes</A></H3>
+<P>The classes module is responsible for managing printer classes in the
+ system. Each class is a collection of local and/or remote printers. The
+ classes module also reads and writes the classes configuration file.</P>
+<H3><A NAME="3_8_3">3.8.3 Client</A></H3>
+<P>The client module is responsible for all HTTP client communications.
+ It handles listening on selected interfaces, accepting connections from
+ prospective clients, processing incoming HTTP requests, and sending
+ HTTP responses to those requests. The client module also is responsible
+ for executing the external CGI programs as needed to support web-based
+ printer, class, and job status monitoring and administration.</P>
+<P>Once authorized, all IPP requests are sent to the IPP module.</P>
+<H3><A NAME="3_8_4">3.8.4 Configuration</A></H3>
+<P>The configuration module is responsible for reading the CUPS
+ configuration file and initializing the appropriate data structures and
+ values. The configuration module also stops CUPS services before
+ reading the configuration file and restarts them after the
+ configuration file has been read.</P>
+<H3><A NAME="3_8_5">3.8.5 Devices</A></H3>
+<P>The devices module is responsible for managing the list of available
+ devices for the CUPS-Get-Devices operation.</P>
+<H3><A NAME="3_8_6">3.8.6 Directory Services</A></H3>
+<P>The directory services module sends and recieves printer state
+ information over a broadcast socket. Remote printers and classes are
+ automatically added to or removed from the local printer and class
+ lists as needed.</P>
+<P>The directory services module can only recieve printer state
+ information over a single UDP port, however it can broadcast to
+ multiple addresses and ports as needed.</P>
+<H3><A NAME="3_8_7">3.8.7 IPP</A></H3>
+<P>The IPP module handles IPP requests and acts accordingly. URI
+ validation is also performed here, as a client can post IPP data to any
+ URI on the server which might sidestep the access control or
+ authentication of the HTTP server.</P>
+<H3><A NAME="3_8_8">3.8.8 Jobs</A></H3>
+<P>The jobs module manages print jobs, starts filter and backend
+ processes for jobs to be printed, and monitors status messages from
+ those filters and backends.</P>
+<H3><A NAME="3_8_9">3.8.9 Logging</A></H3>
+<P>The logging module manages the access, error, and page log files that
+ are generated by the scheduler.</P>
+<H3><A NAME="3_8_10">3.8.10 Main</A></H3>
+<P>The main module is responsible for timing out and dispatching input
+ and output for client connections. It also watches for incoming <CODE>
+SIGHUP</CODE> and <CODE>SIGCHLD</CODE> signals, reloads the server
+ configuration files as needed, and handles child process errors and
+ exits.</P>
+<H3><A NAME="3_8_11">3.8.11 MIME</A></H3>
+<P>The Multimedia Internet Mail Exchange module manages a MIME type and
+ conversion database that supports file typing by extension and content
+ and least-cost file filtering from a source to a destination file type.</P>
+<H3><A NAME="3_8_12">3.8.12 PPDs</A></H3>
+<P>The PPDs module is responsible for managing the list of available PPD
+ files for the CUPS-Get-PPDs operation.</P>
+<H3><A NAME="3_8_13">3.8.13 Printers</A></H3>
+<P>The printers module is responsible for managing printers and PPD
+ files in the system. The printers module also reads and writes the
+ printers configuration file.</P>
+<H2><A NAME="3_9">3.9 System V Commands</A></H2>
+<P>The System V commands provide a robust command-line interface to CUPS
+ to submit and control printers and jobs.</P>
+<H3><A NAME="3_9_1">3.9.1 accept</A></H3>
+<P>The accept command tells the scheduler to accept new jobs for
+ specific printers.</P>
+<H3><A NAME="3_9_2">3.9.2 cancel</A></H3>
+<P>The cancel command tells the scheduler to cancel one or more jobs
+ that are queued for printing.</P>
+<H3><A NAME="3_9_3">3.9.3 disable</A></H3>
+<P>The disable command tells the scheduler to stop printing jobs on the
+ specified printers.</P>
+<H3><A NAME="3_9_4">3.9.4 enable</A></H3>
+<P>The enable command tells the scheduler to start printing jobs on the
+ specified printers.</P>
+<H3><A NAME="3_9_5">3.9.5 lp</A></H3>
+<P>The lp command submits submits files for printing. Unlike the
+ standard System V lp command, a single CUPS lp command will generate a
+ separate job ID for each file that is printed. Also, the Solaris &quot;f&quot;,
+ &quot;H&quot;, &quot;P&quot;, &quot;S&quot;, and &quot;y&quot; options are silently ignored.</P>
+<H3><A NAME="3_9_6">3.9.6 lpadmin</A></H3>
+<P>The lpadmin command manages printer queues and classes. The Solaris
+ &quot;A&quot;, &quot;F&quot;, &quot;I&quot;, &quot;M&quot;, &quot;P&quot;, &quot;Q&quot;, &quot;S&quot;, &quot;T&quot;, &quot;U&quot;, &quot;W&quot;, &quot;f&quot;, &quot;l&quot;, &quot;m&quot;, &quot;o&quot;,
+ &quot;s&quot;, &quot;t&quot;, and &quot;u&quot; options are not supported, and new options &quot;P&quot; (PPD
+ file) and &quot;E&quot; (enable and accept) are provided to configure
+ CUPS-specific features.</P>
+<H3><A NAME="3_9_7">3.9.7 lpinfo</A></H3>
+<P>The lpinfo command lists the available PPD files or devices as
+ selected by the user.</P>
+<H3><A NAME="3_9_8">3.9.8 lpmove</A></H3>
+<P>The lpmove command moves a print job to a new destination.</P>
+<H3><A NAME="3_9_9">3.9.9 lpoptions</A></H3>
+<P>The lpoptions command manages user-defined printers and options.</P>
+<H3><A NAME="3_9_10">3.9.10 lpstat</A></H3>
+<P>The lpstat command lists printers, classes, and jobs as requested by
+ the user.</P>
+<H3><A NAME="3_9_11">3.9.11 reject</A></H3>
+<P>The reject command tells the scheduler not to accept new jobs for
+ specific printers.</P>
+<H1 TYPE="A" VALUE="1"><A NAME="4">A Glossary</A></H1>
+<H2><A NAME="4_1">A.1 Terms</A></H2>
+<DL>
+<DT>C</DT>
+<DD>A computer language.</DD>
+<DT>parallel</DT>
+<DD>Sending or receiving data more than 1 bit at a time.</DD>
+<DT>pipe</DT>
+<DD>A one-way communications channel between two programs.</DD>
+<DT>serial</DT>
+<DD>Sending or receiving data 1 bit at a time.</DD>
+<DT>socket</DT>
+<DD>A two-way network communications channel.</DD>
+</DL>
+<H2><A NAME="4_2">A.2 Acronyms</A></H2>
+<DL>
+<DT>ASCII</DT>
+<DD>American Standard Code for Information Interchange</DD>
+<DT>CUPS</DT>
+<DD>Common UNIX Printing System</DD>
+<DT>ESC/P</DT>
+<DD>EPSON Standard Code for Printers</DD>
+<DT>FTP</DT>
+<DD>File Transfer Protocol</DD>
+<DT>HP-GL</DT>
+<DD>Hewlett-Packard Graphics Language</DD>
+<DT>HP-PCL</DT>
+<DD>Hewlett-Packard Page Control Language</DD>
+<DT>HP-PJL</DT>
+<DD>Hewlett-Packard Printer Job Language</DD>
+<DT>IETF</DT>
+<DD>Internet Engineering Task Force</DD>
+<DT>IPP</DT>
+<DD>Internet Printing Protocol</DD>
+<DT>ISO</DT>
+<DD>International Standards Organization</DD>
+<DT>LPD</DT>
+<DD>Line Printer Daemon</DD>
+<DT>MIME</DT>
+<DD>Multimedia Internet Mail Exchange</DD>
+<DT>PPD</DT>
+<DD>PostScript Printer Description</DD>
+<DT>SMB</DT>
+<DD>Server Message Block</DD>
+<DT>TFTP</DT>
+<DD>Trivial File Transfer Protocol</DD>
+</DL>
+</BODY>
+</HTML>
diff --git a/doc/sdd.pdf b/doc/sdd.pdf
new file mode 100644
index 000000000..dcbded1ee
--- /dev/null
+++ b/doc/sdd.pdf
Binary files differ
diff --git a/doc/sdd.shtml b/doc/sdd.shtml
new file mode 100644
index 000000000..e14ef4c0f
--- /dev/null
+++ b/doc/sdd.shtml
@@ -0,0 +1,564 @@
+<HTML>
+<HEAD>
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-SDD-1.1">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Software Design Description</TITLE>
+</HEAD>
+<BODY>
+
+<H1>Scope</H1>
+
+<H2>Identification</H2>
+
+This software design description document provides general information
+on the architecture and coding of the Common UNIX Printing System
+(&quot;CUPS&quot;) Version 1.1.
+
+<EMBED SRC="system-overview.shtml">
+
+<H2>Document Overview</H2>
+
+This software design description document is organized into the
+following sections:
+
+<UL>
+
+ <LI>1 - Scope
+
+ <LI>2 - References
+
+ <LI>3 - Design Overview
+
+ <LI>A - Glossary
+
+</UL>
+
+<EMBED SRC="references.shtml">
+
+<H1>Design Overview</H1>
+
+CUPS is composed of 9 software sub-systems that operate together to
+perform common printing tasks:
+
+<UL>
+
+ <LI>Backends
+
+ <LI>Berkeley Commands
+
+ <LI>CGI
+
+ <LI>CUPS Application Programmers Interface
+
+ <LI>CUPS Imaging Library
+
+ <LI>Daemons
+
+ <LI>Filters
+
+ <LI>Scheduler
+
+ <LI>System V Commands
+
+</UL>
+
+<H2>Backends</H2>
+
+The backends implement communications over a number of different interfaces.
+All backends are called with a common set of arguments:
+
+<UL>
+
+ <LI>Device URI - the Uniform Resource Identifier for the output device
+ (e.g. <CODE>parallel:/dev/plp</CODE>,
+ <CODE>ipp://hostname/resource</CODE>).
+
+ <LI>Job Identifier - the job identifier for this job (integer).
+
+ <LI>User Name - the user associated with this job (name string).
+
+ <LI>Title - the title/job-name associated with this job (name string).
+
+ <LI>Copies - the number of copies required (integer).
+
+ <LI>Options - the options associated with this job (space separated
+ option strings).
+
+ <LI>Filename (optional) - the file to print; if this option is not
+ specified, the backend must read the print file from the standard
+ input.
+
+</UL>
+
+<P>Backends are named using the scheme of the URI, so a URI of
+"ipp://hostname/resource" would be processed by the "ipp" backend.
+
+<H3>ipp</H3>
+
+<P>The ipp backend sends the specified job to a network printer or host using
+the Internet Printing Protocol. The URI is as specified by the
+<CODE>printer-uri-supported</CODE> attribute from the printer or host.
+
+<H3>lpd</H3>
+
+<P>The lpd backend sends the specified job to a network printer or host using
+the Line Printer Daemon protocol. The URI is of the form:
+
+<UL><PRE>lpd://hostname/queue
+</PRE></UL>
+
+<H3>parallel</H3>
+
+<P>The parallel backend sends the specified job to a local printer connected
+via the specified parallel port device. The URI is of the form:
+
+<UL><PRE>parallel:/dev/file
+</PRE></UL>
+
+<H3>serial</H3>
+
+<P>The serial backend sends the specified job to a local printer connected
+via the specified serial port device. The URI is of the form:
+
+<UL><PRE>serial:/dev/file?option[+option+...]
+</PRE></UL>
+
+The options can be any combination of the following:
+
+<UL>
+
+ <LI><CODE>baud=<I>rate</I></CODE> - Sets the baud rate for the device.
+
+ <LI><CODE>bits=<I>7 or 8</I></CODE> - Sets the number of data bits.
+
+ <LI><CODE>parity=<I>even</I></CODE> - Sets even parity checking.
+
+ <LI><CODE>parity=<I>odd</I></CODE> - Sets odd parity checking.
+
+ <LI><CODE>parity=<I>none</I></CODE> - Turns parity checking off.
+
+ <LI><CODE>flow=dtrdsr<I></I></CODE> - Turns DTR/DSR (hardware) flow
+ control on.
+
+ <LI><CODE>flow=hard<I></I></CODE> - Turns RTS/CTS
+ (hardware) flow control on.
+
+ <LI><CODE>flow=none<I></I></CODE> - Turns flow control off.
+
+ <LI><CODE>flow=rtscts<I></I></CODE> - Turns RTS/CTS
+ (hardware) flow control on.
+
+ <LI><CODE>flow=xonxoff<I></I></CODE> - Turns XON/XOFF
+ (software) flow control on.
+
+</UL>
+
+<H3>socket</H3>
+
+<P>The socket backend sends the specified job to a network host using the
+AppSocket protocol commonly used by Hewlett-Packard and Tektronix
+printers. The URI is of the form:
+
+<UL><PRE>socket://hostname[:port]
+</PRE></UL>
+
+The default port number is 9100.
+
+<H3>usb</H3>
+
+<P>The usb backend sends the specified job to a local printer connected
+via the specified usb port device. The URI is of the form:
+
+<UL><PRE>usb:/dev/file
+</PRE></UL>
+
+<H2>Berkeley Commands</H2>
+
+<P>The Berkeley commands provide a simple command-line interface to CUPS
+to submit and control print jobs. It is provided for compatibility with
+existing software that is hardcoded to use the Berkeley commands.
+
+<H3>lpc</H3>
+
+The lpc command allows users and administrators to check the status and
+control print queues. The version provided with CUPS supports the following
+commands:
+
+<UL>
+
+ <LI>quit - Quits the lpc command.
+
+ <LI>status - Shows the status of printers and jobs in the queue.
+
+</UL>
+
+<H3>lpq</H3>
+
+<P>The lpq command shows the current queue status.
+
+<H3>lpr</H3>
+
+<P>The lpr command submits a job for printing. The CUPS version of lpr silently
+ignores the "i", "t", "m", "h", and "s" options.
+
+<H3>lprm</H3>
+
+<P>The lprm removes one or more print jobs.
+
+<H2>CGI</H2>
+
+<P>The Common Gateway Interface (CGI) programs provide a web-based
+status interface to monitor the status of printers, classes, and jobs.
+Each of the CGIs utilize HTML template files that can be customized to
+provide alternate appearances.
+
+<H3>admin.cgi</H3>
+
+<P>The admin CGI provides administration interfaces for printers and
+classes. The user can add, modify, delete, start, stop, and configure
+printers and classes using "wizard" interfaces.
+
+<H3>classes.cgi</H3>
+
+<P>The classes CGI lists the available printer classes and any pending
+jobs for the class. The user can click on individual classes to limit
+the display and click on jobs to see the job status.
+
+<H3>jobs.cgi</H3>
+
+<P>The jobs CGI lists the queued print jobs in order of priority. The
+list can be limited by printer or job.
+
+<H3>printers.cgi</H3>
+
+<P>The printers CGI lists the available printer queues and any pending
+jobs for the printer. The user can click on individual printers to
+limit the display and click on jobs to see the job status.
+
+<H2>CUPS Application Programmers Interface</H2>
+
+<P>The CUPS Application Programmers Interface ("API") provides common
+convenience, HTTP, IPP, language, and PPD functions used by the CUPS
+software.
+
+<H3>Convenience Functions</H3>
+
+<P>Convenience functions are provided to submit an IPP request, send a
+print file, cancel a job, get a list of available printers, get a list
+of available classes, get the default printer or class, get the default
+server name, get the local username, and get a password string.
+
+<H3>HTTP Functions</H3>
+
+<P>The HTTP functions provide functions to connect to HTTP servers,
+issue requests, read data from a server, and write data to a server.
+
+<H3>IPP Functions</H3>
+
+<P>The IPP function provide functions to manage IPP request data and
+attributes, read IPP responses from a server, and write IPP requests to
+a server.
+
+<H3>Language Functions</H3>
+
+<P>The language functions provide a standard interface for retrieving
+common textual messages for a particular locale and determining the
+correct encoding (e.g. US ASCII, UTF-8, ISO-8859-1, etc.)
+
+<H3>PPD Functions</H3>
+
+<P>The PostScript Printer Description functions manage PPD files,
+select options, check for option conflicts, and emit selected options
+in the correct order.
+
+<H2>CUPS Imaging Library</H2>
+
+<P>The CUPS imaging library provides colorspace conversion, color
+management, image management, scaling, image file, and raster functions
+used by the CUPS raster filters.
+
+<H3>Colorspace Conversion Functions</H3>
+
+<P>The colorspace conversion functions handle conversion of grayscale
+and RGB colors to grayscale, RGB, K, CMY, CMYK, and CMYKcm colorspaces.
+
+<H3>Color Management Functions</H3>
+
+<P>The color management functions handle gamut mapping and density
+correction. These are integrated with the colorspace conversion
+functions so that colorspace conversion and color management are
+processed in a single step.
+
+<H3>Image Management Functions</H3>
+
+<P>The image management functions manage a tiled image database that is
+swapped to/from disk as needed.
+
+<H3>Scaling Functions</H3>
+
+<P>The scaling functions provide image scaling services using
+nearest-neighbor sampling and bilinear interpolation as appropriate.
+
+<H3>Image File Functions</H3>
+
+<P>The image file functions handle loading of all image file formats.
+
+<H3>Raster Functions</H3>
+
+<P>The raster functions manage streams of CUPS raster data (described
+in the Interface Design Document) used by non-PostScript printer
+drivers and raster filters.
+
+<H2>Daemons</H2>
+
+<P>The daemons provide additional network functions for the scheduler.
+Currently only two daemons are provided with CUPS.
+
+<H3>Line Printer Daemon</H3>
+
+<P>The line printer daemon provides remote LPD client support and is
+run by the <CODE>inetd(8)</CODE> daemon as needed.
+
+<H3>Polling Daemon</H3>
+
+<P>The polling daemon is used to poll a remote server for a list of
+available printers and provide it to the scheduler for addition. A
+separate polling daemon is run by the scheduler for every remote
+system listed for polling in the scheduler configuration file.
+
+<H2>Filters</H2>
+
+<P>The filters implement file conversion services for CUPS. All filters
+are called with a common set of arguments:
+
+<UL>
+
+ <LI>Printer name - the name of the destination printer (name string).
+
+ <LI>Job Identifier - the job identifier for this job (integer).
+
+ <LI>User Name - the user associated with this job (name string).
+
+ <LI>Title - the title/job-name associated with this job (name string).
+
+ <LI>Copies - the number of copies required (integer).
+
+ <LI>Options - the options associated with this job (space separated
+ option strings).
+
+ <LI>Filename (optional) - the file to print; if this option is not
+ specified, the filter must read the input file from the standard
+ input.
+
+</UL>
+
+<P>Filters are added to the MIME conversion data file and implement all
+necessary conversions from one file type to another.
+
+<H3>hpgltops</H3>
+
+<P>The hpgltops filter converts HP-GL/2 files into PostScript.
+
+<H3>imagetops</H3>
+
+<P>The imagetops filter converts image files into PostScript.
+
+<H3>imagetoraster</H3>
+
+<P>The imagetoraster filter converts image files into CUPS raster data.
+
+<H3>pdftops</H3>
+
+<P>The pdftops filter converts PDF files into PostScript.
+
+<H3>pstops</H3>
+
+<P>The pstops filter inserts printer-specific commands from PPD files and
+performs page filtering as requested by the user.
+
+<H3>pstoraster</H3>
+
+<P>The pstoraster filter converts PostScript program data into CUPS
+raster data.
+
+<H3>rastertoepson</H3>
+
+<P>The rastertoepson filter handles converting CUPS raster data to
+ESC/P and supports both color and black-and-white printers.
+
+<H3>rastertohp</H3>
+
+<P>The rastertohp filter handles converting CUPS raster data to HP-PCL
+and supports both color and black-and-white printers.
+
+<H3>texttops</H3>
+
+<P>The texttops filter converts text files into PostScript.
+
+<H2>Scheduler</H2>
+
+<P>The scheduler is a fully-functional HTTP/1.1 and IPP/1.1 server that
+manages the printers, classes, and jobs in the system. It also handles
+a simple broadcast-based directory service so that remote print queues
+and classes can be accessed transparently from the local system.
+
+<H3>Authorization</H3>
+
+<P>The authorization module is responsible for performing access
+control and authentication for all HTTP and IPP requests entering the
+system.
+
+<H3>Classes</H3>
+
+<P>The classes module is responsible for managing printer classes in
+the system. Each class is a collection of local and/or remote
+printers. The classes module also reads and writes the classes
+configuration file.
+
+<H3>Client</H3>
+
+<P>The client module is responsible for all HTTP client
+communications. It handles listening on selected interfaces, accepting
+connections from prospective clients, processing incoming HTTP
+requests, and sending HTTP responses to those requests. The client
+module also is responsible for executing the external CGI programs as
+needed to support web-based printer, class, and job status monitoring
+and administration.
+
+<P>Once authorized, all IPP requests are sent to the IPP module.
+
+<H3>Configuration</H3>
+
+<P>The configuration module is responsible for reading the CUPS
+configuration file and initializing the appropriate data structures and
+values. The configuration module also stops CUPS services before
+reading the configuration file and restarts them after the
+configuration file has been read.
+
+<H3>Devices</H3>
+
+<P>The devices module is responsible for managing the list of available
+devices for the CUPS-Get-Devices operation.
+
+<H3>Directory Services</H3>
+
+<P>The directory services module sends and recieves printer state
+information over a broadcast socket. Remote printers and classes are
+automatically added to or removed from the local printer and class
+lists as needed.
+
+<P>The directory services module can only recieve printer state information
+over a single UDP port, however it can broadcast to multiple addresses and
+ports as needed.
+
+<H3>IPP</H3>
+
+<P>The IPP module handles IPP requests and acts accordingly. URI
+validation is also performed here, as a client can post IPP data to any
+URI on the server which might sidestep the access control or
+authentication of the HTTP server.
+
+<H3>Jobs</H3>
+
+<P>The jobs module manages print jobs, starts filter and backend
+processes for jobs to be printed, and monitors status messages from
+those filters and backends.
+
+<H3>Logging</H3>
+
+<P>The logging module manages the access, error, and page log files
+that are generated by the scheduler.
+
+<H3>Main</H3>
+
+<P>The main module is responsible for timing out and dispatching input
+and output for client connections. It also watches for incoming
+<CODE>SIGHUP</CODE> and <CODE>SIGCHLD</CODE> signals, reloads the
+server configuration files as needed, and handles child process errors
+and exits.
+
+<H3>MIME</H3>
+
+<P>The Multimedia Internet Mail Exchange module manages a MIME type and
+conversion database that supports file typing by extension and content
+and least-cost file filtering from a source to a destination file type.
+
+<H3>PPDs</H3>
+
+<P>The PPDs module is responsible for managing the list of available
+PPD files for the CUPS-Get-PPDs operation.
+
+<H3>Printers</H3>
+
+<P>The printers module is responsible for managing printers and PPD
+files in the system. The printers module also reads and writes the
+printers configuration file.
+
+<H2>System V Commands</H2>
+
+<P>The System V commands provide a robust command-line interface to
+CUPS to submit and control printers and jobs.
+
+<H3>accept</H3>
+
+<P>The accept command tells the scheduler to accept new jobs for specific
+printers.
+
+<H3>cancel</H3>
+
+<P>The cancel command tells the scheduler to cancel one or more jobs that are
+queued for printing.
+
+<H3>disable</H3>
+
+<P>The disable command tells the scheduler to stop printing jobs on the
+specified printers.
+
+<H3>enable</H3>
+
+<P>The enable command tells the scheduler to start printing jobs on the
+specified printers.
+
+<H3>lp</H3>
+
+<P>The lp command submits submits files for printing. Unlike the standard
+System V lp command, a single CUPS lp command will generate a separate
+job ID for each file that is printed. Also, the Solaris "f", "H", "P", "S",
+and "y" options are silently ignored.
+
+<H3>lpadmin</H3>
+
+<P>The lpadmin command manages printer queues and classes. The Solaris
+"A", "F", "I", "M", "P", "Q", "S", "T", "U", "W", "f", "l", "m", "o",
+"s", "t", and "u" options are not supported, and new options "P" (PPD
+file) and "E" (enable and accept) are provided to configure
+CUPS-specific features.
+
+<H3>lpinfo</H3>
+
+<P>The lpinfo command lists the available PPD files or devices as selected
+by the user.
+
+<H3>lpmove</H3>
+
+<P>The lpmove command moves a print job to a new destination.
+
+<H3>lpoptions</H3>
+
+<P>The lpoptions command manages user-defined printers and options.
+
+<H3>lpstat</H3>
+
+<P>The lpstat command lists printers, classes, and jobs as requested by the
+user.
+
+<H3>reject</H3>
+
+<P>The reject command tells the scheduler not to accept new jobs for specific
+printers.
+
+<EMBED SRC="glossary.shtml">
+
+</BODY>
+</HTML>
diff --git a/doc/spm.html b/doc/spm.html
new file mode 100644
index 000000000..4f7d950d3
--- /dev/null
+++ b/doc/spm.html
@@ -0,0 +1,8920 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Software Programmers Manual</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-SPM-1.1.16">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY BGCOLOR="#ffffff">
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Software Programmers Manual</H1></A><BR>
+CUPS-SPM-1.1.16<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">Preface</A></B>
+<UL>
+<LI><A HREF="#1_1">System Overview</A></LI>
+<LI><A HREF="#1_2">Document Overview</A></LI>
+<LI><A HREF="#1_3">Notation Conventions</A></LI>
+<LI><A HREF="#1_4">Abbreviations</A></LI>
+<LI><A HREF="#1_5">Other References</A></LI>
+</UL>
+<B><A HREF="#OVERVIEW">1 - Printing System Overview</A></B>
+<UL>
+<LI><A HREF="#2_1">The Printing Problem</A></LI>
+<LI><A HREF="#2_2">The Technology</A></LI>
+<LI><A HREF="#2_3">Jobs</A></LI>
+<LI><A HREF="#2_4">Classes</A></LI>
+<LI><A HREF="#2_5">Filters</A></LI>
+<LI><A HREF="#2_6">Backends</A></LI>
+<LI><A HREF="#2_7">Printer Drivers</A></LI>
+<LI><A HREF="#2_8">Networking</A></LI>
+</UL>
+<B><A HREF="#CUPS_API">2 - The CUPS API</A></B>
+<UL>
+<LI><A HREF="#3_1">The CUPS API Library</A></LI>
+<UL>
+<LI><A HREF="#3_1_1">Detecting the CUPS API Library in GNU Autoconf</A></LI>
+</UL>
+<LI><A HREF="#3_2">Printing Services</A></LI>
+<UL>
+<LI><A HREF="#3_2_1">Include Files</A></LI>
+<LI><A HREF="#3_2_2">Printing a File</A></LI>
+<LI><A HREF="#3_2_3">Printing Multiple Files</A></LI>
+<LI><A HREF="#3_2_4">Cancelling Jobs</A></LI>
+<LI><A HREF="#3_2_5">Getting the Available Printers and Classes</A></LI>
+<LI><A HREF="#3_2_6">Printing with Options</A></LI>
+<LI><A HREF="#3_2_7">Setting Printer Options</A></LI>
+<LI><A HREF="#3_2_8">Getting Errors</A></LI>
+<LI><A HREF="#3_2_9">Passwords and Authentication</A></LI>
+</UL>
+<LI><A HREF="#3_3">PPD Services</A></LI>
+<UL>
+<LI><A HREF="#3_3_1">Include Files</A></LI>
+<LI><A HREF="#3_3_2">Getting a PPD File for a Printer</A></LI>
+<LI><A HREF="#3_3_3">Loading a PPD File</A></LI>
+<LI><A HREF="#3_3_4">Freeing PPD File Information</A></LI>
+<LI><A HREF="#3_3_5">The PPD File Structure</A></LI>
+<LI><A HREF="#3_3_6">Marking Options</A></LI>
+<LI><A HREF="#3_3_7">Checking for Conflicts</A></LI>
+</UL>
+</UL>
+<B><A HREF="#WRITING_FILTERS">3 - Writing Filters</A></B>
+<UL>
+<LI><A HREF="#4_1">Overview</A></LI>
+<UL>
+<LI><A HREF="#4_1_1">Security Considerations</A></LI>
+<LI><A HREF="#4_1_2">Users and Groups</A></LI>
+<LI><A HREF="#4_1_3">Temporary Files</A></LI>
+<LI><A HREF="#4_1_4">Sending Messages to the User</A></LI>
+<LI><A HREF="#4_1_5">Page Accounting</A></LI>
+<LI><A HREF="#4_1_6">Command-Line Arguments</A></LI>
+<LI><A HREF="#4_1_7">Copy Generation</A></LI>
+<LI><A HREF="#4_1_8">Environment Variables</A></LI>
+</UL>
+<LI><A HREF="#4_2">Dissecting the HP-GL/2 Filter</A></LI>
+<UL>
+<LI><A HREF="#4_2_1">Initializing the Filter</A></LI>
+</UL>
+<LI><A HREF="#4_3">PostScript Output</A></LI>
+</UL>
+<B><A HREF="#WRITING_DRIVERS">4 - Writing Printer Drivers</A></B>
+<UL>
+<LI><A HREF="#5_1">Overview</A></LI>
+<UL>
+<LI><A HREF="#5_1_1">CUPS Raster Data</A></LI>
+<LI><A HREF="#5_1_2">Page Accounting</A></LI>
+<LI><A HREF="#5_1_3">Color Management</A></LI>
+<LI><A HREF="#5_1_4">Device and Bitmap Variables</A></LI>
+</UL>
+<LI><A HREF="#5_2">Dissecting the HP-PCL Driver</A></LI>
+<UL>
+<LI><A HREF="#5_2_1">PPD Files</A></LI>
+<LI><A HREF="#5_2_2">Reading Raster Data</A></LI>
+</UL>
+</UL>
+<B><A HREF="#WRITING_BACKENDS">5 - Writing Backends</A></B>
+<UL>
+<LI><A HREF="#6_1">Overview</A></LI>
+<UL>
+<LI><A HREF="#6_1_1">Security Considerations</A></LI>
+<LI><A HREF="#6_1_2">Command-Line Arguments</A></LI>
+<LI><A HREF="#6_1_3">Copy Generation</A></LI>
+<LI><A HREF="#6_1_4">Page Accounting</A></LI>
+<LI><A HREF="#6_1_5">Exclusive Access</A></LI>
+<LI><A HREF="#6_1_6">Retries</A></LI>
+</UL>
+<LI><A HREF="#6_2">Dissecting the Serial Port Backend</A></LI>
+<UL>
+<LI><A HREF="#6_2_1">Supporting Device Discovery</A></LI>
+<LI><A HREF="#6_2_2">Opening the Serial Port</A></LI>
+<LI><A HREF="#6_2_3">Writing Data to the Port</A></LI>
+<LI><A HREF="#6_2_4">Finishing Up</A></LI>
+</UL>
+</UL>
+<B><A HREF="#LICENSE">A - Software License Agreement</A></B>
+<UL>
+<LI><A HREF="#7_1">Common UNIX Printing System License Agreement</A></LI>
+<UL>
+<LI><A HREF="#7_1_1">Introduction</A></LI>
+<LI><A HREF="#7_1_2">License Exceptions</A></LI>
+<LI><A HREF="#7_1_3">Trademarks</A></LI>
+<LI><A HREF="#7_1_4">Binary Distribution Rights</A></LI>
+<LI><A HREF="#7_1_5">Support</A></LI>
+</UL>
+<LI><A HREF="#7_2">GNU GENERAL PUBLIC LICENSE</A></LI>
+<LI><A HREF="#7_3">GNU LIBRARY GENERAL PUBLIC LICENSE</A></LI>
+</UL>
+<B><A HREF="#CONSTANTS">B - Constants</A></B>
+<UL>
+<LI><A HREF="#8_1">CUPS Constants</A></LI>
+<UL>
+<LI><A HREF="#8_1_1">Version Number</A></LI>
+<LI><A HREF="#8_1_2">Printer Capabilities</A></LI>
+<LI><A HREF="#8_1_3">Encodings</A></LI>
+</UL>
+<LI><A HREF="#8_2">HTTP Constants</A></LI>
+<UL>
+<LI><A HREF="#8_2_1">Limits</A></LI>
+<LI><A HREF="#8_2_2">Status Codes</A></LI>
+<LI><A HREF="#8_2_3">Fields</A></LI>
+</UL>
+<LI><A HREF="#8_3">IPP Constants</A></LI>
+<UL>
+<LI><A HREF="#8_3_1">Limits</A></LI>
+<LI><A HREF="#8_3_2">Tags</A></LI>
+<LI><A HREF="#8_3_3">Resolution Units</A></LI>
+<LI><A HREF="#8_3_4">Finishings</A></LI>
+<LI><A HREF="#8_3_5">Orientations</A></LI>
+<LI><A HREF="#8_3_6">Qualities</A></LI>
+<LI><A HREF="#8_3_7">Job States</A></LI>
+<LI><A HREF="#8_3_8">Printer States</A></LI>
+<LI><A HREF="#8_3_9">Operations</A></LI>
+<LI><A HREF="#8_3_10">Status Codes</A></LI>
+</UL>
+<LI><A HREF="#8_4">PPD Constants</A></LI>
+<UL>
+<LI><A HREF="#8_4_1">PPD Format Version</A></LI>
+<LI><A HREF="#8_4_2">PPD User-Interface Types</A></LI>
+<LI><A HREF="#8_4_3">PPD Sections</A></LI>
+<LI><A HREF="#8_4_4">PPD Colorspaces</A></LI>
+</UL>
+<LI><A HREF="#8_5">Raster Constants</A></LI>
+<UL>
+<LI><A HREF="#8_5_1">Raster Sync Words</A></LI>
+<LI><A HREF="#8_5_2">Raster Stream Modes</A></LI>
+<LI><A HREF="#8_5_3">Raster Boolean Constants</A></LI>
+<LI><A HREF="#8_5_4">Raster Jog Values</A></LI>
+<LI><A HREF="#8_5_5">Raster Orientation Values</A></LI>
+<LI><A HREF="#8_5_6">Raster CutMedia Values</A></LI>
+<LI><A HREF="#8_5_7">Raster AdvanceMedia Values</A></LI>
+<LI><A HREF="#8_5_8">Raster LeadingEdge Values</A></LI>
+<LI><A HREF="#8_5_9">Raster Color Order Values</A></LI>
+<LI><A HREF="#8_5_10">Raster Colorspace Values</A></LI>
+</UL>
+</UL>
+<B><A HREF="#STRUCTURES">C - Structures</A></B>
+<UL>
+<LI><A HREF="#9_1">CUPS Structures</A></LI>
+<UL>
+<LI><A HREF="#cups_dest_t">CUPS Destinations</A></LI>
+<LI><A HREF="#cups_job_t">CUPS Jobs</A></LI>
+<LI><A HREF="#cups_lang_t">CUPS Messages</A></LI>
+<LI><A HREF="#cups_option_t">CUPS Options</A></LI>
+</UL>
+<LI><A HREF="#9_2">Networking Structures</A></LI>
+<UL>
+<LI><A HREF="#http_t">HTTP State</A></LI>
+<LI><A HREF="#ipp_t">IPP State</A></LI>
+</UL>
+<LI><A HREF="#9_3">Raster Structures</A></LI>
+<UL>
+<LI><A HREF="#cups_raster_header_t">Raster Page Header</A></LI>
+</UL>
+</UL>
+<B><A HREF="#FUNCTIONS">D - Functions</A></B>
+<UL>
+<LI><A HREF="#cupsAddDest">cupsAddDest()</A></LI>
+<UL>
+<LI><A HREF="#10_1_1">Usage</A></LI>
+<LI><A HREF="#10_1_2">Arguments</A></LI>
+<LI><A HREF="#10_1_3">Returns</A></LI>
+<LI><A HREF="#10_1_4">Description</A></LI>
+<LI><A HREF="#10_1_5">Example</A></LI>
+<LI><A HREF="#10_1_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsAddOption">cupsAddOption()</A></LI>
+<UL>
+<LI><A HREF="#10_2_1">Usage</A></LI>
+<LI><A HREF="#10_2_2">Arguments</A></LI>
+<LI><A HREF="#10_2_3">Returns</A></LI>
+<LI><A HREF="#10_2_4">Description</A></LI>
+<LI><A HREF="#10_2_5">Example</A></LI>
+<LI><A HREF="#10_2_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsCancelJob">cupsCancelJob()</A></LI>
+<UL>
+<LI><A HREF="#10_3_1">Usage</A></LI>
+<LI><A HREF="#10_3_2">Arguments</A></LI>
+<LI><A HREF="#10_3_3">Returns</A></LI>
+<LI><A HREF="#10_3_4">Description</A></LI>
+<LI><A HREF="#10_3_5">Example</A></LI>
+<LI><A HREF="#10_3_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsDoFileRequest">cupsDoFileRequest()</A></LI>
+<UL>
+<LI><A HREF="#10_4_1">Usage</A></LI>
+<LI><A HREF="#10_4_2">Arguments</A></LI>
+<LI><A HREF="#10_4_3">Returns</A></LI>
+<LI><A HREF="#10_4_4">Description</A></LI>
+<LI><A HREF="#10_4_5">Example</A></LI>
+<LI><A HREF="#10_4_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsDoRequest">cupsDoRequest()</A></LI>
+<UL>
+<LI><A HREF="#10_5_1">Usage</A></LI>
+<LI><A HREF="#10_5_2">Arguments</A></LI>
+<LI><A HREF="#10_5_3">Returns</A></LI>
+<LI><A HREF="#10_5_4">Description</A></LI>
+<LI><A HREF="#10_5_5">Example</A></LI>
+<LI><A HREF="#10_5_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsEncodeOptions">cupsEncodeOptions()</A></LI>
+<UL>
+<LI><A HREF="#10_6_1">Usage</A></LI>
+<LI><A HREF="#10_6_2">Arguments</A></LI>
+<LI><A HREF="#10_6_3">Description</A></LI>
+<LI><A HREF="#10_6_4">Example</A></LI>
+<LI><A HREF="#10_6_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsEncryption">cupsEncryption()</A></LI>
+<UL>
+<LI><A HREF="#10_7_1">Usage</A></LI>
+<LI><A HREF="#10_7_2">Returns</A></LI>
+<LI><A HREF="#10_7_3">Description</A></LI>
+<LI><A HREF="#10_7_4">Example</A></LI>
+<LI><A HREF="#10_7_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsFreeDests">cupsFreeDests()</A></LI>
+<UL>
+<LI><A HREF="#10_8_1">Usage</A></LI>
+<LI><A HREF="#10_8_2">Arguments</A></LI>
+<LI><A HREF="#10_8_3">Description</A></LI>
+<LI><A HREF="#10_8_4">Example</A></LI>
+<LI><A HREF="#10_8_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsFreeJobs">cupsFreeJobs()</A></LI>
+<UL>
+<LI><A HREF="#10_9_1">Usage</A></LI>
+<LI><A HREF="#10_9_2">Arguments</A></LI>
+<LI><A HREF="#10_9_3">Description</A></LI>
+<LI><A HREF="#10_9_4">Example</A></LI>
+<LI><A HREF="#10_9_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsFreeOptions">cupsFreeOptions()</A></LI>
+<UL>
+<LI><A HREF="#10_10_1">Usage</A></LI>
+<LI><A HREF="#10_10_2">Arguments</A></LI>
+<LI><A HREF="#10_10_3">Description</A></LI>
+<LI><A HREF="#10_10_4">Example</A></LI>
+<LI><A HREF="#10_10_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsGetClasses">cupsGetClasses()</A></LI>
+<UL>
+<LI><A HREF="#10_11_1">Usage</A></LI>
+<LI><A HREF="#10_11_2">Arguments</A></LI>
+<LI><A HREF="#10_11_3">Returns</A></LI>
+<LI><A HREF="#10_11_4">Description</A></LI>
+<LI><A HREF="#10_11_5">Example</A></LI>
+<LI><A HREF="#10_11_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsGetDefault">cupsGetDefault()</A></LI>
+<UL>
+<LI><A HREF="#10_12_1">Usage</A></LI>
+<LI><A HREF="#10_12_2">Returns</A></LI>
+<LI><A HREF="#10_12_3">Description</A></LI>
+<LI><A HREF="#10_12_4">Example</A></LI>
+<LI><A HREF="#10_12_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsGetDest">cupsGetDest()</A></LI>
+<UL>
+<LI><A HREF="#10_13_1">Usage</A></LI>
+<LI><A HREF="#10_13_2">Arguments</A></LI>
+<LI><A HREF="#10_13_3">Returns</A></LI>
+<LI><A HREF="#10_13_4">Description</A></LI>
+<LI><A HREF="#10_13_5">Example</A></LI>
+<LI><A HREF="#10_13_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsGetDests">cupsGetDests()</A></LI>
+<UL>
+<LI><A HREF="#10_14_1">Usage</A></LI>
+<LI><A HREF="#10_14_2">Arguments</A></LI>
+<LI><A HREF="#10_14_3">Returns</A></LI>
+<LI><A HREF="#10_14_4">Description</A></LI>
+<LI><A HREF="#10_14_5">Example</A></LI>
+<LI><A HREF="#10_14_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsGetJobs">cupsGetJobs()</A></LI>
+<UL>
+<LI><A HREF="#10_15_1">Usage</A></LI>
+<LI><A HREF="#10_15_2">Arguments</A></LI>
+<LI><A HREF="#10_15_3">Returns</A></LI>
+<LI><A HREF="#10_15_4">Description</A></LI>
+<LI><A HREF="#10_15_5">Example</A></LI>
+<LI><A HREF="#10_15_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsGetOption">cupsGetOption()</A></LI>
+<UL>
+<LI><A HREF="#10_16_1">Usage</A></LI>
+<LI><A HREF="#10_16_2">Arguments</A></LI>
+<LI><A HREF="#10_16_3">Returns</A></LI>
+<LI><A HREF="#10_16_4">Description</A></LI>
+<LI><A HREF="#10_16_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsGetPassword">cupsGetPassword()</A></LI>
+<UL>
+<LI><A HREF="#10_17_1">Usage</A></LI>
+<LI><A HREF="#10_17_2">Arguments</A></LI>
+<LI><A HREF="#10_17_3">Returns</A></LI>
+<LI><A HREF="#10_17_4">Description</A></LI>
+<LI><A HREF="#10_17_5">Example</A></LI>
+<LI><A HREF="#10_17_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsGetPPD">cupsGetPPD()</A></LI>
+<UL>
+<LI><A HREF="#10_18_1">Usage</A></LI>
+<LI><A HREF="#10_18_2">Arguments</A></LI>
+<LI><A HREF="#10_18_3">Returns</A></LI>
+<LI><A HREF="#10_18_4">Description</A></LI>
+<LI><A HREF="#10_18_5">Example</A></LI>
+</UL>
+<LI><A HREF="#cupsGetPrinters">cupsGetPrinters()</A></LI>
+<UL>
+<LI><A HREF="#10_19_1">Usage</A></LI>
+<LI><A HREF="#10_19_2">Arguments</A></LI>
+<LI><A HREF="#10_19_3">Returns</A></LI>
+<LI><A HREF="#10_19_4">Description</A></LI>
+<LI><A HREF="#10_19_5">Example</A></LI>
+<LI><A HREF="#10_19_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsLangDefault">cupsLangDefault()</A></LI>
+<UL>
+<LI><A HREF="#10_20_1">Usage</A></LI>
+<LI><A HREF="#10_20_2">Returns</A></LI>
+<LI><A HREF="#10_20_3">Description</A></LI>
+<LI><A HREF="#10_20_4">Example</A></LI>
+<LI><A HREF="#10_20_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsLangEncoding">cupsLangEncoding()</A></LI>
+<UL>
+<LI><A HREF="#10_21_1">Usage</A></LI>
+<LI><A HREF="#10_21_2">Arguments</A></LI>
+<LI><A HREF="#10_21_3">Returns</A></LI>
+<LI><A HREF="#10_21_4">Description</A></LI>
+<LI><A HREF="#10_21_5">Example</A></LI>
+<LI><A HREF="#10_21_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsLangFlush">cupsLangFlush()</A></LI>
+<UL>
+<LI><A HREF="#10_22_1">Usage</A></LI>
+<LI><A HREF="#10_22_2">Description</A></LI>
+<LI><A HREF="#10_22_3">Example</A></LI>
+<LI><A HREF="#10_22_4">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsLangFree">cupsLangFree()</A></LI>
+<UL>
+<LI><A HREF="#10_23_1">Usage</A></LI>
+<LI><A HREF="#10_23_2">Arguments</A></LI>
+<LI><A HREF="#10_23_3">Description</A></LI>
+<LI><A HREF="#10_23_4">Example</A></LI>
+<LI><A HREF="#10_23_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsLangGet">cupsLangGet()</A></LI>
+<UL>
+<LI><A HREF="#10_24_1">Usage</A></LI>
+<LI><A HREF="#10_24_2">Arguments</A></LI>
+<LI><A HREF="#10_24_3">Returns</A></LI>
+<LI><A HREF="#10_24_4">Description</A></LI>
+<LI><A HREF="#10_24_5">Example</A></LI>
+<LI><A HREF="#10_24_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsLangString">cupsLangString()</A></LI>
+<UL>
+<LI><A HREF="#10_25_1">Usage</A></LI>
+<LI><A HREF="#10_25_2">Arguments</A></LI>
+<LI><A HREF="#10_25_3">Returns</A></LI>
+<LI><A HREF="#10_25_4">Description</A></LI>
+<LI><A HREF="#10_25_5">Example</A></LI>
+<LI><A HREF="#10_25_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsLastError">cupsLastError()</A></LI>
+<UL>
+<LI><A HREF="#10_26_1">Usage</A></LI>
+<LI><A HREF="#10_26_2">Returns</A></LI>
+<LI><A HREF="#10_26_3">Description</A></LI>
+<LI><A HREF="#10_26_4">Example</A></LI>
+<LI><A HREF="#10_26_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsMarkOptions">cupsMarkOptions()</A></LI>
+<UL>
+<LI><A HREF="#10_27_1">Usage</A></LI>
+<LI><A HREF="#10_27_2">Arguments</A></LI>
+<LI><A HREF="#10_27_3">Returns</A></LI>
+<LI><A HREF="#10_27_4">Description</A></LI>
+<LI><A HREF="#10_27_5">Example</A></LI>
+<LI><A HREF="#10_27_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsParseOptions">cupsParseOptions()</A></LI>
+<UL>
+<LI><A HREF="#10_28_1">Usage</A></LI>
+<LI><A HREF="#10_28_2">Arguments</A></LI>
+<LI><A HREF="#10_28_3">Returns</A></LI>
+<LI><A HREF="#10_28_4">Description</A></LI>
+<LI><A HREF="#10_28_5">Example</A></LI>
+<LI><A HREF="#10_28_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsPrintFile">cupsPrintFile()</A></LI>
+<UL>
+<LI><A HREF="#10_29_1">Usage</A></LI>
+<LI><A HREF="#10_29_2">Arguments</A></LI>
+<LI><A HREF="#10_29_3">Returns</A></LI>
+<LI><A HREF="#10_29_4">Description</A></LI>
+<LI><A HREF="#10_29_5">Example</A></LI>
+<LI><A HREF="#10_29_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsPrintFiles">cupsPrintFiles()</A></LI>
+<UL>
+<LI><A HREF="#10_30_1">Usage</A></LI>
+<LI><A HREF="#10_30_2">Arguments</A></LI>
+<LI><A HREF="#10_30_3">Returns</A></LI>
+<LI><A HREF="#10_30_4">Description</A></LI>
+<LI><A HREF="#10_30_5">Example</A></LI>
+<LI><A HREF="#10_30_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsRasterClose">cupsRasterClose()</A></LI>
+<UL>
+<LI><A HREF="#10_31_1">Usage</A></LI>
+<LI><A HREF="#10_31_2">Arguments</A></LI>
+<LI><A HREF="#10_31_3">Description</A></LI>
+<LI><A HREF="#10_31_4">Example</A></LI>
+<LI><A HREF="#10_31_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsRasterOpen">cupsRasterOpen()</A></LI>
+<UL>
+<LI><A HREF="#10_32_1">Usage</A></LI>
+<LI><A HREF="#10_32_2">Arguments</A></LI>
+<LI><A HREF="#10_32_3">Returns</A></LI>
+<LI><A HREF="#10_32_4">Description</A></LI>
+<LI><A HREF="#10_32_5">Example</A></LI>
+<LI><A HREF="#10_32_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsRasterReadHeader">cupsRasterReadHeader()</A></LI>
+<UL>
+<LI><A HREF="#10_33_1">Usage</A></LI>
+<LI><A HREF="#10_33_2">Arguments</A></LI>
+<LI><A HREF="#10_33_3">Returns</A></LI>
+<LI><A HREF="#10_33_4">Description</A></LI>
+<LI><A HREF="#10_33_5">Example</A></LI>
+<LI><A HREF="#10_33_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsRasterReadPixels">cupsRasterReadPixels()</A></LI>
+<UL>
+<LI><A HREF="#10_34_1">Usage</A></LI>
+<LI><A HREF="#10_34_2">Arguments</A></LI>
+<LI><A HREF="#10_34_3">Returns</A></LI>
+<LI><A HREF="#10_34_4">Description</A></LI>
+<LI><A HREF="#10_34_5">Example</A></LI>
+<LI><A HREF="#10_34_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsRasterWriteHeader">cupsRasterWriteHeader()</A></LI>
+<UL>
+<LI><A HREF="#10_35_1">Usage</A></LI>
+<LI><A HREF="#10_35_2">Arguments</A></LI>
+<LI><A HREF="#10_35_3">Returns</A></LI>
+<LI><A HREF="#10_35_4">Description</A></LI>
+<LI><A HREF="#10_35_5">Example</A></LI>
+<LI><A HREF="#10_35_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsRasterWritePixels">cupsRasterWritePixels()</A></LI>
+<UL>
+<LI><A HREF="#10_36_1">Usage</A></LI>
+<LI><A HREF="#10_36_2">Arguments</A></LI>
+<LI><A HREF="#10_36_3">Returns</A></LI>
+<LI><A HREF="#10_36_4">Description</A></LI>
+<LI><A HREF="#10_36_5">Example</A></LI>
+<LI><A HREF="#10_36_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsServer">cupsServer()</A></LI>
+<UL>
+<LI><A HREF="#10_37_1">Usage</A></LI>
+<LI><A HREF="#10_37_2">Returns</A></LI>
+<LI><A HREF="#10_37_3">Description</A></LI>
+<LI><A HREF="#10_37_4">Example</A></LI>
+<LI><A HREF="#10_37_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsSetDests">cupsSetDests()</A></LI>
+<UL>
+<LI><A HREF="#10_38_1">Usage</A></LI>
+<LI><A HREF="#10_38_2">Arguments</A></LI>
+<LI><A HREF="#10_38_3">Description</A></LI>
+<LI><A HREF="#10_38_4">Example</A></LI>
+<LI><A HREF="#10_38_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsSetEncryption">cupsSetEncryption()</A></LI>
+<UL>
+<LI><A HREF="#10_39_1">Usage</A></LI>
+<LI><A HREF="#10_39_2">Arguments</A></LI>
+<LI><A HREF="#10_39_3">Description</A></LI>
+<LI><A HREF="#10_39_4">Example</A></LI>
+<LI><A HREF="#10_39_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsSetPasswordCB">cupsSetPasswordCB()</A></LI>
+<UL>
+<LI><A HREF="#10_40_1">Usage</A></LI>
+<LI><A HREF="#10_40_2">Arguments</A></LI>
+<LI><A HREF="#10_40_3">Description</A></LI>
+<LI><A HREF="#10_40_4">Example</A></LI>
+<LI><A HREF="#10_40_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsSetServer">cupsSetServer()</A></LI>
+<UL>
+<LI><A HREF="#10_41_1">Usage</A></LI>
+<LI><A HREF="#10_41_2">Arguments</A></LI>
+<LI><A HREF="#10_41_3">Description</A></LI>
+<LI><A HREF="#10_41_4">Example</A></LI>
+<LI><A HREF="#10_41_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsSetUser">cupsSetUser()</A></LI>
+<UL>
+<LI><A HREF="#10_42_1">Usage</A></LI>
+<LI><A HREF="#10_42_2">Arguments</A></LI>
+<LI><A HREF="#10_42_3">Description</A></LI>
+<LI><A HREF="#10_42_4">Example</A></LI>
+<LI><A HREF="#10_42_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsTempFd">cupsTempFd()</A></LI>
+<UL>
+<LI><A HREF="#10_43_1">Usage</A></LI>
+<LI><A HREF="#10_43_2">Arguments</A></LI>
+<LI><A HREF="#10_43_3">Returns</A></LI>
+<LI><A HREF="#10_43_4">Description</A></LI>
+<LI><A HREF="#10_43_5">Example</A></LI>
+<LI><A HREF="#10_43_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsTempFile">cupsTempFile()</A></LI>
+<UL>
+<LI><A HREF="#10_44_1">Usage</A></LI>
+<LI><A HREF="#10_44_2">Arguments</A></LI>
+<LI><A HREF="#10_44_3">Returns</A></LI>
+<LI><A HREF="#10_44_4">Description</A></LI>
+<LI><A HREF="#10_44_5">Example</A></LI>
+<LI><A HREF="#10_44_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#cupsUser">cupsUser()</A></LI>
+<UL>
+<LI><A HREF="#10_45_1">Usage</A></LI>
+<LI><A HREF="#10_45_2">Returns</A></LI>
+<LI><A HREF="#10_45_3">Description</A></LI>
+<LI><A HREF="#10_45_4">Example</A></LI>
+<LI><A HREF="#10_45_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpBlocking">httpBlocking()</A></LI>
+<UL>
+<LI><A HREF="#10_46_1">Usage</A></LI>
+<LI><A HREF="#10_46_2">Arguments</A></LI>
+<LI><A HREF="#10_46_3">Description</A></LI>
+<LI><A HREF="#10_46_4">Example</A></LI>
+<LI><A HREF="#10_46_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpCheck">httpCheck()</A></LI>
+<UL>
+<LI><A HREF="#10_47_1">Usage</A></LI>
+<LI><A HREF="#10_47_2">Arguments</A></LI>
+<LI><A HREF="#10_47_3">Returns</A></LI>
+<LI><A HREF="#10_47_4">Description</A></LI>
+<LI><A HREF="#10_47_5">Example</A></LI>
+<LI><A HREF="#10_47_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpClearFields">httpClearFields()</A></LI>
+<UL>
+<LI><A HREF="#10_48_1">Usage</A></LI>
+<LI><A HREF="#10_48_2">Arguments</A></LI>
+<LI><A HREF="#10_48_3">Description</A></LI>
+<LI><A HREF="#10_48_4">Example</A></LI>
+<LI><A HREF="#10_48_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpClose">httpClose()</A></LI>
+<UL>
+<LI><A HREF="#10_49_1">Usage</A></LI>
+<LI><A HREF="#10_49_2">Arguments</A></LI>
+<LI><A HREF="#10_49_3">Description</A></LI>
+<LI><A HREF="#10_49_4">Example</A></LI>
+<LI><A HREF="#10_49_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpConnect">httpConnect()</A></LI>
+<UL>
+<LI><A HREF="#10_50_1">Usage</A></LI>
+<LI><A HREF="#10_50_2">Arguments</A></LI>
+<LI><A HREF="#10_50_3">Returns</A></LI>
+<LI><A HREF="#10_50_4">Description</A></LI>
+<LI><A HREF="#10_50_5">Example</A></LI>
+<LI><A HREF="#10_50_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpConnectEncrypt">httpConnectEncrypt()</A></LI>
+<UL>
+<LI><A HREF="#10_51_1">Usage</A></LI>
+<LI><A HREF="#10_51_2">Arguments</A></LI>
+<LI><A HREF="#10_51_3">Returns</A></LI>
+<LI><A HREF="#10_51_4">Description</A></LI>
+<LI><A HREF="#10_51_5">Example</A></LI>
+<LI><A HREF="#10_51_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpDecode64">httpDecode64()</A></LI>
+<UL>
+<LI><A HREF="#10_52_1">Usage</A></LI>
+<LI><A HREF="#10_52_2">Arguments</A></LI>
+<LI><A HREF="#10_52_3">Returns</A></LI>
+<LI><A HREF="#10_52_4">Description</A></LI>
+<LI><A HREF="#10_52_5">Example</A></LI>
+<LI><A HREF="#10_52_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpDelete">httpDelete()</A></LI>
+<UL>
+<LI><A HREF="#10_53_1">Usage</A></LI>
+<LI><A HREF="#10_53_2">Arguments</A></LI>
+<LI><A HREF="#10_53_3">Returns</A></LI>
+<LI><A HREF="#10_53_4">Description</A></LI>
+<LI><A HREF="#10_53_5">Example</A></LI>
+<LI><A HREF="#10_53_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpEncode64">httpEncode64()</A></LI>
+<UL>
+<LI><A HREF="#10_54_1">Usage</A></LI>
+<LI><A HREF="#10_54_2">Arguments</A></LI>
+<LI><A HREF="#10_54_3">Returns</A></LI>
+<LI><A HREF="#10_54_4">Description</A></LI>
+<LI><A HREF="#10_54_5">Example</A></LI>
+<LI><A HREF="#10_54_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpEncryption">httpEncryption()</A></LI>
+<UL>
+<LI><A HREF="#10_55_1">Usage</A></LI>
+<LI><A HREF="#10_55_2">Arguments</A></LI>
+<LI><A HREF="#10_55_3">Returns</A></LI>
+<LI><A HREF="#10_55_4">Description</A></LI>
+<LI><A HREF="#10_55_5">Example</A></LI>
+<LI><A HREF="#10_55_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpError">httpError()</A></LI>
+<UL>
+<LI><A HREF="#10_56_1">Usage</A></LI>
+<LI><A HREF="#10_56_2">Arguments</A></LI>
+<LI><A HREF="#10_56_3">Returns</A></LI>
+<LI><A HREF="#10_56_4">Description</A></LI>
+<LI><A HREF="#10_56_5">Example</A></LI>
+<LI><A HREF="#10_56_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpFlush">httpFlush()</A></LI>
+<UL>
+<LI><A HREF="#10_57_1">Usage</A></LI>
+<LI><A HREF="#10_57_2">Arguments</A></LI>
+<LI><A HREF="#10_57_3">Description</A></LI>
+<LI><A HREF="#10_57_4">Example</A></LI>
+<LI><A HREF="#10_57_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpGet">httpGet()</A></LI>
+<UL>
+<LI><A HREF="#10_58_1">Usage</A></LI>
+<LI><A HREF="#10_58_2">Arguments</A></LI>
+<LI><A HREF="#10_58_3">Returns</A></LI>
+<LI><A HREF="#10_58_4">Description</A></LI>
+<LI><A HREF="#10_58_5">Example</A></LI>
+<LI><A HREF="#10_58_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpGets">httpGets()</A></LI>
+<UL>
+<LI><A HREF="#10_59_1">Usage</A></LI>
+<LI><A HREF="#10_59_2">Arguments</A></LI>
+<LI><A HREF="#10_59_3">Returns</A></LI>
+<LI><A HREF="#10_59_4">Description</A></LI>
+<LI><A HREF="#10_59_5">Example</A></LI>
+<LI><A HREF="#10_59_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpGetDateString">httpGetDateString()</A></LI>
+<UL>
+<LI><A HREF="#10_60_1">Usage</A></LI>
+<LI><A HREF="#10_60_2">Arguments</A></LI>
+<LI><A HREF="#10_60_3">Returns</A></LI>
+<LI><A HREF="#10_60_4">Description</A></LI>
+<LI><A HREF="#10_60_5">Example</A></LI>
+<LI><A HREF="#10_60_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpGetDateTime">httpGetDateTime()</A></LI>
+<UL>
+<LI><A HREF="#10_61_1">Usage</A></LI>
+<LI><A HREF="#10_61_2">Arguments</A></LI>
+<LI><A HREF="#10_61_3">Returns</A></LI>
+<LI><A HREF="#10_61_4">Description</A></LI>
+<LI><A HREF="#10_61_5">Example</A></LI>
+<LI><A HREF="#10_61_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpGetField">httpGetField()</A></LI>
+<UL>
+<LI><A HREF="#10_62_1">Usage</A></LI>
+<LI><A HREF="#10_62_2">Arguments</A></LI>
+<LI><A HREF="#10_62_3">Returns</A></LI>
+<LI><A HREF="#10_62_4">Description</A></LI>
+<LI><A HREF="#10_62_5">Example</A></LI>
+<LI><A HREF="#10_62_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpGetHostByName">httpGetHostByName()</A></LI>
+<UL>
+<LI><A HREF="#10_63_1">Usage</A></LI>
+<LI><A HREF="#10_63_2">Arguments</A></LI>
+<LI><A HREF="#10_63_3">Returns</A></LI>
+<LI><A HREF="#10_63_4">Description</A></LI>
+<LI><A HREF="#10_63_5">Example</A></LI>
+</UL>
+<LI><A HREF="#httpGetLength">httpGetLength()</A></LI>
+<UL>
+<LI><A HREF="#10_64_1">Usage</A></LI>
+<LI><A HREF="#10_64_2">Arguments</A></LI>
+<LI><A HREF="#10_64_3">Returns</A></LI>
+<LI><A HREF="#10_64_4">Description</A></LI>
+<LI><A HREF="#10_64_5">Example</A></LI>
+<LI><A HREF="#10_64_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpGetSubField">httpGetSubField()</A></LI>
+<UL>
+<LI><A HREF="#10_65_1">Usage</A></LI>
+<LI><A HREF="#10_65_2">Arguments</A></LI>
+<LI><A HREF="#10_65_3">Returns</A></LI>
+<LI><A HREF="#10_65_4">Description</A></LI>
+<LI><A HREF="#10_65_5">Example</A></LI>
+<LI><A HREF="#10_65_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpHead">httpHead()</A></LI>
+<UL>
+<LI><A HREF="#10_66_1">Usage</A></LI>
+<LI><A HREF="#10_66_2">Arguments</A></LI>
+<LI><A HREF="#10_66_3">Returns</A></LI>
+<LI><A HREF="#10_66_4">Description</A></LI>
+<LI><A HREF="#10_66_5">Example</A></LI>
+<LI><A HREF="#10_66_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpInitialize">httpInitialize()</A></LI>
+<UL>
+<LI><A HREF="#10_67_1">Usage</A></LI>
+<LI><A HREF="#10_67_2">Description</A></LI>
+<LI><A HREF="#10_67_3">Example</A></LI>
+<LI><A HREF="#10_67_4">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpMD5">httpMD5()</A></LI>
+<UL>
+<LI><A HREF="#10_68_1">Usage</A></LI>
+<LI><A HREF="#10_68_2">Arguments</A></LI>
+<LI><A HREF="#10_68_3">Returns</A></LI>
+<LI><A HREF="#10_68_4">Description</A></LI>
+<LI><A HREF="#10_68_5">Example</A></LI>
+<LI><A HREF="#10_68_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpMD5Final">httpMD5Final()</A></LI>
+<UL>
+<LI><A HREF="#10_69_1">Usage</A></LI>
+<LI><A HREF="#10_69_2">Arguments</A></LI>
+<LI><A HREF="#10_69_3">Returns</A></LI>
+<LI><A HREF="#10_69_4">Description</A></LI>
+<LI><A HREF="#10_69_5">Example</A></LI>
+<LI><A HREF="#10_69_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpMD5String">httpMD5String()</A></LI>
+<UL>
+<LI><A HREF="#10_70_1">Usage</A></LI>
+<LI><A HREF="#10_70_2">Arguments</A></LI>
+<LI><A HREF="#10_70_3">Returns</A></LI>
+<LI><A HREF="#10_70_4">Description</A></LI>
+<LI><A HREF="#10_70_5">Example</A></LI>
+<LI><A HREF="#10_70_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpOptions">httpOptions()</A></LI>
+<UL>
+<LI><A HREF="#10_71_1">Usage</A></LI>
+<LI><A HREF="#10_71_2">Arguments</A></LI>
+<LI><A HREF="#10_71_3">Returns</A></LI>
+<LI><A HREF="#10_71_4">Description</A></LI>
+<LI><A HREF="#10_71_5">Example</A></LI>
+<LI><A HREF="#10_71_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpPost">httpPost()</A></LI>
+<UL>
+<LI><A HREF="#10_72_1">Usage</A></LI>
+<LI><A HREF="#10_72_2">Arguments</A></LI>
+<LI><A HREF="#10_72_3">Returns</A></LI>
+<LI><A HREF="#10_72_4">Description</A></LI>
+<LI><A HREF="#10_72_5">Example</A></LI>
+<LI><A HREF="#10_72_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpPrintf">httpPrintf()</A></LI>
+<UL>
+<LI><A HREF="#10_73_1">Usage</A></LI>
+<LI><A HREF="#10_73_2">Arguments</A></LI>
+<LI><A HREF="#10_73_3">Returns</A></LI>
+<LI><A HREF="#10_73_4">Description</A></LI>
+<LI><A HREF="#10_73_5">Example</A></LI>
+<LI><A HREF="#10_73_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpPut">httpPut()</A></LI>
+<UL>
+<LI><A HREF="#10_74_1">Usage</A></LI>
+<LI><A HREF="#10_74_2">Arguments</A></LI>
+<LI><A HREF="#10_74_3">Returns</A></LI>
+<LI><A HREF="#10_74_4">Description</A></LI>
+<LI><A HREF="#10_74_5">Example</A></LI>
+<LI><A HREF="#10_74_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpRead">httpRead()</A></LI>
+<UL>
+<LI><A HREF="#10_75_1">Usage</A></LI>
+<LI><A HREF="#10_75_2">Arguments</A></LI>
+<LI><A HREF="#10_75_3">Returns</A></LI>
+<LI><A HREF="#10_75_4">Description</A></LI>
+<LI><A HREF="#10_75_5">Example</A></LI>
+<LI><A HREF="#10_75_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpReconnect">httpReconnect()</A></LI>
+<UL>
+<LI><A HREF="#10_76_1">Usage</A></LI>
+<LI><A HREF="#10_76_2">Arguments</A></LI>
+<LI><A HREF="#10_76_3">Returns</A></LI>
+<LI><A HREF="#10_76_4">Description</A></LI>
+<LI><A HREF="#10_76_5">Example</A></LI>
+<LI><A HREF="#10_76_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpSeparate">httpSeparate()</A></LI>
+<UL>
+<LI><A HREF="#10_77_1">Usage</A></LI>
+<LI><A HREF="#10_77_2">Arguments</A></LI>
+<LI><A HREF="#10_77_3">Description</A></LI>
+<LI><A HREF="#10_77_4">Example</A></LI>
+<LI><A HREF="#10_77_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpSetField">httpSetField()</A></LI>
+<UL>
+<LI><A HREF="#10_78_1">Usage</A></LI>
+<LI><A HREF="#10_78_2">Arguments</A></LI>
+<LI><A HREF="#10_78_3">Description</A></LI>
+<LI><A HREF="#10_78_4">Example</A></LI>
+<LI><A HREF="#10_78_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpStatus">httpStatus()</A></LI>
+<UL>
+<LI><A HREF="#10_79_1">Usage</A></LI>
+<LI><A HREF="#10_79_2">Arguments</A></LI>
+<LI><A HREF="#10_79_3">Returns</A></LI>
+<LI><A HREF="#10_79_4">Description</A></LI>
+<LI><A HREF="#10_79_5">Example</A></LI>
+</UL>
+<LI><A HREF="#httpTrace">httpTrace()</A></LI>
+<UL>
+<LI><A HREF="#10_80_1">Usage</A></LI>
+<LI><A HREF="#10_80_2">Arguments</A></LI>
+<LI><A HREF="#10_80_3">Returns</A></LI>
+<LI><A HREF="#10_80_4">Description</A></LI>
+<LI><A HREF="#10_80_5">Example</A></LI>
+<LI><A HREF="#10_80_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpUpdate">httpUpdate()</A></LI>
+<UL>
+<LI><A HREF="#10_81_1">Usage</A></LI>
+<LI><A HREF="#10_81_2">Arguments</A></LI>
+<LI><A HREF="#10_81_3">Returns</A></LI>
+<LI><A HREF="#10_81_4">Description</A></LI>
+<LI><A HREF="#10_81_5">Example</A></LI>
+<LI><A HREF="#10_81_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#httpWrite">httpWrite()</A></LI>
+<UL>
+<LI><A HREF="#10_82_1">Usage</A></LI>
+<LI><A HREF="#10_82_2">Arguments</A></LI>
+<LI><A HREF="#10_82_3">Returns</A></LI>
+<LI><A HREF="#10_82_4">Description</A></LI>
+<LI><A HREF="#10_82_5">Example</A></LI>
+<LI><A HREF="#10_82_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddBoolean">ippAddBoolean()</A></LI>
+<UL>
+<LI><A HREF="#10_83_1">Usage</A></LI>
+<LI><A HREF="#10_83_2">Arguments</A></LI>
+<LI><A HREF="#10_83_3">Returns</A></LI>
+<LI><A HREF="#10_83_4">Description</A></LI>
+<LI><A HREF="#10_83_5">Example</A></LI>
+<LI><A HREF="#10_83_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddBooleans">ippAddBooleans()</A></LI>
+<UL>
+<LI><A HREF="#10_84_1">Usage</A></LI>
+<LI><A HREF="#10_84_2">Arguments</A></LI>
+<LI><A HREF="#10_84_3">Returns</A></LI>
+<LI><A HREF="#10_84_4">Description</A></LI>
+<LI><A HREF="#10_84_5">Example</A></LI>
+<LI><A HREF="#10_84_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddDate">ippAddDate()</A></LI>
+<UL>
+<LI><A HREF="#10_85_1">Usage</A></LI>
+<LI><A HREF="#10_85_2">Arguments</A></LI>
+<LI><A HREF="#10_85_3">Returns</A></LI>
+<LI><A HREF="#10_85_4">Description</A></LI>
+<LI><A HREF="#10_85_5">Example</A></LI>
+<LI><A HREF="#10_85_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddInteger">ippAddInteger()</A></LI>
+<UL>
+<LI><A HREF="#10_86_1">Usage</A></LI>
+<LI><A HREF="#10_86_2">Arguments</A></LI>
+<LI><A HREF="#10_86_3">Returns</A></LI>
+<LI><A HREF="#10_86_4">Description</A></LI>
+<LI><A HREF="#10_86_5">Example</A></LI>
+<LI><A HREF="#10_86_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddIntegers">ippAddIntegers()</A></LI>
+<UL>
+<LI><A HREF="#10_87_1">Usage</A></LI>
+<LI><A HREF="#10_87_2">Arguments</A></LI>
+<LI><A HREF="#10_87_3">Returns</A></LI>
+<LI><A HREF="#10_87_4">Description</A></LI>
+<LI><A HREF="#10_87_5">Example</A></LI>
+<LI><A HREF="#10_87_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddRange">ippAddRange()</A></LI>
+<UL>
+<LI><A HREF="#10_88_1">Usage</A></LI>
+<LI><A HREF="#10_88_2">Arguments</A></LI>
+<LI><A HREF="#10_88_3">Returns</A></LI>
+<LI><A HREF="#10_88_4">Description</A></LI>
+<LI><A HREF="#10_88_5">Example</A></LI>
+<LI><A HREF="#10_88_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddRanges">ippAddRanges()</A></LI>
+<UL>
+<LI><A HREF="#10_89_1">Usage</A></LI>
+<LI><A HREF="#10_89_2">Arguments</A></LI>
+<LI><A HREF="#10_89_3">Returns</A></LI>
+<LI><A HREF="#10_89_4">Description</A></LI>
+<LI><A HREF="#10_89_5">Example</A></LI>
+<LI><A HREF="#10_89_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddResolution">ippAddResolution()</A></LI>
+<UL>
+<LI><A HREF="#10_90_1">Usage</A></LI>
+<LI><A HREF="#10_90_2">Arguments</A></LI>
+<LI><A HREF="#10_90_3">Returns</A></LI>
+<LI><A HREF="#10_90_4">Description</A></LI>
+<LI><A HREF="#10_90_5">Example</A></LI>
+<LI><A HREF="#10_90_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddResolutions">ippAddResolutions()</A></LI>
+<UL>
+<LI><A HREF="#10_91_1">Usage</A></LI>
+<LI><A HREF="#10_91_2">Arguments</A></LI>
+<LI><A HREF="#10_91_3">Returns</A></LI>
+<LI><A HREF="#10_91_4">Description</A></LI>
+<LI><A HREF="#10_91_5">Example</A></LI>
+<LI><A HREF="#10_91_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddSeparator">ippAddSeparator()</A></LI>
+<UL>
+<LI><A HREF="#10_92_1">Usage</A></LI>
+<LI><A HREF="#10_92_2">Arguments</A></LI>
+<LI><A HREF="#10_92_3">Returns</A></LI>
+<LI><A HREF="#10_92_4">Description</A></LI>
+<LI><A HREF="#10_92_5">Example</A></LI>
+<LI><A HREF="#10_92_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddString">ippAddString()</A></LI>
+<UL>
+<LI><A HREF="#10_93_1">Usage</A></LI>
+<LI><A HREF="#10_93_2">Arguments</A></LI>
+<LI><A HREF="#10_93_3">Returns</A></LI>
+<LI><A HREF="#10_93_4">Description</A></LI>
+<LI><A HREF="#10_93_5">Example</A></LI>
+<LI><A HREF="#10_93_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippAddStrings">ippAddStrings()</A></LI>
+<UL>
+<LI><A HREF="#10_94_1">Usage</A></LI>
+<LI><A HREF="#10_94_2">Arguments</A></LI>
+<LI><A HREF="#10_94_3">Returns</A></LI>
+<LI><A HREF="#10_94_4">Description</A></LI>
+<LI><A HREF="#10_94_5">Example</A></LI>
+<LI><A HREF="#10_94_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippDateToTime">ippDateToTime()</A></LI>
+<UL>
+<LI><A HREF="#10_95_1">Usage</A></LI>
+<LI><A HREF="#10_95_2">Arguments</A></LI>
+<LI><A HREF="#10_95_3">Returns</A></LI>
+<LI><A HREF="#10_95_4">Description</A></LI>
+<LI><A HREF="#10_95_5">Example</A></LI>
+<LI><A HREF="#10_95_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippDelete">ippDelete()</A></LI>
+<UL>
+<LI><A HREF="#10_96_1">Usage</A></LI>
+<LI><A HREF="#10_96_2">Arguments</A></LI>
+<LI><A HREF="#10_96_3">Description</A></LI>
+<LI><A HREF="#10_96_4">Example</A></LI>
+<LI><A HREF="#10_96_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippErrorString">ippErrorString()</A></LI>
+<UL>
+<LI><A HREF="#10_97_1">Usage</A></LI>
+<LI><A HREF="#10_97_2">Arguments</A></LI>
+<LI><A HREF="#10_97_3">Returns</A></LI>
+<LI><A HREF="#10_97_4">Description</A></LI>
+<LI><A HREF="#10_97_5">Example</A></LI>
+<LI><A HREF="#10_97_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippFindAttribute">ippFindAttribute()</A></LI>
+<UL>
+<LI><A HREF="#10_98_1">Usage</A></LI>
+<LI><A HREF="#10_98_2">Arguments</A></LI>
+<LI><A HREF="#10_98_3">Returns</A></LI>
+<LI><A HREF="#10_98_4">Description</A></LI>
+<LI><A HREF="#10_98_5">Example</A></LI>
+<LI><A HREF="#10_98_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippFindNextAttribute">ippFindNextAttribute()</A></LI>
+<UL>
+<LI><A HREF="#10_99_1">Usage</A></LI>
+<LI><A HREF="#10_99_2">Arguments</A></LI>
+<LI><A HREF="#10_99_3">Returns</A></LI>
+<LI><A HREF="#10_99_4">Description</A></LI>
+<LI><A HREF="#10_99_5">Example</A></LI>
+<LI><A HREF="#10_99_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippLength">ippLength()</A></LI>
+<UL>
+<LI><A HREF="#10_100_1">Usage</A></LI>
+<LI><A HREF="#10_100_2">Arguments</A></LI>
+<LI><A HREF="#10_100_3">Returns</A></LI>
+<LI><A HREF="#10_100_4">Description</A></LI>
+<LI><A HREF="#10_100_5">Example</A></LI>
+<LI><A HREF="#10_100_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippNew">ippNew()</A></LI>
+<UL>
+<LI><A HREF="#10_101_1">Usage</A></LI>
+<LI><A HREF="#10_101_2">Returns</A></LI>
+<LI><A HREF="#10_101_3">Description</A></LI>
+<LI><A HREF="#10_101_4">Example</A></LI>
+<LI><A HREF="#10_101_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippPort">ippPort()</A></LI>
+<UL>
+<LI><A HREF="#10_102_1">Usage</A></LI>
+<LI><A HREF="#10_102_2">Returns</A></LI>
+<LI><A HREF="#10_102_3">Description</A></LI>
+<LI><A HREF="#10_102_4">Example</A></LI>
+<LI><A HREF="#10_102_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippRead">ippRead()</A></LI>
+<UL>
+<LI><A HREF="#10_103_1">Usage</A></LI>
+<LI><A HREF="#10_103_2">Arguments</A></LI>
+<LI><A HREF="#10_103_3">Returns</A></LI>
+<LI><A HREF="#10_103_4">Description</A></LI>
+<LI><A HREF="#10_103_5">Example</A></LI>
+<LI><A HREF="#10_103_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippSetPort">ippSetPort()</A></LI>
+<UL>
+<LI><A HREF="#10_104_1">Usage</A></LI>
+<LI><A HREF="#10_104_2">Arguments</A></LI>
+<LI><A HREF="#10_104_3">Description</A></LI>
+<LI><A HREF="#10_104_4">Example</A></LI>
+<LI><A HREF="#10_104_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippTimeToDate">ippTimeToDate()</A></LI>
+<UL>
+<LI><A HREF="#10_105_1">Usage</A></LI>
+<LI><A HREF="#10_105_2">Arguments</A></LI>
+<LI><A HREF="#10_105_3">Returns</A></LI>
+<LI><A HREF="#10_105_4">Description</A></LI>
+<LI><A HREF="#10_105_5">Example</A></LI>
+<LI><A HREF="#10_105_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ippWrite">ippWrite()</A></LI>
+<UL>
+<LI><A HREF="#10_106_1">Usage</A></LI>
+<LI><A HREF="#10_106_2">Arguments</A></LI>
+<LI><A HREF="#10_106_3">Returns</A></LI>
+<LI><A HREF="#10_106_4">Description</A></LI>
+<LI><A HREF="#10_106_5">Example</A></LI>
+<LI><A HREF="#10_106_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdClose">ppdClose()</A></LI>
+<UL>
+<LI><A HREF="#10_107_1">Usage</A></LI>
+<LI><A HREF="#10_107_2">Arguments</A></LI>
+<LI><A HREF="#10_107_3">Description</A></LI>
+<LI><A HREF="#10_107_4">Example</A></LI>
+<LI><A HREF="#10_107_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdCollect">ppdCollect()</A></LI>
+<UL>
+<LI><A HREF="#10_108_1">Usage</A></LI>
+<LI><A HREF="#10_108_2">Arguments</A></LI>
+<LI><A HREF="#10_108_3">Returns</A></LI>
+<LI><A HREF="#10_108_4">Description</A></LI>
+<LI><A HREF="#10_108_5">Example</A></LI>
+<LI><A HREF="#10_108_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdConflicts">ppdConflicts()</A></LI>
+<UL>
+<LI><A HREF="#10_109_1">Usage</A></LI>
+<LI><A HREF="#10_109_2">Arguments</A></LI>
+<LI><A HREF="#10_109_3">Returns</A></LI>
+<LI><A HREF="#10_109_4">Description</A></LI>
+<LI><A HREF="#10_109_5">Example</A></LI>
+<LI><A HREF="#10_109_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdEmit">ppdEmit()</A></LI>
+<UL>
+<LI><A HREF="#10_110_1">Usage</A></LI>
+<LI><A HREF="#10_110_2">Arguments</A></LI>
+<LI><A HREF="#10_110_3">Returns</A></LI>
+<LI><A HREF="#10_110_4">Description</A></LI>
+<LI><A HREF="#10_110_5">Example</A></LI>
+<LI><A HREF="#10_110_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdEmitFd">ppdEmitFd()</A></LI>
+<UL>
+<LI><A HREF="#10_111_1">Usage</A></LI>
+<LI><A HREF="#10_111_2">Arguments</A></LI>
+<LI><A HREF="#10_111_3">Returns</A></LI>
+<LI><A HREF="#10_111_4">Description</A></LI>
+<LI><A HREF="#10_111_5">Example</A></LI>
+<LI><A HREF="#10_111_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdFindChoice">ppdFindChoice()</A></LI>
+<UL>
+<LI><A HREF="#10_112_1">Usage</A></LI>
+<LI><A HREF="#10_112_2">Arguments</A></LI>
+<LI><A HREF="#10_112_3">Returns</A></LI>
+<LI><A HREF="#10_112_4">Description</A></LI>
+<LI><A HREF="#10_112_5">Example</A></LI>
+<LI><A HREF="#10_112_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdFindMarkedChoice">ppdFindMarkedChoice()</A></LI>
+<UL>
+<LI><A HREF="#10_113_1">Usage</A></LI>
+<LI><A HREF="#10_113_2">Arguments</A></LI>
+<LI><A HREF="#10_113_3">Returns</A></LI>
+<LI><A HREF="#10_113_4">Description</A></LI>
+<LI><A HREF="#10_113_5">Example</A></LI>
+<LI><A HREF="#10_113_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdFindOption">ppdFindOption()</A></LI>
+<UL>
+<LI><A HREF="#10_114_1">Usage</A></LI>
+<LI><A HREF="#10_114_2">Arguments</A></LI>
+<LI><A HREF="#10_114_3">Returns</A></LI>
+<LI><A HREF="#10_114_4">Description</A></LI>
+<LI><A HREF="#10_114_5">Example</A></LI>
+<LI><A HREF="#10_114_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdIsMarked">ppdIsMarked()</A></LI>
+<UL>
+<LI><A HREF="#10_115_1">Usage</A></LI>
+<LI><A HREF="#10_115_2">Arguments</A></LI>
+<LI><A HREF="#10_115_3">Returns</A></LI>
+<LI><A HREF="#10_115_4">Description</A></LI>
+<LI><A HREF="#10_115_5">Example</A></LI>
+<LI><A HREF="#10_115_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdMarkDefaults">ppdMarkDefaults()</A></LI>
+<UL>
+<LI><A HREF="#10_116_1">Usage</A></LI>
+<LI><A HREF="#10_116_2">Arguments</A></LI>
+<LI><A HREF="#10_116_3">Description</A></LI>
+<LI><A HREF="#10_116_4">Example</A></LI>
+<LI><A HREF="#10_116_5">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdMarkOption">ppdMarkOption()</A></LI>
+<UL>
+<LI><A HREF="#10_117_1">Usage</A></LI>
+<LI><A HREF="#10_117_2">Arguments</A></LI>
+<LI><A HREF="#10_117_3">Returns</A></LI>
+<LI><A HREF="#10_117_4">Description</A></LI>
+<LI><A HREF="#10_117_5">Example</A></LI>
+<LI><A HREF="#10_117_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdOpen">ppdOpen()</A></LI>
+<UL>
+<LI><A HREF="#10_118_1">Usage</A></LI>
+<LI><A HREF="#10_118_2">Arguments</A></LI>
+<LI><A HREF="#10_118_3">Returns</A></LI>
+<LI><A HREF="#10_118_4">Description</A></LI>
+<LI><A HREF="#10_118_5">Example</A></LI>
+<LI><A HREF="#10_118_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdOpenFd">ppdOpenFd()</A></LI>
+<UL>
+<LI><A HREF="#10_119_1">Usage</A></LI>
+<LI><A HREF="#10_119_2">Arguments</A></LI>
+<LI><A HREF="#10_119_3">Returns</A></LI>
+<LI><A HREF="#10_119_4">Description</A></LI>
+<LI><A HREF="#10_119_5">Example</A></LI>
+<LI><A HREF="#10_119_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdOpenFile">ppdOpenFile()</A></LI>
+<UL>
+<LI><A HREF="#10_120_1">Usage</A></LI>
+<LI><A HREF="#10_120_2">Arguments</A></LI>
+<LI><A HREF="#10_120_3">Returns</A></LI>
+<LI><A HREF="#10_120_4">Description</A></LI>
+<LI><A HREF="#10_120_5">Example</A></LI>
+<LI><A HREF="#10_120_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdPageLength">ppdPageLength()</A></LI>
+<UL>
+<LI><A HREF="#10_121_1">Usage</A></LI>
+<LI><A HREF="#10_121_2">Arguments</A></LI>
+<LI><A HREF="#10_121_3">Returns</A></LI>
+<LI><A HREF="#10_121_4">Description</A></LI>
+<LI><A HREF="#10_121_5">Example</A></LI>
+<LI><A HREF="#10_121_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdPageSize">ppdPageSize()</A></LI>
+<UL>
+<LI><A HREF="#10_122_1">Usage</A></LI>
+<LI><A HREF="#10_122_2">Arguments</A></LI>
+<LI><A HREF="#10_122_3">Returns</A></LI>
+<LI><A HREF="#10_122_4">Description</A></LI>
+<LI><A HREF="#10_122_5">Example</A></LI>
+<LI><A HREF="#10_122_6">See Also</A></LI>
+</UL>
+<LI><A HREF="#ppdPageWidth">ppdPageWidth()</A></LI>
+<UL>
+<LI><A HREF="#10_123_1">Usage</A></LI>
+<LI><A HREF="#10_123_2">Arguments</A></LI>
+<LI><A HREF="#10_123_3">Returns</A></LI>
+<LI><A HREF="#10_123_4">Description</A></LI>
+<LI><A HREF="#10_123_5">Example</A></LI>
+<LI><A HREF="#10_123_6">See Also</A></LI>
+</UL>
+</UL>
+<HR>
+<H1 ALIGN="RIGHT"><A NAME="1">Preface</A></H1>
+<P>This software programmers manual provides software programming
+ information for the Common UNIX Printing System (&quot;CUPS&quot;) Version
+ 1.1.16.</P>
+<H2><A NAME="1_1">System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+
+<!-- NEED 2in -->
+<H2><A NAME="1_2">Document Overview</A></H2>
+<P>This software programmers manual is organized into the following
+ sections:</P>
+<UL>
+<LI><A HREF="#OVERVIEW">1 - Printing System Overview</A></LI>
+<LI><A HREF="#CUPS_API">2 - The CUPS API</A></LI>
+<LI><A HREF="#WRITING_FILTERS">3 - Writing Filters</A></LI>
+<LI><A HREF="#WRITING_DRIVERS">4 - Writing Printer Drivers</A></LI>
+<LI><A HREF="#WRITING_BACKENDS">5 - Writing Backends</A></LI>
+<LI><A HREF="#LICENSE">A - Software License Agreement</A></LI>
+<LI><A HREF="#CONSTANTS">B - Constants</A></LI>
+<LI><A HREF="#STRUCTURES">C - Structures</A></LI>
+<LI><A HREF="#FUNCTIONS">D - Functions</A></LI>
+</UL>
+<H2><A NAME="1_3">Notation Conventions</A></H2>
+<P>Various font and syntax conventions are used in this guide. Examples
+ and their meanings and uses are explained below:
+<CENTER>
+<TABLE WIDTH="80%">
+<TR><TH>Example</TH><TD>&nbsp;&nbsp;&nbsp;</TD><TH>Description</TH></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD><CODE>lpstat</CODE>
+<BR> <CODE>lpstat(1)</CODE></TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>The names of commands;
+ the first mention of a command or function in a chapter is followed by
+ a manual page section number.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD><VAR>/var</VAR>
+<BR><VAR> /usr/share/cups/data/testprint.ps</VAR></TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>
+File and directory names.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD NOWRAP><TT>Request ID is Printer-123</TT></TD><TD>
+&nbsp;&nbsp;&nbsp;</TD><TD>Screen output.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD NOWRAP><KBD>lp -d printer filename ENTER</KBD></TD><TD>
+&nbsp;&nbsp;&nbsp;</TD><TD>Literal user input; special keys like <KBD>ENTER</KBD> are
+ in ALL CAPS.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD>12.3</TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>Numbers in the text are
+ written using the period (.) to indicate the decimal point.</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+</P>
+<H2><A NAME="1_4">Abbreviations</A></H2>
+ The following abbreviations are used throughout this manual:
+<UL>
+<DL>
+<DT>kb</DT>
+<DD>Kilobytes, or 1024 bytes
+<BR>&nbsp;</DD>
+<DT>Mb</DT>
+<DD>Megabytes, or 1048576 bytes
+<BR>&nbsp;</DD>
+<DT>Gb</DT>
+<DD>Gigabytes, or 1073741824 bytes
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H2><A NAME="1_5">Other References</A></H2>
+<UL>
+<DL>
+<DT>CUPS Software Administrators Manual</DT>
+<DD>An administration guide for the CUPS software.
+<BR>&nbsp;</DD>
+<DT>CUPS Software Users Manual</DT>
+<DD>An end-user guide for using the CUPS software.
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H1 ALIGN="RIGHT"><A NAME="OVERVIEW">1 - Printing System Overview</A></H1>
+<P>This chapter provides an overview of how the Common UNIX Printing
+ System works.</P>
+<H2><A NAME="2_1">The Printing Problem</A></H2>
+<P>For years<I> the printing problem</I> has plagued UNIX. Unlike
+ Microsoft&reg; Windows&reg; or Mac OS, UNIX has no standard interface or system
+ in place for supporting printers. Among the solutions currently
+ available, the Berkeley and System V printing systems are the most
+ prevalent.</P>
+<P>These printing systems support line printers (text only) or
+ PostScript printers (text and graphics), and with some coaxing they can
+ be made to support a full range of printers and file formats. However,
+ because each varient of the UNIX operating system uses a different
+ printing system than the next developing printer drivers for a wide
+ range of printers and operating systems is extremely difficult. That
+ combined with the limited volume of customers for each UNIX varient has
+ forced most printer vendors to give up supporting UNIX entirely.</P>
+<P>CUPS is designed to eliminate<I> the printing problem</I>. One common
+ printing system can be used by all UNIX varients to support the
+ printing needs of users. Printer vendors can use its modular filter
+ interface to develop a single driver program that supports a wide range
+ of file formats with little or no effort. Since CUPS provides both the
+ System V and Berkeley printing commands, users (and applications) can
+ reap the benefits of this new technology with no changes.</P>
+<H2><A NAME="2_2">The Technology</A></H2>
+<P>CUPS is based upon an emerging Internet standard called the Internet
+ Printing Protocol. IPP has been embraced by dozens of printer and
+ printer server manufacturers and is supported by Microsoft Windows
+ 2000.</P>
+<P>IPP defines a standard protocol for printing as well as managing
+ print jobs and printer options like media size, resolution, and so
+ forth. Like all IP-based protocols, IPP can be used locally or over the
+ Internet to printers hundreds or thousands of miles away. Unlike other
+ protocols, however, IPP also supports access control, authentication,
+ and encryption, making it a much more capable and secure printing
+ solution than older ones.</P>
+<P>IPP is layered on top of the Hyper-Text Transport Protocol (&quot;HTTP&quot;)
+ which is the basis of web servers on the Internet. This allows users to
+ view documentation, check status information on a printer or server,
+ and manage their printers, classes, and jobs using their web browser.</P>
+<P>CUPS provides a complete IPP/1.1 based printing system that provides
+ Basic, Digest, and local certificate authentication and user, domain,
+ or IP-based access control. TLS encryption will be available in future
+ versions of CUPS.</P>
+<H2><A NAME="2_3">Jobs</A></H2>
+<P>Each file or set of files that is submitted for printing is called a<I>
+ job</I>. Jobs are identified by a unique number starting at 1 and are
+ assigned to a particular destination, usually a printer. Jobs can also
+ have options associated with them such as media size, number of copies,
+ and priority.</P>
+<H2><A NAME="2_4">Classes</A></H2>
+<P>CUPS supports collections of printers known as<I> classes</I>. Jobs
+ sent to a class are forwarded to the first available printer in the
+ class.</P>
+<H2><A NAME="2_5">Filters</A></H2>
+<P>Filters allow a user or application to print many types of files
+ without extra effort. Print jobs sent to a CUPS server are filtered
+ before sending them to a printer. Some filters convert job files to
+ different formats that the printer can understand. Others perform page
+ selection and ordering tasks.</P>
+<P>CUPS provides filters for printing many types of image files, HP-GL/2
+ files, PDF files, and text files. CUPS also supplies PostScript and
+ image file Raster Image Processor (&quot;RIP&quot;) filters that convert
+ PostScript or image files into bitmaps that can be sent to a raster
+ printer.</P>
+<H2><A NAME="2_6">Backends</A></H2>
+<P>Backends perform the most important task of all - they send the
+ filtered print data to the printer.</P>
+<P>CUPS provides backends for printing over parallel, serial, and USB
+ ports, and over the network via the IPP, JetDirect (AppSocket), and
+ Line Printer Daemon (&quot;LPD&quot;) protocols. Additional backends are
+ available in network service packages such as the SMB backend included
+ with the popular SAMBA software.</P>
+<P>Backends are also used to determine the available devices. On startup
+ each backend is asked for a list of devices it supports, and any
+ information that is available. This allows the parallel backend to tell
+ CUPS that an EPSON Stylus Color 600 printer is attached to parallel
+ port 1, for example.</P>
+<H2><A NAME="2_7">Printer Drivers</A></H2>
+<P>Printer drivers in CUPS consist of one of more filters specific to a
+ printer. CUPS includes sample printer drivers for Hewlett-Packard
+ LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color,
+ and Stylus Photo printers. While these drivers do not generate optimal
+ output for the different printer models, they do provide basic printing
+ and demonstrate how you can write your own printer drivers and
+ incorporate them into CUPS.</P>
+<H2><A NAME="2_8">Networking</A></H2>
+<P>Printers and classes on the local system are automatically shared
+ with other systems on the network. This allows you to setup one system
+ to print to a printer and use this system as a printer server or spool
+ host for all of the others. Users may then select a local printer by
+ name or a remote printer using &quot;name@server&quot;.</P>
+<P>CUPS also provides<I> implicit classes</I>, which are collections of
+ printers and/or classes with the same name. This allows you to setup
+ multiple servers pointing to the same physical network printer, for
+ example, so that you aren't relying on a single system for printing.
+ Because this also works with printer classes, you can setup multiple
+ servers and printers and never worry about a single point of failure
+ unless all of the printers and servers go down!</P>
+<H1 ALIGN="RIGHT"><A NAME="CUPS_API">2 - The CUPS API</A></H1>
+<P>This chapter describes the CUPS Application Programmers Interface
+ (&quot;API&quot;).</P>
+<H2><A NAME="3_1">The CUPS API Library</A></H2>
+<P>The CUPS library provides a whole collection of interfaces needed to
+ support the internal needs of the CUPS software as well as the needs of
+ applications, filters, printer drivers, and backends.</P>
+<P>Unlike the rest of CUPS, the CUPS API library is provided under the
+ GNU Library General Public License. This means that you can use the
+ CUPS API library in both proprietary and open-source programs.</P>
+<P>Programs that use the CUPS API library typically will include the <CODE>
+&lt;cups/cups.h&gt;</CODE> header file:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+jobid = cupsPrintFile(&quot;myprinter&quot;, &quot;filename.ps&quot;, &quot;title&quot;,
+ num_options, options);
+</PRE>
+</UL>
+<P>Use the <CODE>-lcups</CODE> compiler option when linking to the CUPS
+ API library:</P>
+<UL>
+<PRE>
+<B>cc -o program program.c -lcups ENTER</B>
+</PRE>
+</UL>
+<P>Additional options and libraries may be required depending on the
+ operating system and the location of the CUPS API library.</P>
+<H3><A NAME="3_1_1">Detecting the CUPS API Library in GNU Autoconf</A></H3>
+<P>GNU autoconf is a popular configuration tool used by many programs.
+ Add the following lines to your<VAR> configure.in</VAR> file to check
+ for the CUPS API library in your configuration script:</P>
+<UL>
+<PRE>
+AC_CHECK_LIB(socket,socket,
+if test &quot;$uname&quot; != &quot;IRIX&quot;; then
+ LIBS=&quot;-lsocket $LIBS&quot;
+else
+ echo &quot;Not using -lsocket since you are running IRIX.&quot;
+fi)
+AC_CHECK_LIB(nsl,gethostbyaddr,
+if test &quot;$uname&quot; != &quot;IRIX&quot;; then
+ LIBS=&quot;-lnsl $LIBS&quot;
+else
+ echo &quot;Not using -lnsl since you are running IRIX.&quot;
+fi)
+
+AC_CHECK_LIB(cups,httpConnect)
+</PRE>
+</UL>
+<H2><A NAME="3_2">Printing Services</A></H2>
+<P>The CUPS API library provides some basic printing services for
+ applications that need to print files.</P>
+<H3><A NAME="3_2_1">Include Files</A></H3>
+<P>The include file used by all of these functions is <CODE>
+&lt;cups/cups.h&gt;</CODE>:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+</PRE>
+</UL>
+<H3><A NAME="3_2_2">Printing a File</A></H3>
+<P>The CUPS API provides two functions for printing files. The first is <CODE>
+cupsPrintFile</CODE> which prints a single named file:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int jobid;
+
+...
+
+jobid = cupsPrintFile(&quot;<I>name</I>&quot;, &quot;<I>filename</I>&quot;, &quot;<I>title</I>&quot;, 0, NULL);
+</PRE>
+</UL>
+<P>The <CODE>name</CODE> string is the name of the printer or class to
+ print to. The <CODE>filename</CODE> string is the name of the file to
+ print. The <CODE>title</CODE> string is the name of the print job, e.g.
+ &quot;Acme Word Document&quot;.</P>
+<P>The return value is a unique ID number for the print job or 0 if
+ there was an error.</P>
+<H3><A NAME="3_2_3">Printing Multiple Files</A></H3>
+<P>The second printing function is <CODE>cupsPrintFiles</CODE>:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int jobid;
+int num_files;
+const char *files[100];
+...
+
+jobid = cupsPrintFiles(&quot;name&quot;, <I>num_files</I>, <I>files</I>, &quot;title&quot;, 0, NULL);
+</PRE>
+</UL>
+<P>Instead of passing a filename string as with <CODE>cupsPrintFile()</CODE>
+ you pass a file count (<CODE>num_files</CODE>) and filename pointer
+ array (<CODE>files</CODE>) for each file that you want to print.</P>
+<P>As with <CODE>cupsPrintFile()</CODE> the return value is a unique ID
+ for the print job.</P>
+<H3><A NAME="3_2_4">Cancelling Jobs</A></H3>
+<P>The <CODE>cupsCancelJob()</CODE> function cancels a queued print job:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int jobid;
+int status;
+...
+
+status = cupsCancelJob(&quot;<I>name</I>&quot;, <I>jobid</I>);
+</PRE>
+</UL>
+<P>The <CODE>name</CODE> string specifies the destination and is used to
+ determine the server to send the request to. The <CODE>jobid</CODE>
+ value is the integer returned from a previous <CODE>cupsPrintFile()</CODE>
+ or <CODE>cupsPrintFiles()</CODE> call.</P>
+<P><CODE>cupsCancelJob()</CODE> returns <CODE>1</CODE> if the job was
+ successfully cancelled and <CODE>0</CODE> if there was an error.</P>
+<H3><A NAME="3_2_5">Getting the Available Printers and Classes</A></H3>
+<P>The <CODE>cupsGetDests()</CODE> function can be used to get a list of
+ the available printers, classes, and instances that a user has defined:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int num_dests;
+cups_dest_t *dests;
+
+...
+
+num_dests = cupsGetDests(&amp;dests);
+</PRE>
+</UL>
+<P>Each destination is stored in a <CODE>cups_dest_t</CODE> structure
+ which defines the printer or class name, the instance name (if any), if
+ it is the default destination, and the default options the user has
+ defined for the destination:</P>
+<UL>
+<PRE>
+typedef struct /**** Destination ****/
+{
+ char *name, /* Printer or class name */
+ *instance; /* Local instance name or NULL */
+ int is_default; /* Is this printer the default? */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+} cups_dest_t;
+</PRE>
+</UL>
+<P>The destinations are sorted by name and instance for your
+ convenience. Once you have the list of available destinations, you can
+ lookup a specific destination using the <CODE>cupsGetDest()</CODE>
+ function:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int num_dests;
+cups_dest_t *dests;
+cups_dest_t *mydest;
+
+...
+
+mydest = cupsGetDest(&quot;<I>name</I>&quot;, &quot;<I>instance</I>&quot;, num_dests, dests);
+</PRE>
+</UL>
+<P>The <CODE>name</CODE> string is the printer or class name. You can
+ pass a value of <CODE>NULL</CODE> to get the default destination.</P>
+<P>The <CODE>instance</CODE> string is the user-defined instance name.
+ Pass <CODE>NULL</CODE> to select the default instance, e.g. &quot;name&quot;
+ instead of &quot;name/instance&quot;.</P>
+<H3><A NAME="3_2_6">Printing with Options</A></H3>
+<P>All of the previous printing examples have passed <CODE>0</CODE> and <CODE>
+NULL</CODE> for the last two arguments to the <CODE>cupsPrintFile()</CODE>
+ and <CODE>cupsPrintFiles()</CODE> functions. These last two arguments
+ are the number of options and a pointer to the option array:</P>
+<UL>
+<PRE>
+int cupsPrintFile(const char *name, const char *filename, const char *title,
+ int num_options, cups_option_t *options);
+int cupsPrintFiles(const char *name, int num_files, const char **files,
+ const char *title, int num_options,
+ cups_option_t *options);
+</PRE>
+</UL>
+<P>The <CODE>cups_option_t</CODE> structure holds each option and its
+ value. These are converted as needed and passed to the CUPS server when
+ printing a file.</P>
+<P>The simplest way of handling options is to use the <CODE>num_options</CODE>
+ and <CODE>options</CODE> members of the <CODE>cups_dest_t</CODE>
+ structure described earlier:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int jobid;
+int num_dests;
+cups_dest_t *dests;
+cups_dest_t *mydest;
+
+...
+
+mydest = cupsGetDest(&quot;<I>name</I>&quot;, &quot;<I>instance</I>&quot;, num_dests, dests);
+
+jobid = cupsPrintFile(mydest-&gt;name, &quot;filename&quot;, &quot;title&quot;,
+ mydest-&gt;num_options, mydest-&gt;options);
+</PRE>
+</UL>
+<P>This effectively uses the options a user has previous selected
+ without a lot of code.</P>
+<H3><A NAME="3_2_7">Setting Printer Options</A></H3>
+<P>Options can also be set by your program using the <CODE>
+cupsAddOption()</CODE> function:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int num_options;
+cups_option_t *options;
+
+...
+
+num_options = 0;
+options = NULL;
+
+...
+
+num_options = cupsAddOption(&quot;<I>name</I>&quot;, &quot;<I>value</I>&quot;, num_options, &amp;options);
+num_options = cupsAddOption(&quot;<I>name</I>&quot;, &quot;<I>value</I>&quot;, num_options, &amp;options);
+num_options = cupsAddOption(&quot;<I>name</I>&quot;, &quot;<I>value</I>&quot;, num_options, &amp;options);
+num_options = cupsAddOption(&quot;<I>name</I>&quot;, &quot;<I>value</I>&quot;, num_options, &amp;options);
+</PRE>
+</UL>
+<P>The <CODE>name</CODE> string is the name of the option, and the <CODE>
+value</CODE> string is the value for that option.</P>
+<P>Each call to <CODE>cupsAddOption()</CODE> returns the new number of
+ options. Since adding two options with the same name overwrites the
+ first value with the second, do not assume that calling <CODE>
+cupsAddOptions()</CODE> 20 times will result in 20 options.</P>
+<P>Call <CODE>cupsFreeOptions</CODE> once you are done using the
+ options:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int num_options;
+cups_option_t *options;
+
+...
+
+cupsFreeOptions(num_options, options);
+</PRE>
+</UL>
+<H3><A NAME="3_2_8">Getting Errors</A></H3>
+<P>If any of the CUPS API printing functions returns an error, the
+ reason for that error can be found by calling <CODE>cupsLastError()</CODE>
+ and <CODE>cupsErrorString()</CODE>. <CODE>cupsLastError()</CODE>
+ returns the last IPP error code that was encountered. <CODE>
+cupsErrorString()</CODE> converts the error code to a localized message
+ string suitable for presentation to the user:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int jobid;
+
+...
+
+if (jobid == 0)
+ puts(cupsErrorString(cupsLastError()));
+</PRE>
+</UL>
+<H3><A NAME="3_2_9">Passwords and Authentication</A></H3>
+<P>CUPS supports authentication of any request, including submission of
+ print jobs. The default mechanism for getting the username and password
+ is to use the login user and a password from the console.</P>
+<P>To support other types of applications, in particular Graphical User
+ Interfaces (&quot;GUIs&quot;), the CUPS API provides functions to set the default
+ username and to register a callback function that returns a password
+ string.</P>
+<P>The<A HREF="#cupsSetPasswordCB"> <CODE>cupsSetPasswordCB()</CODE></A>
+ function is used to set a password callback in your program. Only one
+ function can be used at any time.</P>
+<P>The<A HREF="#cupsSetUser"> <CODE>cupsSetUser()</CODE></A> function
+ sets the current username for authentication. This function can be
+ called by your password callback function to change the current
+ username as needed.</P>
+<P>The following example shows a simple password callback that gets a
+ username and password from the user:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+const char *
+my_password_cb(const char *prompt)
+{
+ char user[65];
+
+
+ puts(prompt);
+
+ /* Get a username from the user */
+ printf(&quot;Username: &quot;);
+ if (fgets(user, sizeof(user), stdin) == NULL)
+ return (NULL);
+
+ /* Strip the newline from the string and set the user */
+ user[strlen(user) - 1] = '\0';
+
+ cupsSetUser(user);
+
+ /* Use getpass() to ask for the password... */
+ return (getpass(&quot;Password: &quot;));
+}
+
+...
+
+cupsSetPasswordCB(my_password_cb);
+</PRE>
+</UL>
+<P>Similarly, a GUI interface could display the prompt string in a
+ window with input fields for the username and password. The username
+ should probably default to the value of<A HREF="#cupsUser"> <CODE>
+cupsUser()</CODE></A> to make things easier on the user.</P>
+<H2><A NAME="3_3">PPD Services</A></H2>
+<P>CUPS includes functions to access and manipulate PostScript Printer
+ Description (&quot;PPD&quot;) files that are used with the printer drivers in
+ CUPS.</P>
+<P>Each PPD file enumerates the available features provided by a
+ printer, including conflict information for specific options (e.g.
+ can't duplex output on envelopes.)</P>
+<H3><A NAME="3_3_1">Include Files</A></H3>
+<P>Include the <CODE>&lt;cups/ppd.h&gt;</CODE> header file to use the PPD
+ functions:</P>
+<UL>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+</PRE>
+</UL>
+<P>This header file is also included by the <CODE>&lt;cups/cups.h&gt;</CODE>
+ header file.</P>
+<H3><A NAME="3_3_2">Getting a PPD File for a Printer</A></H3>
+<P>The <CODE>cupsGetPPD()</CODE> function retrieves the PPD file for the
+ named printer or class:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+const char *filename;
+
+filename = cupsGetPPD(&quot;<I>name</I>&quot;);
+</PRE>
+</UL>
+<P>The <CODE>name</CODE> string is the name of the printer or class,
+ including the remote server name as appropriate (e.g.
+ &quot;printer@server&quot;.)</P>
+<P>The return value is a pointer to a filename in static storage; this
+ value is overwritten with each call to <CODE>cupsGetPPD()</CODE>. If
+ the printer or class does not exist, a <CODE>NULL</CODE> pointer will
+ be returned.</P>
+<H3><A NAME="3_3_3">Loading a PPD File</A></H3>
+<P>The <CODE>ppdOpenFile()</CODE> function &quot;opens&quot; a PPD file and loads
+ it into memory:</P>
+<UL>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+...
+
+ppd_file_t *ppd;
+
+ppd = ppdOpenFile(&quot;<I>filename</I>&quot;);
+</PRE>
+</UL>
+<P>The <CODE>filename</CODE> string is the name of the file to load,
+ such as the value returned by the <CODE>cupsGetPPD()</CODE> function.</P>
+<P>The return value is a pointer to a structure describing the contents
+ of the PPD file or NULL if the PPD file could not be read.</P>
+<H3><A NAME="3_3_4">Freeing PPD File Information</A></H3>
+<P>Once you are done using a PPD file, call the <CODE>ppdClose()</CODE>
+ function to free all memory that has been used:</P>
+<UL>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+...
+
+ppd_file_t *ppd;
+
+...
+
+ppdClose(ppd);
+</PRE>
+</UL>
+<H3><A NAME="3_3_5">The PPD File Structure</A></H3>
+<P>Each PPD file contains a number of capability attributes, printer
+ options, and conflict definitions. The page size options also include
+ the physical margins for the printer and the minimum and maximum sizes
+ for the printer. All of this information is stored in the <CODE>
+ppd_file_t</CODE> structure.</P>
+<H4>Capabilities</H4>
+<P>Each PPD file contains a number of informational attributes that
+ describe the capabilities of the printer. These are provided in the <CODE>
+ppd_file_t</CODE> structure in the following members:
+<CENTER>
+<TABLE BORDER="1" WIDTH="80%">
+<TR><TH>Member</TH><TH>Type</TH><TH>Description</TH></TR>
+<TR><TD><CODE>accurate_screens</CODE></TD><TD><CODE>int</CODE></TD><TD>1
+ = supports accurate screens</TD></TR>
+<TR><TD><CODE>color_device</CODE></TD><TD><CODE>int</CODE></TD><TD>1 =
+ color device</TD></TR>
+<TR><TD><CODE>colorspace</CODE></TD><TD><CODE>ppd_cs_t</CODE></TD><TD>
+Default colorspace: PPD_CS_CMYK, PPD_CS_CMY, PPD_CS_GRAY, PPD_CS_RGB,
+ PPD_CS_RGBK, PPD_CS_N</TD></TR>
+<TR><TD><CODE>contone_only</CODE></TD><TD><CODE>int</CODE></TD><TD>1 =
+ printer is continuous tone only</TD></TR>
+<TR><TD><CODE>num_emulations
+<BR> emulations</CODE></TD><TD><CODE>int
+<BR> ppd_emul_t *</CODE></TD><TD>Emulations supported by the printer</TD>
+</TR>
+<TR><TD><CODE>flip_duplex</CODE></TD><TD><CODE>int</CODE></TD><TD>1 =
+ need to flip odd pages when duplexing</TD></TR>
+<TR><TD><CODE>num_fonts
+<BR> fonts</CODE></TD><TD><CODE>int
+<BR> char **</CODE></TD><TD>The fonts available on the printer.</TD></TR>
+<TR><TD><CODE>jcl_begin
+<BR> jcl_ps
+<BR> jcl_end</CODE></TD><TD><CODE>char *</CODE></TD><TD>Job Control
+ Language commands for PostScript output</TD></TR>
+<TR><TD><CODE>landscape</CODE></TD><TD><CODE>int</CODE></TD><TD>
+Landscape orientation, -90 or 90 degrees</TD></TR>
+<TR><TD><CODE>lang_encoding</CODE></TD><TD><CODE>char *</CODE></TD><TD>
+The character used for the option strings</TD></TR>
+<TR><TD><CODE>lang_version</CODE></TD><TD><CODE>char *</CODE></TD><TD>
+The language used for the options strings (English, French, etc.)</TD></TR>
+<TR><TD><CODE>language_level</CODE></TD><TD><CODE>int</CODE></TD><TD>
+PostScript language level, 1 to 3</TD></TR>
+<TR><TD><CODE>manual_copies</CODE></TD><TD><CODE>int</CODE></TD><TD>1 =
+ Copies are done manually</TD></TR>
+<TR><TD><CODE>model_number</CODE></TD><TD><CODE>int</CODE></TD><TD>
+Driver-specific model number.</TD></TR>
+<TR><TD><CODE>patches</CODE></TD><TD><CODE>char *</CODE></TD><TD>Patch
+ commands to send to the printer</TD></TR>
+<TR><TD><CODE>manufacturer</CODE></TD><TD><CODE>char *</CODE></TD><TD>
+The Manufacturer attribute from the PPD file, if any</TD></TR>
+<TR><TD><CODE>modelname</CODE></TD><TD><CODE>char *</CODE></TD><TD>The
+ ModelName attribute from the PPD file</TD></TR>
+<TR><TD><CODE>nickname</CODE></TD><TD><CODE>char *</CODE></TD><TD>The
+ NickName attribute from the PPD file, if any</TD></TR>
+<TR><TD><CODE>product</CODE></TD><TD><CODE>char *</CODE></TD><TD>The
+ Product attribute from the PPD file, if any</TD></TR>
+<TR><TD><CODE>shortnickname</CODE></TD><TD><CODE>char *</CODE></TD><TD>
+The ShortNickName attribute from the PPD file, if any</TD></TR>
+<TR><TD><CODE>throughput</CODE></TD><TD><CODE>int</CODE></TD><TD>Number
+ of pages per minute</TD></TR>
+<TR><TD><CODE>ttrasterizer</CODE></TD><TD><CODE>char *</CODE></TD><TD>
+The TruType font rasterizer (Type42)</TD></TR>
+<TR><TD><CODE>variable_sizes</CODE></TD><TD><CODE>int</CODE></TD><TD>1 =
+ supports variable sizes</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H4>Options and Groups</H4>
+<P>PPD files support multiple options, which are stored in <CODE>
+ppd_option_t</CODE> and <CODE>ppd_choice_t</CODE> structures by the PPD
+ functions.</P>
+<P>Each option in turn is associated with a group stored in the <CODE>
+ppd_group_t</CODE> structure. Groups can be specified in the PPD file;
+ if an option is not associated with a group then it is put in a
+ &quot;General&quot; or &quot;Extra&quot; group depending on the option.</P>
+<P>Groups can also have sub-groups; CUPS currently limits the depth of
+ sub-groups to 1 level to reduce programming complexity.</P>
+<H4>Conflicts</H4>
+<P>PPD files support specification of conflict conditions between
+ different options. Conflicts are stored in <CODE>ppd_conflict_t</CODE>
+ structures which specify the options that conflict with each other.</P>
+<H4>Page Sizes</H4>
+<P>PPD files specify all of the available pages sizes and the physical
+ margins associated with them. These sizes are stored in <CODE>
+ppd_size_t</CODE> structures and are available in the <CODE>num_sizes</CODE>
+ and <CODE>sizes</CODE> members of the <CODE>ppd_file_t</CODE>
+ structure. You can lookup a particular page size with the <CODE>
+ppdPageWidth()</CODE>, <CODE>ppdPageLength()</CODE>, and <CODE>
+ppdPageSize()</CODE> functions:</P>
+<UL>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+...
+
+ppd_file_t *ppd;
+ppd_size_t *size;
+float width;
+float length;
+
+...
+
+size = ppdPageSize(ppd, &quot;<I>size</I>&quot;);
+width = ppdPageWidth(ppd, &quot;<I>size</I>&quot;);
+length = ppdPageLength(ppd, &quot;<I>size</I>&quot;);
+</PRE>
+</UL>
+<P>The <CODE>size</CODE> string is the named page size option. The width
+ and length are in points; there are 72 points per inch. The <CODE>
+ppd_size_t</CODE> structure contains the width, length, and margin
+ information:</P>
+<UL>
+<PRE>
+typedef struct /**** Page Sizes ****/
+{
+ int marked; /* Page size selected? */
+ char name[41]; /* Media size option */
+ float width, /* Width of media in points */
+ length, /* Length of media in points */
+ left, /* Left printable margin in points */
+ bottom, /* Bottom printable margin in points */
+ right, /* Right printable margin in points */
+ top; /* Top printable margin in points */
+} ppd_size_t;
+</PRE>
+</UL>
+<H4>Custom Page Sizes</H4>
+<P>Besides the standard page sizes listed in a PPD file, some printers
+ support variable or custom page sizes. If <CODE>variables_sizes</CODE>
+ is non-zero, the <CODE>custom_min</CODE>, <CODE>custom_max</CODE>, and <CODE>
+custom_margins</CODE> members of the <CODE>ppd_file_t</CODE> structure
+ define the limits of the variable sizes.</P>
+<P>To get the resulting media size, use a page size string of <CODE>
+Custom.<I>width</I>x<I>length</I></CODE>, where <CODE>width</CODE> and <CODE>
+length</CODE> are integer values in points:</P>
+<UL>
+<PRE>
+Custom.612x792 [8.5 inches wide, 11 inches long]
+Custom.1224x792 [17 inches wide, 11 inches long]
+</PRE>
+</UL>
+<H3><A NAME="3_3_6">Marking Options</A></H3>
+<P>Before marking any user-defined options, call the <CODE>
+ppdMarkDefaults()</CODE> function to mark the default options from the
+ PPD file:</P>
+<UL>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+...
+
+ppd_file_t *ppd;
+
+...
+
+ppdMarkDefaults(ppd);
+</PRE>
+</UL>
+<P>Then call the <CODE>ppdMarkOption()</CODE> function to mark
+ individual options:</P>
+<UL>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+...
+
+ppd_file_t *ppd;
+int conflicts;
+
+...
+
+conflicts = ppdMarkOption(ppd, &quot;<I>name</I>&quot;, &quot;<I>value</I>&quot;);
+</PRE>
+</UL>
+<P>The <CODE>name</CODE> and <CODE>value</CODE> strings choose a
+ particular option and choice, respectively. The return value is 0 if
+ there are not conflicts created by the selection.</P>
+<P>CUPS also provides a convenience function for marking all options in
+ the <CODE>cups_option_t</CODE> structure:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+ppd_file_t *ppd;
+int num_options;
+cups_option_t *options;
+int conflicts;
+
+...
+
+conflicts = cupsMarkOptions(ppd, num_options, options);
+</PRE>
+</UL>
+<P>The <CODE>cupsMarkOptions()</CODE> function also handles mapping the
+ IPP job template attributes to PPD options. The return value is the
+ number of conflicts present.</P>
+<H3><A NAME="3_3_7">Checking for Conflicts</A></H3>
+<P>The <CODE>ppdMarkOption()</CODE> and <CODE>cupsMarkOptions()</CODE>
+ functions return the number of conflicts with the currently marked
+ options.</P>
+<P>Call the <CODE>ppdConflicts()</CODE> function to get the number of
+ conflicts after you have marked all of the options:</P>
+<UL>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+ppd_file_t *ppd;
+int conflicts;
+
+...
+
+conflicts = ppdConflicts(ppd);
+</PRE>
+</UL>
+<P>The return value is the number of conflicting options, or 0 if there
+ are no conflicts.</P>
+<H1 ALIGN="RIGHT"><A NAME="WRITING_FILTERS">3 - Writing Filters</A></H1>
+<P>This chapter describes how to write a file filter for CUPS.</P>
+<H2><A NAME="4_1">Overview</A></H2>
+<P>File filters are programs that convert from one or more MIME types to
+ another type. Filters use a common command-line and environment
+ interface that allows them to be joined as needed to print files to any
+ type of printer.</P>
+<H3><A NAME="4_1_1">Security Considerations</A></H3>
+<P>Filters are normally run as a non-priviledged user, so the major
+ security consideration is resource utilization - filters should not
+ depend on unlimited amounts of memory and disk space.</P>
+<H3><A NAME="4_1_2">Users and Groups</A></H3>
+<P>The default CUPS configuration runs filters as user &quot;lp&quot; and group
+ &quot;other&quot;.</P>
+<H3><A NAME="4_1_3">Temporary Files</A></H3>
+<P>Temporary files should be created in the directory specified by the
+ &quot;TMPDIR&quot; environment variable. The<A HREF="#cupsTempFile"> <CODE>
+cupsTempFile()</CODE></A> function can be used to safely choose
+ temporary files in this directory.</P>
+<H3><A NAME="4_1_4">Sending Messages to the User</A></H3>
+<P>The CUPS scheduler collects messages sent to the standard error file
+ by the filter. These messages are relayed to the user based upon the
+ scheduler <CODE>LogLevel</CODE> directive.</P>
+<P>The type of message is determined by an initial prefix sent on each
+ line:</P>
+<UL>
+<LI><CODE>DEBUG:</CODE> - a debug message</LI>
+<LI><CODE>INFO:</CODE> - an informational message</LI>
+<LI><CODE>WARNING:</CODE> - a warning message</LI>
+<LI><CODE>ERROR:</CODE> - an error message</LI>
+<LI><CODE>PAGE:</CODE> - a page accounting message</LI>
+</UL>
+<P>If the line of text does not begin with any of the above prefixes, it
+ is treated as a debug message. Text following the prefix is copied to
+ the <CODE>printer-state-message</CODE> attribute for the printer, and
+ also added to the<VAR> error_log</VAR> unless it is an informational or
+ page accounting message.</P>
+<H3><A NAME="4_1_5">Page Accounting</A></H3>
+<P>Page accounting messages are used to inform the server when one or
+ more pages are printed. Each line has the form:</P>
+<UL>
+<PRE>
+PAGE: page-number copy-count
+</PRE>
+</UL>
+<P>The<I> page-number</I> field is the current page number, starting at
+ 1. The<I> copy-count</I> field specifies the number of copies of that
+ page that was produced.</P>
+<P>Page account messages are added to the<VAR> page_log</VAR> file and
+ cause the <CODE>job-sheets-completed</CODE> attribute to be updated for
+ the job.</P>
+<H3><A NAME="4_1_6">Command-Line Arguments</A></H3>
+<P>Every filter accepts exactly 6 or 7 command-line arguments:</P>
+<UL>
+<PRE>
+printer job user title copies options [filename]
+</PRE>
+<LI><CODE>printer</CODE> - The name of the printer queue (normally this
+ is the name of the program being run)</LI>
+<LI><CODE>job</CODE> - The numeric job ID for the job being printed</LI>
+<LI><CODE>user</CODE> - The string from the <CODE>originating-user-name</CODE>
+ attribute</LI>
+<LI><CODE>title</CODE> - The string from the <CODE>job-name</CODE>
+ attribute</LI>
+<LI><CODE>copies</CODE> - The numeric value from the <CODE>number-copies</CODE>
+ attribute</LI>
+<LI><CODE>options</CODE> - String representations of the job template
+ attributes, separated by spaces. Boolean attributes are provided as
+ &quot;name&quot; for true values and &quot;noname&quot; for false values. All other
+ attributes are provided as &quot;name=value&quot; for single-valued attributes
+ and &quot;name=value1,value2,...,valueN&quot; for set attributes</LI>
+<LI><CODE>filename</CODE> - The request file</LI>
+</UL>
+<P>The<I> filename</I> argument is only provided to the first filter in
+ the chain; all filters<B> must</B> be prepared to read the print file
+ from the standard input if the<I> filename</I> argument is omitted.</P>
+<H3><A NAME="4_1_7">Copy Generation</A></H3>
+<P>The<I> copies</I> argument specifies the number of copies to produce
+ of the input file. In general, you should only generate copies if the<I>
+ filename</I> argument is supplied. The only exception to this are
+ filters that produce device-independent PostScript output (without any
+ printer commands from the printer's PPD file), since the PostScript
+ filter <CODE>pstops</CODE> is responsible for copy generation.</P>
+<H3><A NAME="4_1_8">Environment Variables</A></H3>
+<P>Every filter receives a fixed set of environment variables that can
+ be used by the filter:</P>
+<UL>
+<LI><CODE>CHARSET</CODE> - The character set used by the client for this
+ print file</LI>
+<LI><CODE>CONTENT_TYPE</CODE> - The original document type, such as
+ &quot;application/postscript&quot;</LI>
+<LI><CODE>CUPS_DATADIR</CODE> - The location of CUPS data files</LI>
+<LI><CODE>CUPS_SERVERROOT</CODE> - The location of CUPS configuration
+ files</LI>
+<LI><CODE>DEVICE_URI</CODE> - The output device URI</LI>
+<LI><CODE>LANG</CODE> - The language used by the client for this print
+ file</LI>
+<LI><CODE>PATH</CODE> - The execution path exported to the filter</LI>
+<LI><CODE>PPD</CODE> - The full filename of the printer's PPD file</LI>
+<LI><CODE>PRINTER</CODE> - The name of the printer queue</LI>
+<LI><CODE>RIP_CACHE</CODE> - The maximum amount of memory each filter
+ should use</LI>
+<LI><CODE>SOFTWARE</CODE> - The name of the CUPS software, typically
+ &quot;CUPS/1.1&quot;</LI>
+<LI><CODE>TZ</CODE> - The local timezone</LI>
+<LI><CODE>USER</CODE> - The name of the current user</LI>
+</UL>
+<H2><A NAME="4_2">Dissecting the HP-GL/2 Filter</A></H2>
+<P>The HP-GL/2 filter (<CODE>hpgltops</CODE>) provided with CUPS is a
+ complex program that converts HP-GL/2 files into device-independent
+ PostScript output. Since it produces device-independent PostScript
+ output, it does not need to handle copy generation or writing printer
+ options from the printer's PPD file.</P>
+<H3><A NAME="4_2_1">Initializing the Filter</A></H3>
+<P>The first task of any filter is to ensure that the correct number of
+ command-line arguments are present:</P>
+<UL>
+<PRE>
+if (argc &lt; 6 || argc &gt; 7)
+{
+ fputs(&quot;ERROR: hpgltops job-id user title copies options [file]\n&quot;, stderr);
+ return (1);
+}
+</PRE>
+</UL>
+<P>After this you open the print file or read from the standard input as
+ needed:</P>
+<UL>
+<PRE>
+FILE *fp;
+
+/*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+if (argc == 6)
+ fp = stdin;
+else
+{
+ /*
+ * Try to open the print file...
+ */
+
+ if ((fp = fopen(argv[6], &quot;rb&quot;)) == NULL)
+ {
+ perror(&quot;ERROR: unable to open print file - &quot;);
+ return (1);
+ }
+}
+</PRE>
+</UL>
+<P>Once the print file has been opened, options can be processed using
+ the<A HREF="#cupsParseOptions"> <CODE>cupsParseOptions()</CODE></A> and<A
+HREF="#cupsGetOption"> <CODE>cupsGetOption()</CODE></A> functions:</P>
+<UL>
+<PRE>
+int num_options;
+cups_option_t *options;
+const char *val;
+
+/*
+ * Process command-line options and write the prolog...
+ */
+
+options = NULL;
+num_options = cupsParseOptions(argv[5], 0,
+
+if ((val = cupsGetOption(&quot;blackplot&quot;, num_options, options)) != NULL)
+ shading = 0;
+
+if ((val = cupsGetOption(&quot;fitplot&quot;, num_options, options)) != NULL)
+ FitPlot = 1;
+
+if ((val = cupsGetOption(&quot;penwidth&quot;, num_options, options)) != NULL)
+ PenWidth = (float)atoi(val) * 0.001f;
+</PRE>
+</UL>
+<P>After the options have been processed, the filter writes PostScript
+ code to the standard output based on the print file, closes the print
+ file (as needed), and returns 0 to the scheduler.</P>
+<H2><A NAME="4_3">PostScript Output</A></H2>
+<P>Filters that produce PostScript output must generate output
+ conforming to the Adobe Document Structuring Conventions, 3.0. In
+ general this means the beginning of each file must begin with:</P>
+<UL>
+<PRE>
+%!PS-Adobe-3.0
+%%BoundingBox: left bottom right top
+%%Pages: (atend)
+%%EndComments
+</PRE>
+</UL>
+<P>The<I> left</I>,<I> bottom</I>,<I> right</I>, and<I> top</I> values
+ are integers in points from the lower-lefthand corner of the page.</P>
+<P>Pages must be surrounded by:</P>
+<UL>
+<PRE>
+%%Page: number number
+gsave
+...
+grestore
+showpage
+</PRE>
+</UL>
+<P>And the end of each file must contain:</P>
+<UL>
+<PRE>
+%%Trailer
+%%Pages: number-pages
+%%EOF
+</PRE>
+</UL>
+<P>These comments allow the PostScript filter to correctly perform page
+ accounting, copy generation, N-up printing, and so forth.</P>
+<H1 ALIGN="RIGHT"><A NAME="WRITING_DRIVERS">4 - Writing Printer Drivers</A>
+</H1>
+<P>This chapter discusses how to write a printer driver, which is a
+ special filter program that converts CUPS raster data into the
+ appropriate commands and data required for a printer.</P>
+<H2><A NAME="5_1">Overview</A></H2>
+<P>Raster printers utilitize PPD files that specify one or more
+ device-specific filters that handle converting print files for the
+ printer. The simplest raster printer drivers provide a single filter
+ that converts CUPS raster data to the printer's native format.</P>
+<H3><A NAME="5_1_1">CUPS Raster Data</A></H3>
+<P>CUPS raster data (<CODE>application/vnd.cups-raster</CODE>) consists
+ of a stream of raster page descriptions produced by one of the RIP
+ filters, such as <CODE>pstoraster</CODE> or <CODE>imagetoraster</CODE>.</P>
+<P>Each page of data begins with a page dictionary structure called<A HREF="#cups_raster_header_t">
+ <CODE>cups_raster_header_t</CODE></A>. This structure contains the
+ colorspace, bits per color, media size, media type, hardware
+ resolution, and so forth.</P>
+<P>After the page dictionary comes the page data which is a
+ full-resolution, uncompressed bitmap representing the page in the
+ printer's output colorspace.</P>
+<H3><A NAME="5_1_2">Page Accounting</A></H3>
+<P>Printer drivers must handle all page accounting. This means they must
+ send &quot;PAGE:&quot; messages to the standard error file for each page (and in
+ many cases, copy) sent to the printer.</P>
+<H3><A NAME="5_1_3">Color Management</A></H3>
+<P>Printer drivers can implement their color management via the <CODE>
+cupsColorProfile</CODE> attributes in the PPD file or internally in the
+ driver from a device-independent colorspace. In general, color
+ management performed by the RIP filters is more efficient than that
+ performed inside printer drivers.</P>
+<P>For example, the <CODE>pstoraster</CODE> filter often only has to
+ perform a color conversion once each time the color is used for
+ multiple output pixels, while the raster filter must convert every
+ pixel on the page.</P>
+<H3><A NAME="5_1_4">Device and Bitmap Variables</A></H3>
+<P>Besides the standard PostScript page device dictionary variables
+ defined in the Adobe PostScript Level 3 reference manual, the CUPS
+ filters support additional variables that are passed in the page device
+ dictionary header for the page and in some cases control the type of
+ raster data that is generated:
+<CENTER>
+<TABLE BORDER="1" WIDTH="90%">
+<TR><TH>Variable</TH><TH>Type</TH><TH>Description</TH></TR>
+<TR><TD>cupsWidth</TD><TD>read-only integer</TD><TD>Width of bitmap in
+ pixels</TD></TR>
+<TR><TD>cupsHeight</TD><TD>read-only integer</TD><TD>Height of bitmap in
+ pixels</TD></TR>
+<TR><TD>cupsMediaType</TD><TD>read-write integer</TD><TD>Device-specific
+ media type code</TD></TR>
+<TR><TD>cupsBitsPerColor</TD><TD>read-write integer</TD><TD>Number of
+ bits per color; 1, 2, 4, and 8 are currently supported</TD></TR>
+<TR><TD>cupsBitsPerPixel</TD><TD>read-only integer</TD><TD>Number of
+ bits per pixel; 1 to 32</TD></TR>
+<TR><TD>cupsBytesPerLine</TD><TD>read-only integer</TD><TD>Number of
+ bytes per line of raster graphics</TD></TR>
+<TR><TD>cupsColorOrder</TD><TD>read-write enum</TD><TD>The order of
+ color values in the bitmap:
+<UL>
+<LI><CODE>CUPS_ORDER_CHUNKED</CODE> - CMYK&nbsp;CMYK&nbsp;CMYK</LI>
+<LI><CODE>CUPS_ORDER_BANDED</CODE> - CCC&nbsp;MMM&nbsp;YYY&nbsp;KKK</LI>
+<LI><CODE>CUPS_ORDER_PLANAR</CODE> - CCC&nbsp;...&nbsp;MMM&nbsp;...&nbsp;YYY&nbsp;...&nbsp;KKK&nbsp;...</LI>
+</UL>
+</TD></TR>
+<TR><TD>cupsColorSpace</TD><TD>read-write enum</TD><TD>The colorspace of
+ the bitmap:
+<UL>
+<LI><CODE>CUPS_CSPACE_W</CODE> - White (luminance)</LI>
+<LI><CODE>CUPS_CSPACE_RGB</CODE> - Red, green, blue</LI>
+<LI><CODE>CUPS_CSPACE_RGBA</CODE> - Red, green, blue, alpha</LI>
+<LI><CODE>CUPS_CSPACE_K</CODE> - Black</LI>
+<LI><CODE>CUPS_CSPACE_CMY</CODE> - Cyan, magenta, yellow</LI>
+<LI><CODE>CUPS_CSPACE_YMC</CODE> - Yellow, magenta, cyan</LI>
+<LI><CODE>CUPS_CSPACE_CMYK</CODE> - Cyan, magenta, yellow, black</LI>
+<LI><CODE>CUPS_CSPACE_YMCK</CODE> - Yellow, magenta, cyan, black</LI>
+<LI><CODE>CUPS_CSPACE_KCMY</CODE> - Black, cyan, magenta, yellow</LI>
+<LI><CODE>CUPS_CSPACE_KCMYcm</CODE> - Black, cyan, magenta, yellow,
+ light cyan, light magenta</LI>
+<LI><CODE>CUPS_CSPACE_GMCK</CODE> - Metallic yellow (gold), metallic
+ magenta, metallic cyan, black</LI>
+<LI><CODE>CUPS_CSPACE_GMCS</CODE> - Metallic yellow (gold), metallic
+ magenta, metallic cyan, metallic grey (silver)</LI>
+<LI><CODE>CUPS_CSPACE_WHITE</CODE> - White pigment (black as white
+ pigment)</LI>
+<LI><CODE>CUPS_CSPACE_GOLD</CODE> - Gold foil (black as gold foil)</LI>
+<LI><CODE>CUPS_CSPACE_SILVER</CODE> - Silver foil (black as silver foil)</LI>
+</UL>
+</TD></TR>
+<TR><TD>cupsCompression</TD><TD>read-write integer</TD><TD>
+Device-specific compression type code</TD></TR>
+<TR><TD>cupsRowCount</TD><TD>read-write integer</TD><TD>Device-specific
+ row count value</TD></TR>
+<TR><TD>cupsRowFeed</TD><TD>read-write integer</TD><TD>Device-specific
+ row feed value</TD></TR>
+<TR><TD>cupsRowStep</TD><TD>read-write integer</TD><TD>Device-specific
+ row step value</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<P>Bitmaps with a colorspace of CUPS_CSPACE_KCMYcm and more than 1 bit
+ per color are transmitted to the raster driver in KCMY colorspace; the
+ driver is responsible for producing the correct separation of normal
+ and light cyan and magenta inks.</P>
+<H2><A NAME="5_2">Dissecting the HP-PCL Driver</A></H2>
+<P>The HP-PCL driver provided with CUPS (<CODE>rastertohp</CODE>)
+ converts bitmap data from the raster filters into HP-PCL commands for
+ most PCL-compatible printers. The actual format of the raster data is
+ controlled by the PPD file being used -<VAR> deskjet.ppd</VAR> or<VAR>
+ laserjet.ppd</VAR>.</P>
+<H3><A NAME="5_2_1">PPD Files</A></H3>
+<P>PPD files play an important part of all raster printer drivers.
+ Options defined in the PPD file contain PostScript commands that
+ control the raster data that is sent to the printer driver.</P>
+<P>A typical CUPS printer driver will include <CODE>ColorModel</CODE>, <CODE>
+InputSlot</CODE>, <CODE>PageSize</CODE>, <CODE>PageRegion</CODE>, and <CODE>
+Resolution</CODE> options. Each option is shown using the standard PPD
+ format:</P>
+<UL>
+<PRE>
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/US Letter: &quot;&lt;&lt;
+/PageSize [612 792]
+/ImagingBBox null
+&gt;&gt; setpagedevice&quot;
+*End
+*PageSize Legal/US Legal: &quot;&lt;&lt;
+/PageSize [612 1008]
+/ImagingBBox null
+&gt;&gt; setpagedevice&quot;
+*End
+*PageSize A4/A4: &quot;&lt;&lt;
+/PageSize [595 842]
+/ImagingBBox null
+&gt;&gt; setpagedevice&quot;
+*End
+*CloseUI: *PageSize
+</PRE>
+</UL>
+<P>The <CODE>OpenUI</CODE> keyword specifies the new option. The first
+ name is the option with an asterisk (*) in front of it. The first name
+ is usually followed by a slash (/) and a human-readable version of the
+ option name.</P>
+<P>Every option<B> must</B> have a default value, specified using the <CODE>
+Default<I>Option</I></CODE> keyword.</P>
+<P>Each option begins with the option name followed by the computer and
+ human-readable values. The PostScript commands follow these inside
+ double quotes. PostScript commands can be provided on a single line:</P>
+<UL>
+<PRE>
+*PageSize A4/A4: &quot;&lt;&lt;/PageSize[595 842]/ImagingBBox null&gt;&gt; setpagedevice&quot;
+</PRE>
+</UL>
+<P>or broken down on separate lines using the <CODE>End</CODE> keyword
+ to terminate them:</P>
+<UL>
+<PRE>
+*PageSize A4/A4: &quot;&lt;&lt;
+/PageSize [595 842]
+/ImagingBBox null
+&gt;&gt; setpagedevice&quot;
+*End
+</PRE>
+</UL>
+<P>The choice of the two formats is usually esthetic. However, each line
+ in a PPD file must not exceed 255 characters, so if your PostScript
+ commands are long you may need to break them up on separate lines.</P>
+<H3><A NAME="5_2_2">Reading Raster Data</A></H3>
+<P>As with any filter, your printer driver should handle raster data
+ from a filename specified on the command-line or from the standard
+ input. The<A HREF="#cupsRasterOpen"> <CODE>cupsRasterOpen()</CODE></A>
+ function opens a raster stream for printing:</P>
+<UL>
+<PRE>
+int fd; /* File descriptor */
+cups_raster_t *ras; /* Raster stream for printing */
+
+
+/*
+ * Check for valid arguments...
+ */
+
+if (argc &lt; 6 || argc &gt; 7)
+{
+ /*
+ * We don't have the correct number of arguments; write an error message
+ * and return.
+ */
+
+ fputs(&quot;ERROR: rastertopcl job-id user title copies options [file]\n&quot;, stderr);
+ return (1);
+}
+
+/*
+ * Open the page stream...
+ */
+
+if (argc == 7)
+{
+ if ((fd = open(argv[6], O_RDONLY)) == -1)
+ {
+ perror(&quot;ERROR: Unable to open raster file - &quot;);
+ sleep(1);
+ return (1);
+ }
+}
+else
+ fd = 0;
+
+ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
+</PRE>
+</UL>
+<P>Once you have opened the raster stream you just need to read each
+ page and print it:</P>
+<UL>
+<PRE>
+cups_raster_header_t header;
+int y;
+unsigned char data[8192];
+
+while (cupsRasterReadHeader(ras, &amp;header))
+{
+ ... initialize the printer ...
+ for (y = header.cupsHeight; y &gt; 0; y ++)
+ {
+ cupsRasterReadPixels(ras, data, header.cupsBytesPerLine);
+ ... send raster line to printer ...
+ }
+}
+</PRE>
+</UL>
+<P>After you have processed all pages, close the raster stream and
+ return:</P>
+<UL>
+<PRE>
+cupsRasterClose(ras);
+
+return (0);
+</PRE>
+</UL>
+<H1 ALIGN="RIGHT"><A NAME="WRITING_BACKENDS">5 - Writing Backends</A></H1>
+<P>This chapter describes how to write a backend for CUPS. Backends
+ communicate directly with printers and allow printer drivers and
+ filters to send data using any type of connection transparently.</P>
+<H2><A NAME="6_1">Overview</A></H2>
+<P>Backends are special filters that communicate with printers directly.
+ They are treated slightly differently than filters, however, and have
+ some unique requirements.</P>
+<H3><A NAME="6_1_1">Security Considerations</A></H3>
+<P>Backends are run as the root user, so special care must be taken to
+ avoid potential security violations. In particular, remember that a
+ backend will be able to manipulate disk files, devices, and other
+ resources that potentially could damage a system or printer.</P>
+<H3><A NAME="6_1_2">Command-Line Arguments</A></H3>
+<P>Besides the standard filter arguments, backends are also run with no
+ arguments to get a list of available devices. This discovery process is
+ described later in this chapter.</P>
+<H3><A NAME="6_1_3">Copy Generation</A></H3>
+<P>Like filters, backends should send multiple copies of the print file
+ only if a filename is supplied on the command-line. Otherwise the
+ backend should assume that the upstream filter has already added the
+ necessary commands or data to produce the multiple copies.</P>
+<H3><A NAME="6_1_4">Page Accounting</A></H3>
+<P>Backend filters generally do not do page accounting, however they
+ should at a minimum produce a single page message for each copy that is
+ produced when a filename is present on the command-line. This is
+ because the user selected &quot;raw&quot; printing and no other accounting
+ information is possible.</P>
+<H3><A NAME="6_1_5">Exclusive Access</A></H3>
+<P>Backends that talk to local character or block devices should open
+ the device file in exclusive mode (<CODE>O_EXCL</CODE>) to cooperate
+ with other printers defined for the same device.</P>
+<H3><A NAME="6_1_6">Retries</A></H3>
+<P>All backends<B> must</B> retry connections to the device. This
+ includes backends that talk to local character or block devices, as the
+ user may define more than one printer queue pointing at the same
+ physical device.</P>
+<P>To prevent excess CPU utilitization, the backend should go to sleep
+ for an amount of time between retries; the CUPS-supplied backends retry
+ once every 30 seconds.</P>
+<H2><A NAME="6_2">Dissecting the Serial Port Backend</A></H2>
+<P>The serial port backend provides support for serial printers. Since
+ it does everything a good backend needs to do, it provides an excellent
+ example of what to do.</P>
+<H3><A NAME="6_2_1">Supporting Device Discovery</A></H3>
+<P>As previously noted, backends are special filter programs that talk
+ to printer devices. Another task a backend must perform is to list the
+ available devices it supports. The backend lists the available devices
+ when no additioanl arguments are supplied on the command-line (i.e.
+ just the command name...)</P>
+<P>The serial backend lists devices by looking at serial port files in
+ the<VAR> /dev</VAR> directory, by consulting a hardware inventory
+ (IRIX), and in some cases by trying to open the ports to see if they
+ actually exist.</P>
+<P>Once it finds a serial port it writes a single line for each port to
+ the standard error file. Each line looks like this:</P>
+<UL>
+<PRE>
+serial serial:/dev/ttyS0?baud=115200 &quot;Unknown&quot; &quot;Serial Port 1&quot;
+</PRE>
+</UL>
+<P>The first word &quot;serial&quot; is the<I> device class</I>; this identifies
+ the class of device which can be used to categorize it in user
+ interfaces. CUPS currently recognizes the following classes:</P>
+<UL>
+<LI>&quot;file&quot; - a disk file.</LI>
+<LI>&quot;direct&quot; - a parallel or fixed-rate serial data port, currently used
+ for Centronics, IEEE-1284, and USB printer ports.</LI>
+<LI>&quot;serial&quot; - a variable-rate serial port.</LI>
+<LI>&quot;network&quot; - a network connection, typically via AppSocket, HTTP,
+ IPP, LPD, or SMB/CIFS protocols.</LI>
+</UL>
+<P>After the device class is the<I> device URI</I>, in this case
+ &quot;serial:/dev/ttyS0?baud=115200&quot;. This is the URI that should be used by
+ the user to select this port. For serial ports, the &quot;baud=115200&quot;
+ specifies the maximum baud rate supported by the port - the actual
+ value will vary based on the speed the user selects for the printer.</P>
+<P>The last two strings are the model and description for the port. The
+ &quot;Unknown&quot; string means that the printer model is unknown - some devices
+ are able to provide a make and model such as &quot;HP DeskJet&quot; that allows
+ users and software to choose an appropriate printer driver more easily.
+ Both the model and description must be enclosed inside double quotes.</P>
+<H3><A NAME="6_2_2">Opening the Serial Port</A></H3>
+<P>As noted previously, all backends should open device files in
+ exclusive mode, and retry as needed until the port is available. The
+ serial port does this using a <CODE>do-while</CODE> loop:</P>
+<UL>
+<PRE>
+do
+{
+ if ((fd = open(resource, O_WRONLY | O_NOCTTY | O_EXCL)) == -1)
+ {
+ if (errno == EBUSY)
+ {
+ fputs(&quot;INFO: Serial port busy; will retry in 30 seconds...\n&quot;, stderr);
+ sleep(30);
+ }
+ else
+ {
+ perror(&quot;ERROR: Unable to open serial port device file&quot;);
+ return (1);
+ }
+ }
+}
+while (fd &lt; 0);
+</PRE>
+</UL>
+<P>If the port is busy or in use by another process, the backend will go
+ to sleep for 30 seconds and try again. If another error is detected a
+ message is sent to the user and the backend aborts the print job until
+ the problem can be corrected.</P>
+<H3><A NAME="6_2_3">Writing Data to the Port</A></H3>
+<P>Network and character devices pose an interesting problem when
+ writing data to the port - they may not be able to write all of the
+ bytes in your buffer before returning. To work around this problem you
+ must loop until all bytes have been written:</P>
+<UL>
+<PRE>
+while (nbytes &gt; 0)
+{
+ if ((wbytes = write(fd, bufptr, nbytes)) &lt; 0)
+ if (errno == ENOTTY)
+ wbytes = write(fd, bufptr, nbytes);
+
+ if (wbytes &lt; 0)
+ {
+ perror(&quot;ERROR: Unable to send print file to printer&quot;);
+ break;
+ }
+
+ nbytes -= wbytes;
+ bufptr += wbytes;
+}
+</PRE>
+</UL>
+<P>The check for the <CODE>ENOTTY</CODE> error is needed on some
+ platforms to clear an error from a previous <CODE>ioctl()</CODE> call.</P>
+<H3><A NAME="6_2_4">Finishing Up</A></H3>
+<P>Once you have sent the print file, return 0 if the file printed
+ successfully or 1 if it did not. This will allow the scheduler to stop
+ the print job if there is a device error, preserving the print job for
+ later printing once the problem has been corrected.</P>
+<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - Software License Agreement</A></H1>
+<H2 ALIGN="CENTER"><A NAME="7_1">Common UNIX Printing System License
+ Agreement</A></H2>
+<P ALIGN="CENTER">Copyright 1997-2002 by Easy Software Products
+<BR> 44141 AIRPORT VIEW DR STE 204
+<BR> HOLLYWOOD, MARYLAND 20636-3111 USA
+<BR>
+<BR> Voice: +1.301.373.9600
+<BR> Email:<A HREF="mailto:cups-info@cups.org"> cups-info@cups.org</A>
+<BR> WWW:<A HREF="http://www.cups.org"> http://www.cups.org</A></P>
+<H3><A NAME="7_1_1">Introduction</A></H3>
+<P>The Common UNIX Printing System<SUP>TM</SUP>, (&quot;CUPS<SUP>TM</SUP>&quot;),
+ is provided under the GNU General Public License (&quot;GPL&quot;) and GNU
+ Library General Public License (&quot;LGPL&quot;), Version 2, with exceptions for
+ Apple operating systems and the OpenSSL toolkit. A copy of the
+ exceptions and licenses follow this introduction.</P>
+<P>The GNU LGPL applies to the CUPS API library, located in the &quot;cups&quot;
+ subdirectory of the CUPS source distribution and in the &quot;cups&quot; include
+ directory and library files in the binary distributions. The GNU GPL
+ applies to the remainder of the CUPS distribution, including the
+ &quot;pdftops&quot; filter which is based upon Xpdf and the CUPS imaging library.</P>
+<P>For those not familiar with the GNU GPL, the license basically allows
+ you to:</P>
+<UL>
+<LI>Use the CUPS software at no charge.</LI>
+<LI>Distribute verbatim copies of the software in source or binary form.</LI>
+<LI>Sell verbatim copies of the software for a media fee, or sell
+ support for the software.</LI>
+<LI>Distribute or sell printer drivers and filters that use CUPS so long
+ as source code is made available under the GPL.</LI>
+</UL>
+<P>What this license<B> does not</B> allow you to do is make changes or
+ add features to CUPS and then sell a binary distribution without source
+ code. You must provide source for any new drivers, changes, or
+ additions to the software, and all code must be provided under the GPL
+ or LGPL as appropriate. The only exceptions to this are the portions of
+ the CUPS software covered by the Apple operating system license
+ exceptions outlined later in this license agreement.</P>
+<P>The GNU LGPL relaxes the &quot;link-to&quot; restriction, allowing you to
+ develop applications that use the CUPS API library under other licenses
+ and/or conditions as appropriate for your application.</P>
+<H3><A NAME="7_1_2">License Exceptions</A></H3>
+<P>In addition, as the copyright holder of CUPS, Easy Software Products
+ grants the following special exceptions:</P>
+<OL>
+<LI><B>Apple Operating System Development License Exception</B>;
+<OL TYPE="a">
+<LI>Software that is developed by any person or entity for an Apple
+ Operating System (&quot;Apple OS-Developed Software&quot;), including but not
+ limited to Apple and third party printer drivers, filters, and backends
+ for an Apple Operating System, that is linked to the CUPS imaging
+ library or based on any sample filters or backends provided with CUPS
+ shall not be considered to be a derivative work or collective work
+ based on the CUPS program and is exempt from the mandatory source code
+ release clauses of the GNU GPL. You may therefore distribute linked
+ combinations of the CUPS imaging library with Apple OS-Developed
+ Software without releasing the source code of the Apple OS-Developed
+ Software. You may also use sample filters and backends provided with
+ CUPS to develop Apple OS-Developed Software without releasing the
+ source code of the Apple OS-Developed Software.</LI>
+<LI>An Apple Operating System means any operating system software
+ developed and/or marketed by Apple Computer, Inc., including but not
+ limited to all existing releases and versions of Apple's Darwin, Mac OS
+ X, and Mac OS X Server products and all follow-on releases and future
+ versions thereof.</LI>
+<LI>This exception is only available for Apple OS-Developed Software and
+ does not apply to software that is distributed for use on other
+ operating systems.</LI>
+<LI>All CUPS software that falls under this license exception have the
+ following text at the top of each source file:<BLOCKQUOTE>This file is
+ subject to the Apple OS-Developed Software exception.</BLOCKQUOTE></LI>
+</OL>
+</LI>
+<LI><B>OpenSSL Toolkit License Exception</B>;
+<OL TYPE="a">
+<LI>Easy Software Products explicitly allows the compilation and
+ distribution of the CUPS software with the OpenSSL Toolkit.</LI>
+</OL>
+</LI>
+</OL>
+<P>No developer is required to provide these exceptions in a derived
+ work.</P>
+<H3><A NAME="7_1_3">Trademarks</A></H3>
+<P>Easy Software Products has trademarked the Common UNIX Printing
+ System, CUPS, and CUPS logo. These names and logos may be used freely
+ in any direct port or binary distribution of CUPS. Please contract Easy
+ Software Products for written permission to use them in derivative
+ products. Our intention is to protect the value of these trademarks and
+ ensure that any derivative product meets the same high-quality
+ standards as the original.</P>
+<H3><A NAME="7_1_4">Binary Distribution Rights</A></H3>
+<P>Easy Software Products also sells rights to the CUPS source code
+ under a binary distribution license for vendors that are unable to
+ release source code for their drivers, additions, and modifications to
+ CUPS under the GNU GPL and LGPL. For information please contact us at
+ the address shown above.</P>
+<P>The Common UNIX Printing System provides a &quot;pdftops&quot; filter that is
+ based on the Xpdf software. For binary distribution licensing of this
+ software, please contact:<BLOCKQUOTE> Derek B. Noonburg
+<BR> Email:<A HREF="mailto:derekn@foolabs.com"> derekn@foolabs.com</A>
+<BR> WWW:<A HREF="http://www.foolabs.com/xpdf/">
+ http://www.foolabs.com/xpdf/</A></BLOCKQUOTE></P>
+<H3><A NAME="7_1_5">Support</A></H3>
+<P>Easy Software Products sells software support for CUPS as well as a
+ commercial printing product based on CUPS called ESP Print Pro. You can
+ find out more at our web site:</P>
+<UL>
+<PRE>
+<A HREF="http://www.easysw.com/">http://www.easysw.com/</A>
+</PRE>
+</UL>
+
+<!-- NEW PAGE -->
+<H2><A NAME="7_2">GNU GENERAL PUBLIC LICENSE</A></H2>
+<P>Version 2, June 1991</P>
+<PRE>
+Copyright 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim
+copies of this license document, but changing it is not allowed.
+</PRE>
+<H4>Preamble</H4>
+<P>The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public License is
+ intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users. This
+ General Public License applies to most of the Free Software
+ Foundation's software and to any other program whose authors commit to
+ using it. (Some other Free Software Foundation software is covered by
+ the GNU Library General Public License instead.) You can apply it to
+ your programs, too.</P>
+<P>When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it in
+ new free programs; and that you know you can do these things.</P>
+<P>To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the software, or if you modify it.</P>
+<P>For example, if you distribute copies of such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have. You must make sure that they, too, receive or can get the
+ source code. And you must show them these terms so they know their
+ rights.</P>
+<P>We protect your rights with two steps: (1) copyright the software,
+ and (2) offer you this license which gives you legal permission to
+ copy, distribute and/or modify the software.</P>
+<P>Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software. If the software is modified by someone else and passed on, we
+ want its recipients to know that what they have is not the original, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.</P>
+<P>Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that redistributors of a free
+ program will individually obtain patent licenses, in effect making the
+ program proprietary. To prevent this, we have made it clear that any
+ patent must be licensed for everyone's free use or not licensed at all.</P>
+<P>The precise terms and conditions for copying, distribution and
+ modification follow.</P>
+<H4>GNU GENERAL PUBLIC LICENSE
+<BR> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+<OL START="0">
+<LI>This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The &quot;Program&quot;, below,
+ refers to any such program or work, and a &quot;work based on the Program&quot;
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language. (Hereinafter, translation is included without limitation in
+ the term &quot;modification&quot;.) Each licensee is addressed as &quot;you&quot;.
+<P>Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ the Program is not restricted, and the output from the Program is
+ covered only if its contents constitute a work based on the Program
+ (independent of having been made by running the Program). Whether that
+ is true depends on what the Program does.</P>
+<LI>You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you conspicuously
+ and appropriately publish on each copy an appropriate copyright notice
+ and disclaimer of warranty; keep intact all the notices that refer to
+ this License and to the absence of any warranty; and give any other
+ recipients of the Program a copy of this License along with the
+ Program.
+<P>You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.</P>
+<LI>You may modify your copy or copies of the Program or any portion of
+ it, thus forming a work based on the Program, and copy and distribute
+ such modifications or work under the terms of Section 1 above, provided
+ that you also meet all of these conditions:
+<OL TYPE="a">
+<LI>You must cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change.</LI>
+<LI>You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any part
+ thereof, to be licensed as a whole at no charge to all third parties
+ under the terms of this License.</LI>
+<LI>if the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the most ordinary way, to print or display an announcement including
+ an appropriate copyright notice and a notice that there is no warranty
+ (or else, saying that you provide a warranty) and that users may
+ redistribute the program under these conditions, and telling the user
+ how to view a copy of this License. (Exception: if the Program itself
+ is interactive but does not normally print such an announcement, your
+ work based on the Program is not required to print an announcement.)</LI>
+</OL>
+<P>These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Program,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Program, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.</P>
+<P>Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.</P>
+<P>In addition, mere aggregation of another work not based on the
+ Program with the Program (or with a work based on the Program) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.</P>
+<LI>You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+<OL TYPE="a">
+<LI>Accompany it with the complete corresponding machine-readable source
+ code, which must be distributed under the terms of Sections 1 and 2
+ above on a medium customarily used for software interchange; or,</LI>
+<LI>Accompany it with a written offer, valid for at least three years,
+ to give any third party, for a charge no more than your cost of
+ physically performing source distribution, a complete machine-readable
+ copy of the corresponding source code, to be distributed under the
+ terms of Sections 1 and 2 above on a medium customarily used for
+ software interchange; or,</LI>
+<LI>Accompany it with the information you received as to the offer to
+ distribute corresponding source code. (This alternative is allowed only
+ for noncommercial distribution and only if you received the program in
+ object code or executable form with such an offer, in accord with
+ Subsection b above.)</LI>
+</OL>
+<P>The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to control
+ compilation and installation of the executable. However, as a special
+ exception, the source code distributed need not include anything that
+ is normally distributed (in either source or binary form) with the
+ major components (compiler, kernel, and so on) of the operating system
+ on which the executable runs, unless that component itself accompanies
+ the executable.</P>
+<P>If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent access
+ to copy the source code from the same place counts as distribution of
+ the source code, even though third parties are not compelled to copy
+ the source along with the object code.</P>
+<LI>You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt otherwise
+ to copy, modify, sublicense or distribute the Program is void, and will
+ automatically terminate your rights under this License. However,
+ parties who have received copies, or rights, from you under this
+ License will not have their licenses terminated so long as such parties
+ remain in full compliance.</LI>
+<LI>You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying the
+ Program or works based on it.</LI>
+<LI>Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject to
+ these terms and conditions. You may not impose any further restrictions
+ on the recipients' exercise of the rights granted herein. You are not
+ responsible for enforcing compliance by third parties to this License.</LI>
+<LI>If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all. For example, if a patent license
+ would not permit royalty-free redistribution of the Program by all
+ those who receive copies directly or indirectly through you, then the
+ only way you could satisfy both it and this License would be to refrain
+ entirely from distribution of the Program.
+<P>If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.</P>
+<P>It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.</P>
+<P>This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.</P>
+<LI>If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License may
+ add an explicit geographical distribution limitation excluding those
+ countries, so that distribution is permitted only in or among countries
+ not thus excluded. In such case, this License incorporates the
+ limitation as if written in the body of this License.</LI>
+<LI>The Free Software Foundation may publish revised and/or new versions
+ of the General Public License from time to time. Such new versions will
+ be similar in spirit to the present version, but may differ in detail
+ to address new problems or concerns.
+<P>Each version is given a distinguishing version number. If the Program
+ specifies a version number of this License which applies to it and &quot;any
+ later version&quot;, you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Program does not specify a version
+ number of this License, you may choose any version ever published by
+ the Free Software Foundation.</P>
+<LI>If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted by the
+ Free Software Foundation, write to the Free Software Foundation; we
+ sometimes make exceptions for this. Our decision will be guided by the
+ two goals of preserving the free status of all derivatives of our free
+ software and of promoting the sharing and reuse of software generally.</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<H4>NO WARRANTY</H4>
+<OL START="11">
+<LI>BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER
+ EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
+ YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+ NECESSARY SERVICING, REPAIR OR CORRECTION.</LI>
+<LI>IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+ AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
+ FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.</LI>
+</OL>
+<H4>END OF TERMS AND CONDITIONS</H4>
+
+<!-- NEW PAGE -->
+<H2><A NAME="7_3">GNU LIBRARY GENERAL PUBLIC LICENSE</A></H2>
+<P>Version 2, June 1991</P>
+<PRE>
+Copyright (C) 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+</PRE>
+<H4>Preamble</H4>
+<P>The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public Licenses
+ are intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users.</P>
+<P>This license, the Library General Public License, applies to some
+ specially designated Free Software Foundation software, and to any
+ other libraries whose authors decide to use it. You can use it for your
+ libraries, too.</P>
+<P>When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it in
+ new free programs; and that you know you can do these things.</P>
+<P>To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the library, or if you modify it.</P>
+<P>For example, if you distribute copies of the library, whether gratis
+ or for a fee, you must give the recipients all the rights that we gave
+ you. You must make sure that they, too, receive or can get the source
+ code. If you link a program with the library, you must provide complete
+ object files to the recipients so that they can relink them with the
+ library, after making changes to the library and recompiling it. And
+ you must show them these terms so they know their rights.</P>
+<P>Our method of protecting your rights has two steps: (1) copyright the
+ library, and (2) offer you this license which gives you legal
+ permission to copy, distribute and/or modify the library.</P>
+<P>Also, for each distributor's protection, we want to make certain that
+ everyone understands that there is no warranty for this free library.
+ If the library is modified by someone else and passed on, we want its
+ recipients to know that what they have is not the original version, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.</P>
+<P>Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that companies distributing free
+ software will individually obtain patent licenses, thus in effect
+ transforming the program into proprietary software. To prevent this, we
+ have made it clear that any patent must be licensed for everyone's free
+ use or not licensed at all.</P>
+<P>Most GNU software, including some libraries, is covered by the
+ ordinary GNU General Public License, which was designed for utility
+ programs. This license, the GNU Library General Public License, applies
+ to certain designated libraries. This license is quite different from
+ the ordinary one; be sure to read it in full, and don't assume that
+ anything in it is the same as in the ordinary license.</P>
+<P>The reason we have a separate public license for some libraries is
+ that they blur the distinction we usually make between modifying or
+ adding to a program and simply using it. Linking a program with a
+ library, without changing the library, is in some sense simply using
+ the library, and is analogous to running a utility program or
+ application program. However, in a textual and legal sense, the linked
+ executable is a combined work, a derivative of the original library,
+ and the ordinary General Public License treats it as such.</P>
+<P>Because of this blurred distinction, using the ordinary General
+ Public License for libraries did not effectively promote software
+ sharing, because most developers did not use the libraries. We
+ concluded that weaker conditions might promote sharing better.</P>
+<P>However, unrestricted linking of non-free programs would deprive the
+ users of those programs of all benefit from the free status of the
+ libraries themselves. This Library General Public License is intended
+ to permit developers of non-free programs to use free libraries, while
+ preserving your freedom as a user of such programs to change the free
+ libraries that are incorporated in them. (We have not seen how to
+ achieve this as regards changes in header files, but we have achieved
+ it as regards changes in the actual functions of the Library.) The hope
+ is that this will lead to faster development of free libraries.</P>
+<P>The precise terms and conditions for copying, distribution and
+ modification follow. Pay close attention to the difference between a
+ &quot;work based on the library&quot; and a &quot;work that uses the library&quot;. The
+ former contains code derived from the library, while the latter only
+ works together with the library.</P>
+<P>Note that it is possible for a library to be covered by the ordinary
+ General Public License rather than by this special one.</P>
+<H4>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+<P><STRONG>0.</STRONG> This License Agreement applies to any software
+ library which contains a notice placed by the copyright holder or other
+ authorized party saying it may be distributed under the terms of this
+ Library General Public License (also called &quot;this License&quot;). Each
+ licensee is addressed as &quot;you&quot;.</P>
+<P>A &quot;library&quot; means a collection of software functions and/or data
+ prepared so as to be conveniently linked with application programs
+ (which use some of those functions and data) to form executables.</P>
+<P>The &quot;Library&quot;, below, refers to any such software library or work
+ which has been distributed under these terms. A &quot;work based on the
+ Library&quot; means either the Library or any derivative work under
+ copyright law: that is to say, a work containing the Library or a
+ portion of it, either verbatim or with modifications and/or translated
+ straightforwardly into another language. (Hereinafter, translation is
+ included without limitation in the term &quot;modification&quot;.)</P>
+<P>&quot;Source code&quot; for a work means the preferred form of the work for
+ making modifications to it. For a library, complete source code means
+ all the source code for all modules it contains, plus any associated
+ interface definition files, plus the scripts used to control
+ compilation and installation of the library.</P>
+<P>Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ a program using the Library is not restricted, and output from such a
+ program is covered only if its contents constitute a work based on the
+ Library (independent of the use of the Library in a tool for writing
+ it). Whether that is true depends on what the Library does and what the
+ program that uses the Library does.</P>
+<P><STRONG>1.</STRONG> You may copy and distribute verbatim copies of
+ the Library's complete source code as you receive it, in any medium,
+ provided that you conspicuously and appropriately publish on each copy
+ an appropriate copyright notice and disclaimer of warranty; keep intact
+ all the notices that refer to this License and to the absence of any
+ warranty; and distribute a copy of this License along with the Library.</P>
+<P>You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.</P>
+<P><STRONG>2.</STRONG> You may modify your copy or copies of the Library
+ or any portion of it, thus forming a work based on the Library, and
+ copy and distribute such modifications or work under the terms of
+ Section 1 above, provided that you also meet all of these conditions:</P>
+<OL TYPE="a">
+<LI>The modified work must itself be a software library.
+<P></P>
+<LI>You must cause the files modified to carry prominent notices stating
+ that you changed the files and the date of any change.
+<P></P>
+<LI>You must cause the whole of the work to be licensed at no charge to
+ all third parties under the terms of this License.
+<P></P>
+<LI>If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses the
+ facility, other than as an argument passed when the facility is
+ invoked, then you must make a good faith effort to ensure that, in the
+ event an application does not supply such function or table, the
+ facility still operates, and performs whatever part of its purpose
+ remains meaningful.
+<P>(For example, a function in a library to compute square roots has a
+ purpose that is entirely well-defined independent of the application.
+ Therefore, Subsection 2d requires that any application-supplied
+ function or table used by this function must be optional: if the
+ application does not supply it, the square root function must still
+ compute square roots.)</P>
+</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<P>These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Library,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Library, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.</P>
+<P>Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Library.</P>
+<P>In addition, mere aggregation of another work not based on the
+ Library with the Library (or with a work based on the Library) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.</P>
+<P><STRONG>3.</STRONG> You may opt to apply the terms of the ordinary
+ GNU General Public License instead of this License to a given copy of
+ the Library. To do this, you must alter all the notices that refer to
+ this License, so that they refer to the ordinary GNU General Public
+ License, version 2, instead of to this License. (If a newer version
+ than version 2 of the ordinary GNU General Public License has appeared,
+ then you can specify that version instead if you wish.) Do not make any
+ other change in these notices.</P>
+<P>Once this change is made in a given copy, it is irreversible for that
+ copy, so the ordinary GNU General Public License applies to all
+ subsequent copies and derivative works made from that copy.</P>
+<P>This option is useful when you wish to copy part of the code of the
+ Library into a program that is not a library.</P>
+<P><STRONG>4.</STRONG> You may copy and distribute the Library (or a
+ portion or derivative of it, under Section 2) in object code or
+ executable form under the terms of Sections 1 and 2 above provided that
+ you accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections 1
+ and 2 above on a medium customarily used for software interchange.</P>
+<P>If distribution of object code is made by offering access to copy
+ from a designated place, then offering equivalent access to copy the
+ source code from the same place satisfies the requirement to distribute
+ the source code, even though third parties are not compelled to copy
+ the source along with the object code.</P>
+<P><STRONG>5.</STRONG> A program that contains no derivative of any
+ portion of the Library, but is designed to work with the Library by
+ being compiled or linked with it, is called a &quot;work that uses the
+ Library&quot;. Such a work, in isolation, is not a derivative work of the
+ Library, and therefore falls outside the scope of this License.</P>
+<P>However, linking a &quot;work that uses the Library&quot; with the Library
+ creates an executable that is a derivative of the Library (because it
+ contains portions of the Library), rather than a &quot;work that uses the
+ library&quot;. The executable is therefore covered by this License. Section
+ 6 states terms for distribution of such executables.</P>
+<P>When a &quot;work that uses the Library&quot; uses material from a header file
+ that is part of the Library, the object code for the work may be a
+ derivative work of the Library even though the source code is not.
+ Whether this is true is especially significant if the work can be
+ linked without the Library, or if the work is itself a library. The
+ threshold for this to be true is not precisely defined by law.</P>
+<P>If such an object file uses only numerical parameters, data structure
+ layouts and accessors, and small macros and small inline functions (ten
+ lines or less in length), then the use of the object file is
+ unrestricted, regardless of whether it is legally a derivative work.
+ (Executables containing this object code plus portions of the Library
+ will still fall under Section 6.)</P>
+<P>Otherwise, if the work is a derivative of the Library, you may
+ distribute the object code for the work under the terms of Section 6.
+ Any executables containing that work also fall under Section 6, whether
+ or not they are linked directly with the Library itself.</P>
+<P><STRONG>6.</STRONG> As an exception to the Sections above, you may
+ also compile or link a &quot;work that uses the Library&quot; with the Library to
+ produce a work containing portions of the Library, and distribute that
+ work under terms of your choice, provided that the terms permit
+ modification of the work for the customer's own use and reverse
+ engineering for debugging such modifications.</P>
+<P>You must give prominent notice with each copy of the work that the
+ Library is used in it and that the Library and its use are covered by
+ this License. You must supply a copy of this License. If the work
+ during execution displays copyright notices, you must include the
+ copyright notice for the Library among them, as well as a reference
+ directing the user to the copy of this License. Also, you must do one
+ of these things:</P>
+<OL TYPE="a">
+<LI>Accompany the work with the complete corresponding machine-readable
+ source code for the Library including whatever changes were used in the
+ work (which must be distributed under Sections 1 and 2 above); and, if
+ the work is an executable linked with the Library, with the complete
+ machine-readable &quot;work that uses the Library&quot;, as object code and/or
+ source code, so that the user can modify the Library and then relink to
+ produce a modified executable containing the modified Library. (It is
+ understood that the user who changes the contents of definitions files
+ in the Library will not necessarily be able to recompile the
+ application to use the modified definitions.)
+<P></P>
+<LI>Accompany the work with a written offer, valid for at least three
+ years, to give the same user the materials specified in Subsection 6a,
+ above, for a charge no more than the cost of performing this
+ distribution.
+<P></P>
+<LI>If distribution of the work is made by offering access to copy from
+ a designated place, offer equivalent access to copy the above specified
+ materials from the same place.
+<P></P>
+<LI>Verify that the user has already received a copy of these materials
+ or that you have already sent this user a copy.</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<P>For an executable, the required form of the &quot;work that uses the
+ Library&quot; must include any data and utility programs needed for
+ reproducing the executable from it. However, as a special exception,
+ the source code distributed need not include anything that is normally
+ distributed (in either source or binary form) with the major components
+ (compiler, kernel, and so on) of the operating system on which the
+ executable runs, unless that component itself accompanies the
+ executable.</P>
+<P>It may happen that this requirement contradicts the license
+ restrictions of other proprietary libraries that do not normally
+ accompany the operating system. Such a contradiction means you cannot
+ use both them and the Library together in an executable that you
+ distribute.</P>
+<P><STRONG>7.</STRONG> You may place library facilities that are a work
+ based on the Library side-by-side in a single library together with
+ other library facilities not covered by this License, and distribute
+ such a combined library, provided that the separate distribution of the
+ work based on the Library and of the other library facilities is
+ otherwise permitted, and provided that you do these two things:</P>
+<OL TYPE="a">
+<LI>Accompany the combined library with a copy of the same work based on
+ the Library, uncombined with any other library facilities. This must be
+ distributed under the terms of the Sections above.
+<P></P>
+<LI>Give prominent notice with the combined library of the fact that
+ part of it is a work based on the Library, and explaining where to find
+ the accompanying uncombined form of the same work.</LI>
+</LI>
+</OL>
+<P><STRONG>8.</STRONG> You may not copy, modify, sublicense, link with,
+ or distribute the Library except as expressly provided under this
+ License. Any attempt otherwise to copy, modify, sublicense, link with,
+ or distribute the Library is void, and will automatically terminate
+ your rights under this License. However, parties who have received
+ copies, or rights, from you under this License will not have their
+ licenses terminated so long as such parties remain in full compliance.</P>
+<P><STRONG>9.</STRONG> You are not required to accept this License,
+ since you have not signed it. However, nothing else grants you
+ permission to modify or distribute the Library or its derivative works.
+ These actions are prohibited by law if you do not accept this License.
+ Therefore, by modifying or distributing the Library (or any work based
+ on the Library), you indicate your acceptance of this License to do so,
+ and all its terms and conditions for copying, distributing or modifying
+ the Library or works based on it.</P>
+<P><STRONG>10.</STRONG> Each time you redistribute the Library (or any
+ work based on the Library), the recipient automatically receives a
+ license from the original licensor to copy, distribute, link with or
+ modify the Library subject to these terms and conditions. You may not
+ impose any further restrictions on the recipients' exercise of the
+ rights granted herein. You are not responsible for enforcing compliance
+ by third parties to this License.</P>
+<P><STRONG>11.</STRONG> If, as a consequence of a court judgment or
+ allegation of patent infringement or for any other reason (not limited
+ to patent issues), conditions are imposed on you (whether by court
+ order, agreement or otherwise) that contradict the conditions of this
+ License, they do not excuse you from the conditions of this License. If
+ you cannot distribute so as to satisfy simultaneously your obligations
+ under this License and any other pertinent obligations, then as a
+ consequence you may not distribute the Library at all. For example, if
+ a patent license would not permit royalty-free redistribution of the
+ Library by all those who receive copies directly or indirectly through
+ you, then the only way you could satisfy both it and this License would
+ be to refrain entirely from distribution of the Library.</P>
+<P>If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply, and the section as a whole is intended to apply in other
+ circumstances.</P>
+<P>It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system which is implemented
+ by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.</P>
+<P>This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.</P>
+<P><STRONG>12.</STRONG> If the distribution and/or use of the Library is
+ restricted in certain countries either by patents or by copyrighted
+ interfaces, the original copyright holder who places the Library under
+ this License may add an explicit geographical distribution limitation
+ excluding those countries, so that distribution is permitted only in or
+ among countries not thus excluded. In such case, this License
+ incorporates the limitation as if written in the body of this License.</P>
+<P><STRONG>13.</STRONG> The Free Software Foundation may publish revised
+ and/or new versions of the Library General Public License from time to
+ time. Such new versions will be similar in spirit to the present
+ version, but may differ in detail to address new problems or concerns.</P>
+<P>Each version is given a distinguishing version number. If the Library
+ specifies a version number of this License which applies to it and &quot;any
+ later version&quot;, you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Library does not specify a license
+ version number, you may choose any version ever published by the Free
+ Software Foundation.</P>
+<P><STRONG>14.</STRONG> If you wish to incorporate parts of the Library
+ into other free programs whose distribution conditions are incompatible
+ with these, write to the author to ask for permission. For software
+ which is copyrighted by the Free Software Foundation, write to the Free
+ Software Foundation; we sometimes make exceptions for this. Our
+ decision will be guided by the two goals of preserving the free status
+ of all derivatives of our free software and of promoting the sharing
+ and reuse of software generally.</P>
+<P><STRONG>NO WARRANTY</STRONG></P>
+<P><STRONG>15.</STRONG> BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE,
+ THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY &quot;AS IS&quot; WITHOUT
+ WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
+ OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU
+ ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</P>
+<P><STRONG>16.</STRONG> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
+ AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO
+ MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.</P>
+<H4>END OF TERMS AND CONDITIONS</H4>
+<H1 ALIGN="RIGHT"><A NAME="CONSTANTS">B - Constants</A></H1>
+<P>This appendix lists all of the constants that are defined by the CUPS
+ API.</P>
+<H2><A NAME="8_1">CUPS Constants</A></H2>
+<H3><A NAME="8_1_1">Version Number</A></H3>
+<P>The <CODE>CUPS_VERSION</CODE> constant is a floating-point number
+ representing the API version number. The current version number is
+ 1.0100 which represents CUPS version 1.1.0.</P>
+<H3><A NAME="8_1_2">Printer Capabilities</A></H3>
+<P>The <CODE>CUPS_PRINTER</CODE> constants represent capability bits for
+ printers and classes:</P>
+<UL>
+<LI><CODE>CUPS_PRINTER_LOCAL</CODE> - Is a local printer or class.</LI>
+<LI><CODE>CUPS_PRINTER_REMOTE</CODE> - Is a remote printer or class.</LI>
+<LI><CODE>CUPS_PRINTER_CLASS</CODE> - Is a class.</LI>
+<LI><CODE>CUPS_PRINTER_BW</CODE> - Printer prints in black and white.</LI>
+<LI><CODE>CUPS_PRINTER_COLOR</CODE> - Printer prints in color.</LI>
+<LI><CODE>CUPS_PRINTER_DUPLEX</CODE> - Printer can print double-sided.</LI>
+<LI><CODE>CUPS_PRINTER_STAPLE</CODE> - Printer can staple output.</LI>
+<LI><CODE>CUPS_PRINTER_COPIES</CODE> - Printer can produce multiple
+ copies on its own.</LI>
+<LI><CODE>CUPS_PRINTER_COLLATE</CODE> - Printer can collate copies.</LI>
+<LI><CODE>CUPS_PRINTER_PUNCH</CODE> - Printer can punch holes in output.</LI>
+<LI><CODE>CUPS_PRINTER_COVER</CODE> - Printer can put covers on output.</LI>
+<LI><CODE>CUPS_PRINTER_BIND</CODE> - Printer can bind output.</LI>
+<LI><CODE>CUPS_PRINTER_SORT</CODE> - Printer can sort output.</LI>
+<LI><CODE>CUPS_PRINTER_SMALL</CODE> - Printer can print on media up to
+ 9x14 inches.</LI>
+<LI><CODE>CUPS_PRINTER_MEDIUM</CODE> - Printer can print on media from
+ 9x14 to 18x24 inches.</LI>
+<LI><CODE>CUPS_PRINTER_LARGE</CODE> - Printer can print on media larger
+ than 18x24 inches.</LI>
+<LI><CODE>CUPS_PRINTER_VARIABLE</CODE> - Printer can print on variable
+ or custom media sizes.</LI>
+<LI><CODE>CUPS_PRINTER_IMPLICIT</CODE> - Is an implicit class.</LI>
+<LI><CODE>CUPS_PRINTER_OPTIONS</CODE> - All of the printer capability
+ and option bits.</LI>
+</UL>
+<H3><A NAME="8_1_3">Encodings</A></H3>
+<P>CUPS defines the following character set encoding constants:</P>
+<UL>
+<LI><CODE>CUPS_US_ASCII</CODE> - US ASCII character set.</LI>
+<LI><CODE>CUPS_UTF_8</CODE> - UTF-8 encoding of Unicode.</LI>
+<LI><CODE>CUPS_ISO8859_1</CODE> - ISO-8859-1 character set.</LI>
+<LI><CODE>CUPS_ISO8859_2</CODE> - ISO-8859-2 character set.</LI>
+<LI><CODE>CUPS_ISO8859_3</CODE> - ISO-8859-3 character set.</LI>
+<LI><CODE>CUPS_ISO8859_4</CODE> - ISO-8859-4 character set.</LI>
+<LI><CODE>CUPS_ISO8859_5</CODE> - ISO-8859-5 character set.</LI>
+<LI><CODE>CUPS_ISO8859_6</CODE> - ISO-8859-6 character set.</LI>
+<LI><CODE>CUPS_ISO8859_7</CODE> - ISO-8859-7 character set.</LI>
+<LI><CODE>CUPS_ISO8859_8</CODE> - ISO-8859-8 character set.</LI>
+<LI><CODE>CUPS_ISO8859_9</CODE> - ISO-8859-9 character set.</LI>
+<LI><CODE>CUPS_ISO8859_10</CODE> - ISO-8859-10 character set.</LI>
+<LI><CODE>CUPS_ISO8859_13</CODE> - ISO-8859-13 character set.</LI>
+<LI><CODE>CUPS_ISO8859_14</CODE> - ISO-8859-14 character set.</LI>
+<LI><CODE>CUPS_ISO8859_15</CODE> - ISO-8859-15 character set.</LI>
+<LI><CODE>CUPS_WINDOWS_874</CODE> - Windows code page 874.</LI>
+<LI><CODE>CUPS_WINDOWS_1250</CODE> - Windows code page 1250.</LI>
+<LI><CODE>CUPS_WINDOWS_1251</CODE> - Windows code page 1251.</LI>
+<LI><CODE>CUPS_WINDOWS_1252</CODE> - Windows code page 1252.</LI>
+<LI><CODE>CUPS_WINDOWS_1253</CODE> - Windows code page 1253.</LI>
+<LI><CODE>CUPS_WINDOWS_1254</CODE> - Windows code page 1254.</LI>
+<LI><CODE>CUPS_WINDOWS_1255</CODE> - Windows code page 1255.</LI>
+<LI><CODE>CUPS_WINDOWS_1256</CODE> - Windows code page 1256.</LI>
+<LI><CODE>CUPS_WINDOWS_1257</CODE> - Windows code page 1257.</LI>
+<LI><CODE>CUPS_WINDOWS_1258</CODE> - Windows code page 1258.</LI>
+<LI><CODE>CUPS_KOI8_R</CODE> - Russian code page koi8-r.</LI>
+<LI><CODE>CUPS_KOI8_U</CODE> - Ukrainian code page koi8-r.</LI>
+</UL>
+<H2><A NAME="8_2">HTTP Constants</A></H2>
+<H3><A NAME="8_2_1">Limits</A></H3>
+<P>The following constants define the limits for strings:</P>
+<UL>
+<LI><CODE>HTTP_MAX_BUFFER</CODE> - Size of socket buffer.</LI>
+<LI><CODE>HTTP_MAX_HOST</CODE> - Maximum length of hostname.</LI>
+<LI><CODE>HTTP_MAX_URI</CODE> - Maximum length of URI.</LI>
+<LI><CODE>HTTP_MAX_VALUE</CODE> - Maximum length of field values.</LI>
+</UL>
+<H3><A NAME="8_2_2">Status Codes</A></H3>
+<P>The following status codes can be returned by <CODE>httpUpdate()</CODE>
+:</P>
+<UL>
+<LI><CODE>HTTP_ERROR</CODE> - A network error occurred</LI>
+<LI><CODE>HTTP_CONTINUE</CODE> - Continue response from HTTP proxy</LI>
+<LI><CODE>HTTP_OK</CODE> - OPTIONS/GET/HEAD/POST/TRACE command was
+ successful</LI>
+<LI><CODE>HTTP_CREATED</CODE> - PUT command was successful</LI>
+<LI><CODE>HTTP_ACCEPTED</CODE> - DELETE command was successful</LI>
+<LI><CODE>HTTP_NOT_AUTHORITATIVE</CODE> - Information isn't
+ authoritative</LI>
+<LI><CODE>HTTP_NO_CONTENT</CODE> - Successful command</LI>
+<LI><CODE>HTTP_RESET_CONTENT</CODE> - Content was reset/recreated</LI>
+<LI><CODE>HTTP_PARTIAL_CONTENT</CODE> - Only a partial file was
+ recieved/sent</LI>
+<LI><CODE>HTTP_MULTIPLE_CHOICES</CODE> - Multiple files match request</LI>
+<LI><CODE>HTTP_MOVED_PERMANENTLY</CODE> - Document has moved permanently</LI>
+<LI><CODE>HTTP_MOVED_TEMPORARILY</CODE> - Document has moved temporarily</LI>
+<LI><CODE>HTTP_SEE_OTHER</CODE> - See this other link...</LI>
+<LI><CODE>HTTP_NOT_MODIFIED</CODE> - File not modified</LI>
+<LI><CODE>HTTP_USE_PROXY</CODE> - Must use a proxy to access this URI</LI>
+<LI><CODE>HTTP_BAD_REQUEST</CODE> - Bad request</LI>
+<LI><CODE>HTTP_UNAUTHORIZED</CODE> - Unauthorized to access host</LI>
+<LI><CODE>HTTP_PAYMENT_REQUIRED</CODE> - Payment required</LI>
+<LI><CODE>HTTP_FORBIDDEN</CODE> - Forbidden to access this URI</LI>
+<LI><CODE>HTTP_NOT_FOUND</CODE> - URI was not found</LI>
+<LI><CODE>HTTP_METHOD_NOT_ALLOWED</CODE> - Method is not allowed</LI>
+<LI><CODE>HTTP_NOT_ACCEPTABLE</CODE> - Not Acceptable</LI>
+<LI><CODE>HTTP_PROXY_AUTHENTICATION</CODE> - Proxy Authentication is
+ Required</LI>
+<LI><CODE>HTTP_REQUEST_TIMEOUT</CODE> - Request timed out</LI>
+<LI><CODE>HTTP_CONFLICT</CODE> - Request is self-conflicting</LI>
+<LI><CODE>HTTP_GONE</CODE> - Server has gone away</LI>
+<LI><CODE>HTTP_LENGTH_REQUIRED</CODE> - A content length or encoding is
+ required</LI>
+<LI><CODE>HTTP_PRECONDITION</CODE> - Precondition failed</LI>
+<LI><CODE>HTTP_REQUEST_TOO_LARGE</CODE> - Request entity too large</LI>
+<LI><CODE>HTTP_URI_TOO_LONG</CODE> - URI too long</LI>
+<LI><CODE>HTTP_UNSUPPORTED_MEDIATYPE</CODE> - The requested media type
+ is unsupported</LI>
+<LI><CODE>HTTP_SERVER_ERROR</CODE> - Internal server error</LI>
+<LI><CODE>HTTP_NOT_IMPLEMENTED</CODE> - Feature not implemented</LI>
+<LI><CODE>HTTP_BAD_GATEWAY</CODE> - Bad gateway</LI>
+<LI><CODE>HTTP_SERVICE_UNAVAILABLE</CODE> - Service is unavailable</LI>
+<LI><CODE>HTTP_GATEWAY_TIMEOUT</CODE> - Gateway connection timed out</LI>
+<LI><CODE>HTTP_NOT_SUPPORTED</CODE> - HTTP version not supported</LI>
+</UL>
+<H3><A NAME="8_2_3">Fields</A></H3>
+<P>The following fields are indices for each of the standard HTTP fields
+ in HTTP 1/1:</P>
+<UL>
+<LI><CODE>HTTP_FIELD_ACCEPT_LANGUAGE</CODE> - Accept-Language</LI>
+<LI><CODE>HTTP_FIELD_ACCEPT_RANGES</CODE> - Accept-Ranges</LI>
+<LI><CODE>HTTP_FIELD_AUTHORIZATION</CODE> - Authorization</LI>
+<LI><CODE>HTTP_FIELD_CONNECTION</CODE> - Connection</LI>
+<LI><CODE>HTTP_FIELD_CONTENT_ENCODING</CODE> - Content-Encoding</LI>
+<LI><CODE>HTTP_FIELD_CONTENT_LANGUAGE</CODE> - Content-Language</LI>
+<LI><CODE>HTTP_FIELD_CONTENT_LENGTH</CODE> - Content-Length</LI>
+<LI><CODE>HTTP_FIELD_CONTENT_LOCATION</CODE> - Content-Location</LI>
+<LI><CODE>HTTP_FIELD_CONTENT_MD5</CODE> - Content-MD5</LI>
+<LI><CODE>HTTP_FIELD_CONTENT_RANGE</CODE> - Content-Range</LI>
+<LI><CODE>HTTP_FIELD_CONTENT_TYPE</CODE> - Content-Type</LI>
+<LI><CODE>HTTP_FIELD_CONTENT_VERSION</CODE> - Content-Version</LI>
+<LI><CODE>HTTP_FIELD_DATE</CODE> - Date</LI>
+<LI><CODE>HTTP_FIELD_HOST</CODE> - Host</LI>
+<LI><CODE>HTTP_FIELD_IF_MODIFIED_SINCE</CODE> - If-Modified-Since</LI>
+<LI><CODE>HTTP_FIELD_IF_UNMODIFIED_SINCE</CODE> - If-Unmodified-Since</LI>
+<LI><CODE>HTTP_FIELD_KEEP_ALIVE</CODE> - Keep-Alive</LI>
+<LI><CODE>HTTP_FIELD_LAST_MODIFIED</CODE> - Last-Modified</LI>
+<LI><CODE>HTTP_FIELD_LINK</CODE> - Link</LI>
+<LI><CODE>HTTP_FIELD_LOCATION</CODE> - Location</LI>
+<LI><CODE>HTTP_FIELD_RANGE</CODE> - Range</LI>
+<LI><CODE>HTTP_FIELD_REFERER</CODE> - Referer</LI>
+<LI><CODE>HTTP_FIELD_RETRY_AFTER</CODE> - Retry-After</LI>
+<LI><CODE>HTTP_FIELD_TRANSFER_ENCODING</CODE> - Transfer-Encoding</LI>
+<LI><CODE>HTTP_FIELD_UPGRADE</CODE> - Upgrade</LI>
+<LI><CODE>HTTP_FIELD_USER_AGENT</CODE> - User-Agent</LI>
+<LI><CODE>HTTP_FIELD_WWW_AUTHENTICATE</CODE> - WWW-Authenticate</LI>
+</UL>
+<H2><A NAME="8_3">IPP Constants</A></H2>
+<H3><A NAME="8_3_1">Limits</A></H3>
+<P>The following constants define array limits for IPP data:</P>
+<UL>
+<LI><CODE>IPP_MAX_NAME</CODE> - Maximum length of an attribute name</LI>
+<LI><CODE>IPP_MAX_VALUES</CODE> - Maximum number of set-of values that
+ can be read in a request.</LI>
+</UL>
+<H3><A NAME="8_3_2">Tags</A></H3>
+<UL>
+<LI><CODE>IPP_TAG_ZERO</CODE> - Wildcard tag value for searches; also
+ used to separate groups of attributes</LI>
+<LI><CODE>IPP_TAG_OPERATION</CODE> - Tag for values of type operation</LI>
+<LI><CODE>IPP_TAG_JOB</CODE> - Tag for values of type job</LI>
+<LI><CODE>IPP_TAG_END</CODE> - Tag for values of type end</LI>
+<LI><CODE>IPP_TAG_PRINTER</CODE> - Tag for values of type printer</LI>
+<LI><CODE>IPP_TAG_UNSUPPORTED_GROUP</CODE> - Tag for values of type
+ unsupported_group</LI>
+<LI><CODE>IPP_TAG_UNSUPPORTED_VALUE</CODE> - Tag for values of type
+ unsupported_value</LI>
+<LI><CODE>IPP_TAG_DEFAULT</CODE> - Tag for values of type default</LI>
+<LI><CODE>IPP_TAG_UNKNOWN</CODE> - Tag for values of type unknown</LI>
+<LI><CODE>IPP_TAG_NOVALUE</CODE> - Tag for values of type novalue</LI>
+<LI><CODE>IPP_TAG_NOTSETTABLE</CODE> - Tag for values of type
+ notsettable</LI>
+<LI><CODE>IPP_TAG_DELETEATTR</CODE> - Tag for values of type deleteattr</LI>
+<LI><CODE>IPP_TAG_ANYVALUE</CODE> - Tag for values of type anyvalue</LI>
+<LI><CODE>IPP_TAG_INTEGER</CODE> - Tag for values of type integer</LI>
+<LI><CODE>IPP_TAG_BOOLEAN</CODE> - Tag for values of type boolean</LI>
+<LI><CODE>IPP_TAG_ENUM</CODE> - Tag for values of type enum</LI>
+<LI><CODE>IPP_TAG_STRING</CODE> - Tag for values of type string</LI>
+<LI><CODE>IPP_TAG_DATE</CODE> - Tag for values of type date</LI>
+<LI><CODE>IPP_TAG_RESOLUTION</CODE> - Tag for values of type resolution</LI>
+<LI><CODE>IPP_TAG_RANGE</CODE> - Tag for values of type range</LI>
+<LI><CODE>IPP_TAG_COLLECTION</CODE> - Tag for values of type collection</LI>
+<LI><CODE>IPP_TAG_TEXTLANG</CODE> - Tag for values of type textlang</LI>
+<LI><CODE>IPP_TAG_NAMELANG</CODE> - Tag for values of type namelang</LI>
+<LI><CODE>IPP_TAG_TEXT</CODE> - Tag for values of type text</LI>
+<LI><CODE>IPP_TAG_NAME</CODE> - Tag for values of type name</LI>
+<LI><CODE>IPP_TAG_KEYWORD</CODE> - Tag for values of type keyword</LI>
+<LI><CODE>IPP_TAG_URI</CODE> - Tag for values of type uri</LI>
+<LI><CODE>IPP_TAG_URISCHEME</CODE> - Tag for values of type urischeme</LI>
+<LI><CODE>IPP_TAG_CHARSET</CODE> - Tag for values of type charset</LI>
+<LI><CODE>IPP_TAG_LANGUAGE</CODE> - Tag for values of type language</LI>
+<LI><CODE>IPP_TAG_MIMETYPE</CODE> - Tag for values of type mimetype</LI>
+</UL>
+<H3><A NAME="8_3_3">Resolution Units</A></H3>
+<P>The <CODE>IPP_RES_PER_INCH</CODE> and <CODE>IPP_RES_PER_CM</CODE>
+ constants specify dots per inch and dots per centimeter, respectively.</P>
+<H3><A NAME="8_3_4">Finishings</A></H3>
+<P>The finishing values specify special finishing operations to be
+ performed on the job.</P>
+<UL>
+<LI><CODE>IPP_FINISH_NONE</CODE> - Do no finishing</LI>
+<LI><CODE>IPP_FINISH_STAPLE</CODE> - Staple the job</LI>
+<LI><CODE>IPP_FINISH_PUNCH</CODE> - Punch the job</LI>
+<LI><CODE>IPP_FINISH_COVER</CODE> - Cover the job</LI>
+<LI><CODE>IPP_FINISH_BIND</CODE> - Bind the job</LI>
+</UL>
+<H3><A NAME="8_3_5">Orientations</A></H3>
+<P>The orientation values specify the orientation of the job.</P>
+<UL>
+<LI><CODE>IPP_PORTRAIT</CODE> - No rotation</LI>
+<LI><CODE>IPP_LANDSCAPE</CODE> - 90 degrees counter-clockwise</LI>
+<LI><CODE>IPP_REVERSE_LANDSCAPE</CODE> - 90 degrees clockwise</LI>
+<LI><CODE>IPP_REVERSE_PORTRAIT</CODE> - 180 degrees</LI>
+</UL>
+<H3><A NAME="8_3_6">Qualities</A></H3>
+<P>The quality values specify the desired quality of the print.</P>
+<UL>
+<LI><CODE>IPP_QUALITY_DRAFT</CODE> - Draft quality</LI>
+<LI><CODE>IPP_QUALITY_NORMAL</CODE> - Normal quality</LI>
+<LI><CODE>IPP_QUALITY_HIGH</CODE> - High quality</LI>
+</UL>
+<H3><A NAME="8_3_7">Job States</A></H3>
+<P>The job state values are used to represent the current job state.</P>
+<UL>
+<LI><CODE>IPP_JOB_PENDING</CODE> - Job is pending</LI>
+<LI><CODE>IPP_JOB_HELD</CODE> - Job is held</LI>
+<LI><CODE>IPP_JOB_PROCESSING</CODE> - Job is processing</LI>
+<LI><CODE>IPP_JOB_STOPPED</CODE> - Job is stopped</LI>
+<LI><CODE>IPP_JOB_CANCELLED</CODE> - Job is cancelled</LI>
+<LI><CODE>IPP_JOB_ABORTED</CODE> - Job is aborted</LI>
+<LI><CODE>IPP_JOB_COMPLETED</CODE> - Job is completed</LI>
+</UL>
+<H3><A NAME="8_3_8">Printer States</A></H3>
+<P>The printer state values are used to represent the current printer
+ state.</P>
+<UL>
+<LI><CODE>IPP_PRINTER_IDLE</CODE> - Printer is idle</LI>
+<LI><CODE>IPP_PRINTER_PROCESSING</CODE> - Printer is processing</LI>
+<LI><CODE>IPP_PRINTER_STOPPED</CODE> - Printer is stopped</LI>
+</UL>
+<H3><A NAME="8_3_9">Operations</A></H3>
+<P>The operation values represent the available IPP operations.</P>
+<UL>
+<LI><CODE>IPP_PRINT_JOB</CODE> - Print a file</LI>
+<LI><CODE>IPP_PRINT_URI</CODE> - Print a URI</LI>
+<LI><CODE>IPP_VALIDATE_JOB</CODE> - Validate job attributes</LI>
+<LI><CODE>IPP_CREATE_JOB</CODE> - Create a new job</LI>
+<LI><CODE>IPP_SEND_DOCUMENT</CODE> - Send a document to a job</LI>
+<LI><CODE>IPP_SEND_URI</CODE> - Send a URI to a job</LI>
+<LI><CODE>IPP_CANCEL_JOB</CODE> - Cancel a job</LI>
+<LI><CODE>IPP_GET_JOB_ATTRIBUTES</CODE> - Get job attributes</LI>
+<LI><CODE>IPP_GET_JOBS</CODE> - Get a list of all jobs</LI>
+<LI><CODE>IPP_GET_PRINTER_ATTRIBUTES</CODE> - Get printer attributes</LI>
+<LI><CODE>IPP_HOLD_JOB</CODE> - Hold a pending job</LI>
+<LI><CODE>IPP_RELEASE_JOB</CODE> - Release a held job</LI>
+<LI><CODE>IPP_RESTART_JOB</CODE> - Restart a completed job</LI>
+<LI><CODE>IPP_PAUSE_PRINTER</CODE> - Pause a printer</LI>
+<LI><CODE>IPP_RESUME_PRINTER</CODE> - Restart a paused printer</LI>
+<LI><CODE>IPP_PURGE_JOBS</CODE> - Purge jobs from the queue</LI>
+<LI><CODE>IPP_SET_PRINTER_ATTRIBUTES</CODE> - Set printer attributes</LI>
+<LI><CODE>IPP_SET_JOB_ATTRIBUTES</CODE> - Set job attributes</LI>
+<LI><CODE>IPP_GET_PRINTER_SUPPORTED_VALUES</CODE> - Get printer
+ supported values</LI>
+<LI><CODE>CUPS_GET_DEFAULT</CODE> - Get the default destination</LI>
+<LI><CODE>CUPS_GET_PRINTERS</CODE> - Get a list of all printers</LI>
+<LI><CODE>CUPS_ADD_PRINTER</CODE> - Add or modify a printer</LI>
+<LI><CODE>CUPS_DELETE_PRINTER</CODE> - Delete a printer</LI>
+<LI><CODE>CUPS_GET_CLASSES</CODE> - Get a list of all classes</LI>
+<LI><CODE>CUPS_ADD_CLASS</CODE> - Add or modify a class</LI>
+<LI><CODE>CUPS_DELETE_CLASS</CODE> - Delete a class</LI>
+<LI><CODE>CUPS_ACCEPT_JOBS</CODE> - Accept jobs on a printer or class</LI>
+<LI><CODE>CUPS_REJECT_JOBS</CODE> - Reject jobs on a printer or class</LI>
+<LI><CODE>CUPS_SET_DEFAULT</CODE> - Set the default destination</LI>
+<LI><CODE>CUPS_GET_DEVICES</CODE> - Get a list of all devices</LI>
+<LI><CODE>CUPS_GET_PPDS</CODE> - Get a list of all PPDs</LI>
+<LI><CODE>CUPS_MOVE_JOB</CODE> - Move a job to a new destination</LI>
+</UL>
+<H3><A NAME="8_3_10">Status Codes</A></H3>
+<P>Status codes are returned by all IPP requests.</P>
+<UL>
+<LI><CODE>IPP_OK</CODE> - Request completed with no errors</LI>
+<LI><CODE>IPP_OK_SUBST</CODE> - Request completed but some attribute
+ values were substituted</LI>
+<LI><CODE>IPP_OK_CONFLICT</CODE> - Request completed but some attributes
+ conflicted</LI>
+<LI><CODE>IPP_BAD_REQUEST</CODE> - The request was bad</LI>
+<LI><CODE>IPP_FORBIDDEN</CODE> - You don't have access to the resource</LI>
+<LI><CODE>IPP_NOT_AUTHENTICATED</CODE> - You are not authenticated for
+ the resource</LI>
+<LI><CODE>IPP_NOT_AUTHORIZED</CODE> - You not authorized to access the
+ resource</LI>
+<LI><CODE>IPP_NOT_POSSIBLE</CODE> - The requested operation cannot be
+ completed</LI>
+<LI><CODE>IPP_TIMEOUT</CODE> - A timeout occurred</LI>
+<LI><CODE>IPP_NOT_FOUND</CODE> - The resource was not found</LI>
+<LI><CODE>IPP_GONE</CODE> - The resource has gone away</LI>
+<LI><CODE>IPP_REQUEST_ENTITY</CODE> - The request was too large</LI>
+<LI><CODE>IPP_REQUEST_VALUE</CODE> - The request contained a value that
+ was unknown to the server</LI>
+<LI><CODE>IPP_DOCUMENT_FORMAT</CODE> - The document format is not
+ supported by the server</LI>
+<LI><CODE>IPP_ATTRIBUTES</CODE> - Required attributes are missing</LI>
+<LI><CODE>IPP_URI_SCHEME</CODE> - The URI scheme is not supported</LI>
+<LI><CODE>IPP_CHARSET</CODE> - The charset is not supported</LI>
+<LI><CODE>IPP_CONFLICT</CODE> - One or more attributes conflict</LI>
+<LI><CODE>IPP_COMPRESSION_NOT_SUPPORTED</CODE> - The specified
+ compression is not supported</LI>
+<LI><CODE>IPP_COMPRESSION_ERROR</CODE> - The compressed data contained
+ an error</LI>
+<LI><CODE>IPP_DOCUMENT_FORMAT_ERROR</CODE> - The document data contained
+ an error in it</LI>
+<LI><CODE>IPP_DOCUMENT_ACCESS_ERROR</CODE> - The remote document could
+ not be accessed</LI>
+<LI><CODE>IPP_INTERNAL_ERROR</CODE> - The server encountered an internal
+ error</LI>
+<LI><CODE>IPP_OPERATION_NOT_SUPPORTED</CODE> - The requested operation
+ is not supported</LI>
+<LI><CODE>IPP_SERVICE_UNAVAILABLE</CODE> - The requested service is
+ unavailable</LI>
+<LI><CODE>IPP_VERSION_NOT_SUPPORTED</CODE> - The IPP request version is
+ not supported</LI>
+<LI><CODE>IPP_DEVICE_ERROR</CODE> - The output device encountered an
+ error</LI>
+<LI><CODE>IPP_TEMPORARY_ERROR</CODE> - A temporary error occurred</LI>
+<LI><CODE>IPP_NOT_ACCEPTING</CODE> - The destination is not accepting
+ jobs</LI>
+<LI><CODE>IPP_PRINTER_BUSY</CODE> - The destination is busy</LI>
+<LI><CODE>IPP_ERROR_JOB_CANCELLED</CODE> - The requested job has been
+ cancelled</LI>
+<LI><CODE>IPP_MULTIPLE_JOBS_NOT_SUPPORTED</CODE> - The server does not
+ support multiple jobs</LI>
+</UL>
+<H2><A NAME="8_4">PPD Constants</A></H2>
+<H3><A NAME="8_4_1">PPD Format Version</A></H3>
+<P>The <CODE>PPD_VERSION</CODE> constant defines a floating point number
+ representing the newest format version that is supported by CUPS,
+ currently 4.3.</P>
+<H3><A NAME="8_4_2">PPD User-Interface Types</A></H3>
+<P>Each printer option has a type associated with it:</P>
+<UL>
+<LI><CODE>PPD_UI_BOOLEAN</CODE> - The user can turn this option on or
+ off</LI>
+<LI><CODE>PPD_UI_PICKONE</CODE> - The user can choose one option value
+ to use.</LI>
+<LI><CODE>PPD_UI_PICKMANY</CODE> - The user can choose zero or more
+ option values.</LI>
+</UL>
+<H3><A NAME="8_4_3">PPD Sections</A></H3>
+<P>Some options must be output before others, or in different sections
+ of the output document. The <CODE>ppd_section_t</CODE> enumeration
+ defines which section the option must be output in:</P>
+<UL>
+<LI><CODE>PPD_ORDER_ANY</CODE> - The option can be output in any of the
+ document, page, or prolog sections of the document</LI>
+<LI><CODE>PPD_ORDER_DOCUMENT</CODE> - The option must be output in the
+ DocumentSetup section of the document</LI>
+<LI><CODE>PPD_ORDER_EXIT</CODE> - The option must be output before the
+ document</LI>
+<LI><CODE>PPD_ORDER_JCL</CODE> - The option must be output in the job
+ control section of the document</LI>
+<LI><CODE>PPD_ORDER_PAGE</CODE> - The option must be output in the
+ PageSetup section of the document</LI>
+<LI><CODE>PPD_ORDER_PROLOG</CODE> - The option must be output in the
+ Prolog section of the document</LI>
+</UL>
+<H3><A NAME="8_4_4">PPD Colorspaces</A></H3>
+<P>Each printer has a default colorspace:</P>
+<UL>
+<LI><CODE>PPD_CS_CMYK</CODE> - The printer uses CMYK colors by default</LI>
+<LI><CODE>PPD_CS_CMY</CODE> - The printer uses CMY colors by default</LI>
+<LI><CODE>PPD_CS_GRAY</CODE> - The printer uses grayscale by default</LI>
+<LI><CODE>PPD_CS_RGB</CODE> - The printer uses RGB colors by default</LI>
+<LI><CODE>PPD_CS_RGBK</CODE> - The printer uses RGBK colors by default</LI>
+<LI><CODE>PPD_CS_N</CODE> - The printer uses a DeviceN colorspace by
+ default</LI>
+</UL>
+<H2><A NAME="8_5">Raster Constants</A></H2>
+<H3><A NAME="8_5_1">Raster Sync Words</A></H3>
+<P>The <CODE>CUPS_RASTER_SYNC</CODE> and <CODE>CUPS_RASTER_REVSYNC</CODE>
+ constants define the standard sync words at the beginning of each CUPS
+ raster file.</P>
+<H3><A NAME="8_5_2">Raster Stream Modes</A></H3>
+<P>The <CODE>CUPS_RASTER_READ</CODE> and <CODE>CUPS_RASTER_WRITE</CODE>
+ constants are used with the<A HREF="#cupsRasterOpen"> <CODE>
+cupsRasterOpen()</CODE></A> function to specify a stream for reading or
+ writing.</P>
+<H3><A NAME="8_5_3">Raster Boolean Constants</A></H3>
+<P>The <CODE>CUPS_FALSE</CODE> and <CODE>CUPS_TRUE</CODE> constants
+ represent boolean values in the page header.</P>
+<H3><A NAME="8_5_4">Raster Jog Values</A></H3>
+<P>The <CODE>cups_jog_t</CODE> enumeration defines constants for the Jog
+ page device dictionary variable:</P>
+<UL>
+<LI><CODE>CUPS_JOG_NONE</CODE> - Do no jogging</LI>
+<LI><CODE>CUPS_JOG_FILE</CODE> - Jog pages after each file</LI>
+<LI><CODE>CUPS_JOG_JOB</CODE> - Jog pages after each job</LI>
+<LI><CODE>CUPS_JOG_SET</CODE> - Jog pages after each set of jobs</LI>
+</UL>
+<H3><A NAME="8_5_5">Raster Orientation Values</A></H3>
+<P>The <CODE>cups_orient_t</CODE> enumeration defines constants for the
+ Orientation page device dictionary variable:</P>
+<UL>
+<LI><CODE>CUPS_ORIENT_0</CODE> - Portrait orientation</LI>
+<LI><CODE>CUPS_ORIENT_90</CODE> - Landscape orientation</LI>
+<LI><CODE>CUPS_ORIENT_180</CODE> - Reverse-portrait orientation</LI>
+<LI><CODE>CUPS_ORIENT_270</CODE> - Reverse-landscape orientation</LI>
+</UL>
+<H3><A NAME="8_5_6">Raster CutMedia Values</A></H3>
+<P>The <CODE>cups_cut_t</CODE> enumeration defines constants for the
+ CutMedia page device dictionary variable:</P>
+<UL>
+<LI><CODE>CUPS_CUT_NONE</CODE> - Do no jogging</LI>
+<LI><CODE>CUPS_CUT_FILE</CODE> - Cut pages after each file</LI>
+<LI><CODE>CUPS_CUT_JOB</CODE> - Cut pages after each job</LI>
+<LI><CODE>CUPS_CUT_SET</CODE> - Cut pages after each set of jobs</LI>
+<LI><CODE>CUPS_CUT_PAGE</CODE> - Cut each page</LI>
+</UL>
+<H3><A NAME="8_5_7">Raster AdvanceMedia Values</A></H3>
+<P>The <CODE>cups_advance_t</CODE> enumeration defines constants for the
+ AdvanceMedia page device dictionary variable:</P>
+<UL>
+<LI><CODE>CUPS_ADVANCE_NONE</CODE> - Do no jogging</LI>
+<LI><CODE>CUPS_ADVANCE_FILE</CODE> - Advance media after each file</LI>
+<LI><CODE>CUPS_ADVANCE_JOB</CODE> - Advance media after each job</LI>
+<LI><CODE>CUPS_ADVANCE_SET</CODE> - Advance media after each set of jobs</LI>
+<LI><CODE>CUPS_ADVANCE_PAGE</CODE> - Advance media for each page</LI>
+</UL>
+<H3><A NAME="8_5_8">Raster LeadingEdge Values</A></H3>
+<P>The <CODE>cups_edge_t</CODE> enumeration defines constants for the
+ LeadingEdge page device dictionary variable:</P>
+<UL>
+<LI><CODE>CUPS_EDGE_TOP</CODE> - The top of the media is the leading
+ edge</LI>
+<LI><CODE>CUPS_EDGE_RIGHT</CODE> - The right of the media is the leading
+ edge</LI>
+<LI><CODE>CUPS_EDGE_BOTTOM</CODE> - The bottom of the media is the
+ leading edge</LI>
+<LI><CODE>CUPS_EDGE_LEFT</CODE> - The left of the media is the leading
+ edge</LI>
+</UL>
+<H3><A NAME="8_5_9">Raster Color Order Values</A></H3>
+<P>The <CODE>cups_order_t</CODE> enumeration defines the possible color
+ value orderings:</P>
+<UL>
+<LI><CODE>CUPS_ORDER_CHUNKED</CODE> - CMYK&nbsp;CMYK&nbsp;CMYK</LI>
+<LI><CODE>CUPS_ORDER_BANDED</CODE> - CCC&nbsp;MMM&nbsp;YYY&nbsp;KKK</LI>
+<LI><CODE>CUPS_ORDER_PLANAR</CODE> - CCC&nbsp;...&nbsp;MMM&nbsp;...&nbsp;YYY&nbsp;...&nbsp;KKK&nbsp;...</LI>
+</UL>
+<H3><A NAME="8_5_10">Raster Colorspace Values</A></H3>
+<P>The <CODE>cups_cspace_t</CODE> enumeration defines the possible
+ colorspaces:</P>
+<UL>
+<LI><CODE>CUPS_CSPACE_W</CODE> - White (luminance)</LI>
+<LI><CODE>CUPS_CSPACE_RGB</CODE> - Red, green, blue</LI>
+<LI><CODE>CUPS_CSPACE_RGBA</CODE> - Red, green, blue, alpha</LI>
+<LI><CODE>CUPS_CSPACE_K</CODE> - Black</LI>
+<LI><CODE>CUPS_CSPACE_CMY</CODE> - Cyan, magenta, yellow</LI>
+<LI><CODE>CUPS_CSPACE_YMC</CODE> - Yellow, magenta, cyan</LI>
+<LI><CODE>CUPS_CSPACE_CMYK</CODE> - Cyan, magenta, yellow, black</LI>
+<LI><CODE>CUPS_CSPACE_YMCK</CODE> - Yellow, magenta, cyan, black</LI>
+<LI><CODE>CUPS_CSPACE_KCMY</CODE> - Black, cyan, magenta, yellow</LI>
+<LI><CODE>CUPS_CSPACE_KCMYcm</CODE> - Black, cyan, magenta, yellow,
+ light cyan, light magenta</LI>
+<LI><CODE>CUPS_CSPACE_GMCK</CODE> - Metallic yellow (gold), metallic
+ magenta, metallic cyan, black</LI>
+<LI><CODE>CUPS_CSPACE_GMCS</CODE> - Metallic yellow (gold), metallic
+ magenta, metallic cyan, metallic grey (silver)</LI>
+<LI><CODE>CUPS_CSPACE_WHITE</CODE> - White pigment (black as white
+ pigment)</LI>
+<LI><CODE>CUPS_CSPACE_GOLD</CODE> - Gold foil (black as gold foil)</LI>
+<LI><CODE>CUPS_CSPACE_SILVER</CODE> - Silver foil (black as silver foil)</LI>
+</UL>
+<H1 ALIGN="RIGHT"><A NAME="STRUCTURES">C - Structures</A></H1>
+<P>This appendix describes all of the structures that are defined by the
+ CUPS API.</P>
+<H2><A NAME="9_1">CUPS Structures</A></H2>
+<H3><A NAME="cups_dest_t">CUPS Destinations</A></H3>
+<P>The CUPS destination structure (<CODE>cups_dest_t</CODE>) contains
+ information on a specific destination or instance:
+<CENTER>
+<TABLE BORDER="1" WIDTH="90%">
+<TR><TH>Member</TH><TH>Type</TH><TH>Description</TH></TR>
+<TR><TD>name</TD><TD>char *</TD><TD>The name of the printer or class.</TD>
+</TR>
+<TR><TD>instance</TD><TD>char *</TD><TD>The instance of the printer or
+ class; NULL for the primary instance.</TD></TR>
+<TR><TD>is_default</TD><TD>int</TD><TD>1 if the destination is set as
+ the default, 0 otherwise.</TD></TR>
+<TR><TD>num_options</TD><TD>int</TD><TD>The number of options associated
+ with this destination.</TD></TR>
+<TR><TD>options</TD><TD><A HREF="#cups_option_t">cups_option_t *</A></TD><TD>
+The options associated with this destination.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="cups_job_t">CUPS Jobs</A></H3>
+<P>The CUPS job structure (<CODE>cups_job_t</CODE>) contains information
+ on a specific job:
+<CENTER>
+<TABLE BORDER="1" WIDTH="90%">
+<TR><TH>Member</TH><TH>Type</TH><TH>Description</TH></TR>
+<TR><TD>id</TD><TD>int</TD><TD>The job ID for this job.</TD></TR>
+<TR><TD>dest</TD><TD>char *</TD><TD>The destination for this job
+ (printer or class name).</TD></TR>
+<TR><TD>title</TD><TD>char *</TD><TD>The job-name for this job (title).</TD>
+</TR>
+<TR><TD>user</TD><TD>char *</TD><TD>The job-originating-user-name for
+ this job (username).</TD></TR>
+<TR><TD>format</TD><TD>char *</TD><TD>The document-format for this job
+ (MIME type string).</TD></TR>
+<TR><TD>state</TD><TD>ipp_jstate</TD><TD>The current state of the job.</TD>
+</TR>
+<TR><TD>size</TD><TD>int</TD><TD>The size of this job in kilobytes.</TD></TR>
+<TR><TD>priority</TD><TD>int</TD><TD>The priority of this job from 1 to
+ 100 (50 is normal).</TD></TR>
+<TR><TD>completed_time</TD><TD>time_t</TD><TD>The time the job was
+ completed, or 0 if not yet completed.</TD></TR>
+<TR><TD>creation_time</TD><TD>time_t</TD><TD>The time the job was
+ queued.</TD></TR>
+<TR><TD>processing_time</TD><TD>time_t</TD><TD>The time the job started
+ printing.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="cups_lang_t">CUPS Messages</A></H3>
+<P>The CUPS messages structure (<CODE>cups_lang_t</CODE>) contains the
+ character set, locale name, and messages array:
+<CENTER>
+<TABLE BORDER="1" WIDTH="90%">
+<TR><TH>Member</TH><TH>Type</TH><TH>Description</TH></TR>
+<TR><TD>next</TD><TD>cups_lang_t *</TD><TD>Pointer to the next messages
+ structure in memory.</TD></TR>
+<TR><TD>used</TD><TD>int</TD><TD>The number of active users of this
+ messages structure.</TD></TR>
+<TR><TD>encoding</TD><TD>cups_encoding_t</TD><TD>The character encoding
+ of the message strings.</TD></TR>
+<TR><TD>language</TD><TD>char [16]</TD><TD>The language/locale name.</TD>
+</TR>
+<TR><TD>messages</TD><TD>char *[]</TD><TD>The array of message strings.</TD>
+</TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="cups_option_t">CUPS Options</A></H3>
+<P>The CUPS option structure (<CODE>cups_option_t</CODE>) contains the
+ option name and string value:
+<CENTER>
+<TABLE BORDER="1" WIDTH="90%">
+<TR><TH>Member</TH><TH>Type</TH><TH>Description</TH></TR>
+<TR><TD>name</TD><TD>char *</TD><TD>The name of the option.</TD></TR>
+<TR><TD>value</TD><TD>char *</TD><TD>The string value of the option.</TD>
+</TR>
+</TABLE>
+</CENTER>
+</P>
+<H2><A NAME="9_2">Networking Structures</A></H2>
+<H3><A NAME="http_t">HTTP State</A></H3>
+<P>The HTTP state structure (<CODE>http_t</CODE>) contains the current
+ state of a HTTP request or response:
+<CENTER>
+<TABLE BORDER="1" WIDTH="90%">
+<TR><TH>Member</TH><TH>Type</TH><TH>Description</TH></TR>
+<TR><TD>fd</TD><TD>int</TD><TD>The socket for the HTTP connection.</TD></TR>
+<TR><TD>blocking</TD><TD>int</TD><TD>1 if the HTTP functions should
+ block, 0 if not.</TD></TR>
+<TR><TD>error</TD><TD>int</TD><TD>The last OS error that occurred on the
+ socket.</TD></TR>
+<TR><TD>activity</TD><TD>time_t</TD><TD>The last time the HTTP
+ connection was used.</TD></TR>
+<TR><TD>state</TD><TD>http_state_t</TD><TD>The current HTTP
+ request/response state.</TD></TR>
+<TR><TD>status</TD><TD>int</TD><TD>The last HTTP status seen.</TD></TR>
+<TR><TD>version</TD><TD>http_version_t</TD><TD>The HTTP protocol version
+ in use.</TD></TR>
+<TR><TD>keep_alive</TD><TD>http_keep_alive_t</TD><TD>Whether or not to
+ use Keep-Alive</TD></TR>
+<TR><TD>hostaddr</TD><TD>struct sockaddr_in</TD><TD>The IPv4 address of
+ the HTTP server.</TD></TR>
+<TR><TD>hostname</TD><TD>char []</TD><TD>The hostname of the HTTP
+ server.</TD></TR>
+<TR><TD>fields</TD><TD>char [][]</TD><TD>The string values of all HTTP
+ request/response fields.</TD></TR>
+<TR><TD>data</TD><TD>char *</TD><TD>Current byte in data buffer.</TD></TR>
+<TR><TD>data_encoding</TD><TD>http_encoding_t</TD><TD>The transfer
+ encoding for the request/response.</TD></TR>
+<TR><TD>data_remaining</TD><TD>int</TD><TD>The number of bytes remaining
+ in the current request, response, or chunk.</TD></TR>
+<TR><TD>used</TD><TD>int</TD><TD>The number of bytes that are used in
+ the buffer.</TD></TR>
+<TR><TD>buffer</TD><TD>char []</TD><TD>The read/write buffer.</TD></TR>
+<TR><TD>auth_type</TD><TD>int</TD><TD>The type of authentication in use.</TD>
+</TR>
+<TR><TD>md5_state</TD><TD>md5_state_t</TD><TD>The current MD5 digest
+ state.</TD></TR>
+<TR><TD>nonce</TD><TD>char []</TD><TD>The nonce value for Digest
+ authentication.</TD></TR>
+<TR><TD>nonce_count</TD><TD>int</TD><TD>The nonce count value.</TD></TR>
+<TR><TD>tls</TD><TD>void *</TD><TD>A pointer to private encryption data.</TD>
+</TR>
+<TR><TD>encryption</TD><TD>http_encryption_t</TD><TD>The current
+ encryption mode.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="ipp_t">IPP State</A></H3>
+<P>The IPP state structure (<CODE>ipp_t</CODE>) contains the current
+ state of a IPP request or response:
+<CENTER>
+<TABLE BORDER="1" WIDTH="90%">
+<TR><TH>Member</TH><TH>Type</TH><TH>Description</TH></TR>
+<TR><TD></TD><TD></TD><TD></TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H2><A NAME="9_3">Raster Structures</A></H2>
+<H3><A NAME="cups_raster_header_t">Raster Page Header</A></H3>
+<P>The raster page header (<CODE>cups_raster_header_t</CODE>) consists
+ of the PostScript page device dictionary for the page:
+<CENTER>
+<TABLE BORDER="1" WIDTH="90%">
+<TR><TH>Member</TH><TH>Type</TH><TH>Description</TH></TR>
+<TR><TD>MediaClass</TD><TD>char[64]</TD><TD>The media class name</TD></TR>
+<TR><TD>MediaColor</TD><TD>char[64]</TD><TD>The media color name</TD></TR>
+<TR><TD>MediaType</TD><TD>char[64]</TD><TD>The media type name</TD></TR>
+<TR><TD>OutputType</TD><TD>char[64]</TD><TD>The output type name</TD></TR>
+<TR><TD>AdvanceDistance</TD><TD>unsigned</TD><TD>The distance to advance
+ the media in points</TD></TR>
+<TR><TD>AdvanceMedia</TD><TD>cups_adv_t</TD><TD>When to advance the
+ media</TD></TR>
+<TR><TD>Collate</TD><TD>cups_bool_t</TD><TD>Whether or not to produce
+ collated copies</TD></TR>
+<TR><TD>CutMedia</TD><TD>cups_cut_t</TD><TD>When to cut the media</TD></TR>
+<TR><TD>Duplex</TD><TD>cups_bool_t</TD><TD>Whether or not to print on
+ both sides of the paper</TD></TR>
+<TR><TD>HWResolution</TD><TD>unsigned[2]</TD><TD>The resolution of the
+ page image in pixels per inch; the HWResolution[0] represents the
+ horizontal resolution and HWResolution[1] represents the vertical
+ resolution</TD></TR>
+<TR><TD>ImagingBoundingBox</TD><TD>unsigned[4]</TD><TD>The bounding box
+ for the page in points; the elements represent the left, bottom, right,
+ and top coordinates of the imaged area (if 0 then the whole page is
+ imaged)</TD></TR>
+<TR><TD>InsertSheet</TD><TD>cups_bool_t</TD><TD>Whether or not to insert
+ a sheet before this page</TD></TR>
+<TR><TD>Jog</TD><TD>cups_jog_t</TD><TD>When to jog copies of the page</TD>
+</TR>
+<TR><TD>LeadingEdge</TD><TD>cups_edge_t</TD><TD>The leading edge of the
+ page</TD></TR>
+<TR><TD>Margins</TD><TD>unsigned[2]</TD><TD>The lower-lefthand margin of
+ the page in points</TD></TR>
+<TR><TD>ManualFeed</TD><TD>cups_bool_t</TD><TD>Whether or not to
+ manually feed the page</TD></TR>
+<TR><TD>MediaPosition</TD><TD>unsigned</TD><TD>The input slot number to
+ use</TD></TR>
+<TR><TD>MediaWeight</TD><TD>unsigned</TD><TD>The weight of the output
+ media in grams/m<SUP>2</SUP></TD></TR>
+<TR><TD>MirrorPrint</TD><TD>cups_bool_t</TD><TD>Whether or not to mirror
+ the print</TD></TR>
+<TR><TD>NegativePrint</TD><TD>cups_bool_t</TD><TD>Whether or not to
+ invert the print</TD></TR>
+<TR><TD>NumCopies</TD><TD>unsigned</TD><TD>The number of copies to
+ produce</TD></TR>
+<TR><TD>Orientation</TD><TD>cups_orient_t</TD><TD>The orientation of the
+ page image</TD></TR>
+<TR><TD>OutputFaceUp</TD><TD>cups_bool_t</TD><TD>Whether or not to
+ output the page face up</TD></TR>
+<TR><TD>PageSize</TD><TD>unsigned[2]</TD><TD>The width and height of the
+ page in points</TD></TR>
+<TR><TD>Separations</TD><TD>cups_bool_t</TD><TD>Whether or not to output
+ separations</TD></TR>
+<TR><TD>TraySwitch</TD><TD>cups_bool_t</TD><TD>Whether or not to
+ automatically switch trays for the requested media size/type</TD></TR>
+<TR><TD>Tumble</TD><TD>cups_bool_t</TD><TD>Whether or not to rotate the
+ back side of the page</TD></TR>
+<TR><TD>cupsWidth</TD><TD>unsigned</TD><TD>The width of the page image
+ in pixels</TD></TR>
+<TR><TD>cupsHeight</TD><TD>unsigned</TD><TD>The height of the page image
+ in pixels</TD></TR>
+<TR><TD>cupsMediaType</TD><TD>unsigned</TD><TD>The device-specific media
+ type code</TD></TR>
+<TR><TD>cupsBitsPerColor</TD><TD>unsigned</TD><TD>The number of bits per
+ color</TD></TR>
+<TR><TD>cupsBitsPerPixel</TD><TD>unsigned</TD><TD>The number of bits per
+ pixel</TD></TR>
+<TR><TD>cupsBytesPerLine</TD><TD>unsigned</TD><TD>The number of bytes
+ per line of image data</TD></TR>
+<TR><TD>cupsColorOrder</TD><TD>cups_order_t</TD><TD>The order of color
+ values</TD></TR>
+<TR><TD>cupsColorSpace</TD><TD>cups_cspace_t</TD><TD>The type of color
+ values</TD></TR>
+<TR><TD>cupsCompression</TD><TD>unsigned</TD><TD>The device-specific
+ compression code</TD></TR>
+<TR><TD>cupsRowCount</TD><TD>unsigned</TD><TD>The device-specific row
+ count</TD></TR>
+<TR><TD>cupsRowFeed</TD><TD>unsigned</TD><TD>The device-specific row
+ feed</TD></TR>
+<TR><TD>cupsRowStep</TD><TD>unsigned</TD><TD>The device-specific row
+ step</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H1 ALIGN="RIGHT"><A NAME="FUNCTIONS">D - Functions</A></H1>
+<P>This appendix provides a reference for all of the CUPS API functions.
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsAddDest">cupsAddDest()</A></H2>
+<H3><A NAME="10_1_1">Usage</A></H3>
+<PRE>
+int
+cupsAddDest(const char *name,
+ const char *instance,
+ int num_dests,
+ cups_dest_t **dests);
+</PRE>
+<H3><A NAME="10_1_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>name</TD><TD>The name of the destination.</TD></TR>
+<TR><TD>instance</TD><TD>The instance of the destination, or NULL for
+ the primary instance.</TD></TR>
+<TR><TD>num_dests</TD><TD>The number of destinations in the array.</TD></TR>
+<TR><TD>dest</TD><TD>A pointer to the destination array pointer.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_1_3">Returns</A></H3>
+<P>The new number of destinations in the array.</P>
+<H3><A NAME="10_1_4">Description</A></H3>
+<P><CODE>cupsAddDest()</CODE> adds the named destination to the
+ destination array if it does not already exist.</P>
+<H3><A NAME="10_1_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_dests;
+<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
+
+
+num_dests = cupsAddDests(&quot;foo&quot;, &quot;bar&quot;, num_dests, &amp;dests);
+</PRE>
+<H3><A NAME="10_1_6">See Also</A></H3>
+<P><A HREF="#cupsFreeDests"> <CODE>cupsFreeDests()</CODE></A>,<A HREF="#cupsGetDest">
+ <CODE>cupsGetDest()</CODE></A>,<A HREF="#cupsGetDests"> <CODE>
+cupsGetDests()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsAddOption">cupsAddOption()</A></H2>
+<H3><A NAME="10_2_1">Usage</A></H3>
+<PRE>
+int
+cupsAddOption(const char *name,
+ const char *value,
+ int num_options,
+ cups_option_t **options);
+</PRE>
+<H3><A NAME="10_2_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>name</TD><TD>The name of the option.</TD></TR>
+<TR><TD>value</TD><TD>The value of the option.</TD></TR>
+<TR><TD>num_options</TD><TD>Number of options currently in the array.</TD>
+</TR>
+<TR><TD>options</TD><TD>Pointer to the options array.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_2_3">Returns</A></H3>
+<P>The new number of options.</P>
+<H3><A NAME="10_2_4">Description</A></H3>
+<P><CODE>cupsAddOption()</CODE> adds an option to the specified array.</P>
+<H3><A NAME="10_2_5">Example</A></H3>
+<PRE>
+#include &lt;cups.h&gt;
+
+...
+
+/* Declare the options array */
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+
+/* Initialize the options array */
+num_options = 0;
+options = (cups_option_t *)0;
+
+/* Add options using cupsAddOption() */
+num_options = cupsAddOption(&quot;media&quot;, &quot;letter&quot;, num_options, &amp;options);
+num_options = cupsAddOption(&quot;resolution&quot;, &quot;300dpi&quot;, num_options, &amp;options);
+</PRE>
+<H3><A NAME="10_2_6">See Also</A></H3>
+<A HREF="#cupsEncodeOptions"> <CODE>cupsEncodeOptions()</CODE></A>,<A HREF="#cupsFreeOptions">
+ <CODE>cupsFreeOptions()</CODE></A>,<A HREF="#cupsGetOption"> <CODE>
+cupsGetOption()</CODE></A>,<A HREF="#cupsParseOptions"> <CODE>
+cupsParseOptions()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="cupsCancelJob">cupsCancelJob()</A></H2>
+<H3><A NAME="10_3_1">Usage</A></H3>
+<PRE>
+int
+cupsCancelJob(const char *dest,
+ int job);
+</PRE>
+<H3><A NAME="10_3_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>dest</TD><TD>Printer or class name</TD></TR>
+<TR><TD>job</TD><TD>Job ID</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_3_3">Returns</A></H3>
+<P>1 on success, 0 on failure. On failure the error can be found by
+ calling<A HREF="#cupsLastError"> <CODE>cupsLastError()</CODE></A>.</P>
+<H3><A NAME="10_3_4">Description</A></H3>
+<P><CODE>cupsCancelJob()</CODE> cancels the specifies job.</P>
+<H3><A NAME="10_3_5">Example</A></H3>
+<PRE>
+#include &lt;cups.h&gt;
+
+cupsCancelJob(&quot;LaserJet&quot;, 1);
+</PRE>
+<H3><A NAME="10_3_6">See Also</A></H3>
+<P><A HREF="#cupsLastError"> <CODE>cupsLastError()</CODE></A>,<A HREF="#cupsPrintFile">
+ <CODE>cupsPrintFile()</CODE></A>,<A HREF="#cupsPrintFiles"> <CODE>
+cupsPrintFiles()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsDoFileRequest">cupsDoFileRequest()</A></H2>
+<H3><A NAME="10_4_1">Usage</A></H3>
+<PRE>
+ipp_t *
+cupsDoFileRequest(http_t *http,
+ ipp_t *request,
+ const char *resource,
+ const char *filename);
+</PRE>
+<H3><A NAME="10_4_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>HTTP connection to server.</TD></TR>
+<TR><TD>request</TD><TD>IPP request data.</TD></TR>
+<TR><TD>resource</TD><TD>HTTP resource name for POST.</TD></TR>
+<TR><TD>filename</TD><TD>File to send with POST request (<CODE>NULL</CODE>
+ pointer if none.)</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_4_3">Returns</A></H3>
+<P>IPP response data or <CODE>NULL</CODE> if the request fails. On
+ failure the error can be found by calling<A HREF="#cupsLastError"> <CODE>
+cupsLastError()</CODE></A>.</P>
+<H3><A NAME="10_4_4">Description</A></H3>
+<P><CODE>cupsDoFileRequest()</CODE> does a HTTP POST request and
+ provides the IPP request and optionally the contents of a file to the
+ IPP server. It also handles resubmitting the request and performing
+ password authentication as needed.</P>
+<H3><A NAME="10_4_5">Example</A></H3>
+<PRE>
+#include &lt;cups.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+<A HREF="#ipp_t">ipp_t</A> *request;
+ipp_t *response;
+
+...
+
+/* Get the default language */
+language = <A HREF="#cupsLangDefault">cupsLangDefault()</A>;
+
+/* Create a new IPP request */
+request = <A HREF="#ippNew">ippNew()</A>;
+
+request-&gt;request.op.operation_id = IPP_PRINT_FILE;
+request-&gt;request.op.request_id = 1;
+
+/* Add required attributes */
+<A HREF="#ippAddString">ippAddString</A>(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ &quot;attributes-charset&quot;, NULL, <A HREF="#cupsLangEncoding">cupsLangEncoding</A>(language));
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ &quot;attributes-natural-language&quot;, NULL,
+ language != NULL ? language-&gt;language : &quot;C&quot;);
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, &quot;printer-uri&quot;,
+ NULL, &quot;ipp://hostname/resource&quot;);
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, &quot;requesting-user-name&quot;,
+ NULL, <A HREF="#cupsUser">cupsUser()</A>);
+
+/* Do the request... */
+response = cupsDoFileRequest(http, request, &quot;/resource&quot;, &quot;filename.txt&quot;);
+</PRE>
+<H3><A NAME="10_4_6">See Also</A></H3>
+<P><A HREF="#cupsLangDefault"> <CODE>cupsLangDefault()</CODE></A>,<A HREF="#cupsLangEncoding">
+ <CODE>cupsLangEncoding()</CODE></A>,<A HREF="#cupsUser"> <CODE>
+cupsUser()</CODE></A>,<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>
+,<A HREF="#ippAddString"> <CODE>ippAddString()</CODE></A>,<A HREF="#ippNew">
+ <CODE>ippNew()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsDoRequest">cupsDoRequest()</A></H2>
+<H3><A NAME="10_5_1">Usage</A></H3>
+<PRE>
+ipp_t *
+cupsDoRequest(http_t *http,
+ ipp_t *request,
+ const char *resource);
+</PRE>
+<H3><A NAME="10_5_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>HTTP connection to server.</TD></TR>
+<TR><TD>request</TD><TD>IPP request data.</TD></TR>
+<TR><TD>resource</TD><TD>HTTP resource name for POST.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_5_3">Returns</A></H3>
+<P>IPP response data or <CODE>NULL</CODE> if the request fails. On
+ failure the error can be found by calling<A HREF="#cupsLastError"> <CODE>
+cupsLastError()</CODE></A>.</P>
+<H3><A NAME="10_5_4">Description</A></H3>
+<P><CODE>cupsDoRequest()</CODE> does a HTTP POST request and provides
+ the IPP request to the IPP server. It also handles resubmitting the
+ request and performing password authentication as needed.</P>
+<H3><A NAME="10_5_5">Example</A></H3>
+<PRE>
+#include &lt;cups.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+<A HREF="#ipp_t">ipp_t</A> *request;
+ipp_t *response;
+
+...
+
+/* Get the default language */
+language = <A HREF="#cupsLangDefault">cupsLangDefault()</A>;
+
+/* Create a new IPP request */
+request = <A HREF="#ippNew">ippNew()</A>;
+
+request-&gt;request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+request-&gt;request.op.request_id = 1;
+
+/* Add required attributes */
+<A HREF="#ippAddString">ippAddString</A>(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ &quot;attributes-charset&quot;, NULL, <A HREF="#cupsLangEncoding">cupsLangEncoding</A>(language));
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ &quot;attributes-natural-language&quot;, NULL,
+ language != NULL ? language-&gt;language : &quot;C&quot;);
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, &quot;printer-uri&quot;,
+ NULL, &quot;ipp://hostname/resource&quot;);
+
+/* Do the request... */
+response = cupsDoRequest(http, request, &quot;/resource&quot;);
+</PRE>
+<H3><A NAME="10_5_6">See Also</A></H3>
+<P><A HREF="#cupsLangDefault"> <CODE>cupsLangDefault()</CODE></A>,<A HREF="#cupsLangEncoding">
+ <CODE>cupsLangEncoding()</CODE></A>,<A HREF="#cupsUser"> <CODE>
+cupsUser()</CODE></A>,<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>
+,<A HREF="#ippAddString"> <CODE>ippAddString()</CODE></A>,<A HREF="#ippNew">
+ <CODE>ippNew()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsEncodeOptions">cupsEncodeOptions()</A></H2>
+<H3><A NAME="10_6_1">Usage</A></H3>
+<PRE>
+void
+cupsEncodeOptions(ipp_t *ipp,
+ int num_options,
+ cups_option_t *options);
+</PRE>
+<H3><A NAME="10_6_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request.</TD></TR>
+<TR><TD>num_options</TD><TD>The number of options.</TD></TR>
+<TR><TD>options</TD><TD>The options.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_6_3">Description</A></H3>
+<P><CODE>cupsEncodeOptions()</CODE> encodes all of the options in the
+ specified array as IPP attributes and adds them to the IPP request.</P>
+<H3><A NAME="10_6_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+<A HREF="#ipp_t">ipp_t</A> *ipp;
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+
+
+cupsEncodeOptions(ipp, num_options, options);
+</PRE>
+<H3><A NAME="10_6_5">See Also</A></H3>
+<P><A HREF="#cupsAddOption"> <CODE>cupsAddOption()</CODE></A>,<A HREF="#cupsParseOptions">
+ <CODE>cupsParseOptions()</CODE></A>,<A HREF="#ippNew"> <CODE>ippNew()</CODE>
+</A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsEncryption">cupsEncryption()</A></H2>
+<H3><A NAME="10_7_1">Usage</A></H3>
+<PRE>
+http_encryption_t
+cupsEncryption(void);
+</PRE>
+<H3><A NAME="10_7_2">Returns</A></H3>
+<P>The current encryption setting.</P>
+<H3><A NAME="10_7_3">Description</A></H3>
+<P><CODE>cupsEncryption()</CODE> returns the current encryption setting
+ for IPP requests such as printing.</P>
+<H3><A NAME="10_7_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+printf(&quot;The current encryption setting is %d.\n&quot;, cupsEncryption());
+
+http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
+</PRE>
+<H3><A NAME="10_7_5">See Also</A></H3>
+<P><A HREF="#cupsServer"> <CODE>cupsServer()</CODE></A>,<A HREF="#httpConnectEncrypt">
+ <CODE>httpConnectEncrypt()</CODE></A>,<A HREF="#ippPort"> <CODE>
+ippPort()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsFreeDests">cupsFreeDests()</A></H2>
+<H3><A NAME="10_8_1">Usage</A></H3>
+<PRE>
+void
+cupsFreeDests(int num_dests,
+ cups_dest_t *dests);
+</PRE>
+<H3><A NAME="10_8_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>num_dests</TD><TD>The number of destinations in the array.</TD></TR>
+<TR><TD>dests</TD><TD>The destination array.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_8_3">Description</A></H3>
+<P><CODE>cupsFreeDests()</CODE> frees a destination array that was
+ created using <CODE>cupsGetDests()</CODE>.</P>
+<H3><A NAME="10_8_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_dests;
+<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
+cups_dest_t *dest;
+
+num_dests = cupsGetDests(&amp;dests);
+dest = cupsGetDest(NULL, NULL, num_dests, dests);
+
+if (dest)
+ printf(&quot;The default destination is %s\n&quot;, dest-&gt;name);
+else
+ puts(&quot;No default destination.&quot;);
+
+cupsFreeDests(num_dests, dests);
+</PRE>
+<H3><A NAME="10_8_5">See Also</A></H3>
+<P><A HREF="#cupsGetDest"> <CODE>cupsGetDest()</CODE></A>,<A HREF="#cupsGetDests">
+ <CODE>cupsGetDests()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsFreeJobs">cupsFreeJobs()</A></H2>
+<H3><A NAME="10_9_1">Usage</A></H3>
+<PRE>
+void
+cupsFreeJobs(int num_jobs,
+ cups_job_t *jobs);
+</PRE>
+<H3><A NAME="10_9_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>num_jobs</TD><TD>The number of jobs.</TD></TR>
+<TR><TD>jobs</TD><TD>The job array.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_9_3">Description</A></H3>
+<P><CODE>cupsFreeJobs()</CODE> frees an array of print jobs created by
+ the <CODE>cupsGetJobs()</CODE> function.</P>
+<H3><A NAME="10_9_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int i;
+int num_jobs;
+<A HREF="#cups_job_t">cups_job_t</A> *jobs;
+
+
+num_jobs = cupsGetJobs(&amp;jobs, NULL, 0, 0);
+
+printf(&quot;%d active job(s):\n&quot;, num_jobs);
+for (i = 0; i &lt; num_jobs; i ++)
+ printf(&quot;%-16.16s %-6d %-12.12s %s (%s)\n&quot;, jobs[i].dest, jobs[i].id,
+ jobs[i].user, jobs[i].title,
+ jobs[i].state != IPP_JOB_PENDING ? &quot;printing&quot; : &quot;pending&quot;);
+
+cupsFreeJobs(num_jobs, jobs);
+</PRE>
+<H3><A NAME="10_9_5">See Also</A></H3>
+<P><A HREF="#cupsGetJobs"> <CODE>cupsGetJobs()</CODE></A>,<A HREF="#cupsGetDests">
+ <CODE>cupsGetDests()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsFreeOptions">cupsFreeOptions()</A></H2>
+<H3><A NAME="10_10_1">Usage</A></H3>
+<PRE>
+void
+cupsFreeOptions(int num_options,
+ cups_option_t *options);
+</PRE>
+<H3><A NAME="10_10_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>num_options</TD><TD>Number of options in array.</TD></TR>
+<TR><TD>options</TD><TD>Pointer to options array.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_10_3">Description</A></H3>
+<P><CODE>cupsFreeOptions()</CODE> frees all memory associated with the
+ option array specified.</P>
+<H3><A NAME="10_10_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+
+...
+
+cupsFreeOptions(num_options, options);
+</PRE>
+<H3><A NAME="10_10_5">See Also</A></H3>
+<P><A HREF="#cupsAddOption"> <CODE>cupsAddOption()</CODE></A>,<A HREF="#cupsEncodeOptions">
+ <CODE>cupsEncodeOptions()</CODE></A>,<A HREF="#cupsGetOption"> <CODE>
+cupsGetOption()</CODE></A>,<A HREF="#cupsMarkOptions"> <CODE>
+cupsMarkOptions()</CODE></A>,<A HREF="#cupsParseOptions"> <CODE>
+cupsParseOptions()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsGetClasses">cupsGetClasses()</A></H2>
+<H3><A NAME="10_11_1">Usage</A></H3>
+<PRE>
+int
+cupsGetClasses(char ***classes);
+</PRE>
+<H3><A NAME="10_11_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>classes</TD><TD>Pointer to character pointer array.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_11_3">Returns</A></H3>
+<P>The number of printer classes available.</P>
+<H3><A NAME="10_11_4">Description</A></H3>
+<P><CODE>cupsGetClasses()</CODE> gets a list of the available printer
+ classes. The returned array should be freed using the <CODE>free()</CODE>
+ when it is no longer needed.</P>
+<H3><A NAME="10_11_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int i;
+int num_classes;
+char **classes;
+
+...
+
+num_classes = cupsGetClasses(
+
+...
+
+if (num_classes &gt; 0)
+{
+ for (i = 0; i &lt; num_classes; i ++)
+ free(classes[i]);
+
+ free(classes);
+}
+</PRE>
+<H3><A NAME="10_11_6">See Also</A></H3>
+<P><A HREF="#cupsGetDefault"> <CODE>cupsGetDefault()</CODE></A>,<A HREF="#cupsGetPrinters">
+ <CODE>cupsGetPrinters()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsGetDefault">cupsGetDefault()</A></H2>
+<H3><A NAME="10_12_1">Usage</A></H3>
+<PRE>
+const char *
+cupsGetDefault(void);
+</PRE>
+<H3><A NAME="10_12_2">Returns</A></H3>
+<P>A pointer to the default destination.</P>
+<H3><A NAME="10_12_3">Description</A></H3>
+<P><CODE>cupsGetDefault()</CODE> gets the default destination printer or
+ class. The default destination is stored in a static string and will be
+ overwritten (usually with the same value) after each call.</P>
+<H3><A NAME="10_12_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+printf(&quot;The default destination is %s\n&quot;, cupsGetDefault());
+</PRE>
+<H3><A NAME="10_12_5">See Also</A></H3>
+<P><A HREF="#cupsGetClasses"> <CODE>cupsGetClasses()</CODE></A>,<A HREF="#cupsGetPrinters">
+ <CODE>cupsGetPrinters()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsGetDest">cupsGetDest()</A></H2>
+<H3><A NAME="10_13_1">Usage</A></H3>
+<PRE>
+cups_dest_t *
+cupsGetDest(const char *name,
+ const char *instance,
+ int num_dests,
+ cups_dest_t *dests);
+</PRE>
+<H3><A NAME="10_13_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>name</TD><TD>The name of the destination, or NULL for the
+ default destination.</TD></TR>
+<TR><TD>instance</TD><TD>The instance of the destination, or NULL for
+ the primary instance.</TD></TR>
+<TR><TD>num_dests</TD><TD>The number of destinations.</TD></TR>
+<TR><TD>dests</TD><TD>The destination array.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_13_3">Returns</A></H3>
+<P>A pointer to the specified destination, or NULL if none exists.</P>
+<H3><A NAME="10_13_4">Description</A></H3>
+<P><CODE>cupsGetDest()</CODE> finds the specified destination in the
+ array of destinations created by the <CODE>cupsGetDests()</CODE>
+ function.</P>
+<H3><A NAME="10_13_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_dests;
+<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
+cups_dest_t *dest;
+
+num_dests = cupsGetDests(&amp;dests);
+dest = cupsGetDest(NULL, NULL, num_dests, dests);
+
+if (dest)
+ printf(&quot;The default destination is %s\n&quot;, dest-&gt;name);
+else
+ puts(&quot;No default destination.&quot;);
+
+cupsFreeDests(num_dests, dests);
+</PRE>
+<H3><A NAME="10_13_6">See Also</A></H3>
+<P><A HREF="#cupsGetDests"> <CODE>cupsGetDests()</CODE></A>,<A HREF="#cupsGetJobs">
+ <CODE>cupsGetJobs()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsGetDests">cupsGetDests()</A></H2>
+<H3><A NAME="10_14_1">Usage</A></H3>
+<PRE>
+int
+cupsGetDests(cups_dest_t **dests);
+</PRE>
+<H3><A NAME="10_14_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>dests</TD><TD>A pointer to a destination array pointer.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_14_3">Returns</A></H3>
+<P>The number of available destinations.</P>
+<H3><A NAME="10_14_4">Description</A></H3>
+<P><CODE>cupsGetDests()</CODE> creates an array of available
+ destinations that the user can print to. The array should be freed
+ using the <CODE>cupsFreeDests()</CODE> function.</P>
+<H3><A NAME="10_14_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_dests;
+<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
+cups_dest_t *dest;
+
+num_dests = cupsGetDests(&amp;dests);
+dest = cupsGetDest(NULL, NULL, num_dests, dests);
+
+if (dest)
+ printf(&quot;The default destination is %s\n&quot;, dest-&gt;name);
+else
+ puts(&quot;No default destination.&quot;);
+
+cupsFreeDests(num_dests, dests);
+</PRE>
+<H3><A NAME="10_14_6">See Also</A></H3>
+<P><A HREF="#cupsFreeDests"> <CODE>cupsFreeDests()</CODE></A>,<A HREF="#cupsGetDest">
+ <CODE>cupsGetDest()</CODE></A>,<A HREF="#cupsGetJobs"> <CODE>
+cupsGetJobs()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsGetJobs">cupsGetJobs()</A></H2>
+<H3><A NAME="10_15_1">Usage</A></H3>
+<PRE>
+int
+cupsGetJobs(cups_job_t **jobs,
+ const char *dest,
+ int myjobs,
+ int completed);
+</PRE>
+<H3><A NAME="10_15_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>jobs</TD><TD>A pointer to the job array pointer.</TD></TR>
+<TR><TD>dest</TD><TD>The destination name, or NULL if jobs for all
+ destinations are requested.</TD></TR>
+<TR><TD>myjobs</TD><TD>1 if only those jobs submitted by the current <CODE>
+cupsUser()</CODE> should be returned, 0 for jobs submitted by all users.</TD>
+</TR>
+<TR><TD>completed</TD><TD>1 if only completed jobs should be returned, 0
+ if only pending/processing jobs should be returned.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_15_3">Returns</A></H3>
+<P>The number of jobs.</P>
+<H3><A NAME="10_15_4">Description</A></H3>
+<P><CODE>cupsGetJobs()</CODE> creates an array of print jobs based on
+ the arguments supplied in the function call. The returned array should
+ be freed using the <CODE>cupsFreeJobs()</CODE> function.</P>
+<H3><A NAME="10_15_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int i;
+int num_jobs;
+<A HREF="#cups_job_t">cups_job_t</A> *jobs;
+
+
+num_jobs = cupsGetJobs(&amp;jobs, NULL, 0, 0);
+
+printf(&quot;%d active job(s):\n&quot;, num_jobs);
+for (i = 0; i &lt; num_jobs; i ++)
+ printf(&quot;%-16.16s %-6d %-12.12s %s (%s)\n&quot;, jobs[i].dest, jobs[i].id,
+ jobs[i].user, jobs[i].title,
+ jobs[i].state != IPP_JOB_PENDING ? &quot;printing&quot; : &quot;pending&quot;);
+
+cupsFreeJobs(num_jobs, jobs);
+</PRE>
+<H3><A NAME="10_15_6">See Also</A></H3>
+<P><A HREF="#cupsFreeJobs"> <CODE>cupsFreeJobs()</CODE></A>,<A HREF="#cupsGetDests">
+ <CODE>cupsGetDests()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsGetOption">cupsGetOption()</A></H2>
+<H3><A NAME="10_16_1">Usage</A></H3>
+<PRE>
+const char *
+cupsGetOption(const char *name,
+ int num_options,
+ cups_option_t *options);
+</PRE>
+<H3><A NAME="10_16_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>name</TD><TD>The name of the option.</TD></TR>
+<TR><TD>num_options</TD><TD>The number of options in the array.</TD></TR>
+<TR><TD>options</TD><TD>The options array.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_16_3">Returns</A></H3>
+<P>A pointer to the option values or <CODE>NULL</CODE> if the option is
+ not defined.</P>
+<H3><A NAME="10_16_4">Description</A></H3>
+<P><CODE>cupsGetOption()</CODE> returns the first occurrence of the
+ named option. If the option is not included in the options array then a
+ <CODE>NULL</CODE> pointer is returned.</P>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_options;
+cups_option_t *options;
+const char *media;
+
+...
+
+media = cupsGetOption(&quot;media&quot;, num_options, options);
+</PRE>
+<H3><A NAME="10_16_5">See Also</A></H3>
+<P><A HREF="#cupsAddOption"> <CODE>cupsAddOption()</CODE></A>,<A HREF="#cupsEncodeOptions">
+ <CODE>cupsEncodeOptions()</CODE></A>,<A HREF="#cupsFreeOptions"> <CODE>
+cupsFreeOptions()</CODE></A>,<A HREF="#cupsMarkOptions"> <CODE>
+cupsMarkOptions()</CODE></A>,<A HREF="#cupsParseOptions"> <CODE>
+cupsParseOptions()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsGetPassword">cupsGetPassword()</A></H2>
+<H3><A NAME="10_17_1">Usage</A></H3>
+<PRE>
+const char *
+cupsGetPassword(const char *prompt);
+</PRE>
+<H3><A NAME="10_17_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>prompt</TD><TD>The prompt to display to the user.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_17_3">Returns</A></H3>
+<P>A pointer to the password that was entered or <CODE>NULL</CODE> if no
+ password was entered.</P>
+<H3><A NAME="10_17_4">Description</A></H3>
+<P><CODE>cupsGetPassword()</CODE> displays the prompt string and asks
+ the user for a password. The password text is not echoed to the user.</P>
+<H3><A NAME="10_17_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+char *password;
+
+...
+
+password = cupsGetPassword(&quot;Please enter a password:&quot;);
+</PRE>
+<H3><A NAME="10_17_6">See Also</A></H3>
+<P><A HREF="#cupsServer"> <CODE>cupsServer()</CODE></A>,<A HREF="#cupsSetPasswordCB">
+ <CODE>cupsSetPasswordCB()</CODE></A>,<A HREF="#cupsSetServer"> <CODE>
+cupsSetServer()</CODE></A>,<A HREF="#cupsSetUser"> <CODE>cupsSetUser()</CODE>
+</A>,<A HREF="#cupsUser"> <CODE>cupsUser()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsGetPPD">cupsGetPPD()</A></H2>
+<H3><A NAME="10_18_1">Usage</A></H3>
+<PRE>
+const char *
+cupsGetPPD(const char *printer);
+</PRE>
+<H3><A NAME="10_18_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>printer</TD><TD>The name of the printer.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_18_3">Returns</A></H3>
+<P>The name of a temporary file containing the PPD file or <CODE>NULL</CODE>
+ if the printer cannot be located or does not have a PPD file.</P>
+<H3><A NAME="10_18_4">Description</A></H3>
+<P><CODE>cupsGetPPD()</CODE> gets a copy of the PPD file for the named
+ printer. The printer name can be of the form &quot;printer&quot; or
+ &quot;printer@hostname&quot;.</P>
+<P>You should remove (unlink) the PPD file after you are done using it.
+ The filename is stored in a static buffer and will be overwritten with
+ each call to <CODE>cupsGetPPD()</CODE>.</P>
+<H3><A NAME="10_18_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+char *ppd;
+
+...
+
+ppd = cupsGetPPD(&quot;printer@hostname&quot;);
+
+...
+
+unlink(ppd);
+</PRE>
+
+<!-- NEW PAGE -->
+<H2><A NAME="cupsGetPrinters">cupsGetPrinters()</A></H2>
+<H3><A NAME="10_19_1">Usage</A></H3>
+<PRE>
+int
+cupsGetPrinters(char ***printers);
+</PRE>
+<H3><A NAME="10_19_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>printers</TD><TD>Pointer to character pointer array.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_19_3">Returns</A></H3>
+<P>The number of printer printers available.</P>
+<H3><A NAME="10_19_4">Description</A></H3>
+<P><CODE>cupsGetPrinters()</CODE> gets a list of the available printers.
+ The returned array should be freed using the <CODE>free()</CODE> when
+ it is no longer needed.</P>
+<H3><A NAME="10_19_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int i;
+int num_printers;
+char **printers;
+
+...
+
+num_printers = cupsGetPrinters(
+
+...
+
+if (num_printers &gt; 0)
+{
+ for (i = 0; i &lt; num_printers; i ++)
+ free(printers[i]);
+
+ free(printers);
+}
+</PRE>
+<H3><A NAME="10_19_6">See Also</A></H3>
+<P><A HREF="#cupsGetClasses"> <CODE>cupsGetClasses()</CODE></A><A HREF="#cupsGetDefault">
+ <CODE>cupsGetDefault()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsLangDefault">cupsLangDefault()</A></H2>
+<H3><A NAME="10_20_1">Usage</A></H3>
+<PRE>
+const char *
+cupsLangDefault(void);
+</PRE>
+<H3><A NAME="10_20_2">Returns</A></H3>
+<P>A pointer to the default language structure.</P>
+<H3><A NAME="10_20_3">Description</A></H3>
+<P><CODE>cupsLangDefault()</CODE> returns a language structure for the
+ default language. The default language is defined by the <CODE>LANG</CODE>
+ environment variable. If the specified language cannot be located then
+ the POSIX (English) locale is used.</P>
+<P>Call <CODE>cupsLangFree()</CODE> to free any memory associated with
+ the language structure when you are done.</P>
+<H3><A NAME="10_20_4">Example</A></H3>
+<PRE>
+#include &lt;cups/language.h&gt;
+
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+...
+
+language = cupsLangDefault();
+
+...
+
+cupsLangFree(language);
+</PRE>
+<H3><A NAME="10_20_5">See Also</A></H3>
+<P><A HREF="#cupsLangEncoding"> <CODE>cupsLangEncoding()</CODE></A>,<A HREF="#cupsLangFlush">
+ <CODE>cupsLangFlush()</CODE></A>,<A HREF="#cupsLangFree"> <CODE>
+cupsLangFree()</CODE></A>,<A HREF="#cupsLangGet"> <CODE>cupsLangGet()</CODE>
+</A>,<A HREF="#cupsLangString"> <CODE>cupsLangString()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsLangEncoding">cupsLangEncoding()</A></H2>
+<H3><A NAME="10_21_1">Usage</A></H3>
+<PRE>
+char *
+cupsLangEncoding(cups_lang_t *language);
+</PRE>
+<H3><A NAME="10_21_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>language</TD><TD>The language structure.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_21_3">Returns</A></H3>
+<P>A pointer to the encoding string.</P>
+<H3><A NAME="10_21_4">Description</A></H3>
+<P><CODE>cupsLangEncoding()</CODE> returns the language encoding used
+ for the specified language, e.g. &quot;iso-8859-1&quot;, &quot;utf-8&quot;, etc.</P>
+<H3><A NAME="10_21_5">Example</A></H3>
+<PRE>
+#include &lt;cups/language.h&gt;
+
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+char *encoding;
+...
+
+language = cupsLangDefault();
+encoding = cupsLangEncoding(language);
+...
+
+cupsLangFree(language);
+</PRE>
+<H3><A NAME="10_21_6">See Also</A></H3>
+<P><A HREF="#cupsLangDefault"> <CODE>cupsLangDefault()</CODE></A>,<A HREF="#cupsLangFlush">
+ <CODE>cupsLangFlush()</CODE></A>,<A HREF="#cupsLangFree"> <CODE>
+cupsLangFree()</CODE></A>,<A HREF="#cupsLangGet"> <CODE>cupsLangGet()</CODE>
+</A>,<A HREF="#cupsLangString"> <CODE>cupsLangString()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsLangFlush">cupsLangFlush()</A></H2>
+<H3><A NAME="10_22_1">Usage</A></H3>
+<PRE>
+void
+cupsLangFlush(void);
+</PRE>
+<H3><A NAME="10_22_2">Description</A></H3>
+<P><CODE>cupsLangFlush()</CODE> frees all language structures that have
+ been allocated.</P>
+<H3><A NAME="10_22_3">Example</A></H3>
+<PRE>
+#include &lt;cups/language.h&gt;
+
+...
+
+cupsLangFlush();
+</PRE>
+<H3><A NAME="10_22_4">See Also</A></H3>
+<P><A HREF="#cupsLangDefault"> <CODE>cupsLangDefault()</CODE></A>,<A HREF="#cupsLangEncoding">
+ <CODE>cupsLangEncoding()</CODE></A>,<A HREF="#cupsLangFree"> <CODE>
+cupsLangFree()</CODE></A>,<A HREF="#cupsLangGet"> <CODE>cupsLangGet()</CODE>
+</A>,<A HREF="#cupsLangString"> <CODE>cupsLangString()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsLangFree">cupsLangFree()</A></H2>
+<H3><A NAME="10_23_1">Usage</A></H3>
+<PRE>
+void
+cupsLangFree(cups_lang_t *language);
+</PRE>
+<H3><A NAME="10_23_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>language</TD><TD>The language structure to free.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_23_3">Description</A></H3>
+<P><CODE>cupsLangFree()</CODE> frees the specified language structure.</P>
+<H3><A NAME="10_23_4">Example</A></H3>
+<PRE>
+#include &lt;cups/language.h&gt;
+
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+...
+
+cupsLangFree(language);
+</PRE>
+<H3><A NAME="10_23_5">See Also</A></H3>
+<P><A HREF="#cupsLangDefault"> <CODE>cupsLangDefault()</CODE></A>,<A HREF="#cupsLangEncoding">
+ <CODE>cupsLangEncoding()</CODE></A>,<A HREF="#cupsLangFlush"> <CODE>
+cupsLangFlush()</CODE></A>,<A HREF="#cupsLangGet"> <CODE>cupsLangGet()</CODE>
+</A>,<A HREF="#cupsLangString"> <CODE>cupsLangString()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsLangGet">cupsLangGet()</A></H2>
+<H3><A NAME="10_24_1">Usage</A></H3>
+<PRE>
+cups_lang_t *
+cupsLangGet(const char *name);
+</PRE>
+<H3><A NAME="10_24_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>name</TD><TD>The name of the locale.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_24_3">Returns</A></H3>
+<P>A pointer to a language structure.</P>
+<H3><A NAME="10_24_4">Description</A></H3>
+<P><CODE>cupsLangGet()</CODE> returns a language structure for the
+ specified locale. If the locale is not defined then the POSIX (English)
+ locale is substituted.</P>
+<H3><A NAME="10_24_5">Example</A></H3>
+<PRE>
+#include &lt;cups/language.h&gt;
+
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+
+...
+
+language = cupsLangGet(&quot;fr&quot;);
+
+...
+
+cupsLangFree(language);
+</PRE>
+<H3><A NAME="10_24_6">See Also</A></H3>
+<P><A HREF="#cupsLangDefault"> <CODE>cupsLangDefault()</CODE></A>,<A HREF="#cupsLangEncoding">
+ <CODE>cupsLangEncoding()</CODE></A>,<A HREF="#cupsLangFlush"> <CODE>
+cupsLangFlush()</CODE></A>,<A HREF="#cupsLangFree"> <CODE>cupsLangFree()</CODE>
+</A>,<A HREF="#cupsLangString"> <CODE>cupsLangString()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsLangString">cupsLangString()</A></H2>
+<H3><A NAME="10_25_1">Usage</A></H3>
+<PRE>
+char *
+cupsLangString(cups_lang_t *language,
+ int message);
+</PRE>
+<H3><A NAME="10_25_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>language</TD><TD>The language to query.</TD></TR>
+<TR><TD>message</TD><TD>The message number.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_25_3">Returns</A></H3>
+<P>A pointer to the message string or <CODE>NULL</CODE> if the message
+ is not defined.</P>
+<H3><A NAME="10_25_4">Description</A></H3>
+<P><CODE>cupsLangString()</CODE> returns a pointer to the specified
+ message string in the specified language.</P>
+<H3><A NAME="10_25_5">Example</A></H3>
+<PRE>
+#include &lt;cups/language.h&gt;
+
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+char *s;
+...
+
+language = cupsLangGet(&quot;fr&quot;);
+
+s = cupsLangString(language, CUPS_MSG_YES);
+
+...
+
+cupsLangFree(language);
+</PRE>
+<H3><A NAME="10_25_6">See Also</A></H3>
+<P><A HREF="#cupsLangDefault"> <CODE>cupsLangDefault()</CODE></A>,<A HREF="#cupsLangEncoding">
+ <CODE>cupsLangEncoding()</CODE></A>,<A HREF="#cupsLangFlush"> <CODE>
+cupsLangFlush()</CODE></A>,<A HREF="#cupsLangFree"> <CODE>cupsLangFree()</CODE>
+</A>,<A HREF="#cupsLangGet"> <CODE>cupsLangGet()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsLastError">cupsLastError()</A></H2>
+<H3><A NAME="10_26_1">Usage</A></H3>
+<PRE>
+ipp_status_t
+cupsLastError(void);
+</PRE>
+<H3><A NAME="10_26_2">Returns</A></H3>
+<P>An enumeration containing the last IPP error.</P>
+<H3><A NAME="10_26_3">Description</A></H3>
+<P><CODE>cupsLastError()</CODE> returns the last IPP error that
+ occurred. If no error occurred then it will return <CODE>IPP_OK</CODE>
+ or <CODE>IPP_OK_CONFLICT</CODE>.</P>
+<H3><A NAME="10_26_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+ipp_status_t status;
+
+...
+
+status = cupsLastError();
+</PRE>
+<H3><A NAME="10_26_5">See Also</A></H3>
+<P><A HREF="#cupsCancelJob"> <CODE>cupsCancelJob()</CODE></A>,<A HREF="#cupsPrintFile">
+ <CODE>cupsPrintFile()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsMarkOptions">cupsMarkOptions()</A></H2>
+<H3><A NAME="10_27_1">Usage</A></H3>
+<PRE>
+int
+cupsMarkOptions(ppd_file_t *ppd,
+ int num_options,
+ cups_option_t *options);
+</PRE>
+<H3><A NAME="10_27_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file to mark.</TD></TR>
+<TR><TD>num_options</TD><TD>The number of options in the options array.</TD>
+</TR>
+<TR><TD>options</TD><TD>A pointer to the options array.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_27_3">Returns</A></H3>
+<P>The number of conflicts found.</P>
+<H3><A NAME="10_27_4">Description</A></H3>
+<P><CODE>cupsMarkOptions()</CODE> marks options in the PPD file. It also
+ handles mapping of IPP option names and values to PPD option names.</P>
+<H3><A NAME="10_27_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+<A HREF="#ppd_file_t">ppd_file_t</A> *ppd;
+
+...
+
+cupsMarkOptions(ppd, num_options, options);
+</PRE>
+<H3><A NAME="10_27_6">See Also</A></H3>
+<P><A HREF="#cupsAddOption"> <CODE>cupsAddOption()</CODE></A>,<A HREF="#cupsFreeOptions">
+ <CODE>cupsFreeOptions()</CODE></A>,<A HREF="#cupsGetOption"> <CODE>
+cupsGetOption()</CODE></A>,<A HREF="#cupsParseOptions"> <CODE>
+cupsParseOptions()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsParseOptions">cupsParseOptions()</A></H2>
+<H3><A NAME="10_28_1">Usage</A></H3>
+<PRE>
+int
+cupsParseOptions(const char *arg,
+ int num_options,
+ cups_option_t **options);
+</PRE>
+<H3><A NAME="10_28_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>arg</TD><TD>The string containing one or more options.</TD></TR>
+<TR><TD>num_options</TD><TD>The number of options in the options array.</TD>
+</TR>
+<TR><TD>options</TD><TD>A pointer to the options array pointer.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_28_3">Returns</A></H3>
+<P>The new number of options in the array.</P>
+<H3><A NAME="10_28_4">Description</A></H3>
+<P><CODE>cupsParseOptions()</CODE> parses the specifies string for one
+ or more options of the form &quot;name=value&quot;, &quot;name&quot;, or &quot;noname&quot;. It can
+ be called multiple times to combine the options from several strings.</P>
+<H3><A NAME="10_28_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_options;
+<A HREF="#cups_options_t">cups_option_t</A> *options;
+
+...
+
+num_options = 0;
+options = (cups_option_t *)0;
+num_options = cupsParseOptions(argv[5], num_options, &amp;options);
+</PRE>
+<H3><A NAME="10_28_6">See Also</A></H3>
+<P><A HREF="#cupsAddOption"> <CODE>cupsAddOption()</CODE></A>,<A HREF="#cupsFreeOptions">
+ <CODE>cupsFreeOptions()</CODE></A>,<A HREF="#cupsGetOption"> <CODE>
+cupsGetOption()</CODE></A>,<A HREF="#cupsMarkOptions"> <CODE>
+cupsMarkOptions()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsPrintFile">cupsPrintFile()</A></H2>
+<H3><A NAME="10_29_1">Usage</A></H3>
+<PRE>
+int
+cupsPrintFile(const char *printer,
+ const char *filename,
+ const char *title,
+ int num_options,
+ cups_option_t *options);
+</PRE>
+<H3><A NAME="10_29_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>printer</TD><TD>The printer or class to print to.</TD></TR>
+<TR><TD>filename</TD><TD>The file to print.</TD></TR>
+<TR><TD>title</TD><TD>The job title.</TD></TR>
+<TR><TD>num_options</TD><TD>The number of options in the options array.</TD>
+</TR>
+<TR><TD>options</TD><TD>A pointer to the options array.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_29_3">Returns</A></H3>
+<P>The new job ID number or 0 on error.</P>
+<H3><A NAME="10_29_4">Description</A></H3>
+<P><CODE>cupsPrintFile()</CODE> sends a file to the specified printer or
+ class for printing. If the job cannot be printed the error code can be
+ found by calling <CODE>cupsLastError()</CODE>.</P>
+<H3><A NAME="10_29_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+int jobid;
+
+...
+
+jobid = cupsPrintFile(&quot;printer@hostname&quot;, &quot;filename.ps&quot;, &quot;Job Title&quot;,
+ num_options, options);
+</PRE>
+<H3><A NAME="10_29_6">See Also</A></H3>
+<P><A HREF="#cupsCancelJob"> <CODE>cupsCancelJob()</CODE></A>,<A HREF="#cupsLastError">
+ <CODE>cupsLastError()</CODE></A>,<A HREF="#cupsPrintFiles"> <CODE>
+cupsPrintFiles()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsPrintFiles">cupsPrintFiles()</A></H2>
+<H3><A NAME="10_30_1">Usage</A></H3>
+<PRE>
+int
+cupsPrintFiles(const char *printer,
+ int num_files,
+ const char **files,
+ const char *title,
+ int num_options,
+ cups_option_t *options);
+</PRE>
+<H3><A NAME="10_30_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>printer</TD><TD>The printer or class to print to.</TD></TR>
+<TR><TD>num_files</TD><TD>The number of files to print.</TD></TR>
+<TR><TD>files</TD><TD>The files to print.</TD></TR>
+<TR><TD>title</TD><TD>The job title.</TD></TR>
+<TR><TD>num_options</TD><TD>The number of options in the options array.</TD>
+</TR>
+<TR><TD>options</TD><TD>A pointer to the options array.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_30_3">Returns</A></H3>
+<P>The new job ID number or 0 on error.</P>
+<H3><A NAME="10_30_4">Description</A></H3>
+<P><CODE>cupsPrintFiles()</CODE> sends multiple files to the specified
+ printer or class for printing. If the job cannot be printed the error
+ code can be found by calling <CODE>cupsLastError()</CODE>.</P>
+<H3><A NAME="10_30_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_files;
+const char *files[100];
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+int jobid;
+
+...
+
+jobid = cupsPrintFiles(&quot;printer@hostname&quot;, num_files, files,
+ &quot;Job Title&quot;, num_options, options);
+</PRE>
+<H3><A NAME="10_30_6">See Also</A></H3>
+<P><A HREF="#cupsCancelJob"> <CODE>cupsCancelJob()</CODE></A>,<A HREF="#cupsLastError">
+ <CODE>cupsLastError()</CODE></A>,<A HREF="#cupsPrintFile"> <CODE>
+cupsPrintFile()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsRasterClose">cupsRasterClose()</A></H2>
+<H3><A NAME="10_31_1">Usage</A></H3>
+<PRE>
+void
+cupsRasterClose(cups_raster_t *ras);
+</PRE>
+<H3><A NAME="10_31_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ras</TD><TD>The raster stream to close.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_31_3">Description</A></H3>
+<P><CODE>cupsRasterClose()</CODE> closes the specified raster stream.</P>
+<H3><A NAME="10_31_4">Example</A></H3>
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+
+...
+
+cupsRasterClose(ras);
+</PRE>
+<H3><A NAME="10_31_5">See Also</A></H3>
+<P><A HREF="#cupsRasterOpen"> <CODE>cupsRasterOpen()</CODE></A>,<A HREF="#cupsRasterReadHeader">
+ <CODE>cupsRasterReadHeader()</CODE></A>,<A HREF="#cupsRasterReadPixels">
+ <CODE>cupsRasterReadPixels()</CODE></A>,<A HREF="#cupsRasterWriteHeader">
+ <CODE>cupsRasterWriteHeader()</CODE></A>,<A HREF="#cupsRasterWritePixels">
+ <CODE>cupsRasterWritePixels()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsRasterOpen">cupsRasterOpen()</A></H2>
+<H3><A NAME="10_32_1">Usage</A></H3>
+<PRE>
+cups_raster_t *
+cupsRasterOpen(int fd,
+ cups_mode_t mode);
+</PRE>
+<H3><A NAME="10_32_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>fd</TD><TD>The file descriptor to use.</TD></TR>
+<TR><TD>mode</TD><TD>The mode to use; <CODE>CUPS_RASTER_READ</CODE> or <CODE>
+CUPS_RASTER_WRITE</CODE>.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_32_3">Returns</A></H3>
+<P>A pointer to a raster stream or <CODE>NULL</CODE> if there was an
+ error.</P>
+<H3><A NAME="10_32_4">Description</A></H3>
+<P><CODE>cupsRasterOpen()</CODE> opens a raster stream for reading or
+ writing.</P>
+<H3><A NAME="10_32_5">Example</A></H3>
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+
+...
+
+ras = cupsRasterOpen(0, CUPS_RASTER_READ);
+</PRE>
+<H3><A NAME="10_32_6">See Also</A></H3>
+<P><A HREF="#cupsRasterClose"> <CODE>cupsRasterClose()</CODE></A>,<A HREF="#cupsRasterReadHeader">
+ <CODE>cupsRasterReadHeader()</CODE></A>,<A HREF="#cupsRasterReadPixels">
+ <CODE>cupsRasterReadPixels()</CODE></A>,<A HREF="#cupsRasterWriteHeader">
+ <CODE>cupsRasterWriteHeader()</CODE></A>,<A HREF="#cupsRasterWritePixels">
+ <CODE>cupsRasterWritePixels()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsRasterReadHeader">cupsRasterReadHeader()</A></H2>
+<H3><A NAME="10_33_1">Usage</A></H3>
+<PRE>
+unsigned
+cupsRasterReadHeader(cups_raster_t *ras,
+ cups_page_header_t *header);
+</PRE>
+<H3><A NAME="10_33_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ras</TD><TD>The raster stream to read from.</TD></TR>
+<TR><TD>header</TD><TD>A pointer to a page header structure to read
+ into.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_33_3">Returns</A></H3>
+<P>1 on success, 0 on EOF or error.</P>
+<H3><A NAME="10_33_4">Description</A></H3>
+<P><CODE>cupsRasterReadHeader()</CODE> reads a page header from the
+ specified raster stream.</P>
+<H3><A NAME="10_33_5">Example</A></H3>
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+int line;
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
+unsigned char pixels[8192];
+...
+
+while (cupsRasterReadHeader(ras, &amp;header))
+{
+ ...
+
+ for (line = 0; line &lt; header.cupsHeight; line ++)
+ {
+ cupsRasterReadPixels(ras, pixels, header.cupsBytesPerLine);
+
+ ...
+ }
+}
+</PRE>
+<H3><A NAME="10_33_6">See Also</A></H3>
+<P><A HREF="#cupsRasterClose"> <CODE>cupsRasterClose()</CODE></A>,<A HREF="#cupsRasterOpen">
+ <CODE>cupsRasterOpen()</CODE></A>,<A HREF="#cupsRasterReadPixels"> <CODE>
+cupsRasterReadPixels()</CODE></A>,<A HREF="#cupsRasterWriteHeader"> <CODE>
+cupsRasterWriteHeader()</CODE></A>,<A HREF="#cupsRasterWritePixels"> <CODE>
+cupsRasterWritePixels()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsRasterReadPixels">cupsRasterReadPixels()</A></H2>
+<H3><A NAME="10_34_1">Usage</A></H3>
+<PRE>
+unsigned
+cupsRasterReadPixels(cups_raster_t *ras,
+ unsigned char *pixels,
+ unsigned length);
+</PRE>
+<H3><A NAME="10_34_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ras</TD><TD>The raster stream to read from.</TD></TR>
+<TR><TD>pixels</TD><TD>The pointer to a pixel buffer.</TD></TR>
+<TR><TD>length</TD><TD>The number of bytes of pixel data to read.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_34_3">Returns</A></H3>
+<P>The number of bytes read or 0 on EOF or error.</P>
+<H3><A NAME="10_34_4">Description</A></H3>
+<P><CODE>cupsRasterReadPixels()</CODE> reads pixel data from the
+ specified raster stream.</P>
+<H3><A NAME="10_34_5">Example</A></H3>
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+int line;
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
+unsigned char pixels[8192];
+...
+
+while (cupsRasterReadHeader(ras, &amp;header))
+{
+ ...
+
+ for (line = 0; line &lt; header.cupsHeight; line ++)
+ {
+ cupsRasterReadPixels(ras, pixels, header.cupsBytesPerLine);
+
+ ...
+ }
+}
+</PRE>
+<H3><A NAME="10_34_6">See Also</A></H3>
+<P><A HREF="#cupsRasterClose"> <CODE>cupsRasterClose()</CODE></A>,<A HREF="#cupsRasterOpen">
+ <CODE>cupsRasterOpen()</CODE></A>,<A HREF="#cupsRasterReadHeader"> <CODE>
+cupsRasterReadHeader()</CODE></A>,<A HREF="#cupsRasterWriteHeader"> <CODE>
+cupsRasterWriteHeader()</CODE></A>,<A HREF="#cupsRasterWritePixels"> <CODE>
+cupsRasterWritePixels()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsRasterWriteHeader">cupsRasterWriteHeader()</A></H2>
+<H3><A NAME="10_35_1">Usage</A></H3>
+<PRE>
+unsigned
+cupsRasterWriteHeader(cups_raster_t *ras,
+ cups_page_header_t *header);
+</PRE>
+<H3><A NAME="10_35_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ras</TD><TD>The raster stream to write to.</TD></TR>
+<TR><TD>header</TD><TD>A pointer to the page header to write.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_35_3">Returns</A></H3>
+<P>1 on success, 0 on error.</P>
+<H3><A NAME="10_35_4">Description</A></H3>
+<P><CODE>cupsRasterWriteHeader()</CODE> writes the specified page header
+ to a raster stream.</P>
+<H3><A NAME="10_35_5">Example</A></H3>
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+int line;
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
+unsigned char pixels[8192];
+...
+
+cupsRasterWriteHeader(ras, &amp;header);
+
+for (line = 0; line &lt; header.cupsHeight; line ++)
+{
+ ...
+
+ cupsRasterWritePixels(ras, pixels, header.cupsBytesPerLine);
+}
+</PRE>
+<H3><A NAME="10_35_6">See Also</A></H3>
+<P><A HREF="#cupsRasterClose"> <CODE>cupsRasterClose()</CODE></A>,<A HREF="#cupsRasterOpen">
+ <CODE>cupsRasterOpen()</CODE></A>,<A HREF="#cupsRasterReadHeader"> <CODE>
+cupsRasterReadHeader()</CODE></A>,<A HREF="#cupsRasterReadPixels"> <CODE>
+cupsRasterReadPixels()</CODE></A>,<A HREF="#cupsRasterWritePixels"> <CODE>
+cupsRasterWritePixels()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsRasterWritePixels">cupsRasterWritePixels()</A></H2>
+<H3><A NAME="10_36_1">Usage</A></H3>
+<PRE>
+unsigned
+cupsRasterWritePixels(cups_raster_t *ras,
+ unsigned char *pixels,
+ unsigned length);
+</PRE>
+<H3><A NAME="10_36_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ras</TD><TD>The raster stream to write to.</TD></TR>
+<TR><TD>pixels</TD><TD>The pixel data to write.</TD></TR>
+<TR><TD>length</TD><TD>The number of bytes to write.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_36_3">Returns</A></H3>
+<P>The number of bytes written.</P>
+<H3><A NAME="10_36_4">Description</A></H3>
+<P><CODE>cupsRasterWritePixels()</CODE> writes the specified pixel data
+ to a raster stream.</P>
+<H3><A NAME="10_36_5">Example</A></H3>
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+int line;
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
+unsigned char pixels[8192];
+...
+
+cupsRasterWriteHeader(ras, &amp;header);
+
+for (line = 0; line &lt; header.cupsHeight; line ++)
+{
+ ...
+
+ cupsRasterWritePixels(ras, pixels, header.cupsBytesPerLine);
+}
+</PRE>
+<H3><A NAME="10_36_6">See Also</A></H3>
+<P><A HREF="#cupsRasterClose"> <CODE>cupsRasterClose()</CODE></A>,<A HREF="#cupsRasterOpen">
+ <CODE>cupsRasterOpen()</CODE></A>,<A HREF="#cupsRasterReadHeader"> <CODE>
+cupsRasterReadHeader()</CODE></A>,<A HREF="#cupsRasterReadPixels"> <CODE>
+cupsRasterReadPixels()</CODE></A>,<A HREF="#cupsRasterWriteHeader"> <CODE>
+cupsRasterWriteHeader()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsServer">cupsServer()</A></H2>
+<H3><A NAME="10_37_1">Usage</A></H3>
+<PRE>
+const char *
+cupsServer(void);
+</PRE>
+<H3><A NAME="10_37_2">Returns</A></H3>
+<P>A pointer to the default server name.</P>
+<H3><A NAME="10_37_3">Description</A></H3>
+<P><CODE>cupsServer()</CODE> returns a pointer to the default server
+ name. The server name is stored in a static location and will be
+ overwritten with every call to <CODE>cupsServer()</CODE>.</P>
+<P>The default server is determined from the following locations:</P>
+<OL>
+<LI>The <CODE>CUPS_SERVER</CODE> environment variable,</LI>
+<LI>The <CODE>ServerName</CODE> directive in the<VAR> client.conf</VAR>
+ file,</LI>
+<LI>The default host, &quot;localhost&quot;.</LI>
+</OL>
+<H3><A NAME="10_37_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+const char *server;
+
+server = cupsServer();
+</PRE>
+<H3><A NAME="10_37_5">See Also</A></H3>
+<P><A HREF="#cupsGetPassword"> <CODE>cupsGetPassword()</CODE></A>,<A HREF="#cupsSetPasswordCB">
+ <CODE>cupsSetPasswordCB()</CODE></A>,<A HREF="#cupsSetServer"> <CODE>
+cupsSetServer()</CODE></A>,<A HREF="#cupsSetUser"> <CODE>cupsSetUser()</CODE>
+</A>,<A HREF="#cupsUser"> <CODE>cupsUser()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsSetDests">cupsSetDests()</A></H2>
+<H3><A NAME="10_38_1">Usage</A></H3>
+<PRE>
+void
+cupsSetDests(int num_dests,
+ cups_dest_t *dests);
+</PRE>
+<H3><A NAME="10_38_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>num_dests</TD><TD>Number of destinations.</TD></TR>
+<TR><TD>dests</TD><TD>Array of destinations.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_38_3">Description</A></H3>
+<P><CODE>cupsSetDests()</CODE> saves the destination array to disk. If
+ the current UID is 0, the destinations are saved in the<VAR>
+ /etc/cups/lpoptions</VAR> file, otherwise they are saved in the<VAR>
+ ~/.lpoptions</VAR> file. This function is typically used to save the
+ default options and instances that are set by the user.</P>
+<H3><A NAME="10_38_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_dests;
+<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
+
+...
+
+cupsSetDests(num_dests, dests);
+</PRE>
+<H3><A NAME="10_38_5">See Also</A></H3>
+<P><A HREF="#cupsGetDests"> <CODE>cupsGetDests()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsSetEncryption">cupsSetEncryption()</A></H2>
+<H3><A NAME="10_39_1">Usage</A></H3>
+<PRE>
+void
+cupsSetEncryption(http_encryption_t encryption);
+</PRE>
+<H3><A NAME="10_39_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>encryption</TD><TD>The type of encryption to use.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_39_3">Description</A></H3>
+<P><CODE>cupsSetEncryption()</CODE> sets the default type of encryption
+ to use when connecting with the print server.</P>
+<H3><A NAME="10_39_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+</PRE>
+<H3><A NAME="10_39_5">See Also</A></H3>
+<P><A HREF="#cupsEncryption"> <CODE>cupsEncryption()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsSetPasswordCB">cupsSetPasswordCB()</A></H2>
+<H3><A NAME="10_40_1">Usage</A></H3>
+<PRE>
+void
+cupsSetPasswordCB(const char *(*cb)(const char *prompt));
+</PRE>
+<H3><A NAME="10_40_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>cb</TD><TD>The password callback function.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_40_3">Description</A></H3>
+<P><CODE>cupsSetPasswordCB()</CODE> sets the callback function to use
+ when asking the user for a password. The callback function must accept
+ a single character string pointer (the prompt string) and return <CODE>
+NULL</CODE> if the user did not enter a password string or a pointer to
+ the password string otherwise.</P>
+<H3><A NAME="10_40_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+const char *
+my_password_cb(const char *prompt)
+{
+ return (getpass(prompt));
+}
+
+...
+
+char *password;
+
+...
+
+cupsSetPasswordCB(my_password_cb);
+password = cupsGetPassword(&quot;Please enter a password:&quot;);
+</PRE>
+<H3><A NAME="10_40_5">See Also</A></H3>
+<P><A HREF="#cupsServer"> <CODE>cupsServer()</CODE></A>,<A HREF="#cupsSetServer">
+ <CODE>cupsSetServer()</CODE></A>,<A HREF="#cupsSetUser"> <CODE>
+cupsSetUser()</CODE></A>,<A HREF="#cupsUser"> <CODE>cupsUser()</CODE></A>
+<!-- NEW PAGE -->
+
+</P>
+<H2><A NAME="cupsSetServer">cupsSetServer()</A></H2>
+<H3><A NAME="10_41_1">Usage</A></H3>
+<PRE>
+void
+cupsSetServer(const char *server);
+</PRE>
+<H3><A NAME="10_41_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>server</TD><TD>The default server to use.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_41_3">Description</A></H3>
+<P><CODE>cupsSetServer()</CODE> sets the default server to use for the
+ CUPS API. If the <CODE>server</CODE> argument is <CODE>NULL</CODE>, the
+ default server is used.</P>
+<H3><A NAME="10_41_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+cupsSetServer(&quot;foo.bar.com&quot;);
+</PRE>
+<H3><A NAME="10_41_5">See Also</A></H3>
+<P><A HREF="#cupsServer"> <CODE>cupsServer()</CODE></A>,<A HREF="#cupsSetPasswordCB">
+ <CODE>cupsSetPasswordCB()</CODE></A>,<A HREF="#cupsSetUser"> <CODE>
+cupsSetUser()</CODE></A>,<A HREF="#cupsUser"> <CODE>cupsUser()</CODE></A>
+<!-- NEW PAGE -->
+
+</P>
+<H2><A NAME="cupsSetUser">cupsSetUser()</A></H2>
+<H3><A NAME="10_42_1">Usage</A></H3>
+<PRE>
+void
+cupsSetUser(const char *user);
+</PRE>
+<H3><A NAME="10_42_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>user</TD><TD>The user name string to use.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_42_3">Description</A></H3>
+<P><CODE>cupsSetUser()</CODE> sets the default user name for
+ authentication. If the <CODE>user</CODE> argument is <CODE>NULL</CODE>
+ then the current login user is used.</P>
+<H3><A NAME="10_42_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+cupsSetUser(&quot;root&quot;);
+</PRE>
+<H3><A NAME="10_42_5">See Also</A></H3>
+<P><A HREF="#cupsServer"> <CODE>cupsServer()</CODE></A>,<A HREF="#cupsSetPasswordCB">
+ <CODE>cupsSetPasswordCB()</CODE></A>,<A HREF="#cupsSetServer"> <CODE>
+cupsSetServer()</CODE></A>,<A HREF="#cupsUser"> <CODE>cupsUser()</CODE></A>
+<!-- NEW PAGE -->
+
+</P>
+<H2><A NAME="cupsTempFd">cupsTempFd()</A></H2>
+<H3><A NAME="10_43_1">Usage</A></H3>
+<PRE>
+int
+cupsTempFd(char *filename,
+ int length);
+</PRE>
+<H3><A NAME="10_43_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>filename</TD><TD>The character string to hold the temporary
+ filename.</TD></TR>
+<TR><TD>length</TD><TD>The size of the filename string in bytes.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_43_3">Returns</A></H3>
+<P>A file descriptor open for reading and writing.</P>
+<H3><A NAME="10_43_4">Description</A></H3>
+<P><CODE>cupsTempFd()</CODE> create a temporary filename in the<VAR>
+ /var/tmp</VAR> directory or the directory specified by the <CODE>TMPDIR</CODE>
+ environment variable.</P>
+<H3><A NAME="10_43_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int fd;
+char filename[256];
+
+fd = cupsTempFd(filename, sizeof(filename));
+</PRE>
+<H3><A NAME="10_43_6">See Also</A></H3>
+<P><A HREF="#cupsTempFile"> <CODE>cupsTempFile()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsTempFile">cupsTempFile()</A></H2>
+<H3><A NAME="10_44_1">Usage</A></H3>
+<PRE>
+char *
+cupsTempFile(char *filename,
+ int length);
+</PRE>
+<H3><A NAME="10_44_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>filename</TD><TD>The character string to hold the temporary
+ filename.</TD></TR>
+<TR><TD>length</TD><TD>The size of the filename string in bytes.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_44_3">Returns</A></H3>
+<P>A pointer to <CODE>filename</CODE>.</P>
+<H3><A NAME="10_44_4">Description</A></H3>
+<P><CODE>cupsTempFile()</CODE> creates a temporary filename in the<VAR>
+ /var/tmp</VAR> directory or the directory specified by the <CODE>TMPDIR</CODE>
+ environment variable.</P>
+<H3><A NAME="10_44_5">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+char filename[256];
+
+cupsTempFile(filename, sizeof(filename));
+</PRE>
+<H3><A NAME="10_44_6">See Also</A></H3>
+<P><A HREF="#cupsTempFd"> <CODE>cupsTempFd()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="cupsUser">cupsUser()</A></H2>
+<H3><A NAME="10_45_1">Usage</A></H3>
+<PRE>
+const char *
+cupsUser(void);
+</PRE>
+<H3><A NAME="10_45_2">Returns</A></H3>
+<P>A pointer to the current username or <CODE>NULL</CODE> if the user ID
+ is undefined.</P>
+<H3><A NAME="10_45_3">Description</A></H3>
+<P><CODE>cupsUser()</CODE> returns the name associated with the current
+ user ID as reported by the <CODE>getuid()</CODE> system call.</P>
+<H3><A NAME="10_45_4">Example</A></H3>
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+const char *user;
+
+user = cupsUser();
+</PRE>
+<H3><A NAME="10_45_5">See Also</A></H3>
+<P><A HREF="#cupsGetPassword"> <CODE>cupsGetPassword()</CODE></A>,<A HREF="#cupsServer">
+ <CODE>cupsServer()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="httpBlocking">httpBlocking()</A></H2>
+<H3><A NAME="10_46_1">Usage</A></H3>
+<PRE>
+void
+httpBlocking(http_t *http,
+ int blocking)
+</PRE>
+<H3><A NAME="10_46_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>blocking</TD><TD>0 if the connection should be non-blocking, 1
+ if it should be blocking</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_46_3">Description</A></H3>
+<P>The <CODE>httpBlocking()</CODE> function sets the blocking mode for
+ the HTTP connection. By default HTTP connections will block (stop) the
+ client program until data is available or can be sent to the server.</P>
+<H3><A NAME="10_46_4">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+http = httpConnect(&quot;server&quot;, port);
+httpBlocking(http, 0);
+</PRE>
+<H3><A NAME="10_46_5">See Also</A></H3>
+<A HREF="#httpCheck"> <CODE>httpCheck()</CODE></A>,<A HREF="#httpConnect">
+ <CODE>httpConnect()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpCheck">httpCheck()</A></H2>
+<H3><A NAME="10_47_1">Usage</A></H3>
+<PRE>
+int
+httpCheck(http_t *http);
+</PRE>
+<H3><A NAME="10_47_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_47_3">Returns</A></H3>
+<P>0 if there is no data pending, 1 otherwise.</P>
+<H3><A NAME="10_47_4">Description</A></H3>
+<P>The <CODE>httpCheck()</CODE> function checks to see if there is any
+ data pending on an HTTP connection.</P>
+<H3><A NAME="10_47_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+if (httpCheck(http))
+{
+ ... do something ...
+}
+</PRE>
+<H3><A NAME="10_47_6">See Also</A></H3>
+<A HREF="#httpBlocking"> <CODE>httpBlocking()</CODE></A>,<A HREF="#httpConnect">
+ <CODE>httpConnect()</CODE></A>,<A HREF="#httpGets"> <CODE>httpGets()</CODE>
+</A>,<A HREF="#httpRead"> <CODE>httpRead()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpClearFields">httpClearFields()</A></H2>
+<H3><A NAME="10_48_1">Usage</A></H3>
+<PRE>
+void
+httpClearFields(http_t *http)
+</PRE>
+<H3><A NAME="10_48_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_48_3">Description</A></H3>
+<P>The <CODE>httpClearFields()</CODE> function clears all HTTP request
+ fields for the HTTP connection.</P>
+<H3><A NAME="10_48_4">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpClearFields(http);
+</PRE>
+<H3><A NAME="10_48_5">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpGetField">
+ <CODE>httpGetField()</CODE></A>,<A HREF="#httpSetField"> <CODE>
+httpSetField()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpClose">httpClose()</A></H2>
+<H3><A NAME="10_49_1">Usage</A></H3>
+<PRE>
+void
+httpClose(http_t *http);
+</PRE>
+<H3><A NAME="10_49_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_49_3">Description</A></H3>
+<P>The <CODE>httpClose()</CODE> function closes an active HTTP
+ connection.</P>
+<H3><A NAME="10_49_4">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpClose(http);
+</PRE>
+<H3><A NAME="10_49_5">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpConnect">httpConnect()</A></H2>
+<H3><A NAME="10_50_1">Usage</A></H3>
+<PRE>
+http_t *
+httpConnect(const char *hostname,
+ int port);
+</PRE>
+<H3><A NAME="10_50_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>hostname</TD><TD>The name or IP address of the server to connect
+ to</TD></TR>
+<TR><TD>port</TD><TD>The port number to use</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_50_3">Returns</A></H3>
+<P>A pointer to a HTTP connection structure or NULL if the connection
+ could not be made.</P>
+<H3><A NAME="10_50_4">Description</A></H3>
+<P>The <CODE>httpConnect()</CODE> function opens a HTTP connection to
+ the specified server and port.</P>
+<H3><A NAME="10_50_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+http = httpConnect(cupsServer(), ippPort());
+</PRE>
+<H3><A NAME="10_50_6">See Also</A></H3>
+<A HREF="#httpClose"> <CODE>httpClose()</CODE></A>,<A HREF="#httpConnectEncrypt">
+ <CODE>httpConnectEncrypt()</CODE></A>,<A HREF="#httpGet"> <CODE>
+httpGet()</CODE></A>,<A HREF="#httpGets"> <CODE>httpGets()</CODE></A>,<A HREF="#httpPost">
+ <CODE>httpPost()</CODE></A>,<A HREF="#httpRead"> <CODE>httpRead()</CODE>
+</A>,<A HREF="#httpWrite"> <CODE>httpWrite()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpConnectEncrypt">httpConnectEncrypt()</A></H2>
+<H3><A NAME="10_51_1">Usage</A></H3>
+<PRE>
+http_t *
+httpConnectEncrypt(const char *hostname,
+ int port,
+ http_encryption_t encryption);
+</PRE>
+<H3><A NAME="10_51_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>hostname</TD><TD>The name or IP address of the server to connect
+ to</TD></TR>
+<TR><TD>port</TD><TD>The port number to use</TD></TR>
+<TR><TD>encryption</TD><TD>The level of encryption to use</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_51_3">Returns</A></H3>
+<P>A pointer to a HTTP connection structure or NULL if the connection
+ could not be made.</P>
+<H3><A NAME="10_51_4">Description</A></H3>
+<P>The <CODE>httpConnectEncrypt()</CODE> function opens a HTTP
+ connection to the specified server, port, and encryption.</P>
+<H3><A NAME="10_51_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
+</PRE>
+<H3><A NAME="10_51_6">See Also</A></H3>
+<A HREF="#httpClose"> <CODE>httpClose()</CODE></A>,<A HREF="#httpConnect">
+ <CODE>httpConnect()</CODE></A>,<A HREF="#httpGet"> <CODE>httpGet()</CODE>
+</A>,<A HREF="#httpGets"> <CODE>httpGets()</CODE></A>,<A HREF="#httpPost">
+ <CODE>httpPost()</CODE></A>,<A HREF="#httpRead"> <CODE>httpRead()</CODE>
+</A>,<A HREF="#httpWrite"> <CODE>httpWrite()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpDecode64">httpDecode64()</A></H2>
+<H3><A NAME="10_52_1">Usage</A></H3>
+<PRE>
+char *
+httpDecode64(char *out,
+ const char *in);
+</PRE>
+<H3><A NAME="10_52_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>out</TD><TD>The output string</TD></TR>
+<TR><TD>in</TD><TD>The input string</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_52_3">Returns</A></H3>
+<P>A pointer to the decoded string.</P>
+<H3><A NAME="10_52_4">Description</A></H3>
+<P>The <CODE>httpDecode64()</CODE> function decodes a base-64 encoded
+ string to the original string.</P>
+<H3><A NAME="10_52_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+char encoded_string[255];
+char original_string[255];
+
+httpDecode64(original_string, encoded_string);
+</PRE>
+<H3><A NAME="10_52_6">See Also</A></H3>
+<A HREF="#httpEncode64"> <CODE>httpEncode64()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpDelete">httpDelete()</A></H2>
+<H3><A NAME="10_53_1">Usage</A></H3>
+<PRE>
+int
+httpDelete(http_t *http,
+ const char *uri);
+</PRE>
+<H3><A NAME="10_53_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>uri</TD><TD>The URI to delete</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_53_3">Returns</A></H3>
+<P>0 on success, non-zero on failure.</P>
+<H3><A NAME="10_53_4">Description</A></H3>
+<P>The <CODE>httpDelete()</CODE> function sends a HTTP DELETE request to
+ the server.</P>
+<H3><A NAME="10_53_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpDelete(http, &quot;/some/uri&quot;);
+</PRE>
+<H3><A NAME="10_53_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpSetField">
+ <CODE>httpSetField()</CODE></A>,<A HREF="#httpUpdate"> <CODE>
+httpUpdate()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpEncode64">httpEncode64()</A></H2>
+<H3><A NAME="10_54_1">Usage</A></H3>
+<PRE>
+char *
+httpEncode64(char *out,
+ const char *in);
+</PRE>
+<H3><A NAME="10_54_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>out</TD><TD>The output string</TD></TR>
+<TR><TD>in</TD><TD>The input string</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_54_3">Returns</A></H3>
+<P>A pointer to the encoded string.</P>
+<H3><A NAME="10_54_4">Description</A></H3>
+<P>The <CODE>httpEncode64()</CODE> function decodes a base-64 encoded
+ string to the original string.</P>
+<H3><A NAME="10_54_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+char encoded_string[255];
+char original_string[255];
+
+httpEncode64(encoded_string, original_string);
+</PRE>
+<H3><A NAME="10_54_6">See Also</A></H3>
+<A HREF="#httpDecode64"> <CODE>httpDecode64()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpEncryption">httpEncryption()</A></H2>
+<H3><A NAME="10_55_1">Usage</A></H3>
+<PRE>
+int
+httpEncryption(http_t *http,
+ http_encryption_t encryption);
+</PRE>
+<H3><A NAME="10_55_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection.</TD></TR>
+<TR><TD>encryption</TD><TD>The desired level of encryption.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_55_3">Returns</A></H3>
+<P>0 on success, -1 on error.</P>
+<H3><A NAME="10_55_4">Description</A></H3>
+<P><CODE>httpEncryption()</CODE> sets the encryption level for the HTTP
+ connection.</P>
+<H3><A NAME="10_55_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+...
+
+httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+</PRE>
+<H3><A NAME="10_55_6">See Also</A></H3>
+<P><A HREF="#httpConnectEncrypt"> <CODE>httpConnectEncrypt()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="httpError">httpError()</A></H2>
+<H3><A NAME="10_56_1">Usage</A></H3>
+<PRE>
+int
+httpError(http_t *http);
+</PRE>
+<H3><A NAME="10_56_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_56_3">Returns</A></H3>
+<P>The last error that occurred or 0 if no error has occurred.</P>
+<H3><A NAME="10_56_4">Description</A></H3>
+<P>The <CODE>httpError()</CODE> function returns the last error that
+ occurred on the HTTP connection.</P>
+<H3><A NAME="10_56_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+if (httpError(http))
+{
+ ... show an error message ...
+}
+</PRE>
+<H3><A NAME="10_56_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpFlush">httpFlush()</A></H2>
+<H3><A NAME="10_57_1">Usage</A></H3>
+<PRE>
+void
+httpFlush(http_t *http);
+</PRE>
+<H3><A NAME="10_57_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_57_3">Description</A></H3>
+<P>The <CODE>httpFlush()</CODE> function flushes any remaining data left
+ from a GET or POST operation.</P>
+<H3><A NAME="10_57_4">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpFlush(http);
+</PRE>
+<H3><A NAME="10_57_5">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpGet">httpGet()</A></H2>
+<H3><A NAME="10_58_1">Usage</A></H3>
+<PRE>
+int
+httpGet(http_t *http,
+ const char *uri);
+</PRE>
+<H3><A NAME="10_58_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>uri</TD><TD>The URI to get</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_58_3">Returns</A></H3>
+<P>0 on success, non-zero on failure.</P>
+<H3><A NAME="10_58_4">Description</A></H3>
+<P>The <CODE>httpGet()</CODE> function sends a HTTP GET request to the
+ server.</P>
+<H3><A NAME="10_58_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+httpGet(http, &quot;/some/uri&quot;);
+</PRE>
+<H3><A NAME="10_58_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpSetField">
+ <CODE>httpSetField()</CODE></A>,<A HREF="#httpUpdate"> <CODE>
+httpUpdate()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpGets">httpGets()</A></H2>
+<H3><A NAME="10_59_1">Usage</A></H3>
+<PRE>
+char *
+httpGets(char *line,
+ int length,
+ http_t *http)
+</PRE>
+<H3><A NAME="10_59_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>line</TD><TD>The string to fill with a line from the HTTP
+ connection</TD></TR>
+<TR><TD>length</TD><TD>The maximum length of the string</TD></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_59_3">Returns</A></H3>
+<P>A pointer to the string or NULL if no line could be retrieved.</P>
+<H3><A NAME="10_59_4">Description</A></H3>
+<P>The <CODE>httpGets()</CODE> function is used to read a request line
+ from the HTTP connection. It is not normally used by a client program.</P>
+<H3><A NAME="10_59_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+char line[1024];
+
+if (httpGets(line, sizeof(line), http))
+{
+ ... process the line ...
+}
+</PRE>
+<H3><A NAME="10_59_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpUpdate">
+ <CODE>httpUpdate()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpGetDateString">httpGetDateString()</A></H2>
+<H3><A NAME="10_60_1">Usage</A></H3>
+<PRE>
+const char *
+httpGetDateString(time_t time)
+</PRE>
+<H3><A NAME="10_60_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>time</TD><TD>The UNIX date/time value</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_60_3">Returns</A></H3>
+<P>A pointer to a static string containing the HTTP date/time string for
+ the specified UNIX time value.</P>
+<H3><A NAME="10_60_4">Description</A></H3>
+<P>The <CODE>httpGetDateString()</CODE> function generates a date/time
+ string suitable for HTTP requests from a UNIX time value.</P>
+<H3><A NAME="10_60_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+puts(httpGetDateString(time(NULL)));
+</PRE>
+<H3><A NAME="10_60_6">See Also</A></H3>
+<A HREF="#httpGetDateTime"> <CODE>httpGetDateTime()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpGetDateTime">httpGetDateTime()</A></H2>
+<H3><A NAME="10_61_1">Usage</A></H3>
+<PRE>
+time_t
+httpGetDateTime(const char *date)
+</PRE>
+<H3><A NAME="10_61_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>date</TD><TD>The HTTP date/time string</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_61_3">Returns</A></H3>
+<P>A UNIX time value.</P>
+<H3><A NAME="10_61_4">Description</A></H3>
+<P>The <CODE>httpGetDateTime()</CODE> function converts a HTTP date/time
+ string to a UNIX time value.</P>
+<H3><A NAME="10_61_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+printf(&quot;%d\n&quot;, httpGetDateTime(&quot;Fri, 30 June 2000 12:34:56 GMT&quot;));
+</PRE>
+<H3><A NAME="10_61_6">See Also</A></H3>
+<A HREF="#httpGetDateString"> <CODE>httpGetDateString()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpGetField">httpGetField()</A></H2>
+<H3><A NAME="10_62_1">Usage</A></H3>
+<PRE>
+const char *
+httpGetField(http_t *http,
+ http_field_t field);
+</PRE>
+<H3><A NAME="10_62_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>field</TD><TD>The HTTP field</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_62_3">Returns</A></H3>
+<P>A pointer to the field value string.</P>
+<H3><A NAME="10_62_4">Description</A></H3>
+<P>The <CODE>httpGetField()</CODE> function returns the current value
+ for the specified HTTP field.</P>
+<H3><A NAME="10_62_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+httpGet(http, &quot;/some/uri&quot;);
+while (httpUpdate(http) == HTTP_CONTINUE);
+
+puts(httpGetField(http, HTTP_FIELD_CONTENT_TYPE));
+</PRE>
+<H3><A NAME="10_62_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpGetSubField">
+ <CODE>httpGetSubField()</CODE></A>,<A HREF="#httpSetField"> <CODE>
+httpSetField()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpGetHostByName">httpGetHostByName()</A></H2>
+<H3><A NAME="10_63_1">Usage</A></H3>
+<PRE>
+struct hostent *
+httpGetHostByName(const char *name);
+</PRE>
+<H3><A NAME="10_63_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>name</TD><TD>Name or IP address to lookup.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_63_3">Returns</A></H3>
+<P>NULL if the host could not be found or a pointer to a host entry
+ containing one or more addresses.</P>
+<H3><A NAME="10_63_4">Description</A></H3>
+<P><CODE>httpGetHostByName()</CODE> is a portable wrapper around the <CODE>
+gethostbyname()</CODE> function which handles both hostnames and IP
+ addresses.</P>
+<H3><A NAME="10_63_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+struct hostent *hostaddr;
+
+hostaddr = httpGetHostByName(&quot;foo.bar.com&quot;);
+</PRE>
+
+<!-- NEW PAGE -->
+<H2><A NAME="httpGetLength">httpGetLength()</A></H2>
+<H3><A NAME="10_64_1">Usage</A></H3>
+<PRE>
+int
+httpGetLength(http_t *http);
+</PRE>
+<H3><A NAME="10_64_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_64_3">Returns</A></H3>
+<P>The content length of the response or MAX_INT if chunking is used.</P>
+<H3><A NAME="10_64_4">Description</A></H3>
+<P><CODE>httpGetLength()</CODE> returns the content length of a
+ response.</P>
+<H3><A NAME="10_64_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+...
+
+printf(&quot;The length of the response is %d bytes.\n&quot;, httpGetLength(http));
+</PRE>
+<H3><A NAME="10_64_6">See Also</A></H3>
+<P><A HREF="#httpGet"> <CODE>httpGet()</CODE></A>,<A HREF="#httpPost"> <CODE>
+httpPost()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="httpGetSubField">httpGetSubField()</A></H2>
+<H3><A NAME="10_65_1">Usage</A></H3>
+<PRE>
+const char *
+httpGetSubField(http_t *http,
+ http_field_t field,
+ const char *name,
+ char *value);
+</PRE>
+<H3><A NAME="10_65_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection.</TD></TR>
+<TR><TD>field</TD><TD>The HTTP field.</TD></TR>
+<TR><TD>name</TD><TD>The name of the subfield.</TD></TR>
+<TR><TD>value</TD><TD>The string to hold the subfield value.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_65_3">Returns</A></H3>
+<P>A pointer to the subfield value string or NULL if it does not exist.</P>
+<H3><A NAME="10_65_4">Description</A></H3>
+<P>The <CODE>httpGetSubField()</CODE> function returns a subfield value
+ from the specified HTTP field. The destination string buffer must be at
+ least <CODE>HTTP_MAX_VALUE</CODE> bytes in length.</P>
+<H3><A NAME="10_65_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+char value[HTTP_MAX_VALUE];
+
+httpGet(http, &quot;/some/uri&quot;);
+while (httpUpdate(http) == HTTP_CONTINUE);
+
+puts(httpGetSubField(http, HTTP_FIELD_CONTENT_TYPE, &quot;charset&quot;, value));
+</PRE>
+<H3><A NAME="10_65_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpGetField">
+ <CODE>httpGetField()</CODE></A>,<A HREF="#httpSetField"> <CODE>
+httpSetField()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpHead">httpHead()</A></H2>
+<H3><A NAME="10_66_1">Usage</A></H3>
+<PRE>
+int
+httpHead(http_t *http,
+ const char *uri);
+</PRE>
+<H3><A NAME="10_66_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>uri</TD><TD>The URI to head</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_66_3">Returns</A></H3>
+<P>0 on success, non-zero on failure.</P>
+<H3><A NAME="10_66_4">Description</A></H3>
+<P>The <CODE>httpHead()</CODE> function sends a HTTP HEAD request to the
+ server.</P>
+<H3><A NAME="10_66_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpHead(http, &quot;/some/uri&quot;);
+</PRE>
+<H3><A NAME="10_66_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpSetField">
+ <CODE>httpSetField()</CODE></A>,<A HREF="#httpUpdate"> <CODE>
+httpUpdate()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpInitialize">httpInitialize()</A></H2>
+<H3><A NAME="10_67_1">Usage</A></H3>
+<PRE>
+void httpInitialize(void);
+</PRE>
+<H3><A NAME="10_67_2">Description</A></H3>
+<P>The <CODE>httpInitialize()</CODE> function initializes the networking
+ code as needed by the underlying platform. It is called automatically
+ by the <CODE>httpConnect()</CODE> function.</P>
+<H3><A NAME="10_67_3">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+httpInitialize();
+</PRE>
+<H3><A NAME="10_67_4">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpMD5">httpMD5()</A></H2>
+<H3><A NAME="10_68_1">Usage</A></H3>
+<PRE>
+char *
+httpMD5(const char *username,
+ const char *realm,
+ const char *passwd,
+ char md5[33]);
+</PRE>
+<H3><A NAME="10_68_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>username</TD><TD>The authenticating user name.</TD></TR>
+<TR><TD>realm</TD><TD>The authenticating realm name.</TD></TR>
+<TR><TD>passwd</TD><TD>The authenticating password.</TD></TR>
+<TR><TD>md5</TD><TD>The MD5 sum string.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_68_3">Returns</A></H3>
+<P>A pointer to the MD5 sum string.</P>
+<H3><A NAME="10_68_4">Description</A></H3>
+<P><CODE>httpMD5()</CODE> computes the MD5 hash of the username, realm,
+ and password as required by the HTTP Digest specification.</P>
+<H3><A NAME="10_68_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+char md5[33];
+
+...
+
+httpMD5(&quot;user&quot;, &quot;realm&quot;, &quot;password&quot;, md5);
+</PRE>
+<H3><A NAME="10_68_6">See Also</A></H3>
+<P><A HREF="#httpMD5Final"> <CODE>httpMD5Final()</CODE></A>,<A HREF="#httpMD5String">
+ <CODE>httpMD5String()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="httpMD5Final">httpMD5Final()</A></H2>
+<H3><A NAME="10_69_1">Usage</A></H3>
+<PRE>
+char *
+httpMD5Final(const char *nonce,
+ const char *method,
+ const char *resource,
+ char md5[33]);
+</PRE>
+<H3><A NAME="10_69_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>nonce</TD><TD>The server nonce value.</TD></TR>
+<TR><TD>method</TD><TD>The HTTP method (GET, POST, etc.)</TD></TR>
+<TR><TD>resource</TD><TD>The resource path.</TD></TR>
+<TR><TD>md5</TD><TD>The MD5 sum string.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_69_3">Returns</A></H3>
+<P>The MD5 sum string.</P>
+<H3><A NAME="10_69_4">Description</A></H3>
+<P><CODE>httpMD5Final()</CODE> appends the nonce, method, and resource
+ to the specified MD5 sum.</P>
+<H3><A NAME="10_69_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+char md5[33];
+
+...
+
+httpMD5Final(&quot;nonce&quot;, &quot;GET&quot;, &quot;/jobs&quot;, md5);
+</PRE>
+<H3><A NAME="10_69_6">See Also</A></H3>
+<P><A HREF="#httpMD5"> <CODE>httpMD5()</CODE></A>,<A HREF="#httpMD5String">
+ <CODE>httpMD5String()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="httpMD5String">httpMD5String()</A></H2>
+<H3><A NAME="10_70_1">Usage</A></H3>
+<PRE>
+char *
+httpMD5String(const md5_byte_t *sum,
+ char md5[33]);
+</PRE>
+<H3><A NAME="10_70_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>sum</TD><TD>The raw MD5 sum data.</TD></TR>
+<TR><TD>md5</TD><TD>The MD5 sum string.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_70_3">Returns</A></H3>
+<P>The MD5 sum string.</P>
+<H3><A NAME="10_70_4">Description</A></H3>
+<P><CODE>httpMD5String()</CODE> converts the raw MD5 sum value to a
+ string.</P>
+<H3><A NAME="10_70_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+md5_byte_t sum[16];
+char md5[33];
+
+...
+
+httpMD5String(sum, md5);
+</PRE>
+<H3><A NAME="10_70_6">See Also</A></H3>
+<P><A HREF="#httpMD5"> <CODE>httpMD5()</CODE></A>,<A HREF="#httpMD5Final">
+ <CODE>httpMD5Final()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="httpOptions">httpOptions()</A></H2>
+<H3><A NAME="10_71_1">Usage</A></H3>
+<PRE>
+int
+httpOptions(http_t *http,
+ const char *uri);
+</PRE>
+<H3><A NAME="10_71_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>uri</TD><TD>The URI to check for options</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_71_3">Returns</A></H3>
+<P>0 on success, non-zero on failure.</P>
+<H3><A NAME="10_71_4">Description</A></H3>
+<P>The <CODE>httpOptions()</CODE> function sends a HTTP OPTIONS request
+ to the server.</P>
+<H3><A NAME="10_71_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpOptions(http, &quot;/some/uri&quot;);
+</PRE>
+<H3><A NAME="10_71_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpSetField">
+ <CODE>httpSetField()</CODE></A>,<A HREF="#httpUpdate"> <CODE>
+httpUpdate()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpPost">httpPost()</A></H2>
+<H3><A NAME="10_72_1">Usage</A></H3>
+<PRE>
+int
+httpPost(http_t *http,
+ const char *uri);
+</PRE>
+<H3><A NAME="10_72_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>uri</TD><TD>The URI to post to</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_72_3">Returns</A></H3>
+<P>0 on success, non-zero on failure.</P>
+<H3><A NAME="10_72_4">Description</A></H3>
+<P>The <CODE>httpPost()</CODE> function sends a HTTP POST request to the
+ server.</P>
+<H3><A NAME="10_72_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpPost(http, &quot;/some/uri&quot;);
+</PRE>
+<H3><A NAME="10_72_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpSetField">
+ <CODE>httpSetField()</CODE></A>,<A HREF="#httpUpdate"> <CODE>
+httpUpdate()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpPrintf">httpPrintf()</A></H2>
+<H3><A NAME="10_73_1">Usage</A></H3>
+<PRE>
+int
+httpPrintf(http_t *http,
+ const char *format,
+ ...);
+</PRE>
+<H3><A NAME="10_73_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>format</TD><TD>A printf-style format string</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_73_3">Returns</A></H3>
+<P>The number of bytes written.</P>
+<H3><A NAME="10_73_4">Description</A></H3>
+<P>The <CODE>httpPrintf()</CODE> function sends a formatted string to
+ the HTTP connection. It is normally only used by the CUPS API and
+ scheduler.</P>
+<H3><A NAME="10_73_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpPrintf(http, &quot;GET / HTTP/1.1 \r\n&quot;);
+</PRE>
+<H3><A NAME="10_73_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpPut">httpPut()</A></H2>
+<H3><A NAME="10_74_1">Usage</A></H3>
+<PRE>
+int
+httpPut(http_t *http,
+ const char *uri);
+</PRE>
+<H3><A NAME="10_74_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>uri</TD><TD>The URI to put</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_74_3">Returns</A></H3>
+<P>0 on success, non-zero on failure.</P>
+<H3><A NAME="10_74_4">Description</A></H3>
+<P>The <CODE>httpPut()</CODE> function sends a HTTP PUT request to the
+ server.</P>
+<H3><A NAME="10_74_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpDelete(http, &quot;/some/uri&quot;);
+</PRE>
+<H3><A NAME="10_74_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpSetField">
+ <CODE>httpSetField()</CODE></A>,<A HREF="#httpUpdate"> <CODE>
+httpUpdate()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpRead">httpRead()</A></H2>
+<H3><A NAME="10_75_1">Usage</A></H3>
+<PRE>
+int
+httpRead(http_t *http,
+ char *buffer,
+ int length);
+</PRE>
+<H3><A NAME="10_75_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>buffer</TD><TD>The buffer to read into</TD></TR>
+<TR><TD>length</TD><TD>The number of bytes to read</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_75_3">Returns</A></H3>
+<P>The number of bytes read or -1 on error.</P>
+<H3><A NAME="10_75_4">Description</A></H3>
+<P>The <CODE>httpRead()</CODE> function reads data from the HTTP
+ connection, possibly the result of a GET or POST request.</P>
+<H3><A NAME="10_75_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+char buffer[1024];
+int bytes;
+
+httpGet(http, &quot;/&quot;);
+while (httpUpdate(http) != HTTP_CONTINUE);
+while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) &gt; 0)
+{
+ buffer[bytes] = '\0';
+ fputs(buffer, stdout);
+}
+</PRE>
+<H3><A NAME="10_75_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpWrite">
+ <CODE>httpWrite()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpReconnect">httpReconnect()</A></H2>
+<H3><A NAME="10_76_1">Usage</A></H3>
+<PRE>
+int
+httpReconnect(http_t *http);
+</PRE>
+<H3><A NAME="10_76_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_76_3">Returns</A></H3>
+<P>0 on success, non-zero on failure.</P>
+<H3><A NAME="10_76_4">Description</A></H3>
+<P>The <CODE>httpReconnect()</CODE> function reconnects to the HTTP
+ server. This is usually done automatically if the HTTP functions detect
+ that the server connection has terminated.</P>
+<H3><A NAME="10_76_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpReconnect(http);
+</PRE>
+<H3><A NAME="10_76_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpSeparate">httpSeparate()</A></H2>
+<H3><A NAME="10_77_1">Usage</A></H3>
+<PRE>
+void
+httpSeparate(const char *uri,
+ char *method,
+ char *username,
+ char *host,
+ int *port,
+ char *resource);
+</PRE>
+<H3><A NAME="10_77_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>uri</TD><TD>The URI to separate</TD></TR>
+<TR><TD>method</TD><TD>The method (scheme) of the URI</TD></TR>
+<TR><TD>username</TD><TD>The username (and password) portion of the URI,
+ if any</TD></TR>
+<TR><TD>host</TD><TD>The hostname portion of the URI, if any</TD></TR>
+<TR><TD>port</TD><TD>The port number for the URI, either as specified or
+ as default for the method/scheme</TD></TR>
+<TR><TD>resource</TD><TD>The resource string, usually a filename on the
+ server</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_77_3">Description</A></H3>
+<P>The <CODE>httpSeparate()</CODE> function separates the specified URI
+ into its component parts. The method, username, hostname, and resource
+ strings should be at least <CODE>HTTP_MAX_URI</CODE> characters long to
+ avoid potential buffer overflow problems.</P>
+<H3><A NAME="10_77_4">Example</A></H3>
+<PRE>
+char uri[HTTP_MAX_URI];
+char method[HTTP_MAX_URI];
+char username[HTTP_MAX_URI];
+char host[HTTP_MAX_URI];
+char resource[HTTP_MAX_URI];
+int port;
+
+...
+
+httpSeparate(uri, method, username, host, &amp;port, resource);
+</PRE>
+<H3><A NAME="10_77_5">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpSetField">httpSetField()</A></H2>
+<H3><A NAME="10_78_1">Usage</A></H3>
+<PRE>
+void
+httpSetField(http_t *http,
+ http_field_t field,
+ const char *value);
+</PRE>
+<H3><A NAME="10_78_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>field</TD><TD>The HTTP field</TD></TR>
+<TR><TD>value</TD><TD>The string value for the field</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_78_3">Description</A></H3>
+<P>The <CODE>httpSetField()</CODE> function sets the current value for
+ the specified HTTP field.</P>
+<H3><A NAME="10_78_4">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpSetField(http, HTTP_FIELD_AUTHORIZATION, &quot;Basic dfdr34453454325&quot;));
+httpGet(http, &quot;/some/uri&quot;);
+while (httpUpdate(http) == HTTP_CONTINUE);
+</PRE>
+<H3><A NAME="10_78_5">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpGetField">
+ <CODE>httpGetField()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpStatus">httpStatus()</A></H2>
+<H3><A NAME="10_79_1">Usage</A></H3>
+<PRE>
+const char *
+httpStatus(http_status_t status);
+</PRE>
+<H3><A NAME="10_79_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>status</TD><TD>The HTTP status code from the server.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_79_3">Returns</A></H3>
+<P>The standard HTTP status text associated with the status code.</P>
+<H3><A NAME="10_79_4">Description</A></H3>
+<P><CODE>httpStatus()</CODE> returns the standard HTTP status text
+ associated with the status code.</P>
+<H3><A NAME="10_79_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+...
+
+puts(httpStatus(http-&gt;status));
+</PRE>
+
+<!-- NEW PAGE -->
+<H2><A NAME="httpTrace">httpTrace()</A></H2>
+<H3><A NAME="10_80_1">Usage</A></H3>
+<PRE>
+int
+httpTrace(http_t *http,
+ const char *uri);
+</PRE>
+<H3><A NAME="10_80_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>uri</TD><TD>The URI to trace</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_80_3">Returns</A></H3>
+<P>0 on success, non-zero on failure.</P>
+<H3><A NAME="10_80_4">Description</A></H3>
+<P>The <CODE>httpTrace()</CODE> function sends a HTTP TRACE request to
+ the server.</P>
+<H3><A NAME="10_80_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpTrace(http, &quot;/some/uri&quot;);
+</PRE>
+<H3><A NAME="10_80_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpSetField">
+ <CODE>httpSetField()</CODE></A>,<A HREF="#httpUpdate"> <CODE>
+httpUpdate()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpUpdate">httpUpdate()</A></H2>
+<H3><A NAME="10_81_1">Usage</A></H3>
+<PRE>
+http_status_t
+httpUpdate(http_t *http);
+</PRE>
+<H3><A NAME="10_81_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_81_3">Returns</A></H3>
+<P>The HTTP status of the current request.</P>
+<H3><A NAME="10_81_4">Description</A></H3>
+<P>The <CODE>httpUpdate()</CODE> function updates the current request
+ status. It is used after any DELETE, GET, HEAD, OPTIONS, POST, PUT, or
+ TRACE request to finalize the HTTP request and retrieve the request
+ status.</P>
+<P>Since proxies and the current blocking mode can cause the request to
+ take longer, programs should continue calling <CODE>httpUpdate() <CODE>
+until the return status is not the constant value <CODE>HTTP_CONTINUE</CODE>
+.</CODE></CODE></P>
+<H3><A NAME="10_81_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+http_status_t status;
+
+httpGet(http, &quot;/some/uri&quot;);
+while ((status = httpUpdate(http)) == HTTP_CONTINUE);
+printf(&quot;Request status is %d\n&quot;, status);
+</PRE>
+<H3><A NAME="10_81_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpDelete">
+ <CODE>httpDelete()</CODE></A>,<A HREF="#httpGet"> <CODE>httpGet()</CODE>
+</A>,<A HREF="#httpHead"> <CODE>httpHead()</CODE></A>,<A HREF="#httpOptions">
+ <CODE>httpOptions()</CODE></A>,<A HREF="#httpPost"> <CODE>httpPost()</CODE>
+</A>,<A HREF="#httpPut"> <CODE>httpPut()</CODE></A>,<A HREF="#httpTrace">
+ <CODE>httpTrace()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="httpWrite">httpWrite()</A></H2>
+<H3><A NAME="10_82_1">Usage</A></H3>
+<PRE>
+int
+httpWrite(http_t *http,
+ char *buffer,
+ int length);
+</PRE>
+<H3><A NAME="10_82_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>buffer</TD><TD>The buffer to read into</TD></TR>
+<TR><TD>length</TD><TD>The number of bytes to read</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_82_3">Returns</A></H3>
+<P>The number of bytes read or -1 on error.</P>
+<H3><A NAME="10_82_4">Description</A></H3>
+<P>The <CODE>httpWrite()</CODE> function reads data from the HTTP
+ connection, possibly the result of a GET or POST request.</P>
+<H3><A NAME="10_82_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+FILE *fp;
+char buffer[1024];
+int bytes;
+
+httpPost(http, &quot;/&quot;);
+
+while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) &gt; 0)
+ httpWrite(http, buffer, bytes);
+
+while (httpUpdate(http) != HTTP_CONTINUE);
+
+while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) &gt; 0)
+{
+ buffer[bytes] = '\0';
+ fputs(buffer, stdout);
+}
+</PRE>
+<H3><A NAME="10_82_6">See Also</A></H3>
+<A HREF="#httpConnect"> <CODE>httpConnect()</CODE></A>,<A HREF="#httpRead">
+ <CODE>httpRead()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddBoolean">ippAddBoolean()</A></H2>
+<H3><A NAME="10_83_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddBoolean(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ char value);
+</PRE>
+<H3><A NAME="10_83_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+<TR><TD>group</TD><TD>The IPP group</TD></TR>
+<TR><TD>name</TD><TD>The name of attribute</TD></TR>
+<TR><TD>value</TD><TD>The boolean value</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_83_3">Returns</A></H3>
+<P>A pointer to the new attribute or NULL if the attribute could not be
+ created.</P>
+<H3><A NAME="10_83_4">Description</A></H3>
+<P>The <CODE>ippAddBoolean()</CODE> function adds a single boolean
+ attribute value to the specified IPP request.</P>
+<H3><A NAME="10_83_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, &quot;my-jobs&quot;, 1);
+</PRE>
+<H3><A NAME="10_83_6">See Also</A></H3>
+<A HREF="#ippAddBooleans"> <CODE>ippAddBooleans()</CODE></A>,<A HREF="#ippAddDate">
+ <CODE>ippAddDate()</CODE></A>,<A HREF="#ippAddInteger"> <CODE>
+ippAddInteger()</CODE></A>,<A HREF="#ippAddIntegers"> <CODE>
+ippAddIntegers()</CODE></A>,<A HREF="#ippAddRange"> <CODE>ippAddRange()</CODE>
+</A>,<A HREF="#ippAddRanges"> <CODE>ippAddRanges()</CODE></A>,<A HREF="#ippAddResolution">
+ <CODE>ippAddResolution()</CODE></A>,<A HREF="#ippAddResolutions"> <CODE>
+ippAddResolutions()</CODE></A>,<A HREF="#ippAddSeparator"> <CODE>
+ippAddSeparator()</CODE></A>,<A HREF="#ippAddString"> <CODE>
+ippAddString()</CODE></A>,<A HREF="#ippAddStrings"> <CODE>
+ippAddStrings()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddBooleans">ippAddBooleans()</A></H2>
+<H3><A NAME="10_84_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddBooleans(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ int num_values,
+ const char *values);
+</PRE>
+<H3><A NAME="10_84_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+<TR><TD>group</TD><TD>The IPP group</TD></TR>
+<TR><TD>name</TD><TD>The name of attribute</TD></TR>
+<TR><TD>num_values</TD><TD>The number of values</TD></TR>
+<TR><TD>values</TD><TD>The boolean values</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_84_3">Returns</A></H3>
+<P>A pointer to the new attribute or NULL if the attribute could not be
+ created.</P>
+<H3><A NAME="10_84_4">Description</A></H3>
+<P>The <CODE>ippAddBooleans()</CODE> function adds one or more boolean
+ attribute values to the specified IPP request. If the <CODE>values</CODE>
+ pointer is <CODE>NULL</CODE> then an array of <CODE>num_values</CODE>
+ false values is created.</P>
+<H3><A NAME="10_84_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+char values[10];
+
+ippAddBooleans(ipp, IPP_TAG_OPERATION, &quot;some-attribute&quot;, 10, values);
+</PRE>
+<H3><A NAME="10_84_6">See Also</A></H3>
+<A HREF="#ippAddBoolean"> <CODE>ippAddBoolean()</CODE></A>,<A HREF="#ippAddDate">
+ <CODE>ippAddDate()</CODE></A>,<A HREF="#ippAddInteger"> <CODE>
+ippAddInteger()</CODE></A>,<A HREF="#ippAddIntegers"> <CODE>
+ippAddIntegers()</CODE></A>,<A HREF="#ippAddRange"> <CODE>ippAddRange()</CODE>
+</A>,<A HREF="#ippAddRanges"> <CODE>ippAddRanges()</CODE></A>,<A HREF="#ippAddResolution">
+ <CODE>ippAddResolution()</CODE></A>,<A HREF="#ippAddResolutions"> <CODE>
+ippAddResolutions()</CODE></A>,<A HREF="#ippAddSeparator"> <CODE>
+ippAddSeparator()</CODE></A>,<A HREF="#ippAddString"> <CODE>
+ippAddString()</CODE></A>,<A HREF="#ippAddStrings"> <CODE>
+ippAddStrings()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddDate">ippAddDate()</A></H2>
+<H3><A NAME="10_85_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddDate(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ ipp_uchar_t *value);
+</PRE>
+<H3><A NAME="10_85_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+<TR><TD>group</TD><TD>The IPP group</TD></TR>
+<TR><TD>name</TD><TD>The name of attribute</TD></TR>
+<TR><TD>value</TD><TD>The date value</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_85_3">Returns</A></H3>
+<P>A pointer to the new attribute or NULL if the attribute could not be
+ created.</P>
+<H3><A NAME="10_85_4">Description</A></H3>
+<P>The <CODE>ippAddDate()</CODE> function adds a single date-time
+ attribute value to the specified IPP request.</P>
+<H3><A NAME="10_85_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+
+ippAddDate(ipp, IPP_TAG_OPERATION, &quot;some-attribute&quot;,
+ ippTimeToDate(time(NULL));
+</PRE>
+<H3><A NAME="10_85_6">See Also</A></H3>
+<A HREF="#ippAddBoolean"> <CODE>ippAddBoolean()</CODE></A>,<A HREF="#ippAddBooleans">
+ <CODE>ippAddBooleans()</CODE></A>,<A HREF="#ippAddInteger"> <CODE>
+ippAddInteger()</CODE></A>,<A HREF="#ippAddIntegers"> <CODE>
+ippAddIntegers()</CODE></A>,<A HREF="#ippAddRange"> <CODE>ippAddRange()</CODE>
+</A>,<A HREF="#ippAddRanges"> <CODE>ippAddRanges()</CODE></A>,<A HREF="#ippAddResolution">
+ <CODE>ippAddResolution()</CODE></A>,<A HREF="#ippAddResolutions"> <CODE>
+ippAddResolutions()</CODE></A>,<A HREF="#ippAddSeparator"> <CODE>
+ippAddSeparator()</CODE></A>,<A HREF="#ippAddString"> <CODE>
+ippAddString()</CODE></A>,<A HREF="#ippAddStrings"> <CODE>
+ippAddStrings()</CODE></A>,<A HREF="#ippTimeToDate"> <CODE>
+ippTimeToDate()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddInteger">ippAddInteger()</A></H2>
+<H3><A NAME="10_86_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddInteger(ipp_t *ipp,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ int value);
+</PRE>
+<H3><A NAME="10_86_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+<TR><TD>group</TD><TD>The IPP group</TD></TR>
+<TR><TD>tag</TD><TD>The type of integer value (IPP_TAG_INTEGER or
+ IPP_TAG_ENUM)</TD></TR>
+<TR><TD>name</TD><TD>The name of attribute</TD></TR>
+<TR><TD>value</TD><TD>The integer value</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_86_3">Returns</A></H3>
+<P>A pointer to the new attribute or NULL if the attribute could not be
+ created.</P>
+<H3><A NAME="10_86_4">Description</A></H3>
+<P>The <CODE>ippAddInteger()</CODE> function adds a single integer
+ attribute value to the specified IPP request.</P>
+<H3><A NAME="10_86_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+
+ippAddInteger(ipp, IPP_TAG_OPERATION, &quot;limit&quot;, 100);
+</PRE>
+<H3><A NAME="10_86_6">See Also</A></H3>
+<A HREF="#ippAddBoolean"> <CODE>ippAddBoolean()</CODE></A>,<A HREF="#ippAddBooleans">
+ <CODE>ippAddBooleans()</CODE></A>,<A HREF="#ippAddDate"> <CODE>
+ippAddDate()</CODE></A>,<A HREF="#ippAddIntegers"> <CODE>
+ippAddIntegers()</CODE></A>,<A HREF="#ippAddRange"> <CODE>ippAddRange()</CODE>
+</A>,<A HREF="#ippAddRanges"> <CODE>ippAddRanges()</CODE></A>,<A HREF="#ippAddResolution">
+ <CODE>ippAddResolution()</CODE></A>,<A HREF="#ippAddResolutions"> <CODE>
+ippAddResolutions()</CODE></A>,<A HREF="#ippAddSeparator"> <CODE>
+ippAddSeparator()</CODE></A>,<A HREF="#ippAddString"> <CODE>
+ippAddString()</CODE></A>,<A HREF="#ippAddStrings"> <CODE>
+ippAddStrings()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddIntegers">ippAddIntegers()</A></H2>
+<H3><A NAME="10_87_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddIntegers(ipp_t *ipp,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ int num_values,
+ const int *values);
+</PRE>
+<H3><A NAME="10_87_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+<TR><TD>group</TD><TD>The IPP group</TD></TR>
+<TR><TD>tag</TD><TD>The type of integer value (IPP_TAG_INTEGER or
+ IPP_TAG_ENUM)</TD></TR>
+<TR><TD>name</TD><TD>The name of attribute</TD></TR>
+<TR><TD>num_values</TD><TD>The number of values</TD></TR>
+<TR><TD>values</TD><TD>The integer values</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_87_3">Returns</A></H3>
+<P>A pointer to the new attribute or NULL if the attribute could not be
+ created.</P>
+<H3><A NAME="10_87_4">Description</A></H3>
+<P>The <CODE>ippAddIntegers()</CODE> function adds one or more integer
+ attribute values to the specified IPP request. If the <CODE>values</CODE>
+ pointer is <CODE>NULL</CODE> then an array of <CODE>num_values</CODE> 0
+ values is created.</P>
+<H3><A NAME="10_87_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+int values[100];
+
+ippAddIntegers(ipp, IPP_TAG_OPERATION, &quot;some-attribute&quot;, 100, values);
+</PRE>
+<H3><A NAME="10_87_6">See Also</A></H3>
+<A HREF="#ippAddBoolean"> <CODE>ippAddBoolean()</CODE></A>,<A HREF="#ippAddBooleans">
+ <CODE>ippAddBooleans()</CODE></A>,<A HREF="#ippAddDate"> <CODE>
+ippAddDate()</CODE></A>,<A HREF="#ippAddInteger"> <CODE>ippAddInteger()</CODE>
+</A>,<A HREF="#ippAddRange"> <CODE>ippAddRange()</CODE></A>,<A HREF="#ippAddRanges">
+ <CODE>ippAddRanges()</CODE></A>,<A HREF="#ippAddResolution"> <CODE>
+ippAddResolution()</CODE></A>,<A HREF="#ippAddResolutions"> <CODE>
+ippAddResolutions()</CODE></A>,<A HREF="#ippAddSeparator"> <CODE>
+ippAddSeparator()</CODE></A>,<A HREF="#ippAddString"> <CODE>
+ippAddString()</CODE></A>,<A HREF="#ippAddStrings"> <CODE>
+ippAddStrings()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddRange">ippAddRange()</A></H2>
+<H3><A NAME="10_88_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddRange(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ int low,
+ int high);
+</PRE>
+<H3><A NAME="10_88_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+<TR><TD>group</TD><TD>The IPP group</TD></TR>
+<TR><TD>name</TD><TD>The name of attribute</TD></TR>
+<TR><TD>low</TD><TD>The lower value</TD></TR>
+<TR><TD>high</TD><TD>The higher value</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_88_3">Returns</A></H3>
+<P>A pointer to the new attribute or NULL if the attribute could not be
+ created.</P>
+<H3><A NAME="10_88_4">Description</A></H3>
+<P>The <CODE>ippAddRange()</CODE> function adds a single range attribute
+ value to the specified IPP request.</P>
+<H3><A NAME="10_88_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+
+ippAddRange(ipp, IPP_TAG_OPERATION, &quot;page-ranges&quot;, 1, 10);
+</PRE>
+<H3><A NAME="10_88_6">See Also</A></H3>
+<A HREF="#ippAddBoolean"> <CODE>ippAddBoolean()</CODE></A>,<A HREF="#ippAddBooleans">
+ <CODE>ippAddBooleans()</CODE></A>,<A HREF="#ippAddDate"> <CODE>
+ippAddDate()</CODE></A>,<A HREF="#ippAddInteger"> <CODE>ippAddInteger()</CODE>
+</A>,<A HREF="#ippAddIntegers"> <CODE>ippAddIntegers()</CODE></A>,<A HREF="#ippAddRanges">
+ <CODE>ippAddRanges()</CODE></A>,<A HREF="#ippAddResolution"> <CODE>
+ippAddResolution()</CODE></A>,<A HREF="#ippAddResolutions"> <CODE>
+ippAddResolutions()</CODE></A>,<A HREF="#ippAddSeparator"> <CODE>
+ippAddSeparator()</CODE></A>,<A HREF="#ippAddString"> <CODE>
+ippAddString()</CODE></A>,<A HREF="#ippAddStrings"> <CODE>
+ippAddStrings()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddRanges">ippAddRanges()</A></H2>
+<H3><A NAME="10_89_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddRanges(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ int num_values,
+ const int *lows,
+ const int *highs);
+</PRE>
+<H3><A NAME="10_89_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+<TR><TD>group</TD><TD>The IPP group</TD></TR>
+<TR><TD>name</TD><TD>The name of attribute</TD></TR>
+<TR><TD>num_values</TD><TD>The number of range values</TD></TR>
+<TR><TD>lows</TD><TD>The lower values</TD></TR>
+<TR><TD>highs</TD><TD>The higher values</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_89_3">Returns</A></H3>
+<P>A pointer to the new attribute or NULL if the attribute could not be
+ created.</P>
+<H3><A NAME="10_89_4">Description</A></H3>
+<P>The <CODE>ippAddRanges()</CODE> function adds one or more range
+ attribute values to the specified IPP request. If the <CODE>values</CODE>
+ pointer is <CODE>NULL</CODE> then an array of <CODE>num_values</CODE>
+ 0,0 ranges is created.</P>
+<H3><A NAME="10_89_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+int lows[2];
+int highs[2];
+
+ippAddRanges(ipp, IPP_TAG_OPERATION, &quot;page-ranges&quot;, 2, lows, highs);
+</PRE>
+<H3><A NAME="10_89_6">See Also</A></H3>
+<A HREF="#ippAddBoolean"> <CODE>ippAddBoolean()</CODE></A>,<A HREF="#ippAddBooleans">
+ <CODE>ippAddBooleans()</CODE></A>,<A HREF="#ippAddDate"> <CODE>
+ippAddDate()</CODE></A>,<A HREF="#ippAddInteger"> <CODE>ippAddInteger()</CODE>
+</A>,<A HREF="#ippAddIntegers"> <CODE>ippAddIntegers()</CODE></A>,<A HREF="#ippAddRange">
+ <CODE>ippAddRange()</CODE></A>,<A HREF="#ippAddResolution"> <CODE>
+ippAddResolution()</CODE></A>,<A HREF="#ippAddResolutions"> <CODE>
+ippAddResolutions()</CODE></A>,<A HREF="#ippAddSeparator"> <CODE>
+ippAddSeparator()</CODE></A>,<A HREF="#ippAddString"> <CODE>
+ippAddString()</CODE></A>,<A HREF="#ippAddStrings"> <CODE>
+ippAddStrings()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddResolution">ippAddResolution()</A></H2>
+<H3><A NAME="10_90_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddResolution(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ int xres,
+ int yres,
+ ipp_res_t units);
+</PRE>
+<H3><A NAME="10_90_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+<TR><TD>group</TD><TD>The IPP group</TD></TR>
+<TR><TD>name</TD><TD>The name of attribute</TD></TR>
+<TR><TD>xres</TD><TD>The horizontal resolution</TD></TR>
+<TR><TD>yres</TD><TD>The vertical resolution</TD></TR>
+<TR><TD>units</TD><TD>The resolution units</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_90_3">Returns</A></H3>
+<P>A pointer to the new attribute or NULL if the attribute could not be
+ created.</P>
+<H3><A NAME="10_90_4">Description</A></H3>
+<P>The <CODE>ippAddResolution()</CODE> function adds a single resolution
+ attribute value to the specified IPP request.</P>
+<H3><A NAME="10_90_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, &quot;printer-resolution&quot;,
+ 720, 720, IPP_RES_PER_INCH);
+</PRE>
+<H3><A NAME="10_90_6">See Also</A></H3>
+<A HREF="#ippAddBoolean"> <CODE>ippAddBoolean()</CODE></A>,<A HREF="#ippAddBooleans">
+ <CODE>ippAddBooleans()</CODE></A>,<A HREF="#ippAddDate"> <CODE>
+ippAddDate()</CODE></A>,<A HREF="#ippAddInteger"> <CODE>ippAddInteger()</CODE>
+</A>,<A HREF="#ippAddIntegers"> <CODE>ippAddIntegers()</CODE></A>,<A HREF="#ippAddRange">
+ <CODE>ippAddRange()</CODE></A>,<A HREF="#ippAddRanges"> <CODE>
+ippAddRanges()</CODE></A>,<A HREF="#ippAddResolutions"> <CODE>
+ippAddResolutions()</CODE></A>,<A HREF="#ippAddSeparator"> <CODE>
+ippAddSeparator()</CODE></A>,<A HREF="#ippAddString"> <CODE>
+ippAddString()</CODE></A>,<A HREF="#ippAddStrings"> <CODE>
+ippAddStrings()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddResolutions">ippAddResolutions()</A></H2>
+<H3><A NAME="10_91_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddResolutions(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ int num_values,
+ const int *xres,
+ const int *yres,
+ const ipp_res_t *units);
+</PRE>
+<H3><A NAME="10_91_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+<TR><TD>group</TD><TD>The IPP group</TD></TR>
+<TR><TD>name</TD><TD>The name of attribute</TD></TR>
+<TR><TD>num_values</TD><TD>The number of resolution values</TD></TR>
+<TR><TD>xres</TD><TD>The horizontal resolutions</TD></TR>
+<TR><TD>yres</TD><TD>The vertical resolutions</TD></TR>
+<TR><TD>units</TD><TD>The resolution units</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_91_3">Returns</A></H3>
+<P>A pointer to the new attribute or NULL if the attribute could not be
+ created.</P>
+<H3><A NAME="10_91_4">Description</A></H3>
+<P>The <CODE>ippAddResolutions()</CODE> function adds one or more
+ resolution attribute values to the specified IPP request. If the <CODE>
+values</CODE> pointer is <CODE>NULL</CODE> then an array of <CODE>
+num_values</CODE> 0,0 resolutions is created.</P>
+<H3><A NAME="10_91_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+int xres[5];
+int yres[5];
+ipp_res_t units[5];
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, &quot;printer-resolutions-supported&quot;,
+ 5, xres, yres, units);
+</PRE>
+<H3><A NAME="10_91_6">See Also</A></H3>
+<A HREF="#ippAddBoolean"> <CODE>ippAddBoolean()</CODE></A>,<A HREF="#ippAddBooleans">
+ <CODE>ippAddBooleans()</CODE></A>,<A HREF="#ippAddDate"> <CODE>
+ippAddDate()</CODE></A>,<A HREF="#ippAddInteger"> <CODE>ippAddInteger()</CODE>
+</A>,<A HREF="#ippAddIntegers"> <CODE>ippAddIntegers()</CODE></A>,<A HREF="#ippAddRange">
+ <CODE>ippAddRange()</CODE></A>,<A HREF="#ippAddRanges"> <CODE>
+ippAddRanges()</CODE></A>,<A HREF="#ippAddResolution"> <CODE>
+ippAddResolution()</CODE></A>,<A HREF="#ippAddSeparator"> <CODE>
+ippAddSeparator()</CODE></A>,<A HREF="#ippAddString"> <CODE>
+ippAddString()</CODE></A>,<A HREF="#ippAddStrings"> <CODE>
+ippAddStrings()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddSeparator">ippAddSeparator()</A></H2>
+<H3><A NAME="10_92_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddSeparator(ipp_t *ipp);
+</PRE>
+<H3><A NAME="10_92_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_92_3">Returns</A></H3>
+<P>A pointer to the new separator or NULL if the separator could not be
+ created.</P>
+<H3><A NAME="10_92_4">Description</A></H3>
+<P>The <CODE>ippAddSeparator()</CODE> function adds a group separator to
+ the specified IPP request.</P>
+<H3><A NAME="10_92_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+
+ippAddSeparator(ipp);
+</PRE>
+<H3><A NAME="10_92_6">See Also</A></H3>
+<A HREF="#ippAddBoolean"> <CODE>ippAddBoolean()</CODE></A>,<A HREF="#ippAddBooleans">
+ <CODE>ippAddBooleans()</CODE></A>,<A HREF="#ippAddDate"> <CODE>
+ippAddDate()</CODE></A>,<A HREF="#ippAddInteger"> <CODE>ippAddInteger()</CODE>
+</A>,<A HREF="#ippAddIntegers"> <CODE>ippAddIntegers()</CODE></A>,<A HREF="#ippAddRange">
+ <CODE>ippAddRange()</CODE></A>,<A HREF="#ippAddRanges"> <CODE>
+ippAddRanges()</CODE></A>,<A HREF="#ippAddResolution"> <CODE>
+ippAddResolution()</CODE></A>,<A HREF="#ippAddResolutions"> <CODE>
+ippAddResolutions()</CODE></A>,<A HREF="#ippAddString"> <CODE>
+ippAddString()</CODE></A>,<A HREF="#ippAddStrings"> <CODE>
+ippAddStrings()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddString">ippAddString()</A></H2>
+<H3><A NAME="10_93_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddString(ipp_t *ipp,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ const char *charset,
+ const char *value);
+</PRE>
+<H3><A NAME="10_93_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+<TR><TD>group</TD><TD>The IPP group</TD></TR>
+<TR><TD>tag</TD><TD>The type of string value</TD></TR>
+<TR><TD>name</TD><TD>The name of attribute</TD></TR>
+<TR><TD>charset</TD><TD>The character set for the string</TD></TR>
+<TR><TD>value</TD><TD>The string value</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_93_3">Returns</A></H3>
+<P>A pointer to the new attribute or NULL if the attribute could not be
+ created.</P>
+<H3><A NAME="10_93_4">Description</A></H3>
+<P>The <CODE>ippAddString()</CODE> function adds a single string
+ attribute value to the specified IPP request. For <CODE>
+IPP_TAG_NAMELANG</CODE> and <CODE>IPP_TAG_TEXTLANG</CODE> strings, the
+ charset value is provided with the string to identify the string
+ encoding used. Otherwise the charset value is ignored.</P>
+<H3><A NAME="10_93_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+
+ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_NAME, &quot;job-name&quot;,
+ NULL, &quot;abc123&quot;);
+</PRE>
+<H3><A NAME="10_93_6">See Also</A></H3>
+<A HREF="#ippAddBoolean"> <CODE>ippAddBoolean()</CODE></A>,<A HREF="#ippAddBooleans">
+ <CODE>ippAddBooleans()</CODE></A>,<A HREF="#ippAddDate"> <CODE>
+ippAddDate()</CODE></A>,<A HREF="#ippAddInteger"> <CODE>ippAddInteger()</CODE>
+</A>,<A HREF="#ippAddIntegers"> <CODE>ippAddIntegers()</CODE></A>,<A HREF="#ippAddRange">
+ <CODE>ippAddRange()</CODE></A>,<A HREF="#ippAddRanges"> <CODE>
+ippAddRanges()</CODE></A>,<A HREF="#ippAddResolution"> <CODE>
+ippAddResolution()</CODE></A>,<A HREF="#ippAddResolutions"> <CODE>
+ippAddResolutions()</CODE></A>,<A HREF="#ippAddSeparator"> <CODE>
+ippAddSeparator()</CODE></A>,<A HREF="#ippAddStrings"> <CODE>
+ippAddStrings()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippAddStrings">ippAddStrings()</A></H2>
+<H3><A NAME="10_94_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippAddStrings(ipp_t *ipp,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ int num_values,
+ const char *charset,
+ const char **values);
+</PRE>
+<H3><A NAME="10_94_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request</TD></TR>
+<TR><TD>group</TD><TD>The IPP group</TD></TR>
+<TR><TD>tag</TD><TD>The type of string value</TD></TR>
+<TR><TD>name</TD><TD>The name of attribute</TD></TR>
+<TR><TD>num_values</TD><TD>The number of strings</TD></TR>
+<TR><TD>charset</TD><TD>The character set for the strings</TD></TR>
+<TR><TD>values</TD><TD>The string values</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_94_3">Returns</A></H3>
+<P>A pointer to the new attribute or NULL if the attribute could not be
+ created.</P>
+<H3><A NAME="10_94_4">Description</A></H3>
+<P>The <CODE>ippAddStrings()</CODE> function adds one or more string
+ attribute values to the specified IPP request. For <CODE>
+IPP_TAG_NAMELANG</CODE> and <CODE>IPP_TAG_TEXTLANG</CODE> strings, the
+ charset value is provided with the strings to identify the string
+ encoding used. Otherwise the charset value is ignored. If the <CODE>
+values</CODE> pointer is <CODE>NULL</CODE> then an array of <CODE>
+num_values</CODE> NULL strings is created.</P>
+<H3><A NAME="10_94_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+char *values[2] = { &quot;one&quot;, &quot;two&quot; };
+
+ippAddStrings(ipp, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, &quot;attr-name&quot;,
+ 2, NULL, values);
+</PRE>
+<H3><A NAME="10_94_6">See Also</A></H3>
+<A HREF="#ippAddBoolean"> <CODE>ippAddBoolean()</CODE></A>,<A HREF="#ippAddBooleans">
+ <CODE>ippAddBooleans()</CODE></A>,<A HREF="#ippAddDate"> <CODE>
+ippAddDate()</CODE></A>,<A HREF="#ippAddInteger"> <CODE>ippAddInteger()</CODE>
+</A>,<A HREF="#ippAddIntegers"> <CODE>ippAddIntegers()</CODE></A>,<A HREF="#ippAddRange">
+ <CODE>ippAddRange()</CODE></A>,<A HREF="#ippAddRanges"> <CODE>
+ippAddRanges()</CODE></A>,<A HREF="#ippAddResolution"> <CODE>
+ippAddResolution()</CODE></A>,<A HREF="#ippAddResolutions"> <CODE>
+ippAddResolutions()</CODE></A>,<A HREF="#ippAddSeparator"> <CODE>
+ippAddSeparator()</CODE></A>,<A HREF="#ippAddString"> <CODE>
+ippAddString()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippDateToTime">ippDateToTime()</A></H2>
+<H3><A NAME="10_95_1">Usage</A></H3>
+<PRE>
+time_t
+ippDateToTime(const ipp_uchar_t date[11]);
+</PRE>
+<H3><A NAME="10_95_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>date</TD><TD>The IPP date-time value</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_95_3">Returns</A></H3>
+<P>A UNIX time value.</P>
+<H3><A NAME="10_95_4">Description</A></H3>
+<P>The <CODE>ippDateToTime()</CODE> function converts an IPP date-time
+ value to a UNIX time value.</P>
+<H3><A NAME="10_95_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_uchar_t date[11];
+
+printf(&quot;UNIX time is %d\n&quot;, ippDateToTime(date));
+</PRE>
+<H3><A NAME="10_95_6">See Also</A></H3>
+<A HREF="#ippTimeToDate"> <CODE>ippTimeToDate()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippDelete">ippDelete()</A></H2>
+<H3><A NAME="10_96_1">Usage</A></H3>
+<PRE>
+void
+ippDelete(ipp_t *ipp);
+</PRE>
+<H3><A NAME="10_96_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request or response</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_96_3">Description</A></H3>
+<P>The <CODE>ippDelete()</CODE> function deletes all memory used by an
+ IPP request or response.</P>
+<H3><A NAME="10_96_4">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+
+ippDelete(ipp);
+</PRE>
+<H3><A NAME="10_96_5">See Also</A></H3>
+<A HREF="#ippNew"> <CODE>ippNew()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippErrorString">ippErrorString()</A></H2>
+<H3><A NAME="10_97_1">Usage</A></H3>
+<PRE>
+const char *
+ippErrorString(ipp_status_t error);
+</PRE>
+<H3><A NAME="10_97_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>error</TD><TD>IPP error code.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_97_3">Returns</A></H3>
+<P>The standard text representation of the IPP error code.</P>
+<H3><A NAME="10_97_4">Description</A></H3>
+<P><CODE>ippErrorString()</CODE> returns the standard text
+ representation of the IPP error code.</P>
+<H3><A NAME="10_97_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+puts(ippErrorString(IPP_OK));
+</PRE>
+<H3><A NAME="10_97_6">See Also</A></H3>
+<P><A HREF="#cupsLastError"> <CODE>cupsLastError()</CODE></A>
+<!-- NEW PAGE -->
+</P>
+<H2><A NAME="ippFindAttribute">ippFindAttribute()</A></H2>
+<H3><A NAME="10_98_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippFindAttribute(ipp_t *ipp,
+ const char *name,
+ ipp_tag_t tag);
+</PRE>
+<H3><A NAME="10_98_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request or response</TD></TR>
+<TR><TD>name</TD><TD>The name of the attribute</TD></TR>
+<TR><TD>tag</TD><TD>The required value tag for the attribute or <CODE>
+IPP_TAG_ZERO</CODE> for any type of value.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_98_3">Returns</A></H3>
+<P>A pointer to the first occurrence of the requested attribute, or <CODE>
+NULL</CODE> if it was not found.</P>
+<H3><A NAME="10_98_4">Description</A></H3>
+<P><CODE>ippFindAttribute()</CODE> finds the first occurrence of the
+ named attribute. The <CODE>tag</CODE> parameter restricts the search to
+ a specific value type - use <CODE>IPP_TAG_ZERO</CODE> to find any value
+ with the name.</P>
+<P>The value tags <CODE>IPP_TAG_NAME</CODE> and <CODE>IPP_TAG_TEXT</CODE>
+ match the name/text values with or without the language code.</P>
+<H3><A NAME="10_98_5">Example</A></H3>
+<PRE>
+<A HREF="#ipp_attribute_t">ipp_attribute_t</A> *attr;
+
+attr = ippFindAttribute(response, &quot;printer-state-message&quot;, IPP_TAG_TEXT);
+while (attr != NULL)
+{
+ puts(attr-&gt;values[0].string.text);
+
+ attr = ippFindNextAttribute(response, &quot;printer-state-message&quot;, IPP_TAG_TEXT);
+}
+</PRE>
+<H3><A NAME="10_98_6">See Also</A></H3>
+<A HREF="#cupsDoFileRequest"> <CODE>cupsDoFileRequest()</CODE></A>,<A HREF="#cupsDoRequest">
+ <CODE>cupsDoRequest()</CODE></A>,<A HREF="#ippDelete"> <CODE>
+ippDelete()</CODE></A>,<A HREF="#ippFindNextAttribute"> <CODE>
+ippFindNextAttribute()</CODE></A>,<A HREF="#ippNew"> <CODE>ippNew()</CODE>
+</A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippFindNextAttribute">ippFindNextAttribute()</A></H2>
+<H3><A NAME="10_99_1">Usage</A></H3>
+<PRE>
+ipp_attribute_t *
+ippFindNextAttribute(ipp_t *ipp,
+ const char *name,
+ ipp_tag_t tag);
+</PRE>
+<H3><A NAME="10_99_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request or response</TD></TR>
+<TR><TD>name</TD><TD>The name of the attribute</TD></TR>
+<TR><TD>tag</TD><TD>The required value tag for the attribute or <CODE>
+IPP_TAG_ZERO</CODE> for any type of value.</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_99_3">Returns</A></H3>
+<P>A pointer to the next occurrence of the requested attribute, or <CODE>
+NULL</CODE> if it was not found.</P>
+<H3><A NAME="10_99_4">Description</A></H3>
+<P><CODE>ippFindNextAttribute()</CODE> finds the next occurrence of the
+ named attribute. The <CODE>tag</CODE> parameter restricts the search to
+ a specific value type - use <CODE>IPP_TAG_ZERO</CODE> to find any value
+ with the name.</P>
+<P>The value tags <CODE>IPP_TAG_NAME</CODE> and <CODE>IPP_TAG_TEXT</CODE>
+ match the name/text values with or without the language code.</P>
+<H3><A NAME="10_99_5">Example</A></H3>
+<PRE>
+<A HREF="#ipp_attribute_t">ipp_attribute_t</A> *attr;
+
+attr = ippFindAttribute(response, &quot;printer-state-message&quot;, IPP_TAG_TEXT);
+while (attr != NULL)
+{
+ puts(attr-&gt;values[0].string.text);
+
+ attr = ippFindNextAttribute(response, &quot;printer-state-message&quot;, IPP_TAG_TEXT);
+}
+</PRE>
+<H3><A NAME="10_99_6">See Also</A></H3>
+<A HREF="#cupsDoFileRequest"> <CODE>cupsDoFileRequest()</CODE></A>,<A HREF="#cupsDoRequest">
+ <CODE>cupsDoRequest()</CODE></A>,<A HREF="#ippDelete"> <CODE>
+ippDelete()</CODE></A>,<A HREF="#ippFindNextAttribute"> <CODE>
+ippFindNextAttribute()</CODE></A>,<A HREF="#ippNew"> <CODE>ippNew()</CODE>
+</A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippLength">ippLength()</A></H2>
+<H3><A NAME="10_100_1">Usage</A></H3>
+<PRE>
+int
+ippLength(ipp_t *ipp);
+</PRE>
+<H3><A NAME="10_100_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ipp</TD><TD>The IPP request or response</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_100_3">Returns</A></H3>
+<P>The total encoded length of the IPP request or response in bytes.</P>
+<H3><A NAME="10_100_4">Description</A></H3>
+<P><CODE>ippLength()</CODE> returns the length of the IPP request or
+ response in bytes.</P>
+<H3><A NAME="10_100_5">Example</A></H3>
+<PRE>
+printf(&quot;The length of the response is %d bytes.\n&quot;, ippLength(response));
+</PRE>
+<H3><A NAME="10_100_6">See Also</A></H3>
+<A HREF="#ippDelete"> <CODE>ippDelete()</CODE></A>,<A HREF="#ippNew"> <CODE>
+ippNew()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippNew">ippNew()</A></H2>
+<H3><A NAME="10_101_1">Usage</A></H3>
+<PRE>
+ipp_t *
+ippNew(void);
+</PRE>
+<H3><A NAME="10_101_2">Returns</A></H3>
+<P>A pointer to a new IPP request or response.</P>
+<H3><A NAME="10_101_3">Description</A></H3>
+<P>The <CODE>ippNew()</CODE> function creates a new IPP request or
+ response.</P>
+<H3><A NAME="10_101_4">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_t *ipp;
+
+ipp = ippNew();
+</PRE>
+<H3><A NAME="10_101_5">See Also</A></H3>
+<A HREF="#ippDelete"> <CODE>ippDelete()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippPort">ippPort()</A></H2>
+<H3><A NAME="10_102_1">Usage</A></H3>
+<PRE>
+int
+ippPort(void);
+</PRE>
+<H3><A NAME="10_102_2">Returns</A></H3>
+<P>The default TCP/IP port number for IPP requests.</P>
+<H3><A NAME="10_102_3">Description</A></H3>
+<P>The <CODE>ippPort()</CODE> function returns the default IPP port
+ number for requests.</P>
+<H3><A NAME="10_102_4">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+#include &lt;cups/ipp.h&gt;
+
+http_t *http;
+
+http = httpConnect(cupsServer(), ippPort());
+</PRE>
+<H3><A NAME="10_102_5">See Also</A></H3>
+<A HREF="#cupsServer"> <CODE>cupsServer()</CODE></A>,<A HREF="#ippSetPort">
+ <CODE>ippSetPort()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippRead">ippRead()</A></H2>
+<H3><A NAME="10_103_1">Usage</A></H3>
+<PRE>
+ipp_state_t
+ippRead(http_t *http,
+ ipp_t *ipp);
+</PRE>
+<H3><A NAME="10_103_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>ipp</TD><TD>The IPP request or response</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_103_3">Returns</A></H3>
+<P>The current read state.</P>
+<H3><A NAME="10_103_4">Description</A></H3>
+<P>The <CODE>ippRead()</CODE> function reads IPP attributes from the
+ specified HTTP connection. Programs should continue calling <CODE>
+ippRead()</CODE> until <CODE>IPP_ERROR</CODE> or <CODE>IPP_DATA</CODE>
+ is returned.</P>
+<H3><A NAME="10_103_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+#include &lt;cups/ipp.h&gt;
+
+http_t *http;
+ipp_t *ipp;
+ipp_state_t status;
+
+ipp = ippNew();
+
+while ((status = ippRead(http, ipp)) != IPP_ERROR)
+ if (status == IPP_DATA)
+ break;
+
+if (status == IPP_DATA)
+{
+ ... read additional non-IPP data using httpRead() ...
+}
+</PRE>
+<H3><A NAME="10_103_6">See Also</A></H3>
+<A HREF="#ippWrite"> <CODE>ippWrite()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippSetPort">ippSetPort()</A></H2>
+<H3><A NAME="10_104_1">Usage</A></H3>
+<PRE>
+void
+ippSetPort(int port);
+</PRE>
+<H3><A NAME="10_104_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>port</TD><TD>The port number to use</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_104_3">Description</A></H3>
+<P>The <CODE>ippSetPort()</CODE> function sets the default IPP port
+ number for requests.</P>
+<H3><A NAME="10_104_4">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+#include &lt;cups/ipp.h&gt;
+
+...
+
+ippSetPort(8631);
+</PRE>
+<H3><A NAME="10_104_5">See Also</A></H3>
+<A HREF="#ippPort"> <CODE>ippPort()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippTimeToDate">ippTimeToDate()</A></H2>
+<H3><A NAME="10_105_1">Usage</A></H3>
+<PRE>
+ipp_uchar_t *
+ippTimeToDate(time_t time);
+</PRE>
+<H3><A NAME="10_105_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>time</TD><TD>The UNIX time value</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_105_3">Returns</A></H3>
+<P>A static pointer to an IPP date-time value.</P>
+<H3><A NAME="10_105_4">Description</A></H3>
+<P>The <CODE>ippTimeToDate()</CODE> function converts a UNIX time to an
+ IPP date-time value.</P>
+<H3><A NAME="10_105_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+ipp_uchar_t *date;
+
+date = ippTimeToDate(time(NULL));
+</PRE>
+<H3><A NAME="10_105_6">See Also</A></H3>
+<A HREF="#ippDateToTime"> <CODE>ippDateToTime()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ippWrite">ippWrite()</A></H2>
+<H3><A NAME="10_106_1">Usage</A></H3>
+<PRE>
+ipp_state_t
+ippWrite(http_t *http,
+ ipp_t *ipp);
+</PRE>
+<H3><A NAME="10_106_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>http</TD><TD>The HTTP connection</TD></TR>
+<TR><TD>ipp</TD><TD>The IPP request or response</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_106_3">Returns</A></H3>
+<P>The current write state.</P>
+<H3><A NAME="10_106_4">Description</A></H3>
+<P>The <CODE>ippWrite()</CODE> function writes IPP attributes to the
+ specified HTTP connection. Programs should continue calling <CODE>
+ippWrite()</CODE> until <CODE>IPP_ERROR</CODE> or <CODE>IPP_DATA</CODE>
+ is returned.</P>
+<H3><A NAME="10_106_5">Example</A></H3>
+<PRE>
+#include &lt;cups/http.h&gt;
+#include &lt;cups/ipp.h&gt;
+
+http_t *http;
+ipp_t *ipp;
+ipp_state_t status;
+
+ipp = ippNew();
+... add attributes ...
+
+while ((status = ippWrite(http, ipp)) != IPP_ERROR)
+ if (status == IPP_DATA)
+ break;
+
+if (status == IPP_DATA)
+{
+ ... read additional non-IPP data using httpWrite() ...
+}
+</PRE>
+<H3><A NAME="10_106_6">See Also</A></H3>
+<A HREF="#ippRead"> <CODE>ippRead()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdClose">ppdClose()</A></H2>
+<H3><A NAME="10_107_1">Usage</A></H3>
+<PRE>
+void
+ppdClose(ppd_file_t *ppd);
+</PRE>
+<H3><A NAME="10_107_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_107_3">Description</A></H3>
+<P>The <CODE>ppdClose()</CODE> function frees all memory associated with
+ the PPD file.</P>
+<H3><A NAME="10_107_4">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+
+ppdClose(ppd);
+</PRE>
+<H3><A NAME="10_107_5">See Also</A></H3>
+<A HREF="#ppdOpen"> <CODE>ppdOpen()</CODE></A>,<A HREF="#ppdOpenFd"> <CODE>
+ppdOpenFd()</CODE></A>,<A HREF="#ppdOpenFile"> <CODE>ppdOpenFile()</CODE>
+</A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdCollect">ppdCollect()</A></H2>
+<H3><A NAME="10_108_1">Usage</A></H3>
+<PRE>
+int
+ppdCollect(ppd_file_t *ppd,
+ ppd_section_t section,
+ ppd_choice_t ***choices);
+</PRE>
+<H3><A NAME="10_108_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file.</TD></TR>
+<TR><TD>section</TD><TD>The document section to collect.</TD></TR>
+<TR><TD>choices</TD><TD>The array of option choices that are marked.</TD>
+</TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_108_3">Returns</A></H3>
+<P>The number of options collected.</P>
+<H3><A NAME="10_108_4">Description</A></H3>
+<P><CODE>ppdCollect()</CODE> collects all of the marked options in the
+ specified section, sorts them by their order dependency values, and
+ returns an array that can be used to emit option commands in the proper
+ order. It is normally used by the <CODE>ppdEmit*()</CODE> functions.</P>
+<H3><A NAME="10_108_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+<A HREF="#ppd_file_t">ppd_file_t</A> *ppd;
+int num_choices;
+<A HREF="#ppd_choice_t">ppd_choice_t</A> **choices;
+
+...
+
+num_choices = ppdCollect(ppd, PPD_ORDER_JCL, &amp;choices);
+</PRE>
+<H3><A NAME="10_108_6">See Also</A></H3>
+<P><A HREF="#ppdEmit"> <CODE>ppdEmit()</CODE></A>,<A HREF="#ppdEmitFd"> <CODE>
+ppdEmitFd()</CODE></A>,<A HREF="#ppdEmitJCL"> <CODE>ppdEmitJCL()</CODE></A>
+<!-- NEW PAGE -->
+
+</P>
+<H2><A NAME="ppdConflicts">ppdConflicts()</A></H2>
+<H3><A NAME="10_109_1">Usage</A></H3>
+<PRE>
+int
+ppdConflicts(ppd_file_t *ppd);
+</PRE>
+<H3><A NAME="10_109_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_109_3">Returns</A></H3>
+<P>The number of option conflicts in the file.</P>
+<H3><A NAME="10_109_4">Description</A></H3>
+<P>The <CODE>ppdConflicts()</CODE> function returns the number of
+ conflicts with the currently selected options.</P>
+<H3><A NAME="10_109_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+
+printf(&quot;%d conflicts\n&quot;, ppdConflicts(ppd));
+</PRE>
+<H3><A NAME="10_109_6">See Also</A></H3>
+<A HREF="#cupsMarkOptions"> <CODE>cupsMarkOptions()</CODE></A>,<A HREF="#ppdIsMarked">
+ <CODE>ppdIsMarked()</CODE></A>,<A HREF="#ppdMarkDefaults"> <CODE>
+ppdMarkDefaults()</CODE></A>,<A HREF="#ppdMarkOption"> <CODE>
+ppdMarkOption()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdEmit">ppdEmit()</A></H2>
+<H3><A NAME="10_110_1">Usage</A></H3>
+<PRE>
+int
+ppdEmit(ppd_file_t *ppd,
+ FILE *file,
+ ppd_section_t section);
+</PRE>
+<H3><A NAME="10_110_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+<TR><TD>file</TD><TD>The file to write to</TD></TR>
+<TR><TD>section</TD><TD>The option section to write</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_110_3">Returns</A></H3>
+<P>0 on success, -1 on error.</P>
+<H3><A NAME="10_110_4">Description</A></H3>
+<P>The <CODE>ppdEmit()</CODE> function sends printer-specific option
+ commands to the specified file.</P>
+<H3><A NAME="10_110_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+
+ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+</PRE>
+<H3><A NAME="10_110_6">See Also</A></H3>
+<A HREF="#ppdEmitFd"> <CODE>ppdEmitFd()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdEmitFd">ppdEmitFd()</A></H2>
+<H3><A NAME="10_111_1">Usage</A></H3>
+<PRE>
+int
+ppdEmitFd(ppd_file_t *ppd,
+ int fd,
+ ppd_section_t section);
+</PRE>
+<H3><A NAME="10_111_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+<TR><TD>fd</TD><TD>The file descriptor to write to</TD></TR>
+<TR><TD>section</TD><TD>The option section to write</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_111_3">Returns</A></H3>
+<P>0 on success, -1 on error.</P>
+<H3><A NAME="10_111_4">Description</A></H3>
+<P>The <CODE>ppdEmitFd()</CODE> function sends printer-specific option
+ commands to the specified file descriptor.</P>
+<H3><A NAME="10_111_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+
+ppdEmitFd(ppd, 1, PPD_ORDER_PAGE);
+</PRE>
+<H3><A NAME="10_111_6">See Also</A></H3>
+<A HREF="#ppdEmit"> <CODE>ppdEmit()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdFindChoice">ppdFindChoice()</A></H2>
+<H3><A NAME="10_112_1">Usage</A></H3>
+<PRE>
+ppd_choice_t *
+ppdFindChoice(ppd_option_t *option,
+ const char *choice);
+</PRE>
+<H3><A NAME="10_112_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>option</TD><TD>A pointer to the option</TD></TR>
+<TR><TD>choice</TD><TD>The name of the choice</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_112_3">Returns</A></H3>
+<P>A pointer to the choice data or NULL if the choice does not exist.</P>
+<H3><A NAME="10_112_4">Description</A></H3>
+<P>The <CODE>ppdFindChoice()</CODE> function returns a pointer to the
+ choice data for the specified option.</P>
+<H3><A NAME="10_112_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+ppd_option_t *option;
+ppd_choice_t *choice;
+
+option = ppdFindOption(ppd, &quot;PageSize&quot;);
+choice = ppdFindChoice(option, &quot;Letter&quot;);
+</PRE>
+<H3><A NAME="10_112_6">See Also</A></H3>
+<A HREF="#ppdFindMarkedChoice"> <CODE>ppdFindMarkedChoice()</CODE></A>,<A
+HREF="#ppdFindOption"> <CODE>ppdFindOption()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdFindMarkedChoice">ppdFindMarkedChoice()</A></H2>
+<H3><A NAME="10_113_1">Usage</A></H3>
+<PRE>
+ppd_choice_t *
+ppdFindMarkedChoice(ppd_file_t *ppd,
+ const char *keyword);
+</PRE>
+<H3><A NAME="10_113_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+<TR><TD>keyword</TD><TD>The name of the option</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_113_3">Returns</A></H3>
+<P>A pointer to the choice data or NULL if the choice does not exist or
+ is not marked.</P>
+<H3><A NAME="10_113_4">Description</A></H3>
+<P>The <CODE>ppdFindMarkedChoice()</CODE> function returns a pointer to
+ the marked choice data for the specified option.</P>
+<H3><A NAME="10_113_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+ppd_choice_t *choice;
+
+choice = ppdFindMarkedChoice(ppd, &quot;PageSize&quot;);
+</PRE>
+<H3><A NAME="10_113_6">See Also</A></H3>
+<A HREF="#ppdFindChoice"> <CODE>ppdFindChoice()</CODE></A>,<A HREF="#ppdFindOption">
+ <CODE>ppdFindOption()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdFindOption">ppdFindOption()</A></H2>
+<H3><A NAME="10_114_1">Usage</A></H3>
+<PRE>
+ppd_option_t *
+ppdFindOption(ppd_file_t *ppd,
+ const char *keyword);
+</PRE>
+<H3><A NAME="10_114_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+<TR><TD>keyword</TD><TD>The name of the option</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_114_3">Returns</A></H3>
+<P>A pointer to the option data or NULL if the option does not exist.</P>
+<H3><A NAME="10_114_4">Description</A></H3>
+<P>The <CODE>ppdFindOption()</CODE> function returns a pointer to the
+ option data for the specified option.</P>
+<H3><A NAME="10_114_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+ppd_option_t *option;
+
+option = ppdFindOption(ppd, &quot;PageSize&quot;);
+</PRE>
+<H3><A NAME="10_114_6">See Also</A></H3>
+<A HREF="#ppdFindChoice"> <CODE>ppdFindChoice()</CODE></A>,<A HREF="#ppdFindMarkedChoice">
+ <CODE>ppdFindMarkedChoice()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdIsMarked">ppdIsMarked()</A></H2>
+<H3><A NAME="10_115_1">Usage</A></H3>
+<PRE>
+int
+ppdIsMarked(ppd_file_t *ppd,
+ const char *keyword,
+ const char *choice);
+</PRE>
+<H3><A NAME="10_115_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+<TR><TD>keyword</TD><TD>The name of the option</TD></TR>
+<TR><TD>choice</TD><TD>The name of the option choice</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_115_3">Returns</A></H3>
+<P>1 if the choice is marked, 0 otherwise.</P>
+<H3><A NAME="10_115_4">Description</A></H3>
+<P>The <CODE>ppdIsMarked()</CODE> function returns whether or not the
+ specified option choice is marked.</P>
+<H3><A NAME="10_115_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+
+printf(&quot;Letter size %s selected.\n&quot;,
+ ppdIsMarked(ppd, &quot;PageSize&quot;, &quot;Letter&quot;) ? &quot;is&quot; : &quot;is not&quot;);
+</PRE>
+<H3><A NAME="10_115_6">See Also</A></H3>
+<A HREF="#cupsMarkOptions"> <CODE>cupsMarkOptions()</CODE></A>,<A HREF="#ppdConflicts">
+ <CODE>ppdConflicts()</CODE></A>,<A HREF="#ppdIsMarked"> <CODE>
+ppdIsMarked()</CODE></A>,<A HREF="#ppdMarkDefaults"> <CODE>
+ppdMarkDefaults()</CODE></A>,<A HREF="#ppdMarkOption"> <CODE>
+ppdMarkOption()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdMarkDefaults">ppdMarkDefaults()</A></H2>
+<H3><A NAME="10_116_1">Usage</A></H3>
+<PRE>
+void
+ppdMarkDefaults(ppd_file_t *ppd);
+</PRE>
+<H3><A NAME="10_116_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_116_3">Description</A></H3>
+<P>The <CODE>ppdMarkDefaults()</CODE> function marks all of the default
+ choices in the PPD file.</P>
+<H3><A NAME="10_116_4">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+
+ppdMarkDefaults(ppd);
+</PRE>
+<H3><A NAME="10_116_5">See Also</A></H3>
+<A HREF="#cupsMarkOptions"> <CODE>cupsMarkOptions()</CODE></A>,<A HREF="#ppdConflicts">
+ <CODE>ppdConflicts()</CODE></A>,<A HREF="#ppdIsMarked"> <CODE>
+ppdIsMarked()</CODE></A>,<A HREF="#ppdMarkDefaults"> <CODE>
+ppdMarkDefaults()</CODE></A>,<A HREF="#ppdMarkOption"> <CODE>
+ppdMarkOption()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdMarkOption">ppdMarkOption()</A></H2>
+<H3><A NAME="10_117_1">Usage</A></H3>
+<PRE>
+int
+ppdMarkOption(ppd_file_t *ppd,
+ const char *keyword,
+ const char *choice);
+</PRE>
+<H3><A NAME="10_117_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+<TR><TD>keyword</TD><TD>The name of the option</TD></TR>
+<TR><TD>choice</TD><TD>The name of the choice</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_117_3">Returns</A></H3>
+<P>The number of conflicts in the PPD file.</P>
+<H3><A NAME="10_117_4">Description</A></H3>
+<P>The <CODE>ppdMarkOption()</CODE> function marks the specified option
+ choice.</P>
+<H3><A NAME="10_117_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+
+ppdMarkOption(ppd, &quot;PageSize&quot;, &quot;Letter&quot;);
+</PRE>
+<H3><A NAME="10_117_6">See Also</A></H3>
+<A HREF="#cupsMarkOptions"> <CODE>cupsMarkOptions()</CODE></A>,<A HREF="#ppdConflicts">
+ <CODE>ppdConflicts()</CODE></A>,<A HREF="#ppdIsMarked"> <CODE>
+ppdIsMarked()</CODE></A>,<A HREF="#ppdMarkDefaults"> <CODE>
+ppdMarkDefaults()</CODE></A>,<A HREF="#ppdMarkOption"> <CODE>
+ppdMarkOption()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdOpen">ppdOpen()</A></H2>
+<H3><A NAME="10_118_1">Usage</A></H3>
+<PRE>
+ppd_file_t *
+ppdOpen(FILE *file);
+</PRE>
+<H3><A NAME="10_118_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>file</TD><TD>The file to read from</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_118_3">Returns</A></H3>
+<P>A pointer to a PPD file structure or NULL if the PPD file could not
+ be read.</P>
+<H3><A NAME="10_118_4">Description</A></H3>
+<P>The <CODE>ppdOpen()</CODE> function reads a PPD file from the
+ specified file into memory.</P>
+<H3><A NAME="10_118_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+FILE *file;
+
+file = fopen(&quot;filename.ppd&quot;, &quot;rb&quot;);
+ppd = ppdOpen(file);
+fclose(file);
+</PRE>
+<H3><A NAME="10_118_6">See Also</A></H3>
+<A HREF="#ppdClose"> <CODE>ppdClose()</CODE></A>,<A HREF="#ppdOpenFd"> <CODE>
+ppdOpenFd()</CODE></A>,<A HREF="#ppdOpenFile"> <CODE>ppdOpenFile()</CODE>
+</A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdOpenFd">ppdOpenFd()</A></H2>
+<H3><A NAME="10_119_1">Usage</A></H3>
+<PRE>
+ppd_file_t *
+ppdOpenFd(int fd);
+</PRE>
+<H3><A NAME="10_119_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>fd</TD><TD>The file descriptor to read from</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_119_3">Returns</A></H3>
+<P>A pointer to a PPD file structure or NULL if the PPD file could not
+ be read.</P>
+<H3><A NAME="10_119_4">Description</A></H3>
+<P>The <CODE>ppdOpenFd()</CODE> function reads a PPD file from the
+ specified file descriptor into memory.</P>
+<H3><A NAME="10_119_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+int fd;
+
+fd = open(&quot;filename.ppd&quot;, O_RDONLY);
+ppd = ppdOpenFd(fd);
+close(fd);
+</PRE>
+<H3><A NAME="10_119_6">See Also</A></H3>
+<A HREF="#ppdClose"> <CODE>ppdClose()</CODE></A>,<A HREF="#ppdOpen"> <CODE>
+ppdOpen()</CODE></A>,<A HREF="#ppdOpenFile"> <CODE>ppdOpenFile()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdOpenFile">ppdOpenFile()</A></H2>
+<H3><A NAME="10_120_1">Usage</A></H3>
+<PRE>
+ppd_file_t *
+ppdOpenFile(const char *filename);
+</PRE>
+<H3><A NAME="10_120_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>filename</TD><TD>The name of the file to read from</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_120_3">Returns</A></H3>
+<P>A pointer to a PPD file structure or NULL if the PPD file could not
+ be read.</P>
+<H3><A NAME="10_120_4">Description</A></H3>
+<P>The <CODE>ppdOpenFile()</CODE> function reads a PPD file from the
+ named file into memory.</P>
+<H3><A NAME="10_120_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+
+ppd = ppdOpenFile(&quot;filename.ppd&quot;);
+</PRE>
+<H3><A NAME="10_120_6">See Also</A></H3>
+<A HREF="#ppdClose"> <CODE>ppdClose()</CODE></A>,<A HREF="#ppdOpen"> <CODE>
+ppdOpen()</CODE></A>,<A HREF="#ppdOpenFd"> <CODE>ppdOpenFd()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdPageLength">ppdPageLength()</A></H2>
+<H3><A NAME="10_121_1">Usage</A></H3>
+<PRE>
+float
+ppdPageLength(ppd_file_t *ppd,
+ const char *name);
+</PRE>
+<H3><A NAME="10_121_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+<TR><TD>name</TD><TD>The name of the page size</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_121_3">Returns</A></H3>
+<P>The length of the specified page size in points or 0 if the page size
+ does not exist.</P>
+<H3><A NAME="10_121_4">Description</A></H3>
+<P>The <CODE>ppdPageLength()</CODE> function returns the page length of
+ the specified page size.</P>
+<H3><A NAME="10_121_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+
+printf(&quot;Length = %.0f\n&quot;, ppdPageLength(ppd, &quot;Letter&quot;));
+</PRE>
+<H3><A NAME="10_121_6">See Also</A></H3>
+<A HREF="#ppdPageLength"> <CODE>ppdPageLength()</CODE></A>,<A HREF="#ppdPageSize">
+ <CODE>ppdPageSize()</CODE></A>,<A HREF="#ppdPageWidth"> <CODE>
+ppdPageWidth()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdPageSize">ppdPageSize()</A></H2>
+<H3><A NAME="10_122_1">Usage</A></H3>
+<PRE>
+ppd_size_t *
+ppdPageSize(ppd_file_t *ppd,
+ const char *name);
+</PRE>
+<H3><A NAME="10_122_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+<TR><TD>name</TD><TD>The name of the page size</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_122_3">Returns</A></H3>
+<P>A pointer to the page size record of the specified page size in
+ points or NULL if the page size does not exist.</P>
+<H3><A NAME="10_122_4">Description</A></H3>
+<P>The <CODE>ppdPageSize()</CODE> function returns the page size record
+ for the specified page size.</P>
+<H3><A NAME="10_122_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+ppd_size_t *size;
+
+size = ppdPageSize(ppd, &quot;Letter&quot;);
+if (size != NULL)
+{
+ printf(&quot; Width = %.0f\n&quot;, size-&gt;width);
+ printf(&quot;Length = %.0f\n&quot;, size-&gt;length);
+ printf(&quot; Left = %.0f\n&quot;, size-&gt;left);
+ printf(&quot; Right = %.0f\n&quot;, size-&gt;right);
+ printf(&quot;Bottom = %.0f\n&quot;, size-&gt;bottom);
+ printf(&quot; Top = %.0f\n&quot;, size-&gt;top);
+}
+</PRE>
+<H3><A NAME="10_122_6">See Also</A></H3>
+<A HREF="#ppdPageLength"> <CODE>ppdPageLength()</CODE></A>,<A HREF="#ppdPageWidth">
+ <CODE>ppdPageWidth()</CODE></A>
+<!-- NEW PAGE -->
+
+<H2><A NAME="ppdPageWidth">ppdPageWidth()</A></H2>
+<H3><A NAME="10_123_1">Usage</A></H3>
+<PRE>
+float
+ppdPageWidth(ppd_file_t *ppd,
+ const char *name);
+</PRE>
+<H3><A NAME="10_123_2">Arguments</A></H3>
+<CENTER>
+<TABLE BORDER WIDTH="80%">
+<TR><TH>Argument</TH><TH>Description</TH></TR>
+<TR><TD>ppd</TD><TD>The PPD file</TD></TR>
+<TR><TD>name</TD><TD>The name of the page size</TD></TR>
+</TABLE>
+</CENTER>
+<H3><A NAME="10_123_3">Returns</A></H3>
+<P>The width of the specified page size in points or 0 if the page size
+ does not exist.</P>
+<H3><A NAME="10_123_4">Description</A></H3>
+<P>The <CODE>ppdPageWidth()</CODE> function returns the page width of
+ the specified page size.</P>
+<H3><A NAME="10_123_5">Example</A></H3>
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+ppd_file_t *ppd;
+
+printf(&quot;Width = %.0f\n&quot;, ppdPageWidth(ppd, &quot;Letter&quot;));
+</PRE>
+<H3><A NAME="10_123_6">See Also</A></H3>
+<A HREF="#ppdPageLength"> <CODE>ppdPageLength()</CODE></A>,<A HREF="#ppdPageSize">
+ <CODE>ppdPageSize()</CODE></A></BODY>
+</HTML>
diff --git a/doc/spm.pdf b/doc/spm.pdf
new file mode 100644
index 000000000..329605196
--- /dev/null
+++ b/doc/spm.pdf
Binary files differ
diff --git a/doc/spm.shtml b/doc/spm.shtml
new file mode 100644
index 000000000..5a5e19d99
--- /dev/null
+++ b/doc/spm.shtml
@@ -0,0 +1,10202 @@
+<HTML>
+<HEAD>
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-SPM-1.1.16">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Software Programmers Manual</TITLE>
+</HEAD>
+<BODY>
+
+<H1 ALIGN="RIGHT">Preface</H1>
+
+<P>This software programmers manual provides software
+programming information for the Common UNIX Printing System
+("CUPS") Version 1.1.16.
+
+<EMBED SRC="system-overview.shtml">
+
+<!-- NEED 2in -->
+<H2>Document Overview</H2>
+
+<P>This software programmers manual is organized into the following sections:
+
+<UL>
+ <LI><A HREF="#OVERVIEW">1 - Printing System Overview</A>
+ <LI><A HREF="#CUPS_API">2 - The CUPS API</A>
+ <LI><A HREF="#WRITING_FILTERS">3 - Writing Filters</A>
+ <LI><A HREF="#WRITING_DRIVERS">4 - Writing Printer Drivers</A>
+ <LI><A HREF="#WRITING_BACKENDS">5 - Writing Backends</A>
+ <LI><A HREF="#LICENSE">A - Software License Agreement</A>
+ <LI><A HREF="#CONSTANTS">B - Constants</A>
+ <LI><A HREF="#STRUCTURES">C - Structures</A>
+ <LI><A HREF="#FUNCTIONS">D - Functions</A>
+</UL>
+
+<H2>Notation Conventions</H2>
+
+<P>Various font and syntax conventions are used in this guide. Examples and
+their meanings and uses are explained below:
+
+<CENTER><TABLE WIDTH="80%">
+<TR>
+ <TH>Example</TH>
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+ <TH>Description</TH>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD><CODE>lpstat</CODE><BR>
+ <CODE>lpstat(1)</CODE></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>The names of commands; the first mention of a command or
+ function in a chapter is followed by a manual page section
+ number.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD><VAR>/var</VAR><BR>
+ <VAR>/usr/share/cups/data/testprint.ps</VAR></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>File and directory names.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD NOWRAP><TT>Request ID is Printer-123</TT></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Screen output.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD NOWRAP><KBD>lp -d printer filename ENTER</KBD></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Literal user input; special keys like <KBD>ENTER</KBD> are
+ in ALL CAPS.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD>12.3</TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Numbers in the text are written using the period (.) to indicate
+ the decimal point.</TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H2>Abbreviations</H2>
+
+The following abbreviations are used throughout this manual:
+
+<UL>
+<DL>
+
+ <DT>kb
+ <DD>Kilobytes, or 1024 bytes<BR>&nbsp;
+
+ <DT>Mb
+ <DD>Megabytes, or 1048576 bytes<BR>&nbsp;
+
+ <DT>Gb
+ <DD>Gigabytes, or 1073741824 bytes<BR>&nbsp;
+
+</DL>
+</UL>
+
+<H2>Other References</H2>
+
+<UL>
+<DL>
+
+ <DT>CUPS Software Administrators Manual
+
+ <DD>An administration guide for the CUPS software.<BR>&nbsp;
+
+ <DT>CUPS Software Users Manual
+
+ <DD>An end-user guide for using the CUPS software.<BR>&nbsp;
+
+</DL>
+</UL>
+
+
+<EMBED SRC="printing-overview.shtml">
+
+
+<H1 ALIGN="RIGHT"><A NAME="CUPS_API">2 - The CUPS API</A></H1>
+
+<P>This chapter describes the CUPS Application Programmers Interface ("API").
+
+<H2>The CUPS API Library</H2>
+
+<P>The CUPS library provides a whole collection of interfaces needed to
+support the internal needs of the CUPS software as well as the needs of
+applications, filters, printer drivers, and backends.
+
+<P>Unlike the rest of CUPS, the CUPS API library is provided under the
+GNU Library General Public License. This means that you can use the
+CUPS API library in both proprietary and open-source programs.
+
+<P>Programs that use the CUPS API library typically will include the
+<CODE>&lt;cups/cups.h&gt;</CODE> header file:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+jobid = cupsPrintFile("myprinter", "filename.ps", "title",
+ num_options, options);
+</PRE></UL>
+
+<P>Use the <CODE>-lcups</CODE> compiler option when linking to the CUPS API
+library:
+
+<UL><PRE>
+<B>cc -o program program.c -lcups ENTER</B>
+</PRE></UL>
+
+<P>Additional options and libraries may be required depending on the
+operating system and the location of the CUPS API library.
+
+<H3>Detecting the CUPS API Library in GNU Autoconf</H3>
+
+<P>GNU autoconf is a popular configuration tool used by many programs.
+Add the following lines to your <VAR>configure.in</VAR> file to check
+for the CUPS API library in your configuration script:
+
+<UL><PRE>
+AC_CHECK_LIB(socket,socket,
+if test "$uname" != "IRIX"; then
+ LIBS="-lsocket $LIBS"
+else
+ echo "Not using -lsocket since you are running IRIX."
+fi)
+AC_CHECK_LIB(nsl,gethostbyaddr,
+if test "$uname" != "IRIX"; then
+ LIBS="-lnsl $LIBS"
+else
+ echo "Not using -lnsl since you are running IRIX."
+fi)
+
+AC_CHECK_LIB(cups,httpConnect)
+</PRE></UL>
+
+<H2>Printing Services</H2>
+
+<P>The CUPS API library provides some basic printing services for applications
+that need to print files.
+
+<H3>Include Files</H3>
+
+<P>The include file used by all of these functions is
+<CODE>&lt;cups/cups.h&gt;</CODE>:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+</PRE></UL>
+
+<H3>Printing a File</H3>
+
+<P>The CUPS API provides two functions for printing files. The first is
+<CODE>cupsPrintFile</CODE> which prints a single named file:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int jobid;
+
+...
+
+jobid = cupsPrintFile("<I>name</I>", "<I>filename</I>", "<I>title</I>", 0, NULL);
+</PRE></UL>
+
+<P>The <CODE>name</CODE> string is the name of the printer or class to
+print to. The <CODE>filename</CODE> string is the name of the file to
+print. The <CODE>title</CODE> string is the name of the print job, e.g.
+"Acme Word Document".
+
+<P>The return value is a unique ID number for the print job or 0 if there
+was an error.
+
+<H3>Printing Multiple Files</H3>
+
+<P>The second printing function is <CODE>cupsPrintFiles</CODE>:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int jobid;
+int num_files;
+const char *files[100];
+...
+
+jobid = cupsPrintFiles("name", <I>num_files</I>, <I>files</I>, "title", 0, NULL);
+</PRE></UL>
+
+<P>Instead of passing a filename string as with <CODE>cupsPrintFile()</CODE>
+you pass a file count (<CODE>num_files</CODE>) and filename pointer array
+(<CODE>files</CODE>) for each file that you want to print.
+
+<P>As with <CODE>cupsPrintFile()</CODE> the return value is a unique ID for
+the print job.
+
+<H3>Cancelling Jobs</H3>
+
+<P>The <CODE>cupsCancelJob()</CODE> function cancels a queued print job:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int jobid;
+int status;
+...
+
+status = cupsCancelJob("<I>name</I>", <I>jobid</I>);
+</PRE></UL>
+
+<P>The <CODE>name</CODE> string specifies the destination and is used
+to determine the server to send the request to. The <CODE>jobid</CODE>
+value is the integer returned from a previous <CODE>cupsPrintFile()</CODE>
+or <CODE>cupsPrintFiles()</CODE> call.
+
+<P><CODE>cupsCancelJob()</CODE> returns <CODE>1</CODE> if the job was
+successfully cancelled and <CODE>0</CODE> if there was an error.
+
+<H3>Getting the Available Printers and Classes</H3>
+
+<P>The <CODE>cupsGetDests()</CODE> function can be used to get a list
+of the available printers, classes, and instances that a user has defined:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int num_dests;
+cups_dest_t *dests;
+
+...
+
+num_dests = cupsGetDests(&amp;dests);
+</PRE></UL>
+
+<P>Each destination is stored in a <CODE>cups_dest_t</CODE> structure which
+defines the printer or class name, the instance name (if any), if it is the
+default destination, and the default options the user has defined for the
+destination:
+
+<UL><PRE>
+typedef struct /**** Destination ****/
+{
+ char *name, /* Printer or class name */
+ *instance; /* Local instance name or NULL */
+ int is_default; /* Is this printer the default? */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+} cups_dest_t;
+</PRE></UL>
+
+<P>The destinations are sorted by name and instance for your convenience.
+Once you have the list of available destinations, you can lookup a specific
+destination using the <CODE>cupsGetDest()</CODE> function:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int num_dests;
+cups_dest_t *dests;
+cups_dest_t *mydest;
+
+...
+
+mydest = cupsGetDest("<I>name</I>", "<I>instance</I>", num_dests, dests);
+</PRE></UL>
+
+<P>The <CODE>name</CODE> string is the printer or class name. You can pass
+a value of <CODE>NULL</CODE> to get the default destination.
+
+<P>The <CODE>instance</CODE> string is the user-defined instance name. Pass
+<CODE>NULL</CODE> to select the default instance, e.g. "name" instead of
+"name/instance".
+
+<H3>Printing with Options</H3>
+
+<P>All of the previous printing examples have passed <CODE>0</CODE> and
+<CODE>NULL</CODE> for the last two arguments to the <CODE>cupsPrintFile()</CODE>
+and <CODE>cupsPrintFiles()</CODE> functions. These last two arguments are the
+number of options and a pointer to the option array:
+
+<UL><PRE>
+int cupsPrintFile(const char *name, const char *filename, const char *title,
+ int num_options, cups_option_t *options);
+int cupsPrintFiles(const char *name, int num_files, const char **files,
+ const char *title, int num_options,
+ cups_option_t *options);
+</PRE></UL>
+
+<P>The <CODE>cups_option_t</CODE> structure holds each option and its value.
+These are converted as needed and passed to the CUPS server when printing a
+file.
+
+<P>The simplest way of handling options is to use the <CODE>num_options</CODE>
+and <CODE>options</CODE> members of the <CODE>cups_dest_t</CODE>
+structure described earlier:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int jobid;
+int num_dests;
+cups_dest_t *dests;
+cups_dest_t *mydest;
+
+...
+
+mydest = cupsGetDest("<I>name</I>", "<I>instance</I>", num_dests, dests);
+
+jobid = cupsPrintFile(mydest-&gt;name, "filename", "title",
+ mydest-&gt;num_options, mydest-&gt;options);
+</PRE></UL>
+
+<P>This effectively uses the options a user has previous selected without a
+lot of code.
+
+<H3>Setting Printer Options</H3>
+
+<P>Options can also be set by your program using the <CODE>cupsAddOption()</CODE>
+function:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int num_options;
+cups_option_t *options;
+
+...
+
+num_options = 0;
+options = NULL;
+
+...
+
+num_options = cupsAddOption("<I>name</I>", "<I>value</I>", num_options, &amp;options);
+num_options = cupsAddOption("<I>name</I>", "<I>value</I>", num_options, &amp;options);
+num_options = cupsAddOption("<I>name</I>", "<I>value</I>", num_options, &amp;options);
+num_options = cupsAddOption("<I>name</I>", "<I>value</I>", num_options, &amp;options);
+</PRE></UL>
+
+<P>The <CODE>name</CODE> string is the name of the option, and the
+<CODE>value</CODE> string is the value for that option.
+
+<P>Each call to <CODE>cupsAddOption()</CODE> returns the new number of
+options. Since adding two options with the same name overwrites the
+first value with the second, do not assume that calling
+<CODE>cupsAddOptions()</CODE> 20 times will result in 20 options.
+
+<P>Call <CODE>cupsFreeOptions</CODE> once you are done using the options:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int num_options;
+cups_option_t *options;
+
+...
+
+cupsFreeOptions(num_options, options);
+</PRE></UL>
+
+<H3>Getting Errors</H3>
+
+<P>If any of the CUPS API printing functions returns an error, the reason for
+that error can be found by calling <CODE>cupsLastError()</CODE> and
+<CODE>cupsErrorString()</CODE>. <CODE>cupsLastError()</CODE> returns the
+last IPP error code that was encountered. <CODE>cupsErrorString()</CODE>
+converts the error code to a localized message string suitable for
+presentation to the user:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+int jobid;
+
+...
+
+if (jobid == 0)
+ puts(cupsErrorString(cupsLastError()));
+</PRE></UL>
+
+<H3>Passwords and Authentication</H3>
+
+<P>CUPS supports authentication of any request, including
+submission of print jobs. The default mechanism for getting the
+username and password is to use the login user and a password
+from the console.
+
+<P>To support other types of applications, in particular
+Graphical User Interfaces ("GUIs"), the CUPS API provides
+functions to set the default username and to register a callback
+function that returns a password string.
+
+<P>The <A HREF="#cupsSetPasswordCB"><CODE>cupsSetPasswordCB()</CODE></A>
+function is used to set a password callback in your program. Only one
+function can be used at any time.
+
+<P>The <A HREF="#cupsSetUser"><CODE>cupsSetUser()</CODE></A> function sets
+the current username for authentication. This function can be called by
+your password callback function to change the current username as needed.
+
+<P>The following example shows a simple password callback that gets a
+username and password from the user:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+const char *
+my_password_cb(const char *prompt)
+{
+ char user[65];
+
+
+ puts(prompt);
+
+ /* Get a username from the user */
+ printf("Username: ");
+ if (fgets(user, sizeof(user), stdin) == NULL)
+ return (NULL);
+
+ /* Strip the newline from the string and set the user */
+ user[strlen(user) - 1] = '\0';
+
+ cupsSetUser(user);
+
+ /* Use getpass() to ask for the password... */
+ return (getpass("Password: "));
+}
+
+...
+
+cupsSetPasswordCB(my_password_cb);
+</PRE></UL>
+
+<P>Similarly, a GUI interface could display the prompt string in a
+window with input fields for the username and password. The username
+should probably default to the value of
+<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A> to make things easier
+on the user.
+
+<H2>PPD Services</H2>
+
+<P>CUPS includes functions to access and manipulate PostScript Printer
+Description ("PPD") files that are used with the printer drivers in CUPS.
+
+<P>Each PPD file enumerates the available features provided by a
+printer, including conflict information for specific options (e.g.
+can't duplex output on envelopes.)
+
+<H3>Include Files</H3>
+
+<P>Include the <CODE>&lt;cups/ppd.h&gt;</CODE> header file to use the PPD
+functions:
+
+<UL><PRE>
+#include &lt;cups/ppd.h&gt;
+</PRE></UL>
+
+<P>This header file is also included by the
+<CODE>&lt;cups/cups.h&gt;</CODE> header file.
+
+<H3>Getting a PPD File for a Printer</H3>
+
+<P>The <CODE>cupsGetPPD()</CODE> function retrieves the PPD file for the
+named printer or class:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+const char *filename;
+
+filename = cupsGetPPD("<I>name</I>");
+</PRE></UL>
+
+<P>The <CODE>name</CODE> string is the name of the printer or class, including
+the remote server name as appropriate (e.g. "printer@server".)
+
+<P>The return value is a pointer to a filename in static storage; this value
+is overwritten with each call to <CODE>cupsGetPPD()</CODE>. If the printer
+or class does not exist, a <CODE>NULL</CODE> pointer will be returned.
+
+<H3>Loading a PPD File</H3>
+
+<P>The <CODE>ppdOpenFile()</CODE> function "opens" a PPD file and loads it
+into memory:
+
+<UL><PRE>
+#include &lt;cups/ppd.h&gt;
+
+...
+
+ppd_file_t *ppd;
+
+ppd = ppdOpenFile("<I>filename</I>");
+</PRE></UL>
+
+<P>The <CODE>filename</CODE> string is the name of the file to load, such as
+the value returned by the <CODE>cupsGetPPD()</CODE> function.
+
+<P>The return value is a pointer to a structure describing the contents of the
+PPD file or NULL if the PPD file could not be read.
+
+<H3>Freeing PPD File Information</H3>
+
+<P>Once you are done using a PPD file, call the <CODE>ppdClose()</CODE> function
+to free all memory that has been used:
+
+<UL><PRE>
+#include &lt;cups/ppd.h&gt;
+
+...
+
+ppd_file_t *ppd;
+
+...
+
+ppdClose(ppd);
+</PRE></UL>
+
+<H3>The PPD File Structure</H3>
+
+<P>Each PPD file contains a number of capability attributes, printer options,
+and conflict definitions. The page size options also include the physical
+margins for the printer and the minimum and maximum sizes for the printer.
+All of this information is stored in the <CODE>ppd_file_t</CODE> structure.
+
+<H4>Capabilities</H4>
+
+<P>Each PPD file contains a number of informational attributes that
+describe the capabilities of the printer. These are provided in the
+<CODE>ppd_file_t</CODE> structure in the following members:
+
+<CENTER><TABLE WIDTH="80%" BORDER="1">
+<TR>
+ <TH>Member</TH>
+ <TH>Type</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD><CODE>accurate_screens</CODE></TD>
+ <TD><CODE>int</CODE></TD>
+ <TD>1 = supports accurate screens</TD>
+</TR>
+<TR>
+ <TD><CODE>color_device</CODE></TD>
+ <TD><CODE>int</CODE></TD>
+ <TD>1 = color device</TD>
+</TR>
+<TR>
+ <TD><CODE>colorspace</CODE></TD>
+ <TD><CODE>ppd_cs_t</CODE></TD>
+ <TD>Default colorspace: PPD_CS_CMYK, PPD_CS_CMY, PPD_CS_GRAY,
+ PPD_CS_RGB, PPD_CS_RGBK, PPD_CS_N</TD>
+</TR>
+<TR>
+ <TD><CODE>contone_only</CODE></TD>
+ <TD><CODE>int</CODE></TD>
+ <TD>1 = printer is continuous tone only</TD>
+</TR>
+<TR>
+ <TD><CODE>num_emulations<BR>
+ emulations</CODE></TD>
+ <TD><CODE>int<BR>
+ ppd_emul_t *</CODE></TD>
+ <TD>Emulations supported by the printer</TD>
+</TR>
+<TR>
+ <TD><CODE>flip_duplex</CODE></TD>
+ <TD><CODE>int</CODE></TD>
+ <TD>1 = need to flip odd pages when duplexing</TD>
+</TR>
+<TR>
+ <TD><CODE>num_fonts<BR>
+ fonts</CODE></TD>
+ <TD><CODE>int<BR>
+ char **</CODE></TD>
+ <TD>The fonts available on the printer.</TD>
+</TR>
+<TR>
+ <TD><CODE>jcl_begin<BR>
+ jcl_ps<BR>
+ jcl_end</CODE></TD>
+ <TD><CODE>char *</CODE></TD>
+ <TD>Job Control Language commands for PostScript output</TD>
+</TR>
+<TR>
+ <TD><CODE>landscape</CODE></TD>
+ <TD><CODE>int</CODE></TD>
+ <TD>Landscape orientation, -90 or 90 degrees</TD>
+</TR>
+<TR>
+ <TD><CODE>lang_encoding</CODE></TD>
+ <TD><CODE>char *</CODE></TD>
+ <TD>The character used for the option strings</TD>
+</TR>
+<TR>
+ <TD><CODE>lang_version</CODE></TD>
+ <TD><CODE>char *</CODE></TD>
+ <TD>The language used for the options strings (English, French, etc.)</TD>
+</TR>
+<TR>
+ <TD><CODE>language_level</CODE></TD>
+ <TD><CODE>int</CODE></TD>
+ <TD>PostScript language level, 1 to 3</TD>
+</TR>
+<TR>
+ <TD><CODE>manual_copies</CODE></TD>
+ <TD><CODE>int</CODE></TD>
+ <TD>1 = Copies are done manually</TD>
+</TR>
+<TR>
+ <TD><CODE>model_number</CODE></TD>
+ <TD><CODE>int</CODE></TD>
+ <TD>Driver-specific model number.</TD>
+</TR>
+<TR>
+ <TD><CODE>patches</CODE></TD>
+ <TD><CODE>char *</CODE></TD>
+ <TD>Patch commands to send to the printer</TD>
+</TR>
+<TR>
+ <TD><CODE>manufacturer</CODE></TD>
+ <TD><CODE>char *</CODE></TD>
+ <TD>The Manufacturer attribute from the PPD file, if any</TD>
+</TR>
+<TR>
+ <TD><CODE>modelname</CODE></TD>
+ <TD><CODE>char *</CODE></TD>
+ <TD>The ModelName attribute from the PPD file</TD>
+</TR>
+<TR>
+ <TD><CODE>nickname</CODE></TD>
+ <TD><CODE>char *</CODE></TD>
+ <TD>The NickName attribute from the PPD file, if any</TD>
+</TR>
+<TR>
+ <TD><CODE>product</CODE></TD>
+ <TD><CODE>char *</CODE></TD>
+ <TD>The Product attribute from the PPD file, if any</TD>
+</TR>
+<TR>
+ <TD><CODE>shortnickname</CODE></TD>
+ <TD><CODE>char *</CODE></TD>
+ <TD>The ShortNickName attribute from the PPD file, if any</TD>
+</TR>
+<TR>
+ <TD><CODE>throughput</CODE></TD>
+ <TD><CODE>int</CODE></TD>
+ <TD>Number of pages per minute</TD>
+</TR>
+<TR>
+ <TD><CODE>ttrasterizer</CODE></TD>
+ <TD><CODE>char *</CODE></TD>
+ <TD>The TruType font rasterizer (Type42)</TD>
+</TR>
+<TR>
+ <TD><CODE>variable_sizes</CODE></TD>
+ <TD><CODE>int</CODE></TD>
+ <TD>1 = supports variable sizes</TD>
+</TR>
+</TABLE></CENTER>
+
+<H4>Options and Groups</H4>
+
+<P>PPD files support multiple options, which are stored in
+<CODE>ppd_option_t</CODE> and <CODE>ppd_choice_t</CODE> structures by
+the PPD functions.
+
+<P>Each option in turn is associated with a group
+stored in the <CODE>ppd_group_t</CODE> structure. Groups can be
+specified in the PPD file; if an option is not associated with a group
+then it is put in a "General" or "Extra" group depending on the option.
+
+<P>Groups can also have sub-groups; CUPS currently limits the depth of
+sub-groups to 1 level to reduce programming complexity.
+
+<H4>Conflicts</H4>
+
+<P>PPD files support specification of conflict conditions between
+different options. Conflicts are stored in <CODE>ppd_conflict_t</CODE>
+structures which specify the options that conflict with each other.
+
+<H4>Page Sizes</H4>
+
+<P>PPD files specify all of the available pages sizes and the physical
+margins associated with them. These sizes are stored in
+<CODE>ppd_size_t</CODE> structures and are available in the
+<CODE>num_sizes</CODE> and <CODE>sizes</CODE> members of the
+<CODE>ppd_file_t</CODE> structure. You can lookup a particular page size
+with the <CODE>ppdPageWidth()</CODE>, <CODE>ppdPageLength()</CODE>, and
+<CODE>ppdPageSize()</CODE> functions:
+
+<UL><PRE>
+#include &lt;cups/ppd.h&gt;
+
+...
+
+ppd_file_t *ppd;
+ppd_size_t *size;
+float width;
+float length;
+
+...
+
+size = ppdPageSize(ppd, "<I>size</I>");
+width = ppdPageWidth(ppd, "<I>size</I>");
+length = ppdPageLength(ppd, "<I>size</I>");
+</PRE></UL>
+
+<P>The <CODE>size</CODE> string is the named page size option. The
+width and length are in points; there are 72 points per inch. The
+<CODE>ppd_size_t</CODE> structure contains the width, length, and
+margin information:
+
+<UL><PRE>
+typedef struct /**** Page Sizes ****/
+{
+ int marked; /* Page size selected? */
+ char name[41]; /* Media size option */
+ float width, /* Width of media in points */
+ length, /* Length of media in points */
+ left, /* Left printable margin in points */
+ bottom, /* Bottom printable margin in points */
+ right, /* Right printable margin in points */
+ top; /* Top printable margin in points */
+} ppd_size_t;
+</PRE></UL>
+
+<H4>Custom Page Sizes</H4>
+
+<P>Besides the standard page sizes listed in a PPD file, some printers
+support variable or custom page sizes. If <CODE>variables_sizes</CODE>
+is non-zero, the <CODE>custom_min</CODE>, <CODE>custom_max</CODE>, and
+<CODE>custom_margins</CODE> members of the <CODE>ppd_file_t</CODE>
+structure define the limits of the variable sizes.
+
+<P>To get the resulting media size, use a page size string of
+<CODE>Custom.<I>width</I>x<I>length</I></CODE>, where <CODE>width</CODE>
+and <CODE>length</CODE> are integer values in points:
+
+<UL><PRE>
+Custom.612x792 [8.5 inches wide, 11 inches long]
+Custom.1224x792 [17 inches wide, 11 inches long]
+</PRE></UL>
+
+<H3>Marking Options</H3>
+
+<P>Before marking any user-defined options, call the <CODE>ppdMarkDefaults()</CODE>
+function to mark the default options from the PPD file:
+
+<UL><PRE>
+#include &lt;cups/ppd.h&gt;
+
+...
+
+ppd_file_t *ppd;
+
+...
+
+ppdMarkDefaults(ppd);
+</PRE></UL>
+
+<P>Then call the <CODE>ppdMarkOption()</CODE> function to mark individual
+options:
+
+<UL><PRE>
+#include &lt;cups/ppd.h&gt;
+
+...
+
+ppd_file_t *ppd;
+int conflicts;
+
+...
+
+conflicts = ppdMarkOption(ppd, "<I>name</I>", "<I>value</I>");
+</PRE></UL>
+
+<P>The <CODE>name</CODE> and <CODE>value</CODE> strings choose a
+particular option and choice, respectively. The return value is 0
+if there are not conflicts created by the selection.
+
+<P>CUPS also provides a convenience function for marking all options
+in the <CODE>cups_option_t</CODE> structure:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+ppd_file_t *ppd;
+int num_options;
+cups_option_t *options;
+int conflicts;
+
+...
+
+conflicts = cupsMarkOptions(ppd, num_options, options);
+</PRE></UL>
+
+<P>The <CODE>cupsMarkOptions()</CODE> function also handles mapping the
+IPP job template attributes to PPD options. The return value is the number
+of conflicts present.
+
+<H3>Checking for Conflicts</H3>
+
+<P>The <CODE>ppdMarkOption()</CODE> and <CODE>cupsMarkOptions()</CODE>
+functions return the number of conflicts with the currently marked options.
+
+<P>Call the <CODE>ppdConflicts()</CODE> function to get the number of
+conflicts after you have marked all of the options:
+
+<UL><PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+ppd_file_t *ppd;
+int conflicts;
+
+...
+
+conflicts = ppdConflicts(ppd);
+</PRE></UL>
+
+<P>The return value is the number of conflicting options, or 0 if there
+are no conflicts.
+
+
+<H1 ALIGN="RIGHT"><A NAME="WRITING_FILTERS">3 - Writing Filters</A></H1>
+
+<P>This chapter describes how to write a file filter for CUPS.
+
+<H2>Overview</H2>
+
+<P>File filters are programs that convert from one or more MIME types to
+another type. Filters use a common command-line and environment interface
+that allows them to be joined as needed to print files to any type of
+printer.
+
+<H3>Security Considerations</H3>
+
+<P>Filters are normally run as a non-priviledged user, so the major
+security consideration is resource utilization - filters should not
+depend on unlimited amounts of memory and disk space.
+
+<H3>Users and Groups</H3>
+
+<P>The default CUPS configuration runs filters as user "lp" and group "other".
+
+<H3>Temporary Files</H3>
+
+<P>Temporary files should be created in the directory specified by the
+"TMPDIR" environment variable. The
+<A HREF="#cupsTempFile"><CODE>cupsTempFile()</CODE></A> function can be
+used to safely choose temporary files in this directory.
+
+<H3>Sending Messages to the User</H3>
+
+<P>The CUPS scheduler collects messages sent to the standard error file
+by the filter. These messages are relayed to the user based upon the
+scheduler <CODE>LogLevel</CODE> directive.
+
+<P>The type of message is determined by an initial prefix sent on each
+line:
+
+<UL>
+
+ <LI><CODE>DEBUG:</CODE> - a debug message
+
+ <LI><CODE>INFO:</CODE> - an informational message
+
+ <LI><CODE>WARNING:</CODE> - a warning message
+
+ <LI><CODE>ERROR:</CODE> - an error message
+
+ <LI><CODE>PAGE:</CODE> - a page accounting message
+
+</UL>
+
+<P>If the line of text does not begin with any of the above prefixes, it
+is treated as a debug message. Text following the prefix is copied to the
+<CODE>printer-state-message</CODE> attribute for the printer, and also
+added to the <VAR>error_log</VAR> unless it is an informational or page
+accounting message.
+
+<H3>Page Accounting</H3>
+
+<P>Page accounting messages are used to inform the server when one or more
+pages are printed. Each line has the form:
+
+<UL><PRE>
+PAGE: page-number copy-count
+</PRE></UL>
+
+<P>The <I>page-number</I> field is the current page number, starting at 1.
+The <I>copy-count</I> field specifies the number of copies of that page
+that was produced.
+
+<P>Page account messages are added to the <VAR>page_log</VAR> file and
+cause the <CODE>job-sheets-completed</CODE> attribute to be updated for
+the job.
+
+<H3>Command-Line Arguments</H3>
+
+<P>Every filter accepts exactly 6 or 7 command-line arguments:
+
+<UL><PRE>
+printer job user title copies options [filename]
+</PRE>
+
+ <LI><CODE>printer</CODE> - The name of the printer queue (normally
+ this is the name of the program being run)
+
+ <LI><CODE>job</CODE> - The numeric job ID for the job being
+ printed
+
+ <LI><CODE>user</CODE> - The string from the
+ <CODE>originating-user-name</CODE> attribute
+
+ <LI><CODE>title</CODE> - The string from the
+ <CODE>job-name</CODE> attribute
+
+ <LI><CODE>copies</CODE> - The numeric value from the
+ <CODE>number-copies</CODE> attribute
+
+ <LI><CODE>options</CODE> - String representations of the
+ job template attributes, separated by spaces. Boolean attributes
+ are provided as "name" for true values and "noname" for false
+ values. All other attributes are provided as "name=value" for
+ single-valued attributes and "name=value1,value2,...,valueN" for
+ set attributes
+
+ <LI><CODE>filename</CODE> - The request file
+
+</UL>
+
+<P>The <I>filename</I> argument is only provided to the first filter in the
+chain; all filters <B>must</B> be prepared to read the print file from
+the standard input if the <I>filename</I> argument is omitted.
+
+<H3>Copy Generation</H3>
+
+<P>The <I>copies</I> argument specifies the number of copies to produce
+of the input file. In general, you should only generate copies if the
+<I>filename</I> argument is supplied. The only exception to this are
+filters that produce device-independent PostScript output (without any
+printer commands from the printer's PPD file), since the PostScript
+filter <CODE>pstops</CODE> is responsible for copy generation.
+
+<H3>Environment Variables</H3>
+
+<P>Every filter receives a fixed set of environment variables that can
+be used by the filter:
+
+<UL>
+
+ <LI><CODE>CHARSET</CODE> - The character set used by the client for
+ this print file
+
+ <LI><CODE>CONTENT_TYPE</CODE> - The original document type, such as
+ "application/postscript"
+
+ <LI><CODE>CUPS_DATADIR</CODE> - The location of CUPS data files
+
+ <LI><CODE>CUPS_SERVERROOT</CODE> - The location of CUPS configuration
+ files
+
+ <LI><CODE>DEVICE_URI</CODE> - The output device URI
+
+ <LI><CODE>LANG</CODE> - The language used by the client for
+ this print file
+
+ <LI><CODE>PATH</CODE> - The execution path exported to the filter
+
+ <LI><CODE>PPD</CODE> - The full filename of the printer's PPD file
+
+ <LI><CODE>PRINTER</CODE> - The name of the printer queue
+
+ <LI><CODE>RIP_CACHE</CODE> - The maximum amount of memory each filter
+ should use
+
+ <LI><CODE>SOFTWARE</CODE> - The name of the CUPS software, typically
+ "CUPS/1.1"
+
+ <LI><CODE>TZ</CODE> - The local timezone
+
+ <LI><CODE>USER</CODE> - The name of the current user
+
+</UL>
+
+<H2>Dissecting the HP-GL/2 Filter</H2>
+
+<P>The HP-GL/2 filter (<CODE>hpgltops</CODE>) provided with CUPS is a
+complex program that converts HP-GL/2 files into device-independent PostScript
+output. Since it produces device-independent PostScript output, it does not
+need to handle copy generation or writing printer options from the printer's
+PPD file.
+
+<H3>Initializing the Filter</H3>
+
+<P>The first task of any filter is to ensure that the correct number of
+command-line arguments are present:
+
+<UL><PRE>
+if (argc &lt; 6 || argc > 7)
+{
+ fputs("ERROR: hpgltops job-id user title copies options [file]\n", stderr);
+ return (1);
+}
+</PRE></UL>
+
+<P>After this you open the print file or read from the standard input
+as needed:
+
+<UL><PRE>
+FILE *fp;
+
+/*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+if (argc == 6)
+ fp = stdin;
+else
+{
+ /*
+ * Try to open the print file...
+ */
+
+ if ((fp = fopen(argv[6], "rb")) == NULL)
+ {
+ perror("ERROR: unable to open print file - ");
+ return (1);
+ }
+}
+</PRE></UL>
+
+<P>Once the print file has been opened, options can be processed using
+the <A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A> and
+<A HREF="#cupsGetOption"><CODE>cupsGetOption()</CODE></A> functions:
+
+<UL><PRE>
+int num_options;
+cups_option_t *options;
+const char *val;
+
+/*
+ * Process command-line options and write the prolog...
+ */
+
+options = NULL;
+num_options = cupsParseOptions(argv[5], 0, &options);
+
+if ((val = cupsGetOption("blackplot", num_options, options)) != NULL)
+ shading = 0;
+
+if ((val = cupsGetOption("fitplot", num_options, options)) != NULL)
+ FitPlot = 1;
+
+if ((val = cupsGetOption("penwidth", num_options, options)) != NULL)
+ PenWidth = (float)atoi(val) * 0.001f;
+</PRE></UL>
+
+<P>After the options have been processed, the filter writes PostScript code
+to the standard output based on the print file, closes the print file (as
+needed), and returns 0 to the scheduler.
+
+<H2>PostScript Output</H2>
+
+<P>Filters that produce PostScript output must generate output conforming
+to the Adobe Document Structuring Conventions, 3.0. In general this means
+the beginning of each file must begin with:
+
+<UL><PRE>
+%!PS-Adobe-3.0
+%%BoundingBox: left bottom right top
+%%Pages: (atend)
+%%EndComments
+</PRE></UL>
+
+<P>The <I>left</I>, <I>bottom</I>, <I>right</I>, and <I>top</I> values
+are integers in points from the lower-lefthand corner of the page.
+
+<P>Pages must be surrounded by:
+
+<UL><PRE>
+%%Page: number number
+gsave
+...
+grestore
+showpage
+</PRE></UL>
+
+<P>And the end of each file must contain:
+
+<UL><PRE>
+%%Trailer
+%%Pages: number-pages
+%%EOF
+</PRE></UL>
+
+<P>These comments allow the PostScript filter to correctly perform page
+accounting, copy generation, N-up printing, and so forth.
+
+<H1 ALIGN="RIGHT"><A NAME="WRITING_DRIVERS">4 - Writing Printer Drivers</A></H1>
+
+<P>This chapter discusses how to write a printer driver, which is a
+special filter program that converts CUPS raster data into the
+appropriate commands and data required for a printer.
+
+<H2>Overview</H2>
+
+<P>Raster printers utilitize PPD files that specify one or more
+device-specific filters that handle converting print files for the
+printer. The simplest raster printer drivers provide a single filter
+that converts CUPS raster data to the printer's native format.
+
+<H3>CUPS Raster Data</H3>
+
+<P>CUPS raster data (<CODE>application/vnd.cups-raster</CODE>) consists of
+a stream of raster page descriptions produced by one of the RIP filters,
+such as <CODE>pstoraster</CODE> or <CODE>imagetoraster</CODE>.
+
+<P>Each page of data begins with a page dictionary structure called
+<A HREF="#cups_raster_header_t"><CODE>cups_raster_header_t</CODE></A>. This
+structure contains the colorspace, bits per color, media size, media type,
+hardware resolution, and so forth.
+
+<P>After the page dictionary comes the page data which is a full-resolution,
+uncompressed bitmap representing the page in the printer's output colorspace.
+
+<H3>Page Accounting</H3>
+
+<P>Printer drivers must handle all page accounting. This means they must
+send "PAGE:" messages to the standard error file for each page (and in many
+cases, copy) sent to the printer.
+
+<H3>Color Management</H3>
+
+<P>Printer drivers can implement their color management via the
+<CODE>cupsColorProfile</CODE> attributes in the PPD file or internally
+in the driver from a device-independent colorspace. In general, color
+management performed by the RIP filters is more efficient than that
+performed inside printer drivers.
+
+<P>For example, the <CODE>pstoraster</CODE> filter often only has to
+perform a color conversion once each time the color is used for
+multiple output pixels, while the raster filter must convert every
+pixel on the page.
+
+<H3>Device and Bitmap Variables</H3>
+
+<P>Besides the standard PostScript page device dictionary variables defined
+in the Adobe PostScript Level 3 reference manual, the CUPS filters support
+additional variables that are passed in the page device dictionary header for
+the page and in some cases control the type of raster data that is generated:
+
+<CENTER><TABLE WIDTH="90%" BORDER="1">
+<TR>
+ <TH>Variable</TH>
+ <TH>Type</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>cupsWidth</TD>
+ <TD>read-only integer</TD>
+ <TD>Width of bitmap in pixels</TD>
+</TR>
+<TR>
+ <TD>cupsHeight</TD>
+ <TD>read-only integer </TD>
+ <TD>Height of bitmap in pixels</TD>
+</TR>
+<TR>
+ <TD>cupsMediaType</TD>
+ <TD>read-write integer</TD>
+ <TD>Device-specific media type code</TD>
+</TR>
+<TR>
+ <TD>cupsBitsPerColor</TD>
+ <TD>read-write integer</TD>
+ <TD>Number of bits per color; 1, 2, 4, and 8 are currently
+ supported</TD>
+</TR>
+<TR>
+ <TD>cupsBitsPerPixel</TD>
+ <TD>read-only integer </TD>
+ <TD>Number of bits per pixel; 1 to 32</TD>
+</TR>
+<TR>
+ <TD>cupsBytesPerLine</TD>
+ <TD>read-only integer</TD>
+ <TD>Number of bytes per line of raster graphics</TD>
+</TR>
+<TR>
+ <TD>cupsColorOrder</TD>
+ <TD>read-write enum</TD>
+ <TD>The order of color values in the bitmap:
+ <UL>
+ <LI><CODE>CUPS_ORDER_CHUNKED</CODE> - CMYK&nbsp;CMYK&nbsp;CMYK
+ <LI><CODE>CUPS_ORDER_BANDED</CODE> - CCC&nbsp;MMM&nbsp;YYY&nbsp;KKK
+ <LI><CODE>CUPS_ORDER_PLANAR</CODE> - CCC&nbsp;...&nbsp;MMM&nbsp;...&nbsp;YYY&nbsp;...&nbsp;KKK&nbsp;...
+ </UL>
+ </TD>
+</TR>
+<TR>
+ <TD>cupsColorSpace</TD>
+ <TD>read-write enum</TD>
+ <TD>The colorspace of the bitmap:
+ <UL>
+ <LI><CODE>CUPS_CSPACE_W</CODE> - White (luminance)
+ <LI><CODE>CUPS_CSPACE_RGB</CODE> - Red, green, blue
+ <LI><CODE>CUPS_CSPACE_RGBA</CODE> - Red, green, blue, alpha
+ <LI><CODE>CUPS_CSPACE_K</CODE> - Black
+ <LI><CODE>CUPS_CSPACE_CMY</CODE> - Cyan, magenta, yellow
+ <LI><CODE>CUPS_CSPACE_YMC</CODE> - Yellow, magenta, cyan
+ <LI><CODE>CUPS_CSPACE_CMYK</CODE> - Cyan, magenta, yellow, black
+ <LI><CODE>CUPS_CSPACE_YMCK</CODE> - Yellow, magenta, cyan, black
+ <LI><CODE>CUPS_CSPACE_KCMY</CODE> - Black, cyan, magenta, yellow
+ <LI><CODE>CUPS_CSPACE_KCMYcm</CODE> - Black, cyan, magenta, yellow,
+ light cyan, light magenta
+ <LI><CODE>CUPS_CSPACE_GMCK</CODE> - Metallic yellow (gold), metallic magenta,
+ metallic cyan, black
+ <LI><CODE>CUPS_CSPACE_GMCS</CODE> - Metallic yellow (gold), metallic magenta,
+ metallic cyan, metallic grey (silver)
+ <LI><CODE>CUPS_CSPACE_WHITE</CODE> - White pigment (black as white pigment)
+ <LI><CODE>CUPS_CSPACE_GOLD</CODE> - Gold foil (black as gold foil)
+ <LI><CODE>CUPS_CSPACE_SILVER</CODE> - Silver foil (black as silver foil)
+ </UL>
+ </TD>
+</TR>
+<TR>
+ <TD>cupsCompression</TD>
+ <TD>read-write integer</TD>
+ <TD>Device-specific compression type code</TD>
+</TR>
+<TR>
+ <TD>cupsRowCount</TD>
+ <TD>read-write integer</TD>
+ <TD>Device-specific row count value</TD>
+</TR>
+<TR>
+ <TD>cupsRowFeed</TD>
+ <TD>read-write integer</TD>
+ <TD>Device-specific row feed value</TD>
+</TR>
+<TR>
+ <TD>cupsRowStep</TD>
+ <TD>read-write integer</TD>
+ <TD>Device-specific row step value</TD>
+</TR>
+</TABLE></CENTER>
+
+<P>Bitmaps with a colorspace of CUPS_CSPACE_KCMYcm and more than 1 bit per
+color are transmitted to the raster driver in KCMY colorspace; the driver
+is responsible for producing the correct separation of normal and light
+cyan and magenta inks.
+
+<H2>Dissecting the HP-PCL Driver</H2>
+
+<P>The HP-PCL driver provided with CUPS (<CODE>rastertohp</CODE>) converts
+bitmap data from the raster filters into HP-PCL commands for most
+PCL-compatible printers. The actual format of the raster data is controlled
+by the PPD file being used - <VAR>deskjet.ppd</VAR> or <VAR>laserjet.ppd</VAR>.
+
+<H3>PPD Files</H3>
+
+<P>PPD files play an important part of all raster printer drivers. Options
+defined in the PPD file contain PostScript commands that control the raster
+data that is sent to the printer driver.
+
+<P>A typical CUPS printer driver will include <CODE>ColorModel</CODE>,
+<CODE>InputSlot</CODE>, <CODE>PageSize</CODE>, <CODE>PageRegion</CODE>,
+and <CODE>Resolution</CODE> options. Each option is shown using the
+standard PPD format:
+
+<UL><PRE>
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/US Letter: "&lt;&lt;
+/PageSize [612 792]
+/ImagingBBox null
+>> setpagedevice"
+*End
+*PageSize Legal/US Legal: "&lt;&lt;
+/PageSize [612 1008]
+/ImagingBBox null
+>> setpagedevice"
+*End
+*PageSize A4/A4: "&lt;&lt;
+/PageSize [595 842]
+/ImagingBBox null
+>> setpagedevice"
+*End
+*CloseUI: *PageSize
+</PRE></UL>
+
+<P>The <CODE>OpenUI</CODE> keyword specifies the new option. The first
+name is the option with an asterisk (*) in front of it. The first name is
+usually followed by a slash (/) and a human-readable version of the
+option name.
+
+<P>Every option <B>must</B> have a default value, specified using the
+<CODE>Default<I>Option</I></CODE> keyword.
+
+<P>Each option begins with the option name followed by the computer and
+human-readable values. The PostScript commands follow these inside double
+quotes. PostScript commands can be provided on a single line:
+
+<UL><PRE>
+*PageSize A4/A4: "&lt;&lt;/PageSize[595 842]/ImagingBBox null>> setpagedevice"
+</PRE></UL>
+
+<P>or broken down on separate lines using the <CODE>End</CODE> keyword to
+terminate them:
+
+<UL><PRE>
+*PageSize A4/A4: "&lt;&lt;
+/PageSize [595 842]
+/ImagingBBox null
+>> setpagedevice"
+*End
+</PRE></UL>
+
+<P>The choice of the two formats is usually esthetic. However, each line in
+a PPD file must not exceed 255 characters, so if your PostScript commands are
+long you may need to break them up on separate lines.
+
+<H3>Reading Raster Data</H3>
+
+<P>As with any filter, your printer driver should handle raster data from
+a filename specified on the command-line or from the standard input. The
+<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A> function opens
+a raster stream for printing:
+
+<UL><PRE>
+int fd; /* File descriptor */
+cups_raster_t *ras; /* Raster stream for printing */
+
+
+/*
+ * Check for valid arguments...
+ */
+
+if (argc &lt; 6 || argc > 7)
+{
+ /*
+ * We don't have the correct number of arguments; write an error message
+ * and return.
+ */
+
+ fputs("ERROR: rastertopcl job-id user title copies options [file]\n", stderr);
+ return (1);
+}
+
+/*
+ * Open the page stream...
+ */
+
+if (argc == 7)
+{
+ if ((fd = open(argv[6], O_RDONLY)) == -1)
+ {
+ perror("ERROR: Unable to open raster file - ");
+ sleep(1);
+ return (1);
+ }
+}
+else
+ fd = 0;
+
+ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
+</PRE></UL>
+
+<P>Once you have opened the raster stream you just need to read each
+page and print it:
+
+<UL><PRE>
+cups_raster_header_t header;
+int y;
+unsigned char data[8192];
+
+while (cupsRasterReadHeader(ras, &amp;header))
+{
+ ... initialize the printer ...
+ for (y = header.cupsHeight; y > 0; y ++)
+ {
+ cupsRasterReadPixels(ras, data, header.cupsBytesPerLine);
+ ... send raster line to printer ...
+ }
+}
+</PRE></UL>
+
+<P>After you have processed all pages, close the raster stream and
+return:
+
+<UL><PRE>
+cupsRasterClose(ras);
+
+return (0);
+</PRE></UL>
+
+<H1 ALIGN="RIGHT"><A NAME="WRITING_BACKENDS">5 - Writing Backends</A></H1>
+
+<P>This chapter describes how to write a backend for CUPS. Backends
+communicate directly with printers and allow printer drivers and
+filters to send data using any type of connection transparently.
+
+<H2>Overview</H2>
+
+<P>Backends are special filters that communicate with printers directly.
+They are treated slightly differently than filters, however, and have some
+unique requirements.
+
+<H3>Security Considerations</H3>
+
+<P>Backends are run as the root user, so special care must be taken to
+avoid potential security violations. In particular, remember that a backend
+will be able to manipulate disk files, devices, and other resources that
+potentially could damage a system or printer.
+
+<H3>Command-Line Arguments</H3>
+
+<P>Besides the standard filter arguments, backends are also run with no
+arguments to get a list of available devices. This discovery process is
+described later in this chapter.
+
+<H3>Copy Generation</H3>
+
+<P>Like filters, backends should send multiple copies of the print file only
+if a filename is supplied on the command-line. Otherwise the backend should
+assume that the upstream filter has already added the necessary commands or
+data to produce the multiple copies.
+
+<H3>Page Accounting</H3>
+
+<P>Backend filters generally do not do page accounting, however they should
+at a minimum produce a single page message for each copy that is produced
+when a filename is present on the command-line. This is because the user
+selected "raw" printing and no other accounting information is possible.
+
+<H3>Exclusive Access</H3>
+
+<P>Backends that talk to local character or block devices should open the
+device file in exclusive mode (<CODE>O_EXCL</CODE>) to cooperate with other
+printers defined for the same device.
+
+<H3>Retries</H3>
+
+<P>All backends <B>must</B> retry connections to the device. This
+includes backends that talk to local character or block devices, as the
+user may define more than one printer queue pointing at the same
+physical device.
+
+<P>To prevent excess CPU utilitization, the backend should go to sleep
+for an amount of time between retries; the CUPS-supplied backends retry
+once every 30 seconds.
+
+<H2>Dissecting the Serial Port Backend</H2>
+
+<P>The serial port backend provides support for serial printers. Since
+it does everything a good backend needs to do, it provides an excellent
+example of what to do.
+
+<H3>Supporting Device Discovery</H3>
+
+<P>As previously noted, backends are special filter programs that talk
+to printer devices. Another task a backend must perform is to list the
+available devices it supports. The backend lists the available devices
+when no additioanl arguments are supplied on the command-line (i.e.
+just the command name...)
+
+<P>The serial backend lists devices by looking at serial port files in the
+<VAR>/dev</VAR> directory, by consulting a hardware inventory (IRIX), and
+in some cases by trying to open the ports to see if they actually exist.
+
+<P>Once it finds a serial port it writes a single line for each port to
+the standard error file. Each line looks like this:
+
+<UL><PRE>
+serial serial:/dev/ttyS0?baud=115200 "Unknown" "Serial Port 1"
+</PRE></UL>
+
+<P>The first word "serial" is the <I>device class</I>; this identifies the
+class of device which can be used to categorize it in user interfaces. CUPS
+currently recognizes the following classes:
+
+<UL>
+
+ <LI>"file" - a disk file.
+
+ <LI>"direct" - a parallel or fixed-rate serial data port,
+ currently used for Centronics, IEEE-1284, and USB printer
+ ports.
+
+ <LI>"serial" - a variable-rate serial port.
+
+ <LI>"network" - a network connection, typically via AppSocket,
+ HTTP, IPP, LPD, or SMB/CIFS protocols.
+
+</UL>
+
+<P>After the device class is the <I>device URI</I>, in this case
+"serial:/dev/ttyS0?baud=115200". This is the URI that should be used by
+the user to select this port. For serial ports, the "baud=115200"
+specifies the maximum baud rate supported by the port - the actual
+value will vary based on the speed the user selects for the printer.
+
+<P>The last two strings are the model and description for the port. The
+"Unknown" string means that the printer model is unknown - some devices
+are able to provide a make and model such as "HP DeskJet" that allows
+users and software to choose an appropriate printer driver more easily.
+Both the model and description must be enclosed inside double quotes.
+
+<H3>Opening the Serial Port</H3>
+
+<P>As noted previously, all backends should open device files in exclusive
+mode, and retry as needed until the port is available. The serial port does
+this using a <CODE>do-while</CODE> loop:
+
+<UL><PRE>
+do
+{
+ if ((fd = open(resource, O_WRONLY | O_NOCTTY | O_EXCL)) == -1)
+ {
+ if (errno == EBUSY)
+ {
+ fputs("INFO: Serial port busy; will retry in 30 seconds...\n", stderr);
+ sleep(30);
+ }
+ else
+ {
+ perror("ERROR: Unable to open serial port device file");
+ return (1);
+ }
+ }
+}
+while (fd &lt; 0);
+</PRE></UL>
+
+<P>If the port is busy or in use by another process, the backend will
+go to sleep for 30 seconds and try again. If another error is detected
+a message is sent to the user and the backend aborts the print job
+until the problem can be corrected.
+
+<H3>Writing Data to the Port</H3>
+
+<P>Network and character devices pose an interesting problem when writing
+data to the port - they may not be able to write all of the bytes in your
+buffer before returning. To work around this problem you must loop until
+all bytes have been written:
+
+<UL><PRE>
+while (nbytes > 0)
+{
+ if ((wbytes = write(fd, bufptr, nbytes)) &lt; 0)
+ if (errno == ENOTTY)
+ wbytes = write(fd, bufptr, nbytes);
+
+ if (wbytes &lt; 0)
+ {
+ perror("ERROR: Unable to send print file to printer");
+ break;
+ }
+
+ nbytes -= wbytes;
+ bufptr += wbytes;
+}
+</PRE></UL>
+
+<P>The check for the <CODE>ENOTTY</CODE> error is needed on some platforms
+to clear an error from a previous <CODE>ioctl()</CODE> call.
+
+<H3>Finishing Up</H3>
+
+<P>Once you have sent the print file, return 0 if the file printed
+successfully or 1 if it did not. This will allow the scheduler to stop
+the print job if there is a device error, preserving the print job for
+later printing once the problem has been corrected.
+
+<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - Software License Agreement</A></H1>
+
+<EMBED SRC="../LICENSE.html">
+
+
+<H1 ALIGN="RIGHT"><A NAME="CONSTANTS">B - Constants</A></H1>
+
+<P>This appendix lists all of the constants that are defined by the CUPS
+API.
+
+<H2>CUPS Constants</H2>
+
+<H3>Version Number</H3>
+
+<P>The <CODE>CUPS_VERSION</CODE> constant is a floating-point number
+representing the API version number. The current version number is
+1.0100 which represents CUPS version 1.1.0.
+
+<H3>Printer Capabilities</H3>
+
+<P>The <CODE>CUPS_PRINTER</CODE> constants represent capability bits for
+printers and classes:
+
+<UL>
+
+ <LI><CODE>CUPS_PRINTER_LOCAL</CODE> - Is a local printer or class.
+
+ <LI><CODE>CUPS_PRINTER_REMOTE</CODE> - Is a remote printer or class.
+
+ <LI><CODE>CUPS_PRINTER_CLASS</CODE> - Is a class.
+
+ <LI><CODE>CUPS_PRINTER_BW</CODE> - Printer prints in black and white.
+
+ <LI><CODE>CUPS_PRINTER_COLOR</CODE> - Printer prints in color.
+
+ <LI><CODE>CUPS_PRINTER_DUPLEX</CODE> - Printer can print double-sided.
+
+ <LI><CODE>CUPS_PRINTER_STAPLE</CODE> - Printer can staple output.
+
+ <LI><CODE>CUPS_PRINTER_COPIES</CODE> - Printer can produce multiple
+ copies on its own.
+
+ <LI><CODE>CUPS_PRINTER_COLLATE</CODE> - Printer can collate copies.
+
+ <LI><CODE>CUPS_PRINTER_PUNCH</CODE> - Printer can punch holes in output.
+
+ <LI><CODE>CUPS_PRINTER_COVER</CODE> - Printer can put covers on output.
+
+ <LI><CODE>CUPS_PRINTER_BIND</CODE> - Printer can bind output.
+
+ <LI><CODE>CUPS_PRINTER_SORT</CODE> - Printer can sort output.
+
+ <LI><CODE>CUPS_PRINTER_SMALL</CODE> - Printer can print on media up
+ to 9x14 inches.
+
+ <LI><CODE>CUPS_PRINTER_MEDIUM</CODE> - Printer can print on media
+ from 9x14 to 18x24 inches.
+
+ <LI><CODE>CUPS_PRINTER_LARGE</CODE> - Printer can print on media
+ larger than 18x24 inches.
+
+ <LI><CODE>CUPS_PRINTER_VARIABLE</CODE> - Printer can print on
+ variable or custom media sizes.
+
+ <LI><CODE>CUPS_PRINTER_IMPLICIT</CODE> - Is an implicit class.
+
+ <LI><CODE>CUPS_PRINTER_OPTIONS</CODE> - All of the printer capability
+ and option bits.
+
+</UL>
+
+<H3>Encodings</H3>
+
+<P>CUPS defines the following character set encoding constants:
+
+<UL>
+
+ <LI><CODE>CUPS_US_ASCII</CODE> - US ASCII character set.
+
+ <LI><CODE>CUPS_UTF_8</CODE> - UTF-8 encoding of Unicode.
+
+ <LI><CODE>CUPS_ISO8859_1</CODE> - ISO-8859-1 character set.
+
+ <LI><CODE>CUPS_ISO8859_2</CODE> - ISO-8859-2 character set.
+
+ <LI><CODE>CUPS_ISO8859_3</CODE> - ISO-8859-3 character set.
+
+ <LI><CODE>CUPS_ISO8859_4</CODE> - ISO-8859-4 character set.
+
+ <LI><CODE>CUPS_ISO8859_5</CODE> - ISO-8859-5 character set.
+
+ <LI><CODE>CUPS_ISO8859_6</CODE> - ISO-8859-6 character set.
+
+ <LI><CODE>CUPS_ISO8859_7</CODE> - ISO-8859-7 character set.
+
+ <LI><CODE>CUPS_ISO8859_8</CODE> - ISO-8859-8 character set.
+
+ <LI><CODE>CUPS_ISO8859_9</CODE> - ISO-8859-9 character set.
+
+ <LI><CODE>CUPS_ISO8859_10</CODE> - ISO-8859-10 character set.
+
+ <LI><CODE>CUPS_ISO8859_13</CODE> - ISO-8859-13 character set.
+
+ <LI><CODE>CUPS_ISO8859_14</CODE> - ISO-8859-14 character set.
+
+ <LI><CODE>CUPS_ISO8859_15</CODE> - ISO-8859-15 character set.
+
+ <LI><CODE>CUPS_WINDOWS_874</CODE> - Windows code page 874.
+
+ <LI><CODE>CUPS_WINDOWS_1250</CODE> - Windows code page 1250.
+
+ <LI><CODE>CUPS_WINDOWS_1251</CODE> - Windows code page 1251.
+
+ <LI><CODE>CUPS_WINDOWS_1252</CODE> - Windows code page 1252.
+
+ <LI><CODE>CUPS_WINDOWS_1253</CODE> - Windows code page 1253.
+
+ <LI><CODE>CUPS_WINDOWS_1254</CODE> - Windows code page 1254.
+
+ <LI><CODE>CUPS_WINDOWS_1255</CODE> - Windows code page 1255.
+
+ <LI><CODE>CUPS_WINDOWS_1256</CODE> - Windows code page 1256.
+
+ <LI><CODE>CUPS_WINDOWS_1257</CODE> - Windows code page 1257.
+
+ <LI><CODE>CUPS_WINDOWS_1258</CODE> - Windows code page 1258.
+
+ <LI><CODE>CUPS_KOI8_R</CODE> - Russian code page koi8-r.
+
+ <LI><CODE>CUPS_KOI8_U</CODE> - Ukrainian code page koi8-r.
+
+</UL>
+
+<H2>HTTP Constants</H2>
+
+<H3>Limits</H3>
+
+<P>The following constants define the limits for strings:
+
+<UL>
+
+ <LI><CODE>HTTP_MAX_BUFFER</CODE> - Size of socket buffer.
+
+ <LI><CODE>HTTP_MAX_HOST</CODE> - Maximum length of hostname.
+
+ <LI><CODE>HTTP_MAX_URI</CODE> - Maximum length of URI.
+
+ <LI><CODE>HTTP_MAX_VALUE</CODE> - Maximum length of field values.
+
+</UL>
+
+<H3>Status Codes</H3>
+
+<P>The following status codes can be returned by <CODE>httpUpdate()</CODE>:
+
+<UL>
+
+ <LI><CODE>HTTP_ERROR</CODE> - A network error occurred
+
+ <LI><CODE>HTTP_CONTINUE</CODE> - Continue response from HTTP proxy
+
+ <LI><CODE>HTTP_OK</CODE> - OPTIONS/GET/HEAD/POST/TRACE command was successful
+
+ <LI><CODE>HTTP_CREATED</CODE> - PUT command was successful
+
+ <LI><CODE>HTTP_ACCEPTED</CODE> - DELETE command was successful
+
+ <LI><CODE>HTTP_NOT_AUTHORITATIVE</CODE> - Information isn't authoritative
+
+ <LI><CODE>HTTP_NO_CONTENT</CODE> - Successful command
+
+ <LI><CODE>HTTP_RESET_CONTENT</CODE> - Content was reset/recreated
+
+ <LI><CODE>HTTP_PARTIAL_CONTENT</CODE> - Only a partial file was recieved/sent
+
+ <LI><CODE>HTTP_MULTIPLE_CHOICES</CODE> - Multiple files match request
+
+ <LI><CODE>HTTP_MOVED_PERMANENTLY</CODE> - Document has moved permanently
+
+ <LI><CODE>HTTP_MOVED_TEMPORARILY</CODE> - Document has moved temporarily
+
+ <LI><CODE>HTTP_SEE_OTHER</CODE> - See this other link...
+
+ <LI><CODE>HTTP_NOT_MODIFIED</CODE> - File not modified
+
+ <LI><CODE>HTTP_USE_PROXY</CODE> - Must use a proxy to access this URI
+
+ <LI><CODE>HTTP_BAD_REQUEST</CODE> - Bad request
+
+ <LI><CODE>HTTP_UNAUTHORIZED</CODE> - Unauthorized to access host
+
+ <LI><CODE>HTTP_PAYMENT_REQUIRED</CODE> - Payment required
+
+ <LI><CODE>HTTP_FORBIDDEN</CODE> - Forbidden to access this URI
+
+ <LI><CODE>HTTP_NOT_FOUND</CODE> - URI was not found
+
+ <LI><CODE>HTTP_METHOD_NOT_ALLOWED</CODE> - Method is not allowed
+
+ <LI><CODE>HTTP_NOT_ACCEPTABLE</CODE> - Not Acceptable
+
+ <LI><CODE>HTTP_PROXY_AUTHENTICATION</CODE> - Proxy Authentication is Required
+
+ <LI><CODE>HTTP_REQUEST_TIMEOUT</CODE> - Request timed out
+
+ <LI><CODE>HTTP_CONFLICT</CODE> - Request is self-conflicting
+
+ <LI><CODE>HTTP_GONE</CODE> - Server has gone away
+
+ <LI><CODE>HTTP_LENGTH_REQUIRED</CODE> - A content length or encoding is required
+
+ <LI><CODE>HTTP_PRECONDITION</CODE> - Precondition failed
+
+ <LI><CODE>HTTP_REQUEST_TOO_LARGE</CODE> - Request entity too large
+
+ <LI><CODE>HTTP_URI_TOO_LONG</CODE> - URI too long
+
+ <LI><CODE>HTTP_UNSUPPORTED_MEDIATYPE</CODE> - The requested media type is unsupported
+
+ <LI><CODE>HTTP_SERVER_ERROR</CODE> - Internal server error
+
+ <LI><CODE>HTTP_NOT_IMPLEMENTED</CODE> - Feature not implemented
+
+ <LI><CODE>HTTP_BAD_GATEWAY</CODE> - Bad gateway
+
+ <LI><CODE>HTTP_SERVICE_UNAVAILABLE</CODE> - Service is unavailable
+
+ <LI><CODE>HTTP_GATEWAY_TIMEOUT</CODE> - Gateway connection timed out
+
+ <LI><CODE>HTTP_NOT_SUPPORTED</CODE> - HTTP version not supported
+
+</UL>
+
+<H3>Fields</H3>
+
+<P>The following fields are indices for each of the standard HTTP fields in
+HTTP 1/1:
+
+<UL>
+
+ <LI><CODE>HTTP_FIELD_ACCEPT_LANGUAGE</CODE> - Accept-Language
+
+ <LI><CODE>HTTP_FIELD_ACCEPT_RANGES</CODE> - Accept-Ranges
+
+ <LI><CODE>HTTP_FIELD_AUTHORIZATION</CODE> - Authorization
+
+ <LI><CODE>HTTP_FIELD_CONNECTION</CODE> - Connection
+
+ <LI><CODE>HTTP_FIELD_CONTENT_ENCODING</CODE> - Content-Encoding
+
+ <LI><CODE>HTTP_FIELD_CONTENT_LANGUAGE</CODE> - Content-Language
+
+ <LI><CODE>HTTP_FIELD_CONTENT_LENGTH</CODE> - Content-Length
+
+ <LI><CODE>HTTP_FIELD_CONTENT_LOCATION</CODE> - Content-Location
+
+ <LI><CODE>HTTP_FIELD_CONTENT_MD5</CODE> - Content-MD5
+
+ <LI><CODE>HTTP_FIELD_CONTENT_RANGE</CODE> - Content-Range
+
+ <LI><CODE>HTTP_FIELD_CONTENT_TYPE</CODE> - Content-Type
+
+ <LI><CODE>HTTP_FIELD_CONTENT_VERSION</CODE> - Content-Version
+
+ <LI><CODE>HTTP_FIELD_DATE</CODE> - Date
+
+ <LI><CODE>HTTP_FIELD_HOST</CODE> - Host
+
+ <LI><CODE>HTTP_FIELD_IF_MODIFIED_SINCE</CODE> - If-Modified-Since
+
+ <LI><CODE>HTTP_FIELD_IF_UNMODIFIED_SINCE</CODE> - If-Unmodified-Since
+
+ <LI><CODE>HTTP_FIELD_KEEP_ALIVE</CODE> - Keep-Alive
+
+ <LI><CODE>HTTP_FIELD_LAST_MODIFIED</CODE> - Last-Modified
+
+ <LI><CODE>HTTP_FIELD_LINK</CODE> - Link
+
+ <LI><CODE>HTTP_FIELD_LOCATION</CODE> - Location
+
+ <LI><CODE>HTTP_FIELD_RANGE</CODE> - Range
+
+ <LI><CODE>HTTP_FIELD_REFERER</CODE> - Referer
+
+ <LI><CODE>HTTP_FIELD_RETRY_AFTER</CODE> - Retry-After
+
+ <LI><CODE>HTTP_FIELD_TRANSFER_ENCODING</CODE> - Transfer-Encoding
+
+ <LI><CODE>HTTP_FIELD_UPGRADE</CODE> - Upgrade
+
+ <LI><CODE>HTTP_FIELD_USER_AGENT</CODE> - User-Agent
+
+ <LI><CODE>HTTP_FIELD_WWW_AUTHENTICATE</CODE> - WWW-Authenticate
+
+
+</UL>
+
+<H2>IPP Constants</H2>
+
+<H3>Limits</H3>
+
+<P>The following constants define array limits for IPP data:
+
+<UL>
+
+ <LI><CODE>IPP_MAX_NAME</CODE> - Maximum length of an attribute name
+
+ <LI><CODE>IPP_MAX_VALUES</CODE> - Maximum number of set-of values
+ that can be read in a request.
+
+</UL>
+
+<H3>Tags</H3>
+
+<UL>
+
+ <LI><CODE>IPP_TAG_ZERO</CODE> - Wildcard tag value for searches; also
+ used to separate groups of attributes
+
+ <LI><CODE>IPP_TAG_OPERATION</CODE> - Tag for values of type operation
+
+ <LI><CODE>IPP_TAG_JOB</CODE> - Tag for values of type job
+
+ <LI><CODE>IPP_TAG_END</CODE> - Tag for values of type end
+
+ <LI><CODE>IPP_TAG_PRINTER</CODE> - Tag for values of type printer
+
+ <LI><CODE>IPP_TAG_UNSUPPORTED_GROUP</CODE> - Tag for values of type unsupported_group
+
+ <LI><CODE>IPP_TAG_UNSUPPORTED_VALUE</CODE> - Tag for values of type unsupported_value
+
+ <LI><CODE>IPP_TAG_DEFAULT</CODE> - Tag for values of type default
+
+ <LI><CODE>IPP_TAG_UNKNOWN</CODE> - Tag for values of type unknown
+
+ <LI><CODE>IPP_TAG_NOVALUE</CODE> - Tag for values of type novalue
+
+ <LI><CODE>IPP_TAG_NOTSETTABLE</CODE> - Tag for values of type notsettable
+
+ <LI><CODE>IPP_TAG_DELETEATTR</CODE> - Tag for values of type deleteattr
+
+ <LI><CODE>IPP_TAG_ANYVALUE</CODE> - Tag for values of type anyvalue
+
+ <LI><CODE>IPP_TAG_INTEGER</CODE> - Tag for values of type integer
+
+ <LI><CODE>IPP_TAG_BOOLEAN</CODE> - Tag for values of type boolean
+
+ <LI><CODE>IPP_TAG_ENUM</CODE> - Tag for values of type enum
+
+ <LI><CODE>IPP_TAG_STRING</CODE> - Tag for values of type string
+
+ <LI><CODE>IPP_TAG_DATE</CODE> - Tag for values of type date
+
+ <LI><CODE>IPP_TAG_RESOLUTION</CODE> - Tag for values of type resolution
+
+ <LI><CODE>IPP_TAG_RANGE</CODE> - Tag for values of type range
+
+ <LI><CODE>IPP_TAG_COLLECTION</CODE> - Tag for values of type collection
+
+ <LI><CODE>IPP_TAG_TEXTLANG</CODE> - Tag for values of type textlang
+
+ <LI><CODE>IPP_TAG_NAMELANG</CODE> - Tag for values of type namelang
+
+ <LI><CODE>IPP_TAG_TEXT</CODE> - Tag for values of type text
+
+ <LI><CODE>IPP_TAG_NAME</CODE> - Tag for values of type name
+
+ <LI><CODE>IPP_TAG_KEYWORD</CODE> - Tag for values of type keyword
+
+ <LI><CODE>IPP_TAG_URI</CODE> - Tag for values of type uri
+
+ <LI><CODE>IPP_TAG_URISCHEME</CODE> - Tag for values of type urischeme
+
+ <LI><CODE>IPP_TAG_CHARSET</CODE> - Tag for values of type charset
+
+ <LI><CODE>IPP_TAG_LANGUAGE</CODE> - Tag for values of type language
+
+ <LI><CODE>IPP_TAG_MIMETYPE</CODE> - Tag for values of type mimetype
+
+</UL>
+
+<H3>Resolution Units</H3>
+
+<P>The <CODE>IPP_RES_PER_INCH</CODE> and <CODE>IPP_RES_PER_CM</CODE> constants
+specify dots per inch and dots per centimeter, respectively.
+
+<H3>Finishings</H3>
+
+<P>The finishing values specify special finishing operations to be
+performed on the job.
+
+<UL>
+
+ <LI><CODE>IPP_FINISH_NONE</CODE> - Do no finishing
+
+ <LI><CODE>IPP_FINISH_STAPLE</CODE> - Staple the job
+
+ <LI><CODE>IPP_FINISH_PUNCH</CODE> - Punch the job
+
+ <LI><CODE>IPP_FINISH_COVER</CODE> - Cover the job
+
+ <LI><CODE>IPP_FINISH_BIND</CODE> - Bind the job
+
+</UL>
+
+<H3>Orientations</H3>
+
+<P>The orientation values specify the orientation of the job.
+
+<UL>
+
+ <LI><CODE>IPP_PORTRAIT</CODE> - No rotation
+
+ <LI><CODE>IPP_LANDSCAPE</CODE> - 90 degrees counter-clockwise
+
+ <LI><CODE>IPP_REVERSE_LANDSCAPE</CODE> - 90 degrees clockwise
+
+ <LI><CODE>IPP_REVERSE_PORTRAIT</CODE> - 180 degrees
+
+</UL>
+
+<H3>Qualities</H3>
+
+<P>The quality values specify the desired quality of the print.
+<UL>
+
+ <LI><CODE>IPP_QUALITY_DRAFT</CODE> - Draft quality
+
+ <LI><CODE>IPP_QUALITY_NORMAL</CODE> - Normal quality
+
+ <LI><CODE>IPP_QUALITY_HIGH</CODE> - High quality
+
+</UL>
+
+<H3>Job States</H3>
+
+<P>The job state values are used to represent the current job state.
+
+<UL>
+
+ <LI><CODE>IPP_JOB_PENDING</CODE> - Job is pending
+
+ <LI><CODE>IPP_JOB_HELD</CODE> - Job is held
+
+ <LI><CODE>IPP_JOB_PROCESSING</CODE> - Job is processing
+
+ <LI><CODE>IPP_JOB_STOPPED</CODE> - Job is stopped
+
+ <LI><CODE>IPP_JOB_CANCELLED</CODE> - Job is cancelled
+
+ <LI><CODE>IPP_JOB_ABORTED</CODE> - Job is aborted
+
+ <LI><CODE>IPP_JOB_COMPLETED</CODE> - Job is completed
+
+</UL>
+
+<H3>Printer States</H3>
+
+<P>The printer state values are used to represent the current printer
+state.
+
+<UL>
+
+ <LI><CODE>IPP_PRINTER_IDLE</CODE> - Printer is idle
+
+ <LI><CODE>IPP_PRINTER_PROCESSING</CODE> - Printer is processing
+
+ <LI><CODE>IPP_PRINTER_STOPPED</CODE> - Printer is stopped
+
+</UL>
+
+<H3>Operations</H3>
+
+<P>The operation values represent the available IPP operations.
+
+<UL>
+
+ <LI><CODE>IPP_PRINT_JOB</CODE> - Print a file
+
+ <LI><CODE>IPP_PRINT_URI</CODE> - Print a URI
+
+ <LI><CODE>IPP_VALIDATE_JOB</CODE> - Validate job attributes
+
+ <LI><CODE>IPP_CREATE_JOB</CODE> - Create a new job
+
+ <LI><CODE>IPP_SEND_DOCUMENT</CODE> - Send a document to a job
+
+ <LI><CODE>IPP_SEND_URI</CODE> - Send a URI to a job
+
+ <LI><CODE>IPP_CANCEL_JOB</CODE> - Cancel a job
+
+ <LI><CODE>IPP_GET_JOB_ATTRIBUTES</CODE> - Get job attributes
+
+ <LI><CODE>IPP_GET_JOBS</CODE> - Get a list of all jobs
+
+ <LI><CODE>IPP_GET_PRINTER_ATTRIBUTES</CODE> - Get printer attributes
+
+ <LI><CODE>IPP_HOLD_JOB</CODE> - Hold a pending job
+
+ <LI><CODE>IPP_RELEASE_JOB</CODE> - Release a held job
+
+ <LI><CODE>IPP_RESTART_JOB</CODE> - Restart a completed job
+
+ <LI><CODE>IPP_PAUSE_PRINTER</CODE> - Pause a printer
+
+ <LI><CODE>IPP_RESUME_PRINTER</CODE> - Restart a paused printer
+
+ <LI><CODE>IPP_PURGE_JOBS</CODE> - Purge jobs from the queue
+
+ <LI><CODE>IPP_SET_PRINTER_ATTRIBUTES</CODE> - Set printer attributes
+
+ <LI><CODE>IPP_SET_JOB_ATTRIBUTES</CODE> - Set job attributes
+
+ <LI><CODE>IPP_GET_PRINTER_SUPPORTED_VALUES</CODE> - Get printer supported values
+
+ <LI><CODE>CUPS_GET_DEFAULT</CODE> - Get the default destination
+
+ <LI><CODE>CUPS_GET_PRINTERS</CODE> - Get a list of all printers
+
+ <LI><CODE>CUPS_ADD_PRINTER</CODE> - Add or modify a printer
+
+ <LI><CODE>CUPS_DELETE_PRINTER</CODE> - Delete a printer
+
+ <LI><CODE>CUPS_GET_CLASSES</CODE> - Get a list of all classes
+
+ <LI><CODE>CUPS_ADD_CLASS</CODE> - Add or modify a class
+
+ <LI><CODE>CUPS_DELETE_CLASS</CODE> - Delete a class
+
+ <LI><CODE>CUPS_ACCEPT_JOBS</CODE> - Accept jobs on a printer or class
+
+ <LI><CODE>CUPS_REJECT_JOBS</CODE> - Reject jobs on a printer or class
+
+ <LI><CODE>CUPS_SET_DEFAULT</CODE> - Set the default destination
+
+ <LI><CODE>CUPS_GET_DEVICES</CODE> - Get a list of all devices
+
+ <LI><CODE>CUPS_GET_PPDS</CODE> - Get a list of all PPDs
+
+ <LI><CODE>CUPS_MOVE_JOB</CODE> - Move a job to a new destination
+
+</UL>
+
+<H3>Status Codes</H3>
+
+<P>Status codes are returned by all IPP requests.
+
+<UL>
+
+ <LI><CODE>IPP_OK</CODE> - Request completed with no errors
+
+ <LI><CODE>IPP_OK_SUBST</CODE> - Request completed but some attribute
+ values were substituted
+
+ <LI><CODE>IPP_OK_CONFLICT</CODE> - Request completed but some attributes
+ conflicted
+
+ <LI><CODE>IPP_BAD_REQUEST</CODE> - The request was bad
+
+ <LI><CODE>IPP_FORBIDDEN</CODE> - You don't have access to the resource
+
+ <LI><CODE>IPP_NOT_AUTHENTICATED</CODE> - You are not authenticated for
+ the resource
+
+ <LI><CODE>IPP_NOT_AUTHORIZED</CODE> - You not authorized to access
+ the resource
+
+ <LI><CODE>IPP_NOT_POSSIBLE</CODE> - The requested operation cannot be
+ completed
+
+ <LI><CODE>IPP_TIMEOUT</CODE> - A timeout occurred
+
+ <LI><CODE>IPP_NOT_FOUND</CODE> - The resource was not found
+
+ <LI><CODE>IPP_GONE</CODE> - The resource has gone away
+
+ <LI><CODE>IPP_REQUEST_ENTITY</CODE> - The request was too large
+
+ <LI><CODE>IPP_REQUEST_VALUE</CODE> - The request contained a value
+ that was unknown to the server
+
+ <LI><CODE>IPP_DOCUMENT_FORMAT</CODE> - The document format is not
+ supported by the server
+
+ <LI><CODE>IPP_ATTRIBUTES</CODE> - Required attributes are missing
+
+ <LI><CODE>IPP_URI_SCHEME</CODE> - The URI scheme is not supported
+
+ <LI><CODE>IPP_CHARSET</CODE> - The charset is not supported
+
+ <LI><CODE>IPP_CONFLICT</CODE> - One or more attributes conflict
+
+ <LI><CODE>IPP_COMPRESSION_NOT_SUPPORTED</CODE> - The specified
+ compression is not supported
+
+ <LI><CODE>IPP_COMPRESSION_ERROR</CODE> - The compressed data
+ contained an error
+
+ <LI><CODE>IPP_DOCUMENT_FORMAT_ERROR</CODE> - The document data
+ contained an error in it
+
+ <LI><CODE>IPP_DOCUMENT_ACCESS_ERROR</CODE> - The remote document
+ could not be accessed
+
+ <LI><CODE>IPP_INTERNAL_ERROR</CODE> - The server encountered an
+ internal error
+
+ <LI><CODE>IPP_OPERATION_NOT_SUPPORTED</CODE> - The requested operation
+ is not supported
+
+ <LI><CODE>IPP_SERVICE_UNAVAILABLE</CODE> - The requested service
+ is unavailable
+
+ <LI><CODE>IPP_VERSION_NOT_SUPPORTED</CODE> - The IPP request
+ version is not supported
+
+ <LI><CODE>IPP_DEVICE_ERROR</CODE> - The output device encountered
+ an error
+
+ <LI><CODE>IPP_TEMPORARY_ERROR</CODE> - A temporary error occurred
+
+ <LI><CODE>IPP_NOT_ACCEPTING</CODE> - The destination is not accepting
+ jobs
+
+ <LI><CODE>IPP_PRINTER_BUSY</CODE> - The destination is busy
+
+ <LI><CODE>IPP_ERROR_JOB_CANCELLED</CODE> - The requested job has been
+ cancelled
+
+ <LI><CODE>IPP_MULTIPLE_JOBS_NOT_SUPPORTED</CODE> - The server
+ does not support multiple jobs
+
+</UL>
+
+<H2>PPD Constants</H2>
+
+<H3>PPD Format Version</H3>
+
+<P>The <CODE>PPD_VERSION</CODE> constant defines a floating point number
+representing the newest format version that is supported by CUPS, currently
+4.3.
+
+<H3>PPD User-Interface Types</H3>
+
+<P>Each printer option has a type associated with it:
+
+<UL>
+
+ <LI><CODE>PPD_UI_BOOLEAN</CODE> - The user can turn this option on or off
+
+ <LI><CODE>PPD_UI_PICKONE</CODE> - The user can choose one option value
+ to use.
+
+ <LI><CODE>PPD_UI_PICKMANY</CODE> - The user can choose zero or more
+ option values.
+
+</UL>
+
+<H3>PPD Sections</H3>
+
+<P>Some options must be output before others, or in different sections of
+the output document. The <CODE>ppd_section_t</CODE> enumeration defines
+which section the option must be output in:
+
+<UL>
+
+ <LI><CODE>PPD_ORDER_ANY</CODE> - The option can be output in any of
+ the document, page, or prolog sections of the document
+
+ <LI><CODE>PPD_ORDER_DOCUMENT</CODE> - The option must be output in
+ the DocumentSetup section of the document
+
+ <LI><CODE>PPD_ORDER_EXIT</CODE> - The option must be output before
+ the document
+
+ <LI><CODE>PPD_ORDER_JCL</CODE> - The option must be output in the
+ job control section of the document
+
+ <LI><CODE>PPD_ORDER_PAGE</CODE> - The option must be output in the
+ PageSetup section of the document
+
+ <LI><CODE>PPD_ORDER_PROLOG</CODE> - The option must be output in the
+ Prolog section of the document
+
+</UL>
+
+<H3>PPD Colorspaces</H3>
+
+<P>Each printer has a default colorspace:
+
+<UL>
+
+ <LI><CODE>PPD_CS_CMYK</CODE> - The printer uses CMYK colors by default
+
+ <LI><CODE>PPD_CS_CMY</CODE> - The printer uses CMY colors by default
+
+ <LI><CODE>PPD_CS_GRAY</CODE> - The printer uses grayscale by default
+
+ <LI><CODE>PPD_CS_RGB</CODE> - The printer uses RGB colors by default
+
+ <LI><CODE>PPD_CS_RGBK</CODE> - The printer uses RGBK colors by default
+
+ <LI><CODE>PPD_CS_N</CODE> - The printer uses a DeviceN colorspace
+ by default
+
+</UL>
+
+<H2>Raster Constants</H2>
+
+<H3>Raster Sync Words</H3>
+
+<P>The <CODE>CUPS_RASTER_SYNC</CODE> and <CODE>CUPS_RASTER_REVSYNC</CODE>
+constants define the standard sync words at the beginning of each CUPS
+raster file.
+
+<H3>Raster Stream Modes</H3>
+
+<P>The <CODE>CUPS_RASTER_READ</CODE> and <CODE>CUPS_RASTER_WRITE</CODE>
+constants are used with the
+<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A> function to
+specify a stream for reading or writing.
+
+<H3>Raster Boolean Constants</H3>
+
+<P>The <CODE>CUPS_FALSE</CODE> and <CODE>CUPS_TRUE</CODE> constants
+represent boolean values in the page header.
+
+<H3>Raster Jog Values</H3>
+
+<P>The <CODE>cups_jog_t</CODE> enumeration defines constants for the
+Jog page device dictionary variable:
+
+<UL>
+
+ <LI><CODE>CUPS_JOG_NONE</CODE> - Do no jogging
+
+ <LI><CODE>CUPS_JOG_FILE</CODE> - Jog pages after each file
+
+ <LI><CODE>CUPS_JOG_JOB</CODE> - Jog pages after each job
+
+ <LI><CODE>CUPS_JOG_SET</CODE> - Jog pages after each set of jobs
+
+</UL>
+
+<H3>Raster Orientation Values</H3>
+
+<P>The <CODE>cups_orient_t</CODE> enumeration defines constants for the
+Orientation page device dictionary variable:
+
+<UL>
+
+ <LI><CODE>CUPS_ORIENT_0</CODE> - Portrait orientation
+
+ <LI><CODE>CUPS_ORIENT_90</CODE> - Landscape orientation
+
+ <LI><CODE>CUPS_ORIENT_180</CODE> - Reverse-portrait orientation
+
+ <LI><CODE>CUPS_ORIENT_270</CODE> - Reverse-landscape orientation
+
+</UL>
+
+<H3>Raster CutMedia Values</H3>
+
+<P>The <CODE>cups_cut_t</CODE> enumeration defines constants for the
+CutMedia page device dictionary variable:
+
+<UL>
+
+ <LI><CODE>CUPS_CUT_NONE</CODE> - Do no jogging
+
+ <LI><CODE>CUPS_CUT_FILE</CODE> - Cut pages after each file
+
+ <LI><CODE>CUPS_CUT_JOB</CODE> - Cut pages after each job
+
+ <LI><CODE>CUPS_CUT_SET</CODE> - Cut pages after each set of jobs
+
+ <LI><CODE>CUPS_CUT_PAGE</CODE> - Cut each page
+
+</UL>
+
+<H3>Raster AdvanceMedia Values</H3>
+
+<P>The <CODE>cups_advance_t</CODE> enumeration defines constants for the
+AdvanceMedia page device dictionary variable:
+
+<UL>
+
+ <LI><CODE>CUPS_ADVANCE_NONE</CODE> - Do no jogging
+
+ <LI><CODE>CUPS_ADVANCE_FILE</CODE> - Advance media after each file
+
+ <LI><CODE>CUPS_ADVANCE_JOB</CODE> - Advance media after each job
+
+ <LI><CODE>CUPS_ADVANCE_SET</CODE> - Advance media after each set of jobs
+
+ <LI><CODE>CUPS_ADVANCE_PAGE</CODE> - Advance media for each page
+
+</UL>
+
+<H3>Raster LeadingEdge Values</H3>
+
+<P>The <CODE>cups_edge_t</CODE> enumeration defines constants for the
+LeadingEdge page device dictionary variable:
+
+<UL>
+
+ <LI><CODE>CUPS_EDGE_TOP</CODE> - The top of the media is the leading
+ edge
+
+ <LI><CODE>CUPS_EDGE_RIGHT</CODE> - The right of the media is the leading
+ edge
+
+ <LI><CODE>CUPS_EDGE_BOTTOM</CODE> - The bottom of the media is the
+ leading edge
+
+ <LI><CODE>CUPS_EDGE_LEFT</CODE> - The left of the media is the leading
+ edge
+
+</UL>
+
+<H3>Raster Color Order Values</H3>
+
+<P>The <CODE>cups_order_t</CODE> enumeration defines the possible color
+value orderings:
+
+<UL>
+
+ <LI><CODE>CUPS_ORDER_CHUNKED</CODE> - CMYK&nbsp;CMYK&nbsp;CMYK
+
+ <LI><CODE>CUPS_ORDER_BANDED</CODE> - CCC&nbsp;MMM&nbsp;YYY&nbsp;KKK
+
+ <LI><CODE>CUPS_ORDER_PLANAR</CODE> - CCC&nbsp;...&nbsp;MMM&nbsp;...&nbsp;YYY&nbsp;...&nbsp;KKK&nbsp;...
+
+</UL>
+
+<H3>Raster Colorspace Values</H3>
+
+<P>The <CODE>cups_cspace_t</CODE> enumeration defines the possible colorspaces:
+
+<UL>
+
+ <LI><CODE>CUPS_CSPACE_W</CODE> - White (luminance)
+
+ <LI><CODE>CUPS_CSPACE_RGB</CODE> - Red, green, blue
+
+ <LI><CODE>CUPS_CSPACE_RGBA</CODE> - Red, green, blue, alpha
+
+ <LI><CODE>CUPS_CSPACE_K</CODE> - Black
+
+ <LI><CODE>CUPS_CSPACE_CMY</CODE> - Cyan, magenta, yellow
+
+ <LI><CODE>CUPS_CSPACE_YMC</CODE> - Yellow, magenta, cyan
+
+ <LI><CODE>CUPS_CSPACE_CMYK</CODE> - Cyan, magenta, yellow, black
+
+ <LI><CODE>CUPS_CSPACE_YMCK</CODE> - Yellow, magenta, cyan, black
+
+ <LI><CODE>CUPS_CSPACE_KCMY</CODE> - Black, cyan, magenta, yellow
+
+ <LI><CODE>CUPS_CSPACE_KCMYcm</CODE> - Black, cyan, magenta, yellow,
+ light cyan, light magenta
+
+ <LI><CODE>CUPS_CSPACE_GMCK</CODE> - Metallic yellow (gold), metallic magenta,
+ metallic cyan, black
+
+ <LI><CODE>CUPS_CSPACE_GMCS</CODE> - Metallic yellow (gold), metallic magenta,
+ metallic cyan, metallic grey (silver)
+
+ <LI><CODE>CUPS_CSPACE_WHITE</CODE> - White pigment (black as white pigment)
+
+ <LI><CODE>CUPS_CSPACE_GOLD</CODE> - Gold foil (black as gold foil)
+
+ <LI><CODE>CUPS_CSPACE_SILVER</CODE> - Silver foil (black as silver foil)
+
+</UL>
+
+<H1 ALIGN="RIGHT"><A NAME="STRUCTURES">C - Structures</A></H1>
+
+<P>This appendix describes all of the structures that are
+defined by the CUPS API.
+
+<H2>CUPS Structures</H2>
+
+<H3><A NAME="cups_dest_t">CUPS Destinations</A></H3>
+
+<P>The CUPS destination structure (<CODE>cups_dest_t</CODE>)
+contains information on a specific destination or instance:
+
+<CENTER><TABLE WIDTH="90%" BORDER="1">
+<TR>
+ <TH>Member</TH>
+ <TH>Type</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>char *</TD>
+ <TD>The name of the printer or class.</TD>
+</TR>
+<TR>
+ <TD>instance</TD>
+ <TD>char *</TD>
+ <TD>The instance of the printer or class; NULL for the primary
+ instance.</TD>
+</TR>
+<TR>
+ <TD>is_default</TD>
+ <TD>int</TD>
+ <TD>1 if the destination is set as the default, 0 otherwise.</TD>
+</TR>
+<TR>
+ <TD>num_options</TD>
+ <TD>int</TD>
+ <TD>The number of options associated with this destination.</TD>
+</TR>
+<TR>
+ <TD>options</TD>
+ <TD><A HREF="#cups_option_t">cups_option_t *</A></TD>
+ <TD>The options associated with this destination.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3><A NAME="cups_job_t">CUPS Jobs</A></H3>
+
+<P>The CUPS job structure (<CODE>cups_job_t</CODE>) contains
+information on a specific job:
+
+<CENTER><TABLE WIDTH="90%" BORDER="1">
+<TR>
+ <TH>Member</TH>
+ <TH>Type</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>id</TD>
+ <TD>int</TD>
+ <TD>The job ID for this job.</TD>
+</TR>
+<TR>
+ <TD>dest</TD>
+ <TD>char *</TD>
+ <TD>The destination for this job (printer or class name).</TD>
+</TR>
+<TR>
+ <TD>title</TD>
+ <TD>char *</TD>
+ <TD>The job-name for this job (title).</TD>
+</TR>
+<TR>
+ <TD>user</TD>
+ <TD>char *</TD>
+ <TD>The job-originating-user-name for this job (username).</TD>
+</TR>
+<TR>
+ <TD>format</TD>
+ <TD>char *</TD>
+ <TD>The document-format for this job (MIME type string).</TD>
+</TR>
+<TR>
+ <TD>state</TD>
+ <TD>ipp_jstate</TD>
+ <TD>The current state of the job.</TD>
+</TR>
+<TR>
+ <TD>size</TD>
+ <TD>int</TD>
+ <TD>The size of this job in kilobytes.</TD>
+</TR>
+<TR>
+ <TD>priority</TD>
+ <TD>int</TD>
+ <TD>The priority of this job from 1 to 100 (50 is normal).</TD>
+</TR>
+<TR>
+ <TD>completed_time</TD>
+ <TD>time_t</TD>
+ <TD>The time the job was completed, or 0 if not yet completed.</TD>
+</TR>
+<TR>
+ <TD>creation_time</TD>
+ <TD>time_t</TD>
+ <TD>The time the job was queued.</TD>
+</TR>
+<TR>
+ <TD>processing_time</TD>
+ <TD>time_t</TD>
+ <TD>The time the job started printing.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3><A NAME="cups_lang_t">CUPS Messages</A></H3>
+
+<P>The CUPS messages structure (<CODE>cups_lang_t</CODE>)
+contains the character set, locale name, and messages array:
+
+<CENTER><TABLE WIDTH="90%" BORDER="1">
+<TR>
+ <TH>Member</TH>
+ <TH>Type</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>next</TD>
+ <TD>cups_lang_t *</TD>
+ <TD>Pointer to the next messages structure in memory.</TD>
+</TR>
+<TR>
+ <TD>used</TD>
+ <TD>int</TD>
+ <TD>The number of active users of this messages structure.</TD>
+</TR>
+<TR>
+ <TD>encoding</TD>
+ <TD>cups_encoding_t</TD>
+ <TD>The character encoding of the message strings.</TD>
+</TR>
+<TR>
+ <TD>language</TD>
+ <TD>char [16]</TD>
+ <TD>The language/locale name.</TD>
+</TR>
+<TR>
+ <TD>messages</TD>
+ <TD>char *[]</TD>
+ <TD>The array of message strings.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3><A NAME="cups_option_t">CUPS Options</A></H3>
+
+<P>The CUPS option structure (<CODE>cups_option_t</CODE>)
+contains the option name and string value:
+
+<CENTER><TABLE WIDTH="90%" BORDER="1">
+<TR>
+ <TH>Member</TH>
+ <TH>Type</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>char *</TD>
+ <TD>The name of the option.</TD>
+</TR>
+<TR>
+ <TD>value</TD>
+ <TD>char *</TD>
+ <TD>The string value of the option.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H2>Networking Structures</H2>
+
+<H3><A NAME="http_t">HTTP State</A></H3>
+
+<P>The HTTP state structure (<CODE>http_t</CODE>) contains the
+current state of a HTTP request or response:
+
+<CENTER><TABLE WIDTH="90%" BORDER="1">
+<TR>
+ <TH>Member</TH>
+ <TH>Type</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>fd</TD>
+ <TD>int</TD>
+ <TD>The socket for the HTTP connection.</TD>
+</TR>
+<TR>
+ <TD>blocking</TD>
+ <TD>int</TD>
+ <TD>1 if the HTTP functions should block, 0 if not.</TD>
+</TR>
+<TR>
+ <TD>error</TD>
+ <TD>int</TD>
+ <TD>The last OS error that occurred on the socket.</TD>
+</TR>
+<TR>
+ <TD>activity</TD>
+ <TD>time_t</TD>
+ <TD>The last time the HTTP connection was used.</TD>
+</TR>
+<TR>
+ <TD>state</TD>
+ <TD>http_state_t</TD>
+ <TD>The current HTTP request/response state.</TD>
+</TR>
+<TR>
+ <TD>status</TD>
+ <TD>int</TD>
+ <TD>The last HTTP status seen.</TD>
+</TR>
+<TR>
+ <TD>version</TD>
+ <TD>http_version_t</TD>
+ <TD>The HTTP protocol version in use.</TD>
+</TR>
+<TR>
+ <TD>keep_alive</TD>
+ <TD>http_keep_alive_t</TD>
+ <TD>Whether or not to use Keep-Alive</TD>
+</TR>
+<TR>
+ <TD>hostaddr</TD>
+ <TD>struct sockaddr_in</TD>
+ <TD>The IPv4 address of the HTTP server.</TD>
+</TR>
+<TR>
+ <TD>hostname</TD>
+ <TD>char []</TD>
+ <TD>The hostname of the HTTP server.</TD>
+</TR>
+<TR>
+ <TD>fields</TD>
+ <TD>char [][]</TD>
+ <TD>The string values of all HTTP request/response
+ fields.</TD>
+</TR>
+<TR>
+ <TD>data</TD>
+ <TD>char *</TD>
+ <TD>Current byte in data buffer.</TD>
+</TR>
+<TR>
+ <TD>data_encoding</TD>
+ <TD>http_encoding_t</TD>
+ <TD>The transfer encoding for the request/response.</TD>
+</TR>
+<TR>
+ <TD>data_remaining</TD>
+ <TD>int</TD>
+ <TD>The number of bytes remaining in the current request,
+ response, or chunk.</TD>
+</TR>
+<TR>
+ <TD>used</TD>
+ <TD>int</TD>
+ <TD>The number of bytes that are used in the buffer.</TD>
+</TR>
+<TR>
+ <TD>buffer</TD>
+ <TD>char []</TD>
+ <TD>The read/write buffer.</TD>
+</TR>
+<TR>
+ <TD>auth_type</TD>
+ <TD>int</TD>
+ <TD>The type of authentication in use.</TD>
+</TR>
+<TR>
+ <TD>md5_state</TD>
+ <TD>md5_state_t</TD>
+ <TD>The current MD5 digest state.</TD>
+</TR>
+<TR>
+ <TD>nonce</TD>
+ <TD>char []</TD>
+ <TD>The nonce value for Digest authentication.</TD>
+</TR>
+<TR>
+ <TD>nonce_count</TD>
+ <TD>int</TD>
+ <TD>The nonce count value.</TD>
+</TR>
+<TR>
+ <TD>tls</TD>
+ <TD>void *</TD>
+ <TD>A pointer to private encryption data.</TD>
+</TR>
+<TR>
+ <TD>encryption</TD>
+ <TD>http_encryption_t</TD>
+ <TD>The current encryption mode.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3><A NAME="ipp_t">IPP State</A></H3>
+
+<P>The IPP state structure (<CODE>ipp_t</CODE>) contains the
+current state of a IPP request or response:
+
+<CENTER><TABLE WIDTH="90%" BORDER="1">
+<TR>
+ <TH>Member</TH>
+ <TH>Type</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD></TD>
+</TR>
+</TABLE></CENTER>
+
+<H2>Raster Structures</H2>
+
+<H3><A NAME="cups_raster_header_t">Raster Page Header</A></H3>
+
+<P>The raster page header (<CODE>cups_raster_header_t</CODE>)
+consists of the PostScript page device dictionary for the page:
+
+<CENTER><TABLE WIDTH="90%" BORDER="1">
+<TR>
+ <TH>Member</TH>
+ <TH>Type</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>MediaClass</TD>
+ <TD>char[64]</TD>
+ <TD>The media class name</TD>
+</TR>
+<TR>
+ <TD>MediaColor</TD>
+ <TD>char[64]</TD>
+ <TD>The media color name</TD>
+</TR>
+<TR>
+ <TD>MediaType</TD>
+ <TD>char[64]</TD>
+ <TD>The media type name</TD>
+</TR>
+<TR>
+ <TD>OutputType</TD>
+ <TD>char[64]</TD>
+ <TD>The output type name</TD>
+</TR>
+<TR>
+ <TD>AdvanceDistance</TD>
+ <TD>unsigned</TD>
+ <TD>The distance to advance the media in points</TD>
+</TR>
+<TR>
+ <TD>AdvanceMedia</TD>
+ <TD>cups_adv_t</TD>
+ <TD>When to advance the media</TD>
+</TR>
+<TR>
+ <TD>Collate</TD>
+ <TD>cups_bool_t</TD>
+ <TD>Whether or not to produce collated copies</TD>
+</TR>
+<TR>
+ <TD>CutMedia</TD>
+ <TD>cups_cut_t</TD>
+ <TD>When to cut the media</TD>
+</TR>
+<TR>
+ <TD>Duplex</TD>
+ <TD>cups_bool_t</TD>
+ <TD>Whether or not to print on both sides of the paper</TD>
+</TR>
+<TR>
+ <TD>HWResolution</TD>
+ <TD>unsigned[2]</TD>
+ <TD>The resolution of the page image in pixels per inch; the
+ HWResolution[0] represents the horizontal resolution and
+ HWResolution[1] represents the vertical resolution</TD>
+</TR>
+<TR>
+ <TD>ImagingBoundingBox</TD>
+ <TD>unsigned[4]</TD>
+ <TD>The bounding box for the page in points; the elements
+ represent the left, bottom, right, and top coordinates of the
+ imaged area (if 0 then the whole page is imaged)</TD>
+</TR>
+<TR>
+ <TD>InsertSheet</TD>
+ <TD>cups_bool_t</TD>
+ <TD>Whether or not to insert a sheet before this page</TD>
+</TR>
+<TR>
+ <TD>Jog</TD>
+ <TD>cups_jog_t</TD>
+ <TD>When to jog copies of the page</TD>
+</TR>
+<TR>
+ <TD>LeadingEdge</TD>
+ <TD>cups_edge_t</TD>
+ <TD>The leading edge of the page</TD>
+</TR>
+<TR>
+ <TD>Margins</TD>
+ <TD>unsigned[2]</TD>
+ <TD>The lower-lefthand margin of the page in points</TD>
+</TR>
+<TR>
+ <TD>ManualFeed</TD>
+ <TD>cups_bool_t</TD>
+ <TD>Whether or not to manually feed the page</TD>
+</TR>
+<TR>
+ <TD>MediaPosition</TD>
+ <TD>unsigned</TD>
+ <TD>The input slot number to use</TD>
+</TR>
+<TR>
+ <TD>MediaWeight</TD>
+ <TD>unsigned</TD>
+ <TD>The weight of the output media in grams/m<SUP>2</SUP></TD>
+</TR>
+<TR>
+ <TD>MirrorPrint</TD>
+ <TD>cups_bool_t</TD>
+ <TD>Whether or not to mirror the print</TD>
+</TR>
+<TR>
+ <TD>NegativePrint</TD>
+ <TD>cups_bool_t</TD>
+ <TD>Whether or not to invert the print</TD>
+</TR>
+<TR>
+ <TD>NumCopies</TD>
+ <TD>unsigned</TD>
+ <TD>The number of copies to produce</TD>
+</TR>
+<TR>
+ <TD>Orientation</TD>
+ <TD>cups_orient_t</TD>
+ <TD>The orientation of the page image</TD>
+</TR>
+<TR>
+ <TD>OutputFaceUp</TD>
+ <TD>cups_bool_t</TD>
+ <TD>Whether or not to output the page face up</TD>
+</TR>
+<TR>
+ <TD>PageSize</TD>
+ <TD>unsigned[2]</TD>
+ <TD>The width and height of the page in points</TD>
+</TR>
+<TR>
+ <TD>Separations</TD>
+ <TD>cups_bool_t</TD>
+ <TD>Whether or not to output separations</TD>
+</TR>
+<TR>
+ <TD>TraySwitch</TD>
+ <TD>cups_bool_t</TD>
+ <TD>Whether or not to automatically switch trays for the requested
+ media size/type</TD>
+</TR>
+<TR>
+ <TD>Tumble</TD>
+ <TD>cups_bool_t</TD>
+ <TD>Whether or not to rotate the back side of the page</TD>
+</TR>
+<TR>
+ <TD>cupsWidth</TD>
+ <TD>unsigned</TD>
+ <TD>The width of the page image in pixels</TD>
+</TR>
+<TR>
+ <TD>cupsHeight</TD>
+ <TD>unsigned</TD>
+ <TD>The height of the page image in pixels</TD>
+</TR>
+<TR>
+ <TD>cupsMediaType</TD>
+ <TD>unsigned</TD>
+ <TD>The device-specific media type code</TD>
+</TR>
+<TR>
+ <TD>cupsBitsPerColor</TD>
+ <TD>unsigned</TD>
+ <TD>The number of bits per color</TD>
+</TR>
+<TR>
+ <TD>cupsBitsPerPixel</TD>
+ <TD>unsigned</TD>
+ <TD>The number of bits per pixel</TD>
+</TR>
+<TR>
+ <TD>cupsBytesPerLine</TD>
+ <TD>unsigned</TD>
+ <TD>The number of bytes per line of image data</TD>
+</TR>
+<TR>
+ <TD>cupsColorOrder</TD>
+ <TD>cups_order_t</TD>
+ <TD>The order of color values</TD>
+</TR>
+<TR>
+ <TD>cupsColorSpace</TD>
+ <TD>cups_cspace_t</TD>
+ <TD>The type of color values</TD>
+</TR>
+<TR>
+ <TD>cupsCompression</TD>
+ <TD>unsigned</TD>
+ <TD>The device-specific compression code</TD>
+</TR>
+<TR>
+ <TD>cupsRowCount</TD>
+ <TD>unsigned</TD>
+ <TD>The device-specific row count</TD>
+</TR>
+<TR>
+ <TD>cupsRowFeed</TD>
+ <TD>unsigned</TD>
+ <TD>The device-specific row feed</TD>
+</TR>
+<TR>
+ <TD>cupsRowStep</TD>
+ <TD>unsigned</TD>
+ <TD>The device-specific row step</TD>
+</TR>
+</TABLE></CENTER>
+
+<H1 ALIGN="RIGHT"><A NAME="FUNCTIONS">D - Functions</A></H1>
+
+<P>This appendix provides a reference for all of the CUPS API functions.
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsAddDest">cupsAddDest()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsAddDest(const char *name,
+ const char *instance,
+ int num_dests,
+ cups_dest_t **dests);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of the destination.</TD>
+</TR>
+<TR>
+ <TD>instance</TD>
+ <TD>The instance of the destination, or NULL for the primary instance.</TD>
+</TR>
+<TR>
+ <TD>num_dests</TD>
+ <TD>The number of destinations in the array.</TD>
+</TR>
+<TR>
+ <TD>dest</TD>
+ <TD>A pointer to the destination array pointer.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The new number of destinations in the array.
+
+<H3>Description</H3>
+
+<P><CODE>cupsAddDest()</CODE> adds the named destination to the destination
+array if it does not already exist.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_dests;
+<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
+
+
+num_dests = cupsAddDests("foo", "bar", num_dests, &amp;dests);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsFreeDests"><CODE>cupsFreeDests()</CODE></A>,
+<A HREF="#cupsGetDest"><CODE>cupsGetDest()</CODE></A>,
+<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsAddOption">cupsAddOption()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsAddOption(const char *name,
+ const char *value,
+ int num_options,
+ cups_option_t **options);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of the option.</TD>
+</TR>
+<TR>
+ <TD>value</TD>
+ <TD>The value of the option.</TD>
+</TR>
+<TR>
+ <TD>num_options</TD>
+ <TD>Number of options currently in the array.</TD>
+</TR>
+<TR>
+ <TD>options</TD>
+ <TD>Pointer to the options array.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The new number of options.
+
+<H3>Description</H3>
+
+<P><CODE>cupsAddOption()</CODE> adds an option to the specified array.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups.h&gt;
+
+...
+
+/* Declare the options array */
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+
+/* Initialize the options array */
+num_options = 0;
+options = (cups_option_t *)0;
+
+/* Add options using cupsAddOption() */
+num_options = cupsAddOption("media", "letter", num_options, &amp;options);
+num_options = cupsAddOption("resolution", "300dpi", num_options, &amp;options);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#cupsEncodeOptions"><CODE>cupsEncodeOptions()</CODE></A>,
+<A HREF="#cupsFreeOptions"><CODE>cupsFreeOptions()</CODE></A>,
+<A HREF="#cupsGetOption"><CODE>cupsGetOption()</CODE></A>,
+<A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsCancelJob">cupsCancelJob()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsCancelJob(const char *dest,
+ int job);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>dest</TD>
+ <TD>Printer or class name</TD>
+</TR>
+<TR>
+ <TD>job</TD>
+ <TD>Job ID</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>1 on success, 0 on failure. On failure the error can be found by calling
+<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>.
+
+<H3>Description</H3>
+
+<P><CODE>cupsCancelJob()</CODE> cancels the specifies job.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups.h&gt;
+
+cupsCancelJob("LaserJet", 1);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>,
+<A HREF="#cupsPrintFile"><CODE>cupsPrintFile()</CODE></A>,
+<A HREF="#cupsPrintFiles"><CODE>cupsPrintFiles()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsDoFileRequest">cupsDoFileRequest()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_t *
+cupsDoFileRequest(http_t *http,
+ ipp_t *request,
+ const char *resource,
+ const char *filename);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>HTTP connection to server.</TD>
+</TR>
+<TR>
+ <TD>request</TD>
+ <TD>IPP request data.</TD>
+</TR>
+<TR>
+ <TD>resource</TD>
+ <TD>HTTP resource name for POST.</TD>
+</TR>
+<TR>
+ <TD>filename</TD>
+ <TD>File to send with POST request (<CODE>NULL</CODE> pointer if none.)</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>IPP response data or <CODE>NULL</CODE> if the request fails. On failure
+the error can be found by calling
+<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>.
+
+<H3>Description</H3>
+
+<P><CODE>cupsDoFileRequest()</CODE> does a HTTP POST request and provides the
+IPP request and optionally the contents of a file to the IPP server. It also
+handles resubmitting the request and performing password authentication as
+needed.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+<A HREF="#ipp_t">ipp_t</A> *request;
+ipp_t *response;
+
+...
+
+/* Get the default language */
+language = <A HREF="#cupsLangDefault">cupsLangDefault()</A>;
+
+/* Create a new IPP request */
+request = <A HREF="#ippNew">ippNew()</A>;
+
+request-&gt;request.op.operation_id = IPP_PRINT_FILE;
+request-&gt;request.op.request_id = 1;
+
+/* Add required attributes */
+<A HREF="#ippAddString">ippAddString</A>(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, <A HREF="#cupsLangEncoding">cupsLangEncoding</A>(language));
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language != NULL ? language-&gt;language : "C");
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://hostname/resource");
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, <A HREF="#cupsUser">cupsUser()</A>);
+
+/* Do the request... */
+response = cupsDoFileRequest(http, request, "/resource", "filename.txt");
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
+<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
+<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>,
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsDoRequest">cupsDoRequest()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_t *
+cupsDoRequest(http_t *http,
+ ipp_t *request,
+ const char *resource);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>HTTP connection to server.</TD>
+</TR>
+<TR>
+ <TD>request</TD>
+ <TD>IPP request data.</TD>
+</TR>
+<TR>
+ <TD>resource</TD>
+ <TD>HTTP resource name for POST.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>IPP response data or <CODE>NULL</CODE> if the request fails. On failure
+the error can be found by calling
+<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>.
+
+<H3>Description</H3>
+
+<P><CODE>cupsDoRequest()</CODE> does a HTTP POST request and provides
+the IPP request to the IPP server. It also handles resubmitting the
+request and performing password authentication as needed.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+<A HREF="#ipp_t">ipp_t</A> *request;
+ipp_t *response;
+
+...
+
+/* Get the default language */
+language = <A HREF="#cupsLangDefault">cupsLangDefault()</A>;
+
+/* Create a new IPP request */
+request = <A HREF="#ippNew">ippNew()</A>;
+
+request-&gt;request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+request-&gt;request.op.request_id = 1;
+
+/* Add required attributes */
+<A HREF="#ippAddString">ippAddString</A>(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, <A HREF="#cupsLangEncoding">cupsLangEncoding</A>(language));
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language != NULL ? language-&gt;language : "C");
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://hostname/resource");
+
+/* Do the request... */
+response = cupsDoRequest(http, request, "/resource");
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
+<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
+<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>,
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsEncodeOptions">cupsEncodeOptions()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsEncodeOptions(ipp_t *ipp,
+ int num_options,
+ cups_option_t *options);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request.</TD>
+</TR>
+<TR>
+ <TD>num_options</TD>
+ <TD>The number of options.</TD>
+</TR>
+<TR>
+ <TD>options</TD>
+ <TD>The options.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P><CODE>cupsEncodeOptions()</CODE> encodes all of the options
+in the specified array as IPP attributes and adds them to the
+IPP request.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+<A HREF="#ipp_t">ipp_t</A> *ipp;
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+
+
+cupsEncodeOptions(ipp, num_options, options);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsAddOption"><CODE>cupsAddOption()</CODE></A>,
+<A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A>,
+<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsEncryption">cupsEncryption()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+http_encryption_t
+cupsEncryption(void);
+</PRE>
+
+<H3>Returns</H3>
+
+<P>The current encryption setting.
+
+<H3>Description</H3>
+
+<P><CODE>cupsEncryption()</CODE> returns the current encryption setting
+for IPP requests such as printing.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+printf("The current encryption setting is %d.\n", cupsEncryption());
+
+http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
+<A HREF="#httpConnectEncrypt"><CODE>httpConnectEncrypt()</CODE></A>,
+<A HREF="#ippPort"><CODE>ippPort()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsFreeDests">cupsFreeDests()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsFreeDests(int num_dests,
+ cups_dest_t *dests);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>num_dests</TD>
+ <TD>The number of destinations in the array.</TD>
+</TR>
+<TR>
+ <TD>dests</TD>
+ <TD>The destination array.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P><CODE>cupsFreeDests()</CODE> frees a destination array that was
+created using <CODE>cupsGetDests()</CODE>.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_dests;
+<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
+cups_dest_t *dest;
+
+num_dests = cupsGetDests(&amp;dests);
+dest = cupsGetDest(NULL, NULL, num_dests, dests);
+
+if (dest)
+ printf("The default destination is %s\n", dest->name);
+else
+ puts("No default destination.");
+
+cupsFreeDests(num_dests, dests);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsGetDest"><CODE>cupsGetDest()</CODE></A>,
+<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsFreeJobs">cupsFreeJobs()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsFreeJobs(int num_jobs,
+ cups_job_t *jobs);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>num_jobs</TD>
+ <TD>The number of jobs.</TD>
+</TR>
+<TR>
+ <TD>jobs</TD>
+ <TD>The job array.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P><CODE>cupsFreeJobs()</CODE> frees an array of print jobs created by
+the <CODE>cupsGetJobs()</CODE> function.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int i;
+int num_jobs;
+<A HREF="#cups_job_t">cups_job_t</A> *jobs;
+
+
+num_jobs = cupsGetJobs(&amp;jobs, NULL, 0, 0);
+
+printf("%d active job(s):\n", num_jobs);
+for (i = 0; i &lt; num_jobs; i ++)
+ printf("%-16.16s %-6d %-12.12s %s (%s)\n", jobs[i].dest, jobs[i].id,
+ jobs[i].user, jobs[i].title,
+ jobs[i].state != IPP_JOB_PENDING ? "printing" : "pending");
+
+cupsFreeJobs(num_jobs, jobs);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsGetJobs"><CODE>cupsGetJobs()</CODE></A>,
+<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsFreeOptions">cupsFreeOptions()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsFreeOptions(int num_options,
+ cups_option_t *options);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>num_options</TD>
+ <TD>Number of options in array.</TD>
+</TR>
+<TR>
+ <TD>options</TD>
+ <TD>Pointer to options array.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P><CODE>cupsFreeOptions()</CODE> frees all memory associated with the
+option array specified.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+
+...
+
+cupsFreeOptions(num_options, options);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsAddOption"><CODE>cupsAddOption()</CODE></A>,
+<A HREF="#cupsEncodeOptions"><CODE>cupsEncodeOptions()</CODE></A>,
+<A HREF="#cupsGetOption"><CODE>cupsGetOption()</CODE></A>,
+<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
+<A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsGetClasses">cupsGetClasses()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsGetClasses(char ***classes);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>classes</TD>
+ <TD>Pointer to character pointer array.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of printer classes available.
+
+<H3>Description</H3>
+
+<P><CODE>cupsGetClasses()</CODE> gets a list of the available printer classes.
+The returned array should be freed using the <CODE>free()</CODE> when it is
+no longer needed.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int i;
+int num_classes;
+char **classes;
+
+...
+
+num_classes = cupsGetClasses(&classes);
+
+...
+
+if (num_classes > 0)
+{
+ for (i = 0; i &lt; num_classes; i ++)
+ free(classes[i]);
+
+ free(classes);
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsGetDefault"><CODE>cupsGetDefault()</CODE></A>,
+<A HREF="#cupsGetPrinters"><CODE>cupsGetPrinters()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsGetDefault">cupsGetDefault()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+cupsGetDefault(void);
+</PRE>
+
+<H3>Returns</H3>
+
+<P>A pointer to the default destination.
+
+<H3>Description</H3>
+
+<P><CODE>cupsGetDefault()</CODE> gets the default destination printer or class.
+The default destination is stored in a static string and will be overwritten
+(usually with the same value) after each call.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+printf("The default destination is %s\n", cupsGetDefault());
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsGetClasses"><CODE>cupsGetClasses()</CODE></A>,
+<A HREF="#cupsGetPrinters"><CODE>cupsGetPrinters()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsGetDest">cupsGetDest()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+cups_dest_t *
+cupsGetDest(const char *name,
+ const char *instance,
+ int num_dests,
+ cups_dest_t *dests);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of the destination, or NULL for the default destination.</TD>
+</TR>
+<TR>
+ <TD>instance</TD>
+ <TD>The instance of the destination, or NULL for the primary instance.</TD>
+</TR>
+<TR>
+ <TD>num_dests</TD>
+ <TD>The number of destinations.</TD>
+</TR>
+<TR>
+ <TD>dests</TD>
+ <TD>The destination array.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the specified destination, or NULL if none exists.
+
+<H3>Description</H3>
+
+<P><CODE>cupsGetDest()</CODE> finds the specified destination in the array
+of destinations created by the <CODE>cupsGetDests()</CODE> function.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_dests;
+<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
+cups_dest_t *dest;
+
+num_dests = cupsGetDests(&amp;dests);
+dest = cupsGetDest(NULL, NULL, num_dests, dests);
+
+if (dest)
+ printf("The default destination is %s\n", dest->name);
+else
+ puts("No default destination.");
+
+cupsFreeDests(num_dests, dests);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>,
+<A HREF="#cupsGetJobs"><CODE>cupsGetJobs()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsGetDests">cupsGetDests()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsGetDests(cups_dest_t **dests);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>dests</TD>
+ <TD>A pointer to a destination array pointer.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of available destinations.
+
+<H3>Description</H3>
+
+<P><CODE>cupsGetDests()</CODE> creates an array of available
+destinations that the user can print to. The array should be
+freed using the <CODE>cupsFreeDests()</CODE> function.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_dests;
+<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
+cups_dest_t *dest;
+
+num_dests = cupsGetDests(&amp;dests);
+dest = cupsGetDest(NULL, NULL, num_dests, dests);
+
+if (dest)
+ printf("The default destination is %s\n", dest->name);
+else
+ puts("No default destination.");
+
+cupsFreeDests(num_dests, dests);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsFreeDests"><CODE>cupsFreeDests()</CODE></A>,
+<A HREF="#cupsGetDest"><CODE>cupsGetDest()</CODE></A>,
+<A HREF="#cupsGetJobs"><CODE>cupsGetJobs()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsGetJobs">cupsGetJobs()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsGetJobs(cups_job_t **jobs,
+ const char *dest,
+ int myjobs,
+ int completed);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>jobs</TD>
+ <TD>A pointer to the job array pointer.</TD>
+</TR>
+<TR>
+ <TD>dest</TD>
+ <TD>The destination name, or NULL if jobs for all destinations are requested.</TD>
+</TR>
+<TR>
+ <TD>myjobs</TD>
+ <TD>1 if only those jobs submitted by the current
+ <CODE>cupsUser()</CODE> should be returned, 0 for jobs
+ submitted by all users.</TD>
+</TR>
+<TR>
+ <TD>completed</TD>
+ <TD>1 if only completed jobs should be returned, 0 if only
+ pending/processing jobs should be returned.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of jobs.
+
+<H3>Description</H3>
+
+<P><CODE>cupsGetJobs()</CODE> creates an array of print jobs based on the
+arguments supplied in the function call. The returned array should be freed
+using the <CODE>cupsFreeJobs()</CODE> function.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int i;
+int num_jobs;
+<A HREF="#cups_job_t">cups_job_t</A> *jobs;
+
+
+num_jobs = cupsGetJobs(&amp;jobs, NULL, 0, 0);
+
+printf("%d active job(s):\n", num_jobs);
+for (i = 0; i &lt; num_jobs; i ++)
+ printf("%-16.16s %-6d %-12.12s %s (%s)\n", jobs[i].dest, jobs[i].id,
+ jobs[i].user, jobs[i].title,
+ jobs[i].state != IPP_JOB_PENDING ? "printing" : "pending");
+
+cupsFreeJobs(num_jobs, jobs);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsFreeJobs"><CODE>cupsFreeJobs()</CODE></A>,
+<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsGetOption">cupsGetOption()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+cupsGetOption(const char *name,
+ int num_options,
+ cups_option_t *options);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of the option.</TD>
+</TR>
+<TR>
+ <TD>num_options</TD>
+ <TD>The number of options in the array.</TD>
+</TR>
+<TR>
+ <TD>options</TD>
+ <TD>The options array.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the option values or <CODE>NULL</CODE> if the option is
+not defined.
+
+<H3>Description</H3>
+
+<P><CODE>cupsGetOption()</CODE> returns the first occurrence of the
+named option. If the option is not included in the options array then a
+<CODE>NULL</CODE> pointer is returned.
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_options;
+cups_option_t *options;
+const char *media;
+
+...
+
+media = cupsGetOption("media", num_options, options);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsAddOption"><CODE>cupsAddOption()</CODE></A>,
+<A HREF="#cupsEncodeOptions"><CODE>cupsEncodeOptions()</CODE></A>,
+<A HREF="#cupsFreeOptions"><CODE>cupsFreeOptions()</CODE></A>,
+<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
+<A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsGetPassword">cupsGetPassword()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+cupsGetPassword(const char *prompt);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>prompt</TD>
+ <TD>The prompt to display to the user.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the password that was entered or <CODE>NULL</CODE> if no
+password was entered.
+
+<H3>Description</H3>
+
+<P><CODE>cupsGetPassword()</CODE> displays the prompt string and asks the user
+for a password. The password text is not echoed to the user.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+char *password;
+
+...
+
+password = cupsGetPassword("Please enter a password:");
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
+<A HREF="#cupsSetPasswordCB"><CODE>cupsSetPasswordCB()</CODE></A>,
+<A HREF="#cupsSetServer"><CODE>cupsSetServer()</CODE></A>,
+<A HREF="#cupsSetUser"><CODE>cupsSetUser()</CODE></A>,
+<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsGetPPD">cupsGetPPD()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+cupsGetPPD(const char *printer);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>printer</TD>
+ <TD>The name of the printer.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The name of a temporary file containing the PPD file or <CODE>NULL</CODE>
+if the printer cannot be located or does not have a PPD file.
+
+<H3>Description</H3>
+
+<P><CODE>cupsGetPPD()</CODE> gets a copy of the PPD file for the named printer.
+The printer name can be of the form "printer" or "printer@hostname".
+
+<P>You should remove (unlink) the PPD file after you are done using it. The
+filename is stored in a static buffer and will be overwritten with each call
+to <CODE>cupsGetPPD()</CODE>.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+char *ppd;
+
+...
+
+ppd = cupsGetPPD("printer@hostname");
+
+...
+
+unlink(ppd);
+</PRE>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsGetPrinters">cupsGetPrinters()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsGetPrinters(char ***printers);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>printers</TD>
+ <TD>Pointer to character pointer array.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of printer printers available.
+
+<H3>Description</H3>
+
+<P><CODE>cupsGetPrinters()</CODE> gets a list of the available printers.
+The returned array should be freed using the <CODE>free()</CODE> when it is
+no longer needed.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int i;
+int num_printers;
+char **printers;
+
+...
+
+num_printers = cupsGetPrinters(&printers);
+
+...
+
+if (num_printers > 0)
+{
+ for (i = 0; i &lt; num_printers; i ++)
+ free(printers[i]);
+
+ free(printers);
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsGetClasses"><CODE>cupsGetClasses()</CODE></A>
+<A HREF="#cupsGetDefault"><CODE>cupsGetDefault()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsLangDefault">cupsLangDefault()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+cupsLangDefault(void);
+</PRE>
+
+<H3>Returns</H3>
+
+<P>A pointer to the default language structure.
+
+<H3>Description</H3>
+
+<P><CODE>cupsLangDefault()</CODE> returns a language structure for the default
+language. The default language is defined by the <CODE>LANG</CODE> environment
+variable. If the specified language cannot be located then the POSIX (English)
+locale is used.
+
+<P>Call <CODE>cupsLangFree()</CODE> to free any memory associated with the
+language structure when you are done.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/language.h&gt;
+
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+...
+
+language = cupsLangDefault();
+
+...
+
+cupsLangFree(language);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
+<A HREF="#cupsLangFlush"><CODE>cupsLangFlush()</CODE></A>,
+<A HREF="#cupsLangFree"><CODE>cupsLangFree()</CODE></A>,
+<A HREF="#cupsLangGet"><CODE>cupsLangGet()</CODE></A>,
+<A HREF="#cupsLangString"><CODE>cupsLangString()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsLangEncoding">cupsLangEncoding()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+char *
+cupsLangEncoding(cups_lang_t *language);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>language</TD>
+ <TD>The language structure.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the encoding string.
+
+<H3>Description</H3>
+
+<P><CODE>cupsLangEncoding()</CODE> returns the language encoding used for the
+specified language, e.g. "iso-8859-1", "utf-8", etc.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/language.h&gt;
+
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+char *encoding;
+...
+
+language = cupsLangDefault();
+encoding = cupsLangEncoding(language);
+...
+
+cupsLangFree(language);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
+<A HREF="#cupsLangFlush"><CODE>cupsLangFlush()</CODE></A>,
+<A HREF="#cupsLangFree"><CODE>cupsLangFree()</CODE></A>,
+<A HREF="#cupsLangGet"><CODE>cupsLangGet()</CODE></A>,
+<A HREF="#cupsLangString"><CODE>cupsLangString()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsLangFlush">cupsLangFlush()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsLangFlush(void);
+</PRE>
+
+<H3>Description</H3>
+
+<P><CODE>cupsLangFlush()</CODE> frees all language structures that have been
+allocated.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/language.h&gt;
+
+...
+
+cupsLangFlush();
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
+<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
+<A HREF="#cupsLangFree"><CODE>cupsLangFree()</CODE></A>,
+<A HREF="#cupsLangGet"><CODE>cupsLangGet()</CODE></A>,
+<A HREF="#cupsLangString"><CODE>cupsLangString()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsLangFree">cupsLangFree()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsLangFree(cups_lang_t *language);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>language</TD>
+ <TD>The language structure to free.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P><CODE>cupsLangFree()</CODE> frees the specified language structure.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/language.h&gt;
+
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+...
+
+cupsLangFree(language);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
+<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
+<A HREF="#cupsLangFlush"><CODE>cupsLangFlush()</CODE></A>,
+<A HREF="#cupsLangGet"><CODE>cupsLangGet()</CODE></A>,
+<A HREF="#cupsLangString"><CODE>cupsLangString()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsLangGet">cupsLangGet()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+cups_lang_t *
+cupsLangGet(const char *name);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of the locale.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to a language structure.
+
+<H3>Description</H3>
+
+<P><CODE>cupsLangGet()</CODE> returns a language structure for the specified
+locale. If the locale is not defined then the POSIX (English) locale is
+substituted.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/language.h&gt;
+
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+
+...
+
+language = cupsLangGet("fr");
+
+...
+
+cupsLangFree(language);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
+<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
+<A HREF="#cupsLangFlush"><CODE>cupsLangFlush()</CODE></A>,
+<A HREF="#cupsLangFree"><CODE>cupsLangFree()</CODE></A>,
+<A HREF="#cupsLangString"><CODE>cupsLangString()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsLangString">cupsLangString()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+char *
+cupsLangString(cups_lang_t *language,
+ int message);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>language</TD>
+ <TD>The language to query.</TD>
+</TR>
+<TR>
+ <TD>message</TD>
+ <TD>The message number.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the message string or <CODE>NULL</CODE> if the message is
+not defined.
+
+<H3>Description</H3>
+
+<P><CODE>cupsLangString()</CODE> returns a pointer to the specified message
+string in the specified language.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/language.h&gt;
+
+<A HREF="#cups_lang_t">cups_lang_t</A> *language;
+char *s;
+...
+
+language = cupsLangGet("fr");
+
+s = cupsLangString(language, CUPS_MSG_YES);
+
+...
+
+cupsLangFree(language);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsLangDefault"><CODE>cupsLangDefault()</CODE></A>,
+<A HREF="#cupsLangEncoding"><CODE>cupsLangEncoding()</CODE></A>,
+<A HREF="#cupsLangFlush"><CODE>cupsLangFlush()</CODE></A>,
+<A HREF="#cupsLangFree"><CODE>cupsLangFree()</CODE></A>,
+<A HREF="#cupsLangGet"><CODE>cupsLangGet()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsLastError">cupsLastError()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_status_t
+cupsLastError(void);
+</PRE>
+
+<H3>Returns</H3>
+
+<P>An enumeration containing the last IPP error.
+
+<H3>Description</H3>
+
+<P><CODE>cupsLastError()</CODE> returns the last IPP error that occurred.
+If no error occurred then it will return <CODE>IPP_OK</CODE> or
+<CODE>IPP_OK_CONFLICT</CODE>.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+ipp_status_t status;
+
+...
+
+status = cupsLastError();
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsCancelJob"><CODE>cupsCancelJob()</CODE></A>,
+<A HREF="#cupsPrintFile"><CODE>cupsPrintFile()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsMarkOptions">cupsMarkOptions()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsMarkOptions(ppd_file_t *ppd,
+ int num_options,
+ cups_option_t *options);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file to mark.</TD>
+</TR>
+<TR>
+ <TD>num_options</TD>
+ <TD>The number of options in the options array.</TD>
+</TR>
+<TR>
+ <TD>options</TD>
+ <TD>A pointer to the options array.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of conflicts found.
+
+<H3>Description</H3>
+
+<P><CODE>cupsMarkOptions()</CODE> marks options in the PPD file. It also
+handles mapping of IPP option names and values to PPD option names.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+<A HREF="#ppd_file_t">ppd_file_t</A> *ppd;
+
+...
+
+cupsMarkOptions(ppd, num_options, options);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsAddOption"><CODE>cupsAddOption()</CODE></A>,
+<A HREF="#cupsFreeOptions"><CODE>cupsFreeOptions()</CODE></A>,
+<A HREF="#cupsGetOption"><CODE>cupsGetOption()</CODE></A>,
+<A HREF="#cupsParseOptions"><CODE>cupsParseOptions()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsParseOptions">cupsParseOptions()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsParseOptions(const char *arg,
+ int num_options,
+ cups_option_t **options);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>arg</TD>
+ <TD>The string containing one or more options.</TD>
+</TR>
+<TR>
+ <TD>num_options</TD>
+ <TD>The number of options in the options array.</TD>
+</TR>
+<TR>
+ <TD>options</TD>
+ <TD>A pointer to the options array pointer.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The new number of options in the array.
+
+<H3>Description</H3>
+
+<P><CODE>cupsParseOptions()</CODE> parses the specifies string for one
+or more options of the form "name=value", "name", or "noname". It can
+be called multiple times to combine the options from several strings.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_options;
+<A HREF="#cups_options_t">cups_option_t</A> *options;
+
+...
+
+num_options = 0;
+options = (cups_option_t *)0;
+num_options = cupsParseOptions(argv[5], num_options, &amp;options);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsAddOption"><CODE>cupsAddOption()</CODE></A>,
+<A HREF="#cupsFreeOptions"><CODE>cupsFreeOptions()</CODE></A>,
+<A HREF="#cupsGetOption"><CODE>cupsGetOption()</CODE></A>,
+<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsPrintFile">cupsPrintFile()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsPrintFile(const char *printer,
+ const char *filename,
+ const char *title,
+ int num_options,
+ cups_option_t *options);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>printer</TD>
+ <TD>The printer or class to print to.</TD>
+</TR>
+<TR>
+ <TD>filename</TD>
+ <TD>The file to print.</TD>
+</TR>
+<TR>
+ <TD>title</TD>
+ <TD>The job title.</TD>
+</TR>
+<TR>
+ <TD>num_options</TD>
+ <TD>The number of options in the options array.</TD>
+</TR>
+<TR>
+ <TD>options</TD>
+ <TD>A pointer to the options array.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The new job ID number or 0 on error.
+
+<H3>Description</H3>
+
+<P><CODE>cupsPrintFile()</CODE> sends a file to the specified printer or
+class for printing. If the job cannot be printed the error code can be
+found by calling <CODE>cupsLastError()</CODE>.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+int jobid;
+
+...
+
+jobid = cupsPrintFile("printer@hostname", "filename.ps", "Job Title",
+ num_options, options);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsCancelJob"><CODE>cupsCancelJob()</CODE></A>,
+<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>,
+<A HREF="#cupsPrintFiles"><CODE>cupsPrintFiles()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsPrintFiles">cupsPrintFiles()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsPrintFiles(const char *printer,
+ int num_files,
+ const char **files,
+ const char *title,
+ int num_options,
+ cups_option_t *options);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>printer</TD>
+ <TD>The printer or class to print to.</TD>
+</TR>
+<TR>
+ <TD>num_files</TD>
+ <TD>The number of files to print.</TD>
+</TR>
+<TR>
+ <TD>files</TD>
+ <TD>The files to print.</TD>
+</TR>
+<TR>
+ <TD>title</TD>
+ <TD>The job title.</TD>
+</TR>
+<TR>
+ <TD>num_options</TD>
+ <TD>The number of options in the options array.</TD>
+</TR>
+<TR>
+ <TD>options</TD>
+ <TD>A pointer to the options array.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The new job ID number or 0 on error.
+
+<H3>Description</H3>
+
+<P><CODE>cupsPrintFiles()</CODE> sends multiple files to the specified
+printer or class for printing. If the job cannot be printed the error
+code can be found by calling <CODE>cupsLastError()</CODE>.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_files;
+const char *files[100];
+int num_options;
+<A HREF="#cups_option_t">cups_option_t</A> *options;
+int jobid;
+
+...
+
+jobid = cupsPrintFiles("printer@hostname", num_files, files,
+ "Job Title", num_options, options);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsCancelJob"><CODE>cupsCancelJob()</CODE></A>,
+<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>,
+<A HREF="#cupsPrintFile"><CODE>cupsPrintFile()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsRasterClose">cupsRasterClose()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsRasterClose(cups_raster_t *ras);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ras</TD>
+ <TD>The raster stream to close.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P><CODE>cupsRasterClose()</CODE> closes the specified raster stream.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+
+...
+
+cupsRasterClose(ras);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A>,
+<A HREF="#cupsRasterReadHeader"><CODE>cupsRasterReadHeader()</CODE></A>,
+<A HREF="#cupsRasterReadPixels"><CODE>cupsRasterReadPixels()</CODE></A>,
+<A HREF="#cupsRasterWriteHeader"><CODE>cupsRasterWriteHeader()</CODE></A>,
+<A HREF="#cupsRasterWritePixels"><CODE>cupsRasterWritePixels()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsRasterOpen">cupsRasterOpen()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+cups_raster_t *
+cupsRasterOpen(int fd,
+ cups_mode_t mode);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>fd</TD>
+ <TD>The file descriptor to use.</TD>
+</TR>
+<TR>
+ <TD>mode</TD>
+ <TD>The mode to use; <CODE>CUPS_RASTER_READ</CODE> or
+ <CODE>CUPS_RASTER_WRITE</CODE>.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to a raster stream or <CODE>NULL</CODE> if there was an error.
+
+<H3>Description</H3>
+
+<P><CODE>cupsRasterOpen()</CODE> opens a raster stream for reading or writing.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+
+...
+
+ras = cupsRasterOpen(0, CUPS_RASTER_READ);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsRasterClose"><CODE>cupsRasterClose()</CODE></A>,
+<A HREF="#cupsRasterReadHeader"><CODE>cupsRasterReadHeader()</CODE></A>,
+<A HREF="#cupsRasterReadPixels"><CODE>cupsRasterReadPixels()</CODE></A>,
+<A HREF="#cupsRasterWriteHeader"><CODE>cupsRasterWriteHeader()</CODE></A>,
+<A HREF="#cupsRasterWritePixels"><CODE>cupsRasterWritePixels()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsRasterReadHeader">cupsRasterReadHeader()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+unsigned
+cupsRasterReadHeader(cups_raster_t *ras,
+ cups_page_header_t *header);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ras</TD>
+ <TD>The raster stream to read from.</TD>
+</TR>
+<TR>
+ <TD>header</TD>
+ <TD>A pointer to a page header structure to read into.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>1 on success, 0 on EOF or error.
+
+<H3>Description</H3>
+
+<P><CODE>cupsRasterReadHeader()</CODE> reads a page header from the specified
+raster stream.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+int line;
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
+unsigned char pixels[8192];
+...
+
+while (cupsRasterReadHeader(ras, &amp;header))
+{
+ ...
+
+ for (line = 0; line &lt; header.cupsHeight; line ++)
+ {
+ cupsRasterReadPixels(ras, pixels, header.cupsBytesPerLine);
+
+ ...
+ }
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsRasterClose"><CODE>cupsRasterClose()</CODE></A>,
+<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A>,
+<A HREF="#cupsRasterReadPixels"><CODE>cupsRasterReadPixels()</CODE></A>,
+<A HREF="#cupsRasterWriteHeader"><CODE>cupsRasterWriteHeader()</CODE></A>,
+<A HREF="#cupsRasterWritePixels"><CODE>cupsRasterWritePixels()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsRasterReadPixels">cupsRasterReadPixels()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+unsigned
+cupsRasterReadPixels(cups_raster_t *ras,
+ unsigned char *pixels,
+ unsigned length);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ras</TD>
+ <TD>The raster stream to read from.</TD>
+</TR>
+<TR>
+ <TD>pixels</TD>
+ <TD>The pointer to a pixel buffer.</TD>
+</TR>
+<TR>
+ <TD>length</TD>
+ <TD>The number of bytes of pixel data to read.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of bytes read or 0 on EOF or error.
+
+<H3>Description</H3>
+
+<P><CODE>cupsRasterReadPixels()</CODE> reads pixel data from the specified
+raster stream.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+int line;
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
+unsigned char pixels[8192];
+...
+
+while (cupsRasterReadHeader(ras, &amp;header))
+{
+ ...
+
+ for (line = 0; line &lt; header.cupsHeight; line ++)
+ {
+ cupsRasterReadPixels(ras, pixels, header.cupsBytesPerLine);
+
+ ...
+ }
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsRasterClose"><CODE>cupsRasterClose()</CODE></A>,
+<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A>,
+<A HREF="#cupsRasterReadHeader"><CODE>cupsRasterReadHeader()</CODE></A>,
+<A HREF="#cupsRasterWriteHeader"><CODE>cupsRasterWriteHeader()</CODE></A>,
+<A HREF="#cupsRasterWritePixels"><CODE>cupsRasterWritePixels()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsRasterWriteHeader">cupsRasterWriteHeader()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+unsigned
+cupsRasterWriteHeader(cups_raster_t *ras,
+ cups_page_header_t *header);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ras</TD>
+ <TD>The raster stream to write to.</TD>
+</TR>
+<TR>
+ <TD>header</TD>
+ <TD>A pointer to the page header to write.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>1 on success, 0 on error.
+
+<H3>Description</H3>
+
+<P><CODE>cupsRasterWriteHeader()</CODE> writes the specified page header to
+a raster stream.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+int line;
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
+unsigned char pixels[8192];
+...
+
+cupsRasterWriteHeader(ras, &amp;header);
+
+for (line = 0; line &lt; header.cupsHeight; line ++)
+{
+ ...
+
+ cupsRasterWritePixels(ras, pixels, header.cupsBytesPerLine);
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsRasterClose"><CODE>cupsRasterClose()</CODE></A>,
+<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A>,
+<A HREF="#cupsRasterReadHeader"><CODE>cupsRasterReadHeader()</CODE></A>,
+<A HREF="#cupsRasterReadPixels"><CODE>cupsRasterReadPixels()</CODE></A>,
+<A HREF="#cupsRasterWritePixels"><CODE>cupsRasterWritePixels()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsRasterWritePixels">cupsRasterWritePixels()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+unsigned
+cupsRasterWritePixels(cups_raster_t *ras,
+ unsigned char *pixels,
+ unsigned length);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ras</TD>
+ <TD>The raster stream to write to.</TD>
+</TR>
+<TR>
+ <TD>pixels</TD>
+ <TD>The pixel data to write.</TD>
+</TR>
+<TR>
+ <TD>length</TD>
+ <TD>The number of bytes to write.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of bytes written.
+
+<H3>Description</H3>
+
+<P><CODE>cupsRasterWritePixels()</CODE> writes the specified pixel data to a
+raster stream.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/raster.h&gt;
+
+int line;
+<A HREF="#cups_raster_t">cups_raster_t</A> *ras;
+<A HREF="#cups_raster_header_t">cups_raster_header_t</A> header;
+unsigned char pixels[8192];
+...
+
+cupsRasterWriteHeader(ras, &amp;header);
+
+for (line = 0; line &lt; header.cupsHeight; line ++)
+{
+ ...
+
+ cupsRasterWritePixels(ras, pixels, header.cupsBytesPerLine);
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsRasterClose"><CODE>cupsRasterClose()</CODE></A>,
+<A HREF="#cupsRasterOpen"><CODE>cupsRasterOpen()</CODE></A>,
+<A HREF="#cupsRasterReadHeader"><CODE>cupsRasterReadHeader()</CODE></A>,
+<A HREF="#cupsRasterReadPixels"><CODE>cupsRasterReadPixels()</CODE></A>,
+<A HREF="#cupsRasterWriteHeader"><CODE>cupsRasterWriteHeader()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsServer">cupsServer()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+cupsServer(void);
+</PRE>
+
+<H3>Returns</H3>
+
+<P>A pointer to the default server name.
+
+<H3>Description</H3>
+
+<P><CODE>cupsServer()</CODE> returns a pointer to the default server name.
+The server name is stored in a static location and will be overwritten with
+every call to <CODE>cupsServer()</CODE>.
+
+<P>The default server is determined from the following locations:
+
+<OL>
+
+ <LI>The <CODE>CUPS_SERVER</CODE> environment variable,
+
+ <LI>The <CODE>ServerName</CODE> directive in the
+ <VAR>client.conf</VAR> file,
+
+ <LI>The default host, "localhost".
+
+</OL>
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+const char *server;
+
+server = cupsServer();
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsGetPassword"><CODE>cupsGetPassword()</CODE></A>,
+<A HREF="#cupsSetPasswordCB"><CODE>cupsSetPasswordCB()</CODE></A>,
+<A HREF="#cupsSetServer"><CODE>cupsSetServer()</CODE></A>,
+<A HREF="#cupsSetUser"><CODE>cupsSetUser()</CODE></A>,
+<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsSetDests">cupsSetDests()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsSetDests(int num_dests,
+ cups_dest_t *dests);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>num_dests</TD>
+ <TD>Number of destinations.</TD>
+</TR>
+<TR>
+ <TD>dests</TD>
+ <TD>Array of destinations.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P><CODE>cupsSetDests()</CODE> saves the destination array to
+disk. If the current UID is 0, the destinations are saved in the
+<VAR>/etc/cups/lpoptions</VAR> file, otherwise they are saved
+in the <VAR>~/.lpoptions</VAR> file. This function is typically used
+to save the default options and instances that are set by the user.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int num_dests;
+<A HREF="#cups_dest_t">cups_dest_t</A> *dests;
+
+...
+
+cupsSetDests(num_dests, dests);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsGetDests"><CODE>cupsGetDests()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsSetEncryption">cupsSetEncryption()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsSetEncryption(http_encryption_t encryption);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>encryption</TD>
+ <TD>The type of encryption to use.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P><CODE>cupsSetEncryption()</CODE> sets the default type of encryption to
+use when connecting with the print server.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsEncryption"><CODE>cupsEncryption()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsSetPasswordCB">cupsSetPasswordCB()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsSetPasswordCB(const char *(*cb)(const char *prompt));
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>cb</TD>
+ <TD>The password callback function.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P><CODE>cupsSetPasswordCB()</CODE> sets the callback function to use when
+asking the user for a password. The callback function must accept a single
+character string pointer (the prompt string) and return <CODE>NULL</CODE>
+if the user did not enter a password string or a pointer to the password
+string otherwise.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+const char *
+my_password_cb(const char *prompt)
+{
+ return (getpass(prompt));
+}
+
+...
+
+char *password;
+
+...
+
+cupsSetPasswordCB(my_password_cb);
+password = cupsGetPassword("Please enter a password:");
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
+<A HREF="#cupsSetServer"><CODE>cupsSetServer()</CODE></A>,
+<A HREF="#cupsSetUser"><CODE>cupsSetUser()</CODE></A>,
+<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsSetServer">cupsSetServer()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsSetServer(const char *server);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>server</TD>
+ <TD>The default server to use.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P><CODE>cupsSetServer()</CODE> sets the default server to use for
+the CUPS API. If the <CODE>server</CODE> argument is <CODE>NULL</CODE>,
+the default server is used.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+cupsSetServer("foo.bar.com");
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
+<A HREF="#cupsSetPasswordCB"><CODE>cupsSetPasswordCB()</CODE></A>,
+<A HREF="#cupsSetUser"><CODE>cupsSetUser()</CODE></A>,
+<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsSetUser">cupsSetUser()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+cupsSetUser(const char *user);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>user</TD>
+ <TD>The user name string to use.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P><CODE>cupsSetUser()</CODE> sets the default user name for authentication.
+If the <CODE>user</CODE> argument is <CODE>NULL</CODE> then the current
+login user is used.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+...
+
+cupsSetUser("root");
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
+<A HREF="#cupsSetPasswordCB"><CODE>cupsSetPasswordCB()</CODE></A>,
+<A HREF="#cupsSetServer"><CODE>cupsSetServer()</CODE></A>,
+<A HREF="#cupsUser"><CODE>cupsUser()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsTempFd">cupsTempFd()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+cupsTempFd(char *filename,
+ int length);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>filename</TD>
+ <TD>The character string to hold the temporary filename.</TD>
+</TR>
+<TR>
+ <TD>length</TD>
+ <TD>The size of the filename string in bytes.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A file descriptor open for reading and writing.
+
+<H3>Description</H3>
+
+<P><CODE>cupsTempFd()</CODE> create a temporary filename in the
+<VAR>/var/tmp</VAR> directory or the directory specified by the
+<CODE>TMPDIR</CODE> environment variable.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+int fd;
+char filename[256];
+
+fd = cupsTempFd(filename, sizeof(filename));
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsTempFile"><CODE>cupsTempFile()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsTempFile">cupsTempFile()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+char *
+cupsTempFile(char *filename,
+ int length);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>filename</TD>
+ <TD>The character string to hold the temporary filename.</TD>
+</TR>
+<TR>
+ <TD>length</TD>
+ <TD>The size of the filename string in bytes.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to <CODE>filename</CODE>.
+
+<H3>Description</H3>
+
+<P><CODE>cupsTempFile()</CODE> creates a temporary filename in the
+<VAR>/var/tmp</VAR> directory or the directory specified by the
+<CODE>TMPDIR</CODE> environment variable.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+char filename[256];
+
+cupsTempFile(filename, sizeof(filename));
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsTempFd"><CODE>cupsTempFd()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="cupsUser">cupsUser()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+cupsUser(void);
+</PRE>
+
+<H3>Returns</H3>
+
+<P>A pointer to the current username or <CODE>NULL</CODE> if the user ID is
+undefined.
+
+<H3>Description</H3>
+
+<P><CODE>cupsUser()</CODE> returns the name associated with the current
+user ID as reported by the <CODE>getuid()</CODE> system call.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/cups.h&gt;
+
+const char *user;
+
+user = cupsUser();
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsGetPassword"><CODE>cupsGetPassword()</CODE></A>,
+<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpBlocking">httpBlocking()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+httpBlocking(http_t *http,
+ int blocking)
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>blocking</TD>
+ <TD>0 if the connection should be non-blocking, 1 if it should
+ be blocking</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P>The <CODE>httpBlocking()</CODE> function sets the blocking mode for the
+HTTP connection. By default HTTP connections will block (stop) the client
+program until data is available or can be sent to the server.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+http = httpConnect("server", port);
+httpBlocking(http, 0);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpCheck"><CODE>httpCheck()</CODE></A>,
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpCheck">httpCheck()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpCheck(http_t *http);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 if there is no data pending, 1 otherwise.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpCheck()</CODE> function checks to see if there is any data
+pending on an HTTP connection.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+if (httpCheck(http))
+{
+ ... do something ...
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpBlocking"><CODE>httpBlocking()</CODE></A>,
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpGets"><CODE>httpGets()</CODE></A>,
+<A HREF="#httpRead"><CODE>httpRead()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpClearFields">httpClearFields()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+httpClearFields(http_t *http)
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P>The <CODE>httpClearFields()</CODE> function clears all HTTP request fields
+for the HTTP connection.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpClearFields(http);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpGetField"><CODE>httpGetField()</CODE></A>,
+<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpClose">httpClose()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+httpClose(http_t *http);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P>The <CODE>httpClose()</CODE> function closes an active HTTP connection.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpClose(http);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpConnect">httpConnect()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+http_t *
+httpConnect(const char *hostname,
+ int port);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>hostname</TD>
+ <TD>The name or IP address of the server to connect to</TD>
+</TR>
+<TR>
+ <TD>port</TD>
+ <TD>The port number to use</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to a HTTP connection structure or NULL if the connection could
+not be made.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpConnect()</CODE> function opens a HTTP connection to the
+specified server and port.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+http = httpConnect(cupsServer(), ippPort());
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpClose"><CODE>httpClose()</CODE></A>,
+<A HREF="#httpConnectEncrypt"><CODE>httpConnectEncrypt()</CODE></A>,
+<A HREF="#httpGet"><CODE>httpGet()</CODE></A>,
+<A HREF="#httpGets"><CODE>httpGets()</CODE></A>,
+<A HREF="#httpPost"><CODE>httpPost()</CODE></A>,
+<A HREF="#httpRead"><CODE>httpRead()</CODE></A>,
+<A HREF="#httpWrite"><CODE>httpWrite()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpConnectEncrypt">httpConnectEncrypt()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+http_t *
+httpConnectEncrypt(const char *hostname,
+ int port,
+ http_encryption_t encryption);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>hostname</TD>
+ <TD>The name or IP address of the server to connect to</TD>
+</TR>
+<TR>
+ <TD>port</TD>
+ <TD>The port number to use</TD>
+</TR>
+<TR>
+ <TD>encryption</TD>
+ <TD>The level of encryption to use</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to a HTTP connection structure or NULL if the connection could
+not be made.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpConnectEncrypt()</CODE> function opens a HTTP
+connection to the specified server, port, and encryption.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpClose"><CODE>httpClose()</CODE></A>,
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpGet"><CODE>httpGet()</CODE></A>,
+<A HREF="#httpGets"><CODE>httpGets()</CODE></A>,
+<A HREF="#httpPost"><CODE>httpPost()</CODE></A>,
+<A HREF="#httpRead"><CODE>httpRead()</CODE></A>,
+<A HREF="#httpWrite"><CODE>httpWrite()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpDecode64">httpDecode64()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+char *
+httpDecode64(char *out,
+ const char *in);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>out</TD>
+ <TD>The output string</TD>
+</TR>
+<TR>
+ <TD>in</TD>
+ <TD>The input string</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the decoded string.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpDecode64()</CODE> function decodes a base-64 encoded string
+to the original string.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+char encoded_string[255];
+char original_string[255];
+
+httpDecode64(original_string, encoded_string);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpEncode64"><CODE>httpEncode64()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpDelete">httpDelete()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpDelete(http_t *http,
+ const char *uri);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>uri</TD>
+ <TD>The URI to delete</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 on success, non-zero on failure.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpDelete()</CODE> function sends a HTTP DELETE request to
+the server.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpDelete(http, "/some/uri");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
+<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpEncode64">httpEncode64()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+char *
+httpEncode64(char *out,
+ const char *in);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>out</TD>
+ <TD>The output string</TD>
+</TR>
+<TR>
+ <TD>in</TD>
+ <TD>The input string</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the encoded string.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpEncode64()</CODE> function decodes a base-64 encoded string
+to the original string.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+char encoded_string[255];
+char original_string[255];
+
+httpEncode64(encoded_string, original_string);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpDecode64"><CODE>httpDecode64()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpEncryption">httpEncryption()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpEncryption(http_t *http,
+ http_encryption_t encryption);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection.</TD>
+</TR>
+<TR>
+ <TD>encryption</TD>
+ <TD>The desired level of encryption.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 on success, -1 on error.
+
+<H3>Description</H3>
+
+<P><CODE>httpEncryption()</CODE> sets the encryption level for the HTTP
+connection.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+...
+
+httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#httpConnectEncrypt"><CODE>httpConnectEncrypt()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpError">httpError()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpError(http_t *http);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The last error that occurred or 0 if no error has occurred.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpError()</CODE> function returns the last error that occurred
+on the HTTP connection.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+if (httpError(http))
+{
+ ... show an error message ...
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpFlush">httpFlush()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+httpFlush(http_t *http);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P>The <CODE>httpFlush()</CODE> function flushes any remaining data left from
+a GET or POST operation.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpFlush(http);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+
+
+<!-- NEW PAGE --><H2><A NAME="httpGet">httpGet()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpGet(http_t *http,
+ const char *uri);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>uri</TD>
+ <TD>The URI to get</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 on success, non-zero on failure.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpGet()</CODE> function sends a HTTP GET request to the
+server.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+httpGet(http, "/some/uri");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
+<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpGets">httpGets()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+char *
+httpGets(char *line,
+ int length,
+ http_t *http)
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>line</TD>
+ <TD>The string to fill with a line from the HTTP connection</TD>
+</TR>
+<TR>
+ <TD>length</TD>
+ <TD>The maximum length of the string</TD>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the string or NULL if no line could be retrieved.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpGets()</CODE> function is used to read a request line from
+the HTTP connection. It is not normally used by a client program.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+char line[1024];
+
+if (httpGets(line, sizeof(line), http))
+{
+ ... process the line ...
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpGetDateString">httpGetDateString()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+httpGetDateString(time_t time)
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>time</TD>
+ <TD>The UNIX date/time value</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to a static string containing the HTTP date/time string for
+the specified UNIX time value.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpGetDateString()</CODE> function generates a date/time string
+suitable for HTTP requests from a UNIX time value.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+puts(httpGetDateString(time(NULL)));
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpGetDateTime"><CODE>httpGetDateTime()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpGetDateTime">httpGetDateTime()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+time_t
+httpGetDateTime(const char *date)
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>date</TD>
+ <TD>The HTTP date/time string</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A UNIX time value.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpGetDateTime()</CODE> function converts a HTTP
+date/time string to a UNIX time value.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+printf("%d\n", httpGetDateTime("Fri, 30 June 2000 12:34:56 GMT"));
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpGetDateString"><CODE>httpGetDateString()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpGetField">httpGetField()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+httpGetField(http_t *http,
+ http_field_t field);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>field</TD>
+ <TD>The HTTP field</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the field value string.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpGetField()</CODE> function returns the current value for
+the specified HTTP field.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+httpGet(http, "/some/uri");
+while (httpUpdate(http) == HTTP_CONTINUE);
+
+puts(httpGetField(http, HTTP_FIELD_CONTENT_TYPE));
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpGetSubField"><CODE>httpGetSubField()</CODE></A>,
+<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpGetHostByName">httpGetHostByName()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+struct hostent *
+httpGetHostByName(const char *name);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>Name or IP address to lookup.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>NULL if the host could not be found or a pointer to a host entry
+containing one or more addresses.
+
+<H3>Description</H3>
+
+<P><CODE>httpGetHostByName()</CODE> is a portable wrapper around the
+<CODE>gethostbyname()</CODE> function which handles both hostnames
+and IP addresses.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+struct hostent *hostaddr;
+
+hostaddr = httpGetHostByName("foo.bar.com");
+</PRE>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpGetLength">httpGetLength()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpGetLength(http_t *http);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The content length of the response or MAX_INT if chunking is used.
+
+<H3>Description</H3>
+
+<P><CODE>httpGetLength()</CODE> returns the content length of a response.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+...
+
+printf("The length of the response is %d bytes.\n", httpGetLength(http));
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#httpGet"><CODE>httpGet()</CODE></A>,
+<A HREF="#httpPost"><CODE>httpPost()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpGetSubField">httpGetSubField()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+httpGetSubField(http_t *http,
+ http_field_t field,
+ const char *name,
+ char *value);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection.</TD>
+</TR>
+<TR>
+ <TD>field</TD>
+ <TD>The HTTP field.</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of the subfield.</TD>
+</TR>
+<TR>
+ <TD>value</TD>
+ <TD>The string to hold the subfield value.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the subfield value string or NULL if it does not exist.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpGetSubField()</CODE> function returns a subfield value
+from the specified HTTP field. The destination string buffer must be at
+least <CODE>HTTP_MAX_VALUE</CODE> bytes in length.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+char value[HTTP_MAX_VALUE];
+
+httpGet(http, "/some/uri");
+while (httpUpdate(http) == HTTP_CONTINUE);
+
+puts(httpGetSubField(http, HTTP_FIELD_CONTENT_TYPE, "charset", value));
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpGetField"><CODE>httpGetField()</CODE></A>,
+<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpHead">httpHead()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpHead(http_t *http,
+ const char *uri);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>uri</TD>
+ <TD>The URI to head</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 on success, non-zero on failure.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpHead()</CODE> function sends a HTTP HEAD request to the
+server.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpHead(http, "/some/uri");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
+<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpInitialize">httpInitialize()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void httpInitialize(void);
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>httpInitialize()</CODE> function initializes the networking
+code as needed by the underlying platform. It is called automatically by
+the <CODE>httpConnect()</CODE> function.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+httpInitialize();
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpMD5">httpMD5()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+char *
+httpMD5(const char *username,
+ const char *realm,
+ const char *passwd,
+ char md5[33]);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>username</TD>
+ <TD>The authenticating user name.</TD>
+</TR>
+<TR>
+ <TD>realm</TD>
+ <TD>The authenticating realm name.</TD>
+</TR>
+<TR>
+ <TD>passwd</TD>
+ <TD>The authenticating password.</TD>
+</TR>
+<TR>
+ <TD>md5</TD>
+ <TD>The MD5 sum string.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the MD5 sum string.
+
+<H3>Description</H3>
+
+<P><CODE>httpMD5()</CODE> computes the MD5 hash of the username,
+realm, and password as required by the HTTP Digest specification.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+char md5[33];
+
+...
+
+httpMD5("user", "realm", "password", md5);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#httpMD5Final"><CODE>httpMD5Final()</CODE></A>,
+<A HREF="#httpMD5String"><CODE>httpMD5String()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpMD5Final">httpMD5Final()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+char *
+httpMD5Final(const char *nonce,
+ const char *method,
+ const char *resource,
+ char md5[33]);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>nonce</TD>
+ <TD>The server nonce value.</TD>
+</TR>
+<TR>
+ <TD>method</TD>
+ <TD>The HTTP method (GET, POST, etc.)</TD>
+</TR>
+<TR>
+ <TD>resource</TD>
+ <TD>The resource path.</TD>
+</TR>
+<TR>
+ <TD>md5</TD>
+ <TD>The MD5 sum string.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The MD5 sum string.
+
+<H3>Description</H3>
+
+<P><CODE>httpMD5Final()</CODE> appends the nonce, method, and resource
+to the specified MD5 sum.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+char md5[33];
+
+...
+
+httpMD5Final("nonce", "GET", "/jobs", md5);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#httpMD5"><CODE>httpMD5()</CODE></A>,
+<A HREF="#httpMD5String"><CODE>httpMD5String()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpMD5String">httpMD5String()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+char *
+httpMD5String(const md5_byte_t *sum,
+ char md5[33]);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>sum</TD>
+ <TD>The raw MD5 sum data.</TD>
+</TR>
+<TR>
+ <TD>md5</TD>
+ <TD>The MD5 sum string.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The MD5 sum string.
+
+<H3>Description</H3>
+
+<P><CODE>httpMD5String()</CODE> converts the raw MD5 sum value to a string.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+md5_byte_t sum[16];
+char md5[33];
+
+...
+
+httpMD5String(sum, md5);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#httpMD5"><CODE>httpMD5()</CODE></A>,
+<A HREF="#httpMD5Final"><CODE>httpMD5Final()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpOptions">httpOptions()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpOptions(http_t *http,
+ const char *uri);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>uri</TD>
+ <TD>The URI to check for options</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 on success, non-zero on failure.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpOptions()</CODE> function sends a HTTP OPTIONS request to the
+server.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpOptions(http, "/some/uri");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
+<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpPost">httpPost()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpPost(http_t *http,
+ const char *uri);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>uri</TD>
+ <TD>The URI to post to</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 on success, non-zero on failure.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpPost()</CODE> function sends a HTTP POST request to the
+server.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpPost(http, "/some/uri");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
+<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpPrintf">httpPrintf()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpPrintf(http_t *http,
+ const char *format,
+ ...);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>format</TD>
+ <TD>A printf-style format string</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of bytes written.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpPrintf()</CODE> function sends a formatted string to the
+HTTP connection. It is normally only used by the CUPS API and scheduler.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpPrintf(http, "GET / HTTP/1.1 \r\n");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpPut">httpPut()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpPut(http_t *http,
+ const char *uri);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>uri</TD>
+ <TD>The URI to put</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 on success, non-zero on failure.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpPut()</CODE> function sends a HTTP PUT request to the
+server.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpDelete(http, "/some/uri");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
+<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpRead">httpRead()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpRead(http_t *http,
+ char *buffer,
+ int length);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>buffer</TD>
+ <TD>The buffer to read into</TD>
+</TR>
+<TR>
+ <TD>length</TD>
+ <TD>The number of bytes to read</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of bytes read or -1 on error.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpRead()</CODE> function reads data from the HTTP connection,
+possibly the result of a GET or POST request.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+char buffer[1024];
+int bytes;
+
+httpGet(http, "/");
+while (httpUpdate(http) != HTTP_CONTINUE);
+while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) > 0)
+{
+ buffer[bytes] = '\0';
+ fputs(buffer, stdout);
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpWrite"><CODE>httpWrite()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpReconnect">httpReconnect()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpReconnect(http_t *http);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 on success, non-zero on failure.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpReconnect()</CODE> function reconnects to the HTTP server.
+This is usually done automatically if the HTTP functions detect that the
+server connection has terminated.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpReconnect(http);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpSeparate">httpSeparate()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+httpSeparate(const char *uri,
+ char *method,
+ char *username,
+ char *host,
+ int *port,
+ char *resource);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>uri</TD>
+ <TD>The URI to separate</TD>
+</TR>
+<TR>
+ <TD>method</TD>
+ <TD>The method (scheme) of the URI</TD>
+</TR>
+<TR>
+ <TD>username</TD>
+ <TD>The username (and password) portion of the URI, if any</TD>
+</TR>
+<TR>
+ <TD>host</TD>
+ <TD>The hostname portion of the URI, if any</TD>
+</TR>
+<TR>
+ <TD>port</TD>
+ <TD>The port number for the URI, either as specified or as
+ default for the method/scheme</TD>
+</TR>
+<TR>
+ <TD>resource</TD>
+ <TD>The resource string, usually a filename on the server</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P>The <CODE>httpSeparate()</CODE> function separates the specified URI into
+its component parts. The method, username, hostname, and resource strings should
+be at least <CODE>HTTP_MAX_URI</CODE> characters long to avoid potential
+buffer overflow problems.
+
+<H3>Example</H3>
+
+<PRE>
+char uri[HTTP_MAX_URI];
+char method[HTTP_MAX_URI];
+char username[HTTP_MAX_URI];
+char host[HTTP_MAX_URI];
+char resource[HTTP_MAX_URI];
+int port;
+
+...
+
+httpSeparate(uri, method, username, host, &amp;port, resource);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpSetField">httpSetField()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+httpSetField(http_t *http,
+ http_field_t field,
+ const char *value);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>field</TD>
+ <TD>The HTTP field</TD>
+</TR>
+<TR>
+ <TD>value</TD>
+ <TD>The string value for the field</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P>The <CODE>httpSetField()</CODE> function sets the current value for
+the specified HTTP field.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpSetField(http, HTTP_FIELD_AUTHORIZATION, "Basic dfdr34453454325"));
+httpGet(http, "/some/uri");
+while (httpUpdate(http) == HTTP_CONTINUE);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpGetField"><CODE>httpGetField()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpStatus">httpStatus()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+httpStatus(http_status_t status);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>status</TD>
+ <TD>The HTTP status code from the server.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The standard HTTP status text associated with the status code.
+
+<H3>Description</H3>
+
+<P><CODE>httpStatus()</CODE> returns the standard HTTP status text
+associated with the status code.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+<A HREF="#http_t">http_t</A> *http;
+
+...
+
+puts(httpStatus(http->status));
+</PRE>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpTrace">httpTrace()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpTrace(http_t *http,
+ const char *uri);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>uri</TD>
+ <TD>The URI to trace</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 on success, non-zero on failure.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpTrace()</CODE> function sends a HTTP TRACE request to the
+server.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+
+httpTrace(http, "/some/uri");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpSetField"><CODE>httpSetField()</CODE></A>,
+<A HREF="#httpUpdate"><CODE>httpUpdate()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpUpdate">httpUpdate()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+http_status_t
+httpUpdate(http_t *http);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The HTTP status of the current request.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpUpdate()</CODE> function updates the current request status.
+It is used after any DELETE, GET, HEAD, OPTIONS, POST, PUT, or TRACE
+request to finalize the HTTP request and retrieve the request status.
+
+<P>Since proxies and the current blocking mode can cause the request to
+take longer, programs should continue calling <CODE>httpUpdate()<CODE>
+until the return status is not the constant value <CODE>HTTP_CONTINUE</CODE>.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+http_status_t status;
+
+httpGet(http, "/some/uri");
+while ((status = httpUpdate(http)) == HTTP_CONTINUE);
+printf("Request status is %d\n", status);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpDelete"><CODE>httpDelete()</CODE></A>,
+<A HREF="#httpGet"><CODE>httpGet()</CODE></A>,
+<A HREF="#httpHead"><CODE>httpHead()</CODE></A>,
+<A HREF="#httpOptions"><CODE>httpOptions()</CODE></A>,
+<A HREF="#httpPost"><CODE>httpPost()</CODE></A>,
+<A HREF="#httpPut"><CODE>httpPut()</CODE></A>,
+<A HREF="#httpTrace"><CODE>httpTrace()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="httpWrite">httpWrite()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+httpWrite(http_t *http,
+ char *buffer,
+ int length);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>buffer</TD>
+ <TD>The buffer to read into</TD>
+</TR>
+<TR>
+ <TD>length</TD>
+ <TD>The number of bytes to read</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of bytes read or -1 on error.
+
+<H3>Description</H3>
+
+<P>The <CODE>httpWrite()</CODE> function reads data from the HTTP connection,
+possibly the result of a GET or POST request.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h&gt;
+
+http_t *http;
+FILE *fp;
+char buffer[1024];
+int bytes;
+
+httpPost(http, "/");
+
+while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
+ httpWrite(http, buffer, bytes);
+
+while (httpUpdate(http) != HTTP_CONTINUE);
+
+while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) > 0)
+{
+ buffer[bytes] = '\0';
+ fputs(buffer, stdout);
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#httpConnect"><CODE>httpConnect()</CODE></A>,
+<A HREF="#httpRead"><CODE>httpRead()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddBoolean">ippAddBoolean()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddBoolean(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ char value);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+<TR>
+ <TD>group</TD>
+ <TD>The IPP group</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of attribute</TD>
+</TR>
+<TR>
+ <TD>value</TD>
+ <TD>The boolean value</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new attribute or NULL if the attribute could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddBoolean()</CODE> function adds a single boolean attribute
+value to the specified IPP request.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, "my-jobs", 1);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
+<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
+<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
+<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
+<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
+<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
+<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
+<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
+<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddBooleans">ippAddBooleans()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddBooleans(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ int num_values,
+ const char *values);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+<TR>
+ <TD>group</TD>
+ <TD>The IPP group</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of attribute</TD>
+</TR>
+<TR>
+ <TD>num_values</TD>
+ <TD>The number of values</TD>
+</TR>
+<TR>
+ <TD>values</TD>
+ <TD>The boolean values</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new attribute or NULL if the attribute could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddBooleans()</CODE> function adds one or more boolean
+attribute values to the specified IPP request. If the
+<CODE>values</CODE> pointer is <CODE>NULL</CODE> then an array of
+<CODE>num_values</CODE> false values is created.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+char values[10];
+
+ippAddBooleans(ipp, IPP_TAG_OPERATION, "some-attribute", 10, values);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
+<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
+<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
+<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
+<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
+<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
+<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
+<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
+<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddDate">ippAddDate()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddDate(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ ipp_uchar_t *value);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+<TR>
+ <TD>group</TD>
+ <TD>The IPP group</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of attribute</TD>
+</TR>
+<TR>
+ <TD>value</TD>
+ <TD>The date value</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new attribute or NULL if the attribute could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddDate()</CODE> function adds a single date-time attribute
+value to the specified IPP request.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddDate(ipp, IPP_TAG_OPERATION, "some-attribute",
+ ippTimeToDate(time(NULL));
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
+<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
+<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
+<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
+<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
+<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
+<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
+<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
+<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>,
+<A HREF="#ippTimeToDate"><CODE>ippTimeToDate()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddInteger">ippAddInteger()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddInteger(ipp_t *ipp,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ int value);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+<TR>
+ <TD>group</TD>
+ <TD>The IPP group</TD>
+</TR>
+<TR>
+ <TD>tag</TD>
+ <TD>The type of integer value (IPP_TAG_INTEGER or IPP_TAG_ENUM)</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of attribute</TD>
+</TR>
+<TR>
+ <TD>value</TD>
+ <TD>The integer value</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new attribute or NULL if the attribute could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddInteger()</CODE> function adds a single integer attribute
+value to the specified IPP request.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddInteger(ipp, IPP_TAG_OPERATION, "limit", 100);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
+<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
+<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
+<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
+<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
+<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
+<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
+<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
+<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddIntegers">ippAddIntegers()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddIntegers(ipp_t *ipp,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ int num_values,
+ const int *values);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+<TR>
+ <TD>group</TD>
+ <TD>The IPP group</TD>
+</TR>
+<TR>
+ <TD>tag</TD>
+ <TD>The type of integer value (IPP_TAG_INTEGER or IPP_TAG_ENUM)</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of attribute</TD>
+</TR>
+<TR>
+ <TD>num_values</TD>
+ <TD>The number of values</TD>
+</TR>
+<TR>
+ <TD>values</TD>
+ <TD>The integer values</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new attribute or NULL if the attribute could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddIntegers()</CODE> function adds one or more integer
+attribute values to the specified IPP request. If the
+<CODE>values</CODE> pointer is <CODE>NULL</CODE> then an array of
+<CODE>num_values</CODE> 0 values is created.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+int values[100];
+
+ippAddIntegers(ipp, IPP_TAG_OPERATION, "some-attribute", 100, values);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
+<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
+<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
+<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
+<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
+<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
+<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
+<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
+<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddRange">ippAddRange()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddRange(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ int low,
+ int high);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+<TR>
+ <TD>group</TD>
+ <TD>The IPP group</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of attribute</TD>
+</TR>
+<TR>
+ <TD>low</TD>
+ <TD>The lower value</TD>
+</TR>
+<TR>
+ <TD>high</TD>
+ <TD>The higher value</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new attribute or NULL if the attribute could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddRange()</CODE> function adds a single range attribute
+value to the specified IPP request.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddRange(ipp, IPP_TAG_OPERATION, "page-ranges", 1, 10);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
+<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
+<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
+<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
+<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
+<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
+<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
+<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
+<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddRanges">ippAddRanges()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddRanges(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ int num_values,
+ const int *lows,
+ const int *highs);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+<TR>
+ <TD>group</TD>
+ <TD>The IPP group</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of attribute</TD>
+</TR>
+<TR>
+ <TD>num_values</TD>
+ <TD>The number of range values</TD>
+</TR>
+<TR>
+ <TD>lows</TD>
+ <TD>The lower values</TD>
+</TR>
+<TR>
+ <TD>highs</TD>
+ <TD>The higher values</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new attribute or NULL if the attribute could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddRanges()</CODE> function adds one or more range
+attribute values to the specified IPP request. If the
+<CODE>values</CODE> pointer is <CODE>NULL</CODE> then an array of
+<CODE>num_values</CODE> 0,0 ranges is created.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+int lows[2];
+int highs[2];
+
+ippAddRanges(ipp, IPP_TAG_OPERATION, "page-ranges", 2, lows, highs);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
+<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
+<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
+<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
+<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
+<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
+<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
+<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
+<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddResolution">ippAddResolution()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddResolution(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ int xres,
+ int yres,
+ ipp_res_t units);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+<TR>
+ <TD>group</TD>
+ <TD>The IPP group</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of attribute</TD>
+</TR>
+<TR>
+ <TD>xres</TD>
+ <TD>The horizontal resolution</TD>
+</TR>
+<TR>
+ <TD>yres</TD>
+ <TD>The vertical resolution</TD>
+</TR>
+<TR>
+ <TD>units</TD>
+ <TD>The resolution units</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new attribute or NULL if the attribute could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddResolution()</CODE> function adds a single resolution attribute
+value to the specified IPP request.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, "printer-resolution",
+ 720, 720, IPP_RES_PER_INCH);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
+<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
+<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
+<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
+<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
+<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
+<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
+<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
+<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddResolutions">ippAddResolutions()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddResolutions(ipp_t *ipp,
+ ipp_tag_t group,
+ const char *name,
+ int num_values,
+ const int *xres,
+ const int *yres,
+ const ipp_res_t *units);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+<TR>
+ <TD>group</TD>
+ <TD>The IPP group</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of attribute</TD>
+</TR>
+<TR>
+ <TD>num_values</TD>
+ <TD>The number of resolution values</TD>
+</TR>
+<TR>
+ <TD>xres</TD>
+ <TD>The horizontal resolutions</TD>
+</TR>
+<TR>
+ <TD>yres</TD>
+ <TD>The vertical resolutions</TD>
+</TR>
+<TR>
+ <TD>units</TD>
+ <TD>The resolution units</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new attribute or NULL if the attribute could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddResolutions()</CODE> function adds one or more
+resolution attribute values to the specified IPP request. If the
+<CODE>values</CODE> pointer is <CODE>NULL</CODE> then an array of
+<CODE>num_values</CODE> 0,0 resolutions is created.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+int xres[5];
+int yres[5];
+ipp_res_t units[5];
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, "printer-resolutions-supported",
+ 5, xres, yres, units);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
+<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
+<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
+<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
+<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
+<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
+<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
+<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
+<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddSeparator">ippAddSeparator()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddSeparator(ipp_t *ipp);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new separator or NULL if the separator could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddSeparator()</CODE> function adds a group separator
+to the specified IPP request.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddSeparator(ipp);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
+<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
+<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
+<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
+<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
+<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
+<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
+<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
+<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>,
+<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddString">ippAddString()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddString(ipp_t *ipp,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ const char *charset,
+ const char *value);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+<TR>
+ <TD>group</TD>
+ <TD>The IPP group</TD>
+</TR>
+<TR>
+ <TD>tag</TD>
+ <TD>The type of string value</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of attribute</TD>
+</TR>
+<TR>
+ <TD>charset</TD>
+ <TD>The character set for the string</TD>
+</TR>
+<TR>
+ <TD>value</TD>
+ <TD>The string value</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new attribute or NULL if the attribute could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddString()</CODE> function adds a single string attribute
+value to the specified IPP request. For <CODE>IPP_TAG_NAMELANG</CODE> and
+<CODE>IPP_TAG_TEXTLANG</CODE> strings, the charset value is provided with
+the string to identify the string encoding used. Otherwise the charset value
+is ignored.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
+ NULL, "abc123");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
+<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
+<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
+<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
+<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
+<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
+<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
+<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
+<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
+<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
+<A HREF="#ippAddStrings"><CODE>ippAddStrings()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippAddStrings">ippAddStrings()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippAddStrings(ipp_t *ipp,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ int num_values,
+ const char *charset,
+ const char **values);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request</TD>
+</TR>
+<TR>
+ <TD>group</TD>
+ <TD>The IPP group</TD>
+</TR>
+<TR>
+ <TD>tag</TD>
+ <TD>The type of string value</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of attribute</TD>
+</TR>
+<TR>
+ <TD>num_values</TD>
+ <TD>The number of strings</TD>
+</TR>
+<TR>
+ <TD>charset</TD>
+ <TD>The character set for the strings</TD>
+</TR>
+<TR>
+ <TD>values</TD>
+ <TD>The string values</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the new attribute or NULL if the attribute could not be
+created.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippAddStrings()</CODE> function adds one or more string
+attribute values to the specified IPP request. For
+<CODE>IPP_TAG_NAMELANG</CODE> and <CODE>IPP_TAG_TEXTLANG</CODE>
+strings, the charset value is provided with the strings to identify the
+string encoding used. Otherwise the charset value is ignored. If the
+<CODE>values</CODE> pointer is <CODE>NULL</CODE> then an array of
+<CODE>num_values</CODE> NULL strings is created.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+char *values[2] = { "one", "two" };
+
+ippAddStrings(ipp, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "attr-name",
+ 2, NULL, values);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippAddBoolean"><CODE>ippAddBoolean()</CODE></A>,
+<A HREF="#ippAddBooleans"><CODE>ippAddBooleans()</CODE></A>,
+<A HREF="#ippAddDate"><CODE>ippAddDate()</CODE></A>,
+<A HREF="#ippAddInteger"><CODE>ippAddInteger()</CODE></A>,
+<A HREF="#ippAddIntegers"><CODE>ippAddIntegers()</CODE></A>,
+<A HREF="#ippAddRange"><CODE>ippAddRange()</CODE></A>,
+<A HREF="#ippAddRanges"><CODE>ippAddRanges()</CODE></A>,
+<A HREF="#ippAddResolution"><CODE>ippAddResolution()</CODE></A>,
+<A HREF="#ippAddResolutions"><CODE>ippAddResolutions()</CODE></A>,
+<A HREF="#ippAddSeparator"><CODE>ippAddSeparator()</CODE></A>,
+<A HREF="#ippAddString"><CODE>ippAddString()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippDateToTime">ippDateToTime()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+time_t
+ippDateToTime(const ipp_uchar_t date[11]);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>date</TD>
+ <TD>The IPP date-time value</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A UNIX time value.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippDateToTime()</CODE> function converts an IPP date-time value
+to a UNIX time value.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_uchar_t date[11];
+
+printf("UNIX time is %d\n", ippDateToTime(date));
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippTimeToDate"><CODE>ippTimeToDate()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippDelete">ippDelete()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+ippDelete(ipp_t *ipp);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request or response</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P>The <CODE>ippDelete()</CODE> function deletes all memory used by an IPP
+request or response.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+
+ippDelete(ipp);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippErrorString">ippErrorString()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+const char *
+ippErrorString(ipp_status_t error);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>error</TD>
+ <TD>IPP error code.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The standard text representation of the IPP error code.
+
+<H3>Description</H3>
+
+<P><CODE>ippErrorString()</CODE> returns the standard text representation
+of the IPP error code.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h&gt;
+
+puts(ippErrorString(IPP_OK));
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#cupsLastError"><CODE>cupsLastError()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippFindAttribute">ippFindAttribute()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippFindAttribute(ipp_t *ipp,
+ const char *name,
+ ipp_tag_t tag);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request or response</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of the attribute</TD>
+</TR>
+<TR>
+ <TD>tag</TD>
+ <TD>The required value tag for the attribute or
+ <CODE>IPP_TAG_ZERO</CODE> for any type of value.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the first occurrence of the requested attribute, or
+<CODE>NULL</CODE> if it was not found.
+
+<H3>Description</H3>
+
+<P><CODE>ippFindAttribute()</CODE> finds the first occurrence of the named
+attribute. The <CODE>tag</CODE> parameter restricts the search to a specific
+value type - use <CODE>IPP_TAG_ZERO</CODE> to find any value with the name.
+
+<P>The value tags <CODE>IPP_TAG_NAME</CODE> and <CODE>IPP_TAG_TEXT</CODE>
+match the name/text values with or without the language code.
+
+<H3>Example</H3>
+
+<PRE>
+<A HREF="#ipp_attribute_t">ipp_attribute_t</A> *attr;
+
+attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT);
+while (attr != NULL)
+{
+ puts(attr->values[0].string.text);
+
+ attr = ippFindNextAttribute(response, "printer-state-message", IPP_TAG_TEXT);
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#cupsDoFileRequest"><CODE>cupsDoFileRequest()</CODE></A>,
+<A HREF="#cupsDoRequest"><CODE>cupsDoRequest()</CODE></A>,
+<A HREF="#ippDelete"><CODE>ippDelete()</CODE></A>,
+<A HREF="#ippFindNextAttribute"><CODE>ippFindNextAttribute()</CODE></A>,
+<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippFindNextAttribute">ippFindNextAttribute()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_attribute_t *
+ippFindNextAttribute(ipp_t *ipp,
+ const char *name,
+ ipp_tag_t tag);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request or response</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of the attribute</TD>
+</TR>
+<TR>
+ <TD>tag</TD>
+ <TD>The required value tag for the attribute or
+ <CODE>IPP_TAG_ZERO</CODE> for any type of value.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the next occurrence of the requested attribute, or
+<CODE>NULL</CODE> if it was not found.
+
+<H3>Description</H3>
+
+<P><CODE>ippFindNextAttribute()</CODE> finds the next occurrence of the named
+attribute. The <CODE>tag</CODE> parameter restricts the search to a specific
+value type - use <CODE>IPP_TAG_ZERO</CODE> to find any value with the name.
+
+<P>The value tags <CODE>IPP_TAG_NAME</CODE> and <CODE>IPP_TAG_TEXT</CODE>
+match the name/text values with or without the language code.
+
+<H3>Example</H3>
+
+<PRE>
+<A HREF="#ipp_attribute_t">ipp_attribute_t</A> *attr;
+
+attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT);
+while (attr != NULL)
+{
+ puts(attr->values[0].string.text);
+
+ attr = ippFindNextAttribute(response, "printer-state-message", IPP_TAG_TEXT);
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#cupsDoFileRequest"><CODE>cupsDoFileRequest()</CODE></A>,
+<A HREF="#cupsDoRequest"><CODE>cupsDoRequest()</CODE></A>,
+<A HREF="#ippDelete"><CODE>ippDelete()</CODE></A>,
+<A HREF="#ippFindNextAttribute"><CODE>ippFindNextAttribute()</CODE></A>,
+<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippLength">ippLength()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+ippLength(ipp_t *ipp);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request or response</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The total encoded length of the IPP request or response in bytes.
+
+<H3>Description</H3>
+
+<P><CODE>ippLength()</CODE> returns the length of the IPP request or
+response in bytes.
+
+<H3>Example</H3>
+
+<PRE>
+printf("The length of the response is %d bytes.\n", ippLength(response));
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippDelete"><CODE>ippDelete()</CODE></A>,
+<A HREF="#ippNew"><CODE>ippNew()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippNew">ippNew()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_t *
+ippNew(void);
+</PRE>
+
+<H3>Returns</H3>
+
+<P>A pointer to a new IPP request or response.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippNew()</CODE> function creates a new IPP request or response.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_t *ipp;
+
+ipp = ippNew();
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippDelete"><CODE>ippDelete()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippPort">ippPort()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+ippPort(void);
+</PRE>
+
+<H3>Returns</H3>
+
+<P>The default TCP/IP port number for IPP requests.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippPort()</CODE> function returns the default IPP port number
+for requests.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h>
+#include &lt;cups/ipp.h>
+
+http_t *http;
+
+http = httpConnect(cupsServer(), ippPort());
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#cupsServer"><CODE>cupsServer()</CODE></A>,
+<A HREF="#ippSetPort"><CODE>ippSetPort()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippRead">ippRead()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_state_t
+ippRead(http_t *http,
+ ipp_t *ipp);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request or response</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The current read state.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippRead()</CODE> function reads IPP attributes from the specified
+HTTP connection. Programs should continue calling <CODE>ippRead()</CODE> until
+<CODE>IPP_ERROR</CODE> or <CODE>IPP_DATA</CODE> is returned.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h>
+#include &lt;cups/ipp.h>
+
+http_t *http;
+ipp_t *ipp;
+ipp_state_t status;
+
+ipp = ippNew();
+
+while ((status = ippRead(http, ipp)) != IPP_ERROR)
+ if (status == IPP_DATA)
+ break;
+
+if (status == IPP_DATA)
+{
+ ... read additional non-IPP data using httpRead() ...
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippWrite"><CODE>ippWrite()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippSetPort">ippSetPort()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+ippSetPort(int port);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>port</TD>
+ <TD>The port number to use</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P>The <CODE>ippSetPort()</CODE> function sets the default IPP port number
+for requests.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h>
+#include &lt;cups/ipp.h>
+
+...
+
+ippSetPort(8631);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippPort"><CODE>ippPort()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippTimeToDate">ippTimeToDate()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_uchar_t *
+ippTimeToDate(time_t time);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>time</TD>
+ <TD>The UNIX time value</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A static pointer to an IPP date-time value.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippTimeToDate()</CODE> function converts a UNIX time to an IPP
+date-time value.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ipp.h>
+
+ipp_uchar_t *date;
+
+date = ippTimeToDate(time(NULL));
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippDateToTime"><CODE>ippDateToTime()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ippWrite">ippWrite()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ipp_state_t
+ippWrite(http_t *http,
+ ipp_t *ipp);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>http</TD>
+ <TD>The HTTP connection</TD>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>The IPP request or response</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The current write state.
+
+<H3>Description</H3>
+
+<P>The <CODE>ippWrite()</CODE> function writes IPP attributes to the specified
+HTTP connection. Programs should continue calling <CODE>ippWrite()</CODE> until
+<CODE>IPP_ERROR</CODE> or <CODE>IPP_DATA</CODE> is returned.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/http.h>
+#include &lt;cups/ipp.h>
+
+http_t *http;
+ipp_t *ipp;
+ipp_state_t status;
+
+ipp = ippNew();
+... add attributes ...
+
+while ((status = ippWrite(http, ipp)) != IPP_ERROR)
+ if (status == IPP_DATA)
+ break;
+
+if (status == IPP_DATA)
+{
+ ... read additional non-IPP data using httpWrite() ...
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ippRead"><CODE>ippRead()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdClose">ppdClose()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+ppdClose(ppd_file_t *ppd);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdClose()</CODE> function frees all memory associated with the
+PPD file.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdClose(ppd);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdOpen"><CODE>ppdOpen()</CODE></A>,
+<A HREF="#ppdOpenFd"><CODE>ppdOpenFd()</CODE></A>,
+<A HREF="#ppdOpenFile"><CODE>ppdOpenFile()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdCollect">ppdCollect()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+ppdCollect(ppd_file_t *ppd,
+ ppd_section_t section,
+ ppd_choice_t ***choices);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file.</TD>
+</TR>
+<TR>
+ <TD>section</TD>
+ <TD>The document section to collect.</TD>
+</TR>
+<TR>
+ <TD>choices</TD>
+ <TD>The array of option choices that are marked.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of options collected.
+
+<H3>Description</H3>
+
+<P><CODE>ppdCollect()</CODE> collects all of the marked options in the
+specified section, sorts them by their order dependency values, and
+returns an array that can be used to emit option commands in the proper
+order. It is normally used by the <CODE>ppdEmit*()</CODE> functions.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h&gt;
+
+<A HREF="#ppd_file_t">ppd_file_t</A> *ppd;
+int num_choices;
+<A HREF="#ppd_choice_t">ppd_choice_t</A> **choices;
+
+...
+
+num_choices = ppdCollect(ppd, PPD_ORDER_JCL, &amp;choices);
+</PRE>
+
+<H3>See Also</H3>
+
+<P>
+<A HREF="#ppdEmit"><CODE>ppdEmit()</CODE></A>,
+<A HREF="#ppdEmitFd"><CODE>ppdEmitFd()</CODE></A>,
+<A HREF="#ppdEmitJCL"><CODE>ppdEmitJCL()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdConflicts">ppdConflicts()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+ppdConflicts(ppd_file_t *ppd);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of option conflicts in the file.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdConflicts()</CODE> function returns the number of conflicts
+with the currently selected options.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("%d conflicts\n", ppdConflicts(ppd));
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
+<A HREF="#ppdIsMarked"><CODE>ppdIsMarked()</CODE></A>,
+<A HREF="#ppdMarkDefaults"><CODE>ppdMarkDefaults()</CODE></A>,
+<A HREF="#ppdMarkOption"><CODE>ppdMarkOption()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdEmit">ppdEmit()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+ppdEmit(ppd_file_t *ppd,
+ FILE *file,
+ ppd_section_t section);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+<TR>
+ <TD>file</TD>
+ <TD>The file to write to</TD>
+</TR>
+<TR>
+ <TD>section</TD>
+ <TD>The option section to write</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 on success, -1 on error.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdEmit()</CODE> function sends printer-specific option
+commands to the specified file.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdEmitFd"><CODE>ppdEmitFd()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdEmitFd">ppdEmitFd()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+ppdEmitFd(ppd_file_t *ppd,
+ int fd,
+ ppd_section_t section);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+<TR>
+ <TD>fd</TD>
+ <TD>The file descriptor to write to</TD>
+</TR>
+<TR>
+ <TD>section</TD>
+ <TD>The option section to write</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>0 on success, -1 on error.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdEmitFd()</CODE> function sends printer-specific option
+commands to the specified file descriptor.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdEmitFd(ppd, 1, PPD_ORDER_PAGE);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdEmit"><CODE>ppdEmit()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdFindChoice">ppdFindChoice()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ppd_choice_t *
+ppdFindChoice(ppd_option_t *option,
+ const char *choice);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>option</TD>
+ <TD>A pointer to the option</TD>
+</TR>
+<TR>
+ <TD>choice</TD>
+ <TD>The name of the choice</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the choice data or NULL if the choice does not exist.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdFindChoice()</CODE> function returns a pointer to the choice
+data for the specified option.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_option_t *option;
+ppd_choice_t *choice;
+
+option = ppdFindOption(ppd, "PageSize");
+choice = ppdFindChoice(option, "Letter");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdFindMarkedChoice"><CODE>ppdFindMarkedChoice()</CODE></A>,
+<A HREF="#ppdFindOption"><CODE>ppdFindOption()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdFindMarkedChoice">ppdFindMarkedChoice()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ppd_choice_t *
+ppdFindMarkedChoice(ppd_file_t *ppd,
+ const char *keyword);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+<TR>
+ <TD>keyword</TD>
+ <TD>The name of the option</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the choice data or NULL if the choice does not exist or
+is not marked.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdFindMarkedChoice()</CODE> function returns a pointer to
+the marked choice data for the specified option.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_choice_t *choice;
+
+choice = ppdFindMarkedChoice(ppd, "PageSize");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdFindChoice"><CODE>ppdFindChoice()</CODE></A>,
+<A HREF="#ppdFindOption"><CODE>ppdFindOption()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdFindOption">ppdFindOption()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ppd_option_t *
+ppdFindOption(ppd_file_t *ppd,
+ const char *keyword);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+<TR>
+ <TD>keyword</TD>
+ <TD>The name of the option</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the option data or NULL if the option does not exist.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdFindOption()</CODE> function returns a pointer to the option
+data for the specified option.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_option_t *option;
+
+option = ppdFindOption(ppd, "PageSize");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdFindChoice"><CODE>ppdFindChoice()</CODE></A>,
+<A HREF="#ppdFindMarkedChoice"><CODE>ppdFindMarkedChoice()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdIsMarked">ppdIsMarked()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+ppdIsMarked(ppd_file_t *ppd,
+ const char *keyword,
+ const char *choice);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+<TR>
+ <TD>keyword</TD>
+ <TD>The name of the option</TD>
+</TR>
+<TR>
+ <TD>choice</TD>
+ <TD>The name of the option choice</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>1 if the choice is marked, 0 otherwise.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdIsMarked()</CODE> function returns whether or not the
+specified option choice is marked.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("Letter size %s selected.\n",
+ ppdIsMarked(ppd, "PageSize", "Letter") ? "is" : "is not");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
+<A HREF="#ppdConflicts"><CODE>ppdConflicts()</CODE></A>,
+<A HREF="#ppdIsMarked"><CODE>ppdIsMarked()</CODE></A>,
+<A HREF="#ppdMarkDefaults"><CODE>ppdMarkDefaults()</CODE></A>,
+<A HREF="#ppdMarkOption"><CODE>ppdMarkOption()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdMarkDefaults">ppdMarkDefaults()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+void
+ppdMarkDefaults(ppd_file_t *ppd);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdMarkDefaults()</CODE> function marks all of the default
+choices in the PPD file.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdMarkDefaults(ppd);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
+<A HREF="#ppdConflicts"><CODE>ppdConflicts()</CODE></A>,
+<A HREF="#ppdIsMarked"><CODE>ppdIsMarked()</CODE></A>,
+<A HREF="#ppdMarkDefaults"><CODE>ppdMarkDefaults()</CODE></A>,
+<A HREF="#ppdMarkOption"><CODE>ppdMarkOption()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdMarkOption">ppdMarkOption()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+int
+ppdMarkOption(ppd_file_t *ppd,
+ const char *keyword,
+ const char *choice);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+<TR>
+ <TD>keyword</TD>
+ <TD>The name of the option</TD>
+</TR>
+<TR>
+ <TD>choice</TD>
+ <TD>The name of the choice</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The number of conflicts in the PPD file.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdMarkOption()</CODE> function marks the specified option
+choice.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdMarkOption(ppd, "PageSize", "Letter");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#cupsMarkOptions"><CODE>cupsMarkOptions()</CODE></A>,
+<A HREF="#ppdConflicts"><CODE>ppdConflicts()</CODE></A>,
+<A HREF="#ppdIsMarked"><CODE>ppdIsMarked()</CODE></A>,
+<A HREF="#ppdMarkDefaults"><CODE>ppdMarkDefaults()</CODE></A>,
+<A HREF="#ppdMarkOption"><CODE>ppdMarkOption()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdOpen">ppdOpen()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ppd_file_t *
+ppdOpen(FILE *file);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>file</TD>
+ <TD>The file to read from</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to a PPD file structure or NULL if the PPD file could not be
+read.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdOpen()</CODE> function reads a PPD file from the specified
+file into memory.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+FILE *file;
+
+file = fopen("filename.ppd", "rb");
+ppd = ppdOpen(file);
+fclose(file);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdClose"><CODE>ppdClose()</CODE></A>,
+<A HREF="#ppdOpenFd"><CODE>ppdOpenFd()</CODE></A>,
+<A HREF="#ppdOpenFile"><CODE>ppdOpenFile()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdOpenFd">ppdOpenFd()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ppd_file_t *
+ppdOpenFd(int fd);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>fd</TD>
+ <TD>The file descriptor to read from</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to a PPD file structure or NULL if the PPD file could not be
+read.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdOpenFd()</CODE> function reads a PPD file from the specified
+file descriptor into memory.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+int fd;
+
+fd = open("filename.ppd", O_RDONLY);
+ppd = ppdOpenFd(fd);
+close(fd);
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdClose"><CODE>ppdClose()</CODE></A>,
+<A HREF="#ppdOpen"><CODE>ppdOpen()</CODE></A>,
+<A HREF="#ppdOpenFile"><CODE>ppdOpenFile()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdOpenFile">ppdOpenFile()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ppd_file_t *
+ppdOpenFile(const char *filename);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>filename</TD>
+ <TD>The name of the file to read from</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to a PPD file structure or NULL if the PPD file could not be
+read.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdOpenFile()</CODE> function reads a PPD file from the named
+file into memory.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppd = ppdOpenFile("filename.ppd");
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdClose"><CODE>ppdClose()</CODE></A>,
+<A HREF="#ppdOpen"><CODE>ppdOpen()</CODE></A>,
+<A HREF="#ppdOpenFd"><CODE>ppdOpenFd()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdPageLength">ppdPageLength()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+float
+ppdPageLength(ppd_file_t *ppd,
+ const char *name);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of the page size</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The length of the specified page size in points or 0 if the page size
+does not exist.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdPageLength()</CODE> function returns the page length of the
+specified page size.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("Length = %.0f\n", ppdPageLength(ppd, "Letter"));
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdPageLength"><CODE>ppdPageLength()</CODE></A>,
+<A HREF="#ppdPageSize"><CODE>ppdPageSize()</CODE></A>,
+<A HREF="#ppdPageWidth"><CODE>ppdPageWidth()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdPageSize">ppdPageSize()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+ppd_size_t *
+ppdPageSize(ppd_file_t *ppd,
+ const char *name);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of the page size</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>A pointer to the page size record of the specified page size in
+points or NULL if the page size does not exist.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdPageSize()</CODE> function returns the page size record for the
+specified page size.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_size_t *size;
+
+size = ppdPageSize(ppd, "Letter");
+if (size != NULL)
+{
+ printf(" Width = %.0f\n", size->width);
+ printf("Length = %.0f\n", size->length);
+ printf(" Left = %.0f\n", size->left);
+ printf(" Right = %.0f\n", size->right);
+ printf("Bottom = %.0f\n", size->bottom);
+ printf(" Top = %.0f\n", size->top);
+}
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdPageLength"><CODE>ppdPageLength()</CODE></A>,
+<A HREF="#ppdPageWidth"><CODE>ppdPageWidth()</CODE></A>
+
+
+<!-- NEW PAGE --><H2><A NAME="ppdPageWidth">ppdPageWidth()</A></H2>
+
+<H3>Usage</H3>
+
+<PRE>
+float
+ppdPageWidth(ppd_file_t *ppd,
+ const char *name);
+</PRE>
+
+<H3>Arguments</H3>
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<TR>
+ <TH>Argument</TH>
+ <TH>Description</TH>
+</TR>
+<TR>
+ <TD>ppd</TD>
+ <TD>The PPD file</TD>
+</TR>
+<TR>
+ <TD>name</TD>
+ <TD>The name of the page size</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Returns</H3>
+
+<P>The width of the specified page size in points or 0 if the page size
+does not exist.
+
+<H3>Description</H3>
+
+<P>The <CODE>ppdPageWidth()</CODE> function returns the page width of the
+specified page size.
+
+<H3>Example</H3>
+
+<PRE>
+#include &lt;cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("Width = %.0f\n", ppdPageWidth(ppd, "Letter"));
+</PRE>
+
+<H3>See Also</H3>
+
+<A HREF="#ppdPageLength"><CODE>ppdPageLength()</CODE></A>,
+<A HREF="#ppdPageSize"><CODE>ppdPageSize()</CODE></A>
+
+
+</BODY>
+</HTML>
diff --git a/doc/sps.html b/doc/sps.html
new file mode 100644
index 000000000..77af67b9e
--- /dev/null
+++ b/doc/sps.html
@@ -0,0 +1,297 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Software Performance Specification</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-SPS-1.1">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY>
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Software Performance Specification</H1></A><BR>
+CUPS-SPS-1.1<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">1 Scope</A></B>
+<UL>
+<LI><A HREF="#1_1">1.1 Identification</A></LI>
+<LI><A HREF="#1_2">1.2 System Overview</A></LI>
+<LI><A HREF="#1_3">1.3 Document Overview</A></LI>
+</UL>
+<B><A HREF="#2">2 References</A></B>
+<UL>
+<LI><A HREF="#2_1">2.1 CUPS Documentation</A></LI>
+<LI><A HREF="#2_2">2.2 Other Documents</A></LI>
+</UL>
+<B><A HREF="#3">3 Programs</A></B>
+<BR>
+<BR><B><A HREF="#4">4 Scheduler Objects</A></B>
+<BR>
+<BR><B><A HREF="#5">A Glossary</A></B>
+<UL>
+<LI><A HREF="#5_1">A.1 Terms</A></LI>
+<LI><A HREF="#5_2">A.2 Acronyms</A></LI>
+</UL>
+<HR>
+<H1><A NAME="1">1 Scope</A></H1>
+<H2><A NAME="1_1">1.1 Identification</A></H2>
+<P>This software performance specification provides an analysis of the
+ memory, disk, and processor utilitization of each program in the Common
+ UNIX Printing System (&quot;CUPS&quot;) Version 1.1.</P>
+<P>For the purposes of comparison, all figures are for the Linux Intel
+ platform. Memory utilization on other platforms should be similar.</P>
+<H2><A NAME="1_2">1.2 System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+<H2><A NAME="1_3">1.3 Document Overview</A></H2>
+<P>This software performance specification is organized into the
+ following sections:</P>
+<UL>
+<LI>1 - Scope</LI>
+<LI>2 - References</LI>
+<LI>3 - Programs</LI>
+<LI>4 - Scheduler Objects</LI>
+<LI>A - Glossary</LI>
+</UL>
+<H1><A NAME="2">2 References</A></H1>
+<H2><A NAME="2_1">2.1 CUPS Documentation</A></H2>
+<P>The following CUPS documentation is referenced by this document:</P>
+<UL>
+<LI>CUPS-CMP-1.1: CUPS Configuration Management Plan</LI>
+<LI>CUPS-IDD-1.1: CUPS System Interface Design Description</LI>
+<LI>CUPS-IPP-1.1: CUPS Implementation of IPP</LI>
+<LI>CUPS-SAM-1.1.x: CUPS Software Administrators Manual</LI>
+<LI>CUPS-SDD-1.1: CUPS Software Design Description</LI>
+<LI>CUPS-SPM-1.1.x: CUPS Software Programming Manual</LI>
+<LI>CUPS-SSR-1.1: CUPS Software Security Report</LI>
+<LI>CUPS-STP-1.1: CUPS Software Test Plan</LI>
+<LI>CUPS-SUM-1.1.x: CUPS Software Users Manual</LI>
+<LI>CUPS-SVD-1.1: CUPS Software Version Description</LI>
+</UL>
+<H2><A NAME="2_2">2.2 Other Documents</A></H2>
+<P>The following non-CUPS documents are referenced by this document:</P>
+<UL>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">
+Adobe PostScript Printer Description File Format Specification, Version
+ 4.3.</A></LI>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
+Adobe PostScript Language Reference, Third Edition.</A></LI>
+<LI>IPP: Job and Printer Set Operations</LI>
+<LI>IPP/1.1: Encoding and Transport</LI>
+<LI>IPP/1.1: Implementers Guide</LI>
+<LI>IPP/1.1: Model and Semantics</LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179, Line Printer
+ Daemon Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2567.txt">RFC 2567, Design Goals
+ for an Internet Printing Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2568.txt">RFC 2568, Rationale
+ for the Structure of the Model and Protocol for the Internet Printing
+ Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2569.txt">RFC 2569, Mapping
+ between LPD and IPP Protocols</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616, Hypertext
+ Transfer Protocol -- HTTP/1.1</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617, HTTP
+ Authentication: Basic and Digest Access</A> Authentication</LI>
+</UL>
+<H1><A NAME="3">3 Programs</A></H1>
+<P>The following table describes the average memory, disk, and CPU usage
+ of each program in CUPS.</P>
+<P>The base memory column shows the initial memory requirements for each
+ program, including any shared libraries that are provided by CUPS.</P>
+<P>The max memory column shows the maximum amount of memory that will be
+ used by the program based upon the default configuration settings
+ supplied with CUPS.</P>
+<P>The temp files column indicates whether any temporary files are
+ created.</P>
+<P>The CPU usage column specifies a relative CPU usage by the program
+ under normal conditions, either low, medium, or high. Low usage
+ indicates that the program will never use more than 33% of the
+ available CPU time. Medium usage indicates the program will use as much
+ as 66% of the available CPU time. High usage indicates the program uses
+ 66% or more of the available CPU time.
+<CENTER>
+<TABLE BORDER="1" WIDTH="80%">
+<TR><TH COLSPAN="3">Backends</TH></TR>
+<TR><TH>Program</TH><TH>Base Memory</TH><TH>Max Memory</TH><TH>Temp
+ Files</TH><TH>CPU Usage</TH></TR>
+<TR><TD>ipp</TD><TD>91k</TD><TD>256k</TD><TD>Up to size of print file</TD><TD>
+Low</TD></TR>
+<TR><TD>lpd</TD><TD>89k</TD><TD>89k</TD><TD>Up to size of print file</TD><TD>
+Low</TD></TR>
+<TR><TD>parallel</TD><TD>85k</TD><TD>85k</TD><TD>Up to size of print
+ file</TD><TD>Low</TD></TR>
+<TR><TD>serial</TD><TD>85k</TD><TD>85k</TD><TD>Up to size of print file</TD><TD>
+Low</TD></TR>
+<TR><TD>socket</TD><TD>85k</TD><TD>85k</TD><TD>Up to size of print file</TD><TD>
+Low</TD></TR>
+<TR><TD>usb</TD><TD>85k</TD><TD>85k</TD><TD>Up to size of print file</TD><TD>
+Low</TD></TR>
+<TR><TH COLSPAN="3">CGIs</TH></TR>
+<TR><TH>Program</TH><TH>Base Memory</TH><TH>Max Memory</TH><TH>Temp
+ Files</TH><TH>CPU Usage</TH></TR>
+<TR><TD>admin.cgi</TD><TD>107k</TD><TD>256k</TD><TD>Up to size of PPD
+ file</TD><TD>Medium</TD></TR>
+<TR><TD>classes.cgi</TD><TD>95k</TD><TD>Size of class objects</TD><TD>
+None</TD><TD>Medium</TD></TR>
+<TR><TD>jobs.cgi</TD><TD>93k</TD><TD>Size of job objects</TD><TD>None</TD><TD>
+Medium</TD></TR>
+<TR><TD>printers.cgi</TD><TD>95k</TD><TD>Size of printer objects</TD><TD>
+None</TD><TD>Medium</TD></TR>
+<TR><TH COLSPAN="3">Command-Line Programs</TH></TR>
+<TR><TH>Program</TH><TH>Base Memory</TH><TH>Max Memory</TH><TH>Temp
+ Files</TH><TH>CPU Usage</TH></TR>
+<TR><TD>accept</TD><TD>88k</TD><TD>128k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>cancel</TD><TD>88k</TD><TD>128k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>disable</TD><TD>88k</TD><TD>128k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>enable</TD><TD>88k</TD><TD>128k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>lp</TD><TD>90k</TD><TD>256k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>lpadmin</TD><TD>148k</TD><TD>256k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>lpc</TD><TD>86k</TD><TD>Size of job and printer objects</TD><TD>
+None</TD><TD>Medium</TD></TR>
+<TR><TD>lpinfo</TD><TD>89k</TD><TD>Size of device and PPD objects</TD><TD>
+None</TD><TD>Medium</TD></TR>
+<TR><TD>lpmove</TD><TD>88k</TD><TD>128k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>lpoptions</TD><TD>89k</TD><TD>128k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>lppasswd</TD><TD>90k</TD><TD>90k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>lpq</TD><TD>87k</TD><TD>Size of job objects</TD><TD>None</TD><TD>
+Medium</TD></TR>
+<TR><TD>lpr</TD><TD>87k</TD><TD>256k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>lprm</TD><TD>84k</TD><TD>128k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>lpstat</TD><TD>119k</TD><TD>Size of job, printer, and class
+ objects</TD><TD>None</TD><TD>Medium</TD></TR>
+<TR><TD>reject</TD><TD>88k</TD><TD>128k</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TH COLSPAN="3">Daemons</TH></TR>
+<TR><TH>Program</TH><TH>Base Memory</TH><TH>Max Memory</TH><TH>Temp
+ Files</TH><TH>CPU Usage</TH></TR>
+<TR><TD>cups-lpd</TD><TD>92k</TD><TD>256k</TD><TD>One file per control
+ or data file from client</TD><TD>Low</TD></TR>
+<TR><TD>cupsd</TD><TD>308k</TD><TD>See Scheduler Requirements</TD><TD>
+See Scheduler Requirements</TD><TD>Medium</TD></TR>
+<TR><TD>cups-polld</TD><TD>84k</TD><TD>Size of printer and class objects</TD><TD>
+None</TD><TD>Low</TD></TR>
+<TR><TH COLSPAN="3">Filters</TH></TR>
+<TR><TH>Program</TH><TH>Base Memory</TH><TH>Max Memory</TH><TH>Temp
+ Files</TH><TH>CPU Usage</TH></TR>
+<TR><TD>hpgltops</TD><TD>263k</TD><TD>320k</TD><TD>None</TD><TD>Medium</TD>
+</TR>
+<TR><TD>imagetops</TD><TD>628k</TD><TD>10M</TD><TD>Swap file for
+ uncompressed image data</TD><TD>Medium</TD></TR>
+<TR><TD>imagetoraster</TD><TD>652k</TD><TD>10M</TD><TD>Swap file for
+ uncompressed image data</TD><TD>High</TD></TR>
+<TR><TD>pstops</TD><TD>775k</TD><TD>840k</TD><TD>Up to size of print
+ file</TD><TD>Medium</TD></TR>
+<TR><TD>pstoraster</TD><TD>4M</TD><TD>14M</TD><TD>Swap file for command
+ lists</TD><TD>High</TD></TR>
+<TR><TD>rastertoepson</TD><TD>693k</TD><TD>1M</TD><TD>None</TD><TD>Low</TD>
+</TR>
+<TR><TD>rastertohp</TD><TD>690k</TD><TD>1M</TD><TD>None</TD><TD>Low</TD></TR>
+<TR><TD>texttops</TD><TD>638k</TD><TD>4*cols*rows</TD><TD>None</TD><TD>
+Low</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H1><A NAME="4">4 Scheduler Objects</A></H1>
+<P>The <CODE>cupsd</CODE> program is the CUPS scheduler process. It
+ manages many interdependent server objects that are used to manage and
+ print files to printers.</P>
+<P>The following table provides the memory and disk cost associated with
+ each server object.
+<CENTER>
+<TABLE BORDER="1" WIDTH="80%">
+<TR><TH>Object</TH><TH>Memory Per</TH><TH>Disk Per</TH></TR>
+<TR><TD>Browse ACL</TD><TD>1k</TD><TD>120</TD></TR>
+<TR><TD>Browse Poll</TD><TD>24</TD><TD>80</TD></TR>
+<TR><TD>Browse Relay</TD><TD>28</TD><TD>80</TD></TR>
+<TR><TD>Certificate</TD><TD>76</TD><TD>32</TD></TR>
+<TR><TD>Class</TD><TD>9k</TD><TD>200</TD></TR>
+<TR><TD>Client</TD><TD>13k</TD><TD>-</TD></TR>
+<TR><TD>Device</TD><TD>256</TD><TD>-</TD></TR>
+<TR><TD>Job</TD><TD>2k</TD><TD>1k + size of document files</TD></TR>
+<TR><TD>Location ACL</TD><TD>1k</TD><TD>120</TD></TR>
+<TR><TD>MIME Filter</TD><TD>268</TD><TD>80</TD></TR>
+<TR><TD>MIME Type</TD><TD>340</TD><TD>80</TD></TR>
+<TR><TD>PPD</TD><TD>200</TD><TD>656</TD></TR>
+<TR><TD>Printer</TD><TD>11k</TD><TD>32k</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H1 TYPE="A" VALUE="1"><A NAME="5">A Glossary</A></H1>
+<H2><A NAME="5_1">A.1 Terms</A></H2>
+<DL>
+<DT>C</DT>
+<DD>A computer language.</DD>
+<DT>parallel</DT>
+<DD>Sending or receiving data more than 1 bit at a time.</DD>
+<DT>pipe</DT>
+<DD>A one-way communications channel between two programs.</DD>
+<DT>serial</DT>
+<DD>Sending or receiving data 1 bit at a time.</DD>
+<DT>socket</DT>
+<DD>A two-way network communications channel.</DD>
+</DL>
+<H2><A NAME="5_2">A.2 Acronyms</A></H2>
+<DL>
+<DT>ASCII</DT>
+<DD>American Standard Code for Information Interchange</DD>
+<DT>CUPS</DT>
+<DD>Common UNIX Printing System</DD>
+<DT>ESC/P</DT>
+<DD>EPSON Standard Code for Printers</DD>
+<DT>FTP</DT>
+<DD>File Transfer Protocol</DD>
+<DT>HP-GL</DT>
+<DD>Hewlett-Packard Graphics Language</DD>
+<DT>HP-PCL</DT>
+<DD>Hewlett-Packard Page Control Language</DD>
+<DT>HP-PJL</DT>
+<DD>Hewlett-Packard Printer Job Language</DD>
+<DT>IETF</DT>
+<DD>Internet Engineering Task Force</DD>
+<DT>IPP</DT>
+<DD>Internet Printing Protocol</DD>
+<DT>ISO</DT>
+<DD>International Standards Organization</DD>
+<DT>LPD</DT>
+<DD>Line Printer Daemon</DD>
+<DT>MIME</DT>
+<DD>Multimedia Internet Mail Exchange</DD>
+<DT>PPD</DT>
+<DD>PostScript Printer Description</DD>
+<DT>SMB</DT>
+<DD>Server Message Block</DD>
+<DT>TFTP</DT>
+<DD>Trivial File Transfer Protocol</DD>
+</DL>
+</BODY>
+</HTML>
diff --git a/doc/sps.pdf b/doc/sps.pdf
new file mode 100644
index 000000000..af050fe19
--- /dev/null
+++ b/doc/sps.pdf
Binary files differ
diff --git a/doc/sps.shtml b/doc/sps.shtml
new file mode 100644
index 000000000..88959006e
--- /dev/null
+++ b/doc/sps.shtml
@@ -0,0 +1,457 @@
+<HTML>
+<HEAD>
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-SPS-1.1">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Software Performance Specification</TITLE>
+</HEAD>
+<BODY>
+
+<H1>Scope</H1>
+
+<H2>Identification</H2>
+
+<P>This software performance specification provides an analysis of the
+memory, disk, and processor utilitization of each program in the
+Common UNIX Printing System ("CUPS") Version 1.1.</P>
+
+<P>For the purposes of comparison, all figures are for the Linux Intel
+platform. Memory utilization on other platforms should be similar.
+
+<EMBED SRC="system-overview.shtml">
+
+<H2>Document Overview</H2>
+
+<P>This software performance specification is organized into the
+following sections:</P>
+
+<UL>
+ <LI>1 - Scope</LI>
+ <LI>2 - References</LI>
+ <LI>3 - Programs</LI>
+ <LI>4 - Scheduler Objects</LI>
+ <LI>A - Glossary</LI>
+</UL>
+
+<EMBED SRC="references.shtml">
+
+<H1>Programs</H1>
+
+<P>The following table describes the average memory, disk, and CPU usage of
+each program in CUPS.
+
+<P>The base memory column shows the initial memory requirements for each
+program, including any shared libraries that are provided by CUPS.
+
+<P>The max memory column shows the maximum amount of memory that will be
+used by the program based upon the default configuration settings supplied
+with CUPS.
+
+<P>The temp files column indicates whether any temporary files are created.
+
+<P>The CPU usage column specifies a relative CPU usage by the program under
+normal conditions, either low, medium, or high. Low usage indicates that
+the program will never use more than 33% of the available CPU time. Medium
+usage indicates the program will use as much as 66% of the available CPU
+time. High usage indicates the program uses 66% or more of the available CPU
+time.
+
+<CENTER><TABLE WIDTH="80%" BORDER="1">
+<TR>
+ <TH COLSPAN="3">Backends</TH>
+</TR>
+<TR>
+ <TH>Program</TH>
+ <TH>Base Memory</TH>
+ <TH>Max Memory</TH>
+ <TH>Temp Files</TH>
+ <TH>CPU Usage</TH>
+</TR>
+<TR>
+ <TD>ipp</TD>
+ <TD>91k</TD>
+ <TD>256k</TD>
+ <TD>Up to size of print file</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>lpd</TD>
+ <TD>89k</TD>
+ <TD>89k</TD>
+ <TD>Up to size of print file</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>parallel</TD>
+ <TD>85k</TD>
+ <TD>85k</TD>
+ <TD>Up to size of print file</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>serial</TD>
+ <TD>85k</TD>
+ <TD>85k</TD>
+ <TD>Up to size of print file</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>socket</TD>
+ <TD>85k</TD>
+ <TD>85k</TD>
+ <TD>Up to size of print file</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>usb</TD>
+ <TD>85k</TD>
+ <TD>85k</TD>
+ <TD>Up to size of print file</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TH COLSPAN="3">CGIs</TH>
+</TR>
+<TR>
+ <TH>Program</TH>
+ <TH>Base Memory</TH>
+ <TH>Max Memory</TH>
+ <TH>Temp Files</TH>
+ <TH>CPU Usage</TH>
+</TR>
+<TR>
+ <TD>admin.cgi</TD>
+ <TD>107k</TD>
+ <TD>256k</TD>
+ <TD>Up to size of PPD file</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TD>classes.cgi</TD>
+ <TD>95k</TD>
+ <TD>Size of class objects</TD>
+ <TD>None</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TD>jobs.cgi</TD>
+ <TD>93k</TD>
+ <TD>Size of job objects</TD>
+ <TD>None</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TD>printers.cgi</TD>
+ <TD>95k</TD>
+ <TD>Size of printer objects</TD>
+ <TD>None</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TH COLSPAN="3">Command-Line Programs</TH>
+</TR>
+<TR>
+ <TH>Program</TH>
+ <TH>Base Memory</TH>
+ <TH>Max Memory</TH>
+ <TH>Temp Files</TH>
+ <TH>CPU Usage</TH>
+</TR>
+<TR>
+ <TD>accept</TD>
+ <TD>88k</TD>
+ <TD>128k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>cancel</TD>
+ <TD>88k</TD>
+ <TD>128k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>disable</TD>
+ <TD>88k</TD>
+ <TD>128k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>enable</TD>
+ <TD>88k</TD>
+ <TD>128k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>lp</TD>
+ <TD>90k</TD>
+ <TD>256k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>lpadmin</TD>
+ <TD>148k</TD>
+ <TD>256k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>lpc</TD>
+ <TD>86k</TD>
+ <TD>Size of job and printer objects</TD>
+ <TD>None</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TD>lpinfo</TD>
+ <TD>89k</TD>
+ <TD>Size of device and PPD objects</TD>
+ <TD>None</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TD>lpmove</TD>
+ <TD>88k</TD>
+ <TD>128k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>lpoptions</TD>
+ <TD>89k</TD>
+ <TD>128k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>lppasswd</TD>
+ <TD>90k</TD>
+ <TD>90k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>lpq</TD>
+ <TD>87k</TD>
+ <TD>Size of job objects</TD>
+ <TD>None</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TD>lpr</TD>
+ <TD>87k</TD>
+ <TD>256k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>lprm</TD>
+ <TD>84k</TD>
+ <TD>128k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>lpstat</TD>
+ <TD>119k</TD>
+ <TD>Size of job, printer, and class objects</TD>
+ <TD>None</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TD>reject</TD>
+ <TD>88k</TD>
+ <TD>128k</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TH COLSPAN="3">Daemons</TH>
+</TR>
+<TR>
+ <TH>Program</TH>
+ <TH>Base Memory</TH>
+ <TH>Max Memory</TH>
+ <TH>Temp Files</TH>
+ <TH>CPU Usage</TH>
+</TR>
+<TR>
+ <TD>cups-lpd</TD>
+ <TD>92k</TD>
+ <TD>256k</TD>
+ <TD>One file per control or data file from client</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>cupsd</TD>
+ <TD>308k</TD>
+ <TD>See Scheduler Requirements</TD>
+ <TD>See Scheduler Requirements</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TD>cups-polld</TD>
+ <TD>84k</TD>
+ <TD>Size of printer and class objects</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TH COLSPAN="3">Filters</TH>
+</TR>
+<TR>
+ <TH>Program</TH>
+ <TH>Base Memory</TH>
+ <TH>Max Memory</TH>
+ <TH>Temp Files</TH>
+ <TH>CPU Usage</TH>
+</TR>
+<TR>
+ <TD>hpgltops</TD>
+ <TD>263k</TD>
+ <TD>320k</TD>
+ <TD>None</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TD>imagetops</TD>
+ <TD>628k</TD>
+ <TD>10M</TD>
+ <TD>Swap file for uncompressed image data</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TD>imagetoraster</TD>
+ <TD>652k</TD>
+ <TD>10M</TD>
+ <TD>Swap file for uncompressed image data</TD>
+ <TD>High</TD>
+</TR>
+<TR>
+ <TD>pstops</TD>
+ <TD>775k</TD>
+ <TD>840k</TD>
+ <TD>Up to size of print file</TD>
+ <TD>Medium</TD>
+</TR>
+<TR>
+ <TD>pstoraster</TD>
+ <TD>4M</TD>
+ <TD>14M</TD>
+ <TD>Swap file for command lists</TD>
+ <TD>High</TD>
+</TR>
+<TR>
+ <TD>rastertoepson</TD>
+ <TD>693k</TD>
+ <TD>1M</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>rastertohp</TD>
+ <TD>690k</TD>
+ <TD>1M</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+<TR>
+ <TD>texttops</TD>
+ <TD>638k</TD>
+ <TD>4*cols*rows</TD>
+ <TD>None</TD>
+ <TD>Low</TD>
+</TR>
+</TABLE></CENTER>
+
+
+<H1>Scheduler Objects</H1>
+
+<P>The <CODE>cupsd</CODE> program is the CUPS scheduler process. It manages
+many interdependent server objects that are used to manage and print files
+to printers.
+
+<P>The following table provides the memory and disk cost associated with each
+server object.
+
+<CENTER><TABLE WIDTH="80%" BORDER="1">
+<TR>
+ <TH>Object</TH>
+ <TH>Memory Per</TH>
+ <TH>Disk Per</TH>
+</TR>
+<TR>
+ <TD>Browse ACL</TD>
+ <TD>1k</TD>
+ <TD>120</TD>
+</TR>
+<TR>
+ <TD>Browse Poll</TD>
+ <TD>24</TD>
+ <TD>80</TD>
+</TR>
+<TR>
+ <TD>Browse Relay</TD>
+ <TD>28</TD>
+ <TD>80</TD>
+</TR>
+<TR>
+ <TD>Certificate</TD>
+ <TD>76</TD>
+ <TD>32</TD>
+</TR>
+<TR>
+ <TD>Class</TD>
+ <TD>9k</TD>
+ <TD>200</TD>
+</TR>
+<TR>
+ <TD>Client</TD>
+ <TD>13k</TD>
+ <TD>-</TD>
+</TR>
+<TR>
+ <TD>Device</TD>
+ <TD>256</TD>
+ <TD>-</TD>
+</TR>
+<TR>
+ <TD>Job</TD>
+ <TD>2k</TD>
+ <TD>1k + size of document files</TD>
+</TR>
+<TR>
+ <TD>Location ACL</TD>
+ <TD>1k</TD>
+ <TD>120</TD>
+</TR>
+<TR>
+ <TD>MIME Filter</TD>
+ <TD>268</TD>
+ <TD>80</TD>
+</TR>
+<TR>
+ <TD>MIME Type</TD>
+ <TD>340</TD>
+ <TD>80</TD>
+</TR>
+<TR>
+ <TD>PPD</TD>
+ <TD>200</TD>
+ <TD>656</TD>
+</TR>
+<TR>
+ <TD>Printer</TD>
+ <TD>11k</TD>
+ <TD>32k</TD>
+</TR>
+</TABLE></CENTER>
+
+<EMBED SRC="glossary.shtml">
+
+</BODY>
+</HTML>
diff --git a/doc/ssr.html b/doc/ssr.html
new file mode 100644
index 000000000..68b144c99
--- /dev/null
+++ b/doc/ssr.html
@@ -0,0 +1,275 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Software Security Report</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-SSR-1.1">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY>
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Software Security Report</H1></A><BR>
+CUPS-SSR-1.1<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">1 Scope</A></B>
+<UL>
+<LI><A HREF="#1_1">1.1 Identification</A></LI>
+<LI><A HREF="#1_2">1.2 System Overview</A></LI>
+<LI><A HREF="#1_3">1.3 Document Overview</A></LI>
+</UL>
+<B><A HREF="#2">2 References</A></B>
+<UL>
+<LI><A HREF="#2_1">2.1 CUPS Documentation</A></LI>
+<LI><A HREF="#2_2">2.2 Other Documents</A></LI>
+</UL>
+<B><A HREF="#3">3 Local Access Risks</A></B>
+<UL>
+<LI><A HREF="#3_1">3.1 Security Breaches</A></LI>
+</UL>
+<B><A HREF="#4">4 Remote Access Risks</A></B>
+<UL>
+<LI><A HREF="#4_1">4.1 Denial of Service Attacks</A></LI>
+<LI><A HREF="#4_2">4.2 Security Breaches</A></LI>
+</UL>
+<B><A HREF="#5">A Glossary</A></B>
+<UL>
+<LI><A HREF="#5_1">A.1 Terms</A></LI>
+<LI><A HREF="#5_2">A.2 Acronyms</A></LI>
+</UL>
+<HR>
+<H1><A NAME="1">1 Scope</A></H1>
+<H2><A NAME="1_1">1.1 Identification</A></H2>
+<P>This software security report provides an analysis of possible
+ security concerns for the Common UNIX Printing System (&quot;CUPS&quot;) Version
+ 1.1.</P>
+<H2><A NAME="1_2">1.2 System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+<H2><A NAME="1_3">1.3 Document Overview</A></H2>
+<P>This software security report is organized into the following
+ sections:</P>
+<UL>
+<LI>1 - Scope</LI>
+<LI>2 - References</LI>
+<LI>3 - Local Access Risks</LI>
+<LI>4 - Remote Access Risks</LI>
+<LI>A - Glossary</LI>
+</UL>
+<H1><A NAME="2">2 References</A></H1>
+<H2><A NAME="2_1">2.1 CUPS Documentation</A></H2>
+<P>The following CUPS documentation is referenced by this document:</P>
+<UL>
+<LI>CUPS-CMP-1.1: CUPS Configuration Management Plan</LI>
+<LI>CUPS-IDD-1.1: CUPS System Interface Design Description</LI>
+<LI>CUPS-IPP-1.1: CUPS Implementation of IPP</LI>
+<LI>CUPS-SAM-1.1.x: CUPS Software Administrators Manual</LI>
+<LI>CUPS-SDD-1.1: CUPS Software Design Description</LI>
+<LI>CUPS-SPM-1.1.x: CUPS Software Programming Manual</LI>
+<LI>CUPS-SSR-1.1: CUPS Software Security Report</LI>
+<LI>CUPS-STP-1.1: CUPS Software Test Plan</LI>
+<LI>CUPS-SUM-1.1.x: CUPS Software Users Manual</LI>
+<LI>CUPS-SVD-1.1: CUPS Software Version Description</LI>
+</UL>
+<H2><A NAME="2_2">2.2 Other Documents</A></H2>
+<P>The following non-CUPS documents are referenced by this document:</P>
+<UL>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">
+Adobe PostScript Printer Description File Format Specification, Version
+ 4.3.</A></LI>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
+Adobe PostScript Language Reference, Third Edition.</A></LI>
+<LI>IPP: Job and Printer Set Operations</LI>
+<LI>IPP/1.1: Encoding and Transport</LI>
+<LI>IPP/1.1: Implementers Guide</LI>
+<LI>IPP/1.1: Model and Semantics</LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179, Line Printer
+ Daemon Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2567.txt">RFC 2567, Design Goals
+ for an Internet Printing Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2568.txt">RFC 2568, Rationale
+ for the Structure of the Model and Protocol for the Internet Printing
+ Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2569.txt">RFC 2569, Mapping
+ between LPD and IPP Protocols</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616, Hypertext
+ Transfer Protocol -- HTTP/1.1</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617, HTTP
+ Authentication: Basic and Digest Access</A> Authentication</LI>
+</UL>
+<H1><A NAME="3">3 Local Access Risks</A></H1>
+<P>Local access risks are those that can be exploited only with a local
+ user account. This section does not address issues related to
+ dissemination of the root password or other security issues associated
+ with the UNIX operating system.</P>
+<H2><A NAME="3_1">3.1 Security Breaches</A></H2>
+<P>There is one known security vulnerability with local access:</P>
+<OL>
+<LI>Device URIs are passed to backend filters in argv[0] and in an
+ environment variable. Since device URIs can contain usernames and
+ passwords it may be possible for a local user to gain access to a
+ remote resource.
+<P>We recommend that any password-protected accounts used for remote
+ printing have limited access priviledges so that the possible damages
+ can be minimized.</P>
+<P>The device URI is &quot;sanitized&quot; (the username and password are removed)
+ when sent to an IPP client so that a remote user cannot exploit this
+ vulnerability.</P>
+</LI>
+</OL>
+<H1><A NAME="4">4 Remote Access Risks</A></H1>
+<P>Remote access risks are those that can be exploited without a local
+ user account and/or from a remote system. This section does not address
+ issues related to network or firewall security.</P>
+<H2><A NAME="4_1">4.1 Denial of Service Attacks</A></H2>
+<P>Like all Internet services, the CUPS server is vulnerable to denial
+ of service attacks, including:</P>
+<OL>
+<LI>Establishing multiple connections to the server until the server
+ will accept no more.
+<P>This cannot be protected against by the current software. It is
+ possible that future versions of the CUPS software could be configured
+ to limit the number of connections allowed from a single host, however
+ that still would not prevent a distributed attack.</P>
+<LI>Repeatedly opening and closing connections to the server as fast as
+ possible.
+<P>There is no easy way of protecting against this in the CUPS software.
+ If the attack is coming from outside the local network it might be
+ possible to filter such an attack, however once the connection request
+ has been received by the server it must at least accept the connection
+ to find out who is connecting.</P>
+<LI>Flooding the network with broadcast packets on port 631.
+<P>It might be possible to disable browsing if this condition is
+ detected by the CUPS software, however if there are large numbers of
+ printers available on the network such an algorithm might think that an
+ attack was occurring when instead a valid update was being received.</P>
+<LI>Sending partial IPP requests; specifically, sending part of an
+ attribute value and then stopping transmission.
+<P>The current code is structured to read and write the IPP request data
+ on-the-fly, so there is no easy way to protect against this for large
+ attribute values.</P>
+<LI>Sending large/long print jobs to printers, preventing other users
+ from printing.
+<P>There are limited facilities for protecting against large print jobs
+ (the <CODE>MaxRequestSize</CODE> attribute), however this will not
+ protect printers from malicious users and print files that generate
+ hundreds or thousands of pages. In general, we recommend restricting
+ printer access to known hosts or networks, and adding user-level access
+ control as needed for expensive printers.</P>
+</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<H2><A NAME="4_2">4.2 Security Breaches</A></H2>
+<P>The current CUPS server supports Basic, Digest, and local certificate
+ authentication:</P>
+<OL>
+<LI>Basic authentication essentially places the clear text of the
+ username and password on the network. Since CUPS uses the UNIX username
+ and password account information, the authentication information could
+ be used to gain access to accounts (possibly priviledged accounts) on
+ the server.</LI>
+<LI>Digest authentication uses an MD5 checksum of the username,
+ password, and domain (&quot;CUPS&quot;), so the original username and password is
+ not sent over the network. However, the current implementation does not
+ authenticate the entire message and uses the client's IP address for
+ the nonce value, making it possible to launch &quot;man in the middle&quot; and
+ replay attacks from the same client. The next minor release of CUPS
+ will support Digest authentication of the entire message body,
+ effectively stopping these methods of attack.</LI>
+<LI>Local certificate authentication passes 128-bit &quot;certificates&quot; that
+ identify an authenticated user. Certificates are created on-the-fly
+ from random data and stored in files under <CODE>/etc/cups/certs</CODE>
+. They have restricted read permissions: root + system for the root
+ certificate, and lp + system for CGI certificates. Because certificates
+ are only available on the local system, the CUPS server does not accept
+ local authentication unless the client is connected to the localhost
+ address (127.0.0.1.)</LI>
+</OL>
+<P>The default CUPS configuration disables remote administration. We do
+ not recommend that remote administration be enabled for all hosts.
+ However, if you have a trusted network or subnet, access can be
+ restricted accordingly. Also, we highly recommend using Digest
+ authentication when possible. Unfortunately, most web browsers do not
+ support Digest authentication at this time.</P>
+<H1 TYPE="A" VALUE="1"><A NAME="5">A Glossary</A></H1>
+<H2><A NAME="5_1">A.1 Terms</A></H2>
+<DL>
+<DT>C</DT>
+<DD>A computer language.</DD>
+<DT>parallel</DT>
+<DD>Sending or receiving data more than 1 bit at a time.</DD>
+<DT>pipe</DT>
+<DD>A one-way communications channel between two programs.</DD>
+<DT>serial</DT>
+<DD>Sending or receiving data 1 bit at a time.</DD>
+<DT>socket</DT>
+<DD>A two-way network communications channel.</DD>
+</DL>
+<H2><A NAME="5_2">A.2 Acronyms</A></H2>
+<DL>
+<DT>ASCII</DT>
+<DD>American Standard Code for Information Interchange</DD>
+<DT>CUPS</DT>
+<DD>Common UNIX Printing System</DD>
+<DT>ESC/P</DT>
+<DD>EPSON Standard Code for Printers</DD>
+<DT>FTP</DT>
+<DD>File Transfer Protocol</DD>
+<DT>HP-GL</DT>
+<DD>Hewlett-Packard Graphics Language</DD>
+<DT>HP-PCL</DT>
+<DD>Hewlett-Packard Page Control Language</DD>
+<DT>HP-PJL</DT>
+<DD>Hewlett-Packard Printer Job Language</DD>
+<DT>IETF</DT>
+<DD>Internet Engineering Task Force</DD>
+<DT>IPP</DT>
+<DD>Internet Printing Protocol</DD>
+<DT>ISO</DT>
+<DD>International Standards Organization</DD>
+<DT>LPD</DT>
+<DD>Line Printer Daemon</DD>
+<DT>MIME</DT>
+<DD>Multimedia Internet Mail Exchange</DD>
+<DT>PPD</DT>
+<DD>PostScript Printer Description</DD>
+<DT>SMB</DT>
+<DD>Server Message Block</DD>
+<DT>TFTP</DT>
+<DD>Trivial File Transfer Protocol</DD>
+</DL>
+</BODY>
+</HTML>
diff --git a/doc/ssr.pdf b/doc/ssr.pdf
new file mode 100644
index 000000000..ab3f5b85f
--- /dev/null
+++ b/doc/ssr.pdf
Binary files differ
diff --git a/doc/ssr.shtml b/doc/ssr.shtml
new file mode 100644
index 000000000..8dc9cf590
--- /dev/null
+++ b/doc/ssr.shtml
@@ -0,0 +1,167 @@
+<HTML>
+<HEAD>
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-SSR-1.1">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Software Security Report</TITLE>
+</HEAD>
+<BODY>
+
+<H1>Scope</H1>
+
+<H2>Identification</H2>
+
+<P>This software security report provides an analysis of possible security
+concerns for the Common UNIX Printing System ("CUPS") Version 1.1.</P>
+
+<EMBED SRC="system-overview.shtml">
+
+<H2>Document Overview</H2>
+
+<P>This software security report is organized into the following sections:</P>
+
+<UL>
+ <LI>1 - Scope</LI>
+ <LI>2 - References</LI>
+ <LI>3 - Local Access Risks</LI>
+ <LI>4 - Remote Access Risks</LI>
+ <LI>A - Glossary</LI>
+</UL>
+
+<EMBED SRC="references.shtml">
+
+<H1>Local Access Risks</H1>
+
+<P>Local access risks are those that can be exploited only with a local user
+account. This section does not address issues related to dissemination of the
+root password or other security issues associated with the UNIX operating
+system.
+
+<H2>Security Breaches</H2>
+
+<P>There is one known security vulnerability with local access:
+
+<OL>
+
+ <LI>Device URIs are passed to backend filters in argv[0] and in
+ an environment variable. Since device URIs can contain
+ usernames and passwords it may be possible for a local user to
+ gain access to a remote resource.
+
+ <P>We recommend that any password-protected accounts used for
+ remote printing have limited access priviledges so that the
+ possible damages can be minimized.
+
+ <P>The device URI is "sanitized" (the username and password are
+ removed) when sent to an IPP client so that a remote user
+ cannot exploit this vulnerability.
+
+</OL>
+
+<H1>Remote Access Risks</H1>
+
+<P>Remote access risks are those that can be exploited without a local user
+account and/or from a remote system. This section does not address issues
+related to network or firewall security.
+
+<H2>Denial of Service Attacks</H2>
+
+<P>Like all Internet services, the CUPS server is vulnerable to denial of
+service attacks, including:
+
+<OL>
+
+ <LI>Establishing multiple connections to the server until the server
+ will accept no more.
+
+ <P>This cannot be protected against by the current software. It
+ is possible that future versions of the CUPS software could be
+ configured to limit the number of connections allowed from a
+ single host, however that still would not prevent a distributed
+ attack.
+
+ <LI>Repeatedly opening and closing connections to the server as fast
+ as possible.
+
+ <P>There is no easy way of protecting against this in the CUPS
+ software. If the attack is coming from outside the local
+ network it might be possible to filter such an attack, however
+ once the connection request has been received by the server it
+ must at least accept the connection to find out who is
+ connecting.
+
+ <LI>Flooding the network with broadcast packets on port 631.
+
+ <P>It might be possible to disable browsing if this condition
+ is detected by the CUPS software, however if there are large
+ numbers of printers available on the network such an algorithm
+ might think that an attack was occurring when instead a valid
+ update was being received.
+
+ <LI>Sending partial IPP requests; specifically, sending part of an
+ attribute value and then stopping transmission.
+
+ <P>The current code is structured to read and write the IPP
+ request data on-the-fly, so there is no easy way to protect
+ against this for large attribute values.
+
+ <LI>Sending large/long print jobs to printers, preventing other users
+ from printing.
+
+ <P>There are limited facilities for protecting against large print
+ jobs (the <CODE>MaxRequestSize</CODE> attribute), however this will
+ not protect printers from malicious users and print files that
+ generate hundreds or thousands of pages. In general, we recommend
+ restricting printer access to known hosts or networks, and adding
+ user-level access control as needed for expensive printers.
+
+</OL>
+
+<H2>Security Breaches</H2>
+
+<P>The current CUPS server supports Basic, Digest, and local certificate
+authentication:
+
+<OL>
+
+ <LI>Basic authentication essentially places the clear text of
+ the username and password on the network. Since CUPS uses the
+ UNIX username and password account information, the
+ authentication information could be used to gain access to
+ accounts (possibly priviledged accounts) on the server.
+
+ <LI>Digest authentication uses an MD5 checksum of the username,
+ password, and domain ("CUPS"), so the original username and
+ password is not sent over the network. However, the current
+ implementation does not authenticate the entire message and
+ uses the client's IP address for the nonce value, making it
+ possible to launch "man in the middle" and replay attacks from
+ the same client. The next minor release of CUPS will support
+ Digest authentication of the entire message body, effectively
+ stopping these methods of attack.
+
+ <LI>Local certificate authentication passes 128-bit
+ "certificates" that identify an authenticated user.
+ Certificates are created on-the-fly from random data and stored
+ in files under <CODE>/etc/cups/certs</CODE>. They have
+ restricted read permissions: root + system for the root
+ certificate, and lp + system for CGI certificates. Because
+ certificates are only available on the local system, the CUPS
+ server does not accept local authentication unless the client
+ is connected to the localhost address (127.0.0.1.)
+
+</OL>
+
+<P>The default CUPS configuration disables remote administration. We do
+not recommend that remote administration be enabled for all hosts.
+However, if you have a trusted network or subnet, access can be
+restricted accordingly.
+
+Also, we highly recommend using Digest authentication when possible.
+Unfortunately, most web browsers do not support Digest authentication
+at this time.
+
+<EMBED SRC="glossary.shtml">
+
+</BODY>
+</HTML>
diff --git a/doc/stp.html b/doc/stp.html
new file mode 100644
index 000000000..c26223ccf
--- /dev/null
+++ b/doc/stp.html
@@ -0,0 +1,262 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Software Test Plan</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-STP-1.1">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY>
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Software Test Plan</H1></A><BR>
+CUPS-STP-1.1<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">1 Scope</A></B>
+<UL>
+<LI><A HREF="#1_1">1.1 Identification</A></LI>
+<LI><A HREF="#1_2">1.2 System Overview</A></LI>
+<LI><A HREF="#1_3">1.3 Document Overview</A></LI>
+</UL>
+<B><A HREF="#2">2 References</A></B>
+<UL>
+<LI><A HREF="#2_1">2.1 CUPS Documentation</A></LI>
+<LI><A HREF="#2_2">2.2 Other Documents</A></LI>
+</UL>
+<B><A HREF="#3">3 Test Procedure</A></B>
+<BR>
+<BR><B><A HREF="#4">4 IPP Compliance Tests</A></B>
+<UL>
+<LI><A HREF="#4_1">4.1 Request Tests</A></LI>
+<LI><A HREF="#4_2">4.2 CUPS Printer Operation Tests</A></LI>
+<LI><A HREF="#4_3">4.3 Job Operation Tests</A></LI>
+</UL>
+<B><A HREF="#5">5 Command Tests</A></B>
+<UL>
+<LI><A HREF="#5_1">5.1 lpadmin</A></LI>
+<LI><A HREF="#5_2">5.2 lpc</A></LI>
+<LI><A HREF="#5_3">5.3 lpq</A></LI>
+<LI><A HREF="#5_4">5.4 lpstat</A></LI>
+<LI><A HREF="#5_5">5.5 lp</A></LI>
+<LI><A HREF="#5_6">5.6 lpr</A></LI>
+<LI><A HREF="#5_7">5.7 lprm</A></LI>
+<LI><A HREF="#5_8">5.8 cancel</A></LI>
+<LI><A HREF="#5_9">5.9 lpinfo</A></LI>
+</UL>
+<B><A HREF="#6">A Glossary</A></B>
+<UL>
+<LI><A HREF="#6_1">A.1 Terms</A></LI>
+<LI><A HREF="#6_2">A.2 Acronyms</A></LI>
+</UL>
+<HR>
+<H1><A NAME="1">1 Scope</A></H1>
+<H2><A NAME="1_1">1.1 Identification</A></H2>
+<P>This software test plan provides detailed tests that are used to
+ evaluate the stability and compliance of the Common UNIX Printing
+ System (&quot;CUPS&quot;) Version 1.1.</P>
+<H2><A NAME="1_2">1.2 System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+<H2><A NAME="1_3">1.3 Document Overview</A></H2>
+<P>This software test plan is organized into the following sections:</P>
+<UL>
+<LI>1 - Scope</LI>
+<LI>2 - References</LI>
+<LI>3 - Test Procedure</LI>
+<LI>4 - IPP Compliance Tests</LI>
+<LI>5 - Command Tests</LI>
+<LI>A - Glossary</LI>
+</UL>
+<H1><A NAME="2">2 References</A></H1>
+<H2><A NAME="2_1">2.1 CUPS Documentation</A></H2>
+<P>The following CUPS documentation is referenced by this document:</P>
+<UL>
+<LI>CUPS-CMP-1.1: CUPS Configuration Management Plan</LI>
+<LI>CUPS-IDD-1.1: CUPS System Interface Design Description</LI>
+<LI>CUPS-IPP-1.1: CUPS Implementation of IPP</LI>
+<LI>CUPS-SAM-1.1.x: CUPS Software Administrators Manual</LI>
+<LI>CUPS-SDD-1.1: CUPS Software Design Description</LI>
+<LI>CUPS-SPM-1.1.x: CUPS Software Programming Manual</LI>
+<LI>CUPS-SSR-1.1: CUPS Software Security Report</LI>
+<LI>CUPS-STP-1.1: CUPS Software Test Plan</LI>
+<LI>CUPS-SUM-1.1.x: CUPS Software Users Manual</LI>
+<LI>CUPS-SVD-1.1: CUPS Software Version Description</LI>
+</UL>
+<H2><A NAME="2_2">2.2 Other Documents</A></H2>
+<P>The following non-CUPS documents are referenced by this document:</P>
+<UL>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">
+Adobe PostScript Printer Description File Format Specification, Version
+ 4.3.</A></LI>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
+Adobe PostScript Language Reference, Third Edition.</A></LI>
+<LI>IPP: Job and Printer Set Operations</LI>
+<LI>IPP/1.1: Encoding and Transport</LI>
+<LI>IPP/1.1: Implementers Guide</LI>
+<LI>IPP/1.1: Model and Semantics</LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179, Line Printer
+ Daemon Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2567.txt">RFC 2567, Design Goals
+ for an Internet Printing Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2568.txt">RFC 2568, Rationale
+ for the Structure of the Model and Protocol for the Internet Printing
+ Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2569.txt">RFC 2569, Mapping
+ between LPD and IPP Protocols</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616, Hypertext
+ Transfer Protocol -- HTTP/1.1</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617, HTTP
+ Authentication: Basic and Digest Access</A> Authentication</LI>
+</UL>
+<H1><A NAME="3">3 Test Procedure</A></H1>
+<P>The test software and data files are located in the<VAR> test</VAR>
+ subdirectory of the source distribution. A script is provided to
+ compile the <CODE>ipptest</CODE> program and run all of the tests that
+ follow, producing a success/fail report.</P>
+<P>The <CODE>test</CODE> target of the top-level makefile can be used to
+ run this script:</P>
+<UL>
+<PRE>
+make test
+</PRE>
+</UL>
+<P>or you can run the test script directly:</P>
+<UL>
+<PRE>
+cd test
+./run-stp-tests
+</PRE>
+</UL>
+<P>A Software Test Report is stored in HTML and PDF files that are
+ generated using the<A HREF="http://www.easysw.com/htmldoc"> HTMLDOC</A>
+ software.</P>
+<H1><A NAME="4">4 IPP Compliance Tests</A></H1>
+<P>This section describes the tests used to validate the IPP standards
+ compliance of the CUPS server.</P>
+<H2><A NAME="4_1">4.1 Request Tests</A></H2>
+<P>These tests verify that the CUPS scheduler only accepts valid IPP
+ requests that start with the <CODE>attributes-charset</CODE> and <CODE>
+attributes-natural-language</CODE> attributes and also contain a <CODE>
+printer-uri</CODE> or <CODE>job-uri</CODE> attribute.</P>
+<P>It also verifies that the CUPS scheduler always responds with <CODE>
+attributes-charset</CODE> and <CODE>attributes-natural-language</CODE>
+ attributes, using default values if they are not provided by the
+ client.</P>
+<H2><A NAME="4_2">4.2 CUPS Printer Operation Tests</A></H2>
+<P>These tests verify that the CUPS printer operations are supported and
+ function properly. Two printers called <CODE>Test1</CODE> and <CODE>
+Test2</CODE> are created, one as a PostScript printer and one as a
+ raster printer.</P>
+<H2><A NAME="4_3">4.3 Job Operation Tests</A></H2>
+<P>These test verify that the CUPS scheduler accepts print jobs for all
+ supported file formats and that the <CODE>cancel-job</CODE>, <CODE>
+hold-job</CODE>, and <CODE>resume-job</CODE> operations work.</P>
+<H1><A NAME="5">5 Command Tests</A></H1>
+<P>This section describes the tests used to validate the Berkeley and
+ System V commands included with CUPS.</P>
+<H2><A NAME="5_1">5.1 lpadmin</A></H2>
+<P>This test verifies that printers can be added, modified, and
+ defaulted using the <CODE>lpadmin</CODE> command.</P>
+<H2><A NAME="5_2">5.2 lpc</A></H2>
+<P>This test verifies that the <CODE>lpc</CODE> command can show the
+ current status of all print queues.</P>
+<H2><A NAME="5_3">5.3 lpq</A></H2>
+<P>This test verifies that the <CODE>lpq</CODE> command lists any jobs
+ in the queue.</P>
+<H2><A NAME="5_4">5.4 lpstat</A></H2>
+<P>This test verifies that the <CODE>lpstat</CODE> command works with
+ all reports using the &quot;<CODE>-t</CODE>&quot; option.</P>
+<H2><A NAME="5_5">5.5 lp</A></H2>
+<P>This test verifies that the <CODE>lp</CODE> command works with both
+ the default destination and a specific destination.</P>
+<H2><A NAME="5_6">5.6 lpr</A></H2>
+<P>This test verifies that the <CODE>lpr</CODE> command works with both
+ the default destination and a specific destination.</P>
+<H2><A NAME="5_7">5.7 lprm</A></H2>
+<P>This test verifies that the <CODE>lprm</CODE> command can properly
+ cancel a job.</P>
+<H2><A NAME="5_8">5.8 cancel</A></H2>
+<P>This test verifies that the <CODE>cancel</CODE> command can properly
+ cancel a job or all jobs.</P>
+<H2><A NAME="5_9">5.9 lpinfo</A></H2>
+<P>This test verifies that the <CODE>lpinfo</CODE> command returns a
+ list of available printer drivers and devices.</P>
+<H1 TYPE="A" VALUE="1"><A NAME="6">A Glossary</A></H1>
+<H2><A NAME="6_1">A.1 Terms</A></H2>
+<DL>
+<DT>C</DT>
+<DD>A computer language.</DD>
+<DT>parallel</DT>
+<DD>Sending or receiving data more than 1 bit at a time.</DD>
+<DT>pipe</DT>
+<DD>A one-way communications channel between two programs.</DD>
+<DT>serial</DT>
+<DD>Sending or receiving data 1 bit at a time.</DD>
+<DT>socket</DT>
+<DD>A two-way network communications channel.</DD>
+</DL>
+<H2><A NAME="6_2">A.2 Acronyms</A></H2>
+<DL>
+<DT>ASCII</DT>
+<DD>American Standard Code for Information Interchange</DD>
+<DT>CUPS</DT>
+<DD>Common UNIX Printing System</DD>
+<DT>ESC/P</DT>
+<DD>EPSON Standard Code for Printers</DD>
+<DT>FTP</DT>
+<DD>File Transfer Protocol</DD>
+<DT>HP-GL</DT>
+<DD>Hewlett-Packard Graphics Language</DD>
+<DT>HP-PCL</DT>
+<DD>Hewlett-Packard Page Control Language</DD>
+<DT>HP-PJL</DT>
+<DD>Hewlett-Packard Printer Job Language</DD>
+<DT>IETF</DT>
+<DD>Internet Engineering Task Force</DD>
+<DT>IPP</DT>
+<DD>Internet Printing Protocol</DD>
+<DT>ISO</DT>
+<DD>International Standards Organization</DD>
+<DT>LPD</DT>
+<DD>Line Printer Daemon</DD>
+<DT>MIME</DT>
+<DD>Multimedia Internet Mail Exchange</DD>
+<DT>PPD</DT>
+<DD>PostScript Printer Description</DD>
+<DT>SMB</DT>
+<DD>Server Message Block</DD>
+<DT>TFTP</DT>
+<DD>Trivial File Transfer Protocol</DD>
+</DL>
+</BODY>
+</HTML>
diff --git a/doc/stp.pdf b/doc/stp.pdf
new file mode 100644
index 000000000..85bf0f988
--- /dev/null
+++ b/doc/stp.pdf
Binary files differ
diff --git a/doc/stp.shtml b/doc/stp.shtml
new file mode 100644
index 000000000..ebd4a85fc
--- /dev/null
+++ b/doc/stp.shtml
@@ -0,0 +1,144 @@
+<HTML>
+<HEAD>
+ <META NAME="Description" CONTENT="Common UNIX Printing System Software Test Plan">
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-STP-1.1">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Software Test Plan</TITLE>
+</HEAD>
+<BODY>
+
+<H1>Scope</H1>
+
+<H2>Identification</H2>
+
+<P>This software test plan provides detailed tests that are used
+to evaluate the stability and compliance of the Common UNIX
+Printing System ("CUPS") Version 1.1.
+
+<EMBED SRC="system-overview.shtml">
+
+<H2>Document Overview</H2>
+
+<P>This software test plan is organized into the following sections:
+
+<UL>
+ <LI>1 - Scope</LI>
+ <LI>2 - References</LI>
+ <LI>3 - Test Procedure</LI>
+ <LI>4 - IPP Compliance Tests</LI>
+ <LI>5 - Command Tests</LI>
+ <LI>A - Glossary</LI>
+</UL>
+
+<EMBED SRC="references.shtml">
+
+<H1>Test Procedure</H1>
+
+<P>The test software and data files are located in the <VAR>test</VAR>
+subdirectory of the source distribution. A script is provided to compile
+the <CODE>ipptest</CODE> program and run all of the tests that follow,
+producing a success/fail report.
+
+<P>The <CODE>test</CODE> target of the top-level makefile can be used to
+run this script:
+
+<UL><PRE>
+make test
+</PRE></UL>
+
+<P>or you can run the test script directly:
+
+<UL><PRE>
+cd test
+./run-stp-tests
+</PRE></UL>
+
+<P>A Software Test Report is stored in HTML and PDF files that
+are generated using the
+<A HREF="http://www.easysw.com/htmldoc">HTMLDOC</A> software.
+
+<H1>IPP Compliance Tests</H1>
+
+<P>This section describes the tests used to validate the IPP
+standards compliance of the CUPS server.
+
+<H2>Request Tests</H2>
+
+<P>These tests verify that the CUPS scheduler only accepts valid
+IPP requests that start with the <CODE>attributes-charset</CODE>
+and <CODE>attributes-natural-language</CODE> attributes and also
+contain a <CODE>printer-uri</CODE> or <CODE>job-uri</CODE> attribute.
+
+<P>It also verifies that the CUPS scheduler always responds with
+<CODE>attributes-charset</CODE> and
+<CODE>attributes-natural-language</CODE> attributes, using
+default values if they are not provided by the client.
+
+<H2>CUPS Printer Operation Tests</H2>
+
+<P>These tests verify that the CUPS printer operations are supported
+and function properly. Two printers called <CODE>Test1</CODE> and
+<CODE>Test2</CODE> are created, one as a PostScript printer and one
+as a raster printer.
+
+<H2>Job Operation Tests</H2>
+
+<P>These test verify that the CUPS scheduler accepts print jobs for
+all supported file formats and that the <CODE>cancel-job</CODE>,
+<CODE>hold-job</CODE>, and <CODE>resume-job</CODE> operations work.
+
+<H1>Command Tests</H1>
+
+<P>This section describes the tests used to validate the
+Berkeley and System V commands included with CUPS.
+
+<H2>lpadmin</H2>
+
+<P>This test verifies that printers can be added, modified, and
+defaulted using the <CODE>lpadmin</CODE> command.
+
+<H2>lpc</H2>
+
+<P>This test verifies that the <CODE>lpc</CODE> command can show
+the current status of all print queues.
+
+<H2>lpq</H2>
+
+<P>This test verifies that the <CODE>lpq</CODE> command lists
+any jobs in the queue.
+
+<H2>lpstat</H2>
+
+<P>This test verifies that the <CODE>lpstat</CODE> command works
+with all reports using the "<CODE>-t</CODE>" option.
+
+<H2>lp</H2>
+
+<P>This test verifies that the <CODE>lp</CODE> command works
+with both the default destination and a specific destination.
+
+<H2>lpr</H2>
+
+<P>This test verifies that the <CODE>lpr</CODE> command works
+with both the default destination and a specific destination.
+
+<H2>lprm</H2>
+
+<P>This test verifies that the <CODE>lprm</CODE> command can
+properly cancel a job.
+
+<H2>cancel</H2>
+
+<P>This test verifies that the <CODE>cancel</CODE> command can
+properly cancel a job or all jobs.
+
+<H2>lpinfo</H2>
+
+<P>This test verifies that the <CODE>lpinfo</CODE> command
+returns a list of available printer drivers and devices.
+
+<EMBED SRC="glossary.shtml">
+
+</BODY>
+</HTML>
diff --git a/doc/sum.html b/doc/sum.html
new file mode 100644
index 000000000..c653d58c3
--- /dev/null
+++ b/doc/sum.html
@@ -0,0 +1,1732 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Software Users Manual</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-SUM-1.1.16">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY BGCOLOR="#ffffff">
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Software Users Manual</H1></A><BR>
+CUPS-SUM-1.1.16<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">Preface</A></B>
+<UL>
+<LI><A HREF="#1_1">System Overview</A></LI>
+<LI><A HREF="#1_2">Document Overview</A></LI>
+<LI><A HREF="#1_3">Notation Conventions</A></LI>
+<LI><A HREF="#1_4">Abbreviations</A></LI>
+<LI><A HREF="#1_5">Other References</A></LI>
+</UL>
+<B><A HREF="#OVERVIEW">1 - Printing System Overview</A></B>
+<UL>
+<LI><A HREF="#2_1">The Printing Problem</A></LI>
+<LI><A HREF="#2_2">The Technology</A></LI>
+<LI><A HREF="#2_3">Jobs</A></LI>
+<LI><A HREF="#2_4">Classes</A></LI>
+<LI><A HREF="#2_5">Filters</A></LI>
+<LI><A HREF="#2_6">Backends</A></LI>
+<LI><A HREF="#2_7">Printer Drivers</A></LI>
+<LI><A HREF="#2_8">Networking</A></LI>
+</UL>
+<B><A HREF="#USING_SYSTEM">2 - Using the Printing System</A></B>
+<UL>
+<LI><A HREF="#3_1">Submitting Files for Printing</A></LI>
+<LI><A HREF="#3_2">Choosing a Printer</A></LI>
+<LI><A HREF="#3_3">Setting Printer Options</A></LI>
+<LI><A HREF="#3_4">Printing Multiple Copies</A></LI>
+<LI><A HREF="#3_5">Checking the Printer Status from the Command-Line</A></LI>
+<LI><A HREF="#3_6">Checking the Printer Status from the Web</A></LI>
+<LI><A HREF="#3_7">Canceling a Print Job</A></LI>
+</UL>
+<B><A HREF="#STANDARD_OPTIONS">3 - Standard Printer Options</A></B>
+<UL>
+<LI><A HREF="#4_1">General Options</A></LI>
+<UL>
+<LI><A HREF="#4_1_1">Selecting the Media Size, Type, and Source</A></LI>
+<LI><A HREF="#4_1_2">Setting the Orientation</A></LI>
+<LI><A HREF="#4_1_3">Printing On Both Sides of the Paper</A></LI>
+</UL>
+<LI><A HREF="#4_2">Banner Options</A></LI>
+<UL>
+<LI><A HREF="#4_2_1">Selecting the Banner Page(s)</A></LI>
+</UL>
+<LI><A HREF="#4_3">Document Options</A></LI>
+<UL>
+<LI><A HREF="#4_3_1">Selecting a Range of Pages</A></LI>
+<LI><A HREF="#4_3_2">Selecting Even or Odd Pages</A></LI>
+<LI><A HREF="#4_3_3">N-Up Printing</A></LI>
+<LI><A HREF="#4_3_4">Setting the Brightness</A></LI>
+<LI><A HREF="#4_3_5">Setting the Gamma Correction</A></LI>
+</UL>
+<LI><A HREF="#4_4">Text Options</A></LI>
+<UL>
+<LI><A HREF="#4_4_1">Setting the Number of Characters Per Inch</A></LI>
+<LI><A HREF="#4_4_2">Setting the Number of Lines Per Inch</A></LI>
+<LI><A HREF="#4_4_3">Setting the Number of Columns</A></LI>
+<LI><A HREF="#4_4_4">Setting the Page Margins</A></LI>
+<LI><A HREF="#4_4_5">Pretty Printing</A></LI>
+</UL>
+<LI><A HREF="#4_5">Image Options</A></LI>
+<UL>
+<LI><A HREF="#4_5_1">Positioning the Image</A></LI>
+<LI><A HREF="#4_5_2">Scaling the Image</A></LI>
+<LI><A HREF="#4_5_3">Adjusting the Hue (Tint) of an Image</A></LI>
+<LI><A HREF="#4_5_4">Adjusting the Saturation (Color) of an Image</A></LI>
+</UL>
+<LI><A HREF="#4_6">HP-GL/2 Options</A></LI>
+<UL>
+<LI><A HREF="#4_6_1">Printing in Black</A></LI>
+<LI><A HREF="#4_6_2">Fitting the Plot on the Page</A></LI>
+<LI><A HREF="#4_6_3">Setting the Default Pen Width</A></LI>
+</UL>
+<LI><A HREF="#4_7">Raw or Unfiltered Output</A></LI>
+</UL>
+<B><A HREF="#SAVING_OPTIONS">4 - Saving Printer Options and Defaults</A></B>
+<UL>
+<LI><A HREF="#5_1">Printer Options</A></LI>
+<LI><A HREF="#5_2">Setting Options for a Specific Printer</A></LI>
+<LI><A HREF="#5_3">Removing Options</A></LI>
+<LI><A HREF="#5_4">Viewing the Current Defaults</A></LI>
+<LI><A HREF="#5_5">Viewing Options for a Specific Printer</A></LI>
+<LI><A HREF="#5_6">Setting the Default Printer</A></LI>
+<LI><A HREF="#5_7">Printer Instances</A></LI>
+<LI><A HREF="#5_8">Removing Instances</A></LI>
+</UL>
+<B><A HREF="#LICENSE">A - Software License Agreement</A></B>
+<UL>
+<LI><A HREF="#6_1">Common UNIX Printing System License Agreement</A></LI>
+<UL>
+<LI><A HREF="#6_1_1">Introduction</A></LI>
+<LI><A HREF="#6_1_2">License Exceptions</A></LI>
+<LI><A HREF="#6_1_3">Trademarks</A></LI>
+<LI><A HREF="#6_1_4">Binary Distribution Rights</A></LI>
+<LI><A HREF="#6_1_5">Support</A></LI>
+</UL>
+<LI><A HREF="#6_2">GNU GENERAL PUBLIC LICENSE</A></LI>
+<LI><A HREF="#6_3">GNU LIBRARY GENERAL PUBLIC LICENSE</A></LI>
+</UL>
+<HR>
+<H1 ALIGN="RIGHT"><A NAME="1">Preface</A></H1>
+<P>This software users manual describes how to use the Common UNIX
+ Printing System<SUP>TM</SUP> (&quot;CUPS<SUP>TM</SUP>&quot;) Version 1.1.16.</P>
+<H2><A NAME="1_1">System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+
+<!-- NEED 2in -->
+<H2><A NAME="1_2">Document Overview</A></H2>
+<P>This software users manual is organized into the following sections:</P>
+<UL>
+<LI><A HREF="#OVERVIEW">1 - Printing System Overview</A></LI>
+<LI><A HREF="#USING_SYSTEM">2 - Using the Printing System</A></LI>
+<LI><A HREF="#STANDARD_OPTIONS">3 - Standard Printer Options</A></LI>
+<LI><A HREF="#SAVING_OPTIONS">4 - Saving Printer Options and Defaults</A>
+</LI>
+<LI><A HREF="#LICENSE">A - Software License Agreement</A></LI>
+</UL>
+<H2><A NAME="1_3">Notation Conventions</A></H2>
+<P>Various font and syntax conventions are used in this guide. Examples
+ and their meanings and uses are explained below:
+<CENTER>
+<TABLE WIDTH="80%">
+<TR><TH>Example</TH><TD>&nbsp;&nbsp;&nbsp;</TD><TH>Description</TH></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD><CODE>lpstat</CODE>
+<BR> <CODE>lpstat(1)</CODE></TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>The names of commands;
+ the first mention of a command or function in a chapter is followed by
+ a manual page section number.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD><VAR>/var</VAR>
+<BR><VAR> /usr/share/cups/data/testprint.ps</VAR></TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>
+File and directory names.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD NOWRAP><TT>Request ID is Printer-123</TT></TD><TD>
+&nbsp;&nbsp;&nbsp;</TD><TD>Screen output.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD NOWRAP><KBD>lp -d printer filename ENTER</KBD></TD><TD>
+&nbsp;&nbsp;&nbsp;</TD><TD>Literal user input; special keys like <KBD>ENTER</KBD> are
+ in ALL CAPS.</TD></TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP"><TD>12.3</TD><TD>&nbsp;&nbsp;&nbsp;</TD><TD>Numbers in the text are
+ written using the period (.) to indicate the decimal point.</TD></TR>
+</TABLE>
+</CENTER>
+
+<!-- NEED 3in -->
+</P>
+<H2><A NAME="1_4">Abbreviations</A></H2>
+ The following abbreviations are used throughout this manual:
+<UL>
+<DL>
+<DT>kb</DT>
+<DD>Kilobytes, or 1024 bytes
+<BR>&nbsp;</DD>
+<DT>Mb</DT>
+<DD>Megabytes, or 1048576 bytes
+<BR>&nbsp;</DD>
+<DT>Gb</DT>
+<DD>Gigabytes, or 1073741824 bytes
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H2><A NAME="1_5">Other References</A></H2>
+<UL>
+<DL>
+<DT>CUPS Software Administrators Manual</DT>
+<DD>An administration guide for the CUPS software.
+<BR>&nbsp;</DD>
+<DT>CUPS Software Programmers Manual</DT>
+<DD>A programmer guide for interfacing with and/or extending the CUPS
+ software.
+<BR>&nbsp;</DD>
+</DL>
+</UL>
+<H1 ALIGN="RIGHT"><A NAME="OVERVIEW">1 - Printing System Overview</A></H1>
+<P>This chapter provides an overview of how the Common UNIX Printing
+ System works.</P>
+<H2><A NAME="2_1">The Printing Problem</A></H2>
+<P>For years<I> the printing problem</I> has plagued UNIX. Unlike
+ Microsoft&reg; Windows&reg; or Mac OS, UNIX has no standard interface or system
+ in place for supporting printers. Among the solutions currently
+ available, the Berkeley and System V printing systems are the most
+ prevalent.</P>
+<P>These printing systems support line printers (text only) or
+ PostScript printers (text and graphics), and with some coaxing they can
+ be made to support a full range of printers and file formats. However,
+ because each varient of the UNIX operating system uses a different
+ printing system than the next developing printer drivers for a wide
+ range of printers and operating systems is extremely difficult. That
+ combined with the limited volume of customers for each UNIX varient has
+ forced most printer vendors to give up supporting UNIX entirely.</P>
+<P>CUPS is designed to eliminate<I> the printing problem</I>. One common
+ printing system can be used by all UNIX varients to support the
+ printing needs of users. Printer vendors can use its modular filter
+ interface to develop a single driver program that supports a wide range
+ of file formats with little or no effort. Since CUPS provides both the
+ System V and Berkeley printing commands, users (and applications) can
+ reap the benefits of this new technology with no changes.</P>
+<H2><A NAME="2_2">The Technology</A></H2>
+<P>CUPS is based upon an emerging Internet standard called the Internet
+ Printing Protocol. IPP has been embraced by dozens of printer and
+ printer server manufacturers and is supported by Microsoft Windows
+ 2000.</P>
+<P>IPP defines a standard protocol for printing as well as managing
+ print jobs and printer options like media size, resolution, and so
+ forth. Like all IP-based protocols, IPP can be used locally or over the
+ Internet to printers hundreds or thousands of miles away. Unlike other
+ protocols, however, IPP also supports access control, authentication,
+ and encryption, making it a much more capable and secure printing
+ solution than older ones.</P>
+<P>IPP is layered on top of the Hyper-Text Transport Protocol (&quot;HTTP&quot;)
+ which is the basis of web servers on the Internet. This allows users to
+ view documentation, check status information on a printer or server,
+ and manage their printers, classes, and jobs using their web browser.</P>
+<P>CUPS provides a complete IPP/1.1 based printing system that provides
+ Basic, Digest, and local certificate authentication and user, domain,
+ or IP-based access control. TLS encryption will be available in future
+ versions of CUPS.</P>
+<H2><A NAME="2_3">Jobs</A></H2>
+<P>Each file or set of files that is submitted for printing is called a<I>
+ job</I>. Jobs are identified by a unique number starting at 1 and are
+ assigned to a particular destination, usually a printer. Jobs can also
+ have options associated with them such as media size, number of copies,
+ and priority.</P>
+<H2><A NAME="2_4">Classes</A></H2>
+<P>CUPS supports collections of printers known as<I> classes</I>. Jobs
+ sent to a class are forwarded to the first available printer in the
+ class.</P>
+<H2><A NAME="2_5">Filters</A></H2>
+<P>Filters allow a user or application to print many types of files
+ without extra effort. Print jobs sent to a CUPS server are filtered
+ before sending them to a printer. Some filters convert job files to
+ different formats that the printer can understand. Others perform page
+ selection and ordering tasks.</P>
+<P>CUPS provides filters for printing many types of image files, HP-GL/2
+ files, PDF files, and text files. CUPS also supplies PostScript and
+ image file Raster Image Processor (&quot;RIP&quot;) filters that convert
+ PostScript or image files into bitmaps that can be sent to a raster
+ printer.</P>
+<H2><A NAME="2_6">Backends</A></H2>
+<P>Backends perform the most important task of all - they send the
+ filtered print data to the printer.</P>
+<P>CUPS provides backends for printing over parallel, serial, and USB
+ ports, and over the network via the IPP, JetDirect (AppSocket), and
+ Line Printer Daemon (&quot;LPD&quot;) protocols. Additional backends are
+ available in network service packages such as the SMB backend included
+ with the popular SAMBA software.</P>
+<P>Backends are also used to determine the available devices. On startup
+ each backend is asked for a list of devices it supports, and any
+ information that is available. This allows the parallel backend to tell
+ CUPS that an EPSON Stylus Color 600 printer is attached to parallel
+ port 1, for example.</P>
+<H2><A NAME="2_7">Printer Drivers</A></H2>
+<P>Printer drivers in CUPS consist of one of more filters specific to a
+ printer. CUPS includes sample printer drivers for Hewlett-Packard
+ LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color,
+ and Stylus Photo printers. While these drivers do not generate optimal
+ output for the different printer models, they do provide basic printing
+ and demonstrate how you can write your own printer drivers and
+ incorporate them into CUPS.</P>
+<H2><A NAME="2_8">Networking</A></H2>
+<P>Printers and classes on the local system are automatically shared
+ with other systems on the network. This allows you to setup one system
+ to print to a printer and use this system as a printer server or spool
+ host for all of the others. Users may then select a local printer by
+ name or a remote printer using &quot;name@server&quot;.</P>
+<P>CUPS also provides<I> implicit classes</I>, which are collections of
+ printers and/or classes with the same name. This allows you to setup
+ multiple servers pointing to the same physical network printer, for
+ example, so that you aren't relying on a single system for printing.
+ Because this also works with printer classes, you can setup multiple
+ servers and printers and never worry about a single point of failure
+ unless all of the printers and servers go down!</P>
+<H1 ALIGN="RIGHT"><A NAME="USING_SYSTEM">2 - Using the Printing System</A>
+</H1>
+<P>This chapter shows you how to submit, query, and cancel print jobs to
+ different printers.</P>
+<H2><A NAME="3_1">Submitting Files for Printing</A></H2>
+<P>CUPS provides both the System V (<CODE>lp(1)</CODE>) and Berkeley (<CODE>
+lpr(1)</CODE>) printing commands. Type the following command to print a
+ file to the default (or only) printer on the system:</P>
+<UL>
+<PRE>
+<B>lp filename ENTER</B>
+</PRE>
+</UL>
+<P>or:</P>
+<UL>
+<PRE>
+<B>lpr filename ENTER</B>
+</PRE>
+</UL>
+<P>CUPS understands many different types of files directly, including
+ PostScript and image files. This allows you to print from inside your
+ applications or at the command-line, whichever is most convenient!</P>
+<H2><A NAME="3_2">Choosing a Printer</A></H2>
+<P>Many systems will have more than one printer available to the user.
+ These printers can be attached to the local system via a parallel,
+ serial, or USB port, or available over the network.</P>
+<P>Use the <CODE>lpstat(1)</CODE> command to see a list of available
+ printers:</P>
+<UL>
+<PRE>
+<B>lpstat -p -d ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>-p</CODE> option specifies that you want to see a list of
+ printers, and the <CODE>-d</CODE> option reports the current default
+ printer or class.</P>
+<P>Use the <CODE>-d</CODE> option with the <CODE>lp</CODE> command to
+ print to a specific printer:</P>
+<UL>
+<PRE>
+<B>lp -d printer filename ENTER</B>
+</PRE>
+</UL>
+<P>or the <CODE>-P</CODE> option with the <CODE>lpr</CODE> command:</P>
+<UL>
+<PRE>
+<B>lpr -P printer filename ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="3_3">Setting Printer Options</A></H2>
+<P>For many types of files, the default printer options may be
+ sufficient for your needs. However, there may be times when you need to
+ change the options for a particular file you are printing.</P>
+<P>The <CODE>lp</CODE> and <CODE>lpr</CODE> commands allow you to pass
+ printer options using the <CODE>-o</CODE> option:</P>
+<UL>
+<PRE>
+<B>lp -o landscape -o scaling=75 -o media=A4 filename.jpg
+<B>lpr -o landscape -o scaling=75 -o media=A4 filename.jpg
+</B></B></PRE>
+</UL>
+<P>The available printer options vary depending on the printer. The
+ standard options are described in<A HREF="#STANDARD_OPTIONS"> Chapter
+ 3, &quot;Standard Printing Options&quot;</A>.</P>
+<H2><A NAME="3_4">Printing Multiple Copies</A></H2>
+<P>Both the <CODE>lp</CODE> and <CODE>lpr</CODE> commands have options
+ for printing more than one copy of a file:</P>
+<UL>
+<PRE>
+<B>lp -n <I>num-copies</I> filename ENTER</B>
+<B>lpr -#<I>num-copies</I> filename ENTER</B>
+</PRE>
+</UL>
+<P>Copies are normally<I> not</I> collated for you. Use the <CODE>-o
+ Collate=True</CODE> option to get collated copies :</P>
+<UL>
+<PRE>
+<B>lp -n <I>num-copies</I> -o Collate=True filename ENTER</B>
+<B>lpr -#<I>num-copies</I> -o Collate=True filename ENTER</B>
+</PRE>
+</UL>
+
+<!-- NEED 3in -->
+<H2><A NAME="3_5">Checking the Printer Status from the Command-Line</A></H2>
+<P>The <CODE>lpstat</CODE> command can be used to check for jobs that
+ you have submitted for printing:</P>
+<UL>
+<PRE>
+<B>lpstat ENTER</B>
+Printer-1 johndoe 4427776
+Printer-2 johndoe 15786
+Printer-3 johndoe 372842
+</PRE>
+</UL>
+<P>The jobs are listed in the order they will be printed. Use the <CODE>
+-p</CODE> option to see which files and printers are active:</P>
+<UL>
+<PRE>
+<B>lpstat -p ENTER</B>
+printer DeskJet now printing DeskJet-1.
+</PRE>
+</UL>
+
+<!-- NEED 2in -->
+<P>Use the <CODE>-o</CODE> and <CODE>-p</CODE> options together to show
+ the jobs and the printers:</P>
+<UL>
+<PRE>
+<B>lpstat -o -p ENTER</B>
+Printer-1 johndoe 4427776
+Printer-2 johndoe 15786
+Printer-3 johndoe 372842
+printer DeskJet now printing DeskJet-1.
+</PRE>
+</UL>
+<H2><A NAME="3_6">Checking the Printer Status from the Web</A></H2>
+<P>Since CUPS uses the Internet Printing Protocol, it is also a
+ fully-functional web server. To use your web browser to monitor the
+ printers on your system, open the URL:</P>
+<UL>
+<PRE>
+<A HREF="http://localhost:631">http://localhost:631</A>
+</PRE>
+</UL>
+<P>From there you can view the status of classes, jobs, and printers
+ with the click of a button!</P>
+<H2><A NAME="3_7">Canceling a Print Job</A></H2>
+<P>The <CODE>cancel(1)</CODE> and <CODE>lprm(1)</CODE> commands cancel a
+ print job:</P>
+<UL>
+<PRE>
+<B>cancel <I>job-id</I> ENTER</B>
+<B>lprm <I>job-id</I> ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>job-id</CODE> is the number that was reported to you by the
+ <CODE>lp</CODE> or <CODE>lpstat</CODE> commands.</P>
+<H1 ALIGN="RIGHT"><A NAME="STANDARD_OPTIONS">3 - Standard Printer
+ Options</A></H1>
+<P>This chapter describes the standard printer options that are
+ available when printing with the <CODE>lp</CODE> and <CODE>lpr</CODE>
+ commands.</P>
+<H2><A NAME="4_1">General Options</A></H2>
+<P>The following options apply when printing all types of files.
+<!-- NEED 2in -->
+</P>
+<H3><A NAME="4_1_1">Selecting the Media Size, Type, and Source</A></H3>
+<P>The <CODE>-o media=xyz</CODE> option sets the media size, type,
+ and/or source:</P>
+<UL>
+<PRE>
+<B>lp -o media=Letter filename ENTER</B>
+<B>lp -o media=Letter,MultiPurpose filename ENTER</B>
+<B>lpr -o media=Letter,Transparency filename ENTER</B>
+<B>lpr -o media=Letter,MultiPurpose,Transparency filename ENTER</B>
+</PRE>
+</UL>
+
+<!-- NEED 3in -->
+<P>The available media sizes, types, and sources depend on the printer,
+ but most support the following options (case is not significant):</P>
+<UL>
+<LI><CODE>Letter</CODE> - US Letter (8.5x11 inches, or 216x279mm)</LI>
+<LI><CODE>Legal</CODE> - US Legal (8.5x14 inches, or 216x356mm)</LI>
+<LI><CODE>A4</CODE> - ISO A4 (8.27x11.69 inches, or 210x297mm)</LI>
+<LI><CODE>COM10</CODE> - US #10 Envelope (9.5x4.125 inches, or
+ 241x105mm)</LI>
+<LI><CODE>DL</CODE> - ISO DL Envelope (8.66x4.33 inches, or 220x110mm)</LI>
+<LI><CODE>Transparency</CODE> - Transparency media type or source</LI>
+<LI><CODE>Upper</CODE> - Upper paper tray</LI>
+<LI><CODE>Lower</CODE> - Lower paper tray</LI>
+<LI><CODE>MultiPurpose</CODE> - Multi-purpose paper tray</LI>
+<LI><CODE>LargeCapacity</CODE> - Large capacity paper tray</LI>
+</UL>
+<P>The actual options supported are defined in the printer's PPD file in
+ the <CODE>PageSize</CODE>, <CODE>InputSlot</CODE>, and <CODE>MediaType</CODE>
+ options.</P>
+<H3><A NAME="4_1_2">Setting the Orientation</A></H3>
+<P>The <CODE>-o landscape</CODE> option will rotate the page 90 degrees
+ to print in landscape orientation:</P>
+<UL>
+<PRE>
+<B>lp -o landscape filename ENTER</B>
+<B>lpr -o landscape filename ENTER</B>
+</PRE>
+</UL>
+<H3><A NAME="4_1_3">Printing On Both Sides of the Paper</A></H3>
+<P>The <CODE>-o sides=two-sided-short-edge</CODE> and <CODE>-o
+ sides=two-sided-long-edge</CODE> options will enable duplexing on the
+ printer, if the printer supports it. The <CODE>-o
+ sides=two-sided-short-edge</CODE> option is suitable for landscape
+ pages, while the <CODE>-o sides=two-sided-long-edge</CODE> option is
+ suitable for portrait pages:</P>
+<UL>
+<PRE>
+<B>lp -o sides=two-sided-short-edge filename ENTER</B>
+<B>lp -o sides=two-sided-long-edge filename ENTER</B>
+<B>lpr -o sides=two-sided-long-edge filename ENTER</B>
+</PRE>
+</UL>
+<P>The default is to print single-sided:</P>
+<UL>
+<PRE>
+<B>lp -o sides=one-sided filename ENTER</B>
+<B>lpr -o sides=one-sided filename ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="4_2">Banner Options</A></H2>
+<P>The following options apply when printing all types of files.</P>
+<H3><A NAME="4_2_1">Selecting the Banner Page(s)</A></H3>
+<P>The <CODE>-o jobsheets=start,end</CODE> option sets the banner
+ page(s) to use for a job:</P>
+<UL>
+<PRE>
+<B>lp -o job-sheets=none filename ENTER</B>
+<B>lp -o job-sheets=standard filename ENTER</B>
+<B>lpr -o job-sheets=classified,classified filename ENTER</B>
+</PRE>
+</UL>
+<P>If only one banner file is specified, it will be printed before the
+ files in the job. If a second banner file is specified, it is printed
+ after the files in the job.</P>
+<P>The available banner pages depend on the local system configuration;
+ CUPS includes the following banner files:</P>
+<UL>
+<LI><CODE>none</CODE> - Do not produce a banner page.</LI>
+<LI><CODE>classified</CODE> - A banner page with a &quot;classified&quot; label at
+ the top and bottom.</LI>
+<LI><CODE>confidential</CODE> - A banner page with a &quot;confidential&quot;
+ label at the top and bottom.</LI>
+<LI><CODE>secret</CODE> - A banner page with a &quot;secret&quot; label at the top
+ and bottom.</LI>
+<LI><CODE>standard</CODE> - A banner page with no label at the top and
+ bottom.</LI>
+<LI><CODE>topsecret</CODE> - A banner page with a &quot;top secret&quot; label at
+ the top and bottom.</LI>
+<LI><CODE>unclassified</CODE> - A banner page with an &quot;unclassified&quot;
+ label at the top and bottom.</LI>
+</UL>
+<H2><A NAME="4_3">Document Options</A></H2>
+<P>The following options apply when printing all types of files.</P>
+<H3><A NAME="4_3_1">Selecting a Range of Pages</A></H3>
+<P>The <CODE>-o page-ranges=pages</CODE> option selects a range of pages
+ for printing:</P>
+<UL>
+<PRE>
+<B>lp -o page-ranges=1 filename ENTER</B>
+<B>lp -o page-ranges=1-4 filename ENTER</B>
+<B>lp -o page-ranges=1-4,7,9-12 filename ENTER</B>
+<B>lpr -o page-ranges=1-4,7,9-12 filename ENTER</B>
+</PRE>
+</UL>
+<P>As shown above, the <CODE>pages</CODE> value can be a single page, a
+ range of pages, or a collection of page numbers and ranges separated by
+ commas. The pages will always be printed in ascending order, regardless
+ of the order of the pages in the <CODE>page-ranges</CODE> option.</P>
+<P>The default is to print all pages.</P>
+<H3><A NAME="4_3_2">Selecting Even or Odd Pages</A></H3>
+<P>Use the <CODE>-o page-set=set</CODE> option to select the even or odd
+ pages:</P>
+<UL>
+<PRE>
+<B>lp -o page-set=odd filename ENTER</B>
+<B>lp -o page-set=even filename ENTER</B>
+<B>lpr -o page-set=even filename ENTER</B>
+</PRE>
+</UL>
+<P>The default is to print all pages.</P>
+<H3><A NAME="4_3_3">N-Up Printing</A></H3>
+<P>The <CODE>-o number-up=value</CODE> option selects N-Up printing.
+ N-Up printing places multiple document pages on a single printed page.
+ CUPS supports 1, 2, 4, 6, 9, and 16-Up formats; the default format is
+ 1-Up:</P>
+<UL>
+<PRE>
+<B>lp -o number-up=1 filename ENTER</B>
+<B>lp -o number-up=2 filename ENTER</B>
+<B>lp -o number-up=4 filename ENTER</B>
+<B>lpr -o number-up=16 filename ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>-o page-border=value</CODE> option chooses the border to
+ draw around each page:</P>
+<UL>
+<LI><CODE>-o page-border=double</CODE>; draw two hairline borders around
+ each page</LI>
+<LI><CODE>-o page-border=double-thick</CODE>; draw two 1pt borders
+ around each page</LI>
+<LI><CODE>-o page-border=none</CODE>; do not draw a border (default)</LI>
+<LI><CODE>-o page-border=single</CODE>; draw one hairline border around
+ each page</LI>
+<LI><CODE>-o page-border=single-thick</CODE>; draw one 1pt border around
+ each page</LI>
+</UL>
+<P>The <CODE>-o number-up-layout=value</CODE> option chooses the layout
+ of the pages on each output page:</P>
+<UL>
+<LI><CODE>-o number-up-layout=btlr</CODE>; Bottom to top, left to right</LI>
+<LI><CODE>-o number-up-layout=btrl</CODE>; Bottom to top, right to left</LI>
+<LI><CODE>-o number-up-layout=lrbt</CODE>; Left to right, bottom to top</LI>
+<LI><CODE>-o number-up-layout=lrtb</CODE>; Left to right, top to bottom
+ (default)</LI>
+<LI><CODE>-o number-up-layout=rlbt</CODE>; Right to left, bottom to top</LI>
+<LI><CODE>-o number-up-layout=rltb</CODE>; Right to left, top to bottom</LI>
+<LI><CODE>-o number-up-layout=tblr</CODE>; Top to bottom, left to right</LI>
+<LI><CODE>-o number-up-layout=tbrl</CODE>; Top to bottom, right to left</LI>
+</UL>
+<H3><A NAME="4_3_4">Setting the Brightness</A></H3>
+<P>You can control the overall brightness of the printed output using
+ the <CODE>-o brightness=percent</CODE> option:</P>
+<UL>
+<PRE>
+<B>lp -o brightness=120 filename ENTER</B>
+<B>lpr -o brightness=120 filename ENTER</B>
+</PRE>
+</UL>
+<P>Values greater than 100 will lighten the print, while values less
+ than 100 will darken it.</P>
+<H3><A NAME="4_3_5">Setting the Gamma Correction</A></H3>
+<P>You can control the overall gamma correction of the printed output
+ using the <CODE>-o gamma=value</CODE> option:</P>
+<UL>
+<PRE>
+<B>lp -o gamma=1700 filename ENTER</B>
+<B>lpr -o gamma=1700 filename ENTER</B>
+</PRE>
+</UL>
+<P>Values greater than 1000 will lighten the print, while values less
+ than 1000 will darken it. The default gamma is 1000.</P>
+<H2><A NAME="4_4">Text Options</A></H2>
+<P>The following options apply when printing text files.</P>
+<H3><A NAME="4_4_1">Setting the Number of Characters Per Inch</A></H3>
+<P>The <CODE>-o cpi=value</CODE> option sets the number of characters
+ per inch:</P>
+<UL>
+<PRE>
+<B>lp -o cpi=10 filename ENTER</B>
+<B>lp -o cpi=12 filename ENTER</B>
+<B>lpr -o cpi=17 filename ENTER</B>
+</PRE>
+</UL>
+<P>The default characters per inch is 10.</P>
+<H3><A NAME="4_4_2">Setting the Number of Lines Per Inch</A></H3>
+<P>The <CODE>-o lpi=value</CODE> option sets the number of lines per
+ inch:</P>
+<UL>
+<PRE>
+<B>lp -o lpi=6 filename ENTER</B>
+<B>lpr -o lpi=8 filename ENTER</B>
+</PRE>
+</UL>
+<P>The default lines per inch is 6.</P>
+<H3><A NAME="4_4_3">Setting the Number of Columns</A></H3>
+<P>The <CODE>-o columns=value</CODE> option sets the number of text
+ columns:</P>
+<UL>
+<PRE>
+<B>lp -o columns=2 filename ENTER</B>
+<B>lpr -o columns=3 filename ENTER</B>
+</PRE>
+</UL>
+<P>The default number of columns is 1.</P>
+<H3><A NAME="4_4_4">Setting the Page Margins</A></H3>
+<P>Normally the page margins are set to the hard limits of the printer.
+ Use the <CODE>-o page-left=value</CODE>, <CODE>-o page-right=value</CODE>
+, <CODE>-o page-top=value</CODE>, and <CODE>-o page-bottom=value</CODE>
+ options to adjust the page margins:</P>
+<UL>
+<PRE>
+<B>lp -o page-left=<I>value</I> filename ENTER</B>
+<B>lp -o page-right=<I>value</I> filename ENTER</B>
+<B>lp -o page-top=<I>value</I> filename ENTER</B>
+<B>lp -o page-bottom=<I>value</I> filename ENTER</B>
+<B>lpr -o page-bottom=<I>value</I> filename ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>value</CODE> argument is the margin in points; each point
+ is 1/72 inch or 0.35mm.</P>
+<H3><A NAME="4_4_5">Pretty Printing</A></H3>
+<P>The <CODE>-o prettyprint</CODE> option puts a header at the top of
+ each page with the page number, job title (usually the filename), and
+ the date. Also, C and C++ keywords are highlighted, and comment lines
+ are italicized:</P>
+<UL>
+<PRE>
+<B>lp -o prettyprint filename ENTER</B>
+<B>lpr -o prettyprint filename ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="4_5">Image Options</A></H2>
+<P>The following options apply when printing image files.</P>
+<H3><A NAME="4_5_1">Positioning the Image</A></H3>
+<P>The <CODE>-o position=name</CODE> option specifies the position of
+ the image on the page:</P>
+<UL>
+<LI><CODE>center</CODE> - Center the image on the page (default)</LI>
+<LI><CODE>top</CODE> - Print the image centered at the top of the page</LI>
+<LI><CODE>left</CODE> - Print the image centered on the left of page</LI>
+<LI><CODE>right</CODE> - Print the image centered on the right of the
+ page</LI>
+<LI><CODE>top-left</CODE> - Print the image at the top left corner of
+ the page</LI>
+<LI><CODE>top-right</CODE> - Print the image at the top right corner of
+ the page</LI>
+<LI><CODE>bottom</CODE> - Print the image centered at the bottom of the
+ page</LI>
+<LI><CODE>bottom-left</CODE> - Print the image at the bottom left corner
+ of the page</LI>
+<LI><CODE>bottom-right</CODE> - Print the image at the bottom right
+ corner of the page</LI>
+</UL>
+<H3><A NAME="4_5_2">Scaling the Image</A></H3>
+<P>The <CODE>-o scaling=percent</CODE>, <CODE>-o ppi=value</CODE>, and <CODE>
+-o natural-scaling=percent</CODE> options change the size of a printed
+ image:</P>
+<UL>
+<PRE>
+<B>lp -o scaling=<I>percent</I> filename ENTER</B>
+<B>lp -o ppi=<I>value</I> filename ENTER</B>
+<B>lpr -o natural-scaling=<I>percent</I> filename ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>scaling=percent</CODE> value is a number from 1 to 800
+ specifying the size in relation to the page (<I>not</I> the image.) A
+ scaling of 100 percent will fill the page as completely as the image
+ aspect ratio allows. A scaling of 200 percent will print on up to 4
+ pages.</P>
+<P>The <CODE>ppi=value</CODE> value is a number from 1 to 1200
+ specifying the resolution of the image in pixels per inch. An image
+ that is 3000x2400 pixels will print 10x8 inches at 300 pixels per inch,
+ for example. If the specified resolution makes the image larger than
+ the page, multiple pages will be printed to satisfy the request.</P>
+<P>The <CODE>natural-scaling=percent</CODE> value is a number from 1 to
+ 800 specifying the size in relation to the natural image size. A
+ scaling of 100 percent will print the image at its natural size, while
+ a scaling of 50 percent will print the image at half its natural size.
+ If the specified scaling makes the image larger than the page, multiple
+ pages will be printed to satisfy the request.</P>
+<H3><A NAME="4_5_3">Adjusting the Hue (Tint) of an Image</A></H3>
+<P>The <CODE>-o hue=value</CODE> option will adjust the hue of the
+ printed image, much like the tint control on your television:</P>
+<UL>
+<PRE>
+<B>lp -o hue=<I>value</I> filename ENTER</B>
+<B>lpr -o hue=<I>value</I> filename ENTER</B>
+</PRE>
+</UL>
+
+<!-- NEED 3in -->
+<P>The <CODE>value</CODE> argument is a number from -360 to 360 and
+ represents the color hue rotation. The following table summarizes the
+ change you'll see with different colors:
+<CENTER>
+<TABLE BORDER="1" WIDTH="50%">
+<TR><TH>Original</TH><TH>hue=-45</TH><TH>hue=45</TH></TR>
+<TR><TD>Red</TD><TD>Purple</TD><TD>Yellow-orange</TD></TR>
+<TR><TD>Green</TD><TD>Yellow-green</TD><TD>Blue-green</TD></TR>
+<TR><TD>Yellow</TD><TD>Orange</TD><TD>Green-yellow</TD></TR>
+<TR><TD>Blue</TD><TD>Sky-blue</TD><TD>Purple</TD></TR>
+<TR><TD>Magenta</TD><TD>Indigo</TD><TD>Crimson</TD></TR>
+<TR><TD>Cyan</TD><TD>Blue-green</TD><TD>Light-navy-blue</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<P>The default hue adjustment is 0.</P>
+<H3><A NAME="4_5_4">Adjusting the Saturation (Color) of an Image</A></H3>
+<P>The <CODE>-o saturation=percent</CODE> option adjusts the saturation
+ of the colors in an image, much like the color knob on your television:</P>
+<UL>
+<PRE>
+<B>lp -o saturation=<I>percent</I> filename ENTER</B>
+<B>lpr -o saturation=<I>percent</I> filename ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>percent</CODE> argument specifies the color saturation from
+ 0 to 200. A color saturation of 0 produces a black-and-white print,
+ while a value of 200 will make the colors extremely intense.</P>
+<P>The default saturation is 100.
+<!-- NEED 4in -->
+</P>
+<H2><A NAME="4_6">HP-GL/2 Options</A></H2>
+<P>The following options apply to HP-GL/2 files.</P>
+<H3><A NAME="4_6_1">Printing in Black</A></H3>
+<P>The <CODE>-o blackplot</CODE> option specifies that all pens should
+ plot in black:</P>
+<UL>
+<PRE>
+<B>lp -o blackplot filename ENTER</B>
+<B>lpr -o blackplot filename ENTER</B>
+</PRE>
+</UL>
+<P>The default is to use the colors defined in the plot file or the
+ standard pen colors defined in the HP-GL/2 reference manual from
+ Hewlett Packard.</P>
+<H3><A NAME="4_6_2">Fitting the Plot on the Page</A></H3>
+<P>The <CODE>-o fitplot</CODE> option specifies that the plot should be
+ scaled to fit on the page:</P>
+<UL>
+<PRE>
+<B>lp -o fitplot filename ENTER</B>
+<B>lpr -o fitplot filename ENTER</B>
+</PRE>
+</UL>
+<P>The default is to use the absolute distances specified in the plot
+ file.
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>This feature depends upon an accurate plot size (<CODE>PS</CODE>)
+ command in the HP-GL/2 file. If no plot size is given in the file than
+ the HP-GL/2 filter assumes the plot is ANSI E size.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="4_6_3">Setting the Default Pen Width</A></H3>
+<P>The <CODE>-o penwidth=value</CODE> option specifies the default pen
+ width for HP-GL/2 files:</P>
+<UL>
+<PRE>
+<B>lp -o penwidth=<I>value</I> filename ENTER</B>
+<B>lpr -o penwidth=<I>value</I> filename ENTER</B>
+</PRE>
+</UL>
+<P>The pen width <CODE>value</CODE> specifies the pen width in
+ micrometers. The default value of 1000 produces lines that are 1
+ millimeter in width. Specifying a pen width of 0 produces lines that
+ are exactly 1 pixel wide.
+<CENTER>
+<TABLE BGCOLOR="#cccccc" BORDER="1" CELLPADDING="5" WIDTH="80%">
+<TR><TD><B> NOTE:</B>
+<P>This option is ignored when the pen widths are set in the plot file.</P>
+</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H2><A NAME="4_7">Raw or Unfiltered Output</A></H2>
+<P>The <CODE>-o raw</CODE> option allows you to send files directly to a
+ printer without filtering. This is sometimes required when printing
+ from applications that provide their own &quot;printer drivers&quot; for your
+ printer:</P>
+<UL>
+<PRE>
+<B>lp -o raw filename ENTER</B>
+<B>lpr -o raw filename ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>-l</CODE> option can also be used with the <CODE>lpr</CODE>
+ command to send files directly to a printer:</P>
+<UL>
+<PRE>
+<B>lpr -l filename ENTER</B>
+</PRE>
+</UL>
+<H1 ALIGN="RIGHT"><A NAME="SAVING_OPTIONS">4 - Saving Printer Options
+ and Defaults</A></H1>
+<P>This chapter describes how to save printer options for your printer
+ and set your own default printer.</P>
+<H2><A NAME="5_1">Printer Options</A></H2>
+<P>Each printer supports a large number of options, which you learned
+ about in<A HREF="#STANDARD_OPTIONS"> Chapter 3, &quot;Standard Printer
+ Options&quot;</A>. Rather than specifying these options each time you print
+ a file, CUPS allows you to save them as &quot;default&quot; options for the
+ printer.</P>
+<P>The <CODE>lpoptions(1)</CODE> command saves the options for your
+ printers. Like the <CODE>lp</CODE> and <CODE>lpr</CODE> commands, it
+ accepts printer options using the <CODE>-o</CODE> argument:</P>
+<UL>
+<PRE>
+<B>lpoptions -o prettyprint ENTER</B>
+<B>lpoptions -o media=A4 -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -o media=Legal -o scaling=100 ENTER</B>
+</PRE>
+</UL>
+<P>Once saved, any <CODE>lp</CODE> or <CODE>lpr</CODE> command will use
+ them when you print.</P>
+<H2><A NAME="5_2">Setting Options for a Specific Printer</A></H2>
+<P>The previous example shows how to set the options for the default
+ printer. The <CODE>-p printer</CODE> option specifies the options are
+ for another printer:</P>
+<UL>
+<PRE>
+<B>lpoptions -p laserjet -o prettyprint ENTER</B>
+<B>lpoptions -p laserjet -o media=A4 -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -p deskjet -o media=Legal -o scaling=100 ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="5_3">Removing Options</A></H2>
+<P>The previous two examples shows how to set options for the default
+ and a specific printer. Below, shows you how to remove the saved option
+ using the <CODE>-r</CODE> argument:</P>
+<UL>
+<PRE>
+<KBD>lpoptions -r prettyprint <I>ENTER</I></KBD>
+<KBD>lpoptions -p laserjet -r prettyprint <I>ENTER</I></KBD>
+</PRE>
+</UL>
+<H2><A NAME="5_4">Viewing the Current Defaults</A></H2>
+<P>The <CODE>lpoptions</CODE> command can also be used to show the
+ current options by not specifying any new options on the command-line:</P>
+<UL>
+<PRE>
+<B>lpoptions ENTER</B>
+media=A4 sides=two-sided-long-edge
+<B>lpoptions -p deskjet ENTER</B>
+media=Legal scaling=100
+</PRE>
+</UL>
+<H2><A NAME="5_5">Viewing Options for a Specific Printer</A></H2>
+<P>You can display the supported options using the <CODE>lpoptions</CODE>
+ command with the <CODE>-l</CODE> option, as follows:</P>
+<UL>
+<PRE>
+<B>lpoptions -p laserjet -l ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="5_6">Setting the Default Printer</A></H2>
+<P>The administrator normally will set a system-wide default printer
+ that is normally used as the default printer by everyone. Use the <CODE>
+-d printer</CODE> option to set your own default printer:</P>
+<UL>
+<PRE>
+<B>lpoptions -d deskjet ENTER</B>
+</PRE>
+</UL>
+<P>The printer can be local (<CODE>deskjet</CODE>) or remote (<CODE>
+deskjet@server</CODE>).</P>
+<H2><A NAME="5_7">Printer Instances</A></H2>
+<P>Besides setting options for each print queue, CUPS supports<I>
+ printer instances</I> which allow you to define several different sets
+ of options for each printer. You specify a printer instance using the
+ slash (<CODE>/</CODE>) character:</P>
+<UL>
+<PRE>
+<B>lpoptions -p laserjet/duplex -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -p laserjet/legal -o media=Legal ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>lp</CODE> and <CODE>lpr</CODE> commands also understand
+ this notation:</P>
+<UL>
+<PRE>
+<B>lp -d laserjet/duplex filename ENTER</B>
+<B>lpr -P laserjet/legal filename ENTER</B>
+</PRE>
+</UL>
+<H2><A NAME="5_8">Removing Instances</A></H2>
+<P>Use the <CODE>-x printer/instance</CODE> option to remove a printer
+ instance that you no longer need:</P>
+<UL>
+<PRE>
+<B>lpoptions -x laserjet ENTER</B>
+<B>lpoptions -x laserjet/duplex ENTER</B>
+<B>lpoptions -x laserjet/legal ENTER</B>
+</PRE>
+</UL>
+<P>The <CODE>-x</CODE> option only removes the default options for that
+ printer and instance; the original print queue will remain until
+ deleted with the <CODE>lpadmin(8)</CODE> command by the administrator.</P>
+<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - Software License Agreement</A></H1>
+<H2 ALIGN="CENTER"><A NAME="6_1">Common UNIX Printing System License
+ Agreement</A></H2>
+<P ALIGN="CENTER">Copyright 1997-2002 by Easy Software Products
+<BR> 44141 AIRPORT VIEW DR STE 204
+<BR> HOLLYWOOD, MARYLAND 20636-3111 USA
+<BR>
+<BR> Voice: +1.301.373.9600
+<BR> Email:<A HREF="mailto:cups-info@cups.org"> cups-info@cups.org</A>
+<BR> WWW:<A HREF="http://www.cups.org"> http://www.cups.org</A></P>
+<H3><A NAME="6_1_1">Introduction</A></H3>
+<P>The Common UNIX Printing System<SUP>TM</SUP>, (&quot;CUPS<SUP>TM</SUP>&quot;),
+ is provided under the GNU General Public License (&quot;GPL&quot;) and GNU
+ Library General Public License (&quot;LGPL&quot;), Version 2, with exceptions for
+ Apple operating systems and the OpenSSL toolkit. A copy of the
+ exceptions and licenses follow this introduction.</P>
+<P>The GNU LGPL applies to the CUPS API library, located in the &quot;cups&quot;
+ subdirectory of the CUPS source distribution and in the &quot;cups&quot; include
+ directory and library files in the binary distributions. The GNU GPL
+ applies to the remainder of the CUPS distribution, including the
+ &quot;pdftops&quot; filter which is based upon Xpdf and the CUPS imaging library.</P>
+<P>For those not familiar with the GNU GPL, the license basically allows
+ you to:</P>
+<UL>
+<LI>Use the CUPS software at no charge.</LI>
+<LI>Distribute verbatim copies of the software in source or binary form.</LI>
+<LI>Sell verbatim copies of the software for a media fee, or sell
+ support for the software.</LI>
+<LI>Distribute or sell printer drivers and filters that use CUPS so long
+ as source code is made available under the GPL.</LI>
+</UL>
+<P>What this license<B> does not</B> allow you to do is make changes or
+ add features to CUPS and then sell a binary distribution without source
+ code. You must provide source for any new drivers, changes, or
+ additions to the software, and all code must be provided under the GPL
+ or LGPL as appropriate. The only exceptions to this are the portions of
+ the CUPS software covered by the Apple operating system license
+ exceptions outlined later in this license agreement.</P>
+<P>The GNU LGPL relaxes the &quot;link-to&quot; restriction, allowing you to
+ develop applications that use the CUPS API library under other licenses
+ and/or conditions as appropriate for your application.</P>
+<H3><A NAME="6_1_2">License Exceptions</A></H3>
+<P>In addition, as the copyright holder of CUPS, Easy Software Products
+ grants the following special exceptions:</P>
+<OL>
+<LI><B>Apple Operating System Development License Exception</B>;
+<OL TYPE="a">
+<LI>Software that is developed by any person or entity for an Apple
+ Operating System (&quot;Apple OS-Developed Software&quot;), including but not
+ limited to Apple and third party printer drivers, filters, and backends
+ for an Apple Operating System, that is linked to the CUPS imaging
+ library or based on any sample filters or backends provided with CUPS
+ shall not be considered to be a derivative work or collective work
+ based on the CUPS program and is exempt from the mandatory source code
+ release clauses of the GNU GPL. You may therefore distribute linked
+ combinations of the CUPS imaging library with Apple OS-Developed
+ Software without releasing the source code of the Apple OS-Developed
+ Software. You may also use sample filters and backends provided with
+ CUPS to develop Apple OS-Developed Software without releasing the
+ source code of the Apple OS-Developed Software.</LI>
+<LI>An Apple Operating System means any operating system software
+ developed and/or marketed by Apple Computer, Inc., including but not
+ limited to all existing releases and versions of Apple's Darwin, Mac OS
+ X, and Mac OS X Server products and all follow-on releases and future
+ versions thereof.</LI>
+<LI>This exception is only available for Apple OS-Developed Software and
+ does not apply to software that is distributed for use on other
+ operating systems.</LI>
+<LI>All CUPS software that falls under this license exception have the
+ following text at the top of each source file:<BLOCKQUOTE>This file is
+ subject to the Apple OS-Developed Software exception.</BLOCKQUOTE></LI>
+</OL>
+</LI>
+<LI><B>OpenSSL Toolkit License Exception</B>;
+<OL TYPE="a">
+<LI>Easy Software Products explicitly allows the compilation and
+ distribution of the CUPS software with the OpenSSL Toolkit.</LI>
+</OL>
+</LI>
+</OL>
+<P>No developer is required to provide these exceptions in a derived
+ work.</P>
+<H3><A NAME="6_1_3">Trademarks</A></H3>
+<P>Easy Software Products has trademarked the Common UNIX Printing
+ System, CUPS, and CUPS logo. These names and logos may be used freely
+ in any direct port or binary distribution of CUPS. Please contract Easy
+ Software Products for written permission to use them in derivative
+ products. Our intention is to protect the value of these trademarks and
+ ensure that any derivative product meets the same high-quality
+ standards as the original.</P>
+<H3><A NAME="6_1_4">Binary Distribution Rights</A></H3>
+<P>Easy Software Products also sells rights to the CUPS source code
+ under a binary distribution license for vendors that are unable to
+ release source code for their drivers, additions, and modifications to
+ CUPS under the GNU GPL and LGPL. For information please contact us at
+ the address shown above.</P>
+<P>The Common UNIX Printing System provides a &quot;pdftops&quot; filter that is
+ based on the Xpdf software. For binary distribution licensing of this
+ software, please contact:<BLOCKQUOTE> Derek B. Noonburg
+<BR> Email:<A HREF="mailto:derekn@foolabs.com"> derekn@foolabs.com</A>
+<BR> WWW:<A HREF="http://www.foolabs.com/xpdf/">
+ http://www.foolabs.com/xpdf/</A></BLOCKQUOTE></P>
+<H3><A NAME="6_1_5">Support</A></H3>
+<P>Easy Software Products sells software support for CUPS as well as a
+ commercial printing product based on CUPS called ESP Print Pro. You can
+ find out more at our web site:</P>
+<UL>
+<PRE>
+<A HREF="http://www.easysw.com/">http://www.easysw.com/</A>
+</PRE>
+</UL>
+
+<!-- NEW PAGE -->
+<H2><A NAME="6_2">GNU GENERAL PUBLIC LICENSE</A></H2>
+<P>Version 2, June 1991</P>
+<PRE>
+Copyright 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim
+copies of this license document, but changing it is not allowed.
+</PRE>
+<H4>Preamble</H4>
+<P>The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public License is
+ intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users. This
+ General Public License applies to most of the Free Software
+ Foundation's software and to any other program whose authors commit to
+ using it. (Some other Free Software Foundation software is covered by
+ the GNU Library General Public License instead.) You can apply it to
+ your programs, too.</P>
+<P>When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it in
+ new free programs; and that you know you can do these things.</P>
+<P>To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the software, or if you modify it.</P>
+<P>For example, if you distribute copies of such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have. You must make sure that they, too, receive or can get the
+ source code. And you must show them these terms so they know their
+ rights.</P>
+<P>We protect your rights with two steps: (1) copyright the software,
+ and (2) offer you this license which gives you legal permission to
+ copy, distribute and/or modify the software.</P>
+<P>Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software. If the software is modified by someone else and passed on, we
+ want its recipients to know that what they have is not the original, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.</P>
+<P>Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that redistributors of a free
+ program will individually obtain patent licenses, in effect making the
+ program proprietary. To prevent this, we have made it clear that any
+ patent must be licensed for everyone's free use or not licensed at all.</P>
+<P>The precise terms and conditions for copying, distribution and
+ modification follow.</P>
+<H4>GNU GENERAL PUBLIC LICENSE
+<BR> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+<OL START="0">
+<LI>This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The &quot;Program&quot;, below,
+ refers to any such program or work, and a &quot;work based on the Program&quot;
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language. (Hereinafter, translation is included without limitation in
+ the term &quot;modification&quot;.) Each licensee is addressed as &quot;you&quot;.
+<P>Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ the Program is not restricted, and the output from the Program is
+ covered only if its contents constitute a work based on the Program
+ (independent of having been made by running the Program). Whether that
+ is true depends on what the Program does.</P>
+<LI>You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you conspicuously
+ and appropriately publish on each copy an appropriate copyright notice
+ and disclaimer of warranty; keep intact all the notices that refer to
+ this License and to the absence of any warranty; and give any other
+ recipients of the Program a copy of this License along with the
+ Program.
+<P>You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.</P>
+<LI>You may modify your copy or copies of the Program or any portion of
+ it, thus forming a work based on the Program, and copy and distribute
+ such modifications or work under the terms of Section 1 above, provided
+ that you also meet all of these conditions:
+<OL TYPE="a">
+<LI>You must cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change.</LI>
+<LI>You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any part
+ thereof, to be licensed as a whole at no charge to all third parties
+ under the terms of this License.</LI>
+<LI>if the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the most ordinary way, to print or display an announcement including
+ an appropriate copyright notice and a notice that there is no warranty
+ (or else, saying that you provide a warranty) and that users may
+ redistribute the program under these conditions, and telling the user
+ how to view a copy of this License. (Exception: if the Program itself
+ is interactive but does not normally print such an announcement, your
+ work based on the Program is not required to print an announcement.)</LI>
+</OL>
+<P>These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Program,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Program, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.</P>
+<P>Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.</P>
+<P>In addition, mere aggregation of another work not based on the
+ Program with the Program (or with a work based on the Program) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.</P>
+<LI>You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+<OL TYPE="a">
+<LI>Accompany it with the complete corresponding machine-readable source
+ code, which must be distributed under the terms of Sections 1 and 2
+ above on a medium customarily used for software interchange; or,</LI>
+<LI>Accompany it with a written offer, valid for at least three years,
+ to give any third party, for a charge no more than your cost of
+ physically performing source distribution, a complete machine-readable
+ copy of the corresponding source code, to be distributed under the
+ terms of Sections 1 and 2 above on a medium customarily used for
+ software interchange; or,</LI>
+<LI>Accompany it with the information you received as to the offer to
+ distribute corresponding source code. (This alternative is allowed only
+ for noncommercial distribution and only if you received the program in
+ object code or executable form with such an offer, in accord with
+ Subsection b above.)</LI>
+</OL>
+<P>The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to control
+ compilation and installation of the executable. However, as a special
+ exception, the source code distributed need not include anything that
+ is normally distributed (in either source or binary form) with the
+ major components (compiler, kernel, and so on) of the operating system
+ on which the executable runs, unless that component itself accompanies
+ the executable.</P>
+<P>If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent access
+ to copy the source code from the same place counts as distribution of
+ the source code, even though third parties are not compelled to copy
+ the source along with the object code.</P>
+<LI>You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt otherwise
+ to copy, modify, sublicense or distribute the Program is void, and will
+ automatically terminate your rights under this License. However,
+ parties who have received copies, or rights, from you under this
+ License will not have their licenses terminated so long as such parties
+ remain in full compliance.</LI>
+<LI>You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying the
+ Program or works based on it.</LI>
+<LI>Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject to
+ these terms and conditions. You may not impose any further restrictions
+ on the recipients' exercise of the rights granted herein. You are not
+ responsible for enforcing compliance by third parties to this License.</LI>
+<LI>If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all. For example, if a patent license
+ would not permit royalty-free redistribution of the Program by all
+ those who receive copies directly or indirectly through you, then the
+ only way you could satisfy both it and this License would be to refrain
+ entirely from distribution of the Program.
+<P>If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.</P>
+<P>It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.</P>
+<P>This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.</P>
+<LI>If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License may
+ add an explicit geographical distribution limitation excluding those
+ countries, so that distribution is permitted only in or among countries
+ not thus excluded. In such case, this License incorporates the
+ limitation as if written in the body of this License.</LI>
+<LI>The Free Software Foundation may publish revised and/or new versions
+ of the General Public License from time to time. Such new versions will
+ be similar in spirit to the present version, but may differ in detail
+ to address new problems or concerns.
+<P>Each version is given a distinguishing version number. If the Program
+ specifies a version number of this License which applies to it and &quot;any
+ later version&quot;, you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Program does not specify a version
+ number of this License, you may choose any version ever published by
+ the Free Software Foundation.</P>
+<LI>If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted by the
+ Free Software Foundation, write to the Free Software Foundation; we
+ sometimes make exceptions for this. Our decision will be guided by the
+ two goals of preserving the free status of all derivatives of our free
+ software and of promoting the sharing and reuse of software generally.</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<H4>NO WARRANTY</H4>
+<OL START="11">
+<LI>BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER
+ EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
+ YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+ NECESSARY SERVICING, REPAIR OR CORRECTION.</LI>
+<LI>IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+ AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
+ FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.</LI>
+</OL>
+<H4>END OF TERMS AND CONDITIONS</H4>
+
+<!-- NEW PAGE -->
+<H2><A NAME="6_3">GNU LIBRARY GENERAL PUBLIC LICENSE</A></H2>
+<P>Version 2, June 1991</P>
+<PRE>
+Copyright (C) 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+</PRE>
+<H4>Preamble</H4>
+<P>The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public Licenses
+ are intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users.</P>
+<P>This license, the Library General Public License, applies to some
+ specially designated Free Software Foundation software, and to any
+ other libraries whose authors decide to use it. You can use it for your
+ libraries, too.</P>
+<P>When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it in
+ new free programs; and that you know you can do these things.</P>
+<P>To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the library, or if you modify it.</P>
+<P>For example, if you distribute copies of the library, whether gratis
+ or for a fee, you must give the recipients all the rights that we gave
+ you. You must make sure that they, too, receive or can get the source
+ code. If you link a program with the library, you must provide complete
+ object files to the recipients so that they can relink them with the
+ library, after making changes to the library and recompiling it. And
+ you must show them these terms so they know their rights.</P>
+<P>Our method of protecting your rights has two steps: (1) copyright the
+ library, and (2) offer you this license which gives you legal
+ permission to copy, distribute and/or modify the library.</P>
+<P>Also, for each distributor's protection, we want to make certain that
+ everyone understands that there is no warranty for this free library.
+ If the library is modified by someone else and passed on, we want its
+ recipients to know that what they have is not the original version, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.</P>
+<P>Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that companies distributing free
+ software will individually obtain patent licenses, thus in effect
+ transforming the program into proprietary software. To prevent this, we
+ have made it clear that any patent must be licensed for everyone's free
+ use or not licensed at all.</P>
+<P>Most GNU software, including some libraries, is covered by the
+ ordinary GNU General Public License, which was designed for utility
+ programs. This license, the GNU Library General Public License, applies
+ to certain designated libraries. This license is quite different from
+ the ordinary one; be sure to read it in full, and don't assume that
+ anything in it is the same as in the ordinary license.</P>
+<P>The reason we have a separate public license for some libraries is
+ that they blur the distinction we usually make between modifying or
+ adding to a program and simply using it. Linking a program with a
+ library, without changing the library, is in some sense simply using
+ the library, and is analogous to running a utility program or
+ application program. However, in a textual and legal sense, the linked
+ executable is a combined work, a derivative of the original library,
+ and the ordinary General Public License treats it as such.</P>
+<P>Because of this blurred distinction, using the ordinary General
+ Public License for libraries did not effectively promote software
+ sharing, because most developers did not use the libraries. We
+ concluded that weaker conditions might promote sharing better.</P>
+<P>However, unrestricted linking of non-free programs would deprive the
+ users of those programs of all benefit from the free status of the
+ libraries themselves. This Library General Public License is intended
+ to permit developers of non-free programs to use free libraries, while
+ preserving your freedom as a user of such programs to change the free
+ libraries that are incorporated in them. (We have not seen how to
+ achieve this as regards changes in header files, but we have achieved
+ it as regards changes in the actual functions of the Library.) The hope
+ is that this will lead to faster development of free libraries.</P>
+<P>The precise terms and conditions for copying, distribution and
+ modification follow. Pay close attention to the difference between a
+ &quot;work based on the library&quot; and a &quot;work that uses the library&quot;. The
+ former contains code derived from the library, while the latter only
+ works together with the library.</P>
+<P>Note that it is possible for a library to be covered by the ordinary
+ General Public License rather than by this special one.</P>
+<H4>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</H4>
+<P><STRONG>0.</STRONG> This License Agreement applies to any software
+ library which contains a notice placed by the copyright holder or other
+ authorized party saying it may be distributed under the terms of this
+ Library General Public License (also called &quot;this License&quot;). Each
+ licensee is addressed as &quot;you&quot;.</P>
+<P>A &quot;library&quot; means a collection of software functions and/or data
+ prepared so as to be conveniently linked with application programs
+ (which use some of those functions and data) to form executables.</P>
+<P>The &quot;Library&quot;, below, refers to any such software library or work
+ which has been distributed under these terms. A &quot;work based on the
+ Library&quot; means either the Library or any derivative work under
+ copyright law: that is to say, a work containing the Library or a
+ portion of it, either verbatim or with modifications and/or translated
+ straightforwardly into another language. (Hereinafter, translation is
+ included without limitation in the term &quot;modification&quot;.)</P>
+<P>&quot;Source code&quot; for a work means the preferred form of the work for
+ making modifications to it. For a library, complete source code means
+ all the source code for all modules it contains, plus any associated
+ interface definition files, plus the scripts used to control
+ compilation and installation of the library.</P>
+<P>Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ a program using the Library is not restricted, and output from such a
+ program is covered only if its contents constitute a work based on the
+ Library (independent of the use of the Library in a tool for writing
+ it). Whether that is true depends on what the Library does and what the
+ program that uses the Library does.</P>
+<P><STRONG>1.</STRONG> You may copy and distribute verbatim copies of
+ the Library's complete source code as you receive it, in any medium,
+ provided that you conspicuously and appropriately publish on each copy
+ an appropriate copyright notice and disclaimer of warranty; keep intact
+ all the notices that refer to this License and to the absence of any
+ warranty; and distribute a copy of this License along with the Library.</P>
+<P>You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.</P>
+<P><STRONG>2.</STRONG> You may modify your copy or copies of the Library
+ or any portion of it, thus forming a work based on the Library, and
+ copy and distribute such modifications or work under the terms of
+ Section 1 above, provided that you also meet all of these conditions:</P>
+<OL TYPE="a">
+<LI>The modified work must itself be a software library.
+<P></P>
+<LI>You must cause the files modified to carry prominent notices stating
+ that you changed the files and the date of any change.
+<P></P>
+<LI>You must cause the whole of the work to be licensed at no charge to
+ all third parties under the terms of this License.
+<P></P>
+<LI>If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses the
+ facility, other than as an argument passed when the facility is
+ invoked, then you must make a good faith effort to ensure that, in the
+ event an application does not supply such function or table, the
+ facility still operates, and performs whatever part of its purpose
+ remains meaningful.
+<P>(For example, a function in a library to compute square roots has a
+ purpose that is entirely well-defined independent of the application.
+ Therefore, Subsection 2d requires that any application-supplied
+ function or table used by this function must be optional: if the
+ application does not supply it, the square root function must still
+ compute square roots.)</P>
+</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<P>These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Library,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Library, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.</P>
+<P>Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Library.</P>
+<P>In addition, mere aggregation of another work not based on the
+ Library with the Library (or with a work based on the Library) on a
+ volume of a storage or distribution medium does not bring the other
+ work under the scope of this License.</P>
+<P><STRONG>3.</STRONG> You may opt to apply the terms of the ordinary
+ GNU General Public License instead of this License to a given copy of
+ the Library. To do this, you must alter all the notices that refer to
+ this License, so that they refer to the ordinary GNU General Public
+ License, version 2, instead of to this License. (If a newer version
+ than version 2 of the ordinary GNU General Public License has appeared,
+ then you can specify that version instead if you wish.) Do not make any
+ other change in these notices.</P>
+<P>Once this change is made in a given copy, it is irreversible for that
+ copy, so the ordinary GNU General Public License applies to all
+ subsequent copies and derivative works made from that copy.</P>
+<P>This option is useful when you wish to copy part of the code of the
+ Library into a program that is not a library.</P>
+<P><STRONG>4.</STRONG> You may copy and distribute the Library (or a
+ portion or derivative of it, under Section 2) in object code or
+ executable form under the terms of Sections 1 and 2 above provided that
+ you accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections 1
+ and 2 above on a medium customarily used for software interchange.</P>
+<P>If distribution of object code is made by offering access to copy
+ from a designated place, then offering equivalent access to copy the
+ source code from the same place satisfies the requirement to distribute
+ the source code, even though third parties are not compelled to copy
+ the source along with the object code.</P>
+<P><STRONG>5.</STRONG> A program that contains no derivative of any
+ portion of the Library, but is designed to work with the Library by
+ being compiled or linked with it, is called a &quot;work that uses the
+ Library&quot;. Such a work, in isolation, is not a derivative work of the
+ Library, and therefore falls outside the scope of this License.</P>
+<P>However, linking a &quot;work that uses the Library&quot; with the Library
+ creates an executable that is a derivative of the Library (because it
+ contains portions of the Library), rather than a &quot;work that uses the
+ library&quot;. The executable is therefore covered by this License. Section
+ 6 states terms for distribution of such executables.</P>
+<P>When a &quot;work that uses the Library&quot; uses material from a header file
+ that is part of the Library, the object code for the work may be a
+ derivative work of the Library even though the source code is not.
+ Whether this is true is especially significant if the work can be
+ linked without the Library, or if the work is itself a library. The
+ threshold for this to be true is not precisely defined by law.</P>
+<P>If such an object file uses only numerical parameters, data structure
+ layouts and accessors, and small macros and small inline functions (ten
+ lines or less in length), then the use of the object file is
+ unrestricted, regardless of whether it is legally a derivative work.
+ (Executables containing this object code plus portions of the Library
+ will still fall under Section 6.)</P>
+<P>Otherwise, if the work is a derivative of the Library, you may
+ distribute the object code for the work under the terms of Section 6.
+ Any executables containing that work also fall under Section 6, whether
+ or not they are linked directly with the Library itself.</P>
+<P><STRONG>6.</STRONG> As an exception to the Sections above, you may
+ also compile or link a &quot;work that uses the Library&quot; with the Library to
+ produce a work containing portions of the Library, and distribute that
+ work under terms of your choice, provided that the terms permit
+ modification of the work for the customer's own use and reverse
+ engineering for debugging such modifications.</P>
+<P>You must give prominent notice with each copy of the work that the
+ Library is used in it and that the Library and its use are covered by
+ this License. You must supply a copy of this License. If the work
+ during execution displays copyright notices, you must include the
+ copyright notice for the Library among them, as well as a reference
+ directing the user to the copy of this License. Also, you must do one
+ of these things:</P>
+<OL TYPE="a">
+<LI>Accompany the work with the complete corresponding machine-readable
+ source code for the Library including whatever changes were used in the
+ work (which must be distributed under Sections 1 and 2 above); and, if
+ the work is an executable linked with the Library, with the complete
+ machine-readable &quot;work that uses the Library&quot;, as object code and/or
+ source code, so that the user can modify the Library and then relink to
+ produce a modified executable containing the modified Library. (It is
+ understood that the user who changes the contents of definitions files
+ in the Library will not necessarily be able to recompile the
+ application to use the modified definitions.)
+<P></P>
+<LI>Accompany the work with a written offer, valid for at least three
+ years, to give the same user the materials specified in Subsection 6a,
+ above, for a charge no more than the cost of performing this
+ distribution.
+<P></P>
+<LI>If distribution of the work is made by offering access to copy from
+ a designated place, offer equivalent access to copy the above specified
+ materials from the same place.
+<P></P>
+<LI>Verify that the user has already received a copy of these materials
+ or that you have already sent this user a copy.</LI>
+</LI>
+</LI>
+</LI>
+</OL>
+<P>For an executable, the required form of the &quot;work that uses the
+ Library&quot; must include any data and utility programs needed for
+ reproducing the executable from it. However, as a special exception,
+ the source code distributed need not include anything that is normally
+ distributed (in either source or binary form) with the major components
+ (compiler, kernel, and so on) of the operating system on which the
+ executable runs, unless that component itself accompanies the
+ executable.</P>
+<P>It may happen that this requirement contradicts the license
+ restrictions of other proprietary libraries that do not normally
+ accompany the operating system. Such a contradiction means you cannot
+ use both them and the Library together in an executable that you
+ distribute.</P>
+<P><STRONG>7.</STRONG> You may place library facilities that are a work
+ based on the Library side-by-side in a single library together with
+ other library facilities not covered by this License, and distribute
+ such a combined library, provided that the separate distribution of the
+ work based on the Library and of the other library facilities is
+ otherwise permitted, and provided that you do these two things:</P>
+<OL TYPE="a">
+<LI>Accompany the combined library with a copy of the same work based on
+ the Library, uncombined with any other library facilities. This must be
+ distributed under the terms of the Sections above.
+<P></P>
+<LI>Give prominent notice with the combined library of the fact that
+ part of it is a work based on the Library, and explaining where to find
+ the accompanying uncombined form of the same work.</LI>
+</LI>
+</OL>
+<P><STRONG>8.</STRONG> You may not copy, modify, sublicense, link with,
+ or distribute the Library except as expressly provided under this
+ License. Any attempt otherwise to copy, modify, sublicense, link with,
+ or distribute the Library is void, and will automatically terminate
+ your rights under this License. However, parties who have received
+ copies, or rights, from you under this License will not have their
+ licenses terminated so long as such parties remain in full compliance.</P>
+<P><STRONG>9.</STRONG> You are not required to accept this License,
+ since you have not signed it. However, nothing else grants you
+ permission to modify or distribute the Library or its derivative works.
+ These actions are prohibited by law if you do not accept this License.
+ Therefore, by modifying or distributing the Library (or any work based
+ on the Library), you indicate your acceptance of this License to do so,
+ and all its terms and conditions for copying, distributing or modifying
+ the Library or works based on it.</P>
+<P><STRONG>10.</STRONG> Each time you redistribute the Library (or any
+ work based on the Library), the recipient automatically receives a
+ license from the original licensor to copy, distribute, link with or
+ modify the Library subject to these terms and conditions. You may not
+ impose any further restrictions on the recipients' exercise of the
+ rights granted herein. You are not responsible for enforcing compliance
+ by third parties to this License.</P>
+<P><STRONG>11.</STRONG> If, as a consequence of a court judgment or
+ allegation of patent infringement or for any other reason (not limited
+ to patent issues), conditions are imposed on you (whether by court
+ order, agreement or otherwise) that contradict the conditions of this
+ License, they do not excuse you from the conditions of this License. If
+ you cannot distribute so as to satisfy simultaneously your obligations
+ under this License and any other pertinent obligations, then as a
+ consequence you may not distribute the Library at all. For example, if
+ a patent license would not permit royalty-free redistribution of the
+ Library by all those who receive copies directly or indirectly through
+ you, then the only way you could satisfy both it and this License would
+ be to refrain entirely from distribution of the Library.</P>
+<P>If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply, and the section as a whole is intended to apply in other
+ circumstances.</P>
+<P>It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system which is implemented
+ by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.</P>
+<P>This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.</P>
+<P><STRONG>12.</STRONG> If the distribution and/or use of the Library is
+ restricted in certain countries either by patents or by copyrighted
+ interfaces, the original copyright holder who places the Library under
+ this License may add an explicit geographical distribution limitation
+ excluding those countries, so that distribution is permitted only in or
+ among countries not thus excluded. In such case, this License
+ incorporates the limitation as if written in the body of this License.</P>
+<P><STRONG>13.</STRONG> The Free Software Foundation may publish revised
+ and/or new versions of the Library General Public License from time to
+ time. Such new versions will be similar in spirit to the present
+ version, but may differ in detail to address new problems or concerns.</P>
+<P>Each version is given a distinguishing version number. If the Library
+ specifies a version number of this License which applies to it and &quot;any
+ later version&quot;, you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Library does not specify a license
+ version number, you may choose any version ever published by the Free
+ Software Foundation.</P>
+<P><STRONG>14.</STRONG> If you wish to incorporate parts of the Library
+ into other free programs whose distribution conditions are incompatible
+ with these, write to the author to ask for permission. For software
+ which is copyrighted by the Free Software Foundation, write to the Free
+ Software Foundation; we sometimes make exceptions for this. Our
+ decision will be guided by the two goals of preserving the free status
+ of all derivatives of our free software and of promoting the sharing
+ and reuse of software generally.</P>
+<P><STRONG>NO WARRANTY</STRONG></P>
+<P><STRONG>15.</STRONG> BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE,
+ THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY &quot;AS IS&quot; WITHOUT
+ WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
+ OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU
+ ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</P>
+<P><STRONG>16.</STRONG> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
+ AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO
+ MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
+ LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.</P>
+<H4>END OF TERMS AND CONDITIONS</H4>
+</BODY>
+</HTML>
diff --git a/doc/sum.pdf b/doc/sum.pdf
new file mode 100644
index 000000000..90d2cb339
--- /dev/null
+++ b/doc/sum.pdf
Binary files differ
diff --git a/doc/sum.shtml b/doc/sum.shtml
new file mode 100644
index 000000000..ea79765bb
--- /dev/null
+++ b/doc/sum.shtml
@@ -0,0 +1,933 @@
+<HTML>
+<HEAD>
+ <META NAME="Description" CONTENT="Common UNIX Printing System Software Users Manual">
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-SUM-1.1.16">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Software Users Manual</TITLE>
+</HEAD>
+<BODY>
+
+<H1 ALIGN="RIGHT">Preface</H1>
+
+<P>This software users manual describes how to use the Common UNIX Printing
+System<SUP>TM</SUP> ("CUPS<SUP>TM</SUP>") Version 1.1.16.
+
+<EMBED SRC="system-overview.shtml">
+
+<!-- NEED 2in -->
+<H2>Document Overview</H2>
+
+<P>This software users manual is organized into the following sections:</P>
+
+<UL>
+ <LI><A HREF="#OVERVIEW">1 - Printing System Overview</A>
+ <LI><A HREF="#USING_SYSTEM">2 - Using the Printing System</A>
+ <LI><A HREF="#STANDARD_OPTIONS">3 - Standard Printer Options</A>
+ <LI><A HREF="#SAVING_OPTIONS">4 - Saving Printer Options and Defaults</A>
+ <LI><A HREF="#LICENSE">A - Software License Agreement</A>
+</UL>
+
+<H2>Notation Conventions</H2>
+
+<P>Various font and syntax conventions are used in this guide. Examples and
+their meanings and uses are explained below:
+
+<CENTER><TABLE WIDTH="80%">
+<TR>
+ <TH>Example</TH>
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+ <TH>Description</TH>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD><CODE>lpstat</CODE><BR>
+ <CODE>lpstat(1)</CODE></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>The names of commands; the first mention of a command or
+ function in a chapter is followed by a manual page section
+ number.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD><VAR>/var</VAR><BR>
+ <VAR>/usr/share/cups/data/testprint.ps</VAR></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>File and directory names.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD NOWRAP><TT>Request ID is Printer-123</TT></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Screen output.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD NOWRAP><KBD>lp -d printer filename ENTER</KBD></TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Literal user input; special keys like <KBD>ENTER</KBD> are
+ in ALL CAPS.</TD>
+</TR>
+<TR><TD>&nbsp;</TD></TR>
+<TR VALIGN="TOP">
+ <TD>12.3</TD>
+
+ <TD>&nbsp;&nbsp;&nbsp;</TD>
+
+ <TD>Numbers in the text are written using the period (.) to indicate
+ the decimal point.</TD>
+</TR>
+</TABLE></CENTER>
+
+<!-- NEED 3in -->
+<H2>Abbreviations</H2>
+
+The following abbreviations are used throughout this manual:
+
+<UL>
+<DL>
+
+ <DT>kb
+ <DD>Kilobytes, or 1024 bytes<BR>&nbsp;
+
+ <DT>Mb
+ <DD>Megabytes, or 1048576 bytes<BR>&nbsp;
+
+ <DT>Gb
+ <DD>Gigabytes, or 1073741824 bytes<BR>&nbsp;
+
+</DL>
+</UL>
+
+<H2>Other References</H2>
+
+<UL>
+<DL>
+
+ <DT>CUPS Software Administrators Manual
+
+ <DD>An administration guide for the CUPS software.<BR>&nbsp;
+
+ <DT>CUPS Software Programmers Manual
+
+ <DD>A programmer guide for interfacing with and/or extending the CUPS
+ software.<BR>&nbsp;
+
+</DL>
+</UL>
+
+
+<EMBED SRC="printing-overview.shtml">
+
+
+<H1 ALIGN="RIGHT"><A NAME="USING_SYSTEM">2 - Using the Printing System</A></H1>
+
+<P>This chapter shows you how to submit, query, and cancel print jobs to
+different printers.
+
+<H2>Submitting Files for Printing</H2>
+
+<P>CUPS provides both the System V (<CODE>lp(1)</CODE>) and Berkeley
+(<CODE>lpr(1)</CODE>) printing commands. Type the following command to
+print a file to the default (or only) printer on the system:
+
+<UL><PRE>
+<B>lp filename ENTER</B>
+</PRE></UL>
+
+<P>or:
+
+<UL><PRE>
+<B>lpr filename ENTER</B>
+</PRE></UL>
+
+<P>CUPS understands many different types of files directly, including
+PostScript and image files. This allows you to print from inside your
+applications or at the command-line, whichever is most convenient!
+
+<H2>Choosing a Printer</H2>
+
+<P>Many systems will have more than one printer available to the user. These
+printers can be attached to the local system via a parallel, serial, or USB
+port, or available over the network.
+
+<P>Use the <CODE>lpstat(1)</CODE> command to see a list of available printers:
+
+<UL><PRE>
+<B>lpstat -p -d ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>-p</CODE> option specifies that you want to see a
+list of printers, and the <CODE>-d</CODE> option reports the
+current default printer or class.
+
+<P>Use the <CODE>-d</CODE> option with the <CODE>lp</CODE> command to
+print to a specific printer:
+
+<UL><PRE>
+<B>lp -d printer filename ENTER</B>
+</PRE></UL>
+
+<P>or the <CODE>-P</CODE> option with the <CODE>lpr</CODE> command:
+
+<UL><PRE>
+<B>lpr -P printer filename ENTER</B>
+</PRE></UL>
+
+<H2>Setting Printer Options</H2>
+
+<P>For many types of files, the default printer options may be sufficient for
+your needs. However, there may be times when you need to change the options
+for a particular file you are printing.
+
+<P>The <CODE>lp</CODE> and <CODE>lpr</CODE> commands allow you to pass
+printer options using the <CODE>-o</CODE> option:
+
+<UL><PRE>
+<B>lp -o landscape -o scaling=75 -o media=A4 filename.jpg
+<B>lpr -o landscape -o scaling=75 -o media=A4 filename.jpg
+</PRE></UL>
+
+<P>The available printer options vary depending on the printer. The standard
+options are described in <A HREF="#STANDARD_OPTIONS">Chapter 3, "Standard
+Printing Options"</A>.
+
+<H2>Printing Multiple Copies</H2>
+
+<P>Both the <CODE>lp</CODE> and <CODE>lpr</CODE> commands have options for
+printing more than one copy of a file:
+
+<UL><PRE>
+<B>lp -n <I>num-copies</I> filename ENTER</B>
+<B>lpr -#<I>num-copies</I> filename ENTER</B>
+</PRE></UL>
+
+<P>Copies are normally <I>not</I> collated for you. Use the <CODE>-o
+Collate=True</CODE> option to get collated copies :
+
+<UL><PRE>
+<B>lp -n <I>num-copies</I> -o Collate=True filename ENTER</B>
+<B>lpr -#<I>num-copies</I> -o Collate=True filename ENTER</B>
+</PRE></UL>
+
+<!-- NEED 3in -->
+<H2>Checking the Printer Status from the Command-Line</H2>
+
+<P>The <CODE>lpstat</CODE> command can be used to check for jobs that you
+have submitted for printing:
+
+<UL><PRE>
+<B>lpstat ENTER</B>
+Printer-1 johndoe 4427776
+Printer-2 johndoe 15786
+Printer-3 johndoe 372842
+</PRE></UL>
+
+<P>The jobs are listed in the order they will be printed. Use the
+<CODE>-p</CODE> option to see which files and printers are active:
+
+<UL><PRE>
+<B>lpstat -p ENTER</B>
+printer DeskJet now printing DeskJet-1.
+</PRE></UL>
+
+<!-- NEED 2in -->
+<P>Use the <CODE>-o</CODE> and <CODE>-p</CODE> options together to show
+the jobs and the printers:
+
+<UL><PRE>
+<B>lpstat -o -p ENTER</B>
+Printer-1 johndoe 4427776
+Printer-2 johndoe 15786
+Printer-3 johndoe 372842
+printer DeskJet now printing DeskJet-1.
+</PRE></UL>
+
+<H2>Checking the Printer Status from the Web</H2>
+
+<P>Since CUPS uses the Internet Printing Protocol, it is also a
+fully-functional web server. To use your web browser to monitor the
+printers on your system, open the URL:
+
+<UL><PRE>
+<A HREF="http://localhost:631">http://localhost:631</A>
+</PRE></UL>
+
+<P>From there you can view the status of classes, jobs, and printers
+with the click of a button!
+
+<H2>Canceling a Print Job</H2>
+
+<P>The <CODE>cancel(1)</CODE> and <CODE>lprm(1)</CODE> commands cancel
+a print job:
+
+<UL><PRE>
+<B>cancel <I>job-id</I> ENTER</B>
+<B>lprm <I>job-id</I> ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>job-id</CODE> is the number that was reported to you by
+the <CODE>lp</CODE> or <CODE>lpstat</CODE> commands.
+
+
+<H1 ALIGN="RIGHT"><A NAME="STANDARD_OPTIONS">3 - Standard Printer Options</A></H1>
+
+<P>This chapter describes the standard printer options that are available
+when printing with the <CODE>lp</CODE> and <CODE>lpr</CODE> commands.
+
+<H2>General Options</H2>
+
+<P>The following options apply when printing all types of files.
+
+<!-- NEED 2in -->
+<H3>Selecting the Media Size, Type, and Source</H3>
+
+<P>The <CODE>-o media=xyz</CODE> option sets the media size, type,
+and/or source:
+
+<UL><PRE>
+<B>lp -o media=Letter filename ENTER</B>
+<B>lp -o media=Letter,MultiPurpose filename ENTER</B>
+<B>lpr -o media=Letter,Transparency filename ENTER</B>
+<B>lpr -o media=Letter,MultiPurpose,Transparency filename ENTER</B>
+</PRE></UL>
+
+<!-- NEED 3in -->
+<P>The available media sizes, types, and sources depend on the printer, but
+most support the following options (case is not significant):
+
+<UL>
+
+ <LI><CODE>Letter</CODE> - US Letter (8.5x11 inches, or 216x279mm)
+
+ <LI><CODE>Legal</CODE> - US Legal (8.5x14 inches, or 216x356mm)
+
+ <LI><CODE>A4</CODE> - ISO A4 (8.27x11.69 inches, or 210x297mm)
+
+ <LI><CODE>COM10</CODE> - US #10 Envelope (9.5x4.125 inches, or
+ 241x105mm)
+
+ <LI><CODE>DL</CODE> - ISO DL Envelope (8.66x4.33 inches, or 220x110mm)
+
+ <LI><CODE>Transparency</CODE> - Transparency media type or source
+
+ <LI><CODE>Upper</CODE> - Upper paper tray
+
+ <LI><CODE>Lower</CODE> - Lower paper tray
+
+ <LI><CODE>MultiPurpose</CODE> - Multi-purpose paper tray
+
+ <LI><CODE>LargeCapacity</CODE> - Large capacity paper tray
+
+</UL>
+
+<P>The actual options supported are defined in the printer's PPD file
+in the <CODE>PageSize</CODE>, <CODE>InputSlot</CODE>, and
+<CODE>MediaType</CODE> options.
+
+<H3>Setting the Orientation</H3>
+
+<P>The <CODE>-o landscape</CODE> option will rotate the page 90 degrees
+to print in landscape orientation:
+
+<UL><PRE>
+<B>lp -o landscape filename ENTER</B>
+<B>lpr -o landscape filename ENTER</B>
+</PRE></UL>
+
+<H3>Printing On Both Sides of the Paper</H3>
+
+<P>The <CODE>-o sides=two-sided-short-edge</CODE> and <CODE>-o
+sides=two-sided-long-edge</CODE> options will enable duplexing on the
+printer, if the printer supports it. The <CODE>-o
+sides=two-sided-short-edge</CODE> option is suitable for landscape
+pages, while the <CODE>-o sides=two-sided-long-edge</CODE> option is
+suitable for portrait pages:
+
+<UL><PRE>
+<B>lp -o sides=two-sided-short-edge filename ENTER</B>
+<B>lp -o sides=two-sided-long-edge filename ENTER</B>
+<B>lpr -o sides=two-sided-long-edge filename ENTER</B>
+</PRE></UL>
+
+<P>The default is to print single-sided:
+
+<UL><PRE>
+<B>lp -o sides=one-sided filename ENTER</B>
+<B>lpr -o sides=one-sided filename ENTER</B>
+</PRE></UL>
+
+<H2>Banner Options</H2>
+
+<P>The following options apply when printing all types of files.
+
+<H3>Selecting the Banner Page(s)</H3>
+
+<P>The <CODE>-o jobsheets=start,end</CODE> option sets the banner page(s) to
+use for a job:
+
+<UL><PRE>
+<B>lp -o job-sheets=none filename ENTER</B>
+<B>lp -o job-sheets=standard filename ENTER</B>
+<B>lpr -o job-sheets=classified,classified filename ENTER</B>
+</PRE></UL>
+
+<P>If only one banner file is specified, it will be printed before the
+files in the job. If a second banner file is specified, it is printed after
+the files in the job.
+
+<P>The available banner pages depend on the local system configuration; CUPS
+includes the following banner files:
+
+<UL>
+
+ <LI><CODE>none</CODE> - Do not produce a banner page.
+
+ <LI><CODE>classified</CODE> - A banner page with a "classified"
+ label at the top and bottom.
+
+ <LI><CODE>confidential</CODE> - A banner page with a
+ "confidential" label at the top and bottom.
+
+ <LI><CODE>secret</CODE> - A banner page with a "secret" label
+ at the top and bottom.
+
+ <LI><CODE>standard</CODE> - A banner page with no label at the
+ top and bottom.
+
+ <LI><CODE>topsecret</CODE> - A banner page with a "top secret"
+ label at the top and bottom.
+
+ <LI><CODE>unclassified</CODE> - A banner page with an
+ "unclassified" label at the top and bottom.
+
+</UL>
+
+<H2>Document Options</H2>
+
+<P>The following options apply when printing all types of files.
+
+<H3>Selecting a Range of Pages</H3>
+
+<P>The <CODE>-o page-ranges=pages</CODE> option selects a range of
+pages for printing:
+
+<UL><PRE>
+<B>lp -o page-ranges=1 filename ENTER</B>
+<B>lp -o page-ranges=1-4 filename ENTER</B>
+<B>lp -o page-ranges=1-4,7,9-12 filename ENTER</B>
+<B>lpr -o page-ranges=1-4,7,9-12 filename ENTER</B>
+</PRE></UL>
+
+<P>As shown above, the <CODE>pages</CODE> value can be a single page, a
+range of pages, or a collection of page numbers and ranges separated by
+commas. The pages will always be printed in ascending order, regardless
+of the order of the pages in the <CODE>page-ranges</CODE> option.
+
+<P>The default is to print all pages.
+
+<H3>Selecting Even or Odd Pages</H3>
+
+<P>Use the <CODE>-o page-set=set</CODE> option to select the even or odd pages:
+
+<UL><PRE>
+<B>lp -o page-set=odd filename ENTER</B>
+<B>lp -o page-set=even filename ENTER</B>
+<B>lpr -o page-set=even filename ENTER</B>
+</PRE></UL>
+
+<P>The default is to print all pages.
+
+<H3>N-Up Printing</H3>
+
+<P>The <CODE>-o number-up=value</CODE> option selects N-Up printing.
+N-Up printing places multiple document pages on a single printed page.
+CUPS supports 1, 2, 4, 6, 9, and 16-Up formats; the default format is
+1-Up:
+
+<UL><PRE>
+<B>lp -o number-up=1 filename ENTER</B>
+<B>lp -o number-up=2 filename ENTER</B>
+<B>lp -o number-up=4 filename ENTER</B>
+<B>lpr -o number-up=16 filename ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>-o page-border=value</CODE> option chooses the border
+to draw around each page:
+
+<UL>
+ <LI><CODE>-o page-border=double</CODE>; draw two hairline borders around each page</LI>
+ <LI><CODE>-o page-border=double-thick</CODE>; draw two 1pt borders around each page</LI>
+ <LI><CODE>-o page-border=none</CODE>; do not draw a border (default)</LI>
+ <LI><CODE>-o page-border=single</CODE>; draw one hairline border around each page</LI>
+ <LI><CODE>-o page-border=single-thick</CODE>; draw one 1pt border around each page</LI>
+</UL>
+
+<P>The <CODE>-o number-up-layout=value</CODE> option chooses the layout
+of the pages on each output page:
+
+<UL>
+ <LI><CODE>-o number-up-layout=btlr</CODE>; Bottom to top, left to right</LI>
+ <LI><CODE>-o number-up-layout=btrl</CODE>; Bottom to top, right to left</LI>
+ <LI><CODE>-o number-up-layout=lrbt</CODE>; Left to right, bottom to top</LI>
+ <LI><CODE>-o number-up-layout=lrtb</CODE>; Left to right, top to bottom (default)</LI>
+ <LI><CODE>-o number-up-layout=rlbt</CODE>; Right to left, bottom to top</LI>
+ <LI><CODE>-o number-up-layout=rltb</CODE>; Right to left, top to bottom</LI>
+ <LI><CODE>-o number-up-layout=tblr</CODE>; Top to bottom, left to right</LI>
+ <LI><CODE>-o number-up-layout=tbrl</CODE>; Top to bottom, right to left</LI>
+</UL>
+
+<H3>Setting the Brightness</H3>
+
+<P>You can control the overall brightness of the printed output using the
+<CODE>-o brightness=percent</CODE> option:
+
+<UL><PRE>
+<B>lp -o brightness=120 filename ENTER</B>
+<B>lpr -o brightness=120 filename ENTER</B>
+</PRE></UL>
+
+<P>Values greater than 100 will lighten the print, while values less than
+100 will darken it.
+
+<H3>Setting the Gamma Correction</H3>
+
+<P>You can control the overall gamma correction of the printed output
+using the <CODE>-o gamma=value</CODE> option:
+
+<UL><PRE>
+<B>lp -o gamma=1700 filename ENTER</B>
+<B>lpr -o gamma=1700 filename ENTER</B>
+</PRE></UL>
+
+<P>Values greater than 1000 will lighten the print, while values less
+than 1000 will darken it. The default gamma is 1000.
+
+<H2>Text Options</H2>
+
+<P>The following options apply when printing text files.
+
+<H3>Setting the Number of Characters Per Inch</H3>
+
+<P>The <CODE>-o cpi=value</CODE> option sets the number of characters per inch:
+
+<UL><PRE>
+<B>lp -o cpi=10 filename ENTER</B>
+<B>lp -o cpi=12 filename ENTER</B>
+<B>lpr -o cpi=17 filename ENTER</B>
+</PRE></UL>
+
+<P>The default characters per inch is 10.
+
+<H3>Setting the Number of Lines Per Inch</H3>
+
+<P>The <CODE>-o lpi=value</CODE> option sets the number of lines per inch:
+
+<UL><PRE>
+<B>lp -o lpi=6 filename ENTER</B>
+<B>lpr -o lpi=8 filename ENTER</B>
+</PRE></UL>
+
+<P>The default lines per inch is 6.
+
+<H3>Setting the Number of Columns</H3>
+
+<P>The <CODE>-o columns=value</CODE> option sets the number of text columns:
+
+<UL><PRE>
+<B>lp -o columns=2 filename ENTER</B>
+<B>lpr -o columns=3 filename ENTER</B>
+</PRE></UL>
+
+<P>The default number of columns is 1.
+
+<H3>Setting the Page Margins</H3>
+
+<P>Normally the page margins are set to the hard limits of the printer.
+Use the <CODE>-o page-left=value</CODE>, <CODE>-o
+page-right=value</CODE>, <CODE>-o page-top=value</CODE>, and <CODE>-o
+page-bottom=value</CODE> options to adjust the page margins:
+
+<UL><PRE>
+<B>lp -o page-left=<I>value</I> filename ENTER</B>
+<B>lp -o page-right=<I>value</I> filename ENTER</B>
+<B>lp -o page-top=<I>value</I> filename ENTER</B>
+<B>lp -o page-bottom=<I>value</I> filename ENTER</B>
+<B>lpr -o page-bottom=<I>value</I> filename ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>value</CODE> argument is the margin in points; each point is 1/72 inch
+or 0.35mm.
+
+<H3>Pretty Printing</H3>
+
+<P>The <CODE>-o prettyprint</CODE> option puts a header at the top of each page with the
+page number, job title (usually the filename), and the date. Also, C and C++
+keywords are highlighted, and comment lines are italicized:
+
+<UL><PRE>
+<B>lp -o prettyprint filename ENTER</B>
+<B>lpr -o prettyprint filename ENTER</B>
+</PRE></UL>
+
+<H2>Image Options</H2>
+
+<P>The following options apply when printing image files.
+
+<H3>Positioning the Image</H3>
+
+<P>The <CODE>-o position=name</CODE> option specifies the position of the
+image on the page:
+
+<UL>
+
+ <LI><CODE>center</CODE> - Center the image on the page (default)
+
+ <LI><CODE>top</CODE> - Print the image centered at the top of the page
+
+ <LI><CODE>left</CODE> - Print the image centered on the left of page
+
+ <LI><CODE>right</CODE> - Print the image centered on the right of the page
+
+ <LI><CODE>top-left</CODE> - Print the image at the top left corner of
+ the page
+
+ <LI><CODE>top-right</CODE> - Print the image at the top right corner of
+ the page
+
+ <LI><CODE>bottom</CODE> - Print the image centered at the bottom of
+ the page
+
+ <LI><CODE>bottom-left</CODE> - Print the image at the bottom left
+ corner of the page
+
+ <LI><CODE>bottom-right</CODE> - Print the image at the bottom right
+ corner of the page
+
+</UL>
+
+<H3>Scaling the Image</H3>
+
+<P>The <CODE>-o scaling=percent</CODE>, <CODE>-o
+ppi=value</CODE>, and <CODE>-o natural-scaling=percent</CODE>
+options change the size of a printed image:
+
+<UL><PRE>
+<B>lp -o scaling=<I>percent</I> filename ENTER</B>
+<B>lp -o ppi=<I>value</I> filename ENTER</B>
+<B>lpr -o natural-scaling=<I>percent</I> filename ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>scaling=percent</CODE> value is a number from 1 to 800
+specifying the size in relation to the page (<I>not</I> the image.) A
+scaling of 100 percent will fill the page as completely as the image
+aspect ratio allows. A scaling of 200 percent will print on up to 4
+pages.
+
+<P>The <CODE>ppi=value</CODE> value is a number from 1 to 1200 specifying the
+resolution of the image in pixels per inch. An image that is 3000x2400
+pixels will print 10x8 inches at 300 pixels per inch, for example. If
+the specified resolution makes the image larger than the page, multiple
+pages will be printed to satisfy the request.
+
+<P>The <CODE>natural-scaling=percent</CODE> value is a number
+from 1 to 800 specifying the size in relation to the natural
+image size. A scaling of 100 percent will print the image at its
+natural size, while a scaling of 50 percent will print the image
+at half its natural size. If the specified scaling makes the
+image larger than the page, multiple pages will be printed to
+satisfy the request.
+
+<H3>Adjusting the Hue (Tint) of an Image</H3>
+
+<P>The <CODE>-o hue=value</CODE> option will adjust the hue of the
+printed image, much like the tint control on your television:
+
+<UL><PRE>
+<B>lp -o hue=<I>value</I> filename ENTER</B>
+<B>lpr -o hue=<I>value</I> filename ENTER</B>
+</PRE></UL>
+
+<!-- NEED 3in -->
+<P>The <CODE>value</CODE> argument is a number from -360 to 360 and represents the
+color hue rotation. The following table summarizes the change you'll see with
+different colors:
+
+<CENTER><TABLE WIDTH="50%" BORDER="1">
+<TR>
+ <TH>Original</TH>
+ <TH>hue=-45</TH>
+ <TH>hue=45</TH>
+</TR>
+<TR>
+ <TD>Red</TD>
+ <TD>Purple</TD>
+ <TD>Yellow-orange</TD>
+</TR>
+<TR>
+ <TD>Green</TD>
+ <TD>Yellow-green</TD>
+ <TD>Blue-green</TD>
+</TR>
+<TR>
+ <TD>Yellow</TD>
+ <TD>Orange</TD>
+ <TD>Green-yellow</TD>
+</TR>
+<TR>
+ <TD>Blue</TD>
+ <TD>Sky-blue</TD>
+ <TD>Purple</TD>
+</TR>
+<TR>
+ <TD>Magenta</TD>
+ <TD>Indigo</TD>
+ <TD>Crimson</TD>
+</TR>
+<TR>
+ <TD>Cyan</TD>
+ <TD>Blue-green</TD>
+ <TD>Light-navy-blue</TD>
+</TR>
+</TABLE></CENTER>
+
+<P>The default hue adjustment is 0.
+
+<H3>Adjusting the Saturation (Color) of an Image</H3>
+
+<P>The <CODE>-o saturation=percent</CODE> option adjusts the saturation
+of the colors in an image, much like the color knob on your television:
+
+<UL><PRE>
+<B>lp -o saturation=<I>percent</I> filename ENTER</B>
+<B>lpr -o saturation=<I>percent</I> filename ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>percent</CODE> argument specifies the color saturation
+from 0 to 200. A color saturation of 0 produces a black-and-white
+print, while a value of 200 will make the colors extremely intense.
+
+<P>The default saturation is 100.
+
+<!-- NEED 4in -->
+<H2>HP-GL/2 Options</H2>
+
+<P>The following options apply to HP-GL/2 files.
+
+<H3>Printing in Black</H3>
+
+<P>The <CODE>-o blackplot</CODE> option specifies that all pens should
+plot in black:
+
+<UL><PRE>
+<B>lp -o blackplot filename ENTER</B>
+<B>lpr -o blackplot filename ENTER</B>
+</PRE></UL>
+
+<P>The default is to use the colors defined in the plot file or the
+standard pen colors defined in the HP-GL/2 reference manual from
+Hewlett Packard.
+
+<H3>Fitting the Plot on the Page</H3>
+
+<P>The <CODE>-o fitplot</CODE> option specifies that the plot should be
+scaled to fit on the page:
+
+<UL><PRE>
+<B>lp -o fitplot filename ENTER</B>
+<B>lpr -o fitplot filename ENTER</B>
+</PRE></UL>
+
+<P>The default is to use the absolute distances specified in the plot
+file.
+
+<CENTER><TABLE WIDTH="80%" CELLPADDING="5" BORDER="1" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>This feature depends upon an accurate plot size (<CODE>PS</CODE>)
+ command in the HP-GL/2 file. If no plot size is given in the file
+ than the HP-GL/2 filter assumes the plot is ANSI E size.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Setting the Default Pen Width</H3>
+
+<P>The <CODE>-o penwidth=value</CODE> option specifies the default pen
+width for HP-GL/2 files:
+
+<UL><PRE>
+<B>lp -o penwidth=<I>value</I> filename ENTER</B>
+<B>lpr -o penwidth=<I>value</I> filename ENTER</B>
+</PRE></UL>
+
+<P>The pen width <CODE>value</CODE> specifies the pen width in micrometers.
+The default value of 1000 produces lines that are 1 millimeter in width.
+Specifying a pen width of 0 produces lines that are exactly 1 pixel wide.
+
+<CENTER><TABLE WIDTH="80%" CELLPADDING="5" BORDER="1" BGCOLOR="#cccccc">
+<TR>
+ <TD>
+ <B>NOTE:</B>
+
+ <P>This option is ignored when the pen widths are set in the
+ plot file.
+ </TD>
+</TR>
+</TABLE></CENTER>
+
+<H2>Raw or Unfiltered Output</H2>
+
+<P>The <CODE>-o raw</CODE> option allows you to send files directly to
+a printer without filtering. This is sometimes required when printing
+from applications that provide their own "printer drivers" for your
+printer:
+
+<UL><PRE>
+<B>lp -o raw filename ENTER</B>
+<B>lpr -o raw filename ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>-l</CODE> option can also be used with the
+<CODE>lpr</CODE> command to send files directly to a printer:
+
+<UL><PRE>
+<B>lpr -l filename ENTER</B>
+</PRE></UL>
+
+
+<H1 ALIGN="RIGHT"><A NAME="SAVING_OPTIONS">4 - Saving Printer Options and Defaults</A></H1>
+
+<P>This chapter describes how to save printer options for your printer and
+set your own default printer.
+
+<H2>Printer Options</H2>
+
+<P>Each printer supports a large number of options, which you learned about
+in <A HREF="#STANDARD_OPTIONS">Chapter 3, "Standard Printer Options"</A>.
+Rather than specifying these options each time you print a file, CUPS allows
+you to save them as "default" options for the printer.
+
+<P>The <CODE>lpoptions(1)</CODE> command saves the options for your printers.
+Like the <CODE>lp</CODE> and <CODE>lpr</CODE> commands, it accepts printer
+options using the <CODE>-o</CODE> argument:
+
+<UL><PRE>
+<B>lpoptions -o prettyprint ENTER</B>
+<B>lpoptions -o media=A4 -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -o media=Legal -o scaling=100 ENTER</B>
+</PRE></UL>
+
+<P>Once saved, any <CODE>lp</CODE> or <CODE>lpr</CODE> command will
+use them when you print.
+
+<H2>Setting Options for a Specific Printer</H2>
+
+<P>The previous example shows how to set the options for the default
+printer. The <CODE>-p printer</CODE> option specifies the options are
+for another printer:
+
+<UL><PRE>
+<B>lpoptions -p laserjet -o prettyprint ENTER</B>
+<B>lpoptions -p laserjet -o media=A4 -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -p deskjet -o media=Legal -o scaling=100 ENTER</B>
+</PRE></UL>
+
+<H2>Removing Options</H2>
+
+<P>The previous two examples shows how to set options for the default
+and a specific printer. Below, shows you how to remove the saved
+option using the <CODE>-r</CODE> argument:
+
+<UL><PRE>
+<KBD>lpoptions -r prettyprint <I>ENTER</I></KBD>
+<KBD>lpoptions -p laserjet -r prettyprint <I>ENTER</I></KBD>
+</PRE></UL>
+
+<H2>Viewing the Current Defaults</H2>
+
+<P>The <CODE>lpoptions</CODE> command can also be used to show the current
+options by not specifying any new options on the command-line:
+
+<UL><PRE>
+<B>lpoptions ENTER</B>
+media=A4 sides=two-sided-long-edge
+<B>lpoptions -p deskjet ENTER</B>
+media=Legal scaling=100
+</PRE></UL>
+
+<H2>Viewing Options for a Specific Printer</H2>
+
+<P>You can display the supported options using the <CODE>lpoptions</CODE>
+command with the <CODE>-l</CODE> option, as follows:
+
+<UL><PRE>
+<B>lpoptions -p laserjet -l ENTER</B>
+</PRE></UL>
+
+<H2>Setting the Default Printer</H2>
+
+<P>The administrator normally will set a system-wide default printer
+that is normally used as the default printer by everyone. Use the
+<CODE>-d printer</CODE> option to set your own default printer:
+
+<UL><PRE>
+<B>lpoptions -d deskjet ENTER</B>
+</PRE></UL>
+
+<P>The printer can be local (<CODE>deskjet</CODE>) or remote
+(<CODE>deskjet@server</CODE>).
+
+<H2>Printer Instances</H2>
+
+<P>Besides setting options for each print queue, CUPS supports
+<I>printer instances</I> which allow you to define several different
+sets of options for each printer. You specify a printer instance using
+the slash (<CODE>/</CODE>) character:
+
+<UL><PRE>
+<B>lpoptions -p laserjet/duplex -o sides=two-sided-long-edge ENTER</B>
+<B>lpoptions -p laserjet/legal -o media=Legal ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>lp</CODE> and <CODE>lpr</CODE> commands also understand
+this notation:
+
+<UL><PRE>
+<B>lp -d laserjet/duplex filename ENTER</B>
+<B>lpr -P laserjet/legal filename ENTER</B>
+</PRE></UL>
+
+<H2>Removing Instances</H2>
+
+<P>Use the <CODE>-x printer/instance</CODE> option to remove a printer
+instance that you no longer need:
+
+<UL><PRE>
+<B>lpoptions -x laserjet ENTER</B>
+<B>lpoptions -x laserjet/duplex ENTER</B>
+<B>lpoptions -x laserjet/legal ENTER</B>
+</PRE></UL>
+
+<P>The <CODE>-x</CODE> option only removes the default options for that
+printer and instance; the original print queue will remain until deleted
+with the <CODE>lpadmin(8)</CODE> command by the administrator.
+
+
+<H1 ALIGN="RIGHT"><A NAME="LICENSE">A - Software License
+Agreement</A></H1>
+
+<EMBED SRC="../LICENSE.html">
+
+</BODY>
+</HTML>
diff --git a/doc/svd.html b/doc/svd.html
new file mode 100644
index 000000000..096bf4425
--- /dev/null
+++ b/doc/svd.html
@@ -0,0 +1,296 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Software Version Description</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 1997-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-SVD-1.1">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY>
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Software Version Description</H1></A><BR>
+CUPS-SVD-1.1<BR>
+Easy Software Products<BR>
+Copyright 1997-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">1 Scope</A></B>
+<UL>
+<LI><A HREF="#1_1">1.1 Identification</A></LI>
+<LI><A HREF="#1_2">1.2 System Overview</A></LI>
+<LI><A HREF="#1_3">1.3 Document Overview</A></LI>
+</UL>
+<B><A HREF="#2">2 References</A></B>
+<UL>
+<LI><A HREF="#2_1">2.1 CUPS Documentation</A></LI>
+<LI><A HREF="#2_2">2.2 Other Documents</A></LI>
+</UL>
+<B><A HREF="#3">3 Additions</A></B>
+<UL>
+<LI><A HREF="#3_1">3.1 Filters</A></LI>
+<UL>
+<LI><A HREF="#3_1_1">3.1.1 imagetoraster, imagetops</A></LI>
+<LI><A HREF="#3_1_2">3.1.2 pdftops</A></LI>
+<LI><A HREF="#3_1_3">3.1.3 pstoraster</A></LI>
+<LI><A HREF="#3_1_4">3.1.4 rastertoepson</A></LI>
+</UL>
+<LI><A HREF="#3_2">3.2 User-Defined Printers and Options</A></LI>
+<LI><A HREF="#3_3">3.3 Daemons</A></LI>
+<UL>
+<LI><A HREF="#3_3_1">3.3.1 cups-lpd</A></LI>
+<LI><A HREF="#3_3_2">3.3.2 cups-polld</A></LI>
+</UL>
+<LI><A HREF="#3_4">3.4 Commands</A></LI>
+<UL>
+<LI><A HREF="#3_4_1">3.4.1 lpoptions</A></LI>
+<LI><A HREF="#3_4_2">3.4.2 lpmove</A></LI>
+<LI><A HREF="#3_4_3">3.4.3 lpinfo</A></LI>
+</UL>
+<LI><A HREF="#3_5">3.5 IPP Implementation</A></LI>
+</UL>
+<B><A HREF="#4">4 Changes</A></B>
+<UL>
+<LI><A HREF="#4_1">4.1 Directory Structure</A></LI>
+<LI><A HREF="#4_2">4.2 IPP Implementation</A></LI>
+</UL>
+<B><A HREF="#5">A Glossary</A></B>
+<UL>
+<LI><A HREF="#5_1">A.1 Terms</A></LI>
+<LI><A HREF="#5_2">A.2 Acronyms</A></LI>
+</UL>
+<HR>
+<H1><A NAME="1">1 Scope</A></H1>
+<H2><A NAME="1_1">1.1 Identification</A></H2>
+ This software version description document provides release information
+ for the Common UNIX Printing System (&quot;CUPS&quot;) Version 1.1.
+<H2><A NAME="1_2">1.2 System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+<H2><A NAME="1_3">1.3 Document Overview</A></H2>
+<P>This software version description document is organized into the
+ following sections:</P>
+<UL>
+<LI><A HREF="#1">1 - Scope</A></LI>
+<LI><A HREF="#2">2 - References</A></LI>
+<LI><A HREF="#3">3 - Additions</A></LI>
+<LI><A HREF="#4">4 - Changes</A></LI>
+<LI><A HREF="#5">A - Glossary</A></LI>
+</UL>
+<H1><A NAME="2">2 References</A></H1>
+<H2><A NAME="2_1">2.1 CUPS Documentation</A></H2>
+<P>The following CUPS documentation is referenced by this document:</P>
+<UL>
+<LI>CUPS-CMP-1.1: CUPS Configuration Management Plan</LI>
+<LI>CUPS-IDD-1.1: CUPS System Interface Design Description</LI>
+<LI>CUPS-IPP-1.1: CUPS Implementation of IPP</LI>
+<LI>CUPS-SAM-1.1.x: CUPS Software Administrators Manual</LI>
+<LI>CUPS-SDD-1.1: CUPS Software Design Description</LI>
+<LI>CUPS-SPM-1.1.x: CUPS Software Programming Manual</LI>
+<LI>CUPS-SSR-1.1: CUPS Software Security Report</LI>
+<LI>CUPS-STP-1.1: CUPS Software Test Plan</LI>
+<LI>CUPS-SUM-1.1.x: CUPS Software Users Manual</LI>
+<LI>CUPS-SVD-1.1: CUPS Software Version Description</LI>
+</UL>
+<H2><A NAME="2_2">2.2 Other Documents</A></H2>
+<P>The following non-CUPS documents are referenced by this document:</P>
+<UL>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">
+Adobe PostScript Printer Description File Format Specification, Version
+ 4.3.</A></LI>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
+Adobe PostScript Language Reference, Third Edition.</A></LI>
+<LI>IPP: Job and Printer Set Operations</LI>
+<LI>IPP/1.1: Encoding and Transport</LI>
+<LI>IPP/1.1: Implementers Guide</LI>
+<LI>IPP/1.1: Model and Semantics</LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179, Line Printer
+ Daemon Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2567.txt">RFC 2567, Design Goals
+ for an Internet Printing Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2568.txt">RFC 2568, Rationale
+ for the Structure of the Model and Protocol for the Internet Printing
+ Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2569.txt">RFC 2569, Mapping
+ between LPD and IPP Protocols</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616, Hypertext
+ Transfer Protocol -- HTTP/1.1</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617, HTTP
+ Authentication: Basic and Digest Access</A> Authentication</LI>
+</UL>
+<H1><A NAME="3">3 Additions</A></H1>
+<P>CUPS 1.1 includes many new features from the 1.0.x releases.</P>
+<H2><A NAME="3_1">3.1 Filters</A></H2>
+<H3><A NAME="3_1_1">3.1.1 <CODE>imagetoraster</CODE>, <CODE>imagetops</CODE>
+</A></H3>
+<P>The image file filters have been upgraded to support conversion of
+ Microsoft Bitmap (&quot;BMP&quot;) and Alias PIX files.</P>
+<H3><A NAME="3_1_2">3.1.2 pdftops</A></H3>
+<P>A new pdftops filter has been developed that is based on the
+ excellent Xpdf 0.90 software from Derek B. Noonburg. The new filter is
+ faster, smaller, and considerably more reliable than the
+ Ghostscript-based filter in CUPS 1.0.</P>
+<H3><A NAME="3_1_3">3.1.3 pstoraster</A></H3>
+<P>The <CODE>pstoraster</CODE> filter has been integrated with GNU
+ GhostScript 5.50. The new RIP supports most Level 3 PostScript language
+ features.</P>
+<H3><A NAME="3_1_4">3.1.4 rastertoepson</A></H3>
+<P>The new <CODE>rastertoepson</CODE> filter supports EPSON printers
+ using the ESC/P or ESC/P2 command sets. PPDs are supplied for 9-pin,
+ 24-pin, Stylus Color, and Stylus Photo printers.</P>
+<H2><A NAME="3_2">3.2 User-Defined Printers and Options</A></H2>
+<P>The new <CODE>lpoptions</CODE> command allows users to configure
+ default document options and create additional &quot;instances&quot; of existing
+ printers, each with unique options.</P>
+<P>The <CODE>lp</CODE>, <CODE>lpr</CODE>, and <CODE>lpstat</CODE>
+ commands have been upgraded to use this option and printer instance
+ information automatically.</P>
+<H2><A NAME="3_3">3.3 Daemons</A></H2>
+<P>CUPS 1.1 includes two new daemons that provide enhanced network
+ printing support.</P>
+<H3><A NAME="3_3_1">3.3.1 cups-lpd</A></H3>
+<P>The <CODE>cups-lpd</CODE> daemon provides support for clients using
+ the Line Printer Daemon protocol.</P>
+<H3><A NAME="3_3_2">3.3.2 cups-polld</A></H3>
+<P>The <CODE>cups-polld</CODE> daemon provides remote polling services
+ for the scheduler.</P>
+<H2><A NAME="3_4">3.4 Commands</A></H2>
+<P>CUPS 1.1 includes several new printing commands.</P>
+<H3><A NAME="3_4_1">3.4.1 lpoptions</A></H3>
+<P>The <CODE>lpoptions</CODE> command provides user-defined printers and
+ options.</P>
+<H3><A NAME="3_4_2">3.4.2 lpmove</A></H3>
+<P>The <CODE>lpmove</CODE> command moves a print job to a new
+ destination.</P>
+<H3><A NAME="3_4_3">3.4.3 lpinfo</A></H3>
+<P>The <CODE>lpinfo</CODE> command lists the available PPD files or
+ devices.</P>
+<H2><A NAME="3_5">3.5 IPP Implementation</A></H2>
+<P>CUPS 1.1 adds support for the <CODE>set-job-attributes</CODE>
+ extension operation as well as two new CUPS-specific extension
+ operations to determine which devices and printer drivers are available
+ on the system.</P>
+<P>Further information on the CUPS implementation of IPP can be found in
+ CUPS-IPP-1.1.</P>
+<H1><A NAME="4">4 Changes</A></H1>
+<P>CUPS 1.1 includes many changes from the 1.0.x releases.</P>
+<H2><A NAME="4_1">4.1 Directory Structure</A></H2>
+<P>The directory structure in CUPS 1.1 has been modified to conform to
+ the Filesystem Hierarchy Standard, 2.0. The following table describes
+ the new file locations.
+<CENTER>
+<TABLE BORDER WIDTH="80%"><CAPTION> Table 1: Directory structure changes
+ from CUPS 1.0.x to 1.1.x.</CAPTION>
+<TR><TH>Description</TH><TH>CUPS 1.0.x</TH><TH>CUPS 1.1.x</TH></TR>
+<TR><TD>Backends</TD><TD>/var/cups/backend</TD><TD>/usr/lib/cups/backend</TD>
+</TR>
+<TR><TD>CGI programs</TD><TD>/var/cups/cgi-bin</TD><TD>
+/usr/lib/cups/cgi-bin</TD></TR>
+<TR><TD>Configuration files</TD><TD>/var/cups/conf</TD><TD>/etc/cups</TD>
+</TR>
+<TR><TD>Documentation</TD><TD>/usr/share/cups/doc</TD><TD>
+/usr/share/doc/cups</TD></TR>
+<TR><TD>Filter programs</TD><TD>/var/cups/filter</TD><TD>
+/usr/lib/cups/filter</TD></TR>
+<TR><TD>Interface scripts</TD><TD>/var/cups/interfaces</TD><TD>
+/etc/cups/interfaces</TD></TR>
+<TR><TD>Locale data</TD><TD>/usr/lib/locale</TD><TD>/usr/share/locale</TD>
+</TR>
+<TR><TD>Log files</TD><TD>/var/cups/logs</TD><TD>/var/log/cups</TD></TR>
+<TR><TD>PPD files</TD><TD>/var/cups/ppd</TD><TD>/etc/cups/ppd</TD></TR>
+<TR><TD>Request files</TD><TD>/var/cups/requests</TD><TD>/var/spool/cups</TD>
+</TR>
+</TABLE>
+</CENTER>
+</P>
+<H2><A NAME="4_2">4.2 IPP Implementation</A></H2>
+<P>CUPS 1.1 is based on version 1.1 of the Internet Printing Protocol.</P>
+<P>The new scheduler supports the <CODE>create-job</CODE> and <CODE>
+send-document</CODE> operations. In addition, the <CODE>job-sheets</CODE>
+, <CODE>job-sheets-default</CODE>, and <CODE>job-sheets-supported</CODE>
+ attributes are now supported for banner pages.</P>
+<P>The <CODE>CUPS-get-printers</CODE> and <CODE>CUPS-get-classes</CODE>
+ operations have been upgraded to support limited filtering based upon
+ the <CODE>printer-type</CODE>, <CODE>printer-location</CODE>, <CODE>
+printer-info</CODE>, and <CODE>printer-make-and-model</CODE> attributes.</P>
+<P>The <CODE>CUPS-add-printer</CODE> operation now supports the <CODE>
+ppd-name</CODE> attribute to specify a locally-available PPD file rather
+ than sending the PPD file from the client with the request.</P>
+<P>Further information on the CUPS implementation of IPP can be found in
+ CUPS-IPP-1.1.</P>
+<H1 TYPE="A" VALUE="1"><A NAME="5">A Glossary</A></H1>
+<H2><A NAME="5_1">A.1 Terms</A></H2>
+<DL>
+<DT>C</DT>
+<DD>A computer language.</DD>
+<DT>parallel</DT>
+<DD>Sending or receiving data more than 1 bit at a time.</DD>
+<DT>pipe</DT>
+<DD>A one-way communications channel between two programs.</DD>
+<DT>serial</DT>
+<DD>Sending or receiving data 1 bit at a time.</DD>
+<DT>socket</DT>
+<DD>A two-way network communications channel.</DD>
+</DL>
+<H2><A NAME="5_2">A.2 Acronyms</A></H2>
+<DL>
+<DT>ASCII</DT>
+<DD>American Standard Code for Information Interchange</DD>
+<DT>CUPS</DT>
+<DD>Common UNIX Printing System</DD>
+<DT>ESC/P</DT>
+<DD>EPSON Standard Code for Printers</DD>
+<DT>FTP</DT>
+<DD>File Transfer Protocol</DD>
+<DT>HP-GL</DT>
+<DD>Hewlett-Packard Graphics Language</DD>
+<DT>HP-PCL</DT>
+<DD>Hewlett-Packard Page Control Language</DD>
+<DT>HP-PJL</DT>
+<DD>Hewlett-Packard Printer Job Language</DD>
+<DT>IETF</DT>
+<DD>Internet Engineering Task Force</DD>
+<DT>IPP</DT>
+<DD>Internet Printing Protocol</DD>
+<DT>ISO</DT>
+<DD>International Standards Organization</DD>
+<DT>LPD</DT>
+<DD>Line Printer Daemon</DD>
+<DT>MIME</DT>
+<DD>Multimedia Internet Mail Exchange</DD>
+<DT>PPD</DT>
+<DD>PostScript Printer Description</DD>
+<DT>SMB</DT>
+<DD>Server Message Block</DD>
+<DT>TFTP</DT>
+<DD>Trivial File Transfer Protocol</DD>
+</DL>
+</BODY>
+</HTML>
diff --git a/doc/svd.pdf b/doc/svd.pdf
new file mode 100644
index 000000000..a757a1375
--- /dev/null
+++ b/doc/svd.pdf
Binary files differ
diff --git a/doc/svd.shtml b/doc/svd.shtml
new file mode 100644
index 000000000..b536bb200
--- /dev/null
+++ b/doc/svd.shtml
@@ -0,0 +1,212 @@
+<HTML>
+<HEAD>
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-SVD-1.1">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Software Version Description</TITLE>
+</HEAD>
+<BODY>
+
+<H1>Scope</H1>
+
+<H2>Identification</H2>
+
+This software version description document provides release information for the
+Common UNIX Printing System ("CUPS") Version 1.1.
+
+<EMBED SRC="system-overview.shtml">
+
+<H2>Document Overview</H2>
+
+<P>This software version description document is organized into the following
+sections:</P>
+
+<UL>
+ <LI><A HREF="#1">1 - Scope</A></LI>
+ <LI><A HREF="#2">2 - References</A></LI>
+ <LI><A HREF="#3">3 - Additions</A></LI>
+ <LI><A HREF="#4">4 - Changes</A></LI>
+ <LI><A HREF="#5">A - Glossary</A></LI>
+</UL>
+
+<EMBED SRC="references.shtml">
+
+<H1>Additions</H1>
+
+<P>CUPS 1.1 includes many new features from the 1.0.x releases.
+
+<H2>Filters</H2>
+
+<H3><CODE>imagetoraster</CODE>, <CODE>imagetops</CODE></H3>
+
+<P>The image file filters have been upgraded to support conversion of
+Microsoft Bitmap ("BMP") and Alias PIX files.
+
+<H3>pdftops</H3>
+
+<P>A new pdftops filter has been developed that is based on the
+excellent Xpdf 0.90 software from Derek B. Noonburg. The new filter is
+faster, smaller, and considerably more reliable than the
+Ghostscript-based filter in CUPS 1.0.
+
+<H3>pstoraster</H3>
+
+<P>The <CODE>pstoraster</CODE> filter has been integrated with GNU
+GhostScript 5.50. The new RIP supports most Level 3 PostScript language
+features.
+
+<H3>rastertoepson</H3>
+
+<P>The new <CODE>rastertoepson</CODE> filter supports EPSON printers
+using the ESC/P or ESC/P2 command sets. PPDs are supplied for 9-pin,
+24-pin, Stylus Color, and Stylus Photo printers.
+
+<H2>User-Defined Printers and Options</H2>
+
+<P>The new <CODE>lpoptions</CODE> command allows users to configure default
+document options and create additional "instances" of existing printers,
+each with unique options.
+
+<P>The <CODE>lp</CODE>, <CODE>lpr</CODE>, and <CODE>lpstat</CODE> commands
+have been upgraded to use this option and printer instance information
+automatically.
+
+<H2>Daemons</H2>
+
+<P>CUPS 1.1 includes two new daemons that provide enhanced network printing
+support.
+
+<H3>cups-lpd</H3>
+
+<P>The <CODE>cups-lpd</CODE> daemon provides support for clients using the
+Line Printer Daemon protocol.
+
+<H3>cups-polld</H3>
+
+<P>The <CODE>cups-polld</CODE> daemon provides remote polling services for
+the scheduler.
+
+<H2>Commands</H2>
+
+<P>CUPS 1.1 includes several new printing commands.
+
+<H3>lpoptions</H3>
+
+<P>The <CODE>lpoptions</CODE> command provides user-defined printers and
+options.
+
+<H3>lpmove</H3>
+
+<P>The <CODE>lpmove</CODE> command moves a print job to a new destination.
+
+<H3>lpinfo</H3>
+
+<P>The <CODE>lpinfo</CODE> command lists the available PPD files or devices.
+
+<H2>IPP Implementation</H2>
+
+<P>CUPS 1.1 adds support for the <CODE>set-job-attributes</CODE>
+extension operation as well as two new CUPS-specific extension
+operations to determine which devices and printer drivers are available
+on the system.
+
+<P>Further information on the CUPS implementation of IPP can be found
+in CUPS-IPP-1.1.
+
+
+<H1>Changes</H1>
+
+<P>CUPS 1.1 includes many changes from the 1.0.x releases.
+
+<H2>Directory Structure</H2>
+
+<P>The directory structure in CUPS 1.1 has been modified to conform to the
+Filesystem Hierarchy Standard, 2.0. The following table describes the
+new file locations.
+
+<CENTER><TABLE WIDTH="80%" BORDER>
+<CAPTION>Table 1: Directory structure changes from CUPS 1.0.x to 1.1.x.</CAPTION>
+<TR>
+ <TH>Description</TH>
+ <TH>CUPS 1.0.x</TH>
+ <TH>CUPS 1.1.x</TH>
+</TR>
+<TR>
+ <TD>Backends</TD>
+ <TD>/var/cups/backend</TD>
+ <TD>/usr/lib/cups/backend</TD>
+</TR>
+<TR>
+ <TD>CGI programs</TD>
+ <TD>/var/cups/cgi-bin</TD>
+ <TD>/usr/lib/cups/cgi-bin</TD>
+</TR>
+<TR>
+ <TD>Configuration files</TD>
+ <TD>/var/cups/conf</TD>
+ <TD>/etc/cups</TD>
+</TR>
+<TR>
+ <TD>Documentation</TD>
+ <TD>/usr/share/cups/doc</TD>
+ <TD>/usr/share/doc/cups</TD>
+</TR>
+<TR>
+ <TD>Filter programs</TD>
+ <TD>/var/cups/filter</TD>
+ <TD>/usr/lib/cups/filter</TD>
+</TR>
+<TR>
+ <TD>Interface scripts</TD>
+ <TD>/var/cups/interfaces</TD>
+ <TD>/etc/cups/interfaces</TD>
+</TR>
+<TR>
+ <TD>Locale data</TD>
+ <TD>/usr/lib/locale</TD>
+ <TD>/usr/share/locale</TD>
+</TR>
+<TR>
+ <TD>Log files</TD>
+ <TD>/var/cups/logs</TD>
+ <TD>/var/log/cups</TD>
+</TR>
+<TR>
+ <TD>PPD files</TD>
+ <TD>/var/cups/ppd</TD>
+ <TD>/etc/cups/ppd</TD>
+</TR>
+<TR>
+ <TD>Request files</TD>
+ <TD>/var/cups/requests</TD>
+ <TD>/var/spool/cups</TD>
+</TR>
+</TABLE></CENTER>
+
+<H2>IPP Implementation</H2>
+
+<P>CUPS 1.1 is based on version 1.1 of the Internet Printing Protocol.
+
+<P>The new scheduler supports the <CODE>create-job</CODE> and
+<CODE>send-document</CODE> operations. In addition, the
+<CODE>job-sheets</CODE>, <CODE>job-sheets-default</CODE>, and
+<CODE>job-sheets-supported</CODE> attributes are now supported for
+banner pages.
+
+<P>The <CODE>CUPS-get-printers</CODE> and <CODE>CUPS-get-classes</CODE>
+operations have been upgraded to support limited filtering based upon
+the <CODE>printer-type</CODE>, <CODE>printer-location</CODE>,
+<CODE>printer-info</CODE>, and <CODE>printer-make-and-model</CODE>
+attributes.
+
+<P>The <CODE>CUPS-add-printer</CODE> operation now supports the
+<CODE>ppd-name</CODE> attribute to specify a locally-available PPD file
+rather than sending the PPD file from the client with the request.
+
+<P>Further information on the CUPS implementation of IPP can be found
+in CUPS-IPP-1.1.
+
+<EMBED SRC="glossary.shtml">
+
+</BODY>
+</HTML>
diff --git a/doc/system-overview.shtml b/doc/system-overview.shtml
new file mode 100644
index 000000000..54b7df5e9
--- /dev/null
+++ b/doc/system-overview.shtml
@@ -0,0 +1,19 @@
+<H2>System Overview</H2>
+
+<P>CUPS provides a portable printing layer for UNIX&reg;-based
+operating systems. It has been developed by
+<A HREF="http://www.easysw.com">Easy Software Products</A> to promote a
+standard printing solution for all UNIX vendors and users. CUPS
+provides the System V and Berkeley command-line interfaces.
+
+<P>CUPS uses the Internet Printing Protocol ("IPP") as the basis for
+managing print jobs and queues. The Line Printer Daemon ("LPD") Server
+Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are
+also supported with reduced functionality. CUPS adds network printer
+browsing and PostScript Printer Description ("PPD") based
+printing options to support real-world printing under UNIX.
+
+<P>CUPS also includes a customized version of GNU Ghostscript
+(currently based off GNU Ghostscript 5.50) and an image file RIP that
+are used to support non-PostScript printers. Sample drivers for HP and
+EPSON printers are included that use these filters.
diff --git a/doc/translation.html b/doc/translation.html
new file mode 100644
index 000000000..f3e352e8a
--- /dev/null
+++ b/doc/translation.html
@@ -0,0 +1,605 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+<TITLE>CUPS Translation Guide</TITLE>
+<META NAME="author" CONTENT="Easy Software Products">
+<META NAME="copyright" CONTENT="Copyright 2001-2002, All Rights Reserved">
+<META NAME="docnumber" CONTENT="CUPS-TRANS-1.1">
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso-8859-1">
+<STYLE TYPE="text/css"><!--
+BODY { font-family: serif }
+H1 { font-family: sans-serif }
+H2 { font-family: sans-serif }
+H3 { font-family: sans-serif }
+H4 { font-family: sans-serif }
+H5 { font-family: sans-serif }
+H6 { font-family: sans-serif }
+SUB { font-size: smaller }
+SUP { font-size: smaller }
+PRE { font-family: monospace }
+--></STYLE>
+</HEAD>
+<BODY>
+<CENTER><A HREF="#CONTENTS"><IMG SRC="images/cups-large.gif" BORDER="0" WIDTH="431" HEIGHT="511"><BR>
+<H1>CUPS Translation Guide</H1></A><BR>
+CUPS-TRANS-1.1<BR>
+Easy Software Products<BR>
+Copyright 2001-2002, All Rights Reserved<BR>
+</CENTER>
+<HR>
+<H1 ALIGN="CENTER"><A NAME="CONTENTS">Table of Contents</A></H1>
+<BR>
+<BR><B><A HREF="#1">1 Scope</A></B>
+<UL>
+<LI><A HREF="#1_1">1.1 Identification</A></LI>
+<LI><A HREF="#1_2">1.2 System Overview</A></LI>
+<LI><A HREF="#1_3">1.3 Document Overview</A></LI>
+</UL>
+<B><A HREF="#2">2 References</A></B>
+<UL>
+<LI><A HREF="#2_1">2.1 CUPS Documentation</A></LI>
+<LI><A HREF="#2_2">2.2 Other Documents</A></LI>
+</UL>
+<B><A HREF="#3">3 Character Sets</A></B>
+<BR>
+<BR><B><A HREF="#4">4 Message Catalogs</A></B>
+<BR>
+<BR><B><A HREF="#5">5 Web Interfaces</A></B>
+<UL>
+<LI><A HREF="#5_1">5.1 Template Files</A></LI>
+<UL>
+<LI><A HREF="#5_1_1">5.1.1 Inserting Attributes and Values</A></LI>
+<LI><A HREF="#5_1_2">5.1.2 Array Substitutions</A></LI>
+<LI><A HREF="#5_1_3">5.1.3 Conditional Tests</A></LI>
+<LI><A HREF="#5_1_4">5.1.4 Template File List</A></LI>
+</UL>
+<LI><A HREF="#5_2">5.2 CGI Programs</A></LI>
+<UL>
+<LI><A HREF="#5_2_1">5.2.1 admin.cgi</A></LI>
+<LI><A HREF="#5_2_2">5.2.2 classes.cgi</A></LI>
+<LI><A HREF="#5_2_3">5.2.3 jobs.cgi</A></LI>
+<LI><A HREF="#5_2_4">5.2.4 printers.cgi</A></LI>
+</UL>
+</UL>
+<B><A HREF="#6">A Glossary</A></B>
+<UL>
+<LI><A HREF="#6_1">A.1 Terms</A></LI>
+<LI><A HREF="#6_2">A.2 Acronyms</A></LI>
+</UL>
+<HR>
+<H1><A NAME="1">1 Scope</A></H1>
+<H2><A NAME="1_1">1.1 Identification</A></H2>
+<P>This translation guide provides instructions for creating
+ translations of the CUPS message catalogs and web pages for the Common
+ UNIX Printing System (&quot;CUPS&quot;) Version 1.1 software.</P>
+<H2><A NAME="1_2">1.2 System Overview</A></H2>
+<P>CUPS provides a portable printing layer for UNIX&reg;-based operating
+ systems. It has been developed by<A HREF="http://www.easysw.com"> Easy
+ Software Products</A> to promote a standard printing solution for all
+ UNIX vendors and users. CUPS provides the System V and Berkeley
+ command-line interfaces.</P>
+<P>CUPS uses the Internet Printing Protocol (&quot;IPP&quot;) as the basis for
+ managing print jobs and queues. The Line Printer Daemon (&quot;LPD&quot;) Server
+ Message Block (&quot;SMB&quot;), and AppSocket (a.k.a. JetDirect) protocols are
+ also supported with reduced functionality. CUPS adds network printer
+ browsing and PostScript Printer Description (&quot;PPD&quot;) based printing
+ options to support real-world printing under UNIX.</P>
+<P>CUPS also includes a customized version of GNU Ghostscript (currently
+ based off GNU Ghostscript 5.50) and an image file RIP that are used to
+ support non-PostScript printers. Sample drivers for HP and EPSON
+ printers are included that use these filters.</P>
+<H2><A NAME="1_3">1.3 Document Overview</A></H2>
+<P>This translation guide is organized into the following sections:</P>
+<UL>
+<LI>1 - Scope</LI>
+<LI>2 - References</LI>
+<LI>3 - Character Sets</LI>
+<LI>4 - Message Catalogs</LI>
+<LI>5 - Web Interfaces</LI>
+<LI>A - Glossary</LI>
+</UL>
+<H1><A NAME="2">2 References</A></H1>
+<H2><A NAME="2_1">2.1 CUPS Documentation</A></H2>
+<P>The following CUPS documentation is referenced by this document:</P>
+<UL>
+<LI>CUPS-CMP-1.1: CUPS Configuration Management Plan</LI>
+<LI>CUPS-IDD-1.1: CUPS System Interface Design Description</LI>
+<LI>CUPS-IPP-1.1: CUPS Implementation of IPP</LI>
+<LI>CUPS-SAM-1.1.x: CUPS Software Administrators Manual</LI>
+<LI>CUPS-SDD-1.1: CUPS Software Design Description</LI>
+<LI>CUPS-SPM-1.1.x: CUPS Software Programming Manual</LI>
+<LI>CUPS-SSR-1.1: CUPS Software Security Report</LI>
+<LI>CUPS-STP-1.1: CUPS Software Test Plan</LI>
+<LI>CUPS-SUM-1.1.x: CUPS Software Users Manual</LI>
+<LI>CUPS-SVD-1.1: CUPS Software Version Description</LI>
+</UL>
+<H2><A NAME="2_2">2.2 Other Documents</A></H2>
+<P>The following non-CUPS documents are referenced by this document:</P>
+<UL>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/5003.PPD_Spec_v4.3.pdf">
+Adobe PostScript Printer Description File Format Specification, Version
+ 4.3.</A></LI>
+<LI><A HREF="http://partners.adobe.com/asn/developer/PDFS/TN/PLRM.pdf">
+Adobe PostScript Language Reference, Third Edition.</A></LI>
+<LI>IPP: Job and Printer Set Operations</LI>
+<LI>IPP/1.1: Encoding and Transport</LI>
+<LI>IPP/1.1: Implementers Guide</LI>
+<LI>IPP/1.1: Model and Semantics</LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc1179.txt">RFC 1179, Line Printer
+ Daemon Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2567.txt">RFC 2567, Design Goals
+ for an Internet Printing Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2568.txt">RFC 2568, Rationale
+ for the Structure of the Model and Protocol for the Internet Printing
+ Protocol</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2569.txt">RFC 2569, Mapping
+ between LPD and IPP Protocols</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616, Hypertext
+ Transfer Protocol -- HTTP/1.1</A></LI>
+<LI><A HREF="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617, HTTP
+ Authentication: Basic and Digest Access</A> Authentication</LI>
+</UL>
+<H1><A NAME="3">3 Character Sets</A></H1>
+<P>CUPS uses character set files to define the mapping of local
+ character sets to Unicode code points, as well as the fonts that should
+ be used for different ranges of characters.</P>
+<P>CUPS includes files for common 8-bit encodings as well as UTF-8 for
+ Unicode text. The format of these files is described in the CUPS
+ Interface Design Description (IDD) document. Current character sets are
+ enumerated in the CUPS API, so in order to add a new character set you
+ must patch the CUPS source as well as provide a new charset file.</P>
+<P>CUPS 1.1 supports the following character sets:</P>
+<UL>
+<LI>iso-8859-1</LI>
+<LI>iso-8859-2</LI>
+<LI>iso-8859-3</LI>
+<LI>iso-8859-4</LI>
+<LI>iso-8859-5</LI>
+<LI>iso-8859-6</LI>
+<LI>iso-8859-7</LI>
+<LI>iso-8859-8</LI>
+<LI>iso-8859-9</LI>
+<LI>iso-8859-10</LI>
+<LI>iso-8859-13</LI>
+<LI>iso-8859-14</LI>
+<LI>iso-8859-15</LI>
+<LI>koi8-r</LI>
+<LI>koi8-u</LI>
+<LI>us-ascii</LI>
+<LI>utf-8</LI>
+<LI>windows-874</LI>
+<LI>windows-1250</LI>
+<LI>windows-1251</LI>
+<LI>windows-1252</LI>
+<LI>windows-1253</LI>
+<LI>windows-1254</LI>
+<LI>windows-1255</LI>
+<LI>windows-1256</LI>
+<LI>windows-1257</LI>
+<LI>windows-1258</LI>
+</UL>
+<H1><A NAME="4">4 Message Catalogs</A></H1>
+<P>CUPS message catalogs are text files that identify the default
+ character set for the locale and a list of localized message strings
+ for the CUPS software. The format of the message catalog files is
+ described in the CUPS IDD.</P>
+<P>Message catalogs are named<VAR> cups_ll</VAR>,<VAR> cups_ll_CC</VAR>,
+ or<VAR> cups_ll_CC.charset</VAR>, where &quot;ll&quot; is the standard 2-letter
+ abbreviation for the language, &quot;CC&quot; is the standard 2-letter
+ abbreviation for the country, and &quot;charset&quot; is the charset name which
+ may differ from the list above.</P>
+<P>Each message catalog file is stored in a subdirectory named<VAR> ll</VAR>
+,<VAR> ll_CC</VAR>, or<VAR> ll_CC.charset</VAR> to match the trailing
+ portion of the message catalog filename.</P>
+<P>When translating a new message catalog, copy the<VAR> cups_C</VAR>
+ message catalog file to a new subdirectory; to translate the message
+ catalog to Canadian French, you would type the following commands:</P>
+<UL>
+<PRE>
+<KBD>cd locale <I>ENTER</I></KBD>
+<KBD>mkdir fr_CA <I>ENTER</I></KBD>
+<KBD>cp C/cups_C fr_CA/cups_fr_CA <I>ENTER</I></KBD>
+</PRE>
+</UL>
+<P>Alternatively, you could copy the existing<VAR> cups_fr</VAR> message
+ catalog and then make any changes necessary.</P>
+<P>Once you have make your copy of the file, edit it using your favorite
+ text editor to translate the text to the desired language. Be sure to
+ preserve any numbers starting in the first column, as they indicate a
+ new message number - you'll see this for the HTTP status messages.</P>
+<P>Finally, add your locale to the list of locales in the makefile and
+ run the following command to install it:</P>
+<UL>
+<PRE>
+<KBD>make install <I>ENTER</I></KBD>
+</PRE>
+</UL>
+<H1><A NAME="5">5 Web Interfaces</A></H1>
+<P>The CUPS scheduler provides a web interface that can be used to do
+ many common printing and administration tasks. The built-in web server
+ supports localization of web pages through the use of subdirectories
+ for each locale, e.g. &quot;fr&quot; for French, &quot;de&quot; for German, &quot;fr_ca&quot; for
+ French in Canada, and so forth.</P>
+<H2><A NAME="5_1">5.1 Template Files</A></H2>
+<P>Template files are HTML files with special formatting characters in
+ them that allow substition of variables and arrays. The CUPS CGI
+ programs (<CODE>admin.cgi</CODE>, <CODE>classes.cgi</CODE>, <CODE>
+jobs.cgi</CODE>, and <CODE>printers.cgi</CODE>) use these template file
+ to provide dynamic content for the web interface. Template files are
+ installed in the<VAR> /usr/share/cups/templates</VAR> directory by
+ default.</P>
+<P>Translated versions of the template files should be installed in the
+ appropriate subdirectories under<VAR> /usr/share/cups/templates</VAR>.
+ For example, Canadian French template files should be stored in the<VAR>
+ /usr/share/cups/templates/fr_CA</VAR> directory.</P>
+<H3><A NAME="5_1_1">5.1.1 Inserting Attributes and Values</A></H3>
+<P>Template files consist of HTML with variable substitutions for named
+ inside curley braces &quot;{name}&quot;. Variable names are generally the IPP
+ attribute names with the hyphen (&quot;-&quot;) replaced by the underscore (&quot;_&quot;)
+ character. For example, the <TT>job-printer-uri</TT> attribute is
+ renamed to <TT>job_printer_uri</TT>.</P>
+<P>Curley braces (&quot;{&quot; and &quot;}&quot;) to indicate substitutions, and the
+ backslash (&quot;\&quot;) character for quoting. To insert any of these special
+ characters as-is you need to use the HTML <CODE>&amp;name;</CODE> mechanism
+ or prefix each special character with the backslash (&quot;\&quot;.)</P>
+<P>You substitute the value of a variable using <CODE>{NAME}</CODE> in
+ your template file. If the variable is undefined then the <CODE>{NAME}</CODE>
+ string is output as-is.</P>
+<P>To substitute an empty string if the variable is undefined, use <CODE>
+{?NAME}</CODE> instead.</P>
+<H3><A NAME="5_1_2">5.1.2 Array Substitutions</A></H3>
+<P>The number of array elements can be inserted using <CODE>{#NAME}</CODE>
+. If the array is undefined then 0 is output. The current array element
+ (starting at 1) is inserted with <CODE>{#}</CODE>.</P>
+<P>Arrays are handled using <CODE>{[NAME]</CODE> at the beginning of a
+ section and <CODE>}</CODE> at the end. The information between the
+ closing bracket (&quot;]&quot;) and closing brace (&quot;}&quot;) is repeated for as many
+ elements as are in the named array. For example, the following template
+ will display a list of each job in the <CODE>job_id</CODE> array:</P>
+<UL>
+<PRE>
+&lt;TABLE&gt;
+&lt;TR&gt;
+ &lt;TH&gt;Job ID&lt;/TH&gt;
+ &lt;TH&gt;Destination&lt;/TH&gt;
+ &lt;TH&gt;Title&lt;/TH&gt;
+&lt;/TR&gt;
+
+{[job_id]
+&lt;TR&gt;
+ &lt;TD&gt;{?job_id}&lt;/TD&gt;
+ &lt;TD&gt;{?job_printer_name}&lt;/TD&gt;
+ &lt;TD&gt;{?job_name}&lt;/TD&gt;
+&lt;/TR&gt;
+}
+&lt;/TABLE&gt;
+</PRE>
+</UL>
+<P>Arrays can be nested, however all elements within the curley braces
+ (&quot;{&quot; and &quot;}&quot;) are indexed using the innermost array.</P>
+<H3><A NAME="5_1_3">5.1.3 Conditional Tests</A></H3>
+<P>Templates can also test variables against specific values and
+ conditionally include text in the template. The format is:</P>
+<UL>
+<PRE>
+{<I>variable</I>?<I>true</I>:<I>false</I>}
+{<I>variable</I>=<I>value</I>?<I>true</I>:<I>false</I>}
+{<I>variable</I>!<I>value</I>?<I>true</I>:<I>false</I>}
+{<I>variable</I>&lt;<I>value</I>?<I>true</I>:<I>false</I>}
+{<I>variable</I>&gt;<I>value</I>?<I>true</I>:<I>false</I>}
+</PRE>
+</UL>
+<P>where<VAR> true</VAR> is the text that is included if the condition
+ is true and<VAR> false</VAR> is the text that is included if the
+ condition is false. A value of <CODE>#</CODE> is replaced with the
+ current element number (starting at 1.)</P>
+<P>The character after the variable name specifies the condition to
+ test:
+<CENTER>
+<TABLE BORDER="1">
+<TR><TH WIDTH="5%">Char</TH><TH WIDTH="50%">Condition</TH></TR>
+<TR><TD>?</TD><TD>True if<VAR> variable</VAR> exists.</TD></TR>
+<TR><TD>=</TD><TD>True if<VAR> variable</VAR> is equal to<VAR> value</VAR>
+.</TD></TR>
+<TR><TD>!</TD><TD>True if<VAR> variable</VAR> is not equal to<VAR> value</VAR>
+.</TD></TR>
+<TR><TD>&lt;</TD><TD>True if<VAR> variable</VAR> is less than<VAR> value</VAR>
+.</TD></TR>
+<TR><TD>&gt;</TD><TD>True if<VAR> variable</VAR> is greater than<VAR> value</VAR>
+.</TD></TR>
+</TABLE>
+</CENTER>
+</P>
+<H3><A NAME="5_1_4">5.1.4 Template File List</A></H3>
+<P>The following template files are used by the web interface:</P>
+<DL>
+<DT>add-class.tmpl</DT>
+<DD>This is the initial form that is shown to add a new printer class.</DD>
+<DT>add-printer.tmpl</DT>
+<DD>This is the initial form that is shown to add a new printer.</DD>
+<DT>admin-op.tmpl</DT>
+<DD>This is the template that is used to display an error message when
+ the admin interface sees an undefined operation name.</DD>
+<DT>admin.tmpl</DT>
+<DD>This is the template that shows the initial menu of operations (add
+ a class, manage classes, etc.)</DD>
+<DT>choose-device.tmpl</DT>
+<DD>This is the form that shows the list of available devices.</DD>
+<DT>choose-make.tmpl</DT>
+<DD>This is the form that shows the list of available manufacturers.</DD>
+<DT>choose-members.tmpl</DT>
+<DD>This is the form that shows the list of available printers that can
+ be added to a class.</DD>
+<DT>choose-model.tmpl</DT>
+<DD>This is the form that shows the list of available printer
+ models/drivers.</DD>
+<DT>choose-serial.tmpl</DT>
+<DD>This is the form that allows the user to choose a serial port and
+ any options.</DD>
+<DT>choose-uri.tmpl</DT>
+<DD>This is the form that allows the user to enter a device URI for
+ network printers.</DD>
+<DT>class-added.tmpl</DT>
+<DD>This template shows the &quot;class added&quot; message.</DD>
+<DT>class-confirm.tmpl</DT>
+<DD>This is the template used to confirm the deletion of a class.</DD>
+<DT>class-deleted.tmpl</DT>
+<DD>This template shows the &quot;class deleted&quot; message.</DD>
+<DT>classes.tmpl</DT>
+<DD>This template shows one or more printer classes.</DD>
+<DT>class-modified.tmpl</DT>
+<DD>This template shows the &quot;class modified&quot; message.</DD>
+<DT>config-printer.tmpl</DT>
+<DD>This template starts the printer configuration form.</DD>
+<DT>config-printer2.tmpl</DT>
+<DD>This template ends the printer configuration form.</DD>
+<DT>error.tmpl</DT>
+<DD>This template displays a generic error message.</DD>
+<DT>header.tmpl</DT>
+<DD>This template is used as the standard header on all dynamic content.</DD>
+<DT>job-cancel.tmpl</DT>
+<DD>This template shows &quot;job cancelled&quot;.</DD>
+<DT>job-hold.tmpl</DT>
+<DD>This template shows &quot;job held&quot;.</DD>
+<DT>job-op.tmpl</DT>
+<DD>This is the template that is used to display an error message when
+ the job interface sees an undefined operation name.</DD>
+<DT>job-release.tmpl</DT>
+<DD>This template shows &quot;job released&quot;.</DD>
+<DT>job-restart.tmpl</DT>
+<DD>This template shows &quot;job restarted&quot;.</DD>
+<DT>jobs.tmpl</DT>
+<DD>This template is used to list the print jobs on a server, class, or
+ printer.</DD>
+<DT>modify-class.tmpl</DT>
+<DD>This template is used as the first form when modifying a class.</DD>
+<DT>modify-printer.tmpl</DT>
+<DD>This template is used as the first form when modifying a printer.</DD>
+<DT>option-boolean.tmpl</DT>
+<DD>This template is used to select a boolean PPD option.</DD>
+<DT>option-header.tmpl</DT>
+<DD>This template is used to start a PPD option group.</DD>
+<DT>option-pickmany.tmpl</DT>
+<DD>This template is used to select a multi-valued PPD option.</DD>
+<DT>option-pickone.tmpl</DT>
+<DD>This template is used to select a single-valued PPD option.</DD>
+<DT>option-trailer.tmpl</DT>
+<DD>This template is used to end a PPD option group.</DD>
+<DT>printer-accept.tmpl</DT>
+<DD>This template shows &quot;printer now accepting jobs&quot;.</DD>
+<DT>printer-added.tmpl</DT>
+<DD>This template shows &quot;printer added&quot;.</DD>
+<DT>printer-configured.tmpl</DT>
+<DD>This template shows &quot;printer configured&quot;.</DD>
+<DT>printer-confirm.tmpl</DT>
+<DD>This template asks the user to confirm the deletion of a printer.</DD>
+<DT>printer-deleted.tmpl</DT>
+<DD>This template shows &quot;printer deleted&quot;.</DD>
+<DT>printer-modified.tmpl</DT>
+<DD>This template shows &quot;printer modified&quot;.</DD>
+<DT>printer-purge.tmpl</DT>
+<DD>This template shows &quot;printer has been purged of all jobs&quot;.</DD>
+<DT>printer-reject.tmpl</DT>
+<DD>This template shows &quot;printer now rejecting jobs&quot;.</DD>
+<DT>printer-start.tmpl</DT>
+<DD>This template shows &quot;printer started&quot;.</DD>
+<DT>printers.tmpl</DT>
+<DD>This template is used to list information on one or more printers.</DD>
+<DT>printer-stop.tmpl</DT>
+<DD>This template shows &quot;printer stopped&quot;.</DD>
+<DT>test-page.tmpl</DT>
+<DD>This template shows &quot;test page printed&quot;.</DD>
+<DT>trailer.tmpl</DT>
+<DD>This template is used as the standard trailer on all dynamic
+ content.</DD>
+</DL>
+<H2><A NAME="5_2">5.2 CGI Programs</A></H2>
+<P>CUPS uses four CGI programs to manage the dynamic web interfaces:</P>
+<UL>
+<LI><CODE>admin.cgi</CODE></LI>
+<LI><CODE>classes.cgi</CODE></LI>
+<LI><CODE>jobs.cgi</CODE></LI>
+<LI><CODE>printers.cgi</CODE></LI>
+</UL>
+<H3><A NAME="5_2_1">5.2.1 admin.cgi</A></H3>
+<P>The <CODE>admin.cgi</CODE> program handles all of the printer and
+ class administration functions and is run for all direct accesses to
+ the<VAR> /admin</VAR> resource. For most operations it uses the <CODE>
+PRINTER_NAME</CODE> and <CODE>OP</CODE> form variables to specify the
+ action requested.</P>
+<P>The following <CODE>OP</CODE> values are supported:</P>
+<DL>
+<DT>accept-jobs</DT>
+<DD>Accepts jobs on the named destination.</DD>
+<DT>add-class</DT>
+<DD>Adds a new printer class. This operation also adds several other
+ form variables:
+<DL>
+<DT>MEMBER_URIS</DT>
+<DD>Sets the members of the class. Multiple <CODE>MEMBER_URIS</CODE>
+ values can be provided.</DD>
+<DT>PRINTER_INFO</DT>
+<DD>Sets the printer-info attribute for the printer class, which is
+ usually the printer description.</DD>
+<DT>PRINTER_LOCATION</DT>
+<DD>Sets the printer-location attribute for the printer class.</DD>
+</DL>
+</DD>
+<DT>add-printer</DT>
+<DD>Adds a new printer. This operation also adds several other form
+ variables:
+<DL>
+<DT>BAUDRATE</DT>
+<DD>Sets the baud rate for serial devices.</DD>
+<DT>BITS</DT>
+<DD>Sets the number of data bits for serial devices.</DD>
+<DT>DEVICE_URI</DT>
+<DD>Sets the device URI for the printer.</DD>
+<DT>FLOW</DT>
+<DD>Sets the flow control for serial devices.</DD>
+<DT>PARITY</DT>
+<DD>Sets the parity checking for serial devices.</DD>
+<DT>PPD_NAME</DT>
+<DD>Sets the driver name for the printer (&quot;raw&quot; for a raw queue.)</DD>
+<DT>PRINTER_INFO</DT>
+<DD>Sets the printer-info attribute for the printer, which is usually
+ the printer description.</DD>
+<DT>PRINTER_LOCATION</DT>
+<DD>Sets the printer-location attribute for the printer.</DD>
+</DL>
+</DD>
+<DT>config-printer</DT>
+<DD>Configures an existing printer. This operation uses form variables
+ of the same name as the options in the printer's PPD file.</DD>
+<DT>delete-class</DT>
+<DD>Deletes a printer class. The form variable <CODE>CONFIRM</CODE> may
+ be set to any value to bypass the confirmation page.</DD>
+<DT>delete-printer</DT>
+<DD>Deletes a printer. The form variable <CODE>CONFIRM</CODE> may be set
+ to any value to bypass the confirmation page.</DD>
+<DT>modify-class</DT>
+<DD>Modifies a printer class. See the add-class operation for a list of
+ form variables.</DD>
+<DT>modify-printer</DT>
+<DD>Modifies a printer. See the add-printer operation for a list of form
+ variables.</DD>
+<DT>purge-jobs</DT>
+<DD>Purges all jobs on the named destination.</DD>
+<DT>reject-jobs</DT>
+<DD>Rejects new jobs on the named destination.</DD>
+<DT>start-printer</DT>
+<DD>Starts the named destination.</DD>
+<DT>stop-printer</DT>
+<DD>Stops the named destination.</DD>
+</DL>
+<H3><A NAME="5_2_2">5.2.2 classes.cgi</A></H3>
+<P>The <CODE>classes.cgi</CODE> program is responsible for listing class
+ information, including jobs destined for that class. It is for all
+ direct accesses to the<VAR> /classes</VAR> resource and supports the
+ optional form variables <CODE>OP</CODE> and <CODE>WHICH_JOBS</CODE>. If
+ no form variables are supplied then the CGI lists all or a specific
+ class and the active jobs on each class.</P>
+<P>The following <CODE>WHICH_JOBS</CODE> values are supported:</P>
+<DL>
+<DT>completed</DT>
+<DD>Show only the completed jobs.</DD>
+<DT>not-completed</DT>
+<DD>Show only the active jobs.</DD>
+</DL>
+<P>The following <CODE>OP</CODE> values are supported:</P>
+<DL>
+<DT>print-test-page</DT>
+<DD>Print a PostScript test page.</DD>
+</DL>
+<H3><A NAME="5_2_3">5.2.3 jobs.cgi</A></H3>
+<P>The <CODE>jobs.cgi</CODE> program handles all of the job functions
+ and is run for all direct accesses to the<VAR> /jobs</VAR> resource.
+ For most operations it uses the <CODE>JOB_ID</CODE>, <CODE>OP</CODE>,
+ and <CODE>WHICH_JOBS</CODE> form variables to specify the action
+ requested.</P>
+<P>The following <CODE>WHICH_JOBS</CODE> values are supported:</P>
+<DL>
+<DT>completed</DT>
+<DD>Show only the completed jobs.</DD>
+<DT>not-completed</DT>
+<DD>Show only the active jobs.</DD>
+</DL>
+<P>The following <CODE>OP</CODE> values are supported:</P>
+<DL>
+<DT>job-cancel</DT>
+<DD>Cancels a job.</DD>
+<DT>job-hold</DT>
+<DD>Holds a job indefinitely.</DD>
+<DT>job-release</DT>
+<DD>Releases a job for printing.</DD>
+<DT>job-restart</DT>
+<DD>Restarts a stopped, cancelled, completed, or aborted print job.</DD>
+</DL>
+<H3><A NAME="5_2_4">5.2.4 printers.cgi</A></H3>
+<P>The <CODE>printers.cgi</CODE> program is responsible for listing
+ printer information, including jobs destined for that printer. It is
+ for all direct accesses to the<VAR> /printers</VAR> resource and
+ supports the optional form variables <CODE>OP</CODE> and <CODE>
+WHICH_JOBS</CODE>. If no form variables are supplied then the CGI lists
+ all or a specific printer and the active jobs on each printer.</P>
+<P>The following <CODE>WHICH_JOBS</CODE> values are supported:</P>
+<DL>
+<DT>completed</DT>
+<DD>Show only the completed jobs.</DD>
+<DT>not-completed</DT>
+<DD>Show only the active jobs.</DD>
+</DL>
+<P>The following <CODE>OP</CODE> values are supported:</P>
+<DL>
+<DT>print-test-page</DT>
+<DD>Print a PostScript test page.</DD>
+</DL>
+<H1 TYPE="A" VALUE="1"><A NAME="6">A Glossary</A></H1>
+<H2><A NAME="6_1">A.1 Terms</A></H2>
+<DL>
+<DT>C</DT>
+<DD>A computer language.</DD>
+<DT>parallel</DT>
+<DD>Sending or receiving data more than 1 bit at a time.</DD>
+<DT>pipe</DT>
+<DD>A one-way communications channel between two programs.</DD>
+<DT>serial</DT>
+<DD>Sending or receiving data 1 bit at a time.</DD>
+<DT>socket</DT>
+<DD>A two-way network communications channel.</DD>
+</DL>
+<H2><A NAME="6_2">A.2 Acronyms</A></H2>
+<DL>
+<DT>ASCII</DT>
+<DD>American Standard Code for Information Interchange</DD>
+<DT>CUPS</DT>
+<DD>Common UNIX Printing System</DD>
+<DT>ESC/P</DT>
+<DD>EPSON Standard Code for Printers</DD>
+<DT>FTP</DT>
+<DD>File Transfer Protocol</DD>
+<DT>HP-GL</DT>
+<DD>Hewlett-Packard Graphics Language</DD>
+<DT>HP-PCL</DT>
+<DD>Hewlett-Packard Page Control Language</DD>
+<DT>HP-PJL</DT>
+<DD>Hewlett-Packard Printer Job Language</DD>
+<DT>IETF</DT>
+<DD>Internet Engineering Task Force</DD>
+<DT>IPP</DT>
+<DD>Internet Printing Protocol</DD>
+<DT>ISO</DT>
+<DD>International Standards Organization</DD>
+<DT>LPD</DT>
+<DD>Line Printer Daemon</DD>
+<DT>MIME</DT>
+<DD>Multimedia Internet Mail Exchange</DD>
+<DT>PPD</DT>
+<DD>PostScript Printer Description</DD>
+<DT>SMB</DT>
+<DD>Server Message Block</DD>
+<DT>TFTP</DT>
+<DD>Trivial File Transfer Protocol</DD>
+</DL>
+</BODY>
+</HTML>
diff --git a/doc/translation.pdf b/doc/translation.pdf
new file mode 100644
index 000000000..db80999ec
--- /dev/null
+++ b/doc/translation.pdf
Binary files differ
diff --git a/doc/translation.shtml b/doc/translation.shtml
new file mode 100644
index 000000000..8a587fff4
--- /dev/null
+++ b/doc/translation.shtml
@@ -0,0 +1,734 @@
+<HTML>
+<HEAD>
+ <META NAME="COPYRIGHT" CONTENT="Copyright 2001-2002, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-TRANS-1.1">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Translation Guide</TITLE>
+</HEAD>
+<BODY>
+
+<H1>Scope</H1>
+
+<H2>Identification</H2>
+
+<P>This translation guide provides instructions for creating
+translations of the CUPS message catalogs and web pages for the
+Common UNIX Printing System ("CUPS") Version 1.1 software.
+
+<EMBED SRC="system-overview.shtml">
+
+<H2>Document Overview</H2>
+
+<P>This translation guide is organized into the following
+sections:
+
+<UL>
+ <LI>1 - Scope</LI>
+ <LI>2 - References</LI>
+ <LI>3 - Character Sets</LI>
+ <LI>4 - Message Catalogs</LI>
+ <LI>5 - Web Interfaces</LI>
+ <LI>A - Glossary</LI>
+</UL>
+
+<EMBED SRC="references.shtml">
+
+
+<H1>Character Sets</H1>
+
+<P>CUPS uses character set files to define the mapping of local
+character sets to Unicode code points, as well as the fonts that
+should be used for different ranges of characters.
+
+<P>CUPS includes files for common 8-bit encodings as well as
+UTF-8 for Unicode text. The format of these files is described
+in the CUPS Interface Design Description (IDD) document.
+Current character sets are enumerated in the CUPS API, so in
+order to add a new character set you must patch the CUPS source
+as well as provide a new charset file.
+
+<P>CUPS 1.1 supports the following character sets:
+
+<UL>
+
+ <LI>iso-8859-1
+ <LI>iso-8859-2
+ <LI>iso-8859-3
+ <LI>iso-8859-4
+ <LI>iso-8859-5
+ <LI>iso-8859-6
+ <LI>iso-8859-7
+ <LI>iso-8859-8
+ <LI>iso-8859-9
+ <LI>iso-8859-10
+ <LI>iso-8859-13
+ <LI>iso-8859-14
+ <LI>iso-8859-15
+ <LI>koi8-r
+ <LI>koi8-u
+ <LI>us-ascii
+ <LI>utf-8
+ <LI>windows-874
+ <LI>windows-1250
+ <LI>windows-1251
+ <LI>windows-1252
+ <LI>windows-1253
+ <LI>windows-1254
+ <LI>windows-1255
+ <LI>windows-1256
+ <LI>windows-1257
+ <LI>windows-1258
+
+</UL>
+
+<H1>Message Catalogs</H1>
+
+<P>CUPS message catalogs are text files that identify the
+default character set for the locale and a list of localized
+message strings for the CUPS software. The format of the
+message catalog files is described in the CUPS IDD.
+
+<P>Message catalogs are named <VAR>cups_ll</VAR>,
+<VAR>cups_ll_CC</VAR>, or <VAR>cups_ll_CC.charset</VAR>, where
+"ll" is the standard 2-letter abbreviation for the language,
+"CC" is the standard 2-letter abbreviation for the country, and
+"charset" is the charset name which may differ from the list
+above.
+
+<P>Each message catalog file is stored in a subdirectory named
+<VAR>ll</VAR>, <VAR>ll_CC</VAR>, or <VAR>ll_CC.charset</VAR> to
+match the trailing portion of the message catalog filename.
+
+<P>When translating a new message catalog, copy the <VAR>cups_C</VAR>
+message catalog file to a new subdirectory; to translate the
+message catalog to Canadian French, you would type the following
+commands:
+
+<UL><PRE>
+<KBD>cd locale <I>ENTER</I></KBD>
+<KBD>mkdir fr_CA <I>ENTER</I></KBD>
+<KBD>cp C/cups_C fr_CA/cups_fr_CA <I>ENTER</I></KBD>
+</PRE></UL>
+
+<P>Alternatively, you could copy the existing <VAR>cups_fr</VAR>
+message catalog and then make any changes necessary.
+
+<P>Once you have make your copy of the file, edit it using your
+favorite text editor to translate the text to the desired
+language. Be sure to preserve any numbers starting in the first
+column, as they indicate a new message number - you'll see this
+for the HTTP status messages.
+
+<P>Finally, add your locale to the list of locales in the
+makefile and run the following command to install it:
+
+<UL><PRE>
+<KBD>make install <I>ENTER</I></KBD>
+</PRE></UL>
+
+<H1>Web Interfaces</H1>
+
+<P>The CUPS scheduler provides a web interface that can be used
+to do many common printing and administration tasks. The built-in
+web server supports localization of web pages through the use of
+subdirectories for each locale, e.g. "fr" for French, "de" for
+German, "fr_ca" for French in Canada, and so forth.
+
+<H2>Template Files</H2>
+
+<P>Template files are HTML files with special formatting
+characters in them that allow substition of variables and
+arrays. The CUPS CGI programs (<CODE>admin.cgi</CODE>,
+<CODE>classes.cgi</CODE>, <CODE>jobs.cgi</CODE>, and
+<CODE>printers.cgi</CODE>) use these template file to provide
+dynamic content for the web interface. Template files are
+installed in the <VAR>/usr/share/cups/templates</VAR> directory
+by default.
+
+<P>Translated versions of the template files should be installed
+in the appropriate subdirectories under
+<VAR>/usr/share/cups/templates</VAR>. For example, Canadian
+French template files should be stored in the
+<VAR>/usr/share/cups/templates/fr_CA</VAR> directory.
+
+<H3>Inserting Attributes and Values</H3>
+
+<P>Template files consist of HTML with variable substitutions
+for named inside curley braces "{name}". Variable names are
+generally the IPP attribute names with the hyphen ("-") replaced
+by the underscore ("_") character. For example, the
+<TT>job-printer-uri</TT> attribute is renamed to
+<TT>job_printer_uri</TT>.
+
+<P>Curley braces ("{" and "}") to indicate substitutions, and
+the backslash ("\") character for quoting. To insert any of
+these special characters as-is you need to use the HTML
+<CODE>&amp;name;</CODE> mechanism or prefix each special
+character with the backslash ("\".)</P>
+
+<P>You substitute the value of a variable using
+<CODE>{NAME}</CODE> in your template file. If the variable is
+undefined then the <CODE>{NAME}</CODE> string is output
+as-is.</P>
+
+<P>To substitute an empty string if the variable is undefined, use
+<CODE>{?NAME}</CODE> instead.</P>
+
+<H3>Array Substitutions</H3>
+
+<P>The number of array elements can be inserted using
+<CODE>{#NAME}</CODE>. If the array is undefined then 0 is
+output. The current array element (starting at 1) is inserted
+with <CODE>{#}</CODE>.</P>
+
+<P>Arrays are handled using <CODE>{[NAME]</CODE> at the beginning of a
+section and <CODE>}</CODE> at the end. The information between the closing
+bracket ("]") and closing brace ("}") is repeated for as many elements as
+are in the named array. For example, the following template will display
+a list of each job in the <CODE>job_id</CODE> array:</P>
+
+<UL><PRE>
+&lt;TABLE&gt;
+&lt;TR&gt;
+ &lt;TH&gt;Job ID&lt;/TH&gt;
+ &lt;TH&gt;Destination&lt;/TH&gt;
+ &lt;TH&gt;Title&lt;/TH&gt;
+&lt;/TR&gt;
+
+{[job_id]
+&lt;TR&gt;
+ &lt;TD&gt;{?job_id}&lt;/TD&gt;
+ &lt;TD&gt;{?job_printer_name}&lt;/TD&gt;
+ &lt;TD&gt;{?job_name}&lt;/TD&gt;
+&lt;/TR&gt;
+}
+&lt;/TABLE&gt;
+</PRE></UL>
+
+<P>Arrays can be nested, however all elements within the curley
+braces ("{" and "}") are indexed using the innermost array.</P>
+
+<H3>Conditional Tests</H3>
+
+<P>Templates can also test variables against specific values and
+conditionally include text in the template. The format is:
+
+<UL><PRE>
+{<I>variable</I>?<I>true</I>:<I>false</I>}
+{<I>variable</I>=<I>value</I>?<I>true</I>:<I>false</I>}
+{<I>variable</I>!<I>value</I>?<I>true</I>:<I>false</I>}
+{<I>variable</I>&lt;<I>value</I>?<I>true</I>:<I>false</I>}
+{<I>variable</I>><I>value</I>?<I>true</I>:<I>false</I>}
+</PRE></UL>
+
+<P>where <VAR>true</VAR> is the text that is included if the
+condition is true and <VAR>false</VAR> is the text that is
+included if the condition is false. A value of <CODE>#</CODE> is
+replaced with the current element number (starting at 1.)
+
+<P>The character after the variable name specifies the condition
+to test:
+
+<CENTER><TABLE BORDER="1">
+<TR>
+ <TH WIDTH="5%">Char</TH>
+ <TH WIDTH="50%">Condition</TH>
+</TR>
+<TR>
+ <TD>?</TD>
+ <TD>True if <VAR>variable</VAR> exists.</TD>
+</TR>
+<TR>
+ <TD>=</TD>
+ <TD>True if <VAR>variable</VAR> is equal to <VAR>value</VAR>.</TD>
+</TR>
+<TR>
+ <TD>!</TD>
+ <TD>True if <VAR>variable</VAR> is not equal to <VAR>value</VAR>.</TD>
+</TR>
+<TR>
+ <TD>&lt;</TD>
+ <TD>True if <VAR>variable</VAR> is less than <VAR>value</VAR>.</TD>
+</TR>
+<TR>
+ <TD>></TD>
+ <TD>True if <VAR>variable</VAR> is greater than <VAR>value</VAR>.</TD>
+</TR>
+</TABLE></CENTER>
+
+<H3>Template File List</H3>
+
+<P>The following template files are used by the web interface:
+
+<DL>
+
+<DT>add-class.tmpl
+
+ <DD>This is the initial form that is shown to add a new
+ printer class.
+
+<DT>add-printer.tmpl
+
+ <DD>This is the initial form that is shown to add a new
+ printer.
+
+<DT>admin-op.tmpl
+
+ <DD>This is the template that is used to display an error
+ message when the admin interface sees an undefined
+ operation name.
+
+<DT>admin.tmpl
+
+ <DD>This is the template that shows the initial menu of
+ operations (add a class, manage classes, etc.)
+
+<DT>choose-device.tmpl
+
+ <DD>This is the form that shows the list of available
+ devices.
+
+<DT>choose-make.tmpl
+
+ <DD>This is the form that shows the list of available
+ manufacturers.
+
+<DT>choose-members.tmpl
+
+ <DD>This is the form that shows the list of available
+ printers that can be added to a class.
+
+<DT>choose-model.tmpl
+
+ <DD>This is the form that shows the list of available
+ printer models/drivers.
+
+<DT>choose-serial.tmpl
+
+ <DD>This is the form that allows the user to choose
+ a serial port and any options.
+
+<DT>choose-uri.tmpl
+
+ <DD>This is the form that allows the user to enter
+ a device URI for network printers.
+
+<DT>class-added.tmpl
+
+ <DD>This template shows the "class added" message.
+
+<DT>class-confirm.tmpl
+
+ <DD>This is the template used to confirm the
+ deletion of a class.
+
+<DT>class-deleted.tmpl
+
+ <DD>This template shows the "class deleted" message.
+
+<DT>classes.tmpl
+
+ <DD>This template shows one or more printer classes.
+
+<DT>class-modified.tmpl
+
+ <DD>This template shows the "class modified" message.
+
+<DT>config-printer.tmpl
+
+ <DD>This template starts the printer configuration form.
+
+<DT>config-printer2.tmpl
+
+ <DD>This template ends the printer configuration form.
+
+<DT>error.tmpl
+
+ <DD>This template displays a generic error message.
+
+<DT>header.tmpl
+
+ <DD>This template is used as the standard header on all dynamic
+ content.
+
+<DT>job-cancel.tmpl
+
+ <DD>This template shows "job cancelled".
+
+<DT>job-hold.tmpl
+
+ <DD>This template shows "job held".
+
+<DT>job-op.tmpl
+
+ <DD>This is the template that is used to display an
+ error message when the job interface sees an undefined
+ operation name.
+
+<DT>job-release.tmpl
+
+ <DD>This template shows "job released".
+
+<DT>job-restart.tmpl
+
+ <DD>This template shows "job restarted".
+
+<DT>jobs.tmpl
+
+ <DD>This template is used to list the print jobs on a server,
+ class, or printer.
+
+<DT>modify-class.tmpl
+
+ <DD>This template is used as the first form when modifying a
+ class.
+
+<DT>modify-printer.tmpl
+
+ <DD>This template is used as the first form when modifying a
+ printer.
+
+<DT>option-boolean.tmpl
+
+ <DD>This template is used to select a boolean PPD option.
+
+<DT>option-header.tmpl
+
+ <DD>This template is used to start a PPD option group.
+
+<DT>option-pickmany.tmpl
+
+ <DD>This template is used to select a multi-valued PPD option.
+
+<DT>option-pickone.tmpl
+
+ <DD>This template is used to select a single-valued PPD option.
+
+<DT>option-trailer.tmpl
+
+ <DD>This template is used to end a PPD option group.
+
+<DT>printer-accept.tmpl
+
+ <DD>This template shows "printer now accepting jobs".
+
+<DT>printer-added.tmpl
+
+ <DD>This template shows "printer added".
+
+<DT>printer-configured.tmpl
+
+ <DD>This template shows "printer configured".
+
+<DT>printer-confirm.tmpl
+
+ <DD>This template asks the user to confirm the deletion of a printer.
+
+<DT>printer-deleted.tmpl
+
+ <DD>This template shows "printer deleted".
+
+<DT>printer-modified.tmpl
+
+ <DD>This template shows "printer modified".
+
+<DT>printer-purge.tmpl
+
+ <DD>This template shows "printer has been purged of all jobs".
+
+<DT>printer-reject.tmpl
+
+ <DD>This template shows "printer now rejecting jobs".
+
+<DT>printer-start.tmpl
+
+ <DD>This template shows "printer started".
+
+<DT>printers.tmpl
+
+ <DD>This template is used to list information on one or more
+ printers.
+
+<DT>printer-stop.tmpl
+
+ <DD>This template shows "printer stopped".
+
+<DT>test-page.tmpl
+
+ <DD>This template shows "test page printed".
+
+<DT>trailer.tmpl
+
+ <DD>This template is used as the standard trailer on all dynamic
+ content.
+
+</DL>
+
+<H2>CGI Programs</H2>
+
+<P>CUPS uses four CGI programs to manage the dynamic web interfaces:
+
+<UL>
+
+ <LI><CODE>admin.cgi</CODE></LI>
+ <LI><CODE>classes.cgi</CODE></LI>
+ <LI><CODE>jobs.cgi</CODE></LI>
+ <LI><CODE>printers.cgi</CODE></LI>
+
+</UL>
+
+<H3>admin.cgi</H3>
+
+<P>The <CODE>admin.cgi</CODE> program handles all of the printer
+and class administration functions and is run for all direct
+accesses to the <VAR>/admin</VAR> resource. For most operations it uses the
+<CODE>PRINTER_NAME</CODE> and <CODE>OP</CODE> form variables to
+specify the action requested.
+
+<P>The following <CODE>OP</CODE> values are supported:
+
+<DL>
+
+<DT>accept-jobs</DT>
+
+ <DD>Accepts jobs on the named destination.</DD>
+
+<DT>add-class</DT>
+
+ <DD>Adds a new printer class. This operation also adds
+ several other form variables:
+
+ <DL>
+
+ <DT>MEMBER_URIS</DT>
+
+ <DD>Sets the members of the class. Multiple
+ <CODE>MEMBER_URIS</CODE> values can be
+ provided.</DD>
+
+ <DT>PRINTER_INFO</DT>
+
+ <DD>Sets the printer-info attribute for the
+ printer class, which is usually the printer
+ description.</DD>
+
+ <DT>PRINTER_LOCATION</DT>
+
+ <DD>Sets the printer-location attribute for the
+ printer class.</DD>
+
+ </DL>
+
+ </DD>
+
+<DT>add-printer</DT>
+
+ <DD>Adds a new printer. This operation also adds several other
+ form variables:
+
+ <DL>
+
+ <DT>BAUDRATE</DT>
+
+ <DD>Sets the baud rate for serial devices.</DD>
+
+ <DT>BITS</DT>
+
+ <DD>Sets the number of data bits for serial devices.</DD>
+
+ <DT>DEVICE_URI</DT>
+
+ <DD>Sets the device URI for the printer.</DD>
+
+ <DT>FLOW</DT>
+
+ <DD>Sets the flow control for serial devices.</DD>
+
+ <DT>PARITY</DT>
+
+ <DD>Sets the parity checking for serial devices.</DD>
+
+ <DT>PPD_NAME</DT>
+
+ <DD>Sets the driver name for the printer ("raw" for a
+ raw queue.)</DD>
+
+ <DT>PRINTER_INFO</DT>
+
+ <DD>Sets the printer-info attribute for the
+ printer, which is usually the printer
+ description.</DD>
+
+ <DT>PRINTER_LOCATION</DT>
+
+ <DD>Sets the printer-location attribute for the
+ printer.</DD>
+
+ </DL>
+
+ </DD>
+
+<DT>config-printer</DT>
+
+ <DD>Configures an existing printer. This operation uses
+ form variables of the same name as the options in the
+ printer's PPD file.</DD>
+
+<DT>delete-class</DT>
+
+ <DD>Deletes a printer class. The form variable <CODE>CONFIRM</CODE>
+ may be set to any value to bypass the confirmation page.</DD>
+
+<DT>delete-printer</DT>
+
+ <DD>Deletes a printer. The form variable <CODE>CONFIRM</CODE>
+ may be set to any value to bypass the confirmation page.</DD>
+
+<DT>modify-class</DT>
+
+ <DD>Modifies a printer class. See the add-class operation for a
+ list of form variables.</DD>
+
+<DT>modify-printer</DT>
+
+ <DD>Modifies a printer. See the add-printer operation for a
+ list of form variables.</DD>
+
+<DT>purge-jobs</DT>
+
+ <DD>Purges all jobs on the named destination.</DD>
+
+<DT>reject-jobs</DT>
+
+ <DD>Rejects new jobs on the named destination.</DD>
+
+<DT>start-printer</DT>
+
+ <DD>Starts the named destination.</DD>
+
+<DT>stop-printer</DT>
+
+ <DD>Stops the named destination.</DD>
+
+</DL>
+
+
+<H3>classes.cgi</H3>
+
+<P>The <CODE>classes.cgi</CODE> program is responsible for
+listing class information, including jobs destined for that
+class. It is for all direct accesses to the <VAR>/classes</VAR> resource
+and supports the optional form variables <CODE>OP</CODE> and
+<CODE>WHICH_JOBS</CODE>. If no form variables are supplied then
+the CGI lists all or a specific class and the active jobs on
+each class.
+
+<P>The following <CODE>WHICH_JOBS</CODE> values are supported:
+
+<DL>
+
+<DT>completed</DT>
+
+ <DD>Show only the completed jobs.</DD>
+
+<DT>not-completed</DT>
+
+ <DD>Show only the active jobs.</DD>
+
+</DL>
+
+<P>The following <CODE>OP</CODE> values are supported:
+
+<DL>
+
+<DT>print-test-page</DT>
+
+ <DD>Print a PostScript test page.</DD>
+
+</DL>
+
+<H3>jobs.cgi</H3>
+
+<P>The <CODE>jobs.cgi</CODE> program handles all of the job
+functions and is run for all direct accesses to the <VAR>/jobs</VAR>
+resource. For most operations it uses the
+<CODE>JOB_ID</CODE>, <CODE>OP</CODE>, and
+<CODE>WHICH_JOBS</CODE> form variables to specify the action
+requested.
+
+<P>The following <CODE>WHICH_JOBS</CODE> values are supported:
+
+<DL>
+
+<DT>completed</DT>
+
+ <DD>Show only the completed jobs.</DD>
+
+<DT>not-completed</DT>
+
+ <DD>Show only the active jobs.</DD>
+
+</DL>
+
+<P>The following <CODE>OP</CODE> values are supported:
+
+<DL>
+
+<DT>job-cancel</DT>
+
+ <DD>Cancels a job.</DD>
+
+<DT>job-hold</DT>
+
+ <DD>Holds a job indefinitely.</DD>
+
+<DT>job-release</DT>
+
+ <DD>Releases a job for printing.</DD>
+
+<DT>job-restart</DT>
+
+ <DD>Restarts a stopped, cancelled, completed, or aborted
+ print job.</DD>
+
+</DL>
+
+<H3>printers.cgi</H3>
+
+<P>The <CODE>printers.cgi</CODE> program is responsible for
+listing printer information, including jobs destined for that
+printer. It is for all direct accesses to the <VAR>/printers</VAR> resource
+and supports the optional form variables <CODE>OP</CODE> and
+<CODE>WHICH_JOBS</CODE>. If no form variables are supplied then
+the CGI lists all or a specific printer and the active jobs on
+each printer.
+
+<P>The following <CODE>WHICH_JOBS</CODE> values are supported:
+
+<DL>
+
+<DT>completed</DT>
+
+ <DD>Show only the completed jobs.</DD>
+
+<DT>not-completed</DT>
+
+ <DD>Show only the active jobs.</DD>
+
+</DL>
+
+<P>The following <CODE>OP</CODE> values are supported:
+
+<DL>
+
+<DT>print-test-page</DT>
+
+ <DD>Print a PostScript test page.</DD>
+
+</DL>
+
+
+<EMBED SRC="glossary.shtml">
+
+</BODY>
+</HTML>
diff --git a/filter/.cvsignore b/filter/.cvsignore
new file mode 100644
index 000000000..ac32441d7
--- /dev/null
+++ b/filter/.cvsignore
@@ -0,0 +1,31 @@
+hpgltops
+imagetops
+imagetoraster
+libcupsimage.a
+libcupsimage.dylib.2
+libcupsimage.sl.2
+libcupsimage.so.2
+libcupsimage_s.a
+pstops
+rastertodymo
+rastertoepson
+rastertohp
+texttops
+rastertoalps
+rastertoalps-oem
+rastertobj
+rastertobj-oem
+rastertoescp
+rastertoescp-oem
+rastertoescp2
+rastertoescp2-oem
+rastertoescp2x
+rastertoescp2x-oem
+rastertopcl
+rastertopcl-oem
+texttopcl
+texttopcl-oem
+decode-escp2
+decode-pcl
+images
+testdither
diff --git a/filter/Dependencies b/filter/Dependencies
new file mode 100644
index 000000000..fcc94363b
--- /dev/null
+++ b/filter/Dependencies
@@ -0,0 +1,75 @@
+# DO NOT DELETE
+
+hpgl-attr.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-attr.o: ../cups/md5.h ../cups/ppd.h ../cups/language.h ../cups/string.h
+hpgl-attr.o: ../config.h
+hpgl-config.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-config.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/language.h
+hpgl-config.o: ../cups/string.h ../config.h
+hpgl-main.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-main.o: ../cups/md5.h ../cups/ppd.h ../cups/language.h ../cups/string.h
+hpgl-main.o: ../config.h
+hpgl-prolog.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-prolog.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/language.h
+hpgl-prolog.o: ../cups/string.h ../config.h
+hpgl-char.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-char.o: ../cups/md5.h ../cups/ppd.h ../cups/language.h ../cups/string.h
+hpgl-char.o: ../config.h
+hpgl-input.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+hpgl-input.o: ../cups/md5.h ../cups/ppd.h ../cups/language.h ../cups/string.h
+hpgl-input.o: ../config.h
+hpgl-polygon.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-polygon.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/language.h
+hpgl-polygon.o: ../cups/string.h ../config.h
+hpgl-vector.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h
+hpgl-vector.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/language.h
+hpgl-vector.o: ../cups/string.h ../config.h
+image-bmp.o: image.h ../config.h raster.h
+image-colorspace.o: image.h ../config.h raster.h
+image-gif.o: image.h ../config.h raster.h
+image-jpeg.o: image.h ../config.h raster.h
+image-photocd.o: image.h ../config.h raster.h
+image-pix.o: image.h ../config.h raster.h
+image-png.o: image.h ../config.h raster.h
+image-pnm.o: image.h ../config.h raster.h
+image-sgi.o: image.h ../config.h raster.h image-sgi.h
+image-sgilib.o: image-sgi.h
+image-sun.o: image.h ../config.h raster.h
+image-tiff.o: image.h ../config.h raster.h
+image-zoom.o: image.h ../config.h raster.h
+image.o: image.h ../config.h raster.h ../cups/cups.h ../cups/ipp.h
+image.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h
+raster.o: raster.h
+form-main.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-main.o: ../cups/md5.h ../cups/ppd.h ../cups/language.h ../cups/string.h
+form-main.o: ../config.h
+form-ps.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-ps.o: ../cups/md5.h ../cups/ppd.h ../cups/language.h ../cups/string.h
+form-ps.o: ../config.h
+form-tree.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+form-tree.o: ../cups/md5.h ../cups/ppd.h ../cups/language.h ../cups/string.h
+form-tree.o: ../config.h
+imagetops.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+imagetops.o: ../cups/md5.h ../cups/ppd.h ../cups/language.h ../cups/string.h
+imagetops.o: ../config.h image.h raster.h
+imagetoraster.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+imagetoraster.o: ../cups/md5.h ../cups/ppd.h ../cups/language.h
+imagetoraster.o: ../cups/string.h ../config.h image.h raster.h
+common.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+common.o: ../cups/ppd.h ../cups/language.h ../cups/string.h ../config.h
+pstops.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+pstops.o: ../cups/ppd.h ../cups/language.h ../cups/string.h ../config.h
+raster.o: raster.h
+rastertodymo.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+rastertodymo.o: ../cups/ppd.h ../cups/string.h ../config.h raster.h
+rastertoepson.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+rastertoepson.o: ../cups/ppd.h ../cups/ppd.h ../cups/string.h ../config.h
+rastertoepson.o: raster.h
+rastertohp.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+rastertohp.o: ../cups/ppd.h ../cups/string.h ../config.h raster.h
+texttops.o: textcommon.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+texttops.o: ../cups/md5.h ../cups/ppd.h ../cups/language.h ../cups/string.h
+texttops.o: ../config.h
+textcommon.o: textcommon.h common.h ../cups/cups.h ../cups/ipp.h
+textcommon.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/language.h
+textcommon.o: ../cups/string.h ../config.h
diff --git a/filter/Makefile b/filter/Makefile
new file mode 100644
index 000000000..7818808c4
--- /dev/null
+++ b/filter/Makefile
@@ -0,0 +1,253 @@
+#
+# "$Id$"
+#
+# Filter makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+# This file is subject to the Apple OS-Developed Software exception.
+#
+
+include ../Makedefs
+
+TARGETS = hpgltops texttops pstops imagetops imagetoraster \
+ rastertodymo rastertoepson rastertohp
+
+HPGLOBJS = hpgl-attr.o hpgl-config.o hpgl-main.o hpgl-prolog.o \
+ hpgl-char.o hpgl-input.o hpgl-polygon.o hpgl-vector.o
+IMAGEOBJS = image-bmp.o image-colorspace.o image-gif.o image-jpeg.o \
+ image-photocd.o image-pix.o image-png.o image-pnm.o \
+ image-sgi.o image-sgilib.o image-sun.o image-tiff.o \
+ image-zoom.o image.o raster.o
+FORMOBJS = form-attr.o form-main.o form-ps.o form-text.o form-tree.o
+OBJS = $(HPGLOBJS) $(IMAGEOBJS) $(FORMOBJS) \
+ imagetops.o imagetoraster.o common.o pstops.o raster.o \
+ rastertodymo.o rastertoepson.o rastertohp.o texttops.o \
+ textcommon.o
+
+#
+# Make all targets...
+#
+
+all: $(TARGETS) libcupsimage.a
+
+
+#
+# Clean all object files...
+#
+
+clean:
+ $(RM) $(OBJS) $(TARGETS) $(LIBCUPSIMAGE)
+ $(RM) `basename $(LIBCUPSIMAGE) .2` libcupsimage.dylib
+
+
+#
+# Update dependencies (without system header dependencies...)
+#
+
+depend:
+ makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1
+
+
+#
+# Install all targets...
+#
+
+install: all installhdrs
+ $(INSTALL_DIR) $(SERVERBIN)/filter
+ for file in $(TARGETS); do \
+ $(INSTALL_BIN) $$file $(SERVERBIN)/filter; \
+ done
+ $(INSTALL_DIR) $(LIBDIR)
+ $(INSTALL_LIB) $(LIBCUPSIMAGE) $(LIBDIR)
+ -if test $(LIBCUPSIMAGE) = "libcupsimage.so.2" -o $(LIBCUPSIMAGE) = "libcupsimage.sl.2"; then \
+ $(RM) $(LIBDIR)/`basename $(LIBCUPSIMAGE) .2`; \
+ $(LN) $(LIBCUPSIMAGE) $(LIBDIR)/`basename $(LIBCUPSIMAGE) .2`; \
+ fi
+ -if test $(LIBCUPSIMAGE) = "libcupsimage.2.dylib"; then \
+ $(STRIP) -x $(LIBDIR)/$(LIBCUPSIMAGE); \
+ $(RM) $(LIBDIR)/libcupsimage.dylib; \
+ $(LN) $(LIBCUPSIMAGE) $(LIBDIR)/libcupsimage.dylib; \
+ fi
+ -if test $(LIBCUPSIMAGE) != "libcupsimage.a"; then \
+ $(INSTALL_LIB) libcupsimage.a $(LIBDIR); \
+ fi
+ $(RANLIB) $(LIBDIR)/libcupsimage.a
+
+installhdrs:
+ $(INSTALL_DIR) $(INCLUDEDIR)/cups
+ $(INSTALL_DATA) image.h $(INCLUDEDIR)/cups
+ $(INSTALL_DATA) raster.h $(INCLUDEDIR)/cups
+
+
+#
+# formtops
+#
+
+formtops: $(FORMOBJS) common.o ../Makedefs ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ $(FORMOBJS) common.o $(LIBS) -lm
+
+
+#
+# hpgltops
+#
+
+hpgltops: $(HPGLOBJS) common.o ../Makedefs ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ $(HPGLOBJS) common.o $(LIBS) -lm
+
+
+#
+# libcupsimage.so.2, libcupsimage.sl.2
+#
+
+libcupsimage.so.2 libcupsimage.sl.2: $(IMAGEOBJS) ../Makedefs
+ echo Linking $@...
+ $(DSO) $(DSOFLAGS) -o $@ $(IMAGEOBJS) $(DSOLIBS) -lm
+ $(RM) `basename $@ .2`
+ $(LN) $@ `basename $@ .2`
+
+
+#
+# libcupsimage.2.dylib
+#
+
+libcupsimage.2.dylib: $(IMAGEOBJS) ../Makedefs
+ echo Linking $@...
+ $(DSO) $(DSOFLAGS) -o $@ \
+ -install_name $(libdir)/$@ \
+ -current_version 2.1.0 \
+ -compatibility_version 2.0.0 \
+ $(IMAGEOBJS) $(DSOLIBS) -L../cups $(LINKCUPS) -lm -lcc_dynamic
+ $(RM) libcupsimage.dylib
+ $(LN) $@ libcupsimage.dylib
+
+
+#
+# libcupsimage_s.a
+#
+
+libcupsimage_s.a: $(IMAGEOBJS) ../Makedefs
+ echo Linking $@...
+ $(DSO) $(DSOFLAGS) -o libcupsimage_s.o $(IMAGEOBJS) $(DSOLIBS) \
+ $(LINKCUPS) -lm
+ $(RM) $@
+ $(AR) $(ARFLAGS) $@ libcupsimage_s.o
+
+
+#
+# libcupsimage.la
+#
+
+libcupsimage.la: $(IMAGEOBJS) ../Makedefs
+ echo Linking $@...
+ $(DSO) -o $(DSOFLAGS) $@ $(IMAGEOBJS:.o=.lo) $(DSOLIBS) \
+ -rpath $(LIBDIR) -version-info 2:1
+
+
+#
+# libcupsimage.a
+#
+
+libcupsimage.a: $(IMAGEOBJS) ../Makedefs
+ echo Archiving $@...
+ $(RM) $@
+ $(AR) $(ARFLAGS) $@ $(IMAGEOBJS)
+ $(RANLIB) $@
+
+
+#
+# imagetops
+#
+
+imagetops: imagetops.o common.o $(LIBCUPSIMAGE) ../Makedefs \
+ ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ imagetops.o common.o $(LINKCUPSIMAGE) \
+ $(IMGLIBS) $(LIBS)
+
+
+#
+# imagetoraster
+#
+
+imagetoraster: imagetoraster.o common.o $(LIBCUPSIMAGE) ../Makedefs \
+ ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ imagetoraster.o common.o $(LINKCUPSIMAGE) \
+ $(IMGLIBS) $(LIBS)
+
+
+#
+# pstops
+#
+
+pstops: pstops.o common.o ../Makedefs ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ pstops.o common.o $(LIBS)
+
+
+#
+# rastertodymo
+#
+
+rastertodymo: rastertodymo.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ rastertodymo.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
+
+
+#
+# rastertoepson
+#
+
+rastertoepson: rastertoepson.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ rastertoepson.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
+
+
+#
+# rastertohp
+#
+
+rastertohp: rastertohp.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSIMAGE)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ rastertohp.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS)
+
+
+#
+# texttops
+#
+
+texttops: texttops.o textcommon.o common.o ../Makedefs \
+ ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ texttops.o textcommon.o common.o $(LIBS)
+
+
+#
+# Dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id$".
+#
diff --git a/filter/common.c b/filter/common.c
new file mode 100644
index 000000000..ec2ed71a7
--- /dev/null
+++ b/filter/common.c
@@ -0,0 +1,443 @@
+/*
+ * "$Id$"
+ *
+ * Common filter routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * SetCommonOptions() - Set common filter options for media size,
+ * etc.
+ * UpdatePageVars() - Update the page variables for the orientation.
+ * WriteCommon() - Write common procedures...
+ * WriteLabelProlog() - Write the prolog with the classification
+ * and page label.
+ * WriteLabels() - Write the actual page labels.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "common.h"
+
+
+/*
+ * Globals...
+ */
+
+int Orientation = 0, /* 0 = portrait, 1 = landscape, etc. */
+ Duplex = 0, /* Duplexed? */
+ LanguageLevel = 1, /* Language level of printer */
+ ColorDevice = 1; /* Do color text? */
+float PageLeft = 18.0f, /* Left margin */
+ PageRight = 594.0f, /* Right margin */
+ PageBottom = 36.0f, /* Bottom margin */
+ PageTop = 756.0f, /* Top margin */
+ PageWidth = 612.0f, /* Total page width */
+ PageLength = 792.0f; /* Total page length */
+
+
+/*
+ * 'SetCommonOptions()' - Set common filter options for media size, etc.
+ */
+
+ppd_file_t * /* O - PPD file */
+SetCommonOptions(int num_options, /* I - Number of options */
+ cups_option_t *options, /* I - Options */
+ int change_size) /* I - Change page size? */
+{
+ ppd_file_t *ppd; /* PPD file */
+ ppd_size_t *pagesize; /* Current page size */
+ const char *val; /* Option value */
+
+
+ ppd = ppdOpenFile(getenv("PPD"));
+
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, num_options, options);
+
+ if ((pagesize = ppdPageSize(ppd, NULL)) != NULL)
+ {
+ PageWidth = pagesize->width;
+ PageLength = pagesize->length;
+ PageTop = pagesize->top;
+ PageBottom = pagesize->bottom;
+ PageLeft = pagesize->left;
+ PageRight = pagesize->right;
+
+ fprintf(stderr, "DEBUG: Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n",
+ PageWidth, PageLength, PageLeft, PageBottom, PageRight, PageTop);
+ }
+
+ if (ppd != NULL)
+ {
+ ColorDevice = ppd->color_device;
+ LanguageLevel = ppd->language_level;
+ }
+
+ if ((val = cupsGetOption("landscape", num_options, options)) != NULL &&
+ strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 &&
+ strcasecmp(val, "false") != 0)
+ Orientation = 1;
+
+ if ((val = cupsGetOption("orientation-requested", num_options, options)) != NULL)
+ {
+ /*
+ * Map IPP orientation values to 0 to 3:
+ *
+ * 3 = 0 degrees = 0
+ * 4 = 90 degrees = 1
+ * 5 = -90 degrees = 3
+ * 6 = 180 degrees = 2
+ */
+
+ Orientation = atoi(val) - 3;
+ if (Orientation >= 2)
+ Orientation ^= 1;
+ }
+
+ if ((val = cupsGetOption("page-left", num_options, options)) != NULL)
+ {
+ switch (Orientation & 3)
+ {
+ case 0 :
+ PageLeft = (float)atof(val);
+ break;
+ case 1 :
+ PageBottom = (float)atof(val);
+ break;
+ case 2 :
+ PageRight = PageWidth - (float)atof(val);
+ break;
+ case 3 :
+ PageTop = PageLength - (float)atof(val);
+ break;
+ }
+ }
+
+ if ((val = cupsGetOption("page-right", num_options, options)) != NULL)
+ {
+ switch (Orientation & 3)
+ {
+ case 0 :
+ PageRight = PageWidth - (float)atof(val);
+ break;
+ case 1 :
+ PageTop = PageLength - (float)atof(val);
+ break;
+ case 2 :
+ PageLeft = (float)atof(val);
+ break;
+ case 3 :
+ PageBottom = (float)atof(val);
+ break;
+ }
+ }
+
+ if ((val = cupsGetOption("page-bottom", num_options, options)) != NULL)
+ {
+ switch (Orientation & 3)
+ {
+ case 0 :
+ PageBottom = (float)atof(val);
+ break;
+ case 1 :
+ PageLeft = (float)atof(val);
+ break;
+ case 2 :
+ PageTop = PageLength - (float)atof(val);
+ break;
+ case 3 :
+ PageRight = PageWidth - (float)atof(val);
+ break;
+ }
+ }
+
+ if ((val = cupsGetOption("page-top", num_options, options)) != NULL)
+ {
+ switch (Orientation & 3)
+ {
+ case 0 :
+ PageTop = PageLength - (float)atof(val);
+ break;
+ case 1 :
+ PageRight = PageWidth - (float)atof(val);
+ break;
+ case 2 :
+ PageBottom = (float)atof(val);
+ break;
+ case 3 :
+ PageLeft = (float)atof(val);
+ break;
+ }
+ }
+
+ if (change_size)
+ UpdatePageVars();
+
+ if ((val = cupsGetOption("sides", num_options, options)) != NULL &&
+ strncasecmp(val, "two-", 4) == 0)
+ Duplex = 1;
+ else if ((val = cupsGetOption("Duplex", num_options, options)) != NULL &&
+ strncasecmp(val, "Duplex", 6) == 0)
+ Duplex = 1;
+ else if ((val = cupsGetOption("JCLDuplex", num_options, options)) != NULL &&
+ strncasecmp(val, "Duplex", 6) == 0)
+ Duplex = 1;
+ else if ((val = cupsGetOption("EFDuplex", num_options, options)) != NULL &&
+ strncasecmp(val, "Duplex", 6) == 0)
+ Duplex = 1;
+ else if ((val = cupsGetOption("KD03Duplex", num_options, options)) != NULL &&
+ strncasecmp(val, "Duplex", 6) == 0)
+ Duplex = 1;
+ else if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "Duplex", "DuplexTumble") ||
+ ppdIsMarked(ppd, "JCLDuplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "JCLDuplex", "DuplexTumble") ||
+ ppdIsMarked(ppd, "EFDuplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "EFDuplex", "DuplexTumble") ||
+ ppdIsMarked(ppd, "KD03Duplex", "DuplexNoTumble") ||
+ ppdIsMarked(ppd, "KD03Duplex", "DuplexTumble"))
+ Duplex = 1;
+
+ return (ppd);
+}
+
+
+/*
+ * 'UpdatePageVars()' - Update the page variables for the orientation.
+ */
+
+void
+UpdatePageVars(void)
+{
+ float temp; /* Swapping variable */
+
+
+ switch (Orientation & 3)
+ {
+ case 0 : /* Portait */
+ break;
+
+ case 1 : /* Landscape */
+ temp = PageLeft;
+ PageLeft = PageBottom;
+ PageBottom = temp;
+
+ temp = PageRight;
+ PageRight = PageTop;
+ PageTop = temp;
+
+ temp = PageWidth;
+ PageWidth = PageLength;
+ PageLength = temp;
+ break;
+
+ case 2 : /* Reverse Portrait */
+ temp = PageWidth - PageLeft;
+ PageLeft = PageWidth - PageRight;
+ PageRight = temp;
+
+ temp = PageLength - PageBottom;
+ PageBottom = PageLength - PageTop;
+ PageTop = temp;
+ break;
+
+ case 3 : /* Reverse Landscape */
+ temp = PageWidth - PageLeft;
+ PageLeft = PageWidth - PageRight;
+ PageRight = temp;
+
+ temp = PageLength - PageBottom;
+ PageBottom = PageLength - PageTop;
+ PageTop = temp;
+
+ temp = PageLeft;
+ PageLeft = PageBottom;
+ PageBottom = temp;
+
+ temp = PageRight;
+ PageRight = PageTop;
+ PageTop = temp;
+
+ temp = PageWidth;
+ PageWidth = PageLength;
+ PageLength = temp;
+ break;
+ }
+}
+
+
+/*
+ * 'WriteCommon()' - Write common procedures...
+ */
+
+void
+WriteCommon(void)
+{
+ puts("% x y w h ESPrc - Clip to a rectangle.\n"
+ "userdict/ESPrc/rectclip where{pop/rectclip load}\n"
+ "{{newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
+ "neg 0 rlineto closepath clip newpath}bind}ifelse put");
+ puts("% x y w h ESPrf - Fill a rectangle.\n"
+ "userdict/ESPrf/rectfill where{pop/rectfill load}\n"
+ "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
+ "neg 0 rlineto closepath fill grestore}bind}ifelse put\n");
+ puts("% x y w h ESPrs - Stroke a rectangle.\n"
+ "userdict/ESPrs/rectstroke where{pop/rectstroke load}\n"
+ "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
+ "neg 0 rlineto closepath stroke grestore}bind}ifelse put\n");
+}
+
+
+/*
+ * 'WriteLabelProlog()' - Write the prolog with the classification
+ * and page label.
+ */
+
+void
+WriteLabelProlog(const char *label, /* I - Page label */
+ float bottom, /* I - Bottom position in points */
+ float top, /* I - Top position in points */
+ float width) /* I - Width in points */
+{
+ const char *classification; /* CLASSIFICATION environment variable */
+
+
+ /*
+ * First get the current classification...
+ */
+
+ if ((classification = getenv("CLASSIFICATION")) == NULL)
+ classification = "";
+ if (strcmp(classification, "none") == 0)
+ classification = "";
+
+ /*
+ * If there is nothing to show, bind an empty 'write labels' procedure
+ * and return...
+ */
+
+ if (!classification[0] && (label == NULL || !label[0]))
+ {
+ puts("userdict/ESPwl{}bind put");
+ return;
+ }
+
+ /*
+ * Set the classification + page label string...
+ */
+
+ printf("userdict");
+ if (strcmp(classification, "confidential") == 0)
+ printf("/ESPpl(CONFIDENTIAL");
+ else if (strcmp(classification, "classified") == 0)
+ printf("/ESPpl(CLASSIFIED");
+ else if (strcmp(classification, "secret") == 0)
+ printf("/ESPpl(SECRET");
+ else if (strcmp(classification, "topsecret") == 0)
+ printf("/ESPpl(TOP SECRET");
+ else if (strcmp(classification, "unclassified") == 0)
+ printf("/ESPpl(UNCLASSIFIED");
+ else
+ printf("/ESPpl(");
+
+ if (classification[0] && label)
+ printf(" - %s)put\n", label);
+ else if (label)
+ printf("%s)put\n", label);
+ else
+ puts(")put");
+
+ /*
+ * Then get a 14 point Helvetica-Bold font...
+ */
+
+ puts("userdict/ESPpf /Helvetica-Bold findfont 14 scalefont put");
+
+ /*
+ * Finally, the procedure to write the labels on the page...
+ */
+
+ puts("userdict/ESPwl{");
+ puts(" ESPpf setfont");
+ printf(" ESPpl stringwidth pop dup 12 add exch -0.5 mul %.0f add\n",
+ width * 0.5f);
+ puts(" 1 setgray");
+ printf(" dup 6 sub %.0f 3 index 20 ESPrf\n", bottom - 2.0);
+ printf(" dup 6 sub %.0f 3 index 20 ESPrf\n", top - 18.0);
+ puts(" 0 setgray");
+ printf(" dup 6 sub %.0f 3 index 20 ESPrs\n", bottom - 2.0);
+ printf(" dup 6 sub %.0f 3 index 20 ESPrs\n", top - 18.0);
+ printf(" dup %.0f moveto ESPpl show\n", bottom + 2.0);
+ printf(" %.0f moveto ESPpl show\n", top - 14.0);
+ puts("pop");
+ puts("}bind put");
+}
+
+
+/*
+ * 'WriteLabels()' - Write the actual page labels.
+ */
+
+void
+WriteLabels(int orient) /* I - Orientation of the page */
+{
+ float width, /* Width of page */
+ length; /* Length of page */
+
+
+ puts("gsave");
+
+ if ((orient ^ Orientation) & 1)
+ {
+ width = PageLength;
+ length = PageWidth;
+ }
+ else
+ {
+ width = PageWidth;
+ length = PageLength;
+ }
+
+ switch (orient & 3)
+ {
+ case 1 : /* Landscape */
+ printf("%.1f 0.0 translate 90 rotate\n", length);
+ break;
+ case 2 : /* Reverse Portrait */
+ printf("%.1f %.1f translate 180 rotate\n", width, length);
+ break;
+ case 3 : /* Reverse Landscape */
+ printf("0.0 %.1f translate -90 rotate\n", width);
+ break;
+ }
+
+ puts("ESPwl");
+ puts("grestore");
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/common.h b/filter/common.h
new file mode 100644
index 000000000..045d8b9eb
--- /dev/null
+++ b/filter/common.h
@@ -0,0 +1,92 @@
+/*
+ * "$Id$"
+ *
+ * Common filter definitions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <time.h>
+
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <cups/string.h>
+
+
+/*
+ * C++ magic...
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/*
+ * Globals...
+ */
+
+extern int Orientation, /* 0 = portrait, 1 = landscape, etc. */
+ Duplex, /* Duplexed? */
+ LanguageLevel, /* Language level of printer */
+ ColorDevice; /* Do color text? */
+extern float PageLeft, /* Left margin */
+ PageRight, /* Right margin */
+ PageBottom, /* Bottom margin */
+ PageTop, /* Top margin */
+ PageWidth, /* Total page width */
+ PageLength; /* Total page length */
+
+
+/*
+ * Prototypes...
+ */
+
+extern ppd_file_t *SetCommonOptions(int num_options, cups_option_t *options,
+ int change_size);
+extern void UpdatePageVars(void);
+extern void WriteCommon(void);
+extern void WriteLabelProlog(const char *label, float bottom,
+ float top, float width);
+extern void WriteLabels(int orient);
+
+
+/*
+ * C++ magic...
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/form-main.c b/filter/form-main.c
new file mode 100644
index 000000000..451f60e89
--- /dev/null
+++ b/filter/form-main.c
@@ -0,0 +1,62 @@
+/*
+ * "$Id$"
+ *
+ * CUPS form main entry for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Load the specified form file and output PostScript.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "form.h"
+
+
+/*
+ * Globals...
+ */
+
+int NumOptions; /* Number of command-line options */
+cups_option_t *Options; /* Command-line options */
+ppd_file_t *PPD; /* PPD file */
+
+
+/*
+ * 'main()' - Load the specified form file and output PostScript.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/form-ps.c b/filter/form-ps.c
new file mode 100644
index 000000000..a2a5ba748
--- /dev/null
+++ b/filter/form-ps.c
@@ -0,0 +1,49 @@
+/*
+ * "$Id$"
+ *
+ * CUPS form PostScript routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "form.h"
+
+
+/*
+ * 'formWrite()' - Write PostScript output for the given form document.
+ */
+
+void
+formWrite(tree_t *t) /* I - Document tree to write */
+{
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/form-tree.c b/filter/form-tree.c
new file mode 100644
index 000000000..38008e978
--- /dev/null
+++ b/filter/form-tree.c
@@ -0,0 +1,624 @@
+/*
+ * "$Id$"
+ *
+ * CUPS form document tree routines for the Common UNIX Printing
+ * System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "form.h"
+
+
+/*
+ * Local functions...
+ */
+
+static int compare_attr(attr_t *a0, attr_t *a1);
+static int compare_elements(char **e0, char **e1);
+static int parse_attr(tree_t *t, FILE *fp);
+static int parse_element(tree_t *t, FILE *fp);
+
+
+/*
+ * Local globals...
+ */
+
+static char *elements[] =
+ {
+ "",
+ "!--",
+ "ARC",
+ "BOX",
+ "BR",
+ "B",
+ "CUPSFORM",
+ "DEFVAR",
+ "FONT",
+ "H1",
+ "H2",
+ "H3",
+ "H4",
+ "H5",
+ "H6",
+ "HEAD",
+ "IMG",
+ "I",
+ "LINE",
+ "PAGE",
+ "PIE",
+ "POLY",
+ "PRE",
+ "P",
+ "RECT",
+ "TEXT",
+ "TT",
+ "VAR"
+ };
+
+
+/*
+ * 'formDelete()' - Delete a node and its children.
+ */
+
+void
+formDelete(tree_t *t) /* I - Tree node */
+{
+}
+
+
+/*
+ * 'formGetAttr()' - Get a node attribute value.
+ */
+
+char * /* O - Value or NULL */
+formGetAttr(tree_t *t, /* I - Tree node */
+ const char *name) /* I - Name of attribute */
+{
+}
+
+
+/*
+ * 'formNew()' - Create a new form node.
+ */
+
+tree_t * /* O - New tree node */
+formNew(tree_t *p) /* I - Parent node */
+{
+ tree_t *t; /* New tree node */
+
+
+ /*
+ * Allocate the new node...
+ */
+
+ if ((t = (tree_t *)calloc(sizeof(tree_t), 1)) == NULL)
+ return (NULL);
+
+ /*
+ * Set/copy attributes...
+ */
+
+ if (p == NULL)
+ {
+ t->bg[0] = 1.0;
+ t->bg[1] = 1.0;
+ t->bg[2] = 1.0;
+ t->halign = HALIGN_LEFT;
+ t->valign = VALIGN_MIDDLE;
+ t->typeface = "Courier";
+ t->size = 12.0;
+ }
+ else
+ {
+ memcpy(t, p, sizeof(tree_t));
+
+ t->prev = NULL;
+ t->next = NULL;
+ t->child = NULL;
+ t->last_child = NULL;
+ t->parent = NULL;
+ t->num_attrs = 0;
+ t->attrs = NULL;
+ t->data = NULL;
+ }
+
+ /*
+ * Return the new node...
+ */
+
+ return (t);
+}
+
+
+/*
+ * 'formRead()' - Read a form tree from a file.
+ */
+
+tree_t * /* O - New form tree */
+formRead(FILE *fp, /* I - File to read from */
+ tree_t *p) /* I - Parent node */
+{
+ int ch, /* Character from file */
+ closech, /* Closing character */
+ have_whitespace; /* Leading whitespace? */
+ static char s[10240]; /* String from file */
+ uchar *ptr, /* Pointer in string */
+ glyph[16], /* Glyph name (&#nnn;) */
+ *glyphptr; /* Pointer in glyph string */
+ tree_t *tree, /* "top" of this tree */
+ *t, /* New tree node */
+ *prev, /* Previous tree node */
+ *temp; /* Temporary looping var */
+ uchar *face, /* Typeface for FONT tag */
+ *color, /* Color for FONT tag */
+ *size; /* Size for FONT tag */
+
+
+ /*
+ * Start off with no previous tree node...
+ */
+
+ prev = NULL;
+ tree = NULL;
+
+ /*
+ * Parse data until we hit end-of-file...
+ */
+
+ while ((ch = getc(fp)) != EOF)
+ {
+ /*
+ * Ignore leading whitespace...
+ */
+
+ have_whitespace = 0;
+ closech = '/';
+
+ if (p == NULL || !p->preformatted)
+ {
+ while (isspace(ch))
+ {
+ have_whitespace = 1;
+ ch = getc(fp);
+ }
+
+ if (ch == EOF)
+ break;
+ }
+
+ /*
+ * Allocate a new tree node - use calloc() to get zeroed data...
+ */
+
+ t = formNew(p);
+
+ /*
+ * See what the character was...
+ */
+
+ if (ch == '<')
+ {
+ /*
+ * Markup char; grab the next char to see if this is a /...
+ */
+
+ ch = getc(fp);
+ if (ch == ' ')
+ {
+ /*
+ * Illegal lone "<"! Ignore it...
+ */
+
+ free(t);
+ continue;
+ }
+
+ if (ch != '/')
+ ungetc(ch, fp);
+
+ if (parse_element(t, fp) < 0)
+ {
+ free(t);
+ break;
+ }
+
+ if ((closech = getc(fp)) == '/')
+ getc(fp);
+
+ /*
+ * If this is the matching close mark, or if we are starting the same
+ * element, or if we've completed a list, we're done!
+ */
+
+ if (ch == '/')
+ {
+ /*
+ * Close element; find matching element...
+ */
+
+ for (temp = p; temp != NULL; temp = temp->p)
+ if (temp->element == t->element)
+ break;
+
+ free(t);
+
+ if (temp != NULL)
+ break;
+ else
+ continue;
+ }
+ }
+ else if (t->preformatted)
+ {
+ /*
+ * Read a pre-formatted string into the current tree node...
+ */
+
+ ptr = s;
+ while (ch != '<' && ch != EOF && ptr < (s + sizeof(s) - 1))
+ {
+ if (ch == '&')
+ {
+ for (glyphptr = glyph;
+ (ch = getc(fp)) != EOF && (glyphptr - glyph) < 15;
+ glyphptr ++)
+ if (!isalnum(ch))
+ break;
+ else
+ *glyphptr = ch;
+
+ *glyphptr = '\0';
+ if (atoi(glyph) > 0)
+ ch = atoi(glyph);
+ else if (strcmp(glyph, "lt") == 0)
+ ch = '<';
+ else if (strcmp(glyph, "gt") == 0)
+ ch = '>';
+ else if (strcmp(glyph, "quot") == 0)
+ ch = '\'';
+ else if (strcmp(glyph, "nbsp") == 0)
+ ch = ' ';
+ else
+ ch = '&';
+ }
+
+ if (ch != 0)
+ *ptr++ = ch;
+
+ if (ch == '\n')
+ break;
+
+ ch = getc(fp);
+ }
+
+ *ptr = '\0';
+
+ if (ch == '<')
+ ungetc(ch, fp);
+
+ t->element = ELEMENT_FRAGMENT;
+ t->data = strdup(s);
+ }
+ else
+ {
+ /*
+ * Read the next string fragment...
+ */
+
+ ptr = s;
+ if (have_whitespace)
+ *ptr++ = ' ';
+
+ while (!isspace(ch) && ch != '<' && ch != EOF && ptr < (s + sizeof(s) - 1))
+ {
+ if (ch == '&')
+ {
+ for (glyphptr = glyph;
+ (ch = getc(fp)) != EOF && (glyphptr - glyph) < 15;
+ glyphptr ++)
+ if (!isalnum(ch))
+ break;
+ else
+ *glyphptr = ch;
+
+ *glyphptr = '\0';
+ if (atoi(glyph) > 0)
+ ch = atoi(glyph);
+ else if (strcmp(glyph, "lt") == 0)
+ ch = '<';
+ else if (strcmp(glyph, "gt") == 0)
+ ch = '>';
+ else if (strcmp(glyph, "quot") == 0)
+ ch = '\'';
+ else if (strcmp(glyph, "nbsp") == 0)
+ ch = ' ';
+ else
+ ch = '&';
+ }
+
+ if (ch != 0)
+ *ptr++ = ch;
+
+ ch = getc(fp);
+ }
+
+ if (isspace(ch))
+ *ptr++ = ' ';
+
+ *ptr = '\0';
+
+ if (ch == '<')
+ ungetc(ch, fp);
+
+ t->element = ELEMENT_FRAGMENT;
+ t->data = strdup(s);
+ }
+
+ /*
+ * If the p tree pointer is not NULL and this is the first
+ * entry we've read, set the child pointer...
+ */
+
+ if (p != NULL && prev == NULL)
+ p->child = t;
+
+ if (p != NULL)
+ p->last_child = t;
+
+ /*
+ * Do the prev/next links...
+ */
+
+ t->parent = p;
+ t->prev = prev;
+ if (prev != NULL)
+ prev->next = t;
+ else
+ tree = t;
+
+ prev = t;
+
+ /*
+ * Do child stuff as needed...
+ */
+
+ if (closech == '>')
+ t->child = formRead(t, fp);
+ }
+
+ return (tree);
+}
+
+
+/*
+ * 'formSetAttr()' - Set a node attribute.
+ */
+
+void
+formSetAttr(tree_t *t, /* I - Tree node */
+ const char *name, /* I - Attribute name */
+ const char *value) /* I - Attribute value */
+{
+}
+
+
+/*
+ * 'compare_attr()' - Compare two attributes.
+ */
+
+static int /* O - -1 if a0 < a1, etc. */
+compare_attr(attr_t *a0, /* I - First attribute */
+ attr_t *a1) /* I - Second attribute */
+{
+ return (strcasecmp(a0->name, a1->name));
+}
+
+
+/*
+ * 'compare_elements()' - Compare two elements.
+ */
+
+static int /* O - -1 if e0 < e1, etc. */
+compare_elements(char **e0, /* I - First element */
+ char **e1) /* I - Second element */
+{
+ return (strcasecmp(*e0, *e1));
+}
+
+
+/*
+ * 'parse_attr()' - Parse an element attribute string.
+ */
+
+static int /* O - -1 on error, 0 on success */
+parse_attr(tree_t *t, /* I - Current tree node */
+ FILE *fp) /* I - Input file */
+{
+ char name[1024], /* Name of attr */
+ value[10240], /* Value of attr */
+ *ptr; /* Temporary pointer */
+ int ch; /* Character from file */
+
+
+ ptr = name;
+ while ((ch = getc(fp)) != EOF)
+ if (isalnum(ch))
+ {
+ if (ptr < (name + sizeof(name) - 1))
+ *ptr++ = ch;
+ }
+ else
+ break;
+
+ *ptr = '\0';
+
+ while (isspace(ch) || ch == '\r')
+ ch = getc(fp);
+
+ switch (ch)
+ {
+ default :
+ ungetc(ch, fp);
+ return (formSetAttr(t, name, NULL));
+ case EOF :
+ return (-1);
+ case '=' :
+ ptr = value;
+ ch = getc(fp);
+
+ while (isspace(ch) || ch == '\r')
+ ch = getc(fp);
+
+ if (ch == EOF)
+ return (-1);
+
+ if (ch == '\'')
+ {
+ while ((ch = getc(fp)) != EOF)
+ if (ch == '\'')
+ break;
+ else if (ptr < (value + sizeof(value) - 1))
+ *ptr++ = ch;
+
+ *ptr = '\0';
+ }
+ else if (ch == '\"')
+ {
+ while ((ch = getc(fp)) != EOF)
+ if (ch == '\"')
+ break;
+ else if (ptr < (value + sizeof(value) - 1))
+ *ptr++ = ch;
+
+ *ptr = '\0';
+ }
+ else
+ {
+ *ptr++ = ch;
+ while ((ch = getc(fp)) != EOF)
+ if (isspace(ch) || ch == '>' || ch == '/' || ch == '\r')
+ break;
+ else if (ptr < (value + sizeof(value) - 1))
+ *ptr++ = ch;
+
+ *ptr = '\0';
+ if (ch == '>' || ch == '/')
+ ungetc(ch, fp);
+ }
+
+ return (formSetAttr(t, name, value));
+ }
+}
+
+
+/*
+ * 'parse_element()' - Parse an element.
+ */
+
+static int /* O - -1 on error or ELEMENT_nnnn */
+parse_element(tree_t *t, /* I - Current tree node */
+ FILE *fp) /* I - Input file */
+{
+ int ch; /* Character from file */
+ char element[255], /* Element string... */
+ *eptr, /* Current character... */
+ comment[10240], /* Comment string */
+ *cptr, /* Current char... */
+ **temp; /* Element variable entry */
+
+
+ eptr = element;
+
+ while ((ch = getc(fp)) != EOF && eptr < (element + sizeof(element) - 1))
+ if (ch == '>' || ch == '/' || isspace(ch))
+ break;
+ else
+ *eptr++ = ch;
+
+ *eptr = '\0';
+
+ if (ch == EOF)
+ return (ELEMENT_ERROR);
+
+ eptr = element;
+ temp = bsearch(&mptr, elements, sizeof(elements) / sizeof(elements[0]),
+ sizeof(elements[0]),
+ (int (*)(const void *, const void *))compare_elements);
+
+ if (temp == NULL)
+ {
+ /*
+ * Unrecognized element stuff...
+ */
+
+ t->element = ELEMENT_COMMENT;
+ strcpy(comment, element);
+ cptr = comment + strlen(comment);
+ }
+ else
+ {
+ t->element = (element_t)((char **)temp - elements);
+ cptr = comment;
+ }
+
+ if (t->element == ELEMENT_COMMENT)
+ {
+ while (ch != EOF && ch != '>' && cptr < (comment + sizeof(comment) - 1))
+ {
+ *cptr++ = ch;
+ ch = getc(fp);
+ }
+
+ *cptr = '\0';
+ t->data = strdup(comment);
+ }
+ else
+ {
+ while (ch != EOF && ch != '>' && ch != '/')
+ {
+ if (!isspace(ch))
+ {
+ ungetc(ch, fp);
+ parse_variable(t, fp);
+ }
+
+ ch = getc(fp);
+ }
+
+ if (ch != EOF)
+ ungetc(ch, fp);
+ }
+
+ return (t->element);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/form.h b/filter/form.h
new file mode 100644
index 000000000..3100049de
--- /dev/null
+++ b/filter/form.h
@@ -0,0 +1,177 @@
+/*
+ * "$Id$"
+ *
+ * CUPS form header file for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "common.h"
+
+
+/*
+ * Form elements...
+ */
+
+typedef enum
+{
+ ELEMENT_FILE = -1, /* Pseudo element, not in file, but above */
+ ELEMENT_FRAGMENT, /* Text fragment */
+ ELEMENT_COMMENT, /* <!-- .... --> */
+ ELEMENT_ARC,
+ ELEMENT_BOX,
+ ELEMENT_BR,
+ ELEMENT_B,
+ ELEMENT_CUPSFORM,
+ ELEMENT_DEFVAR,
+ ELEMENT_FONT,
+ ELEMENT_H1,
+ ELEMENT_H2,
+ ELEMENT_H3,
+ ELEMENT_H4,
+ ELEMENT_H5,
+ ELEMENT_H6,
+ ELEMENT_HEAD,
+ ELEMENT_IMG,
+ ELEMENT_I,
+ ELEMENT_LINE,
+ ELEMENT_PAGE,
+ ELEMENT_PIE,
+ ELEMENT_POLY,
+ ELEMENT_PRE,
+ ELEMENT_P,
+ ELEMENT_RECT,
+ ELEMENT_TEXT,
+ ELEMENT_TT,
+ ELEMENT_VAR
+} element_t;
+
+
+/*
+ * Font styles...
+ */
+
+typedef enum
+{
+ STYLE_NORMAL,
+ STYLE_BOLD,
+ STYLE_ITALIC,
+ STYLE_BOLD_ITALIC
+} style_t;
+
+
+/*
+ * Text alignments...
+ */
+
+typedef enum
+{
+ HALIGN_LEFT,
+ HALIGN_CENTER,
+ HALIGN_RIGHT
+} halign_t;
+
+typedef enum
+{
+ VALIGN_BOTTOM,
+ VALIGN_CENTER,
+ VALIGN_TOP
+} valign_t;
+
+
+/*
+ * Text directions...
+ */
+
+typedef enun
+{
+ DIR_LEFT_TO_RIGHT,
+ DIR_RIGHT_TO_LEFT
+} dir_t;
+
+
+/*
+ * Attribute structure...
+ */
+
+typedef struct
+{
+ char *name, /* Name of attribute */
+ *value; /* Value of attribute */
+} attr_t;
+
+
+/*
+ * Form document tree structure...
+ */
+
+typedef struct tree_str
+{
+ struct tree_str *prev, /* Previous tree node */
+ *next, /* Next tree node */
+ *parent, /* Parent tree node */
+ *child, /* First child node */
+ *last_child; /* Last child node */
+ element_t element; /* Element type */
+ float x, y, w, h; /* Position and size in points */
+ float bg[3], fg[3]; /* Colors of element */
+ float thickness; /* Thickness of lines */
+ int preformatted; /* Preformatted text? */
+ float size; /* Height of text in points */
+ char *typeface; /* Typeface of text */
+ style_t style; /* Style of text */
+ halign_t halign; /* Horizontal alignment */
+ valign_t valign; /* Vertical alignment */
+ dir_t dir; /* Direction of text */
+ int num_attrs; /* Number of attributes */
+ attr_t *attrs; /* Attributes */
+ void *data; /* Text fragment data */
+} tree_t;
+
+
+/*
+ * Globals...
+ */
+
+extern int NumOptions; /* Number of command-line options */
+extern cups_option_t *Options; /* Command-line options */
+extern ppd_file_t *PPD; /* PPD file */
+
+
+/*
+ * Prototypes...
+ */
+
+extern void formDelete(tree_t *t);
+extern char *formGetAttr(tree_t *t, const char *name);
+extern tree_t *formNew(tree_t *p);
+extern tree_t *formRead(FILE *fp, tree_t *p);
+extern void formSetAttr(tree_t *t, const char *name, const char *value);
+extern void formWrite(tree_t *p);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/hpgl-attr.c b/filter/hpgl-attr.c
new file mode 100644
index 000000000..2a5ee21a8
--- /dev/null
+++ b/filter/hpgl-attr.c
@@ -0,0 +1,454 @@
+/*
+ * "$Id$"
+ *
+ * HP-GL/2 attribute processing for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * CR_color_range() - Set the range for color values.
+ * AC_anchor_corner() - Set the anchor corner.
+ * FT_fill_type() - Set the fill type or pattern.
+ * LA_line_attributes() - Set the line drawing attributes.
+ * LT_line_type() - Set the line type (style)...
+ * NP_number_pens() - Set the number of pens to be used.
+ * PC_pen_color() - Set the pen color...
+ * PW_pen_width() - Set the pen width.
+ * RF_raster_fill() - Set the raster fill pattern.
+ * SM_symbol_mode() - Set where symbols are drawn.
+ * SP_select_pen() - Select a pen for drawing.
+ * UL_user_line_type() - Set a user-defined line type.
+ * WU_width_units() - Set the units used for pen widths.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "hpgltops.h"
+
+
+/*
+ * 'CR_color_range()' - Set the range for color values.
+ */
+
+void
+CR_color_range(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0)
+ {
+ /*
+ * Default to 0 to 255 for all color values.
+ */
+
+ ColorRange[0][0] = 0.0;
+ ColorRange[0][1] = 255.0;
+ ColorRange[1][0] = 0.0;
+ ColorRange[1][1] = 255.0;
+ ColorRange[2][0] = 0.0;
+ ColorRange[2][1] = 255.0;
+ }
+ else if (num_params == 6)
+ {
+ /*
+ * Set the range based on the parameters...
+ */
+
+ ColorRange[0][0] = params[0].value.number;
+ ColorRange[0][1] = params[1].value.number - params[0].value.number;
+ ColorRange[1][0] = params[2].value.number;
+ ColorRange[1][1] = params[3].value.number - params[2].value.number;
+ ColorRange[2][0] = params[4].value.number;
+ ColorRange[2][1] = params[5].value.number - params[4].value.number;
+ }
+ else
+ fprintf(stderr, "WARNING: HP-GL/2 \'CR\' command with invalid number of parameters (%d)!\n",
+ num_params);
+}
+
+
+/*
+ * 'AC_anchor_corner()' - Set the anchor corner.
+ */
+
+void
+AC_anchor_corner(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'FT_fill_type()' - Set the fill type or pattern.
+ *
+ * Note:
+ *
+ * This needs to be updated to support non-solid fill.
+ */
+
+void
+FT_fill_type(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0 ||
+ params[0].value.number == 1 ||
+ params[0].value.number == 2)
+ {
+ /**** SOLID PATTERN ****/
+ }
+}
+
+
+/*
+ * 'LA_line_attributes()' - Set the line drawing attributes.
+ */
+
+void
+LA_line_attributes(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ int i; /* Looping var */
+
+
+ if (num_params == 0)
+ {
+ MiterLimit = 3.0f;
+ LineCap = 0;
+ LineJoin = 0;
+ }
+ else for (i = 0; i < (num_params - 1); i += 2)
+ switch ((int)params[i].value.number)
+ {
+ case 1 :
+ LineCap = params[i + 1].value.number == 1 ? 0 :
+ params[i + 1].value.number == 4 ? 1 : 2;
+ break;
+ case 2 :
+ switch ((int)params[i + 1].value.number)
+ {
+ case 1 :
+ case 2 :
+ case 3 :
+ LineJoin = 0;
+ break;
+ case 5 :
+ LineJoin = 2;
+ break;
+ default :
+ LineJoin = 1;
+ break;
+ }
+ break;
+ case 3 :
+ MiterLimit = 1.0 + 0.5 * (params[i + 1].value.number - 1.0);
+ break;
+ }
+
+ if (PageDirty)
+ {
+ printf("%.1f setmiterlimit\n", MiterLimit);
+ printf("%d setlinecap\n", LineCap);
+ printf("%d setlinejoin\n", LineJoin);
+ }
+}
+
+
+/*
+ * 'LT_line_type()' - Set the line type (style)...
+ *
+ * Note:
+ *
+ * This needs to be updated to support line types.
+ */
+
+void
+LT_line_type(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'NP_number_pens()' - Set the number of pens to be used.
+ */
+
+void
+NP_number_pens(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ int i; /* Looping var */
+
+
+ if (num_params == 0)
+ PenCount = 8;
+ else if (num_params == 1 && params[0].value.number <= 1024)
+ PenCount = (int)params[0].value.number;
+ else
+ fprintf(stderr, "WARNING: HP-GL/2 \'NP\' command with invalid number of parameters (%d)!\n",
+ num_params);
+
+ for (i = 0; i <= PenCount; i ++)
+ Pens[i].width = PenWidth;
+
+ PC_pen_color(0, NULL);
+}
+
+
+/*
+ * 'PC_pen_color()' - Set the pen color...
+ */
+
+void
+PC_pen_color(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ int i; /* Looping var */
+ static float standard_colors[8][3] = /* Standard colors for first 8 pens */
+ {
+ { 1.0, 1.0, 1.0 }, /* White */
+ { 0.0, 0.0, 0.0 }, /* Black */
+ { 1.0, 0.0, 0.0 }, /* Red */
+ { 0.0, 1.0, 0.0 }, /* Green */
+ { 1.0, 1.0, 0.0 }, /* Yellow */
+ { 0.0, 0.0, 1.0 }, /* Blue */
+ { 1.0, 0.0, 1.0 }, /* Magenta */
+ { 0.0, 1.0, 1.0 } /* Cyan */
+ };
+
+
+ if (num_params == 0)
+ {
+ for (i = 0; i <= PenCount; i ++)
+ if (i < 8)
+ {
+ Pens[i].rgb[0] = standard_colors[i][0];
+ Pens[i].rgb[1] = standard_colors[i][1];
+ Pens[i].rgb[2] = standard_colors[i][2];
+ }
+ else
+ {
+ Pens[i].rgb[0] = 0.0f;
+ Pens[i].rgb[1] = 0.0f;
+ Pens[i].rgb[2] = 0.0f;
+ }
+
+ if (PageDirty)
+ printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0],
+ Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2],
+ Pens[PenNumber].width * PenScaling);
+ }
+ else if (num_params == 1 || num_params == 4)
+ {
+ i = (int)params[0].value.number;
+
+ if (num_params == 1)
+ {
+ Pens[i].rgb[0] = standard_colors[i & 7][0];
+ Pens[i].rgb[1] = standard_colors[i & 7][1];
+ Pens[i].rgb[2] = standard_colors[i & 7][2];
+ }
+ else
+ {
+ Pens[i].rgb[0] = (params[1].value.number - ColorRange[0][0]) /
+ (ColorRange[0][1] - ColorRange[0][0]);
+ Pens[i].rgb[1] = (params[2].value.number - ColorRange[1][0]) /
+ (ColorRange[1][1] - ColorRange[1][0]);
+ Pens[i].rgb[2] = (params[3].value.number - ColorRange[2][0]) /
+ (ColorRange[2][1] - ColorRange[2][0]);
+
+ fprintf(stderr, "DEBUG: Pen %d %.0f %.0f %.0f = %.3f %.3f %.3f\n",
+ i, params[1].value.number, params[2].value.number,
+ params[3].value.number, Pens[i].rgb[0], Pens[i].rgb[1],
+ Pens[i].rgb[2]);
+ }
+
+ if (PageDirty && i == PenNumber)
+ printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0],
+ Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2],
+ Pens[PenNumber].width * PenScaling);
+ }
+ else
+ fprintf(stderr, "WARNING: HP-GL/2 \'PC\' command with invalid number of parameters (%d)!\n",
+ num_params);
+}
+
+
+/*
+ * 'PW_pen_width()' - Set the pen width.
+ */
+
+void
+PW_pen_width(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ int pen; /* Pen number */
+ float w; /* Width value */
+
+
+ if (WidthUnits == 0)
+ {
+ /*
+ * Metric...
+ */
+
+ if (num_params == 0)
+ w = 0.35f / 25.4f * 72.0f;
+ else
+ w = params[0].value.number / 25.4f * 72.0f;
+ }
+ else
+ {
+ /*
+ * Relative...
+ */
+
+ w = (float)hypot(PlotSize[0], PlotSize[1]) / 1016.0f * 72.0f;
+
+ if (num_params == 0)
+ w *= 0.01f;
+ else
+ w *= params[0].value.number;
+ }
+
+ if (num_params == 2)
+ {
+ pen = (int)params[1].value.number;
+
+ Pens[pen].width = w;
+
+ if (PageDirty && pen == PenNumber)
+ printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0],
+ Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2],
+ Pens[PenNumber].width * PenScaling);
+ }
+ else if (num_params < 2)
+ {
+ /*
+ * Set width for all pens...
+ */
+
+ for (pen = 0; pen <= PenCount; pen ++)
+ Pens[pen].width = w;
+
+ if (PageDirty)
+ printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0],
+ Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2],
+ Pens[PenNumber].width * PenScaling);
+ }
+ else
+ fprintf(stderr, "WARNING: HP-GL/2 \'PW\' command with invalid number of parameters (%d)!\n",
+ num_params);
+}
+
+
+/*
+ * 'RF_raster_fill()' - Set the raster fill pattern.
+ *
+ * Note:
+ *
+ * This needs to be implemented.
+ */
+
+void
+RF_raster_fill(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'SM_symbol_mode()' - Set where symbols are drawn.
+ */
+
+void
+SM_symbol_mode(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'SP_select_pen()' - Select a pen for drawing.
+ */
+
+void
+SP_select_pen(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0)
+ PenNumber = 1;
+ else if (params[0].value.number <= PenCount)
+ PenNumber = (int)params[0].value.number;
+ else
+ fprintf(stderr, "WARNING: HP-GL/2 \'SP\' command with invalid number or value of parameters (%d, %d)!\n",
+ num_params, (int)params[0].value.number);
+
+ if (PageDirty)
+ printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0],
+ Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2],
+ Pens[PenNumber].width * PenScaling);
+}
+
+
+/*
+ * 'UL_user_line_type()' - Set a user-defined line type.
+ */
+
+void
+UL_user_line_type(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'WU_width_units()' - Set the units used for pen widths.
+ */
+
+void
+WU_width_units(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0)
+ WidthUnits = 0;
+ else if (num_params == 1)
+ WidthUnits = (int)params[0].value.number;
+ else
+ fprintf(stderr, "WARNING: HP-GL/2 \'WU\' command with invalid number of parameters (%d)!\n",
+ num_params);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/hpgl-char.c b/filter/hpgl-char.c
new file mode 100644
index 000000000..4378f2380
--- /dev/null
+++ b/filter/hpgl-char.c
@@ -0,0 +1,502 @@
+/*
+ * "$Id$"
+ *
+ * HP-GL/2 character processing for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * AD_define_alternate() - Define the alternate font.
+ * CF_character_fill() - Set whether or not to fill or outline
+ * characters.
+ * CP_character_plot() - Move the current pen position for the given
+ * number of columns and rows.
+ * DI_absolute_direction() - Set the direction vector for text.
+ * DR_relative_direction() - Set the relative direction vector for text.
+ * DT_define_label_term() - Set the label string terminator.
+ * DV_define_variable_path() - Define a path for text.
+ * ES_extra_space() - Set extra spacing (kerning) between characters.
+ * LB_label() - Display a label string.
+ * LO_label_origin() - Set the label origin.
+ * SA_select_alternate() - Select the alternate font.
+ * SD_define_standard() - Define the standard font...
+ * SI_absolute_size() - Set the absolute size of text.
+ * SL_character_slant() - Set the slant of text.
+ * SR_relative_size() - Set the relative size of text.
+ * SS_select_standard() - Select the standard font for text.
+ * TD_transparent_data() - Send transparent print data.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "hpgltops.h"
+
+
+/*
+ * 'AD_define_alternate()' - Define the alternate font.
+ */
+
+void
+AD_define_alternate(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ int i; /* Looping var */
+
+
+ /*
+ * Set default font attributes...
+ */
+
+ AlternateFont.typeface = 48;
+ AlternateFont.posture = 0;
+ AlternateFont.weight = 0;
+ AlternateFont.height = 11.5;
+
+ /*
+ * Loop through parameter value pairs...
+ */
+
+ for (i = 0; i < (num_params - 1); i += 2)
+ switch ((int)params[i].value.number)
+ {
+ case 4 :
+ AlternateFont.height = params[i + 1].value.number;
+ break;
+ case 5 :
+ AlternateFont.posture = (int)params[i + 1].value.number;
+ break;
+ case 6 :
+ AlternateFont.weight = (int)params[i + 1].value.number;
+ break;
+ case 7 :
+ AlternateFont.typeface = (int)params[i + 1].value.number;
+ break;
+ }
+
+ /*
+ * Define the font...
+ */
+
+ if (PageDirty)
+ printf("/SA {\n"
+ " /%s%s%s%s findfont\n"
+ " [ %f %f %f %f 0.0 0.0 ] makefont\n"
+ " setfont\n"
+ "} bind def\n",
+ AlternateFont.typeface == 48 ? "Courier" : "Helvetica",
+ (AlternateFont.weight != 0 || AlternateFont.posture != 0) ? "-" : "",
+ AlternateFont.weight != 0 ? "Bold" : "",
+ AlternateFont.posture != 0 ? "Oblique" : "",
+ AlternateFont.x * AlternateFont.height,
+ -AlternateFont.y * AlternateFont.height,
+ AlternateFont.y * AlternateFont.height,
+ AlternateFont.x * AlternateFont.height);
+
+ CharHeight[1] = AlternateFont.height;
+}
+
+
+/*
+ * 'CF_character_fill()' - Set whether or not to fill or outline characters.
+ */
+
+void
+CF_character_fill(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0)
+ CharFillMode = 0;
+ else
+ CharFillMode = (int)params[0].value.number;
+
+ if (num_params == 2)
+ CharPen = (int)params[1].value.number;
+}
+
+
+/*
+ * 'CP_character_plot()' - Move the current pen position for the given number
+ * of columns and rows.
+ */
+
+void
+CP_character_plot(int num_params,
+ param_t *params)
+{
+ if (num_params < 2)
+ return;
+
+ switch (Rotation)
+ {
+ case 0:
+ PenPosition[0] += params[0].value.number * 1.2f / CharHeight[CharFont];
+ PenPosition[1] += params[1].value.number * CharHeight[CharFont];
+ break;
+ case 90:
+ PenPosition[0] -= params[1].value.number * 1.2f / CharHeight[CharFont];
+ PenPosition[1] += params[0].value.number * CharHeight[CharFont];
+ break;
+ case 180:
+ PenPosition[0] -= params[0].value.number * 1.2f / CharHeight[CharFont];
+ PenPosition[1] -= params[1].value.number * CharHeight[CharFont];
+ break;
+ case 270:
+ PenPosition[0] += params[1].value.number * 1.2f / CharHeight[CharFont];
+ PenPosition[1] -= params[0].value.number * CharHeight[CharFont];
+ break;
+ }
+}
+
+
+/*
+ * 'DI_absolute_direction()' - Set the direction vector for text.
+ */
+
+void
+DI_absolute_direction(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (CharFont)
+ {
+ if (num_params == 2)
+ {
+ AlternateFont.x = params[0].value.number;
+ AlternateFont.y = params[1].value.number;
+ }
+
+ if (PageDirty)
+ {
+ printf("/SA {\n"
+ " /%s%s%s%s findfont\n"
+ " [ %f %f %f %f 0.0 0.0 ] makefont\n"
+ " setfont\n"
+ "} bind def\n",
+ AlternateFont.typeface == 48 ? "Courier" : "Helvetica",
+ (AlternateFont.weight != 0 || AlternateFont.posture != 0) ? "-" : "",
+ AlternateFont.weight != 0 ? "Bold" : "",
+ AlternateFont.posture != 0 ? "Oblique" : "",
+ AlternateFont.x * AlternateFont.height,
+ -AlternateFont.y * AlternateFont.height,
+ AlternateFont.y * AlternateFont.height,
+ AlternateFont.x * AlternateFont.height);
+ puts("SA");
+ }
+ }
+ else
+ {
+ if (num_params == 2)
+ {
+ StandardFont.x = params[0].value.number;
+ StandardFont.y = params[1].value.number;
+ }
+
+ if (PageDirty)
+ {
+ printf("/SS {\n"
+ " /%s%s%s%s findfont\n"
+ " [ %f %f %f %f 0.0 0.0 ] makefont\n"
+ " setfont\n"
+ "} bind def\n",
+ StandardFont.typeface == 48 ? "Courier" : "Helvetica",
+ (StandardFont.weight != 0 || StandardFont.posture != 0) ? "-" : "",
+ StandardFont.weight != 0 ? "Bold" : "",
+ StandardFont.posture != 0 ? "Oblique" : "",
+ StandardFont.x * StandardFont.height,
+ -StandardFont.y * StandardFont.height,
+ StandardFont.y * StandardFont.height,
+ StandardFont.x * StandardFont.height);
+ puts("SS");
+ }
+ }
+}
+
+
+/*
+ * 'DR_relative_direction()' - Set the relative direction vector for text.
+ */
+
+void
+DR_relative_direction(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'DT_define_label_term()' - Set the label string terminator.
+ */
+
+void
+DT_define_label_term(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0)
+ StringTerminator = '\003';
+ else
+ StringTerminator = params[0].value.string[0];
+}
+
+
+/*
+ * 'DV_define_variable_path()' - Define a path for text.
+ */
+
+void
+DV_define_variable_path(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'ES_extra_space()' - Set extra spacing (kerning) between characters.
+ */
+
+void
+ES_extra_space(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'LB_label()' - Display a label string.
+ */
+
+void
+LB_label(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ char *s; /* Pointer into string */
+
+
+ if (num_params == 0)
+ return;
+
+ Outputf("gsave\n");
+ Outputf("currentmiterlimit 1.0 \n");
+ Outputf("MP\n");
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+
+ Outputf("(");
+ for (s = params[0].value.string; *s != '\0'; s ++)
+ if (strchr("()\\", *s) != NULL)
+ Outputf("\\%c", *s);
+ else
+ Outputf("%c", *s);
+ Outputf(") true charpath\n");
+
+ if (CharFillMode != 1)
+ Outputf("FI\n");
+ if (CharFillMode == 1 || CharFillMode == 3)
+ {
+ Outputf("%.3f %.3f %.3f %.2f SP ST\n", Pens[CharPen].rgb[0],
+ Pens[CharPen].rgb[CharPen], Pens[CharPen].rgb[2],
+ Pens[CharPen].width * PenScaling);
+ Outputf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0],
+ Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2],
+ Pens[PenNumber].width * PenScaling);
+ }
+
+ Outputf("setmiterlimit\n");
+ Outputf("grestore\n");
+}
+
+
+/*
+ * 'LO_label_origin()' - Set the label origin.
+ */
+
+void
+LO_label_origin(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'SA_select_alternate()' - Select the alternate font.
+ */
+
+void
+SA_select_alternate(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+
+ if (PageDirty)
+ puts("SA");
+
+ CharFont = 1;
+}
+
+
+/*
+ * 'SD_define_standard()' - Define the standard font...
+ */
+
+void
+SD_define_standard(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ int i; /* Looping var */
+
+
+ /*
+ * Set default font attributes...
+ */
+
+ StandardFont.typeface = 48;
+ StandardFont.posture = 0;
+ StandardFont.weight = 0;
+ StandardFont.height = 11.5;
+ StandardFont.x = 1.0;
+ StandardFont.y = 0.0;
+
+ /*
+ * Loop through parameter value pairs...
+ */
+
+ for (i = 0; i < (num_params - 1); i += 2)
+ switch ((int)params[i].value.number)
+ {
+ case 4 :
+ StandardFont.height = params[i + 1].value.number;
+ break;
+ case 5 :
+ StandardFont.posture = (int)params[i + 1].value.number;
+ break;
+ case 6 :
+ StandardFont.weight = (int)params[i + 1].value.number;
+ break;
+ case 7 :
+ StandardFont.typeface = (int)params[i + 1].value.number;
+ break;
+ }
+
+ /*
+ * Define the font...
+ */
+
+ if (PageDirty)
+ printf("/SS {\n"
+ " /%s%s%s%s findfont\n"
+ " [ %f %f %f %f 0.0 0.0 ] makefont\n"
+ " setfont\n"
+ "} bind def\n",
+ StandardFont.typeface == 48 ? "Courier" : "Helvetica",
+ (StandardFont.weight != 0 || StandardFont.posture != 0) ? "-" : "",
+ StandardFont.weight != 0 ? "Bold" : "",
+ StandardFont.posture != 0 ? "Oblique" : "",
+ StandardFont.x * StandardFont.height,
+ -StandardFont.y * StandardFont.height,
+ StandardFont.y * StandardFont.height,
+ StandardFont.x * StandardFont.height);
+
+ CharHeight[0] = StandardFont.height;
+}
+
+
+/*
+ * 'SI_absolute_size()' - Set the absolute size of text.
+ */
+
+void
+SI_absolute_size(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'SL_character_slant()' - Set the slant of text.
+ */
+
+void
+SL_character_slant(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'SR_relative_size()' - Set the relative size of text.
+ */
+
+void
+SR_relative_size(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'SS_select_standard()' - Select the standard font for text.
+ */
+
+void
+SS_select_standard(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+
+ if (PageDirty)
+ puts("SS");
+
+ CharFont = 0;
+}
+
+
+/*
+ * 'TD_transparent_data()' - Send transparent print data.
+ */
+
+void
+TD_transparent_data(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/hpgl-config.c b/filter/hpgl-config.c
new file mode 100644
index 000000000..e56c88d73
--- /dev/null
+++ b/filter/hpgl-config.c
@@ -0,0 +1,643 @@
+/*
+ * "$Id$"
+ *
+ * HP-GL/2 configuration routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * update_transform() - Update the page transformation matrix as needed.
+ * BP_begin_plot() - Start a plot...
+ * DF_default_values() - Set all state info to the default values.
+ * IN_initialize() - Initialize the plotter.
+ * IP_input_absolute() - Set P1 and P2 values for the plot.
+ * IR_input_relative() - Update P1 and P2.
+ * IW_input_window() - Setup an input window.
+ * PG_advance_page() - Eject the current page.
+ * PS_plot_size() - Set the plot size.
+ * RO_rotate() - Rotate the plot.
+ * RP_replot() - Replot the current page.
+ * SC_scale() - Set user-defined scaling.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "hpgltops.h"
+
+#define max(a,b) ((a) < (b) ? (b) : (a))
+
+
+/*
+ * 'update_transform()' - Update the page transformation matrix as needed.
+ */
+
+void
+update_transform(void)
+{
+ float page_width, /* Actual page width */
+ page_height; /* Actual page height */
+ float scaling; /* Scaling factor */
+ float left, right, /* Scaling window */
+ bottom, top;
+ float width, height; /* Scaling width and height */
+ float iw1[2], iw2[2]; /* Clipping window */
+
+
+ /*
+ * Get the page and input window sizes...
+ */
+
+ if (FitPlot)
+ {
+ page_width = PageRight - PageLeft;
+ page_height = PageTop - PageBottom;
+ }
+ else
+ {
+ page_width = (P2[0] - P1[0]) * 72.0f / 1016.0f;
+ page_height = (P2[1] - P1[1]) * 72.0f / 1016.0f;
+ }
+
+ fprintf(stderr, "DEBUG: page_width = %.0f, page_height = %.0f\n",
+ page_width, page_height);
+
+ if (page_width == 0 || page_height == 0)
+ return;
+
+ /*
+ * Set the scaling window...
+ */
+
+ switch (ScalingType)
+ {
+ default : /* No user scaling */
+ left = P1[0];
+ bottom = P1[1];
+ right = P2[0];
+ top = P2[1];
+ break;
+
+ case 0 : /* Anisotropic (non-uniform) scaling */
+ left = Scaling1[0];
+ bottom = Scaling1[1];
+ right = Scaling2[0];
+ top = Scaling2[1];
+ break;
+
+ case 1 : /* Isotropic (uniform) scaling */
+ left = Scaling1[0];
+ bottom = Scaling1[1];
+ right = Scaling2[0];
+ top = Scaling2[1];
+
+ width = right - left;
+ height = top - bottom;
+
+ if (width == 0 || height == 0)
+ return;
+
+ if ((width * page_height) != (height * page_width))
+ {
+ scaling = height * page_width / page_height;
+ if (width < scaling)
+ {
+ width = scaling;
+ left = 0.5f * (left + right - width);
+ right = left + width;
+ }
+ else
+ {
+ height = width * page_height / page_width;
+ bottom = 0.5f * (bottom + top - height);
+ top = bottom + height;
+ }
+ }
+ break;
+
+ case 2 :
+ left = Scaling1[0];
+ bottom = Scaling1[1];
+ right = left + page_width * Scaling2[0] * 1016.0f / 72.0f;
+ top = bottom + page_height * Scaling2[1] * 1016.0f / 72.0f;
+ break;
+ }
+
+ width = right - left;
+ height = top - bottom;
+
+ if (width == 0 || height == 0)
+ return;
+
+ /*
+ * Scale the plot as needed...
+ */
+
+ if (Rotation == 0 || Rotation == 180)
+ scaling = page_width / width;
+ else
+ scaling = page_width / height;
+
+ if (FitPlot)
+ scaling *= max(page_width, page_height) / max(PlotSize[1], PlotSize[0]);
+
+ /*
+ * Offset for the current P1 location...
+ */
+
+ if (FitPlot)
+ {
+ left = 0;
+ bottom = 0;
+ }
+ else
+ {
+ left = P1[0] * 72.0f / 1016.0f;
+ bottom = P1[1] * 72.0f / 1016.0f;
+ }
+
+ /*
+ * Generate a new transformation matrix...
+ */
+
+ switch (Rotation)
+ {
+ case 0 :
+ Transform[0][0] = scaling;
+ Transform[0][1] = 0.0;
+ Transform[0][2] = -left;
+ Transform[1][0] = 0.0;
+ Transform[1][1] = scaling;
+ Transform[1][2] = -bottom;
+ break;
+
+ case 90 :
+ Transform[0][0] = 0.0;
+ Transform[0][1] = -scaling;
+ Transform[0][2] = PageLength - left;
+ Transform[1][0] = scaling;
+ Transform[1][1] = 0.0;
+ Transform[1][2] = -bottom;
+ break;
+
+ case 180 :
+ Transform[0][0] = -scaling;
+ Transform[0][1] = 0.0;
+ Transform[0][2] = PageLength - left;
+ Transform[1][0] = 0.0;
+ Transform[1][1] = -scaling;
+ Transform[1][2] = PageWidth - bottom;
+ break;
+
+ case 270 :
+ Transform[0][0] = 0.0;
+ Transform[0][1] = scaling;
+ Transform[0][2] = -left;
+ Transform[1][0] = -scaling;
+ Transform[1][1] = 0.0;
+ Transform[1][2] = PageWidth - bottom;
+ break;
+ }
+
+ fprintf(stderr, "DEBUG: Transform = [ %.3f %.3f\n"
+ "DEBUG: %.3f %.3f\n"
+ "DEBUG: %.3f %.3f ]\n",
+ Transform[0][0], Transform[1][0], Transform[0][1],
+ Transform[1][1], Transform[0][2], Transform[1][2]);
+
+ if (FitPlot)
+ {
+ if (Rotation == 0 || Rotation == 180)
+ PenScaling = page_width / PlotSize[1];
+ else
+ PenScaling = page_width / PlotSize[0];
+ }
+ else
+ PenScaling = 1.0;
+
+ if (PenScaling < 0.0)
+ PenScaling = -PenScaling;
+
+ if (PageDirty)
+ {
+ printf("%.2f setlinewidth\n", Pens[PenNumber].width * PenScaling);
+
+ if (IW1[0] != IW2[0] && IW1[1] != IW2[1])
+ {
+ iw1[0] = IW1[0] * 72.0f / 1016.0f;
+ iw1[1] = IW1[1] * 72.0f / 1016.0f;
+ iw2[0] = IW2[0] * 72.0f / 1016.0f;
+ iw2[1] = IW2[1] * 72.0f / 1016.0f;
+
+ printf("initclip MP %.3f %.3f MO %.3f %.3f LI %.3f %.3f LI %.3f %.3f LI CP clip\n",
+ iw1[0], iw1[1], iw1[0], iw2[1], iw2[0], iw2[1], iw2[0], iw1[1]);
+ }
+ }
+}
+
+
+/*
+ * 'BP_begin_plot()' - Start a plot...
+ */
+
+void
+BP_begin_plot(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'DF_default_values()' - Set all state info to the default values.
+ */
+
+void
+DF_default_values(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+
+ AC_anchor_corner(0, NULL);
+ AD_define_alternate(0, NULL);
+ SD_define_standard(0, NULL);
+ CF_character_fill(0, NULL);
+ DI_absolute_direction(0, NULL);
+ DT_define_label_term(0, NULL);
+ DV_define_variable_path(0, NULL);
+ ES_extra_space(0, NULL);
+ FT_fill_type(0, NULL);
+ IW_input_window(0, NULL);
+ LA_line_attributes(0, NULL);
+ LO_label_origin(0, NULL);
+ LT_line_type(0, NULL);
+ PA_plot_absolute(0, NULL);
+ PolygonMode = 0;
+ RF_raster_fill(0, NULL);
+ SC_scale(0, NULL);
+ SM_symbol_mode(0, NULL);
+ SS_select_standard(0, NULL);
+ TD_transparent_data(0, NULL);
+ UL_user_line_type(0, NULL);
+}
+
+
+/*
+ * 'IN_initialize()' - Initialize the plotter.
+ */
+
+void
+IN_initialize(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+
+ DF_default_values(0, NULL);
+ PU_pen_up(0, NULL);
+ RO_rotate(0, NULL);
+ PS_plot_size(0, NULL);
+ WU_width_units(0, NULL);
+ PW_pen_width(0, NULL);
+
+ PenWidth = 1;
+
+ PenPosition[0] = PenPosition[1] = 0.0;
+}
+
+
+/*
+ * 'IP_input_absolute()' - Set P1 and P2 values for the plot.
+ */
+
+void
+IP_input_absolute(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0)
+ {
+ P1[0] = PageLeft / 72.0f * 1016.0f;
+ P1[1] = PageBottom / 72.0f * 1016.0f;
+ P2[0] = PageRight / 72.0f * 1016.0f;
+ P2[1] = PageTop / 72.0f * 1016.0f;
+ }
+ else if (num_params == 2)
+ {
+ P2[0] -= P1[0];
+ P2[1] -= P1[1];
+ P1[0] = params[0].value.number;
+ P1[1] = params[1].value.number;
+ P2[0] += P1[0];
+ P2[1] += P1[1];
+ }
+ else if (num_params == 4)
+ {
+ P1[0] = params[0].value.number;
+ P1[1] = params[1].value.number;
+ P2[0] = params[2].value.number;
+ P2[1] = params[3].value.number;
+ }
+
+ IW1[0] = 0.0;
+ IW1[1] = 0.0;
+ IW2[0] = 0.0;
+ IW2[1] = 0.0;
+
+ if (ScalingType < 0)
+ {
+ Scaling1[0] = P1[0];
+ Scaling1[0] = P1[1];
+ Scaling2[0] = P2[0];
+ Scaling2[1] = P2[1];
+ }
+
+ update_transform();
+}
+
+
+/*
+ * 'IR_input_relative()' - Update P1 and P2.
+ */
+
+void
+IR_input_relative(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0)
+ {
+ P1[0] = PageLeft / 72.0f * 1016.0f;
+ P1[1] = PageBottom / 72.0f * 1016.0f;
+ P2[0] = PageRight / 72.0f * 1016.0f;
+ P2[1] = PageTop / 72.0f * 1016.0f;
+ }
+ else if (num_params == 2)
+ {
+ P2[0] -= P1[0];
+ P2[1] -= P1[1];
+ P1[0] = params[0].value.number * PlotSize[0] / 72.0f * 1016.0f / 100.0f;
+ P1[1] = params[1].value.number * PlotSize[1] / 72.0f * 1016.0f / 100.0f;
+ P2[0] += P1[0];
+ P2[1] += P1[1];
+ }
+ else if (num_params == 4)
+ {
+ P1[0] = params[0].value.number * PlotSize[0] / 72.0f * 1016.0f / 100.0f;
+ P1[1] = params[1].value.number * PlotSize[1] / 72.0f * 1016.0f / 100.0f;
+ P2[0] = params[2].value.number * PlotSize[0] / 72.0f * 1016.0f / 100.0f;
+ P2[1] = params[3].value.number * PlotSize[1] / 72.0f * 1016.0f / 100.0f;
+ }
+
+ IW1[0] = 0.0;
+ IW1[1] = 0.0;
+ IW2[0] = 0.0;
+ IW2[1] = 0.0;
+
+ if (ScalingType < 0)
+ {
+ Scaling1[0] = P1[0];
+ Scaling1[0] = P1[1];
+ Scaling2[0] = P2[0];
+ Scaling2[1] = P2[1];
+ }
+
+ update_transform();
+}
+
+
+/*
+ * 'IW_input_window()' - Setup an input window.
+ */
+
+void
+IW_input_window(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0)
+ {
+ IW1[0] = PageLeft / 72.0f * 1016.0f;
+ IW1[1] = PageBottom / 72.0f * 1016.0f;
+ IW2[0] = PageRight / 72.0f * 1016.0f;
+ IW2[1] = PageTop / 72.0f * 1016.0f;
+ }
+ else if (num_params == 4)
+ {
+
+ if (ScalingType < 0)
+ {
+ IW1[0] = params[0].value.number;
+ IW1[1] = params[1].value.number;
+ IW2[0] = params[2].value.number;
+ IW2[1] = params[3].value.number;
+ }
+ else
+ {
+ IW1[0] = (Transform[0][0] * params[0].value.number +
+ Transform[0][1] * params[1].value.number +
+ Transform[0][2]) / 72.0f * 1016.0f;
+ IW1[1] = (Transform[1][0] * params[0].value.number +
+ Transform[1][1] * params[1].value.number +
+ Transform[1][2]) / 72.0f * 1016.0f;
+ IW2[0] = (Transform[0][0] * params[2].value.number +
+ Transform[0][1] * params[3].value.number +
+ Transform[0][2]) / 72.0f * 1016.0f;
+ IW2[1] = (Transform[1][0] * params[2].value.number +
+ Transform[1][1] * params[3].value.number +
+ Transform[1][2]) / 72.0f * 1016.0f;
+ }
+
+ fprintf(stderr, "DEBUG: IW%.0f,%.0f,%.0f,%.0f = [ %.0f %.0f %.0f %.0f ]\n",
+ params[0].value.number, params[1].value.number,
+ params[2].value.number, params[3].value.number,
+ IW1[0], IW1[1], IW2[0], IW2[1]);
+ }
+
+
+ update_transform();
+}
+
+
+/*
+ * 'PG_advance_page()' - Eject the current page.
+ */
+
+void
+PG_advance_page(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+
+ if (PageDirty)
+ {
+ puts("grestore");
+ puts("showpage");
+
+ PageDirty = 0;
+ }
+}
+
+
+/*
+ * 'PS_plot_size()' - Set the plot size.
+ */
+
+void
+PS_plot_size(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ switch (num_params)
+ {
+ case 0 : /* PS ; */
+ if (Rotation == 0 || Rotation == 180)
+ {
+ PlotSize[0] = PageWidth;
+ PlotSize[1] = PageLength;
+ }
+ else
+ {
+ PlotSize[0] = PageLength;
+ PlotSize[1] = PageWidth;
+ }
+
+ PlotSizeSet = 0;
+ break;
+ case 1 : /* PS length ; */
+ if (Rotation == 0 || Rotation == 180)
+ {
+ PlotSize[1] = 72.0f * params[0].value.number / 1016.0f;
+ PlotSize[0] = 0.75f * PlotSize[1];
+ }
+ else
+ {
+ PlotSize[0] = 72.0f * params[0].value.number / 1016.0f;
+ PlotSize[1] = 0.75f * PlotSize[0];
+ }
+
+ PlotSizeSet = 1;
+ break;
+ case 2 : /* PS length, width ; */
+ /*
+ * Unfortunately, it appears that NO application correctly
+ * sends a two-argument PS command as documented in the
+ * HP-GL/2 Reference Manual from HP. Instead, applications
+ * send the width before the length, which causes all sorts
+ * of problems when scaling.
+ *
+ * Rather than fight it, we now look for them as width,length
+ * instead of length,width.
+ *
+ * Don't like it? Send mail to the folks that make Ideas, Pro/E,
+ * AutoCAD, etc.
+ */
+
+ if (Rotation == 0 || Rotation == 180)
+ {
+ PlotSize[0] = 72.0f * params[0].value.number / 1016.0f;
+ PlotSize[1] = 72.0f * params[1].value.number / 1016.0f;
+ }
+ else
+ {
+ PlotSize[0] = 72.0f * params[1].value.number / 1016.0f;
+ PlotSize[1] = 72.0f * params[0].value.number / 1016.0f;
+ }
+
+ PlotSizeSet = 1;
+ break;
+ }
+
+ /*
+ * This is required for buggy files that don't set the input window.
+ */
+
+ IP_input_absolute(0, NULL);
+}
+
+
+/*
+ * 'RO_rotate()' - Rotate the plot.
+ */
+
+void
+RO_rotate(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0)
+ Rotation = 0;
+ else
+ Rotation = (int)params[0].value.number;
+
+ update_transform();
+}
+
+
+/*
+ * 'RP_replot()' - Replot the current page.
+ */
+
+void
+RP_replot(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+}
+
+
+/*
+ * 'SC_scale()' - Set user-defined scaling.
+ */
+
+void
+SC_scale(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0)
+ {
+ ScalingType = -1;
+ Scaling1[0] = P1[0];
+ Scaling1[0] = P1[1];
+ Scaling2[0] = P2[0];
+ Scaling2[1] = P2[1];
+ }
+ else if (num_params > 3)
+ {
+ Scaling1[0] = params[0].value.number;
+ Scaling2[0] = params[1].value.number;
+ Scaling1[1] = params[2].value.number;
+ Scaling2[1] = params[3].value.number;
+
+ if (num_params > 4)
+ ScalingType = (int)params[4].value.number;
+ else
+ ScalingType = 1;
+ }
+
+ update_transform();
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/hpgl-input.c b/filter/hpgl-input.c
new file mode 100644
index 000000000..19b95fae1
--- /dev/null
+++ b/filter/hpgl-input.c
@@ -0,0 +1,234 @@
+/*
+ * "$Id$"
+ *
+ * HP-GL/2 input processing for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ParseCommand() - Parse an HPGL/2 command.
+ * FreeParameters() - Free all string parameter values.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "hpgltops.h"
+#include <ctype.h>
+
+#define MAX_PARAMS 16384
+
+
+/*
+ * 'ParseCommand()' - Parse an HPGL/2 command.
+ *
+ * Returns the number of parameters seen or -1 on EOF.
+ */
+
+int /* O - -1 on EOF, # params otherwise */
+ParseCommand(FILE *fp, /* I - File to read from */
+ char *name, /* O - Name of command */
+ param_t **params) /* O - Parameter list */
+{
+ int num_params, /* Number of parameters seen */
+ ch, /* Current char */
+ done, /* Non-zero when the current command is read */
+ i; /* Looping var */
+ char buf[262144]; /* String buffer */
+ static param_t p[MAX_PARAMS]; /* Parameter buffer */
+
+
+ num_params = 0;
+ done = 0;
+
+ do
+ {
+ while ((ch = getc(fp)) != EOF)
+ if (strchr(" \t\r\n,;", ch) == NULL)
+ break;
+
+ if (ch == EOF)
+ return (-1);
+
+ if (ch == 0x1b)
+ switch (getc(fp))
+ {
+ case '.' : /* HP-GL/2 job control */
+ i = getc(fp);
+
+ if (strchr(")Z", i) != NULL)
+ {
+ /*
+ * 'Printer Off' command - look for next 'Printer On' command...
+ */
+
+ for (;;)
+ {
+ while ((i = getc(fp)) != EOF && i != 0x1b);
+
+ if (i == EOF)
+ return (-1);
+
+ if (getc(fp) != '.')
+ continue;
+
+ if ((i = getc(fp)) == '(' ||
+ i == 'Y')
+ break;
+ }
+ }
+ else if (strchr("@HIMNTI\003", i) != NULL)
+ {
+ while ((i = getc(fp)) != EOF && i != ':');
+ }
+ break;
+
+ default : /* HP RTL/PCL control */
+ while ((i = getc(fp)) != EOF && !isupper(i));
+ break;
+ }
+ } while (ch == 0x1b);
+
+ name[0] = ch;
+ name[1] = getc(fp);
+ name[2] = '\0';
+
+ if (strcasecmp(name, "LB") == 0)
+ {
+ for (i = 0; (ch = getc(fp)) != StringTerminator; i ++)
+ buf[i] = ch;
+ buf[i] = '\0';
+ p[num_params].type = PARAM_STRING;
+ p[num_params].value.string = strdup(buf);
+ num_params ++;
+ }
+ else if (strcasecmp(name, "SM") == 0)
+ {
+ buf[0] = getc(fp);
+ buf[1] = '\0';
+ p[num_params].type = PARAM_STRING;
+ p[num_params].value.string = strdup(buf);
+ num_params ++;
+ }
+ else if (strcasecmp(name, "DT") == 0)
+ {
+ if ((buf[0] = getc(fp)) != ';')
+ {
+ buf[1] = '\0';
+ p[num_params].type = PARAM_STRING;
+ p[num_params].value.string = strdup(buf);
+ num_params ++;
+ }
+ }
+ else if (strcasecmp(name, "PE") == 0)
+ {
+ for (i = 0; i < (sizeof(buf) - 1); i ++)
+ if ((buf[i] = getc(fp)) == ';')
+ break;
+
+ buf[i] = '\0';
+ p[num_params].type = PARAM_STRING;
+ p[num_params].value.string = strdup(buf);
+ num_params ++;
+ }
+
+ while (!done)
+ switch (ch = getc(fp))
+ {
+ case ',' :
+ case ' ' :
+ case '\n' :
+ case '\r' :
+ case '\t' :
+ break;
+
+ case '\"' :
+ fscanf(fp, "%262143[^\"]\"", buf);
+ if (num_params < MAX_PARAMS)
+ {
+ p[num_params].type = PARAM_STRING;
+ p[num_params].value.string = strdup(buf);
+ num_params ++;
+ };
+ break;
+
+ case '-' :
+ case '+' :
+ ungetc(ch, fp);
+ fscanf(fp, "%f", &(p[num_params].value.number));
+ if (num_params < MAX_PARAMS)
+ {
+ p[num_params].type = PARAM_RELATIVE;
+ num_params ++;
+ }
+ break;
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ case '.' :
+ ungetc(ch, fp);
+ fscanf(fp, "%f", &(p[num_params].value.number));
+ if (num_params < MAX_PARAMS)
+ {
+ p[num_params].type = PARAM_ABSOLUTE;
+ num_params ++;
+ }
+ break;
+ default :
+ ungetc(ch, fp);
+ done = 1;
+ break;
+ }
+
+ *params = p;
+ return (num_params);
+}
+
+
+/*
+ * 'FreeParameters()' - Free all string parameter values.
+ */
+
+void
+FreeParameters(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameter values */
+{
+ int i; /* Looping var */
+
+
+ for (i = 0; i < num_params; i ++)
+ if (params[i].type == PARAM_STRING)
+ free(params[i].value.string);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/hpgl-main.c b/filter/hpgl-main.c
new file mode 100644
index 000000000..950bd99d4
--- /dev/null
+++ b/filter/hpgl-main.c
@@ -0,0 +1,267 @@
+/*
+ * "$Id$"
+ *
+ * HP-GL/2 filter main entry for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Main entry for HP-GL/2 filter.
+ * compare_names() - Compare two command names.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+/*#define DEBUG*/
+#define _HPGL_MAIN_C_
+#include "hpgltops.h"
+
+
+/*
+ * HP-GL/2 command table...
+ */
+
+typedef struct
+{
+ char name[4]; /* Name of command */
+ void (*func)(int, param_t *); /* Function to call */
+} name_t;
+
+static name_t commands[] =
+{
+ { "BP", BP_begin_plot },
+ { "DF", DF_default_values },
+ { "IN", IN_initialize },
+ { "IP", IP_input_absolute },
+ { "IR", IR_input_relative },
+ { "IW", IW_input_window },
+ { "PG", PG_advance_page },
+ { "RO", RO_rotate },
+ { "RP", RP_replot },
+ { "SC", SC_scale },
+ { "AA", AA_arc_absolute },
+ { "AR", AR_arc_relative },
+ { "AT", AT_arc_absolute3 },
+ { "CI", CI_circle },
+ { "PA", PA_plot_absolute },
+ { "PD", PD_pen_down },
+ { "PE", PE_polyline_encoded },
+ { "PR", PR_plot_relative },
+ { "PS", PS_plot_size },
+ { "PU", PU_pen_up },
+ { "RT", RT_arc_relative3 },
+ { "EA", EA_edge_rect_absolute },
+ { "EP", EP_edge_polygon },
+ { "ER", ER_edge_rect_relative },
+ { "EW", EW_edge_wedge },
+ { "FP", FP_fill_polygon },
+ { "PM", PM_polygon_mode },
+ { "RA", RA_fill_rect_absolute },
+ { "RR", RR_fill_rect_relative },
+ { "WG", WG_fill_wedge },
+ { "AD", AD_define_alternate },
+ { "CF", CF_character_fill },
+ { "CP", CP_character_plot },
+ { "DI", DI_absolute_direction },
+ { "DR", DR_relative_direction },
+ { "DT", DT_define_label_term },
+ { "DV", DV_define_variable_path },
+ { "ES", ES_extra_space },
+ { "LB", LB_label },
+ { "LO", LO_label_origin },
+ { "SA", SA_select_alternate },
+ { "SD", SD_define_standard },
+ { "SI", SI_absolute_size },
+ { "SL", SL_character_slant },
+ { "SR", SR_relative_size },
+ { "SS", SS_select_standard },
+ { "TD", TD_transparent_data },
+ { "AC", AC_anchor_corner },
+ { "FT", FT_fill_type },
+ { "LA", LA_line_attributes },
+ { "LT", LT_line_type },
+ { "NP", NP_number_pens },
+ { "PC", PC_pen_color },
+ { "CR", CR_color_range },
+ { "PW", PW_pen_width },
+ { "RF", RF_raster_fill },
+ { "SM", SM_symbol_mode },
+ { "SP", SP_select_pen },
+ { "UL", UL_user_line_type },
+ { "WU", WU_width_units }
+};
+#define NUM_COMMANDS (sizeof(commands) / sizeof(name_t))
+
+
+/*
+ * Local functions...
+ */
+
+static int compare_names(const void *p1, const void *p2);
+
+
+/*
+ * 'main()' - Main entry for HP-GL/2 filter.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ FILE *fp; /* Input file */
+ int num_params; /* Number of parameters */
+ param_t *params; /* Command parameters */
+ name_t *command, /* Command */
+ name; /* Name of command */
+ int num_options; /* Number of print options */
+ cups_option_t *options; /* Print options */
+ const char *val; /* Option value */
+ int shading; /* -1 = black, 0 = grey, 1 = color */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fputs("ERROR: hpgltops job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+ if (argc == 6)
+ fp = stdin;
+ else
+ {
+ /*
+ * Try to open the print file...
+ */
+
+ if ((fp = fopen(argv[6], "rb")) == NULL)
+ {
+ perror("ERROR: unable to open print file - ");
+ return (1);
+ }
+ }
+
+ /*
+ * Process command-line options and write the prolog...
+ */
+
+ options = NULL;
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ PPD = SetCommonOptions(num_options, options, 1);
+
+ PlotSize[0] = PageWidth;
+ PlotSize[1] = PageLength;
+
+ shading = 1;
+ PenWidth = 1.0;
+
+ if ((val = cupsGetOption("blackplot", num_options, options)) != NULL)
+ shading = 0;
+
+ if ((val = cupsGetOption("fitplot", num_options, options)) != NULL)
+ FitPlot = 1;
+
+ if ((val = cupsGetOption("penwidth", num_options, options)) != NULL)
+ PenWidth = (float)atoi(val) * 0.001f;
+
+ /*
+ * Write the PostScript prolog and initialize the plotting "engine"...
+ */
+
+ OutputProlog(argv[3], argv[2], shading);
+
+ IP_input_absolute(0, NULL);
+
+ /*
+ * Sort the command array...
+ */
+
+ qsort(commands, NUM_COMMANDS, sizeof(name_t),
+ (int (*)(const void *, const void *))compare_names);
+
+ /*
+ * Read commands until we reach the end of file.
+ */
+
+ while ((num_params = ParseCommand(fp, name.name, &params)) >= 0)
+ {
+#ifdef DEBUG
+ {
+ int i;
+ fprintf(stderr, "DEBUG: %s(%d)", name.name, num_params);
+ for (i = 0; i < num_params; i ++)
+ if (params[i].type == PARAM_STRING)
+ fprintf(stderr, " \'%s\'", params[i].value.string);
+ else
+ fprintf(stderr, " %f", params[i].value.number);
+ fputs("\n", stderr);
+ }
+#endif /* DEBUG */
+
+ if ((command = bsearch(&name, commands, NUM_COMMANDS, sizeof(name_t),
+ (int (*)(const void *, const void *))compare_names)) != NULL)
+ (*command->func)(num_params, params);
+
+ FreeParameters(num_params, params);
+ }
+
+ OutputTrailer();
+
+ if (fp != stdin)
+ fclose(fp);
+
+ return (0);
+}
+
+
+/*
+ * 'compare_names()' - Compare two command names.
+ */
+
+static int /* O - Result of strcasecmp() on names */
+compare_names(const void *p1, /* I - First name */
+ const void *p2) /* I - Second name */
+{
+ return (strcasecmp(((name_t *)p1)->name, ((name_t *)p2)->name));
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/hpgl-polygon.c b/filter/hpgl-polygon.c
new file mode 100644
index 000000000..c666b8964
--- /dev/null
+++ b/filter/hpgl-polygon.c
@@ -0,0 +1,382 @@
+/*
+ * "$Id$"
+ *
+ * HP-GL/2 polygon routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * EA_edge_rect_absolute() - Draw a rectangle.
+ * EP_edge_polygon() - Stroke the edges of a polygon.
+ * ER_edge_rect_relative() - Draw a rectangle relative to the current
+ * EW_edge_wedge() - Draw a pie wedge.
+ * FP_fill_polygon() - Fill a polygon.
+ * PM_polygon_mode() - Set the polygon drawing mode.
+ * RA_fill_rect_absolute() - Fill a rectangle.
+ * RR_fill_rect_relative() - Fill a rectangle relative to the current
+ * WG_fill_wedge() - Fill a pie wedge.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "hpgltops.h"
+
+
+/*
+ * 'EA_edge_rect_absolute()' - Draw a rectangle.
+ */
+
+void
+EA_edge_rect_absolute(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ float x, y; /* Transformed coordinates */
+
+
+ if (num_params < 2)
+ return;
+
+ x = Transform[0][0] * params[0].value.number +
+ Transform[0][1] * params[1].value.number +
+ Transform[0][2];
+ y = Transform[1][0] * params[0].value.number +
+ Transform[1][1] * params[1].value.number +
+ Transform[1][2];
+
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+ Outputf("%.3f %.3f LI\n", PenPosition[0], y);
+ Outputf("%.3f %.3f LI\n", x, y);
+ Outputf("%.3f %.3f LI\n", x, PenPosition[1]);
+
+ Outputf("CP\n");
+ if (!PolygonMode)
+ Outputf("ST\n");
+}
+
+
+/*
+ * 'EP_edge_polygon()' - Stroke the edges of a polygon.
+ */
+
+void
+EP_edge_polygon(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+
+ Outputf("ST\n");
+}
+
+
+/*
+ * 'ER_edge_rect_relative()' - Draw a rectangle relative to the current
+ * pen position.
+ */
+
+void
+ER_edge_rect_relative(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ float x, y; /* Transformed coordinates */
+
+
+ if (num_params < 2)
+ return;
+
+ x = Transform[0][0] * params[0].value.number +
+ Transform[0][1] * params[1].value.number +
+ PenPosition[0];
+ y = Transform[1][0] * params[0].value.number +
+ Transform[1][1] * params[1].value.number +
+ PenPosition[1];
+
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+ Outputf("%.3f %.3f LI\n", PenPosition[0], y);
+ Outputf("%.3f %.3f LI\n", x, y);
+ Outputf("%.3f %.3f LI\n", x, PenPosition[1]);
+
+ Outputf("CP\n");
+ if (!PolygonMode)
+ Outputf("ST\n");
+}
+
+
+/*
+ * 'EW_edge_wedge()' - Draw a pie wedge.
+ */
+
+void
+EW_edge_wedge(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ float x, y; /* Transformed coordinates */
+ float start, end, /* Start and end of arc */
+ theta, /* Current angle */
+ dt, /* Step between points */
+ radius; /* Radius of arc */
+
+
+ if (num_params < 3)
+ return;
+
+ radius = params[0].value.number;
+ start = params[1].value.number;
+ end = start + params[2].value.number;
+
+ if (num_params > 3)
+ dt = (float)fabs(params[3].value.number);
+ else
+ dt = 5.0f;
+
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+
+ if (start < end)
+ for (theta = start + dt; theta < end; theta += dt)
+ {
+ x = (float)(PenPosition[0] +
+ radius * cos(M_PI * theta / 180.0) * Transform[0][0] +
+ radius * sin(M_PI * theta / 180.0) * Transform[0][1]);
+ y = (float)(PenPosition[1] +
+ radius * cos(M_PI * theta / 180.0) * Transform[1][0] +
+ radius * sin(M_PI * theta / 180.0) * Transform[1][1]);
+
+ Outputf("%.3f %.3f LI\n", x, y);
+ }
+ else
+ for (theta = start - dt; theta > end; theta -= dt)
+ {
+ x = (float)(PenPosition[0] +
+ radius * cos(M_PI * theta / 180.0) * Transform[0][0] +
+ radius * sin(M_PI * theta / 180.0) * Transform[0][1]);
+ y = (float)(PenPosition[1] +
+ radius * cos(M_PI * theta / 180.0) * Transform[1][0] +
+ radius * sin(M_PI * theta / 180.0) * Transform[1][1]);
+
+ Outputf("%.3f %.3f LI\n", x, y);
+ }
+
+ x = (float)(PenPosition[0] +
+ radius * cos(M_PI * end / 180.0) * Transform[0][0] +
+ radius * sin(M_PI * end / 180.0) * Transform[0][1]);
+ y = (float)(PenPosition[1] +
+ radius * cos(M_PI * end / 180.0) * Transform[1][0] +
+ radius * sin(M_PI * end / 180.0) * Transform[1][1]);
+ Outputf("%.3f %.3f LI\n", x, y);
+
+ Outputf("CP\n");
+ if (!PolygonMode)
+ Outputf("ST\n");
+}
+
+
+/*
+ * 'FP_fill_polygon()' - Fill a polygon.
+ */
+
+void
+FP_fill_polygon(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ (void)num_params;
+ (void)params;
+
+ Outputf("FI\n");
+}
+
+
+/*
+ * 'PM_polygon_mode()' - Set the polygon drawing mode.
+ */
+
+void
+PM_polygon_mode(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params == 0 ||
+ params[0].value.number == 0)
+ {
+ Outputf("MP\n");
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+ PolygonMode = 1;
+ }
+ else if (params[0].value.number == 2)
+ PolygonMode = 0;
+}
+
+
+/*
+ * 'RA_fill_rect_absolute()' - Fill a rectangle.
+ */
+
+void
+RA_fill_rect_absolute(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ float x, y; /* Transformed coordinates */
+
+
+ if (num_params < 2)
+ return;
+
+ x = Transform[0][0] * params[0].value.number +
+ Transform[0][1] * params[1].value.number +
+ Transform[0][2];
+ y = Transform[1][0] * params[0].value.number +
+ Transform[1][1] * params[1].value.number +
+ Transform[1][2];
+
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+ Outputf("%.3f %.3f LI\n", PenPosition[0], y);
+ Outputf("%.3f %.3f LI\n", x, y);
+ Outputf("%.3f %.3f LI\n", x, PenPosition[1]);
+
+ Outputf("CP\n");
+ if (!PolygonMode)
+ Outputf("FI\n");
+}
+
+
+/*
+ * 'RR_fill_rect_relative()' - Fill a rectangle relative to the current
+ * pen position.
+ */
+
+void
+RR_fill_rect_relative(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ float x, y; /* Transformed coordinates */
+
+
+ if (num_params < 2)
+ return;
+
+ x = Transform[0][0] * params[0].value.number +
+ Transform[0][1] * params[1].value.number +
+ PenPosition[0];
+ y = Transform[1][0] * params[0].value.number +
+ Transform[1][1] * params[1].value.number +
+ PenPosition[1];
+
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+ Outputf("%.3f %.3f LI\n", PenPosition[0], y);
+ Outputf("%.3f %.3f LI\n", x, y);
+ Outputf("%.3f %.3f LI\n", x, PenPosition[1]);
+
+ Outputf("CP\n");
+ if (!PolygonMode)
+ Outputf("FI\n");
+}
+
+
+/*
+ * 'WG_fill_wedge()' - Fill a pie wedge.
+ */
+
+void
+WG_fill_wedge(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ float x, y; /* Transformed coordinates */
+ float start, end, /* Start and end angles */
+ theta, /* Current angle */
+ dt, /* Step between points */
+ radius; /* Radius of arc */
+
+
+ if (num_params < 3)
+ return;
+
+ radius = params[0].value.number;
+ start = params[1].value.number;
+ end = start + params[2].value.number;
+
+ if (num_params > 3)
+ dt = (float)fabs(params[3].value.number);
+ else
+ dt = 5.0;
+
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+
+ if (start < end)
+ for (theta = start + dt; theta < end; theta += dt)
+ {
+ x = (float)(PenPosition[0] +
+ radius * cos(M_PI * theta / 180.0) * Transform[0][0] +
+ radius * sin(M_PI * theta / 180.0) * Transform[0][1]);
+ y = (float)(PenPosition[1] +
+ radius * cos(M_PI * theta / 180.0) * Transform[1][0] +
+ radius * sin(M_PI * theta / 180.0) * Transform[1][1]);
+
+ Outputf("%.3f %.3f LI\n", x, y);
+ }
+ else
+ for (theta = start - dt; theta > end; theta -= dt)
+ {
+ x = (float)(PenPosition[0] +
+ radius * cos(M_PI * theta / 180.0) * Transform[0][0] +
+ radius * sin(M_PI * theta / 180.0) * Transform[0][1]);
+ y = (float)(PenPosition[1] +
+ radius * cos(M_PI * theta / 180.0) * Transform[1][0] +
+ radius * sin(M_PI * theta / 180.0) * Transform[1][1]);
+
+ Outputf("%.3f %.3f LI\n", x, y);
+ }
+
+ x = (float)(PenPosition[0] +
+ radius * cos(M_PI * end / 180.0) * Transform[0][0] +
+ radius * sin(M_PI * end / 180.0) * Transform[0][1]);
+ y = (float)(PenPosition[1] +
+ radius * cos(M_PI * end / 180.0) * Transform[1][0] +
+ radius * sin(M_PI * end / 180.0) * Transform[1][1]);
+ Outputf("%.3f %.3f LI\n", x, y);
+
+ Outputf("CP\n");
+ if (!PolygonMode)
+ Outputf("FI\n");
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/hpgl-prolog.c b/filter/hpgl-prolog.c
new file mode 100644
index 000000000..b2b3c356f
--- /dev/null
+++ b/filter/hpgl-prolog.c
@@ -0,0 +1,408 @@
+/*
+ * "$Id$"
+ *
+ * HP-GL/2 prolog routines for for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * OutputProlog() - Output the PostScript prolog...
+ * OutputTrailer() - Output the PostScript trailer...
+ * Outputf() - Write a formatted string to the output file, creating the
+ * page header as needed...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "hpgltops.h"
+#include <stdarg.h>
+
+
+/*
+ * 'OutputProlog()' - Output the PostScript prolog...
+ */
+
+void
+OutputProlog(char *title, /* I - Job title */
+ char *user, /* I - Username */
+ int shading) /* I - Type of shading */
+{
+ FILE *prolog; /* Prolog file */
+ char line[255]; /* Line from prolog file */
+ const char *datadir; /* CUPS_DATADIR environment variable */
+ char filename[1024]; /* Name of prolog file */
+ time_t curtime; /* Current time */
+ struct tm *curtm; /* Current date */
+
+
+ curtime = time(NULL);
+ curtm = localtime(&curtime);
+
+ puts("%!PS-Adobe-3.0");
+ printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n",
+ PageLeft, PageBottom, PageRight, PageTop);
+ puts("%%Pages: (atend)");
+ printf("%%%%LanguageLevel: %d\n", LanguageLevel);
+ puts("%%DocumentData: Clean7Bit");
+ puts("%%DocumentSuppliedResources: procset hpgltops 1.1 0");
+ puts("%%DocumentNeededResources: font Courier Helvetica");
+ puts("%%Creator: hpgltops/" CUPS_SVERSION);
+ strftime(line, sizeof(line), CUPS_STRFTIME_FORMAT, curtm);
+ printf("%%%%CreationDate: %s\n", line);
+ printf("%%%%Title: %s\n", title);
+ printf("%%%%For: %s\n", user);
+ printf("%%cupsRotation: %d\n", (Orientation & 3) * 90);
+ puts("%%EndComments");
+ puts("%%BeginProlog");
+ printf("/DefaultPenWidth %.2f def\n", PenWidth * 72.0 / 25.4);
+ puts("3.0 setmiterlimit");
+ if (!shading) /* Black only */
+ puts("/setrgbcolor { pop pop pop } bind def");
+ else if (!ColorDevice) /* Greyscale */
+ puts("/setrgbcolor { 0.08 mul exch 0.61 mul add exch 0.31 mul add setgray } bind def\n");
+
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+ datadir = CUPS_DATADIR;
+
+ snprintf(filename, sizeof(filename), "%s/data/HPGLprolog", datadir);
+
+ if ((prolog = fopen(filename, "r")) == NULL)
+ {
+ fprintf(stderr, "ERROR: Unable to open HPGL prolog \"%s\" for reading - %s\n",
+ filename, strerror(errno));
+ exit(1);
+ }
+
+ while (fgets(line, sizeof(line), prolog) != NULL)
+ fputs(line, stdout);
+
+ fclose(prolog);
+
+ puts("%%EndProlog");
+
+ IN_initialize(0, NULL);
+}
+
+
+/*
+ * 'OutputTrailer()' - Output the PostScript trailer...
+ */
+
+void
+OutputTrailer(void)
+{
+ if (PageDirty)
+ PG_advance_page(0, NULL);
+
+ puts("%%Trailer");
+ printf("%%%%Pages: %d\n", PageCount);
+ puts("%%EOF");
+}
+
+
+/*
+ * 'Outputf()' - Write a formatted string to the output file, creating the
+ * page header as needed...
+ */
+
+int /* O - Number of bytes written */
+Outputf(const char *format, /* I - Printf-style string */
+ ...) /* I - Additional args as needed */
+{
+ va_list ap; /* Argument pointer */
+ int bytes; /* Number of bytes written */
+ float iw1[2], iw2[2]; /* Clipping window */
+ int i; /* Looping var */
+ ppd_size_t *size; /* Page size */
+ ppd_option_t *option; /* Page size option */
+ ppd_choice_t *choice; /* Page size choice */
+ float width, length; /* Page dimensions */
+ int landscape; /* Rotate for landscape orientation? */
+
+
+ /*
+ * Write the page header as needed...
+ */
+
+ if (!PageDirty)
+ {
+ PageDirty = 1;
+ PageCount ++;
+
+ printf("%%%%Page: %d %d\n", PageCount, PageCount);
+
+ landscape = 0;
+
+ if (!FitPlot && PlotSizeSet)
+ {
+ /*
+ * Set the page size for this page...
+ */
+
+ if (PageRotation == 0 || PageRotation == 180)
+ {
+ width = PlotSize[0];
+ length = PlotSize[1];
+ }
+ else
+ {
+ width = PlotSize[1];
+ length = PlotSize[0];
+ }
+
+ fprintf(stderr, "DEBUG: hpgltops setting page size (%.0f x %.0f)\n",
+ width, length);
+
+ if (PPD != NULL)
+ {
+ fputs("DEBUG: hpgltops has a PPD file!\n", stderr);
+
+ /*
+ * Lookup the closest PageSize and set it...
+ */
+
+ for (i = PPD->num_sizes, size = PPD->sizes; i > 0; i --, size ++)
+ if ((fabs(length - size->length) < 36.0 && size->width >= width) ||
+ (fabs(length - size->width) < 36.0 && size->length >= width))
+ break;
+
+ if (i == 0 && PPD->variable_sizes)
+ {
+ for (i = PPD->num_sizes, size = PPD->sizes; i > 0; i --, size ++)
+ if (strcasecmp(size->name, "custom") == 0)
+ break;
+ }
+
+ if (i > 0)
+ {
+ /*
+ * Found a matching size...
+ */
+
+ option = ppdFindOption(PPD, "PageSize");
+ choice = ppdFindChoice(option, size->name);
+
+ puts("%%BeginPageSetup");
+ printf("%%%%BeginFeature: PageSize %s\n", size->name);
+
+ if (strcasecmp(size->name, "custom") == 0)
+ {
+ PageLeft = PPD->custom_margins[0];
+ PageRight = width - PPD->custom_margins[2];
+ PageWidth = width;
+ PageBottom = PPD->custom_margins[1];
+ PageTop = length - PPD->custom_margins[3];
+ PageLength = length;
+
+ printf("%.0f %.0f 0 0 0\n", width, length);
+
+ if (choice->code == NULL)
+ {
+ /*
+ * This can happen with certain buggy PPD files that don't include
+ * a CustomPageSize command sequence... We just use a generic
+ * Level 2 command sequence...
+ */
+
+ puts("pop pop pop");
+ puts("<</PageSize[5 -2 roll]/ImagingBBox null>>setpagedevice\n");
+ }
+ else
+ {
+ /*
+ * Use the vendor-supplied command...
+ */
+
+ printf("%s\n", choice->code);
+ }
+ }
+ else
+ {
+ if (choice->code)
+ printf("%s\n", choice->code);
+
+ if (fabs(length - size->width) < 36.0)
+ {
+ /*
+ * Do landscape orientation...
+ */
+
+ PageLeft = size->bottom;
+ PageRight = size->top;
+ PageWidth = size->length;
+ PageBottom = size->left;
+ PageTop = size->right;
+ PageLength = size->width;
+
+ landscape = 1;
+ }
+ else
+ {
+ /*
+ * Do portrait orientation...
+ */
+
+ PageLeft = size->left;
+ PageRight = size->right;
+ PageWidth = size->width;
+ PageBottom = size->bottom;
+ PageTop = size->top;
+ PageLength = size->length;
+ }
+ }
+
+ puts("%%EndFeature");
+ puts("%%EndPageSetup");
+ }
+ }
+ else
+ {
+ fputs("DEBUG: hpgltops does not have a PPD file!\n", stderr);
+
+ puts("%%BeginPageSetup");
+ printf("%%%%BeginFeature: PageSize w%.0fh%.0f\n", width, length);
+ printf("<</PageSize[%.0f %.0f]/ImageBBox null>>setpagedevice\n",
+ width, length);
+ puts("%%EndFeature");
+ puts("%%EndPageSetup");
+
+ PageLeft = 0.0;
+ PageRight = width;
+ PageWidth = width;
+ PageBottom = 0.0;
+ PageTop = length;
+ PageLength = length;
+ }
+ }
+
+ printf("/SA {\n"
+ " /%s%s%s%s findfont\n"
+ " [ %f %f %f %f 0.0 0.0 ] makefont\n"
+ " setfont\n"
+ "} bind def\n",
+ AlternateFont.typeface == 48 ? "Courier" : "Helvetica",
+ (AlternateFont.weight != 0 || AlternateFont.posture != 0) ? "-" : "",
+ AlternateFont.weight != 0 ? "Bold" : "",
+ AlternateFont.posture != 0 ? "Oblique" : "",
+ AlternateFont.x * AlternateFont.height,
+ -AlternateFont.y * AlternateFont.height,
+ AlternateFont.y * AlternateFont.height,
+ AlternateFont.x * AlternateFont.height);
+
+ printf("/SS {\n"
+ " /%s%s%s%s findfont\n"
+ " [ %f %f %f %f 0.0 0.0 ] makefont\n"
+ " setfont\n"
+ "} bind def\n",
+ StandardFont.typeface == 48 ? "Courier" : "Helvetica",
+ (StandardFont.weight != 0 || StandardFont.posture != 0) ? "-" : "",
+ StandardFont.weight != 0 ? "Bold" : "",
+ StandardFont.posture != 0 ? "Oblique" : "",
+ StandardFont.x * StandardFont.height,
+ -StandardFont.y * StandardFont.height,
+ StandardFont.y * StandardFont.height,
+ StandardFont.x * StandardFont.height);
+
+ if (CharFont)
+ puts("SA");
+ else
+ puts("SS");
+
+ printf("%.1f setmiterlimit\n", MiterLimit);
+ printf("%d setlinecap\n", LineCap);
+ printf("%d setlinejoin\n", LineJoin);
+
+ printf("%.3f %.3f %.3f %.2f SP\n", Pens[1].rgb[0], Pens[1].rgb[1],
+ Pens[1].rgb[2], Pens[1].width * PenScaling);
+
+ puts("gsave");
+
+ if (Duplex && (PageCount & 1) == 0)
+ switch ((PageRotation / 90 + landscape) & 3)
+ {
+ case 0 :
+ printf("%.1f %.1f translate\n", PageWidth - PageRight, PageBottom);
+ break;
+ case 1 :
+ printf("%.0f 0 translate 90 rotate\n", PageLength);
+ printf("%.1f %.1f translate\n", PageLength - PageTop,
+ PageWidth - PageRight);
+ break;
+ case 2 :
+ printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength);
+ printf("%.1f %.1f translate\n", PageLeft, PageLength - PageTop);
+ break;
+ case 3 :
+ printf("0 %.0f translate -90 rotate\n", PageWidth);
+ printf("%.1f %.1f translate\n", PageBottom, PageLeft);
+ break;
+ }
+ else
+ switch ((PageRotation / 90 + landscape) & 3)
+ {
+ case 0 :
+ printf("%.1f %.1f translate\n", PageLeft, PageBottom);
+ break;
+ case 1 :
+ printf("%.0f 0 translate 90 rotate\n", PageLength);
+ printf("%.1f %.1f translate\n", PageBottom, PageWidth - PageRight);
+ break;
+ case 2 :
+ printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength);
+ printf("%.1f %.1f translate\n", PageWidth - PageRight,
+ PageLength - PageTop);
+ break;
+ case 3 :
+ printf("0 %.0f translate -90 rotate\n", PageWidth);
+ printf("%.1f %.1f translate\n", PageLength - PageTop, PageLeft);
+ break;
+ }
+
+ if (IW1[0] != IW2[0] && IW1[1] != IW2[1])
+ {
+ iw1[0] = IW1[0] * 72.0f / 1016.0f;
+ iw1[1] = IW1[1] * 72.0f / 1016.0f;
+ iw2[0] = IW2[0] * 72.0f / 1016.0f;
+ iw2[1] = IW2[1] * 72.0f / 1016.0f;
+
+ printf("initclip MP %.3f %.3f MO %.3f %.3f LI %.3f %.3f LI %.3f %.3f LI CP clip\n",
+ iw1[0], iw1[1], iw1[0], iw2[1], iw2[0], iw2[1], iw2[0], iw1[1]);
+ }
+ }
+
+ /*
+ * Write the string to the output file...
+ */
+
+ va_start(ap, format);
+ bytes = vprintf(format, ap);
+ va_end(ap);
+
+ return (bytes);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/hpgl-vector.c b/filter/hpgl-vector.c
new file mode 100644
index 000000000..011b6de71
--- /dev/null
+++ b/filter/hpgl-vector.c
@@ -0,0 +1,733 @@
+/*
+ * "$Id$"
+ *
+ * HP-GL/2 vector routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * AA_arc_absolute() - Draw an arc.
+ * AR_arc_relative() - Draw an arc relative to the current pen
+ * AT_arc_absolute3() - Draw an arc using 3 points.
+ * CI_circle() - Draw a circle.
+ * PA_plot_absolute() - Plot a line using absolute coordinates.
+ * PD_pen_down() - Start drawing.
+ * PE_polygon_encoded() - Draw an encoded polyline.
+ * PR_plot_relative() - Plot a line using relative coordinates.
+ * PU_pen_up() - Stop drawing.
+ * RT_arc_relative3() - Draw an arc through 3 points relative to the
+ * decode_number() - Decode an encoded number.
+ * plot_points() - Plot the specified points.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "hpgltops.h"
+
+
+/*
+ * Local functions...
+ */
+
+static double decode_number(unsigned char **, int, double);
+static void plot_points(int, param_t *);
+
+
+/*
+ * 'AA_arc_absolute()' - Draw an arc.
+ */
+
+void
+AA_arc_absolute(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ float x, y, /* Transformed coordinates */
+ dx, dy; /* Distance from current pen */
+ float start, end, /* Start and end angles */
+ theta, /* Current angle */
+ dt, /* Step between points */
+ radius; /* Radius of arc */
+
+
+ if (num_params < 3)
+ return;
+
+ x = Transform[0][0] * params[0].value.number +
+ Transform[0][1] * params[1].value.number +
+ Transform[0][2];
+ y = Transform[1][0] * params[0].value.number +
+ Transform[1][1] * params[1].value.number +
+ Transform[1][2];
+
+ dx = PenPosition[0] - x;
+ dy = PenPosition[1] - y;
+
+ start = (float)(180.0 * atan2(dy, dx) / M_PI);
+ if (start < 0.0)
+ start += 360.0f;
+
+ end = start + params[2].value.number;
+ radius = (float)hypot(dx, dy);
+
+ if (PenDown)
+ {
+ if (num_params > 3 && params[3].value.number > 0.0)
+ dt = (float)fabs(params[3].value.number);
+ else
+ dt = 5.0;
+
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+
+ if (start < end)
+ for (theta = start + dt; theta < end; theta += dt)
+ {
+ PenPosition[0] = (float)(x + radius * cos(M_PI * theta / 180.0));
+ PenPosition[1] = (float)(y + radius * sin(M_PI * theta / 180.0));
+
+ Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]);
+ }
+ else
+ for (theta = start - dt; theta > end; theta -= dt)
+ {
+ PenPosition[0] = (float)(x + radius * cos(M_PI * theta / 180.0));
+ PenPosition[1] = (float)(y + radius * sin(M_PI * theta / 180.0));
+
+ Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]);
+ }
+ }
+
+ PenPosition[0] = (float)(x + radius * cos(M_PI * end / 180.0));
+ PenPosition[1] = (float)(y + radius * sin(M_PI * end / 180.0));
+
+ if (PenDown)
+ {
+ Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]);
+
+ if (!PolygonMode)
+ Outputf("ST\n");
+ }
+}
+
+
+/*
+ * 'AR_arc_relative()' - Draw an arc relative to the current pen
+ * position.
+ */
+
+void
+AR_arc_relative(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ float x, y, /* Transformed coordinates */
+ dx, dy; /* Distance from current pen */
+ float start, end, /* Start and end angles */
+ theta, /* Current angle */
+ dt, /* Step between points */
+ radius; /* Radius of arc */
+
+
+ if (num_params < 3)
+ return;
+
+ x = Transform[0][0] * params[0].value.number +
+ Transform[0][1] * params[1].value.number +
+ PenPosition[0];
+ y = Transform[1][0] * params[0].value.number +
+ Transform[1][1] * params[1].value.number +
+ PenPosition[1];
+
+ dx = PenPosition[0] - x;
+ dy = PenPosition[1] - y;
+
+ start = (float)(180.0 * atan2(dy, dx) / M_PI);
+ if (start < 0.0)
+ start += 360.0f;
+
+ end = start + params[2].value.number;
+ radius = (float)hypot(dx, dy);
+
+ if (PenDown)
+ {
+ if (num_params > 3 && params[3].value.number > 0.0)
+ dt = (float)fabs(params[3].value.number);
+ else
+ dt = 5.0;
+
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+
+ if (start < end)
+ for (theta = start + dt; theta < end; theta += dt)
+ {
+ PenPosition[0] = (float)(x + radius * cos(M_PI * theta / 180.0));
+ PenPosition[1] = (float)(y + radius * sin(M_PI * theta / 180.0));
+
+ Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]);
+ }
+ else
+ for (theta = start - dt; theta > end; theta -= dt)
+ {
+ PenPosition[0] = (float)(x + radius * cos(M_PI * theta / 180.0));
+ PenPosition[1] = (float)(y + radius * sin(M_PI * theta / 180.0));
+
+ Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]);
+ }
+ }
+
+ PenPosition[0] = (float)(x + radius * cos(M_PI * end / 180.0));
+ PenPosition[1] = (float)(y + radius * sin(M_PI * end / 180.0));
+
+ if (PenDown)
+ {
+ Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]);
+
+ if (!PolygonMode)
+ Outputf("ST\n");
+ }
+}
+
+
+/*
+ * 'AT_arc_absolute3()' - Draw an arc using 3 points.
+ *
+ * Note:
+ *
+ * Currently this only draws two line segments through the
+ * specified points.
+ */
+
+void
+AT_arc_absolute3(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params < 4)
+ return;
+
+ if (PenDown)
+ {
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+
+ PenPosition[0] = Transform[0][0] * params[0].value.number +
+ Transform[0][1] * params[1].value.number +
+ Transform[0][2];
+ PenPosition[1] = Transform[1][0] * params[0].value.number +
+ Transform[1][1] * params[1].value.number +
+ Transform[1][2];
+
+ Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]);
+ }
+
+ PenPosition[0] = Transform[0][0] * params[2].value.number +
+ Transform[0][1] * params[3].value.number +
+ Transform[0][2];
+ PenPosition[1] = Transform[1][0] * params[2].value.number +
+ Transform[1][1] * params[3].value.number +
+ Transform[1][2];
+
+ if (PenDown)
+ {
+ Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]);
+
+ if (!PolygonMode)
+ Outputf("ST\n");
+ }
+}
+
+
+/*
+ * 'CI_circle()' - Draw a circle.
+ */
+
+void
+CI_circle(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ float x, y; /* Transformed coordinates */
+ float theta, /* Current angle */
+ dt, /* Step between points */
+ radius; /* Radius of circle */
+
+
+ if (num_params < 1)
+ return;
+
+ if (!PenDown)
+ return;
+
+ radius = params[0].value.number;
+
+ if (num_params > 1)
+ dt = (float)fabs(params[1].value.number);
+ else
+ dt = 5.0;
+
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ for (theta = 0.0; theta < 360.0; theta += dt)
+ {
+ x = (float)(PenPosition[0] +
+ radius * cos(M_PI * theta / 180.0) * Transform[0][0] +
+ radius * sin(M_PI * theta / 180.0) * Transform[0][1]);
+ y = (float)(PenPosition[1] +
+ radius * cos(M_PI * theta / 180.0) * Transform[1][0] +
+ radius * sin(M_PI * theta / 180.0) * Transform[1][1]);
+
+ Outputf("%.3f %.3f %s\n", x, y, theta == 0.0 ? "MO" : "LI");
+ }
+
+ Outputf("CP\n");
+ if (!PolygonMode)
+ Outputf("ST\n");
+}
+
+
+/*
+ * 'PA_plot_absolute()' - Plot a line using absolute coordinates.
+ */
+
+void
+PA_plot_absolute(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ PenMotion = 0;
+
+ if (num_params > 1)
+ plot_points(num_params, params);
+}
+
+
+/*
+ * 'PD_pen_down()' - Start drawing.
+ */
+
+void
+PD_pen_down(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ PenDown = 1;
+
+ if (num_params > 1)
+ plot_points(num_params, params);
+}
+
+
+/*
+ * 'PE_polygon_encoded()' - Draw an encoded polyline.
+ */
+
+void
+PE_polyline_encoded(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ unsigned char *s; /* Pointer into string */
+ int temp, /* Temporary value */
+ base_bits, /* Data bits per byte */
+ draw, /* Draw or move */
+ abscoords; /* Use absolute coordinates */
+ double tx, ty, /* Transformed coordinates */
+ x, y, /* Raw coordinates */
+ frac_bits; /* Multiplier for encoded number */
+
+
+ base_bits = 6;
+ frac_bits = 1.0;
+ draw = 1;
+ abscoords = 0;
+
+ if (num_params == 0)
+ return;
+
+ if (!PolygonMode)
+ {
+ Outputf("MP\n");
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+ }
+
+ for (s = (unsigned char *)params[0].value.string; *s != '\0';)
+ switch (*s)
+ {
+ case '7' :
+ s ++;
+ base_bits = 5;
+
+#ifdef DEBUG
+ fputs("DEBUG: 7-bit\n", stderr);
+#endif /* DEBUG */
+ break;
+ case ':' : /* Select pen */
+ s ++;
+ PenNumber = (int)decode_number(&s, base_bits, 1.0);
+ if (PageDirty)
+ printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0],
+ Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2],
+ Pens[PenNumber].width * PenScaling);
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: set pen #%d\n", PenNumber);
+#endif /* DEBUG */
+ break;
+ case '<' : /* Next coords are a move-to */
+ draw = 0;
+ s ++;
+
+#ifdef DEBUG
+ fputs("DEBUG: moveto\n", stderr);
+#endif /* DEBUG */
+ break;
+ case '>' : /* Set fractional bits */
+ s ++;
+ temp = (int)decode_number(&s, base_bits, 1.0);
+ frac_bits = 1.0 / (1 << temp);
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: set fractional bits %d\n", temp);
+#endif /* DEBUG */
+ break;
+ case '=' : /* Next coords are absolute */
+ s ++;
+ abscoords = 1;
+
+#ifdef DEBUG
+ fputs("DEBUG: absolute\n", stderr);
+#endif /* DEBUG */
+ break;
+ default :
+ if (*s >= 63)
+ {
+ /*
+ * Coordinate...
+ */
+
+ x = decode_number(&s, base_bits, frac_bits);
+ y = decode_number(&s, base_bits, frac_bits);
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: coords %.3f %.3f\n", x, y);
+#endif /* DEBUG */
+
+ if (abscoords)
+ {
+ tx = Transform[0][0] * x + Transform[0][1] * y +
+ Transform[0][2];
+ ty = Transform[1][0] * x + Transform[1][1] * y +
+ Transform[1][2];
+ }
+ else if (x == 0.0 && y == 0.0)
+ {
+ draw = 1;
+ continue;
+ }
+ else
+ {
+ tx = Transform[0][0] * x + Transform[0][1] * y +
+ PenPosition[0];
+ ty = Transform[1][0] * x + Transform[1][1] * y +
+ PenPosition[1];
+ }
+
+ if (draw)
+ Outputf("%.3f %.3f LI\n", tx, ty);
+ else
+ Outputf("%.3f %.3f MO\n", tx, ty);
+
+ PenPosition[0] = (float)tx;
+ PenPosition[1] = (float)ty;
+
+ draw = 1;
+ abscoords = 0;
+ }
+ else
+ {
+ /*
+ * Junk - ignore...
+ */
+
+ if (*s != '\n' && *s != '\r')
+ fprintf(stderr, "WARNING: ignoring illegal PE char \'%c\'...\n", *s);
+ s ++;
+ }
+ break;
+ }
+
+ if (!PolygonMode)
+ Outputf("ST\n");
+}
+
+
+/*
+ * 'PR_plot_relative()' - Plot a line using relative coordinates.
+ */
+
+void
+PR_plot_relative(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ PenMotion = 1;
+
+ if (num_params > 1)
+ plot_points(num_params, params);
+}
+
+
+/*
+ * 'PU_pen_up()' - Stop drawing.
+ */
+
+void
+PU_pen_up(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ PenDown = 0;
+
+ if (num_params > 1)
+ plot_points(num_params, params);
+}
+
+
+/*
+ * 'RT_arc_relative3()' - Draw an arc through 3 points relative to the
+ * current pen position.
+ *
+ * Note:
+ *
+ * This currently only draws two line segments through the specified
+ * points.
+ */
+
+void
+RT_arc_relative3(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ if (num_params < 4)
+ return;
+
+ if (PenDown)
+ {
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+
+ PenPosition[0] = Transform[0][0] * params[0].value.number +
+ Transform[0][1] * params[1].value.number +
+ PenPosition[0];
+ PenPosition[1] = Transform[1][0] * params[0].value.number +
+ Transform[1][1] * params[1].value.number +
+ PenPosition[1];
+
+ Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]);
+ }
+
+ PenPosition[0] = Transform[0][0] * params[2].value.number +
+ Transform[0][1] * params[3].value.number +
+ PenPosition[0];
+ PenPosition[1] = Transform[1][0] * params[2].value.number +
+ Transform[1][1] * params[3].value.number +
+ PenPosition[1];
+
+ if (PenDown)
+ {
+ Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]);
+
+ if (!PolygonMode)
+ Outputf("ST\n");
+ }
+}
+
+
+/*
+ * 'decode_number()' - Decode an encoded number.
+ */
+
+static double /* O - Value */
+decode_number(unsigned char **s, /* IO - String to decode */
+ int base_bits, /* I - Number of data bits per byte */
+ double frac_bits) /* I - Multiplier for fractional data */
+{
+ double temp, /* Current value */
+ shift; /* Multiplier */
+ int sign; /* Sign of result */
+
+
+ sign = 0;
+
+ if (base_bits == 5)
+ {
+ for (temp = 0.0, shift = frac_bits * 0.5; **s != '\0'; (*s) ++)
+ if (**s >= 95 && **s < 127)
+ {
+ if (sign == 0)
+ {
+ if ((**s - 95) & 1)
+ sign = -1;
+ else
+ sign = 1;
+
+ temp += ((**s - 95) & ~1) * shift;
+ }
+ else
+ temp += (**s - 95) * shift;
+ break;
+ }
+ else if (**s < 63)
+ {
+ if (**s != '\r' && **s != '\n')
+ fprintf(stderr, "hpgl2ps: Bad PE character \'%c\'!\n", **s);
+
+ continue;
+ }
+ else
+ {
+ if (sign == 0)
+ {
+ if ((**s - 63) & 1)
+ sign = -1;
+ else
+ sign = 1;
+
+ temp += ((**s - 63) & ~1) * shift;
+ }
+ else
+ temp += (**s - 63) * shift;
+
+ shift *= 32.0;
+ }
+ }
+ else
+ {
+ for (temp = 0.0, shift = frac_bits * 0.5; **s != '\0'; (*s) ++)
+ if (**s >= 191 && **s < 255)
+ {
+ if (sign == 0)
+ {
+ if ((**s - 191) & 1)
+ sign = -1;
+ else
+ sign = 1;
+
+ temp += ((**s - 191) & ~1) * shift;
+ }
+ else
+ temp += (**s - 191) * shift;
+ break;
+ }
+ else if (**s < 63)
+ {
+ if (**s != '\r' && **s != '\n')
+ fprintf(stderr, "hpgl2ps: Bad PE character \'%c\'!\n", **s);
+
+ continue;
+ }
+ else
+ {
+ if (sign == 0)
+ {
+ if ((**s - 63) & 1)
+ sign = -1;
+ else
+ sign = 1;
+
+ temp += ((**s - 63) & ~1) * shift;
+ }
+ else
+ temp += (**s - 63) * shift;
+
+ shift *= 64.0;
+ }
+ }
+
+ (*s) ++;
+
+ return (temp * sign);
+}
+
+
+/*
+ * 'plot_points()' - Plot the specified points.
+ */
+
+static void
+plot_points(int num_params, /* I - Number of parameters */
+ param_t *params) /* I - Parameters */
+{
+ int i; /* Looping var */
+ float x, y; /* Transformed coordinates */
+
+
+ if (PenDown)
+ {
+ if (!PolygonMode)
+ Outputf("MP\n");
+
+ Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]);
+ }
+
+ for (i = 0; i < num_params; i += 2)
+ {
+ if (PenMotion == 0)
+ {
+ x = Transform[0][0] * params[i + 0].value.number +
+ Transform[0][1] * params[i + 1].value.number +
+ Transform[0][2];
+ y = Transform[1][0] * params[i + 0].value.number +
+ Transform[1][1] * params[i + 1].value.number +
+ Transform[1][2];
+ }
+ else
+ {
+ x = Transform[0][0] * params[i + 0].value.number +
+ Transform[0][1] * params[i + 1].value.number +
+ PenPosition[0];
+ y = Transform[1][0] * params[i + 0].value.number +
+ Transform[1][1] * params[i + 1].value.number +
+ PenPosition[1];
+ }
+
+ if (PenDown)
+ Outputf("%.3f %.3f LI\n", x, y);
+
+ PenPosition[0] = x;
+ PenPosition[1] = y;
+ }
+
+ if (PenDown)
+ {
+ if (!PolygonMode)
+ Outputf("ST\n");
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/hpgltops.dsp b/filter/hpgltops.dsp
new file mode 100644
index 000000000..3f678523d
--- /dev/null
+++ b/filter/hpgltops.dsp
@@ -0,0 +1,130 @@
+# Microsoft Developer Studio Project File - Name="hpgltops" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=hpgltops - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "hpgltops.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "hpgltops.mak" CFG="hpgltops - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "hpgltops - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "hpgltops - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "hpgltops - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ../cups/cups.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"hpgltops.exe"
+
+!ELSEIF "$(CFG)" == "hpgltops - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "hpgltops___Win32_Debug"
+# PROP BASE Intermediate_Dir "hpgltops___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ../cups/cupsd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"hpgltopsd.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "hpgltops - Win32 Release"
+# Name "hpgltops - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=".\hpgl-attr.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\hpgl-char.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\hpgl-config.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\hpgl-input.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\hpgl-main.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\hpgl-polygon.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\hpgl-prolog.c"
+# End Source File
+# Begin Source File
+
+SOURCE=".\hpgl-vector.c"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\hpgltops.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/filter/hpgltops.h b/filter/hpgltops.h
new file mode 100644
index 000000000..534c39565
--- /dev/null
+++ b/filter/hpgltops.h
@@ -0,0 +1,235 @@
+/*
+ * "$Id$"
+ *
+ * HP-GL/2 to PostScript filter for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "common.h"
+#include <math.h>
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif /* M_PI */
+
+/*
+ * Parameter value structure...
+ */
+
+typedef struct
+{
+ int type;
+ union
+ {
+ float number;
+ char *string;
+ } value;
+} param_t;
+
+#define PARAM_ABSOLUTE 0
+#define PARAM_RELATIVE 1
+#define PARAM_STRING 2
+
+
+/*
+ * Font information...
+ */
+
+typedef struct
+{
+ int typeface, /* Typeface number */
+ posture, /* Posture number */
+ weight; /* Weight number */
+ float height; /* Height/size of font */
+ float x, y; /* X and Y direction/scaling */
+} font_t;
+
+
+/*
+ * Pen information...
+ */
+
+typedef struct
+{
+ float rgb[3]; /* Pen color */
+ float width; /* Pen width */
+} pen_t;
+
+
+/*
+ * Globals...
+ */
+
+#ifdef _HPGL_MAIN_C_
+# define VAR
+# define VALUE(x) =x
+# define VALUE2(x,y) ={x,y}
+#else
+# define VAR extern
+# define VALUE(x)
+# define VALUE2(x,y)
+#endif /* _HPGL_MAIN_C_ */
+
+VAR ppd_file_t *PPD VALUE(NULL); /* PPD file */
+
+VAR float P1[2], /* Lower-lefthand physical limit */
+ P2[2], /* Upper-righthand physical limit */
+ IW1[2], /* Window lower-lefthand limit */
+ IW2[2]; /* Window upper-righthand limit */
+VAR int Rotation VALUE(0); /* Page rotation */
+VAR int ScalingType VALUE(-1); /* Type of scaling (-1 for none) */
+VAR float Scaling1[2], /* Lower-lefthand user limit */
+ Scaling2[2]; /* Upper-righthand user limit */
+VAR float Transform[2][3]; /* Transform matrix */
+VAR int PageRotation VALUE(0); /* Page/plot rotation */
+
+VAR char StringTerminator VALUE('\003'); /* Terminator for labels */
+VAR font_t StandardFont, /* Standard font */
+ AlternateFont; /* Alternate font */
+VAR float PenPosition[2] VALUE2(0.0f, 0.0f),
+ /* Current pen position */
+ PenScaling VALUE(1.0f), /* Pen width scaling factor */
+ PenWidth VALUE(1.0f); /* Default pen width */
+VAR pen_t Pens[1024]; /* State of each pen */
+VAR int PenMotion VALUE(0), /* 0 = absolute, 1 = relative */
+ PenNumber VALUE(1), /* Current pen number */
+ PenCount VALUE(8), /* Number of pens */
+ PenDown VALUE(0), /* 0 = pen up, 1 = pen down */
+ PolygonMode VALUE(0), /* Drawing polygons? */
+ PageCount VALUE(0), /* Number of pages in plot */
+ PageDirty VALUE(0), /* Current page written on? */
+ WidthUnits VALUE(0); /* 0 = mm, 1 = proportionate */
+VAR float PlotSize[2] VALUE2(2592.0f, 3456.0f);
+ /* Plot size */
+VAR int PlotSizeSet VALUE(0); /* Plot size set? */
+VAR int CharFillMode VALUE(0), /* Where to draw labels */
+ CharPen VALUE(0), /* Pen to use for labels */
+ CharFont VALUE(0); /* Font to use for labels */
+VAR float CharHeight[2] VALUE2(11.5f,11.5f);
+ /* Size of font for labels */
+VAR int FitPlot VALUE(0); /* 1 = fit to page */
+VAR float ColorRange[3][2] /* Range of color values */
+#ifdef _HPGL_MAIN_C_
+ = {
+ { 0.0, 255.0 },
+ { 0.0, 255.0 },
+ { 0.0, 255.0 }
+ }
+#endif /* _HPGL_MAIN_C_ */
+;
+
+VAR int LineCap VALUE(0); /* Line capping */
+VAR int LineJoin VALUE(0); /* Line joining */
+VAR float MiterLimit VALUE(3.0f); /* Miter limit at joints */
+
+
+/*
+ * Prototypes...
+ */
+
+/* hpgl-input.c */
+extern int ParseCommand(FILE *fp, char *name, param_t **params);
+extern void FreeParameters(int num_params, param_t *params);
+
+/* hpgl-config.c */
+extern void update_transform(void);
+extern void BP_begin_plot(int num_params, param_t *params);
+extern void DF_default_values(int num_params, param_t *params);
+extern void IN_initialize(int num_params, param_t *params);
+extern void IP_input_absolute(int num_params, param_t *params);
+extern void IR_input_relative(int num_params, param_t *params);
+extern void IW_input_window(int num_params, param_t *params);
+extern void PG_advance_page(int num_params, param_t *params);
+extern void PS_plot_size(int num_params, param_t *params);
+extern void RO_rotate(int num_params, param_t *params);
+extern void RP_replot(int num_params, param_t *params);
+extern void SC_scale(int num_params, param_t *params);
+
+/* hpgl-vector.c */
+extern void AA_arc_absolute(int num_params, param_t *params);
+extern void AR_arc_relative(int num_params, param_t *params);
+extern void AT_arc_absolute3(int num_params, param_t *params);
+extern void CI_circle(int num_params, param_t *params);
+extern void PA_plot_absolute(int num_params, param_t *params);
+extern void PD_pen_down(int num_params, param_t *params);
+extern void PE_polyline_encoded(int num_params, param_t *params);
+extern void PR_plot_relative(int num_params, param_t *params);
+extern void PU_pen_up(int num_params, param_t *params);
+extern void RT_arc_relative3(int num_params, param_t *params);
+
+/* hpgl-polygon.c */
+extern void EA_edge_rect_absolute(int num_params, param_t *params);
+extern void EP_edge_polygon(int num_params, param_t *params);
+extern void ER_edge_rect_relative(int num_params, param_t *params);
+extern void EW_edge_wedge(int num_params, param_t *params);
+extern void FP_fill_polygon(int num_params, param_t *params);
+extern void PM_polygon_mode(int num_params, param_t *params);
+extern void RA_fill_rect_absolute(int num_params, param_t *params);
+extern void RR_fill_rect_relative(int num_params, param_t *params);
+extern void WG_fill_wedge(int num_params, param_t *params);
+
+/* hpgl-char.c */
+extern void AD_define_alternate(int num_params, param_t *params);
+extern void CF_character_fill(int num_params, param_t *params);
+extern void CP_character_plot(int num_params, param_t *params);
+extern void DI_absolute_direction(int num_params, param_t *params);
+extern void DR_relative_direction(int num_params, param_t *params);
+extern void DT_define_label_term(int num_params, param_t *params);
+extern void DV_define_variable_path(int num_params, param_t *params);
+extern void ES_extra_space(int num_params, param_t *params);
+extern void LB_label(int num_params, param_t *params);
+extern void LO_label_origin(int num_params, param_t *params);
+extern void SA_select_alternate(int num_params, param_t *params);
+extern void SD_define_standard(int num_params, param_t *params);
+extern void SI_absolute_size(int num_params, param_t *params);
+extern void SL_character_slant(int num_params, param_t *params);
+extern void SR_relative_size(int num_params, param_t *params);
+extern void SS_select_standard(int num_params, param_t *params);
+extern void TD_transparent_data(int num_params, param_t *params);
+
+/* hpgl-attr.c */
+extern void AC_anchor_corner(int num_params, param_t *params);
+extern void CR_color_range(int num_params, param_t *params);
+extern void FT_fill_type(int num_params, param_t *params);
+extern void LA_line_attributes(int num_params, param_t *params);
+extern void LT_line_type(int num_params, param_t *params);
+extern void NP_number_pens(int num_params, param_t *params);
+extern void PC_pen_color(int num_params, param_t *params);
+extern void PW_pen_width(int num_params, param_t *params);
+extern void RF_raster_fill(int num_params, param_t *params);
+extern void SM_symbol_mode(int num_params, param_t *params);
+extern void SP_select_pen(int num_params, param_t *params);
+extern void UL_user_line_type(int num_params, param_t *params);
+extern void WU_width_units(int num_params, param_t *params);
+
+/* hpgl-prolog.c */
+extern void OutputProlog(char *title, char *user, int shading);
+extern void OutputTrailer(void);
+extern int Outputf(const char *format, ...);
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-bmp.c b/filter/image-bmp.c
new file mode 100644
index 000000000..41c0a08e0
--- /dev/null
+++ b/filter/image-bmp.c
@@ -0,0 +1,512 @@
+/*
+ * "$Id$"
+ *
+ * BMP image routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageReadBMP() - Read a BMP image file.
+ * read_word() - Read a 16-bit unsigned integer.
+ * read_dword() - Read a 32-bit unsigned integer.
+ * read_long() - Read a 32-bit signed integer.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+
+
+/*
+ * Constants for the bitmap compression...
+ */
+
+# define BI_RGB 0 /* No compression - straight BGR data */
+# define BI_RLE8 1 /* 8-bit run-length compression */
+# define BI_RLE4 2 /* 4-bit run-length compression */
+# define BI_BITFIELDS 3 /* RGB bitmap with RGB masks */
+
+
+/*
+ * Local functions...
+ */
+
+static unsigned short read_word(FILE *fp);
+static unsigned int read_dword(FILE *fp);
+static int read_long(FILE *fp);
+
+
+/*
+ * 'ImageReadBMP()' - Read a BMP image file.
+ */
+
+int /* O - Read status */
+ImageReadBMP(image_t *img, /* IO - Image */
+ FILE *fp, /* I - Image file */
+ int primary, /* I - Primary choice for colorspace */
+ int secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int offset, /* Offset to bitmap data */
+ info_size, /* Size of info header */
+ planes, /* Number of planes (always 1) */
+ depth, /* Depth of image (bits) */
+ compression, /* Type of compression */
+ image_size, /* Size of image in bytes */
+ colors_used, /* Number of colors used */
+ colors_important, /* Number of important colors */
+ bpp, /* Bytes per pixel */
+ x, y, /* Looping vars */
+ color, /* Color of RLE pixel */
+ count, /* Number of times to repeat */
+ temp, /* Temporary color */
+ align; /* Alignment bytes */
+ ib_t bit, /* Bit in image */
+ byte; /* Byte in image */
+ ib_t *in, /* Input pixels */
+ *out, /* Output pixels */
+ *ptr; /* Pointer into pixels */
+ ib_t colormap[256][4]; /* Colormap */
+
+
+ (void)secondary;
+
+ /*
+ * Get the header...
+ */
+
+ getc(fp); /* Skip "BM" sync chars */
+ getc(fp);
+ read_dword(fp); /* Skip size */
+ read_word(fp); /* Skip reserved stuff */
+ read_word(fp);
+ offset = read_dword(fp);
+
+ fprintf(stderr, "offset = %d\n", offset);
+
+ /*
+ * Then the bitmap information...
+ */
+
+ info_size = read_dword(fp);
+ img->xsize = read_long(fp);
+ img->ysize = read_long(fp);
+ planes = read_word(fp);
+ depth = read_word(fp);
+ compression = read_dword(fp);
+ image_size = read_dword(fp);
+ img->xppi = read_long(fp) * 0.0254 + 0.5;
+ img->yppi = read_long(fp) * 0.0254 + 0.5;
+ colors_used = read_dword(fp);
+ colors_important = read_dword(fp);
+
+ /*
+ * Make sure the resolution info is valid...
+ */
+
+ if (img->xppi == 0)
+ img->xppi = 128;
+ if (img->yppi == 0)
+ img->yppi = 128;
+
+ fprintf(stderr, "info_size = %d, xsize = %d, ysize = %d, planes = %d, depth = %d\n",
+ info_size, img->xsize, img->ysize, planes, depth);
+ fprintf(stderr, "compression = %d, image_size = %d, xppi = %d, yppi = %d\n",
+ compression, image_size, img->xppi, img->yppi);
+ fprintf(stderr, "colors_used = %d, colors_important = %d\n", colors_used,
+ colors_important);
+
+ if (info_size > 40)
+ for (info_size -= 40; info_size > 0; info_size --)
+ getc(fp);
+
+ /*
+ * Get colormap...
+ */
+
+ if (colors_used == 0 && depth <= 8)
+ colors_used = 1 << depth;
+
+ fread(colormap, colors_used, 4, fp);
+
+ /*
+ * Setup image and buffers...
+ */
+
+ img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_RGB : primary;
+
+ ImageSetMaxTiles(img, 0);
+
+ in = malloc(img->xsize * 3);
+ bpp = ImageGetDepth(img);
+ out = malloc(img->xsize * bpp);
+
+ /*
+ * Read the image data...
+ */
+
+ color = 0;
+ count = 0;
+ align = 0;
+
+ for (y = img->ysize - 1; y >= 0; y --)
+ {
+ if (img->colorspace == IMAGE_RGB)
+ ptr = out;
+ else
+ ptr = in;
+
+ switch (depth)
+ {
+ case 1 : /* Bitmap */
+ for (x = img->xsize, bit = 128, byte = 0; x > 0; x --)
+ {
+ if (bit == 128)
+ byte = getc(fp);
+
+ if (byte & bit)
+ {
+ *ptr++ = colormap[1][2];
+ *ptr++ = colormap[1][1];
+ *ptr++ = colormap[1][0];
+ }
+ else
+ {
+ *ptr++ = colormap[0][2];
+ *ptr++ = colormap[0][1];
+ *ptr++ = colormap[0][0];
+ }
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ bit = 128;
+ }
+
+ /*
+ * Read remaining bytes to align to 32 bits...
+ */
+
+ for (temp = (img->xsize + 7) / 8; temp & 3; temp ++)
+ getc(fp);
+ break;
+
+ case 4 : /* 16-color */
+ for (x = img->xsize, bit = 0xf0, temp = 0; x > 0; x --)
+ {
+ /*
+ * Get a new count as needed...
+ */
+
+ if (compression != BI_RLE4 && count == 0)
+ {
+ count = 2;
+ color = -1;
+ }
+
+ if (count == 0)
+ {
+ while (align > 0)
+ {
+ align --;
+ getc(fp);
+ }
+
+ if ((count = getc(fp)) == 0)
+ {
+ if ((count = getc(fp)) == 0)
+ {
+ /*
+ * End of line...
+ */
+
+ x ++;
+ continue;
+ }
+ else if (count == 1)
+ {
+ /*
+ * End of image...
+ */
+
+ break;
+ }
+ else if (count == 2)
+ {
+ /*
+ * Delta...
+ */
+
+ count = getc(fp) * getc(fp) * img->xsize;
+ color = 0;
+ }
+ else
+ {
+ /*
+ * Absolute...
+ */
+
+ color = -1;
+ align = ((4 - (count & 3)) / 2) & 1;
+ }
+ }
+ else
+ color = getc(fp);
+ }
+
+ /*
+ * Get a new color as needed...
+ */
+
+ count --;
+
+ if (bit == 0xf0)
+ {
+ if (color < 0)
+ temp = getc(fp);
+ else
+ temp = color;
+
+ /*
+ * Copy the color value...
+ */
+
+ *ptr++ = colormap[temp >> 4][2];
+ *ptr++ = colormap[temp >> 4][1];
+ *ptr++ = colormap[temp >> 4][0];
+ bit = 0x0f;
+ }
+ else
+ {
+ /*
+ * Copy the color value...
+ */
+
+ *ptr++ = colormap[temp & 15][2];
+ *ptr++ = colormap[temp & 15][1];
+ *ptr++ = colormap[temp & 15][0];
+ bit = 0xf0;
+ }
+ }
+ break;
+
+ case 8 : /* 256-color */
+ for (x = img->xsize; x > 0; x --)
+ {
+ /*
+ * Get a new count as needed...
+ */
+
+ if (compression != BI_RLE8)
+ {
+ count = 1;
+ color = -1;
+ }
+
+ if (count == 0)
+ {
+ while (align > 0)
+ {
+ align --;
+ getc(fp);
+ }
+
+ if ((count = getc(fp)) == 0)
+ {
+ if ((count = getc(fp)) == 0)
+ {
+ /*
+ * End of line...
+ */
+
+ x ++;
+ continue;
+ }
+ else if (count == 1)
+ {
+ /*
+ * End of image...
+ */
+
+ break;
+ }
+ else if (count == 2)
+ {
+ /*
+ * Delta...
+ */
+
+ count = getc(fp) * getc(fp) * img->xsize;
+ color = 0;
+ }
+ else
+ {
+ /*
+ * Absolute...
+ */
+
+ color = -1;
+ align = (2 - (count & 1)) & 1;
+ }
+ }
+ else
+ color = getc(fp);
+ }
+
+ /*
+ * Get a new color as needed...
+ */
+
+ if (color < 0)
+ temp = getc(fp);
+ else
+ temp = color;
+
+ count --;
+
+ /*
+ * Copy the color value...
+ */
+
+ *ptr++ = colormap[temp][2];
+ *ptr++ = colormap[temp][1];
+ *ptr++ = colormap[temp][0];
+ }
+ break;
+
+ case 24 : /* 24-bit RGB */
+ for (x = img->xsize; x > 0; x --, ptr += 3)
+ {
+ ptr[2] = getc(fp);
+ ptr[1] = getc(fp);
+ ptr[0] = getc(fp);
+ }
+
+ /*
+ * Read remaining bytes to align to 32 bits...
+ */
+
+ for (temp = img->xsize * 3; temp & 3; temp ++)
+ getc(fp);
+ break;
+ }
+
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (saturation != 100 || hue != 0)
+ ImageRGBAdjust(out, img->xsize, saturation, hue);
+ }
+ else
+ {
+ if (saturation != 100 || hue != 0)
+ ImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+
+ fclose(fp);
+ free(in);
+ free(out);
+
+ return (0);
+}
+
+
+/*
+ * 'read_word()' - Read a 16-bit unsigned integer.
+ */
+
+static unsigned short /* O - 16-bit unsigned integer */
+read_word(FILE *fp) /* I - File to read from */
+{
+ unsigned char b0, b1; /* Bytes from file */
+
+ b0 = getc(fp);
+ b1 = getc(fp);
+
+ return ((b1 << 8) | b0);
+}
+
+
+/*
+ * 'read_dword()' - Read a 32-bit unsigned integer.
+ */
+
+static unsigned int /* O - 32-bit unsigned integer */
+read_dword(FILE *fp) /* I - File to read from */
+{
+ unsigned char b0, b1, b2, b3; /* Bytes from file */
+
+ b0 = getc(fp);
+ b1 = getc(fp);
+ b2 = getc(fp);
+ b3 = getc(fp);
+
+ return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
+}
+
+
+/*
+ * 'read_long()' - Read a 32-bit signed integer.
+ */
+
+static int /* O - 32-bit signed integer */
+read_long(FILE *fp) /* I - File to read from */
+{
+ unsigned char b0, b1, b2, b3; /* Bytes from file */
+
+ b0 = getc(fp);
+ b1 = getc(fp);
+ b2 = getc(fp);
+ b3 = getc(fp);
+
+ return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-colorspace.c b/filter/image-colorspace.c
new file mode 100644
index 000000000..af5fd048e
--- /dev/null
+++ b/filter/image-colorspace.c
@@ -0,0 +1,1485 @@
+/*
+ * "$Id$"
+ *
+ * Colorspace conversions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageSetProfile() - Set the device color profile.
+ * ImageWhiteToWhite() - Convert luminance colors to device-dependent
+ * ImageWhiteToRGB() - Convert luminance data to RGB.
+ * ImageWhiteToBlack() - Convert luminance colors to black.
+ * ImageWhiteToCMY() - Convert luminance colors to CMY.
+ * ImageWhiteToCMYK() - Convert luminance colors to CMYK.
+ * ImageRGBToBlack() - Convert RGB data to black.
+ * ImageRGBToCMY() - Convert RGB colors to CMY.
+ * ImageRGBToCMYK() - Convert RGB colors to CMYK.
+ * ImageRGBToWhite() - Convert RGB colors to luminance.
+ * ImageRGBToRGB() - Convert RGB colors to device-dependent RGB.
+ * ImageCMYKToBlack() - Convert CMYK data to black.
+ * ImageCMYKToCMY() - Convert CMYK colors to CMY.
+ * ImageCMYKToCMYK() - Convert CMYK colors to CMYK.
+ * ImageCMYKToWhite() - Convert CMYK colors to luminance.
+ * ImageCMYKToRGB() - Convert CMYK colors to device-dependent RGB.
+ * ImageLut() - Adjust all pixel values with the given LUT.
+ * ImageRGBAdjust() - Adjust the hue and saturation of the given RGB
+ * colors.
+ * huerotate() - Rotate the hue, maintaining luminance.
+ * ident() - Make an identity matrix.
+ * mult() - Multiply two matrices.
+ * saturate() - Make a saturation matrix.
+ * xform() - Transform a 3D point using a matrix...
+ * xrotate() - Rotate about the x (red) axis...
+ * yrotate() - Rotate about the y (green) axis...
+ * zrotate() - Rotate about the z (blue) axis...
+ * zshear() - Shear z using x and y...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+#include <math.h>
+
+
+/*
+ * Define some math constants that are required...
+ */
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif /* !M_PI */
+
+#ifndef M_SQRT2
+# define M_SQRT2 1.41421356237309504880
+#endif /* !M_SQRT2 */
+
+#ifndef M_SQRT1_2
+# define M_SQRT1_2 0.70710678118654752440
+#endif /* !M_SQRT1_2 */
+
+
+/*
+ * Local globals...
+ */
+
+static int ImageHaveProfile = 0;
+ /* Do we have a color profile? */
+static int ImageDensity[256];
+ /* Ink/marker density LUT */
+static int ImageMatrix[3][3][256];
+ /* Color transform matrix LUT */
+static cups_cspace_t ImageColorSpace = CUPS_CSPACE_RGB;
+ /* Destination colorspace */
+
+
+/*
+ * Local functions...
+ */
+
+static float cielab(float x, float xn);
+static void rgb_to_xyz(ib_t *val);
+static void rgb_to_lab(ib_t *val);
+
+static void huerotate(float [3][3], float);
+static void ident(float [3][3]);
+static void mult(float [3][3], float [3][3], float [3][3]);
+static void saturate(float [3][3], float);
+static void xform(float [3][3], float, float, float, float *, float *, float *);
+static void xrotate(float [3][3], float, float);
+static void yrotate(float [3][3], float, float);
+static void zrotate(float [3][3], float, float);
+static void zshear(float [3][3], float, float);
+
+
+/*
+ * 'ImageSetColorSpace()' - Set the destination colorspace.
+ */
+
+void
+ImageSetColorSpace(cups_cspace_t cs) /* I - Destination colorspace */
+{
+ /*
+ * Set the destination colorspace...
+ */
+
+ ImageColorSpace = cs;
+
+ /*
+ * Don't use color profiles in colorimetric colorspaces...
+ */
+
+ if (cs >= CUPS_CSPACE_CIEXYZ)
+ ImageHaveProfile = 0;
+}
+
+
+/*
+ * 'ImageSetProfile()' - Set the device color profile.
+ */
+
+void
+ImageSetProfile(float d, /* I - Ink/marker density */
+ float g, /* I - Ink/marker gamma */
+ float matrix[3][3]) /* I - Color transform matrix */
+{
+ int i, j, k; /* Looping vars */
+ float m; /* Current matrix value */
+ int *im; /* Pointer into ImageMatrix */
+
+ ImageHaveProfile = 1;
+
+ for (i = 0, im = ImageMatrix[0][0]; i < 3; i ++)
+ for (j = 0; j < 3; j ++)
+ for (k = 0, m = matrix[i][j]; k < 256; k ++)
+ *im++ = (int)(k * m + 0.5);
+
+ for (k = 0, im = ImageDensity; k < 256; k ++)
+ *im++ = 255.0 * d * pow((float)k / 255.0, g) + 0.5;
+}
+
+
+/*
+ * 'ImageWhiteToWhite()' - Convert luminance colors to device-dependent
+ * luminance.
+ */
+
+void
+ImageWhiteToWhite(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (ImageHaveProfile)
+ while (count > 0)
+ {
+ *out++ = 255 - ImageDensity[255 - *in++];
+ count --;
+ }
+ else if (in != out)
+ memcpy(out, in, count);
+}
+
+
+/*
+ * 'ImageWhiteToRGB()' - Convert luminance data to RGB.
+ */
+
+void
+ImageWhiteToRGB(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (ImageHaveProfile)
+ {
+ while (count > 0)
+ {
+ out[0] = 255 - ImageDensity[255 - *in++];
+ out[1] = out[0];
+ out[2] = out[0];
+ out += 3;
+ count --;
+ }
+ }
+ else
+ {
+ while (count > 0)
+ {
+ *out++ = *in;
+ *out++ = *in;
+ *out++ = *in++;
+
+ if (ImageColorSpace == CUPS_CSPACE_CIELab)
+ rgb_to_lab(out - 3);
+ else if (ImageColorSpace >= CUPS_CSPACE_CIEXYZ)
+ rgb_to_xyz(out - 3);
+
+ count --;
+ }
+ }
+}
+
+
+/*
+ * 'ImageWhiteToBlack()' - Convert luminance colors to black.
+ */
+
+void
+ImageWhiteToBlack(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (ImageHaveProfile)
+ while (count > 0)
+ {
+ *out++ = ImageDensity[255 - *in++];
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ *out++ = 255 - *in++;
+ count --;
+ }
+}
+
+
+/*
+ * 'ImageWhiteToCMY()' - Convert luminance colors to CMY.
+ */
+
+void
+ImageWhiteToCMY(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (ImageHaveProfile)
+ while (count > 0)
+ {
+ out[0] = ImageDensity[255 - *in++];
+ out[1] = out[0];
+ out[2] = out[0];
+ out += 3;
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ *out++ = 255 - *in;
+ *out++ = 255 - *in;
+ *out++ = 255 - *in++;
+ count --;
+ }
+}
+
+
+/*
+ * 'ImageWhiteToCMYK()' - Convert luminance colors to CMYK.
+ */
+
+void
+ImageWhiteToCMYK(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (ImageHaveProfile)
+ while (count > 0)
+ {
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = ImageDensity[255 - *in++];
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = 255 - *in++;
+ count --;
+ }
+}
+
+
+/*
+ * 'ImageRGBToBlack()' - Convert RGB data to black.
+ */
+
+void
+ImageRGBToBlack(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (ImageHaveProfile)
+ while (count > 0)
+ {
+ *out++ = ImageDensity[255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100];
+ in += 3;
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ *out++ = 255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100;
+ in += 3;
+ count --;
+ }
+}
+
+
+/*
+ * 'ImageRGBToCMY()' - Convert RGB colors to CMY.
+ */
+
+void
+ImageRGBToCMY(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int c, m, y, k; /* CMYK values */
+ int cc, cm, cy; /* Calibrated CMY values */
+
+
+ if (ImageHaveProfile)
+ while (count > 0)
+ {
+ c = 255 - *in++;
+ m = 255 - *in++;
+ y = 255 - *in++;
+ k = min(c, min(m, y));
+ c -= k;
+ m -= k;
+ y -= k;
+
+ cc = ImageMatrix[0][0][c] +
+ ImageMatrix[0][1][m] +
+ ImageMatrix[0][2][y] + k;
+ cm = ImageMatrix[1][0][c] +
+ ImageMatrix[1][1][m] +
+ ImageMatrix[1][2][y] + k;
+ cy = ImageMatrix[2][0][c] +
+ ImageMatrix[2][1][m] +
+ ImageMatrix[2][2][y] + k;
+
+ if (cc < 0)
+ *out++ = 0;
+ else if (cc > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cc];
+
+ if (cm < 0)
+ *out++ = 0;
+ else if (cm > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cm];
+
+ if (cy < 0)
+ *out++ = 0;
+ else if (cy > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cy];
+
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ c = 255 - in[0];
+ m = 255 - in[1];
+ y = 255 - in[2];
+ k = min(c, min(m, y));
+
+ *out++ = (255 - in[1] / 4) * (c - k) / 255 + k;
+ *out++ = (255 - in[2] / 4) * (m - k) / 255 + k;
+ *out++ = (255 - in[0] / 4) * (y - k) / 255 + k;
+ in += 3;
+ count --;
+ }
+}
+
+
+/*
+ * 'ImageRGBToCMYK()' - Convert RGB colors to CMYK.
+ */
+
+void
+ImageRGBToCMYK(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count)/* I - Number of pixels */
+{
+ int c, m, y, k, /* CMYK values */
+ km; /* Maximum K value */
+ int cc, cm, cy; /* Calibrated CMY values */
+
+
+ if (ImageHaveProfile)
+ while (count > 0)
+ {
+ c = 255 - *in++;
+ m = 255 - *in++;
+ y = 255 - *in++;
+ k = min(c, min(m, y));
+
+ if ((km = max(c, max(m, y))) > k)
+ k = k * k * k / (km * km);
+
+ c -= k;
+ m -= k;
+ y -= k;
+
+ cc = (ImageMatrix[0][0][c] +
+ ImageMatrix[0][1][m] +
+ ImageMatrix[0][2][y]);
+ cm = (ImageMatrix[1][0][c] +
+ ImageMatrix[1][1][m] +
+ ImageMatrix[1][2][y]);
+ cy = (ImageMatrix[2][0][c] +
+ ImageMatrix[2][1][m] +
+ ImageMatrix[2][2][y]);
+
+ if (cc < 0)
+ *out++ = 0;
+ else if (cc > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cc];
+
+ if (cm < 0)
+ *out++ = 0;
+ else if (cm > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cm];
+
+ if (cy < 0)
+ *out++ = 0;
+ else if (cy > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cy];
+
+ *out++ = ImageDensity[k];
+
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ c = 255 - *in++;
+ m = 255 - *in++;
+ y = 255 - *in++;
+ k = min(c, min(m, y));
+
+ if ((km = max(c, max(m, y))) > k)
+ k = k * k * k / (km * km);
+
+ c -= k;
+ m -= k;
+ y -= k;
+
+ *out++ = c;
+ *out++ = m;
+ *out++ = y;
+ *out++ = k;
+
+ count --;
+ }
+}
+
+
+/*
+ * 'ImageRGBToWhite()' - Convert RGB colors to luminance.
+ */
+
+void
+ImageRGBToWhite(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ if (ImageHaveProfile)
+ {
+ while (count > 0)
+ {
+ *out++ = 255 - ImageDensity[255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100];
+ in += 3;
+ count --;
+ }
+ }
+ else
+ {
+ while (count > 0)
+ {
+ *out++ = (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100;
+ in += 3;
+ count --;
+ }
+ }
+}
+
+
+/*
+ * 'ImageRGBToRGB()' - Convert RGB colors to device-dependent RGB.
+ */
+
+void
+ImageRGBToRGB(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int c, m, y, k; /* CMYK values */
+ int cr, cg, cb; /* Calibrated RGB values */
+
+
+ if (ImageHaveProfile)
+ {
+ while (count > 0)
+ {
+ c = 255 - *in++;
+ m = 255 - *in++;
+ y = 255 - *in++;
+ k = min(c, min(m, y));
+ c -= k;
+ m -= k;
+ y -= k;
+
+ cr = ImageMatrix[0][0][c] +
+ ImageMatrix[0][1][m] +
+ ImageMatrix[0][2][y] + k;
+ cg = ImageMatrix[1][0][c] +
+ ImageMatrix[1][1][m] +
+ ImageMatrix[1][2][y] + k;
+ cb = ImageMatrix[2][0][c] +
+ ImageMatrix[2][1][m] +
+ ImageMatrix[2][2][y] + k;
+
+ if (cr < 0)
+ *out++ = 255;
+ else if (cr > 255)
+ *out++ = 255 - ImageDensity[255];
+ else
+ *out++ = 255 - ImageDensity[cr];
+
+ if (cg < 0)
+ *out++ = 255;
+ else if (cg > 255)
+ *out++ = 255 - ImageDensity[255];
+ else
+ *out++ = 255 - ImageDensity[cg];
+
+ if (cb < 0)
+ *out++ = 255;
+ else if (cb > 255)
+ *out++ = 255 - ImageDensity[255];
+ else
+ *out++ = 255 - ImageDensity[cb];
+
+ count --;
+ }
+ }
+ else
+ {
+ if (in != out)
+ memcpy(out, in, count * 3);
+
+ if (ImageColorSpace >= CUPS_CSPACE_CIEXYZ)
+ {
+ while (count > 0)
+ {
+ if (ImageColorSpace == CUPS_CSPACE_CIELab)
+ rgb_to_lab(out);
+ else
+ rgb_to_xyz(out);
+
+ out += 3;
+ count --;
+ }
+ }
+ }
+}
+
+
+/*
+ * 'ImageCMYKToBlack()' - Convert CMYK data to black.
+ */
+
+void
+ImageCMYKToBlack(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int k; /* Black value */
+
+
+ if (ImageHaveProfile)
+ while (count > 0)
+ {
+ k = (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 + in[3];
+
+ if (k < 255)
+ *out++ = ImageDensity[k];
+ else
+ *out++ = ImageDensity[255];
+
+ in += 4;
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ k = (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 + in[3];
+
+ if (k < 255)
+ *out++ = k;
+ else
+ *out++ = 255;
+
+ in += 4;
+ count --;
+ }
+}
+
+
+/*
+ * 'ImageCMYKToCMY()' - Convert CMYK colors to CMY.
+ */
+
+void
+ImageCMYKToCMY(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count)/* I - Number of pixels */
+{
+ int c, m, y, k; /* CMYK values */
+ int cc, cm, cy; /* Calibrated CMY values */
+
+
+ if (ImageHaveProfile)
+ while (count > 0)
+ {
+ c = *in++;
+ m = *in++;
+ y = *in++;
+ k = *in++;
+
+ cc = ImageMatrix[0][0][c] +
+ ImageMatrix[0][1][m] +
+ ImageMatrix[0][2][y] + k;
+ cm = ImageMatrix[1][0][c] +
+ ImageMatrix[1][1][m] +
+ ImageMatrix[1][2][y] + k;
+ cy = ImageMatrix[2][0][c] +
+ ImageMatrix[2][1][m] +
+ ImageMatrix[2][2][y] + k;
+
+ if (cc < 0)
+ *out++ = 0;
+ else if (cc > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cc];
+
+ if (cm < 0)
+ *out++ = 0;
+ else if (cm > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cm];
+
+ if (cy < 0)
+ *out++ = 0;
+ else if (cy > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cy];
+
+ count --;
+ }
+ else
+ while (count > 0)
+ {
+ c = *in++;
+ m = *in++;
+ y = *in++;
+ k = *in++;
+
+ c += k;
+ m += k;
+ y += k;
+
+ if (c < 255)
+ *out++ = c;
+ else
+ *out++ = 255;
+
+ if (m < 255)
+ *out++ = y;
+ else
+ *out++ = 255;
+
+ if (y < 255)
+ *out++ = y;
+ else
+ *out++ = 255;
+
+ count --;
+ }
+}
+
+
+/*
+ * 'ImageCMYKToCMYK()' - Convert CMYK colors to CMYK.
+ */
+
+void
+ImageCMYKToCMYK(const ib_t *in, /* I - Input pixels */
+ ib_t *out,/* I - Output pixels */
+ int count)/* I - Number of pixels */
+{
+ int c, m, y, k; /* CMYK values */
+ int cc, cm, cy; /* Calibrated CMY values */
+
+
+ if (ImageHaveProfile)
+ while (count > 0)
+ {
+ c = *in++;
+ m = *in++;
+ y = *in++;
+ k = *in++;
+
+ cc = (ImageMatrix[0][0][c] +
+ ImageMatrix[0][1][m] +
+ ImageMatrix[0][2][y]);
+ cm = (ImageMatrix[1][0][c] +
+ ImageMatrix[1][1][m] +
+ ImageMatrix[1][2][y]);
+ cy = (ImageMatrix[2][0][c] +
+ ImageMatrix[2][1][m] +
+ ImageMatrix[2][2][y]);
+
+ if (cc < 0)
+ *out++ = 0;
+ else if (cc > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cc];
+
+ if (cm < 0)
+ *out++ = 0;
+ else if (cm > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cm];
+
+ if (cy < 0)
+ *out++ = 0;
+ else if (cy > 255)
+ *out++ = ImageDensity[255];
+ else
+ *out++ = ImageDensity[cy];
+
+ *out++ = ImageDensity[k];
+
+ count --;
+ }
+ else if (in != out)
+ {
+ while (count > 0)
+ {
+ *out++ = *in++;
+ *out++ = *in++;
+ *out++ = *in++;
+ *out++ = *in++;
+
+ count --;
+ }
+ }
+}
+
+
+/*
+ * 'ImageCMYKToWhite()' - Convert CMYK colors to luminance.
+ */
+
+void
+ImageCMYKToWhite(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count) /* I - Number of pixels */
+{
+ int w; /* White value */
+
+
+ if (ImageHaveProfile)
+ {
+ while (count > 0)
+ {
+ w = 255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 - in[3];
+
+ if (w > 0)
+ *out++ = ImageDensity[w];
+ else
+ *out++ = ImageDensity[0];
+
+ in += 4;
+ count --;
+ }
+ }
+ else
+ {
+ while (count > 0)
+ {
+ w = 255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 - in[3];
+
+ if (w > 0)
+ *out++ = w;
+ else
+ *out++ = 0;
+
+ in += 4;
+ count --;
+ }
+ }
+}
+
+
+/*
+ * 'ImageCMYKToRGB()' - Convert CMYK colors to device-dependent RGB.
+ */
+
+void
+ImageCMYKToRGB(const ib_t *in, /* I - Input pixels */
+ ib_t *out, /* I - Output pixels */
+ int count)/* I - Number of pixels */
+{
+ int c, m, y, k; /* CMYK values */
+ int cr, cg, cb; /* Calibrated RGB values */
+
+
+ if (ImageHaveProfile)
+ {
+ while (count > 0)
+ {
+ c = *in++;
+ m = *in++;
+ y = *in++;
+ k = *in++;
+
+ cr = ImageMatrix[0][0][c] +
+ ImageMatrix[0][1][m] +
+ ImageMatrix[0][2][y] + k;
+ cg = ImageMatrix[1][0][c] +
+ ImageMatrix[1][1][m] +
+ ImageMatrix[1][2][y] + k;
+ cb = ImageMatrix[2][0][c] +
+ ImageMatrix[2][1][m] +
+ ImageMatrix[2][2][y] + k;
+
+ if (cr < 0)
+ *out++ = 255;
+ else if (cr > 255)
+ *out++ = 255 - ImageDensity[255];
+ else
+ *out++ = 255 - ImageDensity[cr];
+
+ if (cg < 0)
+ *out++ = 255;
+ else if (cg > 255)
+ *out++ = 255 - ImageDensity[255];
+ else
+ *out++ = 255 - ImageDensity[cg];
+
+ if (cb < 0)
+ *out++ = 255;
+ else if (cb > 255)
+ *out++ = 255 - ImageDensity[255];
+ else
+ *out++ = 255 - ImageDensity[cb];
+
+ count --;
+ }
+ }
+ else
+ {
+ while (count > 0)
+ {
+ c = 255 - *in++;
+ m = 255 - *in++;
+ y = 255 - *in++;
+ k = *in++;
+
+ c -= k;
+ m -= k;
+ y -= k;
+
+ if (c > 0)
+ *out++ = c;
+ else
+ *out++ = 0;
+
+ if (m > 0)
+ *out++ = m;
+ else
+ *out++ = 0;
+
+ if (y > 0)
+ *out++ = y;
+ else
+ *out++ = 0;
+
+ if (ImageColorSpace == CUPS_CSPACE_CIELab)
+ rgb_to_lab(out - 3);
+ else if (ImageColorSpace >= CUPS_CSPACE_CIEXYZ)
+ rgb_to_xyz(out - 3);
+
+ count --;
+ }
+ }
+}
+
+
+/*
+ * 'ImageLut()' - Adjust all pixel values with the given LUT.
+ */
+
+void
+ImageLut(ib_t *pixels, /* IO - Input/output pixels */
+ int count, /* I - Number of pixels/bytes to adjust */
+ const ib_t *lut) /* I - Lookup table */
+{
+ while (count > 0)
+ {
+ *pixels = lut[*pixels];
+ pixels ++;
+ count --;
+ }
+}
+
+
+/*
+ * 'ImageRGBAdjust()' - Adjust the hue and saturation of the given RGB colors.
+ */
+
+void
+ImageRGBAdjust(ib_t *pixels, /* IO - Input/output pixels */
+ int count, /* I - Number of pixels to adjust */
+ int saturation, /* I - Color saturation (%) */
+ int hue) /* I - Color hue (degrees) */
+{
+ int i, j, k; /* Looping vars */
+ float mat[3][3]; /* Color adjustment matrix */
+ static int last_sat = 100, /* Last saturation used */
+ last_hue = 0; /* Last hue used */
+ static int lut[3][3][256]; /* Lookup table for matrix */
+
+
+ if (saturation != last_sat ||
+ hue != last_hue)
+ {
+ /*
+ * Build the color adjustment matrix...
+ */
+
+ ident(mat);
+ saturate(mat, saturation * 0.01);
+ huerotate(mat, (float)hue);
+
+ /*
+ * Convert the matrix into a 3x3 array of lookup tables...
+ */
+
+ for (i = 0; i < 3; i ++)
+ for (j = 0; j < 3; j ++)
+ for (k = 0; k < 256; k ++)
+ lut[i][j][k] = mat[i][j] * k + 0.5;
+
+ /*
+ * Save the saturation and hue to compare later...
+ */
+
+ last_sat = saturation;
+ last_hue = hue;
+ }
+
+ /*
+ * Adjust each pixel in the given buffer.
+ */
+
+ while (count > 0)
+ {
+ i = lut[0][0][pixels[0]] +
+ lut[1][0][pixels[1]] +
+ lut[2][0][pixels[2]];
+ if (i < 0)
+ pixels[0] = 0;
+ else if (i > 255)
+ pixels[0] = 255;
+ else
+ pixels[0] = i;
+
+ i = lut[0][1][pixels[0]] +
+ lut[1][1][pixels[1]] +
+ lut[2][1][pixels[2]];
+ if (i < 0)
+ pixels[1] = 0;
+ else if (i > 255)
+ pixels[1] = 255;
+ else
+ pixels[1] = i;
+
+ i = lut[0][2][pixels[0]] +
+ lut[1][2][pixels[1]] +
+ lut[2][2][pixels[2]];
+ if (i < 0)
+ pixels[2] = 0;
+ else if (i > 255)
+ pixels[2] = 255;
+ else
+ pixels[2] = i;
+
+ count --;
+ pixels += 3;
+ }
+}
+
+
+/*
+ * Convert from RGB to CIE XYZ or Lab...
+ */
+
+#define D65_X (0.412453 + 0.357580 + 0.180423)
+#define D65_Y (0.212671 + 0.715160 + 0.072169)
+#define D65_Z (0.019334 + 0.119193 + 0.950227)
+
+
+/*
+ * 'cielab()' - Map CIE Lab transformation...
+ */
+
+static float /* O - Adjusted color value */
+cielab(float x, /* I - Raw color value */
+ float xn) /* I - Whitepoint color value */
+{
+ float x_xn; /* Fraction of whitepoint */
+
+
+ x_xn = x / xn;
+
+ if (x_xn > 0.008856)
+ return (cbrt(x_xn));
+ else
+ return (7.787 * x_xn + 16.0 / 116.0);
+}
+
+
+/*
+ * 'rgb_to_xyz()' - Convert an RGB color to CIE XYZ.
+ */
+
+static void
+rgb_to_xyz(ib_t *val) /* IO - Color value */
+{
+ float r, /* Red value */
+ g, /* Green value */
+ b, /* Blue value */
+ ciex, /* CIE X value */
+ ciey, /* CIE Y value */
+ ciez; /* CIE Z value */
+
+
+ /*
+ * Convert sRGB to linear RGB...
+ */
+
+ r = pow(val[0] / 255.0, 0.58823529412);
+ g = pow(val[1] / 255.0, 0.58823529412);
+ b = pow(val[2] / 255.0, 0.58823529412);
+
+ /*
+ * Convert to CIE XYZ...
+ */
+
+ ciex = 0.412453 * r + 0.357580 * g + 0.180423 * b;
+ ciey = 0.212671 * r + 0.715160 * g + 0.072169 * b;
+ ciez = 0.019334 * r + 0.119193 * g + 0.950227 * b;
+
+ /*
+ * Output 8-bit value...
+ */
+
+ val[0] = (int)(ciex * 255.0 + 0.5);
+ val[1] = (int)(ciey * 255.0 + 0.5);
+ val[2] = (int)(ciez * 255.0 + 0.5);
+}
+
+
+/*
+ * 'rgb_to_lab()' - Convert an RGB color to CIE Lab.
+ */
+
+static void
+rgb_to_lab(ib_t *val) /* IO - Color value */
+{
+ float r, /* Red value */
+ g, /* Green value */
+ b, /* Blue value */
+ ciex, /* CIE X value */
+ ciey, /* CIE Y value */
+ ciez, /* CIE Z value */
+ ciey_yn, /* Normalized luminance */
+ ciel, /* CIE L value */
+ ciea, /* CIE a value */
+ cieb; /* CIE b value */
+
+
+ /*
+ * Convert sRGB to linear RGB...
+ */
+
+ r = pow(val[0] / 255.0, 0.58823529412);
+ g = pow(val[1] / 255.0, 0.58823529412);
+ b = pow(val[2] / 255.0, 0.58823529412);
+
+ /*
+ * Convert to CIE XYZ...
+ */
+
+ ciex = 0.412453 * r + 0.357580 * g + 0.180423 * b;
+ ciey = 0.212671 * r + 0.715160 * g + 0.072169 * b;
+ ciez = 0.019334 * r + 0.119193 * g + 0.950227 * b;
+
+ /*
+ * Normalize and convert to CIE Lab...
+ */
+
+ ciey_yn = ciey / D65_Y;
+
+ if (ciey_yn > 0.008856)
+ ciel = 116 * cbrt(ciey_yn) - 16;
+ else
+ ciel = 903.3 * ciey_yn;
+
+ ciea = 500 * (cielab(ciex, D65_X) - cielab(ciey, D65_Y));
+ cieb = 200 * (cielab(ciey, D65_Y) - cielab(ciez, D65_Z));
+
+ /*
+ * Output 8-bit value...
+ */
+
+ if (ciel < 0.0)
+ val[0] = 0;
+ else if (ciel < 255.0)
+ val[0] = (int)(ciel + 0.5);
+ else
+ val[0] = 255;
+
+ if (ciea < -127.0)
+ val[1] = 128;
+ else if (ciea < 0.0)
+ val[1] = (int)(ciea + 256.5);
+ else if (ciea > 127.0)
+ val[1] = 127;
+ else
+ val[1] = (int)(ciea + 0.5);
+
+ if (cieb < -127.0)
+ val[2] = 128;
+ else if (cieb < 0.0)
+ val[2] = (int)(cieb + 256.5);
+ else if (cieb > 127.0)
+ val[2] = 127;
+ else
+ val[2] = (int)(cieb + 0.5);
+}
+
+
+/*
+ * The color saturation/hue matrix stuff is provided thanks to Mr. Paul
+ * Haeberli at "http://www.sgi.com/grafica/matrix/index.html".
+ */
+
+/*
+ * 'huerotate()' - Rotate the hue, maintaining luminance.
+ */
+
+static void
+huerotate(float mat[3][3], /* I - Matrix to append to */
+ float rot) /* I - Hue rotation in degrees */
+{
+ float hmat[3][3]; /* Hue matrix */
+ float lx, ly, lz; /* Luminance vector */
+ float xrs, xrc; /* X rotation sine/cosine */
+ float yrs, yrc; /* Y rotation sine/cosine */
+ float zrs, zrc; /* Z rotation sine/cosine */
+ float zsx, zsy; /* Z shear x/y */
+
+
+ /*
+ * Load the identity matrix...
+ */
+
+ ident(hmat);
+
+ /*
+ * Rotate the grey vector into positive Z...
+ */
+
+ xrs = M_SQRT1_2;
+ xrc = M_SQRT1_2;
+ xrotate(hmat,xrs,xrc);
+
+ yrs = -1.0 / sqrt(3.0);
+ yrc = -M_SQRT2 * yrs;
+ yrotate(hmat,yrs,yrc);
+
+ /*
+ * Shear the space to make the luminance plane horizontal...
+ */
+
+ xform(hmat, 0.3086, 0.6094, 0.0820, &lx, &ly, &lz);
+ zsx = lx / lz;
+ zsy = ly / lz;
+ zshear(hmat, zsx, zsy);
+
+ /*
+ * Rotate the hue...
+ */
+
+ zrs = sin(rot * M_PI / 180.0);
+ zrc = cos(rot * M_PI / 180.0);
+
+ zrotate(hmat, zrs, zrc);
+
+ /*
+ * Unshear the space to put the luminance plane back...
+ */
+
+ zshear(hmat, -zsx, -zsy);
+
+ /*
+ * Rotate the grey vector back into place...
+ */
+
+ yrotate(hmat, -yrs, yrc);
+ xrotate(hmat, -xrs, xrc);
+
+ /*
+ * Append it to the current matrix...
+ */
+
+ mult(hmat, mat, mat);
+}
+
+
+/*
+ * 'ident()' - Make an identity matrix.
+ */
+
+static void
+ident(float mat[3][3]) /* I - Matrix to identify */
+{
+ mat[0][0] = 1.0;
+ mat[0][1] = 0.0;
+ mat[0][2] = 0.0;
+ mat[1][0] = 0.0;
+ mat[1][1] = 1.0;
+ mat[1][2] = 0.0;
+ mat[2][0] = 0.0;
+ mat[2][1] = 0.0;
+ mat[2][2] = 1.0;
+}
+
+
+/*
+ * 'mult()' - Multiply two matrices.
+ */
+
+static void
+mult(float a[3][3], /* I - First matrix */
+ float b[3][3], /* I - Second matrix */
+ float c[3][3]) /* I - Destination matrix */
+{
+ int x, y; /* Looping vars */
+ float temp[3][3]; /* Temporary matrix */
+
+
+ /*
+ * Multiply a and b, putting the result in temp...
+ */
+
+ for (y = 0; y < 3; y ++)
+ for (x = 0; x < 3; x ++)
+ temp[y][x] = b[y][0] * a[0][x] +
+ b[y][1] * a[1][x] +
+ b[y][2] * a[2][x];
+
+ /*
+ * Copy temp to c (that way c can be a pointer to a or b).
+ */
+
+ memcpy(c, temp, sizeof(temp));
+}
+
+
+/*
+ * 'saturate()' - Make a saturation matrix.
+ */
+
+static void
+saturate(float mat[3][3], /* I - Matrix to append to */
+ float sat) /* I - Desired color saturation */
+{
+ float smat[3][3]; /* Saturation matrix */
+
+
+ smat[0][0] = (1.0 - sat) * 0.3086 + sat;
+ smat[0][1] = (1.0 - sat) * 0.3086;
+ smat[0][2] = (1.0 - sat) * 0.3086;
+ smat[1][0] = (1.0 - sat) * 0.6094;
+ smat[1][1] = (1.0 - sat) * 0.6094 + sat;
+ smat[1][2] = (1.0 - sat) * 0.6094;
+ smat[2][0] = (1.0 - sat) * 0.0820;
+ smat[2][1] = (1.0 - sat) * 0.0820;
+ smat[2][2] = (1.0 - sat) * 0.0820 + sat;
+
+ mult(smat, mat, mat);
+}
+
+
+/*
+ * 'xform()' - Transform a 3D point using a matrix...
+ */
+
+static void
+xform(float mat[3][3], /* I - Matrix */
+ float x, /* I - Input X coordinate */
+ float y, /* I - Input Y coordinate */
+ float z, /* I - Input Z coordinate */
+ float *tx, /* O - Output X coordinate */
+ float *ty, /* O - Output Y coordinate */
+ float *tz) /* O - Output Z coordinate */
+{
+ *tx = x * mat[0][0] + y * mat[1][0] + z * mat[2][0];
+ *ty = x * mat[0][1] + y * mat[1][1] + z * mat[2][1];
+ *tz = x * mat[0][2] + y * mat[1][2] + z * mat[2][2];
+}
+
+
+/*
+ * 'xrotate()' - Rotate about the x (red) axis...
+ */
+
+static void
+xrotate(float mat[3][3], /* I - Matrix */
+ float rs, /* I - Rotation angle sine */
+ float rc) /* I - Rotation angle cosine */
+{
+ float rmat[3][3]; /* I - Rotation matrix */
+
+
+ rmat[0][0] = 1.0;
+ rmat[0][1] = 0.0;
+ rmat[0][2] = 0.0;
+
+ rmat[1][0] = 0.0;
+ rmat[1][1] = rc;
+ rmat[1][2] = rs;
+
+ rmat[2][0] = 0.0;
+ rmat[2][1] = -rs;
+ rmat[2][2] = rc;
+
+ mult(rmat, mat, mat);
+}
+
+
+/*
+ * 'yrotate()' - Rotate about the y (green) axis...
+ */
+
+static void
+yrotate(float mat[3][3], /* I - Matrix */
+ float rs, /* I - Rotation angle sine */
+ float rc) /* I - Rotation angle cosine */
+{
+ float rmat[3][3]; /* I - Rotation matrix */
+
+
+ rmat[0][0] = rc;
+ rmat[0][1] = 0.0;
+ rmat[0][2] = -rs;
+
+ rmat[1][0] = 0.0;
+ rmat[1][1] = 1.0;
+ rmat[1][2] = 0.0;
+
+ rmat[2][0] = rs;
+ rmat[2][1] = 0.0;
+ rmat[2][2] = rc;
+
+ mult(rmat,mat,mat);
+}
+
+
+/*
+ * 'zrotate()' - Rotate about the z (blue) axis...
+ */
+
+static void
+zrotate(float mat[3][3], /* I - Matrix */
+ float rs, /* I - Rotation angle sine */
+ float rc) /* I - Rotation angle cosine */
+{
+ float rmat[3][3]; /* I - Rotation matrix */
+
+
+ rmat[0][0] = rc;
+ rmat[0][1] = rs;
+ rmat[0][2] = 0.0;
+
+ rmat[1][0] = -rs;
+ rmat[1][1] = rc;
+ rmat[1][2] = 0.0;
+
+ rmat[2][0] = 0.0;
+ rmat[2][1] = 0.0;
+ rmat[2][2] = 1.0;
+
+ mult(rmat,mat,mat);
+}
+
+
+/*
+ * 'zshear()' - Shear z using x and y...
+ */
+
+static void
+zshear(float mat[3][3], /* I - Matrix */
+ float dx, /* I - X shear */
+ float dy) /* I - Y shear */
+{
+ float smat[3][3]; /* Shear matrix */
+
+
+ smat[0][0] = 1.0;
+ smat[0][1] = 0.0;
+ smat[0][2] = dx;
+
+ smat[1][0] = 0.0;
+ smat[1][1] = 1.0;
+ smat[1][2] = dy;
+
+ smat[2][0] = 0.0;
+ smat[2][1] = 0.0;
+ smat[2][2] = 1.0;
+
+ mult(smat, mat, mat);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-gif.c b/filter/image-gif.c
new file mode 100644
index 000000000..8cb7d1105
--- /dev/null
+++ b/filter/image-gif.c
@@ -0,0 +1,658 @@
+/*
+ * "$Id$"
+ *
+ * GIF image routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageReadGIF() - Read a GIF image file.
+ * gif_read_cmap() - Read the colormap from a GIF file...
+ * gif_get_block() - Read a GIF data block...
+ * gif_get_code() - Get a LZW code from the file...
+ * gif_read_lzw() - Read a byte from the LZW stream...
+ * gif_read_image() - Read a GIF image stream...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+
+
+/*
+ * GIF definitions...
+ */
+
+#define GIF_INTERLACE 0x40
+#define GIF_COLORMAP 0x80
+
+typedef ib_t gif_cmap_t[256][4];
+
+
+/*
+ * Local globals...
+ */
+
+static int gif_eof = 0; /* Did we hit EOF? */
+
+
+/*
+ * Local functions...
+ */
+
+static int gif_read_cmap(FILE *fp, int ncolors, gif_cmap_t cmap,
+ int *gray);
+static int gif_get_block(FILE *fp, unsigned char *buffer);
+static int gif_get_code (FILE *fp, int code_size, int first_time);
+static int gif_read_lzw(FILE *fp, int first_time, int input_code_size);
+static int gif_read_image(FILE *fp, image_t *img, gif_cmap_t cmap,
+ int interlace);
+
+
+/*
+ * 'ImageReadGIF()' - Read a GIF image file.
+ */
+
+int /* O - Read status */
+ImageReadGIF(image_t *img, /* IO - Image */
+ FILE *fp, /* I - Image file */
+ int primary, /* I - Primary choice for colorspace */
+ int secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ unsigned char buf[1024]; /* Input buffer */
+ gif_cmap_t cmap; /* Colormap */
+ int i, /* Looping var */
+ bpp, /* Bytes per pixel */
+ gray, /* Grayscale image? */
+ ncolors, /* Bits per pixel */
+ transparent; /* Transparent color index */
+
+
+ /*
+ * GIF files are either grayscale or RGB - no CMYK...
+ */
+
+ if (primary == IMAGE_RGB_CMYK)
+ primary = IMAGE_RGB;
+
+ /*
+ * Read the header; we already know it is a GIF file...
+ */
+
+ fread(buf, 13, 1, fp);
+
+ img->xsize = (buf[7] << 8) | buf[6];
+ img->ysize = (buf[9] << 8) | buf[8];
+ ncolors = 2 << (buf[10] & 0x07);
+ gray = primary == IMAGE_BLACK || primary == IMAGE_WHITE;
+
+ if (buf[10] & GIF_COLORMAP)
+ if (gif_read_cmap(fp, ncolors, cmap, &gray))
+ {
+ fclose(fp);
+ return (-1);
+ }
+
+ transparent = -1;
+
+ for (;;)
+ {
+ switch (getc(fp))
+ {
+ case ';' : /* End of image */
+ fclose(fp);
+ return (-1); /* Early end of file */
+
+ case '!' : /* Extension record */
+ buf[0] = getc(fp);
+ if (buf[0] == 0xf9) /* Graphic Control Extension */
+ {
+ gif_get_block(fp, buf);
+ if (buf[0] & 1) /* Get transparent color index */
+ transparent = buf[3];
+ }
+
+ while (gif_get_block(fp, buf) != 0);
+ break;
+
+ case ',' : /* Image data */
+ fread(buf, 9, 1, fp);
+
+ if (buf[8] & GIF_COLORMAP)
+ {
+ ncolors = 2 << (buf[8] & 0x07);
+ gray = primary == IMAGE_BLACK || primary == IMAGE_WHITE;
+
+ if (gif_read_cmap(fp, ncolors, cmap, &gray))
+ {
+ fclose(fp);
+ return (-1);
+ }
+ }
+
+ if (transparent >= 0)
+ {
+ /*
+ * Make transparent color white...
+ */
+
+ cmap[transparent][0] = 255;
+ cmap[transparent][1] = 255;
+ cmap[transparent][2] = 255;
+ }
+
+ if (gray)
+ {
+ switch (secondary)
+ {
+ case IMAGE_CMYK :
+ for (i = ncolors - 1; i >= 0; i --)
+ ImageWhiteToCMYK(cmap[i], cmap[i], 1);
+ break;
+ case IMAGE_CMY :
+ for (i = ncolors - 1; i >= 0; i --)
+ ImageWhiteToCMY(cmap[i], cmap[i], 1);
+ break;
+ case IMAGE_BLACK :
+ for (i = ncolors - 1; i >= 0; i --)
+ ImageWhiteToBlack(cmap[i], cmap[i], 1);
+ break;
+ case IMAGE_WHITE :
+ break;
+ case IMAGE_RGB :
+ for (i = ncolors - 1; i >= 0; i --)
+ ImageWhiteToRGB(cmap[i], cmap[i], 1);
+ break;
+ }
+
+ img->colorspace = secondary;
+ }
+ else
+ {
+ if (hue != 0 || saturation != 100)
+ for (i = ncolors - 1; i >= 0; i --)
+ ImageRGBAdjust(cmap[i], 1, saturation, hue);
+
+ switch (primary)
+ {
+ case IMAGE_CMYK :
+ for (i = ncolors - 1; i >= 0; i --)
+ ImageRGBToCMYK(cmap[i], cmap[i], 1);
+ break;
+ case IMAGE_CMY :
+ for (i = ncolors - 1; i >= 0; i --)
+ ImageRGBToCMY(cmap[i], cmap[i], 1);
+ break;
+ case IMAGE_BLACK :
+ for (i = ncolors - 1; i >= 0; i --)
+ ImageRGBToBlack(cmap[i], cmap[i], 1);
+ break;
+ case IMAGE_WHITE :
+ for (i = ncolors - 1; i >= 0; i --)
+ ImageRGBToWhite(cmap[i], cmap[i], 1);
+ break;
+ case IMAGE_RGB :
+ break;
+ }
+
+ img->colorspace = primary;
+ }
+
+ if (lut)
+ {
+ bpp = ImageGetDepth(img);
+
+ for (i = ncolors - 1; i >= 0; i --)
+ ImageLut(cmap[i], bpp, lut);
+ }
+
+ img->xsize = (buf[5] << 8) | buf[4];
+ img->ysize = (buf[7] << 8) | buf[6];
+
+ i = gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE);
+ fclose(fp);
+ return (i);
+ }
+ }
+}
+
+
+/*
+ * 'gif_read_cmap()' - Read the colormap from a GIF file...
+ */
+
+static int /* O - -1 on error, 0 on success */
+gif_read_cmap(FILE *fp, /* I - File to read from */
+ int ncolors, /* I - Number of colors in file */
+ gif_cmap_t cmap, /* O - Colormap information */
+ int *gray) /* IO - Is the image grayscale? */
+{
+ int i; /* Looping var */
+
+
+ /*
+ * Read the colormap...
+ */
+
+ for (i = 0; i < ncolors; i ++)
+ if (fread(cmap[i], 3, 1, fp) < 1)
+ return (-1);
+
+ /*
+ * Check to see if the colormap is a grayscale ramp...
+ */
+
+ for (i = 0; i < ncolors; i ++)
+ if (cmap[i][0] != cmap[i][1] || cmap[i][1] != cmap[i][2])
+ break;
+
+ if (i == ncolors)
+ {
+ *gray = 1;
+ return (0);
+ }
+
+ /*
+ * If this needs to be a grayscale image, convert the RGB values to
+ * luminance values...
+ */
+
+ if (*gray)
+ for (i = 0; i < ncolors; i ++)
+ cmap[i][0] = (cmap[i][0] * 31 + cmap[i][1] * 61 + cmap[i][2] * 8) / 100;
+
+ return (0);
+}
+
+
+/*
+ * 'gif_get_block()' - Read a GIF data block...
+ */
+
+static int /* O - Number characters read */
+gif_get_block(FILE *fp, /* I - File to read from */
+ unsigned char *buf) /* I - Input buffer */
+{
+ int count; /* Number of character to read */
+
+
+ /*
+ * Read the count byte followed by the data from the file...
+ */
+
+ if ((count = getc(fp)) == EOF)
+ {
+ gif_eof = 1;
+ return (-1);
+ }
+ else if (count == 0)
+ gif_eof = 1;
+ else if (fread(buf, 1, count, fp) < count)
+ {
+ gif_eof = 1;
+ return (-1);
+ }
+ else
+ gif_eof = 0;
+
+ return (count);
+}
+
+
+/*
+ * 'gif_get_code()' - Get a LZW code from the file...
+ */
+
+static int /* O - LZW code */
+gif_get_code(FILE *fp, /* I - File to read from */
+ int code_size, /* I - Size of code in bits */
+ int first_time) /* I - 1 = first time, 0 = not first time */
+{
+ unsigned i, j, /* Looping vars */
+ ret; /* Return value */
+ int count; /* Number of bytes read */
+ static unsigned char buf[280]; /* Input buffer */
+ static unsigned curbit, /* Current bit */
+ lastbit, /* Last bit in buffer */
+ done, /* Done with this buffer? */
+ last_byte; /* Last byte in buffer */
+ static unsigned char bits[8] = /* Bit masks for codes */
+ {
+ 0x01, 0x02, 0x04, 0x08,
+ 0x10, 0x20, 0x40, 0x80
+ };
+
+
+ if (first_time)
+ {
+ /*
+ * Just initialize the input buffer...
+ */
+
+ curbit = 0;
+ lastbit = 0;
+ done = 0;
+
+ return (0);
+ }
+
+
+ if ((curbit + code_size) >= lastbit)
+ {
+ /*
+ * Don't have enough bits to hold the code...
+ */
+
+ if (done)
+ return (-1); /* Sorry, no more... */
+
+ /*
+ * Move last two bytes to front of buffer...
+ */
+
+ if (last_byte > 1)
+ {
+ buf[0] = buf[last_byte - 2];
+ buf[1] = buf[last_byte - 1];
+
+ last_byte = 2;
+ }
+
+ /*
+ * Read in another buffer...
+ */
+
+ if ((count = gif_get_block (fp, buf + last_byte)) <= 0)
+ {
+ /*
+ * Whoops, no more data!
+ */
+
+ done = 1;
+ return (-1);
+ }
+
+ /*
+ * Update buffer state...
+ */
+
+ last_byte += count;
+ curbit = (curbit - lastbit) + 16;
+ lastbit = last_byte * 8;
+ }
+
+ ret = 0;
+ for (ret = 0, i = curbit + code_size - 1, j = code_size;
+ j > 0;
+ i --, j --)
+ ret = (ret << 1) | ((buf[i / 8] & bits[i & 7]) != 0);
+
+ curbit += code_size;
+
+ return ret;
+}
+
+
+/*
+ * 'gif_read_lzw()' - Read a byte from the LZW stream...
+ */
+
+static int /* I - Byte from stream */
+gif_read_lzw(FILE *fp, /* I - File to read from */
+ int first_time, /* I - 1 = first time, 0 = not first time */
+ int input_code_size) /* I - Code size in bits */
+{
+ int i, /* Looping var */
+ code, /* Current code */
+ incode; /* Input code */
+ static short fresh = 0, /* 1 = empty buffers */
+ code_size, /* Current code size */
+ set_code_size, /* Initial code size set */
+ max_code, /* Maximum code used */
+ max_code_size, /* Maximum code size */
+ firstcode, /* First code read */
+ oldcode, /* Last code read */
+ clear_code, /* Clear code for LZW input */
+ end_code, /* End code for LZW input */
+ table[2][4096], /* String table */
+ stack[8192], /* Output stack */
+ *sp; /* Current stack pointer */
+
+
+ if (first_time)
+ {
+ /*
+ * Setup LZW state...
+ */
+
+ set_code_size = input_code_size;
+ code_size = set_code_size + 1;
+ clear_code = 1 << set_code_size;
+ end_code = clear_code + 1;
+ max_code_size = 2 * clear_code;
+ max_code = clear_code + 2;
+
+ /*
+ * Initialize input buffers...
+ */
+
+ gif_get_code(fp, 0, 1);
+
+ /*
+ * Wipe the decompressor table...
+ */
+
+ fresh = 1;
+
+ for (i = 0; i < clear_code; i ++)
+ {
+ table[0][i] = 0;
+ table[1][i] = i;
+ }
+
+ for (; i < 4096; i ++)
+ table[0][i] = table[1][0] = 0;
+
+ sp = stack;
+
+ return (0);
+ }
+ else if (fresh)
+ {
+ fresh = 0;
+
+ do
+ firstcode = oldcode = gif_get_code(fp, code_size, 0);
+ while (firstcode == clear_code);
+
+ return (firstcode);
+ }
+
+ if (sp > stack)
+ return (*--sp);
+
+ while ((code = gif_get_code (fp, code_size, 0)) >= 0)
+ {
+ if (code == clear_code)
+ {
+ for (i = 0; i < clear_code; i ++)
+ {
+ table[0][i] = 0;
+ table[1][i] = i;
+ }
+
+ for (; i < 4096; i ++)
+ table[0][i] = table[1][i] = 0;
+
+ code_size = set_code_size + 1;
+ max_code_size = 2 * clear_code;
+ max_code = clear_code + 2;
+
+ sp = stack;
+
+ firstcode = oldcode = gif_get_code(fp, code_size, 0);
+
+ return (firstcode);
+ }
+ else if (code == end_code)
+ {
+ unsigned char buf[260];
+
+
+ if (!gif_eof)
+ while (gif_get_block(fp, buf) > 0);
+
+ return (-2);
+ }
+
+ incode = code;
+
+ if (code >= max_code)
+ {
+ *sp++ = firstcode;
+ code = oldcode;
+ }
+
+ while (code >= clear_code)
+ {
+ *sp++ = table[1][code];
+ if (code == table[0][code])
+ return (255);
+
+ code = table[0][code];
+ }
+
+ *sp++ = firstcode = table[1][code];
+ code = max_code;
+
+ if (code < 4096)
+ {
+ table[0][code] = oldcode;
+ table[1][code] = firstcode;
+ max_code ++;
+
+ if (max_code >= max_code_size && max_code_size < 4096)
+ {
+ max_code_size *= 2;
+ code_size ++;
+ }
+ }
+
+ oldcode = incode;
+
+ if (sp > stack)
+ return (*--sp);
+ }
+
+ return (code);
+}
+
+
+/*
+ * 'gif_read_image()' - Read a GIF image stream...
+ */
+
+static int /* I - 0 = success, -1 = failure */
+gif_read_image(FILE *fp, /* I - Input file */
+ image_t *img, /* I - Image pointer */
+ gif_cmap_t cmap, /* I - Colormap */
+ int interlace) /* I - Non-zero = interlaced image */
+{
+ unsigned char code_size; /* Code size */
+ ib_t *pixels, /* Pixel buffer */
+ *temp; /* Current pixel */
+ int xpos, /* Current X position */
+ ypos, /* Current Y position */
+ pass; /* Current pass */
+ int pixel; /* Current pixel */
+ int bpp; /* Bytes per pixel */
+ static int xpasses[4] = { 8, 8, 4, 2 },
+ ypasses[5] = { 0, 4, 2, 1, 999999 };
+
+
+ bpp = ImageGetDepth(img);
+ pixels = calloc(bpp, img->xsize);
+ xpos = 0;
+ ypos = 0;
+ pass = 0;
+ code_size = getc(fp);
+
+ if (gif_read_lzw(fp, 1, code_size) < 0)
+ return (-1);
+
+ temp = pixels;
+ while ((pixel = gif_read_lzw(fp, 0, code_size)) >= 0)
+ {
+ switch (bpp)
+ {
+ case 4 :
+ temp[3] = cmap[pixel][3];
+ case 3 :
+ temp[2] = cmap[pixel][2];
+ case 2 :
+ temp[1] = cmap[pixel][1];
+ default :
+ temp[0] = cmap[pixel][0];
+ }
+
+ xpos ++;
+ temp += bpp;
+ if (xpos == img->xsize)
+ {
+ ImagePutRow(img, 0, ypos, img->xsize, pixels);
+
+ xpos = 0;
+ temp = pixels;
+
+ if (interlace)
+ {
+ ypos += xpasses[pass];
+
+ if (ypos >= img->ysize)
+ {
+ pass ++;
+
+ ypos = ypasses[pass];
+ }
+ }
+ else
+ ypos ++;
+ }
+
+ if (ypos >= img->ysize)
+ break;
+ }
+
+ free(pixels);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-jpeg.c b/filter/image-jpeg.c
new file mode 100644
index 000000000..b8c3e7a70
--- /dev/null
+++ b/filter/image-jpeg.c
@@ -0,0 +1,296 @@
+/*
+ * "$Id$"
+ *
+ * JPEG image routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageReadJPEG() - Read a JPEG image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+
+#ifdef HAVE_LIBJPEG
+# include <jpeglib.h> /* JPEG/JFIF image definitions */
+
+
+/*
+ * 'ImageReadJPEG()' - Read a JPEG image file.
+ */
+
+int /* O - Read status */
+ImageReadJPEG(image_t *img, /* IO - Image */
+ FILE *fp, /* I - Image file */
+ int primary, /* I - Primary choice for colorspace */
+ int secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ struct jpeg_decompress_struct cinfo; /* Decompressor info */
+ struct jpeg_error_mgr jerr; /* Error handler info */
+ ib_t *in, /* Input pixels */
+ *out; /* Output pixels */
+ char header[16];
+ /* Photoshop JPEG header */
+ int psjpeg; /* Non-zero if Photoshop JPEG */
+ static const char *cspaces[] =
+ { /* JPEG colorspaces... */
+ "JCS_UNKNOWN",
+ "JCS_GRAYSCALE",
+ "JCS_RGB",
+ "JCS_YCbCr",
+ "JCS_CMYK",
+ "JCS_YCCK"
+ };
+
+
+ /*
+ * Read the first 16 bytes to determine if this is a Photoshop JPEG file...
+ */
+
+ fread(header, sizeof(header), 1, fp);
+ rewind(fp);
+
+ psjpeg = memcmp(header + 6, "Photoshop ", 10) == 0;
+
+ /*
+ * Read the JPEG header...
+ */
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&cinfo);
+ jpeg_stdio_src(&cinfo, fp);
+ jpeg_read_header(&cinfo, 1);
+
+ cinfo.quantize_colors = 0;
+
+ fprintf(stderr, "DEBUG: num_components = %d\n", cinfo.num_components);
+ fprintf(stderr, "DEBUG: jpeg_color_space = %s\n",
+ cspaces[cinfo.jpeg_color_space]);
+
+ if (cinfo.num_components == 1)
+ {
+ fputs("DEBUG: Converting image to grayscale...\n", stderr);
+
+ cinfo.out_color_space = JCS_GRAYSCALE;
+ cinfo.out_color_components = 1;
+ cinfo.output_components = 1;
+
+ img->colorspace = secondary;
+ }
+ else if (cinfo.num_components == 4)
+ {
+ fputs("DEBUG: Converting image to CMYK...\n", stderr);
+
+ cinfo.out_color_space = JCS_CMYK;
+ cinfo.out_color_components = 4;
+ cinfo.output_components = 4;
+
+ img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_CMYK : primary;
+ }
+ else
+ {
+ fputs("DEBUG: Converting image to RGB...\n", stderr);
+
+ cinfo.out_color_space = JCS_RGB;
+ cinfo.out_color_components = 3;
+ cinfo.output_components = 3;
+
+ img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_RGB : primary;
+ }
+
+ jpeg_calc_output_dimensions(&cinfo);
+
+ img->xsize = cinfo.output_width;
+ img->ysize = cinfo.output_height;
+
+ if (cinfo.X_density > 0 && cinfo.Y_density > 0 && cinfo.density_unit > 0)
+ {
+ if (cinfo.density_unit == 1)
+ {
+ img->xppi = cinfo.X_density;
+ img->yppi = cinfo.Y_density;
+ }
+ else
+ {
+ img->xppi = (int)((float)cinfo.X_density * 2.54);
+ img->yppi = (int)((float)cinfo.Y_density * 2.54);
+ }
+ }
+
+ fprintf(stderr, "DEBUG: JPEG image %dx%dx%d, %dx%d PPI\n",
+ img->xsize, img->ysize, cinfo.output_components,
+ img->xppi, img->yppi);
+
+ ImageSetMaxTiles(img, 0);
+
+ in = malloc(img->xsize * cinfo.output_components);
+ out = malloc(img->xsize * ImageGetDepth(img));
+
+ jpeg_start_decompress(&cinfo);
+
+ while (cinfo.output_scanline < cinfo.output_height)
+ {
+ jpeg_read_scanlines(&cinfo, (JSAMPROW *)&in, (JDIMENSION)1);
+
+ if (psjpeg && cinfo.output_components == 4)
+ {
+ /*
+ * Invert CMYK data from Photoshop...
+ */
+
+ ib_t *ptr; /* Pointer into buffer */
+ int i; /* Looping var */
+
+
+ for (ptr = in, i = img->xsize * 4; i > 0; i --, ptr ++)
+ *ptr = 255 - *ptr;
+ }
+
+ if ((saturation != 100 || hue != 0) && cinfo.output_components == 3)
+ ImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ if ((img->colorspace == IMAGE_WHITE && cinfo.out_color_space == JCS_GRAYSCALE) ||
+ (img->colorspace == IMAGE_RGB && cinfo.out_color_space == JCS_RGB) ||
+ (img->colorspace == IMAGE_CMYK && cinfo.out_color_space == JCS_CMYK))
+ {
+#ifdef DEBUG
+ int i, j;
+ ib_t *ptr;
+
+
+ fputs("DEBUG: Direct Data...\n", stderr);
+
+ fputs("DEBUG:", stderr);
+
+ for (i = 0, ptr = in; i < img->xsize; i ++)
+ {
+ putc(' ', stderr);
+ for (j = 0; j < cinfo.output_components; j ++, ptr ++)
+ fprintf(stderr, "%02X", *ptr & 255);
+ }
+
+ putc('\n', stderr);
+#endif /* DEBUG */
+
+ if (lut)
+ ImageLut(in, img->xsize * ImageGetDepth(img), lut);
+
+ ImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, in);
+ }
+ else if (cinfo.out_color_space == JCS_GRAYSCALE)
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_BLACK :
+ ImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_RGB :
+ ImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * ImageGetDepth(img), lut);
+
+ ImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out);
+ }
+ else if (cinfo.out_color_space == JCS_RGB)
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * ImageGetDepth(img), lut);
+
+ ImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out);
+ }
+ else /* JCS_CMYK */
+ {
+ fputs("DEBUG: JCS_CMYK\n", stderr);
+
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageCMYKToWhite(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageCMYKToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageCMYKToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_RGB :
+ ImageCMYKToRGB(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * ImageGetDepth(img), lut);
+
+ ImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out);
+ }
+ }
+
+ free(in);
+ free(out);
+
+ jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+
+ fclose(fp);
+
+ return (0);
+}
+
+
+#endif /* HAVE_LIBJPEG */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-photocd.c b/filter/image-photocd.c
new file mode 100644
index 000000000..6f2ca1c73
--- /dev/null
+++ b/filter/image-photocd.c
@@ -0,0 +1,325 @@
+/*
+ * "$Id$"
+ *
+ * PhotoCD routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageReadPhotoCD() - Read a PhotoCD image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+
+
+/*
+ * PhotoCD support is currently limited to the 768x512 base image, which
+ * is only YCC encoded. Support for the higher resolution images will
+ * require a lot of extra code...
+ */
+
+/*
+ * 'ImageReadPhotoCD()' - Read a PhotoCD image file.
+ */
+
+int /* O - Read status */
+ImageReadPhotoCD(image_t *img, /* IO - Image */
+ FILE *fp, /* I - Image file */
+ int primary, /* I - Primary choice for colorspace */
+ int secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int x, y; /* Looping vars */
+ int xdir, /* X direction */
+ xstart; /* X starting point */
+ int bpp; /* Bytes per pixel */
+ int pass; /* Pass number */
+ int rotation; /* 0 for 768x512, 1 for 512x768 */
+ int temp, /* Adjusted luminance */
+ temp2, /* Red, green, and blue values */
+ cb, cr; /* Adjusted chroma values */
+ ib_t *in, /* Input (YCC) pixels */
+ *iy, /* Luminance */
+ *icb, /* Blue chroma */
+ *icr, /* Red chroma */
+ *rgb, /* RGB */
+ *rgbptr, /* Pointer into RGB data */
+ *out; /* Output pixels */
+
+
+ (void)secondary;
+
+ /*
+ * Get the image orientation...
+ */
+
+ fseek(fp, 72, SEEK_SET);
+ rotation = (getc(fp) & 63) != 8;
+
+ /*
+ * Seek to the start of the base image...
+ */
+
+ fseek(fp, 0x30000, SEEK_SET);
+
+ /*
+ * Allocate and initialize...
+ */
+
+ img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_RGB : primary;
+ img->xppi = 128;
+ img->yppi = 128;
+
+ if (rotation)
+ {
+ img->xsize = 512;
+ img->ysize = 768;
+ }
+ else
+ {
+ img->xsize = 768;
+ img->ysize = 512;
+ }
+
+ ImageSetMaxTiles(img, 0);
+
+ bpp = ImageGetDepth(img);
+ in = malloc(768 * 3);
+ out = malloc(768 * bpp);
+
+ if (bpp > 1)
+ rgb = malloc(768 * 3);
+ else
+ rgb = NULL;
+
+ if (rotation)
+ {
+ xstart = 767 * bpp;
+ xdir = -2 * bpp;
+ }
+ else
+ {
+ xstart = 0;
+ xdir = 0;
+ }
+
+ /*
+ * Read the image file...
+ */
+
+ for (y = 0; y < 512; y += 2)
+ {
+ /*
+ * Grab the next two scanlines:
+ *
+ * YYYYYYYYYYYYYYY...
+ * YYYYYYYYYYYYYYY...
+ * CbCbCb...CrCrCr...
+ */
+
+ if (fread(in, 1, 768 * 3, fp) < (768 * 3))
+ {
+ /*
+ * Couldn't read a row of data - return an error!
+ */
+
+ free(in);
+ free(out);
+
+ return (-1);
+ }
+
+ /*
+ * Process the two scanlines...
+ */
+
+ for (pass = 0, iy = in; pass < 2; pass ++)
+ {
+ if (bpp == 1)
+ {
+ /*
+ * Just extract the luminance channel from the line and put it
+ * in the image...
+ */
+
+ if (primary == IMAGE_BLACK)
+ {
+ if (rotation)
+ {
+ for (rgbptr = out + xstart, x = 0; x < 768; x ++)
+ *rgbptr-- = 255 - *iy++;
+
+ if (lut)
+ ImageLut(out, 768, lut);
+
+ ImagePutCol(img, 511 - y - pass, 0, 768, out);
+ }
+ else
+ {
+ ImageWhiteToBlack(iy, out, 768);
+
+ if (lut)
+ ImageLut(out, 768, lut);
+
+ ImagePutRow(img, 0, y + pass, 768, out);
+ iy += 768;
+ }
+ }
+ else if (rotation)
+ {
+ for (rgbptr = out + xstart, x = 0; x < 768; x ++)
+ *rgbptr-- = 255 - *iy++;
+
+ if (lut)
+ ImageLut(out, 768, lut);
+
+ ImagePutCol(img, 511 - y - pass, 0, 768, out);
+ }
+ else
+ {
+ if (lut)
+ ImageLut(iy, 768, lut);
+
+ ImagePutRow(img, 0, y + pass, 768, iy);
+ iy += 768;
+ }
+ }
+ else
+ {
+ /*
+ * Convert YCbCr to RGB... While every pixel gets a luminance
+ * value, adjacent pixels share chroma information.
+ */
+
+ cb = cr = 0.0f;
+
+ for (x = 0, rgbptr = rgb + xstart, icb = in + 1536, icr = in + 1920;
+ x < 768;
+ x ++, iy ++, rgbptr += xdir)
+ {
+ if (!(x & 1))
+ {
+ cb = (float)(*icb - 156);
+ cr = (float)(*icr - 137);
+ }
+
+ temp = 92241 * (*iy);
+
+ temp2 = (temp + 86706 * cr) / 65536;
+ if (temp2 < 0)
+ *rgbptr++ = 0;
+ else if (temp2 > 255)
+ *rgbptr++ = 255;
+ else
+ *rgbptr++ = temp2;
+
+ temp2 = (temp - 25914 * cb - 44166 * cr) / 65536;
+ if (temp2 < 0)
+ *rgbptr++ = 0;
+ else if (temp2 > 255)
+ *rgbptr++ = 255;
+ else
+ *rgbptr++ = temp2;
+
+ temp2 = (temp + 133434 * cb) / 65536;
+ if (temp2 < 0)
+ *rgbptr++ = 0;
+ else if (temp2 > 255)
+ *rgbptr++ = 255;
+ else
+ *rgbptr++ = temp2;
+
+ if (x & 1)
+ {
+ icb ++;
+ icr ++;
+ }
+ }
+
+ /*
+ * Adjust the hue and saturation if needed...
+ */
+
+ if (saturation != 100 || hue != 0)
+ ImageRGBAdjust(rgb, 768, saturation, hue);
+
+ /*
+ * Then convert the RGB data to the appropriate colorspace and
+ * put it in the image...
+ */
+
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (lut)
+ ImageLut(rgb, 768 * 3, lut);
+
+ if (rotation)
+ ImagePutCol(img, 511 - y - pass, 0, 768, rgb);
+ else
+ ImagePutRow(img, 0, y + pass, 768, rgb);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_CMY :
+ ImageRGBToCMY(rgb, out, 768);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(rgb, out, 768);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, 768 * bpp, lut);
+
+ if (rotation)
+ ImagePutCol(img, 511 - y - pass, 0, 768, out);
+ else
+ ImagePutRow(img, 0, y + pass, 768, out);
+ }
+ }
+ }
+ }
+
+ /*
+ * Free memory and return...
+ */
+
+ free(in);
+ free(out);
+ if (bpp > 1)
+ free(rgb);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-pix.c b/filter/image-pix.c
new file mode 100644
index 000000000..71e4b1569
--- /dev/null
+++ b/filter/image-pix.c
@@ -0,0 +1,225 @@
+/*
+ * "$Id$"
+ *
+ * Alias PIX image routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageReadPIX() - Read a PIX image file.
+ * read_short() - Read a 16-bit integer.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+
+
+/*
+ * Local functions...
+ */
+
+static short read_short(FILE *fp);
+
+
+/*
+ * 'ImageReadPIX()' - Read a PIX image file.
+ */
+
+int /* O - Read status */
+ImageReadPIX(image_t *img, /* IO - Image */
+ FILE *fp, /* I - Image file */
+ int primary, /* I - Primary choice for colorspace */
+ int secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ short width, /* Width of image */
+ height, /* Height of image */
+ depth; /* Depth of image (bits) */
+ int count, /* Repetition count */
+ bpp, /* Bytes per pixel */
+ x, y; /* Looping vars */
+ ib_t r, g, b; /* Red, green/gray, blue values */
+ ib_t *in, /* Input pixels */
+ *out, /* Output pixels */
+ *ptr; /* Pointer into pixels */
+
+
+ /*
+ * Get the image dimensions and setup the image...
+ */
+
+ width = read_short(fp);
+ height = read_short(fp);
+ read_short(fp);
+ read_short(fp);
+ depth = read_short(fp);
+
+ if (depth == 8)
+ img->colorspace = secondary;
+ else
+ img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_RGB : primary;
+
+ img->xsize = width;
+ img->ysize = height;
+
+ ImageSetMaxTiles(img, 0);
+
+ in = malloc(img->xsize * (depth / 8));
+ bpp = ImageGetDepth(img);
+ out = malloc(img->xsize * bpp);
+
+ /*
+ * Read the image data...
+ */
+
+ if (depth == 8)
+ {
+ for (count = 0, y = 0, g = 0; y < img->ysize; y ++)
+ {
+ if (img->colorspace == IMAGE_WHITE)
+ ptr = out;
+ else
+ ptr = in;
+
+ for (x = img->xsize; x > 0; x --, count --)
+ {
+ if (count == 0)
+ {
+ count = getc(fp);
+ g = getc(fp);
+ }
+
+ *ptr++ = g;
+ }
+
+ if (img->colorspace != IMAGE_WHITE)
+ switch (img->colorspace)
+ {
+ case IMAGE_RGB :
+ ImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ else
+ {
+ for (count = 0, y = 0, r = 0, g = 0, b = 0; y < img->ysize; y ++)
+ {
+ if (img->colorspace == IMAGE_RGB)
+ ptr = out;
+ else
+ ptr = in;
+
+ for (x = img->xsize; x > 0; x --, count --)
+ {
+ if (count == 0)
+ {
+ count = getc(fp);
+ b = getc(fp);
+ g = getc(fp);
+ r = getc(fp);
+ }
+
+ *ptr++ = r;
+ *ptr++ = g;
+ *ptr++ = b;
+ }
+
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (saturation != 100 || hue != 0)
+ ImageRGBAdjust(out, img->xsize, saturation, hue);
+ }
+ else
+ {
+ if (saturation != 100 || hue != 0)
+ ImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+
+ fclose(fp);
+ free(in);
+ free(out);
+
+ return (0);
+}
+
+
+/*
+ * 'read_short()' - Read a 16-bit integer.
+ */
+
+static short /* O - Value from file */
+read_short(FILE *fp) /* I - File to read from */
+{
+ int ch; /* Character from file */
+
+
+ ch = getc(fp);
+ return ((ch << 8) | getc(fp));
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-png.c b/filter/image-png.c
new file mode 100644
index 000000000..3470317fc
--- /dev/null
+++ b/filter/image-png.c
@@ -0,0 +1,252 @@
+/*
+ * "$Id$"
+ *
+ * PNG image routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageReadPNG() - Read a PNG image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+
+#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
+#include <png.h> /* Portable Network Graphics (PNG) definitions */
+
+
+/*
+ * 'ImageReadPNG()' - Read a PNG image file.
+ */
+
+int /* O - Read status */
+ImageReadPNG(image_t *img, /* IO - Image */
+ FILE *fp, /* I - Image file */
+ int primary, /* I - Primary choice for colorspace */
+ int secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int y; /* Looping var */
+ png_structp pp; /* PNG read pointer */
+ png_infop info; /* PNG info pointers */
+ int bpp; /* Bytes per pixel */
+ int pass, /* Current pass */
+ passes; /* Number of passes required */
+ ib_t *in, /* Input pixels */
+ *inptr, /* Pointer into pixels */
+ *out; /* Output pixels */
+ png_color_16 bg; /* Background color */
+
+ /*
+ * Setup the PNG data structures...
+ */
+
+ pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ info = png_create_info_struct(pp);
+
+ /*
+ * Initialize the PNG read "engine"...
+ */
+
+ png_init_io(pp, fp);
+
+ /*
+ * Get the image dimensions and load the output image...
+ */
+
+ png_read_info(pp, info);
+
+ if (info->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_set_expand(pp);
+
+ if (info->color_type == PNG_COLOR_TYPE_GRAY ||
+ info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ img->colorspace = secondary;
+ else
+ img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_RGB : primary;
+
+ img->xsize = info->width;
+ img->ysize = info->height;
+
+ if (info->valid & PNG_INFO_pHYs &&
+ info->phys_unit_type == PNG_RESOLUTION_METER)
+ {
+ img->xppi = (int)((float)info->x_pixels_per_unit * 0.0254);
+ img->yppi = (int)((float)info->y_pixels_per_unit * 0.0254);
+ }
+
+ ImageSetMaxTiles(img, 0);
+
+ if (info->bit_depth < 8)
+ {
+ png_set_packing(pp);
+
+ if (info->valid & PNG_INFO_sBIT)
+ png_set_shift(pp, &(info->sig_bit));
+ }
+ else if (info->bit_depth == 16)
+ png_set_strip_16(pp);
+
+ passes = png_set_interlace_handling(pp);
+
+ /*
+ * Handle transparency...
+ */
+
+ if (png_get_valid(pp, info, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(pp);
+
+ bg.red = 65535;
+ bg.green = 65535;
+ bg.blue = 65535;
+
+ png_set_background(pp, &bg, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+ if (passes == 1)
+ {
+ /*
+ * Load one row at a time...
+ */
+
+ if (info->color_type == PNG_COLOR_TYPE_GRAY ||
+ info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ in = malloc(img->xsize);
+ else
+ in = malloc(img->xsize * 3);
+ }
+ else
+ {
+ /*
+ * Interlaced images must be loaded all at once...
+ */
+
+ if (info->color_type == PNG_COLOR_TYPE_GRAY ||
+ info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ in = malloc(img->xsize * img->ysize);
+ else
+ in = malloc(img->xsize * img->ysize * 3);
+ }
+
+ bpp = ImageGetDepth(img);
+ out = malloc(img->xsize * bpp);
+
+ /*
+ * Read the image, interlacing as needed...
+ */
+
+ for (pass = 1; pass <= passes; pass ++)
+ for (inptr = in, y = 0; y < img->ysize; y ++)
+ {
+ png_read_row(pp, (png_bytep)inptr, NULL);
+
+ if (pass == passes)
+ {
+ /*
+ * Output this row...
+ */
+
+ if (info->color_type == PNG_COLOR_TYPE_GRAY ||
+ info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ memcpy(out, inptr, img->xsize);
+ break;
+ case IMAGE_RGB :
+ ImageWhiteToRGB(inptr, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageWhiteToBlack(inptr, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageWhiteToCMY(inptr, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageWhiteToCMYK(inptr, out, img->xsize);
+ break;
+ }
+ }
+ else
+ {
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ ImageRGBAdjust(inptr, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(inptr, out, img->xsize);
+ break;
+ case IMAGE_RGB :
+ memcpy(out, inptr, img->xsize * 3);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(inptr, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(inptr, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(inptr, out, img->xsize);
+ break;
+ }
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+
+ if (passes > 1)
+ {
+ if (info->color_type == PNG_COLOR_TYPE_GRAY ||
+ info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ inptr += img->xsize;
+ else
+ inptr += img->xsize * 3;
+ }
+ }
+
+ png_read_end(pp, info);
+ png_read_destroy(pp, info, NULL);
+
+ fclose(fp);
+ free(in);
+ free(out);
+
+ return (0);
+}
+
+
+#endif /* HAVE_LIBPNG && HAVE_LIBZ */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-pnm.c b/filter/image-pnm.c
new file mode 100644
index 000000000..43c89511f
--- /dev/null
+++ b/filter/image-pnm.c
@@ -0,0 +1,290 @@
+/*
+ * "$Id$"
+ *
+ * Portable Any Map file routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageReadPNM() - Read a PNM image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+#include <ctype.h>
+
+
+/*
+ * 'ImageReadPNM()' - Read a PNM image file.
+ */
+
+int /* O - Read status */
+ImageReadPNM(image_t *img, /* IO - Image */
+ FILE *fp, /* I - Image file */
+ int primary, /* I - Primary choice for colorspace */
+ int secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int x, y; /* Looping vars */
+ int bpp; /* Bytes per pixel */
+ ib_t *in, /* Input pixels */
+ *inptr, /* Current input pixel */
+ *out, /* Output pixels */
+ *outptr, /* Current output pixel */
+ bit; /* Bit in input line */
+ char line[255], /* Input line */
+ *lineptr; /* Pointer in line */
+ int format, /* Format of PNM file */
+ val, /* Pixel value */
+ maxval; /* Maximum pixel value */
+
+
+ /*
+ * Read the file header in the format:
+ *
+ * Pformat
+ * # comment1
+ * # comment2
+ * ...
+ * # commentN
+ * width
+ * height
+ * max sample
+ */
+
+ lineptr = fgets(line, sizeof(line), fp);
+ lineptr ++;
+
+ format = atoi(lineptr);
+ while (isdigit(*lineptr))
+ lineptr ++;
+
+ while (lineptr != NULL && img->xsize == 0)
+ {
+ if (*lineptr == '\0' || *lineptr == '#')
+ lineptr = fgets(line, sizeof(line), fp);
+ else if (isdigit(*lineptr))
+ {
+ img->xsize = atoi(lineptr);
+ while (isdigit(*lineptr))
+ lineptr ++;
+ }
+ else
+ lineptr ++;
+ }
+
+ while (lineptr != NULL && img->ysize == 0)
+ {
+ if (*lineptr == '\0' || *lineptr == '#')
+ lineptr = fgets(line, sizeof(line), fp);
+ else if (isdigit(*lineptr))
+ {
+ img->ysize = atoi(lineptr);
+ while (isdigit(*lineptr))
+ lineptr ++;
+ }
+ else
+ lineptr ++;
+ }
+
+ if (format != 1 && format != 4)
+ {
+ maxval = 0;
+
+ while (lineptr != NULL && maxval == 0)
+ {
+ if (*lineptr == '\0' || *lineptr == '#')
+ lineptr = fgets(line, sizeof(line), fp);
+ else if (isdigit(*lineptr))
+ {
+ maxval = atoi(lineptr);
+ while (isdigit(*lineptr))
+ lineptr ++;
+ }
+ else
+ lineptr ++;
+ }
+ }
+ else
+ maxval = 1;
+
+ if (format == 1 || format == 2 || format == 4 || format == 5)
+ img->colorspace = secondary;
+ else
+ img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_RGB : primary;
+
+ ImageSetMaxTiles(img, 0);
+
+ bpp = ImageGetDepth(img);
+ in = malloc(img->xsize * 3);
+ out = malloc(img->xsize * bpp);
+
+ /*
+ * Read the image file...
+ */
+
+ for (y = 0; y < img->ysize; y ++)
+ {
+ switch (format)
+ {
+ case 1 :
+ case 2 :
+ for (x = img->xsize, inptr = in; x > 0; x --, inptr ++)
+ if (fscanf(fp, "%d", &val) == 1)
+ *inptr = 255 * val / maxval;
+ break;
+
+ case 3 :
+ for (x = img->xsize, inptr = in; x > 0; x --, inptr += 3)
+ {
+ if (fscanf(fp, "%d", &val) == 1)
+ inptr[0] = 255 * val / maxval;
+ if (fscanf(fp, "%d", &val) == 1)
+ inptr[1] = 255 * val / maxval;
+ if (fscanf(fp, "%d", &val) == 1)
+ inptr[2] = 255 * val / maxval;
+ }
+ break;
+
+ case 4 :
+ fread(out, (img->xsize + 7) / 8, 1, fp);
+ for (x = img->xsize, inptr = in, outptr = out, bit = 128;
+ x > 0;
+ x --, inptr ++)
+ {
+ if (*outptr & bit)
+ *inptr = 255;
+ else
+ *inptr = 0;
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ inptr ++;
+ }
+ }
+ break;
+
+ case 5 :
+ fread(in, img->xsize, 1, fp);
+ break;
+
+ case 6 :
+ fread(in, img->xsize, 3, fp);
+ break;
+ }
+
+ switch (format)
+ {
+ case 1 :
+ case 2 :
+ case 4 :
+ case 5 :
+ if (img->colorspace == IMAGE_WHITE)
+ {
+ if (lut)
+ ImageLut(in, img->xsize, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_RGB :
+ ImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ break;
+
+ default :
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ ImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (lut)
+ ImageLut(in, img->xsize * 3, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ break;
+ }
+ }
+
+ free(in);
+ free(out);
+
+ fclose(fp);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-sgi.c b/filter/image-sgi.c
new file mode 100644
index 000000000..67eae8a94
--- /dev/null
+++ b/filter/image-sgi.c
@@ -0,0 +1,269 @@
+/*
+ * "$Id$"
+ *
+ * SGI image file routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageReadSGI() - Read a SGI image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+#include "image-sgi.h"
+
+
+/*
+ * 'ImageReadSGI()' - Read a SGI image file.
+ */
+
+int /* O - Read status */
+ImageReadSGI(image_t *img, /* IO - Image */
+ FILE *fp, /* I - Image file */
+ int primary, /* I - Primary choice for colorspace */
+ int secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int i, y; /* Looping vars */
+ int bpp; /* Bytes per pixel */
+ sgi_t *sgip; /* SGI image file */
+ ib_t *in, /* Input pixels */
+ *inptr, /* Current input pixel */
+ *out; /* Output pixels */
+ unsigned short *rows[4], /* Row pointers for image data */
+ *red,
+ *green,
+ *blue,
+ *gray,
+ *alpha;
+
+
+ /*
+ * Setup the SGI file...
+ */
+
+ sgip = sgiOpenFile(fp, SGI_READ, 0, 0, 0, 0, 0);
+
+ /*
+ * Get the image dimensions and load the output image...
+ */
+
+ if (sgip->zsize < 3)
+ img->colorspace = secondary;
+ else
+ img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_RGB : primary;
+
+ img->xsize = sgip->xsize;
+ img->ysize = sgip->ysize;
+
+ ImageSetMaxTiles(img, 0);
+
+ bpp = ImageGetDepth(img);
+ in = malloc(img->xsize * sgip->zsize);
+ out = malloc(img->xsize * bpp);
+
+ rows[0] = calloc(img->xsize * sgip->zsize, sizeof(unsigned short));
+ for (i = 1; i < sgip->zsize; i ++)
+ rows[i] = rows[0] + i * img->xsize;
+
+ /*
+ * Read the SGI image file...
+ */
+
+ for (y = 0; y < img->ysize; y ++)
+ {
+ for (i = 0; i < sgip->zsize; i ++)
+ sgiGetRow(sgip, rows[i], img->ysize - 1 - y, i);
+
+ switch (sgip->zsize)
+ {
+ case 1 :
+ if (sgip->bpp == 1)
+ for (i = img->xsize - 1, gray = rows[0], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = *gray++;
+ }
+ else
+ for (i = img->xsize - 1, gray = rows[0], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = (*gray++) / 256 + 128;
+ }
+ break;
+ case 2 :
+ if (sgip->bpp == 1)
+ for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = (*gray++) * (*alpha++) / 255;
+ }
+ else
+ for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = ((*gray++) / 256 + 128) * (*alpha++) / 32767;
+ }
+ break;
+ case 3 :
+ if (sgip->bpp == 1)
+ for (i = img->xsize - 1, red = rows[0], green = rows[1],
+ blue = rows[2], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = *red++;
+ *inptr++ = *green++;
+ *inptr++ = *blue++;
+ }
+ else
+ for (i = img->xsize - 1, red = rows[0], green = rows[1],
+ blue = rows[2], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = (*red++) / 256 + 128;
+ *inptr++ = (*green++) / 256 + 128;
+ *inptr++ = (*blue++) / 256 + 128;
+ }
+ break;
+ case 4 :
+ if (sgip->bpp == 1)
+ for (i = img->xsize - 1, red = rows[0], green = rows[1],
+ blue = rows[2], alpha = rows[3], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = (*red++) * (*alpha) / 255;
+ *inptr++ = (*green++) * (*alpha) / 255;
+ *inptr++ = (*blue++) * (*alpha++) / 255;
+ }
+ else
+ for (i = img->xsize - 1, red = rows[0], green = rows[1],
+ blue = rows[2], alpha = rows[3], inptr = in;
+ i >= 0;
+ i --)
+ {
+ *inptr++ = ((*red++) / 256 + 128) * (*alpha) / 32767;
+ *inptr++ = ((*green++) / 256 + 128) * (*alpha) / 32767;
+ *inptr++ = ((*blue++) / 256 + 128) * (*alpha++) / 32767;
+ }
+ break;
+ }
+
+ if (sgip->zsize < 3)
+ {
+ if (img->colorspace == IMAGE_WHITE)
+ {
+ if (lut)
+ ImageLut(in, img->xsize, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_RGB :
+ ImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ else
+ {
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (saturation != 100 || hue != 0)
+ ImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ if (lut)
+ ImageLut(in, img->xsize * 3, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ ImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ }
+
+ free(in);
+ free(out);
+ free(rows[0]);
+
+ sgiClose(sgip);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-sgi.h b/filter/image-sgi.h
new file mode 100644
index 000000000..9eb6b069b
--- /dev/null
+++ b/filter/image-sgi.h
@@ -0,0 +1,96 @@
+/*
+ * "$Id$"
+ *
+ * SGI image file format library definitions for the Common UNIX Printing
+ * System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _SGI_H_
+# define _SGI_H_
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+
+/*
+ * Constants...
+ */
+
+# define SGI_MAGIC 474 /* Magic number in image file */
+
+# define SGI_READ 0 /* Read from an SGI image file */
+# define SGI_WRITE 1 /* Write to an SGI image file */
+
+# define SGI_COMP_NONE 0 /* No compression */
+# define SGI_COMP_RLE 1 /* Run-length encoding */
+# define SGI_COMP_ARLE 2 /* Agressive run-length encoding */
+
+
+/*
+ * Image structure...
+ */
+
+typedef struct
+{
+ FILE *file; /* Image file */
+ int mode, /* File open mode */
+ bpp, /* Bytes per pixel/channel */
+ comp; /* Compression */
+ unsigned short xsize, /* Width in pixels */
+ ysize, /* Height in pixels */
+ zsize; /* Number of channels */
+ long firstrow, /* File offset for first row */
+ nextrow, /* File offset for next row */
+ **table, /* Offset table for compression */
+ **length; /* Length table for compression */
+ unsigned short *arle_row; /* Advanced RLE compression buffer */
+ long arle_offset, /* Advanced RLE buffer offset */
+ arle_length; /* Advanced RLE buffer length */
+} sgi_t;
+
+
+/*
+ * Prototypes...
+ */
+
+extern int sgiClose(sgi_t *sgip);
+extern int sgiGetRow(sgi_t *sgip, unsigned short *row, int y, int z);
+extern sgi_t *sgiOpen(char *filename, int mode, int comp, int bpp,
+ int xsize, int ysize, int zsize);
+extern sgi_t *sgiOpenFile(FILE *file, int mode, int comp, int bpp,
+ int xsize, int ysize, int zsize);
+extern int sgiPutRow(sgi_t *sgip, unsigned short *row, int y, int z);
+
+# ifdef __cplusplus
+}
+# endif
+#endif /* !_SGI_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-sgilib.c b/filter/image-sgilib.c
new file mode 100644
index 000000000..b1d97b6a7
--- /dev/null
+++ b/filter/image-sgilib.c
@@ -0,0 +1,859 @@
+/*
+ * "$Id$"
+ *
+ * SGI image file format library routines for the Common UNIX Printing
+ * System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * sgiClose() - Close an SGI image file.
+ * sgiGetRow() - Get a row of image data from a file.
+ * sgiOpen() - Open an SGI image file for reading or writing.
+ * sgiOpenFile() - Open an SGI image file for reading or writing.
+ * sgiPutRow() - Put a row of image data to a file.
+ * getlong() - Get a 32-bit big-endian integer.
+ * getshort() - Get a 16-bit big-endian integer.
+ * putlong() - Put a 32-bit big-endian integer.
+ * putshort() - Put a 16-bit big-endian integer.
+ * read_rle8() - Read 8-bit RLE data.
+ * read_rle16() - Read 16-bit RLE data.
+ * write_rle8() - Write 8-bit RLE data.
+ * write_rle16() - Write 16-bit RLE data.
+ */
+
+#include "image-sgi.h"
+
+
+/*
+ * Local functions...
+ */
+
+static int getlong(FILE *);
+static int getshort(FILE *);
+static int putlong(long, FILE *);
+static int putshort(unsigned short, FILE *);
+static int read_rle8(FILE *, unsigned short *, int);
+static int read_rle16(FILE *, unsigned short *, int);
+static int write_rle8(FILE *, unsigned short *, int);
+static int write_rle16(FILE *, unsigned short *, int);
+
+
+/*
+ * 'sgiClose()' - Close an SGI image file.
+ */
+
+int
+sgiClose(sgi_t *sgip) /* I - SGI image */
+{
+ int i; /* Return status */
+ long *offset; /* Looping var for offset table */
+
+
+ if (sgip == NULL)
+ return (-1);
+
+ if (sgip->mode == SGI_WRITE && sgip->comp != SGI_COMP_NONE)
+ {
+ /*
+ * Write the scanline offset table to the file...
+ */
+
+ fseek(sgip->file, 512, SEEK_SET);
+
+ for (i = sgip->ysize * sgip->zsize, offset = sgip->table[0];
+ i > 0;
+ i --, offset ++)
+ if (putlong(offset[0], sgip->file) < 0)
+ return (-1);
+
+ for (i = sgip->ysize * sgip->zsize, offset = sgip->length[0];
+ i > 0;
+ i --, offset ++)
+ if (putlong(offset[0], sgip->file) < 0)
+ return (-1);
+ }
+
+ if (sgip->table != NULL)
+ {
+ free(sgip->table[0]);
+ free(sgip->table);
+ }
+
+ if (sgip->length != NULL)
+ {
+ free(sgip->length[0]);
+ free(sgip->length);
+ }
+
+ if (sgip->comp == SGI_COMP_ARLE)
+ free(sgip->arle_row);
+
+ i = fclose(sgip->file);
+ free(sgip);
+
+ return (i);
+}
+
+
+/*
+ * 'sgiGetRow()' - Get a row of image data from a file.
+ */
+
+int
+sgiGetRow(sgi_t *sgip, /* I - SGI image */
+ unsigned short *row, /* O - Row to read */
+ int y, /* I - Line to read */
+ int z) /* I - Channel to read */
+{
+ int x; /* X coordinate */
+ long offset; /* File offset */
+
+
+ if (sgip == NULL ||
+ row == NULL ||
+ y < 0 || y >= sgip->ysize ||
+ z < 0 || z >= sgip->zsize)
+ return (-1);
+
+ switch (sgip->comp)
+ {
+ case SGI_COMP_NONE :
+ /*
+ * Seek to the image row - optimize buffering by only seeking if
+ * necessary...
+ */
+
+ offset = 512 + (y + z * sgip->ysize) * sgip->xsize * sgip->bpp;
+ if (offset != ftell(sgip->file))
+ fseek(sgip->file, offset, SEEK_SET);
+
+ if (sgip->bpp == 1)
+ {
+ for (x = sgip->xsize; x > 0; x --, row ++)
+ *row = getc(sgip->file);
+ }
+ else
+ {
+ for (x = sgip->xsize; x > 0; x --, row ++)
+ *row = getshort(sgip->file);
+ }
+ break;
+
+ case SGI_COMP_RLE :
+ offset = sgip->table[z][y];
+ if (offset != ftell(sgip->file))
+ fseek(sgip->file, offset, SEEK_SET);
+
+ if (sgip->bpp == 1)
+ return (read_rle8(sgip->file, row, sgip->xsize));
+ else
+ return (read_rle16(sgip->file, row, sgip->xsize));
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'sgiOpen()' - Open an SGI image file for reading or writing.
+ */
+
+sgi_t *
+sgiOpen(char *filename, /* I - File to open */
+ int mode, /* I - Open mode (SGI_READ or SGI_WRITE) */
+ int comp, /* I - Type of compression */
+ int bpp, /* I - Bytes per pixel */
+ int xsize, /* I - Width of image in pixels */
+ int ysize, /* I - Height of image in pixels */
+ int zsize) /* I - Number of channels */
+{
+ sgi_t *sgip; /* New SGI image file */
+ FILE *file; /* Image file pointer */
+
+
+ if (mode == SGI_READ)
+ file = fopen(filename, "rb");
+ else
+ file = fopen(filename, "wb+");
+
+ if (file == NULL)
+ return (NULL);
+
+ if ((sgip = sgiOpenFile(file, mode, comp, bpp, xsize, ysize, zsize)) == NULL)
+ fclose(file);
+
+ return (sgip);
+}
+
+
+/*
+ * 'sgiOpenFile()' - Open an SGI image file for reading or writing.
+ */
+
+sgi_t *
+sgiOpenFile(FILE *file, /* I - File to open */
+ int mode, /* I - Open mode (SGI_READ or SGI_WRITE) */
+ int comp, /* I - Type of compression */
+ int bpp, /* I - Bytes per pixel */
+ int xsize, /* I - Width of image in pixels */
+ int ysize, /* I - Height of image in pixels */
+ int zsize) /* I - Number of channels */
+{
+ int i, j; /* Looping var */
+ char name[80]; /* Name of file in image header */
+ short magic; /* Magic number */
+ sgi_t *sgip; /* New image pointer */
+
+
+ if ((sgip = calloc(sizeof(sgi_t), 1)) == NULL)
+ return (NULL);
+
+ sgip->file = file;
+
+ switch (mode)
+ {
+ case SGI_READ :
+ sgip->mode = SGI_READ;
+
+ magic = getshort(sgip->file);
+ if (magic != SGI_MAGIC)
+ {
+ free(sgip);
+ return (NULL);
+ }
+
+ sgip->comp = getc(sgip->file);
+ sgip->bpp = getc(sgip->file);
+ getshort(sgip->file); /* Dimensions */
+ sgip->xsize = getshort(sgip->file);
+ sgip->ysize = getshort(sgip->file);
+ sgip->zsize = getshort(sgip->file);
+ getlong(sgip->file); /* Minimum pixel */
+ getlong(sgip->file); /* Maximum pixel */
+
+ if (sgip->comp)
+ {
+ /*
+ * This file is compressed; read the scanline tables...
+ */
+
+ fseek(sgip->file, 512, SEEK_SET);
+
+ sgip->table = calloc(sgip->zsize, sizeof(long *));
+ sgip->table[0] = calloc(sgip->ysize * sgip->zsize, sizeof(long));
+ for (i = 1; i < sgip->zsize; i ++)
+ sgip->table[i] = sgip->table[0] + i * sgip->ysize;
+
+ for (i = 0; i < sgip->zsize; i ++)
+ for (j = 0; j < sgip->ysize; j ++)
+ sgip->table[i][j] = getlong(sgip->file);
+ }
+ break;
+
+ case SGI_WRITE :
+ if (xsize < 1 ||
+ ysize < 1 ||
+ zsize < 1 ||
+ bpp < 1 || bpp > 2 ||
+ comp < SGI_COMP_NONE || comp > SGI_COMP_ARLE)
+ {
+ free(sgip);
+ return (NULL);
+ }
+
+ sgip->mode = SGI_WRITE;
+
+ putshort(SGI_MAGIC, sgip->file);
+ putc((sgip->comp = comp) != 0, sgip->file);
+ putc(sgip->bpp = bpp, sgip->file);
+ putshort(3, sgip->file); /* Dimensions */
+ putshort(sgip->xsize = xsize, sgip->file);
+ putshort(sgip->ysize = ysize, sgip->file);
+ putshort(sgip->zsize = zsize, sgip->file);
+ if (bpp == 1)
+ {
+ putlong(0, sgip->file); /* Minimum pixel */
+ putlong(255, sgip->file); /* Maximum pixel */
+ }
+ else
+ {
+ putlong(-32768, sgip->file); /* Minimum pixel */
+ putlong(32767, sgip->file); /* Maximum pixel */
+ }
+ putlong(0, sgip->file); /* Reserved */
+
+ memset(name, 0, sizeof(name));
+ fwrite(name, sizeof(name), 1, sgip->file);
+
+ for (i = 0; i < 102; i ++)
+ putlong(0, sgip->file);
+
+ switch (comp)
+ {
+ case SGI_COMP_NONE : /* No compression */
+ /*
+ * This file is uncompressed. To avoid problems with sparse files,
+ * we need to write blank pixels for the entire image...
+ */
+
+ if (bpp == 1)
+ {
+ for (i = xsize * ysize * zsize; i > 0; i --)
+ putc(0, sgip->file);
+ }
+ else
+ {
+ for (i = xsize * ysize * zsize; i > 0; i --)
+ putshort(0, sgip->file);
+ }
+ break;
+
+ case SGI_COMP_ARLE : /* Aggressive RLE */
+ sgip->arle_row = calloc(xsize, sizeof(unsigned short));
+ sgip->arle_offset = 0;
+
+ case SGI_COMP_RLE : /* Run-Length Encoding */
+ /*
+ * This file is compressed; write the (blank) scanline tables...
+ */
+
+ for (i = 2 * ysize * zsize; i > 0; i --)
+ putlong(0, sgip->file);
+
+ sgip->firstrow = ftell(sgip->file);
+ sgip->nextrow = ftell(sgip->file);
+ sgip->table = calloc(sgip->zsize, sizeof(long *));
+ sgip->table[0] = calloc(sgip->ysize * sgip->zsize, sizeof(long));
+ for (i = 1; i < sgip->zsize; i ++)
+ sgip->table[i] = sgip->table[0] + i * sgip->ysize;
+ sgip->length = calloc(sgip->zsize, sizeof(long *));
+ sgip->length[0] = calloc(sgip->ysize * sgip->zsize, sizeof(long));
+ for (i = 1; i < sgip->zsize; i ++)
+ sgip->length[i] = sgip->length[0] + i * sgip->ysize;
+ break;
+ }
+ break;
+
+ default :
+ free(sgip);
+ return (NULL);
+ }
+
+ return (sgip);
+}
+
+
+/*
+ * 'sgiPutRow()' - Put a row of image data to a file.
+ */
+
+int
+sgiPutRow(sgi_t *sgip, /* I - SGI image */
+ unsigned short *row, /* I - Row to write */
+ int y, /* I - Line to write */
+ int z) /* I - Channel to write */
+{
+ int x; /* X coordinate */
+ long offset; /* File offset */
+
+
+ if (sgip == NULL ||
+ row == NULL ||
+ y < 0 || y >= sgip->ysize ||
+ z < 0 || z >= sgip->zsize)
+ return (-1);
+
+ switch (sgip->comp)
+ {
+ case SGI_COMP_NONE :
+ /*
+ * Seek to the image row - optimize buffering by only seeking if
+ * necessary...
+ */
+
+ offset = 512 + (y + z * sgip->ysize) * sgip->xsize * sgip->bpp;
+ if (offset != ftell(sgip->file))
+ fseek(sgip->file, offset, SEEK_SET);
+
+ if (sgip->bpp == 1)
+ {
+ for (x = sgip->xsize; x > 0; x --, row ++)
+ putc(*row, sgip->file);
+ }
+ else
+ {
+ for (x = sgip->xsize; x > 0; x --, row ++)
+ putshort(*row, sgip->file);
+ }
+ break;
+
+ case SGI_COMP_ARLE :
+ if (sgip->table[z][y] != 0)
+ return (-1);
+
+ /*
+ * First check the last row written...
+ */
+
+ if (sgip->arle_offset > 0)
+ {
+ for (x = 0; x < sgip->xsize; x ++)
+ if (row[x] != sgip->arle_row[x])
+ break;
+
+ if (x == sgip->xsize)
+ {
+ sgip->table[z][y] = sgip->arle_offset;
+ sgip->length[z][y] = sgip->arle_length;
+ return (0);
+ }
+ }
+
+ /*
+ * If that didn't match, search all the previous rows...
+ */
+
+ fseek(sgip->file, sgip->firstrow, SEEK_SET);
+
+ if (sgip->bpp == 1)
+ {
+ for (;;)
+ {
+ sgip->arle_offset = ftell(sgip->file);
+ if ((sgip->arle_length = read_rle8(sgip->file, sgip->arle_row, sgip->xsize)) < 0)
+ {
+ x = 0;
+ break;
+ }
+
+ if (memcmp(row, sgip->arle_row, sgip->xsize * sizeof(unsigned short)) == 0)
+ {
+ x = sgip->xsize;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ sgip->arle_offset = ftell(sgip->file);
+ if ((sgip->arle_length = read_rle16(sgip->file, sgip->arle_row, sgip->xsize)) < 0)
+ {
+ x = 0;
+ break;
+ }
+
+ if (memcmp(row, sgip->arle_row, sgip->xsize * sizeof(unsigned short)) == 0)
+ {
+ x = sgip->xsize;
+ break;
+ }
+ }
+ }
+
+ if (x == sgip->xsize)
+ {
+ sgip->table[z][y] = sgip->arle_offset;
+ sgip->length[z][y] = sgip->arle_length;
+ return (0);
+ }
+ else
+ fseek(sgip->file, 0, SEEK_END); /* Clear EOF */
+
+ case SGI_COMP_RLE :
+ if (sgip->table[z][y] != 0)
+ return (-1);
+
+ offset = sgip->table[z][y] = sgip->nextrow;
+
+ if (offset != ftell(sgip->file))
+ fseek(sgip->file, offset, SEEK_SET);
+
+ if (sgip->bpp == 1)
+ x = write_rle8(sgip->file, row, sgip->xsize);
+ else
+ x = write_rle16(sgip->file, row, sgip->xsize);
+
+ if (sgip->comp == SGI_COMP_ARLE)
+ {
+ sgip->arle_offset = offset;
+ sgip->arle_length = x;
+ memcpy(sgip->arle_row, row, sgip->xsize * sizeof(unsigned short));
+ }
+
+ sgip->nextrow = ftell(sgip->file);
+ sgip->length[z][y] = x;
+
+ return (x);
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'getlong()' - Get a 32-bit big-endian integer.
+ */
+
+static int
+getlong(FILE *fp) /* I - File to read from */
+{
+ unsigned char b[4];
+
+
+ fread(b, 4, 1, fp);
+ return ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]);
+}
+
+
+/*
+ * 'getshort()' - Get a 16-bit big-endian integer.
+ */
+
+static int
+getshort(FILE *fp) /* I - File to read from */
+{
+ unsigned char b[2];
+
+
+ fread(b, 2, 1, fp);
+ return ((b[0] << 8) | b[1]);
+}
+
+
+/*
+ * 'putlong()' - Put a 32-bit big-endian integer.
+ */
+
+static int
+putlong(long n, /* I - Long to write */
+ FILE *fp) /* I - File to write to */
+{
+ if (putc(n >> 24, fp) == EOF)
+ return (EOF);
+ if (putc(n >> 16, fp) == EOF)
+ return (EOF);
+ if (putc(n >> 8, fp) == EOF)
+ return (EOF);
+ if (putc(n, fp) == EOF)
+ return (EOF);
+ else
+ return (0);
+}
+
+
+/*
+ * 'putshort()' - Put a 16-bit big-endian integer.
+ */
+
+static int
+putshort(unsigned short n, /* I - Short to write */
+ FILE *fp) /* I - File to write to */
+{
+ if (putc(n >> 8, fp) == EOF)
+ return (EOF);
+ if (putc(n, fp) == EOF)
+ return (EOF);
+ else
+ return (0);
+}
+
+
+/*
+ * 'read_rle8()' - Read 8-bit RLE data.
+ */
+
+static int
+read_rle8(FILE *fp, /* I - File to read from */
+ unsigned short *row, /* O - Data */
+ int xsize) /* I - Width of data in pixels */
+{
+ int i, /* Looping var */
+ ch, /* Current character */
+ count, /* RLE count */
+ length; /* Number of bytes read... */
+
+
+ length = 0;
+
+ while (xsize > 0)
+ {
+ if ((ch = getc(fp)) == EOF)
+ return (-1);
+ length ++;
+
+ count = ch & 127;
+ if (count == 0)
+ break;
+
+ if (ch & 128)
+ {
+ for (i = 0; i < count; i ++, row ++, xsize --, length ++)
+ *row = getc(fp);
+ }
+ else
+ {
+ ch = getc(fp);
+ length ++;
+ for (i = 0; i < count; i ++, row ++, xsize --)
+ *row = ch;
+ }
+ }
+
+ return (xsize > 0 ? -1 : length);
+}
+
+
+/*
+ * 'read_rle16()' - Read 16-bit RLE data.
+ */
+
+static int
+read_rle16(FILE *fp, /* I - File to read from */
+ unsigned short *row, /* O - Data */
+ int xsize)/* I - Width of data in pixels */
+{
+ int i, /* Looping var */
+ ch, /* Current character */
+ count, /* RLE count */
+ length; /* Number of bytes read... */
+
+
+ length = 0;
+
+ while (xsize > 0)
+ {
+ if ((ch = getshort(fp)) == EOF)
+ return (-1);
+ length ++;
+
+ count = ch & 127;
+ if (count == 0)
+ break;
+
+ if (ch & 128)
+ {
+ for (i = 0; i < count; i ++, row ++, xsize --, length ++)
+ *row = getshort(fp);
+ }
+ else
+ {
+ ch = getshort(fp);
+ length ++;
+ for (i = 0; i < count; i ++, row ++, xsize --)
+ *row = ch;
+ }
+ }
+
+ return (xsize > 0 ? -1 : length * 2);
+}
+
+
+/*
+ * 'write_rle8()' - Write 8-bit RLE data.
+ */
+
+static int
+write_rle8(FILE *fp, /* I - File to write to */
+ unsigned short *row, /* I - Data */
+ int xsize)/* I - Width of data in pixels */
+{
+ int length,
+ count,
+ i,
+ x;
+ unsigned short *start,
+ repeat;
+
+
+ for (x = xsize, length = 0; x > 0;)
+ {
+ start = row;
+ row += 2;
+ x -= 2;
+
+ while (x > 0 && (row[-2] != row[-1] || row[-1] != row[0]))
+ {
+ row ++;
+ x --;
+ }
+
+ row -= 2;
+ x += 2;
+
+ count = row - start;
+ while (count > 0)
+ {
+ i = count > 126 ? 126 : count;
+ count -= i;
+
+ if (putc(128 | i, fp) == EOF)
+ return (-1);
+ length ++;
+
+ while (i > 0)
+ {
+ if (putc(*start, fp) == EOF)
+ return (-1);
+ start ++;
+ i --;
+ length ++;
+ }
+ }
+
+ if (x <= 0)
+ break;
+
+ start = row;
+ repeat = row[0];
+
+ row ++;
+ x --;
+
+ while (x > 0 && *row == repeat)
+ {
+ row ++;
+ x --;
+ }
+
+ count = row - start;
+ while (count > 0)
+ {
+ i = count > 126 ? 126 : count;
+ count -= i;
+
+ if (putc(i, fp) == EOF)
+ return (-1);
+ length ++;
+
+ if (putc(repeat, fp) == EOF)
+ return (-1);
+ length ++;
+ }
+ }
+
+ length ++;
+
+ if (putc(0, fp) == EOF)
+ return (-1);
+ else
+ return (length);
+}
+
+
+/*
+ * 'write_rle16()' - Write 16-bit RLE data.
+ */
+
+static int
+write_rle16(FILE *fp, /* I - File to write to */
+ unsigned short *row, /* I - Data */
+ int xsize)/* I - Width of data in pixels */
+{
+ int length,
+ count,
+ i,
+ x;
+ unsigned short *start,
+ repeat;
+
+
+ for (x = xsize, length = 0; x > 0;)
+ {
+ start = row;
+ row += 2;
+ x -= 2;
+
+ while (x > 0 && (row[-2] != row[-1] || row[-1] != row[0]))
+ {
+ row ++;
+ x --;
+ }
+
+ row -= 2;
+ x += 2;
+
+ count = row - start;
+ while (count > 0)
+ {
+ i = count > 126 ? 126 : count;
+ count -= i;
+
+ if (putshort(128 | i, fp) == EOF)
+ return (-1);
+ length ++;
+
+ while (i > 0)
+ {
+ if (putshort(*start, fp) == EOF)
+ return (-1);
+ start ++;
+ i --;
+ length ++;
+ }
+ }
+
+ if (x <= 0)
+ break;
+
+ start = row;
+ repeat = row[0];
+
+ row ++;
+ x --;
+
+ while (x > 0 && *row == repeat)
+ {
+ row ++;
+ x --;
+ }
+
+ count = row - start;
+ while (count > 0)
+ {
+ i = count > 126 ? 126 : count;
+ count -= i;
+
+ if (putshort(i, fp) == EOF)
+ return (-1);
+ length ++;
+
+ if (putshort(repeat, fp) == EOF)
+ return (-1);
+ length ++;
+ }
+ }
+
+ length ++;
+
+ if (putshort(0, fp) == EOF)
+ return (-1);
+ else
+ return (2 * length);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-sun.c b/filter/image-sun.c
new file mode 100644
index 000000000..a4eaf869c
--- /dev/null
+++ b/filter/image-sun.c
@@ -0,0 +1,379 @@
+/*
+ * "$Id$"
+ *
+ * Sun Raster image file routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageReadSunRaster() - Read a SunRaster image file.
+ * read_unsigned() - Read a 32-bit unsigned integer.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+
+
+#define RAS_MAGIC 0x59a66a95
+
+ /* Sun supported ras_type's */
+#define RT_OLD 0 /* Raw pixrect image in 68000 byte order */
+#define RT_STANDARD 1 /* Raw pixrect image in 68000 byte order */
+#define RT_BYTE_ENCODED 2 /* Run-length compression of bytes */
+#define RT_FORMAT_RGB 3 /* XRGB or RGB instead of XBGR or BGR */
+#define RT_EXPERIMENTAL 0xffff /* Reserved for testing */
+
+ /* Sun registered ras_maptype's */
+#define RMT_RAW 2
+ /* Sun supported ras_maptype's */
+#define RMT_NONE 0 /* ras_maplength is expected to be 0 */
+#define RMT_EQUAL_RGB 1 /* red[ras_maplength/3],green[],blue[] */
+
+#define RAS_RLE 0x80
+
+/*
+ * NOTES:
+ * Each line of the image is rounded out to a multiple of 16 bits.
+ * This corresponds to the rounding convention used by the memory pixrect
+ * package (/usr/include/pixrect/memvar.h) of the SunWindows system.
+ * The ras_encoding field (always set to 0 by Sun's supported software)
+ * was renamed to ras_length in release 2.0. As a result, rasterfiles
+ * of type 0 generated by the old software claim to have 0 length; for
+ * compatibility, code reading rasterfiles must be prepared to compute the
+ * true length from the width, height, and depth fields.
+ */
+
+/*
+ * Local functions...
+ */
+
+static unsigned read_unsigned(FILE *fp);
+
+
+/*
+ * 'ImageReadSunRaster()' - Read a SunRaster image file.
+ */
+
+int /* O - Read status */
+ImageReadSunRaster(image_t *img, /* IO - Image */
+ FILE *fp, /* I - Image file */
+ int primary, /* I - Primary choice for colorspace */
+ int secondary,/* I - Secondary choice for colorspace */
+ int saturation,/* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ int i, x, y,
+ bpp, /* Bytes per pixel */
+ scanwidth,
+ run_count,
+ run_value;
+ ib_t *in,
+ *out,
+ *scanline,
+ *scanptr,
+ *p,
+ bit;
+ unsigned ras_depth, /* depth (1, 8, or 24 bits) of pixel */
+ ras_type, /* type of file; see RT_* below */
+ ras_maplength; /* length (bytes) of following map */
+ unsigned char cmap[3][256]; /* colormap */
+
+
+ /*
+ * Read the header; we already know that this is a raster file (ImageOpen
+ * checks this) so we don't need to check the magic number again.
+ */
+
+ read_unsigned(fp); /* Skip magic */
+ img->xsize = read_unsigned(fp);
+ img->ysize = read_unsigned(fp);
+ ras_depth = read_unsigned(fp);
+ /* ras_length */read_unsigned(fp);
+ ras_type = read_unsigned(fp);
+ /* ras_maptype*/read_unsigned(fp);
+ ras_maplength = read_unsigned(fp);
+
+ if (ras_maplength > 0)
+ {
+ fread(cmap[0], 1, ras_maplength / 3, fp);
+ fread(cmap[1], 1, ras_maplength / 3, fp);
+ fread(cmap[2], 1, ras_maplength / 3, fp);
+ }
+
+ /*
+ * Compute the width of each line and allocate memory as needed...
+ */
+
+ scanwidth = (img->xsize * ras_depth + 7) / 8;
+ if (scanwidth & 1)
+ scanwidth ++;
+
+ if (ras_depth < 24 && ras_maplength == 0)
+ {
+ img->colorspace = secondary;
+ in = malloc(img->xsize + 1);
+ }
+ else
+ {
+ img->colorspace = (primary == IMAGE_RGB_CMYK) ? IMAGE_RGB : primary;
+ in = malloc(img->xsize * 3 + 1);
+ }
+
+ bpp = ImageGetDepth(img);
+ out = malloc(img->xsize * bpp);
+ scanline = malloc(scanwidth);
+ run_count = 0;
+ run_value = 0;
+
+ for (y = 0; y < img->ysize; y ++)
+ {
+ if (ras_depth != 8 || ras_maplength > 0)
+ p = scanline;
+ else
+ p = in;
+
+ if (ras_type != RT_BYTE_ENCODED)
+ fread(p, scanwidth, 1, fp);
+ else
+ {
+ for (i = scanwidth; i > 0; i --, p ++)
+ {
+ if (run_count > 0)
+ {
+ *p = run_value;
+ run_count --;
+ }
+ else
+ {
+ run_value = getc(fp);
+
+ if (run_value == RAS_RLE)
+ {
+ run_count = getc(fp);
+ if (run_count == 0)
+ *p = RAS_RLE;
+ else
+ run_value = *p = getc(fp);
+ }
+ else
+ *p = run_value;
+ }
+ }
+ }
+
+ if (ras_depth == 1 && ras_maplength == 0)
+ {
+ /*
+ * 1-bit B&W image...
+ */
+
+ for (x = img->xsize, bit = 128, scanptr = scanline, p = in;
+ x > 0;
+ x --, p ++)
+ {
+ if (*scanptr & bit)
+ *p = 255;
+ else
+ *p = 0;
+
+ if (bit > 1)
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ else
+ bit >>= 1;
+ }
+ }
+ else if (ras_depth == 1)
+ {
+ /*
+ * 1-bit colormapped image...
+ */
+
+ for (x = img->xsize, bit = 128, scanptr = scanline, p = in;
+ x > 0;
+ x --)
+ {
+ if (*scanptr & bit)
+ {
+ *p++ = cmap[0][1];
+ *p++ = cmap[1][1];
+ *p++ = cmap[2][1];
+ }
+ else
+ {
+ *p++ = cmap[0][0];
+ *p++ = cmap[1][0];
+ *p++ = cmap[2][0];
+ }
+
+ if (bit > 1)
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ else
+ bit >>= 1;
+ }
+ }
+ else if (ras_depth == 8 && ras_maplength > 0)
+ {
+ /*
+ * 8-bit colormapped image.
+ */
+
+ for (x = img->xsize, scanptr = scanline, p = in;
+ x > 0;
+ x --)
+ {
+ *p++ = cmap[0][*scanptr];
+ *p++ = cmap[1][*scanptr];
+ *p++ = cmap[2][*scanptr++];
+ }
+ }
+ else if (ras_depth == 24 && ras_type != RT_FORMAT_RGB)
+ {
+ /*
+ * Convert BGR to RGB...
+ */
+
+ for (x = img->xsize, scanptr = scanline, p = in;
+ x > 0;
+ x --, scanptr += 3)
+ {
+ *p++ = scanptr[2];
+ *p++ = scanptr[1];
+ *p++ = scanptr[0];
+ }
+ }
+
+ if (bpp == 1)
+ {
+ if (img->colorspace == IMAGE_WHITE)
+ {
+ if (lut)
+ ImageLut(in, img->xsize, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_RGB :
+ ImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ else
+ {
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (saturation != 100 || hue != 0)
+ ImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ if (lut)
+ ImageLut(in, img->xsize * 3, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ ImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ }
+
+ free(scanline);
+ free(in);
+ free(out);
+
+ fclose(fp);
+
+ return (0);
+}
+
+
+/*
+ * 'read_unsigned()' - Read a 32-bit unsigned integer.
+ */
+
+static unsigned /* O - Integer from file */
+read_unsigned(FILE *fp) /* I - File to read from */
+{
+ unsigned v; /* Integer from file */
+
+
+ v = getc(fp);
+ v = (v << 8) | getc(fp);
+ v = (v << 8) | getc(fp);
+ v = (v << 8) | getc(fp);
+
+ return (v);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-tiff.c b/filter/image-tiff.c
new file mode 100644
index 000000000..1e275d61c
--- /dev/null
+++ b/filter/image-tiff.c
@@ -0,0 +1,1720 @@
+/*
+ * "$Id$"
+ *
+ * TIFF file routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageReadTIFF() - Read a TIFF image file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+
+#ifdef HAVE_LIBTIFF
+# include <tiff.h> /* TIFF image definitions */
+# include <tiffio.h>
+# include <unistd.h>
+
+
+/*
+ * 'ImageReadTIFF()' - Read a TIFF image file.
+ */
+
+int /* O - Read status */
+ImageReadTIFF(image_t *img, /* IO - Image */
+ FILE *fp, /* I - Image file */
+ int primary, /* I - Primary choice for colorspace */
+ int secondary, /* I - Secondary choice for colorspace */
+ int saturation, /* I - Color saturation (%) */
+ int hue, /* I - Color hue (degrees) */
+ const ib_t *lut) /* I - Lookup table for gamma/brightness */
+{
+ TIFF *tif; /* TIFF file */
+ uint32 width, height; /* Size of image */
+ uint16 photometric, /* Colorspace */
+ compression, /* Type of compression */
+ orientation, /* Orientation */
+ resunit, /* Units for resolution */
+ samples, /* Number of samples/pixel */
+ bits, /* Number of bits/pixel */
+ inkset, /* Ink set for color separations */
+ numinks; /* Number of inks in set */
+ float xres, /* Horizontal resolution */
+ yres; /* Vertical resolution */
+ uint16 *redcmap, /* Red colormap information */
+ *greencmap, /* Green colormap information */
+ *bluecmap; /* Blue colormap information */
+ int c, /* Color index */
+ num_colors, /* Number of colors */
+ bpp, /* Bytes per pixel */
+ x, y, /* Current x & y */
+ row, /* Current row in image */
+ xstart, ystart, /* Starting x & y */
+ xdir, ydir, /* X & y direction */
+ xcount, ycount, /* X & Y counters */
+ pstep, /* Pixel step (= bpp or -2 * bpp) */
+ scanwidth, /* Width of scanline */
+ r, g, b, k, /* Red, green, blue, and black values */
+ alpha; /* Image includes alpha? */
+ ib_t *in, /* Input buffer */
+ *out, /* Output buffer */
+ *p, /* Pointer into buffer */
+ *scanline, /* Scanline buffer */
+ *scanptr, /* Pointer into scanline buffer */
+ bit, /* Current bit */
+ pixel, /* Current pixel */
+ zero, /* Zero value (bitmaps) */
+ one; /* One value (bitmaps) */
+
+
+ /*
+ * Open the TIFF file and get the required parameters...
+ */
+
+ lseek(fileno(fp), 0, SEEK_SET); /* Work around "feature" in some stdio's */
+
+ if ((tif = TIFFFdOpen(fileno(fp), "", "r")) == NULL)
+ {
+ fputs("ERROR: TIFFFdOpen() failed!\n", stderr);
+ fclose(fp);
+ return (-1);
+ }
+
+ if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width))
+ {
+ fputs("ERROR: No image width tag in the file!\n", stderr);
+ TIFFClose(tif);
+ fclose(fp);
+ return (-1);
+ }
+
+ if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))
+ {
+ fputs("ERROR: No image height tag in the file!\n", stderr);
+ TIFFClose(tif);
+ fclose(fp);
+ return (-1);
+ }
+
+ if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric))
+ {
+ fputs("ERROR: No photometric tag in the file!\n", stderr);
+ TIFFClose(tif);
+ fclose(fp);
+ return (-1);
+ }
+
+ if (!TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression))
+ {
+ fputs("ERROR: No compression tag in the file!\n", stderr);
+ TIFFClose(tif);
+ fclose(fp);
+ return (-1);
+ }
+
+ if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samples))
+ samples = 1;
+
+ if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bits))
+ bits = 1;
+
+ /*
+ * Get the image orientation...
+ */
+
+ if (!TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation))
+ orientation = 0;
+
+ /*
+ * Get the image resolution...
+ */
+
+ if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) &&
+ TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) &&
+ TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resunit))
+ {
+ if (resunit == RESUNIT_INCH)
+ {
+ img->xppi = xres;
+ img->yppi = yres;
+ }
+ else if (resunit == RESUNIT_CENTIMETER)
+ {
+ img->xppi = xres * 2.54;
+ img->yppi = yres * 2.54;
+ }
+ else
+ {
+ img->xppi = 128;
+ img->yppi = 128;
+ }
+
+ fprintf(stderr, "DEBUG: TIFF resolution = %fx%f, units=%d\n",
+ xres, yres, resunit);
+ fprintf(stderr, "DEBUG: Stored resolution = %dx%d PPI\n",
+ img->xppi, img->yppi);
+ }
+
+ /*
+ * See if the image has an alpha channel...
+ */
+
+ if (samples == 2 || (samples == 4 && photometric == PHOTOMETRIC_RGB))
+ alpha = 1;
+ else
+ alpha = 0;
+
+ /*
+ * Setup the image size and colorspace...
+ */
+
+ img->xsize = width;
+ img->ysize = height;
+ if (photometric == PHOTOMETRIC_MINISBLACK ||
+ photometric == PHOTOMETRIC_MINISWHITE)
+ img->colorspace = secondary;
+ else if (photometric == PHOTOMETRIC_SEPARATED && primary == IMAGE_RGB_CMYK)
+ img->colorspace = IMAGE_CMYK;
+ else if (primary == IMAGE_RGB_CMYK)
+ img->colorspace = IMAGE_RGB;
+ else
+ img->colorspace = primary;
+
+ fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace);
+
+ bpp = ImageGetDepth(img);
+
+ ImageSetMaxTiles(img, 0);
+
+ /*
+ * Set the X & Y start and direction according to the image orientation...
+ */
+
+ switch (orientation)
+ {
+ case ORIENTATION_TOPRIGHT :
+ fputs("DEBUG: orientation = top-right\n", stderr);
+ break;
+ case ORIENTATION_RIGHTTOP :
+ fputs("DEBUG: orientation = right-top\n", stderr);
+ break;
+ default :
+ case ORIENTATION_TOPLEFT :
+ fputs("DEBUG: orientation = top-left\n", stderr);
+ break;
+ case ORIENTATION_LEFTTOP :
+ fputs("DEBUG: orientation = left-top\n", stderr);
+ break;
+ case ORIENTATION_BOTLEFT :
+ fputs("DEBUG: orientation = bottom-left\n", stderr);
+ break;
+ case ORIENTATION_LEFTBOT :
+ fputs("DEBUG: orientation = left-bottom\n", stderr);
+ break;
+ case ORIENTATION_BOTRIGHT :
+ fputs("DEBUG: orientation = bottom-right\n", stderr);
+ break;
+ case ORIENTATION_RIGHTBOT :
+ fputs("DEBUG: orientation = right-bottom\n", stderr);
+ break;
+ }
+
+ switch (orientation)
+ {
+ case ORIENTATION_TOPRIGHT :
+ case ORIENTATION_RIGHTTOP :
+ xstart = img->xsize - 1;
+ xdir = -1;
+ ystart = 0;
+ ydir = 1;
+ break;
+ default :
+ case ORIENTATION_TOPLEFT :
+ case ORIENTATION_LEFTTOP :
+ xstart = 0;
+ xdir = 1;
+ ystart = 0;
+ ydir = 1;
+ break;
+ case ORIENTATION_BOTLEFT :
+ case ORIENTATION_LEFTBOT :
+ xstart = 0;
+ xdir = 1;
+ ystart = img->ysize - 1;
+ ydir = -1;
+ break;
+ case ORIENTATION_BOTRIGHT :
+ case ORIENTATION_RIGHTBOT :
+ xstart = img->xsize - 1;
+ xdir = -1;
+ ystart = img->ysize - 1;
+ ydir = -1;
+ break;
+ }
+
+ /*
+ * Allocate a scanline buffer...
+ */
+
+ scanwidth = TIFFScanlineSize(tif);
+ scanline = _TIFFmalloc(scanwidth);
+
+ /*
+ * Allocate input and output buffers...
+ */
+
+ if (orientation < ORIENTATION_LEFTTOP)
+ {
+ if (samples > 1 || photometric == PHOTOMETRIC_PALETTE)
+ pstep = xdir * 3;
+ else
+ pstep = xdir;
+
+ in = malloc(img->xsize * 3 + 3);
+ out = malloc(img->xsize * bpp);
+ }
+ else
+ {
+ if (samples > 1 || photometric == PHOTOMETRIC_PALETTE)
+ pstep = ydir * 3;
+ else
+ pstep = ydir;
+
+ in = malloc(img->ysize * 3 + 3);
+ out = malloc(img->ysize * bpp);
+ }
+
+ /*
+ * Read the image. This is greatly complicated by the fact that TIFF
+ * supports literally hundreds of different colorspaces and orientations,
+ * each which must be handled separately...
+ */
+
+ fprintf(stderr, "DEBUG: photometric = %d\n", photometric);
+ fprintf(stderr, "DEBUG: compression = %d\n", compression);
+
+ switch (photometric)
+ {
+ case PHOTOMETRIC_MINISWHITE :
+ case PHOTOMETRIC_MINISBLACK :
+ if (photometric == PHOTOMETRIC_MINISWHITE)
+ {
+ zero = 255;
+ one = 0;
+ }
+ else
+ {
+ zero = 0;
+ one = 255;
+ }
+
+ if (orientation < ORIENTATION_LEFTTOP)
+ {
+ /*
+ * Row major order...
+ */
+
+ for (y = ystart, ycount = img->ysize, row = 0;
+ ycount > 0;
+ ycount --, y += ydir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 128;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (*scanptr & bit)
+ *p = one;
+ else
+ *p = zero;
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 0xc0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ pixel = *scanptr & bit;
+ while (pixel > 3)
+ pixel >>= 2;
+ *p = (255 * pixel / 3) ^ zero;
+
+ if (bit > 3)
+ bit >>= 2;
+ else
+ {
+ bit = 0xc0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 0xf0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (bit == 0xf0)
+ {
+ *p = (255 * ((*scanptr & 0xf0) >> 4) / 15) ^ zero;
+ bit = 0x0f;
+ }
+ else
+ {
+ *p = (255 * (*scanptr & 0x0f) / 15) ^ zero;
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (xdir < 0 || zero || alpha)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ if (alpha)
+ {
+ if (zero)
+ {
+ for (xcount = img->xsize, p = in + xstart, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 2)
+ *p = (scanptr[1] * (255 - scanptr[0]) +
+ (255 - scanptr[1]) * 255) / 255;
+ }
+ else
+ {
+ for (xcount = img->xsize, p = in + xstart, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 2)
+ *p = (scanptr[1] * scanptr[0] +
+ (255 - scanptr[1]) * 255) / 255;
+ }
+ }
+ else
+ {
+ if (zero)
+ {
+ for (xcount = img->xsize, p = in + xstart, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr ++)
+ *p = 255 - *scanptr;
+ }
+ else
+ {
+ for (xcount = img->xsize, p = in + xstart, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr ++)
+ *p = *scanptr;
+ }
+ }
+ }
+ else
+ TIFFReadScanline(tif, in, row, 0);
+
+ if (img->colorspace == IMAGE_WHITE)
+ {
+ if (lut)
+ ImageLut(in, img->xsize, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_RGB :
+ ImageWhiteToRGB(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageWhiteToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageWhiteToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageWhiteToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Column major order...
+ */
+
+ for (x = xstart, xcount = img->xsize, row = 0;
+ xcount > 0;
+ xcount --, x += xdir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 128;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ if (*scanptr & bit)
+ *p = one;
+ else
+ *p = zero;
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 0xc0;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ pixel = *scanptr & 0xc0;
+ while (pixel > 3)
+ pixel >>= 2;
+
+ *p = (255 * pixel / 3) ^ zero;
+
+ if (bit > 3)
+ bit >>= 2;
+ else
+ {
+ bit = 0xc0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 0xf0;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ if (bit == 0xf0)
+ {
+ *p = (255 * ((*scanptr & 0xf0) >> 4) / 15) ^ zero;
+ bit = 0x0f;
+ }
+ else
+ {
+ *p = (255 * (*scanptr & 0x0f) / 15) ^ zero;
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (ydir < 0 || zero || alpha)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ if (alpha)
+ {
+ if (zero)
+ {
+ for (ycount = img->ysize, p = in + ystart, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += ydir, scanptr += 2)
+ *p = (scanptr[1] * (255 - scanptr[0]) +
+ (255 - scanptr[1]) * 255) / 255;
+ }
+ else
+ {
+ for (ycount = img->ysize, p = in + ystart, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += ydir, scanptr += 2)
+ *p = (scanptr[1] * scanptr[0] +
+ (255 - scanptr[1]) * 255) / 255;
+ }
+ }
+ else
+ {
+ if (zero)
+ {
+ for (ycount = img->ysize, p = in + ystart, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += ydir, scanptr ++)
+ *p = 255 - *scanptr;
+ }
+ else
+ {
+ for (ycount = img->ysize, p = in + ystart, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += ydir, scanptr ++)
+ *p = *scanptr;
+ }
+ }
+ }
+ else
+ TIFFReadScanline(tif, in, row, 0);
+
+ if (img->colorspace == IMAGE_WHITE)
+ {
+ if (lut)
+ ImageLut(in, img->ysize, lut);
+
+ ImagePutCol(img, x, 0, img->ysize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_RGB :
+ ImageWhiteToRGB(in, out, img->ysize);
+ break;
+ case IMAGE_BLACK :
+ ImageWhiteToBlack(in, out, img->ysize);
+ break;
+ case IMAGE_CMY :
+ ImageWhiteToCMY(in, out, img->ysize);
+ break;
+ case IMAGE_CMYK :
+ ImageWhiteToCMYK(in, out, img->ysize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->ysize * bpp, lut);
+
+ ImagePutCol(img, x, 0, img->ysize, out);
+ }
+ }
+ }
+ break;
+
+ case PHOTOMETRIC_PALETTE :
+ if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &redcmap, &greencmap, &bluecmap))
+ {
+ fputs("ERROR: No colormap tag in the file!\n", stderr);
+ fclose(fp);
+ return (-1);
+ }
+
+ num_colors = 1 << bits;
+
+ for (c = 0; c < num_colors; c ++)
+ {
+ redcmap[c] >>= 8;
+ greencmap[c] >>= 8;
+ bluecmap[c] >>= 8;
+ }
+
+ if (orientation < ORIENTATION_LEFTTOP)
+ {
+ /*
+ * Row major order...
+ */
+
+ for (y = ystart, ycount = img->ysize, row = 0;
+ ycount > 0;
+ ycount --, y += ydir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline,
+ p = in + xstart * 3, bit = 128;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (*scanptr & bit)
+ {
+ p[0] = redcmap[1];
+ p[1] = greencmap[1];
+ p[2] = bluecmap[1];
+ }
+ else
+ {
+ p[0] = redcmap[0];
+ p[1] = greencmap[0];
+ p[2] = bluecmap[0];
+ }
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline,
+ p = in + xstart * 3, bit = 0xc0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ pixel = *scanptr & bit;
+ while (pixel > 3)
+ pixel >>= 2;
+
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+
+ if (bit > 3)
+ bit >>= 2;
+ else
+ {
+ bit = 0xc0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline,
+ p = in + 3 * xstart, bit = 0xf0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (bit == 0xf0)
+ {
+ pixel = (*scanptr & 0xf0) >> 4;
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+ bit = 0x0f;
+ }
+ else
+ {
+ pixel = *scanptr++ & 0x0f;
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+ bit = 0xf0;
+ }
+ }
+ }
+ else
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ for (xcount = img->xsize, p = in + 3 * xstart, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ p[0] = redcmap[*scanptr];
+ p[1] = greencmap[*scanptr];
+ p[2] = bluecmap[*scanptr++];
+ }
+ }
+
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (lut)
+ ImageLut(in, img->xsize * 3, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Column major order...
+ */
+
+ for (x = xstart, xcount = img->xsize, row = 0;
+ xcount > 0;
+ xcount --, x += xdir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline,
+ p = in + 3 * ystart, bit = 128;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ if (*scanptr & bit)
+ {
+ p[0] = redcmap[1];
+ p[1] = greencmap[1];
+ p[2] = bluecmap[1];
+ }
+ else
+ {
+ p[0] = redcmap[0];
+ p[1] = greencmap[0];
+ p[2] = bluecmap[0];
+ }
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline,
+ p = in + 3 * ystart, bit = 0xc0;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ pixel = *scanptr & 0xc0;
+ while (pixel > 3)
+ pixel >>= 2;
+
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+
+ if (bit > 3)
+ bit >>= 2;
+ else
+ {
+ bit = 0xc0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline,
+ p = in + 3 * ystart, bit = 0xf0;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ if (bit == 0xf0)
+ {
+ pixel = (*scanptr & 0xf0) >> 4;
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+ bit = 0x0f;
+ }
+ else
+ {
+ pixel = *scanptr++ & 0x0f;
+ p[0] = redcmap[pixel];
+ p[1] = greencmap[pixel];
+ p[2] = bluecmap[pixel];
+ bit = 0xf0;
+ }
+ }
+ }
+ else
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ for (ycount = img->ysize, p = in + 3 * ystart, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += ydir)
+ {
+ p[0] = redcmap[*scanptr];
+ p[1] = greencmap[*scanptr];
+ p[2] = bluecmap[*scanptr++];
+ }
+ }
+
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (lut)
+ ImageLut(in, img->ysize * 3, lut);
+
+ ImagePutCol(img, x, 0, img->ysize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->ysize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->ysize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->ysize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->ysize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->ysize * bpp, lut);
+
+ ImagePutCol(img, x, 0, img->ysize, out);
+ }
+ }
+ }
+ break;
+
+ case PHOTOMETRIC_RGB :
+ if (orientation < ORIENTATION_LEFTTOP)
+ {
+ /*
+ * Row major order...
+ */
+
+ for (y = ystart, ycount = img->ysize, row = 0;
+ ycount > 0;
+ ycount --, y += ydir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (*scanptr & bit & 0x88)
+ p[0] = 255;
+ else
+ p[0] = 0;
+
+ if (*scanptr & bit & 0x44)
+ p[1] = 255;
+ else
+ p[1] = 0;
+
+ if (*scanptr & bit & 0x22)
+ p[2] = 255;
+ else
+ p[2] = 0;
+
+ if (bit == 0xf0)
+ bit = 0x0f;
+ else
+ {
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
+ xcount > 0;
+ xcount --, p += pstep, scanptr ++)
+ {
+ pixel = *scanptr >> 2;
+ p[0] = 255 * (pixel & 3) / 3;
+ pixel >>= 2;
+ p[1] = 255 * (pixel & 3) / 3;
+ pixel >>= 2;
+ p[2] = 255 * (pixel & 3) / 3;
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
+ xcount > 0;
+ xcount -= 2, p += 2 * pstep, scanptr += 3)
+ {
+ pixel = scanptr[0];
+ p[1] = 255 * (pixel & 15) / 15;
+ pixel >>= 4;
+ p[0] = 255 * (pixel & 15) / 15;
+ pixel = scanptr[1];
+ p[2] = 255 * ((pixel >> 4) & 15) / 15;
+
+ if (xcount > 1)
+ {
+ p[pstep + 0] = 255 * (pixel & 15) / 15;
+ pixel = scanptr[2];
+ p[pstep + 2] = 255 * (pixel & 15) / 15;
+ pixel >>= 4;
+ p[pstep + 1] = 255 * (pixel & 15) / 15;
+ }
+ }
+ }
+ else if (xdir < 0 || alpha)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ if (alpha)
+ {
+ for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 4)
+ {
+ p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ }
+ }
+ else
+ {
+ for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 3)
+ {
+ p[0] = scanptr[0];
+ p[1] = scanptr[1];
+ p[2] = scanptr[2];
+ }
+ }
+ }
+ else
+ TIFFReadScanline(tif, in, row, 0);
+
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ ImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (lut)
+ ImageLut(in, img->xsize * 3, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * bpp, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Column major order...
+ */
+
+ for (x = xstart, xcount = img->xsize, row = 0;
+ xcount > 0;
+ xcount --, x += xdir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3, bit = 0xf0;
+ ycount > 0;
+ ycount --, p += pstep)
+ {
+ if (*scanptr & bit & 0x88)
+ p[0] = 255;
+ else
+ p[0] = 0;
+
+ if (*scanptr & bit & 0x44)
+ p[1] = 255;
+ else
+ p[1] = 0;
+
+ if (*scanptr & bit & 0x22)
+ p[2] = 255;
+ else
+ p[2] = 0;
+
+ if (bit == 0xf0)
+ bit = 0x0f;
+ else
+ {
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3;
+ ycount > 0;
+ ycount --, p += pstep, scanptr ++)
+ {
+ pixel = *scanptr >> 2;
+ p[0] = 255 * (pixel & 3) / 3;
+ pixel >>= 2;
+ p[1] = 255 * (pixel & 3) / 3;
+ pixel >>= 2;
+ p[2] = 255 * (pixel & 3) / 3;
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3;
+ ycount > 0;
+ ycount -= 2, p += 2 * pstep, scanptr += 3)
+ {
+ pixel = scanptr[0];
+ p[1] = 255 * (pixel & 15) / 15;
+ pixel >>= 4;
+ p[0] = 255 * (pixel & 15) / 15;
+ pixel = scanptr[1];
+ p[2] = 255 * ((pixel >> 4) & 15) / 15;
+
+ if (ycount > 1)
+ {
+ p[pstep + 0] = 255 * (pixel & 15) / 15;
+ pixel = scanptr[2];
+ p[pstep + 2] = 255 * (pixel & 15) / 15;
+ pixel >>= 4;
+ p[pstep + 1] = 255 * (pixel & 15) / 15;
+ }
+ }
+ }
+ else if (ydir < 0 || alpha)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ if (alpha)
+ {
+ for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += pstep, scanptr += 4)
+ {
+ p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
+ }
+ }
+ else
+ {
+ for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += pstep, scanptr += 3)
+ {
+ p[0] = scanptr[0];
+ p[1] = scanptr[1];
+ p[2] = scanptr[2];
+ }
+ }
+ }
+ else
+ TIFFReadScanline(tif, in, row, 0);
+
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ ImageRGBAdjust(in, img->ysize, saturation, hue);
+
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (lut)
+ ImageLut(in, img->ysize * 3, lut);
+
+ ImagePutCol(img, x, 0, img->ysize, in);
+ }
+ else
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->ysize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->ysize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->ysize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->ysize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->ysize * bpp, lut);
+
+ ImagePutCol(img, x, 0, img->ysize, out);
+ }
+ }
+ }
+ break;
+
+ case PHOTOMETRIC_SEPARATED :
+ inkset = INKSET_CMYK;
+ numinks = 4;
+
+#ifdef TIFFTAG_NUMBEROFINKS
+ if (!TIFFGetField(tif, TIFFTAG_INKSET, &inkset) &&
+ !TIFFGetField(tif, TIFFTAG_NUMBEROFINKS, &numinks))
+#else
+ if (!TIFFGetField(tif, TIFFTAG_INKSET, &inkset))
+#endif /* TIFFTAG_NUMBEROFINKS */
+ {
+ fputs("WARNING: No inkset or number-of-inks tag in the file!\n", stderr);
+ }
+
+ if (inkset == INKSET_CMYK || numinks == 4)
+ {
+ if (orientation < ORIENTATION_LEFTTOP)
+ {
+ /*
+ * Row major order...
+ */
+
+ for (y = ystart, ycount = img->ysize, row = 0;
+ ycount > 0;
+ ycount --, y += ydir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0;
+ xcount > 0;
+ xcount --, p += pstep)
+ {
+ if (*scanptr & bit & 0x11)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ if (*scanptr & bit & 0x88)
+ p[0] = 0;
+ else
+ p[0] = 255;
+
+ if (*scanptr & bit & 0x44)
+ p[1] = 0;
+ else
+ p[1] = 255;
+
+ if (*scanptr & bit & 0x22)
+ p[2] = 0;
+ else
+ p[2] = 255;
+ }
+
+ if (bit == 0xf0)
+ bit = 0x0f;
+ else
+ {
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
+ xcount > 0;
+ xcount --, p += pstep, scanptr ++)
+ {
+ pixel = *scanptr;
+ k = 255 * (pixel & 3) / 3;
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ pixel >>= 2;
+ b = 255 - 255 * (pixel & 3) / 3 - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+
+ pixel >>= 2;
+ g = 255 - 255 * (pixel & 3) / 3 - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ pixel >>= 2;
+ r = 255 - 255 * (pixel & 3) / 3 - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 2)
+ {
+ pixel = scanptr[1];
+ k = 255 * (pixel & 15) / 15;
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ pixel >>= 4;
+ b = 255 - 255 * (pixel & 15) / 15 - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+
+ pixel = scanptr[0];
+ g = 255 - 255 * (pixel & 15) / 15 - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ pixel >>= 4;
+ r = 255 - 255 * (pixel & 15) / 15 - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+ }
+ }
+ }
+ else if (img->colorspace == IMAGE_CMYK)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ ImagePutRow(img, 0, y, img->xsize, scanline);
+ }
+ else
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline;
+ xcount > 0;
+ xcount --, p += pstep, scanptr += 4)
+ {
+ k = scanptr[3];
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ r = 255 - scanptr[0] - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+
+ g = 255 - scanptr[1] - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ b = 255 - scanptr[2] - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+ }
+ }
+ }
+
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ ImageRGBAdjust(in, img->xsize, saturation, hue);
+
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (lut)
+ ImageLut(in, img->xsize * 3, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, in);
+ }
+ else if (img->colorspace == IMAGE_WHITE)
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->xsize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->xsize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->xsize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->xsize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->xsize * 3, lut);
+
+ ImagePutRow(img, 0, y, img->xsize, out);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Column major order...
+ */
+
+ for (x = xstart, xcount = img->xsize, row = 0;
+ xcount > 0;
+ xcount --, x += xdir, row ++)
+ {
+ if (bits == 1)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0;
+ ycount > 0;
+ ycount --, p += pstep)
+ {
+ if (*scanptr & bit & 0x11)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ if (*scanptr & bit & 0x88)
+ p[0] = 0;
+ else
+ p[0] = 255;
+
+ if (*scanptr & bit & 0x44)
+ p[1] = 0;
+ else
+ p[1] = 255;
+
+ if (*scanptr & bit & 0x22)
+ p[2] = 0;
+ else
+ p[2] = 255;
+ }
+
+ if (bit == 0xf0)
+ bit = 0x0f;
+ else
+ {
+ bit = 0xf0;
+ scanptr ++;
+ }
+ }
+ }
+ else if (bits == 2)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3;
+ ycount > 0;
+ ycount --, p += pstep, scanptr ++)
+ {
+ pixel = *scanptr;
+ k = 255 * (pixel & 3) / 3;
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ pixel >>= 2;
+ b = 255 - 255 * (pixel & 3) / 3 - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+
+ pixel >>= 2;
+ g = 255 - 255 * (pixel & 3) / 3 - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ pixel >>= 2;
+ r = 255 - 255 * (pixel & 3) / 3 - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+ }
+ }
+ }
+ else if (bits == 4)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3;
+ ycount > 0;
+ ycount --, p += pstep, scanptr += 2)
+ {
+ pixel = scanptr[1];
+ k = 255 * (pixel & 15) / 15;
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ pixel >>= 4;
+ b = 255 - 255 * (pixel & 15) / 15 - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+
+ pixel = scanptr[0];
+ g = 255 - 255 * (pixel & 15) / 15 - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ pixel >>= 4;
+ r = 255 - 255 * (pixel & 15) / 15 - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+ }
+ }
+ }
+ else if (img->colorspace == IMAGE_CMYK)
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+ ImagePutCol(img, x, 0, img->ysize, scanline);
+ }
+ else
+ {
+ TIFFReadScanline(tif, scanline, row, 0);
+
+ for (ycount = img->ysize, p = in + xstart * 3, scanptr = scanline;
+ ycount > 0;
+ ycount --, p += pstep, scanptr += 4)
+ {
+ k = scanptr[3];
+ if (k == 255)
+ {
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ }
+ else
+ {
+ r = 255 - scanptr[0] - k;
+ if (r < 0)
+ p[0] = 0;
+ else if (r < 256)
+ p[0] = r;
+ else
+ p[0] = 255;
+
+ g = 255 - scanptr[1] - k;
+ if (g < 0)
+ p[1] = 0;
+ else if (g < 256)
+ p[1] = g;
+ else
+ p[1] = 255;
+
+ b = 255 - scanptr[2] - k;
+ if (b < 0)
+ p[2] = 0;
+ else if (b < 256)
+ p[2] = b;
+ else
+ p[2] = 255;
+ }
+ }
+ }
+
+ if ((saturation != 100 || hue != 0) && bpp > 1)
+ ImageRGBAdjust(in, img->ysize, saturation, hue);
+
+ if (img->colorspace == IMAGE_RGB)
+ {
+ if (lut)
+ ImageLut(in, img->ysize * 3, lut);
+
+ ImagePutCol(img, x, 0, img->ysize, in);
+ }
+ else if (img->colorspace == IMAGE_WHITE)
+ {
+ switch (img->colorspace)
+ {
+ case IMAGE_WHITE :
+ ImageRGBToWhite(in, out, img->ysize);
+ break;
+ case IMAGE_BLACK :
+ ImageRGBToBlack(in, out, img->ysize);
+ break;
+ case IMAGE_CMY :
+ ImageRGBToCMY(in, out, img->ysize);
+ break;
+ case IMAGE_CMYK :
+ ImageRGBToCMYK(in, out, img->ysize);
+ break;
+ }
+
+ if (lut)
+ ImageLut(out, img->ysize * bpp, lut);
+
+ ImagePutCol(img, x, 0, img->ysize, out);
+ }
+ }
+ }
+
+ break;
+ }
+
+ default :
+ _TIFFfree(scanline);
+ free(in);
+ free(out);
+
+ TIFFClose(tif);
+ fputs("ERROR: Unknown TIFF photometric value!\n", stderr);
+ return (-1);
+ }
+
+ /*
+ * Free temporary buffers, close the TIFF file, and return.
+ */
+
+ _TIFFfree(scanline);
+ free(in);
+ free(out);
+
+ TIFFClose(tif);
+ return (0);
+}
+
+
+#endif /* HAVE_LIBTIFF */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image-zoom.c b/filter/image-zoom.c
new file mode 100644
index 000000000..a588b5040
--- /dev/null
+++ b/filter/image-zoom.c
@@ -0,0 +1,329 @@
+/*
+ * "$Id$"
+ *
+ * Image zoom routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageZoomAlloc() - Allocate a pixel zoom record...
+ * ImageZoomFill() - Fill a zoom record with image data utilizing bilinear
+ * interpolation.
+ * ImageZoomQFill() - Fill a zoom record quickly using nearest-neighbor
+ * sampling.
+ * ImageZoomFree() - Free a zoom record...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+
+
+/*
+ * 'ZoomAlloc()' - Allocate a pixel zoom record...
+ */
+
+izoom_t *
+ImageZoomAlloc(image_t *img, /* I - Image to zoom */
+ int x0, /* I - Upper-lefthand corner */
+ int y0, /* I - ... */
+ int x1, /* I - Lower-righthand corner */
+ int y1, /* I - ... */
+ int xsize, /* I - Final width of image */
+ int ysize, /* I - Final height of image */
+ int rotated) /* I - Non-zero if image is rotated 90 degs */
+{
+ izoom_t *z; /* New zoom record */
+ int flip; /* Flip on X axis? */
+
+
+ if ((z = (izoom_t *)calloc(1, sizeof(izoom_t))) == NULL)
+ return (NULL);
+
+ z->img = img;
+ z->row = 0;
+ z->depth = ImageGetDepth(img);
+ z->rotated = rotated;
+
+ if (xsize < 0)
+ {
+ flip = 1;
+ xsize = -xsize;
+ }
+ else
+ {
+ flip = 0;
+ }
+
+ if (rotated)
+ {
+ z->xorig = x1;
+ z->yorig = y0;
+ z->width = y1 - y0 + 1;
+ z->height = x1 - x0 + 1;
+ z->xsize = xsize;
+ z->ysize = ysize;
+ z->xmod = z->width % z->xsize;
+ z->xstep = z->width / z->xsize;
+ z->xincr = 1;
+ z->ymod = z->height % z->ysize;
+ z->ystep = z->height / z->ysize;
+ z->yincr = 1;
+ z->instep = z->xstep * z->depth;
+ z->inincr = z->xincr * z->depth;
+
+ if (z->width < img->ysize)
+ z->xmax = z->width;
+ else
+ z->xmax = z->width - 1;
+
+ if (z->height < img->xsize)
+ z->ymax = z->height;
+ else
+ z->ymax = z->height - 1;
+ }
+ else
+ {
+ z->xorig = x0;
+ z->yorig = y0;
+ z->width = x1 - x0 + 1;
+ z->height = y1 - y0 + 1;
+ z->xsize = xsize;
+ z->ysize = ysize;
+ z->xmod = z->width % z->xsize;
+ z->xstep = z->width / z->xsize;
+ z->xincr = 1;
+ z->ymod = z->height % z->ysize;
+ z->ystep = z->height / z->ysize;
+ z->yincr = 1;
+ z->instep = z->xstep * z->depth;
+ z->inincr = z->xincr * z->depth;
+
+ if (z->width < img->xsize)
+ z->xmax = z->width;
+ else
+ z->xmax = z->width - 1;
+
+ if (z->height < img->ysize)
+ z->ymax = z->height;
+ else
+ z->ymax = z->height - 1;
+ }
+
+ if (flip)
+ {
+ z->instep = -z->instep;
+ z->inincr = -z->inincr;
+ }
+
+ if ((z->rows[0] = (ib_t *)malloc(z->xsize * z->depth)) == NULL)
+ {
+ free(z);
+ return (NULL);
+ }
+
+ if ((z->rows[1] = (ib_t *)malloc(z->xsize * z->depth)) == NULL)
+ {
+ free(z->rows[0]);
+ free(z);
+ return (NULL);
+ }
+
+ if ((z->in = (ib_t *)malloc(z->width * z->depth)) == NULL)
+ {
+ free(z->rows[0]);
+ free(z->rows[1]);
+ free(z);
+ return (NULL);
+ }
+
+ return (z);
+}
+
+
+/*
+ * 'ImageZoomFill()' - Fill a zoom record with image data utilizing bilinear
+ * interpolation.
+ */
+
+void
+ImageZoomFill(izoom_t *z, /* I - Zoom record to fill */
+ int iy) /* I - Zoom image row */
+{
+ ib_t *r, /* Row pointer */
+ *inptr; /* Pixel pointer */
+ int xerr0, /* X error counter */
+ xerr1; /* ... */
+ int ix,
+ x,
+ count,
+ z_depth,
+ z_xstep,
+ z_xincr,
+ z_instep,
+ z_inincr,
+ z_xmax,
+ z_xmod,
+ z_xsize;
+
+
+ if (iy > z->ymax)
+ iy = z->ymax;
+
+ z->row ^= 1;
+
+ z_depth = z->depth;
+ z_xsize = z->xsize;
+ z_xmax = z->xmax;
+ z_xmod = z->xmod;
+ z_xstep = z->xstep;
+ z_xincr = z->xincr;
+ z_instep = z->instep;
+ z_inincr = z->inincr;
+
+ if (z->rotated)
+ ImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in);
+ else
+ ImageGetRow(z->img, z->xorig, z->yorig + iy, z->width, z->in);
+
+ if (z_inincr < 0)
+ inptr = z->in + (z->width - 1) * z_depth;
+ else
+ inptr = z->in;
+
+ for (x = z_xsize, xerr0 = z_xsize, xerr1 = 0, ix = 0, r = z->rows[z->row];
+ x > 0;
+ x --)
+ {
+ if (ix < z_xmax)
+ {
+ for (count = 0; count < z_depth; count ++)
+ *r++ = (inptr[count] * xerr0 + inptr[z_depth + count] * xerr1) / z_xsize;
+ }
+ else
+ {
+ for (count = 0; count < z_depth; count ++)
+ *r++ = inptr[count];
+ }
+
+ ix += z_xstep;
+ inptr += z_instep;
+ xerr0 -= z_xmod;
+ xerr1 += z_xmod;
+
+ if (xerr0 <= 0)
+ {
+ xerr0 += z_xsize;
+ xerr1 -= z_xsize;
+ ix += z_xincr;
+ inptr += z_inincr;
+ }
+ }
+}
+
+
+/*
+ * 'ImageZoomQFill()' - Fill a zoom record quickly using nearest-neighbor sampling.
+ */
+
+void
+ImageZoomQFill(izoom_t *z, /* I - Zoom record to fill */
+ int iy) /* I - Zoom image row */
+{
+ ib_t *r, /* Row pointer */
+ *inptr; /* Pixel pointer */
+ int xerr0; /* X error counter */
+ int ix,
+ x,
+ count,
+ z_depth,
+ z_xstep,
+ z_xincr,
+ z_instep,
+ z_inincr,
+ z_xmod,
+ z_xsize;
+
+
+ if (iy > z->ymax)
+ iy = z->ymax;
+
+ z->row ^= 1;
+
+ z_depth = z->depth;
+ z_xsize = z->xsize;
+ z_xmod = z->xmod;
+ z_xstep = z->xstep;
+ z_xincr = z->xincr;
+ z_instep = z->instep;
+ z_inincr = z->inincr;
+
+ if (z->rotated)
+ ImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in);
+ else
+ ImageGetRow(z->img, z->xorig, z->yorig + iy, z->width, z->in);
+
+ if (z_inincr < 0)
+ inptr = z->in + (z->width - 1) * z_depth;
+ else
+ inptr = z->in;
+
+ for (x = z_xsize, xerr0 = z_xsize, ix = 0, r = z->rows[z->row];
+ x > 0;
+ x --)
+ {
+ for (count = 0; count < z_depth; count ++)
+ *r++ = inptr[count];
+
+ ix += z_xstep;
+ inptr += z_instep;
+ xerr0 -= z_xmod;
+
+ if (xerr0 <= 0)
+ {
+ xerr0 += z_xsize;
+ ix += z_xincr;
+ inptr += z_inincr;
+ }
+ }
+}
+
+
+/*
+ * 'ImageZoomFree()' - Free a zoom record...
+ */
+
+void
+ImageZoomFree(izoom_t *z) /* I - Zoom record to free */
+{
+ free(z->rows[0]);
+ free(z->rows[1]);
+ free(z->in);
+ free(z);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image.c b/filter/image.c
new file mode 100644
index 000000000..f17b24fce
--- /dev/null
+++ b/filter/image.c
@@ -0,0 +1,775 @@
+/*
+ * "$Id$"
+ *
+ * Base image support for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * ImageOpen() - Open an image file and read it into memory.
+ * ImageClose() - Close an image file.
+ * ImageSetMaxTiles() - Set the maximum number of tiles to cache.
+ * ImageGetCol() - Get a column of pixels from an image.
+ * ImageGetRow() - Get a row of pixels from an image.
+ * ImagePutCol() - Put a column of pixels to an image.
+ * ImagePutRow() - Put a row of pixels to an image.
+ * get_tile() - Get a cached tile.
+ * flush_tile() - Flush the least-recently-used tile in the cache.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "image.h"
+#include <unistd.h>
+#include <ctype.h>
+#include <math.h>
+#include <cups/cups.h>
+
+
+/*
+ * Local functions...
+ */
+
+static ib_t *get_tile(image_t *img, int x, int y);
+static void flush_tile(image_t *img);
+
+
+/*
+ * 'ImageOpen()' - Open an image file and read it into memory.
+ */
+
+image_t * /* O - New image */
+ImageOpen(char *filename, /* I - Filename of image */
+ int primary, /* I - Primary colorspace needed */
+ int secondary, /* I - Secondary colorspace if primary no good */
+ int saturation,/* I - Color saturation level */
+ int hue, /* I - Color hue adjustment */
+ const ib_t *lut) /* I - RGB gamma/brightness LUT */
+{
+ FILE *fp; /* File pointer */
+ unsigned char header[16], /* First 16 bytes of file */
+ header2[16]; /* Bytes 2048-2064 (PhotoCD) */
+ image_t *img; /* New image buffer */
+ int status; /* Status of load... */
+
+
+ fprintf(stderr, "DEBUG: ImageOpen(\"%s\", %d, %d, %d, %d, %p)\n",
+ filename ? filename : "(null)", primary, secondary,
+ saturation, hue, lut);
+
+ /*
+ * Range check...
+ */
+
+ if (filename == NULL)
+ {
+ fputs("ERROR: Image filename == NULL!\n", stderr);
+ return (NULL);
+ }
+
+ /*
+ * Figure out the file type...
+ */
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ {
+ perror("ERROR: Unable to open image file");
+ return (NULL);
+ }
+
+ if (fread(header, 1, sizeof(header), fp) == 0)
+ {
+ perror("ERROR: Unable to read image file header");
+
+ fclose(fp);
+ return (NULL);
+ }
+
+ fseek(fp, 2048, SEEK_SET);
+ memset(header2, 0, sizeof(header2));
+ fread(header2, 1, sizeof(header2), fp);
+ fseek(fp, 0, SEEK_SET);
+
+ /*
+ * Allocate memory...
+ */
+
+ img = calloc(sizeof(image_t), 1);
+
+ if (img == NULL)
+ {
+ perror("ERROR: Unable to allocate memory for image file");
+ fclose(fp);
+ return (NULL);
+ }
+
+ /*
+ * Load the image as appropriate...
+ */
+
+ img->max_ics = TILE_MINIMUM;
+ img->xppi = 128;
+ img->yppi = 128;
+
+ if (memcmp(header, "GIF87a", 6) == 0 ||
+ memcmp(header, "GIF89a", 6) == 0)
+ status = ImageReadGIF(img, fp, primary, secondary, saturation, hue, lut);
+ else if (memcmp(header, "BM", 2) == 0)
+ status = ImageReadBMP(img, fp, primary, secondary, saturation, hue, lut);
+ else if (header[0] == 0x01 && header[1] == 0xda)
+ status = ImageReadSGI(img, fp, primary, secondary, saturation, hue, lut);
+ else if (header[0] == 0x59 && header[1] == 0xa6 &&
+ header[2] == 0x6a && header[3] == 0x95)
+ status = ImageReadSunRaster(img, fp, primary, secondary, saturation, hue, lut);
+ else if (header[0] == 'P' && header[1] >= '1' && header[1] <= '6')
+ status = ImageReadPNM(img, fp, primary, secondary, saturation, hue, lut);
+ else if (memcmp(header2, "PCD_IPI", 7) == 0)
+ status = ImageReadPhotoCD(img, fp, primary, secondary, saturation, hue, lut);
+ else if (memcmp(header + 8, "\000\010", 2) == 0 ||
+ memcmp(header + 8, "\000\030", 2) == 0)
+ status = ImageReadPIX(img, fp, primary, secondary, saturation, hue, lut);
+#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
+ else if (memcmp(header, "\211PNG", 4) == 0)
+ status = ImageReadPNG(img, fp, primary, secondary, saturation, hue, lut);
+#endif /* HAVE_LIBPNG && HAVE_LIBZ */
+#ifdef HAVE_LIBJPEG
+ else if (memcmp(header, "\377\330\377", 3) == 0 && /* Start-of-Image */
+ header[3] >= 0xe0 && header[3] <= 0xef) /* APPn */
+ status = ImageReadJPEG(img, fp, primary, secondary, saturation, hue, lut);
+#endif /* HAVE_LIBJPEG */
+#ifdef HAVE_LIBTIFF
+ else if (memcmp(header, "MM", 2) == 0 ||
+ memcmp(header, "II", 2) == 0)
+ status = ImageReadTIFF(img, fp, primary, secondary, saturation, hue, lut);
+#endif /* HAVE_LIBTIFF */
+ else
+ {
+ fputs("ERROR: Unknown image file format!\n", stderr);
+ fclose(fp);
+ status = -1;
+ }
+
+ if (status)
+ {
+ free(img);
+ return (NULL);
+ }
+ else
+ return (img);
+}
+
+
+/*
+ * 'ImageClose()' - Close an image file.
+ */
+
+void
+ImageClose(image_t *img) /* I - Image to close */
+{
+ ic_t *current, /* Current cached tile */
+ *next; /* Next cached tile */
+
+
+ /*
+ * Wipe the tile cache file (if any)...
+ */
+
+ if (img->cachefile != NULL)
+ {
+ fprintf(stderr, "DEBUG: Closing and removing swap file \"%s\"...\n",
+ img->cachename);
+
+ fclose(img->cachefile);
+ unlink(img->cachename);
+ }
+
+ /*
+ * Free the image cache...
+ */
+
+ fputs("DEBUG: Freeing memory...\n", stderr);
+
+ for (current = img->first, next = NULL; current != NULL; current = next)
+ {
+ fprintf(stderr, "DEBUG: Freeing cache (%p, next = %p)...\n",
+ current, next);
+
+ next = current->next;
+ free(current);
+ }
+
+ /*
+ * Free the rest of memory...
+ */
+
+ if (img->tiles != NULL)
+ {
+ fprintf(stderr, "DEBUG: Freeing tiles (%p)...\n", img->tiles[0]);
+
+ free(img->tiles[0]);
+
+ fprintf(stderr, "DEBUG: Freeing tile pointers (%p)...\n", img->tiles);
+
+ free(img->tiles);
+ }
+
+ free(img);
+}
+
+
+/*
+ * 'ImageSetMaxTiles()' - Set the maximum number of tiles to cache.
+ *
+ * If the "max_tiles" argument is 0 then the maximum number of tiles is
+ * computed from the image size or the RIP_CACHE environment variable.
+ */
+
+void
+ImageSetMaxTiles(image_t *img, /* I - Image to set */
+ int max_tiles) /* I - Number of tiles to cache */
+{
+ int cache_size, /* Size of tile cache in bytes */
+ min_tiles, /* Minimum number of tiles to cache */
+ max_size; /* Maximum cache size in bytes */
+ char *cache_env, /* Cache size environment variable */
+ cache_units[255]; /* Cache size units */
+
+
+ min_tiles = max(TILE_MINIMUM,
+ 1 + max((img->xsize + TILE_SIZE - 1) / TILE_SIZE,
+ (img->ysize + TILE_SIZE - 1) / TILE_SIZE));
+
+ if (max_tiles == 0)
+ max_tiles = ((img->xsize + TILE_SIZE - 1) / TILE_SIZE) *
+ ((img->ysize + TILE_SIZE - 1) / TILE_SIZE);
+
+ cache_size = max_tiles * TILE_SIZE * TILE_SIZE * ImageGetDepth(img);
+
+ if ((cache_env = getenv("RIP_MAX_CACHE")) != NULL)
+ {
+ switch (sscanf(cache_env, "%d%254s", &max_size, cache_units))
+ {
+ case 0 :
+ max_size = 32 * 1024 * 1024;
+ break;
+ case 1 :
+ max_size *= 4 * TILE_SIZE * TILE_SIZE;
+ break;
+ case 2 :
+ if (tolower(cache_units[0]) == 'g')
+ max_size *= 1024 * 1024 * 1024;
+ else if (tolower(cache_units[0]) == 'm')
+ max_size *= 1024 * 1024;
+ else if (tolower(cache_units[0]) == 'k')
+ max_size *= 1024;
+ else if (tolower(cache_units[0]) == 't')
+ max_size *= 4 * TILE_SIZE * TILE_SIZE;
+ break;
+ }
+ }
+ else
+ max_size = 32 * 1024 * 1024;
+
+ if (cache_size > max_size)
+ max_tiles = max_size / TILE_SIZE / TILE_SIZE / ImageGetDepth(img);
+
+ if (max_tiles < min_tiles)
+ max_tiles = min_tiles;
+
+ img->max_ics = max_tiles;
+
+ fprintf(stderr, "DEBUG: max_ics=%d...\n", img->max_ics);
+}
+
+
+/*
+ * 'ImageGetCol()' - Get a column of pixels from an image.
+ */
+
+int /* O - -1 on error, 0 on success */
+ImageGetCol(image_t *img, /* I - Image */
+ int x, /* I - Column */
+ int y, /* I - Start row */
+ int height, /* I - Column height */
+ ib_t *pixels) /* O - Pixel data */
+{
+ int bpp, /* Bytes per pixel */
+ twidth, /* Tile width */
+ count; /* Number of pixels to get */
+ const ib_t *ib; /* Pointer into tile */
+
+
+ if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize)
+ return (-1);
+
+ if (y < 0)
+ {
+ height += y;
+ y = 0;
+ }
+
+ if ((y + height) > img->ysize)
+ height = img->ysize - y;
+
+ if (height < 1)
+ return (-1);
+
+ bpp = ImageGetDepth(img);
+ twidth = bpp * (TILE_SIZE - 1);
+
+ while (height > 0)
+ {
+ ib = get_tile(img, x, y);
+
+ if (ib == NULL)
+ return (-1);
+
+ count = TILE_SIZE - (y & (TILE_SIZE - 1));
+ if (count > height)
+ count = height;
+
+ y += count;
+ height -= count;
+
+ for (; count > 0; count --, ib += twidth)
+ switch (bpp)
+ {
+ case 4 :
+ *pixels++ = *ib++;
+ case 3 :
+ *pixels++ = *ib++;
+ *pixels++ = *ib++;
+ case 1 :
+ *pixels++ = *ib++;
+ break;
+ }
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'ImageGetRow()' - Get a row of pixels from an image.
+ */
+
+int /* O - -1 on error, 0 on success */
+ImageGetRow(image_t *img, /* I - Image */
+ int x, /* I - Start column */
+ int y, /* I - Row */
+ int width, /* I - Width of row */
+ ib_t *pixels) /* O - Pixel data */
+{
+ int bpp, /* Bytes per pixel */
+ count; /* Number of pixels to get */
+ const ib_t *ib; /* Pointer to pixels */
+
+
+ if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize)
+ return (-1);
+
+ if (x < 0)
+ {
+ width += x;
+ x = 0;
+ }
+
+ if ((x + width) > img->xsize)
+ width = img->xsize - x;
+
+ if (width < 1)
+ return (-1);
+
+ bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace;
+
+ while (width > 0)
+ {
+ ib = get_tile(img, x, y);
+
+ if (ib == NULL)
+ return (-1);
+
+ count = TILE_SIZE - (x & (TILE_SIZE - 1));
+ if (count > width)
+ count = width;
+ memcpy(pixels, ib, count * bpp);
+ pixels += count * bpp;
+ x += count;
+ width -= count;
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'ImagePutCol()' - Put a column of pixels to an image.
+ */
+
+int /* O - -1 on error, 0 on success */
+ImagePutCol(image_t *img, /* I - Image */
+ int x, /* I - Column */
+ int y, /* I - Start row */
+ int height, /* I - Column height */
+ const ib_t *pixels) /* I - Pixels to put */
+{
+ int bpp, /* Bytes per pixel */
+ twidth, /* Width of tile */
+ count; /* Number of pixels to put */
+ int tilex, /* Column within tile */
+ tiley; /* Row within tile */
+ ib_t *ib; /* Pointer to pixels in tile */
+
+
+ if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize)
+ return (-1);
+
+ if (y < 0)
+ {
+ height += y;
+ y = 0;
+ }
+
+ if ((y + height) > img->ysize)
+ height = img->ysize - y;
+
+ if (height < 1)
+ return (-1);
+
+ bpp = ImageGetDepth(img);
+ twidth = bpp * (TILE_SIZE - 1);
+ tilex = x / TILE_SIZE;
+ tiley = y / TILE_SIZE;
+
+ while (height > 0)
+ {
+ ib = get_tile(img, x, y);
+
+ if (ib == NULL)
+ return (-1);
+
+ img->tiles[tiley][tilex].dirty = 1;
+ tiley ++;
+
+ count = TILE_SIZE - (y & (TILE_SIZE - 1));
+ if (count > height)
+ count = height;
+
+ y += count;
+ height -= count;
+
+ for (; count > 0; count --, ib += twidth)
+ switch (bpp)
+ {
+ case 4 :
+ *ib++ = *pixels++;
+ case 3 :
+ *ib++ = *pixels++;
+ *ib++ = *pixels++;
+ case 1 :
+ *ib++ = *pixels++;
+ break;
+ }
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'ImagePutRow()' - Put a row of pixels to an image.
+ */
+
+int /* O - -1 on error, 0 on success */
+ImagePutRow(image_t *img, /* I - Image */
+ int x, /* I - Start column */
+ int y, /* I - Row */
+ int width, /* I - Row width */
+ const ib_t *pixels) /* I - Pixel data */
+{
+ int bpp, /* Bytes per pixel */
+ count; /* Number of pixels to put */
+ int tilex, /* Column within tile */
+ tiley; /* Row within tile */
+ ib_t *ib; /* Pointer to pixels in tile */
+
+
+ if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize)
+ return (-1);
+
+ if (x < 0)
+ {
+ width += x;
+ x = 0;
+ }
+
+ if ((x + width) > img->xsize)
+ width = img->xsize - x;
+
+ if (width < 1)
+ return (-1);
+
+ bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace;
+ tilex = x / TILE_SIZE;
+ tiley = y / TILE_SIZE;
+
+ while (width > 0)
+ {
+ ib = get_tile(img, x, y);
+
+ if (ib == NULL)
+ return (-1);
+
+ img->tiles[tiley][tilex].dirty = 1;
+
+ count = TILE_SIZE - (x & (TILE_SIZE - 1));
+ if (count > width)
+ count = width;
+ memcpy(ib, pixels, count * bpp);
+ pixels += count * bpp;
+ x += count;
+ width -= count;
+ tilex ++;
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'get_tile()' - Get a cached tile.
+ */
+
+static ib_t * /* O - Pointer to tile or NULL */
+get_tile(image_t *img, /* I - Image */
+ int x, /* I - Column in image */
+ int y) /* I - Row in image */
+{
+ int bpp, /* Bytes per pixel */
+ tilex, /* Column within tile */
+ tiley, /* Row within tile */
+ xtiles, /* Number of tiles horizontally */
+ ytiles; /* Number of tiles vertically */
+ ic_t *ic; /* Cache pointer */
+ itile_t *tile; /* Tile pointer */
+
+
+ if (x >= img->xsize || y >= img->ysize)
+ {
+ fprintf(stderr, "ERROR: Internal image RIP error - %d,%d is outside of %dx%d\n",
+ x, y, img->xsize, img->ysize);
+ return (NULL);
+ }
+
+ if (img->tiles == NULL)
+ {
+ xtiles = (img->xsize + TILE_SIZE - 1) / TILE_SIZE;
+ ytiles = (img->ysize + TILE_SIZE - 1) / TILE_SIZE;
+
+ fprintf(stderr, "DEBUG: Creating tile array (%dx%d)\n", xtiles, ytiles);
+
+ img->tiles = calloc(sizeof(itile_t *), ytiles);
+ tile = calloc(sizeof(itile_t), xtiles * ytiles);
+
+ for (tiley = 0; tiley < ytiles; tiley ++)
+ {
+ img->tiles[tiley] = tile;
+ for (tilex = xtiles; tilex > 0; tilex --, tile ++)
+ tile->pos = -1;
+ }
+ }
+
+ bpp = ImageGetDepth(img);
+ tilex = x / TILE_SIZE;
+ tiley = y / TILE_SIZE;
+ x &= (TILE_SIZE - 1);
+ y &= (TILE_SIZE - 1);
+
+ tile = img->tiles[tiley] + tilex;
+
+ if ((ic = tile->ic) == NULL)
+ {
+ if (img->num_ics < img->max_ics)
+ {
+ ic = calloc(sizeof(ic_t) + bpp * TILE_SIZE * TILE_SIZE, 1);
+ ic->pixels = ((ib_t *)ic) + sizeof(ic_t);
+
+ img->num_ics ++;
+
+ fprintf(stderr, "DEBUG: Allocated cache tile %d (%p)...\n",
+ img->num_ics, ic);
+ }
+ else
+ {
+ fprintf(stderr, "DEBUG: Flushing old cache tile (%p)...\n",
+ img->first);
+
+ flush_tile(img);
+ ic = img->first;
+ }
+
+ ic->tile = tile;
+ tile->ic = ic;
+
+ if (tile->pos >= 0)
+ {
+ fprintf(stderr, "DEBUG: Loading cache tile from file position %ld...\n",
+ tile->pos);
+
+ if (ftell(img->cachefile) != tile->pos)
+ if (fseek(img->cachefile, tile->pos, SEEK_SET))
+ perror("get_tile:");
+
+ fread(ic->pixels, bpp, TILE_SIZE * TILE_SIZE, img->cachefile);
+ }
+ else
+ {
+ fputs("DEBUG: Clearing cache tile...\n", stderr);
+
+ memset(ic->pixels, 0, bpp * TILE_SIZE * TILE_SIZE);
+ }
+ }
+
+ if (ic == img->first)
+ {
+ if (ic->next != NULL)
+ ic->next->prev = NULL;
+
+ img->first = ic->next;
+ ic->next = NULL;
+ ic->prev = NULL;
+ }
+ else if (img->first == NULL)
+ img->first = ic;
+
+ if (ic != img->last)
+ {
+ /*
+ * Remove the cache entry from the list...
+ */
+
+ if (ic->prev != NULL)
+ ic->prev->next = ic->next;
+ if (ic->next != NULL)
+ ic->next->prev = ic->prev;
+
+ /*
+ * And add it to the end...
+ */
+
+ if (img->last != NULL)
+ img->last->next = ic;
+
+ ic->prev = img->last;
+ img->last = ic;
+ }
+
+ ic->next = NULL;
+
+ return (ic->pixels + bpp * (y * TILE_SIZE + x));
+}
+
+
+/*
+ * 'flush_tile()' - Flush the least-recently-used tile in the cache.
+ */
+
+static void
+flush_tile(image_t *img) /* I - Image */
+{
+ int fd; /* Cache file descriptor */
+ int bpp; /* Bytes per pixel */
+ itile_t *tile; /* Pointer to tile */
+
+
+ bpp = ImageGetDepth(img);
+ tile = img->first->tile;
+
+ if (!tile->dirty)
+ {
+ tile->ic = NULL;
+ return;
+ }
+
+ if (img->cachefile == NULL)
+ {
+ if ((fd = cupsTempFd(img->cachename, sizeof(img->cachename))) < 0)
+ {
+ perror("ERROR: Unable to create image swap file");
+ tile->ic = NULL;
+ tile->dirty = 0;
+ return;
+ }
+
+ fprintf(stderr, "DEBUG: Created swap file \"%s\"...\n", img->cachename);
+
+ if ((img->cachefile = fdopen(fd, "wb+")) == NULL)
+ {
+ perror("ERROR: Unable to create image swap file");
+ close(fd);
+ unlink(img->cachename);
+ tile->ic = NULL;
+ tile->dirty = 0;
+ return;
+ }
+ }
+
+ if (tile->pos >= 0)
+ {
+ if (ftell(img->cachefile) != tile->pos)
+ if (fseek(img->cachefile, tile->pos, SEEK_SET))
+ {
+ perror("ERROR: Unable to seek in swap file");
+ tile->ic = NULL;
+ tile->dirty = 0;
+ return;
+ }
+ }
+ else
+ {
+ if (fseek(img->cachefile, 0, SEEK_END))
+ {
+ perror("ERROR: Unable to append to swap file");
+ tile->ic = NULL;
+ tile->dirty = 0;
+ return;
+ }
+
+ tile->pos = ftell(img->cachefile);
+ }
+
+
+ if (fwrite(tile->ic->pixels, bpp, TILE_SIZE * TILE_SIZE, img->cachefile) < 1)
+ perror("ERROR: Unable to write tile to swap file");
+ else
+ fprintf(stderr, "DEBUG: Wrote tile at position %ld...\n", tile->pos);
+
+ tile->ic = NULL;
+ tile->dirty = 0;
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/image.h b/filter/image.h
new file mode 100644
index 000000000..6c5bf297e
--- /dev/null
+++ b/filter/image.h
@@ -0,0 +1,243 @@
+/*
+ * "$Id$"
+ *
+ * Image library definitions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _IMAGE_H_
+# define _IMAGE_H_
+
+/*
+ * Include necessary headers...
+ */
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <errno.h>
+# include <config.h>
+# include "raster.h"
+
+
+/*
+ * Colorspaces...
+ */
+
+# define IMAGE_CMYK -4 /* Cyan, magenta, yellow, and black */
+# define IMAGE_CMY -3 /* Cyan, magenta, and yellow */
+# define IMAGE_BLACK -1 /* Black */
+# define IMAGE_WHITE 1 /* White (luminance) */
+# define IMAGE_RGB 3 /* Red, green, and blue */
+# define IMAGE_RGB_CMYK 4 /* Use RGB or CMYK */
+
+
+/*
+ * Tile definitions...
+ */
+
+# define TILE_SIZE 256 /* 256x256 pixel tiles */
+# define TILE_MINIMUM 10 /* Minimum number of tiles */
+
+/*
+ * min/max/abs macros...
+ */
+
+#ifndef max
+# define max(a,b) ((a) > (b) ? (a) : (b))
+#endif /* !max */
+#ifndef min
+# define min(a,b) ((a) < (b) ? (a) : (b))
+#endif /* !min */
+#ifndef abs
+# define abs(a) ((a) < 0 ? -(a) : (a))
+#endif /* !abs */
+
+
+/*
+ * Image byte type...
+ */
+
+typedef unsigned char ib_t;
+
+/*
+ * Tile cache structure...
+ */
+
+typedef struct ic_str
+{
+ struct ic_str *prev, /* Previous tile in cache */
+ *next; /* Next tile in cache */
+ void *tile; /* Tile this is attached to */
+ ib_t *pixels; /* Pixel data */
+} ic_t;
+
+/*
+ * Tile structure...
+ */
+
+typedef struct
+{
+ int dirty; /* True if tile is dirty */
+ long pos; /* Position of tile on disk (-1 if not written) */
+ ic_t *ic; /* Pixel data */
+} itile_t;
+
+/*
+ * Image structure...
+ */
+
+typedef struct
+{
+ int colorspace; /* Colorspace of image */
+ unsigned xsize, /* Width of image in pixels */
+ ysize, /* Height of image in pixels */
+ xppi, /* X resolution in pixels-per-inch */
+ yppi, /* Y resolution in pixels-per-inch */
+ num_ics, /* Number of cached tiles */
+ max_ics; /* Maximum number of cached tiles */
+ itile_t **tiles; /* Tiles in image */
+ ic_t *first, /* First cached tile in image */
+ *last; /* Last cached tile in image */
+ FILE *cachefile; /* Tile cache file */
+ char cachename[256]; /* Tile cache filename */
+} image_t;
+
+/*
+ * Image row zooming structure...
+ */
+
+typedef struct
+{
+ image_t *img; /* Image to zoom */
+ unsigned xorig,
+ yorig,
+ width, /* Width of input area */
+ height, /* Height of input area */
+ depth, /* Number of bytes per pixel */
+ rotated, /* Non-zero if image needs to be rotated */
+ xsize, /* Width of output image */
+ ysize, /* Height of output image */
+ xmax, /* Maximum input image X position */
+ ymax, /* Maximum input image Y position */
+ xmod, /* Threshold for Bresenheim rounding */
+ ymod; /* ... */
+ int xstep, /* Amount to step for each pixel along X */
+ xincr,
+ instep, /* Amount to step pixel pointer along X */
+ inincr,
+ ystep, /* Amount to step for each pixel along Y */
+ yincr,
+ row; /* Current row */
+ ib_t *rows[2], /* Horizontally scaled pixel data */
+ *in; /* Unscaled input pixel data */
+} izoom_t;
+
+
+/*
+ * Basic image functions...
+ */
+
+extern image_t *ImageOpen(char *filename, int primary, int secondary,
+ int saturation, int hue, const ib_t *lut);
+extern void ImageClose(image_t *img);
+extern void ImageSetColorSpace(cups_cspace_t cs);
+extern void ImageSetMaxTiles(image_t *img, int max_tiles);
+extern void ImageSetProfile(float d, float g, float matrix[3][3]);
+
+#define ImageGetDepth(img) ((img)->colorspace < 0 ? -(img)->colorspace : (img)->colorspace)
+extern int ImageGetCol(image_t *img, int x, int y, int height, ib_t *pixels);
+extern int ImageGetRow(image_t *img, int x, int y, int width, ib_t *pixels);
+extern int ImagePutCol(image_t *img, int x, int y, int height, const ib_t *pixels);
+extern int ImagePutRow(image_t *img, int x, int y, int width, const ib_t *pixels);
+
+/*
+ * File formats...
+ */
+
+extern int ImageReadBMP(image_t *img, FILE *fp, int primary, int secondary,
+ int saturation, int hue, const ib_t *lut);
+extern int ImageReadFPX(image_t *img, FILE *fp, int primary, int secondary,
+ int saturation, int hue, const ib_t *lut);
+extern int ImageReadGIF(image_t *img, FILE *fp, int primary, int secondary,
+ int saturation, int hue, const ib_t *lut);
+extern int ImageReadJPEG(image_t *img, FILE *fp, int primary, int secondary,
+ int saturation, int hue, const ib_t *lut);
+extern int ImageReadPIX(image_t *img, FILE *fp, int primary, int secondary,
+ int saturation, int hue, const ib_t *lut);
+extern int ImageReadPNG(image_t *img, FILE *fp, int primary, int secondary,
+ int saturation, int hue, const ib_t *lut);
+extern int ImageReadPNM(image_t *img, FILE *fp, int primary, int secondary,
+ int saturation, int hue, const ib_t *lut);
+extern int ImageReadPhotoCD(image_t *img, FILE *fp, int primary,
+ int secondary, int saturation, int hue,
+ const ib_t *lut);
+extern int ImageReadSGI(image_t *img, FILE *fp, int primary, int secondary,
+ int saturation, int hue, const ib_t *lut);
+extern int ImageReadSunRaster(image_t *img, FILE *fp, int primary,
+ int secondary, int saturation, int hue,
+ const ib_t *lut);
+extern int ImageReadTIFF(image_t *img, FILE *fp, int primary, int secondary,
+ int saturation, int hue, const ib_t *lut);
+
+/*
+ * Colorspace conversions...
+ */
+
+extern void ImageWhiteToWhite(const ib_t *in, ib_t *out, int count);
+extern void ImageWhiteToRGB(const ib_t *in, ib_t *out, int count);
+extern void ImageWhiteToBlack(const ib_t *in, ib_t *out, int count);
+extern void ImageWhiteToCMY(const ib_t *in, ib_t *out, int count);
+extern void ImageWhiteToCMYK(const ib_t *in, ib_t *out, int count);
+
+extern void ImageRGBToWhite(const ib_t *in, ib_t *out, int count);
+extern void ImageRGBToRGB(const ib_t *in, ib_t *out, int count);
+extern void ImageRGBToBlack(const ib_t *in, ib_t *out, int count);
+extern void ImageRGBToCMY(const ib_t *in, ib_t *out, int count);
+extern void ImageRGBToCMYK(const ib_t *in, ib_t *out, int count);
+
+extern void ImageCMYKToWhite(const ib_t *in, ib_t *out, int count);
+extern void ImageCMYKToRGB(const ib_t *in, ib_t *out, int count);
+extern void ImageCMYKToBlack(const ib_t *in, ib_t *out, int count);
+extern void ImageCMYKToCMY(const ib_t *in, ib_t *out, int count);
+extern void ImageCMYKToCMYK(const ib_t *in, ib_t *out, int count);
+
+extern void ImageRGBAdjust(ib_t *pixels, int count, int saturation, int hue);
+
+extern void ImageLut(ib_t *pixels, int count, const ib_t *lut);
+
+/*
+ * Image scaling operations...
+ */
+
+extern izoom_t *ImageZoomAlloc(image_t *img, int x0, int y0, int x1, int y1,
+ int xsize, int ysize, int rotated);
+extern void ImageZoomFill(izoom_t *z, int iy);
+extern void ImageZoomQFill(izoom_t *z, int iy);
+extern void ImageZoomFree(izoom_t *z);
+
+
+#endif /* !_IMAGE_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/imagetops.c b/filter/imagetops.c
new file mode 100644
index 000000000..345892e2b
--- /dev/null
+++ b/filter/imagetops.c
@@ -0,0 +1,892 @@
+/*
+ * "$Id$"
+ *
+ * Image file to PostScript filter for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Main entry...
+ * ps_hex() - Print binary data as a series of hexadecimal numbers.
+ * ps_ascii85() - Print binary data as a series of base-85 numbers.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "common.h"
+#include "image.h"
+#include <math.h>
+
+
+/*
+ * Globals...
+ */
+
+int Flip = 0, /* Flip/mirror pages */
+ XPosition = 0, /* Horizontal position on page */
+ YPosition = 0, /* Vertical position on page */
+ Collate = 0, /* Collate copies? */
+ Copies = 1; /* Number of copies */
+
+
+/*
+ * Local functions...
+ */
+
+static void ps_hex(ib_t *, int, int);
+static void ps_ascii85(ib_t *, int, int);
+
+
+/*
+ * 'main()' - Main entry...
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ image_t *img; /* Image to print */
+ float xprint, /* Printable area */
+ yprint,
+ xinches, /* Total size in inches */
+ yinches;
+ float xsize, /* Total size in points */
+ ysize,
+ xsize2,
+ ysize2;
+ float aspect; /* Aspect ratio */
+ int xpages, /* # x pages */
+ ypages, /* # y pages */
+ xpage, /* Current x page */
+ ypage, /* Current y page */
+ page; /* Current page number */
+ int x0, y0, /* Corners of the page in image coords */
+ x1, y1;
+ ib_t *row; /* Current row */
+ int y; /* Current Y coordinate in image */
+ int colorspace; /* Output colorspace */
+ int out_offset, /* Offset into output buffer */
+ out_length; /* Length of output buffer */
+ ppd_file_t *ppd; /* PPD file */
+ ppd_choice_t *choice; /* PPD option choice */
+ int num_options; /* Number of print options */
+ cups_option_t *options; /* Print options */
+ const char *val; /* Option value */
+ int slowcollate; /* Collate copies the slow way */
+ float g; /* Gamma correction value */
+ float b; /* Brightness factor */
+ float zoom; /* Zoom facter */
+ int xppi, yppi; /* Pixels-per-inch */
+ int hue, sat; /* Hue and saturation adjustment */
+ int realcopies; /* Real copies being printed */
+ float left, top; /* Left and top of image */
+ char filename[1024]; /* Name of file to print */
+ time_t curtime; /* Current time */
+ struct tm *curtm; /* Current date */
+ char curdate[255]; /* Current date string */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fputs("ERROR: imagetops job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ fprintf(stderr, "INFO: %s %s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5], argv[6] ? argv[6] : "(null)");
+
+ /*
+ * Copy stdin as needed...
+ */
+
+ if (argc == 6)
+ {
+ int fd; /* File to write to */
+ char buffer[8192]; /* Buffer to read into */
+ int bytes; /* # of bytes to read */
+
+
+ if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
+ {
+ perror("ERROR: Unable to copy image file");
+ return (1);
+ }
+
+ fprintf(stderr, "DEBUG: imagetoraster - copying to temp print file \"%s\"\n",
+ filename);
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ write(fd, buffer, bytes);
+
+ close(fd);
+ }
+ else
+ strlcpy(filename, argv[6], sizeof(filename));
+
+ /*
+ * Process command-line options and write the prolog...
+ */
+
+ zoom = 0.0;
+ xppi = 0;
+ yppi = 0;
+ hue = 0;
+ sat = 100;
+ g = 1.0;
+ b = 1.0;
+
+ Copies = atoi(argv[4]);
+
+ options = NULL;
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ ppd = SetCommonOptions(num_options, options, 1);
+
+ if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL)
+ {
+ /*
+ * This IPP attribute is unnecessarily complicated...
+ *
+ * single-document, separate-documents-collated-copies, and
+ * single-document-new-sheet all require collated copies.
+ *
+ * separate-documents-uncollated-copies allows for uncollated copies.
+ */
+
+ Collate = strcasecmp(val, "separate-documents-uncollated-copies") != 0;
+ }
+
+ if ((val = cupsGetOption("Collate", num_options, options)) != NULL &&
+ strcasecmp(val, "True") == 0)
+ Collate = 1;
+
+ if ((val = cupsGetOption("gamma", num_options, options)) != NULL)
+ g = atoi(val) * 0.001f;
+
+ if ((val = cupsGetOption("brightness", num_options, options)) != NULL)
+ b = atoi(val) * 0.01f;
+
+ if ((val = cupsGetOption("scaling", num_options, options)) != NULL)
+ zoom = atoi(val) * 0.01;
+
+ if ((val = cupsGetOption("ppi", num_options, options)) != NULL)
+ if (sscanf(val, "%dx%d", &xppi, &yppi) < 2)
+ yppi = xppi;
+
+ if ((val = cupsGetOption("position", num_options, options)) != NULL)
+ {
+ if (strcasecmp(val, "center") == 0)
+ {
+ XPosition = 0;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "top") == 0)
+ {
+ XPosition = 0;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "left") == 0)
+ {
+ XPosition = -1;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "right") == 0)
+ {
+ XPosition = 1;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "top-left") == 0)
+ {
+ XPosition = -1;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "top-right") == 0)
+ {
+ XPosition = 1;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "bottom") == 0)
+ {
+ XPosition = 0;
+ YPosition = -1;
+ }
+ else if (strcasecmp(val, "bottom-left") == 0)
+ {
+ XPosition = -1;
+ YPosition = -1;
+ }
+ else if (strcasecmp(val, "bottom-right") == 0)
+ {
+ XPosition = 1;
+ YPosition = -1;
+ }
+ }
+
+ if ((val = cupsGetOption("saturation", num_options, options)) != NULL)
+ sat = atoi(val);
+
+ if ((val = cupsGetOption("hue", num_options, options)) != NULL)
+ hue = atoi(val);
+
+ if ((val = cupsGetOption("mirror", num_options, options)) != NULL &&
+ strcasecmp(val, "True") == 0)
+ Flip = 1;
+
+ /*
+ * Open the input image to print...
+ */
+
+ colorspace = ColorDevice ? IMAGE_RGB_CMYK : IMAGE_WHITE;
+
+ img = ImageOpen(filename, colorspace, IMAGE_WHITE, sat, hue, NULL);
+
+ if (argc == 6)
+ unlink(filename);
+
+ if (img == NULL)
+ {
+ fputs("ERROR: Unable to open image file for printing!\n", stderr);
+ ppdClose(ppd);
+ return (1);
+ }
+
+ colorspace = img->colorspace;
+
+ /*
+ * Scale as necessary...
+ */
+
+ xprint = (PageRight - PageLeft) / 72.0;
+ yprint = (PageTop - PageBottom) / 72.0;
+
+ if (zoom == 0.0 && xppi == 0)
+ {
+ xppi = img->xppi;
+ yppi = img->yppi;
+ }
+
+ if (yppi == 0)
+ yppi = xppi;
+
+ if (xppi > 0)
+ {
+ /*
+ * Scale the image as neccesary to match the desired pixels-per-inch.
+ */
+
+ xinches = (float)img->xsize / (float)xppi;
+ yinches = (float)img->ysize / (float)yppi;
+
+ if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
+ {
+ xinches = xinches * atoi(val) / 100;
+ yinches = yinches * atoi(val) / 100;
+ }
+
+ if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
+ cupsGetOption("landscape", num_options, options) == NULL)
+ {
+ /*
+ * Rotate the image if it will fit landscape but not portrait...
+ */
+
+ if ((xinches > xprint || yinches > yprint) &&
+ xinches <= yprint && yinches <= xprint)
+ {
+ /*
+ * Rotate the image as needed...
+ */
+
+ Orientation = (Orientation + 1) & 3;
+ xsize = yprint;
+ yprint = xprint;
+ xprint = xsize;
+
+ xsize = PageLeft;
+ PageLeft = PageBottom;
+ PageBottom = PageWidth - PageRight;
+ PageRight = PageTop;
+ PageTop = PageLength - xsize;
+
+ xsize = PageWidth;
+ PageWidth = PageLength;
+ PageLength = xsize;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Scale percentage of page size...
+ */
+
+ aspect = (float)img->yppi / (float)img->xppi;
+
+ fprintf(stderr, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
+ img->xppi, img->yppi, aspect);
+
+ xsize = xprint * zoom;
+ ysize = xsize * img->ysize / img->xsize / aspect;
+
+ if (ysize > (yprint * zoom))
+ {
+ ysize = yprint * zoom;
+ xsize = ysize * img->xsize * aspect / img->ysize;
+ }
+
+ xsize2 = yprint * zoom;
+ ysize2 = xsize2 * img->ysize / img->xsize / aspect;
+
+ if (ysize2 > (xprint * zoom))
+ {
+ ysize2 = xprint * zoom;
+ xsize2 = ysize2 * img->xsize * aspect / img->ysize;
+ }
+
+ fprintf(stderr, "DEBUG: xsize = %.0f, ysize = %.0f\n", xsize, ysize);
+ fprintf(stderr, "DEBUG: xsize2 = %.0f, ysize2 = %.0f\n", xsize2, ysize2);
+
+ if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
+ cupsGetOption("landscape", num_options, options) == NULL)
+ {
+ /*
+ * Choose the rotation with the largest area, but prefer
+ * portrait if they are equal...
+ */
+
+ if ((xsize * ysize) < (xsize2 * xsize2))
+ {
+ /*
+ * Do landscape orientation...
+ */
+
+ Orientation = 1;
+ xinches = xsize2;
+ yinches = ysize2;
+ xprint = (PageTop - PageBottom) / 72.0;
+ yprint = (PageRight - PageLeft) / 72.0;
+
+ xsize = PageLeft;
+ PageLeft = PageBottom;
+ PageBottom = PageWidth - PageRight;
+ PageRight = PageTop;
+ PageTop = PageLength - xsize;
+
+ xsize = PageWidth;
+ PageWidth = PageLength;
+ PageLength = xsize;
+ }
+ else
+ {
+ /*
+ * Do portrait orientation...
+ */
+
+ Orientation = 0;
+ xinches = xsize;
+ yinches = ysize;
+ }
+ }
+ else if (Orientation & 1)
+ {
+ xinches = xsize2;
+ yinches = ysize2;
+ xprint = (PageTop - PageBottom) / 72.0;
+ yprint = (PageRight - PageLeft) / 72.0;
+
+ xsize = PageLeft;
+ PageLeft = PageBottom;
+ PageBottom = PageWidth - PageRight;
+ PageRight = PageTop;
+ PageTop = PageLength - xsize;
+
+ xsize = PageWidth;
+ PageWidth = PageLength;
+ PageLength = xsize;
+ }
+ else
+ {
+ xinches = xsize;
+ yinches = ysize;
+ xprint = (PageRight - PageLeft) / 72.0;
+ yprint = (PageTop - PageBottom) / 72.0;
+ }
+ }
+
+ /*
+ * Compute the number of pages to print and the size of the image on each
+ * page...
+ */
+
+ xpages = ceil(xinches / xprint);
+ ypages = ceil(yinches / yprint);
+
+ xprint = xinches / xpages;
+ yprint = yinches / ypages;
+
+ /*
+ * Update the page size for custom sizes...
+ */
+
+ if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL &&
+ strcasecmp(choice->choice, "Custom") == 0)
+ {
+ float width, /* New width in points */
+ length; /* New length in points */
+ char s[255]; /* New custom page size... */
+
+
+ if (Orientation & 1)
+ {
+ width = yprint * 72.0;
+ length = xprint * 72.0;
+ }
+ else
+ {
+ width = xprint * 72.0;
+ length = yprint * 72.0;
+ }
+
+ /*
+ * Add margins to page size...
+ */
+
+ width += ppd->custom_margins[0] + ppd->custom_margins[2];
+ length += ppd->custom_margins[1] + ppd->custom_margins[3];
+
+ /*
+ * Enforce minimums...
+ */
+
+ if (width < ppd->custom_min[0])
+ width = ppd->custom_min[0];
+
+ if (length < ppd->custom_min[1])
+ length = ppd->custom_min[1];
+
+ /*
+ * Set the new custom size...
+ */
+
+ sprintf(s, "Custom.%.0fx%.0f", width, length);
+ ppdMarkOption(ppd, "PageSize", s);
+
+ /*
+ * Update page variables...
+ */
+
+ PageWidth = width;
+ PageLength = length;
+ PageLeft = ppd->custom_margins[0];
+ PageRight = width - ppd->custom_margins[2];
+ PageBottom = ppd->custom_margins[1];
+ PageTop = length - ppd->custom_margins[3];
+
+ UpdatePageVars();
+ }
+
+ /*
+ * See if we need to collate, and if so how we need to do it...
+ */
+
+ if (xpages == 1 && ypages == 1)
+ Collate = 0;
+
+ slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL;
+
+ if (Copies > 1 && !slowcollate)
+ {
+ realcopies = Copies;
+ Copies = 1;
+ }
+ else
+ realcopies = 1;
+
+ /*
+ * Write any "exit server" options that have been selected...
+ */
+
+ ppdEmit(ppd, stdout, PPD_ORDER_EXIT);
+
+ /*
+ * Write any JCL commands that are needed to print PostScript code...
+ */
+
+ ppdEmitJCL(ppd, stdout, atoi(argv[1]), argv[2], argv[3]);
+
+ /*
+ * Start sending the document with any commands needed...
+ */
+
+ curtime = time(NULL);
+ curtm = localtime(&curtime);
+
+ puts("%!PS-Adobe-3.0");
+ printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom,
+ PageRight, PageTop);
+ printf("%%%%LanguageLevel: %d\n", LanguageLevel);
+ printf("%%%%Pages: %d\n", xpages * ypages * Copies);
+ puts("%%DocumentData: Clean7Bit");
+ puts("%%DocumentNeededResources: font Helvetica-Bold");
+ puts("%%Creator: imagetops/" CUPS_SVERSION);
+ strftime(curdate, sizeof(curdate), CUPS_STRFTIME_FORMAT, curtm);
+ printf("%%%%CreationDate: %s\n", curdate);
+ printf("%%%%Title: %s\n", argv[3]);
+ printf("%%%%For: %s\n", argv[2]);
+ if (Orientation & 1)
+ puts("%%Orientation: Landscape");
+ else
+ puts("%%Orientation: Portrait");
+ puts("%%EndComments");
+ puts("%%BeginProlog");
+
+ if (ppd != NULL && ppd->patches != NULL)
+ puts(ppd->patches);
+
+ ppdEmit(ppd, stdout, PPD_ORDER_DOCUMENT);
+ ppdEmit(ppd, stdout, PPD_ORDER_ANY);
+ ppdEmit(ppd, stdout, PPD_ORDER_PROLOG);
+
+ if (g != 1.0 || b != 1.0)
+ printf("{ neg 1 add dup 0 lt { pop 1 } { %.3f exp neg 1 add } "
+ "ifelse %.3f mul } bind settransfer\n", g, b);
+
+ WriteLabelProlog(cupsGetOption("page-label", num_options, options),
+ PageBottom, PageTop, PageWidth);
+
+ if (realcopies > 1)
+ {
+ if (ppd == NULL || ppd->language_level == 1)
+ printf("/#copies %d def\n", realcopies);
+ else
+ printf("<</NumCopies %d>>setpagedevice\n", realcopies);
+ }
+
+ puts("%%EndProlog");
+
+ /*
+ * Output the pages...
+ */
+
+ row = malloc(img->xsize * abs(colorspace) + 3);
+
+ for (page = 1; Copies > 0; Copies --)
+ for (xpage = 0; xpage < xpages; xpage ++)
+ for (ypage = 0; ypage < ypages; ypage ++, page ++)
+ {
+ if (ppd && ppd->num_filters == 0)
+ fprintf(stderr, "PAGE: %d %d\n", page, realcopies);
+
+ fprintf(stderr, "INFO: Printing page %d...\n", page);
+
+ printf("%%%%Page: %d %d\n", page, page);
+
+ ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+
+ puts("gsave");
+
+ if (Flip)
+ printf("%.0f 0 translate -1 1 scale\n", PageWidth);
+
+ switch (Orientation)
+ {
+ case 1 : /* Landscape */
+ printf("%.0f 0 translate 90 rotate\n", PageLength);
+ break;
+ case 2 : /* Reverse Portrait */
+ printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength);
+ break;
+ case 3 : /* Reverse Landscape */
+ printf("0 %.0f translate -90 rotate\n", PageWidth);
+ break;
+ }
+
+ x0 = img->xsize * xpage / xpages;
+ x1 = img->xsize * (xpage + 1) / xpages - 1;
+ y0 = img->ysize * ypage / ypages;
+ y1 = img->ysize * (ypage + 1) / ypages - 1;
+
+ switch (XPosition)
+ {
+ case -1 :
+ left = PageLeft;
+ break;
+ default :
+ left = (PageWidth - xprint * 72.0) * 0.5;
+ break;
+ case 1 :
+ left = PageRight - xprint * 72.0;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case -1 :
+ top = PageBottom + 72.0 * yprint;
+ break;
+ default :
+ top = (PageLength + yprint * 72.0) * 0.5;
+ break;
+ case 1 :
+ top = PageTop;
+ break;
+ }
+
+ printf("%.1f %.1f translate\n", left, top);
+
+ printf("%.3f %.3f scale\n\n",
+ xprint * 72.0 / (x1 - x0 + 1),
+ yprint * 72.0 / (y1 - y0 + 1));
+
+ if (LanguageLevel == 1)
+ {
+ printf("/picture %d string def\n", (x1 - x0 + 1) * abs(colorspace));
+ printf("%d %d 8[1 0 0 -1 0 1]", (x1 - x0 + 1), (y1 - y0 + 1));
+
+ if (colorspace == IMAGE_WHITE)
+ puts("{currentfile picture readhexstring pop} image");
+ else
+ printf("{currentfile picture readhexstring pop} false %d colorimage\n",
+ abs(colorspace));
+
+ for (y = y0; y <= y1; y ++)
+ {
+ ImageGetRow(img, x0, y, x1 - x0 + 1, row);
+ ps_hex(row, (x1 - x0 + 1) * abs(colorspace), y == y1);
+ }
+ }
+ else
+ {
+ switch (colorspace)
+ {
+ case IMAGE_WHITE :
+ puts("/DeviceGray setcolorspace");
+ break;
+ case IMAGE_RGB :
+ puts("/DeviceRGB setcolorspace");
+ break;
+ case IMAGE_CMYK :
+ puts("/DeviceCMYK setcolorspace");
+ break;
+ }
+
+ printf("<<"
+ "/ImageType 1"
+ "/Width %d"
+ "/Height %d"
+ "/BitsPerComponent 8",
+ x1 - x0 + 1, y1 - y0 + 1);
+
+ switch (colorspace)
+ {
+ case IMAGE_WHITE :
+ fputs("/Decode[0 1]", stdout);
+ break;
+ case IMAGE_RGB :
+ fputs("/Decode[0 1 0 1 0 1]", stdout);
+ break;
+ case IMAGE_CMYK :
+ fputs("/Decode[0 1 0 1 0 1 0 1]", stdout);
+ break;
+ }
+
+ fputs("/DataSource currentfile /ASCII85Decode filter", stdout);
+
+ if (((x1 - x0 + 1) / xprint) < 100.0)
+ fputs("/Interpolate true", stdout);
+
+ puts("/ImageMatrix[1 0 0 -1 0 1]>>image");
+
+ for (y = y0, out_offset = 0; y <= y1; y ++)
+ {
+ ImageGetRow(img, x0, y, x1 - x0 + 1, row + out_offset);
+
+ out_length = (x1 - x0 + 1) * abs(colorspace) + out_offset;
+ out_offset = out_length & 3;
+
+ ps_ascii85(row, out_length, y == y1);
+
+ if (out_offset > 0)
+ memcpy(row, row + out_length - out_offset, out_offset);
+ }
+ }
+
+ puts("grestore");
+ WriteLabels(Orientation);
+ puts("showpage");
+ }
+
+ puts("%%EOF");
+
+ /*
+ * End the job with the appropriate JCL command or CTRL-D otherwise.
+ */
+
+ if (ppd != NULL && ppd->jcl_end)
+ fputs(ppd->jcl_end, stdout);
+ else
+ putchar(0x04);
+
+ /*
+ * Close files...
+ */
+
+ ImageClose(img);
+ ppdClose(ppd);
+
+ return (0);
+}
+
+
+/*
+ * 'ps_hex()' - Print binary data as a series of hexadecimal numbers.
+ */
+
+static void
+ps_hex(ib_t *data, /* I - Data to print */
+ int length, /* I - Number of bytes to print */
+ int last_line) /* I - Last line of raster data? */
+{
+ static int col = 0; /* Current column */
+ static char *hex = "0123456789ABCDEF";
+ /* Hex digits */
+
+
+ while (length > 0)
+ {
+ /*
+ * Put the hex chars out to the file; note that we don't use printf()
+ * for speed reasons...
+ */
+
+ putchar(hex[*data >> 4]);
+ putchar(hex[*data & 15]);
+
+ data ++;
+ length --;
+
+ col += 2;
+ if (col > 78)
+ {
+ putchar('\n');
+ col = 0;
+ }
+ }
+
+ if (last_line && col)
+ {
+ putchar('\n');
+ col = 0;
+ }
+}
+
+
+/*
+ * 'ps_ascii85()' - Print binary data as a series of base-85 numbers.
+ */
+
+static void
+ps_ascii85(ib_t *data, /* I - Data to print */
+ int length, /* I - Number of bytes to print */
+ int last_line) /* I - Last line of raster data? */
+{
+ unsigned b; /* Binary data word */
+ unsigned char c[5]; /* ASCII85 encoded chars */
+ static int col = 0; /* Current column */
+
+
+ while (length > 3)
+ {
+ b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3];
+
+ if (b == 0)
+ {
+ putchar('z');
+ col ++;
+ }
+ else
+ {
+ c[4] = (b % 85) + '!';
+ b /= 85;
+ c[3] = (b % 85) + '!';
+ b /= 85;
+ c[2] = (b % 85) + '!';
+ b /= 85;
+ c[1] = (b % 85) + '!';
+ b /= 85;
+ c[0] = b + '!';
+
+ fwrite(c, 5, 1, stdout);
+ col += 5;
+ }
+
+ data += 4;
+ length -= 4;
+
+ if (col >= 75)
+ {
+ putchar('\n');
+ col = 0;
+ }
+ }
+
+ if (last_line)
+ {
+ if (length > 0)
+ {
+ memset(data + length, 0, 4 - length);
+ b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3];
+
+ c[4] = (b % 85) + '!';
+ b /= 85;
+ c[3] = (b % 85) + '!';
+ b /= 85;
+ c[2] = (b % 85) + '!';
+ b /= 85;
+ c[1] = (b % 85) + '!';
+ b /= 85;
+ c[0] = b + '!';
+
+ fwrite(c, length + 1, 1, stdout);
+ }
+
+ puts("~>");
+ col = 0;
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/imagetoraster.c b/filter/imagetoraster.c
new file mode 100644
index 000000000..6c0da9eb7
--- /dev/null
+++ b/filter/imagetoraster.c
@@ -0,0 +1,4516 @@
+/*
+ * "$Id$"
+ *
+ * Image file to raster filter for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Main entry...
+ * exec_code() - Execute PostScript setpagedevice commands as
+ * appropriate.
+ * format_CMY() - Convert image data to CMY.
+ * format_CMYK() - Convert image data to CMYK.
+ * format_K() - Convert image data to black.
+ * format_KCMY() - Convert image data to KCMY.
+ * format_KCMYcm() - Convert image data to KCMYcm.
+ * format_RGBA() - Convert image data to RGBA.
+ * format_W() - Convert image data to luminance.
+ * format_YMC() - Convert image data to YMC.
+ * format_YMCK() - Convert image data to YMCK.
+ * make_lut() - Make a lookup table given gamma and brightness values.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "common.h"
+#include "image.h"
+#include "raster.h"
+#include <unistd.h>
+#include <math.h>
+
+
+/*
+ * Globals...
+ */
+
+int Flip = 0, /* Flip/mirror pages */
+ XPosition = 0, /* Horizontal position on page */
+ YPosition = 0, /* Vertical position on page */
+ Collate = 0, /* Collate copies? */
+ Copies = 1; /* Number of copies */
+int Floyd16x16[16][16] = /* Traditional Floyd ordered dither */
+ {
+ { 0, 128, 32, 160, 8, 136, 40, 168,
+ 2, 130, 34, 162, 10, 138, 42, 170 },
+ { 192, 64, 224, 96, 200, 72, 232, 104,
+ 194, 66, 226, 98, 202, 74, 234, 106 },
+ { 48, 176, 16, 144, 56, 184, 24, 152,
+ 50, 178, 18, 146, 58, 186, 26, 154 },
+ { 240, 112, 208, 80, 248, 120, 216, 88,
+ 242, 114, 210, 82, 250, 122, 218, 90 },
+ { 12, 140, 44, 172, 4, 132, 36, 164,
+ 14, 142, 46, 174, 6, 134, 38, 166 },
+ { 204, 76, 236, 108, 196, 68, 228, 100,
+ 206, 78, 238, 110, 198, 70, 230, 102 },
+ { 60, 188, 28, 156, 52, 180, 20, 148,
+ 62, 190, 30, 158, 54, 182, 22, 150 },
+ { 252, 124, 220, 92, 244, 116, 212, 84,
+ 254, 126, 222, 94, 246, 118, 214, 86 },
+ { 3, 131, 35, 163, 11, 139, 43, 171,
+ 1, 129, 33, 161, 9, 137, 41, 169 },
+ { 195, 67, 227, 99, 203, 75, 235, 107,
+ 193, 65, 225, 97, 201, 73, 233, 105 },
+ { 51, 179, 19, 147, 59, 187, 27, 155,
+ 49, 177, 17, 145, 57, 185, 25, 153 },
+ { 243, 115, 211, 83, 251, 123, 219, 91,
+ 241, 113, 209, 81, 249, 121, 217, 89 },
+ { 15, 143, 47, 175, 7, 135, 39, 167,
+ 13, 141, 45, 173, 5, 133, 37, 165 },
+ { 207, 79, 239, 111, 199, 71, 231, 103,
+ 205, 77, 237, 109, 197, 69, 229, 101 },
+ { 63, 191, 31, 159, 55, 183, 23, 151,
+ 61, 189, 29, 157, 53, 181, 21, 149 },
+ { 254, 127, 223, 95, 247, 119, 215, 87,
+ 253, 125, 221, 93, 245, 117, 213, 85 }
+ };
+int Floyd8x8[8][8] =
+ {
+ { 0, 32, 8, 40, 2, 34, 10, 42 },
+ { 48, 16, 56, 24, 50, 18, 58, 26 },
+ { 12, 44, 4, 36, 14, 46, 6, 38 },
+ { 60, 28, 52, 20, 62, 30, 54, 22 },
+ { 3, 35, 11, 43, 1, 33, 9, 41 },
+ { 51, 19, 59, 27, 49, 17, 57, 25 },
+ { 15, 47, 7, 39, 13, 45, 5, 37 },
+ { 63, 31, 55, 23, 61, 29, 53, 21 }
+ };
+int Floyd4x4[4][4] =
+ {
+ { 0, 8, 2, 10 },
+ { 12, 4, 14, 6 },
+ { 3, 11, 1, 9 },
+ { 15, 7, 13, 5 }
+ };
+
+ib_t OnPixels[256], /* On-pixel LUT */
+ OffPixels[256]; /* Off-pixel LUT */
+int Planes[] = /* Number of planes for each colorspace */
+ {
+ 1, /* CUPS_CSPACE_W */
+ 3, /* CUPS_CSPACE_RGB */
+ 4, /* CUPS_CSPACE_RGBA */
+ 1, /* CUPS_CSPACE_K */
+ 3, /* CUPS_CSPACE_CMY */
+ 3, /* CUPS_CSPACE_YMC */
+ 4, /* CUPS_CSPACE_CMYK */
+ 4, /* CUPS_CSPACE_YMCK */
+ 4, /* CUPS_CSPACE_KCMY */
+ 6, /* CUPS_CSPACE_KCMYcm */
+ 4, /* CUPS_CSPACE_GMCK */
+ 4, /* CUPS_CSPACE_GMCS */
+ 1, /* CUPS_CSPACE_WHITE */
+ 1, /* CUPS_CSPACE_GOLD */
+ 1, /* CUPS_CSPACE_SILVER */
+ 3, /* CUPS_CSPACE_CIEXYZ */
+ 3, /* CUPS_CSPACE_CIELab */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 0, /* ... reserved ... */
+ 1, /* CUPS_CSPACE_ICC1 */
+ 2, /* CUPS_CSPACE_ICC2 */
+ 3, /* CUPS_CSPACE_ICC3 */
+ 4, /* CUPS_CSPACE_ICC4 */
+ 5, /* CUPS_CSPACE_ICC5 */
+ 6, /* CUPS_CSPACE_ICC6 */
+ 7, /* CUPS_CSPACE_ICC7 */
+ 8, /* CUPS_CSPACE_ICC8 */
+ 9, /* CUPS_CSPACE_ICC9 */
+ 10, /* CUPS_CSPACE_ICCA */
+ 11, /* CUPS_CSPACE_ICCB */
+ 12, /* CUPS_CSPACE_ICCC */
+ 13, /* CUPS_CSPACE_ICCD */
+ 14, /* CUPS_CSPACE_ICCE */
+ 15 /* CUPS_CSPACE_ICCF */
+ };
+
+
+/*
+ * Local functions...
+ */
+
+static void exec_code(cups_page_header_t *header, const char *code);
+static void format_CMY(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1);
+static void format_CMYK(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1);
+static void format_K(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1);
+static void format_KCMYcm(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1);
+static void format_KCMY(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1);
+#define format_RGB format_CMY
+static void format_RGBA(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1);
+static void format_W(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1);
+static void format_YMC(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1);
+static void format_YMCK(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1);
+static void make_lut(ib_t *, int, float, float);
+
+
+/*
+ * 'main()' - Main entry...
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ image_t *img; /* Image to print */
+ float xprint, /* Printable area */
+ yprint,
+ xinches, /* Total size in inches */
+ yinches;
+ float xsize, /* Total size in points */
+ ysize,
+ xsize2,
+ ysize2;
+ float aspect; /* Aspect ratio */
+ int xpages, /* # x pages */
+ ypages, /* # y pages */
+ xpage, /* Current x page */
+ ypage, /* Current y page */
+ xtemp, /* Bitmap width in pixels */
+ ytemp, /* Bitmap height in pixels */
+ page; /* Current page number */
+ int x0, y0, /* Corners of the page in image coords */
+ x1, y1;
+ ppd_file_t *ppd; /* PPD file */
+ ppd_choice_t *choice, /* PPD option choice */
+ **choices; /* List of marked choices */
+ int count; /* Number of marked choices */
+ char *resolution, /* Output resolution */
+ *media_type; /* Media type */
+ ppd_profile_t *profile; /* Color profile */
+ ppd_profile_t userprofile; /* User-specified profile */
+ cups_raster_t *ras; /* Raster stream */
+ cups_page_header_t header; /* Page header */
+ int num_options; /* Number of print options */
+ cups_option_t *options; /* Print options */
+ const char *val; /* Option value */
+ int slowcollate, /* Collate copies the slow way */
+ slowcopies; /* Make copies the "slow" way? */
+ float g; /* Gamma correction value */
+ float b; /* Brightness factor */
+ float zoom; /* Zoom facter */
+ int xppi, yppi; /* Pixels-per-inch */
+ int hue, sat; /* Hue and saturation adjustment */
+ izoom_t *z; /* ImageZoom buffer */
+ int primary, /* Primary image colorspace */
+ secondary; /* Secondary image colorspace */
+ ib_t *row, /* Current row */
+ *r0, /* Top row */
+ *r1; /* Bottom row */
+ int y, /* Current Y coordinate on page */
+ iy, /* Current Y coordinate in image */
+ last_iy, /* Previous Y coordinate in image */
+ yerr0, /* Top Y error value */
+ yerr1, /* Bottom Y error value */
+ blank; /* Blank value */
+ ib_t lut[256]; /* Gamma/brightness LUT */
+ int plane, /* Current color plane */
+ num_planes; /* Number of color planes */
+ char filename[1024]; /* Name of file to print */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fputs("ERROR: imagetoraster job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ fprintf(stderr, "INFO: %s %s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5], argv[6] ? argv[6] : "(null)");
+
+ /*
+ * See if we need to use the imagetops and pstoraster filters instead...
+ */
+
+ options = NULL;
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ if (getenv("CLASSIFICATION") ||
+ cupsGetOption("page-label", num_options, options))
+ {
+ /*
+ * Yes, fork a copy of pstoraster and then transfer control to imagetops...
+ */
+
+ int mypipes[2]; /* New pipes for imagetops | pstoraster */
+ int pid; /* PID of pstoraster */
+
+
+ cupsFreeOptions(num_options, options);
+
+ if (pipe(mypipes))
+ {
+ perror("ERROR: Unable to create pipes for imagetops | pstoraster");
+ return (errno);
+ }
+
+ if ((pid = fork()) == 0)
+ {
+ /*
+ * Child process for pstoraster... Assign new pipe input to pstoraster...
+ */
+
+ close(0);
+ dup(mypipes[0]);
+ close(mypipes[0]);
+ close(mypipes[1]);
+
+ execlp("pstoraster", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
+ NULL);
+ perror("ERROR: Unable to exec pstoraster");
+ return (errno);
+ }
+ else if (pid < 0)
+ {
+ /*
+ * Error!
+ */
+
+ perror("ERROR: Unable to fork pstoraster");
+ return (errno);
+ }
+
+ /*
+ * Update stdout so it points at the new pstoraster...
+ */
+
+ close(1);
+ dup(mypipes[1]);
+ close(mypipes[0]);
+ close(mypipes[1]);
+
+ /*
+ * Run imagetops to get the classification or page labelling that was
+ * requested...
+ */
+
+ execlp("imagetops", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
+ argv[6], NULL);
+ perror("ERROR: Unable to exec imagetops");
+ return (errno);
+ }
+
+ /*
+ * Copy stdin as needed...
+ */
+
+ if (argc == 6)
+ {
+ int fd; /* File to write to */
+ char buffer[8192]; /* Buffer to read into */
+ int bytes; /* # of bytes to read */
+
+
+ if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
+ {
+ perror("ERROR: Unable to copy image file");
+ return (1);
+ }
+
+ fprintf(stderr, "DEBUG: imagetoraster - copying to temp print file \"%s\"\n",
+ filename);
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ write(fd, buffer, bytes);
+
+ close(fd);
+ }
+ else
+ strlcpy(filename, argv[6], sizeof(filename));
+
+ /*
+ * Process command-line options and write the prolog...
+ */
+
+ zoom = 0.0;
+ xppi = 0;
+ yppi = 0;
+ hue = 0;
+ sat = 100;
+ g = 1.0;
+ b = 1.0;
+
+ Copies = atoi(argv[4]);
+
+ ppd = SetCommonOptions(num_options, options, 0);
+
+ if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL)
+ {
+ /*
+ * This IPP attribute is unnecessarily complicated...
+ *
+ * single-document, separate-documents-collated-copies, and
+ * single-document-new-sheet all require collated copies.
+ *
+ * separate-documents-collated-copies allows for uncollated copies.
+ */
+
+ Collate = strcasecmp(val, "separate-documents-collated-copies") != 0;
+ }
+
+ if ((val = cupsGetOption("Collate", num_options, options)) != NULL &&
+ strcasecmp(val, "True") == 0)
+ Collate = 1;
+
+ if ((val = cupsGetOption("gamma", num_options, options)) != NULL)
+ g = atoi(val) * 0.001f;
+
+ if ((val = cupsGetOption("brightness", num_options, options)) != NULL)
+ b = atoi(val) * 0.01f;
+
+ if ((val = cupsGetOption("scaling", num_options, options)) != NULL)
+ zoom = atoi(val) * 0.01;
+
+ if ((val = cupsGetOption("ppi", num_options, options)) != NULL)
+ if (sscanf(val, "%dx%d", &xppi, &yppi) < 2)
+ yppi = xppi;
+
+ if ((val = cupsGetOption("position", num_options, options)) != NULL)
+ {
+ if (strcasecmp(val, "center") == 0)
+ {
+ XPosition = 0;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "top") == 0)
+ {
+ XPosition = 0;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "left") == 0)
+ {
+ XPosition = -1;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "right") == 0)
+ {
+ XPosition = 1;
+ YPosition = 0;
+ }
+ else if (strcasecmp(val, "top-left") == 0)
+ {
+ XPosition = -1;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "top-right") == 0)
+ {
+ XPosition = 1;
+ YPosition = 1;
+ }
+ else if (strcasecmp(val, "bottom") == 0)
+ {
+ XPosition = 0;
+ YPosition = -1;
+ }
+ else if (strcasecmp(val, "bottom-left") == 0)
+ {
+ XPosition = -1;
+ YPosition = -1;
+ }
+ else if (strcasecmp(val, "bottom-right") == 0)
+ {
+ XPosition = 1;
+ YPosition = -1;
+ }
+ }
+
+ if ((val = cupsGetOption("saturation", num_options, options)) != NULL)
+ sat = atoi(val);
+
+ if ((val = cupsGetOption("hue", num_options, options)) != NULL)
+ hue = atoi(val);
+
+ if ((val = cupsGetOption("mirror", num_options, options)) != NULL &&
+ strcasecmp(val, "True") == 0)
+ Flip = 1;
+
+ /*
+ * Set the needed options in the page header...
+ */
+
+ memset(&header, 0, sizeof(header));
+ header.HWResolution[0] = 100;
+ header.HWResolution[1] = 100;
+ header.cupsBitsPerColor = 1;
+ header.cupsColorOrder = CUPS_ORDER_CHUNKED;
+ header.cupsColorSpace = CUPS_CSPACE_K;
+
+ if (ppd && ppd->patches)
+ exec_code(&header, ppd->patches);
+
+ if ((count = ppdCollect(ppd, PPD_ORDER_DOCUMENT, &choices)) > 0)
+ for (i = 0; i < count; i ++)
+ exec_code(&header, choices[i]->code);
+
+ if ((count = ppdCollect(ppd, PPD_ORDER_ANY, &choices)) > 0)
+ for (i = 0; i < count; i ++)
+ exec_code(&header, choices[i]->code);
+
+ if ((count = ppdCollect(ppd, PPD_ORDER_PROLOG, &choices)) > 0)
+ for (i = 0; i < count; i ++)
+ exec_code(&header, choices[i]->code);
+
+ if ((count = ppdCollect(ppd, PPD_ORDER_PAGE, &choices)) > 0)
+ for (i = 0; i < count; i ++)
+ exec_code(&header, choices[i]->code);
+
+ /*
+ * Get the media type and resolution that have been chosen...
+ */
+
+ if ((choice = ppdFindMarkedChoice(ppd, "MediaType")) != NULL)
+ media_type = choice->choice;
+ else
+ media_type = "";
+
+ if ((choice = ppdFindMarkedChoice(ppd, "Resolution")) != NULL)
+ resolution = choice->choice;
+ else
+ resolution = "";
+
+ /*
+ * Choose the appropriate colorspace...
+ */
+
+ switch (header.cupsColorSpace)
+ {
+ case CUPS_CSPACE_W :
+ primary = IMAGE_WHITE;
+ secondary = IMAGE_WHITE;
+ header.cupsBitsPerPixel = header.cupsBitsPerColor;
+ break;
+
+ default :
+ case CUPS_CSPACE_RGB :
+ case CUPS_CSPACE_RGBA :
+ primary = IMAGE_RGB;
+ secondary = IMAGE_RGB;
+
+ if (header.cupsColorOrder == CUPS_ORDER_CHUNKED)
+ {
+ if (header.cupsBitsPerColor >= 8)
+ header.cupsBitsPerPixel = header.cupsBitsPerColor * 3;
+ else
+ header.cupsBitsPerPixel = header.cupsBitsPerColor * 4;
+ }
+ else
+ header.cupsBitsPerPixel = header.cupsBitsPerColor;
+ break;
+
+ case CUPS_CSPACE_K :
+ case CUPS_CSPACE_WHITE :
+ case CUPS_CSPACE_GOLD :
+ case CUPS_CSPACE_SILVER :
+ primary = IMAGE_BLACK;
+ secondary = IMAGE_BLACK;
+ header.cupsBitsPerPixel = header.cupsBitsPerColor;
+ break;
+
+ case CUPS_CSPACE_CMYK :
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_KCMY :
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ primary = IMAGE_CMYK;
+ secondary = IMAGE_CMYK;
+
+ if (header.cupsColorOrder == CUPS_ORDER_CHUNKED)
+ header.cupsBitsPerPixel = header.cupsBitsPerColor * 4;
+ else
+ header.cupsBitsPerPixel = header.cupsBitsPerColor;
+ break;
+
+ case CUPS_CSPACE_CMY :
+ case CUPS_CSPACE_YMC :
+ primary = IMAGE_CMY;
+ secondary = IMAGE_CMY;
+
+ if (header.cupsColorOrder == CUPS_ORDER_CHUNKED)
+ {
+ if (header.cupsBitsPerColor >= 8)
+ header.cupsBitsPerPixel = 24;
+ else
+ header.cupsBitsPerPixel = header.cupsBitsPerColor * 4;
+ }
+ else
+ header.cupsBitsPerPixel = header.cupsBitsPerColor;
+ break;
+
+ case CUPS_CSPACE_KCMYcm :
+ if (header.cupsBitsPerPixel == 1)
+ {
+ primary = IMAGE_CMY;
+ secondary = IMAGE_CMY;
+
+ if (header.cupsColorOrder == CUPS_ORDER_CHUNKED)
+ header.cupsBitsPerPixel = 8;
+ else
+ header.cupsBitsPerPixel = 1;
+ }
+ else
+ {
+ primary = IMAGE_CMYK;
+ secondary = IMAGE_CMYK;
+
+ if (header.cupsColorOrder == CUPS_ORDER_CHUNKED)
+ header.cupsBitsPerPixel = header.cupsBitsPerColor * 4;
+ else
+ header.cupsBitsPerPixel = header.cupsBitsPerColor;
+ }
+ break;
+ }
+
+ /*
+ * Find a color profile matching the current options...
+ */
+
+ if ((val = cupsGetOption("profile", num_options, options)) != NULL)
+ {
+ profile = &userprofile;
+ sscanf(val, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
+ &(userprofile.density), &(userprofile.gamma),
+ userprofile.matrix[0] + 0, userprofile.matrix[0] + 1,
+ userprofile.matrix[0] + 2,
+ userprofile.matrix[1] + 0, userprofile.matrix[1] + 1,
+ userprofile.matrix[1] + 2,
+ userprofile.matrix[2] + 0, userprofile.matrix[2] + 1,
+ userprofile.matrix[2] + 2);
+
+ userprofile.density *= 0.001f;
+ userprofile.gamma *= 0.001f;
+ userprofile.matrix[0][0] *= 0.001f;
+ userprofile.matrix[0][1] *= 0.001f;
+ userprofile.matrix[0][2] *= 0.001f;
+ userprofile.matrix[1][0] *= 0.001f;
+ userprofile.matrix[1][1] *= 0.001f;
+ userprofile.matrix[1][2] *= 0.001f;
+ userprofile.matrix[2][0] *= 0.001f;
+ userprofile.matrix[2][1] *= 0.001f;
+ userprofile.matrix[2][2] *= 0.001f;
+ }
+ else if (ppd != NULL)
+ {
+ fprintf(stderr, "DEBUG: Searching for profile \"%s/%s\"...\n",
+ resolution, media_type);
+
+ for (i = 0, profile = ppd->profiles; i < ppd->num_profiles; i ++, profile ++)
+ {
+ fprintf(stderr, "DEBUG: \"%s/%s\" = ", profile->resolution,
+ profile->media_type);
+
+ if ((strcmp(profile->resolution, resolution) == 0 ||
+ profile->resolution[0] == '-') &&
+ (strcmp(profile->media_type, media_type) == 0 ||
+ profile->media_type[0] == '-'))
+ {
+ fputs("MATCH!\n", stderr);
+ break;
+ }
+ else
+ fputs("no.\n", stderr);
+ }
+
+ /*
+ * If we found a color profile, use it!
+ */
+
+ if (i >= ppd->num_profiles)
+ profile = NULL;
+ }
+ else
+ profile = NULL;
+
+ if (profile)
+ ImageSetProfile(profile->density, profile->gamma, profile->matrix);
+
+ ImageSetColorSpace(header.cupsColorSpace);
+
+ /*
+ * Create a gamma/brightness LUT...
+ */
+
+ make_lut(lut, primary, g, b);
+
+ /*
+ * Open the input image to print...
+ */
+
+ fputs("INFO: Loading image file...\n", stderr);
+
+ img = ImageOpen(filename, primary, secondary, sat, hue, lut);
+
+ if (argc == 6)
+ unlink(filename);
+
+ if (img == NULL)
+ {
+ fputs("ERROR: Unable to open image file for printing!\n", stderr);
+ ppdClose(ppd);
+ return (1);
+ }
+
+ /*
+ * Scale as necessary...
+ */
+
+ if (zoom == 0.0 && xppi == 0)
+ {
+ xppi = img->xppi;
+ yppi = img->yppi;
+ }
+
+ if (yppi == 0)
+ yppi = xppi;
+
+ if (xppi > 0)
+ {
+ /*
+ * Scale the image as neccesary to match the desired pixels-per-inch.
+ */
+
+ if (Orientation & 1)
+ {
+ xprint = (PageTop - PageBottom) / 72.0;
+ yprint = (PageRight - PageLeft) / 72.0;
+ }
+ else
+ {
+ xprint = (PageRight - PageLeft) / 72.0;
+ yprint = (PageTop - PageBottom) / 72.0;
+ }
+
+ xinches = (float)img->xsize / (float)xppi;
+ yinches = (float)img->ysize / (float)yppi;
+
+ if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
+ {
+ xinches = xinches * atoi(val) / 100;
+ yinches = yinches * atoi(val) / 100;
+ }
+
+ if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
+ cupsGetOption("landscape", num_options, options) == NULL)
+ {
+ /*
+ * Rotate the image if it will fit landscape but not portrait...
+ */
+
+ if ((xinches > xprint || yinches > yprint) &&
+ xinches <= yprint && yinches <= xprint)
+ {
+ /*
+ * Rotate the image as needed...
+ */
+
+ Orientation = (Orientation + 1) & 3;
+ xsize = yprint;
+ yprint = xprint;
+ xprint = xsize;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Scale percentage of page size...
+ */
+
+ xprint = (PageRight - PageLeft) / 72.0;
+ yprint = (PageTop - PageBottom) / 72.0;
+ aspect = (float)img->yppi / (float)img->xppi;
+
+ fprintf(stderr, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
+ img->xppi, img->yppi, aspect);
+
+ xsize = xprint * zoom;
+ ysize = xsize * img->ysize / img->xsize / aspect;
+
+ if (ysize > (yprint * zoom))
+ {
+ ysize = yprint * zoom;
+ xsize = ysize * img->xsize * aspect / img->ysize;
+ }
+
+ xsize2 = yprint * zoom;
+ ysize2 = xsize2 * img->ysize / img->xsize / aspect;
+
+ if (ysize2 > (xprint * zoom))
+ {
+ ysize2 = xprint * zoom;
+ xsize2 = ysize2 * img->xsize * aspect / img->ysize;
+ }
+
+ fprintf(stderr, "DEBUG: xsize = %.0f, ysize = %.0f\n", xsize, ysize);
+ fprintf(stderr, "DEBUG: xsize2 = %.0f, ysize2 = %.0f\n", xsize2, ysize2);
+
+ if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
+ cupsGetOption("landscape", num_options, options) == NULL)
+ {
+ /*
+ * Choose the rotation with the largest area, but prefer
+ * portrait if they are equal...
+ */
+
+ if ((xsize * ysize) < (xsize2 * xsize2))
+ {
+ /*
+ * Do landscape orientation...
+ */
+
+ Orientation = 1;
+ xinches = xsize2;
+ yinches = ysize2;
+ xprint = (PageTop - PageBottom) / 72.0;
+ yprint = (PageRight - PageLeft) / 72.0;
+ }
+ else
+ {
+ /*
+ * Do portrait orientation...
+ */
+
+ Orientation = 0;
+ xinches = xsize;
+ yinches = ysize;
+ }
+ }
+ else if (Orientation & 1)
+ {
+ xinches = xsize2;
+ yinches = ysize2;
+ xprint = (PageTop - PageBottom) / 72.0;
+ yprint = (PageRight - PageLeft) / 72.0;
+
+ xsize = PageLeft;
+ PageLeft = PageBottom;
+ PageBottom = PageWidth - PageRight;
+ PageRight = PageTop;
+ PageTop = PageLength - xsize;
+
+ xsize = PageWidth;
+ PageWidth = PageLength;
+ PageLength = xsize;
+ }
+ else
+ {
+ xinches = xsize;
+ yinches = ysize;
+ xprint = (PageRight - PageLeft) / 72.0;
+ yprint = (PageTop - PageBottom) / 72.0;
+ }
+ }
+
+ xpages = ceil(xinches / xprint);
+ ypages = ceil(yinches / yprint);
+
+ fprintf(stderr, "DEBUG: xpages = %d, ypages = %d\n", xpages, ypages);
+
+ /*
+ * Compute the bitmap size...
+ */
+
+ xprint = xinches / xpages;
+ yprint = yinches / ypages;
+
+ if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL &&
+ strcasecmp(choice->choice, "Custom") == 0)
+ {
+ float width, /* New width in points */
+ length; /* New length in points */
+
+
+ if (Orientation & 1)
+ {
+ width = yprint * 72.0;
+ length = xprint * 72.0;
+ }
+ else
+ {
+ width = xprint * 72.0;
+ length = yprint * 72.0;
+ }
+
+ /*
+ * Add margins to page size...
+ */
+
+ width += ppd->custom_margins[0] + ppd->custom_margins[2];
+ length += ppd->custom_margins[1] + ppd->custom_margins[3];
+
+ /*
+ * Enforce minimums...
+ */
+
+ if (width < ppd->custom_min[0])
+ width = ppd->custom_min[0];
+
+ if (length < ppd->custom_min[1])
+ length = ppd->custom_min[1];
+
+ /*
+ * Set the new custom size...
+ */
+
+ header.PageSize[0] = width + 0.5;
+ header.PageSize[1] = length + 0.5;
+
+ /*
+ * Update page variables...
+ */
+
+ PageWidth = width;
+ PageLength = length;
+ PageLeft = ppd->custom_margins[0];
+ PageRight = width - ppd->custom_margins[2];
+ PageBottom = ppd->custom_margins[1];
+ PageTop = length - ppd->custom_margins[3];
+
+ /*
+ * Remove margins from page size...
+ */
+
+ width -= ppd->custom_margins[0] + ppd->custom_margins[2];
+ length -= ppd->custom_margins[1] + ppd->custom_margins[3];
+
+ /*
+ * Set the bitmap size...
+ */
+
+ header.cupsWidth = width * header.HWResolution[0] / 72.0;
+ header.cupsHeight = length * header.HWResolution[1] / 72.0;
+ }
+ else
+ {
+ header.cupsWidth = (PageRight - PageLeft) * header.HWResolution[0] / 72.0;
+ header.cupsHeight = (PageTop - PageBottom) * header.HWResolution[1] / 72.0;
+ header.PageSize[0] = PageWidth;
+ header.PageSize[1] = PageLength;
+ }
+
+ header.Margins[0] = PageLeft;
+ header.Margins[1] = PageBottom;
+
+ fprintf(stderr, "DEBUG: PageSize = [%d %d]\n", header.PageSize[0],
+ header.PageSize[1]);
+
+ switch (Orientation)
+ {
+ case 0 :
+ switch (XPosition)
+ {
+ case -1 :
+ header.ImagingBoundingBox[0] = PageLeft;
+ header.ImagingBoundingBox[2] = PageLeft + xprint * 72;
+ break;
+ default :
+ header.ImagingBoundingBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
+ header.ImagingBoundingBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
+ break;
+ case 1 :
+ header.ImagingBoundingBox[0] = PageRight - xprint * 72;
+ header.ImagingBoundingBox[2] = PageRight;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case -1 :
+ header.ImagingBoundingBox[1] = PageBottom;
+ header.ImagingBoundingBox[3] = PageBottom + yprint * 72;
+ break;
+ default :
+ header.ImagingBoundingBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
+ header.ImagingBoundingBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
+ break;
+ case 1 :
+ header.ImagingBoundingBox[1] = PageTop - yprint * 72;
+ header.ImagingBoundingBox[3] = PageTop;
+ break;
+ }
+ break;
+
+ case 1 :
+ switch (XPosition)
+ {
+ case -1 :
+ header.ImagingBoundingBox[0] = PageBottom;
+ header.ImagingBoundingBox[2] = PageBottom + yprint * 72;
+ break;
+ default :
+ header.ImagingBoundingBox[0] = (PageTop + PageBottom - yprint * 72) / 2;
+ header.ImagingBoundingBox[2] = (PageTop + PageBottom + yprint * 72) / 2;
+ break;
+ case 1 :
+ header.ImagingBoundingBox[0] = PageTop - yprint * 72;
+ header.ImagingBoundingBox[2] = PageTop;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case -1 :
+ header.ImagingBoundingBox[1] = PageLeft;
+ header.ImagingBoundingBox[3] = PageLeft + xprint * 72;
+ break;
+ default :
+ header.ImagingBoundingBox[1] = (PageRight + PageLeft - xprint * 72) / 2;
+ header.ImagingBoundingBox[3] = (PageRight + PageLeft + xprint * 72) / 2;
+ break;
+ case 1 :
+ header.ImagingBoundingBox[1] = PageRight - xprint * 72;
+ header.ImagingBoundingBox[3] = PageRight;
+ break;
+ }
+ break;
+
+ case 2 :
+ switch (XPosition)
+ {
+ case 1 :
+ header.ImagingBoundingBox[0] = PageLeft;
+ header.ImagingBoundingBox[2] = PageLeft + xprint * 72;
+ break;
+ default :
+ header.ImagingBoundingBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
+ header.ImagingBoundingBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
+ break;
+ case -1 :
+ header.ImagingBoundingBox[0] = PageRight - xprint * 72;
+ header.ImagingBoundingBox[2] = PageRight;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case 1 :
+ header.ImagingBoundingBox[1] = PageBottom;
+ header.ImagingBoundingBox[3] = PageBottom + yprint * 72;
+ break;
+ default :
+ header.ImagingBoundingBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
+ header.ImagingBoundingBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
+ break;
+ case -1 :
+ header.ImagingBoundingBox[1] = PageTop - yprint * 72;
+ header.ImagingBoundingBox[3] = PageTop;
+ break;
+ }
+ break;
+
+ case 3 :
+ switch (XPosition)
+ {
+ case 1 :
+ header.ImagingBoundingBox[0] = PageBottom;
+ header.ImagingBoundingBox[2] = PageBottom + yprint * 72;
+ break;
+ default :
+ header.ImagingBoundingBox[0] = (PageTop + PageBottom - yprint * 72) / 2;
+ header.ImagingBoundingBox[2] = (PageTop + PageBottom + yprint * 72) / 2;
+ break;
+ case -1 :
+ header.ImagingBoundingBox[0] = PageTop - yprint * 72;
+ header.ImagingBoundingBox[2] = PageTop;
+ break;
+ }
+
+ switch (YPosition)
+ {
+ case 1 :
+ header.ImagingBoundingBox[1] = PageLeft;
+ header.ImagingBoundingBox[3] = PageLeft + xprint * 72;
+ break;
+ default :
+ header.ImagingBoundingBox[1] = (PageRight + PageLeft - xprint * 72) / 2;
+ header.ImagingBoundingBox[3] = (PageRight + PageLeft + xprint * 72) / 2;
+ break;
+ case -1 :
+ header.ImagingBoundingBox[1] = PageRight - xprint * 72;
+ header.ImagingBoundingBox[3] = PageRight;
+ break;
+ }
+ break;
+ }
+
+ switch (header.cupsColorOrder)
+ {
+ default :
+ header.cupsBytesPerLine = (header.cupsBitsPerPixel *
+ header.cupsWidth + 7) / 8;
+ num_planes = 1;
+ break;
+
+ case CUPS_ORDER_BANDED :
+ if (header.cupsColorSpace == CUPS_CSPACE_KCMYcm &&
+ header.cupsBitsPerColor > 1)
+ header.cupsBytesPerLine = (header.cupsBitsPerPixel *
+ header.cupsWidth + 7) / 8 * 4;
+ else
+ header.cupsBytesPerLine = (header.cupsBitsPerPixel *
+ header.cupsWidth + 7) / 8 *
+ Planes[header.cupsColorSpace];
+ num_planes = 1;
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ header.cupsBytesPerLine = (header.cupsBitsPerPixel *
+ header.cupsWidth + 7) / 8;
+ num_planes = Planes[header.cupsColorSpace];
+ break;
+ }
+
+ /*
+ * See if we need to collate, and if so how we need to do it...
+ */
+
+ if (xpages == 1 && ypages == 1)
+ Collate = 0;
+
+ slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL;
+ if (ppd != NULL)
+ slowcopies = ppd->manual_copies;
+ else
+ slowcopies = 1;
+
+ if (Copies > 1 && !slowcollate && !slowcopies)
+ {
+ header.Collate = (cups_bool_t)Collate;
+ header.NumCopies = Copies;
+
+ Copies = 1;
+ }
+ else
+ header.NumCopies = 1;
+
+ /*
+ * Create the dithering lookup tables...
+ */
+
+ OnPixels[0] = 0x00;
+ OnPixels[255] = 0xff;
+ OffPixels[0] = 0x00;
+ OffPixels[255] = 0xff;
+
+ switch (header.cupsBitsPerColor)
+ {
+ case 2 :
+ for (i = 1; i < 255; i ++)
+ {
+ OnPixels[i] = 0x55 * (i / 85 + 1);
+ OffPixels[i] = 0x55 * (i / 64);
+ }
+ break;
+ case 4 :
+ for (i = 1; i < 255; i ++)
+ {
+ OnPixels[i] = 17 * (i / 17 + 1);
+ OffPixels[i] = 17 * (i / 16);
+ }
+
+ OnPixels[255] = OffPixels[255] = 0xff;
+ break;
+ }
+
+ /*
+ * Output the pages...
+ */
+
+ fprintf(stderr, "DEBUG: cupsWidth = %d\n", header.cupsWidth);
+ fprintf(stderr, "DEBUG: cupsHeight = %d\n", header.cupsHeight);
+ fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header.cupsBitsPerColor);
+ fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header.cupsBitsPerPixel);
+ fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header.cupsBytesPerLine);
+ fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header.cupsColorOrder);
+ fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header.cupsColorSpace);
+ fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace);
+
+ row = malloc(2 * header.cupsBytesPerLine);
+ ras = cupsRasterOpen(1, CUPS_RASTER_WRITE);
+ blank = img->colorspace < 0 ? 0 : ~0;
+
+ for (i = 0, page = 1; i < Copies; i ++)
+ for (xpage = 0; xpage < xpages; xpage ++)
+ for (ypage = 0; ypage < ypages; ypage ++, page ++)
+ {
+ fprintf(stderr, "INFO: Formatting page %d...\n", page);
+
+ if (Orientation & 1)
+ {
+ x0 = img->xsize * ypage / ypages;
+ x1 = img->xsize * (ypage + 1) / ypages - 1;
+ y0 = img->ysize * xpage / xpages;
+ y1 = img->ysize * (xpage + 1) / xpages - 1;
+
+ xtemp = header.HWResolution[0] * yprint;
+ ytemp = header.HWResolution[1] * xprint;
+ }
+ else
+ {
+ x0 = img->xsize * xpage / xpages;
+ x1 = img->xsize * (xpage + 1) / xpages - 1;
+ y0 = img->ysize * ypage / ypages;
+ y1 = img->ysize * (ypage + 1) / ypages - 1;
+
+ xtemp = header.HWResolution[0] * xprint;
+ ytemp = header.HWResolution[1] * yprint;
+ }
+
+ cupsRasterWriteHeader(ras, &header);
+
+ for (plane = 0; plane < num_planes; plane ++)
+ {
+ /*
+ * Initialize the image "zoom" engine...
+ */
+
+ if (Flip)
+ z = ImageZoomAlloc(img, x0, y0, x1, y1, -xtemp, ytemp,
+ Orientation & 1);
+ else
+ z = ImageZoomAlloc(img, x0, y0, x1, y1, xtemp, ytemp,
+ Orientation & 1);
+
+ /*
+ * Write leading blank space as needed...
+ */
+
+ if (header.cupsHeight > z->ysize && YPosition <= 0)
+ {
+ memset(row, blank, header.cupsBytesPerLine);
+
+ y = header.cupsHeight - z->ysize;
+ if (YPosition == 0)
+ y /= 2;
+
+ for (; y > 0; y --)
+ {
+ if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
+ header.cupsBytesPerLine)
+ {
+ fputs("ERROR: Unable to write raster data to driver!\n", stderr);
+ ImageClose(img);
+ exit(1);
+ }
+ }
+ }
+
+ /*
+ * Then write image data...
+ */
+
+ for (y = z->ysize, yerr0 = 0, yerr1 = z->ysize, iy = 0, last_iy = -2;
+ y > 0;
+ y --)
+ {
+ if (iy != last_iy)
+ {
+ if (header.cupsBitsPerColor >= 8)
+ {
+ /*
+ * Do bilinear interpolation for 8+ bpp images...
+ */
+
+ if ((iy - last_iy) > 1)
+ ImageZoomFill(z, iy);
+
+ ImageZoomFill(z, iy + z->yincr);
+ }
+ else
+ {
+ /*
+ * Just do nearest-neighbor sampling for < 8 bpp images...
+ */
+
+ ImageZoomQFill(z, iy);
+ }
+
+ last_iy = iy;
+ }
+
+ /*
+ * Format this line of raster data for the printer...
+ */
+
+ memset(row, blank, header.cupsBytesPerLine);
+
+ r0 = z->rows[z->row];
+ r1 = z->rows[1 - z->row];
+
+ switch (header.cupsColorSpace)
+ {
+ case CUPS_CSPACE_W :
+ format_W(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ default :
+ case CUPS_CSPACE_RGB :
+ format_RGB(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_RGBA :
+ format_RGBA(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_K :
+ case CUPS_CSPACE_WHITE :
+ case CUPS_CSPACE_GOLD :
+ case CUPS_CSPACE_SILVER :
+ format_K(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_CMY :
+ format_CMY(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_YMC :
+ format_YMC(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_CMYK :
+ format_CMYK(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ format_YMCK(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_KCMY :
+ format_KCMY(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ case CUPS_CSPACE_KCMYcm :
+ format_KCMYcm(&header, row, y, plane, z->xsize, z->ysize,
+ yerr0, yerr1, r0, r1);
+ break;
+ }
+
+ /*
+ * Write the raster data to the driver...
+ */
+
+ if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
+ header.cupsBytesPerLine)
+ {
+ fputs("ERROR: Unable to write raster data to driver!\n", stderr);
+ ImageClose(img);
+ exit(1);
+ }
+
+ /*
+ * Compute the next scanline in the image...
+ */
+
+ iy += z->ystep;
+ yerr0 += z->ymod;
+ yerr1 -= z->ymod;
+ if (yerr1 <= 0)
+ {
+ yerr0 -= z->ysize;
+ yerr1 += z->ysize;
+ iy += z->yincr;
+ }
+ }
+
+ /*
+ * Write trailing blank space as needed...
+ */
+
+ if (header.cupsHeight > z->ysize && YPosition >= 0)
+ {
+ memset(row, blank, header.cupsBytesPerLine);
+
+ y = header.cupsHeight - z->ysize;
+ if (YPosition == 0)
+ y = y - y / 2;
+
+ for (; y > 0; y --)
+ {
+ if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
+ header.cupsBytesPerLine)
+ {
+ fputs("ERROR: Unable to write raster data to driver!\n", stderr);
+ ImageClose(img);
+ exit(1);
+ }
+ }
+ }
+
+ /*
+ * Free memory used for the "zoom" engine...
+ */
+
+ ImageZoomFree(z);
+ }
+ }
+
+ /*
+ * Close files...
+ */
+
+ free(row);
+ cupsRasterClose(ras);
+ ImageClose(img);
+ ppdClose(ppd);
+
+ return (0);
+}
+
+
+/*
+ * 'exec_code()' - Execute PostScript setpagedevice commands as appropriate.
+ */
+
+static void
+exec_code(cups_page_header_t *header, /* I - Page header */
+ const char *code) /* I - Option choice to execute */
+{
+ char *ptr, /* Pointer into name/value string */
+ name[255], /* Name of pagedevice entry */
+ value[1024]; /* Value of pagedevice entry */
+
+
+ for (; *code != '\0';)
+ {
+ /*
+ * Search for the start of a dictionary name...
+ */
+
+ while (*code != '/' && *code != '\0')
+ code ++;
+
+ if (*code == '\0')
+ break;
+
+ /*
+ * Get the name...
+ */
+
+ code ++;
+ for (ptr = name; isalnum(*code) && (ptr - name) < (sizeof(name) - 1);)
+ *ptr++ = *code++;
+ *ptr = '\0';
+
+ /*
+ * The parse the value as needed...
+ */
+
+ while (isspace(*code))
+ code ++;
+
+ if (*code == '\0')
+ break;
+
+ if (*code == '[')
+ {
+ /*
+ * Read array of values...
+ */
+
+ code ++;
+ for (ptr = value;
+ *code != ']' && *code != '\0' &&
+ (ptr - value) < (sizeof(value) - 1);)
+ *ptr++ = *code++;
+ *ptr = '\0';
+ }
+ else if (*code == '(')
+ {
+ /*
+ * Read string value...
+ */
+
+ code ++;
+ for (ptr = value;
+ *code != ')' && *code != '\0' &&
+ (ptr - value) < (sizeof(value) - 1);)
+ if (*code == '\\')
+ {
+ code ++;
+ if (isdigit(*code))
+ *ptr++ = (char)strtol(code, (char **)&code, 8);
+ else
+ *ptr++ = *code++;
+ }
+ else
+ *ptr++ = *code++;
+
+ *ptr = '\0';
+ }
+ else if (isdigit(*code) || *code == '-')
+ {
+ /*
+ * Read single number...
+ */
+
+ for (ptr = value;
+ (isdigit(*code) || *code == '-') &&
+ (ptr - value) < (sizeof(value) - 1);)
+ *ptr++ = *code++;
+ *ptr = '\0';
+ }
+ else
+ continue;
+
+ /*
+ * Assign the value as needed...
+ */
+
+ if (strcmp(name, "cupsMediaType") == 0)
+ header->cupsMediaType = atoi(value);
+ else if (strcmp(name, "cupsBitsPerColor") == 0)
+ header->cupsBitsPerColor = atoi(value);
+ else if (strcmp(name, "cupsColorOrder") == 0)
+ header->cupsColorOrder = (cups_order_t)atoi(value);
+ else if (strcmp(name, "cupsColorSpace") == 0)
+ header->cupsColorSpace = (cups_cspace_t)atoi(value);
+ else if (strcmp(name, "cupsCompression") == 0)
+ header->cupsCompression = atoi(value);
+ else if (strcmp(name, "cupsRowCount") == 0)
+ header->cupsRowCount = atoi(value);
+ else if (strcmp(name, "cupsRowFeed") == 0)
+ header->cupsRowFeed = atoi(value);
+ else if (strcmp(name, "cupsRowStep") == 0)
+ header->cupsRowStep = atoi(value);
+ else if (strcmp(name, "CutMedia") == 0)
+ header->CutMedia = (cups_cut_t)atoi(value);
+ else if (strcmp(name, "HWResolution") == 0)
+ sscanf(value, "%d%d", header->HWResolution + 0, header->HWResolution + 1);
+ else if (strcmp(name, "cupsMediaPosition") == 0 || /* Compatibility */
+ strcmp(name, "MediaPosition") == 0)
+ header->MediaPosition = atoi(value);
+ else if (strcmp(name, "MediaClass") == 0)
+ strlcpy(header->MediaClass, value, sizeof(header->MediaClass));
+ else if (strcmp(name, "MediaColor") == 0)
+ strlcpy(header->MediaColor, value, sizeof(header->MediaColor));
+ else if (strcmp(name, "MediaType") == 0)
+ strlcpy(header->MediaType, value, sizeof(header->MediaType));
+ else if (strcmp(name, "OutputType") == 0)
+ strlcpy(header->OutputType, value, sizeof(header->OutputType));
+ }
+}
+
+
+/*
+ * 'format_CMY()' - Convert image data to CMY.
+ */
+
+static void
+format_CMY(cups_page_header_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ ib_t *r0, /* I - Primary image data */
+ ib_t *r1) /* I - Image data for interpolation */
+{
+ ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 3;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 64 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 64;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[1]]);
+
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr++ ^= (0x03 & OnPixels[r0[2]]);
+ else
+ *ptr++ ^= (0x03 & OffPixels[r0[2]]);
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[0]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[0]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[1]]);
+
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[2]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[2]]);
+ }
+ break;
+
+ case 8 :
+ for (x = xsize * 3; x > 0; x --, r0 ++, r1 ++)
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ cptr = ptr;
+ mptr = ptr + bandwidth;
+ yptr = ptr + 2 * bandwidth;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *cptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *mptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *yptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ switch (z)
+ {
+ case 0 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[0] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 1 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[1] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[2] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ r0 += z;
+ r1 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_CMYK()' - Convert image data to CMYK.
+ */
+
+static void
+format_CMYK(cups_page_header_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ ib_t *r0, /* I - Primary image data */
+ ib_t *r1) /* I - Image data for interpolation */
+{
+ ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ *kptr, /* Pointer into black */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 4;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 128 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 128;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr ^= (0xc0 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0xc0 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[1]]);
+
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[2]]);
+
+ if ((r0[3] & 63) > dither[x & 7])
+ *ptr++ ^= (0x03 & OnPixels[r0[3]]);
+ else
+ *ptr++ ^= (0x03 & OffPixels[r0[3]]);
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[1]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[1]]);
+
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[2]]);
+
+ if ((r0[3] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[3]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[3]]);
+ }
+ break;
+
+ case 8 :
+ for (x = xsize * 4; x > 0; x --, r0 ++, r1 ++)
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ cptr = ptr;
+ mptr = ptr + bandwidth;
+ yptr = ptr + 2 * bandwidth;
+ kptr = ptr + 3 * bandwidth;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *cptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *mptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *yptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *kptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ if (r0[3] == r1[3])
+ *kptr++ = r0[3];
+ else
+ *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if (*r0 > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ r0 += z;
+ r1 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_K()' - Convert image data to black.
+ */
+
+static void
+format_K(cups_page_header_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ ib_t *r0, /* I - Primary image data */
+ ib_t *r1) /* I - Image data for interpolation */
+{
+ ib_t *ptr, /* Pointer into row */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ (void)z;
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 ++, r1 ++)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_KCMY()' - Convert image data to KCMY.
+ */
+
+static void
+format_KCMY(cups_page_header_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ ib_t *r0, /* I - Primary image data */
+ ib_t *r1) /* I - Image data for interpolation */
+{
+ ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ *kptr, /* Pointer into black */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 4;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 128 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if (r0[3] > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (r0[0] > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (r0[1] > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (r0[2] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 128;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[3] & 63) > dither[x & 7])
+ *ptr ^= (0xc0 & OnPixels[r0[3]]);
+ else
+ *ptr ^= (0xc0 & OffPixels[r0[3]]);
+
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[1]]);
+
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr++ ^= (0x03 & OnPixels[r0[2]]);
+ else
+ *ptr++ ^= (0x03 & OffPixels[r0[2]]);
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[3] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[3]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[3]]);
+
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[0]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[0]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[1]]);
+
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[2]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[2]]);
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[3] == r1[3])
+ *ptr++ = r0[3];
+ else
+ *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+
+ if (r0[0] == r1[0])
+ *ptr++ = r0[0];
+ else
+ *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *ptr++ = r0[1];
+ else
+ *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *ptr++ = r0[2];
+ else
+ *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ kptr = ptr;
+ cptr = ptr + bandwidth;
+ mptr = ptr + 2 * bandwidth;
+ yptr = ptr + 3 * bandwidth;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *cptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *mptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *yptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *kptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ if (r0[3] == r1[3])
+ *kptr++ = r0[3];
+ else
+ *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+ if (z == 0)
+ r0 += 3;
+ else
+ r0 += z - 1;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if (*r0 > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ if (z == 0)
+ r0 += 3;
+ else
+ r0 += z - 1;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ if (z == 0)
+ r0 += 3;
+ else
+ r0 += z - 1;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ if (z == 0)
+ {
+ r0 += 3;
+ r1 += 3;
+ }
+ else
+ {
+ r0 += z - 1;
+ r1 += z - 1;
+ }
+
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_KCMYcm()' - Convert image data to KCMYcm.
+ */
+
+static void
+format_KCMYcm(cups_page_header_t *header,/* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ ib_t *r0, /* I - Primary image data */
+ ib_t *r1) /* I - Image data for interpolation */
+{
+ int pc, pm, py, pk; /* Cyan, magenta, yellow, and black values */
+ ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ *kptr, /* Pointer into black */
+ *lcptr, /* Pointer into light cyan */
+ *lmptr, /* Pointer into light magenta */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ if (header->cupsBitsPerColor == 1)
+ bandwidth = header->cupsBytesPerLine / 6;
+ else
+ bandwidth = header->cupsBytesPerLine / 4;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+ pk = *r0++ > dither[x & 15];
+
+ if (pk)
+ *ptr++ ^= 32; /* Black */
+ else if (pc && pm)
+ *ptr++ ^= 17; /* Blue (cyan + light magenta) */
+ else if (pc && py)
+ *ptr++ ^= 6; /* Green (light cyan + yellow) */
+ else if (pm && py)
+ *ptr++ ^= 12; /* Red (magenta + yellow) */
+ else if (pc)
+ *ptr++ ^= 16;
+ else if (pm)
+ *ptr++ ^= 8;
+ else if (py)
+ *ptr++ ^= 4;
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[3] == r1[3])
+ *ptr++ = r0[3];
+ else
+ *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+
+ if (r0[0] == r1[0])
+ *ptr++ = r0[0];
+ else
+ *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *ptr++ = r0[1];
+ else
+ *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *ptr++ = r0[2];
+ else
+ *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ kptr = ptr;
+ cptr = ptr + bandwidth;
+ mptr = ptr + 2 * bandwidth;
+ yptr = ptr + 3 * bandwidth;
+ lcptr = ptr + 4 * bandwidth;
+ lmptr = ptr + 5 * bandwidth;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ pc = *r0++ > dither[x & 15];
+ pm = *r0++ > dither[x & 15];
+ py = *r0++ > dither[x & 15];
+ pk = *r0++ > dither[x & 15];
+
+ if (pk)
+ *kptr ^= bitmask; /* Black */
+ else if (pc && pm)
+ {
+ *cptr ^= bitmask; /* Blue (cyan + light magenta) */
+ *lmptr ^= bitmask;
+ }
+ else if (pc && py)
+ {
+ *lcptr ^= bitmask; /* Green (light cyan + yellow) */
+ *yptr ^= bitmask;
+ }
+ else if (pm && py)
+ {
+ *mptr ^= bitmask; /* Red (magenta + yellow) */
+ *yptr ^= bitmask;
+ }
+ else if (pc)
+ *cptr ^= bitmask;
+ else if (pm)
+ *mptr ^= bitmask;
+ else if (py)
+ *yptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ lcptr ++;
+ lmptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ if (r0[3] == r1[3])
+ *kptr++ = r0[3];
+ else
+ *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ switch (z)
+ {
+ case 0 :
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if (r0[3] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 1 :
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if (r0[0] > dither[x & 15] &&
+ r0[2] < dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if (r0[1] > dither[x & 15] &&
+ (r0[0] < dither[x & 15] ||
+ r0[2] > dither[x & 15]))
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 3 :
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if (r0[2] > dither[x & 15] &&
+ (r0[0] < dither[x & 15] ||
+ r0[1] < dither[x & 15]))
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if (r0[0] > dither[x & 15] &&
+ r0[2] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 5 :
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if (r0[0] > dither[x & 15] &&
+ r0[1] > dither[x & 15] &&
+ r0[2] < dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 8 :
+ if (z == 0)
+ {
+ r0 += 3;
+ r1 += 3;
+ }
+ else
+ {
+ r0 += z - 1;
+ r1 += z - 1;
+ }
+
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_RGBA()' - Convert image data to RGBA.
+ */
+
+static void
+format_RGBA(cups_page_header_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ ib_t *r0, /* I - Primary image data */
+ ib_t *r1) /* I - Image data for interpolation */
+{
+ ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 4;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 128 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 2)
+ {
+ *ptr ^= 16;
+ bitmask >>= 2;
+ }
+ else
+ {
+ bitmask = 128;
+ *ptr++ ^= 1;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr ^= (0xc0 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0xc0 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[1]]);
+
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[2]]);
+
+ *ptr++ ^= 0x03;
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[0]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[1]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[1]]);
+
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[2]]);
+
+ *ptr++ ^= 0x0f;
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (r0[0] == r1[0])
+ *ptr++ = r0[0];
+ else
+ *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *ptr++ = r0[1];
+ else
+ *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *ptr++ = r0[2];
+ else
+ *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ *ptr++ = 255;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ cptr = ptr;
+ mptr = ptr + bandwidth;
+ yptr = ptr + 2 * bandwidth;
+
+ memset(ptr + 3 * bandwidth, 255, bandwidth);
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *cptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *mptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *yptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ if (z == 3)
+ {
+ memset(row, 255, header->cupsBytesPerLine);
+ break;
+ }
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ switch (z)
+ {
+ case 0 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[0] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 1 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[1] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[2] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ r0 += z;
+ r1 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_W()' - Convert image data to luminance.
+ */
+
+static void
+format_W(cups_page_header_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ ib_t *r0, /* I - Primary image data */
+ ib_t *r1) /* I - Image data for interpolation */
+{
+ ib_t *ptr, /* Pointer into row */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ (void)z;
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 ++, r1 ++)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_YMC()' - Convert image data to YMC.
+ */
+
+static void
+format_YMC(cups_page_header_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ ib_t *r0, /* I - Primary image data */
+ ib_t *r1) /* I - Image data for interpolation */
+{
+ ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 3;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 64 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if (r0[2] > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (r0[1] > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (r0[0] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 64;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[2]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[1]]);
+
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr++ ^= (0x03 & OnPixels[r0[0]]);
+ else
+ *ptr++ ^= (0x03 & OffPixels[r0[0]]);
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 3)
+ {
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[2]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[2]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[1]]);
+
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[0]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[0]]);
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (r0[2] == r1[2])
+ *ptr++ = r0[2];
+ else
+ *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *ptr++ = r0[1];
+ else
+ *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[0] == r1[0])
+ *ptr++ = r0[0];
+ else
+ *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ yptr = ptr;
+ mptr = ptr + bandwidth;
+ cptr = ptr + 2 * bandwidth;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *cptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *mptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *yptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ switch (z)
+ {
+ case 2 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[0] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 1 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[1] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 0 :
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if (r0[2] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ z = 2 - z;
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ z = 2 - z;
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ z = 2 - z;
+ r0 += z;
+ r1 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'format_YMCK()' - Convert image data to YMCK.
+ */
+
+static void
+format_YMCK(cups_page_header_t *header, /* I - Page header */
+ unsigned char *row, /* IO - Bitmap data for device */
+ int y, /* I - Current row */
+ int z, /* I - Current plane */
+ int xsize, /* I - Width of image data */
+ int ysize, /* I - Height of image data */
+ int yerr0, /* I - Top Y error */
+ int yerr1, /* I - Bottom Y error */
+ ib_t *r0, /* I - Primary image data */
+ ib_t *r1) /* I - Image data for interpolation */
+{
+ ib_t *ptr, /* Pointer into row */
+ *cptr, /* Pointer into cyan */
+ *mptr, /* Pointer into magenta */
+ *yptr, /* Pointer into yellow */
+ *kptr, /* Pointer into black */
+ bitmask; /* Current mask for pixel */
+ int bitoffset; /* Current offset in line */
+ int bandwidth; /* Width of a color band */
+ int x, /* Current X coordinate on page */
+ *dither; /* Pointer into dither array */
+
+
+ switch (XPosition)
+ {
+ case -1 :
+ bitoffset = 0;
+ break;
+ default :
+ bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
+ break;
+ case 1 :
+ bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
+ break;
+ }
+
+ ptr = row + bitoffset / 8;
+ bandwidth = header->cupsBytesPerLine / 4;
+
+ switch (header->cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 128 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if (r0[2] > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (r0[1] > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (r0[0] > dither[x & 15])
+ *ptr ^= bitmask;
+ bitmask >>= 1;
+
+ if (r0[3] > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 128;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[2] & 63) > dither[x & 7])
+ *ptr ^= (0xc0 & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0xc0 & OffPixels[r0[2]]);
+
+ if ((r0[1] & 63) > dither[x & 7])
+ *ptr ^= (0x30 & OnPixels[r0[1]]);
+ else
+ *ptr ^= (0x30 & OffPixels[r0[1]]);
+
+ if ((r0[0] & 63) > dither[x & 7])
+ *ptr ^= (0x0c & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0x0c & OffPixels[r0[0]]);
+
+ if ((r0[3] & 63) > dither[x & 7])
+ *ptr++ ^= (0x03 & OnPixels[r0[3]]);
+ else
+ *ptr++ ^= (0x03 & OffPixels[r0[3]]);
+ }
+ break;
+
+ case 4 :
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize ; x > 0; x --, r0 += 4)
+ {
+ if ((r0[2] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[2]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[2]]);
+
+ if ((r0[1] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[1]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[1]]);
+
+ if ((r0[0] & 15) > dither[x & 3])
+ *ptr ^= (0xf0 & OnPixels[r0[0]]);
+ else
+ *ptr ^= (0xf0 & OffPixels[r0[0]]);
+
+ if ((r0[3] & 15) > dither[x & 3])
+ *ptr++ ^= (0x0f & OnPixels[r0[3]]);
+ else
+ *ptr++ ^= (0x0f & OffPixels[r0[3]]);
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[2] == r1[2])
+ *ptr++ = r0[2];
+ else
+ *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *ptr++ = r0[1];
+ else
+ *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[0] == r1[0])
+ *ptr++ = r0[0];
+ else
+ *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[3] == r1[3])
+ *ptr++ = r0[3];
+ else
+ *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_BANDED :
+ yptr = ptr;
+ mptr = ptr + bandwidth;
+ cptr = ptr + 2 * bandwidth;
+ kptr = ptr + 3 * bandwidth;
+
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if (*r0++ > dither[x & 15])
+ *cptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *mptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *yptr ^= bitmask;
+ if (*r0++ > dither[x & 15])
+ *kptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 63) > dither[x & 7])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+
+ for (x = xsize; x > 0; x --)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *cptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *cptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *mptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *mptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *yptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *yptr ^= (bitmask & OffPixels[*r0++]);
+
+ if ((*r0 & 15) > dither[x & 3])
+ *kptr ^= (bitmask & OnPixels[*r0++]);
+ else
+ *kptr ^= (bitmask & OffPixels[*r0++]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (r0[0] == r1[0])
+ *cptr++ = r0[0];
+ else
+ *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
+
+ if (r0[1] == r1[1])
+ *mptr++ = r0[1];
+ else
+ *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
+
+ if (r0[2] == r1[2])
+ *yptr++ = r0[2];
+ else
+ *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
+
+ if (r0[3] == r1[3])
+ *kptr++ = r0[3];
+ else
+ *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ switch (header->cupsBitsPerColor)
+ {
+ case 1 :
+ bitmask = 0x80 >> (bitoffset & 7);
+ dither = Floyd16x16[y & 15];
+
+ if (z < 3)
+ r0 += 2 - z;
+ else
+ r0 += z;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if (*r0 > dither[x & 15])
+ *ptr ^= bitmask;
+
+ if (bitmask > 1)
+ bitmask >>= 1;
+ else
+ {
+ bitmask = 0x80;
+ ptr ++;
+ }
+ }
+ break;
+
+ case 2 :
+ bitmask = 0xc0 >> (bitoffset & 7);
+ dither = Floyd8x8[y & 7];
+ if (z == 3)
+ r0 += 3;
+ else
+ r0 += 2 - z;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 63) > dither[x & 7])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask > 3)
+ bitmask >>= 2;
+ else
+ {
+ bitmask = 0xc0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 4 :
+ bitmask = 0xf0 >> (bitoffset & 7);
+ dither = Floyd4x4[y & 3];
+ if (z == 3)
+ r0 += 3;
+ else
+ r0 += 2 - z;
+
+ for (x = xsize; x > 0; x --, r0 += 4)
+ {
+ if ((*r0 & 15) > dither[x & 3])
+ *ptr ^= (bitmask & OnPixels[*r0]);
+ else
+ *ptr ^= (bitmask & OffPixels[*r0]);
+
+ if (bitmask == 0xf0)
+ bitmask = 0x0f;
+ else
+ {
+ bitmask = 0xf0;
+
+ ptr ++;
+ }
+ }
+ break;
+
+ case 8 :
+ if (z == 3)
+ {
+ r0 += 3;
+ r1 += 3;
+ }
+ else
+ {
+ r0 += 2 - z;
+ r1 += 2 - z;
+ }
+
+ for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
+ {
+ if (*r0 == *r1)
+ *ptr++ = *r0;
+ else
+ *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+
+/*
+ * 'make_lut()' - Make a lookup table given gamma and brightness values.
+ */
+
+static void
+make_lut(ib_t *lut, /* I - Lookup table */
+ int colorspace, /* I - Colorspace */
+ float g, /* I - Image gamma */
+ float b) /* I - Image brightness */
+{
+ int i; /* Looping var */
+ int v; /* Current value */
+
+
+ g = 1.0 / g;
+ b = 1.0 / b;
+
+ for (i = 0; i < 256; i ++)
+ {
+ if (colorspace < 0)
+ v = 255.0 * b * (1.0 - pow(1.0 - (float)i / 255.0, g)) + 0.5;
+ else
+ v = 255.0 * (1.0 - b * (1.0 - pow((float)i / 255.0, g))) + 0.5;
+
+ if (v < 0)
+ *lut++ = 0;
+ else if (v > 255)
+ *lut++ = 255;
+ else
+ *lut++ = v;
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/pstops.c b/filter/pstops.c
new file mode 100644
index 000000000..717a5f053
--- /dev/null
+++ b/filter/pstops.c
@@ -0,0 +1,1671 @@
+/*
+ * "$Id$"
+ *
+ * PostScript filter for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Main entry...
+ * check_range() - Check to see if the current page is selected for
+ * copy_bytes() - Copy bytes from the input file to stdout...
+ * do_prolog() - Send the necessary document prolog commands...
+ * do_setup() - Send the necessary document setup commands...
+ * end_nup() - End processing for N-up printing...
+ * psgets() - Get a line from a file.
+ * start_nup() - Start processing for N-up printing...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "common.h"
+
+
+/*
+ * Constants...
+ */
+
+#define MAX_PAGES 10000
+
+#define BORDER_NONE 0 /* No border or hairline border */
+#define BORDER_THICK 1 /* Think border */
+#define BORDER_SINGLE 2 /* Single-line hairline border */
+#define BORDER_SINGLE2 3 /* Single-line thick border */
+#define BORDER_DOUBLE 4 /* Double-line hairline border */
+#define BORDER_DOUBLE2 5 /* Double-line thick border */
+
+#define LAYOUT_LRBT 0 /* Left to right, bottom to top */
+#define LAYOUT_LRTB 1 /* Left to right, top to bottom */
+#define LAYOUT_RLBT 2 /* Right to left, bottom to top */
+#define LAYOUT_RLTB 3 /* Right to left, top to bottom */
+#define LAYOUT_BTLR 4 /* Bottom to top, left to right */
+#define LAYOUT_TBLR 5 /* Top to bottom, left to right */
+#define LAYOUT_BTRL 6 /* Bottom to top, right to left */
+#define LAYOUT_TBRL 7 /* Top to bottom, right to left */
+
+#define LAYOUT_NEGATEY 1
+#define LAYOUT_NEGATEX 2
+#define LAYOUT_VERTICAL 4
+
+
+/*
+ * Globals...
+ */
+
+int NumPages = 0; /* Number of pages in file */
+long Pages[MAX_PAGES]; /* Offsets to each page */
+char PageLabels[MAX_PAGES][64];
+ /* Page labels */
+const char *PageRanges = NULL; /* Range of pages selected */
+const char *PageSet = NULL; /* All, Even, Odd pages */
+int Order = 0, /* 0 = normal, 1 = reverse pages */
+ Flip = 0, /* Flip/mirror pages */
+ NUp = 1, /* Number of pages on each sheet (1, 2, 4) */
+ Collate = 0, /* Collate copies? */
+ Copies = 1, /* Number of copies */
+ UseESPsp = 0, /* Use ESPshowpage? */
+ Border = BORDER_NONE, /* Border around pages */
+ Layout = LAYOUT_LRTB, /* Layout of N-up pages */
+ NormalLandscape = 0; /* Normal rotation for landscape? */
+
+
+/*
+ * Local functions...
+ */
+
+static int check_range(int page);
+static void copy_bytes(FILE *fp, size_t length);
+static void do_prolog(ppd_file_t *ppd);
+static void do_setup(ppd_file_t *ppd, int copies, int collate,
+ int slowcollate, float g, float b);
+static void end_nup(int number);
+#define is_first_page(p) (NUp == 1 || (((p)+1) % NUp) == 1)
+#define is_last_page(p) (NUp > 1 && (((p)+1) % NUp) == 0)
+#define is_not_last_page(p) (NUp > 1 && ((p) % NUp) != 0)
+static char *psgets(char *buf, size_t len, FILE *fp);
+static void start_nup(int number, int show_border);
+
+
+/*
+ * 'main()' - Main entry...
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ FILE *fp; /* Print file */
+ ppd_file_t *ppd; /* PPD file */
+ int num_options; /* Number of print options */
+ cups_option_t *options; /* Print options */
+ const char *val; /* Option value */
+ char tempfile[255]; /* Temporary file name */
+ FILE *temp; /* Temporary file */
+ int tempfd; /* Temporary file descriptor */
+ int number; /* Page number */
+ int slowcollate; /* 1 if we need to collate manually */
+ int sloworder; /* 1 if we need to order manually */
+ int slowduplex; /* 1 if we need an even number of pages */
+ char line[8192]; /* Line buffer */
+ float g; /* Gamma correction value */
+ float b; /* Brightness factor */
+ int level; /* Nesting level for embedded files */
+ int nbytes, /* Number of bytes read */
+ tbytes; /* Total bytes to read for binary data */
+ int page; /* Current page sequence number */
+ int real_page; /* "Real" page number in document */
+ int page_count; /* Page count for NUp */
+ int basepage; /* Base page number */
+ int subpage; /* Sub-page number */
+ int copy; /* Current copy */
+ int saweof; /* Did we see a %%EOF tag? */
+ int sent_espsp, /* Did we send the ESPshowpage commands? */
+ sent_prolog, /* Did we send the prolog commands? */
+ sent_setup; /* Did we send the setup commands? */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fputs("ERROR: pstops job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+ if (argc == 6)
+ fp = stdin;
+ else
+ {
+ /*
+ * Try to open the print file...
+ */
+
+ if ((fp = fopen(argv[6], "rb")) == NULL)
+ {
+ fprintf(stderr, "ERROR: unable to open print file \"%s\" - %s\n",
+ argv[6], strerror(errno));
+ return (1);
+ }
+ }
+
+ /*
+ * Process command-line options and write the prolog...
+ */
+
+ g = 1.0;
+ b = 1.0;
+
+ Copies = atoi(argv[4]);
+
+ options = NULL;
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ ppd = SetCommonOptions(num_options, options, 1);
+
+ if (ppd && ppd->landscape > 0)
+ NormalLandscape = 1;
+
+ if ((val = cupsGetOption("page-ranges", num_options, options)) != NULL)
+ PageRanges = val;
+
+ if ((val = cupsGetOption("page-set", num_options, options)) != NULL)
+ PageSet = val;
+
+ if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL)
+ {
+ /*
+ * This IPP attribute is unnecessarily complicated...
+ *
+ * single-document, separate-documents-collated-copies, and
+ * single-document-new-sheet all require collated copies.
+ *
+ * separate-documents-uncollated-copies allows for uncollated copies.
+ */
+
+ Collate = strcasecmp(val, "separate-documents-uncollated-copies") != 0;
+ }
+
+ if ((val = cupsGetOption("Collate", num_options, options)) != NULL &&
+ strcasecmp(val, "True") == 0)
+ Collate = 1;
+
+ if ((val = cupsGetOption("OutputOrder", num_options, options)) != NULL &&
+ strcasecmp(val, "Reverse") == 0)
+ Order = 1;
+
+ if ((val = cupsGetOption("number-up", num_options, options)) != NULL)
+ NUp = atoi(val);
+
+ if ((val = cupsGetOption("page-border", num_options, options)) != NULL)
+ {
+ if (strcasecmp(val, "none") == 0)
+ Border = BORDER_NONE;
+ else if (strcasecmp(val, "single") == 0)
+ Border = BORDER_SINGLE;
+ else if (strcasecmp(val, "single-thick") == 0)
+ Border = BORDER_SINGLE2;
+ else if (strcasecmp(val, "double") == 0)
+ Border = BORDER_DOUBLE;
+ else if (strcasecmp(val, "double-thick") == 0)
+ Border = BORDER_DOUBLE2;
+ }
+
+ if ((val = cupsGetOption("number-up-layout", num_options, options)) != NULL)
+ {
+ if (strcasecmp(val, "lrtb") == 0)
+ Layout = LAYOUT_LRTB;
+ else if (strcasecmp(val, "lrbt") == 0)
+ Layout = LAYOUT_LRBT;
+ else if (strcasecmp(val, "rltb") == 0)
+ Layout = LAYOUT_RLTB;
+ else if (strcasecmp(val, "rlbt") == 0)
+ Layout = LAYOUT_RLBT;
+ else if (strcasecmp(val, "tblr") == 0)
+ Layout = LAYOUT_TBLR;
+ else if (strcasecmp(val, "tbrl") == 0)
+ Layout = LAYOUT_TBRL;
+ else if (strcasecmp(val, "btlr") == 0)
+ Layout = LAYOUT_BTLR;
+ else if (strcasecmp(val, "btrl") == 0)
+ Layout = LAYOUT_BTRL;
+ }
+
+ if ((val = cupsGetOption("gamma", num_options, options)) != NULL)
+ g = atoi(val) * 0.001f;
+
+ if ((val = cupsGetOption("brightness", num_options, options)) != NULL)
+ b = atoi(val) * 0.01f;
+
+ if ((val = cupsGetOption("mirror", num_options, options)) != NULL &&
+ strcasecmp(val, "True") == 0)
+ Flip = 1;
+
+ /*
+ * See if we have to filter the fast or slow way...
+ */
+
+ if (ppd && ppd->manual_copies && Duplex && Copies > 1)
+ {
+ /*
+ * Force collated copies when printing a duplexed document to
+ * a non-PS printer that doesn't do hardware copy generation.
+ * Otherwise the copies will end up on the front/back side of
+ * each page. Also, set the "slowduplex" option to make sure
+ * that we output an even number of pages...
+ */
+
+ Collate = 1;
+ slowduplex = 1;
+ }
+ else
+ slowduplex = 0;
+
+ if (ppdFindOption(ppd, "Collate") == NULL && Collate && Copies > 1)
+ slowcollate = 1;
+ else
+ slowcollate = 0;
+
+ if (ppdFindOption(ppd, "OutputOrder") == NULL && Order)
+ sloworder = 1;
+ else
+ sloworder = 0;
+
+ /*
+ * If we need to filter slowly, then create a temporary file for page data...
+ *
+ * If the temp file can't be created, then we'll ignore the collating/output
+ * order options...
+ */
+
+ if (sloworder || slowcollate)
+ {
+ tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+ temp = fdopen(tempfd, "wb+");
+
+ if (temp == NULL)
+ slowcollate = sloworder = 0;
+ }
+ else
+ temp = NULL;
+
+ /*
+ * Write any "exit server" options that have been selected...
+ */
+
+ ppdEmit(ppd, stdout, PPD_ORDER_EXIT);
+
+ /*
+ * Write any JCL commands that are needed to print PostScript code...
+ */
+
+ ppdEmitJCL(ppd, stdout, atoi(argv[1]), argv[2], argv[3]);
+
+ /*
+ * Read the first line to see if we have DSC comments...
+ */
+
+ if (psgets(line, sizeof(line), fp) == NULL)
+ {
+ fputs("ERROR: Empty print file!\n", stderr);
+ ppdClose(ppd);
+ return (1);
+ }
+
+ /*
+ * Start sending the document with any commands needed...
+ */
+
+ fputs(line, stdout);
+
+ saweof = 0;
+ sent_espsp = 0;
+ sent_prolog = 0;
+ sent_setup = 0;
+
+ if (Copies != 1 && (!Collate || !slowcollate))
+ {
+ /*
+ * Tell the document processor the copy and duplex options
+ * that are required...
+ */
+
+ printf("%%%%Requirements: numcopies(%d)%s%s\n", Copies,
+ Collate ? " collate" : "",
+ Duplex ? " duplex" : "");
+
+ /*
+ * Apple uses RBI comments for various non-PPD options...
+ */
+
+ printf("%%RBINumCopies: %d\n", Copies);
+ }
+ else
+ {
+ /*
+ * Tell the document processor the duplex option that is required...
+ */
+
+ if (Duplex)
+ puts("%%Requirements: duplex\n");
+
+ /*
+ * Apple uses RBI comments for various non-PPD options...
+ */
+
+ puts("%RBINumCopies: 1");
+ }
+
+ /*
+ * Figure out if we should use ESPshowpage or not...
+ */
+
+ val = cupsGetOption("page-label", num_options, options);
+
+ if (val != NULL || getenv("CLASSIFICATION") != NULL || NUp > 1 ||
+ Border || strstr(line, "EPS") != NULL)
+ {
+ /*
+ * Yes, use ESPshowpage...
+ */
+
+ UseESPsp = 1;
+ }
+
+ if (strncmp(line, "%!PS-Adobe-", 11) == 0 && strstr(line, "EPSF") == NULL)
+ {
+ /*
+ * OK, we have DSC comments and this isn't an EPS file; read until we
+ * find a %%Page comment...
+ */
+
+ puts("%%Pages: (atend)");
+
+ level = 0;
+
+ while (psgets(line, sizeof(line), fp) != NULL)
+ {
+ if (strncmp(line, "%%", 2) == 0)
+ fprintf(stderr, "DEBUG: %d %s", level, line);
+ else if (line[0] != '%' && line[0] && !sent_espsp && UseESPsp)
+ {
+ /*
+ * Send ESPshowpage stuff...
+ */
+
+ sent_espsp = 1;
+
+ puts("userdict/ESPshowpage/showpage load put\n"
+ "userdict/showpage{}put");
+ }
+
+ if (strncmp(line, "%%BeginDocument:", 16) == 0 ||
+ strncmp(line, "%%BeginDocument ", 16) == 0) /* Adobe Acrobat BUG */
+ {
+ fputs(line, stdout);
+ level ++;
+ }
+ else if (strncmp(line, "%%EndDocument", 13) == 0 && level > 0)
+ {
+ fputs(line, stdout);
+ level --;
+ }
+ else if (strncmp(line, "%cupsRotation:", 13) == 0 && level == 0)
+ {
+ /*
+ * Reset orientation of document?
+ */
+
+ int orient = (atoi(line + 13) / 90) & 3;
+
+ if (orient != Orientation)
+ {
+ Orientation = (4 - Orientation + orient) & 3;
+ UpdatePageVars();
+ Orientation = orient;
+ }
+ }
+ else if (strncmp(line, "%%BeginProlog", 13) == 0 && level == 0)
+ {
+ /*
+ * Write the existing comment line, and then follow with patches
+ * and prolog commands...
+ */
+
+ fputs(line, stdout);
+
+ if (!sent_prolog)
+ {
+ sent_prolog = 1;
+ do_prolog(ppd);
+ }
+ }
+ else if (strncmp(line, "%%BeginSetup", 12) == 0 && level == 0)
+ {
+ /*
+ * Write the existing comment line, and then follow with document
+ * setup commands...
+ */
+
+ fputs(line, stdout);
+
+ if (!sent_setup)
+ {
+ sent_setup = 1;
+ do_setup(ppd, Copies, Collate, slowcollate, g, b);
+ }
+ }
+ else if (strncmp(line, "%%Page:", 7) == 0 && level == 0)
+ break;
+ else if (strncmp(line, "%%BeginBinary:", 14) == 0 ||
+ (strncmp(line, "%%BeginData:", 12) == 0 &&
+ strstr(line, "ASCII") == NULL && strstr(line, "Hex") == NULL))
+ {
+ /*
+ * Copy binary data...
+ */
+
+ tbytes = atoi(strchr(line, ':') + 1);
+ fputs(line, stdout);
+
+ while (tbytes > 0)
+ {
+ if (tbytes > sizeof(line))
+ nbytes = fread(line, 1, sizeof(line), fp);
+ else
+ nbytes = fread(line, 1, tbytes, fp);
+
+ if (nbytes < 1)
+ {
+ perror("ERROR: Early end-of-file while reading binary data");
+ return (1);
+ }
+
+ fwrite(line, 1, nbytes, stdout);
+ tbytes -= nbytes;
+ }
+ }
+ else if (strncmp(line, "%%Pages:", 8) != 0)
+ fputs(line, stdout);
+ }
+
+ /*
+ * Make sure we have the prolog and setup commands written...
+ */
+
+ if (!sent_prolog)
+ {
+ puts("%%BeginProlog");
+
+ sent_prolog = 1;
+ do_prolog(ppd);
+
+ puts("%%EndProlog");
+ }
+
+ if (!sent_setup)
+ {
+ puts("%%BeginSetup");
+
+ sent_setup = 1;
+ do_setup(ppd, Copies, Collate, slowcollate, g, b);
+
+ puts("%%EndSetup");
+ }
+
+ if (!sent_espsp && UseESPsp)
+ {
+ /*
+ * Send ESPshowpage stuff...
+ */
+
+ sent_espsp = 1;
+
+ puts("userdict/ESPshowpage/showpage load put\n"
+ "userdict/showpage{}put");
+ }
+
+ /*
+ * Write the page and label prologs...
+ */
+
+ if (NUp == 2 || NUp == 6)
+ {
+ /*
+ * For 2- and 6-up output, rotate the labels to match the orientation
+ * of the pages...
+ */
+
+ if (Orientation & 1)
+ WriteLabelProlog(val, PageBottom, PageWidth - PageLength + PageTop,
+ PageLength);
+ else
+ WriteLabelProlog(val, PageLeft, PageRight, PageLength);
+ }
+ else
+ WriteLabelProlog(val, PageBottom, PageTop, PageWidth);
+
+ /*
+ * Then read all of the pages, filtering as needed...
+ */
+
+ for (page = 1, real_page = 1;;)
+ {
+ if (strncmp(line, "%%", 2) == 0)
+ fprintf(stderr, "DEBUG: %d %s", level, line);
+
+ if (strncmp(line, "%%BeginDocument:", 16) == 0 ||
+ strncmp(line, "%%BeginDocument ", 16) == 0) /* Adobe Acrobat BUG */
+ level ++;
+ else if (strncmp(line, "%%EndDocument", 13) == 0 && level > 0)
+ level --;
+ else if (strcmp(line, "\004") == 0)
+ break;
+ else if (strncmp(line, "%%EOF", 5) == 0 && level == 0)
+ {
+ fputs("DEBUG: Saw EOF!\n", stderr);
+ saweof = 1;
+ break;
+ }
+ else if (strncmp(line, "%%Page:", 7) == 0 && level == 0)
+ {
+ if (!check_range(real_page))
+ {
+ while (psgets(line, sizeof(line), fp) != NULL)
+ if (strncmp(line, "%%BeginDocument:", 16) == 0 ||
+ strncmp(line, "%%BeginDocument ", 16) == 0) /* Adobe Acrobat BUG */
+ level ++;
+ else if (strcmp(line, "%%EndDocument") == 0 && level > 0)
+ level --;
+ else if (strncmp(line, "%%Page:", 7) == 0 && level == 0)
+ {
+ real_page ++;
+ break;
+ }
+
+ continue;
+ }
+
+ if (!sloworder && NumPages > 0)
+ end_nup(NumPages - 1);
+
+ if (slowcollate || sloworder)
+ Pages[NumPages] = ftell(temp);
+
+ if (!sloworder)
+ {
+ if (is_first_page(NumPages))
+ {
+ if (ppd == NULL || ppd->num_filters == 0)
+ fprintf(stderr, "PAGE: %d %d\n", page, Copies);
+
+ printf("%%%%Page: %d %d\n", page, page);
+ page ++;
+ ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+ }
+
+ start_nup(NumPages, 1);
+ }
+
+ NumPages ++;
+ real_page ++;
+ }
+ else if (strncmp(line, "%%BeginBinary:", 14) == 0 ||
+ (strncmp(line, "%%BeginData:", 12) == 0 &&
+ strstr(line, "ASCII") == NULL && strstr(line, "Hex") == NULL))
+ {
+ /*
+ * Copy binary data...
+ */
+
+ tbytes = atoi(strchr(line, ':') + 1);
+
+ if (!sloworder)
+ fputs(line, stdout);
+ if (slowcollate || sloworder)
+ fputs(line, temp);
+
+ while (tbytes > 0)
+ {
+ if (tbytes > sizeof(line))
+ nbytes = fread(line, 1, sizeof(line), fp);
+ else
+ nbytes = fread(line, 1, tbytes, fp);
+
+ if (nbytes < 1)
+ {
+ perror("ERROR: Early end-of-file while reading binary data");
+ return (1);
+ }
+
+ if (!sloworder)
+ fwrite(line, 1, nbytes, stdout);
+
+ if (slowcollate || sloworder)
+ fwrite(line, 1, nbytes, temp);
+
+ tbytes -= nbytes;
+ }
+ }
+ else if (strncmp(line, "%%Trailer", 9) == 0 && level == 0)
+ {
+ fputs("DEBUG: Saw Trailer!\n", stderr);
+ break;
+ }
+ else
+ {
+ if (!sloworder)
+ fputs(line, stdout);
+
+ if (slowcollate || sloworder)
+ fputs(line, temp);
+ }
+
+ if (psgets(line, sizeof(line), fp) == NULL)
+ break;
+ }
+
+ if (!sloworder)
+ {
+ end_nup(NumPages - 1);
+
+ if (is_not_last_page(NumPages))
+ {
+ start_nup(NUp - 1, 0);
+ end_nup(NUp - 1);
+ }
+
+ if (slowduplex && !(page & 1))
+ {
+ /*
+ * Make sure we have an even number of pages...
+ */
+
+ if (ppd == NULL || ppd->num_filters == 0)
+ fprintf(stderr, "PAGE: %d %d\n", page, Copies);
+
+ printf("%%%%Page: %d %d\n", page, page);
+ page ++;
+ ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+
+ start_nup(NUp - 1, 0);
+ puts("showpage");
+ end_nup(NUp - 1);
+ }
+ }
+
+ if (slowcollate || sloworder)
+ {
+ Pages[NumPages] = ftell(temp);
+
+ if (!sloworder)
+ {
+ while (Copies > 1)
+ {
+ rewind(temp);
+
+ for (number = 0; number < NumPages; number ++)
+ {
+ if (is_first_page(number))
+ {
+ if (ppd == NULL || ppd->num_filters == 0)
+ fprintf(stderr, "PAGE: %d 1\n", page);
+
+ printf("%%%%Page: %d %d\n", page, page);
+ page ++;
+ ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+ }
+
+ start_nup(number, 1);
+ copy_bytes(temp, Pages[number + 1] - Pages[number]);
+ end_nup(number);
+ }
+
+ if (is_not_last_page(NumPages))
+ {
+ start_nup(NUp - 1, 0);
+ end_nup(NUp - 1);
+ }
+
+ if (slowduplex && !(page & 1))
+ {
+ /*
+ * Make sure we have an even number of pages...
+ */
+
+ if (ppd == NULL || ppd->num_filters == 0)
+ fprintf(stderr, "PAGE: %d 1\n", page);
+
+ printf("%%%%Page: %d %d\n", page, page);
+ page ++;
+ ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+
+ start_nup(NUp - 1, 0);
+ puts("showpage");
+ end_nup(NUp - 1);
+ }
+
+ Copies --;
+ }
+ }
+ else
+ {
+ page_count = (NumPages + NUp - 1) / NUp;
+ copy = 0;
+
+ do
+ {
+ if (slowduplex && (page_count & 1))
+ {
+ basepage = page_count - 1;
+ }
+ else
+ basepage = page_count - 1 - slowduplex;
+
+ for (; basepage >= 0; basepage -= 1 + slowduplex)
+ {
+ if (ppd == NULL || ppd->num_filters == 0)
+ fprintf(stderr, "PAGE: %d %d\n", page,
+ slowcollate ? 1 : Copies);
+
+ printf("%%%%Page: %d %d\n", page, page);
+ page ++;
+
+ ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+
+ for (subpage = 0, number = basepage * NUp;
+ subpage < NUp && number < NumPages;
+ subpage ++, number ++)
+ {
+ start_nup(number, 1);
+ fseek(temp, Pages[number], SEEK_SET);
+ copy_bytes(temp, Pages[number + 1] - Pages[number]);
+ end_nup(number);
+ }
+
+ if (is_not_last_page(number))
+ {
+ start_nup(NUp - 1, 0);
+ end_nup(NUp - 1);
+ }
+
+ if (slowduplex)
+ {
+ if (number < NumPages)
+ {
+ if (ppd == NULL || ppd->num_filters == 0)
+ fprintf(stderr, "PAGE: %d %d\n", page,
+ slowcollate ? 1 : Copies);
+
+ printf("%%%%Page: %d %d\n", page, page);
+ page ++;
+
+ ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+
+ for (subpage = 0, number = (basepage + 1) * NUp;
+ subpage < NUp && number < NumPages;
+ subpage ++, number ++)
+ {
+ start_nup(number, 1);
+ fseek(temp, Pages[number], SEEK_SET);
+ copy_bytes(temp, Pages[number + 1] - Pages[number]);
+ end_nup(number);
+ }
+
+ if (is_not_last_page(number))
+ {
+ start_nup(NUp - 1, 0);
+ end_nup(NUp - 1);
+ }
+ }
+ else
+ {
+ /*
+ * Make sure we have an even number of pages...
+ */
+
+ if (ppd == NULL || ppd->num_filters == 0)
+ fprintf(stderr, "PAGE: %d %d\n", page, slowcollate ? 1 : Copies);
+
+ printf("%%%%Page: %d %d\n", page, page);
+ page ++;
+ ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+
+ start_nup(NUp - 1, 0);
+ puts("showpage");
+ end_nup(NUp - 1);
+
+ basepage = page_count - 1;
+ }
+ }
+ }
+
+ copy ++;
+ }
+ while (copy < Copies && slowcollate);
+ }
+ }
+
+ /*
+ * Copy the trailer, if any...
+ */
+
+ puts("%%Trailer");
+ printf("%%%%Pages: %d\n", page - 1);
+
+ while (psgets(line, sizeof(line), fp) != NULL)
+ {
+ if (strcmp(line, "\004") != 0 &&
+ strncmp(line, "%%Pages:", 8) != 0)
+ fputs(line, stdout);
+
+ if (strncmp(line, "%%EOF", 5) == 0)
+ {
+ fputs("DEBUG: Saw EOF!\n", stderr);
+ saweof = 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * No DSC comments - write any page commands and then the rest of the file...
+ */
+
+ if (slowcollate && Copies > 1)
+ printf("%%%%Pages: %d\n", Copies);
+ else
+ puts("%%Pages: 1");
+
+ if (UseESPsp)
+ puts("userdict/ESPshowpage/showpage load put\n"
+ "userdict/showpage{}put");
+
+ puts("%%BeginProlog");
+ do_prolog(ppd);
+ puts("%%EndProlog");
+
+ puts("%%BeginSetup");
+ do_setup(ppd, Copies, Collate, slowcollate, g, b);
+ puts("%%EndSetup");
+
+ if (ppd == NULL || ppd->num_filters == 0)
+ fprintf(stderr, "PAGE: 1 %d\n", slowcollate ? 1 : Copies);
+
+ ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+
+ saweof = 1;
+
+ while ((nbytes = fread(line, 1, sizeof(line), fp)) > 0)
+ {
+ fwrite(line, 1, nbytes, stdout);
+
+ if (slowcollate)
+ fwrite(line, 1, nbytes, temp);
+ }
+
+ if (UseESPsp)
+ puts("ESPshowpage");
+
+ if (slowcollate)
+ {
+ while (Copies > 1)
+ {
+ if (ppd == NULL || ppd->num_filters == 0)
+ fputs("PAGE: 1 1\n", stderr);
+
+ ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+ rewind(temp);
+ copy_bytes(temp, 0);
+ Copies --;
+
+ if (UseESPsp)
+ puts("ESPshowpage");
+ }
+ }
+ }
+
+ /*
+ * Send %%EOF if needed...
+ */
+
+ if (!saweof)
+ puts("%%EOF");
+
+ /*
+ * End the job with the appropriate JCL command or CTRL-D otherwise.
+ */
+
+ if (ppd != NULL)
+ {
+ if (ppd->jcl_end)
+ fputs(ppd->jcl_end, stdout);
+ else if (ppd->num_filters == 0)
+ putchar(0x04);
+ }
+
+ /*
+ * Close files and remove the temporary file if needed...
+ */
+
+ if (slowcollate || sloworder)
+ {
+ fclose(temp);
+ unlink(tempfile);
+ }
+
+ ppdClose(ppd);
+
+ if (fp != stdin)
+ fclose(fp);
+
+ return (0);
+}
+
+
+/*
+ * 'check_range()' - Check to see if the current page is selected for
+ * printing.
+ */
+
+static int /* O - 1 if selected, 0 otherwise */
+check_range(int page) /* I - Page number */
+{
+ const char *range; /* Pointer into range string */
+ int lower, upper; /* Lower and upper page numbers */
+
+
+ if (PageSet != NULL)
+ {
+ /*
+ * See if we only print even or odd pages...
+ */
+
+ if (strcasecmp(PageSet, "even") == 0 && ((page - 1) % (NUp << 1)) < NUp)
+ return (0);
+ if (strcasecmp(PageSet, "odd") == 0 && ((page - 1) % (NUp << 1)) >= NUp)
+ return (0);
+ }
+
+ if (PageRanges == NULL)
+ return (1); /* No range, print all pages... */
+
+ for (range = PageRanges; *range != '\0';)
+ {
+ if (*range == '-')
+ {
+ lower = 1;
+ range ++;
+ upper = strtol(range, (char **)&range, 10);
+ }
+ else
+ {
+ lower = strtol(range, (char **)&range, 10);
+
+ if (*range == '-')
+ {
+ range ++;
+ if (!isdigit(*range))
+ upper = 65535;
+ else
+ upper = strtol(range, (char **)&range, 10);
+ }
+ else
+ upper = lower;
+ }
+
+ if (page >= lower && page <= upper)
+ return (1);
+
+ if (*range == ',')
+ range ++;
+ else
+ break;
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'copy_bytes()' - Copy bytes from the input file to stdout...
+ */
+
+static void
+copy_bytes(FILE *fp, /* I - File to read from */
+ size_t length) /* I - Length of page data */
+{
+ char buffer[8192]; /* Data buffer */
+ size_t nbytes, /* Number of bytes read */
+ nleft; /* Number of bytes left/remaining */
+
+
+ nleft = length;
+
+ while (nleft > 0 || length == 0)
+ {
+ if (nleft > sizeof(buffer) || length == 0)
+ nbytes = sizeof(buffer);
+ else
+ nbytes = nleft;
+
+ if ((nbytes = fread(buffer, 1, nbytes, fp)) < 1)
+ return;
+
+ nleft -= nbytes;
+
+ fwrite(buffer, 1, nbytes, stdout);
+ }
+}
+
+
+/*
+ * 'do_prolog()' - Send the necessary document prolog commands...
+ */
+
+static void
+do_prolog(ppd_file_t *ppd) /* I - PPD file */
+{
+ /*
+ * Send the document prolog commands...
+ */
+
+ if (ppd != NULL && ppd->patches != NULL)
+ {
+ puts("%%BeginFeature: *JobPatchFile 1");
+ puts(ppd->patches);
+ puts("%%EndFeature");
+ }
+
+ ppdEmit(ppd, stdout, PPD_ORDER_PROLOG);
+}
+
+
+/*
+ * 'do_setup()' - Send the necessary document setup commands...
+ */
+
+static void
+do_setup(ppd_file_t *ppd, /* I - PPD file */
+ int copies, /* I - Number of copies */
+ int collate, /* I - Collate output? */
+ int slowcollate, /* I - Slow collate */
+ float g, /* I - Gamma value */
+ float b) /* I - Brightness value */
+{
+ /*
+ * Send all the printer-specific setup commands...
+ */
+
+ ppdEmit(ppd, stdout, PPD_ORDER_DOCUMENT);
+ ppdEmit(ppd, stdout, PPD_ORDER_ANY);
+
+ /*
+ * Set the number of copies for the job...
+ */
+
+ if (copies != 1 && (!collate || !slowcollate))
+ {
+ printf("%%RBIBeginNonPPDFeature: *NumCopies %d\n", copies);
+ printf("%d/languagelevel where{pop languagelevel 2 ge}{false}ifelse{1 dict begin"
+ "/NumCopies exch def currentdict end "
+ "setpagedevice}{userdict/#copies 3 -1 roll put}ifelse\n", copies);
+ printf("%%RBIEndNonPPDFeature\n");
+ }
+
+ /*
+ * Changes to the transfer function must be made AFTER any
+ * setpagedevice code...
+ */
+
+ if (g != 1.0 || b != 1.0)
+ printf("{ neg 1 add dup 0 lt { pop 1 } { %.3f exp neg 1 add } "
+ "ifelse %.3f mul } bind settransfer\n", g, b);
+
+ /*
+ * Make sure we have rectclip and rectstroke procedures of some sort...
+ */
+
+ WriteCommon();
+}
+
+
+/*
+ * 'end_nup()' - End processing for N-up printing...
+ */
+
+static void
+end_nup(int number) /* I - Page number */
+{
+ puts("");
+
+ if (Flip || Orientation || NUp > 1)
+ puts("userdict /ESPsave get restore");
+
+ switch (NUp)
+ {
+ case 1 :
+ if (UseESPsp)
+ {
+ WriteLabels(Orientation);
+ puts("ESPshowpage");
+ }
+ break;
+
+ case 2 :
+ case 6 :
+ if (is_last_page(number) && UseESPsp)
+ {
+ if (Orientation & 1)
+ {
+ /*
+ * Rotate the labels back to portrait...
+ */
+
+ WriteLabels(Orientation - 1);
+ }
+ else if (Orientation == 0)
+ {
+ /*
+ * Rotate the labels to landscape...
+ */
+
+ WriteLabels(NormalLandscape ? 1 : 3);
+ }
+ else
+ {
+ /*
+ * Rotate the labels to landscape...
+ */
+
+ WriteLabels(NormalLandscape ? 3 : 1);
+ }
+
+ puts("ESPshowpage");
+ }
+ break;
+
+ default :
+ if (is_last_page(number) && UseESPsp)
+ {
+ WriteLabels(Orientation);
+ puts("ESPshowpage");
+ }
+ break;
+ }
+
+ fflush(stdout);
+}
+
+
+/*
+ * 'psgets()' - Get a line from a file.
+ *
+ * Note:
+ *
+ * This function differs from the gets() function in that it
+ * handles any combination of CR, LF, or CR LF to end input
+ * lines.
+ */
+
+static char * /* O - String or NULL if EOF */
+psgets(char *buf, /* I - Buffer to read into */
+ size_t len, /* I - Length of buffer */
+ FILE *fp) /* I - File to read from */
+{
+ char *bufptr; /* Pointer into buffer */
+ int ch; /* Character from file */
+
+
+ len --;
+ bufptr = buf;
+ ch = EOF;
+
+ while ((bufptr - buf) < len)
+ {
+ if ((ch = getc(fp)) == EOF)
+ break;
+
+ if (ch == 0x0d)
+ {
+ /*
+ * Got a CR; see if there is a LF as well...
+ */
+
+ ch = getc(fp);
+ if (ch != EOF && ch != 0x0a)
+ ungetc(ch, fp); /* Nope, save it for later... */
+
+ ch = 0x0a;
+ break;
+ }
+ else if (ch == 0x0a)
+ break;
+ else
+ *bufptr++ = ch;
+ }
+
+ /*
+ * Add a trailing newline if it is there...
+ */
+
+ if (ch == '\n')
+ *bufptr++ = '\n';
+
+ /*
+ * Nul-terminate the string and return it (or NULL for EOF).
+ */
+
+ *bufptr = '\0';
+
+ if (ch == EOF && bufptr == buf)
+ return (NULL);
+ else
+ return (buf);
+}
+
+
+/*
+ * 'start_nup()' - Start processing for N-up printing...
+ */
+
+static void
+start_nup(int number, /* I - Page number */
+ int show_border) /* I - Show the page border? */
+{
+ int pos; /* Position on page */
+ int x, y; /* Relative position of subpage */
+ float w, l, /* Width and length of subpage */
+ tx, ty; /* Translation values for subpage */
+ float pw, pl; /* Printable width and length of full page */
+
+
+ if (Flip || Orientation || NUp > 1)
+ puts("userdict/ESPsave save put");
+
+ if (Flip)
+ printf("%.1f 0.0 translate -1 1 scale\n", PageWidth);
+
+ pos = number % NUp;
+ pw = PageRight - PageLeft;
+ pl = PageTop - PageBottom;
+
+ fprintf(stderr, "DEBUG: pw = %.1f, pl = %.1f\n", pw, pl);
+ fprintf(stderr, "DEBUG: PageLeft = %.1f, PageRight = %.1f\n", PageLeft, PageRight);
+ fprintf(stderr, "DEBUG: PageTop = %.1f, PageBottom = %.1f\n", PageTop, PageBottom);
+ fprintf(stderr, "DEBUG: PageWidth = %.1f, PageLength = %.1f\n", PageWidth, PageLength);
+
+ switch (Orientation)
+ {
+ case 1 : /* Landscape */
+ printf("%.1f 0.0 translate 90 rotate\n", PageLength);
+ break;
+ case 2 : /* Reverse Portrait */
+ printf("%.1f %.1f translate 180 rotate\n", PageWidth, PageLength);
+ break;
+ case 3 : /* Reverse Landscape */
+ printf("0.0 %.1f translate -90 rotate\n", PageWidth);
+ break;
+ }
+
+ if (Duplex && NUp > 1 && ((number / NUp) & 1))
+ printf("%.1f %.1f translate\n", PageWidth - PageRight, PageBottom);
+ else if (NUp > 1)
+ printf("%.1f %.1f translate\n", PageLeft, PageBottom);
+
+ switch (NUp)
+ {
+ default :
+ w = PageWidth;
+ l = PageLength;
+ break;
+
+ case 2 :
+ if (Orientation & 1)
+ {
+ x = pos & 1;
+
+ if (Layout & LAYOUT_NEGATEY)
+ x = 1 - x;
+
+ w = pl;
+ l = w * PageLength / PageWidth;
+
+ if (l > (pw * 0.5))
+ {
+ l = pw * 0.5;
+ w = l * PageWidth / PageLength;
+ }
+
+ tx = 0.5 * (pw * 0.5 - l);
+ ty = 0.5 * (pl - w);
+
+ if (NormalLandscape)
+ printf("0.0 %.1f translate -90 rotate\n", pl);
+ else
+ printf("%.1f 0.0 translate 90 rotate\n", pw);
+
+ printf("%.1f %.1f translate %.3f %.3f scale\n",
+ ty, tx + l * x, w / PageWidth, l / PageLength);
+ }
+ else
+ {
+ x = pos & 1;
+
+ if (Layout & LAYOUT_NEGATEX)
+ x = 1 - x;
+
+ l = pw;
+ w = l * PageWidth / PageLength;
+
+ if (w > (pl * 0.5))
+ {
+ w = pl * 0.5;
+ l = w * PageLength / PageWidth;
+ }
+
+ tx = 0.5 * (pl * 0.5 - w);
+ ty = 0.5 * (pw - l);
+
+ if (NormalLandscape)
+ printf("%.1f 0.0 translate 90 rotate\n", pw);
+ else
+ printf("0.0 %.1f translate -90 rotate\n", pl);
+
+ printf("%.1f %.1f translate %.3f %.3f scale\n",
+ tx + w * x, ty, w / PageWidth, l / PageLength);
+ }
+ break;
+
+ case 4 :
+ if (Layout & LAYOUT_VERTICAL)
+ {
+ x = (pos / 2) & 1;
+ y = pos & 1;
+ }
+ else
+ {
+ x = pos & 1;
+ y = (pos / 2) & 1;
+ }
+
+ if (Layout & LAYOUT_NEGATEX)
+ x = 1 - x;
+
+ if (Layout & LAYOUT_NEGATEY)
+ y = 1 - y;
+
+ w = pw * 0.5;
+ l = w * PageLength / PageWidth;
+
+ if (l > (pl * 0.5))
+ {
+ l = pl * 0.5;
+ w = l * PageWidth / PageLength;
+ }
+
+ tx = 0.5 * (pw * 0.5 - w);
+ ty = 0.5 * (pl * 0.5 - l);
+
+ printf("%.1f %.1f translate %.3f %.3f scale\n", tx + x * w, ty + y * l,
+ w / PageWidth, l / PageLength);
+ break;
+
+ case 6 :
+ if (Orientation & 1)
+ {
+ if (Layout & LAYOUT_VERTICAL)
+ {
+ x = pos / 3;
+ y = pos % 3;
+
+ if (Layout & LAYOUT_NEGATEX)
+ x = 1 - x;
+
+ if (Layout & LAYOUT_NEGATEY)
+ y = 2 - y;
+ }
+ else
+ {
+ x = pos & 1;
+ y = pos / 2;
+
+ if (Layout & LAYOUT_NEGATEX)
+ x = 1 - x;
+
+ if (Layout & LAYOUT_NEGATEY)
+ y = 2 - y;
+ }
+
+ w = pl * 0.5;
+ l = w * PageLength / PageWidth;
+
+ if (l > (pw * 0.333))
+ {
+ l = pw * 0.333;
+ w = l * PageWidth / PageLength;
+ }
+
+ tx = 0.5 * (pl - 2 * w);
+ ty = 0.5 * (pw - 3 * l);
+
+ if (NormalLandscape)
+ printf("0.0 %.1f translate -90 rotate\n", pl);
+ else
+ printf("%.1f 0.0 translate 90 rotate\n", pw);
+
+ printf("%.1f %.1f translate %.3f %.3f scale\n",
+ tx + x * w, ty + y * l, w / PageWidth, l / PageLength);
+ }
+ else
+ {
+ if (Layout & LAYOUT_VERTICAL)
+ {
+ x = pos / 2;
+ y = pos & 1;
+
+ if (Layout & LAYOUT_NEGATEX)
+ x = 2 - x;
+
+ if (Layout & LAYOUT_NEGATEY)
+ y = 1 - y;
+ }
+ else
+ {
+ x = pos % 3;
+ y = pos / 3;
+
+ if (Layout & LAYOUT_NEGATEX)
+ x = 2 - x;
+
+ if (Layout & LAYOUT_NEGATEY)
+ y = 1 - y;
+ }
+
+ l = pw * 0.5;
+ w = l * PageWidth / PageLength;
+
+ if (w > (pl * 0.333))
+ {
+ w = pl * 0.333;
+ l = w * PageLength / PageWidth;
+ }
+
+ tx = 0.5 * (pl - 3 * w);
+ ty = 0.5 * (pw - 2 * l);
+
+ if (NormalLandscape)
+ printf("%.1f 0.0 translate 90 rotate\n", pw);
+ else
+ printf("0.0 %.1f translate -90 rotate\n", pl);
+
+ printf("%.1f %.1f translate %.3f %.3f scale\n",
+ tx + w * x, ty + l * y, w / PageWidth, l / PageLength);
+ }
+ break;
+
+ case 9 :
+ if (Layout & LAYOUT_VERTICAL)
+ {
+ x = (pos / 3) % 3;
+ y = pos % 3;
+ }
+ else
+ {
+ x = pos % 3;
+ y = (pos / 3) % 3;
+ }
+
+ if (Layout & LAYOUT_NEGATEX)
+ x = 2 - x;
+
+ if (Layout & LAYOUT_NEGATEY)
+ y = 2 - y;
+
+ w = pw * 0.333;
+ l = w * PageLength / PageWidth;
+
+ if (l > (pl * 0.333))
+ {
+ l = pl * 0.333;
+ w = l * PageWidth / PageLength;
+ }
+
+ tx = 0.5 * (pw * 0.333 - w);
+ ty = 0.5 * (pl * 0.333 - l);
+
+ printf("%.1f %.1f translate %.3f %.3f scale\n", tx + x * w, ty + y * l,
+ w / PageWidth, l / PageLength);
+ break;
+
+ case 16 :
+ if (Layout & LAYOUT_VERTICAL)
+ {
+ x = (pos / 4) & 3;
+ y = pos & 3;
+ }
+ else
+ {
+ x = pos & 3;
+ y = (pos / 4) & 3;
+ }
+
+ if (Layout & LAYOUT_NEGATEX)
+ x = 3 - x;
+
+ if (Layout & LAYOUT_NEGATEY)
+ y = 3 - y;
+
+ w = pw * 0.25;
+ l = w * PageLength / PageWidth;
+
+ if (l > (pl * 0.25))
+ {
+ l = pl * 0.25;
+ w = l * PageWidth / PageLength;
+ }
+
+ tx = 0.5 * (pw * 0.25 - w);
+ ty = 0.5 * (pl * 0.25 - l);
+
+ printf("%.1f %.1f translate %.3f %.3f scale\n", tx + x * w, ty + y * l,
+ w / PageWidth, l / PageLength);
+ break;
+ }
+
+ /*
+ * Draw borders as necessary...
+ */
+
+ if (Border && show_border)
+ {
+ int rects; /* Number of border rectangles */
+ float fscale, /* Scaling value for points */
+ margin; /* Current margin for borders */
+
+
+ rects = (Border & BORDER_DOUBLE) ? 2 : 1;
+ fscale = PageWidth / w;
+ margin = 2.25 * fscale;
+
+ /*
+ * Set the line width and color...
+ */
+
+ puts("gsave");
+ printf("%.3f setlinewidth 0 setgray newpath\n",
+ (Border & BORDER_THICK) ? 0.5 * fscale : 0.24 * fscale);
+
+ /*
+ * Draw border boxes...
+ */
+
+ for (; rects > 0; rects --, margin += 2 * fscale)
+ if (NUp > 1)
+ printf("%.1f %.1f %.1f %.1f ESPrs\n",
+ margin,
+ margin,
+ PageWidth - 2 * margin,
+ PageLength - 2 * margin);
+ else
+ printf("%.1f %.1f %.1f %.1f ESPrs\n",
+ PageLeft + margin,
+ PageBottom + margin,
+ PageRight - PageLeft - 2 * margin,
+ PageTop - PageBottom - 2 * margin);
+
+ /*
+ * Restore pen settings...
+ */
+
+ puts("grestore");
+ }
+
+ if (NUp > 1)
+ {
+ /*
+ * Clip the page that follows to the bounding box of the page...
+ */
+
+ printf("0 0 %.1f %.1f ESPrc\n", PageWidth, PageLength);
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/pstops.dsp b/filter/pstops.dsp
new file mode 100644
index 000000000..956c8ab65
--- /dev/null
+++ b/filter/pstops.dsp
@@ -0,0 +1,107 @@
+# Microsoft Developer Studio Project File - Name="pstops" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=pstops - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "pstops.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "pstops.mak" CFG="pstops - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "pstops - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "pstops - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "pstops - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ../cups/cups.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"pstops.exe"
+
+!ELSEIF "$(CFG)" == "pstops - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "pstops___Win32_Debug"
+# PROP BASE Intermediate_Dir "pstops___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ../cups/cups.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"pstopsd.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "pstops - Win32 Release"
+# Name "pstops - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\pstops.c
+
+!IF "$(CFG)" == "pstops - Win32 Release"
+
+!ELSEIF "$(CFG)" == "pstops - Win32 Debug"
+
+# ADD CPP /Zi
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# End Target
+# End Project
diff --git a/filter/raster.c b/filter/raster.c
new file mode 100644
index 000000000..2767e9303
--- /dev/null
+++ b/filter/raster.c
@@ -0,0 +1,254 @@
+/*
+ * "$Id$"
+ *
+ * Raster file routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights for the CUPS Raster source
+ * files are outlined in the GNU Library General Public License, located
+ * in the "pstoraster" directory. If this file is missing or damaged
+ * please contact Easy Software Products at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This code and any derivative of it may be used and distributed
+ * freely under the terms of the GNU General Public License when
+ * used with GNU Ghostscript or its derivatives. Use of the code
+ * (or any derivative of it) with software other than GNU
+ * GhostScript (or its derivatives) is governed by the CUPS license
+ * agreement.
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * cupsRasterClose() - Close a raster stream.
+ * cupsRasterOpen() - Open a raster stream.
+ * cupsRasterReadHeader() - Read a raster page header.
+ * cupsRasterReadPixels() - Read raster pixels.
+ * cupsRasterWriteHeader() - Write a raster page header.
+ * cupsRasterWritePixels() - Write raster pixels.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "raster.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#if defined(WIN32) || defined(__EMX__)
+# include <io.h>
+#else
+# include <unistd.h>
+#endif /* WIN32 || __EMX__ */
+
+
+/*
+ * 'cupsRasterClose()' - Close a raster stream.
+ */
+
+void
+cupsRasterClose(cups_raster_t *r) /* I - Stream to close */
+{
+ if (r != NULL)
+ free(r);
+}
+
+
+/*
+ * 'cupsRasterOpen()' - Open a raster stream.
+ */
+
+cups_raster_t * /* O - New stream */
+cupsRasterOpen(int fd, /* I - File descriptor */
+ cups_mode_t mode) /* I - Mode */
+{
+ cups_raster_t *r; /* New stream */
+
+
+ if ((r = calloc(sizeof(cups_raster_t), 1)) == NULL)
+ return (NULL);
+
+ r->fd = fd;
+ r->mode = mode;
+
+ if (mode == CUPS_RASTER_READ)
+ {
+ /*
+ * Open for read - get sync word...
+ */
+
+ if (read(fd, &(r->sync), sizeof(r->sync)) < sizeof(r->sync))
+ {
+ free(r);
+ return (NULL);
+ }
+
+ if (r->sync != CUPS_RASTER_SYNC &&
+ r->sync != CUPS_RASTER_REVSYNC)
+ {
+ free(r);
+ return (NULL);
+ }
+ }
+ else
+ {
+ /*
+ * Open for write - put sync word...
+ */
+
+ r->sync = CUPS_RASTER_SYNC;
+ if (write(fd, &(r->sync), sizeof(r->sync)) < sizeof(r->sync))
+ {
+ free(r);
+ return (NULL);
+ }
+ }
+
+ return (r);
+}
+
+
+/*
+ * 'cupsRasterReadHeader()' - Read a raster page header.
+ */
+
+unsigned /* O - 1 on success, 0 on fail */
+cupsRasterReadHeader(cups_raster_t *r, /* I - Raster stream */
+ cups_page_header_t *h) /* I - Pointer to header data */
+{
+ int len; /* Number of words to swap */
+ union swap_s /* Swapping structure */
+ {
+ unsigned char b[4];
+ unsigned v;
+ } *s;
+
+
+ if (r == NULL || r->mode != CUPS_RASTER_READ)
+ return (0);
+
+ if (cupsRasterReadPixels(r, (unsigned char *)h, sizeof(cups_page_header_t)) <
+ sizeof(cups_page_header_t))
+ return (0);
+
+ if (r->sync == CUPS_RASTER_REVSYNC)
+ for (len = (sizeof(cups_page_header_t) - 256) / 4,
+ s = (union swap_s *)&(h->AdvanceDistance);
+ len > 0;
+ len --, s ++)
+ s->v = (((((s->b[3] << 8) | s->b[2]) << 8) | s->b[1]) << 8) | s->b[0];
+
+ return (1);
+}
+
+
+/*
+ * 'cupsRasterReadPixels()' - Read raster pixels.
+ */
+
+unsigned /* O - Number of bytes read */
+cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */
+ unsigned char *p, /* I - Pointer to pixel buffer */
+ unsigned len) /* I - Number of bytes to read */
+{
+ int bytes; /* Bytes read */
+ unsigned remaining; /* Bytes remaining */
+
+
+ if (r == NULL || r->mode != CUPS_RASTER_READ)
+ return (0);
+
+ remaining = len;
+
+ while (remaining > 0)
+ {
+ bytes = read(r->fd, p, remaining);
+
+ if (bytes <= 0)
+ {
+ if (errno != EAGAIN && errno != EINTR)
+ return (0);
+ else
+ continue;
+ }
+
+ remaining -= bytes;
+ p += bytes;
+ }
+
+ return (len);
+}
+
+
+/*
+ * 'cupsRasterWriteHeader()' - Write a raster page header.
+ */
+
+unsigned
+cupsRasterWriteHeader(cups_raster_t *r,
+ cups_page_header_t *h)
+{
+ if (r == NULL || r->mode != CUPS_RASTER_WRITE)
+ return (0);
+
+ return (cupsRasterWritePixels(r, (unsigned char *)h,
+ sizeof(cups_page_header_t)) ==
+ sizeof(cups_page_header_t));
+}
+
+
+/*
+ * 'cupsRasterWritePixels()' - Write raster pixels.
+ */
+
+unsigned /* O - Number of bytes written */
+cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */
+ unsigned char *p, /* I - Bytes to write */
+ unsigned len)/* I - Number of bytes to write */
+{
+ int bytes; /* Bytes read */
+ unsigned remaining; /* Bytes remaining */
+
+
+ if (r == NULL || r->mode != CUPS_RASTER_WRITE)
+ return (0);
+
+ remaining = len;
+
+ while (remaining > 0)
+ {
+ bytes = write(r->fd, p, remaining);
+
+ if (bytes <= 0)
+ {
+ if (errno != EAGAIN && errno != EINTR)
+ return (0);
+ else
+ continue;
+ }
+
+ remaining -= bytes;
+ p += bytes;
+ }
+
+ return (len);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/raster.h b/filter/raster.h
new file mode 100644
index 000000000..e0e34252d
--- /dev/null
+++ b/filter/raster.h
@@ -0,0 +1,263 @@
+/*
+ * "$Id$"
+ *
+ * Raster file definitions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights for the CUPS Raster source
+ * files are outlined in the GNU Library General Public License, located
+ * in the "pstoraster" directory. If this file is missing or damaged
+ * please contact Easy Software Products at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This code and any derivative of it may be used and distributed
+ * freely under the terms of the GNU General Public License when
+ * used with GNU Ghostscript or its derivatives. Use of the code
+ * (or any derivative of it) with software other than GNU
+ * GhostScript (or its derivatives) is governed by the CUPS license
+ * agreement.
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _CUPS_RASTER_H_
+# define _CUPS_RASTER_H_
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+/*
+ * Every non-PostScript printer driver that supports raster images should
+ * use the application/vnd.cups-raster image file format. Since both the
+ * PostScript RIP (pstoraster, based on GNU Ghostscript) and Image RIP
+ * (imagetoraster, located in the filter directory) use it, using this format
+ * saves you a lot of work. Also, the PostScript RIP passes any printer
+ * options that are in a PS file to your driver this way as well...
+ */
+
+/*
+ * Constants...
+ */
+
+# define CUPS_RASTER_SYNC 0x52615374 /* RaSt */
+# define CUPS_RASTER_REVSYNC 0x74536152 /* tSaR */
+
+
+/*
+ * The following definition can be used to determine if the
+ * colorimetric colorspaces (CIEXYZ, CIELAB, and ICCn) are
+ * defined...
+ */
+
+# define CUPS_RASTER_HAVE_COLORIMETRIC 1
+
+
+/*
+ * Types...
+ */
+
+typedef enum
+{
+ CUPS_RASTER_READ, /* Open stream for reading */
+ CUPS_RASTER_WRITE /* Open stream for writing */
+} cups_mode_t;
+
+typedef enum
+{
+ CUPS_FALSE, /* Logical false */
+ CUPS_TRUE /* Logical true */
+} cups_bool_t;
+
+typedef enum
+{
+ CUPS_JOG_NONE, /* Never move pages */
+ CUPS_JOG_FILE, /* Move pages after this file */
+ CUPS_JOG_JOB, /* Move pages after this job */
+ CUPS_JOG_SET /* Move pages after this set */
+} cups_jog_t;
+
+typedef enum
+{
+ CUPS_ORIENT_0, /* Don't rotate the page */
+ CUPS_ORIENT_90, /* Rotate the page counter-clockwise */
+ CUPS_ORIENT_180, /* Turn the page upside down */
+ CUPS_ORIENT_270 /* Rotate the page clockwise */
+} cups_orient_t;
+
+typedef enum
+{
+ CUPS_CUT_NONE, /* Never cut the roll */
+ CUPS_CUT_FILE, /* Cut the roll after this file */
+ CUPS_CUT_JOB, /* Cut the roll after this job */
+ CUPS_CUT_SET, /* Cut the roll after this set */
+ CUPS_CUT_PAGE /* Cut the roll after this page */
+} cups_cut_t;
+
+typedef enum
+{
+ CUPS_ADVANCE_NONE, /* Never advance the roll */
+ CUPS_ADVANCE_FILE, /* Advance the roll after this file */
+ CUPS_ADVANCE_JOB, /* Advance the roll after this job */
+ CUPS_ADVANCE_SET, /* Advance the roll after this set */
+ CUPS_ADVANCE_PAGE /* Advance the roll after this page */
+} cups_adv_t;
+
+typedef enum
+{
+ CUPS_EDGE_TOP, /* Leading edge is the top of the page */
+ CUPS_EDGE_RIGHT, /* Leading edge is the right of the page */
+ CUPS_EDGE_BOTTOM, /* Leading edge is the bottom of the page */
+ CUPS_EDGE_LEFT /* Leading edge is the left of the page */
+} cups_edge_t;
+
+typedef enum
+{
+ CUPS_ORDER_CHUNKED, /* CMYK CMYK CMYK ... */
+ CUPS_ORDER_BANDED, /* CCC MMM YYY KKK ... */
+ CUPS_ORDER_PLANAR /* CCC ... MMM ... YYY ... KKK ... */
+} cups_order_t;
+
+typedef enum
+{
+ CUPS_CSPACE_W, /* Luminance */
+ CUPS_CSPACE_RGB, /* Red, green, blue */
+ CUPS_CSPACE_RGBA, /* Red, green, blue, alpha */
+ CUPS_CSPACE_K, /* Black */
+ CUPS_CSPACE_CMY, /* Cyan, magenta, yellow */
+ CUPS_CSPACE_YMC, /* Yellow, magenta, cyan */
+ CUPS_CSPACE_CMYK, /* Cyan, magenta, yellow, black */
+ CUPS_CSPACE_YMCK, /* Yellow, magenta, cyan, black */
+ CUPS_CSPACE_KCMY, /* Black, cyan, magenta, yellow */
+ CUPS_CSPACE_KCMYcm, /* Black, cyan, magenta, yellow, *
+ * light-cyan, light-magenta */
+ CUPS_CSPACE_GMCK, /* Gold, magenta, yellow, black */
+ CUPS_CSPACE_GMCS, /* Gold, magenta, yellow, silver */
+ CUPS_CSPACE_WHITE, /* White ink (as black) */
+ CUPS_CSPACE_GOLD, /* Gold foil */
+ CUPS_CSPACE_SILVER, /* Silver foil */
+
+ CUPS_CSPACE_CIEXYZ, /* CIE XYZ */
+ CUPS_CSPACE_CIELab, /* CIE Lab */
+
+ CUPS_CSPACE_ICC1 = 32, /* ICC-based, 1 color */
+ CUPS_CSPACE_ICC2, /* ICC-based, 2 colors */
+ CUPS_CSPACE_ICC3, /* ICC-based, 3 colors */
+ CUPS_CSPACE_ICC4, /* ICC-based, 4 colors */
+ CUPS_CSPACE_ICC5, /* ICC-based, 5 colors */
+ CUPS_CSPACE_ICC6, /* ICC-based, 6 colors */
+ CUPS_CSPACE_ICC7, /* ICC-based, 7 colors */
+ CUPS_CSPACE_ICC8, /* ICC-based, 8 colors */
+ CUPS_CSPACE_ICC9, /* ICC-based, 9 colors */
+ CUPS_CSPACE_ICCA, /* ICC-based, 10 colors */
+ CUPS_CSPACE_ICCB, /* ICC-based, 11 colors */
+ CUPS_CSPACE_ICCC, /* ICC-based, 12 colors */
+ CUPS_CSPACE_ICCD, /* ICC-based, 13 colors */
+ CUPS_CSPACE_ICCE, /* ICC-based, 14 colors */
+ CUPS_CSPACE_ICCF /* ICC-based, 15 colors */
+} cups_cspace_t;
+
+
+/*
+ * The page header structure contains the standard PostScript page device
+ * dictionary, along with some CUPS-specific parameters that are provided
+ * by the RIPs...
+ */
+
+typedef struct
+{
+ /**** Standard Page Device Dictionary String Values ****/
+ char MediaClass[64]; /* MediaClass string */
+ char MediaColor[64]; /* MediaColor string */
+ char MediaType[64]; /* MediaType string */
+ char OutputType[64]; /* OutputType string */
+
+ /**** Standard Page Device Dictionary Integer Values ****/
+ unsigned AdvanceDistance; /* AdvanceDistance value in points */
+ cups_adv_t AdvanceMedia; /* AdvanceMedia value (see above) */
+ cups_bool_t Collate; /* Collated copies value */
+ cups_cut_t CutMedia; /* CutMedia value (see above) */
+ cups_bool_t Duplex; /* Duplexed (double-sided) value */
+ unsigned HWResolution[2]; /* Resolution in dots-per-inch */
+ unsigned ImagingBoundingBox[4]; /* Pixel region that is painted (points) */
+ cups_bool_t InsertSheet; /* InsertSheet value */
+ cups_jog_t Jog; /* Jog value (see above) */
+ cups_edge_t LeadingEdge; /* LeadingEdge value (see above) */
+ unsigned Margins[2]; /* Lower-lefthand margins in points */
+ cups_bool_t ManualFeed; /* ManualFeed value */
+ unsigned MediaPosition; /* MediaPosition value */
+ unsigned MediaWeight; /* MediaWeight value in grams/m^2 */
+ cups_bool_t MirrorPrint; /* MirrorPrint value */
+ cups_bool_t NegativePrint; /* NegativePrint value */
+ unsigned NumCopies; /* Number of copies to produce */
+ cups_orient_t Orientation; /* Orientation value (see above) */
+ cups_bool_t OutputFaceUp; /* OutputFaceUp value */
+ unsigned PageSize[2]; /* Width and length of page in points */
+ cups_bool_t Separations; /* Separations value */
+ cups_bool_t TraySwitch; /* TraySwitch value */
+ cups_bool_t Tumble; /* Tumble value */
+
+ /**** CUPS Page Device Dictionary Values ****/
+ unsigned cupsWidth; /* Width of page image in pixels */
+ unsigned cupsHeight; /* Height of page image in pixels */
+ unsigned cupsMediaType; /* Media type code */
+ unsigned cupsBitsPerColor; /* Number of bits for each color */
+ unsigned cupsBitsPerPixel; /* Number of bits for each pixel */
+ unsigned cupsBytesPerLine; /* Number of bytes per line */
+ cups_order_t cupsColorOrder; /* Order of colors */
+ cups_cspace_t cupsColorSpace; /* True colorspace */
+ unsigned cupsCompression; /* Device compression to use */
+ unsigned cupsRowCount; /* Rows per band */
+ unsigned cupsRowFeed; /* Feed between bands */
+ unsigned cupsRowStep; /* Spacing between lines */
+} cups_page_header_t;
+
+
+/*
+ * The raster structure maintains information about a raster data
+ * stream...
+ */
+
+typedef struct
+{
+ unsigned sync; /* Sync word from start of stream */
+ int fd; /* File descriptor */
+ cups_mode_t mode; /* Read/write mode */
+} cups_raster_t;
+
+
+/*
+ * Prototypes...
+ */
+
+extern void cupsRasterClose(cups_raster_t *r);
+extern cups_raster_t *cupsRasterOpen(int fd, cups_mode_t mode);
+extern unsigned cupsRasterReadHeader(cups_raster_t *r,
+ cups_page_header_t *h);
+extern unsigned cupsRasterReadPixels(cups_raster_t *r,
+ unsigned char *p, unsigned len);
+extern unsigned cupsRasterWriteHeader(cups_raster_t *r,
+ cups_page_header_t *h);
+extern unsigned cupsRasterWritePixels(cups_raster_t *r,
+ unsigned char *p, unsigned len);
+
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+
+#endif /* !_CUPS_RASTER_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/rastertodymo.c b/filter/rastertodymo.c
new file mode 100644
index 000000000..c8869e1d6
--- /dev/null
+++ b/filter/rastertodymo.c
@@ -0,0 +1,363 @@
+/*
+ * "$Id$"
+ *
+ * DYMO label printer filter for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 2001 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * Setup() - Prepare the printer for printing.
+ * StartPage() - Start a page of graphics.
+ * EndPage() - Finish a page of graphics.
+ * Shutdown() - Shutdown the printer.
+ * CancelJob() - Cancel the current job...
+ * CompressData() - Compress a line of graphics.
+ * OutputLine() - Output a line of graphics.
+ * main() - Main entry and processing of driver.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/cups.h>
+#include <cups/string.h>
+#include "raster.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+
+
+/*
+ * Globals...
+ */
+
+unsigned char *Buffer; /* Output buffer */
+int Page, /* Current page */
+ Feed; /* Number of lines to skip */
+
+
+/*
+ * Prototypes...
+ */
+
+void Setup(void);
+void StartPage(cups_page_header_t *header);
+void EndPage(void);
+
+void CancelJob(int sig);
+
+/**** MRS - supported resolutions = 136, 203, 300 ****/
+
+
+/*
+ * 'Setup()' - Prepare the printer for printing.
+ */
+
+void
+Setup(void)
+{
+ int i; /* Looping var */
+
+
+ /*
+ * Clear any remaining data...
+ */
+
+ for (i = 0; i < 100; i ++)
+ putchar(0x1b);
+}
+
+
+/*
+ * 'StartPage()' - Start a page of graphics.
+ */
+
+void
+StartPage(cups_page_header_t *header) /* I - Page header */
+{
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Register a signal handler to eject the current page if the
+ * job is cancelled.
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, CancelJob);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = CancelJob;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, CancelJob);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Setup printer/job attributes...
+ */
+
+ printf("\033L%c%c", header->cupsHeight, header->cupsHeight >> 8);
+ printf("\033D%c", header->cupsBytesPerLine);
+
+ printf("\033%c", header->cupsCompression + 'c'); /* Darkness */
+
+ /*
+ * Allocate memory for a line of graphics...
+ */
+
+ Buffer = malloc(header->cupsBytesPerLine);
+ Feed = 0;
+}
+
+
+/*
+ * 'EndPage()' - Finish a page of graphics.
+ */
+
+void
+EndPage(void)
+{
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Eject the current page...
+ */
+
+ printf("\033E");
+
+ fflush(stdout);
+
+ /*
+ * Unregister the signal handler...
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Free memory...
+ */
+
+ free(Buffer);
+}
+
+
+/*
+ * 'CancelJob()' - Cancel the current job...
+ */
+
+void
+CancelJob(int sig) /* I - Signal */
+{
+ int i; /* Looping var */
+
+
+ (void)sig;
+
+ /*
+ * Send out lots of ESC bytes to clear out any pending raster data...
+ */
+
+ for (i = 0; i < 100; i ++)
+ putchar(0x1b);
+
+ /*
+ * End the current page and exit...
+ */
+
+ EndPage();
+
+ exit(0);
+}
+
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int fd; /* File descriptor */
+ cups_raster_t *ras; /* Raster stream for printing */
+ cups_page_header_t header; /* Page header from file */
+ int y; /* Current line */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ /*
+ * We don't have the correct number of arguments; write an error message
+ * and return.
+ */
+
+ fputs("ERROR: rastertodymo job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Open the page stream...
+ */
+
+ if (argc == 7)
+ {
+ if ((fd = open(argv[6], O_RDONLY)) == -1)
+ {
+ perror("ERROR: Unable to open raster file - ");
+ sleep(1);
+ return (1);
+ }
+ }
+ else
+ fd = 0;
+
+ ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
+
+ /*
+ * Initialize the print device...
+ */
+
+ Setup();
+
+ /*
+ * Process pages as needed...
+ */
+
+ Page = 0;
+
+ while (cupsRasterReadHeader(ras, &header))
+ {
+ /*
+ * Write a status message with the page number and number of copies.
+ */
+
+ Page ++;
+
+ fprintf(stderr, "PAGE: %d 1\n", Page);
+
+ /*
+ * Start the page...
+ */
+
+ StartPage(&header);
+
+ /*
+ * Loop for each line on the page...
+ */
+
+ for (y = 0; y < header.cupsHeight; y ++)
+ {
+ /*
+ * Let the user know how far we have progressed...
+ */
+
+ if ((y & 15) == 0)
+ fprintf(stderr, "INFO: Printing page %d, %d%% complete...\n", Page,
+ 100 * y / header.cupsHeight);
+
+ /*
+ * Read a line of graphics...
+ */
+
+ if (cupsRasterReadPixels(ras, Buffer, header.cupsBytesPerLine) < 1)
+ break;
+
+ /*
+ * See if the line is blank; if not, write it to the printer...
+ */
+
+ if (Buffer[0] ||
+ memcmp(Buffer, Buffer + 1, header.cupsBytesPerLine - 1))
+ {
+ if (Feed)
+ {
+ printf("\033f\001%c", Feed);
+ Feed = 0;
+ }
+ putchar(0x16);
+ fwrite(Buffer, header.cupsBytesPerLine, 1, stdout);
+ }
+ else
+ Feed ++;
+ }
+
+ /*
+ * Eject the page...
+ */
+
+ EndPage();
+ }
+
+ /*
+ * Close the raster stream...
+ */
+
+ cupsRasterClose(ras);
+ if (fd != 0)
+ close(fd);
+
+ /*
+ * If no pages were printed, send an error message...
+ */
+
+ if (Page == 0)
+ fputs("ERROR: No pages found!\n", stderr);
+ else
+ fputs("INFO: " CUPS_SVERSION " is ready to print.\n", stderr);
+
+ return (Page == 0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/rastertoepson.c b/filter/rastertoepson.c
new file mode 100644
index 000000000..0ad44b03e
--- /dev/null
+++ b/filter/rastertoepson.c
@@ -0,0 +1,1133 @@
+/*
+ * "$Id$"
+ *
+ * EPSON ESC/P and ESC/P2 filter for the Common UNIX Printing System
+ * (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * Setup() - Prepare the printer for printing.
+ * StartPage() - Start a page of graphics.
+ * EndPage() - Finish a page of graphics.
+ * Shutdown() - Shutdown the printer.
+ * CompressData() - Compress a line of graphics.
+ * OutputLine() - Output a line of graphics.
+ * main() - Main entry and processing of driver.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/cups.h>
+#include <cups/ppd.h>
+#include <cups/string.h>
+#include "raster.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+
+
+/*
+ * Model numbers...
+ */
+
+#define EPSON_9PIN 0
+#define EPSON_24PIN 1
+#define EPSON_COLOR 2
+#define EPSON_PHOTO 3
+#define EPSON_ICOLOR 4
+#define EPSON_IPHOTO 5
+
+
+/*
+ * Macros...
+ */
+
+#define pwrite(s,n) fwrite((s), 1, (n), stdout)
+
+
+/*
+ * Globals...
+ */
+
+unsigned char *Planes[6], /* Output buffers */
+ *CompBuffer, /* Compression buffer */
+ *LineBuffers[2]; /* Line bitmap buffers */
+int Model, /* Model number */
+ NumPlanes, /* Number of color planes */
+ Feed; /* Number of lines to skip */
+int DotBit, /* Bit in buffers */
+ DotBytes, /* # bytes in a dot column */
+ DotColumns, /* # columns in 1/60 inch */
+ LineCount, /* # of lines processed */
+ EvenOffset, /* Offset into 'even' buffers */
+ OddOffset, /* Offset into 'odd' buffers */
+ Shingling; /* Shingle output? */
+
+
+/*
+ * Prototypes...
+ */
+
+void Setup(void);
+void StartPage(const ppd_file_t *ppd, const cups_page_header_t *header);
+void EndPage(const cups_page_header_t *header);
+void Shutdown(void);
+
+void CancelJob(int sig);
+void CompressData(const unsigned char *line, int length, int plane,
+ int type, int xstep, int ystep);
+void OutputLine(const cups_page_header_t *header);
+void OutputRows(const cups_page_header_t *header, int row);
+
+
+/*
+ * 'Setup()' - Prepare the printer for printing.
+ */
+
+void
+Setup(void)
+{
+ const char *device_uri; /* The device for the printer... */
+
+
+ /*
+ * EPSON USB printers need an additional command issued at the
+ * beginning of each job to exit from "packet" mode...
+ */
+
+ if ((device_uri = getenv("DEVICE_URI")) != NULL &&
+ strncmp(device_uri, "usb:", 4) == 0)
+ pwrite("\000\000\000\033\001@EJL 1284.4\n@EJL \n\033@", 29);
+}
+
+
+/*
+ * 'StartPage()' - Start a page of graphics.
+ */
+
+void
+StartPage(const ppd_file_t *ppd, /* I - PPD file */
+ const cups_page_header_t *header) /* I - Page header */
+{
+ int n, t; /* Numbers */
+ int plane; /* Looping var */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Register a signal handler to eject the current page if the
+ * job is cancelled.
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, CancelJob);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = CancelJob;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, CancelJob);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Send a reset sequence.
+ */
+
+ if (ppd->nickname && strstr(ppd->nickname, "OKIDATA") != NULL)
+ printf("\033{A"); /* Set EPSON emulation mode */
+
+ printf("\033@");
+
+ /*
+ * See which type of printer we are using...
+ */
+
+ Model = ppd->model_number;
+
+ switch (ppd->model_number)
+ {
+ case EPSON_9PIN :
+ case EPSON_24PIN :
+ printf("\033P"); /* Set 10 CPI */
+
+ if (header->HWResolution[0] == 360 || header->HWResolution[0] == 240)
+ {
+ printf("\033x1"); /* LQ printing */
+ printf("\033U1"); /* Unidirectional */
+ }
+ else
+ {
+ printf("\033x0"); /* Draft printing */
+ printf("\033U0"); /* Bidirectional */
+ }
+
+ printf("\033l%c\033Q%c", 0, /* Side margins */
+ (int)(10.0 * header->PageSize[0] / 72.0 + 0.5));
+ printf("\033C%c%c", 0, /* Page length */
+ (int)(header->PageSize[1] / 72.0 + 0.5));
+ printf("\033N%c", 0); /* Bottom margin */
+
+ /*
+ * Setup various buffer limits...
+ */
+
+ DotBytes = header->cupsRowCount / 8;
+ DotColumns = header->HWResolution[0] / 60;
+ Shingling = 0;
+
+ if (ppd->model_number == EPSON_9PIN)
+ printf("\033\063\030"); /* Set line feed */
+ else
+ switch (header->HWResolution[0])
+ {
+ case 60:
+ case 120 :
+ printf("\033\063\030"); /* Set line feed */
+ break;
+
+ case 180 :
+ case 360 :
+ Shingling = 1;
+
+ if (header->HWResolution[1] == 180)
+ printf("\033\063\010");/* Set line feed */
+ else
+ printf("\033+\010"); /* Set line feed */
+ break;
+ }
+ break;
+
+ default :
+ /*
+ * Set graphics mode...
+ */
+
+ pwrite("\033(G\001\000\001", 6); /* Graphics mode */
+
+ /*
+ * Set the media size...
+ */
+
+ if (Model < EPSON_ICOLOR)
+ {
+ pwrite("\033(U\001\000", 5); /* Resolution/units */
+ putchar(3600 / header->HWResolution[1]);
+ }
+ else
+ {
+ pwrite("\033(U\005\000", 5);
+ putchar(1440 / header->HWResolution[1]);
+ putchar(1440 / header->HWResolution[1]);
+ putchar(1440 / header->HWResolution[0]);
+ putchar(0xa0); /* n/1440ths... */
+ putchar(0x05);
+ }
+
+ n = header->PageSize[1] * header->HWResolution[1] / 72.0;
+
+ pwrite("\033(C\002\000", 5); /* Page length */
+ putchar(n);
+ putchar(n >> 8);
+
+ t = (ppd->sizes[1].length - ppd->sizes[1].top) *
+ header->HWResolution[1] / 72.0;
+
+ pwrite("\033(c\004\000", 5); /* Top & bottom margins */
+ putchar(t);
+ putchar(t >> 8);
+ putchar(n);
+ putchar(n >> 8);
+
+ if (header->HWResolution[1] == 720)
+ {
+ pwrite("\033(i\001\000\001", 6); /* Microweave */
+ pwrite("\033(e\002\000\000\001", 7); /* Small dots */
+ }
+
+ pwrite("\033(V\002\000\000\000", 7); /* Set absolute position 0 */
+
+ DotBytes = 0;
+ DotColumns = 0;
+ Shingling = 0;
+ break;
+ }
+
+ /*
+ * Set other stuff...
+ */
+
+ if (header->cupsColorSpace == CUPS_CSPACE_CMY)
+ NumPlanes = 3;
+ else if (header->cupsColorSpace == CUPS_CSPACE_KCMY)
+ NumPlanes = 4;
+ else if (header->cupsColorSpace == CUPS_CSPACE_KCMYcm)
+ NumPlanes = 6;
+ else
+ NumPlanes = 1;
+
+ Feed = 0; /* No blank lines yet */
+
+ /*
+ * Allocate memory for a line/row of graphics...
+ */
+
+ Planes[0] = malloc(header->cupsBytesPerLine);
+ for (plane = 1; plane < NumPlanes; plane ++)
+ Planes[plane] = Planes[0] + plane * header->cupsBytesPerLine / NumPlanes;
+
+ if (header->cupsCompression || DotBytes)
+ CompBuffer = calloc(2, header->cupsWidth);
+ else
+ CompBuffer = NULL;
+
+ if (DotBytes)
+ {
+ LineBuffers[0] = calloc(DotBytes, header->cupsWidth * (Shingling + 1));
+ LineBuffers[1] = LineBuffers[0] + DotBytes * header->cupsWidth;
+ DotBit = 128;
+ LineCount = 0;
+ EvenOffset = 0;
+ OddOffset = 0;
+ }
+}
+
+
+/*
+ * 'EndPage()' - Finish a page of graphics.
+ */
+
+void
+EndPage(const cups_page_header_t *header) /* I - Page header */
+{
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ if (DotBytes && header)
+ {
+ /*
+ * Flush remaining graphics as needed...
+ */
+
+ if (!Shingling)
+ OutputRows(header, 0);
+ else if (OddOffset > EvenOffset)
+ {
+ OutputRows(header, 1);
+ OutputRows(header, 0);
+ }
+ else
+ {
+ OutputRows(header, 0);
+ OutputRows(header, 1);
+ }
+ }
+
+ /*
+ * Eject the current page...
+ */
+
+ putchar(12); /* Form feed */
+ fflush(stdout);
+
+ /*
+ * Unregister the signal handler...
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Free memory...
+ */
+
+ free(Planes[0]);
+
+ if (CompBuffer)
+ free(CompBuffer);
+
+ if (DotBytes)
+ free(LineBuffers[0]);
+}
+
+
+/*
+ * 'Shutdown()' - Shutdown the printer.
+ */
+
+void
+Shutdown(void)
+{
+ /*
+ * Send a reset sequence.
+ */
+
+ printf("\033@");
+}
+
+
+/*
+ * 'CancelJob()' - Cancel the current job...
+ */
+
+void
+CancelJob(int sig) /* I - Signal */
+{
+ int i; /* Looping var */
+
+
+ (void)sig;
+
+ /*
+ * Send out lots of NUL bytes to clear out any pending raster data...
+ */
+
+ if (DotBytes)
+ i = DotBytes * 360 * 8;
+ else
+ i = 720;
+
+ for (; i > 0; i --)
+ putchar(0);
+
+ /*
+ * End the current page and exit...
+ */
+
+ EndPage(NULL);
+ Shutdown();
+
+ exit(0);
+}
+
+
+/*
+ * 'CompressData()' - Compress a line of graphics.
+ */
+
+void
+CompressData(const unsigned char *line, /* I - Data to compress */
+ int length,/* I - Number of bytes */
+ int plane, /* I - Color plane */
+ int type, /* I - Type of compression */
+ int xstep, /* I - X resolution */
+ int ystep) /* I - Y resolution */
+{
+ const unsigned char *line_ptr, /* Current byte pointer */
+ *line_end, /* End-of-line byte pointer */
+ *start; /* Start of compression sequence */
+ unsigned char *comp_ptr, /* Pointer into compression buffer */
+ temp; /* Current byte */
+ int count; /* Count of bytes for output */
+ static int ctable[6] = { 0, 2, 1, 4, 18, 17 };
+ /* KCMYcm color values */
+
+
+ /*
+ * Setup pointers...
+ */
+
+ line_ptr = line;
+ line_end = line + length;
+
+ /*
+ * Do depletion for 720 DPI printing...
+ */
+
+ if (ystep == 5)
+ {
+ for (comp_ptr = (unsigned char *)line; comp_ptr < line_end;)
+ {
+ /*
+ * Grab the current byte...
+ */
+
+ temp = *comp_ptr;
+
+ /*
+ * Check adjacent bits...
+ */
+
+ if ((temp & 0xc0) == 0xc0)
+ temp &= 0xbf;
+ if ((temp & 0x60) == 0x60)
+ temp &= 0xdf;
+ if ((temp & 0x30) == 0x30)
+ temp &= 0xef;
+ if ((temp & 0x18) == 0x18)
+ temp &= 0xf7;
+ if ((temp & 0x0c) == 0x0c)
+ temp &= 0xfb;
+ if ((temp & 0x06) == 0x06)
+ temp &= 0xfd;
+ if ((temp & 0x03) == 0x03)
+ temp &= 0xfe;
+
+ *comp_ptr++ = temp;
+
+ /*
+ * Check the last bit in the current byte and the first bit in the
+ * next byte...
+ */
+
+ if ((temp & 0x01) && comp_ptr < line_end && *comp_ptr & 0x80)
+ *comp_ptr &= 0x7f;
+ }
+ }
+
+ switch (type)
+ {
+ case 0 :
+ /*
+ * Do no compression...
+ */
+ break;
+
+ case 1 :
+ /*
+ * Do TIFF pack-bits encoding...
+ */
+
+ comp_ptr = CompBuffer;
+
+ while (line_ptr < line_end)
+ {
+ if ((line_ptr + 1) >= line_end)
+ {
+ /*
+ * Single byte on the end...
+ */
+
+ *comp_ptr++ = 0x00;
+ *comp_ptr++ = *line_ptr++;
+ }
+ else if (line_ptr[0] == line_ptr[1])
+ {
+ /*
+ * Repeated sequence...
+ */
+
+ line_ptr ++;
+ count = 2;
+
+ while (line_ptr < (line_end - 1) &&
+ line_ptr[0] == line_ptr[1] &&
+ count < 127)
+ {
+ line_ptr ++;
+ count ++;
+ }
+
+ *comp_ptr++ = 257 - count;
+ *comp_ptr++ = *line_ptr++;
+ }
+ else
+ {
+ /*
+ * Non-repeated sequence...
+ */
+
+ start = line_ptr;
+ line_ptr ++;
+ count = 1;
+
+ while (line_ptr < (line_end - 1) &&
+ line_ptr[0] != line_ptr[1] &&
+ count < 127)
+ {
+ line_ptr ++;
+ count ++;
+ }
+
+ *comp_ptr++ = count - 1;
+
+ memcpy(comp_ptr, start, count);
+ comp_ptr += count;
+ }
+ }
+
+ line_ptr = CompBuffer;
+ line_end = comp_ptr;
+ break;
+ }
+
+ putchar(0x0d); /* Move print head to left margin */
+
+ if (Model < EPSON_ICOLOR)
+ {
+ /*
+ * Do graphics the "old" way...
+ */
+
+ if (NumPlanes > 1)
+ {
+ /*
+ * Set the color...
+ */
+
+ if (plane > 3)
+ printf("\033(r%c%c%c%c", 2, 0, 1, ctable[plane] & 15);
+ /* Set extended color */
+ else if (NumPlanes == 3)
+ printf("\033r%c", ctable[plane + 1]);
+ /* Set color */
+ else
+ printf("\033r%c", ctable[plane]); /* Set color */
+ }
+
+ /*
+ * Send a raster plane...
+ */
+
+ length *= 8;
+ printf("\033."); /* Raster graphics */
+ putchar(type);
+ putchar(ystep);
+ putchar(xstep);
+ putchar(1);
+ putchar(length);
+ putchar(length >> 8);
+ }
+ else
+ {
+ /*
+ * Do graphics the "new" way...
+ */
+
+ printf("\033i");
+ putchar(ctable[plane]);
+ putchar(type);
+ putchar(1);
+ putchar(length & 255);
+ putchar(length >> 8);
+ putchar(1);
+ putchar(0);
+ }
+
+ pwrite(line_ptr, line_end - line_ptr);
+ fflush(stdout);
+}
+
+
+/*
+ * 'OutputLine()' - Output a line of graphics.
+ */
+
+void
+OutputLine(const cups_page_header_t *header) /* I - Page header */
+{
+ if (header->cupsRowCount)
+ {
+ int width;
+ unsigned char *tempptr,
+ *evenptr,
+ *oddptr;
+ register int x;
+ unsigned char bit;
+ const unsigned char *pixel;
+ unsigned char *temp;
+
+
+ /*
+ * Collect bitmap data in the line buffers and write after each buffer.
+ */
+
+ for (x = header->cupsWidth, bit = 128, pixel = Planes[0],
+ temp = CompBuffer;
+ x > 0;
+ x --, temp ++)
+ {
+ if (*pixel & bit)
+ *temp |= DotBit;
+
+ if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ bit = 128;
+ pixel ++;
+ }
+ }
+
+ if (DotBit > 1)
+ DotBit >>= 1;
+ else
+ {
+ /*
+ * Copy the holding buffer to the output buffer, shingling as necessary...
+ */
+
+ if (Shingling && LineCount != 0)
+ {
+ /*
+ * Shingle the output...
+ */
+
+ if (LineCount & 1)
+ {
+ evenptr = LineBuffers[1] + OddOffset;
+ oddptr = LineBuffers[0] + EvenOffset + DotBytes;
+ }
+ else
+ {
+ evenptr = LineBuffers[0] + EvenOffset;
+ oddptr = LineBuffers[1] + OddOffset + DotBytes;
+ }
+
+ for (width = header->cupsWidth, tempptr = CompBuffer;
+ width > 0;
+ width -= 2, tempptr += 2, oddptr += DotBytes * 2,
+ evenptr += DotBytes * 2)
+ {
+ evenptr[0] = tempptr[0];
+ oddptr[0] = tempptr[1];
+ }
+ }
+ else
+ {
+ /*
+ * Don't shingle the output...
+ */
+
+ for (width = header->cupsWidth, tempptr = CompBuffer,
+ evenptr = LineBuffers[0] + EvenOffset;
+ width >= 0;
+ width --, tempptr ++, evenptr += DotBytes)
+ *evenptr = tempptr[0];
+ }
+
+ if (Shingling && LineCount != 0)
+ {
+ EvenOffset ++;
+ OddOffset ++;
+
+ if (EvenOffset == DotBytes)
+ {
+ EvenOffset = 0;
+ OutputRows(header, 0);
+ }
+
+ if (OddOffset == DotBytes)
+ {
+ OddOffset = 0;
+ OutputRows(header, 1);
+ }
+ }
+ else
+ {
+ EvenOffset ++;
+
+ if (EvenOffset == DotBytes)
+ {
+ EvenOffset = 0;
+ OutputRows(header, 0);
+ }
+ }
+
+ DotBit = 128;
+ LineCount ++;
+
+ memset(CompBuffer, 0, header->cupsWidth);
+ }
+ }
+ else
+ {
+ int plane; /* Current plane */
+ int bytes; /* Bytes per plane */
+ int xstep, ystep; /* X & Y resolutions */
+
+
+ /*
+ * Write a single line of bitmap data as needed...
+ */
+
+ xstep = 3600 / header->HWResolution[0];
+ ystep = 3600 / header->HWResolution[1];
+ bytes = header->cupsBytesPerLine / NumPlanes;
+
+ for (plane = 0; plane < NumPlanes; plane ++)
+ {
+ /*
+ * Skip blank data...
+ */
+
+ if (!Planes[plane][0] &&
+ memcmp(Planes[plane], Planes[plane] + 1, bytes - 1) == 0)
+ continue;
+
+ /*
+ * Output whitespace as needed...
+ */
+
+ if (Feed > 0)
+ {
+ pwrite("\033(v\002\000", 5); /* Relative vertical position */
+ putchar(Feed);
+ putchar(Feed >> 8);
+
+ Feed = 0;
+ }
+
+ CompressData(Planes[plane], bytes, plane, header->cupsCompression, xstep,
+ ystep);
+ }
+
+ Feed ++;
+ }
+}
+
+
+/*
+ * 'OutputRows()' - Output 8, 24, or 48 rows.
+ */
+
+void
+OutputRows(const cups_page_header_t *header, /* I - Page image header */
+ int row) /* I - Row number (0 or 1) */
+{
+ unsigned i, n; /* Looping vars */
+ int dot_count, /* Number of bytes to print */
+ dot_min; /* Minimum number of bytes */
+ unsigned char *dot_ptr, /* Pointer to print data */
+ *ptr; /* Current data */
+
+
+ dot_min = DotBytes * DotColumns;
+
+ if (LineBuffers[row][0] != 0 ||
+ memcmp(LineBuffers[row], LineBuffers[row] + 1,
+ header->cupsWidth * DotBytes - 1))
+ {
+ /*
+ * Skip leading space...
+ */
+
+ i = 0;
+ dot_count = header->cupsWidth * DotBytes;
+ dot_ptr = LineBuffers[row];
+
+ while (dot_count >= dot_min && dot_ptr[0] == 0 &&
+ memcmp(dot_ptr, dot_ptr + 1, dot_min - 1) == 0)
+ {
+ i ++;
+ dot_ptr += dot_min;
+ dot_count -= dot_min;
+ }
+
+ /*
+ * Skip trailing space...
+ */
+
+ while (dot_count >= dot_min && dot_ptr[dot_count - dot_min] == 0 &&
+ memcmp(dot_ptr + dot_count - dot_min,
+ dot_ptr + dot_count - dot_min + 1, dot_min - 1) == 0)
+ dot_count -= dot_min;
+
+ /*
+ * Position print head for printing...
+ */
+
+ putchar(0x1b);
+ putchar('$');
+ putchar(i & 255);
+ putchar(i >> 8);
+
+ /*
+ * Start bitmap graphics for this line...
+ */
+
+ printf("\033*"); /* Select bit image */
+ switch (header->HWResolution[0])
+ {
+ case 60 : /* 60x60/72 DPI gfx */
+ putchar(0);
+ break;
+ case 120 : /* 120x60/72 DPI gfx */
+ putchar(1);
+ break;
+ case 180 : /* 180 DPI gfx */
+ putchar(39);
+ break;
+ case 240 : /* 240x72 DPI gfx */
+ putchar(3);
+ break;
+ case 360 : /* 360x180/360 DPI gfx */
+ if (header->HWResolution[1] == 180)
+ {
+ if (Shingling && LineCount != 0)
+ putchar(40); /* 360x180 fast */
+ else
+ putchar(41); /* 360x180 slow */
+ }
+ else
+ {
+ if (Shingling && LineCount != 0)
+ putchar(72); /* 360x360 fast */
+ else
+ putchar(73); /* 360x360 slow */
+ }
+ break;
+ }
+
+ n = (unsigned)dot_count / DotBytes;
+ putchar(n & 255);
+ putchar(n / 256);
+
+ /*
+ * Write the graphics data...
+ */
+
+ if (header->HWResolution[0] == 120 ||
+ header->HWResolution[0] == 240)
+ {
+ /*
+ * Need to interleave the dots to avoid hosing the print head...
+ */
+
+ for (n = dot_count / 2, ptr = dot_ptr; n > 0; n --, ptr += 2)
+ {
+ putchar(*ptr);
+ putchar(0);
+ }
+
+ /*
+ * Move the head back and print the odd bytes...
+ */
+
+ putchar(0x1b);
+ putchar('$');
+ putchar(i & 255);
+ putchar(i >> 8);
+
+ if (header->HWResolution[0] == 120)
+ printf("\033*\001"); /* Select bit image */
+ else
+ printf("\033*\003"); /* Select bit image */
+
+ n = (unsigned)dot_count / DotBytes;
+ putchar(n & 255);
+ putchar(n / 256);
+
+ for (n = dot_count / 2, ptr = dot_ptr + 1; n > 0; n --, ptr += 2)
+ {
+ putchar(0);
+ putchar(*ptr);
+ }
+ }
+ else
+ pwrite(dot_ptr, dot_count);
+ }
+
+ /*
+ * Feed the paper...
+ */
+
+ putchar('\n');
+
+ if (Shingling && row == 1)
+ {
+ if (header->HWResolution[1] == 360)
+ printf("\n\n\n\n");
+ else
+ printf("\n");
+ }
+
+ fflush(stdout);
+
+ /*
+ * Clear the buffer...
+ */
+
+ memset(LineBuffers[row], 0, header->cupsWidth * DotBytes);
+}
+
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int fd; /* File descriptor */
+ cups_raster_t *ras; /* Raster stream for printing */
+ cups_page_header_t header; /* Page header from file */
+ ppd_file_t *ppd; /* PPD file */
+ int page; /* Current page */
+ int y; /* Current line */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ /*
+ * We don't have the correct number of arguments; write an error message
+ * and return.
+ */
+
+ fputs("ERROR: rastertoepson job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Open the page stream...
+ */
+
+ if (argc == 7)
+ {
+ if ((fd = open(argv[6], O_RDONLY)) == -1)
+ {
+ perror("ERROR: Unable to open raster file - ");
+ sleep(1);
+ return (1);
+ }
+ }
+ else
+ fd = 0;
+
+ ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
+
+ /*
+ * Initialize the print device...
+ */
+
+ ppd = ppdOpenFile(getenv("PPD"));
+
+ Setup();
+
+ /*
+ * Process pages as needed...
+ */
+
+ page = 0;
+
+ while (cupsRasterReadHeader(ras, &header))
+ {
+ /*
+ * Write a status message with the page number and number of copies.
+ */
+
+ page ++;
+
+ fprintf(stderr, "PAGE: %d %d\n", page, header.NumCopies);
+
+ /*
+ * Start the page...
+ */
+
+ StartPage(ppd, &header);
+
+ /*
+ * Loop for each line on the page...
+ */
+
+ for (y = 0; y < header.cupsHeight; y ++)
+ {
+ /*
+ * Let the user know how far we have progressed...
+ */
+
+ if ((y & 127) == 0)
+ fprintf(stderr, "INFO: Printing page %d, %d%% complete...\n", page,
+ 100 * y / header.cupsHeight);
+
+ /*
+ * Read a line of graphics...
+ */
+
+ if (cupsRasterReadPixels(ras, Planes[0], header.cupsBytesPerLine) < 1)
+ break;
+
+ /*
+ * Write it to the printer...
+ */
+
+ OutputLine(&header);
+ }
+
+ /*
+ * Eject the page...
+ */
+
+ EndPage(&header);
+ }
+
+ /*
+ * Shutdown the printer...
+ */
+
+ Shutdown();
+
+ ppdClose(ppd);
+
+ /*
+ * Close the raster stream...
+ */
+
+ cupsRasterClose(ras);
+ if (fd != 0)
+ close(fd);
+
+ /*
+ * If no pages were printed, send an error message...
+ */
+
+ if (page == 0)
+ fputs("ERROR: No pages found!\n", stderr);
+ else
+ fputs("INFO: " CUPS_SVERSION " is ready to print.\n", stderr);
+
+ return (page == 0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/rastertohp.c b/filter/rastertohp.c
new file mode 100644
index 000000000..6123b2569
--- /dev/null
+++ b/filter/rastertohp.c
@@ -0,0 +1,808 @@
+/*
+ * "$Id$"
+ *
+ * Hewlett-Packard Page Control Language filter for the Common UNIX
+ * Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * Setup() - Prepare the printer for printing.
+ * StartPage() - Start a page of graphics.
+ * EndPage() - Finish a page of graphics.
+ * Shutdown() - Shutdown the printer.
+ * CancelJob() - Cancel the current job...
+ * CompressData() - Compress a line of graphics.
+ * OutputLine() - Output a line of graphics.
+ * main() - Main entry and processing of driver.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/cups.h>
+#include <cups/string.h>
+#include "raster.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+
+
+/*
+ * Globals...
+ */
+
+unsigned char *Planes[4], /* Output buffers */
+ *CompBuffer, /* Compression buffer */
+ *BitBuffer; /* Buffer for output bits */
+int NumPlanes, /* Number of color planes */
+ ColorBits, /* Number of bits per color */
+ Feed, /* Number of lines to skip */
+ Duplex, /* Current duplex mode */
+ Page; /* Current page number */
+
+
+/*
+ * Prototypes...
+ */
+
+void Setup(void);
+void StartPage(ppd_file_t *ppd, cups_page_header_t *header);
+void EndPage(void);
+void Shutdown(void);
+
+void CancelJob(int sig);
+void CompressData(unsigned char *line, int length, int plane, int type);
+void OutputLine(cups_page_header_t *header);
+
+
+/*
+ * 'Setup()' - Prepare the printer for printing.
+ */
+
+void
+Setup(void)
+{
+ /*
+ * Send a PCL reset sequence.
+ */
+
+ putchar(0x1b);
+ putchar('E');
+}
+
+
+/*
+ * 'StartPage()' - Start a page of graphics.
+ */
+
+void
+StartPage(ppd_file_t *ppd, /* I - PPD file */
+ cups_page_header_t *header) /* I - Page header */
+{
+ int plane; /* Looping var */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Register a signal handler to eject the current page if the
+ * job is cancelled.
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, CancelJob);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = CancelJob;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, CancelJob);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Setup printer/job attributes...
+ */
+
+ Duplex = header->Duplex;
+ ColorBits = header->cupsBitsPerColor;
+
+ if (!Duplex || (Page & 1))
+ {
+ /*
+ * Set the media type, position, and size...
+ */
+
+ printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */
+ printf("\033&l0O"); /* Set portrait orientation */
+
+ switch (header->PageSize[1])
+ {
+ case 540 : /* Monarch Envelope */
+ printf("\033&l80A"); /* Set page size */
+ break;
+
+ case 624 : /* DL Envelope */
+ printf("\033&l90A"); /* Set page size */
+ break;
+
+ case 649 : /* C5 Envelope */
+ printf("\033&l91A"); /* Set page size */
+ break;
+
+ case 684 : /* COM-10 Envelope */
+ printf("\033&l81A"); /* Set page size */
+ break;
+
+ case 709 : /* B5 Envelope */
+ printf("\033&l100A"); /* Set page size */
+ break;
+
+ case 756 : /* Executive */
+ printf("\033&l1A"); /* Set page size */
+ break;
+
+ case 792 : /* Letter */
+ printf("\033&l2A"); /* Set page size */
+ break;
+
+ case 842 : /* A4 */
+ printf("\033&l26A"); /* Set page size */
+ break;
+
+ case 1008 : /* Legal */
+ printf("\033&l3A"); /* Set page size */
+ break;
+
+ case 1191 : /* A3 */
+ printf("\033&l27A"); /* Set page size */
+ break;
+
+ case 1224 : /* Tabloid */
+ printf("\033&l6A"); /* Set page size */
+ break;
+ }
+
+ printf("\033&l%dP", /* Set page length */
+ header->PageSize[1] / 12);
+ printf("\033&l0E"); /* Set top margin to 0 */
+
+ printf("\033&l%dX", header->NumCopies); /* Set number copies */
+
+ if (header->MediaPosition)
+ printf("\033&l%dH", /* Set media position */
+ header->MediaPosition);
+
+ if (header->cupsMediaType)
+ printf("\033&l%dM", /* Set media type */
+ header->cupsMediaType);
+
+ if (header->Duplex)
+ printf("\033&l%dS", /* Set duplex mode */
+ header->Duplex + header->Tumble);
+
+ printf("\033&l0L"); /* Turn off perforation skip */
+
+ if (ppd && ppd->model_number == 2)
+ printf("\033&l-2H"); /* Load media */
+ }
+ else
+ printf("\033&a2G"); /* Set back side */
+
+ /*
+ * Set graphics mode...
+ */
+
+ printf("\033*t%dR", header->HWResolution[0]); /* Set resolution */
+
+ if (ppd->model_number == 2)
+ {
+ /*
+ * Figure out the number of color planes...
+ */
+
+ if (header->cupsColorSpace == CUPS_CSPACE_KCMY)
+ NumPlanes = 4;
+ else
+ NumPlanes = 1;
+
+ /*
+ * Send 26-byte configure image data command with horizontal and
+ * vertical resolutions as well as a color count...
+ */
+
+ printf("\033*g26W");
+ putchar(2); /* Format 2 */
+ putchar(NumPlanes); /* Output planes */
+
+ putchar(header->HWResolution[0] >> 8); /* Black resolution */
+ putchar(header->HWResolution[0]);
+ putchar(header->HWResolution[1] >> 8);
+ putchar(header->HWResolution[1]);
+ putchar(0);
+ putchar(1 << ColorBits); /* # of black levels */
+
+ putchar(header->HWResolution[0] >> 8); /* Cyan resolution */
+ putchar(header->HWResolution[0]);
+ putchar(header->HWResolution[1] >> 8);
+ putchar(header->HWResolution[1]);
+ putchar(0);
+ putchar(1 << ColorBits); /* # of cyan levels */
+
+ putchar(header->HWResolution[0] >> 8); /* Magenta resolution */
+ putchar(header->HWResolution[0]);
+ putchar(header->HWResolution[1] >> 8);
+ putchar(header->HWResolution[1]);
+ putchar(0);
+ putchar(1 << ColorBits); /* # of magenta levels */
+
+ putchar(header->HWResolution[0] >> 8); /* Yellow resolution */
+ putchar(header->HWResolution[0]);
+ putchar(header->HWResolution[1] >> 8);
+ putchar(header->HWResolution[1]);
+ putchar(0);
+ putchar(1 << ColorBits); /* # of yellow levels */
+ }
+ else
+ {
+ if (header->cupsColorSpace == CUPS_CSPACE_KCMY)
+ {
+ NumPlanes = 4;
+ printf("\033*r-4U"); /* Set KCMY graphics */
+ }
+ else if (header->cupsColorSpace == CUPS_CSPACE_CMY)
+ {
+ NumPlanes = 3;
+ printf("\033*r-3U"); /* Set CMY graphics */
+ }
+ else
+ NumPlanes = 1; /* Black&white graphics */
+ }
+
+ /*
+ * Set size and position of graphics...
+ */
+
+ printf("\033*r%dS", header->cupsWidth); /* Set width */
+ printf("\033*r%dT", header->cupsHeight); /* Set height */
+
+ printf("\033&a0H"); /* Set horizontal position */
+
+ if (ppd)
+ printf("\033&a%.0fV", /* Set vertical position */
+ 10.0 * (ppd->sizes[0].length - ppd->sizes[0].top));
+ else
+ printf("\033&a0V"); /* Set top-of-page */
+
+ printf("\033*r1A"); /* Start graphics */
+
+ if (header->cupsCompression)
+ printf("\033*b%dM", /* Set compression */
+ header->cupsCompression);
+
+ Feed = 0; /* No blank lines yet */
+
+ /*
+ * Allocate memory for a line of graphics...
+ */
+
+ Planes[0] = malloc(header->cupsBytesPerLine);
+ for (plane = 1; plane < NumPlanes; plane ++)
+ Planes[plane] = Planes[0] + plane * header->cupsBytesPerLine / NumPlanes;
+
+ if (ColorBits > 1)
+ BitBuffer = malloc(ColorBits * ((header->cupsWidth + 7) / 8));
+ else
+ BitBuffer = NULL;
+
+ if (header->cupsCompression)
+ CompBuffer = malloc(header->cupsBytesPerLine * 2);
+ else
+ CompBuffer = NULL;
+}
+
+
+/*
+ * 'EndPage()' - Finish a page of graphics.
+ */
+
+void
+EndPage(void)
+{
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Eject the current page...
+ */
+
+ if (NumPlanes > 1)
+ {
+ printf("\033*rC"); /* End color GFX */
+
+ if (!(Duplex && (Page & 1)))
+ printf("\033&l0H"); /* Eject current page */
+ }
+ else
+ {
+ printf("\033*r0B"); /* End GFX */
+
+ if (!(Duplex && (Page & 1)))
+ printf("\014"); /* Eject current page */
+ }
+
+ fflush(stdout);
+
+ /*
+ * Unregister the signal handler...
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Free memory...
+ */
+
+ free(Planes[0]);
+
+ if (BitBuffer)
+ free(BitBuffer);
+
+ if (CompBuffer)
+ free(CompBuffer);
+}
+
+
+/*
+ * 'Shutdown()' - Shutdown the printer.
+ */
+
+void
+Shutdown(void)
+{
+ /*
+ * Send a PCL reset sequence.
+ */
+
+ putchar(0x1b);
+ putchar('E');
+}
+
+
+/*
+ * 'CancelJob()' - Cancel the current job...
+ */
+
+void
+CancelJob(int sig) /* I - Signal */
+{
+ int i; /* Looping var */
+
+
+ (void)sig;
+
+ /*
+ * Send out lots of NUL bytes to clear out any pending raster data...
+ */
+
+ for (i = 0; i < 600; i ++)
+ putchar(0);
+
+ /*
+ * End the current page and exit...
+ */
+
+ EndPage();
+ Shutdown();
+
+ exit(0);
+}
+
+
+/*
+ * 'CompressData()' - Compress a line of graphics.
+ */
+
+void
+CompressData(unsigned char *line, /* I - Data to compress */
+ int length, /* I - Number of bytes */
+ int plane, /* I - Color plane */
+ int type) /* I - Type of compression */
+{
+ unsigned char *line_ptr, /* Current byte pointer */
+ *line_end, /* End-of-line byte pointer */
+ *comp_ptr, /* Pointer into compression buffer */
+ *start; /* Start of compression sequence */
+ int count; /* Count of bytes for output */
+
+
+ switch (type)
+ {
+ default :
+ /*
+ * Do no compression...
+ */
+
+ line_ptr = line;
+ line_end = line + length;
+ break;
+
+ case 1 :
+ /*
+ * Do run-length encoding...
+ */
+
+ line_end = line + length;
+ for (line_ptr = line, comp_ptr = CompBuffer;
+ line_ptr < line_end;
+ comp_ptr += 2, line_ptr += count)
+ {
+ for (count = 1;
+ (line_ptr + count) < line_end &&
+ line_ptr[0] == line_ptr[count] &&
+ count < 256;
+ count ++);
+
+ comp_ptr[0] = count - 1;
+ comp_ptr[1] = line_ptr[0];
+ }
+
+ line_ptr = CompBuffer;
+ line_end = comp_ptr;
+ break;
+
+ case 2 :
+ /*
+ * Do TIFF pack-bits encoding...
+ */
+
+ line_ptr = line;
+ line_end = line + length;
+ comp_ptr = CompBuffer;
+
+ while (line_ptr < line_end)
+ {
+ if ((line_ptr + 1) >= line_end)
+ {
+ /*
+ * Single byte on the end...
+ */
+
+ *comp_ptr++ = 0x00;
+ *comp_ptr++ = *line_ptr++;
+ }
+ else if (line_ptr[0] == line_ptr[1])
+ {
+ /*
+ * Repeated sequence...
+ */
+
+ line_ptr ++;
+ count = 2;
+
+ while (line_ptr < (line_end - 1) &&
+ line_ptr[0] == line_ptr[1] &&
+ count < 127)
+ {
+ line_ptr ++;
+ count ++;
+ }
+
+ *comp_ptr++ = 257 - count;
+ *comp_ptr++ = *line_ptr++;
+ }
+ else
+ {
+ /*
+ * Non-repeated sequence...
+ */
+
+ start = line_ptr;
+ line_ptr ++;
+ count = 1;
+
+ while (line_ptr < (line_end - 1) &&
+ line_ptr[0] != line_ptr[1] &&
+ count < 127)
+ {
+ line_ptr ++;
+ count ++;
+ }
+
+ *comp_ptr++ = count - 1;
+
+ memcpy(comp_ptr, start, count);
+ comp_ptr += count;
+ }
+ }
+
+ line_ptr = CompBuffer;
+ line_end = comp_ptr;
+ break;
+ }
+
+ /*
+ * Set the length of the data and write a raster plane...
+ */
+
+ printf("\033*b%d%c", line_end - line_ptr, plane);
+ fwrite(line_ptr, line_end - line_ptr, 1, stdout);
+}
+
+
+/*
+ * 'OutputLine()' - Output a line of graphics.
+ */
+
+void
+OutputLine(cups_page_header_t *header) /* I - Page header */
+{
+ int plane, /* Current plane */
+ bytes, /* Bytes to write */
+ count; /* Bytes to convert */
+ unsigned char bit, /* Current plane data */
+ bit0, /* Current low bit data */
+ bit1, /* Current high bit data */
+ *plane_ptr, /* Pointer into Planes */
+ *bit_ptr; /* Pointer into BitBuffer */
+
+
+ /*
+ * Output whitespace as needed...
+ */
+
+ if (Feed > 0)
+ {
+ printf("\033*b%dY", Feed);
+ Feed = 0;
+ }
+
+ /*
+ * Write bitmap data as needed...
+ */
+
+ bytes = (header->cupsWidth + 7) / 8;
+
+ for (plane = 0; plane < NumPlanes; plane ++)
+ if (ColorBits == 1)
+ {
+ /*
+ * Send bits as-is...
+ */
+
+ CompressData(Planes[plane], bytes, plane < (NumPlanes - 1) ? 'V' : 'W',
+ header->cupsCompression);
+ }
+ else
+ {
+ /*
+ * Separate low and high bit data into separate buffers.
+ */
+
+ for (count = header->cupsBytesPerLine / NumPlanes,
+ plane_ptr = Planes[plane], bit_ptr = BitBuffer;
+ count > 0;
+ count -= 2, plane_ptr += 2, bit_ptr ++)
+ {
+ bit = plane_ptr[0];
+
+ bit0 = ((bit & 64) << 1) | ((bit & 16) << 2) | ((bit & 4) << 3) | ((bit & 1) << 4);
+ bit1 = (bit & 128) | ((bit & 32) << 1) | ((bit & 8) << 2) | ((bit & 2) << 3);
+
+ if (count > 1)
+ {
+ bit = plane_ptr[1];
+
+ bit0 |= (bit & 1) | ((bit & 4) >> 1) | ((bit & 16) >> 2) | ((bit & 64) >> 3);
+ bit1 |= ((bit & 2) >> 1) | ((bit & 8) >> 2) | ((bit & 32) >> 3) | ((bit & 128) >> 4);
+ }
+
+ bit_ptr[0] = bit0;
+ bit_ptr[bytes] = bit1;
+ }
+
+ /*
+ * Send low and high bits...
+ */
+
+ CompressData(BitBuffer, bytes, 'V', header->cupsCompression);
+ CompressData(BitBuffer + bytes, bytes, plane < (NumPlanes - 1) ? 'V' : 'W',
+ header->cupsCompression);
+ }
+
+ fflush(stdout);
+}
+
+
+/*
+ * 'main()' - Main entry and processing of driver.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int fd; /* File descriptor */
+ cups_raster_t *ras; /* Raster stream for printing */
+ cups_page_header_t header; /* Page header from file */
+ int y; /* Current line */
+ ppd_file_t *ppd; /* PPD file */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ /*
+ * We don't have the correct number of arguments; write an error message
+ * and return.
+ */
+
+ fputs("ERROR: rastertopcl job-id user title copies options [file]\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Open the page stream...
+ */
+
+ if (argc == 7)
+ {
+ if ((fd = open(argv[6], O_RDONLY)) == -1)
+ {
+ perror("ERROR: Unable to open raster file - ");
+ sleep(1);
+ return (1);
+ }
+ }
+ else
+ fd = 0;
+
+ ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
+
+ /*
+ * Initialize the print device...
+ */
+
+ ppd = ppdOpenFile(getenv("PPD"));
+
+ Setup();
+
+ /*
+ * Process pages as needed...
+ */
+
+ Page = 0;
+
+ while (cupsRasterReadHeader(ras, &header))
+ {
+ /*
+ * Write a status message with the page number and number of copies.
+ */
+
+ Page ++;
+
+ fprintf(stderr, "PAGE: %d %d\n", Page, header.NumCopies);
+
+ /*
+ * Start the page...
+ */
+
+ StartPage(ppd, &header);
+
+ /*
+ * Loop for each line on the page...
+ */
+
+ for (y = 0; y < header.cupsHeight; y ++)
+ {
+ /*
+ * Let the user know how far we have progressed...
+ */
+
+ if ((y & 127) == 0)
+ fprintf(stderr, "INFO: Printing page %d, %d%% complete...\n", Page,
+ 100 * y / header.cupsHeight);
+
+ /*
+ * Read a line of graphics...
+ */
+
+ if (cupsRasterReadPixels(ras, Planes[0], header.cupsBytesPerLine) < 1)
+ break;
+
+ /*
+ * See if the line is blank; if not, write it to the printer...
+ */
+
+ if (Planes[0][0] ||
+ memcmp(Planes[0], Planes[0] + 1, header.cupsBytesPerLine - 1))
+ OutputLine(&header);
+ else
+ Feed ++;
+ }
+
+ /*
+ * Eject the page...
+ */
+
+ EndPage();
+ }
+
+ /*
+ * Shutdown the printer...
+ */
+
+ Shutdown();
+
+ if (ppd)
+ ppdClose(ppd);
+
+ /*
+ * Close the raster stream...
+ */
+
+ cupsRasterClose(ras);
+ if (fd != 0)
+ close(fd);
+
+ /*
+ * If no pages were printed, send an error message...
+ */
+
+ if (Page == 0)
+ fputs("ERROR: No pages found!\n", stderr);
+ else
+ fputs("INFO: " CUPS_SVERSION " is ready to print.\n", stderr);
+
+ return (Page == 0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/textcommon.c b/filter/textcommon.c
new file mode 100644
index 000000000..8ed368d89
--- /dev/null
+++ b/filter/textcommon.c
@@ -0,0 +1,1185 @@
+/*
+ * "$Id$"
+ *
+ * Common text filter routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * TextMain() - Standard main entry for text filters.
+ * compare_keywords() - Compare two C/C++ keywords.
+ * getutf8() - Get a UTF-8 encoded wide character...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "textcommon.h"
+
+
+/*
+ * Globals...
+ */
+
+int WrapLines = 1, /* Wrap text in lines */
+ SizeLines = 60, /* Number of lines on a page */
+ SizeColumns = 80, /* Number of columns on a line */
+ PageColumns = 1, /* Number of columns on a page */
+ ColumnGutter = 0, /* Number of characters between text columns */
+ ColumnWidth = 80, /* Width of each column */
+ PrettyPrint = 0, /* Do pretty code formatting */
+ Copies = 1; /* Number of copies */
+lchar_t **Page = NULL; /* Page characters */
+int NumPages = 0; /* Number of pages in document */
+float CharsPerInch = 10; /* Number of character columns per inch */
+float LinesPerInch = 6; /* Number of lines per inch */
+int UTF8 = 0; /* Use UTF-8 encoding? */
+int NumKeywords = 0; /* Number of known keywords */
+char **Keywords = NULL; /* List of known keywords */
+
+
+/*
+ * Local globals...
+ */
+
+static char *code_keywords[] = /* List of known C/C++ keywords... */
+ {
+ "and",
+ "and_eq",
+ "asm",
+ "auto",
+ "bitand",
+ "bitor",
+ "bool",
+ "break",
+ "case",
+ "catch",
+ "char",
+ "class",
+ "compl",
+ "const",
+ "const_cast",
+ "continue",
+ "default",
+ "delete",
+ "do",
+ "double",
+ "dynamic_cast",
+ "else",
+ "enum",
+ "explicit",
+ "extern",
+ "false",
+ "float",
+ "for",
+ "friend",
+ "goto",
+ "if",
+ "inline",
+ "int",
+ "long",
+ "mutable",
+ "namespace",
+ "new",
+ "not",
+ "not_eq",
+ "operator",
+ "or",
+ "or_eq",
+ "private",
+ "protected",
+ "public",
+ "register",
+ "return",
+ "short",
+ "signed",
+ "sizeof",
+ "static",
+ "static_cast",
+ "struct",
+ "switch",
+ "template",
+ "this",
+ "throw",
+ "true",
+ "try",
+ "typedef",
+ "typename",
+ "union",
+ "unsigned",
+ "virtual",
+ "void",
+ "volatile",
+ "while",
+ "xor",
+ "xor_eq"
+ },
+ *sh_keywords[] = /* List of known Boure/Korn/zsh/bash keywords... */
+ {
+ "alias",
+ "bg",
+ "break",
+ "case",
+ "cd",
+ "command",
+ "continue",
+ "do",
+ "done",
+ "echo",
+ "elif",
+ "else",
+ "esac",
+ "eval",
+ "exec",
+ "exit",
+ "export",
+ "fc",
+ "fg",
+ "fi",
+ "for",
+ "function",
+ "getopts",
+ "if",
+ "in",
+ "jobs",
+ "kill",
+ "let",
+ "limit",
+ "newgrp",
+ "print",
+ "pwd",
+ "read",
+ "readonly",
+ "return",
+ "select",
+ "set",
+ "shift",
+ "test",
+ "then",
+ "time",
+ "times",
+ "trap",
+ "typeset",
+ "ulimit",
+ "umask",
+ "unalias",
+ "unlimit",
+ "unset",
+ "until",
+ "wait",
+ "whence"
+ "while",
+ },
+ *csh_keywords[] = /* List of known csh/tcsh keywords... */
+ {
+ "alias",
+ "aliases",
+ "bg",
+ "bindkey",
+ "break",
+ "breaksw",
+ "builtins",
+ "case",
+ "cd",
+ "chdir",
+ "complete",
+ "continue",
+ "default",
+ "dirs",
+ "echo",
+ "echotc",
+ "else",
+ "end",
+ "endif",
+ "eval",
+ "exec",
+ "exit",
+ "fg",
+ "foreach",
+ "glob",
+ "goto",
+ "history",
+ "if",
+ "jobs",
+ "kill",
+ "limit",
+ "login",
+ "logout",
+ "ls",
+ "nice",
+ "nohup",
+ "notify",
+ "onintr",
+ "popd",
+ "pushd",
+ "pwd",
+ "rehash",
+ "repeat",
+ "set",
+ "setenv",
+ "settc",
+ "shift",
+ "source",
+ "stop",
+ "suspend",
+ "switch",
+ "telltc",
+ "then",
+ "time",
+ "umask",
+ "unalias",
+ "unbindkey",
+ "unhash",
+ "unlimit",
+ "unset",
+ "unsetenv",
+ "wait",
+ "where",
+ "which",
+ "while"
+ },
+ *perl_keywords[] = /* List of known perl keywords... */
+ {
+ "abs",
+ "accept",
+ "alarm",
+ "and",
+ "atan2",
+ "bind",
+ "binmode",
+ "bless",
+ "caller",
+ "chdir",
+ "chmod",
+ "chomp",
+ "chop",
+ "chown",
+ "chr",
+ "chroot",
+ "closdir",
+ "close",
+ "connect",
+ "continue",
+ "cos",
+ "crypt",
+ "dbmclose",
+ "dbmopen",
+ "defined",
+ "delete",
+ "die",
+ "do",
+ "dump",
+ "each",
+ "else",
+ "elsif",
+ "endgrent",
+ "endhostent",
+ "endnetent",
+ "endprotoent",
+ "endpwent",
+ "endservent",
+ "eof",
+ "eval",
+ "exec",
+ "exists",
+ "exit",
+ "exp",
+ "fcntl",
+ "fileno",
+ "flock",
+ "for",
+ "foreach",
+ "fork",
+ "format",
+ "formline",
+ "getc",
+ "getgrent",
+ "getgrgid",
+ "getgrnam",
+ "gethostbyaddr",
+ "gethostbyname",
+ "gethostent",
+ "getlogin",
+ "getnetbyaddr",
+ "getnetbyname",
+ "getnetent",
+ "getpeername",
+ "getpgrp",
+ "getppid",
+ "getpriority",
+ "getprotobyname",
+ "getprotobynumber",
+ "getprotoent",
+ "getpwent",
+ "getpwnam",
+ "getpwuid",
+ "getservbyname",
+ "getservbyport",
+ "getservent",
+ "getsockname",
+ "getsockopt",
+ "glob",
+ "gmtime",
+ "goto",
+ "grep",
+ "hex",
+ "if",
+ "import",
+ "index",
+ "int",
+ "ioctl",
+ "join",
+ "keys",
+ "kill",
+ "last",
+ "lc",
+ "lcfirst",
+ "length",
+ "link",
+ "listen",
+ "local",
+ "localtime",
+ "log",
+ "lstat",
+ "map",
+ "mkdir",
+ "msgctl",
+ "msgget",
+ "msgrcv",
+ "msgsend",
+ "my",
+ "next",
+ "no",
+ "not",
+ "oct",
+ "open",
+ "opendir",
+ "or",
+ "ord",
+ "pack",
+ "package",
+ "pipe",
+ "pop",
+ "pos",
+ "print",
+ "printf",
+ "push",
+ "quotemeta",
+ "rand",
+ "read",
+ "readdir",
+ "readlink",
+ "recv",
+ "redo",
+ "ref",
+ "rename",
+ "require",
+ "reset",
+ "return",
+ "reverse",
+ "rewinddir",
+ "rindex",
+ "rmdir",
+ "scalar",
+ "seek",
+ "seekdir",
+ "select",
+ "semctl",
+ "semget",
+ "semop",
+ "send",
+ "setgrent",
+ "sethostent",
+ "setnetent",
+ "setpgrp",
+ "setpriority",
+ "setprotoent",
+ "setpwent",
+ "setservent",
+ "setsockopt",
+ "shift",
+ "shmctl",
+ "shmget",
+ "shmread",
+ "shmwrite",
+ "shutdown",
+ "sin",
+ "sleep",
+ "socket",
+ "socketpair",
+ "sort",
+ "splice",
+ "split",
+ "sprintf",
+ "sqrt",
+ "srand",
+ "stat",
+ "study",
+ "sub",
+ "substr",
+ "symlink",
+ "syscall",
+ "sysread",
+ "sysseek",
+ "system",
+ "syswrite",
+ "tell",
+ "telldir",
+ "tie",
+ "tied",
+ "time",
+ "times"
+ "times",
+ "truncate",
+ "uc",
+ "ucfirst",
+ "umask",
+ "undef",
+ "unless",
+ "unlink",
+ "unpack",
+ "unshift",
+ "untie",
+ "until",
+ "use",
+ "utime",
+ "values",
+ "vec",
+ "wait",
+ "waitpid",
+ "wantarray",
+ "warn",
+ "while",
+ "write"
+ };
+
+
+/*
+ * Local functions...
+ */
+
+static int compare_keywords(const void *, const void *);
+static int getutf8(FILE *fp);
+
+
+/*
+ * 'TextMain()' - Standard main entry for text filters.
+ */
+
+int /* O - Exit status */
+TextMain(const char *name, /* I - Name of filter */
+ int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ FILE *fp; /* Print file */
+ ppd_file_t *ppd; /* PPD file */
+ int i, /* Looping var */
+ ch, /* Current char from file */
+ lastch, /* Previous char from file */
+ attr, /* Current attribute */
+ line, /* Current line */
+ column, /* Current column */
+ page_column; /* Current page column */
+ int num_options; /* Number of print options */
+ cups_option_t *options; /* Print options */
+ const char *val; /* Option value */
+ char keyword[64], /* Keyword string */
+ *keyptr; /* Pointer into string */
+ int keycol; /* Column where keyword starts */
+ int ccomment; /* Inside a C-style comment? */
+ int cstring; /* Inside a C string */
+
+
+ /*
+ * Make sure status messages are not buffered...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * Check command-line...
+ */
+
+ if (argc < 6 || argc > 7)
+ {
+ fprintf(stderr, "ERROR: %s job-id user title copies options [file]\n",
+ name);
+ return (1);
+ }
+
+ /*
+ * If we have 7 arguments, print the file named on the command-line.
+ * Otherwise, send stdin instead...
+ */
+
+ if (argc == 6)
+ fp = stdin;
+ else
+ {
+ /*
+ * Try to open the print file...
+ */
+
+ if ((fp = fopen(argv[6], "rb")) == NULL)
+ {
+ perror("ERROR: unable to open print file - ");
+ return (1);
+ }
+ }
+
+ /*
+ * Process command-line options and write the prolog...
+ */
+
+ options = NULL;
+ num_options = cupsParseOptions(argv[5], 0, &options);
+
+ if ((val = cupsGetOption("prettyprint", num_options, options)) != NULL &&
+ strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 &&
+ strcasecmp(val, "false") != 0)
+ {
+ PageLeft = 72.0f;
+ PageRight = PageWidth - 36.0f;
+ PageBottom = PageBottom > 36.0f ? PageBottom : 36.0f;
+ PageTop = PageLength - 36.0f;
+ CharsPerInch = 12;
+ LinesPerInch = 8;
+
+ if ((val = getenv("CONTENT_TYPE")) == NULL)
+ {
+ PrettyPrint = PRETTY_CODE;
+ NumKeywords = sizeof(code_keywords) / sizeof(code_keywords[0]);
+ Keywords = code_keywords;
+ }
+ else if (strcasecmp(val, "application/x-cshell") == 0)
+ {
+ PrettyPrint = PRETTY_SHELL;
+ NumKeywords = sizeof(csh_keywords) / sizeof(csh_keywords[0]);
+ Keywords = csh_keywords;
+ }
+ else if (strcasecmp(val, "application/x-perl") == 0)
+ {
+ PrettyPrint = PRETTY_PERL;
+ NumKeywords = sizeof(perl_keywords) / sizeof(perl_keywords[0]);
+ Keywords = perl_keywords;
+ }
+ else if (strcasecmp(val, "application/x-shell") == 0)
+ {
+ PrettyPrint = PRETTY_SHELL;
+ NumKeywords = sizeof(sh_keywords) / sizeof(sh_keywords[0]);
+ Keywords = sh_keywords;
+ }
+ else
+ {
+ PrettyPrint = PRETTY_CODE;
+ NumKeywords = sizeof(code_keywords) / sizeof(code_keywords[0]);
+ Keywords = code_keywords;
+ }
+ }
+
+ ppd = SetCommonOptions(num_options, options, 1);
+
+ if ((val = cupsGetOption("wrap", num_options, options)) == NULL)
+ WrapLines = 0;
+ else
+ WrapLines = strcasecmp(val, "true") == 0;
+
+ if ((val = cupsGetOption("columns", num_options, options)) != NULL)
+ PageColumns = atoi(val);
+
+ if ((val = cupsGetOption("cpi", num_options, options)) != NULL)
+ CharsPerInch = atof(val);
+
+ if ((val = cupsGetOption("lpi", num_options, options)) != NULL)
+ LinesPerInch = atof(val);
+
+ if (PrettyPrint)
+ PageTop -= 216.0f / LinesPerInch;
+
+ Copies = atoi(argv[4]);
+
+ WriteProlog(argv[3], argv[2], getenv("CLASSIFICATION"),
+ cupsGetOption("page-label", num_options, options), ppd);
+
+ /*
+ * Read text from the specified source and print it...
+ */
+
+ lastch = 0;
+ column = 0;
+ line = 0;
+ page_column = 0;
+ attr = 0;
+ keyptr = keyword;
+ keycol = 0;
+ ccomment = 0;
+ cstring = 0;
+
+ while ((ch = getutf8(fp)) >= 0)
+ {
+ /*
+ * Control codes:
+ *
+ * BS Backspace (0x08)
+ * HT Horizontal tab; next 8th column (0x09)
+ * LF Line feed; forward full line (0x0a)
+ * VT Vertical tab; reverse full line (0x0b)
+ * FF Form feed (0x0c)
+ * CR Carriage return (0x0d)
+ * ESC 7 Reverse full line (0x1b 0x37)
+ * ESC 8 Reverse half line (0x1b 0x38)
+ * ESC 9 Forward half line (0x1b 0x39)
+ */
+
+ switch (ch)
+ {
+ case 0x08 : /* BS - backspace for boldface & underline */
+ if (column > 0)
+ column --;
+
+ keyptr = keyword;
+ keycol = column;
+ break;
+
+ case 0x09 : /* HT - tab to next 8th column */
+ if (PrettyPrint && keyptr > keyword)
+ {
+ *keyptr = '\0';
+ keyptr = keyword;
+
+ if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *),
+ compare_keywords))
+ {
+ /*
+ * Put keywords in boldface...
+ */
+
+ i = page_column * (ColumnWidth + ColumnGutter);
+
+ while (keycol < column)
+ {
+ Page[line][keycol + i].attr |= ATTR_BOLD;
+ keycol ++;
+ }
+ }
+ }
+
+ column = (column + 8) & ~7;
+
+ if (column >= ColumnWidth && WrapLines)
+ { /* Wrap text to margins */
+ line ++;
+ column = 0;
+
+ if (line >= SizeLines)
+ {
+ page_column ++;
+ line = 0;
+
+ if (page_column >= PageColumns)
+ {
+ WritePage();
+ page_column = 0;
+ }
+ }
+ }
+
+ keycol = column;
+ break;
+
+ case 0x0d : /* CR */
+#ifndef __APPLE__
+ /*
+ * All but MacOS/Darwin treat CR as was intended by ANSI
+ * folks, namely to move to column 0/1. Some programs still
+ * use this to do boldfacing and underlining...
+ */
+
+ column = 0;
+ break;
+#else
+ /*
+ * MacOS/Darwin still need to treat CR as a line ending.
+ */
+
+ {
+ int nextch;
+ if ((nextch = getc(fp)) != 0x0a)
+ ungetc(nextch, fp);
+ else
+ ch = nextch;
+ }
+#endif /* !__APPLE__ */
+
+ case 0x0a : /* LF - output current line */
+ if (PrettyPrint && keyptr > keyword)
+ {
+ *keyptr = '\0';
+ keyptr = keyword;
+
+ if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *),
+ compare_keywords))
+ {
+ /*
+ * Put keywords in boldface...
+ */
+
+ i = page_column * (ColumnWidth + ColumnGutter);
+
+ while (keycol < column)
+ {
+ Page[line][keycol + i].attr |= ATTR_BOLD;
+ keycol ++;
+ }
+ }
+ }
+
+ line ++;
+ column = 0;
+ keycol = 0;
+
+ if (!ccomment && !cstring)
+ attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE);
+
+ if (line >= SizeLines)
+ {
+ page_column ++;
+ line = 0;
+
+ if (page_column >= PageColumns)
+ {
+ WritePage();
+ page_column = 0;
+ }
+ }
+ break;
+
+ case 0x0b : /* VT - move up 1 line */
+ if (line > 0)
+ line --;
+
+ keyptr = keyword;
+ keycol = column;
+
+ if (!ccomment && !cstring)
+ attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE);
+ break;
+
+ case 0x0c : /* FF - eject current page... */
+ if (PrettyPrint && keyptr > keyword)
+ {
+ *keyptr = '\0';
+ keyptr = keyword;
+
+ if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *),
+ compare_keywords))
+ {
+ /*
+ * Put keywords in boldface...
+ */
+
+ i = page_column * (ColumnWidth + ColumnGutter);
+
+ while (keycol < column)
+ {
+ Page[line][keycol + i].attr |= ATTR_BOLD;
+ keycol ++;
+ }
+ }
+ }
+
+ page_column ++;
+ column = 0;
+ keycol = 0;
+ line = 0;
+
+ if (!ccomment && !cstring)
+ attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE);
+
+ if (page_column >= PageColumns)
+ {
+ WritePage();
+ page_column = 0;
+ }
+ break;
+
+ case 0x1b : /* Escape sequence */
+ ch = getutf8(fp);
+ if (ch == '7')
+ {
+ /*
+ * ESC 7 Reverse full line (0x1b 0x37)
+ */
+
+ if (line > 0)
+ line --;
+ }
+ else if (ch == '8')
+ {
+ /*
+ * ESC 8 Reverse half line (0x1b 0x38)
+ */
+
+ if ((attr & ATTR_RAISED) && line > 0)
+ {
+ attr &= ~ATTR_RAISED;
+ line --;
+ }
+ else if (attr & ATTR_LOWERED)
+ attr &= ~ATTR_LOWERED;
+ else
+ attr |= ATTR_RAISED;
+ }
+ else if (ch == '9')
+ {
+ /*
+ * ESC 9 Forward half line (0x1b 0x39)
+ */
+
+ if ((attr & ATTR_LOWERED) && line < (SizeLines - 1))
+ {
+ attr &= ~ATTR_LOWERED;
+ line ++;
+ }
+ else if (attr & ATTR_RAISED)
+ attr &= ~ATTR_RAISED;
+ else
+ attr |= ATTR_LOWERED;
+ }
+ break;
+
+ default : /* All others... */
+ if (ch < ' ')
+ break; /* Ignore other control chars */
+
+ if (PrettyPrint)
+ {
+ /*
+ * Do highlighting of C/C++ keywords, preprocessor commands,
+ * and comments...
+ */
+
+ if ((ch == ' ' || ch == '\t') && (attr & ATTR_BOLD))
+ {
+ /*
+ * Stop bolding preprocessor command...
+ */
+
+ attr &= ~ATTR_BOLD;
+ }
+ else if (!(isalnum(ch) || ch == '_') && keyptr > keyword)
+ {
+ /*
+ * Look for a keyword...
+ */
+
+ *keyptr = '\0';
+ keyptr = keyword;
+
+ if (!(attr & ATTR_ITALIC) &&
+ bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *),
+ compare_keywords))
+ {
+ /*
+ * Put keywords in boldface...
+ */
+
+ i = page_column * (ColumnWidth + ColumnGutter);
+
+ while (keycol < column)
+ {
+ Page[line][keycol + i].attr |= ATTR_BOLD;
+ keycol ++;
+ }
+ }
+ }
+ else if ((isalnum(ch) || ch == '_') && !ccomment && !cstring)
+ {
+ /*
+ * Add characters to the current keyword (if they'll fit).
+ */
+
+ if (keyptr == keyword)
+ keycol = column;
+
+ if (keyptr < (keyword + sizeof(keyword) - 1))
+ *keyptr++ = ch;
+ }
+ else if (ch == '\"' && lastch != '\\' && !ccomment && !cstring)
+ {
+ /*
+ * Start a C string constant...
+ */
+
+ cstring = -1;
+ attr |= ATTR_BLUE;
+ }
+ else if (ch == '*' && lastch == '/' && !cstring &&
+ PrettyPrint != PRETTY_SHELL)
+ {
+ /*
+ * Start a C-style comment...
+ */
+
+ ccomment = 1;
+ attr |= ATTR_ITALIC | ATTR_GREEN;
+ }
+ else if (ch == '/' && lastch == '/' && !cstring &&
+ PrettyPrint == PRETTY_CODE)
+ {
+ /*
+ * Start a C++-style comment...
+ */
+
+ attr |= ATTR_ITALIC | ATTR_GREEN;
+ }
+ else if (ch == '#' && !cstring && PrettyPrint != PRETTY_CODE)
+ {
+ /*
+ * Start a shell-style comment...
+ */
+
+ attr |= ATTR_ITALIC | ATTR_GREEN;
+ }
+ else if (ch == '#' && column == 0 && !ccomment && !cstring &&
+ PrettyPrint == PRETTY_CODE)
+ {
+ /*
+ * Start a preprocessor command...
+ */
+
+ attr |= ATTR_BOLD | ATTR_RED;
+ }
+ }
+
+ if (column >= ColumnWidth && WrapLines)
+ { /* Wrap text to margins */
+ column = 0;
+ line ++;
+
+ if (line >= SizeLines)
+ {
+ page_column ++;
+ line = 0;
+
+ if (page_column >= PageColumns)
+ {
+ WritePage();
+ page_column = 0;
+ }
+ }
+ }
+
+ /*
+ * Add text to the current column & line...
+ */
+
+ if (column < ColumnWidth)
+ {
+ i = column + page_column * (ColumnWidth + ColumnGutter);
+
+ if (PrettyPrint)
+ Page[line][i].attr = attr;
+ else if (ch == ' ' && Page[line][i].ch)
+ ch = Page[line][i].ch;
+ else if (ch == Page[line][i].ch)
+ Page[line][i].attr |= ATTR_BOLD;
+ else if (Page[line][i].ch == '_')
+ Page[line][i].attr |= ATTR_UNDERLINE;
+ else if (ch == '_')
+ {
+ Page[line][i].attr |= ATTR_UNDERLINE;
+
+ if (Page[line][i].ch)
+ ch = Page[line][i].ch;
+ }
+ else
+ Page[line][i].attr = attr;
+
+ Page[line][i].ch = ch;
+ }
+
+ if (PrettyPrint)
+ {
+ if ((ch == '{' || ch == '}') && !ccomment && !cstring &&
+ column < ColumnWidth)
+ {
+ /*
+ * Highlight curley braces...
+ */
+
+ Page[line][column].attr |= ATTR_BOLD;
+ }
+ else if ((ch == '/' || ch == '*') && lastch == '/' &&
+ column < ColumnWidth && PrettyPrint != PRETTY_SHELL)
+ {
+ /*
+ * Highlight first comment character...
+ */
+
+ Page[line][column - 1].attr = attr;
+ }
+ else if (ch == '\"' && lastch != '\\' && !ccomment && cstring > 0)
+ {
+ /*
+ * End a C string constant...
+ */
+
+ cstring = 0;
+ attr &= ~ATTR_BLUE;
+ }
+ else if (ch == '/' && lastch == '*' && ccomment)
+ {
+ /*
+ * End a C-style comment...
+ */
+
+ ccomment = 0;
+ attr &= ~(ATTR_ITALIC | ATTR_GREEN);
+ }
+
+ if (cstring < 0)
+ cstring = 1;
+ }
+
+ column ++;
+ break;
+ }
+
+ /*
+ * Save this character for the next cycle.
+ */
+
+ lastch = ch;
+ }
+
+ /*
+ * Write any remaining page data...
+ */
+
+ if (line > 0 || page_column > 0 || column > 0)
+ WritePage();
+
+ /*
+ * Write the epilog and return...
+ */
+
+ WriteEpilogue();
+
+ if (ppd != NULL)
+ ppdClose(ppd);
+
+ return (0);
+}
+
+
+/*
+ * 'compare_keywords()' - Compare two C/C++ keywords.
+ */
+
+static int /* O - Result of strcmp */
+compare_keywords(const void *k1, /* I - First keyword */
+ const void *k2) /* I - Second keyword */
+{
+ return (strcmp(*((const char **)k1), *((const char **)k2)));
+}
+
+
+/*
+ * 'getutf8()' - Get a UTF-8 encoded wide character...
+ */
+
+static int /* O - Character or -1 on error */
+getutf8(FILE *fp) /* I - File to read from */
+{
+ int ch; /* Current character value */
+ int next; /* Next character from file */
+
+
+ /*
+ * Read the first character and process things accordingly...
+ *
+ * UTF-8 maps 16-bit characters to:
+ *
+ * 0 to 127 = 0xxxxxxx
+ * 128 to 2047 = 110xxxxx 10yyyyyy (xxxxxyyyyyy)
+ * 2048 to 65535 = 1110xxxx 10yyyyyy 10zzzzzz (xxxxyyyyyyzzzzzz)
+ *
+ * We also accept:
+ *
+ * 128 to 191 = 10xxxxxx
+ *
+ * since this range of values is otherwise undefined unless you are
+ * in the middle of a multi-byte character...
+ *
+ * This code currently does not support anything beyond 16-bit
+ * characters, in part because PostScript doesn't support more than
+ * 16-bit characters...
+ */
+
+ if ((ch = getc(fp)) == EOF)
+ return (EOF);
+
+ if (ch < 0xc0 || !UTF8) /* One byte character? */
+ return (ch);
+ else if ((ch & 0xe0) == 0xc0)
+ {
+ /*
+ * Two byte character...
+ */
+
+ if ((next = getc(fp)) == EOF)
+ return (EOF);
+ else
+ return (((ch & 0x1f) << 6) | (next & 0x3f));
+ }
+ else if ((ch & 0xf0) == 0xe0)
+ {
+ /*
+ * Three byte character...
+ */
+
+ if ((next = getc(fp)) == EOF)
+ return (EOF);
+
+ ch = ((ch & 0x0f) << 6) | (next & 0x3f);
+
+ if ((next = getc(fp)) == EOF)
+ return (EOF);
+ else
+ return ((ch << 6) | (next & 0x3f));
+ }
+ else
+ {
+ /*
+ * More than three bytes... We don't support that...
+ */
+
+ return (EOF);
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/textcommon.h b/filter/textcommon.h
new file mode 100644
index 000000000..0a356f457
--- /dev/null
+++ b/filter/textcommon.h
@@ -0,0 +1,122 @@
+/*
+ * "$Id$"
+ *
+ * Common text filter definitions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "common.h"
+
+
+/*
+ * C++ magic...
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/*
+ * Constants...
+ */
+
+#define ATTR_NORMAL 0x00
+#define ATTR_BOLD 0x01
+#define ATTR_ITALIC 0x02
+#define ATTR_BOLDITALIC 0x03
+#define ATTR_FONT 0x03
+
+#define ATTR_UNDERLINE 0x04
+#define ATTR_RAISED 0x08
+#define ATTR_LOWERED 0x10
+#define ATTR_RED 0x20
+#define ATTR_GREEN 0x40
+#define ATTR_BLUE 0x80
+
+#define PRETTY_OFF 0
+#define PRETTY_CODE 1
+#define PRETTY_SHELL 2
+#define PRETTY_PERL 3
+#define PRETTY_HTML 4
+
+
+/*
+ * Structures...
+ */
+
+typedef struct /**** Character/attribute structure... ****/
+{
+ unsigned short ch, /* Character */
+ attr; /* Any attributes */
+} lchar_t;
+
+
+/*
+ * Globals...
+ */
+
+extern int WrapLines, /* Wrap text in lines */
+ SizeLines, /* Number of lines on a page */
+ SizeColumns, /* Number of columns on a line */
+ PageColumns, /* Number of columns on a page */
+ ColumnGutter, /* Number of characters between text columns */
+ ColumnWidth, /* Width of each column */
+ PrettyPrint, /* Do pretty code formatting? */
+ Copies; /* Number of copies to produce */
+extern lchar_t **Page; /* Page characters */
+extern int NumPages; /* Number of pages in document */
+extern float CharsPerInch, /* Number of character columns per inch */
+ LinesPerInch; /* Number of lines per inch */
+extern int UTF8, /* Use UTF-8 encoding? */
+ NumKeywords; /* Number of known keywords */
+extern char **Keywords; /* List of known keywords... */
+
+
+/*
+ * Required functions...
+ */
+
+extern int TextMain(const char *name, int argc, char *argv[]);
+extern void WriteEpilogue(void);
+extern void WritePage(void);
+extern void WriteProlog(const char *title, const char *user,
+ const char *classification, const char *label,
+ ppd_file_t *ppd);
+
+
+/*
+ * C++ magic...
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/texttops.c b/filter/texttops.c
new file mode 100644
index 000000000..a30193e1d
--- /dev/null
+++ b/filter/texttops.c
@@ -0,0 +1,1305 @@
+/*
+ * "$Id$"
+ *
+ * Text to PostScript filter for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * main() - Main entry for text to PostScript filter.
+ * WriteEpilogue() - Write the PostScript file epilogue.
+ * WritePage() - Write a page of text.
+ * WriteProlog() - Write the PostScript file prolog with options.
+ * write_line() - Write a row of text.
+ * write_string() - Write a string of text.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "textcommon.h"
+
+
+/*
+ * Globals...
+ */
+
+char *Glyphs[65536]; /* PostScript glyphs for Unicode */
+int NumFonts; /* Number of fonts to use */
+char *Fonts[256][4]; /* Fonts to use */
+unsigned short Chars[65536]; /* 0xffcc (ff = font, cc = char) */
+unsigned short Codes[65536]; /* Unicode glyph mapping to fonts */
+int Widths[256]; /* Widths of each font */
+int Directions[256];/* Text directions for each font */
+
+
+/*
+ * Local functions...
+ */
+
+static void write_line(int row, lchar_t *line);
+static void write_string(int col, int row, int len, lchar_t *s);
+static void write_text(const char *s);
+
+
+/*
+ * 'main()' - Main entry for text to PostScript filter.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ return (TextMain("texttops", argc, argv));
+}
+
+
+/*
+ * 'WriteEpilogue()' - Write the PostScript file epilogue.
+ */
+
+void
+WriteEpilogue(void)
+{
+ puts("%%Trailer");
+ printf("%%%%Pages: %d\n", NumPages);
+ puts("%%EOF");
+
+ free(Page[0]);
+ free(Page);
+}
+
+
+/*
+ * 'WritePage()' - Write a page of text.
+ */
+
+void
+WritePage(void)
+{
+ int line; /* Current line */
+
+
+ NumPages ++;
+ printf("%%%%Page: %d %d\n", NumPages, NumPages);
+
+ puts("gsave");
+
+ if (PrettyPrint)
+ printf("%d H\n", NumPages);
+
+ for (line = 0; line < SizeLines; line ++)
+ write_line(line, Page[line]);
+
+ puts("grestore");
+ puts("showpage");
+
+ memset(Page[0], 0, sizeof(lchar_t) * SizeColumns * SizeLines);
+}
+
+
+/*
+ * 'WriteProlog()' - Write the PostScript file prolog with options.
+ */
+
+void
+WriteProlog(const char *title, /* I - Title of job */
+ const char *user, /* I - Username */
+ const char *classification, /* I - Classification */
+ const char *label, /* I - Page label */
+ ppd_file_t *ppd) /* I - PPD file info */
+{
+ int i, j, k; /* Looping vars */
+ char *charset; /* Character set string */
+ char filename[1024]; /* Glyph filenames */
+ FILE *fp; /* Glyph files */
+ const char *datadir; /* CUPS_DATADIR environment variable */
+ char line[1024], /* Line from file */
+ *lineptr, /* Pointer into line */
+ *valptr; /* Pointer to value in line */
+ int ch, unicode; /* Character values */
+ int start, end; /* Start and end values for range */
+ char glyph[64]; /* Glyph name */
+ time_t curtime; /* Current time */
+ struct tm *curtm; /* Current date */
+ char curdate[255]; /* Current date (text format) */
+ int num_fonts; /* Number of unique fonts */
+ char *fonts[1024]; /* Unique fonts */
+ static char *names[] = /* Font names */
+ {
+ "cupsNormal",
+ "cupsBold",
+ "cupsItalic"
+ };
+
+
+ /*
+ * Get the data directory...
+ */
+
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+ datadir = CUPS_DATADIR;
+
+ /*
+ * Adjust margins as necessary...
+ */
+
+ if (classification || label)
+ {
+ /*
+ * Leave room for labels...
+ */
+
+ PageBottom += 36;
+ PageTop -= 36;
+ }
+
+ /*
+ * Allocate memory for the page...
+ */
+
+ SizeColumns = (PageRight - PageLeft) / 72.0 * CharsPerInch;
+ SizeLines = (PageTop - PageBottom) / 72.0 * LinesPerInch;
+
+ Page = calloc(sizeof(lchar_t *), SizeLines);
+ Page[0] = calloc(sizeof(lchar_t), SizeColumns * SizeLines);
+ for (i = 1; i < SizeLines; i ++)
+ Page[i] = Page[0] + i * SizeColumns;
+
+ if (PageColumns > 1)
+ {
+ ColumnGutter = CharsPerInch / 2;
+ ColumnWidth = (SizeColumns - ColumnGutter * (PageColumns - 1)) /
+ PageColumns;
+ }
+ else
+ ColumnWidth = SizeColumns;
+
+ /*
+ * Output the DSC header...
+ */
+
+ curtime = time(NULL);
+ curtm = localtime(&curtime);
+ strftime(curdate, sizeof(curdate), CUPS_STRFTIME_FORMAT, curtm);
+
+ puts("%!PS-Adobe-3.0");
+ printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom,
+ PageRight, PageTop);
+ printf("%%cupsRotation: %d\n", (Orientation & 3) * 90);
+ puts("%%Creator: texttops/" CUPS_SVERSION);
+ printf("%%%%CreationDate: %s\n", curdate);
+ printf("%%%%Title: %s\n", title);
+ printf("%%%%For: %s\n", user);
+ puts("%%Pages: (atend)");
+
+ /*
+ * Initialize globals...
+ */
+
+ NumFonts = 0;
+ memset(Fonts, 0, sizeof(Fonts));
+ memset(Glyphs, 0, sizeof(Glyphs));
+ memset(Chars, 0, sizeof(Chars));
+ memset(Codes, 0, sizeof(Codes));
+
+ /*
+ * Load the PostScript glyph names and the corresponding character
+ * set definition...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/data/psglyphs", datadir);
+
+ if ((fp = fopen(filename, "r")) != NULL)
+ {
+ while (fscanf(fp, "%x%63s", &unicode, glyph) == 2)
+ Glyphs[unicode] = strdup(glyph);
+
+ fclose(fp);
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Unable to open \"%s\" - %s\n", filename,
+ strerror(errno));
+ exit(1);
+ }
+
+ /*
+ * Get the output character set...
+ */
+
+ charset = getenv("CHARSET");
+ if (charset != NULL && strcmp(charset, "us-ascii") != 0)
+ {
+ snprintf(filename, sizeof(filename), "%s/charsets/%s", datadir, charset);
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ {
+ /*
+ * Can't open charset file!
+ */
+
+ fprintf(stderr, "ERROR: Unable to open %s: %s\n", filename,
+ strerror(errno));
+ exit(1);
+ }
+
+ /*
+ * Opened charset file; now see if this is really a charset file...
+ */
+
+ if (fgets(line, sizeof(line), fp) == NULL)
+ {
+ /*
+ * Bad/empty charset file!
+ */
+
+ fclose(fp);
+ fprintf(stderr, "ERROR: Bad/empty charset file %s\n", filename);
+ exit(1);
+ }
+
+ if (strncmp(line, "charset", 7) != 0)
+ {
+ /*
+ * Bad format/not a charset file!
+ */
+
+ fclose(fp);
+ fprintf(stderr, "ERROR: Bad charset file %s\n", filename);
+ exit(1);
+ }
+
+ /*
+ * See if this is an 8-bit or UTF-8 character set file...
+ */
+
+ line[strlen(line) - 1] = '\0'; /* Drop \n */
+ for (lineptr = line + 7; isspace(*lineptr); lineptr ++); /* Skip whitespace */
+
+ if (strcmp(lineptr, "8bit") == 0)
+ {
+ /*
+ * 8-bit text...
+ */
+
+ UTF8 = 0;
+ NumFonts = 0;
+
+ /*
+ * Read the font description(s)...
+ */
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Skip comment and blank lines...
+ */
+
+ if (line[0] == '#' || line[0] == '\n')
+ continue;
+
+ /*
+ * Read the font descriptions that should look like:
+ *
+ * first last direction width normal [bold italic bold-italic]
+ */
+
+ lineptr = line;
+
+ start = strtol(lineptr, &lineptr, 16);
+ end = strtol(lineptr, &lineptr, 16);
+
+ while (isspace(*lineptr))
+ lineptr ++;
+
+ if (!*lineptr)
+ break; /* Must be a font mapping */
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr) && *lineptr)
+ lineptr ++;
+
+ if (!*lineptr)
+ {
+ /*
+ * Can't have a font without all required values...
+ */
+
+ fprintf(stderr, "ERROR: bad font description line: %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ *lineptr++ = '\0';
+
+ if (strcmp(valptr, "ltor") == 0)
+ Directions[NumFonts] = 1;
+ else if (strcmp(valptr, "rtol") == 0)
+ Directions[NumFonts] = -1;
+ else
+ {
+ fprintf(stderr, "ERROR: Bad text direction %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ /*
+ * Got the direction, now get the width...
+ */
+
+ while (isspace(*lineptr))
+ lineptr ++;
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr) && *lineptr)
+ lineptr ++;
+
+ if (!*lineptr)
+ {
+ /*
+ * Can't have a font without all required values...
+ */
+
+ fprintf(stderr, "ERROR: bad font description line: %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ *lineptr++ = '\0';
+
+ if (strcmp(valptr, "single") == 0)
+ Widths[NumFonts] = 1;
+ else if (strcmp(valptr, "double") == 0)
+ Widths[NumFonts] = 2;
+ else
+ {
+ fprintf(stderr, "ERROR: Bad text width %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ /*
+ * Get the fonts...
+ */
+
+ for (i = 0; *lineptr && i < 4; i ++)
+ {
+ while (isspace(*lineptr))
+ lineptr ++;
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr) && *lineptr)
+ lineptr ++;
+
+ if (*lineptr)
+ *lineptr++ = '\0';
+
+ if (lineptr > valptr)
+ Fonts[NumFonts][i] = strdup(valptr);
+ }
+
+ /*
+ * Fill in remaining fonts as needed...
+ */
+
+ for (j = i; j < 4; j ++)
+ Fonts[NumFonts][j] = strdup(Fonts[NumFonts][0]);
+
+ /*
+ * Define the character mappings...
+ */
+
+ for (i = start, j = NumFonts * 256; i <= end; i ++, j ++)
+ Chars[i] = j;
+
+ NumFonts ++;
+ }
+
+ /*
+ * Read encoding lines...
+ */
+
+ do
+ {
+ /*
+ * Skip comment and blank lines...
+ */
+
+ if (line[0] == '#' || line[0] == '\n')
+ continue;
+
+ /*
+ * Grab the character and unicode glyph number.
+ */
+
+ if (sscanf(line, "%x%x", &ch, &unicode) == 2 && ch < 256)
+ Codes[Chars[ch]] = unicode;
+ }
+ while (fgets(line, sizeof(line), fp) != NULL);
+
+ fclose(fp);
+ }
+ else if (strcmp(lineptr, "utf8") == 0)
+ {
+ /*
+ * UTF-8 (Unicode) text...
+ */
+
+ UTF8 = 1;
+
+ /*
+ * Read the font descriptions...
+ */
+
+ NumFonts = 0;
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Skip comment and blank lines...
+ */
+
+ if (line[0] == '#' || line[0] == '\n')
+ continue;
+
+ /*
+ * Read the font descriptions that should look like:
+ *
+ * start end direction width normal [bold italic bold-italic]
+ */
+
+ lineptr = line;
+
+ start = strtol(lineptr, &lineptr, 16);
+ end = strtol(lineptr, &lineptr, 16);
+
+ while (isspace(*lineptr))
+ lineptr ++;
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr) && *lineptr)
+ lineptr ++;
+
+ if (!*lineptr)
+ {
+ /*
+ * Can't have a font without all required values...
+ */
+
+ fprintf(stderr, "ERROR: bad font description line: %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ *lineptr++ = '\0';
+
+ if (strcmp(valptr, "ltor") == 0)
+ Directions[NumFonts] = 1;
+ else if (strcmp(valptr, "rtol") == 0)
+ Directions[NumFonts] = -1;
+ else
+ {
+ fprintf(stderr, "ERROR: Bad text direction %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ /*
+ * Got the direction, now get the width...
+ */
+
+ while (isspace(*lineptr))
+ lineptr ++;
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr) && *lineptr)
+ lineptr ++;
+
+ if (!*lineptr)
+ {
+ /*
+ * Can't have a font without all required values...
+ */
+
+ fprintf(stderr, "ERROR: bad font description line: %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ *lineptr++ = '\0';
+
+ if (strcmp(valptr, "single") == 0)
+ Widths[NumFonts] = 1;
+ else if (strcmp(valptr, "double") == 0)
+ Widths[NumFonts] = 2;
+ else
+ {
+ fprintf(stderr, "ERROR: Bad text width %s\n", valptr);
+ fclose(fp);
+ exit(1);
+ }
+
+ /*
+ * Get the fonts...
+ */
+
+ for (i = 0; *lineptr && i < 4; i ++)
+ {
+ while (isspace(*lineptr))
+ lineptr ++;
+
+ valptr = lineptr;
+
+ while (!isspace(*lineptr) && *lineptr)
+ lineptr ++;
+
+ if (*lineptr)
+ *lineptr++ = '\0';
+
+ if (lineptr > valptr)
+ Fonts[NumFonts][i] = strdup(valptr);
+ }
+
+ /*
+ * Fill in remaining fonts as needed...
+ */
+
+ for (j = i; j < 4; j ++)
+ Fonts[NumFonts][j] = strdup(Fonts[NumFonts][0]);
+
+ /*
+ * Define the character mappings...
+ */
+
+ for (i = start, j = NumFonts * 256; i <= end; i ++, j ++)
+ {
+ Chars[i] = j;
+ Codes[j] = i;
+ }
+
+ /*
+ * Move to the next font, stopping if needed...
+ */
+
+ NumFonts ++;
+ if (NumFonts >= 256)
+ break;
+ }
+
+ fclose(fp);
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Bad charset type %s\n", lineptr);
+ fclose(fp);
+ exit(1);
+ }
+ }
+ else
+ {
+ /*
+ * Standard ASCII output just uses Courier, Courier-Bold, and
+ * possibly Courier-Oblique.
+ */
+
+ NumFonts = 1;
+
+ Fonts[0][ATTR_NORMAL] = strdup("Courier");
+ Fonts[0][ATTR_BOLD] = strdup("Courier-Bold");
+ Fonts[0][ATTR_ITALIC] = strdup("Courier-Oblique");
+ Fonts[0][ATTR_BOLDITALIC] = strdup("Courier-BoldOblique");
+
+ Widths[0] = 1;
+ Directions[0] = 1;
+
+ /*
+ * Define US-ASCII characters...
+ */
+
+ for (i = 32; i < 127; i ++)
+ {
+ Chars[i] = i;
+ Codes[i] = i;
+ }
+ }
+
+ /*
+ * Generate a list of unique fonts to use...
+ */
+
+ for (i = 0, num_fonts = 0; i < NumFonts; i ++)
+ for (j = PrettyPrint ? 2 : 1; j >= 0; j --)
+ {
+ for (k = 0; k < num_fonts; k ++)
+ if (strcmp(Fonts[i][j], fonts[k]) == 0)
+ break;
+
+ if (k >= num_fonts)
+ {
+ /*
+ * Add new font...
+ */
+
+ fonts[num_fonts] = Fonts[i][j];
+ num_fonts ++;
+ }
+ }
+
+ /*
+ * List the fonts that will be used...
+ */
+
+ for (i = 0; i < num_fonts; i ++)
+ if (i == 0)
+ printf("%%%%DocumentNeededResources: font %s\n", fonts[i]);
+ else
+ printf("%%%%+ font %s\n", fonts[i]);
+
+ puts("%%DocumentSuppliedResources: procset texttops 1.1 0");
+
+ for (i = 0; i < num_fonts; i ++)
+ {
+ if (ppd != NULL)
+ {
+ fprintf(stderr, "DEBUG: ppd->num_fonts = %d\n", ppd->num_fonts);
+
+ for (j = 0; j < ppd->num_fonts; j ++)
+ {
+ fprintf(stderr, "DEBUG: ppd->fonts[%d] = %s\n", j, ppd->fonts[j]);
+
+ if (strcmp(fonts[i], ppd->fonts[j]) == 0)
+ break;
+ }
+ }
+ else
+ j = 0;
+
+ if ((ppd != NULL && j >= ppd->num_fonts) ||
+ strncmp(fonts[i], "Courier", 7) == 0 ||
+ strcmp(fonts[i], "Symbol") == 0)
+ {
+ /*
+ * Need to embed this font...
+ */
+
+ printf("%%%%+ font %s\n", fonts[i]);
+ }
+ }
+
+ puts("%%EndComments");
+
+ puts("%%BeginProlog");
+
+ /*
+ * Download any missing fonts...
+ */
+
+ for (i = 0; i < num_fonts; i ++)
+ {
+ if (ppd != NULL)
+ {
+ for (j = 0; j < ppd->num_fonts; j ++)
+ if (strcmp(fonts[i], ppd->fonts[j]) == 0)
+ break;
+ }
+ else
+ j = 0;
+
+ if ((ppd != NULL && j >= ppd->num_fonts) ||
+ strncmp(fonts[i], "Courier", 7) == 0 ||
+ strcmp(fonts[i], "Symbol") == 0)
+ {
+ /*
+ * Need to embed this font...
+ */
+
+ printf("%%%%BeginResource: font %s\n", fonts[i]);
+
+ /**** MRS: Need to use CUPS_FONTPATH env var! ****/
+ /**** Also look for Fontmap file or name.pfa, name.pfb... ****/
+ snprintf(filename, sizeof(filename), "%s/fonts/%s", datadir, fonts[i]);
+ if ((fp = fopen(filename, "rb")) != NULL)
+ {
+ while ((j = fread(line, 1, sizeof(line), fp)) > 0)
+ fwrite(line, 1, j, stdout);
+
+ fclose(fp);
+ }
+
+ puts("\n%%EndResource");
+ }
+ }
+
+ /*
+ * Write the encoding array(s)...
+ */
+
+ puts("% character encoding(s)");
+
+ for (i = 0; i < NumFonts; i ++)
+ {
+ printf("/cupsEncoding%02x [\n", i);
+
+ for (ch = 0; ch < 256; ch ++)
+ {
+ if (Glyphs[Codes[i * 256 + ch]])
+ printf("/%s", Glyphs[Codes[i * 256 + ch]]);
+ else if (Codes[i * 256 + ch] > 255)
+ printf("/uni%04X", Codes[i * 256 + ch]);
+ else
+ printf("/.notdef");
+
+ if ((ch & 7) == 7)
+ putchar('\n');
+ }
+
+ puts("] def");
+ }
+
+ /*
+ * Create the fonts...
+ */
+
+ if (NumFonts == 1)
+ {
+ /*
+ * Just reencode the named fonts...
+ */
+
+ puts("% Reencode fonts");
+
+ for (i = PrettyPrint ? 2 : 1; i >= 0; i --)
+ {
+ printf("/%s findfont\n", Fonts[0][i]);
+ puts("dup length 1 add dict begin\n"
+ " { 1 index /FID ne { def } { pop pop } ifelse } forall\n"
+ " /Encoding cupsEncoding00 def\n"
+ " currentdict\n"
+ "end");
+ printf("/%s exch definefont pop\n", names[i]);
+ }
+ }
+ else
+ {
+ /*
+ * Construct composite fonts... Start by reencoding the base fonts...
+ */
+
+ puts("% Reencode base fonts");
+
+ for (i = 1 + PrettyPrint; i >= 0; i --)
+ for (j = 0; j < NumFonts; j ++)
+ {
+ printf("/%s findfont\n", Fonts[j][i]);
+ printf("dup length 1 add dict begin\n"
+ " { 1 index /FID ne { def } { pop pop } ifelse } forall\n"
+ " /Encoding cupsEncoding%02x def\n"
+ " currentdict\n"
+ "end\n", j);
+ printf("/%s%02x exch definefont /%s%02x exch def\n", names[i], j,
+ names[i], j);
+ }
+
+ /*
+ * Then merge them into composite fonts...
+ */
+
+ puts("% Create composite fonts...");
+
+ for (i = 1 + PrettyPrint; i >= 0; i --)
+ {
+ puts("8 dict begin");
+ puts("/FontType 0 def/FontMatrix[1.0 0 0 1.0 0 0]def/FMapType 2 def/Encoding[");
+ for (j = 0; j < NumFonts; j ++)
+ if (j == (NumFonts - 1))
+ printf("%d", j);
+ else if ((j & 15) == 15)
+ printf("%d\n", j);
+ else
+ printf("%d ", j);
+ puts("]def/FDepVector[");
+ for (j = 0; j < NumFonts; j ++)
+ if (j == (NumFonts - 1))
+ printf("%s%02x", names[i], j);
+ else if ((j & 3) == 3)
+ printf("%s%02x\n", names[i], j);
+ else
+ printf("%s%02x ", names[i], j);
+ puts("]def currentdict end");
+ printf("/%s exch definefont pop\n", names[i]);
+ }
+ }
+
+ /*
+ * Output the texttops procset...
+ */
+
+ puts("%%BeginResource: procset texttops 1.1 0");
+
+ puts("% Define fonts");
+
+ printf("/FN /cupsNormal findfont [%.3f 0 0 %.3f 0 0] makefont def\n",
+ 120.0 / CharsPerInch, 68.0 / LinesPerInch);
+ printf("/FB /cupsBold findfont [%.3f 0 0 %.3f 0 0] makefont def\n",
+ 120.0 / CharsPerInch, 68.0 / LinesPerInch);
+ if (PrettyPrint)
+ printf("/FI /cupsItalic findfont [%.3f 0 0 %.3f 0 0] makefont def\n",
+ 120.0 / CharsPerInch, 68.0 / LinesPerInch);
+
+ puts("% Common procedures");
+
+ puts("/N { FN setfont moveto } bind def");
+ puts("/B { FB setfont moveto } bind def");
+ printf("/U { gsave 0.5 setlinewidth 0 %.3f rmoveto "
+ "0 rlineto stroke grestore } bind def\n", -6.8 / LinesPerInch);
+
+ if (PrettyPrint)
+ {
+ if (ColorDevice)
+ {
+ puts("/S { 0.0 setgray show } bind def");
+ puts("/r { 0.5 0.0 0.0 setrgbcolor show } bind def");
+ puts("/g { 0.0 0.5 0.0 setrgbcolor show } bind def");
+ puts("/b { 0.0 0.0 0.5 setrgbcolor show } bind def");
+ }
+ else
+ {
+ puts("/S { 0.0 setgray show } bind def");
+ puts("/r { 0.2 setgray show } bind def");
+ puts("/g { 0.2 setgray show } bind def");
+ puts("/b { 0.2 setgray show } bind def");
+ }
+
+ puts("/I { FI setfont moveto } bind def");
+
+ puts("/n {");
+ puts("\t20 string cvs % convert page number to string");
+ puts("\tdup length % get length");
+ puts("\tdup 2 mul string /P exch def % P = string twice as long");
+ puts("\t0 1 2 index 1 sub { % loop through each character in the page number");
+ puts("\t\tdup 3 index exch get % get character N from the page number");
+ puts("\t\texch 2 mul dup % compute offset in P");
+ puts("\t\tP exch 0 put % font 0");
+ puts("\t\t1 add P exch 2 index put % character");
+ puts("\t\tpop % discard character");
+ puts("\t} for % do for loop");
+ puts("\tpop pop % discard string and length");
+ puts("\tP % put string on stack");
+ puts("} bind def");
+
+ printf("/T");
+ write_text(title);
+ puts("def");
+
+ printf("/D");
+ write_text(curdate);
+ puts("def");
+
+ puts("/H {");
+ puts("gsave");
+ puts("\t0.9 setgray");
+
+ if (Duplex)
+ {
+ puts("\tdup 2 mod 0 eq {");
+ printf("\t\t%.3f %.3f translate } {\n",
+ PageWidth - PageRight, PageTop + 72.0f / LinesPerInch);
+ printf("\t\t%.3f %.3f translate } ifelse\n",
+ PageLeft, PageTop + 72.0f / LinesPerInch);
+ }
+ else
+ printf("\t%.3f %.3f translate\n",
+ PageLeft, PageTop + 72.0f / LinesPerInch);
+
+ printf("\t0 0 %.3f %.3f rectfill\n", PageRight - PageLeft,
+ 144.0f / LinesPerInch);
+
+ puts("\tFB setfont");
+ puts("\t0 setgray");
+
+ if (Duplex)
+ {
+ puts("\tdup 2 mod 0 eq {");
+ printf("\t\tT stringwidth pop neg %.3f add %.3f } {\n",
+ PageRight - PageLeft - 36.0f / LinesPerInch,
+ (0.5f + 0.157f) * 72.0f / LinesPerInch);
+ printf("\t\t%.3f %.3f } ifelse\n", 36.0f / LinesPerInch,
+ (0.5f + 0.157f) * 72.0f / LinesPerInch);
+ }
+ else
+ printf("\t%.3f %.3f\n", 36.0f / LinesPerInch,
+ (0.5f + 0.157f) * 72.0f / LinesPerInch);
+
+ puts("\tmoveto T show");
+
+ printf("\tD dup stringwidth pop neg 2 div %.3f add %.3f\n",
+ (PageRight - PageLeft) * 0.5,
+ (0.5f + 0.157f) * 72.0f / LinesPerInch);
+ puts("\tmoveto show");
+
+ if (Duplex)
+ {
+ puts("\tdup n exch 2 mod 0 eq {");
+ printf("\t\t%.3f %.3f } {\n", 36.0f / LinesPerInch,
+ (0.5f + 0.157f) * 72.0f / LinesPerInch);
+ printf("\t\tdup stringwidth pop neg %.3f add %.3f } ifelse\n",
+ PageRight - PageLeft - 36.0f / LinesPerInch,
+ (0.5f + 0.157f) * 72.0f / LinesPerInch);
+ }
+ else
+ printf("\tn dup stringwidth pop neg %.3f add %.3f\n",
+ PageRight - PageLeft - 36.0f / LinesPerInch,
+ (0.5f + 0.157f) * 72.0f / LinesPerInch);
+
+ puts("\tmoveto show");
+ puts("\tgrestore");
+ puts("} bind def");
+ }
+ else
+ puts("/S { show } bind def");
+
+ puts("%%EndResource");
+
+ puts("%%EndProlog");
+}
+
+
+/*
+ * 'write_line()' - Write a row of text.
+ */
+
+static void
+write_line(int row, /* I - Row number (0 to N) */
+ lchar_t *line) /* I - Line to print */
+{
+ int i; /* Looping var */
+ int col; /* Current column */
+ int attr; /* Current attribute */
+ int font, /* Font to use */
+ lastfont, /* Last font */
+ mono; /* Monospaced? */
+ lchar_t *start; /* First character in sequence */
+
+
+ for (col = 0, start = line; col < SizeColumns;)
+ {
+ while (col < SizeColumns && (line->ch == ' ' || line->ch == 0))
+ {
+ col ++;
+ line ++;
+ }
+
+ if (col >= SizeColumns)
+ break;
+
+ if (NumFonts == 1)
+ {
+ /*
+ * All characters in a single font - assume monospaced...
+ */
+
+ attr = line->attr;
+ start = line;
+
+ while (col < SizeColumns && line->ch != 0 && attr == line->attr)
+ {
+ col ++;
+ line ++;
+ }
+
+ write_string(col - (line - start), row, line - start, start);
+ }
+ else
+ {
+ /*
+ * Multiple fonts; break up based on the font...
+ */
+
+ attr = line->attr;
+ start = line;
+ lastfont = Chars[line->ch] / 256;
+ mono = strncmp(Fonts[lastfont][0], "Courier", 7) == 0;
+ col ++;
+ line ++;
+
+ if (mono)
+ {
+ while (col < SizeColumns && line->ch != 0 && attr == line->attr)
+ {
+ font = Chars[line->ch] / 256;
+ if (strncmp(Fonts[font][0], "Courier", 7) != 0 ||
+ font != lastfont)
+ break;
+
+ col ++;
+ line ++;
+ }
+ }
+
+ if (Directions[lastfont] > 0)
+ write_string(col - (line - start), row, line - start, start);
+ else
+ {
+ /*
+ * Do right-to-left text...
+ */
+
+ while (col < SizeColumns && line->ch != 0 && attr == line->attr)
+ {
+ if (Directions[Chars[line->ch] / 256] > 0 &&
+ !ispunct(line->ch) && !isspace(line->ch))
+ break;
+
+ col ++;
+ line ++;
+ }
+
+ for (i = 1; start < line; i ++, start ++)
+ if (!isspace(start->ch))
+ write_string(col - i, row, 1, start);
+ }
+ }
+ }
+}
+
+
+/*
+ * 'write_string()' - Write a string of text.
+ */
+
+static void
+write_string(int col, /* I - Start column */
+ int row, /* I - Row */
+ int len, /* I - Number of characters */
+ lchar_t *s) /* I - String to print */
+{
+ int ch; /* Current character */
+ float x, y; /* Position of text */
+ unsigned attr; /* Character attributes */
+
+
+ /*
+ * Position the text and set the font...
+ */
+
+ if (Duplex && (NumPages & 1) == 0)
+ {
+ x = PageWidth - PageRight;
+ y = PageTop;
+ }
+ else
+ {
+ x = PageLeft;
+ y = PageTop;
+ }
+
+ x += (float)col * 72.0f / (float)CharsPerInch;
+ y -= (float)(row + 0.843) * 72.0f / (float)LinesPerInch;
+
+ attr = s->attr;
+
+ if (attr & ATTR_RAISED)
+ y += 36.0 / (float)LinesPerInch;
+ else if (attr & ATTR_LOWERED)
+ y -= 36.0 / (float)LinesPerInch;
+
+ if (x == (int)x)
+ printf("%.0f ", x);
+ else
+ printf("%.3f ", x);
+
+ if (y == (int)y)
+ printf("%.0f ", y);
+ else
+ printf("%.3f ", y);
+
+ if (attr & ATTR_BOLD)
+ putchar('B');
+ else if (attr & ATTR_ITALIC)
+ putchar('I');
+ else
+ putchar('N');
+
+ if (attr & ATTR_UNDERLINE)
+ printf(" %.3f U", (float)len * 72.0 / (float)CharsPerInch);
+
+ if (NumFonts > 1)
+ {
+ /*
+ * Write a hex string...
+ */
+
+ putchar('<');
+
+ while (len > 0)
+ {
+ printf("%04x", Chars[s->ch]);
+
+ len --;
+ s ++;
+ }
+
+ putchar('>');
+ }
+ else
+ {
+ /*
+ * Write a quoted string...
+ */
+
+ putchar('(');
+
+ while (len > 0)
+ {
+ ch = Chars[s->ch];
+
+ if (ch < 32 || ch > 126)
+ {
+ /*
+ * Quote 8-bit and control characters...
+ */
+
+ printf("\\%03o", ch);
+ }
+ else
+ {
+ /*
+ * Quote the parenthesis and backslash as needed...
+ */
+
+ if (ch == '(' || ch == ')' || ch == '\\')
+ putchar('\\');
+
+ putchar(ch);
+ }
+
+ len --;
+ s ++;
+ }
+
+ putchar(')');
+ }
+
+ if (PrettyPrint)
+ {
+ if (attr & ATTR_RED)
+ puts("r");
+ else if (attr & ATTR_GREEN)
+ puts("g");
+ else if (attr & ATTR_BLUE)
+ puts("b");
+ else
+ puts("S");
+ }
+ else
+ puts("S");
+}
+
+
+/*
+ * 'write_text()' - Write a text string, quoting/encoding as needed.
+ */
+
+static void
+write_text(const char *s) /* I - String to write */
+{
+ int ch; /* Actual character value (UTF8) */
+ const unsigned char *utf8; /* UTF8 text */
+
+
+ if (NumFonts > 1)
+ {
+ /*
+ * 8/8 encoding...
+ */
+
+ putchar('<');
+
+ utf8 = (const unsigned char *)s;
+
+ while (*utf8)
+ {
+ if (*utf8 < 0xc0 || !UTF8)
+ ch = *utf8 ++;
+ else if ((*utf8 & 0xe0) == 0xc0)
+ {
+ /*
+ * Two byte character...
+ */
+
+ ch = ((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f);
+ utf8 += 2;
+ }
+ else
+ {
+ /*
+ * Three byte character...
+ */
+
+ ch = ((((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f)) << 6) |
+ (utf8[2] & 0x3f);
+ utf8 += 3;
+ }
+
+ printf("%04x", Chars[ch]);
+ }
+
+ putchar('>');
+ }
+ else
+ {
+ /*
+ * Standard 8-bit encoding...
+ */
+
+ putchar('(');
+
+ while (*s)
+ {
+ if (*s < 32 || *s > 126)
+ printf("\\%03o", *s);
+ else
+ {
+ if (*s == '(' || *s == ')' || *s == '\\')
+ putchar('\\');
+
+ putchar(*s);
+ }
+
+ s ++;
+ }
+
+ putchar(')');
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/filter/texttops.dsp b/filter/texttops.dsp
new file mode 100644
index 000000000..12b7cc6be
--- /dev/null
+++ b/filter/texttops.dsp
@@ -0,0 +1,98 @@
+# Microsoft Developer Studio Project File - Name="texttops" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=texttops - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "texttops.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "texttops.mak" CFG="texttops - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "texttops - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "texttops - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "texttops - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W1 /GX /O2 /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ../cups/cups.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"texttops.exe"
+
+!ELSEIF "$(CFG)" == "texttops - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W1 /Gm /GX /Zi /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ../cups/cupsd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"texttopsd.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "texttops - Win32 Release"
+# Name "texttops - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\texttops.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# End Target
+# End Project
diff --git a/fonts/Courier b/fonts/Courier
new file mode 100644
index 000000000..5ec263dbe
--- /dev/null
+++ b/fonts/Courier
@@ -0,0 +1,1494 @@
+%!PS-AdobeFont-1.0: Courier 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file COPYING (GNU General Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Courier) readonly def
+/FamilyName (Courier) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /Courier def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-12 -237 650 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020945 def
+currentdict end
+currentfile eexec
+e98d09d760a3c22cf119f9dc699a22c35b5b35ed6aa23593c76d54cabb5e
+942bf7d6dd84f1664b89699c74b472de9f8e6df925f6c4f204e9f1c639b4
+dba988ed2ac419ff2b2bde605b8ee3264edd66412d4f21c64ac522bdfc7c
+5502f9c3f3e5592b3b2093d33c9bfaedd2d49e89aabaa832e23f062e91a2
+5032519d1868816e44b4e0747795003d7930299d6e1e2a5bfe0d595dc97e
+140989ce81d8d7f852ff9cdc7a1b1b598c69131dee005b415805a16d8a12
+3e6a2261c63c769d2f4b60fa2c438ad7d199d8e45f7e7c9a605c8ca14e21
+fcd81c9a515fb8db6f99604534d06ea9d87fe0faa852899c9d0595c7a97e
+6c55f79fac45cd38e87b10d210ce7501e88c8fcd3444354365fb893a12f5
+96ae2c1e70d5819ee0d087d10bf8da96f3dabd5405d28c4228c6c31ba405
+2464859640933feefd8071c0c84cdd829a9b1d0ba01f25a4d50ee2ea2b45
+160ca6333b2d2800306ed2befdfe155e9d9f9342eb8d5b0adbf2460ccc98
+643fb1287ccd28aba7b5cab92ec39ee2e918990372b16f8487eba30eae88
+708b6cf33b6c015d8096c7cfe2f139f52052e3925c0d50fd64ce68236d59
+cb83ef56bfc584150ec38065059f3308ad6f9a99f83ef4e6cb13855c8175
+e31417d190d036b387d3952344a950f4d8c7781b307a094df1ecaee4d2c2
+fd747bc6f7f9c6bd0e90c19294f96c8c5cfe88fb34c477574a1b1630b8cc
+591529e59b20794da32e61decda8abbd1ae956cf74012aa01d42ee01e861
+b0aa6897c864788ae59def43c493246fdb1aca554c12594bc7b33657a9ec
+c9e3d1472ef826073f632be540c35ff6fb40566773f3bb2204d3a579a08c
+cbc844c14b18c350f003b9da23a570c362d6003893ca32f86f59b829c78e
+e3188b6e3f7fa81d7f622825c639638dfb78b7af1f500f5b450fa54dbfa5
+cba277c794ece93275a3de0b452fdc8ddc2993baa42f28a636008cdcb03e
+bf71bdcaf35019778993443f88412ad2ad0d7155a3944606463266322dbc
+0244b07da1e9c27a27b59664e8566d7a54cc03e995aad008b0a17e2c3ef6
+1f720ce7f7788599c4e44c709cd5c31b11107f16ad70b17b9afe2e8cd922
+a7428dac171427ffaf51067307fab0adb530e701fd22da22c4cd3064067b
+d4f6089c4b2c87937dd426e4e9d2f60e608288bac9056554d04947e69200
+61e379cf5e81bfd32fd37efac1f61cebee551b0851516471a7472c60df89
+daa9eb1dc5a67e4797453e69b9e22baf4e3cca4192d603295b018c4ab69d
+18de52dfdf15e96b557f290a4b8c5b1e7a6caca81f2351b97adfc36995ab
+a43803a6e5ac04a3c93495f6d38106b8b144449c07d1358210f9176e1565
+72363cfbde576bfdf99fa329dd1346e83f79e06cf68250ca57a68931bc7f
+342ad295d0cba17aa95bb8eeb53ea6e8e660b814e9f857cecb14f44a4328
+8b69a9e7908d55bf19e844359879d28caef1c38a36420185d20dfb32c2e0
+02202800e8ef3d67c5d50e919657ca958b538d537d503444865331d79bfc
+40312068d72364503bd0cc84b5f30a74d8b5b6a26af2db764564fb65a6ba
+8f9051ae2b4ea458d46a4569f30c6e77dc097356770362e6cf3f16610747
+78ebb44ff7d1e3b64ff75e77e11fe525bb121c6546cfd13300ca1f02d571
+b82a5825e6226d14fdcf27f06d87452a8b6c5dca658535cee2a795e58137
+d48e566b69d53a0c3b766e84c51eaa221c46999cc8065adb2f129d5b630f
+ab1814c0c33b5aea0efbb6e994d80941b53079af96d90a0b924f9b0e319b
+ed9836b8f9053f868363d3ca554cbb181863301f8cb940872ed5fa7bd18c
+e39218b5ad8ac57d0f752d941076b1c64d99be0db86d7a6d96510d772eb2
+4c587f11779bd21cfe5bde1f29c1ef9022b2b8bcd7f91153c84590672247
+7829c40111d810480f3cf62de8dba7fd86cd236e656618caf6fc46827fbc
+4898ea7672f8c9971afe43e0e01ec8b77d4af48cbf1210e98c1db15c16d1
+49bff58ab0270cf015b107a3a50f5dc8f37ffb92eec8cb6778ddb7ce4aab
+c464c4aff654223006a550eb52485a23d2b4aa7198d3cd54418102f1e9a4
+fbde37b841e56f5c2c53966db9b66b000e4588282e3fb80c2c519339f000
+2d2f83c979edc5827a3b3c8ef8810a0f9dacb6b9998e9af6551f56313dc4
+011904cb979aa2d32b11a811bc248141e4b9734d9fb7982a5671002d8279
+cab93abe057474628defc95d43890db1ed34cfa8a20bdc3d874e7679a396
+158e522ed0ab969a4e3ec7e4474e192590504d54deb7b260b7935c4e5654
+8a7d121ac1f741f8cdf259ea1b5813175a77a1d2d30ba26f65eb765a04c0
+9ed51f69f41551adf399e6aa2fc09788137bea4913f17b8eb838c38fb272
+1fdcb55fd65697ff0b850e7d3d1ce266bf90f7ec06a9a0876bdfe767d3a9
+18b092fc78c775f945cf1f96e859c03dbf630d9a940939654c3549d8f792
+1cb94ee23d5a0535de9df31ea0f937f860b4f220a99addfc343d7cf7bfa0
+b803c12c26403f0dcffc8ea786d0d8a8d9c367419ca8ae41190ce93a8086
+583a1e6c9d70b612c84d87d2eeaa71ec2dc12f4cde6a821303d5f6a9bbdb
+7eedcd289e80fa3b75f47f481b50719dcf4a142069393593b9af9cceeaec
+56a35b8787193d7c88113e9e1e221d151e093b019ef89f6118bec4735103
+cc8003cc5ad1b6727b3226cd44c497da7052dd681695dbec3397f9598c91
+77701c73bf0594ce93f23d50ec5bee2fb9da1fc966df148b27b28ee3c895
+26dd6625e2887f9fa0767c127c609ee315626bc14d274fbea56528dc06a2
+7b2d476d46e9e7916590b156a5df04a6cb15e36245d77021767b6e5bdfcc
+679670263fd891446c3371b11bb6e1df60f960aab4149d7753e6a5c33810
+c42c8bff4e935003388506f8278bd7cb672f132e065ae684dca0b9064d01
+dd620e7ffdfe04f14277efe8e60159ba0fca3fe2f28b902d4ac275d19f0a
+c6971ebe827c4a232d87650d2688345bca78f879077114f0463c5f058107
+b669566f8171e4e284d278405580f04bffc9902784216e0c9a17aa9b2935
+e66e18a783f723be044389b7e9d62aa36818ff2ea406c3c1a9d2f3436f3e
+e7db8be86afa8daa6a4b1b84611350d8d27605509612b515e16aa843164d
+5d0805e36a2b9ef74c5f6a0b9d59a04b5569712327f4b1b30e9587cd1033
+37639967cbdc655aa46e80d2cfd24beb50815b5338e522b3a7afe8362ab4
+f05d8bc52bba9c5089ada8c89529b0275af422eb540d31a938b874086075
+6325b966b36817115213faaf92de63f6bae1e0064bfbc5588098b61eb83c
+71f1c2082436d37daf1acbe186fedc4be7c1233b6f18bec5f99002d21cb7
+864e4811f7ab3c03003e1e4490ad1ac793bd28fcd5ef0e6cc30ef39a08c5
+2f71939b0cef620dc69e31e39d6db969049031b0c92ef2db653d97f37014
+1456a52985076b268652fa2648c792780bad637c4d7581fb2d62011d57e2
+93719487cf2d1f013cfaa532e1c2d39178d51272a6af041440bca174b5cc
+902bd7390c7d3695056cb4bd7791f9fb6d88e7a70def2c97869f5dbc5bd8
+23c517c7b7c39d624df627dc9653ea5347bfda80b723f05f6dbb4c9ea501
+d862ace05b9dbdf21b7056fbcd8c6d4b85873dcee6166c8b5adc0316ca12
+d9639f361b15a42f00e1d62edbca1111972fa0f45758becb31db38316f3c
+dfe1b41748c93ed58b67e9b57abbed5924a6d53e99fbc9a994a6489a8bdf
+13eb685548b4dc6d62da7426c22227d4d43b6ffc7b5ea91c896730253e89
+41afee588359c2becf6ffc415b9eb6d31ccb0f6c7f85853e6449fa6d627a
+97a3ce8303f148393adcccdfa2fe085c6908be5c3c05af00a6f02840206c
+3253a559ac5c049bddfd11ad9b118403b84da10ae3c470cb9a9a2d1d7b73
+2f59f5fe146deda60ae750f551aac934621b4470e1bc324c436303e25f81
+d0dc3188be0d6fec5414c20e4cb18952e12cb6423df7124627acde145500
+d77a97a8bfd9cb50d1faa008e2ce2b2505a4749f1ebbb092c34702371405
+5a9b63353af9e7fee05bb54c9843698101f79888a91531773830c2c967b5
+88d3acd2192883d5ce3962d51084fc653eae2c5fb2da41dacefb5c76812d
+2edb5b109677289cd1998d457fb1023a19ac67295bbc1a9a20a426b06a36
+8df3c5dd083cb1180d287f5500f2c635ede157eefceec5503447382d15c7
+48c1e35f68753992e5c90f900de54d18f8e1b355d1076adfb1f3590135fa
+d1a36f028e44f48abb149b80ca9a54614d467f8d71cb310bbc7ac7100261
+092db8c5bfd39e0ac6bc2c9d6cbc3a8c05ff8a74cb21608ec4a4cfe4cbaa
+2d056dba14206106044decf59f957ef8a9cade4c9b19d8d30dd4fde6a954
+8e50db51aca73330142153fc36b69c1c8d5b26d0c689b7040e81ac2c864f
+d7c097c99be5953843e172c97ab5684f35fb03a725a89dbf371f08ddf40a
+1531fc1b676db0e1543aec6e97d3d2e4aa3d5831d8b3c952abbfa1123528
+14fb6fab61a0d680e6640f6aec8426200cf61286f7422cb2f78c61ebaa36
+d47ec16d7faf8b4af31d090cdfa255d9d7c61d46cfb22a7d6e1758e71ed5
+67e00cbd8e8f468ddfb477f091a2f915627f22ff47b876544bc1f03b6bbb
+98385f009c20bb1aa2a7a78674692b8eac2e3c8069b79e679338da57f729
+76810f845beb6b9add32b95d78e5e60f16dd16689c05fd82d36a3115be8e
+d494a74dd211d58a2cdf983fcb9cdc29bf7f0e29988fa23560edf514bc1d
+183f3b2a22c09fb179b47e05adef48df02f31c29875d1915037b19407764
+a4292fe44e741651a8e3beb5f0d972b6327090f664417c84f84ffbf0afff
+8b1d85c822d90730ab4140c42a51aa8b1dbe43984ea8566040eb8b341cce
+23fd3f69dd235a080ba5c69aecb9bc732bc2d7d40617dda6b79fb6ee40c3
+556c7df9b23dad89e94054b1345db8402ae679fc4655a4a776c0150463f8
+db2bfc0608ea1f124e221ddae6026b5e5d007a7e4a0d6b3b0cf3a2669e67
+c5e4f01551966a7bc48f2f4b6a87e740d8095e63f77c7a027f26b52f2299
+de5b8a2f6209bcf3d31cb0235f998f781e5cc81e31dc424e008d46ec0920
+2951e5684804a0592ea47d6c788a20487bea2ec8f2e6c1d7f378b62db43c
+a43c4b366f8b4319631cfe9854f0e10321cfa3b01c873584863bbefc23c7
+2c05e695b56e8a52e89aa2dab543834d34dcac5fed08dc51825c5257ae59
+850d101d84f4caa1d29fc932f9e0effbf7a9a7f3685f61f0490cd3cc8988
+2db52a757a6af4c4e67b407bd2316b1c0ffe7dc54e43c87b874f57e49033
+34e2140b011484863cdcaca331175f2cf3d72e0042855983aaf8853d3015
+e870ff0807014c31d55060df3fe1fce1573244812744ab51322444632f9a
+fda6706e320ffe82b8cbe242a19df00ce73ee48e25ff49d5871bd3e60652
+298fe3e8d400609e232e0ddc794c0579acef89e841b2edca50d51151f65e
+8c1cc3b01ef1870558f0bf5743718c3e068617e81bfe120c6ca16e0924bf
+c2541177d53671caa3ab641c41557dcdae1a346147b5e999c4541b08b4af
+cbc187afd653d5b5f8386df6ad8fe69e21bd0567df494f736c6a184fa4de
+48dc9f347787ca96e2e00a296c2da05c2ad9bc423e9ca428d7f1fa12dc93
+53a302fb8c529af8688cbb543b45b2717ebf8f6c497935f4f3bffd285e04
+02ab7544b3ca4643ae5a8b5250ed987a95fc1f275b9707acd0641bd0ee2a
+e9758494f8d8a51dce408a38ac20eaf0852d72d84d0c6be973326793aeb9
+55eac6fe0a2813a355dcd22f6f2ce56588d1c055cddfa98878bceb6a018d
+b22922d2b600a20f81842e665df41013ca0947c4237c2bd60a75e2fd1a3f
+b8c8fa19485730b87461ad466acb02df8ca240914fb090b3d2b41eb6b8ff
+05e1a59d9fd668af70ba5bb72778953ba55fc5f9f626043450e1d09bc83d
+8605098abef884639a37809a32565cbefb3ff39ee53d6c18c58c272bb928
+e4410e361e59a50f242d69747a032617c52debbf62364ab5a96efaf642d9
+d82ba679b1d70fac10a4eb62fa5cfc308e86368aaad7e75948f43598cd1c
+544a0d4091374d7e88d4522cbe902391641327e888e7748fa889dce67ade
+61699e7d77763681caee9b1ca8837b2f7ef9c18cbcc538c465c8e2dd3461
+6953ccb6030a222c728b834911c1a179e2c770289407ab28b303e724d97f
+747d6134b425216a64c6e0b60f633e2b85300047e4c90339ce030a0fae31
+e830c8aba5ab3386a3b69267351a7bfdd66356ae5e57fb2994452993e90d
+e7c4e260abab93c37831856a650d56e44172feca01d6c7c380f250b82473
+960d2a2a5fb6b4da668f46e624acf7fa0fd4490f485d640a3adfc9f8652e
+7a38ce5799f770c3606db4b8b947f93967f779e3a3c0572f13a5a187d31d
+7bd12a5c7be23cb6ed6192086241b76c5ba6983db9c93e4b208d707d3760
+f03cd6272ef3a4ce89b8e52e6ac5871a3d03eb975759ab4be239e5ec7842
+cbb333e692cc607c722e185d3c39164dd320c6945629c70ff66a5237c0a9
+520a1fad6eb9816069351ab0f135d90cc0982b147d2294ae4a38a527ee40
+be9cde2512aaebb590e134388bb171d0956a7c4566d65a9a041be6c4f883
+6b3ec3d2ed1b48b566a783292b15b6127920d247d494f070bb20beff6064
+0b11b276ddeee49706e8b2b21bb40b7f00aafc594c492c25dca774e0b80d
+82e927448de2e74a9d0dc7ac9260096eaf187b6cd6aeaa6d1dc4205b4411
+122751a5b22688404ea7c5861730371ffac10f5afd4727a0e402ab5ea757
+606b75eb86a05e8f774d6e430a1a3fe2a37ebb06700474239fb1cfa05ee4
+4b91b82244c575b52e7faf934b04eeb0d933feb57ebe326d75821c8b23ea
+a85b583aed4320b7f04b9f2dc591091216fde52e064baaa9c2c9d9714b95
+a4558c21f3cebe624b5403b31508f178581af6863083ed762f1e2e34a45c
+fdd71660d626ff8648f5d6c5e580d4765a67fb6159ec8077a9f0a88038c8
+d3d7c77ff0926e2123be874f7bcaf129d55a5b5960f824bd1728abcfcc51
+d23936de9a25c408d786e44c3a2bafa4423177ad060d21d38e15e23eb6ff
+c0b4120e814695d423eefc2744a1fc81b4df89d76f0a6803d8b14e75538c
+aad03a72517b86514f6952f6fd619d9e910d980f00964db325318c045bdf
+79647f453d4a5cf4e61dd5359782827229310405fbcf6107c3ad9ddef9a9
+a339d5d5a6eb2e7838a0a43221bd62cbdf732db0a638a52016fb35ba7761
+aec846a023d3bf2d1bb183543e81eb7cac1e5970cdc6f068c5ea118c7aae
+528d1396e6dc939112da4460c890ead5c01bdc438f5bb734218ba6270add
+0dc1778fd8ab16831d6a302b814a1a44b07edc65956c9e6cf4875df521f3
+ce5b422f71081b6d69bd270f739095c9e81c0377934a8bc6390c420c4e4c
+dd9cf7e32544c68d884e15aca3bcc07fc8c132d8fb9d752c15d75c52c288
+57e2ea461a6fcad90c56843513f74461f18d7164bc597a28ae4ba7c86ee1
+703535a9b9ed5012262771fc12f102e800e0e1af7bb46681bd2b14b614ce
+a91b7b2aaa35235de76c0e113c92688f8ec81277d58c3406778e1ec1cc15
+f1cd9a137c8ffdaab99ace3bfc782916f1a877170589a92dc921e6740a22
+b84dc6bacdabcc76e64c79e3a588d80f8f4d376e1b426f15751cf7391102
+102f0afafd8b22dfdeb548aeb5f30b1673023d22054a13391a0ec08de6e7
+b685a0d031aabf20b7c62187c0284892d5eaadf121ba28263eb863d5e36e
+a9c06a77ccfc0e17f593961591f84d82af823efe41044c8d606fef83ccc7
+b0e961e7994df8a3cc36b209d953e250adab8d22d7f2b4e2c9ca39efa2d9
+3e56195c1560e30a5190cc5b17faefcf250df79f6b624a4b917e11c33222
+2fccfec4f6a47bd9e75da9854fc3f7ae554e91edde144d7aef38a0e3edb5
+e5a5626374db94f022c8cf549093041de00d7269b7ce544e748439ba2870
+718c08e58fb4a77d93ebc04b7957d272ae1601d41bf85a2badaa0df73b0d
+3841d4839c85677fb2e15f1d6ce592669ff4bbc9c69dba334dc37706f2f6
+be83d5863e8cd6a30c08640aac4c233684e66b4fe6b62d4a8be9d531e47b
+ef5640d9b5c27d990092be1597f6995c8a77be9c18aae6c1cf130775ddac
+41d34438fc7ad8e042cb56cbf2944932eba7d053e9376ff398367450e35a
+1945fe23e05c921096a15454721ffd0f429a3e06dc3ed36f1c170be79c66
+996ef8337aff85b90c5d3a4a94455ae9fa32e2117a63e59001f052d5f622
+3125bfafa40901e98960adf7bb886729dca82fc3b8cc52b37ff2517299e1
+d769057f8154fb95582f02cb0becc873a9c71796adbd3e91324faa94f2c4
+1cf57c30b5897d031c02d256c909e080e70bfd1f32e69ef67031138c2ddc
+d1a8e4b65e485c23c3e450abdd9815512d6f34a84b9db715db2c7a93bfb4
+24316e1aa44397749cb01088428f149a3b4324737ed9957fd388248462ac
+1b2610d72bf5c073eca567e7385cc959e37cac7e05470160ffa5a9f63b8e
+9b082937e911586ea165374938f492edf28ce6020953a5b5ccec7737f9d9
+cc8538c4339567aaed3794aba3b9f4eae65466e8e326f6c399b36355935f
+bdcb9972f10b13494dc25097fcec5a6398f275c8c151558e74c5175f7baf
+4155e36b733f75cf9d5c5979b0764f14d8306e06ba24bf791141e404c69f
+3f8fccd91b9c58c2c671aae7d4f9e5d6414e46ed633a5f78aa5bf04e6522
+46a066ead9e582b181cc196ea2d3cfaa383b5d0e4cac9336e119c08cc6ac
+55cbfbae147c623b400453bbf447e96de036fc025624384359eed7c7d5f7
+858dc0521377cf647a157fc3f188de5eef094dba125510fde34c570d7be7
+6ab5df0a28bf45ddaadbea7eeedb936332dfe93081e0afd3fdd46bed08d6
+914b2efcfdc41662a33b90b03d76d34f48d30fc6bbbb600e90e6ac7243fd
+f026762a44b4d6e4ecbef48c9d7b696af29eee063e557d8fcf0f09e0136f
+45d17e608da36e59f2aecf8493f8d62536119b5f7e1554dfe3f6e8d7c9a2
+c6f557d18b4af92c9f6e050975c3b5c54f9b5f4e39d600b6fa2cd6de203a
+174028cbb2a201af126d1013c229bb82cfd013ed199d01e51ee2780fe896
+e01c63c655087a3e61a7f1029fa5e97ea1872f1b45f22282ddc317e17926
+7368cb52da9444f6055a3c653659cad2a1d8712bc2b1b32c1dc6906d957f
+b88524ee066156ed6bdeb8d832f9338f9912e29a250a8c4674e667c1c278
+b677aec9972be83cba3fb779893fcb8f81a323ac91474ba2a2334a07bb56
+28e905c518e634f6761a3289056f83d5dd7b3890987eee1c18fb2d379cc1
+905f1aeb3b3d2ad578f0d6c845d2d40c4bcee3f71c90e68e5417bb8cddd8
+78d83ba80ad8485f4067e5c3cabf28ab56cbb219c0aab8ffc6c7e192bec8
+cbca1459ae4450afcc81b9548f40ce2622e5a7c281f74dcc02dad57efd92
+d072318ddf05bf42f1ea8163071e23949b0179cf7de64677ca99b23cb926
+b3e294194ec13397ea1dc9a5e1cdcd828156cd71f81b64167d4fb01e6002
+713bd8ac6f82b20cd3699c6ca4704dc5c65a2d66eb155b7af1c9bb464694
+16fb49c1c7e17a30a5f045271d7df3fff2f42c6b470701c381e3456a500c
+6bb3d0e47b4d91c5f34b49bb6272f1f8698b307d89eda3a1565dad1c0864
+627560cf922dcf5b34c67860352390b282f95394aa2cde0e97ce3ed39546
+a6af1c52bfcf81a29be82c47c99e8050e4889e4575b75f39e662f2db7420
+673797e2ed3d67cda7ae2c15d0a0a794d57d168ebe13214e89e0209ab2c0
+eb7784e9491aefa3c02d0df3ae5365a0fc4ae023cab528162c7a1b173664
+9dfaddaca8da5fa18b7d6489e4229e9e24d38a620464a744a5c60f6f9d33
+4b908706b738aed186698a8b278341fa4d65a0a88680ba484694921512f7
+de93337fc1c02bbe6e64af2dad07603279d873291d1f4d39c1dd6d89c90f
+65240f4808f6f1115ca55b88e242565e59f3bbf1f10ec7b88872e9ae61d4
+4cae185463edfaf7df63de4d2207d307afb61501892965170d2945846fcf
+5973a1d458607f50c15e06e5bec715e0c156259aaa6c735593e5564f65f4
+43b78cc7512ec35a56f126df9d30974a40872e4265e1ae5fd483cfcbbba2
+6dee426cdc4721f19c3fda86ed7ad4fa1120f63669befe7002b128ceafd8
+c63e8ac09943b6cbdfb3d2476a026c00a8ff81b1f651b97f310c82aba5f3
+88cc1db5afcff5996d5252a6a42fa4d972e41ee56088f78cb966f9051171
+c472c774879aecfff08bfd9cea40d7c298922ace64f28c14e0b81f4dcade
+81d71de3983d87d905192ef13cee71b2d3ff1a88aec671ec318917df98a3
+c9054e372d22a3cec82fcc217f47319a40900312f6e32b536b9e7a7fa083
+7ec65ccdb5fb0d41437117596cb39d9382262de6e65379d3a9709b2cfbab
+f5fc5d5b352425f06f88cd31012a2a4147b112f0c1c0accc808cd625e022
+8eef66661f70af96d3dcfecd402700e4f6522ac9a856da466d55c84f65be
+2810a1565163872d62eb81333a698ed7b68352cacca2d7ad38ab55c19e4f
+5582f75818302f5fdadf1dced09d94872f2d48fb636c8e38c7563c72c771
+a08c6b1f041f3532bdb39006c89a33c09be1e3e603622d891f98010bf1de
+5355f557a1e09448d486adef565705277b31b8bf2b86761e32631e3435b6
+88b79d566f1747ba456ddb43cd239fb47ff7b425eaa4c657c8eec26ee01a
+ed07cf916e77d53634c137aeea009c6b515b6342c54be2c7b95955b1a9da
+277a0abcda2346e88018c726f481f71d6011aa42f8852f2e5749518fe3b3
+ab668213fe1a05c10a1c53953d75312631d6bbba01d418199dfeff8cf548
+6109b099fe8e2f606165fe30f532c03567785d5362aa873c9d3eeceb20f1
+945d55f49b0ccac8496759fcc7292e46938943c262d78f3212d3f9d0f7b1
+03157f423d71b1ed54b2a603f4c269029918f238ec6828ffcec66009db9c
+9e59534eabb183f31d7ad4c57b1bdf0bd2ce5a421882bc10cc1bce6a970e
+2b586bb221567cca483989dd0b8dec424c1d1ff042dcb7834423cf244eda
+28d2d969b17440caeaf024a6119db010ce366821afa424d1b8299609c041
+48275ae6e5257a7acb3c766c747ce99cba2d703cf19b7cf301b634d8b613
+ddc4afe4633a4d77bff8e00cfb5e289ebbcac90a24307e7941ec1685cbae
+400cadd876fcef7f6557eee167d2035a05120293527700dc510b038a496b
+e1d5cbaef24ed39f74211a93aadf22214ed606a80582485afe358e3a46d0
+671148998a3b3be209467009b43400870359d4189a8ceb4d5866ab52d16d
+9ceb1eab71c07e6caa34b70e3096bf7604c22c40d5fbfeea616da3babd59
+dcdb97d883fc8742b8267a16a99b7953225f7144568d566e64542c92e538
+ac140c851e5d295528eb7cbb49909b1caf6409c9bcceb325468fa0b5f7cb
+2987382616b477ccfe4f4ac79e4a6f7165363543f04de5b6f6e1c2e910cd
+c3cdd6c4c92737198f892337dcb6647bd226c820ac99c65d8e7772bbb74f
+e65dcaa8a22c33bc168bf48e40a82700a3a7668c5a9a71e397acdfee7d55
+6c5c19467b7aa69c260b727407ac837bdb7d67dec055c1f45d8bac61048c
+45bc9fb3cefe7549eaa2992d2edc126ff7a05eae58613332a2bc1465b2bc
+0429162b907d65f793d236eddd8d35405866d71b25f62dc4a7e06d4dee82
+840accaabc0774f8a63e9c0f7fc980b3583e7a8b01c46590e3bc04eba565
+c2ea94f057d964a78a90ea9f52abfd70f84e44e434bd10a42e98c7940657
+24341f907e35d3cb257161e01c7084e3a0166d15ced65da7ba87dbb2ea33
+d39bd99afb93d3548358d08330e807f8552cecf63c84f805205491ba3a1a
+622e70c232fadf3bf2dcfd6f0539158d3306506f150b0518371912a25eb9
+6163d73e9eeed42edc84d688bc7f7708d9dca348fab4df62e5809bd09484
+2d0a31dbb7c4b41f94d946810c5ec10b69aabc2c91a59500b2e5d37f4755
+ddfb7ae4abf757f4c5bcf77c7f95e6a616646456fe8f18407080bcabbfa5
+7704287ad26222df91ab2613951e2d679472f8adf06ea2a20205ec199722
+99a78bac52114334470c5f5890c2f846b4c6042d73945127f2e3910eca1c
+4cd7a16efe4b4be38a15aaa710682c3836a8ca83fd384970139d8b46fb0a
+ebb002dd224199672ffa02250fbcfa4e649e335428fc71f50f45e498419e
+db0e970f46894a48f65580881c9c4250fcef65c9b28699408e18b26fe6db
+7f1cbdb767564e73cb5954c6d639ce33220c894f36e70f71c9f9aa3fe2ae
+0aa0e3f2e304ec5abc661675cde2e70519e4220ae26fbacbd01d5169eb84
+4750753e6ced53e3678fdcd08ab93e10067e9c64f38b40b76d99b6cd92bd
+f4155a1ea5cc824998b59aad06e09e5f15ebb2288d66ea71b296616734fe
+f2796f07ff0d8b047074a1111d68b99c2b70fc56e74a51b062f4998acc85
+b1943c9477e436e5cd7ab18dbc898d21bb93475a623bdda71d7b895ba2d4
+c10f4b90bf335126f4fd57d73afa50170f6b3c364922e551d40e35da75fa
+891762fa23401d39260f2e92c7807c746f13bb35cef9dbf2e76e66a72fef
+f095da482a4de8a420917065736cf4de904fb52e649a32255e2030a7b31b
+686353492f31c064a3c4b0448c4bfd44b8e15384fd809b8761ee26a7dfa1
+758d57ce4f0bc376eb2b3833534b15a83436ba553955acb5a7a66796ac5b
+92db5388bc53efa27508b08e82821e5cf669bce52bb860780f749b4f38ac
+df5ff12726bf3ec2743f01014cde96fe6b4c40a034e9eafca2a35ccc776c
+2669e6ad138070a40f48ed79136d7ff57e993e09b81c543fbadd350ff5b5
+f7a46f060f88e30fe2d8233832d18b6c323ee017ebc1df5c838321cdc8a8
+4cabcab20b60a1a3aa028f36ea6e87c850af8af7cd50aa6359038bfa8818
+821d02cee8f51dab8c05f7ae9797814d97f3db8ccdde45b21dbb15cee292
+faa534a5f317b357f4091f3da357325b8b9f5edb45865415973c143e5e5b
+aa483fbf2d06cdd4246675ec58b84c6ae65ca743117ff00f229243772561
+31a7f2ba26a9115afd96c18216cfdf41b7220ed0cb3fcc26c36380007b38
+2a02aeae428887dc8be5fdd630ac57ee3dc156c7b8b29e687f24442e35ce
+10ba4087295a641f7139c831f7ccda6cceb5dafe537cc1a97c5a337d3c48
+a6ae947f58a30dc08cc7b58dbbb4737ad52783c573fc1e9408f55495a80e
+7fda61f0b9c4f090158f1a416249ebba936c27befdef19d1bfb839eb7057
+6a010706d8b95657b2189c2ae04c11ef9e57fe09880273761fb4302c388b
+d608fa0c7f00f033c9c00f4e3d5ce2d903e0da52e69c7745ee9fa75e2ad9
+3dc6cb5ccfcd3782a699b807afc36ad1f62b05856d5dfd6f88831b90eb3d
+cd523582a49732e3fd7253126d39e8afb8458b5f7ad7f94a8dac13365f43
+3c857af4a42c0a08c4db9887c4957259ed22d13cfdf5995da957ea5a0f62
+0b0214fbfe08ab6d552dbf048d62cef6eff12f153511eca7833e0e3e95f8
+5e6ac0f95438ac4c126e1f1ecf336ed31cca7eb216d279877123fd9fcd8f
+b5e52b587cffc4428456ddca816819a8a4a211d8f1629e5d42ba4c5c356e
+580c8a22c61d987552faa97893816da73d423686e4ebd44375c257f03131
+8865a20f22115e72bf1eb9f93aaa169c140a33a06c35bd4526a38be79cf4
+0ad1efa10411e8f3300a8a8b97ab140ee6734e1bee6c8ee443d698d34159
+97649c6f10f20acd80236422e215e146d744a262da3fc88dc0d86ff66512
+f49d3f957d3c5cffeb424823509f33f155057a4c6f37b52f4667767ba94f
+6b8b62856b553f307e5d230c44cbfdc9a97a45b139ffb2f2565eb0e22026
+972fad0fb7b9576fb6f368b61979943a398773600e7ee1dfefbf26d45d40
+bda66ebb96a56ee9cae0b2420c5dd83e24dba9ff885bb844bf3d2bf93b07
+325dff60c0cb5fdcca0ac8fb5a2e119d5af26e53ab8e3b428481c2871dda
+26ef0b621cd8572b3c664bc7aac01a1d05b98f791a7080d294be81099bda
+7982432f3dff4775c44d23f4f1b2e0162b61a8b2cb5ee8564bf98e2ed403
+2219085fe6194c19dac98a421826caed7f1ab1477ab32750601021728389
+4235d7dbfc1153d5ecc48aa7293f19592b4d7e95fe55151889bcd1d7fa7d
+c2370d2dfe11d7e4ea34b5c7a8e73bd3a348fd389ef45b6167fb90ba44c2
+3e912f9a4f2fc0427ed070592f7110183bfdb2c400393ba7569058227926
+351f07fed4f33633ba03a72aa2dc6b598e49b96021dd868dad0f352e5722
+fb714f667c15c68d49c03d822d82677edfe86fe9668e537da284068c9b0a
+ed83074c92a5b939296d505b837e6a9ddab1aeab7455a08a114c2222b339
+284674b74bf4ca9ee0c020bf2a148b439c71c6be51a94cb64fbe4a7eb295
+5a455047cf5cb348b062ed4f6471cbc3e9add9be9b96879ac7bc71bce02f
+d02f17c6063985a5e8983d205aa1489da13c408990aba1c54f2f501aa172
+f530480d789c848118c0a74ef98d5f607a067baff6030d887ac6a6497f9a
+0b38f9705f328aad4bfbb634f739386177b07f22d5771282444e5ee17335
+b4d0ec86117c697e79a5f4f65fdc08e4904daedab20067eae2448fd43018
+49e456d085f392dd13167adf75ccfdb723e2904a9c0c976d6b84ddef9d92
+b0e15fb246c3ecc2d0bf314cfb957757b3a3e8e5801f520644e4601d291d
+a0f7507c06f3b9bb36fc1c70eaa444e14e56c0cff06c7f853df36da9d8b6
+af2544b853dfff535a7e5c6fc145250cdda229956019659d0d253a19a7b5
+1a4e538bdc01f74d77049949c2c97c7ec6392c2e61ccc0992b66daf1ab08
+551063e53180d2a67de496716ccbaa45462d9f91b66a22545962ddab1205
+11ff08627131b95e5deeb8b4dd9643e7b2af65c0fdce11f5f1e8dd468da1
+8d41c8c4f00ea73836f4f70ec50fc3ec6d358c0658a4261c6d15a582a2c7
+c994e7882e661855b352014576858a265ffbc425160669ce159d07edac04
+d060b44e5800a7aae8e339c29b929aa81d2f515c46229d2080d5917ab20a
+b6b34fdca8e4af64ed660a3173786fb1a1d005d575c2a5187d3f7cfdc94c
+cc44a38c5cd523e9da726d8efa6da7b6131dff3435fee838b2c7d6b97934
+295f06202d307ff78d906699cb9c5bbb10d1d4dea5fda5bfb094e7046070
+83b646d37f5da1fc7ad21b813f44d8c1afeab66655aaa19703bea2e77df3
+bf350e17c74b3447a452235919452b5175570a006c7680ac05e8950a62e1
+1d7e3aca35a397d1e19630d094a86807593c97f4c484e4e06bcff708b6dc
+a972e3a0009e1cac0ea4141530f5c1b8aef5e1b933f37fddbc4be22b74fe
+346d1a3f5fec0818f8e61765568a2ac04713e828f98c449d9a1cce52d10d
+61dd8bfd084c8d099a75d89dea64d5a7cc68bd5b0593d97953dada976383
+f5015915618aec56d71d1dcd55b89736395c609b315a3f1e1255432fdbd3
+7f38cc43c354fb4b7c44f1a7318b0b7e99c3c08c33b953727b6a63280517
+83a0a33e3cd9e498346a3ca6a77b517096edd52ae443b87643a646c3a7bb
+97f742888d33f9b3127e61942f4103c1dbdcd8eac8f9e259773066736ca6
+53ce57e8822651261d847c131321bb9d6626a1ac50d047c0ba47b411df2a
+995545bd68ec0287cc9b31d5ddca8755ebeb10accb3903ab0fd5788e9842
+20443b8459e7c078da4289f1350905881ad6dfdec47302b0acb0d4af8cae
+d02b4b70df3cf8fec118f0fc2d3dde3e494cd160e676e300bc464bd4400d
+b50ee43b314e0517037bf971acd7cd327cb2134893b8a0410e68ddc518f5
+dec966c7884cf5fdfe74723177f20dedc039d879056caab4bf045062d390
+4f615c5cfe109ac7a35599c94024b41019b9afd404a80acaa4837929f5c9
+317680a13d157a03b59a5588df79d2e113f5f51021d6f6f90e8bbba2c252
+fd10651be80bafd59c53a3367ba3c28db6eb9dabf1ea99f47b503f627e15
+dcf3fd645fc52c5d5d0f2f07db4c25c0d1e1c00146e1c4d973e613ccdbd3
+f9450cc0f5343d79f05e9492e86a1bb889adf40503bd7f3e754343685918
+4a5b20bd8a172f350d846b7570803990adaa48d4b9155a2b4c4bfbef1e1a
+065c08e03928559735bdd442ff1e83e1fa20a5da57d8bdb2ff5427c034cf
+0128af111e6e73099e046e0c240e80a73d7be72b87834e45898d475521ca
+3306707631f5c6136199f354632d1a085f12a1c7c473868b62e534d15f54
+84323e63d0574196a19ef175214eb35a90873efcfb92d6cf68761d45e37e
+aa61e1a1979a82009507ca193e44b36a806486665cedbcf387053aceab97
+9bd35d30978fc7659abbe844f4ecab3303318ece80777a5fa5a9dd91b3d0
+6804c4b4e9b4efcf07eb89866d0dd8ca390cfd1598651417114d78776b1a
+1d36b4ba17746d6be7fc123d473ef1efed1c3bc1d555f914536869fd5b0c
+35f9c83f65b0e6bf7a627b9202d787d72c600ddb6bcce613d88492e13ca0
+aaab196e8a49928c62cea4ffe2d0208eda334acf47f20bd793124d2c5546
+c03f4a364369a76a0425262f9d9118af54e37d32e33ab25dd533a49df5fb
+f1baf4ceac2d9d378cdcd13b00fda432d9042f623da41afb80699b5538a2
+5403b0b3eabec9e8efcf42fef3ea9f91766902cd206b0787c187d5370b60
+ad6dcd002de2de8dcdc0b4719a797c5e26baa67665016da0d967fa1346f9
+588aeda174ca001b31213617fe19ea218ec2359779d979e2663166489c06
+993230b0d07973a117c4e3f4a4c93cf8428248dd5389414d679c69644142
+67c7fea17e35b0cee456667a9b1875c81b2302bddea2818d6019fc1622a8
+2051f60584abc904cd918676305dc03ffbcc64fddac8d8aa9ce2ea00d6c9
+7bc63c8a617dedfc0e40775649438e9f61afd1795e3b20560b01be5e0983
+f136cf48ab206954e41dee0d9ddd953dfd01caeb569151d6bc0dfef29d70
+fae3e198e7edd8922c0e0bcb8bccf1c016142c1a8b337afa7a05a9d7534b
+184bf3bf827f371e9bd19a71244eca1ba73d484cd2fad54db2f0eefbd54b
+536ebcb5094e6bc2f5b2aae41f05b4b311115876ed42c34f8e643b53372e
+3f6350db8a38445822ea9a33e27fb0cc42cedcd1fe2fdf723fc47c996ee3
+56c402112f24d0af899b2d00bea1cfd427998bd22b2a09046d6737814448
+acfb10d387547d7009fb384af0562c85694c071584236d0f1f3d3fcd0cfb
+38b77c81889061e668ba7ab37aa60f58a3967de26f939b79cbf10a9dcc42
+852561d8d6754f1b660d216aab1e133fbaa321c56e2584be5c9bae20ccf0
+0e8dbe6d9c2fcebebad945c3c04101d2387351f132628786f6d9d4cab834
+19288d31f9bc600d966412e6aa457ce6cad26a4c0671097b98c2384c81dd
+8b9a3222d4f4bbda7017895c3edc26662779aee740d9d7e24185fb821970
+b0a3a94041a69e4805ec88ee1ee521981536f2844fb8f5ef645f67d42ce5
+148e2dde43ad5aef200edb3a2c7866c98458a92666e5f9e070178bcc39f6
+5a893102a10564af4e8caaa5075d2f8cd7fab0401c03af299ea3515cc930
+66744eb5af7cf0ed06675bf049a6e3c211a89e16de5bf0445a7cca6ee8eb
+0347454950485d884606651e5887fe8b24323e2aa16de22fc1fc8c4f06a8
+2a1fde5758976024068197e1f4506e4d3d8a16d40461a4586338b374a592
+dc60334402f76388ad6a457dc3f54e6169cf7ae3959676e966a456096210
+55ec3af80e182633300a4418e34a66ddfa6b569e5a13c9115b5fd3ec1ceb
+e50fba247f60803aa83976f00117536342dc3d9890c49b2ac701d370e43a
+955118967827760f7091469c5406f08f18d7e3548148cf0e312b1dc71df6
+7a5e7a1656cf2f47f3aff3dd50ffc2fcdab7177285b29c17ca43019f62ac
+6fba52d1493ed7c427526470acc8389bae8277594958908f517b2863b832
+92eb5ab3f57fffb08393ca610fb1fe905d88a0a16ac395e2a2a6dd033d6a
+0d68992f830b2e1b95fe357bf672716e88ffb92ffc3d62945d1ead22bc68
+c51ee0e10a43011db94c44685a5c4576f6ef44cbfb45f2a4bf110a01657d
+b51fd499767e78058199b31dfd60813f1a344f86289f9378231d5b151c92
+385e3650b4feb1dc91018eab8474cbf69fdc1496a4d078d2c351c8196451
+247a9dcf8117e5b637371d8e22e248c64d999015c3fd2311e9950b8ee092
+2fbdd3d7bff766bfe9e7ce0be12f318ff2a7b5a9c6d00a54401609304ed2
+c55f5c1eac3d4b38355bbd85d66d61636fa6e30c2e82829376bec979a6fe
+ee040e452359768ecf90cc539a546f17ae906c76f14f86ff697797322b05
+1eb311a759fe260c1eee5dacf383816aaf1294cffa7bf87a4d9bc595ee8f
+2c2f86feee11ad959d86f22fdaf4cec098942a57e57813a0fa99239e994f
+ff353c1e781d666b8928cfc648fcf0869fc68468bdbda7d280dfab8b0b3a
+4ca35b074b686de8d372c61fb32305169a1a9912f6541da16cd6316a6ea4
+51524757be5cf6e820011be3859fb8b8578c100ff029680e05f0e0bf11d3
+3fe19460c85ea5e4c0ef28e29407c8ae6be01cfa0d5022bf9fb01416fff7
+22a784dfc8fce330ec95737a854471d334fdc58fab42867a7b62836a8b56
+466e9a6c1247d46ebaffb905cd4321970f59fb8d6ff65fddd34bf913ad32
+2e68455c5ff2d23c1a5eae687f259bc982b6a384d35440f7c693cf50b9ec
+ac0b5578caee87588b562eb6b7f42034c9f2e545ec866316552354eb3728
+c7d26527ed75174eaf635e048b08dc5d23e88981070ad5641a652f234495
+6e9cf4c16e652a99f4a644d1787d6d36537489da4d74e61b2fc4dfdf1d1d
+9d58f9c26c5eb63200526afd168ac57d5611ade4d4a382fc28bb60f9e7d6
+26a6c67afbccd1183c5e3cf2ef210d0bf5cfa7bb10fa3887bdd4cd96eeea
+a8f9219aa2f10abc0a960c3b57c0ec0313ae10ccff1f522124cfc8d2d49b
+fbb0c193eaffc5b48fb3ff30b21cb76f0a4c0f1377c9223145bb0468a5d7
+1b9bc25873ea12e1c60334571c67385c00d0b570d3ffc6c7ff0de62c183c
+76aeeb12dffee1459e0fc818c621b8d12fa1357e2b55d48935d70bf140b4
+cffe8813defd479350b20dc2eb1d3cbb1a2d3dc6ee975d58c89d61fc50e6
+a0197da9a586b72255023de47dabefb11e8aa02414c2ff6258a281219b9d
+ddfe41ba7d7977d0d6f18224fe22f7d4e9355fdb35bf7ed3418f4f68d093
+ac48f7d8fe4194feb6c80b9dc1f74e023c604dea27089f98c3973ff9f4ad
+7bf7bae601db89b08d5d8139b95edcf6c885ffa8b3e4b0477e7040225733
+826bacfd1ec4a0dd72dc41734856ab9fb700df83ca2ce812913bd142d84c
+5c83c0b2583768198af9e885f2ba74877a414233207234aa5f18840557ca
+11682aabde89935338877c6d404bde4153c9827eb16d66c1d73a8143c8a2
+d3604ff72ce579faa3c5224bac48ea83ba8484299472007de96466b5b29a
+cc7c03b05dcaa38a48bff9f214de43146ae4e04fa705421917f99bc54533
+f0ebc01849e396216b9f0794e6f6c6b61b52ef1b1950c0fb609895c3c55f
+f574163fc8b6b09e66abaed1810e698ff37cc1f926b2cda3b48c7d77790e
+bd2d514b6f385d397f713ec3ad3954ea9c8461586031d369e8b99e53408a
+79d64c34eb5a56de8a67de91837960e98a66fc04dfa0ebde21db003234bb
+78665b039d0a469a0221bd541af7149a2a659c300132c14581ef766fffbe
+cba8b58a5eb3f95446def49af863a8113d17b2e7e6ecdeafc3834d4df900
+e3475596e86fbb4e2974c090db4ad61a737d611d92b4535ac291c56ad8b1
+c031d2f9b505bb77517b737d70ab3723db52ae2accd5dd2f617423ed3cc3
+9ca882ef41757bf7151806a9b8b0f312808863e3673fb54de939b35cdeca
+7fbc4dc3bdf5a5f47d35e345916c39366c8b4f439ce1c6f1835c320bd1e6
+7375b03b5de18c93256f251761a4c8cec01019c068e34447bcc503b9571f
+e8000627a6b3dad5854cbc0a2d69e5a8f46bc78f6a7b1422334ec7a98abe
+fe9b83e01dcf3c6c9273b346f3240ea225ae4a4083cc7b0ea141a0773fde
+940768358eb4b13d82aa304a1386d450c1c0c6a7d5a8fd2bd313f78f8524
+8b5196241e31e5595f3bc01f37700a2dd3d4a0ee2dd01a36569cd507130e
+8f5b1e96cb560bb7da15560ccadf3b2c9804a11d9e8055c9ec70e48c1d21
+3eb756a1376f2edcb7189d78cd3d6ca5865537eec31c17d801605efd860b
+0b629472690588d0257502c6f7a75b9a1c1b397781329832cf3ec43c09f1
+559cd562c48fa9500295cd3b0a790dd3fcd4684a7c7ac49ac9bfff36b39a
+9fb148bc28d37907433943cbbf0cbdab46d3ea86dc8f81c859c52d15302b
+94a9b51c199b7104deec9d769c2634cecf8b700ce9c04152cc59c9326bda
+cbec4312deed92dd087a1c4840868d9f97cac046581f762f75e8d24d6445
+370a3f1e0ae74a6478d9dac37e7fa5bebec0a1e081af89c1bbf7f51e3e2e
+22c8c405e8671ba85f1bf0df79a465dac7ec07f731e00632e017d190a99d
+83e27e5c2e63d7dabba23b2e88334c63721ac5a4cbc5d45f4c177259f34c
+2eade01fa008af65ebc601d8dd16436d86aa94c99f3cc0a2f87134e73bf2
+2f108b825a8963b49c6c685474afe4a542c8641dc0375d7efe9ac1168d97
+00459be52d0da399023e141969f25c0dac4668534b6647ec85454be945e8
+26b26de6e3c4584b97a38e2b40a0d23481bca78084fe80e00a71a790bf31
+df468a435ecc88e60a57860bbca3d65930186e9917cbd209c230e8f8255a
+7abc7d3f043ae4d7ad63d9980bedf062b7d5c298c40225b6d03f29a0339e
+0fca02138e526f06b9ef47f5e7a8068a846cfde2bfdebd24f5a73a66c079
+18662aec80b43246284fa4e2ee0d9aab172b1e59a6cc46b801149d8c0df6
+dec9a55d8e1b0efd9d302ff618075944cccb6831d336b11617107b0530d0
+9885e5ca11a5f1fcc8d69d603da16bea51116d42cab1aa1e4d7b9b4d7999
+3f2bfe53eac904feb70b2d330a89780eac10d12cc0c35b8399f218ac2976
+e57a26bad20ce2fa2ae2363d3fd2a8a971747556f2959da74a8963c20b50
+4711ae1cb0d0c02457ff2e9bf696b159af031dd5155f21c0f5549b0471a3
+c5dc8918b675cebcb23e29322b959abc05283a702e878de8ef25ea760f3c
+5c7b7b49d398283de2ed837fd59f7c22d62c58fe4448b1049fdebfc8787e
+67d7dafe9774979bb3802254da59bcc0219f98c219f84d995ca768b8b5d9
+d4a32525dfece003675ee4bd5d8dffc11025af2b468f9207b5b2b42349b9
+8232bac0759758c1f4a283405815bd7145c93fa08f3ed2826655053a3c25
+59073d8acd199dea2c5ba5f616a2e48548b4370ec73493ba07e197165dca
+774438b0766867819c1154d1959fe6e01e6312e0ab91fc2e2bd240fc8652
+a2d456a1de7f34ef372a53794d4c4e050bf3ca5b7bd2f1b8de93b4c80024
+85cb219ad2d029739fd3c81cc6e78edf387235761a57143eede5cc887f28
+2fecd261f6a25d0a7e154ecdf5dc38e426811be86aaa458577e5e0c5f0f7
+5aafa9c41e5d1dc9d91ecd79b514f8cdf7a5f1a189470d35fdf4f9b87888
+79ccbd91b427822ed658389e981e0ee5f7fb87692a3e3e931df8a1d1573e
+3b0166204240b7080089a09ef7487c9aee2d665f5a82f94c877fb5b0dc53
+1cebf1e71c6592cea2401e4b5122e5091df03d203df979b9a6efba12e2f6
+b422fdf15d49ac0914d372d21e871de65cbecd105fd4a3e4714b9cca5c68
+03fa39dbb015ea8a88be7913502e562e5b170b87bfc8572dc9df49ad6369
+4311ef1334444bdf0b4ca3245271c1f7a4d7faf1703e3aa0e1ea8d5c6e82
+1b28707ee0c9b4f22f23796fe87356c58ae2cadc191f4c58e1fb58da03b4
+5a25ac95dbae13a293474217bdb214742b9d9d6af35f70fed2891942eace
+3e625e55ffb820543fbb250a062d3d395bc0f219ecfe0d76686ac148bc41
+476a887bc494ddbd396be200fd3e03cfa12ec9af6b934a283c42aa05589a
+a6b4a8d16946bb51f50419cabeceaec5aef9085c9989289e9b46bafb6fb2
+782d84de2b068f91a9744aab237ceb1ba513e57e4c307108e993c972a3e0
+a898d5a8d27833155031fdb98863c3be7fef3004cbaa5cb60a1f2e3eb4d7
+290ff5fafa088b1ceccb6cf51a58daad998f08396cdfd68f5abc9c1ccb8f
+6514107773c69c26873e889d1f79d10e866910e4684186fcd71c965adf62
+39ba3418b313a27ad632300969b6f284519366ed85e7cd968d64823f8c59
+b5911a72d0a20eb72b603a61e36f52f256ffcdf706b4560b4dfa5d918fbc
+530d83a4b3c01bdd3cb4572e24242d141bf9e77536693a0407d002e09cda
+5b195bf1ccf430ae9824c07928a050d0b460f2704be8f9e647a4884c4567
+0a81eacf7cc038643eb0ff18a376ff6f32b6fe4f197273327fbbdec6443a
+299cad4b26f7778a99f65a11bde047153e764039edb251936aa43dee50dd
+fdf8856519056aafc4c5ae6f2051af0579a9acd41d00775d7dbe70022cc2
+63dca5e0a25b9c7c4f5c418587666b2fe24816b1e0ec92f9074f1403bb83
+afc3f1d52ca79c387bdef864366e34c90be52f7aa09935373a07e4e02622
+4e76f9ec3cb9e7ede50defda48248d61f3cec880a3b8843306375d9711e5
+8645f3625bdb8e87052da67f9794ef4af8db0bcfe00677c3a26907dc651b
+c838c40ec39e2b5a5dc0dbd345944a6c32226089d63c52490fa10b215ae7
+03cfb663eb8a47793b84ce7364da1c4e7fce32dfef09490121222774915b
+a59c78c2275f829d15cf4d8686b095c38c731b83d48738c25f40b8add487
+c350a2ebe846c3916ae384cb1050f9f5dfe09fcbd9129c6270fd86d55a45
+9618fdfa4f907e6b4746196bb717865ab378414029017551161a52e9d24b
+e4f7eed553a927933d4abc8f25df607779a717909cb4d810de8f57625819
+00e224e4b91598149ba471cf8068abe8744356b261600bfcc57fb8be4503
+6cf6571d9b2a95304933bd4f17215f8ef53f8e081af61fa7f9583c34eb56
+55cb0ecb82246959f09091f36989ebdd646bedca614b9a61ab7696b3ff18
+1058a150fa6ec1be2ebc7f64357a3ff2a2b0491d2f4e0b970de5b7788b46
+7ca678039b5ef55c88a384578d427fd2cb16c87b0bf0a3d37ce8ed43e0f0
+49af2436344d5f47c948c632c94a2875092825616c64c5d262fe5b24916f
+fee982a69a6ccf888bd01d62ea591eec51f4b7ddfaffbeea93fe08d736c2
+0129e345d06b10246a5f57151c198d407730713f32299638efbdc01367e2
+3eb59aad42a83ab41b432db462652e29813740f4680a5d4bd47b18328fae
+6bdf4200cfa4ce3773809b45e8887c9b2e4236989f6c48d64f5986f563d9
+a7538a8716082f81936aebd0461e6f4bd470436d8b7656f0fdf89108e6dd
+02abdef907731d458d690bc608ea9ced09eb1e6e64c0790c7a2378201ce9
+97ffe0317679ee1d4ee9f91157449323e53b4ada8096cd628b5861bf7945
+43a98f2fa2ab54ff0f25a13dad43daf9394329b95aa53ca32749fecb0b2b
+c035dd1ebd53ff9fb5ad8bce06cd89e5568091c1cc314cfb1d9821d7f9ac
+7c55f55e0a16e39a87d43148201b928f3c42b110fc056189def183745f3b
+637441de8bd4c3c7ef12f4258e306b2877adaec63441010750db4e6269a4
+c78a0ac01bb3603c386651fe814031cb5d8c1f149eeaff652a53e57bbd4c
+8c0ce36a84a319a53bc1e5fd3f1ed1ee72f4c1a9bf264b594062fcafb22c
+c1fde3f2e3d3c17dd3f7fe0e15ebd812d550227c06d01127385374a11438
+abd50048e17255fcd2bb85122a6fb9b7da9d5e9de8a747fae0da45a1fcef
+e92b9e70a5b2cac668d4d07527a5c1403267d823048be671f725cfc7474b
+44fc5aaa348420b2d7c23c6ca066666fd6f2208e329878d90cef1c2e77ed
+22d3bebb9d547810b189f08920a27e7107f208591a84d463ce2576c70c3d
+fe6643e4ea93f4e1daeb41d46f0e2f56fc10c69ad5034fc9859d31cf27a3
+a1ee256c93111f81c11acf1fc0ce20b90bac9aa327a5c85a7985b951519f
+d4b03c40be637162af41b2fda68f0d1e9b7602fe2659d3d75955c579ac51
+df6a552eb9581ac3f712f083f19b52a6c4f560f36c59ceeb0c996aaf1728
+a2aa45dcad79bd7b23ab388d5b0b64a2b95154b6259b730b0f4a72c8c7f7
+cc93c7d64d9d8810d1f63ff8abd4db89824e2d264fdee916c41e299211db
+1a53256e1db5cdd04862f034d9404b73183a99d3d13d642a663f129b6d16
+7095beb4eaefd03df2ff2f0b6b594c1ee90fdb203da89facee23f1ba3901
+fecc75fe1811bd701259343011262b6a0a9707aaa6316bc3c17f787bb80a
+c8da5aac942d90f80c5a3bb59e47ec767244aa95c63e50bf809998957936
+d3bf6abc24b0a397258f9eb4dc8f65692cb023d9091fb180c69498cd0c08
+bbebadc84a7e0016e8f8bea325d924eb0df82e75d2cc2ccbf039b1193436
+3d4332c5fbc5ec556be85ee4e707cc2753ccc43d2ed50558e51a104221c9
+323cdcb0199b7b83454de3fdc810d0f362c0299f5dd981b31d8e3dda284f
+ef9dc8f9c8de138d3065437a7fe8c30572ad06d62e8527ad37ae39aab0b2
+25f76a25f6c6505241ed73ba494cf923e919f688ddebf193e188f8c4c154
+f21631080763b4d091e8ad1d2fd6649e0cd9360e8d1a67a5b5fafc67547c
+a31c95a5ea8d4eb5d68b9f6d6532db9b545847359558542a2ae58c09f3bd
+2918efbe1699e9c8f2c2a11ea4d224c726d2acd4a8d8abaedc6588cf2ae5
+66528b94f55b823a2a1f7be19000f3e7579d094e047075df18c8c8687602
+95533b26eb3ed90635b129c17aca679c3e88b06998ce5a7a2544b700229f
+5a6a504bd3e45b276471959c8a3f81917a53428739b5ef9e3d463b3ba731
+8448e2a3e79520d2d245a2a72f31ff7070b6e4624e3a5e216bd103640c8d
+f387e49d732529c611f8b971073f17ebd2f6eb18f9b74a67e1997926df17
+8d4c9eded435b9682f1a279c81bb9f60dafe125845a2ff3b02979e5481c7
+8a45c479befb9fef3ce2ba9bc46c77b50b03e48da6d17b76f06f3ad11837
+1adc69e178c52b5fb4b261c9311874ed07dd6d5b3226a005fdd7a6d53848
+09e7063f036cdea41619122635e835d2d74cbb6aa9b38caa4d819c26e951
+15fe0dbab4198fc5838f2c91b7a87b07d734c6d4f4f83444c1e90aa9bfc9
+08a2bac4b3def9157afca5248f2da31ca87bd363ac25e9e77f741d4b2c6e
+02f04987a6f49d30e9038cefc41ba172dd675aed8b392164411144e5b738
+f3210b0e66b17a13cb9631c33d44484e792a7c082dd0a5382f34c5637653
+261b1eb6d2035b08b4d91fa9ab770caf40a103629511f7b43f2743d7e583
+433decfb19c21fd4fd0afcc22a4119e77c87bfe6fe50068b22479015be5a
+9f06beab4d37412e062a45e0cbcd7bb39fee747e96306f79fc4f2e8942df
+5d9da0e55aaccda547da19d30b8404fa121298b44c9cce198c708c69a8d6
+bf17591c5c50d3fc5be6961f7aba8f366dae957a1c3730da4a5b4f035a92
+74675ee3bbf0ca8ce9d8349f50cabb1c3ea4948abe6f9f143592f1ea9540
+4e6909a909168e3279a957ae1924245c356331a75e7008bee92beaa304ba
+40b7c3f48f74d9018b3247df50ebd7ce541da48eccb1b0be51a455c3c13c
+279d4d8676078c3ebe4308748d52c9b041d3e7244c745b1f2f742d010a9e
+60695f3ec4fdc1050ac082b905d6a57e8f407a3b472f731011a5798965b7
+b1a307e252fe02c8f79ceeddeb6e165f1a94d7fff18ddbdf79477f14e9e9
+3981abd200fe7771b29d1d2d120ee79d28b9543818527039ac74085eaff2
+41b56d08220c958b5d9c87c0c04a14d52afd475b542d391bc54ff33def8d
+9484aff6873beed32dda4b371112b523b6ce22b40d1b416b64c9370f1cdf
+2c548f4ccbe9e12e21c36cc3ea52da232dcfb65f66b22b5e2ec04852510d
+5e264ee939bb67aec4764b87062aeb7f680b40bcee04ad45c7519eb3b619
+9c9e0e332661463647f2fb7edf303efef84891cebcf0fac5f723a9d0476c
+3f8c092604c87fc69c7a90f4d64ae45a478ee8ba2df50fb93f55a3546123
+f0b0e2c1c40c98eaae9f0f26b8f80ffe6e6b94b7e27d2884d58b8a119662
+2df6be608c5569d7864bb756df2edd184b90812b44ed4a32d001c31383a4
+0aeee9743651f795084615c48e402dbc01c818d477eac0347795cb2792e9
+c11e8fd4a02e194eed1c919d4598fec003b6d9a8a0bc7d456047a1c05794
+53fc1d7cb2d158d466939a23d7a7b8abed7e2777ec7487973e73f2266d9c
+250ce30729e3c5223ad93b9ae8443b35711e446a3dc660123ed45ce1942a
+1a2ad0610467e081ce2c8b92a6c82f0b17b5d2429e99f1a6268072c6b5aa
+aa6eb6283a872c54d3694cd825eb2926e57dbbc7c1663075e687a144e4d6
+1c225781d80fcae1497b442342b4a3f1cd6bdb50e31791cc3928c30835fe
+f845b6be5e2d7e3f2f5f085aa3faeb45cad0d76bcbb1ed859a9cebb9f745
+7036f0bc3f195cb1a98c9c8648f6583cdbb23894bc719d68c2dbd8003b10
+d08c8caa40bce784d7bfb4eec9ea5359ac056e57b8b0f2ebcb1f4ce40c87
+fc7861180133e0cb6ce2fc4fe690756d327a2b5ae063e3021c0c0bd420d0
+56f0b941e6b36088a55ba11d0c35fd0132d5f48e5d9673572347171b4328
+d4807b972831c0d74cffa5638c145b89c989e6ec942148207d6db8225758
+5958034d9f9d4221c7c9f7013790dbd130f277e0bc88bb179dd09e270623
+79ed06f25eea8b7fb33c35861a0034776e3813d2e9e5c10e227cc569ab36
+cb2d9df2e7b7b44758f9dc4ffad7a24ac7e9f47aa850c221048c3cb35a37
+ce8ea75632ae65fe3212175146fecd6334ae3d3c5f492f067f795e1e8ff3
+86ba198cb74f0bb4dc0000da383bc4cc3f070de17721431988d69c8b1a5a
+fdccc83c22e16a87e01c6d3e79dc7afa3db0371b0866efb8b6f88900472a
+fef1c4a878243c52d4e02e82658979731c841c489a6b97e271c4c93800ec
+7d91f93eb9b9c659a554e1fce42a5ec65ac39190ef4b66deaf6fc0569a00
+0a9e1495f42f706fbea4d32eb7ef11a6489102596a65cf899c2f322f5679
+c6d123469192a9bf1a7f1f2c81c554adb97bd19adb746a4f81a4d5559e60
+ab94c483dbabf6ce2f28cdb412d50ff3fcfa3b3daaacc6a83cfed910ccb3
+b8d2c19590aff4d753034a6ce7f4156896a13808e0dfeac547e69d3c8866
+91728e4a35acd575b40d721e8fcc5385a2eb28d708101dc50811529528f5
+cb0c009ba7e3c88468e37768fb0d83895ab54db2dd5426562af9d8af304b
+f6eda54e9c92643df926f5c3578269750120302a37cb140a18ba56ba0110
+8d4acace8feae640a6c6958ef156b588adb0ea5f3b0f37bba12b7bcb221c
+811415387b024b7076fa4403a3ad6ebb5d9c26efebdb7ade7c60b444ab9f
+90ea493b658b7767ae2be649bdbb3fe85f460f1ed137c61bd95f7cd3d8b0
+15ce45138538930ab62aa0e54b4ce1a5ec5fec0a2b28b345b67089a4e4ae
+14d2e1f5a9c8848da688ca298f93860649ec3aafef3e820d86988c8e3e5a
+4d4bb937791827994aa3e81d0bb3ee115ec36d5fb9a392d09e79af514d11
+c7b3a03c9f9c13355ce79e119a19177ffdca34704d38118a8976d1ee5aa0
+2d14feb1414419f5e85244adc5c0a765a522eef36170064bb19fee3b5f7b
+441e4db967dae0bac2c48fc6a836e0ef5a69f073bee1699f55e9c757ebd6
+fd8b514e2b49d6333815b7dbd1e0694695fca3d21320a0c4b852d9706dad
+d8369a95fdd917328be93dd33818954dbd2c212d2ca81560ed5bc284eb04
+7a5f389e24e43f4fa8c97fecf46589fa7341076555cf55b1c21b28e0c1cb
+b00ab8b6f67472f27bc0d11148f407824b0159b5188d4bb7386fbdbf1c0f
+af34721b7bcb5c0fcb7c4010dcb6a1284e9d78839e3c2111a05d29ab7997
+073b590a81c6168020f1d48951bc7d8476d5ba593f4f23cac1f9bb0e091e
+84b4e99e5c584d1370dd12dee8df16af8bc6b7b23e2feabdb7f32779af8e
+2b5094a6e9b7a7225f24c43a8e5d2b977e1e19e633c26771e23017ed233d
+bb02c64f8cf03992c6484528d0c8464b46f24f9e8380f385d5d01b8893c6
+7fc103498983cf939432aa380ca576d09030cd52fd99bdc3be16c7204cdc
+3365bf76294a83a1fc14a236f5fe5321904e779b13232a76f8fe521f4255
+62678436359c2461bea5ab27209541f557ae2aa60009c9ca0a9fc7898c14
+306ce35a50017badefdecbbf94ee2905220706dc806409ef87db1d73eab0
+698ad2db72cdcdb293e7fb13c94d9fc87e74502e6927a212f0d7d2f2d194
+64f7a66ac07872e18cb1dde8f11835dcbc5c4ef039333fffc0fc1456daad
+e7dae3ec2ee0d3415b0cabb69fc5006f4d14a4ee1a5ca99ad4d5e629c0dd
+1e0f097b5b93de2dd001a8c418234c9c45e8c13d1ae04e9466dab8cf1ecb
+88a4e059c111a6468d2dabb90da79c7c79e94db28f6968b1a632f8c57d9e
+565ff91c6916026ffac0661856b9fb8de9c81661816221b1fc159cfef175
+1e7e403f5f2ce32529dd540792fc17a12a3dcd7c50d38eeaadbd10adbf5d
+8a82442aa900ce6150eb7a4639dd9fb6e385b2fd093493dccd9014b23eb1
+72e21aa89643a6cad1093343d85d81261972de0acb16a4c6b5f0be4c978b
+fa12d3caf0134f9ea49f6e9687c8f99a456745ea252f0ba9968c7f9586e3
+dd841aa92dc7705bdd682dae41518a09df0e209f321d7fa3417202f4ba76
+a984da3addbc58136885362f02f0a24ebc439b3dbbdacffd8498ebd29f88
+f016b1feabc10785438eac860b554525f3266097a675299aa0967bd3b7a0
+eeee3fc578d1be99d3533bd91571aed904bfc9da1a1451fdc5406e1cd614
+e0c7fbc733563cd6ce6cc31e9237ca153f1f0411114361d731636bcf9855
+5abf12848ad109371a42b63675a4130b81e97c2a2ee2bb5d8fae26401560
+01af0f55d9d5df8ff23c8aefe14f120000f14149a36e5c94cd9081dec277
+c2c34870d05011f99d48b0875a5ff542f067f7e9880109f586bcf2b50522
+a1f23ece44349e539e70f84e207dc9bec7cdf856a046f1a03226aa41f541
+719ad1af88ff211e57dd0c1275dd0b7b47440da089b98c6ee92a7d94700b
+83cebe19eaedd8a615f6587587ba8bba3ce3aa5e8eafb1fb0f486be3609b
+169efb178a4292f4c0378afe5d24eed1caab514ddc66c696d8e37f294a65
+79131ddf5488e9436609acd750c3db0a940c84fe022b22adc2676f62e91e
+8f891225f891fba537679b24547bbbf35f04915d20b11739f620d18b5b21
+6921d222f15044368569aa302980b9225bb839f494588481b94b0c724352
+b2df600a22b062561d86cb8f81514fbdaa4f8a043a0265f992fab71fc912
+4a45b8475e1ef3df6b6de35cf329777d45f08325e8505ec0d979f542807a
+e77e57e453525f23bc59a50740371efa98678aee6c425374aeb745b99ddb
+5d8d908fdb551fbc0db15832107bbecc4e11a1a8dec69358a574a2ed46cc
+31d564549eff23102d92bfdcbb2bb985f78f36033e34f59c0ebafa3bdd71
+338736464cefdba9139833995eda4207bfd4a9867d32e867fbeb7de60d13
+2803ef9347cb17bd91315484ef6570892297dd8b7d966103339535e28a00
+cb1eeca4a9775f60a9f5fc9bd8b06d78fe8e6318c31da2e847e3f9ca587c
+b01ae2ba0a2ebde308314413f4f230a758184ed60d4f71f6cec22a93a01b
+6c54e0449a3860fca8954a347b7588329a80974ecbecda1070fbc0556663
+75229f13dd995e99265df870bc8b8cc6347fadbc1a6af64599271a475b91
+23493d46bec41289beeb67eb97a8ded7a9c9730d37c65164cfbdc22e5ca5
+89d2e7954c7136ef4e084c43a6c7f361a3e96989239bddb9a593cc2a80ba
+16de9ee90e95cd39393c212ab22eecb677fd36d34deb46c4ad0d21bf7e6d
+7cbd0c8083842fcd87b18fea7cecf939987e99ba34c214e44dd84c176c9c
+c5a4cea76d380cb316bb4ef9de73d73b4afd4adb54451591def86621d138
+d5a0a29441502bf6c2ade671cec3cb5cab903a657eb2d70c943f976c110e
+46c5d9d29bc00a875f2738e5d22496a43e096e009c5d3cb724b4cabb3283
+8dbe527f83b18cb457e57b092c302ee557fd4f00db9c56e66c9fdf4ec9ff
+aab85f60d02ba79694faba476a199a0331c30a78a92e10417ba236e23364
+8174c826331dc1bab87c5f95027846130c6a2b4027930ebf9a97ba1b039d
+386fc51c302648e25980212f6a582cde2778c677a01fbfb3c5d1b8a374ad
+af6adbf7dc94075f25ed66d440b3922c5f255fb23fd8f6e21ea65b1d93bb
+225684b50f11310e242b087575973345b229ba62c1e2c35bdaec04d10148
+f5b2f3bcf7399bdfdf1f3f79119714aea697245bc647316ea157484ecb95
+1be367234fd02e8b1f091aac3d29bf282dff4011bc0cba8e55234d943db3
+017cc7a766720bbc29b2d097a956c0f1067177f012d42adcb473cde8d1ba
+35b4030757fa1d8211989df3bd22ce5d501c21ef8708fb3449df47d88650
+9ff7b59b76c0dbae443f336fee2d615d7eed1c284f14335bc8a26bf4621e
+10de9611fb2f1dbd52e4b7565d8c65b54ea36d508bcf0c578a49a2665227
+cde1f9768efe847f9d94f1bbb7db83701c2321985c7283d47b2e40b27a26
+8428aaefe75f6b2f8764a8494e5827573758cb9ca46fa93208836bccc8b5
+564a69f5ad882052af1c1417c3fa7f580569528682c77080f3688b65e7fc
+24d2a3aeb61574b4a3215927281544ddd7a6ee0a3e9388f8f631ce725172
+4df70726e5912ddccc8c652dd6c9608f8462303d867f589de0f2f71711b3
+5142ee6ef93b64d6326c4dd7dc83278e057100ee772082e6ba368ed91a55
+53ecfe2293a481e42f83bc8f9148c70eace91f7b7d9cb8a72415bdb3af66
+f68ea733a17abe9db0053bf148629132969589f38d30eabfa96a01fac726
+50b5a6ff3935670198a1ea33810a9b11e330eb8b451f24f93544263436f6
+69ab5a90a53b16cceeac36b1445574efa7e802de73522be725e68704822c
+b7d3912717333367895bbfbe06966a5cc653aab5e9b3596702086bf00100
+85b900711932a95acf15ca4dc45a754ea334e9eb84d6fc8e3fc4f897456b
+ed64bb93b593549ff0d5352275d8e417172a6664c5e0eced1019494a7ed4
+9ab0b965bec1a82e5873766bb38d7d856049cce2fca65aaf61e961b60634
+e2a69ef059754c9d8163d87f928c222772d070d83fec6fa5ac734af65e40
+bfde521f7d9cb1650fdf64754bff21ea3ff0af7611a93d525ec9b28c51af
+ecb04e7fc8323dd6c9b0d8539a34fc3cd8ceb7958e8ebbfed4313c77ed46
+9c199552a9ff70ba5423b03b6148d4eaae17b71c5b39dc436ac53d6ba8a7
+ad81aa8b02335a8b2b11e9f4fa913159a725b8ab60f52f1a2ea50eaf4d56
+656e615bf382cc68a690bf83dff24fe986570adc0290ed1a37c1c2ad469c
+e789e0ea0bb5ce01020100e729721af3b5badd33a2daa6c33eb8f9064f52
+92f715f820b4bbfdd56f76d42e7a1a068c1cbdce4640082f6e7d582d1939
+990ce6ee8d270015a2c461798b37dcb5798ee9f7512168b76d26c28be4a4
+9a1bf96c89d235f21a1db6a96e5da474d0b19b808d13d7a11bf39ea86474
+99c410ed9894a1adf33d41b6fc2e614d8087f4c84e437b136f3cb32db839
+3c49177a0675a0c9e7eecef448a97afdbe840fa01fc7e5f2e8fecedc1884
+84c312e8635cd79195475ddbfdd4d38d5a0246de2c7f21608f8d2c0da137
+1d302e941572e5792a3cf4e51a33228b93a814d03fd4fc223c314cf3714b
+b3a34bd4f7ed6348577feed9deb082c4049e57b5d3cdb7f26629e9f3ba36
+893e09e3c7463d02a22d7056be76b87763260e46e48bb832b7ee13f8dc05
+37ec8e81e9bdfead8c27ebdf1ad706933efd11131e12814f236ebb01be85
+b7f1b2d627413b324918d247604f56ec128909873fec3857028bef76a349
+4364c2a7002d104d486236c30b48e2b75d851c34ea50ba7ffeb4e1919089
+8ae21768c157c0cac628a2181a32796fbc1a7271d2473cd88e5395ddbdb1
+fc3aa8df0f3d588637f19a8b833afdeb5f655a8838eecd684e2315b72c75
+ceefbcef94344ace8d6adbe355008ec72fe7ceeab01363a895f4e73f8676
+39be0a0be67333848816b05b419221be8f9066c362c23fe85b7f392930bf
+e4c12b9526ff2fdec38f23a159ed61a0718e7115c24597d849fa76369153
+54a40c965d4d72ec94da61a03766ab39aab684e134fd1407a5b1b19bfeba
+52aa0da5d99cbe5c82dbaa663711e6deba180e1d4a39c320516a4350d296
+bc19bf1be054859a0889c7e9727a021f3176fe620fb0c837e4141fece531
+a950c03d319e3255703220b7185bd20fe5dba673f8129ab211efcf36ee39
+4c7e00eb0876624bc840fa86e58b2f584754cb6bfdfd76810e300741ebe4
+544e5ac17413adeb21c62f66ca4f075c32381796ba709782de34a675b717
+a2c7f6d88104cb924fde5df775b4f0b68e0e2e5c2f788bbdeaf06d8e1fc2
+105ccbbd5827c0b03fd6cd64f0d073f3192d5f94839644e5ec6c5185badc
+f04112a65f49a8c83174a9ae958e76a2f5af469e8b76c833782c5ffb8bd7
+b1bbbb3ea0cb7c9786c3be2ade5e7afa8c8f20892659a59bc421e28845a1
+08e34ee17864042ef587a6d67decdfb3f510eb40d2229585347a0035670f
+cc76c2837a4e4d68304fe113c539b35c1f0234b5079b8e32934546982978
+c5e4df955a454ea263c3ca5d7101f31a318d82a3f9fcb5a8afd7a6520966
+3b0fc9da400b26f285ef46d0e1eaf8acb1f1cb805e3986d04bc585073fc6
+4895e4dae1ccb749bb439cb32ea91176d5c39c3650d10afb9c9884d5fb90
+183424cee67ef2175d01d2478d67511ec9f54f88763c152697b06d948bed
+49240096eee3d06ab4575e8e8b2cb8263b5bcf4fa1608720f52b67530983
+3071879df52c3ec2871d20f398b5cac8f8a4d41d0f1d47584dd90dcdaea4
+a1cf160c4b3bf1aab890b5ceb6cb3488672aa68fbd938281dbc1d8bcfe92
+fbf514da5358443cb6e0147254e91b38ce6787b2bb0dedd2d38f5938737a
+977b5ea42892520c58f8fbb53c994b57382379e9490f0d6970b980e1bdf8
+cf9f4c3c5e0a18f66e86ee93ffe7fe546de50f41364bcb3721b637072571
+fa1779f1d672fad260c16d7f13cbdf3e4376e7ff56d2a710ac5ac35fcbdb
+ce2c9c17e523bbe6218617b13c1fa6679b308979ae7c61da6e68369324c6
+cbc7ddec364e5a86707266c0b459ee7b2c03fe584e529bffdce98c90a2f3
+d9305aa74d3ed8430dbf3a49fe2ecfd9c4bc9fefd22618fe9c8a973ad072
+ab6f713e4df02dcda7ac5359b2d652013e131b76b3ed6c75fd53ba58d862
+846264627f6b9e70d8800f6d9b32242b747a67bb2b45675840d34f852aa8
+062fa6b01e31ed24dae02f6cf788a17f7b9368175195db0072259cce0ffb
+2c1035c1d26e1777cca3d56a827c3242069e76d6dd69b653768614b9acff
+16567fea61508d51454bc02f6c60f755aef6afae3536bbfa1823f8e1a53c
+41124de983e51cec92aef4f99785d554488a51c20885346d1f761da79017
+940a0c557d93f1db6b3d00ffd61d08e96ff3afce5fedf545cc9f47a2b1bb
+26713431d6d1e47fd6bd6e3c668b0368241f0ebb5fa9c991df79890e52e8
+3a3675ee699b61baf869de91f67278f510061c6fe41de2d883f48cd0e068
+e2a652b244128d82e5cd52f35f210ddae3054691ed55a7d99088aae8fb04
+f525c2084ac09f5edf80a4efafe981f74c0de9d194320709b3464f3ff2c0
+f6aaea6d973d9c323f53de3d741f698fbf01036716bbd62957cb32cd81d3
+a2674560ffbc5bdc5c6e4f547e589ad0b1cfe14f5e17fed1c4a8abe4e67c
+cf8a49f32c4c6044f1431e1cc382e7758722a6d0df9ed23e51f8ad14d11d
+7b6428e27443715eba4e9c05d6f238378f9498aef0e7ee4fe6856622cc8e
+6ed141ee5f109e343cb6695c4be1e0f66601c27975983bf557c04acfc192
+27a1ad7e6c44c00529fc7edd7f886d24b7e029b9c395260088bbfb969721
+99a7b32796d27257de83a7402291c14fecdf7998c5c96b1edade0280f856
+8a8f5007852eed303969180b3329917973c2d32c080c9765b6bab0673bc7
+ecfdbbfbea980c26384339b7f1052591d91667d4fee413afc23de2d4b9da
+742f4269c6c939f5fc32a38040730a018155ad733f231e4d5b9d01c03a58
+eae7b5f590ccfaf25edc8552cfc8d95c60ebae1837d7a97ca137e9d4a4bd
+2cd34aefd68d64b3f4f62326ac429921d7fb3c235184fe0899690a0b775f
+1a566ec29d5830d323726526f7e7f5afdd71b77e07613ddc4fc63edf4905
+1aeb59e6337ac0a4b6dd872e776c9cd0ccb861305322d816732124f5978a
+86c186bf0a0f88e733ce38e4d7c1ba5378c5629b1efc97806059990ed42c
+5cd183bad7e94070e4058569da2e51831ffe0d080301aeab4350ba290318
+aec582c78d05dd92e5afb4424ea808629bc972e68f4ff2489c245593f075
+55ca6a2b25964794cf31cbd3ae5c229ab9b8c29806c01d116ebd0ff0f159
+ed2d3d7dfc73eab4910bff5b0b0b587cd9ea6e6fc45d63c09766224d8346
+1f0588140b258b1729f70bae7962189b1554483392988cf230af4077193e
+53330519394dd99ba1356d4730ab221dc6a66019bfae564893ddad7b177d
+add16add21d396cfa6c3dc818052e2f71149fd594a16de0c2ffdd366c99b
+486c55a6e991e4d22ccb15843f0c3363676af2f5b2d1b7ef66ccf2f12dc5
+0d63776bffb058d70a9c76dce96c754872d72c82a0c33f90d49c935402cd
+d26b6d743b1f43bed5d8b539424849c1495dae73044e885a7d0f307f1816
+df6244a6f2d97bfd4e200e93f69b08af39ea21e6e347a47ceebf803f73b9
+78adbfcf056789bb8e6e2563de87dd9a8c877157b934102dcedac54d487a
+1bb2694f0034093c48f10a17d32e2bdd0c723caf59addd1be373af8c9beb
+4415aa5af36310c31f24354a53c0b962573148bef91d994fe3f3d8450dd4
+d686725799f53c373a0a3e3c060c2e1a3e8005049f26d716e1f381b9f831
+25e4683264a07e2d8938f605978e2513dd2050b3d8a1012797cba8961632
+bed260916338a812ae751c7b657e086a0c7ddcd3bfddff3e48b847519257
+36d1310c4910fc114387f3ed7fe163f91895ebf55fcb425cef5729d99bd8
+f2c072e36c310523e75cd8e5de49c031c42634109d56e91a46c8c8e89fd9
+2012a00c33d0dec52597b5c6933291a7bdc5ceda95dcda5600f9ae1c8250
+54e7ee1067458ccb66610704c58e4a4fc0cb5fc933d0322a716b2cd430a3
+ad48dab3d4cbe9d23f2d092368cfc4e1f5495c133a92942ec62118d45c17
+723646e69407b4a89dcdfd2ab3ffc099a21d9d29741d68270629aa3a414f
+e58658dc9170c247b6e23f35c4bc5ff83009f462f2eef4dbac5fd158a658
+57f9b6dc1f5192dfb169dcb65621cab2f1b07bd22f4155a8e9e2b6388d43
+0fde5ec1c834d22ea035c52e1e34482eadc36b4cae902aae89a7284e62b3
+c84b608d6bd05f75bc31310b2dd3b2c08a00e0737f104f03a41989d5f6b9
+a2c38b22f1d1803ee5d7a4d8de44e4abd496a1de0c0e12c4bc96d0122846
+3f0ea9ce9509fee987139f3dd3f9d0df4313f555be85433718f6d05f197c
+41a9d9c7a8b0d274019682d49f58dd5f66b12a6520d9f226d1df1f1b65cd
+fa261f980ca25a92645b86b64606293f8bfde364c47d2af2c709bbe77a70
+a5712f2cc26f3d66f5be2c307a48e6f887f681d30121e32bbd87271b5dc4
+615d28c309f15ad263fb37424e56dda6e17b998b45be6c7fc6c28e3394a8
+764c9eb2df5c06626593b5c665d550d4600172791cd208ae9f37bc082b0b
+242b0a504b751b18f4d7495172b697ee217834a8a4fb7cc16d6f9e8bb400
+be8aeb0850960283dce725249fcc4de97d9886745ab6066c3e2f64dd8ab7
+9aa11667f11188d7965dc11eb760b772e282dbf13249f31986ac6898febf
+e23e3e8b8d2c33e00ea6fc493850ecb2e6d831d1efca3c2ec8ee2e394599
+091ed58bede97d7a43b6f739eb0f845eac1df6b1ebfe876009cc5d804b15
+ed4b56761b3ce1af59c07b49dc798a44532297ad73d5101ed47f36a3678f
+818297cc27f6aaa2aaccc9aa9b6f5459911d8c56cf499e390ae607f37904
+50b2b9c9be0f006eda0c715b5ca0481734cfb0597478e7602b0d2c1e4f78
+f03c68c17c70e4b42d7d2d3c95cf40f73488b3718e2cb05a549944d86944
+d78724e266c3319af89ae430e777e95f0d792b1c654306e421f3d63a26b2
+1e74b6e8b21b2e2b9dc596d013cda16d08e65e8f24a84b12b2badc653e6e
+1110de2e709c1c1bed13707b70a421b384f20ca7a9a9d20324dd383f28b2
+d3c7a9c53f5d4c6b7c378d26df11cf55238be1b24fa70dcc178dad3d3567
+0fe4919085eb1cd905971d76a368fdfcf9d2f0a23739851a3a6d2e02d65d
+54dee69ed5d81315d3ea5e356f94ef256dd267fd1e1a9edc9cd63e743f29
+9bcc4a4506233b8dd7652ca067f741603f93250c087d368f9e9cc4cc1a6d
+ed567487c05baa992b0056a77f630a72008e394615a9db24fe56a956650e
+c9de90a6c2259189440247970541ca198748928215c0e132a81aa13208d8
+63c1fe817f70ca573b54577d10b73100af8ea088208a44fb92aca314ae58
+79706180788c17bb1d0b81b6b95a1c4e0f9ea66f9b39bfe12444a6446691
+a7bdb03e0f03d9f07a10a7598f2166f108529f34cd90e601ffed3479abcf
+cbde8f051c348e48c61d95b00c59ea1287423f05666c3d36288844067e83
+e14f6b5210842c742b89f13acd126b9fc50abe2ca7d7ed513d43b6ac7f41
+eeda416bfffcc5c844ab2d23d4dc09b2d510504ce98d02e72020d9e669dd
+aa344c63a1b75632f912a1c0da3885da4af7e243e4a4c6493d6595bb6d56
+b0359106957259e59e336baaf35bd1cec5cde735272ebccae8d4904aebd2
+b32610c6fea2b69941d6542ecb44d71092a3cf067708a3d087ae99ff2967
+1ab7dd8758759b971a08ae1bad78270d2fbee37aa2dcb119d72f6c7b0c85
+09018a70d0b0be2c6830ef8e0b24b1ce1141ef873a4d7dcc501f808bfd94
+e4dc0f2915aa023076bcc8006490a43685ea25aafc187302ebde7fe1965a
+04a5a398985d29f08e085127b56b057334d88eb638a4dde64afd204974c3
+939536b1b66a54b4db81151853915718f70813f096cc1b0ea25e363b4926
+4c2ad17158a4489f91453fbedbde15d7b74d7f98e81df23251785d58295b
+a297f295aa6248a912cdd4f1111e6b628eecbb5139709e76ea4ab743cec8
+26621d08e6bc64691cc90b3c3c1778931a28d3d5b1e20e96c643316613fc
+487c9b604c43463fa4533bca1236286e6f5a6eeb2f1d9c34bdde4595495a
+365f88055d9268541cf1654acf478d384a5496a8772ea1402751a093582a
+6625a0a44816b5fdbe166835d598644296249b92cc90aa3fd6445c9a19bf
+27f59cb0616c7306070f33c7df4e1de64ac8c5bb2ffac1ef2b1b30e5a027
+5e6004cf64bbe2c6710edcfc3aa4add60106334708862ffa6652825bc848
+42736e47ae6917180365c75b27505eed3c6108e9898a780e20c3f606a860
+229ac46d0471aca0187d6d539a1b8820f620f72b41ad1d3bf3834bf48ca2
+afea8bf535af74c4562deadcb63d2f5c7585722b77c989342d190ff926c8
+a5263b4f25286f99cf6fc62ee6e2ad61c82b29d82468ac10fd27764278e5
+558ce8b41ba111cb2f040914451a480c93084237cac8f66bb7c6689f340b
+8abf0150e06d5b1177278a4c08742fe22f42c28680f190900344adfa486d
+59718c25d37275bce4df981aac35d2c7e85c72a0188b8953cfa516fd545a
+ee0bf4b8ba301cfde2144241fbdf3d204e3d2823301572e23f204c97305a
+82401660e12926ee7ba6ea1a81ff5c007933afc73266fac4c134ed818a48
+e7da01c71a46335c845f9da5e960b25339d551582b375814148d94cfb781
+fc56093827b78578a73d4ff67b6b87f40cfa5e3f4325d9108cdb64bd0642
+7b88c84105187316fa2990b4e3e8edb6c78abf164f4a9717d523794b2fe7
+72a04dabbe688cca977090979b5f47ceb90a1dbc167d305eab231c9f4260
+c4ad10889cb785169902fc0bed78da15b8417453bb65856ea0bea5245ba0
+573f623d215f6c0cf801851c305b355d26b52b0b343645fe25c78a352684
+1eda480919a1bbe5f56fc10abeaa3e1fcca7c43ee560f067f1aa2afd642f
+769d1ace8e2aaaf38850f0d757cd808c921d716e96fbc07da7860dfa70ce
+ae2888c0ed3cbf9586443532b68daed9a926655c157a416c383a53d8f283
+2a4e67468112a09adc837ed8ec95f70852921f50d4417239fc42ee3624ca
+97f682745cc5e76cc7c67bd99f2180f8c0b7fb49539c8cc474c25c0dde49
+1671ff329e51bcfa779346d4686835a3ad6633fcb5e0f67e0ca9ced8f215
+bef4d240453eb2edd6adb22278aa5b985fa140c9834d38753df2014f8c0e
+e6dad19e8fc54c03c1f6cb0f858986691d99592562cad95fa0a5b2abe4a8
+b54b457d42e8c33a2d1951c0419a72fb94fda78ecd92bd2a1416459e9dec
+a9469f35e4c47db531726dee8f203d7042edb32f025df3d582547bb1d45f
+7a5b70d317df4ebb16e36b0d798e0932fd2a85b04fd67143e4b287a50416
+2c1f5a037ccd780088c5476385af8168e12d97d44b0630621759173c8f1e
+3006b5b1c6d7138b7eefc3cc5f54e24b2c3ca7b41aacfd25e554880aaf40
+6ea4c3c6e21d3b550b040fb1952598a7e8e6488fe38288b2aeb6c4718338
+598a2bfe4d2b9d14c65732da304c16ff3e1f8f03046ef095b65fd609da87
+ec24a69278bfe65c905cd0329f6a486b8525b7eea4f7ae56c2633cd83543
+269e8acd6d71f500d82fdfbde7f7f7b1aee67328549232e26ca55085b6e8
+4d9e2e7f74068f93a90c4654f2f396e57c5f76f7e61cbbe523dbfba6e766
+38bba3064da025a79e3a294fe7f1cc28a3b4c57dd6fdc48e541a85534b25
+e1bc11b4f78019457239eaefd4be9007d205f1d985f389db22400b279c10
+948551a6b4a17fbda0ffc9428b18b43dc76efb15fc2182216f1b60b4e344
+a03ad6c00f141ef99f89f24c819c3e32877a927d84c2d006940f39ca8b71
+e5951673ea9bfd1749923219de38929ecaa9ce43b06cfa7da1bbedfda56c
+61ff6c24f40e59b13870d5fdeb82d981154fae5d6d5152de69339359461a
+41a9713b6bbe47e868c933cd74c75db71d13bae4dec85e02faa14ead6c0a
+253b16c79514657b15e68ccff9ee6aa385cff9e2c53d9ae40f85c793e4e8
+ff50b2b7420f4fe69807bc5f37c3e300e6b3c3549d1d3246a2e70f091054
+1135bdf805e0a698e236b6496702d061241687b7b8d1a0e517df0476da09
+d89667a7ab375fd2672dcbab8124e511502ddbd08ba04d941df1cebdccf7
+ed48405cbcc33774a68c5212fc6f132641ff413c984f8b43bdfd7b1a2a34
+35f15af07ef4970d3e4a0bb947c181e9ca27cc14a35bd1bd096875b45873
+8ca244f88c28728b74e25cb8c4fc1095a56ca75e4569ad3082ef194add11
+350db3b74b96761d4538596ff7243b1e1b724716a144106e080d42036444
+fd472998460ce9abbd05b42af9389ac452bdbba3a13a96890025789f16b9
+d92251fd3b3beb2c61eddb370a20456e3bfe5f4039e2557c451c524f8087
+015baf3ff05f51869fb97512968bdb2b49589c1c7af1e085250a47657465
+f480b7023e24c76731ac0eab6704123d77977d3a2c4c56b691346ebe589c
+619c04515d34f81fc6a17527d5d8319013c5d4ff27cc3925e24c99231ac7
+fb9eaf0bba482d3b75807ac85d03cd09de5d9ae0b07b7a813f0449786500
+0ae8a7e00080300f0ab8c399057eddba273dd2e1b2a0dcefad3b332e6d4a
+c1ffad846167dfd70e0346daf84af292d4f424256ed5ac4e104f80697050
+d50844a708eac9e7f7784fd01646f3bd0c595ca51ee6bd607d254e78addc
+5e15c3b6ac4940ec865a5c23105b6be09ea09f2c05d6d76960a843b81ee4
+33977faac3cbda85cdd2f4db7c28293a77825635992af8f3b38b4480d9a1
+39b1662345a8abe1634a77496c3f57597d2985e9e54717ab2e99ca357894
+41bcddede9a9e2106b401d9684adbefe40d607f075c179e9cc03e59e6543
+0db70b441d43df03f2aa6ff06f224b6e455b01c64fb89eec9103e48453a9
+749b4d602808c7e408a8903091d85e06aaf635d0d529c3cdd1b8479ac0f4
+208c284bb678a547f2bd77bb17c86d4560434f7ad1937760a6aa55b614cf
+a9ff8c9c96561ae6c8f2121c4e20237428bc51df2099b6c49e3efa18e6d4
+39e6e6981e746ebb1dc461259d8ea0f8099c47cca27b2d982b72c9a07cf2
+1b3c05d6e26e6e286e348b8944078e24809f9c5f3d014b4cba02533f5621
+bfba1f0edb776c634746703c9f73ba89b1960a496420c68f54e5b901a6d7
+33d7acc79f275fffb253f389aa480084468bb34da1e797e43b7f6e8caf5e
+8c93069a3a2730e57ec39b677bb73e3f07c2055599f7062e53b37a5f0099
+907d2ed87ff7a82c95fbaeb888033bdfd67ba3a6031a4cdc56cb1e4cf5b0
+6b46e16d988beccefacb9e1c037023d7bf5ccf5d65aa66a17ab361be7981
+f132a578f3abfb97960a6034f052d9d5afdc0679782ec90f240f943a5f9a
+3d969ed7399254ff67d89df668f7c56fcea1ffdcf20481474ac8495d3af4
+b6d7ee093e369c057f0b70858220693b398acf8e8143558132e4391405e3
+0a73937c53402e459f4aa3539cf7a99a3f51c0307d045df8b77757e92ea2
+f51bf0bb4f77d3904dd355665870c2b59f1ed7f84fc71fdd7f0b6c5d3182
+db77827ca6a2060d2b8c83c4ea4a432ef43a4d0a952cc6cbbe52a9f0cd66
+1a538973de41ffe9c5cf55f2506b9efee51fbae5e63bdcf5528499a47c03
+1163c88d3022606784de2f46a9c9235aee3d4f71d4959b0cfdc5b7e78c8c
+0a8f9dc99440c2263dbacb343c5c648577f5610b50eab1cf7fd02419ef39
+41c7ca0b0e64ebad4b2cb05a0793dbc38f1946d44767bd287f5e9779c611
+ca0daaa1e7393dbe0683c8d3455cdfebc0e64b54b737e298dda605227c0c
+4bba87aa3ec7fa6ebaec39e6ef2537d5974391d31739d9fc42983d81aee4
+4711c823f35f8e2321ac74943871739d2dbe9748fe68592263e7713f27e0
+d49b9b5cb7a4e55de54e6b800d15856450ffd3ae5f287b12ae4f438b20ae
+9e27e6caa00f3eaeadbe08432684fdf9931e925544a680182602a3c1997d
+e5d0630bd5a010535e66e1c123013d23966b3545c7431c39b97295bfa409
+9d14461004c42c85095eeacb9b47c593bc6db863533a8619bae09095de8e
+ca432d4ddd49aa600d277e75dc3f5c6631e2a05382cb007825fadb77438d
+cfa78e252d79b6a196d5164c2feb85d75eca25ff80b1d97fe10e87960ca0
+fc47c41d3a213bf141b48bc3aaa93fa86245064668394665bfd52d12c3be
+4ce39efd8111754398a944c3fd1afa98ec337baaaf899d35e804cf416ad7
+fe45fff13fc6354007501043f98fe8428de8013901ba6a28711a2ca85a27
+0bb135b72f1d5026e8217581860729e94f2f1878a0e96c59e9f62714fb5f
+8f25003dfc7347e990078a9a331cb3a6a535bc61866f02513deb982c4a13
+adbfbac3ff70a7335f40d5489e48e5ededef16191973d932479c62183b0e
+25ee8c4f76d4f1ae45daea4a12aedd9ef81d248e8d19f8c8a5becdd1ea1e
+98783eb7a38149170851b1942c96c53de06def80913bfc04e539ec67c110
+498d15b78268853e5c72f485f8a27b768569e54241f6115875e2973292cf
+48ff91d45ebed627ae9f0766d22201b20afdd40e5b17cf337f2999e0bd15
+b86e46eb3c18fc12b7dcadcf9dd50c6c7e3f37e615a892db3f57e250a072
+a49f7277dd6a2c8042698233d35a699b17eca5dbda6d250ed4a16fcc893b
+f0dc2e33fb1ebd7dedea3c1c39603c8b7e1a5a833a8fcdd5570bd088749b
+b232615366687962c7e56ed089cd7b092505cafa5a80f503c4cf337f07ad
+f0d106937e25670839d491f7bff7a523db609d126328c16113ecbcbf9c40
+04904427a108618ae5d4ed809f8ccaf72251104c94ec5bee21f91b179d31
+dba79ceee5ec7ff698eb84ab1d2d1a624f58b3622a78844ce51498b2cef3
+8eafe259d22c7ba61104651a862008bc1ddda58cc45f663eb26428daa85e
+7785363a69d2790996ef5d9621d53042f42f794962fea46e46f37b8ad1fb
+76fc8d5cf2146843f8cc625139c75fb42dda71a752bac48f294e4c0c8289
+fc46da5efd9c91bda6d027518b7e81e8b21f755a9615627d5812aca674d1
+527a1185eed4e3c628196e7d0759b1cae6b9b7e901e9599a65230f1ee469
+cd33b9bd9c104c44e3c1ab966c9678bd0ad78111a4e0f2d07a01a038cede
+7036d0534d684a1562a17ad64a00f279200c0371b1cba61747671d2a21d3
+f9646ca290f6b82418a96fa177c6278277504b7fba936325f5fa124ab018
+a15dc18d2c5e8f93cdeea52beedb78a57828d81a3e6c38b9faf3dc4eb727
+3ece3ea4482a1c6242a335862c2c3717f9c9ed95f77b140c4e1569b2192f
+c7dcf702d0bc9a50428ec406f8bd0caf886b4d979320d3e429816d88f7c7
+146d960ac12e70f2cb7a9f4e3e366665ab3f1b4b6440f55eea26dc9ee009
+6bb7763731740a537766490c8c174723bf0eb40c53701aad12b21d436adc
+e22203c1053a9dc4e9f17ae617888c4b4e6f3a720e4e6366ba628221a387
+d8ab15e04ad69387c310d3528bd2faa5b22bff3fa494f5fbfac4f771c9c7
+402b95580c5ac4bb3af692a70cb2c851fa5cf1173eec3ec29b5a05a0b728
+bbbb51d3b7ad8b0af17a1563e82fafd93f8b71181fb7afe352874f4ec6d3
+34ab6747519ab8e847b7bced33eb5458a828e074e74ba621bdcd03fea604
+7f7b6abda01fc7514ba1aff0d4d0c0cb8f4e42d5a87e395d9acdd02ccc22
+0c157153422018725846009a3acd8c8cddb66bc6836b4026fd9f526aa275
+d06c813179e5924f26a25094e7bda8bd26afc4ceb41d8964d4fc4af1dfb0
+595bc5d6714c32f15dc7194e9a3a73013c45d8fa55cc0550a12d9aae8e9f
+f199fa28efc2426d8d1defb93a65717af3ea8e2d5b4aa8ef0ef38e9600f7
+d4e7d9f1d67a2e63ece4789fa74b159bfe2f91c19b0378ba52e93df12830
+d99553b6618645e26126842ab70262d96e35e5e750eca0ce3458b3e51bee
+2f21191136dfdbca39bdc07939e521e4f492f392debd029c1ea237bd89af
+76bc89f618d530160ab16269fa6b693cf14bdc4ec7c630025703c5337f61
+458fa09104eb15c7cb20aa4c9bdb7cef3a09f25bc7f3149951a7cd753729
+93b80cd2112f7674cefd6afa764aa3486730d2c1897a264d82a91709fec4
+a21e30d812f558451804ee6f3dee2c4c437846bcbda07c5b6cba1d94af02
+9163b7383cac6e088ab1dc14ed3743ee77e26ea7ad3119a76c0b5f925c4d
+e305cd7bb3a09a4539475b9bd79be28fc462d8718ce05f9d94caf3387ba5
+5e6e447bf81a9eddd3a34e17be66bc52b0c0bb6f86f6f008829173816d20
+5182ed2eced319864a796ab65d4e3950288bada94fa32b6f453afdfc6c39
+a4fcfe60353a64627e2057d4b379d3240012b3bb0ed0c7876cb83c1ba5ef
+b6e2a03f340c2b576731f848f762a7e1ccaf267ee06d621bc33fc245d0e1
+547adc12cc0eb58b26babdb8eae9cbfbab93836fff22bda1831dd01b7346
+ad377aa298d84628bf1c07433284b0a90fc89f5aeb2651ba2cea405d4f52
+ddc0e74b871d43f71eb4ace0d2b401f9348eac3a2ef0ad295036bf6cf6f8
+70d58e00b619d50ea7dd77bc28def91d805cd527dcbcfdc16c042bf9b874
+e3b1567eba4c1e70744b9e7e5bd1fda6a5ff6e101613fbe58dc46cfac1a6
+5adaf65e49757e9304e2ac9a91e0588600c709a61d4231730073a36d473f
+518a145e141d0a5a494441b9ea99ac23f60f54f8127b477e1ce698bb4129
+b4b1dfeedf10d9e665c247a62f112f5ca30b0ae5dbf3e495ff06eb28eb43
+8ce8aaad84d5f50fb56a3af002c23bcf66abc2707ac233fc0f2723db99d2
+cfe7d3b3667732a531f5dc315ce74edb9050bf75d29e6430f57cb6778b2a
+cbd57dfcef896e6766c8fc5c9f9fbd701cd62cacf33ee0fc95e78dadd205
+b5f42cc63024624baa0ab4dd447832b4e1dba77bdfadd223989f8e958c8d
+759aaa37930664c6efec708116248a2a7af3d656ddeafd009b7f53338546
+08e67e5e588a857167adf9225cf6c641f5e19c3e08678a281199eddac831
+b57223b1beeadfdcbc8f6f25d32fca2336c808162e8f381656e847fb6cb1
+3969572425aa05ac830c33de6e030f86a3a85d2a66a77f103c7042c97205
+526dc882ea9a00eb8bd5519847eb424c15f808a91652a6cc89b66a573112
+6debade123c63d88a2e550facdeb3886ff98646000c64b3a91078012ca30
+904b71737cef6becabd43dd702880538f5a70085e6cc6015d2163681067c
+3d513a8c66032c34a0fe17a58ad4bc97ca69bf41f11d5e910fdfe9729652
+d3ea21f8dd8cc19160a8fc77573b1e9cef4e790a79d8ad6723b6804e9616
+466c935303e063dee29caa6c3baebf278b818c2ec2f13ed645ab452397bf
+00db8b26e115026e256746cd0c78a959364fde6deddcd0f441a61a1eba32
+c7bc172bb09512148d1ebac9e791b7d51b71cad2dc9b83b2f99b3726607d
+9cbe58b499a13753ce87fcdce21c0ad0528ed0efb9b2c927f57c78c62624
+8aa2b835a0791244c5896686a66173ec9f802c4c633a42b086334d2a4878
+0e53d00809247be64e529f96ad2f8b3922a6097d414dde1ec76f9552f9b8
+d58b8e34f359ad792b2be50c26db05035e7497162e7c49c38d3cd9b98d62
+0aa67492be5afca3a81a7080185c7f0b5105223f1fa77805502a2e8c5fee
+a27699858d84a95842c5f2fb68686d59fe24091fcdde139b6463bc6c7b1e
+0e90d20a83651af00c85797bb9f53ecec1675c7ee636d0d9e77dbd8f8967
+0f855ee4d4800ff3f6950eff09bbf8a0daf6b8242840cfa5ba73beb95115
+f4a78bcc02d85ecce0c0f2ef6f328ad1dd6cc0495a3315b414a4d61da50d
+a46d7acceff6ee56451805d26b0359af193531f95f6589cead6fa041af15
+3067f88a0a2fecd135c56682db2b45a71d1fa737c064ee9a4f404bb72a70
+b3af0330359393247ec781512482579865240a23cd8479f21c2c44a119eb
+c4e81b308dd8aa86e60c3dd8ada50e0dfe8308eb1a7f201ede8dcfda405a
+efb47e0e6ca7ddb376dcb21d37f7acc4d3e9f26b03a8de0e8940ca3a9e75
+963a389df8038d2c486072f61c0ceaf500753c7a6352b1cd0338d9212b42
+a4d3da23d5bdf44c27c94b88a415a3242ffe2e1b332477a21d2b9ce075ee
+479c6e657a4d8874a8c53964229310e01ed4f3c686fef5258edf3b464dd6
+ffd7f1caf473bbe722d60fb14ab4918e93878a8ae4773930b8cee110f476
+7f42a52d9304c55be12846c911a10ab9b2e036bf9dfd597f5348d4223331
+5fa80d0f563c388bc2532103f05e90dbf1923f229f980a2f4585c7a37351
+1372d07dcbaca583099ea972c03e5aa67e6638826db134564db993ceeb6e
+7a6659c7c5c05c310267d5f8a24eec2d5cc3e3f3c808e6d6068d1a57646b
+37fabd98ecb7baf99e7d9ac4414a491a73ca34c52f394352f6b5a15f0fc4
+d88622dac694699c246484adac3b1d366afede2a2cd2042c90516a666a19
+a91c80248b11224beddf1a320e230739e755d098b6a67315535f4c187cfa
+67ed817a035056353fc859bf286317996fffb478a2248b908ff12abde705
+402224a3ee5f463dd3d243875c84e02db968eca1cc52c75171ea50d6a88c
+a91327a7aa5795019f36c0a19c093a1c9d3723c7568f9d41f2e4ffb712fd
+47f897703d7a620b586b81936c84aaed61d84332b3bebc4f95b796b93ef7
+a1f565c494f8a65edb21e2ee18dc025522ef8e599887ca2836069cddd889
+88e5862977b7472584303198cce97ef9f9e1446d1f1f5ed1cfc666a8a0c3
+a03e1792efb60a9b406549e0dedf6accdbd98742568b4735a747d8e5de21
+e630125ae0c691d054e42199c15b1f80cafa6e7bb2005f374a9a5f9900ab
+b7409ccd50c3afccab1214e6a856f7c7eba89bc3291801e1343da9dad2c6
+ed075c8eca1423b43e587aec67e6145272814b3f191b3c285639f9e2d6e1
+48a02dc2cbc0e054d6295cd05dbac1950400a9189316f0265b86a732d302
+c5bee8ed233768f237c62600cbaaff3a110d5efb6cc7ca3b92d965ca7c5e
+8d3e64ecf239fe2507fc797fdbe54c1112b28d4da44c60ab09d994c5ba78
+d663a2591934cc052bc70cd1dca3325c66c9cb982e2039f5db70c848d3dc
+ef655b1c2cd0cec8865fe8e1c0a267be4f707ece6f5a3dfca3cc1edf92c7
+60439f51aa69a4c1801e96ca4d6ea4ad980258f3d15c893913abce091019
+84c61b91d603053e49a97cb82fba707dae8af1d579fd69c8481cb7b712cb
+cddb4d287be995e32c02b399602a08b9dd849039b5673f1930bec7bf366e
+b082d2ca5db2385c8cc45be3fc0e31820191a814eba7c4f23b1938e6c4d8
+00732787cd2cb97f762dfc85d4b798809b5f2254d826ca42b32695428d12
+0298b44cf38494e56240b75df1e41e46e53c44dc505452256dfec819408d
+605ff14d6c1f3f152f2fea96ea0ab3b472d8704e06be9f8c3e8395caadd0
+6d6da033e81ade5dc3b83daff743c6e9e48716003d358df63cd7fd3e2f72
+7d1f2d0c29962f76d5c95ed44b6f08d052025a665785f264a3d5f5593677
+b630e628b5ea81fb37cffd7a30b7fad226b6fdc82b0878af4c0ec4f4243a
+807b9839ea62bcbdf7c2e9b30a623876e632e084ebf4a21eda04fc88a1c0
+7021d0c72ec3e969d449feb08e5826ec20e55b21ea71ea59f6e3b0710b0d
+dab3261b4a2029ecab68c19add5174e55d5e984a4e5f38f592a302fee6ec
+e732dde841a28672c620cc5d687455a5c06fa9fe688394a04f96312ed025
+b7aa6fbce2925f3ae559cc1886beecdb70822e2e5ca3f732a87404b1536a
+ac469989e9610cfa440ace43875a70ca51f36cb6f629d9424c1e35a88f92
+d5da3cd8cbae6e8425a36968e21f4f30349749e0205bff8d552837d6fc39
+532525370bbac833f75f1854c93fc533a4aa53adf7008173a70d94a4ebf5
+38ea9e62bcda7c20e0a073bee2efac34d2ef1d03babd5147659e50b55704
+5b2eb89db303749b04d3f54b43fed612fcc68206e001a7afe90230d9c12f
+74a32c7edb5d0241dc3a5d51481fd7c8fae08fee263fbced7c7d911b3a30
+3c835af5fadfd218f61a9d6de80485abca88200047b094441f7767b97a24
+e8c612590fa2407bab1e8b56c71914eef2355dd97cfafcc192bc06fce063
+d3d9d1a629aadc75e3bf207234c208e7e30663edd691043065c9cbc473d9
+7c6d4dd3dff59d6a9abcdd4412c3128f603160aad8f81c6e7a4dcaf35f3a
+99b4ea10a34375b477c2bf846521a7eabd4d28078e9340452a198f3f5acc
+3db7e3908939ff6e3709c6a3fd9889439a4ae3e10b618cc92e14b68429a3
+ad2c80940a1079452ec266f254657be7d79a2a24084af73f6df71fbcd32b
+f6913a3fab25f977787f7bb0c3a3e8bab38d7a2db0b4826950643dd1e03b
+d7dd1fb149a33862a89226b7cb454daf613128c2075470e42e70a9444a8e
+6eca526345ab48e6f5160ba23b5bddfda6049ec44ed1461c7e0dd514b16e
+2fb285f72039de3c7982efd40d7f6c8e8f4cf35ac71b467bfc578002e8d2
+239a2fd2c4bccdd8af3d7db1f4ae7f2d2e0811df9d0155ba6ede50b5f052
+f14f6ab884fff244d8806c07ebcb49ed22d85df696995991a954aa97a1ec
+d86acd76e061b7541e87997fef0657a826bd88ef3a4a5920462c6595e7a1
+56f453291ca044ced810860c3b0149bce73beca713040664ad0591304106
+129600af71317b0d2907839ceac99515d357e980b1937b6e1200aacada20
+5421001f1b2f91753e80d2263c56aa164a74701a8d5fd28e46480b0dd963
+a683a1f355d7fb4463c7347c94ea5e2ca40b60b56297cb22d972c5bb10e5
+6715a955605256c1541d9f3bc5768a6f355cd3b863f0fa1a781edb49368f
+51b29481cbb41d4aeb07af9dbe8f52c5d0ff75f7fb6431d37d6aed84d78c
+778871cb0f715b4f07580f23b586c969c81b471ff6a6c7276f7e141e02a8
+584d4b9ab00e7bd643d2c3faaa299b1f1e25048461952ea42d4882768a70
+de46b213a287f8d31ac46d5436f22a796c05d1fe50a9bc2a928066627a0d
+87dd57a3ad91db446404b41557d1457873482005ea20916bbe46c613f456
+c849d46ba79d20627b446b2f49e3fa309ae14f8c420cfd94922cbc0fb9d3
+5a0f7dbef577f1849a1a80e0011da8ac082a8c6f61658e65ad177abdf23e
+e17c8cf0d26b9fa3a6e94837eb9e930336889767a8d7ea3ce980a8ea9552
+8b004957be6067cd9bd8e02a0f23cc1762cca656d33412ff45e917fd4a03
+eb6e8c1f43fdb0a8965a33b4fd26bc24a20b304ca817e88495ba9b361a3e
+933717ffb0271f7f70c5d3cba1e86d0f51bf3aba194daf32c35c796627d0
+0c7b2271ace2463e37e97b3c826cf3db60028f240f9452cbe08f7ebcc5fd
+b1bcbb3c327a9f450b9e5671916101d6e3e5e458ca31f04d12f592f83bad
+a2c3683d3886aa3b403963ab5dbe220fec00037a745839f67a3635dfd3bf
+f08f367482962ded88ecf6322852d643a54d5d303eb04bfddee9bba1ebcc
+ba7c653b3a613a8e719adebe3ce1bd7e754e5f4977e863e3c2d388a65227
+b451d4f3a4f94e06513cba4ac1f2f511613ff035611684ccc461599000e5
+46e4d972ca6960e095a526e4735a23421a4c9b597ece08afa2753592bd16
+ded93255a1e33deece3c5eb77b94670e8137f2a4a4b98ac193258e7dea5d
+b8408a806188f2d1ddc440ccf0e9a6e2f0c78fdbd7b68dd4939d2458c196
+5bf8bed4564b32462fff3ec892c03b11d3ea813fab4cfbe8d3016329c5b7
+e3dfed0f08284d44aa0b7a2f6bc96ea4503e8ef52a64c22bed6b452581ae
+8ff8917d53976471941a9116a2d878fb2541b561767abd4e31ccd8a590ca
+03494c62affd64ea0a1bc779173dad84999c7a8d844eb1259de7bb5b25cd
+023537a474a524ebe4660b22568949e624d8fea0ad37f4ce1ec75955eefa
+49c6bf1803be87e9c9865ff3f6b8525b8c15fe8835ca153d27e6c0ff0ca5
+1029a7a9185d25f0f14d86fc797dcc1f99ee97e2054b9c2a2e06fdbeb8de
+f6cdd368bf23a858d9f8c1defdceaf1b4a8de5eafc604ceccf0d285be00a
+a912eab66eff4d37ad2efe34853bbfd87ce09b18749b489943eecae7887b
+006fb827d10191dad18466cd1f86505879310a8b171f902ea0c26a388e13
+b53c700272cee2bfb47acb58247c13449c6bb9d01232c32517358f1a3de0
+64d43c18f8827d53789ccf3ce2ebe78949a6abfa1a6b8414ce360a5e22af
+b7d1dce6f5a06182c3b984b4f9bb1a905a9d5a1483750a1de0a857cd5c06
+945eb7d4a2a6bf1237f32a154fdc06d51a703d44fe052fd3c53e9e8f417b
+35d1c851f9203a8997521529f21ad8498f96930aa77ebaf82ee02a57bc77
+c792d9f220294b45f48ea8fd94e01cd25645d36d168923562f3fdc93cb79
+dd4760da0c103c2675722d7a1b79fcb4245ed12fa0db52492c9cce58b333
+cfee822812f7dca68e802c451b5cfaebac608b950386b6c58239d1c62d62
+4dd5d15782fc552222cca06ddf387b373e32c3c2864c63c768350c372837
+60f3515a5b0afd66c48ab522eb3e808c061f5cd6bd96cd18c9839d30508e
+7d4edb88e8f11e31e10919b16b7971f06d7877a058d8a4944c84fc6caedf
+3341b48b6e0d3c7b85d710e0c35f5b5053cf4b4798b3778cc28b2dc7ae0d
+f3a49f9f3bcd8e95d746c35c3f47d68b8aa35d97aa08e711b5fbe70d1a62
+3c82541ebdc51a827d0a69e6c049087ad26f256eb7577f58ccffbccba5a9
+5d093dc29464c9a38de95bc6b1853963b2deb0b57ad1248d6f1625e115ee
+b9510b5772aae4e3c866657db0b3bf0e0ac345e116f8d4976b770876ffe3
+748c36165522991f46a36f193dd1a1c94713673c7e4c81582391b636c72d
+e94ce6254374f99b623e5686c13d8a8322e83e11bb0b0a896c6a8c2c4f75
+6c5385cd7017f26d23f7c3ee97372c868c8c915581723bb6b76b4c3ce899
+8e4fa6ca40b633dfdaa59ba902a4952da90ec4fc3cf0f2676acfa7f76f78
+236fa2de10fd3545357215246bb7e527f277c28b353cc6d79dcef21bcc8f
+77603cdd58a2ccddbe3a9802f941ced8e035313875319548c41992a2be93
+9a17cc109426e33825ae59bcd17cb19f50d972ffcbe7d9b4b0bb095303d9
+dc9d406696c2508d6ce99e11cf00f6461147e97449ed5f486d480a86d3a7
+acecb7e9a945984724efc21c5079b1fd03ed803c2deafce3327d2d782771
+5fd65d9506216c88b0fa26935e95c64114a51919d419038b1a7e9c1e829f
+bfb53275093752df19891a97f3cbf7719c1fd6cb17019a6d2d25360eca80
+4c4b35172662cc4769d2b785c6c87e5a4ecce31704e59f71263b7c3caec8
+acb4c7426ec25f11a0042323ee6c3eeb04284dbae2c770bc419dce79bd45
+60aea41571c3b595f52560191dc7a8fbf63d413a77a0905e517441b16c2b
+501ea2f9e99cc38d052679f288fdf1894542e3a66989a0090185eb2e7513
+4bfa3d9147c3db8a621d9d35e37786853779e157b47f71626d6b3e633005
+9159c17596c1b87fe2b4ff47ed9d78fa4c2160077276c8b58cef5dc030b4
+a5d83cf257096c047fe64de307c598b815058e72d5f57df5c369e664e137
+de29349e2f9dcd8c9f4eba6e765b6327d7a20dfcb20711273fd8091cba60
+5c4c494248076f7e03df65a6a50164980bbbb708741e5bf6056e6f996dc0
+7fff408c5b8eab8dcec315e92873228c805d4440a6470e3ee3983758dd21
+1c9cecdbfaa4c9300cba00608a4b2404a3c7af017a3b7e67f39f0b51acf9
+50d3e75cc7bc2b8d3480202fa958e8ee0b2405015232ee0d264c7ca02c18
+ca45cb3c2de322d3eb7f00f9455db6c5b1f4e59c3e95520ec36d7d903cbb
+625d70b54bf6f8255e412604bbb29fee026cc660577f91db1db4a613eeef
+b20cf7ae3cd89d565ac838416b01b5de4ffa5550d17fb51fbbebe21cf1d5
+6038863ee931b90dec2e211ed42ba92ec244d4ce2c4ec5ca87a026992772
+dc2af754fc982b94f36ea7b7bf75e0ece90cbb2a6aa1a012e8898bd679c2
+3cb3827c35d5d02f0569c7aa82615d4aa67518ecf668d3b57d6ef1a80134
+24ac2268ba0d9a74d58879edcf6382a89d397864940303eaec45a38304ba
+8b1cb198967ae23eb81054be74b16909a405e8a7799cee3c270fe2a6dc50
+bd7370b6b2c8fdb9a87d88d5d40348d3984e39c693b6f4486d994778607a
+80a3122872dd65e40492107c71c3cf708a9717e9eefafbddc239c53aa964
+5b711038e59c8b861b37411ab2039bedf9cfd00f08d9c5d76154427ff5dd
+39878cecc5d7bfb3f1f035087185c0981f3c2139be84872ffad3408531c4
+ea9387b89f5e3ec779e8850d50992dfdcf9132bc551e985943b07618ac10
+d1150451f0844c0dc41d6e17eb508dc8689ec726400d5a7f6feb3cc7bce0
+5f09228b7cb2c5393664d8dd9a4b96b1020ef25d70aa2d91cae93afb5f2b
+f0aa18ca5c599fa1a708ef35bf8f7ffec9afc1f242870d028b2b1459063b
+493943ef1283829783e1010242e5cf4da39d93d506f3892936e7d6cf1124
+70a521d397438733d053944cff12d6ffae8246f20618684f263715aa98e1
+5d72a526383e05c23214b78338e5b476f0981d90056e6e5d0db66b1df229
+8e597b2abe1d817e18beb056e65edb4234342d9600470b1420c9210419d8
+34e431b82f58608c87ac361a02d0f1fe4b470a3d71e0d21bb87e1023d428
+e23d596cb9e1a2184403a16e36e644bccf9bbde27290485057e62827283e
+7380af786bf395b3961ba5ea469c315763fa59e0f176ef81985f38b882de
+56a74d128e256d1b89939728e55a92aba21a6b7844fac1ba7bbdd8b34a18
+194a2984b000380fe9f672e83efdbf276fe797a325815b0f25cc95c97a9d
+acf56d583486305d7c9e51a7e337d14e3b900333eb38fd93a99587da2341
+b10c059c71ce080fe7533c0f059fa40e560af9c4a41a4be6fb45846ff8f7
+8165e10b4ad40f264bcf5596a1e8ef8cb6ea4b1a3a5c69059ab156384367
+9ecb2511a90e8898f54295649cb73d277760d8d04abacc7bcc6e777a0530
+e2067ccbc08673f9c8c178f9d672ac8a15e5367f0c5651b53e75e0cfa57c
+931746ae1a679c246d7c9417f1cd89dddbd1173c2f880b7b3847cbccebf9
+9f7122e832d7c9bafe2b54cbaa1ed48158de3f36238b76b0e67644a28aea
+996ddc006f6ac0242e4b667639e7523cbc90a0561193c1af34481c2ef402
+ee43a82e1ebf4e3d601bb36b2d95cd93550d61cee7a94e72f6d30c32c8f9
+1a61e964b1f66acfc3987f95d4028f116e9a9a8474aa29c1c1a984be0e39
+3bdc41dcef6a6f1018db60d52024899d8eb5d55d324d73f39bfa47377b9e
+15b3b06a7585589fcf52a54684173e5183367e7b0952dc4bc2767c4c6247
+b1d6103e52bc7b7ea6298f454c5d97ac575f19c10acdff4e10c7d3755cfa
+b4200cac545269ff1d8db0d607c7ad47f40ddf257ab4e7d0750577003c13
+e4941960c3dd7b0774ddac18e8abaf8f53e03cbef6d57b44f24cf821014c
+064278fd51b3427593d17694b4abce81f49cbb984c5878cdf0c38d1ed7fd
+99b0b9a3bd8d8ff6219588b3b8fa59d0cdd1d9b2f65122ab45e48f175746
+7b9204926140e3c350c5a927a2e700173053ec35d3f1da2d7258714c97fa
+a857f0898917bd94625c6d1e2d77138efcaaaf517b17fe187a2212c24a88
+1a2c6a647def6376ed80ae4175c5ee80921f001995b44e49f0d33dd9075a
+cf33bb03671c0bcc34ad5784ad1cdfed3a6d9ba103b3ddc1cc2de74dbb57
+6a0277715275218cd19ca8899209125266d8bf1286f881dcc2c383749d1e
+768d670f4099f7de959edfe852583183c91116012881a56a24aaf020ea45
+cd5f39660debce30ac1c7b8cfc60387b1b0c3e361be612fdfa9f01b7e4b4
+a18839a2c7e0e393ebc5ad9a8a4ebc316a740c1c295d9ef5f4dffa0667f9
+582c0bb837b142c4cfc6b1798e9476d0631111033b8ba75a10fdc800e2ab
+1e0e829632f869cfe4737be9e2800759ee0831dc7d1195eaf80555771981
+dd6dc6606812d92cb8ef86447f5f6c6f626d0e265c67e52a6319189ee349
+d48e49dfe6a9e98f76c414a1e3217ae0a215a17e54aa498f4ecdc50242ac
+c7e2322f63bb2ff2189d057e7354e32a3ed1803116176b9b9d0129930f91
+9e2fec280b2c8924e49e7bb75768a2ee1da8adbed4e3589906df1b923aef
+84c1bd327438b731012e69bb0d43a1842cb88bb54ea4516477f704cfeb28
+6e3ea483445ad4d74586fcf32e96d366901084365f693a53c5fb532fbfe7
+bc0cadc404c4985042d68dbb90a6dcda3531ee324d558a214f935cd9fcc9
+a0cebe9b5fb0323f4b3820529599ef48ee068b5ace85004fea2984f0a86f
+5ac9d56163bbfe1142b774148f1eb0a4dc89c3349052533a7de66729db24
+41b82f8f7360111dacf69293c9b281a0534f3e9e9224a75c49a832f28b2e
+497262475507b6ddfa9f01ca0a6696e3f5ac7ea68595eba0c2eb8a47813f
+f936d84ac1b23eca7aa2862b793ccbb0df9fdd4931bef354cec12fbf4785
+59fec29f81adf4452e83963e56541d31f3691c93a50f0bba5e9552c4f2a2
+3a6e53060729854a3dd71cc4308b91957db19e66aaa18fa67055a950f1c2
+cff78a03bc1a588cf624696068068719afb1001c4581ee072113882d9052
+b21e355d401ed8cd24d067b99e616bda5a0a5a9336fc499632b79ff2fd0d
+efb096ef46b75e2d4e0f48daea239719fec4d9a29818f5875fc5041a9edb
+d26caf0ace14cc80ba49bba59e918eb3d8f1e541aa16026585a2f72df7d8
+3541816de46981fb3efd0c30e458cfad04c79421ab7c4925e23aea07f9f0
+18431c790002596d26bd9663b51b699df53e4882cbc34ede88eb55045b88
+9b6062e35fd1e018bce785157b85ec3b9ca6c85d4b16238275385b8285db
+012d8fb7c9f5b946a41d7a0fb878ff72c39683144d8a007cff631b43748f
+2d5fc690300f9bc0c837006b92ecebe0605e8c3a4a400e18ae8997d1b45f
+ee10068e247c647cf82c6dfbe5e881d511ffa687b7aeb78546bfd07d5f7e
+c242dcef4930d8aaad8c6152b6642aac325963fd147f236bb850a9966573
+9d06cdbd7ca79a527dcf461e33f22bc9c5db00da2bd3dddd8c99d99793bc
+98282aa8872ff96c394285d82d9419eb78b6ae37a5f519397700f75d624a
+09bd255b576e955a323e784e8fc31131f003b0e3024a4f58fef2a6c04379
+6201fc425482e1155e229d1b2d43ef7b0d22322b22ef5c9a1be026a1c3d3
+75edaff99597e1e5477952a4e8d2acf5d014bc00dc2a272fa62b6983e27d
+228881e2ef2b8b95a681cbe90c5fde16331c85222fe2a16f0a3c3000a63e
+2e21666c0c119f8af89a543d37977069a5acf1556324f05204ce8cad50ff
+4fb630d9cbbfc324deda584aa56a99d3a76ff55bdc2c2ea3a021361ccd4a
+83c7a5e2768d210fa6de889fd48a39d679c94ec3c99a8d33ff11377da7f6
+f1b71a2a05b302ecde954f26773f39ac881542f0d0969c3995c3519a8ef7
+0b4220d86bf01beecc6462855e7b686e1aff1ca91fb8fd8b4a69e10ee0c2
+ad94add44449506f9b6ef43641f2026eff6e605c670560c2b74706fb949a
+a7e8cc6a2d0d6207e457e7fd87ec1b9092dc68b9143947cc8ed14afddcbf
+8fdda228a76847f96802e561f67ceefde45ae587673983fc04c96744dbaa
+83f2dc838d633943c75dcb9e6410474eb27b348f26e505f0ab90878940e8
+46c5e9f3c5fe8c3558c3236b1b88c405716949b8506841cabe1717474bb7
+c30db91cdee33b0f844811762faec535bdcf84c1c747cef9b1fa61d2afb5
+a81335bc42c06a94d7d59b7ede55bcf6f9867aee107555cdd084b7684c2c
+87087475a39a9da6347be281ce5635a4d07865ba98ce26c1465b1ab0343f
+49ff37b4d0ca9f3bb693d78dc3b21925cb996a038dcc172527fe57c07460
+ef39c07d4396e7fa970d9f22abd21a9c794b64ad96762c7428f59a8757c3
+6d6c4ffb23216195a04c2a2c2e7b10ef7193931544d782fee4b91e01119c
+5553bbc6252270a8d8c56dd62d448f5ad8dc69ccb45e1f17f0aa1e445129
+dd00f000005b23d38de93a3be55a4c041947f36b4e4536e307d0180553f9
+2e46b743881cb5d5386c48c7d5f84c2bcd06b9c501f78c7ee61fa2351679
+1fcf4db278af688a2e6010a56692ad92008497487edfe4bd5fa083fa5441
+38b20d6940020887e35d46e093b71f7a04a67460dc8116b4d4839625d7ca
+6959d6831cd93f81ac4ea2709036dd738364fde71113bf22ebf13dfe1642
+e564701e6f0ffe7511edf03fe448c2b28c64fb7d54b94ca576e481fa56b2
+b18af10c71f699b6bfd47459cde1869d0fd306bf489a6f42e5b2f05ccf55
+bb6b9526973d19cb134ca7f13f1db3716f8cc21773a832568c16250b5cdb
+16df24bf81d49f5b37018bd310262ea7078107868ab0216cec83cefcab1e
+9f2c665a31585ca04dc01879caa79aaa5ab201b516f7052b01b16bee5606
+098393b0e5d9f9e5e3f4eb20f63c958e796df41cf28839f5c62a04316487
+45d7837b519f3aa36bc6c08ef040ccf53d9b6d8c0c7d1a84d707ec57a3c6
+ac9a62ab37251a01a5ed40fdec6f5be6e34c6a91d058319439778a2ee5d0
+363e2e1f33463c33327d05ffc0cbf08d5bc457c7230448972fb9b4d0d782
+ba7dbf10d3ffef8bf5236ec16d4dd6d0d870d9d5eb5c64c9a46a4f583d4f
+831fee74b0e5b33a09abfd4444929bd8f638cd72eab99cf2e9551df42768
+3964a592e49d186f285258c5d5f62196a98532421d73e3495f82695feec6
+e1952c562d546b28618ffaeebeff03a57f4d855021f85b0c7bc37fcc6da9
+aeca099b646b99d4189609d3ff2d56422f8c37e97640293ec7c90e338088
+7836f4938fbf495cac14fba5648d89282d8d49d91af73ed36581139d8bd4
+2551e263e830ea3c6eb381d85c42d74c50db0ccaec03f535ade92128a016
+0e811c34748309af7604919b66cd43eb5ca975302dcb6076feb6bdd6ff55
+976fe990fb0ce9abb11b195403fb26e3d6c6a0de1c5be79e171a61e21f79
+ee8dbe7a832519813ef6b33ea098c2c32adea219ab2aac8b093f40000995
+539d1276d5f2ef84ccd099b71fe4269bdbdb6a8d59c86f7d2e3fbccf8773
+d0fae97640bc1ad43cb4b992bfadfb09dbd0caaeb8cd9da264187c4f9730
+0e9a6c9deed5525479e605c65ae336cbbdf4e5d7f79ad098f977285e0655
+79b748feaa97f2a753e1f962fcab68d72baa8ee4ff6691c23e31bc0f3e98
+1a96fb440404856ae1ab32a7205b17d411d8f21c8c93b704d07ec594422a
+bc368cda2b1610ce6a973f4474e12b78b532666797f5755d269772c9f540
+0b3bfc6c58395d38527e2cccf29b56123f7dcef3bde5dc1dfc5b0293bb12
+5085b1d2d929bc3ee84f4fad571a4991c3dee03f2db3a3097e52b1a7d5c7
+3ccb6148eac62e8e36de9a71c57638c6e4d5d9ded18174e8c390e50b4a5b
+913c074eeaebe390b214b3a68f02862b9a296db4b409769649e51d738cbb
+dfb7702e15c73c2afc6bc37ce15171f4e822cf20efe55d9f061aa43e6489
+89628ff79e65932390cbb15d8e621333b18b11c3bdf96f841d7434e01ad5
+01fea964a75b248a35cd9df9a37e48a1e5a09c624b93ce44f0042fa00d7f
+9ee89b9f7ab785e9c718cf6e7228f743271c2c9bba17e5208b920e44e765
+d99d86650eb454b0faaa112753aa1bd3a24239e9c5fc47eeb1547ac9d237
+31b8dc48b9707830daec60c8d3790bba1120f7764efac542cffbcd5c05f9
+510b27b2534b704ecd36c8b041fd49a96881302fff5b0163a2dd09c751d6
+d6afea9170a4f4c4ab8d46e62f763fe1bda51dd1ce4a27e772f3a2869155
+f762ff26b7aa6fcfa4f1292e56f03aab6322bf867e7710c34d43b5d85b45
+aa68014ad7879eed051b1933e491496e3e26d9aa8b80a07bf2b94f1077e8
+4a9726f08199887d66de7a307bf33c30dd9cf3da188088c03b2bad09a217
+6b110db2c868b53da9a66c85737ba66c93c58a259860e294ad0191e3a72c
+73f40b0bd98699aa08daf03587b78f391f3a4313c58d9f29b53c70785637
+bd0c58310109c54091ab0a34cbb0c478613a7ac0fb8f0a8b4645ac966395
+d8ba775262cd291136affddf01c1d83dd4eb3b59ccad18057fe7d92a8cd4
+a58f22508d9fd7cf356571f701bbb23e749bddcbf8a317fda0aefd952bb1
+8545610ffad3ac143d351b8db3f66293375e0e50235f0d0466932181d377
+edd32a5f0ffa4e22b5a0cb4f343d9a7e4a342e9d09dff6c697630cd39718
+02c277a5590b8ca94bde6b38446c794d072bbccb724d5bc208eef1b018d7
+39373bb910d668882caa779c2d686081de6a2606417b54d7c20e0e7f7226
+48d893e4edbae8f00d6a6da3712f91ae860c756d1127d133ab828e9d8002
+3b50b162c5a1c5cdf70ccb3fdd7ea060ed20838be1e50c4094c9e79e1a01
+87cdf780caf45a725964f004253e034c5be46bbf89d94631f1a33baa35b8
+4fa2a9d08481c6674126cd96ed05dce48bda069d902d6836d5dfba701dc0
+f98a863e64f0e312145d8dc0b77f25b43aec729a1243b45b08ca228dd610
+1caa2ac5adcc8eff84a4ca3f254176c2cc711ee6c273835d0fd3528eca2a
+976b88e51fe347fdb60f32370b66d338931d6581630ed586f349c638960c
+31ae4204e89521a96e1219e696b913deb2aab7a3b022d06f34fdfcb810a0
+4e60a4febe284c2f063e0ae9edf87704921ccfa193bdc912b747e1357006
+6223a49f1f6e2af0d4d65da04ca876ff7a462ffc9c0ba2cc545c3bd36dbe
+762f32b2d6be5867c59f479195c92440dc165098b74ea5c3ad93cdf2d410
+b04c16bc7801e7956f4e5107450787aa592493171c3628e6b8f49d4f8429
+eb98dc52ef025f001387bc1a7093f7a99f10b5d2d7dd8bbb393bf6e56f08
+f4f7fa1a343f220d5a1eae7168c74d41be1dc1a83bd65b72b982f4f7b34f
+24f97f9ec9a91011064031facff2a14921a32024385f4e061cd07d152e74
+1bf97156d951a342488fa7f5ef934ccad13e2753a0ab7a1f565c2f7f6b34
+9df03bbc25bbd972a9adf809bb5c5048a8ccef9297b2ed3324d18867f293
+cc66e88b3a39d107b610dfe79a3b4e83a96d3d52a17fe8a62c9fdd271130
+148366942c9ce57558d023da5f7501319ebfa33de9e6d1e76d7c20db8a09
+b657839da99f3d8143f1ee6253a3295c9651fa4366547893c2dc7abcbf4b
+b7609de5d001e0a36d9ffbe01f7d0903b3208ae8547e2e5f14ec1af4c253
+5ca8f4ea37e3f3ce172c7a1e8308995b1cc23e6e81190246bcab6e755bf8
+68d449bb02a2aa87c44c9cc0f571adc72547ceecbe104bb274b8ac16dcb7
+5d5f458d356466b921acdeeae384e2eb1df6ef393b41b9747f0a4faeb4af
+1928d9ad6fb7e06fdc621e4c6fc98cfb43f88584bd55d9b97cc9549093ed
+e586912161931162b1b1d52d0443260daba02af2b4432100d5506546013d
+a703573fa8013685cc798ce501960093ded713ffccf89ca2b9106390198c
+29a00864108cdcc1984a8bab53919028c01b26ecc7925e38cbe6cca8978e
+e21c2b06e7b3e48fba978e2a7d186e563c088f84aa23178b60e4729ee87d
+67b1091f3b6973676c1cbfe6530eb773c62e2c2497014ab0e8b71a1f4e86
+a378aa26591511bee3cf3d64c94848582e1354e1605b6457823f2c5e640a
+d3802946bb2e7e8e594e8c04b430c2385dd40746ce8534f50842e74d7115
+f3db0c72d1c9c607c6573b094aeb73b7a79876cffc3e2f8c9feaaa07d3bf
+ce05b61f7749a8793be90ccceca2d7077f25e899d3331fe161a7e86c8424
+95d584c6e4a0880b2951d8a13b88c4672080a0b1be36bf47c3ace7288cfe
+41a8c1baa6f0814a947fbd6b3aa72b6c73a8c578ca51ccc96f2352316c46
+7bb960e981f2b6485bfb44b577e71efda16e7405954bc7c9f0759f5a9f1e
+bcd2fa9cc9648d5831a68887f41b15081a204c24b4b992a231def9e698d4
+c3a25b6f5474f5be6a601f2d337a58a0d21ff37fd91eb86d1d738893a03a
+69f0cd743f611cdffe69db2c6ed0e4611d56f803bb0dc06e7fe85a303839
+612707647b1be9faf8d684122ca9e5cb8bde2936d3f4ff254d31529d7538
+bbd4d35539489f9e7316f24214b996bcdcf1818e749a71cf0e8845aa1e2a
+58aa62a48e02ba4564625d20aa220ee719608521d7d7a7fca0bd8904a401
+9819d371f3f59d46c1354e5fc1a6e5f79b20cf4aca2bf0f2de73da193a6f
+9acbfe0b4731c4bcebe6d96fe822965de965232282a3a130361f188b3aab
+da95a8a2790d9240be008b6a6de4bbfcada05b6786b9bb8e0dfa0c30043a
+3b07ed46277e07b9808422c8ed16758b9c396f4ea929d769785b2c9568e5
+70a83b989b25ce200f1727d41e2b702e7f88f1784f4c83fa60a74eb26b2d
+a95126e508ed519a61cc151db6804f61826c5f86d8fa89d06e526fed97a0
+db88edb432ff32c1acc9b622eedf601081af7b963c9cfc1d13e4a9c74fea
+0a1c8e3d8653cd92a944d4ca6b0d306619afd503506d77732d6514f604be
+4610c2560931bde0b40939bc1d126b0e97f72ae1b4a9252123b54f7a27e0
+cfa4425b4546526fd741ca77952b10d13e0ac2e32006a903808ff0cd013f
+936238c74cc75fd915244c56a8412f37f0134840347699508d6f3d7f3203
+a25b7c70100719582cd588590ee34b3ab13e255b613a6d00386a0104cc5e
+d2c646f09a88888d3751651d5646c5227a3c80e8da1b0a331121dd2429f1
+f4775d30564dff47d01bbe2c6c72ce4d1fd9a2077c04d2b0274b8916f6a9
+d1a4a6964a534f47cf241d5a8e34b23f85be9acffc2fea961f277539f215
+f8728d6788f67beaf45502839bcf23d8763c3949352f00c579a9a4fc408e
+c625e310dae61512dfe6844e82d36a2f81709e1f05b38ae9c222ed62c961
+ee63593ced7aaf73ce2ed3667740c77b309b93eefe1b4ba65d48575a66be
+86743dc9e5d3c2ff418d11f7f211b86e827ee1dfc3613e7498030f070505
+24536d1f8a94ddb6698be7b963c55cb3f74b676cd815a7b3df4b1a0ea2be
+1b0b9a11ffbfd5b1fa49668aee14629316af436a0821c20beef7b3480847
+934a99f6d85b68f4ddf8859a754e009428af89a90d1852c220a607ff0806
+e8080726edc94d691d214b4521c147c4273aebddbb4a697ef16448cd9b2f
+c95293305858decfd406b89b9f3fdae2ac579e80cf321ebae5701fb2f7ca
+d8ed04b4a63115886d45d6120f69aef1a21d80ad3c2d35d2899f1902242b
+96cd349e0aaada40f7a11282b6b52bdd97708e58dc5e2d22d1153e5fa3f3
+b300bcdfaf98dec2f4e3c82a1c85f985735f39874f557579f422664e07cb
+e19da680efb0fc82c323ec5c4644c51709ac8d674608a8043c91e6c7988d
+430f10ba6ce1fc7fc0604fcd8f723895250aec36cc35b3fa14fe2a0d2409
+5dcc30b2093f2298f5f0a97676a0be66c3dc9adacfe2fc0f721a20e945af
+c1096a619075d5e9a264c796ec6c90ef1aeea8dc089b44ffc13d27cb2370
+070a52d4416c53f364393e46edd7ede00799960ce6e0d57e4909e88add64
+bdd2b0ebe2d73fa6acf8b40280daa0637e705c65aabd523b8815f22f23e9
+ff81e7829c7e4bc980c9143aebe1a04dc0d253396bbb7268bd5aeea356b6
+10d5dcee03135e00ae34388251f31714a1c40e182652c48cda2211a22cb6
+f02490e69a44cecb169754c53b16028d352e0119f5d5fae0bd7ea1cda647
+12a6147374b64244e21e9ec9f0d1381ad22d5b6212b26c3f9aa5f6045f25
+dd9f5eb4489ea39b1945331ac70510c5752557de21d0a6cfc1eb10a98fa8
+67b76da6e4249469f591fd154d39e89364a43db007aa0d7a911cfae6ce2b
+557997fbc44f55a27f622bd7b8b10ec9f5d10f2649a646fd964ae1b111b3
+5b46a252c4dee44e7426eb5739f24e8a390694597db3a1fe7800c97e5955
+8322f0e49a0cce2ad94b1e2d1026afa771723e3f523916f55ed866c9fb4a
+2f759651c613a2cff362028cdf9d38f05d4c7c6024c533e930b64b099fb1
+af04b01f5fb9ca6867e6eff55a772c5391831059987e10cbf987e3f378e0
+1329f73d54dc0484177d3c3c06f67397955ff1ca4ef8ad1606b70455255d
+631a7d6eb92bfdba14a0ff28b2ace7e81ad666ea9b3a0f5a6ba3b5dfe350
+44fa4b3d8ed956009c60e98cc132f2e84967f4a98a67b336d5ee7caf7dd1
+f74d1fa08619941361fa7312cf225d89cef97e864c8369eafab94d97f056
+5505d825972b754f6729596eea91210b75dd8f645382ace36de60819a02b
+3b48dd00f5485f9264f9fa926d732e2c267b0be8ca98526f124f97efdb86
+132c5ef16b103908172fc51f286ffe45ff253512e0033f037ff182ba536a
+9eb2df2d1db257d9c86c46e1b002fb32ac70ca9462e6eb48994752cebce3
+9f08abd4f4b0889283e55500702185a841e328
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
diff --git a/fonts/Courier-Bold b/fonts/Courier-Bold
new file mode 100644
index 000000000..b9f5f82ef
--- /dev/null
+++ b/fonts/Courier-Bold
@@ -0,0 +1,1652 @@
+%!PS-AdobeFont-1.0: Courier-Bold 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file COPYING (GNU General Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Courier Bold) readonly def
+/FamilyName (Courier) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /Courier-Bold def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-43 -278 681 871} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020946 def
+currentdict end
+currentfile eexec
+e98d09d760a3c22cf119f9dc699a22c35b5b35ed6aa23593c76d54cabb5e
+942bf7d6dd84f1664b89699c74b472de9f8e6df925f6c4f204e9f1c639b4
+dba988ed2ac419ff2b2bde605b8ee3264edd66412d4f21c64ac522bdfc7c
+5502f9c3f3e5592b3b2093d33c9bfaedd2d49e89aabaa832e23f062e91a2
+5032519d1868816e44b4e0747795003d7930299d6e1e2a5bfe0d595dc97e
+140989ce81d8d7f852ff9cdc7a1b1b598c69131dee005b415805a16d8a12
+3e6a2153daae5ac3449a45325631b26884c3dba4cc4f3aee0dad2907757c
+38746c947e2279cf35bf77cb28bda80e2a1ad4b7a8760262b6922d445d70
+152e2bc1747c734a8c63557dd042f7dfdf15714500691c843a6cab7d419e
+81febaad7a6fc0a5d78bf6cca52de83b6b9f297caaadf2318311eabb9d4f
+b4904e2037862be8eef5101f8723cb1f0e5a1d822d32210c6c742311d9c4
+5c5ab9c69dd641bf3b15ec3cd3f7bbd331caa9324279943c53fe43dba9bf
+08b854f97c47c79b6c241fa72fc1b6b667ee8c41a4e49e903110ff9aefb7
+5e10e007be387d5641c74ec987aef698b77eb9de14aada1850e45b854a2a
+5c1d9446910aa12bb3612a19b2bde6dca1f480b787ed5ff230ff40c3e1aa
+0c0b7a26ec3507d303403057d4b029565a0d0e0f8a3171aa88fb796e21d3
+f94cefd66479640c3bb43d915bfa3af6f3916f2aaae39dd4317563c226e3
+61ee0dcd828f688724bfb2a5ffadd07d1049440df6068a7d75caf8b11bf4
+d52c71c4bc22856d50956b3b892e2435d0d826801540d2b89383e14dd586
+03ebd7ead33174da5f0cd69391c18c79cee94a2f66bc5d3251a8ab9725f0
+196c6cda25a23e260eac31c9e8589fa4c03a4a98e41c2d53f2a0139f29f8
+b72f59fd64170f0271c2cfe03b618252daec5cb272e0db98566c34a6e93c
+421b92eaf5552d4ec6d08432407d44468b5c5aef4dd72ba63e738eca67bf
+bf4bff93864e589f73bc24737c044bba551a41c94ed39cef3f9292dd8b9e
+5fab031e7b392f802611b72aaa6a0cf1dbb35482650bdefa7ae93b4bd621
+0b8b429e9a5e53d1c1c1e4306f83ca3660abfb71018b1dd39ad40f821f88
+6fb4496e31dac11cdee15ada9fa87468c4a4e9840d9d4f5ee6cef4ca0722
+38452546db208efc3ce27356df02f47b22c92eab5b6d69870502c2214d01
+4d6c3d6e4595795b2fefec32348dabf6da6ce51a95c73b4008f0487abc25
+b2d9c6f82a9042d07cf523663083de6aa22a99e11f21127b9c618240f2af
+8e4f5297effb39182faa66e1e357891bfc37df032792d3c7de5a16f43940
+71bb4c54afa190c5b3fb36e7a809c6b65e03f1f1d6db9e485e0dc5a90d60
+9425a985fba03731a0fa9297b4dd5359f8e7ca7146a6eeade722b025d10b
+9fcc045b2e8afac2990da3a112217f9f10866856d9ce093f659ce5eb1066
+36de5a60831a6103a50105c562bd6612c741d529c5c10f6f3e230253164c
+6f65de8b784a9d6a848939ad7580ff0e077ebae7e92450a25490e0a100ad
+eac5225ef45f9a69da534dd649cabf392010cfd8b1dfac4fc1da6fd8ec70
+82c97b30acdc76cb55352057d6893081e9be58c33dab65c69e1aaf0f0da2
+0c3f4013056832a6b0a96f888719e9c6f899b491dc190f74896a4417b9f6
+6703de1fa0ccc70882bf613bd9e362de9f9085c5bf5d8edf64b9f77dce25
+33f64ec53c6d7dce54ae812c0426f70268229bf8f3dc54d583f1605d4e95
+10d2452aacf63bfcb630d796357c6a3bd7ab83a4c661e8e1b63d0b014b3d
+1bd1712e1fbdcc739ebbf35b81e2b32d0517eca9adaa1c504fac1d374b5b
+97c6a8adc41eaf81ef6581c6a8522c2cd145be35c8758391abefb4504e5a
+85858019428dc2fb59d25c95792da6bf1c6e0dd74fba9dd74ddebd475e71
+e625f9db53600369c23f69fcff80ff39767bcd55d308291d32a0697175e1
+1750ce440e80fac6526465a5814897382ee44fac82aedf8e3b035dd4ab9f
+fec2f70e9f744fbe8041d456e3b8f7b12af06bbeae2dc2419871bb8c7cc1
+3edffee6b27e517147c9849d74c89f5dcae2cc2b9330891078393906217c
+2ae704845ee7e519052da05798d73988d2c77ee471d72fb10def97e1353c
+ef2633e1855a2ef29c3848d170590443793248b8b84ee36a33c307fee7e8
+e4c02897557062e32da79c001050f22e9c9e8acafb45d7afff506cf43357
+aa85a689d62942b7cd3910f4538f9a5c52b9614639ee4d72389630091f30
+f85e275d4f08f395887ce66ccdb6e380a93b0519e271339b1c993b74e760
+42fd697b818baf83ae980eaf3ae0b8065557aeff5178d73e25e8b728e94e
+dac70539048fb10e6c7304978eadc4a5d3090a3837fc31b03fbb96d7ed4a
+e3c0948b27c0122c7fa4d6c8095296c3162eddea27a9997e75237691555a
+8a575e542e2d40dc1e20f66bf28c3b09bc1d4612b97310630d01c326d8c7
+2efeebec8dc24fdeb0b8d5c9945385a47543e6c4960a02aacf0cf5b01f8a
+66c7cafef4b88111ee5c79a76b0c949c0391e2c870b30f3a59ce06c52f95
+f6eb7e5aeec243c01b50d159a1b817dda7f6de559e13d63196e81e753264
+2e0834f9b13dd10ca06a91943b36afdbd7a4a26181dfed9cc73752982ecf
+c5bca1513cee9710990be028151445f2e2057457a2baf7e7b321885fd591
+cf4281992533ae0e4d4fdcbbce6539a4f26f4ef00e06d57884c77a9003c2
+16c0b65c04da36d68cc569edc075eadf9d7079e0f7485f32e0e54627db15
+39d4493a5fbbbec8ee69ec7f852822c51584a2f52c77bbba6752ceef68f7
+497f61e4a2aae33e5a630c0674bb6dc4c31d58e12d3f95cd3383d49b7bac
+e7a13694f8ff6ab5a7a683a94e9804c20bfe70740f600e2c5af0ab835c73
+a55f7f681d4292e57cf66198f1f3af82cf336c331f091a85796a72943a13
+0c3466b4229d4800d7f60f439a327f32afd0fcbe141f653dca1c3bffdb05
+509ecf1e419d045c56ac3a90f52700763b9309d2e86e0ad21a368d84ef4c
+077899ee5cf201365d3d90de7091ffab2252869ede93fcce320c47fdfab2
+311285d5b263140089a9b382f33ca61bc587a57d906c5db91e7a675898ee
+240eaede53b28bbac103e0c76df8b12c62a3937fc1aea81ffc30d69793b4
+6bbf32e1f05f540e2af2d7d54a77ef02ba9e5133c2ea31d78b041a1ba75c
+2d6a7ae1a2352b6101347851164360f1451db5e3e91fea53000210505cc0
+221c7c5190a436ac8b81e9a40ee834cd0fde045b0d46aaa4693df0370a98
+04ae7643d1de813cfd75cb785884d68687e8849422504e4a4f014ce400da
+6c65eebc9d9886dbe502ccef99a7088fe363a185bb75f70b022311917c2a
+63e2e41f3e9542cf2e4b35a7b42e2503d6725e7139c1cfa31c3c54c8420b
+0ff0e17d2f52b84216ab127e7c10e058ce02192aed9157198dd471f401d2
+2ad5efcc80c26a76f1babb2e40a4b8257ffc80a71e61cb8db7ba3fe036b6
+a70a9d58fd59bcc1696fba1668191f45835f703175c2cc58a5f190a1c7eb
+8e481b9a7d0d52b907b266a3041d20617c2c980809386de78261b9cc8c95
+188ed585256db375d9c16150d181e2f6365a6384d6f05d13d485f287c45a
+0fffee0c8147f02b65128c59f7d34973c6d5598dbc3d3bdd3614aa4d28f3
+3181ef9aa67b791a884ae0fb62437ecd42d1766f45dba8239f7b220558a8
+94548653cf8009e774ca4fc93237ee9a79ec3f58870313a0f8ab0c9984a3
+d00ceba8dbf3dff581753f75c4baba662175c52e5313e68533c26ac08da9
+888699ce6d34e311f71724e39b6b7e7092ff901b94257831d83921875794
+cfb5c62c42b8b0b2975aaf8854373f9718877da7a9bbb3dd0279a2bfeae3
+55e68a113859646560131d7e8ecbea885694acb6501713ab38b1c20d59f9
+0b8325e2c9e1792ea3ccc740d18e89d54fa6327ec913e4094304b197ff22
+80c6a3169ac17909a5bb002ac783d567d51da8b77ba223982c816bae1ece
+bbb77f871a2d205d8a1e74082afedf6b662fb4159326da561465d1848fcb
+7fdb8a0b33723525184e1069987c23e4c41ae224a0e4a338fd33d9f4eb5d
+718d237af05bea5d867f3b16472aa34e9f705b5463a09154dfbc633d3ecf
+a46b9986361bbdd5bcd3a8e94880555efc481985d6dc64c77d05ed0aa826
+490a079ae4d1ee011ef86bd83f7f9e65433a48dbf124f15ac3da0d5faa6c
+6daac1c4feb7db8b844307160e2281ff7a2d2bc6add43b354454d349a334
+141b4b1e29536e88f289e5448e5b26813ce07432632b5253393f66796833
+2387a1bccb98503f43ab4cc90b12e10f8d7c6435aacd62fc8ef32fb37d13
+fa0b0ff18ae20a6f2f2fd6394d55a8faff09ff91abc226412b0051c282b4
+b49c558ab001d2496dbab68e6653dbb74d210302a78457eb26ecafcbec89
+6fa58f0448387d17608d7a2313c222b413d3f32ed29b683d9dec7927fd93
+a8cb0da06b2e17940d195f7cafc6e5edcb31a8e00187900312ee9bb10205
+6c15ea233e2d43b7c6abbde44ddad3a1f2cbcd730eb5be1f3691aaaf2efe
+94a4736e6c4c753afbe1c005149918a4e5446b31ce005a99d64125c9601c
+b016a54d3241ab21eeb505c4f1cff6178366b3cbc0cbca2772db7d5b3a76
+5dc6db8b7116109f5df210a820aeae41636745344d07cf9ae1ab05a564a6
+a9c5eed8130780e93e0fcb2df9ee1b8587d8facbdc4e1927315df3a8816c
+955f19417bf508ae0524cd04ac53af19619cd938495e4c7f02c26b69a091
+f2f9815e4f8e3b95a610c3ba14a6d7724b88392e6b5edb8e9c333e262ed6
+82f249e9df395b94e7db994369ebf559103f9bde51eaabde3854ad5e6705
+1fbba7eae4d5968d82538732d640739e1f09d5c0d3d6196b7f39990aee1a
+43cfe9872ef0e98bcb8de9377416255ff057188d9f157313cd650451faac
+8a1fae3d00814a6aa4adc548177998cba4d0f1fbb0c7f6b3773260e6001c
+76b681675f5ec4884a166db439eb25f5d5f59a7124f0b2ed99160e3e779c
+b63ae2a7f118e90b180b45d097bfdc0bc95bc790fc8d7b32266b2fe22f76
+87502d6da4e351a7778cbccd31b3c83250c3d21b0151b77a05792ab50a5f
+635b2d932c312eab4b1c06bdff13cc6068e141b03ee8d8638e57d59ca1d8
+b8ccadeac057ceff070ff7fd2765b08576774c3ff51d885aa8694e14dc5b
+ff792430d9298b474e0e1cdbbd4b092341fbda48d12dbfd98bc237e1aff1
+8dfa7935261b40906e20738bfdca16b5842e2a1405b22e4990020448bc4b
+930912e4bec58028d9d86e7e15a64cfe183a94f81e2088ffdcdf5326bd86
+83b303ee08450941ba40646585043d863dd7d4cf0b74e6fcf96976dfef5d
+2616577636a468eaa1f41bae3d82f70160d02b28b318aaa9bb74567460a8
+cd4306667786f6967f39bdb9f210b5a8068e167b6ee194b0ffc9492ec4ef
+e96625fd470039a59551b282844c561b26851b9af6b3f3a6fe9aef52d42a
+81265004bb64dad894a7d6d0436729330762585664e8e78e4cfbf809919b
+ae3e4ec70b61444f8e68af00a419ebb7b5aaf66866a7dbe06a5106e9e63f
+6f19b0417abf32ab22b02bcf0c27af0e898533115fae686eafca9628bad2
+6318f254dd54e876736cebce827de16fd34f2df6afc7a9f39f5ac50164b5
+0013f26dda832d091ee0f772d9199d315ebf589507658cd7fcf22989718f
+2c31ecc18209d32bea2b29bd1a88202a7fbbcdca2023c79d07b886b675b0
+cf820450d6599af701c1f23ac1ab264d9c62352a2cf2db6885ab1b771aa2
+f2d037833454d0c6e6ab9e7884bad12959f9d693583432515e9c4e8e1785
+1f292b5859762dc093fac6d1c4d75f83e6c47cf73b5fe390a161ef0a2942
+640e8683c33cbee292aae8cbce89e2c1e8dc99dd4bcc9a511a7f00455381
+9d85c390eacc9596e67103cce2c2e86a4db07462396620c11b6e391652bb
+358f82401a7b47fc5693b898df7eb1f7a7df06be166864b82498e7a4a52e
+5d78e2b4e379cce4ef1aeddf8093671378edb46ab0f1aa7b79fa1c0e0a12
+4711cae6fbe2b56a74010ee3696d112969b81f3aecf99bab36fa9317fd9a
+2e590a8d1cc447cd24c42995d7b04454a8fde2e589252027392343a11785
+780ade0b3eeb8bb20b63d1bd61be223c44bb8e1353d0d3e37c122aeabe22
+45fb231783396f758c9e4d09058b8f63937468b8648c2764a90b5785a729
+1600ea0699edde3fce774c77a4e8388cb3ae99570ecbd9811ee8f973a6dc
+ed78343d1104f0a10a9bc869ea473da3005d36865d01598e1a6909b711c3
+77a4b4bc536a581655a1b2c2b995e6632434cfa8ef7a794a0e808e6b53d2
+ce9831c720ca03f28c7f0753aae26f5d6a6cb086ea57c92589e9583aa6bc
+3c119436870043247073287061f44efd734ae7102c9a090907e3b61b9dd2
+527cabc63f2f8515e3f8ec022ad88c6844a731d163af292c8f30ec988735
+8f197190cc6933745070799581b7a94f0eac5c9356799ea0f201bd54d1b7
+2aa0f4a50b2851d69e6a2642b762a88870319a684e9eaa9a1b064a3bd2e1
+1ad4dcdf3a977257b6ad3683d4e9f4f678efe74d4a4488274ed980ee6efc
+072708b5358a1da39464757670c3a12f2bcb2505d8bcb8d46ae5a8c88b9f
+1754896d8d7eea8b1d76d8e7dedb88d67f796f76c96b2eb6e0e7a8d10cdd
+d649ff25850fa3834852623e99f264a8daa93ed145f1b6512a75a3ee49d0
+ebf73f90eb6bc75ecc057465af931b300389073f54e5e0a5e1340670393b
+8333548fb4c94404b16d0813a8481425e9ad09be5d8a4f3eec6239f7b141
+a03b428d45b6e3c981c3ee32a065f2d162e25b6bb79e9d46e1838aa510df
+9d8c71f3dee637a97c453c0c26ea8af68e3c004c8de997a6f5a0e2713af2
+7d8f98031233c6bf5ef5c103e5af0862ce6ea9d598abbd08350b18d9ea84
+738d7565cfcfec7f9743b5de7e9de5495555390b0ad89ce01a5a05d6c53a
+235aa3d89cf329b2f4350b0d98da4d4973cb5954c6d639ce367e68776d5b
+a8df9e793c52f381570e909db6121be93919c354722827fbc24aeff4bc70
+fcfc4fb7f49759a6cf27dd5f54efdfd060abdc33d0d1f8ce051c0c026e31
+17309e09471b463deacd1cd12a345fe382b8ac4ecca1feca0814a4f74bde
+a00d08e65288b8d05dd0c6d8b2a323c545e646ac06e52f5bfe40e25a7604
+fb2bf49b2bf6527cc4f1fa7dbc9e6edcc63a3e5bd951a25eb13ff3bd2446
+c8ed32670a19f7d1706994fad9bb9ff448668951ca02edbd950b8233005b
+aff1768a1cc2a44da8e0125e637a6bcb51bb64af227f6a3f7c7ebe4efa39
+5965d49b13b8aa5f1d41fae2904d82092c6c2588b38182891a39d72f1eb2
+50827963d6ce5dc80493b3ababb911189a6b73ec0a74d9de15f0dd992fe1
+1ade383677d02792a720b83ea21ab3c631c9f7058e69749306a4095eafbd
+82b8df219e53243f7cf2efb3c67e169f766302a2084d6ab6dacbdd12a67c
+a369aaa02d22621481c03a8d43763d62d2be3262d1afba823cfda91992ec
+f80cdd3656505c5399118ca13502d03b122c20a2bbbf80aa6642773a6255
+5fb7cee5debbae611eb2d443f2edc24bb153dc634cb6d6b3724972445ba3
+adf97ab075af2a95d2f1bb74cfb2db1e435130296cee19bb8c157eb8db70
+bf5cfc1e791f3531d3ae33554a4edf16070a731bc8b7c74a84bb3be0f2bf
+45560cda74b4c12dd718c62803fb4f4aba5fe89d6f7cbaafcfe4bb518031
+dacdea2ae6c8d0c03bf60a9b060ccebb4858e4cfe1271e316bf7afb05714
+c26cfa91bd96d0622da31ed625533b2502064eec23257b4785f4f0132f3f
+44b0c2b83bb642dd8852ee7f3777956e984735f5d16175c4a27e9282a4e4
+ff0cab7938d921d33dc7e8b62ae24a90b12646b3a5fe88fd944d8309411f
+6eb3031abb67fc9bb2889aec45821020561c1519243773b448d65bbdadc1
+5a5e155b8d1b368cbd97b756a8952b428a358c398630b46e8afdae238593
+c3fd589ec46b77b8d82ec7e1ec5a50cbc77ed54bc1e2426c61d23a08581e
+c1d71c0908f7759d1da9241b087618e9f756bfb86023daf9a7ca0c4eff0d
+45aa95cfde5aac1977911ec6b202bb47547e3b5bf3327e95f7e1a4863e5b
+904af4b37a527e34282cb659a22f85ba406bccbe3070ea53f65a876b9d1b
+9a1096412fef8706be743153d4dcac1681a40a2c265a729121f2d3fc9efe
+0b5c18e002626f3023a5ea705b47ce1a5c537122e7c35af7bf31f66d05e1
+aa3362e68c1d259fcacd0079fca7ef501654744e294e6818ca3badcbaeb8
+8d44319fba9042e25a8250599a8eed5e1c0cbd9f739b7db31c3b18128176
+50e72c970d3090f8325e5ca01fc85e5310787db8dba0ca26d77f403c062a
+647f9f998246f26422374859de43542076b459b7fa829d27182324262532
+99fd3886ac0448ba12726ccab47af3cdc60fb69dda6513c83e0d1277ab88
+4d45ff3976536a13adf80939cf1a1db0a6347f9a4f76ac2674ad49a46ef1
+d47ee4fa717c493131e0a5212c3d4ba134a7a6ccaff9982abe9f792a9179
+87e59dcd1984b5994c8c89b3f9f0878cc3177489a3b9b41e44673bb253ec
+deb2083f4293ed9d24223cbfef26cce564499158482912879082806d048f
+1ea999ab3cb216a5c27d6027468b8aff4b55fb319fded4ee2d308c0f8c96
+fb7feca02b7188bac0ddd4bee03a577e91d258eabad887be25e74c296f63
+bfda0da6709aa66b814189443c8b942be557f260606e0e2c5c0822ad4a5b
+33facd2b90ac826a768ccc37d2591dd28f1e016032bae587b12849d2f9e5
+60e3f8c07cc50f256ff209c9cfb36cf921713e79cf02283e14e52cdc3ada
+d81e2d2adbfa6f1a2c2ca81cf97fb68d61f8c51f8c2d70c59a940dbc31a1
+c0401d41b9c1e5906e6f9d2d4446da96d36a0d4cc8977e665aae5c431657
+39b2226ba59807a4e54fe9901d9e3dfaf531ef2b29398d2d10c24fd2529c
+474469ca0fc17c2c06f670348545826112e834654bec7f039d11990dc823
+c479caf0b9ff71f983457be488a36a54d9dce40b832882eef4b698bb1758
+5ab2c981b5b42d99a546a9c50b56227e76786dbcc6a5728009a707a5c8c3
+9f65bc6d10474296a93833fee38992deda4cee623ab3e672737be803e984
+2003e729a97cffa1a122d9ab0bfa587da67ba7005f51278e3a06a752f86d
+5a8b2f0d7a871ea29a2c3b7260fb62017aa44a696d3c4566b179c9eef15b
+67ed2961683b8417500b6136815823d50eb25f68363adcdde84ab6560227
+69e776795bd5a97122755091c2353598b5e0e5ab0d368fa34cc903993089
+a4fb5539f5da5c59babcf26470065e6fb8df09ef54475a3651550331faf5
+093f96cee0b9c0e94a894acd650d429672e1d66ad6a0027b7d24e1df6bb5
+6e9092928508f4e356275f668ea61dfacc1bd86fe40d9629b8ea84e4c337
+88ce61a3fbdef32603ed42a31c12817dfd57561a1ca265fa093b5942881c
+2a61d2c536bb7d6941879ef6371e1aca84fbeddfd0712f6bfbdd69020265
+aa13bfc463e3fe44558fbd405c69db3cbf18b5ace6a111767f766b8a730d
+8b0705cd5e46544446ff78213f9b2844076110f1717cfefbbfef27c2c17e
+19bd949688b30f0b4f3f23208331fe6e384d4b4f9bf47290f5941df19888
+f78271ed4545b076b96b4e21fd07ca410186f4cb4d723f1ed2cc6c172819
+c346f547e74f99c1cf2bdef1df01afd3fad2381035d516d1f02c650105e8
+092702a8becd50cc295803140ed1ead5bd6fe180816cce1608a582787ff1
+bd66a511b044ad430b97227b61a4177e90f928dcf9c2db0521163be22b5f
+faf3300ac9c039aa436df8654eabb946f64b6a2c4e5b8cc7fa9c11d2cb20
+9b20b92c6e77ab808d474af0041eb80f0b6e635a5f322dd58e1194676999
+2a8e58791e2a08bb0dcda337e882ee421947382a10676c69404e420f3dca
+b6b6cba7bbbd806848fc80ca03eb3a6fdfdf5ebe800f17729f74d72f4e6c
+dd5ddddb891b3690554c04694d39e05f5e2a1dec0100cdc8f2fa39486353
+37d906db314a739f6ddbb748d048e59759c0e5bb93ed6f8313d3aeabf523
+545691769560b501f46f622962be61881ec339ecc24ef0d5a3a66a03d31c
+48be641406539cf845c3dcf4d8adab1ccf6ea04a642644dbe77ccfff9e9c
+e5546eeca7b5d11959dc32a1c09f9e499346b2ebf36c91554ee265da452d
+7b6479c7cb2474113d050fcec2b826a1b6103a1fdb4aed700586aa0b36ad
+df8fdfb4006beec2b075cdb86ad3bb56adde2e7063a3996dbb6b763c034e
+77ba04142e741592191eab60df5e6913ba69ad04963cce6efad86f260d9a
+ae0959be0496413c5299ba27f0c96dffbf5a20135a828dfa5bd116f1aef4
+075d1c4ba49eb90105bf16686869e6da641e3c2bb4b4deb164817616ba7b
+e9f1062f85384c1475185b342f8d10ce389b82e97803700e5090007d7521
+68bee8e937971e94c01cdea21364c05b37f60b86429005750c6d5272296f
+9c3be508d85078c98ed33cbff0411cfc16ee632034fce12ea9c060ec7a12
+f843c69f62779c779a1b514a2808f54572756bb8aa743312bfcb0130a6ac
+0d4c21f790369847adecf452ba675bf9b863bae1e494bfe82a76ba37e951
+7e5ac3418b7f817056fd84906a296c794f77fb8e266ab32f1fb546c9e97e
+435588b749c3d279995886f136b2515acf4dd303647a13f142b70652f7e1
+b587873fb85dbfb6b8c0eff6d40cea9a4c735a7e0a796b3892a40f6cef4b
+bf8f98c14811e2b5f72c20fd2d8d13acdd45728be6efd29abdca3774844e
+1e1c85291a52ccd541d1842fe987dcfae7aea6b546be6508baac4d1e1f88
+c3772f632197600522e10a08771012b39fd2be0dcd415cd93e59c6ee91a1
+3000355b9234cc603033dd74577297100892fb8c7745df45d125034fb268
+4bd4d46476e437656370e13537114b23575da9ab9c57cd0e7c43865049c3
+fbea9b2ad3587da4b5b021384115867408666c11c1bc7e345af1dd4a2593
+b76335451f57fc0621e2712fa23112c4ecfcaf3cdc5871d392fc2b3f09ed
+b5b87105b6de4bf26548925cbf4595bb072429b347586bfa436c10d254e4
+cd1542adc1f72c0a15ee0eb3e21de33ed4192fbce905d16fba1202e45c00
+7bd1ba5a5bf4f456a40d22d0326f3fa5f57fe5335f7bd2d74c3c62f33d1b
+2fb3c3754928f3bbb73396d1e64fc4f9cbf1a57bd2513014c4b49ff68be4
+162d8173ad1425afdf02a2aa32003db6103861c935e54655ed11aefdf7fe
+421d3e46c2324d0940a6dfd0667dc4c483be82abf8e5eddbde02f5b1a11b
+1ec4f2201ca9fda9077aa5be2a637baae83a18e0d07aca462fe53fab3248
+4c4d7929f830b6efd789b22311b6141aa20792c29698c0c0c9683827874c
+80b97e6c8fafc623f8e2776f34356a32c0e7613ebf491bcfaaadc476ec2e
+b904c52e3a65d61fcf4d3baaf68dd8a2df3b6b9958ad606dbc16653b1304
+f03bac8ee4993492879393dec1c3b9930f0edcba5542c22af1aa4d754f65
+3dc8e4f76a9298e0ae859c6c13f8ab24b3349c0abecec29e895516859d5e
+276c73fc3804d194ec154caa7fb3803809c6d669d86cb75a0109a25fd481
+24be0f89ccd2479961fa11144db0d626e32fee84aafe9ff793254c2c28cc
+3208e4c13bf3feef165de8433cd6300fc97ed20e0b482efa38267e0c19a8
+02a795c602a0f34d3274dedfc3928949f16dd15b811f61d682ff303c0be3
+c9b142e434897e2c25c96b9b313b4642e6295881a5a2660dae267240e8fd
+e3a4b58dfaa10caa5de3a730486727a40307b4470b94624512485ceecda1
+9c9d9ebb68825297aca37aa3e5bec4c497b35dc10e86bbb932d5e6a03f95
+0bf45cb19a9f5cf7234f897e163491d733b5510790eb101855b42d82d233
+de4656e4ccc15c70d3c19a367c7e8cd97712520831ff302e59c66bd66081
+92c29b17f125876a4d00f8404c745f36b87abaafb41b20854b8a71417a45
+be9a6d9dff71ac4935e79d30e6657e777bff19363d6c588829af564b1b27
+784bf9c5169817ed2183b0cbd4be72575dd484bf6dc8a9234f54bf079d59
+d5b82796cee38efdbc30d9f39d0f500582f25a729a1f86021ddc17e00174
+d842d05f21c4d6f5d0777c99fd99f5bd7aeb4a8f8997b6aea54a3c336c8e
+68585ab5f654648ef3056012f35bd4b322897777806026a0d405f0eaab93
+61d8d6754f1b660eee091695f39b8fa5f6fba1d55b33381a567447906bde
+e9892b2bf755353f893cd9d912bb8ccf1e0d30cca1c6f2d3ff552f56ac75
+c3c6e892282910da2df650723f375a68dc9eb64ca74a512741c4a652b223
+db2d25ca29d272ed2419944c2f33769926d69f291d2a462d105c53dee439
+9172c11aa0763d48401552ecbd9c8babe6b4da26e7f9623355e430768284
+fa9b53667ab67b06216c05ee54165892d5cc4435a0e5fe3db1690b8c7043
+26def9e9e31a659ae206f8c60cfd663f91688581a0179c9b7b9dab97e1bf
+5f24fda6ed339433afb20839458d18bed5491be9fb118bcd3361cdcf03dd
+f67d11767f7f7a421346dacf711d375bf519fc93753331e1a091fdf603ca
+b41f0e6c48e100e78157e07eb10b30c6f350a146cec0d3d1d0e944a69e85
+2092909fa54f1b4377ad4768fbebdf5334c8f1e326ecb154ee06858342a2
+6f3b58a9e0141d57c20df8c4766be3203ced1e6b24fa2a98bca391b85b7f
+572d49ac38e4482733726f56d5ef42d3c952db9db82d9129dcc30b4b2fcd
+d20fca70364907701bd19028622a3aed72569cd8307e23e48e6a9df04da2
+4bc0460cf88b75dee4379a7c003a6cba112415385c43058a46899d6302ab
+560536e59c67f462528a81213d9c9009fd3975a3b601410e989efe3a68e1
+65fa0ae6dd9c0361e0626f1851077e8ed9fc4cd766291c7f3df8e51e2eb3
+b8e9274798f32e2dfa3d5a08abb61061d4caf45cc837309747df9b0d565b
+34d0c04a2f9ecd64f0df422c7308ed27a7b5fb8a5e5d71c3003914643d25
+8895a0e2f136c02e5fc6659dee6c7822dac93f8e0aa4b5a52f09c2f49d7b
+9a7192a22fe8efc8f5142d3791d3e11b88fa8c9afc2fc568df02c40a109a
+b94e59cd467b9b0bd9f94003b21f522cb5c8b191a372ef5583e66f5217a6
+5d3c7baa1375d59bbd54dd9af7139501b74a2ba74b87db29ac78f1afa21b
+81072b58cac2df329f5a7f3edd6c42839db170cbfbfc575ef172b39c1859
+87141f257d0d6d909c1a95fe10d313b8c0846b80c07ed5124adf1d36ad7a
+f729dec052b2e6c61609211ee576454a86a0c2e6ca0c6c0ff1dabab49143
+8b326088d16ea1ff32e69871cd3f5a5cef3848b734ee20e2510c97c5753b
+2629b9eb302c488319e384166c59257eb0454af6961b87a7569a5c82e1d9
+f1bcd84379a590b4b41166a67ecff44890c105d16f3bc899b652fe115045
+983ac7f6b7d63b5339fa99cef588f822516e135ab40fcfaee90577bd878f
+92ec143bdb5fe5ffae78390ddc3f7d8361759dfb3996aa5dfd331d9ba36f
+2901c65f5e4a6c95a9400d6316ad745e680cf8729f23bfe0b11b148c74b6
+0c36c2fed2eb71ec5faf4d05ae962133c1b8776d1d57bbf46fba30a15f33
+344f26dd85411b16546e1c9dd963f1b334026cdb09ab973d1fa615381847
+1cd310d73575d3e03902f0bdf0048ff5efd1beb2e857f82084b743e10091
+d3374593ba944d05ee97bf0ad7568b45a95a24f49f0ba2d93714857665ea
+9ac457a90a63577f7293fcc0d5bdccdf610aa823f7db43119263fd591a20
+f3f6d2612412bfb5783db3c0865eecd1e7c2ca50d9dea0ba8a50a4a69ee6
+7899bfa6b11bc58b31c98a6b8cd63633dd6ba6e41aff7de644496942b7e8
+c33320c23f0aaa081098d555df9bf66b4af6cba3a71fc9fdb0a19497ea00
+17dfa473bff4ad6badbc6d971157ce98fe123ca2a5711ef9360feaa0f40c
+6069d15b5b224f32f74965d97fd48105f43ad74d08b0b2beefbcb3d301da
+be707da228e802c22734254ece98ad73c080dafa09df15b9340b84154a2d
+1ba6992fed3674aa9a9e002c4d40353bdf87edb73e61318aa003ae7b388f
+e9f8656fdf575e190509727d8385e50b871ccdfcd4fd1813801bfdfd7387
+48042133087e98a8c64083a4b908594dec38ac9c6efdd26f1e13cc59a203
+abd3887fff0638c51082d32a328c3aacca59e173d56d3b3bf27976c6bc95
+4572890d8092e93e35f188e2255d4c223d5d9fca45bdf433121f5f8bdbc3
+84f1c0ebef83a8ce7fa186d413d7fbde7a9d2818eee5a305a57afb635b8f
+f6635f17cb030b0d29ebd19ce29cd932034a3c0c0922c7202288f2a3a13d
+1bbe38506a74046dcbacf7d89a2001785f12f3d885871f9950ae34ed028a
+98b5373403bc1322d1f2c583a8dc11824b4283c233c8744fd56cb20fd6bf
+0ddf76fef1d0eca5a8755a2f15df0329d098033283664aefe0c59eda92bb
+25e4681182e20c008c73f9c736711fdf3c5ca41acc70f320949d0a32e5bd
+0bf4829de9484836c8183542f12bec32fceb5a3bfdbb1a193831cb7539fc
+12f181fab95ba610379821a9a02791dba3b2f154d13788bd248d3b9469df
+01bb9ffd8d69c10e347773c781559ba77f50c172e32dd77ade64202ea88f
+9b22ccff86f1f221741c4c9de7ee719c223860446539488e6ecf7eec8c71
+f82b2a3b54dad191dc7972eec0a571e839c733aebe2c557beeb5a69bffa2
+64d60f3f6d1af9fae5e6da55f9b5e54e29c978a6868c02f936b89c8b11ca
+876d6595861d293fe9a250e723a09716167f20c00f40a3ffab37b236cdb3
+691edafe967e72a69b87f69db6e98d32c976f9448575464c16f43666ce44
+76840b89c880acc159e7ea9623c9c49c4cae911baddaf128e4e336e41b5c
+76d4df9464f7a66ac0787280f27b2ea2cc03637d6a9e2ac6d28bcada2c5d
+cb425f99a0b7b7677b2b79c4f59478c1e0bfd24aef199621b2211783ccc1
+b4dc56da241203b399cfbc46a80cd1d172c25a76b55d0a070c00a17d9e22
+0019121cf06cee286d3582fa02f14b6c0ed78ae52b960f67d6d5331c4e6f
+29c51a14b401714874d0dfe0fb24d264e9f705812bc67b634ad558ec2347
+35566203199dd558fe5297cf1cf5cd5492c93056c5e0a71226481fe13e5b
+ba28b11394fced2131ee45efb37e12f0638352ea688cc6881bd182d9094c
+88552111bf87f88ebba5ae9679354cda6c8888b172d46635220fb98495b2
+6469002cb0575a6360c4b6909672ac06f70ec588df117bea075ec89e865e
+577a0def15804badb8d42ef5c6d6fb70ebfd3f49a5b218be90dacb7ab625
+353bd54e687c4617fc10a5d5010758c64ea0d6581f4f3d4fccb7b90ca9c8
+85b028d29f838a52ad11523310a83d61a73e72a9b12ee941c37906e37b5e
+3f5a2aab32f410561f3682a81ccf959ec63d96b89fdf96a78ab04b236e50
+05bacc7974f7c62eeaa245ac41958ca8fea6ad3fce5339e1739a53127964
+2ceba426ee4ddaf922271152084c4cd08edef50edbfa399de4972844fba6
+8287df1a1d98783774f70ba7655a9f89d64bab11ad3b55459db4ab7663e2
+ad5dfc78bee42e887a2e76b511a159812e489159acca2f0a249a412b1ee4
+a90a46dc9ff832525a9b0913244ac3ce5993e17674d1660563c6d54d66b5
+dde6b64aa76f003ff3533a46ee56bb913b6efe0e9da6fa4e5319b607d53e
+9d7d9636805cf8c3b3947bf195ea25cde547b4450a9eb8ac84146ef54d76
+93213061897bc96ed821fa57c0bda3244fe4a1eea3def679f45ef9f67e10
+b5decdd3e4bec89701f553bb4bcc6d4d1e0fb8c9090b9661196059b1bf1a
+bf1be04d6b74a5cc57e40971884911f452c33b58cb04f2c6fe3e1d71bf5c
+b13e7537d9fa6d65ea935ed5e96ef72363bf78322a8f87bf7a118a9deb71
+b7f246aa676cda52240974e6e9da44d622e4f2a43d7511b83a0126b2b92d
+0bf1b02876e523d9d0a492b5a63d96b1f47e962ee7aca6fb9d3f9aec47ad
+c522dae8aa718bc540cf5d7031a7d3d16f0f6ff33a9768290a90a5fc5e68
+95cff9dbab42a770bd11b787b5078db3de917f923c2eb6ea11e76136a8be
+e36eb784788ea3e2b9d7be95e6d4243b166c494c4b754c6dd160206dbaf3
+99ae4902d3dca7424f6d1e7c455d562023465d0aa9de460b1866d7a52b5a
+f74e923d2fbb49c4470a9e18497bd332f3658806ed19c6077f046c5dc0d0
+bccc1d40ddd20d1dd36627d5394f9d38159c84751b355a8e48754c6dd160
+206dbaf399ae469b9cc7bd8e3d141479a7012a045ff72d51a448fdff39d7
+8be6ffc046e5cf07644c7ed0a1b85cc2398d0f3ad542d1103d2de1f3b341
+bec7d28674961f6b7d313b85f908f24f4d18080ab2c46c61f215557c0d81
+fda6767552c20b037eb4c97e39dd51300a54cf301af3ae93dd0f958d422a
+58e668e91eb14fb295d6923ffd65a2da9a88fa3fe7f9ade3d733f9eeb54a
+127a12f0c791d09fb12fd026e09a8232cabec89a8ff39084fe111795518e
+c8beabcb9e2949d3c58456ff16dd187bc906ed19de8f6d6a2a639e1fd66b
+020c5ca8e69adeb77fc55c84ad5826b2919e09bdd99a537f5c92437aa9ad
+187ece2d245d29a9a0d54ff6ec7841bbe6d39d1e06b6ce3b19ea98823e0c
+31a18bc564dde218b924e38baf75299220b281cabe0c940b404dbcf54d19
+ecd6f22e99e9ecbfcd8a5e225d29d4535b20e4fb69b6662a3af13ec34c1b
+58b8684aa0c7ce8d84f6e711534861328a5e4673d4bd6cd059a16abfd8e1
+573b096a3aaaea3274474fb3a97d7ffb167837a37df2bb69f4d5c31a1bc9
+0f07b0458ef6c85e51cf6163a409d01f67513c5808c5772f8502dd958987
+ed822784d7be448240dbc2c6a9fb7f6885e34e0b842667c15908ce0fb4e5
+ecb4966369ba752e6fc2f39e15caf1a41e441a27d0bd5175e8f50cb46042
+5bdb499d75ffcbaa6606e892b21400db3becbf3aa38ee38da4c333c4263d
+a152f71dc4baff702ea1363a0940a5363ea9b51b1f2a71a1b9a4fdd19152
+7fed7e2516c95ebff0e7c2ce92c50399e18386ed3ee39a48b2da92501389
+cbc1f6501841e867f8b915a334a0abb7a92b2be3af10de37cba4823f932c
+2779c3b008afb65ec03edcec847e412af7787f70c79ac84c58014e8d0e41
+6446b36a50c9e6175726468d9f399a1861431a8bd311ff0567723aa35fbb
+650b173663ba31bff558375f740346216bffd472986ff37bee4aa3675645
+a83eabe1853aa061fb3614b78cc780a471c3c0f5da378ca90ce67f21247b
+c105a3bd4e4afff439fc158b9aa90fd0e850b1508355bf0152225a2c22af
+9e5dedf038f28a11a2a553128c945086e84b4a146617e905a3a16faa485d
+6a5749a7067aec3d2def0aada7436fb1e185bc66d0e30a7bb33af458e605
+ec978d14b6181d8d7e9debe27751a6f5fac11594f6605cbe638d9a98ab6c
+1c3f6c3125a57dc55158dba2bd4d36febe0a8590e80afcbb1340c5553a66
+8ef2d6f5b4305a9d8d38afbd5759209f9eb9cd1cee0fbece6de7ad2aaf09
+6dbe472f83389d743f0d7aadc6743f7646f7bf3a9f73a23a43f37d471a3d
+6d12de84e83d2cf5b41e84f1acc0cbc4cd52d0cec7388f34ead47b45692a
+4918b365eb9f6e813d9223a95fec8de3d3ed7ec85227f8217212bec21893
+053f74e652bae9299e709fd25b9bcb82e860c0c56bce1f787129628e2499
+130fe6ef76418eda7cc648d769c6f54984dea92af4776ebadbe161d180da
+9e5f3d65cac4a7a40ec3a3a7c253581597b69e7526f3e10d619e614f0c2d
+c4f6feba37c1952518fec11b39fbd13ddc21fdeccaaf95ca8fb8d7d6089e
+1bcf9b574d9d8fe5c25a82a0b68b90f140b934eb585af7bcf8c88f9c1c1a
+dd745b02a7e19db4407738a4ed928c83718005a401b77a56622b6c8dcb3b
+26cb5f05ec5fba7f85b0a6a81a0d8e75880ef357d7ad551292d37c7eeabd
+7220af71edf267760571cd3e39af320bbf13c9ddd8053ef41cc81e425b32
+db025cc66649055ae1c6bc468bdcd6d69d3ce334d0b78c45785dfb709ff9
+a77a46a8c660f684d61b3643b2bc838b6e983d4950ae20436173e93db372
+1721546fcea7a2439024051300067137313b2424e1627e053532bdb9caee
+519e9d23ed670d2d5ef3674f225d51e1ed8e082c5fc9f5f9b934c0238cf6
+5b3dd364b466b2aeaea3d3241c59c9cbd3ebf9ea9a7dfa2eea9b7ee86f0f
+7e256ced10993751286150e663580abb541147835b9f14b21f528999160d
+492d9e74b01b55dab2c2e2643f5f20b0f4ec4e8a3a2df47a38fa1d36d755
+2ffb34c1d4c8152e29b7235508e01f79d41e1f2dba807e4cf4a5fc87aef5
+98ec07f4321a2c17dbcb23748bba86a2acdae6b93086a2e26d52b0a10f83
+ff41cd291ad0471f09e62a79bb75e18e680be66da6f3b2a56a8f61cdc1df
+9c7fadd0814370dd82648db161d85f8b2a9a0e51deba297a1250deca1af6
+944d89b7fba2f313ef3d61757dfb7c2801778f393b2383989f16176eee1a
+695f967efe7e04ee79ed936aa121ab47afc0f0809911a290a0fcafd2b0fb
+6cfc059ed1b7f70513a49410232413c1dcb607a668cc18043762ef224dcd
+d7b5d6211ac228650e4607367d4fb15959b8126dec175061a3ca7f7b01db
+2dd72dfb56756ece79fa61a7c845336ac412bda4347c582a6f5e25c9cecb
+66b6d028528f61f0b77f1bc603d20dc104c9462fcdeb290a5bf9633fe6a2
+92b52098f8503bed17548c05d836543f7329dcddb5cad7f89bf26ddefeb4
+912d2c1b3bd40f92aab21ae60fe8c375b960f99e499ae14cb92a5ddab808
+7ef4d41f4450a680c4549f33f2b650dabb0e06f418fb62bb234c2877ea7c
+566e3017b08cb4c381caf984191ba7dfa4e9784ab4543c20a1832e63d0f3
+62448cd2ee72f9a45a0cd74801dfb32c6df28b83c2183d13d37a21fe8f55
+354e420ad334e5e36ca113a1ff16bd3d142751b50c122254e3bbdce4ff28
+85d2c5e4d6a57a37b34a2593f51d6ad89cc225df6b8465f57b6cd034ce66
+e5e86ffe880d507d72933ce7c93964becf15481def7e649e4a1cf96d0e78
+17357dfa81bac3b335e5eb95be5f0e27aa51bed0bb47d556417fd0079d64
+ba1454ff9531c9b090eb6456a8e52544c1bf84a84187671f6c18f7269162
+bd002385dd60dcbde7c5fe69c34d004b2a284564a9cde4e3887ea78d5698
+ba791a710fbe92c7988b361a335265c707c2f00e4baa3855793fe2798ee5
+f3c1af717279ed9d860664996b26095506bd99c8a72ae7ebb45ad74af44d
+6ba45a2401c195e44f1aee76743407a12ed6bb80701e68a2ea02f0dd1af6
+320b59eca2c51a38f1ce6b8d1cdade6d9a745c219a311d646a3b069c44dc
+d226f4ec07cc1b249f651f1a3aaded284ddfc8b8f8eb33371a522823fe2b
+9275e2ec0f4721522a0704760205e8b924ef1c2df09e43e3985ac4d3d496
+0ef19cbc76a77a76ab47e41be9ccd032ed70813c2d4af60f916c510f9df1
+7c5bb577ffd1cd9c3f583e8bc0528b87874638621285df554d1f8b16c4d1
+183e71a22c772c362dbd1427980c002c3c0112061e8ee485d19a020c6f0c
+ae75194d3847585efacd14e2a1f5cd1c8d0e9f435edbc06db63f1dcc42b6
+b8f381d22191fb0f74e34f73b1be39b61d231fe723315de7074133b1e452
+090331eca04f6c383eab1307cd9022ab21e97643c5ff3296613bc3ccd860
+1f406578b6797a228acf6663797b7a7592b665fdb2832898c95b5b814fb3
+e45f678e37b709a23a5d88c999b8ee47348d60e358f7cf8ee72069a523d6
+c74e7c1692dd17ed1cc4535a42636f534f2be5c3b2b15942997a9b12ddfc
+28d44f215db9142e31f198c5e6b0d25fb2ea77bc0f9c8ca42d6ff67cb402
+33e8396ed168b90a3ae58027944665049e54f29164673c4bfcb602890fae
+dd938622e099b93f0939b2cad4da410e69c54259286c8ccf3f77384c4e22
+fc432b44391bcb5be60a6642970357b89191ccb4e5a85ba87be5ceaf2712
+ca6577a55419430c32bdd28b0cd7a6179e833712c0e17f700c31228ff8ea
+7446440dc3fd05fda08c17ada33296fcfb38cc26225ce290adea1d4e26b5
+361ad604d8b08a80636f5d0ea79e16cca7e1a3f3c59cbacf59d252d989a2
+49752d58ce58480dccad56aeeb0a5c75b89a8a6670b7dbf324c0887d3295
+d982cbf0e2c4212c697d91fa63d676d3042c68c1b19797b07591050ec23a
+ff48f141a6a7f3869dd3d9dc93f35ec26b388f43ad1bf2d106e11b35eac1
+c20cd5389511ac69973964c761d32c80e5b64e17c1072c8fc219286320ab
+0eccb5d6c5e2865c998eac3519359e41b2f4afbc30123bc2d0a0de19ee06
+d42dd254db2040e2a2594475fb01b90a52a4178f403bbcd9782c20c8f18d
+b6d72f9c6442f1d0c41b94036ad8bdf9bfedea0b96117a93f04c3c4206a6
+bbe324a255a7f18841d09f976085737b87bb897a984dad2cec5a44c38306
+48e373096da6ffe8e637671b820a62d31dcebb108b5a2b62374c746da5fe
+380bca1e486c3daeb1b9034abe8980b89e0a466dade7a0eff5c8364df55d
+25943937d78fd23bb599fc4d241c7ca6c23f337355d846c3fce08c82e21e
+e124db9e9f1b416e958d91ed2c21e26c3b6720d18154b8f3c41a0b9d035b
+99eb5671d93dd6d366322e15a5bf740c261ad4ed24e89a6df117a414ea0c
+1392691a58b068ca538685c646ff893029357fb8e567855720e803528dd6
+0040c6f061113d9546f2dba4fa83edf6732c6dca4338e14d3d577291b696
+02980b2bd8cfba079e11db2228e473600ed550ae05cd85a1cfcffb645e68
+5654ddcf891b8e4ed4545708f683f57fbc680a18992752f5cf2ec471ced0
+a16bc4363217f9767b684589803f3e6e9efe5e51e9eb0be493de3ee91c45
+61b92a057fb03ed4f0df610ee47f89efd4b1b0e1869dffe2cd55f0e0513c
+738a024c9e514db72c6d387dd63f36dbec694179a70bfe8c740ee2a13a95
+0601f003b83f07bbd035f8809ae347e589302c1f9e3f3863d66ff1f980c4
+8224591a762132041176334ec86f846fbda4db22ea5c4e13c9a80195d4c3
+a8379516f766c8078cb77f67467e2c11a90c5d287ba70e9197f9a2cf81d1
+34e2d939410940a6dfd0667dc491ec1a705b2d1433ac0ddd052b5d1520de
+a8d313bed949de251d7090c1efb589d8c7c4460df3f453a88fd966801a24
+4249b996ead5d21d7294f4c4b9920252b60b0e8959edd9bbc4cfd971a6cc
+e8b402eed87bac510d721956f7200e7b6eccc684774e471fc7777463e74a
+e1e0742f3a9f4110514726ad5d81150234358c95735248e06086770fce74
+9cf6034db5e3071af9ee634140303466baa467e5d5716263dd9291b4cfe8
+56f352334acd0af4c7d27582b3894d294ab287d3ca49b788d7fdf9dbaca6
+34f1a709eb39c3dc65ff732a3dc5b318c9e52dc0b1af189101f02498a1b7
+8f3db2ce24f0003f20957a676a67ecaa25f57adf4f1e22c48c66fd6ad0ce
+33611a35ff2e1fb51fbf4f8a4e19ea7f4cda91cbd64937a1679789b90baa
+549047bee22b3741e3a04d423e041c09afc847156f96d9452bb8e18785d8
+c78313e8aba3852ca8dccfc8c8a69d42fc9eb366296ef9f33b42582beb9c
+7f021bc6c9d27cd19ad3d88e19e8b8303c550ae07ad8fed1519ff5ca68b0
+7e9b97695fe76ba74d04a8101077620ee5a154d1e3d1caa090cb2b50756d
+ba0bf5c9fedaaa3e7869b8272fcb27b1cafdceb940d825f9b7beb7eaa516
+70dbcc38de9ee3b28792e30d2131c8f2f47f79db6ca4b1b5e2f3063e686a
+6d6126707eff0a60a8b7ca850b9f8f91414069354ff0ca285743b3fb3e70
+aa3f3e58cec9d01cbab862d1856d2cc659d1b8502a64b3f9892d018d700c
+3d92030b114b520ee285ff1766db12c1fdc5601c15345c6d33a3c4a994e3
+6b427acc7332662596f2d36f24ae18c15820d0fc53e165926f701599a391
+26331278e31f5dd3dddf8b0b504a6e4dbdd453630beacce725de85ee0c2d
+d759444a157f5e75c65188ad0dec71d7ca53fa5d8f6d1a3ff6486340d81e
+37d8cdd0400f54faaa350cbc232e62c7953a35495730dba62869a27ca03e
+85ec5a01b90848a5adcc9575fb0e60c3d26ade2d72886ceb3561af2b3bb1
+2f2eff9358d313cdce228a468da566f95a61987000720c62abd67fb7b9cd
+2cb5d5f74be8e0919dcb60a5364b1735d31fb3fdb59f9c22f0622f8df391
+294c0c2fed3bcd185c9d932f097bcb2c066b6f2b54613f30ee99cfe0b3b7
+08cfdd0565badf6e1e7b2041cf016e3b3ad1a5c03be3316033da091c0da1
+7473925e79e78f8a3f48ee2348b2a51cee6bdbe2a22244b3ffd8e2f1f6eb
+21a3af001d14e8954e80598937ecaad0fe81a030269f9aeb134350836da4
+2df81f22bf35544daf3d62ff87014d3d62ea58686e5e182d930a2dc3fac2
+588b49b660a22c3a55bf8c99dec4369d1d678210db13535c0fb346f0cb9a
+8c35b29652e763300876287ed1bd8ee4408d586f2c27f3c11c7cae9eb111
+3b01d521a91b24c52ed8f9e5e122b159fa7247af419a2378ea09a59d7214
+7396372a7d1e6d7d533d0a0939cec9a27c6bacc94bf8eba620a10483b09c
+a310ca41a6c2606e2029f3ec1e612afcd9e5302680d1fc088ea26d835531
+f157e9d4530cc97cac29d0de3bb879970eb3d781a222b006b0fae97e6233
+fc47d71f1ab194e672cc5163c4052eeb88a31ab3a3f9a59f8215cc729e27
+1e5db50036b810cd95cfd9826884ae6b1d9e9774747a0a9df039a77c7ac8
+3406b9d23af796412550524df48b18ac8a24e3c79c464a253fe332a3c183
+99fbacf4e2a0c66f152c9f89957a628b359070c773eb7c7b08745028825a
+fab05b092089a598ceeb34a1f40bcc61e05270be279e50ed9103f313a0ea
+b820f053b53669330e8f6eef4504a05d08178355f2c5162c0106a46617cd
+0b424fc04e3dad6ea66bf3f3aabcc63cd504a4797a7698a486eaf5220445
+7f0d1496d62d27a05717b23bab14f37a8082bf9b90b8bc82b19fd98404d9
+ac23ac738af0e624808613538d34f0011ae775adb361e330db975713b672
+e106228daa1c672eee1883b3a489e9f375143e9563d68d1775ba1513e779
+0a7ca7468011420dbe03f372339a5e354aee018dfea076dc8962dffbb443
+3506a5bfc44b0512e8a8eb7d0ba0f81f5b123171a69b2d42ff5cf8a81e89
+a831e006ff5218daf44f25f7e046c6b06bb1b077778652dcf6855253129a
+41884f86db912e57d7c4e06d7dc8a116ce65b628399cb21bf5dd8f9402a5
+a116548c5653a3083e412b537fd8324e6db3f15df83e0185cb8d4c5f132d
+df1f8811e574029f3efa0828f9223e318c0a838b2f9203f707f2254e649b
+7b78757e94056d90f65df04c47e73bd7f5cc5772c1253f1f141567ef5435
+87add907f206187b611235c634c97761e4834077e659b60ee0f9d37af855
+6018cf054eaa400a820d87b72f33137eb2fa3b8c3f8f0e6f21c281cb940c
+0fa9fa00589243d32795125aaedad9d7ceba399ba151f8af63bb3820bcf5
+e59c2bac5eb8a453c8eba8106a05e6c84603d2f91628878a94810ebc9c75
+d951cb4916b4a4c8d471bb739d26984c7e0a0dadcf44aacbf5983a54d979
+9b20298c242166c447b82e7552014a615d21091f33961b5b084cf7670a60
+cee6af1919e4d128a4e15509607caa802093c5668be1d5fd5403b9cc135d
+2ea6c2d9182835e4be3ed5c484b91448aab3ca396f4cbab5b6d2943d7a04
+7f51addf7dc9bec7ee4f952bcb09059b2da0b1ad56ba99994bad26ebda9a
+a2626b6cd881c6b7ca7dc96e7985d7a49c7ee9d035bbdd013ff89bdb181c
+1c2d078159d9059fd4459dc967af31310195a3cf9bbde2422338773f5cb4
+bbf7fb3723133bd398a39fcdfbcb88acb00080cde1eadb8019f151e3b1fa
+e7681447c9987afb4df465344590f47d20e47ec4285c5bf828fa3ba2e3a3
+3ebeb484f413fe1a0fa6aad97f900e27416302a6aff179260a206999db72
+035222b1bcd1ee30f6d202e25599b536dcb10ce7b0c283f2543cb7695726
+741d1a477e0c0db1d1ec085f58e6a8ea91e05eda30f0f66ed6f3a7be7117
+0643cd058ea61f649bcfd9db22a05e8c0e264ccdb0de198ab6e629ac4c40
+43280269f0be430d6adf70b881f56ed5112857fa0ea08ca2bf9e20989c12
+4a54c7498bef5b8d627bf0b42d5d03cc063f8eaecd3932956769367c720d
+4043d64b68aa996282eee296c7f441a226ed8159b166e1aa996d24aca65e
+ce80b674e97d6f7e392ad6bf593ab4f38a3b206ca0cc3128d847845873bd
+11b4293043a22952dab798352d72cefef8ffe015192ca8f60c90d314a8ab
+238a13610382f9f8ec1d8c1fcafad7c2160d7ce47ef373c0c55d7bae9b21
+148701f7a8c0e7cc82de5f26d7363d95163de187a5709820e37bbead6e14
+80246152f5cc865b819d29512b967a90447d98f971f4c4c28c2979d07cb0
+e6ec8d4029dc64aae3dbef8eba571236212600ce0acea3ea444e410c53e9
+e5f1d9d52215aa05e690fa3483cbd5451f4311cd0fd23f39d4e106e69d68
+1565ac01a60824243990cd9b034d3ed1fdb5c0752b5e64e2e417c6b64d23
+c8e45af1b45896ec877c2d87f88f4f4a85d0a407b1d1137f53650c134669
+649806886c2eb049edd7f3b676f52345fa6ef9ab4a418066e08a815302f3
+aa8ffb5fbb75d12cc3bac7d9ddabbac644c2944a44696f69d130e3278d9a
+e457c39c9965e27dce8a47966dab125de8e110d266b7fcd6eef2d820c029
+fa60dd328084faf8ae3b6bd0f570855bfc557e154c7d4931ba6d2e4aaba5
+27e0d098334ca38c9a78edddc086cd1f03bbb8e5ac740d6140f67d749605
+54afe94dda9e1bd3a55c4d591c34ecc27277fbd621ab9dab7c9699c11c88
+010ec97bc46dd1aad64f0df42c25607b55b88544455aa872819232372508
+516f71cfcb5c72b4efdf280fbee2819822cdbbea4caf86273a82d3f050e1
+42e1e0b8b628e34f28f43d57f70718498f4690dbb3e2cffed13b81758457
+541868a14d0c73b9da8f433ad8a7ff1d1ee38348ce1a6d95f625c8c87287
+8c46d87c20e9cd3d2c4222d45bb54d3ebfeb30e53cfa6717b52a9025925c
+efd17f795f78df3babda2beae6b2c1995751c334fadecba5981755bebdd7
+6034871e1445171a71f60282e6785059cb4046ad0bac98d5a1e5668a2fc7
+fcca3b915875fcd0d529a635d64cb34387cd90947d3c909f3d32c4eb40a6
+0f30c3e1f819bd8aa2a035dbc3ddb269c26270244c224c3a93ba4350316c
+664b2ce7153b09ead7d39bc49d6ef04c83703e8b74e6a0232c41a02a7de0
+5afe0e94dada8b1fe6208f12b87e00ef8c65d58b02466ff697d6467f66a0
+3f34284e6342b211a00225a607a556ab1d4c8c42a101ff675d951d0f5a75
+2f2479ce3ed7a4f84488d39f622ee53a54c3202d4e6017832708d41e5338
+13a8d67076421fc76eb25c6b6373f413f67b01d6fbc1a86d381efbd14485
+c715984a13189d77f70af8035c8df5d1d23bf2535245617911a4bd580689
+41e006e7d36650fce069048bb0bcf831d3606f3e730ded0b87a8d3282ccc
+5ff5f8f0dc71c4e0f702dc5b8a8eb71825e09b692adae6793f0bd6dcd92f
+5ec371159f0d61b7e174977766910a5d2013af40264e55351de8f7b7077b
+058918bbddec5e4dc7fd54b83b0af45f11a71ae59646935341bd381b72b1
+c64b82472cc9561f1ed5ad6b5df940884f6574d0304e5b9dcc28875a8ae9
+7ef3fe34068e2e36fa46aa5cbd3dd87f92ee8b5639941300a1034f50fad4
+60024e46c2710dbcff25e3d17a9c0c7697e318b144a77f0a39b1fbe910cc
+a9a8d8632c0ef2c285d5ab8d014d0b2dce8d7b0689af0449d1a22875cb7a
+a6d8c03b544e872ba804ade461c9ebff87461641bb7b9e1e68d13adc8f41
+13e2e08e79b0dc30d59765814a47a64b6a33143b9994d42b767e000e44a1
+a77e5241dc5a9464872b1193df3187c690274520b46c4d2c04d04284b58d
+05e7378d471e34444eed398747dae91728b8b1f3099ab3688d4ce7d82705
+a6a3df49e761f4c59e071e3e1d771ca1b8a60c359bf076e8061d148a6dd8
+04813a596c54149faf1bd2e25dc44ec458af5e2619a418c53b7eaf9cc75f
+c21387ad8b7f8e5e98483cae7e86853890d74588c87078c58237ec97dbfe
+8aab8488138402cbda5c876b43c280efb357342178217879909dfef65a21
+979caff8306759d8b475c3dfd7185074c185e4222deb781fca1c2e7b65e3
+d7bc788eabd2a74551c5bcd2d07695107673c8b38c53cb425e03e426e1d9
+88c4726e6fbb988ea28bdaca5156393213a9cb1c26eaae7b9534e2d25083
+37f2bfa574504a4f7a79467e97511ee052586288b2e095c41920ce77034d
+52ea9d07dfdbf3f094d7d15f0f3dbdaf3fddf1d44a1f51d470ec0f6723f8
+2bc0e874bd5c8d1e5f0530f65e6b675ffab3cd19f1e3bf6a226e3ecfd2b5
+018590395fbfbbe588621cdf2e52e1483794c44c6548206079f1b998bf31
+11772db5cbb8caf6930f225373d891e19a4fe62cf8a4309561274a329a3b
+eba8f589bff6cbc5a5d62d2ce038d3b64bef960b4185796f506c9adb0714
+f47738c76c30ecca61a019424d6ad5ed46bed1320b665c4840b514692f9a
+6bd0f93c53fd71ca297b3f00d9e7ec849a256e63a647fe3164dd2e3ea365
+af25a5c1eb26b13b130cae81be1623a0c8db75ecd68806219b7db3acf4e5
+5d504212e473044465a6f8bb66f730f28241f3159953ea3ca4af93395bbe
+9f1b5a1c3221107ed4cce1c509f522bb17279049041d75eed831a0f6a676
+286db0739f5d9efa13a81c3d38cdec6df61eec011451338db2bc6e5c1688
+605fab1ccfeb842de110d2047cc89138774a45b3c2b174a4241b9959ab39
+d6378d2a1bdd02d200290cff70a5fc3ccabfa166381c47f73e3ef81c359d
+35610fe000371e6cd4f38e525aee9c02fca862c8cc0cc548a846928b50e4
+a1a5af19a7cab7dd540d59eaa930bfff69cd67294d470bdb0e01090f7d07
+11ff287aec4c95f54ecebbef45ae68e07b20e6c9666fb2355a971deaaf5d
+0e77114787d579734e39c222a01456756f7d05a079e7c728d8aed34e28b4
+faedb5e44b28d3def6f351d4abe40a2b02878a4747b1ad064bb43ac2948c
+9d62e3bd6d3ca32c8e062552ab41688e108fd838c969db1ce8435f173349
+a96e2f0b156b9c7dc2b1d9a3d5796a664ebf0b6155e5208d976a95c6da4a
+80ca7cae016e466fb4ce4ecbc9cfcc9f46f389464ba21e51480286fef055
+318d74da79a0612ff316db41855794559ea733ccf0f964626da329b20149
+652408ad37595fd2a7869ad30752421110d0f31b395620b82b32e4db7928
+0455adf028a57c60cce7323e7024023fe9cb11c4563925c1e69392929faf
+046c16813b00516ec1f55fd6544595d1ea9529015a17cc8106709241e35b
+69586c1f00555f0fddfa746a26764fd1fecf101f63c4f25a75b2649200fc
+5c77003d852501153afba3d2a5b90d44852e14e6b6827e6f714481bdefec
+7a68b232bd483565d3a31de86176b2ddf0a42fc9700c643ca6693890127b
+842ba5099908bed877d2a2bf21b69e1f9acafe691fa684f40efa7f297f0f
+49b9b28e64fdb378e0e66ee7567142969c5cb92fe90fa1905b0a5c354a14
+edf705b62ea069248b6d3e7eef1b7b26d2657561a4da5cb3d27ca9be8c28
+3e23a0531cbc9992ea589d3a39a629a94dcfda7bfa0347c852a3ada2d631
+a2f74dd19a7f96a23d61a73e72a9b12ebe45f3c051f7a100517d5f1ed43c
+0a0ac5961fcbc0987f9191fa178acb9d15fd971740952e68eaccbdd70839
+6b6b6b3995976fd8a571e5253ee8cf1cc31af523dd223d13d4ae62e93226
+d83479d64352d7a51773bc123a58a24fc1190b3a02cc5ebd2d34a40240b1
+dd775ab4dd9041592604ec01d5a96de6120b37cf672aa912422003ff4f93
+8ee571b98d190c9a43613b11279d586f9d40a0bf94025161363af525a243
+023eed308423d27bd6246077ae64d38625443fd13e78915f88e284021009
+568b9e2a09d9f750b92eb5b48a60d1d9ae227ba47cb6fe49b1c51bff5a79
+7d087fe6c8458465cd3358bbdbb54fd6263c1abac697ac380f7417dfe253
+6602f0a76fac74c2492e524fb743fb614cc49f82bf59fee542a6de34c33e
+bd135318680ec14b77bd72b0a5792f0d505198133884e346d3d3a8da1747
+a5e3413563ac750d6d2d633a5c90ab136bf0f4c41e1900e1da555570796d
+d7c66f4fbc0fdeef00e7754490d589cc4cc257fc437706cc104e00903428
+1da81e74fbcd8c2dde3559a5eb59a67192bca9ed49ffc49b605a9daca194
+ea025c51c5ecbcb3a7900a3fbf4d1c2b9740fa767704ed75c3b58c7b93a5
+35bf43fa7b0e1e0e696b6c3bf8fc8905f4e5eed80c239bd19c9534922c27
+86c2f9ff1801d2e1e0890e1a6e61918a4c904ad8f8b79e297cf2beaec87a
+fbaca9515dc987e2dddc40f21c5a70d2a93d8d0a626e6e6184a2cfe85f86
+630b03d237d15295c3c5046f7bd5a24f59a8bcae80909b96ebefdf6ce2c5
+823b1352f5a76adfb86a6693cc2cb654ad09cfaba68e2338f5ce117604fc
+5c037512857e43ac097fb024cc5146294ea0c753145ea5c2f16a18fc75f6
+8d0362d4475a1e902fc341a3c82ee30744179d39c3e529b96b112de50711
+954a42ff30ec777feaa3d7c23e0f4da5d0a53bedabd6e46457aa6292585d
+3a148a31f0559e85556414bf2e9e0b62c20ab24ae5382a6d25c24a5d54b2
+672c5689c3ff74358a6d211f4d44e185c64b9e952ac2d60e6d9c816d5e19
+d662d6ef1d18b380935b2ccca31066fd7890f9b4d3c39d7d4a116c16d895
+3737edfcf511e94910f1bcc3a53109c6a21e177ad241ba16f5d09c711ede
+5943009c7b8b6a02976c33c38d43b873029097dc5a93841898122608fc4c
+f3acdcca3a2cb082d8aa4539d8243dbf363cfbdee338879da264292edf7e
+df7776a8d12bf4953f1fe319760a0c6b6275db4ed1b27135132062eb4b7a
+cfb2bda8b2dd2ba97f524d9103c43e81fc0ef9e08af1acbcf0eee058ec5b
+ecb04a1cade9c23d5e50dff7a8fb2c813f4f921fe202a9648207e95cb905
+8d76c6e34b13ea3c56c1ec3f3bebf98963fc566ae80810bedf064e32b75a
+9dcb51426697093f3571af3618619fe007d0c52bf9da695aaf1c2aacdbce
+03e88f208a050a02c7eaa946f41acbf5fefc03e790d08867e255e687b664
+a130c9f2f7537feaab9a431ff78bd2f70f4e3d39ace81e68a83877e62623
+05742e7d16dc3795c6003fabf015ca563916ab7b60fb7f6efceebe4f9f7a
+05f120b9638e9d77801ce319d199a1f15dafaf49b53ec272ea1f3629d013
+0d31eb4854375f171268866da5ec2ec7fe612bb9f8308c2e0df3481cdb4f
+97f8d526eb04dc57d9a84403902967516b7d6ba894583e74c5c9a24623ce
+a44df1772e2acabb5c0e1fdec582b1430a73587fd5f16b784682c0d02a80
+112e2044ffaeab3580f3e4000a25741d0899814832457290be7651b8efd7
+2b485f95d405c6515eccedc45b9bbc76b20676a5f6a91a58501e68f96cb0
+be65def662cd1db19ea8031feefbcf40353b7059476aafa33ba26af93b60
+956aea6d789ff3d80ed3000f266a2d8773eeac7fefd3776da65ed01acf9b
+43175602c26a538b1df061bb3b524f2a6ae4dd052e9ba288b2d35feed1a2
+f325c203072257db68404dd5b9aeb63d441e41ad385f170ddd4aa559296a
+cf4266c7e3bbca5b936e6028ab1bba4a44c79b4700b29fa2ed65d8274b8f
+54c17de9f4f151ed08c5774c1ac53644777fe675355dab5e54b131d64bbb
+aa811dac7925e002f62bbda978c6ece9b7c51c22573702bb08bd218606f2
+a7c9c8abab1b262b923c483730b4e6235607378a6b770a59845efb645312
+9cebc86eb8302e45fcdbdebc88c8b5b3115925044520195a42dc010ad771
+b320083a839a7149433f59442a24eec08286051516e97aaf096c4e87ee8e
+89365b9d4cc7c81c71e000b153a27e74e0515ff30e401252114dc7d4b1c0
+1fae5ef32620d74d9d4c61b63c5d753b3223a9c7267dd516d1cd18f7fe5f
+a60f8fdbaaa8778d79a87ab8901927ac870d580b3f9900b6eba38e830455
+8990ec4a85fda0ca6b3cdf97573e4d0736adbfcf366596f5e34f59f9ea15
+d38e4cc24ef808066457986399d309ce2cb7fe2c1d1ba921f1198a91766e
+1de4531980f5477770783dace9dec59922614b1fd88988007c6adf10ccee
+e138efc2346390fc88d1adf8617e4e56ffa72092913c1b263584089b4e1e
+214213f56af447678a4573091e3edc3b6438c00539d003006bb17aba98f5
+e7b9cbccadff6803b31e6ad941990462fe1b935c67ff9e4aa4b615b2855a
+d28841b296841a9f1a3bf86f9e3b1659d7e77b4b6e07da31af84c1f57e50
+20cf8c5b352fd4124e13117f3456d1ea3fffbe24a86971b712525505104f
+44e260553d10d65978a5ebf7ee66c7ac6603e7be95d2b9e8126931ba1389
+6987f97caea5b7ebe1c54069dea74b6157f19bfcbea2e59ad575103291eb
+36923f31341b9d12c4cedc3ed0383f19e6ddf36ba52652dee81e225691a0
+0b49aa3fa21b5d1a3b70663345263fb59bf0d71667a278394d71616312e1
+f8b2331572b7902fa2968d69ad3d42a938d7e6f9e9f26309443a6d977c64
+613501839d09870f02d282d91027738c17d164384bf49edfbe5859017052
+483a385f3d6c23c8ec31ee9e07c5761d85d6702be4231b95fe357bf67271
+454d8ba54104291df51c2092823d58d7d450c992eedc2b59a720c7195790
+44dae147b760ba9c83f66e2774c36352ca242d4bc6dfb07d15896edf5d07
+62a1b9491bc4f4a2ece2a0c44eb8f3a4e206be87c857f3c3ba01e7c1b329
+d7553a2f5b8c17ee6e339e5c32c75a914ed933c601676dce75f19f769737
+5650fc71a01feb7c88cf93b0870889df962d949ac0c672ca5a63fb9b6e9f
+731b075c02bab9297ed2318099bdc3d2eb26821cf90a2f388a6962c12108
+9bf34d08e3ce5109992f30b9f8e8b5202ad03d03d0e0001285cc4647d919
+b32846ec23fbc8c9106bba7a493c81b3a58bb13dd5d7a43bb6622ad68c84
+1d7f1136f895b1d49496887ac7adc49444803a164a0a1faec299da1c1ab9
+64fb75314bb9d7d4aa04ffb3575641f77bdd0f7e780eb7cdc17a88218c18
+e710e0f8296ade21fbdf35ba06e80aa6bec89f1b2a03076c6daf3f0fba84
+5a5b881402d2c0335b687b4030409688963f6dac5445094d66d33d78a763
+b6f500fd4c9bc8804d40f52cf4baebc6d35da9cdee7a30b70fded0f18587
+a17e08154070b0a38de000351a89f44b6cd66608d8a86844f90d88cb257a
+4af9c67f155036e833d5f5d0fc781dc98b1fc1b74c42822e747653d06600
+67daa7aa765471929ed4e38d9cd69bddb4707fb1d11d1237b3a5064cf8c1
+c628e23de9ee9dfecc4bde42978db529752a3a84b912467569ea3f9d6f40
+978896b86417c11424cda3083447f5c2df66c25c5502ea424e3a6ddcd230
+e649ffc82b3bc0168bb999bc51081b36bfe61177aeab6cc744d9947bc5a8
+938162c79a268e6945c3842dfd87b77d148f9c7941cc629d53547da93086
+30eb7bd3e1c0f27f8ac28ccce80ba0aa0060f26bbab71d175707ab60902f
+fbd9c99c38d852f114f012789673189b246eb64e098c5e9dd197abf6269e
+e1b4adfcf68c1c7b3e5231780f4dab3d4305a18a898ae3d3fe4053905248
+c4ce72a10153702987e2cbfb01cfeef86a19ed5fd00666ff93f1f47846cc
+bf216d42439218abbc95e456c07491a7c1e46f1d201c2d806649fcd234df
+122f89b3b6c0d864053ac7126861a71f40cb271c1499e4651e52a49411be
+51c646d59ddd91dde8736a0297885a0e0281432f254408acaaec81a374c5
+060d0f077677aa42a06b4dbc477b460f8d661789ff0cfeb829abecd6c06f
+a1adb76f27fe5381bb009bd05bab346a2d652d2478b0a8c76aa6c998c972
+6e87cbda66f9bc62fc440eba14c7347014b26e84f30556b8724bea81bf76
+d34263f8e45aea56841ebb601852c082016d5705a7300e8be1276b93c11e
+6bff846f1cb5f37734c467bfa64e935897b789d5985ce3da9a8eb80b9736
+5df25e5e875ed16584566afa3929d869a3fa9cd7aaf47b78939812fbe18f
+2921b393d788f75bf0f0c62a5bd25124cc98844e0e4edecc25d937df5670
+0965787fc4d191a33db8c24ffb2ff5504a4e6108e5fb5f6612db56bbd7d2
+f433fee1b8f0d780ec4f7640b4ffc01f352eb398b7c4116ff43f93a118e0
+56d6d820bf3b41a7c09ead1cc4ff9052421769c56b4599387eb08f750d6a
+6937b06cca4352a3f4961616eb1239ef592d72f7a7801295a1ee3e9782bc
+95ea6832f1b2715ef1aea0f4722e8516fdad1bf4145cd261032108e7892a
+8d040771f86ce98994e1b4b5688d59d6047a513233d86d3608ac4da4cce4
+cad778e366271c1609ddc506304c65b750b8bdb935ce9f0e0db5337d2e50
+715a21d1dd04920afdbadb6a416932bdc697aae5ccf32e9970ff05a18ec7
+6684d125607e26d371ef6e69172bf066f7eb6f527178a09b4077aefe0590
+a8bf000a9f2d483689b75cfd02571453435209ec995e6c072c788cb3687d
+6306d79f771ccff4214df3e63c74e83dbf2baecd472cb129fab760663a5a
+642910713187b42763e8a366c5170a81a2336e9881f5166fd9e0a6ff6c04
+b3b76c3562e0f1df47075ca1be9a79d58cb392f9d9f6b55c49054a35ace1
+b3ce3e8d3c81ba1959c167823375626eda6ca3f9d64c23de7a9f2e23bd32
+15bf3e65830cd8a364fc533ceca8b67b466172d70a891e4b3fe35adcf61e
+3e1f77717fa3924b7bbe8043b9815f9777a4f007792d6d6f9942d02445c2
+b0dc07b4510ca3352359aa3162320d3470d0147b1568b8a914e0df108c2e
+5a76d2bd7d58c8c2d7403e755fe896aa7522053b4cb846bda0a4e9b56b97
+a9d089e3e7416e6b1dd014229b90fd319a45fe161a0e3092e604be24125b
+51f3e7161c64fffbd2ed9eb48bd14342cac1e3030c633fbd6b87d28529fa
+29a5456799bec81d581c3ce827fcda2101419b119a4af6801c945c314f80
+f4d7abf36f73e3e75279530636fe09344e98c368240b9e4366d9e66a6105
+74ebee6f31cc111e83e0544ad321cf2f62f8c530beccfa91c5f3c5645d62
+0ecb35de6fa3dad76964db3a8307e8928c9a18bcb72d919fee70f1b97588
+db5c18e16bc7453597a1f20d7a9d9131b002a56d4c368d6bf69e8bad4e0a
+445c76fbe0af2af7c74db79ab8f767fdeceffab00c620d038fde8341ad14
+6887045489489d680e104129293a3f27e5fcce7529bb4a2772e504054157
+2c22532bf50aa2fc7d4b4db9a6b38e2668ced8fd5fb34b26f7ed5f29df43
+a5b17f9f1fe1f93304e31a2e17ccd8f25560f16074b1dca25c11e086363d
+3ebd6139d32594cd59a2d8b600ac9ee7c020d22b4ace7662b349824c926d
+29aa5fdc9c1dc4fc1718b01d7a04ff71fb10181b05cd613ffba439285862
+973a020895586a0543281cb6e94ab185d3fee9c8caefdffc959ee7ed5101
+8d527b21dca5ba42ba2e3a8a77dba86e64ce0ab27e9b5db014001bddc890
+db7f61e0900459821a7c7063db65136e8af05a68d26f6421fa86e4ae6265
+3c6577ac9187f3d6410bdbd7c8109c9d244376afd4b783ca00473e2797b3
+85c8585c1672932e1547d2183d84adf7e6f8cf420d03a4e78ad171ac8d52
+f443c76989ef51a0774c13711143eb00ec544a2b7421728b79502e8bfa2a
+394cd0cc15af713b5ce0bb78e716891802a281bb8fe6c5f2145b66e64dff
+6509313f3503282460e4c94ccf85569b1ce5840fd638ef514fda9de8b1b1
+e877579cd47b8785b991641a481ba0ef4603580c8edb944e27f4e92935ee
+027e2a55fbaff992f79e03f7b24268bf93b24ba6c604352d147ea9b337d0
+8e02dbc75fec7f50ad4841ae655106764153e6e08c84a2264f2a180c2225
+fa1e39ac081f3c4a3e3383bb9d5107ecd076edc61a7a80d9ae7f55975b60
+76e245f08ec36445d8f05dd13748995af65fffe75597e98683e688a24053
+011bc71b699ae161dcda835a2aadcdf4d9a82750958a39ae685058ce74f8
+91626e99497bc82d62d235494dd83f87e46a3756823e23434d47ae4f35a2
+dee83146805fb5e28af9e2df7812497ef6a45bad66df7b29e495128031cd
+96564323c75a88b98e7333f6f8de1c8e7526fb5f8c1110ffae4bccfe32e5
+32f1228f7a094f67b3518e00a071897f4edb688bf9975123cbe1de0895ea
+0a88277a69a5d7694c44b15ae4b592cf3a176ab6e9693d80d9b1b89bd35c
+d888b764920e865e7e9ad0e8266f17044ed652518d87ffee1dc364422f57
+621afea9160a8c795d44a6ce0c22623aa8af5a08cb2319f335e7364e1070
+6d6c357dfdf082d3ebe3b0503f0648b74aaddd538f5805b11eed58d6e50f
+7d7e6e1a631e89c81e321f6ba32e13a2b72e249ab2dc31e73a23bae59615
+36f1637d1a1ec1f9f777c755e72510df4e86c0acb8fbda3fa87084fd7153
+6ced250a8f31851f0c9b4149a4ff19506ee0d6b5706557b831e09c687bab
+ce784dcab017c4a62cf39df2bf8b25e81b29f8e11cb5a1f4f3eb0014560f
+bf1b8e47319677e83064657dc222f4b89f5ecd066f0ef92c1993d16247ce
+71aee7c8b464772213ffa7b8ecc9b4fc0bc307832deb605e685f6ee7d54a
+d064424e1279e2a1ec2d42b1d293e396ee0d8432a5a0dc32e5299aa79113
+201aa5d2207af42b4b2e617d80a5aa4b28ba84d0e572ecff34fdc202b672
+63b2900e5b8a204af2272fb388c0c1c1c23a8a821b6fb3353bf66c5c01a9
+068afe1e8d70107dc1b88461af7412400ea89be6d9ee48b306629683621f
+af5ad5f9f87b8db31d792108412e4e317b0a4fa1f80fa197315232dc5d4d
+d2a3a3b16c8767fa33e2f227ccb7e75fbe989d1d51e2322426bae35ae94c
+a87356c5cf217dde81adf0625386e8104fca2178217879909dfeaf3c4b49
+22ff0df7b742fd8e53ff06ce37ce7ab7da7a6bd83e753314b4a5db582300
+1d7ae54e696f0fce5006491f9d9fbb4f415f32c6cbaca1e0ece08e6f3536
+1ba4cbd36ab700e7d65c9e7e6828c7a05ef347ec2a433f4d14eed7e00669
+5638f8c3eb83436d5d47dd655803c25fa1acae75067071cc968969647250
+cb082aebfe199d763f534850ad7becc6119c88c36ae5de4dc01631c74b23
+bfc0be2062dca0f40c36b986d06f756a8f6ad3ee511b73b94a21653201a8
+230c66de11afc5dd11f0c7bbca6eda4e20239610d1b7c39758395577a5d8
+34ce808c8175d741d834b184c865c3d8a65c787313a9fb607f977751526a
+7384c153d94b6a929db265128ee0eb7da9ceb15f793384790317c87a4a2b
+18e765518e928dc5cd257d1734efd5f156134530af79e72004c7b3ef05d0
+e1fbcf09213699489e67aaeb39598b718baad866303b5601ea56c178042c
+25b5cb585ec12a336bf74bb3e655959e6f859e6312ec1872eac58fe94966
+fb2c68e160b4901a6fe701da607eb6e371e2a23d2ea43754178f3bdd6da3
+e0dab513f2cc03dde85de5f667a74627dbc8c9324a325ccc52c2ced30c66
+15bd70bf7f59869cc9a2d5757b6a14bc8d2596b949be75c3e6a338edf1b1
+3cef3fe2a02de729df56cc07b5cf2576e971584a9727b84eae6ed9d353f5
+42094c3b11fc9a0751c986f30b10d35a5add9e3102d08c00dda48f942447
+a2015d96c78b011ef763d5d44de2ab8c95bb380e74138a936e03e1b8c5b6
+bab711c995fedfb910b637145fea1767c9283dc78925142f3e870e0d1399
+54b8df666423e5261cb20cafc2898eceb2720cee92aa6277f11282729067
+ef3dfee0aa9d4abb321902c457447661ba78526174124f7c9d5566fdab5d
+df4fb6c08a0cb7808c59bb42de49c87fadd4f75935a0ced714b8f3b5f684
+8ae7a605960db4b2bcb477976264e2a84a43cf6854b82844d5096e422a39
+0211aff3a6f6271c03c4bdbdb5631767f345d09cce4b4fa0e9c2f9cf36a7
+ffb12f2c8ea3136945c087f9c2bde97e5aa7e0781e144ce7bf5efafa7150
+d703505bf7412bb932091f92b371539ce444723eac99aa508399d3eddebf
+4f4ca90564bba44abe73a50e62ec268b2aee66726ffce232dd4868cd1981
+85816064b6316eaed2f4fdbbd4cb75145fda87396baa6e5878154cda0b6d
+8bc799ae07d22a85f4b3eadd0501051c0f46c69cc26a68738bb20acb2698
+15f97cab493969fc16f0714e37629c835132683b4f5e4d7fcf2b78b6c8f2
+f209c4ef075f83ee77d532d6aa7098c893e6f14b0a777abf7c01e9884cee
+55066937178356bdf97f9c1b589de16194fc3b152b22bc06e4842ecfde68
+47dbe695df25ba700dd75c0e2ec2cc9716dfe2a4e75c558e0e5e521e70d7
+305e5379bdb0f5ac30f091a77c64b7bbd94fcd0448865d866f4d241e1921
+ef5291c414ae73824607d9965ca185c3005b25838462b937c91ed9c3a649
+d52cdbcd20cf6a1d8a30325c97a0f8331af0c41a2365f0e374830346ef9d
+895fe924531098876e44079140bc4d7627208b1d09e4662aa45b9796aca2
+5e3ff8624f14ee127c6a86377996a4fa8ebd4be5322fecd2f1ff85645a9a
+11445dc7328a7a69bff5263ac3b77f968f695e4aa381b8581df3f8faa2ce
+465987b1f25689d8b4ff6f79d376a3eae3aac7c8cc6436e5713a61adc6d5
+8e8a9e9e9789938bf39dde35f3ad5d2f619d07b6bb5d35277d27d00d15bc
+34ab44ee8febc29935f4d78f7183471b32fc327a631cb87697db1bf9ea35
+ba099761235bd0fb08c9ecedc02a56f2013280bef6c57c9daccf1cfe2e64
+796d4185edc469a71d96889e6446c40c7005399b895ff1e5bcf46ac23010
+01791fbf7e895fbf64870937ee66725f2c56712da4d480b8a6382c317eef
+a0268211664837c0ae48e66886e0490cf8650c136deae13628fa3b01340e
+7ed17aee48e3f832409690bbe4ee1e4e30f9d7930fb54ef72ef06fbde9d7
+ae68fdae5f146e7adc44b899643cc207c53e14c766075cea41321406abc8
+916ad2f763f268886136ab2651125da29348b6bb4d1721203e60f8504935
+ce98b7781cece00065b6a2469902026e20fc30ef28ada452f82097ed5da4
+874fd5409f7056a02e501895c0f5617682ad95a74013d95fcfc7bf203b5f
+efe8aded7f2713750bd224b8361d3be7b4eff6ec72c4e484556a5d7d62de
+c61e7f4f902cb7d15add2d7cf5b9655371384ceca736ae87848d97541ec6
+45fc0de7ded4e3c8ba4b8a99716e767a2f4242028b61fa2ac2e810fdca21
+ad07a28ea5aba532cd615d0847926c44e7d4fd6bf46063ae725477bbe9ff
+d01cca116c5d2e35cb91436ba0d713e96e81e188217cbc603c3a1ec453f8
+3e958063053c7af403de39a9ed4753db3a876f6da5d7190074c7ce479efd
+c41bf3448bf859a2dfb482eed009fc38c548abfc54288419ec3b7249b66f
+15f5359c461cdd6d77b96e9def3eaec6d526d19f096547061ee7c4cb5a0c
+71bc5ddf090c363a8de648d44cb771665259e50573ff945b52291e822522
+c0dd255ad3ad4247658ac1bdf71e2c8bb62f43c2f3994411b89884821fbf
+963cafa4589a410f8e61317f04cbf9b87ef236724c850a42f9af2f36a850
+72bb16911d7810ce35b58a6b3a978c6eeeb379be4451f6260123a56b73fe
+54dbbc4f1934fd185fb374a2f4b205ed7838c22477f8eb4cd102c53b4ca5
+ad74789a4468cfa7cfddddd23db22ba4315c703763d6b3da578edc4ec040
+d4f0484278eff6b2f4b1e318a575dc53bdadb24be8c5a81f48fc9704c963
+5a57f2bc8b87921f2b3f5cabe517b7909f6fac3bb85a4ff60d5127e45d9b
+38d76620e6ed901ad20fee55a99aec87995f54809f22617b289f303ac768
+9719ce10f9d5456f7a4804115abe4cdb5cfe2cc715941a95b8b187b53f74
+c2b82eaadca96bd8b902c58e17d1bb5e8e87bb0aa354cbed83753aefde1d
+1bf54e3246aa1485f796fe3be9cd5db6992c2647e4d32ba14bfd5ef0cb5f
+b1f77f0e5d13d70154be1e2be0ea6c6ca71a5024dd4c8092c465913019cc
+b8d949e2dd5cd87a196640bdf64024ccf38dcab7f022a688b9c670e6b4fb
+fb0d3c6fc506aa5aa6b9cca0ff2bfdb20a9f876040db7fb7ec2ccbc5304a
+152206cf00f98315ea1aa8fa8a4699c26af04ad9455ab67e60cc95b9ff26
+30cc7721e80fb4c17e0f9a1b7aafb5cde08a489e47689d5138c6d65297f9
+3337b5c6d9917e2d98c65e7328e55b6935e6b81314f88457485f9dc22d69
+daa5f7fbee8940521ee723292bafdf69b9172998b7951967001c8c6919f4
+3e7aa54f352df65b8130a45d5fefe672291e15f34f8fb865600931d1c751
+abd8dca8cc6ec3c7e735a3accb6b407e28ba941276bcd2e221f06aa2e180
+20c88a75e02c8751505800a1d8e8dda4c417c48fafd7b285f8771989d0e8
+4f89adca1d965ffb37c74f63e08f9e5acb085a66c85b84ad8c3e85354d17
+e05494bfaf92dd4e91efa6fc53fe92b7c2cbd93ce69b35cf44bacaa33a59
+de80d50046a1240309e261f1fb355e49f9b15b56ca50327a2c62c0b944ef
+7d448b62fb75805665a50ddb309cdfc7cb7368172a7542fab7eb9d386019
+8874930d428f3751d85c228ac66ca19f3f7b5f2bb93303b2dd1532bf27e6
+8639762b9cb525f916d0478ea7ed6ee9735e7681291e17b2d32cae4159cc
+fe773d9acc97260e721af0943e2bccb8ccbf17077ff7ffd389dcf006064f
+8d89e421a2e8d8098f72be9e286c3e824ea0604f895789866cdb26ea01da
+d4b46faf3804f4ac97ff2a626bc0f059d2143ab05aad944589acb5e15413
+2c9392d823c072aa8799940d5c98386a0fd6b4d0b536525e305699f41773
+2421bb58a75568ad4edb53268c8168f914be852c86ea02d369315dd59236
+3915dc469729f01ef1bffaf4a5d29ee70da632b9e63dd383eecd4ea32114
+642c3c4be801265a9e9594ea6dcef082bc99d2cc7e92333aefa43a33d3c4
+696a1ce363c9b3915aa8563eb616c897b795d29361f8253c267dcb652f60
+5a96d6492ddcac2b13bf904e88c90fd75ec77f7364bb75ae200b61361526
+044a94c7e033bb86d44597ed39b1ad3b7bce8e10659cadbf9e07b3fb041c
+f1a8adc4b74c39306a8590d58d3636ed87299c47cc12a847120ca9f77182
+606f86b724792908367255677d56495f22aa1275b2ffaf1cefda123a8984
+c607d438cd7c00b769497b9af62194895c6c79819357264c7d0b4ce7a259
+dd1696e773cd0722e28a5beafe26c7d04ad867886ac5d9d1f83dfe97f670
+1c200007ce81859e8da06505468f25e77cbd0be59194700ec5b39c300018
+1398248b39e650376b2fbd9750bb27457fb4cae1615d167b6ade44d5d4b9
+b08492e7d2122af169ba8d1f201e0e8333769bf901862ad46ecc9d58b8f7
+2b58fec61bdd691cc14aef8f5d7a34113f9b0d08eaa4fbbfd530b73c15f0
+feef4c45a7c8c7b68e5310e093667282475da5db6765ff566069215bc09d
+d0a8e5186cc2c11e3577b56eb13aea6035d2dc3add1d137ae15f8f9aa9b5
+0b64c7b7c1dfd5815bdbffacc75b84254804b8be1449b32f45ae3b774cb6
+0f3a9ba3450e08a4432ff2527686e3cd04a7f035471bb4bddf4e4ed9309e
+708be043539d298106cb4c6e78267b568221cf6458f5a2ee17ce08cba821
+d9b872b5b985ee939c10a45db0cbb3a09432bdac2d10b73c29990fdade4a
+c161a5df44c1bc8d60dfcce175b9fca5fedc347fcf7a9c897b37857f7d8c
+b1e7af13f4586a23bfc9860b88a28b5cdda25b74b4bb2553e8ed796b0323
+13e5c61ff414bb6eee4d9e5f3e8b4b7811d5809a2be4a609e39a0c8facbb
+ab96619a34df96aaf42ec5bb0f16c92e104b95250ce203aa9c062a409a04
+089d02966f454b8fc5f0272ca0f472aa3bff2d55734f9e3e93c9ef83d7c3
+0f53b334cc0ae1e8b0ca1cd4c74f5993cab7274fdcdfe86bdbbbf3ea762e
+568d9379ddf41f095a5424337277f8e4f110bfdb6544bc603c6a153c2e13
+084d333f6aadca51e7b45003d4459478b9510b48d708e12e30c7ae7e4a1f
+1f872d31ee76df3204aec196b8365c8f3b6d3f386aa63a149e923c205d78
+d7d4c1515782b961927de098c019c865d90c59a24bb2fe821538287cdb9a
+b703acb82892558b3b1321a31620ebe974dc1a12746a047a5ec793e57c09
+1026e8cc0ed07cbf90cf19f792629e55a5a6b7d94e667c870153ca440a72
+2f39401aaa9c3ae417e94e2116d97630c289ea43e026b51d0265d38a8488
+5800099b144bf37188cfb3e59cd846871d524372a3acc721f9ba5659052c
+dc2b78f26192b057945495fd2456089c3df9c543a643f39dbc26d532c88a
+a4fa6936e7579cddc8df83138adaecb0b7096b520ac4d97cef76022200f9
+6542100717c47cc0c59e48dc57f8028c453d8d4508ffcd5b3fff8f09a64d
+a18d08a5f91eb696f169758e35732216736f122192a765b5043a7187c473
+0edb5e11c167dbc62fb78cc6d478c79d41645c2012a067a8c895d746c77f
+d106fe34c2c888020fdc90547dfaf6036027324bfad10157483a0dfa92d5
+77102b892e9ad3ce666ce138f8f32d86cba1ed1f3dbd5b46a9b83d7ddeaa
+57dc7de7ebd5cedc8804410f6df6dad36706754f0796db56e4f7fd86b603
+d68d269004701f81310413a2f78d1e765329c26b37647bb0aae4aeb1d8a2
+53bdac2da74790f5020cb9cc18373f145ced54c39a41ad08a31756366bed
+27e1c358d61008ec2b666d348d50f3b6db72bc68740e8cab62e172aa9332
+27ea0b2b6692ca80d5244e2700de3c5a23f36705efacc566eec594c0fdeb
+319b05e48f25aa6b5cbf5f71343fee2932dddbf8bcfe62a38d8302d0d287
+529dc0383e8efda45177beb4b1a09e3b6121db5f0a25dec3b8a16889b0d2
+dac7ce9ee7339031b5dd48b2e217224cce666a5b218dfaedab6bb9dba36b
+6b588ed0ed3804040785f8672ea17a6b2620f653d98e65876452caacebd4
+f8d399e8581eea899c59e5f50832dcba0c17141c08a609f47047f33aa20b
+815531d7dc90722a2622b03b7e82cf4cfc871f45f7b7f040bf20f2a0db10
+0bf9f352233acb1050d142ba5be8a957f1b2af4f3e651b1ab3083f0c7fba
+cc934863d2845e5071fae1e3989ef2280c56a82f79eee05aa4ebdf6b61c2
+5918d704d7f76d0c0d7dbc1b883f614f3544e025499c16967bc66dd59fc7
+1efefd9bad3ec24945bc6fe1b58849a819bc544c60d4df10201b2be4b765
+9d4c44bbc2bc310105b867c6e8237af12628536c7d4287e7cb3bfc60fdc8
+446f310c6aad457f1b420aa61eda74926dc969d752d0b7cf6f36add88ac6
+67bf4912a237184bc20d38fca2e50cf9698f9713fb1542759b21024109d0
+6d5df512663444ec40b58d828722f0fa752854a4fa27f2e17a3d9d5b6676
+96a8871cf2fcee25855233b670e78e401ea8046510a6cdb7f3492e8abc4d
+23f5f1189ae5b15bb14307c2aabcde0b398bcdc8cb339ee3fa48bb2fc5b1
+a636b30884b342c4d165ba0929eaa8d411f87ab8b36b50a51ba2305e6868
+0f7a5b4bc8555052354a1da9a6fda6a2b37bb248237e7418216c388a2a6a
+18f27888bd2d5715b26463b3bd2924a319981e687c15dd47e4ea71ebc87f
+d75c72453b7288c8c5780062b3182b0babb9ce6bd6ede56327d337ba1c3c
+7f069932292d77eaa0b515d3ebe13b5bb70e17c6665863ac034feb834c55
+d8cd1c078304871bf7d1a782a423b915f670a59cdb30ecc94d2a004f4fb3
+9463a2815bcb1a96817b5d105a8d1ca1a81197a3a83cd64bb15cc9bf31cd
+7d174d1ea78c95757a607a6d3ce4de004e840ffe790cb98f4000520da3aa
+75e0c511567d8d0927e7b0c2cac2de17209481edae918d5d5a76ca6abf5f
+f352f11a3dec26db4ac6b7286ba45d4de5eddd3862ade7f6bc1374ff5623
+fc2749ec4b5fd8e8dec48210511b49ff88aa67a7697a41b75578a6600354
+ab3ff8df60ef834a06e0a88f6a9b5050e3dd3224b511797ef82bb0cc72a3
+77298a714d0380ec24a66463e8d120ca66bdc4bff401718b89890a4c03e2
+a34aad9949db6694aee7d63b32798124e54cdc35aa4ef8fdb748d2c68185
+e4222dfcf0b03d3c121558438956292450e7bc60e00c36f3ba5a2558c153
+b3a7b3e5b6789941f8c83f65b0e6bf7a626824b0e93008c9909b6d6c7210
+f348c72584a67e862d8434840105b28113b5b51e8648e283aa62e60ce215
+0467033bde24acb17606e1ed9c15f9d46439dd00cf5b20e8384da2baeec4
+8d3cfb0763ff3783a005b9a4e7ec0bf36af1755ffb082c69f0e8f4807a29
+87d7a38ce50e1b7fff3d6914dfe2b19ad4b8a4c3582ff4a4a383b15eb15f
+e5f36134b906b18f6b231eacf47abd1b52ab570ac964141997d84e8754ac
+b59de5bc277370ef2e203c661d32213b2620e911e5f02c4b2d99ef88271e
+5c772ccd6c72487ddf5ade79c61f414c4c20bc55be8e887a577ddb0d8129
+49ee3ee14468d2c5e6c2325d25c3a1790eb0dda0d88861a77fd043912065
+f06e7292904d964bca5483959f6fd43702d7ef13e046fc674d8fdbf3b9f4
+ad11d2b14c1f120ae522ae0b69b01eb1de89b3a794b5feb4d6464bd13802
+dd617ab53aa8f1bb962452593456316cf6a9ad6a04c89330bda58ce2ad5b
+30cb368fdc8e2b62845e117c965bf052eed29c02c43a88b04460445f3b2d
+4935ce4d46f92c9949894661a92c241d088d26a74414400beff55c1ba2c0
+ec680d05c5412e753a10566e7c8db2d2303db5161d5f33177105d6ba7cf4
+8faccb3a4eaca923d5a123f2951fc37df94a861a70305464567469d54722
+fb82a31fe18a65056cad43a872963de7b4085005db0be6978b0284e513a8
+9887bad0d8f38bbaa572f6660c7cc52654c706f0b8e198296cc2c6ee6561
+7b383a3f491d562746fcbd014db726a50d4f4410e64ed60f10d5e4f5889d
+741ededad290c03b9d9ca995f49e260442e7307d7ccd36eacbd507601d66
+aaeb232605601aa2b9905f6e7c59453f0e5d6ce8450b8adb3a372b40b765
+0b7e81b0980f095209e8dab194014c299d659144afef2cdf5f12c05f3101
+c73944d76e9ee2fd92906b25b62857b492b23a66ccff19080c55955fa167
+b7aa7e13bf5fa873116695518341a70aa41844ef03c481c2a36f64161d72
+5c150e869e280425996038477fc5a6db064b8d2fd9bed3119b8d93d19cfb
+e418b95d6483bbf8d3047cb788e3b5d3eb2e220eec7b48367a916df77264
+59bb90464c6096029d2f781d30502889ac2c9344b8fa45ecfb1f5099551f
+3c6dec6357580727e277747e62b757d0ac7232b7dccaa2fd8b20379d1645
+799a691c64d47cfc9531451deab72664558a2ae06d90e45e537dbfa1b8f7
+f14ff7619310fd5365036abf9f29492eeaa418e1cc87e53ff3e982b9976d
+adc5f23461dc54d13864bc8bf5fe0e9752870a399d7a9ab81587705ae019
+01a66b4d89b39511ea03e144f56ecb2fac87a5337e8fbdc2cc7d53b62edd
+53d3cd77f8d8a3be417809c7e27900d1fc4bfc89d3e2185816ba2824bbb0
+5de4f0e5781c29ea8262e689c525bb73e7448252fb8573e01b855590bf4a
+baa076adee94fe895a2c51e57e54bc13f6e3a38d6139711165f5a9e30454
+7dd0d41d9304739c4ddec27c07c74c4aa03cedabfe7564b14a65acdabc7c
+9862b13e58004b27c0e489fe7ec5ea6d0dfce31c1b500680607372bed66a
+e33db1ae66a215ef573b52dd07299db401eed536ee4b0b587b910ccc3d51
+72b4ac15489098a6ecbdcbeff2c968d26edc339acdfb7c30e4b13e9b5362
+40264bcc2a34a2eabd641c9e9aed706f266c491b6ac618c022b23fdf20e5
+809f5caf0198876ba92b577b128f81d80affc4b6aa9b8ca747b7832e510f
+404cbeb63939b5d8a77f3d7da7f23fb276d5500959a394a2a854da1a361b
+8e40d1a0f41fc67d51340d687c2bebcda5bba418694cc392301e28e3c2c2
+3e07aeaaf44970e0db8f2e44e67f9f372aff67f735b1df1a228be4dfd3eb
+c0922df5bece2cb1bc8e784331aa2d405f472bb9edb41b80c784f5a7a7f3
+bbda8568b7b2eacba10cfa5728f5a6609ac2a590b74883160cb1f12d1dd3
+6e0b54ce388c5c8f3034f885a29979599fe6d59e93739ff98b2eac79785f
+f9564224d6b454fcc2084320d28c900302379475b911dfd9951b075e4f14
+2686a37a437aef3e158140df71353e0f932546ff92b9fbb7c44db1537060
+e94a421164e814de32d1f3d408d4345626b8bee38896ff335046aa293185
+49ccc78b7ecb2d17d6fc255b69c92781f9a561ddd8bde09f04c4374c0225
+7c98e24e2ee407741a8f02b86022d9dcc449b730960fcf1b9b8d65af9e0f
+10af8edf7bd3f1cdaa9d5e150416b6334089dc862e3fde6633fad940bf88
+5c976185ad5667991e75a2593038fc8c5edac82f06c213b0da990c702244
+9b767a619bbee9c29e65d9ca53ce96016d0cd40aaa188aa7c60bce101426
+5efd9206ddabb6c0abbe54f1890c4045485d1d4fa003874b1052147cd269
+552b663460931b5ef7824cecb7d7b85f6664a7bfec448a7e591daf6891f8
+f8b0c5f8c824d506072c9ef683bc85be1e7f4e240ee40bb1e23d4e8f6f8a
+31f464f1a5d13989456404ff3a50cde14956db3b24e06af7bdb5527a000f
+2a853e9535914d4624cd39ea90a4efdcacae7811370c81309ef360021d0c
+79f656bfd42ceef8f2a7ac6f6647482444f58787706be9c7ab844428aabb
+6679e4b89827af8cf9550093b0f7ea78a53ca24b8c896709ae2213308520
+2c5b5c3e4933092b6c5a2d4ef88cd24697294cd74a7a30571e143277708f
+540f4cee7dd8540ac16ec5f4ded4d43dce5f238d2b607d7728a37a4cd110
+879325f583c1b370d16ebfba95806ab62bf0fe931ca58e68fc101057cce1
+be648ba99d6af6f4f288a81a3e75c2263dc32aab93d4ed052cd9f97f2dd9
+127dd32f895a7e760b6c04bca804ec286c31d58850acb783e4227e8fe6a5
+5eb50f6bb9aaa25fe46421169a1088c3a60c3f8391ac822c57a4d83f018e
+d339d5a7f91b2a47c951eea90a736803932641837100c5cd4cb6ceffdf15
+7a9835855f53d8bfe1e54a9854d8f7584ed4e97730635497604a9df15642
+bb7bbe854c871575556f0bfb3ccf3c8a7ef1aeaff371875ad23014e0e5cf
+a1d1ecce5ac42bb72ff463333cefb2377be4cd71cc06547dce74827a60bb
+3d2c920d918f65b0f4ed436c3a39987965203499728d7f0ba4a3de62b38a
+2168914b279c9455959c51f2dc490581312d26f39113e42cfc81787cd39e
+d884198675298c9970ce6b07a439ae17d346f1a1c4c5417f00d3a285f59b
+08be23018072608e8d2103dd6eb5282535246c78c06abee28e8981682319
+6f6da9f6d1552ebad2a28633acf3f26b86de651f5a3534923bf54758f394
+46fd8c960bc108ff9020c88ad0bf94f24f8c444961bf1742dedf34839a4e
+869651294c8c9a8383291a5b460416a6c30fc8b26d74744d3b0699bc7d7d
+f9af19e6c297032ed61cd9be041d42e1a85272d981176a8d3d028346d2b3
+fd6cf3bfeb759a76149f3c83a372b16aa17d8d13275351901e55bef3477d
+d1440ed8509a565cfe0b4b5d83253a7382b9ea5baed8303b7ab5215a4cd3
+acbbd28a3fc24fd8e6eb59003e083c55bab0ace88797a6174208d9adbe6e
+e313712a611bdddf09fa5d05b9ab89ad94681b536ec836f330dae407625f
+5f7fe3edff500507cd28d86d0f7477ecbbd1085c83a849e50aec49759c5c
+193a79b8b1e03e808347eac949ce187fa816f69e6ede6eb795f910dbfc5d
+85c9f581621b5b7ea982abbf59e7e01eb665695355486d46a3222dccf79e
+fa05254209034eabb0147bc5e21dbb361296aeb014e2a6247166d27e5643
+bfc06ac4b138c0bbdd0aedd15c468eaef74324651aca67c0f7be421226db
+7fbf04b2baedaf2fe6752f13d9df1f5e306e539451de6d708e58328d19b8
+24e8ef308d3044f8552b5ba5b31eb1faed15dc9a99f0d46e5130b5e63d77
+c63d407d277491fb9da2671d24e5cdc15a38b267231914223ffb455f7df8
+bb21f965438c3747b7c1f04f8c5a9f7dabe1ea430514733338232567c4a1
+234aa8af98e445e267d39af70e9eb8c2a660a2153cce33abe475b3a894e2
+3c31fb10c0f0ab994c689b5fdc2b6d07a70f9af7fb4ff8b3e34c5f1de296
+8969f1bd834bab5a2626f1f25b196927c680b9438f795e4f1f31c41eabf1
+ede62ebc46ba5246d086acd10d32492a129eed911a18a4b3df792a4dbfc8
+e44fbc6b71d7dcd6de9156f2030928c7d7c1584ff4f534f221377d8b2e74
+df80cb2abdcc685734ab8466efb981a361dfdd859ca67301840f76491f21
+c63dd556d47b513aa6bf56dc427ca6cac22809671af909f87c2748bee4c7
+ac4dba40239094306f2b40e28dcdbf90cfb22e127cd5f27c1d543ca0c549
+963e94d95ca07ff0fa6d1f4afdfeea5289e7a33ab1a3eeaed32bbc576df1
+d587aa9c24af350ee5349f1e1ef906adfcddeb97a8af555619b45a8b7c71
+420ace89fade1f980797909257083e26232c0cfe0d387e18d4d4d10022a0
+01bf7a265012715b0d9cac530d6d6edf2591fecd9ebb19ea15a931f5814c
+6e83d63e36cc36521960fbfe697685556376661e354dfecfd153fc87b601
+bacd03b1ca8537cc788c4627a47301175aba9d24a606fa5915967e0c47b1
+23a5a6552e8f0bfd748ea73f22fe5b5de2efc0251da7d2917c60cdedcaec
+63e34d2d16bc177a9e3b2e9be7f25663de708b7492eb9daa0e9c7a7a8c51
+17461471a3f8a9d704fdfc6848956f6033e98006d0fb5331453edc8d3854
+143ca54940dd26db56c904839af1ce8f7fb2970308a4d16974163c8c86e0
+a2b3b5eeaa1f4eab594577b76cf35a1dda9469eb319c2668ba7c57b4ec7b
+80c413a384127ba4b9291826d4815a63d987657f9ea870c763cc23cb7401
+03ff300a50bbbb30c29a8df5b081d3efd3d8cf64126ba36084fa7cef3f4d
+5d4f2d8b26011f854c37774770a6c34ffd0086a50d6b61cec6e25ed85c36
+776ad1d522f0069c6f6fb120f3191b0f4a06c0ba50c29a4283c7d876233e
+23c1efa55760ca46491b69a30c8e638279a4385b3359ceb5bc4a616a3e1e
+cebee2ab4279c5ccb2aa5b7576d0777215217cac3f16db73fb1526c4c95b
+db662448cff24b480b224834f8b2b3e49e42e7b668d95428621411653b40
+6bffbd7cd5feaebe10dade204c86bfd3a3c00c12ab790a59d9e47e7798e5
+8071ddbbb583e2c96c27876dfd40f6ad8e0821267e4f0a574d8e5e684c9a
+45a70f999e3ede8b00c1506b5ef0001c28334aefd1f6309cf290ef58fb07
+5379da9fc609c31b1fd0bd33dfae5de4a704e02886a3fda22c0554bde2c7
+1f65880362badfea1471b54c064b2dde0361b586b9071554d77e5c45d704
+ae13f654a34a9d34c198ce8f56be3f99d3c6a3cda12a6f488baac8ff82b7
+ce2b2a341a1eb6d321fce0a1feefb4c1a124a9123f6280db7efef0434fdd
+9c1f570c3d1f70855c166b76fcdf37237ec06df0ba289710b1a1467142a3
+22ca1412c96b41beb0003b12f6423fa92a4460259bada3702c21e2bb799e
+703eac3e7875f673afc8a75293ea9da16f1f87465a8f0984e4457e967ba7
+c5d265f2d997eefc517e2766382144673162d6f937bc6d075a79e8f54723
+9bd8a42e80a4657c0c927d3e7a71cdb8d49534ce254c1f0b161c6f498766
+d11b7e40bb4700ec8ec6f6282535c78ace3fde539ff76d85440cacfe0702
+265163de0fed12f3ccd1d5fd5d5404292c5137f389da4e05b751c32197dc
+6dfe5ccb4d8016dda6c924815d6d80fdbfd04e1357922ae931293a92559e
+6122e0f9a1ab493a4f82ac6290f420c18d24287fec4cd41c226cc06f0512
+12fe8e4e33f3e9d53d37e0fc7819ce859f2963e2bebcc47aef3b877df83a
+d2e7a1e3bec754079ed7f330f684dc53cd2389fea725d1002530f55c4d72
+ae385b6e836a38d306e764ea1cc46ca00b06c4a901bdd45cd76e45dc6f7c
+cc02cee158eae31970bbedc31dabd5fb0dc2e51ff855e53143c726106f38
+084affef8cec7ead3de194dcffaf7758390a21ae63bbfcb18c4db3913843
+5492781247e29fe2089af2c6cc99fad2af2000f0c1f4b5944e15cc402f99
+d7e9eaee03f5a96d4198bdd3dc5140b3abd0b5300db7b40d1a3986d7abdf
+b59934d7dd00ea54c9867805ba6a29f60efd9873d7ad8ff52399daf45311
+c6ddbd2963b3dbe5ade0260209f9fc81ea3a88b4024cb17fb8bcf05e6906
+fd95fbc50439daacb2866759e8c8212d0e67a7eb4aadd6bc5d94f8e97f67
+05730c3cd2bbd303d6c1714c7ba641eada96dd89cb6fe1d655f4b67354a1
+708ff15bc6a45245d57695cd52377e7fd3e38f94a9c4da0a7a921b3a687c
+5ee8d0bd2b725c95e8dcb582f79ea5d5a728c6691ea47950614c78c4c377
+19defbc6e50bad8165f1ed0dcc0208afd12365e70948d44b14f91bf90cfd
+e82296c021aa112364369457567bf58497ece9a36f4058c8eb1713969274
+d29816680623704d034eaf900c52e04975556b58c3ea63e5447c1974248d
+713988c58d1b666321d535be0c5f90e061a2a2f7c36c1e058fb2c01f4d76
+7538a6e41ecae22854b83a77101bf865d6dd442f89cfcace8cbda39321ef
+bc2b79da45fbb39f2d448b03757310283bfb73b97eeb5d160dc002d178eb
+3868a293be770fe4b63c014c1b0bbfdf1af1913cd5480d96d09080225183
+38f18ae7c3961e1d87cba5b6a4254d225a2c9caf5d976f1764a14276eab0
+ff47688a5940c300851424ea934cd53c59869dec2ed89139fed0a1e44037
+9059968726cf1c380890796b0e598e5b1e3fe5998a63224905cb8dbe7d95
+5ee9e9759e0d8195239a359e8e4da5c783ea2d19d0794692f0d59bf50905
+73f7cbdc635429f853f55b75bde37dfb5c1d5642b58f5873d079be65d004
+7b01296394aacd4c4ce242d3c0c37427765a7b1cbbe19f4f9153703613bb
+cc8aa6e1c616df576ff5153c1ebcf9f5d202f42c628e70137837e3a33883
+e9fa8f0476e5414cf337650d94b533aa2cb45b7c473f90aa1824c69a2120
+5db7f301e8d2d6652685db61513cc3ad11c44900084623958d419f0752c6
+7d881df7d20300748f0f53e410d534664c6d13b4c96b49cb991ac1eda4f4
+25ad27510d96fe350b9168a536ae9ec6c50be8de32e2ee7fe9f2db8eeca5
+db7a80ceedc96d5a0b96f91930dbc00d2cc75069f1590c81d75bb6f7e6aa
+720307776f25867fb62e78cdfbaa13eba1fe184efed5f7091c4fa08baca0
+86bff83086334332b8a75892a5bdc514b75118222bc71b8f8fdacf984edd
+d3be4ccd556cc8f30f6a80c2b20c167f577eeee593323e2207694732587a
+0e5b016b6ade30be2887b8ed026d2df4c539d1a0308b0b09770be61ddba0
+fb20926f07399ae6c9c937401e1e160d0375a89e870917de3cf496597d22
+a8ac67138d4313507841ae24ba2c0cf8fc1efc1ac5b8bb51ef6b50b34086
+2017759ee174b4bcca9087f5c463198407f41df40eadbfbdd7d73759cc41
+a9a43c50b1a0f17deafe0fa93669cb5b11a17bc07667c357b4a22b638592
+b721fbf505d8de6c7d69496752cff0317194a3eba37f42627126fa395596
+f5c0585cd5e6964a1ef53ca1b8d886f29df91782cb4201f873a7f93a479f
+c62ef2013e503bea26d1edbed3ff450c9ad21fc04f4f69f6717ed89e0ef9
+67620edb859bb0d7efa3b0ed2ba5e4d5ba200e51d987b0502ca4b21f6efe
+c5d2f471684fae7130eae3e4ed9006ee5cb14e6b9883622872b1be55e09b
+e1e49f3bb6bf07630c58c59856f23d1f60d44589e7c959210719f7e920fa
+067ad3433fdd490f28c9048cd9fa4aa43d134e3058137a09184ee4ff4412
+cfc204ff4a9975b96af8be17031ffe148304af1c4e012d72fa65baaa96ee
+579ab548ec22d8a40e8fcb2c2efab52984c707730953f866bffc31a81e40
+427dcec529a3be22f7772e26ec0fbc26ebc4a3b561ef75e92c777684ea7b
+38d33d99d8f7ce4ebbe1ef36cec712605921e0cc42210f738b72b8b06e2c
+699d6a786379a2fecea0799175569fe77600fd3fa661f5e9d8e62604f59c
+3318cf53e2fafd68fce5448f2f04c3a55b84aee7f2bb12953004aa3b68f8
+12ce7f25cf2f8a0902d38d735a0b9efc4752aa3fe822223a72272763d649
+6a4e82634b8d5d666c22c8f36d3fa25cb49cd8cb57a6ac7b48d697905780
+1e5de91b50dd5fad9999997b63863b73bb9694598dbfe25705b1dd466891
+0955a5e6128769448d35dc0ed21fb4c017d10cdcd5d24b386c41e2d06f3e
+3c105edadefda6a5ff6e101613be39ba5ef511793e96a5aaecd41ee1bf4b
+85a144e147edecc36dfdec820c54bc5ae17b138bfff4a30b5d10b30763cd
+944935bf7d3ec0ae8396f1bdf068b51951d2a7deacaade053d0a3c6a3508
+1f20c1baf4b76838f98b157d9ccd9ffa669302e92886340a8e0032144968
+a3201ec7d3c87d8e5545992b082252acf496eb3eaec509d27d326d5562c6
+862a03829660ae967eca18eb4bfe04191ddba3e03fb6dbab09ecc01c66a4
+4bfa077433a048b741d98a04f7ea5e7d3104e4d6b1b42cf38f5f4821eb67
+32c6def7e2b067c9ee2cb4ac023ca4c329d381a1a7511ecc33b4bb4bd326
+7391ba5e4a88d84829c541382d4ec4eee3a4683f7c0bad3f219a3ab5d0f5
+a7dc3be313ddd434255d12990a7629c712a55b732ec7651b5fa61fbc6c35
+e3f2b7e2c3b62b72c83c67397413d88ae67393e2d8c77eda593f19fbd9a2
+5f69ee9883e02ae7e66dec74f7ec9920252281a580374e478beb58118cc5
+a11c1c20adc018d0706aa360cabb190d3a9a7dce6ee8c68da7a784358791
+850015a3241691dc125436a8c0cb959356f0c32b4ceafe39fc111e6299db
+8068bdd8564b1200a62c15856dd8804da7ecf34f7d135cf45614a243cd34
+b4e8531da69a62538e6724ad4e3f7a1e2b2c71e77fc686738a4f1d2f51f9
+770684fa270a94ceee7c5d5804ca49220a463e7df0a63aace3a2c73f0940
+9d002d83115af1347b9909d08c0d547b6643466d119f4296094f4cef0a10
+0eb23cbd1cdc7cf6e8bf2363a042c64d8234beb4bbdd329d620c99a65c56
+04277780c343b51f842908ef1e66b125b65387885bc152b50566da9c8b71
+ce360f7d724821c5a06f98b3d5408c01217e483d2d40063bd2be7c447fbe
+b398e050e608d2dbfc8ae8b7516d56a85785a6a63ba1d559976e8c699938
+631b10b5e314493a46edd7df429a7f7529101e32c57f08bba5bb6e980651
+0cc39e14ce46ddb626fd4a5b0e89444409b42334e7d6a587836d1cb0c096
+293b0dcfec87d73dc4e9f90ddc2c312a021af05b95f32bdc4b9616fb6db1
+44d76a2a29e8cde277a703362088a76db6413c840661b3aae45ee5623158
+6c21f8ffe87c30c2f00b6b95537094973f54a5c15375e6549fe45e2e020b
+6fc5f624e8c3a9b30d73d0a397e5a32de1920a15997b220276ba3b9d7019
+255a884555b77bc27c1241af0af4d61d6c8a4ecdbb158d86e21eede3cc6b
+28900b71ac5c945e596c9a8546ab01125f8ab5fb17c9ccf75a8a334aabd7
+705a2df1165c97c17ed678a1aa40fde4f4a62b503099727fef5afc32807c
+051866ca6f27ac4729ac0191edf00281a914846ea08526ec0d6973012851
+e87530591b168b6cd69b0f44a45088ee2ced5d53e05e1ba563351c992222
+f23a58a26be2dcec43ce16e281f79184fda1c9e406044127091d5728d7d4
+0d6906e0f528e12d8f82a6b175e39bbab45a9653b2b4bbe4681da493b3c1
+6a20e5647686be5b07e7f41049a2644befe28a100e4ff5ee34105f736e21
+6fe3e81a1e7d2ab8ad823bd537c4b6c2bd9ee406167117c8b3afd2caaa36
+595fe353af33d30606db992f4dcc8c74e1c1b5ea0eb4722f6c9d0ab7aa4e
+44e61d64ea9cc3ef637aae540d2d0ac7d9cb2dabb1a3be34633601a52d20
+6db35f74f1481a54cdeef2ff63bb310283619dcd7b2d52087cfe957b931e
+7926efb5c47bed864f5dd8e7e5583ad66b34ee5133dfd7b88c9655f196d4
+d5c2d06f478c895c46a27f1ef802f5126477fa407f80d4d2cb55119b8cd8
+72272f0ae88ec5c315aa469e37cb7af969d8886851426ae3e6ed5bc44813
+5fcc58282fb238672563a96f20c2d38d6b6e431af706efe5944f675cd169
+9ecc46444589b0b4ab41c5387b1ae844399ccbafe4cd7772d97448eaa402
+cbdf9f7df550aab54d47e2f67d75f2c364318fad9d08e47d1538c7af06d6
+01f0c31ca9295849f809e6ea17a113883b5e192ba7eb3f9a0c6b55159e67
+c0c085fe7ce9cdee489fbca0662d2ff1a6d55f8a1ee87d0cac3b46bb4f8f
+b58dfb2cf046f530732af1cb20ebbda80adbb95dff7ec28b57355ffdd42b
+aa7bb36b277e6c76f1b1da390c3788e42fddd3931785626db52e9406d887
+adcceec2ac6ee736bcf3454a8b510718fd0f429a3e06dc3ec9de047bd9e6
+0186657b1252647cbf3725767b143ff9bdc0a7b58ada9d94745e75b04cbc
+dd755e2c1e26b0d6f8a723a04e04bac494b36591aea5c8c7a8388fb83e24
+6f983f509a0e9117da0bd21078c3bff245b5e478a2b7331e4f3cbddef0d2
+0020081187c2c9dd0a591a380bf3f6956d7b8d65dc13a2d586da84713ae5
+5b745853aa09b3f3b53de393c03d4c8fddd829d8409c41e967b65a00690f
+9528cb18b3fb94b559c86a820f1792e58bbc45aedc02ebbfa0840c8e7298
+1ecca6988b7beb9312e863064b58618eb1cff26b4ddb52a56ac4c364e30e
+fc20211d6f102622a5378cff950b1b38b8852423ebae51a605487551e4ce
+99484df76277917bee1933a1226fa1026b6d7457bd36928079c5fc2bcc28
+aec99667d1018da53c906f22b71c52c9ee3dc4e72439155717a6d44510ca
+2ba6144601bfa675c5253a4443e18350c6b7a9bc074e8ac973e4b619562a
+43a13be8d31e34af31da70cf8bc39909ab80c03e0dc7e8425b1fdfba898e
+352aaa0a1c4c38c711b3c3ac60a7725e958c0974908fa30d06200bfb840b
+9089e9caba0f3d9b00232516adcf252ea6b73c178e6258eb6a450d29be8c
+f6f66e21d5309f0b75b49fe6abab4ab07e48ddf778e4fbe197481246d680
+e9667c7dd1e420257db762dffe7876f6f8e305d668cf4456b9a0b8ecc6e0
+1ff973144f5527a1e6065d2f6797fc3accb88e5e52dde221464fd77823ce
+f7a0592a408cc0eb37725bb339eea0f792105788b2ff981484d6948d15ba
+51efe3eac600c402b6ace16d145f96ee75324a69a77cf8dc43267a56cbdf
+a156903d2392393a8f12f33ef33f9b9aa7a9d95adf7f2368a34d2c47bacc
+93b2a3a90a1260fc3a334218bfeccded1d7f4182ccaa9879f6e006f2fb70
+20e1d1915d4fb12cf20695075276d27ece002865faf6061edb14d15bb434
+e07197a4a142ea659c24098088be777eafbbe50f2902c12f6fa8fdb57ce4
+852442bfe16a25a3ae9a1bf32486cc0448532f53f82179ebcf0fdcd7eb36
+ea8b7abcbd95a6e67aee38823dc6323862294473982eeef3fb3eb510183a
+7e17e3f87b012c485eb8eb8760007bbd1deaec08106cdab59032ce18aa0e
+81efbe09c87a9dfa03e6764fbbae08e72021aa9aea46a48040ea48e66a02
+86747dc4636f680606aaf29bcc51943fb09b805caf1534a65be267b94f14
+89ad6e8101b9101bedbaca870fc959ce28a2f84e02a88471eeb503d306b1
+1ffcd998ca3e4391c188f6d2c7cc6e82475aa5c375d2d1582f98fba2168c
+4bf25dc8e2ab69a52fa5114b519d1599fcdf521bb4008acdc91c6164cf3f
+e4cb77b79ec74b62053e5d546ce1fcfc380e3c0cadcfd0120b5e6c359fdc
+2a4189d6954ec7d35510eb09d5d305c96e482431505c91734b965d773e9e
+37797951ce86d4e2db76075774bc94da133540d566470e678d8e92cbc97f
+567c8e3da28f9e720c807d92475ea4b5a8b08a7b4ea42e77a979b0380eb9
+d168735406795ce1470a0eb315e9945afc15e8005a27304799434b75b606
+6d051e712b9b92d82ab3fb8907c5cadb75eb597330fa7eedd1645270a80c
+602a2aeea063a0af3054d28cab345e25c6171da1f0600a4b7bb1fd40e4ae
+eaac89416009e991b9c549ce3d9e28fa3c611a79a74592a4f48e5d51ca4b
+b19415e2031e6d3f5b6279ba838d9c82ed40326aa42d67a89f5555cfd429
+9d5d99131ce2bedb3c449989214adadd8989c4905e22475bdbb813e7eef4
+794878a7a538d1e0f831d75e7654b981cae483b8c90f5eb8548f76684796
+ed8ecf0141d598d029de8aa959f9218a862a10cab525ff8dfe060d197450
+965dd3990f96833e583302f20235ab7c04d94d0646b1ee4b2858cf9797a2
+83a9f0b2c9b3695faf00845d7da408f5cd55734ad74d160e97432d3d0598
+1478ed7361754488a5cc4e3f7ae1a373fc2bb30320aeb8baf42864ed7fcb
+4022afa9082a7f0d407b17a7d35e4f7e770b7ffc03ff4091ee9a9d4fef2e
+8c745f32358d89f02782b2e50b265c68455c71282b980c51fec4fa7e85ad
+61909862295cd90f0ca7efc0833d9e70361f69a83a5325cae0132c90076e
+fb416fda2645f347f9e29f7e3b200980dc3213bebc6ffd5c459b8cadd0ee
+530340f8347db627c7a06e682047a84c364d074a330fa91aa3203b1ec8f8
+a96cc9c50b36bf7516b8b3dfb6fcfe504ffb37422a5d2baf01ce5297c38b
+0bc1a7ec3e3570c1dec08aec7991ba2c8907d20972278d2edb052e40efff
+9538cfaa17fca6a50c22cde6a29c3add743a7200a4d8997624e1f7732c81
+3546f4bff9f01c5a9404e86a2b18f7b6759b2878aa4f8a8ff55b36a471be
+7f05d5884aa0bf088b87665901ccf35e8ccdce86811c5c4e4f55ca26ce2f
+10b667dfd50e6063e9914d8340d9533bc0ccc8ebce39f45d3e442eea4a99
+a73e5b54e88969d9d7ef02298c40f600bba274a911cf19532cd01447f05d
+1e424ce654458661d98d4cdc1a747224e90e609c3faf44bb29cbdd1e9a97
+5b475e25ef46447f43809ba72292540cf81de6cc751aa965142705082524
+6291840e4f1a9c6a452bda7ce29d9ef68d0007e7217dfda8cccb40053081
+c4e912ab4a7bc5642f898567fc1604c95f35d8852b7fe5f87caaf247623e
+b6aa53342d231a5047d82dcd33c96b9197b5a41d82acf553f3186fab015e
+9fb21c681ac874d236c9382f13fe672ddee53309b5a46a9eff196b426e21
+ddd39784aca3f8b90588ac9b04b993533483acb6e3125a5d8e95650b858d
+4dd01704388890b26f1e707cc1178f545dc4a3cdf21a9730d3e6d29b6000
+66310e49be5018136fbabcb028799b74f7f15c47afbe30e14bc413352450
+b3fc874184c5e128032918845b039bf2dfe29ba87a2f25a61e6bef64f2d0
+64b1cd13dca3d385443df6d66ddbcbf9ad9774abfdffc05f1227159b8acc
+8daf7cc7713e7f763ac899b066683a3fd14ed9c78e1815fe88a7926a8d3b
+e34481b91febb4c2af569e870da8f964a78b462a52c9a971cff4560a9a46
+2f95d49f759772ef75cc1469fcc61c9ddd6c90e68273e1b02493bf38ff9c
+114d75e7b84925249861275e2508856a86df8e23f590f2e5a1d2fb10db73
+ffa35dddbf1abb002c937ba96effcb828c7bad6eba66ae9337ac5210378c
+3447d9b358a6c449ca1ca82712c422173893b9605a3f1faa92946eda7fb2
+b8dd8ed5f4e5c60efcdf38a92739e16ce182ff777729514b353265ce21fb
+b4871033830431ee72422084a67dea902e0eef97ddf955925113eff9548c
+9f956325a1ef9dc75d0570f42ad14f7dbd09b2578332bc70b0ee8a675d8c
+00e2457576aa2a28d82686773ccc7c89423caa6411fa59ffe01e04f04b97
+b322081105bdaa7e09ff85f9e7cf33756d4a7e2542950ce2ae3acaa62c5b
+4f1072462370676c25c413b1388890cbf64cc9e21a5844e30791e9cf854d
+bf6dc8952f6a629ec08cec95dc9fa1eb166a50d13503cc94b4d9be0fa1f9
+0d8c914f83fe726806be5492837abd211c18f82ee4edf985e12df873d90b
+50d46f1bde2eba9d1823b48e8c67f8e3452600466be39c9b0ab5ea55a9b6
+d513b025e199ceb3d3eed9f7b12d4816c1376180f5e3527b326cf112d138
+bc925c67b4079832dc086e2c539de03f72fab6f09c92b8e8accf2ed76a5f
+055241c205f112686449494de69d6dd01300269b1b054456703c2e82d839
+0bc7d46b87c2f02e65ae4a1d4748bf0f01cde328bd0befbd31c3bf30ca09
+fb3c18524bc7f61cf2e97cec85045bf8ea9609f3644ee77ef01bf5f3d8dc
+1e7ff01370c4d007fcd06e7b0b0d1fa190784e9c5e4c93324cf4fe5eed78
+11962ad08a13ef0fd2990737fe01cda020105153609116ce605674d0470b
+438d73f3dd61f3b0059f71a291f32cf463c30ae38c20d2f4cd52bf2fded7
+4c59f19d7cdb97a0dbfcd13877ae4023cf7ff1db8d7655fde46f3aabf95f
+5c4a3050c3f9c35635925f06e820e35899839043fa416b4fc284ec3e6dcf
+d8b305666b93a072e263d0d2b1dd85593a6742019b9aaa989b7307afbdfe
+eeb6e1c2429668c177aaa0aa2f4e27495b18188eb77b93f37348e5e9f1c3
+de961b5b67b109305d84b1178d35769af4ab928c2ff5773fa7bd00ec7435
+87da5c4cbc19bd3cbc4f7c15460213c9103bf7e1bcfd8f3899422f83461f
+7a8c0b9d111f64661955f4bdba28783409f6cf5d54f8c6218e0797a03470
+2068423a4bfc1b19d0be336d990044f084466a2b2d4198476eecd1309e2c
+30e33e8db6202fd31c1484f531056816cd25b80c4b6ed9b1ffde608ddd16
+84450eaaf45d813caaf938e4ddf3ede924a22c8014a2633155d90ee23acd
+02ccd37f0e991080180191079eb3303ec6c685685debe2ed67efd2461abd
+702402a4277fd06381f9165b872f3c77a8468413a5a2dd02a61fcde44538
+376f3f6d3cf72d11fbdba81c400f83e7ea6f4386911b3874557af334c774
+0a070d3c19767476ef21dbd9ca66b74672371a6541a9f3f30ca4dc3afabc
+ee30997fe15ea3000f497b4456d219f8492ccdff2b0a8f7b6c865cb890fc
+075f715f82b6fb531cbc68d344cae08ec83ed8773be6d2632b239763e463
+2307b3207859b2bb1ca39d13bc2763d127339ef4ae22e91adb9cb0b6c614
+7ceea07996afaafa19e0bfdfdf9eb0ac43f73d80af7245d80c5b03047e4e
+0560fcb832ee1f8ef02d4054e72879a3fd64feebfcad750abc6575585ad5
+9d7a21681ee427052ab95ccb1283d2f750bdcfcaf1e66e69c9900514126b
+90abc69efe5c976166b8c4c0e18f94ccb014a303c61b80298c661a6642f3
+af81766e7dc6d699a7780f93a538863349dff728a0557f30f95cc2b313df
+c4c8f12e2a94c9e3f324be1b98142b106f190e30783b0858aa51e9ca230d
+d649883b6f7c2a8dbae39908b34b60a67b147350bf8ae770619f34f9c604
+c70086c8aee426ce5a92fa9227fb52ba82fb17cfad27eeb2b5efd0c706f1
+462d012447ae3f6837311283d7abc3e866fc68957d3cb4f86175c924218a
+a95f7593c4277a7d0938869c2e07f10446f2d45ea9a2849721de54105611
+b086988dbd56ff72e85c4d01addbaac1b053f9a47dda22ddc6f01ec98df4
+0c74743f59d149eb35b71e55e74b5babd36c0e4a24ef5afdb7dd3823d725
+e294986a66bd545ccecc5010f8a6ef2eb6047a74e68cf2623b6ce84e6a0b
+37933fd249991b018b0b6217975032700c81aae0722f5d915654cb9991c8
+0a61625b3742e76c692a042ae42fb7f4ed355f6c3fcffd2acc794de9e08e
+9dbbd39559620d2819a23e85f7498f0076b6230b7f93de99264428ade3ff
+3272bacfd3b52ffd92280e1d1937971e7243eff8038483de1ac2cc000fb3
+94315c35da446f098ce72e8a3f892a71514426abbe6baef9eced76ff16bf
+b30e8647f0e6ca67a987353c5f8848e036b54999b10d6c7899809ffc6611
+76892d7ffd143dc1b0978ad2e6816fcc5edefe51b609f1364a691cd8807b
+4e96348e9842ee5c2457e266318d5362d78c17b303d4cda2f8dc91715f0d
+de5b76c38636605a1a15d1be95d9f23f12fab5e480ded3fed2594a53f852
+1b022aff4c1ab2b44b1fbb6c00286c69375e9e0be730676687ff60d6f2f5
+6f8a75395e15ce545a0a1e5fb68dcc2ddb647fe9db6169af984829859bc4
+2273a34a6806b81d7ca4ded3922cb3e90d9c699d576904132d84c69ef793
+097bc90c59a103249ac49fea69300402e5db75b1d6e36ede739d91bc6d83
+042db4ecaf5e68e78bfe009a6a6549bfb7d538fa5ac80e27163680d951a4
+8aa5420935d71b66244bbdf4b265869761c7aed028429823f530138cf17e
+851fd33eefcf1cb7e3a55798f149595f946dae333f37ab8cea8846ab80b0
+fd354404b5e5eac4cfe7e6c3e7a66311aa8d8b94e8c59a1e0ce7e3495b17
+6f8ee8ed14c1e033fede44f86b1a3017b820d60d76de408b6b01041c49b6
+9c715c484aa6add4dc3147ec63e3172bfc2380535e2639d41537b053a880
+e99de5c5bdd8c9672a2c384ea8604454b6056492cc866c2fe2f1f9556930
+edff9c6db7f08d70addf50b736c927fcbe4397a572d9aea57a07c4dd6a7e
+a02402fbf21d7281fdecd10faa6cc51965fa70cbd682834227e45cffd154
+99aa79774c99c0aa9a3141a222e4db99fc4a91e54980ec9c2b10ba3dde47
+3c402dd71dc879782a29c0f75c1b954c8fecd5c181cfcc5bacb3edc38b71
+ac74f098fa0a1f0003297ac9209e4ffdde948f0a2350cc846eac61707b07
+871590855e555d395efb168a4011c969ae12f90dc87a38e5449fd300f611
+1a50af202f1d5ad3a62c71cbf636d82c27c35cb4f703e7773ca334b5c7bc
+6a95cadadcb55e9ce68d716bd77083855d0b2a672a29249740977b7d848a
+34ad833a1d9ddd4bd81e7b118a62e30da770bd8b2eec33ad1994a581c836
+ec81f99243a9ab233b9e2a0f1b10623797600b82cd0569a2da414ab651c8
+d6f47c0a81959886555a46204d74cbe4f27de08a4211ad764b9a330e5b6f
+ecc9482c391ae086e7544ebf566ba40ef67a6ab4526ddfa4cb98733cca0a
+589903e2b5d7b82364b5714d7b70e3d94eee6bc2786653cf6591f9feb6a6
+d29b3892f33014f2b0227706136b31ec68ac6cd68d556023c8054d8f0863
+32df1ff38c028101ed2db0b41b610640cb59921ba2e251bf8d6bdb3c8eac
+81892c19e354f74eae8ce11d62ae12dc2a3ea97551467907d10381e4df58
+47ffd1046ee994902a4c425ba917f8704ca654cbe93bd04c68b40cf79109
+dd2bb3720404239f5a76119b63b397252fc6ac606fdcb408bfba0031ccd2
+0ad3e6467a09fe11788d91e0805912389fe2689cbca103e7d10bd3784540
+7965f250afde72323921fccb7bdb1196d81fd49f3e99a875e301e683a37a
+9a9d95762613561f41ba1c5b7c64362a508a177247ebcd63b618577d252c
+b442801c379ff346236f4d41a83a1adc16274ffaa4b2f95344116e710b11
+9f0f0a1d66f84d0fc97c6060f94ad6e72c4b821d6d7810a24ab2eb94db25
+e4cde3b5813cf90da162659effcdd3486f8e451dbdc433e48bea1c5541b5
+cb35d5db507b69397bbbfb0e12cd481f21d100b95d20bf3042a9475c9c9d
+d90d8c4eb78350c96dd2911d15edfab3b465c7a76963aedc862ba628556a
+993b335739ce074305e6dea405fdf5d867587b750e401ad170fcbadf948a
+b92f5924fbca8dd8659fb8d88fcf1044095b3d3ecbb88f4b77070236c514
+386c6492334528dbf986efc85f9f8e971790d275e0c7aaf0bafce2f470ad
+039413ecf2b39d846949c932346a1b04452ca11f6ce36ef32866ecb65012
+55c1daca015bf142bf33956d30098388c817517df95d8d5e51062bf2af3f
+aa3a8f0ac463725058f1eb6943d6d0a178d690eb13a9ef87fb1f85b0fadb
+8b6b2709aedcbbcb58ff7ae6c58370209aa60b152feee0a747b60f0b4252
+2526c78231d792f83bce107ecc4e8322597511c7fafd5aba8b3ab0f51902
+2adeed89c0e61c899eaf7e509a3dabb399a6f4c5d7ff9a68b50afbdb67b8
+9e4c7f39d6574fca0d64c4fcb0e54c1589cef927f983940372f6e21b083b
+7bf5a85fe09992677eb32c9fd46277c50fd992c478c292af7e05a3549f71
+2c66bd2818b827bbfde2c481bf489737a71e886f37082afc5a8c0b02b7bf
+a7fc894d8849987758a4fbac084708a62969d7192463538cc4cd31eec7de
+061b00da5a09cb1eb97e3c9a2c2041024a620d7ae2baa99cb070fc01bcbf
+b1243ffd06a4c9ea6a4d4df42f8738fe52a7252cde570a7296aeb5ed351c
+d4b2f6438812cd61910a4d55d772a881cb186d3a3743cc132b27306bdf60
+c3ab4d755e3eff8e10c2ca2431a50f4f4b3bcf60a5112a8ff91bd51eb0c2
+c144aee9e927858826e203226987b292c1d7f8fee533b57a9b055084cac6
+15915ac3a5a827ee04d91fa9e9e267e3ae44ef1101491a27a07129219e9b
+4e20792f1eed42d5ca89c4c49753af7078b6eb6e7a56fff7cecab396b839
+8afdd733ad2884f7bcff5b42f64b4b056a709d656b0d5eb40a76a5f665a6
+9bdb25e0238aac35c5c0caff832b98e64829319aefb07fb974036e0da982
+6129db7ac52292770facaf02bd6afba8862152bf4762425ebbb22d7b6f08
+d29928a53b11aa35516eaea9d249509063c539acfe3954e1f965d2714b86
+257e9fce32cceb0a50661f875926ad7e57ea55aa202f62f88d51a13e6b91
+19391b0753987a5713d7cd96506cd2bc9d9a549e6b6ec7da0d24de9784ff
+7538dcf32ca736754cce162d2008a41fa1c7999c2a8f72da2c517e06f0f0
+77bd88a2ff890db0586228842a011420efe3e910024492161eb477fbdaff
+af1e73d24b75ba72be5c14358c455d538585754e9f6816a226f60e6d17c6
+6c941f516c1f05a618c022c1a7a8874cb0d3f7acfb6fd79d7601ad6dda61
+1d31037f3739bd128616278e7025ca836708c855dee5e3b449c6c5904b95
+caf4c2eb09519564c48af781fbcc49f0dede6cb2be8718c515c05608549f
+d5e54831372076250be22a0fbcdee17fb5849d30205e347e63b8841d1ae5
+71b2c372fd9634e9f16b4823f94dfb807b7c09840f92409ed8041b1515db
+9df22187451f3e3b42737a11611a4a942dec953cfbf9875d36a363e3a2d5
+05d96b6f8f03b7ea1c251bab2ff79dd8cdb28796d1fd364b1103da119bea
+64ac34659023685fb8d5b2755ce523b32f8532845e4c3058036f0862cbd7
+b7d4dc2020f7d29640b5007a78af6d931512aa015585bf80da89fddce137
+02efaaea51c51c856d7c8a7f285a997d749ef5fddb3eb145f51b1071843a
+ff486c7ade3943ca2ce5387215faadda2db4143311617f6281fbc3f8d261
+0272cf235564703f832e85167cb444ed147fae675654fe08945694f9e63e
+3f1fc2f6a64f6e36c0ba774a8b20bad6115ac54450e32d35031e7555481d
+cc0229df599951e758a654282dc75e6242e141a3156a5c98c533228e8b51
+1801c716665dfa23fec5aa20f3fba6ba37fc88258dec647c3b4c85b663c8
+30d763aaf568bda38558e4314b6b510d974d9f21c783c4498eed62c8db29
+bca222f27910b3d196c0e8502b234a739da32a0f6414bfc5e4c9cc167989
+48f996f1b30d1765fc99751beb12168832b5f7f91a7df5940eb763731f69
+939db425ed380c3ffe2b415a7e960055bbb7ab436e6b8cd66a12a6662cf8
+8df26c3890beac4b2b6bc3c075716614d2045a180905eb9270db0f8e42c6
+c4114f285927bb03e92c3d9301710dcc17190a1f78151388d70aec38540f
+031e376d8f31da955938b22196ae56776826c7a658822582a538aa4752b9
+694a5e814ef39c1df410b75d00cb9069cd47b8bf1838f92ef5a1b91daca0
+2d8798c1df839c2430e8d0284e1d16ef72b363670ef519d0d06afe326f37
+ea048fd2e09c151103117879c2efa268645584ff4a1cd478536493adbcb3
+e49e42e7b668d9f0e77ac5a321fd7f339caafdc93267144f9467b605c869
+04c3d1b86bc0e1707b47c3a4c1bf991ca356fbc32e635623f44276cc7358
+da5441438b5fcb4a675bd60bd112cddb4c8357595f7af082af0924123e67
+3a1e74214e7e4198fde4aef1e85e129b6a78a1e975978ef2450c63232588
+6da46521b93748413e02185ee061648cdfff10ca5249d19faad78619783f
+c10cb77554bb502a640e5b243c9e90ff169a855b65d29d25b4d30de4e53a
+139e8a20059cdb796369ec40057f74b7dc4b5a4d3dd463c66be4e8a0026d
+ed6f0110c45baf21f197b649026aee565f47c27a4abc1553790303bc2b34
+adb7c6e54723794eefaac4dc7145a7c3ae16c6bb635a704efcb2b9bb6516
+7654245ae5d466b436232a47d9a2247c3a5a4ee9a7e6f29b83fcb9d7082f
+aec5caf6b48976b000ad92199df65742cd8de4af0541461fdf07f44e9117
+8e8ff2423e01074704dae7370df7080d1745190cc29435f187afea37e30a
+a2c5dfd9c4076e15c1d80b688acaee8ac7f4f6f5b5a2eab3978da7c77958
+719c696d9a545be2d44b884eb94e873942cef0ff497450fb0ab21c392ea6
+4cbec0ab283283ea4b739e36f2fc145fa57eff433e36fbdf217db34f8efd
+02f7a15b77311a506749478551f11e1cf0c984ebd27eec2197babc950624
+2f7c425bc0bb35a1d332c3d7442433ba809a15a50a6487a1cee900a9b604
+747c6821512b934578bebbed7d35d92c35be3ca128dece0dd8e6d61572b5
+6c60a75a230932f6c8f13a0c82475d819d419849c046beb618ffd2ba9b4e
+35593ece10ebba2a923648ae9d921255277b6e8152837d74782b33ff5ad6
+a07d8c6c1e59132d3e5e1f1cce864fad1f7963b5017c7ebb3d29f2af65b0
+dd7322dd6e94e812f0ed2770466a41cc40a6cb57453ee0de32a633a867d5
+fa5ba2b86736a2d2c7cd94af3dbc925dfc2ddfeb04f40481507a287e1ced
+bf35ebfba94429ce54e6b636c33d8821708cfec3a450e15c393b5d5bf7cc
+848c9c5780dd966d01b34db5f9c3137fa0096368f2ae8883e62cdbfc6132
+f7687fd1e9614779274f6b92a12a6d4a8c415f59510913cddef67685cb4f
+97fe0f7b8ce990cae9d8b152b1fc223360fa5480e23d62bfa69df11d97ef
+8b9d4f8f047301f5db7ee34b4f3996a6e226b8b932a195cc8ecdfbeb34cf
+2bc204769a1a1ab2e6be18d156d3c1b0b867ce4ac4e57203585f98ad8ad4
+a1c2cd9823f609af8be966f7cc89e787435f312b7c67c2f9efa22f169a5e
+81c8f3de74afd45675b477ae9df1983de2474729ec80fd5646058051d8f0
+9b253e57be5540ba0b7e9c2a588879d45dac2e94941b47052295ba2909b9
+1db7313ba5d3c780113ee736ef57d7a9aa88031ae61411f32ed3ab2cb97a
+978abb27b822c44282ef5168148fc32ec991f705288c8cfd6c838a37da4e
+2a5dba5d215739005fec9ac00c546884f860db130cfcc1f181cc5f913f78
+9bfe610099cde584d5dbb15604665617d1359d611049eff679aed936aae7
+c27fcde30555f0ee39edb8512bde5007aa9b1bff6a4b6b56e883bd284e21
+3602dfb4465d3111682d4e2b3e339fbb0e0455557281788a6b55eaa5881e
+62ad1cbc65d0ebaad4a5600899b9320a0fc98e8ca2e7967c6c2ce48910d1
+80bdcf2f616e7536f72797e3b1bf7d4fddd08179f5f3429bc3885307089b
+9f4dafb2feaadc8a761f6b41f9d7e6ce750d5d8ffe999da55dc239933bca
+1524aa0078ee24881e120d774b293f1593621230fd5294428653eb453fbf
+97b275bfea389bac5e8ecae12389b15f64338a59131f6abafe3f632c215e
+38f97abe80d3fc93352d0e27702bf83306a03faed8f89160416f1c3ef5f5
+388f2831370b64bf7cb737af5ca95a8023815a222be811b4b85cf52beb04
+6f0c4587643fc0da77810a69bfac4c0a4a71dfd0c0ab2d5635020d264958
+8a8ad4e825478651950a83d5f0f2bd8cc31e825074404d16c05354d18730
+fcd42cccd51437a2f2a90a6a9e294d30a5f5e53f18e53ed4b60f0e0f6159
+4fea136f2ed0c8af5ef7cae946b33a18d9e2d0c8b8ad3ff0e1908d30ffcd
+ab58a28e59fb12d1f28e783ed58e344e9105d9bdba8ecfb7b0df61cb7f43
+7924ff7160563be7094c769f36fab8dc74207bc789eec011e34ef81e3747
+8cc4c9d5a1118ac0a685d25136f7e295b84c060f4fb63ae4cc8af1b96ada
+4b183b054df7ef8ca30aefc9b0cd2345b728a622e2424ae0aa578c065e58
+e8c34ebd2b6df648a9780dea293977946a9a3cd8ec4779f30f8a4b51000a
+55dbefb328e2d5098dbc3f9859d49a463fd24cd8c28ec426088245b09080
+c79ba43fc46dd55f2ba2c190f8c13b0d883fb6737bc0f9acb5f0ac3bfa4e
+8c346ef5d0a9a617bfb9e2fd9fbc68e39401d5978319fe5279108675e8e7
+68f42e01a0b8c133db1c8be7e0a553ed1c1676ed488b0583a3317f233f7a
+4335b7b4ee205d1d324957204a51a0b37241938fe2a54d8aec4a81493384
+590432d5afadc3a84b4e08771be80f2648acf9fbc777a51b530f0ca34fa7
+a8a8a1cb391d0db8f09f10bdfc1935204231718494dba12bddc6fffe20d4
+f3b7062feec978a0797804898db2f14279363b72708d6e7fdaef71aaa495
+ed16db39e5ccea3090cf20c2c0d66eb908ec814daf3f54b4465956efcdfa
+46071a0eae7ab79a2e227f8b2819c1c5ca018646106b35303ecbe73d4923
+8cc10f3bbbc943bfb7d547132c4debc1923df4e8120a3226cb99eb8ef162
+5468ab720065d6baccca3bf4cdfb2f92b61428b033f26b985e8411820ca0
+cd4b5304516465f29c894a6c1bad8942dee1382421a6c06076dd06451ae5
+83b9e7abe0e273365247fa24cd68e9b220f2bfa35adbd60259f5a0de4b66
+0b0241841e2ff4585c658683dd9e6dc847000b238225990820c1faeef4e7
+39789b9e44ab037730dc4f6c60db05e7847360e44b0c14e59af478cf54a9
+670ca35d4ee3e3f81ebfc58043478199aa0e35da74b4ee11c01178e44235
+2eee2f57a651fb1be5123acc973848dd79b1bf5b69dfc2186662c9a54817
+c33cb1a6b589eb64a5885ae8ed5e8ffce9cbc9f1d04faafd0274d5702c22
+09ef9e52b357e22f458bd3beb244fe88c36d088dda229e501227caaa72c5
+8a7d5a95fb1d7e380819daaba59d2eebdc5f7cc2bcc042e73f13f2dfb19e
+f5ba70d00e74bed0ad73726dcccd7b3ecd016dc010185bc34aac6722927e
+c4cfc8d40d5b88cd5f01f20d1bee72b715b9d4931d81dc972c59b3124ca3
+5e773612673e4393de8b93b9b3c6b37860330700514cd31919f42a28f9b7
+c81431ac8912adcae98269d6a64f82228f0edbc59de4f69066c476fe351f
+9869a4bbdbecf649a2e35d019e90a1d280a1fe55bcf528158ffb01facf46
+d9f6eb0266149ed40307d9b070ca8c5e434cb7a555b74d18a6069784896e
+2f250369fc6b6fc426773c64f33497abae8096e2499bc1f5b087f086dcd3
+c5bf9b76d0f50fd3267b319b8363f14a342a90cf0236e8bd8ae8f084af23
+7d04e56efbbba1e86d352ff817c67baa3be98fe63fc4d04c7c18a76573b2
+c66b347f7548d79607b84d90899dadbaaeb9fcd37b1bff2ca865baf35c8f
+3e4be98064e0fe57b8c9d5caab1aa997afe6fb62530ac8833236d5ac7fcd
+65dc18e1e02d059179ee02c33cfc6f5dbd06091d08942f420d359753ff2c
+9edbe16cc23a97cc6b66d32be0b41e0dcb983aa1cbb6534a16e8f6e8b242
+2a95b880c61351a76e1d53e5bfa9aac679b60a7f9b2dfdec878ebb0ad30e
+9b6febd33f986526f03e43ddce13ad5264521a8971752c01cae738ec3bd4
+e556dc6bee76a8850f0ef738980274448a00d8681787a314dc6b1cfb81e8
+3825f3b04ae252ec698187d0a242389eefe1eafc054c9bc0c303a8ec23c0
+63307b21b2a98034f6e7c4758be50cd35474eabf2b7c4bae6ea1cd50883d
+62a38a22819cd666ac6d2f39b1fad6fa4034416c03d9795e4caf59215672
+f2ae88619f172c311a2b7b301f30cc312530762aa42361dbdb7640342928
+98955bff38fc2cf6c716ab525118bf0b7257317c8118e9253a1aea6c878b
+c6377d6428e8ce5fb78544930a46d02b4b08081befc78402ca444c742c20
+3dd1fa3dbc351df112dda778b1e5c3984b03ce9e7eab15dc48ddc469c7ef
+3543f8e19533ac32a3f6b8b12103582303cb46086d7eb69917b9e22f92b0
+7f794b80f5b3a32e44d88d2e66c9e41dc9d60e346e0c99ab6604bbea550f
+be4a1d9656d3d85cd9b8d632a1354b76dea1d876148d9bfc6d7108aa1b12
+6c17dd16a3913fa263fb94274a2aa4ce87a122d72770f3d0afedaccaa121
+bfc2f42f7a0ad1787bc858c3f6ab8cdae76d868aa3bbabd1e166a7ea0560
+8e5eb1068d4cf2d77264218da1ba33e4f1cc3d24868768747fc08cdcaf57
+c67b2498246d7ff6f33acb2f83a970b6b67aee0b2fc0b76c2b4bddbb9b98
+6c5a0d2323416dd954f7036237b18cac8a1ceafe4e6fa1d2396b487a03b9
+b3301ca9b795626fedb3293b364fcbe29b8e606f35863284322d82bb2075
+737e8062454891e245e0f1ec7743f1997b3b36d24d94f69be4ba218a9436
+466b79d816e6a72c7306e3c2711849e9a941983cc589e2f19ed18ddff751
+36e253edaebf57b674134684d1faa21e014b9d5475ae815f56b606ab62f9
+ae1c32315a1448ddd4151d06f4aa1347444d3240df4f82f9fc5dc8709112
+938acf9bb25e7a4b0fef0dd2515b15dfb40d174048ed2a3d841bd0e6c821
+e07c5e959c17d6f2ba659d792c9767b9172453ae9c415a6aa818f3999167
+790321df7695fbea76ec20fb60b516f84d59bfdd09a2fca1bd5eb3ece33e
+51ed225a30c349fde4336163d79ba2053343ed04eccdf8453b33f9bf033e
+ad5bf59225856d7a691657cdfe29eeafb146f41d4cc9c8d4ae0d2d287a93
+c16dc85f7308390929bef532aeef8770b9af6ea7fa5e6e968d211d1f0cee
+98a09a4547ad609f62dc6b5ba70b9a29ddb3faa15102a56a017b9fdacba8
+955f687e2d4ebac571937740f1c6a3e5d9584ec9d7758fd27a467b273e5c
+5d2b49a10f4c935f76a0718347ae59f9f5e29e8f2695664cef0a10112636
+48d486e5ee9c313b8b2f0ed6e9c9a6a5ae154e1f1db95164fda121feac07
+7861c85a765929a69e157e13d25e5e053bd57d16079119329396e4b3ac48
+fde80e0954b665d61b7d3beb0e7b3800b4fe7eccc741581bd4ebe45f1d09
+0ff8a13ff6ecff9b76ef312ebf48775e6600e8261d57dc898edbec1ce72f
+9806ac5a9ab585332133af60ff2ac31b6e97d28bd232a50d28231595d2b2
+c21b253a27a7d430a778ff0dd446bbf93c37c1a4fb1ab70ad1c6615b515d
+72462d81535145ff27630debb40f8439e093c90fec7ebd04ad81866390ef
+8df9d4d4aa47b8da9ff7f5ba3a3a6cc61918639901f4c58c86fd1844c05f
+e795ecf8824e5ff579b339e18cf298786806e9159bc98694cb45a3c33c51
+976a86deacb2abf0ba891471a846ee9f0240ea834f1df61bd439ab8a04f2
+35514a667bca49982cbb4afd0f0b0d9042130b4376a8cdc353ee7846cc80
+d13b38ff7dc0f722e241eb37e015f2c3c449ae1ac99086ab4d09e359b4e0
+cb40fd539c3d95a177fd1b2b6f827dda8f4f37db4d2eb5c9cc0c05ce664a
+e275272d1f131afe30c97e4c1ae8e40245757cecdda343fbf57f633ff29c
+cddd45c54eb21a3e8d11356f26c4d6dfc4cc24d14db7d1f569dd504458d6
+421241a9460b760cc89182a3be4d5e274fba17b0c66a73a31244f94e0e25
+a89a4349fe03bb7b2b76d5087fcf01e23ab8a946541295fe3b8158c19fd5
+281982794babd4d8814b278218e89e9338c7031473cb0670c0010c62ecb8
+d0c37abb74a68f5532ba49f479dfa276b91dfd95d4689f7553de743227aa
+96b674dcec8186556ba8af629a79c624de297c19eaa86e274b4ccb3a6cef
+807469a797eae637909c19232f2801b5bfad8a6bdc6565bfc0c217004854
+dc654c7d98697831a625b3ee7ce24f5f05b0aa6ae0187c98c221820c5a23
+a27533ded30354c4caad3aad261ebb5c0053721407d9eb6bd55380930840
+7de038d2c6a6acd77fef74cfb5d961dcbeaa2da6b8deeca64e4adda73672
+56c1361c7ea99a6b95503fe901d056267f6e36db78d165b74483576e36ab
+a19e6801a33e9e0bc21eae2a0e8e56943f4c2fbf9467afed079849635579
+ea81fde7e07a1c9bd12c72eb2ffc2250030bedf8d8542ffc4b8ed5268925
+c56bff45b33e0bb0f94e12ee694dcfd34a57724cf3b9d347d7a845a0c58d
+a803b999da53cbc1e3955ead076ce86f62085985c9d9fcfdab90b2d26c73
+d767084eba703a13ae41ffdb2a980f3ea0f0b67ed5a0aff4b4186bdcf217
+ff575b1508434dfce67a20e40968257359d0c210b28dff561b8ea85aa74f
+b443daa56f4cc37ac6f5cd3951591acbb84d036170156a6640000982e7aa
+aea636f726609982cc39cf9f0c42868a69a3a54d180400b29094c43e624f
+bcb7a087b54cc2ea930f8740828b6b6d7219ac2237838f63df73fb99f4c5
+1de03e578cf7047bcba4f08a7c56e008284e95cc
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
diff --git a/fonts/Courier-BoldOblique b/fonts/Courier-BoldOblique
new file mode 100644
index 000000000..e6ad560d4
--- /dev/null
+++ b/fonts/Courier-BoldOblique
@@ -0,0 +1,1686 @@
+%!PS-AdobeFont-1.0: Courier-BoldOblique 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file COPYING (GNU General Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Courier Bold Oblique) readonly def
+/FamilyName (Courier) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle -12.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /Courier-BoldOblique def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-61 -278 840 871} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020948 def
+currentdict end
+currentfile eexec
+e98d09d760a3c22cf119f9dc699a22c35b5b35ed6aa23593c76d54cabb5e
+942bf7d6dd84f1664b89699c74b472de9f8e6df925f6c4f204e9f1c639b4
+dba988ed2ac419ff2b2bde605b8ee3264edd66412d4f21c64ac522bdfc7c
+5502f9c3f3e5592b3b2093d33c9bfaedd2d49e89aabaa832e23f062e91a2
+5032519d1868816e44b4e0747795003d7930299d6e1e2a5bfe0d595dc97e
+140989ce81d8d7f852ff9cdc7a1b1b598c69131dee005b415805a16d8a12
+3e6a2f9dbf9f3f34a085f42fe63acd931cd846b57d30dbe2d6b4b42ba7b3
+841204cf185aaeea797b0d16df1d60060bebe83fbdd4931af1827b449bef
+2eab8879ebefe5590120effb8f783be00e602fa76e53ee4e20e9a55189be
+e40ecb842d3838dcc54fbf7423229ad68b98e033813b1a3e460f4a9baea1
+8760d05d85984b0b3e161f130d92ab90a1f47416b3f21d7797d284422bbf
+3f185bff2b2de126046d090be44f9a5d8e6c800defd3a53944fff17566aa
+b69c8f5e58cd7e26c105bb2ca8ac07b6ff104375a98e23e4ef5f370311ee
+aa1954169cdec1a823b51f1da93e50a6c032630f0ed2f0109824f7aeb6b3
+850ec9d1c2a9bee7dbd8c787f78a9402f96c7fd756f9c63151ca0f742b8a
+1ee50d127ea8605c1c1fe194833218e91e06261cbf154e7ce4cecbb941d7
+659f6da4bd998df9fd184e6f6cb0583c8ba18a7d26c9e8cda7f79784f053
+243684693700a482a8f2182c9142114f25533cbf9ba2b43d833aa0fc1d7a
+95ee86cdb19921b4e27b487e2e353c8b942bfdcd06974b8115fa20291f25
+71fa63555110b9fd8ee1bc9467ebdcd4145b372ccad7e9f93460449f2433
+1a6030294c172bc918b1266271e8c39e52850d83d2a78d8fd2636d3eb927
+7275f14498245fdf262d54ab22c919876d3ab407f07fec8e23d28acb2d3d
+413757ed4fbaf2d03dbaaee70345f62672a238589a03b28b03a3a1ab6b3b
+970d28d2f747facb07bef7e8cbc0a847898f00e6a27320cf51db2e143935
+f16e2c6da9d1eb5481f6e75852c3bc7cbdbbdeb5b27a299e1a4003b08965
+6a96de26fb54d3fde40b8dd64d01e330da29486b752890a2e0802fc871ca
+86cb8eb4037a72fe7350e8a87bdcaeaf182333a6bb929b7d202bd5e4d1ac
+9ed69d15f816e39d45089dbd9ed2340302f639496d60181c00c3c8401715
+85c34d9791fcf040f1285874367e125be582088c01dcf773775039237da5
+33e679fe7dfb9b7221b04f2d69add19ecfda0b94bf53dc389fd0666e7fc2
+92383995518fb78173248d9ee7f0fe79ca89ad014a1916da267aee3ce701
+055bc88c4cc0053d8d7e09ca072a04f15b1871a3c1113b29df7fa0c1a608
+8ddb6b2f97e03d829f6de8fb1c51d4e3448730fc94af5d62b69e2afb843a
+e2a8b12d5046e7bfe9fbfc2404bc6232e352b25a128e8a501d6fecf02571
+9e1e1ad7890b40ffffb006dcd42a65402df37d8b2b91ccff1bed30b8e192
+b5f2f53d263ade0798f2fc94d19693734b16ab45ae0d000dee662b209db9
+3c541fda6d822a4e2349f3fd199a654bb931cc36f56bb2f5ec563398d385
+459f964fd343d9b253db726e9d16fb240a84f39bddb76aa7edbaecc0124c
+253cdce59227216a0c74cef8e44ea7fc0dda7433a3b0fa92a0f6a00c43de
+f2f079668ed3e9929056dc1185dd78c663097fe8153aba6410dce819eb69
+d06da03fae4798505301235d725ab2601d935d80daef960061a6c420a696
+a2a1096619f8f0894c659a61c4076664e0ff1e8542acef3376b8e2b48975
+f8f546b1ca4ce7bc9e31fab84df061fb7452459c6c7b68616c8c3c53d4d7
+5830e418fa8cf6e0f25ecf30a3c9048d6635ad9e9f4ff04ab84c2ca1b4da
+a9278de5fd299872b1e57dd7de2478a2b21b2eb96896ba53690a7be8a0c1
+2a8e020dec6f3fc741998fce007033f9959c1328b2785c1a8b26351bc740
+40b30fa99c4c8c7bd3c52aaf8c7ddbfb0dad72d8953e25ad54afc3b53f15
+25a4bbb12ea7ecd712b1a4029742985a2d57223762d6d83688457515d90c
+a3ffe21d9099979e4ebc79bfac708da0adc420c676ad5971288aaf2b8dac
+4a74715cfc76b1e6d52501e0f776b65065458e63e16dc2c6d6ce18adc8ba
+94130d2a90780a127c9b3d878e9426ce14967f8e65e4bfd9f47582ef2c37
+c361c1008db7fe245a6dd6c5bf8a84ccca05cd96cd1aeae072c09856b336
+563e66415b727d58d62e9dcb7382c21bc7e4503c30346ce2bcf4baa2c87b
+70f1a713ea26fd7793b114e3b77104d5f1c5ee8c282bc01e591c068973f8
+53c5788119d0cf53ae213c1770abdb1cf3fbf80a3e77f7db59f9302ea55b
+bb16e9f775d04f3242cad88e2a1cece807db59daec7cf7e89cccf7360ec6
+11deccfd50431d67fbe30e80843ab28cc0e3e9e1374c24c15567453e8e92
+8e7305fe9eeab4e3c8b1bd92140bb0d4d40f80bce763c25bb90f35a6e907
+759e574c7e9d342a2c78b1b78b68cd9301075e6aa6583a4e18528bf066bc
+84375210a973dd1a60a693b45eff6c51ff890946ad331ac05ef80bba6084
+24a582968548d1c5640cb8285786fde01cf8fb15c5b821c5577f7abe9683
+c164ba9a691906709ac46d664b833aa7fe5a3fadb67ad3bd82ae43087ce7
+0212b469cea0e28bfccec30496f803d3ec1fca366ca925ba3f20be9c34d8
+2d0d7215199e829f4d0d7b4e9630879da68ca05161e431b36510804d97ab
+c1891cb76ca24bfb7a897835e67f2c2ad7d0971dbbd6814eb6542f7e4fa3
+06fc97a058406098c53564efbf4689dc448fb69080a08a54c3602b55a681
+09d3ad3fb83eeda6ddeda6ddea4ea424553ec22fbddef65254488f91ad4e
+d38ef195c418428eea7fe850c62dbac2f9e3c9cfc86542153d0d5caf94c7
+89160cee1fc009d0ce68951a7ae1b666e4abbe82a1c6a3e95859352e8400
+e1f33c55626a04c3818aa8a917c3f5755e2eebcb9f3151e2a02339bde457
+4d1a65af690685ad8dc4a64029ea5bc1ea733546d0b0f8871cbb56aac6d1
+f2637c420a5cece2e4229d4473af7ab23a7f6a33514ebba57453ae38d6e9
+3bd8183507acdb9547a6fc5cc68cc72575bdbf27db2a2ad634657dbb1e1c
+4eefd59b0127998b7b12269a61ab02990a59e7c8ac9ab84d07c9de30bb68
+4b29637429604a9f02d9d8923ee27f4e0680bab37e3eb4220de2e271738a
+05c3333f07d04441a4c77e5cb0fedd062f3d0c93d0267644f56b21b1efda
+d3b65e8cc0d2cc526459cf239119f0da1bfdd81f7a2fc15de8658ceac01f
+a7f87e6028a8f25ce711f2706842981edea8c667f98b2e1a446398ee1aaf
+311aa911ed16df089193bb58614df7bf5963112fc14c00dd188fcd6ffda5
+12dc8fd71c300adc8661af41cffb7f70ba702dfadd1a701c1e74abd07e80
+f9314c3ea606aca7574f4d1dddeb4b3508c78cbb376677db4830435894a6
+01c8b3c79fdb04aa048d7e0e5ae3a5db490459b142668f8481262e3d49ea
+ebaa8637ce0211735cfd5bf298bc2274a35577b95bd69dc5af099f64f3c1
+1d64d6457d9dadf22d52f14a50d7d0d87b2db6b1e19224f72030888e2441
+0f04c89aad7ef45574eef2036e3e9e798d02102f63c6b8bb018a915e5af6
+2ab7bc7db9b4da2809bdbe25e57516e8d188e19868bd2ae02af609eeda35
+8829689f61d8115dcae38bcd8ef8615d562a83cffe5e97e2f017e0b78957
+56986913e1bf885786e5543c46671f6325f04d7a78c53af15910e9c0fd27
+af28dfcd149d285f44c14b6f1633da9ddfe683d7139c9f5baf89a154d46c
+6e4d672452a43cd6a55bd1f27c4a3ff0d14a86193ffad59c5b31ad8807da
+065a8190de638c984b971d580a7cc9561b4ff039a2705f6bea4b53403629
+0246bf9fd12d766dbce0ddb5ad42fd48b82f4841144e5b06e3d889c0c7cb
+bdb2cc2b353c392c7d740446b36a8126503c93150922d97e926ce96a20e3
+e698ea1972e36eda0f9aa7693c53cc2994a16db61e5e4316b0f882afbb43
+b8ae94f7f28eb7eabee5f9f3364ffc1aa9342d1777427796db0bf7d7bad7
+1ee2f4e209dbb15254391987fa678905f233a241e77f26a42a1e2f66186e
+1d048a94be60cfbf61d5c5bb361dd4d1c92833cad203c6dfbfc2453c885b
+bf4683a234fa558bbef71c2fe0f0e8ccd545cc3175a31bc100dd087e7321
+932c2779c3b008afdc61117d6a1661ca320cb34770f4d1b490722ce19fe3
+698da34ce35b1345951ad982aec69a78279dc4522edcbb01f9cc4b8cc52f
+9267b527fe427885d67cb62f2fc7709de4ad29c7e6e1aa6dce99a30ca2fc
+fc6c523c90cce6062e25a581fadb1b892cbf35eb20abc4068a73be3488ae
+a12b50635b70cb66d9ab795c487a9d76c2b01ccf27c4df1007ad3b68e3c1
+367def56f2380db21da81a46d9189fecef680f15d22b30ba3596e4fab3a9
+188f0f11bac53df5b71f454996c9613b3edd464d9c9e9844cd357afb858b
+fc28575ba3e350e88bba2a045be02edc0a24bc3ff21f98e318d84cf23ba7
+2931aa278ee21a479375e0d50193d8f8aadfe254619cfd825a559f9639f1
+98ceb491bad5520f1199332ea0cfaa2bcb8faa7d00f97fdc6ba2e11f15d3
+00a9676a12f0e451f92d2ed547e2df0d5b8bbd40bb5aa2df66ffbe68537e
+823da67c29361d9c89c1fd191d9bab91309eff5e0c5758d9ea0b9b1997cc
+101f7db3788bd9ff8e01e1cf1ba032ec90dd5952858726df33cfb6a00b25
+497cd5144edaf481490f26c802a0a3d2e9e8114f23b3f0ff23fee24d1aad
+bc36492e0edfabec0d4fa57c034c47d2e8acb5e9ff5ec486da2ac3ed51a3
+b36933d502044bcec7caeebd3857d383ddc28f976322aa26315e3fd7779a
+5031ab41ef0efbb295afe066e7c1e8083671e51628ec799a549bde48a502
+f879f1361af8c177b122fe8eac38668d8882a46e7d20587bd561b34486da
+d36c2915c24fc446d2bbc41e256af4ea7edd28914a0191ee4116961f339b
+b85bdd38c1417669b345d46f6b6ea2e3209812ac61d080731d0dc89623c9
+a28566a726a6665a05c70c7bd2e1e757c0a03bf89be801063e40d6b64927
+9cf4fcce655cc6cb2a2d95c846d6048853d654286d5c2c2d8eea94fefb67
+62fc17cd93ee1fbac2dffef877c74bdace7163b654982d864b688139dbf4
+7c7ad4f38cdab42bca53eea14d4262da8328b75cc8a342570c7303c053b4
+c507ec2e3ccd2ca8def551ebccc4f6fb925ba2ac8f7cafbed0b0bfae20a2
+7eeccedaf790eb9052fcb6a254a3ed51374c9255cb4448f99e418770987a
+192802766417dbf6929fed937bb340568e826277e8dc38f4dced644e23b8
+f298b7505b11b37bff8864a718821d517dc7af2d9baa66195e7beb2a6cf3
+0a20cb7a7281c13b1e95396706eb3d588f93d2172dc5d01658cc2a46228f
+2f6457ae884e11815930e90de7ef66ec7e56d539a41b7390b4c13b29cd54
+b43e04ef1076d442abd41bad91f6bd2b5236669e5f0b83375a363db705ac
+d528803e445b2032f410a6aa9bfcc1c704d9b9364dc7ed9fb34c3cbc291c
+1a6948cbe72bd0b860f43bd43ffcab6c190a94559830786a58ebeb4b8867
+73a24cef543b06b9def306e868dfb69f80dd18b077606efaa288f3a5fcc5
+ad3dd1d1a38e22e8abee50a7a6c5cb4407cb9dc339fc04ffdad6e48185bb
+e2e396fe1c39860f942bc50aa4ccdb02e5f961f8441dae54353169cf2086
+74a99eaef76c99c4ac8a6c0c74508c7e47702ec17f90e40247493ac906f2
+88deab608ff6a5e6efa260e04852e7dbc79cadc19ae8bf33bde20f7bdd11
+c600e8369e0da03b877cb4a08f719102d3c3f2f58ab4b0a3afc2a91090bf
+6aa5ea74ac07cf30503cf515a1bed7d594bfecbf6fa5cc4361279f607cbc
+7ace2224ae4fdb898397c500631e6f2bfc537f457f863e9d8ea51534adac
+d7a1ea08f44d8ae882eda411b07f25abed54fc52843fefe2fe03c7bc2cfc
+c95eada5276315bd138397102f056529ec7f3e12add6a290cc96dac9a467
+8788c06355c623059485221c5f0321533cfd004b4fd79c4792086d64588c
+2abdc034771fd02c7c42c5e14c7622cfb21934ce02113ebfe71c9e3614e7
+2f1cdebd4e604e67094e5694129704a229d205f116b43c1c76cbed409e1d
+210ef1a405f70f61c30b24afc073a3a5b822eb217db46188767fe33ad18e
+9b0e59456db4d33adc0f189ba48649e84d6c099bbec78c24f48704c6a934
+ddb1a96e5866f389f03b3635758a9dff6f639bc64561a5ab17aa3f1b4bdf
+b0c0059d33e04946e9a5da4de3fd55107f9da9a971ddb14da8f37572e852
+b554db6a88806f4661b0ae234234e15b99a6c416ab21d368df2d1ca65e9a
+3fb736da74068843220d91631b57d7b00fcf5f246ca92bb8389d951b9baf
+507087226da9b5306277be1f528f03dc61168113ee5647a72cdd686c74d7
+2e13a077c406eb58894c571ec9d58c73a4482c30022ae383dabb4415de7e
+758ad9f69244eabfe52e8be1e1429c1ae59b31fc24a540a31b9114abb675
+8c43096e6fa3e714f7c2a423a671dd42d56a5303228f6823d5ba62e1adec
+028b00c438969c2ed5c1c25b9e8f2b5a69f89c9bfe8bbf50c4fc6bef8c8b
+b7d6f3b4858dc52c5a8a90e5b17dfbabfa38eaf53f5171ac6e29af9a64c1
+3d676edb7fe8555661bf426b71fb80f984a37708965e7198133d64ba3eb4
+65988e71f5910ec10b0e3db681e7ecbac9bd9991e6bed1c3c75a8a0d9806
+76dd592bda679a37cfee4d4df2fa84e01c98500771cdefd3e5d7c8fe5435
+e39056c032e5f4994c8ef1f5799ca70a3b3312679b2daeb33afb89252468
+67f710a7ed78aff3298bdfd5bbf5f430c9c159c56d05c65ef4404f4c5255
+1ebd7ce648ad2a44b6bef6d18ebfeb550296c20bdae04628743d7ffaffcb
+8d473eb871b6fb4ed94c8cbbb03dd69b1f5bb4050ab4f0920e88ac9ead11
+4bc532dab69814f5c002004a959ca630bdb063be03bc0d35732aa580237a
+055ebae9a00ca10db283f6e19399d9fb9bd66c86253bd0d3dc730b5fc898
+bfa550885c4e3cbd6b72f43b9e2a0b1d362d630167d52695f07752052a37
+b6552aa290d1e73023bb66a4ae1506a3c9a0dce0a58cea5623686322a8fe
+6e88f218020125257284f152ccee92313428eb653355437459e15ad374e6
+86aca66e737fdfb7c287bea41420019b69b6a30d0a0c65b6d4b0608aaf9a
+b456e564a8ca2dbeed7ee6ba9c4ab1066ca03c4e8acc36b58dd6d7ccccd3
+cd58e6d0bd984c5b3fede36297d9787a7bf16a899f05b2eecd9896946ca2
+a3d857d8a83257866aed94fb753b65a89b976561cb05540ff9738ce0c2d1
+84224882b315c1ca09860d6f04d116b7e7605eb04496fe7df29c9c4f98fa
+fd33b21b302228670549bd5d89433c05906f48a1d4c31497285ea9a759d2
+7bb39afdcfdc9cfbbf7d2c5de03ce66f5217738826e365ea2e28a53d2635
+a33caeb8ae66297824d8fd7cf7cf7c51d000dc0982f064c8c397b385e83d
+2cf5b41e84f1261b101b77d85c908712dd1adc5f6682c94370b360d245d7
+655e10642367ac53a52c23a1d840a0072e0f960de20391d1363a86f22c82
+559eeb01e95e7ca605528ea81a47d7a9c43a2cb63d8350829ef0c260a2f2
+0f5a75965eeabc20b39b8fe45438406736152d6a118f2aff6abc2e97a7aa
+dbccea9970261680af87fcc02a68b9d95d6b04a7d3e83600d77acce0fb16
+23841695ff1dd207d1fa8d89411690ae22f99e8021e075d1ff1f90f7809e
+b1dd8873e8fda2c8451df3f6c5d12cb930472b04c55ebaf709d727b64cd2
+49bee11f10f509856a1f63351fa4850bbe42c8f06c15605fd3473aab9931
+7b8b2a2552443b0e331d9f0e9d91a9ee1f6f67a0d65d9f2ac166c4f38050
+92b7f7e569855a58a71606aaecc7283757a69cf37cd61894eae10209a69c
+d3d10c3f37287851e0b6fc5784c0618c7e155d2d622b23f00abfd601e436
+1ec59a0575f6f85a7d90f83815fc3482954b8cf71966c47f95305ee3553c
+ac77ce96e7c33f2696c49389ff0abfc865d7edaf368dd7871ba72a097446
+fe8db83789cc43b31a74e997fd7edf298c10d61cc0976e7b41a7a41d83ba
+890a68e6cee7d79493369ef2d8812a1ced1880a8fd4765097539a7cf1ed1
+e1ca04bf92b714b6c71f406733e7452c826c5ac226dc16a18a9de3ddf126
+bc419642f9e1fd36d162ce7832c85b5558863d262855fd6267a154211c96
+73670fcb8bb9354820650f25ac9fb6e636833211e9d41c794c2a6c21d59c
+53f7bf5f264f0ceb82632679bd0a0d598f69fb3e983597014e2986b0d9f6
+88908a43eeac604bcf9a0b3ca60aba155f4a03565ac9f9fcc5611fbf0597
+084431d37d97a9152e517ef0f6ac30c7af14ca490b4c76c3a8c8403611f2
+4a2714bbf952a4ef7767518bf0b69737b65b7b6aea2d68acb1f82c5e966b
+e6ab8bb38ab1823775bb35d60b1ec01e1a956e75ad8ff63e90d7c3a09798
+cb1ac0e1235742753c4f0ffaed9d9912d6b9ba310172a100c2e8daded966
+84ca97ad4b0285760e541bd121493403ac952c9f148a4be07a857fbcfa93
+ec60b19d89d9f437a22fb9eb16595efae7bfe2fbe62d3273bab8ed6c8518
+8864e5e2293818bab1864d85aaed9e32cbfcaa68dac5b52db3bd943c70ac
+a81c1720ac0428fea9aea324213166215542b68948f41273af3e7985087e
+727e13934fb13782e7191cc062832406a8bc38c576b5d96c3ff125fb925d
+71f217d7e60775c0c636601937b7b5d7bb35b6ae08f1745a1f7b42dd3f3d
+c1599a2b89760af234d0ca557df5f3be13d9e7cedd2c3e9827f29f4667e4
+a55e8bac85bacf33716f7354ea6b96776c26bf74f8c6dc18814103cf416c
+82b2226785db86e66edde45da8e5aa738934d084ed3f8bab45c5a46940ed
+d326106ee1aa6c8b240a98f1ec8284bcac022fefbe973885a2c5fe025a44
+8ef2ec64c57ac06998aaf24f702b70ead862f4327467dc5558b521b5a475
+fae859534d2deff36b8ff289c9c055076dbe472f83389d74306aa635a7d3
+738f09005fa73bd903a93fa98f5ada485a644a115bed74a7fc0c90febce2
+2ac7ce0ad8e64143301a671e980ac335a90fa735172d9843f65e4c0f267f
+49697564f842ce349ddaac386b317222a0136521c6ecae276b63beb2c192
+7d04886178ec3ed9783ddf414ee134d8b14e923ffe1e5a4f1e267e7553e3
+b021ee27e536bd4963c69455318e5c1deda0bb4faf814cd4998a6a4a7034
+ef0da8c64f30ef18c6ab164e6223233e6183419f53a81d9221a9643c528d
+a4843c88531a41b02e710927b30c748ed2eec921bf1caeae0d4856f3585a
+232ef7b6df214461bc60013d432cab8b6f17148d0efbf763d695d94ca94c
+426c5ab28c18b869579cac5a728c8dc94ad33710040a95a9ea70e953de9f
+45c0a320ada611ccd65ab7ef6423e70bbdc1ae898c9cb50278b5ac3b3f79
+03f6f5aa9a634b5bd103287cf2b25a4e52e70e7e762f00bf3e68dd39588a
+7e9a38fc072a96812c8c517eead56f3610584686ce912505d5fa81cc1de9
+5c7b9c96c1c73ea76970b2c343ca86530e7d1bec56f0bc4307c6a4aad326
+ad3296971877a629480afa1a9b602a6820f21c6520bc9cdefc01a7c48db7
+9caff6cfcc2b9f0bca69d41125476f2d372e1c8b6b499dab943e1130a764
+6dd17f6ebae2be1fad75784b5006f2d713ae30a4cbabcd50d0da9afa4cf3
+380358e575b769c6228b3874430db68aa0411e11621871d357e25bc39947
+e2573cc68bfc532ccf26068391dc516928f8e732d208e5482ad3c73e255d
+1ae8a93700962a56c0f83abe63089f2c9c6c42162729d74dfe84bf720206
+d42d82d2022df238182cd33dc4bc0013c030a92921c4f943cc8f1342f35a
+c1ddd2a6ff37b92ce6c953a9788ee8c4ca60328c76fc37df3b5cbfb7bee8
+d1a0f5934e353b329ec69b9100c41f52a03e80bf3fae5190af63177bccee
+ab2b445dff1b0cfa372020c89ffe21108166e6cb3383592ba4043c32386e
+17ab84d59a463230a1e3bdb428f3a0624cb02eda2fdbcf6b106b72d9a33f
+0bf20ef7e46544894c0f958d9d21a5beaa95dc9ca8b3afd30398861d41e8
+d1f0523ecff60dc3995adf84a464da4611c6f4567f174f93c689ab72cd38
+c921577a0a137281055c5b8bbddb702dcae5533508124f62c6b6ae947ef8
+88df84400b91f15d2d22af9f36860e8efd8d31cd1d507c2a93481b522e32
+f8063f81f68ece985c35ecb0d87ccda2bfda49a7451bf83f4ffb45db63b6
+715d4e11614e0b5add3f90137968abb33945a53679c4a375c64a27e772f3
+a28691c5064b133519aa12970938c3bc47260d8d3b1e06bf6a393015e369
+6db909ea8a80ef0437592e881060be810af96fc113da386ba760f5df40fa
+219e14a11ba6a5bc7d6c54abf59e71f3e8eb5eb02f088194ac3a02de6b89
+bfd576826b14e22534251f63f89f4ca05ab6c728748adffd02e6b21d2197
+e87e0acf1c081b65539083cee95a47e26dd8f848c24225756d9b2502e5fc
+f4820176f519e1feb87549f96a0038b797806874d67631b341dccf5a8414
+e86578839d7ec32968c57e2b70387b4f1ba21197ac8df1cac6175ef0a6f4
+6865c8acbbeb12abfb83d34f4b525eacc12d2733c29df3cc4a28a7e03092
+2609e0398565ffa55b0118a904a4cb0fed5af585c938a809e1573f63d829
+1bcfaac2bb1dec564a94d390223697323ba9d58ac74d28e37032af6f24f6
+076ce4e919b7b85679e228c7432230a85d3505d6f659be33b4697e4c0b6b
+6ee20a512adc3a1d0276c069e46b8b68e81e4893fcf91c64b84e631e92a5
+2ba97daeccf4c352a778225965f29aca689f74c1575a50c3fe6e90be0e1d
+b16a6e473d679e5ad5f422bfb0a4baf02981b0a140a35021d2a93c450516
+a8211e62f1345423ac48c167e7cd60932499251bb8db8190c0bf8290f09c
+1954fef141cbd5703e9176d347363ea768b701a40dc768d5535e1860612b
+84198effd00aa7bc09f3067a716b24dde04d30b73fc9fb783515c62d0391
+c82cf8b3bf0b79962db0bbb699295f324f69095f1a43083d3f7436a5f496
+50bafb86d2d6adee2c9753dfbec512bdc51ef2549ecf376ec05f6b3aa309
+d9c79be20c359ddce0f1bf4f1277de8564a22024e28822e734770c717f70
+c72bc399faf5d8b6805c3a7c6bade9f16d37d5e7eda4d7576a45a9ada1e9
+996a994022b777be0a1c6d9cb58b0987319dee76e0d3709794c05d15ad4a
+ef240b02cdba3dd5ad38ae5bcb9c0df2342b7277a0e241aa5dc4b7c0b5d6
+c66ae3c81cc758d9071c779f714f328befff3ebe0c7e7e6c4eeb16c27585
+a8b22d6791b34d4e2eb9c80ad925469b03706d9996020e298e930190eb9a
+30f56a62389fb49b00d1f91a6af2fa86d85fab4f9b89dbd076a0364053e7
+1a913c88756e305450c4a820c87323e40a615b7158d89312f8472673ce23
+728aaed24d04baee21591aee77258e573f765c432d1cd4221a7ce52339b7
+ba59a1ac2bacf152fbec0158e7876d4120137695a8beadb58a100763a5ed
+959b9ca89f481d9d9e226f7b609a599b30a6a4694bc166eefff954e187d5
+3987868e4d9f1112388eb12b9e5017e3566801fb27a0101227849d150a64
+fbb6104ec6d1e7c354a1baf425c583fc47dbdb958b8f5eb653b5a045fef9
+9279a4a76d0948121f4d37c0343109311513e8235f717948337d777c080d
+13301777ab8987b3d64d0eaf70fe28e957a1e92a7ffe9382a570237b3d3b
+d37910da2e51bcf04b566cadca226ae0b8c62105738f26bf57ed4f6ef0f4
+fe164145db590286d16b2ca36b3f77a0b4d243478c59cb34494b09209ea1
+4d4fe024f373877af88793eda29357fd908195a1952507b726138e377b57
+26d28447562df58e02663b86cbfdf2740d34a0cfb1c514523ea1b7b20601
+9713ce97943ff86e79ed7f3dbb59a6fd96680264e693f06b03e950e4a2c3
+ed234db50ca2a65594c8905c674a9bef1fdfae8a068850af662cd00429af
+4f41a8a95dbcbba1bd7e2b5421a1fa237cf31bc52f736aeddb1814f5a229
+a1e81a0316c6f70d177243adc4813f8429ad874d9efa0b9279975dc15bc1
+41dd3fa2c5696c6a642fde4eea6e54764da50910e51e74506d5f007d1b19
+46ac61f4b5467ae9449192d3f3736740704d28df25a018a681c24dca1862
+cf1989f1179c80edf7ea97eb48b72513a2f5f9410ad33b1e67af4a9b84b7
+03c64c9148a456405a6bde4bef9e20d33b91b921632515d9b7d07fbfe402
+d16179e91101af1ebe99df71582fbcc1aaeba137cf37777db59369eb36eb
+8b88fd6c0d71b89f34fd1df00dcf0f1d584c12cd998b8d3179f95ae3c1da
+483543bd1977d88310b76690d556546b30c573641d1b6310d3f3c9e8c398
+ca6d1b048c629d143584f6b51177a8cae324705be0751b1d769c4f7a80ff
+e810f076d007e01a4d8d2bb80e06a1dd0bc6a79a2db1ff51276880352b0c
+a2aa2a7399918bd9115091072892149e51d7083a471c0835a5f5957f2247
+4b49ebc6ec7d6ae0ef5cde3634b878544099c58c3125496cdeb98874335b
+f1c756b8f6cc7b0aa49d93c048451a6e48377aeef2ef2edd3ffd1d5efe84
+e23aaa143884d60f06f36b3d5fa950c3737105cd80bf383caf1e1c460ee9
+30e4240123b34b83307acb0a02a382fd279316c90fa69c1fdc171f4c7f30
+f645d4fb8879399030521af4ee5c225e6cefd3f1210550193785e2177ae5
+cd7c130e254df39b4de53a7b4b4bea3e747de45707032333b21e13621cd6
+ab912fc701e722d7fac26e92c9d779b6d6bb4912e3c8497fda5048d4c856
+1ca5e83475457986a8aa25869e8329c5afc2be7850ef12c4555310fbf424
+ec5568ffe92ed1ea2396055181565d4b11f98c72189abe6f204918004691
+db14118193c5e291e07d35c45ceafa1b3c3155c4c2c9a91a7baa9b110a97
+a0946827e252dc68d6a1959288ffb63eb6721fdca03e1e72c0d37ca7dc7f
+3deabe15f4e804cbb7f5650a143bdff5e86de36f9f826c4fc05d5667ea4a
+df5d08a31cd4f0d2fc95f5eccd874a40c0847b02cf4f9c4b047c27e5c702
+0a23e2f4504a3c2fb6c310265eca0fe289ea8c9f62804b0040167589f05e
+f21139b321c662b5ccc314a92dacc92664a65cc9f804a751e4eabe11a9ad
+cc08a3808397b68b6510fe49ed4861755386979c858a43c5105383a948b1
+6ef0eb9d79ab162f1c56e08f14e3614cc683ab383d655f5fcdb616f45fda
+9b3ea1b7a4514af796bcdd859421124582605417da88f96bd9bd0a44f6a1
+0352f31be38861eec03d5ef4349c62678171bcbb25c789cfa650ea76716a
+d99f9ef4a361467d0f4bdd305b1656c8e226bc61993e98fe31dc936c9002
+f69caf89e0aad3a215685a82275357fce725877b527eec56a74e4aa352a0
+7fcec7b66d025ad720c760ec5dcd46cb180c7aec171a3200c2bf697fd3bc
+f78447054dc8c38cd443964b27280554a6b3a878ea93b995ba0acb74a4e9
+6118b25dae2f67abe2ee5e580b0c0b2eeb8a0d730978e97205277823411f
+1c04beca7c2ba588631ab10270708ba72eb0c9d76472e90f5c733997031d
+5288c06c2449edea82b0cf653cf1dc5afd64c10bbded31a2c3a2c7a00bf7
+b688c77888d6e6175d8c20994382eaaec14df3783d4b3bc97f1cc3ee6113
+d50bbbc2fb1b82dafc127c466d5909db3a7c2c5b31a17dd588f15b8b5211
+df314fb334c4f5412fb23808bb1a7bb3f85762a0881765b0d5b8cc8a6ca8
+228f29e7e73b496b73160ee8f91b5dc4a50c0a093d28c01850336c56a12e
+95c0b53b39c875f86a646f149241aa070fed7d6ad42eff3fec7e039c36a3
+7aa3e5bec4c497b1f51d07057bf4e9bd067209850f23a614b05ee5993d5b
+61234f9456fe76748acad8016dc2fe48eb5b4dc7f2f6987304764c48a74a
+50621cabc3d8528dd08aad4d4b55aab3a04efa8e69c3f59ef92e3a81c8be
+23be1436758c1ac357426c3558ebf67ac9677551da53638a95f165320e2c
+31de3d9dad7aafc99ae3d4140bd690ba987da161e8951c67a9a74948c350
+4d1b07d5c7694c4c817414d05793081170d387beed9fcb5a7d09a6c5068a
+ef0f3b74e35560d21593ecfc51b9123da0da1143ca1be60448096a663987
+4f355b2825a4c86135d375e88313478861f1b9aaf83f39e2e18a9da3eef7
+944c984de54adf4224d61ffbb85fdc067ccb6c37f81687a5086704356650
+d487678fa2384f48e9e40359cc6efa0f579f8a181dbb8aa01fffceae9e1a
+9766e602aafafc42459c5cc59709cfd3c7c7b7235b9d9f26a50b21c113db
+401fa1e99468e5bf429ddf946fef6a6f26aa0f75d77262119e30eb5529b9
+5c8ca528af78de86a40ed5dbae0f1c36625a60422be9e6f77d5672565ebc
+80e3997b15ddd5903d85f35cbf76b38884080605faa1c17d3fdcdc5f657b
+c4ab3867e917c98ce6c3500a7659d322c981e3b2e0602b4662d2106e1f26
+0d64a894aa1ed38e681a1d0164307af81fa19c1c8ed262075df3e978a1e2
+5fd5a8955f09eb5c8ec79ce0230966ec2b90198ac6961edf4a0b9d7c5926
+d1b5556256fd15ebde50a4756aa163b70918e697ad9b08793adee1a5bf9d
+2ed8069fb5650bb6a215b15c80a2764ebbd65587e368fa510f3f250b3002
+f9256fa6c21b14443505b203c7e1f0e0b6482de317bd56b44630b1a6c836
+a2e398ec36db92a9a3186d55202a7ee88f981f14368c4447a172619c4f9c
+9e747ad286d01fd223b55103c1e0672c9708042f63ba74bdd0d5799503b6
+429b70c9a4925481f634087dbd5dc869da8d57fc7601552edb51b9918709
+bbec37658392a287f5074a8c01ccfb49cc7d833a4501ccefb4e9a982ed89
+0d1807cb287b9ddb8e7e2f43f2fdfdd1b4174b45ac4b20cafc24e25f871b
+60bc4192b2e6431dd24bfa8a3fada89410d0bb68b865f3e43b897ba4f98f
+2fb3da2c322822bc80a55effa49890f1920cb824a16d67d19a33d8cda986
+c8045cc839e20ef94077d191f62dd4a8af82c2f4e95a64e1af8d882dad32
+03ff0f863528db72ef20a1bdf8d998aa85011b3174c0efa0ca6378d488de
+30960140f9df850b36bd310d1a184cf47b70d76654a39d2c5d50ca56bbc9
+a16675482ab01d1425fffa264cfb849b7bb6a60dd4ddfc4395eda9f7dbac
+1f9bd167fcb3e2a5c75e581482862b6572c5ab185f1304fbc90109216561
+c53a766baeef42811a6b27cfe73425a873c6f23313ce98a155a67af59451
+b85af8af514f1ebb9c8b55fbbf174faac6a1151540e59d11185ae7304683
+8380e384b234a76fed74da8fe2dfb16fe8800561eaa8bef5201a23c3c162
+f115207e1f708c252f0c80ebc0102fa1859d1d14d6376f6ca393e1b75e59
+e96786e443ccfa7cffa5d5a532ea301d1a3b11dca3e9524889bb4731fa73
+e3c7106de30a0b103b22a03ff91031f8b305849a122c181496f86b39efc0
+a3c3f03601fb3bea641e049a6b6a5b94c3d2fc4325be8b60d57076e6c6b3
+c919d0e9ac9a352e62c5a18bc174f4400917567e5ab85da35a4a00b99db2
+d0a04395b532a58983b7e1d9ca6ec1b358e0d52ffb82e0a2b61b381865c9
+13aa54ac09bc7b90dc93068183459b1e9ca74be62718eb1a33c0385b0db5
+11df9cde03003ee8a0af0a5de005d9c8d10a96c054a1d47568cc3a1869be
+48305e5a5eb27d67a4e9931f28981fc482c0519e331babc2b016d44eb1d5
+68918235ed02349884de2eda440fe7b98bc02dead0eaf76f5fa85d2a6c38
+4b6974c8b1ecdede290e81397532da1c514fe30a3449ca33faa20d24a47d
+3dddc44e03070eb944b441495ef2ae383bd2b9b656bb0015d7d80e813e33
+886fbadb1ce08fcbecef193456ec9e2e9ce0fb7b8eb71534d6ec565b0950
+cb0b9d921b4a6980f6390d4faa16cf466a02ae2a55146541a20c5a9996c5
+ff61450887b5da72aace428340d9886becbd7d8b0721269883201ffa28d1
+a1ba32af7798aebc064ccf0a22fc9f2d450b9f0d26fe023099a95791c731
+79baaf846e9f1002a930c50862d5e49f27d469f67d948580877e8583c4cd
+0fd48ed98501e3f6d094aa00145091cf3373b7ad6c5050b90762a98d2184
+3d1df31293e5b8a5f25391213bd3f8ef78f1ed91a52c50089c3440e7855f
+315c3ce3c5d02da21a1710555cbeada8d406e0f644bfc2649c6b059ae09e
+a3ce3fdf553eb6298e6968f06c1f3e78a3dadbf80e7dfeb2bd7b87620083
+95b624e0ccbc0fab6ec0279b951c0791b6056ea7e06dd3a7eac13c9390ab
+d98ea4272c99de1a65345b6400549ed0c8adf4ebbb46f05262e2f5c4fae6
+2a279d5be639785d7f26a8158a77607612cf5cf9b6cb3539cd255d9b9427
+af0665ad63c1e8df8cc93cff8db23ac53d16f61f6dc271488b0088e5274d
+1f3f3ec8f8f28c85238345542ba4d538ff2a4b08af29640c5fa7cc8cd89a
+47a083db93096ea8d4b9923a0c069a20e00020dc296f583710279eb6f404
+162da338313fb4db5055f0b5f6dd4b0ecd6e6ae4be65f4cb8ec6b1f70ade
+49702456a001312fec560bd2bb0687d61add0ef2e278a13452736f77814e
+277b153af6fd4fd99e9adc65269a9ef9cddea98953892444e1f49d3a6a33
+75ed9acbd9a9f11070359e8e8d97527fc874059b5ea3b0a82fd7d9265de7
+153eff41b28e397767e9d0932261f839dda7b359b03d4ddf2821a8398fe7
+221640e035e49e371b5594b61adacfa5dee8389dbda04ee349072ae506c5
+19ef43cd8c1bc90fc87777d9bf6fef2650880e0ecc17c4d48d1c7e31db5f
+450581eeee7af65f665ce472da87bc90d322c0fd878f812ebd66c9eaa033
+d5d9622f8f754936102fd51489aba37b725365bcc3dcf1023000061bab41
+8737901cc01500e0dcb2b3bc196e89d164622daba26d31efc6b62951b1d2
+6e15fd1b1448d7dc675031b90ca135e42570b0a948e34e1ed7e0e306636d
+4760fb5535207502fe96cac6b9b0a52db7f04c4140eaa826b0f6849688c4
+a353ad76d780d0ba8aaaaad6d47a3fd77647c9159af91e9b74cbfd38ee17
+88cf37dd6c9cb721a9763064935ace2a941b65d5b11ca2ec06cd700e40dd
+a97d5373c5d4d3a96bda1703c208cfa235909ec79dfcffea284e743b7f04
+88e7cb68fcc3e6c4f7a49f945d859889442748607acf89e8d2b21e76deff
+12df3c6f84868c110ae964b5cb3dde29c671286588442e61075815345252
+ed1174d840c7c7f89255bf99a466d64c780fd13144ab2074400b404c64e2
+20bf46849bd76801fb0ea28e460e89af2101d8cf911dba146ab8e9063a26
+0d77ad509df4f6756eab156a31022dbd4763b23e177cb5b712f0385f328f
+65d238ab8a0edcf6d6b8eda3b222da5422c026db7102375f78323e84fa86
+6f1e2e51c513721d666c17a489a2e00ac5add0ae6ce4d44fdefd65df435c
+49457ec14191351c05443f349e41b6b6eb4675c06f82bb5584522bf8f316
+85481922ac7a1bd51b86243a97dc5c270f07c72b9c5a807a6aa7c36f3f13
+f44c46491f216cb10f3b5d1bc0e84d2cc95bdda64619d8e9e0f2b9d1b3a5
+e8a9aa18d4eb4187239e1010566b561ef613fa582a4b66149c1b1eeded7d
+bad6c2dcec39315f735ad2c30dfb76a9e42b73912d018d3f19f2c77eb7f9
+3ce2433309d7d802949d9ed4fa7ff6cde73577c91bb2b065ea389c0e2104
+57987f9814679b3da6c4da8510cdd4462e249aa37048320cdd48bacb6fc8
+296f12aa3160297ad9e36c01ac7807b6990ee7d646d8ad8d655763a2d685
+ae56af110099ec774ac86df2bc8c23d404da3e04277a14d291c60400163d
+564272b105c61725bfec1b1ee7f5dcfd7a10b14e0184978e123e3f26590b
+3288771243fc11a4252b0af02db678eb84621648e25bfc32e94206c98b7a
+4adf3af635d5b590c606b472996e7ffd26b7f0554b975142473333a061eb
+f79867341bd06a5b05761c595087f20349eeea6845c87785e79117c3a95d
+471eae9d5347970ecc47331cf6a9043c2883f498787b90e6949c8ef311e3
+c97d58e6dd5deb00c88c47e391283a9a50bd006fe5a10a3ad04120437393
+e80a5cca595bce1b7ae05e0685dc003fac9a8e5d860e2c2325a568f4222a
+f2fb7f51463fc3051aa643b3c306ebd9864e08d34de7a9b49bb69dcf69db
+0ad504078638033b143cf2b730d598790c4af2676694ec0ffaef3d3c580f
+477c3c5dc7478609d043bafc6ed8d06b450bd4eb09141d757962cfae60c5
+ad7222fb12c34dee17a0b8cbb97044b401cd632a1797ff022f7bf5d2d9e9
+1e96722ff3d0b51f78f8a2b834f6304c966107416edc93a91e9d914304c2
+98138fbee34f8bcfde736c7f5703daeea23532fe7fb770e8c22e087fcf80
+ed2ecda99c1547a41b7672591fdd5e26dacb333b524dc0de8ded5ce60389
+76ca254bfd62b1c066059053edf8c3a4fccc29386254de895994dd7069fd
+1a9c2c7fa492043abe9e158110fe80a9330ce05063cd7023aa5605beeaee
+eb033229e3cd2c2c3a67d91449cd67578f50c63f1c5329e4217473aeb977
+3971dc69408b48ddc5980329a197531aabf6a92e68c54e2e19290c1de361
+fbe91a6c386d4a1279c82f128c70baba069733957087ea021a8f9c69f0ae
+79e88276f15a7b2cbe6744d41ca32141091cc9c5e1b857205605d99f411b
+4e3da6a647fe14bc94c068911995d3f15be218174c69ca1834f49176743b
+ceb20a385dd2ec01bf6da68c5659e636eba5545196490079a63c49fac2da
+3c1fffc6d21f2d9f38ef7f560701bb71c1c0909a5577161ac0b9e6ab21f2
+2777b7a721b34d5a6f6f1e8994aa89c8cf9ab96e81fbf780bdfb4cb4b6f8
+9c05624f89b86bd8db430ae67f09e20bed731d124a4bb210c46fd61b24d2
+28772e247c2eba3cb6b8acc0814d59b5d04138f601fce20230ba26a8fe1d
+351bea6a77f49ff461620e3b78b4af7825436b2d28b29b2cad0ef79c0794
+654ce86ff755ecf4dfc235480ad6496686d7c54020caf417f57ed100ec0b
+30716ba13b3f9a7084322ece5e140163a228ae8e86ca4f699d94abddb39a
+4cf3ea50ccb58c0bf82fd81fa36466a813c56e16847048a8612242fbf4d6
+6cf9533dfd8ff7d1cd58cbb40b6a2361049e0e5842457629e3893c3d2270
+f7802c6d36a16327474b2c81fc0ceb4ecce7be67bd8c707999c25573239b
+da35c2cda50bdd2a99141b84c9337360ca82e048bf0a460277a2810e9be9
+f19f121d6c32844948b93a98b4b16893d978861a7e35579dada4dbc12b4a
+8f9256f3d6c26eb9d7e6ecc1de7c8948cbe619d5ec751d1b0b3f17af2f11
+6331406de106362ab12953130048abf09f8f3970cc170b31223a6c7d7fa4
+bb2bcf5a6eee4ce50b9dc1c65188f60d2790a561dc552e60f03c536b439f
+1d6b7c90fd5d406b79c512df6868c175413000d38fe1542c873b52139aa7
+c28102bfd0e48771d46eb5f38c174ef7140b2b82af2bdffd879b281210d5
+bb9ecffc4cb8aa09891208a3ec0f3d150514c806be501488e649234e0c27
+fc13f2198553068987deb79b8da835ced758e4957bcee7c623ccba1a4af9
+6916f467bc15b013d49497de3b80b5e70ff1e459a868089d02ad433a57e2
+fc9e474764efabfe35d0e6929b0b2fab129cd92dd5b1a2db3a5f45b657db
+b6f7f929b2fa42c483f80a4c3fb8da8a017d2151aef8811c66028a8fcab5
+3cec7d285ab284be4d97ca882b93d9beace601f6c80c9efeb043d295e95a
+3335266d3f49c6c0c90deb2c0676d525129ccd6191e3364964fa26a487e9
+136aa70c96f9668fc8e420e9270f94f8fcc812c30fa4007f9abab5572a6a
+9d0269edda9ee4c05339f38c4a513458c60bf8c4f399e0e85150ec4ffbac
+3026f3fad2be387f0bbfcdbc9d289d2caf3499f7470f7557ad5912579352
+4bc777b64033fee4f8ff8689e818f86722b447f5378b37f05d53f77ea10e
+26c00282a5088eea8840dc80294a7e806d5025b8ae5a4d0bcb305452ad99
+4083f1fdfe2cc8a3bcce756688b37fb857f3c195955f31f49c113d1a14f6
+d75cb2aff8169007358b0fa8299515ff1f03bef4c6dd6f3ff70d527f8964
+ceb2ba3644fed417e0ce550a1512759e1d76163dc74c53e7f41fce443961
+892afd6f34fbc58e8347dda64fcc52c9a1ae0a817fd5d1d14658125f579d
+32ce165d8531cc34fe44edcd73d85ba8cad4d71cf5ce80510f8e4323d91d
+96fbfb0daefe8af4d57559a9e303551d38a65500f2e02d4c7f65f4a91aa6
+81241d10de140a703a641e0f6233e98fd9ff71699e62cbbc839de8a31a17
+260e657a84e6829d00b54ab85977c8053be31049111e569ba6fb8e29282f
+a5bfa5ccae62aa7ce0b0ee23fe7f429e566f3aacdb4d13945c9616a2e4c9
+02c64d42bab63f25afbb4623475a0846e314c7a7f47cf531bd3f753cd7d4
+14d51199d34da94286647ab5b616569cf61c68e87568a844eea05f9d22fc
+1c51150857aee8868c88b38ac004f1d86d1b6536041772091b3548b82669
+6af82096753e9d6e0445940eac5a902b304b5de5c0b9de23eb298f3774b1
+775394a26c8963bd7e07204b8175b7f2c5073227a16dca74e4bb24ca63c8
+6fa65e6d5121a7290d58a11e0c7b98ca7eb65fd636b20ef56156be14038a
+42d51c873d52a656b1a57d8bdbde43053dd096dff8ec222bde65776c2c46
+a0d64d927d8ffab4ea1e9ef177a711a81f7fc666d30a681996f194e4d5c5
+33c403a93271068b01996f0e250e01c2ee63fd1d0a9163bf8b670f970a6d
+d416b2aebbc96deb02d27e0a83de3c87781edac6aaa5a0d1fd7877222897
+94d3056bc74f5c899f64988a25dc67c3f14da8871d69fc5d8cf6b0e7bc70
+e398694276c69b77a48019989b93755340e000ccc4fa98cfcaaaf1593055
+13a56f8987758c979b5fbc8794cade876d81e4ecf0495f329a3ec2927e95
+9aec2d26c1ad32a3d111d01d0c932624b904da42123d44421c84bc71307a
+d13d0041308fab8d0ee6f9de746400aa041a7c6a99a72300a9b911fd73f0
+cf2e0d41921232f243eca86727776890bdf9d138752bb927b6485c1b45b9
+416d1078a7034ba2b9fb1c7f9cb55734f87d4e1f081d7c4a66b524b2427a
+baba5e91c1318923699ae3820657e89ac8c75322f04017439c7ec53e1891
+28882e761b0363938b7faa0e6440e1b697db26de4fc2b2f3e1752d000758
+978292da03c7fdddf12b5f11606798a4016b756270c1ea095fca04ef36b1
+a72aa27da04d2dc9f30843137834a4b3397eb87f107631bbab8e724f0014
+2091b558357a0753bdd88598877b4a506078292186a852f36e38e606b12e
+ad12002f0273108c594d86d04279282427edd49fc3325d7cde76e9e50e17
+c3ead48da0b5b3409df1e7b711de6ac9cd1a48b907e0e6fab8df98782fdf
+48dc44433148424304699242cecf9bb4d699114a950d53c7d8166018b08a
+b5246d836a0633045a6c0fdf7340ab739e04ab8928ff7ce64875682bc514
+2618c221ce7b6c38633c5afec9e0ff4ca14743d21be4ef5630ba42389f99
+3ace05eab6b06cd8413a4894a3ac685af3b9e8c134970390af3b8d3ad582
+eb2c948b529d1fe2dc23c8919fdd29a295d5088662b9d50c247a7b0450ef
+0c6b4c8564393dceb5a1b670d2b77876a5927969fae71403c719f4200820
+12741fe56d8bf8ffbb2ff70a7b1b7e95478b8500eb356f25ec9d85578e23
+cc4ad1fd61cc16b18d556c0e6021cc7c6317aad2523d1f14eeef767ba598
+2b683bf24fe0cf493cc39c7117379f41028a7cf9a95a970fe5e447b6f815
+da7f0aa455ea915116e94281bbd7300ae58873444d3019acb2c734e114ee
+fec3b05f84fc994070dfcb82999bf421b51f7430bbcbf0275c157ff4ebdf
+d35103fd111a0281e8d52b73bd42360b532f46f830c3a78d44db18d238f3
+21189d7fbe4be34a67787594d440e012e39a439f48267cb383d7a8bfabf9
+08d6fe86abf91c967c1a2c45943dd7fe6cade43d95bc722c896495ff9f0b
+5e85dfd604187857d6cc0eca1aa46ac549fe0e4d99a93d7ce0f712db3ca7
+8a157c1e3065190401e13dd84b504a20b9b1814024528099dc401b6b568e
+ffa0eaf97cce9bd173ac9be0d1c0a56ee21ea0f94e0ec204461ff5930f6b
+01e2af0fb5fb368db5ae44bb9861515088aeabd158e1f4e8617f5b688c08
+513a96299dc88f74f56714844b19ea7416afe963c3a0919f8942124980f4
+9cd1adac4d1d49f9ffcea28ff611090163b5e07129b900304292df6134ae
+eb52bd7b44d0ddf0c06d55d65886a78d3a1e0fa480ea21119d21989605d9
+749ec25026a04026c91c3882d2ebf341603dd84fb0c138a1271dd6c27cea
+2d329de5d810f761212c71bd92da4c9f15592658c9d81211b90763ea857b
+53ab18b7b18f2026ece8841a248c5cc92dc6b6df59e3fdfd04aea5cad5f3
+60f718609d5ac00683bed6d743942cf10371ccde82ca656ec31b6bc726b2
+156c2d5606304fa59ef82e2bd2f212c6e86a9eadc31830f5de8e76679eac
+a9f21b48ff6f41f54cc057ad2c02b030ca376105dc8324bee6d380f82672
+531eae8e4a2dd9c80a01716ace85092dbec6563e7f055b77265b75d416e1
+559133c4b9119bf69c405732b61bc669ba6b6fbbeac9298cee1fcef26b41
+89499086d2db96c8afb534ebcff7494177252aece0b1b9689b7f28493923
+a6016dcfa0ee015025f8bfc4ea2a29293a7c5b8342f444db215a9e765270
+9a67b19fa0bda6a289a394397d543a444ce477e54341435f4e63f9d158d8
+12b434f9f5ec1e9f8e1d5342a28c9be494b49501c6f9ef349cf2c0d24a62
+44a3652b9079a1289ba7031d4d97de225df6ec42a8dcf13ed3a37571d600
+99d5df67769bee27a1b218198a3665932efeb7fe217b4314d3a4d7991bef
+6aa5ff8b8019a5f30a609f27998045a20708b9660ae827d5acca04e94c00
+49e0ec57aae4c0e65cccbba8528867a186368971657d5796c1cb1c0a3d2c
+53d8e215e00dad145328238997a71baaae73c21afc81c5b719eb10dd8b9e
+e8f3ecb779a39405741bfc078bcc995a4fc26eb9d9698f06a0f83f0c0054
+2c85b7b4827b7220b071c88194d0331a35319b638a66edd7be30e86aa1bf
+f1d29b0ebcafb968c68f6ac51766b70480f15b4be0301ac69fc8459c39bf
+dd40155c141faf8fb1123b6dc23a74f7cb863524b971eaea1574c67c0fd7
+bfbcbed4b99473e07d8d41481129fd55b57791886b626f0b1c5dcd3e0500
+861a272095b1eac096bec7f2dd53b1e4891ddef5410a63ce5bf7485dfe80
+fb961594a833c81ca8a581e65777180e5670307c9b79ca97ff38bcbf0629
+95bdadbe5ddb4d0a90a5de1f3547d8cfa9ec142485aba94d597d1387b937
+395f136e3e934b73649dc4bd587c785048373b4936e737724aaf6c407fc5
+7b8a1be3f723fa4f4a68511df9f7b71c6b7065c13c15fd11ff74697647db
+29dcddb07658274959e8b511a9b35e446541d39cffe121329ab2d94c2709
+e08c1389ff7afad2756350bf2ccb35f34228c4eec4eee5656941e2e867ad
+1d285475939c6950929b33cbfb30c50cd4b32bdf6bb25690f32ecabe1a71
+932ddd6f19a3b629173d1a3a24308396244c8507e472f63955cba693fa6e
+18b1c61e80d5fe79a0266831458a37e4390d44276494dc03cef7de44933f
+1db94bb1958d8c77cb65b756af4b87b1ad13c6439e4f9803bdb264d65fce
+9416890b7d054eb3d44c224d52db95d803d1cf2b557c003c453d48e3ee23
+b20d343ef22981faff7e9d7a43b78b2182aed25b5825b03794948946d30b
+30cac8274380ad33065d14ed4a030ae00533c0e0728590efee415cacce63
+e814a0fd54bf98b25cddd41212617f0d39884c8625cb1905ae42da701b03
+6f60680711ee85e5f47dc056045890156b146969422e20f8a2a66cc4a6f6
+fabd063a168f3bef11d6a369f1418b84143d71d30c6d965f18ab4fc08987
+482f83138cdd6fb4226a4908fc091f229c6265171f0cb523286080779320
+b30d4bd678603ecc9161ad8cb5a501833287ba067c97036080c9c93bcc12
+d69013702302c705dac256d764fe6f1d1d57b0c58e806eb45fa42dac9f67
+a79df2b4e9e3ef2e779d00a77f7923d8660a70253a3f58edbe1d4bd6b9e8
+606e9ee90cca725db85221628749c02dddc1b29b64ee0d7e2c4649d972f5
+047f9b376e498b7ac28ac6d90d1e34483c24f1746361b61276f10d6fc383
+5b47e2fef143bf9500b9b8324639a7ae78b2df882457c4d399e5fe605a96
+c9f6db5de2cb22c7119aec39be3dc6c208ed1fe6fae4e11dd8905570eca9
+7c438acd5eb741fd8b355564e369714965a62e86f91df8106e4445d4d959
+a7b90c2dccdf3df61c9f040cffc7bde8c4df505054242bb01e98b057c64b
+f660334a7a01dfb2f143606c072fd1b46a054c9e6256767c4d8a93f061ad
+cafd450c487bd8e60d6b0255f588c804dfef128b4d8dcc6bdcfc54da55e1
+e3db0dcdd83c1a9473ddf625b04ef8cabfe7ff79d7adec16cfb8365ab874
+f0da37b9c793291bcd7b2b9f3541b18510cb7ade212076226ab000bdebc4
+ee22bcdd9cfe6c14af1ae4b53ba27eba3c85616a80865e7afd5fcb87f5a6
+21678a5583d69a74c51a61e64c4aa8792456cc9d28a4aeeca9fe4764f982
+e526724a70773824f9dcbb913d87ab5c451fd858154f3cec4d683fb1a1f3
+d72274f43db4b0a9fb32e1e3edc5b2ab4d19010fec11e349cc961ef016ab
+bd3681d6b8f3749d2f6e19abba2e2d8bc2a64e926e5a54d1bd86b59a5409
+d58947bb01759777e8924507aeee61bbe36ebabc7bced4269352bde9da07
+c9b0551452f2027af01c13218e9afec7c684f8a86b11d4e303e1e984758d
+7487bfd59653ee8699a97c570ae0914fc2a9457e251a9afba94d4157279c
+2626025bc79b1893543d1a35c866ff5bc3c021241e0d1684cb16b3885af9
+d2f0a20ab75bc56aed522d4e32286aaefcc802402d6cc60b2129ba3e06a7
+5c7226bdd46bedb2b55962b586378f168ba9fa4a09e6a910a35f57fe7080
+e53290537a830708504050d779d6d6a746e8f2f0aedacc3b2eb034175790
+59ceede73b3b0c611f57ca4d102eadeae2b4f9611270969a4543b3473169
+ce8b22d2fe62b241f661e07671d8c2d95d5444b905615ba5b4c2cc794889
+2a2c6a0d77271cb6f28407eabad0202e25d8400f006ee3f241f5be1f48ec
+004775469717653b7a236f876b2edd88d433d4b8ed2f47f73d964a9bab03
+8c3e414000c750ecbe3fbd3902f8d24fd6ca52d447227053e3549ccdc49f
+ea46ec7e3578ec7247f77dfa265a007a1b889d36e505f7bf8fab3b68e76d
+9bc00e54dabd29b1b3d907748ca134f067230a6f8a079c8daa81b2bd21a7
+ab19995a447f6eee35e6d8c503cccf679b6c8fcfac07c3a8eec2ca9d512f
+5af7ac7da28c391fa171153a39ca6e470ca72c813b842efcdab632f3a35d
+278e48786adf30c671a500df993b4c27d78fe6677c27a589ba7b52d01c0f
+89ae3ca69441d0cf32513d62e653908c00fe25a24a0c4dceb1ff98b0a4b7
+a2f5092cad028fc216b71e3bd49914c655811b468869853838c9cb0cae5a
+9569cc9789db7d5291f2093f6f02c2aafebafe8f6b6027ae043f7e9a06e5
+e0c74ae9c1792f8877670ff1ddbdc4d332b86f628158f6f0d976d56a1273
+7b219e5615790169d20aa7caa676a8f17b6925b136bd18ed234c2b96e993
+34c0dc04026b579c5aa40788130aa804340e62df9c85ec996e35c4a9f9f4
+9b81d5c87c224611a2d9d5182ef85d01eb2a7f9a2f9f96d45d538afcefae
+ac72e2361bba5c4ac161ae12f1652d1fd84256af1a2596e4cb227d5be574
+8150f1371daa0e04a7855ff191e6c2e4521f5650806f5445465614af801e
+4face7a7a14989551b6a00495935ed1ff4172abf5e78f5a0c31ea6b77fb9
+30d58d808f47305a6a0c987cd6b2d93b017ecbfa57070151f108554cfbbc
+069b9d51cd372f6dbb0b7ef78e650446b0e716f09abb1ff0cc1f81466429
+74afc5ed85e5e87bc9b022c1a14d72fb593b9eb7e4f099850eb8abbfec11
+8a69ad3e178e8b28bc2b0af9ba3a8ba6c415fb55d1fca117b837e4c2659e
+8639789cc35859e14e320fdbc399db88fba095ad29b0fba78fec3da253e5
+48726d96ac280d98b7f45dfaa31bc53d2fdcbbad1063ad462c44eab2aa7c
+c832ec1f5cad70e2409dfb3a487dddfd3b36504c1c85ad04d1b4103ebb92
+a3f801c8afb7685755b266742e72aafa3f877c47c572bc969a18a7fb804b
+16430a5ead8b2f7fdf9f26ac922884906cc1eb171586dcb792b274b2134c
+04f7599d8717b0ee057a3989a721ebca30aa85d31ab943797023065c5f64
+46a8911d7da276e6ecb4569a9ebe5d6f18b1296716da7b47db14c32e3983
+3d361eccc811521394cc38b47d269b6bb04f0bd8bffb63cd0b255c96c98a
+0a0c460565c9a088900051fbc66234013245c12fa47e5c6559c5c1902a3a
+3c1935ce9a78e40fcd17863dc693ee726fb7884c7b7de5a6761c69424bf9
+2243779ff6a9e566ae5372ad5a4a4d0e8ceda90ea12d22579b015f6c6e9d
+5445fb555b45bf280c03f5049d3db36821711c8a7dd5e7a2c1cde2b37c80
+4f50feddaeaa2b8a029bf47b4e917d593418a2e7213840e79fd2d16100d8
+2b76956922fb93ef5cb7a16afe18ccca6bc89c2b6403b3a1ce8abc2768d8
+9230053cb2c13e39322ca4e4682ce1f3eb9ca5dd6428b9ba1c0c573b9bac
+afdf8aa129cdff321adfd514b2596a7ee73671d8cfdffa6014df71a14bcf
+7c246fcac11954c469a5085bcb5865455e7844f8a4113aea74982d1ec5e0
+6bc88b0656aa6dce6ff19491d0331b9e12d348622f1189743e974c190304
+28d9224321063c40455d1420617ee056572e2072ab254af4339bc975f95e
+66b093fbe3ce5d6bd5c601a7ec41bea52349f90f585fc52e57db9fed41c6
+106e15724c8d25e9a92a976047e14c0283981cd53220560c4c477985e5ff
+09dd5786a3d6b20337ea06e40ddd150aeda6e7416f439bb818e267a970a5
+4fbd46088ea02c1e8b689df81ed517a237230df2369acf7ee9ce06c3e24e
+83a5620ce47047c725fb6f57a126d55781406c670ba0dde4cedbb7b28c3d
+a928b6b828efda00f21bdc87638a6bb59b129f50aa79ffef05cddbe7f36b
+599788d9b81380573783dbdeddd08b57aa600a8cf8a294fdda952d6d1d60
+980feaddb0905117f5502198186e8a57019de97ed3369c29d217fa2cae7d
+94a82acddc8a32bcfebfdb167d552ea840b9e8b2689b03724907be1a8f97
+ba4ed0e0fd9825795fdc5464a45d3677fc7b146f6f5c66d87a0757df35d1
+5ead8cad4ccfe98659b6c5811de82cf5644e00434bcb8bdcdac7cfc517cd
+c42e8b758494b6939becc2d6426602f17607feb9a71836b10a59805ec430
+fb6efc49175010cb9ab1953e906cf66fcde4d252a683cfbac8f41e0d221e
+35fda9067decaa71da1d439380339245090df4e21d81845b233f64ad60dd
+6d4046b1a257db23e682d0665c552fd3ac6e9565a73f8f913d84d86273c5
+7f2514b289bf51528798ef4c390cb227a567c1b016e71f02bf7bf0ae8949
+9de53d074c4ae495582317a59cf5947fc469054648b881753b22f63ab936
+c862ece5abfafc01e0abdb4cf163267911229c36dd1df042acf932f1c587
+3b0591c26f576cadcc6a53ad637eb11c8c2ee6cc84e1204025a928907a59
+1a0e086e354cf1f583054953aaebcf4ef89c4eb2c3f01f409efef375cfd8
+ed932d6ec34ac9ab6b0d95842263259f21df66de5d5ae771885d8574349b
+895974407de469058c94cc5d5ecf949954f0801e5be8dedbacba7e893f9a
+14e211e25eb9a8d426ddd692669f78054417baf8dc282aabd7efb148de94
+15b56346e55a8fc3e5296d739e83769731c48a95318d95eb493d0054b9d5
+887c35cf2e4c380e50e1be6690c5f6e9e7018cda116d0d8a983d43ee2464
+565bf8c1fb5661b75838d1c1823eaecbd2ed2721fcc353516e94f5ca4013
+9b8c69f69abf489fd3e0d7066c5a722cf5ca763073041bae3fe9ffac261f
+75457ba5d0f546eec5741a770058b2e8b76958abe5a27cded4a8d190ad7c
+5c53b51e32c105f4773daf259e6d1b25e95d8cb00180523b5180753a18e7
+faac7c47fe9c4aa719ea216efadaec522d1df90632e54f8cca66963a5db7
+8452df426945798b0f9151a929571525995e15ee2638c74bda75e8140161
+1aa448e93614d4841a0b5be40198a44c058ddf14089881673f63268201c1
+99de50eb482a0e2687f02ed99de1af7b2c40ef8ae43e84f79923bed8dca6
+132d7602bb1ea23b10469628c6c263acbafb2f1b9ae53d0fc9ecdc64f3b9
+d513615e1bae542dd407c668d38bcf1f290c822304aa49251ed252f03650
+ee62280ed4e16902ca2eddb24d71e4b16617f447c6bc907db187a01e9be9
+1a4724816136be46ee38a4cf3c64a85ad44e1f2baeaa3b56ffe3f71d41a4
+24c7d9b3f5d17d6e2cf35951bcc0ffe285af2de6f41eca1654b4cf0f8699
+d059919740222a57333140acf73fdaaf99678221244b5245ee90d14e1727
+1c2e22c0afcf1d1b036d2e69b02fce335bc64ac55417b6f53bedfdde7900
+d8861700c282ec1bc90822fd93925d75f0edc3e5a0d4df89a5bc4b31e292
+0ba4009bf1a263b0f752247825d79f9f7f8d62ffb38b4ef51d08c76d10a3
+13803a82a4bbb76881f41a48d3723c47516048d7a57b0c129462c1e02ac4
+a3230c53557111e7451597cb5c005a2aede03d9d632e0c9f09983d67ec24
+2c70fd67c384f01cd52e27b685d4bb9526440c1ac397172e2e2f57cd13af
+cc0d777e15170d431187d7bfd6bae72ea57cb378f900f83da6b0ed75d322
+22fa8bc634de08716904b8d1a114e9417505228076b7e1d3a33fb06af851
+da3449b9b9d7ae4f9d78839e3c2111a05d1dce9f24314d86db842f0906b3
+94fea407f6454c30dd97c6c0bb81a57a4996f557cec7573e91cff5f46a3c
+1995c1d3fe171607787ee048f64a17eae6af9023e9576fb4ca2ceed45d91
+956510b84e077bc62dda487776a2a26965d16f31d1ea5b0fc15701388916
+802b8453501007d6cee79532bc26c3daa5a2e05d8a17f44fa7fd4c02665e
+d14b939e8b853b303822bc1b3ec52dbb8c88850207eaede917663bb751e0
+57b6904968ca5b8685c584c11b9c98eda0c7cfa531a3409fc0c7664c954b
+2d7b7ceddf9bb4bcdf14a341a810ff4982d9a43adb40314d5659fdc2c790
+511cc08557e35011ef1c00050e9382c570d7161980c0e353fb1785cf9cb6
+a2a4e6b5822065ac84912a3130a1a8627f986a954701f8a47e8a9da12d27
+4ee95e51dcbe6dce622ebff358e63d419ded06afffd7147661567b685b32
+e1c17f293d79175ed1df33d10082e30f51cd8bc85c7e817dbaba0ea60341
+d3e0ab20bec2873fd3d15bbae37b4ba1fd32d00c1323be6aa6cd8526ccb2
+fa6018e0221b8442e1e186f42f49e748666b1a67dd612369c19afecb598f
+1f461d45d4acf5b6fbd01240c46fe35bf9f96019fb2822ae4da1ac3c768f
+4f0e6f671c4808e6c19e15f16672d98e44564e4aee08a08bdbe5ffb51503
+d2fbe78c1b077686387bbcb1ebcc145052de95451c5f77e6581c52b13d17
+8dea432dbdf0c97e9fb089c5e44e26fea6ab9a4ea072d59ceb63338d5274
+1c43f684dcbc44d107bd5030cf4390e02322b1fdedf5911722e59c7e8e93
+4ed3846560f4b0c4032a98003b7ad1c86d7f8e1f2143aae7669a8378b38f
+991943e49afdc73ca53c0fe9024eac2a37a1b76bde80ef26303a5ed29efe
+6d664dc5e51788476cf8d0a838b0c49cc4ba6c879b49ff38422a37854e73
+601f7f19945ff1c46d5e685764f653d795d5c93814fedb0c3e88e6d9a5a4
+234c9284318477bb52b00612953a9a8ebb22bb74ec37b9e34b2671cf85eb
+561bb29fc84ea3d8b84a92cdc6310bcf9e5643f4b4ec558fd6ab4faee1aa
+1556387116c82cfd9f7b5e366aafbd365b1e291352f5a77cd13f4f32038f
+c865be940292a3114d3170201a2e1af005e1d176ec573f33e0343f665679
+6e1f02167acd81378cbc03f18699b535ff635b80bcc4b449380da83060fb
+7f7703d94e19941acfec2ae9dd11abf85da49d99f38da1e76d572991aa89
+0a8b6cb7f9174f1445c5926a466666fa8e2abaae5d7a16df2e91dc03f07e
+2e4b901731d69b7f843aa41fd2a7dc029c43510ef3f7d6b82072bbbc4def
+972b4cc2fee6769910e251672af8febe017ba76db5c21b5769b6cab61314
+5652fa6e577c20e34426c2c902c53984f23a6b56f43020001c390a6fd655
+0267378fe8094baa648b722688ffaadfb08cf330d096983f6e43408533b5
+ea3a520f89443e0b8819b7c11867050189b659115a9a19e8f5bb28f27d6d
+ee19fe63fcbea06f3f1ded2e81fc4f493dbe06e26742ab961dba195ddfe8
+6e49390d7094008ac5214d31c4feaa246abf1a285365ed3e65042ad9284a
+b85486433408b9ad90f2457a3b62b6fd99073f0b3a116be3bb6a568ec27b
+abab5a5a37d1a15f97e9e075e1ffa1a9be38bff64e366b5653d0f2901a38
+dcfa9b7a95a9a661bef4dfee91e68dd6a747c712963415309f9512a75fcc
+b68e2b53b4ffe5aa14c49a4346dae193efe95253463790d3075902142022
+71c469ae3c6bd625f93c62783bbabf4231c1c9551a64fe3d13ca1dc32f78
+f506e42d22af63b0e2fce3f5c9677a63479f4b3dbf93bb83136a5a2731e7
+38e5d3c9b4a218549203af2a1fd06f8c1c03deb6de61d18f2884079464ca
+ac1e8bc7ff15aa770ee581d7b5e33b2e9313077f2fd3bf9f76e6e359123a
+62549e51d55540bb2ee0f496d25d84d8cdd6eb58bc23d09310c72047257e
+f9f8a60481dd7d307f7654568519f6011f2d96e56d1f3ae856bdba5f0a13
+c5e45f58df9f9fb757f12405c78a71dcc5fc5e258285ab105ce64d1964db
+b93811c52edaf26f2b2bcb98be05966f245bffb7847cc2c67ab196e5afbf
+2c8f12e725366a72b8e0bcac99317489123cc1fc4d693dfb84990efc45a8
+89fa7aa93026d43db1f4fa85c35261d08e4dc63a06db06bd509adbe77f43
+d6a83330583667db9789ab88b5373ad587cc48e38d522183f4d8b7663d1c
+5d147a53aa70bcd4f4ee824df2824eb837691ebc7f46e876ca6ee19ee1c3
+38023b3554721f1aa857f1a4bbe4ff2142e1764f273972e184f08ed35658
+e07f6e189debe065264c8e9446e904d82aee35d8e2c0f1061ec6fdd5cc18
+c569df3cd3c053f618ad59b6721e464064c9d4712f2129458fa813f84081
+94724fbc297b2f2e1e1bbcc7b6286bd93bc112b7e2a322b5886e676ff362
+88218e94b483212dc4301a3dd2d55c14853c21227ec300c49f3450f08a2f
+61151d77527044e59369e6160bddf601497466bc37468e307e1bc2fc4687
+25f29df7d9be742e6a4f4f4626a30647a44e5271ae1e781347a7e29bb052
+5bc5ff0bc7ee0ecb33354c1a0e9fdafa255a4e46dc00fd5f6f1725aec2b5
+5a88fe79eb9eb272c4fb7c4f537fe9ccdeba60ecebbd820865dbd15a08c6
+482fa4247ba6c1e21b9c71f05bcd3796e94a3fbd9e2e67c4df10a1df9aab
+c8e14eacec97d44f113f4281f70f6d8b662ab85340c1ee716b78c0522360
+4af01b5f46c7f9a3d0f7e59c19bd8c32d8d35d127f45c2824f57b2f205b8
+e46f947bf69322c02fca611eae1563e3ed4cf524203f45e135699d26e303
+3eb5dc1d3ba6666188e5e129a843f97b84a3d8ccfc84c15777b8d7dbd5e3
+f75f087e068857173f795b644a6a4ff0e127460d150cf0225322ddc0de2f
+2011373e64991546394dd27ed68b8182fd7e9885cc6b0507157a8a7f05ec
+99b7443180fca4a174b7aab110d9eae5606ebfb56ff53582bda01228d95b
+38a4d87bd8aee6df9e95d64bbbac35841a478694531e014327020c126d04
+06c0466d56b63409e77a9dafaed155452171651988f0f6ef1c357d9b0bde
+c9b4a3eb25671498cb6bf5d572030baf3eb637cbeda764f750431c226aa9
+90ab7bf1d1593d0243c1d4da652b6450af330130c3bc49008ec4094a12a1
+d83b5f45114121aef163209e39213326d35f380824b80e8041d2e98b6c7e
+631067a43a05f5eaf6018eda387d8ef342a37b08ba5fc5c861d8bf70480c
+6edf82f9c973ba0a8c1ba3a7639615452b07390069b078832343082096e4
+da3b0885960e8ec671513abc733afb947381242f4c207e134191c7707ffc
+e833cab39b31e4b67097123daa326ab006ddc77d2685f7bb9b1235eaeaf8
+0433bcd7424bcad8c6b26171f74638ac2b07fcdb3f8aafdc5f50b803c01b
+aef58089b007b8aa3022728c057b1a71343dacc41c5eac4fc4438a8254f5
+aa932e415b496ec9cb16ba608fde83419d2a1ddf556fe8d603606ceb24a5
+81288c450a62ecf77755fbfa986fa0b0de13347b2f90a8cdb7e235dc597a
+ea9ee287650b4869ab58c97ea5597beafe42535a8c6a345b97af14b69ce6
+369125518cb6f7a8968291c6a6b16160193d5a218702b7523ad35710efcf
+4c5c8e9a2a30d995dceb13eae7173a23b4aaaef58574a266305ea7ac5aae
+801c2c17045a0e25195db4a85fe78cf842fa7e39a203842d2f7481603059
+43c36d4510f3fd829dd1e481d6dd88a15145a9dde88a2dbf272ba516da28
+e41408d65e9a3e502f610a2321e9714ad06c425e96d13d50eb8d4ff154c1
+7a854efecb9cc72927a542b87c80c485621debb530443e9aeca23fe2ff9f
+eba32a4d8c96bfe797913b086becc4ea17dd74c28b4f7fca43f431bfb688
+f1fcdae565aa6b7d1401392092307bf35fb5bb3837e885f765f1c4ef3148
+776857f1c184626a9ca19892b1c702b72cf9b4a698a88f3baafba2577874
+822f4b647b3ef96da58e45890fc9a0566163f4ca43e1c5e2a862a761da31
+f897c50ee5d0ef12406dab7247513cacc1bebf84020dd0ca2302f3458210
+95042120812080eafb7f2e94c67c881bef05da597e4b5fc797441a290a3b
+5aebcca1b9f237f2b92335c8dc10b08e29aed74229abbaf575ab5aedb944
+11c5d1f83715139e61aa9a56276d48633dcdeb7f5a9fff32c9957168ee9c
+b16a99a46be0d6c027c1fa51b0ccf485b79ff065a3a574ab421153de39e4
+19d66d124378c3831944967bc1719cdf900c147e5feae77d6a0d5f65cd57
+c860da06d87cb87d55b97304fd77a66e2865f470a41d8660541f3187cdac
+e346515478fbe50582b9ceb26e9409bc294a43b41d8d2eea2e33a9dce83d
+1faec4b0af9dab677237b0d442e07ee79c25dcebb8faa958ed898ef991d1
+6634bd80db743c07f0708102141c9c3249e09999483aad5fd7e06abfa59c
+ded8f5ae6af64ec5f6e6c25e101b76580bc4a776dd5e909ce92c5cc23241
+fb72bacf5ec93550b6ba3013554ca9088cced45a8cc60029f3a7ecc53be5
+eafb169059ab4b73500668600dc145c92a63c93c47a00c4a6bb050630d3f
+09bbf0a56fb590ea0f3264010097f2c755a7f47587c46c0e8f48def4ba1c
+0d1792d73abaff05f2efa723ced107231f1ea2dd28c5ebfb2a2c1dc8829f
+557adf120cec34a9eb62e36d03175564999fcbf6d74d2396dcc632998884
+69ec81b3ca10bf1c51e819396959e76d1e7a7b71c546e9169d885af04a80
+1e05222aefc8ccb775cbf6991569a1a5226271271599189a83f21cbab3ed
+bf359eafcc058eade8388d360532c962078867b4a024fc2453e29fea95fc
+859a0cec970180796f5b481f8375d7184418e26fc03ebd4d1bc9a902bcd9
+52a0db1296355a2fe09a65f7fc344a52e20b5191305fff4ccc97325e2fff
+56334af2a34f2474fde3674032387c08fceec52f19c4f73246dd303af997
+1ca8c27b6fde3cd2b6d3267ec82dd369beaa19c08beb2e02113cc7e93e39
+88cbd6657b210d6fe796f0325ecc3105f46d06364385e609475b967e52db
+4e4348e39d519ceac21357600893199a01d7359c8e454c102ec69744b07b
+87fe539f0471a474a66ba6025b12688b4da26561ac6d074a2d3c8559a00e
+9b8e26cd64afbaf673b83a89c87eddf46226ae4173af0964b5dc3d917eb2
+45629537828d8eb0b2a6adc511d268db029b1c42cd36e61ba324894ae433
+6f3febd08bae3234e3751c1f216b22c5234c814cdcd5a5f09f5c7a0ab02e
+6ad3d02ee4025f63f9139ee70ab5f5d2985ce11b38e0143add025ee46f0c
+2a1db3ddcaa1f85c068903458541ce7ea038aa238cc6f40085659dda05c9
+f3e59ef16e4b140777cec06ba3890634f766b44f450b98c3323381e79b4a
+bceef7852bc584cfa32115c193d207940a8f0dd10081068188fb47877bc5
+7209e4818917d5d619b7a71620f9f5694f8159f114b6bb9fb357b9c50637
+97ce14b0dc6a763e80baf1e2478599beef699e9f2b7c03b867a59e615ad4
+3ddd1eabc5ca3cd49cfb895d38ee79a292554cd41d16066b06b0c962e64e
+aeec8c3869537215c567fee6f356cd461024bf044af06007ca6c07271780
+51eae2b5eb297ade5673aeae031a8dc7bfa4238b4948b2bdb8a7ad2c8999
+825b4dbb7e5ef34b3365dcc71c6c44cb7a6cc01b65a8171f0bdc4a4a76b0
+579aba33c438cf7f10b09e546ba21ef3fb29cb387bc8e9c7f6239801bfb5
+7052eed5c7ad75ed51690ee5914d367ccea4269d955c27f1f0f64d1e4f16
+9bdb8621918617433cf82d7080cfe820e4f28dc5cb2f9cb6e789928407dd
+afc4270d7d5e34e4c0cbd3e1822b4986916fac9fb6d5df23bfef93db2d7a
+2e8916c4239a13f19cf63892f045d065bcf5c8403d335ac0fe41d4286f00
+c3d89adc24e17420f797ee45749c72718bea13c243a91eb76c2159dd85bb
+b6a7a9233a03d5dbed7cf7a7d204cb61a40cb657886d18a29470509bc67d
+5afc33894746efbd5c68e491788f1783b9a176ab9b4835803b9b519098d4
+ca52deb18c099bba120185f86254aa8c5e42eb9a6c344924f5bcd62ae45d
+3c490e2de6e57d3bd2407faf5549fb7bdab9252d2e9caa0ff0b7561046b5
+ea7174db13068e596dc52d6b9fef5249839cbd4320f118654a90eb1c9df0
+0e07d9526c5c7a1ed71fb258b47ac6d2638db0757812a271f5e20b6dcecf
+c0b09ce8d92e63719281f666906c8785873935fe88852564ebdf1cc8235c
+c3f5950cb7478cd3c41eee53fe028d963a48eb599426fbb6bbde891e8d4b
+9de69a4fb790a4f97887497bb36432e49f83862d6c75567381d2dd409438
+6c01d0cbb429187bc0bb3e32523dadaddbc00c390875fbf5893a05d0685a
+02a4bcfb0b7b86d5b5231b0418717379417d027f30d3717a2301cadedf99
+c73738abf2e90d1632e60239e75ac1421b5dfd09da8f0f6cfe3c9144974e
+1ef3923d52e2fb968abe3b3de27865f2d929cf844f9cd60de0e17b10de17
+713350a859ceea437629fa3121fcc1860c404beaac5e66a9e915b305fcfa
+6d4f04c30a7cb5f935c6678d3cd3feafa1cb6ea8603d3474d92d670400ba
+0940a09033a3dc382340473c57461561b8477d175699e6582f7b80a527ba
+3f664b3795404b69867e449e6accbe2a76006b3f94ac73127538944340c8
+370747d89df000db870a15e455b8208d3467a726dbc6d723fdeab51af860
+adea1f8d7460c464873800cb36ef56fe58e0ac3c65083ff6150739d15526
+a9c26c47c38890a0736dca6516cf1ea4846d4cc05b4c2a06d0568d8bc40d
+95d3dbb3e05797f697ff00121c8e76377717d4fafaa7c22d42ad04262546
+ea908c3f2dec39d0dd73ae3ff7cf1eb0dff7d1f8911d5e1a1e82b5c743d9
+2138caec847731416d6c47683f9a02295057a3bd338fca0b115daa7c4631
+e4f60c1aaab81a796a579ff1ac9dfa8a63e1c46f20fec5c2c1f682c9985a
+23b1f5c3e8db57e4ddb241f29dcf7dbeb4205f9282d042b9bb11d770bd85
+bc13b4dc753d6353c3d5c4b678d5050b768e060668b7e6f860b38d611575
+8805dac2319d6244baf0f52f76a3054929e3410b477f7652639a516fe7f3
+5499fbe072ffea5f14cbc63226e82b1f9721fbf042887fdddc63d72be1b6
+ce103589a17ff220b0928ba0398b2b3005ecc42837b019cd3db3fe583bf1
+4209f4d6cb18b44a97fa259ab5d5d50a6b51056255f39df783e160bdbd52
+1f62dc07868df941db96e4de54dd85e689eb7fd041097102290386ea422e
+4e3ae3377d05348c8afb7f0f7bcc256916c49537ffc3dd9af81a4ab070d3
+ee23e07881182a9e455cf5fe9c73ee5f64e18887cd987959967bcae04045
+e11809812a7c8e76cee5a4b24d9d22d647eeafc86a0e178d76bdf7c0f29e
+b5eecdaf8734ab4acae5d94471d281bbb350d87a77342abc9f04d335e562
+2c73d348560a95112e778fa0bdcfa887a4100b2c71ea6f42abb43b701b68
+1e2513bdaf1b21ab8baed2288bd2fcf86fa76a235c907002c5b07eba85f1
+60892ab89dd92f184a9090568a3b4878b86c96ecc0d4fe1d6c696b6123ca
+55f5945eeb19420cee8e6b900d1c31d2145b01aa152bbe93ed98231dc9fb
+59bc09f17b678ae6eb13c5830c6dd9858c4fbfd8ecb043269c87829755d4
+30ec0e47e38e374de01977c1c86c97281e1f953681ccd9df78b958a442dd
+eeed85815839dd05f4ae5dc5960d7f1e3bb89240c64a696910de05bc8bd3
+437670bfe89cedfb9f22b6234cbe21f9414d3a4fba3e64d5a480518efb63
+59bc32a53912e08cc1c848ddb9e8fc23e1d287a8882fd833b8849f0021fc
+cea764bcecc059d22b71300318e52e6531810153b5d3f12b8202ecd58fa2
+0da6276164e443eacc3421f57ddfb57d45dbedbf0808293df296881e2621
+9f270a468ea69591d5ee5fae92a913e2905f011bcd0dc7b794cc8b1c8d16
+6ef115e4a0f3678e9e53c936c9825e30e3ed62e689c67f6c31bf282a714f
+41d988a0f35a0a01b8c7d0a3deba0d947d0a7ca5a321e379837b2b0175fc
+6cd46d2dd2b0c6642ddd1496792c4b1dfae6011af1651499027a7cd1e5ab
+4f52ebaac9c600bef926f955c9d8da1a5eaf4698a71fc0fc709530365f02
+5a558747e11a40c121a130a01303f668532386d0c9a576937c198547b4dd
+4f33c252cbfe9d906fc940c56eeaa242c08a5ec3b44f7d8f42b3d94fb53b
+5a4a8c9cb11f6bb46b153f00b6d58ca6a0314cb16e4b65d5b71c739c0d42
+59bd30a21345abb5d78573a8fb0709945e5f536d30689663b31e64309843
+28e76309ec9d0b816dff6696d34a564f694b2e8b0ad62d54fc97d2d09ca9
+457975bd86493f306be8ae6256f58ffd06b1d9066a4b3ad2646e4943fda6
+f13163cabcff581f8b92d5f33edf512bc80abc2c843552d7c7dc2364bdee
+fadfee5f842c1009817f1153bf092b3191eeaba2099136265052ca1992f7
+93a85b1fe1c1acd6d6b5ab7b169c05bc65bba8a8d47d01f5c4b0147a97ca
+156cee70d33abb5e58aa24669b240540fd1de6671ef067a3fcc2da39337f
+fd87e67d34fd042424a4b35a1f893de8976976fa6a28f378665f0c51237f
+5b83294b9e898523be5bd0920f1457c480dc88b97f25105a04aec0d09c6a
+ad915de6b2d5b8f001ef68d322bf421c98205483b22f7b62797e1236debe
+0196be1a423b34da6cc41a1508dde499b5ba7be07bde225a657888033e08
+134bf424c539ea2666b3c13202b5065dde064d644c13a51a6e0983d04273
+23084c00bcab73201f74ccdae02e951de42dd44039891601fab4457b4b00
+5551607910d221380656b1ecdb91f49a963e9f90f4a84668f2da5ee97aec
+5daafed5d1b76ec9f2b663d3ff10b350fba44bc4208388cf3084a26d2a72
+00a0f9e59330b873e582614ed9625f33b15c32e54f0f26c8c4b272612ced
+73b705f081438218b9ebe6a934a443b8667726fdc4ac2a1d3e250c257c6f
+b7f525b577852262be1c11e65c99b065fa49df1658e2246c6579c2c3d440
+86786f5df550f75c97dcd42299d3ff4fe369dafc86c6ffb8b4bb0ed255f0
+899042b4a5a20e34480706fb57c6aa3c66633fc98f1726ee1ed94ebe80c9
+b80b083bebe029669ab2a9aab869f8bbab90f2e6b3e8118091fc8ec6e4a7
+42e03b9697feac3bd484f8e54d535f2bbf369a35b903366fc07d51797d63
+431f966540ce46e0fa1f4fa96fd80d41cfaab0564869925d4c6661883998
+6ec2d39a3f31d27b59b3f89ff50ad87cf6d246e961813d6cda8eacb063a5
+7071d27b6894f0b6261bdd3dba107819e8b0069b95ac6df2825827fe2a6c
+008894d586edda33d4e4bb73a197fc0e04da8d91e5e58a4a8e79be380e4f
+88f66faffbfb92d4187777c3ac11641c0ee6bbc12f9e25d2e02d73c8be72
+13edb765d4df3a6926ea2365c3077b5eec405f8c8522955900656be71840
+6bf141e7880d3272fa6853247fc1bc7850b88cf77167b147c90a2b33dca0
+217ef653dbadbe88d3ccaba4f125d7abce5e1e255cb65510ed58ef42abe3
+96846e6a35afd0296943d1c3be501f4d4969a088cc28b9e34734430fdc9a
+3a2d5d9246e6b74345112a0168e1b4475a22efe028137d3a8531b1f7b290
+544ca21c9369cfc0ccf0f223ad60480dcd7de406d3a435d47d31032a05df
+9925720f5d75a8b0fdb3ddc452181b9365941f774f8cb12f064b3c2a0104
+677b77bd9ed44f3362220e6c14f71fd42860f931703db69b9eb225f56be5
+1dded349993c82c9ac54c58f516cec603395433d7c1f91ac0477c9d291ce
+c2d7408a67846ac08e5fa57f50e7dddffafb856335620e3111ee5f8e7833
+3e070845aab51c52a4aabe1a4fccd28478709b6fb7827aa068ba2081409a
+396dabd3b0b7fef9adebbf21be845c7ea7eaa6a08a444a133cb40e5eca88
+bf5ceff2df181e75499514cb883772e46a6a88fedf8f42a8df053f379e89
+da985d1baf955d9c2180c61fe8d389d2f783c6ec4742b97ecf86dbd8df35
+a1b8b32bc3babd586f130fc78d0a458a9236dd38cfef1b5fd99d36c64c67
+b226214cd24e236d2185a83dc7c17de1fa7b5ef4a829739aa99e2c4df22f
+7a9725c98ff1ef497ad9df4e23a07f6c0e13217ce2bbcea3abee7719d140
+37b7aeff5a8cd2a14f96270c2575010ddff8544fe3fdb7b2919438fa2e82
+c61020ce4f53b6bc089f350e33dcf757ce8ae30fc87e2f521983ee484aae
+9b1780e303c281760cb7011ae14542977434e7d4ebf847e89b9d7fe480a4
+4e560371ecd82280f5ab4730e067ef1dd2458e67e5d5a688cb59376e46db
+ea7f6d01a4f79a1bbd8f74166479ce63d79ea021ae3f978734d32b4af080
+3c193d584b40127a3517ff31a18a13be94b639b600b015975dbf25fa6337
+0777e1d4aaef381da47d2fe453b23dfbec0c427a274651972cd32d6aec68
+8f022334b0cc1b1e20fe5ace2ff5b8428a80323074545bbb66e9a06aa07a
+635fc77f98c1b3a36fdfb6ebb598c122d8170ea4664a5313496c705ad1ff
+7f8cee9e4cd242ac1d6e5feaf05665605fa6f4f66919c7f17bc4cedb736c
+46e8e814b129c358040ea8b2bcd87c537d7a72ea5ccd322f7133360aee10
+8cb788aef19077cbfede0424d7490a9b9c095aa5208b2eb17be00b2932d1
+5be57b0fc0332b9c0718fddee1ec98fd592d9ff45206a8c5fe3893d921e3
+65786061ab3e3f3eecab58eea5daff02758fb7acbd8fbedb5e7ed25a19cd
+2e8030b8b60670f919b0ef0d0f77d426fc228944465a8cc147e5fe684007
+c5961f2350ab38e031b37788add075c99a4d8517394b5f007d93bf7d4f6e
+26d0ca16818e1bd015c951ceea444af836f3e54e5a717d154262e2e94c13
+ac246670c6e6a2ccf5574abb752a70f54c36dc938a1cd193ad898bdbbffb
+0686077a0d76b96ee02aa45ed3e3f1d7d8726515d5dcc296ed1eaa36b436
+b9404df2ee1edfcb0762e3c9c3b3a9713b485f276e6adc283fb31a8f0c8e
+30b12c9fb01bc2848f2b87e76a934ad5583fccb0be2077bf6805e7bfa2b3
+226375c2c1c57e58f83c85cc394068a7798612dc47fc420f10a6131f0bb5
+29c8c7f1ce725a9c2d63108116b3f486066bf441be65580d0f7357b39203
+414ad2e1edc5de3f8bc89e35d40bbf4343dd7f794f71c23bb1f544dc3df7
+1b271ea1a04936481c06dba58e0c14a3b4c765311e6f9a525dda70fcd36a
+500e9592a2d09a724f58b1bdcb9f6bee2202c5c34bd4dab4fda371b263c6
+380baa85887025b1b3f82ee02cb9df0a358f469131cc6a7c7d1090184998
+5cc05234cd313da57093c2b05339ea4a33efcbae7c6fea6e83b675e628aa
+e9ee04d93aa05002dbdfac3ec439134741d3b5832ec59b2ed54cdc010ab3
+f2f775cffa46a7f1ad148b85122ced80c71bda3609d646de4fcfa6eea599
+9a2d7253a2a2935b8190ea39fd8b8b23337b3ba3d2b7b28c974bdcbae3ce
+23742143bf744e6d3bfa0c6b0de3a329ae49972cdc2a5a54cfedd4c37622
+3ae6fb11566d346be71c4d942e47cc0587bb1dfdf5d4dbd2c0db44b1404a
+a3652d2c49cb00779dfcb3b9723a6cd46048b1c5d6fd1c6264d9c1ce8e55
+b7f5314c2ad4764d690d6c6f67c80c87e3ba1831876e4602c2eccdfa3fc1
+f5e38630316cf4b1a78c8c19012a7c42f955736074758a50949f7fe56ff2
+0c75007f00ef89167908246b636a499d1067be560dd538982c0b432dce25
+150d9cf51b3e2b376e428bec1355d42d3418fdd8cdcf153213fba77c0211
+aeaf3bb5bf9d8aecaa2be9fc22bf59ab04b9b8727570033a31c796f81825
+91a972ebf01b0f58b27cda24dc4d3ebe9614b5396f3fab6760b7a47abb28
+c639dc7675e27f8984bb07ad370be631eee6c6bff903f27646a5b12b2c9f
+8fc2446ed6d29afbe34d52a0b5aa0cd25c15e65416031bb91f2cf9a842dc
+b6dc7756423dfd187d624ee3fcb3eca3bd9e64ccd5293a4ed62ab25ef0d3
+f4653d94dd4a12913ecf5819b1992d22810cf648949d26bf4b752e1d8f70
+ab4240cdc4a30790a98fa8a7b80e8ebabe343fdaeba41a10d0554c250182
+d04beacdccdcfb6f779b88926fed7116eebc9f9e0e6910d3b3a480785a21
+17314bf06bd22256baaab66a2ce4bb0a4d585b2d52f8ac37445d78fba186
+0fe594bbda1207c72cf7a37d14a5ea9b9503279771af9c74bd7375e55172
+adf6d8abcc525f1bb199f8255961d075020c0ac6abf4be0ae65e2123faf1
+c9beb33832e08df28b0e25e9dc6dc8b86965998c259c3e1dd05996c030bd
+203680588ddd680de3fc7dcd6bdd329ec679597e4408d248d610778bc286
+8e9aa3ffb1b40b8d3891cd03e726b1ea1d7e6e59157df0bdd85a67b35c5c
+e671ac595d95fb5a9906d73e24e5e04c6ed089747163585c7a89596a37ef
+aaca6a7eefc794fc65800be79f5e0824afb0c43030b3bdb342a9b4f05463
+66d93f2b36998dedb85a8ce186a78bb32fb484cabe8674dafa05dabda180
+fbc38eaa84d4e37b4d17e7717a29233a296e95ef26b04bcde0c0196f96bd
+deae6febc60e9ef06fa12faa16dae0178d04527c596c35ab31125cf17b23
+aeb68f840da1465205e482faa17388f63d18c8f656ba94a1a8e8c74ba8b0
+bbc8ba454d3b42e85bbcbf8d22fb008be86e9dd22c95d13cf0a471c207b2
+25a4226265d68c8aaa1746e4eeea667f5f6aea68fdcc91de8abd883386d2
+a1a8de7b79535db2aff83c13af40e46fae1f9229e9a07b504b3ad1a3cfd9
+24c0b7b0f80c59d9cfcd0019b10bf8000401155bb62145d56118b3de28fa
+5a980a9c5aa1dfdb7c9921d72145fd64fa623cf7f821229e2f5642a66ef5
+21f3d73e111761eee04638ebd933f3b1afcf9a14cdf8e39a956c1bad533c
+c9bdb0c15dfeaae14032839079ab552ad647685826ac145195576c184fcd
+ae44fc524d74d34b5b43bb9885b8e3f0ed130a708760e92650f868682140
+4479a88ab16cc0fa2ed5bb2cd3bcc0b3bbc37644ec846b5fa08d533a4b3a
+730dd4b6e94171526b29b7f89d0501accd6ff70a20451877fd5c0f0ad691
+51be0d127502db63841b29e96cb3cdf00ba2e4d43c494be2d97319a0009d
+a3112ca70713ac18562f8e1f08c787edd1346c0f43c1045d3fb5c67ca494
+8f1a4b3b120d3f8cf0aa18a7e642c5e3bf38e960f207859a922e4df90c39
+a0d213aa61b31e7d389f6c6ed525a1b5088913134fb8670291e624622c1e
+3365e85925f58b68cc55038a1ddfe30b6e1c7f91138911622179bd2294aa
+ee3b46bb141271e11e059abe673e1d7c76577ee1ea7e991c88a191ca1a98
+7a2ced3be8c70bc5f9b263b756721e1e3e2a850c4682a16a7b4610780a2b
+ded9da273cb7443cb59a6d7a0159c254012c4b6231fff238ce4e11eff921
+41366e8c25cfa8c8af0c80a809adb56233ed205de8b00c233a1d666c0820
+4244c0f0d225e38c85344f9247e1ac59d465b74109ba18fd044912315a3a
+b58c807c22a3e2f07ddd4c78c51f4e68f1a85a1ab47d180ae37394316ee5
+13e32f8b3a9416bf9648d5556791e5d4fde3d1f9f1e4a0135c649de3e730
+8933dbbab840f5e7aca82f962619688d9d92fc10f01ab5e461689b163de8
+530869a733eded113c1b4bd50663f34e2f12ed35797cc6457f90456fd5d2
+4f66cbc0d73a5c01a21892518fff09a31c5d0a69283a671fd0ed0aa9bd8f
+5b9000e0de5d46e7510352c45a663b418d5f5ff9ef32088417e05c668628
+6dd141316ebef48bbbb11a7fd97bfeaae428263ec2c852f248935c174969
+b043671376a3e9fef9d477cc78533d6c6eed5249454e5d70ce3b2884ddd4
+0f9e7079ac840a59bad2770a04a74625e3fc5f609e903feba616554da424
+3bb389351b55923a7132b0465fe4bdf29347b091e3dd790e49f9ab22efc4
+174582994879f2d6cb5c0fcb7c075d4ad35ca15c50cd05b5125028fb01b1
+0a946e47907ee7dfee9816a4baacf58c6c267586592927bb42f798215c07
+cbb8705900d00a6cb771e0b50394307f5afc0e696bae7ceb275825cf4bd2
+72cdc83e4c92c1a74ba4e49f36b665f22558e50bf2508d47d00a3db176d0
+74a97ac384bf912f15a11d79a1d834765f4ba678c00acd9ba9f2fed3ba0a
+824a76b91594fc57517667a28ab6ecb370a9c99e79a6c1e26ac0512fa455
+11a188dea762acdb3b4c1d00238545cd8f66845444b9389b3386cd1a4a99
+28c199bc903895b40f7a4770117ba88994d3b0bda82918ac4c657a45626b
+cfb3c22da3855d3774f75051b3d743afefd9d759140c9509d7cab68497a0
+9f2ac7856ffa0befd13e74bcc5e3dd8ed7f0b5f31ad45068284be0898f44
+65dc13bf17e4ad69e2b8e490ec2670e184ab81b1e96663cedf9533257cbe
+cb29ebf27089f6478f17d12ab93e521f8a31c3f631d18dd3506a00019e86
+6112a6239fe5bbdaf15e88c1fec877a8bd8d1d02038f28159a7b18fc04d9
+15053b84a9d1a8568c44ac1b25ace3dbe913410bc340f13200e05892bd23
+efd7888ba0f8a19f71b025cba05f1c52d84e7af93cff7aeee6692c08aec4
+4a3ae446e27048b4dff167a4d1270493a28c84e72f8c915bd95cb67d5e07
+ac855ef06750225071764e1f85a46a62b0778fa0d16edf3bb714c5a0e259
+aec71c6d9bf808356bce7219ace6bc8750658903d58ba77d787c4130e12e
+fedd4eadc9dcf60758ca4f6d1804d36e3e8dcce451522535be0a136231b2
+8b60ca7285d9573cf125991a07e1b9b747b0c27f816dfdd391c44610b58e
+575b415e722e4b2983d05b1952e878a4ac1666c9ed613de46fcf148b14de
+c380b11f8061f3de38b92015878a504cda1238679db31911fe82a0b8d48b
+8c1b7258afdd18261966ae42b93079e9fba683a957188f096a9e219b7fed
+e7bfd55f4ce5ae3c57f5ad7314278a17858eb68766b2383c69de620cf450
+40936e9d2e1317ed4a711ca32da934d1e00d2c54792bd7720d5a5439758e
+2e9307c94255f8e33be837f43768c85c2ff0774dfe18a1f3cb4d8544e4aa
+8fc72aecb801df075f22773dbc8c7aec5635bc4750d0a2392307dad6bbf5
+84d065774dfc0725d4c56fba356eda94ea9538639f01bdf8e5963fc665c0
+159a3117e345acb1eb6a4a3699c54cf096bf369782c8ebf62de423c8235b
+4db3ff59cf130c6f9c856912022441946d703baff74848cf0bbb16edf93d
+0351de8d9a7240d3429ae4f1268be3ae553983c415cfc43226fb5c813f17
+2f440922e73cffbe4201add64f01c37ffc36e9b746b85466566649fc71bb
+2db6f88a1241e9b072980d136bd8baf9be30fcf86e5a66e64daf98f03379
+8d8f0c19db4aa3de7300996b11292c7bb67b88eb3dbd9a9c5c2b9f37e13d
+7c1c8d66e6df212ab2ac7dde58ba5897bf3a6e4a607ef1ac00b062bcad0a
+20da8dd0557726496bb7c55137f373531c620ff7822d0d2cda8ec4aa2b5c
+70a01d39be75a40e7e7dd4868905a358461fd451d650a6c48367dcb60d5f
+884425b4c4eab84749646810c829924dee4a8fdb49e084d013037e2f9fa7
+eefcd4ab8c7315791f6e77c3ac749ace6216ae55576c2b7f6138c7d10940
+c805be36c488efa5442769118afbba36fe78acb2b702eccc44a5de3f20eb
+0a6c3a3ee947e8fee213f034adb2195b84cdfa089063eaef5e489583c42e
+9475cc5dfaed3b90aac4f809cf9fe52a68a52f57c329b7d5b191bb4d7503
+88398011eaf81116cf82102af320c92a8f4523f808d208cefe1cd7c4c1e3
+6af03028dc7bcf6129e82ebe328c62e8b851775bb4dbb99314bc4b0c4b4a
+0668d6e891f4b5cafee3cca709b50efbdc63a6e4f0b645c24129567e4aa9
+76fedf285abec1b21a94e1abe140f54f1605a05c3d432a316fe92f742e99
+0d16396288a812a9951114d8cb688ee94b7c4977e398e24f0da3674610de
+6b834adf3ba0d324a395857f1f6b613251da72e557e0b501566b40a6ba2f
+c33e327de7ee6ec6306370fe89d1068b6e21d3fd16c643e75e8daef9e21d
+4c4d1ad5ebc20b59a4ec8d4871aaf61afbe61249b9a7c98cb11713f757bd
+7cc495e990c8f4c02f167643226fc7bc519b6ad13c108d0fcf6011526211
+287149179cb3a365beabd956988b7427a6c99e3138cfca940bd9a100cc42
+29a4e39394f13170e020f0201d3e12fd8733db20d6429397162fa80cf651
+8df73293fcf713c0718f4cee898e4458d20fcabd7df1d515160dea8ee657
+ba23b9cfa04b77e9735ea8a28630f4b59c6c0c880454d83163276d15a44c
+54954e0db01ab948e5d43dc3d9c35188b5985f90d3836e98391cb158e077
+dfa96ac6327cff10098b0bd0251c3f8d6b52a30df2057ee7e7ef476df08d
+a94f6d7205db461c59a53746295d972453d35259ae58e9c84aba5ce78edc
+9dc3a3bbbf9a8476fed3dc7fb0caeea41e4f9133df0f6fdfca03fc0a0929
+b8c9aae471306e8f5d6a4acffaf9cad054ba131f95480d9c39ac587d772a
+42a5eb6804e1949034bb2797d26dafd17869bfcb6ef7ebc86534cfc47285
+0a387e630adf1f44ef3030414a043d1a470b4243df8f4f2167ad1d41fc46
+4ff6a2dde946a45c40b22dfbd0d695e4a4e23c33df35a63131d52cea49c3
+8b6c2af7ff8661188fad07c1b9b60a8abd8c58654a6c7f1569095744b6b5
+eaadebb9bb84f3ea89691699132d550b035f290d98d0912d733b4953b84c
+8c0ce36a84a319d73ed69ada4710e2a10e0ad59217c7168ed9dbb99e52db
+af904e5ab280122b7d9294970ad8f0c502540b15db3a7c92be004cd2ac7f
+b671a76002cad472e75ee188cfbd6a5296b2b5bafea24be23df32c373699
+f39640cedd846f0d3c179cb02e1cdbee87fc0a64840510d3533f7b73c95c
+6cd25cf46d53dc8f75166e2a8e54bbd82af532c519c3e53dd5c6544e9737
+300121fe0c63d4373cc944fdba943736a104c657c0bfe84c06985241e11c
+beacac70c1378ab30ba5d3a5c93f04b0626f5a0e055efc1ed8720900e6d4
+a4914c7d0630e9ed0e6bf98a72eb9381a3d93e7200742fb65bae28852212
+72beecbe7b24775f44bdc9a3708e84bb691732af1f39f7243d600cf7ee9b
+25c5a2a52b0f1abe0e6a984590c7e430ccfc8524fa7f1e20c92ee10d7763
+d096b5b792d4086c8dd2bafea15ad19ab754c08a2f8119cd0733c33d47ea
+1d84794fc47a2f83439ac4a65eae7525de8745b2971bee811686073e55b1
+8708945e0445d695dedaab56f5aa1fa29b46575f995bf604fc45ae5dc043
+11952cccde3c99e2fa68704fc47308add2fc3f83cb63b2b873c213eb2e0f
+23548de52b3908cd31473213c9eb64550ee1908ab3c2f134014df33c3453
+6c17d812906af49c7550904e59902edb5153d3e86e649e372940e9223d32
+95ccde0807c959565b5426ca1ba959dd3a64b6357a0789de5473ba1175d6
+7a53d9db968d9682febd4c2a01cf28e6bd7e5a1411f488f9bc571de02100
+3d988de831a3d6f1e51faecc90029b527befd59da843e58ba9f4d0ac47d7
+9e91c56cc48c5ad0075911df2c7f74c3826fa7dcab6f66f4923a19e4389d
+c4e8f0a2004824482a4a4cb96fa431d251a51f035258b90d8ce3651914b3
+c9d955b77f36b2ce03f8cbdd0793f1f2eb7116f24035f333f3d1a6097a1a
+eb710546a09c9babee2881eb44a09cd2d19251ca8044b78cf31c6d8ace83
+c55800bf5c3b1041a654be76ae2720b22900315e0ad2e933be9945e47e6c
+a6b7477a94cc9582274e5c894aecd1b544856b68c72c574e506002519545
+32bd9ec00aae146bb1048dfc0a06ffe8a2f2c0a2807a6954b455be078c28
+9b5af21cdf2dee0368b6b88590edf81357c3cc4ee316523c1c0f6edce339
+3a5acadafc56dc6565ef554b8ccbdef6954385165b8647af8c7cf267845d
+d42e2a8df493f56f534500c7d82149ca21c6a2944ec91c1730c63d4329e5
+0fbe42508116deb021753abb64ab752c45e00ad697d99c0ddff09eafaa8d
+b9189f5ae7fd4cfc58f9098d0f67ecc489714a7d7684e85b02c0a5b8d598
+ef32a79137e11a12c8c14cfcc0bda0effa2f2c2398b0cdd5eafc0966b1cc
+6cb0aa51f225fd25c49949fe9f78b189fe698e4fd37f755b1e9ad12d807e
+16cbfd671e37494ddc407630db77f07156023b5b47f0a4799b9649028c56
+0216750a6a7c89c7c3cc0a2fad201113acb18eb0ba31bce9b0631abc96a5
+84f4d4f78c0d7082f743e899b1c012ecec31e499963ebbbdfb97d92c99e5
+63c8e95d8d3702e4ed816989191ecc46d155c285bdbdfc7b283c29b0e5c8
+00345dd40bccc07abdff173e1596170734a3d91d892509e08a948fc127e2
+c5de525778b2fd0fc0841626f81e25c0de7473fa627427ef0e6a20e39124
+8cd9cf3100209bb173d56daf8c452a388f30d8d9615276e47620acc19431
+67404aaeb2fe696c36489e21878187df01b45a888f34045e61114a4946e2
+9c16a2036d7789b8e46c2437754fb1027cbd105a8a5cb1b6efe2b660dcc9
+7b43c72b08c633f968bb54996ee8452b8ad93b2e73a8ed46e1e173e6f7c4
+51bbccdd56e83ca7aee834d0fa12a459d472c15a53a15dd753f93c25731e
+9d653820fb3eea99577aaa86761cb9bcb4b0400aa7f8ff4339c4f0be3880
+5e2f1a4685319aad1a882532b7df962483d6ec9a47b8ae11084513f49816
+caaf4decaa70460031e7ff9fbbc13fba3c12b63aec3285b7467fbc399ce6
+5820a7bd0238f314fd15b1f9b0d28a5ef043e5b27aa4b3e7434fc40a923c
+5b23debee9613a09c48ebb05b8106c9b5fceff7aa93871fb90016bd72ae8
+c59bcd5f5e8e912faf1894906ffcbcc0fe34a67f2b0905c56740858105d4
+8ea5f5e2ede29c596acb85a60c5a6c058504812fa90fb05211cb6de6d95d
+0098c0cbcd8fd37951de11a16750db13323eb4b961a4dbf93bae3232471d
+654a4e3b7a0a9fc87686fc22c89b06f3ed5d7fae5d0615b334a7fe5b95cb
+03c748b2f02dcbdd253c944243115882318e4b74da5c4c5ac663bdce9580
+3f6741cf50432b1c5564107dd05ee0b6b7ad112080fc65c480253d38b2a5
+cb086bc8fa2e362e3593d4f070cb16ee0cfde3c50c39d5689d2cf5cd5657
+804641d8525edc36eb9fab819ff549270f16a74f6ebbd8a97922aeb99982
+dff05d3223222d04fc9a9c385db246f41449532a1be9041a646bcd72f4d3
+a2e6820a83292c7d47484110cc62f14e5c08cd42af83f7bc2d64a0956e0e
+bd7015ba7aa3bcec0fcd5885308af509aed402f1396c7a25e47eb25920cf
+e88f95b7ff66d6d50a9eefc2d66f3d1392cc12cba26378f05a53a4c47d44
+b8006c6aa31931bd8f442c13a0c21e48c5868a1c275a3e84ad5f27a2c9ff
+e16ed8ea7d2b3725e2fc31b07dfbe9bf04a07dc8228619785077d99137b4
+f7cde57aa7490cc258c2b2d1c4c920f33fd155a6fd1bc79c26548be69d8e
+2f50e52f43760fd522fc605ab356a0e1b88bd2a6dad4fd981e59063dc76b
+ea561592660425ce3950a1a8ae22a82304bc1ea0542a943528773a55b4db
+a01a24ab34fb45021d9799bf29656b2d708982c70f68b5942594d9e7d9c4
+b8fc7d16f31fa7da05209f4b32c75b2ef4d1cb485bf83339b4dd4a3b06b5
+61780dabdb959024204d1b10c21af5b53ccf11576a5bed494153051ec6fc
+896be696600dee78061f661fa00d32020cbeeedab18e432dc785fac8b07f
+47d0c5ac0d6553f5628eb560902806d4132bba6e0c22003060ea45d43740
+26d0009e231be79e948299076c3a020d3ccf8a96e6f5b781027d75490b10
+ea64067692cc1742295ff01e173bd3d92fedb3a5256e81341b608919e4fb
+9035390372d560849bf0134db57d43e245f9726a8d3bf16edc36c9945772
+9cc21eb0d636b393890d51c696b6234c04d4a709bdd848174c26de3a1029
+0ae7e3e0e00ad67f2c47c097465d4f9fb72ae2cd781781d876cc4fad8f4d
+d32487481c1258b272b9457621680d67a0dfde705b92de4c9027a2159cf3
+95d1518c1fb970fa566c3eaccbe5bebbc67eea26b01c8c3e763ca3402054
+4eb3efb615e184287d005bf513d83f5059b451184950bc33725cd383921f
+1101263af8f68ae528f0b8fd58b23ff4e33377ff4cd42b7bb862c4f24cf3
+5b78c1a06a5991092be70afbe763d988584ca8e27a45f202ea76c5bbad75
+eba84a8e687701d2ffa6ebdb8b892fe0b7d2f6bb22a9e63d01db96f48afa
+536cdb363d3294c6b912bc8393afe6cd0933c2fb69c3bb9b0247a69c9ce9
+2ccbb86a319cbafe871d86eb1beff057df1740d5d78943b71eedfb5d10be
+a9c9b5f5b256428f8483bdfb74446f01e19704bb63ff46b89ac1ad1ea9e6
+b8167740d92824b70d10e62bf91e5f195d3c5b34c89ebb76dd0c3ae81583
+e62b30fa89bc91505ddde2ba491c88b2cb4fe1ffe969fa639c731cdf8bc4
+f4026c95877683dffa4ca845cf3ec817262482bb4027bb7e5b90c2c56153
+529f62fc54d2b56c951cda1dae3bd3c9b168bc93cb7508c95bc0b9681f91
+661d8d201f655701572e90de07ce20b27f5f91c66216e66a89a39c0d7080
+5dcda7789d3e4bb292e193464737d7254bc70b93a5c9b4c49bfeef3df5fa
+2d333eef22d067df635e6264d151137948e44cbffce8b7a2f85ecf808e3f
+4f8f1eae3cc3df13da3e92911910e92b5ff641155180be4c77f5ec0ccf0a
+d2e7395faba6b848b3883d2d07573fbd446b5f9718ea09d1918bab4487b8
+195b5436c81767635525ba753ca7423a9783ffea585e9932fcbbf6efaaed
+d1f9f1e4a0135c64e8cec283876678cd568f75a116ac9c757528625176a3
+a8bc8b63b7b9e8cd06a9b60d00c5c21f6a1dab66c7802110737b3e1ce8ab
+a5d14061b604c18d7fcf6dca718c594259bd74547250c0d47b30e3297dbb
+05c50f4128b83f58fa96321e6c1fe34d5296e11bfb4cc550cd80a1214d82
+1c04be92b7aeee3ef4e4b70e627635617d5496dc3281fb474718e5497303
+199bdcbc3318423e0c2227795ff34923772c7f53e6cd0811da7d2c231018
+47541e5d6a2439b2313f7ecf5f12d731d0de9db8bd45b08e1ab129eec0d4
+eab8ec632d0e5176ad67ea81c681b9203a4988d22db6b6059f3fd8870889
+664e1f888265ed3b316219dfbe24a7d4254cc2f4981ae42bd78c73326019
+c504eda3a4d3fd181a70dd5085883c11637c78b82b5fc78e27878b53208c
+5593a52114d83c37026041f801d950a69bf9cbc9b75b12813eadd695e65c
+1583254b25d17403fa4d59f518c572f8ac90a386c9b63cb662f50d092cdf
+374e5c14bd92e50ff46e4fef2d8a9e3da367e7d3f3ba17400d5445463992
+74fbc801c11e85e8d10450ac0bea7a468f1ba990b4d959292e40bbc11d25
+30e42e65356719a85c76efcc6ea9a36029411ca1225b11448115c16d510c
+0456ecca598ecdc3eded05152b669d0e7ff3e80372f23e098c6d02eb9e5a
+fb256359405bfc81cc9a927550e4994c9dee0815afffaf2d0a5fd3ece4f9
+057bc6fe048761f74d81057eef2b4fbed38f8cf6df765975d3cc5131093f
+757c390e1e324c159a70472d784e49e6ccb75af3f303f9ca91e2eca0664a
+4b4ddd83256e22753f1fbf2b5b1e73779390c8c582e1113acfdb212c1a9a
+a7537ddb197c3c36c642657a5c7242b6d25976bd15e1ac607db186bc2ffb
+480b1c95b1f71faf1903c864e036ddb42a681f2318dc212b1be3a8fd781d
+ba69daf6390ebe299a5d57d596e24b737c529e48d7d8ae8f29d897eddd5c
+fd970a7502efe9dff7a8def548d07dfcad7cf7171f14464ed185ca1ca7f8
+12647d82f37267f9340b4b8138471099bc9947ffe8836a5fca145d246298
+fa6a16a220c4957dc09e1f7db803a488bd9e23e9b06a948f46327a0174f3
+8564f5aab476c38781bd01240031dcbad5f3ea380bd1da2a57d5833a2804
+f3385741d1062fbec7f2dcb99029f671e73d200cde3c6c22e56be77ad640
+e00e418ba9c5b55f32033e77132d1a3f105050d4ece20e315042ec670355
+52a327e5d2134355b65872fc7043d796e4552c360adeecd58ffce6ebc142
+6d3604163e8736d658b52d0eb31f61e7da24ce6083494e103b0138084258
+1f745984d95cdb80a5b318651f0d969e88b6a192d8fb6833c8edc1721346
+512e30dd5638d4bfa4cc6d6ae59546d32261fb0da92490c81f486af1222f
+b5b8a8beff009a7533be98aee67c751502e811e6d80ace82316e10872ec0
+38f3ba8db28844e6226bf76fb4dd1d533e32dd98afad08686ed7ac5f22d2
+3ac3efc4ca3c8807963329d4c5e5445e483b31feb1b665e81efa14e50016
+cf6ad2c9902bbb09c1169cc0987c8965e17ffda6ef44209c580e87e21435
+9ff2f1658f602c21469e861fa93a6922fb81173edc3087d967c29861b5ac
+4b8bf09a80a39a719bbbef195833a535b795155d31d2c514ef77b63fafea
+0d3e65fd3d036d347f9b131644172d1d05b14b58e0a3d05e1eb3c63cb59c
+9921465766ab68033fd268c305a484cf5ec0fc57ab818734b6facc6c5377
+6a27e1eaabdf22bc862fefae9a5ad864afcb2e1025b92e42b8f7fc360fdc
+84384a5b85e5d3dcb8bb5a8c0a71aef443fabe70f61f25485dce3b5d1309
+5f83463dfed9d1e6f076ea41f6458415d65fa5f1fc7e10e71bc5538050b4
+1fe27d3fc52a0111ff111cbea421a963cb8913b53cc9e2e9f5f6a1202b0b
+1ffebe8afd7c8e3805c631028e15a3bce7227c6e2f554fb6d82db30455d5
+74ec84fdbd4e589ec093e7a9f2687a30a0709da926aa83660e19ac331029
+3b93b6b7614d7c8b941435268bf88d7daa8f413cfaa4bcdade3b06e0a4af
+b63e66cdbfce3fff5da6668c7c4b8c09f36470315f9fbd6c41917b4beffe
+85c2fe8789c26cf07eae1eb5f51213ec4188a4298d6a7eca9dbdb35334ee
+727a393e779392106de99423bfa78eaedaff42e719ef1e430015dc4aed0f
+66db1bc722d1ce5022ed01ec6160b9c6a1e059006a634cf1c81738aa735b
+1b8adf3b53f0381c921d3e1db16797d935a90d7100dad04932134098cfbe
+f607d493b1c2858f4bbfd59fd711861e7fc8d3c39275137209e878b54927
+eb538fbc1b7570d94ec72a417c7c93b97e64ffa489feaa8e448f60bd7198
+eb87700c55af20c26b30b74117948d3a2c8e63f551dfa1597e1151fd036b
+450ed365dceb627a8276ae186b63cdfdc9bfeecfab49e24cfcc88e336f28
+7209ad7c19ed66735525382582d34a1c427fcac42eea2e2bb2bca3b889f2
+f94c17889af17b8527fa8c98db89a62ffbd0e7d74af803672ef0ac1a4f8a
+b730dfaa7e39279dbea0b7eb15943309dacf9ae8d7ea5530bf423e8b09ba
+f591b7fcb0bf32be49fce97cf65278b3a078e693ab4009e8991edd66df5f
+6517d1cb896c23c958260268b7a10343744c83361a7d4c0f58d2a3b147f8
+6aa96105b68a2a68fb84750acd807efc2b43e75aaf3f69110f4007f0dad9
+be64c51774a90e76f59f7ba21c4e213b9e036e8fd95b7149ede827c895a7
+c935d004aeaa657d8e89808b943517aae13b98b7fa25bb2c050b2bf3d2aa
+94d03660870ebc3313df28b019dc87a834aff78dd233d329b6307abde48f
+7b33136591af9fdc1526a3b290c074701a93fd4e2d23e80c25452a46844f
+6751b18e383c69be5182a1ca0b1829d491b2ff2763ff8bd8c219a9b40550
+f83e3c7e657b622df0b55c12fd92c6966db54cc7ce9872d381d9f3337161
+eb3ef659164d2db7b3c0ae5c1b8fbb5c6f325873c3469c42ea7849ddb54a
+b86da499e3870699a349ba1f2a882bbdec2a2defebd80a91e20f580c355f
+99d2c1c17657b2210507a615026b58eb1159468bbac06bacd1840b3e9e4a
+2fedbd3db9b3da6aa5935857c2f35a8a07f89934f03f1ac4179bdf2deaca
+cd37dd60596890d56ac5de35d346f05ccbeb01af776f6c6b78c7ffea773d
+9fb02638a27a1572e88506627bdf29461b4ea9757d3dc4b4881c23afdae1
+b3e6ea7890e5791a05ac9be14bfe5031a5e7759fe0a77a2c433c5f4abd2d
+6dd24c455a61ba4bbdbfb879954c301c87cb83a65571abb4ed0d12b38247
+a122e6ed2529a3e9f303cc50334ff66633913474ef5b3944f431727817c3
+3f99961c8fae4a9fad6f7fcea2ca3dcd7ff630e1dd1a2b1b2e7702d45b90
+022e3b986f8ac02ae7337d881aae3b5ed5ff6589982c0376f7e0184e2677
+6f4910f5764a9e87c0a011c4826884b733a7c94081502fd642f9d01ef2f0
+d13b8c3202b0c65017dc52c6bb896a2d5d6a6eb7186595395c1761fba3ba
+78533adde3cc35cbc61f5e3049235872217f858600c7d9dc5446689e2fdc
+4bc18bae0dc69a6b9538899a72eb972da71bcf204be2a1bd4f3b41ff4e88
+0a474e78b3cd9787255ed129ff5fdb1971bde1a628f3d0031c9c07729465
+3a805069b0737c56f13cad9a7712c5a89c08364ea2a7ec47459f01eb1e79
+b1ebaedf65b74d2f04112943e925c77353b85bf4284d44f9e035f98eb381
+04de862cdb67588bdc7a01ed46e3b4021a365c143eb8f2a289ea8cb86c26
+0e2b68079858cd80d7d01062c777cc5509102ca78f35a14b371228d9f3be
+79c260bb444bf12f229e6d734f455f4777d344c4adf4e3bea74b3fabbef4
+ff6f50810c9ba2cc4ceb642045c50475e0519dca6f80dbaa84bb3d52993b
+7c64eda507d3fa96233782b7460616fc479bcc66f1fa45da506e6841734c
+04197afdf22e4948fbe46321f240aa99c9567b623edef4001964022942a1
+04a3ed4ded4b0752ce877d4132970adadf6a3707e5e999eb9083731ed70a
+4c4d3ca516e1f2a2cc21e7a3335bea3f2998598776ca3cab0c495a595f08
+b14d6d047088271a42de0cd894fa2ef40321e655fa94934d56dea79fb009
+e18011e64f0d712b853c13061d9bf18d2449102dd6b76d026cb41bf188a4
+48d758c8d61111ecc664a1577c90baeef21970e1f796ec34ba758968c061
+f4d3a0f4c6f2967f33e6ad2c296293beeeeb78244c37be4924f888806dd8
+a2623e7afeae2b3f3b7fb25c2ca5f9dba9f6847f21a5d2350e09ea9fcf3a
+7b3471c70f0bba2f4ce96afe288670d8876188aee1c0b9477f645b3d4d9e
+f81fab33af3f6cd10bbe7949a51efcb189f8d7bdfd18cb0ff37f5295f617
+bd21422c088ebe9ae34859728bf8e2260f0556ff6cf266be35330bf2183a
+46b0f2e02be6735260fd8e32994bc9ebb66da8172178c0a5d2a46ebf81d5
+33dc0e8d85f9da009d9cebe0e5123c5943e805ba8ca03feab7eb753933aa
+dd88df02b74e0c3eb9b3c2b4cd0178998350c87afa4f8bf9b1d4c88f1446
+f3bd28b7f7e6a123536504746ecde5360c6eac798c6b8effb282a930806e
+559e5c6147f75b3a9bfb6f80dd672076f99d8ebb064801196dc13c837fe2
+506d523fdbe6871cf3cd286f553c6432bba9a1e6915cc4857a5e499c3157
+e8532ebb1b3f605ae39e52e47e8d2d72aded3475a22d612111212bae39e5
+e53c53294115cb01446379d9c65efc4e9751d2510df8a8f5d05999d321ae
+cdf6a8f0c6bef3adf0a5f07ecc76a07c5a3e3743b2c29656f8622bf507fd
+994d1a2cbf0b6252a1676802e41aac858fc8c05f3b0f9bd7f5659daf2635
+bc654f2d4ec5840476df5bbe92c94f6dfe01b053817bd11e98293c1d82d4
+2618ff76b7d7477cf44a55a05e6267c780288497538773c45e7c005465be
+3706cfeda1a768e34b16529130151c81c21cb79b5ca2613118dc99801056
+fb20ddfb772af8f6c058d291bb60d1bf0e24f1090cfe102dbcfcdf3ebe9c
+2be95830bc74254fb33c5ee961173d7f192c77e9f3cf560a6acfae216537
+8f8ec20794bc2fe89be5fd2cc4cb7bc64b180e316d6c7a8aec02cd3ba489
+ea1bc7290d443f2017db5c9f56d3c01f60aac361dfbb21391d4631e1ce7d
+caaf8b7147424d2e280401552eb8d28ea29a2e3ae8d497899b0a9ab07572
+8943e310b6f119f7f4745fbf157679fcafeca4b489b2c989169572d9eea4
+ea4a268ad55c09e5f935e581fb3c3bdf7a19cbca4e31c2f11c7f94041c17
+20f4afaeb34297d0d443ea15f45047d428e170be83e949a747f2b0eb1114
+adfe5816e4c6dce2e15fa5c04cbfc35eefb2ff31e7e8249a68dc182bea5c
+38d94cc14d4fba937bf7dd6d0d7e97e886dab9cabc1065152f0eea63490d
+8ff3fceded7c66b94b432164faceecd537e8dd7d764f9c723300f677cbf9
+62f512e0c2bd926aedceced203219b44c6a33eb81f68a80874692f0ba475
+e151735c02f37c7f827b7c18a50f403c60b26ba07598a2340079ec79870f
+dcf1d0a10f95b4917ae9ba414fbba00dd561fff7e3669a840d5637a670b9
+c7603f950be19410da99280f836d316578627ed4060e8aad11975142bc93
+1efbb553216411d2a3ee089e0435d256cf6c27134f97426be3fd8a6ae9a0
+b7b6b7d660e4bdbe8baf5ea8d81f4249f03fa53a4ad8c49fa79a5c346f6d
+73384af34d6ba5733650794b840bbc12c2d1e693e6a2de9ff5b317468381
+44bdac7ecb57847f26c1807beea229a7ef033292df577c4fa8df7125c95f
+beb9d3c9a67a95ea90f975a93ccff6684a4076367d6df13f403673c13098
+ef55e1c5957349548ce21775c7428dd33904ffc4aae249cb65c05c2ac6fe
+643fb75a2f4aa279392013513a6a908ed6bc2bb5c56a38a69a5a5a0aa07e
+84ae5895a20adda2ca292145d12ed42648092f9d7e79ee6cec978e1a3548
+5ef3222e3e9dd4f9c24d0fa75189308ad03819b4252840afd44e87e4f457
+fc7b8ef67cad28c1242bebe3760b5a90e3752ed20fa3b447e577d6b2c490
+eb76f5b357c0a6181208a8f99549a2809b7c4ffe37e229e3e01d5e7bd67c
+6f82114fa9436a79bf0d3d6fb88f272792670b0f6b22d14c5f2193d9ed7f
+12f6f1c7f336f597d2f10b5941635350ee6b462353c2f211d01810491556
+dae168530350e99421b509105a6e550bcf9e2843605b95a89c93ab24b9d9
+b7ed3a9965b6fca21ab95c560b02e763202f7c55461419984edb144d0ebb
+ef6436aaa3c68959b0869b58e5bcbc54436c238ac93aaf882e5bc014e03f
+5eaeb671ac3cc090ebcbfb2aac69186cf36746f535736a2c8bd703aabb7a
+b8c9df63d73191b98ee4279473dca298c41a6f67983ef91b2e56ef59b933
+59d405b42f5a30ac8117cf7be52f01022137441efa08549bcadb2efb90ad
+4ccd93a6022a8424a86ed4a48c213326737bd968e627f6f8a8e806676bfc
+d6a6517e623b84204a5d8dfa46eae6abe89870ff3bb19c6452ffa3a5abd0
+e0cd418ffd2ff221827bd313d753a63434ea1bf9822aa9d7f2e839e9a0de
+bbeaadd3a4ea4746dcb2814b98a52fa00db4c1c71bd7687049b5faeaf564
+9507c2303513f1b3a6f4f7de783bccf85aea628b1afd8f473076e95195d1
+e8af64a05d05a661e2b2f77779144905a2c5601df0eef0c8812b8d9a5165
+489396ac9de54d715250a3acceff5659b1f51ad7a7239d9a8bc7631a35df
+244e9cf1a3d080de8fdf09052dafb200b907e8da5bb2404efab14e5d3500
+7710f369d3dce9654d0332bb19a5bc9bcf10c2ae8a12d97831bfd0c06881
+bef8cac8a9bdeb42a264593254ad8d72fa97f189901a857830cf52cf137f
+cb6d46b9b934b98e52a251b029422ddaeee26aaa89a57e3bc0c40e95bcdc
+9d9aa36a34805520a647a1dd5de148d7d50dc9ead70d923c9c78db90f8ba
+02d68c3cec9f5fd771c33140b93b82ec063c8da7d96444beb4fd1f9438c0
+0b1c747d8833dd0a1e12fe2036bf38b4aea8f8708bd3e3e289425abbe7a6
+ce0a9b3a4eb6d6cf021a03a40b32a6fb27f714ab28b1a8d0a7be38e3585c
+fbdf46ac0906b0656599998331baeb24e94effc3d56b37a6f33695c847b4
+5eae4abe907128987e7bc61c9c2cbc35b8edb6c4d00004d36dd05fe001fe
+25a044bb325117ffcd3ae307684029c29ed0ceda734d1b9685da4cda79c5
+53eefb7e26d3e31caa1b815e31d0718b190be691abff96c3c89ad3ab8669
+a6912149e59eeb566ec95113895f17d5ae021e1ee285d0c49e054153944e
+63e019fbbb0863dace341b53cd5b976f7b61ed082f6423dcb631494d2e6d
+4685bcea79f5dcd4db9e4e323c4badc4fab74487d059351b7f301e8c0cea
+9163871789ef9c71d2366f65ee95a84efc738faecfd1f72bff12abfa9f51
+afa6e0b40d6c70005e60aaf92a68ec136c4169f429c705d51aa86c841fa6
+8a4c44e92bceb6605732d355dc995d5a9ee4c078c0bbf80de0351af8ba35
+0d24c5191cd1094a7399cb946132469c3034c6b125c8edd52f8fd240a5a1
+4e945431a1b8505b9436e2e07f19e2be43b6a7eb616dbaf95a7335778a47
+9b2e659e623bc0b6db8f4abb16f269cf3550de6ba58f2be5c3e9cda1387f
+0afb3a1f52330675440c89e329b3253a143c4bf1fe2485b5e402b2c11ece
+38ae8987c19facbd48b9209e3781fb2cc48b0fbb3e5b38c73910d8c945b0
+59c36e26211956e67659bc13ac100ae8bfbc297a8c4c8985fb5fb4227237
+52856e39d5713557e4eb3f14c5e15f822d2204ef14a91c6ab8136c6ccbf9
+04beab720daaac5775a4ad27362986eb78d995b7eb70913519f0b0d29591
+624f159285880ca18b183240410cbd0e9a293f2220c6ffc289668ca820cc
+6e3f8c6e24c437280e067379bebb7dcd7bfee73a804de04866c102488a72
+1dc5c19f64c17b1ba6f543fd024a2bddf2b43d27185b7355ece2fa7b9f36
+7d5d56cf40e8c861039b7026b465d40ac264bdf4d43bb59e451a152f0219
+80df72ac89ca53fff8dd2a7849877bd8ff0ed654254ce9037925d3c0747d
+23dedef33f9510a6730c9537503a4612c76b36698e4bb1297a3ff72caa98
+7bfd0fb801544fa5b04753780faeea75a567ea18098f2ae84f226220df46
+42a70b6f0557772d7ba1f13bef7ce9d9c1f3254f373ba0fcfc44c0063fcf
+f3c2d7b48b1cdded8f78a1ec7c06695ce889670b6921f98d986547fb75ff
+3fafbe090a2d33c41a1f5fecdd2c21e5ef808d7cd4a7195b7715766521c0
+0815f524e75d1b554816fada08b6c246d1b66cdec4bf1909d40d48d5a25b
+0b1615523fbac1eec49f404dd72247b2c07cefb405faaa273973e8714b13
+ae5e763d62d077f15fbb15030d7b4062275335987bc5ed9bce2473baacc9
+fe39ea65d5a7ff0e3767123c69238eaf663975233dd6e9845ccbf2df9399
+285c8dea6175f2215257f0022403092ba7dbccfbd2c2da8778f3833952b5
+9d2019d11b63c7fb0d1344ff0c5b8e8a55636399f3611b062e803e39af3b
+4a6a369569b9d8757fd054cc0d6b62ee29cd6cf2fcbc6a8d57a2f9c6a504
+bab41004df5292dafaec65a2861b432dc41a368136117b746553777f1fa0
+f7b2e3faf253a0bf40d392b4e046cf697abf4d8b3268e4f2648439ade9d2
+e45524f3c0e052076bf35400cbdd16e70f88239dea74cd27633275ccede4
+9c6b7c237fb7bd201b3dfa9b7794555961414d80fd5c32032a3310b6b32d
+46a6e744934f9d680c5ffd81f331991d1c997eb3e4ce241916174da8bfb5
+06b0ff918c6117576a6fcdf4bd9dd90c9b5273331c5bf07e5897e9f02aa3
+296cc05cf47e48b55886b8826f2822140cc84f54b8b9d6477d9893ee74fe
+73e39297bf414e0179bdb25166e8836d49b2add6274aff33c82361197968
+fdfacca49b85772de9a148e017a8ffc62a38a30be5850513071727f3ba34
+dd644ce08bf3fd2a550809730a5c3591d60c3b0e3ed24eaf57817d4c84a4
+66c5f03794e6aeb3e1846ab2e93a5dcc3ef835664ae013464937451180ab
+b91d54cc81967cf85ee6b9d75c14a77f737fa6b414ed667fcaba82ded665
+3b8d6649cfe57b4672c44e0f0bfe5ad630c48ccf549b7cd2deae9c5527d0
+4783ec5319bb9ef7d750d87ba3c6b9b819545ca242d41f76fcd3df2f8842
+fa5714aff9e5139bd2908a003d5c0e6263a2bbe4105c510087db0ecd7c4b
+57cc3af64dbaaac5de21bcab8a58003225efe67be7f9a6709eee25d359fc
+1aebc969130f3050c0ebb6d8b74859ad54865f400863d769e91db9edeb43
+8525a7c7caa68b0d198475a449f5f87b5ebb495ebbd0dce87bbf35408679
+302b4dc66d893f4b4158e1b53054ab9b197c6ecb07792ba9c8c5b9c900af
+c5a05cc9c31b5078427a1c7d74449b9eb8617b3f0098eff3c586744dbd27
+5a117d0aa14a042c51b7506130de59694db9e45d48f39a31411b656512a3
+2d3cd96686806a73ca7f46dcf9a4872c0334c89ffc2948a2bd98bb2f003a
+85834c049877a4729f3cf001b1385814a17baf20a0ef75708ddf0f4b656d
+4122e30d794da048d83b201a252c92c8c92809cc3027150ad65ecc94cb14
+69c5db56965a42b367ca27015b161acb2318686bc3451e03a299f67de0ad
+bde7f33807213565cfaab7a5ad04a442fd3cb710a6d4b78a62c318815ff2
+d9e14b9357e8bbd13faabe9d9ea43c0c39bf4976ff03d1573b1571e3013c
+fed9bfaa0c42017ecf25d7c12d70410e7a0d79e37d5d505d11da9696e2b1
+13019e10355aff4967c56ea86d4362a89b42cc01f3abf0dea5f029ef0c2f
+d3f33bfd58e31a652040ac6179585f9bb03e0bf8f1e94da93240f5637fa6
+21687bb4b7edc3a2f5f89fd1434412333aa9b97bd0c1d362285ab643f426
+f75dd854f116a0d8bbdcdb80ce513cc45650945b546f72ca69dd9d2707eb
+7b5bdd9501febac3c4476852a1d21d6cec9a25e4d1671dcdbbb67b6fb02a
+78daabb55f140eec157eb91075e1f5cfbc2aa8d8d3fe990f47429bc573b6
+52d0da673909f36bf15852a7ffd991d927e99a6c956f33408a8f5edc6d7b
+200ef63dceb2cfb8da9475d34528238f4d5a7aacb905e6a769662a31ddad
+4e75795f11f3332bee039bea7eb9a9295a93e8f05a0978d88173c2f48a7a
+403daaf47c0444ac49e3544a2aa319176d51911b49da0c034f3e9c3384f9
+063d449eadde60491ed22c3bb5c0bac31fc564bb75cf75597c977bd9abf9
+05993bdec686728b1c3bce5d0f6302b3e034e556e43fbe1851b2d137cf73
+8a277fc4ce3f289c1b6aca82f97401eac80ea9a7682cdc9a588ab100c844
+8b60ac0b360f1af03ab5525536c34351dc7d1169193e71fa12892ee79a9e
+41552f5deee05e9b714587288852de794d16c571a4d61c2a41dfb1c5e0c0
+e6e2e9dc4ec7927fb76b52ec0bd581f6982969c8dd2400377428fc757010
+ad039cc3c917421a7e20d261034b9f86c69723e9823a2648d648879e13ba
+aa98bc59e45180ecd907804c0132b14f5a90705869a8c3b06b1a60303836
+4029f3801ef74c8f798f712beb2aeb55a917e4e15907e16070a0f9b52928
+92a05082b8cc5a51aacb34e227fa8b389c08245bda3f03570f04c1a06462
+4c8929938e966bcd981c11f70509bc65be7d3d1825a918a73c9c3479cd93
+24cc604e0b38bdd77beb802d4fe0c6c75dc1494f6816dd520f295c1a23d0
+0c8ec16e45d9d3aa9e5b6c138b7669be34f62b7250fb016034fc3d459fac
+491bb407501f99ff6915f17ba0587f17d19f05e4011a8260c6d9ea10cfe8
+4db4cdac6f5cb8f8a8c19d71a8b51c803fecaa5e78d0900e717e6db0f16d
+b5e3fd766b221033d64c4695127399ca9e5559374bbe717c772746ff02be
+0d9cda0216a202489aa5872d200e9c96a70c6f3709264c4047847a606353
+fc3eab0995cbe4dc9209cd53d2f869e8fb49952d2507c28d978a444848cf
+7d40200e56a1dd0eca3dd2cd861ab8029e8fed1e2ea8a4b457514a0c118c
+6c64b3ffdeafd9fa3fbf92dc132dc4acb1dd082ed5ef10e1c85bd4601a3e
+f2a6b5083ded55f5d9d2c575d0eba89700b4806dbcc6e5d2a2ad26c72cb5
+502eaf92ce02eb0769b552f7b372edc1d14ebc12545545d55e1be0cace86
+0ea950c891f47a066e334fda3afa5fcce5cb58a121c70a646e8fcf3b6b3d
+2bddbd3bb137ab4b1b3056343439432df4aa089b70b47511cfec8ff6bc3e
+97b320f8bee6fb49981dd5b411207ee7f4bcaa5d17e9ae30fb79ca887c04
+20c8024cb1445137e243d42fcbfea96f6259ddd05d335b390ed2580dc82d
+0abaee5e669d537e766e7ec16c512a8b47aae6380d8994c87d00dfed9f5d
+85232a84e3d3cb3ea5b307c16cbb2f962effa16cae18a2b6f8b1ef0420e0
+4b1e8658f368b7d94d949aea27aca6ad429007363ce870cde7573dcab8e9
+813ddb3181634525744118220890a4c17249ce7ae314a9adcde389949f14
+64976b4a819e87b7588aaaf4ee1a501c03a1c7e928c3b4401ebeb2eb5ec5
+b65d06d61c11831a50e59124ee7fda18fc49cafa2ae407af526d1a94a305
+96e5aa91e7991ef4c05cb0ff348e86942c706cfcd879b527c8e5f00ccd36
+20f2e1118317172c0ef4cda072faf995d0d8db0b835cc9df1921fa42bcd2
+613d38b149a9ffc4514e727b453c7c8dedecf45e1e6c15b7f2d5e841b28e
+73e6298ed645aa91337a07021879c9c3c80618372242f0c6d4206e57fcb6
+0e426dacc9ebe8319ccdc3a6ab7d074b85fbfaa94b2135790ae82fb3a489
+3b44f2414e3f9f3da85a8308417f197b92810c2d6c80b2fb8d725a69a5df
+6e197cd82a77dfac7d82ed903a49e81d27e6256a726858a6f47eeffcac83
+aed170e22059c41aae419c1397430677b1e38d4d10ea1d73d59b836dc1a0
+32f5ff3c5fcb37b151ca33de6fedb9b6732470965ec19547e1cf2a717a1d
+858a0c6ff05a74fcc9b512e4f504e9de2bda922a254ed810b0ca0a352c3e
+6db3e08ec0afd82391697f3818bd50a9cc03aa1ad62a9ddbe42f5ab7f4bc
+c14e5ef46a23750f8b09959c0b4afdd79f7bfd8f9ba0dde92ae631ac520c
+676454657047ed18a0723244e9aacf6394c7d1dfe20c52efded832b1aae4
+dd0215271fc46ef5b90de2514fb118396a7a6069bb49b95bb240616d4115
+9be72b5fb37d4f2037c39a4163180379e5e91adc987003b0a1cd676ccb8c
+f6e44f523c3b74d543d55eb3cc465463440720be08ee3f85a60b9398673d
+7e4900c4583979887c6e22d3f27c0db0359a7305b5465274d09f7bcb3b7b
+04893b2c9cb576e8e570b49efc409ce5054548ffb1b19dd3098029958360
+b0d936b7b107ce046648ba437befa9bef67b8cbddecb82cd9c4b1bcdc7fc
+6af26075f3cb2924dfacf5f1c4160d1f96f2d7592b57edb1cad20ef93953
+71d6aac1791e98bf4bc84bfd81b92a5c2b40dbfee3d50ee9269df632a68c
+9f6ef75d69939e764a1b4f527e4993097a1bf28c6e5690ab9e32c73b29d0
+275e10f9559ba7f96bf7c701694ce13133e6fba2276c125b83f43a84cf3e
+8aba4a86b180f66842267e70f5c794303689962ae067290e2cf87e3fdd77
+4ed173f91fa1fbb0f6eba3ef1a34e826604961d2cb47b40b260d79b9b2fd
+1de584ea79329dc8ec75e84dbcd90b888c59e8f7e5e90f4e2cf7ad8cc5d6
+ac6a42bb0aba27236ee4d68e994a1fa5e5ec15a55c15b0306297a637d669
+6e1933d8c0e9c4e81a4625f427aa47b7e8553b580a45c1685e60267e563e
+9a3785a9c16e32dfa66a55ffccc8ebce3956c1e9778b64258e09695fae08
+6b493e3d2fcc4cf6904e2ab22b4ba631c50527a56801737bfcd881bf0499
+1b7677662f0bc6709b981e6dd9dfa90cd3672ea00e00bf2649163c3d20c6
+baeaf3fa2cf56cdc5ecc24628936bdc5a30910cee7afb97edd4f1a38fab7
+fa3a5cad31bbb821ea103b67f99d0b74d7c157a351144b9d755b36e250fd
+a96d686bf4d69d7b6fd6bf5808f715fc393de15b86a6e4b1e878ad83115e
+90eda05354fc1cbc1734a024607c081fc229ad35770030d77dd164c8e255
+3e9745ed40d9bce5427536793af013665a394cf966f2535713ed2c4a3ff8
+16f50c2bc9c9dcbfe53223d06a009268da596bf894ce9580ef23f4eee7db
+887770709f7ea8909ef744ba0ea85267e62573dba51c25f77528870ad317
+f1ed63b2802fc54d81d149a2121762dcca760e5ea5e7ac32a1d48191d63c
+bf1e049b78dfa7bb2b2237a9d52f714859f5ea6c92d44c17b64efd507e2c
+9820575ca9ba46026fbcc25efbca849abc4a9c385520e5d7d64a787dfd23
+229bfaca0785aa219f310d6f0210e4aafd5f75033ed560f123964476972b
+db2a8087df61d0ff47fef572009a81809c7021d62dba53f6b6a26b976d53
+94eff109b3af588cf8deb44bb00763526423d8077836d5e3bce10378ce95
+cf14d8732ccab691ddd13f9a00d285f2d63fa8e7b16136b1a8edfb44a462
+254de6d3a5ec710b9184c2bf8b23eb1aadc2d40bcb53822dd29f4e5cb045
+3e863c11aa73e1bbfc28e336bdb59ce3e88065ea9d8b79991461bc3a0d5c
+97febab06079f7a1defb82bca12f28329c063ab726ab7c6a2dacdac6e1da
+46e58285015695a4b206d9e0a4df7093033a9e42dd097c6ac0ad87fdf42b
+8d453936731448ddd3870a490cd48fce942bae6a88cc0f8525788e222239
+a38476946060a8feb6959613b28a01090293a9f5895f7b509985e3643ee4
+7752ebad364d54437ef2ce6c3fe86a4d2be12812577b126df132cc7d602d
+c5ec6ceed3041af208b69b7e98ccad48b2e6d99ab607bbb33a19ea0ad941
+6b31e145d3939e04e9b4afbcc2504c82d879dee54455c0f5d01c028d4648
+bd3d3b9cd2036537764102007df035a9ed9660123faeda255a7385adab5f
+13e3fdc490503d9b631c537f1c4447a4fd4fe3f1cbb242705431a9858a0c
+60fa8a836c307497698053cd8c62f21aad03ab06aca920bcad87f68afc45
+39f39d9d6759b7c04e15ede59bbcc04f528a277a927152ec89409192f2e5
+26f79921a4e76fece2373f3375c3c0a36ae1d6f3bd1b70586ab9461f65df
+c1c5654b5b5aec5f92d6387a11bb28b81d2366fe463a5ea0f8198a1fd8df
+e0889a281e1016d72188023de9c0244764e480b801f83381360bff7a3509
+5609a6e61174b0274c2b7293509f9c4e4eec290e2c538c02adb877c8b21f
+62c070f58cea8bb436d3b34706de6a6fe8dae931caafba634aca1948da44
+c2cef4d8be6b194d3c41d0c584c82f6f48c67ddeac49b17a692ec941895a
+c203310de514f325c7e70d6e1048ffd7f31682da946fcbaa2f5a50535f0a
+ff3dc0eedf67fdf9898e759b929b447593edc1fb8c5b77062e19bfbf2fb6
+c4b8b7d695e24cf6470608ab635002afc38d755592a0c723730a042ac5dc
+4b74436dbf5eb8dac79ea9e6b7f21ed831f33b6b8c3141c98134e2a69af8
+fc7572bc08aa0ebe9deb04ee9aa794d2afb9bc0e97c60f93a7a72d15556d
+36ca0b58c60fc42b6adca84658447da164fb558ae1c856f4c3aa6fd30c26
+7ee9a8668426a3d742e6b8e130c523e1d8340ccd3d3f741be49ce3935b24
+aa20443b6049d0b136a36c1f13176048d69d4150af8cefd458fa78a2859a
+8a2f7c58bdbb92191a7dfc1a3cedc12ff91b26b6828d38784a5f829973e9
+d103739a1d8cb4366edc151e396c415fa51c740e0d81c18eca84798f80b3
+5344f2c5c7dbda319d6d50821f236d1d678930cfa18259a97496df61ae7e
+ab1c06abe785cd887259a7f08e79915ff96cd781d91435f5b5e4da140c2c
+6c0136dca6c57c7df01f9e87fbb0edf55f80dce3a544b7992800d8966f07
+e1297af93114a9efa7eb21baf2583055770eff67b5d21f64c5c2a11b4147
+9e314762bd6409dc5a73a8b32664b55691a01bde6f95d5f1c1065c81b129
+45e5b63d7e845b3ac1f16f760345f886eaf7b091c4c56cf0d0c2a9360f7c
+4e546630b93a2aaad80b4ca35d46350095286ef840123cec13dc12e0648b
+69d17a43aefe796a02dfe7de3eb520b5e247af46f31ee8507deb1774ab72
+81a32bd0fd6e6439fee6e94a49a8567e68d3156cb34212ea86b6e97f2866
+4dadacf5173e64c7d39237d0744b315fab7b6b85a6a2955a8f45ebffbd87
+9bda5f7cb3285c7241500278ed4574e464adb3d3f07f5a63560873aba6e7
+f9f3f5afc580d06fe0254bcea4da8af4dfad93b9225d636b0cad7a4466d3
+0e6c378b5d2e15e54a0d2686f971b8a3a04bd412ea4d59784bf73b7b8215
+7e398056a48fd391677420dd5c85c3aed14709871fa319b5677889022e1b
+3b9e27172dee5df9aa604c98307c576e292bbd17836bef068be34136538e
+a77ad4a000894fd8251e9950fcc41b70c2be9368150056bcd41badb91d89
+4da2f98d599bf224120fc5a57028c8dd55148c788a24f8feb19da237fca4
+93a9a0e313e37bae205a00829c9f7d0b790369f6cf5b1c54f4efe3917851
+e9f67a29dd264d2ba0b1bdb05de9c6894b30cf8d5b2d37a960b24b14ac52
+e93421da5d3f2e4484d870f333ce9544a9f578edee46de93125bd65e0584
+3d475c64b2fc036c699eecd9a1b54b5ca8c37c02365dfe7afe918204f6e4
+09d24ef92e8af22d1325f84bd31716add00d5323d34da177b1dd377b77a5
+0a08d86f13000039ba4e1501edab6ddb0073ba7843e22f49f93c80bb7d7e
+09a12c0e9c2af050fa39a83ecf87e60672257a62af6f3686aa17b0f246fc
+f1a109cc2f7a2a74ecd62849c741d45d92beb3864b6377f648585a7292f2
+98cc3c44b5755dd907e1c3a12f6c152926d30455c3c74e1501eda8e5c295
+7c64c587108f18db3ecc698a96f4c839edc7495f50b3244c59ed2a313509
+e26132ec29067092c12578715104dff4cc0e30ec1da6c13961b9f8b68a88
+65fcab289d5cba904d8891aa7fec7bd57cb4183cef55ad7cbda701d2cf0a
+3878c52a77e1e22cfcb4bf8ff5e3e0833f4dde59f2e8a6dc5eb9b625f05a
+6575445cf98267e442061d2ad99b52cc789d1d8f6988433c5c0d1d4b4f51
+0f8c73f6bba8e929362ebf38d26c9be8aecaec33f268e2725d3f51cd327c
+48d2abc52e265be63a2a2fc87454ae42003eb5a28d6ca5da2d7e8abbb9e8
+439b683e8e631f2e6da1f4b85c04d8bbb1730f2caa091f1b1eef31e08fa4
+df9a9b9eb8c6421cd5bcc0f6ded67fd19617213a80d18024ab79f408f7cf
+e3684483819c85a061c53b4fe853e382a3a7778fa471a196f24e124b1436
+29926a24620037e5f73ee2930195e2ecf4ecd53461b5b73c686578d48124
+c8878e0ae2cd2cb654cf98ea3d238dcb37ae7bc18bd0d21b323c959fe82a
+99842575f35bb6f286f5b3578413938ef1cdedf1469878f28d0f9ed53100
+c991598f7aeada761e896998a42b10fd186dd494e9ca575e984138469d98
+d4fab45dbd1ee3c2f61b877b9da3660aacd8774dba08bc31ae8e73cfbd3c
+fff34ac4047df0776d0db02306024adf7c9efe019128f2488d22883a4eff
+f3b5af9fc7552f70a78955d4854a32b3281ddda5dcf15f915b90bd584c40
+e7bfe27697ff9c6a9870d329a63a45d35b7d5c87060ca3960accae323beb
+e22f909f71d9ce8f4e59f87698954cc5468b9fa31eec9a1723665de649d4
+9d1f4d8e6b96c4bf83e02806d4d9bde12c1a598f801e2169afaef48cb6b8
+d5040f2be6901dc81c691776b45321a8959939a90b6099446e8cd50576fe
+da3c0809294c8cb309ea895075d2eef2a0f2b019e3f2e5941b5863004868
+d81b733cfffdff18b54df5ecb4d3230d0d82f091283ec5aa46c060541366
+3f46eced8a3e98334b9c2ab430f435f792176874df89f2f1675c5d350fa2
+1724a0d2f19a6b24f86f858d0af6934d8fb84016cfff258ba15935a2612d
+4fa06dc5579534c7193324b282a8f5a67a8c77eee35ecf2fc7005a3d8d5d
+6ed4a4e19d385848a8b95aa6454573815d0182f4c93a3face72d7c2c33ce
+e19499d1232adfb742e6212a6c93666bc1dac3a4275c1228ab98b9779850
+ea291edda7bbf14b5e2c68aa26f1b877920aff9ca30788348798b4423b39
+4fad935b35e3d5e71277ec32b142a386a96fece14fb96d3b31fb36b36440
+a71c2d83c5da38c9fedf38148f7cd58748bb2612be4b4895b02e8eb09a5b
+0e7548cde6c939ce8880eb89b19b3e26f354cb21ad2a31f8db6b49683fc7
+fd7850a81f4b801bb9f108688435a2b8ff617607c570defce9c4586abd5d
+a7cd2a81c93c9e53c3ecc79d637be3d0d9f8b0b08214af29b7c525c6415b
+89e0759c5c6389bf00d01e884d9ff86b1bd35ba5d679e80f93d259e88588
+c5ef5e81d89a29b4814ef4a54cb37750182f50662db8fbc27a03ffb3d0bc
+eba5cca63c454b12960451ce170828efeb66bc5397c2f0603472cf10a18f
+321a4a55eec51dd5a63a4de376ac65f858cbe20ad56395c7b1123cdaa942
+c558cf95faf70c57cbcc724aa11cb7f141e0db8cfb173d518f0da1bee461
+42a05de5108677f5b14dacb79782b2010bf7c5806dbdd67811cc136c0c0a
+f869d8dd9df0ece29b581c55c60339948e044da340cc704dd18f8884a6d3
+c851e6113d77742d6dc05365ddc5806b9beba531037aaeae23aff0b19737
+443e8105d57c2c246b09222b25926d5368e62728acb1b98ff51eb1fe6a13
+8e660361caf8f3074de12b7137db4819bca2b39409636c8ff8368c07cc46
+5451818e7e726f02c9dc803e1e53fa04de26cc59b24b5d86cd16a1ab7ea7
+303af8cbb2ad7ce30256052cd4c3b086446db5bd8677a6c8fdc13bfc7824
+23e9694c7a60501ade93a3c867a594c04cc0fb1626fde284b566ea1e4f6f
+7b79f4f22fe9c586d25d8b40c0a4147b7a2be24a83afa65f2adff816d656
+19052d81c9cc87be737233aa0916b9cc41736ea4630f4d10c0867aae059f
+22ecbc3868edd11f4cc97dc44581c52ef5a5879da40e356281bc0e1e72c0
+5e0f039a679f0c13955e6f577fb6e78c94810ebc9c75d9519a7868d474b3
+2d8a2c62d7e82630059325a9cd33d2ca35d0369bd45cd6f17d83c2c30172
+1bd3c9c34c68b0e709dfe50b428a4f051786ab64f707dd4e4d8a075e0657
+22d5b68e5e9095c5184cd7c01246cfc418f75914f0a01b088ffffadf85c8
+499cb1408f7396b0d94b0b5dfe84e9a619c55e87240a81af16ee893984fe
+331f15f597cd3c9415533f9b53563e478d8c6a159e428a806d33f4616ffd
+8103ad221a19845547097bd9f1b234c1fedcdcfa0d8ffec356130515c5c5
+11fe5c5ba8d25ff61e6368741cc466592cd920696e964cfc0bde1c5e0b1f
+bada15b871d8ee1ad94bc4a42cba6af0526a061d1535d8f3fb4cfcf249ad
+f9672e73a4af5ae352b191015de331dbff2a889839c40ea4d315813604f4
+4f6f51144d0014fb69fbc5d4d64d9486b7285d7533a746503920212f1ee2
+8b61b9b44f79e15dcc51fbfedcb91b9eab18bf942525df15e67644bd4d05
+29fe44333175ed909c06d6ec35280ff1354bdcfb509295ff3123e2a53108
+79760e6e7af5b0d6fd44c14f82ca4ca89fc41771745e1290ac86909dcd89
+4a360b9c549939522c7e54ab92d1cf0b5bdc4cf8e9c8b9fd49b5f246b6bb
+51fbb881eb6a1184b2383acfa9c8907dd73c8be9a200e555f674c73de70d
+9c171eb3a2133fc8058c1a44adf8b143acb43b394d142eed9fbea7b0cc3b
+e960e0384ef1dcf4094a22e0b3b4b73b88ec0e5183b2996fd906b9bf3d12
+a818c817b16afb99bf7c0de191eef8aeed90fa137fd2ab84dc9d27e49793
+5ec1be47d5b2555e98d1580687ff82cbf0b9b76fe073620ce33a2450095c
+e859a89e68a94d96fd9c8ae07bb9d0608a67c17dc15ca273c013c816150e
+ed83d03f502e7dbf208b7748117ad59b24187c60e4a44fac5c9d53ca11a2
+f5426d2e50372727c576042647485f3f06a779c11a398eb91440c74d8566
+54871042a976cd54f8f3e771ac35226a8bddb87884a1d73a888019e11845
+495d6f354e24af23a9cdafeeba7d517cafd89c7a3796eefc2076467e5b2e
+f4a244d269fad741b24b4ddea4d52374ae5655457fa30f4b8b1b22110a68
+bb9011f55edff5478382cfc3ff17c3e52a376be295d3547920127c96247c
+9c2d069ea9f10a41d206e45b228901d8ec47f261544c4bd1974692ec5195
+839a638de49102290fd09f831a1b5b6398ee8c2337b18ba47e29d3a228cc
+3cf1447df2de3160b2f2ea11ebd3430d44d176c13a5a876c6bf13765fb2f
+4aa9e7e0ad311a3a832e7d4ec3d04a154c04c50bdd7e08c329c0c682c566
+69fd704da7b4c4a56a50f50f60adc6a30f31542706f8092fdf406035167b
+dafef98111e39d3d8be13f057e44562c1b033115c8c4adcaba90b7f7265b
+7267952c5164e68a4434b7684178a1ae46e7bf10e344ab99799461abae9e
+3d4e424de0bd99a66cd3b0facf3c6948c00860f64dc81f71aee12245787a
+82e040f0fd0b5dd075475574f7a60d157cef30d0400ccdb5da27604a975c
+2db600d55acbd7c16e329d5c7c8d073d46723e29ef8248918331076ec458
+a85f98cbb0fc0a78630e99db7ab0f178c629bb726c511825cb722514ca36
+7dcdd067a731c8ed72324e5cf715a12602f6a49f921f0632175f615e1d93
+bb225684b50f39b26d65a0110e9ea45fab51763fb785e505942b4b0e0d8d
+e21356d58c5d87ef69457dd47944b34e4b29293cd535f7c25a762bf24233
+2f12955daa0b04af9b0f1ae4bbcb2d4abf16374038566d419e71d8b9d91a
+af8b2838c3f69d7802d91001837eea69be47f595f864ee03fe2270e05556
+680c719a0f33e24953f7bbe30d03c31f88125a888a9fc47406578c79dd69
+9a9e73aec17997374ec94e9f0147007806407df213edf9fae457f396e403
+9291c23e0a54e6d07c28652374a367404c3a8c50a74eaa4ceeaea98a05ec
+220003a80f3565ad05100a397c89dede629ba9af67cdf1608b08ba01f653
+44bd44b5d8a655e1fbd2521b0fac160bfb4628296c6f712d98efefd28cbe
+2631dc4d53bd915483586c9619c7a665ea243877b4d34c550d473a36f9c1
+ddaba89a7c727a2625f76cc3d8734efe913f04bf6a9aba435ab32ce26f21
+2499cb4c4e97da602b4b51c35b237f933ef51e091beacb8e0ac275b14339
+e13299374378ffb3a0f25691dd7f2beea5edb9bd152adc86d01fa3e9acee
+f2eec45bd016e255dc58df2a9c5cd64a07b4bc410b37a137210dcf214c30
+27d1876726567d9c50926ff4550391079a02c7b4087c1108c509d88f56df
+ce7ac59788ea14a42fc69419882a869c6254618843790f987143a6ba0060
+829739cbe213e30194f21d012dced304470847ed0c2b8f597f0fd570eb04
+41c3a15384309dd83f2eefd3d27609dd090c0557391a04bbf9110afdd00d
+d584bebbcb4250174d7503d8610beca0ae95aaba34a30abb7ecef68e1076
+6adac81a2814051b4f484478c66b39348436687670185f1717f84da062d4
+8fe0772c986713eec9fb5af2df8dda8dbd76aacb89821761f76f70bc34c9
+37766f16f00e5898ea1531e8b4b4ff65ea0189a8eab73a03089e205e791a
+65534ac99113f975ea5223b4388841e3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
diff --git a/fonts/Courier-Oblique b/fonts/Courier-Oblique
new file mode 100644
index 000000000..2c02e5cac
--- /dev/null
+++ b/fonts/Courier-Oblique
@@ -0,0 +1,1448 @@
+%!PS-AdobeFont-1.0: Courier-Oblique 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file COPYING (GNU General Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Courier Oblique) readonly def
+/FamilyName (Courier) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle -12.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /Courier-Oblique def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-61 -237 774 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+/UniqueID 5020947 def
+currentdict end
+currentfile eexec
+e98d09d760a3c22cf119f9dc699a22c35b5b35ed6aa23593c76d54cabb5e
+942bf7d6dd84f1664b89699c74b472de9f8e6df925f6c4f204e9f1c639b4
+dba988ed2ac419ff2b2bde605b8ee3264edd66412d4f21c64ac522bdfc7c
+5502f9c3f3e5592b3b2093d33c9bfaedd2d49e89aabaa832e23f062e91a2
+5032519d1868816e44b4e0747795003d7930299d6e1e2a5bfe0d595dc97e
+140989ce81d8d7f852ff9cdc7a1b1b598c69131dee005b415805a16d8a12
+3e6a208511c6d0c255b9a5bb2fdedb4d399c6cf194ffac236883767c0f68
+f4ef84ee696b677de704ec3b097384f2e673a1f51692b7b260693738c211
+9f7d90ffdb21eb715fd5b8134fc87dba320ee54c2cec6a4d6bb350555eaf
+f2ec4f84365ccc0802dbb3bd0e3f0d9f858647dd637725c2caf9557fdf84
+2a0da6a0ca0f1b442ef8ee6cbf2b03858468a466ac5883cbbd3815b28334
+3b39205803c02c917d06825c09e2bb14609fa32c28d720c0e14a4b12d4f1
+25ff6281ff324da33a56fc49987ac7d3aa206540f8127273ffe9a3dacffe
+2b1c269d3db9a811578ac7d532c2efc18376f473fbb2b32ef642b19cdec1
+d6de83643723e3c6dfc87f97a7007b6081894bbc45c955b7001eb36211b2
+6ad7a3d07459cfb33f9c54a40a360cb802fd202c8e93d4db888b325ce246
+d02d1220abf55ce646dfb45f07cb848406e470362f80ce4c02d98dd84518
+9877732744cc16c7f5669f77ef096ea55aff98aa103eeaefb971731ebf37
+82e6ab725d4e9e35b2968689e8007c038cf25b6ae69451a4731e79ac22bd
+268f56942a233e52d71873e83e00a1874e04d3b22e72fb2d0671af81c698
+53c389b51f4a257373aebf4de2da1e4da5e2ca88941f81eae0e32d982064
+c8afdd7a9a600d56d73605b9463c6240606b3361baf22af74ef89ac804a5
+793bd512da2d13f4bb1b73efca1e621ed2a65d665aad0ad228b3b7e3d90d
+bdb6061e172b686e92355a7c7459d83199040a368b5697ddc3b81ddad341
+6ff4405e1096b1240edc18a0e9985ca55a0d697972bb11e9f1bc30765d67
+75bb68c69704be200eef4e11b78addb6229d8fa49a6b1525adadf17122c0
+fff51a08aa7aed158724ac4352ebb91ed0c157e24281bdc1fd610195f495
+e87062a8c38e0d046da4067ee16e81bc5f87e583315b973184e474064482
+9b2a52e0d37e249bab31988b906f891ac904d1bb8901f0673aece60acede
+97b8db7935c6488ade8dfd898027424aa85a11a3da494498b084133b8570
+17a6d507d70a3421235486eb3cf7613c59139fd4dcb92eadc60bb6225d9c
+d0599779217bdaf4813a453989b2e56903f4dbb83d83df4837c86bb4c3d3
+ccf98f07a23ebbf7ab5687c3e1e6792e40f92a7a466de352294064537505
+eef3f9c308c9eb94506db02cfae289f10005a6e42d2dce43731a7ae36856
+4b2983038dad6987f67062199018395bc0fcaf287a2b040c71f7325fa1e9
+a9808979b2fef19096b98b8a0a728eb98f2ba3d33b49e3c20be992822c7a
+1bcca5b4e4d1099d456d8d7d83c57ecba0ff21428024f7572a1470317cb8
+cbc8679a974e13d88c681338c68c9ac9557f97784f4e1c8c2e61f26023ac
+f46232cbbdf3c0bcc5583b935fe9fa09a562129a8927ae73988db0f7e733
+c6561ca7c9716dca9b88208a715166f2fae6d5eff289a9b2edce813403a4
+16f243f1b57eede7d81e10c2da4065a3082bc92a38b2457368eec9c3c172
+96cb09819e9e642d7365f9a6ef430fc7dd611ea5fdbdedfa72634ab599eb
+666a5dc178b0a0bd1fab042792115ef3b6222c1241dce36cb38b738f68b1
+b3cb489fed9e53315553f3c5c3bbce40451e47b7ea53fd3d3aba6ce0ad22
+5daee734bdfa3bf1d81c1b42c6d856a05d0924e03f7627c5eb24d7fbea3b
+d85716207f961b56803dbe046e81ed5fdc378f9ca52c14fd8544ca7c5392
+01bee06487ebdc30ff3b28e8264ec7fd5da7e08065b0a9147344ce28da51
+82335875e9f8b2347a44e33dfaa167232a5c3e69e8c5b58b7c7216537827
+c936f5741b87fc68753eb0d4a466961d0050db59df3195bd3379f5647f8c
+fed35da952d7cf2ded45eb442dbfe992711d22eb228bddf36b8d7dba2706
+2d60d2271ea8e8412f4290b58f5be26ff06f0559872f9de4deaaba015eab
+4904ba1f509f6d517c6e897312ddd571d769bc474fd378af4360e8b1f103
+aa75f48721b9e0ba589319e15d74ac0b03d730c3ef708c7c504787483f13
+4ea6297097b46d2680ff8aa50b7a255563c88d594b912f5574564a137146
+3674793e4834af11d14c7991e7fdb3a6abf8529e1a4f10cae79c60d37429
+579093dbd041ecaf03824df9c007e96f45595a524b27ef8774a83aeebd3a
+7134ab4435c80944deff5c1cba921b0a41b9651968581da4834b3c0e6d4d
+e13c1e792fceed26a72adc4d9e3903661d8803ddb58eb2b929ce31fc9f50
+a694116b00ac9f3eef53ffdb1aca3394bf11161038f39917b022394c75a0
+d467d64b89a44e5505ded7d9c6b8ba6ba098f140c9c00e09200eb4828356
+a2d6be9ec1d5524b09c06d9c6fcb5e2808050a339b5e5fd4dd6c2035a48f
+e9674520901edcad107f67ac8c8e508e6003011978d77ed225f361bc0f86
+a98b6120eeafb73f7377db1e7213e02d12c330f5492511b4dde08558d75d
+5b8aa2d56a3111dccd257ee96e3446ef1c76f000c8916c4ce261425ed9d1
+5b58ced128daa6c1300466e7b152bcfb5e6faab2519b8a98f26b29f98133
+af886a0aa7e586a090bda1dc6120dbb5640885c609a8bdadeefe5de0da5b
+75a8a29e92515e86e7e66bb29581e5aff8cb6551d8d1103df60d558e7987
+e6f56126a13db2c9a04886c655064e68a0a20d1b7de24dad22bbfee1b7c3
+c208d4fd6a58de78d6a0a6126efdee3b1a9713dee94069a9f0a2b392a2f3
+91c4c75327803b53f252cc9ef0323f84929ba4716c50385681ff5b4ed549
+29821594f9026b7c1297941b178c3f8a704ce09760533dbc6cf4b18afbcb
+ad039ecb2ebdc7838a9410e7b227924bed7123944675a5dbca388b710f8a
+f6048b03dfb713f881ea0f3b191a5cd989ea150b979059c8aade40385581
+5d8f7980ce6288f47eaa37c1097d33f13776f08779063c5217d7408d9835
+aacbe5c071ea40c9ae6df685f4a9827b828815d8f3a672e73a418e5cb156
+84eb6c6fe0998a386e124d76620446907f993be16fe5afcec681f585601e
+18182edcfd3024062a3082af97e803c47d32229d0a24596cf7e03f18229f
+a631175699e2f0d60fc09c4f1954c5d12d03bfb4395f0e5eb6c687708380
+7d91d93ca4177a6b5a8d2aa500131fcb670e711873f8a3c77575ec93a3ac
+ba37ea117db268cf10d04ad0f079484db124f6dc14a50ad3b0294f7157d0
+837d8f9a6060fbcb385606066401708c041594e0396a0be4b8b66fea141c
+ce4bd29366a986adb98d9a6935c49c57f8cd415e93ff8ae0df75e463e02a
+ac68df064c1b789b685f84e15e512404e065a39e9e8f5568a7d97671ae16
+02605fc7e4933975189837586fb1a55007fbb0e91382a629277c36a190bc
+85af49ef3f0f38d4add2b5dee09916b79690ec83473c63e92cf617617a66
+df472a49641da10654e3ad3880d060b02a4a6c75b51e4e9917a2b6d8efda
+12d59de5a8e222dc7e82f02f23a9d3dbf637154f719b14114dbb102be5eb
+76b441d7e9990ef6420c2e80942c8aed5a1d0b19bce115b5929ab9e145f1
+496753dd6b1798324f5ec1d0c7f26fc3045d7bb46a14110c99ba07a45ec1
+6002cb754c0bae7a1a88eb387bb345fa70b0a38ab4d532c2de49274d4f86
+f2582728a2cc54b4c09d26c0cdeb8fee6a42885c6207d74953cfcc583ed8
+2dd7c0f29d35bdae5bb251b8a2d4b1dc97e2264dce035e359dfbadde84f7
+37ea6a59c23d1a64d963e635769233624f7682ea34636b595ccd064aaff3
+887d916867475731bfcbf7f96d5e5e1fbe6aabf454c2f504ea4e8eb38291
+1560195295c87793d5f7739ad7ec7176e126413cd4d1058ebd7d6ebee14b
+b94a1ecf28b686411d91e07373e891f78c4c0a05d2e8d90a8ae2614f7fc2
+63a762d0f43485473a54c31726f8547701d4a38d20565ed1707847aed9c8
+05780f062b847e668e15565cba07a72b0ba99f03fb57d26fa26ff579c30e
+ed0aab6fec1b5dbea81aa88f16f0c9be869505be18c1cb79657d91d6706e
+2a3f0be9920655b93ebbae2b4d0b5df6be622c951f2cfa42aedbf7ae649e
+2150fe87cdbf5c2685ef36051080bf39d864573a45ae2648ad97662b1f69
+787031b9bc43511fb84155ecdc3d91e2475d072bde6a5207acea1e0d2ecb
+1da8a1bc4beec335a5c7102963e84b97be741c4458acc3d72a7e53b1f08c
+955f33edc3a0dc3e7308270c0f7ff814b111459985733c62e8863625a551
+837952f3cbf32adcfd9f345e14b585b23ecc440775310654daf7f41e56ff
+45f89701292019a94bf30eb2d65e14b1a1d6bf89d4cc43187adadf3f6e03
+a90ed01e5d876bd3aa56e5ee84dbaa4dad9824de9984bd45af96fb8a56c0
+10b3c3a3c6139d58e9d69d9109db18561b55ead6452497840b9ae90c749c
+155b6329716f0152a7ad52dbd0b8a25b9995e1416681f38fdbdfa443879b
+5c4c25aa29e0dcc07de8bb161c36d76ef286ec88d57c74bf44dbcb4feff7
+71d3bd82c8f4e233357c48e516efe3db9e60ef168e2c45b54651df9a5acb
+5f1790f7929bcb16ce5e9f6a43919ad287dbc8e12d9f9e97e5dbaa592879
+1a5a02d39d259f3ce273a870906a643cc18d86e23f115d2a35de6926053d
+8c84b940b362e7db183c4905060316b269223dad309eb5ac96deba757bea
+45fa3100f77f4765334edf3d659e09bd1a5552da492be9174dd406f8353a
+059ecfee3709422940a8c369919ee1f22f7c02412c995fe93dc4559d32a3
+155dd22d3526d89b16d9addc30cb7ada6e52d62c5f2dfd142d4d7b6e0666
+71ebad08f54917e317041f410cfd8a3243f8b39459c418b7b7c6494551c6
+f6753a94072d09e0d812351d62916383c6e061f35ed864923002007e6260
+89772d269b298dca2cc1f25d9be43fd8ad62d554c16afeb7ef6e5dda66d0
+5a810f003cddcfd2c02fff02bb61344968091f67d3862c1499409ecca137
+b9a2a9be314995b818accdae27ed4ad583be29dde4e8c2400c5f8152c857
+09ad2a4737bac768feb70ce81a92c9657dddb2d0bcf9169d272a063c75c1
+50addfcbc2f5f2503de3d13231aa8cfb396db38e80197a605f6bc20efa1e
+de40cf424cf221218d51beace64a3dc88377e4f3efe43db4f4fc0803bf61
+764104cff0b618c9031198b094e20b0facfb94240b438b67ba298e31d3f4
+e31fd190e48bfce27b1be29d36e765e7d295e96edce09094fac43b87e294
+818fde9363fc7dc5ea36a1497ee25762d02dfa00a9be53f87abe62e52ed6
+f59818fdfca643042ec13d670ded1980413950ee43372d31ae2694b83dda
+42e1fbb049f7e7b7e69c93ffa3195a2462423dd2c022e5141783ffa07e19
+2aebc5070f08b23aec9142eed56da74f93bdb50478da55ddd0a9987fea13
+1e4cca0efc51064e4b37632728261369c3fedaca100f1aa78fb718ece7a9
+f56296c5fb43781e63f36b0e1d34bb748eff35e1953941f94d1a9b0fa474
+fd68b47183f2ac53a63f9f1d30b9b89c5fe54c3765b43db403d57994701c
+133e42b950d9bb1ca202f15b5e590ee75598fae43d5cf1546572770bba9a
+6373f100cdc61db4e5ebbe0a93e0e51c86005e333f69110b1c8e492f2bf2
+52cadd5b73e7d3ebb53e759353f1ef3c9b8b39c230d13ab7158a5d92ee4c
+452f81f6dfc18803280aa023832fd0dcb482ce5af615c952bc3f7e58f641
+7d69775fc7c0d5b405aac632857736acf32b2ee0f2a2c0f3b3cad483c614
+505be94706322f2a2830fc5ab592907d0291ed1873377e7a6158140c2cdb
+1b0e27eec9ca50176102200992308045ccb5a169b61ea0546778b8d28073
+7319046716604945a21f2a1cb9e15e3a5db31e0fb5a3b0afdfdf6f3424b7
+536d473f9756ca3694dee4301fb1ab1ae47128f8d2b461c051c1b999dbb0
+10e78dd13afcbba6f7d5226d540527f17881a18f551b3eef76a7e28b4fdd
+879381a2217ef2ff9f9982e9ea70ad2003b862d7c36d57c5ff9fbeaab560
+40fee973efc3b34d83191960010110ba10694c17b7635ae03cc1cd087c0b
+05522a7a791f0ca34022a3f5860b536d9551bdfdbf560a07f63aa4e68740
+7e5e48584e689591f1b52671213e430a708c06a34d2e1d51cfa6b328a122
+007c81b5eb263b967746961bcfc8772f8502dd95898724abf369b0877f33
+13a167f3f714023c229c5757d4d46fcd9b4afecd093dcabe52b78132ce9a
+b6225c9a344c4bf8d96f2c50c4272cb9aa0d606f013b2642f8c880e08ea2
+822c8cf5097d2cdb64932fe195abd5fdf36d3be123aedd8ba2f82a8a628d
+be3ed6129dc0fdc4be50d5574ae4fecc65062e70f4703bfecb35eade1962
+94fe173ea57938679dba6d15448ff44c0d1a903b202439da93c0b0e61211
+0068f8079219aa89f435e44d0464f54833beb338670bd820d941df4b31f5
+1b895bedf833f9c43cb7616db80f988ce72fd3c12c7d49f740cf85b4766c
+0ed398eb837695d102dec16e24b7475a0f5dde88fbf2d6b94f126417c811
+e8362b9ccc52d8891c13c10937aacc228d621d4712cb9de0bab60ede2a97
+e9292be04e42e6d3425594df56931a61e1f961726af6e6891d63b240e6e7
+9e5bf30c052091d681ba1102409874cfd8edc3ee2be331676e31ac00f807
+91d1019bb789ca4f5907f4823b002af3581448c352bb67d80fdffcd1c5be
+ef60523330aa2c0456008f62deb55e69ac2f86369fab1ecc90d2487954e6
+1117a90d9269a65dfbdf297ebd29c3dd1f62755f8f289c42a534f5965068
+5f8576ea2fc5d26b99b8e3dcd3f1feec73131000f99aa9868ea9bac0b56d
+ae2cf46da6cc1d18c0ab8d77becff7b89992175cba2e22779c13db9df53f
+f5b1c8fe95e164997d94202c37175e562c8622989b075cdcde173452c064
+274354d5db8f7d5a78d48ad4a103b9e47500d08edc7c51c1f3cfa7f43c36
+86a3c24a7eb5018b0f419961564f87e212ce0a0741ac68d6822c7ab9fd68
+85f5d0b2ac249cb7f50e2353cc4b0a6a24562f564fbbc7090c3fdf1284ab
+0ec615e0b3fbe132f31570c8a65c814f93910aa4bb80d516cb70d2e1d119
+69238e6f022d628fa2f33a0a15c4ef0ce7f753df80a8ad9494885a1b9ada
+e6c38ac9da6fb0a61696ad3a502630252ad7b574c841117d34bd20bd6581
+217d977b35f5d04e02b933e1e84f5c090f6615af484d63265d28517ba74b
+ea8876fda332a84aea12e6cd82b94ae10a778cd3a216abc08495ef319f06
+ad6ff8add237d911f846a514fdbfaa8a1ec8e0aa9f80f11f1ce615519a4b
+044f3d1cf1a17d7f3d2174222a5ffa8b39f20197ff6caf250b6adbdbf519
+1c525070c8d38220fb501c223f493d80f498621a02ebccd6efe914f16b2a
+435d60c0a1a453e288a53d818fe1edca7d55a26a017f2ee47a816e90d6c3
+fcdf0035eea307dfb06d2bcce43458a67354a4edb6e5c57233de4fbe41ed
+07ee5ec77a5dfadc4032138da9e1b74428cad02a913e40152f8063a774d4
+fdd4070e4b8a6c089f199af7c529c277e902195db760d81ec655dffd1bb2
+83f3c5aa8bb58f2476bc797b2892e94414abbe96d4db93e280cf7de23eb8
+52e7ca954d6682a6f1a4be0507884c2a05ac863d2ba73f3b54668397b6c5
+4dc2f4183130ab414875f3c3d8792bf7e5fc4d228df87748bf0b14178db7
+e3ffb7891d700a1e9520d778b095da80e4801f53442d5c073edeb706a5db
+8466ffe7e701aba9c364a37169f585c883a83713a61c9c3bd9336a667ea4
+e3db5f4df6bc6a552be8d3ef093639ec67e5ff718959f9902477f5aa894e
+d2d1cd312ed82ee417d95c49c96671b23fb0e1738e892adffe62ec1c3d4c
+beb6cd089c98de8d247df7ed17dfa2959d3662f105e8386d75ad30848053
+6959f8e6cf8f2c6937b09f2e8137c811327d6b165abe46c51834a955fe83
+06d10033f8c2a34667f13a8ba831ccf52c7a21c13db92f3e77b55ce291f6
+190bb1d194a33fd73151c3f61abd2d8a0c9bde90e796bd996d2d0094db2b
+e98657e751bdeefe8a43ee4501b98f0cc6d80805189438872a60047a8caa
+9039893530a3e5f6bd75bb466b25165737c939aff3ea59bff4a7db09c2a5
+b36b8a1f0c6c5e5870c7c9412589877ef44f84284b8a53b5b74315ce72d2
+eafc631bc4cc2e5b71dc958b5a6350cb5f615c3a4502e973622e3e18193b
+69572def1d02303a375ed60aba1bc8a179faa0f221a49078fe15ae133835
+85fb45ff4d5f3bb3d0f6d8bf62e9bd6bab3c9a7d38c8a5ab0be57acdadcb
+d02b1dc7952d73aef702d406f62719922bea96b8fdc9b879708e794891c7
+a0a42f2ccd6812c3f4db030b5178e3a627c3e77621d312ce4ebe815cd387
+7208fad92761a5396b67e835222609f823728b1c987857cfeaae21f2ad5e
+a9d841212993508091a4a2c268bf1d8da1c650f6ab93995e7c13a3f84db5
+5748c626fd09c0da1e3325ccb0bf091e996245bf51eb486680162bae63b6
+513c74ce83b92359938439921950d713c69324a87bce67b45a030c9cf10a
+dfa0a82781d49ff224ac57a23c6cb321f95915c5e14e41fa852f66e1e204
+4a9e7b1dc3be9e818515d28b2c4d2f2210098c39557067062ba4239f2aae
+28816d999955910298a450741947a9a1aabcbd8aff3530626089978c87df
+c73618c044731b6db8007739a9699abc354a6f985e03c11d750b8b9e9ae0
+5436205faad1b895b159e2c90562b82a62ea1a7ffb501767dce2b11c51d5
+5a17529ef5adf0a0ee9a96d0e7e89f68e50eed813836531b4b46e9071e84
+aa413f4135cc882ce832bf78ecfa7cab0c9f64eb92c86dfcd1152bb7d4ab
+33831aa0c139b555967f6346068d5c3351a7a4368eebd2933e6b9f789daf
+37ef536fcf965c397af1b7f98af864b301f3f440b7acf704b59540453678
+fd6c15045194818938123e2f47b265ec4f5cf2172d394543d84cd4281165
+cbeb11349b315a85deb2d1699507b0c8c110c72662ea2959c4962ff093aa
+5ee6f21f89b3ccb0149cefef1855b9a48d28bb363416c015a1f4ea1975c3
+d8807f616c5817c8162536176f464a198ebee6c97029f15f414275a39b82
+19128b8c8542e94835507fc2d3908bb0ec375771280b9ebe87e827811418
+ef93e52ef70546891bfc0fb34969fd7dea4ce7524d9eeff2b46bed908c0f
+b2e02efc1d1624642eaea1cac1eb4841e020532e88e59ac890e6c3f44734
+b99722e9816402d1d0fdf8045c5481ec055100836ebfb48e9fbc39214303
+2c909853c9ba38a19363141bed09daf02fdf4e7cc9808321cd0708a1b452
+70bffcc3a0d7c27f7e781713d5dece82c72ed30386b02d14575a1a644754
+7ecc7faac1bdff332c92984758e242256c054656cdd2c45d46e67aec6f83
+9f95d74e222a6eae12efaab723a7c816d4e42d4ed2725a794743f67597f3
+db8ccdde45baabc25726b851e02e56341ebe69e4d91f2a233583ec816f18
+a1decbda4ab69320f55e730617360fcfb8ac2d2b737675b406297f7f8c4b
+c370cb084c22bfec5fef02e9ab290282f7b153f0a4b1ae569f1e52371a43
+46a748dde09336cad1f5337fc3d7cf0677091e59480ab15021e023e356b0
+e1bac6c6471ad53625c70206c338536f4d0d40733ab217e2297f86b59371
+7c61458b6c93a16027cc886a8cfdc01ef19c34c9a608b95a84b6a2e31454
+bc03c10fa55cdcb7b1eb7dc16ac1e93981a46decd7e7f00638dcac568744
+69a2d9b45cbc81398727e4ed3db5db31965f358d8179cbf934ee2c4d652c
+9cc211807f070c80e3a8222b4c31ffec8dfb9ee07a94c973462254bc1b15
+81903ee6f9ad91524a787129a63fce048b45bbe6855826750c586b6b23b8
+05fec3e7aaac079576949a06f422fc2c826bdb78ae96135e9e2c20c2b2ef
+f6171d610b2eb8635acab7c5c5ed9c9ffc26cd54d2fd4cb9e4294e178cec
+a1e16cc8e3fc06518bd16f4d63ae2b435753538834cdd9d8ae7de624006c
+e688938031336351a6578c304c2e5480a3fcb43a8bee4953dabc30558b77
+90c6e7a6f0f9ffa557c50417407ac6a0dda1e736f7070bc89455fc293453
+3db004aa9070734c8c2608a07330e421a0220dab99f8a77489132f6413ad
+b9ea637f3b75948050e667276a55beb09d4153dc126bbdbe0db9298ac799
+a943d72afb769bfa1488d311beb86a907ec9385aae4f77835dffe4389e3d
+9aded1b08bbc2b1ed6084b3d1074a326ccbf38e06bd026919107bd03bd9c
+30470db779508dfe0dc82dffd2ded749e872eb7eb9ddf509d5319865070d
+d76846c34e4e43691af429aa40db4bf2cdd50b275589987d8081f7c5a046
+1aa5d1455a660178a94a0ba0dcb69c3cebf5ee0426d6534f6f919d9795ad
+6a0e1a1f452af3b4cb2ea54d6011fa809132421d111efc51174e223ab6a1
+3596411a9723079231b050cedae7659cf168c39aea9c6902c2cd37d25492
+cee00096edd63dc7643b667fdfde5b595dc54f0a72c2650e1e46990584c7
+8a5cef9bfc3c5f88cfb0c49cd6cadd9dba675177d601927d75c6902b55aa
+ed0e9e3cb52a577c887d581b3ce6201a1c77c9546cee5a13b92963337f17
+070e2bf9f5c5e86b84225863874618aa50f4de855de567bf2ab7163944ed
+43dbd7f4bbc0e16231807c43dcb47b2eb694e6fedcfbe26194d2d9943a1b
+fe32aa1e5305f5e341ea021f91532162978dd1b8c5295a5e7551e2dee46d
+c2347c6b32197af430af3bb676a53bca9bd1ea88678377dc0a9a86e2ab6d
+e29e3e261bfd5573c66fb5687ba9c0544d894a759866b066e1db5c66e60a
+e071cc3a1c4ae40197cde4ec723f7b80137619dedc99af57a5497d6e03c1
+c9e672e74f48f6c213a3cfacf2699cae72345a51c71c1d69348de5bc5f44
+3ec0eade1e76a8a33066922cf3869e3c1d26a3b34e540dc08ea4da2dde3e
+eb17c16790da4ef1a3a76d71d34b788a87838bf2a5a3db8176f9c097d232
+0050a79ea6c4a94926da11abcdcd26dba09fd33f30aeed977e8b5ad928f3
+967f607628859429dcb4ecec7da3411be35a03851017b535985632639d37
+8cdcd13b00fe537a49fd9eb6df1e3aaf5c41ebe35721fa6833c2fe08aa3c
+ffc3477e7fcebf9ef9f4dae62ff78f319481c3f1e72999c8a493ec6ee295
+316b58a5cd62ffab62c896e521b678342f04bce1613cf7f6778cbf5227ba
+20504500d743270771953acbd5c6586432f3fa6c0987bad33b88bc6c15d2
+9c4b3cc54a9dd72a2357aa5baeb2cb057cdce72dc80cc98c62b16ac50b4c
+6a7641379b766cddf990dbb2fc7f9cdbba755b6e3dea438fd6699c30a99a
+8b3178e6d613aa938120835e517431d28114bca1ab745c11fe6e52adb82b
+9d3d53a33bcc49740c93017d9531ecf43831359c5c93cb0e926db440b139
+e3125cc2e069b1cf6d96ef68407f32db517242c3ae0bc6723e560b0f45fc
+7f87a5e44e1751c8b7f9f669c24ad5cf16f84fb03ba121b86b0694234d8f
+2c9c947269af96fca08a78f736e4e04acea44c5baafde360fcd8ba6a5972
+4ca86160a5527fd564468123d302db45173c1b216b01dc5b6d3415b13fbd
+bbd3121a5493374b3357efb131cabfe5087aa1d2c7472b0377066b3632c8
+2073c6a846285cc953a8f28e131cf587b35217ee498d9a1db57b063ce068
+daf55d8cc1771c0c30999ca4fdc5d67be4e7e69418f6334bc6149000821b
+89a7437ccdf9a6a0ed702d5968f1e04f7e4fe9fec9d1e994885cb624035b
+bc5426cb8edf0456828f8eee75be491b45fac192a405eba25caa4f4c66c0
+dc234d7b417628da5276c08260be512b2432256c401a66e3b583e69d23e9
+fd278cd5f2178544d05416b9b4f61a88a4728af2ceed07c08e207f31d644
+e8e3ba1e4e2f9d8e30936bcb9c6aeb54e37db46bd64f2ecc1021336d0564
+df0f18e5a6b6ba470233d8d41fdd9d1079706ea685b6d8a740570bfb78e3
+984bb155c3155c69bcccb41cb51975eea1c1b4294cb546cfb03dc31bf86e
+c3bcb1977e8f94a771cab09de12a82f1d6c791fa7800e5a21df81c9c8fcd
+a78622abe75b54aeea747aa4f26d563200992e337231a430137c720a17d4
+4f3ad6cffe63b2de12d3184bd3e151f955786b8ddcccb290c42718f3a219
+1759df76371c2fc177544a6c425cab14aaab31628a9cf9d71b5257aff0d5
+9843989cf0d747375a26dc9ed29b66ac2147da0168306c48c2484c70ca92
+f33c0c138f92f276f5eaf5ea3082a8a1cb12db661633c2f71e3b69918f50
+9060ac949fcd52c36498a2abb77d139df1eb33e3b846a7c1bbdcef5deeca
+4ef0ad250cea9c2751e13ef7681e8fae0491cfa6c144dbac1fc39d39e76e
+b12d3ee9ca159aa77d2794f0c433345b135ba632f544082bbdc9471e9fa3
+aed3a7d465ab7158e8ac97f68b1fbc8d368e235045c18efccadee98778d8
+94d96301f903283c5ae355a863bb0dc5809158f7e108662d04a5c1234915
+e7bd5b4c30f9efa55e702e54f87fca06fb321507bc57a1e55cc117e21aa4
+e3a4dfb77c1a949efe366d93f2bd827ef8cc16d387ca82ac039f77fe995b
+e6d9aefc87f8d809e90c1017803bcfa1c737dad5f1a631ebe6894ad20c70
+791665e7bc71f21c2c3f4462f60fde75c8a377cf49be99314663c6ecb538
+b1bf021b2f2174d2b22cf6fad115eb0ece8a2e64097a5fb0a2af666e1ee1
+3276aec59fd0c9d4bff23f71e835984e5eeee36490c54e077ad7355dbc98
+bdd37df29b3ddf8c55480b7349c4d17322418705796a8c521fff920dd117
+73fc44fc631c7d6e9b420d7965d7f62ec7385f2be30a51e2d796483134f8
+40aec71fa19ed1272c27f98f2cdc9c7e54dab585ac1703ed08f5f9e82556
+4902efd08edf99dfd49444c21fa6be16cb8a1b6d0c8a5abf80a50bb8d055
+483176fd0aa07ebaead88fd694f96febd60751e5c4d8f9bc747d4f4030bc
+df9b0370b7a5e0a6923ff60dea16ef47f886f10ccee6956ecf41a21f7c59
+6f3bc78299a9657266807e01762b2b2878e551914ca312c2a68d34cd91e4
+f5115ea1fbe801346e14ae529049089b6b0273e258785773a9ce8e4b6c42
+11cb7c2767319576758f811cbaf3a3ffb41b31306c49f3798b698a47bfa2
+e3ca0251c4d90c0b02aca28c611744526906791d9e157e54ce4e1bcf5b68
+6990ba8ab7897d624ef00eab92cbac255ae9177da9f0d86447d35b452cd2
+f337147b5d3ebbf2b95235778a72914eb3707ea78294b3a3bc4acb19fe87
+c72aa1d982e4b822f07b115cadf4d3e7ee3d1ba708653bec6f0a352a0c33
+252ed0630e7274961896d461ee8bf523d5911bac1c8ac763e5fb11fdd217
+4e1f129675969c195476c7a5e18a81bf9a11ed9f2336d5301e3bd32174ed
+5c933e8c85d6272ea21852a6f7e2aab174e0965f73e0ef89e906bafb181d
+bcf8b1f5aa0c12d12c6272753c016afec2ec9f9541b8757874d6f2e061ab
+be8b29281677246305b3c41e90418426c575baa216cee3c5ec29b2fdee1c
+77c14fdf940792f48a56ae80aa33e370b037cb28a7373f882022af378f26
+b6006a049fd3b35074a865c97d153352acc156992c00de26ad21c982c71f
+0edcfeb61593bb40fa5f2cebf23c4ff34a4f4bdb73ca273c269242d1c611
+7262b7c47771f2619fe5710855134a80fa8f92bb2425cf88940ca3450f81
+234abf2b11775929b12cff86442b2aa0f4243d324a5983e5d1829775b3c7
+a111d5622d1c4e2b2a2f982fc8a95f789881416dcb34950a393f4f1720d2
+212f3d343a17683060182355de9e4718506d76c9184f8dac55788d7e603c
+faf4907dde965a49c323dff425fe88c09aa4a4d16283f9b14ab9ef1bb885
+a954034710b4a9da4c88a8a0932b18d139a687303ee562ec9f656f12f3e8
+f27daa9c75db0fa946fd0e1a982bb58e040bfc0a49a4ad8cd668493fcb57
+3c849ec5474049a693cbebd4d79ac7515047cc347a9a7570c90861f3ecfb
+57b9f53ab9c0d6b05c8c570a8f3c04d58555a45524c98ff091b8f8a422f2
+e0e9e5a7b7ff69f1cefc13e42f1ca276bcd584516d266ba6838d5e9ca9e9
+854f50c7d92caed61aacaf758a7c7be59c3baa82bf32b691aca3e8eb171e
+08ad22c39fbe586a54e6e4de2cd86b31138546bb8da5834b2c6e4838547a
+1b67e651964e43988c8036931088904bbb589ca901e7ebbc094c0da81e09
+1915d9e46828ad8596fd0fca39ff12a6c27a359337f973809e81b2e9e3d4
+3b3146f2516667e607ffeb9ac80fc95a7b7d4ded551fee0f3561c70db2d6
+9aba96673e39e3397f1c3f8fe5f48bab8ad6e0ed8901f90f6cff24e80cb5
+dcac498506c4d01033e497c1241e413b022227a3264da68bc3f91b35781f
+a2d018475c199f43cba7d3a0d5697b45321bad2c394b207136e1e16b4179
+4975e8903ef2b2e1c33f87cf72c325c11ec0b92fd3890acdf60b521da325
+96763bdfcdca837adc6f26f129b23ca32f9cd39b33e64576970df3c05b8d
+ca4bfe2f17e6c5678b84d69494f1dba9fe0446ae6afeaa1ff245c07916c7
+b7569e6267c42b459435a1d116cec665b311e404171774c0acc8dde96b0d
+9167c8cc7d99c42405592d745c4428755500eb4719340d2fc6bc215b6782
+3f69fa949c08b5ec985d7aa87c9ac1f9bcc8994c6cbce6027b7d1e0c22a8
+3a5de61dba05d4af6884c95f46ba7f253e0b2337e312916e163caf9db2ec
+56c5425990fe73ee53e42b3bcca1cf642f02b0c5abd529b568e9adff865b
+9dc190240ad78ad226ed884bed3c285b4cb0e3929e805c67f1318d186504
+d92085764b70de6ab5ab6990f181bda50fc31262348d980ec76608cf0817
+6c2502e065ac2d8ea5cf9e2d44e2b70a7ddc7b922047c471df8a0b2087d1
+106b5bd8a830ec0e53223ce3c96ef56e5541191167860eea58d696ec357e
+c55799438c90156bbf2b13a0d5c9ee93227746654ed73ea5b9cab61dac5b
+c690f89c87fecaf9ad03bd39e438f43b81d39e07e0422f94e8b096ab38c8
+8bc2e1a043811d8141c1a35dd3a6dbe41620e83c8ed3a379cd80d4f9bc30
+41bb44b933daca7c5d4427ae94a176829f24b5968b713431cb8bd9f53080
+832c6b784cea9b515687f121983eb9d9c9ce8bd4fa3bec48afe64e643b7b
+d86d8383d07521fe5d091392be124ccc911136043824b686988e7c83aebf
+406d2da88fd952d0fa9327f4ad04c55fedbfbfa76ecae8a176c516479ae1
+467125b7eb3c9e7c5b103bc0c470946346df271f8ee19df7e3ff7478c35e
+e059297f4bf21a5c7b95993be6202e897776952a7ed0613a5cacafa731ff
+c633cab62963150e86edac796026ce02eb235b9f7a54e0b0c5281567138a
+612bafe409a818c216da8eac5edf9d1e3a1e3514ae50735a111b4d2aa083
+4ec6c11e290d58ff340f82f0e079f1c7b3566f2336eaa45bf72bcf885699
+88db5f65d4c1e59b50f341e45a899656a0b522847ed567b49cd5284fe50e
+5f8652cdac1c076804f2b2185f6a51ed19dd49412e65a0d2dbc844b75e2d
+f71b009776d9f97a4c6f786effeb87a307fb6b912bb659dc2bcc6d509a9f
+bde87de8d716040a8551b6ccfb7743978ad992d14d2b85ca052e87326138
+db196c24593f8f7ecd6f486f85d1666b9de2aca6c7900044ee369d223524
+664a2790b773f9ea26e0a4cdfd709942a44298b8249506eb9b77bc887dc0
+ef947dddc7cb3cfc6b48f060dbf032a11884e6c226d9d447a5a458cba325
+d57e144c6dc295262763e7bb8ff6a0ca473eb7661c12e0e8e23ea37e8ab3
+387b9e54686f3e57765d4067e521bc1afae52394227793c737c19208803f
+2f2da920b553e2aaf94eb992ab17e31b58c15cc4aa8a1b444df5b3e7cd93
+7cf03e1f7fac63342731b4589f16939d16e8e497a74cde5686f529e9495e
+1603d74875288cf53271db9313a4511b104f80b179fcf213558970a002e9
+45281bf3ae51e668dd6d13d9e85152747f562ca0b75ddec8fe9fe31f8d05
+b0f59e802888a7a4f19b29954a31108d2f041367debd6aa1cad856bdd142
+7e9efe89956fe28d500cdc6a0cb80a76902a08d0bc6705583243f1dd8020
+749b257edf4803bcaa653f7fd6d8b91690995ba5ea3ee92fcd367c11601c
+6b8adcedce67b16c596c5d200693ac5fa15d4cc6ce9df7a71c8a925e99f5
+085313d60fad25c1bbaad28d4ac2b69062d68f390530a976319a3904cee4
+4dc9451e441aab4780425440f8c499b81460b5d3e268974145117ed843b1
+71bb14aa84c3a084a7d8e07b9979260675d5ce6534dc176ddb60dde90f6a
+3674f67462ef78195f8dff74fb5882b079dee31fe92816f16ce1a70d0775
+2ea25faf5000adf79bbe7d17eb1bd2f9bf6cdbb6f078caf97986442680a8
+fc4121866f9ce86c385de34e30d8b9768a0136d9eef79a4b38ee99cbb9a4
+d32316564c9d56996e2595753ea71bef684834fd030d38bb100e2332b026
+b046316a53270a96dab2182e994e91262fb03d1affbad623f16892284098
+84f91dba153030870a7beb2c7ee2dec51875b13733b7929041f8d23a9490
+4bd54dd4bc9b432dd0c78dd81639f46d686ffad39aafbd1b6c1a37e248ce
+48f23e12464d5379b4aed0d50b5a41577e6ecb75270e9ad3ea7d0fc09dab
+271fb18b51dcfc0069f15d72546e6c51049f3425ad005f88fd7f02042dab
+e9f097f9d6a076b30d8cd777b1ec12bd163fdaba5972eaa61e3c87e9ac00
+7a052b1a3ffe14d7d43c7a0adc89b1dd4cb4f9c762a84a6c0701494b2d8c
+4e4e1a9245738be4111805c2f153a20ed9fecf2dcf4c8f7c3baf84d60454
+a7403d4f5f81c6404173a7ba81bb0ceaecfd493d877465dc5735d43e3102
+cec57b8a589182fc65a4704661a9e351fccbc7315a87e62f65d24eeb9cee
+979c6e10dbcf5c162adb926ec8cc9bffe381f6b8a3ac0a19d1631bea2938
+731afc99e8eaa39bc75ddb3a39d01ad8f0bc1838f4d674b9bee9f6f7be4d
+9c8bd97e8d171eff330c15b76614a1ffd25b3be19e4a201bcc850f926ed5
+1616318c965ad2f0e56f9433b1247c6d5b72edf3d408a3e0674a509bf30b
+e813a5e669d72b978794683ca8b85e3469eacb167c30f7666db5e081b81e
+e99ecfbc1704b9646b1a29e4a4ce5654ca8409add60145dfc54225bdb848
+5e39cc98cbc3f38fd0a797e5dfc2099452a2418c6636bd2d5f6b24345acf
+a65f4e7dbd2d0aa0c1776a4920b4466c509bb5bc7d6627946c4dcb38a270
+98b7b5beedc2b3ba18f927077f71e38644597719652037621bb350bb5369
+dccc073954026e6438fd8393ddb3630c4473f06d9fb9e422e435566c396b
+12fdcd5605dfea232171cd8ef298786806e9159b84599c26d4c7d8c3bb06
+4665cdd072e2083190372aa808b2268b3fec8878b6420ca829bcf995dc20
+e067ee6b8e44d2869d51ba3aedd1763f7f8d2cfb8ec41e6e9e0129de5343
+1457960cc51d546b10b8b6ce08a1c2b79fba448df9783d815608a16c55e5
+89dcd8ef6b04c66232f47a473973a35618000d79b8173258b7365c9691dd
+fe47b16eeb08b28f881828b946fb5d6fe10ecc6afc4ea1f762e90b332040
+3382e42af4885b183aa48db5e4dfc9a54e0b4ffbf7c26eb17a4f13b4bb93
+12234434fff05549e7587ba0373acb3e31418bfaf400d8938fc6466b9427
+3d1735306ab912aab13e31da3541c1733e2a7e4da5b82767d37f3084aa7a
+7c488cdca7abef77d19e42b4448abbd346e9bc288abc4540c0a1cfd0bf46
+c5bc7454b25e27e9906a3e6cbf678bfecad1b19b4e42398a210cd567ec35
+fb115d5c0df0eeece593982056b0e1d14c292f70b3e049984f8881c8b477
+956ad3140b4aa22256daac0d11c4126808b5b9f922bcc5f24a77ff352e2c
+621a3941ac07a20e550a69c49b1b87d116ee6f2f970918f0f1a501166ac4
+423fc212e4ec8039ac7f9c212d864f418cbb92948fbd588228108fac1ad1
+837070512305c110f0fc3fafe6e1529c2bd0dde868a9ebe5137dfdfc5c12
+a3d08014bf0ee27b108002aad6b607f5c5c0f1b1eed3c552919c9a2e9720
+4a8127f97b1066607ecfb47ba95ef2b51f007c293b2f6a63041a9c1120d9
+cfcd5357222e5b02dfc73cf94cf9b5cb00eaf073e9bf253e30e09b50341e
+57bf245a746ea31bffd0b00201c34cf0881bbd1006bc9ba7d420a48e5368
+6b598bedb3449924eba58d5db1b1b01ae2ba281d5758c99efe38adce18f7
+b182fbd0d0622a6ea497a4e7c00c7d17299a2765efd8de376c214d01a218
+19451fc04a0277ec84a151ff93903d61c78ab7886911e36e12526ed855ab
+43f6289c1890222602b8efbf15782b374ac1e580b6e963403d6d15a051db
+8558f2e61c0b9476c6de5d4861585cf515ce951732f20d32969f39192fbf
+1690d242ac04d47e0c53d467d0fe4656b9526c0f7f852348b0437737cb0f
+29ecf9b54a5e17185236dd0c16349c3496f3aba569ea20e343f6d771210c
+39dc932dc65ecef94575c6e76902cdf6c8c8361f9c757a2577da535187fd
+526699917cfe0ad438c2a758727b306bc7979547e68b94e87ed820614bdb
+c649d469ef6b4e4e3dd2eaeb5f80b22fe576ced256495467c76a75f58946
+0061e03f3a1b065121a5abe3e2c51148b3ddc9f624c97889aaf7fb84b158
+c015eda5670746c6359d27b0c2bd65144f2b88a64331816da904572be398
+e015a9924218b3eef95123aabfc3ac8217b7b4f691219a1c9dd0a3edd5c0
+4e63acbde71b423522532561f4b71b7028415c3437e346be728a415596ab
+749015c1d59bd8328e39a850cb98085b34b57fb52dd1d154f98fec49b3ae
+bfcb1672762e4d2a1ecf02787f59df1ebf2625c3631bed849b298c6d226b
+e4e6ea2ab66a287d2ba92a6c9c612a5f849b3cb3c25f17164be286f6e4f5
+e7e4c9eb17bc68aa5ef0190b64696a570442e1d9bdd1a30e7692524e30e4
+b4c3df84481dcec6e10e7308e65de9d90099f3fabb3f4f766bb86cc98594
+6d2003e21287761a7386cd8461615b570bda015f5efa23d18e83c325ee44
+4ec166a1a32d9818c2a65a092d44156c06d3fd079b92450b8a491cbb3529
+ddac7d95afe8eaf33777fbb265feb8a4b9aff2cecefff49afbdcf6c41974
+97d3b448866d70ef28d8e4b17e7ce95f43f64bb48c4a73eb84b26650f62d
+3e5199d64db0b5b87702650ed0b850fd5d16c848d096e4c7e61bc63b2a3e
+cfc099cd713e12c91a6577a88d6f55d348617c7a49890a86ea8fe2045704
+b5ed529db128c9b19ee129e5fe6498cc97087f6bde96007c9d01ce9caf75
+646e5a5b32bfead9362a52223d746943a2d09c536cfaf78e601bc2d2f0b7
+63ad722e3a7ae7069d65f9f2bded7278511d0120f5ea071d41a69f8c2a2d
+720d3b24b4be61c83ffbeffae21b0560a6fd1a44e53e42e0d10e0e93f421
+a8a7e167bb65f0d7f1dde2809fa3cdfd931ccc69b119c83238c1c00ec100
+d8e7ab1c7fb02ede97073c8a5860371a8132be391eb1c397b61f93876feb
+438c288ef2e38ddcd182a5cfbba994a94a1bf818312cd8234215fccd7c24
+0a15ac01a885e1179e5d7d6305dc2f534baa141f25ea6a5f356486e5fa0a
+e3c6980a9f5e8e99e7ae5b95ac429775109702454fc951e4319ae4b1ddc9
+b07d0998372c0a95aba6985a4dbe6dc633154faa30ace689d36a7f17011b
+f29cedc58a6692a8b3b0a5742e6cec2f69b255bceda762dee72f125eba98
+891cff4d88aac14188a18d81424979c9079e44890d94ee094d4caddc1c7a
+c5f6791fab8849cc0240a579abd800efe3aa4ee2f78119a3c2806c05c2b1
+f17940be73984982d1c0065433a9bd658ea31ac819da9a11b87475bb565c
+c294b6f302fe3f7752ed9b963c5279b5f1196762d0e12e6da46ff9a0cade
+3876d7df695d8965cb4b47b351fa3f759811269376b2c3134403633fde27
+c9b024f6ba81f3e1699cf64a426618428ba6c3266bf016c5daa5fa4cc82f
+b6dc23ff2d742160518cd3a65adb38e53f1067076ca1625466e0c64670a1
+564a54ce14dc5c57d24a12283fbcbffd0fd594ac2a56ee58b552f7586825
+e4fb1ec23f8221711692c8c56f42272b87ebff3865191f1c11943bb76d8c
+0cfc53ed452ae49404d2c8193ecc2a7bb8cfbf24870aba38d2ccf7869e93
+63dc0ad94facaed5922b324dc3b6fe83e7b34fe29abc1ead62b49ffbcb81
+1adbb5148d5ac2743e3a058386036fadab6ff071bc1c3b8023f908b6ff48
+db0ab1c9c67487c35211d40995e1892c8b66ad6c9c6203f6f8b513b11117
+b10da8725ab45b4437b5a88a96af3178d856d601196e8162868a83da64e4
+08fddebd14d6591881ea652032cf2f88b3fd6c0479c8f89ac68d14d01af0
+ceafd95ad146e68fae01a07f39e7a0c5e4ffa6d6a91d710827ca5acfe7d1
+f946a8d7b67621d60f5341f32c12a6efb03ae5ac5373a382c044a276f6b4
+1c173d0aaaae0c1de4c3cc71ec2637225ccbfbd45eab92bf39357c57195b
+410f74283585b12b926438ac72afadaad2d0fa2cca728c8e86bd3fe75d47
+b8beb96ab13b5480f7a3d5741eb51e3e40c21ff2ed7d9221d9877c7d1a8c
+ecf394e4023fcf8c4efdb38b839499ff5cd96a46ab4fdb46f35d3b48b917
+57c0159328120e93cf1f2739e936e28908fb19471d3ad7f6f1ad2bd1ec36
+4986a411cc1b547d0ca104fbc10b1ca7b638a60e75485574034561db345d
+da68415146aac632dfa34769b6ed7d7d4694e92cbff4efb16b5549590810
+2e85e827fc623cf1bbe6a13cbf64e878e1a2a159948b5529b75e071744a5
+f0e50df18c110b0af117ce7f33f8c959d4c98ced5a9d492ae6f56da57b0f
+17495dacb130660bcefb064fd8309d965abe8d2be98f6898c1b7a39cbbe3
+e75da0ffef6cc3945ce76da3be915546fe8a5310130ae0acaa9ab73c7e04
+1c00533b4bc7724657aa649b9388b791aac5eabfcdddea2cc67a0fd0ae9b
+e37df9ad40636538ee55a83f60e9e026c64fbd8b220ceb46e67410144a52
+0fceaca252e8165448f84d8ea083c793ad09b90b3ee83b73fefc3365c729
+e3c738894b8c01c2f8aee0cc8b114e1175efb44cc4c6cef5c8754b1cc7ce
+c200ad8bf1189d741cb75bca4e88be959e32216ad33f674f49ab20a354cf
+3969f1611a95d3934e148831ae7c81a7ebe3c5244f743e66a82e10d16cc0
+9f8194ea7a596bc5981d833318ab4f7dbf2abce543e410b649d18d146f01
+486159683df61a3f880f9b21ebfab77e908c6cfc79f89ba5f51114f0bf7c
+3ccec7bf0f3b057c3195cfba6908e31e0df10df69163c9da7babc00e9a58
+0fa7fac202910615bd479bbf76fb8068630d1ec21cd2926d351e869e16c2
+cf1e023cf04d4fc61607daefeeedff5593e6023492f00029e2ae4b4a2c14
+50954efa2792f32b4934a768f892171245a1e2f034e2b9f39833f1b331a1
+9a386baacfec8c929ba6b67cd8922bbc9dc005ec3976575d5b0508d0717c
+6bf11123ea36d8fd37fa77a6f1f5aa84d4ad8d25b2c11d1877a6e2f9b74f
+3b5829faefd4f7209ce9785aa6fde68672554a6f29d8bf03fe108ed90a7f
+58690fac399a8ad3a26899072b832874ddb629581a51b3325cd9edfd49e8
+90ea8959db937dab83c777f2a426b967af5888c33a3635b78d647ad6ba44
+1e222c958ea58d61945f781d7ef409771b89b20242ad7d07c2ef592cbf41
+3c5fc89ec30fc9ebee4bc63709ae33b65ee3091cecbe610b847e12c556a2
+79c8b114c3e460822d3330adfd72bd69f54c08a81848c2002a08326cf3b0
+9b1305490d35aee5917908e1604ece75bbe811a715ae8af7ea9c371b322d
+0428edf4c893fdea607e70e1b6f6614947326101eaef18e29be0557d2a92
+cf1fc1505e8b434bc368ce07ccaabc0774f8a63e1073fbbceb3f4052462a
+a9008a1e53f188c9eae339faba74afd6d60f47282cd9ff721f64bd51787f
+3c13b5a6c5a5f78611710111f5e0471e206d72520f1dfa465f4a23c71dcf
+99a04ceef11b0e3bdfc35b7461a60753d3ac26dc50a5956c9195a4f52263
+88e0953ddd03af128a98f03bdfa0602cbbaa20ab9eccdf7255962a332e16
+d4380762e498fda4885c64ff5f9b480da487c58e78943df62616e6e2c69e
+ec8836dfcfa9ebf58938a878f3e792e8bd8c5d6df557a5d82018dbae1ca9
+c64ba5af8e21be1b6680fc5db22422220b776e9ba0bf1ed2b7212f8bf111
+ec8c8c77b223c05eb5e5f1cfabd2d037f4ba0f9503e2cd83f4519d180476
+63f09e308883f5da5228f83045ff41214d2273b2fe0a9017d5e0557bc2a1
+98c35d1e7e81f79654445760cba1d3f05ea4b90658e53fdf0823bdb1501e
+d51da75c47395073d8980d1e3504e3f67db3259e4ee73a87cfd96f84e221
+796573958d364a51e635fc55478c9cbf9aea16b7d8c25f2115cfe4b7f598
+54e24968833ba0d64d1d332a666dfa2a3fd71b05a26bab7da382907b13de
+0b80871df184d3622b623d7e09bc32a4f6ea2e6da450a906ead36d53fdec
+7f83e101fef32f4faec581b000686d86a0d3861c1e67f18a4c4647f51f97
+8484d9e3100b37be9d20ae84c085461c1fbf929c669e936659050c2627ac
+1b019837baa75757f5b0a82e8ae9cf2111931a38bfc94744e2fde3f87103
+42ac615286e4ace7f269743aa05463af537d9416230ecca859d8c99b7c6e
+70be7fe11db698589be9e11900c8e9582a4ef5ea94b5f62820c90dbc022a
+620ec536e06cb8be7526a789996d0e741aad980880a33800a6fe92286ccd
+02c9cb407eb31fb95d9c9f4aff38b37087ac582c1f7b64a7c3d2202bdd62
+e9aeb31bca85c4cf323f03da9d318b91f78fdc0d266630f7444ed068b55c
+05461c97552366a82c2e743cec353d51028fdcf5403b3b74d379b82eb69c
+4380ed40239e15a86b2e5c860891e26781cc111fb5705e3b7c7af1946006
+54b5fa1b5fc54fd0ba43666e7babd2c91c859f393ed49f7123edfb648a3d
+6152f2c17f7e438c0a638968ac06b4fb3f77f64f358ae063820bd33f0213
+c85c40e4d97ed100ec2da1c2e1ea258bf107af675a9d995f60bfa37222b9
+c2b325c0052bb8537d2b27dd43a129c7e8ff42757b3ac9b447703d382108
+da520b8b3bb3e8c7295b776b44ed28f863b8e1f81b0bd1daee8a171525d0
+9d2620c04dd3219d880c2ecc79282dd7b1772a9cbbca706909ae8bc7798e
+6ec7375189b6cfce8a875849176e5913b85a18fb197a33ca4b5b4058603c
+f1fa79a56856b43d538e9ece117d99afa73b57e307364f553644de01edb4
+6234efac13046b6e047ecc8f63942f20097ad7acf0a45c0501a95263de94
+39a880d6b5c5214d29180a54d7fe9b2e627ef49e189b59fcc78745e878e4
+5b46c0a648955d3ea8c935113d94f92ec963f66cf3cf3a526ba71cdf3cd4
+ca69efab08b7389e3390716892a4872bd29dc1e0889a42d7ffb4190e9a8d
+05d84eb9c5741be6b02716bc75e0106f5f94bd3778be985e03860d27e440
+88c3cb2a059debc420dce3a8f4087a9548485e616c409ac400dd1c411ce4
+b6a229d091b253eb68f06e43511ec5aa6eca4d6e4818d6aa2068da1aefca
+377611bfa816b5215182432d5683294d67a7c1fd76c52233087ca44943ec
+7280005e93145f5e7ae50100c18364e1b36741e9647c4dc1f68a58ec4409
+5920fdcf05532f60371780f78420077ef5c24d63e26040cddff8dfd65d87
+1db943f50cde84900c1372ef33fd8ab9889c82f94f61a0e6842219a0f39e
+c7b232cbf802c4a744f33159432e827006c7ca77e480a48a9b0e6a876158
+8a3102e3f98a77bbd62a3a23150fd140d3941773bf7cbba2338ff37b9eb6
+40558a2313e8824e8e620331568a9b76f4897198a709f9313f4ac40827d8
+c3a71f2abff02bfd57d30d0b14012fb5c39b85af540dda0adc27a85b3169
+4e8d7b61f9d9b476571022d98f2d768246550a877293f3ff6ed918a498d6
+a600223e1a61890c49acfb60265867ce9464f9c32c59e94f7641c3873fb4
+fa6eb237f8ed94579957270d6fd640bd9543e683f2372ccd7b60aad269e0
+3a72c5cdb732b128818d41a6ddd2bc139f7d3911f48e1b1d263dd4ae8e4c
+e1a686f3a00a2cbf48978631cd243566e22e68f8d7397134a3530ea3745e
+4f1eacb4d6a5fd84c3011094f37573f7f9902305020c53926716d4780c6b
+0a257bf711ad94c83f1d41a02c1c7dd203a3e6e4b14eda2fdbb36b063a3e
+074495f626b0eea146d22ac33457f44f416759676d2a0566ec2b726d2f05
+40abf225339f02f406d4e7a62e5233ddf20ae7c86ca0cdd561f33c422654
+bf2dc3685ca91bb9d4b09ac8b15a24a99ff56e2894f11f7bb4728fe8f0f5
+b799f74f475d2d01f61b7e9e0e541f7feb8a557486d7df2ce50927515d83
+3bcaa1cd9bf7a650bee9e003a5951c98ed147c4c52f64f692ab281984ee6
+5a47e44a4a5fa93d6f18d276d3b01c5e5f6135ac6940524cd713df4077fb
+4943e8ac927a68489ea52acf7a854393cd027eb52ea2dc6234ef034f3dc7
+42d6db5a67fc21d22b97146b9c268ba97c30161ce01edc69a6a1f05efb0e
+06f22644e1a368f0e2c0c6c1c832878e0614b74bd645f5cb293cfdb7618b
+837fff14a1210aa061c8c81867244305b80daa73cb25a417228e9559e7bd
+52c119b0ccdb7c4dce7e1b9f7e8ebbcb575e5bd213bdd6db88769dacb05e
+5870232f0ef82f448559187423409eef756ba6247493be24cb1879b5dd82
+2e03d0adea1edbdd83d3fc46759c679b921f0616f27212903f728ab44c17
+84e8a7dced0df5625a7d3f48a20fca34008184cecd145ccd98e31b79e174
+cf107e8f35c40c19d86b40baee6164353408801edf75a619ffc5b6faf3f3
+a95f64795cc40c1f89634fd8c13852d265fbcef834c800ab46e3e8167476
+b23cdd8aff6e2f997c99a86a9cb30ef8c853154d0d89eee9b9cdc1b4f27b
+da32432a4173b55ca8d9fb50acb2d886ad8e5862ffd5dff224ba13c8b8a5
+4a7f1a9f987fbbdbc5a3c3d762a5be309d5d926ae5093c40aa47b3b1bd82
+8797cbb9bc9fec9d19eea73d2a39764816113a8edc6cfa6e605ad578fc8e
+30abd600658a49abcd5ac54655d29c50fdb72070169d1b389f114b7c71ef
+95a80d82ab537ac8c165d47371fc142a51625029a990a577eb1618480d72
+6da93c98e5c5f24f622a850cdd94badaea91d4bc32cd50ce69e9f00e77de
+a8ec1d37916398fb7092402605359df08afe7b99c76c2a7c70383f28a7c0
+00c696f45291bb8f074791798197caff1544c76ceea8c9e6d76edcbd92a8
+6df889481f3bbff0865442264f0ea40d3caa69ae467a08003f9c30ff7f2b
+77e767580575398462d5b1171dd441d8986f33bc7bda17d413ebb6b7a326
+42e33f20b284bf3eded002352fc66c6f7741a542155f4a159cd778be56b9
+492cd95115c1a06189a216cfd2e6725965a13de973765a05114d9a5a4be0
+615af8bf6a5eaff84468b849954d15beae1cdd57c435788b331905c01421
+b50f20b184506a0bef746330bc98e9c89aaa8f9d102f158043beb6a68205
+9a1c8b8cf67b2f3d7af4d8bbe086254cde53765e3226ba2f95ae8063649f
+9f94bd9519411daf8a0287307335668190638806e29484a4ffbc1e46b180
+0e03b162c23b1dc0b4c0dd3c7abed2f00762972ef06eeb9bcdc7b3f39c70
+be32789d366f073ac3280c273dff2979507671b3e1e7685a9a4f0fd3867f
+96dd675bf05f25ed986a79249b75f182fd73cda2a6a66d693e4cc5afe340
+2431b2c816da1486c34bc9dca4e2d51c868688a7787cd10abb9aca14b718
+1369de89913cd8fab58fc84519ea2aa14e54b7a8ce474f213e07cf2de2e8
+88093deec937526816b71c96ed75fa9e2edc0f9e6e84569c12bb8e39aaed
+bf546630745553d6084ff9524fec6a7264f88ceb7ec3358e923b392474e3
+a48865564431662988fea768ce555ab0da48bd526a84b0cb17b4584066c1
+640c1023d91f7869ef0c4d701be121a6e3c832010427490758aed7a2b30d
+6028f2215aa44e86d852fdc67da5ccba79eea863bac9edc2535b66ab0e54
+ec4d4411390fdeb8d1fbc1743f15c3b68dc92a8659e7a892d5e53872ea51
+ee8ca7ef51103e87c29a2714e907c79db9cf37441785d2f73a1ee5855011
+1a4d9bccbebf2e39cd3b93dca300fac3ed1add8215301e5766c30c8cf296
+75746c5a77bf1fe3cd75d25cf193de8d9af02af8f7a6e8f84b548058cdd3
+c6998ed13463fade739126d83d3ce2c7201f955382832e32c10dcbcca358
+35985b9a93f8e3b0208be6e92428787c47d3808a0f77b8f1d76e6bf6a17f
+f81cdb065180e03809d03638307bd7bf5cedbf64904e918fc805ac905379
+928b816480f6e3bdee47042cba98539da0e113b1a5f23eaf1a3210bd1856
+1985e6436eab90395da477c7a6d7888d2377b3fc4169368357d880ce041e
+1f7c875e956600db7d9b35d1ee66be476e9dd8064cc02230276829c2c0a0
+98f051502e828a0cc505afd8c3df293da1508ac4d25866beee6bbd5a230e
+9c2dcdd4f06883936381f476ddcd86ccfe15c2ce3c3243e148cbe603b851
+3a7ce7a6910a66a90b7089e5ccd4368befff2bcf8e918bfe0a1b069ab2a9
+14ca7bb91a0ac3b3c0b060fa1a0316f6135e890ee549315897c8464496cc
+6dea0f7e3af43ffa4c3281156067582ca255b1d2e80f999a3ac0402bbd17
+01824c3bb524130f5b82a45275807bc2f3a0655ea208f968b297f98c3691
+92c8aca26beba7dc4506fbd1305e2efa4dbe5375281a88ee2d6fc88fc0a7
+55e72934b4b58f6dd3bdaf7171a4a3c7765767352492bfa9a7758504750a
+b7f38754683b70e9e293cb1cd7b23ba62bd7397abb84d7edb22ef6c3f58b
+3eeaf656e361747ed04020163253d1cf3f905b5e85f83fff30ab2778cae4
+3781667c0f65c8fd404d6b9202a99ea76af9ae1236631550b66b06384718
+0b6dca832ea8dc4a6efdb674b5a26552a7c7d54c2799c7d4e03c24f661a9
+1103086de3a90a774a6988347656344cfba06065ab22476bb09fb68f9928
+c0045f2764af643cfef0516d87fde6dbf93bae2829b176cb507bb99835e0
+1bad5e55c2f8798c93fa35eb3fef02cfa31d3d21b030547f86d27b9448d6
+8e2b155a65c742bd2999daa0c3aed64447b9cc67f7af33b63afaf25f3cf7
+ef86657fe8f952288ca4b691d369e8f1935cda44a180a6767560c2ed3f2f
+cc38b6bd7991d4170c7c566d690a8a25be03212a80871108d18cceff2466
+23e653107631f29227d64754b2208d19f84e547799e691ca473780ddd56a
+e620cd953d5133d135e3d51f237078feebb7371454ee633cfe238aea63f9
+999e32850e6c197687a0ec4e5908d2a18c5349627e336ab5e3185b218228
+603a4b1852069f5ee849d571b8387dce1f8f8e9fe94fadef128ba83bdd24
+5f8c1c27c11f2ed1a8ab2d6d601726842cee744ee7aac6b6fa16ccaa39db
+f5b3b1d47339f31dfa562671a9cf7dde6915fef9f19b3e068a464dd350a3
+ad146d1a241673b5112a4a8768f976723e6e184790c0604506c46591bef2
+106c40789b733331a80740d59abed39868f80becc2aa21c400a0bd0cc326
+d186fff9eb37680f1edc32ac78f9059280d07b5ff2e354fed545129fa5fa
+8f3d4317ff21e027602fdb2522f049bb545ff4da60248130f81f4e348373
+142f3148ded038afba818f26d5b49fc02de9800d894e9239c88ee0ede431
+f8083697cb0be3b497473473e5714717c914a1a926730c249413fea2615e
+f72bdb0906933387a892370f77eebf62d26cd583ee643b02e323821379c0
+dc966407d36ae3cdf646b95dedc7d7fd0f28e95078f12dfc0d6400b327b7
+43c548a0a3517a175a7ed963ed756b1e107ae7087e2446ba702cd4e26e2d
+cdc1a8b697108b5b5e81e9f03105f220c72d4aebc57665887c8c7964089f
+be9424120efdb14d76eef8c6f7a30b13e1ae90cb9d93d2e14bde47f4a1d0
+5ed5b18d32aa39911b92d24c93976aceb7ef597a75161923a73b2cc76178
+5493d0eedc08b5afe95f3c006b41438a0785c962b070de2bd096cb63b847
+c87539880aa3d3fc5c345e0992d7be77c6cff4948617fdda784cc5565219
+2b0ed775129c4ea4245a41bcf3875be319da0ee2dafefae920cd2b6c6c20
+01762f88c0c5c05053025c0349db17104360fce15d7f3a8e30ed13155a74
+faf91dc77b8aabdd6fbd5a1eaf255db209d7f2b90822296b5603fb5e2cc9
+5cbc5f7a6044058b8044adce73acfd896177f1f70ead2f6534dc3ad755ab
+2ba87126d63ca2e9c441df0965bddd6be494e58d6b5057a561d1e31bd38e
+92cb73c1465af6b9c001f7229059bca4104847d1639e124e082f7364b565
+48bf8112d0eb461b316b2449049f6a476d36d6b7c0c1126c08f2e9a1246a
+3b5b21e7c8fac6e23b82e33a7783e4f31f0240e96e69c9444e7d7a928636
+cfd086475df1e0a2846481387bb2010655b9f81a0744121699b4905aaedc
+c84bc5d5ab3674601dbbb651ede7b5df05c8a463dab41f79706d285c4f90
+63997f7ac8cef35cad51fbe5f5bb1b3fa6da2c3abf2b3e925581349728d6
+da0d59c1ef6444539742ee9a23a5727f20cf9377f4f84dea420607015a30
+fb14632d084a2dd181bb02fc3a84fc499b318156b675b9ca3ccabd87fdb2
+497c6705fa70eba43addb6cf961b30e8f6ab9f84e1dd8d6db3314b34b7f7
+aa3bbe19d5bdc75ecadfd8eae19e07b387a1fc586f0f30db695926764b54
+0d89f1d854b0ff86528ad9523caf56371e29498c11afb2f4d5202670c834
+e930103f039d1334882416a49bf93b84fd3cf1209eef7d4994c8302436c0
+794497461c11f5b8ba152bacbcc08af8a15f4a4df3effb7227ca97fc21d2
+d0356c93390c749cbe9750b821f1a7bcfae2c8bc6d9a27f844d8ad088320
+79abf0ead8ecd4ea72846dfeed021857f33c1ace4c07bec90398b629814c
+498d33beb375b9a53da0f926fe6e89e70322c72cb2ddbfb16b13ef7a4f50
+df783316584c6ac2bd7d9029124933133b2229bf74a228868ab30ea5c3e8
+7c78c3f0962199480dbcadbef53bdde45849da857a4fd85b96682f1edeb8
+5384929dee4afaf84c51a09f5d572705673d885070303fdb47dc898f874e
+103a9e7c1e894115dfddad81549c7375d4aedcce2e52c13e5130b47f206f
+7c5afaf1f9ee83da8188d70b473269ca280a6a02de85300b93d8a4f6b402
+fb5df58f1327470ce11cc63ecef2efaa396a6680a6746a20382d9529b58e
+7ce684b39ac00f7086bcb47c2230df0343bed9b9152a61c9826aef9e00a1
+452d91305cf05490d4bc0badc9c6fcbfa93fad52c3a80705a19568904975
+57c0873ebdcf61ccdd2219354a4f5621ab33b11932065c1d990a9b688583
+31ee7875cac855f98563b14ef9e1060bea90f195afff94728ae935453438
+dab35123d0e2699475884ddafc7307a5cc06920f35341728d85965f5ba86
+f261cffcb1e29b429f976970d42d10e6af6c4b792b4384122aef2448e22a
+58d3aa007743c71324ea08d06819fed14ac1f22a4f0be4787bc8738e1cef
+240677571c65804ed3e748d72e89c94b6f310be748faea31ee246859caf7
+a1ea17ccb5b246c87eab771e2ac5d378650191081514ddc2c66878e3766c
+b20dc49f630f2743a7faecbe9dbe9e815a3cb57dadf2bff5ef2fce23a562
+98a30a2e052feaefbd698101f9db992613706693cb0efaf6f60c8bb5e7d0
+a50b3392b9831ef3a304a846cd4af431e9f018fcd3a5b16387552d55daea
+683d36257418aaa0e7bf8a03ed7bab114d7c15119e6c71c1946bd7903c1c
+42e115e954619051b853bf05ae316e15e619a7dee498f771e809d9435969
+c1056402725ef40c0200e083f3ec6e0ec27b8ed38dfe32ea0e5e156ac36c
+4bb9ac5ed111a11678339703f1b9299345aeb1f251fcefa11fb3101cc499
+907dc862b4463d5523b9b25c5b69f70ab6b29cfc1df1ecab8227eb3ed1f8
+82e90b12080ee003714d403ec43b7b54491446b6a3dd6eb641efbfef060c
+45e873e7398025b1cb7065441f1753028f6f8c49a96801c0d598e098eadc
+96a21117f817b6fd6e6947642f93e22425a00e8f6b592ad50b317b69c0f9
+4047386a45e5ebc9504fe55451a01eb29ddf9a41d4bad85fc84ce280971e
+834f06cef49c8c20ed2ceac889f158cb14a8c070900478804cff1d1637cc
+880c81aa287d8382837ffa8f41ff3c9df2f22cb20044c171e4815d0d0f6c
+22d19a52114e780cecd71daf63427782e85e463dcb333789f496340e8cff
+885a9d9a4250118b439c71c6be51a9338be29251aa794edc67deec6337fa
+63ca9b03c1c9f75e733a4a918646e7bc9792486cb5a4bcc5f84fbabdfe33
+8c3792254a3eea3d88903c2c47b91e076259dccc8bd3dca90eccc832c09c
+45141c6242026bfe309029a562c3ee0fccdcd40e5cf265ed9c3de582884e
+0e14819db98b3af734b1b3276ac41d43384ebe73003d15ce39ffcc041095
+83390e470f431b4407f98550e138f96c4564b494e5480f47c853bdd237e2
+7301f55e42a3bed18fada152572b7b465a581dbfe7db2619365cf16d71bf
+8f091862b9fcf04bf8d0859a76f46e7b5712f2757edce332d3213b8a30ac
+2ce7d7797eef6f30904906b0805dfa7ca36d32a20d989858497a66ce7249
+1393dd79332003d55c095a5ab5df761c4be5c041fa8407263d604e53091f
+7b6b15496245dbbee96a63f10fc2978d99e6573128689366fe8b0bada48b
+50185b861bad03e3600f22bad4274f2542b635f6c7944befc3bc741bdef1
+1a8dd659038cb40fef2e16ad1ae7ebedb7d9ba15fdcf26355331505a386d
+d7399fb999535d6061eabc61dd76ef3eb457446f29d0bb6ec2fc0aabac20
+b27a3c123c27bc27a76336d0a0a6d456da0703674d959a4afe428e2206a5
+11bfc80039ecd56e75f69786da0a8084d81a66644dd98b6018681f1d70ad
+e09bd9bf3d16d68dd5d0a03ae26dcf1552549e459fe190b310a8776b2c84
+68c14ca8b1b9a7af2956507a3b705ad75a17a0eea7fe089273353cecd07b
+b8563465ec8deca0eb42f43fe3664eb5f31e1d1324185539b28d508bcd06
+5ed576d8814ed3fd637d576f027927162344afb0255a91ffc616948e4e35
+8867e9fc76a9affacaebffe110808c1532a2bbb0dbef3f010e45ffc73f22
+8d28f12e98478b27397d8f456781ed9e19711df2e9eecbc3fe61f7493fdf
+1a59124668a91be51f122f93dca4bbd22deea339e6eda3d6ebee03df9581
+13e1ca49c8398d2c59da6764882ee3663f62a55ae50a7e91b4fead1b11fe
+0d50accc5d75f1a515f0c53616a500f1491381dfd0e2477e402ab0cf9f67
+d501a442629c8593ed5d25a72edb9746b02f2b0f0759cc9cdcb4c9d8b451
+9c8c617e569b432f0cf6890372aa879ca7de46e110d95e230a4f0e52cf65
+811c54365df4a3e40d819e2fd379b47da3233d0def0efbce04ad8baa3888
+4f6a69fe5c373e38ae0fd0241480f2be7ccd18af85916d2703a049779fe7
+398fc47d348454cf03f22eb3fecc064606957898b5643464845445c25c0c
+7d685c8db042af5d5882174374ace90081c686789bca96ac602eb41d317b
+d652293ee628951875641661ec86a2c40a42e8f0813a861d41a0f5178e55
+43651ca0e99150462db5ee0010f00de6d55b0d7fd7ec5baea24ed3e90a7d
+6a0589761922b91a6a913a7feddd3b68254d89ecf767ce8e27f966426a8b
+4fb1b4085384fd09d63e288405b78a646f44c87eee22c8596b1318808547
+9f75f63d3d97a28f9c8306fd207dbfd38dedf0ffeb7dd80b2a3292dfbf1e
+d605adf1b33e85b010309e3ec058fcd922b1325fee71eff2dbbc2e68db52
+d513e024c01d47cf657bb61c9734649a4ab63c0af4720ec3efcd82dd3ca6
+e80bb63bcf1b8de810a0c6c517c63b76fe68c0b286867be102424fc31c49
+37048b6f323d039618586fc21731005d949e7d802a430df8d2f0ce99f2a2
+376c2953efc4184355e4d12f422c9e1e25c4df38dea334dbc89b540e14c6
+1a7769d77115ce8968fb76b27d0863cea2496783114c24d4cc816da884d9
+53da3f9b9d3af8938bc607bf26a071956ca07e6a5509ea2f5d80e5cbeb98
+041b197fac760976ee75b470dc20aa023ba3f63c2876eb281ff5173bb490
+d6815604517aa1b1fa0631401b3c1a04ca103e2ca4eccd83874d9cfc8abc
+134cc0f9141d9afa56848bf222342016c556c14b3482482dce5d0b6ef1ab
+522aa1812bdd8dd3397e05327ec12748fc4808429b97202e24e1de0c7c0d
+272c046ba73b37d30930c5de5a47d96955cb0f5ded8f3ad929a8b42d2839
+0458f5910a0f93610f79eddb27078943dfe17c716d65f96589769349f3b6
+6ab7b8c004ccc59ef6881f745ec7129865a76f9c2d029d4660ccfb4d5f9d
+412ba3372a27cb175e9d65f759575cf14a5899a8d31ff039ac02dbd8391c
+3397428ac0d5717c005200790785354813c8859be90e0e17914f6cb9c674
+f1e9a9648657b54e5e1f52756c4f982df74e73f6e4d40718c71d1d0e2420
+fb7462fec9e457c0414a96e475c6be2c10437096fca0c942e995a9ada789
+ab637b648781d32dfb68e62e91c2ce7e13680f8d31ecf8c824885fa76189
+81cd05fb335aa111b409c59ee337df4e5f9dcc920a5fc0d620dc07f20dad
+63f4ff5e0ee5a2f390af1c32122ba7780f210229e5a5e3ed97bc1c3cdddd
+456e739ca782edbf4b810552368e9c734b0c78b0b8e3f8b2dd782862b743
+18871bb1ef087828cc173d7b049811fcf598b8efde4d9bc5447f4848c980
+29c854f3ae461b9d46ddad8ce67a521f3c811a81a396cb0f80f3c8d8ec88
+30532fb7f9624f7cae0f8c6df875073333deb28aaa90aaf486ab8c932553
+ce697b885e71ec8e40c7835cd5d59a2c695db9e51216ff9b77a15b0da637
+17ff25b05b939e45cf7fbe490e51e9344213b32e115c2de14d76dfd58450
+88de645b0e75042a61d82fb1753c445ad0a956a1263e5a096b681d3bc51a
+9ff32ebafff7eca8b59d40f0937eeff38312ae57462c7bf3b1fe24d2ba8d
+fe84515270e09063ce3c80df4935e409f62eb4f54af16a186d4329972b9b
+df15fb08461b688ed49928429226cad9f67c9d636d1375cbb7b08a563195
+6b7fe29cc9efa8d75c9e4919c8c2c54f401d2e0d7bfba40c50cae214d210
+c6f3ea5802339f63fc4c1c1995787617f3ec2c806ce44cf8e29f76606cd5
+836f6e5a2e423cd791becd3f112f25657dfed9366fc4adf90b685cce4a56
+98e5fe16d7542b913fbc01b288dd13f43db2b1ed8ccb80159dbdc90a8132
+125df8df547c4851ca609d1f6f4d647741260e845b457937787827a89e37
+cda06bb191669ac84b8608eae132d10177f3fc384980f3a6e439b048a38d
+0d6b9cef09f3f2d732aa71bd058169d6d0f8c9d146d9da046774027559a8
+b3843f6116b418427e78476ad8f0f81e8a6b12098060ff7dd686503f972d
+6c42fd6cc29c083ac3d72e3751f21d2e44a572eec80e81ee44c90faa7afa
+bcd3eceb98fd4068f6c3a4ded0e6cec523c9a0054d1fc2a8d61a4a26f9bc
+250b8f302416924ab22e722297888b85b9c12f8dfd2a744cbd143f9b2514
+c1cbe988d9cb4e77d90b2efd5c2a528355a35f7c4af039c7d1d756305967
+b847d4acbb81263d4992c001e2a262b9fee2d1f5022be5b15e1d8f1d67bc
+52227344ee912c018cb73e5f47ced54fd202627777bb77aacf3ee6b22706
+fb2fa9062bee87e22cd2802e7706322648daa0c624ea885430175f746e1f
+536f9a8e1c610c4a761d07248426db63c9319a88a3fa449c3fb8ac94c600
+3c745e6bad717a3b2ea3862d1e08512a98e57772a62f85f1e2ffba40e2ee
+43aec11203da9ce5afbf673436f2db6af85bbe89d802f7a9e5fa25a408db
+69e51f0577dd26f94cf2ba2fc53eddd6fbeb534af15f74f66ef8d14e7ff7
+7d8a5d284c8202dd5a6053ceaa606bf9259923825ef4effaa8d878652a4c
+af2ee43ed26bf3590402686c876f86c1ae95046e527617cdd3c429bd4cc3
+f9654d2c76dd4102471ff746fa9fa379b16df96bfe3836d43fcc0b8e9512
+0c27370049aca4ac313e1d50d72d1814f2566b8b29fa9c9c20d048874372
+2a766436776783b939171fffa00e04805a8b58214d4f114f7b9c3c17ce74
+86aea2bcc895ecde809502bde57981318a93f23016f056a421b733c4590e
+34ab08bb348da4a48f19b6befaa1ddd2a49a6c440443028333cdd48c85cd
+698adaf3fd8676739e44400a98b575be02350576f96cfa54d4184ba47555
+b8d12374b86d038d085f7fa51ff4be2ff5981408999b48b2faf305212ed5
+4b2e371f5a0074cf68d1b0e5cd279bbc8bbaef694a89a6c43f518d01bb4e
+8402aadf34e96e9b3fccab4cbea2741d3fd9adf7af32388f7771845af999
+65a6078f4da335efa436be36903e33a743c112c0267309f266dd44fa998c
+9a139704e400b89dab952eecfe2ac09c82d9f4975371ccc27da37890ec84
+123193314d8a7a707c217ffc951a547ee5b6d1b7c8ed85bebd9d3f4b9b09
+6a78e5f7df88c931e3f396973974454e59340ca51dbfea1a00de084b6463
+0e26c6d6a3593b828814e27db0186bf2a87eef268aa1b135ac09b52cfe53
+051cbcc88cec5657bd47f603c8e1a6249161684fd9084ac279f57a4f9bbd
+0a546a87e147b62ac860911969a29b8aa20e3aaad0079d64e6bf1b0f2ce8
+f0c54c9019207e1b403358253c2fa93a662f63b9380b65c5173c198d86a3
+d0dc1800d1f5378da39ce8523eb62c6afad8a0d7ad1629f2cecad82b8fde
+38975303768c7d3a08b91478edb3c45a8c6b7725ea8596a8ed50b8355fb8
+52fb8966479d12e1086223b1e6523a65fba81dd106fe254f7309718768ab
+009ff7714a8c363b09dda73cd3f81bf9c0cd3b0c806cf3b7bbfab73e46fa
+cad2480eeba97ae68ec94d3d79aa01ecc22067858effa9d7b7f997abd2ce
+5aaa8781e5499e8580c405681cc63eea53bb47e55ecc5ba2a7a3c5472df0
+34b022f455c60fff971b01583a29e211a87f7163187b190b0c1083d696b5
+86e9438fd8baa45101a5edcd1be5ab9a585511089ddac8df1b1fdbe582ab
+d945e67f99adc4452988a9859e39c90ef794c5c4e62997085b7a16a0d901
+07d08610ba175ad66377345662da7da4d8fef847ee5d57e3ac54b928a095
+7cc1c944e7ff14658fe4a641cd26c61105c0f136a75950764b69ca17509e
+3c19351d456b22c87c55e8dcc4acd3e150d936333ff36499ad6b02b6403d
+e0f12901301ecb2eba10324ba72b58206a13b8f37b0aeb12115d0c12879c
+8ea8a2eb70e85c95434564ba3dff481c8972587eff74eebbbab14fb32b8a
+84b8fc42ebeca65d25e8c32c19ca5962832bf45dfda4e871508aec318495
+0d6dbe89019cea29e40484c36e33d76b756255531add1db24c03b2a64a47
+bd8fba3fdcb1f5b96f8eecb60d5834ab001a70740498720afb6ec03445cc
+35b51f7987109618c6c78cbe3041bedc69b6fb128142cec5c8683b558afe
+3024eff7a12d04ef59a72e156df11d33aba08a8eeb16259dd9529cd003ad
+4ef4137b6ff1654236473dfb93f597331a5e26c7796f528f65c94fe07b3b
+4f4dd49034fa0cc189dfcdff70c2f1c6d3df30ae103e2ac5cff20664ab93
+4ce5c19693292071c93bd590383e0a1931e04d1ddd18071dafb628f5d747
+2e457bf81d6064edfa8debff91701c5038cb30865d6122076a336732dbcd
+b0a625548773d0013648a76f07bbdc9c16284d158ec7a105ae37a6227941
+9c3a2f360d0c7a74d6fdd0e36dca2a8bd59945a4196598f690878f84c894
+852c1811afea4be3b9f6a5219e6628c66669dbd8fa9a0cfc2dde7716a356
+fc4fb271d8a2cddc8d4684de447355bc7a287dc56852a638c5777826eb6e
+b72faccc86f80beddd0d649a883cfeef4d74750172a90b5dd8252592fcfe
+19ffaad868e99562daeae70514f5de296ef7b57e6f193737abb6aa317956
+584423817e11664a67389197ad9f8f771ea5955198c9ee40a0761639e638
+ce9d890df468642670235f1373d3ac6b1f43b5777fc0a91a96e095e89bb9
+fd62614de456ce7afd6b855112367573fd9fcbbd4a4f9c676e672d62ddd3
+4a9bfe8311b6175a003cd143c0df15e4c0b48c735404086e48aeed6b6fa2
+1fd9f40b84215dff287f0677904e2ddfda774a4019df45cc877f553e95a1
+c65df1d67bc0c60e0bba4d205c0da3da80229fdd71859f65ad04506b308c
+2b783839f31cfe4425263224f08c5c7e98a2c9d3dc8ea5ac1920f4e39541
+3262e0836bc019a092a0deca104eb2df6b63392ae8e2136379140de5fc98
+b0b69860fe8e31dab5c5df7807d19bea34ac14e0abc6f6519c51247b104d
+e7d912c5bf6ef11b48fc6df84512e9f5febb48f72ff1b722bdc3bb2e835b
+2e7cc6324bee84893996b8dc2d4dc2793a4f69c18e63daf04a7bb5c0a907
+6e2d5a343e134cc3c89c4712900656ffc202e1988526d80c7fd9281fe47f
+ba8ab5d025e63a84051f6b13167bec15b346212cbd051afe7a98be3a2491
+f3c469718a58e783ed91f90e274fb4978f8719e92a99a1e8f142ea7e1f2c
+46aff0a2fb50f4d105130ce8ea309b0e480dc8f80d506172b609ea4bb4e2
+bbae98d8882814fb273e690da990b60a9cda20a2418246bd10ae67d846a0
+fa815ac25858145adda106a6778a11877fe59a2abe300d7db9bbab31cb5b
+960b7e4ef91d4600886d8795dc361cbdddde05ebd54b1941f426f7fa8399
+270d2f54c998be92d146227270a8e89af90c48bafc4eccca01e6322afc16
+5743475e752f39bdaec49297290510ffa264342a0afe2985f85deec66c36
+eb4a1d46683ee7c591a89b81569a8566afbca26810ddb0970577a76ec8a0
+66622606b08315db0f2e6c671f3259c73637d773d1a180aad66adada2a65
+95b5f481e5f59e51cba876fa06d21e1d674cfab46a02d267e20234324d08
+91e7847c13c69bfceea3ac55f2eaf753726bceb0de1eecf42ada964bf9e4
+75953302c2fca804b70b779482dc9319b40381e09c0096460ae113c19a2d
+c9157fa138cf0e7758f71008e71d0f7599744d647b09b16e3c795c56ee5b
+d14d8d63e7a512900d67487975ec9ceaef69572fc3c2342ac5d365e8a4bc
+f462006b5268ecc1575494cad9a9e7a9e8d9affe49af647c017743ec7cfd
+5e66f4e4d845a6bbc836849274fbd270cbf263f167df7e26ba91f21c60f9
+6257c07523ac37a2193010e976965cbd75751e312817c0564e1c5ae0cba8
+bd12b01122d07020a0852120680985a8ac987bc33be863eec52af13435b6
+e4048d951f5bce36526e07a8661cf2538f69d1f223bc53bf5896437d1bd4
+6f57d9698f642f0e99c7392d8ee47134e34dce94d392949b418d9821e12c
+afa8337323e8469dac24dadc6aad4a0dadd7ff65694ba3a27964d28d8eb4
+1179458f91cd3f83b8f119bf5e76184dd29cc4c0718cf7945dcecc993a7a
+78739363136cec7f2fb495eea8cedb3ebf14373a058758c442939d367744
+35554851e9519b6f09c31ef26b6cd997dafa11da91fa9759f17b7079164c
+5b47b99ccb7a876fbab1d0d5d1e1a2683cd6914e6b3b755939cef1c9168d
+30b2738c4349650cf86c90d2542fc9b90f36a494c035a1c86dd716014aa1
+6e6b9ec7aa03b16554bec436511dd3097fab1fd0cd49edab96f74e8fd264
+00fc748cbd9ee1eeaee24da30db6f8734b52818b3a5e510aa5c14e420608
+98033e7e36cba9a64042cf94a74e4b52e37ac027c0dc69bac4944cce12e7
+ad81aedce642ec34ca23e3ff07b8cd35dff19f33c8d4dbb56a52534f8a82
+7be47ad4aedcad83b27338409fd1101c4dff3f12d3df79ad1fce65b2f419
+451dd059c88bf066413e23de27d3621dac2dcc8f9f3620dad0f4b1a6e8c9
+e6e8adb552e1eb2c4b2a3b73986ad53ed9ed8911f82f750df05cd2eba3e1
+b0df208a87fb5ed44c3296b803881c1d9776d13350cd29c3f716f0b5a8b8
+557812024ba70069be6589aa579eadb1f657712df2570843d7c5ff7f4009
+d4d232d3547dc8b92ed5c4db77b76255e661ff8b163c6f3856de5651b597
+ec7c78b84f0c6c1d6ea3a82286f1d3bb45f708d564e139e81f473c705ab2
+56346328daa64d1ea8645dc10fd449092e0634d9d7344b2aec3c75f6b6cd
+8b3f3867ff3cbb0f556b186ee9a7c26bd2d17c8a773055d9d5013bd2f937
+d697a770c57bdb36d922cb911cd14e7fa14160be19c1a052e297b1a2d682
+d4bbc9f1d2493bcd7cad2fa75d904c5f5479179daf7dc6a4e0d269baca2c
+4f2430b4c8cf1572fbdc750a05dcd5b09fa3a9cd6f2f2a386e2b3d4d8e25
+7bd43a783b38e63bcee503ea96ff2c373181744a607f0cb8d281d7db1a6f
+4076aa3e2c61914bd796ef8a0873f79f964fde28b792ba99a20c3f1f5ed1
+fd189fb1867c84dcd6af43d49420c8b1f3dce7dbae71deb17fe45644db24
+4f44b1011c7c768ebb7254f4daca64e9ba87aa7cd0f0c4b2228ffb9ebdcf
+3dde4dced39399ffeb348811547d025320a88b480943a339e2cd2fa3605a
+aae87939b1d7901465a1879bcb4c5be1a179e7e371f1ba2e0844f88afbae
+9b78dcca47ae8aedf5bd3d458c7d4a7a08accbf880d1f1dc69c636628df1
+ebdc5c42ff88ff8b66351f3f72d703e52f3ce91e4e00759753a599fdd863
+788e99858498b66b93e5083bc3501c39a9ba928b0d763c28826fd237e949
+ef0ba85cca9aa20c405db6d5612db718f7b4ad31d253ae306e4d7cb615c5
+9ae668d347a4e60fff7b103f8bd0e7cbdb142a763be88ab40eef6b8fc200
+458d728930ad0f94fe52acbf0657c4907cc7942710ab1fd8bd149a9c9def
+6b8dca7db9062aa7b1b011abb5aae8b77893a023f9eeeed4a20fbc30f922
+282a7ae2f1acff64151013d6b8ac2eaae58171a10f80bc18c3bbb5de1e22
+ebe6033bf83040629023d74ccbab3f1923cfa4a6735e1dfa8a1b261fbf1c
+397e26f3ba9c2629cfda84dfa3d1087ebb19dda7e2d76e30dc2e15b8821d
+5291da1dfd73940e5560a8a6dc91be0075e3ed8d9e8cac85ac20768d868c
+d2dc45deadcc8b59aabe6ee5b2f891e0d7cbae820f83479332bf97074866
+98fe196c72ef72b52f54314329fc498171782bf160e1110a19b8208fc591
+ef0f0da71af657b43a7cc649a8488b759f7b69134b4f9dcf79daebc1ce52
+cc8015f324c9d46320f44e1551eda6d86139dfd1db814cf38a22a89fabb4
+f75fb896b00e769820f763486e86668253cc466c1529a5a924cc337c4844
+8851a381dcef63a0a302b65203d6571a1dd1fb9dc0c3bd6aef4891497033
+109ceb5a481bfe442249940ec54096f1d0f2436d9e60495d0acff967a741
+b30467d24ac6b003221318666b951efd45324987b10bef4aaa0ff1df6887
+377a7f70f555dfb9ff1001c67438a167a00b05d2c37065655173a7ed9ae3
+42dfa1497fb1f2fed6098901249a085d31b66dbb6ac25ef16c106b0a6ff3
+47cdf66434dc3f0012daade80b942d522cd59af4c31c1c062157b3d000b9
+cb86e2aa7b4a5bf316058a0d5a148eaa2c67977faa0966e4c3454e08df14
+c2498ad76e389af65d2c139a6d8675298c46aceb7dbe6904c373c06e5f71
+399b2eda0b40ab96e8be991ddc39f92f1d24797f9ec9f2fae25669b43754
+e2498e8ea5c44b176c3fb3e8f7a7a1481275a461f2549afc4cc73e28417b
+d8c5212c13105eab967daa679ae822b9b75b372a99c7e82d6bd83aa2ba00
+314da4ac51b9caa30d80507505be24bad0a87c5d5d7336edf60cca4cec82
+01d243c3932f74d171e2409d789aad0d04a7bb22fb6dc3ab92ae33ffea89
+7c484d741039f38c317ea396a0fbb9f15a27d87fcbe007558799bab73212
+b6e5faf2080ba074724eac87d88166dbc1464cf5d41b99428851ff1d9924
+6944511cf42c3f9248513e9e51593f253d89c604388ad7132d6a169e9dd8
+88e020ac1f8ba606f2e1ebb97977e505d8c40853653d8f398f71cc9f8f9c
+540c22a1e6195ba578ae7262fc845fccf77b33f33eef266489af8b81a615
+d6a13464bca58bec16c23f31d678f14a938bec31272dac3ccb1b2dae577a
+26bed852fc59843176a5fcfcfa0ab7fb00d2309de55c82cb9049f44fa61f
+1e313205a76317c4cf529a4456019d970624129681f46a9cd7950b8b5c40
+61853040113c8115319e68b37f88d864c6957df813b305d09e6a1716b10f
+26f2ef5c727fc77aabba73e12b5ae6416ab19f6563ce14046b715bd4cb2b
+1e4d315f42d10f74cdede82bcdd524a1a54609219084cf1cdabfe72cc837
+5478b41614bc18a914903596d6fc2f361ee519f875385f4ecb50f7053127
+4ebdeb14a5dbd906a60817246042e3799bb3ac647cda7244b7998ae4f3bf
+be5c767fd2142e48518a4217599e0ec2cf5e86c8c270ff8b02f949ee001d
+6a439bcb4bc7d7f7c8167c3ae0a7e59687fb8bf6f37beaa164541b8eafd9
+2e9d152e3fd0f413c99ccc34fcd8aa455a0b55dec846a5874b94fc95cff1
+bb386b2a1e22cd1c3914264b6d5bd1746972857c9235052d77a6c0dd3019
+f8a307fbee63a3ef12b039b224108276ffa84021f1ac5b745c54690b3ff5
+87b4b1710ac3533a67bcefc503adf1f4b62b2910b31965e364eec9cc437c
+c40181a7320cd52be9c546b8f1dc824312216c2fd8232e2bb8d40ee2e314
+54c09772a387f9520e331456c269f51a078e6abd9fb6a68bfd5f557215b0
+bbd2227b8959cbd1bd4aeeab094dd18e891c61fb00933c0a0d76174d169c
+0b6445d34c00dc9e06d85eb086c18f3be27df734ebb9cf078aff65144385
+49cbe92a0c0d25efe4a527d86f158b4e9d8870c7ac5d6c059643a3298079
+cc20398324ca87273b86ed801057d797d91bc3cf2f96c650ee1566cd3cf8
+656cc577d38b830201be718dc9a494268177a5019546eeedbf101996be59
+3631654b638c75a6baa648cd1e7aa9ac1ea60f4cd604071c89dccff8b3e4
+30a57ed6de11c5837e78956ed991058f3646219beae94e4d9381a33d48ca
+9b8ff12b54a73ff869d0eeed7e098d80152295e6016cdd809173c57d1f5f
+ce908a37010ad4c4471a53451de9b4363b63437c374c598f548f145d3d28
+8f42531fcf36a9cdf72521f1c0868fceeeb1857ea983f6b75ce245d875be
+ad1bcb8819e5464518e04717b78bd6e335f0ad77b832af5682062a1e2ac7
+7cd5edd5dc372ee456c96d38bf8bf348dac2b4ebbb2440f2ce97b4b337f2
+e23247e3e8423bfa9237ca6ceb6fb93f960cad894a96f0371168a3322205
+2de9b3be04b022ab95c0c243486e35197721fc55311dc55f87bc72d09b6c
+940ca36e6640aeb66c394a5949a604e7f15dce3a008bb41b0eef2840a357
+f348443b4dce064b4c15e5ec52e448c985faa1c3d6526270b1cc69100995
+9a7620c9a6202619a19be410ff7bd535a8b2640aaa459dfdcb8f2bb35112
+626497e8a397d4f9e04788322a738dc8907cb64315cf63c95809e90d06ef
+02f72ab04aa61fe02eccf7e9049ff9f3ef2258a75656178aaac9f3c2a26c
+001341862d526cc14e92a81bd63502f959066e0bcd659cb9b5a45606153d
+d77039b8c5d5b13565f00d95a41937cf97089f3938e39659a64dc3d6046d
+0e9ef66544caf8a206635df49926a3eef3fdbc9dccea2886ec855f1821c4
+b9ce1d02a19a11bbbef43a7d4d536715548a62802f64af30bbcbea8c7e55
+ad56c801d8a569c8183615a78cd393ca42c103f155941e845712c335f4ac
+fc7807202b92a983111aed241bbb8501f15560e8f2157c29752bdcdb2740
+08137277920053d6d7dcdc626a574a82a8a34f1e77b2fc8cf7c1a7322f22
+dfcb450259eb450c52b70df3584a7c54c813db41e3dd81253a03b02bc252
+346af0160716355797b6f8210c453dd7e1e756ff08c7e6a5f4f87605e1df
+f35a130d79148a57b7ad12d94a129fe3f055cf974eba09a2b13deeca2e02
+ea818a58b81e8743004646c7746110bc61b86adf2d5d8c45a6a5461eb344
+97fccd09e711f47bfa742c73f87b257b53f30cb68d151424dc3c210d3e8a
+c67c2495a8236ea2d7985a5e1deac699d7b700e6d38eee2e93b191baa5a8
+a2c916d206c63fe63427aaafed2b5784276fc21eeff2d70e47c8540dccc3
+e00134642b703795cd3702631ae2a90e063a218b61e5b89bbcfff84f567e
+37a31a9b349717a8cdb9c9377215ba838ff7469bc486b64ef2b6d92519c0
+bf0826e3652903f40e400689f5749df86fe3de178e21e20edf9053081f65
+10d8f19acd021cba481c484d30ead3b84ed0190087ee478a17154b243346
+c3938fdd5340cf6e47b185e64abdf44f8cbcdb8294492b91929bfeb9da2b
+033c3acee554f0f1a7f8a56df7c06a3583c1e9c5ca458d40e550fdf3e2f2
+e7be8312d5fee98543388edc8a04ca29f1b82b7ab4adabba3f2c331eff35
+21b2b92f99c4377ab827a989b423750d36addd2e286e7f3b694e29b8bc40
+3693c6f7cab5fe34f1e48c8d41b47831e8c3f5be5ed5142e3c44acf5180c
+d41fda149b1f4aed36812e42bc184227f5034220f74f67830255e1caec12
+66defa358a87d2e3b4b4e7ef30181570d0b2b43072ee0311c2c157d32ee2
+bea8ea4251b59f6b61d2b4fdeb654deb67aa3dff4ad65b727f0d6b7d6152
+3e4b44d99ba5cd33540f340a35ddd466abea4e72e504fc9baae51d231c33
+a8ce7dc2970de4c1fb5b096a3d9c641ef77dc9039886831ddd01c4f21e6e
+168e38bbdda5f4308c959c7bbf36a42d042da6862937eb20d4fa2e592774
+1a58da5cbffd9553beffbd92e6d64871d8b25d9049f4e71970a8ff5557d1
+de83dd24286d6c3e4770ee00f9a1a0b0063c99994aec75e84d6f9c488434
+d1f3dcfd0a8bee9ed8257ca97e75e8b1285747184d6d2228ef95d4a0b8da
+252318abd35c8398fc6568b294d90ab308a7675f9f160140f0a08c88ad0c
+a1ca2cf85e4d031cfa3b87635f1398eb7dbc666a259f02db6741d13e11b2
+30025dd6dd64c438409af109090058151e4dfb8c0e9cd65935c4cc063cc6
+100fde70896e23e3661c7fc1b8228b26a55903e997f80207edd8863fa074
+ee4ff23be585baf708040c9f8cfdeb42fb8eb71d4cb6d7757e973e4d8c9d
+dd082712c23f868e1135ecd91250bb4335958b07c12fda75eeb56be19d16
+44c1f76a8811c021122619f751cbbfeb1d3dc912999017fa163672a1ef75
+4c5cb78962baab76ec48461b492fa88f9897170de857cc8374c8bae417d4
+c78a56047024731f4a45145f0393a27cab614a7ff747bbc28e6880d4d01c
+0a6cf317a1de5bb5adfa4b5fbfe0c57598c79f25ae57bb797a489d51f85a
+9b9cf8bea64293f8fcc43b0d5484df99dbe19152692ce756f6fbe8ce5831
+cf4b8a5af47524e272c45c62acbfbdfe7e60b05bb1a1a6af0e9210012014
+69b3dbb49ec7b23a363fa68417b7118dcea71d4aca2e36f88c6ddefb7020
+5df3ab7c74cf65cfd01ff85faf99f172689737331d4c6cff7a29029772f4
+87fbf625f17bdad89b4ac076948277b4ed687840301016c2b7ad4c6d02f8
+1e88c75b7a04d724e234e38a38269351582245e361a42c75b8256afd5624
+b558ada2190f960a896bbae7a8c57e76da10dc29e69bbf3aa86214c001a2
+7b39c1d17c548da5601e86a5cf53e7b1896bf003aae9387aba9b102eb1e9
+002dd3754a378f3e49f2c6eecf47eb1bac2cfce11ac0c5cb063672d32733
+563f3e1e891b6073739bc53aaa0043fc45e90e413dfbd4548dd320b681ed
+70a7443a233d79e3f038d26975586e5cdd2115aa614727b1f6dd4024b85c
+ccfc79d10b7b6afa789db37bd0e8c423c1a4a8681b5ff3a9fa1f61a46e46
+c4b1836d1aa41a89264a7f4b1c259e4b10ecdf375bd26a1f412fe01fbdc0
+3368fcaf48aa0ec28b1bd603a6a0d0dade66d14c9b7285569230fab76803
+35be104305e4b748fa99fa31f23991608dfdd2097da292551136f255051c
+9f7eef3fb7c7fdb4e651c3d03a4ca357b587245236f4ff3252563f6be08e
+f8a3ec09be2bf27b9120f7d37801f6999efb1c8ad1a08698cc59ceae2cfc
+dbf6bd8f94dec94f7ebf33af05f52c85760c63950b455510c6ab9398d09a
+c288efa09e8f631a59b03fbbc75bbdafd675ffacccf8adf71e815a4a49f1
+4bf70e42db0b7347b5284e234c24010e2177dbbd57648e398fa6b54571a3
+7ba8c989503594d03c6e60871a7f96459902215402ba168b8d1d2685f5cf
+8645d5e11a1769473027f42564c2966c10c0dee1ee1b6975852a4870d492
+83a470e623337544a7cda5c16fe2855ba2a548511fb4d4ff2e3e78d108e4
+c734f64ee2f12cc9562cbdf363efaf5201b673ad00583ff108aff6b68055
+a5f299452d176eaafb92c84f114c8c22a05ead6564a3371420ea9e646308
+de97d40705e1638df08704fc90249cbc0d2d3e884a4562cc27370b1a9738
+9d8efd237e644a7370b8b38ed1c377f522c75f981d878a5e87101e621df9
+d85c7207bbe5a87ccb607f93a2e52f660e05c83a7a6ce6d01ab4b62a1ef8
+da47cf97d4bba0fa8effa9c0f61a325a97ada69445f23ab1fe27a66c2716
+39f839203040d44b11ecc6e805fbe88843b34c4fd52d1d3c6c70ffed433f
+c04501fc20536abdffa429b8dc8192b2d45dd9d646049cbf40719c3d6747
+73f9676f9fcf32817dcb55402a72c56d74aa4ce4035687c730b6b44a9cc6
+14bca5a3fd17c170ed949e588ee45e89e18b07662a6327fb9e8475c43e5d
+a1b0af07c23774b19c9ef59281f5d884990d6194170d8293a86db52a0fe1
+7e88da82209a00a16bd29b8b2f13fd60aa25fcfa9745f57c8216283c1d6e
+a1c119cb9b8d57c004195210ffbd56395a3ec2d3098ed38f389efc0324fd
+0e55ea339b3892568229d8d3e205a821e8219fcb1a7713fcf3450f8bef97
+6ca0beca47376a8ca73df85b340c67efe4534d459617996526b5e5d3d19e
+17cc5449e5ef2b82b2c4c2131ff8a19fcfe6a186a9840d872d85c40665a7
+a04e67ee26b8bc9206c35b44c8f8a1afc3867d96dc6d48bd45063be25b88
+2e9bc0d0948c18dc870e6925818e1fe17d336217f174eb4481f5c0ed37a3
+beafaf4d46f857811b6728bec461ae6468d87a736572f4ff95b58b04564a
+9d3c22754587df15495a319d822b838461764b73483c1f7cb930eecc6f74
+24841ee10e4087e951202fe88a391375c96bec4480328a54740213f74110
+5b12a39f19808f3823507b88115d468c61b212a8abae7480e39ba52390a1
+892c7ec50271156b4e8076fc3ada222695df372385da7b117a29e04cd2b8
+0a320f186d61c963fbdafe9224e537057c49e82e405196aab621b5fe4011
+e1782a747ef935ed8bb11bda39a141cc0ba42d04ae123383bc95a1d03a85
+a9440010c3b9613064ffeca76197e10919ba5006f35837ed9bcd7de5e6d9
+68aacb6fc91178091fa467ef6fdeb728e17293dc89dde5a5261faa95a2b0
+000fc750e7073900d4d88247da464613adc2b3903a6132d96ac0e1c56438
+5ffbf6249dea76bea2a99160632dd2fc2b99133e9f2f470f72b45d6f18b4
+5020f604b06cd9174ba3805db60eb9c5e6a9c789ace76ae9c79c1bd34434
+e95e501bc968633af93ff4883c6a596776254c0c74993710327086b2886b
+02fd3e42a725a03459cb36ee34a094139af5fcf487d3dfe63fad20bf0dfb
+60deeda2acca3510e963189d1256eabd81253f7ff9d11263fdbc1dcfda3d
+1ea2e52005ce3c605c993231258a717423f64bfeebc34684efa676358b9b
+543c2042bef954829fe3246a879845b30ebacb43d8dd7a20fcfedf763ad2
+c5d20a798b69e08722dce6a5762e249ace3055b650d9e110599ea30de5c4
+fe7200d5a8da9e1fe2686350d0df334877d0b9f6524c552d0b6dffae125e
+c4c18f7547bd51c14288e4abb7f8a1a00458596c390aeee6fa308ac1f788
+fae30d7f8928afc91d4de6352d20b19d8d8ab122b7378cb379c5be7e3ce2
+922fe667ea057b5d7b3f0b51c7bf0c85f87ac2f360d82c38964f4dabcc91
+04b32f0fb8802235e8e8d9a5997d392259074c00af2ce1d2bf7b8e90e2e2
+ac34185c68a03bab8b267778292b227245d7ff8670786e3f746f86b9d4d1
+7190db859a0e144b2a61e6ac9254de5dbaef20e2e9db0b2ff654b996e962
+f55e465dd238bd1643ce59dc2b5a58b1e6e4ae2ddc2d74d79aff3c34e4e5
+93e051fda236b79cc0db268d2a89b1878051223bb8f33ff99ba87a4811c0
+b3bcc01171d0a731eb732ecd8749d27952c27886b252f9c3d190419fd290
+0987a0a255b9753fb7aa70c37462134c467a2c4b7920bed9f9e86f8f98b9
+6d00af8b05a4bd5f14c2a0d914a9a84160d554fd0718f50ecb5df5e76623
+065852daa74c9ad6da07a119df12c3577fe276ae551d48b1c5cd8a50e84d
+ec9cb0840520d78fa7f9a7c2071e28cd20ec7649b991f3818cde295cdb60
+85f24fcf93147e9f4dd084fbd32525326d2ea147ecd5b6c9d9f4a7166663
+ad18bf234e9cb92ff72138a8a49e73e527e9a6488a4ca808aecabc94d693
+cd2c0c357d285f65006fa2f9197f61fbca6ef07b013e2b558ab531d2fd27
+0cee7fa8e467fab885e90c5884843aa08e2bbfea0aa575643727ba18acc4
+99ff34e3438645be2aa71ea491e54687cd305e12bbc94faec848311ae816
+495b013bc5075a2d2ae54a7ad7c9105b64356cb51f18c2c28e3a83b9d81a
+4554dbec9bea9a660cf7e1ba89e6d4dfb3eec6a3de3fcded9b2d614156ed
+ae8cfdad5ff0efee31da3e6a54d94ce9453a1caad9756d91be85315f6514
+bafbc821ee810bb5d8e1b8f05f64f3f72c4b35d424f7e4dc3ab581b74ade
+b6d6297cde7aa8278909f269fed79b7dfd39b1c0338e01d556c4db9ca3a8
+578ace3ec3d743ed4b9c0145e4525e8c315f7a1b98584b975c70f0d41570
+8c8ccc13f848b1d36ac8249b73638f95de0cd27c7efb52bed4339ebda481
+2564d7a77416ddf4cc88cfb52d07a252d89353c6826ca1832a153242979b
+6cee783abde65c8b40cf4ea7b42b8dbcc0e02423dd693108006f6a4aebf0
+53b666c3cb63d1861f86eaacd43bb9bb6f2c3a17293c189331d253b44775
+7ee7cbf4518babb73a1d44874d7f0625e6a013c608e991b4ad17a9adb367
+40d25e3e35b459b422f7370b134cdfff3f3bcc4c32b4e9ebf6a2478013f6
+6933a1fa9403a2f1161ec632f1f04edf95ed0f33dad9665d54dd9db2564e
+51da7b65978cab50d6dc1568976e83b056eb0e3a6758518b6e17e9ebfe49
+b72eb148b472ba144bdc2ac95744c9bf1258f0a2e47470ab0eff90e190a4
+1108914ab8c1ed6b11e0681778521870e80c16af2afc723cad8719adb62d
+3939d3bc8cc1d8a4e07e9d734f54eca33d936d2c39d5c8055739c33e5335
+9bd40e576c11e93b4b4c122bdbc9b1bbf44243af4f0bcdbdfade68c526b5
+cd74e29ce3f70d62ba83c489034111fe8e4daea2f01f9d938abb532deeac
+0e329f42453ff5c15dec2aea8c198323c9e8fea55b3f5dc4751d2e2e16b6
+154e7f2add46860e9ca71dc114c99d80e7ea1dab51e925de161cedd678ee
+6282aff38e3cd0e659549c970613209955a3f581e1abe485e56402a3db0d
+1e9b8a9dfd05c4b0b7f97fc6d0eed0b69ad6f182b1d028add2f24463834b
+13f5c1307f91d363891824e81108e57cfd5211f86400d3e96b107f3b1fe8
+9c4908649d04a46dc3cee0de66af03a7ff9f4dafecdd6df4d93784cc899b
+527784dbe0718050fce185bde3f39debcdd660b2488d23ab1cff87b0546d
+02b48e7b7724c9e87b71bf34b5d6640e0f6ece47b182d41c89461f712849
+c6cfdb7e3f5ebc1acdd12d65a422ba362a8fd6caac5104ccc5ab5fc04a46
+e4309acac83d659ddda256ccddd1bff9ab3622450c4fbc89c82214f00c42
+fb0311bcb1b722a691ed839caf9024fb1671f18e4639c96d84718c663a43
+41dec037175c6bbd288bbf5a0478298ca726567a9b74c32a527339c666a2
+94a17f6821cbf243d13ea4b1603c292953308b566653423e7301a032e5d5
+e2b93f1c1434893633dd19501ad12728b5a1d9d36635b589fa2e151140b5
+43d7c5e469afae8e80c4fc1d9cb6c3823cc1bb7ee40aecb58cbc14657922
+26b19e0fe79235115f6a3afe19f98c5db63d372dd7c041cd940f4f79f247
+4d9ceea0334fa04a97dc9773064895cf11cf73f11b4684f06e48f4469f6a
+1aeb2cbbc52994dfab3319dce3a0c8c2efa9627496f8cc84d3df3bdc4ffc
+b61672780f294f453278aeb9262e66486856d37b7647141a82e049364ed3
+d03f925284a3f1fa3ddf4c0b48b3fe22e7df9aba239d33cd300ffa8fd4b9
+6192bd568fb18d325caa8e1f1fd4b27527417b034841fd49e4a77f217062
+3cc8b22101166d80361eb15fa9020d24f61007b0a8274df9dfcd8e97c855
+68e76d34ad5db1779b02f034a69ccf9d4ebaa188eb3017eef5b22a0a5526
+96a574907f695098bd8a4849d5c8311f129447cd7a3cf88b8191aec0aff3
+0a38a9ab8135608a7829207a7d242f6e1fa7dda19f5e4c28560d42db4405
+77cc0c5f5803eee897103eca0bd944e320ac26553bee7852eaa733bd13df
+760056b2f5bd1243bedabc3c1ea0531017d74b47e18f801a60074d6df849
+fd0532234545e5b5e112d1e7385341d39a89551c80dc2deaed5d5da2a4be
+5015d297324e92be64c68428132e6ec654dd4bdcc6640c68835ff8a05e09
+9604b8cd43d3af2b2fe10c8afedec5a70af8509d12f662338cbf166d9452
+cd36331758ac4f4cbd7edd52139ad27dc52569877fe709f297444c4f3189
+9d1945c81b14abdecbf31dc463a4148f04ec4fb9703c158216c0fbe65ccd
+450043abfd4e65bf8b28cc148252e9f3e797ea0b57b8721c94cbc2ea602d
+f2c57e87938c887a382d2659226463bc7d6a1da87f4a341a59bea458177d
+3f18d1213539dc0e301f6efe0111fcf6921368be17ccbb7428127e0c059c
+2c5adb2a3f0197f0ceab77ff7f3c027a8ec3ee76cf5c986eb47cb60561c7
+73b3a2da47b5a35394e29373dbd5c3ff4c9213a89aed77cc4f3fcfc49ef6
+ec7557c521979a546983c106b3627b5fd2d71cc5f08a32bf49332a89c5da
+71afbfb94c949a91220ab1f885c981423af93f73bc1ca4d92d9dbae3efe6
+a76e2de3d0f74fd3255820636e3f1a6b7c18530623c12af90cdcd2c0a728
+521e9b639eb6345d1de8fffc3b19c72e7a93823dfe3115e9e7bbbeb28cb7
+3db121aed8920d47d8cc08ea2e472e39a4cad5881b5c4204f2b732af9d51
+89d25abf413cc78714cb01b1d8ca5565169a919dc481f6d2e67f1d490aeb
+c5cc62a8f62c1a323ebb55ed35aa5c8d6f8b970e93205c2701cf4817bda9
+94fc16197b469ecc5f5e9ddf0fa05640c2e571849571cbd26402b1eb1e80
+3fcf423345007b9b52b13e3b034e8cb3984b925ebffe719ed4f39f3d0e33
+43316a6fdc26bdbea88c4366d3b2f851d2b244cc4408251ae2c77348cce9
+dd8bb9c89800b572d38c5d1cc34c740beebb5ddb0a8bb251655fb989840d
+23205d16311a9fccf7c85f6dffea9704492a4e7a8f6c0bdc29745aac2abf
+aeba02b0e7aefeb92ba63ab0df844eb09d505c3dfc1058ce42cdd8043b76
+398401e1db862ff9f76c05e8bc6260a4443cf494bc1755913d51745bf45a
+df2f8c7a9546d7ef4fb11e9d94e4539632c2a39606d04480ee459408d7a2
+a869807a4c01881c1bb21c296a402b5e6e07093d833c3dff075f4dd426eb
+87b1b8de16c146de79f52f5943015331eeb852809cbb8e1d6460ac4d176f
+e96f8d19f6ccb22abbbaa27c4497d91312c3cfb5bb913b314e43d2ec6ab6
+897ba7c34cf2caa6db4bd69eb5dfcee0aa917d6950e36a68a4c22a60dcc6
+9379d47544a58d640eb10dfe120fca843b588ca8b94f7869f97609a6fe03
+ac86ec1f7cead2ec8e81977d1b946e459dfcfefe65a7bff67e66f5f78a45
+d8df65af0146df74e024fc042328886cc1dd7779f49cdbb750345cf83cd6
+78a6a8897577299deb38ad665dc4f21ce1892a18c256f318107dd3e9245c
+1ad3bc93cef7b7bf057e33ec9a3f953251261aa3d1a8347261e70a46f777
+3a84f3d4d1a0df6dd22a96429349de0d180310e17955b10fbf53220ef648
+3d03c650a8d5c16d63daf65c21adcd6c2d0b5d4adeb2f5526aacf7cf42f9
+a8bf4832fb2d4f73f3d5ffd984b572232f87bd3e59133ed3d2fa19f7856a
+d812515c74f7d851574019c532c25f8e163e595fc9c83e3e820c3cbf690d
+a62578a980fc0803eb6db9b1e90e3256bd4650816abe5ea86ce65c2eb418
+d0adda5f3ea04e17aa8c4536cc471ac20236e66eca3619f161dfefa48538
+6c30ebb86a7ad930fd0aadf2da69dcaf26c0f677206e2030e3b15b3662c0
+ad03dbc1636ebfad1f2f2c37f5fa9856b0198c5b1d80b69c5effd94ce071
+5135c649c26b9ba1266b0a5b270cd08a706166c0b320915c87b27de21deb
+5d7e4806f6e700b7a06a4e29b629cb40761983e9ca8e34e869abd04dda19
+0bfe5a6ee8b22d7e511b84ea584a84211f27af8918dc5af8a1ff2d360b6b
+e3ca8e66ba4cd2ce6a25e7e89406684da83ffbccccbfd0844fe3becd7de6
+7764c59c022db1168d585fe25073fe00e30218d1dfe115ca1fc606afcb04
+f2a082ef91788b6bd09684dea31f20034a91ab9d971366f97b5009fefbf1
+ef0ad941654081b1e8f0b2ea495069a1ddf11dc56857d29533dc857958b4
+9d1a0779732819fd22e437084bd9f3c4f2cda4d12ca14431937ab63a03f9
+c040af1d801f367abdca7302e18a9050d6026fba5a5a7fad44e31593173c
+df277cd737d1cef59fe9684252bc0ddd00a80e023b88222494c1c8c08842
+30ab11d1083225afdcdbc1e24d4ad5fab396d2e370e44a7571b230660d51
+0a5076d8e35f7db72c0566dfc119ee1b8ac3c0406950a3c4a4da36bde297
+040a27f70753a87e6cd593dc6be9962261a99ae5949340c5d45c94a9aa3d
+d636ce8b497bbb8123457c824f443a53b3ee595c38983fe3e07dbdc6acd5
+5cae8be1081afd4857a5f52a3c925143507a3c37f1992cf72ed0d4c48d94
+ae6caddc3bc87ac3a3ef035e02181f78449e4b063b0835e827644051551c
+1603e2eab5875f28fc77beba6923428d5521c698c6b7f133b0f689f105fd
+bac30a8ed2f29f0255ddf8a037b81f04edf004cbe639c8db0f94d0c5db92
+d34d66c2fed66cf8b895afc4e659d08388ea44eae83ce459e5be306750a6
+82b627802990037157339bf142bcb9c08fafdc3c3fb16dc3544f62c6c7e3
+3e20cc4fc7ca21e2c3f6c546cd78dee348f1a4c8cb548ef20c0496789167
+71d83acc9b7b22784ad8580134471a3c79bc86b5d6d0d305c32e62042743
+51c94f9df45d9b2ad5b5087a89f90d6aa033e4b1d1bed022f36147c7abd2
+b73134dffd50907258e610c3b20949e141172b1c6a76db238c375021cba6
+645cdc26b717428b5a9b4d3f32a4b1e22feff3bb93fd889e1def8087718d
+5e3e650fe4a3330da9c37e9eb499df5a342d8ba4c0a033c3347cb25a31be
+143ecbf91384f2381e323e7fd3a82a3197c189053200ae2c86b9d01ab0b2
+89841ea7e9e9a26966e0def54de0b85d8df084b8c590081e444baf1e1f60
+670fa12ab97159318624f2af1b5ec7dd83c1073a99398d2143a52d10a13c
+201fb356bc9e90c63bb0bc2d4c42af4a8b9c8c4d58a1b32e0597c63b3f8b
+3e893bd3be8c60231838f1bc78e73a6c8cdd5e7f2907f897fc8ee99bffda
+7338bcefb5aef950e5549adfd207aeb15846b509fc57989883642498a381
+1b8e5cde69c05924efaec232fa4cef302ee3251366ecaef57d25cfa3b4a9
+e6397d996f421c900bebcf73b038fe7b16fd0a1172ac2f40d19ce0b02fce
+b8bc47da5344cb933c7fec950184f78acb32d3e5e290e84be753b9e7a7bf
+c4416ccf29d023760c06cddef2505806a65e1508990529245059afd301db
+669d41bd72bf7a80a9df66b876b3553fdf4dd38d15289af7a1afbc53ffff
+135a6348dd784ab42a6c0d6aa330b069607e2df3cbefce79d6f63e274c9e
+73a33eb85246d5ebb986bfa923df68b2b8cf82af6c33e785f35b25b1d1d6
+14de85a4f4510adfe42d75b5fa5408a59abe53859e28b3d000eb9c6a7d2f
+67c91dd14c895ba87b9cb57b851e5193fcc2a443af85fe28df6f39537f23
+a058bcf81dd8c04cb2c25040300f4c55975e856dcb4e21e2b5481bdcc056
+01942fb25bb8a6b6f93e2c2a33cd478b44655657c557ebb080179ee5d98c
+5cebe0b25bfdd952ffeb258014d7a5bc4bca4f1a23bba73c454b12960451
+ce1752401b0151cb2e01d5c72595095eae91d8d3bd55a54a2aea89239fa1
+76fa7cd6f16bb0733ef6ce6e77763a23aac77da88c8efa7bbb2991e472ff
+2075fb25a75acfa70a04c28764f4ae4c12051b25b120cad2e3044da35c1f
+94135dbd69b10de147321cbbdc814ce99982ac1d76ce3d3330e41ab31f3c
+76bf89b95eab81af3464c732d5b1411d97db36c9063537f64756f205b16e
+d7058e2cb1d6946c00a1a0cda9ebbe924bda6c7d7b605c514a98133907b7
+93c74ca858e82da3519188cd974b34daa74265db5bc8550d5f0b1173aceb
+87458bce2ab1f96996c811699a0fe4a9b849d39023725e2b1ee7e426d30a
+6c5c75ae6bcea6db41e4eb2035f7f924e6b9f0dcd00eb2bb014222e55fe3
+87fbf5b9b7c04f4688d5ae3529fdacb38b5eb0af5c3a874c1aa6b17cda8d
+1e22eee05a3da88449200d3d0d002db86f6c51b337c8e19f338e7bfa01e1
+202612d50e210140947d5f350e84f790286c3f679a5d7e43bcdc337265c2
+631527fd62d598b7ca1f5835c0441881b97f5197901ecdc4f195bc665a84
+6823d2e41417373f8639567b228fe7b73d781f07a361aa49c3e9d80fe5b2
+a32c4c1e575d194e841967b08d10405fa44eee2847db9372c5cc931e5046
+9532f1baf577f680bab4e30b7e1cffa8574abb679789f69a8a1bac07b7c6
+4ef5ce5eb00e97b36fbeaca9bba4a13b0293d34bdbc77ad1ff88e5744af0
+09823bc262511c4724dd585e7e17d90f230f7a5861b0dfc42f0b4e49a04e
+e0ee4dadb908479def8372f334c53d2ba5d855cb39dc7c9550f9d0f7f77e
+82d5a59fbbf34bffe92dc9e6668b68feeaa4f20053433d6749162bbac5d0
+d428dcf2d58d49b127fa2e674edc7d3613b1342f4d0abd7f4c5b049fbf78
+e804d5f16505ae7edcbf4d6fa08d72890f5d55199034572ab4b0c9a7e7f6
+f5a403198864adf113caff5bf9d4ab5b16f81d0fc2188fc80875e10034d1
+2e30c0364f8f72797f1aed525a2712a40d44210b813df5a29c84e9f6d51b
+1d60a5f6f938faabf878d29e6ab252d95d05fc1adf5d4ce1c9e585219112
+112bc6cd5c766411fbd22731794b5de0a27ac57d3c57926807469c360372
+be529098c350efe2154b87f1205a57a0b04c5206cc4fa66b8793bbbe492c
+c3271fb4f90a28d0066e0d7f63b8dd01549a05afa5482c29560abd628568
+75cac16100087540162473498c14087b29b86b7bfad693e81765cec781f3
+fc80e9c7b410e9b55b88114191a1703c638dfbb469ed1dd8254b1407003a
+319ce74ad419b077f17047a01f0bc0ac8507191bf72d77d9333c9da8c9da
+733efb5305f49cb8c7bc451321add7d896395d269dcdfdd084eb3aa70338
+6c0697e962929651164135c094d9bb1c9b949d5eebd3bb17f02c98c813cc
+bfb23c2c26218a2f4c639a8b9dff2c29406037f91938a5e1227310728428
+b56f48108cdeb33bd3191eca89f947271983db776b2bc897a30eecf2601e
+e3b2a6f0e135397622aac1f2df523ce6e6bc720e13cb530cef4ab9c8273b
+d3d81563ac8a8e6c44a195112daf824bc7a72fcdc4e129a480717beb0108
+5dee65ee4344d0b41ec0bcdf842566b1d9f5353b1f6a063ffa6cdb06ef63
+4c8bd5a7a63f991d178f56eaca653dd67685ce49e98c7554745a4ac53321
+7662d23e1d6937135d13bc2208eb8d50560a2baac319dfae478b6ba4ca5e
+da20222f0e9bdb0806320ed1665b54a347de0c42e9f77842de4d188e7e82
+4eb2f0d7ad163f05480a7fa99c5a603bbc5dbc843774ca66e889b945054c
+0ed0b1a4bb14324ef901b023c208cb95dfce928489789690cc45bab97be4
+49f8e2f5aa9276c0571303e9788c46e7f789555bfcdc3fa9ed8da8ad9ba4
+8b3ae09404664391e63a989ef1e24bb464043aa099e4f2d796e352eb2771
+06d8d81baf2f8562ef46bcfd1e0047e8018cbd973021dc1c1d821af03f08
+3f0b088a62ebcf2bf6c5b0fcfa441aad1625fdb834f943dd47a5a42eb3e9
+a5b49641f797c288b799a64897f1346070461b6d535e0c4ed099199c387a
+3176aedc7da7e7d9e118e55565092a36f7c74abf281720c0147f4e4f37d4
+9436466c61ff12764e3043d8a6d027e70537164f0e7942f4aca42bb2cb13
+6177ef7197e76f49ab403f741c0ef902febc471ad6c627424320a8c3a1f0
+4c310c511b3f91c3937d9acf459999c18a33f2c852ec38ca806599c728c5
+43714018c65e2c5f430f6270af52ad71ed38813b60440779455f9529a4a1
+623cb9f5422b9216f9cdba913b9a1cd95da225e254e81012160850206605
+09d03a034b5d7e32e3db5e5962a9a27711d4c3e29cd84057f7d0d7e80009
+47afe896f8523253391d2e11fffe523366b05c532d5629a90741eab3d4a7
+31d3f6d4f03ff93233ddf88bb1913aba22eb9aa6311e3144381dae29bcc8
+639958eee59accfa06f35dccc63e0609f542f3ee5dfb1cf718ca3f328455
+726f8f65e23acd970e4049225998371b63e35ae98dc54d8329b8db0901fa
+a63129ede21b158776981d4d094013c096e9cd020315d123c03deba21e97
+e4b584b4bc0af25f5dce53c2dc0f3e61f99becab40799478be7f5afd7f68
+e23ef50ad6645c967ee11206b6e791769428acdc370d64e4f2b3972e0e4f
+442297199350663d6e772fc6777a9b9de215273d082cce4e8678fe9948dc
+8d5b0e459cd02f1645ac5620f3571a40b4d5a17df5cff48b6c843ddeab5e
+bf58fe13d7da08e8aa7902119248b3b151da583101cf80853b0150fe05bd
+edbfb50a7fb0f65728c93b9df48ce8af1df1fac25c1d58e1ad30274a00eb
+54cf2f16029e1ac0a0919c0655474b9a6936aee0fb74bd185fe7d70bb847
+86997d34a40326a74356a4afaee67b6b26d1c1a7bcff8697b55c816ccd77
+312c332a55315dc54f9bc0a0f12500e0a76b3936292a3da2ddf5aa8cbb9b
+5dc32edacc4827d684d274e65b8b76fb2c2b19f7d5607523fa953e34bb39
+032c05b1c1244304606c55660d3ca8607e764ea5b03db7fcab5cf7788c6e
+60ec8c449bcafd90bcaba4132b6cbccff16784fb59b36b77cf0a9ea572e4
+ca0a01c725a6cf2e4500cddf5baccb9094d48925434f044118cfdc2696af
+5fc0cab3884107ed17b9bde0c0104b1292a1f8c99b06fc4a6360b24480bd
+59df0488641899b0f42b1311b582717ba7ecfee14143654b5371c8b9b2d8
+0685ad38d897ad1e64875c28c7020a84fbb3a3bbee16617dcb9bc822b7c5
+9c5a18c0cf7e80163adfb7aa03b7cde8497c1697d90f2ed90f813095c5b9
+1657fc294ef0e341db3392ed860cb2e0aa09293d0f99ae9eb54c761ca2db
+1e51e1ceaeab276c7bd916c68510d72d9a67468b09b3c39a7815628fb126
+cdfd5eff59cc8184c0d35a5b5960f824bd175495dd3eb12a4e96008cb13b
+8c5745303e66cf8608ff27c4709c1d854eb79608e52f068fec0151a74c12
+5edeaea555c198fc08027bbbb802835e1d435077ae4b1ccdbf722354f6c5
+72beb1376d3e342195fa80ac9722eb2f46e44de05f5a227b731b8d4a4b6e
+def04af2c5dec2eef8ff48c5b18710ade3dbfa0c956505b6da9ccb7cbb83
+4db6cc754948855d833670ff0ac42a4773fea8322becee04ca74ac2d6685
+5132d11a51524488c54771b5b7a512796d7d7ae0f9c1fbc9cbdba0831074
+f4d200349d0ca40537b92496692766f020ac43ac01db8b2aa2efa9d21732
+be3a315f6caa402bb2e61d40ddebde11276d90c2c601a935c168be600464
+76aded15087d54a14c68eecbbbb590927c1e10d291c9285334cb0c80edbd
+392bde4d535eb61f8e7641f58ac1df5b1c5a5d91e3e27e05caf7ec97ecf0
+c85b6425197aa856521ed701e5aeb82a7f52a8bd7dc97d5b3fb5c99a5df8
+4d1baff89072922509d76bc6edb15ce5f9eb8f4154bee1e82020240283bd
+c83a8e49aa9a2649b7955d5c058f2818a63bd0bfe7eaced4a49063c489a6
+26277ae1246f721c9926e2a2b6c31045fbcd235f3cc58bc4dd6c57fe998e
+bd1e9fa5154652be3a1685bcd2efaa079a3293f78142a6473822fab62792
+7eaccd61b3e99c3077103d2d19382bc7ee15bad0fde489602d055a01dbbc
+f91a566974559d1b477c209416887053169c3f8f59955be4de82b60558cc
+9ae15602a93f029f6b4329e0e62a03982db32f5229714efa1491a7b24aef
+e18febc2c93dfe50b3f641b51bdd33da38871bf5243c17502d00aea2d9e9
+734e80a96788d4cf5bc12a42bc386162fc88a7435ee13200c1c2c6ccc5d2
+1a03941007b4c4291bdb711446ceaf27148104bb240357d5eda0ea5a5ce2
+7d4a83909d75bfc05d75f10aa74a6de37d7de15c1dda3ac3045da6cd4832
+3d904e716b445e5e096fcb379353ed70cf4b6fac102c762711079efaf13f
+b74c9b47af75f3f6bda2a4647d2ab47ecab64da6cc01479f618e8d2d0a36
+45445e8744683cbbc560d47c98078b84206e90eb839b02d37c852b8e2844
+63d4e4d890203c3d5b20352110034ead6bd7f41456b807e1db1631a9d499
+e52e9d9853d86728b1a2e511f40f8ca1e4724a0d17ecd640b52ff6c66e28
+693d89765fc391612e5889e77423ec85cbd0a038b6ba98b607701dc0c4b6
+6b3b28c7790a1f1eb8d051dc98276dd9cfefab3f65c1c928e48a060c992b
+392a43e56eaa6ded896debce71f8245be4687f2f1b8fc0f43ece8db0bd0a
+b0811c5ce73cbe336023a0d66168b34a95b4b0a750b3bf1d197e3c042c79
+14fa731d7831af798e9429571cbb977e6258244e84701e5ff91d608f98fc
+3d68a4ee5b81d5ff38b6c184f6118b875f022b4ce207dc7b37e1452dfdc5
+91a3e506ae82c7e7bff0011b0a3dbd616a993fbf878fb03b6c9f2055a2b0
+95d29361f8253c2623653687fe0ab98078f6aee5fc2c2bde0405eabedb3a
+33eb7f04cb6837176245f190c6bbbcd64522b12fe7f9cdcf201a1aa8a19a
+7bbc4ac064b4958f44aa0f8dda23835ad28a1fd0ea105de2f395385dccfb
+e2261dc5a89a23af606a3985e5038706b1fe0910400e16bf008f250f3bde
+3ad806c735495d499f16f99275010478fd2127bf7cedd6b5bd505fbe9bd0
+065b4a7090c9d27cd5b36c3ad33e1b31eb6d44e375003b51b909da50bd18
+218418b3cd22b43278b144be78406eaf16c7df6b6c1c6238004aab73736b
+38e168441dc16f9a5cf60793a18633bc43d78674d12d38cc979f7caada6e
+fe807cea499cb9fe616496682a66e04bbdace1dc112b2156b9b0b20a58a8
+cb43ff0eedb99805234b9a5789762ac7d65f5a319c33f4f7438cd15e06bb
+80a7a97e976e8cec23f4c646a5821880a82b2f1dc27767f090997e91488b
+fa15064b702f864fce6505d6cef87d2a0a12b55ba189af269811e3b8b850
+c8401f3906c080d32618d9698a766732a40a9fc5a94e5bdda3d028d823d6
+b603b6d17dd046de181fd989ea0f80b4ca62f7973e4df5e032a31fe6bc8f
+5cda678d4a72787eb8253ea5882c337cdf9aa3e1e7d9536dd09b047cd896
+2e773f72f6418a3aef5a289b3406c152a50ce7bd4b493fffc27f6aa52f79
+ea67e362fd92559aa4f94a2f787f6c735dfadcf2f08aaf98b80c53ca5607
+a94f25f04aa65a70a75937840e73055b3d65fb054c63e2e48e68488c9315
+a13ee949e03e46723c11cc759d222cbfad2e1a87cad779b23d38f7e2f660
+de1388eaf1cf4d18994d75c6cc63f187fdb949940c18b537a0afb12ac5f6
+7b0283ca5efe2e764c4369104b9d3b06490d1244c41d6085c85f1106082e
+c9db84586230511c05c82412d2cdf3dafbf4759a775628878f997415296b
+c416ac8352a6c6988691fcb831cf95c10bae691adb3ba2918b35924bd5c3
+acad8b137397b10af82b479800fe16d472cd0cdbdaab4f882a0649cf5610
+04b8cb7ca32ec129d0a415be6cb91da2b65f44e80d138808a127e851a7fc
+f927e99daa0ea2d626b77a16c72e37f058a3b882fc4955dc8cb6312434bd
+3bced75780b13590bf4fe8d64acf0371f9fb1d361b05025852aab9eda1a0
+c997cfa58052c454fd451e6c1f194f4d363114e312f6dc35bbaf357a32cd
+200a3dd9654155134259887d677acc44f89aa401ca27282df7dc3f2f04a1
+08cbef2558dcce28bac2d87b8d5b7181ea927f61977764f882626d4ab338
+d95c9477c54e9c36012a3cffbe199ec8120a99d2d70a21f9d9a0354e4eac
+7947990e8a6e0601796aaf6f14e758cabcabdfbd8204a8e748a3e5feba57
+0d36e2bf474c0083229a63f96114182321b2ebe1bc76dd193724c4588c1d
+39d184c332faeaf4c629f2b3b2f49996e46aa6c9f497428bea52d58876b0
+dc07b460248bc85cc16773a5dac36cde8b152d96057f4efaaf8b1dc10022
+038577368057699b3a37178a9f1f6c6cc60bae820b7add0717911bd23a6d
+cdadafa32473491aa80cfe90f2a77e24ce2826ff77b18b869c33fa292fe0
+1d6477765044c7d14a548b28b1360125c6933f05c58b0889390537cdd16f
+8e967e0b38579449dfc1e07389b7069aa8594c5103465d5041cc929268de
+863fadb6925b350aa94a27d421fb7fcc81c6b35f906f12246b7a5140511a
+97211ba9bd6831a508e963fe8be961332f557808488f06ead75e86d60de3
+fa2425ae8439ecb9112bc3e4d73747c1c8e87a649919827049832db0bf6d
+a8c85c9a2592ac002809070900ecad52a56f1bfd456afe066509694eac07
+5788456b0b0bdd7c192d321e9fb6aadcaef00f570f22cd4a5322fbce8fa9
+8faeb681940895426270bb4319c11da67d88552a7373398aec5da7c9caa9
+f3b34581c6e968daaab2751cc012199dd897b448986cffbae4d412bf9ecb
+f46742715a9569932516259d3b3a5431cd7028e42fc751c434e2b714c718
+202bf02caf9b8a2075de922322ea7cfa605c8376fa958b8fbe43031e1026
+fbe6126a3775f643ea67ebbd97f239fb3c43552675cd08b19ca5ebf53b40
+d728556b4481c7f73ec71cab0f89e34d60c69b272fadc22e8e7bdc6210db
+09fdd913e209f49fd28e8712b8508904620250746ca3b21b026edae60a28
+22f59e912e626b93e0d2bfb3230dfd0e54e91a1dba25a609b64d41abd897
+a5d21764c351e85f9e87beab9e645149ad32aeebb3b1161032c701647115
+f98c1c2aaece871862d91d321ab90f3e923b1fdee00d927f897aa9812373
+6536e2e0700f10053d7e6c589bf66029d794883eae4c8228941ce96565b5
+0d48887b5314a2e5537959638222a6ca54c77cbabd460dac11b063519ae4
+f50d93de41763ba7cfbf4c7724360e750478eb628921daa065858341958e
+4f3eb5966c6dd77c05eeecdf4b5f6cf19ab507589b4219377959bd258ec9
+21c34fe1db003f7d0fea3e2fd6f5ddb0a2d62ca5a2cd3c7ab457dff25094
+efe04a9e1b9ce7ae3f30026b1cb039228d309a22899f6e9b9bff922e1171
+23347967d7c62c670e2c74579c35989925603022c17b1dce378031abc9b4
+b437c7b6e64620932e93189754c01d4b280b8b08699b2ca953ae4823bb9e
+e34133c5c95b3290e1bf010705ad852c72be87291e1034b09f44a95b6a2f
+83fee8841dcf661770af44d0ac7f9cdb280939fc5d953d525e0b41b7be18
+8d5c794687330cd770d24d9cd53b895a253004e18a31be4e82b384
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
diff --git a/fonts/Makefile b/fonts/Makefile
new file mode 100644
index 000000000..70c759ea1
--- /dev/null
+++ b/fonts/Makefile
@@ -0,0 +1,62 @@
+#
+# "$Id$"
+#
+# Fonts makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+#
+# Font files...
+#
+
+FONTS = Courier Courier-Bold Courier-BoldOblique Courier-Oblique \
+ Symbol
+
+
+#
+# Make everything...
+#
+
+all:
+
+
+#
+# Clean all config and object files...
+#
+
+clean:
+
+
+#
+# Install files...
+#
+
+install:
+ $(INSTALL_DIR) $(DATADIR)/fonts
+ for file in $(FONTS); do \
+ $(INSTALL_DATA) $$file $(DATADIR)/fonts; \
+ done
+
+
+#
+# End of "$Id$".
+#
diff --git a/fonts/Symbol b/fonts/Symbol
new file mode 100644
index 000000000..926391db8
--- /dev/null
+++ b/fonts/Symbol
@@ -0,0 +1,1150 @@
+%!PS-AdobeFont-1.0: Symbol 001.005
+%%CreationDate: Thu Oct 21 1999
+% Copyright URW Software, Copyright 1997 by URW
+% URW Software, Copyright 1997 by URW
+% See the file COPYING (GNU General Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (001.005) readonly def
+/Notice (URW Software, Copyright 1997 by URW. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright URW Software, Copyright 1997 by URW) readonly def
+/FullName (Symbol) readonly def
+/FamilyName (Symbol) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -229 def
+/UnderlineThickness 46 def
+end readonly def
+/FontName /Symbol def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-180 -293 1090 1010} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 32 /space put
+dup 33 /exclam put
+dup 34 /universal put
+dup 35 /numbersign put
+dup 36 /existential put
+dup 37 /percent put
+dup 38 /ampersand put
+dup 39 /suchthat put
+dup 40 /parenleft put
+dup 41 /parenright put
+dup 42 /asteriskmath put
+dup 43 /plus put
+dup 44 /comma put
+dup 45 /minus put
+dup 46 /period put
+dup 47 /slash put
+dup 48 /zero put
+dup 49 /one put
+dup 50 /two put
+dup 51 /three put
+dup 52 /four put
+dup 53 /five put
+dup 54 /six put
+dup 55 /seven put
+dup 56 /eight put
+dup 57 /nine put
+dup 58 /colon put
+dup 59 /semicolon put
+dup 60 /less put
+dup 61 /equal put
+dup 62 /greater put
+dup 63 /question put
+dup 64 /congruent put
+dup 65 /Alpha put
+dup 66 /Beta put
+dup 67 /Chi put
+dup 68 /Delta put
+dup 69 /Epsilon put
+dup 70 /Phi put
+dup 71 /Gamma put
+dup 72 /Eta put
+dup 73 /Iota put
+dup 74 /theta1 put
+dup 75 /Kappa put
+dup 76 /Lambda put
+dup 77 /Mu put
+dup 78 /Nu put
+dup 79 /Omicron put
+dup 80 /Pi put
+dup 81 /Theta put
+dup 82 /Rho put
+dup 83 /Sigma put
+dup 84 /Tau put
+dup 85 /Upsilon put
+dup 86 /sigma1 put
+dup 87 /Omega put
+dup 88 /Xi put
+dup 89 /Psi put
+dup 90 /Zeta put
+dup 91 /bracketleft put
+dup 92 /therefore put
+dup 93 /bracketright put
+dup 94 /perpendicular put
+dup 95 /underscore put
+dup 96 /radicalex put
+dup 97 /alpha put
+dup 98 /beta put
+dup 99 /chi put
+dup 100 /delta put
+dup 101 /epsilon put
+dup 102 /phi put
+dup 103 /gamma put
+dup 104 /eta put
+dup 105 /iota put
+dup 106 /phi1 put
+dup 107 /kappa put
+dup 108 /lambda put
+dup 109 /mu put
+dup 110 /nu put
+dup 111 /omicron put
+dup 112 /pi put
+dup 113 /theta put
+dup 114 /rho put
+dup 115 /sigma put
+dup 116 /tau put
+dup 117 /upsilon put
+dup 118 /omega1 put
+dup 119 /omega put
+dup 120 /xi put
+dup 121 /psi put
+dup 122 /zeta put
+dup 123 /braceleft put
+dup 124 /bar put
+dup 125 /braceright put
+dup 126 /similar put
+dup 161 /Upsilon1 put
+dup 160 /Euro put
+dup 162 /minute put
+dup 163 /lessequal put
+dup 164 /fraction put
+dup 165 /infinity put
+dup 166 /florin put
+dup 167 /club put
+dup 168 /diamond put
+dup 169 /heart put
+dup 170 /spade put
+dup 171 /arrowboth put
+dup 172 /arrowleft put
+dup 173 /arrowup put
+dup 174 /arrowright put
+dup 175 /arrowdown put
+dup 176 /degree put
+dup 177 /plusminus put
+dup 178 /second put
+dup 179 /greaterequal put
+dup 180 /multiply put
+dup 181 /proportional put
+dup 182 /partialdiff put
+dup 183 /bullet put
+dup 184 /divide put
+dup 185 /notequal put
+dup 186 /equivalence put
+dup 187 /approxequal put
+dup 188 /ellipsis put
+dup 189 /arrowvertex put
+dup 190 /arrowhorizex put
+dup 191 /carriagereturn put
+dup 192 /aleph put
+dup 193 /Ifraktur put
+dup 194 /Rfraktur put
+dup 195 /weierstrass put
+dup 196 /circlemultiply put
+dup 197 /circleplus put
+dup 198 /emptyset put
+dup 199 /intersection put
+dup 200 /union put
+dup 201 /propersuperset put
+dup 202 /reflexsuperset put
+dup 203 /notsubset put
+dup 204 /propersubset put
+dup 205 /reflexsubset put
+dup 206 /element put
+dup 207 /notelement put
+dup 208 /angle put
+dup 209 /gradient put
+dup 210 /registerserif put
+dup 211 /copyrightserif put
+dup 212 /trademarkserif put
+dup 213 /product put
+dup 214 /radical put
+dup 215 /dotmath put
+dup 216 /logicalnot put
+dup 217 /logicaland put
+dup 218 /logicalor put
+dup 219 /arrowdblboth put
+dup 220 /arrowdblleft put
+dup 221 /arrowdblup put
+dup 222 /arrowdblright put
+dup 223 /arrowdbldown put
+dup 224 /lozenge put
+dup 225 /angleleft put
+dup 226 /registersans put
+dup 227 /copyrightsans put
+dup 228 /trademarksans put
+dup 229 /summation put
+dup 230 /parenlefttp put
+dup 231 /parenleftex put
+dup 232 /parenleftbt put
+dup 233 /bracketlefttp put
+dup 234 /bracketleftex put
+dup 235 /bracketleftbt put
+dup 236 /bracelefttp put
+dup 237 /braceleftmid put
+dup 238 /braceleftbt put
+dup 239 /braceex put
+dup 241 /angleright put
+dup 242 /integral put
+dup 243 /integraltp put
+dup 244 /integralex put
+dup 245 /integralbt put
+dup 246 /parenrighttp put
+dup 247 /parenrightex put
+dup 248 /parenrightbt put
+dup 249 /bracketrighttp put
+dup 250 /bracketrightex put
+dup 251 /bracketrightbt put
+dup 252 /bracerighttp put
+dup 253 /bracerightmid put
+dup 254 /bracerightbt put
+readonly def
+/UniqueID 5021339 def
+currentdict end
+currentfile eexec
+e98d09d760a3c22cf119f9dc699a22c35b5b35ed6aa23593c76d54cabb5e
+942bf7d6dd84f1664b89699c74b472de9f8e6df925f6c4f204e9f1c639b4
+dba988ed2ac419ff2b2bde605b8ee3264edd66412d4f21c64ac522bdfc7c
+5502f9c3f3e5592b3b2093d33c9bfaedd2d49e89aabaa832e23f062e91a2
+5032519d1868816e44b4e0747795003d7930299d6e1e2a5bfe0d595dc97e
+140989ce81d8d7f852ff9cdc7a1b1b598c69131dee005b415805a16d8a13
+e5927617ae7f247a71ce0c7d56afd75d85ed2d9f20ff9a6c38e8d5205197
+d08780180cca9c35522b1609b501724d4d6400169b91bceb6a4de00afc78
+1cf8873012b3117d22a18587895543dbc2a1ffc7752376decd4c92a69122
+4258e8f8f113f2a5cb3d8da10fe823c6656a8800cbc7ffd018a28ac2885f
+35e22ef9fb549b00e23d31bba304dd9c28df02a8c370ce49c58a40c9f673
+ad61f5abee9d62ebac590b5a44f2babd96e137464db066b602a5d8d43ed0
+41b780f0fb98f9952f20ad8084199adfee9ecb193c018772e63a5a83bb06
+00962fe724f63351b4b7a16412743ad14a38418877768af423e3348d48ed
+773c2e87624cfef777a15b6872f54488e42c4849ae6d54cb857dc0972e1b
+57c88f40b89928ea43c18dbc73182f69b52f0bd66b7133881676616ab669
+723240f17d5eaaa27c8e295862288dc30918d00008c9592a51f39e30ddc4
+62f6287654eccc13fb9525f6eac5709e952fb237e8cb0870cac5ddc13da5
+8dbd060d3193fc92e6c4cef3bcfd81ce6b3679bfc5855796cdfa8a26d63a
+659a2ff7a1a7e318a7f76ff80e846a2d647d38e827ffaf54bd5a9221eeb4
+16a475eabf4ef0409b3cc15077e01f742c46ed43ca72924c32e48a786224
+63396680cac363406c524a9b3b768cd5a6892643f78b7cd65c610ebfebd1
+058dfeea67d8a9b9afd9bf39033a56856537c06f75bab0a47079dff64cf7
+343cd6e7fe7bb1fbcee32749c91435cb86f7550d505c81deffbe1e3a1f63
+04dd03cd20842b335d7fce6eb31f175724d51c184800c3756db044e2fe04
+bf53e995fb425aac96fcef384c930334b5f384536cb3abd98447844babf0
+4ca767edb70786132c796cc2f6530852275ab4df0c8b4d2eae01380ed24e
+62f5a85dc8345d556c67f00f622d32dd66fe18219169daca3744a819cfac
+c305fca9471a0de5936e270e3b2d4e1211d9da8de26e790c6f56c2ce8b19
+e175256e8bf85b8e52db7da8c44fe52e57af48de9b771658139b6b81b360
+92ece2b629c0f64d31d62dc7d422c2a204bc0414cc6f78f4e975bf8f27a1
+7cc3b35b31ed313b5274f487a92ebb33b02af472ebd84c4b1b4006e5c522
+8a6f7222dab490259de2223f4cbcdd006a6549f08085eaeae51e4d7b08ac
+c8b08e8f98dbf79ed4220132a755c007366600fc27e0badd73c875074b6f
+211da05ff1454730f3ddfe96d36ca12f8249cbe74c82a940f1d60205cd96
+24aeb7824d5b0a1578eb3fd45ffdb97e66bf0faa27bc25e631c20674e7d6
+db5e4cc7b10f3a77731aa3a53a187e5211da39f2e97c0236e36f8714c49d
+630e6e1fb42206cad9361794a9e002369ccc6587f9a4cbce5cfde26656dd
+8a36663ca82efc1e93cc58863e3a290090906220923f544e8ca05e5c8377
+24afc674e6008278fcc696462cd7986aa3b884ed5c17f9d035b9a1a169d9
+f8f28875f7e5d7bab34668b61d026f77e37277d53e9e0467152f6ac7ab56
+ae9206f15177732ead7b2a003799862772b241d65818c0d2d6c53fd0945c
+aa1719db446f7ce5c383f28bb1f419f023f3def204e895b8057407648efe
+1973dc8f7b8c17abaa1716ab69f3bf0575f564c3400fb55bc430f455b266
+871e7569c39a81bdb082fa5134239272f9d69d2f5be493292555a5115a0d
+bdf30da71bdda418cd5875bf2c0ccf00e236f2c97056b102e8e014c2c118
+a76cf79c10fe2921d32022b8f96443bfa1b34189e5c5abcfec51ad20cc45
+08ac5376690bcfe01dc8f924fa190a6f1295c15c74ddad5e9c4047ad0145
+76858a265ffce0be9e77e763e911bb662359df98dd767367dae1b686eede
+cae1f0c9cbc54bc4cd46e51471256bd340b338c38dcbd6d327fe6d2348b4
+eb2a1c95bf082f2e4a1bdadbe349fb331ae9ea002c602097746265455a5c
+60a7c0bbd2f407c8a7e5fe9fbea4bd8ec9962542e2e3021a0ca40f3b3ffd
+b790592167afb21dbbb9eca9012d06086f1de6749ff3c63be36e0a55a9a1
+03406d8ccc095975872fe895b8c43a2a445afa5e03c7902489d4f4c4a9ac
+829121e532c6604c059c355652fc9c2f16a553d5368ba0752dfdca4c0e9b
+944bd1c2d115c25e4421ebe412b171290ab0d0e5b0b2c42bbe58a4eb39ea
+61c710496dd8a4f0de76759f5d55f557224a4b9549cea21b8fe277fc5848
+8fc369d9c0f1a3dc52b8542125bb42561b594bdf33be43aef93f00ee5c60
+274affc05484b0011d8c465f56bb9d04feb88b6de54fc2104b07dc5ec8cd
+419d9f597e5f4ddfc0bbb0e920629fdf06492bec78c970c1e6653d4bbf92
+d3f1cabdc4fbae380b22f1db6e8aa9b050e33a384d5cad9543a3adbf91a4
+a94059705d20d906fc7ceb2577ca5004339ecbd2a3679f29eb43c89247fa
+11350bad35ebc938bbd745f774727de92eb78bfcbdb109c54022ad09c21e
+85600dcb70cb1b51aeeab9cce57b8b14c54eeb1e956a8c39617472165808
+22c531bea4051318283a3cf1f612360b4d3ed785ec76c59ea475c15b15e9
+e19314bfc6a12892491cd9d7cb3afd9020bd28b685129ef9e2c151c59599
+f1e8e13eea8fb5746cce8ae317691a28d263c77714e5f401f9edaef085b7
+2a86a9cf5dfd56739e3bfcab4929679ef111d23378a443440cf9523d3bf2
+3f9bdcdcd7f2c40d75099f3777e66f6e3f1ae4def3d5b062ffbb2fbda4b9
+38f80f74b6be3032bba77f99501878567f48a64eb09f1684f095f8b4e407
+a78c964825abdb71faadb42aab7c41e146ffd21ac742574049dca257e9f3
+d4ce46d200f776ed7915eea1915e321177963dedb2a24c8701d70a265856
+8cf1313fdc4166e6ea59a4bd300930911c13b7bf4e72012fc99cccda3b8c
+6d07febf15c0a15c01b220a6dfbb1d80ceed73812be525e5b7b35bad9b67
+72c6673ca1f580fff16f3c96b9b9b7f041aed50cdfcf7246db20787436c9
+e2b8706d38591372badac219b83ddb3bfa1af853aa3a7da41b16bdf5e42c
+8277c2cc73c1c9f668931e66ad5523d435dbe68071d056cb8fe1de179c52
+44cc511d40bba8311d976a2120a6c46e85b939291f60394c911e30a214ad
+03bfe58a03e92fc67bfe81b828028e263650d27b064558e3eb72f01b40ca
+4cf029b6f1c1843193fb23721f1f6f19922f821c28ecd4340f10e96eb38b
+788c589cb8815bb708b0c46c378e8c16eacc72ccf9ca0b9ebdb0b4906af5
+8fc5cb8e7d62191f1c11943bb76d82251258c4b251aa9561d42adcf0a5f9
+18491e063b6a88cdf4e0c8d41c968d57c6e3fbcd6bc618d139a687303ee1
+2a6b31bbf23a04f19590540468bb12bc46c3e69f4bab7d195a1fe7db4098
+09f5a6b0178a77a4792f69c23489f5034379b4a7668cc1c9369a36f8951b
+e8c85e23d2e47dedf3718c0a2adf816acbfbda1d46ae86293448abc732db
+99c17a6e747dfe204cb1161c9430ada3787bdb924556234f9e2cfae7571f
+9542fc06c7b7cc06f630d43c04a454c2dbd1b23549311b03d8bace01fead
+8e0f4967f514ad83472957cb2fd7661bd18215af416609669e878c72e1b8
+f692c44911958cb98bcac7c3087956e5369e6f41f1603ed496f4766fd351
+7e88680d37104f5455d00b7769aa1eb0497d65b9c53952b4ceca60add156
+d91f86c60c6e683de2d67fd900e00aff558004a66e12a9c1b94b2eac6162
+c89610943e65de52fc63a8ff04c6e0b80cbfe53e15f94647c5ea40ecc42a
+6bdbbe981cc27fed8df21369c37012087ce77408b77866ecb381f0a1dd65
+1772728b8e07728bc82ad72225c94c86b2451d891c1e1bf843067d38ec94
+23a269daaa3d71eba07fb7f5982bd73ccf01c615ce12b396f656d86e0e4c
+62bff0305566cbc839b1843046cae4b57993f86cb5d5ee8a5381c33f136e
+01b779492e3d0c86787943046324887eb4e927307678f2c8c8af15d5af78
+7584254e99baf1e3345d89eeca11846cccd62bf08b6c3937f7a3d816ca6e
+d30c71999a392d34f04e502e01934f2df047410e72b50a53f11079103502
+080e75e0314bddaa9640887fd0b2d248b73e8ea80bd8cf69627f0d345a73
+791f257bb59b3b0a76243bb06bd0b1fca3448ef08f012fe7d6960d592923
+b13a6962b0ebeff6ee814b6cb369cad2399a3b3e39ad7f0dd9c32fc7eaab
+819eecc9b3fd971231a833d00bcf78ce224933c40f1fd31ab11d89932ed5
+6046d87bebeb0d04dfaba88f20070745a4fa25cdc7f482f6a29e32d5cfcd
+50fce23a1281cc914d9d2fa2d62114e00293e2e74e25e99ce2db0696de78
+b67bcb47ae793721e6958c6da47368536a5c9f9fbc134ddd4d08bf5c0b2d
+3bb4f863eb2c0e88e8699645a41ade9ce5bfc877d7c3c7bcab236fb508e5
+c8fb6a1c33179670e294a7a068199581965c0ffd8b1121f4632088bc9693
+14d1319246e8c9e4564bc6bbb723698edd949d12560b33f770fbecbea8c2
+3beddd57e08c9165420caf1b354852b07b6af70f0352ffbcc71c9172d62d
+85c67bcd90cbd733491ecf747cca756250fe5093a9b8457f0fab6fb3f365
+cd1640e30073d6f3596f896e55d1c0639573284be2be1ca00db036d4d055
+274e620ec875c5d16f2689b20865bae0f14b1453cffefcac59fe0f76be88
+d16d5faf229149767916eee5d37e4b2b060a3a3735fcbd078705fce3e795
+443568c6b74b1ed8f40c7126610bea528083349c2bb60ad9c15edcd2588c
+09c71e5399c0df7ee8e51c4bf67891ee652533564d7e5af2d8910a9879dc
+a382ee62378e2a3c7edf7437b5f639b633ffd5afd3455a7b1da9c4c7fe0c
+03ca927bc933d8821e2f9b7962b8e775717629e24bc980be517eabee67ce
+87203d0423e856f10e4a5b7016952f6928a1d3080aac0e25630b19abd7b4
+bbbe3ec959d60343ff4df715455ea45b5fe5a6e3fcc77ea118037919b2a2
+b1deda705afd532431be9ad75309ecf826af7d63eda6c1434b06bc5e9acb
+43ee209e7b6bc20167028ca785d393ba779ce7a174a8988c2f7623ccf2ce
+9ac3c8982c865120740bd7494ccae328bb37aa4873ffd99c46d20059c1c5
+bcb9aca5e0fa9e1200d12545df876c580e1ecd188295a790e039729ef939
+2117044e157051ce87ef3fe59bfff2557c7138d4c630680f93f31dc51b87
+cd7fd8d2142e16b89b3abffda36ef051b5643c4f533eeb1f8ac18df70072
+9300d3fa5abef49b53a887fadb0dcd5b3e0b22d988c2d607dd2c9f5106f8
+3a521e755684abf21960a0f9033066d573df043adf95f7c8e9f822cb1fbd
+5eed34d0550f44fabf736a5e6338ab99cd0ced9c8a27090c85b498199c3e
+b567f2e92567fe87b20899a3b6843d71d43b28b1c20de059c102c0580254
+642f24efd11ec8ac2819ddabf1ad4b1cd9afe92cc0e46e194865b980b28c
+d543df06ac23efc9c64cbee9d921c29c696f47bd8e700b6d7c1d052e75f7
+597c5d513c76ee9fde2951cd86703ff6824d2f42d4837893d2bf82349260
+038d21e9e0fa96ebeec822f6e91ec01f214aa9d1b83f0b732cee3974019f
+feee359a25bd36b0b8e8250dbe1935bc0ce2c33bbcc6d1e7023630c885ae
+fa7a770fd3b1992ecd9aad06a13dc58f18fe545671e54c71b8f5e66d076d
+1901ac6bf8e874ca84054815a145a7bceff0787367b58c668e22028216f6
+27267f83f279656f6b4fdd61fb071241cc883b0060fb9b8d74313be9c271
+fa13ea9640adc53564f2d2a85e4d1799b2e5d04b67f13a30914bca5597a7
+2d1456eb9f228f56ea95d1abdf5b4332df7892b23c571be72ce474a56854
+88e3b3eb489b6de3f5e3fd5435e3cc6bce8071126261d2b9255417a050cf
+5a286bdac485a678009cb3f7b4be9a245270c08f92f339b57fa9cc899b8a
+df5f73361198781480c3b4d6a2d8c65a60749a47cff15e761a0352c5ab72
+d1df98ef57cae899dfa9d8cc7fdf02c4fa66fb90a68b8569c277d99376ba
+317c9e6e59d7971b3fe53daefb91fd05e32fdd517b0b22a636524b4bc23d
+7464bbfa592b4385d006a495c0f74684fab0d2aa4046b8721cf503e16e6c
+6a65b54d929212a796134ac6ebe6283b722286b8cd869c99a5b7f9b3506e
+ad333ebf2e6b9c97f15f0cb8046f0980b0796857621626ebc802d5f3198e
+d91ec321522d6fa84fc3bc752f6a6f47fc2c051ad193ad4e406ca0150a9a
+77de9371f832d3aca7a84ca8c3f7d97dc5e9485c4f2a77ef071919cc90be
+7fe13618a4a9bd73870a968cb8ba24688708f485c15872888220e73aa662
+368f410ef76b34655663c54aaefee827b7c553abc82543fa8e8dde1323c6
+040fb8f24fc213a188f1949a4701b73c0464ad9657a7535440307897d816
+b3e4b6daca7684f92a4b74262d772969dee711e4ed9ee115fb7f91bd9d1a
+3d40325f135b2e037350a36b43cf5a4cadea68aca368f99278fa5ecdff0d
+10ed1517489c3e59568cf5676015d06d296e7a26013d1282b0be1aed1e1b
+0b72a9bdf8e8d7bcc14633875c07cf5cca202965c0ab8dcf250c33990073
+26ca40b0e3b45a9f82e601b0f69d362cc9352defafb017f76710f829dee9
+f4badfcf550c83868b5100ac893517a84e0dd8ca2c0dbf356e0a7a533080
+ed1b39de69d1a31f0d2fc4d80cf09e75a82401b9e205953571c2988cc68a
+e61e0c986e7631b822ff448098f015a925fa9589d4da4f0b47413218a6c4
+542d45ae8f328318eb676944d9cd0611263ce4f1bec8470d1b8646de66d3
+51646200b5a3e8c7a76940544cffcd6fdc9824275ba4095ef08f5b43cf24
+db7d8b1a0b196e255bd6098dbc3f9859d49a159c692284b52eded6320230
+6487c99740dee252eeb2ce6a53479eaf7fcd6057346b6a83ad3578e65218
+ee3bfa52f9fd7052dbb3b3f841887cab19395f64779f64d3f9b4a3fe3947
+b6a501b68bc288c6ef892f34f8e20a94605b6c42df84d61edcd000dbab26
+f4a1e7bb2da0a926ba762b2112bc10921b387e100d9db20905e27d47f0db
+3c7cc67f29e4efeb6f179f144b83ae9493f724ab589e94bffbdcda86fe2b
+b33e6158bf1547321015d46e1667a22fcc7c56d3c60ca255105cec8b03e8
+8bfa66950424e879d6db2c4ffd9d6df35ab3ecc8d5da69916784e274bd3f
+c32077d6636ed73403105506fe86c7393d6da5c0f43a8847efd46d2999c2
+a662b2caee14ad13e48f1487f534b666bd3882d5ad91ded50023840c3137
+5ee1bfb540190f11c953c3c86c0f66139e57ec50aad8fe9b0aa154250f73
+c0e12b85b42b52f46b7dc85ec0610ccdd08c2f3f7a535fd609897e472be4
+a4228e451693921ed1f6fd9bfdab638da15123f3552dc8be0530c8a76e85
+f59e13d95b5ae41d3171f8c3aa8dad0a02c3749e2090c6a795d53605340c
+4e9b596818aab10ca126e84f9023c81bf23cc73f61ddc66199e562780ade
+bd2e903547098a5915fc7268198af301c501d59b90f5bc507da3b2fae272
+8746cbc4ecdadf62aeb3ff1952d7d9f1042ac5448a77f360b34da1e782f3
+f10194b3d43436b4117694575f7611d1e3427f7f7814d94af7f5c1fe268a
+fd82c2e7e9e3f6e0b8b5fd827db4e7b47e131793c6e29b33c9b0857435e4
+d57f515ebc299023a438e174150403c894aef50c25ac5aaf7f872055faf3
+c1ed0144a6c1028e252c3af250a181bec8730283a087845eb774d9d64fb8
+e73b3770b41e7505e4a502ff355e3f7582f329702508549d5e0751124455
+8145d9c457df485615592593827f8e16e0c392019e9bb9afa29d2ec37e28
+f55f1d812d3f552dd43e9a707fb23652e944967b3da009453d8418c0d709
+021b3d6036133611532664e92eb7cc78a0aaea7ec83ed8353551b6d7ed45
+71e466e55c00da0929645b998c12f2969d76a27d56ee94d981feec5b957a
+0ca637a04a3f0ae1bef57d8a83d1a1593fe04da296482291409185f0e2ae
+09fe4c2439e2f4579f54c784c5a53d3897b6af8b095b9a98054bf89febaf
+16c481f356753c8bb80195bd24445a802a0517ae0944eec6307996f8381b
+2d974d7965e3f3e92296be91de6c548630e726236c658d9861cab98b2572
+79432fa474854f9216ec7b6d27a1321a7b670ade7265c10b6aa509bfd3ad
+fa44cc3a1d33dc82dc4c1b139d95ddd7a2316bfa26c608b40a36ba9bf92f
+441ebbc83a5d0b4627c568f65d5c05372841627a8d8e3059d8737519935c
+2215be69d4c5f60d4dff230a09e72431c1f0ac9885920574775a1224c3c5
+59b0f340085302d07ad4016200443b3bb065cb076e898381faf87af0ab61
+1a55a41b92ed6d9510951751c0ed0bcfbceea792ff6b87979489791dc83b
+88e74770c07df34e782bbd14377b0399025b011c7db92ca2db7d08099a68
+e395e9f282f8d7169e4138dce2824e053ee76f6de8b58296ba38b0d9d273
+e3a4616f60f291dbf4346848e7dc0af3b63a76d83f06abcf2175550a55b6
+cb4a3168f0d33fae389e0484ee677bdde16c106f39bffb37f90d8912ab66
+74a631a3e12efb2e0391bce42a1db09812dbd0fb0bb01abb134ebd0b6eca
+134a7ea7e0ee66f809c46e5fadb70085d7f0c8f7d78fa864f241ea501bdc
+dfb8fb1d2496d96ac23337156cb63f9921bf84b06a7f9de424edb09070d0
+9efcfcd32a7061c990bfa088174ec45a0f4a385803c664c22eab041b71cc
+959d9f3cf8fcb27e6be9d7e13618482c30de5425382fb964a3bd82e7426a
+8ca0ac81a8c09b6c0b416f33c54a45c4f57bbf1026a12c5baa1a5540e7db
+5e954ee101c36a703623a7290ce302753ec158b65f810f7c46c55c7f9f12
+7aa3945fe2a320a6aa49323125c85e174a828c559783107edd7e3967bb1f
+5c6163b9a15b8c9d2be84419fd9c0f36018bde462b7bee204af15eaee3e4
+f5fe39a269742ba5398bc6dcdbacfd346699a28b8d708e8b09ef00c4ffe6
+fc8be121ce97ae6d92b042895344492ad9a66932913563025c0beb65ca34
+3fbcdd121e126c49692d52ab4bcb715f52db80680c0f55a2201b22c2f263
+d38a89cc8981c56bcdb245805347a797d0d71e02a11b8238fbc242456250
+01ec6890cfb1a0939937aab82ff635de52e47d62cbb38d4c89523556125d
+761efbee56916f2ed351a8c8bedeb375b400a5499ef7cc7db0d9d7f60647
+c3416ce1d505293ec1289cc0181479b28a71acccd35d1c497f628443fd33
+291a48f7afa1d6a675ae2baac9fbc4a189fc04a4420b91e3d51ed1ba42c2
+aca67cddab41638c82236f66a8f2cef2c66a33d54253b5609989168e1cb5
+e92e9a46256a87104f0fa8390dbbfb8148d7f900b9634a3e67b0f761bff5
+f4160b2db21528d0a4d55874eea9f015d952cb8ff88f3afe834fc1ea1de2
+73b9c0048e45e3e2aa57e4c092618b50b3c1f51521d03e9ba74389ab4613
+b0337d2c74785f28eee574f18178c167e6a3b5a5f6613fbe58b584a35322
+2458b6e54ac8aa08f31ab0761e1567265fff40cb3e750963f8179d495c22
+6284125367d1ac5d188f5ca6a9fe0f25125f30353df54e96e1f6c511c938
+e100be0c1b4ae68d4e3333794f0bc95d9ae9bb517e0d183cfe88e0483bca
+95780fb6437cd3c2bc3af965bc6bc58d845d3046ce5d12ec9285c1fdde31
+4660a960af7e4a7f07f90f950f06c77be9f26fa91f14fac8dd904eae790e
+d216e7cc22ff475f8f462e1a46bcda71a9d65d07dedc038d00f493b3886f
+674983dcfdd7d760fbde7baacd78ac12f18def55886938f88b99ad4fc8a4
+20cbd6003615d4e31ff2942b35f72c1a1fb13c2b22625273f715e5d89a4d
+fe43e2047562f77e9c8e5c2929bdc7674ee9beaa8c7ce8021d28492d5c54
+768c002a366a862bba99390be487e4781513b80a7bcd5d47dc23541c9a55
+b9455c53e9325d0d77fb0390cd7e12ce2e4e34581a4ab524a6a91fd3bdb9
+e07953447116c7e4f429a99ff6c4c11b1ced99e51127c30904bdf3ed12d7
+261c31aa4833ac725f5597b3c1170a4892c3ccc765f02129442d491b1227
+0413a46c92c9b83d41eadb08c78037a1c8630599695f00bd7c8b29841540
+3aec630237432f7e6f753851cb3588e229ac8a0ee375d815ac0c02250061
+09bdf8e0b496dedd2aa9cfaa16286a4662e256778b125cb4db05d252aa66
+dada5d161ef6a5971e9ed85c913d1befa7d862aab7e16bc95e03956460e1
+f55aa7594800600d5f0d1433ee8f0f0be4cec403cfedca52734645826eb6
+961af0c4e1dffa69f1930e19681539960eb58bc386fe31f266f5e10b13be
+4d4f46a29ba95403e705ca8dbcdcc03c273509d9a8bded6e6118daf7fbc3
+63c7e784f8306f8eeb7749cc6d855ed29f99c7ea8b43378c12738fb813fb
+825cdead8a664e1fadf11f7ab84fa7e4257bd1ef7fcbc31e2da8a8582f43
+be6ae0fca66760484c5122cb38176951449919341a9eb60093edceea347f
+f83a16278c37a9ff38202b27a4f75c066fe443a241b630149c585750e2d8
+15f627a1254276dbeae8182270f2699ac1e78c6a09767e296a646e5eded4
+843d2eb8a68673ac5b81e06510db64872547a92a4bc851e768f43da053a6
+bb3be89cbef166e8a3419eede1b97df88a698c0f5f864d81b5c4f7ad97eb
+f78b4ee82ccd71a34c398dd3f74609c555b7653ce27e78be0de7caa11de7
+8fcac0e0293101a2a8c5545941291c56d4957fcd65e36ccc57c8c9dccc07
+407a11f5c9cb214ff508a5f617ff24f0b617004d6787eaca97296108b8b0
+0276f3b7e28af1db998c36ef517c38d96dbcaf33deb899a344a6c047cdd2
+662a02b94f39ac528a21ffaafe364770bcfb995f62eb0c6d076f12241f72
+e4b284f085a3c6fe9263f879af8c049979f51ebf49314dd0331e935f94f2
+a58a107906c2265e3bd6d644ea75c928ee81268e7db0d2b61775cbdcfce7
+43ef1ae9784c4a9b2d4eb0d5bc2651d79f108306722670399d2a90e45364
+67c00de86ff4a4f4a51176ed721ea3a1c72cee354c54f62db4982a566307
+cfd320d6245bc3108a054f44b3f4f61fde2c84ab416d1816454430b6468c
+57d86c155218c6f05fae1fe22a7da461e960c210ec6e44bd7fea797c1cc6
+b63f5f93e75bf6ce42dd559eb1e97a8cd01daad4e9af2a544896f6e597ed
+16d6847e48539d0fe0c1df99298630ec2b465dd037ca7617ead304993972
+4bb3d428e9137dda6709dde2e72e16c80cc960cb85f1727bf30845fa51fc
+a8d52b6099a65a0cdd444daa35534782ae347cfa7d849ad3a93749db9041
+03e597f6dd56e032025f59f7b724d1c947358099ff3b336e6d688b72bd11
+5b86d6d0c54dd457b7bce443524cb0718a82d6661fbb05673b86a3ef66d1
+981788039a1e26597f2f6c51d055b1de1d32145d39b244c91eb3efd23c3d
+4b785b96296acb8ce21882b4814ca4d25ed88a3b6729890cca8843c1e2f7
+46289b4e3bf5196e268c5c08e52670e875aeed4e9cef6f45a70d6f944aa9
+518c2ec860d163131b66e61be344aafa0fcd4b5af24830da2e9811c4024c
+b807af29ce56a577666bb8a6ae62dd780f3ed028352dee9b6aef748349f0
+71f151b9b33a5c707d690cacacdc1fbc8eaab920d11c4ebf406827329303
+32a7542c002ed0e4ef2d3cc5a611a48585fc0097426f9710d6dea70f1ffc
+a65b3d39c875369a91c045ae73d2de28b548f6bd8d0d76e874655e7ab6ef
+5bf9a4e08e12a1ad867ff1b70cb0f2ac3d198d5f70c3a251058291d7f537
+e66af56c87c11916390b7705821107c658d2a403cf1c6cac79137505d904
+a6e31f34ef23045f923ac40aa9335058ad760dcddf43aa9b516652fb81fd
+e901d29cc3d2ea99c42fb8cbb10a5cfc0403c5db7256c7d3ad11934d3fcd
+cbde7b87e11966fd3361210cc511459cd82b61ca45e208a92edc040cd58b
+2828fad652ab3846c0415fbbc503c9251d7fa661fb8e5fd167fd3e9df8bb
+17a52d2301c21f974b16340ac7e431272b48895f837687cb41ee7595a826
+315338d997fba43a9f8a0a9067229537c85caaabc2667000e6961f5ca11d
+60d3cb970d0e059e7446f1b42166292d96abae83a185ddeeabbff0d9da54
+ced5cb12e782a26b7128f0da66ebbcba7f45b6d4522a3baafa39d764b7c8
+3efda777dd173720d41e0c494949372f9be61de175bae4ad0bf8d788b3d5
+032bc46e95821290cb6c665122220ccd6cff2544b3ad1e11ddee3c0c6531
+81abe20f6a66a4e898eb48636a8d6087fb79477aaa5419b785dad54f49ca
+a8c3427f2973a49a5b064767afc3b028fa53ca96401d912a71514abedb68
+e6a41b2dc619041ae1b798c1d6d064478ba17c0d040f73f1d158c72fef16
+0d30b80a9ee8054ba8860f69f2241a6926737a040e06fe294544a393fba3
+8e9d850adaaec2ae183b12fb776c82cb3460db4ceeffacfaba629c7a0edc
+662d8fc48b59db18e8c5908d491359a9c1dabe1418b46978924cd0028f1e
+19399904737f41ad8de10d4214d05d6a4db485cbfcf4df0921e4e629ab83
+4a695c317b791baaf902ec59231b856e3e646868ce13fbd5cc41b6fdf3e4
+d918a02efaa20aab7d526a04edcb2eb388a2ccbceedb9d0b0df1343e1831
+7f46a6054c2bbb14201a92afbc452c760f16e12cf94c8a901f50f1263e01
+9308c5aad246ca64570b122032948bbcfe1152937c2c32b764f78bc24817
+4a72a706fce7487ee6c605d48eafc229c9206077a3f0fe0868ad5fedab9a
+9b07a7d7d973fdaab891509a8c8c3cb9862bbfe04cd0c3505df3ea8a4b51
+981705b38ff503abc17fd88230bf242fd737314b9d7b613989438d9e0f71
+d5cbec77f1d93a517d9fe08e0aa138d3aa55c232f493ccc1f13ec45f2e07
+5bb3a95f0d4a32d5dd2176a06bcbccfa8d0ff2e2200ad6f2cb91d325ee48
+40ae4a27c8709eecede5682c0fd5d94d570790e304b9b4fbff08852d9895
+f7faa0464f625e7d51f3fb5424ee25e89da33936de5f313d13f3a5c565e3
+3ede87b22cad211eb58b70f671f5a8c473a15898ef3d35c0d496c62b01dd
+a1963999d313b475dbe8aa888a4d66cfe1af9c86707d86267ab18fbfede6
+8848bbb9dd5af6a5817b5594c6a74dae1cb83ebed616f7bde4a43c6a3811
+a7f0b6ffcc08894d118f53828d5c55060eb0acfd818cf991796a9439f733
+9482c925946a5e5d7b55ec7c9f0f31de88caf20686ff27415eb83022c7b7
+299f23cebf34a766a4bf842de6c113c39db711a6291ee66abc42e4021dfc
+43d91aec3aec56ffa48fe9d555d9c435ee363533fe2195111b9483eaeace
+96281b83962fa3f7e0c57a2c3cf955ddd8774a263ee61b2d43ad97b0cc58
+d4657bc27aef767215cfe5c9f7a87df9d439cecf6124baf26e619e7d7a0a
+ffb678df6eb3d663bc9f77aacd75fabad0b41622c3d5ac9a78a432595715
+5f36c9dbe2d1dfa81bf0e11e0512978bc8e74d30b73fc9fb783539a1c132
+1b893b4ff9787084185280967b2d2df72690339994563b8abd371ffbb832
+3c4105d304ba0a184568dd1f32d88aa56724286535c33182fb59830f88e2
+d878822b1c0202b3d34fa70a1525e5f06bb08844abe54e98ca304fafdc6d
+c9522871eb5e6c838476cf5c15a43c694d7ac26b04f8c0deaf7f0cb0e44b
+0448e958e31374de9fe5397530ed700e78e09edeaba6d006b5e82566c399
+afdd754ee2638ecc0a2f59a1557a084502ffefdcb7e9b32ac98eb2750038
+bae5487dc255d76461273fa3708b8a1af0397a2c985f45a26af331286e27
+dbc1e5624c7eb27d87a94a8bbc5e2a67f78e9b202c2298ee390f8cc3581d
+407f555d2699e827058940d1c1c69ae67209d354da032287f55668fb6034
+f5b96919fe361fe6870ef24c914a6a1e98c9b1bdc745c71ce5d6111e67cd
+d5b809b8f789151baf3a208e949c8c7f69bbbd5bdda2958e444d960746bf
+955ffbbc82e88724e54a0bbb4e86085e079d60472b7d9e2e38b58206d7eb
+32bf5459005ba2839a007cc41d41c019713f17b1e209da9a2cccac58a9b0
+e39bbdba1c0e4aa0ea12349b64271e965fd0b5f5d49955034e635645e76d
+cef521cacf68df4ca06557d0900699c52ca3286f682215811fea8c8e7569
+bde853033e165bf1670f1b181988da996262bb0326ef9591bccdb4d48076
+86451d5842d7a79d5e5f5104528c89178e286a4115b9ecdd36cc3b1a08f3
+1c54a2943027de0114ee35d096379c1697ff60336155741cb4669b3ca41c
+6ead258f7d29ea3b4c932511f697eeda22b90c000ed5df8170f0e189b110
+13e3852953c2fa2fb21907c5e19b8343fe43529f7219fecfa8b4a7bb3e01
+fc74eb2dc148940e332d1f53f4f7226c78b158cadf82d756b21e96718db7
+7ba7aca31fd5279d19b1cf40690cf3f7a3624611bab4a7b0ee77b4e30a10
+9bbc1549d0a6f9b6f7363f73226ad19b9295824c1523a8ca0efd878cdf81
+e8df64156d7f5f068730eb304abee1344a9f8d366d0540e913d8f79e9da8
+044de90066a639796fe62569c78ad5e52da7853b5cd251737fced1e17e75
+73b5341ae6927ef38bb57a84370ccaa506bf9656ea00c7d65afc6a7c6253
+42f369bd932745fd4ec25a5afb57c9bc0c8c82de8e9e7390b16064efffbd
+151d9e169f42bbf5ec9df52cf88289ea9d829a29a561b03ccb14bc6a0cc6
+277cd53524e94c0aa173d4b72d3ed2fd7d7dc7a25b7cb9b768310b885a99
+480337ce2c11fe903d7fc5b59376c93d6c169d25b9e8a2cec8b5d971f77f
+0029b61d36d9c46a5fea7d49ffe0320c3b83f5a7dda48ee4a5e15721f778
+12c5f618784670c92d7236cd1d19248fc8c90e6c0bc876a1d9e3b53857fd
+3ee7790f486e7ec4dd3da944967d62f7e8d706a9f6ebff86b38a5300df6f
+5444148978453351bf8d230215d35257bb54a702efebb4ba90f53cd13469
+09329e92e064710259ff8a33f1a9cca5ae5bfdea62876539c0aa79b2dbd9
+5f0b80ac51842edfac8ba6c79aa9f0914113ca29565384571b885aed9ff1
+e2df3bdd667514a78ee26b59f96261b6268b7afb245de6ee930943c3d52c
+238ebb6def8f6777dc9840d0c220ae81755c742c3cf42f6cf3c33a2c6a4f
+abca01ea12c37b2cd899ce780e434592f23c7fe96f878aa5f196d9a70bb3
+d544247a5f295042842181d78f1dd58af09d99d25f4647bfef59e133d425
+7aa689bdcf248532556e6a4cfdf558bfc1af8d0991889ad61d8ba10da576
+d1366be4f6b0203899f9a02fab34e921e9a7b09c2d06f8c6600b9ffcb187
+d95c1facf73d1ecdb28bd4f5143bacae5e193dc0d196e16ab2e4d3168a76
+24de988e1b25e56406f12b6846c66d7ee0771e71be78e2aba637364df774
+f91bd43e6608359b8540bdf22e28c34bae81ae5bfe50d754553cb6858a8c
+2fb7dfe840421b702b99f22b221455d28ac55f2b8b01e5c6ed897d42fe45
+a36d396f2b263fe51663f898fd747630dea134d758954d52a44e36c743dc
+d5831f732a23d4aaf49acf6bcbb3884a21063cf0a007e2516bfa71683e34
+b361d4456f5353e72c1db7c693c9d0357ae8179a644f2f373d5c763f5e6c
+8c8b487288fb8377112784fc50b31e39dd5d69d14aa893b55534374cecf6
+19a98b47eef81c8cd20bd3b1838654f308fcaf94504fd5fd8e93f07a4760
+c182651145778990122e2afa7b5623061ec3f4d7d9f061f2b7a7a09a3ccd
+c33cb1602093369acff1eb1c6dfd73dfd67a4aa978ba1ba496bc17efdfe7
+a8f533486c3b69df01bc5a20230235454f3c41b0584d28f6e8a019db4cc7
+8d5ddc5d9d8a867b7dbf3e39f7ac68ca55a40d9a05e2e385835c888288c2
+4cd9fc51ad2250493122e0302655c463cd7e1188b5081387c4674bf16edd
+2c1f1e49b26899db5e1a4cb1bf6afe14dd24400877f8c8657ba4d3227c76
+7c1971bd33ef70472c2542b60148fc4ae31035240bf578e3ba4ce8a479fe
+b4ab2d06ca63f8b80cb0b592b2e6977db02bd2d9f81335f13f803f5c5cae
+420236e8c5c11dc4d67c210cf2694b47e7d71b47c29c280061b9ca2e4fd8
+a303ba12aef815503b67955f62bfcd7b2a2ea4e31f799987bdad5d028b29
+eb1d91bf894a8cc7f4751d15d11f80c40c0eaa38af5a9cf69d8942a21352
+e3657c3657d92b40985edc1ebfa807c5285a74c47dfdff79c41aaa22826e
+c0161e3a4e6249664f7b7f52161d0ed4630ca4cfdd6d68fe2b4b7a4d64d7
+051b2c12cd0e4dae0f66932d7881d601fb62f3eeac552e654c2de5bdaf65
+178efac1d91ddadf43980b1a23d5c3b5d38a39115548b7124b8bc5fc8f45
+e15f32f506ef0d7dcf45c93d2925829133a732a858cd6f26a3546a613bc1
+024a8d31276e529322d8075bfc9e970415940f96ef9be114aa3c97fcc08a
+6e67971a6854f4cfdf8f6b43a8d9fce53cdeaa81ac6f97a3545f9188596d
+78b6a33476dfb838fd6c4fa785747203133d4518aee00c184ae0fdf5db85
+0326ad9fdcdb244bb4f659b66e3319334f59ea2088e4957477a5defca2d4
+a5fa3e37fbfed1384500784e08ffa2f5aa417795a1d2fe54822e10cb2845
+15b6f394e7681fd911510bd68efa22957930608625775a64a48d0c2492be
+b3ebfe2f85bb6ebe4a5e409fc7f14a98f9239306c5eb3e6d04d741bf3dfc
+478bd03ccffff848e0ed18e47becb6c55c39a4662283f3c4e2dfb76caef1
+6c4fab8944c1ff6243e22715af0b4de2fd6a442ea56a5c88a6b93c36ebe5
+22b5c46014bc03e86167481d599bc3feee0564a090e43571b0dbe0961148
+2d69a250626dcb909668f145f9b626f9a7907f4a1778e8ac066af5b9ee02
+5172917726ccf4164b1e0c7e7c94e3b7df8516c78b1c72f6fd57ca0aed0e
+419f2c5dd1ff24f47438c0e0473edf9b5fcf277c84d500a4ff055566ee7e
+cbf5707262fdcd3c7a28f1d04a4333374b6108c540c64a0cc773cc90d588
+3b7adbbe0668a38ea57cd2292ec92602cf4a0a70ca7bfddb955d71c02aa1
+2effb4c365f7af85f2e379b2a5e80bcf653cfde715c7db2fb98f3cd3af72
+a94de7ab989f2d38441a893934d396c2a418998a0f515aa26914447e3a9c
+025e8169717dcc63fc878b3e825faf7da165662751e0811304ecc1a7c73f
+f806380dac5d61611388f37d7a92dda1c535a3365a82227f999e3f3dde8b
+bd72a5232b3332e0cb275312cd28f4c840c95de6366e02817028782ce6ee
+7c56a004d6de4a2786060fcb6b6d05afddc743c210f6f0458603382c1be8
+3e61e9a03835c2f6bba1a4760564635be899f75bd23bf6f636371bd2238b
+72331220156fdaf0a5d932d24829ea054b6b7910a738c03c231d1dbc9caf
+0165d4091a31350da275976924f83cb4187e618917b56fd9b881bb25a8d7
+f8741b407a89ab26719db257d9e6b60c3c25878c5896094dffc58891fc7c
+a3eaea6ae4876ce36b3d3282c4d1dab373534c261104d235ca94c08a9daa
+039540650fbb97ba61d5d907244be0b6ae1ae2c315fc7a13fd194960922e
+5d54c8528e8ae6651e9b36d7266ac9058ae97ee0af5b27b4c045aec4d2be
+d7c42cab914e1068cc8538861aecee6243b3d38f60ae09cd655da05a2bcb
+1a15f914a4b819d1e173c4abf8d25f3f29b45c4bcdcdcbff3e24add7e76a
+ea86675fd8e8774948a1625dbd5ee5fec0d512de9f2ca7e91b97afdf4a4b
+f242499b6d8f04766b0b8e7522cf8848a4bcbe382c39cbb3bf393ef10347
+f18a2e6dfaa6842e31cb9eeee419c762debfcaf49cd7bf5874f992a78703
+0817e9da9981b0d90ecdc538ebb1812b88c96b6e93b350b327ea5d737887
+7aac9d7129c150c571ecdd4808f02479bbfc87f1df80df86ed6b573339b6
+9bcdec24fb9df93c871a6aab8fa236b3d39abaa1404321d9032971499238
+99dfb447021b9510420441b9fd8ae89e2667441d7670b4061439cfd8767d
+30d2d298ea15c1ab2dd7b25fa514bab9f714176c8ae5a204bb167cdb335b
+132a35f6bd14b70ffd7031cebc7e180924f24fc5417199cf211ee8e6a55e
+094afb5637334e8d42168da0dbcda3b25336705988c929efe68a56ffdb15
+6eac310cce0d067dc6b564634a71d6cbd6f9ca9f868fd2ae88778d2ac52a
+e78ddbb7fa9c939dba897d3dcde0acf6e04d59653df22bcb70f9fbfcfec1
+ee703e923b07e0d41370c4e4cf70ff63f8c79c5c6438f86725a50e49e3ee
+e18687ea324e651dabad022e8a783c4c10cf84f0ab482e5c977d4880bc99
+adff1c8a4c5e9e643ff55128c306cb16eb9d23c7bffd19d55ef59a6f3608
+dead9db7dc3931c48771b9ac55368e5f8a857e6d5c118de26d1a1f383a8a
+5bb9a2a4b4c0958c0437fc96f264ad36d1a0acc37500c0ad72ea86330e77
+c8518a74de75eedc0f3834f03860e2c26169b8c02752dcc5824b02876525
+5026506b2dffec0a1578cdc55f15d471c6481c08a757ea55686352d2a7b6
+9c3eef57c630f12e9b2aff398671240dc216a29c5ec17d44e05f1a8dde90
+76de92456e969c8055b85a3c04041365ec35d79f2c05abd075f14eb26eee
+478deff3d12fcf9937dd3901d509b695f8c1fa590d977d78db84b2849562
+c460659842a7b90f8b21c2cc27d642586872c49b534d299b3fb7e14d70a8
+68138371550f9e021a74d2a6e0f67d90d53ec408502c40d8dc51eaabbe86
+fbf5572a2a7f121bea99be0b0045d2c516d10c9beb813e16f440825a77d4
+dede2c8b49c4ac5b71c11ebd8f8fc4cd73a62e47f7eb212ff0572281b427
+96332f70728d9205ce38570c96bd89b3f2a3edf498ca83a37acb4027b561
+de28ba37b9199d04a56e14716ceb4a4633007637b216b9f6ba2a4eca8a2d
+e0cd63ff0944dc63059befef0dfb53a48ef62f54f15bc0355356787923ed
+729a782d962b4d78235de8dcb31892638f51000f8981b86bfbd853b28929
+f896a0530b72f075cc0bfac799631f2e51f474ac2f98e6e2fab89c2b3890
+007913bb9841969b44ed76d4e888d9b3d9841dfac5d41459dbe7233745bb
+4e79fc22fd7e466601153efe3cd7700aa86acad07b0692ceaa6b00b20d76
+8c5e6052894c5915607e9cbc49f8fe4f6f3c33045fb4f0ec20a3c948af28
+e80fb67f379ccc1bd019b339532191cdb803ca9676977ed9ca01bb039553
+48175f8caa95a0714327d59b82444df22ac4ee8f5049c91473f226d4f27c
+e402bbea6f406cf21872b15b19af6c0cdb798f806994ec1aa9056637b139
+12effa08dc015bb67f3ca7a4c82c5e34d39d88cdd5287c3044ba95f2f75f
+6b6db9f1d60a41fa9034d91bd9cbecfc7ce7d76f4048206f5fab0901f7cd
+d639ed068cc82be17c35f6dbb8d85995a63ff69e52bc0a01261662153ec3
+40fd4027eaad5b1b811fad9e16663918e46e983b02a3ad97ee543c4754f9
+e9b6238295e6477f0e8133fa12360b5fe5adb0389778f4300c11a26fe4c9
+bac6e234ad26f855bca28b49a3bd95c0758587e98fb123c1c80f82573fb4
+583e578bf6599e79a9090f35be2c9fde410ebff05ea76120c7d52b3c4769
+0264e1dd276b6ab08abf52b30b91735b3c84659115bfef8b88c12a7dd1bb
+0898fc1d5782edd9f371379a8c9796cf3616a93193a06152dd3c8da6effd
+03386e580b8011d2de3db70458d957ecd0a2db427058fc80522028c7d203
+904913b0e63d26d60fc42a2c1e9c53b41bb206b324121347c6fc55e99390
+86cf26b3de1933c0586abc166bf9f312754704645d4d29dfef978d8ab341
+1eb295c500446d3e2a62d6738b1b4a9f20ee6b3a7c1c0641b5502d52a28d
+95dd07da8fc8eb96a234565fb0b9d82cbb263450f929c9155d3d29ae2a75
+ebe893d1eb74b6f0628f5bca4c90a7dd943db0e99b178a0d83524800b361
+0d651475905983e84f5905f49b0ef12d880cee222e913b5ba51bc5532afa
+722f8ef9254c49f7f62f744d580bfbdee17d40ff9a04ac2bf64016d4673a
+4538a66e52238b4f4c1d37ac94f1f65c7beda2468a10b0dfa321b18c84e3
+78cdd2555c453d62c92c4293ba0aed6733aafcadfb488dfbe545de91e412
+c8a1ad04d959c75262e92a37c4d1bb48dcdca4c8f6d9fb07a9180b6f9c56
+efa9ad9ab9fe48ed61d59c5a4b0fc284351d439e7e503e9235a30863408f
+a5a99aaa693cb8aebba6eb8476009234be914ce235bc206d093200d35937
+43eae9db40f639eab16fd3a7d049005fbf938696948d82bc25674c69d1d7
+edd0b6d51438183c30769ca3104eb378b82bcb5e605d1e065a11e17892e0
+a32eb07fa974d3c6f70c0b657384ae839f74c622656efbd3878a7aff1a01
+a2933e47f366953bd28773878c6c999f39abb27048e53970a5c88a137c75
+e49c91a53316c5f9044464e40c1eeb3eba35762a490a3ffe8fc886d299e9
+ecfcfe553dbf334913b30e03e5bfbd3de06207bf47cdaaea4cfc8147bbfa
+154d6295bd46af68ad298b5c02fb0569b6ca521361427c55d456ff6d8083
+417f3bb3ee883a957dd0e453a889d389bdf574516be147499cb02d9d760b
+62dde4eeeb70a7fdc12338abd01d709ccd256ffa5f62a7f4aa6d3c7f235d
+ae276553da64993147b5b86f62c473d0d3ed14883ed0de74f1c623f3e624
+9d6af1571dc177d27e2c1f0bff7ed9dcce8fcbd37bea8501aea6c6d7b259
+420bdfb804e3bfa4e339708d19fca748d8ed84050439ba7f5a088da4802f
+dc46b95a99959e95f18407abe239701a6fba7d6e2094641c509da66fe556
+747a21b0d73e3e7e157ba4018295eee683d0fbdbfd52437ef581b00ef2dd
+582661a4a99b02f6685cb183ac801f038e3237eb22f9508c54b34e06a1aa
+fdb4fc6addac5110d2569d4921ef8b43c6ce363e642951badf00ad01b56d
+262cb0796e6bc3500fb760ace1e7c9fe44d6816c84063b7aff0ea04d918d
+048dc193fc07bad3bb8e7a178f8720b68a80027e9ff2fe4bf8f601de48b4
+c863ae6a0f5cc9fca4614fb487a0d7e42cc17ec429e1094c06718a4c01c5
+32cd08503eed35bef2a83c86e85a8e74cb9364a01d7aa51af9a7ad59e93b
+78e3d119e400ed46c608c71e33facd29e424123626b535a7ec87cf2c12d1
+96e378986732c89481d88f14fcf9507dcd50834110c071b68860090e128c
+b525eac3b519c2191dcc7d39d587e56fb33ac6bb2312eb217d08bdf9c9eb
+34ce910a07477031d4edc8226e71421f6ae90bfc43c7398928dc2fdf62a5
+48324c99e740b5815cbac9157f2f5b51a46a1cf6ecb6a03753e7fd49cb4a
+04e5e8ab19c4ac2fb50618bd9f1417faf34225523a6af9f9b23ef982831c
+5f1946460795e0b5970b383bf8addeb045c54e9c593f5e1f9daaef7dc58b
+da2819209f05aeac4ff234e3bf47ec5f496c75322417a96de3b70c509693
+2dd0026384c3d15260446292ba7a0cc570a29a6b31b7a37596db015ec084
+6bfd0a664cda0329e8a452241cbc7443b4cfcbec48b94a1fb2bad1073268
+afd3231bb21ac37602dbf5653780215e4108e2d4f7164b12e74824397373
+c405184888673573b1f2263dbbcdc07ceadb2d2202a18ad03652f0355fab
+f0df08c30278496290306f93be7e42f663b51e4f0f7e49d3292370c92b45
+bbb7660748cdad641b1c2d24bdc33ddd9272c8bc6c4c80fdb1d6476aa6a1
+7d0e35b43ef7d3fbc7828f0209d6f83b04af1df350ce10a3af84855bb90a
+2fdec60f796d5a20eee1b323edfde3d69950ce90894184246dce29499c3e
+87effd5630aabe1442e2399f0393f21beb96708b6cf0b6b207e47273bbe3
+03a35024cf49899328c87191bfbfffef9500611bebeedb27933b1f53d6bc
+805ed7c3271fe94dcc7ffa9f2f53810cd3d08949d5ab0b144a8fac533ba3
+ee72bce2be5cd88034c6303c7d323fef2432edc947cad4af6b1c38be9bd1
+48caca12323f66eb57c3096c72f8268e746cffd4ef80df5ecbcf522d85aa
+41166fddedfe8d843cb25b9975908b5de7c4dab8fff7b98b8c24ec1e8477
+1270ea877b2a5edce15539685991971922f50404b14bbf10e66264fd8207
+cf050c7c0311d387c62b78aaac2b969d315f4a7963a79f8e724f5efa0190
+25e7790e6a5c902b7da857438e84a9bff679409dedf5a4a0f670ae4536f0
+5023a9e13c71978ca70490706cac13d790ed4481ebbd8952f759a038d821
+bd0027e057837754bacbb838eecdf781299a2c349e34578b032250842cb3
+7f3726a67bbc8a8c229262ecc0cdf375ef7469bd85327b8735550f942cc5
+5ce679a0af078126540bd2d4f9581707e67eafe4a1ebcde24a2ad06535ce
+001fb7d2e5f59c2e6b8e3bb16eb2c863dbba5e781c80e5c80fd9d2e7ad5d
+11e809b842f13450f4075c59648f4f59e1b5b8d133bd28ec16d32b6230cf
+626e4d8c76f1e46974703abb1934d3720a9b16ad752b34c0155c2412e3b0
+b4e917cf5111c0a986c361bde767c6262d8ab6520c7f540c75c2c92b134f
+1dfdd0807d3bfff5674e376ce4513ca149bbd53d0ec109d2a8b7ece2f6cd
+76e9b07a249bfe81cb1af012de457337786a7ea8853745e001e3a07aa41f
+b4cf2d0dc29a779ee9ded63df1251dee748a69d71596e1feb5082d14044e
+3b74aedbc2ef7a288c671e7a7b7c43e0d8f3acc76505875855debceb7ded
+992273ca741cbb7073c9fe6182865cad971a7196610134c314826f2f12cc
+4f2835f269cec7b8a046dbc7568b2cbc56cec08095fc771a9b093a4dbd3b
+6e7e71b1ae183bb5428bdf018193ea62a99ad8adf581bb60295874cbea14
+de08f9a9d86c5efc49aa30acbac07f637b2c1a022978383d063e12f17fa4
+a20f18140ff565088be1714bc19701a15166de32429ab505903ba52e1ef0
+72a304d1448755ce00dc7082df7d990635574c9a5b66daad0a45605903d7
+3179e0ed9e2630f43861e22354ea16418cecdfdca05201e2f75ab6f7b3ea
+e336c4ebf7e3851cc097e2105beaed2111444de983c6b82f11b32fdd61ea
+b45331f7ebc1f93cef31f223fce6a349d8969651ab627a481314fba2a3aa
+950327257f8f50e69e1a20943816ef41225ae1b76811c5af88976c4b4e02
+74b43a58f63a27ea8958a3f5d875448cb57abbeb4859668a115108976861
+01542a0830ac31f076c5ed6626ecd9eed04ad3e762e9318c7bab07ad3204
+831f57b4f10deeed0895e24668aadcbeba9257f1ec419111e7257fca098d
+3ca89a1ded16094d10231bbcdcafac1166c08a7007749748e8c4f500b9b8
+7b84e8117042575a5b0d50652355df6cc61cd2c785b1c6811db2e9b9b7b4
+7266b4a1084be1f3f7d188fbd9494cec5116fa627c8069950113f7090936
+f10de3d71de1b70afc56b61ee245ef7278860b64113233a8a7817a0ca23e
+5f08370cd48548e4757478b057a0ae59e9ce81a4ed7ff3ac3d2117354cb0
+a98623705deafad89ce0c5b5196776cb5d437920bb5c72a8a718ae629b25
+e253c75501555420621480afa2b91b756e967c7f24e3005462cd1496fb58
+f34a42a9d59a10d6d68bb3c42566161059dfbbcba569a089d9c1dbaebde6
+51b2275d59df0933dc21d0a902f21c5f5037299c6e8fb9541691ed13c0e3
+6a5af58d7b8bb360e8bdd2a77b24138b88a5aa2938066ff6b098326c2b43
+853800eaa4a304102281325ecdfbb2bb1400f09edee97ae812728cc153f7
+eabc4a7cf7619a74b495fc82b5a89a9e0246f98322c2266bf838bd1defb5
+16c7a371d91bf573de96f05001ec48fdcb9e9045ab1fc910f6b9344adb49
+c38eb75023016e2398846602e2fe7a07a90ca86376fc125d8bed1956b897
+781def6eb4298204e4b551eec3ce13b1fee5711f10c0c8232ccd533f8231
+7027a87c30b91bc14d91e14ad3ac92177830435c27fa8b8f8dbc75c04cab
+0181455eab3d1e101b14974a6f4fb99c87ed435f380f2087438b4b371d1e
+6113bd6519afbfd9244f0384dae185025aea6457401f54545e3494120105
+9ce756cf7fab4fa583f986a8b4d559e834ef331a6833971c89f96c58cd5f
+b3be135cb06f658fe2627509c8cdfa91edeb439eb386e3bf9bc4dc4e7290
+a2ffea0ec25c0b9c021285abcc821befa442c87cedb0a6c2342c933dd461
+16ca786dfa3ee43a7f3aeaca49e4f3a1d404e59eb35611cfc68ebfb5321e
+e4d871b206ac8692930c892dd7cdc7b31baea9a439fffbc5f9d3cba3e71f
+5638dc6dcb8c64f763e254c327f77352297bd706f3a9b4ecf045b1f132ef
+78c2967e393100be57aea4b6a5a8cd51b68bc114ad91e1e43512b8079834
+464e4a9231ce839825cecd400f71dea1b4da2010d89f3fa8506f26888f25
+564f6f0b5864768abe3d3e857bc265fb6b99e9546495e4be3f7b3bd616ed
+a6fca19f05b84df96a2b7174cd315029082ec03d74e9b16fde55e6c51c86
+b0e6c0a1875275fbc8f24e08eff26ba23f0a963f7a40c359df33a2731f13
+fe2c905f6f60acb43d4d03cc63725c85a406108089c33d82e1aa107ccf7f
+0517beba564376c21cc2589dda7994cd35739722509c630c4f8895bf3687
+bb8abae73b5e1c42915994c614e9876b7a1dc571c06ef000d7ec59deb528
+19ae24516aaf054bb91545310116f9c46af65343853f896668dcee475899
+d08f4bc405efbdc9d455d2b48cd23d1dd4e40b8948fbf834132b83bf7b95
+0e2f83a0915cc277d4951b1d9bf8c9d7c2900ed222ca89e7aab7e64d28b0
+d90adf9c470ac90afa395a63964604653936a618dbbee33caa4474ed522a
+cee561047dc163c784d5b8a26e04256b16f96c63eeba3b63dd8cb056834d
+f7f846fa32e32f0ffc14f074f03891816de860f201028060c3043b391fe9
+858cf29622d55418d67f5e6e6c718f1fc2e62daf1dd4cf79eb95a16d9c3f
+eccdedf261f9f41905f8b8c39b9bffb2c0e8d65ee4f9cbae52b55fb3bbe1
+07c08c3abd668e91601c849af2e034b99de6891224a561b7449aec3d0be4
+75991f52211b9d1668311aaa7ac9185e78f90fd31a324b6c820f7f8e189e
+952cd15e57d475430e1beaf7537cf6649e80e35df16fc03a71ea162a19b7
+d29617bd5af341e7ec81ddc338606fe0507649bf761eca6f72dcd2b21797
+32baeb51d65779019e678cc846f184baae95550fc430d6c4e315c1a66193
+2e5a8c4d3d81acb445e2b0b807771e2aad8465847fbfdefd7209d10dbfa7
+faf2c3041a678c70a1c807a6f82eb448688c8e9a6c968f7f9f4cbfa88505
+997572ce6aa228cac0a80f49964957017e9090bee36c566c06e79bebedc2
+de9a7902750e1d25f2b4a51e10221b4ef82d8f1fbfaddce9f9682f3843a5
+81eb10b55cea4a8ea1e2f7c84b6394e04ea4b6bc9d9ad344c41477724a19
+6f73d92b9c4358f73a3f882f4452045c22555127bf9caaf52777c200d679
+86227cb17f94a118ba663428ab3fdda95c359a353b4aae31f94b04d84a9c
+0c699407caafb272ae58ef328e9065b57c33bc9bd75b35e4f7d2a69affb2
+137a0947573d52972b014a28f14700f0fc2af0afb71fa3c038a4fb5fc2ee
+2fc6512596b42d3b72a612b86263862bd3b2dd4333758611077474fac0a7
+22e1d9199d66510a1a86f807aa0de71c13920d5bd7328874bf1a0e2b80c6
+d07638f261ac24dcf7485301c5d5cf0a8b62d6468817d57b9eb835a3f996
+6ebf73223cb5909a1ae2a85bc90f012ee26b484a40c8a998ada321a0fa95
+05d9a09c8f61d708e80c7b5f47599d12e020fe79d63bcbb6227e4158acfd
+41870941fd774f6525b78a6781fb50519ad9240ec7f31c1b85aad48745ea
+2e58ef88b890bf9c5cc5910148aed529f2694f1cec8b0e2c30952a4dd922
+1d53ba846cbbaa2d67d64ec25db97fef8973d51207930fe5584cde28a273
+468ed7713cf2e8865dec285e20f49ad3e6ca4e43908a9116df1bae41bfdb
+724b3bf2cbfd255e0eb69560b329b7eea14bbcdfd0398c663ab9c13cfc78
+98c674bfa207018cd1c85281c4bc995b16eec777f51b0d1929100553532c
+4c3e8e71acc6daf2193471704d3fb92de494e89f81bbf7bb700d0fe46d9a
+21f9cc6bf251ae31f40334c66bd40f801d02ed63b52c3ec6a1303d659ede
+330cd53de8502899ebc6dda655de3d583104e01e123001bca6fb3ba5ffd4
+f1e506cf7ed59fe3f991808b2272b1197210e5ea213b3bf7d6a2177cca3b
+0483447bdb44ad2c80e04cf5e368525f8d6b9ba6b114a4145c2c8a693113
+21c8d5ce682f2e13ee4720e0568efd8488faf57760a93722dfda8489ef49
+63f2e65978adfab8b9c9c8d9146180b92b3c84c725e1f50ea135004b6479
+7ca6c6a87c95952e8f5d68958b644276d106e3706af153ca270f159f6f8a
+d76f0b9f4be493574ff549ad6ab909d42e5718424001d8aa17567dfec66a
+3e0cdaf98c89e56a4692f0d585b13e8c8e1dd4a5801b1eee8b3a333b63d4
+4e65a2c50a1b46615afc550390c1668ea06ab0f6f9a175e408b1568bb470
+f73a9babc7f82795ad940615701ef5e2046887414770ffbe9c86becbef31
+da6f294faed8e4f9ca084a61915d2f7194ad578fd5b9e01f4c23027708ad
+d4326fd70b48d0cbf9b42df2860784859dd9cbc707020c3917d1920ce164
+a671d5e09d268545dfb9d2555a1c7b820ac802007c54b403e1a6f9553e6c
+d52c64816e788e6115ebe9520d57aa5d0278c1e6940fb80959941af78bdd
+96877279cab45c9ef7e47d90d24b5b3e0869b769d3a0fb03dcda79ee3a52
+349f3fe89204afe517b97455ea1b056f87cd846202593cb7768dd89321af
+3dbdc0c188da25b9699cde6e0b1928cb4060f09b4f6a6c2b68700bc14eb9
+fe2890fecb5e389e7606186d4417f5f5a6babdf43c1352f4feb43a99698e
+ca73c7d7eb93ff5d38ebfe6d102cfd0d986af39184b4e007bf65131b6a2d
+abd1593020e2fdba559e939daf7f6cbace2176489d45ab860fa4a05930cd
+77189c67d4b72df03fe8cf482419972621de5f2f0143ea14f5dc08463b30
+2be1f4bd73cd1f6c5b17c74d7740c802cf197ab3f412b697c2bc8f41743e
+b2be55e238dcdc6a0253a72e63479dbf563e6a161935f77f0e5bc5372dd1
+f92ae1763e05e019b47967809d42709324eade06cecd85daabc456d9e903
+e0083d3a74d5cd2df30bf1db1477a6a71a55a52359f4940f2c339bdb6edb
+aade3e614d4c7c36fa2b26accbf520579df89a7239ec627869aec628e7f4
+ac09ea132f7e2d030408dc91f2596c954a9c026fadcc416f1e061b484372
+21b50d8a4b735c91d6e8d2937e4454b0e8d1f553b84a35c43e1101f497f5
+e429d6e0852f011213e7068d53e4dc696f6f7ff9637d3ac5ed28b0f8b55b
+aababfe8e9aa7fa60172450bd17b615b1b89048fcfee829552077abc1d30
+615c9b5725701cb39e6675404c8230ba27395ac8b5444f318600dde103d3
+039cdef4650e68a9f1280ca84aa8cf87c652aeb45cceafd1a21793385a17
+4d4a5a5830700593cdd94d61374ff4eb563eeaee80b761230ed61d06be11
+fa574de0ae6c3452583aa53768238a25f570eff0af5f5ebfdeea98c85afd
+a53319182611e3e6285659ec99d27a718ac5a1cd7cd80f2c97bfe9bbedf6
+912a41a171ec583a0eaa4ac571b495ac78b275bed49eb32a0202a07f1ebc
+b0a89fd2d1cb6ec43631e8e26869aa6abd775f31e1cae5158f904a0c14a4
+ef72d51e20503ff7814c717a0f9b28ae19897a448d8905725da4e40f17f6
+d7978538095add5e820e80de9f261ace43d77d4bf97510f774860e45037c
+793c28915b01cfbf7c6388b2e9225b0e2721cf5fbb52ba2da6bfbc11d515
+3ed1423fabc05624b54a1a60235ee26e908f63c52826315f1ad84fc79de2
+3ed793cc756578475900e7a9ba8a812e06d2b9721556483fce01ecdb7f83
+190b4a6f2eb8728f5bf941a5934c960548e4a8c0d17f6708386607a0502a
+1ceb0cf8ee2ba70d0e0b350019baf415a66ee50ea8a8ceef78ad242421d7
+397c06caf762f6b4bb54bb3b8484f398000f0571f3c9111e96164af8420a
+7aaad2b6b5056ec35d0bd02b46a7e007e24e1cdd1631d343856da9a4b66e
+f36561844b16e6beb6f08b0dc8de04b04364335d6657ff916495c3f9aa5d
+87a2e455428a2d489f70c2aae03b64390a6e083094e925f75f7f2ea29a44
+c76ebb50d62d91fd78c3035cf4bbe13d3d7205daa28ebbb258456e2838c6
+41ab51e1652594c92f592ff8d31d90c6f179e067747e9d499a5e0fccf5c1
+6753bfb70a3201fdee641c9f45ccffad879e477963c8d89162195474ef98
+4f1ed3d69369905a3d55ca6703889213fd8cfd7b029a3be8adaabf620111
+675f6f65df5f5b05c635ebffd9d6c573b0d6217448c881a4d25262cefdf4
+9083e775589a406ed03f8b0038dc7c47e1b484ddff035994f4a6200923c8
+5edc8236d20e46b0d3e617a8b026cf7070ced14b3340e6dc34fef020a9be
+702e17f4bcbc738770e76f47ffd849614e24207dfa5e6f8d2aaab20451d4
+412546e40e8cbf56da8d121f364e03ee310ce1cb7f6fa51c6bcede9fc198
+b66d39d57b23eccd3441460593f44ec22cb4335bf19e09ddd89184dc0f09
+f682dca18763ea72db6c8e32faaa8f002d49f9023d27b508395ab751be5b
+02b5db309dc9a51b40e77552bee48e379fe478bf337e039defcd992afc2f
+712a5b0f646ef0902b593d8e9f03bd9eb512ee344e115f84671f21e5b5d0
+3b0ac0548481a9a07292f79bf74c41772e16611d15cf15ec079814eca31d
+f380ee3f56e9bdb39e0028b15793670aa6d1ebee19603071ee3ca517fda6
+f8c5763c9c97d11ef62cd19542412b55d55058027494143f217df42ff2de
+1c529e533d0ddd46ebfa886ddcb9072d299c13266d7c07a2ce9f5b76addb
+44ee6513244d7d4d55be1aad98821431280e334889718b60b3e58929a1b7
+197d4be03753e22a5bea21669a4ee78ab070a41f2eb01a30f200619fcdb7
+5cff898152f0c44b2fa25508cb346661f4fe7846928d52014ae28981d803
+ea0eb8525e6a2318cd2ed96f7386a22ac36025027c5d9d50186b5a2830de
+062b07ef56ba35883ae1a0c76be54a0986eba08fc4640b5d18bd247f2cad
+7d9f950b698d11eb11aae9f847f9253e91ad4cb56a1b8dc50d19b81362d1
+e1b04661e58fc86b016503bcffb63b3deef03c5dfdfdb7cf2c732d77a0d5
+5ff77d2f6a7ae2a896bc1184c9de0be31924e087e0828628427e0e61f564
+1475c066cc66db890c417df5879f3c6db72d36132e1d87a88cca57c99aa8
+f5f38e5b6911048e5fc827d4170c35f3298ee937f79c7e0f51727ac94602
+191d21bb621246161a5c2cf5260b7e42932b779fcbbb32a391599cf96b46
+2826ddb8c2acb70c4bcc6d8bdb4bfac2691a48bb0d6b7699321352ac3104
+a0bdf7da836a84116f8a52d924fa8db025c37f39dc8af563441c51e317a1
+c2f5242ae9bb32eca30bdd7e304e95d1527b7526992a1279acb46fba73fa
+bf5f038b6081deabb5d2966cee770030d726315080c371aec87cb96ab3d9
+c0858e4fbca3feefc066dc6ca8387326a9eab6e03d1a56e5c5a2ba7254fa
+a91986f2e51a767e8a4b8009ebc6c8cbb6c9024eae983e115bf5d52b9bca
+03bb482da239372f4af2dc92acf7272a35cf622cf6251218df39d9b3d044
+4d36c8b7ef7db3f7eb57df365ced86f4a92d48782c219400b13a0a96ab32
+e09e124b8aa085bc508c44e299b7d5689dbd7ce0981c2127d6853bc099e4
+37ca0592af681ce6ff71a2dd24807997288afa1a407602342d18f0695f44
+2241c897500432fd73529eea55948ca77e86c3f6d4e875aed4dcc5377d05
+5a08cec70057e4133240c63ba28c1ca90623beb512e89f4f3fca56239ad0
+c57a7fa9cc6d4ebc7effb427496fc36d05c395cdeafb5a21dd430c98fd80
+943ec41e7b41a641a28fc257924692a592c1aea49712dfa7baa46f8c5562
+6a1f30fd01105d2f9f460bdffa8342ccad277ba5d11d815b45adad5be5f7
+3bd73eb5e2e5fccc20883bb5a1b5d5d569c9935b0be71e7fb82fb2d1b4c2
+a8dce24236f65d2b8fbff5066fa300f667a4d2b6f150a9b1c2c6e50d6b6f
+642faf0fdb850c6d7efd955f8582384f1a937a9a32dd35747403ba93de7c
+f7ede437edb83e84e9dbaffc0e45f901511dfc3e651434bd58f0fc52c28f
+6cac352eb7ace4ed61f49df8cebfbe0c0964e484d2ca8ca5f1fbc839b907
+f8c2b5a420cca06582868827e9115301faa2bb434e5bc9cc1978217ff5a9
+9a3038acf13a9d8ff87ea545e49da1e9ddd0e953f39ce7fea2b0672b4433
+1d85a03a3015399e4f2d03eb72da4693f733a34bfa872978060e65dc4e42
+894f341473eeed60431ce8fe1f2cfc3e5746c1ead96e228ccd12030bba67
+4bd3efc3db7bc76f56b758a391d44bd6e93a4b65c1b109da98811b08ff4a
+1c98190b24feb0fda2107ff837bb3b29c31afb2ddebc3593ed6d0ff0e88b
+85322230aca6f9cb82d641a67e602c3a0b40a695ac1b7265538a53b04dd2
+2b5439546e8c4ef96070b64469860b82ba4fb73b424f6812cb580e177150
+6a891c678df4851784eb30caa4d3dfe140e518622f8737b86f4d9cffd870
+7132e2b15be6b987dd30a3be8433e7dffde4d62afc8e6ddfcfd68d07b2fd
+e94e4253b75501d2c8e9f556420e14c88993322a24c31f6e37d45ba1a2e0
+34b3f749d3705e43cef545d47af86948448dd0b886cc3a98a1c1b8399bee
+a86ba1f3a69fd5a4ef2cedb670f5b9249e176897e406149ae0c6063da49a
+cafb1dbff711b977dc7f5d4a67366e93c7b7d2cfe461e8faa4d169109c08
+3e6cdd1564e5940d3bcf6421ab684f833c6e53bf76bc7b0b1bf85b0e6d35
+76cc4e86f06a86a241f22e12e5199ce07dfa7460e9f27366ef0f670984ba
+93612d1e68501e5eb5f97a588f71179aa2325cae91456d2a6096c1dda493
+3527dcaa9d23c893408e6b3abd7048b17cb58484cc2c381d3a4decdbd963
+839c343e8ab2165bcf6ec6d3a93de2bd06291b6c04f8658785a2f71a4ccf
+286abb902766a45e9725f0de564d71cf9d514a0d88a2facb119c7f6077d9
+5716e5ac935439b47fa0208e9e5fd9666179f45a21efc417b82e110d6c2c
+b5d724c3fc1032dd5b24644ca4918d4cb4df0b3d8ecddcb2e13baa967d76
+d4abcc2439205e04c93b11240cae025c456de5da2534a524afd87e4e60d6
+2eb1ab7d1d54e23e629dd88754c056e78f057ef66c497d993af61f9b6654
+4a3ca699dfb2edee722219199d4962cb72d34e6f7b5fc4bc45efd1240bf4
+a87a2b88355caa3fbcfbdf6159bc1c72db4489bca279507e8dbe67b168db
+9e6b3ee1e024e42e02cb076ab71ee609f88a109bf00ff75fc91a53d49151
+f1f84fd15f9903f1d3a3c66618c4c00721875f84a9b255466673df7bfefd
+193ab00d239497d5aefa6f78705934f1aaad9b6a51513bae7349cc4f5215
+4c43e03616bcdcdaaa9dbd168dced676bc680ffc6a0ccd9c2f6efe807cf6
+ab5d82d2ba75dca1c2d7e08d25bffd648cd35b1e038274aad7cfc271ffef
+eba50d76d6d22927b4d7931fbbc3cf4aec101e07434cd8baa28d7a344f2b
+4b2755a6f746a66368ccda78a0c40af1c1aef1813213bc1bbd17151ba773
+2dfb8b590378bec84266a3daa34871669db997b178f799c05d310da0d97d
+3ed2f4b31e33e4f134b179818b6faae80ddc1599d04dc8fd1892a95ebb12
+8e719cfb885e13fdbfab96bed732637e75a4237b030990acf70964bc3f16
+b095690c8b54d16270b90045637e0e50947b5b6c0ec4383cf47af58a7771
+22117b1d93912e1d9390d364e7653f920f295fbd79c635a112481583bb78
+1844e3eff4c8667c1f8aabbd6d74f6378611faa1b09175ba98effc02f9ce
+27d66c7d180ce4e8a76da7cdb89901260d72af79f852947f89db2993dd1d
+11ced6202f70b9a6caec7a8213c84eee04363bd2d60bc9bbe93689fafea0
+ede575d489a031519818ae508c599a7b143b1b5fe2ae164a82637b77cbe4
+36d7cd5d1840f1bec3e4d6fabeb3deeabb570cde270070b1417e2c723f85
+3e00a1d1d12a2ec6ca23aa78e136b17c07e7b69a29160d61ba545783a386
+4b1da08942fe40cd220ac3808afc6f69f11c8bc8e2761a74d8738cd41be9
+44fc505b25c3a784e15dbcec050999c8e1f55749c832d64dfe1af119e5dd
+4a05325ecc662bcf7f6a70df6f2b6131ba3d95f0d3563f7f43a678eb9c44
+f7f5aa50a8061a6c16d04e09b8ac05827809beec451af1e2c2530f492a2c
+af5cf38001f2a61686c24c6a1113e9098b2c49f992d32ac4a8f06974ef9f
+974b241121915ece38334c4182780f9e32d4205f7484c033d597c0910d47
+bc3764006d4b5fc28a4615bd27b46e5bb9bb8483b5461933dc9e08693e09
+c267baeb17500d763edefb5036f820081c1ad0c731123206de774fa464b9
+df19e2be494b3b30e29a0b8aad263602357ed11a666272bbb114a1e49043
+1d838be19a268ea96a8d646edc15598038598524796b89a857b0259353d0
+c2560f2b39b6de8383cbb6ca4d0ffb235a2b761ba3f794d067f16fd0e651
+71182614c8c82883bd9203318f38e1279ac713e68ee393efae4c0bef1d4f
+509d19f5404592f0689053d407f1706a3f61eef0ce1d6ebcff4901d87715
+63b0e4fb078597f9c59024b0c67aef020157c09451effb5fba75a9c2780d
+87a865745d0ce8d1f535dd07fe0a17d574bb1457b5d1ee9dc5dc41ec418a
+a318320e5abc070b2b675d1c463f77d727531c787cebb466072d0fdaf224
+a1903f18df46e98bb4cc5288f11f886f570d770b346be00598f99209ebc5
+f2cc5ed4af88a96d6c6324c46e9649b2fc37b56b0a072badb2c7f8af4be1
+ca5978d9db9a45c99d416901cf8c30902d3d4fd413695f18043445888e91
+a76bd572cc4c3ed8eabff296fe8a8ed3320527ee0c9882edf49c6eb839a1
+aafacb82acdb87d4a140970a6a603cdfe8bee72d8a75510e43d169001adb
+292cc6b62d069352c4cff9066e12d8226c14362a30a6288e38515937fc54
+1d1d5ecab8a3291098d33cfaf89339c43844f84ee3c57f1715354fd2ab8f
+efa10d3e04f431b66747e91aee2c935f67d2556beb4b16418b3ca818c8b8
+5f83b592ca9915d341141dc52a66764db0bb74104088d93159c8cf315583
+34e0bfd4c01a122e5ab06f35b751f7fea64f3f07e10643814f38357033b3
+4d82e71cf99e9481bd44f05c9b3ab0ddd0c9028d5b251ef3bc167d6dc137
+75871cad29da1fd91e460150f51506b4fe130454f2e7a3e4c9a4a2d7e6c4
+3291f7d9418d8772f5755660610fa4909b545d594d0bf908c8109279399c
+eb2933d1ecbbddb185b84172610f5b0be712da7e324f9338ba7c56644449
+0f832932fdb33fd09e397be06a0d0ec06e946ff06773a338ede4e3be9fc8
+acf98bc981e1af0c412fc0bd7358932436bddc43b07c061909d929682e7d
+e9872afb6d9b57e96def7ff9ddbe4a64ef21d14189f7005a64d213607abe
+48c67022980cb3681741d633dcc15d5fd3484caceaf5066bafdd863e3eae
+64b6826ed7d74874abacaf28ce9622b1b8d4342a2d833608775f97d0a559
+ce4233008c412fb0117e72e45307b099c64724141506b2a9c565ed541d47
+8f49ae5d98cc9a9b751103efcbb9f09799fa874fd3c9beab0e597ce6eb42
+5f93f4b83560db87f75182a755cca3ddddb8707665a8be010a40ec611704
+6c91e5337fb7ca377ec96f063ba5e1f97bfe1c1214717103606cd3738536
+26fd460620130db020b05f4ea1d3644b2a8da11cdd2c6c2a065117278098
+630bc70fdce0651bc51685841d824fa42df0eab5427c408198db0927c911
+66b46c9d89a760eedb9308a5150c7675bc05ecccbc0051ea8da1fde8132c
+c06412f1d6dce02bc76ffceeb8870564078620f9fa7fda867811a3304f00
+a4169d96e5cfec2ebfa90d81dde07949659d313ff7f8402bdb1eea4ce016
+63e3bec00400aa33f6b816696a13c8dbc338aa192fcc3e06c45b76ea41ef
+156b3645bfc3ee5f1f2b15ef8fef7622007196f9d8279097919a225431e6
+683bb3cabb71dff8d8a579d174b2063f48d63b7fe16a9c83dff1ffaebfd3
+3e9ca293a8c3e6f9501e73900b0f3f5c6986eb2e7a74307b6d86b8480627
+c39c2d01215c4f95baed042305d720dde7116b93190e87d5f5050aa0dbd0
+e8d6988a982e7d2a1b70b3b7f5f8b806f49d3626dd1e5cb70338035df553
+abdb4ce6be4b5f977db8722899ce46c3d0aa8331438f1c22e1697983b82a
+3a6b128f2ae513509fc66d8a56f4f74955716d00081e4f1dcfda34408ffc
+05ca4681379725188378343f875e734bf5ddce99186c9532999800cd4b42
+63105ef314b8ce102a3ec7b5ec0838e6618cc016d8dab5c45976f491cfc1
+f542b6020c907d64f822bb626aa03f04344804da444de14de255853277dd
+1678afaaf82ab3851aafd2c8ffb6b7a25eb5a1165936ac02a53fca5b6a24
+c5b0c9884d01b54895cdc6e64c4f3061d2ea76a7b4f7b0164faf03accd3f
+be9bce7a12d2a37af3f44c2e864fbe8422d461ab553c101f9e21a50bbdcb
+6ddf394e2f80f94a2c721ffdba037688f016c9bec8dc1bbb69ca91b04823
+caa2fd07aa0b1f1071213251d24753fc7a8e152628e23f5bbfcbaecb0f61
+cac8dcc6a8ffca0311483d2798450c4af21f5798763f5b4ec54e99cc25cc
+f0019e95c7b89967eff0e002f576583bf8ffa66850006e9feb0f46183c41
+186476ffc10e193c6912ff8517ac215ccbbf210762c4d3318a83a08947b7
+f3807217fa8d155a3eab3bf2a8cd65cfe9764e8d9998b1d972cacf112738
+d7804c4d2f545529031f81306f5fbbe974063935754c8d8a55ccce35fef8
+0dbb6319a40c2484da95c777d9ab30de56f071ec3298e3163358c5f2d7d0
+b8968ca4df727b8c7c7e571236b7fc308d6c9aed824a7ea3527fccf2626e
+ead5810d45df801ab75cd958cb42a00ff9734ae6a9d870a4392d6249962f
+81bb145d623f5f380406025d4e3a491509439ca5c95579386162aa02d457
+4080aaafda2003a2cc680165749fd5dceaa91bf47bd838f16a21e116a396
+e9e6f758d41df50d3f1610f7d8a65257ae00f2cede6cab0ada9b16d9addc
+30cb7a068b358e247ab5c1810922a70e23d60fcb5d3c67089dd4024c5b9c
+bbaeab1ce8847671732026ec1a6043e38ae228cfc27b0b5b27b2304ee1ad
+b7bc8289edba34935bca94f680fa5eec2dd45f10cf13732b8698d84aa2bb
+5f5db833d672cd7506da8fa396b0845d8994b9be69a515b9a099f3149247
+8f824413a40dd76c862830f89db2f21531141d5ead597fa5d816bb015cc8
+ee87ba594bcf0c717544f32eb695e911f585f593af6852cd27ae6b25e063
+29e7576a9855d0d7cf76e81dc8b6a42a3196d178112ec5b62994af67ffb9
+db4526c76f049b43a251f82426a002d760ea17104cc5702cf5c0dd20454f
+b833d247d38352c951e412d4d5688c1991e4e570ddc3f514218dd1d5ea64
+36a094f14a96983e13b5e5997cb2d115abdd35c8d8d64ec1ba0c0b1da86f
+c40bb1a456c03d79be63a870e9a882c235950bebab733b5a50adb07c35bd
+8c7f8807f603fd0734b496e1a783e518a9069bc22ce8f48f29b905a18f11
+0fda8ee43acf22bedf99b2ebb1e607d1ab920dc290e30d041c468a0cf27d
+948351d50c7205755264dc6add5279ca172abf27ba1b93a623f2e4796409
+592ce84c1ae4102e4b9221c6a8c8466319e6bfe089759d68dd58f74c19b3
+df9e140aa31ac26b7544a8497365507b35f85586b6025581b80f6647fff7
+1339acdd01c2fe36c6b7e615ca23304a828fb79d891545ab8cf5d15129b9
+75aa66132b89bd18e89a9106b7a95de04a3bb4f0802571886c5c38d05ad0
+9a3be3bb2960128bf22b70a8102a2c2063834c969cf050a5af3c050a3347
+358e00fdb0391dc3e0befdb1e52178243a0dde5dc83fc7a854eba1982ce7
+ff65e750b9c4dd86ddb7ff4ae7b72702d3cbc7a0b369102d247cae19677d
+998f7b550f901ada79a82319f24e1806f44dd825326d7f5df6a9c0bb9546
+eb28e1d6dbdb2cc18ba3d463abd838b208419c168a2de68f252825faf425
+fe397f852fbfb4d379696e73b84b9a876458f526a623a5a0238a210cd5bb
+715c33d3a8b48352902c2d83d18952c55fa749885132ab6b7e6db794b159
+88b9d511438124d8dde3678a74654f9253d0b8b5703bd0d35b3f7ea294fd
+d9b44601a8e73ccb3fdbd980c2391d4c7928b41b46e9ad163886acc2b68c
+5c4c2a06911a7fb36ecc544b7d886c75dacb52308ee0efea5e3f16a11028
+a53929f7b495389601bdca158609b9d8be1a5d68e5ce3827189a0f4a7e18
+2db0eb81fa0dcd6c587098f264a3d0e2049f84c8a4e8ff503a68e8102b43
+6a4bc956eb9081143cf2cb903aba73070f8b3c4721c361fd398f7d17b363
+dfffdfce66c02f2a7b110a9626a8fd9b7f053b286a7d7ac4d57ac019b77f
+9051ff0972190fdc0968f8d527afc6d8e70d9c638c33bfea751e62d1d449
+0027c64e60cbe9c5aeb395bc6d692796dda167bd5bbbd233ed01ce57a8df
+6faebf95c6c7539339f31397c1582d47fa00a40e236b7bca3a3bdaa06e53
+350f664c12e10f4b174195986e94c98699bafbd3105aff22a82f8d54e1a4
+88e44842bc58dedbbace508e3a69dd35dba1f0f0d69e34651bb078232519
+dbeed3b29d2dcee4b449be5f39a41d2e0c84ab52609f8bb0b3b85d0cbcfe
+85a9ddd9bce5f1636b4dd7e7c77cdf6a025fcc206b9104ead365d8b52f42
+77d64ad3ec49aca1bb60b87b9f39d40678e3b2c8ad69d1b5d3fa6d0991bf
+f3faadc1225617411fb4ba6b79b3eff8f3e0802d0092567f1c3d43118ed3
+0d3d90807474808a9bb5f07f31371f3a4cae9ede2f758875145f1f4be72e
+8c7a8f1a733f91c761039025275d15f76daa677fb447795ca639a5c9f9e4
+bcf3c2c06bbe0202187ccc5f2cffbbc208641a52da611d40b08908500375
+829b8ceb8c93c7398389264b3821de6d37acca04fcbcd02499847b4297fd
+cdb15ca26fbf868d5e335a3e0f3980ceb288149424968bc10ab2466a15ce
+dbdf550eea623c162a3a7963d657ced119101602898b23d7cb99618b5b3d
+59868f5ac31ce289ef1df56ba4c5c398068d5a928a4aa53325d95bd1c774
+f0d1d503628ba1546f464303e0f454cc6aca98d032acf05872da95a9188d
+0f224b875c05157c2fc993d65521a770e6962407a22c0f2a14b80064bbc7
+4f496c61b44255c40c51bdf60dbfa7900f77296d59abf61f964fefb6aff3
+f5dccdd7a812fb5ec30c6dc8063bd828f6adead242dc0a6e72b100a694ac
+24089d150b8729de5a322ad77d84e7f4a62570a178f0a9ec0dd32a7b9091
+78d9a544430cff30e2e570dbbb649d9e19554b39546713047ee0861b8a0d
+960f690d2e2e160f24f152f6f0a93f6b13b1eb2477a416fbf3c15296ddb1
+3a3d09f771d8618a85dec2362f88d117f1bb174e829f96f9be965b175321
+a3bb0746376b95260b82cf34134d29ba6425d9b86e764791d699784151bf
+26d4dc5b01cc0f88261df88e3cabb371d334e1a2f5f60952ec7038403f20
+45f70925e9d8b49ecc330bd90f563d3894b15ce629e686e3bae594e5c251
+2f7982eab95fd43cd595d8ec5fdf962f5e5277e416a91c279178bd98d082
+ced5655015c9f425c048aec135f5bf41260dea74fc1c16984c3db8deaa0a
+65c1426b7a5e91ac5f67e222905efcdd297c1caa1dfc17fa1a3de462d320
+0a1491d41b26f799475daed3d6e3b1fe923d3cac505823a1e77ce6b07c0c
+2efec207347a8e44d3c5d196376c7b7edce7c9bed0519da191a63fab427a
+b930c1156f51c8d5ac5bd9d062e0e04089355df1619450c40d0050becf10
+37bdc9b62d7d4c90b76219991d215a37b31091cfd832d6a95669dd02b904
+0ac2b60419dcf064aa70a3c91a10e5e4087093246fb95645828a758d835f
+51dcc7ab133b360dbb003ceeaaa1102dfc07931f0ee238273d9dc4c9c8b8
+ff089232bf823ffdd7a33d0d7e142070f240d078fdf590dafd88b89629b0
+275af422eb54bc1285eae58cad06bc2b12d5a0c2bfe51c4d1082aa23eaaf
+334271c0523e3193d6aa4b6a30bcca62edb662d30d93f5f553a211612cc2
+ea7da1d19112cb981727edf44136ef358eda02444649008a8e9db0985ace
+34a56bccd493378138af3f1632cd885259f01f97a38b185443e3b4408aaa
+06c09529403545dc768be1f6e4b4e85ec2f094ab06d4ed78620489de9014
+ed3d4a76af19a75c3d65c73cf8b3aeda993e97289bba416758d561d6dc12
+23f3a5a740c2a64fe4aa02a8af2efff0a3fd8c0dacc5b6a9f0eae8833359
+bf6bef10d03bd931f05bea5cc117e21aa4e3a486845357a256af1ac28296
+7169745bce4592b4501cf410e4045a8ac47bf72f802ce93e562948b00848
+73f33f872340b4930954a97ae25e9c74677117ebbacc18e5cf9da28961e6
+442c545f7ee10d0689cad67b5e7e9abcbad934672e013a622bcde541a2ba
+ea62f957c199fc3eeb1bb8091ed8ac159f5afb61d35893afbaa5883c5a97
+b0dab2b2c4ba2ff7a30935882011248f8d9e6d23b4a3d91a71df66c0398c
+65be4cc71cba58bd19cbc9d5f7bdb30dfe9fa814c9d8b505b2bc3098a220
+4c5d35f353e66576e032fc0d23d2a2d49ed27d4ea0e4e0c17e6cfce3cc97
+470e9292faeda13b6647da7c64c7a717620980de1323c6040fb8f22e2537
+240422e2248bef0dcce6fc223b8720fc9dfe3c47809b31fddf8079d638f8
+690f441eea511b9cf818fbe872ff3e2a0a2950f9acdbb88d48b9d7648091
+5b0dd985074c0429e9f4ec356c6d1f418096ead18cb7669dce76e8b21a6b
+0cf19dbaf1e79e2c70a1888ffcae76174518c355c3f733b6d051d9371b79
+6908c09ba1cb9fe3c7e16e4529912126b5253eff6acecda3c37fccc761f9
+d781f0c75eb7075c121c68540706958e26166e19e1c0b29ee08d2c2382f9
+9ac70ee4ee4a6296a4ffec552f3db6471aa42d3b38857223fe511d0aa35a
+84b1c1205a304b2d0bfc95fffbd603e8e6f42e60017a2808babe00c270ce
+ba6f93b83bb9c41c7787992734171fc2a4f0b46f06c6f029c82ccc985b7c
+3c84ea655478ff79e8ab8fe6cce591ecb39c353a
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
diff --git a/install-sh b/install-sh
new file mode 100755
index 000000000..398a88e14
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ :
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=$mkdirprog
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ :
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ :
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ :
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+ '
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ :
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ :
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/locale/C/cups_C b/locale/C/cups_C
new file mode 100644
index 000000000..85cd4e261
--- /dev/null
+++ b/locale/C/cups_C
@@ -0,0 +1,135 @@
+iso-8859-1
+OK
+Cancel
+Help
+Quit
+Close
+Yes
+No
+On
+Off
+Save
+Discard
+Default
+Options
+More Info
+Black
+Color
+Cyan
+Magenta
+Yellow
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+General
+Printer
+Image
+HP-GL/2
+Extra
+Document
+Other
+Print Pages:
+Entire Document
+Page Range:
+Reverse Order:
+Page Format:
+ 1-Up
+ 2-Up
+ 4-Up
+Image Scaling:
+Use Natural Image Size
+Zoom by Percent
+Zoom by PPI
+Mirror Image:
+Color Saturation:
+Color Hue:
+Fit to Page:
+Shading:
+Pen Width:
+Gamma Correction:
+Brightness:
+Add
+Delete
+Modify
+Printer URI
+Printer Name
+Printer Location
+Printer Info
+Printer Make and Model
+Device URI
+Formatting Page
+Printing Page
+Initializing Printer
+Printer State
+Accepting Jobs
+Not Accepting Jobs
+Print Jobs
+Class
+Local
+Remote
+Duplexing
+Stapling
+Fast Copies
+Collated Copies
+Hole Punching
+Covering
+Binding
+Sorting
+Small (up to 9.5x14in)
+Medium (9.5x14in to 13x19in)
+Large (13x19in and larger)
+Custom Size
+Idle
+Processing
+Stopped
+All
+Odd
+Even
+Darker Lighter
+Media Size
+Media Type
+Media Source
+Orientation:
+Portrait
+Landscape
+Job State
+Job Name
+User Name
+Priority
+Copies
+File Size
+Pending
+Output Mode
+Resolution
+Text
+Pretty Print
+Margins
+Left
+Right
+Bottom
+Top
+Filename(s)
+Print
+Options Installed
+Auto
+400 Your browser sent a request that this server could not understand.
+This server could not verify that you are authorized to access the resource.
+You must pay to access this server.
+You don't have permission to access the resource on this server.
+The requested resource was not found on this server.
+The requested method is not allowed with the resource.
+An appropriate representation for the resource was not found on this server.
+You don't have permission to use this server as a proxy host.
+The request has taken too long to complete and has been aborted.
+The requested resource has more than one value.
+The requested resource is gone and has not been replaced.
+The requested method requires a valid Content-Length.
+The precondition on the request evaluated to false.
+The request is too large for this server to process.
+The request URI is too large for this server to process.
+The request format is not understood by this server.
+426 An upgrade to a secure connection is required. If you are seeing this message in a web browser then it does not support HTTP encryption upgrades.
+500 The server has detected an unrecoverable error and cannot process your request.
+The requested method is not implemented by this server.
+The proxy server received an invalid response from an upstream server.
+The requested resource is currently unavailable on this server.
+The proxy server has taken too long to respond to this server.
+This server does not support the HTTP version required by your browser.
diff --git a/locale/Makefile b/locale/Makefile
new file mode 100644
index 000000000..3ded23f21
--- /dev/null
+++ b/locale/Makefile
@@ -0,0 +1,77 @@
+#
+# "$Id$"
+#
+# Locale file makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+#
+# Locales...
+#
+
+LOCALES = C be cs de en es fr he it ru_RU.koi8r ru_RU.cp1251 \
+ sv uk uk_UA.cp1251 zh_CN
+
+
+#
+# Make everything...
+#
+
+all: translate
+
+
+#
+# Clean all config and object files...
+#
+
+clean:
+
+
+#
+# Install files...
+#
+
+install:
+ $(INSTALL_DIR) $(LOCALEDIR)
+ for dir in $(LOCALES) ; do \
+ $(INSTALL_DIR) $(LOCALEDIR)/$$dir ; \
+ $(INSTALL_DATA) $$dir/cups_$$dir $(LOCALEDIR)/$$dir ; \
+ done
+
+
+#
+# translate - a simple utility to use Bablefish to translate the POSIX message
+# file to one of several languages.
+#
+# translate outfile language
+#
+
+translate: translate.o ../cups/$(LIBCUPS)
+ echo Linking $<...
+ $(CC) $(LDFLAGS) -o translate translate.o $(LIBS)
+
+translate.o: ../cups/http.h
+
+
+#
+# End of "$Id$".
+#
diff --git a/locale/be/cups_be b/locale/be/cups_be
new file mode 100644
index 000000000..102b2786b
--- /dev/null
+++ b/locale/be/cups_be
@@ -0,0 +1,134 @@
+windows-1251
+OK
+Cancel
+Help
+Quit
+Close
+Yes
+No
+On
+Off
+Save
+Discard
+Default
+Options
+More Info
+Black
+Colour
+Cyan
+Magenta
+Yellow
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+General
+Printer
+Image
+HP-GL/2
+Extra
+Document
+Other
+Print Pages:
+Entire Document
+Page Range:
+Reverse Order:
+Page Format:
+ 1-Up
+ 2-Up
+ 4-Up
+Image Scaling:
+Use Natural Image Size
+Zoom by Percent
+Zoom by PPI
+Mirror Image:
+Colour Saturation:
+Colour Hue:
+Fit to Page:
+Shading:
+Pen Width:
+Gamma Correction:
+Brightness:
+Add
+Delete
+Modify
+Printer URI
+Printer Name
+Printer Location
+Printer Info
+Printer Make and Model
+Device URI
+Formatting Page
+Printing Page
+Initializing Printer
+Printer State
+Accepting Jobs
+Not Accepting Jobs
+Print Jobs
+Class
+Local
+Remote
+Duplexing
+Stapling
+Fast Copies
+Collated Copies
+Hole Punching
+Covering
+Binding
+Sorting
+Small (up to 9.5x14in)
+Medium (9.5x14in to 13x19in)
+Large (13x19in and larger)
+Custom Size
+Idle
+Processing
+Stopped
+All
+Odd
+Even
+Darker Lighter
+Media Size
+Media Type
+Media Source
+Orientation:
+Portrait
+Landscape
+Job State
+Job Name
+User Name
+Priority
+Copies
+File Size
+Pending
+Output Mode
+Resolution
+Text
+Pretty Print
+Margins
+Left
+Right
+Bottom
+Top
+Filename(s)
+Print
+Options Installed
+Auto
+400 Your browser sent a request that this server could not understand.
+This server could not verify that you are authorized to access the resource.
+You must pay to access this server.
+You don't have permission to access the resource on this server.
+The requested resource was not found on this server.
+The requested method is not allowed with the resource.
+An appropriate representation for the resource was not found on this server.
+You don't have permission to use this server as a proxy host.
+The request has taken too long to complete and has been aborted.
+The requested resource has more than one value.
+The requested resource is gone and has not been replaced.
+The requested method requires a valid Content-Length.
+The precondition on the request evaluated to false.
+The request is too large for this server to process.
+The request URI is too large for this server to process.
+The request format is not understood by this server.
+500 The server has detected an unrecoverable error and cannot process your request.
+The requested method is not implemented by this server.
+The proxy server received an invalid response from an upstream server.
+The requested resource is currently unavailable on this server.
+The proxy server has taken too long to respond to this server.
+This server does not support the HTTP version required by your browser.
diff --git a/locale/cs/cups_cs b/locale/cs/cups_cs
new file mode 100644
index 000000000..c35fd7c55
--- /dev/null
+++ b/locale/cs/cups_cs
@@ -0,0 +1,135 @@
+iso-8859-2
+OK
+Zru¹it
+Nápovìda
+Ukonèit
+Zavøít
+Ano
+Ne
+Zap
+Vyp
+UloŸit
+Zahodit
+Výchozí
+MoŸnosti
+Více informací
+Èerná
+Barva
+Azurová
+Purpurová
+®lutá
+Copyright 1993-2002 Easy Software Products, v¹echna práva vyhrazena.
+Obecné
+Tiskárna
+Obrázek
+HP-GL/2
+Extra
+Dokument
+Ostatní
+Vytisknout stránky:
+Celý dokument
+Rozsah stránek:
+Obrácené poøadí:
+Formát stránky:
+ 1-Up
+ 2-Up
+ 4-Up
+Zvìt¹ení obrázku:
+PouŸít pøirozenou velikost
+Zvìt¹it podle procent
+Zvìt¹it podle PPI
+Zrcadlit obrázek:
+Barevné nasycení:
+Svìtlost:
+Pøizpùsobit stránce:
+Stínování:
+©íøka pera:
+Gamma korekce:
+Jas:
+Pøidat
+Smazat
+Zmìnit
+URI tiskárny
+Název tiskárny
+Umístìní tiskárny
+Info o tiskárnì
+Model tiskárny
+URI zaøízení
+Formátuji stránku
+Tisknu stránku
+Inicializuji tiskárnu
+Stav tiskárny
+Pøijímá úlohy
+Nepøijímá úlohy
+Vytisknout úlohy
+Tøída
+Lokální
+Vzdálená
+Duplexní
+Se¹ití
+Rychlé kopie
+Srovnané kopie
+Dìrování
+Obal
+Vazba
+Tøídìní
+Malé (aŸ do 9.5x14in)
+Støední (od 9.5x14in do 13x19in)
+Velké (13x19in a vìt¹í)
+Vlastní velikost
+Neèinná
+Probíhá zpracování
+Zastaveno
+V¹e
+Liché
+Sudé
+Svìtlej¹í Tmavìj¹í
+Velikost média
+Typ média
+Zdroj média
+Orientace:
+Portrét
+Krajina
+Stav úlohy
+Název úlohy
+UŸivatelské jméno
+Priorita
+Kopie
+Velikost souboru
+Nevyøízená
+Výstupní reŸim
+Rozli¹ení
+Text
+Hezký tisk
+Okraje
+Vlevo
+Vpravo
+Dole
+Nahoøe
+Soubor(y)
+Tisk
+Options Installed
+Auto
+400 Vá¹ prohlíŸeè odeslal poŸadavek, kterému tento server nerozumí.
+Server nemohl ovìøit, zda máte oprávnìní pøistupovat k tomuto zdroji.
+Pøístup k tomuto serveru je placený.
+Nemáte oprávnìní pøistupovat k tomuto zdroji.
+PoŸadovaný zdroj nebyl nalezen na tomto serveru.
+PoŸadovaná metoda není pøípustná.
+Odpovídající reprezentace zdroje nebyla nalezena.
+Nemáte oprávnìní pouŸívat tento server jako proxy hostitele.
+PoŸadavek zabral pøíli¹ mnoho èasu a byl pøeru¹en.
+PoŸadovaný zdroj má více neŸ jednu hodnotu.
+PoŸadovaný zdroj byl zru¹en bez náhrady.
+PoŸadovaná metoda vyŸaduje platné pole Content-Length.
+Podmínka tohoto poŸadavku byla vyhodnocena zápornì.
+PoŸadavek je pro tento server pøíli¹ velký ke zpracování.
+URI poŸadavku je pro tento server pøíli¹ velké ke zpracování.
+Formát poŸadavku nebyl serverem pochopen.
+426 Je vyŸadována aktualizace na zabezpeèený protokol. Vidíte-li tuto zprávu ve WWW prohlíŸeèi, znamená to, Ÿe není podporován.
+500 Server narazil na kritickou chybu a nemùŸe pokraèovat ve zpracování poŸadavku.
+PoŸadovaná metoda není implementována.
+Proxy server obdrŸel neplatnou odpovìï od nadøazeného serveru.
+PoŸadovaný zdroj je momentálnì nedostupný.
+Proxy server zabral pøíli¹ mnoho èasu na odpovìï tomuto serveru.
+Tento server nepodporuje HTTP ve verzi, kterou poŸaduje vá¹ prohlíŸeè.
diff --git a/locale/de/cups_de b/locale/de/cups_de
new file mode 100644
index 000000000..62f7aefd5
--- /dev/null
+++ b/locale/de/cups_de
@@ -0,0 +1,136 @@
+iso-8859-1
+Okay
+Abbrechen
+Hilfe
+Beenden
+Schließen
+Ja
+Nein
+An
+Aus
+Speichern
+Verwerfen
+Default
+Optionen
+Mehr Info
+Schwarz
+Farbe
+Cyan
+Magenta
+Gelb
+Copyright 1993-2002 durch Easy Software Products, alle Rechte vorbehalten.
+Allgemein
+Drucker
+Bild
+HP-GL/2
+Speziell
+Dokument
+Andere
+Druckbereich:
+Gesamtes Dokument
+Seitenbereich:
+Umgedrehte Reihenfolge:
+Seitenformat:
+ normal
+ 2 auf 1
+ 4 auf 1
+Bild-Skalierung:
+Natürliche Bildgröße
+Zoom in Prozent
+Zoom in PPI
+Gespiegelte Ausgabe:
+Farbsättigung:
+Farbton:
+Auf Seite anpassen:
+Schattiert:
+Strichstärke:
+Gamma-Korrektur:
+Helligkeit:
+Hinzufügen
+Löschen
+Ändern
+Drucker-URI
+Drucker-Name
+Drucker-Standort
+Drucker-Info
+Drucker-Modell
+Device-URI
+Formatiere Seite
+Drucke Seite
+Initialisiere Drucker
+Drucker-Zustand
+Bereit
+Nicht bereit
+Druckaufträge
+Klasse
+Lokal
+Remote
+Duplex
+Hefter
+Schnellkopien
+Sortieren/Gruppieren
+Locher
+Deckblatt
+Bindung
+Sortieren
+Klein (bis 14x35cm)
+Medium (14x35cm bis 33x48cm)
+Groß (33x48cm und größer)
+Benutzerspezifische Größe
+Leerlauf
+In Arbeit
+Gestoppt
+Alles
+Ungerade
+Gerade
+Dunkler Heller
+Medien-Größe
+Medium
+Medien-Quelle
+Ausrichtung:
+Hochformat
+Querformat
+Job-Status
+Job-Name
+Benutzername
+Priorität
+Kopien
+Dateigröße
+In Warteposition
+Ausgabe-Modus
+Auflösung
+Text
+Spezieller Druck
+Seitenränder
+Links
+Recht
+Unterseite
+Oberseite
+Dateiname(s)
+Druker
+Installierte Optionen
+Automatisch
+400 Der Server versteht die Anfrage Ihres Browsers nicht.
+Der Server konnte nicht Ihre Berechtigung überprüfen, diese Ressource zu benutzen.
+Sie müssen bezahlen, um auf diesen Server zuzugreifen.
+Sie sind nicht berechtigt, auf diese Ressource des Servers zuzugreifen.
+Die gewünschte Ressource wurde auf diesem Server nicht gefunden.
+Die gewünschte Methode ist mit dieser Ressource nicht erlaubt.
+Eine passende Art der Ressource wurde auf diesem Server nicht gefunden.
+Sie können diesen Server nicht als Proxy-Server verwenden.
+Der Auftrag brauchte zu lang zur Beendigung und wurde abgebrochen.
+Die gewünschte Ressource besitzt mehr als einen Wert.
+Die gewünschte Ressource existiert nicht mehr und wurde nicht ersetzt.
+Die gewünschte Methode benötigt eine gültige Länge des Inhalts.
+Die Voraussetzungen für den Auftrag sind nicht erfüllt.
+Der Auftrag ist zu groß, um auf diesem Server verarbeitet zu werden.
+Die URI des Auftrags ist zu groß, um auf diesem Server verarbeitet zu werden.
+Das Format des Auftrags wird von diesem Server nicht verstanden.
+426 An upgrade to a secure connection is required. If you are seeing this message in a web browser then it does not support HTTP encryption upgrades.
+500 Der Server hat einen nicht behebbaren Fehler entdeckt und kann Ihren Auftrag nicht verarbeiten.
+Die gewünschte Methode ist auf diesen Server nicht implementiert.
+Der Proxy-Server empfing eine unzulässige Antwort von einem höheren Server.
+Die gewünschte Ressource ist aktuell auf diesem Server nicht verfügbarr.
+Der Proxy-Server braucht zu lang, um auf diesen Server zu reagieren.
+Dieser Server unterstützt nicht die HTTP-Version, die Ihr Browser benötigt.
+
diff --git a/locale/en/cups_en b/locale/en/cups_en
new file mode 100644
index 000000000..f73a2e504
--- /dev/null
+++ b/locale/en/cups_en
@@ -0,0 +1,135 @@
+iso-8859-1
+OK
+Cancel
+Help
+Quit
+Close
+Yes
+No
+On
+Off
+Save
+Discard
+Default
+Options
+More Info
+Black
+Colour
+Cyan
+Magenta
+Yellow
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+General
+Printer
+Image
+HP-GL/2
+Extra
+Document
+Other
+Print Pages:
+Entire Document
+Page Range:
+Reverse Order:
+Page Format:
+ 1-Up
+ 2-Up
+ 4-Up
+Image Scaling:
+Use Natural Image Size
+Zoom by Percent
+Zoom by PPI
+Mirror Image:
+Colour Saturation:
+Colour Hue:
+Fit to Page:
+Shading:
+Pen Width:
+Gamma Correction:
+Brightness:
+Add
+Delete
+Modify
+Printer URI
+Printer Name
+Printer Location
+Printer Info
+Printer Make and Model
+Device URI
+Formatting Page
+Printing Page
+Initializing Printer
+Printer State
+Accepting Jobs
+Not Accepting Jobs
+Print Jobs
+Class
+Local
+Remote
+Duplexing
+Stapling
+Fast Copies
+Collated Copies
+Hole Punching
+Covering
+Binding
+Sorting
+Small (up to 9.5x14in)
+Medium (9.5x14in to 13x19in)
+Large (13x19in and larger)
+Custom Size
+Idle
+Processing
+Stopped
+All
+Odd
+Even
+Darker Lighter
+Media Size
+Media Type
+Media Source
+Orientation:
+Portrait
+Landscape
+Job State
+Job Name
+User Name
+Priority
+Copies
+File Size
+Pending
+Output Mode
+Resolution
+Text
+Pretty Print
+Margins
+Left
+Right
+Bottom
+Top
+Filename(s)
+Print
+Options Installed
+Auto
+400 Your browser sent a request that this server could not understand.
+This server could not verify that you are authorized to access the resource.
+You must pay to access this server.
+You don't have permission to access the resource on this server.
+The requested resource was not found on this server.
+The requested method is not allowed with the resource.
+An appropriate representation for the resource was not found on this server.
+You don't have permission to use this server as a proxy host.
+The request has taken too long to complete and has been aborted.
+The requested resource has more than one value.
+The requested resource is gone and has not been replaced.
+The requested method requires a valid Content-Length.
+The precondition on the request evaluated to false.
+The request is too large for this server to process.
+The request URI is too large for this server to process.
+The request format is not understood by this server.
+426 An upgrade to a secure connection is required. If you are seeing this message in a web browser then it does not support HTTP encryption upgrades.
+500 The server has detected an unrecoverable error and cannot process your request.
+The requested method is not implemented by this server.
+The proxy server received an invalid response from an upstream server.
+The requested resource is currently unavailable on this server.
+The proxy server has taken too long to respond to this server.
+This server does not support the HTTP version required by your browser.
diff --git a/locale/es/cups_es b/locale/es/cups_es
new file mode 100644
index 000000000..b5b514d8d
--- /dev/null
+++ b/locale/es/cups_es
@@ -0,0 +1,135 @@
+iso-8859-1
+OK
+Cancel
+Ayuda
+Salido
+Cercano
+Sí
+No
+En
+De
+Excepto
+Descarte
+Valor por defecto
+Opciones
+Más Info
+Negro
+Color
+Ciánico
+Magenta
+Amarillo
+El copyright 1993-2002 por Easy Software Products, todos endereza reservado.
+General
+Impresora
+Imagen
+HP-GL/2
+Suplemento
+Documento
+Otro
+Paginaciones De la Impresión:
+Entero Documento
+Rango De Paginación:
+Orden Reversa:
+Formato De la Paginación:
+ 1-Up
+ 2-Up
+ 4-Up
+Escalamiento De la Imagen:
+Talla Natural De la Imagen Del Uso
+Zoom de Percent
+Zoom de PPI
+Imagen Del Espejo:
+Saturación Del Color:
+Tonalidad Del Color:
+Quepa para paginar:
+Sombreando:
+Anchura De la Pluma:
+Corrección Gamma:
+Brillo:
+Agregue
+Cancelación
+Modifiqúese
+URI De la Impresora
+Nombre De la Impresora
+Localización De la Impresora
+Impresora Info
+La impresora hace y modela
+URI Del Dispositivo
+Paginación Del Formato
+Imprimiendo La Paginación
+De Incialización Impresora
+Estado De la Impresora
+Validando Trabajos
+No validando Trabajos
+Trabajos De Impresión
+Clase
+Local
+Telecontrol
+Duplexing
+Sujetando con grapa
+Rápidas Copias
+Clasificadas Copias
+Perforación Del Agujero
+Cubierta
+Atando
+Clasificando
+Pequeño (los hasta 9.5x14in)
+Media (los 9.5x14in a el 13x19in)
+Grande (el 13x19in y más grande)
+De encargo Talla
+Marcha lenta
+Procesando
+Parado
+Todo
+Impar
+Par
+Más Oscuro Más Brillante
+Talla De Media
+Tipo De Media
+Fuente De los Media
+Orientación:
+Retrato
+Paisaje
+Estatus del trabajo
+Nombre del trabajo
+Nombre del utilizador
+Prioridad
+Copias
+Tamaño
+Pendiente
+Modo de impresión
+Resolución
+Texto
+Especial impresión
+Márgenes
+Izquierda
+La derecha
+Fondo
+Tapa
+Nombre(s)
+Impresión
+Opciones instaladas
+Automático
+400 Su browser envió una petición que este servidor no podría entender.
+Este servidor no podría verificar que le autoricen a tener acceso al recurso.
+Usted debe pagar tener acceso a este servidor.
+Usted no tiene permiso de tener acceso al recurso en este servidor.
+El recurso solicitado no fue encontrado en este servidor.
+El método solicitado no se permite con el recurso.
+Una representación apropiada para el recurso no fue encontrada en este servidor.
+Usted no tiene permiso de utilizar este servidor como ordenador principal del poder.
+La petición ha durado demasiado para terminar y se ha abortado.
+El recurso solicitado tiene más de un valor.
+Se va y no se ha substituido el recurso solicitado.
+El método solicitado requiere un Content-Length válido.
+La condición previa en la petición evaluó a falso.
+La petición es demasiado grande para que este servidor procese.
+El URI de la petición es demasiado grande para que este servidor procese.
+El formato de la petición no es entendido por este servidor.
+426 An upgrade to a secure connection is required. If you are seeing this message in a web browser then it does not support HTTP encryption upgrades.
+500 El servidor ha detectado un error irrecuperable y no puede procesar su petición.
+El método solicitado no es puesto en ejecución por este servidor.
+El proxy server recibió una respuesta inválida de un servidor por aguas arriba.
+El recurso solicitado es actualmente inasequible en este servidor.
+El proxy server ha durado demasiado para responder a este servidor.
+Este servidor no utiliza la versión del HTTP requerida por su browser.
diff --git a/locale/fr/cups_fr b/locale/fr/cups_fr
new file mode 100644
index 000000000..f16fa9a30
--- /dev/null
+++ b/locale/fr/cups_fr
@@ -0,0 +1,135 @@
+iso-8859-1
+OK
+Annulation
+Aide
+Quitter
+Fermer
+Oui
+Non
+Oui
+Non
+Sauver
+Quitter
+Standard
+Options
+Plus d'informations
+Noir
+Couleur
+Cyan
+Magenta
+Jaune
+Copyright 1993-2002 par Easy Software Products, tous droits réservés.
+Général
+Imprimante
+Image
+HP-GL/2
+Options supplémentaires
+Document
+Autre
+Pages d'impression:
+Document entier
+Plage de pages
+Ordre inverse:
+Pages par feuille:
+ 1
+ 2
+ 4
+Echelle de l'image:
+Utiliser taille normale d'image
+Pourcentage zoom
+Zoom par PPI
+Retournement image:
+Saturation de couleur:
+Teinte:
+Adapter à la page:
+Shading:
+Largeur de tracé:
+Correction Gamma:
+Luminosité:
+Ajouter
+Effacer
+Modifier
+URI de l'imprimante
+Nom de l'imprimante
+Emplacement de l'imprimante
+Information de l'imprimante
+Type et modèle de l'imprimante
+URI de périphérique
+Formatage de la page
+Impression de la page
+Initialisation de l'imprimante
+Etat de l'imprimante
+Accepte les travaux
+Rejette les Travaux
+Travaux d'impression
+Classes
+Locale
+A distance
+Recto-verso
+Agrafage
+Copies rapides
+Copies assemblées
+Perforation
+Couverture
+Reliure
+Tri
+Petit (jusqu'à 9.5x1pouce)
+Moyen (9.5x1pouce à 13x19pouce)
+Grand (13x19pouce et plus grand)
+Taille personnalisée
+Au repos
+En fonctionnement
+Arrêté
+Tout
+Impair
+Pair
+Plus foncé Plus clair
+Dimensions du support
+Type de support
+Source des supports
+Orientation:
+Portrait
+Paysage
+État du travail
+Nom du travail
+Nom de l'utilisateur
+Priorité
+Copies
+Taille du fichier
+En attente de traitement
+Mode de sortie
+Résolution
+Texte
+Impression améliorée
+Marge
+Gauche
+Droite
+Bas
+Haut
+Nom fichier(s)
+Imprimer
+Options installées
+Automatique
+400 Votre navigateur a envoyé une demande que ce serveur ne pouvait pas comprendre.
+Ce serveur n'a pas pu vérifier que vous êtes autorisé(e) à utiliser la ressource.
+Vous devez payer pour accéder à ce serveur.
+Vous n'avez pas la permission d'utiliser la ressource sur ce serveur.
+La ressource demandée n'a pas été trouvée sur ce serveur.
+La méthode demandée n'est pas autorisée avec cette ressource.
+Une représentation appropriée pour la ressource n'a pas été trouvée sur ce serveur.
+Vous n'avez pas la permission d'utiliser ce serveur comme serveur d'impression mandataire (proxy).
+La demande a mis trop de temps à se terminer et a été interrompue.
+La ressource demandée a plus d'une valeur.
+La ressource demandée a disparu et n'a pas été remplacée.
+La méthode demandée exige un attribut Content-Length contenant une valeur correcte.
+La condition préalable sur la demande a donné un résultat à la valeur "faux".
+La demande est trop grosse pour ce serveur.
+L'Uri de demande est trop grande pour être traitée par ce serveur.
+Le format de demande n'est pas compris par ce serveur.
+426 Une mise à jour de connexion sécurisée est nécessaire, si vous voyez ce message dans votre navigateur "web", celui-ci ne prend pas en charge les mises à jour d'encryptage HTTP.
+500 Le serveur a détecté une erreur irrémédiable et ne peut pas traiter votre demande.
+La méthode demandée n'est pas prise en charge par ce serveur.
+Le serveur mandataire (proxy) a reçu une réponse incorrecte d'un serveur ascendant.
+La ressource demandée est actuellement indisponible sur ce serveur.
+Le serveur mandataire (proxy) a pris trop longtemps pour répondre à ce serveur.
+Ce serveur ne supporte pas la version de HTTP exigée par votre navigateur.
diff --git a/locale/he/cups_he b/locale/he/cups_he
new file mode 100644
index 000000000..139993ea3
--- /dev/null
+++ b/locale/he/cups_he
@@ -0,0 +1,135 @@
+iso-8859-8
+OK
+Cancel
+Help
+Quit
+Close
+Yes
+No
+On
+Off
+Save
+Discard
+Default
+Options
+More Info
+Black
+Colour
+Cyan
+Magenta
+Yellow
+Copyright 1993-2001 by Easy Software Products, All Rights Reserved.
+General
+Printer
+Image
+HP-GL/2
+Extra
+Document
+Other
+Print Pages:
+Entire Document
+Page Range:
+Reverse Order:
+Page Format:
+ 1-Up
+ 2-Up
+ 4-Up
+Image Scaling:
+Use Natural Image Size
+Zoom by Percent
+Zoom by PPI
+Mirror Image:
+Colour Saturation:
+Colour Hue:
+Fit to Page:
+Shading:
+Pen Width:
+Gamma Correction:
+Brightness:
+Add
+Delete
+Modify
+Printer URI
+Printer Name
+Printer Location
+Printer Info
+Printer Make and Model
+Device URI
+Formatting Page
+Printing Page
+Initializing Printer
+Printer State
+Accepting Jobs
+Not Accepting Jobs
+Print Jobs
+Class
+Local
+Remote
+Duplexing
+Stapling
+Fast Copies
+Collated Copies
+Hole Punching
+Covering
+Binding
+Sorting
+Small (up to 9.5x14in)
+Medium (9.5x14in to 13x19in)
+Large (13x19in and larger)
+Custom Size
+Idle
+Processing
+Stopped
+All
+Odd
+Even
+Darker Lighter
+Media Size
+Media Type
+Media Source
+Orientation:
+Portrait
+Landscape
+Job State
+Job Name
+User Name
+Priority
+Copies
+File Size
+Pending
+Output Mode
+Resolution
+Text
+Pretty Print
+Margins
+Left
+Right
+Bottom
+Top
+Filename(s)
+Print
+Options Installed
+Auto
+400 Your browser sent a request that this server could not understand.
+This server could not verify that you are authorized to access the resource.
+You must pay to access this server.
+You don't have permission to access the resource on this server.
+The requested resource was not found on this server.
+The requested method is not allowed with the resource.
+An appropriate representation for the resource was not found on this server.
+You don't have permission to use this server as a proxy host.
+The request has taken too long to complete and has been aborted.
+The requested resource has more than one value.
+The requested resource is gone and has not been replaced.
+The requested method requires a valid Content-Length.
+The precondition on the request evaluated to false.
+The request is too large for this server to process.
+The request URI is too large for this server to process.
+The request format is not understood by this server.
+426 An upgrade to a secure connection is required. If you are seeing this message in a web browser then it does not support HTTP encryption upgrades.
+500 The server has detected an unrecoverable error and cannot process your request.
+The requested method is not implemented by this server.
+The proxy server received an invalid response from an upstream server.
+The requested resource is currently unavailable on this server.
+The proxy server has taken too long to respond to this server.
+This server does not support the HTTP version required by your browser.
diff --git a/locale/it/cups_it b/locale/it/cups_it
new file mode 100644
index 000000000..dc1663a3f
--- /dev/null
+++ b/locale/it/cups_it
@@ -0,0 +1,135 @@
+iso-8859-1
+Continua
+Annulla
+Aiuto
+Esci
+Chiudi
+Sì
+No
+Attivo
+Inattivo
+Salva
+Abbandona
+Predefinito
+Opzioni
+Maggiori informazioni
+Nero
+Colore
+Ciano
+Fucsia
+Giallo
+Copyright 1993-2002 Easy Software Products, tutti i diritti riservati.
+Generale
+Stampante
+Immagini
+HP-GL/2
+Extra
+Documento
+Altro
+Stampa delle pagine:
+Intero Documento
+Stampa intervallo:
+Ordine inverso:
+Formato della pagina:
+ 1-Up
+ 2-Up
+ 4-Up
+Dimensione dell'immagine:
+Usa dimensione originale dell'immagine
+Zoom in percentuale
+Zoom in PPI
+Immagine riflessa:
+Saturazione del colore:
+Tonalità del colore:
+Adatta alla pagina:
+Ombreggiatura:
+Larghezza della penna:
+Correzione gamma:
+Luminosità:
+Aggiungi
+Cancella
+Modifica
+URI della stampante
+Nome della stampante
+Collocazione della stampante
+Informazioni sulla stampante
+Produttore e modello della stampante
+URI del dispositivo
+Preparazione della pagina
+Stampa della pagina
+Inizializzazione della stampante
+Stato della stampante
+Accettazione dei lavori di stampa abilitata
+Accettazione dei lavori di stampa disabilitata
+Richieste di stampa
+Categoria
+Locale
+Remoto
+Fronte-retro
+Spillatura in corso
+Copie veloci
+Copie fascicolate
+Perforazione delle pagine (per fascicolatura)
+Inserimento copertina in corso
+Fascicolatura in corso
+Ordinamento in corso
+Piccolo (fino a 9.5x14")
+Medio (da 9.5x14" a 13x19")
+Grande (13x19" o maggiore)
+Formato personalizzato
+In attesa
+In elaborazione
+Fermo
+Tutto
+Dispari
+Pari
+Più scuro Più chiaro
+Formato del supporto
+Tipo del supporto
+Sorgente del supporto
+Orientamento:
+Verticale
+Orizzontale
+Stato del processo
+Nome del processo
+Nome dell'utente
+Priorità
+Copie
+Dimensioni del file
+In attesa
+Modo stampa
+Risoluzione
+Testo
+Stampa di qualità
+Margini
+Sinistro
+Destro
+Inferiore
+Superiore
+Nome/i file
+Stampa
+Opzioni installate
+Automatico
+400 Il vostro browser ha inviato una richiesta che non può essere eseguita su questo server.
+Questo server non ha potuto verificare la vostra autorizzazione ad accedere alla risorsa.
+L'accesso a questo servizio è a pagamento.
+Non avete il permesso di accedere alla risorsa richiesta su questo server.
+La risorsa richiesta non è disponibile su questo server.
+Il metodo richiesto non è consentito con la risorsa selezionata.
+Una rappresentazione adatta per la risorsa non è disponibile su questo server.
+Non avete il permesso utilizzare questo server come proxy.
+La richiesta ha impiegato troppo tempo per essere completata ed è stata annullata.
+La risorsa richiesta ha più di un valore.
+La risorsa richiesta non è più disponibile e non è stata ancora sostituita.
+Il metodo chiesto richiede un campo "Content-Length" valido.
+I prerequisiti per la richiesta non possono essere soddisfatti.
+La richiesta è troppo grande per essere eseguita da questo server.
+L'URI richiesta è troppo grande per essere eseguita da questo server.
+Il formato della richiesta non è valido su questo server.
+426 È richiesto il passaggio ad una connessione sicura. Se state leggendo questo messaggio nella finestra del vostro browser web vuol dire che non è in grado di supportare il funzionamento con HTTP crittografato.
+500 Il server ha rilevato un errore non recuperabile e non può eseguire la vostra richiesta.
+Il metodo richiesto non è implementato da questo server.
+Il proxy server ha ricevuto una risposta non valida da un server di livello superiore.
+La risorsa richiesta non è attualmente disponibile su questo server.
+Il proxy server ha impiegato troppo tempo per rispondere a questo server.
+Questo server non supporta la versione HTTP richiesta dal vostro browser.
diff --git a/locale/locale.txt b/locale/locale.txt
new file mode 100644
index 000000000..f9abe72d6
--- /dev/null
+++ b/locale/locale.txt
@@ -0,0 +1,32 @@
+This directory contains the message strings used by CUPS for various
+languages. Each subdirectory corresponds to a different locale, and
+the cups_xx and cups_xx_YY files contain the messages for the locales
+named "xx" or "xx_YY".
+
+Each message file starts with a character set identifier, which can be
+one of the following:
+
+ us-ascii
+ iso-8859-1
+ iso-8859-2
+ iso-8859-3
+ iso-8859-4
+ iso-8859-5
+ iso-8859-6
+ iso-8859-7
+ iso-8859-8
+ iso-8859-9
+ utf-8
+
+After that, all non-blank lines are treated as messages, with any
+leading whitespace removed. If a line starts with a number then the
+message index is updated to the number. Otherwise, the next message
+number is used.
+
+The message indices are defined in the include file <cups/language.h>.
+The HTTP status messages use the status codes defined in <cups/http.h>.
+
+If you would like to contribute a new message file for your locale, or
+have corrections to the current ones, please send them to:
+
+ cups-support@cups.org
diff --git a/locale/ru_RU.cp1251/cups_ru_RU.cp1251 b/locale/ru_RU.cp1251/cups_ru_RU.cp1251
new file mode 100644
index 000000000..102b2786b
--- /dev/null
+++ b/locale/ru_RU.cp1251/cups_ru_RU.cp1251
@@ -0,0 +1,134 @@
+windows-1251
+OK
+Cancel
+Help
+Quit
+Close
+Yes
+No
+On
+Off
+Save
+Discard
+Default
+Options
+More Info
+Black
+Colour
+Cyan
+Magenta
+Yellow
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+General
+Printer
+Image
+HP-GL/2
+Extra
+Document
+Other
+Print Pages:
+Entire Document
+Page Range:
+Reverse Order:
+Page Format:
+ 1-Up
+ 2-Up
+ 4-Up
+Image Scaling:
+Use Natural Image Size
+Zoom by Percent
+Zoom by PPI
+Mirror Image:
+Colour Saturation:
+Colour Hue:
+Fit to Page:
+Shading:
+Pen Width:
+Gamma Correction:
+Brightness:
+Add
+Delete
+Modify
+Printer URI
+Printer Name
+Printer Location
+Printer Info
+Printer Make and Model
+Device URI
+Formatting Page
+Printing Page
+Initializing Printer
+Printer State
+Accepting Jobs
+Not Accepting Jobs
+Print Jobs
+Class
+Local
+Remote
+Duplexing
+Stapling
+Fast Copies
+Collated Copies
+Hole Punching
+Covering
+Binding
+Sorting
+Small (up to 9.5x14in)
+Medium (9.5x14in to 13x19in)
+Large (13x19in and larger)
+Custom Size
+Idle
+Processing
+Stopped
+All
+Odd
+Even
+Darker Lighter
+Media Size
+Media Type
+Media Source
+Orientation:
+Portrait
+Landscape
+Job State
+Job Name
+User Name
+Priority
+Copies
+File Size
+Pending
+Output Mode
+Resolution
+Text
+Pretty Print
+Margins
+Left
+Right
+Bottom
+Top
+Filename(s)
+Print
+Options Installed
+Auto
+400 Your browser sent a request that this server could not understand.
+This server could not verify that you are authorized to access the resource.
+You must pay to access this server.
+You don't have permission to access the resource on this server.
+The requested resource was not found on this server.
+The requested method is not allowed with the resource.
+An appropriate representation for the resource was not found on this server.
+You don't have permission to use this server as a proxy host.
+The request has taken too long to complete and has been aborted.
+The requested resource has more than one value.
+The requested resource is gone and has not been replaced.
+The requested method requires a valid Content-Length.
+The precondition on the request evaluated to false.
+The request is too large for this server to process.
+The request URI is too large for this server to process.
+The request format is not understood by this server.
+500 The server has detected an unrecoverable error and cannot process your request.
+The requested method is not implemented by this server.
+The proxy server received an invalid response from an upstream server.
+The requested resource is currently unavailable on this server.
+The proxy server has taken too long to respond to this server.
+This server does not support the HTTP version required by your browser.
diff --git a/locale/ru_RU.koi8r/cups_ru_RU.koi8r b/locale/ru_RU.koi8r/cups_ru_RU.koi8r
new file mode 100644
index 000000000..e1db3f4fc
--- /dev/null
+++ b/locale/ru_RU.koi8r/cups_ru_RU.koi8r
@@ -0,0 +1,134 @@
+koi8-r
+OK
+Cancel
+Help
+Quit
+Close
+Yes
+No
+On
+Off
+Save
+Discard
+Default
+Options
+More Info
+Black
+Colour
+Cyan
+Magenta
+Yellow
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+General
+Printer
+Image
+HP-GL/2
+Extra
+Document
+Other
+Print Pages:
+Entire Document
+Page Range:
+Reverse Order:
+Page Format:
+ 1-Up
+ 2-Up
+ 4-Up
+Image Scaling:
+Use Natural Image Size
+Zoom by Percent
+Zoom by PPI
+Mirror Image:
+Colour Saturation:
+Colour Hue:
+Fit to Page:
+Shading:
+Pen Width:
+Gamma Correction:
+Brightness:
+Add
+Delete
+Modify
+Printer URI
+Printer Name
+Printer Location
+Printer Info
+Printer Make and Model
+Device URI
+Formatting Page
+Printing Page
+Initializing Printer
+Printer State
+Accepting Jobs
+Not Accepting Jobs
+Print Jobs
+Class
+Local
+Remote
+Duplexing
+Stapling
+Fast Copies
+Collated Copies
+Hole Punching
+Covering
+Binding
+Sorting
+Small (up to 9.5x14in)
+Medium (9.5x14in to 13x19in)
+Large (13x19in and larger)
+Custom Size
+Idle
+Processing
+Stopped
+All
+Odd
+Even
+Darker Lighter
+Media Size
+Media Type
+Media Source
+Orientation:
+Portrait
+Landscape
+Job State
+Job Name
+User Name
+Priority
+Copies
+File Size
+Pending
+Output Mode
+Resolution
+Text
+Pretty Print
+Margins
+Left
+Right
+Bottom
+Top
+Filename(s)
+Print
+Installed Options
+Auto
+400 Your browser sent a request that this server could not understand.
+This server could not verify that you are authorized to access the resource.
+You must pay to access this server.
+You don't have permission to access the resource on this server.
+The requested resource was not found on this server.
+The requested method is not allowed with the resource.
+An appropriate representation for the resource was not found on this server.
+You don't have permission to use this server as a proxy host.
+The request has taken too long to complete and has been aborted.
+The requested resource has more than one value.
+The requested resource is gone and has not been replaced.
+The requested method requires a valid Content-Length.
+The precondition on the request evaluated to false.
+The request is too large for this server to process.
+The request URI is too large for this server to process.
+The request format is not understood by this server.
+500 The server has detected an unrecoverable error and cannot process your request.
+The requested method is not implemented by this server.
+The proxy server received an invalid response from an upstream server.
+The requested resource is currently unavailable on this server.
+The proxy server has taken too long to respond to this server.
+This server does not support the HTTP version required by your browser.
diff --git a/locale/sv/cups_sv b/locale/sv/cups_sv
new file mode 100644
index 000000000..702032bb5
--- /dev/null
+++ b/locale/sv/cups_sv
@@ -0,0 +1,135 @@
+iso-8859-1
+OK
+Avbryt
+Hjälp
+Sluta
+Stäng
+Ja
+Nej
+Till
+Från
+Spara
+Släng
+Default
+Alternativ
+Mera info
+Svart
+Färg
+Cyan
+Magenta
+Gul
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+Generellt
+Skrivare
+Bild
+HP-GL/2
+Extra
+Dokument
+Andra
+Skriv sidorna:
+Hela dokumentet
+Inkl. sidorna:
+Omvänd sidordning:
+Sidformat:
+ 1 sida/sida
+ 2 sidor/sida
+ 4 sidor/sida
+Bildskalning:
+Naturlig bildstorlek
+Procentuell zoom
+PPI-zoom
+Spegelvänd bild:
+Färgmättnad:
+Färgnyans:
+Fit to Page:
+Skuggning:
+Linjebredd:
+Gammakorrektion:
+Ljushet:
+Lägg till
+Ta bort
+Modifiera
+Skrivarens URI
+Skrivarens Namn
+Skrivarens Placering
+Skrivarens Info
+Skrivarens Fabrikat och Modell
+Enhetens URI
+Formaterar sida
+Skriver sida
+Initialiserar Skrivare
+Skrivarens tillstånd
+Accepterar jobb
+Accepterar inte jobb
+Utskriftsjobb
+Klass
+Lokalt
+Fjärr
+Dubbelsidigt
+Häftning
+Snabbkopior
+Hopsorterade kopior
+Hålslagning
+Omslag
+Inbindning
+Sortering
+Små (upp till 9.5x14")
+Medium (9.5x14" till 13x19")
+Stora (13x19" och större)
+Specificerad storlek
+Tomgång
+Arbetar...
+Avbruten
+Alla
+Udda
+Jämna
+Mörkare Ljusare
+Mediastorlek
+Mediatyp
+Mediakälla
+Orientering:
+Stående
+Liggande
+Jobbtillstånd
+Jobbnam
+Användarnamn
+Prioritet
+Kopior
+Filstorlek
+Pågående
+Utskriftsmod
+Upplösning
+Text
+Skönutskrift
+Marginaler
+Vänster
+Höger
+Nertill
+Upptill
+Filnamn
+Print
+Options Installed
+Auto
+400 Din bläddrare skickade en begäran som den här tjänstehanteraren inte förstår.
+Den här tjänstehanteraren kan inte verifiera att du har tillstånd att använda tjänsten.
+Du måste betala för att använda denna tjänst.
+Du har inte tillstånd att använda denna resurs.
+Kan inte hitta den efterfrågade resursen.
+Du tillåts inte använda den efterfrågade metoden med den här resursen.
+An appropriate representation for the resource was not found on this server.
+Du tillåts inte använda den här tjänstehanteraren som en proxy-värd.
+Din förfrågan har tagit för lång tid att hantera och har därför avbrutits.
+Den efterfrågade resursen har mer än ett värde.
+Den efterfrågade resursen är borta och har inte ersatts.
+Den efterfrågade metoden behöver ett giltigt "Content-Length".
+Förvillkoren till förfrågan evaluerades till FALSKT.
+Förfrågan var för stor för att hanteras av denna tjänstehanterare.
+URI i förfrågan var för stor för att hanteras av denna tjänstehanterare.
+Tjänstehanteraren förstod inte formatet på förfrågan.
+426 Det är nödvändigt att byta till en säker förbindelse. Ser du detta meddelande i en nätbläddrare så understödjer den inte byte till krypterad HTTP-förbindelse.
+500 Tjänstehanteraren har upptäckt ett allvarligt fel och kan inte hantera din begäran.
+Den efterfrågade metoden är inte implementerad av denna tjänstehanterare.
+Proxy-servern mottog ett otillåtet svar från en tjänstehanterare.
+Den efterfrågade resursen är inte tillgänglig på denna tjänstehanterare.
+Proxy-servern har inte svarat fort nog till denna tjänstehanterare.
+Denna tjänstehanterare tillhandahåller inte den version av HTTP som din bläddrare kräver.
diff --git a/locale/translate.c b/locale/translate.c
new file mode 100644
index 000000000..e56690be6
--- /dev/null
+++ b/locale/translate.c
@@ -0,0 +1,259 @@
+/*
+ * "$Id$"
+ *
+ * HTTP-based translation program for the Common UNIX Printing System (CUPS).
+ *
+ * This program uses AltaVista's "babelfish" page to translate the POSIX
+ * message file (C/cups_C) to several different languages. The translation
+ * isn't perfect, but it's a good start (better than working from scratch.)
+ *
+ * Copyright 1997-1999 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44145 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Main entry.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <cups/http.h>
+
+
+/*
+ * 'main()' - Main entry.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ http_t *http; /* HTTP connection */
+ http_status_t status; /* Status of GET command */
+ char line[1024], /* Line from file */
+ *lineptr, /* Pointer into line */
+ buffer[2048], /* Input/output buffer */
+ *bufptr, /* Pointer into buffer */
+ length[16]; /* Content length */
+ int bytes; /* Number of bytes read */
+ FILE *in, /* Input file */
+ *out; /* Output file */
+
+
+ if (argc != 3)
+ {
+ fputs("Usage: translate outfile language\n", stderr);
+ return (1);
+ }
+
+ if ((in = fopen("C/cups_C", "r")) == NULL)
+ {
+ perror("translate: Unable to open input file");
+ return (1);
+ }
+
+ if ((out = fopen(argv[1], "w")) == NULL)
+ {
+ perror("translate: Unable to create output file");
+ fclose(in);
+ return (1);
+ }
+
+ /*
+ * Do character set...
+ */
+
+ fgets(line, sizeof(line), in);
+ fputs("iso-8859-1\n", out); /* Right now that's all that Babelfish does */
+
+ /*
+ * Then strings...
+ */
+
+ while (fgets(line, sizeof(line), in) != NULL)
+ {
+ /*
+ * Strip trailing newline if necessary...
+ */
+
+ lineptr = line + strlen(line) - 1;
+ if (*lineptr == '\n')
+ *lineptr = '\0';
+
+ /*
+ * Skip leading numbers and whitespace...
+ */
+
+ lineptr = line;
+ while (isdigit(*lineptr))
+ putc(*lineptr++, out);
+
+ while (isspace(*lineptr))
+ putc(*lineptr++, out);
+
+ if (*lineptr == '\0')
+ {
+ putc('\n', out);
+ continue;
+ }
+
+ /*
+ * Encode the line into the buffer...
+ */
+
+ sprintf(buffer, "doit=done&lp=en_%s&urltext=[", argv[2]);
+ bufptr = buffer + strlen(buffer);
+
+ while (*lineptr)
+ {
+ if (*lineptr == ' ')
+ *bufptr++ = '+';
+ else if (*lineptr < ' ' || *lineptr == '%')
+ {
+ sprintf(bufptr, "%%%02X", *lineptr & 255);
+ bufptr += 3;
+ }
+ else
+ *bufptr++ = *lineptr;
+
+ lineptr ++;
+ }
+
+ *bufptr++ = '&';
+ *bufptr = '\0';
+
+ sprintf(length, "%d", bufptr - buffer);
+
+ /*
+ * Send the request...
+ */
+
+ if ((http = httpConnect("dns.easysw.com", 80)) == NULL)
+ {
+ perror("translate: Unable to contact proxy server");
+ fclose(in);
+ fclose(out);
+ return (1);
+ }
+
+ lineptr = line;
+ while (isdigit(*lineptr))
+ lineptr ++;
+ while (isspace(*lineptr))
+ lineptr ++;
+
+ printf("%s = ", lineptr);
+ fflush(stdout);
+
+ http->version = HTTP_1_0;
+ httpClearFields(http);
+ httpSetField(http, HTTP_FIELD_CONTENT_TYPE,
+ "application/x-www-form-urlencoded");
+ httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length);
+ if (httpPost(http, "http://babelfish.altavista.digital.com/cgi-bin/translate?"))
+ httpPost(http, "http://babelfish.altavista.digital.com/cgi-bin/translate?");
+
+ httpWrite(http, buffer, bufptr - buffer);
+
+ while ((status = httpUpdate(http)) == HTTP_CONTINUE);
+
+ if (status == HTTP_OK)
+ {
+ int sawparen = 0;
+ int skipws = 1;
+ int sawbracket = 0;
+
+ while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0)
+ {
+ buffer[bytes] = '\0';
+
+ for (bufptr = buffer; *bufptr; bufptr ++)
+ {
+ if (*bufptr == '>')
+ sawbracket = 0;
+ else if (*bufptr == '<')
+ {
+ sawbracket = 1;
+ if (sawparen)
+ break;
+ }
+ else if (*bufptr == '[' && !sawbracket)
+ sawparen = 1;
+ else if (sawparen)
+ {
+ if (skipws)
+ {
+ if (!isspace(*bufptr))
+ {
+ skipws = 0;
+ *bufptr = toupper(*bufptr);
+ }
+ }
+
+ if (!skipws)
+ {
+ if (*bufptr == '\n')
+ {
+ putc(' ', out);
+ putchar(' ');
+ }
+ else
+ {
+ putc(*bufptr, out);
+ putchar(*bufptr);
+ }
+ }
+ }
+ }
+
+ if (sawparen && sawbracket)
+ break;
+ }
+
+ httpFlush(http);
+ putc('\n', out);
+ putchar('\n');
+ }
+ else
+ {
+ printf("HTTP error %d\n", status);
+
+ fprintf(out, "%s\n", lineptr);
+ httpFlush(http);
+ }
+
+ httpClose(http);
+ }
+
+ fclose(in);
+ fclose(out);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/locale/uk/cups_uk b/locale/uk/cups_uk
new file mode 100644
index 000000000..f9ff98014
--- /dev/null
+++ b/locale/uk/cups_uk
@@ -0,0 +1,134 @@
+koi8-u
+OK
+Cancel
+Help
+Quit
+Close
+Yes
+No
+On
+Off
+Save
+Discard
+Default
+Options
+More Info
+Black
+Colour
+Cyan
+Magenta
+Yellow
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+General
+Printer
+Image
+HP-GL/2
+Extra
+Document
+Other
+Print Pages:
+Entire Document
+Page Range:
+Reverse Order:
+Page Format:
+ 1-Up
+ 2-Up
+ 4-Up
+Image Scaling:
+Use Natural Image Size
+Zoom by Percent
+Zoom by PPI
+Mirror Image:
+Colour Saturation:
+Colour Hue:
+Fit to Page:
+Shading:
+Pen Width:
+Gamma Correction:
+Brightness:
+Add
+Delete
+Modify
+Printer URI
+Printer Name
+Printer Location
+Printer Info
+Printer Make and Model
+Device URI
+Formatting Page
+Printing Page
+Initializing Printer
+Printer State
+Accepting Jobs
+Not Accepting Jobs
+Print Jobs
+Class
+Local
+Remote
+Duplexing
+Stapling
+Fast Copies
+Collated Copies
+Hole Punching
+Covering
+Binding
+Sorting
+Small (up to 9.5x14in)
+Medium (9.5x14in to 13x19in)
+Large (13x19in and larger)
+Custom Size
+Idle
+Processing
+Stopped
+All
+Odd
+Even
+Darker Lighter
+Media Size
+Media Type
+Media Source
+Orientation:
+Portrait
+Landscape
+Job State
+Job Name
+User Name
+Priority
+Copies
+File Size
+Pending
+Output Mode
+Resolution
+Text
+Pretty Print
+Margins
+Left
+Right
+Bottom
+Top
+Filename(s)
+Print
+Installed Options
+Auto
+400 Your browser sent a request that this server could not understand.
+This server could not verify that you are authorized to access the resource.
+You must pay to access this server.
+You don't have permission to access the resource on this server.
+The requested resource was not found on this server.
+The requested method is not allowed with the resource.
+An appropriate representation for the resource was not found on this server.
+You don't have permission to use this server as a proxy host.
+The request has taken too long to complete and has been aborted.
+The requested resource has more than one value.
+The requested resource is gone and has not been replaced.
+The requested method requires a valid Content-Length.
+The precondition on the request evaluated to false.
+The request is too large for this server to process.
+The request URI is too large for this server to process.
+The request format is not understood by this server.
+500 The server has detected an unrecoverable error and cannot process your request.
+The requested method is not implemented by this server.
+The proxy server received an invalid response from an upstream server.
+The requested resource is currently unavailable on this server.
+The proxy server has taken too long to respond to this server.
+This server does not support the HTTP version required by your browser.
diff --git a/locale/uk_UA.cp1251/cups_uk_UA.cp1251 b/locale/uk_UA.cp1251/cups_uk_UA.cp1251
new file mode 100644
index 000000000..6d5d6c8d6
--- /dev/null
+++ b/locale/uk_UA.cp1251/cups_uk_UA.cp1251
@@ -0,0 +1,134 @@
+windows-1251
+OK
+Cancel
+Help
+Quit
+Close
+Yes
+No
+On
+Off
+Save
+Discard
+Default
+Options
+More Info
+Black
+Colour
+Cyan
+Magenta
+Yellow
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+General
+Printer
+Image
+HP-GL/2
+Extra
+Document
+Other
+Print Pages:
+Entire Document
+Page Range:
+Reverse Order:
+Page Format:
+ 1-Up
+ 2-Up
+ 4-Up
+Image Scaling:
+Use Natural Image Size
+Zoom by Percent
+Zoom by PPI
+Mirror Image:
+Colour Saturation:
+Colour Hue:
+Fit to Page:
+Shading:
+Pen Width:
+Gamma Correction:
+Brightness:
+Add
+Delete
+Modify
+Printer URI
+Printer Name
+Printer Location
+Printer Info
+Printer Make and Model
+Device URI
+Formatting Page
+Printing Page
+Initializing Printer
+Printer State
+Accepting Jobs
+Not Accepting Jobs
+Print Jobs
+Class
+Local
+Remote
+Duplexing
+Stapling
+Fast Copies
+Collated Copies
+Hole Punching
+Covering
+Binding
+Sorting
+Small (up to 9.5x14in)
+Medium (9.5x14in to 13x19in)
+Large (13x19in and larger)
+Custom Size
+Idle
+Processing
+Stopped
+All
+Odd
+Even
+Darker Lighter
+Media Size
+Media Type
+Media Source
+Orientation:
+Portrait
+Landscape
+Job State
+Job Name
+User Name
+Priority
+Copies
+File Size
+Pending
+Output Mode
+Resolution
+Text
+Pretty Print
+Margins
+Left
+Right
+Bottom
+Top
+Filename(s)
+Print
+Installed Options
+Auto
+400 Your browser sent a request that this server could not understand.
+This server could not verify that you are authorized to access the resource.
+You must pay to access this server.
+You don't have permission to access the resource on this server.
+The requested resource was not found on this server.
+The requested method is not allowed with the resource.
+An appropriate representation for the resource was not found on this server.
+You don't have permission to use this server as a proxy host.
+The request has taken too long to complete and has been aborted.
+The requested resource has more than one value.
+The requested resource is gone and has not been replaced.
+The requested method requires a valid Content-Length.
+The precondition on the request evaluated to false.
+The request is too large for this server to process.
+The request URI is too large for this server to process.
+The request format is not understood by this server.
+500 The server has detected an unrecoverable error and cannot process your request.
+The requested method is not implemented by this server.
+The proxy server received an invalid response from an upstream server.
+The requested resource is currently unavailable on this server.
+The proxy server has taken too long to respond to this server.
+This server does not support the HTTP version required by your browser.
diff --git a/locale/zh_CN/cups_zh_CN b/locale/zh_CN/cups_zh_CN
new file mode 100644
index 000000000..6511496b0
--- /dev/null
+++ b/locale/zh_CN/cups_zh_CN
@@ -0,0 +1,135 @@
+utf-8
+确认
+å–消
+帮助
+退出
+关闭
+是
+ä¸
+打开
+关闭
+ä¿å­˜
+放弃
+默认
+选项
+更多信æ¯
+黑色
+颜色
+é’色
+洋红
+黄色
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+常规
+打å°æœº
+图åƒ
+HP-GL/2
+Extra
+文档
+其它
+打å°é¡µé¢ï¼š
+整个文档
+页é¢èŒƒå›´ï¼š
+åå‘:
+页é¢æ ¼å¼ï¼š
+ 1-Up
+ 2-Up
+ 4-Up
+图åƒç¼©æ”¾ï¼š
+使用图åƒæœ¬èº«çš„大å°
+按百分比缩放
+按 PPI 缩放
+é•œåƒå›¾åƒï¼š
+颜色饱和度:
+色度:
+适åˆé¡µé¢ï¼š
+阴影:
+笔宽:
+Gamma 校正:
+亮度:
+添加
+删除
+修改
+打å°æœº URI
+打å°æœºå称
+打å°æœºä½ç½®
+打å°æœºä¿¡æ¯
+打å°æœºåˆ¶é€ å’Œåž‹å·
+设备 URI
+正在格å¼åŒ–页é¢
+正在打å°é¡µé¢
+正在åˆå§‹åŒ–打å°æœº
+打å°æœºçŠ¶æ€
+正在接å—任务
+没有接å—任务
+打å°ä»»åŠ¡
+类别
+本地
+远程
+åŒå·¥
+正在分类
+快速å¤åˆ¶
+核对å¤åˆ¶
+正在打孔
+正在打å°å°é¢
+正在装订
+正在整ç†
+å°(24.1x35.6厘米)
+中(24.1x35.6厘米至33.0x48.3厘米)
+大(33.0x48.3厘米或更大)
+定制尺寸
+空闲
+正在处ç†
+åœæ­¢
+全部
+奇数页
+å¶æ•°é¡µ
+æ›´æ·± æ›´æµ…
+媒质大å°
+媒质类型
+媒质æ¥æº
+æ–¹å‘:
+纵å‘
+横å‘
+任务状æ€
+任务å
+用户å
+优先级
+å°æ•°
+文件大å°
+等待
+输出模å¼
+分辨率
+文字
+良好质é‡
+è¾¹è·
+å·¦
+å³
+下
+上
+文件å
+打å°
+Options Installed
+Auto
+400 您的æµè§ˆå™¨å‘é€äº†ä¸€ä¸ªæœ¬æœåŠ¡å™¨ä¸ç†è§£çš„请求。
+本æœåŠ¡å™¨æ— æ³•ç¡®è®¤æ‚¨æœ‰æƒè®¿é—®è¯¥èµ„æºã€‚
+您必须付费æ¥è®¿é—®æœ¬æœåŠ¡å™¨ã€‚
+您没有æƒé™è®¿é—®æœ¬æœåŠ¡å™¨ä¸Šçš„该资æºã€‚
+本æœåŠ¡å™¨ä¸Šæ²¡æœ‰è¦æ±‚的资æºã€‚
+请求的方法在该资æºä¸Šä¸å…许。
+本æœåŠ¡å™¨ä¸Šæ²¡æœ‰è¯¥èµ„æºçš„正确表示。
+您没有æƒé™å°†æœ¬æœåŠ¡å™¨ä½œä¸ºä»£ç†æœåŠ¡å™¨ã€‚
+请求过长时间没有完æˆï¼Œå·²ç»è¢«ä¸­æ­¢ã€‚
+请求的资æºæœ‰å¤šäºŽä¸€ä¸ªå€¼ã€‚
+请求的资æºå·²ç»ç”¨å®Œï¼Œä¸”没有被更æ¢ã€‚
+请求的方法需è¦æœ‰æ•ˆçš„ Content-Length 标识。
+请求的å‰æ为å‡ã€‚
+请求过长,本æœåŠ¡å™¨æ— æ³•å¤„ç†ã€‚
+请求的 URI 过长,本æœåŠ¡å™¨æ— æ³•å¤„ç†ã€‚
+本æœåŠ¡å™¨æ— æ³•è¯†åˆ«è¯¥è¯·æ±‚çš„æ ¼å¼ã€‚
+426 需è¦å®‰å…¨çš„连接。如果您在æµè§ˆå™¨ä¸­çœ‹åˆ°æœ¬ä¿¡æ¯ï¼Œæ‚¨çš„æµè§ˆå™¨ä¸æ”¯æŒ HTTP 加密。
+500 æœåŠ¡å™¨æ£€æµ‹åˆ°ä¸€ä¸ªæ— æ³•æ¢å¤çš„错误,无法处ç†æ‚¨çš„请求。
+本æœåŠ¡å™¨æ²¡æœ‰å®žçŽ°æ‰€è¯·æ±‚的方法。
+代ç†æœåŠ¡å™¨æ”¶åˆ°æ¥è‡ªä¸Šæ¸¸æœåŠ¡å™¨çš„无效应答。
+请求的资æºåœ¨æœ¬æœåŠ¡å™¨ä¸Šä¸å¯ç”¨ã€‚
+代ç†æœåŠ¡å™¨é•¿æ—¶é—´æ²¡æœ‰åº”答本æœåŠ¡å™¨ã€‚
+本æœåŠ¡å™¨ä¸æ”¯æŒæ‚¨çš„æµè§ˆå™¨æ‰€éœ€è¦çš„ HTTP 版本。
diff --git a/man/.cvsignore b/man/.cvsignore
new file mode 100644
index 000000000..5b12a6fc7
--- /dev/null
+++ b/man/.cvsignore
@@ -0,0 +1,7 @@
+*.0
+*.1
+*.1m
+*.3
+*.5
+*.8
+*.z
diff --git a/man/Makefile b/man/Makefile
new file mode 100644
index 000000000..ba12ecdc9
--- /dev/null
+++ b/man/Makefile
@@ -0,0 +1,123 @@
+#
+# "$Id$"
+#
+# Man page makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+include Makefile.common
+
+
+#
+# Other languages...
+#
+
+LANGDIRS = fr
+
+
+#
+# Make everything...
+#
+
+all: $(CAT1) $(CAT3) $(CAT5) $(CAT8)
+ for dir in $(LANGDIRS); do \
+ echo "Making all in man/$$dir..."; \
+ (cd $$dir; make all); \
+ done
+
+
+#
+# Clean all config and object files...
+#
+
+clean:
+ $(RM) $(CAT1) $(CAT3) $(CAT5) $(CAT8)
+ for dir in $(LANGDIRS); do \
+ echo "Cleaning all in man/$$dir..."; \
+ (cd $$dir; make clean); \
+ done
+
+
+#
+# Dummy depend target...
+#
+
+depend:
+
+
+#
+# Install files...
+#
+
+install: all
+ $(INSTALL_DIR) $(MANDIR)/man1
+ for file in $(MAN1); do \
+ $(INSTALL_MAN) $$file $(MANDIR)/man1/`basename $$file man`1; \
+ done
+ $(RM) $(MANDIR)/man1/cancel.1
+ $(LN) lp.1 $(MANDIR)/man1/cancel.1
+ $(INSTALL_DIR) $(PMANDIR)/man3
+ for file in $(MAN3); do \
+ $(INSTALL_MAN) $$file $(PMANDIR)/man3/`basename $$file man`3; \
+ done
+ $(INSTALL_DIR) $(MANDIR)/man5
+ for file in $(MAN5); do \
+ $(INSTALL_MAN) $$file $(MANDIR)/man5/`basename $$file man`5; \
+ done
+ $(INSTALL_DIR) $(AMANDIR)/man$(MAN8EXT)
+ for file in $(MAN8); do \
+ $(INSTALL_MAN) $$file $(AMANDIR)/man$(MAN8EXT)/`basename $$file man`$(MAN8EXT); \
+ done
+ $(RM) $(AMANDIR)/man$(MAN8EXT)/reject.$(MAN8EXT)
+ $(LN) accept.$(MAN8EXT) $(AMANDIR)/man$(MAN8EXT)/reject.$(MAN8EXT)
+ $(RM) $(AMANDIR)/man$(MAN8EXT)/disable.$(MAN8EXT)
+ $(LN) enable.$(MAN8EXT) $(AMANDIR)/man$(MAN8EXT)/disable.$(MAN8EXT)
+ $(INSTALL_DIR) $(MANDIR)/cat1
+ for file in $(CAT1); do \
+ $(INSTALL_MAN) $$file $(MANDIR)/cat1; \
+ done
+ $(RM) $(MANDIR)/cat1/cancel.$(CAT1EXT)
+ $(LN) lp.$(CAT1EXT) $(MANDIR)/cat1/cancel.$(CAT1EXT)
+ $(INSTALL_DIR) $(PMANDIR)/cat3
+ for file in $(CAT3); do \
+ $(INSTALL_MAN) $$file $(PMANDIR)/cat3; \
+ done
+ $(INSTALL_DIR) $(MANDIR)/cat5
+ for file in $(CAT5); do \
+ $(INSTALL_MAN) $$file $(MANDIR)/cat5; \
+ done
+ $(INSTALL_DIR) $(AMANDIR)/cat$(MAN8EXT)
+ for file in $(CAT8); do \
+ $(INSTALL_MAN) $$file $(AMANDIR)/cat$(MAN8EXT); \
+ done
+ $(RM) $(AMANDIR)/cat$(MAN8EXT)/reject.$(CAT8EXT)
+ $(LN) accept.$(CAT8EXT) $(AMANDIR)/cat$(MAN8EXT)/reject.$(CAT8EXT)
+ $(RM) $(AMANDIR)/cat$(MAN8EXT)/disable.$(CAT8EXT)
+ $(LN) enable.$(CAT8EXT) $(AMANDIR)/cat$(MAN8EXT)/disable.$(CAT8EXT)
+ for dir in $(LANGDIRS); do \
+ echo "Installing all in man/$$dir..."; \
+ (cd $$dir; make install); \
+ done
+
+
+#
+# End of "$Id$".
+#
diff --git a/man/Makefile.common b/man/Makefile.common
new file mode 100644
index 000000000..207dfe87c
--- /dev/null
+++ b/man/Makefile.common
@@ -0,0 +1,84 @@
+#
+# "$Id: Makefile.common 2429 2002-05-21 19:59:43Z mike $"
+#
+# Man pages definitions for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+#
+# Man pages...
+#
+
+MAN1 = backend.man \
+ filter.man \
+ lp.man \
+ lpoptions.man \
+ lppasswd.man \
+ lpq.man \
+ lprm.man \
+ lpr.man \
+ lpstat.man
+MAN3 = cups-config.man
+MAN5 = classes.conf.man \
+ cupsd.conf.man \
+ mime.convs.man \
+ mime.types.man \
+ printers.conf.man
+MAN8 = accept.man \
+ cupsaddsmb.man \
+ cups-lpd.man \
+ cups-polld.man \
+ cupsd.man \
+ enable.man \
+ lpadmin.man \
+ lpinfo.man \
+ lpmove.man \
+ lpc.man
+
+CAT1 = backend.$(CAT1EXT) \
+ filter.$(CAT1EXT) \
+ lp.$(CAT1EXT) \
+ lpoptions.$(CAT1EXT) \
+ lppasswd.$(CAT1EXT) \
+ lpq.$(CAT1EXT) \
+ lprm.$(CAT1EXT) \
+ lpr.$(CAT1EXT) \
+ lpstat.$(CAT1EXT)
+CAT3 = cups-config.$(CAT3EXT)
+CAT5 = classes.conf.$(CAT5EXT) \
+ cupsd.conf.$(CAT5EXT) \
+ mime.convs.$(CAT5EXT) \
+ mime.types.$(CAT5EXT) \
+ printers.conf.$(CAT5EXT)
+CAT8 = accept.$(CAT8EXT) \
+ cupsaddsmb.$(CAT8EXT) \
+ cups-lpd.$(CAT8EXT) \
+ cups-polld.$(CAT8EXT) \
+ cupsd.$(CAT8EXT) \
+ enable.$(CAT8EXT) \
+ lpadmin.$(CAT8EXT) \
+ lpinfo.$(CAT8EXT) \
+ lpmove.$(CAT8EXT) \
+ lpc.$(CAT8EXT)
+
+
+#
+# End of "$Id: Makefile.common 2429 2002-05-21 19:59:43Z mike $".
+#
diff --git a/man/accept.man b/man/accept.man
new file mode 100644
index 000000000..b09637d3f
--- /dev/null
+++ b/man/accept.man
@@ -0,0 +1,60 @@
+.\"
+.\" "$Id: accept.man 2060 2002-01-23 17:25:41Z mike $"
+.\"
+.\" accept/reject man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH accept 8 "Common UNIX Printing System" "23 January 2001" "Easy Software Products"
+.SH NAME
+accept/reject \- accept/reject jobs sent to a destination
+.SH SYNOPSIS
+.B accept
+destination(s)
+.br
+.B reject
+[ -E ] [ -h
+.I server
+] [ -r
+.I reason
+]
+destination(s)
+.SH DESCRIPTION
+\fIaccept\fR instructs the printing system to accept print jobs to the
+specified destinations.
+.LP
+\fIreject\fR instructs the printing system to reject print jobs to the
+specified destinations. The \fI-r\fR option sets the reason for rejecting
+print jobs. If not specified the reason defaults to "Reason Unknown".
+.LP
+The \fI-E\fR option forces encryption when connecting to the server.
+.SH COMPATIBILITY
+The CUPS versions of \fIaccept\fR and \fIreject\fR may ask the user for an
+access password depending on the printing system configuration. This differs
+from the System V versions which require the root user to execute these
+commands.
+.SH SEE ALSO
+cancel(1), disable(8), enable(8), lp(1), lpadmin(8), lpstat(1),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: accept.man 2060 2002-01-23 17:25:41Z mike $".
+.\"
diff --git a/man/backend.man b/man/backend.man
new file mode 100644
index 000000000..1cec8c681
--- /dev/null
+++ b/man/backend.man
@@ -0,0 +1,115 @@
+.\"
+.\" "$Id: backend.man 2580 2002-07-23 21:16:28Z mike $"
+.\"
+.\" backend man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH backend 1 "Common UNIX Printing System" "22 June 2000" "Easy Software Products"
+.SH NAME
+backend \- cups backend transmission interfaces
+.SH SYNOPSIS
+.B backend
+job user title num-copies options [
+.I filename
+]
+.SH DESCRIPTION
+The CUPS backend interface provides a standard method for sending document
+files to different physical interfaces.
+.LP
+Backends must be capable of reading from a filename on the command-line
+or from the standard input, copying the standard input to a temporary file
+if required by the physical interface.
+.LP
+The command name (argv[0]) is set to the device URI of the destination printer.
+.SH ENVIRONMENT VARIABLES
+The following environment variables are defined by the CUPS server when
+executing the backend:
+.TP 5
+CHARSET
+.br
+The default text character set (typically us-ascii or iso-8859-1).
+.TP 5
+CLASS
+.br
+When a job is submitted to a printer class, contains the name of
+the destination printer class. Otherwise this environment
+variable will not be set.
+.TP 5
+CONTENT_TYPE
+.br
+The MIME type associated with the file (e.g. application/postscript).
+.TP 5
+CUPS_DATADIR
+.br
+The directory where data files can be found.
+.TP 5
+CUPS_SERVERROOT
+.br
+The root directory of the server.
+.TP 5
+DEVICE_URI
+.br
+The device-uri associated with the printer; this is provided for shell
+scripts which may not be able to get the passed argv[0] string.
+.TP 5
+LANG
+.br
+The default language locale (typically C or en).
+.TP 5
+PATH
+.br
+The standard execution path for external programs that may be run by
+the backend.
+.TP 5
+PPD
+.br
+The full pathname of the PostScript Printer Description (PPD) file for
+this printer.
+.TP 5
+PRINTER
+.br
+The name of the printer.
+.TP 5
+RIP_CACHE
+.br
+The recommended amount of memory to use for Raster Image Processors (RIPs).
+.TP 5
+SOFTWARE
+.br
+The name and version number of the server (typically CUPS/1.1).
+.TP 5
+TZ
+.br
+The timezone of the server.
+.TP 5
+USER
+.br
+The user executing the backend (typically lp).
+.SH SEE ALSO
+cupsd(8), filter(1)
+CUPS Interface Design Description,
+CUPS Software Administrators Manual,
+CUPS Software Programmers Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: backend.man 2580 2002-07-23 21:16:28Z mike $".
+.\"
diff --git a/man/classes.conf.man b/man/classes.conf.man
new file mode 100644
index 000000000..22eff311e
--- /dev/null
+++ b/man/classes.conf.man
@@ -0,0 +1,72 @@
+.\"
+.\" "$Id: classes.conf.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" classes.conf man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH classes.conf 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products"
+.SH NAME
+classes.conf \- class configuration file for cups
+.SH DESCRIPTION
+The \fIclasses.conf\fR file defines the local printer classes that are
+available. It is normally located in the \fI/etc/cups\fR directory and
+is generated automatically by the \fIcupsd(8)\fR program when printer
+classes are added or deleted.
+.LP
+Each line in the file can be a configuration directive, a blank line,
+or a comment. Comment lines start with the # character.
+.SH DIRECTIVES
+.TP 5
+<Class name> ... </Class>
+.br
+Defines a specific printer class.
+.TP 5
+Accepting
+.br
+Specifies whether or not the printer class is accepting new jobs.
+.TP 5
+Info
+.br
+Specifies human-readable text describing the printer class.
+.TP 5
+Location
+.br
+Specifies human-readable text describing the location of the printer class.
+.TP 5
+Printer
+.br
+Specifies a printer that is a member of the printer class.
+.TP 5
+State
+.br
+Specifies the initial state of the printer class (Idle or Stopped)
+.TP 5
+StateMessage
+.br
+Specifies the message associated with the state.
+.SH SEE ALSO
+cupsd(8), cupsd.conf(5), mime.convs(5), mime.types(5), printers.conf(5),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: classes.conf.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/cups-config.man b/man/cups-config.man
new file mode 100644
index 000000000..4e4b8bb28
--- /dev/null
+++ b/man/cups-config.man
@@ -0,0 +1,95 @@
+.\"
+.\" "$Id: cups-config.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" cups-config man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cups-config 3 "Common UNIX Printing System" "25 October 2001" "Easy Software Products"
+.SH NAME
+cups-config \- get cups api, compiler, directory, and link information.
+.SH SYNOPSIS
+.B cups-config
+--api-version
+.br
+.B cups-config
+--cflags
+.br
+.B cups-config
+--datadir
+.br
+.B cups-config
+--help
+.br
+.B cups-config
+--ldflags
+.br
+.B cups-config
+[
+.I --image
+] [
+.I --static
+] --libs
+.br
+.B cups-config
+--serverbin
+.br
+.B cups-config
+--serverroot
+.br
+.B cups-config
+--version
+.br
+.SH DESCRIPTION
+\fBcups-config\fR is the CUPS program configuration utility. It should be
+used by application developers to determine the necessary command-line
+options for the compiler and linker, as well as determining installation
+directories for filters, configuration files, and drivers.
+.LP
+The \fI--api-version\fR command displays the current API version (major.minor).
+.LP
+The \fI--cflags\fR command displays the necessary compiler options.
+.LP
+The \fI--datadir\fR command displays the default CUPS data directory.
+.LP
+The \fI--help\fR command displays the program usage message.
+.LP
+The \fI--ldflags\fR command displays the necessary linker options.
+.LP
+The \fI--libs\fR command displays the necessary librarys to link to.
+The \fI--image\fR option adds the CUPS imaging library to the list.
+The \fI--static\fR option shows the static libraries instead of the
+default (shared) libraries.
+.LP
+The \fI--serverbin\fR command displays the default CUPS binary directory,
+where filters and backends are stored.
+.LP
+The \fI--serverroot\fR command displays the default CUPS configuration
+file directory.
+.LP
+The \fI--version\fR command displays the full version number of the
+CUPS installation (major.minor.patch).
+.SH SEE ALSO
+CUPS Software Programmers Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: cups-config.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/cups-lpd.man b/man/cups-lpd.man
new file mode 100644
index 000000000..f55ca6cf3
--- /dev/null
+++ b/man/cups-lpd.man
@@ -0,0 +1,107 @@
+.\"
+.\" "$Id: cups-lpd.man 2232 2002-03-15 20:50:29Z mike $"
+.\"
+.\" cups-lpd man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cups-lpd 8 "Common UNIX Printing System" "4 March 2002" "Easy Software Products"
+.SH NAME
+cups-lpd \- receive print jobs and report printer status to lpd clients
+.SH SYNOPSIS
+.B cups-lpd
+[ -o
+.I option=value
+]
+.SH DESCRIPTION
+\fBcups-lpd\fR is the CUPS Line Printer Daemon ("LPD") mini-server that
+supports legacy client systems that use the LPD protocol.
+\fBcups-lpd\fR does not act as a standalone network daemon but instead
+operates using the Internet "super-server" \fBinetd(8)\fR. Add the
+following line to the \fBinetd.conf\fR file to enable the
+\fBcups-lpd\fR daemon:
+.br
+.nf
+
+ printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd
+.fi
+.LP
+If you are using the newer \fIxinetd(8)\fR daemon, add the following
+lines to the \fBxinetd.conf\fR file:
+.br
+.nf
+
+ service printer
+ {
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ user = lp
+ server = /usr/lib/cups/daemon/cups-lpd
+ }
+.fi
+.SH SECURITY
+\fBcups-lpd\fR currently does not perform any access control
+based on the settings in \fIcupsd.conf(5)\fR or in the
+\fIhosts.allow(5)\fR or \fIhosts.deny\fR files used by TCP
+wrappers. Therefore, running \fBcups-lpd\fR on your server will
+allow any computer on your network (and perhaps the entire
+Internet) to print to your server.
+.LP
+While \fIxinetd\fR has built-in access control support, you
+should use the TCP wrappers package with \fIinetd\fR to limit
+access to only those computers that should be able to print
+through your server.
+.SH OPTIONS
+The \fI-o\fR option to \fBcups-lpd\fR inserts options for all print queues.
+Most often this is used to disable the "l" filter so that remote print jobs
+are filtered as needed for printing:
+.br
+.nf
+
+ printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd \
+ -o document-format=application/octet-stream
+
+ server = /usr/lib/cups/daemon/cups-lpd
+ server_args = -o document-format=application/octet-stream
+.fi
+.LP
+The example shown resets the document format to be
+\fIapplication/octet-stream\fR, which forces auto-detection of the print
+file type.
+.SH COMPATIBILITY
+\fBcups-lpd\fR does not enforce the restricted source port
+number specified in RFC 1179, as using restricted ports does not
+prevent determined users from submitting print jobs. While this
+behavior is different than standard Berkeley LPD
+implementations, it should not affect normal client operations.
+.LP
+The output of the status requests follows RFC 2569, Mapping
+between LPD and IPP Protocols. Since many LPD implementations
+stray from this definition, remote status reporting to LPD
+clients may be unreliable.
+.SH SEE ALSO
+inetd(8), xinetd(8),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: cups-lpd.man 2232 2002-03-15 20:50:29Z mike $".
+.\"
diff --git a/man/cups-polld.man b/man/cups-polld.man
new file mode 100644
index 000000000..0ee6ed8e3
--- /dev/null
+++ b/man/cups-polld.man
@@ -0,0 +1,46 @@
+.\"
+.\" "$Id: cups-polld.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" cups-polld man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cups-polld 8 "Common UNIX Printing System" "10 May 2000" "Easy Software Products"
+.SH NAME
+cups-polld \- cups printer polling daemon
+.SH SYNOPSIS
+.B cups-polld
+.I address ipp-port interval browse-port
+.SH DESCRIPTION
+\fBcups-polld\fR polls remote servers for a list of available printers
+and printer classes every \fIinterval\fR seconds. Printer and class
+information is then broadcast to the localhost interface (127.0.0.1)
+for reception by \fBcupsd(8)\fR.
+.PP
+This program is started automatically by \fBcupsd\fR for each
+BrowsePoll directive found in the \fBcupsd.conf\fR file.
+.SH SEE ALSO
+cupsd.conf(5),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: cups-polld.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/cupsaddsmb.man b/man/cupsaddsmb.man
new file mode 100644
index 000000000..eea59b409
--- /dev/null
+++ b/man/cupsaddsmb.man
@@ -0,0 +1,127 @@
+.\"
+.\" "$Id: cupsaddsmb.man 2218 2002-03-14 15:09:08Z mike $"
+.\"
+.\" cupsaddsmb man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cupsaddsmb 8 "Common UNIX Printing System" "14 March 2002" "Easy Software Products"
+.SH NAME
+cupsaddsmb \- export printers to samba for windows clients
+.SH SYNOPSIS
+.B cupsaddsmb
+[ -H
+.I samba-server
+] [ -U
+.I samba-user
+] [ -h
+.I cups-server
+] [ -v ] -a
+.br
+.B cupsaddsmb
+[ -H
+.I samba-server
+] [ -U
+.I samba-user
+] [ -h
+.I cups-server
+] [ -v ] printer [ ... printer ]
+.SH DESCRIPTION
+\fIcupsaddsmb\fR exports printers to the SAMBA software (version
+2.2.0 or higher) for use with Windows clients. Depending on the
+SAMBA configuration, you may need to provide a password to
+export the printers. This program requires the Adobe PostScript
+printer driver files described below.
+.LP
+The \fI-H\fR option specifies the SAMBA server which defaults
+to the CUPS server.
+.LP
+The \fI-U\fR option specifies the SAMBA print admin username which defaults
+to your current username.
+.LP
+The \fI-a\fR option exports all known printers. Otherwise only
+the named printers are exported.
+.LP
+The \fI-h\fR option specifies a different CUPS server to use.
+.LP
+The \fI-v\fR option specifies that verbose information should be
+shown and is useful for debugging SAMBA configuration problems.
+.SH SAMBA CONFIGURATION
+\fIcupsaddsmb\fR uses the new RPC-based printing support in
+SAMBA 2.2.x to provide printer drivers and PPD files to Windows
+client machines. In order to use this functionality, you must
+first configure SAMBA (via the smb.conf file) to support
+printing through CUPS and provide a printer driver download
+share, as follows:
+.nf
+
+ [global]
+ load printers = yes
+ printing = cups
+ printcap name = cups
+
+ [printers]
+ comment = All Printers
+ path = /var/spool/samba
+ browseable = no
+ public = yes
+ guest ok = yes
+ writable = no
+ printable = yes
+ printer admin = root
+
+ [print$]
+ comment = Printer Drivers
+ path = /etc/samba/drivers
+ browseable = yes
+ guest ok = no
+ read only = yes
+ write list = root
+.fi
+.LP
+This configuration assumes a FHS-compliant installation of
+SAMBA; adjust the [printers] and [print$] share paths
+accordingly on your system as needed.
+.SH ADOBE POSTSCRIPT DRIVERS FOR WINDOWS
+\fIcupsaddsmb\fR uses the Adobe PostScript printer drivers for
+Windows, which are available for download from the Adobe web
+site (http://www.adobe.com). Once you have extracted the driver
+files, create a "drivers" directory in the CUPS data directory
+(usually /usr/share/cups) and copy the Adobe files using
+UPPERCASE filenames, as follows:
+.nf
+
+ ADFONTS.MFM
+ ADOBEPS4.DRV
+ ADOBEPS4.HLP
+ ADOBEPS5.DLL
+ ADOBEPSU.DLL
+ ADOBEPSU.HLP
+ DEFPRTR2.PPD
+ ICONLIB.DLL
+ PSMON.DLL
+.fi
+.SH SEE ALSO
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: cupsaddsmb.man 2218 2002-03-14 15:09:08Z mike $".
+.\"
diff --git a/man/cupsd.conf.man b/man/cupsd.conf.man
new file mode 100644
index 000000000..78652a6b7
--- /dev/null
+++ b/man/cupsd.conf.man
@@ -0,0 +1,359 @@
+.\"
+.\" "$Id: cupsd.conf.man 2726 2002-08-22 17:13:48Z mike $"
+.\"
+.\" cupsd.conf man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cupsd.conf 5 "Common UNIX Printing System" "12 August 2002" "Easy Software Products"
+.SH NAME
+cupsd.conf \- server configuration file for cups
+.SH DESCRIPTION
+The \fIcupsd.conf\fR file configures the CUPS scheduler, \fIcupsd(8)\fR. It
+is normally located in the \fI/etc/cups\fR directory.
+.LP
+Each line in the file can be a configuration directive, a blank line,
+or a comment. Comment lines start with the # character. The
+configuration directives are intentionally similar to those used by the
+popular Apache web server software and are described below.
+.SH DIRECTIVES
+The following directives are understood by \fIcupsd\fR. Consult the CUPS
+Software Administrators Manual for a detailed description:
+.TP 5
+AccessLog
+.br
+Defines the access log filename.
+.TP 5
+Allow
+.br
+Allows access from the named hosts or addresses.
+.TP 5
+AuthClass
+.br
+Specifies the authentication class (User, Group, System)
+.TP 5
+AuthType
+.br
+Specifies the authentication type (None, Basic, Digest)
+.TP 5
+AutoPurgeJobs
+.br
+Specifies whether to purge job history data automatically when
+it is no longer required for quotas.
+.TP 5
+BrowseAddress
+.br
+Specifies a broadcast address for outgoing printer information packets.
+.TP 5
+BrowseAllow
+.br
+Allows incoming printer information packets from the named host or address.
+.TP 5
+BrowseDeny
+.br
+Denies incoming printer information packets from the named host or address.
+.TP 5
+BrowseInterval
+.br
+Specifies the maximum interval between printer information broadcasts.
+.TP 5
+BrowseOrder
+.br
+Specifies the order of printer information access control (allow,deny or deny,allow)
+.TP 5
+BrowsePoll
+.br
+Specifies a server to poll for printer information.
+.TP 5
+BrowsePort
+.br
+Specifies the port to listen to for printer information packets.
+.TP 5
+BrowseProtocols
+.br
+Specifies the protocols to use for printer browsing.
+.TP 5
+BrowseRelay
+.br
+Specifies that printer information packets should be relayed from one host or
+network to another.
+.TP 5
+BrowseShortNames
+.br
+Specifies whether remote printers will use short names ("printer") or not
+("printer@server"). This option is ignored if more than one remote printer
+exists with the same name.
+.TP 5
+BrowseTimeout
+.br
+Specifies the maximum interval between printer information updates before
+remote printers will be removed from the list of available printers.
+.TP 5
+Browsing
+.br
+Specifies whether or not remote printer browsing should be enabled.
+.TP 5
+Classification
+.br
+Specifies the security classification of the server.
+.TP 5
+ClassifyOverride
+.br
+Specifies whether to allow users to override the classification
+of individual print jobs.
+.TP 5
+ConfigFilePerm
+.br
+Specifies the permissions for all configuration files that the scheduler
+writes.
+.TP 5
+DataDir
+.br
+Specified the directory where data files can be found.
+.TP 5
+DefaultCharset
+.br
+Specifies the default character set to use for text.
+.TP 5
+DefaultLanguage
+.br
+Specifies the default language to use for text and web content.
+.TP 5
+Deny
+.br
+Denies access to the named host or address.
+.TP 5
+DocumentRoot
+.br
+Specifies the root directory for the internal web server documents.
+.TP 5
+Encryption
+.br
+Specifies the level of encryption that is required for a particular
+location.
+.TP 5
+ErrorLog
+.br
+Specifies the error log filename.
+.TP 5
+FilterLimit
+.br
+Specifies the maximum cost of filters that are run concurrently.
+.TP 5
+FilterNice
+.br
+Specifies the scheduling priority ("nice" value) of filters that
+are run to print a job.
+.TP 5
+FontPath
+.br
+Specifies the search path for fonts.
+.TP 5
+Group
+.br
+Specifies the group name or ID that will be used when executing
+external programs.
+.TP 5
+HideImplicitMembers
+.br
+Specifies whether to hide members of implicit classes.
+.TP 5
+HostNameLookups
+.br
+Specifies whether or not to do reverse lookups on client addresses.
+.TP 5
+ImplicitAnyClasses
+.br
+Specifies whether or not to create implicit classes for local and
+remote printers, e.g. "AnyPrinter" from "Printer", "Printer@server1",
+and "Printer@server2".
+.TP 5
+ImplicitClasses
+.br
+Specifies whether or not to create implicit classes from identical
+remote printers.
+.TP 5
+KeepAlive
+.br
+Specifies whether or not to support HTTP Keep-Alive.
+.TP 5
+KeepAliveTimeout
+.br
+Specifies the connection timeout for HTTP Keep-Alive.
+.TP 5
+<Limit methods> ... </Limit>
+.TP 5
+<LimitExcept methods> ... </LimitExcept>
+.br
+Specifies the HTTP methods that are being limited inside a location.
+.TP 5
+LimitRequestBody
+.br
+Specifies the maximum size of any print job request.
+.TP 5
+<Location /path> ... </Location>
+.br
+Specifies access control for the named location.
+.TP 5
+LogFilePerm
+.br
+Specifies the permissions for all log files that the scheduler writes.
+.TP 5
+LogLevel
+.br
+Specifies the logging level (none, warn, error, info, debug, or debug2)
+.TP 5
+MaxClients
+.br
+Specifies the maximum number of simultaneous clients to support.
+.TP 5
+MaxCopies
+.br
+Specifies the maximum number of copies that a user can print of each job.
+.TP 5
+MaxJobs
+.br
+Specifies the maximum number of simultaneous jobs to support.
+.TP 5
+MaxJobsPerPrinter
+.br
+Specifies the maximum number of simultaneous jobs per printer to support.
+.TP 5
+MaxJobsPerUser
+.br
+Specifies the maximum number of simultaneous jobs per user to support.
+.TP 5
+MaxLogSize
+.br
+Specifies the maximum size of the log files before they are
+rotated (0 to disable rotation)
+.TP 5
+MaxRequestSize
+.br
+Specifies the maximum request/file size in bytes (0 for no limit)
+.TP 5
+Order
+.br
+Specifies the order of HTTP access control (allow,deny or deny,allow)
+.TP 5
+PageLog
+.br
+Specifies the page log filename.
+.TP 5
+Port
+.br
+Specifies a port number to listen to for HTTP requests.
+.TP 5
+PreserveJobFiles
+.br
+Specifies whether or not to preserve job files after they are printed.
+.TP 5
+PreserveJobHistory
+.br
+Specifies whether or not to preserve the job history after they are
+printed.
+.TP 5
+Printcap
+.br
+Specifies the filename for a printcap file that is updated automatically
+with a list of available printers (needed for legacy applications)
+.TP 5
+PrintcapGUI
+.br
+Specifies whether to generate option panel definition files on some
+operating systems.
+.TP 5
+RemoteRoot
+.br
+Specifies the username that is associated with unauthenticated root
+accesses.
+.TP 5
+RequestRoot
+.br
+Specifies the directory to store print jobs and other HTTP request
+data.
+.TP 5
+Require
+.br
+Specifies that user or group authentication is required.
+.TP 5
+RIPCache
+.br
+Specifies the maximum amount of memory to use when converting images
+and PostScript files to bitmaps for a printer.
+.TP 5
+RunAsUser
+.br
+Specifies that the scheduler should run as the unpriviledged user
+set with the User directive.
+.TP 5
+Satisfy
+.br
+Specifies whether all or any limits set for a Location must be
+satisfied to allow access.
+.TP 5
+ServerAdmin
+.br
+Specifies the email address of the server administrator.
+.TP 5
+ServerBin
+.br
+Specifies the directory where backends, CGIs, daemons, and filters may
+be found.
+.TP 5
+ServerCertificate
+.br
+Specifies the encryption certificate to use.
+.TP 5
+ServerKey
+.br
+Specifies the encryption key to use.
+.TP 5
+ServerName
+.br
+Specifies the fully-qualified hostname of the server.
+.TP 5
+ServerRoot
+.br
+Specifies the directory where the server configuration files can be found.
+.TP 5
+SystemGroup
+.br
+Specifies the group to use for System class authentication.
+.TP 5
+TempDir
+.br
+Specifies the directory where temporary files are stored.
+.TP 5
+Timeout
+.br
+Specifies the HTTP request timeout in seconds.
+.TP 5
+User
+.br
+Specifies the user name or ID that is used when running external programs.
+.SH SEE ALSO
+classes.conf(5), cupsd(8), mime.convs(5), mime.types(5), printers.conf(5),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: cupsd.conf.man 2726 2002-08-22 17:13:48Z mike $".
+.\"
diff --git a/man/cupsd.man b/man/cupsd.man
new file mode 100644
index 000000000..b3827c900
--- /dev/null
+++ b/man/cupsd.man
@@ -0,0 +1,61 @@
+.\"
+.\" "$Id: cupsd.man 2566 2002-07-18 10:50:34Z mike $"
+.\"
+.\" cupsd man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cupsd 8 "Common UNIX Printing System" "18 July 2002" "Easy Software Products"
+.SH NAME
+cupsd \- common unix printing system daemon
+.SH SYNOPSIS
+.B cupsd
+[ \-c
+.I config-file
+] [ \-f ] [ \-F ]
+.SH DESCRIPTION
+\fIcupsd\fR is the scheduler for the Common UNIX Printing System. It
+implements a printing system based upon the Internet Printing Protocol,
+version 1.1. If no options are specified on the command-line then the
+default configuration file (usually \fI/etc/cups/cupsd.conf\fR) will be
+used.
+.PP
+The \fI-f\fR option forces \fIcupsd\fR to run in the foreground; the
+default is to run in the background as a "daemon".
+.PP
+The \fI-F\fR option forces \fIcupsd\fR to run in the foreground
+but detaches the process from the controlling terminal and
+current directory. This is useful for running \fIcupsd\fR from
+\fIinit\fR.
+.SH COMPATIBILITY
+\fIcupsd\fR implements all of the required IPP/1.1 attributes and
+operations. It also implements several CUPS-specific administation
+operations.
+.SH SEE ALSO
+backend(1), classes.conf(5), cupsd.conf(5), filter(1), mime.convs(5),
+mime.types(5), printers.conf(5),
+CUPS Implementation of IPP,
+CUPS Interface Design Description,
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: cupsd.man 2566 2002-07-18 10:50:34Z mike $".
+.\"
diff --git a/man/enable.man b/man/enable.man
new file mode 100644
index 000000000..68ce9fb6b
--- /dev/null
+++ b/man/enable.man
@@ -0,0 +1,67 @@
+.\"
+.\" "$Id: enable.man 2060 2002-01-23 17:25:41Z mike $"
+.\"
+.\" enable/disable man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH enable 8 "Common UNIX Printing System" "23 January 2001" "Easy Software Products"
+.SH NAME
+disable, enable \- stop/start printers and classes
+.SH SYNOPSIS
+.B disable
+[ -E ] [ \-c ] [ -h
+.I server
+] [ \-r
+.I reason
+] destination(s)
+.br
+.B enable
+[ -E ] destination(s)
+.SH DESCRIPTION
+\fIenable\fR starts the named printers or classes.
+.LP
+\fIdisable\fR stops the named printers or classes. The following options may
+be used:
+.TP 5
+\-c
+.br
+Cancels all jobs on the named destination.
+.TP 5
+\-r [ \fIreason\fR ]
+.br
+Sets the message associated with the stopped state. If no reason is specified
+then the message is set to "Reason Unknown".
+.LP
+The \fI-E\fR option forces encryption when connecting to the server.
+.SH COMPATIBILITY
+The CUPS versions of \fIdisable\fR and \fIenable\fR may ask the user for an
+access password depending on the printing system configuration. This differs
+from the System V versions which require the root user to execute these
+commands.
+.SH SEE ALSO
+accept(8), cancel(1), lp(1), lpadmin(8), lpstat(1), reject(8),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+
+.\"
+.\" End of "$Id: enable.man 2060 2002-01-23 17:25:41Z mike $".
+.\"
diff --git a/man/filter.man b/man/filter.man
new file mode 100644
index 000000000..e3930ba13
--- /dev/null
+++ b/man/filter.man
@@ -0,0 +1,122 @@
+.\"
+.\" "$Id: filter.man 2580 2002-07-23 21:16:28Z mike $"
+.\"
+.\" filter man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH filter 1 "Common UNIX Printing System" "22 June 2000" "Easy Software Products"
+.SH NAME
+filter \- cups file conversion filter interfaces
+.SH SYNOPSIS
+.B filter
+job user title num-copies options [
+.I filename
+]
+.SH DESCRIPTION
+The CUPS filter interface provides a standard method for adding support for
+new document types to CUPS. Each filter is capable of converting from one
+or more input formats to another format that can either be printed directly
+or piped into another filter to get it to a printable format.
+.LP
+Filters must be capable of reading from a filename on the command-line
+or from the standard input, copying the standard input to a temporary
+file as required by the file format. All output must be sent to the
+standard output.
+.LP
+The command name (argv[0]) is set to the name of the destination printer.
+.SH ENVIRONMENT VARIABLES
+The following environment variables are defined by the CUPS server when
+executing each filter:
+.TP 5
+CHARSET
+.br
+The default text character set (typically us-ascii or iso-8859-1).
+.TP 5
+CLASS
+.br
+When a job is submitted to a printer class, contains the name of
+the destination printer class. Otherwise this environment
+variable will not be set.
+.TP 5
+CONTENT_TYPE
+.br
+The MIME type associated with the file (e.g. application/postscript).
+.TP 5
+CUPS_DATADIR
+.br
+The directory where data files can be found.
+.TP 5
+CUPS_SERVERROOT
+.br
+The root directory of the server.
+.TP 5
+DEVICE_URI
+.br
+The device-uri associated with the printer.
+.TP 5
+LANG
+.br
+The default language locale (typically C or en).
+.TP 5
+PATH
+.br
+The standard execution path for external programs that may be run by the filter.
+.TP 5
+PPD
+.br
+The full pathname of the PostScript Printer Description (PPD) file for
+this printer.
+.TP 5
+PRINTER
+.br
+The name of the printer; this is provided for shell scripts which may not be
+able to get the passed argv[0] string.
+.TP 5
+RIP_CACHE
+.br
+The recommended amount of memory to use for Raster Image Processors (RIPs).
+.TP 5
+SOFTWARE
+.br
+The name and version number of the server (typically CUPS/1.1).
+.TP 5
+TZ
+.br
+The timezone of the server.
+.TP 5
+USER
+.br
+The user executing the filter (typically lp).
+.SH COMPATIBILITY
+While the filter interface is compatible with System V interface
+scripts, it will only work with the System V interface script as the
+only filter. Typically the interface script will be provided via the
+\fBlpadmin(8)\fR command using the \fI-i\fR option.
+.SH SEE ALSO
+backend(1), cupsd(8),
+CUPS Interface Design Description,
+CUPS Software Administrators Manual,
+CUPS Software Programmers Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: filter.man 2580 2002-07-23 21:16:28Z mike $".
+.\"
diff --git a/man/fr/.cvsignore b/man/fr/.cvsignore
new file mode 100644
index 000000000..5b12a6fc7
--- /dev/null
+++ b/man/fr/.cvsignore
@@ -0,0 +1,7 @@
+*.0
+*.1
+*.1m
+*.3
+*.5
+*.8
+*.z
diff --git a/man/fr/Makefile b/man/fr/Makefile
new file mode 100644
index 000000000..ea58e945f
--- /dev/null
+++ b/man/fr/Makefile
@@ -0,0 +1,111 @@
+#
+# "$Id$"
+#
+# French man page makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../../Makedefs
+include ../Makefile.common
+
+
+#
+# This is the French manpage makefile...
+#
+
+LANGUAGE = fr
+
+
+#
+# Make everything...
+#
+
+all: $(CAT1) $(CAT3) $(CAT5) $(CAT8)
+
+
+#
+# Clean all config and object files...
+#
+
+clean:
+ $(RM) $(CAT1) $(CAT3) $(CAT5) $(CAT8)
+
+
+#
+# Dummy depend target...
+#
+
+depend:
+
+
+#
+# Install files...
+#
+
+install: all
+ $(INSTALL_DIR) $(MANDIR)/$(LANGUAGE)/man1
+ for file in $(MAN1); do \
+ $(INSTALL_MAN) $$file $(MANDIR)/$(LANGUAGE)/man1/`basename $$file man`1; \
+ done
+ $(RM) $(MANDIR)/$(LANGUAGE)/man1/cancel.1
+ $(LN) lp.1 $(MANDIR)/$(LANGUAGE)/man1/cancel.1
+ $(INSTALL_DIR) $(PMANDIR)/fr/man3
+ for file in $(MAN3); do \
+ $(INSTALL_MAN) $$file $(PMANDIR)/fr/man3/`basename $$file man`3; \
+ done
+ $(INSTALL_DIR) $(MANDIR)/$(LANGUAGE)/man5
+ for file in $(MAN5); do \
+ $(INSTALL_MAN) $$file $(MANDIR)/$(LANGUAGE)/man5/`basename $$file man`5; \
+ done
+ $(INSTALL_DIR) $(AMANDIR)/$(LANGUAGE)/man$(MAN8EXT)
+ for file in $(MAN8); do \
+ $(INSTALL_MAN) $$file $(AMANDIR)/$(LANGUAGE)/man$(MAN8EXT)/`basename $$file man`$(MAN8EXT); \
+ done
+ $(RM) $(AMANDIR)/$(LANGUAGE)/man$(MAN8EXT)/reject.$(MAN8EXT)
+ $(LN) accept.$(MAN8EXT) $(AMANDIR)/$(LANGUAGE)/man$(MAN8EXT)/reject.$(MAN8EXT)
+ $(RM) $(AMANDIR)/$(LANGUAGE)/man$(MAN8EXT)/disable.$(MAN8EXT)
+ $(LN) enable.$(MAN8EXT) $(AMANDIR)/$(LANGUAGE)/man$(MAN8EXT)/disable.$(MAN8EXT)
+ $(INSTALL_DIR) $(MANDIR)/$(LANGUAGE)/cat1
+ for file in $(CAT1); do \
+ $(INSTALL_MAN) $$file $(MANDIR)/$(LANGUAGE)/cat1; \
+ done
+ $(RM) $(MANDIR)/$(LANGUAGE)/cat1/cancel.$(CAT1EXT)
+ $(LN) lp.$(CAT1EXT) $(MANDIR)/$(LANGUAGE)/cat1/cancel.$(CAT1EXT)
+ $(INSTALL_DIR) $(PMANDIR)/fr/cat3
+ for file in $(CAT3); do \
+ $(INSTALL_MAN) $$file $(PMANDIR)/fr/cat3; \
+ done
+ $(INSTALL_DIR) $(MANDIR)/$(LANGUAGE)/cat5
+ for file in $(CAT5); do \
+ $(INSTALL_MAN) $$file $(MANDIR)/$(LANGUAGE)/cat5; \
+ done
+ $(INSTALL_DIR) $(AMANDIR)/$(LANGUAGE)/cat$(MAN8EXT)
+ for file in $(CAT8); do \
+ $(INSTALL_MAN) $$file $(AMANDIR)/$(LANGUAGE)/cat$(MAN8EXT); \
+ done
+ $(RM) $(AMANDIR)/$(LANGUAGE)/cat$(MAN8EXT)/reject.$(CAT8EXT)
+ $(LN) accept.$(CAT8EXT) $(AMANDIR)/$(LANGUAGE)/cat$(MAN8EXT)/reject.$(CAT8EXT)
+ $(RM) $(AMANDIR)/$(LANGUAGE)/cat$(MAN8EXT)/disable.$(CAT8EXT)
+ $(LN) enable.$(CAT8EXT) $(AMANDIR)/$(LANGUAGE)/cat$(MAN8EXT)/disable.$(CAT8EXT)
+
+
+#
+# End of "$Id$".
+#
diff --git a/man/fr/accept.man b/man/fr/accept.man
new file mode 100644
index 000000000..cbe9a01b3
--- /dev/null
+++ b/man/fr/accept.man
@@ -0,0 +1,62 @@
+.\"
+.\" "$Id: accept.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" accept/reject man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH accept 8 "Common UNIX Printing System" "23 Janvier 2001" "Easy Software Products"
+.SH NOM
+accept/reject \- Accepte/refuse les travaux d'impression envoyés à une destination
+.SH SYNOPSIS
+.B accept
+destination(s)
+.br
+.B reject
+[ -E ] [ -h
+.I serveur
+] [ -r
+.I raison
+]
+destination(s)
+.SH DESCRIPTION
+\fIaccept\fR envoie l'ordre au système d'impression d'accepter les
+travaux d'impression vers les destinations spécifiées.
+.LP
+\fIreject\fR envoie l'ordre au système d'impression de refuser les
+travaux d'impression vers les destinations spécifiées. L'option \fI-r\fR
+permet de spécifier la raison du rejet des travaux d'impression. Si cette
+raison n'est pas fournie, la raison par défaut est «\ Raison inconnue\ ».
+.LP
+L'option \fI-E\fR force le cryptage lors de la connexion au serveur.
+.SH COMPATIBILITÉ
+Les versions CUPS d'\fIaccept\fR et \fIreject\fR peuvent demander à
+l'utilisateur de s'identifier suivant la configuration du système d'impression,
+à la différence des versions System V, qui demandent le mot de passe root.
+.SH VOIR AUSSI
+cancel(1), disable(8), enable(8), lp(1), lpadmin(8), lpstat(1),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: accept.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
diff --git a/man/fr/backend.man b/man/fr/backend.man
new file mode 100644
index 000000000..6eb5b66b1
--- /dev/null
+++ b/man/fr/backend.man
@@ -0,0 +1,113 @@
+.\"
+.\" "$Id: backend.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" backend man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH backend 1 "Common UNIX Printing System" "22 Juin 2000" "Easy Software Products"
+.SH NOM
+backend \- Programme de transmission de CUPS
+.SH SYNOPSIS
+.B backend
+travail utilisateur titre nb-copies options [
+.I fichier
+]
+.SH DESCRIPTION
+Les programmes de transmission de CUPS fournissent une méthode standard
+d'envoi des fichiers aux différentes interfaces physiques.
+.LP
+Ces programmes doivent être capable de lire un fichier de la ligne de
+commande ou via l'entrée standard, si besoin est en recopiant son contenu
+dans un fichier temporaire.
+.LP
+Le nom de la commande (argv[0]) est l'URI de l'imprimante.
+.SH VARIABLES D'ENVIRONNEMENT
+Les variables d'environnement suivantes sont définies par le serveur CUPS
+lors de l'exécution d'un programme de transmission\ :
+.TP 5
+CHARSET
+.br
+Le jeu de caractères par défaut (généralement us-ascii ou iso-8859-1).
+.TP 5
+CONTENT_TYPE
+.br
+Le type MIME associé au fichier (ex\ : application/postscript).
+.TP 5
+CUPS_DATADIR
+.br
+Le répertoire où se trouvent les données.
+.TP 5
+CUPS_SERVERROOT
+.br
+Le répertoire racine du serveur.
+.TP 5
+DEVICE_URI
+.br
+L'URI de l'imprimante, ceci pour les scripts shells qui ne sont pas
+toujours capables de récupérer l'argument argv[0].
+.TP 5
+LANG
+.br
+La langue (généralement C ou en).
+.TP 5
+PATH
+.br
+La liste des chemins où chercher les programmes pouvant être exécutés
+par le programme.
+.TP 5
+PPD
+.br
+Le chemin complet d'accès au fichier PPD (PostScript Printer Description)
+de l'imprimante.
+.TP 5
+PRINTER
+.br
+Le nom de l'imprimante.
+.TP 5
+RIP_CACHE
+.br
+La quantité de mémoire recommandée pour l'utilisation du RIP (Raster Image
+Processors).
+.TP 5
+SOFTWARE
+.br
+Le nom et le numéro de version du serveur (généralement CUPS/1.1).
+.TP 5
+TZ
+.br
+Le fuseau horaire du serveur.
+.TP 5
+USER
+.br
+L'utilisateur exécutant le programme (généralement lp).
+.SH VOIR AUSSI
+cupsd(8), filter(1)
+CUPS Interface Design Description,
+CUPS Software Administrators Manual,
+CUPS Software Programmers Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: backend.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
+
diff --git a/man/fr/classes.conf.man b/man/fr/classes.conf.man
new file mode 100644
index 000000000..e1e1671bc
--- /dev/null
+++ b/man/fr/classes.conf.man
@@ -0,0 +1,75 @@
+.\"
+.\" "$Id: classes.conf.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" classes.conf man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH classes.conf 5 "Common UNIX Printing System" "22 Juin 2000" "Easy Software Products"
+.SH NOM
+classes.conf \- Fichier de configuration des classes de CUPS
+.SH DESCRIPTION
+Le fichier \fIclasses.conf\fR définit les classes d'imprimantes disponibles. Il est
+habituellement situé dans le répertoire \fI/etc/cups\fR et est généré automatiquement
+par le programme \fIcupsd(8)\fR lorsque des classes d'imprimantes sont créées ou
+supprimées.
+.LP
+Chaque ligne de ce fichier est une directive de configuration, une ligne vide ou
+un commentaire. Les commentaires commencent par le symbole #.
+.SH DIRECTIVES
+.TP 5
+<Class name> ... </Class>
+.br
+Définit une classe d'imprimantes.
+.TP 5
+Accepting
+.br
+Définit si la classe d'imprimante accepte les travaux d'impression ou non.
+.TP 5
+Info
+.br
+Définit une information à destination des utilisateurs pour la classe d'imprimantes.
+.TP 5
+Location
+.br
+Définit la localisation physique de la classe d'imprimantes à destination des utilisateurs.
+.TP 5
+Printer
+.br
+Associe une imprimante à une classe.
+.TP 5
+State
+.br
+Définit l'état initial de la classe d'imprimante (Idle ou Stopped).
+.TP 5
+StateMessage
+.br
+Définit le message associé à l'état.
+.SH VOIR AUSSI
+cupsd(8), cupsd.conf(5), mime.convs(5), mime.types(5), printers.conf(5),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: classes.conf.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
+
diff --git a/man/fr/cups-config.man b/man/fr/cups-config.man
new file mode 100644
index 000000000..dbc97bdb2
--- /dev/null
+++ b/man/fr/cups-config.man
@@ -0,0 +1,98 @@
+.\"
+.\" "$Id: cups-config.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" cups-config man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cups-config 3 "Common UNIX Printing System" "25 Octobre 2001" "Easy Software Products"
+.SH NOM
+cups-config \- Récupère les informations concernant les API, la compilation, les répertoires et les liens de CUPS
+.SH SYNOPSIS
+.B cups-config
+--api-version
+.br
+.B cups-config
+--cflags
+.br
+.B cups-config
+--datadir
+.br
+.B cups-config
+--help
+.br
+.B cups-config
+--ldflags
+.br
+.B cups-config
+[
+.I --image
+] [
+.I --static
+] --libs
+.br
+.B cups-config
+--serverbin
+.br
+.B cups-config
+--serverroot
+.br
+.B cups-config
+--version
+.br
+.SH DESCRIPTION
+\fBcups-config\fR est le programme visualisation de la configuration de CUPS. Il doit être
+utilisé par les développeurs pour déterminer les options du compilateur et du linkeur,
+ainsi que l'endroit où ont été installés les filtres,
+fichiers de configuration et pilotes.
+.LP
+La commande \fI--api-version\fR affiche la version de l'API (majeur.mineur).
+.LP
+La commande \fI--cflags\fR affiche les options indispensables de compilation.
+.LP
+La commande \fI--datadir\fR affiche le répertoire par défaut des données CUPS.
+.LP
+La commande \fI--help\fR affiche le message d'utilisation de ce programme.
+.LP
+La commande \fI--ldflags\fR affiche les options indispensables pour l'édition des liens.
+.LP
+La commande \fI--libs\fR affiche les bibliothèques nécessaires pour l'édition des liens.
+L'option \fI--image\fR ajoute à la liste les bibliothèque pour les images.
+L'option \fI--static\fR affiche les bibliothèques statiques au lieu des bibliothèques
+dynamiques.
+.LP
+La commande \fI--serverbin\fR affiche le répertoire par défaut où
+les programmes de filtres et backends CUPS sont stockés.
+.LP
+La commande \fI--serverroot\fR affiche le fichier de configuration par défaut de CUPS.
+.LP
+La commande \fI--version\fR affiche le numéro complet de version de CUPS
+(majeur.mineur.révision).
+.SH VOIR AUSSI
+CUPS Software Programmers Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: cups-config.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
+
+
diff --git a/man/fr/cups-lpd.man b/man/fr/cups-lpd.man
new file mode 100644
index 000000000..350d5a29c
--- /dev/null
+++ b/man/fr/cups-lpd.man
@@ -0,0 +1,94 @@
+.\"
+.\" "$Id: cups-lpd.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" cups-lpd man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cups-lpd 8 "Common UNIX Printing System" "13 Février 2001" "Easy Software Products"
+.SH NOM
+cups-lpd \- Reçoit les travaux d'impression et renvoie le statut des imprimantes aux clients lpd
+.SH SYNOPSIS
+.B cups-lpd
+[ -o
+.I option=valeur
+]
+.SH DESCRIPTION
+\fBcups-lpd\fR est un mini serveur Line Printer Daemon («\ LPD\ ») qui
+gère les client génériques utilisant le protocole LPD.
+\fBcups-lpd\fR ne fonctionne pas comme un démon réseau solitaire, mais
+utilise le super-serveur \fBinetd(8)\fR. Ajoutez la ligne suivante au fichier
+\fBinetd.conf\fR pour activer le démon \fBcups-lpd\fR\ :
+.br
+.nf
+
+ printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd
+.fi
+.LP
+Si vous utilisez le super-serveur \fIxinetd(8)\fR, ajoutez la ligne suivante au fichier
+\fBxinetd.conf\fR\ :
+.br
+.nf
+
+ service printer
+ {
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ user = lp
+ server = /usr/lib/cups/daemon/cups-lpd
+ }
+.fi
+.SH OPTIONS
+L'option \fI-o\fR ajoute des options à tous les travaux d'impression.
+Cette option est souvent utilisée pour désactiver le filtre «\ l\ » de manière
+à ce que les travaux passant par le réseau soient filtrés correctement.
+.br
+.nf
+
+ printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd \
+ -o document-format=application/octet-stream
+.fi
+.LP
+Dans cet exemple, le format du documet est réinitialisé à la valeur
+\fIapplication/octet-stream\fR, ce qui force l'auto-détection du type de
+fichier.
+.SH COMPATIBILITÉ
+\fBcups-lpd\fR ne se conforme pas à la RFC 1179 concernant l'utilisation
+des ports systèmes (1 à 1\|024), car l'utilisation de ces ports n'empêche pas
+un utilisateur d'envoyer un travail d'impression. Bien que ce comportement
+soit différent de celui des implémentations LPD Berkeley, il ne devrait pas
+affecter le déroulement correct des impressions.
+.LP
+Le format de sortie des demandes d'état se conforme à la RFC 2569, Mapping
+between LPD and IPP Protocols. Comme bon nombre d'implémentations LPD ne suivent
+pas cette définition, la récupération d'état par un client LPD peut être
+erronée.
+.SH VOIR AUSSI
+inetd(8), xinetd(8),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: cups-lpd.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
+
diff --git a/man/fr/cups-polld.man b/man/fr/cups-polld.man
new file mode 100644
index 000000000..e3bfc11bd
--- /dev/null
+++ b/man/fr/cups-polld.man
@@ -0,0 +1,49 @@
+.\"
+.\" "$Id: cups-polld.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" cups-polld man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cups-polld 8 "Common UNIX Printing System" "10 Mai 2000" "Easy Software Products"
+.SH NOM
+cups-polld \- Démon d'interrogation des imprimantes CUPS
+.SH SYNOPSIS
+.B cups-polld
+.I adresse port-ipp intervalle port-de-navigation
+.SH DESCRIPTION
+\fBcups-polld\fR interroge des serveurs distants afin d'obtenir la
+liste des imprimantes et classes d'imprimantes disponibles toutes
+les \fIintervalle\fR secondes. Les informations sont alors renvoyées
+vers l'interface locale (127.0.0.1) pour être récupérées par \fBcupsd(8)\fR.
+.PP
+Ce programme est démarré automatiquement par \fBcupsd\fR pour chaque
+directive «\ BrowsePoll\ » trouvée dans le fichier \fBcupsd.conf\fR.
+.SH VOIR AUSSI
+cupsd.conf(5),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: cups-polld.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
+
diff --git a/man/fr/cupsaddsmb.man b/man/fr/cupsaddsmb.man
new file mode 100644
index 000000000..c01ebe17a
--- /dev/null
+++ b/man/fr/cupsaddsmb.man
@@ -0,0 +1,117 @@
+.\"
+.\" "$Id: cupsaddsmb.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" cupsaddsmb man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cupsaddsmb 8 "Common UNIX Printing System" "9 Novembre 2001" "Easy Software Products"
+.SH NOM
+cupsaddsmb \- Export d'imprimante vers Samba pour les clients Windows
+.SH SYNOPSIS
+.B cupsaddsmb
+[ -a ] [ -U
+.I utilisateur
+] [ -v ]
+.br
+.B cupsaddsmb
+[ -u
+.I utilisateur
+] [ -v ] [ imprimante1 ... imprimanteN ]
+.SH DESCRIPTION
+\fIcupsaddsmb\fR permet l'export d'imprimantes vers SAMBA (version 2.2.0
+ou supérieure) pour l'utilisation par des clients Windows. Suivant
+la configuration de SAMBA, il est possible qu'un mot de passe soit
+demandé pour l'export. Ce programme requiert les fichiers du driver
+d'imprimante Adobe PostScript, comme indiqué plus bas.
+.LP
+L'option \fI-a\fR exporte toutes les imprimantes connues. Sinon,
+seules les imprimantes fournies dans la ligne de commande sont
+exportées.
+.LP
+L'option \fI-U\fR spécifie le nom d'utilisateur de l'administrateur
+d'impression. C'est par défaut votre nom d'utilisateur.
+.LP
+L'option \fI-v\fR spécifie que des informations détaillées doivent
+être affichées. Ceci peut être utile pour le débogage des configurations
+de SAMBA.
+.SH CONFIGURATION DE SAMBA
+\fIcupsaddsmb\fR utilise le nouveau mode d'impression RPC de
+SAMBA pour fournir aux clients Windows les drivers d'impression et les
+fichiers PPD. Pour utiliser cette fonctionnalité, vous devez configurer
+SAMBA (via le fichier smb.conf) pour qu'il utilise l'impression via CUPS, et
+fournir un driver à télécharger. Ceci est fait de la manière suivante\ :
+.nf
+
+ [global]
+ load printers = yes
+ printing = cups
+ printcap name = cups
+
+ [printers]
+ comment = All Printers
+ path = /var/spool/samba
+ browseable = no
+ public = yes
+ guest ok = yes
+ writable = no
+ printable = yes
+ printer admin = root
+
+ [print$]
+ comment = Printer Drivers
+ path = /etc/samba/drivers
+ browseable = yes
+ guest ok = no
+ read only = yes
+ write list = root
+.fi
+.LP
+Cette configuration suppose une installation de SAMBA conforme au
+standard FHS. Modifiez les chemins dans [printers] et [print$] suivant
+votre installation.
+.SH LES DRIVERS ADOBE POSTSCRIPT POUR WINDOWS
+\fIcupsaddsmb\fR utilise les drivers Adobe PostScript pour Windows,
+disponible en téléchargement sur le site web d'Adobe (http://www.adobe.com).
+Une fois les fichiers décompressés, créez un répertoire «\ drivers\ » dans
+le répertoire de données de CUPS (habituellement /usr/share/cups) et
+copiez les fichiers Adobe en utilisant des noms de fichiers en MAJUSCULES,
+comme ci-dessous\ :
+.nf
+ ADFONTS.MFM
+ ADOBEPS4.DRV
+ ADOBEPS4.HLP
+ ADOBEPS5.DLL
+ ADOBEPSU.DLL
+ ADOBEPSU.HLP
+ DEFPRTR2.PPD
+ ICONLIB.DLL
+ PSMON.DLL
+.fi
+.SH VOIR AUSSI
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: cupsaddsmb.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
+
diff --git a/man/fr/cupsd.conf.man b/man/fr/cupsd.conf.man
new file mode 100644
index 000000000..24cb36c63
--- /dev/null
+++ b/man/fr/cupsd.conf.man
@@ -0,0 +1,255 @@
+.\"
+.\" "$Id: cupsd.conf.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" cupsd.conf man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2001 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cupsd.conf 5 "Common UNIX Printing System" "22 Juin 2000" «Easy Software Products»
+.SH NOM
+cupsd.conf \- Fichier de configuration du serveur CUPS
+.SH DESCRIPTION
+Le fichier \fIcupsd.conf\fR configure l'ordonnanceur CUPS, \fIcupsd(8)\fR. Il est
+généralement situé dans le répertoire \fI/etc/cups\fR.
+.LP
+Chaque ligne de ce fichier est soit une directive de configuration, une ligne vide, ou
+un commentaire. Les lignes de commentaire commencent par le caractère #. Les directives
+de configuration sont volontairement similaires à celles utilisées par le serveur web
+Apache, et sont décrites ci-dessous.
+.SH DIRECTIVES
+Les directives suivantes sont interprétées par \fIcupsd\fR. Veuillez vous reporter au
+Manuel d'administration CUPS pour une description plus détaillée.
+.TP 5
+AccessLog
+.br
+Définit le fichier traçant les accès.
+.TP 5
+Allow
+.br
+Permet l'accès à CUPS depuis des machines nommées ou des adresses IP.
+.TP 5
+AuthClass
+.br
+Définit la classe d'identification (User, Group, System)
+.TP 5
+AuthType
+.br
+Définit le type d'identification (None, Basic, Digest)
+.TP 5
+BrowseAddress
+.br
+Définit une adresse où broadcaster les informations sur les imprimantes.
+.TP 5
+BrowseAllow
+.br
+Accepte les paquets arrivant de machines nommées ou d'adresses IP.
+.TP 5
+BrowseDeny
+.br
+Refuse les paquets de demande d'informations sur les imprimantes arrivant
+de machines nommées ou d'adresses IP.
+.TP 5
+BrowseInterval
+.br
+Définit l'intervalle maximum entre les demandes d'information sur les
+imprimantes.
+.TP 5
+BrowseOrder
+.br
+Définit le contrôle d'accès aux informations des imprimantes (allow,deny ou deny,allow).
+.TP 5
+BrowsePoll
+.br
+Définit un serveur récupérant les informations sur les imprimantes.
+.TP 5
+BrowsePort
+.br
+Définit le port utilisé pour les demandes d'informations sur les imprimantes.
+.TP 5
+BrowseRelay
+.br
+Les paquets de demande d'information peuvent être relayés depuis une machine ou
+un réseau vers un autre.
+.TP 5
+BrowseShortNames
+.br
+Définit si les imprimantes distantes utilisent les noms abrégés («\ imprimante\ »)
+ou non («\ imprimante@serveur\ »). Cette option est ignorée si plus d'une imprimante
+distante a le même nom.
+.TP 5
+BrowseTimeout
+.br
+Définit l'intervalle maximum de temps entre deux mises à jour d'informations
+des imprimantes distantes avant que celles-ci ne soient supprimées de la liste
+des imprimantes disponibles.
+.TP 5
+Browsing
+.br
+Définit si la récupération des informations des imprimantes distantes doit être activée.
+.TP 5
+DataDir
+.br
+Définit le répertoire où se trouvent les fichiers de données.
+.TP 5
+DefaultCharset
+.br
+Définit le jeu de caractères par défaut à utiliser pour les textes.
+.TP 5
+DefaultLanguage
+.br
+Définit la langue par défaut à utiliser pour les textes et le site web.
+.TP 5
+Deny
+.br
+Interdit l'accès à une machine nommée ou à une adresse IP.
+.TP 5
+DocumentRoot
+.br
+Définit le répertoire racine des documents du serveur web interne.
+.TP 5
+ErrorLog
+.br
+Définit le nom du fichier traçant les erreurs.
+.TP 5
+Group
+.br
+Définit le nom du groupe ou l'ID qui sera utilisé lors de l'exécution de
+programmes externes.
+.TP 5
+HostNameLookups
+.br
+Définit s'il faut effectuer ou non des recherches de noms à partir des adresses
+des clients.
+.TP 5
+ImplicitClasses
+.br
+Définit s'il faut créer ou non une classe implicite pour les imprimants distantes
+identiques.
+.TP 5
+KeepAlive
+.br
+Définit s'il faut utiliser HTTP-Keep-Alive.
+.TP 5
+KeepAliveTimeout
+.br
+Définit le timeout pour HTTP-Keep-Alive.
+.TP 5
+<Location /path> ... </Location>
+.br
+Définit les contrôles d'accès à une destination donnée.
+.TP 5
+LogLevel
+.br
+Définit le niveau de trace (none, warn, error, info ou debug).
+.TP 5
+MaxClients
+.br
+Définit le nombre maximum de clients simultanés.
+.TP 5
+MaxLogSize
+.br
+Définit la taille maximale des fichiers de trace. Au delà de cette taille, les fichiers
+sont recyclés (on ne garde que les entrées les plus récentes pour supprimer les plus vieilles).
+Indiquer 0 pour supprimer la rotation des fichiers.
+.TP 5
+MaxRequestSize
+.br
+Définit la taille maximale des fichiers et des requêtes à imprimer. La taille
+est exprimée en octets (0 indique qu'il n'y a pas de limite).
+.TP 5
+Order
+.br
+Définit le contrôle d'accès HTTP (allow,deny ou deny,allow).
+.TP 5
+PageLog
+.br
+Définit le fichier de trace des pages web visitées.
+.TP 5
+Port
+.br
+Définit le numéro du port où écouter les requêtes HTTP.
+.TP 5
+PreserveJobFiles
+.br
+Définit s'il faut conserver ou non les fichiers de travail après impression.
+.TP 5
+PreserveJobHistory
+.br
+Définit s'il faut conserver ou non l'historique des demandes d'impression
+une fois qu'elles sont terminées.
+.TP 5
+Printcap
+.br
+Définit l'emplacement du fichier printcap, contenant la liste des imprimantes,
+et qui est mis à jour automatiquement. Ce fichier est indispensable aux
+applications externes.
+.TP 5
+RIPCache
+.br
+Définit la taille maximale de mémoire à utiliser lors de la conversion d'images
+ou de fichiers PostScript en fichier bitmap pour une imprimante.
+.TP 5
+RequestRoot
+.br
+Définit le répertoire où sont stockés les fichiers de travail et les données
+des requêtes HTTP.
+.TP 5
+ServerAdmin
+.br
+Définit l'adresse électronique de l'administrateur du serveur.
+.TP 5
+ServerBin
+.br
+Définit le répertoire où les applications frontales, les CGI, les démons et
+les filtres sont stockés.
+.TP 5
+ServerName
+.br
+Définit le nom complet du serveur.
+.TP 5
+ServerRoot
+.br
+Définit le répertoire où les fichiers de configuration du serveur sont stockés.
+.TP 5
+SystemGroup
+.br
+Définit le groupe à utiliser pour les identifications système.
+.TP 5
+TempDir
+.br
+Définit le répertoire où les fichiers temporaires sont stockés.
+.TP 5
+Timeout
+.br
+Définit le timeout des requêtes HTTP (en secondes).
+.TP 5
+User
+.br
+Définit le nom ou l'identifiant de l'utilisateur utilisé lors du lancement de programmes externes.
+.SH VOIR AUSSI
+classes.conf(5), cupsd(8), mime.convs(5), mime.types(5), printers.conf(5),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: cupsd.conf.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
diff --git a/man/fr/cupsd.man b/man/fr/cupsd.man
new file mode 100644
index 000000000..d36103718
--- /dev/null
+++ b/man/fr/cupsd.man
@@ -0,0 +1,49 @@
+.\"
+.\" "$Id: cupsd.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" cupsd man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2001 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH cupsd 8 "Common UNIX Printing System" "19 Octobre 2000" "Easy Software Products"
+.SH NOM
+cupsd \- common unix printing system daemon
+.SH SYNOPSIS
+.B cupsd
+[ \-c
+.I config-file
+] [ \-f ]
+.SH DESCRIPTION
+\fIcupsd\fR est un programmateur pour le système Common UNIX Printing System. Il fournit des outils pour un système d'impression de base sous le Internet Printing Protocol, version 1.1. Si aucune option n'est spécifiée dans la ligne de commande, alors le fichier de configuration par défaut (habituellement \fI/etc/cups/cupsd.conf\fR) sera utilisé.
+.PP
+L'option \fI-f\fR force \fIcupsd\fR à tourner en avant-plan\ ; par défaut, cupsd tourne en arrière-plan comme «\ démon\ ».
+.SH COMPATIBILITÉ
+\fIcupsd\fR fournit tous les attributs et opération de IPP/1.1. Il implémente aussi plusieurs opérations d'administration spécifiques à CUPS
+.SH VOIR AUSSI
+backend(1), classes.conf(5), cupsd.conf(5), filter(1), mime.convs(5),
+mime.types(5), printers.conf(5),
+CUPS Implementation of IPP,
+CUPS Interface Design Description,
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2001 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: cupsd.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
diff --git a/man/fr/enable.man b/man/fr/enable.man
new file mode 100644
index 000000000..d62b47424
--- /dev/null
+++ b/man/fr/enable.man
@@ -0,0 +1,67 @@
+.\"
+.\" "$Id: enable.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" enable/disable man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH enable 8 "Common UNIX Printing System" "23 Janvier 2001" "Easy Software Products"
+.SH NOM
+disable, enable \- active/désactive les imprimantes et classes
+.SH SYNOPSIS
+.B disable
+[ -E ] [ \-c ] [ -h
+.I serveur
+] [ \-r [
+.I motif
+] ] destination(s)
+.br
+.B enable
+[ -E ] destination(s)
+.SH DESCRIPTION
+\fIenable\fR démarre l'imprimante ou la classe fournie dans la ligne de commande.
+.LP
+\fIdisable\fR arrête l'imprimante ou la classe fournie dans la ligne de commande.
+Les options suivantes peuvent être utilisées\ :
+.TP 5
+\-c
+.br
+Annule les travaux en cours.
+.TP 5
+\-r [ \fImotif\fR ]
+.br
+Associe le message à l'arrêt de la classe ou de l'imprimante. Si aucun motif n'est
+donné, le message est «\ Raison inconnue\ ».
+.LP
+L'option \fI-E\fR force le cryptage lors de la communication au serveur.
+.SH COMPATIBILITÉ
+Les versions CUPS de \fIdisable\fR et \fIenable\fR peuvent demander un mot de
+passe à l'utilisateur suivant la configuration du système d'impression, à la
+différence des versions System V qui demandent le mot de passe root.
+.SH VOIR AUSSI
+accept(8), cancel(1), lp(1), lpadmin(8), lpstat(1), reject(8),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: enable.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
diff --git a/man/fr/filter.man b/man/fr/filter.man
new file mode 100644
index 000000000..50001851e
--- /dev/null
+++ b/man/fr/filter.man
@@ -0,0 +1,119 @@
+.\"
+.\" "$Id: filter.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" filter man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH filter 1 "Common UNIX Printing System" "22 June 2000" "Easy Software Products"
+.SH NOM
+filter \- Interface des filtres de conversion de fichier de CUPS
+.SH SYNOPSIS
+.B filter
+travail utilisateur titre nb_copies options [
+.I nom_de_fichier
+]
+.SH DESCRIPTION
+Les filtres CUPS sont une méthode standard de reconnaissance de nouveaux
+formats de fichier. Un filtre doit être capable de convertir un ou plusieurs
+formats en entrée, et générer un fichier en sortie, dont le format est soit directement
+compréhensible par CUPS, soit retraité par un autre filtre pour obtenir
+un format imprimable.
+.LP
+Ces programmes doivent être capable de lire un fichier de la ligne de
+commande ou via l'entrée standard, si besoin est en recopiant son contenu
+dans un fichier temporaire. Toute sortie doit être faite sur la sortie standard.
+.LP
+Le nom de la commande (argv[0]) est l'URI de l'imprimante.
+.SH VARIABLES D'ENVIRONNEMENT
+Les variables d'environnement suivantes sont définies par le serveur CUPS
+lors de l'exécution d'un filtre\ :
+.TP 5
+CHARSET
+.br
+Le jeu de caractères par défaut (généralement us-ascii ou iso-8859-1).
+.TP 5
+CONTENT_TYPE
+.br
+Le type MIME associé au fichier (ex\ : application/postscript).
+.TP 5
+CUPS_DATADIR
+.br
+Le répertoire où se trouvent les données.
+.TP 5
+CUPS_SERVERROOT
+.br
+Le répertoire racine du serveur.
+.TP 5
+DEVICE_URI
+.br
+L'URI de l'imprimante.
+.TP 5
+LANG
+.br
+La langue (généralement C ou en).
+.TP 5
+PATH
+.br
+La liste des chemins où chercher les programmes pouvant être exécutés
+par le filtre.
+.TP 5
+PPD
+.br
+Le chemin complet d'accès au fichier PPD (PostScript Printer Description)
+de l'imprimante.
+.TP 5
+PRINTER
+.br
+Le nom de l'imprimante, ceci pour les scripts shells qui ne sont pas
+toujours capables de récupérer l'argument argv[0].
+.TP 5
+RIP_CACHE
+.br
+La quantité de mémoire recommandée pour l'utilisation du RIP (Raster Image
+Processors).
+.TP 5
+SOFTWARE
+.br
+Le nom et le numéro de version du serveur (généralement CUPS/1.1).
+.TP 5
+TZ
+.br
+Le fuseau horaire du serveur.
+.TP 5
+USER
+.br
+L'utilisateur exécutant le programme (généralement lp).
+.SH COMPATIBILITÉ
+Bien que l'interface des filtres soit compatible avec les scripts System V,
+ceci ne fonctionnera qu'avec le script System V fourni via la commande
+\fBlpadmin(8)\fR avec l'option \fI-i\fR.
+.SH VOIR AUSSI
+backend(1), cupsd(8),
+CUPS Interface Design Description,
+CUPS Software Administrators Manual,
+CUPS Software Programmers Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: filter.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
diff --git a/man/fr/lp.man b/man/fr/lp.man
new file mode 100644
index 000000000..3e67e1c99
--- /dev/null
+++ b/man/fr/lp.man
@@ -0,0 +1,163 @@
+.\"
+.\" "$Id: lp.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" lp/cancel man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lp 1 "Common UNIX Printing System" "25 Septembre 2001" "Easy Software Products"
+.SH NOM
+lp \- Imprime des fichiers
+.br
+cancel \- Annule des travaux d'impression
+.SH SYNOPSIS
+.B lp
+[ -E ] [ \-c ] [ \-d
+.I destination
+] [ \-h
+.I serveur
+] [ \-m ] [ \-n
+.I nb-copies
+[ \-o
+.I option
+] [ \-q
+.I priorité
+] [ \-s ] [ \-t
+.I titre
+] [ \-H
+.I méthode
+] [ \-P
+.I liste-de-pages
+] [
+.I fichier(s)
+]
+.br
+.B lp
+[ -E ] [ \-c ] [ \-h
+.I serveur
+] [ \-i
+.I numéro-de-travail
+] [ \-n
+.I nb-copies
+[ \-o
+.I option
+] [ \-q
+.I priorité
+] [ \-t
+.I titre
+] [ \-H
+.I méthode
+] [ \-P
+.I liste-de-pages
+]
+.br
+.B cancel
+[ \-a ] [ -h
+.I serveur
+] [
+.I id
+] [
+.I destination
+] [
+.I destination-id
+]
+.SH DESCRIPTION
+\fBlp\fR demande l'impression d'un fichier ou modifie un travail d'impression
+en attente.
+.LP
+\fBcancel\fR annule un travail d'impression. L'option \fI-a\fR supprime tous
+les travaux d'impression d'une destination.
+.SH OPTIONS
+Les options suivantes sont reconnues par \fBlp\fR\ :
+.TP 5
+\-E
+.br
+Force le cryptage des données lors de la connexion au serveur.
+.TP 5
+\-d \fIdestination\fR
+.br
+Imprime les fichiers sur l'imprimante donnée.
+.TP 5
+\-h \fInom-de-machine\fR
+.br
+Demande l'impression sur un serveur d'impression donné. C'est par défaut
+«\ localhost\ » ou le contenu de la variable d'environnement CUPS_SERVER si
+celle-ci existe.
+.TP 5
+\-i \fInuméro-de-travail\fR
+.br
+Donne le numéro du travail d'impression à modifier.
+.TP 5
+\-m
+.br
+Envoie un courrier électronique lorsque l'impression est terminée.
+Cette option n'est pas gérée par CUPS 1.1.
+.TP 5
+\-n \fInb-copies\fR
+.br
+Nombre de copies à effectuer (de 1 à 100).
+.TP 5
+\-o \fIoption\fR
+.br
+Définit une option pour le travail d'impression.
+.TP 5
+\-q \fIpriorité\fR
+.br
+Définit la priorité du travail d'impression, de 1 (minimale) à 100 (maximale).
+La priorité par défaut est 50.
+.TP 5
+\-s
+.br
+N'affiche pas le numéro du travail (mode silencieux).
+.TP 5
+\-t \fInom\fR
+.br
+Définit le nom du travail.
+.TP 5
+\-H \fIméthode\fR
+.br
+Définit quand l'impression doit être effectuée. La valeur \fIimmediate\fR effectue
+l'impression immédiatement, la valeur \fIhold\fR suspend l'impression indéfiniment,
+une valeur, une heure suspend l'impression jusqu'à l'heure donnée. Utilisez la valeur
+\fIresume\fR avec l'option \fI-i\fR pour reprendre un travail suspendu.
+.TP 5
+\-P \fIliste-de-pages\fR
+.br
+Définit quelles sont les pages à imprimer. Cette liste ne peut contenir que des numéros
+ou des portions (#-#), séparés par des virgules (ex\ : 1,3-5,16).
+.SH COMPATIBILITÉ
+Contrairement au système d'impression System V, les imprimantes peuvent contenir n'importe
+quel caractère imprimable sauf ESPACE et TABULATION. De même, les noms d'imprimantes et de
+classes ne sont pas sensibles à la casse.
+.LP
+L'option «\ m\ » n'est pas opérationnelle dans CUPS 1.1.
+.LP
+L'option «\ q\ » accepte des valeurs de 1 à 100, contrairement au lp de Solaris qui
+utilise des valeurs de 0 à 39.
+.SH VOIR AUSSI
+lpstat(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: lp.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
diff --git a/man/fr/lpadmin.man b/man/fr/lpadmin.man
new file mode 100644
index 000000000..81b355ea1
--- /dev/null
+++ b/man/fr/lpadmin.man
@@ -0,0 +1,162 @@
+.\"
+.\" "$Id: lpadmin.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" lpadmin man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpadmin 8 "Common UNIX Printing System" "23 January 2001" "Easy Software Products"
+.SH NOM
+lpadmin \- Configure les imprimantes et classes d'imprimantes de CUPS
+.SH SYNOPSIS
+.B lpadmin
+[ -E ] [ -h
+.I serveur
+] \-d
+.I destination
+.br
+.B lpadmin
+[ -E ] [ -h
+.I serveur
+] \-p
+.I imprimante
+.I option(s)
+.br
+.B lpadmin
+[ -E ] [ -h
+.I serveur
+] \-x
+.I destination
+.SH DESCRIPTION
+\fIlpadmin\fR configure les imprimantes et classes d'imprimantes de CUPS.
+Il est également utilisé pour définir l'imprimante ou classe d'imprimante
+par défaut.
+.LP
+Lorsque l'option \fI-E\fR est spécifiée avant les options \fI-d\fR, \fI-p\fR,
+ou \fI-x\fR, la communication avec le serveur est cryptée.
+.LP
+La première méthode d'utilisation de la commande définit l'imprimante ou la classe
+par défaut. Les impressions futures demandées par les
+commandes \fIlp(1)\fR ou \fIlpr(1)\fR utiliseront cette destination sauf avis
+contraire de l'utilisateur.
+.LP
+La seconde méthode configure une imprimante. Les options disponibles
+sont décrites plus loin.
+.LP
+La troisième méthode supprime l'imprimante ou classe
+\fIdestination\fR. Tous les travaux d'impression en attente sont supprimés,
+et les travaux en cours d'impression sont arrêtés.
+.SH OPTIONS DE CONFIGURATION
+Les options suivantes sont reconnues par la commande \fIlpadmin\fR\ :
+.TP 5
+\-c \fIclasse\fR
+.br
+Ajoute l'imprimante \fIimprimante\fR à la classe \fIclasse\fR. Si la classe
+n'existe pas encore, elle est créée automatiquement.
+.TP 5
+\-i \fIinterface\fR
+.br
+Crée un script d'interface System V pour l'imprimante. Cette option ne
+peut être utilisée en même temps que \fI\-P\fR (fichier PPD) et est destinée
+au support des imprimantes de base.
+.TP 5
+\-m \fImodèle\fR
+.br
+Définit un script d'interface System V ou un fichier PPD à utiliser.
+.TP 5
+\-o \fIname=value\fR
+.br
+Définit une option PPD ou serveur pour une imprimante. La liste des options
+PPD peut être obtenu en utilisant la commande \fIlptions -l\fR.
+.TP 5
+\-o \fIjob-k-limit=valeur\fR
+.br
+Définit les quotas par utilisateur en kilo-octets. La valeur est un nombre
+entier de kilo-octets (valant 1024 octets).
+.TP 5
+\-o \fIjob-page-limit=valeur\fR
+.br
+Définit les quotas par utilisateur en nombre de pages. La valeur est un nombre
+entier de pages pouvant être imprimées. Les recto-verso comptent pour deux
+pages.
+.TP 5
+\-o \fIjob-quota-period=valeur\fR
+.br
+Définit les quotas par utilisateur en impressions par intervalle de temps. La
+valeur est un nombre entier définissant le nombre de secondes entre chaque
+impression. Une journée contient 86400 secondes.
+.TP 5
+\-r \fIclasse\fR
+.br
+Supprime \fIl'imprimante\fR de la \fIclasse\fR. Si la classe d'imprimante devient
+vide, celle-ci est supprimée.
+.TP 5
+\-u \fIallow:user,user\fR
+\-u \fIdeny:user,user\fR
+\-u \fIallow:all\fR
+\-u \fIdeny:none\fR
+.br
+Définit les accès par utilisateur sur une imprimante. Les deux dernières expressions
+suppriment les contrôles d'accès par utilisateur.
+.TP 5
+\-v \fIdevice-uri\fR
+.br
+Définit l'attribut \fIdevice-uri\fR de la file d'attente de l'imprimante. Si \fIdevice-uri\fR
+est un nom de fichier, il est converti automatiquement en la forme \fBfile:/fichier/nom\fR.
+.TP 5
+\-D \fIinfo\fR
+.br
+Définit une description de l'imprimante.
+.TP 5
+\-E
+.br
+Active l'imprimante et lui fait accepter les travaux d'impression. Ceci peut
+également être effectué en lançant les commandes \fIaccept(8)\fR et \fIenable(8)\fR
+sur l'imprimante.
+.TP 5
+\-L \fIlieufR
+.br
+Définit le lieu de l'imprimante.
+.TP 5
+\-P \fIfichier-ppd\fR
+.br
+Définit le fichier PPD (Postscript Printer Description) à utiliser avec cette
+imprimante. Si cette option est spécifiée, elle annule l'option \fI-i\fR
+(script d'interface).
+.SH COMPATIBILITÉ
+Contrairement au système d'impression System V, CUPS permet des noms d'imprimantes
+contenant tout caractère imprimable sauf ESPACE et TABULATION. De plus, les noms
+d'imprimante et de classe ne sont pas sensibles à la casse. De plus, la version
+CUPS peut demander un mot de passe, suivant la configuration du système, à la
+différence de la version System V qui demande le mot de passe root.
+.SH LIMITATIONS
+La version CUPS de \fIlpadmin\fR ne reconnaît pas toutes les options de configuration
+disponibles dans les versions System V ou Solaris.
+.SH VOIR AUSSI
+accept(8), cancel(1), disable(8), enable(8), lp(1), lpstat(1), reject(8),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: lpadmin.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
+
diff --git a/man/fr/lpc.man b/man/fr/lpc.man
new file mode 100644
index 000000000..c320bedec
--- /dev/null
+++ b/man/fr/lpc.man
@@ -0,0 +1,82 @@
+.\"
+.\" "$Id: lpc.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" lpc man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpc 8 "Common UNIX Printing System" "22 Septembre 1999" "Easy Software Products"
+.SH NOM
+lpc \- Programme de contrôle de l'imprimante
+.SH SYNOPSIS
+.B lpc
+[
+.I commande
+[
+.I paramètre(s)
+] ]
+.SH DESCRIPTION
+\fIlpc\fR permet de contrôler partiellement des imprimantes et classes d'imprimantes
+de CUPS. Il est également utilisé pour récupérer l'état des files d'attente.
+.LP
+Si aucune option n'est donnée dans la ligne de commande, \fRlpc\fR affichera une
+invite et prendra ses commandes depuis l'entrée standard.
+.SH COMMANDES
+\fIlpc\fR reconnaît un sous-ensemble des commandes reconnues le programme \fIlpc\fR
+de Berkeley\ :
+.TP 5
+\fIexit
+.br
+Quitte l'interpréteur de commandes.
+.TP 5
+help \fI[commande]\fR
+.br
+Affiche un message d'aide.
+.TP 5
+quit
+.br
+Quitte l'interpréteur de commandes.
+.TP 5
+status \fI[file-attente]\fR
+.br
+Affiche l'état des files d'attente d'une ou plusieurs classes ou imprimantes.
+.TP 5
+? \fI[commande]\fR
+.br
+Affiche un message d'aide.
+.SH LIMITATIONS
+Étant donné que \fIlpc\fR est spécifique au système d'impression de Berkeley, il
+est impossible de l'utiliser pour configurer les files d'attente de CUPS. Pour cela,
+vous devez utiliser le programme \fIlpadmin(8)\fR ou tout autre client compatible
+avec CUPS remplissant ces fonctions.
+.SH COMPATIBILITÉ
+La version CUPS de \fIlpc\fR n'implémente pas toutes les commandes de la version Berkeley.
+.SH VOIR AUSSI
+accept(8), cancel(1), disable(8), enable(8), lp(1), lpr(1), lprm(1),
+lpstat(1), reject(8),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: lpc.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
+
diff --git a/man/fr/lpinfo.man b/man/fr/lpinfo.man
new file mode 100644
index 000000000..289f3d7f6
--- /dev/null
+++ b/man/fr/lpinfo.man
@@ -0,0 +1,63 @@
+.\"
+.\" "$Id: lpinfo.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" lpinfo man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpinfo 8 "Common UNIX Printing System" "23 Janvier 2001" "Easy Software Products"
+.SH NOM
+lpinfo \- Affiche les périphériques et pilotes disponibles
+.SH SYNOPSIS
+.B lpinfo
+[ -E ] [ -l ] [ -m ] [ -v ]
+.SH DESCRIPTION
+\fBlpinfo\fR affiche la liste des périphériques ou pilotes connus par le
+serveur CUPS. Il est impératif d'utiliser une des options \fI-m\fR ou \fI-v\fR
+pour obtenir quelque chose en sortie.
+.TP 5
+\-E
+.br
+Force le cryptage lors de la connexion au serveur.
+.TP 5
+\-l
+.br
+Affiche une liste détaillée des périphériques et pilotes disponibles.
+.TP 5
+\-m
+.br
+Affiche les périphériques disponibles.
+.TP 5
+\-v
+.br
+Affiche les pilotes disponibles.
+.SH COMPATIBILITÉ
+La commande \fBlpinfo\fR est spécifique à CUPS.
+.SH VOIR AUSSI
+lpadmin(8),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: lpinfo.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
+
diff --git a/man/fr/lpmove.man b/man/fr/lpmove.man
new file mode 100644
index 000000000..6eed62d29
--- /dev/null
+++ b/man/fr/lpmove.man
@@ -0,0 +1,57 @@
+.\"
+.\" "$Id: lpmove.man 2540 2002-06-27 19:45:10Z mike $"
+.\"
+.\" lpmove man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpmove 8 "Common UNIX Printing System" "23 Janvier 2001" "Easy Software Products"
+.SH NOM
+lpmove \- Déplace un travail d'impression vers une nouvelle destination
+.SH SYNOPSIS
+.B lpmove
+[ -E ]
+.I ID_du_travail destination
+.SH DESCRIPTION
+\fBlpmove\fR déplace les \fItravaux d'impression\fR vers une nouvelle
+\fIdestination\fR. On peut spécifier le travail sous deux formes\ :
+soit l'ID du travail d'impression, soit ancienne destination et ID du travail.
+Exemple\ :
+.br
+.nf
+
+ lpmove 123 NouvelleImprimante
+ lpmove AncienneImprimante-123 NouvelleImprimante
+.fi
+.LP
+L'option \fI-E\fR force le cryptage des données lors de la connexion au serveur.
+.SH COMPATIBILITÉ
+La version System V de \fBlpmove \fR permet de déplacer tous les travaux d'impression
+d'une file d'attente vers une autre. Cette fonctionnalité n'est pas gérée par CUPS.
+.SH VOIR AUSSI
+cancel(1), lp(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: lpmove.man 2540 2002-06-27 19:45:10Z mike $".
+.\"
diff --git a/man/fr/lpoptions.man b/man/fr/lpoptions.man
new file mode 100644
index 000000000..17244b1c5
--- /dev/null
+++ b/man/fr/lpoptions.man
@@ -0,0 +1,117 @@
+.\"
+.\" "$Id: lpoptions.man 2540 2002-06-27 19:45:10Z mike $"
+.\"
+.\" lpoptions man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpoptions 1 "Common UNIX Printing System" "5 Septembre 2000" "Easy Software Products"
+.SH NOM
+lpoptions \- Affiche et définit les options et paramètres par défaut d'une imprimante
+.SH SYNOPSIS
+.B lpoptions
+[ -h
+.I serveur
+] -d
+.I destination[/instance]
+[ -o
+.I option=valeur
+] ... [ -o
+.I option=valeur
+]
+.br
+.B lpoptions
+[ -h
+.I serveur
+] [ -p
+.I destination[/instance]
+] -l
+.br
+.B lpoptions
+[ -h
+.I serveur
+] [ -o
+.I option=valeur
+] ... [ -o
+.I option=valeur
+] -p
+.I dest[/instance]
+] -r
+.I option
+]
+.br
+.B lpoptions
+[ -h
+.I serveur
+] -x
+.I destination[/instance]
+.SH DESCRIPTION
+Lorsqu'il est lancé sans arguments, \fBlpoptions\fR affiche les options
+par défaut. Les paramètres pouvant être fournis sont\ :
+.TP 5
+\-d \fIdestination[/instance]\fR
+.br
+Définit \fIdestination\fR comme imprimante par défaut. Il est également
+possible de fournir une \fIinstance\fR. Cette option redéfinit
+l'imprimante par défaut de l'utilisateur en cours.
+.TP 5
+\-h \fIserveur\fR
+.br
+Définit le serveur CUPS avec lequel communiquer.
+.TP 5
+\-l
+.br
+Affiche les options spécifiques d'une imprimante et leur paramétrage.
+.TP 5
+\-o \fIoption=valeur\fR
+.br
+Définit une nouvelle option pour une destination.
+.TP 5
+\-p \fIdestination[/instance]\fR
+.br
+Définit les options d'une destination ou instance. Si l'instance n'existe
+pas, celle-ci est créée.
+.TP 5
+\-r \fIoption\fR
+.br
+Supprime une option de la destination fournie en paramètre.
+.TP 5
+\-x \fIdestination[/instance]\fR
+.br
+Supprime toutes les options de la destination ou instance fournie en
+paramètre. Si l'instance n'existe pas, la commande n'a pas d'effet.
+.LP
+Si aucune option n'est fournie dans la ligne de commande, les options
+de l'imprimante fournie en paramètre sont affichées sur la sortie standard.
+.LP
+Les options définies par la commande \fBlpoptions\fR sont utilisées par les
+commandes \fBlp(1)\fR et \fBlpr(1)\fR lors de l'envoi de travaux d'impression.
+.SH COMPATIBILITÉ
+La commande \fBlpoptions\fR est spécifique à CUPS.
+.SH VOIR AUSSI
+cancel(1), lp(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: lpoptions.man 2540 2002-06-27 19:45:10Z mike $".
+.\"
diff --git a/man/fr/lppasswd.man b/man/fr/lppasswd.man
new file mode 100644
index 000000000..acaba136f
--- /dev/null
+++ b/man/fr/lppasswd.man
@@ -0,0 +1,63 @@
+.\"
+.\" "$Id: lppasswd.man 2540 2002-06-27 19:45:10Z mike $"
+.\"
+.\" lpadmin man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lppasswd 1 "Common UNIX Printing System" "7 Juin 2001" "Easy Software Products"
+.SH NOM
+lppasswd \- Ajoute, modifie ou supprime des mots de passe
+.SH SYNOPSIS
+.B lppasswd
+[ -a ] [ -g
+.I groupe
+] [ -x ] [
+.I utilisateur
+]
+.SH DESCRIPTION
+\fIlppasswd\fR ajoute, modifie ou supprime des mots de passe du fichier
+\fIpasswd.md5\fR. Lorsque ce programme est lancé par un utlisateur non privilégié,
+il demande l'ancien et le nouveau mot de passe. Lorsque ce programme est lancé par
+un super-utilisateur, il peut créer de nouveaux comptes utilisateurs (\fI-a utilisateur\fR),
+modifier des comptes existants (\fIutilisateur\fR), ou supprimer des comptes
+(\fI-x utilisateur\fR). Les noms d'utilisateurs ne doivent pas forcément correspondre
+à des noms d'utilisateurs UNIX. Cependant, seuls les utilisateurs UNIX sont gérés
+par les programmes clients CUPS (\fIlp(1)\fR, \fIlpr(1)\fR, etc.)
+.LP
+L'option \fI-g\fR définit un groupe autre que le groupe système -\ «\ sys\ »,
+«\ system\ », «\ root\ », suivant le système d'exploitation.
+.SH PROBLÈMES DE SÉCURITÉ
+La commande \fIlppasswd\fR est installée avec le bit setuid activé. Toutes les précautions
+ont été prises pour empêcher les exploits permettant l'accès aux privilèges du
+super-utilisateur par un utilisateur non privilégié. Cependant, certains administrateurs
+systèmes (paranoïaques) peuvent vouloir désactiver ce programme ou en modifier le
+propriétaire par un utilisateur non privilégié.
+.SH VOIR AUSSI
+lp(1), lpr(1),
+CUPS Software Administrators Manual,
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: lppasswd.man 2540 2002-06-27 19:45:10Z mike $".
+.\"
diff --git a/man/fr/lpq.man b/man/fr/lpq.man
new file mode 100644
index 000000000..dfdfce51c
--- /dev/null
+++ b/man/fr/lpq.man
@@ -0,0 +1,59 @@
+.\"
+.\" "$Id: lpq.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" lpq man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2001 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpq 1 "Common UNIX Printing System" "13 Février 2001" "Easy Software Products"
+.SH NOM
+lpq \- Affiche les travaux en attente d'une imprimante
+.SH SYNOPSIS
+.B lpq
+[ -E ] [ \-P
+.I destination
+] [ \-a ] [ \-l ] [
+.I +intervalle
+]
+.SH DESCRIPTION
+\fIlpq\fR affiche les travaux en attente d'une imprimante. Si aucune imprimante
+ou classe n'est donnée dans la ligne de commande, les travaux en attente
+sur la destination par défaut seront affichés.
+.LP
+L'option \fIintervalle\fR permet d'afficher les travaux en attente en continu
+jusqu'à ce qu'il n'y en ait plus. La liste est réaffichée toutes les \fIintervalle\fR
+secondes.
+.LP
+L'option \fI-E\fR force le cryptage lors de la connexion au serveur.
+.LP
+L'option \fI-a\fR affiche les travaux de toutes les imprimantes.
+.LP
+L'option \fI-l\fR affiche les travaux dans un format verbeux.
+.SH VOIR AUSSI
+cancel(1), lp(1), lpr(1), lprm(1), lpstat(1)
+.br
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2001 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: lpq.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
diff --git a/man/fr/lpr.man b/man/fr/lpr.man
new file mode 100644
index 000000000..76bdbe8f4
--- /dev/null
+++ b/man/fr/lpr.man
@@ -0,0 +1,106 @@
+.\"
+.\" "$Id: lpr.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" lpr man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpr 1 "Common UNIX Printing System" "23 Janvier 2001" "Easy Software Products"
+.SH NOM
+lpr \- Imprime des fichiers
+.SH SYNOPSIS
+.B lpr
+[ -E ] [ \-P
+.I destination
+] [ \-#
+.I nombre de copies
+[ \-l ] [ \-o
+.I option
+] [ \-p] [ \-r ] [ \-C/J/T
+.I titre
+] [
+.I fichier(s)
+]
+.SH DESCRIPTION
+\fBlpr\fR demande l'impression de fichiers. Si des fichiers sont donnés dans la
+ligne de commande, ceux-ci sont envoyés à la destination donnée (ou la destination
+par défaut si aucune n'est fournie).
+Si aucun fichier n'est donné dans la ligne de commande, \fBlpr\fR lit les fichiers
+sur l'entrée standard.
+.SH OPTIONS
+Les options suivantes sont reconnues par \fBlpr\fR\ :
+.TP 5
+\-E
+.br
+Force le cryptage lors de la connexion au serveur.
+.TP 5
+\-P \fIdestination\fR
+.br
+Imprime les fichiers vers l'imprimante donnée.
+.TP 5
+\-# \fInombre de copies\fR
+.br
+Définit le nombre de copies (de 1 à 100).
+.TP 5
+\-C \fInom\fR
+.br
+Définit le nom du travail d'impression.
+.TP 5
+\-J \fInom\fR
+.br
+Définit le nom du travail d'impression.
+.TP 5
+\-T \fInom\fR
+.br
+Définit le nom du travail d'impression.
+.TP 5
+\-l
+.br
+Spécifie que le fichier est déjà formaté pour la destination, et qu'aucun
+filtre n'a besoin d'être appliqué. Cette option est équivalente à «\ -oraw\ ».
+.TP 5
+\-o \fIoption\fR
+.br
+Définit une option pour le travail d'impression.
+.TP 5
+\-p
+.br
+Spécifie que chaque page du fichier à imprimer doit avoir un en-tête ombré,
+contenant la date, l'heure, le nom du travail d'impression et le numéro de page.
+Cette option est équivalente à «\ -oprettyprint\ » et n'est utile que dans le cas de
+fichiers texte.
+.TP 5
+\-r
+.br
+Spécifie que les fichiers doivent être effacés après impression.
+.SH COMPATIBILITÉ
+Les options «\ c\ », «\ d\ », «\ f\ », «\ g\ », «\ i\ », «\ m\ », «\ n\ »,
+«\ t\ », «\ v\ » et «\ w\ » ne sont pas supportées par CUPS et donnent un
+message d'avertissement lorsqu'elles sont utilisées.
+.SH VOIR AUSSI
+cancel(1), lp(1), lpstat(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: lpr.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
diff --git a/man/fr/lprm.man b/man/fr/lprm.man
new file mode 100644
index 000000000..3f809fd44
--- /dev/null
+++ b/man/fr/lprm.man
@@ -0,0 +1,56 @@
+.\"
+.\" "$Id: lprm.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" lprm man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lprm 1 "Common UNIX Printing System" "23 Janvier 2001" "Easy Software Products"
+.SH NOM
+lprm \- Annule des travaux d'impression
+.SH SYNOPSIS
+.B lprm
+[ -E ] [ - ] [ -P
+.I destination
+] [
+.I ID(s) des travaux d'impression
+]
+.SH DESCRIPTION
+\fBlprm\fR annule des travaux d'impression en attente. L'option \fI-P\fR spécifie
+l'imprimante ou la classe de destination.
+.LP
+Si aucun argument n'est fourni, c'est le travail en cours sur la destination par
+défaut qui est annulé. Il est possible de fournir un ou plusieurs ID de travaux
+d'impression à annuler, ou utiliser l'option \fI\-\fR pour annuler tous les
+travaux.
+.LP
+L'option \fI-E\fR force le cryptage lors de la connexion au serveur.
+.SH COMPATIBILITÉ
+La version CUPS de \fIlprm\fR est compatible avec la version standard Berkeley.
+.SH VOIR AUSSI
+cancel(1), lp(1), lpstat(1), lpr(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: lprm.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
diff --git a/man/fr/lpstat.man b/man/fr/lpstat.man
new file mode 100644
index 000000000..5351fb0fc
--- /dev/null
+++ b/man/fr/lpstat.man
@@ -0,0 +1,134 @@
+.\"
+.\" "$Id: lpstat.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" lpstat man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpstat 1 "Common UNIX Printing System" "23 January 2001" "Easy Software Products"
+.SH NOM
+lpstat \- Affiche l'état de CUPS
+.SH SYNOPSIS
+.B lpstat
+[ -E ] [ -a [
+.I destination(s)
+] ] [ -c [
+.I classe(s)
+] [ -d ] [ -h
+.I serveur
+] [ -l ] [ -o [
+.I destination(s)
+] ] [ -p [
+.I imprimante(s)
+] ] [ -r ] [ -R ] [ -s ] [ -t ] [ -u [
+.I utilisateur(s)
+] ] [ -v [
+.I imprimante(s)
+] ]
+.SH DESCRIPTION
+\fBlpstat\fR affiche l'état des classes, travaux et imprimantes.
+Quand \fBlpstat\fR est lancé sans arguments, la liste des travaux en attente
+de l'utilisateur est affichée. Les autres options sont\ :
+.TP 5
+\-E
+.br
+Force le cryptage lors de la connexion au serveur.
+.TP 5
+\-a [\fIimprimante(s)\fR]
+.br
+Vérifie si les files d'attente des imprimantes acceptent les travaux d'impression.
+Si aucune imprimante n'est fournie dans la ligne de commande, toutes les imprimantes
+sont affichées.
+.TP 5
+\-c [\fIclasse(s)\fR]
+.br
+Affiche la classe d'imprimantes et ses imprimantes associées. Si aucune classe n'est
+fournie dans la ligne de commande, toutes les classes sont affichées.
+.TP 5
+\-d
+.br
+Affiche la destination par défaut.
+.TP 5
+\-h \fIserver\fR
+.br
+Définit le serveur CUPS où envoyer la requête.
+.TP 5
+\-l
+.br
+Affiche une liste détaillée des imprimantes, classes et travaux d'impression.
+.TP 5
+\-o [\fIdestination(s)\fR]
+.br
+Affiche la file d'attente des travaux sur les destinations spécifiées. Si aucune
+destination n'est fournie dans la ligne de commande, tous les travaux sont affichés.
+.TP 5
+\-p [\fIimprimante(s)\fR]
+.br
+Affiche les imprimantes et si elles sont prêtes ou non à l'impression. Si aucune
+imprimante n'est fournie dans la ligne de commande, toutes les imprimantes sont affichées.
+.TP 5
+\-r
+.br
+Affiche si le serveur CUPS est actif.
+.TP 5
+\-R
+.br
+Affiche le rang des travaux d'impressions.
+.TP 5
+\-s
+.br
+Affiche l'état détaillé, comprenant la destination par défaut, la liste
+des classes et leurs imprimantes associées, la liste des imprimantes et leur
+périphérique. Ceci peut être effectué en utilisant les options "-d", "-c" et "-p".
+.TP 5
+\-t
+.br
+Affiche toutes les informations. Ceci peut être effectué en utilisant les options
+"-r", "-d", "-c", "-d", "-v", "-a", "-p", et "-o".
+.TP 5
+\-u [\fIutilisateur(s)\fR]
+.br
+Affiche les travaux d'impression en attente d'un utilisateur. Si aucun utilisateur
+n'est fourni dans la ligne de commande, affiche les travaux de l'utilisateur qui lance
+la commande.
+.TP 5
+\-v [\fIimprimante(s)\fR]
+.br
+Affiche les imprimantes et à quel matériel elles sont rattachées. Si aucune imprimante
+n'est fournie dans
+la ligne de commande, toutes les imprimantes sont affichées.
+.SH COMPATIBILITÉ
+Contrairement au système d'impression System V, CUPS permet des noms d'imprimantes
+contenant tout caractère imprimable sauf ESPACE et TABULATION. De plus, les noms
+d'imprimante et de classe ne sont pas sensibles à la casse.
+.LP
+L'option System V «\ -h\ » n'est pas reconnue.
+.LP
+Les options «\ -f\ », «\ -P\ » et «\ -S\ » de Solaris sont ignorées.
+.SH VOIR AUSSI
+cancel(1), lp(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" "$Id: lpstat.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
diff --git a/man/fr/mime.convs.man b/man/fr/mime.convs.man
new file mode 100644
index 000000000..fa393a255
--- /dev/null
+++ b/man/fr/mime.convs.man
@@ -0,0 +1,59 @@
+.\"
+.\" "$Id: mime.convs.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" mime.convs man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH mime.convs 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products"
+.SH NOM
+mime.convs \- Fichier de conversion des types MIME de CUPS
+.SH DESCRIPTION
+Le fichier \fImime.convs\fR définit les filtres disponibles pour
+convertir des fichiers d'un format vers un autre. Les filtres
+standards concernent les fichiers textes, PDF, PostScript, HP-GL/2
+ainsi que plusieurs formats graphiques.
+.LP
+Des filtres supplémentaires peuvent être ajoutés dans le fichier
+\fImime.convs\fR ou dans d'autres fichiers portant l'extension
+«\ .convs\ » dans le répertoire de configuration de CUPS (généralement
+\fB/etc/cups\fR).
+.LP
+Chaque ligne du fichier \fImime.convs\fR est un commentaire,
+une ligne vide ou une définition de filtre. Les commentaires commencent
+par le caractère #. Les lignes contenant un filtre spécifient les types
+MIME source et cible, le coût du filtre, puis le filtre lui-même\ :
+.br
+.nf
+
+super/type super/type coût filtre
+application/postscript application/vnd.cups-raster 50 pstoraster
+.fi
+.SH VOIR AUSSI
+classes.conf(5), cupsd(8), cupsd.conf(5), mime.types(5), printers.conf(5),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: mime.convs.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
+
diff --git a/man/fr/mime.types.man b/man/fr/mime.types.man
new file mode 100644
index 000000000..71cf30c8a
--- /dev/null
+++ b/man/fr/mime.types.man
@@ -0,0 +1,104 @@
+.\"
+.\" "$Id: mime.types.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" mime.types man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH mime.types 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products"
+.SH NOM
+mime.types \- Fichier de description des types MIME de CUPS
+.SH DESCRIPTION
+Le fichier \fImime.types\fR définit les types de fichier reconnus par CUPS.
+.LP
+D'autres types de fichiers peuvent être ajoutés au fichier \fImime.types\fR
+ou à d'autres fichier dans le répertoire \fB/etc/cups\fR. Ceux-ci doivent
+porter l'extension «\ .types\ ».
+.LP
+Chaque ligne du fichier \fImime.types\fR est soit une règle, soit
+une ligne vide, soit un commentaire (ligne commençant par le caractère
+#). Chaque ligne définissant une règle commence par le nom du type MIME,
+et peut être suivi par une liste de règle des reconnaissance utilisées
+pour déterminer le type du fichier\ :
+.br
+.nf
+
+ super/type règle [ ... règleN]
+.fi
+Ces règles doivent être mises entre parenthèses, liées par un "+" pour
+exprimer un ET logique, "," ou une espace pour exprimer un OU logique.
+Elles sont précédées de "!" pour exprimer un NON logique.
+.SH RÈGLES
+Les règles sont composées de deux parties\ : une extension de fichier et des
+fonctions de tests entre parenthèses. Les fonctions suivantes peuvent être
+utilisées\ :
+.TP 5
+match("motif")
+.br
+Reconnaissance d'un motif sur le nom du fichier
+.TP 5
+ascii(début, longueur)
+.br
+Vrai si tous les octets de la portion de document sont des caractères ASCII
+imprimables (CR, NL, TAB, BS, 32-126)
+.TP 5
+printable(début, longueur)
+.br
+Vrai si tous les octets de la portion de document sont des caractères 8 bits
+imprimables (CR, NL, TAB, BS, 32-126, 128-254)
+.TP 5
+string(début, "chaîne")
+.br
+Vrai si les octets sont identiques à "chaîne"
+.TP 5
+char(début, valeur)
+.br
+Vrai si les octets sont identiques
+.TP 5
+short(début, valeur)
+.br
+Vrai si les nombres entiers (16 bits) sont identiques
+.TP 5
+int(début, valeur)
+.br
+Vrai si les nombres entiers (32 bits) sont identiques
+.TP 5
+locale("chaîne")
+.br
+Vrai si les définitions de langage sont identiques
+.TP 5
+contains(début, portée, "chaîne")
+.br
+Vrai si la chaîne est trouvée dans la portion de document
+.SH CHAÎNES DE CARACTÈRES
+Les chaînes de caractères peuvent être définies entre guillemets ("")
+pour des chaînes contenant des espaces ou entre crochets (<>) pour des
+chaînes en hexadécimal.
+.SH VOIR AUSSI
+classes.conf(5), cupsd(8), cupsd.conf(5), mime.convs(5), printers.conf(5),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: mime.types.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
+
diff --git a/man/fr/printers.conf.man b/man/fr/printers.conf.man
new file mode 100644
index 000000000..d558020b8
--- /dev/null
+++ b/man/fr/printers.conf.man
@@ -0,0 +1,75 @@
+.\"
+.\" "$Id: printers.conf.man 2429 2002-05-21 19:59:43Z mike $"
+.\"
+.\" printers.conf man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH printers.conf 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products"
+.SH NOM
+printers.conf \- Fichier de configuration des imprimantes CUPS
+.SH DESCRIPTION
+Le fichier \fIprinters.conf\fR définit les imprimantes locales
+de la machine. Il est habituellement situé dans le répertoire \fI/etc/cups\fR
+et est généré automatiquement par le programme \fIcupsd(8)\fR lors
+de l'ajout ou de la suppression d'imprimantes.
+.LP
+Chaque ligne du fichier est une directive de configuration, une ligne
+vide ou un commentaire (ligne commençant par la caractère #).
+.SH DIRECTIVES
+.TP 5
+Accepting
+.br
+Définit si l'imprimante accepte ou non les travaux d'impression.
+.TP 5
+Info
+.br
+Définit un commentaire de description de l'imprimante.
+.TP 5
+Location
+.br
+Définit un commentaire concernant la localisation physique de l'imprimante.
+.TP 5
+DeviceURI
+.br
+Définit l'URI de l'imprimante.
+.TP 5
+<Printer name> ... </Printer>
+.br
+Définit une imprimante.
+.TP 5
+State
+.br
+Définit l'état initial de l'imprimante (Idle ou Stopped).
+.TP 5
+StateMessage
+.br
+Définit le message associé à cet état.
+.SH VOIR AUSSI
+classes.conf(5), cupsd(8), cupsd.conf(5), mime.convs(5), mime.types(5),
+CUPS Software Administrators Manual,
+CUPS Interface Design Description,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+.SH TRADUCTION
+Gilles QUERRET <gilles.querret@nerim.net>
+.\"
+.\" End of "$Id: printers.conf.man 2429 2002-05-21 19:59:43Z mike $".
+.\"
diff --git a/man/lp.man b/man/lp.man
new file mode 100644
index 000000000..21a1ea8cd
--- /dev/null
+++ b/man/lp.man
@@ -0,0 +1,168 @@
+.\"
+.\" "$Id: lp.man 2371 2002-05-02 20:42:28Z mike $"
+.\"
+.\" lp/cancel man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lp 1 "Common UNIX Printing System" "25 September 2001" "Easy Software Products"
+.SH NAME
+lp \- print files
+.br
+cancel \- cancel jobs
+.SH SYNOPSIS
+.B lp
+[ -E ] [ \-c ] [ \-d
+.I destination
+] [ \-h
+.I server
+] [ \-m ] [ \-n
+.I num-copies
+[ \-o
+.I option
+] [ \-q
+.I priority
+] [ \-s ] [ \-t
+.I title
+] [ \-H
+.I handling
+] [ \-P
+.I page-list
+] [
+.I file(s)
+]
+.br
+.B lp
+[ -E ] [ \-c ] [ \-h
+.I server
+] [ \-i
+.I job-id
+] [ \-n
+.I num-copies
+[ \-o
+.I option
+] [ \-q
+.I priority
+] [ \-t
+.I title
+] [ \-H
+.I handling
+] [ \-P
+.I page-list
+]
+.br
+.B cancel
+[ \-a ] [ -h
+.I server
+] [
+.I id
+] [
+.I destination
+] [
+.I destination-id
+]
+.SH DESCRIPTION
+\fBlp\fR submits files for printing or alters a pending job.
+.LP
+\fBcancel\fR cancels existing print jobs. The \fI-a\fR option will remove
+all jobs from the specified destination.
+.SH OPTIONS
+The following options are recognized by \fBlp\fR:
+.TP 5
+\-E
+.br
+Forces encryption when connecting to the server.
+.TP 5
+\-c
+.br
+This option is provided for backwards-compatibility only. On
+systems that support it, this option forces the print file to be
+copied to the spool directory before printing. In CUPS, print
+files are always sent to the scheduler via IPP which has the
+same effect.
+.TP 5
+\-d \fIdestination\fR
+.br
+Prints files to the named printer.
+.TP 5
+\-h \fIhostname\fR
+.br
+Specifies the print server hostname. The default is "localhost" or the value
+of the CUPS_SERVER environment variable.
+.TP 5
+\-i \fIjob-id\fR
+.br
+Specifies an existing job to modify.
+.TP 5
+\-m
+.br
+Send email when the job is completed (not supported CUPS 1.1.)
+.TP 5
+\-n \fIcopies\fR
+.br
+Sets the number of copies to print from 1 to 100.
+.TP 5
+\-o \fIoption\fR
+.br
+Sets a job option.
+.TP 5
+\-q \fIpriority\fR
+.br
+Sets the job priority from 1 (lowest) to 100 (highest). The
+default priority is 50.
+.TP 5
+\-s
+.br
+Do not report the resulting job IDs (silent mode.)
+.TP 5
+\-t \fIname\fR
+.br
+Sets the job name.
+.TP 5
+\-H \fIhandling\fR
+.br
+Specifies when the job should be printed. A value of
+\fIimmediate\fR will print the file immediately, a value of
+\fIhold\fR will hold the job indefinitely, and a time value
+(HH:MM) will hold the job until the specified time. Use a value
+of \fIresume\fR with the \fI-i\fR option to resume a held job.
+.TP 5
+\-P \fIpage-list\fR
+.br
+Specifies which pages to print in the document. The list can contain a
+list of numbers and ranges (#-#) separated by commas (e.g. 1,3-5,16).
+.SH COMPATIBILITY
+Unlike the System V printing system, CUPS allows printer names to contain
+any printable character except SPACE and TAB. Also, printer and class names are
+\fBnot\fR case-sensitive.
+.LP
+The "m" option is not functional in CUPS 1.1.
+.LP
+The "q" option accepts a different range of values than the
+Solaris lp command, matching the IPP job priority values (1-100)
+instead of the Solaris values (0-39).
+.SH SEE ALSO
+lpstat(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: lp.man 2371 2002-05-02 20:42:28Z mike $".
+.\"
diff --git a/man/lpadmin.man b/man/lpadmin.man
new file mode 100644
index 000000000..041388174
--- /dev/null
+++ b/man/lpadmin.man
@@ -0,0 +1,156 @@
+.\"
+.\" "$Id: lpadmin.man 2137 2002-02-12 18:47:13Z mike $"
+.\"
+.\" lpadmin man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpadmin 8 "Common UNIX Printing System" "23 January 2001" "Easy Software Products"
+.SH NAME
+lpadmin \- configure cups printers and classes
+.SH SYNOPSIS
+.B lpadmin
+[ -E ] [ -h
+.I server
+] \-d
+.I destination
+.br
+.B lpadmin
+[ -E ] [ -h
+.I server
+] \-p
+.I printer
+.I option(s)
+.br
+.B lpadmin
+[ -E ] [ -h
+.I server
+] \-x
+.I destination
+.SH DESCRIPTION
+\fIlpadmin\fR configures printer and class queues provided by CUPS. It can also
+be used to set the system default printer or class.
+.LP
+When specified before the \fI-d\fR, \fI-p\fR, or \fI-x\fR options,
+the \fI-E\fR option forces encryption when connecting to the server.
+.LP
+The first form of the command sets the default printer or class to
+\fIdestination\fR. Subsequent print jobs submitted via the \fIlp(1)\fR or
+\fIlpr(1)\fR commands will use this destination unless the user specifies
+otherwise.
+.LP
+The second form of the command configures the named printer. The additional
+options are described below.
+.LP
+The third form of the command deletes the printer or class \fIdestination\fR.
+Any jobs that are pending for the destination will be removed and any job that
+is currently printed will be aborted.
+.SH CONFIGURATION OPTIONS
+The following options are recognized when configuring a printer queue:
+.TP 5
+\-c \fIclass\fR
+.br
+Adds the named \fIprinter\fR to \fIclass\fR. If \fIclass\fR does not
+exist it is created automatically.
+.TP 5
+\-i \fIinterface\fR
+.br
+Sets a System V style interface script for the printer. This option cannot
+be specified with the \fI\-P\fR option (PPD file) and is intended for
+providing support for legacy printer drivers.
+.TP 5
+\-m \fImodel\fR
+.br
+Sets a standard System V interface script or PPD file from the model
+directory.
+.TP 5
+\-o \fIname=value\fR
+.br
+Sets a PPD or server option for the printer. PPD options can be listed
+using the \fI-l\fR option with the \fIlpoptions(1)\fR command.
+.TP 5
+\-o \fIjob-k-limit=value\fR
+.br
+Sets the kilobyte limit for per-user quotas. The value is an integer number
+of kilobytes; one kilobyte is 1024 bytes.
+.TP 5
+\-o \fIjob-page-limit=value\fR
+.br
+Sets the page limit for per-user quotas. The value is the integer number of
+pages that can be printed; double-sided pages are counted as two pages.
+.TP 5
+\-o \fIjob-quota-period=value\fR
+.br
+Sets the accounting period for per-user quotas. The value is an integer number
+of seconds; 86,400 seconds are in one day.
+.TP 5
+\-r \fIclass\fR
+.br
+Removes the named \fIprinter\fR from \fIclass\fR. If the resulting class
+becomes empty it is removed.
+.TP 5
+\-u \fIallow:user,user\fR
+\-u \fIdeny:user,user\fR
+\-u \fIallow:all\fR
+\-u \fIdeny:none\fR
+.br
+Sets user-level access control on a printer. The latter two forms turn
+user-level access control off.
+.TP 5
+\-v \fIdevice-uri\fR
+.br
+Sets the \fIdevice-uri\fR attribute of the printer queue. If \fIdevice-uri\fR
+is a filename it is automatically converted to the form \fBfile:/file/name\fR.
+.TP 5
+\-D \fIinfo\fR
+.br
+Provides a textual description of the printer.
+.TP 5
+\-E
+.br
+Enables the printer and accepts jobs; this is the same as running the
+\fIaccept(8)\fR and \fIenable(8)\fR programs on the printer.
+.TP 5
+\-L \fIlocation\fR
+.br
+Provides a textual location of the printer.
+.TP 5
+\-P \fIppd-file\fR
+.br
+Specifies a PostScript Printer Description file to use with the printer. If
+specified, this option overrides the \fI-i\fR option (interface script).
+.SH COMPATIBILITY
+Unlike the System V printing system, CUPS allows printer names to contain
+any printable character except SPACE and TAB. Also, printer and class names are
+\fBnot\fR case-sensitive. Finally, the CUPS version of \fIlpadmin\fR may ask the
+user for an access password depending on the printing system configuration.
+This differs from the System V version which requires the root user to execute
+this command.
+.SH LIMITATIONS
+The CUPS version of \fIlpadmin\fR does not support all of the System V or
+Solaris printing system configuration options.
+.SH SEE ALSO
+accept(8), cancel(1), disable(8), enable(8), lp(1), lpstat(1), reject(8),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: lpadmin.man 2137 2002-02-12 18:47:13Z mike $".
+.\"
diff --git a/man/lpc.man b/man/lpc.man
new file mode 100644
index 000000000..e3e5c6ebe
--- /dev/null
+++ b/man/lpc.man
@@ -0,0 +1,80 @@
+.\"
+.\" "$Id: lpc.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" lpc man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpc 8 "Common UNIX Printing System" "22 September 1999" "Easy Software Products"
+.SH NAME
+lpc \- line printer control program
+.SH SYNOPSIS
+.B lpc
+[
+.I command
+[
+.I parameter(s)
+] ]
+.SH DESCRIPTION
+\fIlpc\fR provides limited control over printer and class queues provided by
+CUPS. It can also be used to query the state of queues.
+.LP
+If no command is specified on the command-line, \fRlpc\fR will display a
+prompt and accept commands from the standard input.
+.SH COMMANDS
+The \fIlpc\fR program accepts a subset of commands accepted by the Berkeley
+\fIlpc\fR program of the same name:
+.TP 5
+\fIexit
+.br
+Exits the command interpreter.
+.TP 5
+help \fI[command]\fR
+.br
+Displays a short help message.
+.TP 5
+quit
+.br
+Exits the command interpreter.
+.TP 5
+status \fI[queue]\fR
+.br
+Displays the status of one or more printer or class queues.
+.TP 5
+? \fI[command]\fR
+.br
+Display a short help message.
+.SH LIMITATIONS
+Since \fIlpc\fR is geared towards the Berkeley printing system, it is impossible
+to use \fIlpc\fR to configure printer or class queues provided by CUPS. To
+configure printer or class queues you must use the \fIlpadmin(8)\fR command
+or another CUPS-compatible client with that functionality.
+.SH COMPATIBILITY
+The CUPS version of \fIlpc\fR does not implement all of the standard Berkeley
+commands.
+.SH SEE ALSO
+accept(8), cancel(1), disable(8), enable(8), lp(1), lpr(1), lprm(1),
+lpstat(1), reject(8),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: lpc.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/lpinfo.man b/man/lpinfo.man
new file mode 100644
index 000000000..99ed6b3a9
--- /dev/null
+++ b/man/lpinfo.man
@@ -0,0 +1,60 @@
+.\"
+.\" "$Id: lpinfo.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" lpinfo man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpinfo 8 "Common UNIX Printing System" "23 January 2001" "Easy Software Products"
+.SH NAME
+lpinfo \- show available devices or drivers
+.SH SYNOPSIS
+.B lpinfo
+[ -E ] [ -l ] [ -m ] [ -v ]
+.SH DESCRIPTION
+\fBlpinfo\fR lists the available devices or drivers known to the CUPS
+server. One of the \fI-m\fR or \fI-v\fR options must be specified to
+get any output:
+.TP 5
+\-E
+.br
+Forces encryption when connecting to the server.
+.TP 5
+\-l
+.br
+Shows a "long" listing of devices or drivers.
+.TP 5
+\-m
+.br
+Shows the available printer drivers on the system.
+.TP 5
+\-v
+.br
+Shows the available printer devices on the system.
+.SH COMPATIBILITY
+The \fBlpinfo\fR command is unique to CUPS.
+.SH SEE ALSO
+lpadmin(8),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: lpinfo.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/lpmove.man b/man/lpmove.man
new file mode 100644
index 000000000..bcbe13dfd
--- /dev/null
+++ b/man/lpmove.man
@@ -0,0 +1,53 @@
+.\"
+.\" "$Id: lpmove.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" lpmove man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpmove 8 "Common UNIX Printing System" "23 January 2001" "Easy Software Products"
+.SH NAME
+lpmove \- move a job to a new destination
+.SH SYNOPSIS
+.B lpmove
+[ -E ]
+.I job destination
+.SH DESCRIPTION
+\fBlpmove\fR moves the specified \fIjob\fR to \fIdestination\fR. \fIjob\fR
+can be the job ID number or the old destination and job ID:
+.br
+.nf
+
+ lpmove 123 newprinter
+ lpmove oldprinter-123 newprinter
+.fi
+.LP
+The \fI-E\fR option forces encryption when connecting to the server.
+.SH COMPATIBILITY
+The System V version of this command also allows moving of all jobs from one
+queue to another. This functionality is currently not supported by CUPS.
+.SH SEE ALSO
+cancel(1), lp(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: lpmove.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/lpoptions.man b/man/lpoptions.man
new file mode 100644
index 000000000..cb02414b9
--- /dev/null
+++ b/man/lpoptions.man
@@ -0,0 +1,115 @@
+.\"
+.\" "$Id: lpoptions.man 2599 2002-08-09 00:00:55Z mike $"
+.\"
+.\" lpoptions man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpoptions 1 "Common UNIX Printing System" "5 September 2000" "Easy Software Products"
+.SH NAME
+lpoptions \- display or set printer options and defaults
+.SH SYNOPSIS
+.B lpoptions
+[ -h
+.I server
+] -d
+.I dest[/instance]
+[ -o
+.I option=value
+] ... [ -o
+.I option=value
+]
+.br
+.B lpoptions
+[ -h
+.I server
+] [ -p
+.I dest[/instance]
+] -l
+.br
+.B lpoptions
+[ -h
+.I server
+] [ -o
+.I option=value
+] ... [ -o
+.I option=value
+] [ -p
+.I dest[/instance]
+] -r
+.I option
+.br
+.B lpoptions
+[ -h
+.I server
+] -x
+.I dest[/instance]
+.SH DESCRIPTION
+\fBlpoptions\fR displays or sets printer options and defaults.
+\fBlpoptions\fR shows the default printer options when run with no
+arguments. Other options include:
+.TP 5
+\-d \fIdest[/instance]\fR
+.br
+Sets the default printer to \fIdest\fR. If \fIinstance\fR is supplied then
+that particular instance is used. This option overrides the system default
+printer for the current user.
+.TP 5
+\-h \fIserver\fR
+.br
+Specifies the CUPS server to communicate with.
+.TP 5
+\-l
+.br
+Lists the printer specific options and their current settings.
+.TP 5
+\-o \fIoption=value\fR
+.br
+Specifies a new option for the named destination.
+.TP 5
+\-p \fIdest[/instance]\fR
+.br
+Sets the destination and instance, if specified, for any options that follow.
+If the named instance does not exist then it is created.
+.TP 5
+\-r \fIoption\fR
+.br
+Removes the specified option for the named destination.
+.TP 5
+\-x \fIdest[/instance]\fR
+.br
+Removes the options for the named destination and instance, if specified.
+If the named instance does not exist then this does nothing.
+.LP
+If no options are specified using the \fI-o\fR option then the current
+options for the named printer are reported on the standard output.
+.LP
+Options set with the \fBlpoptions\fR command are used by the \fBlp(1)\fR
+and \fBlpr(1)\fR commands when submitting jobs.
+.SH COMPATIBILITY
+The \fBlpoptions\fR command is unique to CUPS.
+.SH SEE ALSO
+cancel(1), lp(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: lpoptions.man 2599 2002-08-09 00:00:55Z mike $".
+.\"
diff --git a/man/lppasswd.man b/man/lppasswd.man
new file mode 100644
index 000000000..be90f764f
--- /dev/null
+++ b/man/lppasswd.man
@@ -0,0 +1,61 @@
+.\"
+.\" "$Id: lppasswd.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" lpadmin man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lppasswd 1 "Common UNIX Printing System" "7 June 2001" "Easy Software Products"
+.SH NAME
+lppasswd \- add, change, or delete digest passwords.
+.SH SYNOPSIS
+.B lppasswd
+[ -a ] [ -g
+.I groupname
+] [ -x ] [
+.I username
+]
+.SH DESCRIPTION
+\fIlppasswd\fR adds, changes, or deletes passwords in the CUPS digest
+password file, \fIpasswd.md5\fR. When run by a normal user, \fIlppasswd\fR
+will prompt for the old and new passwords. When run by the super-user,
+\fIlppasswd\fR can add new accounts (\fI-a username\fR), change existing
+accounts (\fIusername\fR), or delete accounts (\fI-x username\fR) in the
+digest password file. Digest usernames do not have to match local UNIX
+usernames, but only UNIX usernames are supported by the CUPS client programs
+(\fIlp(1)\fR, \fIlpr(1)\fR, etc.)
+.LP
+The \fI-g\fR option specifies a group other than the system group - "sys",
+"system", or "root", depending on the operating system.
+.SH SECURITY ISSUES
+The \fIlppasswd\fR command is installed setuid to root. While every attempt
+has been made to make it secure against exploits that could grant super-user
+priviledges to unpriviledged users, paranoid system administrators may wish
+to disable or change the ownership of the program to an unpriviledged
+account.
+.SH SEE ALSO
+lp(1), lpr(1),
+CUPS Software Administrators Manual,
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: lppasswd.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/lpq.man b/man/lpq.man
new file mode 100644
index 000000000..b3155a67a
--- /dev/null
+++ b/man/lpq.man
@@ -0,0 +1,57 @@
+.\"
+.\" "$Id: lpq.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" lpq man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpq 1 "Common UNIX Printing System" "13 February 2001" "Easy Software Products"
+.SH NAME
+lpq \- show printer queue status
+.SH SYNOPSIS
+.B lpq
+[ -E ] [ \-P
+.I dest
+] [ \-a ] [ \-l ] [
+.I +interval
+]
+.SH DESCRIPTION
+\fIlpq\fR shows the current print queue status on the named printer.
+Jobs queued on the default destination will be shown if no printer or
+class is specified on the command-line.
+.LP
+The \fIinterval\fR option allows you to continuously report the jobs
+in the queue until the queue is empty; the list of jobs is show one
+every \fIinterval\fR seconds.
+.LP
+The \fI-E\fR option forces encryption when connecting to the server.
+.LP
+The \fI-a\fR option reports jobs on all printers.
+.LP
+The \fI-l\fR option requests a more verbose (long) reporting format.
+.SH SEE ALSO
+cancel(1), lp(1), lpr(1), lprm(1), lpstat(1)
+.br
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: lpq.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/lpr.man b/man/lpr.man
new file mode 100644
index 000000000..d86103fae
--- /dev/null
+++ b/man/lpr.man
@@ -0,0 +1,101 @@
+.\"
+.\" "$Id: lpr.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" lpr man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpr 1 "Common UNIX Printing System" "23 January 2001" "Easy Software Products"
+.SH NAME
+lpr \- print files
+.SH SYNOPSIS
+.B lpr
+[ -E ] [ \-P
+.I destination
+] [ \-#
+.I num-copies
+[ \-l ] [ \-o
+.I option
+] [ \-p] [ \-r ] [ \-C/J/T
+.I title
+] [
+.I file(s)
+]
+.SH DESCRIPTION
+\fBlpr\fR submits files for printing. Files named on the command line are sent
+to the named printer (or the system default destination if no destination is
+specified). If no files are listed on the command-line \fBlpr\fR reads the
+print file from the standard input.
+.SH OPTIONS
+The following options are recognized by \fBlpr\fR:
+.TP 5
+\-E
+.br
+Forces encryption when connecting to the server.
+.TP 5
+\-P \fIdestination\fR
+.br
+Prints files to the named printer.
+.TP 5
+\-# \fIcopies\fR
+.br
+Sets the number of copies to print from 1 to 100.
+.TP 5
+\-C \fIname\fR
+.br
+Sets the job name.
+.TP 5
+\-J \fIname\fR
+.br
+Sets the job name.
+.TP 5
+\-T \fIname\fR
+.br
+Sets the job name.
+.TP 5
+\-l
+.br
+Specifies that the print file is already formatted for the destination and
+should be sent without filtering. This option is equivalent to "-oraw".
+.TP 5
+\-o \fIoption\fR
+.br
+Sets a job option.
+.TP 5
+\-p
+.br
+Specifies that the print file should be formatted with a shaded header with
+the date, time, job name, and page number. This option is equivalent to
+"-oprettyprint" and is only useful when printing text files.
+.TP 5
+\-r
+.br
+Specifies that the named print files should be deleted after printing them.
+.SH COMPATIBILITY
+The "c", "d", "f", "g", "i", "m", "n", "t", "v", and "w" options are not
+supported by CUPS and will produce a warning message if used.
+.SH SEE ALSO
+cancel(1), lp(1), lpstat(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: lpr.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/lprm.man b/man/lprm.man
new file mode 100644
index 000000000..4497ded45
--- /dev/null
+++ b/man/lprm.man
@@ -0,0 +1,54 @@
+.\"
+.\" "$Id: lprm.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" lprm man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lprm 1 "Common UNIX Printing System" "23 January 2001" "Easy Software Products"
+.SH NAME
+lprm \- cancel print jobs
+.SH SYNOPSIS
+.B lprm
+[ -E ] [ - ] [ -P
+.I destination
+] [
+.I job ID(s)
+]
+.SH DESCRIPTION
+\fBlprm\fR cancels print jobs that have been queued for printing. The \fI-P\fR
+option specifies the destination printer or class.
+.LP
+If no arguments are supplied, the current job on the default destination is
+cancelled. You can specify one or more job ID numbers to cancel those jobs,
+or use the \fI\-\fR option to cancel all jobs.
+.LP
+The \fI-E\fR option forces encryption when connecting to the server.
+.SH COMPATIBILITY
+The CUPS version of \fIlprm\fR is compatible with the standard Berkeley
+\fIlprm\fR command.
+.SH SEE ALSO
+cancel(1), lp(1), lpstat(1), lpr(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: lprm.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/lpstat.man b/man/lpstat.man
new file mode 100644
index 000000000..472cc05e4
--- /dev/null
+++ b/man/lpstat.man
@@ -0,0 +1,130 @@
+.\"
+.\" "$Id: lpstat.man 2460 2002-05-29 17:37:08Z mike $"
+.\"
+.\" lpstat man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH lpstat 1 "Common UNIX Printing System" "23 January 2001" "Easy Software Products"
+.SH NAME
+lpstat \- print cups status information
+.SH SYNOPSIS
+.B lpstat
+[ -E ] [ -a [
+.I destination(s)
+] ] [ -c [
+.I class(es)
+] [ -d ] [ -h
+.I server
+] [ -l ] [ -o [
+.I destination(s)
+] ] [ -p [
+.I printer(s)
+] ] [ -r ] [ -R ] [ -s ] [ -t ] [ -u [
+.I user(s)
+] ] [ -v [
+.I printer(s)
+] ]
+.SH DESCRIPTION
+\fBlpstat\fR displays status information about the current classes, jobs, and
+printers. When run with no arguments, \fBlpstat\fR will list jobs queued by
+the user. Other options include:
+.TP 5
+\-E
+.br
+Forces encryption when connecting to the server.
+.TP 5
+\-a [\fIprinter(s)\fR]
+.br
+Shows the accepting state of printer queues. If no printers are
+specified then all printers are listed.
+.TP 5
+\-c [\fIclass(es)\fR]
+.br
+Shows the printer classes and the printers that belong to them. If no
+classes are specified then all classes are listed.
+.TP 5
+\-d
+.br
+Shows the current default destination.
+.TP 5
+\-h \fIserver\fR
+.br
+Specifies the CUPS server to communicate with.
+.TP 5
+\-l
+.br
+Shows a long listing of printers, classes, or jobs.
+.TP 5
+\-o [\fIdestination(s)\fR]
+.br
+Shows the jobs queue on the specified destinations. If no destinations are
+specified all jobs are shown.
+.TP 5
+\-p [\fIprinter(s)\fR]
+.br
+Shows the printers and whether or not they are enabled for printing. If
+no printers are specified then all printers are listed.
+.TP 5
+\-r
+.br
+Shows whether or not the CUPS server is running.
+.TP 5
+\-R
+.br
+Shows the ranking of print jobs.
+.TP 5
+\-s
+.br
+Shows a status summary, including the default destination, a
+list of classes and their member printers, and a list of printers and
+their associated devices. This is equivalent to using the "-d", "-c",
+and "-p" options.
+.TP 5
+\-t
+.br
+Shows all status information. This is equivalent to using the "-r",
+"-d", "-c", "-d", "-v", "-a", "-p", and "-o" options.
+.TP 5
+\-u [\fIuser(s)\fR]
+.br
+Shows a list of print jobs queued by the specified users. If no users
+are specified, lists the jobs queued by the current user.
+.TP 5
+\-v [\fIprinter(s)\fR]
+.br
+Shows the printers and what device they are attached to. If no printers
+are specified then all printers are listed.
+.SH COMPATIBILITY
+Unlike the System V printing system, CUPS allows printer names to contain
+any printable character except SPACE and TAB. Also, printer and class names are
+\fBnot\fR case-sensitive.
+.LP
+The "-h" option is not a standard System V option.
+.LP
+The Solaris "-f", "-P", and "-S" options are silently ignored.
+.SH SEE ALSO
+cancel(1), lp(1),
+CUPS Software Users Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: lpstat.man 2460 2002-05-29 17:37:08Z mike $".
+.\"
diff --git a/man/mime.convs.man b/man/mime.convs.man
new file mode 100644
index 000000000..c144596ed
--- /dev/null
+++ b/man/mime.convs.man
@@ -0,0 +1,54 @@
+.\"
+.\" "$Id: mime.convs.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" mime.convs man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH mime.convs 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products"
+.SH NAME
+mime.convs \- mime type conversion file for cups
+.SH DESCRIPTION
+The \fImime.convs\fR file defines the filters that are available for
+converting files from one format to another. The standard filters
+support text, PDF, PostScript, HP-GL/2, and many types of image files.
+.LP
+Additional filters can be added to the \fImime.convs\fR file or to
+other files in the configuration directory (\fB/etc/cups\fR) with
+the extension ".convs".
+.LP
+Each line in the \fImime.types\fR file is a comment, blank, or filter
+line. Comment lines start with the # character. Filter lines specify
+the source and destination MIME types along with a relative cost
+associated with the filter and the filter to run:
+.br
+.nf
+
+super/type super/type cost filter
+application/postscript application/vnd.cups-raster 50 pstoraster
+.fi
+.SH SEE ALSO
+classes.conf(5), cupsd(8), cupsd.conf(5), mime.types(5), printers.conf(5),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: mime.convs.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/mime.types.man b/man/mime.types.man
new file mode 100644
index 000000000..f9621444f
--- /dev/null
+++ b/man/mime.types.man
@@ -0,0 +1,98 @@
+.\"
+.\" "$Id: mime.types.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" mime.types man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH mime.types 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products"
+.SH NAME
+mime.types \- mime type description file for cups
+.SH DESCRIPTION
+The \fImime.types\fR file defines the recognized file types.
+.LP
+Additional file types can be added to \fImime.types\fR or in additional
+files in the configuration directory \fB/etc/cups\fR with the extension
+".types".
+.LP
+Each line in the \fImime.types\fR file is a comment, blank, or rule
+line. Comment lines start with the # character. Rule lines start with
+the MIME type name and are optionally followed by a series of file
+recognition rules that are used to automatically identify print and web
+files:
+.br
+.nf
+
+ super/type rule [ ... ruleN]
+.fi
+The rules may be grouped using parenthesis, joined using "+" for a
+logical AND and "," or whitespace for a logical OR, and negated using
+"!".
+.SH RULES
+Rules take two forms - a filename extension by itself and functions with test
+values inside parenthesis. The following functions are available:
+.TP 5
+match("pattern")
+.br
+Pattern match on filename
+.TP 5
+ascii(offset,length)
+.br
+True if bytes are valid printable ASCII (CR, NL, TAB, BS, 32-126)
+.TP 5
+printable(offset,length)
+.br
+True if bytes are printable 8-bit chars (CR, NL, TAB, BS, 32-126, 128-254)
+.TP 5
+string(offset,"string")
+.br
+True if bytes are identical to string
+.TP 5
+char(offset,value)
+.br
+True if byte is identical
+.TP 5
+short(offset,value)
+.br
+True if 16-bit integer is identical
+.TP 5
+int(offset,value)
+.br
+True if 32-bit integer is identical
+.TP 5
+locale("string")
+.br
+True if current locale matches string
+.TP 5
+contains(offset,range,"string")
+.br
+True if the range contains the string
+.SH STRING CONSTANTS
+String constants can be specified inside quotes ("") for strings
+containing whitespace and angle brackets (<>) for hexadecimal
+strings.
+.SH SEE ALSO
+classes.conf(5), cupsd(8), cupsd.conf(5), mime.convs(5), printers.conf(5),
+CUPS Software Administrators Manual,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: mime.types.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/man/printers.conf.man b/man/printers.conf.man
new file mode 100644
index 000000000..fa24d3e9c
--- /dev/null
+++ b/man/printers.conf.man
@@ -0,0 +1,73 @@
+.\"
+.\" "$Id: printers.conf.man 2010 2002-01-02 17:59:21Z mike $"
+.\"
+.\" printers.conf man page for the Common UNIX Printing System (CUPS).
+.\"
+.\" Copyright 1997-2002 by Easy Software Products.
+.\"
+.\" These coded instructions, statements, and computer programs are the
+.\" property of Easy Software Products and are protected by Federal
+.\" copyright law. Distribution and use rights are outlined in the file
+.\" "LICENSE.txt" which should have been included with this file. If this
+.\" file is missing or damaged please contact Easy Software Products
+.\" at:
+.\"
+.\" Attn: CUPS Licensing Information
+.\" Easy Software Products
+.\" 44141 Airport View Drive, Suite 204
+.\" Hollywood, Maryland 20636-3111 USA
+.\"
+.\" Voice: (301) 373-9603
+.\" EMail: cups-info@cups.org
+.\" WWW: http://www.cups.org
+.\"
+.TH printers.conf 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products"
+.SH NAME
+printers.conf \- printer configuration file for cups
+.SH DESCRIPTION
+The \fIprinters.conf\fR file defines the local printers that are
+available. It is normally located in the \fI/etc/cups\fR directory and
+is generated automatically by the \fIcupsd(8)\fR program when printers
+are added or deleted.
+.LP
+Each line in the file can be a configuration directive, a blank line,
+or a comment. Comment lines start with the # character.
+.SH DIRECTIVES
+.TP 5
+Accepting
+.br
+Specifies whether or not the printer is accepting new jobs.
+.TP 5
+Info
+.br
+Specifies human-readable text describing the printer.
+.TP 5
+Location
+.br
+Specifies human-readable text describing the location of the printer.
+.TP 5
+DeviceURI
+.br
+Specifies the device URI for a printer.
+.TP 5
+<Printer name> ... </Printer>
+.br
+Defines a specific printer.
+.TP 5
+State
+.br
+Specifies the initial state of the printer (Idle or Stopped)
+.TP 5
+StateMessage
+.br
+Specifies the message associated with the state.
+.SH SEE ALSO
+classes.conf(5), cupsd(8), cupsd.conf(5), mime.convs(5), mime.types(5),
+CUPS Software Administrators Manual,
+CUPS Interface Design Description,
+http://localhost:631/documentation.html
+.SH COPYRIGHT
+Copyright 1993-2002 by Easy Software Products, All Rights Reserved.
+.\"
+.\" End of "$Id: printers.conf.man 2010 2002-01-02 17:59:21Z mike $".
+.\"
diff --git a/pdftops/.cvsignore b/pdftops/.cvsignore
new file mode 100644
index 000000000..3c3f724b2
--- /dev/null
+++ b/pdftops/.cvsignore
@@ -0,0 +1 @@
+pdftops
diff --git a/pdftops/Array.cxx b/pdftops/Array.cxx
new file mode 100644
index 000000000..141afc8ca
--- /dev/null
+++ b/pdftops/Array.cxx
@@ -0,0 +1,52 @@
+//========================================================================
+//
+// Array.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stddef.h>
+#include "gmem.h"
+#include "Object.h"
+#include "Array.h"
+
+//------------------------------------------------------------------------
+// Array
+//------------------------------------------------------------------------
+
+Array::Array(XRef *xrefA) {
+ xref = xrefA;
+ elems = NULL;
+ size = length = 0;
+ ref = 1;
+}
+
+Array::~Array() {
+ int i;
+
+ for (i = 0; i < length; ++i)
+ elems[i].free();
+ gfree(elems);
+}
+
+void Array::add(Object *elem) {
+ if (length + 1 > size) {
+ size += 8;
+ elems = (Object *)grealloc(elems, size * sizeof(Object));
+ }
+ elems[length] = *elem;
+ ++length;
+}
+
+Object *Array::get(int i, Object *obj) {
+ return elems[i].fetch(xref, obj);
+}
+
+Object *Array::getNF(int i, Object *obj) {
+ return elems[i].copy(obj);
+}
diff --git a/pdftops/Array.h b/pdftops/Array.h
new file mode 100644
index 000000000..1616fc33f
--- /dev/null
+++ b/pdftops/Array.h
@@ -0,0 +1,56 @@
+//========================================================================
+//
+// Array.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "Object.h"
+
+class XRef;
+
+//------------------------------------------------------------------------
+// Array
+//------------------------------------------------------------------------
+
+class Array {
+public:
+
+ // Constructor.
+ Array(XRef *xrefA);
+
+ // Destructor.
+ ~Array();
+
+ // Reference counting.
+ int incRef() { return ++ref; }
+ int decRef() { return --ref; }
+
+ // Get number of elements.
+ int getLength() { return length; }
+
+ // Add an element.
+ void add(Object *elem);
+
+ // Accessors.
+ Object *get(int i, Object *obj);
+ Object *getNF(int i, Object *obj);
+
+private:
+
+ XRef *xref; // the xref table for this PDF file
+ Object *elems; // array of elements
+ int size; // size of <elems> array
+ int length; // number of elements in array
+ int ref; // reference count
+};
+
+#endif
diff --git a/pdftops/CNS13CMapInfo.h b/pdftops/CNS13CMapInfo.h
new file mode 100644
index 000000000..284e6036d
--- /dev/null
+++ b/pdftops/CNS13CMapInfo.h
@@ -0,0 +1,47771 @@
+//========================================================================
+//
+// CNS13CMapInfo.h
+//
+// This file was automatically generated by makeCMapInfo.
+//
+// Copyright 1998 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef CNS13CMAPINFO_H
+#define CNS13CMAPINFO_H
+
+static Gushort cns13AdobeCNS10Map2[116] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0x2100, 0x2100,
+ 0x2200, 0x2200,
+ 0x2300, 0x2300,
+ 0x2400, 0x2400,
+ 0x2500, 0x2500,
+ 0x2600, 0x2600,
+ 0x2700, 0x2700,
+ 0x2800, 0x2800,
+ 0x2900, 0x2900,
+ 0x2a00, 0x2a00,
+ 0x2b00, 0x2b00,
+ 0x2c00, 0x2c00,
+ 0x2d00, 0x2d00,
+ 0x2e00, 0x2e00,
+ 0x2f00, 0x2f00,
+ 0x3000, 0x3000,
+ 0x3100, 0x3100,
+ 0x3200, 0x3200,
+ 0x3300, 0x3300,
+ 0x3400, 0x3400,
+ 0x3500, 0x3500,
+ 0x3600, 0x3600,
+ 0x3700, 0x3700,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13AdobeCNS10Enc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13AdobeCNS10Map2, 58
+};
+
+static Gushort cns13AdobeCNS11Map2[140] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0x2100, 0x2100,
+ 0x2200, 0x2200,
+ 0x2300, 0x2300,
+ 0x2400, 0x2400,
+ 0x2500, 0x2500,
+ 0x2600, 0x2600,
+ 0x2700, 0x2700,
+ 0x2800, 0x2800,
+ 0x2900, 0x2900,
+ 0x2a00, 0x2a00,
+ 0x2b00, 0x2b00,
+ 0x2c00, 0x2c00,
+ 0x2d00, 0x2d00,
+ 0x2e00, 0x2e00,
+ 0x2f00, 0x2f00,
+ 0x3000, 0x3000,
+ 0x3100, 0x3100,
+ 0x3200, 0x3200,
+ 0x3300, 0x3300,
+ 0x3400, 0x3400,
+ 0x3500, 0x3500,
+ 0x3600, 0x3600,
+ 0x3700, 0x3700,
+ 0x3800, 0x3800,
+ 0x3900, 0x3900,
+ 0x3a00, 0x3a00,
+ 0x3b00, 0x3b00,
+ 0x3c00, 0x3c00,
+ 0x3d00, 0x3d00,
+ 0x3e00, 0x3e00,
+ 0x3f00, 0x3f00,
+ 0x4000, 0x4000,
+ 0x4100, 0x4100,
+ 0x4200, 0x4200,
+ 0x4300, 0x4300,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13AdobeCNS11Enc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13AdobeCNS11Map2, 70
+};
+
+static Gushort cns13AdobeCNS12Map2[142] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0x2100, 0x2100,
+ 0x2200, 0x2200,
+ 0x2300, 0x2300,
+ 0x2400, 0x2400,
+ 0x2500, 0x2500,
+ 0x2600, 0x2600,
+ 0x2700, 0x2700,
+ 0x2800, 0x2800,
+ 0x2900, 0x2900,
+ 0x2a00, 0x2a00,
+ 0x2b00, 0x2b00,
+ 0x2c00, 0x2c00,
+ 0x2d00, 0x2d00,
+ 0x2e00, 0x2e00,
+ 0x2f00, 0x2f00,
+ 0x3000, 0x3000,
+ 0x3100, 0x3100,
+ 0x3200, 0x3200,
+ 0x3300, 0x3300,
+ 0x3400, 0x3400,
+ 0x3500, 0x3500,
+ 0x3600, 0x3600,
+ 0x3700, 0x3700,
+ 0x3800, 0x3800,
+ 0x3900, 0x3900,
+ 0x3a00, 0x3a00,
+ 0x3b00, 0x3b00,
+ 0x3c00, 0x3c00,
+ 0x3d00, 0x3d00,
+ 0x3e00, 0x3e00,
+ 0x3f00, 0x3f00,
+ 0x4000, 0x4000,
+ 0x4100, 0x4100,
+ 0x4200, 0x4200,
+ 0x4300, 0x4300,
+ 0x4400, 0x4400,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13AdobeCNS12Enc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13AdobeCNS12Map2, 71
+};
+
+static Gushort cns13AdobeCNS13Map2[152] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0x2100, 0x2100,
+ 0x2200, 0x2200,
+ 0x2300, 0x2300,
+ 0x2400, 0x2400,
+ 0x2500, 0x2500,
+ 0x2600, 0x2600,
+ 0x2700, 0x2700,
+ 0x2800, 0x2800,
+ 0x2900, 0x2900,
+ 0x2a00, 0x2a00,
+ 0x2b00, 0x2b00,
+ 0x2c00, 0x2c00,
+ 0x2d00, 0x2d00,
+ 0x2e00, 0x2e00,
+ 0x2f00, 0x2f00,
+ 0x3000, 0x3000,
+ 0x3100, 0x3100,
+ 0x3200, 0x3200,
+ 0x3300, 0x3300,
+ 0x3400, 0x3400,
+ 0x3500, 0x3500,
+ 0x3600, 0x3600,
+ 0x3700, 0x3700,
+ 0x3800, 0x3800,
+ 0x3900, 0x3900,
+ 0x3a00, 0x3a00,
+ 0x3b00, 0x3b00,
+ 0x3c00, 0x3c00,
+ 0x3d00, 0x3d00,
+ 0x3e00, 0x3e00,
+ 0x3f00, 0x3f00,
+ 0x4000, 0x4000,
+ 0x4100, 0x4100,
+ 0x4200, 0x4200,
+ 0x4300, 0x4300,
+ 0x4400, 0x4400,
+ 0x4500, 0x4500,
+ 0x4600, 0x4600,
+ 0x4700, 0x4700,
+ 0x4800, 0x4800,
+ 0x4900, 0x4900,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13AdobeCNS13Enc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13AdobeCNS13Map2, 76
+};
+
+static Gushort cns13B5HMap2[490] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13B5HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3550, 0x3551, 0x3552, 0x3553, 0x3554, 0x3555, 0x3556, 0x3557,
+ 0x3558, 0x3559, 0x355a, 0x355b, 0x355c, 0x355d, 0x355e, 0x355f,
+ 0x3560, 0x3561, 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567,
+ 0x3568, 0x3569, 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f,
+ 0x3570, 0x3571, 0x3572, 0x3573, 0x3574, 0x3575, 0x3576, 0x3577,
+ 0x3578, 0x3579, 0x357a, 0x357b, 0x357c, 0x357d, 0x357e, 0x357f,
+ 0x3580, 0x3581, 0x3582, 0x3583, 0x3584, 0x3585, 0x3586, 0x3587,
+ 0x3588, 0x3589, 0x358a, 0x358b, 0x358c, 0x358d, 0x358e, 0x358f,
+ 0x3590, 0x3591, 0x3592, 0x3593, 0x3594, 0x3595, 0x3596, 0x3597,
+ 0x3598, 0x3599, 0x359a, 0x359b, 0x359c, 0x359d, 0x359e, 0x359f,
+ 0x35a0, 0x35a1, 0x35a2, 0x35a3, 0x35a4, 0x35a5, 0x35a6, 0x35a7,
+ 0x35a8, 0x35a9, 0x35aa, 0x35ab, 0x35ac, 0x35ad, 0x35ae, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13B5HMap2, 245
+};
+
+static Gushort cns13B5VMap2[514] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xa14b, 0x354e,
+ 0xa15a, 0x35af,
+ 0xa15c, 0x35b1,
+ 0xa15d, 0x0082,
+ 0xa161, 0x0086,
+ 0xa165, 0x008a,
+ 0xa169, 0x008e,
+ 0xa16d, 0x0092,
+ 0xa171, 0x0096,
+ 0xa175, 0x009a,
+ 0xa179, 0x009e,
+ 0xa1e3, 0x354f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13B5VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3550, 0x3551, 0x3552, 0x3553, 0x3554, 0x3555, 0x3556, 0x3557,
+ 0x3558, 0x3559, 0x355a, 0x355b, 0x355c, 0x355d, 0x355e, 0x355f,
+ 0x3560, 0x3561, 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567,
+ 0x3568, 0x3569, 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f,
+ 0x3570, 0x3571, 0x3572, 0x3573, 0x3574, 0x3575, 0x3576, 0x3577,
+ 0x3578, 0x3579, 0x357a, 0x357b, 0x357c, 0x357d, 0x357e, 0x357f,
+ 0x3580, 0x3581, 0x3582, 0x3583, 0x3584, 0x3585, 0x3586, 0x3587,
+ 0x3588, 0x3589, 0x358a, 0x358b, 0x358c, 0x358d, 0x358e, 0x358f,
+ 0x3590, 0x3591, 0x3592, 0x3593, 0x3594, 0x3595, 0x3596, 0x3597,
+ 0x3598, 0x3599, 0x359a, 0x359b, 0x359c, 0x359d, 0x359e, 0x359f,
+ 0x35a0, 0x35a1, 0x35a2, 0x35a3, 0x35a4, 0x35a5, 0x35a6, 0x35a7,
+ 0x35a8, 0x35a9, 0x35aa, 0x35ab, 0x35ac, 0x35ad, 0x35ae, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13B5VMap2, 257
+};
+
+static Gushort cns13B5pcHMap2[492] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa3c0, 0x0232,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13B5pcHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x003d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0060, 0x0061, 0x0062 },
+ cns13B5pcHMap2, 246
+};
+
+static Gushort cns13B5pcVMap2[516] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa3c0, 0x0232,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xa14b, 0x354e,
+ 0xa15a, 0x35af,
+ 0xa15c, 0x35b1,
+ 0xa15d, 0x0082,
+ 0xa161, 0x0086,
+ 0xa165, 0x008a,
+ 0xa169, 0x008e,
+ 0xa16d, 0x0092,
+ 0xa171, 0x0096,
+ 0xa175, 0x009a,
+ 0xa179, 0x009e,
+ 0xa1e3, 0x354f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13B5pcVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x003d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0060, 0x0061, 0x0062 },
+ cns13B5pcVMap2, 258
+};
+
+static Gushort cns13CNS1HMap2[316] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0063,
+ 0x2221, 0x00c1,
+ 0x2321, 0x011f,
+ 0x2421, 0x014d,
+ 0x2521, 0x01ab,
+ 0x256e, 0x01f7,
+ 0x2621, 0x01fa,
+ 0x2721, 0x0253,
+ 0x2722, 0x0218,
+ 0x2725, 0x0254,
+ 0x2726, 0x021b,
+ 0x2727, 0x025a,
+ 0x2728, 0x021c,
+ 0x2729, 0x025b,
+ 0x272d, 0x021d,
+ 0x2730, 0x025f,
+ 0x2731, 0x176e,
+ 0x2732, 0x0260,
+ 0x2733, 0x0262,
+ 0x2734, 0x0220,
+ 0x2735, 0x0263,
+ 0x2736, 0x176f,
+ 0x2737, 0x0221,
+ 0x2738, 0x0264,
+ 0x273a, 0x0222,
+ 0x273b, 0x1770,
+ 0x273c, 0x0223,
+ 0x273d, 0x0266,
+ 0x273e, 0x0279,
+ 0x273f, 0x1775,
+ 0x2740, 0x027a,
+ 0x2742, 0x0224,
+ 0x2743, 0x027c,
+ 0x2747, 0x0225,
+ 0x2748, 0x0282,
+ 0x274c, 0x1776,
+ 0x274d, 0x0286,
+ 0x274e, 0x0226,
+ 0x274f, 0x0288,
+ 0x2751, 0x028c,
+ 0x2753, 0x0227,
+ 0x2756, 0x028e,
+ 0x2759, 0x022a,
+ 0x275b, 0x1777,
+ 0x275c, 0x02d0,
+ 0x2760, 0x02d5,
+ 0x2761, 0x022c,
+ 0x2762, 0x02d6,
+ 0x2766, 0x022d,
+ 0x2767, 0x02da,
+ 0x276e, 0x178a,
+ 0x276f, 0x02e1,
+ 0x2773, 0x178c,
+ 0x2774, 0x02e5,
+ 0x2779, 0x178d,
+ 0x277a, 0x02ea,
+ 0x277e, 0x0356,
+ 0x2821, 0x0357,
+ 0x2827, 0x035e,
+ 0x2828, 0x0362,
+ 0x2829, 0x022e,
+ 0x282b, 0x0363,
+ 0x2833, 0x17b2,
+ 0x2834, 0x036b,
+ 0x2837, 0x03f6,
+ 0x283b, 0x1812,
+ 0x283c, 0x03fa,
+ 0x283f, 0x03fe,
+ 0x2844, 0x0405,
+ 0x284d, 0x1813,
+ 0x284e, 0x1818,
+ 0x284f, 0x040f,
+ 0x2853, 0x1819,
+ 0x2854, 0x0508,
+ 0x285a, 0x18e7,
+ 0x285b, 0x050e,
+ 0x2863, 0x0230,
+ 0x2864, 0x051b,
+ 0x2865, 0x0520,
+ 0x2868, 0x0696,
+ 0x286c, 0x0231,
+ 0x286d, 0x069f,
+ 0x2871, 0x0826,
+ 0x287c, 0x09f5,
+ 0x2921, 0x1e33,
+ 0x2922, 0x09f8,
+ 0x2923, 0x1e34,
+ 0x2924, 0x09f9,
+ 0x2926, 0x0be1,
+ 0x292c, 0x0dbb,
+ 0x292f, 0x2360,
+ 0x2930, 0x2612,
+ 0x2931, 0x0f7b,
+ 0x2934, 0x1100,
+ 0x2936, 0x1289,
+ 0x2937, 0x13b2,
+ 0x2939, 0x2f0d,
+ 0x4221, 0x0232,
+ 0x4421, 0x0253,
+ 0x4521, 0x02b1,
+ 0x4621, 0x030f,
+ 0x4721, 0x036d,
+ 0x4821, 0x03cb,
+ 0x4921, 0x0429,
+ 0x4a21, 0x0487,
+ 0x4b21, 0x04e5,
+ 0x4c21, 0x0543,
+ 0x4d21, 0x05a1,
+ 0x4e21, 0x05ff,
+ 0x4f21, 0x065d,
+ 0x5021, 0x06bb,
+ 0x5121, 0x0719,
+ 0x5221, 0x0777,
+ 0x5321, 0x07d5,
+ 0x5421, 0x0833,
+ 0x5521, 0x0891,
+ 0x5621, 0x08ef,
+ 0x5721, 0x094d,
+ 0x5821, 0x09ab,
+ 0x5921, 0x0a09,
+ 0x5a21, 0x0a67,
+ 0x5b21, 0x0ac5,
+ 0x5c21, 0x0b23,
+ 0x5d21, 0x0b81,
+ 0x5e21, 0x0bdf,
+ 0x5f21, 0x0c3d,
+ 0x6021, 0x0c9b,
+ 0x6121, 0x0cf9,
+ 0x6221, 0x0d57,
+ 0x6321, 0x0db5,
+ 0x6421, 0x0e13,
+ 0x6521, 0x0e71,
+ 0x6621, 0x0ecf,
+ 0x6721, 0x0f2d,
+ 0x6821, 0x0f8b,
+ 0x6921, 0x0fe9,
+ 0x6a21, 0x1047,
+ 0x6b21, 0x10a5,
+ 0x6c21, 0x1103,
+ 0x6d21, 0x1161,
+ 0x6e21, 0x11bf,
+ 0x6f21, 0x121d,
+ 0x7021, 0x127b,
+ 0x7121, 0x12d9,
+ 0x7221, 0x1337,
+ 0x7321, 0x1395,
+ 0x7421, 0x13f3,
+ 0x7521, 0x1451,
+ 0x7621, 0x14af,
+ 0x7721, 0x150d,
+ 0x7821, 0x156b,
+ 0x7921, 0x15c9,
+ 0x7a21, 0x1627,
+ 0x7b21, 0x1685,
+ 0x7c21, 0x16e3,
+ 0x7d21, 0x1741,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13CNS1HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13CNS1HMap2, 158
+};
+
+static Gushort cns13CNS1VMap2[340] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0063,
+ 0x2221, 0x00c1,
+ 0x2321, 0x011f,
+ 0x2421, 0x014d,
+ 0x2521, 0x01ab,
+ 0x256e, 0x01f7,
+ 0x2621, 0x01fa,
+ 0x2721, 0x0253,
+ 0x2722, 0x0218,
+ 0x2725, 0x0254,
+ 0x2726, 0x021b,
+ 0x2727, 0x025a,
+ 0x2728, 0x021c,
+ 0x2729, 0x025b,
+ 0x272d, 0x021d,
+ 0x2730, 0x025f,
+ 0x2731, 0x176e,
+ 0x2732, 0x0260,
+ 0x2733, 0x0262,
+ 0x2734, 0x0220,
+ 0x2735, 0x0263,
+ 0x2736, 0x176f,
+ 0x2737, 0x0221,
+ 0x2738, 0x0264,
+ 0x273a, 0x0222,
+ 0x273b, 0x1770,
+ 0x273c, 0x0223,
+ 0x273d, 0x0266,
+ 0x273e, 0x0279,
+ 0x273f, 0x1775,
+ 0x2740, 0x027a,
+ 0x2742, 0x0224,
+ 0x2743, 0x027c,
+ 0x2747, 0x0225,
+ 0x2748, 0x0282,
+ 0x274c, 0x1776,
+ 0x274d, 0x0286,
+ 0x274e, 0x0226,
+ 0x274f, 0x0288,
+ 0x2751, 0x028c,
+ 0x2753, 0x0227,
+ 0x2756, 0x028e,
+ 0x2759, 0x022a,
+ 0x275b, 0x1777,
+ 0x275c, 0x02d0,
+ 0x2760, 0x02d5,
+ 0x2761, 0x022c,
+ 0x2762, 0x02d6,
+ 0x2766, 0x022d,
+ 0x2767, 0x02da,
+ 0x276e, 0x178a,
+ 0x276f, 0x02e1,
+ 0x2773, 0x178c,
+ 0x2774, 0x02e5,
+ 0x2779, 0x178d,
+ 0x277a, 0x02ea,
+ 0x277e, 0x0356,
+ 0x2821, 0x0357,
+ 0x2827, 0x035e,
+ 0x2828, 0x0362,
+ 0x2829, 0x022e,
+ 0x282b, 0x0363,
+ 0x2833, 0x17b2,
+ 0x2834, 0x036b,
+ 0x2837, 0x03f6,
+ 0x283b, 0x1812,
+ 0x283c, 0x03fa,
+ 0x283f, 0x03fe,
+ 0x2844, 0x0405,
+ 0x284d, 0x1813,
+ 0x284e, 0x1818,
+ 0x284f, 0x040f,
+ 0x2853, 0x1819,
+ 0x2854, 0x0508,
+ 0x285a, 0x18e7,
+ 0x285b, 0x050e,
+ 0x2863, 0x0230,
+ 0x2864, 0x051b,
+ 0x2865, 0x0520,
+ 0x2868, 0x0696,
+ 0x286c, 0x0231,
+ 0x286d, 0x069f,
+ 0x2871, 0x0826,
+ 0x287c, 0x09f5,
+ 0x2921, 0x1e33,
+ 0x2922, 0x09f8,
+ 0x2923, 0x1e34,
+ 0x2924, 0x09f9,
+ 0x2926, 0x0be1,
+ 0x292c, 0x0dbb,
+ 0x292f, 0x2360,
+ 0x2930, 0x2612,
+ 0x2931, 0x0f7b,
+ 0x2934, 0x1100,
+ 0x2936, 0x1289,
+ 0x2937, 0x13b2,
+ 0x2939, 0x2f0d,
+ 0x4221, 0x0232,
+ 0x4421, 0x0253,
+ 0x4521, 0x02b1,
+ 0x4621, 0x030f,
+ 0x4721, 0x036d,
+ 0x4821, 0x03cb,
+ 0x4921, 0x0429,
+ 0x4a21, 0x0487,
+ 0x4b21, 0x04e5,
+ 0x4c21, 0x0543,
+ 0x4d21, 0x05a1,
+ 0x4e21, 0x05ff,
+ 0x4f21, 0x065d,
+ 0x5021, 0x06bb,
+ 0x5121, 0x0719,
+ 0x5221, 0x0777,
+ 0x5321, 0x07d5,
+ 0x5421, 0x0833,
+ 0x5521, 0x0891,
+ 0x5621, 0x08ef,
+ 0x5721, 0x094d,
+ 0x5821, 0x09ab,
+ 0x5921, 0x0a09,
+ 0x5a21, 0x0a67,
+ 0x5b21, 0x0ac5,
+ 0x5c21, 0x0b23,
+ 0x5d21, 0x0b81,
+ 0x5e21, 0x0bdf,
+ 0x5f21, 0x0c3d,
+ 0x6021, 0x0c9b,
+ 0x6121, 0x0cf9,
+ 0x6221, 0x0d57,
+ 0x6321, 0x0db5,
+ 0x6421, 0x0e13,
+ 0x6521, 0x0e71,
+ 0x6621, 0x0ecf,
+ 0x6721, 0x0f2d,
+ 0x6821, 0x0f8b,
+ 0x6921, 0x0fe9,
+ 0x6a21, 0x1047,
+ 0x6b21, 0x10a5,
+ 0x6c21, 0x1103,
+ 0x6d21, 0x1161,
+ 0x6e21, 0x11bf,
+ 0x6f21, 0x121d,
+ 0x7021, 0x127b,
+ 0x7121, 0x12d9,
+ 0x7221, 0x1337,
+ 0x7321, 0x1395,
+ 0x7421, 0x13f3,
+ 0x7521, 0x1451,
+ 0x7621, 0x14af,
+ 0x7721, 0x150d,
+ 0x7821, 0x156b,
+ 0x7921, 0x15c9,
+ 0x7a21, 0x1627,
+ 0x7b21, 0x1685,
+ 0x7c21, 0x16e3,
+ 0x7d21, 0x1741,
+ 0x212c, 0x354e,
+ 0x213b, 0x007c,
+ 0x213d, 0x007e,
+ 0x213e, 0x0082,
+ 0x2142, 0x0086,
+ 0x2146, 0x008a,
+ 0x214a, 0x008e,
+ 0x214e, 0x0092,
+ 0x2152, 0x0096,
+ 0x2156, 0x009a,
+ 0x215a, 0x009e,
+ 0x2244, 0x354f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13CNS1VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13CNS1VMap2, 170
+};
+
+static Gushort cns13CNS2HMap2[168] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x176c,
+ 0x2221, 0x17ca,
+ 0x2321, 0x1828,
+ 0x2421, 0x1886,
+ 0x2521, 0x18e4,
+ 0x2621, 0x1942,
+ 0x2721, 0x19a0,
+ 0x2821, 0x19fe,
+ 0x2921, 0x1a5c,
+ 0x2a21, 0x1aba,
+ 0x2b21, 0x1b18,
+ 0x2c21, 0x1b76,
+ 0x2d21, 0x1bd4,
+ 0x2e21, 0x1c32,
+ 0x2f21, 0x1c90,
+ 0x3021, 0x1cee,
+ 0x3121, 0x1d4c,
+ 0x3221, 0x1daa,
+ 0x3321, 0x1e08,
+ 0x3421, 0x1e66,
+ 0x3521, 0x1ec4,
+ 0x3621, 0x1f22,
+ 0x3721, 0x1f80,
+ 0x3821, 0x1fde,
+ 0x3921, 0x203c,
+ 0x3a21, 0x209a,
+ 0x3b21, 0x20f8,
+ 0x3c21, 0x2156,
+ 0x3d21, 0x21b4,
+ 0x3e21, 0x2212,
+ 0x3f21, 0x2270,
+ 0x4021, 0x22ce,
+ 0x4121, 0x232c,
+ 0x4221, 0x238a,
+ 0x4321, 0x23e8,
+ 0x4421, 0x2446,
+ 0x4521, 0x24a4,
+ 0x4621, 0x2502,
+ 0x4721, 0x2560,
+ 0x4821, 0x25be,
+ 0x4921, 0x261c,
+ 0x4a21, 0x267a,
+ 0x4b21, 0x26d8,
+ 0x4c21, 0x2736,
+ 0x4d21, 0x2794,
+ 0x4e21, 0x27f2,
+ 0x4f21, 0x2850,
+ 0x5021, 0x28ae,
+ 0x5121, 0x290c,
+ 0x5221, 0x296a,
+ 0x5321, 0x29c8,
+ 0x5421, 0x2a26,
+ 0x5521, 0x2a84,
+ 0x5621, 0x2ae2,
+ 0x5721, 0x2b40,
+ 0x5821, 0x2b9e,
+ 0x5921, 0x2bfc,
+ 0x5a21, 0x2c5a,
+ 0x5b21, 0x2cb8,
+ 0x5c21, 0x2d16,
+ 0x5d21, 0x2d74,
+ 0x5e21, 0x2dd2,
+ 0x5f21, 0x2e30,
+ 0x6021, 0x2e8e,
+ 0x6121, 0x2eec,
+ 0x6221, 0x2f4a,
+ 0x6321, 0x2fa8,
+ 0x6421, 0x3006,
+ 0x6521, 0x3064,
+ 0x6621, 0x30c2,
+ 0x6721, 0x3120,
+ 0x6821, 0x317e,
+ 0x6921, 0x31dc,
+ 0x6a21, 0x323a,
+ 0x6b21, 0x3298,
+ 0x6c21, 0x32f6,
+ 0x6d21, 0x3354,
+ 0x6e21, 0x33b2,
+ 0x6f21, 0x3410,
+ 0x7021, 0x346e,
+ 0x7121, 0x34cc,
+ 0x7221, 0x352a,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13CNS2HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13CNS2HMap2, 84
+};
+
+static Gushort cns13CNS2VMap2[168] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x176c,
+ 0x2221, 0x17ca,
+ 0x2321, 0x1828,
+ 0x2421, 0x1886,
+ 0x2521, 0x18e4,
+ 0x2621, 0x1942,
+ 0x2721, 0x19a0,
+ 0x2821, 0x19fe,
+ 0x2921, 0x1a5c,
+ 0x2a21, 0x1aba,
+ 0x2b21, 0x1b18,
+ 0x2c21, 0x1b76,
+ 0x2d21, 0x1bd4,
+ 0x2e21, 0x1c32,
+ 0x2f21, 0x1c90,
+ 0x3021, 0x1cee,
+ 0x3121, 0x1d4c,
+ 0x3221, 0x1daa,
+ 0x3321, 0x1e08,
+ 0x3421, 0x1e66,
+ 0x3521, 0x1ec4,
+ 0x3621, 0x1f22,
+ 0x3721, 0x1f80,
+ 0x3821, 0x1fde,
+ 0x3921, 0x203c,
+ 0x3a21, 0x209a,
+ 0x3b21, 0x20f8,
+ 0x3c21, 0x2156,
+ 0x3d21, 0x21b4,
+ 0x3e21, 0x2212,
+ 0x3f21, 0x2270,
+ 0x4021, 0x22ce,
+ 0x4121, 0x232c,
+ 0x4221, 0x238a,
+ 0x4321, 0x23e8,
+ 0x4421, 0x2446,
+ 0x4521, 0x24a4,
+ 0x4621, 0x2502,
+ 0x4721, 0x2560,
+ 0x4821, 0x25be,
+ 0x4921, 0x261c,
+ 0x4a21, 0x267a,
+ 0x4b21, 0x26d8,
+ 0x4c21, 0x2736,
+ 0x4d21, 0x2794,
+ 0x4e21, 0x27f2,
+ 0x4f21, 0x2850,
+ 0x5021, 0x28ae,
+ 0x5121, 0x290c,
+ 0x5221, 0x296a,
+ 0x5321, 0x29c8,
+ 0x5421, 0x2a26,
+ 0x5521, 0x2a84,
+ 0x5621, 0x2ae2,
+ 0x5721, 0x2b40,
+ 0x5821, 0x2b9e,
+ 0x5921, 0x2bfc,
+ 0x5a21, 0x2c5a,
+ 0x5b21, 0x2cb8,
+ 0x5c21, 0x2d16,
+ 0x5d21, 0x2d74,
+ 0x5e21, 0x2dd2,
+ 0x5f21, 0x2e30,
+ 0x6021, 0x2e8e,
+ 0x6121, 0x2eec,
+ 0x6221, 0x2f4a,
+ 0x6321, 0x2fa8,
+ 0x6421, 0x3006,
+ 0x6521, 0x3064,
+ 0x6621, 0x30c2,
+ 0x6721, 0x3120,
+ 0x6821, 0x317e,
+ 0x6921, 0x31dc,
+ 0x6a21, 0x323a,
+ 0x6b21, 0x3298,
+ 0x6c21, 0x32f6,
+ 0x6d21, 0x3354,
+ 0x6e21, 0x33b2,
+ 0x6f21, 0x3410,
+ 0x7021, 0x346e,
+ 0x7121, 0x34cc,
+ 0x7221, 0x352a,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13CNS2VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13CNS2VMap2, 84
+};
+
+static Gushort cns13ETHKB5HMap2[2252] = {
+ 0x0000, 0x0000,
+ 0x8840, 0x44c9,
+ 0x8856, 0x4961,
+ 0x88a1, 0x498a,
+ 0x88a9, 0x499c,
+ 0x8940, 0x4534,
+ 0x8943, 0x4536,
+ 0x8946, 0x4537,
+ 0x894c, 0x453b,
+ 0x894d, 0x43c3,
+ 0x894e, 0x453c,
+ 0x8951, 0x439a,
+ 0x8952, 0x453f,
+ 0x89a1, 0x456c,
+ 0x89a6, 0x43a2,
+ 0x89ab, 0x43ec,
+ 0x89ac, 0x4571,
+ 0x89ad, 0x43eb,
+ 0x89ae, 0x4572,
+ 0x89b0, 0x4573,
+ 0x89b5, 0x4576,
+ 0x89c1, 0x4581,
+ 0x89c5, 0x4584,
+ 0x89cf, 0x43bc,
+ 0x89d0, 0x458e,
+ 0x89d9, 0x439c,
+ 0x89da, 0x4597,
+ 0x89db, 0x439e,
+ 0x89dc, 0x4598,
+ 0x89dd, 0x439f,
+ 0x89de, 0x4599,
+ 0x89e1, 0x43a1,
+ 0x89e2, 0x459c,
+ 0x89e3, 0x43a3,
+ 0x89e4, 0x459d,
+ 0x89ea, 0x43a5,
+ 0x89ec, 0x45a3,
+ 0x89fa, 0x43a9,
+ 0x89fb, 0x45b1,
+ 0x8a40, 0x45b5,
+ 0x8a41, 0x4309,
+ 0x8a43, 0x430b,
+ 0x8a4d, 0x45b6,
+ 0x8a4e, 0x4316,
+ 0x8a5a, 0x45b7,
+ 0x8a5b, 0x4323,
+ 0x8a5e, 0x45b8,
+ 0x8a5f, 0x4327,
+ 0x8a64, 0x432c,
+ 0x8a71, 0x45b9,
+ 0x8a72, 0x433a,
+ 0x8a76, 0x433e,
+ 0x8a77, 0x45ba,
+ 0x8a78, 0x4340,
+ 0x8a7a, 0x45bb,
+ 0x8a7b, 0x4343,
+ 0x8a7c, 0x45bc,
+ 0x8a7d, 0x4345,
+ 0x8a7e, 0x45bd,
+ 0x8aa1, 0x4347,
+ 0x8aa8, 0x45be,
+ 0x8aa9, 0x434f,
+ 0x8aac, 0x4352,
+ 0x8ab2, 0x4358,
+ 0x8ab6, 0x45bf,
+ 0x8ab7, 0x435d,
+ 0x8ab8, 0x45c0,
+ 0x8ab9, 0x435f,
+ 0x8abb, 0x4361,
+ 0x8ac9, 0x436f,
+ 0x8acc, 0x45c1,
+ 0x8ace, 0x4374,
+ 0x8ad6, 0x45c2,
+ 0x8ad8, 0x437e,
+ 0x8adf, 0x4385,
+ 0x8ae6, 0x45c4,
+ 0x8ae7, 0x43db,
+ 0x8ae8, 0x45c5,
+ 0x8af6, 0x45d2,
+ 0x8b40, 0x45db,
+ 0x8b41, 0x438c,
+ 0x8b43, 0x45dc,
+ 0x8b45, 0x438e,
+ 0x8b46, 0x45de,
+ 0x8b47, 0x438f,
+ 0x8b48, 0x45df,
+ 0x8b49, 0x4390,
+ 0x8b4a, 0x45e0,
+ 0x8b4b, 0x4391,
+ 0x8b4c, 0x45e1,
+ 0x8b4d, 0x4392,
+ 0x8b51, 0x45e2,
+ 0x8b55, 0x45e5,
+ 0x8b58, 0x4397,
+ 0x8b59, 0x45e8,
+ 0x8b5a, 0x4398,
+ 0x8b5b, 0x43c4,
+ 0x8b5c, 0x45e9,
+ 0x8b61, 0x43a7,
+ 0x8b62, 0x45ee,
+ 0x8b68, 0x43ac,
+ 0x8b69, 0x45f4,
+ 0x8ba1, 0x460a,
+ 0x8bc0, 0x44df,
+ 0x8bde, 0x44fc,
+ 0x8d60, 0x4629,
+ 0x8d62, 0x43ba,
+ 0x8d63, 0x462b,
+ 0x8d68, 0x43bb,
+ 0x8d69, 0x43a0,
+ 0x8d6a, 0x43bd,
+ 0x8d6b, 0x4630,
+ 0x8d6e, 0x43be,
+ 0x8d6f, 0x4633,
+ 0x8d76, 0x43bf,
+ 0x8d77, 0x463a,
+ 0x8d7a, 0x43c0,
+ 0x8d7b, 0x463d,
+ 0x8d7c, 0x43c1,
+ 0x8d7d, 0x463e,
+ 0x8da1, 0x4640,
+ 0x8da5, 0x43c2,
+ 0x8da6, 0x4644,
+ 0x8da8, 0x43b9,
+ 0x8da9, 0x43ad,
+ 0x8daa, 0x4646,
+ 0x8db6, 0x43c7,
+ 0x8db7, 0x4652,
+ 0x8dc3, 0x43c8,
+ 0x8dc4, 0x465e,
+ 0x8dfa, 0x43f9,
+ 0x8dfb, 0x4694,
+ 0x8e40, 0x372b,
+ 0x8e45, 0x4698,
+ 0x8e46, 0x3730,
+ 0x8e6a, 0x3754,
+ 0x8e6b, 0x4699,
+ 0x8e6d, 0x3756,
+ 0x8e70, 0x3759,
+ 0x8e76, 0x469b,
+ 0x8e77, 0x375f,
+ 0x8e7b, 0x469c,
+ 0x8e7c, 0x3764,
+ 0x8ea1, 0x3766,
+ 0x8ea6, 0x469d,
+ 0x8ea7, 0x376b,
+ 0x8eac, 0x3770,
+ 0x8eb5, 0x3779,
+ 0x8eb8, 0x469e,
+ 0x8eb9, 0x377d,
+ 0x8ec9, 0x469f,
+ 0x8eca, 0x378d,
+ 0x8ece, 0x3791,
+ 0x8ed1, 0x3794,
+ 0x8ee5, 0x46a0,
+ 0x8ee6, 0x37a8,
+ 0x8eef, 0x46a1,
+ 0x8ef0, 0x37b1,
+ 0x8ef6, 0x46a2,
+ 0x8ef7, 0x37b8,
+ 0x8f40, 0x37c0,
+ 0x8f58, 0x37d8,
+ 0x8f59, 0x46a3,
+ 0x8f5a, 0x37d9,
+ 0x8f5f, 0x46a4,
+ 0x8f60, 0x37de,
+ 0x8f67, 0x46a5,
+ 0x8f68, 0x37e5,
+ 0x8f6a, 0x37e7,
+ 0x8f6f, 0x37ec,
+ 0x8f79, 0x46a6,
+ 0x8f7a, 0x37f7,
+ 0x8fa1, 0x37fc,
+ 0x8fb0, 0x46a7,
+ 0x8fb1, 0x380c,
+ 0x8fc5, 0x46a8,
+ 0x8fc6, 0x3820,
+ 0x8fc7, 0x46a9,
+ 0x8fc8, 0x3821,
+ 0x8fca, 0x46aa,
+ 0x8fcd, 0x3826,
+ 0x8fda, 0x46ab,
+ 0x8fdb, 0x3833,
+ 0x8fe3, 0x46ac,
+ 0x8fe4, 0x383c,
+ 0x8ffc, 0x46ad,
+ 0x8ffd, 0x3854,
+ 0x9040, 0x3856,
+ 0x9055, 0x46ae,
+ 0x9056, 0x386c,
+ 0x905c, 0x46af,
+ 0x905f, 0x3873,
+ 0x906e, 0x3882,
+ 0x906f, 0x46b2,
+ 0x9070, 0x3883,
+ 0x907b, 0x388d,
+ 0x90a1, 0x3891,
+ 0x90a6, 0x46b3,
+ 0x90a7, 0x3896,
+ 0x90b8, 0x46b4,
+ 0x90b9, 0x38a7,
+ 0x90dd, 0x38cb,
+ 0x90f2, 0x38e0,
+ 0x9140, 0x38ed,
+ 0x9165, 0x46b5,
+ 0x9166, 0x3912,
+ 0x916e, 0x46b6,
+ 0x916f, 0x391a,
+ 0x917e, 0x46b7,
+ 0x91a1, 0x3929,
+ 0x91a2, 0x46b8,
+ 0x91a3, 0x392a,
+ 0x91c0, 0x3947,
+ 0x91c8, 0x46b9,
+ 0x91c9, 0x3950,
+ 0x9240, 0x3986,
+ 0x9245, 0x398b,
+ 0x9264, 0x46ba,
+ 0x9265, 0x39ab,
+ 0x926d, 0x46bb,
+ 0x926e, 0x39b4,
+ 0x92a1, 0x39c5,
+ 0x92b3, 0x39d3,
+ 0x92c9, 0x39e9,
+ 0x92d2, 0x39f2,
+ 0x92e5, 0x46bc,
+ 0x92e6, 0x3a05,
+ 0x92f2, 0x46bd,
+ 0x92f3, 0x3a11,
+ 0x9340, 0x3a1d,
+ 0x9368, 0x46be,
+ 0x9369, 0x3a45,
+ 0x93a1, 0x3a5b,
+ 0x93aa, 0x46bf,
+ 0x93ab, 0x3a64,
+ 0x93c2, 0x46c0,
+ 0x93c3, 0x3a7b,
+ 0x93e5, 0x46c1,
+ 0x93e6, 0x3a9d,
+ 0x93e8, 0x46c2,
+ 0x93e9, 0x3aa0,
+ 0x93eb, 0x46c3,
+ 0x93ec, 0x3aa2,
+ 0x9440, 0x3ab5,
+ 0x9446, 0x46c4,
+ 0x9448, 0x3abc,
+ 0x9479, 0x46c5,
+ 0x947a, 0x3aee,
+ 0x94a1, 0x3af3,
+ 0x94cb, 0x46c6,
+ 0x94cc, 0x3b1e,
+ 0x9540, 0x3b51,
+ 0x954d, 0x46c7,
+ 0x954e, 0x3b5e,
+ 0x955a, 0x46c8,
+ 0x955b, 0x3b6a,
+ 0x955f, 0x46c9,
+ 0x9560, 0x3b6f,
+ 0x95a1, 0x3b8e,
+ 0x95c6, 0x46ca,
+ 0x95c7, 0x3bb3,
+ 0x95da, 0x3bc6,
+ 0x9640, 0x3beb,
+ 0x9645, 0x3bf0,
+ 0x9651, 0x46cb,
+ 0x9652, 0x3bfd,
+ 0x966a, 0x46cc,
+ 0x966b, 0x3c16,
+ 0x96a1, 0x3c2a,
+ 0x96d4, 0x46cd,
+ 0x96d5, 0x3c5d,
+ 0x96ee, 0x3c76,
+ 0x96fd, 0x3c85,
+ 0x9740, 0x3c87,
+ 0x97a1, 0x3cc6,
+ 0x9840, 0x3d24,
+ 0x9844, 0x46ce,
+ 0x9846, 0x3d2a,
+ 0x986f, 0x46d0,
+ 0x9870, 0x3d54,
+ 0x9875, 0x46d1,
+ 0x9877, 0x3d59,
+ 0x9878, 0x46d3,
+ 0x987a, 0x3d5a,
+ 0x987b, 0x46d5,
+ 0x98a1, 0x46d9,
+ 0x98a3, 0x3d5b,
+ 0x98a4, 0x46db,
+ 0x98af, 0x3d5c,
+ 0x98b0, 0x46e6,
+ 0x98b4, 0x43ca,
+ 0x98b5, 0x46ea,
+ 0x98b6, 0x3d5d,
+ 0x98b7, 0x46eb,
+ 0x98b8, 0x43cc,
+ 0x98b9, 0x3d5e,
+ 0x98ba, 0x46ec,
+ 0x98bb, 0x43fa,
+ 0x98bc, 0x46ed,
+ 0x98bd, 0x3d5f,
+ 0x98bf, 0x46ee,
+ 0x98c2, 0x3d61,
+ 0x98c3, 0x46f1,
+ 0x98c4, 0x3d62,
+ 0x98c5, 0x46f2,
+ 0x98c6, 0x3d63,
+ 0x98c8, 0x46f3,
+ 0x98d2, 0x43cd,
+ 0x98d3, 0x46fd,
+ 0x98d8, 0x43ce,
+ 0x98da, 0x4702,
+ 0x98db, 0x43d1,
+ 0x98dc, 0x4703,
+ 0x98df, 0x43d4,
+ 0x98e0, 0x4706,
+ 0x98e3, 0x3d65,
+ 0x98e4, 0x4709,
+ 0x98e7, 0x3d66,
+ 0x98e8, 0x470c,
+ 0x98ed, 0x3d67,
+ 0x98ee, 0x4711,
+ 0x98f0, 0x3d68,
+ 0x98f1, 0x4713,
+ 0x98f2, 0x3d69,
+ 0x98f3, 0x4714,
+ 0x98f4, 0x43d5,
+ 0x98f6, 0x4715,
+ 0x98fc, 0x3d6a,
+ 0x98fd, 0x471b,
+ 0x98fe, 0x43d7,
+ 0x9940, 0x471c,
+ 0x9942, 0x43fc,
+ 0x9943, 0x3d6b,
+ 0x9944, 0x471e,
+ 0x9945, 0x3d6c,
+ 0x9946, 0x471f,
+ 0x9947, 0x43d8,
+ 0x9948, 0x4720,
+ 0x994f, 0x3d6d,
+ 0x9950, 0x4727,
+ 0x9954, 0x43d9,
+ 0x9955, 0x472b,
+ 0x995c, 0x43da,
+ 0x995d, 0x4732,
+ 0x9964, 0x43dc,
+ 0x9965, 0x4739,
+ 0x996a, 0x3d6e,
+ 0x996b, 0x473e,
+ 0x996e, 0x3d6f,
+ 0x996f, 0x4741,
+ 0x9975, 0x3d70,
+ 0x9976, 0x4747,
+ 0x9978, 0x3d71,
+ 0x9979, 0x4749,
+ 0x99a1, 0x474f,
+ 0x99a2, 0x3d72,
+ 0x99a3, 0x4750,
+ 0x99a4, 0x43c5,
+ 0x99a5, 0x4751,
+ 0x99a6, 0x43c6,
+ 0x99a7, 0x4752,
+ 0x99ae, 0x3d73,
+ 0x99af, 0x4759,
+ 0x99b2, 0x43de,
+ 0x99b3, 0x475c,
+ 0x99b6, 0x3d74,
+ 0x99b7, 0x475f,
+ 0x99ba, 0x3d75,
+ 0x99bb, 0x4762,
+ 0x99ca, 0x43e0,
+ 0x99cb, 0x4771,
+ 0x99cd, 0x43e2,
+ 0x99ce, 0x4773,
+ 0x99d3, 0x43e3,
+ 0x99d4, 0x4778,
+ 0x99d6, 0x43e5,
+ 0x99d7, 0x477a,
+ 0x99df, 0x43df,
+ 0x99e0, 0x4782,
+ 0x99e2, 0x3d76,
+ 0x99e3, 0x4784,
+ 0x99e4, 0x43ab,
+ 0x99e5, 0x4785,
+ 0x99e6, 0x43e7,
+ 0x99e7, 0x4786,
+ 0x99e8, 0x43e9,
+ 0x99e9, 0x4787,
+ 0x99ef, 0x43fd,
+ 0x99f0, 0x478d,
+ 0x99f4, 0x3d77,
+ 0x99f5, 0x4791,
+ 0x9a40, 0x479b,
+ 0x9a4a, 0x3d78,
+ 0x9a4b, 0x47a5,
+ 0x9a4c, 0x3d79,
+ 0x9a4d, 0x47a6,
+ 0x9a59, 0x3d7a,
+ 0x9a5a, 0x47b2,
+ 0x9a5f, 0x43af,
+ 0x9a60, 0x47b7,
+ 0x9a61, 0x3d7b,
+ 0x9a62, 0x47b8,
+ 0x9a66, 0x43ed,
+ 0x9a67, 0x47bc,
+ 0x9a68, 0x3d7c,
+ 0x9a69, 0x43ee,
+ 0x9a6a, 0x47bd,
+ 0x9a6b, 0x43ff,
+ 0x9a6c, 0x47be,
+ 0x9a73, 0x3d7d,
+ 0x9a74, 0x47c5,
+ 0x9a75, 0x43f1,
+ 0x9a76, 0x47c6,
+ 0x9a7e, 0x3d7e,
+ 0x9aa1, 0x47ce,
+ 0x9aa3, 0x43f3,
+ 0x9aa4, 0x47d0,
+ 0x9aa5, 0x43f2,
+ 0x9aa6, 0x47d1,
+ 0x9aa9, 0x43f8,
+ 0x9aaa, 0x43f4,
+ 0x9aab, 0x47d4,
+ 0x9ab2, 0x3d7f,
+ 0x9ab3, 0x47db,
+ 0x9ab7, 0x3d80,
+ 0x9ab8, 0x47df,
+ 0x9ab9, 0x3d81,
+ 0x9aba, 0x47e0,
+ 0x9abb, 0x3d82,
+ 0x9abc, 0x47e1,
+ 0x9abd, 0x43b7,
+ 0x9abe, 0x47e2,
+ 0x9ac7, 0x3d83,
+ 0x9ac8, 0x47eb,
+ 0x9ad0, 0x3d84,
+ 0x9ad1, 0x47f3,
+ 0x9ad2, 0x3d85,
+ 0x9ad3, 0x47f4,
+ 0x9ad9, 0x3d86,
+ 0x9adc, 0x47fa,
+ 0x9ae2, 0x3d89,
+ 0x9ae3, 0x4800,
+ 0x9ae4, 0x3d8a,
+ 0x9ae5, 0x4801,
+ 0x9ae8, 0x3d8b,
+ 0x9ae9, 0x43b0,
+ 0x9aea, 0x4804,
+ 0x9aee, 0x43b2,
+ 0x9aef, 0x4808,
+ 0x9af2, 0x3d8c,
+ 0x9af3, 0x480b,
+ 0x9af6, 0x3d8d,
+ 0x9af7, 0x480e,
+ 0x9afb, 0x3d8e,
+ 0x9afc, 0x4812,
+ 0x9b40, 0x4815,
+ 0x9b46, 0x3d8f,
+ 0x9b47, 0x481b,
+ 0x9b4a, 0x3d90,
+ 0x9b4b, 0x481e,
+ 0x9b54, 0x3d92,
+ 0x9b55, 0x4827,
+ 0x9b58, 0x3d93,
+ 0x9b59, 0x482a,
+ 0x9b5a, 0x3d94,
+ 0x9b5b, 0x482b,
+ 0x9b5c, 0x3d95,
+ 0x9b5d, 0x482c,
+ 0x9b5e, 0x3d96,
+ 0x9b60, 0x482d,
+ 0x9b62, 0x482e,
+ 0x9b70, 0x3d98,
+ 0x9b74, 0x483c,
+ 0x9b77, 0x3d9d,
+ 0x9b79, 0x483e,
+ 0x9b7c, 0x3da0,
+ 0x9b7d, 0x4840,
+ 0x9b7e, 0x3da1,
+ 0x9ba1, 0x3da2,
+ 0x9ba2, 0x4841,
+ 0x9ba3, 0x3da3,
+ 0x9ba5, 0x4842,
+ 0x9ba7, 0x3da5,
+ 0x9bab, 0x4844,
+ 0x9bac, 0x3da9,
+ 0x9bad, 0x4845,
+ 0x9baf, 0x3daa,
+ 0x9bb0, 0x4847,
+ 0x9bb2, 0x3dab,
+ 0x9bba, 0x4849,
+ 0x9bbe, 0x3db3,
+ 0x9bbf, 0x484d,
+ 0x9bc0, 0x3db4,
+ 0x9bc7, 0x484e,
+ 0x9bca, 0x3dbb,
+ 0x9bcb, 0x4851,
+ 0x9bcc, 0x3dbc,
+ 0x9bcd, 0x4852,
+ 0x9bce, 0x43d0,
+ 0x9bcf, 0x4853,
+ 0x9bd0, 0x3dbd,
+ 0x9bd2, 0x4854,
+ 0x9bd3, 0x3dbf,
+ 0x9bd4, 0x4855,
+ 0x9bd5, 0x3dc0,
+ 0x9bd6, 0x4856,
+ 0x9bd8, 0x3dc1,
+ 0x9bdb, 0x4858,
+ 0x9bdd, 0x3dc4,
+ 0x9bdf, 0x3dc5,
+ 0x9be0, 0x485a,
+ 0x9be1, 0x3dc6,
+ 0x9be2, 0x485b,
+ 0x9be3, 0x3dc7,
+ 0x9be4, 0x485c,
+ 0x9be7, 0x3dc8,
+ 0x9be8, 0x485f,
+ 0x9be9, 0x3dc9,
+ 0x9bed, 0x4860,
+ 0x9bee, 0x3dcd,
+ 0x9bf0, 0x4861,
+ 0x9bf3, 0x3dcf,
+ 0x9bf4, 0x4864,
+ 0x9bf7, 0x4866,
+ 0x9bf8, 0x3dd1,
+ 0x9bfa, 0x4867,
+ 0x9bfb, 0x3dd3,
+ 0x9bfd, 0x4868,
+ 0x9c40, 0x3dd5,
+ 0x9c43, 0x486a,
+ 0x9c44, 0x3dd8,
+ 0x9c47, 0x486b,
+ 0x9c48, 0x3ddb,
+ 0x9c49, 0x486c,
+ 0x9c4a, 0x3ddc,
+ 0x9c4b, 0x486d,
+ 0x9c4d, 0x3ddd,
+ 0x9c54, 0x486f,
+ 0x9c55, 0x3de4,
+ 0x9c56, 0x4870,
+ 0x9c57, 0x3de5,
+ 0x9c5c, 0x4871,
+ 0x9c5d, 0x3dea,
+ 0x9c5e, 0x4872,
+ 0x9c60, 0x3deb,
+ 0x9c61, 0x4874,
+ 0x9c63, 0x4875,
+ 0x9c64, 0x3ded,
+ 0x9c67, 0x4876,
+ 0x9c69, 0x4877,
+ 0x9c6a, 0x3df1,
+ 0x9c6c, 0x4878,
+ 0x9c6d, 0x3df2,
+ 0x9c6e, 0x4879,
+ 0x9c6f, 0x3df3,
+ 0x9c73, 0x487a,
+ 0x9c75, 0x3df7,
+ 0x9c78, 0x487c,
+ 0x9c79, 0x3dfa,
+ 0x9c7a, 0x487d,
+ 0x9c7b, 0x3dfb,
+ 0x9c7d, 0x487e,
+ 0x9c7e, 0x3dfd,
+ 0x9ca1, 0x3dfe,
+ 0x9ca3, 0x487f,
+ 0x9ca5, 0x3e00,
+ 0x9ca6, 0x4881,
+ 0x9ca8, 0x3e01,
+ 0x9caa, 0x4883,
+ 0x9cab, 0x3e03,
+ 0x9cac, 0x4884,
+ 0x9cad, 0x3e04,
+ 0x9caf, 0x4885,
+ 0x9cb1, 0x3e06,
+ 0x9cbb, 0x4887,
+ 0x9cbe, 0x3e12,
+ 0x9cc3, 0x4888,
+ 0x9cc6, 0x3e17,
+ 0x9cce, 0x488b,
+ 0x9ccf, 0x3e1f,
+ 0x9cd1, 0x3e21,
+ 0x9cd4, 0x488c,
+ 0x9cd8, 0x3e24,
+ 0x9cdb, 0x4890,
+ 0x9cdc, 0x3e27,
+ 0x9ce6, 0x4891,
+ 0x9ce7, 0x3e31,
+ 0x9cea, 0x4892,
+ 0x9ceb, 0x3e34,
+ 0x9ced, 0x4893,
+ 0x9cee, 0x3e36,
+ 0x9cfa, 0x4894,
+ 0x9cfd, 0x3e42,
+ 0x9cfe, 0x4897,
+ 0x9d40, 0x43e8,
+ 0x9d41, 0x4898,
+ 0x9d46, 0x3e43,
+ 0x9d47, 0x489d,
+ 0x9d49, 0x3e44,
+ 0x9d4a, 0x489f,
+ 0x9d4c, 0x3e46,
+ 0x9d4e, 0x48a1,
+ 0x9d4f, 0x3e48,
+ 0x9d50, 0x48a2,
+ 0x9d51, 0x3e49,
+ 0x9d52, 0x48a3,
+ 0x9d55, 0x3e4a,
+ 0x9d56, 0x48a6,
+ 0x9d58, 0x48a7,
+ 0x9d5b, 0x48a9,
+ 0x9d61, 0x43c9,
+ 0x9d62, 0x3e4c,
+ 0x9d63, 0x48af,
+ 0x9d64, 0x3e4d,
+ 0x9d65, 0x48b0,
+ 0x9d78, 0x43f5,
+ 0x9d79, 0x3e4e,
+ 0x9d7a, 0x48c3,
+ 0x9d7e, 0x3e4f,
+ 0x9da1, 0x48c7,
+ 0x9da5, 0x3e50,
+ 0x9da9, 0x48cb,
+ 0x9daa, 0x3e54,
+ 0x9dab, 0x48cc,
+ 0x9dac, 0x3e55,
+ 0x9dae, 0x48cd,
+ 0x9db0, 0x3e58,
+ 0x9db1, 0x48cf,
+ 0x9db3, 0x3e59,
+ 0x9db4, 0x48d1,
+ 0x9db5, 0x3e5a,
+ 0x9db6, 0x48d2,
+ 0x9db7, 0x3e5b,
+ 0x9db8, 0x48d3,
+ 0x9dbc, 0x3e5c,
+ 0x9dbe, 0x48d7,
+ 0x9dbf, 0x3e5e,
+ 0x9dc1, 0x48d8,
+ 0x9dc3, 0x3e60,
+ 0x9dc5, 0x48da,
+ 0x9dc7, 0x3e62,
+ 0x9dc9, 0x48dc,
+ 0x9dca, 0x3e64,
+ 0x9dcb, 0x48dd,
+ 0x9dcd, 0x3e65,
+ 0x9dd2, 0x48df,
+ 0x9dd3, 0x3e6a,
+ 0x9dd6, 0x48e0,
+ 0x9dda, 0x3e6d,
+ 0x9dfc, 0x48e4,
+ 0x9dfd, 0x3e8f,
+ 0x9e40, 0x3e91,
+ 0x9e43, 0x48e5,
+ 0x9e44, 0x3e95,
+ 0x9e5f, 0x48e6,
+ 0x9e60, 0x3eb1,
+ 0x9e63, 0x48e7,
+ 0x9e64, 0x3eb4,
+ 0x9e66, 0x48e8,
+ 0x9e68, 0x3eb6,
+ 0x9e69, 0x48ea,
+ 0x9e6a, 0x3eb7,
+ 0x9e6b, 0x48eb,
+ 0x9e71, 0x3eb8,
+ 0x9e72, 0x48f1,
+ 0x9e73, 0x3eb9,
+ 0x9e74, 0x48f2,
+ 0x9e77, 0x3eba,
+ 0x9e79, 0x48f5,
+ 0x9e7a, 0x3ebc,
+ 0x9e7b, 0x48f6,
+ 0x9e7c, 0x3ebd,
+ 0x9e7d, 0x48f7,
+ 0x9e7e, 0x3ebe,
+ 0x9ea1, 0x3ebf,
+ 0x9ea3, 0x48f8,
+ 0x9ea4, 0x3ec1,
+ 0x9ea7, 0x48f9,
+ 0x9eaa, 0x3ec5,
+ 0x9eab, 0x48fb,
+ 0x9ead, 0x3ec7,
+ 0x9eae, 0x48fc,
+ 0x9eaf, 0x3ec8,
+ 0x9eb2, 0x48fd,
+ 0x9eb4, 0x3ecb,
+ 0x9eb5, 0x48ff,
+ 0x9eb6, 0x3ecc,
+ 0x9eb8, 0x4900,
+ 0x9eb9, 0x3ece,
+ 0x9eba, 0x4901,
+ 0x9ebc, 0x3ecf,
+ 0x9ebd, 0x4903,
+ 0x9ebf, 0x3ed0,
+ 0x9ec1, 0x4905,
+ 0x9ec5, 0x3ed3,
+ 0x9ec6, 0x4908,
+ 0x9ec7, 0x3ed4,
+ 0x9ecb, 0x4909,
+ 0x9ecd, 0x3ed9,
+ 0x9ece, 0x490b,
+ 0x9ed0, 0x3eda,
+ 0x9ed2, 0x490d,
+ 0x9ed3, 0x3edc,
+ 0x9ed4, 0x490e,
+ 0x9ed6, 0x3edd,
+ 0x9ed8, 0x4910,
+ 0x9eda, 0x3edf,
+ 0x9ef0, 0x3ef5,
+ 0x9ef2, 0x4912,
+ 0x9ef3, 0x3ef7,
+ 0x9ef5, 0x3ef9,
+ 0x9ef6, 0x4913,
+ 0x9ef9, 0x3efa,
+ 0x9efb, 0x4916,
+ 0x9efc, 0x3efc,
+ 0x9efe, 0x3efe,
+ 0x9f40, 0x3eff,
+ 0x9f43, 0x4917,
+ 0x9f44, 0x3f02,
+ 0x9f48, 0x4918,
+ 0x9f49, 0x3f06,
+ 0x9f4b, 0x4919,
+ 0x9f4d, 0x3f08,
+ 0x9f4f, 0x3f0a,
+ 0x9f61, 0x3f1c,
+ 0x9f67, 0x491b,
+ 0x9f69, 0x3f23,
+ 0x9f70, 0x491d,
+ 0x9f71, 0x3f2a,
+ 0x9fa1, 0x3f38,
+ 0x9fae, 0x3f45,
+ 0x9fb2, 0x3f49,
+ 0x9fb5, 0x491e,
+ 0x9fb6, 0x3f4c,
+ 0x9fbb, 0x491f,
+ 0x9fbc, 0x3f51,
+ 0x9fbf, 0x4920,
+ 0x9fc1, 0x4921,
+ 0x9fc2, 0x3f55,
+ 0x9fc9, 0x3f5c,
+ 0x9fcc, 0x4922,
+ 0x9fcd, 0x3f60,
+ 0x9fd4, 0x4923,
+ 0x9fd5, 0x3f68,
+ 0x9fd9, 0x3f6c,
+ 0x9fdb, 0x3f6e,
+ 0x9fe4, 0x4924,
+ 0x9fe5, 0x3f77,
+ 0x9fe7, 0x3f79,
+ 0x9feb, 0x3f7d,
+ 0x9ff0, 0x3f82,
+ 0x9ff9, 0x4925,
+ 0x9ffa, 0x3f8b,
+ 0xa040, 0x4926,
+ 0xa041, 0x3f90,
+ 0xa047, 0x4927,
+ 0xa048, 0x3f96,
+ 0xa055, 0x4928,
+ 0xa056, 0x3fa3,
+ 0xa058, 0x3fa5,
+ 0xa05b, 0x3fa8,
+ 0xa064, 0x3fb1,
+ 0xa06d, 0x4929,
+ 0xa06e, 0x3fba,
+ 0xa073, 0x3fbf,
+ 0xa078, 0x3fc4,
+ 0xa07b, 0x492a,
+ 0xa07c, 0x3fc7,
+ 0xa0a1, 0x3fca,
+ 0xa0a2, 0x492b,
+ 0xa0a3, 0x3fcb,
+ 0xa0a6, 0x3fce,
+ 0xa0a7, 0x492c,
+ 0xa0a8, 0x3fcf,
+ 0xa0ae, 0x3fd5,
+ 0xa0b0, 0x3fd7,
+ 0xa0c5, 0x492d,
+ 0xa0c6, 0x3fec,
+ 0xa0d0, 0x492e,
+ 0xa0d1, 0x3ff6,
+ 0xa0d4, 0x3ff9,
+ 0xa0d6, 0x3ffb,
+ 0xa0e0, 0x4005,
+ 0xa0e2, 0x4007,
+ 0xa0e3, 0x492f,
+ 0xa0e5, 0x4009,
+ 0xa0e7, 0x4930,
+ 0xa0ee, 0x43b4,
+ 0xa0ef, 0x4937,
+ 0xa0f2, 0x43b8,
+ 0xa0f3, 0x493a,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc6a1, 0x01fa,
+ 0xc6bf, 0x0219,
+ 0xc6d8, 0x35b3,
+ 0xc6df, 0x1794,
+ 0xc6e0, 0x35ba,
+ 0xc740, 0x35d9,
+ 0xc7a1, 0x3618,
+ 0xc840, 0x3676,
+ 0xc8a1, 0x36b5,
+ 0xc8d4, 0x44c6,
+ 0xc8d7, 0x451c,
+ 0xc8e0, 0x02dc,
+ 0xc8e1, 0x4525,
+ 0xc8e9, 0x0509,
+ 0xc8ea, 0x452d,
+ 0xc8f1, 0x09f6,
+ 0xc8f5, 0x4992,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xf9d6, 0x36e8,
+ 0xfa40, 0x400b,
+ 0xfa60, 0x402b,
+ 0xfa67, 0x4032,
+ 0xfaa1, 0x404a,
+ 0xfaa9, 0x4946,
+ 0xfaab, 0x4054,
+ 0xfabe, 0x4067,
+ 0xfac6, 0x406f,
+ 0xfad6, 0x407f,
+ 0xfb40, 0x40a8,
+ 0xfb49, 0x40b1,
+ 0xfb53, 0x4948,
+ 0xfb54, 0x40bc,
+ 0xfb6e, 0x4949,
+ 0xfb6f, 0x40d7,
+ 0xfba1, 0x40e7,
+ 0xfba3, 0x494a,
+ 0xfba4, 0x40ea,
+ 0xfbb9, 0x40ff,
+ 0xfbbf, 0x494b,
+ 0xfbc0, 0x4105,
+ 0xfbcd, 0x494c,
+ 0xfbce, 0x4112,
+ 0xfbf4, 0x4138,
+ 0xfbfa, 0x413e,
+ 0xfc40, 0x4143,
+ 0xfc4a, 0x494d,
+ 0xfc4b, 0x414d,
+ 0xfc50, 0x4151,
+ 0xfc52, 0x494e,
+ 0xfc53, 0x4153,
+ 0xfc63, 0x494f,
+ 0xfc64, 0x4163,
+ 0xfc6d, 0x4950,
+ 0xfc6e, 0x416d,
+ 0xfc75, 0x4951,
+ 0xfc76, 0x4174,
+ 0xfca1, 0x417d,
+ 0xfcba, 0x4195,
+ 0xfcbc, 0x4952,
+ 0xfcbe, 0x4198,
+ 0xfccc, 0x4954,
+ 0xfccd, 0x41a7,
+ 0xfce3, 0x4955,
+ 0xfce4, 0x41bd,
+ 0xfcee, 0x4956,
+ 0xfcef, 0x41c7,
+ 0xfcf2, 0x41ca,
+ 0xfd40, 0x41d7,
+ 0xfd49, 0x4957,
+ 0xfd4a, 0x41e0,
+ 0xfd6a, 0x4958,
+ 0xfd6b, 0x4201,
+ 0xfda1, 0x4215,
+ 0xfdb9, 0x422d,
+ 0xfdbc, 0x4230,
+ 0xfde3, 0x4959,
+ 0xfde4, 0x4258,
+ 0xfdf2, 0x495a,
+ 0xfdf3, 0x4266,
+ 0xfe40, 0x4272,
+ 0xfe53, 0x4285,
+ 0xfe6d, 0x495b,
+ 0xfe6e, 0x429f,
+ 0xfe70, 0x42a1,
+ 0xfe78, 0x495c,
+ 0xfe79, 0x42a9,
+ 0xfea1, 0x42af,
+ 0xfeab, 0x42b8,
+ 0xfede, 0x495d,
+ 0xfee0, 0x42eb,
+ 0xfeed, 0x495f,
+ 0xfeef, 0x42f8,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13ETHKB5HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13ETHKB5HMap2, 1126
+};
+
+static Gushort cns13ETHKB5VMap2[2278] = {
+ 0x0000, 0x0000,
+ 0x8840, 0x44c9,
+ 0x8856, 0x4961,
+ 0x88a1, 0x498a,
+ 0x88a9, 0x499c,
+ 0x8940, 0x4534,
+ 0x8943, 0x4536,
+ 0x8946, 0x4537,
+ 0x894c, 0x453b,
+ 0x894d, 0x43c3,
+ 0x894e, 0x453c,
+ 0x8951, 0x439a,
+ 0x8952, 0x453f,
+ 0x89a1, 0x456c,
+ 0x89a6, 0x43a2,
+ 0x89ab, 0x43ec,
+ 0x89ac, 0x4571,
+ 0x89ad, 0x43eb,
+ 0x89ae, 0x4572,
+ 0x89b0, 0x4573,
+ 0x89b5, 0x4576,
+ 0x89c1, 0x4581,
+ 0x89c5, 0x4584,
+ 0x89cf, 0x43bc,
+ 0x89d0, 0x458e,
+ 0x89d9, 0x439c,
+ 0x89da, 0x4597,
+ 0x89db, 0x439e,
+ 0x89dc, 0x4598,
+ 0x89dd, 0x439f,
+ 0x89de, 0x4599,
+ 0x89e1, 0x43a1,
+ 0x89e2, 0x459c,
+ 0x89e3, 0x43a3,
+ 0x89e4, 0x459d,
+ 0x89ea, 0x43a5,
+ 0x89ec, 0x45a3,
+ 0x89fa, 0x43a9,
+ 0x89fb, 0x45b1,
+ 0x8a40, 0x45b5,
+ 0x8a41, 0x4309,
+ 0x8a43, 0x430b,
+ 0x8a4d, 0x45b6,
+ 0x8a4e, 0x4316,
+ 0x8a5a, 0x45b7,
+ 0x8a5b, 0x4323,
+ 0x8a5e, 0x45b8,
+ 0x8a5f, 0x4327,
+ 0x8a64, 0x432c,
+ 0x8a71, 0x45b9,
+ 0x8a72, 0x433a,
+ 0x8a76, 0x433e,
+ 0x8a77, 0x45ba,
+ 0x8a78, 0x4340,
+ 0x8a7a, 0x45bb,
+ 0x8a7b, 0x4343,
+ 0x8a7c, 0x45bc,
+ 0x8a7d, 0x4345,
+ 0x8a7e, 0x45bd,
+ 0x8aa1, 0x4347,
+ 0x8aa8, 0x45be,
+ 0x8aa9, 0x434f,
+ 0x8aac, 0x4352,
+ 0x8ab2, 0x4358,
+ 0x8ab6, 0x45bf,
+ 0x8ab7, 0x435d,
+ 0x8ab8, 0x45c0,
+ 0x8ab9, 0x435f,
+ 0x8abb, 0x4361,
+ 0x8ac9, 0x436f,
+ 0x8acc, 0x45c1,
+ 0x8ace, 0x4374,
+ 0x8ad6, 0x45c2,
+ 0x8ad8, 0x437e,
+ 0x8adf, 0x4385,
+ 0x8ae6, 0x45c4,
+ 0x8ae7, 0x43db,
+ 0x8ae8, 0x45c5,
+ 0x8af6, 0x45d2,
+ 0x8b40, 0x45db,
+ 0x8b41, 0x438c,
+ 0x8b43, 0x45dc,
+ 0x8b45, 0x438e,
+ 0x8b46, 0x45de,
+ 0x8b47, 0x438f,
+ 0x8b48, 0x45df,
+ 0x8b49, 0x4390,
+ 0x8b4a, 0x45e0,
+ 0x8b4b, 0x4391,
+ 0x8b4c, 0x45e1,
+ 0x8b4d, 0x4392,
+ 0x8b51, 0x45e2,
+ 0x8b55, 0x45e5,
+ 0x8b58, 0x4397,
+ 0x8b59, 0x45e8,
+ 0x8b5a, 0x4398,
+ 0x8b5b, 0x43c4,
+ 0x8b5c, 0x45e9,
+ 0x8b61, 0x43a7,
+ 0x8b62, 0x45ee,
+ 0x8b68, 0x43ac,
+ 0x8b69, 0x45f4,
+ 0x8ba1, 0x460a,
+ 0x8bc0, 0x44df,
+ 0x8bde, 0x44fc,
+ 0x8d60, 0x4629,
+ 0x8d62, 0x43ba,
+ 0x8d63, 0x462b,
+ 0x8d68, 0x43bb,
+ 0x8d69, 0x43a0,
+ 0x8d6a, 0x43bd,
+ 0x8d6b, 0x4630,
+ 0x8d6e, 0x43be,
+ 0x8d6f, 0x4633,
+ 0x8d76, 0x43bf,
+ 0x8d77, 0x463a,
+ 0x8d7a, 0x43c0,
+ 0x8d7b, 0x463d,
+ 0x8d7c, 0x43c1,
+ 0x8d7d, 0x463e,
+ 0x8da1, 0x4640,
+ 0x8da5, 0x43c2,
+ 0x8da6, 0x4644,
+ 0x8da8, 0x43b9,
+ 0x8da9, 0x43ad,
+ 0x8daa, 0x4646,
+ 0x8db6, 0x43c7,
+ 0x8db7, 0x4652,
+ 0x8dc3, 0x43c8,
+ 0x8dc4, 0x465e,
+ 0x8dfa, 0x43f9,
+ 0x8dfb, 0x4694,
+ 0x8e40, 0x372b,
+ 0x8e45, 0x4698,
+ 0x8e46, 0x3730,
+ 0x8e6a, 0x3754,
+ 0x8e6b, 0x4699,
+ 0x8e6d, 0x3756,
+ 0x8e70, 0x3759,
+ 0x8e76, 0x469b,
+ 0x8e77, 0x375f,
+ 0x8e7b, 0x469c,
+ 0x8e7c, 0x3764,
+ 0x8ea1, 0x3766,
+ 0x8ea6, 0x469d,
+ 0x8ea7, 0x376b,
+ 0x8eac, 0x3770,
+ 0x8eb5, 0x3779,
+ 0x8eb8, 0x469e,
+ 0x8eb9, 0x377d,
+ 0x8ec9, 0x469f,
+ 0x8eca, 0x378d,
+ 0x8ece, 0x3791,
+ 0x8ed1, 0x3794,
+ 0x8ee5, 0x46a0,
+ 0x8ee6, 0x37a8,
+ 0x8eef, 0x46a1,
+ 0x8ef0, 0x37b1,
+ 0x8ef6, 0x46a2,
+ 0x8ef7, 0x37b8,
+ 0x8f40, 0x37c0,
+ 0x8f58, 0x37d8,
+ 0x8f59, 0x46a3,
+ 0x8f5a, 0x37d9,
+ 0x8f5f, 0x46a4,
+ 0x8f60, 0x37de,
+ 0x8f67, 0x46a5,
+ 0x8f68, 0x37e5,
+ 0x8f6a, 0x37e7,
+ 0x8f6f, 0x37ec,
+ 0x8f79, 0x46a6,
+ 0x8f7a, 0x37f7,
+ 0x8fa1, 0x37fc,
+ 0x8fb0, 0x46a7,
+ 0x8fb1, 0x380c,
+ 0x8fc5, 0x46a8,
+ 0x8fc6, 0x3820,
+ 0x8fc7, 0x46a9,
+ 0x8fc8, 0x3821,
+ 0x8fca, 0x46aa,
+ 0x8fcd, 0x3826,
+ 0x8fda, 0x46ab,
+ 0x8fdb, 0x3833,
+ 0x8fe3, 0x46ac,
+ 0x8fe4, 0x383c,
+ 0x8ffc, 0x46ad,
+ 0x8ffd, 0x3854,
+ 0x9040, 0x3856,
+ 0x9055, 0x46ae,
+ 0x9056, 0x386c,
+ 0x905c, 0x46af,
+ 0x905f, 0x3873,
+ 0x906e, 0x3882,
+ 0x906f, 0x46b2,
+ 0x9070, 0x3883,
+ 0x907b, 0x388d,
+ 0x90a1, 0x3891,
+ 0x90a6, 0x46b3,
+ 0x90a7, 0x3896,
+ 0x90b8, 0x46b4,
+ 0x90b9, 0x38a7,
+ 0x90dd, 0x38cb,
+ 0x90f2, 0x38e0,
+ 0x9140, 0x38ed,
+ 0x9165, 0x46b5,
+ 0x9166, 0x3912,
+ 0x916e, 0x46b6,
+ 0x916f, 0x391a,
+ 0x917e, 0x46b7,
+ 0x91a1, 0x3929,
+ 0x91a2, 0x46b8,
+ 0x91a3, 0x392a,
+ 0x91c0, 0x3947,
+ 0x91c8, 0x46b9,
+ 0x91c9, 0x3950,
+ 0x9240, 0x3986,
+ 0x9245, 0x398b,
+ 0x9264, 0x46ba,
+ 0x9265, 0x39ab,
+ 0x926d, 0x46bb,
+ 0x926e, 0x39b4,
+ 0x92a1, 0x39c5,
+ 0x92b3, 0x39d3,
+ 0x92c9, 0x39e9,
+ 0x92d2, 0x39f2,
+ 0x92e5, 0x46bc,
+ 0x92e6, 0x3a05,
+ 0x92f2, 0x46bd,
+ 0x92f3, 0x3a11,
+ 0x9340, 0x3a1d,
+ 0x9368, 0x46be,
+ 0x9369, 0x3a45,
+ 0x93a1, 0x3a5b,
+ 0x93aa, 0x46bf,
+ 0x93ab, 0x3a64,
+ 0x93c2, 0x46c0,
+ 0x93c3, 0x3a7b,
+ 0x93e5, 0x46c1,
+ 0x93e6, 0x3a9d,
+ 0x93e8, 0x46c2,
+ 0x93e9, 0x3aa0,
+ 0x93eb, 0x46c3,
+ 0x93ec, 0x3aa2,
+ 0x9440, 0x3ab5,
+ 0x9446, 0x46c4,
+ 0x9448, 0x3abc,
+ 0x9479, 0x46c5,
+ 0x947a, 0x3aee,
+ 0x94a1, 0x3af3,
+ 0x94cb, 0x46c6,
+ 0x94cc, 0x3b1e,
+ 0x9540, 0x3b51,
+ 0x954d, 0x46c7,
+ 0x954e, 0x3b5e,
+ 0x955a, 0x46c8,
+ 0x955b, 0x3b6a,
+ 0x955f, 0x46c9,
+ 0x9560, 0x3b6f,
+ 0x95a1, 0x3b8e,
+ 0x95c6, 0x46ca,
+ 0x95c7, 0x3bb3,
+ 0x95da, 0x3bc6,
+ 0x9640, 0x3beb,
+ 0x9645, 0x3bf0,
+ 0x9651, 0x46cb,
+ 0x9652, 0x3bfd,
+ 0x966a, 0x46cc,
+ 0x966b, 0x3c16,
+ 0x96a1, 0x3c2a,
+ 0x96d4, 0x46cd,
+ 0x96d5, 0x3c5d,
+ 0x96ee, 0x3c76,
+ 0x96fd, 0x3c85,
+ 0x9740, 0x3c87,
+ 0x97a1, 0x3cc6,
+ 0x9840, 0x3d24,
+ 0x9844, 0x46ce,
+ 0x9846, 0x3d2a,
+ 0x986f, 0x46d0,
+ 0x9870, 0x3d54,
+ 0x9875, 0x46d1,
+ 0x9877, 0x3d59,
+ 0x9878, 0x46d3,
+ 0x987a, 0x3d5a,
+ 0x987b, 0x46d5,
+ 0x98a1, 0x46d9,
+ 0x98a3, 0x3d5b,
+ 0x98a4, 0x46db,
+ 0x98af, 0x3d5c,
+ 0x98b0, 0x46e6,
+ 0x98b4, 0x43ca,
+ 0x98b5, 0x46ea,
+ 0x98b6, 0x3d5d,
+ 0x98b7, 0x46eb,
+ 0x98b8, 0x43cc,
+ 0x98b9, 0x3d5e,
+ 0x98ba, 0x46ec,
+ 0x98bb, 0x43fa,
+ 0x98bc, 0x46ed,
+ 0x98bd, 0x3d5f,
+ 0x98bf, 0x46ee,
+ 0x98c2, 0x3d61,
+ 0x98c3, 0x46f1,
+ 0x98c4, 0x3d62,
+ 0x98c5, 0x46f2,
+ 0x98c6, 0x3d63,
+ 0x98c8, 0x46f3,
+ 0x98d2, 0x43cd,
+ 0x98d3, 0x46fd,
+ 0x98d8, 0x43ce,
+ 0x98da, 0x4702,
+ 0x98db, 0x43d1,
+ 0x98dc, 0x4703,
+ 0x98df, 0x43d4,
+ 0x98e0, 0x4706,
+ 0x98e3, 0x3d65,
+ 0x98e4, 0x4709,
+ 0x98e7, 0x3d66,
+ 0x98e8, 0x470c,
+ 0x98ed, 0x3d67,
+ 0x98ee, 0x4711,
+ 0x98f0, 0x3d68,
+ 0x98f1, 0x4713,
+ 0x98f2, 0x3d69,
+ 0x98f3, 0x4714,
+ 0x98f4, 0x43d5,
+ 0x98f6, 0x4715,
+ 0x98fc, 0x3d6a,
+ 0x98fd, 0x471b,
+ 0x98fe, 0x43d7,
+ 0x9940, 0x471c,
+ 0x9942, 0x43fc,
+ 0x9943, 0x3d6b,
+ 0x9944, 0x471e,
+ 0x9945, 0x3d6c,
+ 0x9946, 0x471f,
+ 0x9947, 0x43d8,
+ 0x9948, 0x4720,
+ 0x994f, 0x3d6d,
+ 0x9950, 0x4727,
+ 0x9954, 0x43d9,
+ 0x9955, 0x472b,
+ 0x995c, 0x43da,
+ 0x995d, 0x4732,
+ 0x9964, 0x43dc,
+ 0x9965, 0x4739,
+ 0x996a, 0x3d6e,
+ 0x996b, 0x473e,
+ 0x996e, 0x3d6f,
+ 0x996f, 0x4741,
+ 0x9975, 0x3d70,
+ 0x9976, 0x4747,
+ 0x9978, 0x3d71,
+ 0x9979, 0x4749,
+ 0x99a1, 0x474f,
+ 0x99a2, 0x3d72,
+ 0x99a3, 0x4750,
+ 0x99a4, 0x43c5,
+ 0x99a5, 0x4751,
+ 0x99a6, 0x43c6,
+ 0x99a7, 0x4752,
+ 0x99ae, 0x3d73,
+ 0x99af, 0x4759,
+ 0x99b2, 0x43de,
+ 0x99b3, 0x475c,
+ 0x99b6, 0x3d74,
+ 0x99b7, 0x475f,
+ 0x99ba, 0x3d75,
+ 0x99bb, 0x4762,
+ 0x99ca, 0x43e0,
+ 0x99cb, 0x4771,
+ 0x99cd, 0x43e2,
+ 0x99ce, 0x4773,
+ 0x99d3, 0x43e3,
+ 0x99d4, 0x4778,
+ 0x99d6, 0x43e5,
+ 0x99d7, 0x477a,
+ 0x99df, 0x43df,
+ 0x99e0, 0x4782,
+ 0x99e2, 0x3d76,
+ 0x99e3, 0x4784,
+ 0x99e4, 0x43ab,
+ 0x99e5, 0x4785,
+ 0x99e6, 0x43e7,
+ 0x99e7, 0x4786,
+ 0x99e8, 0x43e9,
+ 0x99e9, 0x4787,
+ 0x99ef, 0x43fd,
+ 0x99f0, 0x478d,
+ 0x99f4, 0x3d77,
+ 0x99f5, 0x4791,
+ 0x9a40, 0x479b,
+ 0x9a4a, 0x3d78,
+ 0x9a4b, 0x47a5,
+ 0x9a4c, 0x3d79,
+ 0x9a4d, 0x47a6,
+ 0x9a59, 0x3d7a,
+ 0x9a5a, 0x47b2,
+ 0x9a5f, 0x43af,
+ 0x9a60, 0x47b7,
+ 0x9a61, 0x3d7b,
+ 0x9a62, 0x47b8,
+ 0x9a66, 0x43ed,
+ 0x9a67, 0x47bc,
+ 0x9a68, 0x3d7c,
+ 0x9a69, 0x43ee,
+ 0x9a6a, 0x47bd,
+ 0x9a6b, 0x43ff,
+ 0x9a6c, 0x47be,
+ 0x9a73, 0x3d7d,
+ 0x9a74, 0x47c5,
+ 0x9a75, 0x43f1,
+ 0x9a76, 0x47c6,
+ 0x9a7e, 0x3d7e,
+ 0x9aa1, 0x47ce,
+ 0x9aa3, 0x43f3,
+ 0x9aa4, 0x47d0,
+ 0x9aa5, 0x43f2,
+ 0x9aa6, 0x47d1,
+ 0x9aa9, 0x43f8,
+ 0x9aaa, 0x43f4,
+ 0x9aab, 0x47d4,
+ 0x9ab2, 0x3d7f,
+ 0x9ab3, 0x47db,
+ 0x9ab7, 0x3d80,
+ 0x9ab8, 0x47df,
+ 0x9ab9, 0x3d81,
+ 0x9aba, 0x47e0,
+ 0x9abb, 0x3d82,
+ 0x9abc, 0x47e1,
+ 0x9abd, 0x43b7,
+ 0x9abe, 0x47e2,
+ 0x9ac7, 0x3d83,
+ 0x9ac8, 0x47eb,
+ 0x9ad0, 0x3d84,
+ 0x9ad1, 0x47f3,
+ 0x9ad2, 0x3d85,
+ 0x9ad3, 0x47f4,
+ 0x9ad9, 0x3d86,
+ 0x9adc, 0x47fa,
+ 0x9ae2, 0x3d89,
+ 0x9ae3, 0x4800,
+ 0x9ae4, 0x3d8a,
+ 0x9ae5, 0x4801,
+ 0x9ae8, 0x3d8b,
+ 0x9ae9, 0x43b0,
+ 0x9aea, 0x4804,
+ 0x9aee, 0x43b2,
+ 0x9aef, 0x4808,
+ 0x9af2, 0x3d8c,
+ 0x9af3, 0x480b,
+ 0x9af6, 0x3d8d,
+ 0x9af7, 0x480e,
+ 0x9afb, 0x3d8e,
+ 0x9afc, 0x4812,
+ 0x9b40, 0x4815,
+ 0x9b46, 0x3d8f,
+ 0x9b47, 0x481b,
+ 0x9b4a, 0x3d90,
+ 0x9b4b, 0x481e,
+ 0x9b54, 0x3d92,
+ 0x9b55, 0x4827,
+ 0x9b58, 0x3d93,
+ 0x9b59, 0x482a,
+ 0x9b5a, 0x3d94,
+ 0x9b5b, 0x482b,
+ 0x9b5c, 0x3d95,
+ 0x9b5d, 0x482c,
+ 0x9b5e, 0x3d96,
+ 0x9b60, 0x482d,
+ 0x9b62, 0x482e,
+ 0x9b70, 0x3d98,
+ 0x9b74, 0x483c,
+ 0x9b77, 0x3d9d,
+ 0x9b79, 0x483e,
+ 0x9b7c, 0x3da0,
+ 0x9b7d, 0x4840,
+ 0x9b7e, 0x3da1,
+ 0x9ba1, 0x3da2,
+ 0x9ba2, 0x4841,
+ 0x9ba3, 0x3da3,
+ 0x9ba5, 0x4842,
+ 0x9ba7, 0x3da5,
+ 0x9bab, 0x4844,
+ 0x9bac, 0x3da9,
+ 0x9bad, 0x4845,
+ 0x9baf, 0x3daa,
+ 0x9bb0, 0x4847,
+ 0x9bb2, 0x3dab,
+ 0x9bba, 0x4849,
+ 0x9bbe, 0x3db3,
+ 0x9bbf, 0x484d,
+ 0x9bc0, 0x3db4,
+ 0x9bc7, 0x484e,
+ 0x9bca, 0x3dbb,
+ 0x9bcb, 0x4851,
+ 0x9bcc, 0x3dbc,
+ 0x9bcd, 0x4852,
+ 0x9bce, 0x43d0,
+ 0x9bcf, 0x4853,
+ 0x9bd0, 0x3dbd,
+ 0x9bd2, 0x4854,
+ 0x9bd3, 0x3dbf,
+ 0x9bd4, 0x4855,
+ 0x9bd5, 0x3dc0,
+ 0x9bd6, 0x4856,
+ 0x9bd8, 0x3dc1,
+ 0x9bdb, 0x4858,
+ 0x9bdd, 0x3dc4,
+ 0x9bdf, 0x3dc5,
+ 0x9be0, 0x485a,
+ 0x9be1, 0x3dc6,
+ 0x9be2, 0x485b,
+ 0x9be3, 0x3dc7,
+ 0x9be4, 0x485c,
+ 0x9be7, 0x3dc8,
+ 0x9be8, 0x485f,
+ 0x9be9, 0x3dc9,
+ 0x9bed, 0x4860,
+ 0x9bee, 0x3dcd,
+ 0x9bf0, 0x4861,
+ 0x9bf3, 0x3dcf,
+ 0x9bf4, 0x4864,
+ 0x9bf7, 0x4866,
+ 0x9bf8, 0x3dd1,
+ 0x9bfa, 0x4867,
+ 0x9bfb, 0x3dd3,
+ 0x9bfd, 0x4868,
+ 0x9c40, 0x3dd5,
+ 0x9c43, 0x486a,
+ 0x9c44, 0x3dd8,
+ 0x9c47, 0x486b,
+ 0x9c48, 0x3ddb,
+ 0x9c49, 0x486c,
+ 0x9c4a, 0x3ddc,
+ 0x9c4b, 0x486d,
+ 0x9c4d, 0x3ddd,
+ 0x9c54, 0x486f,
+ 0x9c55, 0x3de4,
+ 0x9c56, 0x4870,
+ 0x9c57, 0x3de5,
+ 0x9c5c, 0x4871,
+ 0x9c5d, 0x3dea,
+ 0x9c5e, 0x4872,
+ 0x9c60, 0x3deb,
+ 0x9c61, 0x4874,
+ 0x9c63, 0x4875,
+ 0x9c64, 0x3ded,
+ 0x9c67, 0x4876,
+ 0x9c69, 0x4877,
+ 0x9c6a, 0x3df1,
+ 0x9c6c, 0x4878,
+ 0x9c6d, 0x3df2,
+ 0x9c6e, 0x4879,
+ 0x9c6f, 0x3df3,
+ 0x9c73, 0x487a,
+ 0x9c75, 0x3df7,
+ 0x9c78, 0x487c,
+ 0x9c79, 0x3dfa,
+ 0x9c7a, 0x487d,
+ 0x9c7b, 0x3dfb,
+ 0x9c7d, 0x487e,
+ 0x9c7e, 0x3dfd,
+ 0x9ca1, 0x3dfe,
+ 0x9ca3, 0x487f,
+ 0x9ca5, 0x3e00,
+ 0x9ca6, 0x4881,
+ 0x9ca8, 0x3e01,
+ 0x9caa, 0x4883,
+ 0x9cab, 0x3e03,
+ 0x9cac, 0x4884,
+ 0x9cad, 0x3e04,
+ 0x9caf, 0x4885,
+ 0x9cb1, 0x3e06,
+ 0x9cbb, 0x4887,
+ 0x9cbe, 0x3e12,
+ 0x9cc3, 0x4888,
+ 0x9cc6, 0x3e17,
+ 0x9cce, 0x488b,
+ 0x9ccf, 0x3e1f,
+ 0x9cd1, 0x3e21,
+ 0x9cd4, 0x488c,
+ 0x9cd8, 0x3e24,
+ 0x9cdb, 0x4890,
+ 0x9cdc, 0x3e27,
+ 0x9ce6, 0x4891,
+ 0x9ce7, 0x3e31,
+ 0x9cea, 0x4892,
+ 0x9ceb, 0x3e34,
+ 0x9ced, 0x4893,
+ 0x9cee, 0x3e36,
+ 0x9cfa, 0x4894,
+ 0x9cfd, 0x3e42,
+ 0x9cfe, 0x4897,
+ 0x9d40, 0x43e8,
+ 0x9d41, 0x4898,
+ 0x9d46, 0x3e43,
+ 0x9d47, 0x489d,
+ 0x9d49, 0x3e44,
+ 0x9d4a, 0x489f,
+ 0x9d4c, 0x3e46,
+ 0x9d4e, 0x48a1,
+ 0x9d4f, 0x3e48,
+ 0x9d50, 0x48a2,
+ 0x9d51, 0x3e49,
+ 0x9d52, 0x48a3,
+ 0x9d55, 0x3e4a,
+ 0x9d56, 0x48a6,
+ 0x9d58, 0x48a7,
+ 0x9d5b, 0x48a9,
+ 0x9d61, 0x43c9,
+ 0x9d62, 0x3e4c,
+ 0x9d63, 0x48af,
+ 0x9d64, 0x3e4d,
+ 0x9d65, 0x48b0,
+ 0x9d78, 0x43f5,
+ 0x9d79, 0x3e4e,
+ 0x9d7a, 0x48c3,
+ 0x9d7e, 0x3e4f,
+ 0x9da1, 0x48c7,
+ 0x9da5, 0x3e50,
+ 0x9da9, 0x48cb,
+ 0x9daa, 0x3e54,
+ 0x9dab, 0x48cc,
+ 0x9dac, 0x3e55,
+ 0x9dae, 0x48cd,
+ 0x9db0, 0x3e58,
+ 0x9db1, 0x48cf,
+ 0x9db3, 0x3e59,
+ 0x9db4, 0x48d1,
+ 0x9db5, 0x3e5a,
+ 0x9db6, 0x48d2,
+ 0x9db7, 0x3e5b,
+ 0x9db8, 0x48d3,
+ 0x9dbc, 0x3e5c,
+ 0x9dbe, 0x48d7,
+ 0x9dbf, 0x3e5e,
+ 0x9dc1, 0x48d8,
+ 0x9dc3, 0x3e60,
+ 0x9dc5, 0x48da,
+ 0x9dc7, 0x3e62,
+ 0x9dc9, 0x48dc,
+ 0x9dca, 0x3e64,
+ 0x9dcb, 0x48dd,
+ 0x9dcd, 0x3e65,
+ 0x9dd2, 0x48df,
+ 0x9dd3, 0x3e6a,
+ 0x9dd6, 0x48e0,
+ 0x9dda, 0x3e6d,
+ 0x9dfc, 0x48e4,
+ 0x9dfd, 0x3e8f,
+ 0x9e40, 0x3e91,
+ 0x9e43, 0x48e5,
+ 0x9e44, 0x3e95,
+ 0x9e5f, 0x48e6,
+ 0x9e60, 0x3eb1,
+ 0x9e63, 0x48e7,
+ 0x9e64, 0x3eb4,
+ 0x9e66, 0x48e8,
+ 0x9e68, 0x3eb6,
+ 0x9e69, 0x48ea,
+ 0x9e6a, 0x3eb7,
+ 0x9e6b, 0x48eb,
+ 0x9e71, 0x3eb8,
+ 0x9e72, 0x48f1,
+ 0x9e73, 0x3eb9,
+ 0x9e74, 0x48f2,
+ 0x9e77, 0x3eba,
+ 0x9e79, 0x48f5,
+ 0x9e7a, 0x3ebc,
+ 0x9e7b, 0x48f6,
+ 0x9e7c, 0x3ebd,
+ 0x9e7d, 0x48f7,
+ 0x9e7e, 0x3ebe,
+ 0x9ea1, 0x3ebf,
+ 0x9ea3, 0x48f8,
+ 0x9ea4, 0x3ec1,
+ 0x9ea7, 0x48f9,
+ 0x9eaa, 0x3ec5,
+ 0x9eab, 0x48fb,
+ 0x9ead, 0x3ec7,
+ 0x9eae, 0x48fc,
+ 0x9eaf, 0x3ec8,
+ 0x9eb2, 0x48fd,
+ 0x9eb4, 0x3ecb,
+ 0x9eb5, 0x48ff,
+ 0x9eb6, 0x3ecc,
+ 0x9eb8, 0x4900,
+ 0x9eb9, 0x3ece,
+ 0x9eba, 0x4901,
+ 0x9ebc, 0x3ecf,
+ 0x9ebd, 0x4903,
+ 0x9ebf, 0x3ed0,
+ 0x9ec1, 0x4905,
+ 0x9ec5, 0x3ed3,
+ 0x9ec6, 0x4908,
+ 0x9ec7, 0x3ed4,
+ 0x9ecb, 0x4909,
+ 0x9ecd, 0x3ed9,
+ 0x9ece, 0x490b,
+ 0x9ed0, 0x3eda,
+ 0x9ed2, 0x490d,
+ 0x9ed3, 0x3edc,
+ 0x9ed4, 0x490e,
+ 0x9ed6, 0x3edd,
+ 0x9ed8, 0x4910,
+ 0x9eda, 0x3edf,
+ 0x9ef0, 0x3ef5,
+ 0x9ef2, 0x4912,
+ 0x9ef3, 0x3ef7,
+ 0x9ef5, 0x3ef9,
+ 0x9ef6, 0x4913,
+ 0x9ef9, 0x3efa,
+ 0x9efb, 0x4916,
+ 0x9efc, 0x3efc,
+ 0x9efe, 0x3efe,
+ 0x9f40, 0x3eff,
+ 0x9f43, 0x4917,
+ 0x9f44, 0x3f02,
+ 0x9f48, 0x4918,
+ 0x9f49, 0x3f06,
+ 0x9f4b, 0x4919,
+ 0x9f4d, 0x3f08,
+ 0x9f4f, 0x3f0a,
+ 0x9f61, 0x3f1c,
+ 0x9f67, 0x491b,
+ 0x9f69, 0x3f23,
+ 0x9f70, 0x491d,
+ 0x9f71, 0x3f2a,
+ 0x9fa1, 0x3f38,
+ 0x9fae, 0x3f45,
+ 0x9fb2, 0x3f49,
+ 0x9fb5, 0x491e,
+ 0x9fb6, 0x3f4c,
+ 0x9fbb, 0x491f,
+ 0x9fbc, 0x3f51,
+ 0x9fbf, 0x4920,
+ 0x9fc1, 0x4921,
+ 0x9fc2, 0x3f55,
+ 0x9fc9, 0x3f5c,
+ 0x9fcc, 0x4922,
+ 0x9fcd, 0x3f60,
+ 0x9fd4, 0x4923,
+ 0x9fd5, 0x3f68,
+ 0x9fd9, 0x3f6c,
+ 0x9fdb, 0x3f6e,
+ 0x9fe4, 0x4924,
+ 0x9fe5, 0x3f77,
+ 0x9fe7, 0x3f79,
+ 0x9feb, 0x3f7d,
+ 0x9ff0, 0x3f82,
+ 0x9ff9, 0x4925,
+ 0x9ffa, 0x3f8b,
+ 0xa040, 0x4926,
+ 0xa041, 0x3f90,
+ 0xa047, 0x4927,
+ 0xa048, 0x3f96,
+ 0xa055, 0x4928,
+ 0xa056, 0x3fa3,
+ 0xa058, 0x3fa5,
+ 0xa05b, 0x3fa8,
+ 0xa064, 0x3fb1,
+ 0xa06d, 0x4929,
+ 0xa06e, 0x3fba,
+ 0xa073, 0x3fbf,
+ 0xa078, 0x3fc4,
+ 0xa07b, 0x492a,
+ 0xa07c, 0x3fc7,
+ 0xa0a1, 0x3fca,
+ 0xa0a2, 0x492b,
+ 0xa0a3, 0x3fcb,
+ 0xa0a6, 0x3fce,
+ 0xa0a7, 0x492c,
+ 0xa0a8, 0x3fcf,
+ 0xa0ae, 0x3fd5,
+ 0xa0b0, 0x3fd7,
+ 0xa0c5, 0x492d,
+ 0xa0c6, 0x3fec,
+ 0xa0d0, 0x492e,
+ 0xa0d1, 0x3ff6,
+ 0xa0d4, 0x3ff9,
+ 0xa0d6, 0x3ffb,
+ 0xa0e0, 0x4005,
+ 0xa0e2, 0x4007,
+ 0xa0e3, 0x492f,
+ 0xa0e5, 0x4009,
+ 0xa0e7, 0x4930,
+ 0xa0ee, 0x43b4,
+ 0xa0ef, 0x4937,
+ 0xa0f2, 0x43b8,
+ 0xa0f3, 0x493a,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc6a1, 0x01fa,
+ 0xc6bf, 0x0219,
+ 0xc6d8, 0x35b3,
+ 0xc6df, 0x1794,
+ 0xc6e0, 0x35ba,
+ 0xc740, 0x35d9,
+ 0xc7a1, 0x3618,
+ 0xc840, 0x3676,
+ 0xc8a1, 0x36b5,
+ 0xc8d4, 0x44c6,
+ 0xc8d7, 0x451c,
+ 0xc8e0, 0x02dc,
+ 0xc8e1, 0x4525,
+ 0xc8e9, 0x0509,
+ 0xc8ea, 0x452d,
+ 0xc8f1, 0x09f6,
+ 0xc8f5, 0x4992,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xf9d6, 0x36e8,
+ 0xfa40, 0x400b,
+ 0xfa60, 0x402b,
+ 0xfa67, 0x4032,
+ 0xfaa1, 0x404a,
+ 0xfaa9, 0x4946,
+ 0xfaab, 0x4054,
+ 0xfabe, 0x4067,
+ 0xfac6, 0x406f,
+ 0xfad6, 0x407f,
+ 0xfb40, 0x40a8,
+ 0xfb49, 0x40b1,
+ 0xfb53, 0x4948,
+ 0xfb54, 0x40bc,
+ 0xfb6e, 0x4949,
+ 0xfb6f, 0x40d7,
+ 0xfba1, 0x40e7,
+ 0xfba3, 0x494a,
+ 0xfba4, 0x40ea,
+ 0xfbb9, 0x40ff,
+ 0xfbbf, 0x494b,
+ 0xfbc0, 0x4105,
+ 0xfbcd, 0x494c,
+ 0xfbce, 0x4112,
+ 0xfbf4, 0x4138,
+ 0xfbfa, 0x413e,
+ 0xfc40, 0x4143,
+ 0xfc4a, 0x494d,
+ 0xfc4b, 0x414d,
+ 0xfc50, 0x4151,
+ 0xfc52, 0x494e,
+ 0xfc53, 0x4153,
+ 0xfc63, 0x494f,
+ 0xfc64, 0x4163,
+ 0xfc6d, 0x4950,
+ 0xfc6e, 0x416d,
+ 0xfc75, 0x4951,
+ 0xfc76, 0x4174,
+ 0xfca1, 0x417d,
+ 0xfcba, 0x4195,
+ 0xfcbc, 0x4952,
+ 0xfcbe, 0x4198,
+ 0xfccc, 0x4954,
+ 0xfccd, 0x41a7,
+ 0xfce3, 0x4955,
+ 0xfce4, 0x41bd,
+ 0xfcee, 0x4956,
+ 0xfcef, 0x41c7,
+ 0xfcf2, 0x41ca,
+ 0xfd40, 0x41d7,
+ 0xfd49, 0x4957,
+ 0xfd4a, 0x41e0,
+ 0xfd6a, 0x4958,
+ 0xfd6b, 0x4201,
+ 0xfda1, 0x4215,
+ 0xfdb9, 0x422d,
+ 0xfdbc, 0x4230,
+ 0xfde3, 0x4959,
+ 0xfde4, 0x4258,
+ 0xfdf2, 0x495a,
+ 0xfdf3, 0x4266,
+ 0xfe40, 0x4272,
+ 0xfe53, 0x4285,
+ 0xfe6d, 0x495b,
+ 0xfe6e, 0x429f,
+ 0xfe70, 0x42a1,
+ 0xfe78, 0x495c,
+ 0xfe79, 0x42a9,
+ 0xfea1, 0x42af,
+ 0xfeab, 0x42b8,
+ 0xfede, 0x495d,
+ 0xfee0, 0x42eb,
+ 0xfeed, 0x495f,
+ 0xfeef, 0x42f8,
+ 0xa14b, 0x354e,
+ 0xa15a, 0x35af,
+ 0xa15c, 0x35b1,
+ 0xa15d, 0x0082,
+ 0xa161, 0x0086,
+ 0xa165, 0x008a,
+ 0xa169, 0x008e,
+ 0xa16d, 0x0092,
+ 0xa171, 0x0096,
+ 0xa175, 0x009a,
+ 0xa179, 0x009e,
+ 0xa1e3, 0x354f,
+ 0xc6e4, 0x3711,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13ETHKB5VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13ETHKB5VMap2, 1139
+};
+
+static Gushort cns13ETenB5HMap2[510] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc6a1, 0x01fa,
+ 0xc6bf, 0x0219,
+ 0xc6d8, 0x35b3,
+ 0xc6df, 0x1794,
+ 0xc6e0, 0x35ba,
+ 0xc740, 0x35d9,
+ 0xc7a1, 0x3618,
+ 0xc840, 0x3676,
+ 0xc8a1, 0x36b5,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xf9d6, 0x36e8,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13ETenB5HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3550, 0x3551, 0x3552, 0x3553, 0x3554, 0x3555, 0x3556, 0x3557,
+ 0x3558, 0x3559, 0x355a, 0x355b, 0x355c, 0x355d, 0x355e, 0x355f,
+ 0x3560, 0x3561, 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567,
+ 0x3568, 0x3569, 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f,
+ 0x3570, 0x3571, 0x3572, 0x3573, 0x3574, 0x3575, 0x3576, 0x3577,
+ 0x3578, 0x3579, 0x357a, 0x357b, 0x357c, 0x357d, 0x357e, 0x357f,
+ 0x3580, 0x3581, 0x3582, 0x3583, 0x3584, 0x3585, 0x3586, 0x3587,
+ 0x3588, 0x3589, 0x358a, 0x358b, 0x358c, 0x358d, 0x358e, 0x358f,
+ 0x3590, 0x3591, 0x3592, 0x3593, 0x3594, 0x3595, 0x3596, 0x3597,
+ 0x3598, 0x3599, 0x359a, 0x359b, 0x359c, 0x359d, 0x359e, 0x359f,
+ 0x35a0, 0x35a1, 0x35a2, 0x35a3, 0x35a4, 0x35a5, 0x35a6, 0x35a7,
+ 0x35a8, 0x35a9, 0x35aa, 0x35ab, 0x35ac, 0x35ad, 0x35ae, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13ETenB5HMap2, 255
+};
+
+static Gushort cns13ETenB5VMap2[536] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc6a1, 0x01fa,
+ 0xc6bf, 0x0219,
+ 0xc6d8, 0x35b3,
+ 0xc6df, 0x1794,
+ 0xc6e0, 0x35ba,
+ 0xc740, 0x35d9,
+ 0xc7a1, 0x3618,
+ 0xc840, 0x3676,
+ 0xc8a1, 0x36b5,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xf9d6, 0x36e8,
+ 0xa14b, 0x354e,
+ 0xa15a, 0x35af,
+ 0xa15c, 0x35b1,
+ 0xa15d, 0x0082,
+ 0xa161, 0x0086,
+ 0xa165, 0x008a,
+ 0xa169, 0x008e,
+ 0xa16d, 0x0092,
+ 0xa171, 0x0096,
+ 0xa175, 0x009a,
+ 0xa179, 0x009e,
+ 0xa1e3, 0x354f,
+ 0xc6e4, 0x3711,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13ETenB5VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3550, 0x3551, 0x3552, 0x3553, 0x3554, 0x3555, 0x3556, 0x3557,
+ 0x3558, 0x3559, 0x355a, 0x355b, 0x355c, 0x355d, 0x355e, 0x355f,
+ 0x3560, 0x3561, 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567,
+ 0x3568, 0x3569, 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f,
+ 0x3570, 0x3571, 0x3572, 0x3573, 0x3574, 0x3575, 0x3576, 0x3577,
+ 0x3578, 0x3579, 0x357a, 0x357b, 0x357c, 0x357d, 0x357e, 0x357f,
+ 0x3580, 0x3581, 0x3582, 0x3583, 0x3584, 0x3585, 0x3586, 0x3587,
+ 0x3588, 0x3589, 0x358a, 0x358b, 0x358c, 0x358d, 0x358e, 0x358f,
+ 0x3590, 0x3591, 0x3592, 0x3593, 0x3594, 0x3595, 0x3596, 0x3597,
+ 0x3598, 0x3599, 0x359a, 0x359b, 0x359c, 0x359d, 0x359e, 0x359f,
+ 0x35a0, 0x35a1, 0x35a2, 0x35a3, 0x35a4, 0x35a5, 0x35a6, 0x35a7,
+ 0x35a8, 0x35a9, 0x35aa, 0x35ab, 0x35ac, 0x35ad, 0x35ae, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13ETenB5VMap2, 268
+};
+
+static Gushort cns13ETenmsB5HMap2[510] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc6a1, 0x01fa,
+ 0xc6bf, 0x0219,
+ 0xc6d8, 0x35b3,
+ 0xc6df, 0x1794,
+ 0xc6e0, 0x35ba,
+ 0xc740, 0x35d9,
+ 0xc7a1, 0x3618,
+ 0xc840, 0x3676,
+ 0xc8a1, 0x36b5,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xf9d6, 0x36e8,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13ETenmsB5HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13ETenmsB5HMap2, 255
+};
+
+static Gushort cns13ETenmsB5VMap2[568] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa14b, 0x354e,
+ 0xa14c, 0x006d,
+ 0xa14d, 0x0070,
+ 0xa156, 0x0138,
+ 0xa157, 0x007a,
+ 0xa158, 0x007a,
+ 0xa159, 0x35af,
+ 0xa15a, 0x35af,
+ 0xa15b, 0x35b1,
+ 0xa15c, 0x35b1,
+ 0xa15d, 0x0082,
+ 0xa15f, 0x0082,
+ 0xa161, 0x0086,
+ 0xa163, 0x0086,
+ 0xa165, 0x008a,
+ 0xa167, 0x008a,
+ 0xa169, 0x008e,
+ 0xa16b, 0x008e,
+ 0xa16d, 0x0092,
+ 0xa16f, 0x0092,
+ 0xa171, 0x0096,
+ 0xa173, 0x0096,
+ 0xa175, 0x009a,
+ 0xa177, 0x009a,
+ 0xa179, 0x009e,
+ 0xa17b, 0x009e,
+ 0xa17d, 0x0082,
+ 0xa1a1, 0x0086,
+ 0xa1a3, 0x008a,
+ 0xa1a5, 0x00a6,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc6a1, 0x01fa,
+ 0xc6bf, 0x0219,
+ 0xc6d8, 0x35b3,
+ 0xc6df, 0x1794,
+ 0xc6e0, 0x35ba,
+ 0xc6e4, 0x3711,
+ 0xc6e6, 0x35c0,
+ 0xc740, 0x35d9,
+ 0xc7a1, 0x3618,
+ 0xc840, 0x3676,
+ 0xc8a1, 0x36b5,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xf9d6, 0x36e8,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13ETenmsB5VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13ETenmsB5VMap2, 284
+};
+
+static Gushort cns13HKdlaB5HMap2[2046] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xfa41, 0x4149,
+ 0xfa42, 0x3ea3,
+ 0xfa43, 0x3e84,
+ 0xfa44, 0x3e87,
+ 0xfa45, 0x3e05,
+ 0xfa46, 0x4096,
+ 0xfa47, 0x39c4,
+ 0xfa48, 0x3d6d,
+ 0xfa49, 0x3e7f,
+ 0xfa4a, 0x3c77,
+ 0xfa4b, 0x3e86,
+ 0xfa4c, 0x387c,
+ 0xfa4d, 0x3ea7,
+ 0xfa4e, 0x420e,
+ 0xfa4f, 0x3ea4,
+ 0xfa50, 0x418a,
+ 0xfa51, 0x405f,
+ 0xfa52, 0x4116,
+ 0xfa53, 0x408b,
+ 0xfa54, 0x3e66,
+ 0xfa55, 0x3e65,
+ 0xfa56, 0x3d8f,
+ 0xfa57, 0x419e,
+ 0xfa58, 0x3a66,
+ 0xfa59, 0x4161,
+ 0xfa5a, 0x3e8a,
+ 0xfa5b, 0x3d8e,
+ 0xfa5c, 0x3e8d,
+ 0xfa5d, 0x3dbc,
+ 0xfa5e, 0x3e95,
+ 0xfa5f, 0x39a3,
+ 0xfa60, 0x41f4,
+ 0xfa61, 0x3e91,
+ 0xfa62, 0x3bc6,
+ 0xfa63, 0x3dc3,
+ 0xfa64, 0x3eae,
+ 0xfa65, 0x3746,
+ 0xfa66, 0x3871,
+ 0xfa67, 0x3a00,
+ 0xfa68, 0x428c,
+ 0xfa69, 0x425b,
+ 0xfa6a, 0x3ead,
+ 0xfa6b, 0x4123,
+ 0xfa6c, 0x3ea6,
+ 0xfa6d, 0x3ea0,
+ 0xfa6e, 0x3b2e,
+ 0xfa6f, 0x3dbd,
+ 0xfa70, 0x3864,
+ 0xfa71, 0x3c7d,
+ 0xfa72, 0x3ea9,
+ 0xfa73, 0x420d,
+ 0xfa74, 0x3f58,
+ 0xfa75, 0x3e98,
+ 0xfa76, 0x3d70,
+ 0xfa77, 0x3ea8,
+ 0xfa78, 0x3e94,
+ 0xfa79, 0x3e9d,
+ 0xfa7a, 0x3aaa,
+ 0xfa7b, 0x3ea5,
+ 0xfa7c, 0x3ccc,
+ 0xfa7d, 0x4098,
+ 0xfa7e, 0x3e9f,
+ 0xfaa1, 0x41f5,
+ 0xfaa2, 0x3e8b,
+ 0xfaa3, 0x3b72,
+ 0xfaa4, 0x37e0,
+ 0xfaa5, 0x3adf,
+ 0xfaa6, 0x42e0,
+ 0xfaa7, 0x3e97,
+ 0xfaa8, 0x4192,
+ 0xfaa9, 0x3888,
+ 0xfaaa, 0x42c8,
+ 0xfaab, 0x3e90,
+ 0xfaac, 0x386f,
+ 0xfaad, 0x3e9c,
+ 0xfaae, 0x4144,
+ 0xfaaf, 0x4146,
+ 0xfab0, 0x3e9e,
+ 0xfab1, 0x3e89,
+ 0xfab2, 0x4093,
+ 0xfab3, 0x3e81,
+ 0xfab5, 0x3c0e,
+ 0xfab6, 0x3e85,
+ 0xfab7, 0x38dc,
+ 0xfab8, 0x4069,
+ 0xfab9, 0x37d8,
+ 0xfaba, 0x3e99,
+ 0xfabb, 0x3e83,
+ 0xfabc, 0x3e88,
+ 0xfabd, 0x3e80,
+ 0xfabe, 0x3eb1,
+ 0xfabf, 0x416a,
+ 0xfac0, 0x376b,
+ 0xfac1, 0x3e67,
+ 0xfac2, 0x3e78,
+ 0xfac3, 0x4262,
+ 0xfac4, 0x37f5,
+ 0xfac5, 0x37f4,
+ 0xfac6, 0x3b45,
+ 0xfac7, 0x3e59,
+ 0xfac8, 0x2abc,
+ 0xfac9, 0x3dbf,
+ 0xfaca, 0x40bd,
+ 0xfacb, 0x3e7e,
+ 0xfacc, 0x382d,
+ 0xfacd, 0x3eb0,
+ 0xface, 0x3eab,
+ 0xfacf, 0x3eb2,
+ 0xfad0, 0x4221,
+ 0xfad1, 0x3f6a,
+ 0xfad2, 0x381b,
+ 0xfad3, 0x3e9a,
+ 0xfad4, 0x4223,
+ 0xfad5, 0x3e8e,
+ 0xfad6, 0x3bfd,
+ 0xfad7, 0x405a,
+ 0xfad8, 0x3eaf,
+ 0xfad9, 0x3cc8,
+ 0xfada, 0x3948,
+ 0xfadb, 0x42bd,
+ 0xfadc, 0x40cc,
+ 0xfadd, 0x3e5c,
+ 0xfade, 0x3eac,
+ 0xfadf, 0x391a,
+ 0xfae0, 0x3eaa,
+ 0xfae1, 0x4399,
+ 0xfae2, 0x389a,
+ 0xfae3, 0x3e8c,
+ 0xfae4, 0x389f,
+ 0xfae5, 0x3ea1,
+ 0xfae6, 0x4187,
+ 0xfae7, 0x3e8f,
+ 0xfae8, 0x3fc3,
+ 0xfae9, 0x3ea2,
+ 0xfaea, 0x3e9b,
+ 0xfaeb, 0x3e7d,
+ 0xfaec, 0x4051,
+ 0xfaed, 0x3fbc,
+ 0xfaee, 0x3fd5,
+ 0xfaef, 0x3b14,
+ 0xfaf0, 0x4222,
+ 0xfaf1, 0x379b,
+ 0xfaf2, 0x407b,
+ 0xfaf3, 0x3788,
+ 0xfaf4, 0x3bb4,
+ 0xfaf5, 0x41d0,
+ 0xfaf6, 0x4264,
+ 0xfaf7, 0x385e,
+ 0xfaf8, 0x376c,
+ 0xfaf9, 0x3dbe,
+ 0xfafa, 0x3813,
+ 0xfafb, 0x3fff,
+ 0xfafc, 0x3d63,
+ 0xfafd, 0x3786,
+ 0xfafe, 0x3b4a,
+ 0xfb40, 0x373a,
+ 0xfb41, 0x427a,
+ 0xfb42, 0x3c7a,
+ 0xfb43, 0x4205,
+ 0xfb44, 0x3c26,
+ 0xfb45, 0x38af,
+ 0xfb46, 0x3936,
+ 0xfb47, 0x37a8,
+ 0xfb48, 0x3b74,
+ 0xfb49, 0x3f6d,
+ 0xfb4a, 0x3e96,
+ 0xfb4b, 0x37bc,
+ 0xfb4c, 0x3e7b,
+ 0xfb4d, 0x3fea,
+ 0xfb4e, 0x41ca,
+ 0xfb4f, 0x39d7,
+ 0xfb50, 0x40d1,
+ 0xfb51, 0x3b71,
+ 0xfb52, 0x3fcf,
+ 0xfb53, 0x07c2,
+ 0xfb54, 0x42fe,
+ 0xfb55, 0x3ccd,
+ 0xfb56, 0x3e70,
+ 0xfb57, 0x3e72,
+ 0xfb58, 0x374c,
+ 0xfb59, 0x3769,
+ 0xfb5a, 0x3b4f,
+ 0xfb5b, 0x379f,
+ 0xfb5c, 0x2e45,
+ 0xfb5d, 0x380d,
+ 0xfb5e, 0x3fa2,
+ 0xfb5f, 0x381c,
+ 0xfb60, 0x3f7c,
+ 0xfb61, 0x3f59,
+ 0xfb62, 0x3f9e,
+ 0xfb63, 0x3d93,
+ 0xfb64, 0x3815,
+ 0xfb65, 0x388b,
+ 0xfb66, 0x3c60,
+ 0xfb67, 0x38f0,
+ 0xfb68, 0x37aa,
+ 0xfb69, 0x3f34,
+ 0xfb6a, 0x3c12,
+ 0xfb6b, 0x3900,
+ 0xfb6c, 0x3faa,
+ 0xfb6d, 0x390b,
+ 0xfb6e, 0x3929,
+ 0xfb6f, 0x3f27,
+ 0xfb70, 0x3f90,
+ 0xfb71, 0x3f57,
+ 0xfb72, 0x3f5b,
+ 0xfb73, 0x3f62,
+ 0xfb74, 0x3d76,
+ 0xfb75, 0x39c8,
+ 0xfb76, 0x3f64,
+ 0xfb78, 0x393d,
+ 0xfb79, 0x3c66,
+ 0xfb7a, 0x39d0,
+ 0xfb7b, 0x4022,
+ 0xfb7c, 0x3f2c,
+ 0xfb7d, 0x3f28,
+ 0xfb7e, 0x39cc,
+ 0xfba1, 0x3f26,
+ 0xfba2, 0x39cd,
+ 0xfba3, 0x3f3f,
+ 0xfba4, 0x39c5,
+ 0xfba5, 0x3fce,
+ 0xfba6, 0x4034,
+ 0xfba7, 0x3f5e,
+ 0xfba8, 0x4032,
+ 0xfba9, 0x4054,
+ 0xfbaa, 0x4178,
+ 0xfbab, 0x3f60,
+ 0xfbac, 0x3f29,
+ 0xfbad, 0x405d,
+ 0xfbae, 0x3f43,
+ 0xfbaf, 0x3f68,
+ 0xfbb0, 0x4060,
+ 0xfbb1, 0x3f2a,
+ 0xfbb2, 0x4063,
+ 0xfbb3, 0x39e7,
+ 0xfbb4, 0x38b6,
+ 0xfbb5, 0x4090,
+ 0xfbb6, 0x4048,
+ 0xfbb7, 0x4012,
+ 0xfbb8, 0x3d7c,
+ 0xfbb9, 0x404b,
+ 0xfbba, 0x404d,
+ 0xfbbb, 0x404f,
+ 0xfbbc, 0x424f,
+ 0xfbbd, 0x3d79,
+ 0xfbbe, 0x3f40,
+ 0xfbbf, 0x3f0a,
+ 0xfbc0, 0x3fd0,
+ 0xfbc1, 0x3f36,
+ 0xfbc2, 0x406d,
+ 0xfbc3, 0x4085,
+ 0xfbc4, 0x4084,
+ 0xfbc5, 0x413e,
+ 0xfbc6, 0x413b,
+ 0xfbc7, 0x3fc6,
+ 0xfbc8, 0x4086,
+ 0xfbc9, 0x3952,
+ 0xfbca, 0x40a1,
+ 0xfbcb, 0x3f32,
+ 0xfbcc, 0x4203,
+ 0xfbcd, 0x3f66,
+ 0xfbce, 0x3d83,
+ 0xfbcf, 0x3e75,
+ 0xfbd0, 0x40a2,
+ 0xfbd1, 0x0570,
+ 0xfbd2, 0x3f39,
+ 0xfbd3, 0x0871,
+ 0xfbd4, 0x3f24,
+ 0xfbd5, 0x40ae,
+ 0xfbd6, 0x3f44,
+ 0xfbd7, 0x38f5,
+ 0xfbd8, 0x3fc9,
+ 0xfbd9, 0x3fcd,
+ 0xfbda, 0x3fb5,
+ 0xfbdb, 0x3e7c,
+ 0xfbdc, 0x3fd2,
+ 0xfbdd, 0x3f4d,
+ 0xfbde, 0x40bc,
+ 0xfbdf, 0x40b7,
+ 0xfbe0, 0x3858,
+ 0xfbe1, 0x43af,
+ 0xfbe2, 0x3f6c,
+ 0xfbe3, 0x3d85,
+ 0xfbe4, 0x4396,
+ 0xfbe5, 0x39a6,
+ 0xfbe6, 0x3f7d,
+ 0xfbe7, 0x3fbf,
+ 0xfbe8, 0x40c8,
+ 0xfbe9, 0x3f5f,
+ 0xfbea, 0x3f2b,
+ 0xfbeb, 0x3d72,
+ 0xfbec, 0x40cf,
+ 0xfbed, 0x3a05,
+ 0xfbee, 0x3d82,
+ 0xfbef, 0x40dc,
+ 0xfbf0, 0x3d65,
+ 0xfbf1, 0x40d4,
+ 0xfbf2, 0x40da,
+ 0xfbf3, 0x3f2d,
+ 0xfbf4, 0x0595,
+ 0xfbf5, 0x3d81,
+ 0xfbf6, 0x40f1,
+ 0xfbf7, 0x06f5,
+ 0xfbf8, 0x40f8,
+ 0xfbf9, 0x40fb,
+ 0xfbfa, 0x3f41,
+ 0xfbfb, 0x4118,
+ 0xfbfc, 0x3d89,
+ 0xfbfd, 0x3f5c,
+ 0xfbfe, 0x3d67,
+ 0xfc40, 0x3f0e,
+ 0xfc41, 0x3f13,
+ 0xfc42, 0x4122,
+ 0xfc43, 0x3fca,
+ 0xfc44, 0x4129,
+ 0xfc45, 0x3f0c,
+ 0xfc46, 0x3f0b,
+ 0xfc47, 0x3f61,
+ 0xfc48, 0x3d8a,
+ 0xfc49, 0x3f2e,
+ 0xfc4a, 0x1971,
+ 0xfc4b, 0x4135,
+ 0xfc4c, 0x3a2b,
+ 0xfc4d, 0x3f6b,
+ 0xfc4e, 0x3ba5,
+ 0xfc4f, 0x4044,
+ 0xfc50, 0x4255,
+ 0xfc51, 0x3737,
+ 0xfc52, 0x3f25,
+ 0xfc53, 0x3739,
+ 0xfc54, 0x3a30,
+ 0xfc55, 0x4143,
+ 0xfc56, 0x40c4,
+ 0xfc57, 0x3d64,
+ 0xfc58, 0x3fbe,
+ 0xfc59, 0x3fa6,
+ 0xfc5a, 0x402c,
+ 0xfc5b, 0x4157,
+ 0xfc5c, 0x3f9f,
+ 0xfc5d, 0x2b40,
+ 0xfc5e, 0x3fa7,
+ 0xfc5f, 0x4005,
+ 0xfc60, 0x4001,
+ 0xfc61, 0x1c9b,
+ 0xfc62, 0x3d84,
+ 0xfc63, 0x0a95,
+ 0xfc64, 0x416c,
+ 0xfc65, 0x4009,
+ 0xfc66, 0x3d75,
+ 0xfc67, 0x3adc,
+ 0xfc68, 0x3fa8,
+ 0xfc69, 0x3f37,
+ 0xfc6a, 0x4174,
+ 0xfc6b, 0x4006,
+ 0xfc6c, 0x4002,
+ 0xfc6d, 0x3fba,
+ 0xfc6e, 0x3fc0,
+ 0xfc6f, 0x12b0,
+ 0xfc70, 0x3fbd,
+ 0xfc71, 0x4173,
+ 0xfc72, 0x4186,
+ 0xfc73, 0x3a54,
+ 0xfc74, 0x3fc5,
+ 0xfc75, 0x4259,
+ 0xfc76, 0x3fc2,
+ 0xfc77, 0x3f15,
+ 0xfc78, 0x3f50,
+ 0xfc79, 0x3f86,
+ 0xfc7a, 0x3fc1,
+ 0xfc7b, 0x418c,
+ 0xfc7c, 0x3fc7,
+ 0xfc7d, 0x3f16,
+ 0xfc7e, 0x418e,
+ 0xfca1, 0x3f4b,
+ 0xfca2, 0x419d,
+ 0xfca3, 0x115f,
+ 0xfca4, 0x3fc4,
+ 0xfca5, 0x3384,
+ 0xfca6, 0x3d99,
+ 0xfca7, 0x41b9,
+ 0xfca8, 0x3a89,
+ 0xfca9, 0x41b7,
+ 0xfcaa, 0x3d8b,
+ 0xfcab, 0x3d66,
+ 0xfcac, 0x03e2,
+ 0xfcad, 0x3d6a,
+ 0xfcae, 0x3d7a,
+ 0xfcaf, 0x41e3,
+ 0xfcb0, 0x0619,
+ 0xfcb1, 0x3996,
+ 0xfcb2, 0x3fc8,
+ 0xfcb3, 0x3a9e,
+ 0xfcb4, 0x3f38,
+ 0xfcb5, 0x3d80,
+ 0xfcb6, 0x41de,
+ 0xfcb8, 0x42eb,
+ 0xfcb9, 0x3d86,
+ 0xfcba, 0x41db,
+ 0xfcbb, 0x3f3e,
+ 0xfcbc, 0x4056,
+ 0xfcbd, 0x41d9,
+ 0xfcbe, 0x3ff6,
+ 0xfcbf, 0x3f5d,
+ 0xfcc0, 0x3d74,
+ 0xfcc1, 0x41e8,
+ 0xfcc2, 0x41c7,
+ 0xfcc3, 0x3d91,
+ 0xfcc4, 0x3b4b,
+ 0xfcc5, 0x3d42,
+ 0xfcc6, 0x3aad,
+ 0xfcc7, 0x3aa5,
+ 0xfcc8, 0x41f2,
+ 0xfcc9, 0x3f4c,
+ 0xfcca, 0x41f8,
+ 0xfccb, 0x3f6e,
+ 0xfccc, 0x3f79,
+ 0xfccd, 0x3f8d,
+ 0xfcce, 0x4003,
+ 0xfccf, 0x3f91,
+ 0xfcd0, 0x3ac3,
+ 0xfcd1, 0x091a,
+ 0xfcd2, 0x4234,
+ 0xfcd3, 0x3ffb,
+ 0xfcd4, 0x4240,
+ 0xfcd6, 0x3ffd,
+ 0xfcd7, 0x3f78,
+ 0xfcd8, 0x3c75,
+ 0xfcd9, 0x3c73,
+ 0xfcda, 0x38a5,
+ 0xfcdb, 0x43f9,
+ 0xfcdc, 0x3cfe,
+ 0xfcdd, 0x4257,
+ 0xfcde, 0x4233,
+ 0xfcdf, 0x3d69,
+ 0xfce0, 0x3c7e,
+ 0xfce1, 0x3d6f,
+ 0xfce2, 0x4000,
+ 0xfce3, 0x3dc0,
+ 0xfce4, 0x4004,
+ 0xfce5, 0x0e72,
+ 0xfce6, 0x3938,
+ 0xfce7, 0x3fa4,
+ 0xfce8, 0x295a,
+ 0xfce9, 0x4273,
+ 0xfcea, 0x3ac9,
+ 0xfceb, 0x427d,
+ 0xfcec, 0x3aca,
+ 0xfced, 0x3fb2,
+ 0xfcee, 0x3fb6,
+ 0xfcef, 0x3f97,
+ 0xfcf0, 0x3f9a,
+ 0xfcf1, 0x428b,
+ 0xfcf2, 0x43fa,
+ 0xfcf3, 0x428a,
+ 0xfcf4, 0x3f51,
+ 0xfcf5, 0x3f98,
+ 0xfcf6, 0x41a3,
+ 0xfcf7, 0x3d5c,
+ 0xfcf8, 0x3f63,
+ 0xfcf9, 0x4290,
+ 0xfcfa, 0x1f94,
+ 0xfcfb, 0x42c6,
+ 0xfcfc, 0x42a2,
+ 0xfcfd, 0x3ffa,
+ 0xfcfe, 0x3f9d,
+ 0xfd40, 0x3ffe,
+ 0xfd41, 0x3f9b,
+ 0xfd42, 0x3fdf,
+ 0xfd43, 0x3fe6,
+ 0xfd44, 0x3fde,
+ 0xfd45, 0x42b7,
+ 0xfd46, 0x3ff4,
+ 0xfd47, 0x42b8,
+ 0xfd48, 0x3feb,
+ 0xfd49, 0x42bf,
+ 0xfd4a, 0x3d71,
+ 0xfd4b, 0x3f4f,
+ 0xfd4c, 0x42c5,
+ 0xfd4d, 0x42d5,
+ 0xfd4e, 0x42d0,
+ 0xfd4f, 0x42d8,
+ 0xfd50, 0x3f55,
+ 0xfd51, 0x3fe8,
+ 0xfd52, 0x3ff3,
+ 0xfd53, 0x42df,
+ 0xfd54, 0x3fd3,
+ 0xfd55, 0x3e73,
+ 0xfd56, 0x3f95,
+ 0xfd57, 0x42ee,
+ 0xfd58, 0x42f4,
+ 0xfd59, 0x3f8c,
+ 0xfd5a, 0x3fcf,
+ 0xfd5b, 0x42ec,
+ 0xfd5c, 0x3fd4,
+ 0xfd5d, 0x42f0,
+ 0xfd5e, 0x07c2,
+ 0xfd5f, 0x0955,
+ 0xfd60, 0x42fe,
+ 0xfd61, 0x4301,
+ 0xfd62, 0x3ccd,
+ 0xfd63, 0x4307,
+ 0xfd64, 0x43fb,
+ 0xfd65, 0x3fda,
+ 0xfd66, 0x3f8b,
+ 0xfd67, 0x3733,
+ 0xfd68, 0x3f8a,
+ 0xfd69, 0x3741,
+ 0xfd6a, 0x3740,
+ 0xfd6b, 0x3742,
+ 0xfd6c, 0x3f93,
+ 0xfd6d, 0x3f8f,
+ 0xfd6e, 0x3e70,
+ 0xfd6f, 0x42c9,
+ 0xfd70, 0x3e72,
+ 0xfd71, 0x3fa9,
+ 0xfd72, 0x42cd,
+ 0xfd73, 0x43d2,
+ 0xfd74, 0x3f8e,
+ 0xfd75, 0x3f77,
+ 0xfd76, 0x3d6e,
+ 0xfd77, 0x0d0a,
+ 0xfd78, 0x3f11,
+ 0xfd79, 0x3752,
+ 0xfd7a, 0x3f14,
+ 0xfd7b, 0x3f18,
+ 0xfd7c, 0x3f53,
+ 0xfd7d, 0x3f1f,
+ 0xfd7e, 0x3f1c,
+ 0xfda1, 0x3fb8,
+ 0xfda2, 0x339d,
+ 0xfda3, 0x3b3f,
+ 0xfda4, 0x3f52,
+ 0xfda5, 0x3f1a,
+ 0xfda6, 0x3f1d,
+ 0xfda7, 0x375c,
+ 0xfda8, 0x3885,
+ 0xfda9, 0x3761,
+ 0xfdaa, 0x3fd7,
+ 0xfdab, 0x3fd6,
+ 0xfdac, 0x3fd9,
+ 0xfdad, 0x3fd8,
+ 0xfdae, 0x3fdd,
+ 0xfdaf, 0x3e93,
+ 0xfdb0, 0x3769,
+ 0xfdb1, 0x376e,
+ 0xfdb2, 0x3b4c,
+ 0xfdb3, 0x3774,
+ 0xfdb4, 0x377f,
+ 0xfdb5, 0x377b,
+ 0xfdb6, 0x3782,
+ 0xfdb7, 0x3b4f,
+ 0xfdb8, 0x3792,
+ 0xfdb9, 0x3fe3,
+ 0xfdba, 0x3fdc,
+ 0xfdbb, 0x3fdb,
+ 0xfdbc, 0x3fe5,
+ 0xfdbd, 0x3b75,
+ 0xfdbe, 0x37a2,
+ 0xfdbf, 0x3fe2,
+ 0xfdc0, 0x3fe7,
+ 0xfdc1, 0x3e6d,
+ 0xfdc2, 0x0d2a,
+ 0xfdc3, 0x3e79,
+ 0xfdc4, 0x3e76,
+ 0xfdc5, 0x379f,
+ 0xfdc6, 0x3fee,
+ 0xfdc7, 0x42d4,
+ 0xfdc8, 0x3d94,
+ 0xfdc9, 0x3d61,
+ 0xfdca, 0x3fe1,
+ 0xfdcb, 0x375e,
+ 0xfdcc, 0x3b7a,
+ 0xfdcd, 0x380b,
+ 0xfdce, 0x3fec,
+ 0xfdcf, 0x3fef,
+ 0xfdd0, 0x2e45,
+ 0xfdd1, 0x3ffc,
+ 0xfdd2, 0x3fed,
+ 0xfdd3, 0x380d,
+ 0xfdd4, 0x3fe4,
+ 0xfdd5, 0x3f92,
+ 0xfdd6, 0x3fae,
+ 0xfdd7, 0x3811,
+ 0xfdd8, 0x3f7a,
+ 0xfdd9, 0x3b8b,
+ 0xfdda, 0x3f5a,
+ 0xfddb, 0x3816,
+ 0xfddc, 0x3fa2,
+ 0xfddd, 0x3b8e,
+ 0xfdde, 0x381c,
+ 0xfddf, 0x2054,
+ 0xfde0, 0x381f,
+ 0xfde1, 0x3fa0,
+ 0xfde2, 0x43fc,
+ 0xfde3, 0x3e16,
+ 0xfde4, 0x3b94,
+ 0xfde5, 0x3f7c,
+ 0xfde6, 0x4007,
+ 0xfde7, 0x3f7b,
+ 0xfde8, 0x3d73,
+ 0xfde9, 0x3e77,
+ 0xfdea, 0x3d92,
+ 0xfdeb, 0x3fa1,
+ 0xfdec, 0x37c1,
+ 0xfded, 0x37d3,
+ 0xfdee, 0x3e7a,
+ 0xfdef, 0x3f59,
+ 0xfdf0, 0x3c55,
+ 0xfdf1, 0x3ff8,
+ 0xfdf2, 0x3ff5,
+ 0xfdf3, 0x3c4c,
+ 0xfdf4, 0x3d8c,
+ 0xfdf5, 0x3fa3,
+ 0xfdf6, 0x37c0,
+ 0xfdf7, 0x3f54,
+ 0xfdf8, 0x3800,
+ 0xfdf9, 0x3b7f,
+ 0xfdfa, 0x3f9e,
+ 0xfdfb, 0x3822,
+ 0xfdfc, 0x3fe9,
+ 0xfdfd, 0x3823,
+ 0xfdfe, 0x3fe0,
+ 0xfe40, 0x3d93,
+ 0xfe41, 0x3ff9,
+ 0xfe42, 0x3827,
+ 0xfe43, 0x3fa5,
+ 0xfe44, 0x3ff0,
+ 0xfe45, 0x3836,
+ 0xfe46, 0x3f99,
+ 0xfe47, 0x3ff2,
+ 0xfe48, 0x3d8d,
+ 0xfe49, 0x43e6,
+ 0xfe4a, 0x3522,
+ 0xfe4b, 0x3ff1,
+ 0xfe4c, 0x3f9c,
+ 0xfe4d, 0x3fb1,
+ 0xfe4e, 0x3f96,
+ 0xfe4f, 0x3e6f,
+ 0xfe50, 0x3f69,
+ 0xfe51, 0x3ff7,
+ 0xfe52, 0x3f82,
+ 0xfe53, 0x3f88,
+ 0xfe54, 0x3f85,
+ 0xfe55, 0x3f83,
+ 0xfe56, 0x3f7f,
+ 0xfe57, 0x3f89,
+ 0xfe58, 0x3bb5,
+ 0xfe59, 0x3862,
+ 0xfe5a, 0x3f87,
+ 0xfe5b, 0x3f31,
+ 0xfe5c, 0x3815,
+ 0xfe5d, 0x387e,
+ 0xfe5e, 0x3f49,
+ 0xfe5f, 0x3f48,
+ 0xfe60, 0x3f47,
+ 0xfe61, 0x3f45,
+ 0xfe62, 0x43eb,
+ 0xfe63, 0x3882,
+ 0xfe64, 0x3f6f,
+ 0xfe65, 0x3f4e,
+ 0xfe66, 0x3bc8,
+ 0xfe67, 0x43fd,
+ 0xfe68, 0x3d6b,
+ 0xfe6a, 0x43fe,
+ 0xfe6b, 0x3fcb,
+ 0xfe6c, 0x3dd2,
+ 0xfe6d, 0x3879,
+ 0xfe6e, 0x3f10,
+ 0xfe6f, 0x382e,
+ 0xfe70, 0x388b,
+ 0xfe71, 0x3c60,
+ 0xfe72, 0x2a9f,
+ 0xfe73, 0x3c61,
+ 0xfe74, 0x3893,
+ 0xfe75, 0x3e74,
+ 0xfe76, 0x3fac,
+ 0xfe77, 0x3f81,
+ 0xfe78, 0x3bcd,
+ 0xfe79, 0x3bd4,
+ 0xfe7a, 0x3bd3,
+ 0xfe7b, 0x3fcc,
+ 0xfe7c, 0x3fd1,
+ 0xfe7d, 0x3f3d,
+ 0xfe7e, 0x3f4a,
+ 0xfea1, 0x2352,
+ 0xfea2, 0x38ad,
+ 0xfea3, 0x3f46,
+ 0xfea4, 0x38b5,
+ 0xfea5, 0x3f0d,
+ 0xfea6, 0x3fb3,
+ 0xfea7, 0x38c0,
+ 0xfea8, 0x3e2f,
+ 0xfea9, 0x38cf,
+ 0xfeaa, 0x38d5,
+ 0xfeab, 0x3f33,
+ 0xfeac, 0x3d95,
+ 0xfead, 0x3f35,
+ 0xfeae, 0x38d7,
+ 0xfeaf, 0x3f2f,
+ 0xfeb0, 0x38e0,
+ 0xfeb1, 0x3c02,
+ 0xfeb2, 0x3f72,
+ 0xfeb3, 0x3f70,
+ 0xfeb4, 0x3d96,
+ 0xfeb5, 0x38e6,
+ 0xfeb7, 0x4035,
+ 0xfeb8, 0x3f73,
+ 0xfeb9, 0x38f0,
+ 0xfeba, 0x3c0b,
+ 0xfebb, 0x38f7,
+ 0xfebc, 0x37aa,
+ 0xfebd, 0x43ff,
+ 0xfebe, 0x38fa,
+ 0xfebf, 0x3c11,
+ 0xfec0, 0x3f34,
+ 0xfec1, 0x3fb9,
+ 0xfec2, 0x3c12,
+ 0xfec3, 0x400a,
+ 0xfec4, 0x3d77,
+ 0xfec5, 0x3f42,
+ 0xfec6, 0x3900,
+ 0xfec7, 0x3902,
+ 0xfec8, 0x3f74,
+ 0xfec9, 0x3d97,
+ 0xfeca, 0x3faa,
+ 0xfecb, 0x3f19,
+ 0xfecc, 0x3f1b,
+ 0xfecd, 0x390e,
+ 0xfece, 0x3909,
+ 0xfecf, 0x390b,
+ 0xfed0, 0x3f12,
+ 0xfed1, 0x3f17,
+ 0xfed2, 0x3fb7,
+ 0xfed3, 0x3f20,
+ 0xfed4, 0x3fbb,
+ 0xfed5, 0x3f3c,
+ 0xfed6, 0x3fad,
+ 0xfed7, 0x3919,
+ 0xfed8, 0x3f56,
+ 0xfed9, 0x3f71,
+ 0xfeda, 0x3fb4,
+ 0xfedb, 0x391c,
+ 0xfedc, 0x3f1e,
+ 0xfedd, 0x3f3a,
+ 0xfede, 0x391b,
+ 0xfedf, 0x3d87,
+ 0xfee0, 0x3c3a,
+ 0xfee1, 0x3f22,
+ 0xfee2, 0x3e71,
+ 0xfee3, 0x3c39,
+ 0xfee4, 0x3d7e,
+ 0xfee5, 0x4124,
+ 0xfee6, 0x3f3b,
+ 0xfee7, 0x3e6e,
+ 0xfee8, 0x3fab,
+ 0xfee9, 0x3925,
+ 0xfeea, 0x3f30,
+ 0xfeeb, 0x3929,
+ 0xfeec, 0x3f84,
+ 0xfeed, 0x3f0f,
+ 0xfeee, 0x3f76,
+ 0xfeef, 0x3f94,
+ 0xfef0, 0x3932,
+ 0xfef1, 0x3f27,
+ 0xfef2, 0x3933,
+ 0xfef3, 0x3f75,
+ 0xfef4, 0x3937,
+ 0xfef5, 0x3d78,
+ 0xfef6, 0x3f21,
+ 0xfef7, 0x3f90,
+ 0xfef8, 0x3940,
+ 0xfef9, 0x3d7f,
+ 0xfefa, 0x394a,
+ 0xfefb, 0x3f80,
+ 0xfefc, 0x3f23,
+ 0xfefd, 0x3950,
+ 0xfefe, 0x3f7e,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKdlaB5HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKdlaB5HMap2, 1023
+};
+
+static Gushort cns13HKdlaB5VMap2[2070] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xfa41, 0x4149,
+ 0xfa42, 0x3ea3,
+ 0xfa43, 0x3e84,
+ 0xfa44, 0x3e87,
+ 0xfa45, 0x3e05,
+ 0xfa46, 0x4096,
+ 0xfa47, 0x39c4,
+ 0xfa48, 0x3d6d,
+ 0xfa49, 0x3e7f,
+ 0xfa4a, 0x3c77,
+ 0xfa4b, 0x3e86,
+ 0xfa4c, 0x387c,
+ 0xfa4d, 0x3ea7,
+ 0xfa4e, 0x420e,
+ 0xfa4f, 0x3ea4,
+ 0xfa50, 0x418a,
+ 0xfa51, 0x405f,
+ 0xfa52, 0x4116,
+ 0xfa53, 0x408b,
+ 0xfa54, 0x3e66,
+ 0xfa55, 0x3e65,
+ 0xfa56, 0x3d8f,
+ 0xfa57, 0x419e,
+ 0xfa58, 0x3a66,
+ 0xfa59, 0x4161,
+ 0xfa5a, 0x3e8a,
+ 0xfa5b, 0x3d8e,
+ 0xfa5c, 0x3e8d,
+ 0xfa5d, 0x3dbc,
+ 0xfa5e, 0x3e95,
+ 0xfa5f, 0x39a3,
+ 0xfa60, 0x41f4,
+ 0xfa61, 0x3e91,
+ 0xfa62, 0x3bc6,
+ 0xfa63, 0x3dc3,
+ 0xfa64, 0x3eae,
+ 0xfa65, 0x3746,
+ 0xfa66, 0x3871,
+ 0xfa67, 0x3a00,
+ 0xfa68, 0x428c,
+ 0xfa69, 0x425b,
+ 0xfa6a, 0x3ead,
+ 0xfa6b, 0x4123,
+ 0xfa6c, 0x3ea6,
+ 0xfa6d, 0x3ea0,
+ 0xfa6e, 0x3b2e,
+ 0xfa6f, 0x3dbd,
+ 0xfa70, 0x3864,
+ 0xfa71, 0x3c7d,
+ 0xfa72, 0x3ea9,
+ 0xfa73, 0x420d,
+ 0xfa74, 0x3f58,
+ 0xfa75, 0x3e98,
+ 0xfa76, 0x3d70,
+ 0xfa77, 0x3ea8,
+ 0xfa78, 0x3e94,
+ 0xfa79, 0x3e9d,
+ 0xfa7a, 0x3aaa,
+ 0xfa7b, 0x3ea5,
+ 0xfa7c, 0x3ccc,
+ 0xfa7d, 0x4098,
+ 0xfa7e, 0x3e9f,
+ 0xfaa1, 0x41f5,
+ 0xfaa2, 0x3e8b,
+ 0xfaa3, 0x3b72,
+ 0xfaa4, 0x37e0,
+ 0xfaa5, 0x3adf,
+ 0xfaa6, 0x42e0,
+ 0xfaa7, 0x3e97,
+ 0xfaa8, 0x4192,
+ 0xfaa9, 0x3888,
+ 0xfaaa, 0x42c8,
+ 0xfaab, 0x3e90,
+ 0xfaac, 0x386f,
+ 0xfaad, 0x3e9c,
+ 0xfaae, 0x4144,
+ 0xfaaf, 0x4146,
+ 0xfab0, 0x3e9e,
+ 0xfab1, 0x3e89,
+ 0xfab2, 0x4093,
+ 0xfab3, 0x3e81,
+ 0xfab5, 0x3c0e,
+ 0xfab6, 0x3e85,
+ 0xfab7, 0x38dc,
+ 0xfab8, 0x4069,
+ 0xfab9, 0x37d8,
+ 0xfaba, 0x3e99,
+ 0xfabb, 0x3e83,
+ 0xfabc, 0x3e88,
+ 0xfabd, 0x3e80,
+ 0xfabe, 0x3eb1,
+ 0xfabf, 0x416a,
+ 0xfac0, 0x376b,
+ 0xfac1, 0x3e67,
+ 0xfac2, 0x3e78,
+ 0xfac3, 0x4262,
+ 0xfac4, 0x37f5,
+ 0xfac5, 0x37f4,
+ 0xfac6, 0x3b45,
+ 0xfac7, 0x3e59,
+ 0xfac8, 0x2abc,
+ 0xfac9, 0x3dbf,
+ 0xfaca, 0x40bd,
+ 0xfacb, 0x3e7e,
+ 0xfacc, 0x382d,
+ 0xfacd, 0x3eb0,
+ 0xface, 0x3eab,
+ 0xfacf, 0x3eb2,
+ 0xfad0, 0x4221,
+ 0xfad1, 0x3f6a,
+ 0xfad2, 0x381b,
+ 0xfad3, 0x3e9a,
+ 0xfad4, 0x4223,
+ 0xfad5, 0x3e8e,
+ 0xfad6, 0x3bfd,
+ 0xfad7, 0x405a,
+ 0xfad8, 0x3eaf,
+ 0xfad9, 0x3cc8,
+ 0xfada, 0x3948,
+ 0xfadb, 0x42bd,
+ 0xfadc, 0x40cc,
+ 0xfadd, 0x3e5c,
+ 0xfade, 0x3eac,
+ 0xfadf, 0x391a,
+ 0xfae0, 0x3eaa,
+ 0xfae1, 0x4399,
+ 0xfae2, 0x389a,
+ 0xfae3, 0x3e8c,
+ 0xfae4, 0x389f,
+ 0xfae5, 0x3ea1,
+ 0xfae6, 0x4187,
+ 0xfae7, 0x3e8f,
+ 0xfae8, 0x3fc3,
+ 0xfae9, 0x3ea2,
+ 0xfaea, 0x3e9b,
+ 0xfaeb, 0x3e7d,
+ 0xfaec, 0x4051,
+ 0xfaed, 0x3fbc,
+ 0xfaee, 0x3fd5,
+ 0xfaef, 0x3b14,
+ 0xfaf0, 0x4222,
+ 0xfaf1, 0x379b,
+ 0xfaf2, 0x407b,
+ 0xfaf3, 0x3788,
+ 0xfaf4, 0x3bb4,
+ 0xfaf5, 0x41d0,
+ 0xfaf6, 0x4264,
+ 0xfaf7, 0x385e,
+ 0xfaf8, 0x376c,
+ 0xfaf9, 0x3dbe,
+ 0xfafa, 0x3813,
+ 0xfafb, 0x3fff,
+ 0xfafc, 0x3d63,
+ 0xfafd, 0x3786,
+ 0xfafe, 0x3b4a,
+ 0xfb40, 0x373a,
+ 0xfb41, 0x427a,
+ 0xfb42, 0x3c7a,
+ 0xfb43, 0x4205,
+ 0xfb44, 0x3c26,
+ 0xfb45, 0x38af,
+ 0xfb46, 0x3936,
+ 0xfb47, 0x37a8,
+ 0xfb48, 0x3b74,
+ 0xfb49, 0x3f6d,
+ 0xfb4a, 0x3e96,
+ 0xfb4b, 0x37bc,
+ 0xfb4c, 0x3e7b,
+ 0xfb4d, 0x3fea,
+ 0xfb4e, 0x41ca,
+ 0xfb4f, 0x39d7,
+ 0xfb50, 0x40d1,
+ 0xfb51, 0x3b71,
+ 0xfb52, 0x3fcf,
+ 0xfb53, 0x07c2,
+ 0xfb54, 0x42fe,
+ 0xfb55, 0x3ccd,
+ 0xfb56, 0x3e70,
+ 0xfb57, 0x3e72,
+ 0xfb58, 0x374c,
+ 0xfb59, 0x3769,
+ 0xfb5a, 0x3b4f,
+ 0xfb5b, 0x379f,
+ 0xfb5c, 0x2e45,
+ 0xfb5d, 0x380d,
+ 0xfb5e, 0x3fa2,
+ 0xfb5f, 0x381c,
+ 0xfb60, 0x3f7c,
+ 0xfb61, 0x3f59,
+ 0xfb62, 0x3f9e,
+ 0xfb63, 0x3d93,
+ 0xfb64, 0x3815,
+ 0xfb65, 0x388b,
+ 0xfb66, 0x3c60,
+ 0xfb67, 0x38f0,
+ 0xfb68, 0x37aa,
+ 0xfb69, 0x3f34,
+ 0xfb6a, 0x3c12,
+ 0xfb6b, 0x3900,
+ 0xfb6c, 0x3faa,
+ 0xfb6d, 0x390b,
+ 0xfb6e, 0x3929,
+ 0xfb6f, 0x3f27,
+ 0xfb70, 0x3f90,
+ 0xfb71, 0x3f57,
+ 0xfb72, 0x3f5b,
+ 0xfb73, 0x3f62,
+ 0xfb74, 0x3d76,
+ 0xfb75, 0x39c8,
+ 0xfb76, 0x3f64,
+ 0xfb78, 0x393d,
+ 0xfb79, 0x3c66,
+ 0xfb7a, 0x39d0,
+ 0xfb7b, 0x4022,
+ 0xfb7c, 0x3f2c,
+ 0xfb7d, 0x3f28,
+ 0xfb7e, 0x39cc,
+ 0xfba1, 0x3f26,
+ 0xfba2, 0x39cd,
+ 0xfba3, 0x3f3f,
+ 0xfba4, 0x39c5,
+ 0xfba5, 0x3fce,
+ 0xfba6, 0x4034,
+ 0xfba7, 0x3f5e,
+ 0xfba8, 0x4032,
+ 0xfba9, 0x4054,
+ 0xfbaa, 0x4178,
+ 0xfbab, 0x3f60,
+ 0xfbac, 0x3f29,
+ 0xfbad, 0x405d,
+ 0xfbae, 0x3f43,
+ 0xfbaf, 0x3f68,
+ 0xfbb0, 0x4060,
+ 0xfbb1, 0x3f2a,
+ 0xfbb2, 0x4063,
+ 0xfbb3, 0x39e7,
+ 0xfbb4, 0x38b6,
+ 0xfbb5, 0x4090,
+ 0xfbb6, 0x4048,
+ 0xfbb7, 0x4012,
+ 0xfbb8, 0x3d7c,
+ 0xfbb9, 0x404b,
+ 0xfbba, 0x404d,
+ 0xfbbb, 0x404f,
+ 0xfbbc, 0x424f,
+ 0xfbbd, 0x3d79,
+ 0xfbbe, 0x3f40,
+ 0xfbbf, 0x3f0a,
+ 0xfbc0, 0x3fd0,
+ 0xfbc1, 0x3f36,
+ 0xfbc2, 0x406d,
+ 0xfbc3, 0x4085,
+ 0xfbc4, 0x4084,
+ 0xfbc5, 0x413e,
+ 0xfbc6, 0x413b,
+ 0xfbc7, 0x3fc6,
+ 0xfbc8, 0x4086,
+ 0xfbc9, 0x3952,
+ 0xfbca, 0x40a1,
+ 0xfbcb, 0x3f32,
+ 0xfbcc, 0x4203,
+ 0xfbcd, 0x3f66,
+ 0xfbce, 0x3d83,
+ 0xfbcf, 0x3e75,
+ 0xfbd0, 0x40a2,
+ 0xfbd1, 0x0570,
+ 0xfbd2, 0x3f39,
+ 0xfbd3, 0x0871,
+ 0xfbd4, 0x3f24,
+ 0xfbd5, 0x40ae,
+ 0xfbd6, 0x3f44,
+ 0xfbd7, 0x38f5,
+ 0xfbd8, 0x3fc9,
+ 0xfbd9, 0x3fcd,
+ 0xfbda, 0x3fb5,
+ 0xfbdb, 0x3e7c,
+ 0xfbdc, 0x3fd2,
+ 0xfbdd, 0x3f4d,
+ 0xfbde, 0x40bc,
+ 0xfbdf, 0x40b7,
+ 0xfbe0, 0x3858,
+ 0xfbe1, 0x43af,
+ 0xfbe2, 0x3f6c,
+ 0xfbe3, 0x3d85,
+ 0xfbe4, 0x4396,
+ 0xfbe5, 0x39a6,
+ 0xfbe6, 0x3f7d,
+ 0xfbe7, 0x3fbf,
+ 0xfbe8, 0x40c8,
+ 0xfbe9, 0x3f5f,
+ 0xfbea, 0x3f2b,
+ 0xfbeb, 0x3d72,
+ 0xfbec, 0x40cf,
+ 0xfbed, 0x3a05,
+ 0xfbee, 0x3d82,
+ 0xfbef, 0x40dc,
+ 0xfbf0, 0x3d65,
+ 0xfbf1, 0x40d4,
+ 0xfbf2, 0x40da,
+ 0xfbf3, 0x3f2d,
+ 0xfbf4, 0x0595,
+ 0xfbf5, 0x3d81,
+ 0xfbf6, 0x40f1,
+ 0xfbf7, 0x06f5,
+ 0xfbf8, 0x40f8,
+ 0xfbf9, 0x40fb,
+ 0xfbfa, 0x3f41,
+ 0xfbfb, 0x4118,
+ 0xfbfc, 0x3d89,
+ 0xfbfd, 0x3f5c,
+ 0xfbfe, 0x3d67,
+ 0xfc40, 0x3f0e,
+ 0xfc41, 0x3f13,
+ 0xfc42, 0x4122,
+ 0xfc43, 0x3fca,
+ 0xfc44, 0x4129,
+ 0xfc45, 0x3f0c,
+ 0xfc46, 0x3f0b,
+ 0xfc47, 0x3f61,
+ 0xfc48, 0x3d8a,
+ 0xfc49, 0x3f2e,
+ 0xfc4a, 0x1971,
+ 0xfc4b, 0x4135,
+ 0xfc4c, 0x3a2b,
+ 0xfc4d, 0x3f6b,
+ 0xfc4e, 0x3ba5,
+ 0xfc4f, 0x4044,
+ 0xfc50, 0x4255,
+ 0xfc51, 0x3737,
+ 0xfc52, 0x3f25,
+ 0xfc53, 0x3739,
+ 0xfc54, 0x3a30,
+ 0xfc55, 0x4143,
+ 0xfc56, 0x40c4,
+ 0xfc57, 0x3d64,
+ 0xfc58, 0x3fbe,
+ 0xfc59, 0x3fa6,
+ 0xfc5a, 0x402c,
+ 0xfc5b, 0x4157,
+ 0xfc5c, 0x3f9f,
+ 0xfc5d, 0x2b40,
+ 0xfc5e, 0x3fa7,
+ 0xfc5f, 0x4005,
+ 0xfc60, 0x4001,
+ 0xfc61, 0x1c9b,
+ 0xfc62, 0x3d84,
+ 0xfc63, 0x0a95,
+ 0xfc64, 0x416c,
+ 0xfc65, 0x4009,
+ 0xfc66, 0x3d75,
+ 0xfc67, 0x3adc,
+ 0xfc68, 0x3fa8,
+ 0xfc69, 0x3f37,
+ 0xfc6a, 0x4174,
+ 0xfc6b, 0x4006,
+ 0xfc6c, 0x4002,
+ 0xfc6d, 0x3fba,
+ 0xfc6e, 0x3fc0,
+ 0xfc6f, 0x12b0,
+ 0xfc70, 0x3fbd,
+ 0xfc71, 0x4173,
+ 0xfc72, 0x4186,
+ 0xfc73, 0x3a54,
+ 0xfc74, 0x3fc5,
+ 0xfc75, 0x4259,
+ 0xfc76, 0x3fc2,
+ 0xfc77, 0x3f15,
+ 0xfc78, 0x3f50,
+ 0xfc79, 0x3f86,
+ 0xfc7a, 0x3fc1,
+ 0xfc7b, 0x418c,
+ 0xfc7c, 0x3fc7,
+ 0xfc7d, 0x3f16,
+ 0xfc7e, 0x418e,
+ 0xfca1, 0x3f4b,
+ 0xfca2, 0x419d,
+ 0xfca3, 0x115f,
+ 0xfca4, 0x3fc4,
+ 0xfca5, 0x3384,
+ 0xfca6, 0x3d99,
+ 0xfca7, 0x41b9,
+ 0xfca8, 0x3a89,
+ 0xfca9, 0x41b7,
+ 0xfcaa, 0x3d8b,
+ 0xfcab, 0x3d66,
+ 0xfcac, 0x03e2,
+ 0xfcad, 0x3d6a,
+ 0xfcae, 0x3d7a,
+ 0xfcaf, 0x41e3,
+ 0xfcb0, 0x0619,
+ 0xfcb1, 0x3996,
+ 0xfcb2, 0x3fc8,
+ 0xfcb3, 0x3a9e,
+ 0xfcb4, 0x3f38,
+ 0xfcb5, 0x3d80,
+ 0xfcb6, 0x41de,
+ 0xfcb8, 0x42eb,
+ 0xfcb9, 0x3d86,
+ 0xfcba, 0x41db,
+ 0xfcbb, 0x3f3e,
+ 0xfcbc, 0x4056,
+ 0xfcbd, 0x41d9,
+ 0xfcbe, 0x3ff6,
+ 0xfcbf, 0x3f5d,
+ 0xfcc0, 0x3d74,
+ 0xfcc1, 0x41e8,
+ 0xfcc2, 0x41c7,
+ 0xfcc3, 0x3d91,
+ 0xfcc4, 0x3b4b,
+ 0xfcc5, 0x3d42,
+ 0xfcc6, 0x3aad,
+ 0xfcc7, 0x3aa5,
+ 0xfcc8, 0x41f2,
+ 0xfcc9, 0x3f4c,
+ 0xfcca, 0x41f8,
+ 0xfccb, 0x3f6e,
+ 0xfccc, 0x3f79,
+ 0xfccd, 0x3f8d,
+ 0xfcce, 0x4003,
+ 0xfccf, 0x3f91,
+ 0xfcd0, 0x3ac3,
+ 0xfcd1, 0x091a,
+ 0xfcd2, 0x4234,
+ 0xfcd3, 0x3ffb,
+ 0xfcd4, 0x4240,
+ 0xfcd6, 0x3ffd,
+ 0xfcd7, 0x3f78,
+ 0xfcd8, 0x3c75,
+ 0xfcd9, 0x3c73,
+ 0xfcda, 0x38a5,
+ 0xfcdb, 0x43f9,
+ 0xfcdc, 0x3cfe,
+ 0xfcdd, 0x4257,
+ 0xfcde, 0x4233,
+ 0xfcdf, 0x3d69,
+ 0xfce0, 0x3c7e,
+ 0xfce1, 0x3d6f,
+ 0xfce2, 0x4000,
+ 0xfce3, 0x3dc0,
+ 0xfce4, 0x4004,
+ 0xfce5, 0x0e72,
+ 0xfce6, 0x3938,
+ 0xfce7, 0x3fa4,
+ 0xfce8, 0x295a,
+ 0xfce9, 0x4273,
+ 0xfcea, 0x3ac9,
+ 0xfceb, 0x427d,
+ 0xfcec, 0x3aca,
+ 0xfced, 0x3fb2,
+ 0xfcee, 0x3fb6,
+ 0xfcef, 0x3f97,
+ 0xfcf0, 0x3f9a,
+ 0xfcf1, 0x428b,
+ 0xfcf2, 0x43fa,
+ 0xfcf3, 0x428a,
+ 0xfcf4, 0x3f51,
+ 0xfcf5, 0x3f98,
+ 0xfcf6, 0x41a3,
+ 0xfcf7, 0x3d5c,
+ 0xfcf8, 0x3f63,
+ 0xfcf9, 0x4290,
+ 0xfcfa, 0x1f94,
+ 0xfcfb, 0x42c6,
+ 0xfcfc, 0x42a2,
+ 0xfcfd, 0x3ffa,
+ 0xfcfe, 0x3f9d,
+ 0xfd40, 0x3ffe,
+ 0xfd41, 0x3f9b,
+ 0xfd42, 0x3fdf,
+ 0xfd43, 0x3fe6,
+ 0xfd44, 0x3fde,
+ 0xfd45, 0x42b7,
+ 0xfd46, 0x3ff4,
+ 0xfd47, 0x42b8,
+ 0xfd48, 0x3feb,
+ 0xfd49, 0x42bf,
+ 0xfd4a, 0x3d71,
+ 0xfd4b, 0x3f4f,
+ 0xfd4c, 0x42c5,
+ 0xfd4d, 0x42d5,
+ 0xfd4e, 0x42d0,
+ 0xfd4f, 0x42d8,
+ 0xfd50, 0x3f55,
+ 0xfd51, 0x3fe8,
+ 0xfd52, 0x3ff3,
+ 0xfd53, 0x42df,
+ 0xfd54, 0x3fd3,
+ 0xfd55, 0x3e73,
+ 0xfd56, 0x3f95,
+ 0xfd57, 0x42ee,
+ 0xfd58, 0x42f4,
+ 0xfd59, 0x3f8c,
+ 0xfd5a, 0x3fcf,
+ 0xfd5b, 0x42ec,
+ 0xfd5c, 0x3fd4,
+ 0xfd5d, 0x42f0,
+ 0xfd5e, 0x07c2,
+ 0xfd5f, 0x0955,
+ 0xfd60, 0x42fe,
+ 0xfd61, 0x4301,
+ 0xfd62, 0x3ccd,
+ 0xfd63, 0x4307,
+ 0xfd64, 0x43fb,
+ 0xfd65, 0x3fda,
+ 0xfd66, 0x3f8b,
+ 0xfd67, 0x3733,
+ 0xfd68, 0x3f8a,
+ 0xfd69, 0x3741,
+ 0xfd6a, 0x3740,
+ 0xfd6b, 0x3742,
+ 0xfd6c, 0x3f93,
+ 0xfd6d, 0x3f8f,
+ 0xfd6e, 0x3e70,
+ 0xfd6f, 0x42c9,
+ 0xfd70, 0x3e72,
+ 0xfd71, 0x3fa9,
+ 0xfd72, 0x42cd,
+ 0xfd73, 0x43d2,
+ 0xfd74, 0x3f8e,
+ 0xfd75, 0x3f77,
+ 0xfd76, 0x3d6e,
+ 0xfd77, 0x0d0a,
+ 0xfd78, 0x3f11,
+ 0xfd79, 0x3752,
+ 0xfd7a, 0x3f14,
+ 0xfd7b, 0x3f18,
+ 0xfd7c, 0x3f53,
+ 0xfd7d, 0x3f1f,
+ 0xfd7e, 0x3f1c,
+ 0xfda1, 0x3fb8,
+ 0xfda2, 0x339d,
+ 0xfda3, 0x3b3f,
+ 0xfda4, 0x3f52,
+ 0xfda5, 0x3f1a,
+ 0xfda6, 0x3f1d,
+ 0xfda7, 0x375c,
+ 0xfda8, 0x3885,
+ 0xfda9, 0x3761,
+ 0xfdaa, 0x3fd7,
+ 0xfdab, 0x3fd6,
+ 0xfdac, 0x3fd9,
+ 0xfdad, 0x3fd8,
+ 0xfdae, 0x3fdd,
+ 0xfdaf, 0x3e93,
+ 0xfdb0, 0x3769,
+ 0xfdb1, 0x376e,
+ 0xfdb2, 0x3b4c,
+ 0xfdb3, 0x3774,
+ 0xfdb4, 0x377f,
+ 0xfdb5, 0x377b,
+ 0xfdb6, 0x3782,
+ 0xfdb7, 0x3b4f,
+ 0xfdb8, 0x3792,
+ 0xfdb9, 0x3fe3,
+ 0xfdba, 0x3fdc,
+ 0xfdbb, 0x3fdb,
+ 0xfdbc, 0x3fe5,
+ 0xfdbd, 0x3b75,
+ 0xfdbe, 0x37a2,
+ 0xfdbf, 0x3fe2,
+ 0xfdc0, 0x3fe7,
+ 0xfdc1, 0x3e6d,
+ 0xfdc2, 0x0d2a,
+ 0xfdc3, 0x3e79,
+ 0xfdc4, 0x3e76,
+ 0xfdc5, 0x379f,
+ 0xfdc6, 0x3fee,
+ 0xfdc7, 0x42d4,
+ 0xfdc8, 0x3d94,
+ 0xfdc9, 0x3d61,
+ 0xfdca, 0x3fe1,
+ 0xfdcb, 0x375e,
+ 0xfdcc, 0x3b7a,
+ 0xfdcd, 0x380b,
+ 0xfdce, 0x3fec,
+ 0xfdcf, 0x3fef,
+ 0xfdd0, 0x2e45,
+ 0xfdd1, 0x3ffc,
+ 0xfdd2, 0x3fed,
+ 0xfdd3, 0x380d,
+ 0xfdd4, 0x3fe4,
+ 0xfdd5, 0x3f92,
+ 0xfdd6, 0x3fae,
+ 0xfdd7, 0x3811,
+ 0xfdd8, 0x3f7a,
+ 0xfdd9, 0x3b8b,
+ 0xfdda, 0x3f5a,
+ 0xfddb, 0x3816,
+ 0xfddc, 0x3fa2,
+ 0xfddd, 0x3b8e,
+ 0xfdde, 0x381c,
+ 0xfddf, 0x2054,
+ 0xfde0, 0x381f,
+ 0xfde1, 0x3fa0,
+ 0xfde2, 0x43fc,
+ 0xfde3, 0x3e16,
+ 0xfde4, 0x3b94,
+ 0xfde5, 0x3f7c,
+ 0xfde6, 0x4007,
+ 0xfde7, 0x3f7b,
+ 0xfde8, 0x3d73,
+ 0xfde9, 0x3e77,
+ 0xfdea, 0x3d92,
+ 0xfdeb, 0x3fa1,
+ 0xfdec, 0x37c1,
+ 0xfded, 0x37d3,
+ 0xfdee, 0x3e7a,
+ 0xfdef, 0x3f59,
+ 0xfdf0, 0x3c55,
+ 0xfdf1, 0x3ff8,
+ 0xfdf2, 0x3ff5,
+ 0xfdf3, 0x3c4c,
+ 0xfdf4, 0x3d8c,
+ 0xfdf5, 0x3fa3,
+ 0xfdf6, 0x37c0,
+ 0xfdf7, 0x3f54,
+ 0xfdf8, 0x3800,
+ 0xfdf9, 0x3b7f,
+ 0xfdfa, 0x3f9e,
+ 0xfdfb, 0x3822,
+ 0xfdfc, 0x3fe9,
+ 0xfdfd, 0x3823,
+ 0xfdfe, 0x3fe0,
+ 0xfe40, 0x3d93,
+ 0xfe41, 0x3ff9,
+ 0xfe42, 0x3827,
+ 0xfe43, 0x3fa5,
+ 0xfe44, 0x3ff0,
+ 0xfe45, 0x3836,
+ 0xfe46, 0x3f99,
+ 0xfe47, 0x3ff2,
+ 0xfe48, 0x3d8d,
+ 0xfe49, 0x43e6,
+ 0xfe4a, 0x3522,
+ 0xfe4b, 0x3ff1,
+ 0xfe4c, 0x3f9c,
+ 0xfe4d, 0x3fb1,
+ 0xfe4e, 0x3f96,
+ 0xfe4f, 0x3e6f,
+ 0xfe50, 0x3f69,
+ 0xfe51, 0x3ff7,
+ 0xfe52, 0x3f82,
+ 0xfe53, 0x3f88,
+ 0xfe54, 0x3f85,
+ 0xfe55, 0x3f83,
+ 0xfe56, 0x3f7f,
+ 0xfe57, 0x3f89,
+ 0xfe58, 0x3bb5,
+ 0xfe59, 0x3862,
+ 0xfe5a, 0x3f87,
+ 0xfe5b, 0x3f31,
+ 0xfe5c, 0x3815,
+ 0xfe5d, 0x387e,
+ 0xfe5e, 0x3f49,
+ 0xfe5f, 0x3f48,
+ 0xfe60, 0x3f47,
+ 0xfe61, 0x3f45,
+ 0xfe62, 0x43eb,
+ 0xfe63, 0x3882,
+ 0xfe64, 0x3f6f,
+ 0xfe65, 0x3f4e,
+ 0xfe66, 0x3bc8,
+ 0xfe67, 0x43fd,
+ 0xfe68, 0x3d6b,
+ 0xfe6a, 0x43fe,
+ 0xfe6b, 0x3fcb,
+ 0xfe6c, 0x3dd2,
+ 0xfe6d, 0x3879,
+ 0xfe6e, 0x3f10,
+ 0xfe6f, 0x382e,
+ 0xfe70, 0x388b,
+ 0xfe71, 0x3c60,
+ 0xfe72, 0x2a9f,
+ 0xfe73, 0x3c61,
+ 0xfe74, 0x3893,
+ 0xfe75, 0x3e74,
+ 0xfe76, 0x3fac,
+ 0xfe77, 0x3f81,
+ 0xfe78, 0x3bcd,
+ 0xfe79, 0x3bd4,
+ 0xfe7a, 0x3bd3,
+ 0xfe7b, 0x3fcc,
+ 0xfe7c, 0x3fd1,
+ 0xfe7d, 0x3f3d,
+ 0xfe7e, 0x3f4a,
+ 0xfea1, 0x2352,
+ 0xfea2, 0x38ad,
+ 0xfea3, 0x3f46,
+ 0xfea4, 0x38b5,
+ 0xfea5, 0x3f0d,
+ 0xfea6, 0x3fb3,
+ 0xfea7, 0x38c0,
+ 0xfea8, 0x3e2f,
+ 0xfea9, 0x38cf,
+ 0xfeaa, 0x38d5,
+ 0xfeab, 0x3f33,
+ 0xfeac, 0x3d95,
+ 0xfead, 0x3f35,
+ 0xfeae, 0x38d7,
+ 0xfeaf, 0x3f2f,
+ 0xfeb0, 0x38e0,
+ 0xfeb1, 0x3c02,
+ 0xfeb2, 0x3f72,
+ 0xfeb3, 0x3f70,
+ 0xfeb4, 0x3d96,
+ 0xfeb5, 0x38e6,
+ 0xfeb7, 0x4035,
+ 0xfeb8, 0x3f73,
+ 0xfeb9, 0x38f0,
+ 0xfeba, 0x3c0b,
+ 0xfebb, 0x38f7,
+ 0xfebc, 0x37aa,
+ 0xfebd, 0x43ff,
+ 0xfebe, 0x38fa,
+ 0xfebf, 0x3c11,
+ 0xfec0, 0x3f34,
+ 0xfec1, 0x3fb9,
+ 0xfec2, 0x3c12,
+ 0xfec3, 0x400a,
+ 0xfec4, 0x3d77,
+ 0xfec5, 0x3f42,
+ 0xfec6, 0x3900,
+ 0xfec7, 0x3902,
+ 0xfec8, 0x3f74,
+ 0xfec9, 0x3d97,
+ 0xfeca, 0x3faa,
+ 0xfecb, 0x3f19,
+ 0xfecc, 0x3f1b,
+ 0xfecd, 0x390e,
+ 0xfece, 0x3909,
+ 0xfecf, 0x390b,
+ 0xfed0, 0x3f12,
+ 0xfed1, 0x3f17,
+ 0xfed2, 0x3fb7,
+ 0xfed3, 0x3f20,
+ 0xfed4, 0x3fbb,
+ 0xfed5, 0x3f3c,
+ 0xfed6, 0x3fad,
+ 0xfed7, 0x3919,
+ 0xfed8, 0x3f56,
+ 0xfed9, 0x3f71,
+ 0xfeda, 0x3fb4,
+ 0xfedb, 0x391c,
+ 0xfedc, 0x3f1e,
+ 0xfedd, 0x3f3a,
+ 0xfede, 0x391b,
+ 0xfedf, 0x3d87,
+ 0xfee0, 0x3c3a,
+ 0xfee1, 0x3f22,
+ 0xfee2, 0x3e71,
+ 0xfee3, 0x3c39,
+ 0xfee4, 0x3d7e,
+ 0xfee5, 0x4124,
+ 0xfee6, 0x3f3b,
+ 0xfee7, 0x3e6e,
+ 0xfee8, 0x3fab,
+ 0xfee9, 0x3925,
+ 0xfeea, 0x3f30,
+ 0xfeeb, 0x3929,
+ 0xfeec, 0x3f84,
+ 0xfeed, 0x3f0f,
+ 0xfeee, 0x3f76,
+ 0xfeef, 0x3f94,
+ 0xfef0, 0x3932,
+ 0xfef1, 0x3f27,
+ 0xfef2, 0x3933,
+ 0xfef3, 0x3f75,
+ 0xfef4, 0x3937,
+ 0xfef5, 0x3d78,
+ 0xfef6, 0x3f21,
+ 0xfef7, 0x3f90,
+ 0xfef8, 0x3940,
+ 0xfef9, 0x3d7f,
+ 0xfefa, 0x394a,
+ 0xfefb, 0x3f80,
+ 0xfefc, 0x3f23,
+ 0xfefd, 0x3950,
+ 0xfefe, 0x3f7e,
+ 0xa14b, 0x354e,
+ 0xa15a, 0x35af,
+ 0xa15c, 0x35b1,
+ 0xa15d, 0x0082,
+ 0xa161, 0x0086,
+ 0xa165, 0x008a,
+ 0xa169, 0x008e,
+ 0xa16d, 0x0092,
+ 0xa171, 0x0096,
+ 0xa175, 0x009a,
+ 0xa179, 0x009e,
+ 0xa1e3, 0x354f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKdlaB5VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKdlaB5VMap2, 1035
+};
+
+static Gushort cns13HKdlbB5HMap2[1816] = {
+ 0x0000, 0x0000,
+ 0x8e40, 0x3d77,
+ 0x8e41, 0x3d6c,
+ 0x8e42, 0x3f59,
+ 0x8e43, 0x3919,
+ 0x8e44, 0x3e70,
+ 0x8e45, 0x3752,
+ 0x8e46, 0x38af,
+ 0x8e47, 0x3786,
+ 0x8e48, 0x3f1b,
+ 0x8e49, 0x3d5c,
+ 0x8e4a, 0x3f99,
+ 0x8e4b, 0x3fe8,
+ 0x8e4c, 0x388b,
+ 0x8e4d, 0x38dc,
+ 0x8e4e, 0x3faa,
+ 0x8e4f, 0x42c8,
+ 0x8e50, 0x3741,
+ 0x8e51, 0x3d7f,
+ 0x8e52, 0x42ec,
+ 0x8e53, 0x3f93,
+ 0x8e54, 0x389a,
+ 0x8e55, 0x3879,
+ 0x8e56, 0x373a,
+ 0x8e57, 0x42d0,
+ 0x8e58, 0x3e6f,
+ 0x8e59, 0x3f18,
+ 0x8e5a, 0x36e8,
+ 0x8e5b, 0x3739,
+ 0x8e5c, 0x3e99,
+ 0x8e5d, 0x3b4c,
+ 0x8e5e, 0x3dd2,
+ 0x8e5f, 0x3fa9,
+ 0x8e60, 0x3fac,
+ 0x8e61, 0x3fcb,
+ 0x8e62, 0x3733,
+ 0x8e63, 0x3f9f,
+ 0x8e64, 0x40da,
+ 0x8e65, 0x3f29,
+ 0x8e66, 0x3c66,
+ 0x8e67, 0x4222,
+ 0x8e68, 0x40ae,
+ 0x8e69, 0x3d7a,
+ 0x8e6a, 0x3f8d,
+ 0x8e6b, 0x39d0,
+ 0x8e6c, 0x4264,
+ 0x8e6d, 0x3d82,
+ 0x8e6e, 0x4203,
+ 0x8e6f, 0x41db,
+ 0x8e70, 0x3fde,
+ 0x8e71, 0x3ff4,
+ 0x8e72, 0x4004,
+ 0x8e73, 0x3f66,
+ 0x8e74, 0x3f9b,
+ 0x8e75, 0x3d66,
+ 0x8e76, 0x404b,
+ 0x8e77, 0x3fdf,
+ 0x8e78, 0x40fb,
+ 0x8e79, 0x4012,
+ 0x8e7a, 0x3fe6,
+ 0x8e7b, 0x42eb,
+ 0x8e7c, 0x4124,
+ 0x8e7d, 0x3d7c,
+ 0x8e7e, 0x3d69,
+ 0x8ea1, 0x3ffe,
+ 0x8ea2, 0x3d72,
+ 0x8ea3, 0x3fc6,
+ 0x8ea4, 0x3cfe,
+ 0x8ea5, 0x43f9,
+ 0x8ea6, 0x3d42,
+ 0x8ea7, 0x3f15,
+ 0x8ea8, 0x3fce,
+ 0x8ea9, 0x428b,
+ 0x8eaa, 0x40cf,
+ 0x8eab, 0x43f6,
+ 0x8eac, 0x4005,
+ 0x8ead, 0x3f2d,
+ 0x8eae, 0x4161,
+ 0x8eaf, 0x3f2c,
+ 0x8eb0, 0x3aca,
+ 0x8eb1, 0x3d6a,
+ 0x8eb2, 0x4063,
+ 0x8eb3, 0x3fc5,
+ 0x8eb4, 0x39e7,
+ 0x8eb5, 0x3f2a,
+ 0x8eb6, 0x4060,
+ 0x8eb7, 0x4273,
+ 0x8eb8, 0x4221,
+ 0x8eb9, 0x40a2,
+ 0x8eba, 0x3f68,
+ 0x8ebb, 0x40a1,
+ 0x8ebc, 0x3f57,
+ 0x8ebd, 0x3f70,
+ 0x8ebe, 0x3fb7,
+ 0x8ebf, 0x3746,
+ 0x8ec0, 0x3fab,
+ 0x8ec1, 0x3ff2,
+ 0x8ec2, 0x3f8c,
+ 0x8ec3, 0x3f88,
+ 0x8ec4, 0x37d3,
+ 0x8ec5, 0x3b74,
+ 0x8ec7, 0x42f4,
+ 0x8ec8, 0x3c4c,
+ 0x8ec9, 0x3b7a,
+ 0x8eca, 0x3885,
+ 0x8ecb, 0x3737,
+ 0x8ecc, 0x3fdb,
+ 0x8ecd, 0x3f1d,
+ 0x8ece, 0x3fec,
+ 0x8ecf, 0x3fe5,
+ 0x8ed0, 0x375e,
+ 0x8ed1, 0x3ff7,
+ 0x8ed2, 0x3813,
+ 0x8ed3, 0x3fe3,
+ 0x8ed4, 0x3f1a,
+ 0x8ed5, 0x38e6,
+ 0x8ed6, 0x3fdc,
+ 0x8ed7, 0x377f,
+ 0x8ed8, 0x3d87,
+ 0x8ed9, 0x3bd3,
+ 0x8eda, 0x3d78,
+ 0x8edb, 0x3bd4,
+ 0x8edc, 0x3f96,
+ 0x8edd, 0x3f95,
+ 0x8ede, 0x3d8c,
+ 0x8edf, 0x3937,
+ 0x8ee0, 0x3f1c,
+ 0x8ee1, 0x3932,
+ 0x8ee2, 0x3d6b,
+ 0x8ee3, 0x3800,
+ 0x8ee4, 0x3ff8,
+ 0x8ee5, 0x3c3a,
+ 0x8ee6, 0x3f42,
+ 0x8ee7, 0x43fd,
+ 0x8ee8, 0x3fb1,
+ 0x8ee9, 0x3792,
+ 0x8eea, 0x3f94,
+ 0x8eeb, 0x3f1e,
+ 0x8eec, 0x400a,
+ 0x8eed, 0x3882,
+ 0x8eee, 0x3f9c,
+ 0x8eef, 0x3d61,
+ 0x8ef0, 0x3f22,
+ 0x8ef1, 0x3fe9,
+ 0x8ef2, 0x3d92,
+ 0x8ef3, 0x377f,
+ 0x8ef4, 0x3b94,
+ 0x8ef5, 0x376e,
+ 0x8ef6, 0x4301,
+ 0x8ef7, 0x3f3a,
+ 0x8ef8, 0x3863,
+ 0x8ef9, 0x3ff1,
+ 0x8efa, 0x42fe,
+ 0x8efb, 0x3bfc,
+ 0x8efc, 0x3f45,
+ 0x8efd, 0x379f,
+ 0x8efe, 0x376b,
+ 0x8f40, 0x3f14,
+ 0x8f41, 0x3f47,
+ 0x8f42, 0x3862,
+ 0x8f43, 0x3769,
+ 0x8f44, 0x3c12,
+ 0x8f45, 0x3f49,
+ 0x8f46, 0x381f,
+ 0x8f47, 0x3929,
+ 0x8f48, 0x3f56,
+ 0x8f49, 0x3f34,
+ 0x8f4a, 0x3fdd,
+ 0x8f4b, 0x38fa,
+ 0x8f4c, 0x3f7b,
+ 0x8f4d, 0x3c11,
+ 0x8f4e, 0x3f7c,
+ 0x8f4f, 0x43ff,
+ 0x8f50, 0x3e73,
+ 0x8f51, 0x3f71,
+ 0x8f52, 0x3925,
+ 0x8f53, 0x3c55,
+ 0x8f54, 0x38b5,
+ 0x8f55, 0x3f5a,
+ 0x8f56, 0x3816,
+ 0x8f57, 0x3e6d,
+ 0x8f58, 0x3782,
+ 0x8f59, 0x3f11,
+ 0x8f5a, 0x3b8b,
+ 0x8f5b, 0x37c0,
+ 0x8f5c, 0x3815,
+ 0x8f5d, 0x383b,
+ 0x8f5e, 0x3d73,
+ 0x8f5f, 0x3d6e,
+ 0x8f60, 0x3f8a,
+ 0x8f61, 0x3f3e,
+ 0x8f62, 0x4234,
+ 0x8f63, 0x41e3,
+ 0x8f64, 0x3fc7,
+ 0x8f65, 0x3ff3,
+ 0x8f66, 0x4003,
+ 0x8f67, 0x4032,
+ 0x8f68, 0x3f6e,
+ 0x8f69, 0x41a3,
+ 0x8f6a, 0x4006,
+ 0x8f6b, 0x3f2b,
+ 0x8f6c, 0x3f7d,
+ 0x8f6d, 0x3c73,
+ 0x8f6e, 0x3f16,
+ 0x8f6f, 0x4002,
+ 0x8f70, 0x4056,
+ 0x8f71, 0x3fba,
+ 0x8f72, 0x3f6b,
+ 0x8f73, 0x3f91,
+ 0x8f74, 0x3fbe,
+ 0x8f75, 0x405a,
+ 0x8f76, 0x3adf,
+ 0x8f77, 0x3e41,
+ 0x8f78, 0x3d67,
+ 0x8f79, 0x3f60,
+ 0x8f7a, 0x41e8,
+ 0x8f7b, 0x3fc0,
+ 0x8f7c, 0x3d83,
+ 0x8f7d, 0x4173,
+ 0x8f7e, 0x3f5c,
+ 0x8fa1, 0x3f32,
+ 0x8fa2, 0x3f3f,
+ 0x8fa3, 0x3d63,
+ 0x8fa4, 0x4146,
+ 0x8fa5, 0x3fcd,
+ 0x8fa6, 0x3d79,
+ 0x8fa7, 0x3f28,
+ 0x8fa8, 0x3fc1,
+ 0x8fa9, 0x40bc,
+ 0x8faa, 0x3d71,
+ 0x8fab, 0x3f37,
+ 0x8fac, 0x42d8,
+ 0x8fad, 0x3feb,
+ 0x8fae, 0x4241,
+ 0x8faf, 0x3a30,
+ 0x8fb0, 0x39cd,
+ 0x8fb1, 0x42bf,
+ 0x8fb2, 0x420e,
+ 0x8fb3, 0x3f0a,
+ 0x8fb4, 0x39cc,
+ 0x8fb5, 0x4044,
+ 0x8fb6, 0x4098,
+ 0x8fb7, 0x418c,
+ 0x8fb8, 0x3d64,
+ 0x8fb9, 0x3f44,
+ 0x8fba, 0x404f,
+ 0x8fbb, 0x42d5,
+ 0x8fbc, 0x4290,
+ 0x8fbd, 0x4000,
+ 0x8fbe, 0x3a89,
+ 0x8fbf, 0x416c,
+ 0x8fc0, 0x40c4,
+ 0x8fc1, 0x404d,
+ 0x8fc2, 0x3dc0,
+ 0x8fc3, 0x3f50,
+ 0x8fc4, 0x4009,
+ 0x8fc5, 0x3faf,
+ 0x8fc6, 0x3f86,
+ 0x8fc7, 0x4093,
+ 0x8fc8, 0x3aad,
+ 0x8fc9, 0x3f38,
+ 0x8fca, 0x3d75,
+ 0x8fcb, 0x3f39,
+ 0x8fcc, 0x42cd,
+ 0x8fcd, 0x3f78,
+ 0x8fce, 0x3f9d,
+ 0x8fcf, 0x4090,
+ 0x8fd0, 0x3d80,
+ 0x8fd1, 0x3f2e,
+ 0x8fd2, 0x38b6,
+ 0x8fd3, 0x41b9,
+ 0x8fd4, 0x3d8a,
+ 0x8fd5, 0x3f24,
+ 0x8fd6, 0x3a9e,
+ 0x8fd7, 0x3adc,
+ 0x8fd8, 0x3d65,
+ 0x8fd9, 0x4085,
+ 0x8fda, 0x3f51,
+ 0x8fdb, 0x43fa,
+ 0x8fdc, 0x3f63,
+ 0x8fdd, 0x4178,
+ 0x8fde, 0x41b7,
+ 0x8fdf, 0x3e72,
+ 0x8fe0, 0x41d9,
+ 0x8fe1, 0x418e,
+ 0x8fe2, 0x3d76,
+ 0x8fe3, 0x42d4,
+ 0x8fe4, 0x42a2,
+ 0x8fe5, 0x4257,
+ 0x8fe6, 0x3f0c,
+ 0x8fe7, 0x3996,
+ 0x8fe8, 0x4255,
+ 0x8fe9, 0x40b7,
+ 0x8fea, 0x3f9a,
+ 0x8feb, 0x3fca,
+ 0x8fec, 0x3f5e,
+ 0x8fed, 0x3d85,
+ 0x8fee, 0x3ffa,
+ 0x8fef, 0x3fb6,
+ 0x8ff0, 0x3ac3,
+ 0x8ff1, 0x3fc8,
+ 0x8ff2, 0x3f4b,
+ 0x8ff3, 0x40f1,
+ 0x8ff4, 0x4034,
+ 0x8ff5, 0x3f5b,
+ 0x8ff6, 0x42c9,
+ 0x8ff7, 0x3c75,
+ 0x8ff8, 0x3f79,
+ 0x8ff9, 0x42c6,
+ 0x8ffa, 0x38cf,
+ 0x8ffb, 0x41f4,
+ 0x8ffc, 0x3f41,
+ 0x8ffd, 0x390b,
+ 0x8ffe, 0x38e0,
+ 0x9040, 0x427d,
+ 0x9041, 0x42f0,
+ 0x9042, 0x3f27,
+ 0x9043, 0x3822,
+ 0x9044, 0x37d8,
+ 0x9045, 0x37a2,
+ 0x9046, 0x3f73,
+ 0x9047, 0x42b8,
+ 0x9048, 0x3f19,
+ 0x9049, 0x42b7,
+ 0x904a, 0x3d8b,
+ 0x904b, 0x4129,
+ 0x904c, 0x40d4,
+ 0x904d, 0x38f5,
+ 0x904e, 0x4143,
+ 0x904f, 0x4022,
+ 0x9050, 0x41d0,
+ 0x9051, 0x41f5,
+ 0x9052, 0x3f43,
+ 0x9053, 0x40c8,
+ 0x9054, 0x4096,
+ 0x9055, 0x405d,
+ 0x9056, 0x4174,
+ 0x9057, 0x413e,
+ 0x9058, 0x413b,
+ 0x9059, 0x39c4,
+ 0x905a, 0x3d89,
+ 0x905b, 0x4205,
+ 0x905c, 0x36eb,
+ 0x905d, 0x39c5,
+ 0x905e, 0x3d84,
+ 0x905f, 0x4054,
+ 0x9060, 0x193f,
+ 0x9061, 0x0619,
+ 0x9062, 0x0871,
+ 0x9063, 0x115f,
+ 0x9064, 0x3f53,
+ 0x9065, 0x3f1f,
+ 0x9066, 0x339d,
+ 0x9067, 0x3fb8,
+ 0x9068, 0x3b3f,
+ 0x9069, 0x3f52,
+ 0x906a, 0x3761,
+ 0x906b, 0x375c,
+ 0x906c, 0x3fd9,
+ 0x906d, 0x3fd7,
+ 0x906e, 0x3fd6,
+ 0x906f, 0x3e93,
+ 0x9070, 0x3774,
+ 0x9071, 0x377b,
+ 0x9072, 0x3b4f,
+ 0x9073, 0x4007,
+ 0x9074, 0x3fe2,
+ 0x9075, 0x3e79,
+ 0x9076, 0x3e76,
+ 0x9077, 0x3fe7,
+ 0x9078, 0x0d2a,
+ 0x9079, 0x3fee,
+ 0x907a, 0x3fe1,
+ 0x907b, 0x3e77,
+ 0x907c, 0x3fa3,
+ 0x907d, 0x3f54,
+ 0x907e, 0x37bc,
+ 0x90a1, 0x3e7a,
+ 0x90a2, 0x3fa1,
+ 0x90a3, 0x37c1,
+ 0x90a4, 0x3ff5,
+ 0x90a5, 0x3f9e,
+ 0x90a6, 0x3b7f,
+ 0x90a7, 0x380b,
+ 0x90a8, 0x3fef,
+ 0x90a9, 0x3ffc,
+ 0x90aa, 0x380d,
+ 0x90ab, 0x3fed,
+ 0x90ac, 0x3fe4,
+ 0x90ad, 0x3811,
+ 0x90ae, 0x3f7a,
+ 0x90af, 0x3fa2,
+ 0x90b0, 0x3b8e,
+ 0x90b1, 0x381c,
+ 0x90b2, 0x3fa0,
+ 0x90b3, 0x3fe0,
+ 0x90b4, 0x3d93,
+ 0x90b5, 0x3827,
+ 0x90b6, 0x3ff0,
+ 0x90b7, 0x3fa5,
+ 0x90b8, 0x3836,
+ 0x90b9, 0x3d8d,
+ 0x90ba, 0x3f69,
+ 0x90bb, 0x3f82,
+ 0x90bc, 0x3f85,
+ 0x90bd, 0x3f83,
+ 0x90be, 0x3f89,
+ 0x90bf, 0x3f7f,
+ 0x90c0, 0x3bb5,
+ 0x90c1, 0x3f87,
+ 0x90c2, 0x3f31,
+ 0x90c3, 0x3d94,
+ 0x90c4, 0x0230,
+ 0x90c5, 0x43fe,
+ 0x90c6, 0x3f10,
+ 0x90c7, 0x387e,
+ 0x90c8, 0x43eb,
+ 0x90c9, 0x3f6f,
+ 0x90ca, 0x3e9b,
+ 0x90cb, 0x3f4e,
+ 0x90cc, 0x3bc8,
+ 0x90cd, 0x1e29,
+ 0x90ce, 0x3f48,
+ 0x90cf, 0x382e,
+ 0x90d0, 0x3c60,
+ 0x90d1, 0x2a9f,
+ 0x90d2, 0x3893,
+ 0x90d3, 0x43f7,
+ 0x90d4, 0x3e74,
+ 0x90d5, 0x3bcd,
+ 0x90d6, 0x3ac9,
+ 0x90d7, 0x3fcc,
+ 0x90d8, 0x3fd1,
+ 0x90d9, 0x3f3d,
+ 0x90da, 0x3f4a,
+ 0x90db, 0x38ad,
+ 0x90dc, 0x2352,
+ 0x90dd, 0x3f46,
+ 0x90de, 0x38b2,
+ 0x90df, 0x3fb3,
+ 0x90e0, 0x3f0d,
+ 0x90e1, 0x38c0,
+ 0x90e2, 0x3e2f,
+ 0x90e3, 0x38d5,
+ 0x90e4, 0x3f35,
+ 0x90e5, 0x38d7,
+ 0x90e6, 0x3f2f,
+ 0x90e7, 0x3f33,
+ 0x90e8, 0x3d95,
+ 0x90e9, 0x3c02,
+ 0x90ea, 0x3f72,
+ 0x90eb, 0x3d96,
+ 0x90ec, 0x38e7,
+ 0x90ed, 0x4035,
+ 0x90ee, 0x3c0b,
+ 0x90ef, 0x38f0,
+ 0x90f0, 0x38f7,
+ 0x90f1, 0x3fb9,
+ 0x90f2, 0x3900,
+ 0x90f3, 0x3f74,
+ 0x90f4, 0x3909,
+ 0x90f5, 0x3f12,
+ 0x90f6, 0x3f17,
+ 0x90f7, 0x3f20,
+ 0x90f8, 0x3fbb,
+ 0x90f9, 0x3f3c,
+ 0x90fa, 0x3fb4,
+ 0x90fb, 0x3fad,
+ 0x90fc, 0x391a,
+ 0x90fd, 0x391c,
+ 0x90fe, 0x391b,
+ 0x9140, 0x3c39,
+ 0x9141, 0x3e71,
+ 0x9142, 0x3d7e,
+ 0x9143, 0x3f3b,
+ 0x9144, 0x3f30,
+ 0x9145, 0x3f84,
+ 0x9146, 0x43f8,
+ 0x9147, 0x3f0f,
+ 0x9148, 0x3f76,
+ 0x9149, 0x3933,
+ 0x914a, 0x3f75,
+ 0x914b, 0x3940,
+ 0x914c, 0x3f21,
+ 0x914d, 0x3f90,
+ 0x914e, 0x394a,
+ 0x914f, 0x3f80,
+ 0x9150, 0x3f23,
+ 0x9151, 0x3950,
+ 0x9152, 0x3d97,
+ 0x9153, 0x2e45,
+ 0x9154, 0x0570,
+ 0x9155, 0x3ead,
+ 0x9156, 0x3522,
+ 0x9157, 0x0be3,
+ 0x9158, 0x0595,
+ 0x9159, 0x0228,
+ 0x915a, 0x0a95,
+ 0x915b, 0x12b0,
+ 0x915c, 0x091a,
+ 0x915d, 0x43fc,
+ 0x915e, 0x3f92,
+ 0x915f, 0x3fae,
+ 0x9160, 0x07c2,
+ 0x9161, 0x0955,
+ 0x9162, 0x3785,
+ 0x9163, 0x3e6e,
+ 0x9164, 0x3d6d,
+ 0x9165, 0x3f62,
+ 0x9166, 0x39c8,
+ 0x9167, 0x3f65,
+ 0x9168, 0x393d,
+ 0x9169, 0x3f26,
+ 0x916a, 0x406d,
+ 0x916b, 0x3fd0,
+ 0x916c, 0x3f36,
+ 0x916d, 0x4086,
+ 0x916e, 0x3952,
+ 0x916f, 0x3fd2,
+ 0x9170, 0x3858,
+ 0x9171, 0x3ffb,
+ 0x9172, 0x3f67,
+ 0x9173, 0x3e81,
+ 0x9174, 0x3fc9,
+ 0x9175, 0x3fb5,
+ 0x9176, 0x3e7c,
+ 0x9177, 0x3e75,
+ 0x9178, 0x3c77,
+ 0x9179, 0x3b2e,
+ 0x917a, 0x3f4d,
+ 0x917b, 0x43af,
+ 0x917c, 0x3e67,
+ 0x917d, 0x40bd,
+ 0x917e, 0x3f6c,
+ 0x91a1, 0x39a6,
+ 0x91a2, 0x3948,
+ 0x91a3, 0x3fbf,
+ 0x91a4, 0x3f5f,
+ 0x91a5, 0x3a05,
+ 0x91a6, 0x06f5,
+ 0x91a7, 0x40f8,
+ 0x91a8, 0x41ad,
+ 0x91a9, 0x3f0e,
+ 0x91aa, 0x4122,
+ 0x91ab, 0x3f13,
+ 0x91ac, 0x3f0b,
+ 0x91ad, 0x4135,
+ 0x91ae, 0x3a2b,
+ 0x91af, 0x4138,
+ 0x91b0, 0x0226,
+ 0x91b1, 0x4149,
+ 0x91b2, 0x3ba5,
+ 0x91b3, 0x4001,
+ 0x91b4, 0x3fbd,
+ 0x91b5, 0x3fa8,
+ 0x91b6, 0x4186,
+ 0x91b7, 0x3a54,
+ 0x91b8, 0x3fc2,
+ 0x91b9, 0x4192,
+ 0x91ba, 0x4187,
+ 0x91bb, 0x3384,
+ 0x91bc, 0x3fc4,
+ 0x91bd, 0x3d99,
+ 0x91be, 0x3aaa,
+ 0x91bf, 0x41de,
+ 0x91c1, 0x3ff6,
+ 0x91c2, 0x3f5d,
+ 0x91c3, 0x41c7,
+ 0x91c4, 0x3d91,
+ 0x91c5, 0x3d74,
+ 0x91c6, 0x3f4c,
+ 0x91c7, 0x41f2,
+ 0x91c8, 0x3aa5,
+ 0x91c9, 0x3b4b,
+ 0x91ca, 0x3d86,
+ 0x91cb, 0x41f8,
+ 0x91cc, 0x4240,
+ 0x91cd, 0x3ffd,
+ 0x91ce, 0x3fa7,
+ 0x91cf, 0x4259,
+ 0x91d0, 0x0e72,
+ 0x91d1, 0x4262,
+ 0x91d2, 0x3c7e,
+ 0x91d3, 0x3938,
+ 0x91d4, 0x4233,
+ 0x91d5, 0x295a,
+ 0x91d7, 0x3f97,
+ 0x91d8, 0x3fb2,
+ 0x91d9, 0x428a,
+ 0x91da, 0x3f98,
+ 0x91db, 0x1f94,
+ 0x91dc, 0x3f40,
+ 0x91dd, 0x3f4f,
+ 0x91de, 0x3f8f,
+ 0x91df, 0x3d6f,
+ 0x91e0, 0x42df,
+ 0x91e1, 0x3f55,
+ 0x91e2, 0x3fd3,
+ 0x91e3, 0x42ee,
+ 0x91e4, 0x3fcf,
+ 0x91e5, 0x3fd4,
+ 0x91e6, 0x3e7d,
+ 0x91e7, 0x4307,
+ 0x91e8, 0x43fb,
+ 0x91e9, 0x3fda,
+ 0x91ea, 0x0d0a,
+ 0x91eb, 0x3f77,
+ 0x91ec, 0x3dbf,
+ 0x91ed, 0x402c,
+ 0x91ee, 0x3fa4,
+ 0x91ef, 0x3d6f,
+ 0x91f0, 0x3ccd,
+ 0x91f1, 0x3f64,
+ 0x91f2, 0x3f8b,
+ 0x91f3, 0x386f,
+ 0x91f4, 0x1971,
+ 0x91f5, 0x1c9b,
+ 0x91f6, 0x0745,
+ 0x91f7, 0x1d75,
+ 0x91f8, 0x3888,
+ 0x91f9, 0x3742,
+ 0x91fa, 0x2b40,
+ 0x91fb, 0x36e9,
+ 0x91fc, 0x37e0,
+ 0x91fd, 0x3e16,
+ 0x91fe, 0x387c,
+ 0x9240, 0x37aa,
+ 0x9241, 0x3f8e,
+ 0x9242, 0x40dc,
+ 0x9243, 0x3c7a,
+ 0x9244, 0x3fa6,
+ 0x9245, 0x405f,
+ 0x9246, 0x3c26,
+ 0x9247, 0x385e,
+ 0x9248, 0x3f25,
+ 0x9249, 0x4048,
+ 0x924a, 0x3d81,
+ 0x924b, 0x390e,
+ 0x924c, 0x4084,
+ 0x924d, 0x4118,
+ 0x924e, 0x4157,
+ 0x924f, 0x3902,
+ 0x9250, 0x389f,
+ 0x9251, 0x3ff9,
+ 0x9252, 0x3823,
+ 0x9253, 0x3871,
+ 0x9254, 0x36ea,
+ 0x9255, 0x376c,
+ 0x9256, 0x3740,
+ 0x9257, 0x37f4,
+ 0x9258, 0x42e0,
+ 0x9259, 0x425b,
+ 0x925a, 0x36ed,
+ 0x925b, 0x3b14,
+ 0x925c, 0x42c5,
+ 0x925d, 0x408b,
+ 0x925e, 0x38a5,
+ 0x925f, 0x416a,
+ 0x9260, 0x419d,
+ 0x9261, 0x4144,
+ 0x9262, 0x424f,
+ 0x9263, 0x3f61,
+ 0x9264, 0x3fd8,
+ 0x9265, 0x061c,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKdlbB5HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKdlbB5HMap2, 908
+};
+
+static Gushort cns13HKdlbB5VMap2[1840] = {
+ 0x0000, 0x0000,
+ 0x8e40, 0x3d77,
+ 0x8e41, 0x3d6c,
+ 0x8e42, 0x3f59,
+ 0x8e43, 0x3919,
+ 0x8e44, 0x3e70,
+ 0x8e45, 0x3752,
+ 0x8e46, 0x38af,
+ 0x8e47, 0x3786,
+ 0x8e48, 0x3f1b,
+ 0x8e49, 0x3d5c,
+ 0x8e4a, 0x3f99,
+ 0x8e4b, 0x3fe8,
+ 0x8e4c, 0x388b,
+ 0x8e4d, 0x38dc,
+ 0x8e4e, 0x3faa,
+ 0x8e4f, 0x42c8,
+ 0x8e50, 0x3741,
+ 0x8e51, 0x3d7f,
+ 0x8e52, 0x42ec,
+ 0x8e53, 0x3f93,
+ 0x8e54, 0x389a,
+ 0x8e55, 0x3879,
+ 0x8e56, 0x373a,
+ 0x8e57, 0x42d0,
+ 0x8e58, 0x3e6f,
+ 0x8e59, 0x3f18,
+ 0x8e5a, 0x36e8,
+ 0x8e5b, 0x3739,
+ 0x8e5c, 0x3e99,
+ 0x8e5d, 0x3b4c,
+ 0x8e5e, 0x3dd2,
+ 0x8e5f, 0x3fa9,
+ 0x8e60, 0x3fac,
+ 0x8e61, 0x3fcb,
+ 0x8e62, 0x3733,
+ 0x8e63, 0x3f9f,
+ 0x8e64, 0x40da,
+ 0x8e65, 0x3f29,
+ 0x8e66, 0x3c66,
+ 0x8e67, 0x4222,
+ 0x8e68, 0x40ae,
+ 0x8e69, 0x3d7a,
+ 0x8e6a, 0x3f8d,
+ 0x8e6b, 0x39d0,
+ 0x8e6c, 0x4264,
+ 0x8e6d, 0x3d82,
+ 0x8e6e, 0x4203,
+ 0x8e6f, 0x41db,
+ 0x8e70, 0x3fde,
+ 0x8e71, 0x3ff4,
+ 0x8e72, 0x4004,
+ 0x8e73, 0x3f66,
+ 0x8e74, 0x3f9b,
+ 0x8e75, 0x3d66,
+ 0x8e76, 0x404b,
+ 0x8e77, 0x3fdf,
+ 0x8e78, 0x40fb,
+ 0x8e79, 0x4012,
+ 0x8e7a, 0x3fe6,
+ 0x8e7b, 0x42eb,
+ 0x8e7c, 0x4124,
+ 0x8e7d, 0x3d7c,
+ 0x8e7e, 0x3d69,
+ 0x8ea1, 0x3ffe,
+ 0x8ea2, 0x3d72,
+ 0x8ea3, 0x3fc6,
+ 0x8ea4, 0x3cfe,
+ 0x8ea5, 0x43f9,
+ 0x8ea6, 0x3d42,
+ 0x8ea7, 0x3f15,
+ 0x8ea8, 0x3fce,
+ 0x8ea9, 0x428b,
+ 0x8eaa, 0x40cf,
+ 0x8eab, 0x43f6,
+ 0x8eac, 0x4005,
+ 0x8ead, 0x3f2d,
+ 0x8eae, 0x4161,
+ 0x8eaf, 0x3f2c,
+ 0x8eb0, 0x3aca,
+ 0x8eb1, 0x3d6a,
+ 0x8eb2, 0x4063,
+ 0x8eb3, 0x3fc5,
+ 0x8eb4, 0x39e7,
+ 0x8eb5, 0x3f2a,
+ 0x8eb6, 0x4060,
+ 0x8eb7, 0x4273,
+ 0x8eb8, 0x4221,
+ 0x8eb9, 0x40a2,
+ 0x8eba, 0x3f68,
+ 0x8ebb, 0x40a1,
+ 0x8ebc, 0x3f57,
+ 0x8ebd, 0x3f70,
+ 0x8ebe, 0x3fb7,
+ 0x8ebf, 0x3746,
+ 0x8ec0, 0x3fab,
+ 0x8ec1, 0x3ff2,
+ 0x8ec2, 0x3f8c,
+ 0x8ec3, 0x3f88,
+ 0x8ec4, 0x37d3,
+ 0x8ec5, 0x3b74,
+ 0x8ec7, 0x42f4,
+ 0x8ec8, 0x3c4c,
+ 0x8ec9, 0x3b7a,
+ 0x8eca, 0x3885,
+ 0x8ecb, 0x3737,
+ 0x8ecc, 0x3fdb,
+ 0x8ecd, 0x3f1d,
+ 0x8ece, 0x3fec,
+ 0x8ecf, 0x3fe5,
+ 0x8ed0, 0x375e,
+ 0x8ed1, 0x3ff7,
+ 0x8ed2, 0x3813,
+ 0x8ed3, 0x3fe3,
+ 0x8ed4, 0x3f1a,
+ 0x8ed5, 0x38e6,
+ 0x8ed6, 0x3fdc,
+ 0x8ed7, 0x377f,
+ 0x8ed8, 0x3d87,
+ 0x8ed9, 0x3bd3,
+ 0x8eda, 0x3d78,
+ 0x8edb, 0x3bd4,
+ 0x8edc, 0x3f96,
+ 0x8edd, 0x3f95,
+ 0x8ede, 0x3d8c,
+ 0x8edf, 0x3937,
+ 0x8ee0, 0x3f1c,
+ 0x8ee1, 0x3932,
+ 0x8ee2, 0x3d6b,
+ 0x8ee3, 0x3800,
+ 0x8ee4, 0x3ff8,
+ 0x8ee5, 0x3c3a,
+ 0x8ee6, 0x3f42,
+ 0x8ee7, 0x43fd,
+ 0x8ee8, 0x3fb1,
+ 0x8ee9, 0x3792,
+ 0x8eea, 0x3f94,
+ 0x8eeb, 0x3f1e,
+ 0x8eec, 0x400a,
+ 0x8eed, 0x3882,
+ 0x8eee, 0x3f9c,
+ 0x8eef, 0x3d61,
+ 0x8ef0, 0x3f22,
+ 0x8ef1, 0x3fe9,
+ 0x8ef2, 0x3d92,
+ 0x8ef3, 0x377f,
+ 0x8ef4, 0x3b94,
+ 0x8ef5, 0x376e,
+ 0x8ef6, 0x4301,
+ 0x8ef7, 0x3f3a,
+ 0x8ef8, 0x3863,
+ 0x8ef9, 0x3ff1,
+ 0x8efa, 0x42fe,
+ 0x8efb, 0x3bfc,
+ 0x8efc, 0x3f45,
+ 0x8efd, 0x379f,
+ 0x8efe, 0x376b,
+ 0x8f40, 0x3f14,
+ 0x8f41, 0x3f47,
+ 0x8f42, 0x3862,
+ 0x8f43, 0x3769,
+ 0x8f44, 0x3c12,
+ 0x8f45, 0x3f49,
+ 0x8f46, 0x381f,
+ 0x8f47, 0x3929,
+ 0x8f48, 0x3f56,
+ 0x8f49, 0x3f34,
+ 0x8f4a, 0x3fdd,
+ 0x8f4b, 0x38fa,
+ 0x8f4c, 0x3f7b,
+ 0x8f4d, 0x3c11,
+ 0x8f4e, 0x3f7c,
+ 0x8f4f, 0x43ff,
+ 0x8f50, 0x3e73,
+ 0x8f51, 0x3f71,
+ 0x8f52, 0x3925,
+ 0x8f53, 0x3c55,
+ 0x8f54, 0x38b5,
+ 0x8f55, 0x3f5a,
+ 0x8f56, 0x3816,
+ 0x8f57, 0x3e6d,
+ 0x8f58, 0x3782,
+ 0x8f59, 0x3f11,
+ 0x8f5a, 0x3b8b,
+ 0x8f5b, 0x37c0,
+ 0x8f5c, 0x3815,
+ 0x8f5d, 0x383b,
+ 0x8f5e, 0x3d73,
+ 0x8f5f, 0x3d6e,
+ 0x8f60, 0x3f8a,
+ 0x8f61, 0x3f3e,
+ 0x8f62, 0x4234,
+ 0x8f63, 0x41e3,
+ 0x8f64, 0x3fc7,
+ 0x8f65, 0x3ff3,
+ 0x8f66, 0x4003,
+ 0x8f67, 0x4032,
+ 0x8f68, 0x3f6e,
+ 0x8f69, 0x41a3,
+ 0x8f6a, 0x4006,
+ 0x8f6b, 0x3f2b,
+ 0x8f6c, 0x3f7d,
+ 0x8f6d, 0x3c73,
+ 0x8f6e, 0x3f16,
+ 0x8f6f, 0x4002,
+ 0x8f70, 0x4056,
+ 0x8f71, 0x3fba,
+ 0x8f72, 0x3f6b,
+ 0x8f73, 0x3f91,
+ 0x8f74, 0x3fbe,
+ 0x8f75, 0x405a,
+ 0x8f76, 0x3adf,
+ 0x8f77, 0x3e41,
+ 0x8f78, 0x3d67,
+ 0x8f79, 0x3f60,
+ 0x8f7a, 0x41e8,
+ 0x8f7b, 0x3fc0,
+ 0x8f7c, 0x3d83,
+ 0x8f7d, 0x4173,
+ 0x8f7e, 0x3f5c,
+ 0x8fa1, 0x3f32,
+ 0x8fa2, 0x3f3f,
+ 0x8fa3, 0x3d63,
+ 0x8fa4, 0x4146,
+ 0x8fa5, 0x3fcd,
+ 0x8fa6, 0x3d79,
+ 0x8fa7, 0x3f28,
+ 0x8fa8, 0x3fc1,
+ 0x8fa9, 0x40bc,
+ 0x8faa, 0x3d71,
+ 0x8fab, 0x3f37,
+ 0x8fac, 0x42d8,
+ 0x8fad, 0x3feb,
+ 0x8fae, 0x4241,
+ 0x8faf, 0x3a30,
+ 0x8fb0, 0x39cd,
+ 0x8fb1, 0x42bf,
+ 0x8fb2, 0x420e,
+ 0x8fb3, 0x3f0a,
+ 0x8fb4, 0x39cc,
+ 0x8fb5, 0x4044,
+ 0x8fb6, 0x4098,
+ 0x8fb7, 0x418c,
+ 0x8fb8, 0x3d64,
+ 0x8fb9, 0x3f44,
+ 0x8fba, 0x404f,
+ 0x8fbb, 0x42d5,
+ 0x8fbc, 0x4290,
+ 0x8fbd, 0x4000,
+ 0x8fbe, 0x3a89,
+ 0x8fbf, 0x416c,
+ 0x8fc0, 0x40c4,
+ 0x8fc1, 0x404d,
+ 0x8fc2, 0x3dc0,
+ 0x8fc3, 0x3f50,
+ 0x8fc4, 0x4009,
+ 0x8fc5, 0x3faf,
+ 0x8fc6, 0x3f86,
+ 0x8fc7, 0x4093,
+ 0x8fc8, 0x3aad,
+ 0x8fc9, 0x3f38,
+ 0x8fca, 0x3d75,
+ 0x8fcb, 0x3f39,
+ 0x8fcc, 0x42cd,
+ 0x8fcd, 0x3f78,
+ 0x8fce, 0x3f9d,
+ 0x8fcf, 0x4090,
+ 0x8fd0, 0x3d80,
+ 0x8fd1, 0x3f2e,
+ 0x8fd2, 0x38b6,
+ 0x8fd3, 0x41b9,
+ 0x8fd4, 0x3d8a,
+ 0x8fd5, 0x3f24,
+ 0x8fd6, 0x3a9e,
+ 0x8fd7, 0x3adc,
+ 0x8fd8, 0x3d65,
+ 0x8fd9, 0x4085,
+ 0x8fda, 0x3f51,
+ 0x8fdb, 0x43fa,
+ 0x8fdc, 0x3f63,
+ 0x8fdd, 0x4178,
+ 0x8fde, 0x41b7,
+ 0x8fdf, 0x3e72,
+ 0x8fe0, 0x41d9,
+ 0x8fe1, 0x418e,
+ 0x8fe2, 0x3d76,
+ 0x8fe3, 0x42d4,
+ 0x8fe4, 0x42a2,
+ 0x8fe5, 0x4257,
+ 0x8fe6, 0x3f0c,
+ 0x8fe7, 0x3996,
+ 0x8fe8, 0x4255,
+ 0x8fe9, 0x40b7,
+ 0x8fea, 0x3f9a,
+ 0x8feb, 0x3fca,
+ 0x8fec, 0x3f5e,
+ 0x8fed, 0x3d85,
+ 0x8fee, 0x3ffa,
+ 0x8fef, 0x3fb6,
+ 0x8ff0, 0x3ac3,
+ 0x8ff1, 0x3fc8,
+ 0x8ff2, 0x3f4b,
+ 0x8ff3, 0x40f1,
+ 0x8ff4, 0x4034,
+ 0x8ff5, 0x3f5b,
+ 0x8ff6, 0x42c9,
+ 0x8ff7, 0x3c75,
+ 0x8ff8, 0x3f79,
+ 0x8ff9, 0x42c6,
+ 0x8ffa, 0x38cf,
+ 0x8ffb, 0x41f4,
+ 0x8ffc, 0x3f41,
+ 0x8ffd, 0x390b,
+ 0x8ffe, 0x38e0,
+ 0x9040, 0x427d,
+ 0x9041, 0x42f0,
+ 0x9042, 0x3f27,
+ 0x9043, 0x3822,
+ 0x9044, 0x37d8,
+ 0x9045, 0x37a2,
+ 0x9046, 0x3f73,
+ 0x9047, 0x42b8,
+ 0x9048, 0x3f19,
+ 0x9049, 0x42b7,
+ 0x904a, 0x3d8b,
+ 0x904b, 0x4129,
+ 0x904c, 0x40d4,
+ 0x904d, 0x38f5,
+ 0x904e, 0x4143,
+ 0x904f, 0x4022,
+ 0x9050, 0x41d0,
+ 0x9051, 0x41f5,
+ 0x9052, 0x3f43,
+ 0x9053, 0x40c8,
+ 0x9054, 0x4096,
+ 0x9055, 0x405d,
+ 0x9056, 0x4174,
+ 0x9057, 0x413e,
+ 0x9058, 0x413b,
+ 0x9059, 0x39c4,
+ 0x905a, 0x3d89,
+ 0x905b, 0x4205,
+ 0x905c, 0x36eb,
+ 0x905d, 0x39c5,
+ 0x905e, 0x3d84,
+ 0x905f, 0x4054,
+ 0x9060, 0x193f,
+ 0x9061, 0x0619,
+ 0x9062, 0x0871,
+ 0x9063, 0x115f,
+ 0x9064, 0x3f53,
+ 0x9065, 0x3f1f,
+ 0x9066, 0x339d,
+ 0x9067, 0x3fb8,
+ 0x9068, 0x3b3f,
+ 0x9069, 0x3f52,
+ 0x906a, 0x3761,
+ 0x906b, 0x375c,
+ 0x906c, 0x3fd9,
+ 0x906d, 0x3fd7,
+ 0x906e, 0x3fd6,
+ 0x906f, 0x3e93,
+ 0x9070, 0x3774,
+ 0x9071, 0x377b,
+ 0x9072, 0x3b4f,
+ 0x9073, 0x4007,
+ 0x9074, 0x3fe2,
+ 0x9075, 0x3e79,
+ 0x9076, 0x3e76,
+ 0x9077, 0x3fe7,
+ 0x9078, 0x0d2a,
+ 0x9079, 0x3fee,
+ 0x907a, 0x3fe1,
+ 0x907b, 0x3e77,
+ 0x907c, 0x3fa3,
+ 0x907d, 0x3f54,
+ 0x907e, 0x37bc,
+ 0x90a1, 0x3e7a,
+ 0x90a2, 0x3fa1,
+ 0x90a3, 0x37c1,
+ 0x90a4, 0x3ff5,
+ 0x90a5, 0x3f9e,
+ 0x90a6, 0x3b7f,
+ 0x90a7, 0x380b,
+ 0x90a8, 0x3fef,
+ 0x90a9, 0x3ffc,
+ 0x90aa, 0x380d,
+ 0x90ab, 0x3fed,
+ 0x90ac, 0x3fe4,
+ 0x90ad, 0x3811,
+ 0x90ae, 0x3f7a,
+ 0x90af, 0x3fa2,
+ 0x90b0, 0x3b8e,
+ 0x90b1, 0x381c,
+ 0x90b2, 0x3fa0,
+ 0x90b3, 0x3fe0,
+ 0x90b4, 0x3d93,
+ 0x90b5, 0x3827,
+ 0x90b6, 0x3ff0,
+ 0x90b7, 0x3fa5,
+ 0x90b8, 0x3836,
+ 0x90b9, 0x3d8d,
+ 0x90ba, 0x3f69,
+ 0x90bb, 0x3f82,
+ 0x90bc, 0x3f85,
+ 0x90bd, 0x3f83,
+ 0x90be, 0x3f89,
+ 0x90bf, 0x3f7f,
+ 0x90c0, 0x3bb5,
+ 0x90c1, 0x3f87,
+ 0x90c2, 0x3f31,
+ 0x90c3, 0x3d94,
+ 0x90c4, 0x0230,
+ 0x90c5, 0x43fe,
+ 0x90c6, 0x3f10,
+ 0x90c7, 0x387e,
+ 0x90c8, 0x43eb,
+ 0x90c9, 0x3f6f,
+ 0x90ca, 0x3e9b,
+ 0x90cb, 0x3f4e,
+ 0x90cc, 0x3bc8,
+ 0x90cd, 0x1e29,
+ 0x90ce, 0x3f48,
+ 0x90cf, 0x382e,
+ 0x90d0, 0x3c60,
+ 0x90d1, 0x2a9f,
+ 0x90d2, 0x3893,
+ 0x90d3, 0x43f7,
+ 0x90d4, 0x3e74,
+ 0x90d5, 0x3bcd,
+ 0x90d6, 0x3ac9,
+ 0x90d7, 0x3fcc,
+ 0x90d8, 0x3fd1,
+ 0x90d9, 0x3f3d,
+ 0x90da, 0x3f4a,
+ 0x90db, 0x38ad,
+ 0x90dc, 0x2352,
+ 0x90dd, 0x3f46,
+ 0x90de, 0x38b2,
+ 0x90df, 0x3fb3,
+ 0x90e0, 0x3f0d,
+ 0x90e1, 0x38c0,
+ 0x90e2, 0x3e2f,
+ 0x90e3, 0x38d5,
+ 0x90e4, 0x3f35,
+ 0x90e5, 0x38d7,
+ 0x90e6, 0x3f2f,
+ 0x90e7, 0x3f33,
+ 0x90e8, 0x3d95,
+ 0x90e9, 0x3c02,
+ 0x90ea, 0x3f72,
+ 0x90eb, 0x3d96,
+ 0x90ec, 0x38e7,
+ 0x90ed, 0x4035,
+ 0x90ee, 0x3c0b,
+ 0x90ef, 0x38f0,
+ 0x90f0, 0x38f7,
+ 0x90f1, 0x3fb9,
+ 0x90f2, 0x3900,
+ 0x90f3, 0x3f74,
+ 0x90f4, 0x3909,
+ 0x90f5, 0x3f12,
+ 0x90f6, 0x3f17,
+ 0x90f7, 0x3f20,
+ 0x90f8, 0x3fbb,
+ 0x90f9, 0x3f3c,
+ 0x90fa, 0x3fb4,
+ 0x90fb, 0x3fad,
+ 0x90fc, 0x391a,
+ 0x90fd, 0x391c,
+ 0x90fe, 0x391b,
+ 0x9140, 0x3c39,
+ 0x9141, 0x3e71,
+ 0x9142, 0x3d7e,
+ 0x9143, 0x3f3b,
+ 0x9144, 0x3f30,
+ 0x9145, 0x3f84,
+ 0x9146, 0x43f8,
+ 0x9147, 0x3f0f,
+ 0x9148, 0x3f76,
+ 0x9149, 0x3933,
+ 0x914a, 0x3f75,
+ 0x914b, 0x3940,
+ 0x914c, 0x3f21,
+ 0x914d, 0x3f90,
+ 0x914e, 0x394a,
+ 0x914f, 0x3f80,
+ 0x9150, 0x3f23,
+ 0x9151, 0x3950,
+ 0x9152, 0x3d97,
+ 0x9153, 0x2e45,
+ 0x9154, 0x0570,
+ 0x9155, 0x3ead,
+ 0x9156, 0x3522,
+ 0x9157, 0x0be3,
+ 0x9158, 0x0595,
+ 0x9159, 0x0228,
+ 0x915a, 0x0a95,
+ 0x915b, 0x12b0,
+ 0x915c, 0x091a,
+ 0x915d, 0x43fc,
+ 0x915e, 0x3f92,
+ 0x915f, 0x3fae,
+ 0x9160, 0x07c2,
+ 0x9161, 0x0955,
+ 0x9162, 0x3785,
+ 0x9163, 0x3e6e,
+ 0x9164, 0x3d6d,
+ 0x9165, 0x3f62,
+ 0x9166, 0x39c8,
+ 0x9167, 0x3f65,
+ 0x9168, 0x393d,
+ 0x9169, 0x3f26,
+ 0x916a, 0x406d,
+ 0x916b, 0x3fd0,
+ 0x916c, 0x3f36,
+ 0x916d, 0x4086,
+ 0x916e, 0x3952,
+ 0x916f, 0x3fd2,
+ 0x9170, 0x3858,
+ 0x9171, 0x3ffb,
+ 0x9172, 0x3f67,
+ 0x9173, 0x3e81,
+ 0x9174, 0x3fc9,
+ 0x9175, 0x3fb5,
+ 0x9176, 0x3e7c,
+ 0x9177, 0x3e75,
+ 0x9178, 0x3c77,
+ 0x9179, 0x3b2e,
+ 0x917a, 0x3f4d,
+ 0x917b, 0x43af,
+ 0x917c, 0x3e67,
+ 0x917d, 0x40bd,
+ 0x917e, 0x3f6c,
+ 0x91a1, 0x39a6,
+ 0x91a2, 0x3948,
+ 0x91a3, 0x3fbf,
+ 0x91a4, 0x3f5f,
+ 0x91a5, 0x3a05,
+ 0x91a6, 0x06f5,
+ 0x91a7, 0x40f8,
+ 0x91a8, 0x41ad,
+ 0x91a9, 0x3f0e,
+ 0x91aa, 0x4122,
+ 0x91ab, 0x3f13,
+ 0x91ac, 0x3f0b,
+ 0x91ad, 0x4135,
+ 0x91ae, 0x3a2b,
+ 0x91af, 0x4138,
+ 0x91b0, 0x0226,
+ 0x91b1, 0x4149,
+ 0x91b2, 0x3ba5,
+ 0x91b3, 0x4001,
+ 0x91b4, 0x3fbd,
+ 0x91b5, 0x3fa8,
+ 0x91b6, 0x4186,
+ 0x91b7, 0x3a54,
+ 0x91b8, 0x3fc2,
+ 0x91b9, 0x4192,
+ 0x91ba, 0x4187,
+ 0x91bb, 0x3384,
+ 0x91bc, 0x3fc4,
+ 0x91bd, 0x3d99,
+ 0x91be, 0x3aaa,
+ 0x91bf, 0x41de,
+ 0x91c1, 0x3ff6,
+ 0x91c2, 0x3f5d,
+ 0x91c3, 0x41c7,
+ 0x91c4, 0x3d91,
+ 0x91c5, 0x3d74,
+ 0x91c6, 0x3f4c,
+ 0x91c7, 0x41f2,
+ 0x91c8, 0x3aa5,
+ 0x91c9, 0x3b4b,
+ 0x91ca, 0x3d86,
+ 0x91cb, 0x41f8,
+ 0x91cc, 0x4240,
+ 0x91cd, 0x3ffd,
+ 0x91ce, 0x3fa7,
+ 0x91cf, 0x4259,
+ 0x91d0, 0x0e72,
+ 0x91d1, 0x4262,
+ 0x91d2, 0x3c7e,
+ 0x91d3, 0x3938,
+ 0x91d4, 0x4233,
+ 0x91d5, 0x295a,
+ 0x91d7, 0x3f97,
+ 0x91d8, 0x3fb2,
+ 0x91d9, 0x428a,
+ 0x91da, 0x3f98,
+ 0x91db, 0x1f94,
+ 0x91dc, 0x3f40,
+ 0x91dd, 0x3f4f,
+ 0x91de, 0x3f8f,
+ 0x91df, 0x3d6f,
+ 0x91e0, 0x42df,
+ 0x91e1, 0x3f55,
+ 0x91e2, 0x3fd3,
+ 0x91e3, 0x42ee,
+ 0x91e4, 0x3fcf,
+ 0x91e5, 0x3fd4,
+ 0x91e6, 0x3e7d,
+ 0x91e7, 0x4307,
+ 0x91e8, 0x43fb,
+ 0x91e9, 0x3fda,
+ 0x91ea, 0x0d0a,
+ 0x91eb, 0x3f77,
+ 0x91ec, 0x3dbf,
+ 0x91ed, 0x402c,
+ 0x91ee, 0x3fa4,
+ 0x91ef, 0x3d6f,
+ 0x91f0, 0x3ccd,
+ 0x91f1, 0x3f64,
+ 0x91f2, 0x3f8b,
+ 0x91f3, 0x386f,
+ 0x91f4, 0x1971,
+ 0x91f5, 0x1c9b,
+ 0x91f6, 0x0745,
+ 0x91f7, 0x1d75,
+ 0x91f8, 0x3888,
+ 0x91f9, 0x3742,
+ 0x91fa, 0x2b40,
+ 0x91fb, 0x36e9,
+ 0x91fc, 0x37e0,
+ 0x91fd, 0x3e16,
+ 0x91fe, 0x387c,
+ 0x9240, 0x37aa,
+ 0x9241, 0x3f8e,
+ 0x9242, 0x40dc,
+ 0x9243, 0x3c7a,
+ 0x9244, 0x3fa6,
+ 0x9245, 0x405f,
+ 0x9246, 0x3c26,
+ 0x9247, 0x385e,
+ 0x9248, 0x3f25,
+ 0x9249, 0x4048,
+ 0x924a, 0x3d81,
+ 0x924b, 0x390e,
+ 0x924c, 0x4084,
+ 0x924d, 0x4118,
+ 0x924e, 0x4157,
+ 0x924f, 0x3902,
+ 0x9250, 0x389f,
+ 0x9251, 0x3ff9,
+ 0x9252, 0x3823,
+ 0x9253, 0x3871,
+ 0x9254, 0x36ea,
+ 0x9255, 0x376c,
+ 0x9256, 0x3740,
+ 0x9257, 0x37f4,
+ 0x9258, 0x42e0,
+ 0x9259, 0x425b,
+ 0x925a, 0x36ed,
+ 0x925b, 0x3b14,
+ 0x925c, 0x42c5,
+ 0x925d, 0x408b,
+ 0x925e, 0x38a5,
+ 0x925f, 0x416a,
+ 0x9260, 0x419d,
+ 0x9261, 0x4144,
+ 0x9262, 0x424f,
+ 0x9263, 0x3f61,
+ 0x9264, 0x3fd8,
+ 0x9265, 0x061c,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xa14b, 0x354e,
+ 0xa15a, 0x35af,
+ 0xa15c, 0x35b1,
+ 0xa15d, 0x0082,
+ 0xa161, 0x0086,
+ 0xa165, 0x008a,
+ 0xa169, 0x008e,
+ 0xa16d, 0x0092,
+ 0xa171, 0x0096,
+ 0xa175, 0x009a,
+ 0xa179, 0x009e,
+ 0xa1e3, 0x354f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKdlbB5VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKdlbB5VMap2, 920
+};
+
+static Gushort cns13HKgccsB5HMap2[1106] = {
+ 0x0000, 0x0000,
+ 0x8a40, 0x4308,
+ 0x8aa1, 0x4347,
+ 0x8b41, 0x438c,
+ 0x8b45, 0x438e,
+ 0x8b47, 0x438f,
+ 0x8b49, 0x4390,
+ 0x8b4b, 0x4391,
+ 0x8b4d, 0x4392,
+ 0x8b54, 0x4396,
+ 0x8b58, 0x4397,
+ 0x8b5a, 0x4398,
+ 0x8e40, 0x372b,
+ 0x8e46, 0x3730,
+ 0x8e6c, 0x3755,
+ 0x8e77, 0x375f,
+ 0x8e7e, 0x0121,
+ 0x8ea1, 0x3766,
+ 0x8ea7, 0x376b,
+ 0x8eca, 0x378d,
+ 0x8ee6, 0x37a8,
+ 0x8ef0, 0x37b1,
+ 0x8f40, 0x37c0,
+ 0x8f5a, 0x37d9,
+ 0x8f60, 0x37de,
+ 0x8f68, 0x37e5,
+ 0x8fa1, 0x37fc,
+ 0x8fc6, 0x3820,
+ 0x8fc8, 0x3821,
+ 0x8fdb, 0x3833,
+ 0x8ffd, 0x3854,
+ 0x9040, 0x3856,
+ 0x905e, 0x3872,
+ 0x9070, 0x3883,
+ 0x907a, 0x36e9,
+ 0x907b, 0x388d,
+ 0x90a1, 0x3891,
+ 0x90a7, 0x3896,
+ 0x90b9, 0x38a7,
+ 0x9140, 0x38ed,
+ 0x9166, 0x3912,
+ 0x916f, 0x391a,
+ 0x91a1, 0x3929,
+ 0x91a3, 0x392a,
+ 0x9240, 0x3986,
+ 0x92a1, 0x39c5,
+ 0x92af, 0x0119,
+ 0x92b1, 0x011c,
+ 0x92b2, 0x011b,
+ 0x92b3, 0x39d3,
+ 0x92e6, 0x3a05,
+ 0x92f3, 0x3a11,
+ 0x9340, 0x3a1d,
+ 0x9369, 0x3a45,
+ 0x93a1, 0x3a5b,
+ 0x93ab, 0x3a64,
+ 0x93c3, 0x3a7b,
+ 0x93e6, 0x3a9d,
+ 0x93ec, 0x3aa2,
+ 0x9440, 0x3ab5,
+ 0x9447, 0x3abb,
+ 0x94a1, 0x3af3,
+ 0x9540, 0x3b51,
+ 0x954e, 0x3b5e,
+ 0x955b, 0x3b6a,
+ 0x95a1, 0x3b8e,
+ 0x95c7, 0x3bb3,
+ 0x9640, 0x3beb,
+ 0x96a1, 0x3c2a,
+ 0x96d5, 0x3c5d,
+ 0x9740, 0x3c87,
+ 0x97a1, 0x3cc6,
+ 0x9840, 0x3d24,
+ 0x9877, 0x3d59,
+ 0x987a, 0x3d5a,
+ 0x98a3, 0x3d5b,
+ 0x98af, 0x3d5c,
+ 0x98b6, 0x3d5d,
+ 0x98b9, 0x3d5e,
+ 0x98bd, 0x3d5f,
+ 0x98c2, 0x3d61,
+ 0x98c4, 0x3d62,
+ 0x98c6, 0x3d63,
+ 0x98e3, 0x3d65,
+ 0x98e7, 0x3d66,
+ 0x98ed, 0x3d67,
+ 0x98f0, 0x3d68,
+ 0x98f2, 0x3d69,
+ 0x98fc, 0x3d6a,
+ 0x9943, 0x3d6b,
+ 0x9945, 0x3d6c,
+ 0x994f, 0x3d6d,
+ 0x996a, 0x3d6e,
+ 0x996e, 0x3d6f,
+ 0x9975, 0x3d70,
+ 0x9978, 0x3d71,
+ 0x99a2, 0x3d72,
+ 0x99ae, 0x3d73,
+ 0x99b6, 0x3d74,
+ 0x99ba, 0x3d75,
+ 0x99e2, 0x3d76,
+ 0x99f4, 0x3d77,
+ 0x9a4a, 0x3d78,
+ 0x9a4c, 0x3d79,
+ 0x9a59, 0x3d7a,
+ 0x9a61, 0x3d7b,
+ 0x9a68, 0x3d7c,
+ 0x9a73, 0x3d7d,
+ 0x9a7e, 0x3d7e,
+ 0x9ab2, 0x3d7f,
+ 0x9ab7, 0x3d80,
+ 0x9ab9, 0x3d81,
+ 0x9abb, 0x3d82,
+ 0x9ac7, 0x3d83,
+ 0x9ad0, 0x3d84,
+ 0x9ad2, 0x3d85,
+ 0x9ad9, 0x3d86,
+ 0x9ae2, 0x3d89,
+ 0x9ae4, 0x3d8a,
+ 0x9ae8, 0x3d8b,
+ 0x9af2, 0x3d8c,
+ 0x9af6, 0x3d8d,
+ 0x9afb, 0x3d8e,
+ 0x9b46, 0x3d8f,
+ 0x9b4a, 0x3d90,
+ 0x9b4c, 0x3d91,
+ 0x9b54, 0x3d92,
+ 0x9b58, 0x3d93,
+ 0x9b5a, 0x3d94,
+ 0x9b5c, 0x3d95,
+ 0x9b5e, 0x3d96,
+ 0x9b70, 0x3d98,
+ 0x9b76, 0x3d9c,
+ 0x9b7b, 0x3d9f,
+ 0x9b7e, 0x3da1,
+ 0x9ba1, 0x3da2,
+ 0x9ba3, 0x3da3,
+ 0x9ba7, 0x3da5,
+ 0x9bac, 0x3da9,
+ 0x9baf, 0x3daa,
+ 0x9bb2, 0x3dab,
+ 0x9bbe, 0x3db3,
+ 0x9bc0, 0x3db4,
+ 0x9bca, 0x3dbb,
+ 0x9bcc, 0x3dbc,
+ 0x9bd0, 0x3dbd,
+ 0x9bd3, 0x3dbf,
+ 0x9bd5, 0x3dc0,
+ 0x9bd8, 0x3dc1,
+ 0x9bdd, 0x3dc4,
+ 0x9bde, 0x1c14,
+ 0x9bdf, 0x3dc5,
+ 0x9be1, 0x3dc6,
+ 0x9be3, 0x3dc7,
+ 0x9be7, 0x3dc8,
+ 0x9be9, 0x3dc9,
+ 0x9bee, 0x3dcd,
+ 0x9bf3, 0x3dcf,
+ 0x9bf6, 0x3dd0,
+ 0x9bf8, 0x3dd1,
+ 0x9bfb, 0x3dd3,
+ 0x9c40, 0x3dd5,
+ 0x9c44, 0x3dd8,
+ 0x9c48, 0x3ddb,
+ 0x9c4a, 0x3ddc,
+ 0x9c4d, 0x3ddd,
+ 0x9c55, 0x3de4,
+ 0x9c57, 0x3de5,
+ 0x9c5d, 0x3dea,
+ 0x9c60, 0x3deb,
+ 0x9c62, 0x3dec,
+ 0x9c64, 0x3ded,
+ 0x9c68, 0x3df0,
+ 0x9c6a, 0x3df1,
+ 0x9c6b, 0x346a,
+ 0x9c6d, 0x3df2,
+ 0x9c6f, 0x3df3,
+ 0x9c75, 0x3df7,
+ 0x9c79, 0x3dfa,
+ 0x9c7b, 0x3dfb,
+ 0x9c7e, 0x3dfd,
+ 0x9ca1, 0x3dfe,
+ 0x9ca5, 0x3e00,
+ 0x9ca8, 0x3e01,
+ 0x9cab, 0x3e03,
+ 0x9cad, 0x3e04,
+ 0x9cb1, 0x3e06,
+ 0x9cbc, 0x3e10,
+ 0x9cc6, 0x3e17,
+ 0x9ccf, 0x3e1f,
+ 0x9cd8, 0x3e24,
+ 0x9cdc, 0x3e27,
+ 0x9ce7, 0x3e31,
+ 0x9ceb, 0x3e34,
+ 0x9cee, 0x3e36,
+ 0x9cfd, 0x3e42,
+ 0x9d46, 0x3e43,
+ 0x9d49, 0x3e44,
+ 0x9d4c, 0x3e46,
+ 0x9d4f, 0x3e48,
+ 0x9d51, 0x3e49,
+ 0x9d55, 0x3e4a,
+ 0x9d57, 0x25c1,
+ 0x9d5a, 0x3e4b,
+ 0x9d62, 0x3e4c,
+ 0x9d64, 0x3e4d,
+ 0x9d79, 0x3e4e,
+ 0x9d7e, 0x3e4f,
+ 0x9da5, 0x3e50,
+ 0x9daa, 0x3e54,
+ 0x9dac, 0x3e55,
+ 0x9db0, 0x3e58,
+ 0x9db3, 0x3e59,
+ 0x9db5, 0x3e5a,
+ 0x9db7, 0x3e5b,
+ 0x9dbc, 0x3e5c,
+ 0x9dbf, 0x3e5e,
+ 0x9dc3, 0x3e60,
+ 0x9dc7, 0x3e62,
+ 0x9dca, 0x3e64,
+ 0x9dcd, 0x3e65,
+ 0x9dd3, 0x3e6a,
+ 0x9dda, 0x3e6d,
+ 0x9dfd, 0x3e8f,
+ 0x9e40, 0x3e91,
+ 0x9e64, 0x3eb4,
+ 0x9e68, 0x3eb6,
+ 0x9e6a, 0x3eb7,
+ 0x9e71, 0x3eb8,
+ 0x9e73, 0x3eb9,
+ 0x9e77, 0x3eba,
+ 0x9e7a, 0x3ebc,
+ 0x9e7c, 0x3ebd,
+ 0x9e7e, 0x3ebe,
+ 0x9ea1, 0x3ebf,
+ 0x9ea4, 0x3ec1,
+ 0x9ea9, 0x3ec4,
+ 0x9eac, 0x3ec6,
+ 0x9eaf, 0x3ec8,
+ 0x9eb4, 0x3ecb,
+ 0x9eb6, 0x3ecc,
+ 0x9eb9, 0x3ece,
+ 0x9ebc, 0x3ecf,
+ 0x9ebf, 0x3ed0,
+ 0x9ec4, 0x3ed2,
+ 0x9ec7, 0x3ed4,
+ 0x9ecc, 0x3ed8,
+ 0x9ed0, 0x3eda,
+ 0x9ed3, 0x3edc,
+ 0x9ed6, 0x3edd,
+ 0x9eda, 0x3edf,
+ 0x9ef3, 0x3ef7,
+ 0x9ef9, 0x3efa,
+ 0x9efc, 0x3efc,
+ 0x9f40, 0x3eff,
+ 0x9f44, 0x3f02,
+ 0x9f49, 0x3f06,
+ 0x9f4d, 0x3f08,
+ 0x9f69, 0x3f23,
+ 0x9f71, 0x3f2a,
+ 0x9fa1, 0x3f38,
+ 0x9fb6, 0x3f4c,
+ 0x9fbc, 0x3f51,
+ 0x9fc0, 0x3f54,
+ 0x9fc2, 0x3f55,
+ 0x9fe5, 0x3f77,
+ 0x9ffa, 0x3f8b,
+ 0xa041, 0x3f90,
+ 0xa048, 0x3f96,
+ 0xa056, 0x3fa3,
+ 0xa06e, 0x3fba,
+ 0xa07c, 0x3fc7,
+ 0xa0a1, 0x3fca,
+ 0xa0a3, 0x3fcb,
+ 0xa0a8, 0x3fcf,
+ 0xa0c6, 0x3fec,
+ 0xa0d1, 0x3ff6,
+ 0xa0e4, 0x4008,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xfa40, 0x400b,
+ 0xfaa1, 0x404a,
+ 0xfb40, 0x40a8,
+ 0xfba1, 0x40e7,
+ 0xfbc0, 0x4105,
+ 0xfbce, 0x4112,
+ 0xfc40, 0x4143,
+ 0xfc4b, 0x414d,
+ 0xfc4f, 0x212f,
+ 0xfc50, 0x4151,
+ 0xfc53, 0x4153,
+ 0xfc64, 0x4163,
+ 0xfc76, 0x4174,
+ 0xfca1, 0x417d,
+ 0xfcb9, 0x115f,
+ 0xfcba, 0x4195,
+ 0xfcbd, 0x4197,
+ 0xfce4, 0x41bd,
+ 0xfcef, 0x41c7,
+ 0xfd40, 0x41d7,
+ 0xfd4a, 0x41e0,
+ 0xfda1, 0x4215,
+ 0xfdf3, 0x4266,
+ 0xfe40, 0x4272,
+ 0xfe6e, 0x429f,
+ 0xfe79, 0x42a9,
+ 0xfea1, 0x42af,
+ 0xfeaa, 0x0120,
+ 0xfeab, 0x42b8,
+ 0xfee0, 0x42eb,
+ 0xfeef, 0x42f8,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKgccsB5HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKgccsB5HMap2, 553
+};
+
+static Gushort cns13HKgccsB5VMap2[1130] = {
+ 0x0000, 0x0000,
+ 0x8a40, 0x4308,
+ 0x8aa1, 0x4347,
+ 0x8b41, 0x438c,
+ 0x8b45, 0x438e,
+ 0x8b47, 0x438f,
+ 0x8b49, 0x4390,
+ 0x8b4b, 0x4391,
+ 0x8b4d, 0x4392,
+ 0x8b54, 0x4396,
+ 0x8b58, 0x4397,
+ 0x8b5a, 0x4398,
+ 0x8e40, 0x372b,
+ 0x8e46, 0x3730,
+ 0x8e6c, 0x3755,
+ 0x8e77, 0x375f,
+ 0x8e7e, 0x0121,
+ 0x8ea1, 0x3766,
+ 0x8ea7, 0x376b,
+ 0x8eca, 0x378d,
+ 0x8ee6, 0x37a8,
+ 0x8ef0, 0x37b1,
+ 0x8f40, 0x37c0,
+ 0x8f5a, 0x37d9,
+ 0x8f60, 0x37de,
+ 0x8f68, 0x37e5,
+ 0x8fa1, 0x37fc,
+ 0x8fc6, 0x3820,
+ 0x8fc8, 0x3821,
+ 0x8fdb, 0x3833,
+ 0x8ffd, 0x3854,
+ 0x9040, 0x3856,
+ 0x905e, 0x3872,
+ 0x9070, 0x3883,
+ 0x907a, 0x36e9,
+ 0x907b, 0x388d,
+ 0x90a1, 0x3891,
+ 0x90a7, 0x3896,
+ 0x90b9, 0x38a7,
+ 0x9140, 0x38ed,
+ 0x9166, 0x3912,
+ 0x916f, 0x391a,
+ 0x91a1, 0x3929,
+ 0x91a3, 0x392a,
+ 0x9240, 0x3986,
+ 0x92a1, 0x39c5,
+ 0x92af, 0x0119,
+ 0x92b1, 0x011c,
+ 0x92b2, 0x011b,
+ 0x92b3, 0x39d3,
+ 0x92e6, 0x3a05,
+ 0x92f3, 0x3a11,
+ 0x9340, 0x3a1d,
+ 0x9369, 0x3a45,
+ 0x93a1, 0x3a5b,
+ 0x93ab, 0x3a64,
+ 0x93c3, 0x3a7b,
+ 0x93e6, 0x3a9d,
+ 0x93ec, 0x3aa2,
+ 0x9440, 0x3ab5,
+ 0x9447, 0x3abb,
+ 0x94a1, 0x3af3,
+ 0x9540, 0x3b51,
+ 0x954e, 0x3b5e,
+ 0x955b, 0x3b6a,
+ 0x95a1, 0x3b8e,
+ 0x95c7, 0x3bb3,
+ 0x9640, 0x3beb,
+ 0x96a1, 0x3c2a,
+ 0x96d5, 0x3c5d,
+ 0x9740, 0x3c87,
+ 0x97a1, 0x3cc6,
+ 0x9840, 0x3d24,
+ 0x9877, 0x3d59,
+ 0x987a, 0x3d5a,
+ 0x98a3, 0x3d5b,
+ 0x98af, 0x3d5c,
+ 0x98b6, 0x3d5d,
+ 0x98b9, 0x3d5e,
+ 0x98bd, 0x3d5f,
+ 0x98c2, 0x3d61,
+ 0x98c4, 0x3d62,
+ 0x98c6, 0x3d63,
+ 0x98e3, 0x3d65,
+ 0x98e7, 0x3d66,
+ 0x98ed, 0x3d67,
+ 0x98f0, 0x3d68,
+ 0x98f2, 0x3d69,
+ 0x98fc, 0x3d6a,
+ 0x9943, 0x3d6b,
+ 0x9945, 0x3d6c,
+ 0x994f, 0x3d6d,
+ 0x996a, 0x3d6e,
+ 0x996e, 0x3d6f,
+ 0x9975, 0x3d70,
+ 0x9978, 0x3d71,
+ 0x99a2, 0x3d72,
+ 0x99ae, 0x3d73,
+ 0x99b6, 0x3d74,
+ 0x99ba, 0x3d75,
+ 0x99e2, 0x3d76,
+ 0x99f4, 0x3d77,
+ 0x9a4a, 0x3d78,
+ 0x9a4c, 0x3d79,
+ 0x9a59, 0x3d7a,
+ 0x9a61, 0x3d7b,
+ 0x9a68, 0x3d7c,
+ 0x9a73, 0x3d7d,
+ 0x9a7e, 0x3d7e,
+ 0x9ab2, 0x3d7f,
+ 0x9ab7, 0x3d80,
+ 0x9ab9, 0x3d81,
+ 0x9abb, 0x3d82,
+ 0x9ac7, 0x3d83,
+ 0x9ad0, 0x3d84,
+ 0x9ad2, 0x3d85,
+ 0x9ad9, 0x3d86,
+ 0x9ae2, 0x3d89,
+ 0x9ae4, 0x3d8a,
+ 0x9ae8, 0x3d8b,
+ 0x9af2, 0x3d8c,
+ 0x9af6, 0x3d8d,
+ 0x9afb, 0x3d8e,
+ 0x9b46, 0x3d8f,
+ 0x9b4a, 0x3d90,
+ 0x9b4c, 0x3d91,
+ 0x9b54, 0x3d92,
+ 0x9b58, 0x3d93,
+ 0x9b5a, 0x3d94,
+ 0x9b5c, 0x3d95,
+ 0x9b5e, 0x3d96,
+ 0x9b70, 0x3d98,
+ 0x9b76, 0x3d9c,
+ 0x9b7b, 0x3d9f,
+ 0x9b7e, 0x3da1,
+ 0x9ba1, 0x3da2,
+ 0x9ba3, 0x3da3,
+ 0x9ba7, 0x3da5,
+ 0x9bac, 0x3da9,
+ 0x9baf, 0x3daa,
+ 0x9bb2, 0x3dab,
+ 0x9bbe, 0x3db3,
+ 0x9bc0, 0x3db4,
+ 0x9bca, 0x3dbb,
+ 0x9bcc, 0x3dbc,
+ 0x9bd0, 0x3dbd,
+ 0x9bd3, 0x3dbf,
+ 0x9bd5, 0x3dc0,
+ 0x9bd8, 0x3dc1,
+ 0x9bdd, 0x3dc4,
+ 0x9bde, 0x1c14,
+ 0x9bdf, 0x3dc5,
+ 0x9be1, 0x3dc6,
+ 0x9be3, 0x3dc7,
+ 0x9be7, 0x3dc8,
+ 0x9be9, 0x3dc9,
+ 0x9bee, 0x3dcd,
+ 0x9bf3, 0x3dcf,
+ 0x9bf6, 0x3dd0,
+ 0x9bf8, 0x3dd1,
+ 0x9bfb, 0x3dd3,
+ 0x9c40, 0x3dd5,
+ 0x9c44, 0x3dd8,
+ 0x9c48, 0x3ddb,
+ 0x9c4a, 0x3ddc,
+ 0x9c4d, 0x3ddd,
+ 0x9c55, 0x3de4,
+ 0x9c57, 0x3de5,
+ 0x9c5d, 0x3dea,
+ 0x9c60, 0x3deb,
+ 0x9c62, 0x3dec,
+ 0x9c64, 0x3ded,
+ 0x9c68, 0x3df0,
+ 0x9c6a, 0x3df1,
+ 0x9c6b, 0x346a,
+ 0x9c6d, 0x3df2,
+ 0x9c6f, 0x3df3,
+ 0x9c75, 0x3df7,
+ 0x9c79, 0x3dfa,
+ 0x9c7b, 0x3dfb,
+ 0x9c7e, 0x3dfd,
+ 0x9ca1, 0x3dfe,
+ 0x9ca5, 0x3e00,
+ 0x9ca8, 0x3e01,
+ 0x9cab, 0x3e03,
+ 0x9cad, 0x3e04,
+ 0x9cb1, 0x3e06,
+ 0x9cbc, 0x3e10,
+ 0x9cc6, 0x3e17,
+ 0x9ccf, 0x3e1f,
+ 0x9cd8, 0x3e24,
+ 0x9cdc, 0x3e27,
+ 0x9ce7, 0x3e31,
+ 0x9ceb, 0x3e34,
+ 0x9cee, 0x3e36,
+ 0x9cfd, 0x3e42,
+ 0x9d46, 0x3e43,
+ 0x9d49, 0x3e44,
+ 0x9d4c, 0x3e46,
+ 0x9d4f, 0x3e48,
+ 0x9d51, 0x3e49,
+ 0x9d55, 0x3e4a,
+ 0x9d57, 0x25c1,
+ 0x9d5a, 0x3e4b,
+ 0x9d62, 0x3e4c,
+ 0x9d64, 0x3e4d,
+ 0x9d79, 0x3e4e,
+ 0x9d7e, 0x3e4f,
+ 0x9da5, 0x3e50,
+ 0x9daa, 0x3e54,
+ 0x9dac, 0x3e55,
+ 0x9db0, 0x3e58,
+ 0x9db3, 0x3e59,
+ 0x9db5, 0x3e5a,
+ 0x9db7, 0x3e5b,
+ 0x9dbc, 0x3e5c,
+ 0x9dbf, 0x3e5e,
+ 0x9dc3, 0x3e60,
+ 0x9dc7, 0x3e62,
+ 0x9dca, 0x3e64,
+ 0x9dcd, 0x3e65,
+ 0x9dd3, 0x3e6a,
+ 0x9dda, 0x3e6d,
+ 0x9dfd, 0x3e8f,
+ 0x9e40, 0x3e91,
+ 0x9e64, 0x3eb4,
+ 0x9e68, 0x3eb6,
+ 0x9e6a, 0x3eb7,
+ 0x9e71, 0x3eb8,
+ 0x9e73, 0x3eb9,
+ 0x9e77, 0x3eba,
+ 0x9e7a, 0x3ebc,
+ 0x9e7c, 0x3ebd,
+ 0x9e7e, 0x3ebe,
+ 0x9ea1, 0x3ebf,
+ 0x9ea4, 0x3ec1,
+ 0x9ea9, 0x3ec4,
+ 0x9eac, 0x3ec6,
+ 0x9eaf, 0x3ec8,
+ 0x9eb4, 0x3ecb,
+ 0x9eb6, 0x3ecc,
+ 0x9eb9, 0x3ece,
+ 0x9ebc, 0x3ecf,
+ 0x9ebf, 0x3ed0,
+ 0x9ec4, 0x3ed2,
+ 0x9ec7, 0x3ed4,
+ 0x9ecc, 0x3ed8,
+ 0x9ed0, 0x3eda,
+ 0x9ed3, 0x3edc,
+ 0x9ed6, 0x3edd,
+ 0x9eda, 0x3edf,
+ 0x9ef3, 0x3ef7,
+ 0x9ef9, 0x3efa,
+ 0x9efc, 0x3efc,
+ 0x9f40, 0x3eff,
+ 0x9f44, 0x3f02,
+ 0x9f49, 0x3f06,
+ 0x9f4d, 0x3f08,
+ 0x9f69, 0x3f23,
+ 0x9f71, 0x3f2a,
+ 0x9fa1, 0x3f38,
+ 0x9fb6, 0x3f4c,
+ 0x9fbc, 0x3f51,
+ 0x9fc0, 0x3f54,
+ 0x9fc2, 0x3f55,
+ 0x9fe5, 0x3f77,
+ 0x9ffa, 0x3f8b,
+ 0xa041, 0x3f90,
+ 0xa048, 0x3f96,
+ 0xa056, 0x3fa3,
+ 0xa06e, 0x3fba,
+ 0xa07c, 0x3fc7,
+ 0xa0a1, 0x3fca,
+ 0xa0a3, 0x3fcb,
+ 0xa0a8, 0x3fcf,
+ 0xa0c6, 0x3fec,
+ 0xa0d1, 0x3ff6,
+ 0xa0e4, 0x4008,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xfa40, 0x400b,
+ 0xfaa1, 0x404a,
+ 0xfb40, 0x40a8,
+ 0xfba1, 0x40e7,
+ 0xfbc0, 0x4105,
+ 0xfbce, 0x4112,
+ 0xfc40, 0x4143,
+ 0xfc4b, 0x414d,
+ 0xfc4f, 0x212f,
+ 0xfc50, 0x4151,
+ 0xfc53, 0x4153,
+ 0xfc64, 0x4163,
+ 0xfc76, 0x4174,
+ 0xfca1, 0x417d,
+ 0xfcb9, 0x115f,
+ 0xfcba, 0x4195,
+ 0xfcbd, 0x4197,
+ 0xfce4, 0x41bd,
+ 0xfcef, 0x41c7,
+ 0xfd40, 0x41d7,
+ 0xfd4a, 0x41e0,
+ 0xfda1, 0x4215,
+ 0xfdf3, 0x4266,
+ 0xfe40, 0x4272,
+ 0xfe6e, 0x429f,
+ 0xfe79, 0x42a9,
+ 0xfea1, 0x42af,
+ 0xfeaa, 0x0120,
+ 0xfeab, 0x42b8,
+ 0xfee0, 0x42eb,
+ 0xfeef, 0x42f8,
+ 0xa14b, 0x354e,
+ 0xa15a, 0x35af,
+ 0xa15c, 0x35b1,
+ 0xa15d, 0x0082,
+ 0xa161, 0x0086,
+ 0xa165, 0x008a,
+ 0xa169, 0x008e,
+ 0xa16d, 0x0092,
+ 0xa171, 0x0096,
+ 0xa175, 0x009a,
+ 0xa179, 0x009e,
+ 0xa1e3, 0x354f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKgccsB5VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKgccsB5VMap2, 565
+};
+
+static Gushort cns13HKm314B5HMap2[1086] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc740, 0x3d6d,
+ 0xc741, 0x39c4,
+ 0xc742, 0x4399,
+ 0xc743, 0x3e05,
+ 0xc744, 0x36ea,
+ 0xc745, 0x39c8,
+ 0xc746, 0x393d,
+ 0xc747, 0x439b,
+ 0xc748, 0x4022,
+ 0xc749, 0x439d,
+ 0xc74a, 0x4034,
+ 0xc74b, 0x439f,
+ 0xc74c, 0x3ea3,
+ 0xc74d, 0x3ea6,
+ 0xc74e, 0x4051,
+ 0xc74f, 0x4048,
+ 0xc751, 0x404b,
+ 0xc752, 0x404f,
+ 0xc753, 0x43a2,
+ 0xc754, 0x405a,
+ 0xc755, 0x3ea4,
+ 0xc756, 0x3dbd,
+ 0xc757, 0x3dbf,
+ 0xc758, 0x405c,
+ 0xc759, 0x405f,
+ 0xc75a, 0x43a4,
+ 0xc75b, 0x407b,
+ 0xc75c, 0x4082,
+ 0xc75d, 0x3f6d,
+ 0xc75e, 0x408b,
+ 0xc75f, 0x43a6,
+ 0xc760, 0x4093,
+ 0xc761, 0x4096,
+ 0xc762, 0x43a7,
+ 0xc763, 0x4098,
+ 0xc764, 0x3e7f,
+ 0xc765, 0x3c77,
+ 0xc766, 0x3ea7,
+ 0xc767, 0x3e8a,
+ 0xc768, 0x3e98,
+ 0xc769, 0x3e8c,
+ 0xc76a, 0x40a1,
+ 0xc76b, 0x3a00,
+ 0xc76c, 0x39a3,
+ 0xc76d, 0x3e8d,
+ 0xc76e, 0x43a8,
+ 0xc76f, 0x3f58,
+ 0xc770, 0x3dbc,
+ 0xc771, 0x3ccc,
+ 0xc772, 0x3ea8,
+ 0xc774, 0x3b2e,
+ 0xc775, 0x3bc6,
+ 0xc776, 0x3e8b,
+ 0xc777, 0x3e9f,
+ 0xc778, 0x432c,
+ 0xc779, 0x43a9,
+ 0xc77a, 0x3f08,
+ 0xc77b, 0x3ea5,
+ 0xc77c, 0x3e89,
+ 0xc77d, 0x3dc3,
+ 0xc77e, 0x3e82,
+ 0xc7a1, 0x3e81,
+ 0xc7a2, 0x3e94,
+ 0xc7a3, 0x3e83,
+ 0xc7a4, 0x3e88,
+ 0xc7a5, 0x43ab,
+ 0xc7a6, 0x3e91,
+ 0xc7a7, 0x43ac,
+ 0xc7a8, 0x3e7c,
+ 0xc7a9, 0x3e80,
+ 0xc7aa, 0x3e8f,
+ 0xc7ab, 0x3e67,
+ 0xc7ac, 0x3e78,
+ 0xc7ad, 0x3e68,
+ 0xc7ae, 0x43ad,
+ 0xc7af, 0x37d2,
+ 0xc7b0, 0x3f4d,
+ 0xc7b1, 0x43ae,
+ 0xc7b2, 0x3e7e,
+ 0xc7b3, 0x40bc,
+ 0xc7b4, 0x3e63,
+ 0xc7b5, 0x40bd,
+ 0xc7b6, 0x43af,
+ 0xc7b7, 0x40b7,
+ 0xc7b8, 0x3eb7,
+ 0xc7b9, 0x3eed,
+ 0xc7ba, 0x3f6a,
+ 0xc7bb, 0x3e95,
+ 0xc7bc, 0x3948,
+ 0xc7bd, 0x3cc8,
+ 0xc7be, 0x43b1,
+ 0xc7c0, 0x40cc,
+ 0xc7c1, 0x3e86,
+ 0xc7c2, 0x3c7a,
+ 0xc7c3, 0x3c7d,
+ 0xc7c4, 0x43b4,
+ 0xc7c5, 0x40d1,
+ 0xc7c6, 0x3d72,
+ 0xc7c7, 0x3c26,
+ 0xc7c8, 0x36eb,
+ 0xc7c9, 0x40bf,
+ 0xc7ca, 0x4100,
+ 0xc7cb, 0x3c85,
+ 0xc7cc, 0x43b5,
+ 0xc7cd, 0x3a1d,
+ 0xc7ce, 0x37f5,
+ 0xc7cf, 0x36ee,
+ 0xc7d0, 0x3e5f,
+ 0xc7d1, 0x4116,
+ 0xc7d2, 0x411f,
+ 0xc7d3, 0x4118,
+ 0xc7d4, 0x4123,
+ 0xc7d5, 0x4127,
+ 0xc7d6, 0x4129,
+ 0xc7d7, 0x43bc,
+ 0xc7d9, 0x3e8e,
+ 0xc7da, 0x386f,
+ 0xc7db, 0x4143,
+ 0xc7dc, 0x4146,
+ 0xc7dd, 0x4144,
+ 0xc7de, 0x4149,
+ 0xc7df, 0x3ba5,
+ 0xc7e0, 0x4157,
+ 0xc7e1, 0x4161,
+ 0xc7e2, 0x36ec,
+ 0xc7e3, 0x416a,
+ 0xc7e4, 0x4002,
+ 0xc7e5, 0x4186,
+ 0xc7e6, 0x3fba,
+ 0xc7e7, 0x3f50,
+ 0xc7e8, 0x3e96,
+ 0xc7e9, 0x418a,
+ 0xc7ea, 0x3fc1,
+ 0xc7eb, 0x3d8f,
+ 0xc7ec, 0x43c1,
+ 0xc7ed, 0x3ea0,
+ 0xc7ee, 0x3f16,
+ 0xc7ef, 0x3e9d,
+ 0xc7f0, 0x4192,
+ 0xc7f1, 0x3a66,
+ 0xc7f2, 0x3e9c,
+ 0xc7f3, 0x3e90,
+ 0xc7f4, 0x419d,
+ 0xc7f5, 0x43c2,
+ 0xc7f7, 0x37a8,
+ 0xc7f8, 0x419e,
+ 0xc7f9, 0x4187,
+ 0xc7fa, 0x3ea2,
+ 0xc7fb, 0x3e87,
+ 0xc7fc, 0x3e84,
+ 0xc7fd, 0x3eae,
+ 0xc7fe, 0x3b74,
+ 0xc840, 0x3b75,
+ 0xc841, 0x3b72,
+ 0xc842, 0x3eb2,
+ 0xc843, 0x3eac,
+ 0xc844, 0x41ca,
+ 0xc845, 0x41f4,
+ 0xc846, 0x41d0,
+ 0xc847, 0x3aaa,
+ 0xc848, 0x41f5,
+ 0xc849, 0x41f8,
+ 0xc84a, 0x41fb,
+ 0xc84b, 0x4205,
+ 0xc84c, 0x3d8e,
+ 0xc84d, 0x420e,
+ 0xc84e, 0x3d63,
+ 0xc84f, 0x4222,
+ 0xc850, 0x4221,
+ 0xc851, 0x4223,
+ 0xc852, 0x4069,
+ 0xc853, 0x402f,
+ 0xc854, 0x38a5,
+ 0xc855, 0x3cf5,
+ 0xc856, 0x3d69,
+ 0xc857, 0x425b,
+ 0xc858, 0x3ac8,
+ 0xc859, 0x3dc0,
+ 0xc85a, 0x39ea,
+ 0xc85b, 0x4000,
+ 0xc85c, 0x4264,
+ 0xc85d, 0x4262,
+ 0xc85e, 0x3fff,
+ 0xc85f, 0x3e9a,
+ 0xc860, 0x4273,
+ 0xc861, 0x3969,
+ 0xc862, 0x427a,
+ 0xc863, 0x43ca,
+ 0xc864, 0x3f9a,
+ 0xc865, 0x3eb5,
+ 0xc866, 0x43cb,
+ 0xc868, 0x3fb2,
+ 0xc869, 0x428a,
+ 0xc86c, 0x3adf,
+ 0xc86d, 0x42c8,
+ 0xc86e, 0x3ead,
+ 0xc86f, 0x43ce,
+ 0xc870, 0x3f8f,
+ 0xc871, 0x43cf,
+ 0xc872, 0x3e72,
+ 0xc873, 0x3eaa,
+ 0xc874, 0x43d3,
+ 0xc875, 0x42e0,
+ 0xc876, 0x382d,
+ 0xc877, 0x3fd5,
+ 0xc878, 0x3b14,
+ 0xc879, 0x36e8,
+ 0xc87a, 0x42f0,
+ 0xc87b, 0x3e7d,
+ 0xc87c, 0x42fe,
+ 0xc87d, 0x4305,
+ 0xc87e, 0x373a,
+ 0xc8a1, 0x3746,
+ 0xc8a2, 0x3752,
+ 0xc8a3, 0x36ed,
+ 0xc8a4, 0x3b4a,
+ 0xc8a5, 0x3b45,
+ 0xc8a6, 0x43da,
+ 0xc8a7, 0x3ede,
+ 0xc8a8, 0x376c,
+ 0xc8a9, 0x376b,
+ 0xc8aa, 0x3782,
+ 0xc8ab, 0x3e69,
+ 0xc8ac, 0x3b4f,
+ 0xc8ad, 0x3786,
+ 0xc8ae, 0x43db,
+ 0xc8af, 0x3788,
+ 0xc8b0, 0x43dc,
+ 0xc8b1, 0x3ecd,
+ 0xc8b2, 0x3797,
+ 0xc8b3, 0x420d,
+ 0xc8b4, 0x37d8,
+ 0xc8b5, 0x3b71,
+ 0xc8b6, 0x38dc,
+ 0xc8b7, 0x37e0,
+ 0xc8b8, 0x37f4,
+ 0xc8b9, 0x3813,
+ 0xc8ba, 0x3eb0,
+ 0xc8bb, 0x380d,
+ 0xc8bc, 0x3eaf,
+ 0xc8bd, 0x381b,
+ 0xc8bf, 0x381e,
+ 0xc8c1, 0x3eb1,
+ 0xc8c2, 0x3fe9,
+ 0xc8c3, 0x43e4,
+ 0xc8c4, 0x3ff9,
+ 0xc8c5, 0x3e59,
+ 0xc8c6, 0x3e99,
+ 0xc8c7, 0x3e5e,
+ 0xc8c8, 0x3bb4,
+ 0xc8c9, 0x3eab,
+ 0xc8ca, 0x43e7,
+ 0xc8cc, 0x385e,
+ 0xc8cd, 0x43e9,
+ 0xc8ce, 0x3dbe,
+ 0xc8cf, 0x3e85,
+ 0xc8d0, 0x3863,
+ 0xc8d2, 0x3d6c,
+ 0xc8d3, 0x3871,
+ 0xc8d4, 0x387c,
+ 0xc8d5, 0x3882,
+ 0xc8d6, 0x3e9b,
+ 0xc8d7, 0x3888,
+ 0xc8d8, 0x3c0e,
+ 0xc8d9, 0x382e,
+ 0xc8da, 0x389a,
+ 0xc8db, 0x388b,
+ 0xc8dc, 0x3c04,
+ 0xc8dd, 0x36e9,
+ 0xc8de, 0x42bd,
+ 0xc8df, 0x3bcd,
+ 0xc8e0, 0x389f,
+ 0xc8e1, 0x379b,
+ 0xc8e2, 0x38af,
+ 0xc8e3, 0x3e97,
+ 0xc8e4, 0x38f0,
+ 0xc8e5, 0x3bfd,
+ 0xc8e6, 0x3c11,
+ 0xc8e8, 0x43ef,
+ 0xc8e9, 0x3785,
+ 0xc8ea, 0x3902,
+ 0xc8eb, 0x3faa,
+ 0xc8ec, 0x3f19,
+ 0xc8ed, 0x3919,
+ 0xc8ee, 0x43f1,
+ 0xc8ef, 0x391a,
+ 0xc8f1, 0x3e66,
+ 0xc8f2, 0x3f22,
+ 0xc8f3, 0x3d7e,
+ 0xc8f4, 0x3c39,
+ 0xc8f5, 0x3ea1,
+ 0xc8f6, 0x43f2,
+ 0xc8f8, 0x3f30,
+ 0xc8f9, 0x3929,
+ 0xc8fa, 0x3fbc,
+ 0xc8fb, 0x3936,
+ 0xc8fd, 0x3f90,
+ 0xc8fe, 0x0aba,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKm314B5HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKm314B5HMap2, 543
+};
+
+static Gushort cns13HKm314B5VMap2[1110] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc740, 0x3d6d,
+ 0xc741, 0x39c4,
+ 0xc742, 0x4399,
+ 0xc743, 0x3e05,
+ 0xc744, 0x36ea,
+ 0xc745, 0x39c8,
+ 0xc746, 0x393d,
+ 0xc747, 0x439b,
+ 0xc748, 0x4022,
+ 0xc749, 0x439d,
+ 0xc74a, 0x4034,
+ 0xc74b, 0x439f,
+ 0xc74c, 0x3ea3,
+ 0xc74d, 0x3ea6,
+ 0xc74e, 0x4051,
+ 0xc74f, 0x4048,
+ 0xc751, 0x404b,
+ 0xc752, 0x404f,
+ 0xc753, 0x43a2,
+ 0xc754, 0x405a,
+ 0xc755, 0x3ea4,
+ 0xc756, 0x3dbd,
+ 0xc757, 0x3dbf,
+ 0xc758, 0x405c,
+ 0xc759, 0x405f,
+ 0xc75a, 0x43a4,
+ 0xc75b, 0x407b,
+ 0xc75c, 0x4082,
+ 0xc75d, 0x3f6d,
+ 0xc75e, 0x408b,
+ 0xc75f, 0x43a6,
+ 0xc760, 0x4093,
+ 0xc761, 0x4096,
+ 0xc762, 0x43a7,
+ 0xc763, 0x4098,
+ 0xc764, 0x3e7f,
+ 0xc765, 0x3c77,
+ 0xc766, 0x3ea7,
+ 0xc767, 0x3e8a,
+ 0xc768, 0x3e98,
+ 0xc769, 0x3e8c,
+ 0xc76a, 0x40a1,
+ 0xc76b, 0x3a00,
+ 0xc76c, 0x39a3,
+ 0xc76d, 0x3e8d,
+ 0xc76e, 0x43a8,
+ 0xc76f, 0x3f58,
+ 0xc770, 0x3dbc,
+ 0xc771, 0x3ccc,
+ 0xc772, 0x3ea8,
+ 0xc774, 0x3b2e,
+ 0xc775, 0x3bc6,
+ 0xc776, 0x3e8b,
+ 0xc777, 0x3e9f,
+ 0xc778, 0x432c,
+ 0xc779, 0x43a9,
+ 0xc77a, 0x3f08,
+ 0xc77b, 0x3ea5,
+ 0xc77c, 0x3e89,
+ 0xc77d, 0x3dc3,
+ 0xc77e, 0x3e82,
+ 0xc7a1, 0x3e81,
+ 0xc7a2, 0x3e94,
+ 0xc7a3, 0x3e83,
+ 0xc7a4, 0x3e88,
+ 0xc7a5, 0x43ab,
+ 0xc7a6, 0x3e91,
+ 0xc7a7, 0x43ac,
+ 0xc7a8, 0x3e7c,
+ 0xc7a9, 0x3e80,
+ 0xc7aa, 0x3e8f,
+ 0xc7ab, 0x3e67,
+ 0xc7ac, 0x3e78,
+ 0xc7ad, 0x3e68,
+ 0xc7ae, 0x43ad,
+ 0xc7af, 0x37d2,
+ 0xc7b0, 0x3f4d,
+ 0xc7b1, 0x43ae,
+ 0xc7b2, 0x3e7e,
+ 0xc7b3, 0x40bc,
+ 0xc7b4, 0x3e63,
+ 0xc7b5, 0x40bd,
+ 0xc7b6, 0x43af,
+ 0xc7b7, 0x40b7,
+ 0xc7b8, 0x3eb7,
+ 0xc7b9, 0x3eed,
+ 0xc7ba, 0x3f6a,
+ 0xc7bb, 0x3e95,
+ 0xc7bc, 0x3948,
+ 0xc7bd, 0x3cc8,
+ 0xc7be, 0x43b1,
+ 0xc7c0, 0x40cc,
+ 0xc7c1, 0x3e86,
+ 0xc7c2, 0x3c7a,
+ 0xc7c3, 0x3c7d,
+ 0xc7c4, 0x43b4,
+ 0xc7c5, 0x40d1,
+ 0xc7c6, 0x3d72,
+ 0xc7c7, 0x3c26,
+ 0xc7c8, 0x36eb,
+ 0xc7c9, 0x40bf,
+ 0xc7ca, 0x4100,
+ 0xc7cb, 0x3c85,
+ 0xc7cc, 0x43b5,
+ 0xc7cd, 0x3a1d,
+ 0xc7ce, 0x37f5,
+ 0xc7cf, 0x36ee,
+ 0xc7d0, 0x3e5f,
+ 0xc7d1, 0x4116,
+ 0xc7d2, 0x411f,
+ 0xc7d3, 0x4118,
+ 0xc7d4, 0x4123,
+ 0xc7d5, 0x4127,
+ 0xc7d6, 0x4129,
+ 0xc7d7, 0x43bc,
+ 0xc7d9, 0x3e8e,
+ 0xc7da, 0x386f,
+ 0xc7db, 0x4143,
+ 0xc7dc, 0x4146,
+ 0xc7dd, 0x4144,
+ 0xc7de, 0x4149,
+ 0xc7df, 0x3ba5,
+ 0xc7e0, 0x4157,
+ 0xc7e1, 0x4161,
+ 0xc7e2, 0x36ec,
+ 0xc7e3, 0x416a,
+ 0xc7e4, 0x4002,
+ 0xc7e5, 0x4186,
+ 0xc7e6, 0x3fba,
+ 0xc7e7, 0x3f50,
+ 0xc7e8, 0x3e96,
+ 0xc7e9, 0x418a,
+ 0xc7ea, 0x3fc1,
+ 0xc7eb, 0x3d8f,
+ 0xc7ec, 0x43c1,
+ 0xc7ed, 0x3ea0,
+ 0xc7ee, 0x3f16,
+ 0xc7ef, 0x3e9d,
+ 0xc7f0, 0x4192,
+ 0xc7f1, 0x3a66,
+ 0xc7f2, 0x3e9c,
+ 0xc7f3, 0x3e90,
+ 0xc7f4, 0x419d,
+ 0xc7f5, 0x43c2,
+ 0xc7f7, 0x37a8,
+ 0xc7f8, 0x419e,
+ 0xc7f9, 0x4187,
+ 0xc7fa, 0x3ea2,
+ 0xc7fb, 0x3e87,
+ 0xc7fc, 0x3e84,
+ 0xc7fd, 0x3eae,
+ 0xc7fe, 0x3b74,
+ 0xc840, 0x3b75,
+ 0xc841, 0x3b72,
+ 0xc842, 0x3eb2,
+ 0xc843, 0x3eac,
+ 0xc844, 0x41ca,
+ 0xc845, 0x41f4,
+ 0xc846, 0x41d0,
+ 0xc847, 0x3aaa,
+ 0xc848, 0x41f5,
+ 0xc849, 0x41f8,
+ 0xc84a, 0x41fb,
+ 0xc84b, 0x4205,
+ 0xc84c, 0x3d8e,
+ 0xc84d, 0x420e,
+ 0xc84e, 0x3d63,
+ 0xc84f, 0x4222,
+ 0xc850, 0x4221,
+ 0xc851, 0x4223,
+ 0xc852, 0x4069,
+ 0xc853, 0x402f,
+ 0xc854, 0x38a5,
+ 0xc855, 0x3cf5,
+ 0xc856, 0x3d69,
+ 0xc857, 0x425b,
+ 0xc858, 0x3ac8,
+ 0xc859, 0x3dc0,
+ 0xc85a, 0x39ea,
+ 0xc85b, 0x4000,
+ 0xc85c, 0x4264,
+ 0xc85d, 0x4262,
+ 0xc85e, 0x3fff,
+ 0xc85f, 0x3e9a,
+ 0xc860, 0x4273,
+ 0xc861, 0x3969,
+ 0xc862, 0x427a,
+ 0xc863, 0x43ca,
+ 0xc864, 0x3f9a,
+ 0xc865, 0x3eb5,
+ 0xc866, 0x43cb,
+ 0xc868, 0x3fb2,
+ 0xc869, 0x428a,
+ 0xc86c, 0x3adf,
+ 0xc86d, 0x42c8,
+ 0xc86e, 0x3ead,
+ 0xc86f, 0x43ce,
+ 0xc870, 0x3f8f,
+ 0xc871, 0x43cf,
+ 0xc872, 0x3e72,
+ 0xc873, 0x3eaa,
+ 0xc874, 0x43d3,
+ 0xc875, 0x42e0,
+ 0xc876, 0x382d,
+ 0xc877, 0x3fd5,
+ 0xc878, 0x3b14,
+ 0xc879, 0x36e8,
+ 0xc87a, 0x42f0,
+ 0xc87b, 0x3e7d,
+ 0xc87c, 0x42fe,
+ 0xc87d, 0x4305,
+ 0xc87e, 0x373a,
+ 0xc8a1, 0x3746,
+ 0xc8a2, 0x3752,
+ 0xc8a3, 0x36ed,
+ 0xc8a4, 0x3b4a,
+ 0xc8a5, 0x3b45,
+ 0xc8a6, 0x43da,
+ 0xc8a7, 0x3ede,
+ 0xc8a8, 0x376c,
+ 0xc8a9, 0x376b,
+ 0xc8aa, 0x3782,
+ 0xc8ab, 0x3e69,
+ 0xc8ac, 0x3b4f,
+ 0xc8ad, 0x3786,
+ 0xc8ae, 0x43db,
+ 0xc8af, 0x3788,
+ 0xc8b0, 0x43dc,
+ 0xc8b1, 0x3ecd,
+ 0xc8b2, 0x3797,
+ 0xc8b3, 0x420d,
+ 0xc8b4, 0x37d8,
+ 0xc8b5, 0x3b71,
+ 0xc8b6, 0x38dc,
+ 0xc8b7, 0x37e0,
+ 0xc8b8, 0x37f4,
+ 0xc8b9, 0x3813,
+ 0xc8ba, 0x3eb0,
+ 0xc8bb, 0x380d,
+ 0xc8bc, 0x3eaf,
+ 0xc8bd, 0x381b,
+ 0xc8bf, 0x381e,
+ 0xc8c1, 0x3eb1,
+ 0xc8c2, 0x3fe9,
+ 0xc8c3, 0x43e4,
+ 0xc8c4, 0x3ff9,
+ 0xc8c5, 0x3e59,
+ 0xc8c6, 0x3e99,
+ 0xc8c7, 0x3e5e,
+ 0xc8c8, 0x3bb4,
+ 0xc8c9, 0x3eab,
+ 0xc8ca, 0x43e7,
+ 0xc8cc, 0x385e,
+ 0xc8cd, 0x43e9,
+ 0xc8ce, 0x3dbe,
+ 0xc8cf, 0x3e85,
+ 0xc8d0, 0x3863,
+ 0xc8d2, 0x3d6c,
+ 0xc8d3, 0x3871,
+ 0xc8d4, 0x387c,
+ 0xc8d5, 0x3882,
+ 0xc8d6, 0x3e9b,
+ 0xc8d7, 0x3888,
+ 0xc8d8, 0x3c0e,
+ 0xc8d9, 0x382e,
+ 0xc8da, 0x389a,
+ 0xc8db, 0x388b,
+ 0xc8dc, 0x3c04,
+ 0xc8dd, 0x36e9,
+ 0xc8de, 0x42bd,
+ 0xc8df, 0x3bcd,
+ 0xc8e0, 0x389f,
+ 0xc8e1, 0x379b,
+ 0xc8e2, 0x38af,
+ 0xc8e3, 0x3e97,
+ 0xc8e4, 0x38f0,
+ 0xc8e5, 0x3bfd,
+ 0xc8e6, 0x3c11,
+ 0xc8e8, 0x43ef,
+ 0xc8e9, 0x3785,
+ 0xc8ea, 0x3902,
+ 0xc8eb, 0x3faa,
+ 0xc8ec, 0x3f19,
+ 0xc8ed, 0x3919,
+ 0xc8ee, 0x43f1,
+ 0xc8ef, 0x391a,
+ 0xc8f1, 0x3e66,
+ 0xc8f2, 0x3f22,
+ 0xc8f3, 0x3d7e,
+ 0xc8f4, 0x3c39,
+ 0xc8f5, 0x3ea1,
+ 0xc8f6, 0x43f2,
+ 0xc8f8, 0x3f30,
+ 0xc8f9, 0x3929,
+ 0xc8fa, 0x3fbc,
+ 0xc8fb, 0x3936,
+ 0xc8fd, 0x3f90,
+ 0xc8fe, 0x0aba,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xa14b, 0x354e,
+ 0xa15a, 0x35af,
+ 0xa15c, 0x35b1,
+ 0xa15d, 0x0082,
+ 0xa161, 0x0086,
+ 0xa165, 0x008a,
+ 0xa169, 0x008e,
+ 0xa16d, 0x0092,
+ 0xa171, 0x0096,
+ 0xa175, 0x009a,
+ 0xa179, 0x009e,
+ 0xa1e3, 0x354f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKm314B5VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKm314B5VMap2, 555
+};
+
+static Gushort cns13HKm471B5HMap2[1380] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xfa40, 0x3d6d,
+ 0xfa41, 0x39c4,
+ 0xfa42, 0x4399,
+ 0xfa43, 0x3f4f,
+ 0xfa44, 0x3e05,
+ 0xfa45, 0x439a,
+ 0xfa46, 0x3b8e,
+ 0xfa47, 0x36ea,
+ 0xfa48, 0x39c8,
+ 0xfa49, 0x393d,
+ 0xfa4a, 0x439b,
+ 0xfa4b, 0x4022,
+ 0xfa4c, 0x39cc,
+ 0xfa4e, 0x439c,
+ 0xfa4f, 0x39c5,
+ 0xfa50, 0x439d,
+ 0xfa51, 0x4034,
+ 0xfa52, 0x439e,
+ 0xfa54, 0x3ea3,
+ 0xfa55, 0x3ea6,
+ 0xfa56, 0x43a0,
+ 0xfa57, 0x4051,
+ 0xfa58, 0x4048,
+ 0xfa5a, 0x404b,
+ 0xfa5b, 0x404f,
+ 0xfa5c, 0x4054,
+ 0xfa5d, 0x4178,
+ 0xfa5e, 0x3f0a,
+ 0xfa5f, 0x43a1,
+ 0xfa61, 0x405a,
+ 0xfa62, 0x3ea4,
+ 0xfa63, 0x3dbd,
+ 0xfa64, 0x43a3,
+ 0xfa65, 0x3dbf,
+ 0xfa66, 0x405c,
+ 0xfa67, 0x405f,
+ 0xfa69, 0x4063,
+ 0xfa6a, 0x43a4,
+ 0xfa6b, 0x407a,
+ 0xfa6d, 0x407d,
+ 0xfa6e, 0x4082,
+ 0xfa6f, 0x3f6d,
+ 0xfa70, 0x43a5,
+ 0xfa71, 0x408b,
+ 0xfa72, 0x43a6,
+ 0xfa73, 0x3f39,
+ 0xfa74, 0x4093,
+ 0xfa75, 0x4096,
+ 0xfa76, 0x43a7,
+ 0xfa77, 0x4098,
+ 0xfa78, 0x3e7f,
+ 0xfa79, 0x3c77,
+ 0xfa7a, 0x3ea7,
+ 0xfa7b, 0x4203,
+ 0xfa7c, 0x3ed1,
+ 0xfa7d, 0x3e8a,
+ 0xfa7e, 0x3e98,
+ 0xfaa1, 0x3e8c,
+ 0xfaa2, 0x40a1,
+ 0xfaa3, 0x3d83,
+ 0xfaa4, 0x3a00,
+ 0xfaa5, 0x39a3,
+ 0xfaa6, 0x3e8d,
+ 0xfaa7, 0x43a8,
+ 0xfaa8, 0x3f58,
+ 0xfaa9, 0x3dbc,
+ 0xfaaa, 0x40a2,
+ 0xfaab, 0x3ccc,
+ 0xfaac, 0x3ea8,
+ 0xfaae, 0x3b2e,
+ 0xfaaf, 0x3bc6,
+ 0xfab0, 0x3e8b,
+ 0xfab1, 0x3e9f,
+ 0xfab2, 0x432c,
+ 0xfab3, 0x43a9,
+ 0xfab4, 0x3f08,
+ 0xfab5, 0x3ea5,
+ 0xfab6, 0x3e89,
+ 0xfab7, 0x3dc3,
+ 0xfab8, 0x3e82,
+ 0xfab9, 0x3e81,
+ 0xfaba, 0x3e94,
+ 0xfabb, 0x43aa,
+ 0xfabc, 0x3e83,
+ 0xfabd, 0x3e88,
+ 0xfabe, 0x43ab,
+ 0xfabf, 0x3e91,
+ 0xfac0, 0x43ac,
+ 0xfac1, 0x3e7c,
+ 0xfac2, 0x3e80,
+ 0xfac3, 0x3e8f,
+ 0xfac4, 0x4325,
+ 0xfac5, 0x3e67,
+ 0xfac6, 0x3e78,
+ 0xfac7, 0x3e68,
+ 0xfac8, 0x43ad,
+ 0xfac9, 0x37d2,
+ 0xfaca, 0x3f4d,
+ 0xfacb, 0x43ae,
+ 0xfacc, 0x3e7e,
+ 0xfacd, 0x40bc,
+ 0xface, 0x3e63,
+ 0xfacf, 0x40bd,
+ 0xfad0, 0x43af,
+ 0xfad1, 0x3f6c,
+ 0xfad2, 0x3ef9,
+ 0xfad3, 0x40b7,
+ 0xfad4, 0x3eb7,
+ 0xfad5, 0x3eed,
+ 0xfad6, 0x3f6a,
+ 0xfad7, 0x39a6,
+ 0xfad8, 0x43b0,
+ 0xfad9, 0x3e95,
+ 0xfada, 0x3948,
+ 0xfadb, 0x3cc8,
+ 0xfadc, 0x43b1,
+ 0xfadf, 0x40cc,
+ 0xfae0, 0x3e86,
+ 0xfae1, 0x40c8,
+ 0xfae2, 0x3c7a,
+ 0xfae3, 0x3c7d,
+ 0xfae4, 0x43b4,
+ 0xfae5, 0x40d1,
+ 0xfae6, 0x3d72,
+ 0xfae7, 0x40d4,
+ 0xfae8, 0x3c26,
+ 0xfae9, 0x36eb,
+ 0xfaea, 0x40da,
+ 0xfaeb, 0x40d9,
+ 0xfaec, 0x40bf,
+ 0xfaed, 0x3d81,
+ 0xfaee, 0x40f1,
+ 0xfaef, 0x4100,
+ 0xfaf0, 0x3c85,
+ 0xfaf1, 0x43b5,
+ 0xfaf2, 0x3a1d,
+ 0xfaf3, 0x37f5,
+ 0xfaf4, 0x36ee,
+ 0xfaf5, 0x3e5f,
+ 0xfaf6, 0x4116,
+ 0xfaf7, 0x42bb,
+ 0xfaf8, 0x411f,
+ 0xfaf9, 0x43b6,
+ 0xfafa, 0x4118,
+ 0xfafb, 0x43b7,
+ 0xfafd, 0x4123,
+ 0xfafe, 0x4122,
+ 0xfb40, 0x4127,
+ 0xfb41, 0x43b9,
+ 0xfb42, 0x4129,
+ 0xfb43, 0x43ba,
+ 0xfb44, 0x3dd5,
+ 0xfb45, 0x3eef,
+ 0xfb46, 0x3d8a,
+ 0xfb47, 0x43bb,
+ 0xfb48, 0x3a2b,
+ 0xfb49, 0x43bc,
+ 0xfb4a, 0x4138,
+ 0xfb4b, 0x43bd,
+ 0xfb4c, 0x3e8e,
+ 0xfb4d, 0x3a30,
+ 0xfb4e, 0x386f,
+ 0xfb4f, 0x4143,
+ 0xfb50, 0x4146,
+ 0xfb51, 0x4144,
+ 0xfb52, 0x4149,
+ 0xfb53, 0x3ba5,
+ 0xfb54, 0x4157,
+ 0xfb55, 0x43be,
+ 0xfb56, 0x4161,
+ 0xfb57, 0x36ec,
+ 0xfb58, 0x416a,
+ 0xfb59, 0x3d84,
+ 0xfb5a, 0x4002,
+ 0xfb5b, 0x4186,
+ 0xfb5c, 0x3fba,
+ 0xfb5d, 0x43bf,
+ 0xfb5e, 0x3fc5,
+ 0xfb5f, 0x3f50,
+ 0xfb60, 0x3e96,
+ 0xfb61, 0x43c0,
+ 0xfb62, 0x418a,
+ 0xfb63, 0x3fc1,
+ 0xfb64, 0x3d8f,
+ 0xfb65, 0x43c1,
+ 0xfb66, 0x3ea0,
+ 0xfb67, 0x3f16,
+ 0xfb68, 0x3e9d,
+ 0xfb69, 0x418e,
+ 0xfb6a, 0x4192,
+ 0xfb6b, 0x3a66,
+ 0xfb6c, 0x3e9c,
+ 0xfb6d, 0x438f,
+ 0xfb6e, 0x3e90,
+ 0xfb6f, 0x419d,
+ 0xfb70, 0x43c2,
+ 0xfb72, 0x4356,
+ 0xfb73, 0x37a8,
+ 0xfb74, 0x419e,
+ 0xfb75, 0x4199,
+ 0xfb76, 0x4187,
+ 0xfb77, 0x3ea2,
+ 0xfb78, 0x419f,
+ 0xfb79, 0x3e87,
+ 0xfb7a, 0x3e84,
+ 0xfb7b, 0x3eae,
+ 0xfb7c, 0x3b74,
+ 0xfb7e, 0x37a2,
+ 0xfba1, 0x3b72,
+ 0xfba2, 0x3e79,
+ 0xfba3, 0x3e6d,
+ 0xfba4, 0x43c4,
+ 0xfba6, 0x3eb2,
+ 0xfba7, 0x43c6,
+ 0xfba8, 0x3eac,
+ 0xfba9, 0x41ca,
+ 0xfbaa, 0x41f4,
+ 0xfbab, 0x43c7,
+ 0xfbac, 0x41d0,
+ 0xfbad, 0x3aaa,
+ 0xfbae, 0x41de,
+ 0xfbaf, 0x41db,
+ 0xfbb0, 0x41e8,
+ 0xfbb1, 0x43c8,
+ 0xfbb2, 0x3ff6,
+ 0xfbb3, 0x41d9,
+ 0xfbb4, 0x3d42,
+ 0xfbb5, 0x41f5,
+ 0xfbb6, 0x41f8,
+ 0xfbb7, 0x41fb,
+ 0xfbb8, 0x4205,
+ 0xfbb9, 0x3d8e,
+ 0xfbba, 0x420e,
+ 0xfbbb, 0x3d63,
+ 0xfbbc, 0x4222,
+ 0xfbbd, 0x4221,
+ 0xfbbe, 0x4223,
+ 0xfbbf, 0x4069,
+ 0xfbc0, 0x402f,
+ 0xfbc1, 0x4242,
+ 0xfbc2, 0x38a5,
+ 0xfbc3, 0x4246,
+ 0xfbc4, 0x3cf5,
+ 0xfbc5, 0x3d69,
+ 0xfbc6, 0x3cfe,
+ 0xfbc7, 0x425b,
+ 0xfbc8, 0x3ac8,
+ 0xfbc9, 0x3dc0,
+ 0xfbca, 0x39ea,
+ 0xfbcb, 0x4000,
+ 0xfbcc, 0x4264,
+ 0xfbcd, 0x4262,
+ 0xfbce, 0x3fff,
+ 0xfbcf, 0x3e9a,
+ 0xfbd0, 0x4273,
+ 0xfbd1, 0x3969,
+ 0xfbd2, 0x427a,
+ 0xfbd3, 0x4283,
+ 0xfbd4, 0x43c9,
+ 0xfbd6, 0x3f9a,
+ 0xfbd7, 0x3eb5,
+ 0xfbd8, 0x43cb,
+ 0xfbda, 0x3fb2,
+ 0xfbdb, 0x428a,
+ 0xfbdd, 0x3b17,
+ 0xfbde, 0x428c,
+ 0xfbdf, 0x4290,
+ 0xfbe0, 0x3adf,
+ 0xfbe1, 0x43cd,
+ 0xfbe2, 0x42c5,
+ 0xfbe3, 0x42c8,
+ 0xfbe4, 0x3ead,
+ 0xfbe5, 0x43ce,
+ 0xfbe6, 0x3f8f,
+ 0xfbe7, 0x43cf,
+ 0xfbe8, 0x3e72,
+ 0xfbe9, 0x3e70,
+ 0xfbea, 0x43d0,
+ 0xfbeb, 0x3eaa,
+ 0xfbec, 0x43d1,
+ 0xfbed, 0x3fa9,
+ 0xfbee, 0x43d2,
+ 0xfbf1, 0x42d8,
+ 0xfbf2, 0x3ff3,
+ 0xfbf3, 0x42e0,
+ 0xfbf4, 0x3b00,
+ 0xfbf5, 0x4317,
+ 0xfbf6, 0x382d,
+ 0xfbf7, 0x3e73,
+ 0xfbf8, 0x3fd5,
+ 0xfbf9, 0x43d5,
+ 0xfbfb, 0x3b14,
+ 0xfbfc, 0x36e8,
+ 0xfbfd, 0x42f4,
+ 0xfbfe, 0x3b0e,
+ 0xfc40, 0x42ec,
+ 0xfc41, 0x42f0,
+ 0xfc42, 0x3e7d,
+ 0xfc43, 0x43d7,
+ 0xfc44, 0x42fe,
+ 0xfc45, 0x4305,
+ 0xfc46, 0x3fda,
+ 0xfc47, 0x3df1,
+ 0xfc48, 0x3733,
+ 0xfc49, 0x3d7d,
+ 0xfc4a, 0x43d8,
+ 0xfc4b, 0x373a,
+ 0xfc4c, 0x3740,
+ 0xfc4d, 0x3742,
+ 0xfc4e, 0x3746,
+ 0xfc4f, 0x3752,
+ 0xfc50, 0x3f1f,
+ 0xfc51, 0x43d9,
+ 0xfc52, 0x36ed,
+ 0xfc53, 0x3b4a,
+ 0xfc54, 0x375e,
+ 0xfc55, 0x3b45,
+ 0xfc56, 0x43da,
+ 0xfc57, 0x3ede,
+ 0xfc58, 0x3769,
+ 0xfc59, 0x376c,
+ 0xfc5a, 0x376b,
+ 0xfc5b, 0x376e,
+ 0xfc5c, 0x377f,
+ 0xfc5d, 0x377b,
+ 0xfc5e, 0x3782,
+ 0xfc5f, 0x3e69,
+ 0xfc60, 0x3b4f,
+ 0xfc61, 0x3786,
+ 0xfc62, 0x43db,
+ 0xfc63, 0x3788,
+ 0xfc64, 0x43dc,
+ 0xfc65, 0x3ecd,
+ 0xfc66, 0x3797,
+ 0xfc67, 0x420d,
+ 0xfc68, 0x43dd,
+ 0xfc69, 0x37bc,
+ 0xfc6a, 0x43de,
+ 0xfc6b, 0x37d8,
+ 0xfc6c, 0x3b71,
+ 0xfc6d, 0x3e7a,
+ 0xfc6e, 0x43df,
+ 0xfc6f, 0x38dc,
+ 0xfc70, 0x37e0,
+ 0xfc71, 0x37ee,
+ 0xfc72, 0x37f4,
+ 0xfc73, 0x3813,
+ 0xfc74, 0x43e0,
+ 0xfc76, 0x3eb0,
+ 0xfc77, 0x43e2,
+ 0xfc78, 0x3fed,
+ 0xfc79, 0x380d,
+ 0xfc7a, 0x3eaf,
+ 0xfc7b, 0x3f92,
+ 0xfc7c, 0x3816,
+ 0xfc7d, 0x381b,
+ 0xfc7e, 0x3fa2,
+ 0xfca1, 0x381c,
+ 0xfca2, 0x381e,
+ 0xfca4, 0x3eb1,
+ 0xfca5, 0x134a,
+ 0xfca6, 0x43e3,
+ 0xfca7, 0x3fe9,
+ 0xfca8, 0x43e4,
+ 0xfca9, 0x3ff9,
+ 0xfcaa, 0x3d93,
+ 0xfcab, 0x43e5,
+ 0xfcac, 0x3e59,
+ 0xfcad, 0x43e6,
+ 0xfcae, 0x3837,
+ 0xfcaf, 0x3f99,
+ 0xfcb0, 0x3e99,
+ 0xfcb1, 0x3e5e,
+ 0xfcb2, 0x3bb4,
+ 0xfcb3, 0x3eab,
+ 0xfcb4, 0x43e7,
+ 0xfcb6, 0x385e,
+ 0xfcb7, 0x43e9,
+ 0xfcb8, 0x3dbe,
+ 0xfcb9, 0x3e85,
+ 0xfcba, 0x3863,
+ 0xfcbc, 0x3d6c,
+ 0xfcbd, 0x3871,
+ 0xfcbe, 0x3ee0,
+ 0xfcbf, 0x43ea,
+ 0xfcc0, 0x387c,
+ 0xfcc1, 0x43eb,
+ 0xfcc2, 0x3eb8,
+ 0xfcc3, 0x3882,
+ 0xfcc4, 0x3e9b,
+ 0xfcc5, 0x43ec,
+ 0xfcc6, 0x3888,
+ 0xfcc7, 0x3c0e,
+ 0xfcc8, 0x382e,
+ 0xfcc9, 0x389a,
+ 0xfcca, 0x388b,
+ 0xfccb, 0x3c04,
+ 0xfccc, 0x36e9,
+ 0xfccd, 0x42bd,
+ 0xfcce, 0x3bcd,
+ 0xfccf, 0x389f,
+ 0xfcd0, 0x3dde,
+ 0xfcd1, 0x379b,
+ 0xfcd2, 0x3bd3,
+ 0xfcd3, 0x38af,
+ 0xfcd4, 0x3e97,
+ 0xfcd5, 0x38d6,
+ 0xfcd6, 0x3f35,
+ 0xfcd7, 0x38e0,
+ 0xfcd8, 0x4035,
+ 0xfcd9, 0x38f0,
+ 0xfcda, 0x43ed,
+ 0xfcdc, 0x3bfd,
+ 0xfcdd, 0x3c11,
+ 0xfcdf, 0x43ef,
+ 0xfce0, 0x3785,
+ 0xfce1, 0x3902,
+ 0xfce2, 0x3ddc,
+ 0xfce3, 0x43f0,
+ 0xfce4, 0x3faa,
+ 0xfce5, 0x390b,
+ 0xfce6, 0x3f19,
+ 0xfce7, 0x390e,
+ 0xfce8, 0x3919,
+ 0xfce9, 0x43f1,
+ 0xfcea, 0x3c3c,
+ 0xfceb, 0x391a,
+ 0xfcec, 0x3c3a,
+ 0xfced, 0x391b,
+ 0xfcee, 0x3e66,
+ 0xfcef, 0x3f22,
+ 0xfcf0, 0x3d7e,
+ 0xfcf1, 0x3e71,
+ 0xfcf2, 0x3c39,
+ 0xfcf3, 0x3ea1,
+ 0xfcf4, 0x43f2,
+ 0xfcf6, 0x3f30,
+ 0xfcf7, 0x3929,
+ 0xfcf8, 0x3fbc,
+ 0xfcf9, 0x3936,
+ 0xfcfa, 0x43f4,
+ 0xfcfb, 0x3937,
+ 0xfcfc, 0x3f90,
+ 0xfcfd, 0x43f5,
+ 0xfcfe, 0x0aba,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKm471B5HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKm471B5HMap2, 690
+};
+
+static Gushort cns13HKm471B5VMap2[1404] = {
+ 0x0000, 0x0000,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xfa40, 0x3d6d,
+ 0xfa41, 0x39c4,
+ 0xfa42, 0x4399,
+ 0xfa43, 0x3f4f,
+ 0xfa44, 0x3e05,
+ 0xfa45, 0x439a,
+ 0xfa46, 0x3b8e,
+ 0xfa47, 0x36ea,
+ 0xfa48, 0x39c8,
+ 0xfa49, 0x393d,
+ 0xfa4a, 0x439b,
+ 0xfa4b, 0x4022,
+ 0xfa4c, 0x39cc,
+ 0xfa4e, 0x439c,
+ 0xfa4f, 0x39c5,
+ 0xfa50, 0x439d,
+ 0xfa51, 0x4034,
+ 0xfa52, 0x439e,
+ 0xfa54, 0x3ea3,
+ 0xfa55, 0x3ea6,
+ 0xfa56, 0x43a0,
+ 0xfa57, 0x4051,
+ 0xfa58, 0x4048,
+ 0xfa5a, 0x404b,
+ 0xfa5b, 0x404f,
+ 0xfa5c, 0x4054,
+ 0xfa5d, 0x4178,
+ 0xfa5e, 0x3f0a,
+ 0xfa5f, 0x43a1,
+ 0xfa61, 0x405a,
+ 0xfa62, 0x3ea4,
+ 0xfa63, 0x3dbd,
+ 0xfa64, 0x43a3,
+ 0xfa65, 0x3dbf,
+ 0xfa66, 0x405c,
+ 0xfa67, 0x405f,
+ 0xfa69, 0x4063,
+ 0xfa6a, 0x43a4,
+ 0xfa6b, 0x407a,
+ 0xfa6d, 0x407d,
+ 0xfa6e, 0x4082,
+ 0xfa6f, 0x3f6d,
+ 0xfa70, 0x43a5,
+ 0xfa71, 0x408b,
+ 0xfa72, 0x43a6,
+ 0xfa73, 0x3f39,
+ 0xfa74, 0x4093,
+ 0xfa75, 0x4096,
+ 0xfa76, 0x43a7,
+ 0xfa77, 0x4098,
+ 0xfa78, 0x3e7f,
+ 0xfa79, 0x3c77,
+ 0xfa7a, 0x3ea7,
+ 0xfa7b, 0x4203,
+ 0xfa7c, 0x3ed1,
+ 0xfa7d, 0x3e8a,
+ 0xfa7e, 0x3e98,
+ 0xfaa1, 0x3e8c,
+ 0xfaa2, 0x40a1,
+ 0xfaa3, 0x3d83,
+ 0xfaa4, 0x3a00,
+ 0xfaa5, 0x39a3,
+ 0xfaa6, 0x3e8d,
+ 0xfaa7, 0x43a8,
+ 0xfaa8, 0x3f58,
+ 0xfaa9, 0x3dbc,
+ 0xfaaa, 0x40a2,
+ 0xfaab, 0x3ccc,
+ 0xfaac, 0x3ea8,
+ 0xfaae, 0x3b2e,
+ 0xfaaf, 0x3bc6,
+ 0xfab0, 0x3e8b,
+ 0xfab1, 0x3e9f,
+ 0xfab2, 0x432c,
+ 0xfab3, 0x43a9,
+ 0xfab4, 0x3f08,
+ 0xfab5, 0x3ea5,
+ 0xfab6, 0x3e89,
+ 0xfab7, 0x3dc3,
+ 0xfab8, 0x3e82,
+ 0xfab9, 0x3e81,
+ 0xfaba, 0x3e94,
+ 0xfabb, 0x43aa,
+ 0xfabc, 0x3e83,
+ 0xfabd, 0x3e88,
+ 0xfabe, 0x43ab,
+ 0xfabf, 0x3e91,
+ 0xfac0, 0x43ac,
+ 0xfac1, 0x3e7c,
+ 0xfac2, 0x3e80,
+ 0xfac3, 0x3e8f,
+ 0xfac4, 0x4325,
+ 0xfac5, 0x3e67,
+ 0xfac6, 0x3e78,
+ 0xfac7, 0x3e68,
+ 0xfac8, 0x43ad,
+ 0xfac9, 0x37d2,
+ 0xfaca, 0x3f4d,
+ 0xfacb, 0x43ae,
+ 0xfacc, 0x3e7e,
+ 0xfacd, 0x40bc,
+ 0xface, 0x3e63,
+ 0xfacf, 0x40bd,
+ 0xfad0, 0x43af,
+ 0xfad1, 0x3f6c,
+ 0xfad2, 0x3ef9,
+ 0xfad3, 0x40b7,
+ 0xfad4, 0x3eb7,
+ 0xfad5, 0x3eed,
+ 0xfad6, 0x3f6a,
+ 0xfad7, 0x39a6,
+ 0xfad8, 0x43b0,
+ 0xfad9, 0x3e95,
+ 0xfada, 0x3948,
+ 0xfadb, 0x3cc8,
+ 0xfadc, 0x43b1,
+ 0xfadf, 0x40cc,
+ 0xfae0, 0x3e86,
+ 0xfae1, 0x40c8,
+ 0xfae2, 0x3c7a,
+ 0xfae3, 0x3c7d,
+ 0xfae4, 0x43b4,
+ 0xfae5, 0x40d1,
+ 0xfae6, 0x3d72,
+ 0xfae7, 0x40d4,
+ 0xfae8, 0x3c26,
+ 0xfae9, 0x36eb,
+ 0xfaea, 0x40da,
+ 0xfaeb, 0x40d9,
+ 0xfaec, 0x40bf,
+ 0xfaed, 0x3d81,
+ 0xfaee, 0x40f1,
+ 0xfaef, 0x4100,
+ 0xfaf0, 0x3c85,
+ 0xfaf1, 0x43b5,
+ 0xfaf2, 0x3a1d,
+ 0xfaf3, 0x37f5,
+ 0xfaf4, 0x36ee,
+ 0xfaf5, 0x3e5f,
+ 0xfaf6, 0x4116,
+ 0xfaf7, 0x42bb,
+ 0xfaf8, 0x411f,
+ 0xfaf9, 0x43b6,
+ 0xfafa, 0x4118,
+ 0xfafb, 0x43b7,
+ 0xfafd, 0x4123,
+ 0xfafe, 0x4122,
+ 0xfb40, 0x4127,
+ 0xfb41, 0x43b9,
+ 0xfb42, 0x4129,
+ 0xfb43, 0x43ba,
+ 0xfb44, 0x3dd5,
+ 0xfb45, 0x3eef,
+ 0xfb46, 0x3d8a,
+ 0xfb47, 0x43bb,
+ 0xfb48, 0x3a2b,
+ 0xfb49, 0x43bc,
+ 0xfb4a, 0x4138,
+ 0xfb4b, 0x43bd,
+ 0xfb4c, 0x3e8e,
+ 0xfb4d, 0x3a30,
+ 0xfb4e, 0x386f,
+ 0xfb4f, 0x4143,
+ 0xfb50, 0x4146,
+ 0xfb51, 0x4144,
+ 0xfb52, 0x4149,
+ 0xfb53, 0x3ba5,
+ 0xfb54, 0x4157,
+ 0xfb55, 0x43be,
+ 0xfb56, 0x4161,
+ 0xfb57, 0x36ec,
+ 0xfb58, 0x416a,
+ 0xfb59, 0x3d84,
+ 0xfb5a, 0x4002,
+ 0xfb5b, 0x4186,
+ 0xfb5c, 0x3fba,
+ 0xfb5d, 0x43bf,
+ 0xfb5e, 0x3fc5,
+ 0xfb5f, 0x3f50,
+ 0xfb60, 0x3e96,
+ 0xfb61, 0x43c0,
+ 0xfb62, 0x418a,
+ 0xfb63, 0x3fc1,
+ 0xfb64, 0x3d8f,
+ 0xfb65, 0x43c1,
+ 0xfb66, 0x3ea0,
+ 0xfb67, 0x3f16,
+ 0xfb68, 0x3e9d,
+ 0xfb69, 0x418e,
+ 0xfb6a, 0x4192,
+ 0xfb6b, 0x3a66,
+ 0xfb6c, 0x3e9c,
+ 0xfb6d, 0x438f,
+ 0xfb6e, 0x3e90,
+ 0xfb6f, 0x419d,
+ 0xfb70, 0x43c2,
+ 0xfb72, 0x4356,
+ 0xfb73, 0x37a8,
+ 0xfb74, 0x419e,
+ 0xfb75, 0x4199,
+ 0xfb76, 0x4187,
+ 0xfb77, 0x3ea2,
+ 0xfb78, 0x419f,
+ 0xfb79, 0x3e87,
+ 0xfb7a, 0x3e84,
+ 0xfb7b, 0x3eae,
+ 0xfb7c, 0x3b74,
+ 0xfb7e, 0x37a2,
+ 0xfba1, 0x3b72,
+ 0xfba2, 0x3e79,
+ 0xfba3, 0x3e6d,
+ 0xfba4, 0x43c4,
+ 0xfba6, 0x3eb2,
+ 0xfba7, 0x43c6,
+ 0xfba8, 0x3eac,
+ 0xfba9, 0x41ca,
+ 0xfbaa, 0x41f4,
+ 0xfbab, 0x43c7,
+ 0xfbac, 0x41d0,
+ 0xfbad, 0x3aaa,
+ 0xfbae, 0x41de,
+ 0xfbaf, 0x41db,
+ 0xfbb0, 0x41e8,
+ 0xfbb1, 0x43c8,
+ 0xfbb2, 0x3ff6,
+ 0xfbb3, 0x41d9,
+ 0xfbb4, 0x3d42,
+ 0xfbb5, 0x41f5,
+ 0xfbb6, 0x41f8,
+ 0xfbb7, 0x41fb,
+ 0xfbb8, 0x4205,
+ 0xfbb9, 0x3d8e,
+ 0xfbba, 0x420e,
+ 0xfbbb, 0x3d63,
+ 0xfbbc, 0x4222,
+ 0xfbbd, 0x4221,
+ 0xfbbe, 0x4223,
+ 0xfbbf, 0x4069,
+ 0xfbc0, 0x402f,
+ 0xfbc1, 0x4242,
+ 0xfbc2, 0x38a5,
+ 0xfbc3, 0x4246,
+ 0xfbc4, 0x3cf5,
+ 0xfbc5, 0x3d69,
+ 0xfbc6, 0x3cfe,
+ 0xfbc7, 0x425b,
+ 0xfbc8, 0x3ac8,
+ 0xfbc9, 0x3dc0,
+ 0xfbca, 0x39ea,
+ 0xfbcb, 0x4000,
+ 0xfbcc, 0x4264,
+ 0xfbcd, 0x4262,
+ 0xfbce, 0x3fff,
+ 0xfbcf, 0x3e9a,
+ 0xfbd0, 0x4273,
+ 0xfbd1, 0x3969,
+ 0xfbd2, 0x427a,
+ 0xfbd3, 0x4283,
+ 0xfbd4, 0x43c9,
+ 0xfbd6, 0x3f9a,
+ 0xfbd7, 0x3eb5,
+ 0xfbd8, 0x43cb,
+ 0xfbda, 0x3fb2,
+ 0xfbdb, 0x428a,
+ 0xfbdd, 0x3b17,
+ 0xfbde, 0x428c,
+ 0xfbdf, 0x4290,
+ 0xfbe0, 0x3adf,
+ 0xfbe1, 0x43cd,
+ 0xfbe2, 0x42c5,
+ 0xfbe3, 0x42c8,
+ 0xfbe4, 0x3ead,
+ 0xfbe5, 0x43ce,
+ 0xfbe6, 0x3f8f,
+ 0xfbe7, 0x43cf,
+ 0xfbe8, 0x3e72,
+ 0xfbe9, 0x3e70,
+ 0xfbea, 0x43d0,
+ 0xfbeb, 0x3eaa,
+ 0xfbec, 0x43d1,
+ 0xfbed, 0x3fa9,
+ 0xfbee, 0x43d2,
+ 0xfbf1, 0x42d8,
+ 0xfbf2, 0x3ff3,
+ 0xfbf3, 0x42e0,
+ 0xfbf4, 0x3b00,
+ 0xfbf5, 0x4317,
+ 0xfbf6, 0x382d,
+ 0xfbf7, 0x3e73,
+ 0xfbf8, 0x3fd5,
+ 0xfbf9, 0x43d5,
+ 0xfbfb, 0x3b14,
+ 0xfbfc, 0x36e8,
+ 0xfbfd, 0x42f4,
+ 0xfbfe, 0x3b0e,
+ 0xfc40, 0x42ec,
+ 0xfc41, 0x42f0,
+ 0xfc42, 0x3e7d,
+ 0xfc43, 0x43d7,
+ 0xfc44, 0x42fe,
+ 0xfc45, 0x4305,
+ 0xfc46, 0x3fda,
+ 0xfc47, 0x3df1,
+ 0xfc48, 0x3733,
+ 0xfc49, 0x3d7d,
+ 0xfc4a, 0x43d8,
+ 0xfc4b, 0x373a,
+ 0xfc4c, 0x3740,
+ 0xfc4d, 0x3742,
+ 0xfc4e, 0x3746,
+ 0xfc4f, 0x3752,
+ 0xfc50, 0x3f1f,
+ 0xfc51, 0x43d9,
+ 0xfc52, 0x36ed,
+ 0xfc53, 0x3b4a,
+ 0xfc54, 0x375e,
+ 0xfc55, 0x3b45,
+ 0xfc56, 0x43da,
+ 0xfc57, 0x3ede,
+ 0xfc58, 0x3769,
+ 0xfc59, 0x376c,
+ 0xfc5a, 0x376b,
+ 0xfc5b, 0x376e,
+ 0xfc5c, 0x377f,
+ 0xfc5d, 0x377b,
+ 0xfc5e, 0x3782,
+ 0xfc5f, 0x3e69,
+ 0xfc60, 0x3b4f,
+ 0xfc61, 0x3786,
+ 0xfc62, 0x43db,
+ 0xfc63, 0x3788,
+ 0xfc64, 0x43dc,
+ 0xfc65, 0x3ecd,
+ 0xfc66, 0x3797,
+ 0xfc67, 0x420d,
+ 0xfc68, 0x43dd,
+ 0xfc69, 0x37bc,
+ 0xfc6a, 0x43de,
+ 0xfc6b, 0x37d8,
+ 0xfc6c, 0x3b71,
+ 0xfc6d, 0x3e7a,
+ 0xfc6e, 0x43df,
+ 0xfc6f, 0x38dc,
+ 0xfc70, 0x37e0,
+ 0xfc71, 0x37ee,
+ 0xfc72, 0x37f4,
+ 0xfc73, 0x3813,
+ 0xfc74, 0x43e0,
+ 0xfc76, 0x3eb0,
+ 0xfc77, 0x43e2,
+ 0xfc78, 0x3fed,
+ 0xfc79, 0x380d,
+ 0xfc7a, 0x3eaf,
+ 0xfc7b, 0x3f92,
+ 0xfc7c, 0x3816,
+ 0xfc7d, 0x381b,
+ 0xfc7e, 0x3fa2,
+ 0xfca1, 0x381c,
+ 0xfca2, 0x381e,
+ 0xfca4, 0x3eb1,
+ 0xfca5, 0x134a,
+ 0xfca6, 0x43e3,
+ 0xfca7, 0x3fe9,
+ 0xfca8, 0x43e4,
+ 0xfca9, 0x3ff9,
+ 0xfcaa, 0x3d93,
+ 0xfcab, 0x43e5,
+ 0xfcac, 0x3e59,
+ 0xfcad, 0x43e6,
+ 0xfcae, 0x3837,
+ 0xfcaf, 0x3f99,
+ 0xfcb0, 0x3e99,
+ 0xfcb1, 0x3e5e,
+ 0xfcb2, 0x3bb4,
+ 0xfcb3, 0x3eab,
+ 0xfcb4, 0x43e7,
+ 0xfcb6, 0x385e,
+ 0xfcb7, 0x43e9,
+ 0xfcb8, 0x3dbe,
+ 0xfcb9, 0x3e85,
+ 0xfcba, 0x3863,
+ 0xfcbc, 0x3d6c,
+ 0xfcbd, 0x3871,
+ 0xfcbe, 0x3ee0,
+ 0xfcbf, 0x43ea,
+ 0xfcc0, 0x387c,
+ 0xfcc1, 0x43eb,
+ 0xfcc2, 0x3eb8,
+ 0xfcc3, 0x3882,
+ 0xfcc4, 0x3e9b,
+ 0xfcc5, 0x43ec,
+ 0xfcc6, 0x3888,
+ 0xfcc7, 0x3c0e,
+ 0xfcc8, 0x382e,
+ 0xfcc9, 0x389a,
+ 0xfcca, 0x388b,
+ 0xfccb, 0x3c04,
+ 0xfccc, 0x36e9,
+ 0xfccd, 0x42bd,
+ 0xfcce, 0x3bcd,
+ 0xfccf, 0x389f,
+ 0xfcd0, 0x3dde,
+ 0xfcd1, 0x379b,
+ 0xfcd2, 0x3bd3,
+ 0xfcd3, 0x38af,
+ 0xfcd4, 0x3e97,
+ 0xfcd5, 0x38d6,
+ 0xfcd6, 0x3f35,
+ 0xfcd7, 0x38e0,
+ 0xfcd8, 0x4035,
+ 0xfcd9, 0x38f0,
+ 0xfcda, 0x43ed,
+ 0xfcdc, 0x3bfd,
+ 0xfcdd, 0x3c11,
+ 0xfcdf, 0x43ef,
+ 0xfce0, 0x3785,
+ 0xfce1, 0x3902,
+ 0xfce2, 0x3ddc,
+ 0xfce3, 0x43f0,
+ 0xfce4, 0x3faa,
+ 0xfce5, 0x390b,
+ 0xfce6, 0x3f19,
+ 0xfce7, 0x390e,
+ 0xfce8, 0x3919,
+ 0xfce9, 0x43f1,
+ 0xfcea, 0x3c3c,
+ 0xfceb, 0x391a,
+ 0xfcec, 0x3c3a,
+ 0xfced, 0x391b,
+ 0xfcee, 0x3e66,
+ 0xfcef, 0x3f22,
+ 0xfcf0, 0x3d7e,
+ 0xfcf1, 0x3e71,
+ 0xfcf2, 0x3c39,
+ 0xfcf3, 0x3ea1,
+ 0xfcf4, 0x43f2,
+ 0xfcf6, 0x3f30,
+ 0xfcf7, 0x3929,
+ 0xfcf8, 0x3fbc,
+ 0xfcf9, 0x3936,
+ 0xfcfa, 0x43f4,
+ 0xfcfb, 0x3937,
+ 0xfcfc, 0x3f90,
+ 0xfcfd, 0x43f5,
+ 0xfcfe, 0x0aba,
+ 0xa14b, 0x354e,
+ 0xa15a, 0x35af,
+ 0xa15c, 0x35b1,
+ 0xa15d, 0x0082,
+ 0xa161, 0x0086,
+ 0xa165, 0x008a,
+ 0xa169, 0x008e,
+ 0xa16d, 0x0092,
+ 0xa171, 0x0096,
+ 0xa175, 0x009a,
+ 0xa179, 0x009e,
+ 0xa1e3, 0x354f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKm471B5VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKm471B5VMap2, 702
+};
+
+static Gushort cns13HKscsB5HMap2[2258] = {
+ 0x0000, 0x0000,
+ 0x8840, 0x44c9,
+ 0x8856, 0x4961,
+ 0x88a1, 0x498a,
+ 0x88a9, 0x499c,
+ 0x8940, 0x4534,
+ 0x8943, 0x4536,
+ 0x8946, 0x4537,
+ 0x894c, 0x453b,
+ 0x894d, 0x43c3,
+ 0x894e, 0x453c,
+ 0x8951, 0x439a,
+ 0x8952, 0x453f,
+ 0x89a1, 0x456c,
+ 0x89a6, 0x43a2,
+ 0x89ab, 0x43ec,
+ 0x89ac, 0x4571,
+ 0x89ad, 0x43eb,
+ 0x89ae, 0x4572,
+ 0x89b0, 0x4573,
+ 0x89b5, 0x4576,
+ 0x89c1, 0x4581,
+ 0x89c5, 0x4584,
+ 0x89cf, 0x43bc,
+ 0x89d0, 0x458e,
+ 0x89d9, 0x439c,
+ 0x89da, 0x4597,
+ 0x89db, 0x439e,
+ 0x89dc, 0x4598,
+ 0x89dd, 0x439f,
+ 0x89de, 0x4599,
+ 0x89e1, 0x43a1,
+ 0x89e2, 0x459c,
+ 0x89e3, 0x43a3,
+ 0x89e4, 0x459d,
+ 0x89ea, 0x43a5,
+ 0x89ec, 0x45a3,
+ 0x89fa, 0x43a9,
+ 0x89fb, 0x45b1,
+ 0x8a40, 0x45b5,
+ 0x8a41, 0x4309,
+ 0x8a43, 0x430b,
+ 0x8a4d, 0x45b6,
+ 0x8a4e, 0x4316,
+ 0x8a5a, 0x45b7,
+ 0x8a5b, 0x4323,
+ 0x8a5e, 0x45b8,
+ 0x8a5f, 0x4327,
+ 0x8a64, 0x432c,
+ 0x8a71, 0x45b9,
+ 0x8a72, 0x433a,
+ 0x8a76, 0x433e,
+ 0x8a77, 0x45ba,
+ 0x8a78, 0x4340,
+ 0x8a7a, 0x45bb,
+ 0x8a7b, 0x4343,
+ 0x8a7c, 0x45bc,
+ 0x8a7d, 0x4345,
+ 0x8a7e, 0x45bd,
+ 0x8aa1, 0x4347,
+ 0x8aa8, 0x45be,
+ 0x8aa9, 0x434f,
+ 0x8aac, 0x4352,
+ 0x8ab2, 0x4358,
+ 0x8ab6, 0x45bf,
+ 0x8ab7, 0x435d,
+ 0x8ab8, 0x45c0,
+ 0x8ab9, 0x435f,
+ 0x8abb, 0x4361,
+ 0x8ac9, 0x436f,
+ 0x8acc, 0x45c1,
+ 0x8ace, 0x4374,
+ 0x8ad6, 0x45c2,
+ 0x8ad8, 0x437e,
+ 0x8adf, 0x4385,
+ 0x8ae6, 0x45c4,
+ 0x8ae7, 0x43db,
+ 0x8ae8, 0x45c5,
+ 0x8af6, 0x45d2,
+ 0x8b40, 0x45db,
+ 0x8b41, 0x438c,
+ 0x8b43, 0x45dc,
+ 0x8b45, 0x438e,
+ 0x8b46, 0x45de,
+ 0x8b47, 0x438f,
+ 0x8b48, 0x45df,
+ 0x8b49, 0x4390,
+ 0x8b4a, 0x45e0,
+ 0x8b4b, 0x4391,
+ 0x8b4c, 0x45e1,
+ 0x8b4d, 0x4392,
+ 0x8b51, 0x45e2,
+ 0x8b55, 0x45e5,
+ 0x8b58, 0x4397,
+ 0x8b59, 0x45e8,
+ 0x8b5a, 0x4398,
+ 0x8b5b, 0x43c4,
+ 0x8b5c, 0x45e9,
+ 0x8b61, 0x43a7,
+ 0x8b62, 0x45ee,
+ 0x8b68, 0x43ac,
+ 0x8b69, 0x45f4,
+ 0x8ba1, 0x460a,
+ 0x8bc0, 0x44df,
+ 0x8bde, 0x44fc,
+ 0x8d60, 0x4629,
+ 0x8d62, 0x43ba,
+ 0x8d63, 0x462b,
+ 0x8d68, 0x43bb,
+ 0x8d69, 0x43a0,
+ 0x8d6a, 0x43bd,
+ 0x8d6b, 0x4630,
+ 0x8d6e, 0x43be,
+ 0x8d6f, 0x4633,
+ 0x8d76, 0x43bf,
+ 0x8d77, 0x463a,
+ 0x8d7a, 0x43c0,
+ 0x8d7b, 0x463d,
+ 0x8d7c, 0x43c1,
+ 0x8d7d, 0x463e,
+ 0x8da1, 0x4640,
+ 0x8da5, 0x43c2,
+ 0x8da6, 0x4644,
+ 0x8da8, 0x43b9,
+ 0x8da9, 0x43ad,
+ 0x8daa, 0x4646,
+ 0x8db6, 0x43c7,
+ 0x8db7, 0x4652,
+ 0x8dc3, 0x43c8,
+ 0x8dc4, 0x465e,
+ 0x8dfa, 0x43f9,
+ 0x8dfb, 0x4694,
+ 0x8e40, 0x372b,
+ 0x8e45, 0x4698,
+ 0x8e46, 0x3730,
+ 0x8e6a, 0x3754,
+ 0x8e6b, 0x4699,
+ 0x8e6d, 0x3756,
+ 0x8e70, 0x3759,
+ 0x8e76, 0x469b,
+ 0x8e77, 0x375f,
+ 0x8e7b, 0x469c,
+ 0x8e7c, 0x3764,
+ 0x8ea1, 0x3766,
+ 0x8ea6, 0x469d,
+ 0x8ea7, 0x376b,
+ 0x8eac, 0x3770,
+ 0x8eb5, 0x3779,
+ 0x8eb8, 0x469e,
+ 0x8eb9, 0x377d,
+ 0x8ec9, 0x469f,
+ 0x8eca, 0x378d,
+ 0x8ece, 0x3791,
+ 0x8ed1, 0x3794,
+ 0x8ee5, 0x46a0,
+ 0x8ee6, 0x37a8,
+ 0x8eef, 0x46a1,
+ 0x8ef0, 0x37b1,
+ 0x8ef6, 0x46a2,
+ 0x8ef7, 0x37b8,
+ 0x8f40, 0x37c0,
+ 0x8f58, 0x37d8,
+ 0x8f59, 0x46a3,
+ 0x8f5a, 0x37d9,
+ 0x8f5f, 0x46a4,
+ 0x8f60, 0x37de,
+ 0x8f67, 0x46a5,
+ 0x8f68, 0x37e5,
+ 0x8f6a, 0x37e7,
+ 0x8f6f, 0x37ec,
+ 0x8f79, 0x46a6,
+ 0x8f7a, 0x37f7,
+ 0x8fa1, 0x37fc,
+ 0x8fb0, 0x46a7,
+ 0x8fb1, 0x380c,
+ 0x8fc5, 0x46a8,
+ 0x8fc6, 0x3820,
+ 0x8fc7, 0x46a9,
+ 0x8fc8, 0x3821,
+ 0x8fca, 0x46aa,
+ 0x8fcd, 0x3826,
+ 0x8fda, 0x46ab,
+ 0x8fdb, 0x3833,
+ 0x8fe3, 0x46ac,
+ 0x8fe4, 0x383c,
+ 0x8ffc, 0x46ad,
+ 0x8ffd, 0x3854,
+ 0x9040, 0x3856,
+ 0x9055, 0x46ae,
+ 0x9056, 0x386c,
+ 0x905c, 0x46af,
+ 0x905f, 0x3873,
+ 0x906e, 0x3882,
+ 0x906f, 0x46b2,
+ 0x9070, 0x3883,
+ 0x907b, 0x388d,
+ 0x90a1, 0x3891,
+ 0x90a6, 0x46b3,
+ 0x90a7, 0x3896,
+ 0x90b8, 0x46b4,
+ 0x90b9, 0x38a7,
+ 0x90dd, 0x38cb,
+ 0x90f2, 0x38e0,
+ 0x9140, 0x38ed,
+ 0x9165, 0x46b5,
+ 0x9166, 0x3912,
+ 0x916e, 0x46b6,
+ 0x916f, 0x391a,
+ 0x917e, 0x46b7,
+ 0x91a1, 0x3929,
+ 0x91a2, 0x46b8,
+ 0x91a3, 0x392a,
+ 0x91c0, 0x3947,
+ 0x91c8, 0x46b9,
+ 0x91c9, 0x3950,
+ 0x9240, 0x3986,
+ 0x9245, 0x398b,
+ 0x9264, 0x46ba,
+ 0x9265, 0x39ab,
+ 0x926d, 0x46bb,
+ 0x926e, 0x39b4,
+ 0x92a1, 0x39c5,
+ 0x92b3, 0x39d3,
+ 0x92c9, 0x39e9,
+ 0x92d2, 0x39f2,
+ 0x92e5, 0x46bc,
+ 0x92e6, 0x3a05,
+ 0x92f2, 0x46bd,
+ 0x92f3, 0x3a11,
+ 0x9340, 0x3a1d,
+ 0x9368, 0x46be,
+ 0x9369, 0x3a45,
+ 0x93a1, 0x3a5b,
+ 0x93aa, 0x46bf,
+ 0x93ab, 0x3a64,
+ 0x93c2, 0x46c0,
+ 0x93c3, 0x3a7b,
+ 0x93e5, 0x46c1,
+ 0x93e6, 0x3a9d,
+ 0x93e8, 0x46c2,
+ 0x93e9, 0x3aa0,
+ 0x93eb, 0x46c3,
+ 0x93ec, 0x3aa2,
+ 0x9440, 0x3ab5,
+ 0x9446, 0x46c4,
+ 0x9448, 0x3abc,
+ 0x9479, 0x46c5,
+ 0x947a, 0x3aee,
+ 0x94a1, 0x3af3,
+ 0x94cb, 0x46c6,
+ 0x94cc, 0x3b1e,
+ 0x9540, 0x3b51,
+ 0x954d, 0x46c7,
+ 0x954e, 0x3b5e,
+ 0x955a, 0x46c8,
+ 0x955b, 0x3b6a,
+ 0x955f, 0x46c9,
+ 0x9560, 0x3b6f,
+ 0x95a1, 0x3b8e,
+ 0x95c6, 0x46ca,
+ 0x95c7, 0x3bb3,
+ 0x95da, 0x3bc6,
+ 0x9640, 0x3beb,
+ 0x9645, 0x3bf0,
+ 0x9651, 0x46cb,
+ 0x9652, 0x3bfd,
+ 0x966a, 0x46cc,
+ 0x966b, 0x3c16,
+ 0x96a1, 0x3c2a,
+ 0x96d4, 0x46cd,
+ 0x96d5, 0x3c5d,
+ 0x96ee, 0x3c76,
+ 0x96fd, 0x3c85,
+ 0x9740, 0x3c87,
+ 0x97a1, 0x3cc6,
+ 0x9840, 0x3d24,
+ 0x9844, 0x46ce,
+ 0x9846, 0x3d2a,
+ 0x986f, 0x46d0,
+ 0x9870, 0x3d54,
+ 0x9875, 0x46d1,
+ 0x9877, 0x3d59,
+ 0x9878, 0x46d3,
+ 0x987a, 0x3d5a,
+ 0x987b, 0x46d5,
+ 0x98a1, 0x46d9,
+ 0x98a3, 0x3d5b,
+ 0x98a4, 0x46db,
+ 0x98af, 0x3d5c,
+ 0x98b0, 0x46e6,
+ 0x98b4, 0x43ca,
+ 0x98b5, 0x46ea,
+ 0x98b6, 0x3d5d,
+ 0x98b7, 0x46eb,
+ 0x98b8, 0x43cc,
+ 0x98b9, 0x3d5e,
+ 0x98ba, 0x46ec,
+ 0x98bb, 0x43fa,
+ 0x98bc, 0x46ed,
+ 0x98bd, 0x3d5f,
+ 0x98bf, 0x46ee,
+ 0x98c2, 0x3d61,
+ 0x98c3, 0x46f1,
+ 0x98c4, 0x3d62,
+ 0x98c5, 0x46f2,
+ 0x98c6, 0x3d63,
+ 0x98c8, 0x46f3,
+ 0x98d2, 0x43cd,
+ 0x98d3, 0x46fd,
+ 0x98d8, 0x43ce,
+ 0x98da, 0x4702,
+ 0x98db, 0x43d1,
+ 0x98dc, 0x4703,
+ 0x98df, 0x43d4,
+ 0x98e0, 0x4706,
+ 0x98e3, 0x3d65,
+ 0x98e4, 0x4709,
+ 0x98e7, 0x3d66,
+ 0x98e8, 0x470c,
+ 0x98ed, 0x3d67,
+ 0x98ee, 0x4711,
+ 0x98f0, 0x3d68,
+ 0x98f1, 0x4713,
+ 0x98f2, 0x3d69,
+ 0x98f3, 0x4714,
+ 0x98f4, 0x43d5,
+ 0x98f6, 0x4715,
+ 0x98fc, 0x3d6a,
+ 0x98fd, 0x471b,
+ 0x98fe, 0x43d7,
+ 0x9940, 0x471c,
+ 0x9942, 0x43fc,
+ 0x9943, 0x3d6b,
+ 0x9944, 0x471e,
+ 0x9945, 0x3d6c,
+ 0x9946, 0x471f,
+ 0x9947, 0x43d8,
+ 0x9948, 0x4720,
+ 0x994f, 0x3d6d,
+ 0x9950, 0x4727,
+ 0x9954, 0x43d9,
+ 0x9955, 0x472b,
+ 0x995c, 0x43da,
+ 0x995d, 0x4732,
+ 0x9964, 0x43dc,
+ 0x9965, 0x4739,
+ 0x996a, 0x3d6e,
+ 0x996b, 0x473e,
+ 0x996e, 0x3d6f,
+ 0x996f, 0x4741,
+ 0x9975, 0x3d70,
+ 0x9976, 0x4747,
+ 0x9978, 0x3d71,
+ 0x9979, 0x4749,
+ 0x99a1, 0x474f,
+ 0x99a2, 0x3d72,
+ 0x99a3, 0x4750,
+ 0x99a4, 0x43c5,
+ 0x99a5, 0x4751,
+ 0x99a6, 0x43c6,
+ 0x99a7, 0x4752,
+ 0x99ae, 0x3d73,
+ 0x99af, 0x4759,
+ 0x99b2, 0x43de,
+ 0x99b3, 0x475c,
+ 0x99b6, 0x3d74,
+ 0x99b7, 0x475f,
+ 0x99ba, 0x3d75,
+ 0x99bb, 0x4762,
+ 0x99ca, 0x43e0,
+ 0x99cb, 0x4771,
+ 0x99cd, 0x43e2,
+ 0x99ce, 0x4773,
+ 0x99d3, 0x43e3,
+ 0x99d4, 0x4778,
+ 0x99d6, 0x43e5,
+ 0x99d7, 0x477a,
+ 0x99df, 0x43df,
+ 0x99e0, 0x4782,
+ 0x99e2, 0x3d76,
+ 0x99e3, 0x4784,
+ 0x99e4, 0x43ab,
+ 0x99e5, 0x4785,
+ 0x99e6, 0x43e7,
+ 0x99e7, 0x4786,
+ 0x99e8, 0x43e9,
+ 0x99e9, 0x4787,
+ 0x99ef, 0x43fd,
+ 0x99f0, 0x478d,
+ 0x99f4, 0x3d77,
+ 0x99f5, 0x4791,
+ 0x9a40, 0x479b,
+ 0x9a4a, 0x3d78,
+ 0x9a4b, 0x47a5,
+ 0x9a4c, 0x3d79,
+ 0x9a4d, 0x47a6,
+ 0x9a59, 0x3d7a,
+ 0x9a5a, 0x47b2,
+ 0x9a5f, 0x43af,
+ 0x9a60, 0x47b7,
+ 0x9a61, 0x3d7b,
+ 0x9a62, 0x47b8,
+ 0x9a66, 0x43ed,
+ 0x9a67, 0x47bc,
+ 0x9a68, 0x3d7c,
+ 0x9a69, 0x43ee,
+ 0x9a6a, 0x47bd,
+ 0x9a6b, 0x43ff,
+ 0x9a6c, 0x47be,
+ 0x9a73, 0x3d7d,
+ 0x9a74, 0x47c5,
+ 0x9a75, 0x43f1,
+ 0x9a76, 0x47c6,
+ 0x9a7e, 0x3d7e,
+ 0x9aa1, 0x47ce,
+ 0x9aa3, 0x43f3,
+ 0x9aa4, 0x47d0,
+ 0x9aa5, 0x43f2,
+ 0x9aa6, 0x47d1,
+ 0x9aa9, 0x43f8,
+ 0x9aaa, 0x43f4,
+ 0x9aab, 0x47d4,
+ 0x9ab2, 0x3d7f,
+ 0x9ab3, 0x47db,
+ 0x9ab7, 0x3d80,
+ 0x9ab8, 0x47df,
+ 0x9ab9, 0x3d81,
+ 0x9aba, 0x47e0,
+ 0x9abb, 0x3d82,
+ 0x9abc, 0x47e1,
+ 0x9abd, 0x43b7,
+ 0x9abe, 0x47e2,
+ 0x9ac7, 0x3d83,
+ 0x9ac8, 0x47eb,
+ 0x9ad0, 0x3d84,
+ 0x9ad1, 0x47f3,
+ 0x9ad2, 0x3d85,
+ 0x9ad3, 0x47f4,
+ 0x9ad9, 0x3d86,
+ 0x9adc, 0x47fa,
+ 0x9ae2, 0x3d89,
+ 0x9ae3, 0x4800,
+ 0x9ae4, 0x3d8a,
+ 0x9ae5, 0x4801,
+ 0x9ae8, 0x3d8b,
+ 0x9ae9, 0x43b0,
+ 0x9aea, 0x4804,
+ 0x9aee, 0x43b2,
+ 0x9aef, 0x4808,
+ 0x9af2, 0x3d8c,
+ 0x9af3, 0x480b,
+ 0x9af6, 0x3d8d,
+ 0x9af7, 0x480e,
+ 0x9afb, 0x3d8e,
+ 0x9afc, 0x4812,
+ 0x9b40, 0x4815,
+ 0x9b46, 0x3d8f,
+ 0x9b47, 0x481b,
+ 0x9b4a, 0x3d90,
+ 0x9b4b, 0x481e,
+ 0x9b54, 0x3d92,
+ 0x9b55, 0x4827,
+ 0x9b58, 0x3d93,
+ 0x9b59, 0x482a,
+ 0x9b5a, 0x3d94,
+ 0x9b5b, 0x482b,
+ 0x9b5c, 0x3d95,
+ 0x9b5d, 0x482c,
+ 0x9b5e, 0x3d96,
+ 0x9b60, 0x482d,
+ 0x9b62, 0x482e,
+ 0x9b70, 0x3d98,
+ 0x9b74, 0x483c,
+ 0x9b77, 0x3d9d,
+ 0x9b79, 0x483e,
+ 0x9b7c, 0x3da0,
+ 0x9b7d, 0x4840,
+ 0x9b7e, 0x3da1,
+ 0x9ba1, 0x3da2,
+ 0x9ba2, 0x4841,
+ 0x9ba3, 0x3da3,
+ 0x9ba5, 0x4842,
+ 0x9ba7, 0x3da5,
+ 0x9bab, 0x4844,
+ 0x9bac, 0x3da9,
+ 0x9bad, 0x4845,
+ 0x9baf, 0x3daa,
+ 0x9bb0, 0x4847,
+ 0x9bb2, 0x3dab,
+ 0x9bba, 0x4849,
+ 0x9bbe, 0x3db3,
+ 0x9bbf, 0x484d,
+ 0x9bc0, 0x3db4,
+ 0x9bc7, 0x484e,
+ 0x9bca, 0x3dbb,
+ 0x9bcb, 0x4851,
+ 0x9bcc, 0x3dbc,
+ 0x9bcd, 0x4852,
+ 0x9bce, 0x43d0,
+ 0x9bcf, 0x4853,
+ 0x9bd0, 0x3dbd,
+ 0x9bd2, 0x4854,
+ 0x9bd3, 0x3dbf,
+ 0x9bd4, 0x4855,
+ 0x9bd5, 0x3dc0,
+ 0x9bd6, 0x4856,
+ 0x9bd8, 0x3dc1,
+ 0x9bdb, 0x4858,
+ 0x9bdd, 0x3dc4,
+ 0x9bdf, 0x3dc5,
+ 0x9be0, 0x485a,
+ 0x9be1, 0x3dc6,
+ 0x9be2, 0x485b,
+ 0x9be3, 0x3dc7,
+ 0x9be4, 0x485c,
+ 0x9be7, 0x3dc8,
+ 0x9be8, 0x485f,
+ 0x9be9, 0x3dc9,
+ 0x9bed, 0x4860,
+ 0x9bee, 0x3dcd,
+ 0x9bf0, 0x4861,
+ 0x9bf3, 0x3dcf,
+ 0x9bf4, 0x4864,
+ 0x9bf7, 0x4866,
+ 0x9bf8, 0x3dd1,
+ 0x9bfa, 0x4867,
+ 0x9bfb, 0x3dd3,
+ 0x9bfd, 0x4868,
+ 0x9c40, 0x3dd5,
+ 0x9c43, 0x486a,
+ 0x9c44, 0x3dd8,
+ 0x9c47, 0x486b,
+ 0x9c48, 0x3ddb,
+ 0x9c49, 0x486c,
+ 0x9c4a, 0x3ddc,
+ 0x9c4b, 0x486d,
+ 0x9c4d, 0x3ddd,
+ 0x9c54, 0x486f,
+ 0x9c55, 0x3de4,
+ 0x9c56, 0x4870,
+ 0x9c57, 0x3de5,
+ 0x9c5c, 0x4871,
+ 0x9c5d, 0x3dea,
+ 0x9c5e, 0x4872,
+ 0x9c60, 0x3deb,
+ 0x9c61, 0x4874,
+ 0x9c63, 0x4875,
+ 0x9c64, 0x3ded,
+ 0x9c67, 0x4876,
+ 0x9c69, 0x4877,
+ 0x9c6a, 0x3df1,
+ 0x9c6c, 0x4878,
+ 0x9c6d, 0x3df2,
+ 0x9c6e, 0x4879,
+ 0x9c6f, 0x3df3,
+ 0x9c73, 0x487a,
+ 0x9c75, 0x3df7,
+ 0x9c78, 0x487c,
+ 0x9c79, 0x3dfa,
+ 0x9c7a, 0x487d,
+ 0x9c7b, 0x3dfb,
+ 0x9c7d, 0x487e,
+ 0x9c7e, 0x3dfd,
+ 0x9ca1, 0x3dfe,
+ 0x9ca3, 0x487f,
+ 0x9ca5, 0x3e00,
+ 0x9ca6, 0x4881,
+ 0x9ca8, 0x3e01,
+ 0x9caa, 0x4883,
+ 0x9cab, 0x3e03,
+ 0x9cac, 0x4884,
+ 0x9cad, 0x3e04,
+ 0x9caf, 0x4885,
+ 0x9cb1, 0x3e06,
+ 0x9cbb, 0x4887,
+ 0x9cbe, 0x3e12,
+ 0x9cc3, 0x4888,
+ 0x9cc6, 0x3e17,
+ 0x9cce, 0x488b,
+ 0x9ccf, 0x3e1f,
+ 0x9cd1, 0x3e21,
+ 0x9cd4, 0x488c,
+ 0x9cd8, 0x3e24,
+ 0x9cdb, 0x4890,
+ 0x9cdc, 0x3e27,
+ 0x9ce6, 0x4891,
+ 0x9ce7, 0x3e31,
+ 0x9cea, 0x4892,
+ 0x9ceb, 0x3e34,
+ 0x9ced, 0x4893,
+ 0x9cee, 0x3e36,
+ 0x9cfa, 0x4894,
+ 0x9cfd, 0x3e42,
+ 0x9cfe, 0x4897,
+ 0x9d40, 0x43e8,
+ 0x9d41, 0x4898,
+ 0x9d46, 0x3e43,
+ 0x9d47, 0x489d,
+ 0x9d49, 0x3e44,
+ 0x9d4a, 0x489f,
+ 0x9d4c, 0x3e46,
+ 0x9d4e, 0x48a1,
+ 0x9d4f, 0x3e48,
+ 0x9d50, 0x48a2,
+ 0x9d51, 0x3e49,
+ 0x9d52, 0x48a3,
+ 0x9d55, 0x3e4a,
+ 0x9d56, 0x48a6,
+ 0x9d58, 0x48a7,
+ 0x9d5b, 0x48a9,
+ 0x9d61, 0x43c9,
+ 0x9d62, 0x3e4c,
+ 0x9d63, 0x48af,
+ 0x9d64, 0x3e4d,
+ 0x9d65, 0x48b0,
+ 0x9d78, 0x43f5,
+ 0x9d79, 0x3e4e,
+ 0x9d7a, 0x48c3,
+ 0x9d7e, 0x3e4f,
+ 0x9da1, 0x48c7,
+ 0x9da5, 0x3e50,
+ 0x9da9, 0x48cb,
+ 0x9daa, 0x3e54,
+ 0x9dab, 0x48cc,
+ 0x9dac, 0x3e55,
+ 0x9dae, 0x48cd,
+ 0x9db0, 0x3e58,
+ 0x9db1, 0x48cf,
+ 0x9db3, 0x3e59,
+ 0x9db4, 0x48d1,
+ 0x9db5, 0x3e5a,
+ 0x9db6, 0x48d2,
+ 0x9db7, 0x3e5b,
+ 0x9db8, 0x48d3,
+ 0x9dbc, 0x3e5c,
+ 0x9dbe, 0x48d7,
+ 0x9dbf, 0x3e5e,
+ 0x9dc1, 0x48d8,
+ 0x9dc3, 0x3e60,
+ 0x9dc5, 0x48da,
+ 0x9dc7, 0x3e62,
+ 0x9dc9, 0x48dc,
+ 0x9dca, 0x3e64,
+ 0x9dcb, 0x48dd,
+ 0x9dcd, 0x3e65,
+ 0x9dd2, 0x48df,
+ 0x9dd3, 0x3e6a,
+ 0x9dd6, 0x48e0,
+ 0x9dda, 0x3e6d,
+ 0x9dfc, 0x48e4,
+ 0x9dfd, 0x3e8f,
+ 0x9e40, 0x3e91,
+ 0x9e43, 0x48e5,
+ 0x9e44, 0x3e95,
+ 0x9e5f, 0x48e6,
+ 0x9e60, 0x3eb1,
+ 0x9e63, 0x48e7,
+ 0x9e64, 0x3eb4,
+ 0x9e66, 0x48e8,
+ 0x9e68, 0x3eb6,
+ 0x9e69, 0x48ea,
+ 0x9e6a, 0x3eb7,
+ 0x9e6b, 0x48eb,
+ 0x9e71, 0x3eb8,
+ 0x9e72, 0x48f1,
+ 0x9e73, 0x3eb9,
+ 0x9e74, 0x48f2,
+ 0x9e77, 0x3eba,
+ 0x9e79, 0x48f5,
+ 0x9e7a, 0x3ebc,
+ 0x9e7b, 0x48f6,
+ 0x9e7c, 0x3ebd,
+ 0x9e7d, 0x48f7,
+ 0x9e7e, 0x3ebe,
+ 0x9ea1, 0x3ebf,
+ 0x9ea3, 0x48f8,
+ 0x9ea4, 0x3ec1,
+ 0x9ea7, 0x48f9,
+ 0x9eaa, 0x3ec5,
+ 0x9eab, 0x48fb,
+ 0x9ead, 0x3ec7,
+ 0x9eae, 0x48fc,
+ 0x9eaf, 0x3ec8,
+ 0x9eb2, 0x48fd,
+ 0x9eb4, 0x3ecb,
+ 0x9eb5, 0x48ff,
+ 0x9eb6, 0x3ecc,
+ 0x9eb8, 0x4900,
+ 0x9eb9, 0x3ece,
+ 0x9eba, 0x4901,
+ 0x9ebc, 0x3ecf,
+ 0x9ebd, 0x4903,
+ 0x9ebf, 0x3ed0,
+ 0x9ec1, 0x4905,
+ 0x9ec5, 0x3ed3,
+ 0x9ec6, 0x4908,
+ 0x9ec7, 0x3ed4,
+ 0x9ecb, 0x4909,
+ 0x9ecd, 0x3ed9,
+ 0x9ece, 0x490b,
+ 0x9ed0, 0x3eda,
+ 0x9ed2, 0x490d,
+ 0x9ed3, 0x3edc,
+ 0x9ed4, 0x490e,
+ 0x9ed6, 0x3edd,
+ 0x9ed8, 0x4910,
+ 0x9eda, 0x3edf,
+ 0x9ef0, 0x3ef5,
+ 0x9ef2, 0x4912,
+ 0x9ef3, 0x3ef7,
+ 0x9ef5, 0x3ef9,
+ 0x9ef6, 0x4913,
+ 0x9ef9, 0x3efa,
+ 0x9efb, 0x4916,
+ 0x9efc, 0x3efc,
+ 0x9efe, 0x3efe,
+ 0x9f40, 0x3eff,
+ 0x9f43, 0x4917,
+ 0x9f44, 0x3f02,
+ 0x9f48, 0x4918,
+ 0x9f49, 0x3f06,
+ 0x9f4b, 0x4919,
+ 0x9f4d, 0x3f08,
+ 0x9f4f, 0x3f0a,
+ 0x9f61, 0x3f1c,
+ 0x9f67, 0x491b,
+ 0x9f69, 0x3f23,
+ 0x9f70, 0x491d,
+ 0x9f71, 0x3f2a,
+ 0x9fa1, 0x3f38,
+ 0x9fae, 0x3f45,
+ 0x9fb2, 0x3f49,
+ 0x9fb5, 0x491e,
+ 0x9fb6, 0x3f4c,
+ 0x9fbb, 0x491f,
+ 0x9fbc, 0x3f51,
+ 0x9fbf, 0x4920,
+ 0x9fc1, 0x4921,
+ 0x9fc2, 0x3f55,
+ 0x9fc9, 0x3f5c,
+ 0x9fcc, 0x4922,
+ 0x9fcd, 0x3f60,
+ 0x9fd4, 0x4923,
+ 0x9fd5, 0x3f68,
+ 0x9fd9, 0x3f6c,
+ 0x9fdb, 0x3f6e,
+ 0x9fe4, 0x4924,
+ 0x9fe5, 0x3f77,
+ 0x9fe7, 0x3f79,
+ 0x9feb, 0x3f7d,
+ 0x9ff0, 0x3f82,
+ 0x9ff9, 0x4925,
+ 0x9ffa, 0x3f8b,
+ 0xa040, 0x4926,
+ 0xa041, 0x3f90,
+ 0xa047, 0x4927,
+ 0xa048, 0x3f96,
+ 0xa055, 0x4928,
+ 0xa056, 0x3fa3,
+ 0xa058, 0x3fa5,
+ 0xa05b, 0x3fa8,
+ 0xa064, 0x3fb1,
+ 0xa06d, 0x4929,
+ 0xa06e, 0x3fba,
+ 0xa073, 0x3fbf,
+ 0xa078, 0x3fc4,
+ 0xa07b, 0x492a,
+ 0xa07c, 0x3fc7,
+ 0xa0a1, 0x3fca,
+ 0xa0a2, 0x492b,
+ 0xa0a3, 0x3fcb,
+ 0xa0a6, 0x3fce,
+ 0xa0a7, 0x492c,
+ 0xa0a8, 0x3fcf,
+ 0xa0ae, 0x3fd5,
+ 0xa0b0, 0x3fd7,
+ 0xa0c5, 0x492d,
+ 0xa0c6, 0x3fec,
+ 0xa0d0, 0x492e,
+ 0xa0d1, 0x3ff6,
+ 0xa0d4, 0x3ff9,
+ 0xa0d6, 0x3ffb,
+ 0xa0e0, 0x4005,
+ 0xa0e2, 0x4007,
+ 0xa0e3, 0x492f,
+ 0xa0e5, 0x4009,
+ 0xa0e7, 0x4930,
+ 0xa0ee, 0x43b4,
+ 0xa0ef, 0x4937,
+ 0xa0f2, 0x43b8,
+ 0xa0f3, 0x493a,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc6a1, 0x01fa,
+ 0xc6bf, 0x0219,
+ 0xc6d0, 0x022a,
+ 0xc6d4, 0x022e,
+ 0xc6d6, 0x0230,
+ 0xc6d8, 0x35b3,
+ 0xc6e0, 0x35ba,
+ 0xc740, 0x35d9,
+ 0xc7a1, 0x3618,
+ 0xc840, 0x3676,
+ 0xc8a1, 0x36b5,
+ 0xc8cd, 0x36e1,
+ 0xc8d4, 0x44c6,
+ 0xc8d7, 0x451c,
+ 0xc8e0, 0x02dc,
+ 0xc8e1, 0x4525,
+ 0xc8e9, 0x0509,
+ 0xc8ea, 0x452d,
+ 0xc8f1, 0x09f6,
+ 0xc8f5, 0x4992,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xf9d6, 0x36e8,
+ 0xfa40, 0x400b,
+ 0xfa60, 0x402b,
+ 0xfa67, 0x4032,
+ 0xfaa1, 0x404a,
+ 0xfaa9, 0x4946,
+ 0xfaab, 0x4054,
+ 0xfabe, 0x4067,
+ 0xfac6, 0x406f,
+ 0xfad6, 0x407f,
+ 0xfb40, 0x40a8,
+ 0xfb49, 0x40b1,
+ 0xfb53, 0x4948,
+ 0xfb54, 0x40bc,
+ 0xfb6e, 0x4949,
+ 0xfb6f, 0x40d7,
+ 0xfba1, 0x40e7,
+ 0xfba3, 0x494a,
+ 0xfba4, 0x40ea,
+ 0xfbb9, 0x40ff,
+ 0xfbbf, 0x494b,
+ 0xfbc0, 0x4105,
+ 0xfbcd, 0x494c,
+ 0xfbce, 0x4112,
+ 0xfbf4, 0x4138,
+ 0xfbfa, 0x413e,
+ 0xfc40, 0x4143,
+ 0xfc4a, 0x494d,
+ 0xfc4b, 0x414d,
+ 0xfc50, 0x4151,
+ 0xfc52, 0x494e,
+ 0xfc53, 0x4153,
+ 0xfc63, 0x494f,
+ 0xfc64, 0x4163,
+ 0xfc6d, 0x4950,
+ 0xfc6e, 0x416d,
+ 0xfc75, 0x4951,
+ 0xfc76, 0x4174,
+ 0xfca1, 0x417d,
+ 0xfcba, 0x4195,
+ 0xfcbc, 0x4952,
+ 0xfcbe, 0x4198,
+ 0xfccc, 0x4954,
+ 0xfccd, 0x41a7,
+ 0xfce3, 0x4955,
+ 0xfce4, 0x41bd,
+ 0xfcee, 0x4956,
+ 0xfcef, 0x41c7,
+ 0xfcf2, 0x41ca,
+ 0xfd40, 0x41d7,
+ 0xfd49, 0x4957,
+ 0xfd4a, 0x41e0,
+ 0xfd6a, 0x4958,
+ 0xfd6b, 0x4201,
+ 0xfda1, 0x4215,
+ 0xfdb9, 0x422d,
+ 0xfdbc, 0x4230,
+ 0xfde3, 0x4959,
+ 0xfde4, 0x4258,
+ 0xfdf2, 0x495a,
+ 0xfdf3, 0x4266,
+ 0xfe40, 0x4272,
+ 0xfe53, 0x4285,
+ 0xfe6d, 0x495b,
+ 0xfe6e, 0x429f,
+ 0xfe70, 0x42a1,
+ 0xfe78, 0x495c,
+ 0xfe79, 0x42a9,
+ 0xfea1, 0x42af,
+ 0xfeab, 0x42b8,
+ 0xfede, 0x495d,
+ 0xfee0, 0x42eb,
+ 0xfeed, 0x495f,
+ 0xfeef, 0x42f8,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKscsB5HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKscsB5HMap2, 1129
+};
+
+static Gushort cns13HKscsB5VMap2[2284] = {
+ 0x0000, 0x0000,
+ 0x8840, 0x44c9,
+ 0x8856, 0x4961,
+ 0x88a1, 0x498a,
+ 0x88a9, 0x499c,
+ 0x8940, 0x4534,
+ 0x8943, 0x4536,
+ 0x8946, 0x4537,
+ 0x894c, 0x453b,
+ 0x894d, 0x43c3,
+ 0x894e, 0x453c,
+ 0x8951, 0x439a,
+ 0x8952, 0x453f,
+ 0x89a1, 0x456c,
+ 0x89a6, 0x43a2,
+ 0x89ab, 0x43ec,
+ 0x89ac, 0x4571,
+ 0x89ad, 0x43eb,
+ 0x89ae, 0x4572,
+ 0x89b0, 0x4573,
+ 0x89b5, 0x4576,
+ 0x89c1, 0x4581,
+ 0x89c5, 0x4584,
+ 0x89cf, 0x43bc,
+ 0x89d0, 0x458e,
+ 0x89d9, 0x439c,
+ 0x89da, 0x4597,
+ 0x89db, 0x439e,
+ 0x89dc, 0x4598,
+ 0x89dd, 0x439f,
+ 0x89de, 0x4599,
+ 0x89e1, 0x43a1,
+ 0x89e2, 0x459c,
+ 0x89e3, 0x43a3,
+ 0x89e4, 0x459d,
+ 0x89ea, 0x43a5,
+ 0x89ec, 0x45a3,
+ 0x89fa, 0x43a9,
+ 0x89fb, 0x45b1,
+ 0x8a40, 0x45b5,
+ 0x8a41, 0x4309,
+ 0x8a43, 0x430b,
+ 0x8a4d, 0x45b6,
+ 0x8a4e, 0x4316,
+ 0x8a5a, 0x45b7,
+ 0x8a5b, 0x4323,
+ 0x8a5e, 0x45b8,
+ 0x8a5f, 0x4327,
+ 0x8a64, 0x432c,
+ 0x8a71, 0x45b9,
+ 0x8a72, 0x433a,
+ 0x8a76, 0x433e,
+ 0x8a77, 0x45ba,
+ 0x8a78, 0x4340,
+ 0x8a7a, 0x45bb,
+ 0x8a7b, 0x4343,
+ 0x8a7c, 0x45bc,
+ 0x8a7d, 0x4345,
+ 0x8a7e, 0x45bd,
+ 0x8aa1, 0x4347,
+ 0x8aa8, 0x45be,
+ 0x8aa9, 0x434f,
+ 0x8aac, 0x4352,
+ 0x8ab2, 0x4358,
+ 0x8ab6, 0x45bf,
+ 0x8ab7, 0x435d,
+ 0x8ab8, 0x45c0,
+ 0x8ab9, 0x435f,
+ 0x8abb, 0x4361,
+ 0x8ac9, 0x436f,
+ 0x8acc, 0x45c1,
+ 0x8ace, 0x4374,
+ 0x8ad6, 0x45c2,
+ 0x8ad8, 0x437e,
+ 0x8adf, 0x4385,
+ 0x8ae6, 0x45c4,
+ 0x8ae7, 0x43db,
+ 0x8ae8, 0x45c5,
+ 0x8af6, 0x45d2,
+ 0x8b40, 0x45db,
+ 0x8b41, 0x438c,
+ 0x8b43, 0x45dc,
+ 0x8b45, 0x438e,
+ 0x8b46, 0x45de,
+ 0x8b47, 0x438f,
+ 0x8b48, 0x45df,
+ 0x8b49, 0x4390,
+ 0x8b4a, 0x45e0,
+ 0x8b4b, 0x4391,
+ 0x8b4c, 0x45e1,
+ 0x8b4d, 0x4392,
+ 0x8b51, 0x45e2,
+ 0x8b55, 0x45e5,
+ 0x8b58, 0x4397,
+ 0x8b59, 0x45e8,
+ 0x8b5a, 0x4398,
+ 0x8b5b, 0x43c4,
+ 0x8b5c, 0x45e9,
+ 0x8b61, 0x43a7,
+ 0x8b62, 0x45ee,
+ 0x8b68, 0x43ac,
+ 0x8b69, 0x45f4,
+ 0x8ba1, 0x460a,
+ 0x8bc0, 0x44df,
+ 0x8bde, 0x44fc,
+ 0x8d60, 0x4629,
+ 0x8d62, 0x43ba,
+ 0x8d63, 0x462b,
+ 0x8d68, 0x43bb,
+ 0x8d69, 0x43a0,
+ 0x8d6a, 0x43bd,
+ 0x8d6b, 0x4630,
+ 0x8d6e, 0x43be,
+ 0x8d6f, 0x4633,
+ 0x8d76, 0x43bf,
+ 0x8d77, 0x463a,
+ 0x8d7a, 0x43c0,
+ 0x8d7b, 0x463d,
+ 0x8d7c, 0x43c1,
+ 0x8d7d, 0x463e,
+ 0x8da1, 0x4640,
+ 0x8da5, 0x43c2,
+ 0x8da6, 0x4644,
+ 0x8da8, 0x43b9,
+ 0x8da9, 0x43ad,
+ 0x8daa, 0x4646,
+ 0x8db6, 0x43c7,
+ 0x8db7, 0x4652,
+ 0x8dc3, 0x43c8,
+ 0x8dc4, 0x465e,
+ 0x8dfa, 0x43f9,
+ 0x8dfb, 0x4694,
+ 0x8e40, 0x372b,
+ 0x8e45, 0x4698,
+ 0x8e46, 0x3730,
+ 0x8e6a, 0x3754,
+ 0x8e6b, 0x4699,
+ 0x8e6d, 0x3756,
+ 0x8e70, 0x3759,
+ 0x8e76, 0x469b,
+ 0x8e77, 0x375f,
+ 0x8e7b, 0x469c,
+ 0x8e7c, 0x3764,
+ 0x8ea1, 0x3766,
+ 0x8ea6, 0x469d,
+ 0x8ea7, 0x376b,
+ 0x8eac, 0x3770,
+ 0x8eb5, 0x3779,
+ 0x8eb8, 0x469e,
+ 0x8eb9, 0x377d,
+ 0x8ec9, 0x469f,
+ 0x8eca, 0x378d,
+ 0x8ece, 0x3791,
+ 0x8ed1, 0x3794,
+ 0x8ee5, 0x46a0,
+ 0x8ee6, 0x37a8,
+ 0x8eef, 0x46a1,
+ 0x8ef0, 0x37b1,
+ 0x8ef6, 0x46a2,
+ 0x8ef7, 0x37b8,
+ 0x8f40, 0x37c0,
+ 0x8f58, 0x37d8,
+ 0x8f59, 0x46a3,
+ 0x8f5a, 0x37d9,
+ 0x8f5f, 0x46a4,
+ 0x8f60, 0x37de,
+ 0x8f67, 0x46a5,
+ 0x8f68, 0x37e5,
+ 0x8f6a, 0x37e7,
+ 0x8f6f, 0x37ec,
+ 0x8f79, 0x46a6,
+ 0x8f7a, 0x37f7,
+ 0x8fa1, 0x37fc,
+ 0x8fb0, 0x46a7,
+ 0x8fb1, 0x380c,
+ 0x8fc5, 0x46a8,
+ 0x8fc6, 0x3820,
+ 0x8fc7, 0x46a9,
+ 0x8fc8, 0x3821,
+ 0x8fca, 0x46aa,
+ 0x8fcd, 0x3826,
+ 0x8fda, 0x46ab,
+ 0x8fdb, 0x3833,
+ 0x8fe3, 0x46ac,
+ 0x8fe4, 0x383c,
+ 0x8ffc, 0x46ad,
+ 0x8ffd, 0x3854,
+ 0x9040, 0x3856,
+ 0x9055, 0x46ae,
+ 0x9056, 0x386c,
+ 0x905c, 0x46af,
+ 0x905f, 0x3873,
+ 0x906e, 0x3882,
+ 0x906f, 0x46b2,
+ 0x9070, 0x3883,
+ 0x907b, 0x388d,
+ 0x90a1, 0x3891,
+ 0x90a6, 0x46b3,
+ 0x90a7, 0x3896,
+ 0x90b8, 0x46b4,
+ 0x90b9, 0x38a7,
+ 0x90dd, 0x38cb,
+ 0x90f2, 0x38e0,
+ 0x9140, 0x38ed,
+ 0x9165, 0x46b5,
+ 0x9166, 0x3912,
+ 0x916e, 0x46b6,
+ 0x916f, 0x391a,
+ 0x917e, 0x46b7,
+ 0x91a1, 0x3929,
+ 0x91a2, 0x46b8,
+ 0x91a3, 0x392a,
+ 0x91c0, 0x3947,
+ 0x91c8, 0x46b9,
+ 0x91c9, 0x3950,
+ 0x9240, 0x3986,
+ 0x9245, 0x398b,
+ 0x9264, 0x46ba,
+ 0x9265, 0x39ab,
+ 0x926d, 0x46bb,
+ 0x926e, 0x39b4,
+ 0x92a1, 0x39c5,
+ 0x92b3, 0x39d3,
+ 0x92c9, 0x39e9,
+ 0x92d2, 0x39f2,
+ 0x92e5, 0x46bc,
+ 0x92e6, 0x3a05,
+ 0x92f2, 0x46bd,
+ 0x92f3, 0x3a11,
+ 0x9340, 0x3a1d,
+ 0x9368, 0x46be,
+ 0x9369, 0x3a45,
+ 0x93a1, 0x3a5b,
+ 0x93aa, 0x46bf,
+ 0x93ab, 0x3a64,
+ 0x93c2, 0x46c0,
+ 0x93c3, 0x3a7b,
+ 0x93e5, 0x46c1,
+ 0x93e6, 0x3a9d,
+ 0x93e8, 0x46c2,
+ 0x93e9, 0x3aa0,
+ 0x93eb, 0x46c3,
+ 0x93ec, 0x3aa2,
+ 0x9440, 0x3ab5,
+ 0x9446, 0x46c4,
+ 0x9448, 0x3abc,
+ 0x9479, 0x46c5,
+ 0x947a, 0x3aee,
+ 0x94a1, 0x3af3,
+ 0x94cb, 0x46c6,
+ 0x94cc, 0x3b1e,
+ 0x9540, 0x3b51,
+ 0x954d, 0x46c7,
+ 0x954e, 0x3b5e,
+ 0x955a, 0x46c8,
+ 0x955b, 0x3b6a,
+ 0x955f, 0x46c9,
+ 0x9560, 0x3b6f,
+ 0x95a1, 0x3b8e,
+ 0x95c6, 0x46ca,
+ 0x95c7, 0x3bb3,
+ 0x95da, 0x3bc6,
+ 0x9640, 0x3beb,
+ 0x9645, 0x3bf0,
+ 0x9651, 0x46cb,
+ 0x9652, 0x3bfd,
+ 0x966a, 0x46cc,
+ 0x966b, 0x3c16,
+ 0x96a1, 0x3c2a,
+ 0x96d4, 0x46cd,
+ 0x96d5, 0x3c5d,
+ 0x96ee, 0x3c76,
+ 0x96fd, 0x3c85,
+ 0x9740, 0x3c87,
+ 0x97a1, 0x3cc6,
+ 0x9840, 0x3d24,
+ 0x9844, 0x46ce,
+ 0x9846, 0x3d2a,
+ 0x986f, 0x46d0,
+ 0x9870, 0x3d54,
+ 0x9875, 0x46d1,
+ 0x9877, 0x3d59,
+ 0x9878, 0x46d3,
+ 0x987a, 0x3d5a,
+ 0x987b, 0x46d5,
+ 0x98a1, 0x46d9,
+ 0x98a3, 0x3d5b,
+ 0x98a4, 0x46db,
+ 0x98af, 0x3d5c,
+ 0x98b0, 0x46e6,
+ 0x98b4, 0x43ca,
+ 0x98b5, 0x46ea,
+ 0x98b6, 0x3d5d,
+ 0x98b7, 0x46eb,
+ 0x98b8, 0x43cc,
+ 0x98b9, 0x3d5e,
+ 0x98ba, 0x46ec,
+ 0x98bb, 0x43fa,
+ 0x98bc, 0x46ed,
+ 0x98bd, 0x3d5f,
+ 0x98bf, 0x46ee,
+ 0x98c2, 0x3d61,
+ 0x98c3, 0x46f1,
+ 0x98c4, 0x3d62,
+ 0x98c5, 0x46f2,
+ 0x98c6, 0x3d63,
+ 0x98c8, 0x46f3,
+ 0x98d2, 0x43cd,
+ 0x98d3, 0x46fd,
+ 0x98d8, 0x43ce,
+ 0x98da, 0x4702,
+ 0x98db, 0x43d1,
+ 0x98dc, 0x4703,
+ 0x98df, 0x43d4,
+ 0x98e0, 0x4706,
+ 0x98e3, 0x3d65,
+ 0x98e4, 0x4709,
+ 0x98e7, 0x3d66,
+ 0x98e8, 0x470c,
+ 0x98ed, 0x3d67,
+ 0x98ee, 0x4711,
+ 0x98f0, 0x3d68,
+ 0x98f1, 0x4713,
+ 0x98f2, 0x3d69,
+ 0x98f3, 0x4714,
+ 0x98f4, 0x43d5,
+ 0x98f6, 0x4715,
+ 0x98fc, 0x3d6a,
+ 0x98fd, 0x471b,
+ 0x98fe, 0x43d7,
+ 0x9940, 0x471c,
+ 0x9942, 0x43fc,
+ 0x9943, 0x3d6b,
+ 0x9944, 0x471e,
+ 0x9945, 0x3d6c,
+ 0x9946, 0x471f,
+ 0x9947, 0x43d8,
+ 0x9948, 0x4720,
+ 0x994f, 0x3d6d,
+ 0x9950, 0x4727,
+ 0x9954, 0x43d9,
+ 0x9955, 0x472b,
+ 0x995c, 0x43da,
+ 0x995d, 0x4732,
+ 0x9964, 0x43dc,
+ 0x9965, 0x4739,
+ 0x996a, 0x3d6e,
+ 0x996b, 0x473e,
+ 0x996e, 0x3d6f,
+ 0x996f, 0x4741,
+ 0x9975, 0x3d70,
+ 0x9976, 0x4747,
+ 0x9978, 0x3d71,
+ 0x9979, 0x4749,
+ 0x99a1, 0x474f,
+ 0x99a2, 0x3d72,
+ 0x99a3, 0x4750,
+ 0x99a4, 0x43c5,
+ 0x99a5, 0x4751,
+ 0x99a6, 0x43c6,
+ 0x99a7, 0x4752,
+ 0x99ae, 0x3d73,
+ 0x99af, 0x4759,
+ 0x99b2, 0x43de,
+ 0x99b3, 0x475c,
+ 0x99b6, 0x3d74,
+ 0x99b7, 0x475f,
+ 0x99ba, 0x3d75,
+ 0x99bb, 0x4762,
+ 0x99ca, 0x43e0,
+ 0x99cb, 0x4771,
+ 0x99cd, 0x43e2,
+ 0x99ce, 0x4773,
+ 0x99d3, 0x43e3,
+ 0x99d4, 0x4778,
+ 0x99d6, 0x43e5,
+ 0x99d7, 0x477a,
+ 0x99df, 0x43df,
+ 0x99e0, 0x4782,
+ 0x99e2, 0x3d76,
+ 0x99e3, 0x4784,
+ 0x99e4, 0x43ab,
+ 0x99e5, 0x4785,
+ 0x99e6, 0x43e7,
+ 0x99e7, 0x4786,
+ 0x99e8, 0x43e9,
+ 0x99e9, 0x4787,
+ 0x99ef, 0x43fd,
+ 0x99f0, 0x478d,
+ 0x99f4, 0x3d77,
+ 0x99f5, 0x4791,
+ 0x9a40, 0x479b,
+ 0x9a4a, 0x3d78,
+ 0x9a4b, 0x47a5,
+ 0x9a4c, 0x3d79,
+ 0x9a4d, 0x47a6,
+ 0x9a59, 0x3d7a,
+ 0x9a5a, 0x47b2,
+ 0x9a5f, 0x43af,
+ 0x9a60, 0x47b7,
+ 0x9a61, 0x3d7b,
+ 0x9a62, 0x47b8,
+ 0x9a66, 0x43ed,
+ 0x9a67, 0x47bc,
+ 0x9a68, 0x3d7c,
+ 0x9a69, 0x43ee,
+ 0x9a6a, 0x47bd,
+ 0x9a6b, 0x43ff,
+ 0x9a6c, 0x47be,
+ 0x9a73, 0x3d7d,
+ 0x9a74, 0x47c5,
+ 0x9a75, 0x43f1,
+ 0x9a76, 0x47c6,
+ 0x9a7e, 0x3d7e,
+ 0x9aa1, 0x47ce,
+ 0x9aa3, 0x43f3,
+ 0x9aa4, 0x47d0,
+ 0x9aa5, 0x43f2,
+ 0x9aa6, 0x47d1,
+ 0x9aa9, 0x43f8,
+ 0x9aaa, 0x43f4,
+ 0x9aab, 0x47d4,
+ 0x9ab2, 0x3d7f,
+ 0x9ab3, 0x47db,
+ 0x9ab7, 0x3d80,
+ 0x9ab8, 0x47df,
+ 0x9ab9, 0x3d81,
+ 0x9aba, 0x47e0,
+ 0x9abb, 0x3d82,
+ 0x9abc, 0x47e1,
+ 0x9abd, 0x43b7,
+ 0x9abe, 0x47e2,
+ 0x9ac7, 0x3d83,
+ 0x9ac8, 0x47eb,
+ 0x9ad0, 0x3d84,
+ 0x9ad1, 0x47f3,
+ 0x9ad2, 0x3d85,
+ 0x9ad3, 0x47f4,
+ 0x9ad9, 0x3d86,
+ 0x9adc, 0x47fa,
+ 0x9ae2, 0x3d89,
+ 0x9ae3, 0x4800,
+ 0x9ae4, 0x3d8a,
+ 0x9ae5, 0x4801,
+ 0x9ae8, 0x3d8b,
+ 0x9ae9, 0x43b0,
+ 0x9aea, 0x4804,
+ 0x9aee, 0x43b2,
+ 0x9aef, 0x4808,
+ 0x9af2, 0x3d8c,
+ 0x9af3, 0x480b,
+ 0x9af6, 0x3d8d,
+ 0x9af7, 0x480e,
+ 0x9afb, 0x3d8e,
+ 0x9afc, 0x4812,
+ 0x9b40, 0x4815,
+ 0x9b46, 0x3d8f,
+ 0x9b47, 0x481b,
+ 0x9b4a, 0x3d90,
+ 0x9b4b, 0x481e,
+ 0x9b54, 0x3d92,
+ 0x9b55, 0x4827,
+ 0x9b58, 0x3d93,
+ 0x9b59, 0x482a,
+ 0x9b5a, 0x3d94,
+ 0x9b5b, 0x482b,
+ 0x9b5c, 0x3d95,
+ 0x9b5d, 0x482c,
+ 0x9b5e, 0x3d96,
+ 0x9b60, 0x482d,
+ 0x9b62, 0x482e,
+ 0x9b70, 0x3d98,
+ 0x9b74, 0x483c,
+ 0x9b77, 0x3d9d,
+ 0x9b79, 0x483e,
+ 0x9b7c, 0x3da0,
+ 0x9b7d, 0x4840,
+ 0x9b7e, 0x3da1,
+ 0x9ba1, 0x3da2,
+ 0x9ba2, 0x4841,
+ 0x9ba3, 0x3da3,
+ 0x9ba5, 0x4842,
+ 0x9ba7, 0x3da5,
+ 0x9bab, 0x4844,
+ 0x9bac, 0x3da9,
+ 0x9bad, 0x4845,
+ 0x9baf, 0x3daa,
+ 0x9bb0, 0x4847,
+ 0x9bb2, 0x3dab,
+ 0x9bba, 0x4849,
+ 0x9bbe, 0x3db3,
+ 0x9bbf, 0x484d,
+ 0x9bc0, 0x3db4,
+ 0x9bc7, 0x484e,
+ 0x9bca, 0x3dbb,
+ 0x9bcb, 0x4851,
+ 0x9bcc, 0x3dbc,
+ 0x9bcd, 0x4852,
+ 0x9bce, 0x43d0,
+ 0x9bcf, 0x4853,
+ 0x9bd0, 0x3dbd,
+ 0x9bd2, 0x4854,
+ 0x9bd3, 0x3dbf,
+ 0x9bd4, 0x4855,
+ 0x9bd5, 0x3dc0,
+ 0x9bd6, 0x4856,
+ 0x9bd8, 0x3dc1,
+ 0x9bdb, 0x4858,
+ 0x9bdd, 0x3dc4,
+ 0x9bdf, 0x3dc5,
+ 0x9be0, 0x485a,
+ 0x9be1, 0x3dc6,
+ 0x9be2, 0x485b,
+ 0x9be3, 0x3dc7,
+ 0x9be4, 0x485c,
+ 0x9be7, 0x3dc8,
+ 0x9be8, 0x485f,
+ 0x9be9, 0x3dc9,
+ 0x9bed, 0x4860,
+ 0x9bee, 0x3dcd,
+ 0x9bf0, 0x4861,
+ 0x9bf3, 0x3dcf,
+ 0x9bf4, 0x4864,
+ 0x9bf7, 0x4866,
+ 0x9bf8, 0x3dd1,
+ 0x9bfa, 0x4867,
+ 0x9bfb, 0x3dd3,
+ 0x9bfd, 0x4868,
+ 0x9c40, 0x3dd5,
+ 0x9c43, 0x486a,
+ 0x9c44, 0x3dd8,
+ 0x9c47, 0x486b,
+ 0x9c48, 0x3ddb,
+ 0x9c49, 0x486c,
+ 0x9c4a, 0x3ddc,
+ 0x9c4b, 0x486d,
+ 0x9c4d, 0x3ddd,
+ 0x9c54, 0x486f,
+ 0x9c55, 0x3de4,
+ 0x9c56, 0x4870,
+ 0x9c57, 0x3de5,
+ 0x9c5c, 0x4871,
+ 0x9c5d, 0x3dea,
+ 0x9c5e, 0x4872,
+ 0x9c60, 0x3deb,
+ 0x9c61, 0x4874,
+ 0x9c63, 0x4875,
+ 0x9c64, 0x3ded,
+ 0x9c67, 0x4876,
+ 0x9c69, 0x4877,
+ 0x9c6a, 0x3df1,
+ 0x9c6c, 0x4878,
+ 0x9c6d, 0x3df2,
+ 0x9c6e, 0x4879,
+ 0x9c6f, 0x3df3,
+ 0x9c73, 0x487a,
+ 0x9c75, 0x3df7,
+ 0x9c78, 0x487c,
+ 0x9c79, 0x3dfa,
+ 0x9c7a, 0x487d,
+ 0x9c7b, 0x3dfb,
+ 0x9c7d, 0x487e,
+ 0x9c7e, 0x3dfd,
+ 0x9ca1, 0x3dfe,
+ 0x9ca3, 0x487f,
+ 0x9ca5, 0x3e00,
+ 0x9ca6, 0x4881,
+ 0x9ca8, 0x3e01,
+ 0x9caa, 0x4883,
+ 0x9cab, 0x3e03,
+ 0x9cac, 0x4884,
+ 0x9cad, 0x3e04,
+ 0x9caf, 0x4885,
+ 0x9cb1, 0x3e06,
+ 0x9cbb, 0x4887,
+ 0x9cbe, 0x3e12,
+ 0x9cc3, 0x4888,
+ 0x9cc6, 0x3e17,
+ 0x9cce, 0x488b,
+ 0x9ccf, 0x3e1f,
+ 0x9cd1, 0x3e21,
+ 0x9cd4, 0x488c,
+ 0x9cd8, 0x3e24,
+ 0x9cdb, 0x4890,
+ 0x9cdc, 0x3e27,
+ 0x9ce6, 0x4891,
+ 0x9ce7, 0x3e31,
+ 0x9cea, 0x4892,
+ 0x9ceb, 0x3e34,
+ 0x9ced, 0x4893,
+ 0x9cee, 0x3e36,
+ 0x9cfa, 0x4894,
+ 0x9cfd, 0x3e42,
+ 0x9cfe, 0x4897,
+ 0x9d40, 0x43e8,
+ 0x9d41, 0x4898,
+ 0x9d46, 0x3e43,
+ 0x9d47, 0x489d,
+ 0x9d49, 0x3e44,
+ 0x9d4a, 0x489f,
+ 0x9d4c, 0x3e46,
+ 0x9d4e, 0x48a1,
+ 0x9d4f, 0x3e48,
+ 0x9d50, 0x48a2,
+ 0x9d51, 0x3e49,
+ 0x9d52, 0x48a3,
+ 0x9d55, 0x3e4a,
+ 0x9d56, 0x48a6,
+ 0x9d58, 0x48a7,
+ 0x9d5b, 0x48a9,
+ 0x9d61, 0x43c9,
+ 0x9d62, 0x3e4c,
+ 0x9d63, 0x48af,
+ 0x9d64, 0x3e4d,
+ 0x9d65, 0x48b0,
+ 0x9d78, 0x43f5,
+ 0x9d79, 0x3e4e,
+ 0x9d7a, 0x48c3,
+ 0x9d7e, 0x3e4f,
+ 0x9da1, 0x48c7,
+ 0x9da5, 0x3e50,
+ 0x9da9, 0x48cb,
+ 0x9daa, 0x3e54,
+ 0x9dab, 0x48cc,
+ 0x9dac, 0x3e55,
+ 0x9dae, 0x48cd,
+ 0x9db0, 0x3e58,
+ 0x9db1, 0x48cf,
+ 0x9db3, 0x3e59,
+ 0x9db4, 0x48d1,
+ 0x9db5, 0x3e5a,
+ 0x9db6, 0x48d2,
+ 0x9db7, 0x3e5b,
+ 0x9db8, 0x48d3,
+ 0x9dbc, 0x3e5c,
+ 0x9dbe, 0x48d7,
+ 0x9dbf, 0x3e5e,
+ 0x9dc1, 0x48d8,
+ 0x9dc3, 0x3e60,
+ 0x9dc5, 0x48da,
+ 0x9dc7, 0x3e62,
+ 0x9dc9, 0x48dc,
+ 0x9dca, 0x3e64,
+ 0x9dcb, 0x48dd,
+ 0x9dcd, 0x3e65,
+ 0x9dd2, 0x48df,
+ 0x9dd3, 0x3e6a,
+ 0x9dd6, 0x48e0,
+ 0x9dda, 0x3e6d,
+ 0x9dfc, 0x48e4,
+ 0x9dfd, 0x3e8f,
+ 0x9e40, 0x3e91,
+ 0x9e43, 0x48e5,
+ 0x9e44, 0x3e95,
+ 0x9e5f, 0x48e6,
+ 0x9e60, 0x3eb1,
+ 0x9e63, 0x48e7,
+ 0x9e64, 0x3eb4,
+ 0x9e66, 0x48e8,
+ 0x9e68, 0x3eb6,
+ 0x9e69, 0x48ea,
+ 0x9e6a, 0x3eb7,
+ 0x9e6b, 0x48eb,
+ 0x9e71, 0x3eb8,
+ 0x9e72, 0x48f1,
+ 0x9e73, 0x3eb9,
+ 0x9e74, 0x48f2,
+ 0x9e77, 0x3eba,
+ 0x9e79, 0x48f5,
+ 0x9e7a, 0x3ebc,
+ 0x9e7b, 0x48f6,
+ 0x9e7c, 0x3ebd,
+ 0x9e7d, 0x48f7,
+ 0x9e7e, 0x3ebe,
+ 0x9ea1, 0x3ebf,
+ 0x9ea3, 0x48f8,
+ 0x9ea4, 0x3ec1,
+ 0x9ea7, 0x48f9,
+ 0x9eaa, 0x3ec5,
+ 0x9eab, 0x48fb,
+ 0x9ead, 0x3ec7,
+ 0x9eae, 0x48fc,
+ 0x9eaf, 0x3ec8,
+ 0x9eb2, 0x48fd,
+ 0x9eb4, 0x3ecb,
+ 0x9eb5, 0x48ff,
+ 0x9eb6, 0x3ecc,
+ 0x9eb8, 0x4900,
+ 0x9eb9, 0x3ece,
+ 0x9eba, 0x4901,
+ 0x9ebc, 0x3ecf,
+ 0x9ebd, 0x4903,
+ 0x9ebf, 0x3ed0,
+ 0x9ec1, 0x4905,
+ 0x9ec5, 0x3ed3,
+ 0x9ec6, 0x4908,
+ 0x9ec7, 0x3ed4,
+ 0x9ecb, 0x4909,
+ 0x9ecd, 0x3ed9,
+ 0x9ece, 0x490b,
+ 0x9ed0, 0x3eda,
+ 0x9ed2, 0x490d,
+ 0x9ed3, 0x3edc,
+ 0x9ed4, 0x490e,
+ 0x9ed6, 0x3edd,
+ 0x9ed8, 0x4910,
+ 0x9eda, 0x3edf,
+ 0x9ef0, 0x3ef5,
+ 0x9ef2, 0x4912,
+ 0x9ef3, 0x3ef7,
+ 0x9ef5, 0x3ef9,
+ 0x9ef6, 0x4913,
+ 0x9ef9, 0x3efa,
+ 0x9efb, 0x4916,
+ 0x9efc, 0x3efc,
+ 0x9efe, 0x3efe,
+ 0x9f40, 0x3eff,
+ 0x9f43, 0x4917,
+ 0x9f44, 0x3f02,
+ 0x9f48, 0x4918,
+ 0x9f49, 0x3f06,
+ 0x9f4b, 0x4919,
+ 0x9f4d, 0x3f08,
+ 0x9f4f, 0x3f0a,
+ 0x9f61, 0x3f1c,
+ 0x9f67, 0x491b,
+ 0x9f69, 0x3f23,
+ 0x9f70, 0x491d,
+ 0x9f71, 0x3f2a,
+ 0x9fa1, 0x3f38,
+ 0x9fae, 0x3f45,
+ 0x9fb2, 0x3f49,
+ 0x9fb5, 0x491e,
+ 0x9fb6, 0x3f4c,
+ 0x9fbb, 0x491f,
+ 0x9fbc, 0x3f51,
+ 0x9fbf, 0x4920,
+ 0x9fc1, 0x4921,
+ 0x9fc2, 0x3f55,
+ 0x9fc9, 0x3f5c,
+ 0x9fcc, 0x4922,
+ 0x9fcd, 0x3f60,
+ 0x9fd4, 0x4923,
+ 0x9fd5, 0x3f68,
+ 0x9fd9, 0x3f6c,
+ 0x9fdb, 0x3f6e,
+ 0x9fe4, 0x4924,
+ 0x9fe5, 0x3f77,
+ 0x9fe7, 0x3f79,
+ 0x9feb, 0x3f7d,
+ 0x9ff0, 0x3f82,
+ 0x9ff9, 0x4925,
+ 0x9ffa, 0x3f8b,
+ 0xa040, 0x4926,
+ 0xa041, 0x3f90,
+ 0xa047, 0x4927,
+ 0xa048, 0x3f96,
+ 0xa055, 0x4928,
+ 0xa056, 0x3fa3,
+ 0xa058, 0x3fa5,
+ 0xa05b, 0x3fa8,
+ 0xa064, 0x3fb1,
+ 0xa06d, 0x4929,
+ 0xa06e, 0x3fba,
+ 0xa073, 0x3fbf,
+ 0xa078, 0x3fc4,
+ 0xa07b, 0x492a,
+ 0xa07c, 0x3fc7,
+ 0xa0a1, 0x3fca,
+ 0xa0a2, 0x492b,
+ 0xa0a3, 0x3fcb,
+ 0xa0a6, 0x3fce,
+ 0xa0a7, 0x492c,
+ 0xa0a8, 0x3fcf,
+ 0xa0ae, 0x3fd5,
+ 0xa0b0, 0x3fd7,
+ 0xa0c5, 0x492d,
+ 0xa0c6, 0x3fec,
+ 0xa0d0, 0x492e,
+ 0xa0d1, 0x3ff6,
+ 0xa0d4, 0x3ff9,
+ 0xa0d6, 0x3ffb,
+ 0xa0e0, 0x4005,
+ 0xa0e2, 0x4007,
+ 0xa0e3, 0x492f,
+ 0xa0e5, 0x4009,
+ 0xa0e7, 0x4930,
+ 0xa0ee, 0x43b4,
+ 0xa0ef, 0x4937,
+ 0xa0f2, 0x43b8,
+ 0xa0f3, 0x493a,
+ 0xa140, 0x0063,
+ 0xa159, 0x35af,
+ 0xa15d, 0x0080,
+ 0xa1a1, 0x00a2,
+ 0xa1f6, 0x00f8,
+ 0xa1f7, 0x00f7,
+ 0xa1f8, 0x00f9,
+ 0xa240, 0x0100,
+ 0xa2a1, 0x013f,
+ 0xa340, 0x019d,
+ 0xa3a1, 0x01dc,
+ 0xa3bd, 0x01f7,
+ 0xa440, 0x0253,
+ 0xa4a1, 0x0292,
+ 0xa540, 0x02f0,
+ 0xa5a1, 0x032f,
+ 0xa640, 0x038d,
+ 0xa6a1, 0x03cc,
+ 0xa740, 0x042a,
+ 0xa7a1, 0x0469,
+ 0xa840, 0x04c7,
+ 0xa8a1, 0x0506,
+ 0xa940, 0x0564,
+ 0xa9a1, 0x05a3,
+ 0xaa40, 0x0601,
+ 0xaaa1, 0x0640,
+ 0xab40, 0x069e,
+ 0xaba1, 0x06dd,
+ 0xac40, 0x073b,
+ 0xaca1, 0x077a,
+ 0xacfe, 0x097f,
+ 0xad40, 0x07d7,
+ 0xada1, 0x0816,
+ 0xae40, 0x0874,
+ 0xaea1, 0x08b3,
+ 0xaf40, 0x0911,
+ 0xafa1, 0x0950,
+ 0xafd0, 0x0980,
+ 0xb040, 0x09af,
+ 0xb0a1, 0x09ee,
+ 0xb140, 0x0a4c,
+ 0xb1a1, 0x0a8b,
+ 0xb240, 0x0ae9,
+ 0xb2a1, 0x0b28,
+ 0xb340, 0x0b86,
+ 0xb3a1, 0x0bc5,
+ 0xb440, 0x0c23,
+ 0xb4a1, 0x0c62,
+ 0xb540, 0x0cc0,
+ 0xb5a1, 0x0cff,
+ 0xb640, 0x0d5d,
+ 0xb6a1, 0x0d9c,
+ 0xb740, 0x0dfa,
+ 0xb7a1, 0x0e39,
+ 0xb840, 0x0e97,
+ 0xb8a1, 0x0ed6,
+ 0xb940, 0x0f34,
+ 0xb9a1, 0x0f73,
+ 0xba40, 0x0fd1,
+ 0xbaa1, 0x1010,
+ 0xbb40, 0x106e,
+ 0xbba1, 0x10ad,
+ 0xbbc8, 0x10d5,
+ 0xbc40, 0x110c,
+ 0xbca1, 0x114b,
+ 0xbd40, 0x11a9,
+ 0xbda1, 0x11e8,
+ 0xbe40, 0x1246,
+ 0xbe52, 0x10d4,
+ 0xbe53, 0x1258,
+ 0xbea1, 0x1284,
+ 0xbf40, 0x12e2,
+ 0xbfa1, 0x1321,
+ 0xc040, 0x137f,
+ 0xc0a1, 0x13be,
+ 0xc140, 0x141c,
+ 0xc1a1, 0x145b,
+ 0xc1ab, 0x1466,
+ 0xc240, 0x14ba,
+ 0xc2a1, 0x14f9,
+ 0xc2cb, 0x1465,
+ 0xc2cc, 0x1523,
+ 0xc340, 0x1556,
+ 0xc361, 0x1578,
+ 0xc3a1, 0x1596,
+ 0xc3b9, 0x15af,
+ 0xc3ba, 0x15ae,
+ 0xc3bb, 0x15b0,
+ 0xc440, 0x15f4,
+ 0xc456, 0x1577,
+ 0xc457, 0x160a,
+ 0xc4a1, 0x1632,
+ 0xc540, 0x1690,
+ 0xc5a1, 0x16cf,
+ 0xc640, 0x172d,
+ 0xc6a1, 0x01fa,
+ 0xc6bf, 0x0219,
+ 0xc6d0, 0x022a,
+ 0xc6d4, 0x022e,
+ 0xc6d6, 0x0230,
+ 0xc6d8, 0x35b3,
+ 0xc6e0, 0x35ba,
+ 0xc740, 0x35d9,
+ 0xc7a1, 0x3618,
+ 0xc840, 0x3676,
+ 0xc8a1, 0x36b5,
+ 0xc8cd, 0x36e1,
+ 0xc8d4, 0x44c6,
+ 0xc8d7, 0x451c,
+ 0xc8e0, 0x02dc,
+ 0xc8e1, 0x4525,
+ 0xc8e9, 0x0509,
+ 0xc8ea, 0x452d,
+ 0xc8f1, 0x09f6,
+ 0xc8f5, 0x4992,
+ 0xc940, 0x176c,
+ 0xc94a, 0x0274,
+ 0xc94b, 0x1776,
+ 0xc96c, 0x1798,
+ 0xc9a1, 0x17ab,
+ 0xc9be, 0x1797,
+ 0xc9bf, 0x17c8,
+ 0xc9ed, 0x17f7,
+ 0xca40, 0x1809,
+ 0xcaa1, 0x1848,
+ 0xcaf7, 0x17f6,
+ 0xcaf8, 0x189e,
+ 0xcb40, 0x18a5,
+ 0xcba1, 0x18e4,
+ 0xcc40, 0x1942,
+ 0xcca1, 0x1981,
+ 0xcd40, 0x19df,
+ 0xcda1, 0x1a1e,
+ 0xce40, 0x1a7c,
+ 0xcea1, 0x1abb,
+ 0xcf40, 0x1b19,
+ 0xcfa1, 0x1b58,
+ 0xd040, 0x1bb6,
+ 0xd0a1, 0x1bf5,
+ 0xd140, 0x1c53,
+ 0xd1a1, 0x1c92,
+ 0xd240, 0x1cf0,
+ 0xd2a1, 0x1d2f,
+ 0xd340, 0x1d8d,
+ 0xd3a1, 0x1dcc,
+ 0xd440, 0x1e2a,
+ 0xd4a1, 0x1e69,
+ 0xd540, 0x1ec7,
+ 0xd5a1, 0x1f06,
+ 0xd640, 0x1f64,
+ 0xd6a1, 0x1fa3,
+ 0xd6cc, 0x2254,
+ 0xd6cd, 0x1fcf,
+ 0xd740, 0x2001,
+ 0xd77a, 0x22b9,
+ 0xd77b, 0x203b,
+ 0xd7a1, 0x203f,
+ 0xd840, 0x209d,
+ 0xd8a1, 0x20dc,
+ 0xd940, 0x213a,
+ 0xd9a1, 0x2179,
+ 0xda40, 0x21d7,
+ 0xdaa1, 0x2216,
+ 0xdadf, 0x1fce,
+ 0xdae0, 0x2255,
+ 0xdb40, 0x2274,
+ 0xdba1, 0x22b3,
+ 0xdba7, 0x22ba,
+ 0xdc40, 0x2312,
+ 0xdca1, 0x2351,
+ 0xdd40, 0x23af,
+ 0xdda1, 0x23ee,
+ 0xddfc, 0x2381,
+ 0xddfd, 0x2449,
+ 0xde40, 0x244b,
+ 0xdea1, 0x248a,
+ 0xdf40, 0x24e8,
+ 0xdfa1, 0x2527,
+ 0xe040, 0x2585,
+ 0xe0a1, 0x25c4,
+ 0xe140, 0x2622,
+ 0xe1a1, 0x2661,
+ 0xe240, 0x26bf,
+ 0xe2a1, 0x26fe,
+ 0xe340, 0x275c,
+ 0xe3a1, 0x279b,
+ 0xe440, 0x27f9,
+ 0xe4a1, 0x2838,
+ 0xe540, 0x2896,
+ 0xe5a1, 0x28d5,
+ 0xe640, 0x2933,
+ 0xe6a1, 0x2972,
+ 0xe740, 0x29d0,
+ 0xe7a1, 0x2a0f,
+ 0xe840, 0x2a6d,
+ 0xe8a1, 0x2aac,
+ 0xe8a3, 0x2aaf,
+ 0xe940, 0x2b0b,
+ 0xe976, 0x2b42,
+ 0xe9a1, 0x2b4b,
+ 0xea40, 0x2ba9,
+ 0xeaa1, 0x2be8,
+ 0xeb40, 0x2c46,
+ 0xeb5b, 0x2c62,
+ 0xeba1, 0x2c86,
+ 0xebf1, 0x2aae,
+ 0xebf2, 0x2cd6,
+ 0xec40, 0x2ce3,
+ 0xeca1, 0x2d22,
+ 0xecde, 0x2b41,
+ 0xecdf, 0x2d5f,
+ 0xed40, 0x2d7f,
+ 0xeda1, 0x2dbe,
+ 0xedaa, 0x2dc8,
+ 0xee40, 0x2e1d,
+ 0xeea1, 0x2e5c,
+ 0xeeeb, 0x3014,
+ 0xeeec, 0x2ea6,
+ 0xef40, 0x2eb9,
+ 0xefa1, 0x2ef8,
+ 0xf040, 0x2f56,
+ 0xf056, 0x2dc7,
+ 0xf057, 0x2f6c,
+ 0xf0a1, 0x2f94,
+ 0xf0cb, 0x2c61,
+ 0xf0cc, 0x2fbe,
+ 0xf140, 0x2ff1,
+ 0xf163, 0x3015,
+ 0xf16b, 0x3160,
+ 0xf16c, 0x301d,
+ 0xf1a1, 0x3030,
+ 0xf240, 0x308e,
+ 0xf268, 0x31ef,
+ 0xf269, 0x30b6,
+ 0xf2a1, 0x30cc,
+ 0xf2c3, 0x30ef,
+ 0xf340, 0x312b,
+ 0xf375, 0x3161,
+ 0xf3a1, 0x316b,
+ 0xf440, 0x31c9,
+ 0xf466, 0x31f0,
+ 0xf4a1, 0x3209,
+ 0xf4b5, 0x30ee,
+ 0xf4b6, 0x321d,
+ 0xf4fd, 0x3265,
+ 0xf540, 0x3267,
+ 0xf5a1, 0x32a6,
+ 0xf640, 0x3304,
+ 0xf663, 0x3264,
+ 0xf664, 0x3327,
+ 0xf6a1, 0x3342,
+ 0xf740, 0x33a0,
+ 0xf7a1, 0x33df,
+ 0xf840, 0x343d,
+ 0xf8a1, 0x347c,
+ 0xf940, 0x34da,
+ 0xf977, 0x3512,
+ 0xf9a1, 0x351a,
+ 0xf9c4, 0x3511,
+ 0xf9c5, 0x353d,
+ 0xf9c6, 0x3549,
+ 0xf9c7, 0x353e,
+ 0xf9d2, 0x354a,
+ 0xf9d6, 0x36e8,
+ 0xfa40, 0x400b,
+ 0xfa60, 0x402b,
+ 0xfa67, 0x4032,
+ 0xfaa1, 0x404a,
+ 0xfaa9, 0x4946,
+ 0xfaab, 0x4054,
+ 0xfabe, 0x4067,
+ 0xfac6, 0x406f,
+ 0xfad6, 0x407f,
+ 0xfb40, 0x40a8,
+ 0xfb49, 0x40b1,
+ 0xfb53, 0x4948,
+ 0xfb54, 0x40bc,
+ 0xfb6e, 0x4949,
+ 0xfb6f, 0x40d7,
+ 0xfba1, 0x40e7,
+ 0xfba3, 0x494a,
+ 0xfba4, 0x40ea,
+ 0xfbb9, 0x40ff,
+ 0xfbbf, 0x494b,
+ 0xfbc0, 0x4105,
+ 0xfbcd, 0x494c,
+ 0xfbce, 0x4112,
+ 0xfbf4, 0x4138,
+ 0xfbfa, 0x413e,
+ 0xfc40, 0x4143,
+ 0xfc4a, 0x494d,
+ 0xfc4b, 0x414d,
+ 0xfc50, 0x4151,
+ 0xfc52, 0x494e,
+ 0xfc53, 0x4153,
+ 0xfc63, 0x494f,
+ 0xfc64, 0x4163,
+ 0xfc6d, 0x4950,
+ 0xfc6e, 0x416d,
+ 0xfc75, 0x4951,
+ 0xfc76, 0x4174,
+ 0xfca1, 0x417d,
+ 0xfcba, 0x4195,
+ 0xfcbc, 0x4952,
+ 0xfcbe, 0x4198,
+ 0xfccc, 0x4954,
+ 0xfccd, 0x41a7,
+ 0xfce3, 0x4955,
+ 0xfce4, 0x41bd,
+ 0xfcee, 0x4956,
+ 0xfcef, 0x41c7,
+ 0xfcf2, 0x41ca,
+ 0xfd40, 0x41d7,
+ 0xfd49, 0x4957,
+ 0xfd4a, 0x41e0,
+ 0xfd6a, 0x4958,
+ 0xfd6b, 0x4201,
+ 0xfda1, 0x4215,
+ 0xfdb9, 0x422d,
+ 0xfdbc, 0x4230,
+ 0xfde3, 0x4959,
+ 0xfde4, 0x4258,
+ 0xfdf2, 0x495a,
+ 0xfdf3, 0x4266,
+ 0xfe40, 0x4272,
+ 0xfe53, 0x4285,
+ 0xfe6d, 0x495b,
+ 0xfe6e, 0x429f,
+ 0xfe70, 0x42a1,
+ 0xfe78, 0x495c,
+ 0xfe79, 0x42a9,
+ 0xfea1, 0x42af,
+ 0xfeab, 0x42b8,
+ 0xfede, 0x495d,
+ 0xfee0, 0x42eb,
+ 0xfeed, 0x495f,
+ 0xfeef, 0x42f8,
+ 0xa14b, 0x354e,
+ 0xa15a, 0x35af,
+ 0xa15c, 0x35b1,
+ 0xa15d, 0x0082,
+ 0xa161, 0x0086,
+ 0xa165, 0x008a,
+ 0xa169, 0x008e,
+ 0xa16d, 0x0092,
+ 0xa171, 0x0096,
+ 0xa175, 0x009a,
+ 0xa179, 0x009e,
+ 0xa1e3, 0x354f,
+ 0xc6e4, 0x3711,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13HKscsB5VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13HKscsB5VMap2, 1142
+};
+
+static Gushort cns13UniCNSUCS2HMap2[30910] = {
+ 0x0000, 0x0000,
+ 0x0020, 0x0001,
+ 0x00a2, 0x0106,
+ 0x00a5, 0x0104,
+ 0x00a7, 0x00b2,
+ 0x00a8, 0x35b3,
+ 0x00ac, 0x36e1,
+ 0x00b0, 0x0118,
+ 0x00b1, 0x00d4,
+ 0x00b7, 0x0073,
+ 0x00c0, 0x4964,
+ 0x00c1, 0x4962,
+ 0x00c8, 0x4968,
+ 0x00c9, 0x4966,
+ 0x00ca, 0x4971,
+ 0x00d2, 0x496c,
+ 0x00d3, 0x496a,
+ 0x00d7, 0x00d2,
+ 0x00e0, 0x4975,
+ 0x00e1, 0x4973,
+ 0x00e8, 0x497a,
+ 0x00e9, 0x4978,
+ 0x00ea, 0x4990,
+ 0x00ec, 0x497e,
+ 0x00ed, 0x497c,
+ 0x00f2, 0x4982,
+ 0x00f3, 0x4980,
+ 0x00f7, 0x00d3,
+ 0x00f8, 0x4998,
+ 0x00f9, 0x4986,
+ 0x00fa, 0x4984,
+ 0x00fc, 0x498b,
+ 0x0100, 0x4961,
+ 0x0101, 0x4972,
+ 0x0112, 0x4965,
+ 0x0113, 0x4977,
+ 0x011a, 0x4967,
+ 0x011b, 0x4979,
+ 0x012b, 0x497b,
+ 0x014b, 0x4999,
+ 0x014c, 0x4969,
+ 0x014d, 0x497f,
+ 0x0153, 0x4997,
+ 0x016b, 0x4983,
+ 0x01cd, 0x4963,
+ 0x01ce, 0x4974,
+ 0x01d0, 0x497d,
+ 0x01d1, 0x496b,
+ 0x01d2, 0x4981,
+ 0x01d4, 0x4985,
+ 0x01d6, 0x4987,
+ 0x01d8, 0x4988,
+ 0x01da, 0x4989,
+ 0x01dc, 0x498a,
+ 0x0250, 0x4993,
+ 0x0251, 0x4976,
+ 0x0254, 0x4995,
+ 0x025b, 0x4994,
+ 0x0261, 0x4991,
+ 0x026a, 0x499b,
+ 0x0275, 0x4996,
+ 0x0283, 0x4992,
+ 0x028a, 0x499a,
+ 0x02c6, 0x35b4,
+ 0x02c7, 0x01f8,
+ 0x02ca, 0x01f7,
+ 0x02cb, 0x01f9,
+ 0x02d9, 0x01f6,
+ 0x0308, 0x35b3,
+ 0x0391, 0x01a1,
+ 0x03a3, 0x01b2,
+ 0x03b1, 0x01b9,
+ 0x03c3, 0x01ca,
+ 0x0401, 0x3670,
+ 0x0410, 0x366a,
+ 0x0416, 0x3671,
+ 0x0436, 0x3692,
+ 0x0451, 0x3691,
+ 0x1ebe, 0x496e,
+ 0x1ebf, 0x498d,
+ 0x1ec0, 0x4970,
+ 0x1ec1, 0x498f,
+ 0x2013, 0x0079,
+ 0x2014, 0x007b,
+ 0x2018, 0x00a6,
+ 0x201c, 0x00a8,
+ 0x2022, 0x0068,
+ 0x2025, 0x006f,
+ 0x2026, 0x006e,
+ 0x2032, 0x00ad,
+ 0x2035, 0x00ac,
+ 0x203b, 0x00b1,
+ 0x203e, 0x00c3,
+ 0x20ac, 0x44c1,
+ 0x2103, 0x010a,
+ 0x2105, 0x00c2,
+ 0x2109, 0x010b,
+ 0x2116, 0x36e6,
+ 0x2121, 0x36e7,
+ 0x2160, 0x0157,
+ 0x2170, 0x020e,
+ 0x2190, 0x00f8,
+ 0x2191, 0x00f5,
+ 0x2192, 0x00f7,
+ 0x2193, 0x00f6,
+ 0x2196, 0x00f9,
+ 0x2198, 0x00fc,
+ 0x2199, 0x00fb,
+ 0x21b8, 0x36ad,
+ 0x21e7, 0x36ac,
+ 0x221a, 0x00d5,
+ 0x221e, 0x00dc,
+ 0x221f, 0x00e9,
+ 0x2220, 0x00e8,
+ 0x2223, 0x00fe,
+ 0x2225, 0x00fd,
+ 0x2229, 0x00e5,
+ 0x222b, 0x00ed,
+ 0x222e, 0x00ee,
+ 0x2234, 0x00f0,
+ 0x2235, 0x00ef,
+ 0x223c, 0x00e4,
+ 0x2252, 0x00dd,
+ 0x2260, 0x00db,
+ 0x2261, 0x00de,
+ 0x2266, 0x00d9,
+ 0x22a5, 0x00e7,
+ 0x22bf, 0x00ea,
+ 0x2400, 0x0232,
+ 0x2421, 0x0252,
+ 0x2460, 0x01fa,
+ 0x2474, 0x0204,
+ 0x2500, 0x0137,
+ 0x2502, 0x0138,
+ 0x250c, 0x013a,
+ 0x2510, 0x013b,
+ 0x2514, 0x013c,
+ 0x2518, 0x013d,
+ 0x251c, 0x0135,
+ 0x2524, 0x0134,
+ 0x252c, 0x0133,
+ 0x2534, 0x0132,
+ 0x253c, 0x0131,
+ 0x2550, 0x0142,
+ 0x2551, 0x370a,
+ 0x2552, 0x36f8,
+ 0x2553, 0x3701,
+ 0x2554, 0x36ef,
+ 0x2555, 0x36fa,
+ 0x2556, 0x3703,
+ 0x2557, 0x36f1,
+ 0x2558, 0x36fe,
+ 0x2559, 0x3707,
+ 0x255a, 0x36f5,
+ 0x255b, 0x3700,
+ 0x255c, 0x3709,
+ 0x255d, 0x36f7,
+ 0x255e, 0x0143,
+ 0x255f, 0x3704,
+ 0x2560, 0x36f2,
+ 0x2561, 0x0145,
+ 0x2562, 0x3706,
+ 0x2563, 0x36f4,
+ 0x2564, 0x36f9,
+ 0x2565, 0x3702,
+ 0x2566, 0x36f0,
+ 0x2567, 0x36ff,
+ 0x2568, 0x3708,
+ 0x2569, 0x36f6,
+ 0x256a, 0x0144,
+ 0x256b, 0x3705,
+ 0x256c, 0x36f3,
+ 0x256d, 0x013e,
+ 0x256f, 0x0141,
+ 0x2570, 0x0140,
+ 0x2571, 0x014a,
+ 0x2581, 0x0122,
+ 0x2589, 0x0130,
+ 0x258a, 0x012f,
+ 0x258b, 0x012e,
+ 0x258c, 0x012d,
+ 0x258d, 0x012c,
+ 0x258e, 0x012b,
+ 0x258f, 0x012a,
+ 0x2593, 0x3710,
+ 0x2594, 0x0136,
+ 0x2595, 0x0139,
+ 0x25a0, 0x00be,
+ 0x25a1, 0x00bd,
+ 0x25b2, 0x00b7,
+ 0x25b3, 0x00b6,
+ 0x25bc, 0x00c0,
+ 0x25bd, 0x00bf,
+ 0x25c6, 0x00bc,
+ 0x25c7, 0x00bb,
+ 0x25cb, 0x00b4,
+ 0x25ce, 0x00b8,
+ 0x25cf, 0x00b5,
+ 0x25e2, 0x0146,
+ 0x25e4, 0x0149,
+ 0x25e5, 0x0148,
+ 0x2605, 0x00ba,
+ 0x2606, 0x00b9,
+ 0x2609, 0x00f4,
+ 0x2640, 0x00f1,
+ 0x2641, 0x00f3,
+ 0x2642, 0x00f2,
+ 0x273d, 0x35c0,
+ 0x2e80, 0x44c8,
+ 0x2e84, 0x451c,
+ 0x2e86, 0x451d,
+ 0x2e8a, 0x4520,
+ 0x2e8c, 0x4521,
+ 0x2e95, 0x4523,
+ 0x2e9c, 0x4524,
+ 0x2e9d, 0x02dc,
+ 0x2ea5, 0x4525,
+ 0x2ea7, 0x4526,
+ 0x2eaa, 0x4527,
+ 0x2eac, 0x4528,
+ 0x2eae, 0x4529,
+ 0x2eb6, 0x452a,
+ 0x2ebc, 0x452b,
+ 0x2ebe, 0x452c,
+ 0x2ec6, 0x0509,
+ 0x2eca, 0x452d,
+ 0x2ecc, 0x452e,
+ 0x2ecf, 0x4530,
+ 0x2ed6, 0x4531,
+ 0x2ede, 0x4533,
+ 0x2ee3, 0x09f6,
+ 0x2f33, 0x0227,
+ 0x3000, 0x0063,
+ 0x3001, 0x0065,
+ 0x3003, 0x00b3,
+ 0x3005, 0x35ba,
+ 0x3008, 0x0094,
+ 0x300a, 0x0090,
+ 0x300c, 0x0098,
+ 0x300e, 0x009c,
+ 0x3010, 0x008c,
+ 0x3012, 0x0105,
+ 0x3014, 0x0088,
+ 0x301d, 0x00aa,
+ 0x3021, 0x0161,
+ 0x3041, 0x35c1,
+ 0x309b, 0x44c6,
+ 0x309d, 0x35b7,
+ 0x30a1, 0x3614,
+ 0x30fc, 0x35bd,
+ 0x30fd, 0x35b5,
+ 0x3105, 0x01d1,
+ 0x3231, 0x36e5,
+ 0x32a3, 0x00c1,
+ 0x338e, 0x0115,
+ 0x339c, 0x0110,
+ 0x33a1, 0x0114,
+ 0x33c4, 0x0117,
+ 0x33ce, 0x0113,
+ 0x33d1, 0x00ec,
+ 0x33d2, 0x00eb,
+ 0x33d5, 0x010f,
+ 0x3435, 0x39bd,
+ 0x3440, 0x3c67,
+ 0x344c, 0x4593,
+ 0x3464, 0x3a85,
+ 0x3473, 0x3dc5,
+ 0x347a, 0x4033,
+ 0x347d, 0x4597,
+ 0x347e, 0x46a3,
+ 0x3493, 0x439e,
+ 0x3496, 0x37dc,
+ 0x34a5, 0x4598,
+ 0x34af, 0x3c7f,
+ 0x34bc, 0x4380,
+ 0x34c1, 0x44fb,
+ 0x34c8, 0x3d00,
+ 0x34df, 0x3ea4,
+ 0x34e4, 0x3e54,
+ 0x34fb, 0x3dca,
+ 0x3506, 0x4336,
+ 0x353e, 0x44e7,
+ 0x3551, 0x45a1,
+ 0x3553, 0x43a5,
+ 0x3561, 0x40d8,
+ 0x356d, 0x45a4,
+ 0x3570, 0x3b2f,
+ 0x3572, 0x45a5,
+ 0x3577, 0x3ecb,
+ 0x3578, 0x4379,
+ 0x3584, 0x39fb,
+ 0x3597, 0x3b2d,
+ 0x3598, 0x45b0,
+ 0x35a1, 0x40e2,
+ 0x35a5, 0x45b1,
+ 0x35ad, 0x3efc,
+ 0x35bf, 0x45b2,
+ 0x35c1, 0x4580,
+ 0x35c5, 0x45b4,
+ 0x35c7, 0x459f,
+ 0x35ca, 0x3e43,
+ 0x35ce, 0x3e81,
+ 0x35d2, 0x3fc9,
+ 0x35d6, 0x3fb5,
+ 0x35db, 0x470d,
+ 0x35dd, 0x43ac,
+ 0x35f1, 0x4696,
+ 0x35f2, 0x4627,
+ 0x35f3, 0x3f6c,
+ 0x35fb, 0x45c8,
+ 0x35fe, 0x3f6a,
+ 0x3609, 0x45f5,
+ 0x3618, 0x4871,
+ 0x361a, 0x461a,
+ 0x3623, 0x40c6,
+ 0x362d, 0x3e86,
+ 0x3635, 0x492e,
+ 0x3639, 0x4165,
+ 0x363e, 0x3a08,
+ 0x3647, 0x4806,
+ 0x3648, 0x3806,
+ 0x3649, 0x4013,
+ 0x364e, 0x4698,
+ 0x365f, 0x3df3,
+ 0x367a, 0x3ee3,
+ 0x3681, 0x45a6,
+ 0x369a, 0x3c71,
+ 0x36a5, 0x4902,
+ 0x36aa, 0x3b30,
+ 0x36ac, 0x4900,
+ 0x36b0, 0x3cdf,
+ 0x36b1, 0x40cd,
+ 0x36b5, 0x3bc2,
+ 0x36b9, 0x4887,
+ 0x36bc, 0x3cff,
+ 0x36c1, 0x37c5,
+ 0x36c3, 0x40e5,
+ 0x36c4, 0x3905,
+ 0x36c5, 0x4296,
+ 0x36c7, 0x3d3a,
+ 0x36c8, 0x4820,
+ 0x36d3, 0x3a38,
+ 0x36d4, 0x3bb3,
+ 0x36d6, 0x3d0c,
+ 0x36dd, 0x3a36,
+ 0x36e1, 0x397c,
+ 0x36e2, 0x3cdd,
+ 0x36e5, 0x4216,
+ 0x36e6, 0x40fc,
+ 0x36f5, 0x3a18,
+ 0x3701, 0x3a34,
+ 0x3703, 0x460f,
+ 0x3708, 0x40ff,
+ 0x370a, 0x3cd5,
+ 0x370d, 0x4238,
+ 0x371c, 0x3dfe,
+ 0x3722, 0x3979,
+ 0x3723, 0x3980,
+ 0x3725, 0x3849,
+ 0x372c, 0x3c8c,
+ 0x372d, 0x3d37,
+ 0x3730, 0x495c,
+ 0x3732, 0x4106,
+ 0x3733, 0x3997,
+ 0x373a, 0x3e56,
+ 0x3740, 0x4202,
+ 0x3743, 0x4036,
+ 0x3762, 0x3db6,
+ 0x376f, 0x47cb,
+ 0x3797, 0x45ed,
+ 0x37a0, 0x3a28,
+ 0x37b9, 0x43b7,
+ 0x37be, 0x393e,
+ 0x37f2, 0x3ba1,
+ 0x37f8, 0x42d2,
+ 0x37fb, 0x3ef5,
+ 0x380f, 0x462c,
+ 0x3819, 0x39af,
+ 0x3820, 0x462f,
+ 0x382d, 0x412e,
+ 0x3836, 0x4133,
+ 0x3838, 0x43bb,
+ 0x3863, 0x46c3,
+ 0x38a0, 0x4145,
+ 0x38c3, 0x3912,
+ 0x38cc, 0x4076,
+ 0x38d1, 0x3a95,
+ 0x38fa, 0x44eb,
+ 0x3908, 0x4632,
+ 0x3914, 0x43be,
+ 0x3927, 0x3c31,
+ 0x3932, 0x4182,
+ 0x393f, 0x4633,
+ 0x394d, 0x4634,
+ 0x3963, 0x4163,
+ 0x3980, 0x3874,
+ 0x3989, 0x4638,
+ 0x398a, 0x3ce8,
+ 0x3992, 0x4376,
+ 0x3999, 0x39ba,
+ 0x399b, 0x3db3,
+ 0x39a1, 0x3e19,
+ 0x39a4, 0x3e0f,
+ 0x39b8, 0x463b,
+ 0x39dc, 0x3ece,
+ 0x39e2, 0x46c8,
+ 0x39e5, 0x393b,
+ 0x39ec, 0x4310,
+ 0x39f8, 0x463e,
+ 0x39fb, 0x4345,
+ 0x39fe, 0x4368,
+ 0x3a01, 0x41e0,
+ 0x3a03, 0x4640,
+ 0x3a06, 0x4377,
+ 0x3a17, 0x4190,
+ 0x3a18, 0x438f,
+ 0x3a29, 0x3a5e,
+ 0x3a2a, 0x3edf,
+ 0x3a34, 0x4319,
+ 0x3a4b, 0x4644,
+ 0x3a52, 0x3ed3,
+ 0x3a57, 0x419e,
+ 0x3a5c, 0x3fc4,
+ 0x3a5e, 0x3b07,
+ 0x3a66, 0x419c,
+ 0x3a67, 0x4333,
+ 0x3a97, 0x4647,
+ 0x3aab, 0x4091,
+ 0x3abd, 0x4649,
+ 0x3ade, 0x414c,
+ 0x3ae0, 0x3a7a,
+ 0x3af0, 0x46b2,
+ 0x3af2, 0x464c,
+ 0x3afb, 0x3af2,
+ 0x3b0e, 0x38e8,
+ 0x3b19, 0x46c5,
+ 0x3b22, 0x464e,
+ 0x3b2b, 0x4956,
+ 0x3b39, 0x474b,
+ 0x3b42, 0x4650,
+ 0x3b58, 0x4652,
+ 0x3b60, 0x393a,
+ 0x3b71, 0x4656,
+ 0x3b72, 0x4655,
+ 0x3b7b, 0x4657,
+ 0x3b7c, 0x385a,
+ 0x3b80, 0x41e2,
+ 0x3b96, 0x3a9c,
+ 0x3b99, 0x3a98,
+ 0x3ba1, 0x41e9,
+ 0x3bbc, 0x43c8,
+ 0x3bbe, 0x3db1,
+ 0x3bc2, 0x4134,
+ 0x3bc4, 0x3aa0,
+ 0x3bd7, 0x3aac,
+ 0x3bdd, 0x465f,
+ 0x3bec, 0x4664,
+ 0x3bf2, 0x4666,
+ 0x3bf3, 0x41f3,
+ 0x3bf4, 0x3a6e,
+ 0x3c0d, 0x41f7,
+ 0x3c11, 0x3e40,
+ 0x3c15, 0x3998,
+ 0x3c54, 0x3e00,
+ 0x3ccb, 0x4670,
+ 0x3ccd, 0x3ce5,
+ 0x3cd1, 0x4003,
+ 0x3cd6, 0x3cf7,
+ 0x3cdc, 0x404e,
+ 0x3ceb, 0x4217,
+ 0x3cef, 0x4675,
+ 0x3d13, 0x3773,
+ 0x3d1d, 0x393c,
+ 0x3d32, 0x4957,
+ 0x3d3b, 0x4245,
+ 0x3d46, 0x4685,
+ 0x3d4c, 0x3ceb,
+ 0x3d4e, 0x4242,
+ 0x3d51, 0x38ea,
+ 0x3d5f, 0x4159,
+ 0x3d62, 0x3c5e,
+ 0x3d69, 0x3cea,
+ 0x3d6a, 0x4689,
+ 0x3d6f, 0x3cfc,
+ 0x3d75, 0x468a,
+ 0x3d7d, 0x3c2f,
+ 0x3d85, 0x494b,
+ 0x3d8a, 0x468d,
+ 0x3d8f, 0x3abd,
+ 0x3d91, 0x468f,
+ 0x3da5, 0x3d56,
+ 0x3dad, 0x4699,
+ 0x3db4, 0x40a6,
+ 0x3dbf, 0x37d0,
+ 0x3dc6, 0x48de,
+ 0x3dc7, 0x4164,
+ 0x3dcc, 0x3d6f,
+ 0x3dcd, 0x3af3,
+ 0x3dd3, 0x37e1,
+ 0x3ddb, 0x3fff,
+ 0x3de7, 0x3999,
+ 0x3de8, 0x425d,
+ 0x3deb, 0x3e5a,
+ 0x3df3, 0x46d4,
+ 0x3df7, 0x48ab,
+ 0x3dfc, 0x462b,
+ 0x3dfd, 0x3c14,
+ 0x3e06, 0x491d,
+ 0x3e40, 0x4169,
+ 0x3e43, 0x436d,
+ 0x3e48, 0x4595,
+ 0x3e55, 0x427f,
+ 0x3e74, 0x3ee2,
+ 0x3ea8, 0x4304,
+ 0x3ea9, 0x46ed,
+ 0x3eaa, 0x4075,
+ 0x3ead, 0x3b9d,
+ 0x3eb1, 0x3ad8,
+ 0x3eb8, 0x3a4b,
+ 0x3ebf, 0x3b0b,
+ 0x3ec2, 0x3bd8,
+ 0x3ec7, 0x3975,
+ 0x3eca, 0x46f1,
+ 0x3ecc, 0x3be2,
+ 0x3ed0, 0x3854,
+ 0x3ed1, 0x46f2,
+ 0x3ed6, 0x3cad,
+ 0x3ed7, 0x429f,
+ 0x3eda, 0x3d02,
+ 0x3ede, 0x39f2,
+ 0x3ee1, 0x3ca8,
+ 0x3ee2, 0x46f6,
+ 0x3ee7, 0x3bdc,
+ 0x3ee9, 0x3ca4,
+ 0x3eeb, 0x396a,
+ 0x3ef0, 0x46f7,
+ 0x3ef3, 0x3add,
+ 0x3ef4, 0x46f8,
+ 0x3efa, 0x46f9,
+ 0x3efc, 0x3be8,
+ 0x3eff, 0x3af5,
+ 0x3f00, 0x3c0d,
+ 0x3f04, 0x42c3,
+ 0x3f06, 0x3ad7,
+ 0x3f0e, 0x46fb,
+ 0x3f53, 0x46fc,
+ 0x3f58, 0x3ae9,
+ 0x3f59, 0x4089,
+ 0x3f63, 0x3ae6,
+ 0x3f7c, 0x4700,
+ 0x3f93, 0x45cd,
+ 0x3fc0, 0x43cf,
+ 0x3fd7, 0x43d1,
+ 0x3fdc, 0x4704,
+ 0x3fe5, 0x46df,
+ 0x3fed, 0x4335,
+ 0x3ff9, 0x45d7,
+ 0x3ffa, 0x4354,
+ 0x4004, 0x410e,
+ 0x401d, 0x4709,
+ 0x4039, 0x470b,
+ 0x4045, 0x470c,
+ 0x4053, 0x45b6,
+ 0x4057, 0x399d,
+ 0x4062, 0x3bcb,
+ 0x4065, 0x3fd3,
+ 0x406a, 0x470f,
+ 0x406f, 0x4710,
+ 0x40a8, 0x43d5,
+ 0x40bb, 0x45c0,
+ 0x40bf, 0x3eec,
+ 0x40c8, 0x3b0e,
+ 0x40d8, 0x41ab,
+ 0x40df, 0x3e17,
+ 0x40fa, 0x3ebe,
+ 0x4103, 0x43d7,
+ 0x4104, 0x425c,
+ 0x4109, 0x471c,
+ 0x410e, 0x3b1b,
+ 0x4132, 0x3b25,
+ 0x4167, 0x471f,
+ 0x416c, 0x38ae,
+ 0x416e, 0x3b23,
+ 0x417f, 0x3b82,
+ 0x4190, 0x46c0,
+ 0x41b2, 0x4720,
+ 0x41c4, 0x4723,
+ 0x41ca, 0x373f,
+ 0x41cf, 0x4726,
+ 0x41db, 0x37bf,
+ 0x41ef, 0x3743,
+ 0x41f9, 0x3b3e,
+ 0x4211, 0x3b41,
+ 0x4240, 0x37f1,
+ 0x4260, 0x472b,
+ 0x426a, 0x3b55,
+ 0x427a, 0x472c,
+ 0x428c, 0x472f,
+ 0x4294, 0x4731,
+ 0x42b5, 0x4010,
+ 0x42b9, 0x38a6,
+ 0x42bc, 0x3c8a,
+ 0x42f4, 0x3bb9,
+ 0x42fb, 0x3cee,
+ 0x42fc, 0x41e6,
+ 0x432b, 0x377d,
+ 0x436e, 0x46ca,
+ 0x4397, 0x473b,
+ 0x43ba, 0x435f,
+ 0x43c1, 0x4695,
+ 0x43d9, 0x433e,
+ 0x43df, 0x3e49,
+ 0x43ed, 0x4745,
+ 0x43f2, 0x3e48,
+ 0x4401, 0x474a,
+ 0x4402, 0x3b73,
+ 0x4413, 0x474f,
+ 0x4425, 0x4751,
+ 0x442d, 0x4752,
+ 0x447a, 0x37af,
+ 0x448f, 0x4758,
+ 0x449f, 0x3ae2,
+ 0x44a0, 0x37ed,
+ 0x44a2, 0x4079,
+ 0x44b0, 0x475c,
+ 0x44b7, 0x3fa1,
+ 0x44c0, 0x3c07,
+ 0x44c5, 0x4210,
+ 0x44ce, 0x3d23,
+ 0x44dd, 0x39dd,
+ 0x44df, 0x3d22,
+ 0x44e4, 0x37e2,
+ 0x44e9, 0x41cf,
+ 0x44ea, 0x3b71,
+ 0x44eb, 0x3cf2,
+ 0x44ec, 0x3eb4,
+ 0x44f4, 0x3992,
+ 0x4503, 0x469f,
+ 0x4504, 0x4763,
+ 0x4509, 0x3e50,
+ 0x450b, 0x37d4,
+ 0x4516, 0x37f9,
+ 0x451d, 0x3767,
+ 0x4527, 0x37f7,
+ 0x452e, 0x3cd3,
+ 0x4533, 0x3c51,
+ 0x453b, 0x476a,
+ 0x453d, 0x38c4,
+ 0x453f, 0x3e12,
+ 0x4543, 0x37f3,
+ 0x4551, 0x3ae4,
+ 0x4552, 0x40b3,
+ 0x4555, 0x423e,
+ 0x455c, 0x378b,
+ 0x4562, 0x4940,
+ 0x456a, 0x3804,
+ 0x4577, 0x476e,
+ 0x4585, 0x38c5,
+ 0x45e9, 0x3ee4,
+ 0x4606, 0x4773,
+ 0x460f, 0x3815,
+ 0x4615, 0x3843,
+ 0x4617, 0x4774,
+ 0x465b, 0x381d,
+ 0x467a, 0x39e9,
+ 0x4680, 0x3d01,
+ 0x46cf, 0x3ba0,
+ 0x46d0, 0x3dfa,
+ 0x46f5, 0x3b9f,
+ 0x4713, 0x3833,
+ 0x4718, 0x3dc7,
+ 0x474e, 0x3ebc,
+ 0x477c, 0x3dcd,
+ 0x4798, 0x4781,
+ 0x47a6, 0x40a3,
+ 0x47b6, 0x3eea,
+ 0x47d5, 0x431a,
+ 0x47ed, 0x4783,
+ 0x47f4, 0x432f,
+ 0x4800, 0x461e,
+ 0x480b, 0x4352,
+ 0x4837, 0x4787,
+ 0x485d, 0x410f,
+ 0x4871, 0x3d03,
+ 0x489b, 0x3bbd,
+ 0x48ad, 0x4791,
+ 0x48ae, 0x494d,
+ 0x48d0, 0x3da7,
+ 0x48dd, 0x4120,
+ 0x48ed, 0x4288,
+ 0x48f3, 0x3ec1,
+ 0x48fa, 0x3e44,
+ 0x4906, 0x3bc7,
+ 0x4911, 0x4584,
+ 0x491e, 0x4794,
+ 0x4925, 0x3c0f,
+ 0x492a, 0x46ae,
+ 0x492d, 0x46cd,
+ 0x4935, 0x3cc3,
+ 0x493c, 0x3bf8,
+ 0x493e, 0x3d06,
+ 0x4945, 0x47a3,
+ 0x4951, 0x47a4,
+ 0x4953, 0x42ad,
+ 0x4965, 0x3899,
+ 0x496a, 0x47a9,
+ 0x4972, 0x3a24,
+ 0x4989, 0x379b,
+ 0x49a1, 0x38b7,
+ 0x49a7, 0x47ae,
+ 0x49df, 0x38aa,
+ 0x49e5, 0x47b1,
+ 0x49e7, 0x4621,
+ 0x4a0f, 0x38c3,
+ 0x4a1d, 0x3bec,
+ 0x4a24, 0x47b2,
+ 0x4a35, 0x47b4,
+ 0x4a96, 0x3ce7,
+ 0x4ab4, 0x4361,
+ 0x4ab8, 0x3da8,
+ 0x4ad1, 0x38e3,
+ 0x4ae4, 0x47b7,
+ 0x4aff, 0x38f2,
+ 0x4b19, 0x47b9,
+ 0x4b2c, 0x461f,
+ 0x4b37, 0x41a9,
+ 0x4b6f, 0x3c16,
+ 0x4b70, 0x47c0,
+ 0x4b72, 0x38fc,
+ 0x4b7b, 0x3c8d,
+ 0x4b7e, 0x400a,
+ 0x4b8e, 0x39f7,
+ 0x4b90, 0x3c20,
+ 0x4b93, 0x3a8c,
+ 0x4b96, 0x3942,
+ 0x4b97, 0x3c24,
+ 0x4b9d, 0x47c2,
+ 0x4bbd, 0x3c23,
+ 0x4bbe, 0x3954,
+ 0x4bc0, 0x3ddc,
+ 0x4c04, 0x3fbb,
+ 0x4c07, 0x3fb7,
+ 0x4c0e, 0x390c,
+ 0x4c3b, 0x3f3c,
+ 0x4c3e, 0x457b,
+ 0x4c5b, 0x3ed9,
+ 0x4c6d, 0x47c9,
+ 0x4c7d, 0x3e66,
+ 0x4ca4, 0x48be,
+ 0x4cae, 0x3c42,
+ 0x4cb0, 0x3c45,
+ 0x4cb7, 0x3e21,
+ 0x4ccd, 0x4578,
+ 0x4ce1, 0x3ef3,
+ 0x4ced, 0x40ab,
+ 0x4d09, 0x3ed6,
+ 0x4d10, 0x4117,
+ 0x4d34, 0x3935,
+ 0x4d91, 0x43f5,
+ 0x4d9c, 0x48c4,
+ 0x4e00, 0x0253,
+ 0x4e01, 0x0255,
+ 0x4e03, 0x0256,
+ 0x4e04, 0x48fe,
+ 0x4e07, 0x1771,
+ 0x4e08, 0x0269,
+ 0x4e09, 0x0267,
+ 0x4e0a, 0x026a,
+ 0x4e0b, 0x0268,
+ 0x4e0c, 0x1772,
+ 0x4e0d, 0x0294,
+ 0x4e0e, 0x177a,
+ 0x4e0f, 0x1778,
+ 0x4e10, 0x0293,
+ 0x4e11, 0x0292,
+ 0x4e14, 0x02f2,
+ 0x4e15, 0x02f1,
+ 0x4e16, 0x02f0,
+ 0x4e18, 0x02f3,
+ 0x4e19, 0x02ef,
+ 0x4e1a, 0x48fd,
+ 0x4e1c, 0x48e0,
+ 0x4e1e, 0x036e,
+ 0x4e21, 0x3d6d,
+ 0x4e24, 0x458d,
+ 0x4e26, 0x0528,
+ 0x4e28, 0x0218,
+ 0x4e2a, 0x3f57,
+ 0x4e2b, 0x026b,
+ 0x4e2c, 0x44f3,
+ 0x4e2d, 0x0295,
+ 0x4e2e, 0x177b,
+ 0x4e30, 0x0296,
+ 0x4e31, 0x178e,
+ 0x4e32, 0x0415,
+ 0x4e33, 0x18f4,
+ 0x4e36, 0x0219,
+ 0x4e37, 0x4517,
+ 0x4e38, 0x026c,
+ 0x4e39, 0x0297,
+ 0x4e3b, 0x02f4,
+ 0x4e3c, 0x178f,
+ 0x4e3d, 0x4537,
+ 0x4e3f, 0x021a,
+ 0x4e41, 0x36af,
+ 0x4e42, 0x176c,
+ 0x4e43, 0x0257,
+ 0x4e45, 0x026e,
+ 0x4e47, 0x1773,
+ 0x4e48, 0x026f,
+ 0x4e49, 0x408e,
+ 0x4e4b, 0x0298,
+ 0x4e4d, 0x02f5,
+ 0x4e4e, 0x02f7,
+ 0x4e4f, 0x02f6,
+ 0x4e52, 0x0370,
+ 0x4e56, 0x0529,
+ 0x4e58, 0x0831,
+ 0x4e59, 0x0254,
+ 0x4e5a, 0x36b1,
+ 0x4e5b, 0x44e5,
+ 0x4e5c, 0x176d,
+ 0x4e5d, 0x0258,
+ 0x4e5e, 0x0271,
+ 0x4e5f, 0x0270,
+ 0x4e69, 0x0372,
+ 0x4e6a, 0x3de5,
+ 0x4e73, 0x052a,
+ 0x4e78, 0x3d8e,
+ 0x4e7e, 0x09fb,
+ 0x4e7f, 0x1e35,
+ 0x4e80, 0x458e,
+ 0x4e81, 0x43bc,
+ 0x4e82, 0x0dbe,
+ 0x4e83, 0x2361,
+ 0x4e85, 0x021b,
+ 0x4e86, 0x0259,
+ 0x4e87, 0x458f,
+ 0x4e88, 0x029a,
+ 0x4e89, 0x459c,
+ 0x4e8b, 0x052b,
+ 0x4e8c, 0x025a,
+ 0x4e8d, 0x1774,
+ 0x4e8e, 0x0272,
+ 0x4e91, 0x029b,
+ 0x4e92, 0x029d,
+ 0x4e93, 0x177c,
+ 0x4e94, 0x029e,
+ 0x4e95, 0x029c,
+ 0x4e98, 0x39c4,
+ 0x4e99, 0x0373,
+ 0x4e9a, 0x48d5,
+ 0x4e9b, 0x052c,
+ 0x4e9e, 0x052d,
+ 0x4e9f, 0x06a3,
+ 0x4ea0, 0x021c,
+ 0x4ea1, 0x0273,
+ 0x4ea2, 0x029f,
+ 0x4ea4, 0x0374,
+ 0x4ea5, 0x0376,
+ 0x4ea6, 0x0375,
+ 0x4ea8, 0x0416,
+ 0x4eab, 0x052e,
+ 0x4ead, 0x06a4,
+ 0x4eb3, 0x0832,
+ 0x4eb6, 0x2363,
+ 0x4eb7, 0x413c,
+ 0x4eb9, 0x3377,
+ 0x4eba, 0x025b,
+ 0x4ebb, 0x44e6,
+ 0x4ebc, 0x39b1,
+ 0x4ebf, 0x4590,
+ 0x4ec0, 0x02a1,
+ 0x4ec1, 0x02a0,
+ 0x4ec2, 0x177d,
+ 0x4ec3, 0x02a2,
+ 0x4ec4, 0x02a8,
+ 0x4ec6, 0x02a3,
+ 0x4ec8, 0x177f,
+ 0x4ec9, 0x177e,
+ 0x4eca, 0x02a6,
+ 0x4ecd, 0x02a5,
+ 0x4ece, 0x3f62,
+ 0x4ed4, 0x02fa,
+ 0x4ed8, 0x02f9,
+ 0x4ed9, 0x0300,
+ 0x4eda, 0x1795,
+ 0x4edc, 0x1791,
+ 0x4edd, 0x1794,
+ 0x4ede, 0x0301,
+ 0x4edf, 0x0311,
+ 0x4ee1, 0x1793,
+ 0x4ee3, 0x02fe,
+ 0x4ee5, 0x02f8,
+ 0x4ee8, 0x1790,
+ 0x4ee9, 0x1792,
+ 0x4eea, 0x48cb,
+ 0x4eeb, 0x4591,
+ 0x4eee, 0x3d76,
+ 0x4ef0, 0x0383,
+ 0x4ef1, 0x17ba,
+ 0x4ef2, 0x0380,
+ 0x4ef3, 0x0384,
+ 0x4ef4, 0x17c4,
+ 0x4ef5, 0x17b8,
+ 0x4ef6, 0x0381,
+ 0x4ef7, 0x17bc,
+ 0x4ef8, 0x39ad,
+ 0x4efb, 0x0382,
+ 0x4efd, 0x0385,
+ 0x4eff, 0x0377,
+ 0x4f00, 0x17bb,
+ 0x4f01, 0x0386,
+ 0x4f02, 0x17bf,
+ 0x4f03, 0x39c8,
+ 0x4f04, 0x17c3,
+ 0x4f05, 0x17c0,
+ 0x4f08, 0x17bd,
+ 0x4f09, 0x0378,
+ 0x4f0a, 0x037a,
+ 0x4f0b, 0x0387,
+ 0x4f0d, 0x037c,
+ 0x4f0e, 0x17b5,
+ 0x4f0f, 0x037f,
+ 0x4f10, 0x037d,
+ 0x4f12, 0x17c5,
+ 0x4f13, 0x17c2,
+ 0x4f14, 0x17b9,
+ 0x4f15, 0x037b,
+ 0x4f18, 0x17b6,
+ 0x4f19, 0x0379,
+ 0x4f1a, 0x453c,
+ 0x4f1d, 0x17be,
+ 0x4f22, 0x17c1,
+ 0x4f28, 0x453d,
+ 0x4f29, 0x39be,
+ 0x4f2c, 0x17b7,
+ 0x4f2d, 0x182f,
+ 0x4f2f, 0x042c,
+ 0x4f30, 0x041f,
+ 0x4f32, 0x393d,
+ 0x4f33, 0x1830,
+ 0x4f34, 0x041c,
+ 0x4f36, 0x042e,
+ 0x4f37, 0x4592,
+ 0x4f38, 0x0424,
+ 0x4f39, 0x3f65,
+ 0x4f3a, 0x0423,
+ 0x4f3b, 0x1824,
+ 0x4f3c, 0x0427,
+ 0x4f3d, 0x0422,
+ 0x4f3e, 0x1829,
+ 0x4f3f, 0x1831,
+ 0x4f41, 0x182d,
+ 0x4f42, 0x39cb,
+ 0x4f43, 0x0425,
+ 0x4f45, 0x3b8f,
+ 0x4f46, 0x0428,
+ 0x4f47, 0x0419,
+ 0x4f48, 0x0431,
+ 0x4f49, 0x1826,
+ 0x4f4b, 0x39b4,
+ 0x4f4c, 0x1900,
+ 0x4f4d, 0x0417,
+ 0x4f4e, 0x042d,
+ 0x4f4f, 0x0418,
+ 0x4f50, 0x0420,
+ 0x4f52, 0x182b,
+ 0x4f53, 0x1827,
+ 0x4f54, 0x0426,
+ 0x4f55, 0x041e,
+ 0x4f56, 0x1823,
+ 0x4f57, 0x041a,
+ 0x4f58, 0x182e,
+ 0x4f59, 0x042f,
+ 0x4f5a, 0x0432,
+ 0x4f5b, 0x041d,
+ 0x4f5c, 0x042a,
+ 0x4f5d, 0x0430,
+ 0x4f5e, 0x041b,
+ 0x4f5f, 0x182c,
+ 0x4f60, 0x042b,
+ 0x4f61, 0x1832,
+ 0x4f62, 0x1825,
+ 0x4f63, 0x0429,
+ 0x4f64, 0x1828,
+ 0x4f67, 0x182a,
+ 0x4f69, 0x053d,
+ 0x4f6a, 0x1902,
+ 0x4f6b, 0x190e,
+ 0x4f6c, 0x0535,
+ 0x4f6e, 0x190f,
+ 0x4f6f, 0x0530,
+ 0x4f70, 0x053a,
+ 0x4f72, 0x3c72,
+ 0x4f73, 0x0533,
+ 0x4f74, 0x18fc,
+ 0x4f75, 0x053b,
+ 0x4f76, 0x18fb,
+ 0x4f77, 0x18ff,
+ 0x4f78, 0x1906,
+ 0x4f79, 0x1904,
+ 0x4f7a, 0x0543,
+ 0x4f7b, 0x053e,
+ 0x4f7c, 0x18f6,
+ 0x4f7d, 0x18f8,
+ 0x4f7e, 0x0540,
+ 0x4f7f, 0x0534,
+ 0x4f80, 0x18f9,
+ 0x4f81, 0x1905,
+ 0x4f82, 0x190c,
+ 0x4f83, 0x0539,
+ 0x4f84, 0x18fe,
+ 0x4f85, 0x18f7,
+ 0x4f86, 0x0538,
+ 0x4f87, 0x18fa,
+ 0x4f88, 0x053c,
+ 0x4f89, 0x18fd,
+ 0x4f8a, 0x39b5,
+ 0x4f8b, 0x0537,
+ 0x4f8d, 0x0532,
+ 0x4f8f, 0x0541,
+ 0x4f90, 0x1907,
+ 0x4f91, 0x0542,
+ 0x4f92, 0x190b,
+ 0x4f94, 0x1909,
+ 0x4f95, 0x190d,
+ 0x4f96, 0x053f,
+ 0x4f97, 0x1901,
+ 0x4f98, 0x18f5,
+ 0x4f9a, 0x1903,
+ 0x4f9b, 0x0536,
+ 0x4f9c, 0x1908,
+ 0x4f9d, 0x0531,
+ 0x4f9e, 0x190a,
+ 0x4fa2, 0x39c7,
+ 0x4fa8, 0x453e,
+ 0x4fab, 0x4022,
+ 0x4fae, 0x06b4,
+ 0x4faf, 0x06a8,
+ 0x4fb0, 0x3d4a,
+ 0x4fb2, 0x1a5d,
+ 0x4fb3, 0x1a65,
+ 0x4fb5, 0x06a7,
+ 0x4fb6, 0x06af,
+ 0x4fb7, 0x06bb,
+ 0x4fb9, 0x1a6b,
+ 0x4fba, 0x1a69,
+ 0x4fbb, 0x1a64,
+ 0x4fbd, 0x4594,
+ 0x4fbf, 0x06a9,
+ 0x4fc0, 0x1a6a,
+ 0x4fc1, 0x1a60,
+ 0x4fc2, 0x06b7,
+ 0x4fc3, 0x06ae,
+ 0x4fc4, 0x06b6,
+ 0x4fc5, 0x1a5b,
+ 0x4fc7, 0x1a67,
+ 0x4fc8, 0x46e8,
+ 0x4fc9, 0x1a5e,
+ 0x4fca, 0x06b2,
+ 0x4fcb, 0x1a5f,
+ 0x4fcc, 0x39cf,
+ 0x4fcd, 0x1a5a,
+ 0x4fce, 0x06b9,
+ 0x4fcf, 0x06ac,
+ 0x4fd0, 0x06b5,
+ 0x4fd1, 0x06ab,
+ 0x4fd3, 0x1a5c,
+ 0x4fd4, 0x1a61,
+ 0x4fd6, 0x1a68,
+ 0x4fd7, 0x06b3,
+ 0x4fd8, 0x06b0,
+ 0x4fd9, 0x1a63,
+ 0x4fda, 0x06b8,
+ 0x4fdb, 0x1a66,
+ 0x4fdc, 0x1a62,
+ 0x4fdd, 0x06ad,
+ 0x4fde, 0x06ba,
+ 0x4fdf, 0x06b1,
+ 0x4fe0, 0x06aa,
+ 0x4fe1, 0x06a6,
+ 0x4fe4, 0x3c66,
+ 0x4fe5, 0x39d0,
+ 0x4fec, 0x1a6c,
+ 0x4fee, 0x084c,
+ 0x4fef, 0x0836,
+ 0x4ff1, 0x0846,
+ 0x4ff2, 0x3f28,
+ 0x4ff3, 0x084b,
+ 0x4ff4, 0x1c24,
+ 0x4ff5, 0x1c23,
+ 0x4ff6, 0x1c28,
+ 0x4ff8, 0x0839,
+ 0x4ff9, 0x37b3,
+ 0x4ffa, 0x0842,
+ 0x4ffd, 0x3f26,
+ 0x4ffe, 0x084f,
+ 0x5000, 0x0843,
+ 0x5003, 0x4596,
+ 0x5005, 0x1c1d,
+ 0x5006, 0x083c,
+ 0x5007, 0x1c1e,
+ 0x5008, 0x4024,
+ 0x5009, 0x0851,
+ 0x500b, 0x0848,
+ 0x500c, 0x0833,
+ 0x500e, 0x1c31,
+ 0x500f, 0x0a0c,
+ 0x5011, 0x0841,
+ 0x5012, 0x0840,
+ 0x5013, 0x1c1f,
+ 0x5014, 0x0844,
+ 0x5015, 0x1e45,
+ 0x5016, 0x083b,
+ 0x5017, 0x1c2a,
+ 0x5018, 0x084a,
+ 0x5019, 0x0849,
+ 0x501a, 0x083f,
+ 0x501b, 0x1c22,
+ 0x501c, 0x1c2b,
+ 0x501e, 0x1c1c,
+ 0x501f, 0x083e,
+ 0x5020, 0x1c2c,
+ 0x5021, 0x0847,
+ 0x5022, 0x1c20,
+ 0x5023, 0x0835,
+ 0x5025, 0x0838,
+ 0x5026, 0x0837,
+ 0x5027, 0x1c2d,
+ 0x5028, 0x0845,
+ 0x5029, 0x083a,
+ 0x502a, 0x084e,
+ 0x502b, 0x0850,
+ 0x502c, 0x1c27,
+ 0x502d, 0x084d,
+ 0x502e, 0x39cc,
+ 0x502f, 0x1c2f,
+ 0x5030, 0x1c21,
+ 0x5031, 0x1c30,
+ 0x5033, 0x1c25,
+ 0x5034, 0x3910,
+ 0x5035, 0x1c2e,
+ 0x5037, 0x1c26,
+ 0x503c, 0x083d,
+ 0x5040, 0x1e4d,
+ 0x5041, 0x1e41,
+ 0x5043, 0x0a00,
+ 0x5045, 0x1e46,
+ 0x5046, 0x1e4c,
+ 0x5047, 0x09ff,
+ 0x5048, 0x1e3f,
+ 0x5049, 0x0a03,
+ 0x504a, 0x1e43,
+ 0x504b, 0x1e3c,
+ 0x504c, 0x0a01,
+ 0x504d, 0x1e40,
+ 0x504e, 0x0a06,
+ 0x504f, 0x0a0b,
+ 0x5051, 0x1e51,
+ 0x5053, 0x1e3b,
+ 0x5055, 0x0a07,
+ 0x5056, 0x3f2c,
+ 0x5057, 0x1e50,
+ 0x5058, 0x39d1,
+ 0x505a, 0x0a02,
+ 0x505b, 0x1e42,
+ 0x505c, 0x09fe,
+ 0x505d, 0x1e3d,
+ 0x505e, 0x1e39,
+ 0x505f, 0x1e47,
+ 0x5060, 0x1e3a,
+ 0x5061, 0x1e38,
+ 0x5062, 0x1e44,
+ 0x5063, 0x1e4a,
+ 0x5065, 0x0a04,
+ 0x5066, 0x3dc9,
+ 0x5068, 0x20b8,
+ 0x5069, 0x1e48,
+ 0x506a, 0x1e37,
+ 0x506b, 0x1e49,
+ 0x506c, 0x39cd,
+ 0x506d, 0x0a0e,
+ 0x506e, 0x1e4e,
+ 0x506f, 0x0a0d,
+ 0x5070, 0x1e36,
+ 0x5072, 0x1e3e,
+ 0x5073, 0x1e4f,
+ 0x5074, 0x0a09,
+ 0x5075, 0x0a08,
+ 0x5076, 0x0a05,
+ 0x5077, 0x0a0a,
+ 0x507a, 0x09fc,
+ 0x507d, 0x09fd,
+ 0x5080, 0x0bec,
+ 0x5081, 0x39ce,
+ 0x5082, 0x20bb,
+ 0x5083, 0x20b4,
+ 0x5085, 0x0be9,
+ 0x5087, 0x20bc,
+ 0x5088, 0x439c,
+ 0x508b, 0x20b2,
+ 0x508c, 0x20b5,
+ 0x508d, 0x0be8,
+ 0x508e, 0x20b6,
+ 0x5090, 0x41ec,
+ 0x5091, 0x0beb,
+ 0x5092, 0x20ba,
+ 0x5094, 0x20b0,
+ 0x5095, 0x20af,
+ 0x5096, 0x0bed,
+ 0x5098, 0x0bee,
+ 0x5099, 0x0bea,
+ 0x509a, 0x0bef,
+ 0x509b, 0x20ae,
+ 0x509c, 0x20b9,
+ 0x509d, 0x20b7,
+ 0x509e, 0x20b1,
+ 0x50a2, 0x0be7,
+ 0x50a3, 0x20b3,
+ 0x50a6, 0x3f3f,
+ 0x50ac, 0x0dc5,
+ 0x50ad, 0x0dbf,
+ 0x50ae, 0x2367,
+ 0x50af, 0x0dc8,
+ 0x50b0, 0x236d,
+ 0x50b1, 0x2370,
+ 0x50b2, 0x0dc1,
+ 0x50b4, 0x236a,
+ 0x50b5, 0x0dc0,
+ 0x50b6, 0x2373,
+ 0x50b7, 0x0dc6,
+ 0x50b8, 0x2374,
+ 0x50ba, 0x236f,
+ 0x50bb, 0x0dc7,
+ 0x50bd, 0x2364,
+ 0x50be, 0x0dc4,
+ 0x50bf, 0x2365,
+ 0x50c1, 0x236e,
+ 0x50c2, 0x236c,
+ 0x50c4, 0x2368,
+ 0x50c5, 0x0dc3,
+ 0x50c6, 0x2366,
+ 0x50c7, 0x0dc9,
+ 0x50c8, 0x236b,
+ 0x50c9, 0x2372,
+ 0x50ca, 0x2369,
+ 0x50cb, 0x2371,
+ 0x50cd, 0x39c5,
+ 0x50ce, 0x0f88,
+ 0x50cf, 0x0f85,
+ 0x50d0, 0x38d1,
+ 0x50d1, 0x0f86,
+ 0x50d3, 0x261c,
+ 0x50d4, 0x2614,
+ 0x50d5, 0x0f84,
+ 0x50d6, 0x0f81,
+ 0x50d7, 0x2615,
+ 0x50d9, 0x3fce,
+ 0x50da, 0x0f83,
+ 0x50db, 0x2618,
+ 0x50dd, 0x261a,
+ 0x50de, 0x4031,
+ 0x50df, 0x3afd,
+ 0x50e0, 0x2621,
+ 0x50e1, 0x4171,
+ 0x50e3, 0x2620,
+ 0x50e4, 0x261b,
+ 0x50e5, 0x0f80,
+ 0x50e6, 0x2613,
+ 0x50e7, 0x0f7e,
+ 0x50e8, 0x2616,
+ 0x50e9, 0x0f89,
+ 0x50ea, 0x2619,
+ 0x50ec, 0x261d,
+ 0x50ed, 0x0f82,
+ 0x50ee, 0x0f7f,
+ 0x50ef, 0x261f,
+ 0x50f0, 0x261e,
+ 0x50f1, 0x0f87,
+ 0x50f3, 0x2617,
+ 0x50f4, 0x3ce9,
+ 0x50f5, 0x1105,
+ 0x50f6, 0x2883,
+ 0x50f8, 0x2880,
+ 0x50f9, 0x1106,
+ 0x50fb, 0x1104,
+ 0x50fc, 0x39d2,
+ 0x50fd, 0x2887,
+ 0x50fe, 0x2884,
+ 0x50ff, 0x287d,
+ 0x5100, 0x1103,
+ 0x5101, 0x4032,
+ 0x5102, 0x1107,
+ 0x5103, 0x287e,
+ 0x5104, 0x1102,
+ 0x5105, 0x110a,
+ 0x5106, 0x2881,
+ 0x5108, 0x1108,
+ 0x510a, 0x2888,
+ 0x510b, 0x2885,
+ 0x510d, 0x39c6,
+ 0x510e, 0x4034,
+ 0x5110, 0x128d,
+ 0x5111, 0x2b04,
+ 0x5112, 0x128a,
+ 0x5113, 0x2b01,
+ 0x5114, 0x128c,
+ 0x5115, 0x128e,
+ 0x5117, 0x2b02,
+ 0x5118, 0x128b,
+ 0x511a, 0x2b03,
+ 0x511c, 0x2b00,
+ 0x511f, 0x13b5,
+ 0x5120, 0x2d3e,
+ 0x5121, 0x13b6,
+ 0x5122, 0x2d3c,
+ 0x5124, 0x2d3d,
+ 0x5125, 0x2d3b,
+ 0x5126, 0x2d3a,
+ 0x5129, 0x2d3f,
+ 0x512a, 0x13b4,
+ 0x512b, 0x39ae,
+ 0x512d, 0x2f0f,
+ 0x5130, 0x287f,
+ 0x5131, 0x2f0e,
+ 0x5132, 0x13b7,
+ 0x5133, 0x1575,
+ 0x5134, 0x307a,
+ 0x5137, 0x1668,
+ 0x5139, 0x32c6,
+ 0x513a, 0x32c5,
+ 0x513b, 0x16bc,
+ 0x513c, 0x16bb,
+ 0x513d, 0x340e,
+ 0x513f, 0x025c,
+ 0x5140, 0x0274,
+ 0x5141, 0x02aa,
+ 0x5143, 0x02a9,
+ 0x5144, 0x0303,
+ 0x5145, 0x0302,
+ 0x5146, 0x038a,
+ 0x5147, 0x0389,
+ 0x5148, 0x038b,
+ 0x5149, 0x0388,
+ 0x514b, 0x0434,
+ 0x514c, 0x0433,
+ 0x514d, 0x0435,
+ 0x5152, 0x0545,
+ 0x5154, 0x0544,
+ 0x5155, 0x0546,
+ 0x5156, 0x439a,
+ 0x5157, 0x06bc,
+ 0x5159, 0x0119,
+ 0x515a, 0x1c32,
+ 0x515b, 0x011a,
+ 0x515c, 0x0a0f,
+ 0x515d, 0x011c,
+ 0x515e, 0x011b,
+ 0x515f, 0x20bd,
+ 0x5160, 0x403a,
+ 0x5161, 0x011d,
+ 0x5162, 0x0f8a,
+ 0x5163, 0x011e,
+ 0x5165, 0x025d,
+ 0x5167, 0x02ab,
+ 0x5168, 0x038c,
+ 0x5169, 0x0547,
+ 0x516a, 0x403c,
+ 0x516b, 0x025e,
+ 0x516c, 0x02ae,
+ 0x516d, 0x02ac,
+ 0x5171, 0x038d,
+ 0x5174, 0x453f,
+ 0x5175, 0x0436,
+ 0x5176, 0x0549,
+ 0x5177, 0x0548,
+ 0x5178, 0x054a,
+ 0x5179, 0x3ace,
+ 0x517c, 0x0852,
+ 0x5180, 0x128f,
+ 0x5182, 0x021d,
+ 0x5186, 0x439f,
+ 0x5187, 0x1779,
+ 0x5188, 0x36b6,
+ 0x5189, 0x0304,
+ 0x518d, 0x038e,
+ 0x518f, 0x1833,
+ 0x5191, 0x06be,
+ 0x5192, 0x06bd,
+ 0x5193, 0x1c34,
+ 0x5194, 0x1c33,
+ 0x5195, 0x0a10,
+ 0x5196, 0x021e,
+ 0x5197, 0x02af,
+ 0x5198, 0x1780,
+ 0x519a, 0x3ea3,
+ 0x519c, 0x4540,
+ 0x519e, 0x1910,
+ 0x51a0, 0x06bf,
+ 0x51a2, 0x0855,
+ 0x51a4, 0x0853,
+ 0x51a7, 0x3ea6,
+ 0x51a8, 0x39da,
+ 0x51aa, 0x1290,
+ 0x51ab, 0x021f,
+ 0x51ac, 0x0306,
+ 0x51b0, 0x038f,
+ 0x51b1, 0x17c6,
+ 0x51b2, 0x4048,
+ 0x51b3, 0x4051,
+ 0x51b4, 0x3d7c,
+ 0x51b5, 0x4012,
+ 0x51b6, 0x0437,
+ 0x51b8, 0x4049,
+ 0x51b9, 0x1834,
+ 0x51bc, 0x1911,
+ 0x51bd, 0x054b,
+ 0x51be, 0x1912,
+ 0x51c3, 0x39db,
+ 0x51c4, 0x1c36,
+ 0x51c6, 0x0858,
+ 0x51c7, 0x422a,
+ 0x51c8, 0x1c38,
+ 0x51c9, 0x404b,
+ 0x51ca, 0x1c35,
+ 0x51cb, 0x0859,
+ 0x51cc, 0x0857,
+ 0x51cd, 0x0856,
+ 0x51ce, 0x1c39,
+ 0x51cf, 0x404c,
+ 0x51d0, 0x1e52,
+ 0x51d1, 0x404d,
+ 0x51d2, 0x3dad,
+ 0x51d3, 0x404f,
+ 0x51d4, 0x20be,
+ 0x51d7, 0x2375,
+ 0x51d8, 0x2622,
+ 0x51db, 0x459a,
+ 0x51dc, 0x110b,
+ 0x51dd, 0x1291,
+ 0x51de, 0x2b05,
+ 0x51df, 0x424f,
+ 0x51e0, 0x025f,
+ 0x51e1, 0x026d,
+ 0x51e2, 0x4052,
+ 0x51e4, 0x4541,
+ 0x51ed, 0x4054,
+ 0x51f0, 0x0a11,
+ 0x51f1, 0x0bf1,
+ 0x51f3, 0x0f8b,
+ 0x51f4, 0x4178,
+ 0x51f5, 0x176e,
+ 0x51f6, 0x02b0,
+ 0x51f8, 0x0309,
+ 0x51f9, 0x0307,
+ 0x51fc, 0x459b,
+ 0x51fd, 0x054c,
+ 0x51fe, 0x3f0a,
+ 0x5200, 0x0260,
+ 0x5202, 0x36b3,
+ 0x5203, 0x0275,
+ 0x5205, 0x43a1,
+ 0x5206, 0x02b1,
+ 0x5209, 0x1797,
+ 0x520a, 0x030a,
+ 0x520b, 0x4059,
+ 0x520c, 0x1796,
+ 0x520e, 0x0393,
+ 0x5210, 0x17c8,
+ 0x5211, 0x0391,
+ 0x5213, 0x17c7,
+ 0x5216, 0x0394,
+ 0x5217, 0x0390,
+ 0x521c, 0x1835,
+ 0x521d, 0x068b,
+ 0x521e, 0x1836,
+ 0x521f, 0x3f60,
+ 0x5220, 0x4930,
+ 0x5221, 0x1837,
+ 0x5224, 0x043a,
+ 0x5225, 0x0439,
+ 0x5226, 0x405a,
+ 0x5227, 0x43a2,
+ 0x5228, 0x043d,
+ 0x5229, 0x043b,
+ 0x522e, 0x0552,
+ 0x5230, 0x0551,
+ 0x5231, 0x1917,
+ 0x5232, 0x1914,
+ 0x5234, 0x3efb,
+ 0x5235, 0x1913,
+ 0x5236, 0x0553,
+ 0x5237, 0x054f,
+ 0x5238, 0x054e,
+ 0x523a, 0x0550,
+ 0x523b, 0x054d,
+ 0x523c, 0x405b,
+ 0x5241, 0x0554,
+ 0x5243, 0x06c1,
+ 0x5244, 0x1a6d,
+ 0x5246, 0x1916,
+ 0x5247, 0x06c6,
+ 0x5249, 0x1a6e,
+ 0x524a, 0x06c2,
+ 0x524b, 0x06c5,
+ 0x524c, 0x06c4,
+ 0x524d, 0x06c3,
+ 0x524e, 0x06c0,
+ 0x5252, 0x1c3c,
+ 0x5254, 0x085c,
+ 0x5255, 0x1c3f,
+ 0x5256, 0x085a,
+ 0x5257, 0x405d,
+ 0x5259, 0x39e4,
+ 0x525a, 0x1c3b,
+ 0x525b, 0x085d,
+ 0x525c, 0x085b,
+ 0x525d, 0x085e,
+ 0x525e, 0x1c3d,
+ 0x5260, 0x3f29,
+ 0x5261, 0x1c3a,
+ 0x5262, 0x1c40,
+ 0x5268, 0x4619,
+ 0x5269, 0x0bf5,
+ 0x526a, 0x0a12,
+ 0x526b, 0x1e53,
+ 0x526c, 0x1e55,
+ 0x526d, 0x1e54,
+ 0x526e, 0x1e56,
+ 0x526f, 0x0a13,
+ 0x5272, 0x0bf2,
+ 0x5273, 0x3f43,
+ 0x5274, 0x0bf3,
+ 0x5277, 0x0dcb,
+ 0x5278, 0x2377,
+ 0x5279, 0x43a3,
+ 0x527a, 0x2376,
+ 0x527b, 0x2378,
+ 0x527d, 0x0dcc,
+ 0x527f, 0x0dca,
+ 0x5280, 0x2623,
+ 0x5282, 0x0f8d,
+ 0x5283, 0x0f8c,
+ 0x5284, 0x2776,
+ 0x5287, 0x110c,
+ 0x528a, 0x1110,
+ 0x528b, 0x2889,
+ 0x528d, 0x110f,
+ 0x528f, 0x3dbf,
+ 0x5290, 0x459d,
+ 0x5291, 0x1292,
+ 0x5293, 0x1293,
+ 0x5294, 0x405e,
+ 0x5296, 0x307c,
+ 0x5297, 0x32c8,
+ 0x5298, 0x32c7,
+ 0x5299, 0x340f,
+ 0x529a, 0x3f68,
+ 0x529b, 0x0262,
+ 0x529f, 0x030c,
+ 0x52a0, 0x030b,
+ 0x52a1, 0x4542,
+ 0x52a3, 0x0395,
+ 0x52a4, 0x39e5,
+ 0x52a6, 0x17c9,
+ 0x52a8, 0x4543,
+ 0x52a9, 0x043f,
+ 0x52ab, 0x043e,
+ 0x52ac, 0x0441,
+ 0x52ad, 0x1838,
+ 0x52b5, 0x405c,
+ 0x52b9, 0x405f,
+ 0x52bb, 0x0556,
+ 0x52bc, 0x1918,
+ 0x52be, 0x0555,
+ 0x52c0, 0x1a6f,
+ 0x52c1, 0x06ca,
+ 0x52c2, 0x1a70,
+ 0x52c3, 0x06c9,
+ 0x52c5, 0x4060,
+ 0x52c7, 0x06c7,
+ 0x52c9, 0x06c8,
+ 0x52cc, 0x3ee1,
+ 0x52cd, 0x1c41,
+ 0x52d0, 0x4109,
+ 0x52d1, 0x3f2a,
+ 0x52d2, 0x0a14,
+ 0x52d3, 0x1e58,
+ 0x52d5, 0x0a17,
+ 0x52d6, 0x1e57,
+ 0x52d7, 0x0acf,
+ 0x52d8, 0x0a16,
+ 0x52d9, 0x0a15,
+ 0x52db, 0x0bf8,
+ 0x52dd, 0x0bf7,
+ 0x52de, 0x0bf6,
+ 0x52df, 0x0dcd,
+ 0x52e0, 0x4063,
+ 0x52e1, 0x39e7,
+ 0x52e2, 0x0dd0,
+ 0x52e4, 0x0dcf,
+ 0x52e6, 0x0dce,
+ 0x52e9, 0x2625,
+ 0x52eb, 0x2626,
+ 0x52ef, 0x288c,
+ 0x52f0, 0x1111,
+ 0x52f1, 0x288b,
+ 0x52f3, 0x1294,
+ 0x52f4, 0x2d40,
+ 0x52f5, 0x13b8,
+ 0x52f7, 0x307d,
+ 0x52f8, 0x1609,
+ 0x52f9, 0x0220,
+ 0x52fa, 0x0276,
+ 0x52fb, 0x02b4,
+ 0x52fc, 0x1781,
+ 0x52fe, 0x02b5,
+ 0x5301, 0x3d79,
+ 0x5305, 0x030d,
+ 0x5308, 0x0396,
+ 0x5309, 0x183a,
+ 0x530a, 0x1919,
+ 0x530d, 0x06cb,
+ 0x530e, 0x1c42,
+ 0x530f, 0x0a19,
+ 0x5310, 0x0a18,
+ 0x5311, 0x20c0,
+ 0x5312, 0x20bf,
+ 0x5315, 0x0263,
+ 0x5316, 0x02b7,
+ 0x5317, 0x030f,
+ 0x5319, 0x0a1a,
+ 0x531a, 0x176f,
+ 0x531c, 0x1798,
+ 0x531d, 0x0310,
+ 0x531f, 0x17cb,
+ 0x5320, 0x0398,
+ 0x5321, 0x0397,
+ 0x5322, 0x17ca,
+ 0x5323, 0x0442,
+ 0x5327, 0x459e,
+ 0x532a, 0x085f,
+ 0x532c, 0x3f36,
+ 0x532d, 0x1e59,
+ 0x532f, 0x0dd2,
+ 0x5330, 0x2627,
+ 0x5331, 0x0f8e,
+ 0x5332, 0x3fd0,
+ 0x5333, 0x406d,
+ 0x5334, 0x2b06,
+ 0x5337, 0x31c7,
+ 0x5338, 0x0221,
+ 0x5339, 0x02b8,
+ 0x533b, 0x4544,
+ 0x533c, 0x191b,
+ 0x533d, 0x1a71,
+ 0x533e, 0x0a1d,
+ 0x533f, 0x0a1b,
+ 0x5341, 0x0264,
+ 0x5342, 0x4947,
+ 0x5343, 0x0277,
+ 0x5344, 0x016b,
+ 0x5345, 0x02bb,
+ 0x5347, 0x02ba,
+ 0x5348, 0x02b9,
+ 0x5349, 0x0313,
+ 0x534a, 0x0312,
+ 0x534c, 0x1799,
+ 0x534d, 0x17cc,
+ 0x534e, 0x4545,
+ 0x5351, 0x055a,
+ 0x5352, 0x0557,
+ 0x5353, 0x0559,
+ 0x5354, 0x0558,
+ 0x5357, 0x06cc,
+ 0x535a, 0x0bf9,
+ 0x535c, 0x0265,
+ 0x535d, 0x4501,
+ 0x535e, 0x02bc,
+ 0x535f, 0x43a7,
+ 0x5360, 0x0315,
+ 0x5361, 0x0314,
+ 0x5363, 0x183b,
+ 0x5364, 0x480a,
+ 0x5366, 0x055b,
+ 0x5367, 0x3ecd,
+ 0x5369, 0x0222,
+ 0x536c, 0x1782,
+ 0x536d, 0x407a,
+ 0x536e, 0x0317,
+ 0x536f, 0x0316,
+ 0x5370, 0x0399,
+ 0x5372, 0x183c,
+ 0x5373, 0x0443,
+ 0x5374, 0x407b,
+ 0x5375, 0x0444,
+ 0x5377, 0x055c,
+ 0x537b, 0x06cd,
+ 0x537c, 0x1a72,
+ 0x537d, 0x4901,
+ 0x537e, 0x407d,
+ 0x537f, 0x0860,
+ 0x5382, 0x1770,
+ 0x5384, 0x02bd,
+ 0x538a, 0x17cd,
+ 0x538e, 0x183d,
+ 0x5392, 0x191c,
+ 0x5393, 0x4082,
+ 0x5394, 0x191d,
+ 0x5396, 0x1a74,
+ 0x5397, 0x1a73,
+ 0x5398, 0x1a76,
+ 0x5399, 0x1a75,
+ 0x539a, 0x06ce,
+ 0x539c, 0x1e5a,
+ 0x539d, 0x0862,
+ 0x539e, 0x1c43,
+ 0x539f, 0x0861,
+ 0x53a0, 0x4084,
+ 0x53a2, 0x3e2b,
+ 0x53a4, 0x20c1,
+ 0x53a5, 0x0bfa,
+ 0x53a6, 0x413b,
+ 0x53a7, 0x20c2,
+ 0x53a8, 0x413e,
+ 0x53a9, 0x45a0,
+ 0x53aa, 0x3fc6,
+ 0x53ab, 0x4085,
+ 0x53ac, 0x2628,
+ 0x53ad, 0x0f8f,
+ 0x53ae, 0x4086,
+ 0x53b0, 0x45a2,
+ 0x53b2, 0x1112,
+ 0x53b4, 0x307e,
+ 0x53b6, 0x0223,
+ 0x53b9, 0x1783,
+ 0x53bb, 0x0318,
+ 0x53c1, 0x408b,
+ 0x53c2, 0x43a6,
+ 0x53c3, 0x0a1e,
+ 0x53c5, 0x408c,
+ 0x53c8, 0x0266,
+ 0x53c9, 0x0278,
+ 0x53ca, 0x02bf,
+ 0x53cb, 0x02be,
+ 0x53cc, 0x38b6,
+ 0x53cd, 0x02c0,
+ 0x53d0, 0x39fa,
+ 0x53d1, 0x4546,
+ 0x53d2, 0x3e3d,
+ 0x53d4, 0x0560,
+ 0x53d6, 0x055f,
+ 0x53d7, 0x0561,
+ 0x53d8, 0x4547,
+ 0x53d9, 0x4090,
+ 0x53da, 0x3f39,
+ 0x53db, 0x06cf,
+ 0x53df, 0x0863,
+ 0x53e0, 0x4093,
+ 0x53e1, 0x2b07,
+ 0x53e2, 0x14c9,
+ 0x53e3, 0x0279,
+ 0x53e4, 0x031a,
+ 0x53e5, 0x0329,
+ 0x53e6, 0x0324,
+ 0x53e8, 0x031f,
+ 0x53e9, 0x031e,
+ 0x53ea, 0x0325,
+ 0x53eb, 0x0323,
+ 0x53ec, 0x031c,
+ 0x53ed, 0x032a,
+ 0x53ee, 0x031d,
+ 0x53ef, 0x0319,
+ 0x53f0, 0x0328,
+ 0x53f1, 0x0327,
+ 0x53f2, 0x0326,
+ 0x53f3, 0x031b,
+ 0x53f5, 0x0322,
+ 0x53f6, 0x4096,
+ 0x53f7, 0x3808,
+ 0x53f8, 0x0321,
+ 0x53fb, 0x032b,
+ 0x53fc, 0x0320,
+ 0x53fe, 0x40c1,
+ 0x5401, 0x03a0,
+ 0x5403, 0x03a6,
+ 0x5404, 0x03a2,
+ 0x5406, 0x03a8,
+ 0x5407, 0x17ce,
+ 0x5408, 0x03a5,
+ 0x5409, 0x039b,
+ 0x540a, 0x039e,
+ 0x540b, 0x03a1,
+ 0x540c, 0x039d,
+ 0x540d, 0x03a4,
+ 0x540e, 0x03a7,
+ 0x540f, 0x039c,
+ 0x5410, 0x039f,
+ 0x5411, 0x03a3,
+ 0x5412, 0x03a9,
+ 0x5413, 0x4098,
+ 0x5414, 0x3c77,
+ 0x5416, 0x3e7f,
+ 0x5418, 0x1847,
+ 0x5419, 0x1844,
+ 0x541a, 0x3e64,
+ 0x541b, 0x0451,
+ 0x541c, 0x1845,
+ 0x541d, 0x0445,
+ 0x541e, 0x0447,
+ 0x541f, 0x045f,
+ 0x5420, 0x045a,
+ 0x5421, 0x4203,
+ 0x5423, 0x45a3,
+ 0x5424, 0x184c,
+ 0x5425, 0x1846,
+ 0x5426, 0x0449,
+ 0x5427, 0x044b,
+ 0x5428, 0x184b,
+ 0x5429, 0x0452,
+ 0x542a, 0x1841,
+ 0x542b, 0x045e,
+ 0x542c, 0x0460,
+ 0x542d, 0x0446,
+ 0x542e, 0x0457,
+ 0x542f, 0x40ac,
+ 0x5430, 0x183f,
+ 0x5431, 0x045d,
+ 0x5432, 0x3e75,
+ 0x5433, 0x044e,
+ 0x5435, 0x0458,
+ 0x5437, 0x1840,
+ 0x5438, 0x0456,
+ 0x5439, 0x0454,
+ 0x543b, 0x0455,
+ 0x543c, 0x045b,
+ 0x543d, 0x1848,
+ 0x543e, 0x0448,
+ 0x5440, 0x045c,
+ 0x5441, 0x184a,
+ 0x5442, 0x0450,
+ 0x5443, 0x044d,
+ 0x5445, 0x1843,
+ 0x5446, 0x044c,
+ 0x5447, 0x184d,
+ 0x5448, 0x044f,
+ 0x544a, 0x0453,
+ 0x544b, 0x3ed1,
+ 0x544d, 0x3ea7,
+ 0x544e, 0x044a,
+ 0x544f, 0x1849,
+ 0x5454, 0x1842,
+ 0x5460, 0x192e,
+ 0x5461, 0x192d,
+ 0x5462, 0x0573,
+ 0x5463, 0x1930,
+ 0x5464, 0x1932,
+ 0x5465, 0x1927,
+ 0x5466, 0x192a,
+ 0x5467, 0x1931,
+ 0x5468, 0x0574,
+ 0x5469, 0x3f32,
+ 0x546a, 0x3d83,
+ 0x546b, 0x1924,
+ 0x546c, 0x1928,
+ 0x546d, 0x409d,
+ 0x546f, 0x192c,
+ 0x5470, 0x1a85,
+ 0x5471, 0x056f,
+ 0x5472, 0x1a89,
+ 0x5473, 0x0562,
+ 0x5474, 0x1929,
+ 0x5475, 0x0563,
+ 0x5476, 0x0570,
+ 0x5477, 0x0569,
+ 0x5478, 0x0565,
+ 0x547a, 0x1925,
+ 0x547b, 0x0568,
+ 0x547c, 0x056d,
+ 0x547d, 0x0576,
+ 0x547e, 0x1926,
+ 0x547f, 0x191f,
+ 0x5480, 0x0567,
+ 0x5481, 0x1920,
+ 0x5482, 0x1922,
+ 0x5484, 0x056a,
+ 0x5485, 0x46d9,
+ 0x5486, 0x056c,
+ 0x5487, 0x191e,
+ 0x5488, 0x1923,
+ 0x548b, 0x0575,
+ 0x548c, 0x0571,
+ 0x548d, 0x192b,
+ 0x548e, 0x0577,
+ 0x548f, 0x40a1,
+ 0x5490, 0x056e,
+ 0x5491, 0x1921,
+ 0x5492, 0x056b,
+ 0x5493, 0x45a7,
+ 0x5494, 0x3e98,
+ 0x5495, 0x0566,
+ 0x5496, 0x0564,
+ 0x5497, 0x3e8a,
+ 0x5498, 0x192f,
+ 0x549a, 0x0572,
+ 0x549c, 0x3f66,
+ 0x549e, 0x47ed,
+ 0x54a0, 0x1a84,
+ 0x54a1, 0x1a78,
+ 0x54a2, 0x1a87,
+ 0x54a3, 0x45a8,
+ 0x54a4, 0x40a2,
+ 0x54a5, 0x1a7a,
+ 0x54a6, 0x06d6,
+ 0x54a7, 0x06e4,
+ 0x54a8, 0x06d2,
+ 0x54a9, 0x06e3,
+ 0x54aa, 0x06db,
+ 0x54ab, 0x06e0,
+ 0x54ac, 0x06d0,
+ 0x54ad, 0x1a79,
+ 0x54ae, 0x1a7f,
+ 0x54af, 0x06df,
+ 0x54b0, 0x1a8b,
+ 0x54b1, 0x06e1,
+ 0x54b2, 0x3744,
+ 0x54b3, 0x06d7,
+ 0x54b4, 0x45a9,
+ 0x54b6, 0x1a81,
+ 0x54b7, 0x1a7e,
+ 0x54b8, 0x06d5,
+ 0x54b9, 0x45aa,
+ 0x54ba, 0x1a77,
+ 0x54bb, 0x06e2,
+ 0x54bc, 0x1a86,
+ 0x54bd, 0x06da,
+ 0x54be, 0x1a88,
+ 0x54bf, 0x06e5,
+ 0x54c0, 0x06d1,
+ 0x54c1, 0x06dc,
+ 0x54c2, 0x06d9,
+ 0x54c3, 0x1a7c,
+ 0x54c4, 0x06dd,
+ 0x54c5, 0x1a82,
+ 0x54c7, 0x06d8,
+ 0x54c8, 0x06de,
+ 0x54c9, 0x06d4,
+ 0x54cb, 0x39a3,
+ 0x54cc, 0x43a8,
+ 0x54cd, 0x3a00,
+ 0x54ce, 0x06d3,
+ 0x54cf, 0x1a7b,
+ 0x54d0, 0x45ab,
+ 0x54d6, 0x1a80,
+ 0x54da, 0x4923,
+ 0x54de, 0x1a8a,
+ 0x54e0, 0x1c57,
+ 0x54e1, 0x0870,
+ 0x54e2, 0x1c45,
+ 0x54e3, 0x4341,
+ 0x54e4, 0x1c4a,
+ 0x54e5, 0x0869,
+ 0x54e6, 0x0874,
+ 0x54e7, 0x1c48,
+ 0x54e8, 0x0864,
+ 0x54e9, 0x086e,
+ 0x54ea, 0x0873,
+ 0x54eb, 0x1c4f,
+ 0x54ed, 0x086f,
+ 0x54ee, 0x0872,
+ 0x54ef, 0x45ac,
+ 0x54f1, 0x1c52,
+ 0x54f2, 0x086a,
+ 0x54f3, 0x1c49,
+ 0x54f7, 0x1c55,
+ 0x54fa, 0x086c,
+ 0x54fb, 0x1c54,
+ 0x54fc, 0x0868,
+ 0x54fd, 0x0877,
+ 0x54ff, 0x1c4c,
+ 0x5501, 0x0866,
+ 0x5502, 0x3ccc,
+ 0x5503, 0x1c59,
+ 0x5504, 0x1c4d,
+ 0x5505, 0x1c51,
+ 0x5506, 0x086b,
+ 0x5507, 0x0876,
+ 0x5508, 0x1c4e,
+ 0x5509, 0x0871,
+ 0x550a, 0x1c53,
+ 0x550b, 0x1c5a,
+ 0x550c, 0x1e69,
+ 0x550d, 0x3a73,
+ 0x550e, 0x1c58,
+ 0x550f, 0x0878,
+ 0x5510, 0x0865,
+ 0x5511, 0x1c50,
+ 0x5512, 0x1c47,
+ 0x5513, 0x3ea9,
+ 0x5514, 0x086d,
+ 0x5517, 0x1c46,
+ 0x5518, 0x45ad,
+ 0x551a, 0x1c4b,
+ 0x551e, 0x3ea8,
+ 0x5523, 0x45ae,
+ 0x5525, 0x4309,
+ 0x5526, 0x1c44,
+ 0x5527, 0x0875,
+ 0x5528, 0x45af,
+ 0x552a, 0x1e61,
+ 0x552b, 0x409a,
+ 0x552c, 0x0a31,
+ 0x552d, 0x1e6f,
+ 0x552e, 0x0a2f,
+ 0x552f, 0x0a2c,
+ 0x5530, 0x1e66,
+ 0x5531, 0x0a28,
+ 0x5532, 0x1e6a,
+ 0x5533, 0x0a33,
+ 0x5534, 0x1e60,
+ 0x5535, 0x1e65,
+ 0x5536, 0x1e64,
+ 0x5537, 0x0867,
+ 0x5538, 0x0a2e,
+ 0x5539, 0x1e6d,
+ 0x553b, 0x1e70,
+ 0x553c, 0x1e5d,
+ 0x553e, 0x0c0c,
+ 0x553f, 0x43a9,
+ 0x5540, 0x1e71,
+ 0x5541, 0x0a34,
+ 0x5543, 0x0a26,
+ 0x5544, 0x0a23,
+ 0x5545, 0x1e68,
+ 0x5546, 0x0a20,
+ 0x5547, 0x40aa,
+ 0x5548, 0x1e6e,
+ 0x5549, 0x4068,
+ 0x554a, 0x0a27,
+ 0x554b, 0x1e72,
+ 0x554d, 0x1e5e,
+ 0x554e, 0x1e6c,
+ 0x554f, 0x0a2a,
+ 0x5550, 0x1e5f,
+ 0x5551, 0x1e62,
+ 0x5552, 0x1e67,
+ 0x5553, 0x43ae,
+ 0x5555, 0x0a2b,
+ 0x5556, 0x0a29,
+ 0x5557, 0x0a35,
+ 0x555c, 0x0a30,
+ 0x555d, 0x40a0,
+ 0x555e, 0x0a24,
+ 0x555f, 0x0abc,
+ 0x5561, 0x0a25,
+ 0x5562, 0x1e63,
+ 0x5563, 0x0a32,
+ 0x5564, 0x0a2d,
+ 0x5565, 0x1e6b,
+ 0x5566, 0x0a22,
+ 0x5569, 0x3e9f,
+ 0x556a, 0x0a21,
+ 0x556b, 0x3b2e,
+ 0x5571, 0x3bc6,
+ 0x5572, 0x3e8b,
+ 0x5573, 0x3f24,
+ 0x5575, 0x1e5b,
+ 0x5577, 0x20c7,
+ 0x5579, 0x435d,
+ 0x557b, 0x0bfb,
+ 0x557c, 0x0bfe,
+ 0x557d, 0x20d2,
+ 0x557e, 0x0c12,
+ 0x557f, 0x20d5,
+ 0x5580, 0x0bfc,
+ 0x5581, 0x20ce,
+ 0x5582, 0x0c02,
+ 0x5583, 0x0c08,
+ 0x5584, 0x0d1b,
+ 0x5586, 0x40ae,
+ 0x5587, 0x0c06,
+ 0x5588, 0x20cb,
+ 0x5589, 0x0c13,
+ 0x558a, 0x0bff,
+ 0x558b, 0x0c07,
+ 0x558c, 0x20d3,
+ 0x558d, 0x2387,
+ 0x558e, 0x20d8,
+ 0x558f, 0x20cc,
+ 0x5590, 0x430e,
+ 0x5591, 0x20c3,
+ 0x5592, 0x20d0,
+ 0x5593, 0x20ca,
+ 0x5594, 0x0c05,
+ 0x5595, 0x20d6,
+ 0x5598, 0x0c01,
+ 0x5599, 0x0c15,
+ 0x559a, 0x0c0e,
+ 0x559c, 0x0c03,
+ 0x559d, 0x0c00,
+ 0x559f, 0x0c0b,
+ 0x55a1, 0x20d7,
+ 0x55a2, 0x20c9,
+ 0x55a3, 0x20cf,
+ 0x55a4, 0x20d1,
+ 0x55a5, 0x20c5,
+ 0x55a6, 0x20d4,
+ 0x55a7, 0x0bfd,
+ 0x55a8, 0x20c4,
+ 0x55a9, 0x40af,
+ 0x55aa, 0x0c04,
+ 0x55ab, 0x0c14,
+ 0x55ac, 0x0c10,
+ 0x55ad, 0x20c6,
+ 0x55ae, 0x0c0a,
+ 0x55b0, 0x38f5,
+ 0x55b1, 0x0c11,
+ 0x55b2, 0x0c0d,
+ 0x55b3, 0x0c09,
+ 0x55b4, 0x39fe,
+ 0x55b5, 0x20cd,
+ 0x55b9, 0x43aa,
+ 0x55ba, 0x3e89,
+ 0x55bb, 0x0c0f,
+ 0x55bc, 0x3dc3,
+ 0x55bf, 0x2385,
+ 0x55c0, 0x2381,
+ 0x55c1, 0x3e4f,
+ 0x55c2, 0x2390,
+ 0x55c3, 0x237a,
+ 0x55c4, 0x2383,
+ 0x55c5, 0x0de0,
+ 0x55c7, 0x0dd9,
+ 0x55c8, 0x238c,
+ 0x55c9, 0x0de3,
+ 0x55ca, 0x237f,
+ 0x55cb, 0x237e,
+ 0x55cc, 0x237c,
+ 0x55cd, 0x238e,
+ 0x55ce, 0x0dd7,
+ 0x55cf, 0x2388,
+ 0x55d0, 0x237d,
+ 0x55d1, 0x0dda,
+ 0x55d2, 0x2386,
+ 0x55d3, 0x0dd5,
+ 0x55d4, 0x2382,
+ 0x55d5, 0x2389,
+ 0x55d6, 0x238b,
+ 0x55d7, 0x45b3,
+ 0x55d8, 0x43ab,
+ 0x55d9, 0x238f,
+ 0x55da, 0x0dde,
+ 0x55db, 0x237b,
+ 0x55dc, 0x0dd8,
+ 0x55dd, 0x2380,
+ 0x55de, 0x3e94,
+ 0x55df, 0x0dd3,
+ 0x55e1, 0x0ddf,
+ 0x55e2, 0x238a,
+ 0x55e3, 0x0ddb,
+ 0x55e5, 0x0de2,
+ 0x55e6, 0x0dd6,
+ 0x55e7, 0x011f,
+ 0x55e8, 0x0dd4,
+ 0x55e9, 0x2384,
+ 0x55ea, 0x3e7c,
+ 0x55ec, 0x37d2,
+ 0x55ef, 0x0ddd,
+ 0x55f0, 0x3e88,
+ 0x55f1, 0x3e83,
+ 0x55f2, 0x238d,
+ 0x55f5, 0x4786,
+ 0x55f6, 0x0f9f,
+ 0x55f7, 0x0f9a,
+ 0x55f9, 0x2637,
+ 0x55fa, 0x2633,
+ 0x55fb, 0x4626,
+ 0x55fc, 0x262d,
+ 0x55fd, 0x0f94,
+ 0x55fe, 0x0f90,
+ 0x55ff, 0x2636,
+ 0x5600, 0x0f91,
+ 0x5601, 0x2630,
+ 0x5602, 0x2632,
+ 0x5604, 0x2635,
+ 0x5605, 0x3e82,
+ 0x5606, 0x0f96,
+ 0x5608, 0x0f9d,
+ 0x5609, 0x0f97,
+ 0x560c, 0x262b,
+ 0x560d, 0x0f98,
+ 0x560f, 0x262e,
+ 0x5610, 0x0f9e,
+ 0x5611, 0x3f4d,
+ 0x5612, 0x262c,
+ 0x5613, 0x2631,
+ 0x5614, 0x0f95,
+ 0x5615, 0x262a,
+ 0x5616, 0x0f9b,
+ 0x5617, 0x0f93,
+ 0x561b, 0x0f92,
+ 0x561c, 0x262f,
+ 0x561d, 0x2634,
+ 0x561e, 0x3e68,
+ 0x561f, 0x0f9c,
+ 0x5620, 0x3f7d,
+ 0x5621, 0x43ad,
+ 0x5622, 0x3e67,
+ 0x5623, 0x4707,
+ 0x5625, 0x3e78,
+ 0x5627, 0x2629,
+ 0x5629, 0x1119,
+ 0x562a, 0x289d,
+ 0x562c, 0x289a,
+ 0x562d, 0x3e63,
+ 0x562e, 0x1113,
+ 0x562f, 0x111f,
+ 0x5632, 0x1116,
+ 0x5633, 0x2898,
+ 0x5634, 0x1118,
+ 0x5635, 0x2890,
+ 0x5636, 0x111e,
+ 0x5637, 0x40b7,
+ 0x5638, 0x289c,
+ 0x5639, 0x1115,
+ 0x563a, 0x289e,
+ 0x563b, 0x1114,
+ 0x563d, 0x2899,
+ 0x563e, 0x289b,
+ 0x563f, 0x1117,
+ 0x5640, 0x2897,
+ 0x5641, 0x2891,
+ 0x5642, 0x288e,
+ 0x5643, 0x3e7e,
+ 0x5645, 0x20c8,
+ 0x5646, 0x2894,
+ 0x5648, 0x288d,
+ 0x5649, 0x2893,
+ 0x564a, 0x2892,
+ 0x564c, 0x288f,
+ 0x564d, 0x40bc,
+ 0x564e, 0x111b,
+ 0x564f, 0x40bd,
+ 0x5650, 0x47cf,
+ 0x5652, 0x45c2,
+ 0x5653, 0x111a,
+ 0x5654, 0x43af,
+ 0x5657, 0x111c,
+ 0x5658, 0x2895,
+ 0x5659, 0x1295,
+ 0x565a, 0x2896,
+ 0x565d, 0x3ef9,
+ 0x565e, 0x2b10,
+ 0x5660, 0x2b09,
+ 0x5661, 0x3812,
+ 0x5662, 0x12a1,
+ 0x5663, 0x2b0d,
+ 0x5664, 0x1299,
+ 0x5665, 0x129d,
+ 0x5666, 0x2b0c,
+ 0x5668, 0x129c,
+ 0x5669, 0x1298,
+ 0x566a, 0x129b,
+ 0x566b, 0x1296,
+ 0x566c, 0x12a0,
+ 0x566d, 0x2b0e,
+ 0x566e, 0x2b0a,
+ 0x566f, 0x129f,
+ 0x5670, 0x2b08,
+ 0x5671, 0x129e,
+ 0x5672, 0x2b0f,
+ 0x5673, 0x2b0b,
+ 0x5674, 0x111d,
+ 0x5676, 0x12a2,
+ 0x5677, 0x2b11,
+ 0x5678, 0x129a,
+ 0x5679, 0x1297,
+ 0x567a, 0x3d85,
+ 0x567b, 0x3eb7,
+ 0x567c, 0x3eed,
+ 0x567e, 0x2d47,
+ 0x567f, 0x2d49,
+ 0x5680, 0x13ba,
+ 0x5681, 0x2d4a,
+ 0x5682, 0x2d48,
+ 0x5683, 0x2d46,
+ 0x5684, 0x2d45,
+ 0x5685, 0x13bc,
+ 0x5686, 0x2d44,
+ 0x5687, 0x13bd,
+ 0x5689, 0x4628,
+ 0x568a, 0x3949,
+ 0x568b, 0x3e4c,
+ 0x568c, 0x2d42,
+ 0x568e, 0x13b9,
+ 0x568f, 0x13be,
+ 0x5690, 0x13bb,
+ 0x5692, 0x39a6,
+ 0x5693, 0x2d41,
+ 0x5695, 0x14ca,
+ 0x5697, 0x2f13,
+ 0x5698, 0x2f11,
+ 0x5699, 0x2f16,
+ 0x569a, 0x2f14,
+ 0x569c, 0x2f12,
+ 0x569d, 0x2f15,
+ 0x569e, 0x39a4,
+ 0x569f, 0x3948,
+ 0x56a1, 0x436b,
+ 0x56a4, 0x3cc8,
+ 0x56a5, 0x1576,
+ 0x56a6, 0x3081,
+ 0x56a8, 0x1577,
+ 0x56aa, 0x3083,
+ 0x56ab, 0x307f,
+ 0x56ac, 0x3084,
+ 0x56ad, 0x3080,
+ 0x56ae, 0x14cb,
+ 0x56af, 0x45f7,
+ 0x56b1, 0x463f,
+ 0x56b2, 0x31c8,
+ 0x56b3, 0x31ca,
+ 0x56b4, 0x160c,
+ 0x56b5, 0x31c9,
+ 0x56b6, 0x160b,
+ 0x56b7, 0x160a,
+ 0x56b9, 0x486f,
+ 0x56bc, 0x160d,
+ 0x56bd, 0x32ca,
+ 0x56bf, 0x3e5d,
+ 0x56c0, 0x166b,
+ 0x56c1, 0x166a,
+ 0x56c2, 0x166c,
+ 0x56c3, 0x32c9,
+ 0x56c5, 0x3379,
+ 0x56c6, 0x3378,
+ 0x56c8, 0x16bd,
+ 0x56c9, 0x16bf,
+ 0x56ca, 0x16be,
+ 0x56cb, 0x337a,
+ 0x56cc, 0x16f6,
+ 0x56cd, 0x3481,
+ 0x56d1, 0x171f,
+ 0x56d3, 0x3480,
+ 0x56d4, 0x34c9,
+ 0x56d6, 0x488a,
+ 0x56d7, 0x1775,
+ 0x56da, 0x032d,
+ 0x56db, 0x032c,
+ 0x56dd, 0x03ac,
+ 0x56de, 0x03ab,
+ 0x56df, 0x17d0,
+ 0x56e0, 0x03aa,
+ 0x56e1, 0x17cf,
+ 0x56e2, 0x4548,
+ 0x56e4, 0x0463,
+ 0x56e5, 0x1850,
+ 0x56e7, 0x184f,
+ 0x56ea, 0x0461,
+ 0x56eb, 0x0464,
+ 0x56ed, 0x40c4,
+ 0x56ee, 0x184e,
+ 0x56ef, 0x40c3,
+ 0x56f0, 0x0462,
+ 0x56f1, 0x40bf,
+ 0x56f7, 0x1933,
+ 0x56f9, 0x1934,
+ 0x56fa, 0x0578,
+ 0x56fd, 0x3d64,
+ 0x56ff, 0x06e6,
+ 0x5700, 0x40c2,
+ 0x5701, 0x1c5b,
+ 0x5703, 0x0879,
+ 0x5707, 0x1e74,
+ 0x5708, 0x0a36,
+ 0x5709, 0x0a38,
+ 0x570a, 0x1e73,
+ 0x570b, 0x0a37,
+ 0x570c, 0x20d9,
+ 0x570d, 0x0c16,
+ 0x5712, 0x0de4,
+ 0x5714, 0x2391,
+ 0x5715, 0x3e36,
+ 0x5716, 0x0fa1,
+ 0x5718, 0x0fa0,
+ 0x571a, 0x289f,
+ 0x571b, 0x2b13,
+ 0x571c, 0x2b12,
+ 0x571d, 0x3a02,
+ 0x571e, 0x3505,
+ 0x571f, 0x027a,
+ 0x5720, 0x1784,
+ 0x5722, 0x179a,
+ 0x5728, 0x03af,
+ 0x5729, 0x03b3,
+ 0x572a, 0x17d2,
+ 0x572c, 0x03b1,
+ 0x572d, 0x03b0,
+ 0x572e, 0x17d1,
+ 0x572f, 0x03b2,
+ 0x5730, 0x03ae,
+ 0x5732, 0x3af9,
+ 0x5733, 0x03ad,
+ 0x5734, 0x17d3,
+ 0x573b, 0x046e,
+ 0x573e, 0x046b,
+ 0x573f, 0x4855,
+ 0x5740, 0x0467,
+ 0x5741, 0x1851,
+ 0x5742, 0x40cc,
+ 0x5743, 0x40de,
+ 0x5745, 0x1852,
+ 0x5746, 0x40c8,
+ 0x5747, 0x0469,
+ 0x5749, 0x1854,
+ 0x574a, 0x0465,
+ 0x574b, 0x1855,
+ 0x574c, 0x1853,
+ 0x574d, 0x0468,
+ 0x574e, 0x046a,
+ 0x574f, 0x046d,
+ 0x5750, 0x046c,
+ 0x5751, 0x0466,
+ 0x5752, 0x1856,
+ 0x5754, 0x4785,
+ 0x5757, 0x47e6,
+ 0x575b, 0x3982,
+ 0x575f, 0x3fbf,
+ 0x5761, 0x057d,
+ 0x5762, 0x1941,
+ 0x5764, 0x057f,
+ 0x5766, 0x057e,
+ 0x5767, 0x3f2b,
+ 0x5768, 0x1942,
+ 0x5769, 0x057c,
+ 0x576a, 0x057b,
+ 0x576b, 0x1938,
+ 0x576d, 0x1937,
+ 0x576f, 0x1935,
+ 0x5770, 0x193a,
+ 0x5771, 0x1939,
+ 0x5772, 0x1936,
+ 0x5773, 0x193f,
+ 0x5775, 0x193d,
+ 0x5776, 0x193b,
+ 0x5777, 0x057a,
+ 0x577a, 0x3f5f,
+ 0x577b, 0x193e,
+ 0x577c, 0x0580,
+ 0x577d, 0x1943,
+ 0x577e, 0x46dc,
+ 0x577f, 0x3a07,
+ 0x5780, 0x193c,
+ 0x5782, 0x06e7,
+ 0x5783, 0x0579,
+ 0x5788, 0x484b,
+ 0x578a, 0x3c7b,
+ 0x578b, 0x06e8,
+ 0x578c, 0x1a90,
+ 0x578d, 0x3a06,
+ 0x578f, 0x1a96,
+ 0x5790, 0x4166,
+ 0x5793, 0x06ee,
+ 0x5794, 0x1a94,
+ 0x5795, 0x1a9a,
+ 0x5797, 0x1a91,
+ 0x5798, 0x1a95,
+ 0x5799, 0x1a97,
+ 0x579a, 0x1a99,
+ 0x579b, 0x1a93,
+ 0x579c, 0x4608,
+ 0x579d, 0x1a92,
+ 0x579e, 0x1a8d,
+ 0x57a0, 0x06e9,
+ 0x57a1, 0x4864,
+ 0x57a2, 0x06eb,
+ 0x57a3, 0x06ea,
+ 0x57a4, 0x1a8f,
+ 0x57a5, 0x1a98,
+ 0x57a7, 0x4914,
+ 0x57aa, 0x4905,
+ 0x57ae, 0x06ed,
+ 0x57b4, 0x4741,
+ 0x57b5, 0x1a8c,
+ 0x57b6, 0x1c66,
+ 0x57b8, 0x1c65,
+ 0x57b9, 0x1c6a,
+ 0x57ba, 0x1c61,
+ 0x57bb, 0x3c79,
+ 0x57bc, 0x1c64,
+ 0x57bd, 0x1c63,
+ 0x57be, 0x372c,
+ 0x57bf, 0x1c67,
+ 0x57c1, 0x1c6b,
+ 0x57c2, 0x087b,
+ 0x57c3, 0x087e,
+ 0x57c4, 0x3b5b,
+ 0x57c6, 0x1c62,
+ 0x57c7, 0x1c68,
+ 0x57c8, 0x3d0b,
+ 0x57cb, 0x087d,
+ 0x57cc, 0x1c5d,
+ 0x57ce, 0x06ec,
+ 0x57cf, 0x1e82,
+ 0x57d0, 0x1c69,
+ 0x57d2, 0x1c60,
+ 0x57d4, 0x087c,
+ 0x57d5, 0x1c5f,
+ 0x57d7, 0x3c7d,
+ 0x57dc, 0x1e79,
+ 0x57dd, 0x3a05,
+ 0x57de, 0x3f01,
+ 0x57df, 0x0a39,
+ 0x57e0, 0x0a3d,
+ 0x57e1, 0x1e89,
+ 0x57e2, 0x1e77,
+ 0x57e3, 0x1e85,
+ 0x57e4, 0x0a3e,
+ 0x57e5, 0x1e87,
+ 0x57e6, 0x40cf,
+ 0x57e7, 0x1e8d,
+ 0x57e9, 0x1e91,
+ 0x57ec, 0x1e88,
+ 0x57ed, 0x1e7c,
+ 0x57ee, 0x1e84,
+ 0x57ef, 0x4754,
+ 0x57f0, 0x1e92,
+ 0x57f1, 0x1e90,
+ 0x57f2, 0x1e86,
+ 0x57f3, 0x1e81,
+ 0x57f4, 0x1e7a,
+ 0x57f5, 0x20e1,
+ 0x57f6, 0x1e78,
+ 0x57f7, 0x0a42,
+ 0x57f8, 0x1e7f,
+ 0x57f9, 0x0a43,
+ 0x57fa, 0x0a3f,
+ 0x57fb, 0x1e75,
+ 0x57fc, 0x1e8b,
+ 0x57fd, 0x1e7d,
+ 0x57fe, 0x408f,
+ 0x5800, 0x1e7b,
+ 0x5801, 0x1e8e,
+ 0x5802, 0x0a40,
+ 0x5803, 0x40d1,
+ 0x5804, 0x1e94,
+ 0x5805, 0x0a3a,
+ 0x5806, 0x0a3c,
+ 0x5807, 0x1e83,
+ 0x5808, 0x1e7e,
+ 0x5809, 0x087f,
+ 0x580a, 0x0a3b,
+ 0x580b, 0x1e80,
+ 0x580c, 0x1e8f,
+ 0x580d, 0x1e93,
+ 0x580e, 0x1e8a,
+ 0x5810, 0x1e8c,
+ 0x5812, 0x3d0a,
+ 0x5814, 0x1e76,
+ 0x5819, 0x20dc,
+ 0x581b, 0x20e5,
+ 0x581c, 0x20e4,
+ 0x581d, 0x0c1e,
+ 0x581e, 0x20dd,
+ 0x5820, 0x0c1f,
+ 0x5821, 0x0c1d,
+ 0x5822, 0x3c28,
+ 0x5823, 0x20df,
+ 0x5824, 0x0c1a,
+ 0x5825, 0x20e3,
+ 0x5826, 0x40d4,
+ 0x5827, 0x20de,
+ 0x5828, 0x20e0,
+ 0x5829, 0x20da,
+ 0x582a, 0x0c18,
+ 0x582c, 0x20ed,
+ 0x582d, 0x20ec,
+ 0x582e, 0x20e9,
+ 0x582f, 0x0c17,
+ 0x5830, 0x0c1b,
+ 0x5832, 0x1c5e,
+ 0x5833, 0x20e6,
+ 0x5834, 0x0c19,
+ 0x5835, 0x0a41,
+ 0x5836, 0x20e8,
+ 0x5837, 0x20db,
+ 0x5838, 0x20eb,
+ 0x5839, 0x20ea,
+ 0x583a, 0x3d72,
+ 0x583b, 0x20ee,
+ 0x583d, 0x239f,
+ 0x583f, 0x20e7,
+ 0x5840, 0x3d82,
+ 0x5844, 0x47bb,
+ 0x5847, 0x3ac2,
+ 0x5848, 0x20e2,
+ 0x5849, 0x2397,
+ 0x584a, 0x0def,
+ 0x584b, 0x0df2,
+ 0x584c, 0x0ded,
+ 0x584d, 0x2396,
+ 0x584e, 0x239a,
+ 0x584f, 0x2395,
+ 0x5851, 0x0de7,
+ 0x5852, 0x0df1,
+ 0x5853, 0x2392,
+ 0x5854, 0x0deb,
+ 0x5855, 0x2399,
+ 0x5857, 0x0de9,
+ 0x5858, 0x0de8,
+ 0x5859, 0x239c,
+ 0x585a, 0x0dea,
+ 0x585b, 0x239e,
+ 0x585c, 0x4949,
+ 0x585d, 0x239b,
+ 0x585e, 0x0de6,
+ 0x585f, 0x43df,
+ 0x5862, 0x0df0,
+ 0x5863, 0x23a0,
+ 0x5864, 0x2394,
+ 0x5865, 0x239d,
+ 0x5868, 0x2393,
+ 0x5869, 0x3d65,
+ 0x586b, 0x0dec,
+ 0x586c, 0x399a,
+ 0x586d, 0x0dee,
+ 0x586f, 0x2398,
+ 0x5871, 0x23a1,
+ 0x5872, 0x3c26,
+ 0x5873, 0x4355,
+ 0x5874, 0x263f,
+ 0x5875, 0x0fa2,
+ 0x5876, 0x2645,
+ 0x5879, 0x0fa7,
+ 0x587a, 0x2641,
+ 0x587b, 0x2648,
+ 0x587c, 0x2639,
+ 0x587d, 0x0fa9,
+ 0x587e, 0x0fa3,
+ 0x587f, 0x263e,
+ 0x5880, 0x1121,
+ 0x5881, 0x263d,
+ 0x5882, 0x2646,
+ 0x5883, 0x0fa4,
+ 0x5885, 0x0fa8,
+ 0x5886, 0x263c,
+ 0x5887, 0x2642,
+ 0x5888, 0x2647,
+ 0x5889, 0x2638,
+ 0x588a, 0x0fa6,
+ 0x588b, 0x2640,
+ 0x588e, 0x2644,
+ 0x588f, 0x264a,
+ 0x5890, 0x263a,
+ 0x5891, 0x2643,
+ 0x5893, 0x0fa5,
+ 0x5894, 0x2649,
+ 0x5898, 0x263b,
+ 0x5899, 0x4618,
+ 0x589a, 0x4903,
+ 0x589c, 0x1125,
+ 0x589d, 0x28a1,
+ 0x589e, 0x1123,
+ 0x589f, 0x1122,
+ 0x58a0, 0x28a3,
+ 0x58a1, 0x28a8,
+ 0x58a3, 0x28a4,
+ 0x58a5, 0x28a7,
+ 0x58a6, 0x1128,
+ 0x58a7, 0x3eeb,
+ 0x58a8, 0x1288,
+ 0x58a9, 0x1127,
+ 0x58aa, 0x40d7,
+ 0x58ab, 0x28a0,
+ 0x58ac, 0x28a6,
+ 0x58ae, 0x1126,
+ 0x58af, 0x28a5,
+ 0x58b0, 0x37a4,
+ 0x58b1, 0x28a2,
+ 0x58b3, 0x1124,
+ 0x58b5, 0x4840,
+ 0x58b6, 0x3dfd,
+ 0x58ba, 0x2b18,
+ 0x58bb, 0x36eb,
+ 0x58bc, 0x2b1a,
+ 0x58bd, 0x2b15,
+ 0x58be, 0x12a4,
+ 0x58bf, 0x2b17,
+ 0x58c1, 0x12a3,
+ 0x58c2, 0x2b19,
+ 0x58c5, 0x12a6,
+ 0x58c6, 0x2b1b,
+ 0x58c7, 0x12a5,
+ 0x58c8, 0x2b14,
+ 0x58c9, 0x2b16,
+ 0x58cb, 0x3a09,
+ 0x58ce, 0x13c2,
+ 0x58cf, 0x2d4d,
+ 0x58d1, 0x13c1,
+ 0x58d2, 0x2d4e,
+ 0x58d3, 0x13c0,
+ 0x58d4, 0x2d4c,
+ 0x58d5, 0x13bf,
+ 0x58d6, 0x2d4b,
+ 0x58d8, 0x14cd,
+ 0x58d9, 0x14cc,
+ 0x58da, 0x3085,
+ 0x58db, 0x3087,
+ 0x58dc, 0x40da,
+ 0x58dd, 0x3086,
+ 0x58de, 0x1578,
+ 0x58e0, 0x40d9,
+ 0x58e2, 0x157a,
+ 0x58e3, 0x31cb,
+ 0x58e4, 0x160e,
+ 0x58e7, 0x3411,
+ 0x58e8, 0x3410,
+ 0x58e9, 0x1720,
+ 0x58eb, 0x027b,
+ 0x58ec, 0x02c1,
+ 0x58ef, 0x046f,
+ 0x58f0, 0x4549,
+ 0x58f2, 0x3d68,
+ 0x58f3, 0x3c7a,
+ 0x58f4, 0x1a9b,
+ 0x58f9, 0x0c20,
+ 0x58fb, 0x40dc,
+ 0x58fc, 0x23a2,
+ 0x58fd, 0x0faa,
+ 0x58fe, 0x264b,
+ 0x58ff, 0x28a9,
+ 0x5902, 0x0224,
+ 0x5903, 0x1785,
+ 0x5904, 0x454a,
+ 0x5905, 0x4599,
+ 0x5906, 0x1857,
+ 0x5907, 0x454b,
+ 0x590a, 0x0224,
+ 0x590c, 0x1944,
+ 0x590d, 0x1a9c,
+ 0x590e, 0x1c6c,
+ 0x590f, 0x0880,
+ 0x5911, 0x4274,
+ 0x5912, 0x3088,
+ 0x5914, 0x166d,
+ 0x5915, 0x027c,
+ 0x5916, 0x032e,
+ 0x5917, 0x179c,
+ 0x5919, 0x03b4,
+ 0x591c, 0x0581,
+ 0x591f, 0x40e3,
+ 0x5920, 0x0a44,
+ 0x5922, 0x0fac,
+ 0x5924, 0x0fad,
+ 0x5925, 0x0fab,
+ 0x5927, 0x027d,
+ 0x5929, 0x02c2,
+ 0x592a, 0x02c4,
+ 0x592b, 0x02c3,
+ 0x592c, 0x1786,
+ 0x592d, 0x02c5,
+ 0x592e, 0x032f,
+ 0x592f, 0x179d,
+ 0x5931, 0x0330,
+ 0x5932, 0x454c,
+ 0x5934, 0x454d,
+ 0x5937, 0x03b6,
+ 0x593c, 0x17d4,
+ 0x593e, 0x0470,
+ 0x5940, 0x1858,
+ 0x5944, 0x0585,
+ 0x5945, 0x1945,
+ 0x5947, 0x0583,
+ 0x5949, 0x0582,
+ 0x594a, 0x1c6d,
+ 0x594e, 0x06f2,
+ 0x594f, 0x06f1,
+ 0x5950, 0x06f3,
+ 0x5951, 0x06f0,
+ 0x5953, 0x1a9d,
+ 0x5954, 0x0586,
+ 0x5955, 0x06ef,
+ 0x5957, 0x0881,
+ 0x595a, 0x0883,
+ 0x595c, 0x1e95,
+ 0x5960, 0x0c22,
+ 0x5961, 0x20ef,
+ 0x5962, 0x0a45,
+ 0x5965, 0x4852,
+ 0x5967, 0x0df3,
+ 0x5969, 0x0faf,
+ 0x596a, 0x0fae,
+ 0x596b, 0x264c,
+ 0x596d, 0x1129,
+ 0x596e, 0x12a7,
+ 0x5970, 0x2f17,
+ 0x5971, 0x337b,
+ 0x5972, 0x3412,
+ 0x5973, 0x027e,
+ 0x5974, 0x0331,
+ 0x5975, 0x3e6a,
+ 0x5976, 0x0332,
+ 0x5977, 0x17da,
+ 0x5978, 0x03b9,
+ 0x5979, 0x03bc,
+ 0x597b, 0x17d8,
+ 0x597c, 0x17d6,
+ 0x597d, 0x03bb,
+ 0x597e, 0x17d9,
+ 0x597f, 0x17db,
+ 0x5980, 0x17d5,
+ 0x5981, 0x03be,
+ 0x5982, 0x03bd,
+ 0x5983, 0x03ba,
+ 0x5984, 0x03b8,
+ 0x5985, 0x17d7,
+ 0x5989, 0x3d30,
+ 0x598a, 0x047b,
+ 0x598d, 0x0478,
+ 0x598e, 0x185d,
+ 0x598f, 0x1860,
+ 0x5990, 0x185f,
+ 0x5992, 0x0472,
+ 0x5993, 0x047a,
+ 0x5994, 0x3c99,
+ 0x5996, 0x0477,
+ 0x5997, 0x185c,
+ 0x5998, 0x185a,
+ 0x5999, 0x0476,
+ 0x599a, 0x3bb0,
+ 0x599d, 0x0471,
+ 0x599e, 0x0474,
+ 0x599f, 0x3daf,
+ 0x59a0, 0x185b,
+ 0x59a1, 0x1862,
+ 0x59a2, 0x185e,
+ 0x59a3, 0x0475,
+ 0x59a4, 0x0479,
+ 0x59a5, 0x047c,
+ 0x59a6, 0x1859,
+ 0x59a7, 0x1861,
+ 0x59a8, 0x0473,
+ 0x59ac, 0x3d81,
+ 0x59ae, 0x058b,
+ 0x59af, 0x0593,
+ 0x59b0, 0x3cd8,
+ 0x59b1, 0x1951,
+ 0x59b2, 0x194a,
+ 0x59b3, 0x0594,
+ 0x59b4, 0x1955,
+ 0x59b5, 0x1946,
+ 0x59b6, 0x194d,
+ 0x59b7, 0x3f2d,
+ 0x59b8, 0x3a10,
+ 0x59b9, 0x058a,
+ 0x59ba, 0x1947,
+ 0x59bb, 0x0588,
+ 0x59bc, 0x194e,
+ 0x59bd, 0x1952,
+ 0x59be, 0x0587,
+ 0x59c0, 0x1953,
+ 0x59c1, 0x194c,
+ 0x59c3, 0x194f,
+ 0x59c4, 0x3d04,
+ 0x59c5, 0x0596,
+ 0x59c6, 0x058d,
+ 0x59c7, 0x1956,
+ 0x59c8, 0x1954,
+ 0x59c9, 0x40ec,
+ 0x59ca, 0x0592,
+ 0x59cb, 0x0590,
+ 0x59cc, 0x194b,
+ 0x59cd, 0x058f,
+ 0x59ce, 0x1949,
+ 0x59cf, 0x1948,
+ 0x59d0, 0x058e,
+ 0x59d1, 0x058c,
+ 0x59d2, 0x0595,
+ 0x59d3, 0x0591,
+ 0x59d4, 0x0589,
+ 0x59d6, 0x1950,
+ 0x59d8, 0x06f5,
+ 0x59d9, 0x40f1,
+ 0x59da, 0x06fc,
+ 0x59db, 0x1aab,
+ 0x59dc, 0x06f4,
+ 0x59dd, 0x1aa3,
+ 0x59de, 0x1a9f,
+ 0x59e0, 0x1aaf,
+ 0x59e1, 0x1a9e,
+ 0x59e3, 0x06f7,
+ 0x59e4, 0x1aa8,
+ 0x59e5, 0x06fa,
+ 0x59e6, 0x06fd,
+ 0x59e8, 0x06f8,
+ 0x59e9, 0x1aac,
+ 0x59ea, 0x06fb,
+ 0x59eb, 0x3d59,
+ 0x59ec, 0x088a,
+ 0x59ed, 0x1ab2,
+ 0x59ee, 0x1aa0,
+ 0x59ef, 0x3d38,
+ 0x59f0, 0x3bb2,
+ 0x59f1, 0x1aa2,
+ 0x59f2, 0x1aa9,
+ 0x59f3, 0x1aad,
+ 0x59f4, 0x1ab1,
+ 0x59f5, 0x1aae,
+ 0x59f6, 0x1aa7,
+ 0x59f7, 0x1aaa,
+ 0x59f8, 0x3e4a,
+ 0x59f9, 0x40f8,
+ 0x59fa, 0x1aa4,
+ 0x59fb, 0x06ff,
+ 0x59fc, 0x1aa6,
+ 0x59fd, 0x1aa5,
+ 0x59fe, 0x1ab0,
+ 0x59ff, 0x06f6,
+ 0x5a00, 0x1aa1,
+ 0x5a01, 0x06fe,
+ 0x5a02, 0x3b8d,
+ 0x5a03, 0x06f9,
+ 0x5a09, 0x0890,
+ 0x5a0a, 0x1c75,
+ 0x5a0b, 0x3c89,
+ 0x5a0c, 0x088f,
+ 0x5a0d, 0x3b38,
+ 0x5a0f, 0x1c73,
+ 0x5a11, 0x0884,
+ 0x5a12, 0x3a13,
+ 0x5a13, 0x0889,
+ 0x5a15, 0x1c72,
+ 0x5a16, 0x1c6f,
+ 0x5a17, 0x1c74,
+ 0x5a18, 0x0885,
+ 0x5a19, 0x1c6e,
+ 0x5a1b, 0x0888,
+ 0x5a1c, 0x0886,
+ 0x5a1e, 0x1c76,
+ 0x5a1f, 0x0887,
+ 0x5a20, 0x088b,
+ 0x5a21, 0x3a1b,
+ 0x5a23, 0x088c,
+ 0x5a24, 0x40e8,
+ 0x5a25, 0x088e,
+ 0x5a27, 0x3de1,
+ 0x5a29, 0x088d,
+ 0x5a2a, 0x3b3b,
+ 0x5a2b, 0x3d40,
+ 0x5a2c, 0x3a0f,
+ 0x5a2d, 0x1c70,
+ 0x5a33, 0x1c77,
+ 0x5a35, 0x1e9c,
+ 0x5a36, 0x0a46,
+ 0x5a37, 0x20fd,
+ 0x5a38, 0x1e9b,
+ 0x5a39, 0x1eae,
+ 0x5a3c, 0x0a4c,
+ 0x5a3d, 0x3ac0,
+ 0x5a3e, 0x1eac,
+ 0x5a40, 0x0a4b,
+ 0x5a41, 0x0a47,
+ 0x5a42, 0x1eb5,
+ 0x5a43, 0x1ea5,
+ 0x5a44, 0x1ea8,
+ 0x5a45, 0x3917,
+ 0x5a46, 0x0a4f,
+ 0x5a47, 0x1eb2,
+ 0x5a48, 0x1eaa,
+ 0x5a49, 0x0a48,
+ 0x5a4a, 0x0a50,
+ 0x5a4c, 0x1eaf,
+ 0x5a4d, 0x1ead,
+ 0x5a50, 0x1e9e,
+ 0x5a51, 0x1eb3,
+ 0x5a52, 0x1ea7,
+ 0x5a53, 0x1ea2,
+ 0x5a54, 0x4603,
+ 0x5a55, 0x1e98,
+ 0x5a56, 0x1eb4,
+ 0x5a57, 0x1ea4,
+ 0x5a58, 0x1e97,
+ 0x5a59, 0x3b34,
+ 0x5a5a, 0x0a4e,
+ 0x5a5b, 0x1ea9,
+ 0x5a5c, 0x1eb6,
+ 0x5a5d, 0x1ea6,
+ 0x5a5e, 0x1e9a,
+ 0x5a5f, 0x1e9f,
+ 0x5a60, 0x1e96,
+ 0x5a61, 0x3d33,
+ 0x5a62, 0x0a4d,
+ 0x5a63, 0x40fb,
+ 0x5a64, 0x1ea3,
+ 0x5a65, 0x1ea0,
+ 0x5a66, 0x0a49,
+ 0x5a67, 0x1e99,
+ 0x5a68, 0x39b7,
+ 0x5a69, 0x1eb1,
+ 0x5a6a, 0x0a4a,
+ 0x5a6b, 0x3a42,
+ 0x5a6c, 0x1ea1,
+ 0x5a6d, 0x1e9d,
+ 0x5a6e, 0x3d3f,
+ 0x5a70, 0x1eb0,
+ 0x5a71, 0x3d34,
+ 0x5a77, 0x0c23,
+ 0x5a78, 0x20f6,
+ 0x5a79, 0x3ce1,
+ 0x5a7a, 0x20f3,
+ 0x5a7b, 0x2104,
+ 0x5a7c, 0x20f8,
+ 0x5a7d, 0x2105,
+ 0x5a7e, 0x3a11,
+ 0x5a7f, 0x0c25,
+ 0x5a81, 0x3a1d,
+ 0x5a82, 0x3d31,
+ 0x5a83, 0x2101,
+ 0x5a84, 0x20fe,
+ 0x5a86, 0x3b81,
+ 0x5a88, 0x4263,
+ 0x5a8a, 0x20ff,
+ 0x5a8b, 0x2102,
+ 0x5a8c, 0x2106,
+ 0x5a8e, 0x1eab,
+ 0x5a8f, 0x2108,
+ 0x5a90, 0x23b6,
+ 0x5a91, 0x4235,
+ 0x5a92, 0x0c26,
+ 0x5a93, 0x2109,
+ 0x5a94, 0x20f1,
+ 0x5a95, 0x20fb,
+ 0x5a96, 0x4100,
+ 0x5a97, 0x2100,
+ 0x5a99, 0x3a0a,
+ 0x5a9a, 0x0c24,
+ 0x5a9b, 0x0c27,
+ 0x5a9c, 0x2107,
+ 0x5a9d, 0x210a,
+ 0x5a9e, 0x20f5,
+ 0x5a9f, 0x20f2,
+ 0x5aa0, 0x4172,
+ 0x5aa1, 0x3cdc,
+ 0x5aa2, 0x20f4,
+ 0x5aa5, 0x20f9,
+ 0x5aa6, 0x20f7,
+ 0x5aa7, 0x0c28,
+ 0x5aa9, 0x2103,
+ 0x5aab, 0x40fa,
+ 0x5aac, 0x20fa,
+ 0x5aae, 0x20fc,
+ 0x5aaf, 0x20f0,
+ 0x5ab0, 0x23aa,
+ 0x5ab1, 0x23a8,
+ 0x5ab2, 0x0dfc,
+ 0x5ab3, 0x0dfa,
+ 0x5ab4, 0x23b2,
+ 0x5ab5, 0x23a9,
+ 0x5ab6, 0x23b3,
+ 0x5ab7, 0x23af,
+ 0x5ab8, 0x23a7,
+ 0x5ab9, 0x23b5,
+ 0x5aba, 0x23a6,
+ 0x5abb, 0x23ad,
+ 0x5abc, 0x0df9,
+ 0x5abd, 0x0df8,
+ 0x5abe, 0x0df7,
+ 0x5abf, 0x23ab,
+ 0x5ac0, 0x23b0,
+ 0x5ac1, 0x0df4,
+ 0x5ac2, 0x0dfb,
+ 0x5ac3, 0x3896,
+ 0x5ac4, 0x23a4,
+ 0x5ac6, 0x23ae,
+ 0x5ac7, 0x23a3,
+ 0x5ac8, 0x23ac,
+ 0x5ac9, 0x0df5,
+ 0x5aca, 0x23b1,
+ 0x5acb, 0x23a5,
+ 0x5acc, 0x0df6,
+ 0x5acd, 0x23b4,
+ 0x5ace, 0x3c88,
+ 0x5acf, 0x43b5,
+ 0x5ad3, 0x4102,
+ 0x5ad5, 0x2650,
+ 0x5ad6, 0x0fb4,
+ 0x5ad7, 0x0fb3,
+ 0x5ad8, 0x0fb5,
+ 0x5ad9, 0x265c,
+ 0x5ada, 0x2652,
+ 0x5adb, 0x2658,
+ 0x5adc, 0x264d,
+ 0x5add, 0x265b,
+ 0x5ade, 0x265a,
+ 0x5adf, 0x265e,
+ 0x5ae0, 0x2657,
+ 0x5ae1, 0x0fb0,
+ 0x5ae2, 0x2656,
+ 0x5ae3, 0x0fb6,
+ 0x5ae4, 0x3b86,
+ 0x5ae5, 0x264f,
+ 0x5ae6, 0x0fb1,
+ 0x5ae8, 0x265d,
+ 0x5ae9, 0x0fb2,
+ 0x5aea, 0x2651,
+ 0x5aeb, 0x2654,
+ 0x5aec, 0x2659,
+ 0x5aed, 0x2653,
+ 0x5aee, 0x264e,
+ 0x5af0, 0x3ee7,
+ 0x5af2, 0x37f5,
+ 0x5af3, 0x2655,
+ 0x5af4, 0x28ab,
+ 0x5af5, 0x112d,
+ 0x5af6, 0x28ae,
+ 0x5af7, 0x28ad,
+ 0x5af8, 0x28b0,
+ 0x5af9, 0x28b2,
+ 0x5afa, 0x36ee,
+ 0x5afb, 0x112b,
+ 0x5afd, 0x28ac,
+ 0x5afe, 0x3c1d,
+ 0x5aff, 0x28aa,
+ 0x5b01, 0x28b3,
+ 0x5b02, 0x28b1,
+ 0x5b03, 0x28af,
+ 0x5b05, 0x28b5,
+ 0x5b07, 0x28b4,
+ 0x5b08, 0x112f,
+ 0x5b09, 0x112a,
+ 0x5b0b, 0x112c,
+ 0x5b0c, 0x112e,
+ 0x5b0d, 0x48ff,
+ 0x5b0f, 0x28b6,
+ 0x5b10, 0x2b22,
+ 0x5b11, 0x3bf6,
+ 0x5b13, 0x2b21,
+ 0x5b14, 0x2b20,
+ 0x5b16, 0x2b23,
+ 0x5b17, 0x2b1c,
+ 0x5b19, 0x2b1d,
+ 0x5b1a, 0x2b25,
+ 0x5b1b, 0x2b1e,
+ 0x5b1d, 0x12a8,
+ 0x5b1e, 0x2b27,
+ 0x5b1f, 0x4941,
+ 0x5b20, 0x2b26,
+ 0x5b21, 0x2b1f,
+ 0x5b23, 0x2d52,
+ 0x5b24, 0x13c5,
+ 0x5b25, 0x2d50,
+ 0x5b26, 0x2d55,
+ 0x5b27, 0x2d54,
+ 0x5b28, 0x2b24,
+ 0x5b2a, 0x13c4,
+ 0x5b2b, 0x3b84,
+ 0x5b2c, 0x2d53,
+ 0x5b2d, 0x2d4f,
+ 0x5b2e, 0x2d57,
+ 0x5b2f, 0x2d56,
+ 0x5b30, 0x13c3,
+ 0x5b32, 0x2d51,
+ 0x5b34, 0x12a9,
+ 0x5b38, 0x14ce,
+ 0x5b3c, 0x2f18,
+ 0x5b3d, 0x3089,
+ 0x5b40, 0x160f,
+ 0x5b41, 0x38c8,
+ 0x5b43, 0x1610,
+ 0x5b44, 0x3a44,
+ 0x5b45, 0x31cc,
+ 0x5b46, 0x42b2,
+ 0x5b47, 0x32cd,
+ 0x5b48, 0x32cc,
+ 0x5b4a, 0x38cd,
+ 0x5b4b, 0x337c,
+ 0x5b4d, 0x3413,
+ 0x5b4e, 0x3482,
+ 0x5b4f, 0x3a31,
+ 0x5b50, 0x027f,
+ 0x5b53, 0x0281,
+ 0x5b54, 0x02c6,
+ 0x5b55, 0x0333,
+ 0x5b56, 0x17dc,
+ 0x5b57, 0x03bf,
+ 0x5b5a, 0x047f,
+ 0x5b5c, 0x047e,
+ 0x5b5d, 0x047d,
+ 0x5b5f, 0x0597,
+ 0x5b62, 0x1957,
+ 0x5b63, 0x0599,
+ 0x5b64, 0x0598,
+ 0x5b65, 0x1958,
+ 0x5b66, 0x454e,
+ 0x5b68, 0x461d,
+ 0x5b69, 0x0700,
+ 0x5b6b, 0x0891,
+ 0x5b6c, 0x1c78,
+ 0x5b6d, 0x3e5f,
+ 0x5b6e, 0x1eb8,
+ 0x5b70, 0x0a51,
+ 0x5b71, 0x0c2a,
+ 0x5b72, 0x1eb7,
+ 0x5b73, 0x0c29,
+ 0x5b74, 0x3732,
+ 0x5b75, 0x0fb7,
+ 0x5b76, 0x410a,
+ 0x5b77, 0x265f,
+ 0x5b78, 0x12aa,
+ 0x5b7a, 0x13c6,
+ 0x5b7b, 0x2d58,
+ 0x5b7c, 0x410c,
+ 0x5b7d, 0x1611,
+ 0x5b7f, 0x16c0,
+ 0x5b80, 0x0225,
+ 0x5b81, 0x179e,
+ 0x5b82, 0x4044,
+ 0x5b83, 0x0334,
+ 0x5b84, 0x179f,
+ 0x5b85, 0x03c3,
+ 0x5b87, 0x03c1,
+ 0x5b89, 0x03c4,
+ 0x5b8b, 0x0482,
+ 0x5b8c, 0x0481,
+ 0x5b8e, 0x1863,
+ 0x5b8f, 0x0483,
+ 0x5b90, 0x48e9,
+ 0x5b92, 0x1864,
+ 0x5b93, 0x1959,
+ 0x5b95, 0x195a,
+ 0x5b97, 0x059a,
+ 0x5b98, 0x059c,
+ 0x5b99, 0x059e,
+ 0x5b9a, 0x059b,
+ 0x5b9b, 0x059f,
+ 0x5b9c, 0x059d,
+ 0x5b9d, 0x4116,
+ 0x5b9e, 0x454f,
+ 0x5ba2, 0x0704,
+ 0x5ba3, 0x0701,
+ 0x5ba4, 0x0703,
+ 0x5ba5, 0x0705,
+ 0x5ba6, 0x0702,
+ 0x5ba7, 0x1c79,
+ 0x5ba8, 0x1ab3,
+ 0x5baa, 0x417b,
+ 0x5bac, 0x1c7b,
+ 0x5bad, 0x1c7a,
+ 0x5bae, 0x0897,
+ 0x5bb0, 0x0893,
+ 0x5bb3, 0x0894,
+ 0x5bb4, 0x0896,
+ 0x5bb5, 0x0898,
+ 0x5bb6, 0x0895,
+ 0x5bb8, 0x089a,
+ 0x5bb9, 0x0899,
+ 0x5bbf, 0x0a56,
+ 0x5bc0, 0x1eba,
+ 0x5bc1, 0x1eb9,
+ 0x5bc2, 0x0a55,
+ 0x5bc3, 0x3f25,
+ 0x5bc4, 0x0a54,
+ 0x5bc5, 0x0a53,
+ 0x5bc6, 0x0a57,
+ 0x5bc7, 0x0a52,
+ 0x5bca, 0x2110,
+ 0x5bcb, 0x210d,
+ 0x5bcc, 0x0c2c,
+ 0x5bcd, 0x210c,
+ 0x5bce, 0x2111,
+ 0x5bd0, 0x0c2e,
+ 0x5bd1, 0x210f,
+ 0x5bd2, 0x0c2b,
+ 0x5bd3, 0x0c2d,
+ 0x5bd4, 0x210e,
+ 0x5bd5, 0x4111,
+ 0x5bd6, 0x23b7,
+ 0x5bd7, 0x42bb,
+ 0x5bd8, 0x23b8,
+ 0x5bde, 0x0fb8,
+ 0x5bdf, 0x0fc0,
+ 0x5be0, 0x2660,
+ 0x5be1, 0x0fba,
+ 0x5be2, 0x0fbe,
+ 0x5be3, 0x2661,
+ 0x5be4, 0x0fbf,
+ 0x5be5, 0x0fbb,
+ 0x5be7, 0x0fb9,
+ 0x5be8, 0x0fbd,
+ 0x5be9, 0x1132,
+ 0x5bea, 0x210b,
+ 0x5beb, 0x1133,
+ 0x5bec, 0x1131,
+ 0x5bee, 0x1130,
+ 0x5bef, 0x2b28,
+ 0x5bf0, 0x12ab,
+ 0x5bf1, 0x2d59,
+ 0x5bf3, 0x4115,
+ 0x5bf5, 0x157b,
+ 0x5bf6, 0x1612,
+ 0x5bf8, 0x0282,
+ 0x5bfa, 0x03c5,
+ 0x5bff, 0x40dd,
+ 0x5c01, 0x0706,
+ 0x5c03, 0x1c7c,
+ 0x5c04, 0x089b,
+ 0x5c05, 0x4118,
+ 0x5c07, 0x0a5a,
+ 0x5c08, 0x0a59,
+ 0x5c09, 0x0a58,
+ 0x5c0a, 0x0c2f,
+ 0x5c0c, 0x2112,
+ 0x5c0d, 0x0fc1,
+ 0x5c0e, 0x12ac,
+ 0x5c0f, 0x0283,
+ 0x5c10, 0x1787,
+ 0x5c11, 0x02c7,
+ 0x5c12, 0x17a0,
+ 0x5c13, 0x411a,
+ 0x5c14, 0x411c,
+ 0x5c15, 0x17dd,
+ 0x5c16, 0x03c6,
+ 0x5c1a, 0x05a0,
+ 0x5c1c, 0x45ea,
+ 0x5c1e, 0x3a29,
+ 0x5c1f, 0x23ba,
+ 0x5c20, 0x3d89,
+ 0x5c22, 0x0284,
+ 0x5c23, 0x44e8,
+ 0x5c24, 0x02c8,
+ 0x5c25, 0x17de,
+ 0x5c28, 0x1865,
+ 0x5c2a, 0x1866,
+ 0x5c2c, 0x0484,
+ 0x5c30, 0x2113,
+ 0x5c31, 0x0c31,
+ 0x5c33, 0x23bb,
+ 0x5c37, 0x13c7,
+ 0x5c38, 0x0285,
+ 0x5c39, 0x0299,
+ 0x5c3a, 0x02c9,
+ 0x5c3b, 0x17a1,
+ 0x5c3c, 0x0335,
+ 0x5c3e, 0x0488,
+ 0x5c3f, 0x0487,
+ 0x5c40, 0x0485,
+ 0x5c44, 0x195b,
+ 0x5c45, 0x05a2,
+ 0x5c47, 0x195c,
+ 0x5c48, 0x05a1,
+ 0x5c49, 0x411f,
+ 0x5c4a, 0x3f5c,
+ 0x5c4b, 0x070a,
+ 0x5c4c, 0x1ab4,
+ 0x5c4d, 0x0709,
+ 0x5c4e, 0x0707,
+ 0x5c50, 0x089e,
+ 0x5c51, 0x089c,
+ 0x5c53, 0x3f02,
+ 0x5c54, 0x1c7e,
+ 0x5c55, 0x089d,
+ 0x5c56, 0x1c7d,
+ 0x5c58, 0x0892,
+ 0x5c59, 0x1ebb,
+ 0x5c5c, 0x0a5c,
+ 0x5c5e, 0x3d67,
+ 0x5c60, 0x0a5b,
+ 0x5c62, 0x0fc2,
+ 0x5c63, 0x2662,
+ 0x5c64, 0x1134,
+ 0x5c67, 0x28b7,
+ 0x5c68, 0x13c8,
+ 0x5c69, 0x2f19,
+ 0x5c6c, 0x166e,
+ 0x5c6d, 0x3483,
+ 0x5c6e, 0x1776,
+ 0x5c6f, 0x02ca,
+ 0x5c71, 0x0286,
+ 0x5c73, 0x17a3,
+ 0x5c74, 0x17a2,
+ 0x5c79, 0x03c7,
+ 0x5c7a, 0x17e0,
+ 0x5c7c, 0x17df,
+ 0x5c7e, 0x17e2,
+ 0x5c85, 0x4121,
+ 0x5c86, 0x186e,
+ 0x5c88, 0x1869,
+ 0x5c89, 0x186b,
+ 0x5c8a, 0x186d,
+ 0x5c8b, 0x186a,
+ 0x5c8c, 0x048c,
+ 0x5c8d, 0x1867,
+ 0x5c8f, 0x1868,
+ 0x5c90, 0x0489,
+ 0x5c92, 0x186c,
+ 0x5c93, 0x186f,
+ 0x5c94, 0x048b,
+ 0x5c95, 0x1870,
+ 0x5c99, 0x468c,
+ 0x5c9a, 0x4551,
+ 0x5c9c, 0x495a,
+ 0x5c9d, 0x196a,
+ 0x5c9e, 0x3a2a,
+ 0x5c9f, 0x1964,
+ 0x5ca0, 0x195f,
+ 0x5ca1, 0x05a5,
+ 0x5ca2, 0x1967,
+ 0x5ca3, 0x1965,
+ 0x5ca4, 0x195e,
+ 0x5ca5, 0x196b,
+ 0x5ca6, 0x196e,
+ 0x5ca7, 0x1969,
+ 0x5ca8, 0x1962,
+ 0x5ca9, 0x05a7,
+ 0x5caa, 0x1968,
+ 0x5cab, 0x05a8,
+ 0x5cac, 0x1963,
+ 0x5cad, 0x1966,
+ 0x5cae, 0x195d,
+ 0x5caf, 0x1961,
+ 0x5cb0, 0x196d,
+ 0x5cb1, 0x05a9,
+ 0x5cb3, 0x05aa,
+ 0x5cb5, 0x1960,
+ 0x5cb6, 0x196c,
+ 0x5cb7, 0x05a4,
+ 0x5cb8, 0x05a6,
+ 0x5cba, 0x412b,
+ 0x5cc1, 0x43b8,
+ 0x5cc2, 0x3d4c,
+ 0x5cc6, 0x1ac5,
+ 0x5cc7, 0x1abe,
+ 0x5cc8, 0x1ac4,
+ 0x5cc9, 0x1abd,
+ 0x5cca, 0x1abf,
+ 0x5ccb, 0x1ab9,
+ 0x5ccc, 0x1ab7,
+ 0x5cce, 0x1ac6,
+ 0x5ccf, 0x1ac3,
+ 0x5cd0, 0x1ab5,
+ 0x5cd1, 0x3f13,
+ 0x5cd2, 0x070c,
+ 0x5cd3, 0x1ac1,
+ 0x5cd6, 0x1ac0,
+ 0x5cd7, 0x1ab8,
+ 0x5cd8, 0x1ab6,
+ 0x5cd9, 0x070b,
+ 0x5cda, 0x1abc,
+ 0x5cdb, 0x1aba,
+ 0x5cde, 0x1abb,
+ 0x5cdf, 0x1ac7,
+ 0x5ce5, 0x4637,
+ 0x5ce8, 0x08a3,
+ 0x5ce9, 0x4122,
+ 0x5cea, 0x08a2,
+ 0x5cec, 0x1c7f,
+ 0x5ced, 0x089f,
+ 0x5cee, 0x1c81,
+ 0x5cef, 0x4123,
+ 0x5cf0, 0x08a4,
+ 0x5cf1, 0x1c82,
+ 0x5cf4, 0x08a7,
+ 0x5cf6, 0x08a5,
+ 0x5cf7, 0x1c83,
+ 0x5cf8, 0x1ac8,
+ 0x5cf9, 0x1c85,
+ 0x5cfb, 0x08a1,
+ 0x5cfd, 0x08a0,
+ 0x5cff, 0x1c80,
+ 0x5d00, 0x1c84,
+ 0x5d01, 0x08a6,
+ 0x5d06, 0x0a5f,
+ 0x5d07, 0x0a5e,
+ 0x5d0b, 0x1ebd,
+ 0x5d0c, 0x1ec1,
+ 0x5d0d, 0x1ec3,
+ 0x5d0e, 0x0a60,
+ 0x5d0f, 0x1ec6,
+ 0x5d10, 0x4127,
+ 0x5d11, 0x0a64,
+ 0x5d12, 0x1ec8,
+ 0x5d14, 0x0a66,
+ 0x5d15, 0x43b9,
+ 0x5d16, 0x0a62,
+ 0x5d17, 0x0a6a,
+ 0x5d18, 0x4128,
+ 0x5d19, 0x0a67,
+ 0x5d1a, 0x1ebf,
+ 0x5d1b, 0x0a61,
+ 0x5d1d, 0x1ebe,
+ 0x5d1e, 0x1ebc,
+ 0x5d1f, 0x1eca,
+ 0x5d20, 0x1ec0,
+ 0x5d22, 0x0a63,
+ 0x5d23, 0x1ec9,
+ 0x5d24, 0x0a68,
+ 0x5d25, 0x1ec5,
+ 0x5d26, 0x1ec4,
+ 0x5d27, 0x0a69,
+ 0x5d28, 0x1ec2,
+ 0x5d29, 0x0a65,
+ 0x5d2c, 0x3df7,
+ 0x5d2e, 0x1ecb,
+ 0x5d2f, 0x46d3,
+ 0x5d30, 0x1ec7,
+ 0x5d31, 0x2122,
+ 0x5d32, 0x2129,
+ 0x5d33, 0x211e,
+ 0x5d34, 0x0c34,
+ 0x5d35, 0x211a,
+ 0x5d36, 0x212a,
+ 0x5d37, 0x2114,
+ 0x5d38, 0x2127,
+ 0x5d39, 0x2125,
+ 0x5d3a, 0x211f,
+ 0x5d3c, 0x2128,
+ 0x5d3d, 0x2121,
+ 0x5d3e, 0x4629,
+ 0x5d3f, 0x2119,
+ 0x5d40, 0x212b,
+ 0x5d41, 0x2117,
+ 0x5d42, 0x2124,
+ 0x5d43, 0x2115,
+ 0x5d45, 0x212c,
+ 0x5d46, 0x4129,
+ 0x5d47, 0x0c35,
+ 0x5d48, 0x462a,
+ 0x5d49, 0x2126,
+ 0x5d4a, 0x23be,
+ 0x5d4b, 0x2118,
+ 0x5d4c, 0x0c32,
+ 0x5d4e, 0x211c,
+ 0x5d50, 0x0c33,
+ 0x5d51, 0x211b,
+ 0x5d52, 0x2120,
+ 0x5d55, 0x211d,
+ 0x5d56, 0x43ba,
+ 0x5d57, 0x3fca,
+ 0x5d59, 0x2123,
+ 0x5d5b, 0x3dd5,
+ 0x5d5e, 0x23c2,
+ 0x5d62, 0x23c5,
+ 0x5d63, 0x23bd,
+ 0x5d65, 0x23bf,
+ 0x5d67, 0x23c4,
+ 0x5d68, 0x23c3,
+ 0x5d69, 0x0dfd,
+ 0x5d6b, 0x2116,
+ 0x5d6c, 0x23c1,
+ 0x5d6f, 0x0dfe,
+ 0x5d70, 0x46e4,
+ 0x5d71, 0x23bc,
+ 0x5d72, 0x23c0,
+ 0x5d74, 0x3eef,
+ 0x5d77, 0x2669,
+ 0x5d79, 0x2670,
+ 0x5d7a, 0x2667,
+ 0x5d7c, 0x266e,
+ 0x5d7d, 0x2665,
+ 0x5d7e, 0x266d,
+ 0x5d7f, 0x2671,
+ 0x5d80, 0x2664,
+ 0x5d81, 0x2668,
+ 0x5d82, 0x2663,
+ 0x5d84, 0x0fc3,
+ 0x5d85, 0x3e34,
+ 0x5d86, 0x2666,
+ 0x5d87, 0x0fc4,
+ 0x5d88, 0x266c,
+ 0x5d89, 0x266b,
+ 0x5d8a, 0x266a,
+ 0x5d8b, 0x4124,
+ 0x5d8d, 0x266f,
+ 0x5d8e, 0x3f0c,
+ 0x5d92, 0x28bb,
+ 0x5d93, 0x28bd,
+ 0x5d94, 0x1137,
+ 0x5d95, 0x28be,
+ 0x5d97, 0x28b9,
+ 0x5d99, 0x28b8,
+ 0x5d9a, 0x28c2,
+ 0x5d9c, 0x28c0,
+ 0x5d9d, 0x1136,
+ 0x5d9e, 0x28c3,
+ 0x5d9f, 0x28ba,
+ 0x5da0, 0x28bf,
+ 0x5da1, 0x28c1,
+ 0x5da2, 0x28bc,
+ 0x5da4, 0x462d,
+ 0x5da7, 0x2b2c,
+ 0x5da8, 0x2b31,
+ 0x5da9, 0x2b2b,
+ 0x5daa, 0x2b30,
+ 0x5dab, 0x3e39,
+ 0x5dac, 0x2b29,
+ 0x5dad, 0x2b33,
+ 0x5dae, 0x2b2f,
+ 0x5daf, 0x2b34,
+ 0x5db0, 0x2b2e,
+ 0x5db1, 0x2b2a,
+ 0x5db2, 0x2b32,
+ 0x5db4, 0x2b35,
+ 0x5db5, 0x2b2d,
+ 0x5db6, 0x4158,
+ 0x5db7, 0x2d5b,
+ 0x5db8, 0x13cc,
+ 0x5db9, 0x462e,
+ 0x5dba, 0x13ca,
+ 0x5dbc, 0x13c9,
+ 0x5dbd, 0x13cb,
+ 0x5dc0, 0x2f1b,
+ 0x5dc1, 0x3bff,
+ 0x5dc2, 0x3023,
+ 0x5dc3, 0x308c,
+ 0x5dc6, 0x31cd,
+ 0x5dc9, 0x1613,
+ 0x5dcb, 0x32ce,
+ 0x5dcd, 0x166f,
+ 0x5dcf, 0x32cf,
+ 0x5dd1, 0x337f,
+ 0x5dd2, 0x16c2,
+ 0x5dd4, 0x16c1,
+ 0x5dd5, 0x337e,
+ 0x5dd6, 0x16f7,
+ 0x5dd7, 0x412c,
+ 0x5dd8, 0x3414,
+ 0x5ddb, 0x0226,
+ 0x5ddd, 0x0287,
+ 0x5dde, 0x03c8,
+ 0x5ddf, 0x17e3,
+ 0x5de0, 0x1871,
+ 0x5de1, 0x051a,
+ 0x5de2, 0x0a6b,
+ 0x5de5, 0x0288,
+ 0x5de6, 0x0338,
+ 0x5de7, 0x0337,
+ 0x5de8, 0x0336,
+ 0x5deb, 0x048d,
+ 0x5dee, 0x08a8,
+ 0x5df0, 0x23c6,
+ 0x5df1, 0x0289,
+ 0x5df4, 0x02cb,
+ 0x5df5, 0x3f61,
+ 0x5df7, 0x070d,
+ 0x5df9, 0x1ac9,
+ 0x5dfd, 0x0c36,
+ 0x5dfe, 0x028c,
+ 0x5dff, 0x1788,
+ 0x5e02, 0x0339,
+ 0x5e04, 0x17a4,
+ 0x5e06, 0x03c9,
+ 0x5e09, 0x4140,
+ 0x5e0a, 0x1872,
+ 0x5e0b, 0x3d8a,
+ 0x5e0c, 0x048e,
+ 0x5e0e, 0x1873,
+ 0x5e11, 0x05b0,
+ 0x5e12, 0x3f2e,
+ 0x5e14, 0x1970,
+ 0x5e15, 0x05ae,
+ 0x5e16, 0x05ad,
+ 0x5e17, 0x196f,
+ 0x5e18, 0x05ab,
+ 0x5e19, 0x1971,
+ 0x5e1a, 0x05ac,
+ 0x5e1b, 0x05af,
+ 0x5e1d, 0x070e,
+ 0x5e1f, 0x0710,
+ 0x5e20, 0x1acd,
+ 0x5e21, 0x1aca,
+ 0x5e24, 0x1ace,
+ 0x5e25, 0x070f,
+ 0x5e28, 0x1c87,
+ 0x5e29, 0x1c86,
+ 0x5e2b, 0x08aa,
+ 0x5e2d, 0x08a9,
+ 0x5e2e, 0x4135,
+ 0x5e33, 0x0a6e,
+ 0x5e34, 0x1ecd,
+ 0x5e36, 0x0a6d,
+ 0x5e37, 0x0a6f,
+ 0x5e38, 0x0a6c,
+ 0x5e3d, 0x0c38,
+ 0x5e3e, 0x1ecc,
+ 0x5e40, 0x0c39,
+ 0x5e41, 0x212e,
+ 0x5e42, 0x43a0,
+ 0x5e43, 0x0c3a,
+ 0x5e44, 0x212d,
+ 0x5e45, 0x0c37,
+ 0x5e48, 0x3a2c,
+ 0x5e4a, 0x23c9,
+ 0x5e4b, 0x23cb,
+ 0x5e4c, 0x0dff,
+ 0x5e4d, 0x23ca,
+ 0x5e4e, 0x23c8,
+ 0x5e4f, 0x23c7,
+ 0x5e53, 0x2674,
+ 0x5e54, 0x0fc9,
+ 0x5e55, 0x0fc7,
+ 0x5e57, 0x0fc8,
+ 0x5e58, 0x2672,
+ 0x5e5b, 0x0fc5,
+ 0x5e5c, 0x28c7,
+ 0x5e5d, 0x28c5,
+ 0x5e5e, 0x3a2b,
+ 0x5e5f, 0x1139,
+ 0x5e60, 0x28c6,
+ 0x5e61, 0x113a,
+ 0x5e62, 0x1138,
+ 0x5e63, 0x0fc6,
+ 0x5e66, 0x2b38,
+ 0x5e67, 0x2b36,
+ 0x5e69, 0x28c4,
+ 0x5e6a, 0x2d5d,
+ 0x5e6b, 0x13cd,
+ 0x5e6c, 0x2d5c,
+ 0x5e6d, 0x2f1c,
+ 0x5e6f, 0x2b39,
+ 0x5e70, 0x308d,
+ 0x5e72, 0x028d,
+ 0x5e73, 0x033b,
+ 0x5e74, 0x03cb,
+ 0x5e75, 0x17e4,
+ 0x5e76, 0x03ca,
+ 0x5e78, 0x05b1,
+ 0x5e79, 0x0e00,
+ 0x5e7a, 0x0227,
+ 0x5e7b, 0x02cc,
+ 0x5e7c, 0x033c,
+ 0x5e7d, 0x0711,
+ 0x5e7e, 0x0c3b,
+ 0x5e7f, 0x0228,
+ 0x5e80, 0x17a5,
+ 0x5e82, 0x17a6,
+ 0x5e83, 0x4108,
+ 0x5e84, 0x17e5,
+ 0x5e86, 0x4552,
+ 0x5e87, 0x0490,
+ 0x5e88, 0x1877,
+ 0x5e89, 0x1875,
+ 0x5e8a, 0x0491,
+ 0x5e8b, 0x1874,
+ 0x5e8c, 0x1876,
+ 0x5e8d, 0x1878,
+ 0x5e8f, 0x048f,
+ 0x5e95, 0x05b5,
+ 0x5e97, 0x05b3,
+ 0x5e9a, 0x05b2,
+ 0x5e9b, 0x1ad2,
+ 0x5e9c, 0x05b4,
+ 0x5ea0, 0x0712,
+ 0x5ea2, 0x1ad1,
+ 0x5ea3, 0x1ad3,
+ 0x5ea4, 0x1ad0,
+ 0x5ea5, 0x1ad4,
+ 0x5ea6, 0x0713,
+ 0x5ea7, 0x08ad,
+ 0x5ea8, 0x1c88,
+ 0x5eaa, 0x1c8a,
+ 0x5eab, 0x08ab,
+ 0x5eac, 0x1c8b,
+ 0x5ead, 0x08ac,
+ 0x5eae, 0x1c89,
+ 0x5eb0, 0x1acf,
+ 0x5eb1, 0x1ece,
+ 0x5eb2, 0x1ed1,
+ 0x5eb4, 0x1ecf,
+ 0x5eb5, 0x0a73,
+ 0x5eb6, 0x0a72,
+ 0x5eb7, 0x0a70,
+ 0x5eb9, 0x1ed0,
+ 0x5ebd, 0x43bd,
+ 0x5ebe, 0x0a74,
+ 0x5ec1, 0x0c3d,
+ 0x5ec4, 0x0c3f,
+ 0x5ec5, 0x23cc,
+ 0x5ec6, 0x23ce,
+ 0x5ec7, 0x23d0,
+ 0x5ec8, 0x0e02,
+ 0x5ec9, 0x0e01,
+ 0x5eca, 0x0c3c,
+ 0x5ecb, 0x23cf,
+ 0x5ecc, 0x23cd,
+ 0x5ecd, 0x3a30,
+ 0x5ece, 0x2678,
+ 0x5ed0, 0x413d,
+ 0x5ed1, 0x2676,
+ 0x5ed2, 0x267c,
+ 0x5ed3, 0x0fca,
+ 0x5ed4, 0x267d,
+ 0x5ed5, 0x267a,
+ 0x5ed6, 0x0fcb,
+ 0x5ed7, 0x2677,
+ 0x5ed8, 0x2675,
+ 0x5ed9, 0x267b,
+ 0x5eda, 0x113c,
+ 0x5edb, 0x28c9,
+ 0x5edc, 0x2679,
+ 0x5edd, 0x113e,
+ 0x5ede, 0x28ca,
+ 0x5edf, 0x113d,
+ 0x5ee0, 0x1140,
+ 0x5ee1, 0x28cb,
+ 0x5ee2, 0x113b,
+ 0x5ee3, 0x113f,
+ 0x5ee5, 0x2b3e,
+ 0x5ee6, 0x2b3c,
+ 0x5ee7, 0x2b3b,
+ 0x5ee8, 0x2b3d,
+ 0x5ee9, 0x2b3a,
+ 0x5eec, 0x157d,
+ 0x5eee, 0x31cf,
+ 0x5ef1, 0x32d0,
+ 0x5ef2, 0x3380,
+ 0x5ef3, 0x1742,
+ 0x5ef4, 0x0229,
+ 0x5ef6, 0x05b7,
+ 0x5ef7, 0x0492,
+ 0x5ef8, 0x386f,
+ 0x5ef9, 0x4143,
+ 0x5efa, 0x0714,
+ 0x5efb, 0x4144,
+ 0x5efc, 0x4146,
+ 0x5efe, 0x028e,
+ 0x5eff, 0x02cd,
+ 0x5f01, 0x033d,
+ 0x5f02, 0x17e6,
+ 0x5f04, 0x0493,
+ 0x5f05, 0x1879,
+ 0x5f07, 0x1ad5,
+ 0x5f08, 0x0715,
+ 0x5f0a, 0x0fcc,
+ 0x5f0b, 0x028f,
+ 0x5f0c, 0x3a3e,
+ 0x5f0d, 0x4149,
+ 0x5f0e, 0x3a3f,
+ 0x5f0f, 0x03cc,
+ 0x5f12, 0x0e03,
+ 0x5f13, 0x0290,
+ 0x5f14, 0x02ce,
+ 0x5f17, 0x033f,
+ 0x5f18, 0x033e,
+ 0x5f1a, 0x17e7,
+ 0x5f1b, 0x03cd,
+ 0x5f1d, 0x187a,
+ 0x5f1f, 0x0494,
+ 0x5f22, 0x1973,
+ 0x5f25, 0x4630,
+ 0x5f26, 0x05b8,
+ 0x5f28, 0x1972,
+ 0x5f29, 0x05ba,
+ 0x5f2d, 0x0716,
+ 0x5f2e, 0x1ad6,
+ 0x5f30, 0x1c8d,
+ 0x5f31, 0x08ae,
+ 0x5f33, 0x1c8c,
+ 0x5f35, 0x0a75,
+ 0x5f36, 0x1ed3,
+ 0x5f37, 0x0a76,
+ 0x5f38, 0x1ed4,
+ 0x5f3a, 0x414e,
+ 0x5f3c, 0x0c40,
+ 0x5f40, 0x23d1,
+ 0x5f43, 0x267f,
+ 0x5f44, 0x267e,
+ 0x5f46, 0x0fcd,
+ 0x5f48, 0x1141,
+ 0x5f49, 0x28cc,
+ 0x5f4a, 0x12ad,
+ 0x5f4b, 0x2b3f,
+ 0x5f4c, 0x13ce,
+ 0x5f4d, 0x3ba5,
+ 0x5f4e, 0x16c3,
+ 0x5f4f, 0x3416,
+ 0x5f50, 0x022a,
+ 0x5f51, 0x44e9,
+ 0x5f54, 0x1976,
+ 0x5f56, 0x1ad7,
+ 0x5f57, 0x0a77,
+ 0x5f58, 0x212f,
+ 0x5f59, 0x0e04,
+ 0x5f5c, 0x3d5a,
+ 0x5f5d, 0x14cf,
+ 0x5f61, 0x022b,
+ 0x5f62, 0x0496,
+ 0x5f63, 0x4152,
+ 0x5f64, 0x0495,
+ 0x5f65, 0x0717,
+ 0x5f67, 0x1c8e,
+ 0x5f69, 0x0a79,
+ 0x5f6a, 0x0b89,
+ 0x5f6b, 0x0a7a,
+ 0x5f6c, 0x0a78,
+ 0x5f6d, 0x0c41,
+ 0x5f6f, 0x2680,
+ 0x5f70, 0x0fce,
+ 0x5f71, 0x1142,
+ 0x5f72, 0x4154,
+ 0x5f73, 0x1777,
+ 0x5f74, 0x17e8,
+ 0x5f76, 0x187c,
+ 0x5f77, 0x0497,
+ 0x5f78, 0x187b,
+ 0x5f79, 0x0498,
+ 0x5f7b, 0x4058,
+ 0x5f7c, 0x05be,
+ 0x5f7d, 0x1979,
+ 0x5f7e, 0x1978,
+ 0x5f7f, 0x05bd,
+ 0x5f80, 0x05bb,
+ 0x5f82, 0x1977,
+ 0x5f83, 0x4631,
+ 0x5f85, 0x0719,
+ 0x5f86, 0x1ad8,
+ 0x5f87, 0x071c,
+ 0x5f88, 0x0718,
+ 0x5f89, 0x071e,
+ 0x5f8a, 0x071a,
+ 0x5f8c, 0x071d,
+ 0x5f90, 0x08b1,
+ 0x5f91, 0x08b0,
+ 0x5f92, 0x08af,
+ 0x5f96, 0x1ed6,
+ 0x5f97, 0x0a7b,
+ 0x5f98, 0x0a7e,
+ 0x5f99, 0x0a7c,
+ 0x5f9b, 0x1ed5,
+ 0x5f9c, 0x0a81,
+ 0x5f9e, 0x0a7d,
+ 0x5f9f, 0x1ed7,
+ 0x5fa0, 0x0a80,
+ 0x5fa1, 0x0a7f,
+ 0x5fa4, 0x402c,
+ 0x5fa5, 0x2131,
+ 0x5fa6, 0x2130,
+ 0x5fa7, 0x4157,
+ 0x5fa8, 0x0c44,
+ 0x5fa9, 0x0c42,
+ 0x5fab, 0x2132,
+ 0x5fac, 0x0e05,
+ 0x5fad, 0x23d3,
+ 0x5fae, 0x0e06,
+ 0x5faf, 0x23d2,
+ 0x5fb1, 0x3d98,
+ 0x5fb2, 0x28cd,
+ 0x5fb5, 0x1144,
+ 0x5fb6, 0x2681,
+ 0x5fb7, 0x1143,
+ 0x5fb9, 0x0fcf,
+ 0x5fba, 0x3f9f,
+ 0x5fbb, 0x2b41,
+ 0x5fbc, 0x2b40,
+ 0x5fbd, 0x13cf,
+ 0x5fbe, 0x2d5e,
+ 0x5fbf, 0x308e,
+ 0x5fc0, 0x31d1,
+ 0x5fc3, 0x02d0,
+ 0x5fc4, 0x44ea,
+ 0x5fc5, 0x0340,
+ 0x5fc9, 0x17a7,
+ 0x5fcc, 0x049a,
+ 0x5fcd, 0x049c,
+ 0x5fcf, 0x17eb,
+ 0x5fd0, 0x187f,
+ 0x5fd1, 0x187e,
+ 0x5fd2, 0x187d,
+ 0x5fd4, 0x17ea,
+ 0x5fd5, 0x17e9,
+ 0x5fd6, 0x03cf,
+ 0x5fd7, 0x049b,
+ 0x5fd8, 0x0499,
+ 0x5fd9, 0x03ce,
+ 0x5fdb, 0x3a4a,
+ 0x5fdd, 0x05bf,
+ 0x5fde, 0x197a,
+ 0x5fdf, 0x41af,
+ 0x5fe0, 0x05c0,
+ 0x5fe1, 0x1884,
+ 0x5fe3, 0x1886,
+ 0x5fe4, 0x1885,
+ 0x5fe5, 0x197b,
+ 0x5fe8, 0x1881,
+ 0x5fea, 0x04a0,
+ 0x5feb, 0x049e,
+ 0x5fed, 0x1880,
+ 0x5fee, 0x1882,
+ 0x5fef, 0x1888,
+ 0x5ff1, 0x049d,
+ 0x5ff3, 0x1883,
+ 0x5ff4, 0x188c,
+ 0x5ff5, 0x05c2,
+ 0x5ff7, 0x1889,
+ 0x5ff8, 0x049f,
+ 0x5ffa, 0x1887,
+ 0x5ffb, 0x188a,
+ 0x5ffd, 0x05c1,
+ 0x5fff, 0x05c3,
+ 0x6000, 0x188b,
+ 0x6009, 0x198f,
+ 0x600a, 0x1982,
+ 0x600b, 0x1980,
+ 0x600c, 0x198e,
+ 0x600d, 0x1989,
+ 0x600e, 0x0723,
+ 0x600f, 0x05c4,
+ 0x6010, 0x198a,
+ 0x6011, 0x198d,
+ 0x6012, 0x071f,
+ 0x6013, 0x198c,
+ 0x6014, 0x05c5,
+ 0x6015, 0x05ca,
+ 0x6016, 0x05c8,
+ 0x6017, 0x1983,
+ 0x6019, 0x197e,
+ 0x601a, 0x1985,
+ 0x601b, 0x05cf,
+ 0x601c, 0x1990,
+ 0x601d, 0x0720,
+ 0x601e, 0x1986,
+ 0x6020, 0x0721,
+ 0x6021, 0x05cb,
+ 0x6022, 0x1988,
+ 0x6023, 0x4185,
+ 0x6024, 0x1ae7,
+ 0x6025, 0x0722,
+ 0x6026, 0x197d,
+ 0x6027, 0x05cc,
+ 0x6028, 0x0724,
+ 0x6029, 0x05cd,
+ 0x602a, 0x05c9,
+ 0x602b, 0x05ce,
+ 0x602c, 0x1987,
+ 0x602d, 0x197c,
+ 0x602e, 0x198b,
+ 0x602f, 0x05c6,
+ 0x6031, 0x4161,
+ 0x6032, 0x197f,
+ 0x6033, 0x1984,
+ 0x6034, 0x1981,
+ 0x6035, 0x05c7,
+ 0x6037, 0x1ad9,
+ 0x6039, 0x1ada,
+ 0x603b, 0x4553,
+ 0x6040, 0x1ae4,
+ 0x6041, 0x1c92,
+ 0x6042, 0x1ae5,
+ 0x6043, 0x072a,
+ 0x6044, 0x1ae8,
+ 0x6045, 0x1ade,
+ 0x6046, 0x0729,
+ 0x6047, 0x1ae0,
+ 0x6049, 0x1ae1,
+ 0x604a, 0x4074,
+ 0x604c, 0x1ae3,
+ 0x604d, 0x0725,
+ 0x6050, 0x08b5,
+ 0x6052, 0x36ec,
+ 0x6053, 0x1adf,
+ 0x6054, 0x1adb,
+ 0x6055, 0x08b6,
+ 0x6058, 0x1ae9,
+ 0x6059, 0x08b2,
+ 0x605a, 0x1c90,
+ 0x605b, 0x1ae2,
+ 0x605d, 0x1c8f,
+ 0x605e, 0x1add,
+ 0x605f, 0x1ae6,
+ 0x6062, 0x0728,
+ 0x6063, 0x08b3,
+ 0x6064, 0x072e,
+ 0x6065, 0x08b4,
+ 0x6066, 0x1aea,
+ 0x6067, 0x1c91,
+ 0x6068, 0x0727,
+ 0x6069, 0x08b8,
+ 0x606a, 0x072d,
+ 0x606b, 0x072c,
+ 0x606c, 0x072b,
+ 0x606d, 0x08b7,
+ 0x606e, 0x1aeb,
+ 0x606f, 0x08b9,
+ 0x6070, 0x0726,
+ 0x6072, 0x1adc,
+ 0x6075, 0x3a56,
+ 0x6077, 0x4005,
+ 0x607e, 0x3a47,
+ 0x607f, 0x0a82,
+ 0x6080, 0x1c95,
+ 0x6081, 0x1c97,
+ 0x6083, 0x1c99,
+ 0x6084, 0x08ba,
+ 0x6085, 0x08c0,
+ 0x6086, 0x1eda,
+ 0x6087, 0x1c9d,
+ 0x6088, 0x1c94,
+ 0x6089, 0x0a84,
+ 0x608a, 0x1ed8,
+ 0x608c, 0x08bf,
+ 0x608d, 0x08bd,
+ 0x608e, 0x1c9f,
+ 0x6090, 0x1ed9,
+ 0x6092, 0x1c96,
+ 0x6094, 0x08be,
+ 0x6095, 0x1c9a,
+ 0x6096, 0x08c1,
+ 0x6097, 0x1c9c,
+ 0x609a, 0x08bc,
+ 0x609b, 0x1c9b,
+ 0x609c, 0x1c9e,
+ 0x609d, 0x1c98,
+ 0x609e, 0x416a,
+ 0x609f, 0x08bb,
+ 0x60a0, 0x0a85,
+ 0x60a2, 0x1c93,
+ 0x60a3, 0x0a83,
+ 0x60a4, 0x4001,
+ 0x60a7, 0x3adc,
+ 0x60a8, 0x0a86,
+ 0x60b0, 0x1edc,
+ 0x60b1, 0x1ee5,
+ 0x60b2, 0x0c47,
+ 0x60b3, 0x416c,
+ 0x60b4, 0x0a88,
+ 0x60b5, 0x0a8d,
+ 0x60b6, 0x0c48,
+ 0x60b7, 0x1ee7,
+ 0x60b8, 0x0a94,
+ 0x60b9, 0x2134,
+ 0x60ba, 0x1edd,
+ 0x60bb, 0x0a8c,
+ 0x60bc, 0x0a8f,
+ 0x60bd, 0x0a8a,
+ 0x60be, 0x1edb,
+ 0x60bf, 0x1ee9,
+ 0x60c0, 0x1eec,
+ 0x60c1, 0x2143,
+ 0x60c3, 0x1eea,
+ 0x60c4, 0x2138,
+ 0x60c5, 0x0a8b,
+ 0x60c6, 0x0a92,
+ 0x60c7, 0x0a96,
+ 0x60c8, 0x1ee4,
+ 0x60c9, 0x2133,
+ 0x60ca, 0x1ee8,
+ 0x60cb, 0x0a87,
+ 0x60cc, 0x2135,
+ 0x60cd, 0x1eeb,
+ 0x60ce, 0x2137,
+ 0x60cf, 0x1ee0,
+ 0x60d1, 0x0c45,
+ 0x60d3, 0x1ede,
+ 0x60d5, 0x0a91,
+ 0x60d7, 0x4635,
+ 0x60d8, 0x0a90,
+ 0x60d9, 0x1ee2,
+ 0x60da, 0x0a95,
+ 0x60db, 0x1ee6,
+ 0x60dc, 0x0a8e,
+ 0x60dd, 0x1ee3,
+ 0x60de, 0x3dcc,
+ 0x60df, 0x0a93,
+ 0x60e0, 0x0c49,
+ 0x60e1, 0x0c46,
+ 0x60e2, 0x2136,
+ 0x60e3, 0x3d75,
+ 0x60e4, 0x1ee1,
+ 0x60e6, 0x0a89,
+ 0x60e7, 0x3d84,
+ 0x60e8, 0x3d7b,
+ 0x60e9, 0x4009,
+ 0x60f0, 0x0c4e,
+ 0x60f1, 0x0c52,
+ 0x60f2, 0x213a,
+ 0x60f3, 0x0e0b,
+ 0x60f4, 0x0c50,
+ 0x60f5, 0x213e,
+ 0x60f6, 0x0c54,
+ 0x60f7, 0x23d4,
+ 0x60f8, 0x2140,
+ 0x60f9, 0x0e0d,
+ 0x60fa, 0x0c4c,
+ 0x60fb, 0x0c4f,
+ 0x60fc, 0x2141,
+ 0x60fd, 0x3fa8,
+ 0x60fe, 0x2142,
+ 0x60ff, 0x2148,
+ 0x6100, 0x0c56,
+ 0x6101, 0x0e0e,
+ 0x6103, 0x2144,
+ 0x6104, 0x2149,
+ 0x6105, 0x213d,
+ 0x6106, 0x0e18,
+ 0x6107, 0x3c35,
+ 0x6108, 0x0e0f,
+ 0x6109, 0x0c55,
+ 0x610a, 0x213b,
+ 0x610b, 0x214a,
+ 0x610c, 0x3c87,
+ 0x610d, 0x0e17,
+ 0x610e, 0x0c53,
+ 0x610f, 0x0e08,
+ 0x6110, 0x2147,
+ 0x6112, 0x0c57,
+ 0x6113, 0x213f,
+ 0x6114, 0x2139,
+ 0x6115, 0x0c4d,
+ 0x6116, 0x213c,
+ 0x6118, 0x2145,
+ 0x6119, 0x3ef6,
+ 0x611a, 0x0e07,
+ 0x611b, 0x0e0c,
+ 0x611c, 0x0c4a,
+ 0x611d, 0x2146,
+ 0x611f, 0x0e0a,
+ 0x6123, 0x0c4b,
+ 0x6127, 0x0e16,
+ 0x6128, 0x2683,
+ 0x6129, 0x23df,
+ 0x612b, 0x23d7,
+ 0x612c, 0x2682,
+ 0x612e, 0x23db,
+ 0x612f, 0x23dd,
+ 0x6130, 0x3f37,
+ 0x6132, 0x23da,
+ 0x6134, 0x0e15,
+ 0x6136, 0x23d9,
+ 0x6137, 0x0e19,
+ 0x613b, 0x2692,
+ 0x613d, 0x4636,
+ 0x613e, 0x0e14,
+ 0x613f, 0x0fd1,
+ 0x6140, 0x23e0,
+ 0x6141, 0x2684,
+ 0x6142, 0x4174,
+ 0x6144, 0x0e12,
+ 0x6145, 0x23d8,
+ 0x6146, 0x23dc,
+ 0x6147, 0x0fd0,
+ 0x6148, 0x0e09,
+ 0x6149, 0x23d5,
+ 0x614b, 0x0fd2,
+ 0x614c, 0x0e11,
+ 0x614d, 0x0e13,
+ 0x614e, 0x0e10,
+ 0x614f, 0x23de,
+ 0x6150, 0x3c32,
+ 0x6152, 0x2688,
+ 0x6154, 0x268e,
+ 0x6155, 0x1149,
+ 0x6156, 0x2695,
+ 0x6158, 0x0fd8,
+ 0x6159, 0x3fba,
+ 0x615a, 0x0fd7,
+ 0x615b, 0x2690,
+ 0x615c, 0x4186,
+ 0x615d, 0x1148,
+ 0x615e, 0x2685,
+ 0x615f, 0x0fd6,
+ 0x6160, 0x494c,
+ 0x6161, 0x2694,
+ 0x6162, 0x0fd4,
+ 0x6164, 0x4173,
+ 0x6165, 0x2691,
+ 0x6166, 0x28de,
+ 0x6167, 0x1146,
+ 0x6168, 0x0c51,
+ 0x616a, 0x2693,
+ 0x616b, 0x114d,
+ 0x616c, 0x268b,
+ 0x616e, 0x1147,
+ 0x616f, 0x3fc0,
+ 0x6170, 0x114c,
+ 0x6171, 0x2686,
+ 0x6172, 0x268a,
+ 0x6173, 0x2687,
+ 0x6174, 0x268d,
+ 0x6175, 0x0fd9,
+ 0x6176, 0x1145,
+ 0x6177, 0x0fd3,
+ 0x6179, 0x28d0,
+ 0x617a, 0x268f,
+ 0x617c, 0x114b,
+ 0x617d, 0x3fbd,
+ 0x617e, 0x114e,
+ 0x6180, 0x268c,
+ 0x6181, 0x4177,
+ 0x6182, 0x114a,
+ 0x6183, 0x28cf,
+ 0x6187, 0x417a,
+ 0x6189, 0x28d4,
+ 0x618a, 0x12b1,
+ 0x618b, 0x28ce,
+ 0x618c, 0x2b4d,
+ 0x618d, 0x28dd,
+ 0x618e, 0x1152,
+ 0x6190, 0x1150,
+ 0x6191, 0x12af,
+ 0x6192, 0x28da,
+ 0x6193, 0x28d6,
+ 0x6194, 0x1156,
+ 0x6195, 0x3de0,
+ 0x6196, 0x2b44,
+ 0x6198, 0x3a55,
+ 0x6199, 0x3a54,
+ 0x619a, 0x1154,
+ 0x619b, 0x28d5,
+ 0x619c, 0x4002,
+ 0x619d, 0x2b42,
+ 0x619f, 0x28d9,
+ 0x61a1, 0x28dc,
+ 0x61a2, 0x28d3,
+ 0x61a4, 0x1155,
+ 0x61a7, 0x114f,
+ 0x61a8, 0x2b43,
+ 0x61a9, 0x12b0,
+ 0x61aa, 0x28db,
+ 0x61ab, 0x1151,
+ 0x61ac, 0x1153,
+ 0x61ad, 0x28d8,
+ 0x61ae, 0x1157,
+ 0x61af, 0x28d7,
+ 0x61b0, 0x28d2,
+ 0x61b1, 0x28d1,
+ 0x61b2, 0x12ae,
+ 0x61b3, 0x28df,
+ 0x61b4, 0x2b46,
+ 0x61b5, 0x2d60,
+ 0x61b6, 0x12b3,
+ 0x61b7, 0x4639,
+ 0x61b8, 0x2b4c,
+ 0x61b9, 0x43bf,
+ 0x61ba, 0x2b4a,
+ 0x61bc, 0x2d61,
+ 0x61be, 0x12b4,
+ 0x61bf, 0x2b4b,
+ 0x61c0, 0x3a50,
+ 0x61c1, 0x2b48,
+ 0x61c2, 0x13d1,
+ 0x61c3, 0x2d5f,
+ 0x61c5, 0x2b45,
+ 0x61c6, 0x2b47,
+ 0x61c7, 0x13d2,
+ 0x61c8, 0x12b6,
+ 0x61c9, 0x13d0,
+ 0x61ca, 0x12b5,
+ 0x61cb, 0x13d4,
+ 0x61cc, 0x2b49,
+ 0x61cd, 0x12b2,
+ 0x61cf, 0x463a,
+ 0x61d0, 0x4181,
+ 0x61d3, 0x417e,
+ 0x61d6, 0x2f26,
+ 0x61d8, 0x2f1e,
+ 0x61da, 0x38b1,
+ 0x61de, 0x2d67,
+ 0x61df, 0x2f1f,
+ 0x61e0, 0x2d63,
+ 0x61e2, 0x3fc5,
+ 0x61e3, 0x14d0,
+ 0x61e4, 0x2d65,
+ 0x61e5, 0x2d64,
+ 0x61e6, 0x13d3,
+ 0x61e7, 0x2d62,
+ 0x61e8, 0x2d66,
+ 0x61e9, 0x2f27,
+ 0x61ea, 0x2f23,
+ 0x61eb, 0x2f25,
+ 0x61ed, 0x2f20,
+ 0x61f0, 0x2f24,
+ 0x61f1, 0x2f22,
+ 0x61f2, 0x157e,
+ 0x61f5, 0x1581,
+ 0x61f6, 0x1580,
+ 0x61f7, 0x157f,
+ 0x61f8, 0x1614,
+ 0x61f9, 0x31d3,
+ 0x61fa, 0x1615,
+ 0x61fb, 0x308f,
+ 0x61fc, 0x1670,
+ 0x61fd, 0x32d1,
+ 0x61fe, 0x1671,
+ 0x61ff, 0x16c4,
+ 0x6200, 0x16f8,
+ 0x6201, 0x3417,
+ 0x6203, 0x3418,
+ 0x6207, 0x3533,
+ 0x6208, 0x02d1,
+ 0x6209, 0x17a8,
+ 0x620a, 0x0341,
+ 0x620c, 0x03d1,
+ 0x620e, 0x03d0,
+ 0x6210, 0x03d3,
+ 0x6211, 0x04a2,
+ 0x6212, 0x04a1,
+ 0x6214, 0x1991,
+ 0x6215, 0x05d1,
+ 0x6216, 0x05d0,
+ 0x6219, 0x1ca0,
+ 0x621a, 0x0a97,
+ 0x621f, 0x0c58,
+ 0x6220, 0x23e1,
+ 0x6221, 0x0e1a,
+ 0x6223, 0x23e3,
+ 0x6224, 0x23e5,
+ 0x6225, 0x23e4,
+ 0x6227, 0x2697,
+ 0x6229, 0x2696,
+ 0x622a, 0x0fda,
+ 0x622b, 0x2698,
+ 0x622c, 0x463c,
+ 0x622d, 0x28e0,
+ 0x622e, 0x1158,
+ 0x6230, 0x12b7,
+ 0x6232, 0x13d5,
+ 0x6233, 0x14d1,
+ 0x6234, 0x13d6,
+ 0x6236, 0x02d2,
+ 0x6237, 0x451a,
+ 0x6239, 0x3fc2,
+ 0x623a, 0x188d,
+ 0x623d, 0x1992,
+ 0x623e, 0x05d3,
+ 0x623f, 0x05d2,
+ 0x6240, 0x05d4,
+ 0x6241, 0x072f,
+ 0x6242, 0x1aec,
+ 0x6246, 0x1ca1,
+ 0x6247, 0x08c2,
+ 0x6248, 0x0a99,
+ 0x6249, 0x0c59,
+ 0x624a, 0x214b,
+ 0x624b, 0x02d3,
+ 0x624c, 0x44ec,
+ 0x624d, 0x0291,
+ 0x624e, 0x02d4,
+ 0x6250, 0x17a9,
+ 0x6251, 0x0345,
+ 0x6252, 0x0344,
+ 0x6253, 0x0342,
+ 0x6258, 0x03d6,
+ 0x6259, 0x17f2,
+ 0x625a, 0x17f4,
+ 0x625b, 0x03d5,
+ 0x625c, 0x17ec,
+ 0x625e, 0x17ed,
+ 0x6260, 0x17f3,
+ 0x6261, 0x17ef,
+ 0x6262, 0x17f1,
+ 0x6263, 0x03d4,
+ 0x6264, 0x17ee,
+ 0x6265, 0x17f5,
+ 0x6266, 0x17f0,
+ 0x6268, 0x3f15,
+ 0x626d, 0x04a9,
+ 0x626e, 0x04b2,
+ 0x626f, 0x04b0,
+ 0x6270, 0x1897,
+ 0x6271, 0x1894,
+ 0x6272, 0x189c,
+ 0x6273, 0x04ae,
+ 0x6274, 0x189d,
+ 0x6276, 0x04a7,
+ 0x6277, 0x189a,
+ 0x6279, 0x04ad,
+ 0x627a, 0x1896,
+ 0x627b, 0x1895,
+ 0x627c, 0x04ab,
+ 0x627d, 0x189b,
+ 0x627e, 0x04ac,
+ 0x627f, 0x05d5,
+ 0x6280, 0x04a6,
+ 0x6281, 0x1898,
+ 0x6282, 0x3f86,
+ 0x6283, 0x188e,
+ 0x6284, 0x04a3,
+ 0x6285, 0x3f50,
+ 0x6286, 0x04b6,
+ 0x6287, 0x1893,
+ 0x6288, 0x1899,
+ 0x6289, 0x04a8,
+ 0x628a, 0x04aa,
+ 0x628c, 0x188f,
+ 0x628e, 0x1890,
+ 0x6290, 0x43c0,
+ 0x6291, 0x04b5,
+ 0x6292, 0x04af,
+ 0x6293, 0x04b4,
+ 0x6294, 0x1892,
+ 0x6295, 0x04b3,
+ 0x6296, 0x04a5,
+ 0x6297, 0x04a4,
+ 0x6298, 0x04b1,
+ 0x629d, 0x3e96,
+ 0x62a4, 0x3a69,
+ 0x62a6, 0x3fc1,
+ 0x62a8, 0x05e3,
+ 0x62a9, 0x199e,
+ 0x62aa, 0x1997,
+ 0x62ab, 0x05de,
+ 0x62ac, 0x05f1,
+ 0x62ad, 0x1993,
+ 0x62ae, 0x199a,
+ 0x62af, 0x199c,
+ 0x62b0, 0x199f,
+ 0x62b1, 0x05ec,
+ 0x62b3, 0x199b,
+ 0x62b4, 0x1994,
+ 0x62b5, 0x05ea,
+ 0x62b6, 0x1998,
+ 0x62b8, 0x19a0,
+ 0x62b9, 0x05db,
+ 0x62bb, 0x199d,
+ 0x62bc, 0x05e5,
+ 0x62bd, 0x05e4,
+ 0x62be, 0x1996,
+ 0x62bf, 0x05d9,
+ 0x62c2, 0x05da,
+ 0x62c3, 0x3d8f,
+ 0x62c4, 0x05d8,
+ 0x62c5, 0x418a,
+ 0x62c6, 0x05f0,
+ 0x62c7, 0x05e8,
+ 0x62c8, 0x05e2,
+ 0x62c9, 0x05d6,
+ 0x62ca, 0x1999,
+ 0x62cb, 0x05e1,
+ 0x62cc, 0x05d7,
+ 0x62cd, 0x05e9,
+ 0x62ce, 0x05f2,
+ 0x62cf, 0x1aee,
+ 0x62d0, 0x05e6,
+ 0x62d1, 0x1995,
+ 0x62d2, 0x05dc,
+ 0x62d3, 0x05df,
+ 0x62d5, 0x418c,
+ 0x62d6, 0x05ee,
+ 0x62d8, 0x05ed,
+ 0x62d9, 0x05e7,
+ 0x62da, 0x05eb,
+ 0x62db, 0x05dd,
+ 0x62dc, 0x0730,
+ 0x62df, 0x401c,
+ 0x62e5, 0x463d,
+ 0x62eb, 0x1af4,
+ 0x62ec, 0x073c,
+ 0x62ed, 0x0734,
+ 0x62ee, 0x0736,
+ 0x62ef, 0x073b,
+ 0x62f0, 0x1b00,
+ 0x62f1, 0x0739,
+ 0x62f2, 0x1ca2,
+ 0x62f3, 0x08c3,
+ 0x62f4, 0x073e,
+ 0x62f5, 0x1af1,
+ 0x62f6, 0x1af9,
+ 0x62f7, 0x073a,
+ 0x62f8, 0x1af8,
+ 0x62f9, 0x1af5,
+ 0x62fa, 0x1afd,
+ 0x62fb, 0x1aff,
+ 0x62fc, 0x0733,
+ 0x62fd, 0x0737,
+ 0x62fe, 0x073d,
+ 0x62ff, 0x08c5,
+ 0x6300, 0x1afa,
+ 0x6301, 0x0735,
+ 0x6302, 0x0740,
+ 0x6303, 0x1af3,
+ 0x6307, 0x0738,
+ 0x6308, 0x08c4,
+ 0x6309, 0x0732,
+ 0x630b, 0x1af0,
+ 0x630c, 0x1af7,
+ 0x630d, 0x1aef,
+ 0x630e, 0x1af2,
+ 0x630f, 0x1af6,
+ 0x6310, 0x1ca3,
+ 0x6311, 0x073f,
+ 0x6313, 0x1afb,
+ 0x6315, 0x1afe,
+ 0x6316, 0x0731,
+ 0x6318, 0x43c1,
+ 0x6328, 0x08d3,
+ 0x6329, 0x1caf,
+ 0x632a, 0x08d1,
+ 0x632c, 0x1ca5,
+ 0x632d, 0x1cb5,
+ 0x632e, 0x3edd,
+ 0x632f, 0x08c8,
+ 0x6331, 0x3a65,
+ 0x6332, 0x1eed,
+ 0x6333, 0x1cb7,
+ 0x6334, 0x1cb1,
+ 0x6335, 0x3f16,
+ 0x6336, 0x1ca8,
+ 0x6337, 0x3a63,
+ 0x6338, 0x1cba,
+ 0x6339, 0x1cab,
+ 0x633a, 0x08ce,
+ 0x633b, 0x1f04,
+ 0x633c, 0x1cae,
+ 0x633d, 0x08d0,
+ 0x633e, 0x08c7,
+ 0x6340, 0x1cbc,
+ 0x6341, 0x1cb0,
+ 0x6342, 0x08ca,
+ 0x6343, 0x1ca9,
+ 0x6344, 0x1ca6,
+ 0x6346, 0x08cb,
+ 0x6347, 0x1cb6,
+ 0x6348, 0x1cbd,
+ 0x6349, 0x08cd,
+ 0x634a, 0x1cad,
+ 0x634b, 0x1cac,
+ 0x634c, 0x08d5,
+ 0x634d, 0x08d4,
+ 0x634e, 0x08c6,
+ 0x634f, 0x08cc,
+ 0x6350, 0x08cf,
+ 0x6351, 0x1cb9,
+ 0x6354, 0x1cb3,
+ 0x6355, 0x08c9,
+ 0x6356, 0x1ca4,
+ 0x6357, 0x1cbb,
+ 0x6358, 0x1cb2,
+ 0x6359, 0x1cb4,
+ 0x635a, 0x1cb8,
+ 0x6364, 0x3fc7,
+ 0x6365, 0x1eee,
+ 0x6367, 0x0aa1,
+ 0x6368, 0x0ab5,
+ 0x6369, 0x0ab4,
+ 0x636b, 0x0aa9,
+ 0x636c, 0x418e,
+ 0x636d, 0x1f00,
+ 0x636e, 0x1efc,
+ 0x636f, 0x1ef9,
+ 0x6370, 0x1f0b,
+ 0x6371, 0x0aa4,
+ 0x6372, 0x0a9c,
+ 0x6375, 0x1efe,
+ 0x6376, 0x0c69,
+ 0x6377, 0x0aa0,
+ 0x6378, 0x1f06,
+ 0x6379, 0x4367,
+ 0x637a, 0x0ab6,
+ 0x637b, 0x0ab3,
+ 0x637c, 0x1f02,
+ 0x637d, 0x1ef1,
+ 0x637f, 0x3f4b,
+ 0x6380, 0x0ab2,
+ 0x6381, 0x1f08,
+ 0x6382, 0x1ef0,
+ 0x6383, 0x0aa7,
+ 0x6384, 0x0aab,
+ 0x6385, 0x1f07,
+ 0x6387, 0x1efa,
+ 0x6388, 0x0aac,
+ 0x6389, 0x0aa6,
+ 0x638a, 0x1eef,
+ 0x638b, 0x4188,
+ 0x638c, 0x0c5b,
+ 0x638d, 0x1f0a,
+ 0x638e, 0x1ef8,
+ 0x638f, 0x0ab1,
+ 0x6390, 0x1efb,
+ 0x6391, 0x1f09,
+ 0x6392, 0x0ab0,
+ 0x6394, 0x214c,
+ 0x6396, 0x0a9d,
+ 0x6397, 0x1ef6,
+ 0x6398, 0x0aa2,
+ 0x6399, 0x0aad,
+ 0x639b, 0x0aa8,
+ 0x639c, 0x1eff,
+ 0x639d, 0x1ef5,
+ 0x639e, 0x1ef3,
+ 0x639f, 0x1f05,
+ 0x63a0, 0x0a9a,
+ 0x63a1, 0x0aae,
+ 0x63a2, 0x0a9e,
+ 0x63a3, 0x0c5a,
+ 0x63a4, 0x1f03,
+ 0x63a5, 0x0a9f,
+ 0x63a7, 0x0a9b,
+ 0x63a8, 0x0aaa,
+ 0x63a9, 0x0aa5,
+ 0x63aa, 0x0aa3,
+ 0x63ab, 0x1ef7,
+ 0x63ac, 0x0aaf,
+ 0x63ad, 0x1ef4,
+ 0x63ae, 0x1f01,
+ 0x63af, 0x1efd,
+ 0x63b0, 0x214e,
+ 0x63b1, 0x214d,
+ 0x63b9, 0x3e9d,
+ 0x63bd, 0x1ef2,
+ 0x63be, 0x215e,
+ 0x63c0, 0x0c5d,
+ 0x63c1, 0x46a8,
+ 0x63c2, 0x2164,
+ 0x63c3, 0x2153,
+ 0x63c4, 0x2161,
+ 0x63c5, 0x23e6,
+ 0x63c6, 0x0c60,
+ 0x63c7, 0x2165,
+ 0x63c8, 0x2168,
+ 0x63c9, 0x0c5f,
+ 0x63ca, 0x2156,
+ 0x63cb, 0x2167,
+ 0x63cc, 0x2166,
+ 0x63cd, 0x0c61,
+ 0x63ce, 0x214f,
+ 0x63cf, 0x0c5c,
+ 0x63d0, 0x0c64,
+ 0x63d1, 0x3a66,
+ 0x63d2, 0x0c62,
+ 0x63d3, 0x2163,
+ 0x63d5, 0x2159,
+ 0x63d6, 0x0c66,
+ 0x63d7, 0x216a,
+ 0x63d8, 0x2162,
+ 0x63d9, 0x216b,
+ 0x63da, 0x0c6e,
+ 0x63db, 0x0c6c,
+ 0x63dc, 0x2160,
+ 0x63dd, 0x215f,
+ 0x63de, 0x3e60,
+ 0x63df, 0x215d,
+ 0x63e0, 0x2157,
+ 0x63e1, 0x0c65,
+ 0x63e2, 0x4641,
+ 0x63e3, 0x0c63,
+ 0x63e4, 0x1caa,
+ 0x63e5, 0x2150,
+ 0x63e6, 0x489f,
+ 0x63e7, 0x2404,
+ 0x63e8, 0x2151,
+ 0x63e9, 0x0c5e,
+ 0x63ea, 0x0c6b,
+ 0x63eb, 0x23e8,
+ 0x63ed, 0x0c67,
+ 0x63ef, 0x2152,
+ 0x63f0, 0x2169,
+ 0x63f1, 0x23e7,
+ 0x63f2, 0x215a,
+ 0x63f3, 0x2155,
+ 0x63f4, 0x0c6a,
+ 0x63f5, 0x215b,
+ 0x63f6, 0x2158,
+ 0x63f8, 0x4192,
+ 0x63f9, 0x0c6f,
+ 0x63fb, 0x4642,
+ 0x63fc, 0x3e9c,
+ 0x63fe, 0x3e9e,
+ 0x6406, 0x0e2a,
+ 0x6407, 0x4643,
+ 0x6409, 0x23eb,
+ 0x640a, 0x23fe,
+ 0x640b, 0x2403,
+ 0x640c, 0x23f7,
+ 0x640d, 0x0e26,
+ 0x640e, 0x2408,
+ 0x640f, 0x0e23,
+ 0x6410, 0x23e9,
+ 0x6412, 0x23ea,
+ 0x6413, 0x0e1c,
+ 0x6414, 0x0e25,
+ 0x6415, 0x23f1,
+ 0x6416, 0x0e28,
+ 0x6418, 0x23f2,
+ 0x641a, 0x23ff,
+ 0x641b, 0x2405,
+ 0x641c, 0x0e24,
+ 0x641e, 0x0e1e,
+ 0x641f, 0x23f0,
+ 0x6420, 0x23ec,
+ 0x6421, 0x2407,
+ 0x6422, 0x23f5,
+ 0x6424, 0x23ed,
+ 0x6425, 0x2401,
+ 0x6426, 0x23f8,
+ 0x6427, 0x2402,
+ 0x6428, 0x23fa,
+ 0x642a, 0x0e1f,
+ 0x642b, 0x2699,
+ 0x642c, 0x0e22,
+ 0x642d, 0x0e20,
+ 0x642e, 0x2406,
+ 0x642f, 0x23fd,
+ 0x6430, 0x23f9,
+ 0x6432, 0x45d9,
+ 0x6433, 0x23ee,
+ 0x6434, 0x0fe4,
+ 0x6435, 0x23fc,
+ 0x6436, 0x0e27,
+ 0x6437, 0x23f4,
+ 0x6438, 0x4191,
+ 0x6439, 0x23f3,
+ 0x643a, 0x419d,
+ 0x643b, 0x3a6b,
+ 0x643d, 0x0e21,
+ 0x643e, 0x0e1d,
+ 0x643f, 0x26ae,
+ 0x6440, 0x2400,
+ 0x6441, 0x23fb,
+ 0x6443, 0x23ef,
+ 0x644b, 0x26a9,
+ 0x644d, 0x269a,
+ 0x644e, 0x26a5,
+ 0x6450, 0x26ac,
+ 0x6451, 0x0fe2,
+ 0x6452, 0x0c6d,
+ 0x6453, 0x26aa,
+ 0x6454, 0x0fdd,
+ 0x6458, 0x0fdc,
+ 0x6459, 0x26b1,
+ 0x645a, 0x43c2,
+ 0x645b, 0x269b,
+ 0x645c, 0x26a8,
+ 0x645d, 0x269c,
+ 0x645e, 0x26a7,
+ 0x645f, 0x0fe0,
+ 0x6460, 0x26ab,
+ 0x6461, 0x215c,
+ 0x6465, 0x26b2,
+ 0x6466, 0x26a3,
+ 0x6467, 0x0fe3,
+ 0x6468, 0x28ee,
+ 0x6469, 0x1159,
+ 0x646b, 0x26b0,
+ 0x646c, 0x26af,
+ 0x646d, 0x0fe5,
+ 0x646e, 0x28e1,
+ 0x646f, 0x115a,
+ 0x6470, 0x28e2,
+ 0x6471, 0x3a5b,
+ 0x6472, 0x269f,
+ 0x6474, 0x269d,
+ 0x6475, 0x26a2,
+ 0x6476, 0x269e,
+ 0x6477, 0x26b3,
+ 0x6478, 0x0fdf,
+ 0x6479, 0x115b,
+ 0x647a, 0x0fe1,
+ 0x647b, 0x0fe6,
+ 0x647c, 0x436c,
+ 0x647d, 0x26a1,
+ 0x647f, 0x26ad,
+ 0x6482, 0x26a6,
+ 0x6485, 0x28e5,
+ 0x6487, 0x0fdb,
+ 0x6488, 0x115e,
+ 0x6489, 0x2b54,
+ 0x648a, 0x28ea,
+ 0x648b, 0x28e9,
+ 0x648c, 0x28eb,
+ 0x648d, 0x4323,
+ 0x648f, 0x28e8,
+ 0x6490, 0x115f,
+ 0x6491, 0x43c3,
+ 0x6492, 0x1165,
+ 0x6493, 0x1162,
+ 0x6495, 0x1163,
+ 0x6496, 0x28e3,
+ 0x6497, 0x28e6,
+ 0x6498, 0x28f0,
+ 0x6499, 0x116b,
+ 0x649a, 0x1169,
+ 0x649c, 0x28e7,
+ 0x649d, 0x2154,
+ 0x649e, 0x115c,
+ 0x649f, 0x28ed,
+ 0x64a0, 0x28e4,
+ 0x64a2, 0x116c,
+ 0x64a3, 0x28ec,
+ 0x64a4, 0x0fde,
+ 0x64a5, 0x1161,
+ 0x64a6, 0x26a4,
+ 0x64a9, 0x1164,
+ 0x64ab, 0x1168,
+ 0x64ac, 0x116a,
+ 0x64ad, 0x1167,
+ 0x64ae, 0x1166,
+ 0x64af, 0x42e1,
+ 0x64b0, 0x1160,
+ 0x64b1, 0x28ef,
+ 0x64b2, 0x115d,
+ 0x64b3, 0x116d,
+ 0x64b4, 0x4340,
+ 0x64b6, 0x3a64,
+ 0x64bb, 0x12bb,
+ 0x64bd, 0x2b53,
+ 0x64be, 0x12c5,
+ 0x64bf, 0x12c2,
+ 0x64c0, 0x4645,
+ 0x64c1, 0x12b9,
+ 0x64c2, 0x12c0,
+ 0x64c3, 0x2b55,
+ 0x64c4, 0x12be,
+ 0x64c5, 0x12b8,
+ 0x64c7, 0x12bf,
+ 0x64c9, 0x2b52,
+ 0x64ca, 0x13d8,
+ 0x64cb, 0x12ba,
+ 0x64cd, 0x12c1,
+ 0x64ce, 0x13d7,
+ 0x64cf, 0x2b51,
+ 0x64d0, 0x2b50,
+ 0x64d2, 0x12c3,
+ 0x64d3, 0x3f03,
+ 0x64d4, 0x12c4,
+ 0x64d6, 0x2b4f,
+ 0x64d7, 0x2b4e,
+ 0x64d8, 0x13d9,
+ 0x64d9, 0x2b58,
+ 0x64da, 0x12bd,
+ 0x64db, 0x2b56,
+ 0x64dd, 0x431e,
+ 0x64e0, 0x13da,
+ 0x64e1, 0x4199,
+ 0x64e2, 0x13df,
+ 0x64e3, 0x2d6a,
+ 0x64e4, 0x2d6c,
+ 0x64e5, 0x419a,
+ 0x64e6, 0x13dc,
+ 0x64e7, 0x37a8,
+ 0x64e8, 0x2d6d,
+ 0x64e9, 0x2d69,
+ 0x64ea, 0x434a,
+ 0x64eb, 0x2d6b,
+ 0x64ec, 0x13dd,
+ 0x64ed, 0x13e0,
+ 0x64ef, 0x2d68,
+ 0x64f0, 0x13db,
+ 0x64f1, 0x13de,
+ 0x64f2, 0x14d3,
+ 0x64f3, 0x2b57,
+ 0x64f4, 0x14d2,
+ 0x64f7, 0x14d8,
+ 0x64f8, 0x2f2b,
+ 0x64fa, 0x14d6,
+ 0x64fc, 0x2f2e,
+ 0x64fd, 0x2f2a,
+ 0x64fe, 0x14d4,
+ 0x64ff, 0x2f28,
+ 0x6500, 0x1582,
+ 0x6501, 0x2f2c,
+ 0x6503, 0x2f2d,
+ 0x6504, 0x2f29,
+ 0x6506, 0x14d5,
+ 0x6507, 0x3090,
+ 0x6509, 0x3093,
+ 0x650a, 0x4536,
+ 0x650c, 0x3094,
+ 0x650d, 0x3092,
+ 0x650e, 0x3095,
+ 0x650f, 0x1583,
+ 0x6510, 0x3091,
+ 0x6511, 0x3aa9,
+ 0x6513, 0x31d7,
+ 0x6514, 0x1617,
+ 0x6515, 0x31d6,
+ 0x6516, 0x31d5,
+ 0x6517, 0x31d4,
+ 0x6518, 0x1616,
+ 0x6519, 0x1618,
+ 0x651b, 0x32d2,
+ 0x651c, 0x1673,
+ 0x651d, 0x1672,
+ 0x651e, 0x4187,
+ 0x651f, 0x3ec0,
+ 0x6520, 0x3382,
+ 0x6521, 0x3381,
+ 0x6522, 0x3384,
+ 0x6523, 0x16f9,
+ 0x6524, 0x16c5,
+ 0x6525, 0x341b,
+ 0x6526, 0x3383,
+ 0x6529, 0x341a,
+ 0x652a, 0x16fb,
+ 0x652b, 0x16fa,
+ 0x652c, 0x1721,
+ 0x652d, 0x3484,
+ 0x652e, 0x34ca,
+ 0x652f, 0x02d5,
+ 0x6530, 0x3e62,
+ 0x6532, 0x216c,
+ 0x6533, 0x2b59,
+ 0x6534, 0x022c,
+ 0x6535, 0x44ed,
+ 0x6536, 0x03d7,
+ 0x6537, 0x17f6,
+ 0x6538, 0x04b9,
+ 0x6539, 0x04b7,
+ 0x653b, 0x04b8,
+ 0x653d, 0x19a1,
+ 0x653e, 0x05f3,
+ 0x653f, 0x0741,
+ 0x6541, 0x1b01,
+ 0x6543, 0x1b02,
+ 0x6545, 0x0742,
+ 0x6546, 0x1cbf,
+ 0x6548, 0x08d6,
+ 0x654a, 0x1cbe,
+ 0x654d, 0x419f,
+ 0x654f, 0x0abd,
+ 0x6551, 0x0ab9,
+ 0x6553, 0x1f0c,
+ 0x6554, 0x0ac0,
+ 0x6555, 0x0abf,
+ 0x6556, 0x0ab8,
+ 0x6557, 0x0abb,
+ 0x6558, 0x0abe,
+ 0x6559, 0x0aba,
+ 0x655c, 0x2170,
+ 0x655d, 0x0ab7,
+ 0x655e, 0x0c70,
+ 0x655f, 0x41a5,
+ 0x6562, 0x0c72,
+ 0x6564, 0x216f,
+ 0x6565, 0x2172,
+ 0x6566, 0x0c71,
+ 0x6567, 0x216d,
+ 0x6568, 0x2171,
+ 0x656a, 0x216e,
+ 0x656b, 0x3a6c,
+ 0x656c, 0x0e2b,
+ 0x656d, 0x41a4,
+ 0x656f, 0x2409,
+ 0x6572, 0x0fe7,
+ 0x6573, 0x26b4,
+ 0x6574, 0x12c6,
+ 0x6575, 0x116e,
+ 0x6576, 0x28f1,
+ 0x6577, 0x116f,
+ 0x6579, 0x28f3,
+ 0x657a, 0x28f2,
+ 0x657b, 0x28f4,
+ 0x657c, 0x2b5b,
+ 0x657f, 0x2b5a,
+ 0x6580, 0x2d6f,
+ 0x6581, 0x2d6e,
+ 0x6582, 0x13e1,
+ 0x6584, 0x3096,
+ 0x6585, 0x41a3,
+ 0x6586, 0x4648,
+ 0x6587, 0x02d6,
+ 0x6588, 0x410b,
+ 0x6589, 0x4554,
+ 0x658c, 0x2173,
+ 0x6590, 0x0c75,
+ 0x6591, 0x0c74,
+ 0x6592, 0x240a,
+ 0x6594, 0x2f2f,
+ 0x6595, 0x1674,
+ 0x6596, 0x341c,
+ 0x6597, 0x02d7,
+ 0x6599, 0x08d8,
+ 0x659b, 0x0ac2,
+ 0x659c, 0x0ac1,
+ 0x659d, 0x2174,
+ 0x659f, 0x0e2c,
+ 0x65a0, 0x26b5,
+ 0x65a1, 0x0fe8,
+ 0x65a2, 0x2b5c,
+ 0x65a4, 0x02d8,
+ 0x65a5, 0x0346,
+ 0x65a7, 0x05f4,
+ 0x65a8, 0x19a2,
+ 0x65aa, 0x1b03,
+ 0x65ab, 0x0743,
+ 0x65ac, 0x0ac3,
+ 0x65ae, 0x2176,
+ 0x65af, 0x0c76,
+ 0x65b0, 0x0e2d,
+ 0x65b2, 0x28f5,
+ 0x65b5, 0x41a7,
+ 0x65b6, 0x2d70,
+ 0x65b7, 0x14d9,
+ 0x65b8, 0x34cb,
+ 0x65b9, 0x02d9,
+ 0x65bb, 0x19a3,
+ 0x65bc, 0x05f5,
+ 0x65bd, 0x0744,
+ 0x65be, 0x3e3b,
+ 0x65bf, 0x1b04,
+ 0x65c1, 0x08d9,
+ 0x65c2, 0x1cc3,
+ 0x65c3, 0x1cc1,
+ 0x65c5, 0x08da,
+ 0x65c6, 0x1cc0,
+ 0x65cb, 0x0ac5,
+ 0x65cd, 0x1f0d,
+ 0x65ce, 0x0ac7,
+ 0x65cf, 0x0ac4,
+ 0x65d0, 0x2177,
+ 0x65d1, 0x41aa,
+ 0x65d2, 0x2178,
+ 0x65d3, 0x240b,
+ 0x65d4, 0x3ba8,
+ 0x65d6, 0x0fea,
+ 0x65d7, 0x0fe9,
+ 0x65da, 0x2d71,
+ 0x65db, 0x2f30,
+ 0x65dd, 0x3098,
+ 0x65de, 0x3097,
+ 0x65df, 0x31d8,
+ 0x65e0, 0x022d,
+ 0x65e1, 0x1789,
+ 0x65e2, 0x0745,
+ 0x65e3, 0x41ae,
+ 0x65e5, 0x02da,
+ 0x65e6, 0x0347,
+ 0x65e8, 0x03d9,
+ 0x65e9, 0x03d8,
+ 0x65ec, 0x03da,
+ 0x65ee, 0x17f8,
+ 0x65ef, 0x17f7,
+ 0x65f0, 0x189e,
+ 0x65f1, 0x04ba,
+ 0x65f2, 0x18a1,
+ 0x65f3, 0x18a0,
+ 0x65f4, 0x189f,
+ 0x65f5, 0x18a2,
+ 0x65fa, 0x05f6,
+ 0x65fb, 0x19a9,
+ 0x65fc, 0x19a5,
+ 0x65fd, 0x19ae,
+ 0x65ff, 0x464a,
+ 0x6600, 0x05fd,
+ 0x6602, 0x05fb,
+ 0x6603, 0x19aa,
+ 0x6604, 0x19a6,
+ 0x6605, 0x19ad,
+ 0x6606, 0x05fa,
+ 0x6607, 0x0601,
+ 0x6608, 0x19a8,
+ 0x6609, 0x19a4,
+ 0x660a, 0x0600,
+ 0x660b, 0x19ab,
+ 0x660c, 0x05f9,
+ 0x660d, 0x19ac,
+ 0x660e, 0x05fc,
+ 0x660f, 0x05fe,
+ 0x6610, 0x19b0,
+ 0x6611, 0x19af,
+ 0x6612, 0x19a7,
+ 0x6613, 0x05f8,
+ 0x6614, 0x05f7,
+ 0x6615, 0x05ff,
+ 0x6618, 0x41b1,
+ 0x661c, 0x1b09,
+ 0x661d, 0x1b0f,
+ 0x661e, 0x3a93,
+ 0x661f, 0x074b,
+ 0x6620, 0x0748,
+ 0x6621, 0x1b06,
+ 0x6622, 0x1b0b,
+ 0x6623, 0x4295,
+ 0x6624, 0x074e,
+ 0x6625, 0x0746,
+ 0x6626, 0x1b0a,
+ 0x6627, 0x0749,
+ 0x6628, 0x074c,
+ 0x662b, 0x1b0d,
+ 0x662d, 0x0747,
+ 0x662e, 0x1b12,
+ 0x662f, 0x074a,
+ 0x6630, 0x3a8d,
+ 0x6631, 0x074d,
+ 0x6632, 0x1b07,
+ 0x6633, 0x1b0c,
+ 0x6634, 0x1b10,
+ 0x6635, 0x1b08,
+ 0x6636, 0x1b05,
+ 0x6639, 0x1b11,
+ 0x663a, 0x1b0e,
+ 0x6641, 0x08e2,
+ 0x6642, 0x08db,
+ 0x6643, 0x08de,
+ 0x6644, 0x41b4,
+ 0x6645, 0x08e1,
+ 0x6647, 0x1cc6,
+ 0x6648, 0x3d99,
+ 0x6649, 0x08dc,
+ 0x664a, 0x1cc4,
+ 0x664b, 0x41b7,
+ 0x664c, 0x08e0,
+ 0x664f, 0x08dd,
+ 0x6651, 0x1cc7,
+ 0x6652, 0x08df,
+ 0x6653, 0x464b,
+ 0x6657, 0x409b,
+ 0x6659, 0x1f11,
+ 0x665a, 0x0ac9,
+ 0x665b, 0x1f10,
+ 0x665c, 0x1f12,
+ 0x665d, 0x0ac8,
+ 0x665e, 0x0acd,
+ 0x665f, 0x1cc5,
+ 0x6661, 0x1f0f,
+ 0x6662, 0x1f13,
+ 0x6663, 0x3a90,
+ 0x6664, 0x0aca,
+ 0x6665, 0x1f0e,
+ 0x6666, 0x0acc,
+ 0x6667, 0x41b9,
+ 0x6668, 0x0acb,
+ 0x666a, 0x217f,
+ 0x666b, 0x3a8b,
+ 0x666c, 0x217a,
+ 0x666e, 0x0c77,
+ 0x666f, 0x0c7b,
+ 0x6670, 0x0c78,
+ 0x6671, 0x217d,
+ 0x6672, 0x2180,
+ 0x6673, 0x41bb,
+ 0x6674, 0x0c79,
+ 0x6676, 0x0c7a,
+ 0x6677, 0x0c7f,
+ 0x6678, 0x2414,
+ 0x6679, 0x217e,
+ 0x667a, 0x0c7d,
+ 0x667b, 0x217b,
+ 0x667c, 0x2179,
+ 0x667d, 0x469b,
+ 0x667e, 0x0c7e,
+ 0x6680, 0x217c,
+ 0x6684, 0x0e33,
+ 0x6685, 0x4162,
+ 0x6686, 0x240c,
+ 0x6687, 0x0e30,
+ 0x6689, 0x0e2f,
+ 0x668a, 0x2411,
+ 0x668b, 0x2410,
+ 0x668c, 0x240d,
+ 0x668d, 0x0e35,
+ 0x668e, 0x3a89,
+ 0x6690, 0x240f,
+ 0x6691, 0x0c7c,
+ 0x6692, 0x464d,
+ 0x6694, 0x2413,
+ 0x6695, 0x240e,
+ 0x6696, 0x0e32,
+ 0x6697, 0x0e2e,
+ 0x6698, 0x0e34,
+ 0x6699, 0x2412,
+ 0x669a, 0x3d3d,
+ 0x669d, 0x0fed,
+ 0x669f, 0x26b8,
+ 0x66a0, 0x26b7,
+ 0x66a1, 0x26b6,
+ 0x66a2, 0x0feb,
+ 0x66a4, 0x40ba,
+ 0x66a8, 0x0fec,
+ 0x66a9, 0x28f9,
+ 0x66aa, 0x28fc,
+ 0x66ab, 0x1172,
+ 0x66ad, 0x4948,
+ 0x66ae, 0x1171,
+ 0x66af, 0x28fd,
+ 0x66b0, 0x28f8,
+ 0x66b1, 0x1174,
+ 0x66b2, 0x28fa,
+ 0x66b3, 0x40b5,
+ 0x66b4, 0x1173,
+ 0x66b5, 0x28f7,
+ 0x66b6, 0x3e13,
+ 0x66b7, 0x28fb,
+ 0x66b8, 0x12cc,
+ 0x66b9, 0x12c9,
+ 0x66ba, 0x2b65,
+ 0x66bb, 0x2b64,
+ 0x66bd, 0x2b63,
+ 0x66be, 0x2b5e,
+ 0x66bf, 0x3d9a,
+ 0x66c0, 0x2b5f,
+ 0x66c4, 0x12ca,
+ 0x66c6, 0x12c7,
+ 0x66c7, 0x12cb,
+ 0x66c8, 0x2b5d,
+ 0x66c9, 0x12c8,
+ 0x66ca, 0x2b60,
+ 0x66cc, 0x2b66,
+ 0x66cd, 0x40b8,
+ 0x66ce, 0x3a77,
+ 0x66cf, 0x2b62,
+ 0x66d2, 0x2d72,
+ 0x66d6, 0x13e4,
+ 0x66d8, 0x2f33,
+ 0x66d9, 0x13e3,
+ 0x66da, 0x2f31,
+ 0x66dc, 0x14da,
+ 0x66dd, 0x1585,
+ 0x66de, 0x3099,
+ 0x66e0, 0x1584,
+ 0x66e3, 0x31da,
+ 0x66e6, 0x1619,
+ 0x66e8, 0x31d9,
+ 0x66e9, 0x1675,
+ 0x66eb, 0x341d,
+ 0x66ec, 0x16fc,
+ 0x66ed, 0x3485,
+ 0x66f0, 0x02db,
+ 0x66f1, 0x3e84,
+ 0x66f2, 0x03dc,
+ 0x66f4, 0x04bb,
+ 0x66f6, 0x19b1,
+ 0x66f7, 0x074f,
+ 0x66f8, 0x08e3,
+ 0x66f9, 0x0ace,
+ 0x66fc, 0x0a1f,
+ 0x66fe, 0x0c80,
+ 0x6700, 0x0bf0,
+ 0x6701, 0x2181,
+ 0x6702, 0x41c4,
+ 0x6703, 0x0e36,
+ 0x6704, 0x26ba,
+ 0x6705, 0x26b9,
+ 0x6708, 0x02dc,
+ 0x6709, 0x03de,
+ 0x670a, 0x19b2,
+ 0x670b, 0x0603,
+ 0x670c, 0x3fe2,
+ 0x670d, 0x0602,
+ 0x670e, 0x3da1,
+ 0x670f, 0x1b13,
+ 0x6712, 0x1cc8,
+ 0x6714, 0x08e4,
+ 0x6716, 0x464f,
+ 0x6717, 0x08e6,
+ 0x6718, 0x1f14,
+ 0x671b, 0x0ad0,
+ 0x671d, 0x0c83,
+ 0x671e, 0x3d8b,
+ 0x671f, 0x0c82,
+ 0x6720, 0x2415,
+ 0x6721, 0x2522,
+ 0x6722, 0x26bb,
+ 0x6723, 0x2b67,
+ 0x6725, 0x379f,
+ 0x6726, 0x14db,
+ 0x6727, 0x161a,
+ 0x6728, 0x02dd,
+ 0x672a, 0x034a,
+ 0x672c, 0x0349,
+ 0x672d, 0x034c,
+ 0x672e, 0x0348,
+ 0x6731, 0x03e1,
+ 0x6733, 0x1800,
+ 0x6734, 0x03e0,
+ 0x6735, 0x03e2,
+ 0x6736, 0x3e41,
+ 0x6738, 0x17fb,
+ 0x6739, 0x17fa,
+ 0x673a, 0x17fd,
+ 0x673b, 0x17fc,
+ 0x673c, 0x17ff,
+ 0x673d, 0x03df,
+ 0x673e, 0x17f9,
+ 0x673f, 0x17fe,
+ 0x6744, 0x401b,
+ 0x6745, 0x18a3,
+ 0x6746, 0x04c5,
+ 0x6747, 0x18a4,
+ 0x6748, 0x18a8,
+ 0x6749, 0x04c4,
+ 0x674b, 0x18ac,
+ 0x674c, 0x18a7,
+ 0x674d, 0x18aa,
+ 0x674e, 0x04bd,
+ 0x6753, 0x04c7,
+ 0x6755, 0x18a6,
+ 0x6756, 0x04c2,
+ 0x6757, 0x04c8,
+ 0x6759, 0x18a5,
+ 0x675a, 0x18ab,
+ 0x675c, 0x04c1,
+ 0x675d, 0x18a9,
+ 0x675e, 0x04c3,
+ 0x675f, 0x04bc,
+ 0x6760, 0x04c6,
+ 0x6761, 0x3d66,
+ 0x6762, 0x41cb,
+ 0x6767, 0x41ca,
+ 0x676a, 0x0618,
+ 0x676c, 0x19b4,
+ 0x676d, 0x0604,
+ 0x676f, 0x060e,
+ 0x6771, 0x0607,
+ 0x6772, 0x0619,
+ 0x6773, 0x0609,
+ 0x6774, 0x19bc,
+ 0x6775, 0x0614,
+ 0x6776, 0x19b7,
+ 0x6777, 0x060a,
+ 0x6778, 0x19c6,
+ 0x677a, 0x19bf,
+ 0x677b, 0x19b8,
+ 0x677c, 0x0617,
+ 0x677d, 0x19c4,
+ 0x677e, 0x0612,
+ 0x677f, 0x0610,
+ 0x6781, 0x19c5,
+ 0x6783, 0x19c3,
+ 0x6784, 0x19bb,
+ 0x6785, 0x19b3,
+ 0x6786, 0x19ba,
+ 0x6787, 0x060b,
+ 0x6789, 0x0611,
+ 0x678b, 0x0605,
+ 0x678c, 0x19be,
+ 0x678d, 0x19bd,
+ 0x678e, 0x19b5,
+ 0x678f, 0x46c1,
+ 0x6790, 0x0613,
+ 0x6791, 0x19c1,
+ 0x6792, 0x19b6,
+ 0x6793, 0x0616,
+ 0x6794, 0x19c8,
+ 0x6795, 0x0606,
+ 0x6797, 0x060d,
+ 0x6798, 0x19b9,
+ 0x6799, 0x19c2,
+ 0x679a, 0x0615,
+ 0x679c, 0x0608,
+ 0x679d, 0x060c,
+ 0x679f, 0x19c0,
+ 0x67a0, 0x3d7a,
+ 0x67a4, 0x4651,
+ 0x67ac, 0x41e3,
+ 0x67ae, 0x1b34,
+ 0x67af, 0x0757,
+ 0x67b0, 0x0764,
+ 0x67b1, 0x41f4,
+ 0x67b2, 0x1b2f,
+ 0x67b3, 0x1b25,
+ 0x67b4, 0x075d,
+ 0x67b5, 0x1b23,
+ 0x67b6, 0x0756,
+ 0x67b7, 0x1b1e,
+ 0x67b8, 0x0760,
+ 0x67b9, 0x1b2b,
+ 0x67ba, 0x1b18,
+ 0x67bb, 0x1b1a,
+ 0x67bf, 0x37fa,
+ 0x67c0, 0x1b1d,
+ 0x67c1, 0x1b15,
+ 0x67c2, 0x1b2a,
+ 0x67c3, 0x1b3a,
+ 0x67c4, 0x075b,
+ 0x67c5, 0x1b1f,
+ 0x67c6, 0x1b31,
+ 0x67c8, 0x1b17,
+ 0x67c9, 0x1b38,
+ 0x67cb, 0x1b3c,
+ 0x67cc, 0x1b33,
+ 0x67cd, 0x1b24,
+ 0x67ce, 0x1b2c,
+ 0x67cf, 0x0761,
+ 0x67d0, 0x0754,
+ 0x67d1, 0x075c,
+ 0x67d2, 0x0768,
+ 0x67d3, 0x0751,
+ 0x67d4, 0x0753,
+ 0x67d6, 0x3b58,
+ 0x67d7, 0x41ce,
+ 0x67d8, 0x1b1c,
+ 0x67d9, 0x0765,
+ 0x67da, 0x075e,
+ 0x67db, 0x1b36,
+ 0x67dc, 0x1b19,
+ 0x67dd, 0x0767,
+ 0x67de, 0x0762,
+ 0x67df, 0x1b22,
+ 0x67e2, 0x0766,
+ 0x67e3, 0x1b29,
+ 0x67e4, 0x1b21,
+ 0x67e5, 0x075f,
+ 0x67e6, 0x1b35,
+ 0x67e7, 0x1b2d,
+ 0x67e9, 0x0759,
+ 0x67ea, 0x1b3b,
+ 0x67eb, 0x1b20,
+ 0x67ec, 0x0755,
+ 0x67ed, 0x1b32,
+ 0x67ee, 0x1b28,
+ 0x67ef, 0x075a,
+ 0x67f0, 0x1b2e,
+ 0x67f1, 0x0752,
+ 0x67f2, 0x1b16,
+ 0x67f3, 0x0763,
+ 0x67f4, 0x08f5,
+ 0x67f5, 0x0758,
+ 0x67f6, 0x1b27,
+ 0x67f7, 0x1b26,
+ 0x67f8, 0x1b1b,
+ 0x67f9, 0x3996,
+ 0x67fa, 0x1b37,
+ 0x67fc, 0x1b30,
+ 0x67fe, 0x4555,
+ 0x67ff, 0x0750,
+ 0x6800, 0x43c7,
+ 0x6801, 0x41d3,
+ 0x6802, 0x3fc8,
+ 0x6803, 0x3d6a,
+ 0x6804, 0x4556,
+ 0x680d, 0x4281,
+ 0x6810, 0x399c,
+ 0x6812, 0x1cdd,
+ 0x6813, 0x08fc,
+ 0x6814, 0x1cde,
+ 0x6816, 0x1cd2,
+ 0x6817, 0x08f1,
+ 0x6818, 0x08fd,
+ 0x681a, 0x1ccb,
+ 0x681b, 0x4072,
+ 0x681c, 0x1cd4,
+ 0x681d, 0x1cdc,
+ 0x681e, 0x46c2,
+ 0x681f, 0x1cca,
+ 0x6820, 0x1ce5,
+ 0x6821, 0x08e7,
+ 0x6822, 0x41d0,
+ 0x6825, 0x1ce4,
+ 0x6826, 0x1cdf,
+ 0x6828, 0x1ce0,
+ 0x6829, 0x08ef,
+ 0x682a, 0x08fa,
+ 0x682b, 0x1cd6,
+ 0x682d, 0x1cd7,
+ 0x682e, 0x1ce1,
+ 0x682f, 0x1cd8,
+ 0x6831, 0x1cd3,
+ 0x6832, 0x1ccd,
+ 0x6834, 0x1cdb,
+ 0x6835, 0x1cd5,
+ 0x6836, 0x3e2e,
+ 0x6837, 0x421d,
+ 0x6838, 0x08e8,
+ 0x6839, 0x08ec,
+ 0x683a, 0x1ce3,
+ 0x683b, 0x1ccf,
+ 0x683c, 0x08f8,
+ 0x683d, 0x08f4,
+ 0x683e, 0x4147,
+ 0x6840, 0x08f7,
+ 0x6841, 0x08fe,
+ 0x6842, 0x08ed,
+ 0x6843, 0x08f9,
+ 0x6844, 0x1cda,
+ 0x6845, 0x08fb,
+ 0x6846, 0x08ea,
+ 0x6847, 0x3beb,
+ 0x6848, 0x08e9,
+ 0x6849, 0x1ccc,
+ 0x684a, 0x4653,
+ 0x684b, 0x1cd0,
+ 0x684c, 0x08f2,
+ 0x684d, 0x1ce2,
+ 0x684e, 0x1cd9,
+ 0x684f, 0x1cd1,
+ 0x6850, 0x08f6,
+ 0x6851, 0x08f3,
+ 0x6853, 0x08eb,
+ 0x6854, 0x08ee,
+ 0x6855, 0x3d90,
+ 0x6856, 0x3814,
+ 0x685d, 0x41d6,
+ 0x6865, 0x4557,
+ 0x686b, 0x1f29,
+ 0x686d, 0x1f19,
+ 0x686f, 0x1f1e,
+ 0x6871, 0x1f2d,
+ 0x6872, 0x1f2a,
+ 0x6874, 0x1f23,
+ 0x6875, 0x1f22,
+ 0x6876, 0x0ad7,
+ 0x6877, 0x1f26,
+ 0x6878, 0x1f35,
+ 0x6879, 0x1f15,
+ 0x687b, 0x1f36,
+ 0x687c, 0x1f28,
+ 0x687d, 0x1f3a,
+ 0x687e, 0x1f2e,
+ 0x687f, 0x0ad6,
+ 0x6880, 0x1f2c,
+ 0x6881, 0x0ad1,
+ 0x6882, 0x0ae6,
+ 0x6883, 0x0adc,
+ 0x6884, 0x4654,
+ 0x6885, 0x0ae0,
+ 0x6886, 0x0adf,
+ 0x6887, 0x1f16,
+ 0x6888, 0x46b7,
+ 0x6889, 0x1f33,
+ 0x688a, 0x1f39,
+ 0x688b, 0x1f31,
+ 0x688c, 0x1f38,
+ 0x688f, 0x1f25,
+ 0x6890, 0x1f17,
+ 0x6891, 0x1f37,
+ 0x6892, 0x1f27,
+ 0x6893, 0x0ad4,
+ 0x6894, 0x0ae1,
+ 0x6896, 0x1f30,
+ 0x6897, 0x0ada,
+ 0x6898, 0x3aaa,
+ 0x689b, 0x1f2f,
+ 0x689c, 0x1f18,
+ 0x689d, 0x0ae2,
+ 0x689f, 0x0ae4,
+ 0x68a0, 0x1f32,
+ 0x68a1, 0x0ae5,
+ 0x68a2, 0x0ad3,
+ 0x68a3, 0x1f1f,
+ 0x68a4, 0x1f34,
+ 0x68a6, 0x40e4,
+ 0x68a7, 0x0ad9,
+ 0x68a8, 0x0ae3,
+ 0x68a9, 0x1f21,
+ 0x68aa, 0x1f2b,
+ 0x68ab, 0x1f1c,
+ 0x68ac, 0x1f20,
+ 0x68ad, 0x0ade,
+ 0x68ae, 0x1f1b,
+ 0x68af, 0x0ad2,
+ 0x68b0, 0x0adb,
+ 0x68b1, 0x0ad8,
+ 0x68b2, 0x1f24,
+ 0x68b3, 0x08f0,
+ 0x68b4, 0x2198,
+ 0x68b5, 0x0ad5,
+ 0x68b6, 0x3a9e,
+ 0x68b9, 0x3d14,
+ 0x68bd, 0x427c,
+ 0x68c3, 0x41dc,
+ 0x68c4, 0x0add,
+ 0x68c5, 0x3c2e,
+ 0x68c6, 0x219b,
+ 0x68c7, 0x21b1,
+ 0x68c8, 0x21a6,
+ 0x68c9, 0x0c97,
+ 0x68ca, 0x42eb,
+ 0x68cb, 0x0c92,
+ 0x68cc, 0x2195,
+ 0x68cd, 0x0c93,
+ 0x68ce, 0x21a5,
+ 0x68d0, 0x219e,
+ 0x68d1, 0x21ab,
+ 0x68d2, 0x0c8f,
+ 0x68d3, 0x2183,
+ 0x68d4, 0x21ad,
+ 0x68d5, 0x0c85,
+ 0x68d6, 0x218b,
+ 0x68d7, 0x0c88,
+ 0x68d8, 0x0c87,
+ 0x68da, 0x0c98,
+ 0x68dc, 0x2185,
+ 0x68dd, 0x21a7,
+ 0x68df, 0x0c8a,
+ 0x68e0, 0x0c86,
+ 0x68e1, 0x2193,
+ 0x68e3, 0x0c91,
+ 0x68e4, 0x218e,
+ 0x68e6, 0x21a9,
+ 0x68e7, 0x0c8d,
+ 0x68e8, 0x21a1,
+ 0x68e9, 0x21ae,
+ 0x68ea, 0x2188,
+ 0x68eb, 0x218d,
+ 0x68ec, 0x2187,
+ 0x68ee, 0x0c8c,
+ 0x68ef, 0x219a,
+ 0x68f0, 0x242b,
+ 0x68f1, 0x2189,
+ 0x68f2, 0x0c90,
+ 0x68f3, 0x2192,
+ 0x68f4, 0x21aa,
+ 0x68f5, 0x0c8b,
+ 0x68f6, 0x218f,
+ 0x68f7, 0x218c,
+ 0x68f8, 0x219d,
+ 0x68f9, 0x0c8e,
+ 0x68fa, 0x0c84,
+ 0x68fb, 0x0c9a,
+ 0x68fc, 0x21a0,
+ 0x68fd, 0x219f,
+ 0x6900, 0x41df,
+ 0x6901, 0x41de,
+ 0x6902, 0x42fb,
+ 0x6903, 0x429c,
+ 0x6904, 0x2184,
+ 0x6905, 0x0c89,
+ 0x6906, 0x21ac,
+ 0x6907, 0x2194,
+ 0x6908, 0x2196,
+ 0x6909, 0x4658,
+ 0x690a, 0x21a3,
+ 0x690b, 0x21a2,
+ 0x690c, 0x2182,
+ 0x690d, 0x0c94,
+ 0x690e, 0x0c96,
+ 0x690f, 0x218a,
+ 0x6910, 0x2191,
+ 0x6911, 0x2199,
+ 0x6912, 0x0c95,
+ 0x6913, 0x2190,
+ 0x6914, 0x219c,
+ 0x6915, 0x21af,
+ 0x6917, 0x21a4,
+ 0x6918, 0x3da2,
+ 0x691a, 0x3d80,
+ 0x691b, 0x37bd,
+ 0x6925, 0x21b0,
+ 0x692a, 0x2186,
+ 0x692c, 0x3f38,
+ 0x692f, 0x243f,
+ 0x6930, 0x0e3e,
+ 0x6932, 0x243d,
+ 0x6933, 0x2428,
+ 0x6934, 0x242d,
+ 0x6935, 0x2426,
+ 0x6936, 0x41e7,
+ 0x6937, 0x2439,
+ 0x6938, 0x2418,
+ 0x6939, 0x241f,
+ 0x693b, 0x2437,
+ 0x693c, 0x2441,
+ 0x693d, 0x2429,
+ 0x693e, 0x4056,
+ 0x693f, 0x241c,
+ 0x6940, 0x242f,
+ 0x6941, 0x2434,
+ 0x6942, 0x2420,
+ 0x6943, 0x4659,
+ 0x6944, 0x2431,
+ 0x6945, 0x241d,
+ 0x6946, 0x456f,
+ 0x6948, 0x2424,
+ 0x694a, 0x0e40,
+ 0x694b, 0x2438,
+ 0x694c, 0x2436,
+ 0x694e, 0x2419,
+ 0x694f, 0x243b,
+ 0x6951, 0x243c,
+ 0x6952, 0x243e,
+ 0x6953, 0x0e44,
+ 0x6954, 0x0e3c,
+ 0x6955, 0x3d86,
+ 0x6956, 0x1f1d,
+ 0x6957, 0x2421,
+ 0x6958, 0x2433,
+ 0x6959, 0x2422,
+ 0x695a, 0x0e39,
+ 0x695b, 0x0e49,
+ 0x695c, 0x243a,
+ 0x695d, 0x0e47,
+ 0x695e, 0x0e43,
+ 0x695f, 0x2417,
+ 0x6960, 0x0e3b,
+ 0x6961, 0x41e4,
+ 0x6962, 0x241a,
+ 0x6963, 0x0e48,
+ 0x6964, 0x465b,
+ 0x6965, 0x242a,
+ 0x6966, 0x2416,
+ 0x6967, 0x3d15,
+ 0x6968, 0x0e41,
+ 0x6969, 0x242e,
+ 0x696a, 0x241e,
+ 0x696b, 0x0e42,
+ 0x696c, 0x2427,
+ 0x696d, 0x0e38,
+ 0x696e, 0x0c99,
+ 0x696f, 0x2430,
+ 0x6970, 0x2197,
+ 0x6971, 0x241b,
+ 0x6972, 0x3a6d,
+ 0x6973, 0x41db,
+ 0x6974, 0x2435,
+ 0x6975, 0x0e3d,
+ 0x6976, 0x2432,
+ 0x6977, 0x0e3a,
+ 0x6978, 0x242c,
+ 0x6979, 0x0e45,
+ 0x697a, 0x2423,
+ 0x697b, 0x2440,
+ 0x6980, 0x3f3e,
+ 0x6982, 0x0e3f,
+ 0x6983, 0x24af,
+ 0x6985, 0x465d,
+ 0x6986, 0x0e46,
+ 0x698a, 0x3d74,
+ 0x698d, 0x26c9,
+ 0x698e, 0x26c7,
+ 0x6990, 0x26dd,
+ 0x6991, 0x26c5,
+ 0x6993, 0x26d7,
+ 0x6994, 0x0e37,
+ 0x6995, 0x0ff0,
+ 0x6996, 0x26c1,
+ 0x6997, 0x26dc,
+ 0x6998, 0x41e8,
+ 0x6999, 0x26c6,
+ 0x699a, 0x26d4,
+ 0x699b, 0x0ff5,
+ 0x699c, 0x0fee,
+ 0x699e, 0x26da,
+ 0x699f, 0x465c,
+ 0x69a0, 0x26bf,
+ 0x69a1, 0x26d9,
+ 0x69a2, 0x3730,
+ 0x69a3, 0x1000,
+ 0x69a4, 0x26d0,
+ 0x69a5, 0x26e0,
+ 0x69a6, 0x0ffe,
+ 0x69a7, 0x26c8,
+ 0x69a8, 0x0fef,
+ 0x69a9, 0x26ca,
+ 0x69aa, 0x26d8,
+ 0x69ab, 0x0ff8,
+ 0x69ac, 0x26c3,
+ 0x69ad, 0x0ffc,
+ 0x69ae, 0x0ff2,
+ 0x69af, 0x26cc,
+ 0x69b0, 0x26c2,
+ 0x69b1, 0x26bc,
+ 0x69b2, 0x3ff6,
+ 0x69b3, 0x26d6,
+ 0x69b4, 0x0ff9,
+ 0x69b5, 0x26df,
+ 0x69b6, 0x26bd,
+ 0x69b7, 0x0ff6,
+ 0x69b9, 0x26d2,
+ 0x69bb, 0x0ff7,
+ 0x69bc, 0x26c4,
+ 0x69bd, 0x26cf,
+ 0x69be, 0x26cb,
+ 0x69bf, 0x26cd,
+ 0x69c0, 0x3f5d,
+ 0x69c1, 0x0ff1,
+ 0x69c2, 0x26de,
+ 0x69c3, 0x0fff,
+ 0x69c4, 0x26ce,
+ 0x69c6, 0x26e1,
+ 0x69c9, 0x26be,
+ 0x69ca, 0x26d3,
+ 0x69cb, 0x0ff4,
+ 0x69cc, 0x0ffd,
+ 0x69cd, 0x0ffb,
+ 0x69ce, 0x26c0,
+ 0x69cf, 0x26d5,
+ 0x69d0, 0x0ffa,
+ 0x69d1, 0x39ef,
+ 0x69d3, 0x0ff3,
+ 0x69d4, 0x26d1,
+ 0x69d5, 0x3e3c,
+ 0x69d6, 0x465e,
+ 0x69d9, 0x26db,
+ 0x69e1, 0x41d8,
+ 0x69e2, 0x2909,
+ 0x69e4, 0x2905,
+ 0x69e5, 0x2901,
+ 0x69e6, 0x2915,
+ 0x69e7, 0x2912,
+ 0x69e8, 0x1177,
+ 0x69e9, 0x3d91,
+ 0x69eb, 0x2919,
+ 0x69ec, 0x2908,
+ 0x69ed, 0x1182,
+ 0x69ee, 0x290f,
+ 0x69f1, 0x2904,
+ 0x69f2, 0x290e,
+ 0x69f3, 0x117f,
+ 0x69f4, 0x2922,
+ 0x69f6, 0x291f,
+ 0x69f7, 0x2911,
+ 0x69f8, 0x2902,
+ 0x69f9, 0x41ed,
+ 0x69fa, 0x41c7,
+ 0x69fb, 0x2916,
+ 0x69fc, 0x2918,
+ 0x69fd, 0x117b,
+ 0x69fe, 0x290c,
+ 0x69ff, 0x2907,
+ 0x6a00, 0x28fe,
+ 0x6a01, 0x1178,
+ 0x6a02, 0x1180,
+ 0x6a03, 0x3e29,
+ 0x6a04, 0x291b,
+ 0x6a05, 0x1181,
+ 0x6a06, 0x28ff,
+ 0x6a07, 0x2921,
+ 0x6a08, 0x2914,
+ 0x6a09, 0x291a,
+ 0x6a0a, 0x117e,
+ 0x6a0b, 0x41d9,
+ 0x6a0c, 0x3d50,
+ 0x6a0d, 0x2917,
+ 0x6a0f, 0x291e,
+ 0x6a11, 0x1183,
+ 0x6a13, 0x117d,
+ 0x6a14, 0x2910,
+ 0x6a15, 0x2903,
+ 0x6a16, 0x2923,
+ 0x6a17, 0x2900,
+ 0x6a18, 0x291c,
+ 0x6a19, 0x117a,
+ 0x6a1a, 0x3d1e,
+ 0x6a1b, 0x290a,
+ 0x6a1c, 0x3b68,
+ 0x6a1d, 0x290b,
+ 0x6a1e, 0x1179,
+ 0x6a1f, 0x1176,
+ 0x6a20, 0x2906,
+ 0x6a21, 0x117c,
+ 0x6a23, 0x1175,
+ 0x6a25, 0x291d,
+ 0x6a26, 0x2920,
+ 0x6a27, 0x290d,
+ 0x6a28, 0x2b74,
+ 0x6a2b, 0x3d42,
+ 0x6a2c, 0x42ab,
+ 0x6a2d, 0x3b1f,
+ 0x6a32, 0x2b6c,
+ 0x6a33, 0x3aa4,
+ 0x6a34, 0x2b68,
+ 0x6a35, 0x12d9,
+ 0x6a38, 0x12ce,
+ 0x6a39, 0x12d3,
+ 0x6a3a, 0x12cf,
+ 0x6a3b, 0x2b76,
+ 0x6a3c, 0x2b81,
+ 0x6a3d, 0x12cd,
+ 0x6a3e, 0x2b6e,
+ 0x6a3f, 0x2b77,
+ 0x6a40, 0x2913,
+ 0x6a41, 0x2b78,
+ 0x6a44, 0x12d4,
+ 0x6a45, 0x41f0,
+ 0x6a46, 0x2b87,
+ 0x6a47, 0x12d8,
+ 0x6a48, 0x12db,
+ 0x6a49, 0x2b6a,
+ 0x6a4b, 0x12d7,
+ 0x6a4c, 0x3aab,
+ 0x6a4d, 0x2b85,
+ 0x6a4f, 0x2b7c,
+ 0x6a50, 0x2b7b,
+ 0x6a51, 0x2b73,
+ 0x6a52, 0x3aa5,
+ 0x6a53, 0x37ac,
+ 0x6a54, 0x2b7d,
+ 0x6a55, 0x2b84,
+ 0x6a56, 0x2b83,
+ 0x6a57, 0x37da,
+ 0x6a58, 0x12d2,
+ 0x6a59, 0x12d0,
+ 0x6a5a, 0x2b75,
+ 0x6a5b, 0x2b72,
+ 0x6a5d, 0x2b6f,
+ 0x6a5e, 0x2b82,
+ 0x6a5f, 0x12da,
+ 0x6a60, 0x2b80,
+ 0x6a61, 0x12d6,
+ 0x6a62, 0x12d5,
+ 0x6a64, 0x2b7a,
+ 0x6a65, 0x4660,
+ 0x6a66, 0x2b69,
+ 0x6a67, 0x2b6b,
+ 0x6a68, 0x2b6d,
+ 0x6a69, 0x2b7f,
+ 0x6a6a, 0x2b79,
+ 0x6a6b, 0x12d1,
+ 0x6a6d, 0x2b70,
+ 0x6a6f, 0x2b7e,
+ 0x6a71, 0x4662,
+ 0x6a74, 0x4661,
+ 0x6a76, 0x2b71,
+ 0x6a7a, 0x3aad,
+ 0x6a7e, 0x13ec,
+ 0x6a7f, 0x2d84,
+ 0x6a80, 0x13e5,
+ 0x6a81, 0x2d75,
+ 0x6a82, 0x4663,
+ 0x6a83, 0x2d80,
+ 0x6a84, 0x13e7,
+ 0x6a85, 0x2d87,
+ 0x6a87, 0x2d7c,
+ 0x6a89, 0x2d77,
+ 0x6a8a, 0x4136,
+ 0x6a8c, 0x2d88,
+ 0x6a8d, 0x2d73,
+ 0x6a8e, 0x2d7e,
+ 0x6a8f, 0x3c1b,
+ 0x6a90, 0x13ee,
+ 0x6a91, 0x2d83,
+ 0x6a92, 0x2d89,
+ 0x6a93, 0x2d7d,
+ 0x6a94, 0x13e6,
+ 0x6a95, 0x2d7f,
+ 0x6a96, 0x2d74,
+ 0x6a97, 0x13ed,
+ 0x6a99, 0x4665,
+ 0x6a9a, 0x2d86,
+ 0x6a9b, 0x2d79,
+ 0x6a9c, 0x13e9,
+ 0x6a9d, 0x41f2,
+ 0x6a9e, 0x2d7b,
+ 0x6a9f, 0x2d78,
+ 0x6aa0, 0x13ef,
+ 0x6aa1, 0x2d7a,
+ 0x6aa2, 0x13e8,
+ 0x6aa3, 0x13eb,
+ 0x6aa4, 0x2d82,
+ 0x6aa5, 0x2d76,
+ 0x6aa6, 0x2d85,
+ 0x6aa7, 0x37e3,
+ 0x6aa8, 0x2d81,
+ 0x6aab, 0x4667,
+ 0x6aac, 0x14dd,
+ 0x6aad, 0x2f3e,
+ 0x6aae, 0x14e2,
+ 0x6ab1, 0x3e53,
+ 0x6ab2, 0x3b4b,
+ 0x6ab3, 0x14dc,
+ 0x6ab4, 0x2f3d,
+ 0x6ab5, 0x4668,
+ 0x6ab6, 0x2f3a,
+ 0x6ab8, 0x14e0,
+ 0x6ab9, 0x2f35,
+ 0x6aba, 0x2f39,
+ 0x6abb, 0x14df,
+ 0x6abd, 0x2f36,
+ 0x6abe, 0x3aa1,
+ 0x6ac2, 0x14e1,
+ 0x6ac3, 0x14de,
+ 0x6ac5, 0x2f34,
+ 0x6ac6, 0x2f38,
+ 0x6ac7, 0x2f3c,
+ 0x6ac8, 0x41f5,
+ 0x6ac9, 0x3aa6,
+ 0x6aca, 0x3f4c,
+ 0x6acb, 0x309f,
+ 0x6acc, 0x309c,
+ 0x6acd, 0x30a5,
+ 0x6acf, 0x30a4,
+ 0x6ad0, 0x30a2,
+ 0x6ad1, 0x309d,
+ 0x6ad3, 0x1589,
+ 0x6ad4, 0x4669,
+ 0x6ad8, 0x3caa,
+ 0x6ad9, 0x309e,
+ 0x6ada, 0x1588,
+ 0x6adb, 0x13ea,
+ 0x6adc, 0x30a1,
+ 0x6add, 0x1587,
+ 0x6ade, 0x30a6,
+ 0x6adf, 0x30a0,
+ 0x6ae0, 0x309b,
+ 0x6ae1, 0x2f37,
+ 0x6ae5, 0x1586,
+ 0x6ae7, 0x309a,
+ 0x6ae8, 0x31df,
+ 0x6aea, 0x31de,
+ 0x6aeb, 0x30a3,
+ 0x6aec, 0x161b,
+ 0x6aee, 0x31e2,
+ 0x6af0, 0x31dd,
+ 0x6af1, 0x31e1,
+ 0x6af3, 0x31dc,
+ 0x6af6, 0x466a,
+ 0x6af8, 0x32d6,
+ 0x6af9, 0x31e0,
+ 0x6afa, 0x1678,
+ 0x6afb, 0x1676,
+ 0x6afc, 0x32d4,
+ 0x6b00, 0x32d7,
+ 0x6b02, 0x32d3,
+ 0x6b03, 0x32d5,
+ 0x6b04, 0x1677,
+ 0x6b05, 0x3aa7,
+ 0x6b08, 0x3386,
+ 0x6b0a, 0x16c6,
+ 0x6b0b, 0x3385,
+ 0x6b0f, 0x3420,
+ 0x6b10, 0x16fd,
+ 0x6b11, 0x341e,
+ 0x6b13, 0x3487,
+ 0x6b16, 0x1743,
+ 0x6b17, 0x34ce,
+ 0x6b18, 0x34cc,
+ 0x6b1a, 0x34cf,
+ 0x6b1d, 0x41f8,
+ 0x6b1e, 0x3534,
+ 0x6b20, 0x02de,
+ 0x6b21, 0x03e3,
+ 0x6b23, 0x061a,
+ 0x6b25, 0x19c9,
+ 0x6b28, 0x1b3d,
+ 0x6b2c, 0x1ce6,
+ 0x6b2d, 0x1ce8,
+ 0x6b2f, 0x1ce7,
+ 0x6b31, 0x1ce9,
+ 0x6b32, 0x0ae7,
+ 0x6b33, 0x1f3c,
+ 0x6b34, 0x1cea,
+ 0x6b35, 0x41fb,
+ 0x6b36, 0x1f3b,
+ 0x6b37, 0x1f3d,
+ 0x6b39, 0x21b2,
+ 0x6b3a, 0x0c9c,
+ 0x6b3b, 0x21b3,
+ 0x6b3c, 0x21b5,
+ 0x6b3d, 0x0c9d,
+ 0x6b3e, 0x0c9b,
+ 0x6b3f, 0x21b4,
+ 0x6b41, 0x2447,
+ 0x6b42, 0x2445,
+ 0x6b43, 0x2444,
+ 0x6b45, 0x2443,
+ 0x6b46, 0x2442,
+ 0x6b47, 0x0e4a,
+ 0x6b48, 0x2446,
+ 0x6b49, 0x1001,
+ 0x6b4a, 0x26e2,
+ 0x6b4b, 0x26e4,
+ 0x6b4c, 0x1002,
+ 0x6b4d, 0x26e3,
+ 0x6b4e, 0x1185,
+ 0x6b50, 0x1184,
+ 0x6b51, 0x2924,
+ 0x6b52, 0x3f6e,
+ 0x6b54, 0x2b89,
+ 0x6b55, 0x2b88,
+ 0x6b56, 0x2b8a,
+ 0x6b57, 0x3aae,
+ 0x6b59, 0x12dc,
+ 0x6b5b, 0x2d8a,
+ 0x6b5c, 0x13f0,
+ 0x6b5e, 0x2f3f,
+ 0x6b5f, 0x14e4,
+ 0x6b60, 0x30a7,
+ 0x6b61, 0x16c7,
+ 0x6b62, 0x02df,
+ 0x6b63, 0x034d,
+ 0x6b64, 0x03e4,
+ 0x6b65, 0x04c9,
+ 0x6b66, 0x061b,
+ 0x6b6a, 0x0769,
+ 0x6b6d, 0x1ceb,
+ 0x6b6f, 0x4515,
+ 0x6b72, 0x0e4b,
+ 0x6b74, 0x41fc,
+ 0x6b76, 0x29a2,
+ 0x6b77, 0x12dd,
+ 0x6b78, 0x14e5,
+ 0x6b79, 0x02e0,
+ 0x6b7a, 0x44ee,
+ 0x6b7b, 0x03e5,
+ 0x6b7e, 0x19cb,
+ 0x6b7f, 0x061d,
+ 0x6b80, 0x19ca,
+ 0x6b81, 0x466b,
+ 0x6b82, 0x1b3e,
+ 0x6b83, 0x076a,
+ 0x6b84, 0x1b3f,
+ 0x6b86, 0x076b,
+ 0x6b88, 0x1ced,
+ 0x6b89, 0x0900,
+ 0x6b8a, 0x08ff,
+ 0x6b8c, 0x1f43,
+ 0x6b8d, 0x1f41,
+ 0x6b8f, 0x1f40,
+ 0x6b91, 0x1f3f,
+ 0x6b94, 0x21b6,
+ 0x6b95, 0x21b9,
+ 0x6b96, 0x0c9f,
+ 0x6b97, 0x21b7,
+ 0x6b98, 0x0c9e,
+ 0x6b99, 0x21b8,
+ 0x6b9b, 0x2448,
+ 0x6b9e, 0x26e5,
+ 0x6ba2, 0x2927,
+ 0x6ba3, 0x2926,
+ 0x6ba4, 0x1186,
+ 0x6ba5, 0x2925,
+ 0x6ba6, 0x2928,
+ 0x6ba7, 0x2b8b,
+ 0x6baa, 0x2b8c,
+ 0x6bad, 0x2d8b,
+ 0x6bae, 0x13f1,
+ 0x6baf, 0x14e6,
+ 0x6bb0, 0x30a8,
+ 0x6bb2, 0x1679,
+ 0x6bb3, 0x178a,
+ 0x6bb5, 0x076c,
+ 0x6bb6, 0x1b40,
+ 0x6bb7, 0x0901,
+ 0x6bba, 0x0ae8,
+ 0x6bbc, 0x0ca0,
+ 0x6bbd, 0x21ba,
+ 0x6bbf, 0x0e4d,
+ 0x6bc0, 0x0e4c,
+ 0x6bc1, 0x466c,
+ 0x6bc3, 0x26e8,
+ 0x6bc5, 0x1187,
+ 0x6bc7, 0x2b8f,
+ 0x6bc8, 0x2b8e,
+ 0x6bc9, 0x2f40,
+ 0x6bca, 0x3421,
+ 0x6bcb, 0x02e1,
+ 0x6bcc, 0x178b,
+ 0x6bcd, 0x034e,
+ 0x6bcf, 0x04ca,
+ 0x6bd0, 0x18ad,
+ 0x6bd2, 0x076d,
+ 0x6bd3, 0x0e4e,
+ 0x6bd4, 0x02e2,
+ 0x6bd6, 0x1b41,
+ 0x6bd7, 0x076e,
+ 0x6bd8, 0x1b42,
+ 0x6bda, 0x13f2,
+ 0x6bdb, 0x02e3,
+ 0x6bdc, 0x4207,
+ 0x6bde, 0x19cc,
+ 0x6be0, 0x1b43,
+ 0x6be1, 0x4205,
+ 0x6be2, 0x1cf2,
+ 0x6be3, 0x1cf1,
+ 0x6be4, 0x1cef,
+ 0x6be6, 0x1cee,
+ 0x6be7, 0x1cf3,
+ 0x6be8, 0x1cf0,
+ 0x6bea, 0x466d,
+ 0x6beb, 0x0ae9,
+ 0x6bef, 0x0ca1,
+ 0x6bf0, 0x21bb,
+ 0x6bf2, 0x21bc,
+ 0x6bf7, 0x244c,
+ 0x6bf9, 0x244b,
+ 0x6bfa, 0x3f79,
+ 0x6bfb, 0x2449,
+ 0x6bfd, 0x0e4f,
+ 0x6bfe, 0x26ea,
+ 0x6bff, 0x292b,
+ 0x6c00, 0x292a,
+ 0x6c01, 0x2929,
+ 0x6c02, 0x292c,
+ 0x6c03, 0x2b91,
+ 0x6c04, 0x2b90,
+ 0x6c05, 0x12de,
+ 0x6c06, 0x2b92,
+ 0x6c08, 0x13f3,
+ 0x6c09, 0x2d8c,
+ 0x6c0b, 0x2f41,
+ 0x6c0c, 0x30a9,
+ 0x6c0d, 0x3388,
+ 0x6c0f, 0x02e4,
+ 0x6c10, 0x0350,
+ 0x6c11, 0x034f,
+ 0x6c13, 0x061e,
+ 0x6c14, 0x178c,
+ 0x6c15, 0x17aa,
+ 0x6c16, 0x03e6,
+ 0x6c18, 0x1801,
+ 0x6c19, 0x18ae,
+ 0x6c1b, 0x061f,
+ 0x6c1c, 0x38ab,
+ 0x6c1d, 0x19cd,
+ 0x6c1f, 0x076f,
+ 0x6c20, 0x1b44,
+ 0x6c23, 0x0902,
+ 0x6c24, 0x0906,
+ 0x6c25, 0x1cf4,
+ 0x6c26, 0x0905,
+ 0x6c27, 0x0903,
+ 0x6c2a, 0x1f44,
+ 0x6c2b, 0x0aeb,
+ 0x6c2c, 0x0ca4,
+ 0x6c2e, 0x0ca2,
+ 0x6c30, 0x21be,
+ 0x6c31, 0x3f63,
+ 0x6c33, 0x1003,
+ 0x6c34, 0x02e5,
+ 0x6c35, 0x44ef,
+ 0x6c36, 0x17ab,
+ 0x6c37, 0x4208,
+ 0x6c38, 0x0351,
+ 0x6c39, 0x3e05,
+ 0x6c3a, 0x44f0,
+ 0x6c3b, 0x17ae,
+ 0x6c3d, 0x4381,
+ 0x6c3e, 0x0354,
+ 0x6c3f, 0x17ad,
+ 0x6c40, 0x0353,
+ 0x6c41, 0x0352,
+ 0x6c42, 0x04cb,
+ 0x6c43, 0x17ac,
+ 0x6c46, 0x1802,
+ 0x6c49, 0x408d,
+ 0x6c4a, 0x1806,
+ 0x6c4b, 0x1808,
+ 0x6c4d, 0x03f0,
+ 0x6c4f, 0x1805,
+ 0x6c50, 0x03ec,
+ 0x6c52, 0x1803,
+ 0x6c54, 0x1807,
+ 0x6c55, 0x03ed,
+ 0x6c57, 0x03e8,
+ 0x6c58, 0x3bba,
+ 0x6c59, 0x03e9,
+ 0x6c5a, 0x420c,
+ 0x6c5b, 0x03ef,
+ 0x6c5c, 0x1804,
+ 0x6c5d, 0x03e7,
+ 0x6c5e, 0x04cc,
+ 0x6c5f, 0x03ea,
+ 0x6c61, 0x03ee,
+ 0x6c65, 0x18c0,
+ 0x6c66, 0x18be,
+ 0x6c67, 0x18b1,
+ 0x6c68, 0x04d8,
+ 0x6c69, 0x18b8,
+ 0x6c6a, 0x04d3,
+ 0x6c6b, 0x18b2,
+ 0x6c6d, 0x18ba,
+ 0x6c6e, 0x40ca,
+ 0x6c6f, 0x18b7,
+ 0x6c70, 0x04d6,
+ 0x6c71, 0x18b6,
+ 0x6c72, 0x04dd,
+ 0x6c73, 0x18bf,
+ 0x6c74, 0x04df,
+ 0x6c75, 0x466e,
+ 0x6c76, 0x04e1,
+ 0x6c78, 0x18b0,
+ 0x6c79, 0x420e,
+ 0x6c7a, 0x04d4,
+ 0x6c7b, 0x18c1,
+ 0x6c7d, 0x04db,
+ 0x6c7e, 0x04de,
+ 0x6c7f, 0x37a6,
+ 0x6c80, 0x19e4,
+ 0x6c81, 0x04ce,
+ 0x6c82, 0x04e5,
+ 0x6c83, 0x04dc,
+ 0x6c84, 0x18b3,
+ 0x6c85, 0x04d1,
+ 0x6c86, 0x04e0,
+ 0x6c87, 0x18bb,
+ 0x6c88, 0x04cf,
+ 0x6c8a, 0x19e2,
+ 0x6c8b, 0x18b4,
+ 0x6c8c, 0x04d7,
+ 0x6c8d, 0x04e2,
+ 0x6c8e, 0x18c2,
+ 0x6c8f, 0x18b5,
+ 0x6c90, 0x04d5,
+ 0x6c92, 0x04da,
+ 0x6c93, 0x19ce,
+ 0x6c94, 0x04e3,
+ 0x6c95, 0x18bc,
+ 0x6c96, 0x04d9,
+ 0x6c98, 0x04e4,
+ 0x6c99, 0x04cd,
+ 0x6c9a, 0x18b9,
+ 0x6c9b, 0x04d2,
+ 0x6c9c, 0x18bd,
+ 0x6c9d, 0x19e3,
+ 0x6c9f, 0x3889,
+ 0x6ca2, 0x3d63,
+ 0x6caa, 0x466f,
+ 0x6cab, 0x062b,
+ 0x6cac, 0x063b,
+ 0x6cad, 0x19d5,
+ 0x6cae, 0x0632,
+ 0x6caf, 0x3cf6,
+ 0x6cb0, 0x19ea,
+ 0x6cb1, 0x0623,
+ 0x6cb2, 0x3ecc,
+ 0x6cb3, 0x0626,
+ 0x6cb4, 0x19e1,
+ 0x6cb6, 0x19d3,
+ 0x6cb7, 0x19d7,
+ 0x6cb8, 0x062e,
+ 0x6cb9, 0x0630,
+ 0x6cba, 0x19da,
+ 0x6cbb, 0x0637,
+ 0x6cbc, 0x0629,
+ 0x6cbd, 0x0627,
+ 0x6cbf, 0x0636,
+ 0x6cc0, 0x19e6,
+ 0x6cc1, 0x0631,
+ 0x6cc2, 0x19d9,
+ 0x6cc3, 0x19db,
+ 0x6cc4, 0x062f,
+ 0x6cc5, 0x0634,
+ 0x6cc6, 0x19dc,
+ 0x6cc7, 0x19e9,
+ 0x6cc9, 0x0770,
+ 0x6cca, 0x063a,
+ 0x6ccb, 0x4070,
+ 0x6ccc, 0x0624,
+ 0x6ccd, 0x19e8,
+ 0x6cce, 0x3f91,
+ 0x6ccf, 0x19ec,
+ 0x6cd0, 0x19d8,
+ 0x6cd1, 0x19ee,
+ 0x6cd2, 0x19df,
+ 0x6cd3, 0x062d,
+ 0x6cd4, 0x19d4,
+ 0x6cd5, 0x062c,
+ 0x6cd6, 0x063e,
+ 0x6cd7, 0x0633,
+ 0x6cd9, 0x19d2,
+ 0x6cda, 0x1b4e,
+ 0x6cdb, 0x0639,
+ 0x6cdc, 0x063d,
+ 0x6cdd, 0x19e0,
+ 0x6cde, 0x19e5,
+ 0x6cdf, 0x3d57,
+ 0x6ce0, 0x063f,
+ 0x6ce1, 0x0638,
+ 0x6ce2, 0x062a,
+ 0x6ce3, 0x0620,
+ 0x6ce5, 0x0625,
+ 0x6ce7, 0x19d6,
+ 0x6ce8, 0x0621,
+ 0x6ce9, 0x19ed,
+ 0x6cea, 0x3f8d,
+ 0x6ceb, 0x19d0,
+ 0x6cec, 0x19cf,
+ 0x6ced, 0x19dd,
+ 0x6cee, 0x19d1,
+ 0x6cef, 0x063c,
+ 0x6cf0, 0x0907,
+ 0x6cf1, 0x0635,
+ 0x6cf2, 0x19de,
+ 0x6cf3, 0x0622,
+ 0x6cf5, 0x077f,
+ 0x6cf9, 0x19eb,
+ 0x6d00, 0x1b55,
+ 0x6d01, 0x1b58,
+ 0x6d02, 0x4671,
+ 0x6d03, 0x1b5b,
+ 0x6d04, 0x1b50,
+ 0x6d05, 0x3a19,
+ 0x6d06, 0x4672,
+ 0x6d07, 0x1b5e,
+ 0x6d08, 0x1b61,
+ 0x6d09, 0x1b63,
+ 0x6d0a, 0x1b4d,
+ 0x6d0b, 0x0771,
+ 0x6d0c, 0x0776,
+ 0x6d0d, 0x1cf9,
+ 0x6d0e, 0x0786,
+ 0x6d0f, 0x1b5c,
+ 0x6d10, 0x1b64,
+ 0x6d11, 0x1b54,
+ 0x6d12, 0x1b4c,
+ 0x6d16, 0x1d14,
+ 0x6d17, 0x0779,
+ 0x6d18, 0x1b59,
+ 0x6d19, 0x1b51,
+ 0x6d1a, 0x1b53,
+ 0x6d1b, 0x077e,
+ 0x6d1d, 0x1b56,
+ 0x6d1e, 0x0778,
+ 0x6d1f, 0x1b49,
+ 0x6d20, 0x1b5f,
+ 0x6d22, 0x1b62,
+ 0x6d24, 0x3ac3,
+ 0x6d25, 0x0775,
+ 0x6d26, 0x4673,
+ 0x6d27, 0x0781,
+ 0x6d28, 0x1b46,
+ 0x6d29, 0x0783,
+ 0x6d2a, 0x0773,
+ 0x6d2b, 0x0787,
+ 0x6d2c, 0x1b60,
+ 0x6d2d, 0x1b48,
+ 0x6d2e, 0x0784,
+ 0x6d2f, 0x1d0e,
+ 0x6d30, 0x19e7,
+ 0x6d31, 0x0777,
+ 0x6d32, 0x0772,
+ 0x6d33, 0x1b4f,
+ 0x6d34, 0x1b47,
+ 0x6d35, 0x0785,
+ 0x6d36, 0x077d,
+ 0x6d37, 0x1b5a,
+ 0x6d38, 0x0782,
+ 0x6d39, 0x0780,
+ 0x6d3a, 0x1b52,
+ 0x6d3b, 0x077a,
+ 0x6d3c, 0x1b4a,
+ 0x6d3d, 0x077b,
+ 0x6d3f, 0x1b4b,
+ 0x6d40, 0x1b5d,
+ 0x6d41, 0x0774,
+ 0x6d42, 0x1b57,
+ 0x6d4e, 0x4558,
+ 0x6d57, 0x3cf3,
+ 0x6d58, 0x1cfc,
+ 0x6d59, 0x090f,
+ 0x6d5a, 0x0914,
+ 0x6d5b, 0x409c,
+ 0x6d5c, 0x4222,
+ 0x6d5e, 0x1d05,
+ 0x6d5f, 0x1d0b,
+ 0x6d60, 0x1d07,
+ 0x6d61, 0x1cfa,
+ 0x6d62, 0x1cfd,
+ 0x6d63, 0x1cf6,
+ 0x6d65, 0x091b,
+ 0x6d66, 0x090c,
+ 0x6d67, 0x1d06,
+ 0x6d68, 0x1d0f,
+ 0x6d69, 0x0916,
+ 0x6d6a, 0x0908,
+ 0x6d6c, 0x0911,
+ 0x6d6d, 0x1cfe,
+ 0x6d6e, 0x0913,
+ 0x6d6f, 0x1cff,
+ 0x6d70, 0x1d09,
+ 0x6d71, 0x40f5,
+ 0x6d72, 0x39d7,
+ 0x6d74, 0x0915,
+ 0x6d75, 0x1d18,
+ 0x6d76, 0x1cf8,
+ 0x6d77, 0x090e,
+ 0x6d78, 0x090d,
+ 0x6d79, 0x0919,
+ 0x6d7a, 0x1cf5,
+ 0x6d7b, 0x1d16,
+ 0x6d7c, 0x1d0a,
+ 0x6d7d, 0x1d17,
+ 0x6d7e, 0x1d11,
+ 0x6d7f, 0x1d03,
+ 0x6d80, 0x1d12,
+ 0x6d81, 0x4674,
+ 0x6d82, 0x1d0c,
+ 0x6d83, 0x1d15,
+ 0x6d84, 0x1d13,
+ 0x6d85, 0x091a,
+ 0x6d86, 0x1d04,
+ 0x6d87, 0x090b,
+ 0x6d88, 0x090a,
+ 0x6d89, 0x0912,
+ 0x6d8a, 0x0918,
+ 0x6d8b, 0x1d10,
+ 0x6d8c, 0x0917,
+ 0x6d8d, 0x1d01,
+ 0x6d8e, 0x0aec,
+ 0x6d8f, 0x3de8,
+ 0x6d90, 0x1d19,
+ 0x6d91, 0x1d00,
+ 0x6d92, 0x1cfb,
+ 0x6d93, 0x0910,
+ 0x6d94, 0x091c,
+ 0x6d95, 0x0909,
+ 0x6d96, 0x4221,
+ 0x6d97, 0x1d08,
+ 0x6d98, 0x1d0d,
+ 0x6da4, 0x4676,
+ 0x6da5, 0x3ab9,
+ 0x6daa, 0x0b0e,
+ 0x6dab, 0x1f46,
+ 0x6dac, 0x1f4a,
+ 0x6dae, 0x0afb,
+ 0x6daf, 0x0af9,
+ 0x6db1, 0x4677,
+ 0x6db2, 0x0af0,
+ 0x6db3, 0x1f48,
+ 0x6db4, 0x1f47,
+ 0x6db5, 0x0b04,
+ 0x6db7, 0x1f4d,
+ 0x6db8, 0x0afe,
+ 0x6db9, 0x3ffb,
+ 0x6dba, 0x1f5f,
+ 0x6dbb, 0x1f6b,
+ 0x6dbc, 0x0aed,
+ 0x6dbd, 0x1f5c,
+ 0x6dbe, 0x1f55,
+ 0x6dbf, 0x0b10,
+ 0x6dc0, 0x1f45,
+ 0x6dc2, 0x1f61,
+ 0x6dc4, 0x0b0d,
+ 0x6dc5, 0x0b01,
+ 0x6dc6, 0x0b0c,
+ 0x6dc7, 0x0af7,
+ 0x6dc8, 0x1f51,
+ 0x6dc9, 0x1f63,
+ 0x6dca, 0x1f5b,
+ 0x6dcb, 0x0af8,
+ 0x6dcc, 0x0af2,
+ 0x6dcd, 0x1f69,
+ 0x6dcf, 0x1f62,
+ 0x6dd0, 0x1f64,
+ 0x6dd1, 0x0afa,
+ 0x6dd2, 0x0b02,
+ 0x6dd3, 0x1f66,
+ 0x6dd4, 0x1f4f,
+ 0x6dd5, 0x1f60,
+ 0x6dd6, 0x1f54,
+ 0x6dd7, 0x1f68,
+ 0x6dd8, 0x0b07,
+ 0x6dd9, 0x0aef,
+ 0x6dda, 0x0b05,
+ 0x6ddb, 0x1f59,
+ 0x6ddc, 0x1f57,
+ 0x6dde, 0x0afc,
+ 0x6ddf, 0x1f53,
+ 0x6de0, 0x1f52,
+ 0x6de1, 0x0af1,
+ 0x6de2, 0x1f4c,
+ 0x6de3, 0x1f6a,
+ 0x6de4, 0x0af3,
+ 0x6de5, 0x1f56,
+ 0x6de6, 0x0b11,
+ 0x6de8, 0x0b0b,
+ 0x6de9, 0x1f4b,
+ 0x6dea, 0x0b08,
+ 0x6deb, 0x0b06,
+ 0x6dec, 0x0b0f,
+ 0x6ded, 0x1f5d,
+ 0x6dee, 0x0b0a,
+ 0x6def, 0x1d02,
+ 0x6df0, 0x1f5e,
+ 0x6df1, 0x0b09,
+ 0x6df2, 0x1f65,
+ 0x6df3, 0x0aee,
+ 0x6df4, 0x1f5a,
+ 0x6df5, 0x0b00,
+ 0x6df6, 0x1f4e,
+ 0x6df7, 0x0aff,
+ 0x6df9, 0x0afd,
+ 0x6dfa, 0x0af5,
+ 0x6dfb, 0x0af4,
+ 0x6dfc, 0x21bf,
+ 0x6dfd, 0x1f67,
+ 0x6e00, 0x1f50,
+ 0x6e02, 0x3cfa,
+ 0x6e03, 0x21d4,
+ 0x6e04, 0x3abe,
+ 0x6e05, 0x0af6,
+ 0x6e0a, 0x3ac1,
+ 0x6e0f, 0x3cf0,
+ 0x6e15, 0x4678,
+ 0x6e18, 0x4679,
+ 0x6e19, 0x0cc1,
+ 0x6e1a, 0x0b03,
+ 0x6e1b, 0x0caf,
+ 0x6e1c, 0x21ce,
+ 0x6e1d, 0x0cbd,
+ 0x6e1f, 0x21c2,
+ 0x6e20, 0x0cac,
+ 0x6e21, 0x0ca8,
+ 0x6e22, 0x21e0,
+ 0x6e23, 0x0cae,
+ 0x6e24, 0x0cb2,
+ 0x6e25, 0x0cad,
+ 0x6e26, 0x0cb6,
+ 0x6e27, 0x21e4,
+ 0x6e28, 0x21db,
+ 0x6e29, 0x467a,
+ 0x6e2a, 0x4302,
+ 0x6e2b, 0x21c9,
+ 0x6e2c, 0x0cbb,
+ 0x6e2d, 0x0cb5,
+ 0x6e2e, 0x21d5,
+ 0x6e2f, 0x0ca5,
+ 0x6e30, 0x21e1,
+ 0x6e31, 0x21da,
+ 0x6e32, 0x0ca9,
+ 0x6e33, 0x21cf,
+ 0x6e34, 0x0cb8,
+ 0x6e35, 0x21ec,
+ 0x6e38, 0x0ca6,
+ 0x6e39, 0x21df,
+ 0x6e3a, 0x0cba,
+ 0x6e3b, 0x21d3,
+ 0x6e3c, 0x21c5,
+ 0x6e3e, 0x0cbe,
+ 0x6e3f, 0x21ca,
+ 0x6e40, 0x21d1,
+ 0x6e41, 0x21cb,
+ 0x6e43, 0x0cbc,
+ 0x6e44, 0x0cc4,
+ 0x6e45, 0x21c7,
+ 0x6e46, 0x21c0,
+ 0x6e49, 0x21c3,
+ 0x6e4a, 0x0cab,
+ 0x6e4b, 0x21d0,
+ 0x6e4d, 0x0cb9,
+ 0x6e4e, 0x0cc2,
+ 0x6e4f, 0x4234,
+ 0x6e50, 0x41d1,
+ 0x6e51, 0x21d2,
+ 0x6e52, 0x21ea,
+ 0x6e53, 0x21e2,
+ 0x6e54, 0x0ca7,
+ 0x6e55, 0x21e8,
+ 0x6e56, 0x0cb3,
+ 0x6e58, 0x0cb1,
+ 0x6e59, 0x40e6,
+ 0x6e5a, 0x21ee,
+ 0x6e5b, 0x0cb0,
+ 0x6e5c, 0x21d8,
+ 0x6e5d, 0x21cc,
+ 0x6e5e, 0x21d6,
+ 0x6e5f, 0x0cc7,
+ 0x6e60, 0x21dc,
+ 0x6e61, 0x21d9,
+ 0x6e62, 0x21c8,
+ 0x6e63, 0x0cc3,
+ 0x6e64, 0x21e6,
+ 0x6e65, 0x21e3,
+ 0x6e66, 0x21eb,
+ 0x6e67, 0x0caa,
+ 0x6e68, 0x21d7,
+ 0x6e69, 0x0cc6,
+ 0x6e6b, 0x21de,
+ 0x6e6e, 0x0cb4,
+ 0x6e6f, 0x0cb7,
+ 0x6e71, 0x21dd,
+ 0x6e72, 0x0cc5,
+ 0x6e73, 0x21cd,
+ 0x6e74, 0x1f49,
+ 0x6e76, 0x39d3,
+ 0x6e77, 0x21e7,
+ 0x6e78, 0x21e5,
+ 0x6e79, 0x21e9,
+ 0x6e7c, 0x4223,
+ 0x6e86, 0x467b,
+ 0x6e88, 0x21c4,
+ 0x6e89, 0x0cc0,
+ 0x6e8b, 0x3bbf,
+ 0x6e8d, 0x246c,
+ 0x6e8e, 0x246b,
+ 0x6e8f, 0x2451,
+ 0x6e90, 0x0e55,
+ 0x6e92, 0x246a,
+ 0x6e93, 0x2454,
+ 0x6e96, 0x0e5f,
+ 0x6e97, 0x2473,
+ 0x6e98, 0x0e5a,
+ 0x6e99, 0x2469,
+ 0x6e9a, 0x4581,
+ 0x6e9b, 0x244e,
+ 0x6e9c, 0x0e60,
+ 0x6e9d, 0x0e56,
+ 0x6e9e, 0x245d,
+ 0x6e9f, 0x2453,
+ 0x6ea0, 0x2456,
+ 0x6ea1, 0x246e,
+ 0x6ea2, 0x0e50,
+ 0x6ea3, 0x2475,
+ 0x6ea4, 0x246d,
+ 0x6ea5, 0x0e59,
+ 0x6ea6, 0x2462,
+ 0x6ea7, 0x0e64,
+ 0x6eaa, 0x0e63,
+ 0x6eab, 0x0e5d,
+ 0x6eae, 0x2474,
+ 0x6eaf, 0x0e51,
+ 0x6eb0, 0x2460,
+ 0x6eb1, 0x2457,
+ 0x6eb2, 0x2464,
+ 0x6eb3, 0x2470,
+ 0x6eb4, 0x0e65,
+ 0x6eb5, 0x41fe,
+ 0x6eb6, 0x0e53,
+ 0x6eb7, 0x245f,
+ 0x6eb8, 0x3e0c,
+ 0x6eb9, 0x2458,
+ 0x6eba, 0x0e5c,
+ 0x6ebb, 0x467d,
+ 0x6ebc, 0x0e5b,
+ 0x6ebd, 0x245b,
+ 0x6ebe, 0x2465,
+ 0x6ebf, 0x246f,
+ 0x6ec0, 0x2452,
+ 0x6ec1, 0x245c,
+ 0x6ec2, 0x0e54,
+ 0x6ec3, 0x2466,
+ 0x6ec4, 0x0e61,
+ 0x6ec5, 0x0e58,
+ 0x6ec6, 0x2459,
+ 0x6ec7, 0x0e57,
+ 0x6ec8, 0x2450,
+ 0x6ec9, 0x245e,
+ 0x6eca, 0x2472,
+ 0x6ecb, 0x0cbf,
+ 0x6ecc, 0x101f,
+ 0x6ecd, 0x2461,
+ 0x6ece, 0x26eb,
+ 0x6ecf, 0x2463,
+ 0x6ed0, 0x2471,
+ 0x6ed1, 0x0e5e,
+ 0x6ed2, 0x245a,
+ 0x6ed3, 0x0e52,
+ 0x6ed4, 0x0e62,
+ 0x6ed5, 0x119a,
+ 0x6ed6, 0x244f,
+ 0x6ed8, 0x2468,
+ 0x6ed9, 0x4069,
+ 0x6eda, 0x467f,
+ 0x6edb, 0x402f,
+ 0x6edc, 0x2467,
+ 0x6edd, 0x4538,
+ 0x6ee2, 0x467e,
+ 0x6ee8, 0x4681,
+ 0x6eeb, 0x2707,
+ 0x6eec, 0x101c,
+ 0x6eed, 0x26fc,
+ 0x6eee, 0x2701,
+ 0x6eef, 0x1011,
+ 0x6ef1, 0x26ed,
+ 0x6ef2, 0x101e,
+ 0x6ef4, 0x1008,
+ 0x6ef5, 0x26ec,
+ 0x6ef6, 0x270d,
+ 0x6ef7, 0x1020,
+ 0x6ef8, 0x26f0,
+ 0x6ef9, 0x2700,
+ 0x6efa, 0x423b,
+ 0x6efb, 0x26f2,
+ 0x6efc, 0x2710,
+ 0x6efd, 0x270c,
+ 0x6efe, 0x1006,
+ 0x6eff, 0x1010,
+ 0x6f00, 0x2946,
+ 0x6f01, 0x101d,
+ 0x6f02, 0x100e,
+ 0x6f03, 0x26ee,
+ 0x6f04, 0x4224,
+ 0x6f05, 0x270b,
+ 0x6f06, 0x1012,
+ 0x6f07, 0x2708,
+ 0x6f08, 0x2715,
+ 0x6f09, 0x26f4,
+ 0x6f0a, 0x26fd,
+ 0x6f0b, 0x3aba,
+ 0x6f0c, 0x3cfb,
+ 0x6f0d, 0x2713,
+ 0x6f0e, 0x2709,
+ 0x6f0f, 0x100d,
+ 0x6f12, 0x26fb,
+ 0x6f13, 0x1007,
+ 0x6f14, 0x1005,
+ 0x6f15, 0x1017,
+ 0x6f16, 0x41a0,
+ 0x6f17, 0x46ce,
+ 0x6f18, 0x26f9,
+ 0x6f19, 0x26f6,
+ 0x6f1c, 0x270f,
+ 0x6f1e, 0x2714,
+ 0x6f1f, 0x2712,
+ 0x6f20, 0x100b,
+ 0x6f21, 0x2716,
+ 0x6f22, 0x100f,
+ 0x6f23, 0x1016,
+ 0x6f24, 0x4683,
+ 0x6f25, 0x26ef,
+ 0x6f26, 0x292e,
+ 0x6f27, 0x26f8,
+ 0x6f29, 0x1009,
+ 0x6f2a, 0x101b,
+ 0x6f2b, 0x1018,
+ 0x6f2c, 0x100c,
+ 0x6f2d, 0x2702,
+ 0x6f2e, 0x26f3,
+ 0x6f2f, 0x1019,
+ 0x6f30, 0x2704,
+ 0x6f31, 0x1013,
+ 0x6f32, 0x1015,
+ 0x6f33, 0x1004,
+ 0x6f34, 0x4684,
+ 0x6f35, 0x2706,
+ 0x6f36, 0x26fe,
+ 0x6f37, 0x26f1,
+ 0x6f38, 0x1014,
+ 0x6f39, 0x270e,
+ 0x6f3a, 0x2711,
+ 0x6f3b, 0x26fa,
+ 0x6f3c, 0x2705,
+ 0x6f3d, 0x4282,
+ 0x6f3e, 0x100a,
+ 0x6f3f, 0x1189,
+ 0x6f40, 0x2703,
+ 0x6f41, 0x292d,
+ 0x6f43, 0x270a,
+ 0x6f44, 0x4240,
+ 0x6f4e, 0x26f5,
+ 0x6f4f, 0x2937,
+ 0x6f50, 0x2941,
+ 0x6f51, 0x118c,
+ 0x6f52, 0x2940,
+ 0x6f53, 0x294c,
+ 0x6f54, 0x118e,
+ 0x6f55, 0x293e,
+ 0x6f56, 0x3e52,
+ 0x6f57, 0x2942,
+ 0x6f58, 0x1199,
+ 0x6f5a, 0x2939,
+ 0x6f5b, 0x1191,
+ 0x6f5c, 0x4241,
+ 0x6f5d, 0x2945,
+ 0x6f5e, 0x2b9a,
+ 0x6f5f, 0x119d,
+ 0x6f60, 0x119c,
+ 0x6f61, 0x2947,
+ 0x6f62, 0x2936,
+ 0x6f63, 0x2951,
+ 0x6f64, 0x1197,
+ 0x6f66, 0x118d,
+ 0x6f67, 0x294a,
+ 0x6f69, 0x294e,
+ 0x6f6a, 0x2953,
+ 0x6f6b, 0x2948,
+ 0x6f6c, 0x293c,
+ 0x6f6d, 0x1190,
+ 0x6f6e, 0x1193,
+ 0x6f6f, 0x119b,
+ 0x6f70, 0x1196,
+ 0x6f72, 0x293f,
+ 0x6f73, 0x26ff,
+ 0x6f74, 0x4243,
+ 0x6f76, 0x293b,
+ 0x6f77, 0x2952,
+ 0x6f78, 0x1192,
+ 0x6f79, 0x3bbe,
+ 0x6f7a, 0x1195,
+ 0x6f7b, 0x2954,
+ 0x6f7c, 0x118a,
+ 0x6f7d, 0x2949,
+ 0x6f7e, 0x292f,
+ 0x6f7f, 0x294f,
+ 0x6f80, 0x13fc,
+ 0x6f81, 0x4687,
+ 0x6f82, 0x293d,
+ 0x6f84, 0x118b,
+ 0x6f85, 0x2938,
+ 0x6f86, 0x118f,
+ 0x6f87, 0x2930,
+ 0x6f88, 0x101a,
+ 0x6f89, 0x2934,
+ 0x6f8a, 0x4195,
+ 0x6f8b, 0x294d,
+ 0x6f8c, 0x2935,
+ 0x6f8d, 0x2933,
+ 0x6f8e, 0x1194,
+ 0x6f90, 0x294b,
+ 0x6f92, 0x2932,
+ 0x6f93, 0x2944,
+ 0x6f94, 0x2943,
+ 0x6f95, 0x2950,
+ 0x6f96, 0x293a,
+ 0x6f97, 0x1198,
+ 0x6f9d, 0x4239,
+ 0x6f9e, 0x2b9d,
+ 0x6f9f, 0x4246,
+ 0x6fa0, 0x12eb,
+ 0x6fa1, 0x12e1,
+ 0x6fa2, 0x2ba9,
+ 0x6fa3, 0x2b95,
+ 0x6fa4, 0x12e3,
+ 0x6fa5, 0x2ba1,
+ 0x6fa6, 0x12ea,
+ 0x6fa7, 0x12e5,
+ 0x6fa8, 0x2b9f,
+ 0x6fa9, 0x2d8e,
+ 0x6faa, 0x2ba5,
+ 0x6fab, 0x2bab,
+ 0x6fac, 0x2ba4,
+ 0x6fad, 0x2b93,
+ 0x6fae, 0x2ba2,
+ 0x6faf, 0x2bad,
+ 0x6fb0, 0x2baf,
+ 0x6fb1, 0x12e0,
+ 0x6fb2, 0x2bae,
+ 0x6fb3, 0x12e6,
+ 0x6fb4, 0x12ec,
+ 0x6fb5, 0x3e27,
+ 0x6fb6, 0x12e9,
+ 0x6fb8, 0x2ba8,
+ 0x6fb9, 0x12e8,
+ 0x6fba, 0x2ba3,
+ 0x6fbb, 0x3bbb,
+ 0x6fbc, 0x2b97,
+ 0x6fbd, 0x2b9c,
+ 0x6fbe, 0x4688,
+ 0x6fbf, 0x2ba7,
+ 0x6fc0, 0x12e7,
+ 0x6fc1, 0x12e4,
+ 0x6fc2, 0x12df,
+ 0x6fc3, 0x12e2,
+ 0x6fc4, 0x2b9b,
+ 0x6fc6, 0x2931,
+ 0x6fc7, 0x2b96,
+ 0x6fc8, 0x2b99,
+ 0x6fc9, 0x2baa,
+ 0x6fca, 0x2b9e,
+ 0x6fcb, 0x2b94,
+ 0x6fcc, 0x2d8d,
+ 0x6fcd, 0x2bac,
+ 0x6fce, 0x2b98,
+ 0x6fcf, 0x2ba6,
+ 0x6fd3, 0x4248,
+ 0x6fd4, 0x2d90,
+ 0x6fd5, 0x1400,
+ 0x6fd8, 0x13f4,
+ 0x6fd9, 0x3c74,
+ 0x6fda, 0x3c73,
+ 0x6fdb, 0x13f8,
+ 0x6fdc, 0x2d92,
+ 0x6fdd, 0x2d98,
+ 0x6fde, 0x2d96,
+ 0x6fdf, 0x13f6,
+ 0x6fe1, 0x13fe,
+ 0x6fe2, 0x2d99,
+ 0x6fe3, 0x2d91,
+ 0x6fe4, 0x13f9,
+ 0x6fe6, 0x2d95,
+ 0x6fe7, 0x2d94,
+ 0x6fe8, 0x2d9a,
+ 0x6fe9, 0x13ff,
+ 0x6feb, 0x13fa,
+ 0x6fec, 0x13fd,
+ 0x6fed, 0x2d93,
+ 0x6fee, 0x1401,
+ 0x6fef, 0x13fb,
+ 0x6ff0, 0x1402,
+ 0x6ff1, 0x13f5,
+ 0x6ff2, 0x2d97,
+ 0x6ff4, 0x2d8f,
+ 0x6ff6, 0x38a5,
+ 0x6ff7, 0x2f4e,
+ 0x6ff8, 0x4237,
+ 0x6ffa, 0x14eb,
+ 0x6ffb, 0x2f4b,
+ 0x6ffc, 0x2f4d,
+ 0x6ffe, 0x14e9,
+ 0x6fff, 0x2f49,
+ 0x7000, 0x2f4a,
+ 0x7001, 0x2f45,
+ 0x7003, 0x46e2,
+ 0x7004, 0x2ba0,
+ 0x7005, 0x2f46,
+ 0x7006, 0x14ea,
+ 0x7007, 0x2f42,
+ 0x7009, 0x14e7,
+ 0x700a, 0x2f4f,
+ 0x700b, 0x14e8,
+ 0x700c, 0x2f43,
+ 0x700e, 0x2f48,
+ 0x700f, 0x14ed,
+ 0x7011, 0x14ec,
+ 0x7014, 0x2f47,
+ 0x7015, 0x158f,
+ 0x7016, 0x30ad,
+ 0x7017, 0x30b3,
+ 0x7018, 0x1590,
+ 0x7019, 0x30aa,
+ 0x701a, 0x158d,
+ 0x701b, 0x158a,
+ 0x701c, 0x30b5,
+ 0x701d, 0x158e,
+ 0x701e, 0x3c76,
+ 0x701f, 0x158b,
+ 0x7020, 0x30ac,
+ 0x7021, 0x30af,
+ 0x7024, 0x30b4,
+ 0x7026, 0x2f4c,
+ 0x7027, 0x30ab,
+ 0x7028, 0x158c,
+ 0x7029, 0x30b2,
+ 0x702a, 0x31ef,
+ 0x702b, 0x30ae,
+ 0x702c, 0x468e,
+ 0x702f, 0x31e6,
+ 0x7030, 0x161d,
+ 0x7031, 0x31e9,
+ 0x7032, 0x161e,
+ 0x7033, 0x31f2,
+ 0x7034, 0x31e8,
+ 0x7035, 0x31e5,
+ 0x7037, 0x31e7,
+ 0x7038, 0x31eb,
+ 0x7039, 0x31ee,
+ 0x703a, 0x31ed,
+ 0x703b, 0x31f1,
+ 0x703c, 0x31e4,
+ 0x703e, 0x161c,
+ 0x703f, 0x31ec,
+ 0x7040, 0x31f0,
+ 0x7041, 0x31f3,
+ 0x7042, 0x31ea,
+ 0x7043, 0x32d8,
+ 0x7045, 0x32dd,
+ 0x7048, 0x32db,
+ 0x704a, 0x32da,
+ 0x704b, 0x4254,
+ 0x704c, 0x167a,
+ 0x7050, 0x4690,
+ 0x7051, 0x16c8,
+ 0x7052, 0x338c,
+ 0x7054, 0x4691,
+ 0x7055, 0x3389,
+ 0x7058, 0x16c9,
+ 0x705a, 0x3423,
+ 0x705b, 0x3422,
+ 0x705c, 0x3852,
+ 0x705d, 0x348a,
+ 0x705e, 0x1722,
+ 0x705f, 0x3488,
+ 0x7060, 0x348b,
+ 0x7061, 0x3489,
+ 0x7062, 0x34d0,
+ 0x7063, 0x1744,
+ 0x7064, 0x1752,
+ 0x7065, 0x351c,
+ 0x7066, 0x3506,
+ 0x7067, 0x3cf5,
+ 0x7068, 0x351b,
+ 0x7069, 0x3547,
+ 0x706b, 0x02e6,
+ 0x706c, 0x44f1,
+ 0x706f, 0x4692,
+ 0x7070, 0x03f2,
+ 0x7071, 0x180a,
+ 0x7074, 0x18c3,
+ 0x7075, 0x38c7,
+ 0x7076, 0x04e6,
+ 0x7078, 0x04e9,
+ 0x7079, 0x4099,
+ 0x707a, 0x18c4,
+ 0x707c, 0x04e7,
+ 0x707e, 0x4255,
+ 0x707f, 0x4693,
+ 0x7081, 0x4959,
+ 0x7082, 0x19f7,
+ 0x7083, 0x19f9,
+ 0x7084, 0x19f4,
+ 0x7085, 0x19f1,
+ 0x7086, 0x19f3,
+ 0x7089, 0x43f9,
+ 0x708a, 0x0643,
+ 0x708b, 0x40cb,
+ 0x708e, 0x0641,
+ 0x708f, 0x46b3,
+ 0x7091, 0x19f5,
+ 0x7092, 0x0642,
+ 0x7093, 0x19f2,
+ 0x7094, 0x19ef,
+ 0x7095, 0x0640,
+ 0x7096, 0x19f6,
+ 0x7098, 0x19f0,
+ 0x7099, 0x0644,
+ 0x709a, 0x19f8,
+ 0x709f, 0x1b66,
+ 0x70a0, 0x4742,
+ 0x70a1, 0x1b6a,
+ 0x70a3, 0x3972,
+ 0x70a4, 0x0790,
+ 0x70a5, 0x3cb7,
+ 0x70a6, 0x3d53,
+ 0x70a7, 0x4256,
+ 0x70a9, 0x1b6d,
+ 0x70ab, 0x0788,
+ 0x70ac, 0x078b,
+ 0x70ad, 0x078d,
+ 0x70ae, 0x078f,
+ 0x70af, 0x078c,
+ 0x70b0, 0x1b69,
+ 0x70b1, 0x1b68,
+ 0x70b3, 0x078a,
+ 0x70b4, 0x1b6b,
+ 0x70b7, 0x1b65,
+ 0x70b8, 0x078e,
+ 0x70b9, 0x3d69,
+ 0x70ba, 0x0789,
+ 0x70bb, 0x4812,
+ 0x70bc, 0x4559,
+ 0x70bd, 0x4270,
+ 0x70be, 0x1b67,
+ 0x70c0, 0x4733,
+ 0x70c4, 0x3baa,
+ 0x70c5, 0x1d27,
+ 0x70c8, 0x0921,
+ 0x70ca, 0x091d,
+ 0x70cb, 0x1d1e,
+ 0x70cc, 0x4258,
+ 0x70cd, 0x1d26,
+ 0x70ce, 0x1d2b,
+ 0x70cf, 0x0922,
+ 0x70d0, 0x396d,
+ 0x70d1, 0x1d1c,
+ 0x70d2, 0x1d22,
+ 0x70d3, 0x1d1b,
+ 0x70d4, 0x1d25,
+ 0x70d5, 0x4259,
+ 0x70d7, 0x1d21,
+ 0x70d8, 0x091e,
+ 0x70d9, 0x0920,
+ 0x70da, 0x1d2a,
+ 0x70dc, 0x1d1a,
+ 0x70dd, 0x1d1d,
+ 0x70de, 0x1d23,
+ 0x70df, 0x425b,
+ 0x70e0, 0x1d24,
+ 0x70e1, 0x1d2c,
+ 0x70e2, 0x1d20,
+ 0x70e4, 0x091f,
+ 0x70ef, 0x0b16,
+ 0x70f0, 0x1f72,
+ 0x70f1, 0x3ac8,
+ 0x70f3, 0x1f74,
+ 0x70f4, 0x1f70,
+ 0x70f5, 0x4760,
+ 0x70f6, 0x1f7c,
+ 0x70f7, 0x1f6e,
+ 0x70f8, 0x1f7b,
+ 0x70f9, 0x0b12,
+ 0x70fa, 0x1f6c,
+ 0x70fb, 0x21f2,
+ 0x70fc, 0x1f76,
+ 0x70fd, 0x0b15,
+ 0x70fe, 0x3d0e,
+ 0x70ff, 0x1f77,
+ 0x7100, 0x1f7a,
+ 0x7102, 0x1f7e,
+ 0x7104, 0x1f73,
+ 0x7105, 0x3a23,
+ 0x7106, 0x1f78,
+ 0x7109, 0x0b13,
+ 0x710b, 0x1f7d,
+ 0x710c, 0x1f71,
+ 0x710d, 0x1f6d,
+ 0x710e, 0x1f7f,
+ 0x7110, 0x1f75,
+ 0x7113, 0x1f79,
+ 0x7117, 0x1f6f,
+ 0x7119, 0x0cc8,
+ 0x711b, 0x21fc,
+ 0x711c, 0x0ccf,
+ 0x711d, 0x3d47,
+ 0x711e, 0x21f0,
+ 0x711f, 0x21f9,
+ 0x7120, 0x21ef,
+ 0x7121, 0x0ccc,
+ 0x7122, 0x21f7,
+ 0x7123, 0x21f5,
+ 0x7125, 0x21f6,
+ 0x7126, 0x0cca,
+ 0x7128, 0x21fa,
+ 0x7129, 0x3ba9,
+ 0x712b, 0x4261,
+ 0x712c, 0x426a,
+ 0x712e, 0x21f3,
+ 0x712f, 0x21f1,
+ 0x7130, 0x0ccb,
+ 0x7131, 0x21f4,
+ 0x7132, 0x21f8,
+ 0x7133, 0x3d54,
+ 0x7134, 0x3c7e,
+ 0x7135, 0x376d,
+ 0x7136, 0x0ccd,
+ 0x713a, 0x21fb,
+ 0x713b, 0x3ac5,
+ 0x713e, 0x372e,
+ 0x7140, 0x4398,
+ 0x7141, 0x247b,
+ 0x7142, 0x2482,
+ 0x7143, 0x2484,
+ 0x7144, 0x248a,
+ 0x7145, 0x4262,
+ 0x7146, 0x0e72,
+ 0x7147, 0x2476,
+ 0x7149, 0x0e6a,
+ 0x714a, 0x4264,
+ 0x714b, 0x2485,
+ 0x714c, 0x0e6f,
+ 0x714d, 0x248b,
+ 0x714e, 0x0e66,
+ 0x714f, 0x4267,
+ 0x7150, 0x2488,
+ 0x7151, 0x4865,
+ 0x7152, 0x2478,
+ 0x7153, 0x2489,
+ 0x7154, 0x2477,
+ 0x7156, 0x0e74,
+ 0x7158, 0x2483,
+ 0x7159, 0x0e67,
+ 0x715a, 0x248c,
+ 0x715c, 0x0e6c,
+ 0x715d, 0x247c,
+ 0x715e, 0x0e71,
+ 0x715f, 0x2487,
+ 0x7160, 0x247a,
+ 0x7161, 0x2481,
+ 0x7162, 0x247d,
+ 0x7163, 0x2479,
+ 0x7164, 0x0e69,
+ 0x7165, 0x0e70,
+ 0x7166, 0x0e6e,
+ 0x7167, 0x0e6b,
+ 0x7168, 0x0e73,
+ 0x7169, 0x0e68,
+ 0x716a, 0x2480,
+ 0x716b, 0x3cc5,
+ 0x716c, 0x0e6d,
+ 0x716e, 0x0cce,
+ 0x7170, 0x2486,
+ 0x7171, 0x3dc0,
+ 0x7172, 0x247e,
+ 0x7173, 0x47e7,
+ 0x7175, 0x3ced,
+ 0x7176, 0x4000,
+ 0x7177, 0x3957,
+ 0x7178, 0x247f,
+ 0x717a, 0x4924,
+ 0x717b, 0x271e,
+ 0x717c, 0x3835,
+ 0x717d, 0x1023,
+ 0x717e, 0x3970,
+ 0x7180, 0x271a,
+ 0x7181, 0x2720,
+ 0x7182, 0x271c,
+ 0x7184, 0x1025,
+ 0x7185, 0x271b,
+ 0x7186, 0x271f,
+ 0x7187, 0x2717,
+ 0x7188, 0x4706,
+ 0x7189, 0x2719,
+ 0x718a, 0x1024,
+ 0x718c, 0x39ea,
+ 0x718e, 0x3d3b,
+ 0x718f, 0x271d,
+ 0x7190, 0x2718,
+ 0x7192, 0x1026,
+ 0x7194, 0x1021,
+ 0x7196, 0x425f,
+ 0x7197, 0x2721,
+ 0x7198, 0x481d,
+ 0x7199, 0x1022,
+ 0x719a, 0x295a,
+ 0x719b, 0x2957,
+ 0x719c, 0x2963,
+ 0x719d, 0x295d,
+ 0x719e, 0x295f,
+ 0x719f, 0x119e,
+ 0x71a0, 0x2959,
+ 0x71a1, 0x2961,
+ 0x71a2, 0x48c1,
+ 0x71a3, 0x3ec8,
+ 0x71a4, 0x2960,
+ 0x71a5, 0x295e,
+ 0x71a7, 0x2964,
+ 0x71a8, 0x11a1,
+ 0x71a9, 0x295b,
+ 0x71aa, 0x2962,
+ 0x71ac, 0x119f,
+ 0x71ad, 0x3e1d,
+ 0x71af, 0x2956,
+ 0x71b0, 0x2958,
+ 0x71b1, 0x11a0,
+ 0x71b2, 0x2955,
+ 0x71b3, 0x2965,
+ 0x71b4, 0x425e,
+ 0x71b5, 0x295c,
+ 0x71b7, 0x468b,
+ 0x71b8, 0x2bb3,
+ 0x71b9, 0x12f3,
+ 0x71ba, 0x426e,
+ 0x71bc, 0x2bbe,
+ 0x71bd, 0x2bbc,
+ 0x71be, 0x12ed,
+ 0x71bf, 0x2bb2,
+ 0x71c0, 0x2bb5,
+ 0x71c2, 0x2bb1,
+ 0x71c3, 0x12f7,
+ 0x71c5, 0x2bb0,
+ 0x71c6, 0x2bbf,
+ 0x71c7, 0x2bba,
+ 0x71c8, 0x12f1,
+ 0x71c9, 0x12ee,
+ 0x71ca, 0x2bb9,
+ 0x71cb, 0x2bb7,
+ 0x71ce, 0x12f4,
+ 0x71cf, 0x2bbb,
+ 0x71d0, 0x12ef,
+ 0x71d1, 0x373d,
+ 0x71d2, 0x12f0,
+ 0x71d4, 0x2bb8,
+ 0x71d5, 0x12f2,
+ 0x71d6, 0x2bb4,
+ 0x71d8, 0x2bbd,
+ 0x71d9, 0x12f5,
+ 0x71da, 0x2bc0,
+ 0x71dc, 0x12f6,
+ 0x71dd, 0x4078,
+ 0x71df, 0x1404,
+ 0x71e0, 0x140b,
+ 0x71e1, 0x2d9b,
+ 0x71e2, 0x2da1,
+ 0x71e4, 0x2d9f,
+ 0x71e5, 0x1407,
+ 0x71e6, 0x1406,
+ 0x71e7, 0x1403,
+ 0x71e8, 0x2d9d,
+ 0x71eb, 0x3c81,
+ 0x71ec, 0x1409,
+ 0x71ed, 0x1408,
+ 0x71ee, 0x1405,
+ 0x71f0, 0x2da0,
+ 0x71f1, 0x2d9c,
+ 0x71f2, 0x2d9e,
+ 0x71f4, 0x140a,
+ 0x71f5, 0x46ee,
+ 0x71f6, 0x3e9a,
+ 0x71f8, 0x14f1,
+ 0x71f9, 0x2f52,
+ 0x71fb, 0x14ee,
+ 0x71fd, 0x2f54,
+ 0x71fe, 0x14f0,
+ 0x71ff, 0x2f51,
+ 0x7201, 0x2f50,
+ 0x7202, 0x30b9,
+ 0x7203, 0x2f53,
+ 0x7205, 0x30ba,
+ 0x7206, 0x1591,
+ 0x7207, 0x30b8,
+ 0x7209, 0x3dbb,
+ 0x720a, 0x30b7,
+ 0x720c, 0x30b6,
+ 0x720d, 0x1592,
+ 0x720e, 0x4271,
+ 0x720f, 0x39fc,
+ 0x7210, 0x161f,
+ 0x7213, 0x31f4,
+ 0x7215, 0x4273,
+ 0x7216, 0x3953,
+ 0x7217, 0x3969,
+ 0x7219, 0x32e1,
+ 0x721a, 0x32e0,
+ 0x721b, 0x167b,
+ 0x721d, 0x32df,
+ 0x721e, 0x338d,
+ 0x7222, 0x3424,
+ 0x7223, 0x348c,
+ 0x7224, 0x4276,
+ 0x7226, 0x34d1,
+ 0x7227, 0x3535,
+ 0x7228, 0x1766,
+ 0x7229, 0x3549,
+ 0x722a, 0x02e7,
+ 0x722b, 0x44f2,
+ 0x722c, 0x0645,
+ 0x722e, 0x4279,
+ 0x7230, 0x0791,
+ 0x7235, 0x140c,
+ 0x7236, 0x02e8,
+ 0x7238, 0x0647,
+ 0x7239, 0x0923,
+ 0x723a, 0x0e75,
+ 0x723b, 0x02e9,
+ 0x723d, 0x0b17,
+ 0x723e, 0x1027,
+ 0x723f, 0x178d,
+ 0x7240, 0x427a,
+ 0x7241, 0x1b6e,
+ 0x7242, 0x1d2d,
+ 0x7244, 0x2722,
+ 0x7246, 0x140d,
+ 0x7247, 0x02ea,
+ 0x7248, 0x0648,
+ 0x7249, 0x1b6f,
+ 0x724b, 0x21fd,
+ 0x724c, 0x0cd0,
+ 0x724f, 0x248d,
+ 0x7250, 0x3ac9,
+ 0x7252, 0x0e76,
+ 0x7253, 0x2723,
+ 0x7255, 0x427d,
+ 0x7256, 0x11a2,
+ 0x7257, 0x427e,
+ 0x7258, 0x1593,
+ 0x7259, 0x02eb,
+ 0x725a, 0x21fe,
+ 0x725b, 0x02ec,
+ 0x725c, 0x465a,
+ 0x725d, 0x03f4,
+ 0x725e, 0x180b,
+ 0x725f, 0x03f3,
+ 0x7260, 0x04ec,
+ 0x7261, 0x04eb,
+ 0x7262, 0x04ea,
+ 0x7263, 0x18c5,
+ 0x7266, 0x3ebb,
+ 0x7267, 0x0649,
+ 0x7269, 0x064a,
+ 0x726a, 0x19fa,
+ 0x726c, 0x1b71,
+ 0x726e, 0x1b74,
+ 0x726f, 0x0793,
+ 0x7270, 0x1b72,
+ 0x7272, 0x0792,
+ 0x7273, 0x1b73,
+ 0x7274, 0x0794,
+ 0x7276, 0x1d30,
+ 0x7277, 0x1d2f,
+ 0x7278, 0x1d2e,
+ 0x7279, 0x0924,
+ 0x727b, 0x1f81,
+ 0x727d, 0x0b18,
+ 0x727e, 0x1f80,
+ 0x727f, 0x1f83,
+ 0x7280, 0x0cd2,
+ 0x7281, 0x0b19,
+ 0x7282, 0x4283,
+ 0x7284, 0x0cd1,
+ 0x7285, 0x2202,
+ 0x7286, 0x2201,
+ 0x7287, 0x3aca,
+ 0x7288, 0x21ff,
+ 0x728b, 0x2203,
+ 0x728c, 0x248f,
+ 0x728d, 0x248e,
+ 0x728e, 0x2492,
+ 0x728f, 0x43c9,
+ 0x7290, 0x2491,
+ 0x7291, 0x2490,
+ 0x7292, 0x1028,
+ 0x7293, 0x2726,
+ 0x7294, 0x3acb,
+ 0x7295, 0x2725,
+ 0x7296, 0x1029,
+ 0x7297, 0x2724,
+ 0x7298, 0x2966,
+ 0x729a, 0x2967,
+ 0x729b, 0x11a3,
+ 0x729d, 0x2bc2,
+ 0x729f, 0x473a,
+ 0x72a1, 0x30bf,
+ 0x72a2, 0x1594,
+ 0x72a3, 0x30be,
+ 0x72a4, 0x30bd,
+ 0x72a5, 0x30bb,
+ 0x72a7, 0x167c,
+ 0x72a8, 0x31f6,
+ 0x72a9, 0x338f,
+ 0x72aa, 0x34d2,
+ 0x72ac, 0x02ed,
+ 0x72ad, 0x44f4,
+ 0x72ae, 0x17af,
+ 0x72af, 0x0355,
+ 0x72b0, 0x17b0,
+ 0x72b2, 0x3fb6,
+ 0x72b4, 0x180c,
+ 0x72ba, 0x18cb,
+ 0x72bd, 0x18c7,
+ 0x72bf, 0x18c6,
+ 0x72c0, 0x064b,
+ 0x72c1, 0x18ca,
+ 0x72c2, 0x04ee,
+ 0x72c3, 0x18c8,
+ 0x72c4, 0x04ed,
+ 0x72c5, 0x18cc,
+ 0x72c6, 0x18c9,
+ 0x72c9, 0x19fe,
+ 0x72ca, 0x1b75,
+ 0x72cb, 0x19fc,
+ 0x72cc, 0x1a03,
+ 0x72cd, 0x43ca,
+ 0x72ce, 0x064c,
+ 0x72d0, 0x064f,
+ 0x72d1, 0x1a04,
+ 0x72d2, 0x1a00,
+ 0x72d4, 0x1a01,
+ 0x72d6, 0x19fb,
+ 0x72d7, 0x064e,
+ 0x72d8, 0x19fd,
+ 0x72d9, 0x064d,
+ 0x72da, 0x1a02,
+ 0x72dc, 0x19ff,
+ 0x72df, 0x1b79,
+ 0x72e0, 0x0796,
+ 0x72e2, 0x3f97,
+ 0x72e3, 0x1b7c,
+ 0x72e4, 0x1b76,
+ 0x72e6, 0x1b7b,
+ 0x72e8, 0x1b77,
+ 0x72e9, 0x0795,
+ 0x72ea, 0x1b7a,
+ 0x72eb, 0x1b78,
+ 0x72f3, 0x1d36,
+ 0x72f4, 0x1d33,
+ 0x72f6, 0x1d35,
+ 0x72f7, 0x0929,
+ 0x72f8, 0x0928,
+ 0x72f9, 0x0926,
+ 0x72fa, 0x1d32,
+ 0x72fb, 0x1d37,
+ 0x72fc, 0x0925,
+ 0x72fd, 0x0927,
+ 0x72fe, 0x1d34,
+ 0x72ff, 0x1f8b,
+ 0x7300, 0x1d31,
+ 0x7301, 0x1d38,
+ 0x7302, 0x3f9a,
+ 0x7304, 0x3eb5,
+ 0x7307, 0x1f86,
+ 0x7308, 0x1f8a,
+ 0x730a, 0x1f89,
+ 0x730b, 0x2205,
+ 0x730c, 0x2210,
+ 0x730f, 0x1f8c,
+ 0x7310, 0x46ea,
+ 0x7311, 0x1f87,
+ 0x7312, 0x2204,
+ 0x7313, 0x0b1d,
+ 0x7316, 0x0b1c,
+ 0x7317, 0x1f85,
+ 0x7318, 0x1f88,
+ 0x7319, 0x0b1e,
+ 0x731b, 0x0b1b,
+ 0x731c, 0x0b1a,
+ 0x731d, 0x1f84,
+ 0x731e, 0x1f8d,
+ 0x7322, 0x2207,
+ 0x7323, 0x220e,
+ 0x7325, 0x0cd4,
+ 0x7326, 0x220d,
+ 0x7327, 0x220a,
+ 0x7328, 0x428a,
+ 0x7329, 0x0cd6,
+ 0x732a, 0x3d70,
+ 0x732b, 0x4285,
+ 0x732c, 0x3fb2,
+ 0x732d, 0x220c,
+ 0x732e, 0x428b,
+ 0x7330, 0x2206,
+ 0x7331, 0x2208,
+ 0x7332, 0x220b,
+ 0x7333, 0x2209,
+ 0x7334, 0x0cd5,
+ 0x7335, 0x220f,
+ 0x7336, 0x0cd3,
+ 0x7337, 0x0e77,
+ 0x7338, 0x46eb,
+ 0x7339, 0x43cc,
+ 0x733a, 0x2496,
+ 0x733b, 0x2495,
+ 0x733c, 0x2493,
+ 0x733e, 0x0e7a,
+ 0x733f, 0x0e79,
+ 0x7340, 0x2497,
+ 0x7341, 0x46ec,
+ 0x7342, 0x2494,
+ 0x7343, 0x2727,
+ 0x7344, 0x102a,
+ 0x7345, 0x0e78,
+ 0x7348, 0x43fa,
+ 0x7349, 0x2499,
+ 0x734a, 0x2498,
+ 0x734c, 0x272a,
+ 0x734d, 0x2728,
+ 0x734e, 0x11a4,
+ 0x734f, 0x3f51,
+ 0x7350, 0x102b,
+ 0x7351, 0x2729,
+ 0x7352, 0x2969,
+ 0x7357, 0x11a5,
+ 0x7358, 0x2968,
+ 0x7359, 0x2971,
+ 0x735a, 0x2970,
+ 0x735b, 0x296e,
+ 0x735d, 0x296d,
+ 0x735e, 0x296a,
+ 0x7361, 0x296f,
+ 0x7362, 0x2972,
+ 0x7365, 0x2bc8,
+ 0x7366, 0x2bc5,
+ 0x7368, 0x12f9,
+ 0x7369, 0x2bc4,
+ 0x736a, 0x2bca,
+ 0x736b, 0x2bc9,
+ 0x736c, 0x2bc7,
+ 0x736e, 0x2da3,
+ 0x7370, 0x140e,
+ 0x7371, 0x3f98,
+ 0x7372, 0x140f,
+ 0x7373, 0x2da2,
+ 0x7374, 0x3ed4,
+ 0x7375, 0x14f3,
+ 0x7376, 0x2f55,
+ 0x7377, 0x14f2,
+ 0x7378, 0x1595,
+ 0x737a, 0x1596,
+ 0x737b, 0x1620,
+ 0x737c, 0x31f8,
+ 0x737d, 0x31f7,
+ 0x737e, 0x32e2,
+ 0x737f, 0x3390,
+ 0x7380, 0x16ca,
+ 0x7381, 0x3426,
+ 0x7382, 0x3425,
+ 0x7383, 0x3427,
+ 0x7384, 0x0356,
+ 0x7385, 0x1b7d,
+ 0x7386, 0x092a,
+ 0x7387, 0x0b1f,
+ 0x7388, 0x1f8e,
+ 0x7389, 0x0357,
+ 0x738a, 0x17b1,
+ 0x738b, 0x02ee,
+ 0x738e, 0x180e,
+ 0x738f, 0x46e5,
+ 0x7392, 0x18d1,
+ 0x7393, 0x18cf,
+ 0x7395, 0x18cd,
+ 0x7396, 0x04ef,
+ 0x7397, 0x18ce,
+ 0x7398, 0x39f6,
+ 0x739c, 0x408a,
+ 0x739d, 0x1a0c,
+ 0x739e, 0x395b,
+ 0x739f, 0x0652,
+ 0x73a0, 0x1a0a,
+ 0x73a1, 0x1a06,
+ 0x73a2, 0x1a09,
+ 0x73a4, 0x1a05,
+ 0x73a5, 0x0654,
+ 0x73a6, 0x1a08,
+ 0x73a7, 0x4087,
+ 0x73a8, 0x0651,
+ 0x73a9, 0x0650,
+ 0x73aa, 0x428d,
+ 0x73ab, 0x0653,
+ 0x73ac, 0x1a0b,
+ 0x73ad, 0x1a07,
+ 0x73b2, 0x079b,
+ 0x73b3, 0x079e,
+ 0x73b4, 0x1b85,
+ 0x73b5, 0x1b84,
+ 0x73b6, 0x1b83,
+ 0x73b7, 0x0798,
+ 0x73b8, 0x1b8c,
+ 0x73b9, 0x1b82,
+ 0x73bb, 0x079a,
+ 0x73bc, 0x1d3d,
+ 0x73be, 0x1b89,
+ 0x73bf, 0x1b87,
+ 0x73c0, 0x079d,
+ 0x73c2, 0x1b7f,
+ 0x73c3, 0x1b8a,
+ 0x73c5, 0x1b81,
+ 0x73c6, 0x1b8b,
+ 0x73c7, 0x1b88,
+ 0x73c8, 0x1b80,
+ 0x73c9, 0x4290,
+ 0x73ca, 0x0799,
+ 0x73cb, 0x1b8d,
+ 0x73cc, 0x1b7e,
+ 0x73cd, 0x079c,
+ 0x73ce, 0x411b,
+ 0x73cf, 0x428c,
+ 0x73d0, 0x3b17,
+ 0x73d2, 0x1d42,
+ 0x73d3, 0x1d39,
+ 0x73d4, 0x1d44,
+ 0x73d5, 0x4073,
+ 0x73d6, 0x1d3c,
+ 0x73d7, 0x1d47,
+ 0x73d9, 0x1d3a,
+ 0x73da, 0x1d46,
+ 0x73db, 0x1d43,
+ 0x73dc, 0x1d41,
+ 0x73dd, 0x1d45,
+ 0x73de, 0x0930,
+ 0x73e0, 0x092e,
+ 0x73e1, 0x46f0,
+ 0x73e2, 0x3ca3,
+ 0x73e3, 0x1d3f,
+ 0x73e4, 0x42a5,
+ 0x73e5, 0x1d3b,
+ 0x73e6, 0x3cba,
+ 0x73e7, 0x1d3e,
+ 0x73e8, 0x1d49,
+ 0x73e9, 0x1d40,
+ 0x73ea, 0x092f,
+ 0x73eb, 0x1b86,
+ 0x73ed, 0x092b,
+ 0x73ee, 0x092d,
+ 0x73ef, 0x4011,
+ 0x73f3, 0x3cab,
+ 0x73f4, 0x1f9c,
+ 0x73f5, 0x1f91,
+ 0x73f6, 0x1f8f,
+ 0x73f7, 0x429a,
+ 0x73f8, 0x1f90,
+ 0x73f9, 0x3bf9,
+ 0x73fa, 0x1f97,
+ 0x73fb, 0x3cac,
+ 0x73fc, 0x1f98,
+ 0x73fd, 0x1f94,
+ 0x73fe, 0x0b24,
+ 0x73ff, 0x1f99,
+ 0x7400, 0x1f96,
+ 0x7401, 0x1f93,
+ 0x7403, 0x0b22,
+ 0x7404, 0x1f92,
+ 0x7405, 0x0b20,
+ 0x7406, 0x0b23,
+ 0x7407, 0x1f95,
+ 0x7408, 0x1f9d,
+ 0x7409, 0x092c,
+ 0x740a, 0x0b21,
+ 0x740b, 0x1f9b,
+ 0x740c, 0x1f9a,
+ 0x740d, 0x0b25,
+ 0x7411, 0x456c,
+ 0x7412, 0x3be6,
+ 0x7414, 0x39f4,
+ 0x7415, 0x429b,
+ 0x7416, 0x2215,
+ 0x7417, 0x40ad,
+ 0x7419, 0x46f3,
+ 0x741a, 0x2216,
+ 0x741b, 0x0ce0,
+ 0x741c, 0x38dd,
+ 0x741d, 0x221c,
+ 0x741e, 0x46f4,
+ 0x7420, 0x221e,
+ 0x7421, 0x2217,
+ 0x7422, 0x0cda,
+ 0x7423, 0x221b,
+ 0x7424, 0x221a,
+ 0x7425, 0x0cdb,
+ 0x7426, 0x0ce1,
+ 0x7428, 0x0ce2,
+ 0x7429, 0x221d,
+ 0x742a, 0x0cd8,
+ 0x742b, 0x2214,
+ 0x742c, 0x2212,
+ 0x742d, 0x2218,
+ 0x742e, 0x2211,
+ 0x742f, 0x0cdf,
+ 0x7430, 0x2213,
+ 0x7431, 0x2219,
+ 0x7432, 0x221f,
+ 0x7433, 0x0cd9,
+ 0x7434, 0x0cde,
+ 0x7435, 0x0cdc,
+ 0x7437, 0x3ae1,
+ 0x7438, 0x3b09,
+ 0x7439, 0x429e,
+ 0x743a, 0x0cd7,
+ 0x743c, 0x3adf,
+ 0x743f, 0x0e81,
+ 0x7440, 0x24a0,
+ 0x7441, 0x0e80,
+ 0x7442, 0x24a4,
+ 0x7443, 0x3a1a,
+ 0x7444, 0x249a,
+ 0x7445, 0x3bd7,
+ 0x7446, 0x24a5,
+ 0x7447, 0x42a4,
+ 0x7448, 0x3cb5,
+ 0x7449, 0x4291,
+ 0x744a, 0x249b,
+ 0x744d, 0x24a6,
+ 0x744e, 0x24a3,
+ 0x744f, 0x24a1,
+ 0x7451, 0x249e,
+ 0x7452, 0x249d,
+ 0x7453, 0x4231,
+ 0x7454, 0x24a7,
+ 0x7455, 0x0e7d,
+ 0x7456, 0x39f5,
+ 0x7457, 0x249f,
+ 0x7459, 0x0e82,
+ 0x745a, 0x0e7c,
+ 0x745b, 0x0e83,
+ 0x745d, 0x42c6,
+ 0x745e, 0x0e7f,
+ 0x745f, 0x0e7e,
+ 0x7460, 0x42a2,
+ 0x7462, 0x272b,
+ 0x7463, 0x102d,
+ 0x7464, 0x102c,
+ 0x7465, 0x4101,
+ 0x7467, 0x2730,
+ 0x7468, 0x3aee,
+ 0x7469, 0x11a6,
+ 0x746a, 0x102e,
+ 0x746b, 0x3be7,
+ 0x746c, 0x42a8,
+ 0x746d, 0x1030,
+ 0x746e, 0x2731,
+ 0x746f, 0x0e7b,
+ 0x7470, 0x102f,
+ 0x7471, 0x272d,
+ 0x7472, 0x272f,
+ 0x7473, 0x272c,
+ 0x7474, 0x42a9,
+ 0x7475, 0x272e,
+ 0x7476, 0x42a6,
+ 0x7479, 0x297c,
+ 0x747a, 0x3ad1,
+ 0x747c, 0x297b,
+ 0x747d, 0x2978,
+ 0x747e, 0x11a9,
+ 0x747f, 0x2bcb,
+ 0x7480, 0x11aa,
+ 0x7481, 0x2977,
+ 0x7482, 0x42ac,
+ 0x7483, 0x11a8,
+ 0x7485, 0x2979,
+ 0x7486, 0x2976,
+ 0x7487, 0x2973,
+ 0x7488, 0x297a,
+ 0x7489, 0x2974,
+ 0x748b, 0x11a7,
+ 0x748c, 0x3a21,
+ 0x748d, 0x469d,
+ 0x7490, 0x2da8,
+ 0x7492, 0x2bcf,
+ 0x7494, 0x2bce,
+ 0x7495, 0x2bd0,
+ 0x7497, 0x2da5,
+ 0x7498, 0x12fc,
+ 0x7499, 0x39f3,
+ 0x749a, 0x2bcc,
+ 0x749b, 0x3b0a,
+ 0x749c, 0x12fa,
+ 0x749e, 0x12fe,
+ 0x749f, 0x12fd,
+ 0x74a0, 0x2bcd,
+ 0x74a1, 0x2bd1,
+ 0x74a3, 0x12fb,
+ 0x74a4, 0x4170,
+ 0x74a5, 0x2dac,
+ 0x74a6, 0x1412,
+ 0x74a7, 0x14f4,
+ 0x74a8, 0x1413,
+ 0x74a9, 0x1410,
+ 0x74aa, 0x2da9,
+ 0x74ab, 0x2da7,
+ 0x74ad, 0x2daa,
+ 0x74af, 0x2dad,
+ 0x74b0, 0x1411,
+ 0x74b1, 0x2dab,
+ 0x74b2, 0x2da6,
+ 0x74b4, 0x3ca5,
+ 0x74b5, 0x2f58,
+ 0x74b6, 0x2f5b,
+ 0x74b7, 0x30c2,
+ 0x74b8, 0x2f56,
+ 0x74ba, 0x31f9,
+ 0x74bb, 0x2f5c,
+ 0x74bd, 0x1597,
+ 0x74be, 0x2f5a,
+ 0x74bf, 0x14f5,
+ 0x74c0, 0x2f57,
+ 0x74c1, 0x2f59,
+ 0x74c2, 0x2f5d,
+ 0x74c3, 0x30c3,
+ 0x74c5, 0x30c1,
+ 0x74c8, 0x42b5,
+ 0x74ca, 0x1598,
+ 0x74cb, 0x30c0,
+ 0x74cc, 0x3ade,
+ 0x74cf, 0x1621,
+ 0x74d0, 0x3a9b,
+ 0x74d3, 0x46fa,
+ 0x74d4, 0x167e,
+ 0x74d5, 0x3392,
+ 0x74d6, 0x167d,
+ 0x74d7, 0x3394,
+ 0x74d8, 0x3391,
+ 0x74d9, 0x3393,
+ 0x74da, 0x16fe,
+ 0x74db, 0x348d,
+ 0x74dc, 0x0358,
+ 0x74dd, 0x1a0d,
+ 0x74de, 0x1d4a,
+ 0x74e0, 0x0b26,
+ 0x74e1, 0x24a8,
+ 0x74e2, 0x12ff,
+ 0x74e3, 0x1599,
+ 0x74e4, 0x16cb,
+ 0x74e5, 0x348e,
+ 0x74e6, 0x0359,
+ 0x74e7, 0x3ffe,
+ 0x74e8, 0x1a0e,
+ 0x74e9, 0x0120,
+ 0x74ec, 0x1b8e,
+ 0x74ee, 0x1b8f,
+ 0x74f0, 0x3fe6,
+ 0x74f1, 0x3f9b,
+ 0x74f2, 0x3fdf,
+ 0x74f4, 0x1d4c,
+ 0x74f6, 0x0b27,
+ 0x74f8, 0x3ff4,
+ 0x74fb, 0x2220,
+ 0x74fd, 0x24ab,
+ 0x74fe, 0x24aa,
+ 0x74ff, 0x24a9,
+ 0x7500, 0x2732,
+ 0x7502, 0x2733,
+ 0x7504, 0x1031,
+ 0x7505, 0x3fde,
+ 0x7507, 0x297e,
+ 0x7508, 0x297d,
+ 0x750b, 0x2bd2,
+ 0x750c, 0x1300,
+ 0x750e, 0x42b7,
+ 0x750f, 0x2db1,
+ 0x7510, 0x2dae,
+ 0x7513, 0x2f5f,
+ 0x7514, 0x2f5e,
+ 0x7515, 0x14f6,
+ 0x7516, 0x30c4,
+ 0x7517, 0x32e3,
+ 0x7518, 0x035a,
+ 0x7519, 0x4583,
+ 0x751a, 0x079f,
+ 0x751c, 0x0b29,
+ 0x751d, 0x24ac,
+ 0x751e, 0x42b8,
+ 0x751f, 0x035b,
+ 0x7521, 0x1d4e,
+ 0x7522, 0x0b2a,
+ 0x7525, 0x0ce3,
+ 0x7528, 0x035c,
+ 0x752a, 0x180f,
+ 0x752b, 0x04f1,
+ 0x752c, 0x04f0,
+ 0x752d, 0x07a0,
+ 0x752e, 0x1b90,
+ 0x752f, 0x2221,
+ 0x7530, 0x035e,
+ 0x7534, 0x3e87,
+ 0x7535, 0x455a,
+ 0x7537, 0x04f2,
+ 0x7539, 0x18d3,
+ 0x753a, 0x18d2,
+ 0x753b, 0x3dfb,
+ 0x753d, 0x0655,
+ 0x753e, 0x1a11,
+ 0x753f, 0x1a0f,
+ 0x7542, 0x43cd,
+ 0x7546, 0x3f40,
+ 0x7547, 0x1b91,
+ 0x754a, 0x42bf,
+ 0x754b, 0x07a4,
+ 0x754c, 0x07a2,
+ 0x754d, 0x42be,
+ 0x754e, 0x07a3,
+ 0x754f, 0x07a1,
+ 0x7551, 0x3cfe,
+ 0x7553, 0x3feb,
+ 0x7554, 0x0931,
+ 0x7555, 0x3aea,
+ 0x7559, 0x0935,
+ 0x755a, 0x0934,
+ 0x755b, 0x1d4f,
+ 0x755c, 0x0933,
+ 0x755d, 0x0932,
+ 0x755f, 0x1d50,
+ 0x7560, 0x3d71,
+ 0x7562, 0x0b2d,
+ 0x7563, 0x1f9f,
+ 0x7564, 0x1f9e,
+ 0x7565, 0x0b2b,
+ 0x7567, 0x42c0,
+ 0x756a, 0x0ce6,
+ 0x756b, 0x0ce5,
+ 0x756c, 0x2223,
+ 0x756d, 0x46fd,
+ 0x756e, 0x42c1,
+ 0x756f, 0x2222,
+ 0x7570, 0x0b2e,
+ 0x7572, 0x46fe,
+ 0x7576, 0x0e85,
+ 0x7577, 0x24ae,
+ 0x7578, 0x0e86,
+ 0x7579, 0x24ad,
+ 0x757a, 0x3f4f,
+ 0x757d, 0x2735,
+ 0x757e, 0x297f,
+ 0x757f, 0x11ab,
+ 0x7580, 0x2bd3,
+ 0x7583, 0x3ae5,
+ 0x7584, 0x2db2,
+ 0x7586, 0x159b,
+ 0x7587, 0x159a,
+ 0x758a, 0x16cc,
+ 0x758b, 0x0362,
+ 0x758c, 0x1a12,
+ 0x758d, 0x46ff,
+ 0x758e, 0x42c5,
+ 0x758f, 0x0b2f,
+ 0x7590, 0x2736,
+ 0x7591, 0x1032,
+ 0x7592, 0x022e,
+ 0x7594, 0x18d4,
+ 0x7598, 0x1a13,
+ 0x7599, 0x0657,
+ 0x759d, 0x0656,
+ 0x759e, 0x42c7,
+ 0x75a2, 0x07a8,
+ 0x75a4, 0x07a6,
+ 0x75a7, 0x1b93,
+ 0x75aa, 0x1b94,
+ 0x75ab, 0x07a5,
+ 0x75b0, 0x1d51,
+ 0x75b1, 0x3ead,
+ 0x75b2, 0x0939,
+ 0x75b4, 0x42c8,
+ 0x75b5, 0x0b32,
+ 0x75b6, 0x1d57,
+ 0x75b8, 0x093f,
+ 0x75b9, 0x093d,
+ 0x75ba, 0x1d58,
+ 0x75bb, 0x1d53,
+ 0x75bc, 0x093c,
+ 0x75bd, 0x093b,
+ 0x75be, 0x0936,
+ 0x75bf, 0x1d56,
+ 0x75c0, 0x1d55,
+ 0x75c1, 0x1d52,
+ 0x75c2, 0x093e,
+ 0x75c3, 0x3f93,
+ 0x75c4, 0x1d54,
+ 0x75c5, 0x0937,
+ 0x75c7, 0x0938,
+ 0x75c8, 0x4701,
+ 0x75ca, 0x0b33,
+ 0x75cb, 0x1fa3,
+ 0x75cd, 0x0b34,
+ 0x75ce, 0x1fa0,
+ 0x75cf, 0x1fa2,
+ 0x75d0, 0x1fa6,
+ 0x75d1, 0x1fa5,
+ 0x75d2, 0x1fa1,
+ 0x75d4, 0x0b30,
+ 0x75d7, 0x222b,
+ 0x75d8, 0x0ceb,
+ 0x75d9, 0x0cea,
+ 0x75da, 0x2225,
+ 0x75db, 0x0ce8,
+ 0x75dc, 0x43ce,
+ 0x75dd, 0x2228,
+ 0x75de, 0x0cec,
+ 0x75df, 0x2229,
+ 0x75e0, 0x0ced,
+ 0x75e1, 0x2226,
+ 0x75e2, 0x0ce7,
+ 0x75e3, 0x0ce9,
+ 0x75e4, 0x222a,
+ 0x75e6, 0x2227,
+ 0x75e7, 0x2224,
+ 0x75ed, 0x24bb,
+ 0x75ef, 0x24b0,
+ 0x75f0, 0x0e88,
+ 0x75f1, 0x0e8b,
+ 0x75f2, 0x0e8a,
+ 0x75f3, 0x0e8f,
+ 0x75f4, 0x0e8e,
+ 0x75f5, 0x24bc,
+ 0x75f6, 0x24ba,
+ 0x75f7, 0x24b3,
+ 0x75f8, 0x24b7,
+ 0x75f9, 0x24b6,
+ 0x75fa, 0x0e8c,
+ 0x75fb, 0x24b9,
+ 0x75fc, 0x24b5,
+ 0x75fd, 0x24bd,
+ 0x75fe, 0x24b4,
+ 0x75ff, 0x0e8d,
+ 0x7600, 0x0e87,
+ 0x7601, 0x0e89,
+ 0x7602, 0x42c9,
+ 0x7603, 0x24b2,
+ 0x7607, 0x3f8f,
+ 0x7608, 0x2738,
+ 0x7609, 0x1036,
+ 0x760a, 0x273c,
+ 0x760b, 0x1035,
+ 0x760c, 0x2739,
+ 0x760d, 0x1034,
+ 0x760f, 0x24b1,
+ 0x7610, 0x24b8,
+ 0x7611, 0x273b,
+ 0x7613, 0x1037,
+ 0x7614, 0x273d,
+ 0x7615, 0x273a,
+ 0x7616, 0x2737,
+ 0x7619, 0x2982,
+ 0x761a, 0x2986,
+ 0x761b, 0x2988,
+ 0x761c, 0x2984,
+ 0x761d, 0x2983,
+ 0x761e, 0x2981,
+ 0x761f, 0x11ae,
+ 0x7620, 0x11ac,
+ 0x7621, 0x11b1,
+ 0x7623, 0x2985,
+ 0x7624, 0x11af,
+ 0x7625, 0x2980,
+ 0x7626, 0x11b0,
+ 0x7627, 0x1033,
+ 0x7628, 0x2987,
+ 0x7629, 0x11ad,
+ 0x762c, 0x42ca,
+ 0x762d, 0x2bd5,
+ 0x762f, 0x2bd4,
+ 0x7630, 0x2bdc,
+ 0x7631, 0x2bd6,
+ 0x7632, 0x2bdb,
+ 0x7633, 0x2bd8,
+ 0x7634, 0x1302,
+ 0x7635, 0x2bda,
+ 0x7638, 0x1303,
+ 0x763a, 0x1304,
+ 0x763b, 0x3e70,
+ 0x763c, 0x2bd9,
+ 0x763d, 0x2bd7,
+ 0x7640, 0x3ee6,
+ 0x7642, 0x1415,
+ 0x7643, 0x2db3,
+ 0x7646, 0x1414,
+ 0x7647, 0x2db6,
+ 0x7648, 0x2db4,
+ 0x764c, 0x1416,
+ 0x764d, 0x4702,
+ 0x764e, 0x3e72,
+ 0x764f, 0x42cc,
+ 0x7650, 0x2f63,
+ 0x7651, 0x42cb,
+ 0x7652, 0x14f9,
+ 0x7653, 0x2f64,
+ 0x7654, 0x3ef0,
+ 0x7656, 0x14f7,
+ 0x7657, 0x2f65,
+ 0x7658, 0x14f8,
+ 0x7659, 0x2f62,
+ 0x765a, 0x2f66,
+ 0x765c, 0x2f60,
+ 0x765f, 0x159c,
+ 0x7660, 0x30c5,
+ 0x7661, 0x159d,
+ 0x7662, 0x1622,
+ 0x7664, 0x2f61,
+ 0x7665, 0x1623,
+ 0x7666, 0x3eaa,
+ 0x7667, 0x3fa9,
+ 0x7669, 0x167f,
+ 0x766a, 0x32e4,
+ 0x766c, 0x16ce,
+ 0x766d, 0x3395,
+ 0x766e, 0x16cd,
+ 0x766f, 0x42cd,
+ 0x7670, 0x3428,
+ 0x7671, 0x1723,
+ 0x7673, 0x3aeb,
+ 0x7674, 0x4703,
+ 0x7675, 0x3543,
+ 0x7676, 0x022f,
+ 0x7678, 0x07aa,
+ 0x7679, 0x1b95,
+ 0x767a, 0x4705,
+ 0x767b, 0x0cee,
+ 0x767d, 0x0363,
+ 0x767e, 0x03f5,
+ 0x767f, 0x1810,
+ 0x7680, 0x43d3,
+ 0x7681, 0x18d6,
+ 0x7682, 0x04f4,
+ 0x7684, 0x0659,
+ 0x7686, 0x07ab,
+ 0x7689, 0x1fa8,
+ 0x768a, 0x1d59,
+ 0x768b, 0x0940,
+ 0x768c, 0x43d4,
+ 0x768e, 0x0b35,
+ 0x768f, 0x1fa7,
+ 0x7690, 0x42d0,
+ 0x7692, 0x222d,
+ 0x7693, 0x0cf1,
+ 0x7695, 0x222c,
+ 0x7696, 0x0cf0,
+ 0x7699, 0x24be,
+ 0x769a, 0x11b3,
+ 0x769b, 0x298c,
+ 0x769c, 0x2989,
+ 0x76a1, 0x42d5,
+ 0x76a4, 0x2db7,
+ 0x76a5, 0x42d6,
+ 0x76a6, 0x2f67,
+ 0x76aa, 0x31fb,
+ 0x76ab, 0x31fa,
+ 0x76ad, 0x3396,
+ 0x76ae, 0x0364,
+ 0x76af, 0x1a14,
+ 0x76b0, 0x0941,
+ 0x76b4, 0x0cf2,
+ 0x76b5, 0x24bf,
+ 0x76b7, 0x42d7,
+ 0x76b8, 0x273e,
+ 0x76ba, 0x11b4,
+ 0x76bb, 0x2bdd,
+ 0x76bd, 0x2f68,
+ 0x76be, 0x31fc,
+ 0x76bf, 0x0365,
+ 0x76c2, 0x065a,
+ 0x76c3, 0x07b0,
+ 0x76c4, 0x1b96,
+ 0x76c5, 0x07b1,
+ 0x76c6, 0x07af,
+ 0x76c8, 0x07ae,
+ 0x76c9, 0x1d5a,
+ 0x76ca, 0x0942,
+ 0x76cc, 0x42d8,
+ 0x76cd, 0x0943,
+ 0x76d2, 0x0b37,
+ 0x76d3, 0x1fa9,
+ 0x76d4, 0x0b36,
+ 0x76d6, 0x3f55,
+ 0x76da, 0x222e,
+ 0x76db, 0x0b38,
+ 0x76dc, 0x0cf3,
+ 0x76dd, 0x24c0,
+ 0x76de, 0x0e90,
+ 0x76e1, 0x1038,
+ 0x76e3, 0x1039,
+ 0x76e4, 0x11b5,
+ 0x76e5, 0x1306,
+ 0x76e6, 0x2bde,
+ 0x76e7, 0x1305,
+ 0x76e9, 0x2db8,
+ 0x76ea, 0x1417,
+ 0x76ec, 0x2f69,
+ 0x76ed, 0x31fd,
+ 0x76ee, 0x0366,
+ 0x76ef, 0x04f5,
+ 0x76f0, 0x1a17,
+ 0x76f1, 0x1a16,
+ 0x76f2, 0x065b,
+ 0x76f3, 0x1a15,
+ 0x76f4, 0x065c,
+ 0x76f5, 0x1a18,
+ 0x76f7, 0x1b9c,
+ 0x76f8, 0x07b4,
+ 0x76f9, 0x07b3,
+ 0x76fa, 0x1b9e,
+ 0x76fb, 0x1b9d,
+ 0x76fc, 0x07b8,
+ 0x76fe, 0x07b7,
+ 0x7701, 0x07b2,
+ 0x7703, 0x1b98,
+ 0x7707, 0x07b9,
+ 0x7708, 0x1b97,
+ 0x7709, 0x07b5,
+ 0x770a, 0x1b9b,
+ 0x770b, 0x07b6,
+ 0x770c, 0x3d62,
+ 0x770e, 0x3b02,
+ 0x7710, 0x1d5d,
+ 0x7711, 0x1d61,
+ 0x7712, 0x1d5f,
+ 0x7713, 0x1d5e,
+ 0x7715, 0x1d62,
+ 0x7719, 0x1d63,
+ 0x771b, 0x1d5c,
+ 0x771d, 0x1d5b,
+ 0x771e, 0x42de,
+ 0x771f, 0x0946,
+ 0x7722, 0x1d65,
+ 0x7723, 0x1d60,
+ 0x7724, 0x3fe8,
+ 0x7725, 0x1fb2,
+ 0x7726, 0x42df,
+ 0x7727, 0x1d66,
+ 0x7728, 0x0948,
+ 0x7729, 0x0945,
+ 0x772b, 0x3ff3,
+ 0x772d, 0x1fac,
+ 0x772f, 0x1fab,
+ 0x7731, 0x1fad,
+ 0x7733, 0x1fb0,
+ 0x7734, 0x1faf,
+ 0x7735, 0x1fb4,
+ 0x7736, 0x0b3c,
+ 0x7737, 0x0b39,
+ 0x7738, 0x0b3d,
+ 0x7739, 0x1faa,
+ 0x773a, 0x0b3e,
+ 0x773b, 0x1fb3,
+ 0x773c, 0x0b3b,
+ 0x773d, 0x1fb1,
+ 0x773e, 0x0b3a,
+ 0x7740, 0x42e0,
+ 0x7743, 0x470a,
+ 0x7744, 0x2231,
+ 0x7745, 0x2233,
+ 0x7746, 0x222f,
+ 0x774a, 0x2234,
+ 0x774b, 0x2236,
+ 0x774d, 0x2232,
+ 0x774e, 0x2235,
+ 0x774f, 0x0cf4,
+ 0x7752, 0x24c4,
+ 0x7754, 0x24c9,
+ 0x7755, 0x24c1,
+ 0x7756, 0x24c5,
+ 0x7758, 0x42e3,
+ 0x7759, 0x24ca,
+ 0x775a, 0x24c6,
+ 0x775b, 0x0e92,
+ 0x775c, 0x0e9a,
+ 0x775e, 0x0e95,
+ 0x775f, 0x24c2,
+ 0x7761, 0x103d,
+ 0x7762, 0x0e9d,
+ 0x7763, 0x0e96,
+ 0x7765, 0x0e9b,
+ 0x7766, 0x0e94,
+ 0x7767, 0x24c8,
+ 0x7768, 0x0e9c,
+ 0x7769, 0x24c7,
+ 0x776a, 0x0e98,
+ 0x776b, 0x0e93,
+ 0x776c, 0x0e99,
+ 0x776d, 0x24cb,
+ 0x776e, 0x2743,
+ 0x776f, 0x2745,
+ 0x7772, 0x396b,
+ 0x7777, 0x46a9,
+ 0x7778, 0x3b00,
+ 0x7779, 0x0e97,
+ 0x777a, 0x4317,
+ 0x777b, 0x3b04,
+ 0x777c, 0x2740,
+ 0x777d, 0x103b,
+ 0x777e, 0x2746,
+ 0x777f, 0x103c,
+ 0x7780, 0x2744,
+ 0x7781, 0x273f,
+ 0x7782, 0x2742,
+ 0x7783, 0x2747,
+ 0x7784, 0x103a,
+ 0x7785, 0x2741,
+ 0x7787, 0x11b7,
+ 0x7788, 0x2990,
+ 0x7789, 0x298f,
+ 0x778b, 0x11ba,
+ 0x778c, 0x11b8,
+ 0x778d, 0x298d,
+ 0x778e, 0x11b6,
+ 0x778f, 0x298e,
+ 0x7791, 0x11b9,
+ 0x7793, 0x382d,
+ 0x7795, 0x2be6,
+ 0x7797, 0x2be8,
+ 0x7798, 0x470e,
+ 0x7799, 0x2be7,
+ 0x779a, 0x2bdf,
+ 0x779b, 0x2be3,
+ 0x779c, 0x2be2,
+ 0x779d, 0x2be0,
+ 0x779e, 0x1308,
+ 0x77a0, 0x1307,
+ 0x77a1, 0x2be1,
+ 0x77a2, 0x2be4,
+ 0x77a5, 0x130a,
+ 0x77a7, 0x141c,
+ 0x77a8, 0x2dc0,
+ 0x77aa, 0x1419,
+ 0x77ab, 0x2dba,
+ 0x77ac, 0x141b,
+ 0x77ad, 0x141d,
+ 0x77af, 0x42e5,
+ 0x77b0, 0x141a,
+ 0x77b1, 0x2dbf,
+ 0x77b2, 0x2dbb,
+ 0x77b3, 0x1418,
+ 0x77b4, 0x2dbe,
+ 0x77b5, 0x2db9,
+ 0x77b6, 0x2dbd,
+ 0x77b7, 0x2dbc,
+ 0x77b9, 0x3e73,
+ 0x77ba, 0x2f6b,
+ 0x77bb, 0x14fc,
+ 0x77bd, 0x14fa,
+ 0x77be, 0x4711,
+ 0x77bf, 0x14fb,
+ 0x77c2, 0x2f6a,
+ 0x77c3, 0x3bb1,
+ 0x77c4, 0x30c8,
+ 0x77c5, 0x41c1,
+ 0x77c7, 0x159e,
+ 0x77c9, 0x30c6,
+ 0x77cb, 0x4712,
+ 0x77cc, 0x31fe,
+ 0x77cd, 0x3201,
+ 0x77ce, 0x31ff,
+ 0x77d0, 0x32e5,
+ 0x77d3, 0x1680,
+ 0x77d4, 0x3429,
+ 0x77d5, 0x348f,
+ 0x77d7, 0x1725,
+ 0x77d8, 0x34d3,
+ 0x77da, 0x1753,
+ 0x77db, 0x0367,
+ 0x77dc, 0x07ba,
+ 0x77de, 0x2238,
+ 0x77e0, 0x24cc,
+ 0x77e2, 0x0368,
+ 0x77e3, 0x04f6,
+ 0x77e5, 0x065d,
+ 0x77e6, 0x4081,
+ 0x77e7, 0x1b9f,
+ 0x77e9, 0x0949,
+ 0x77ec, 0x2239,
+ 0x77ed, 0x0cf5,
+ 0x77ee, 0x0e9e,
+ 0x77ef, 0x141e,
+ 0x77f0, 0x2dc1,
+ 0x77f1, 0x30c9,
+ 0x77f2, 0x3202,
+ 0x77f3, 0x0369,
+ 0x77f4, 0x42e9,
+ 0x77f7, 0x1a1e,
+ 0x77f8, 0x1a19,
+ 0x77f9, 0x1a1b,
+ 0x77fa, 0x1a1d,
+ 0x77fb, 0x1a1c,
+ 0x77fc, 0x1a1a,
+ 0x77fd, 0x065e,
+ 0x77fe, 0x3fd5,
+ 0x7802, 0x07bb,
+ 0x7803, 0x1ba9,
+ 0x7805, 0x1ba4,
+ 0x7806, 0x1ba1,
+ 0x7808, 0x3e46,
+ 0x7809, 0x1ba8,
+ 0x780c, 0x07bd,
+ 0x780e, 0x1ba7,
+ 0x780f, 0x1ba6,
+ 0x7810, 0x1ba5,
+ 0x7811, 0x1ba2,
+ 0x7813, 0x1baa,
+ 0x7814, 0x07bc,
+ 0x7818, 0x4713,
+ 0x781c, 0x4714,
+ 0x781d, 0x094d,
+ 0x781e, 0x3b13,
+ 0x781f, 0x0953,
+ 0x7820, 0x0952,
+ 0x7821, 0x1d6f,
+ 0x7822, 0x1d69,
+ 0x7823, 0x1d67,
+ 0x7825, 0x0950,
+ 0x7826, 0x1fbb,
+ 0x7827, 0x094b,
+ 0x7828, 0x1d6c,
+ 0x7829, 0x1d70,
+ 0x782a, 0x1d72,
+ 0x782b, 0x1d6e,
+ 0x782c, 0x1d68,
+ 0x782d, 0x0951,
+ 0x782e, 0x1d6d,
+ 0x782f, 0x1d6b,
+ 0x7830, 0x094a,
+ 0x7831, 0x1d73,
+ 0x7832, 0x0954,
+ 0x7833, 0x1d71,
+ 0x7834, 0x094e,
+ 0x7835, 0x1d6a,
+ 0x7837, 0x094f,
+ 0x7838, 0x094c,
+ 0x7839, 0x43d6,
+ 0x783c, 0x401a,
+ 0x783d, 0x3c6a,
+ 0x7842, 0x3ac4,
+ 0x7843, 0x0b40,
+ 0x7844, 0x3c2b,
+ 0x7845, 0x1fbc,
+ 0x7847, 0x4715,
+ 0x7848, 0x1fb5,
+ 0x7849, 0x1fb7,
+ 0x784a, 0x1fb9,
+ 0x784b, 0x3c6d,
+ 0x784c, 0x1fba,
+ 0x784d, 0x1fb8,
+ 0x784e, 0x0b41,
+ 0x7850, 0x1fbd,
+ 0x7851, 0x4716,
+ 0x7852, 0x1fb6,
+ 0x7853, 0x3f95,
+ 0x7854, 0x3c6b,
+ 0x785c, 0x223d,
+ 0x785d, 0x0cf6,
+ 0x785e, 0x2245,
+ 0x7860, 0x223a,
+ 0x7862, 0x2246,
+ 0x7864, 0x223b,
+ 0x7866, 0x4717,
+ 0x7868, 0x2244,
+ 0x7869, 0x2243,
+ 0x786a, 0x2240,
+ 0x786b, 0x0b3f,
+ 0x786c, 0x0cf7,
+ 0x786d, 0x223e,
+ 0x786e, 0x2241,
+ 0x786f, 0x0cf8,
+ 0x7870, 0x2242,
+ 0x7871, 0x223f,
+ 0x7879, 0x24d7,
+ 0x787a, 0x3ee9,
+ 0x787b, 0x24db,
+ 0x787c, 0x0ea5,
+ 0x787e, 0x274d,
+ 0x787f, 0x0ea8,
+ 0x7880, 0x24d9,
+ 0x7881, 0x36e8,
+ 0x7883, 0x24d6,
+ 0x7884, 0x24d1,
+ 0x7885, 0x24d3,
+ 0x7887, 0x24cd,
+ 0x7888, 0x3b15,
+ 0x7889, 0x0ea4,
+ 0x788c, 0x0ea3,
+ 0x788d, 0x3b14,
+ 0x788e, 0x0e9f,
+ 0x788f, 0x24d0,
+ 0x7891, 0x0ea6,
+ 0x7893, 0x0ea7,
+ 0x7894, 0x24cf,
+ 0x7895, 0x24d2,
+ 0x7896, 0x24da,
+ 0x7897, 0x0ea1,
+ 0x7899, 0x24d8,
+ 0x789a, 0x24ce,
+ 0x789e, 0x274f,
+ 0x789f, 0x103f,
+ 0x78a0, 0x2751,
+ 0x78a1, 0x24d5,
+ 0x78a2, 0x2753,
+ 0x78a3, 0x1043,
+ 0x78a4, 0x2754,
+ 0x78a5, 0x2750,
+ 0x78a7, 0x1040,
+ 0x78a8, 0x274c,
+ 0x78a9, 0x1042,
+ 0x78aa, 0x2749,
+ 0x78ab, 0x274e,
+ 0x78ac, 0x2752,
+ 0x78ad, 0x274b,
+ 0x78af, 0x42ec,
+ 0x78b0, 0x0ea0,
+ 0x78b1, 0x42f4,
+ 0x78b2, 0x2748,
+ 0x78b3, 0x1041,
+ 0x78b4, 0x274a,
+ 0x78b6, 0x3c6c,
+ 0x78b8, 0x4571,
+ 0x78b9, 0x3c63,
+ 0x78ba, 0x11bd,
+ 0x78bb, 0x2992,
+ 0x78bc, 0x11c1,
+ 0x78be, 0x11bf,
+ 0x78c1, 0x103e,
+ 0x78c3, 0x2999,
+ 0x78c5, 0x11bc,
+ 0x78c7, 0x42ed,
+ 0x78c8, 0x2998,
+ 0x78c9, 0x299b,
+ 0x78ca, 0x11be,
+ 0x78cb, 0x11bb,
+ 0x78cc, 0x2994,
+ 0x78cd, 0x2991,
+ 0x78ce, 0x2996,
+ 0x78cf, 0x2993,
+ 0x78d0, 0x11c2,
+ 0x78d1, 0x2995,
+ 0x78d2, 0x3b16,
+ 0x78d3, 0x42ee,
+ 0x78d4, 0x2997,
+ 0x78d5, 0x11c0,
+ 0x78d7, 0x42f2,
+ 0x78d8, 0x3f8c,
+ 0x78da, 0x130c,
+ 0x78db, 0x2bef,
+ 0x78dd, 0x2be9,
+ 0x78de, 0x2bed,
+ 0x78df, 0x2bf3,
+ 0x78e1, 0x2bf0,
+ 0x78e3, 0x2bee,
+ 0x78e5, 0x2beb,
+ 0x78e7, 0x130e,
+ 0x78e8, 0x130b,
+ 0x78e9, 0x2bea,
+ 0x78ea, 0x2bec,
+ 0x78ec, 0x130d,
+ 0x78ed, 0x2bf2,
+ 0x78ee, 0x3a81,
+ 0x78ef, 0x1422,
+ 0x78f0, 0x3b3a,
+ 0x78f1, 0x40be,
+ 0x78f2, 0x2dc8,
+ 0x78f3, 0x2dc2,
+ 0x78f4, 0x1421,
+ 0x78f5, 0x38b3,
+ 0x78f7, 0x141f,
+ 0x78f9, 0x2dca,
+ 0x78fa, 0x1420,
+ 0x78fb, 0x2dc5,
+ 0x78fd, 0x2dc3,
+ 0x78fe, 0x2dcb,
+ 0x78ff, 0x2dc7,
+ 0x7901, 0x1423,
+ 0x7902, 0x2dc4,
+ 0x7904, 0x2dcc,
+ 0x7905, 0x2dc9,
+ 0x7906, 0x3fcf,
+ 0x7909, 0x2f6f,
+ 0x790c, 0x2f6c,
+ 0x790e, 0x14fe,
+ 0x7910, 0x2f70,
+ 0x7911, 0x2f72,
+ 0x7912, 0x2f71,
+ 0x7913, 0x2f6d,
+ 0x7917, 0x30ce,
+ 0x7919, 0x159f,
+ 0x791b, 0x30cb,
+ 0x791c, 0x30cd,
+ 0x791d, 0x30ca,
+ 0x791e, 0x30cf,
+ 0x7921, 0x30cc,
+ 0x7923, 0x3204,
+ 0x7924, 0x3207,
+ 0x7925, 0x3203,
+ 0x7926, 0x1624,
+ 0x7927, 0x3205,
+ 0x7929, 0x3208,
+ 0x792a, 0x1625,
+ 0x792b, 0x1627,
+ 0x792c, 0x1626,
+ 0x792d, 0x32e6,
+ 0x792e, 0x42f0,
+ 0x792f, 0x32e8,
+ 0x7931, 0x32e7,
+ 0x7932, 0x471b,
+ 0x7933, 0x471a,
+ 0x7934, 0x42f3,
+ 0x7935, 0x3397,
+ 0x7936, 0x3783,
+ 0x7938, 0x3490,
+ 0x7939, 0x34d5,
+ 0x793a, 0x036a,
+ 0x793b, 0x44f7,
+ 0x793c, 0x4300,
+ 0x793d, 0x18d7,
+ 0x793e, 0x065f,
+ 0x793f, 0x1a20,
+ 0x7940, 0x0660,
+ 0x7942, 0x1a1f,
+ 0x7944, 0x1baf,
+ 0x7945, 0x1bae,
+ 0x7946, 0x07bf,
+ 0x7947, 0x07c2,
+ 0x7948, 0x07c1,
+ 0x7949, 0x07c0,
+ 0x794a, 0x1bab,
+ 0x794b, 0x1bad,
+ 0x794c, 0x1bac,
+ 0x794f, 0x1d76,
+ 0x7950, 0x0956,
+ 0x7951, 0x1d7a,
+ 0x7952, 0x1d79,
+ 0x7953, 0x1d78,
+ 0x7954, 0x1d74,
+ 0x7955, 0x0955,
+ 0x7956, 0x0959,
+ 0x7957, 0x095c,
+ 0x7958, 0x37e5,
+ 0x7959, 0x3b18,
+ 0x795a, 0x095d,
+ 0x795b, 0x1d75,
+ 0x795c, 0x1d77,
+ 0x795d, 0x095b,
+ 0x795e, 0x095a,
+ 0x795f, 0x0958,
+ 0x7960, 0x0957,
+ 0x7961, 0x1fc4,
+ 0x7962, 0x3e7d,
+ 0x7963, 0x1fc2,
+ 0x7964, 0x1fbe,
+ 0x7965, 0x0b42,
+ 0x7967, 0x1fbf,
+ 0x7968, 0x0b43,
+ 0x7969, 0x1fc0,
+ 0x796b, 0x1fc3,
+ 0x796d, 0x0b44,
+ 0x7970, 0x224a,
+ 0x7971, 0x4168,
+ 0x7972, 0x2249,
+ 0x7973, 0x2248,
+ 0x7974, 0x2247,
+ 0x7979, 0x24df,
+ 0x797a, 0x0ea9,
+ 0x797c, 0x24dc,
+ 0x797d, 0x24de,
+ 0x797e, 0x3e26,
+ 0x797f, 0x0eaa,
+ 0x7980, 0x42fc,
+ 0x7981, 0x0eab,
+ 0x7982, 0x24dd,
+ 0x7983, 0x3df6,
+ 0x7986, 0x42f9,
+ 0x7987, 0x4588,
+ 0x7988, 0x275d,
+ 0x798a, 0x2756,
+ 0x798d, 0x1046,
+ 0x798e, 0x1044,
+ 0x7990, 0x275f,
+ 0x7991, 0x471d,
+ 0x7992, 0x275e,
+ 0x7993, 0x275b,
+ 0x7994, 0x275a,
+ 0x7995, 0x2759,
+ 0x7996, 0x2758,
+ 0x7997, 0x275c,
+ 0x7998, 0x2755,
+ 0x7999, 0x43fc,
+ 0x799a, 0x299c,
+ 0x799b, 0x29a1,
+ 0x799c, 0x299f,
+ 0x799d, 0x42fe,
+ 0x799f, 0x395e,
+ 0x79a0, 0x299e,
+ 0x79a1, 0x299d,
+ 0x79a2, 0x29a0,
+ 0x79a4, 0x2bf5,
+ 0x79a5, 0x3b1e,
+ 0x79a6, 0x130f,
+ 0x79a7, 0x1424,
+ 0x79a8, 0x2dce,
+ 0x79a9, 0x4301,
+ 0x79aa, 0x1425,
+ 0x79ab, 0x2dcd,
+ 0x79ac, 0x2f74,
+ 0x79ad, 0x2f73,
+ 0x79ae, 0x14ff,
+ 0x79b0, 0x30d0,
+ 0x79b1, 0x15a0,
+ 0x79b2, 0x3209,
+ 0x79b3, 0x16cf,
+ 0x79b4, 0x3398,
+ 0x79b6, 0x3492,
+ 0x79b7, 0x3491,
+ 0x79b8, 0x17b2,
+ 0x79b9, 0x07c3,
+ 0x79bb, 0x1fc5,
+ 0x79bd, 0x0ead,
+ 0x79be, 0x036b,
+ 0x79bf, 0x04f9,
+ 0x79c0, 0x04f8,
+ 0x79c1, 0x04f7,
+ 0x79c4, 0x3ccd,
+ 0x79c5, 0x1a21,
+ 0x79c6, 0x4305,
+ 0x79c8, 0x0663,
+ 0x79c9, 0x0662,
+ 0x79cb, 0x07c7,
+ 0x79cc, 0x4233,
+ 0x79cd, 0x1bb1,
+ 0x79ce, 0x1bb4,
+ 0x79cf, 0x1bb2,
+ 0x79d1, 0x07c5,
+ 0x79d4, 0x4307,
+ 0x79d5, 0x1bb0,
+ 0x79d6, 0x1bb3,
+ 0x79d8, 0x0964,
+ 0x79dc, 0x1d81,
+ 0x79dd, 0x1d83,
+ 0x79de, 0x1d82,
+ 0x79df, 0x0961,
+ 0x79e0, 0x1d7d,
+ 0x79e2, 0x3c5a,
+ 0x79e3, 0x095f,
+ 0x79e4, 0x095e,
+ 0x79e6, 0x0962,
+ 0x79e7, 0x0960,
+ 0x79e9, 0x0963,
+ 0x79ea, 0x1d80,
+ 0x79eb, 0x1d7b,
+ 0x79ed, 0x1d7f,
+ 0x79ee, 0x1d7e,
+ 0x79f1, 0x3b27,
+ 0x79f4, 0x3b22,
+ 0x79f6, 0x1fc8,
+ 0x79f8, 0x1fc7,
+ 0x79fa, 0x1fc6,
+ 0x79fb, 0x0b45,
+ 0x7a00, 0x0cfd,
+ 0x7a02, 0x224b,
+ 0x7a03, 0x224d,
+ 0x7a04, 0x224f,
+ 0x7a05, 0x0cfc,
+ 0x7a06, 0x471e,
+ 0x7a08, 0x0cfa,
+ 0x7a0a, 0x224c,
+ 0x7a0b, 0x0cfb,
+ 0x7a0c, 0x224e,
+ 0x7a0d, 0x0cf9,
+ 0x7a10, 0x24e9,
+ 0x7a11, 0x24e0,
+ 0x7a12, 0x24e3,
+ 0x7a13, 0x24e7,
+ 0x7a14, 0x0eb1,
+ 0x7a15, 0x24e5,
+ 0x7a17, 0x24e4,
+ 0x7a18, 0x24e1,
+ 0x7a1a, 0x0eaf,
+ 0x7a1b, 0x24e8,
+ 0x7a1c, 0x0eae,
+ 0x7a1e, 0x0eb3,
+ 0x7a1f, 0x0eb2,
+ 0x7a20, 0x0eb0,
+ 0x7a22, 0x24e6,
+ 0x7a26, 0x2765,
+ 0x7a28, 0x2764,
+ 0x7a2b, 0x2760,
+ 0x7a2d, 0x3fda,
+ 0x7a2e, 0x1047,
+ 0x7a2f, 0x2763,
+ 0x7a30, 0x2762,
+ 0x7a31, 0x1048,
+ 0x7a37, 0x11c7,
+ 0x7a39, 0x29a3,
+ 0x7a3a, 0x3b21,
+ 0x7a3b, 0x11c8,
+ 0x7a3c, 0x11c4,
+ 0x7a3d, 0x11c6,
+ 0x7a3e, 0x3f8b,
+ 0x7a3f, 0x11c3,
+ 0x7a40, 0x11c5,
+ 0x7a43, 0x396c,
+ 0x7a44, 0x2bf6,
+ 0x7a45, 0x3df1,
+ 0x7a46, 0x1312,
+ 0x7a47, 0x2bf8,
+ 0x7a48, 0x2bf7,
+ 0x7a49, 0x3733,
+ 0x7a4a, 0x2761,
+ 0x7a4b, 0x1314,
+ 0x7a4c, 0x1313,
+ 0x7a4d, 0x1310,
+ 0x7a54, 0x2dd3,
+ 0x7a56, 0x2dd1,
+ 0x7a57, 0x1426,
+ 0x7a58, 0x2dd2,
+ 0x7a5a, 0x2dd4,
+ 0x7a5b, 0x2dd0,
+ 0x7a5c, 0x2dcf,
+ 0x7a5f, 0x2f75,
+ 0x7a60, 0x1502,
+ 0x7a61, 0x1500,
+ 0x7a65, 0x3736,
+ 0x7a67, 0x30d1,
+ 0x7a69, 0x15a2,
+ 0x7a6b, 0x15a1,
+ 0x7a6c, 0x320b,
+ 0x7a6e, 0x320a,
+ 0x7a70, 0x3399,
+ 0x7a74, 0x036c,
+ 0x7a75, 0x1811,
+ 0x7a76, 0x04fa,
+ 0x7a78, 0x1a22,
+ 0x7a79, 0x0665,
+ 0x7a7a, 0x0664,
+ 0x7a7b, 0x1a23,
+ 0x7a7d, 0x3737,
+ 0x7a7e, 0x1bb6,
+ 0x7a7f, 0x07c8,
+ 0x7a80, 0x1bb5,
+ 0x7a81, 0x07c9,
+ 0x7a83, 0x3d7d,
+ 0x7a84, 0x0965,
+ 0x7a85, 0x1d86,
+ 0x7a86, 0x1d84,
+ 0x7a87, 0x1d8a,
+ 0x7a88, 0x0966,
+ 0x7a89, 0x1d85,
+ 0x7a8a, 0x1d89,
+ 0x7a8b, 0x1d87,
+ 0x7a8f, 0x1fca,
+ 0x7a90, 0x1fcc,
+ 0x7a91, 0x43d8,
+ 0x7a92, 0x0b46,
+ 0x7a94, 0x1fcb,
+ 0x7a95, 0x0b47,
+ 0x7a96, 0x0d00,
+ 0x7a97, 0x0cff,
+ 0x7a98, 0x0cfe,
+ 0x7a99, 0x2250,
+ 0x7a9e, 0x24ec,
+ 0x7a9f, 0x0eb4,
+ 0x7aa2, 0x24eb,
+ 0x7aa3, 0x24ea,
+ 0x7aa8, 0x2766,
+ 0x7aa9, 0x104a,
+ 0x7aaa, 0x1049,
+ 0x7aab, 0x2767,
+ 0x7aae, 0x11ca,
+ 0x7aaf, 0x11c9,
+ 0x7ab0, 0x373a,
+ 0x7ab1, 0x2bfc,
+ 0x7ab2, 0x29a4,
+ 0x7ab3, 0x29a6,
+ 0x7ab4, 0x29a5,
+ 0x7ab5, 0x2bfb,
+ 0x7ab6, 0x2bf9,
+ 0x7ab7, 0x2bfd,
+ 0x7ab8, 0x2bfa,
+ 0x7aba, 0x1315,
+ 0x7abb, 0x3739,
+ 0x7abc, 0x4721,
+ 0x7abe, 0x2dd5,
+ 0x7abf, 0x1427,
+ 0x7ac0, 0x2dd6,
+ 0x7ac2, 0x373b,
+ 0x7ac4, 0x1503,
+ 0x7ac7, 0x1628,
+ 0x7ac8, 0x3d7f,
+ 0x7ac9, 0x4570,
+ 0x7aca, 0x16ff,
+ 0x7acb, 0x036d,
+ 0x7acf, 0x4724,
+ 0x7ad1, 0x1bb7,
+ 0x7ad3, 0x3f8a,
+ 0x7ad8, 0x1d8b,
+ 0x7ad9, 0x0967,
+ 0x7ada, 0x3740,
+ 0x7adb, 0x4725,
+ 0x7adc, 0x3951,
+ 0x7add, 0x3741,
+ 0x7adf, 0x0bde,
+ 0x7ae0, 0x0bdd,
+ 0x7ae2, 0x3b33,
+ 0x7ae3, 0x0d02,
+ 0x7ae4, 0x2252,
+ 0x7ae5, 0x0d01,
+ 0x7ae6, 0x2251,
+ 0x7ae7, 0x385d,
+ 0x7ae9, 0x3831,
+ 0x7aea, 0x3742,
+ 0x7aeb, 0x24ed,
+ 0x7aed, 0x104b,
+ 0x7aee, 0x2769,
+ 0x7aef, 0x104c,
+ 0x7af6, 0x1629,
+ 0x7af7, 0x320d,
+ 0x7af9, 0x03f6,
+ 0x7afa, 0x0666,
+ 0x7afb, 0x1a24,
+ 0x7afd, 0x07cb,
+ 0x7afe, 0x3b3d,
+ 0x7aff, 0x07ca,
+ 0x7b00, 0x1bb8,
+ 0x7b04, 0x1d8d,
+ 0x7b05, 0x1d8f,
+ 0x7b06, 0x0968,
+ 0x7b08, 0x1d91,
+ 0x7b09, 0x1d94,
+ 0x7b0a, 0x1d92,
+ 0x7b0b, 0x3746,
+ 0x7b0c, 0x3b63,
+ 0x7b0e, 0x1d93,
+ 0x7b0f, 0x1d90,
+ 0x7b10, 0x1d8c,
+ 0x7b11, 0x0969,
+ 0x7b12, 0x1d95,
+ 0x7b13, 0x1d8e,
+ 0x7b14, 0x3f77,
+ 0x7b18, 0x1fd5,
+ 0x7b19, 0x0b4d,
+ 0x7b1a, 0x1fde,
+ 0x7b1b, 0x0b4a,
+ 0x7b1d, 0x1fd7,
+ 0x7b1e, 0x0b4e,
+ 0x7b1f, 0x3f11,
+ 0x7b20, 0x0b48,
+ 0x7b22, 0x1fd2,
+ 0x7b23, 0x1fdf,
+ 0x7b24, 0x1fd3,
+ 0x7b25, 0x1fd0,
+ 0x7b26, 0x0b4c,
+ 0x7b27, 0x3b5f,
+ 0x7b28, 0x0b49,
+ 0x7b29, 0x3748,
+ 0x7b2a, 0x1fd6,
+ 0x7b2b, 0x1fd9,
+ 0x7b2c, 0x0b4b,
+ 0x7b2d, 0x1fda,
+ 0x7b2e, 0x0b4f,
+ 0x7b2f, 0x1fdb,
+ 0x7b30, 0x1fd1,
+ 0x7b31, 0x1fd8,
+ 0x7b32, 0x1fdc,
+ 0x7b33, 0x1fd4,
+ 0x7b34, 0x1fcf,
+ 0x7b35, 0x1fcd,
+ 0x7b38, 0x1fdd,
+ 0x7b39, 0x3d6e,
+ 0x7b3b, 0x1fce,
+ 0x7b40, 0x2259,
+ 0x7b42, 0x3ded,
+ 0x7b43, 0x3e25,
+ 0x7b44, 0x2255,
+ 0x7b45, 0x225b,
+ 0x7b46, 0x0d05,
+ 0x7b47, 0x2254,
+ 0x7b48, 0x2256,
+ 0x7b49, 0x0d03,
+ 0x7b4a, 0x2253,
+ 0x7b4b, 0x0d0a,
+ 0x7b4c, 0x2257,
+ 0x7b4d, 0x0d09,
+ 0x7b4e, 0x2258,
+ 0x7b4f, 0x0d0b,
+ 0x7b50, 0x0d06,
+ 0x7b51, 0x0d0c,
+ 0x7b52, 0x0d07,
+ 0x7b54, 0x0d08,
+ 0x7b55, 0x3747,
+ 0x7b56, 0x0d04,
+ 0x7b58, 0x225a,
+ 0x7b60, 0x0eb8,
+ 0x7b61, 0x24f8,
+ 0x7b62, 0x4727,
+ 0x7b63, 0x24fb,
+ 0x7b64, 0x24ef,
+ 0x7b65, 0x24f4,
+ 0x7b66, 0x24ee,
+ 0x7b67, 0x0eba,
+ 0x7b69, 0x24f2,
+ 0x7b6c, 0x4728,
+ 0x7b6d, 0x24f0,
+ 0x7b6e, 0x0eb9,
+ 0x7b6f, 0x374c,
+ 0x7b70, 0x24f7,
+ 0x7b71, 0x24f6,
+ 0x7b72, 0x24f3,
+ 0x7b73, 0x24f5,
+ 0x7b74, 0x24f1,
+ 0x7b75, 0x1050,
+ 0x7b76, 0x24fa,
+ 0x7b77, 0x0eb6,
+ 0x7b78, 0x24f9,
+ 0x7b7b, 0x4729,
+ 0x7b82, 0x2779,
+ 0x7b84, 0x1057,
+ 0x7b85, 0x2774,
+ 0x7b87, 0x1056,
+ 0x7b88, 0x276a,
+ 0x7b8a, 0x276c,
+ 0x7b8b, 0x104f,
+ 0x7b8c, 0x2771,
+ 0x7b8d, 0x2770,
+ 0x7b8e, 0x2773,
+ 0x7b8f, 0x1054,
+ 0x7b90, 0x276e,
+ 0x7b91, 0x276d,
+ 0x7b92, 0x3752,
+ 0x7b94, 0x1053,
+ 0x7b95, 0x104e,
+ 0x7b96, 0x276f,
+ 0x7b97, 0x1051,
+ 0x7b98, 0x2775,
+ 0x7b99, 0x2777,
+ 0x7b9b, 0x2772,
+ 0x7b9c, 0x276b,
+ 0x7b9d, 0x1052,
+ 0x7ba0, 0x11d2,
+ 0x7ba1, 0x104d,
+ 0x7ba2, 0x374b,
+ 0x7ba3, 0x3f14,
+ 0x7ba4, 0x2778,
+ 0x7bac, 0x29aa,
+ 0x7bad, 0x11cb,
+ 0x7baf, 0x29ac,
+ 0x7bb1, 0x11cc,
+ 0x7bb2, 0x461c,
+ 0x7bb4, 0x11ce,
+ 0x7bb5, 0x29af,
+ 0x7bb7, 0x29a7,
+ 0x7bb8, 0x1055,
+ 0x7bb9, 0x29ad,
+ 0x7bbe, 0x29a9,
+ 0x7bc0, 0x0eb7,
+ 0x7bc1, 0x11d1,
+ 0x7bc4, 0x11cd,
+ 0x7bc6, 0x11cf,
+ 0x7bc9, 0x1318,
+ 0x7bca, 0x29ae,
+ 0x7bcb, 0x29a8,
+ 0x7bcc, 0x11d3,
+ 0x7bce, 0x29ab,
+ 0x7bcf, 0x3f18,
+ 0x7bd0, 0x3750,
+ 0x7bd4, 0x2c07,
+ 0x7bd5, 0x2c02,
+ 0x7bd8, 0x2c0c,
+ 0x7bd9, 0x1316,
+ 0x7bda, 0x2c04,
+ 0x7bdb, 0x131a,
+ 0x7bdc, 0x2c0a,
+ 0x7bdd, 0x2c01,
+ 0x7bde, 0x2bfe,
+ 0x7bdf, 0x2c0d,
+ 0x7be0, 0x142d,
+ 0x7be1, 0x131b,
+ 0x7be2, 0x2c09,
+ 0x7be3, 0x2bff,
+ 0x7be4, 0x1319,
+ 0x7be5, 0x2c03,
+ 0x7be6, 0x131d,
+ 0x7be7, 0x2c00,
+ 0x7be8, 0x2c05,
+ 0x7be9, 0x131c,
+ 0x7bea, 0x2c08,
+ 0x7beb, 0x2c0b,
+ 0x7bf0, 0x2de9,
+ 0x7bf2, 0x2dda,
+ 0x7bf3, 0x2de1,
+ 0x7bf4, 0x2ddf,
+ 0x7bf7, 0x142b,
+ 0x7bf8, 0x2de6,
+ 0x7bf9, 0x2c06,
+ 0x7bfa, 0x3757,
+ 0x7bfb, 0x2ddd,
+ 0x7bfc, 0x3f1f,
+ 0x7bfd, 0x2de7,
+ 0x7bfe, 0x142a,
+ 0x7bff, 0x2ddc,
+ 0x7c00, 0x2ddb,
+ 0x7c01, 0x2de5,
+ 0x7c02, 0x2de2,
+ 0x7c03, 0x2de4,
+ 0x7c05, 0x2dd8,
+ 0x7c06, 0x2de8,
+ 0x7c07, 0x1428,
+ 0x7c09, 0x2de3,
+ 0x7c0a, 0x2dec,
+ 0x7c0b, 0x2de0,
+ 0x7c0c, 0x142c,
+ 0x7c0d, 0x1429,
+ 0x7c0e, 0x2dde,
+ 0x7c0f, 0x2dd9,
+ 0x7c10, 0x2deb,
+ 0x7c11, 0x1317,
+ 0x7c12, 0x472a,
+ 0x7c15, 0x4061,
+ 0x7c19, 0x2f78,
+ 0x7c1b, 0x43d9,
+ 0x7c1c, 0x2f76,
+ 0x7c1d, 0x2f7c,
+ 0x7c1e, 0x1508,
+ 0x7c1f, 0x2f7a,
+ 0x7c20, 0x2f79,
+ 0x7c21, 0x150a,
+ 0x7c22, 0x2f7f,
+ 0x7c23, 0x1509,
+ 0x7c25, 0x2f80,
+ 0x7c26, 0x2f7d,
+ 0x7c27, 0x1506,
+ 0x7c28, 0x2f7e,
+ 0x7c29, 0x2f77,
+ 0x7c2a, 0x1507,
+ 0x7c2b, 0x1505,
+ 0x7c2c, 0x30d6,
+ 0x7c2d, 0x2f7b,
+ 0x7c30, 0x2f81,
+ 0x7c33, 0x30d3,
+ 0x7c35, 0x3759,
+ 0x7c37, 0x15a7,
+ 0x7c38, 0x15a5,
+ 0x7c39, 0x30d5,
+ 0x7c3b, 0x30d7,
+ 0x7c3c, 0x30d4,
+ 0x7c3d, 0x15a6,
+ 0x7c3e, 0x15a3,
+ 0x7c40, 0x15a8,
+ 0x7c42, 0x3f1c,
+ 0x7c43, 0x162b,
+ 0x7c44, 0x375b,
+ 0x7c45, 0x3212,
+ 0x7c47, 0x3211,
+ 0x7c48, 0x320f,
+ 0x7c49, 0x320e,
+ 0x7c4a, 0x3210,
+ 0x7c4c, 0x162a,
+ 0x7c4d, 0x162c,
+ 0x7c50, 0x1681,
+ 0x7c51, 0x3fb8,
+ 0x7c53, 0x32ea,
+ 0x7c54, 0x32e9,
+ 0x7c56, 0x3eff,
+ 0x7c57, 0x339b,
+ 0x7c59, 0x339d,
+ 0x7c5a, 0x339f,
+ 0x7c5b, 0x339e,
+ 0x7c5c, 0x339c,
+ 0x7c5d, 0x3b3f,
+ 0x7c5f, 0x16d1,
+ 0x7c60, 0x16d0,
+ 0x7c63, 0x1701,
+ 0x7c64, 0x1700,
+ 0x7c65, 0x1702,
+ 0x7c66, 0x342b,
+ 0x7c67, 0x342a,
+ 0x7c69, 0x34d6,
+ 0x7c6a, 0x3493,
+ 0x7c6b, 0x34d7,
+ 0x7c6c, 0x1745,
+ 0x7c6d, 0x3b40,
+ 0x7c6e, 0x1746,
+ 0x7c6f, 0x3507,
+ 0x7c70, 0x3f52,
+ 0x7c72, 0x176b,
+ 0x7c73, 0x03f7,
+ 0x7c74, 0x469c,
+ 0x7c75, 0x1a25,
+ 0x7c78, 0x1bbb,
+ 0x7c7a, 0x1bba,
+ 0x7c7b, 0x472d,
+ 0x7c7c, 0x3b49,
+ 0x7c7d, 0x07cc,
+ 0x7c7e, 0x3f1a,
+ 0x7c7f, 0x1bbd,
+ 0x7c83, 0x375c,
+ 0x7c84, 0x1d96,
+ 0x7c85, 0x1d9c,
+ 0x7c86, 0x3f1d,
+ 0x7c88, 0x1d9a,
+ 0x7c89, 0x096a,
+ 0x7c8a, 0x1d98,
+ 0x7c8c, 0x1d99,
+ 0x7c8d, 0x1d9b,
+ 0x7c8e, 0x3b48,
+ 0x7c91, 0x1d97,
+ 0x7c92, 0x0b50,
+ 0x7c94, 0x1fe0,
+ 0x7c95, 0x0b52,
+ 0x7c96, 0x1fe2,
+ 0x7c97, 0x0b51,
+ 0x7c98, 0x1fe1,
+ 0x7c9c, 0x472e,
+ 0x7c9e, 0x225d,
+ 0x7c9f, 0x0d0d,
+ 0x7ca1, 0x225f,
+ 0x7ca2, 0x225c,
+ 0x7ca3, 0x1fe3,
+ 0x7ca5, 0x0d0e,
+ 0x7ca6, 0x375e,
+ 0x7ca7, 0x36ed,
+ 0x7ca8, 0x225e,
+ 0x7cac, 0x3885,
+ 0x7cae, 0x3b4a,
+ 0x7caf, 0x24fe,
+ 0x7cb1, 0x0ebb,
+ 0x7cb2, 0x24fc,
+ 0x7cb3, 0x0ebc,
+ 0x7cb4, 0x24fd,
+ 0x7cb5, 0x0ebd,
+ 0x7cb8, 0x4730,
+ 0x7cb9, 0x1058,
+ 0x7cba, 0x277d,
+ 0x7cbb, 0x277a,
+ 0x7cbc, 0x277c,
+ 0x7cbd, 0x1059,
+ 0x7cbf, 0x277b,
+ 0x7cc2, 0x3fd7,
+ 0x7cc5, 0x29b0,
+ 0x7cc7, 0x3761,
+ 0x7cc8, 0x29b1,
+ 0x7cc9, 0x3760,
+ 0x7cca, 0x11d4,
+ 0x7ccb, 0x29b3,
+ 0x7ccc, 0x29b2,
+ 0x7ccd, 0x3b45,
+ 0x7cce, 0x0121,
+ 0x7cd0, 0x2c11,
+ 0x7cd2, 0x2c0e,
+ 0x7cd3, 0x3d5c,
+ 0x7cd4, 0x2c0f,
+ 0x7cd5, 0x131e,
+ 0x7cd7, 0x2c10,
+ 0x7cd9, 0x1433,
+ 0x7cda, 0x3fd9,
+ 0x7cdc, 0x142f,
+ 0x7cdd, 0x1434,
+ 0x7cde, 0x1430,
+ 0x7cdf, 0x1432,
+ 0x7ce0, 0x142e,
+ 0x7ce2, 0x1431,
+ 0x7ce6, 0x3762,
+ 0x7ce7, 0x150b,
+ 0x7ce8, 0x2ded,
+ 0x7cea, 0x30d9,
+ 0x7cec, 0x30d8,
+ 0x7ced, 0x43da,
+ 0x7cee, 0x3213,
+ 0x7cef, 0x162d,
+ 0x7cf1, 0x33a1,
+ 0x7cf2, 0x32eb,
+ 0x7cf3, 0x3764,
+ 0x7cf4, 0x33a0,
+ 0x7cf5, 0x3765,
+ 0x7cf6, 0x34d8,
+ 0x7cf7, 0x351d,
+ 0x7cf8, 0x03f8,
+ 0x7cf9, 0x44f8,
+ 0x7cfb, 0x04fb,
+ 0x7cfc, 0x456d,
+ 0x7cfd, 0x1a26,
+ 0x7cfe, 0x0667,
+ 0x7d00, 0x07cf,
+ 0x7d01, 0x1bc2,
+ 0x7d02, 0x07cd,
+ 0x7d03, 0x1bc0,
+ 0x7d04, 0x07d2,
+ 0x7d05, 0x07ce,
+ 0x7d06, 0x07d3,
+ 0x7d07, 0x07d1,
+ 0x7d08, 0x1bc1,
+ 0x7d09, 0x07d0,
+ 0x7d0a, 0x096e,
+ 0x7d0b, 0x096d,
+ 0x7d0c, 0x1da7,
+ 0x7d0d, 0x0976,
+ 0x7d0e, 0x1da0,
+ 0x7d0f, 0x1da6,
+ 0x7d10, 0x0972,
+ 0x7d11, 0x1d9f,
+ 0x7d12, 0x1da5,
+ 0x7d13, 0x1da3,
+ 0x7d14, 0x0971,
+ 0x7d15, 0x0973,
+ 0x7d16, 0x1da2,
+ 0x7d17, 0x096c,
+ 0x7d18, 0x1da1,
+ 0x7d19, 0x0977,
+ 0x7d1a, 0x0974,
+ 0x7d1b, 0x0978,
+ 0x7d1c, 0x0975,
+ 0x7d1d, 0x1d9e,
+ 0x7d1e, 0x1d9d,
+ 0x7d1f, 0x1da4,
+ 0x7d20, 0x096f,
+ 0x7d21, 0x096b,
+ 0x7d22, 0x0970,
+ 0x7d25, 0x3ede,
+ 0x7d28, 0x1ff2,
+ 0x7d29, 0x1feb,
+ 0x7d2b, 0x0d13,
+ 0x7d2c, 0x1fea,
+ 0x7d2e, 0x0b56,
+ 0x7d2f, 0x0b5d,
+ 0x7d30, 0x0b5a,
+ 0x7d31, 0x0b60,
+ 0x7d32, 0x0b5f,
+ 0x7d33, 0x0b5b,
+ 0x7d35, 0x1fe4,
+ 0x7d36, 0x1fe7,
+ 0x7d38, 0x1fe6,
+ 0x7d39, 0x0b57,
+ 0x7d3a, 0x1fe8,
+ 0x7d3b, 0x1ff1,
+ 0x7d3c, 0x0b58,
+ 0x7d3d, 0x1fe5,
+ 0x7d3e, 0x1fee,
+ 0x7d40, 0x0b59,
+ 0x7d41, 0x1fec,
+ 0x7d42, 0x0b5e,
+ 0x7d43, 0x0b54,
+ 0x7d44, 0x0b5c,
+ 0x7d45, 0x1fe9,
+ 0x7d46, 0x0b53,
+ 0x7d47, 0x1fed,
+ 0x7d4a, 0x1ff0,
+ 0x7d4d, 0x3fdd,
+ 0x7d4e, 0x2270,
+ 0x7d4f, 0x2267,
+ 0x7d50, 0x0d10,
+ 0x7d51, 0x226e,
+ 0x7d52, 0x226b,
+ 0x7d53, 0x2263,
+ 0x7d54, 0x226c,
+ 0x7d55, 0x0d12,
+ 0x7d56, 0x2264,
+ 0x7d58, 0x2260,
+ 0x7d5a, 0x3e93,
+ 0x7d5b, 0x0ec3,
+ 0x7d5c, 0x2269,
+ 0x7d5d, 0x3769,
+ 0x7d5e, 0x0d0f,
+ 0x7d5f, 0x226f,
+ 0x7d61, 0x0d16,
+ 0x7d62, 0x0d18,
+ 0x7d63, 0x2262,
+ 0x7d66, 0x0d17,
+ 0x7d67, 0x2265,
+ 0x7d68, 0x0d11,
+ 0x7d69, 0x226d,
+ 0x7d6a, 0x2266,
+ 0x7d6b, 0x226a,
+ 0x7d6d, 0x2268,
+ 0x7d6e, 0x0d14,
+ 0x7d6f, 0x2261,
+ 0x7d70, 0x0d19,
+ 0x7d71, 0x0b55,
+ 0x7d72, 0x0d15,
+ 0x7d73, 0x0d1a,
+ 0x7d79, 0x0ebf,
+ 0x7d7a, 0x2505,
+ 0x7d7b, 0x2507,
+ 0x7d7c, 0x2509,
+ 0x7d7d, 0x250d,
+ 0x7d7f, 0x2503,
+ 0x7d80, 0x2501,
+ 0x7d81, 0x0ec1,
+ 0x7d83, 0x2508,
+ 0x7d84, 0x250c,
+ 0x7d85, 0x2504,
+ 0x7d86, 0x2500,
+ 0x7d88, 0x24ff,
+ 0x7d89, 0x376b,
+ 0x7d8c, 0x250a,
+ 0x7d8d, 0x2502,
+ 0x7d8e, 0x2506,
+ 0x7d8f, 0x0ec2,
+ 0x7d91, 0x0ec0,
+ 0x7d92, 0x250e,
+ 0x7d93, 0x0ebe,
+ 0x7d94, 0x250b,
+ 0x7d96, 0x278e,
+ 0x7d97, 0x3b53,
+ 0x7d9c, 0x105d,
+ 0x7d9d, 0x2786,
+ 0x7d9e, 0x11e1,
+ 0x7d9f, 0x2790,
+ 0x7da0, 0x1060,
+ 0x7da1, 0x2794,
+ 0x7da2, 0x1066,
+ 0x7da3, 0x2781,
+ 0x7da4, 0x46d7,
+ 0x7da6, 0x2791,
+ 0x7da7, 0x277e,
+ 0x7da8, 0x3c9c,
+ 0x7da9, 0x2793,
+ 0x7daa, 0x2782,
+ 0x7dab, 0x376c,
+ 0x7dac, 0x106d,
+ 0x7dad, 0x106a,
+ 0x7dae, 0x2792,
+ 0x7daf, 0x278c,
+ 0x7db0, 0x105c,
+ 0x7db1, 0x1064,
+ 0x7db2, 0x1063,
+ 0x7db3, 0x376e,
+ 0x7db4, 0x1062,
+ 0x7db5, 0x1068,
+ 0x7db7, 0x277f,
+ 0x7db8, 0x1069,
+ 0x7db9, 0x278d,
+ 0x7dba, 0x1065,
+ 0x7dbb, 0x105b,
+ 0x7dbc, 0x278f,
+ 0x7dbd, 0x105e,
+ 0x7dbf, 0x1067,
+ 0x7dc0, 0x2784,
+ 0x7dc1, 0x2783,
+ 0x7dc2, 0x2780,
+ 0x7dc4, 0x2788,
+ 0x7dc5, 0x2785,
+ 0x7dc6, 0x2789,
+ 0x7dc7, 0x106c,
+ 0x7dc9, 0x2795,
+ 0x7dca, 0x1061,
+ 0x7dcb, 0x278a,
+ 0x7dcd, 0x456e,
+ 0x7dce, 0x2787,
+ 0x7dcf, 0x4735,
+ 0x7dd0, 0x4737,
+ 0x7dd2, 0x106b,
+ 0x7dd3, 0x3b4e,
+ 0x7dd4, 0x4736,
+ 0x7dd6, 0x376f,
+ 0x7dd7, 0x29b8,
+ 0x7dd8, 0x11d9,
+ 0x7dd9, 0x11e2,
+ 0x7dda, 0x11de,
+ 0x7ddb, 0x29b5,
+ 0x7ddc, 0x3b4c,
+ 0x7ddd, 0x11db,
+ 0x7dde, 0x11df,
+ 0x7ddf, 0x29c1,
+ 0x7de0, 0x11d5,
+ 0x7de1, 0x29b9,
+ 0x7de3, 0x11dd,
+ 0x7de4, 0x3772,
+ 0x7de5, 0x3776,
+ 0x7de6, 0x29bc,
+ 0x7de7, 0x29b7,
+ 0x7de8, 0x11dc,
+ 0x7de9, 0x11e0,
+ 0x7dea, 0x29b6,
+ 0x7dec, 0x11da,
+ 0x7dee, 0x29c0,
+ 0x7def, 0x11d7,
+ 0x7df0, 0x29bf,
+ 0x7df1, 0x29be,
+ 0x7df2, 0x11e3,
+ 0x7df3, 0x28c8,
+ 0x7df4, 0x11d6,
+ 0x7df5, 0x3774,
+ 0x7df6, 0x29bd,
+ 0x7df7, 0x29b4,
+ 0x7df9, 0x11e4,
+ 0x7dfa, 0x29bb,
+ 0x7dfb, 0x11d8,
+ 0x7dfd, 0x4738,
+ 0x7dfe, 0x3ccf,
+ 0x7e03, 0x29ba,
+ 0x7e07, 0x3b4d,
+ 0x7e08, 0x1322,
+ 0x7e09, 0x1327,
+ 0x7e0a, 0x1320,
+ 0x7e0b, 0x2c1f,
+ 0x7e0c, 0x2c16,
+ 0x7e0d, 0x2c22,
+ 0x7e0e, 0x2c1a,
+ 0x7e0f, 0x2c20,
+ 0x7e10, 0x1328,
+ 0x7e11, 0x1321,
+ 0x7e12, 0x2c13,
+ 0x7e13, 0x2c19,
+ 0x7e14, 0x2c23,
+ 0x7e15, 0x2c1c,
+ 0x7e16, 0x2c21,
+ 0x7e17, 0x2c15,
+ 0x7e1a, 0x2c1d,
+ 0x7e1b, 0x1323,
+ 0x7e1c, 0x2c1b,
+ 0x7e1d, 0x1326,
+ 0x7e1e, 0x1325,
+ 0x7e1f, 0x2c17,
+ 0x7e21, 0x2c14,
+ 0x7e22, 0x2c1e,
+ 0x7e23, 0x1324,
+ 0x7e24, 0x2c25,
+ 0x7e25, 0x2c24,
+ 0x7e27, 0x377f,
+ 0x7e29, 0x2df8,
+ 0x7e2a, 0x2df4,
+ 0x7e2b, 0x143b,
+ 0x7e2d, 0x2dee,
+ 0x7e2e, 0x1435,
+ 0x7e2f, 0x1445,
+ 0x7e30, 0x2dfa,
+ 0x7e31, 0x143d,
+ 0x7e32, 0x1439,
+ 0x7e33, 0x2df1,
+ 0x7e34, 0x1440,
+ 0x7e35, 0x1443,
+ 0x7e36, 0x2dfc,
+ 0x7e37, 0x1438,
+ 0x7e38, 0x2df3,
+ 0x7e39, 0x1441,
+ 0x7e3a, 0x2dfe,
+ 0x7e3b, 0x2dfb,
+ 0x7e3c, 0x2def,
+ 0x7e3d, 0x143c,
+ 0x7e3e, 0x1436,
+ 0x7e3f, 0x1444,
+ 0x7e40, 0x2df6,
+ 0x7e41, 0x143f,
+ 0x7e42, 0x2df0,
+ 0x7e43, 0x143a,
+ 0x7e44, 0x2dfd,
+ 0x7e45, 0x143e,
+ 0x7e46, 0x1437,
+ 0x7e47, 0x2df7,
+ 0x7e48, 0x1442,
+ 0x7e49, 0x2df5,
+ 0x7e4c, 0x2df9,
+ 0x7e50, 0x2f83,
+ 0x7e51, 0x2f89,
+ 0x7e52, 0x1511,
+ 0x7e53, 0x2f8c,
+ 0x7e54, 0x150c,
+ 0x7e56, 0x2f84,
+ 0x7e57, 0x2f8b,
+ 0x7e58, 0x2f86,
+ 0x7e59, 0x1512,
+ 0x7e5a, 0x150f,
+ 0x7e5c, 0x2f82,
+ 0x7e5e, 0x150e,
+ 0x7e5f, 0x2f88,
+ 0x7e60, 0x2f8a,
+ 0x7e61, 0x1510,
+ 0x7e62, 0x2f87,
+ 0x7e63, 0x2f85,
+ 0x7e65, 0x46d2,
+ 0x7e67, 0x3766,
+ 0x7e68, 0x30e3,
+ 0x7e69, 0x15ac,
+ 0x7e6b, 0x15a9,
+ 0x7e6d, 0x15aa,
+ 0x7e6e, 0x377b,
+ 0x7e6f, 0x30df,
+ 0x7e70, 0x30dd,
+ 0x7e72, 0x30e1,
+ 0x7e73, 0x15ae,
+ 0x7e74, 0x30e2,
+ 0x7e75, 0x30db,
+ 0x7e76, 0x30da,
+ 0x7e77, 0x30de,
+ 0x7e78, 0x30dc,
+ 0x7e79, 0x15ab,
+ 0x7e7a, 0x30e0,
+ 0x7e7b, 0x3214,
+ 0x7e7c, 0x1631,
+ 0x7e7d, 0x1630,
+ 0x7e7e, 0x3215,
+ 0x7e7f, 0x3e51,
+ 0x7e80, 0x3217,
+ 0x7e81, 0x3216,
+ 0x7e82, 0x1632,
+ 0x7e86, 0x32f0,
+ 0x7e87, 0x32ed,
+ 0x7e8a, 0x32ec,
+ 0x7e8b, 0x32ef,
+ 0x7e8c, 0x1683,
+ 0x7e8d, 0x32f1,
+ 0x7e8e, 0x3ec9,
+ 0x7e8f, 0x1682,
+ 0x7e91, 0x33a2,
+ 0x7e92, 0x469e,
+ 0x7e93, 0x1703,
+ 0x7e94, 0x1705,
+ 0x7e95, 0x342c,
+ 0x7e96, 0x1704,
+ 0x7e97, 0x3494,
+ 0x7e98, 0x34da,
+ 0x7e99, 0x34dc,
+ 0x7e9a, 0x34d9,
+ 0x7e9b, 0x34db,
+ 0x7e9c, 0x1759,
+ 0x7e9f, 0x48bb,
+ 0x7ea4, 0x455b,
+ 0x7eac, 0x455c,
+ 0x7eba, 0x455d,
+ 0x7ec7, 0x455e,
+ 0x7ecf, 0x455f,
+ 0x7edf, 0x4560,
+ 0x7f06, 0x4561,
+ 0x7f36, 0x03f9,
+ 0x7f37, 0x4562,
+ 0x7f38, 0x07d4,
+ 0x7f39, 0x1d1f,
+ 0x7f3a, 0x0979,
+ 0x7f3d, 0x0b61,
+ 0x7f3e, 0x2271,
+ 0x7f40, 0x3780,
+ 0x7f43, 0x2c26,
+ 0x7f44, 0x1446,
+ 0x7f45, 0x2dff,
+ 0x7f47, 0x3782,
+ 0x7f48, 0x1513,
+ 0x7f49, 0x3e69,
+ 0x7f4a, 0x30e5,
+ 0x7f4b, 0x30e4,
+ 0x7f4c, 0x1633,
+ 0x7f4d, 0x32f2,
+ 0x7f4e, 0x3b4f,
+ 0x7f4f, 0x33a3,
+ 0x7f50, 0x1726,
+ 0x7f51, 0x1812,
+ 0x7f52, 0x44f6,
+ 0x7f53, 0x44f9,
+ 0x7f54, 0x0668,
+ 0x7f55, 0x04fc,
+ 0x7f58, 0x1bc3,
+ 0x7f5b, 0x1dad,
+ 0x7f5c, 0x1da8,
+ 0x7f5d, 0x1dac,
+ 0x7f5e, 0x1daa,
+ 0x7f5f, 0x097a,
+ 0x7f60, 0x1dab,
+ 0x7f61, 0x1da9,
+ 0x7f63, 0x1ff3,
+ 0x7f65, 0x2273,
+ 0x7f67, 0x2511,
+ 0x7f69, 0x0ec5,
+ 0x7f6b, 0x2510,
+ 0x7f6c, 0x2513,
+ 0x7f6d, 0x250f,
+ 0x7f6e, 0x0ec4,
+ 0x7f70, 0x106e,
+ 0x7f71, 0x4007,
+ 0x7f72, 0x0ec7,
+ 0x7f73, 0x2796,
+ 0x7f75, 0x11e5,
+ 0x7f76, 0x29c2,
+ 0x7f77, 0x11e6,
+ 0x7f78, 0x3f7b,
+ 0x7f79, 0x1329,
+ 0x7f7a, 0x2c29,
+ 0x7f7b, 0x2c27,
+ 0x7f7d, 0x2e02,
+ 0x7f7e, 0x2e01,
+ 0x7f7f, 0x2e00,
+ 0x7f83, 0x30e6,
+ 0x7f85, 0x15af,
+ 0x7f86, 0x30e7,
+ 0x7f87, 0x33a4,
+ 0x7f88, 0x1727,
+ 0x7f89, 0x3495,
+ 0x7f8a, 0x03fa,
+ 0x7f8b, 0x066a,
+ 0x7f8c, 0x0669,
+ 0x7f8d, 0x1bc5,
+ 0x7f8e, 0x07d5,
+ 0x7f8f, 0x421c,
+ 0x7f91, 0x1bc4,
+ 0x7f92, 0x1daf,
+ 0x7f93, 0x43db,
+ 0x7f94, 0x097b,
+ 0x7f95, 0x1ff4,
+ 0x7f96, 0x1dae,
+ 0x7f97, 0x3786,
+ 0x7f9a, 0x0b63,
+ 0x7f9b, 0x1ff7,
+ 0x7f9c, 0x1ff5,
+ 0x7f9e, 0x0b62,
+ 0x7fa0, 0x2276,
+ 0x7fa2, 0x2275,
+ 0x7fa3, 0x3788,
+ 0x7fa4, 0x0eca,
+ 0x7fa5, 0x2515,
+ 0x7fa6, 0x2514,
+ 0x7fa7, 0x2516,
+ 0x7fa8, 0x0ec9,
+ 0x7fa9, 0x0ec8,
+ 0x7fac, 0x29c3,
+ 0x7fad, 0x29c5,
+ 0x7fae, 0x43dc,
+ 0x7faf, 0x11e7,
+ 0x7fb0, 0x29c4,
+ 0x7fb1, 0x2c2a,
+ 0x7fb2, 0x132a,
+ 0x7fb3, 0x2f8e,
+ 0x7fb4, 0x4739,
+ 0x7fb5, 0x2f8d,
+ 0x7fb6, 0x15b0,
+ 0x7fb7, 0x30e8,
+ 0x7fb8, 0x15b2,
+ 0x7fb9, 0x15b1,
+ 0x7fba, 0x3218,
+ 0x7fbb, 0x32f3,
+ 0x7fbc, 0x1684,
+ 0x7fbd, 0x03fb,
+ 0x7fbe, 0x1bc6,
+ 0x7fbf, 0x07d6,
+ 0x7fc0, 0x1db2,
+ 0x7fc1, 0x097d,
+ 0x7fc2, 0x1db1,
+ 0x7fc3, 0x1db0,
+ 0x7fc5, 0x097c,
+ 0x7fc7, 0x1ffd,
+ 0x7fc9, 0x1fff,
+ 0x7fca, 0x1ff8,
+ 0x7fcc, 0x0b64,
+ 0x7fcd, 0x1ffa,
+ 0x7fce, 0x0b65,
+ 0x7fcf, 0x1ffe,
+ 0x7fd0, 0x1ffb,
+ 0x7fd2, 0x0b66,
+ 0x7fd4, 0x0d1c,
+ 0x7fd7, 0x2278,
+ 0x7fdb, 0x2517,
+ 0x7fdd, 0x3b5e,
+ 0x7fde, 0x279a,
+ 0x7fdf, 0x1071,
+ 0x7fe0, 0x106f,
+ 0x7fe2, 0x2797,
+ 0x7fe5, 0x2799,
+ 0x7fe6, 0x29ca,
+ 0x7fe7, 0x46e9,
+ 0x7fe8, 0x29cb,
+ 0x7fe9, 0x11e8,
+ 0x7fea, 0x29c8,
+ 0x7feb, 0x29c7,
+ 0x7fec, 0x29c9,
+ 0x7fed, 0x29c6,
+ 0x7fee, 0x132d,
+ 0x7fef, 0x2c2b,
+ 0x7ff0, 0x132b,
+ 0x7ff2, 0x2e04,
+ 0x7ff3, 0x1447,
+ 0x7ff4, 0x2e03,
+ 0x7ff5, 0x2eff,
+ 0x7ff7, 0x2f8f,
+ 0x7ff9, 0x1514,
+ 0x7ffa, 0x378e,
+ 0x7ffb, 0x1515,
+ 0x7ffc, 0x1448,
+ 0x7ffd, 0x30e9,
+ 0x7fff, 0x3219,
+ 0x8000, 0x1634,
+ 0x8001, 0x03fc,
+ 0x8002, 0x44fd,
+ 0x8003, 0x03fd,
+ 0x8004, 0x097f,
+ 0x8005, 0x066b,
+ 0x8006, 0x097e,
+ 0x8007, 0x1bc7,
+ 0x8008, 0x3791,
+ 0x800b, 0x0d1e,
+ 0x800c, 0x03fe,
+ 0x800d, 0x07d8,
+ 0x800e, 0x1bc8,
+ 0x8010, 0x07d7,
+ 0x8011, 0x07d9,
+ 0x8012, 0x03ff,
+ 0x8014, 0x1bca,
+ 0x8015, 0x0981,
+ 0x8016, 0x1db3,
+ 0x8017, 0x0983,
+ 0x8018, 0x0980,
+ 0x8019, 0x0982,
+ 0x801b, 0x2002,
+ 0x801c, 0x0b67,
+ 0x801d, 0x3792,
+ 0x801e, 0x2001,
+ 0x801f, 0x2000,
+ 0x8020, 0x473c,
+ 0x8021, 0x2519,
+ 0x8024, 0x279b,
+ 0x8025, 0x473d,
+ 0x8026, 0x11e9,
+ 0x8028, 0x132e,
+ 0x8029, 0x2c2d,
+ 0x802a, 0x2c2c,
+ 0x802c, 0x2e05,
+ 0x802e, 0x473e,
+ 0x802f, 0x3794,
+ 0x8030, 0x32f4,
+ 0x8031, 0x473f,
+ 0x8033, 0x0400,
+ 0x8034, 0x18d8,
+ 0x8035, 0x1a27,
+ 0x8036, 0x07da,
+ 0x8037, 0x1bcb,
+ 0x8039, 0x1db5,
+ 0x803b, 0x3797,
+ 0x803d, 0x0984,
+ 0x803e, 0x1db4,
+ 0x803f, 0x0985,
+ 0x8043, 0x2004,
+ 0x8046, 0x0b69,
+ 0x8047, 0x2003,
+ 0x8048, 0x2005,
+ 0x804a, 0x0b68,
+ 0x804f, 0x227a,
+ 0x8051, 0x2279,
+ 0x8052, 0x0d1f,
+ 0x8054, 0x4740,
+ 0x8056, 0x0ecb,
+ 0x8058, 0x0ecc,
+ 0x805a, 0x1073,
+ 0x805b, 0x3fe5,
+ 0x805c, 0x279d,
+ 0x805d, 0x279c,
+ 0x805e, 0x1072,
+ 0x8061, 0x3799,
+ 0x8062, 0x3fe3,
+ 0x8063, 0x3fdc,
+ 0x8064, 0x29cc,
+ 0x8066, 0x3fdb,
+ 0x8067, 0x29cd,
+ 0x806c, 0x2c2e,
+ 0x806f, 0x144c,
+ 0x8070, 0x144b,
+ 0x8071, 0x1449,
+ 0x8073, 0x144d,
+ 0x8075, 0x2f91,
+ 0x8076, 0x1517,
+ 0x8077, 0x1516,
+ 0x8078, 0x30eb,
+ 0x8079, 0x321a,
+ 0x807d, 0x16d3,
+ 0x807e, 0x16d2,
+ 0x807f, 0x0401,
+ 0x8080, 0x44fe,
+ 0x8082, 0x1cec,
+ 0x8084, 0x0ece,
+ 0x8085, 0x0d20,
+ 0x8086, 0x0ecd,
+ 0x8087, 0x1074,
+ 0x8089, 0x0402,
+ 0x808a, 0x17b3,
+ 0x808b, 0x0403,
+ 0x808f, 0x1a28,
+ 0x8090, 0x18db,
+ 0x8092, 0x18dc,
+ 0x8093, 0x04fe,
+ 0x8095, 0x18d9,
+ 0x8096, 0x04fd,
+ 0x8098, 0x0500,
+ 0x8099, 0x18da,
+ 0x809a, 0x0502,
+ 0x809b, 0x0501,
+ 0x809c, 0x18dd,
+ 0x809d, 0x04ff,
+ 0x809f, 0x4576,
+ 0x80a1, 0x0670,
+ 0x80a2, 0x066e,
+ 0x80a3, 0x1a2a,
+ 0x80a5, 0x066d,
+ 0x80a7, 0x37a0,
+ 0x80a9, 0x0672,
+ 0x80aa, 0x0674,
+ 0x80ab, 0x0671,
+ 0x80ad, 0x1a2d,
+ 0x80ae, 0x1a29,
+ 0x80af, 0x0675,
+ 0x80b1, 0x066f,
+ 0x80b2, 0x0503,
+ 0x80b4, 0x0673,
+ 0x80b5, 0x1a2c,
+ 0x80b6, 0x3eae,
+ 0x80b7, 0x4743,
+ 0x80b8, 0x1a2b,
+ 0x80ba, 0x066c,
+ 0x80bc, 0x4572,
+ 0x80bd, 0x3e7b,
+ 0x80c2, 0x1bd1,
+ 0x80c3, 0x07de,
+ 0x80c5, 0x1bd3,
+ 0x80c6, 0x3b74,
+ 0x80c7, 0x1bcd,
+ 0x80c8, 0x1bd0,
+ 0x80c9, 0x1bd9,
+ 0x80ca, 0x1bd7,
+ 0x80cc, 0x07e0,
+ 0x80cd, 0x1bdd,
+ 0x80ce, 0x07e3,
+ 0x80cf, 0x1bda,
+ 0x80d0, 0x1bd2,
+ 0x80d1, 0x1bcf,
+ 0x80d4, 0x227d,
+ 0x80d5, 0x1bd8,
+ 0x80d6, 0x07db,
+ 0x80d7, 0x1bdb,
+ 0x80d8, 0x1bcc,
+ 0x80d9, 0x1bd5,
+ 0x80da, 0x07dd,
+ 0x80db, 0x07e2,
+ 0x80dc, 0x1bd6,
+ 0x80dd, 0x07e6,
+ 0x80de, 0x07e4,
+ 0x80e0, 0x1bce,
+ 0x80e1, 0x07e1,
+ 0x80e3, 0x1bd4,
+ 0x80e4, 0x07e5,
+ 0x80e5, 0x07dc,
+ 0x80e6, 0x1bdc,
+ 0x80e9, 0x4744,
+ 0x80ec, 0x45e9,
+ 0x80ed, 0x098a,
+ 0x80ef, 0x0993,
+ 0x80f0, 0x0988,
+ 0x80f1, 0x0986,
+ 0x80f2, 0x1db7,
+ 0x80f3, 0x098e,
+ 0x80f4, 0x098b,
+ 0x80f5, 0x1db9,
+ 0x80f6, 0x4574,
+ 0x80f8, 0x098d,
+ 0x80f9, 0x1db8,
+ 0x80fa, 0x1db6,
+ 0x80fb, 0x1dbb,
+ 0x80fc, 0x0992,
+ 0x80fd, 0x0990,
+ 0x80fe, 0x227c,
+ 0x8100, 0x1dbc,
+ 0x8101, 0x1dba,
+ 0x8102, 0x0987,
+ 0x8103, 0x3fe7,
+ 0x8105, 0x0989,
+ 0x8106, 0x098c,
+ 0x8107, 0x37a2,
+ 0x8108, 0x098f,
+ 0x8109, 0x3b75,
+ 0x810a, 0x0991,
+ 0x810c, 0x4746,
+ 0x810e, 0x4747,
+ 0x8112, 0x4748,
+ 0x8114, 0x4749,
+ 0x8115, 0x200f,
+ 0x8116, 0x0b6b,
+ 0x8117, 0x3e6d,
+ 0x8118, 0x2006,
+ 0x8119, 0x2008,
+ 0x811a, 0x37a3,
+ 0x811b, 0x2009,
+ 0x811d, 0x2011,
+ 0x811e, 0x200d,
+ 0x811f, 0x200b,
+ 0x8121, 0x200e,
+ 0x8122, 0x2012,
+ 0x8123, 0x0b6c,
+ 0x8124, 0x0b70,
+ 0x8125, 0x2007,
+ 0x8127, 0x2010,
+ 0x8129, 0x0b6e,
+ 0x812a, 0x3a39,
+ 0x812b, 0x0b6d,
+ 0x812c, 0x200c,
+ 0x812d, 0x200a,
+ 0x812f, 0x0b6a,
+ 0x8130, 0x0b6f,
+ 0x8132, 0x3e79,
+ 0x8134, 0x45ec,
+ 0x8137, 0x3b72,
+ 0x8139, 0x0d26,
+ 0x813a, 0x2285,
+ 0x813d, 0x2283,
+ 0x813e, 0x0d28,
+ 0x8142, 0x3b76,
+ 0x8143, 0x227e,
+ 0x8144, 0x2527,
+ 0x8146, 0x0d27,
+ 0x8147, 0x2282,
+ 0x8148, 0x3e76,
+ 0x814a, 0x227f,
+ 0x814b, 0x0d23,
+ 0x814c, 0x0d29,
+ 0x814d, 0x2284,
+ 0x814e, 0x0d25,
+ 0x814f, 0x2281,
+ 0x8150, 0x1075,
+ 0x8151, 0x0d24,
+ 0x8152, 0x2280,
+ 0x8153, 0x0d2a,
+ 0x8154, 0x0d22,
+ 0x8155, 0x0d21,
+ 0x8156, 0x474c,
+ 0x8159, 0x474d,
+ 0x815b, 0x251f,
+ 0x815c, 0x251d,
+ 0x815e, 0x2523,
+ 0x8160, 0x251b,
+ 0x8161, 0x2528,
+ 0x8162, 0x2520,
+ 0x8164, 0x251a,
+ 0x8165, 0x0ed2,
+ 0x8166, 0x0ed8,
+ 0x8167, 0x2525,
+ 0x8169, 0x251e,
+ 0x816b, 0x0ed5,
+ 0x816d, 0x43c4,
+ 0x816e, 0x0ed3,
+ 0x816f, 0x2526,
+ 0x8170, 0x0ed0,
+ 0x8171, 0x0ecf,
+ 0x8172, 0x2521,
+ 0x8173, 0x0ed4,
+ 0x8174, 0x0d2b,
+ 0x8176, 0x2524,
+ 0x8177, 0x251c,
+ 0x8178, 0x0ed1,
+ 0x8179, 0x0ed6,
+ 0x817c, 0x4750,
+ 0x817f, 0x107a,
+ 0x8180, 0x1076,
+ 0x8182, 0x107b,
+ 0x8183, 0x27a0,
+ 0x8184, 0x43c5,
+ 0x8186, 0x279f,
+ 0x8187, 0x27a1,
+ 0x8188, 0x1078,
+ 0x8189, 0x279e,
+ 0x818a, 0x1079,
+ 0x818b, 0x27a4,
+ 0x818c, 0x27a3,
+ 0x818d, 0x27a2,
+ 0x818f, 0x1077,
+ 0x8193, 0x43c6,
+ 0x8195, 0x29d1,
+ 0x8197, 0x29d4,
+ 0x8198, 0x11ef,
+ 0x8199, 0x29d3,
+ 0x819a, 0x11ee,
+ 0x819b, 0x11ea,
+ 0x819e, 0x29d0,
+ 0x819f, 0x29cf,
+ 0x81a0, 0x11ed,
+ 0x81a2, 0x29d2,
+ 0x81a3, 0x29ce,
+ 0x81a5, 0x4753,
+ 0x81a6, 0x2c30,
+ 0x81a7, 0x2c3a,
+ 0x81a8, 0x1331,
+ 0x81a9, 0x1330,
+ 0x81aa, 0x4364,
+ 0x81ab, 0x2c34,
+ 0x81ac, 0x2c36,
+ 0x81ae, 0x2c31,
+ 0x81b0, 0x2c35,
+ 0x81b1, 0x2c2f,
+ 0x81b2, 0x2c38,
+ 0x81b3, 0x132f,
+ 0x81b4, 0x2c37,
+ 0x81b5, 0x2c33,
+ 0x81b6, 0x3eb2,
+ 0x81b7, 0x2c39,
+ 0x81b9, 0x2c32,
+ 0x81ba, 0x1450,
+ 0x81bb, 0x2e06,
+ 0x81bc, 0x2e0c,
+ 0x81bd, 0x1454,
+ 0x81be, 0x1456,
+ 0x81bf, 0x1453,
+ 0x81c0, 0x1452,
+ 0x81c1, 0x4755,
+ 0x81c2, 0x1451,
+ 0x81c3, 0x144f,
+ 0x81c4, 0x2e07,
+ 0x81c5, 0x2e0a,
+ 0x81c6, 0x144e,
+ 0x81c7, 0x2e0b,
+ 0x81c8, 0x3fee,
+ 0x81c9, 0x1455,
+ 0x81ca, 0x2e09,
+ 0x81cc, 0x2e08,
+ 0x81cd, 0x1518,
+ 0x81cf, 0x1519,
+ 0x81d0, 0x2f94,
+ 0x81d1, 0x2f92,
+ 0x81d5, 0x30ed,
+ 0x81d7, 0x30ec,
+ 0x81d8, 0x15b3,
+ 0x81d9, 0x321c,
+ 0x81da, 0x1635,
+ 0x81db, 0x321b,
+ 0x81dd, 0x32f5,
+ 0x81de, 0x33a5,
+ 0x81df, 0x16d4,
+ 0x81e0, 0x34dd,
+ 0x81e2, 0x1706,
+ 0x81e3, 0x0405,
+ 0x81e4, 0x4756,
+ 0x81e5, 0x0676,
+ 0x81e6, 0x2286,
+ 0x81e7, 0x107c,
+ 0x81e8, 0x1457,
+ 0x81e9, 0x2e0d,
+ 0x81ea, 0x0406,
+ 0x81ec, 0x0995,
+ 0x81ed, 0x0994,
+ 0x81ee, 0x2287,
+ 0x81ef, 0x42d1,
+ 0x81f2, 0x2c3b,
+ 0x81f3, 0x0407,
+ 0x81f4, 0x07e7,
+ 0x81f6, 0x3d61,
+ 0x81f7, 0x2288,
+ 0x81fa, 0x107d,
+ 0x81fb, 0x1332,
+ 0x81fc, 0x0408,
+ 0x81fe, 0x0677,
+ 0x81ff, 0x1bde,
+ 0x8200, 0x0996,
+ 0x8201, 0x1dbd,
+ 0x8202, 0x0b71,
+ 0x8204, 0x228b,
+ 0x8205, 0x0ed9,
+ 0x8207, 0x107e,
+ 0x8208, 0x1333,
+ 0x8209, 0x1458,
+ 0x820a, 0x151a,
+ 0x820b, 0x30ee,
+ 0x820c, 0x0409,
+ 0x820d, 0x0678,
+ 0x8210, 0x0997,
+ 0x8211, 0x2013,
+ 0x8212, 0x0d2c,
+ 0x8214, 0x107f,
+ 0x8215, 0x27a5,
+ 0x8216, 0x29d5,
+ 0x8218, 0x37aa,
+ 0x821a, 0x3fe1,
+ 0x821b, 0x040a,
+ 0x821c, 0x0d2d,
+ 0x821d, 0x2529,
+ 0x821e, 0x1080,
+ 0x821f, 0x040b,
+ 0x8220, 0x1a2e,
+ 0x8221, 0x1bdf,
+ 0x8222, 0x07e8,
+ 0x8225, 0x1dbf,
+ 0x8226, 0x420d,
+ 0x8228, 0x099a,
+ 0x8229, 0x37b0,
+ 0x822a, 0x0998,
+ 0x822c, 0x099b,
+ 0x822d, 0x3ed0,
+ 0x822f, 0x1dbe,
+ 0x8232, 0x2018,
+ 0x8233, 0x2015,
+ 0x8234, 0x2017,
+ 0x8235, 0x0b72,
+ 0x8236, 0x0b74,
+ 0x8237, 0x0b73,
+ 0x8238, 0x2014,
+ 0x8239, 0x0b75,
+ 0x823a, 0x2016,
+ 0x823c, 0x228c,
+ 0x823e, 0x4582,
+ 0x823f, 0x228e,
+ 0x8240, 0x252c,
+ 0x8242, 0x252d,
+ 0x8244, 0x252b,
+ 0x8245, 0x252e,
+ 0x8247, 0x0eda,
+ 0x8249, 0x252a,
+ 0x824b, 0x1081,
+ 0x824e, 0x29da,
+ 0x824f, 0x29d6,
+ 0x8250, 0x29d9,
+ 0x8251, 0x29db,
+ 0x8252, 0x29d8,
+ 0x8253, 0x29d7,
+ 0x8254, 0x4757,
+ 0x8255, 0x2c3c,
+ 0x8258, 0x1334,
+ 0x825a, 0x2e0f,
+ 0x825b, 0x2e0e,
+ 0x825c, 0x2e10,
+ 0x825e, 0x2f96,
+ 0x825f, 0x2f95,
+ 0x8261, 0x30f0,
+ 0x8262, 0x3b7a,
+ 0x8263, 0x30f1,
+ 0x8264, 0x30ef,
+ 0x8265, 0x3b7b,
+ 0x8266, 0x1636,
+ 0x8268, 0x321d,
+ 0x826b, 0x33a6,
+ 0x826c, 0x342d,
+ 0x826d, 0x3496,
+ 0x826e, 0x040c,
+ 0x826f, 0x0504,
+ 0x8271, 0x1459,
+ 0x8272, 0x040d,
+ 0x8274, 0x2019,
+ 0x8275, 0x228f,
+ 0x8276, 0x4759,
+ 0x8277, 0x172e,
+ 0x8278, 0x1813,
+ 0x8279, 0x4722,
+ 0x827a, 0x4563,
+ 0x827b, 0x37c8,
+ 0x827c, 0x1814,
+ 0x827d, 0x1816,
+ 0x827e, 0x040e,
+ 0x827f, 0x1817,
+ 0x8280, 0x1815,
+ 0x8283, 0x18e5,
+ 0x8285, 0x18e0,
+ 0x8287, 0x4132,
+ 0x828a, 0x18e4,
+ 0x828b, 0x0506,
+ 0x828d, 0x0507,
+ 0x828e, 0x18e1,
+ 0x828f, 0x18df,
+ 0x8290, 0x18de,
+ 0x8291, 0x18e2,
+ 0x8292, 0x0505,
+ 0x8293, 0x18e3,
+ 0x8294, 0x1be0,
+ 0x8298, 0x1a33,
+ 0x8299, 0x067b,
+ 0x829a, 0x1a32,
+ 0x829b, 0x1a34,
+ 0x829d, 0x067a,
+ 0x829e, 0x1a39,
+ 0x829f, 0x067e,
+ 0x82a0, 0x1a2f,
+ 0x82a1, 0x1a3d,
+ 0x82a2, 0x1a43,
+ 0x82a3, 0x0685,
+ 0x82a4, 0x1a40,
+ 0x82a5, 0x0682,
+ 0x82a6, 0x3d73,
+ 0x82a7, 0x1a36,
+ 0x82a8, 0x1a3c,
+ 0x82a9, 0x1a3e,
+ 0x82aa, 0x37bc,
+ 0x82ab, 0x1a31,
+ 0x82ac, 0x0681,
+ 0x82ad, 0x067c,
+ 0x82ae, 0x1a37,
+ 0x82af, 0x0683,
+ 0x82b0, 0x0686,
+ 0x82b1, 0x0680,
+ 0x82b3, 0x0679,
+ 0x82b4, 0x1a3b,
+ 0x82b5, 0x1a35,
+ 0x82b6, 0x1a42,
+ 0x82b7, 0x0688,
+ 0x82b8, 0x0684,
+ 0x82b9, 0x067f,
+ 0x82ba, 0x1a3a,
+ 0x82bb, 0x099c,
+ 0x82bc, 0x1a38,
+ 0x82bd, 0x067d,
+ 0x82be, 0x0687,
+ 0x82c0, 0x1a30,
+ 0x82c2, 0x1a3f,
+ 0x82c3, 0x1a41,
+ 0x82c4, 0x45e3,
+ 0x82ca, 0x475a,
+ 0x82cf, 0x4564,
+ 0x82d0, 0x37c1,
+ 0x82d1, 0x07f9,
+ 0x82d2, 0x07f3,
+ 0x82d3, 0x07fb,
+ 0x82d4, 0x07f8,
+ 0x82d5, 0x1be7,
+ 0x82d6, 0x1bea,
+ 0x82d7, 0x07f4,
+ 0x82d8, 0x475b,
+ 0x82d9, 0x1be1,
+ 0x82db, 0x07ed,
+ 0x82dc, 0x07f7,
+ 0x82de, 0x07fa,
+ 0x82df, 0x07fc,
+ 0x82e0, 0x1bf6,
+ 0x82e1, 0x1bed,
+ 0x82e2, 0x37c9,
+ 0x82e3, 0x07ec,
+ 0x82e4, 0x1bf5,
+ 0x82e5, 0x07f0,
+ 0x82e6, 0x07ee,
+ 0x82e7, 0x07e9,
+ 0x82e8, 0x1be5,
+ 0x82ea, 0x1bf4,
+ 0x82eb, 0x1be9,
+ 0x82ec, 0x1bec,
+ 0x82ed, 0x1bf9,
+ 0x82ee, 0x4018,
+ 0x82ef, 0x07fd,
+ 0x82f0, 0x1bf3,
+ 0x82f1, 0x07f5,
+ 0x82f2, 0x1bee,
+ 0x82f3, 0x1bf8,
+ 0x82f4, 0x1beb,
+ 0x82f5, 0x1bef,
+ 0x82f6, 0x1bf2,
+ 0x82f7, 0x3e77,
+ 0x82f9, 0x1be3,
+ 0x82fa, 0x1bf7,
+ 0x82fb, 0x1bf1,
+ 0x82fc, 0x412d,
+ 0x82fd, 0x3d92,
+ 0x82fe, 0x1be2,
+ 0x82ff, 0x43de,
+ 0x8300, 0x1be6,
+ 0x8301, 0x07f6,
+ 0x8302, 0x07f1,
+ 0x8303, 0x07ea,
+ 0x8304, 0x07ef,
+ 0x8305, 0x07eb,
+ 0x8306, 0x07fe,
+ 0x8307, 0x1be4,
+ 0x8308, 0x1dd0,
+ 0x8309, 0x07f2,
+ 0x830b, 0x3eb6,
+ 0x830c, 0x1bf0,
+ 0x830d, 0x1a7d,
+ 0x8316, 0x1dd3,
+ 0x8317, 0x09aa,
+ 0x8318, 0x37ca,
+ 0x8319, 0x1dc3,
+ 0x831a, 0x37c2,
+ 0x831b, 0x1dce,
+ 0x831c, 0x1dca,
+ 0x831d, 0x37d1,
+ 0x831e, 0x1ddd,
+ 0x8320, 0x1dd5,
+ 0x8322, 0x1dcb,
+ 0x8324, 0x1dd4,
+ 0x8325, 0x1dc5,
+ 0x8326, 0x1dc9,
+ 0x8327, 0x1de0,
+ 0x8328, 0x09ad,
+ 0x8329, 0x1dd8,
+ 0x832a, 0x1dcf,
+ 0x832b, 0x099d,
+ 0x832c, 0x1dde,
+ 0x832d, 0x1dc1,
+ 0x832f, 0x1dd7,
+ 0x8331, 0x09ac,
+ 0x8332, 0x09a7,
+ 0x8333, 0x1dc0,
+ 0x8334, 0x09a5,
+ 0x8335, 0x09a4,
+ 0x8336, 0x09a9,
+ 0x8337, 0x1dd6,
+ 0x8338, 0x09a1,
+ 0x8339, 0x09a8,
+ 0x833a, 0x1be8,
+ 0x833b, 0x2290,
+ 0x833c, 0x1dd1,
+ 0x833d, 0x3d2a,
+ 0x833f, 0x1dc7,
+ 0x8340, 0x09ab,
+ 0x8341, 0x1dc8,
+ 0x8342, 0x1dcc,
+ 0x8343, 0x09ae,
+ 0x8344, 0x1dc2,
+ 0x8345, 0x1dda,
+ 0x8347, 0x1dd9,
+ 0x8348, 0x1de1,
+ 0x8349, 0x09a3,
+ 0x834a, 0x09a0,
+ 0x834b, 0x1ddf,
+ 0x834c, 0x1ddb,
+ 0x834d, 0x1dd2,
+ 0x834e, 0x1dcd,
+ 0x834f, 0x09a6,
+ 0x8350, 0x09a2,
+ 0x8351, 0x1dc4,
+ 0x8352, 0x099e,
+ 0x8353, 0x1ddc,
+ 0x8354, 0x099f,
+ 0x8356, 0x1dc6,
+ 0x8357, 0x475d,
+ 0x8362, 0x37b6,
+ 0x8363, 0x41eb,
+ 0x8366, 0x3e1e,
+ 0x836f, 0x4565,
+ 0x8373, 0x201f,
+ 0x8374, 0x2021,
+ 0x8375, 0x2026,
+ 0x8376, 0x203a,
+ 0x8377, 0x0b83,
+ 0x8378, 0x0b79,
+ 0x837a, 0x201e,
+ 0x837b, 0x0b84,
+ 0x837d, 0x2029,
+ 0x837e, 0x2030,
+ 0x837f, 0x2036,
+ 0x8381, 0x2023,
+ 0x8383, 0x202a,
+ 0x8385, 0x37d3,
+ 0x8386, 0x0b86,
+ 0x8387, 0x2038,
+ 0x8388, 0x2033,
+ 0x8389, 0x0b81,
+ 0x838a, 0x0b7f,
+ 0x838b, 0x202f,
+ 0x838c, 0x202b,
+ 0x838d, 0x201d,
+ 0x838e, 0x0b76,
+ 0x838f, 0x2022,
+ 0x8390, 0x201a,
+ 0x8391, 0x37ec,
+ 0x8392, 0x0b7e,
+ 0x8393, 0x0b80,
+ 0x8394, 0x2027,
+ 0x8395, 0x2024,
+ 0x8396, 0x0b7b,
+ 0x8397, 0x2034,
+ 0x8398, 0x0b78,
+ 0x8399, 0x2025,
+ 0x839a, 0x22b9,
+ 0x839b, 0x202d,
+ 0x839c, 0x374d,
+ 0x839d, 0x202c,
+ 0x839e, 0x0b77,
+ 0x83a0, 0x0b82,
+ 0x83a2, 0x0b7a,
+ 0x83a3, 0x201b,
+ 0x83a4, 0x2020,
+ 0x83a5, 0x2031,
+ 0x83a6, 0x2037,
+ 0x83a7, 0x0b87,
+ 0x83a8, 0x201c,
+ 0x83a9, 0x2028,
+ 0x83aa, 0x202e,
+ 0x83ab, 0x0b7d,
+ 0x83ac, 0x37d6,
+ 0x83ae, 0x2039,
+ 0x83af, 0x2032,
+ 0x83b0, 0x2035,
+ 0x83b9, 0x42a7,
+ 0x83bd, 0x0b7c,
+ 0x83be, 0x3f59,
+ 0x83bf, 0x22a0,
+ 0x83c0, 0x2294,
+ 0x83c1, 0x0d35,
+ 0x83c2, 0x22b1,
+ 0x83c3, 0x22ba,
+ 0x83c4, 0x22bd,
+ 0x83c5, 0x0d33,
+ 0x83c6, 0x229c,
+ 0x83c7, 0x22b5,
+ 0x83c8, 0x229d,
+ 0x83c9, 0x22ab,
+ 0x83ca, 0x0d40,
+ 0x83cb, 0x22a7,
+ 0x83cc, 0x0d3d,
+ 0x83cd, 0x4055,
+ 0x83ce, 0x22a8,
+ 0x83cf, 0x2291,
+ 0x83d1, 0x22b6,
+ 0x83d3, 0x37d8,
+ 0x83d4, 0x0d46,
+ 0x83d5, 0x22b3,
+ 0x83d6, 0x22a9,
+ 0x83d7, 0x22bf,
+ 0x83d8, 0x22a4,
+ 0x83d9, 0x254e,
+ 0x83db, 0x22c2,
+ 0x83dc, 0x0d44,
+ 0x83dd, 0x22a2,
+ 0x83de, 0x22ae,
+ 0x83df, 0x0d47,
+ 0x83e0, 0x0d32,
+ 0x83e1, 0x22a6,
+ 0x83e2, 0x22c0,
+ 0x83e3, 0x229f,
+ 0x83e4, 0x2298,
+ 0x83e5, 0x22a3,
+ 0x83e7, 0x2297,
+ 0x83e8, 0x2295,
+ 0x83e9, 0x0d2e,
+ 0x83ea, 0x22b7,
+ 0x83eb, 0x229e,
+ 0x83ec, 0x22bb,
+ 0x83ed, 0x3d2c,
+ 0x83ee, 0x22bc,
+ 0x83ef, 0x0d36,
+ 0x83f0, 0x0d3b,
+ 0x83f1, 0x0d37,
+ 0x83f2, 0x0d3f,
+ 0x83f3, 0x22b2,
+ 0x83f4, 0x0d38,
+ 0x83f5, 0x22aa,
+ 0x83f6, 0x229a,
+ 0x83f8, 0x0d30,
+ 0x83f9, 0x2292,
+ 0x83fa, 0x22b4,
+ 0x83fb, 0x22be,
+ 0x83fc, 0x2299,
+ 0x83fd, 0x0d3e,
+ 0x83fe, 0x22c3,
+ 0x83ff, 0x22a5,
+ 0x8401, 0x22a1,
+ 0x8403, 0x0d2f,
+ 0x8404, 0x0d43,
+ 0x8405, 0x475f,
+ 0x8406, 0x22b0,
+ 0x8407, 0x0d45,
+ 0x8409, 0x22ac,
+ 0x840a, 0x0d3a,
+ 0x840b, 0x0d34,
+ 0x840c, 0x0d3c,
+ 0x840d, 0x0d31,
+ 0x840e, 0x0d42,
+ 0x840f, 0x22ad,
+ 0x8410, 0x229b,
+ 0x8411, 0x22af,
+ 0x8412, 0x2296,
+ 0x8413, 0x22b8,
+ 0x8414, 0x3c10,
+ 0x8416, 0x4037,
+ 0x8418, 0x3e7a,
+ 0x841b, 0x22c1,
+ 0x841c, 0x3eb3,
+ 0x8420, 0x3c55,
+ 0x8421, 0x3751,
+ 0x8423, 0x2293,
+ 0x8424, 0x4951,
+ 0x8426, 0x46d8,
+ 0x8429, 0x254d,
+ 0x842b, 0x2563,
+ 0x842c, 0x0eac,
+ 0x842d, 0x2552,
+ 0x842e, 0x422d,
+ 0x842f, 0x2550,
+ 0x8430, 0x253b,
+ 0x8431, 0x0ede,
+ 0x8432, 0x254b,
+ 0x8433, 0x255f,
+ 0x8434, 0x2547,
+ 0x8435, 0x0ee6,
+ 0x8436, 0x255e,
+ 0x8437, 0x2545,
+ 0x8438, 0x0d41,
+ 0x8439, 0x2555,
+ 0x843a, 0x2546,
+ 0x843b, 0x255c,
+ 0x843c, 0x0ee5,
+ 0x843d, 0x0edd,
+ 0x843e, 0x3d21,
+ 0x843f, 0x2530,
+ 0x8440, 0x2538,
+ 0x8442, 0x2551,
+ 0x8443, 0x2549,
+ 0x8444, 0x2562,
+ 0x8445, 0x254c,
+ 0x8446, 0x0eeb,
+ 0x8447, 0x255d,
+ 0x8448, 0x4718,
+ 0x8449, 0x0ee2,
+ 0x844a, 0x37e4,
+ 0x844b, 0x254f,
+ 0x844c, 0x2557,
+ 0x844d, 0x253c,
+ 0x844e, 0x2556,
+ 0x8450, 0x2567,
+ 0x8451, 0x2537,
+ 0x8452, 0x2558,
+ 0x8453, 0x3b7d,
+ 0x8454, 0x2565,
+ 0x8455, 0x398b,
+ 0x8456, 0x2531,
+ 0x8457, 0x0d39,
+ 0x8458, 0x37de,
+ 0x8459, 0x253f,
+ 0x845a, 0x253e,
+ 0x845b, 0x0ee4,
+ 0x845c, 0x3edb,
+ 0x845d, 0x2542,
+ 0x845e, 0x2544,
+ 0x845f, 0x2553,
+ 0x8460, 0x2564,
+ 0x8461, 0x0ee7,
+ 0x8462, 0x42da,
+ 0x8463, 0x0ee8,
+ 0x8464, 0x4761,
+ 0x8465, 0x2536,
+ 0x8466, 0x0ee0,
+ 0x8467, 0x253a,
+ 0x8468, 0x2560,
+ 0x8469, 0x0ee9,
+ 0x846b, 0x0ee1,
+ 0x846c, 0x0ee3,
+ 0x846d, 0x0eea,
+ 0x846e, 0x2566,
+ 0x846f, 0x2559,
+ 0x8470, 0x2554,
+ 0x8471, 0x37e0,
+ 0x8472, 0x3c93,
+ 0x8473, 0x2541,
+ 0x8474, 0x2540,
+ 0x8475, 0x0edf,
+ 0x8476, 0x2532,
+ 0x8477, 0x0edc,
+ 0x8478, 0x254a,
+ 0x8479, 0x2533,
+ 0x847a, 0x2548,
+ 0x847d, 0x253d,
+ 0x847e, 0x2561,
+ 0x847f, 0x394e,
+ 0x8480, 0x3b6e,
+ 0x8482, 0x0edb,
+ 0x8486, 0x2539,
+ 0x8488, 0x4762,
+ 0x848d, 0x2535,
+ 0x848e, 0x255b,
+ 0x848f, 0x2534,
+ 0x8490, 0x108e,
+ 0x8491, 0x27cd,
+ 0x8492, 0x3756,
+ 0x8493, 0x37ee,
+ 0x8494, 0x27bc,
+ 0x8496, 0x3b1d,
+ 0x8497, 0x27a6,
+ 0x8498, 0x27c4,
+ 0x8499, 0x1086,
+ 0x849a, 0x27b5,
+ 0x849b, 0x27bf,
+ 0x849c, 0x1089,
+ 0x849d, 0x27b8,
+ 0x849e, 0x1087,
+ 0x849f, 0x27a9,
+ 0x84a0, 0x27c7,
+ 0x84a1, 0x27a8,
+ 0x84a2, 0x27bb,
+ 0x84a3, 0x3b9e,
+ 0x84a4, 0x27a7,
+ 0x84a7, 0x27b9,
+ 0x84a8, 0x27c2,
+ 0x84a9, 0x27c0,
+ 0x84aa, 0x27b4,
+ 0x84ab, 0x27af,
+ 0x84ac, 0x27ad,
+ 0x84ad, 0x3d8c,
+ 0x84ae, 0x27ae,
+ 0x84af, 0x27c1,
+ 0x84b0, 0x27cc,
+ 0x84b1, 0x27b6,
+ 0x84b2, 0x1088,
+ 0x84b4, 0x27b1,
+ 0x84b6, 0x27c5,
+ 0x84b8, 0x108b,
+ 0x84b9, 0x27b0,
+ 0x84ba, 0x27aa,
+ 0x84bb, 0x27ba,
+ 0x84bc, 0x108f,
+ 0x84bd, 0x3c4c,
+ 0x84be, 0x4764,
+ 0x84bf, 0x1083,
+ 0x84c0, 0x108c,
+ 0x84c1, 0x27b2,
+ 0x84c2, 0x27ac,
+ 0x84c4, 0x1085,
+ 0x84c5, 0x255a,
+ 0x84c6, 0x1084,
+ 0x84c7, 0x27bd,
+ 0x84c9, 0x1082,
+ 0x84ca, 0x1091,
+ 0x84cb, 0x108a,
+ 0x84cc, 0x27be,
+ 0x84cd, 0x27b3,
+ 0x84ce, 0x27ab,
+ 0x84cf, 0x27c6,
+ 0x84d0, 0x27b7,
+ 0x84d1, 0x1090,
+ 0x84d2, 0x27ca,
+ 0x84d3, 0x108d,
+ 0x84d4, 0x27c9,
+ 0x84d6, 0x27c3,
+ 0x84d7, 0x27c8,
+ 0x84da, 0x3ff5,
+ 0x84db, 0x27cb,
+ 0x84de, 0x37ea,
+ 0x84e1, 0x4765,
+ 0x84e2, 0x37b5,
+ 0x84e4, 0x37ef,
+ 0x84e5, 0x3bd0,
+ 0x84e7, 0x2a03,
+ 0x84e9, 0x29f7,
+ 0x84ea, 0x29f6,
+ 0x84eb, 0x29f2,
+ 0x84ec, 0x11fb,
+ 0x84ee, 0x11f3,
+ 0x84ef, 0x2a06,
+ 0x84f0, 0x2a05,
+ 0x84f1, 0x252f,
+ 0x84f2, 0x29ef,
+ 0x84f3, 0x29f3,
+ 0x84f4, 0x29ed,
+ 0x84f6, 0x2a00,
+ 0x84f7, 0x29f1,
+ 0x84f8, 0x4766,
+ 0x84f9, 0x2a07,
+ 0x84fa, 0x29ea,
+ 0x84fb, 0x29e8,
+ 0x84fc, 0x29f4,
+ 0x84fd, 0x29fe,
+ 0x84fe, 0x29f9,
+ 0x84ff, 0x11fd,
+ 0x8500, 0x29df,
+ 0x8502, 0x29fd,
+ 0x8503, 0x398a,
+ 0x8505, 0x40eb,
+ 0x8506, 0x11fe,
+ 0x8507, 0x2543,
+ 0x8508, 0x29eb,
+ 0x8509, 0x29e2,
+ 0x850a, 0x29e5,
+ 0x850b, 0x2a0b,
+ 0x850c, 0x29ec,
+ 0x850d, 0x29e3,
+ 0x850e, 0x29e1,
+ 0x850f, 0x29de,
+ 0x8510, 0x4767,
+ 0x8511, 0x11f7,
+ 0x8512, 0x29f5,
+ 0x8513, 0x11f6,
+ 0x8514, 0x11fa,
+ 0x8515, 0x29f0,
+ 0x8516, 0x29f8,
+ 0x8517, 0x11f0,
+ 0x8518, 0x2a08,
+ 0x8519, 0x2a0c,
+ 0x851a, 0x11f2,
+ 0x851c, 0x29e7,
+ 0x851d, 0x29fb,
+ 0x851e, 0x29ff,
+ 0x851f, 0x29e4,
+ 0x8520, 0x2a09,
+ 0x8521, 0x11f9,
+ 0x8523, 0x11f8,
+ 0x8524, 0x29dc,
+ 0x8525, 0x11fc,
+ 0x8526, 0x2a02,
+ 0x8527, 0x29e6,
+ 0x8528, 0x29fa,
+ 0x8529, 0x29e0,
+ 0x852a, 0x29ee,
+ 0x852b, 0x29e9,
+ 0x852c, 0x11f4,
+ 0x852e, 0x29fc,
+ 0x852f, 0x2a0d,
+ 0x8530, 0x2a0a,
+ 0x8531, 0x2a01,
+ 0x8533, 0x4228,
+ 0x8534, 0x37f4,
+ 0x8538, 0x4768,
+ 0x853b, 0x29dd,
+ 0x853d, 0x11f1,
+ 0x853e, 0x2c4f,
+ 0x8540, 0x2c46,
+ 0x8541, 0x2c49,
+ 0x8542, 0x4062,
+ 0x8543, 0x133b,
+ 0x8544, 0x2c4b,
+ 0x8545, 0x2c40,
+ 0x8546, 0x2c47,
+ 0x8547, 0x2c4d,
+ 0x8548, 0x1338,
+ 0x8549, 0x133c,
+ 0x854a, 0x1336,
+ 0x854b, 0x37c0,
+ 0x854c, 0x400f,
+ 0x854d, 0x2c42,
+ 0x854e, 0x2c52,
+ 0x8551, 0x2c4c,
+ 0x8552, 0x4769,
+ 0x8553, 0x2c43,
+ 0x8554, 0x2c5b,
+ 0x8555, 0x2c55,
+ 0x8556, 0x2c3f,
+ 0x8557, 0x2e23,
+ 0x8558, 0x2c45,
+ 0x8559, 0x1337,
+ 0x855a, 0x37db,
+ 0x855b, 0x2c50,
+ 0x855d, 0x2c5a,
+ 0x855e, 0x133f,
+ 0x8560, 0x2c57,
+ 0x8561, 0x2c44,
+ 0x8562, 0x2c4a,
+ 0x8563, 0x2c4e,
+ 0x8564, 0x2c48,
+ 0x8565, 0x2c5c,
+ 0x8566, 0x2c59,
+ 0x8567, 0x2c56,
+ 0x8568, 0x1339,
+ 0x856a, 0x133e,
+ 0x856b, 0x2c41,
+ 0x856c, 0x2c5d,
+ 0x856d, 0x133d,
+ 0x856e, 0x2c53,
+ 0x856f, 0x476b,
+ 0x8571, 0x2c51,
+ 0x8573, 0x37f8,
+ 0x8575, 0x2c54,
+ 0x8576, 0x2e30,
+ 0x8577, 0x2e1d,
+ 0x8578, 0x2e22,
+ 0x8579, 0x2e2f,
+ 0x857a, 0x2e21,
+ 0x857b, 0x2e19,
+ 0x857c, 0x2e1e,
+ 0x857e, 0x145c,
+ 0x8580, 0x2e12,
+ 0x8581, 0x2e2a,
+ 0x8582, 0x2e2c,
+ 0x8583, 0x2e11,
+ 0x8584, 0x145b,
+ 0x8585, 0x2e2e,
+ 0x8586, 0x2e26,
+ 0x8587, 0x1462,
+ 0x8588, 0x2e2d,
+ 0x8589, 0x2e1f,
+ 0x858a, 0x1464,
+ 0x858b, 0x2e17,
+ 0x858c, 0x2c58,
+ 0x858d, 0x2e27,
+ 0x858e, 0x2e24,
+ 0x858f, 0x2e13,
+ 0x8590, 0x2e32,
+ 0x8591, 0x145e,
+ 0x8594, 0x145f,
+ 0x8595, 0x2e15,
+ 0x8596, 0x2e25,
+ 0x8598, 0x2e31,
+ 0x8599, 0x2e28,
+ 0x859a, 0x2e1b,
+ 0x859b, 0x1461,
+ 0x859c, 0x145d,
+ 0x859d, 0x2e29,
+ 0x859e, 0x2e1c,
+ 0x859f, 0x2e33,
+ 0x85a0, 0x2e16,
+ 0x85a1, 0x2e20,
+ 0x85a2, 0x2e2b,
+ 0x85a3, 0x2e18,
+ 0x85a4, 0x2e1a,
+ 0x85a6, 0x1465,
+ 0x85a7, 0x2e14,
+ 0x85a8, 0x1463,
+ 0x85a9, 0x151c,
+ 0x85aa, 0x145a,
+ 0x85af, 0x1460,
+ 0x85b0, 0x1520,
+ 0x85b1, 0x2fa6,
+ 0x85b3, 0x2f9c,
+ 0x85b4, 0x2f97,
+ 0x85b5, 0x2f9d,
+ 0x85b6, 0x2fa7,
+ 0x85b7, 0x2fab,
+ 0x85b8, 0x2faa,
+ 0x85b9, 0x1522,
+ 0x85ba, 0x1521,
+ 0x85bd, 0x2f9e,
+ 0x85be, 0x2fac,
+ 0x85bf, 0x2fa1,
+ 0x85c0, 0x2f99,
+ 0x85c1, 0x37fe,
+ 0x85c2, 0x2f9b,
+ 0x85c3, 0x2f9a,
+ 0x85c4, 0x2fa0,
+ 0x85c5, 0x2fa5,
+ 0x85c6, 0x2f98,
+ 0x85c7, 0x2f9f,
+ 0x85c8, 0x2fa4,
+ 0x85c9, 0x151f,
+ 0x85cb, 0x2fa2,
+ 0x85cd, 0x151d,
+ 0x85ce, 0x2fa3,
+ 0x85cf, 0x151b,
+ 0x85d0, 0x151e,
+ 0x85d1, 0x3101,
+ 0x85d2, 0x2fa8,
+ 0x85d5, 0x15b7,
+ 0x85d7, 0x30f9,
+ 0x85d8, 0x30fd,
+ 0x85d9, 0x30f5,
+ 0x85da, 0x30f8,
+ 0x85dc, 0x3100,
+ 0x85dd, 0x15b5,
+ 0x85de, 0x3105,
+ 0x85df, 0x30fe,
+ 0x85e0, 0x476d,
+ 0x85e1, 0x30f6,
+ 0x85e2, 0x3106,
+ 0x85e3, 0x30ff,
+ 0x85e4, 0x15b8,
+ 0x85e6, 0x3103,
+ 0x85e8, 0x30f7,
+ 0x85e9, 0x15b4,
+ 0x85ea, 0x15b6,
+ 0x85eb, 0x30f2,
+ 0x85ec, 0x30fa,
+ 0x85ed, 0x30f4,
+ 0x85ee, 0x3c56,
+ 0x85ef, 0x3104,
+ 0x85f0, 0x3102,
+ 0x85f1, 0x30f3,
+ 0x85f2, 0x30fb,
+ 0x85f6, 0x3225,
+ 0x85f7, 0x15ba,
+ 0x85f8, 0x30fc,
+ 0x85f9, 0x1638,
+ 0x85fa, 0x163a,
+ 0x85fb, 0x1637,
+ 0x85fc, 0x3c50,
+ 0x85fd, 0x322a,
+ 0x85fe, 0x3222,
+ 0x85ff, 0x3220,
+ 0x8600, 0x3224,
+ 0x8601, 0x3221,
+ 0x8602, 0x3800,
+ 0x8604, 0x3226,
+ 0x8605, 0x3228,
+ 0x8606, 0x163b,
+ 0x8607, 0x163d,
+ 0x8609, 0x3227,
+ 0x860a, 0x163e,
+ 0x860b, 0x163c,
+ 0x860c, 0x3229,
+ 0x860d, 0x4064,
+ 0x8610, 0x3b7f,
+ 0x8611, 0x1639,
+ 0x8614, 0x46be,
+ 0x8616, 0x37fb,
+ 0x8617, 0x1685,
+ 0x8618, 0x32f6,
+ 0x8619, 0x32fc,
+ 0x861a, 0x1687,
+ 0x861b, 0x3223,
+ 0x861c, 0x32fb,
+ 0x861e, 0x3302,
+ 0x861f, 0x32f9,
+ 0x8620, 0x3300,
+ 0x8621, 0x32ff,
+ 0x8622, 0x321f,
+ 0x8623, 0x32fa,
+ 0x8624, 0x2fa9,
+ 0x8625, 0x3303,
+ 0x8626, 0x32f8,
+ 0x8627, 0x32fd,
+ 0x8628, 0x3805,
+ 0x8629, 0x3301,
+ 0x862a, 0x32f7,
+ 0x862c, 0x33aa,
+ 0x862d, 0x1686,
+ 0x862e, 0x32fe,
+ 0x862f, 0x3f9e,
+ 0x8631, 0x3432,
+ 0x8632, 0x33ab,
+ 0x8633, 0x33a9,
+ 0x8634, 0x33a7,
+ 0x8636, 0x33ac,
+ 0x8638, 0x1707,
+ 0x8639, 0x3430,
+ 0x863a, 0x342e,
+ 0x863b, 0x3433,
+ 0x863c, 0x3431,
+ 0x863e, 0x3434,
+ 0x863f, 0x1708,
+ 0x8640, 0x342f,
+ 0x8642, 0x38c1,
+ 0x8643, 0x3497,
+ 0x8645, 0x3b66,
+ 0x8646, 0x34df,
+ 0x864b, 0x353e,
+ 0x864c, 0x3536,
+ 0x864d, 0x1818,
+ 0x864e, 0x0689,
+ 0x8650, 0x07ff,
+ 0x8652, 0x1de3,
+ 0x8653, 0x1de2,
+ 0x8654, 0x09af,
+ 0x8655, 0x0b88,
+ 0x8656, 0x203c,
+ 0x8659, 0x203b,
+ 0x865b, 0x0d48,
+ 0x865c, 0x0eed,
+ 0x865e, 0x0eec,
+ 0x865f, 0x0eee,
+ 0x8661, 0x27ce,
+ 0x8662, 0x2a0e,
+ 0x8663, 0x2c5e,
+ 0x8664, 0x2c60,
+ 0x8665, 0x2c5f,
+ 0x8667, 0x1466,
+ 0x8668, 0x2e34,
+ 0x8669, 0x2fad,
+ 0x866a, 0x351e,
+ 0x866b, 0x040f,
+ 0x866c, 0x3813,
+ 0x866d, 0x1a46,
+ 0x866f, 0x1a45,
+ 0x8670, 0x1a44,
+ 0x8671, 0x068a,
+ 0x8672, 0x476f,
+ 0x8673, 0x1bfd,
+ 0x8674, 0x1bfb,
+ 0x8677, 0x1bfa,
+ 0x8679, 0x0800,
+ 0x867a, 0x0802,
+ 0x867b, 0x0801,
+ 0x867c, 0x1bfc,
+ 0x867e, 0x380a,
+ 0x8685, 0x1def,
+ 0x8686, 0x1dec,
+ 0x8687, 0x1dea,
+ 0x868a, 0x09b0,
+ 0x868b, 0x1ded,
+ 0x868c, 0x09b5,
+ 0x868d, 0x1de7,
+ 0x868e, 0x1df6,
+ 0x8690, 0x1df8,
+ 0x8691, 0x1de8,
+ 0x8692, 0x4770,
+ 0x8693, 0x09b2,
+ 0x8694, 0x1df9,
+ 0x8695, 0x1df4,
+ 0x8696, 0x1de6,
+ 0x8697, 0x1deb,
+ 0x8698, 0x1df5,
+ 0x8699, 0x1df1,
+ 0x869a, 0x1dee,
+ 0x869c, 0x09b7,
+ 0x869d, 0x1df7,
+ 0x869e, 0x1de9,
+ 0x86a0, 0x3b88,
+ 0x86a1, 0x1df2,
+ 0x86a2, 0x1de4,
+ 0x86a3, 0x09b6,
+ 0x86a4, 0x09b3,
+ 0x86a5, 0x1df0,
+ 0x86a7, 0x1df3,
+ 0x86a8, 0x1de5,
+ 0x86a9, 0x09b4,
+ 0x86aa, 0x09b1,
+ 0x86ad, 0x3f06,
+ 0x86af, 0x0b92,
+ 0x86b0, 0x2043,
+ 0x86b1, 0x0b91,
+ 0x86b2, 0x43e0,
+ 0x86b3, 0x2046,
+ 0x86b4, 0x2049,
+ 0x86b5, 0x0b8e,
+ 0x86b6, 0x0b8c,
+ 0x86b7, 0x203e,
+ 0x86b8, 0x2047,
+ 0x86b9, 0x2045,
+ 0x86ba, 0x2042,
+ 0x86bb, 0x204a,
+ 0x86bd, 0x204d,
+ 0x86bf, 0x203d,
+ 0x86c0, 0x0b8b,
+ 0x86c1, 0x2040,
+ 0x86c2, 0x203f,
+ 0x86c3, 0x204c,
+ 0x86c4, 0x0b8d,
+ 0x86c5, 0x2041,
+ 0x86c6, 0x0b8f,
+ 0x86c7, 0x0b8a,
+ 0x86c8, 0x2044,
+ 0x86c9, 0x0b93,
+ 0x86cb, 0x0b90,
+ 0x86cc, 0x2048,
+ 0x86d0, 0x0d4f,
+ 0x86d1, 0x22d2,
+ 0x86d3, 0x22c7,
+ 0x86d4, 0x0d4c,
+ 0x86d6, 0x256d,
+ 0x86d7, 0x22d0,
+ 0x86d8, 0x22c4,
+ 0x86d9, 0x0d4a,
+ 0x86da, 0x22c9,
+ 0x86db, 0x0d4d,
+ 0x86dc, 0x22cd,
+ 0x86dd, 0x22cb,
+ 0x86de, 0x0d50,
+ 0x86df, 0x0d49,
+ 0x86e2, 0x22c5,
+ 0x86e3, 0x22c8,
+ 0x86e4, 0x0d4e,
+ 0x86e6, 0x22c6,
+ 0x86e8, 0x22d1,
+ 0x86e9, 0x22cf,
+ 0x86ea, 0x22ca,
+ 0x86eb, 0x22cc,
+ 0x86ec, 0x22ce,
+ 0x86ed, 0x0d4b,
+ 0x86ef, 0x4771,
+ 0x86f5, 0x256e,
+ 0x86f6, 0x2574,
+ 0x86f7, 0x256a,
+ 0x86f8, 0x2570,
+ 0x86f9, 0x0eef,
+ 0x86fa, 0x256c,
+ 0x86fb, 0x0ef5,
+ 0x86fe, 0x0ef4,
+ 0x8700, 0x0ef3,
+ 0x8701, 0x2573,
+ 0x8702, 0x0ef6,
+ 0x8704, 0x2569,
+ 0x8705, 0x2576,
+ 0x8706, 0x0ef8,
+ 0x8707, 0x0ef2,
+ 0x8708, 0x0ef1,
+ 0x8709, 0x2572,
+ 0x870a, 0x0ef9,
+ 0x870b, 0x2568,
+ 0x870c, 0x256b,
+ 0x870d, 0x2575,
+ 0x870e, 0x2571,
+ 0x8711, 0x27ee,
+ 0x8712, 0x27e3,
+ 0x8713, 0x0ef0,
+ 0x8718, 0x1098,
+ 0x8719, 0x27d7,
+ 0x871a, 0x27ec,
+ 0x871b, 0x27d8,
+ 0x871c, 0x1093,
+ 0x871e, 0x27d5,
+ 0x8720, 0x27de,
+ 0x8721, 0x27d6,
+ 0x8722, 0x1095,
+ 0x8723, 0x27d0,
+ 0x8724, 0x27eb,
+ 0x8725, 0x1096,
+ 0x8726, 0x27e8,
+ 0x8728, 0x27d1,
+ 0x8729, 0x109b,
+ 0x872a, 0x27e0,
+ 0x872c, 0x27da,
+ 0x872d, 0x27e1,
+ 0x872e, 0x27d4,
+ 0x8730, 0x27ed,
+ 0x8731, 0x27e5,
+ 0x8732, 0x27df,
+ 0x8733, 0x27cf,
+ 0x8734, 0x1097,
+ 0x8735, 0x27e6,
+ 0x8737, 0x109a,
+ 0x8738, 0x27ea,
+ 0x873a, 0x27e4,
+ 0x873b, 0x1094,
+ 0x873c, 0x27e2,
+ 0x873e, 0x27dc,
+ 0x873f, 0x1092,
+ 0x8740, 0x27d3,
+ 0x8741, 0x27db,
+ 0x8742, 0x27e7,
+ 0x8743, 0x27d9,
+ 0x8746, 0x27dd,
+ 0x874c, 0x1208,
+ 0x874d, 0x256f,
+ 0x874e, 0x2a20,
+ 0x874f, 0x2a29,
+ 0x8750, 0x2a1f,
+ 0x8751, 0x2a1b,
+ 0x8752, 0x2a18,
+ 0x8753, 0x1209,
+ 0x8754, 0x2a16,
+ 0x8755, 0x1099,
+ 0x8756, 0x2a0f,
+ 0x8757, 0x1207,
+ 0x8758, 0x2a15,
+ 0x8759, 0x1206,
+ 0x875a, 0x2a1a,
+ 0x875b, 0x2a17,
+ 0x875c, 0x2a27,
+ 0x875d, 0x2a22,
+ 0x875e, 0x2a1c,
+ 0x875f, 0x2a21,
+ 0x8760, 0x1202,
+ 0x8761, 0x2a19,
+ 0x8762, 0x2a2c,
+ 0x8763, 0x2a10,
+ 0x8765, 0x2a28,
+ 0x8766, 0x1203,
+ 0x8767, 0x2a2d,
+ 0x8768, 0x1205,
+ 0x8769, 0x2a2e,
+ 0x876a, 0x2a1e,
+ 0x876b, 0x27d2,
+ 0x876c, 0x2a24,
+ 0x876d, 0x2a1d,
+ 0x876e, 0x2a26,
+ 0x876f, 0x2a23,
+ 0x8770, 0x3e6c,
+ 0x8771, 0x380b,
+ 0x8773, 0x2a14,
+ 0x8774, 0x1200,
+ 0x8775, 0x2a2b,
+ 0x8776, 0x1201,
+ 0x8777, 0x2a12,
+ 0x8778, 0x1204,
+ 0x8779, 0x2c6b,
+ 0x877a, 0x2a25,
+ 0x877b, 0x2a2a,
+ 0x877d, 0x4045,
+ 0x8781, 0x2c68,
+ 0x8782, 0x11ff,
+ 0x8783, 0x1340,
+ 0x8784, 0x2c72,
+ 0x8785, 0x2c6e,
+ 0x8786, 0x3eb0,
+ 0x8787, 0x2c6c,
+ 0x8788, 0x2c67,
+ 0x8789, 0x2c76,
+ 0x878b, 0x43e2,
+ 0x878c, 0x3fef,
+ 0x878d, 0x1344,
+ 0x878f, 0x2c63,
+ 0x8790, 0x2c6f,
+ 0x8792, 0x2c66,
+ 0x8793, 0x2c65,
+ 0x8794, 0x2c73,
+ 0x8796, 0x2c69,
+ 0x8797, 0x2c64,
+ 0x8798, 0x2c6a,
+ 0x879a, 0x2c75,
+ 0x879b, 0x2c62,
+ 0x879c, 0x2c74,
+ 0x879d, 0x2c71,
+ 0x879e, 0x1342,
+ 0x879f, 0x1341,
+ 0x87a2, 0x1343,
+ 0x87a3, 0x2c6d,
+ 0x87a4, 0x2c61,
+ 0x87a5, 0x3d88,
+ 0x87a9, 0x3fec,
+ 0x87aa, 0x2e36,
+ 0x87ab, 0x146c,
+ 0x87ac, 0x2e3a,
+ 0x87ad, 0x2e37,
+ 0x87ae, 0x2e3e,
+ 0x87af, 0x2e44,
+ 0x87b0, 0x2e39,
+ 0x87b1, 0x380f,
+ 0x87b2, 0x2e4d,
+ 0x87b3, 0x1469,
+ 0x87b4, 0x2e47,
+ 0x87b5, 0x2e3c,
+ 0x87b6, 0x2e48,
+ 0x87b7, 0x2e43,
+ 0x87b8, 0x2e4a,
+ 0x87b9, 0x2e3b,
+ 0x87ba, 0x146e,
+ 0x87bb, 0x146d,
+ 0x87bc, 0x2e3d,
+ 0x87bd, 0x2e4b,
+ 0x87be, 0x2e35,
+ 0x87bf, 0x2e49,
+ 0x87c0, 0x1467,
+ 0x87c1, 0x3ffc,
+ 0x87c2, 0x2e41,
+ 0x87c3, 0x2e40,
+ 0x87c4, 0x2e45,
+ 0x87c5, 0x2e38,
+ 0x87c6, 0x146b,
+ 0x87c8, 0x146f,
+ 0x87c9, 0x2e3f,
+ 0x87ca, 0x2e46,
+ 0x87cb, 0x1470,
+ 0x87cc, 0x2e42,
+ 0x87ce, 0x3fed,
+ 0x87d1, 0x1468,
+ 0x87d2, 0x146a,
+ 0x87d3, 0x2fba,
+ 0x87d4, 0x2fb8,
+ 0x87d6, 0x3f92,
+ 0x87d7, 0x2fbe,
+ 0x87d8, 0x2fbc,
+ 0x87d9, 0x2fbf,
+ 0x87da, 0x3810,
+ 0x87db, 0x2fb1,
+ 0x87dc, 0x2fb9,
+ 0x87dd, 0x2fc3,
+ 0x87de, 0x2e4c,
+ 0x87df, 0x2fb5,
+ 0x87e0, 0x1526,
+ 0x87e1, 0x2a13,
+ 0x87e2, 0x2fb0,
+ 0x87e3, 0x2fbd,
+ 0x87e4, 0x2fb7,
+ 0x87e5, 0x2fb4,
+ 0x87e6, 0x2faf,
+ 0x87e7, 0x2fae,
+ 0x87e8, 0x2fc2,
+ 0x87ea, 0x2fb3,
+ 0x87eb, 0x2fb2,
+ 0x87ec, 0x1524,
+ 0x87ed, 0x2fbb,
+ 0x87ee, 0x380d,
+ 0x87ef, 0x1523,
+ 0x87f2, 0x1525,
+ 0x87f3, 0x2fb6,
+ 0x87f4, 0x2fc1,
+ 0x87f5, 0x3fae,
+ 0x87f6, 0x310a,
+ 0x87f9, 0x15be,
+ 0x87fa, 0x3108,
+ 0x87fb, 0x15bb,
+ 0x87fc, 0x3110,
+ 0x87fe, 0x15bf,
+ 0x87ff, 0x3112,
+ 0x8800, 0x3107,
+ 0x8801, 0x2fc0,
+ 0x8802, 0x3114,
+ 0x8803, 0x3109,
+ 0x8804, 0x3eaf,
+ 0x8805, 0x15bc,
+ 0x8806, 0x310f,
+ 0x8808, 0x3111,
+ 0x8809, 0x310c,
+ 0x880a, 0x3113,
+ 0x880b, 0x310e,
+ 0x880c, 0x310d,
+ 0x880d, 0x15bd,
+ 0x880f, 0x3811,
+ 0x8810, 0x322c,
+ 0x8813, 0x322f,
+ 0x8814, 0x163f,
+ 0x8816, 0x3230,
+ 0x8817, 0x322e,
+ 0x8818, 0x3f7a,
+ 0x8819, 0x322b,
+ 0x881b, 0x3306,
+ 0x881c, 0x3309,
+ 0x881d, 0x3305,
+ 0x881f, 0x168b,
+ 0x8820, 0x3307,
+ 0x8821, 0x168a,
+ 0x8822, 0x1689,
+ 0x8823, 0x1688,
+ 0x8824, 0x3308,
+ 0x8825, 0x33b1,
+ 0x8826, 0x33af,
+ 0x8827, 0x3e07,
+ 0x8828, 0x33ae,
+ 0x8829, 0x3304,
+ 0x882a, 0x33b0,
+ 0x882b, 0x330a,
+ 0x882c, 0x33ad,
+ 0x882d, 0x3b8b,
+ 0x882e, 0x3437,
+ 0x882f, 0x3415,
+ 0x8830, 0x3435,
+ 0x8831, 0x1709,
+ 0x8832, 0x3436,
+ 0x8833, 0x3438,
+ 0x8835, 0x349a,
+ 0x8836, 0x1728,
+ 0x8837, 0x3499,
+ 0x8838, 0x3498,
+ 0x8839, 0x1729,
+ 0x883b, 0x1747,
+ 0x883c, 0x3508,
+ 0x883d, 0x3520,
+ 0x883e, 0x351f,
+ 0x883f, 0x3521,
+ 0x8840, 0x0410,
+ 0x8841, 0x1bfe,
+ 0x8842, 0x3f5a,
+ 0x8843, 0x1dfa,
+ 0x8845, 0x3816,
+ 0x8848, 0x22d3,
+ 0x884a, 0x330b,
+ 0x884b, 0x349b,
+ 0x884c, 0x0411,
+ 0x884d, 0x0803,
+ 0x884e, 0x1bff,
+ 0x884f, 0x3844,
+ 0x8852, 0x204f,
+ 0x8853, 0x0b94,
+ 0x8855, 0x22d5,
+ 0x8856, 0x22d4,
+ 0x8857, 0x0d51,
+ 0x8859, 0x0efa,
+ 0x885a, 0x2a2f,
+ 0x885b, 0x120a,
+ 0x885d, 0x120b,
+ 0x885e, 0x381b,
+ 0x8860, 0x3a46,
+ 0x8861, 0x1345,
+ 0x8862, 0x172a,
+ 0x8863, 0x0412,
+ 0x8864, 0x4502,
+ 0x8865, 0x3dfc,
+ 0x8867, 0x1c00,
+ 0x8868, 0x068c,
+ 0x8869, 0x1c02,
+ 0x886a, 0x1c01,
+ 0x886b, 0x0804,
+ 0x886d, 0x1dfc,
+ 0x886e, 0x3b8e,
+ 0x886f, 0x1e03,
+ 0x8870, 0x09b8,
+ 0x8871, 0x1e01,
+ 0x8872, 0x1dff,
+ 0x8874, 0x1e06,
+ 0x8875, 0x1dfd,
+ 0x8877, 0x09b9,
+ 0x8879, 0x09bd,
+ 0x887c, 0x1e07,
+ 0x887d, 0x09bc,
+ 0x887e, 0x1e05,
+ 0x887f, 0x1e02,
+ 0x8880, 0x1e00,
+ 0x8881, 0x09ba,
+ 0x8883, 0x1e04,
+ 0x8884, 0x42f7,
+ 0x8887, 0x3b90,
+ 0x8888, 0x0b96,
+ 0x8889, 0x2050,
+ 0x888b, 0x0b9b,
+ 0x888c, 0x2060,
+ 0x888d, 0x0b9a,
+ 0x888e, 0x2062,
+ 0x8891, 0x2056,
+ 0x8892, 0x0b98,
+ 0x8893, 0x2061,
+ 0x8895, 0x2051,
+ 0x8896, 0x0b99,
+ 0x8897, 0x205d,
+ 0x8898, 0x2059,
+ 0x8899, 0x205b,
+ 0x889a, 0x2055,
+ 0x889b, 0x205c,
+ 0x889c, 0x381c,
+ 0x889e, 0x0b95,
+ 0x889f, 0x2058,
+ 0x88a0, 0x3fa0,
+ 0x88a1, 0x2057,
+ 0x88a2, 0x2053,
+ 0x88a4, 0x205e,
+ 0x88a7, 0x205a,
+ 0x88a8, 0x2052,
+ 0x88aa, 0x2054,
+ 0x88ab, 0x0b97,
+ 0x88ac, 0x205f,
+ 0x88ae, 0x4775,
+ 0x88b1, 0x0d54,
+ 0x88b2, 0x22e0,
+ 0x88b4, 0x381e,
+ 0x88b6, 0x22dc,
+ 0x88b7, 0x22de,
+ 0x88b8, 0x22d9,
+ 0x88b9, 0x22d8,
+ 0x88ba, 0x22d6,
+ 0x88bc, 0x22dd,
+ 0x88bd, 0x22df,
+ 0x88be, 0x22db,
+ 0x88bf, 0x3b91,
+ 0x88c0, 0x22da,
+ 0x88c1, 0x0d52,
+ 0x88c5, 0x3820,
+ 0x88c7, 0x3eb1,
+ 0x88c9, 0x22e2,
+ 0x88ca, 0x0f02,
+ 0x88cb, 0x2578,
+ 0x88cc, 0x257e,
+ 0x88cd, 0x2579,
+ 0x88cf, 0x36ea,
+ 0x88d0, 0x257f,
+ 0x88d2, 0x0f04,
+ 0x88d4, 0x0efc,
+ 0x88d5, 0x0f03,
+ 0x88d6, 0x2577,
+ 0x88d7, 0x22d7,
+ 0x88d8, 0x0eff,
+ 0x88d9, 0x0efd,
+ 0x88da, 0x257d,
+ 0x88db, 0x257c,
+ 0x88dc, 0x0efe,
+ 0x88dd, 0x0f00,
+ 0x88de, 0x257b,
+ 0x88df, 0x0efb,
+ 0x88e1, 0x0f01,
+ 0x88e6, 0x3b92,
+ 0x88e7, 0x27f0,
+ 0x88e8, 0x10a2,
+ 0x88eb, 0x27fb,
+ 0x88ec, 0x27fa,
+ 0x88ee, 0x27f5,
+ 0x88ef, 0x10a4,
+ 0x88f0, 0x27f9,
+ 0x88f1, 0x27f1,
+ 0x88f3, 0x109c,
+ 0x88f4, 0x109e,
+ 0x88f5, 0x3e08,
+ 0x88f6, 0x27f7,
+ 0x88f7, 0x27ef,
+ 0x88f8, 0x10a0,
+ 0x88f9, 0x109f,
+ 0x88fa, 0x27f3,
+ 0x88fb, 0x27f8,
+ 0x88fc, 0x27f6,
+ 0x88fd, 0x10a1,
+ 0x88fe, 0x27f4,
+ 0x88ff, 0x4776,
+ 0x8900, 0x42fa,
+ 0x8901, 0x22e1,
+ 0x8902, 0x109d,
+ 0x8905, 0x2a30,
+ 0x8906, 0x2a37,
+ 0x8907, 0x120d,
+ 0x8909, 0x2a3b,
+ 0x890a, 0x1211,
+ 0x890b, 0x2a33,
+ 0x890c, 0x2a31,
+ 0x890e, 0x2a3a,
+ 0x8910, 0x120c,
+ 0x8911, 0x2a39,
+ 0x8912, 0x120e,
+ 0x8914, 0x2a32,
+ 0x8915, 0x1210,
+ 0x8916, 0x2a38,
+ 0x8917, 0x2a34,
+ 0x891a, 0x10a3,
+ 0x891e, 0x2c77,
+ 0x891f, 0x2c83,
+ 0x8921, 0x134a,
+ 0x8922, 0x2c7e,
+ 0x8923, 0x2c80,
+ 0x8924, 0x4777,
+ 0x8925, 0x1348,
+ 0x8926, 0x2c78,
+ 0x8927, 0x2c7c,
+ 0x8929, 0x2c7f,
+ 0x892a, 0x1346,
+ 0x892b, 0x1349,
+ 0x892c, 0x2c82,
+ 0x892d, 0x2c7a,
+ 0x892f, 0x2c81,
+ 0x8930, 0x2c79,
+ 0x8931, 0x2c7d,
+ 0x8932, 0x1347,
+ 0x8933, 0x2e4f,
+ 0x8935, 0x2e4e,
+ 0x8936, 0x1472,
+ 0x8937, 0x2e54,
+ 0x8938, 0x1474,
+ 0x893b, 0x1471,
+ 0x893c, 0x2e50,
+ 0x893d, 0x1475,
+ 0x893e, 0x2e51,
+ 0x8941, 0x2e52,
+ 0x8942, 0x2e55,
+ 0x8943, 0x3e16,
+ 0x8944, 0x1473,
+ 0x8946, 0x2fc8,
+ 0x8947, 0x43e3,
+ 0x8949, 0x2fcb,
+ 0x894b, 0x2fc5,
+ 0x894c, 0x2fc7,
+ 0x894d, 0x3b94,
+ 0x894f, 0x2fc6,
+ 0x8950, 0x2fc9,
+ 0x8952, 0x2e53,
+ 0x8953, 0x2fc4,
+ 0x8954, 0x3b96,
+ 0x8956, 0x15c2,
+ 0x8957, 0x3118,
+ 0x8958, 0x311b,
+ 0x8959, 0x311d,
+ 0x895a, 0x3116,
+ 0x895c, 0x311a,
+ 0x895d, 0x311c,
+ 0x895e, 0x15c3,
+ 0x895f, 0x15c1,
+ 0x8960, 0x15c0,
+ 0x8961, 0x3119,
+ 0x8962, 0x3115,
+ 0x8963, 0x3231,
+ 0x8964, 0x1641,
+ 0x8965, 0x3b93,
+ 0x8966, 0x3232,
+ 0x8969, 0x330d,
+ 0x896a, 0x168c,
+ 0x896b, 0x330f,
+ 0x896c, 0x168d,
+ 0x896d, 0x330c,
+ 0x896e, 0x330e,
+ 0x896f, 0x16d6,
+ 0x8971, 0x33b2,
+ 0x8972, 0x16d5,
+ 0x8973, 0x343b,
+ 0x8974, 0x343a,
+ 0x8976, 0x3439,
+ 0x8977, 0x3dea,
+ 0x8979, 0x34e2,
+ 0x897b, 0x34e5,
+ 0x897c, 0x34e4,
+ 0x897e, 0x1819,
+ 0x897f, 0x0413,
+ 0x8980, 0x4708,
+ 0x8981, 0x0805,
+ 0x8982, 0x2063,
+ 0x8983, 0x0d55,
+ 0x8985, 0x2580,
+ 0x8986, 0x1527,
+ 0x8987, 0x3822,
+ 0x8988, 0x311e,
+ 0x8989, 0x3fe9,
+ 0x898a, 0x3823,
+ 0x898b, 0x0508,
+ 0x898f, 0x0b9d,
+ 0x8991, 0x4778,
+ 0x8993, 0x0b9c,
+ 0x8994, 0x3fe0,
+ 0x8995, 0x22e3,
+ 0x8996, 0x0d56,
+ 0x8997, 0x22e5,
+ 0x8998, 0x22e4,
+ 0x899b, 0x2581,
+ 0x899c, 0x0f05,
+ 0x899d, 0x27fc,
+ 0x899e, 0x27ff,
+ 0x899f, 0x27fe,
+ 0x89a1, 0x27fd,
+ 0x89a2, 0x2a3c,
+ 0x89a3, 0x2a3e,
+ 0x89a4, 0x2a3d,
+ 0x89a5, 0x3d93,
+ 0x89a6, 0x134c,
+ 0x89a7, 0x3826,
+ 0x89a9, 0x3825,
+ 0x89aa, 0x134b,
+ 0x89ac, 0x1476,
+ 0x89ad, 0x2e56,
+ 0x89ae, 0x2e58,
+ 0x89af, 0x2e57,
+ 0x89b2, 0x1528,
+ 0x89b6, 0x3120,
+ 0x89b7, 0x311f,
+ 0x89b9, 0x3233,
+ 0x89ba, 0x1642,
+ 0x89bc, 0x3827,
+ 0x89bd, 0x168e,
+ 0x89be, 0x33b4,
+ 0x89bf, 0x33b3,
+ 0x89c0, 0x1748,
+ 0x89c1, 0x4503,
+ 0x89c6, 0x4566,
+ 0x89d2, 0x0509,
+ 0x89d3, 0x1c03,
+ 0x89d4, 0x0806,
+ 0x89d5, 0x2066,
+ 0x89d6, 0x2064,
+ 0x89d9, 0x2065,
+ 0x89da, 0x22e7,
+ 0x89dc, 0x2588,
+ 0x89dd, 0x22e6,
+ 0x89df, 0x2582,
+ 0x89e0, 0x2586,
+ 0x89e1, 0x2585,
+ 0x89e2, 0x2587,
+ 0x89e3, 0x0f06,
+ 0x89e4, 0x2584,
+ 0x89e5, 0x2583,
+ 0x89e6, 0x2589,
+ 0x89e7, 0x3829,
+ 0x89e8, 0x2802,
+ 0x89e9, 0x2800,
+ 0x89eb, 0x2801,
+ 0x89ec, 0x2a41,
+ 0x89ed, 0x2a3f,
+ 0x89f0, 0x2a40,
+ 0x89f1, 0x2c84,
+ 0x89f2, 0x2e59,
+ 0x89f4, 0x1529,
+ 0x89f6, 0x3121,
+ 0x89f7, 0x3234,
+ 0x89f8, 0x1643,
+ 0x89fa, 0x3310,
+ 0x89fb, 0x33b5,
+ 0x89fc, 0x16d7,
+ 0x89fe, 0x343c,
+ 0x89ff, 0x34e6,
+ 0x8a00, 0x050a,
+ 0x8a02, 0x0808,
+ 0x8a04, 0x1c04,
+ 0x8a07, 0x1c05,
+ 0x8a08, 0x0807,
+ 0x8a0a, 0x09c3,
+ 0x8a0c, 0x09c1,
+ 0x8a0e, 0x09c0,
+ 0x8a0f, 0x09c7,
+ 0x8a10, 0x09bf,
+ 0x8a11, 0x09c8,
+ 0x8a12, 0x1e08,
+ 0x8a13, 0x09c5,
+ 0x8a15, 0x09c2,
+ 0x8a16, 0x09c6,
+ 0x8a17, 0x09c4,
+ 0x8a18, 0x09be,
+ 0x8a1b, 0x0ba5,
+ 0x8a1c, 0x3ba3,
+ 0x8a1d, 0x0b9f,
+ 0x8a1e, 0x206a,
+ 0x8a1f, 0x0ba4,
+ 0x8a22, 0x0ba6,
+ 0x8a23, 0x0ba0,
+ 0x8a25, 0x0ba1,
+ 0x8a27, 0x2068,
+ 0x8a29, 0x43e5,
+ 0x8a2a, 0x0b9e,
+ 0x8a2b, 0x3bd1,
+ 0x8a2c, 0x2069,
+ 0x8a2d, 0x0ba3,
+ 0x8a30, 0x2067,
+ 0x8a31, 0x0ba2,
+ 0x8a34, 0x0d61,
+ 0x8a36, 0x0d63,
+ 0x8a38, 0x477a,
+ 0x8a39, 0x22eb,
+ 0x8a3a, 0x0d62,
+ 0x8a3b, 0x0d57,
+ 0x8a3c, 0x0d5b,
+ 0x8a3d, 0x3ba2,
+ 0x8a3e, 0x0f19,
+ 0x8a3f, 0x258e,
+ 0x8a40, 0x22ed,
+ 0x8a41, 0x0d5c,
+ 0x8a44, 0x22f0,
+ 0x8a46, 0x0d60,
+ 0x8a48, 0x22f3,
+ 0x8a49, 0x3ff0,
+ 0x8a4a, 0x22f5,
+ 0x8a4c, 0x22f6,
+ 0x8a4d, 0x22ea,
+ 0x8a4e, 0x22e9,
+ 0x8a4f, 0x22f7,
+ 0x8a50, 0x0d5f,
+ 0x8a51, 0x22f4,
+ 0x8a52, 0x22f2,
+ 0x8a54, 0x0d5d,
+ 0x8a55, 0x0d59,
+ 0x8a56, 0x0d64,
+ 0x8a57, 0x22ee,
+ 0x8a59, 0x22ec,
+ 0x8a5b, 0x0d5e,
+ 0x8a5e, 0x0d5a,
+ 0x8a60, 0x0d58,
+ 0x8a61, 0x258d,
+ 0x8a62, 0x0f14,
+ 0x8a63, 0x0f0f,
+ 0x8a66, 0x0f0a,
+ 0x8a67, 0x3f8e,
+ 0x8a68, 0x0f1a,
+ 0x8a69, 0x0f0b,
+ 0x8a6b, 0x0f07,
+ 0x8a6c, 0x0f16,
+ 0x8a6d, 0x0f13,
+ 0x8a6e, 0x0f15,
+ 0x8a70, 0x0f0c,
+ 0x8a71, 0x0f11,
+ 0x8a72, 0x0f08,
+ 0x8a74, 0x2595,
+ 0x8a75, 0x2592,
+ 0x8a76, 0x258a,
+ 0x8a77, 0x258f,
+ 0x8a79, 0x0f17,
+ 0x8a7a, 0x2596,
+ 0x8a7b, 0x0f18,
+ 0x8a7c, 0x0f0e,
+ 0x8a7e, 0x3fa5,
+ 0x8a7f, 0x258c,
+ 0x8a81, 0x2594,
+ 0x8a82, 0x2590,
+ 0x8a83, 0x2593,
+ 0x8a84, 0x2591,
+ 0x8a85, 0x0f12,
+ 0x8a86, 0x258b,
+ 0x8a87, 0x0f0d,
+ 0x8a8b, 0x2805,
+ 0x8a8c, 0x10a6,
+ 0x8a8d, 0x10a9,
+ 0x8a8f, 0x2807,
+ 0x8a90, 0x382f,
+ 0x8a91, 0x10b1,
+ 0x8a92, 0x2806,
+ 0x8a93, 0x10ab,
+ 0x8a94, 0x477b,
+ 0x8a95, 0x1216,
+ 0x8a96, 0x2808,
+ 0x8a98, 0x10b0,
+ 0x8a99, 0x2804,
+ 0x8a9a, 0x10b2,
+ 0x8a9c, 0x382c,
+ 0x8a9e, 0x10a7,
+ 0x8aa0, 0x0f10,
+ 0x8aa1, 0x10aa,
+ 0x8aa3, 0x10a8,
+ 0x8aa4, 0x10ac,
+ 0x8aa5, 0x10ae,
+ 0x8aa6, 0x10a5,
+ 0x8aa7, 0x10b3,
+ 0x8aa8, 0x10af,
+ 0x8aa9, 0x383d,
+ 0x8aaa, 0x10ad,
+ 0x8aab, 0x2803,
+ 0x8aaf, 0x3841,
+ 0x8ab0, 0x121d,
+ 0x8ab2, 0x1219,
+ 0x8ab4, 0x477c,
+ 0x8ab6, 0x1220,
+ 0x8ab8, 0x2a44,
+ 0x8ab9, 0x1221,
+ 0x8aba, 0x2a50,
+ 0x8abb, 0x2a49,
+ 0x8abc, 0x1212,
+ 0x8abd, 0x2a51,
+ 0x8abe, 0x2a4b,
+ 0x8abf, 0x121c,
+ 0x8ac0, 0x2a4c,
+ 0x8ac2, 0x121b,
+ 0x8ac3, 0x2a4f,
+ 0x8ac4, 0x1215,
+ 0x8ac5, 0x2a4d,
+ 0x8ac6, 0x2a43,
+ 0x8ac7, 0x1214,
+ 0x8ac8, 0x2c8f,
+ 0x8ac9, 0x121a,
+ 0x8acb, 0x1217,
+ 0x8acd, 0x121f,
+ 0x8acf, 0x2a42,
+ 0x8ad1, 0x2a46,
+ 0x8ad2, 0x1213,
+ 0x8ad3, 0x2a45,
+ 0x8ad4, 0x2a47,
+ 0x8ad6, 0x121e,
+ 0x8ad7, 0x2a4a,
+ 0x8ad8, 0x2a4e,
+ 0x8ad9, 0x2a52,
+ 0x8ada, 0x39c2,
+ 0x8adb, 0x1222,
+ 0x8adc, 0x1352,
+ 0x8add, 0x2c8a,
+ 0x8ade, 0x2c90,
+ 0x8adf, 0x2c8d,
+ 0x8ae0, 0x2c85,
+ 0x8ae1, 0x2c91,
+ 0x8ae2, 0x2c86,
+ 0x8ae4, 0x2c8c,
+ 0x8ae6, 0x134d,
+ 0x8ae7, 0x1353,
+ 0x8ae8, 0x2c92,
+ 0x8aea, 0x3dd9,
+ 0x8aeb, 0x134f,
+ 0x8aed, 0x1359,
+ 0x8aee, 0x1354,
+ 0x8aef, 0x2c94,
+ 0x8af0, 0x2c8e,
+ 0x8af1, 0x1350,
+ 0x8af2, 0x2c87,
+ 0x8af3, 0x135a,
+ 0x8af4, 0x2c88,
+ 0x8af6, 0x135b,
+ 0x8af7, 0x1358,
+ 0x8af8, 0x1218,
+ 0x8afa, 0x134e,
+ 0x8afb, 0x2c95,
+ 0x8afc, 0x135c,
+ 0x8afe, 0x1355,
+ 0x8aff, 0x2c93,
+ 0x8b00, 0x1351,
+ 0x8b01, 0x1356,
+ 0x8b04, 0x147e,
+ 0x8b05, 0x2e5f,
+ 0x8b06, 0x2e68,
+ 0x8b07, 0x2e65,
+ 0x8b08, 0x2e67,
+ 0x8b0a, 0x147b,
+ 0x8b0b, 0x2e60,
+ 0x8b0c, 0x3836,
+ 0x8b0d, 0x2e66,
+ 0x8b0e, 0x1477,
+ 0x8b0f, 0x2e62,
+ 0x8b10, 0x147f,
+ 0x8b11, 0x2e5e,
+ 0x8b12, 0x2e63,
+ 0x8b13, 0x2e6a,
+ 0x8b14, 0x2c8b,
+ 0x8b15, 0x2e64,
+ 0x8b16, 0x2e5d,
+ 0x8b17, 0x1478,
+ 0x8b18, 0x2e5c,
+ 0x8b19, 0x1479,
+ 0x8b1a, 0x2e6b,
+ 0x8b1b, 0x147a,
+ 0x8b1c, 0x2e69,
+ 0x8b1d, 0x147d,
+ 0x8b1e, 0x2e5b,
+ 0x8b1f, 0x3837,
+ 0x8b20, 0x147c,
+ 0x8b22, 0x2e61,
+ 0x8b23, 0x2fce,
+ 0x8b24, 0x2fdc,
+ 0x8b25, 0x2fd7,
+ 0x8b26, 0x2fd9,
+ 0x8b27, 0x2fcd,
+ 0x8b28, 0x152a,
+ 0x8b2a, 0x2fcc,
+ 0x8b2b, 0x152d,
+ 0x8b2c, 0x152c,
+ 0x8b2d, 0x3f99,
+ 0x8b2e, 0x2fdb,
+ 0x8b2f, 0x2fd3,
+ 0x8b30, 0x2fd0,
+ 0x8b31, 0x2fd6,
+ 0x8b33, 0x2fcf,
+ 0x8b35, 0x2fd1,
+ 0x8b36, 0x2fda,
+ 0x8b37, 0x2fd8,
+ 0x8b39, 0x152b,
+ 0x8b3a, 0x2fdf,
+ 0x8b3b, 0x2fdd,
+ 0x8b3c, 0x2fd4,
+ 0x8b3d, 0x2fde,
+ 0x8b3e, 0x2fd5,
+ 0x8b3f, 0x383a,
+ 0x8b40, 0x3125,
+ 0x8b41, 0x15c4,
+ 0x8b42, 0x312c,
+ 0x8b43, 0x3ff2,
+ 0x8b45, 0x3313,
+ 0x8b46, 0x15cb,
+ 0x8b47, 0x2fd2,
+ 0x8b48, 0x3123,
+ 0x8b49, 0x15c7,
+ 0x8b4a, 0x3124,
+ 0x8b4b, 0x3129,
+ 0x8b4c, 0x383b,
+ 0x8b4e, 0x15c9,
+ 0x8b50, 0x3122,
+ 0x8b51, 0x312b,
+ 0x8b52, 0x312d,
+ 0x8b53, 0x3126,
+ 0x8b54, 0x3128,
+ 0x8b55, 0x312a,
+ 0x8b56, 0x3127,
+ 0x8b57, 0x312e,
+ 0x8b58, 0x15c6,
+ 0x8b59, 0x15cc,
+ 0x8b5a, 0x15c8,
+ 0x8b5c, 0x15c5,
+ 0x8b5d, 0x3237,
+ 0x8b5e, 0x3db8,
+ 0x8b5f, 0x1648,
+ 0x8b60, 0x3235,
+ 0x8b62, 0x3dd4,
+ 0x8b63, 0x3239,
+ 0x8b65, 0x323a,
+ 0x8b66, 0x1646,
+ 0x8b67, 0x323b,
+ 0x8b68, 0x3238,
+ 0x8b69, 0x3bf7,
+ 0x8b6a, 0x3236,
+ 0x8b6b, 0x1649,
+ 0x8b6c, 0x1645,
+ 0x8b6d, 0x323c,
+ 0x8b6f, 0x1647,
+ 0x8b70, 0x1644,
+ 0x8b74, 0x168f,
+ 0x8b77, 0x1690,
+ 0x8b78, 0x3312,
+ 0x8b79, 0x3311,
+ 0x8b7a, 0x3314,
+ 0x8b7d, 0x1691,
+ 0x8b7e, 0x33b6,
+ 0x8b7f, 0x33bb,
+ 0x8b80, 0x16d8,
+ 0x8b81, 0x3d8d,
+ 0x8b82, 0x33b8,
+ 0x8b84, 0x33b7,
+ 0x8b85, 0x33ba,
+ 0x8b86, 0x33b9,
+ 0x8b88, 0x3440,
+ 0x8b8a, 0x170a,
+ 0x8b8b, 0x343f,
+ 0x8b8c, 0x343d,
+ 0x8b8e, 0x343e,
+ 0x8b90, 0x383f,
+ 0x8b92, 0x172c,
+ 0x8b93, 0x172b,
+ 0x8b94, 0x349c,
+ 0x8b96, 0x172d,
+ 0x8b98, 0x34e7,
+ 0x8b9a, 0x1754,
+ 0x8b9b, 0x3840,
+ 0x8b9c, 0x175a,
+ 0x8b9e, 0x3522,
+ 0x8b9f, 0x353f,
+ 0x8ba0, 0x4505,
+ 0x8bbe, 0x4567,
+ 0x8be2, 0x4568,
+ 0x8c37, 0x050b,
+ 0x8c39, 0x206b,
+ 0x8c3b, 0x206c,
+ 0x8c3c, 0x2597,
+ 0x8c3d, 0x2809,
+ 0x8c3e, 0x2a53,
+ 0x8c3f, 0x1481,
+ 0x8c41, 0x1480,
+ 0x8c42, 0x2fe0,
+ 0x8c43, 0x312f,
+ 0x8c45, 0x3441,
+ 0x8c46, 0x050c,
+ 0x8c47, 0x1e09,
+ 0x8c48, 0x09c9,
+ 0x8c49, 0x0ba7,
+ 0x8c4a, 0x2599,
+ 0x8c4b, 0x2598,
+ 0x8c4c, 0x1223,
+ 0x8c4d, 0x2a54,
+ 0x8c4e, 0x1224,
+ 0x8c4f, 0x2e6c,
+ 0x8c50, 0x152e,
+ 0x8c51, 0x477d,
+ 0x8c54, 0x1763,
+ 0x8c55, 0x050d,
+ 0x8c56, 0x1a48,
+ 0x8c57, 0x1e0a,
+ 0x8c5a, 0x0ba8,
+ 0x8c5c, 0x206d,
+ 0x8c5f, 0x22f8,
+ 0x8c61, 0x0d65,
+ 0x8c62, 0x0f1b,
+ 0x8c64, 0x259b,
+ 0x8c65, 0x259a,
+ 0x8c66, 0x259c,
+ 0x8c68, 0x280a,
+ 0x8c6a, 0x10b4,
+ 0x8c6b, 0x135d,
+ 0x8c6c, 0x1225,
+ 0x8c6d, 0x135e,
+ 0x8c6f, 0x2e70,
+ 0x8c70, 0x2e6d,
+ 0x8c71, 0x2e6f,
+ 0x8c72, 0x2e6e,
+ 0x8c73, 0x1482,
+ 0x8c75, 0x2fe1,
+ 0x8c76, 0x3131,
+ 0x8c77, 0x3130,
+ 0x8c78, 0x18e7,
+ 0x8c79, 0x09cb,
+ 0x8c7a, 0x09ca,
+ 0x8c7b, 0x1e0b,
+ 0x8c7d, 0x206f,
+ 0x8c80, 0x22fa,
+ 0x8c81, 0x22f9,
+ 0x8c82, 0x0d66,
+ 0x8c84, 0x259e,
+ 0x8c86, 0x259d,
+ 0x8c89, 0x0f1d,
+ 0x8c8a, 0x0f1c,
+ 0x8c8c, 0x10b6,
+ 0x8c8d, 0x10b5,
+ 0x8c8f, 0x2a55,
+ 0x8c90, 0x2c98,
+ 0x8c91, 0x2c96,
+ 0x8c93, 0x135f,
+ 0x8c94, 0x2e72,
+ 0x8c95, 0x2e71,
+ 0x8c97, 0x2fe4,
+ 0x8c98, 0x2fe3,
+ 0x8c99, 0x2fe2,
+ 0x8c9a, 0x3132,
+ 0x8c9b, 0x3845,
+ 0x8c9c, 0x3523,
+ 0x8c9d, 0x050e,
+ 0x8c9e, 0x080a,
+ 0x8c9f, 0x3bad,
+ 0x8ca0, 0x080b,
+ 0x8ca1, 0x09cc,
+ 0x8ca3, 0x1e0d,
+ 0x8ca4, 0x1e0c,
+ 0x8ca5, 0x2070,
+ 0x8ca7, 0x0bae,
+ 0x8ca8, 0x0bac,
+ 0x8ca9, 0x0ba9,
+ 0x8caa, 0x0bad,
+ 0x8cab, 0x0bab,
+ 0x8cac, 0x0baa,
+ 0x8cad, 0x3ff1,
+ 0x8caf, 0x0d67,
+ 0x8cb0, 0x22fd,
+ 0x8cb2, 0x0f22,
+ 0x8cb3, 0x0d69,
+ 0x8cb4, 0x0d6e,
+ 0x8cb5, 0x22ff,
+ 0x8cb6, 0x0d70,
+ 0x8cb7, 0x0d6f,
+ 0x8cb8, 0x0d72,
+ 0x8cb9, 0x22fe,
+ 0x8cba, 0x22fb,
+ 0x8cbb, 0x0d6c,
+ 0x8cbc, 0x0d68,
+ 0x8cbd, 0x0d6a,
+ 0x8cbe, 0x22fc,
+ 0x8cbf, 0x0d71,
+ 0x8cc0, 0x0d6d,
+ 0x8cc1, 0x0d6b,
+ 0x8cc2, 0x0f24,
+ 0x8cc3, 0x0f23,
+ 0x8cc4, 0x0f21,
+ 0x8cc5, 0x0f25,
+ 0x8cc7, 0x0f1f,
+ 0x8cca, 0x0f1e,
+ 0x8ccc, 0x25a0,
+ 0x8ccd, 0x3e99,
+ 0x8ccf, 0x280d,
+ 0x8cd1, 0x10b8,
+ 0x8cd3, 0x10b7,
+ 0x8cd4, 0x477e,
+ 0x8cd5, 0x280c,
+ 0x8cd6, 0x384b,
+ 0x8cd7, 0x280e,
+ 0x8cd9, 0x2a58,
+ 0x8cda, 0x2a5a,
+ 0x8cdb, 0x3851,
+ 0x8cdc, 0x122e,
+ 0x8cdd, 0x2a5b,
+ 0x8cde, 0x1227,
+ 0x8cdf, 0x2a57,
+ 0x8ce0, 0x1226,
+ 0x8ce1, 0x1230,
+ 0x8ce2, 0x122c,
+ 0x8ce4, 0x1229,
+ 0x8ce5, 0x2a56,
+ 0x8ce6, 0x1228,
+ 0x8ce7, 0x2a5c,
+ 0x8ce8, 0x2a59,
+ 0x8ce9, 0x3bae,
+ 0x8cea, 0x122f,
+ 0x8ceb, 0x3f9c,
+ 0x8cec, 0x122a,
+ 0x8cee, 0x2c9a,
+ 0x8cf0, 0x2c9c,
+ 0x8cf1, 0x2c9b,
+ 0x8cf2, 0x477f,
+ 0x8cf3, 0x2c9d,
+ 0x8cf4, 0x1360,
+ 0x8cf5, 0x2c99,
+ 0x8cf7, 0x3fb1,
+ 0x8cf8, 0x1486,
+ 0x8cf9, 0x2e73,
+ 0x8cfa, 0x1483,
+ 0x8cfb, 0x1487,
+ 0x8cfc, 0x1485,
+ 0x8cfd, 0x1484,
+ 0x8cfe, 0x2fe5,
+ 0x8d00, 0x2fe8,
+ 0x8d02, 0x2fe7,
+ 0x8d03, 0x384f,
+ 0x8d04, 0x2fe6,
+ 0x8d05, 0x152f,
+ 0x8d06, 0x3133,
+ 0x8d08, 0x15cd,
+ 0x8d09, 0x3135,
+ 0x8d0a, 0x15ce,
+ 0x8d0b, 0x4573,
+ 0x8d0c, 0x3f96,
+ 0x8d0d, 0x164b,
+ 0x8d0f, 0x164a,
+ 0x8d10, 0x3316,
+ 0x8d11, 0x3853,
+ 0x8d12, 0x384e,
+ 0x8d13, 0x1692,
+ 0x8d14, 0x3317,
+ 0x8d15, 0x33bc,
+ 0x8d16, 0x16d9,
+ 0x8d18, 0x3e6f,
+ 0x8d19, 0x3442,
+ 0x8d1b, 0x172f,
+ 0x8d1c, 0x4780,
+ 0x8d1d, 0x4506,
+ 0x8d64, 0x050f,
+ 0x8d66, 0x0bb0,
+ 0x8d67, 0x0baf,
+ 0x8d68, 0x25a1,
+ 0x8d6b, 0x10ba,
+ 0x8d6c, 0x2c9e,
+ 0x8d6d, 0x1231,
+ 0x8d6e, 0x2c9f,
+ 0x8d6f, 0x2e74,
+ 0x8d70, 0x0510,
+ 0x8d72, 0x1c06,
+ 0x8d73, 0x080d,
+ 0x8d74, 0x080c,
+ 0x8d76, 0x1e0e,
+ 0x8d77, 0x09ce,
+ 0x8d78, 0x1e0f,
+ 0x8d79, 0x2073,
+ 0x8d7a, 0x39e1,
+ 0x8d7b, 0x2072,
+ 0x8d7d, 0x2071,
+ 0x8d80, 0x2301,
+ 0x8d81, 0x0d75,
+ 0x8d82, 0x3f69,
+ 0x8d84, 0x2300,
+ 0x8d85, 0x0d74,
+ 0x8d89, 0x2302,
+ 0x8d8a, 0x0d73,
+ 0x8d8c, 0x25a4,
+ 0x8d8d, 0x25a7,
+ 0x8d8e, 0x25a5,
+ 0x8d90, 0x25aa,
+ 0x8d91, 0x25a3,
+ 0x8d92, 0x25ab,
+ 0x8d93, 0x25a8,
+ 0x8d95, 0x10bc,
+ 0x8d96, 0x280f,
+ 0x8d99, 0x10bb,
+ 0x8d9b, 0x2a60,
+ 0x8d9c, 0x2a5e,
+ 0x8d9f, 0x1232,
+ 0x8da0, 0x2a5d,
+ 0x8da1, 0x2a5f,
+ 0x8da3, 0x1233,
+ 0x8da5, 0x2ca0,
+ 0x8da6, 0x3ff7,
+ 0x8da7, 0x2ca1,
+ 0x8da8, 0x1488,
+ 0x8da9, 0x3856,
+ 0x8daa, 0x3137,
+ 0x8dab, 0x3139,
+ 0x8dac, 0x3136,
+ 0x8dad, 0x3138,
+ 0x8dae, 0x323d,
+ 0x8daf, 0x3318,
+ 0x8db2, 0x3509,
+ 0x8db3, 0x0511,
+ 0x8db4, 0x080e,
+ 0x8db5, 0x1e10,
+ 0x8db6, 0x1e12,
+ 0x8db7, 0x1e11,
+ 0x8db9, 0x2076,
+ 0x8dba, 0x0bb2,
+ 0x8dbc, 0x2074,
+ 0x8dbe, 0x0bb1,
+ 0x8dbf, 0x2077,
+ 0x8dc0, 0x436a,
+ 0x8dc1, 0x2078,
+ 0x8dc2, 0x2075,
+ 0x8dc3, 0x4782,
+ 0x8dc5, 0x230e,
+ 0x8dc6, 0x0d7d,
+ 0x8dc7, 0x2306,
+ 0x8dc8, 0x230c,
+ 0x8dcb, 0x0d78,
+ 0x8dcc, 0x0d7b,
+ 0x8dcd, 0x2305,
+ 0x8dce, 0x0d76,
+ 0x8dcf, 0x2309,
+ 0x8dd0, 0x25b1,
+ 0x8dd1, 0x0d7a,
+ 0x8dd3, 0x2304,
+ 0x8dd4, 0x3f82,
+ 0x8dd5, 0x230a,
+ 0x8dd6, 0x2307,
+ 0x8dd7, 0x230d,
+ 0x8dd8, 0x2303,
+ 0x8dd9, 0x230b,
+ 0x8dda, 0x0d79,
+ 0x8ddb, 0x0d7c,
+ 0x8ddc, 0x2308,
+ 0x8ddd, 0x0d77,
+ 0x8ddf, 0x0f27,
+ 0x8de0, 0x25ad,
+ 0x8de1, 0x0f26,
+ 0x8de2, 0x25b4,
+ 0x8de3, 0x25b3,
+ 0x8de4, 0x0f2d,
+ 0x8de6, 0x0f2e,
+ 0x8de7, 0x25b5,
+ 0x8de8, 0x0f28,
+ 0x8de9, 0x25b2,
+ 0x8dea, 0x0f2c,
+ 0x8deb, 0x25b7,
+ 0x8dec, 0x25ae,
+ 0x8dee, 0x25b0,
+ 0x8def, 0x0f29,
+ 0x8df0, 0x25ac,
+ 0x8df1, 0x25af,
+ 0x8df2, 0x25b6,
+ 0x8df3, 0x0f2a,
+ 0x8df4, 0x25b8,
+ 0x8dfa, 0x0f2b,
+ 0x8dfc, 0x10bd,
+ 0x8dfd, 0x2814,
+ 0x8dfe, 0x281a,
+ 0x8dff, 0x2812,
+ 0x8e00, 0x281b,
+ 0x8e01, 0x3f85,
+ 0x8e02, 0x2811,
+ 0x8e03, 0x2816,
+ 0x8e04, 0x281c,
+ 0x8e05, 0x2819,
+ 0x8e06, 0x2818,
+ 0x8e07, 0x2817,
+ 0x8e09, 0x2810,
+ 0x8e0a, 0x2815,
+ 0x8e0d, 0x2813,
+ 0x8e0e, 0x3e5e,
+ 0x8e0f, 0x1238,
+ 0x8e10, 0x1235,
+ 0x8e11, 0x2a69,
+ 0x8e12, 0x2a6e,
+ 0x8e13, 0x2a70,
+ 0x8e14, 0x2a6d,
+ 0x8e15, 0x2a66,
+ 0x8e16, 0x2a68,
+ 0x8e17, 0x2a72,
+ 0x8e18, 0x2a6f,
+ 0x8e19, 0x2a6a,
+ 0x8e1a, 0x2a73,
+ 0x8e1b, 0x2a67,
+ 0x8e1c, 0x2a71,
+ 0x8e1d, 0x1236,
+ 0x8e1e, 0x123c,
+ 0x8e1f, 0x123a,
+ 0x8e20, 0x2a61,
+ 0x8e21, 0x123b,
+ 0x8e22, 0x1237,
+ 0x8e23, 0x2a62,
+ 0x8e24, 0x2a64,
+ 0x8e25, 0x2a63,
+ 0x8e26, 0x2a6b,
+ 0x8e28, 0x3f88,
+ 0x8e29, 0x1239,
+ 0x8e2a, 0x3bb4,
+ 0x8e2b, 0x1234,
+ 0x8e2d, 0x3eab,
+ 0x8e2e, 0x2a65,
+ 0x8e30, 0x2cab,
+ 0x8e31, 0x1362,
+ 0x8e33, 0x2ca2,
+ 0x8e34, 0x1363,
+ 0x8e35, 0x1366,
+ 0x8e36, 0x2ca7,
+ 0x8e38, 0x2ca4,
+ 0x8e39, 0x1365,
+ 0x8e3a, 0x4784,
+ 0x8e3c, 0x2ca8,
+ 0x8e3e, 0x2ca3,
+ 0x8e3f, 0x2cac,
+ 0x8e40, 0x2ca5,
+ 0x8e41, 0x2caa,
+ 0x8e42, 0x1364,
+ 0x8e44, 0x1361,
+ 0x8e45, 0x2ca6,
+ 0x8e46, 0x4312,
+ 0x8e47, 0x2e7a,
+ 0x8e48, 0x148b,
+ 0x8e49, 0x1489,
+ 0x8e4a, 0x148c,
+ 0x8e4b, 0x148a,
+ 0x8e4c, 0x2e79,
+ 0x8e4d, 0x2e76,
+ 0x8e4e, 0x2e75,
+ 0x8e4f, 0x3f83,
+ 0x8e50, 0x2e78,
+ 0x8e53, 0x2e77,
+ 0x8e54, 0x2ff6,
+ 0x8e55, 0x1535,
+ 0x8e56, 0x2fed,
+ 0x8e57, 0x2fec,
+ 0x8e59, 0x1530,
+ 0x8e5a, 0x2ff2,
+ 0x8e5b, 0x2ff1,
+ 0x8e5c, 0x2fe9,
+ 0x8e5d, 0x2ff4,
+ 0x8e5e, 0x2fee,
+ 0x8e5f, 0x1534,
+ 0x8e60, 0x2feb,
+ 0x8e61, 0x2ff3,
+ 0x8e62, 0x2fea,
+ 0x8e63, 0x1531,
+ 0x8e64, 0x1533,
+ 0x8e65, 0x2fef,
+ 0x8e66, 0x1532,
+ 0x8e67, 0x2ff0,
+ 0x8e68, 0x434d,
+ 0x8e69, 0x2ff5,
+ 0x8e6a, 0x313d,
+ 0x8e6c, 0x15d3,
+ 0x8e6d, 0x313a,
+ 0x8e6f, 0x313e,
+ 0x8e71, 0x43e7,
+ 0x8e72, 0x15d0,
+ 0x8e73, 0x313c,
+ 0x8e74, 0x15d5,
+ 0x8e75, 0x3f89,
+ 0x8e76, 0x15d2,
+ 0x8e77, 0x3f7f,
+ 0x8e78, 0x313b,
+ 0x8e7a, 0x15d4,
+ 0x8e7b, 0x313f,
+ 0x8e7c, 0x15cf,
+ 0x8e7e, 0x4324,
+ 0x8e80, 0x3e57,
+ 0x8e81, 0x164d,
+ 0x8e82, 0x164f,
+ 0x8e84, 0x3240,
+ 0x8e85, 0x164e,
+ 0x8e86, 0x323e,
+ 0x8e87, 0x15d1,
+ 0x8e88, 0x323f,
+ 0x8e89, 0x164c,
+ 0x8e8a, 0x1693,
+ 0x8e8b, 0x1695,
+ 0x8e8c, 0x331a,
+ 0x8e8d, 0x1694,
+ 0x8e8e, 0x3319,
+ 0x8e90, 0x33c1,
+ 0x8e91, 0x16db,
+ 0x8e92, 0x33c0,
+ 0x8e93, 0x16dc,
+ 0x8e94, 0x33be,
+ 0x8e95, 0x33bd,
+ 0x8e96, 0x33c2,
+ 0x8e98, 0x3443,
+ 0x8e9a, 0x33bf,
+ 0x8e9d, 0x34a1,
+ 0x8e9e, 0x349e,
+ 0x8ea1, 0x1749,
+ 0x8ea3, 0x34eb,
+ 0x8ea4, 0x34ea,
+ 0x8ea5, 0x34e9,
+ 0x8ea6, 0x350a,
+ 0x8ea7, 0x3bb5,
+ 0x8ea8, 0x3537,
+ 0x8ea9, 0x3524,
+ 0x8eaa, 0x175b,
+ 0x8eab, 0x0512,
+ 0x8eac, 0x09cf,
+ 0x8ead, 0x385e,
+ 0x8eb0, 0x43e9,
+ 0x8eb2, 0x0f2f,
+ 0x8eb6, 0x385f,
+ 0x8eba, 0x123d,
+ 0x8ebc, 0x38a0,
+ 0x8ebd, 0x2cad,
+ 0x8ec0, 0x1536,
+ 0x8ec2, 0x3140,
+ 0x8ec3, 0x3860,
+ 0x8ec9, 0x3525,
+ 0x8eca, 0x0513,
+ 0x8ecb, 0x068d,
+ 0x8ecc, 0x0810,
+ 0x8ecd, 0x080f,
+ 0x8ece, 0x4788,
+ 0x8ecf, 0x09d2,
+ 0x8ed1, 0x1e13,
+ 0x8ed2, 0x09d0,
+ 0x8ed3, 0x1e14,
+ 0x8ed4, 0x09d1,
+ 0x8ed7, 0x207d,
+ 0x8ed8, 0x2079,
+ 0x8eda, 0x3dbe,
+ 0x8edb, 0x0bb3,
+ 0x8edc, 0x207c,
+ 0x8edd, 0x207b,
+ 0x8ede, 0x207a,
+ 0x8edf, 0x0bb4,
+ 0x8ee0, 0x207e,
+ 0x8ee2, 0x4789,
+ 0x8ee4, 0x478a,
+ 0x8ee5, 0x2315,
+ 0x8ee6, 0x2313,
+ 0x8ee7, 0x2317,
+ 0x8ee9, 0x231e,
+ 0x8eeb, 0x231a,
+ 0x8eec, 0x231c,
+ 0x8eed, 0x478b,
+ 0x8eee, 0x2314,
+ 0x8eef, 0x230f,
+ 0x8ef1, 0x231b,
+ 0x8ef2, 0x478c,
+ 0x8ef4, 0x231d,
+ 0x8ef5, 0x2316,
+ 0x8ef6, 0x2319,
+ 0x8ef7, 0x2310,
+ 0x8ef8, 0x0d7f,
+ 0x8ef9, 0x2312,
+ 0x8efa, 0x2311,
+ 0x8efb, 0x0d7e,
+ 0x8efc, 0x0d80,
+ 0x8efe, 0x0f32,
+ 0x8eff, 0x25ba,
+ 0x8f00, 0x25bc,
+ 0x8f01, 0x25bb,
+ 0x8f02, 0x25c0,
+ 0x8f03, 0x0f30,
+ 0x8f05, 0x25bd,
+ 0x8f06, 0x25b9,
+ 0x8f07, 0x25be,
+ 0x8f09, 0x0f31,
+ 0x8f0a, 0x0f33,
+ 0x8f0b, 0x25c1,
+ 0x8f0d, 0x2820,
+ 0x8f0e, 0x281f,
+ 0x8f10, 0x281d,
+ 0x8f12, 0x10bf,
+ 0x8f13, 0x10c1,
+ 0x8f14, 0x10be,
+ 0x8f15, 0x10c0,
+ 0x8f16, 0x2a7a,
+ 0x8f18, 0x2a76,
+ 0x8f19, 0x3862,
+ 0x8f1a, 0x2a77,
+ 0x8f1b, 0x123f,
+ 0x8f1c, 0x1244,
+ 0x8f1d, 0x123e,
+ 0x8f1e, 0x1245,
+ 0x8f1f, 0x1240,
+ 0x8f20, 0x2a78,
+ 0x8f23, 0x2a79,
+ 0x8f24, 0x2a75,
+ 0x8f25, 0x1246,
+ 0x8f26, 0x1242,
+ 0x8f29, 0x1241,
+ 0x8f2a, 0x1243,
+ 0x8f2c, 0x2a74,
+ 0x8f2d, 0x3863,
+ 0x8f2e, 0x2caf,
+ 0x8f2f, 0x1368,
+ 0x8f30, 0x3bb7,
+ 0x8f32, 0x2cb1,
+ 0x8f33, 0x136a,
+ 0x8f34, 0x2cb4,
+ 0x8f35, 0x2cb0,
+ 0x8f36, 0x2cae,
+ 0x8f37, 0x2cb3,
+ 0x8f38, 0x1369,
+ 0x8f39, 0x2cb2,
+ 0x8f3b, 0x1367,
+ 0x8f3e, 0x148e,
+ 0x8f3f, 0x1491,
+ 0x8f40, 0x2e7c,
+ 0x8f41, 0x3d07,
+ 0x8f42, 0x148f,
+ 0x8f43, 0x2e7b,
+ 0x8f44, 0x148d,
+ 0x8f45, 0x1490,
+ 0x8f46, 0x2ff7,
+ 0x8f49, 0x1537,
+ 0x8f4a, 0x3bb8,
+ 0x8f4b, 0x2ffa,
+ 0x8f4d, 0x1538,
+ 0x8f4e, 0x15d7,
+ 0x8f4f, 0x3143,
+ 0x8f51, 0x3142,
+ 0x8f52, 0x3141,
+ 0x8f53, 0x3145,
+ 0x8f54, 0x15d6,
+ 0x8f55, 0x3244,
+ 0x8f56, 0x3242,
+ 0x8f58, 0x3245,
+ 0x8f59, 0x3241,
+ 0x8f5a, 0x3246,
+ 0x8f5b, 0x331c,
+ 0x8f5c, 0x3f31,
+ 0x8f5d, 0x331d,
+ 0x8f5e, 0x331b,
+ 0x8f5f, 0x1696,
+ 0x8f60, 0x33c4,
+ 0x8f61, 0x16dd,
+ 0x8f62, 0x33c5,
+ 0x8f63, 0x3445,
+ 0x8f64, 0x3444,
+ 0x8f66, 0x4569,
+ 0x8f6e, 0x456b,
+ 0x8f93, 0x4732,
+ 0x8f9b, 0x0514,
+ 0x8f9c, 0x0d81,
+ 0x8f9f, 0x0f34,
+ 0x8fa0, 0x3d94,
+ 0x8fa3, 0x10c2,
+ 0x8fa5, 0x3866,
+ 0x8fa6, 0x136c,
+ 0x8fa8, 0x136b,
+ 0x8fad, 0x15d8,
+ 0x8fae, 0x162f,
+ 0x8faf, 0x1697,
+ 0x8fb0, 0x0515,
+ 0x8fb1, 0x09d3,
+ 0x8fb2, 0x0f35,
+ 0x8fb3, 0x386a,
+ 0x8fb4, 0x3146,
+ 0x8fb5, 0x0230,
+ 0x8fb6, 0x47d3,
+ 0x8fb7, 0x43fd,
+ 0x8fb8, 0x42f6,
+ 0x8fb9, 0x48c9,
+ 0x8fba, 0x48c7,
+ 0x8fbb, 0x3d6b,
+ 0x8fbe, 0x48c6,
+ 0x8fbf, 0x18e9,
+ 0x8fc1, 0x478d,
+ 0x8fc2, 0x0516,
+ 0x8fc4, 0x0519,
+ 0x8fc5, 0x0518,
+ 0x8fc6, 0x0517,
+ 0x8fc9, 0x18e8,
+ 0x8fca, 0x478e,
+ 0x8fcb, 0x1a4a,
+ 0x8fcc, 0x478f,
+ 0x8fcd, 0x1a4c,
+ 0x8fce, 0x068e,
+ 0x8fd0, 0x48ae,
+ 0x8fd1, 0x0690,
+ 0x8fd2, 0x1a49,
+ 0x8fd3, 0x1a4b,
+ 0x8fd4, 0x068f,
+ 0x8fd5, 0x1a4e,
+ 0x8fd6, 0x1a4d,
+ 0x8fd7, 0x1a4f,
+ 0x8fda, 0x3fcb,
+ 0x8fe0, 0x1c0a,
+ 0x8fe1, 0x1c08,
+ 0x8fe2, 0x0813,
+ 0x8fe3, 0x1c07,
+ 0x8fe4, 0x0818,
+ 0x8fe5, 0x0815,
+ 0x8fe6, 0x0812,
+ 0x8fe8, 0x0819,
+ 0x8fea, 0x0814,
+ 0x8feb, 0x0817,
+ 0x8fed, 0x0816,
+ 0x8fee, 0x1c09,
+ 0x8ff0, 0x0811,
+ 0x8ff4, 0x09d9,
+ 0x8ff5, 0x1e16,
+ 0x8ff6, 0x1e1c,
+ 0x8ff7, 0x09d6,
+ 0x8ff8, 0x09dd,
+ 0x8ff9, 0x3871,
+ 0x8ffa, 0x09d8,
+ 0x8ffb, 0x1e19,
+ 0x8ffc, 0x1e1b,
+ 0x8ffd, 0x09db,
+ 0x8ffe, 0x1e15,
+ 0x8fff, 0x1e18,
+ 0x9000, 0x09d7,
+ 0x9001, 0x09d4,
+ 0x9002, 0x1e17,
+ 0x9003, 0x09da,
+ 0x9004, 0x1e1a,
+ 0x9005, 0x09dc,
+ 0x9006, 0x09d5,
+ 0x9008, 0x3ee0,
+ 0x900b, 0x2081,
+ 0x900c, 0x2084,
+ 0x900d, 0x0bb6,
+ 0x900f, 0x0bc0,
+ 0x9010, 0x0bbc,
+ 0x9011, 0x2082,
+ 0x9012, 0x3e4e,
+ 0x9014, 0x0bc4,
+ 0x9015, 0x0bbd,
+ 0x9016, 0x0bc2,
+ 0x9017, 0x0bb8,
+ 0x9019, 0x0bb5,
+ 0x901a, 0x0bb7,
+ 0x901b, 0x0bc3,
+ 0x901c, 0x2083,
+ 0x901d, 0x0bbb,
+ 0x901e, 0x0bbe,
+ 0x901f, 0x0bba,
+ 0x9020, 0x0bbf,
+ 0x9021, 0x2085,
+ 0x9022, 0x0bc1,
+ 0x9023, 0x0bb9,
+ 0x9024, 0x2080,
+ 0x902d, 0x231f,
+ 0x902e, 0x0d82,
+ 0x902f, 0x2321,
+ 0x9031, 0x0d84,
+ 0x9032, 0x0d86,
+ 0x9033, 0x4790,
+ 0x9034, 0x2320,
+ 0x9035, 0x0d83,
+ 0x9036, 0x0d87,
+ 0x9037, 0x3876,
+ 0x9038, 0x0d85,
+ 0x903c, 0x0f3b,
+ 0x903d, 0x25c6,
+ 0x903e, 0x0f43,
+ 0x903f, 0x25c3,
+ 0x9041, 0x0f44,
+ 0x9042, 0x0f39,
+ 0x9044, 0x25c4,
+ 0x9047, 0x0f3e,
+ 0x9049, 0x25c5,
+ 0x904a, 0x0f37,
+ 0x904b, 0x0f36,
+ 0x904c, 0x3f10,
+ 0x904d, 0x0f41,
+ 0x904e, 0x0f40,
+ 0x904f, 0x0f3f,
+ 0x9050, 0x0f3d,
+ 0x9051, 0x0f42,
+ 0x9052, 0x25c2,
+ 0x9053, 0x0f38,
+ 0x9054, 0x0f3a,
+ 0x9055, 0x0f3c,
+ 0x9056, 0x3dd2,
+ 0x9058, 0x10c4,
+ 0x9059, 0x10c7,
+ 0x905b, 0x10cb,
+ 0x905c, 0x10c5,
+ 0x905d, 0x10ca,
+ 0x905e, 0x10c8,
+ 0x9060, 0x10c3,
+ 0x9061, 0x3879,
+ 0x9062, 0x10c9,
+ 0x9063, 0x10c6,
+ 0x9064, 0x3c68,
+ 0x9067, 0x2a7f,
+ 0x9068, 0x1249,
+ 0x9069, 0x1247,
+ 0x906b, 0x2a80,
+ 0x906c, 0x3d60,
+ 0x906d, 0x124a,
+ 0x906e, 0x1248,
+ 0x906f, 0x2a7e,
+ 0x9070, 0x2a7d,
+ 0x9072, 0x1370,
+ 0x9073, 0x2a7c,
+ 0x9074, 0x136e,
+ 0x9075, 0x136d,
+ 0x9076, 0x2cb5,
+ 0x9077, 0x124b,
+ 0x9078, 0x136f,
+ 0x9079, 0x2cb6,
+ 0x907a, 0x1372,
+ 0x907b, 0x2cb7,
+ 0x907c, 0x1371,
+ 0x907d, 0x1493,
+ 0x907e, 0x2e7e,
+ 0x907f, 0x1492,
+ 0x9080, 0x1497,
+ 0x9081, 0x1495,
+ 0x9083, 0x153a,
+ 0x9084, 0x1494,
+ 0x9085, 0x2e7d,
+ 0x9086, 0x2cb8,
+ 0x9087, 0x1539,
+ 0x9088, 0x153b,
+ 0x908a, 0x15d9,
+ 0x908d, 0x3247,
+ 0x908f, 0x170c,
+ 0x9090, 0x170b,
+ 0x9091, 0x051b,
+ 0x9094, 0x181e,
+ 0x9095, 0x09de,
+ 0x9097, 0x181b,
+ 0x9099, 0x181a,
+ 0x909b, 0x181d,
+ 0x909e, 0x18ed,
+ 0x909f, 0x18ea,
+ 0x90a0, 0x18ef,
+ 0x90a1, 0x18eb,
+ 0x90a2, 0x051c,
+ 0x90a3, 0x051f,
+ 0x90a5, 0x18ec,
+ 0x90a6, 0x051e,
+ 0x90a7, 0x18ee,
+ 0x90a8, 0x387c,
+ 0x90aa, 0x051d,
+ 0x90ae, 0x3880,
+ 0x90af, 0x1a52,
+ 0x90b0, 0x1a54,
+ 0x90b1, 0x0693,
+ 0x90b2, 0x1a50,
+ 0x90b3, 0x1a53,
+ 0x90b4, 0x1a51,
+ 0x90b5, 0x0691,
+ 0x90b6, 0x0694,
+ 0x90b8, 0x0692,
+ 0x90bb, 0x3bc4,
+ 0x90bd, 0x1c0c,
+ 0x90be, 0x1c10,
+ 0x90bf, 0x1c0d,
+ 0x90c1, 0x081c,
+ 0x90c3, 0x081d,
+ 0x90c4, 0x387e,
+ 0x90c5, 0x1c0f,
+ 0x90c7, 0x1c11,
+ 0x90c8, 0x1c13,
+ 0x90ca, 0x081a,
+ 0x90cb, 0x1c12,
+ 0x90ce, 0x081b,
+ 0x90d4, 0x208c,
+ 0x90d5, 0x1c0e,
+ 0x90d6, 0x1e1d,
+ 0x90d7, 0x1e26,
+ 0x90d8, 0x1e24,
+ 0x90d9, 0x1e1f,
+ 0x90db, 0x1e25,
+ 0x90dc, 0x1e27,
+ 0x90dd, 0x09e0,
+ 0x90df, 0x1e22,
+ 0x90e0, 0x1e1e,
+ 0x90e1, 0x09df,
+ 0x90e2, 0x09e1,
+ 0x90e3, 0x1e21,
+ 0x90e4, 0x1e28,
+ 0x90e5, 0x1e23,
+ 0x90e8, 0x0bc5,
+ 0x90e9, 0x208f,
+ 0x90ea, 0x2087,
+ 0x90eb, 0x208d,
+ 0x90ed, 0x0bc6,
+ 0x90ef, 0x2086,
+ 0x90f0, 0x2088,
+ 0x90f1, 0x1c0b,
+ 0x90f2, 0x208a,
+ 0x90f4, 0x2089,
+ 0x90f5, 0x0d89,
+ 0x90f9, 0x2328,
+ 0x90fa, 0x2cb9,
+ 0x90fb, 0x2329,
+ 0x90fc, 0x2326,
+ 0x90fd, 0x0bc7,
+ 0x90fe, 0x0d8b,
+ 0x90ff, 0x2325,
+ 0x9100, 0x232b,
+ 0x9101, 0x232a,
+ 0x9102, 0x0d88,
+ 0x9103, 0x232e,
+ 0x9104, 0x2324,
+ 0x9105, 0x232d,
+ 0x9106, 0x2322,
+ 0x9107, 0x232c,
+ 0x9108, 0x2327,
+ 0x9109, 0x0d8a,
+ 0x910b, 0x25cd,
+ 0x910d, 0x25c8,
+ 0x910e, 0x25ce,
+ 0x910f, 0x25c9,
+ 0x9110, 0x25c7,
+ 0x9111, 0x25ca,
+ 0x9112, 0x0f45,
+ 0x9114, 0x25cc,
+ 0x9116, 0x25cb,
+ 0x9117, 0x0f46,
+ 0x9118, 0x10cd,
+ 0x9119, 0x10cc,
+ 0x911a, 0x2827,
+ 0x911b, 0x282a,
+ 0x911c, 0x2822,
+ 0x911d, 0x2826,
+ 0x911e, 0x10ce,
+ 0x911f, 0x2825,
+ 0x9120, 0x2823,
+ 0x9121, 0x2829,
+ 0x9122, 0x2824,
+ 0x9123, 0x2821,
+ 0x9124, 0x2828,
+ 0x9126, 0x2a86,
+ 0x9127, 0x124e,
+ 0x9128, 0x2ffb,
+ 0x9129, 0x2a83,
+ 0x912b, 0x2a82,
+ 0x912c, 0x2323,
+ 0x912d, 0x124d,
+ 0x912e, 0x2a87,
+ 0x912f, 0x2a81,
+ 0x9130, 0x124c,
+ 0x9131, 0x124f,
+ 0x9132, 0x2a85,
+ 0x9133, 0x2cba,
+ 0x9134, 0x1373,
+ 0x9135, 0x2cbb,
+ 0x9138, 0x2e7f,
+ 0x9139, 0x1498,
+ 0x913a, 0x2ffc,
+ 0x913e, 0x2ffe,
+ 0x913f, 0x3148,
+ 0x9140, 0x3147,
+ 0x9141, 0x3249,
+ 0x9143, 0x3248,
+ 0x9144, 0x331f,
+ 0x9146, 0x331e,
+ 0x9147, 0x33c6,
+ 0x9148, 0x16de,
+ 0x9149, 0x0520,
+ 0x914a, 0x081f,
+ 0x914b, 0x081e,
+ 0x914c, 0x09e4,
+ 0x914d, 0x09e3,
+ 0x914e, 0x1e2a,
+ 0x9150, 0x1e29,
+ 0x9151, 0x3f49,
+ 0x9152, 0x09e2,
+ 0x9153, 0x2093,
+ 0x9155, 0x2094,
+ 0x9156, 0x2090,
+ 0x9157, 0x0bc8,
+ 0x9158, 0x2091,
+ 0x9159, 0x3f45,
+ 0x915a, 0x2092,
+ 0x915c, 0x3f47,
+ 0x915e, 0x43eb,
+ 0x915f, 0x2331,
+ 0x9160, 0x2333,
+ 0x9161, 0x232f,
+ 0x9162, 0x2332,
+ 0x9163, 0x0d8c,
+ 0x9164, 0x2330,
+ 0x9165, 0x0d8d,
+ 0x9167, 0x3882,
+ 0x9168, 0x23e2,
+ 0x9169, 0x0f49,
+ 0x916a, 0x0f48,
+ 0x916c, 0x0f47,
+ 0x916e, 0x25cf,
+ 0x9170, 0x3eb8,
+ 0x9172, 0x282c,
+ 0x9173, 0x282e,
+ 0x9174, 0x10d2,
+ 0x9175, 0x10cf,
+ 0x9176, 0x3e9b,
+ 0x9177, 0x10d1,
+ 0x9178, 0x10d0,
+ 0x9179, 0x282d,
+ 0x917a, 0x282b,
+ 0x917c, 0x3f6f,
+ 0x9180, 0x2a8e,
+ 0x9181, 0x2a8b,
+ 0x9183, 0x1253,
+ 0x9184, 0x2a8d,
+ 0x9185, 0x2a88,
+ 0x9187, 0x1250,
+ 0x9189, 0x1251,
+ 0x918a, 0x2a8a,
+ 0x918b, 0x1252,
+ 0x918c, 0x43ec,
+ 0x918d, 0x2cc0,
+ 0x918e, 0x3f4e,
+ 0x918f, 0x2cc1,
+ 0x9190, 0x2cbe,
+ 0x9192, 0x1374,
+ 0x9193, 0x2cbd,
+ 0x9199, 0x2e83,
+ 0x919a, 0x2e80,
+ 0x919b, 0x2e82,
+ 0x919c, 0x149b,
+ 0x919d, 0x2e86,
+ 0x919e, 0x149a,
+ 0x919f, 0x2e84,
+ 0x91a0, 0x2e87,
+ 0x91a1, 0x2e85,
+ 0x91a2, 0x2e81,
+ 0x91a3, 0x1499,
+ 0x91a5, 0x3000,
+ 0x91a7, 0x3001,
+ 0x91a8, 0x2fff,
+ 0x91a9, 0x3883,
+ 0x91aa, 0x3003,
+ 0x91ab, 0x153c,
+ 0x91ad, 0x314a,
+ 0x91ae, 0x15dc,
+ 0x91af, 0x3002,
+ 0x91b0, 0x3149,
+ 0x91b1, 0x15db,
+ 0x91b2, 0x324c,
+ 0x91b4, 0x1650,
+ 0x91b5, 0x324b,
+ 0x91b6, 0x45ef,
+ 0x91b7, 0x324a,
+ 0x91b9, 0x3321,
+ 0x91ba, 0x1698,
+ 0x91bb, 0x3bc8,
+ 0x91bc, 0x3446,
+ 0x91bd, 0x34a3,
+ 0x91be, 0x34a2,
+ 0x91c0, 0x1730,
+ 0x91c1, 0x174a,
+ 0x91c2, 0x34a4,
+ 0x91c3, 0x350b,
+ 0x91c4, 0x3884,
+ 0x91c5, 0x175c,
+ 0x91c6, 0x0521,
+ 0x91c7, 0x0695,
+ 0x91c9, 0x0f4a,
+ 0x91cb, 0x1651,
+ 0x91cc, 0x0522,
+ 0x91cd, 0x0820,
+ 0x91ce, 0x0bc9,
+ 0x91cf, 0x0d8e,
+ 0x91d0, 0x153e,
+ 0x91d1, 0x0696,
+ 0x91d3, 0x1c15,
+ 0x91d4, 0x1c14,
+ 0x91d5, 0x1e2c,
+ 0x91d6, 0x415e,
+ 0x91d7, 0x09e7,
+ 0x91d8, 0x09e5,
+ 0x91d9, 0x09e9,
+ 0x91da, 0x1e2e,
+ 0x91dc, 0x09e8,
+ 0x91dd, 0x09e6,
+ 0x91df, 0x453a,
+ 0x91e2, 0x1e2d,
+ 0x91e3, 0x0bcc,
+ 0x91e4, 0x209a,
+ 0x91e5, 0x3c06,
+ 0x91e6, 0x0bcb,
+ 0x91e7, 0x0bcd,
+ 0x91e8, 0x209f,
+ 0x91e9, 0x0bcf,
+ 0x91ea, 0x209c,
+ 0x91ec, 0x2095,
+ 0x91ed, 0x0bce,
+ 0x91ee, 0x20a0,
+ 0x91f1, 0x2097,
+ 0x91f3, 0x2098,
+ 0x91f4, 0x2096,
+ 0x91f5, 0x0bca,
+ 0x91f7, 0x209e,
+ 0x91f8, 0x2099,
+ 0x91f9, 0x209b,
+ 0x91fa, 0x3af8,
+ 0x91fd, 0x233f,
+ 0x91fe, 0x382e,
+ 0x91ff, 0x233e,
+ 0x9200, 0x233c,
+ 0x9201, 0x2334,
+ 0x9202, 0x2343,
+ 0x9203, 0x2337,
+ 0x9204, 0x2341,
+ 0x9205, 0x2348,
+ 0x9206, 0x2340,
+ 0x9207, 0x0d96,
+ 0x9208, 0x3eb9,
+ 0x9209, 0x0d92,
+ 0x920a, 0x2335,
+ 0x920c, 0x233b,
+ 0x920d, 0x0d94,
+ 0x920e, 0x3888,
+ 0x920f, 0x233a,
+ 0x9210, 0x0d95,
+ 0x9211, 0x0d97,
+ 0x9212, 0x233d,
+ 0x9213, 0x4793,
+ 0x9214, 0x0d8f,
+ 0x9216, 0x2349,
+ 0x9217, 0x2347,
+ 0x9219, 0x2346,
+ 0x921a, 0x2338,
+ 0x921c, 0x2344,
+ 0x921e, 0x0d93,
+ 0x9223, 0x0d91,
+ 0x9224, 0x2345,
+ 0x9225, 0x2336,
+ 0x9226, 0x2339,
+ 0x9227, 0x2342,
+ 0x9228, 0x4795,
+ 0x922a, 0x3c0e,
+ 0x922b, 0x3ba6,
+ 0x922d, 0x2851,
+ 0x922e, 0x25da,
+ 0x9230, 0x25d3,
+ 0x9231, 0x25e6,
+ 0x9232, 0x25ef,
+ 0x9233, 0x25d6,
+ 0x9234, 0x0f55,
+ 0x9235, 0x3b26,
+ 0x9236, 0x25e3,
+ 0x9237, 0x0f4b,
+ 0x9238, 0x0f4d,
+ 0x9239, 0x0f59,
+ 0x923a, 0x25d4,
+ 0x923c, 0x41d2,
+ 0x923d, 0x0f4e,
+ 0x923e, 0x0f50,
+ 0x923f, 0x0f5a,
+ 0x9240, 0x0f4f,
+ 0x9241, 0x388a,
+ 0x9244, 0x389a,
+ 0x9245, 0x0f58,
+ 0x9246, 0x25dc,
+ 0x9248, 0x25d1,
+ 0x9249, 0x0f56,
+ 0x924a, 0x25db,
+ 0x924b, 0x0f52,
+ 0x924c, 0x25ed,
+ 0x924d, 0x0f57,
+ 0x924e, 0x25eb,
+ 0x924f, 0x25df,
+ 0x9250, 0x25e9,
+ 0x9251, 0x0f54,
+ 0x9252, 0x25d2,
+ 0x9253, 0x25ec,
+ 0x9254, 0x25e7,
+ 0x9255, 0x3e47,
+ 0x9256, 0x25ee,
+ 0x9257, 0x0f4c,
+ 0x9258, 0x4796,
+ 0x925a, 0x0f5b,
+ 0x925b, 0x0f51,
+ 0x925d, 0x3a03,
+ 0x925e, 0x25d8,
+ 0x925f, 0x3ce0,
+ 0x9260, 0x25e0,
+ 0x9261, 0x25e4,
+ 0x9262, 0x388b,
+ 0x9263, 0x25e8,
+ 0x9264, 0x0f53,
+ 0x9265, 0x25d7,
+ 0x9266, 0x25d5,
+ 0x9267, 0x25e1,
+ 0x926b, 0x4797,
+ 0x926c, 0x25de,
+ 0x926d, 0x25dd,
+ 0x926e, 0x3d05,
+ 0x926f, 0x25e2,
+ 0x9270, 0x25e5,
+ 0x9272, 0x25ea,
+ 0x9276, 0x2831,
+ 0x9277, 0x3c64,
+ 0x9278, 0x10d3,
+ 0x9279, 0x283b,
+ 0x927a, 0x2833,
+ 0x927b, 0x10d9,
+ 0x927c, 0x10dd,
+ 0x927d, 0x2844,
+ 0x927e, 0x284c,
+ 0x927f, 0x283d,
+ 0x9280, 0x10d5,
+ 0x9281, 0x3e01,
+ 0x9282, 0x2841,
+ 0x9283, 0x25d9,
+ 0x9284, 0x3cb9,
+ 0x9285, 0x10d6,
+ 0x9286, 0x2848,
+ 0x9287, 0x284d,
+ 0x9288, 0x2845,
+ 0x9289, 0x3ab5,
+ 0x928a, 0x2847,
+ 0x928b, 0x2850,
+ 0x928c, 0x2849,
+ 0x928d, 0x2837,
+ 0x928e, 0x2840,
+ 0x928f, 0x46bd,
+ 0x9291, 0x10de,
+ 0x9293, 0x10da,
+ 0x9294, 0x2835,
+ 0x9295, 0x2842,
+ 0x9296, 0x10d8,
+ 0x9297, 0x283c,
+ 0x9298, 0x10d7,
+ 0x9299, 0x284a,
+ 0x929a, 0x2839,
+ 0x929b, 0x2832,
+ 0x929c, 0x10db,
+ 0x929d, 0x284f,
+ 0x92a0, 0x2834,
+ 0x92a1, 0x2846,
+ 0x92a2, 0x2843,
+ 0x92a3, 0x283e,
+ 0x92a4, 0x2830,
+ 0x92a5, 0x282f,
+ 0x92a6, 0x2838,
+ 0x92a7, 0x284b,
+ 0x92a8, 0x10dc,
+ 0x92a9, 0x284e,
+ 0x92aa, 0x2836,
+ 0x92ab, 0x283a,
+ 0x92ac, 0x10d4,
+ 0x92ae, 0x4799,
+ 0x92b1, 0x4798,
+ 0x92b2, 0x125f,
+ 0x92b3, 0x125a,
+ 0x92b4, 0x2ab0,
+ 0x92b5, 0x2aac,
+ 0x92b6, 0x2a94,
+ 0x92b7, 0x1256,
+ 0x92b9, 0x36e9,
+ 0x92ba, 0x3bf5,
+ 0x92bb, 0x1255,
+ 0x92bc, 0x125b,
+ 0x92be, 0x3c60,
+ 0x92bf, 0x479a,
+ 0x92c0, 0x2a92,
+ 0x92c1, 0x1259,
+ 0x92c2, 0x2a9e,
+ 0x92c3, 0x2a90,
+ 0x92c5, 0x1254,
+ 0x92c6, 0x2aaf,
+ 0x92c7, 0x125d,
+ 0x92c8, 0x2aa1,
+ 0x92c9, 0x2aa6,
+ 0x92ca, 0x2aa0,
+ 0x92cb, 0x2cd3,
+ 0x92cc, 0x2a9c,
+ 0x92cd, 0x2aa4,
+ 0x92ce, 0x2aa2,
+ 0x92cf, 0x2a95,
+ 0x92d0, 0x2a8f,
+ 0x92d1, 0x2aaa,
+ 0x92d2, 0x125c,
+ 0x92d3, 0x2aab,
+ 0x92d4, 0x3861,
+ 0x92d5, 0x2aa5,
+ 0x92d7, 0x2a9a,
+ 0x92d8, 0x2a98,
+ 0x92d9, 0x2a93,
+ 0x92db, 0x400c,
+ 0x92dd, 0x2a9b,
+ 0x92de, 0x2aa8,
+ 0x92df, 0x2a97,
+ 0x92e0, 0x2aa7,
+ 0x92e1, 0x2aad,
+ 0x92e3, 0x479b,
+ 0x92e4, 0x1258,
+ 0x92e5, 0x3ca2,
+ 0x92e6, 0x2aa3,
+ 0x92e7, 0x2aa9,
+ 0x92e8, 0x2a9f,
+ 0x92e9, 0x2a99,
+ 0x92ea, 0x1257,
+ 0x92eb, 0x479c,
+ 0x92ec, 0x3964,
+ 0x92ee, 0x283f,
+ 0x92ef, 0x2a9d,
+ 0x92f0, 0x125e,
+ 0x92f1, 0x2a96,
+ 0x92f2, 0x3ab2,
+ 0x92f3, 0x479d,
+ 0x92f6, 0x3c04,
+ 0x92f7, 0x2cd8,
+ 0x92f8, 0x1377,
+ 0x92f9, 0x2cd7,
+ 0x92fa, 0x2cd5,
+ 0x92fb, 0x2ce7,
+ 0x92fc, 0x137b,
+ 0x92fd, 0x479f,
+ 0x92fe, 0x2ce4,
+ 0x92ff, 0x2cdc,
+ 0x9300, 0x2ce6,
+ 0x9301, 0x2cce,
+ 0x9302, 0x2cda,
+ 0x9303, 0x3867,
+ 0x9304, 0x137d,
+ 0x9306, 0x2cc6,
+ 0x9307, 0x3b11,
+ 0x9308, 0x2cc4,
+ 0x9309, 0x2ce5,
+ 0x930b, 0x2ce3,
+ 0x930c, 0x2ce2,
+ 0x930d, 0x2cd2,
+ 0x930e, 0x2cd1,
+ 0x930f, 0x2cc7,
+ 0x9310, 0x137f,
+ 0x9312, 0x2ccd,
+ 0x9313, 0x2cd6,
+ 0x9314, 0x2ce1,
+ 0x9315, 0x1382,
+ 0x9316, 0x2ce8,
+ 0x9318, 0x14a3,
+ 0x9319, 0x1384,
+ 0x931a, 0x137e,
+ 0x931b, 0x2ccb,
+ 0x931d, 0x2cd4,
+ 0x931e, 0x2cc3,
+ 0x931f, 0x2cc5,
+ 0x9320, 0x1375,
+ 0x9321, 0x1381,
+ 0x9322, 0x137a,
+ 0x9323, 0x2ccc,
+ 0x9324, 0x2cdb,
+ 0x9325, 0x2aae,
+ 0x9326, 0x1380,
+ 0x9327, 0x2cc2,
+ 0x9328, 0x149e,
+ 0x9329, 0x2cdd,
+ 0x932a, 0x2ce0,
+ 0x932b, 0x137c,
+ 0x932c, 0x3892,
+ 0x932d, 0x2cd0,
+ 0x932e, 0x1383,
+ 0x932f, 0x1379,
+ 0x9330, 0x3e03,
+ 0x9331, 0x3cbd,
+ 0x9333, 0x1378,
+ 0x9334, 0x2cd9,
+ 0x9335, 0x2cdf,
+ 0x9336, 0x1376,
+ 0x9338, 0x2cc9,
+ 0x9339, 0x2cde,
+ 0x933c, 0x2cca,
+ 0x9340, 0x4155,
+ 0x9341, 0x4277,
+ 0x9342, 0x3afa,
+ 0x9343, 0x47a0,
+ 0x9344, 0x4016,
+ 0x9345, 0x3e74,
+ 0x9346, 0x2ccf,
+ 0x9347, 0x2e8d,
+ 0x9348, 0x3c61,
+ 0x9349, 0x2e92,
+ 0x934a, 0x14a0,
+ 0x934b, 0x14a2,
+ 0x934c, 0x2e98,
+ 0x934d, 0x149c,
+ 0x934e, 0x2ea6,
+ 0x934f, 0x2e9e,
+ 0x9350, 0x2e93,
+ 0x9352, 0x2e9d,
+ 0x9354, 0x14a9,
+ 0x9355, 0x2e9c,
+ 0x9356, 0x2e8c,
+ 0x9357, 0x2e9b,
+ 0x9358, 0x2e8f,
+ 0x9359, 0x2ea7,
+ 0x935a, 0x14a8,
+ 0x935b, 0x14a6,
+ 0x935c, 0x2e90,
+ 0x935e, 0x2ea3,
+ 0x935f, 0x3cbb,
+ 0x9360, 0x2e95,
+ 0x9361, 0x2ea2,
+ 0x9362, 0x4268,
+ 0x9363, 0x2ea4,
+ 0x9364, 0x2e8b,
+ 0x9365, 0x14a1,
+ 0x9366, 0x46bc,
+ 0x9367, 0x2ea5,
+ 0x9368, 0x3bf0,
+ 0x9369, 0x3961,
+ 0x936a, 0x2e99,
+ 0x936b, 0x3893,
+ 0x936c, 0x14a5,
+ 0x936d, 0x2e96,
+ 0x936e, 0x39e8,
+ 0x9370, 0x14a7,
+ 0x9371, 0x2e9f,
+ 0x9373, 0x389e,
+ 0x9374, 0x3ce4,
+ 0x9375, 0x149f,
+ 0x9376, 0x2e91,
+ 0x9377, 0x2ea0,
+ 0x9378, 0x38f9,
+ 0x9379, 0x2e9a,
+ 0x937a, 0x2cc8,
+ 0x937b, 0x2ea1,
+ 0x937c, 0x2e8e,
+ 0x937d, 0x3c25,
+ 0x937e, 0x14a4,
+ 0x9380, 0x3014,
+ 0x9381, 0x3965,
+ 0x9382, 0x149d,
+ 0x9383, 0x2e89,
+ 0x9384, 0x47a1,
+ 0x9385, 0x42bd,
+ 0x9386, 0x3cc0,
+ 0x9387, 0x3ae0,
+ 0x9388, 0x3011,
+ 0x9389, 0x300a,
+ 0x938a, 0x1540,
+ 0x938c, 0x3005,
+ 0x938d, 0x3015,
+ 0x938e, 0x300c,
+ 0x938f, 0x2e97,
+ 0x9390, 0x3d3c,
+ 0x9391, 0x3017,
+ 0x9392, 0x3006,
+ 0x9394, 0x153f,
+ 0x9395, 0x3010,
+ 0x9396, 0x1541,
+ 0x9397, 0x1549,
+ 0x9398, 0x1547,
+ 0x9399, 0x3012,
+ 0x939a, 0x1548,
+ 0x939b, 0x3008,
+ 0x939c, 0x39ac,
+ 0x939d, 0x3009,
+ 0x939e, 0x300e,
+ 0x939f, 0x3013,
+ 0x93a0, 0x3ab1,
+ 0x93a1, 0x2e88,
+ 0x93a2, 0x1542,
+ 0x93a3, 0x301c,
+ 0x93a4, 0x3019,
+ 0x93a5, 0x3160,
+ 0x93a6, 0x300f,
+ 0x93a7, 0x300b,
+ 0x93a8, 0x301a,
+ 0x93a9, 0x3155,
+ 0x93aa, 0x300d,
+ 0x93ac, 0x1545,
+ 0x93ad, 0x47a2,
+ 0x93ae, 0x1544,
+ 0x93af, 0x2e8a,
+ 0x93b0, 0x1546,
+ 0x93b1, 0x3016,
+ 0x93b2, 0x3018,
+ 0x93b3, 0x1543,
+ 0x93b4, 0x301b,
+ 0x93b5, 0x3004,
+ 0x93b7, 0x3007,
+ 0x93b8, 0x3c90,
+ 0x93ba, 0x43f7,
+ 0x93bb, 0x3c8f,
+ 0x93bd, 0x3a27,
+ 0x93bf, 0x3e2d,
+ 0x93c0, 0x315e,
+ 0x93c2, 0x314e,
+ 0x93c3, 0x15e0,
+ 0x93c4, 0x315c,
+ 0x93c6, 0x39aa,
+ 0x93c7, 0x314c,
+ 0x93c8, 0x15e1,
+ 0x93ca, 0x3157,
+ 0x93cb, 0x3966,
+ 0x93cc, 0x3153,
+ 0x93cd, 0x15e6,
+ 0x93ce, 0x315d,
+ 0x93cf, 0x314d,
+ 0x93d0, 0x3150,
+ 0x93d1, 0x15de,
+ 0x93d2, 0x315f,
+ 0x93d3, 0x40e1,
+ 0x93d4, 0x3158,
+ 0x93d5, 0x315b,
+ 0x93d6, 0x15e4,
+ 0x93d7, 0x15e9,
+ 0x93d8, 0x15e7,
+ 0x93d9, 0x3154,
+ 0x93da, 0x314f,
+ 0x93db, 0x3c5f,
+ 0x93dc, 0x15e2,
+ 0x93de, 0x314b,
+ 0x93df, 0x15df,
+ 0x93e0, 0x3a20,
+ 0x93e1, 0x15dd,
+ 0x93e2, 0x15e5,
+ 0x93e3, 0x315a,
+ 0x93e4, 0x15e8,
+ 0x93e6, 0x3156,
+ 0x93e7, 0x3161,
+ 0x93e8, 0x15ea,
+ 0x93ec, 0x3152,
+ 0x93ee, 0x3159,
+ 0x93f0, 0x423f,
+ 0x93f1, 0x42aa,
+ 0x93f3, 0x3962,
+ 0x93f5, 0x325a,
+ 0x93f6, 0x3269,
+ 0x93f7, 0x325c,
+ 0x93f8, 0x3263,
+ 0x93f9, 0x3151,
+ 0x93fa, 0x3261,
+ 0x93fb, 0x3250,
+ 0x93fc, 0x3267,
+ 0x93fd, 0x1654,
+ 0x93fe, 0x3254,
+ 0x93ff, 0x3266,
+ 0x9400, 0x325b,
+ 0x9401, 0x3cd4,
+ 0x9403, 0x1653,
+ 0x9404, 0x3bc9,
+ 0x9406, 0x326b,
+ 0x9407, 0x325d,
+ 0x9408, 0x3a25,
+ 0x9409, 0x3262,
+ 0x940a, 0x3265,
+ 0x940b, 0x324e,
+ 0x940c, 0x3268,
+ 0x940d, 0x3259,
+ 0x940e, 0x325e,
+ 0x940f, 0x3252,
+ 0x9410, 0x3256,
+ 0x9411, 0x326a,
+ 0x9412, 0x3260,
+ 0x9413, 0x324f,
+ 0x9414, 0x3253,
+ 0x9415, 0x3255,
+ 0x9416, 0x325f,
+ 0x9417, 0x47a5,
+ 0x9418, 0x1652,
+ 0x9419, 0x3258,
+ 0x941b, 0x4148,
+ 0x941d, 0x47a6,
+ 0x9420, 0x3251,
+ 0x9424, 0x3943,
+ 0x9425, 0x38d0,
+ 0x9426, 0x38a3,
+ 0x9427, 0x3bcd,
+ 0x9428, 0x3257,
+ 0x9429, 0x3325,
+ 0x942a, 0x3329,
+ 0x942b, 0x169f,
+ 0x942c, 0x332b,
+ 0x942d, 0x47a7,
+ 0x942e, 0x1699,
+ 0x9430, 0x3327,
+ 0x9431, 0x332d,
+ 0x9432, 0x169e,
+ 0x9433, 0x169a,
+ 0x9435, 0x169b,
+ 0x9436, 0x3324,
+ 0x9437, 0x332a,
+ 0x9438, 0x169d,
+ 0x9439, 0x3328,
+ 0x943a, 0x169c,
+ 0x943b, 0x3323,
+ 0x943c, 0x3264,
+ 0x943d, 0x3326,
+ 0x943e, 0x47a8,
+ 0x943f, 0x3322,
+ 0x9440, 0x332c,
+ 0x9442, 0x4272,
+ 0x9443, 0x4275,
+ 0x9444, 0x16df,
+ 0x9445, 0x33cd,
+ 0x9446, 0x33d0,
+ 0x9447, 0x33cc,
+ 0x9448, 0x33ce,
+ 0x944a, 0x33c9,
+ 0x944c, 0x33c7,
+ 0x944d, 0x3c65,
+ 0x944f, 0x33cb,
+ 0x9450, 0x33c8,
+ 0x9451, 0x16e0,
+ 0x9454, 0x47aa,
+ 0x9455, 0x3448,
+ 0x9457, 0x344a,
+ 0x9458, 0x3c30,
+ 0x945b, 0x389f,
+ 0x945d, 0x3449,
+ 0x945e, 0x344b,
+ 0x9460, 0x170e,
+ 0x9462, 0x3447,
+ 0x9463, 0x170d,
+ 0x9464, 0x170f,
+ 0x9465, 0x3dde,
+ 0x9467, 0x3ab8,
+ 0x9468, 0x34a6,
+ 0x946a, 0x1731,
+ 0x946b, 0x34a5,
+ 0x946c, 0x377e,
+ 0x946d, 0x34ed,
+ 0x946e, 0x34ec,
+ 0x946f, 0x34ee,
+ 0x9470, 0x174c,
+ 0x9471, 0x34ef,
+ 0x9472, 0x174b,
+ 0x9473, 0x34f0,
+ 0x9474, 0x350c,
+ 0x9475, 0x350f,
+ 0x9476, 0x350e,
+ 0x9477, 0x1755,
+ 0x9478, 0x350d,
+ 0x9479, 0x47ab,
+ 0x947b, 0x419b,
+ 0x947c, 0x175f,
+ 0x947d, 0x175d,
+ 0x947f, 0x1764,
+ 0x9480, 0x3539,
+ 0x9482, 0x3538,
+ 0x9483, 0x3540,
+ 0x9485, 0x4507,
+ 0x949f, 0x4885,
+ 0x94a2, 0x451b,
+ 0x94c1, 0x47e1,
+ 0x94c3, 0x47df,
+ 0x94dc, 0x47d7,
+ 0x94f6, 0x47d2,
+ 0x952d, 0x47ac,
+ 0x9547, 0x48bf,
+ 0x9577, 0x0697,
+ 0x9578, 0x4508,
+ 0x957a, 0x20a1,
+ 0x957b, 0x234a,
+ 0x957c, 0x2ab1,
+ 0x957d, 0x3162,
+ 0x957f, 0x4509,
+ 0x9580, 0x0698,
+ 0x9582, 0x0821,
+ 0x9583, 0x09ea,
+ 0x9585, 0x38a1,
+ 0x9586, 0x20a2,
+ 0x9588, 0x20a3,
+ 0x9589, 0x0bd0,
+ 0x958b, 0x0d9a,
+ 0x958c, 0x234c,
+ 0x958d, 0x234b,
+ 0x958e, 0x0d9e,
+ 0x958f, 0x0d99,
+ 0x9590, 0x234d,
+ 0x9591, 0x0d9b,
+ 0x9592, 0x0d9d,
+ 0x9593, 0x0d9c,
+ 0x9594, 0x0d98,
+ 0x9596, 0x3bd5,
+ 0x9597, 0x3bd4,
+ 0x9598, 0x0f5c,
+ 0x9599, 0x3bd2,
+ 0x959b, 0x25f3,
+ 0x959c, 0x25f1,
+ 0x959e, 0x25f2,
+ 0x959f, 0x25f0,
+ 0x95a0, 0x38a4,
+ 0x95a1, 0x10df,
+ 0x95a2, 0x47ad,
+ 0x95a3, 0x10e2,
+ 0x95a4, 0x10e4,
+ 0x95a5, 0x10e3,
+ 0x95a6, 0x38a2,
+ 0x95a7, 0x3bd3,
+ 0x95a8, 0x10e0,
+ 0x95aa, 0x4395,
+ 0x95ab, 0x2ab3,
+ 0x95ac, 0x2ab2,
+ 0x95ad, 0x1260,
+ 0x95ae, 0x2ab4,
+ 0x95b0, 0x2ab5,
+ 0x95b1, 0x1261,
+ 0x95b5, 0x2cf0,
+ 0x95b6, 0x2cee,
+ 0x95b7, 0x2ead,
+ 0x95b9, 0x2cec,
+ 0x95bb, 0x1385,
+ 0x95bc, 0x2ce9,
+ 0x95bd, 0x2cf1,
+ 0x95be, 0x2ceb,
+ 0x95bf, 0x2cef,
+ 0x95c0, 0x2ea9,
+ 0x95c3, 0x2eab,
+ 0x95c5, 0x2eac,
+ 0x95c6, 0x14ae,
+ 0x95c7, 0x2ea8,
+ 0x95c8, 0x14ad,
+ 0x95c9, 0x2eaa,
+ 0x95ca, 0x14aa,
+ 0x95cd, 0x2cea,
+ 0x95d0, 0x154c,
+ 0x95d1, 0x301f,
+ 0x95d2, 0x301d,
+ 0x95d4, 0x154a,
+ 0x95d5, 0x154d,
+ 0x95d6, 0x154b,
+ 0x95da, 0x3163,
+ 0x95dc, 0x15eb,
+ 0x95de, 0x326c,
+ 0x95df, 0x326e,
+ 0x95e0, 0x326d,
+ 0x95e1, 0x1655,
+ 0x95e2, 0x16a0,
+ 0x95e3, 0x3330,
+ 0x95e4, 0x332f,
+ 0x95e5, 0x332e,
+ 0x95e8, 0x450a,
+ 0x95f4, 0x47af,
+ 0x961c, 0x0699,
+ 0x961d, 0x4519,
+ 0x961e, 0x17b4,
+ 0x9620, 0x1821,
+ 0x9621, 0x0414,
+ 0x9622, 0x181f,
+ 0x9623, 0x1822,
+ 0x9624, 0x1820,
+ 0x9628, 0x18f1,
+ 0x962a, 0x0526,
+ 0x962c, 0x0527,
+ 0x962d, 0x18f3,
+ 0x962e, 0x0524,
+ 0x962f, 0x18f2,
+ 0x9630, 0x18f0,
+ 0x9631, 0x0525,
+ 0x9632, 0x0523,
+ 0x9633, 0x47b0,
+ 0x9638, 0x3fd1,
+ 0x9639, 0x1a55,
+ 0x963a, 0x1a58,
+ 0x963b, 0x069c,
+ 0x963c, 0x1a57,
+ 0x963d, 0x1a56,
+ 0x963f, 0x069b,
+ 0x9640, 0x069a,
+ 0x9641, 0x3f3d,
+ 0x9642, 0x069e,
+ 0x9643, 0x1a59,
+ 0x9644, 0x069d,
+ 0x9645, 0x4772,
+ 0x964a, 0x1c1a,
+ 0x964b, 0x0823,
+ 0x964e, 0x1c1b,
+ 0x964f, 0x1c17,
+ 0x9650, 0x0822,
+ 0x9651, 0x1c18,
+ 0x9653, 0x1c19,
+ 0x9654, 0x1c16,
+ 0x9656, 0x3de7,
+ 0x9658, 0x09f1,
+ 0x965b, 0x09ee,
+ 0x965c, 0x1e2f,
+ 0x965d, 0x09ef,
+ 0x965e, 0x09f2,
+ 0x965f, 0x1e30,
+ 0x9661, 0x09ed,
+ 0x9662, 0x09eb,
+ 0x9664, 0x09f0,
+ 0x9669, 0x475e,
+ 0x966a, 0x0bd1,
+ 0x966b, 0x20a6,
+ 0x966c, 0x0bd9,
+ 0x966d, 0x20a5,
+ 0x966f, 0x20a8,
+ 0x9670, 0x0bd5,
+ 0x9671, 0x20a7,
+ 0x9672, 0x0da6,
+ 0x9673, 0x0bd3,
+ 0x9674, 0x0bd6,
+ 0x9675, 0x0bd2,
+ 0x9676, 0x0bd7,
+ 0x9678, 0x0bd4,
+ 0x967b, 0x38ac,
+ 0x967c, 0x20a4,
+ 0x967d, 0x0da2,
+ 0x967e, 0x234f,
+ 0x9680, 0x2353,
+ 0x9681, 0x3f46,
+ 0x9683, 0x2352,
+ 0x9684, 0x0da7,
+ 0x9685, 0x0da3,
+ 0x9687, 0x234e,
+ 0x9688, 0x2350,
+ 0x968a, 0x0d9f,
+ 0x968b, 0x0da1,
+ 0x968d, 0x0da5,
+ 0x968e, 0x0da0,
+ 0x968f, 0x3bde,
+ 0x9691, 0x25f6,
+ 0x9692, 0x25f4,
+ 0x9694, 0x0f5e,
+ 0x9696, 0x38ad,
+ 0x9697, 0x25f7,
+ 0x9698, 0x0f5d,
+ 0x9699, 0x10e5,
+ 0x969b, 0x10e7,
+ 0x969c, 0x10e6,
+ 0x969e, 0x2852,
+ 0x96a1, 0x2853,
+ 0x96a2, 0x2ab7,
+ 0x96a3, 0x38af,
+ 0x96a4, 0x2ab6,
+ 0x96a5, 0x42ef,
+ 0x96a7, 0x1386,
+ 0x96a9, 0x2cf2,
+ 0x96aa, 0x1388,
+ 0x96ac, 0x2eb0,
+ 0x96ae, 0x2eae,
+ 0x96b0, 0x2eaf,
+ 0x96b1, 0x14af,
+ 0x96b3, 0x3020,
+ 0x96b4, 0x15ec,
+ 0x96b6, 0x0231,
+ 0x96b8, 0x14b0,
+ 0x96b9, 0x069f,
+ 0x96bb, 0x09f3,
+ 0x96bc, 0x1e31,
+ 0x96bd, 0x38b5,
+ 0x96bf, 0x20a9,
+ 0x96c0, 0x0bda,
+ 0x96c1, 0x0da8,
+ 0x96c2, 0x2354,
+ 0x96c3, 0x2356,
+ 0x96c4, 0x0daa,
+ 0x96c5, 0x0da9,
+ 0x96c6, 0x0dab,
+ 0x96c8, 0x2355,
+ 0x96c9, 0x0f62,
+ 0x96cb, 0x0f61,
+ 0x96cc, 0x10e8,
+ 0x96cd, 0x0f60,
+ 0x96ce, 0x25f8,
+ 0x96d2, 0x10e9,
+ 0x96d3, 0x2ab8,
+ 0x96d4, 0x2cf3,
+ 0x96d5, 0x1389,
+ 0x96d6, 0x14b1,
+ 0x96d7, 0x3021,
+ 0x96d8, 0x3025,
+ 0x96d9, 0x1550,
+ 0x96da, 0x3022,
+ 0x96db, 0x1551,
+ 0x96dc, 0x154f,
+ 0x96dd, 0x3026,
+ 0x96de, 0x1552,
+ 0x96df, 0x3024,
+ 0x96e1, 0x3165,
+ 0x96e2, 0x154e,
+ 0x96e3, 0x15ed,
+ 0x96e5, 0x34a8,
+ 0x96e8, 0x06a0,
+ 0x96e9, 0x0bdc,
+ 0x96ea, 0x0bdb,
+ 0x96ef, 0x0dad,
+ 0x96f0, 0x2358,
+ 0x96f1, 0x2357,
+ 0x96f2, 0x0dae,
+ 0x96f4, 0x3a04,
+ 0x96f5, 0x25fc,
+ 0x96f6, 0x0f67,
+ 0x96f7, 0x0f64,
+ 0x96f8, 0x25fb,
+ 0x96f9, 0x0f66,
+ 0x96fa, 0x25f9,
+ 0x96fb, 0x0f65,
+ 0x96fd, 0x25fa,
+ 0x96ff, 0x2854,
+ 0x9700, 0x10ea,
+ 0x9702, 0x2abb,
+ 0x9703, 0x3f0d,
+ 0x9704, 0x1262,
+ 0x9705, 0x2ab9,
+ 0x9706, 0x1263,
+ 0x9708, 0x2aba,
+ 0x9709, 0x1265,
+ 0x970b, 0x2cf4,
+ 0x970d, 0x138d,
+ 0x970e, 0x138a,
+ 0x970f, 0x138f,
+ 0x9710, 0x2cf6,
+ 0x9711, 0x138b,
+ 0x9712, 0x2cf5,
+ 0x9713, 0x138e,
+ 0x9716, 0x138c,
+ 0x9718, 0x2eb3,
+ 0x9719, 0x2eb5,
+ 0x971b, 0x38c9,
+ 0x971c, 0x14b2,
+ 0x971d, 0x2eb4,
+ 0x971e, 0x14b3,
+ 0x971f, 0x2eb2,
+ 0x9720, 0x2eb1,
+ 0x9721, 0x3fb3,
+ 0x9722, 0x3028,
+ 0x9723, 0x3027,
+ 0x9724, 0x1553,
+ 0x9725, 0x3029,
+ 0x9726, 0x316a,
+ 0x9727, 0x15ef,
+ 0x9728, 0x3169,
+ 0x9729, 0x3166,
+ 0x972a, 0x15ee,
+ 0x972b, 0x3167,
+ 0x972e, 0x326f,
+ 0x9730, 0x1656,
+ 0x9731, 0x38c0,
+ 0x9732, 0x16a3,
+ 0x9735, 0x3331,
+ 0x9736, 0x38c2,
+ 0x9738, 0x16a1,
+ 0x973a, 0x3332,
+ 0x973d, 0x16e2,
+ 0x973f, 0x33d1,
+ 0x9740, 0x47b3,
+ 0x9741, 0x3be9,
+ 0x9742, 0x1732,
+ 0x9743, 0x34aa,
+ 0x9744, 0x1734,
+ 0x9746, 0x34a9,
+ 0x9747, 0x34ab,
+ 0x9748, 0x1733,
+ 0x9749, 0x34f1,
+ 0x974b, 0x3526,
+ 0x9751, 0x44e3,
+ 0x9752, 0x06a1,
+ 0x9756, 0x0f68,
+ 0x9757, 0x38cc,
+ 0x9758, 0x2855,
+ 0x975a, 0x2abc,
+ 0x975b, 0x1390,
+ 0x975d, 0x3bef,
+ 0x975e, 0x06a2,
+ 0x975f, 0x38cf,
+ 0x9760, 0x1266,
+ 0x9761, 0x15f0,
+ 0x9762, 0x0826,
+ 0x9766, 0x1392,
+ 0x9768, 0x1710,
+ 0x9769, 0x0827,
+ 0x976a, 0x20aa,
+ 0x976c, 0x2359,
+ 0x976d, 0x3e97,
+ 0x976e, 0x235b,
+ 0x9770, 0x235a,
+ 0x9771, 0x3bfc,
+ 0x9772, 0x2600,
+ 0x9773, 0x25fd,
+ 0x9774, 0x0f69,
+ 0x9776, 0x0f6a,
+ 0x9777, 0x25fe,
+ 0x977a, 0x2857,
+ 0x977b, 0x285c,
+ 0x977c, 0x10eb,
+ 0x977d, 0x2856,
+ 0x977e, 0x2858,
+ 0x977f, 0x285f,
+ 0x9780, 0x285a,
+ 0x9781, 0x285e,
+ 0x9782, 0x285b,
+ 0x9783, 0x2859,
+ 0x9784, 0x285d,
+ 0x9785, 0x10ec,
+ 0x9787, 0x40c0,
+ 0x9788, 0x2abf,
+ 0x9789, 0x38d4,
+ 0x978a, 0x2abd,
+ 0x978b, 0x1268,
+ 0x978d, 0x1267,
+ 0x978e, 0x2abe,
+ 0x978f, 0x1269,
+ 0x9794, 0x2cf9,
+ 0x9797, 0x2cf8,
+ 0x9798, 0x1393,
+ 0x9799, 0x2cf7,
+ 0x979a, 0x2eb6,
+ 0x979b, 0x3bfb,
+ 0x979c, 0x2eb8,
+ 0x979d, 0x2eba,
+ 0x979e, 0x2eb9,
+ 0x979f, 0x38d5,
+ 0x97a0, 0x14b4,
+ 0x97a1, 0x2eb7,
+ 0x97a2, 0x3030,
+ 0x97a3, 0x1554,
+ 0x97a4, 0x302e,
+ 0x97a5, 0x3031,
+ 0x97a6, 0x1555,
+ 0x97a8, 0x302c,
+ 0x97aa, 0x302f,
+ 0x97ab, 0x302d,
+ 0x97ac, 0x302a,
+ 0x97ad, 0x1556,
+ 0x97ae, 0x302b,
+ 0x97b1, 0x38d6,
+ 0x97b2, 0x47b5,
+ 0x97b3, 0x316b,
+ 0x97b4, 0x3f33,
+ 0x97b6, 0x316d,
+ 0x97b7, 0x316c,
+ 0x97b8, 0x3d95,
+ 0x97b9, 0x3271,
+ 0x97ba, 0x3f35,
+ 0x97bb, 0x3272,
+ 0x97bd, 0x494e,
+ 0x97be, 0x38d7,
+ 0x97bf, 0x3333,
+ 0x97c0, 0x38d8,
+ 0x97c1, 0x16e5,
+ 0x97c2, 0x47b6,
+ 0x97c3, 0x16e4,
+ 0x97c4, 0x344c,
+ 0x97c6, 0x1735,
+ 0x97c7, 0x34ac,
+ 0x97c8, 0x3f2f,
+ 0x97c9, 0x1756,
+ 0x97cb, 0x0828,
+ 0x97cc, 0x0daf,
+ 0x97cd, 0x2861,
+ 0x97ce, 0x2860,
+ 0x97cf, 0x2ac1,
+ 0x97d0, 0x2ac0,
+ 0x97d2, 0x38d9,
+ 0x97d3, 0x14b5,
+ 0x97d4, 0x2ebc,
+ 0x97d5, 0x2ebb,
+ 0x97d6, 0x3034,
+ 0x97d7, 0x3032,
+ 0x97d8, 0x3035,
+ 0x97d9, 0x3033,
+ 0x97dc, 0x15f1,
+ 0x97dd, 0x316e,
+ 0x97e0, 0x38da,
+ 0x97e1, 0x3334,
+ 0x97e3, 0x33d2,
+ 0x97e5, 0x34ad,
+ 0x97e6, 0x450c,
+ 0x97ed, 0x0829,
+ 0x97ee, 0x38dc,
+ 0x97f0, 0x2cfa,
+ 0x97f1, 0x2ebd,
+ 0x97f2, 0x394d,
+ 0x97f3, 0x082a,
+ 0x97f5, 0x38e0,
+ 0x97f6, 0x10ed,
+ 0x97f8, 0x2cfb,
+ 0x97f9, 0x1557,
+ 0x97fa, 0x3036,
+ 0x97fb, 0x15f2,
+ 0x97fd, 0x3273,
+ 0x97ff, 0x16a4,
+ 0x9800, 0x344e,
+ 0x9801, 0x082b,
+ 0x9802, 0x0bdf,
+ 0x9804, 0x20ab,
+ 0x9805, 0x0db0,
+ 0x9807, 0x235c,
+ 0x9808, 0x0db2,
+ 0x980a, 0x0f6e,
+ 0x980c, 0x0f70,
+ 0x980d, 0x2602,
+ 0x980f, 0x2601,
+ 0x9810, 0x0f6b,
+ 0x9812, 0x0f6f,
+ 0x9813, 0x0f6d,
+ 0x9814, 0x4952,
+ 0x9815, 0x433c,
+ 0x9816, 0x2862,
+ 0x9817, 0x10ee,
+ 0x981b, 0x2ac8,
+ 0x981c, 0x126c,
+ 0x981d, 0x2ac3,
+ 0x981e, 0x2ac2,
+ 0x981f, 0x3c02,
+ 0x9820, 0x2ac7,
+ 0x9821, 0x126a,
+ 0x9823, 0x3e37,
+ 0x9824, 0x139a,
+ 0x9826, 0x2ac4,
+ 0x9827, 0x2ac9,
+ 0x9828, 0x2ac6,
+ 0x9829, 0x2ac5,
+ 0x982b, 0x126b,
+ 0x982d, 0x1398,
+ 0x982e, 0x3f72,
+ 0x982f, 0x2cfd,
+ 0x9830, 0x1394,
+ 0x9832, 0x2cfe,
+ 0x9833, 0x38e5,
+ 0x9834, 0x38e4,
+ 0x9835, 0x2cfc,
+ 0x9837, 0x1397,
+ 0x9838, 0x1395,
+ 0x9839, 0x1399,
+ 0x983b, 0x1396,
+ 0x9841, 0x2ebe,
+ 0x9843, 0x2ec3,
+ 0x9844, 0x2ebf,
+ 0x9845, 0x2ec2,
+ 0x9846, 0x14b6,
+ 0x9847, 0x3d96,
+ 0x9848, 0x2df2,
+ 0x9849, 0x2ec1,
+ 0x984a, 0x2ec0,
+ 0x984b, 0x38e6,
+ 0x984c, 0x155a,
+ 0x984d, 0x1558,
+ 0x984e, 0x155b,
+ 0x984f, 0x1559,
+ 0x9850, 0x3037,
+ 0x9853, 0x155c,
+ 0x9857, 0x3174,
+ 0x9858, 0x15f4,
+ 0x9859, 0x3172,
+ 0x985b, 0x15f5,
+ 0x985c, 0x3171,
+ 0x985d, 0x3173,
+ 0x985e, 0x15f3,
+ 0x985f, 0x3278,
+ 0x9860, 0x3275,
+ 0x9862, 0x3276,
+ 0x9864, 0x3335,
+ 0x9865, 0x16a6,
+ 0x9866, 0x38e7,
+ 0x9867, 0x16a5,
+ 0x9869, 0x33d4,
+ 0x986a, 0x33d3,
+ 0x986b, 0x16e6,
+ 0x986c, 0x4035,
+ 0x986f, 0x1711,
+ 0x9870, 0x1736,
+ 0x9871, 0x174d,
+ 0x9872, 0x34f2,
+ 0x9873, 0x3527,
+ 0x9875, 0x450d,
+ 0x98a8, 0x082c,
+ 0x98a9, 0x235d,
+ 0x98ac, 0x2604,
+ 0x98ad, 0x2863,
+ 0x98af, 0x10f0,
+ 0x98b1, 0x10f1,
+ 0x98b2, 0x2aca,
+ 0x98b3, 0x126d,
+ 0x98b4, 0x3f73,
+ 0x98b6, 0x14b7,
+ 0x98b7, 0x38ef,
+ 0x98b8, 0x303a,
+ 0x98b9, 0x47b8,
+ 0x98ba, 0x155d,
+ 0x98bb, 0x3177,
+ 0x98bc, 0x15f6,
+ 0x98bd, 0x3176,
+ 0x98be, 0x3178,
+ 0x98bf, 0x3175,
+ 0x98c0, 0x3338,
+ 0x98c1, 0x3279,
+ 0x98c3, 0x3b78,
+ 0x98c4, 0x1657,
+ 0x98c6, 0x3337,
+ 0x98c7, 0x38f1,
+ 0x98c8, 0x38f0,
+ 0x98c9, 0x3336,
+ 0x98ca, 0x38ee,
+ 0x98cb, 0x33d5,
+ 0x98cc, 0x3529,
+ 0x98ce, 0x450e,
+ 0x98db, 0x082d,
+ 0x98dc, 0x3c0b,
+ 0x98de, 0x450f,
+ 0x98df, 0x082e,
+ 0x98e0, 0x4792,
+ 0x98e1, 0x38f6,
+ 0x98e2, 0x09f4,
+ 0x98e3, 0x1e32,
+ 0x98e5, 0x20ac,
+ 0x98e6, 0x38f7,
+ 0x98e7, 0x0db3,
+ 0x98e9, 0x0db6,
+ 0x98ea, 0x0db4,
+ 0x98eb, 0x235e,
+ 0x98ec, 0x38f8,
+ 0x98ed, 0x0db8,
+ 0x98ef, 0x0db5,
+ 0x98f1, 0x47ba,
+ 0x98f2, 0x0db7,
+ 0x98f4, 0x0f72,
+ 0x98f5, 0x4365,
+ 0x98f6, 0x2605,
+ 0x98f9, 0x2606,
+ 0x98fa, 0x2acc,
+ 0x98fc, 0x0f71,
+ 0x98fd, 0x0f73,
+ 0x9900, 0x2866,
+ 0x9902, 0x2865,
+ 0x9903, 0x10f2,
+ 0x9905, 0x10f3,
+ 0x9907, 0x2867,
+ 0x9908, 0x2acb,
+ 0x9909, 0x10f5,
+ 0x990a, 0x126e,
+ 0x990c, 0x10f4,
+ 0x990e, 0x43ed,
+ 0x9910, 0x139b,
+ 0x9911, 0x2acd,
+ 0x9912, 0x1270,
+ 0x9913, 0x126f,
+ 0x9914, 0x2ace,
+ 0x9915, 0x2ad1,
+ 0x9916, 0x2acf,
+ 0x9918, 0x1271,
+ 0x9919, 0x47bc,
+ 0x991a, 0x13a0,
+ 0x991b, 0x139e,
+ 0x991c, 0x43ee,
+ 0x991e, 0x139d,
+ 0x991f, 0x2d00,
+ 0x9921, 0x139f,
+ 0x9924, 0x2cff,
+ 0x9925, 0x2ec4,
+ 0x9927, 0x2d01,
+ 0x9928, 0x139c,
+ 0x9929, 0x2d02,
+ 0x992a, 0x2ec7,
+ 0x992b, 0x2ec5,
+ 0x992d, 0x2ecb,
+ 0x992e, 0x1561,
+ 0x992f, 0x2eca,
+ 0x9930, 0x2ecd,
+ 0x9931, 0x2ecc,
+ 0x9932, 0x2ec9,
+ 0x9933, 0x2ec8,
+ 0x9935, 0x14b8,
+ 0x9937, 0x47bd,
+ 0x9938, 0x3bfd,
+ 0x9939, 0x38fa,
+ 0x993a, 0x303d,
+ 0x993b, 0x3c11,
+ 0x993c, 0x303c,
+ 0x993d, 0x1560,
+ 0x993e, 0x155e,
+ 0x9940, 0x3f34,
+ 0x9941, 0x303b,
+ 0x9942, 0x43ff,
+ 0x9943, 0x317b,
+ 0x9945, 0x15f7,
+ 0x9947, 0x317a,
+ 0x9948, 0x3179,
+ 0x9949, 0x15f8,
+ 0x994a, 0x3fb9,
+ 0x994b, 0x327f,
+ 0x994c, 0x327e,
+ 0x994d, 0x3c12,
+ 0x994e, 0x327c,
+ 0x9950, 0x327b,
+ 0x9951, 0x1659,
+ 0x9952, 0x1658,
+ 0x9953, 0x3280,
+ 0x9954, 0x33d6,
+ 0x9955, 0x16e7,
+ 0x9956, 0x333a,
+ 0x9957, 0x16a7,
+ 0x9958, 0x3339,
+ 0x9959, 0x327d,
+ 0x995b, 0x33d7,
+ 0x995c, 0x1712,
+ 0x995d, 0x47be,
+ 0x995e, 0x174e,
+ 0x995f, 0x34f3,
+ 0x9961, 0x352a,
+ 0x9962, 0x43ef,
+ 0x9963, 0x4510,
+ 0x9996, 0x082f,
+ 0x9997, 0x20ad,
+ 0x9998, 0x2ece,
+ 0x9999, 0x0830,
+ 0x999b, 0x3c15,
+ 0x999c, 0x2869,
+ 0x999d, 0x2868,
+ 0x999e, 0x2d03,
+ 0x99a1, 0x2ed0,
+ 0x99a3, 0x2ecf,
+ 0x99a4, 0x41c3,
+ 0x99a5, 0x1562,
+ 0x99a6, 0x317c,
+ 0x99a8, 0x165a,
+ 0x99aa, 0x3c17,
+ 0x99ab, 0x352b,
+ 0x99ac, 0x09f5,
+ 0x99ad, 0x0dba,
+ 0x99ae, 0x0db9,
+ 0x99af, 0x2607,
+ 0x99b0, 0x2609,
+ 0x99b1, 0x0f76,
+ 0x99b2, 0x2608,
+ 0x99b3, 0x0f75,
+ 0x99b4, 0x0f77,
+ 0x99b5, 0x260a,
+ 0x99b8, 0x394b,
+ 0x99b9, 0x286b,
+ 0x99ba, 0x286d,
+ 0x99bb, 0x286c,
+ 0x99bc, 0x3c22,
+ 0x99bd, 0x286f,
+ 0x99c1, 0x10f6,
+ 0x99c2, 0x286e,
+ 0x99c3, 0x286a,
+ 0x99c4, 0x3d77,
+ 0x99c5, 0x47c1,
+ 0x99c7, 0x2870,
+ 0x99c9, 0x2ad8,
+ 0x99cb, 0x2adb,
+ 0x99cc, 0x2add,
+ 0x99cd, 0x2ad3,
+ 0x99ce, 0x2ad7,
+ 0x99cf, 0x2ad4,
+ 0x99d0, 0x1273,
+ 0x99d1, 0x1276,
+ 0x99d2, 0x1278,
+ 0x99d3, 0x2ad5,
+ 0x99d5, 0x1277,
+ 0x99d6, 0x2ad9,
+ 0x99d7, 0x2adc,
+ 0x99d8, 0x2ada,
+ 0x99d9, 0x1279,
+ 0x99da, 0x3f42,
+ 0x99db, 0x1275,
+ 0x99dc, 0x2ad2,
+ 0x99dd, 0x1272,
+ 0x99df, 0x1274,
+ 0x99e1, 0x3785,
+ 0x99e2, 0x13a2,
+ 0x99e3, 0x2d09,
+ 0x99e4, 0x2d07,
+ 0x99e5, 0x2d06,
+ 0x99e6, 0x3b65,
+ 0x99e7, 0x2d0c,
+ 0x99e9, 0x2d0b,
+ 0x99ea, 0x2d0a,
+ 0x99ec, 0x2d05,
+ 0x99ed, 0x13a1,
+ 0x99ee, 0x2d04,
+ 0x99f0, 0x2d08,
+ 0x99f1, 0x13a3,
+ 0x99f4, 0x2ed3,
+ 0x99f5, 0x38ff,
+ 0x99f6, 0x2ed7,
+ 0x99f7, 0x2ed4,
+ 0x99f8, 0x2ed6,
+ 0x99f9, 0x2ed5,
+ 0x99fa, 0x2ed2,
+ 0x99fb, 0x2ed8,
+ 0x99fc, 0x2edb,
+ 0x99fd, 0x2ed9,
+ 0x99ff, 0x14ba,
+ 0x9a01, 0x14b9,
+ 0x9a02, 0x2ed1,
+ 0x9a03, 0x2edc,
+ 0x9a04, 0x3042,
+ 0x9a05, 0x3045,
+ 0x9a06, 0x3047,
+ 0x9a07, 0x3046,
+ 0x9a09, 0x3040,
+ 0x9a0a, 0x3044,
+ 0x9a0b, 0x303f,
+ 0x9a0c, 0x3900,
+ 0x9a0d, 0x3041,
+ 0x9a0e, 0x1563,
+ 0x9a0f, 0x303e,
+ 0x9a10, 0x3902,
+ 0x9a11, 0x3043,
+ 0x9a14, 0x318a,
+ 0x9a15, 0x317f,
+ 0x9a16, 0x15f9,
+ 0x9a19, 0x15fa,
+ 0x9a1a, 0x317e,
+ 0x9a1b, 0x3183,
+ 0x9a1c, 0x3189,
+ 0x9a1d, 0x3181,
+ 0x9a1e, 0x3188,
+ 0x9a1f, 0x3b6c,
+ 0x9a20, 0x3185,
+ 0x9a21, 0x3c1c,
+ 0x9a22, 0x3184,
+ 0x9a23, 0x3187,
+ 0x9a24, 0x3182,
+ 0x9a25, 0x3180,
+ 0x9a26, 0x3df2,
+ 0x9a27, 0x3186,
+ 0x9a29, 0x3287,
+ 0x9a2a, 0x3285,
+ 0x9a2b, 0x165b,
+ 0x9a2c, 0x3284,
+ 0x9a2d, 0x328a,
+ 0x9a2e, 0x3288,
+ 0x9a2f, 0x3c1e,
+ 0x9a30, 0x165c,
+ 0x9a31, 0x3283,
+ 0x9a32, 0x3281,
+ 0x9a34, 0x3282,
+ 0x9a35, 0x165e,
+ 0x9a36, 0x3286,
+ 0x9a37, 0x165d,
+ 0x9a38, 0x3289,
+ 0x9a39, 0x333b,
+ 0x9a3a, 0x3341,
+ 0x9a3b, 0x3901,
+ 0x9a3c, 0x47c3,
+ 0x9a3d, 0x333c,
+ 0x9a3e, 0x16ab,
+ 0x9a3f, 0x3342,
+ 0x9a40, 0x16aa,
+ 0x9a41, 0x3340,
+ 0x9a42, 0x333f,
+ 0x9a43, 0x16a9,
+ 0x9a44, 0x333e,
+ 0x9a45, 0x16a8,
+ 0x9a46, 0x333d,
+ 0x9a48, 0x33dd,
+ 0x9a49, 0x33df,
+ 0x9a4a, 0x33de,
+ 0x9a4c, 0x33db,
+ 0x9a4d, 0x16e9,
+ 0x9a4e, 0x33d8,
+ 0x9a4f, 0x33dc,
+ 0x9a50, 0x33e1,
+ 0x9a52, 0x33e0,
+ 0x9a53, 0x33d9,
+ 0x9a55, 0x16e8,
+ 0x9a56, 0x344f,
+ 0x9a57, 0x1715,
+ 0x9a58, 0x3903,
+ 0x9a59, 0x3450,
+ 0x9a5a, 0x1713,
+ 0x9a5c, 0x3c18,
+ 0x9a5e, 0x34ae,
+ 0x9a5f, 0x1737,
+ 0x9a60, 0x3510,
+ 0x9a62, 0x1757,
+ 0x9a63, 0x3b67,
+ 0x9a64, 0x352c,
+ 0x9a65, 0x1758,
+ 0x9a66, 0x352d,
+ 0x9a68, 0x353c,
+ 0x9a69, 0x353b,
+ 0x9a6a, 0x1767,
+ 0x9a6b, 0x3544,
+ 0x9a6c, 0x4585,
+ 0x9a8f, 0x4586,
+ 0x9aa8, 0x09f6,
+ 0x9aab, 0x260c,
+ 0x9aad, 0x260b,
+ 0x9aaf, 0x10f7,
+ 0x9ab1, 0x2871,
+ 0x9ab2, 0x4332,
+ 0x9ab3, 0x2ade,
+ 0x9ab4, 0x2d0f,
+ 0x9ab6, 0x43f0,
+ 0x9ab7, 0x127a,
+ 0x9ab8, 0x13a4,
+ 0x9ab9, 0x2d0d,
+ 0x9aba, 0x3f74,
+ 0x9abb, 0x2d10,
+ 0x9abc, 0x13a5,
+ 0x9abd, 0x3d97,
+ 0x9abe, 0x2edd,
+ 0x9abf, 0x2d0e,
+ 0x9ac0, 0x3048,
+ 0x9ac1, 0x1564,
+ 0x9ac2, 0x318b,
+ 0x9ac6, 0x328d,
+ 0x9ac7, 0x328b,
+ 0x9aca, 0x328c,
+ 0x9acd, 0x3343,
+ 0x9acf, 0x16ac,
+ 0x9ad0, 0x33e2,
+ 0x9ad1, 0x1718,
+ 0x9ad2, 0x16ea,
+ 0x9ad3, 0x1716,
+ 0x9ad5, 0x34af,
+ 0x9ad6, 0x174f,
+ 0x9ad7, 0x3faa,
+ 0x9ad8, 0x09f7,
+ 0x9adc, 0x3049,
+ 0x9adf, 0x1e33,
+ 0x9ae0, 0x3908,
+ 0x9ae1, 0x0f78,
+ 0x9ae2, 0x3909,
+ 0x9ae3, 0x2872,
+ 0x9ae6, 0x10f9,
+ 0x9ae7, 0x2873,
+ 0x9aeb, 0x2ae0,
+ 0x9aec, 0x2adf,
+ 0x9aed, 0x13a7,
+ 0x9aee, 0x127b,
+ 0x9af1, 0x2ae3,
+ 0x9af2, 0x2ae2,
+ 0x9af3, 0x2ae1,
+ 0x9af4, 0x390b,
+ 0x9af6, 0x2d11,
+ 0x9af7, 0x2d14,
+ 0x9af9, 0x2d13,
+ 0x9afa, 0x2d12,
+ 0x9afb, 0x13a6,
+ 0x9afc, 0x2ee1,
+ 0x9afd, 0x2edf,
+ 0x9afe, 0x2ede,
+ 0x9aff, 0x3f17,
+ 0x9b01, 0x2ee0,
+ 0x9b02, 0x3f12,
+ 0x9b03, 0x1565,
+ 0x9b04, 0x304b,
+ 0x9b06, 0x1566,
+ 0x9b08, 0x304a,
+ 0x9b09, 0x3f20,
+ 0x9b0a, 0x318d,
+ 0x9b0b, 0x318c,
+ 0x9b0c, 0x318f,
+ 0x9b0d, 0x15fb,
+ 0x9b0e, 0x318e,
+ 0x9b0f, 0x47c4,
+ 0x9b10, 0x328e,
+ 0x9b11, 0x3290,
+ 0x9b12, 0x328f,
+ 0x9b14, 0x390d,
+ 0x9b15, 0x3344,
+ 0x9b16, 0x3347,
+ 0x9b17, 0x3345,
+ 0x9b19, 0x33e3,
+ 0x9b1a, 0x16eb,
+ 0x9b1e, 0x3451,
+ 0x9b22, 0x1738,
+ 0x9b23, 0x1750,
+ 0x9b24, 0x352f,
+ 0x9b25, 0x09f8,
+ 0x9b27, 0x127d,
+ 0x9b28, 0x13a8,
+ 0x9b29, 0x304d,
+ 0x9b2a, 0x3f19,
+ 0x9b2b, 0x33e4,
+ 0x9b2d, 0x390e,
+ 0x9b2e, 0x3511,
+ 0x9b2f, 0x1e34,
+ 0x9b31, 0x1768,
+ 0x9b32, 0x09f9,
+ 0x9b33, 0x2d15,
+ 0x9b34, 0x3911,
+ 0x9b35, 0x304e,
+ 0x9b37, 0x3190,
+ 0x9b39, 0x3f00,
+ 0x9b3a, 0x3348,
+ 0x9b3b, 0x33e5,
+ 0x9b3c, 0x09fa,
+ 0x9b3e, 0x2874,
+ 0x9b40, 0x3915,
+ 0x9b41, 0x10fa,
+ 0x9b43, 0x2ae5,
+ 0x9b44, 0x127f,
+ 0x9b45, 0x127e,
+ 0x9b46, 0x2ae4,
+ 0x9b48, 0x2ee2,
+ 0x9b4a, 0x304f,
+ 0x9b4b, 0x3051,
+ 0x9b4c, 0x3050,
+ 0x9b4d, 0x1569,
+ 0x9b4e, 0x1568,
+ 0x9b4f, 0x1567,
+ 0x9b50, 0x3914,
+ 0x9b51, 0x16ae,
+ 0x9b52, 0x3349,
+ 0x9b54, 0x16ad,
+ 0x9b55, 0x33e7,
+ 0x9b56, 0x33e6,
+ 0x9b58, 0x1739,
+ 0x9b59, 0x34b0,
+ 0x9b5a, 0x0be1,
+ 0x9b5b, 0x260d,
+ 0x9b5f, 0x2878,
+ 0x9b60, 0x2876,
+ 0x9b64, 0x2aee,
+ 0x9b66, 0x2ae9,
+ 0x9b67, 0x2ae6,
+ 0x9b68, 0x2aed,
+ 0x9b69, 0x47c5,
+ 0x9b6c, 0x2aef,
+ 0x9b6f, 0x1281,
+ 0x9b70, 0x2aec,
+ 0x9b71, 0x2ae8,
+ 0x9b74, 0x2ae7,
+ 0x9b75, 0x2aeb,
+ 0x9b76, 0x2aea,
+ 0x9b77, 0x1280,
+ 0x9b7a, 0x2d20,
+ 0x9b7b, 0x2d1b,
+ 0x9b7c, 0x2d19,
+ 0x9b7d, 0x2d22,
+ 0x9b7e, 0x2d1a,
+ 0x9b7f, 0x3c3b,
+ 0x9b80, 0x2d16,
+ 0x9b81, 0x43f1,
+ 0x9b82, 0x2d1c,
+ 0x9b83, 0x4219,
+ 0x9b85, 0x2d17,
+ 0x9b86, 0x2eeb,
+ 0x9b87, 0x2d18,
+ 0x9b88, 0x2d23,
+ 0x9b8b, 0x3eee,
+ 0x9b8d, 0x4623,
+ 0x9b8e, 0x3919,
+ 0x9b8f, 0x3fad,
+ 0x9b90, 0x2d1f,
+ 0x9b91, 0x13a9,
+ 0x9b92, 0x2d1e,
+ 0x9b93, 0x2d1d,
+ 0x9b95, 0x2d21,
+ 0x9b97, 0x3f71,
+ 0x9b9a, 0x2ee3,
+ 0x9b9b, 0x2ee6,
+ 0x9b9d, 0x3f56,
+ 0x9b9e, 0x2ee5,
+ 0x9b9f, 0x3c3e,
+ 0x9ba0, 0x2eed,
+ 0x9ba1, 0x2ee8,
+ 0x9ba2, 0x2eec,
+ 0x9ba4, 0x2eea,
+ 0x9ba5, 0x2ee9,
+ 0x9ba6, 0x2ee7,
+ 0x9ba8, 0x2ee4,
+ 0x9baa, 0x14bd,
+ 0x9bab, 0x14bc,
+ 0x9bad, 0x14be,
+ 0x9bae, 0x14bb,
+ 0x9baf, 0x2eee,
+ 0x9bb0, 0x3fb4,
+ 0x9bb5, 0x3057,
+ 0x9bb6, 0x305a,
+ 0x9bb8, 0x3058,
+ 0x9bb9, 0x305c,
+ 0x9bbd, 0x305d,
+ 0x9bbf, 0x3055,
+ 0x9bc0, 0x156e,
+ 0x9bc1, 0x3056,
+ 0x9bc3, 0x3054,
+ 0x9bc4, 0x305b,
+ 0x9bc6, 0x3053,
+ 0x9bc7, 0x3052,
+ 0x9bc8, 0x156d,
+ 0x9bc9, 0x156b,
+ 0x9bca, 0x156a,
+ 0x9bcf, 0x3c3c,
+ 0x9bd3, 0x3059,
+ 0x9bd4, 0x3199,
+ 0x9bd5, 0x319f,
+ 0x9bd6, 0x15fe,
+ 0x9bd7, 0x319a,
+ 0x9bd9, 0x319d,
+ 0x9bda, 0x31a1,
+ 0x9bdb, 0x15ff,
+ 0x9bdc, 0x319c,
+ 0x9bdd, 0x47c6,
+ 0x9bde, 0x3194,
+ 0x9be0, 0x3193,
+ 0x9be1, 0x31a0,
+ 0x9be2, 0x3197,
+ 0x9be4, 0x3195,
+ 0x9be5, 0x319e,
+ 0x9be6, 0x3196,
+ 0x9be7, 0x15fd,
+ 0x9be8, 0x15fc,
+ 0x9be9, 0x3bc1,
+ 0x9bea, 0x3191,
+ 0x9bec, 0x319b,
+ 0x9bed, 0x3ed7,
+ 0x9bf0, 0x3198,
+ 0x9bf1, 0x47c7,
+ 0x9bf4, 0x47c8,
+ 0x9bf7, 0x3293,
+ 0x9bf8, 0x3296,
+ 0x9bfd, 0x156c,
+ 0x9bff, 0x391b,
+ 0x9c02, 0x391a,
+ 0x9c05, 0x3294,
+ 0x9c06, 0x329a,
+ 0x9c07, 0x3298,
+ 0x9c08, 0x3292,
+ 0x9c09, 0x329d,
+ 0x9c0a, 0x3f3a,
+ 0x9c0b, 0x3291,
+ 0x9c0c, 0x391c,
+ 0x9c0d, 0x1660,
+ 0x9c0e, 0x3299,
+ 0x9c10, 0x3c3a,
+ 0x9c12, 0x3295,
+ 0x9c13, 0x165f,
+ 0x9c14, 0x329c,
+ 0x9c15, 0x3f1e,
+ 0x9c17, 0x329b,
+ 0x9c1b, 0x491b,
+ 0x9c1c, 0x334c,
+ 0x9c1d, 0x334b,
+ 0x9c1f, 0x4622,
+ 0x9c20, 0x47ca,
+ 0x9c21, 0x3352,
+ 0x9c23, 0x334e,
+ 0x9c24, 0x3351,
+ 0x9c25, 0x16b0,
+ 0x9c26, 0x45e6,
+ 0x9c28, 0x334f,
+ 0x9c2b, 0x334a,
+ 0x9c2c, 0x334d,
+ 0x9c2d, 0x16af,
+ 0x9c2e, 0x3f22,
+ 0x9c2f, 0x3d87,
+ 0x9c31, 0x16ed,
+ 0x9c32, 0x33f2,
+ 0x9c33, 0x33ed,
+ 0x9c34, 0x33f1,
+ 0x9c35, 0x3c39,
+ 0x9c36, 0x33f4,
+ 0x9c37, 0x33f0,
+ 0x9c39, 0x33ec,
+ 0x9c3a, 0x3d7e,
+ 0x9c3b, 0x16ef,
+ 0x9c3c, 0x33ef,
+ 0x9c3d, 0x33f3,
+ 0x9c3e, 0x16ee,
+ 0x9c3f, 0x33ea,
+ 0x9c40, 0x3297,
+ 0x9c41, 0x33ee,
+ 0x9c44, 0x33eb,
+ 0x9c45, 0x3e71,
+ 0x9c46, 0x33e8,
+ 0x9c48, 0x33e9,
+ 0x9c49, 0x16ec,
+ 0x9c4a, 0x3457,
+ 0x9c4b, 0x3459,
+ 0x9c4c, 0x345c,
+ 0x9c4d, 0x3458,
+ 0x9c4e, 0x345d,
+ 0x9c4f, 0x3c36,
+ 0x9c50, 0x3456,
+ 0x9c52, 0x3454,
+ 0x9c53, 0x3c37,
+ 0x9c54, 0x1719,
+ 0x9c55, 0x345a,
+ 0x9c56, 0x171b,
+ 0x9c57, 0x171a,
+ 0x9c58, 0x3455,
+ 0x9c59, 0x345b,
+ 0x9c5d, 0x3ebf,
+ 0x9c5e, 0x34b5,
+ 0x9c5f, 0x173a,
+ 0x9c60, 0x34b6,
+ 0x9c62, 0x34b4,
+ 0x9c63, 0x34b1,
+ 0x9c66, 0x34b3,
+ 0x9c67, 0x34b2,
+ 0x9c68, 0x34f4,
+ 0x9c6d, 0x34f6,
+ 0x9c6e, 0x34f5,
+ 0x9c71, 0x3514,
+ 0x9c72, 0x3ea1,
+ 0x9c73, 0x3513,
+ 0x9c74, 0x3512,
+ 0x9c75, 0x3515,
+ 0x9c77, 0x1760,
+ 0x9c79, 0x3541,
+ 0x9c7a, 0x3545,
+ 0x9c7b, 0x3c38,
+ 0x9c7c, 0x4512,
+ 0x9ce5, 0x0be2,
+ 0x9ce6, 0x235f,
+ 0x9ce7, 0x2610,
+ 0x9ce9, 0x0f79,
+ 0x9cea, 0x260e,
+ 0x9ced, 0x260f,
+ 0x9cf1, 0x2879,
+ 0x9cf3, 0x10fe,
+ 0x9cf4, 0x10fc,
+ 0x9cf5, 0x287b,
+ 0x9cf6, 0x10fd,
+ 0x9cf7, 0x2af4,
+ 0x9cf9, 0x2af7,
+ 0x9cfa, 0x2af1,
+ 0x9cfb, 0x2af8,
+ 0x9cfc, 0x2af0,
+ 0x9cfd, 0x2af2,
+ 0x9cff, 0x2af3,
+ 0x9d00, 0x2af6,
+ 0x9d02, 0x3f3b,
+ 0x9d03, 0x1284,
+ 0x9d04, 0x2afb,
+ 0x9d05, 0x2afa,
+ 0x9d06, 0x1282,
+ 0x9d07, 0x2af5,
+ 0x9d08, 0x2af9,
+ 0x9d09, 0x1283,
+ 0x9d0c, 0x3c46,
+ 0x9d10, 0x2d2d,
+ 0x9d12, 0x13ae,
+ 0x9d14, 0x2d28,
+ 0x9d15, 0x13aa,
+ 0x9d16, 0x3c7c,
+ 0x9d17, 0x2d25,
+ 0x9d18, 0x2d2b,
+ 0x9d19, 0x2d2e,
+ 0x9d1b, 0x13af,
+ 0x9d1d, 0x2d2a,
+ 0x9d1e, 0x2d27,
+ 0x9d1f, 0x2d2f,
+ 0x9d20, 0x2d26,
+ 0x9d21, 0x3c41,
+ 0x9d22, 0x2d2c,
+ 0x9d23, 0x13ab,
+ 0x9d25, 0x2d24,
+ 0x9d26, 0x13ac,
+ 0x9d28, 0x13ad,
+ 0x9d29, 0x2d29,
+ 0x9d2d, 0x2f00,
+ 0x9d2e, 0x2ef3,
+ 0x9d30, 0x2ef7,
+ 0x9d31, 0x2ef5,
+ 0x9d33, 0x2eef,
+ 0x9d34, 0x404a,
+ 0x9d36, 0x2ef2,
+ 0x9d37, 0x2efc,
+ 0x9d38, 0x2ef6,
+ 0x9d39, 0x392e,
+ 0x9d3b, 0x14bf,
+ 0x9d3d, 0x2efe,
+ 0x9d3e, 0x2efb,
+ 0x9d3f, 0x14c0,
+ 0x9d40, 0x2efd,
+ 0x9d41, 0x2ef0,
+ 0x9d42, 0x2ef9,
+ 0x9d44, 0x3fab,
+ 0x9d45, 0x2ef8,
+ 0x9d49, 0x47cd,
+ 0x9d4a, 0x3061,
+ 0x9d4b, 0x3063,
+ 0x9d4c, 0x3066,
+ 0x9d4e, 0x4539,
+ 0x9d4f, 0x3060,
+ 0x9d50, 0x3eca,
+ 0x9d51, 0x156f,
+ 0x9d52, 0x3068,
+ 0x9d53, 0x305f,
+ 0x9d54, 0x3069,
+ 0x9d56, 0x3065,
+ 0x9d57, 0x3067,
+ 0x9d58, 0x306b,
+ 0x9d59, 0x3064,
+ 0x9d5a, 0x306c,
+ 0x9d5b, 0x3062,
+ 0x9d5c, 0x305e,
+ 0x9d5d, 0x1570,
+ 0x9d5e, 0x3e6e,
+ 0x9d5f, 0x306a,
+ 0x9d60, 0x1571,
+ 0x9d61, 0x1601,
+ 0x9d67, 0x2ef1,
+ 0x9d68, 0x31bb,
+ 0x9d69, 0x31b2,
+ 0x9d6a, 0x1603,
+ 0x9d6b, 0x31ae,
+ 0x9d6c, 0x1604,
+ 0x9d6d, 0x3bac,
+ 0x9d6e, 0x433b,
+ 0x9d6f, 0x31b7,
+ 0x9d70, 0x31b1,
+ 0x9d71, 0x31a7,
+ 0x9d72, 0x1602,
+ 0x9d73, 0x31b4,
+ 0x9d74, 0x31af,
+ 0x9d77, 0x31a2,
+ 0x9d78, 0x31a9,
+ 0x9d79, 0x31b8,
+ 0x9d7b, 0x31b5,
+ 0x9d7c, 0x3efe,
+ 0x9d7d, 0x31ad,
+ 0x9d7e, 0x3925,
+ 0x9d7f, 0x31b9,
+ 0x9d80, 0x31a8,
+ 0x9d81, 0x31a3,
+ 0x9d82, 0x31b6,
+ 0x9d83, 0x3926,
+ 0x9d84, 0x31a5,
+ 0x9d85, 0x31b3,
+ 0x9d86, 0x31aa,
+ 0x9d87, 0x31ba,
+ 0x9d88, 0x31a6,
+ 0x9d89, 0x1600,
+ 0x9d8a, 0x31a4,
+ 0x9d8b, 0x31ab,
+ 0x9d90, 0x32a4,
+ 0x9d92, 0x32a2,
+ 0x9d93, 0x43f3,
+ 0x9d94, 0x32a7,
+ 0x9d96, 0x32b3,
+ 0x9d97, 0x32aa,
+ 0x9d98, 0x32a3,
+ 0x9d99, 0x329f,
+ 0x9d9a, 0x32ac,
+ 0x9d9b, 0x32a5,
+ 0x9d9c, 0x32a8,
+ 0x9d9d, 0x32a1,
+ 0x9d9e, 0x32af,
+ 0x9d9f, 0x329e,
+ 0x9da0, 0x32a6,
+ 0x9da1, 0x32ab,
+ 0x9da2, 0x32ad,
+ 0x9da3, 0x32b0,
+ 0x9da4, 0x32a0,
+ 0x9da5, 0x3c4b,
+ 0x9da6, 0x32b4,
+ 0x9da8, 0x32ae,
+ 0x9da9, 0x32b2,
+ 0x9daa, 0x32a9,
+ 0x9dab, 0x3f30,
+ 0x9dac, 0x3362,
+ 0x9dad, 0x3365,
+ 0x9daf, 0x16b1,
+ 0x9db1, 0x3364,
+ 0x9db2, 0x3369,
+ 0x9db3, 0x3367,
+ 0x9db4, 0x16b2,
+ 0x9db5, 0x335e,
+ 0x9db6, 0x3354,
+ 0x9db7, 0x3353,
+ 0x9db8, 0x16b4,
+ 0x9db9, 0x3360,
+ 0x9dbb, 0x335d,
+ 0x9dbc, 0x3355,
+ 0x9dbd, 0x47d0,
+ 0x9dbe, 0x335a,
+ 0x9dbf, 0x32b1,
+ 0x9dc0, 0x43f2,
+ 0x9dc1, 0x3356,
+ 0x9dc2, 0x16b3,
+ 0x9dc3, 0x335c,
+ 0x9dc4, 0x3929,
+ 0x9dc5, 0x335b,
+ 0x9dc7, 0x3357,
+ 0x9dc8, 0x3363,
+ 0x9dc9, 0x4579,
+ 0x9dca, 0x3358,
+ 0x9dcb, 0x33f9,
+ 0x9dcc, 0x3366,
+ 0x9dcd, 0x3368,
+ 0x9dce, 0x335f,
+ 0x9dcf, 0x3359,
+ 0x9dd0, 0x33fa,
+ 0x9dd1, 0x33fc,
+ 0x9dd2, 0x33f6,
+ 0x9dd3, 0x16f0,
+ 0x9dd4, 0x391e,
+ 0x9dd5, 0x3403,
+ 0x9dd6, 0x3401,
+ 0x9dd7, 0x16f1,
+ 0x9dd8, 0x3400,
+ 0x9dd9, 0x33ff,
+ 0x9dda, 0x33f8,
+ 0x9ddb, 0x33f5,
+ 0x9ddc, 0x33fb,
+ 0x9ddd, 0x3404,
+ 0x9dde, 0x33f7,
+ 0x9ddf, 0x33fd,
+ 0x9de1, 0x3466,
+ 0x9de2, 0x346b,
+ 0x9de3, 0x3461,
+ 0x9de4, 0x3464,
+ 0x9de5, 0x171c,
+ 0x9de6, 0x3468,
+ 0x9de8, 0x346f,
+ 0x9de9, 0x33fe,
+ 0x9deb, 0x3462,
+ 0x9dec, 0x346c,
+ 0x9ded, 0x3470,
+ 0x9dee, 0x3467,
+ 0x9def, 0x3460,
+ 0x9df0, 0x346a,
+ 0x9df2, 0x3469,
+ 0x9df3, 0x346e,
+ 0x9df4, 0x346d,
+ 0x9df5, 0x3402,
+ 0x9df6, 0x3465,
+ 0x9df7, 0x345f,
+ 0x9df8, 0x3463,
+ 0x9df9, 0x173b,
+ 0x9dfb, 0x345e,
+ 0x9dfc, 0x47d1,
+ 0x9dfd, 0x34c1,
+ 0x9dfe, 0x34b8,
+ 0x9dff, 0x34c0,
+ 0x9e00, 0x34bd,
+ 0x9e02, 0x34b7,
+ 0x9e03, 0x34ba,
+ 0x9e04, 0x34c2,
+ 0x9e05, 0x34bc,
+ 0x9e06, 0x34bb,
+ 0x9e07, 0x34b9,
+ 0x9e09, 0x34bf,
+ 0x9e0a, 0x457e,
+ 0x9e0b, 0x34f7,
+ 0x9e0c, 0x457a,
+ 0x9e0d, 0x34f8,
+ 0x9e0e, 0x3928,
+ 0x9e0f, 0x34fa,
+ 0x9e10, 0x34f9,
+ 0x9e11, 0x34fc,
+ 0x9e12, 0x34fb,
+ 0x9e13, 0x3517,
+ 0x9e14, 0x3516,
+ 0x9e15, 0x3530,
+ 0x9e17, 0x3531,
+ 0x9e18, 0x3c44,
+ 0x9e19, 0x353d,
+ 0x9e1a, 0x1765,
+ 0x9e1b, 0x1769,
+ 0x9e1c, 0x3f84,
+ 0x9e1d, 0x3546,
+ 0x9e1e, 0x176a,
+ 0x9e1f, 0x4513,
+ 0x9e75, 0x0be3,
+ 0x9e79, 0x1661,
+ 0x9e7a, 0x336a,
+ 0x9e7b, 0x43f8,
+ 0x9e7c, 0x173d,
+ 0x9e7f, 0x0be4,
+ 0x9e80, 0x2611,
+ 0x9e81, 0x3f0f,
+ 0x9e82, 0x0f7a,
+ 0x9e83, 0x2afc,
+ 0x9e84, 0x3f76,
+ 0x9e85, 0x3ef2,
+ 0x9e86, 0x2d31,
+ 0x9e88, 0x2d30,
+ 0x9e89, 0x2f02,
+ 0x9e8a, 0x2f01,
+ 0x9e8b, 0x14c1,
+ 0x9e8c, 0x306e,
+ 0x9e8d, 0x2f03,
+ 0x9e8e, 0x306d,
+ 0x9e90, 0x3931,
+ 0x9e91, 0x31bd,
+ 0x9e92, 0x1605,
+ 0x9e93, 0x1607,
+ 0x9e94, 0x31bc,
+ 0x9e95, 0x3932,
+ 0x9e96, 0x3fbc,
+ 0x9e97, 0x1606,
+ 0x9e98, 0x3f27,
+ 0x9e99, 0x32b6,
+ 0x9e9a, 0x32b8,
+ 0x9e9b, 0x32b7,
+ 0x9e9c, 0x336b,
+ 0x9e9d, 0x16b5,
+ 0x9e9e, 0x3933,
+ 0x9e9f, 0x171d,
+ 0x9ea0, 0x34c3,
+ 0x9ea1, 0x34fd,
+ 0x9ea2, 0x3934,
+ 0x9ea4, 0x354a,
+ 0x9ea5, 0x0be5,
+ 0x9ea6, 0x4944,
+ 0x9ea7, 0x287c,
+ 0x9ea8, 0x3f75,
+ 0x9ea9, 0x1285,
+ 0x9eaa, 0x3936,
+ 0x9eab, 0x3e92,
+ 0x9eac, 0x43f4,
+ 0x9ead, 0x2d34,
+ 0x9eae, 0x2d33,
+ 0x9eaf, 0x3937,
+ 0x9eb0, 0x2f04,
+ 0x9eb1, 0x47d4,
+ 0x9eb4, 0x1608,
+ 0x9eb5, 0x1662,
+ 0x9eb6, 0x3405,
+ 0x9eb7, 0x3542,
+ 0x9ebb, 0x0be6,
+ 0x9ebc, 0x10ff,
+ 0x9ebd, 0x47d5,
+ 0x9ebe, 0x1286,
+ 0x9ebf, 0x3d78,
+ 0x9ec0, 0x31be,
+ 0x9ec1, 0x3939,
+ 0x9ec2, 0x3471,
+ 0x9ec3, 0x0dbb,
+ 0x9ec4, 0x4514,
+ 0x9ec6, 0x47d6,
+ 0x9ec7, 0x4577,
+ 0x9ec8, 0x2f05,
+ 0x9ecc, 0x1751,
+ 0x9ecd, 0x0dbc,
+ 0x9ece, 0x1287,
+ 0x9ecf, 0x14c2,
+ 0x9ed0, 0x3472,
+ 0x9ed1, 0x0dbd,
+ 0x9ed3, 0x2afd,
+ 0x9ed4, 0x13b1,
+ 0x9ed5, 0x2d35,
+ 0x9ed8, 0x13b0,
+ 0x9eda, 0x2f06,
+ 0x9edb, 0x14c6,
+ 0x9edc, 0x14c4,
+ 0x9ede, 0x14c3,
+ 0x9edf, 0x306f,
+ 0x9ee0, 0x1572,
+ 0x9ee2, 0x47d8,
+ 0x9ee4, 0x32ba,
+ 0x9ee5, 0x32b9,
+ 0x9ee6, 0x32bc,
+ 0x9ee7, 0x32bb,
+ 0x9ee8, 0x1663,
+ 0x9eeb, 0x336c,
+ 0x9eed, 0x336e,
+ 0x9eee, 0x336d,
+ 0x9eef, 0x16b6,
+ 0x9ef0, 0x3406,
+ 0x9ef1, 0x47d9,
+ 0x9ef2, 0x3473,
+ 0x9ef4, 0x171e,
+ 0x9ef5, 0x34fe,
+ 0x9ef6, 0x3518,
+ 0x9ef7, 0x1762,
+ 0x9ef8, 0x47da,
+ 0x9ef9, 0x2360,
+ 0x9efa, 0x2d37,
+ 0x9efb, 0x2f07,
+ 0x9efc, 0x31bf,
+ 0x9efd, 0x2612,
+ 0x9efe, 0x47ce,
+ 0x9eff, 0x2f08,
+ 0x9f00, 0x3071,
+ 0x9f01, 0x3070,
+ 0x9f02, 0x3940,
+ 0x9f06, 0x3475,
+ 0x9f07, 0x173f,
+ 0x9f08, 0x3941,
+ 0x9f09, 0x34ff,
+ 0x9f0a, 0x3519,
+ 0x9f0e, 0x0f7b,
+ 0x9f0f, 0x2afe,
+ 0x9f12, 0x2d38,
+ 0x9f13, 0x0f7c,
+ 0x9f15, 0x1573,
+ 0x9f16, 0x3072,
+ 0x9f17, 0x3945,
+ 0x9f18, 0x3370,
+ 0x9f19, 0x16b7,
+ 0x9f1a, 0x3371,
+ 0x9f1b, 0x336f,
+ 0x9f1c, 0x3476,
+ 0x9f1e, 0x34c4,
+ 0x9f20, 0x0f7d,
+ 0x9f22, 0x2f0b,
+ 0x9f23, 0x2f0a,
+ 0x9f24, 0x2f09,
+ 0x9f25, 0x3073,
+ 0x9f26, 0x3f90,
+ 0x9f27, 0x4620,
+ 0x9f28, 0x3077,
+ 0x9f29, 0x3076,
+ 0x9f2a, 0x3075,
+ 0x9f2b, 0x3074,
+ 0x9f2c, 0x1574,
+ 0x9f2d, 0x31c0,
+ 0x9f2e, 0x32be,
+ 0x9f2f, 0x1664,
+ 0x9f30, 0x32bd,
+ 0x9f31, 0x3372,
+ 0x9f32, 0x3409,
+ 0x9f33, 0x3408,
+ 0x9f34, 0x16f2,
+ 0x9f35, 0x3407,
+ 0x9f36, 0x3479,
+ 0x9f37, 0x3478,
+ 0x9f38, 0x3477,
+ 0x9f39, 0x3947,
+ 0x9f3b, 0x1100,
+ 0x9f3d, 0x2d39,
+ 0x9f3e, 0x14c7,
+ 0x9f40, 0x31c1,
+ 0x9f42, 0x340a,
+ 0x9f43, 0x347a,
+ 0x9f44, 0x47db,
+ 0x9f45, 0x394a,
+ 0x9f46, 0x34c5,
+ 0x9f47, 0x3500,
+ 0x9f48, 0x3532,
+ 0x9f49, 0x354c,
+ 0x9f4a, 0x1101,
+ 0x9f4b, 0x14c8,
+ 0x9f4c, 0x3078,
+ 0x9f4d, 0x31c3,
+ 0x9f4e, 0x3373,
+ 0x9f4f, 0x347b,
+ 0x9f50, 0x4943,
+ 0x9f52, 0x1289,
+ 0x9f53, 0x3f80,
+ 0x9f54, 0x2f0c,
+ 0x9f55, 0x3079,
+ 0x9f56, 0x31c4,
+ 0x9f59, 0x32c3,
+ 0x9f5a, 0x3f23,
+ 0x9f5b, 0x32bf,
+ 0x9f5c, 0x16b8,
+ 0x9f5d, 0x32c2,
+ 0x9f5e, 0x32c1,
+ 0x9f5f, 0x1665,
+ 0x9f60, 0x32c0,
+ 0x9f61, 0x1667,
+ 0x9f62, 0x394f,
+ 0x9f63, 0x1666,
+ 0x9f64, 0x3375,
+ 0x9f65, 0x3374,
+ 0x9f66, 0x16b9,
+ 0x9f69, 0x3950,
+ 0x9f6a, 0x16f4,
+ 0x9f6b, 0x340b,
+ 0x9f6c, 0x16f3,
+ 0x9f6e, 0x347e,
+ 0x9f70, 0x347d,
+ 0x9f71, 0x347c,
+ 0x9f72, 0x1741,
+ 0x9f74, 0x34c6,
+ 0x9f77, 0x1740,
+ 0x9f78, 0x3501,
+ 0x9f79, 0x3504,
+ 0x9f7a, 0x3503,
+ 0x9f7b, 0x3502,
+ 0x9f7e, 0x354b,
+ 0x9f7f, 0x4680,
+ 0x9f8d, 0x13b2,
+ 0x9f8e, 0x3952,
+ 0x9f90, 0x157c,
+ 0x9f91, 0x32c4,
+ 0x9f92, 0x3376,
+ 0x9f94, 0x16f5,
+ 0x9f95, 0x340c,
+ 0x9f98, 0x354d,
+ 0x9f99, 0x4587,
+ 0x9f9c, 0x13b3,
+ 0x9f9f, 0x4646,
+ 0x9fa0, 0x2f0d,
+ 0x9fa2, 0x340d,
+ 0x9fa4, 0x351a,
+ 0x9fa5, 0x3f70,
+ 0xfa0c, 0x0274,
+ 0xfa0d, 0x2381,
+ 0xfe30, 0x006d,
+ 0xfe31, 0x007a,
+ 0xfe33, 0x35af,
+ 0xfe34, 0x35b1,
+ 0xfe35, 0x0082,
+ 0xfe37, 0x0086,
+ 0xfe39, 0x008a,
+ 0xfe3b, 0x008e,
+ 0xfe3d, 0x0092,
+ 0xfe3f, 0x0096,
+ 0xfe41, 0x009a,
+ 0xfe43, 0x009e,
+ 0xfe49, 0x00c7,
+ 0xfe4b, 0x00cb,
+ 0xfe4d, 0x00c9,
+ 0xfe4f, 0x35b2,
+ 0xfe50, 0x0070,
+ 0xfe52, 0x0072,
+ 0xfe54, 0x0074,
+ 0xfe59, 0x00a0,
+ 0xfe5f, 0x00cd,
+ 0xfe62, 0x00df,
+ 0xfe69, 0x010c,
+ 0xff01, 0x006c,
+ 0xff02, 0x36e4,
+ 0xff03, 0x00ae,
+ 0xff04, 0x0103,
+ 0xff05, 0x0108,
+ 0xff06, 0x00af,
+ 0xff07, 0x36e3,
+ 0xff08, 0x0080,
+ 0xff0a, 0x00b0,
+ 0xff0b, 0x00d0,
+ 0xff0c, 0x0064,
+ 0xff0d, 0x00d1,
+ 0xff0e, 0x0067,
+ 0xff0f, 0x0101,
+ 0xff10, 0x014d,
+ 0xff1a, 0x006a,
+ 0xff1b, 0x0069,
+ 0xff1c, 0x00d6,
+ 0xff1d, 0x00d8,
+ 0xff1e, 0x00d7,
+ 0xff1f, 0x006b,
+ 0xff20, 0x0109,
+ 0xff21, 0x016d,
+ 0xff3b, 0x35be,
+ 0xff3c, 0x0102,
+ 0xff3d, 0x35bf,
+ 0xff3e, 0x35b4,
+ 0xff3f, 0x00c5,
+ 0xff41, 0x0187,
+ 0xff5b, 0x0084,
+ 0xff5c, 0x0078,
+ 0xff5d, 0x0085,
+ 0xff64, 0x0071,
+ 0xffe2, 0x36e1,
+ 0xffe4, 0x36e2,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13UniCNSUCS2HEnc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13UniCNSUCS2HMap2, 15455
+};
+
+static Gushort cns13UniCNSUCS2VMap2[30936] = {
+ 0x0000, 0x0000,
+ 0x0020, 0x0001,
+ 0x00a2, 0x0106,
+ 0x00a5, 0x0104,
+ 0x00a7, 0x00b2,
+ 0x00a8, 0x35b3,
+ 0x00ac, 0x36e1,
+ 0x00b0, 0x0118,
+ 0x00b1, 0x00d4,
+ 0x00b7, 0x0073,
+ 0x00c0, 0x4964,
+ 0x00c1, 0x4962,
+ 0x00c8, 0x4968,
+ 0x00c9, 0x4966,
+ 0x00ca, 0x4971,
+ 0x00d2, 0x496c,
+ 0x00d3, 0x496a,
+ 0x00d7, 0x00d2,
+ 0x00e0, 0x4975,
+ 0x00e1, 0x4973,
+ 0x00e8, 0x497a,
+ 0x00e9, 0x4978,
+ 0x00ea, 0x4990,
+ 0x00ec, 0x497e,
+ 0x00ed, 0x497c,
+ 0x00f2, 0x4982,
+ 0x00f3, 0x4980,
+ 0x00f7, 0x00d3,
+ 0x00f8, 0x4998,
+ 0x00f9, 0x4986,
+ 0x00fa, 0x4984,
+ 0x00fc, 0x498b,
+ 0x0100, 0x4961,
+ 0x0101, 0x4972,
+ 0x0112, 0x4965,
+ 0x0113, 0x4977,
+ 0x011a, 0x4967,
+ 0x011b, 0x4979,
+ 0x012b, 0x497b,
+ 0x014b, 0x4999,
+ 0x014c, 0x4969,
+ 0x014d, 0x497f,
+ 0x0153, 0x4997,
+ 0x016b, 0x4983,
+ 0x01cd, 0x4963,
+ 0x01ce, 0x4974,
+ 0x01d0, 0x497d,
+ 0x01d1, 0x496b,
+ 0x01d2, 0x4981,
+ 0x01d4, 0x4985,
+ 0x01d6, 0x4987,
+ 0x01d8, 0x4988,
+ 0x01da, 0x4989,
+ 0x01dc, 0x498a,
+ 0x0250, 0x4993,
+ 0x0251, 0x4976,
+ 0x0254, 0x4995,
+ 0x025b, 0x4994,
+ 0x0261, 0x4991,
+ 0x026a, 0x499b,
+ 0x0275, 0x4996,
+ 0x0283, 0x4992,
+ 0x028a, 0x499a,
+ 0x02c6, 0x35b4,
+ 0x02c7, 0x01f8,
+ 0x02ca, 0x01f7,
+ 0x02cb, 0x01f9,
+ 0x02d9, 0x01f6,
+ 0x0308, 0x35b3,
+ 0x0391, 0x01a1,
+ 0x03a3, 0x01b2,
+ 0x03b1, 0x01b9,
+ 0x03c3, 0x01ca,
+ 0x0401, 0x3670,
+ 0x0410, 0x366a,
+ 0x0416, 0x3671,
+ 0x0436, 0x3692,
+ 0x0451, 0x3691,
+ 0x1ebe, 0x496e,
+ 0x1ebf, 0x498d,
+ 0x1ec0, 0x4970,
+ 0x1ec1, 0x498f,
+ 0x2013, 0x0079,
+ 0x2014, 0x007b,
+ 0x2018, 0x00a6,
+ 0x201c, 0x00a8,
+ 0x2022, 0x0068,
+ 0x2025, 0x006f,
+ 0x2026, 0x006e,
+ 0x2032, 0x00ad,
+ 0x2035, 0x00ac,
+ 0x203b, 0x00b1,
+ 0x203e, 0x00c3,
+ 0x20ac, 0x44c1,
+ 0x2103, 0x010a,
+ 0x2105, 0x00c2,
+ 0x2109, 0x010b,
+ 0x2116, 0x36e6,
+ 0x2121, 0x36e7,
+ 0x2160, 0x0157,
+ 0x2170, 0x020e,
+ 0x2190, 0x00f8,
+ 0x2191, 0x00f5,
+ 0x2192, 0x00f7,
+ 0x2193, 0x00f6,
+ 0x2196, 0x00f9,
+ 0x2198, 0x00fc,
+ 0x2199, 0x00fb,
+ 0x21b8, 0x36ad,
+ 0x21e7, 0x36ac,
+ 0x221a, 0x00d5,
+ 0x221e, 0x00dc,
+ 0x221f, 0x00e9,
+ 0x2220, 0x00e8,
+ 0x2223, 0x00fe,
+ 0x2225, 0x00fd,
+ 0x2229, 0x00e5,
+ 0x222b, 0x00ed,
+ 0x222e, 0x00ee,
+ 0x2234, 0x00f0,
+ 0x2235, 0x00ef,
+ 0x223c, 0x00e4,
+ 0x2252, 0x00dd,
+ 0x2260, 0x00db,
+ 0x2261, 0x00de,
+ 0x2266, 0x00d9,
+ 0x22a5, 0x00e7,
+ 0x22bf, 0x00ea,
+ 0x2400, 0x0232,
+ 0x2421, 0x0252,
+ 0x2460, 0x01fa,
+ 0x2474, 0x0204,
+ 0x2500, 0x0137,
+ 0x2502, 0x0138,
+ 0x250c, 0x013a,
+ 0x2510, 0x013b,
+ 0x2514, 0x013c,
+ 0x2518, 0x013d,
+ 0x251c, 0x0135,
+ 0x2524, 0x0134,
+ 0x252c, 0x0133,
+ 0x2534, 0x0132,
+ 0x253c, 0x0131,
+ 0x2550, 0x0142,
+ 0x2551, 0x370a,
+ 0x2552, 0x36f8,
+ 0x2553, 0x3701,
+ 0x2554, 0x36ef,
+ 0x2555, 0x36fa,
+ 0x2556, 0x3703,
+ 0x2557, 0x36f1,
+ 0x2558, 0x36fe,
+ 0x2559, 0x3707,
+ 0x255a, 0x36f5,
+ 0x255b, 0x3700,
+ 0x255c, 0x3709,
+ 0x255d, 0x36f7,
+ 0x255e, 0x0143,
+ 0x255f, 0x3704,
+ 0x2560, 0x36f2,
+ 0x2561, 0x0145,
+ 0x2562, 0x3706,
+ 0x2563, 0x36f4,
+ 0x2564, 0x36f9,
+ 0x2565, 0x3702,
+ 0x2566, 0x36f0,
+ 0x2567, 0x36ff,
+ 0x2568, 0x3708,
+ 0x2569, 0x36f6,
+ 0x256a, 0x0144,
+ 0x256b, 0x3705,
+ 0x256c, 0x36f3,
+ 0x256d, 0x013e,
+ 0x256f, 0x0141,
+ 0x2570, 0x0140,
+ 0x2571, 0x014a,
+ 0x2581, 0x0122,
+ 0x2589, 0x0130,
+ 0x258a, 0x012f,
+ 0x258b, 0x012e,
+ 0x258c, 0x012d,
+ 0x258d, 0x012c,
+ 0x258e, 0x012b,
+ 0x258f, 0x012a,
+ 0x2593, 0x3710,
+ 0x2594, 0x0136,
+ 0x2595, 0x0139,
+ 0x25a0, 0x00be,
+ 0x25a1, 0x00bd,
+ 0x25b2, 0x00b7,
+ 0x25b3, 0x00b6,
+ 0x25bc, 0x00c0,
+ 0x25bd, 0x00bf,
+ 0x25c6, 0x00bc,
+ 0x25c7, 0x00bb,
+ 0x25cb, 0x00b4,
+ 0x25ce, 0x00b8,
+ 0x25cf, 0x00b5,
+ 0x25e2, 0x0146,
+ 0x25e4, 0x0149,
+ 0x25e5, 0x0148,
+ 0x2605, 0x00ba,
+ 0x2606, 0x00b9,
+ 0x2609, 0x00f4,
+ 0x2640, 0x00f1,
+ 0x2641, 0x00f3,
+ 0x2642, 0x00f2,
+ 0x273d, 0x35c0,
+ 0x2e80, 0x44c8,
+ 0x2e84, 0x451c,
+ 0x2e86, 0x451d,
+ 0x2e8a, 0x4520,
+ 0x2e8c, 0x4521,
+ 0x2e95, 0x4523,
+ 0x2e9c, 0x4524,
+ 0x2e9d, 0x02dc,
+ 0x2ea5, 0x4525,
+ 0x2ea7, 0x4526,
+ 0x2eaa, 0x4527,
+ 0x2eac, 0x4528,
+ 0x2eae, 0x4529,
+ 0x2eb6, 0x452a,
+ 0x2ebc, 0x452b,
+ 0x2ebe, 0x452c,
+ 0x2ec6, 0x0509,
+ 0x2eca, 0x452d,
+ 0x2ecc, 0x452e,
+ 0x2ecf, 0x4530,
+ 0x2ed6, 0x4531,
+ 0x2ede, 0x4533,
+ 0x2ee3, 0x09f6,
+ 0x2f33, 0x0227,
+ 0x3000, 0x0063,
+ 0x3001, 0x0065,
+ 0x3003, 0x00b3,
+ 0x3005, 0x35ba,
+ 0x3008, 0x0094,
+ 0x300a, 0x0090,
+ 0x300c, 0x0098,
+ 0x300e, 0x009c,
+ 0x3010, 0x008c,
+ 0x3012, 0x0105,
+ 0x3014, 0x0088,
+ 0x301d, 0x00aa,
+ 0x3021, 0x0161,
+ 0x3041, 0x35c1,
+ 0x309b, 0x44c6,
+ 0x309d, 0x35b7,
+ 0x30a1, 0x3614,
+ 0x30fc, 0x35bd,
+ 0x30fd, 0x35b5,
+ 0x3105, 0x01d1,
+ 0x3231, 0x36e5,
+ 0x32a3, 0x00c1,
+ 0x338e, 0x0115,
+ 0x339c, 0x0110,
+ 0x33a1, 0x0114,
+ 0x33c4, 0x0117,
+ 0x33ce, 0x0113,
+ 0x33d1, 0x00ec,
+ 0x33d2, 0x00eb,
+ 0x33d5, 0x010f,
+ 0x3435, 0x39bd,
+ 0x3440, 0x3c67,
+ 0x344c, 0x4593,
+ 0x3464, 0x3a85,
+ 0x3473, 0x3dc5,
+ 0x347a, 0x4033,
+ 0x347d, 0x4597,
+ 0x347e, 0x46a3,
+ 0x3493, 0x439e,
+ 0x3496, 0x37dc,
+ 0x34a5, 0x4598,
+ 0x34af, 0x3c7f,
+ 0x34bc, 0x4380,
+ 0x34c1, 0x44fb,
+ 0x34c8, 0x3d00,
+ 0x34df, 0x3ea4,
+ 0x34e4, 0x3e54,
+ 0x34fb, 0x3dca,
+ 0x3506, 0x4336,
+ 0x353e, 0x44e7,
+ 0x3551, 0x45a1,
+ 0x3553, 0x43a5,
+ 0x3561, 0x40d8,
+ 0x356d, 0x45a4,
+ 0x3570, 0x3b2f,
+ 0x3572, 0x45a5,
+ 0x3577, 0x3ecb,
+ 0x3578, 0x4379,
+ 0x3584, 0x39fb,
+ 0x3597, 0x3b2d,
+ 0x3598, 0x45b0,
+ 0x35a1, 0x40e2,
+ 0x35a5, 0x45b1,
+ 0x35ad, 0x3efc,
+ 0x35bf, 0x45b2,
+ 0x35c1, 0x4580,
+ 0x35c5, 0x45b4,
+ 0x35c7, 0x459f,
+ 0x35ca, 0x3e43,
+ 0x35ce, 0x3e81,
+ 0x35d2, 0x3fc9,
+ 0x35d6, 0x3fb5,
+ 0x35db, 0x470d,
+ 0x35dd, 0x43ac,
+ 0x35f1, 0x4696,
+ 0x35f2, 0x4627,
+ 0x35f3, 0x3f6c,
+ 0x35fb, 0x45c8,
+ 0x35fe, 0x3f6a,
+ 0x3609, 0x45f5,
+ 0x3618, 0x4871,
+ 0x361a, 0x461a,
+ 0x3623, 0x40c6,
+ 0x362d, 0x3e86,
+ 0x3635, 0x492e,
+ 0x3639, 0x4165,
+ 0x363e, 0x3a08,
+ 0x3647, 0x4806,
+ 0x3648, 0x3806,
+ 0x3649, 0x4013,
+ 0x364e, 0x4698,
+ 0x365f, 0x3df3,
+ 0x367a, 0x3ee3,
+ 0x3681, 0x45a6,
+ 0x369a, 0x3c71,
+ 0x36a5, 0x4902,
+ 0x36aa, 0x3b30,
+ 0x36ac, 0x4900,
+ 0x36b0, 0x3cdf,
+ 0x36b1, 0x40cd,
+ 0x36b5, 0x3bc2,
+ 0x36b9, 0x4887,
+ 0x36bc, 0x3cff,
+ 0x36c1, 0x37c5,
+ 0x36c3, 0x40e5,
+ 0x36c4, 0x3905,
+ 0x36c5, 0x4296,
+ 0x36c7, 0x3d3a,
+ 0x36c8, 0x4820,
+ 0x36d3, 0x3a38,
+ 0x36d4, 0x3bb3,
+ 0x36d6, 0x3d0c,
+ 0x36dd, 0x3a36,
+ 0x36e1, 0x397c,
+ 0x36e2, 0x3cdd,
+ 0x36e5, 0x4216,
+ 0x36e6, 0x40fc,
+ 0x36f5, 0x3a18,
+ 0x3701, 0x3a34,
+ 0x3703, 0x460f,
+ 0x3708, 0x40ff,
+ 0x370a, 0x3cd5,
+ 0x370d, 0x4238,
+ 0x371c, 0x3dfe,
+ 0x3722, 0x3979,
+ 0x3723, 0x3980,
+ 0x3725, 0x3849,
+ 0x372c, 0x3c8c,
+ 0x372d, 0x3d37,
+ 0x3730, 0x495c,
+ 0x3732, 0x4106,
+ 0x3733, 0x3997,
+ 0x373a, 0x3e56,
+ 0x3740, 0x4202,
+ 0x3743, 0x4036,
+ 0x3762, 0x3db6,
+ 0x376f, 0x47cb,
+ 0x3797, 0x45ed,
+ 0x37a0, 0x3a28,
+ 0x37b9, 0x43b7,
+ 0x37be, 0x393e,
+ 0x37f2, 0x3ba1,
+ 0x37f8, 0x42d2,
+ 0x37fb, 0x3ef5,
+ 0x380f, 0x462c,
+ 0x3819, 0x39af,
+ 0x3820, 0x462f,
+ 0x382d, 0x412e,
+ 0x3836, 0x4133,
+ 0x3838, 0x43bb,
+ 0x3863, 0x46c3,
+ 0x38a0, 0x4145,
+ 0x38c3, 0x3912,
+ 0x38cc, 0x4076,
+ 0x38d1, 0x3a95,
+ 0x38fa, 0x44eb,
+ 0x3908, 0x4632,
+ 0x3914, 0x43be,
+ 0x3927, 0x3c31,
+ 0x3932, 0x4182,
+ 0x393f, 0x4633,
+ 0x394d, 0x4634,
+ 0x3963, 0x4163,
+ 0x3980, 0x3874,
+ 0x3989, 0x4638,
+ 0x398a, 0x3ce8,
+ 0x3992, 0x4376,
+ 0x3999, 0x39ba,
+ 0x399b, 0x3db3,
+ 0x39a1, 0x3e19,
+ 0x39a4, 0x3e0f,
+ 0x39b8, 0x463b,
+ 0x39dc, 0x3ece,
+ 0x39e2, 0x46c8,
+ 0x39e5, 0x393b,
+ 0x39ec, 0x4310,
+ 0x39f8, 0x463e,
+ 0x39fb, 0x4345,
+ 0x39fe, 0x4368,
+ 0x3a01, 0x41e0,
+ 0x3a03, 0x4640,
+ 0x3a06, 0x4377,
+ 0x3a17, 0x4190,
+ 0x3a18, 0x438f,
+ 0x3a29, 0x3a5e,
+ 0x3a2a, 0x3edf,
+ 0x3a34, 0x4319,
+ 0x3a4b, 0x4644,
+ 0x3a52, 0x3ed3,
+ 0x3a57, 0x419e,
+ 0x3a5c, 0x3fc4,
+ 0x3a5e, 0x3b07,
+ 0x3a66, 0x419c,
+ 0x3a67, 0x4333,
+ 0x3a97, 0x4647,
+ 0x3aab, 0x4091,
+ 0x3abd, 0x4649,
+ 0x3ade, 0x414c,
+ 0x3ae0, 0x3a7a,
+ 0x3af0, 0x46b2,
+ 0x3af2, 0x464c,
+ 0x3afb, 0x3af2,
+ 0x3b0e, 0x38e8,
+ 0x3b19, 0x46c5,
+ 0x3b22, 0x464e,
+ 0x3b2b, 0x4956,
+ 0x3b39, 0x474b,
+ 0x3b42, 0x4650,
+ 0x3b58, 0x4652,
+ 0x3b60, 0x393a,
+ 0x3b71, 0x4656,
+ 0x3b72, 0x4655,
+ 0x3b7b, 0x4657,
+ 0x3b7c, 0x385a,
+ 0x3b80, 0x41e2,
+ 0x3b96, 0x3a9c,
+ 0x3b99, 0x3a98,
+ 0x3ba1, 0x41e9,
+ 0x3bbc, 0x43c8,
+ 0x3bbe, 0x3db1,
+ 0x3bc2, 0x4134,
+ 0x3bc4, 0x3aa0,
+ 0x3bd7, 0x3aac,
+ 0x3bdd, 0x465f,
+ 0x3bec, 0x4664,
+ 0x3bf2, 0x4666,
+ 0x3bf3, 0x41f3,
+ 0x3bf4, 0x3a6e,
+ 0x3c0d, 0x41f7,
+ 0x3c11, 0x3e40,
+ 0x3c15, 0x3998,
+ 0x3c54, 0x3e00,
+ 0x3ccb, 0x4670,
+ 0x3ccd, 0x3ce5,
+ 0x3cd1, 0x4003,
+ 0x3cd6, 0x3cf7,
+ 0x3cdc, 0x404e,
+ 0x3ceb, 0x4217,
+ 0x3cef, 0x4675,
+ 0x3d13, 0x3773,
+ 0x3d1d, 0x393c,
+ 0x3d32, 0x4957,
+ 0x3d3b, 0x4245,
+ 0x3d46, 0x4685,
+ 0x3d4c, 0x3ceb,
+ 0x3d4e, 0x4242,
+ 0x3d51, 0x38ea,
+ 0x3d5f, 0x4159,
+ 0x3d62, 0x3c5e,
+ 0x3d69, 0x3cea,
+ 0x3d6a, 0x4689,
+ 0x3d6f, 0x3cfc,
+ 0x3d75, 0x468a,
+ 0x3d7d, 0x3c2f,
+ 0x3d85, 0x494b,
+ 0x3d8a, 0x468d,
+ 0x3d8f, 0x3abd,
+ 0x3d91, 0x468f,
+ 0x3da5, 0x3d56,
+ 0x3dad, 0x4699,
+ 0x3db4, 0x40a6,
+ 0x3dbf, 0x37d0,
+ 0x3dc6, 0x48de,
+ 0x3dc7, 0x4164,
+ 0x3dcc, 0x3d6f,
+ 0x3dcd, 0x3af3,
+ 0x3dd3, 0x37e1,
+ 0x3ddb, 0x3fff,
+ 0x3de7, 0x3999,
+ 0x3de8, 0x425d,
+ 0x3deb, 0x3e5a,
+ 0x3df3, 0x46d4,
+ 0x3df7, 0x48ab,
+ 0x3dfc, 0x462b,
+ 0x3dfd, 0x3c14,
+ 0x3e06, 0x491d,
+ 0x3e40, 0x4169,
+ 0x3e43, 0x436d,
+ 0x3e48, 0x4595,
+ 0x3e55, 0x427f,
+ 0x3e74, 0x3ee2,
+ 0x3ea8, 0x4304,
+ 0x3ea9, 0x46ed,
+ 0x3eaa, 0x4075,
+ 0x3ead, 0x3b9d,
+ 0x3eb1, 0x3ad8,
+ 0x3eb8, 0x3a4b,
+ 0x3ebf, 0x3b0b,
+ 0x3ec2, 0x3bd8,
+ 0x3ec7, 0x3975,
+ 0x3eca, 0x46f1,
+ 0x3ecc, 0x3be2,
+ 0x3ed0, 0x3854,
+ 0x3ed1, 0x46f2,
+ 0x3ed6, 0x3cad,
+ 0x3ed7, 0x429f,
+ 0x3eda, 0x3d02,
+ 0x3ede, 0x39f2,
+ 0x3ee1, 0x3ca8,
+ 0x3ee2, 0x46f6,
+ 0x3ee7, 0x3bdc,
+ 0x3ee9, 0x3ca4,
+ 0x3eeb, 0x396a,
+ 0x3ef0, 0x46f7,
+ 0x3ef3, 0x3add,
+ 0x3ef4, 0x46f8,
+ 0x3efa, 0x46f9,
+ 0x3efc, 0x3be8,
+ 0x3eff, 0x3af5,
+ 0x3f00, 0x3c0d,
+ 0x3f04, 0x42c3,
+ 0x3f06, 0x3ad7,
+ 0x3f0e, 0x46fb,
+ 0x3f53, 0x46fc,
+ 0x3f58, 0x3ae9,
+ 0x3f59, 0x4089,
+ 0x3f63, 0x3ae6,
+ 0x3f7c, 0x4700,
+ 0x3f93, 0x45cd,
+ 0x3fc0, 0x43cf,
+ 0x3fd7, 0x43d1,
+ 0x3fdc, 0x4704,
+ 0x3fe5, 0x46df,
+ 0x3fed, 0x4335,
+ 0x3ff9, 0x45d7,
+ 0x3ffa, 0x4354,
+ 0x4004, 0x410e,
+ 0x401d, 0x4709,
+ 0x4039, 0x470b,
+ 0x4045, 0x470c,
+ 0x4053, 0x45b6,
+ 0x4057, 0x399d,
+ 0x4062, 0x3bcb,
+ 0x4065, 0x3fd3,
+ 0x406a, 0x470f,
+ 0x406f, 0x4710,
+ 0x40a8, 0x43d5,
+ 0x40bb, 0x45c0,
+ 0x40bf, 0x3eec,
+ 0x40c8, 0x3b0e,
+ 0x40d8, 0x41ab,
+ 0x40df, 0x3e17,
+ 0x40fa, 0x3ebe,
+ 0x4103, 0x43d7,
+ 0x4104, 0x425c,
+ 0x4109, 0x471c,
+ 0x410e, 0x3b1b,
+ 0x4132, 0x3b25,
+ 0x4167, 0x471f,
+ 0x416c, 0x38ae,
+ 0x416e, 0x3b23,
+ 0x417f, 0x3b82,
+ 0x4190, 0x46c0,
+ 0x41b2, 0x4720,
+ 0x41c4, 0x4723,
+ 0x41ca, 0x373f,
+ 0x41cf, 0x4726,
+ 0x41db, 0x37bf,
+ 0x41ef, 0x3743,
+ 0x41f9, 0x3b3e,
+ 0x4211, 0x3b41,
+ 0x4240, 0x37f1,
+ 0x4260, 0x472b,
+ 0x426a, 0x3b55,
+ 0x427a, 0x472c,
+ 0x428c, 0x472f,
+ 0x4294, 0x4731,
+ 0x42b5, 0x4010,
+ 0x42b9, 0x38a6,
+ 0x42bc, 0x3c8a,
+ 0x42f4, 0x3bb9,
+ 0x42fb, 0x3cee,
+ 0x42fc, 0x41e6,
+ 0x432b, 0x377d,
+ 0x436e, 0x46ca,
+ 0x4397, 0x473b,
+ 0x43ba, 0x435f,
+ 0x43c1, 0x4695,
+ 0x43d9, 0x433e,
+ 0x43df, 0x3e49,
+ 0x43ed, 0x4745,
+ 0x43f2, 0x3e48,
+ 0x4401, 0x474a,
+ 0x4402, 0x3b73,
+ 0x4413, 0x474f,
+ 0x4425, 0x4751,
+ 0x442d, 0x4752,
+ 0x447a, 0x37af,
+ 0x448f, 0x4758,
+ 0x449f, 0x3ae2,
+ 0x44a0, 0x37ed,
+ 0x44a2, 0x4079,
+ 0x44b0, 0x475c,
+ 0x44b7, 0x3fa1,
+ 0x44c0, 0x3c07,
+ 0x44c5, 0x4210,
+ 0x44ce, 0x3d23,
+ 0x44dd, 0x39dd,
+ 0x44df, 0x3d22,
+ 0x44e4, 0x37e2,
+ 0x44e9, 0x41cf,
+ 0x44ea, 0x3b71,
+ 0x44eb, 0x3cf2,
+ 0x44ec, 0x3eb4,
+ 0x44f4, 0x3992,
+ 0x4503, 0x469f,
+ 0x4504, 0x4763,
+ 0x4509, 0x3e50,
+ 0x450b, 0x37d4,
+ 0x4516, 0x37f9,
+ 0x451d, 0x3767,
+ 0x4527, 0x37f7,
+ 0x452e, 0x3cd3,
+ 0x4533, 0x3c51,
+ 0x453b, 0x476a,
+ 0x453d, 0x38c4,
+ 0x453f, 0x3e12,
+ 0x4543, 0x37f3,
+ 0x4551, 0x3ae4,
+ 0x4552, 0x40b3,
+ 0x4555, 0x423e,
+ 0x455c, 0x378b,
+ 0x4562, 0x4940,
+ 0x456a, 0x3804,
+ 0x4577, 0x476e,
+ 0x4585, 0x38c5,
+ 0x45e9, 0x3ee4,
+ 0x4606, 0x4773,
+ 0x460f, 0x3815,
+ 0x4615, 0x3843,
+ 0x4617, 0x4774,
+ 0x465b, 0x381d,
+ 0x467a, 0x39e9,
+ 0x4680, 0x3d01,
+ 0x46cf, 0x3ba0,
+ 0x46d0, 0x3dfa,
+ 0x46f5, 0x3b9f,
+ 0x4713, 0x3833,
+ 0x4718, 0x3dc7,
+ 0x474e, 0x3ebc,
+ 0x477c, 0x3dcd,
+ 0x4798, 0x4781,
+ 0x47a6, 0x40a3,
+ 0x47b6, 0x3eea,
+ 0x47d5, 0x431a,
+ 0x47ed, 0x4783,
+ 0x47f4, 0x432f,
+ 0x4800, 0x461e,
+ 0x480b, 0x4352,
+ 0x4837, 0x4787,
+ 0x485d, 0x410f,
+ 0x4871, 0x3d03,
+ 0x489b, 0x3bbd,
+ 0x48ad, 0x4791,
+ 0x48ae, 0x494d,
+ 0x48d0, 0x3da7,
+ 0x48dd, 0x4120,
+ 0x48ed, 0x4288,
+ 0x48f3, 0x3ec1,
+ 0x48fa, 0x3e44,
+ 0x4906, 0x3bc7,
+ 0x4911, 0x4584,
+ 0x491e, 0x4794,
+ 0x4925, 0x3c0f,
+ 0x492a, 0x46ae,
+ 0x492d, 0x46cd,
+ 0x4935, 0x3cc3,
+ 0x493c, 0x3bf8,
+ 0x493e, 0x3d06,
+ 0x4945, 0x47a3,
+ 0x4951, 0x47a4,
+ 0x4953, 0x42ad,
+ 0x4965, 0x3899,
+ 0x496a, 0x47a9,
+ 0x4972, 0x3a24,
+ 0x4989, 0x379b,
+ 0x49a1, 0x38b7,
+ 0x49a7, 0x47ae,
+ 0x49df, 0x38aa,
+ 0x49e5, 0x47b1,
+ 0x49e7, 0x4621,
+ 0x4a0f, 0x38c3,
+ 0x4a1d, 0x3bec,
+ 0x4a24, 0x47b2,
+ 0x4a35, 0x47b4,
+ 0x4a96, 0x3ce7,
+ 0x4ab4, 0x4361,
+ 0x4ab8, 0x3da8,
+ 0x4ad1, 0x38e3,
+ 0x4ae4, 0x47b7,
+ 0x4aff, 0x38f2,
+ 0x4b19, 0x47b9,
+ 0x4b2c, 0x461f,
+ 0x4b37, 0x41a9,
+ 0x4b6f, 0x3c16,
+ 0x4b70, 0x47c0,
+ 0x4b72, 0x38fc,
+ 0x4b7b, 0x3c8d,
+ 0x4b7e, 0x400a,
+ 0x4b8e, 0x39f7,
+ 0x4b90, 0x3c20,
+ 0x4b93, 0x3a8c,
+ 0x4b96, 0x3942,
+ 0x4b97, 0x3c24,
+ 0x4b9d, 0x47c2,
+ 0x4bbd, 0x3c23,
+ 0x4bbe, 0x3954,
+ 0x4bc0, 0x3ddc,
+ 0x4c04, 0x3fbb,
+ 0x4c07, 0x3fb7,
+ 0x4c0e, 0x390c,
+ 0x4c3b, 0x3f3c,
+ 0x4c3e, 0x457b,
+ 0x4c5b, 0x3ed9,
+ 0x4c6d, 0x47c9,
+ 0x4c7d, 0x3e66,
+ 0x4ca4, 0x48be,
+ 0x4cae, 0x3c42,
+ 0x4cb0, 0x3c45,
+ 0x4cb7, 0x3e21,
+ 0x4ccd, 0x4578,
+ 0x4ce1, 0x3ef3,
+ 0x4ced, 0x40ab,
+ 0x4d09, 0x3ed6,
+ 0x4d10, 0x4117,
+ 0x4d34, 0x3935,
+ 0x4d91, 0x43f5,
+ 0x4d9c, 0x48c4,
+ 0x4e00, 0x0253,
+ 0x4e01, 0x0255,
+ 0x4e03, 0x0256,
+ 0x4e04, 0x48fe,
+ 0x4e07, 0x1771,
+ 0x4e08, 0x0269,
+ 0x4e09, 0x0267,
+ 0x4e0a, 0x026a,
+ 0x4e0b, 0x0268,
+ 0x4e0c, 0x1772,
+ 0x4e0d, 0x0294,
+ 0x4e0e, 0x177a,
+ 0x4e0f, 0x1778,
+ 0x4e10, 0x0293,
+ 0x4e11, 0x0292,
+ 0x4e14, 0x02f2,
+ 0x4e15, 0x02f1,
+ 0x4e16, 0x02f0,
+ 0x4e18, 0x02f3,
+ 0x4e19, 0x02ef,
+ 0x4e1a, 0x48fd,
+ 0x4e1c, 0x48e0,
+ 0x4e1e, 0x036e,
+ 0x4e21, 0x3d6d,
+ 0x4e24, 0x458d,
+ 0x4e26, 0x0528,
+ 0x4e28, 0x0218,
+ 0x4e2a, 0x3f57,
+ 0x4e2b, 0x026b,
+ 0x4e2c, 0x44f3,
+ 0x4e2d, 0x0295,
+ 0x4e2e, 0x177b,
+ 0x4e30, 0x0296,
+ 0x4e31, 0x178e,
+ 0x4e32, 0x0415,
+ 0x4e33, 0x18f4,
+ 0x4e36, 0x0219,
+ 0x4e37, 0x4517,
+ 0x4e38, 0x026c,
+ 0x4e39, 0x0297,
+ 0x4e3b, 0x02f4,
+ 0x4e3c, 0x178f,
+ 0x4e3d, 0x4537,
+ 0x4e3f, 0x021a,
+ 0x4e41, 0x36af,
+ 0x4e42, 0x176c,
+ 0x4e43, 0x0257,
+ 0x4e45, 0x026e,
+ 0x4e47, 0x1773,
+ 0x4e48, 0x026f,
+ 0x4e49, 0x408e,
+ 0x4e4b, 0x0298,
+ 0x4e4d, 0x02f5,
+ 0x4e4e, 0x02f7,
+ 0x4e4f, 0x02f6,
+ 0x4e52, 0x0370,
+ 0x4e56, 0x0529,
+ 0x4e58, 0x0831,
+ 0x4e59, 0x0254,
+ 0x4e5a, 0x36b1,
+ 0x4e5b, 0x44e5,
+ 0x4e5c, 0x176d,
+ 0x4e5d, 0x0258,
+ 0x4e5e, 0x0271,
+ 0x4e5f, 0x0270,
+ 0x4e69, 0x0372,
+ 0x4e6a, 0x3de5,
+ 0x4e73, 0x052a,
+ 0x4e78, 0x3d8e,
+ 0x4e7e, 0x09fb,
+ 0x4e7f, 0x1e35,
+ 0x4e80, 0x458e,
+ 0x4e81, 0x43bc,
+ 0x4e82, 0x0dbe,
+ 0x4e83, 0x2361,
+ 0x4e85, 0x021b,
+ 0x4e86, 0x0259,
+ 0x4e87, 0x458f,
+ 0x4e88, 0x029a,
+ 0x4e89, 0x459c,
+ 0x4e8b, 0x052b,
+ 0x4e8c, 0x025a,
+ 0x4e8d, 0x1774,
+ 0x4e8e, 0x0272,
+ 0x4e91, 0x029b,
+ 0x4e92, 0x029d,
+ 0x4e93, 0x177c,
+ 0x4e94, 0x029e,
+ 0x4e95, 0x029c,
+ 0x4e98, 0x39c4,
+ 0x4e99, 0x0373,
+ 0x4e9a, 0x48d5,
+ 0x4e9b, 0x052c,
+ 0x4e9e, 0x052d,
+ 0x4e9f, 0x06a3,
+ 0x4ea0, 0x021c,
+ 0x4ea1, 0x0273,
+ 0x4ea2, 0x029f,
+ 0x4ea4, 0x0374,
+ 0x4ea5, 0x0376,
+ 0x4ea6, 0x0375,
+ 0x4ea8, 0x0416,
+ 0x4eab, 0x052e,
+ 0x4ead, 0x06a4,
+ 0x4eb3, 0x0832,
+ 0x4eb6, 0x2363,
+ 0x4eb7, 0x413c,
+ 0x4eb9, 0x3377,
+ 0x4eba, 0x025b,
+ 0x4ebb, 0x44e6,
+ 0x4ebc, 0x39b1,
+ 0x4ebf, 0x4590,
+ 0x4ec0, 0x02a1,
+ 0x4ec1, 0x02a0,
+ 0x4ec2, 0x177d,
+ 0x4ec3, 0x02a2,
+ 0x4ec4, 0x02a8,
+ 0x4ec6, 0x02a3,
+ 0x4ec8, 0x177f,
+ 0x4ec9, 0x177e,
+ 0x4eca, 0x02a6,
+ 0x4ecd, 0x02a5,
+ 0x4ece, 0x3f62,
+ 0x4ed4, 0x02fa,
+ 0x4ed8, 0x02f9,
+ 0x4ed9, 0x0300,
+ 0x4eda, 0x1795,
+ 0x4edc, 0x1791,
+ 0x4edd, 0x1794,
+ 0x4ede, 0x0301,
+ 0x4edf, 0x0311,
+ 0x4ee1, 0x1793,
+ 0x4ee3, 0x02fe,
+ 0x4ee5, 0x02f8,
+ 0x4ee8, 0x1790,
+ 0x4ee9, 0x1792,
+ 0x4eea, 0x48cb,
+ 0x4eeb, 0x4591,
+ 0x4eee, 0x3d76,
+ 0x4ef0, 0x0383,
+ 0x4ef1, 0x17ba,
+ 0x4ef2, 0x0380,
+ 0x4ef3, 0x0384,
+ 0x4ef4, 0x17c4,
+ 0x4ef5, 0x17b8,
+ 0x4ef6, 0x0381,
+ 0x4ef7, 0x17bc,
+ 0x4ef8, 0x39ad,
+ 0x4efb, 0x0382,
+ 0x4efd, 0x0385,
+ 0x4eff, 0x0377,
+ 0x4f00, 0x17bb,
+ 0x4f01, 0x0386,
+ 0x4f02, 0x17bf,
+ 0x4f03, 0x39c8,
+ 0x4f04, 0x17c3,
+ 0x4f05, 0x17c0,
+ 0x4f08, 0x17bd,
+ 0x4f09, 0x0378,
+ 0x4f0a, 0x037a,
+ 0x4f0b, 0x0387,
+ 0x4f0d, 0x037c,
+ 0x4f0e, 0x17b5,
+ 0x4f0f, 0x037f,
+ 0x4f10, 0x037d,
+ 0x4f12, 0x17c5,
+ 0x4f13, 0x17c2,
+ 0x4f14, 0x17b9,
+ 0x4f15, 0x037b,
+ 0x4f18, 0x17b6,
+ 0x4f19, 0x0379,
+ 0x4f1a, 0x453c,
+ 0x4f1d, 0x17be,
+ 0x4f22, 0x17c1,
+ 0x4f28, 0x453d,
+ 0x4f29, 0x39be,
+ 0x4f2c, 0x17b7,
+ 0x4f2d, 0x182f,
+ 0x4f2f, 0x042c,
+ 0x4f30, 0x041f,
+ 0x4f32, 0x393d,
+ 0x4f33, 0x1830,
+ 0x4f34, 0x041c,
+ 0x4f36, 0x042e,
+ 0x4f37, 0x4592,
+ 0x4f38, 0x0424,
+ 0x4f39, 0x3f65,
+ 0x4f3a, 0x0423,
+ 0x4f3b, 0x1824,
+ 0x4f3c, 0x0427,
+ 0x4f3d, 0x0422,
+ 0x4f3e, 0x1829,
+ 0x4f3f, 0x1831,
+ 0x4f41, 0x182d,
+ 0x4f42, 0x39cb,
+ 0x4f43, 0x0425,
+ 0x4f45, 0x3b8f,
+ 0x4f46, 0x0428,
+ 0x4f47, 0x0419,
+ 0x4f48, 0x0431,
+ 0x4f49, 0x1826,
+ 0x4f4b, 0x39b4,
+ 0x4f4c, 0x1900,
+ 0x4f4d, 0x0417,
+ 0x4f4e, 0x042d,
+ 0x4f4f, 0x0418,
+ 0x4f50, 0x0420,
+ 0x4f52, 0x182b,
+ 0x4f53, 0x1827,
+ 0x4f54, 0x0426,
+ 0x4f55, 0x041e,
+ 0x4f56, 0x1823,
+ 0x4f57, 0x041a,
+ 0x4f58, 0x182e,
+ 0x4f59, 0x042f,
+ 0x4f5a, 0x0432,
+ 0x4f5b, 0x041d,
+ 0x4f5c, 0x042a,
+ 0x4f5d, 0x0430,
+ 0x4f5e, 0x041b,
+ 0x4f5f, 0x182c,
+ 0x4f60, 0x042b,
+ 0x4f61, 0x1832,
+ 0x4f62, 0x1825,
+ 0x4f63, 0x0429,
+ 0x4f64, 0x1828,
+ 0x4f67, 0x182a,
+ 0x4f69, 0x053d,
+ 0x4f6a, 0x1902,
+ 0x4f6b, 0x190e,
+ 0x4f6c, 0x0535,
+ 0x4f6e, 0x190f,
+ 0x4f6f, 0x0530,
+ 0x4f70, 0x053a,
+ 0x4f72, 0x3c72,
+ 0x4f73, 0x0533,
+ 0x4f74, 0x18fc,
+ 0x4f75, 0x053b,
+ 0x4f76, 0x18fb,
+ 0x4f77, 0x18ff,
+ 0x4f78, 0x1906,
+ 0x4f79, 0x1904,
+ 0x4f7a, 0x0543,
+ 0x4f7b, 0x053e,
+ 0x4f7c, 0x18f6,
+ 0x4f7d, 0x18f8,
+ 0x4f7e, 0x0540,
+ 0x4f7f, 0x0534,
+ 0x4f80, 0x18f9,
+ 0x4f81, 0x1905,
+ 0x4f82, 0x190c,
+ 0x4f83, 0x0539,
+ 0x4f84, 0x18fe,
+ 0x4f85, 0x18f7,
+ 0x4f86, 0x0538,
+ 0x4f87, 0x18fa,
+ 0x4f88, 0x053c,
+ 0x4f89, 0x18fd,
+ 0x4f8a, 0x39b5,
+ 0x4f8b, 0x0537,
+ 0x4f8d, 0x0532,
+ 0x4f8f, 0x0541,
+ 0x4f90, 0x1907,
+ 0x4f91, 0x0542,
+ 0x4f92, 0x190b,
+ 0x4f94, 0x1909,
+ 0x4f95, 0x190d,
+ 0x4f96, 0x053f,
+ 0x4f97, 0x1901,
+ 0x4f98, 0x18f5,
+ 0x4f9a, 0x1903,
+ 0x4f9b, 0x0536,
+ 0x4f9c, 0x1908,
+ 0x4f9d, 0x0531,
+ 0x4f9e, 0x190a,
+ 0x4fa2, 0x39c7,
+ 0x4fa8, 0x453e,
+ 0x4fab, 0x4022,
+ 0x4fae, 0x06b4,
+ 0x4faf, 0x06a8,
+ 0x4fb0, 0x3d4a,
+ 0x4fb2, 0x1a5d,
+ 0x4fb3, 0x1a65,
+ 0x4fb5, 0x06a7,
+ 0x4fb6, 0x06af,
+ 0x4fb7, 0x06bb,
+ 0x4fb9, 0x1a6b,
+ 0x4fba, 0x1a69,
+ 0x4fbb, 0x1a64,
+ 0x4fbd, 0x4594,
+ 0x4fbf, 0x06a9,
+ 0x4fc0, 0x1a6a,
+ 0x4fc1, 0x1a60,
+ 0x4fc2, 0x06b7,
+ 0x4fc3, 0x06ae,
+ 0x4fc4, 0x06b6,
+ 0x4fc5, 0x1a5b,
+ 0x4fc7, 0x1a67,
+ 0x4fc8, 0x46e8,
+ 0x4fc9, 0x1a5e,
+ 0x4fca, 0x06b2,
+ 0x4fcb, 0x1a5f,
+ 0x4fcc, 0x39cf,
+ 0x4fcd, 0x1a5a,
+ 0x4fce, 0x06b9,
+ 0x4fcf, 0x06ac,
+ 0x4fd0, 0x06b5,
+ 0x4fd1, 0x06ab,
+ 0x4fd3, 0x1a5c,
+ 0x4fd4, 0x1a61,
+ 0x4fd6, 0x1a68,
+ 0x4fd7, 0x06b3,
+ 0x4fd8, 0x06b0,
+ 0x4fd9, 0x1a63,
+ 0x4fda, 0x06b8,
+ 0x4fdb, 0x1a66,
+ 0x4fdc, 0x1a62,
+ 0x4fdd, 0x06ad,
+ 0x4fde, 0x06ba,
+ 0x4fdf, 0x06b1,
+ 0x4fe0, 0x06aa,
+ 0x4fe1, 0x06a6,
+ 0x4fe4, 0x3c66,
+ 0x4fe5, 0x39d0,
+ 0x4fec, 0x1a6c,
+ 0x4fee, 0x084c,
+ 0x4fef, 0x0836,
+ 0x4ff1, 0x0846,
+ 0x4ff2, 0x3f28,
+ 0x4ff3, 0x084b,
+ 0x4ff4, 0x1c24,
+ 0x4ff5, 0x1c23,
+ 0x4ff6, 0x1c28,
+ 0x4ff8, 0x0839,
+ 0x4ff9, 0x37b3,
+ 0x4ffa, 0x0842,
+ 0x4ffd, 0x3f26,
+ 0x4ffe, 0x084f,
+ 0x5000, 0x0843,
+ 0x5003, 0x4596,
+ 0x5005, 0x1c1d,
+ 0x5006, 0x083c,
+ 0x5007, 0x1c1e,
+ 0x5008, 0x4024,
+ 0x5009, 0x0851,
+ 0x500b, 0x0848,
+ 0x500c, 0x0833,
+ 0x500e, 0x1c31,
+ 0x500f, 0x0a0c,
+ 0x5011, 0x0841,
+ 0x5012, 0x0840,
+ 0x5013, 0x1c1f,
+ 0x5014, 0x0844,
+ 0x5015, 0x1e45,
+ 0x5016, 0x083b,
+ 0x5017, 0x1c2a,
+ 0x5018, 0x084a,
+ 0x5019, 0x0849,
+ 0x501a, 0x083f,
+ 0x501b, 0x1c22,
+ 0x501c, 0x1c2b,
+ 0x501e, 0x1c1c,
+ 0x501f, 0x083e,
+ 0x5020, 0x1c2c,
+ 0x5021, 0x0847,
+ 0x5022, 0x1c20,
+ 0x5023, 0x0835,
+ 0x5025, 0x0838,
+ 0x5026, 0x0837,
+ 0x5027, 0x1c2d,
+ 0x5028, 0x0845,
+ 0x5029, 0x083a,
+ 0x502a, 0x084e,
+ 0x502b, 0x0850,
+ 0x502c, 0x1c27,
+ 0x502d, 0x084d,
+ 0x502e, 0x39cc,
+ 0x502f, 0x1c2f,
+ 0x5030, 0x1c21,
+ 0x5031, 0x1c30,
+ 0x5033, 0x1c25,
+ 0x5034, 0x3910,
+ 0x5035, 0x1c2e,
+ 0x5037, 0x1c26,
+ 0x503c, 0x083d,
+ 0x5040, 0x1e4d,
+ 0x5041, 0x1e41,
+ 0x5043, 0x0a00,
+ 0x5045, 0x1e46,
+ 0x5046, 0x1e4c,
+ 0x5047, 0x09ff,
+ 0x5048, 0x1e3f,
+ 0x5049, 0x0a03,
+ 0x504a, 0x1e43,
+ 0x504b, 0x1e3c,
+ 0x504c, 0x0a01,
+ 0x504d, 0x1e40,
+ 0x504e, 0x0a06,
+ 0x504f, 0x0a0b,
+ 0x5051, 0x1e51,
+ 0x5053, 0x1e3b,
+ 0x5055, 0x0a07,
+ 0x5056, 0x3f2c,
+ 0x5057, 0x1e50,
+ 0x5058, 0x39d1,
+ 0x505a, 0x0a02,
+ 0x505b, 0x1e42,
+ 0x505c, 0x09fe,
+ 0x505d, 0x1e3d,
+ 0x505e, 0x1e39,
+ 0x505f, 0x1e47,
+ 0x5060, 0x1e3a,
+ 0x5061, 0x1e38,
+ 0x5062, 0x1e44,
+ 0x5063, 0x1e4a,
+ 0x5065, 0x0a04,
+ 0x5066, 0x3dc9,
+ 0x5068, 0x20b8,
+ 0x5069, 0x1e48,
+ 0x506a, 0x1e37,
+ 0x506b, 0x1e49,
+ 0x506c, 0x39cd,
+ 0x506d, 0x0a0e,
+ 0x506e, 0x1e4e,
+ 0x506f, 0x0a0d,
+ 0x5070, 0x1e36,
+ 0x5072, 0x1e3e,
+ 0x5073, 0x1e4f,
+ 0x5074, 0x0a09,
+ 0x5075, 0x0a08,
+ 0x5076, 0x0a05,
+ 0x5077, 0x0a0a,
+ 0x507a, 0x09fc,
+ 0x507d, 0x09fd,
+ 0x5080, 0x0bec,
+ 0x5081, 0x39ce,
+ 0x5082, 0x20bb,
+ 0x5083, 0x20b4,
+ 0x5085, 0x0be9,
+ 0x5087, 0x20bc,
+ 0x5088, 0x439c,
+ 0x508b, 0x20b2,
+ 0x508c, 0x20b5,
+ 0x508d, 0x0be8,
+ 0x508e, 0x20b6,
+ 0x5090, 0x41ec,
+ 0x5091, 0x0beb,
+ 0x5092, 0x20ba,
+ 0x5094, 0x20b0,
+ 0x5095, 0x20af,
+ 0x5096, 0x0bed,
+ 0x5098, 0x0bee,
+ 0x5099, 0x0bea,
+ 0x509a, 0x0bef,
+ 0x509b, 0x20ae,
+ 0x509c, 0x20b9,
+ 0x509d, 0x20b7,
+ 0x509e, 0x20b1,
+ 0x50a2, 0x0be7,
+ 0x50a3, 0x20b3,
+ 0x50a6, 0x3f3f,
+ 0x50ac, 0x0dc5,
+ 0x50ad, 0x0dbf,
+ 0x50ae, 0x2367,
+ 0x50af, 0x0dc8,
+ 0x50b0, 0x236d,
+ 0x50b1, 0x2370,
+ 0x50b2, 0x0dc1,
+ 0x50b4, 0x236a,
+ 0x50b5, 0x0dc0,
+ 0x50b6, 0x2373,
+ 0x50b7, 0x0dc6,
+ 0x50b8, 0x2374,
+ 0x50ba, 0x236f,
+ 0x50bb, 0x0dc7,
+ 0x50bd, 0x2364,
+ 0x50be, 0x0dc4,
+ 0x50bf, 0x2365,
+ 0x50c1, 0x236e,
+ 0x50c2, 0x236c,
+ 0x50c4, 0x2368,
+ 0x50c5, 0x0dc3,
+ 0x50c6, 0x2366,
+ 0x50c7, 0x0dc9,
+ 0x50c8, 0x236b,
+ 0x50c9, 0x2372,
+ 0x50ca, 0x2369,
+ 0x50cb, 0x2371,
+ 0x50cd, 0x39c5,
+ 0x50ce, 0x0f88,
+ 0x50cf, 0x0f85,
+ 0x50d0, 0x38d1,
+ 0x50d1, 0x0f86,
+ 0x50d3, 0x261c,
+ 0x50d4, 0x2614,
+ 0x50d5, 0x0f84,
+ 0x50d6, 0x0f81,
+ 0x50d7, 0x2615,
+ 0x50d9, 0x3fce,
+ 0x50da, 0x0f83,
+ 0x50db, 0x2618,
+ 0x50dd, 0x261a,
+ 0x50de, 0x4031,
+ 0x50df, 0x3afd,
+ 0x50e0, 0x2621,
+ 0x50e1, 0x4171,
+ 0x50e3, 0x2620,
+ 0x50e4, 0x261b,
+ 0x50e5, 0x0f80,
+ 0x50e6, 0x2613,
+ 0x50e7, 0x0f7e,
+ 0x50e8, 0x2616,
+ 0x50e9, 0x0f89,
+ 0x50ea, 0x2619,
+ 0x50ec, 0x261d,
+ 0x50ed, 0x0f82,
+ 0x50ee, 0x0f7f,
+ 0x50ef, 0x261f,
+ 0x50f0, 0x261e,
+ 0x50f1, 0x0f87,
+ 0x50f3, 0x2617,
+ 0x50f4, 0x3ce9,
+ 0x50f5, 0x1105,
+ 0x50f6, 0x2883,
+ 0x50f8, 0x2880,
+ 0x50f9, 0x1106,
+ 0x50fb, 0x1104,
+ 0x50fc, 0x39d2,
+ 0x50fd, 0x2887,
+ 0x50fe, 0x2884,
+ 0x50ff, 0x287d,
+ 0x5100, 0x1103,
+ 0x5101, 0x4032,
+ 0x5102, 0x1107,
+ 0x5103, 0x287e,
+ 0x5104, 0x1102,
+ 0x5105, 0x110a,
+ 0x5106, 0x2881,
+ 0x5108, 0x1108,
+ 0x510a, 0x2888,
+ 0x510b, 0x2885,
+ 0x510d, 0x39c6,
+ 0x510e, 0x4034,
+ 0x5110, 0x128d,
+ 0x5111, 0x2b04,
+ 0x5112, 0x128a,
+ 0x5113, 0x2b01,
+ 0x5114, 0x128c,
+ 0x5115, 0x128e,
+ 0x5117, 0x2b02,
+ 0x5118, 0x128b,
+ 0x511a, 0x2b03,
+ 0x511c, 0x2b00,
+ 0x511f, 0x13b5,
+ 0x5120, 0x2d3e,
+ 0x5121, 0x13b6,
+ 0x5122, 0x2d3c,
+ 0x5124, 0x2d3d,
+ 0x5125, 0x2d3b,
+ 0x5126, 0x2d3a,
+ 0x5129, 0x2d3f,
+ 0x512a, 0x13b4,
+ 0x512b, 0x39ae,
+ 0x512d, 0x2f0f,
+ 0x5130, 0x287f,
+ 0x5131, 0x2f0e,
+ 0x5132, 0x13b7,
+ 0x5133, 0x1575,
+ 0x5134, 0x307a,
+ 0x5137, 0x1668,
+ 0x5139, 0x32c6,
+ 0x513a, 0x32c5,
+ 0x513b, 0x16bc,
+ 0x513c, 0x16bb,
+ 0x513d, 0x340e,
+ 0x513f, 0x025c,
+ 0x5140, 0x0274,
+ 0x5141, 0x02aa,
+ 0x5143, 0x02a9,
+ 0x5144, 0x0303,
+ 0x5145, 0x0302,
+ 0x5146, 0x038a,
+ 0x5147, 0x0389,
+ 0x5148, 0x038b,
+ 0x5149, 0x0388,
+ 0x514b, 0x0434,
+ 0x514c, 0x0433,
+ 0x514d, 0x0435,
+ 0x5152, 0x0545,
+ 0x5154, 0x0544,
+ 0x5155, 0x0546,
+ 0x5156, 0x439a,
+ 0x5157, 0x06bc,
+ 0x5159, 0x0119,
+ 0x515a, 0x1c32,
+ 0x515b, 0x011a,
+ 0x515c, 0x0a0f,
+ 0x515d, 0x011c,
+ 0x515e, 0x011b,
+ 0x515f, 0x20bd,
+ 0x5160, 0x403a,
+ 0x5161, 0x011d,
+ 0x5162, 0x0f8a,
+ 0x5163, 0x011e,
+ 0x5165, 0x025d,
+ 0x5167, 0x02ab,
+ 0x5168, 0x038c,
+ 0x5169, 0x0547,
+ 0x516a, 0x403c,
+ 0x516b, 0x025e,
+ 0x516c, 0x02ae,
+ 0x516d, 0x02ac,
+ 0x5171, 0x038d,
+ 0x5174, 0x453f,
+ 0x5175, 0x0436,
+ 0x5176, 0x0549,
+ 0x5177, 0x0548,
+ 0x5178, 0x054a,
+ 0x5179, 0x3ace,
+ 0x517c, 0x0852,
+ 0x5180, 0x128f,
+ 0x5182, 0x021d,
+ 0x5186, 0x439f,
+ 0x5187, 0x1779,
+ 0x5188, 0x36b6,
+ 0x5189, 0x0304,
+ 0x518d, 0x038e,
+ 0x518f, 0x1833,
+ 0x5191, 0x06be,
+ 0x5192, 0x06bd,
+ 0x5193, 0x1c34,
+ 0x5194, 0x1c33,
+ 0x5195, 0x0a10,
+ 0x5196, 0x021e,
+ 0x5197, 0x02af,
+ 0x5198, 0x1780,
+ 0x519a, 0x3ea3,
+ 0x519c, 0x4540,
+ 0x519e, 0x1910,
+ 0x51a0, 0x06bf,
+ 0x51a2, 0x0855,
+ 0x51a4, 0x0853,
+ 0x51a7, 0x3ea6,
+ 0x51a8, 0x39da,
+ 0x51aa, 0x1290,
+ 0x51ab, 0x021f,
+ 0x51ac, 0x0306,
+ 0x51b0, 0x038f,
+ 0x51b1, 0x17c6,
+ 0x51b2, 0x4048,
+ 0x51b3, 0x4051,
+ 0x51b4, 0x3d7c,
+ 0x51b5, 0x4012,
+ 0x51b6, 0x0437,
+ 0x51b8, 0x4049,
+ 0x51b9, 0x1834,
+ 0x51bc, 0x1911,
+ 0x51bd, 0x054b,
+ 0x51be, 0x1912,
+ 0x51c3, 0x39db,
+ 0x51c4, 0x1c36,
+ 0x51c6, 0x0858,
+ 0x51c7, 0x422a,
+ 0x51c8, 0x1c38,
+ 0x51c9, 0x404b,
+ 0x51ca, 0x1c35,
+ 0x51cb, 0x0859,
+ 0x51cc, 0x0857,
+ 0x51cd, 0x0856,
+ 0x51ce, 0x1c39,
+ 0x51cf, 0x404c,
+ 0x51d0, 0x1e52,
+ 0x51d1, 0x404d,
+ 0x51d2, 0x3dad,
+ 0x51d3, 0x404f,
+ 0x51d4, 0x20be,
+ 0x51d7, 0x2375,
+ 0x51d8, 0x2622,
+ 0x51db, 0x459a,
+ 0x51dc, 0x110b,
+ 0x51dd, 0x1291,
+ 0x51de, 0x2b05,
+ 0x51df, 0x424f,
+ 0x51e0, 0x025f,
+ 0x51e1, 0x026d,
+ 0x51e2, 0x4052,
+ 0x51e4, 0x4541,
+ 0x51ed, 0x4054,
+ 0x51f0, 0x0a11,
+ 0x51f1, 0x0bf1,
+ 0x51f3, 0x0f8b,
+ 0x51f4, 0x4178,
+ 0x51f5, 0x176e,
+ 0x51f6, 0x02b0,
+ 0x51f8, 0x0309,
+ 0x51f9, 0x0307,
+ 0x51fc, 0x459b,
+ 0x51fd, 0x054c,
+ 0x51fe, 0x3f0a,
+ 0x5200, 0x0260,
+ 0x5202, 0x36b3,
+ 0x5203, 0x0275,
+ 0x5205, 0x43a1,
+ 0x5206, 0x02b1,
+ 0x5209, 0x1797,
+ 0x520a, 0x030a,
+ 0x520b, 0x4059,
+ 0x520c, 0x1796,
+ 0x520e, 0x0393,
+ 0x5210, 0x17c8,
+ 0x5211, 0x0391,
+ 0x5213, 0x17c7,
+ 0x5216, 0x0394,
+ 0x5217, 0x0390,
+ 0x521c, 0x1835,
+ 0x521d, 0x068b,
+ 0x521e, 0x1836,
+ 0x521f, 0x3f60,
+ 0x5220, 0x4930,
+ 0x5221, 0x1837,
+ 0x5224, 0x043a,
+ 0x5225, 0x0439,
+ 0x5226, 0x405a,
+ 0x5227, 0x43a2,
+ 0x5228, 0x043d,
+ 0x5229, 0x043b,
+ 0x522e, 0x0552,
+ 0x5230, 0x0551,
+ 0x5231, 0x1917,
+ 0x5232, 0x1914,
+ 0x5234, 0x3efb,
+ 0x5235, 0x1913,
+ 0x5236, 0x0553,
+ 0x5237, 0x054f,
+ 0x5238, 0x054e,
+ 0x523a, 0x0550,
+ 0x523b, 0x054d,
+ 0x523c, 0x405b,
+ 0x5241, 0x0554,
+ 0x5243, 0x06c1,
+ 0x5244, 0x1a6d,
+ 0x5246, 0x1916,
+ 0x5247, 0x06c6,
+ 0x5249, 0x1a6e,
+ 0x524a, 0x06c2,
+ 0x524b, 0x06c5,
+ 0x524c, 0x06c4,
+ 0x524d, 0x06c3,
+ 0x524e, 0x06c0,
+ 0x5252, 0x1c3c,
+ 0x5254, 0x085c,
+ 0x5255, 0x1c3f,
+ 0x5256, 0x085a,
+ 0x5257, 0x405d,
+ 0x5259, 0x39e4,
+ 0x525a, 0x1c3b,
+ 0x525b, 0x085d,
+ 0x525c, 0x085b,
+ 0x525d, 0x085e,
+ 0x525e, 0x1c3d,
+ 0x5260, 0x3f29,
+ 0x5261, 0x1c3a,
+ 0x5262, 0x1c40,
+ 0x5268, 0x4619,
+ 0x5269, 0x0bf5,
+ 0x526a, 0x0a12,
+ 0x526b, 0x1e53,
+ 0x526c, 0x1e55,
+ 0x526d, 0x1e54,
+ 0x526e, 0x1e56,
+ 0x526f, 0x0a13,
+ 0x5272, 0x0bf2,
+ 0x5273, 0x3f43,
+ 0x5274, 0x0bf3,
+ 0x5277, 0x0dcb,
+ 0x5278, 0x2377,
+ 0x5279, 0x43a3,
+ 0x527a, 0x2376,
+ 0x527b, 0x2378,
+ 0x527d, 0x0dcc,
+ 0x527f, 0x0dca,
+ 0x5280, 0x2623,
+ 0x5282, 0x0f8d,
+ 0x5283, 0x0f8c,
+ 0x5284, 0x2776,
+ 0x5287, 0x110c,
+ 0x528a, 0x1110,
+ 0x528b, 0x2889,
+ 0x528d, 0x110f,
+ 0x528f, 0x3dbf,
+ 0x5290, 0x459d,
+ 0x5291, 0x1292,
+ 0x5293, 0x1293,
+ 0x5294, 0x405e,
+ 0x5296, 0x307c,
+ 0x5297, 0x32c8,
+ 0x5298, 0x32c7,
+ 0x5299, 0x340f,
+ 0x529a, 0x3f68,
+ 0x529b, 0x0262,
+ 0x529f, 0x030c,
+ 0x52a0, 0x030b,
+ 0x52a1, 0x4542,
+ 0x52a3, 0x0395,
+ 0x52a4, 0x39e5,
+ 0x52a6, 0x17c9,
+ 0x52a8, 0x4543,
+ 0x52a9, 0x043f,
+ 0x52ab, 0x043e,
+ 0x52ac, 0x0441,
+ 0x52ad, 0x1838,
+ 0x52b5, 0x405c,
+ 0x52b9, 0x405f,
+ 0x52bb, 0x0556,
+ 0x52bc, 0x1918,
+ 0x52be, 0x0555,
+ 0x52c0, 0x1a6f,
+ 0x52c1, 0x06ca,
+ 0x52c2, 0x1a70,
+ 0x52c3, 0x06c9,
+ 0x52c5, 0x4060,
+ 0x52c7, 0x06c7,
+ 0x52c9, 0x06c8,
+ 0x52cc, 0x3ee1,
+ 0x52cd, 0x1c41,
+ 0x52d0, 0x4109,
+ 0x52d1, 0x3f2a,
+ 0x52d2, 0x0a14,
+ 0x52d3, 0x1e58,
+ 0x52d5, 0x0a17,
+ 0x52d6, 0x1e57,
+ 0x52d7, 0x0acf,
+ 0x52d8, 0x0a16,
+ 0x52d9, 0x0a15,
+ 0x52db, 0x0bf8,
+ 0x52dd, 0x0bf7,
+ 0x52de, 0x0bf6,
+ 0x52df, 0x0dcd,
+ 0x52e0, 0x4063,
+ 0x52e1, 0x39e7,
+ 0x52e2, 0x0dd0,
+ 0x52e4, 0x0dcf,
+ 0x52e6, 0x0dce,
+ 0x52e9, 0x2625,
+ 0x52eb, 0x2626,
+ 0x52ef, 0x288c,
+ 0x52f0, 0x1111,
+ 0x52f1, 0x288b,
+ 0x52f3, 0x1294,
+ 0x52f4, 0x2d40,
+ 0x52f5, 0x13b8,
+ 0x52f7, 0x307d,
+ 0x52f8, 0x1609,
+ 0x52f9, 0x0220,
+ 0x52fa, 0x0276,
+ 0x52fb, 0x02b4,
+ 0x52fc, 0x1781,
+ 0x52fe, 0x02b5,
+ 0x5301, 0x3d79,
+ 0x5305, 0x030d,
+ 0x5308, 0x0396,
+ 0x5309, 0x183a,
+ 0x530a, 0x1919,
+ 0x530d, 0x06cb,
+ 0x530e, 0x1c42,
+ 0x530f, 0x0a19,
+ 0x5310, 0x0a18,
+ 0x5311, 0x20c0,
+ 0x5312, 0x20bf,
+ 0x5315, 0x0263,
+ 0x5316, 0x02b7,
+ 0x5317, 0x030f,
+ 0x5319, 0x0a1a,
+ 0x531a, 0x176f,
+ 0x531c, 0x1798,
+ 0x531d, 0x0310,
+ 0x531f, 0x17cb,
+ 0x5320, 0x0398,
+ 0x5321, 0x0397,
+ 0x5322, 0x17ca,
+ 0x5323, 0x0442,
+ 0x5327, 0x459e,
+ 0x532a, 0x085f,
+ 0x532c, 0x3f36,
+ 0x532d, 0x1e59,
+ 0x532f, 0x0dd2,
+ 0x5330, 0x2627,
+ 0x5331, 0x0f8e,
+ 0x5332, 0x3fd0,
+ 0x5333, 0x406d,
+ 0x5334, 0x2b06,
+ 0x5337, 0x31c7,
+ 0x5338, 0x0221,
+ 0x5339, 0x02b8,
+ 0x533b, 0x4544,
+ 0x533c, 0x191b,
+ 0x533d, 0x1a71,
+ 0x533e, 0x0a1d,
+ 0x533f, 0x0a1b,
+ 0x5341, 0x0264,
+ 0x5342, 0x4947,
+ 0x5343, 0x0277,
+ 0x5344, 0x016b,
+ 0x5345, 0x02bb,
+ 0x5347, 0x02ba,
+ 0x5348, 0x02b9,
+ 0x5349, 0x0313,
+ 0x534a, 0x0312,
+ 0x534c, 0x1799,
+ 0x534d, 0x17cc,
+ 0x534e, 0x4545,
+ 0x5351, 0x055a,
+ 0x5352, 0x0557,
+ 0x5353, 0x0559,
+ 0x5354, 0x0558,
+ 0x5357, 0x06cc,
+ 0x535a, 0x0bf9,
+ 0x535c, 0x0265,
+ 0x535d, 0x4501,
+ 0x535e, 0x02bc,
+ 0x535f, 0x43a7,
+ 0x5360, 0x0315,
+ 0x5361, 0x0314,
+ 0x5363, 0x183b,
+ 0x5364, 0x480a,
+ 0x5366, 0x055b,
+ 0x5367, 0x3ecd,
+ 0x5369, 0x0222,
+ 0x536c, 0x1782,
+ 0x536d, 0x407a,
+ 0x536e, 0x0317,
+ 0x536f, 0x0316,
+ 0x5370, 0x0399,
+ 0x5372, 0x183c,
+ 0x5373, 0x0443,
+ 0x5374, 0x407b,
+ 0x5375, 0x0444,
+ 0x5377, 0x055c,
+ 0x537b, 0x06cd,
+ 0x537c, 0x1a72,
+ 0x537d, 0x4901,
+ 0x537e, 0x407d,
+ 0x537f, 0x0860,
+ 0x5382, 0x1770,
+ 0x5384, 0x02bd,
+ 0x538a, 0x17cd,
+ 0x538e, 0x183d,
+ 0x5392, 0x191c,
+ 0x5393, 0x4082,
+ 0x5394, 0x191d,
+ 0x5396, 0x1a74,
+ 0x5397, 0x1a73,
+ 0x5398, 0x1a76,
+ 0x5399, 0x1a75,
+ 0x539a, 0x06ce,
+ 0x539c, 0x1e5a,
+ 0x539d, 0x0862,
+ 0x539e, 0x1c43,
+ 0x539f, 0x0861,
+ 0x53a0, 0x4084,
+ 0x53a2, 0x3e2b,
+ 0x53a4, 0x20c1,
+ 0x53a5, 0x0bfa,
+ 0x53a6, 0x413b,
+ 0x53a7, 0x20c2,
+ 0x53a8, 0x413e,
+ 0x53a9, 0x45a0,
+ 0x53aa, 0x3fc6,
+ 0x53ab, 0x4085,
+ 0x53ac, 0x2628,
+ 0x53ad, 0x0f8f,
+ 0x53ae, 0x4086,
+ 0x53b0, 0x45a2,
+ 0x53b2, 0x1112,
+ 0x53b4, 0x307e,
+ 0x53b6, 0x0223,
+ 0x53b9, 0x1783,
+ 0x53bb, 0x0318,
+ 0x53c1, 0x408b,
+ 0x53c2, 0x43a6,
+ 0x53c3, 0x0a1e,
+ 0x53c5, 0x408c,
+ 0x53c8, 0x0266,
+ 0x53c9, 0x0278,
+ 0x53ca, 0x02bf,
+ 0x53cb, 0x02be,
+ 0x53cc, 0x38b6,
+ 0x53cd, 0x02c0,
+ 0x53d0, 0x39fa,
+ 0x53d1, 0x4546,
+ 0x53d2, 0x3e3d,
+ 0x53d4, 0x0560,
+ 0x53d6, 0x055f,
+ 0x53d7, 0x0561,
+ 0x53d8, 0x4547,
+ 0x53d9, 0x4090,
+ 0x53da, 0x3f39,
+ 0x53db, 0x06cf,
+ 0x53df, 0x0863,
+ 0x53e0, 0x4093,
+ 0x53e1, 0x2b07,
+ 0x53e2, 0x14c9,
+ 0x53e3, 0x0279,
+ 0x53e4, 0x031a,
+ 0x53e5, 0x0329,
+ 0x53e6, 0x0324,
+ 0x53e8, 0x031f,
+ 0x53e9, 0x031e,
+ 0x53ea, 0x0325,
+ 0x53eb, 0x0323,
+ 0x53ec, 0x031c,
+ 0x53ed, 0x032a,
+ 0x53ee, 0x031d,
+ 0x53ef, 0x0319,
+ 0x53f0, 0x0328,
+ 0x53f1, 0x0327,
+ 0x53f2, 0x0326,
+ 0x53f3, 0x031b,
+ 0x53f5, 0x0322,
+ 0x53f6, 0x4096,
+ 0x53f7, 0x3808,
+ 0x53f8, 0x0321,
+ 0x53fb, 0x032b,
+ 0x53fc, 0x0320,
+ 0x53fe, 0x40c1,
+ 0x5401, 0x03a0,
+ 0x5403, 0x03a6,
+ 0x5404, 0x03a2,
+ 0x5406, 0x03a8,
+ 0x5407, 0x17ce,
+ 0x5408, 0x03a5,
+ 0x5409, 0x039b,
+ 0x540a, 0x039e,
+ 0x540b, 0x03a1,
+ 0x540c, 0x039d,
+ 0x540d, 0x03a4,
+ 0x540e, 0x03a7,
+ 0x540f, 0x039c,
+ 0x5410, 0x039f,
+ 0x5411, 0x03a3,
+ 0x5412, 0x03a9,
+ 0x5413, 0x4098,
+ 0x5414, 0x3c77,
+ 0x5416, 0x3e7f,
+ 0x5418, 0x1847,
+ 0x5419, 0x1844,
+ 0x541a, 0x3e64,
+ 0x541b, 0x0451,
+ 0x541c, 0x1845,
+ 0x541d, 0x0445,
+ 0x541e, 0x0447,
+ 0x541f, 0x045f,
+ 0x5420, 0x045a,
+ 0x5421, 0x4203,
+ 0x5423, 0x45a3,
+ 0x5424, 0x184c,
+ 0x5425, 0x1846,
+ 0x5426, 0x0449,
+ 0x5427, 0x044b,
+ 0x5428, 0x184b,
+ 0x5429, 0x0452,
+ 0x542a, 0x1841,
+ 0x542b, 0x045e,
+ 0x542c, 0x0460,
+ 0x542d, 0x0446,
+ 0x542e, 0x0457,
+ 0x542f, 0x40ac,
+ 0x5430, 0x183f,
+ 0x5431, 0x045d,
+ 0x5432, 0x3e75,
+ 0x5433, 0x044e,
+ 0x5435, 0x0458,
+ 0x5437, 0x1840,
+ 0x5438, 0x0456,
+ 0x5439, 0x0454,
+ 0x543b, 0x0455,
+ 0x543c, 0x045b,
+ 0x543d, 0x1848,
+ 0x543e, 0x0448,
+ 0x5440, 0x045c,
+ 0x5441, 0x184a,
+ 0x5442, 0x0450,
+ 0x5443, 0x044d,
+ 0x5445, 0x1843,
+ 0x5446, 0x044c,
+ 0x5447, 0x184d,
+ 0x5448, 0x044f,
+ 0x544a, 0x0453,
+ 0x544b, 0x3ed1,
+ 0x544d, 0x3ea7,
+ 0x544e, 0x044a,
+ 0x544f, 0x1849,
+ 0x5454, 0x1842,
+ 0x5460, 0x192e,
+ 0x5461, 0x192d,
+ 0x5462, 0x0573,
+ 0x5463, 0x1930,
+ 0x5464, 0x1932,
+ 0x5465, 0x1927,
+ 0x5466, 0x192a,
+ 0x5467, 0x1931,
+ 0x5468, 0x0574,
+ 0x5469, 0x3f32,
+ 0x546a, 0x3d83,
+ 0x546b, 0x1924,
+ 0x546c, 0x1928,
+ 0x546d, 0x409d,
+ 0x546f, 0x192c,
+ 0x5470, 0x1a85,
+ 0x5471, 0x056f,
+ 0x5472, 0x1a89,
+ 0x5473, 0x0562,
+ 0x5474, 0x1929,
+ 0x5475, 0x0563,
+ 0x5476, 0x0570,
+ 0x5477, 0x0569,
+ 0x5478, 0x0565,
+ 0x547a, 0x1925,
+ 0x547b, 0x0568,
+ 0x547c, 0x056d,
+ 0x547d, 0x0576,
+ 0x547e, 0x1926,
+ 0x547f, 0x191f,
+ 0x5480, 0x0567,
+ 0x5481, 0x1920,
+ 0x5482, 0x1922,
+ 0x5484, 0x056a,
+ 0x5485, 0x46d9,
+ 0x5486, 0x056c,
+ 0x5487, 0x191e,
+ 0x5488, 0x1923,
+ 0x548b, 0x0575,
+ 0x548c, 0x0571,
+ 0x548d, 0x192b,
+ 0x548e, 0x0577,
+ 0x548f, 0x40a1,
+ 0x5490, 0x056e,
+ 0x5491, 0x1921,
+ 0x5492, 0x056b,
+ 0x5493, 0x45a7,
+ 0x5494, 0x3e98,
+ 0x5495, 0x0566,
+ 0x5496, 0x0564,
+ 0x5497, 0x3e8a,
+ 0x5498, 0x192f,
+ 0x549a, 0x0572,
+ 0x549c, 0x3f66,
+ 0x549e, 0x47ed,
+ 0x54a0, 0x1a84,
+ 0x54a1, 0x1a78,
+ 0x54a2, 0x1a87,
+ 0x54a3, 0x45a8,
+ 0x54a4, 0x40a2,
+ 0x54a5, 0x1a7a,
+ 0x54a6, 0x06d6,
+ 0x54a7, 0x06e4,
+ 0x54a8, 0x06d2,
+ 0x54a9, 0x06e3,
+ 0x54aa, 0x06db,
+ 0x54ab, 0x06e0,
+ 0x54ac, 0x06d0,
+ 0x54ad, 0x1a79,
+ 0x54ae, 0x1a7f,
+ 0x54af, 0x06df,
+ 0x54b0, 0x1a8b,
+ 0x54b1, 0x06e1,
+ 0x54b2, 0x3744,
+ 0x54b3, 0x06d7,
+ 0x54b4, 0x45a9,
+ 0x54b6, 0x1a81,
+ 0x54b7, 0x1a7e,
+ 0x54b8, 0x06d5,
+ 0x54b9, 0x45aa,
+ 0x54ba, 0x1a77,
+ 0x54bb, 0x06e2,
+ 0x54bc, 0x1a86,
+ 0x54bd, 0x06da,
+ 0x54be, 0x1a88,
+ 0x54bf, 0x06e5,
+ 0x54c0, 0x06d1,
+ 0x54c1, 0x06dc,
+ 0x54c2, 0x06d9,
+ 0x54c3, 0x1a7c,
+ 0x54c4, 0x06dd,
+ 0x54c5, 0x1a82,
+ 0x54c7, 0x06d8,
+ 0x54c8, 0x06de,
+ 0x54c9, 0x06d4,
+ 0x54cb, 0x39a3,
+ 0x54cc, 0x43a8,
+ 0x54cd, 0x3a00,
+ 0x54ce, 0x06d3,
+ 0x54cf, 0x1a7b,
+ 0x54d0, 0x45ab,
+ 0x54d6, 0x1a80,
+ 0x54da, 0x4923,
+ 0x54de, 0x1a8a,
+ 0x54e0, 0x1c57,
+ 0x54e1, 0x0870,
+ 0x54e2, 0x1c45,
+ 0x54e3, 0x4341,
+ 0x54e4, 0x1c4a,
+ 0x54e5, 0x0869,
+ 0x54e6, 0x0874,
+ 0x54e7, 0x1c48,
+ 0x54e8, 0x0864,
+ 0x54e9, 0x086e,
+ 0x54ea, 0x0873,
+ 0x54eb, 0x1c4f,
+ 0x54ed, 0x086f,
+ 0x54ee, 0x0872,
+ 0x54ef, 0x45ac,
+ 0x54f1, 0x1c52,
+ 0x54f2, 0x086a,
+ 0x54f3, 0x1c49,
+ 0x54f7, 0x1c55,
+ 0x54fa, 0x086c,
+ 0x54fb, 0x1c54,
+ 0x54fc, 0x0868,
+ 0x54fd, 0x0877,
+ 0x54ff, 0x1c4c,
+ 0x5501, 0x0866,
+ 0x5502, 0x3ccc,
+ 0x5503, 0x1c59,
+ 0x5504, 0x1c4d,
+ 0x5505, 0x1c51,
+ 0x5506, 0x086b,
+ 0x5507, 0x0876,
+ 0x5508, 0x1c4e,
+ 0x5509, 0x0871,
+ 0x550a, 0x1c53,
+ 0x550b, 0x1c5a,
+ 0x550c, 0x1e69,
+ 0x550d, 0x3a73,
+ 0x550e, 0x1c58,
+ 0x550f, 0x0878,
+ 0x5510, 0x0865,
+ 0x5511, 0x1c50,
+ 0x5512, 0x1c47,
+ 0x5513, 0x3ea9,
+ 0x5514, 0x086d,
+ 0x5517, 0x1c46,
+ 0x5518, 0x45ad,
+ 0x551a, 0x1c4b,
+ 0x551e, 0x3ea8,
+ 0x5523, 0x45ae,
+ 0x5525, 0x4309,
+ 0x5526, 0x1c44,
+ 0x5527, 0x0875,
+ 0x5528, 0x45af,
+ 0x552a, 0x1e61,
+ 0x552b, 0x409a,
+ 0x552c, 0x0a31,
+ 0x552d, 0x1e6f,
+ 0x552e, 0x0a2f,
+ 0x552f, 0x0a2c,
+ 0x5530, 0x1e66,
+ 0x5531, 0x0a28,
+ 0x5532, 0x1e6a,
+ 0x5533, 0x0a33,
+ 0x5534, 0x1e60,
+ 0x5535, 0x1e65,
+ 0x5536, 0x1e64,
+ 0x5537, 0x0867,
+ 0x5538, 0x0a2e,
+ 0x5539, 0x1e6d,
+ 0x553b, 0x1e70,
+ 0x553c, 0x1e5d,
+ 0x553e, 0x0c0c,
+ 0x553f, 0x43a9,
+ 0x5540, 0x1e71,
+ 0x5541, 0x0a34,
+ 0x5543, 0x0a26,
+ 0x5544, 0x0a23,
+ 0x5545, 0x1e68,
+ 0x5546, 0x0a20,
+ 0x5547, 0x40aa,
+ 0x5548, 0x1e6e,
+ 0x5549, 0x4068,
+ 0x554a, 0x0a27,
+ 0x554b, 0x1e72,
+ 0x554d, 0x1e5e,
+ 0x554e, 0x1e6c,
+ 0x554f, 0x0a2a,
+ 0x5550, 0x1e5f,
+ 0x5551, 0x1e62,
+ 0x5552, 0x1e67,
+ 0x5553, 0x43ae,
+ 0x5555, 0x0a2b,
+ 0x5556, 0x0a29,
+ 0x5557, 0x0a35,
+ 0x555c, 0x0a30,
+ 0x555d, 0x40a0,
+ 0x555e, 0x0a24,
+ 0x555f, 0x0abc,
+ 0x5561, 0x0a25,
+ 0x5562, 0x1e63,
+ 0x5563, 0x0a32,
+ 0x5564, 0x0a2d,
+ 0x5565, 0x1e6b,
+ 0x5566, 0x0a22,
+ 0x5569, 0x3e9f,
+ 0x556a, 0x0a21,
+ 0x556b, 0x3b2e,
+ 0x5571, 0x3bc6,
+ 0x5572, 0x3e8b,
+ 0x5573, 0x3f24,
+ 0x5575, 0x1e5b,
+ 0x5577, 0x20c7,
+ 0x5579, 0x435d,
+ 0x557b, 0x0bfb,
+ 0x557c, 0x0bfe,
+ 0x557d, 0x20d2,
+ 0x557e, 0x0c12,
+ 0x557f, 0x20d5,
+ 0x5580, 0x0bfc,
+ 0x5581, 0x20ce,
+ 0x5582, 0x0c02,
+ 0x5583, 0x0c08,
+ 0x5584, 0x0d1b,
+ 0x5586, 0x40ae,
+ 0x5587, 0x0c06,
+ 0x5588, 0x20cb,
+ 0x5589, 0x0c13,
+ 0x558a, 0x0bff,
+ 0x558b, 0x0c07,
+ 0x558c, 0x20d3,
+ 0x558d, 0x2387,
+ 0x558e, 0x20d8,
+ 0x558f, 0x20cc,
+ 0x5590, 0x430e,
+ 0x5591, 0x20c3,
+ 0x5592, 0x20d0,
+ 0x5593, 0x20ca,
+ 0x5594, 0x0c05,
+ 0x5595, 0x20d6,
+ 0x5598, 0x0c01,
+ 0x5599, 0x0c15,
+ 0x559a, 0x0c0e,
+ 0x559c, 0x0c03,
+ 0x559d, 0x0c00,
+ 0x559f, 0x0c0b,
+ 0x55a1, 0x20d7,
+ 0x55a2, 0x20c9,
+ 0x55a3, 0x20cf,
+ 0x55a4, 0x20d1,
+ 0x55a5, 0x20c5,
+ 0x55a6, 0x20d4,
+ 0x55a7, 0x0bfd,
+ 0x55a8, 0x20c4,
+ 0x55a9, 0x40af,
+ 0x55aa, 0x0c04,
+ 0x55ab, 0x0c14,
+ 0x55ac, 0x0c10,
+ 0x55ad, 0x20c6,
+ 0x55ae, 0x0c0a,
+ 0x55b0, 0x38f5,
+ 0x55b1, 0x0c11,
+ 0x55b2, 0x0c0d,
+ 0x55b3, 0x0c09,
+ 0x55b4, 0x39fe,
+ 0x55b5, 0x20cd,
+ 0x55b9, 0x43aa,
+ 0x55ba, 0x3e89,
+ 0x55bb, 0x0c0f,
+ 0x55bc, 0x3dc3,
+ 0x55bf, 0x2385,
+ 0x55c0, 0x2381,
+ 0x55c1, 0x3e4f,
+ 0x55c2, 0x2390,
+ 0x55c3, 0x237a,
+ 0x55c4, 0x2383,
+ 0x55c5, 0x0de0,
+ 0x55c7, 0x0dd9,
+ 0x55c8, 0x238c,
+ 0x55c9, 0x0de3,
+ 0x55ca, 0x237f,
+ 0x55cb, 0x237e,
+ 0x55cc, 0x237c,
+ 0x55cd, 0x238e,
+ 0x55ce, 0x0dd7,
+ 0x55cf, 0x2388,
+ 0x55d0, 0x237d,
+ 0x55d1, 0x0dda,
+ 0x55d2, 0x2386,
+ 0x55d3, 0x0dd5,
+ 0x55d4, 0x2382,
+ 0x55d5, 0x2389,
+ 0x55d6, 0x238b,
+ 0x55d7, 0x45b3,
+ 0x55d8, 0x43ab,
+ 0x55d9, 0x238f,
+ 0x55da, 0x0dde,
+ 0x55db, 0x237b,
+ 0x55dc, 0x0dd8,
+ 0x55dd, 0x2380,
+ 0x55de, 0x3e94,
+ 0x55df, 0x0dd3,
+ 0x55e1, 0x0ddf,
+ 0x55e2, 0x238a,
+ 0x55e3, 0x0ddb,
+ 0x55e5, 0x0de2,
+ 0x55e6, 0x0dd6,
+ 0x55e7, 0x011f,
+ 0x55e8, 0x0dd4,
+ 0x55e9, 0x2384,
+ 0x55ea, 0x3e7c,
+ 0x55ec, 0x37d2,
+ 0x55ef, 0x0ddd,
+ 0x55f0, 0x3e88,
+ 0x55f1, 0x3e83,
+ 0x55f2, 0x238d,
+ 0x55f5, 0x4786,
+ 0x55f6, 0x0f9f,
+ 0x55f7, 0x0f9a,
+ 0x55f9, 0x2637,
+ 0x55fa, 0x2633,
+ 0x55fb, 0x4626,
+ 0x55fc, 0x262d,
+ 0x55fd, 0x0f94,
+ 0x55fe, 0x0f90,
+ 0x55ff, 0x2636,
+ 0x5600, 0x0f91,
+ 0x5601, 0x2630,
+ 0x5602, 0x2632,
+ 0x5604, 0x2635,
+ 0x5605, 0x3e82,
+ 0x5606, 0x0f96,
+ 0x5608, 0x0f9d,
+ 0x5609, 0x0f97,
+ 0x560c, 0x262b,
+ 0x560d, 0x0f98,
+ 0x560f, 0x262e,
+ 0x5610, 0x0f9e,
+ 0x5611, 0x3f4d,
+ 0x5612, 0x262c,
+ 0x5613, 0x2631,
+ 0x5614, 0x0f95,
+ 0x5615, 0x262a,
+ 0x5616, 0x0f9b,
+ 0x5617, 0x0f93,
+ 0x561b, 0x0f92,
+ 0x561c, 0x262f,
+ 0x561d, 0x2634,
+ 0x561e, 0x3e68,
+ 0x561f, 0x0f9c,
+ 0x5620, 0x3f7d,
+ 0x5621, 0x43ad,
+ 0x5622, 0x3e67,
+ 0x5623, 0x4707,
+ 0x5625, 0x3e78,
+ 0x5627, 0x2629,
+ 0x5629, 0x1119,
+ 0x562a, 0x289d,
+ 0x562c, 0x289a,
+ 0x562d, 0x3e63,
+ 0x562e, 0x1113,
+ 0x562f, 0x111f,
+ 0x5632, 0x1116,
+ 0x5633, 0x2898,
+ 0x5634, 0x1118,
+ 0x5635, 0x2890,
+ 0x5636, 0x111e,
+ 0x5637, 0x40b7,
+ 0x5638, 0x289c,
+ 0x5639, 0x1115,
+ 0x563a, 0x289e,
+ 0x563b, 0x1114,
+ 0x563d, 0x2899,
+ 0x563e, 0x289b,
+ 0x563f, 0x1117,
+ 0x5640, 0x2897,
+ 0x5641, 0x2891,
+ 0x5642, 0x288e,
+ 0x5643, 0x3e7e,
+ 0x5645, 0x20c8,
+ 0x5646, 0x2894,
+ 0x5648, 0x288d,
+ 0x5649, 0x2893,
+ 0x564a, 0x2892,
+ 0x564c, 0x288f,
+ 0x564d, 0x40bc,
+ 0x564e, 0x111b,
+ 0x564f, 0x40bd,
+ 0x5650, 0x47cf,
+ 0x5652, 0x45c2,
+ 0x5653, 0x111a,
+ 0x5654, 0x43af,
+ 0x5657, 0x111c,
+ 0x5658, 0x2895,
+ 0x5659, 0x1295,
+ 0x565a, 0x2896,
+ 0x565d, 0x3ef9,
+ 0x565e, 0x2b10,
+ 0x5660, 0x2b09,
+ 0x5661, 0x3812,
+ 0x5662, 0x12a1,
+ 0x5663, 0x2b0d,
+ 0x5664, 0x1299,
+ 0x5665, 0x129d,
+ 0x5666, 0x2b0c,
+ 0x5668, 0x129c,
+ 0x5669, 0x1298,
+ 0x566a, 0x129b,
+ 0x566b, 0x1296,
+ 0x566c, 0x12a0,
+ 0x566d, 0x2b0e,
+ 0x566e, 0x2b0a,
+ 0x566f, 0x129f,
+ 0x5670, 0x2b08,
+ 0x5671, 0x129e,
+ 0x5672, 0x2b0f,
+ 0x5673, 0x2b0b,
+ 0x5674, 0x111d,
+ 0x5676, 0x12a2,
+ 0x5677, 0x2b11,
+ 0x5678, 0x129a,
+ 0x5679, 0x1297,
+ 0x567a, 0x3d85,
+ 0x567b, 0x3eb7,
+ 0x567c, 0x3eed,
+ 0x567e, 0x2d47,
+ 0x567f, 0x2d49,
+ 0x5680, 0x13ba,
+ 0x5681, 0x2d4a,
+ 0x5682, 0x2d48,
+ 0x5683, 0x2d46,
+ 0x5684, 0x2d45,
+ 0x5685, 0x13bc,
+ 0x5686, 0x2d44,
+ 0x5687, 0x13bd,
+ 0x5689, 0x4628,
+ 0x568a, 0x3949,
+ 0x568b, 0x3e4c,
+ 0x568c, 0x2d42,
+ 0x568e, 0x13b9,
+ 0x568f, 0x13be,
+ 0x5690, 0x13bb,
+ 0x5692, 0x39a6,
+ 0x5693, 0x2d41,
+ 0x5695, 0x14ca,
+ 0x5697, 0x2f13,
+ 0x5698, 0x2f11,
+ 0x5699, 0x2f16,
+ 0x569a, 0x2f14,
+ 0x569c, 0x2f12,
+ 0x569d, 0x2f15,
+ 0x569e, 0x39a4,
+ 0x569f, 0x3948,
+ 0x56a1, 0x436b,
+ 0x56a4, 0x3cc8,
+ 0x56a5, 0x1576,
+ 0x56a6, 0x3081,
+ 0x56a8, 0x1577,
+ 0x56aa, 0x3083,
+ 0x56ab, 0x307f,
+ 0x56ac, 0x3084,
+ 0x56ad, 0x3080,
+ 0x56ae, 0x14cb,
+ 0x56af, 0x45f7,
+ 0x56b1, 0x463f,
+ 0x56b2, 0x31c8,
+ 0x56b3, 0x31ca,
+ 0x56b4, 0x160c,
+ 0x56b5, 0x31c9,
+ 0x56b6, 0x160b,
+ 0x56b7, 0x160a,
+ 0x56b9, 0x486f,
+ 0x56bc, 0x160d,
+ 0x56bd, 0x32ca,
+ 0x56bf, 0x3e5d,
+ 0x56c0, 0x166b,
+ 0x56c1, 0x166a,
+ 0x56c2, 0x166c,
+ 0x56c3, 0x32c9,
+ 0x56c5, 0x3379,
+ 0x56c6, 0x3378,
+ 0x56c8, 0x16bd,
+ 0x56c9, 0x16bf,
+ 0x56ca, 0x16be,
+ 0x56cb, 0x337a,
+ 0x56cc, 0x16f6,
+ 0x56cd, 0x3481,
+ 0x56d1, 0x171f,
+ 0x56d3, 0x3480,
+ 0x56d4, 0x34c9,
+ 0x56d6, 0x488a,
+ 0x56d7, 0x1775,
+ 0x56da, 0x032d,
+ 0x56db, 0x032c,
+ 0x56dd, 0x03ac,
+ 0x56de, 0x03ab,
+ 0x56df, 0x17d0,
+ 0x56e0, 0x03aa,
+ 0x56e1, 0x17cf,
+ 0x56e2, 0x4548,
+ 0x56e4, 0x0463,
+ 0x56e5, 0x1850,
+ 0x56e7, 0x184f,
+ 0x56ea, 0x0461,
+ 0x56eb, 0x0464,
+ 0x56ed, 0x40c4,
+ 0x56ee, 0x184e,
+ 0x56ef, 0x40c3,
+ 0x56f0, 0x0462,
+ 0x56f1, 0x40bf,
+ 0x56f7, 0x1933,
+ 0x56f9, 0x1934,
+ 0x56fa, 0x0578,
+ 0x56fd, 0x3d64,
+ 0x56ff, 0x06e6,
+ 0x5700, 0x40c2,
+ 0x5701, 0x1c5b,
+ 0x5703, 0x0879,
+ 0x5707, 0x1e74,
+ 0x5708, 0x0a36,
+ 0x5709, 0x0a38,
+ 0x570a, 0x1e73,
+ 0x570b, 0x0a37,
+ 0x570c, 0x20d9,
+ 0x570d, 0x0c16,
+ 0x5712, 0x0de4,
+ 0x5714, 0x2391,
+ 0x5715, 0x3e36,
+ 0x5716, 0x0fa1,
+ 0x5718, 0x0fa0,
+ 0x571a, 0x289f,
+ 0x571b, 0x2b13,
+ 0x571c, 0x2b12,
+ 0x571d, 0x3a02,
+ 0x571e, 0x3505,
+ 0x571f, 0x027a,
+ 0x5720, 0x1784,
+ 0x5722, 0x179a,
+ 0x5728, 0x03af,
+ 0x5729, 0x03b3,
+ 0x572a, 0x17d2,
+ 0x572c, 0x03b1,
+ 0x572d, 0x03b0,
+ 0x572e, 0x17d1,
+ 0x572f, 0x03b2,
+ 0x5730, 0x03ae,
+ 0x5732, 0x3af9,
+ 0x5733, 0x03ad,
+ 0x5734, 0x17d3,
+ 0x573b, 0x046e,
+ 0x573e, 0x046b,
+ 0x573f, 0x4855,
+ 0x5740, 0x0467,
+ 0x5741, 0x1851,
+ 0x5742, 0x40cc,
+ 0x5743, 0x40de,
+ 0x5745, 0x1852,
+ 0x5746, 0x40c8,
+ 0x5747, 0x0469,
+ 0x5749, 0x1854,
+ 0x574a, 0x0465,
+ 0x574b, 0x1855,
+ 0x574c, 0x1853,
+ 0x574d, 0x0468,
+ 0x574e, 0x046a,
+ 0x574f, 0x046d,
+ 0x5750, 0x046c,
+ 0x5751, 0x0466,
+ 0x5752, 0x1856,
+ 0x5754, 0x4785,
+ 0x5757, 0x47e6,
+ 0x575b, 0x3982,
+ 0x575f, 0x3fbf,
+ 0x5761, 0x057d,
+ 0x5762, 0x1941,
+ 0x5764, 0x057f,
+ 0x5766, 0x057e,
+ 0x5767, 0x3f2b,
+ 0x5768, 0x1942,
+ 0x5769, 0x057c,
+ 0x576a, 0x057b,
+ 0x576b, 0x1938,
+ 0x576d, 0x1937,
+ 0x576f, 0x1935,
+ 0x5770, 0x193a,
+ 0x5771, 0x1939,
+ 0x5772, 0x1936,
+ 0x5773, 0x193f,
+ 0x5775, 0x193d,
+ 0x5776, 0x193b,
+ 0x5777, 0x057a,
+ 0x577a, 0x3f5f,
+ 0x577b, 0x193e,
+ 0x577c, 0x0580,
+ 0x577d, 0x1943,
+ 0x577e, 0x46dc,
+ 0x577f, 0x3a07,
+ 0x5780, 0x193c,
+ 0x5782, 0x06e7,
+ 0x5783, 0x0579,
+ 0x5788, 0x484b,
+ 0x578a, 0x3c7b,
+ 0x578b, 0x06e8,
+ 0x578c, 0x1a90,
+ 0x578d, 0x3a06,
+ 0x578f, 0x1a96,
+ 0x5790, 0x4166,
+ 0x5793, 0x06ee,
+ 0x5794, 0x1a94,
+ 0x5795, 0x1a9a,
+ 0x5797, 0x1a91,
+ 0x5798, 0x1a95,
+ 0x5799, 0x1a97,
+ 0x579a, 0x1a99,
+ 0x579b, 0x1a93,
+ 0x579c, 0x4608,
+ 0x579d, 0x1a92,
+ 0x579e, 0x1a8d,
+ 0x57a0, 0x06e9,
+ 0x57a1, 0x4864,
+ 0x57a2, 0x06eb,
+ 0x57a3, 0x06ea,
+ 0x57a4, 0x1a8f,
+ 0x57a5, 0x1a98,
+ 0x57a7, 0x4914,
+ 0x57aa, 0x4905,
+ 0x57ae, 0x06ed,
+ 0x57b4, 0x4741,
+ 0x57b5, 0x1a8c,
+ 0x57b6, 0x1c66,
+ 0x57b8, 0x1c65,
+ 0x57b9, 0x1c6a,
+ 0x57ba, 0x1c61,
+ 0x57bb, 0x3c79,
+ 0x57bc, 0x1c64,
+ 0x57bd, 0x1c63,
+ 0x57be, 0x372c,
+ 0x57bf, 0x1c67,
+ 0x57c1, 0x1c6b,
+ 0x57c2, 0x087b,
+ 0x57c3, 0x087e,
+ 0x57c4, 0x3b5b,
+ 0x57c6, 0x1c62,
+ 0x57c7, 0x1c68,
+ 0x57c8, 0x3d0b,
+ 0x57cb, 0x087d,
+ 0x57cc, 0x1c5d,
+ 0x57ce, 0x06ec,
+ 0x57cf, 0x1e82,
+ 0x57d0, 0x1c69,
+ 0x57d2, 0x1c60,
+ 0x57d4, 0x087c,
+ 0x57d5, 0x1c5f,
+ 0x57d7, 0x3c7d,
+ 0x57dc, 0x1e79,
+ 0x57dd, 0x3a05,
+ 0x57de, 0x3f01,
+ 0x57df, 0x0a39,
+ 0x57e0, 0x0a3d,
+ 0x57e1, 0x1e89,
+ 0x57e2, 0x1e77,
+ 0x57e3, 0x1e85,
+ 0x57e4, 0x0a3e,
+ 0x57e5, 0x1e87,
+ 0x57e6, 0x40cf,
+ 0x57e7, 0x1e8d,
+ 0x57e9, 0x1e91,
+ 0x57ec, 0x1e88,
+ 0x57ed, 0x1e7c,
+ 0x57ee, 0x1e84,
+ 0x57ef, 0x4754,
+ 0x57f0, 0x1e92,
+ 0x57f1, 0x1e90,
+ 0x57f2, 0x1e86,
+ 0x57f3, 0x1e81,
+ 0x57f4, 0x1e7a,
+ 0x57f5, 0x20e1,
+ 0x57f6, 0x1e78,
+ 0x57f7, 0x0a42,
+ 0x57f8, 0x1e7f,
+ 0x57f9, 0x0a43,
+ 0x57fa, 0x0a3f,
+ 0x57fb, 0x1e75,
+ 0x57fc, 0x1e8b,
+ 0x57fd, 0x1e7d,
+ 0x57fe, 0x408f,
+ 0x5800, 0x1e7b,
+ 0x5801, 0x1e8e,
+ 0x5802, 0x0a40,
+ 0x5803, 0x40d1,
+ 0x5804, 0x1e94,
+ 0x5805, 0x0a3a,
+ 0x5806, 0x0a3c,
+ 0x5807, 0x1e83,
+ 0x5808, 0x1e7e,
+ 0x5809, 0x087f,
+ 0x580a, 0x0a3b,
+ 0x580b, 0x1e80,
+ 0x580c, 0x1e8f,
+ 0x580d, 0x1e93,
+ 0x580e, 0x1e8a,
+ 0x5810, 0x1e8c,
+ 0x5812, 0x3d0a,
+ 0x5814, 0x1e76,
+ 0x5819, 0x20dc,
+ 0x581b, 0x20e5,
+ 0x581c, 0x20e4,
+ 0x581d, 0x0c1e,
+ 0x581e, 0x20dd,
+ 0x5820, 0x0c1f,
+ 0x5821, 0x0c1d,
+ 0x5822, 0x3c28,
+ 0x5823, 0x20df,
+ 0x5824, 0x0c1a,
+ 0x5825, 0x20e3,
+ 0x5826, 0x40d4,
+ 0x5827, 0x20de,
+ 0x5828, 0x20e0,
+ 0x5829, 0x20da,
+ 0x582a, 0x0c18,
+ 0x582c, 0x20ed,
+ 0x582d, 0x20ec,
+ 0x582e, 0x20e9,
+ 0x582f, 0x0c17,
+ 0x5830, 0x0c1b,
+ 0x5832, 0x1c5e,
+ 0x5833, 0x20e6,
+ 0x5834, 0x0c19,
+ 0x5835, 0x0a41,
+ 0x5836, 0x20e8,
+ 0x5837, 0x20db,
+ 0x5838, 0x20eb,
+ 0x5839, 0x20ea,
+ 0x583a, 0x3d72,
+ 0x583b, 0x20ee,
+ 0x583d, 0x239f,
+ 0x583f, 0x20e7,
+ 0x5840, 0x3d82,
+ 0x5844, 0x47bb,
+ 0x5847, 0x3ac2,
+ 0x5848, 0x20e2,
+ 0x5849, 0x2397,
+ 0x584a, 0x0def,
+ 0x584b, 0x0df2,
+ 0x584c, 0x0ded,
+ 0x584d, 0x2396,
+ 0x584e, 0x239a,
+ 0x584f, 0x2395,
+ 0x5851, 0x0de7,
+ 0x5852, 0x0df1,
+ 0x5853, 0x2392,
+ 0x5854, 0x0deb,
+ 0x5855, 0x2399,
+ 0x5857, 0x0de9,
+ 0x5858, 0x0de8,
+ 0x5859, 0x239c,
+ 0x585a, 0x0dea,
+ 0x585b, 0x239e,
+ 0x585c, 0x4949,
+ 0x585d, 0x239b,
+ 0x585e, 0x0de6,
+ 0x585f, 0x43df,
+ 0x5862, 0x0df0,
+ 0x5863, 0x23a0,
+ 0x5864, 0x2394,
+ 0x5865, 0x239d,
+ 0x5868, 0x2393,
+ 0x5869, 0x3d65,
+ 0x586b, 0x0dec,
+ 0x586c, 0x399a,
+ 0x586d, 0x0dee,
+ 0x586f, 0x2398,
+ 0x5871, 0x23a1,
+ 0x5872, 0x3c26,
+ 0x5873, 0x4355,
+ 0x5874, 0x263f,
+ 0x5875, 0x0fa2,
+ 0x5876, 0x2645,
+ 0x5879, 0x0fa7,
+ 0x587a, 0x2641,
+ 0x587b, 0x2648,
+ 0x587c, 0x2639,
+ 0x587d, 0x0fa9,
+ 0x587e, 0x0fa3,
+ 0x587f, 0x263e,
+ 0x5880, 0x1121,
+ 0x5881, 0x263d,
+ 0x5882, 0x2646,
+ 0x5883, 0x0fa4,
+ 0x5885, 0x0fa8,
+ 0x5886, 0x263c,
+ 0x5887, 0x2642,
+ 0x5888, 0x2647,
+ 0x5889, 0x2638,
+ 0x588a, 0x0fa6,
+ 0x588b, 0x2640,
+ 0x588e, 0x2644,
+ 0x588f, 0x264a,
+ 0x5890, 0x263a,
+ 0x5891, 0x2643,
+ 0x5893, 0x0fa5,
+ 0x5894, 0x2649,
+ 0x5898, 0x263b,
+ 0x5899, 0x4618,
+ 0x589a, 0x4903,
+ 0x589c, 0x1125,
+ 0x589d, 0x28a1,
+ 0x589e, 0x1123,
+ 0x589f, 0x1122,
+ 0x58a0, 0x28a3,
+ 0x58a1, 0x28a8,
+ 0x58a3, 0x28a4,
+ 0x58a5, 0x28a7,
+ 0x58a6, 0x1128,
+ 0x58a7, 0x3eeb,
+ 0x58a8, 0x1288,
+ 0x58a9, 0x1127,
+ 0x58aa, 0x40d7,
+ 0x58ab, 0x28a0,
+ 0x58ac, 0x28a6,
+ 0x58ae, 0x1126,
+ 0x58af, 0x28a5,
+ 0x58b0, 0x37a4,
+ 0x58b1, 0x28a2,
+ 0x58b3, 0x1124,
+ 0x58b5, 0x4840,
+ 0x58b6, 0x3dfd,
+ 0x58ba, 0x2b18,
+ 0x58bb, 0x36eb,
+ 0x58bc, 0x2b1a,
+ 0x58bd, 0x2b15,
+ 0x58be, 0x12a4,
+ 0x58bf, 0x2b17,
+ 0x58c1, 0x12a3,
+ 0x58c2, 0x2b19,
+ 0x58c5, 0x12a6,
+ 0x58c6, 0x2b1b,
+ 0x58c7, 0x12a5,
+ 0x58c8, 0x2b14,
+ 0x58c9, 0x2b16,
+ 0x58cb, 0x3a09,
+ 0x58ce, 0x13c2,
+ 0x58cf, 0x2d4d,
+ 0x58d1, 0x13c1,
+ 0x58d2, 0x2d4e,
+ 0x58d3, 0x13c0,
+ 0x58d4, 0x2d4c,
+ 0x58d5, 0x13bf,
+ 0x58d6, 0x2d4b,
+ 0x58d8, 0x14cd,
+ 0x58d9, 0x14cc,
+ 0x58da, 0x3085,
+ 0x58db, 0x3087,
+ 0x58dc, 0x40da,
+ 0x58dd, 0x3086,
+ 0x58de, 0x1578,
+ 0x58e0, 0x40d9,
+ 0x58e2, 0x157a,
+ 0x58e3, 0x31cb,
+ 0x58e4, 0x160e,
+ 0x58e7, 0x3411,
+ 0x58e8, 0x3410,
+ 0x58e9, 0x1720,
+ 0x58eb, 0x027b,
+ 0x58ec, 0x02c1,
+ 0x58ef, 0x046f,
+ 0x58f0, 0x4549,
+ 0x58f2, 0x3d68,
+ 0x58f3, 0x3c7a,
+ 0x58f4, 0x1a9b,
+ 0x58f9, 0x0c20,
+ 0x58fb, 0x40dc,
+ 0x58fc, 0x23a2,
+ 0x58fd, 0x0faa,
+ 0x58fe, 0x264b,
+ 0x58ff, 0x28a9,
+ 0x5902, 0x0224,
+ 0x5903, 0x1785,
+ 0x5904, 0x454a,
+ 0x5905, 0x4599,
+ 0x5906, 0x1857,
+ 0x5907, 0x454b,
+ 0x590a, 0x0224,
+ 0x590c, 0x1944,
+ 0x590d, 0x1a9c,
+ 0x590e, 0x1c6c,
+ 0x590f, 0x0880,
+ 0x5911, 0x4274,
+ 0x5912, 0x3088,
+ 0x5914, 0x166d,
+ 0x5915, 0x027c,
+ 0x5916, 0x032e,
+ 0x5917, 0x179c,
+ 0x5919, 0x03b4,
+ 0x591c, 0x0581,
+ 0x591f, 0x40e3,
+ 0x5920, 0x0a44,
+ 0x5922, 0x0fac,
+ 0x5924, 0x0fad,
+ 0x5925, 0x0fab,
+ 0x5927, 0x027d,
+ 0x5929, 0x02c2,
+ 0x592a, 0x02c4,
+ 0x592b, 0x02c3,
+ 0x592c, 0x1786,
+ 0x592d, 0x02c5,
+ 0x592e, 0x032f,
+ 0x592f, 0x179d,
+ 0x5931, 0x0330,
+ 0x5932, 0x454c,
+ 0x5934, 0x454d,
+ 0x5937, 0x03b6,
+ 0x593c, 0x17d4,
+ 0x593e, 0x0470,
+ 0x5940, 0x1858,
+ 0x5944, 0x0585,
+ 0x5945, 0x1945,
+ 0x5947, 0x0583,
+ 0x5949, 0x0582,
+ 0x594a, 0x1c6d,
+ 0x594e, 0x06f2,
+ 0x594f, 0x06f1,
+ 0x5950, 0x06f3,
+ 0x5951, 0x06f0,
+ 0x5953, 0x1a9d,
+ 0x5954, 0x0586,
+ 0x5955, 0x06ef,
+ 0x5957, 0x0881,
+ 0x595a, 0x0883,
+ 0x595c, 0x1e95,
+ 0x5960, 0x0c22,
+ 0x5961, 0x20ef,
+ 0x5962, 0x0a45,
+ 0x5965, 0x4852,
+ 0x5967, 0x0df3,
+ 0x5969, 0x0faf,
+ 0x596a, 0x0fae,
+ 0x596b, 0x264c,
+ 0x596d, 0x1129,
+ 0x596e, 0x12a7,
+ 0x5970, 0x2f17,
+ 0x5971, 0x337b,
+ 0x5972, 0x3412,
+ 0x5973, 0x027e,
+ 0x5974, 0x0331,
+ 0x5975, 0x3e6a,
+ 0x5976, 0x0332,
+ 0x5977, 0x17da,
+ 0x5978, 0x03b9,
+ 0x5979, 0x03bc,
+ 0x597b, 0x17d8,
+ 0x597c, 0x17d6,
+ 0x597d, 0x03bb,
+ 0x597e, 0x17d9,
+ 0x597f, 0x17db,
+ 0x5980, 0x17d5,
+ 0x5981, 0x03be,
+ 0x5982, 0x03bd,
+ 0x5983, 0x03ba,
+ 0x5984, 0x03b8,
+ 0x5985, 0x17d7,
+ 0x5989, 0x3d30,
+ 0x598a, 0x047b,
+ 0x598d, 0x0478,
+ 0x598e, 0x185d,
+ 0x598f, 0x1860,
+ 0x5990, 0x185f,
+ 0x5992, 0x0472,
+ 0x5993, 0x047a,
+ 0x5994, 0x3c99,
+ 0x5996, 0x0477,
+ 0x5997, 0x185c,
+ 0x5998, 0x185a,
+ 0x5999, 0x0476,
+ 0x599a, 0x3bb0,
+ 0x599d, 0x0471,
+ 0x599e, 0x0474,
+ 0x599f, 0x3daf,
+ 0x59a0, 0x185b,
+ 0x59a1, 0x1862,
+ 0x59a2, 0x185e,
+ 0x59a3, 0x0475,
+ 0x59a4, 0x0479,
+ 0x59a5, 0x047c,
+ 0x59a6, 0x1859,
+ 0x59a7, 0x1861,
+ 0x59a8, 0x0473,
+ 0x59ac, 0x3d81,
+ 0x59ae, 0x058b,
+ 0x59af, 0x0593,
+ 0x59b0, 0x3cd8,
+ 0x59b1, 0x1951,
+ 0x59b2, 0x194a,
+ 0x59b3, 0x0594,
+ 0x59b4, 0x1955,
+ 0x59b5, 0x1946,
+ 0x59b6, 0x194d,
+ 0x59b7, 0x3f2d,
+ 0x59b8, 0x3a10,
+ 0x59b9, 0x058a,
+ 0x59ba, 0x1947,
+ 0x59bb, 0x0588,
+ 0x59bc, 0x194e,
+ 0x59bd, 0x1952,
+ 0x59be, 0x0587,
+ 0x59c0, 0x1953,
+ 0x59c1, 0x194c,
+ 0x59c3, 0x194f,
+ 0x59c4, 0x3d04,
+ 0x59c5, 0x0596,
+ 0x59c6, 0x058d,
+ 0x59c7, 0x1956,
+ 0x59c8, 0x1954,
+ 0x59c9, 0x40ec,
+ 0x59ca, 0x0592,
+ 0x59cb, 0x0590,
+ 0x59cc, 0x194b,
+ 0x59cd, 0x058f,
+ 0x59ce, 0x1949,
+ 0x59cf, 0x1948,
+ 0x59d0, 0x058e,
+ 0x59d1, 0x058c,
+ 0x59d2, 0x0595,
+ 0x59d3, 0x0591,
+ 0x59d4, 0x0589,
+ 0x59d6, 0x1950,
+ 0x59d8, 0x06f5,
+ 0x59d9, 0x40f1,
+ 0x59da, 0x06fc,
+ 0x59db, 0x1aab,
+ 0x59dc, 0x06f4,
+ 0x59dd, 0x1aa3,
+ 0x59de, 0x1a9f,
+ 0x59e0, 0x1aaf,
+ 0x59e1, 0x1a9e,
+ 0x59e3, 0x06f7,
+ 0x59e4, 0x1aa8,
+ 0x59e5, 0x06fa,
+ 0x59e6, 0x06fd,
+ 0x59e8, 0x06f8,
+ 0x59e9, 0x1aac,
+ 0x59ea, 0x06fb,
+ 0x59eb, 0x3d59,
+ 0x59ec, 0x088a,
+ 0x59ed, 0x1ab2,
+ 0x59ee, 0x1aa0,
+ 0x59ef, 0x3d38,
+ 0x59f0, 0x3bb2,
+ 0x59f1, 0x1aa2,
+ 0x59f2, 0x1aa9,
+ 0x59f3, 0x1aad,
+ 0x59f4, 0x1ab1,
+ 0x59f5, 0x1aae,
+ 0x59f6, 0x1aa7,
+ 0x59f7, 0x1aaa,
+ 0x59f8, 0x3e4a,
+ 0x59f9, 0x40f8,
+ 0x59fa, 0x1aa4,
+ 0x59fb, 0x06ff,
+ 0x59fc, 0x1aa6,
+ 0x59fd, 0x1aa5,
+ 0x59fe, 0x1ab0,
+ 0x59ff, 0x06f6,
+ 0x5a00, 0x1aa1,
+ 0x5a01, 0x06fe,
+ 0x5a02, 0x3b8d,
+ 0x5a03, 0x06f9,
+ 0x5a09, 0x0890,
+ 0x5a0a, 0x1c75,
+ 0x5a0b, 0x3c89,
+ 0x5a0c, 0x088f,
+ 0x5a0d, 0x3b38,
+ 0x5a0f, 0x1c73,
+ 0x5a11, 0x0884,
+ 0x5a12, 0x3a13,
+ 0x5a13, 0x0889,
+ 0x5a15, 0x1c72,
+ 0x5a16, 0x1c6f,
+ 0x5a17, 0x1c74,
+ 0x5a18, 0x0885,
+ 0x5a19, 0x1c6e,
+ 0x5a1b, 0x0888,
+ 0x5a1c, 0x0886,
+ 0x5a1e, 0x1c76,
+ 0x5a1f, 0x0887,
+ 0x5a20, 0x088b,
+ 0x5a21, 0x3a1b,
+ 0x5a23, 0x088c,
+ 0x5a24, 0x40e8,
+ 0x5a25, 0x088e,
+ 0x5a27, 0x3de1,
+ 0x5a29, 0x088d,
+ 0x5a2a, 0x3b3b,
+ 0x5a2b, 0x3d40,
+ 0x5a2c, 0x3a0f,
+ 0x5a2d, 0x1c70,
+ 0x5a33, 0x1c77,
+ 0x5a35, 0x1e9c,
+ 0x5a36, 0x0a46,
+ 0x5a37, 0x20fd,
+ 0x5a38, 0x1e9b,
+ 0x5a39, 0x1eae,
+ 0x5a3c, 0x0a4c,
+ 0x5a3d, 0x3ac0,
+ 0x5a3e, 0x1eac,
+ 0x5a40, 0x0a4b,
+ 0x5a41, 0x0a47,
+ 0x5a42, 0x1eb5,
+ 0x5a43, 0x1ea5,
+ 0x5a44, 0x1ea8,
+ 0x5a45, 0x3917,
+ 0x5a46, 0x0a4f,
+ 0x5a47, 0x1eb2,
+ 0x5a48, 0x1eaa,
+ 0x5a49, 0x0a48,
+ 0x5a4a, 0x0a50,
+ 0x5a4c, 0x1eaf,
+ 0x5a4d, 0x1ead,
+ 0x5a50, 0x1e9e,
+ 0x5a51, 0x1eb3,
+ 0x5a52, 0x1ea7,
+ 0x5a53, 0x1ea2,
+ 0x5a54, 0x4603,
+ 0x5a55, 0x1e98,
+ 0x5a56, 0x1eb4,
+ 0x5a57, 0x1ea4,
+ 0x5a58, 0x1e97,
+ 0x5a59, 0x3b34,
+ 0x5a5a, 0x0a4e,
+ 0x5a5b, 0x1ea9,
+ 0x5a5c, 0x1eb6,
+ 0x5a5d, 0x1ea6,
+ 0x5a5e, 0x1e9a,
+ 0x5a5f, 0x1e9f,
+ 0x5a60, 0x1e96,
+ 0x5a61, 0x3d33,
+ 0x5a62, 0x0a4d,
+ 0x5a63, 0x40fb,
+ 0x5a64, 0x1ea3,
+ 0x5a65, 0x1ea0,
+ 0x5a66, 0x0a49,
+ 0x5a67, 0x1e99,
+ 0x5a68, 0x39b7,
+ 0x5a69, 0x1eb1,
+ 0x5a6a, 0x0a4a,
+ 0x5a6b, 0x3a42,
+ 0x5a6c, 0x1ea1,
+ 0x5a6d, 0x1e9d,
+ 0x5a6e, 0x3d3f,
+ 0x5a70, 0x1eb0,
+ 0x5a71, 0x3d34,
+ 0x5a77, 0x0c23,
+ 0x5a78, 0x20f6,
+ 0x5a79, 0x3ce1,
+ 0x5a7a, 0x20f3,
+ 0x5a7b, 0x2104,
+ 0x5a7c, 0x20f8,
+ 0x5a7d, 0x2105,
+ 0x5a7e, 0x3a11,
+ 0x5a7f, 0x0c25,
+ 0x5a81, 0x3a1d,
+ 0x5a82, 0x3d31,
+ 0x5a83, 0x2101,
+ 0x5a84, 0x20fe,
+ 0x5a86, 0x3b81,
+ 0x5a88, 0x4263,
+ 0x5a8a, 0x20ff,
+ 0x5a8b, 0x2102,
+ 0x5a8c, 0x2106,
+ 0x5a8e, 0x1eab,
+ 0x5a8f, 0x2108,
+ 0x5a90, 0x23b6,
+ 0x5a91, 0x4235,
+ 0x5a92, 0x0c26,
+ 0x5a93, 0x2109,
+ 0x5a94, 0x20f1,
+ 0x5a95, 0x20fb,
+ 0x5a96, 0x4100,
+ 0x5a97, 0x2100,
+ 0x5a99, 0x3a0a,
+ 0x5a9a, 0x0c24,
+ 0x5a9b, 0x0c27,
+ 0x5a9c, 0x2107,
+ 0x5a9d, 0x210a,
+ 0x5a9e, 0x20f5,
+ 0x5a9f, 0x20f2,
+ 0x5aa0, 0x4172,
+ 0x5aa1, 0x3cdc,
+ 0x5aa2, 0x20f4,
+ 0x5aa5, 0x20f9,
+ 0x5aa6, 0x20f7,
+ 0x5aa7, 0x0c28,
+ 0x5aa9, 0x2103,
+ 0x5aab, 0x40fa,
+ 0x5aac, 0x20fa,
+ 0x5aae, 0x20fc,
+ 0x5aaf, 0x20f0,
+ 0x5ab0, 0x23aa,
+ 0x5ab1, 0x23a8,
+ 0x5ab2, 0x0dfc,
+ 0x5ab3, 0x0dfa,
+ 0x5ab4, 0x23b2,
+ 0x5ab5, 0x23a9,
+ 0x5ab6, 0x23b3,
+ 0x5ab7, 0x23af,
+ 0x5ab8, 0x23a7,
+ 0x5ab9, 0x23b5,
+ 0x5aba, 0x23a6,
+ 0x5abb, 0x23ad,
+ 0x5abc, 0x0df9,
+ 0x5abd, 0x0df8,
+ 0x5abe, 0x0df7,
+ 0x5abf, 0x23ab,
+ 0x5ac0, 0x23b0,
+ 0x5ac1, 0x0df4,
+ 0x5ac2, 0x0dfb,
+ 0x5ac3, 0x3896,
+ 0x5ac4, 0x23a4,
+ 0x5ac6, 0x23ae,
+ 0x5ac7, 0x23a3,
+ 0x5ac8, 0x23ac,
+ 0x5ac9, 0x0df5,
+ 0x5aca, 0x23b1,
+ 0x5acb, 0x23a5,
+ 0x5acc, 0x0df6,
+ 0x5acd, 0x23b4,
+ 0x5ace, 0x3c88,
+ 0x5acf, 0x43b5,
+ 0x5ad3, 0x4102,
+ 0x5ad5, 0x2650,
+ 0x5ad6, 0x0fb4,
+ 0x5ad7, 0x0fb3,
+ 0x5ad8, 0x0fb5,
+ 0x5ad9, 0x265c,
+ 0x5ada, 0x2652,
+ 0x5adb, 0x2658,
+ 0x5adc, 0x264d,
+ 0x5add, 0x265b,
+ 0x5ade, 0x265a,
+ 0x5adf, 0x265e,
+ 0x5ae0, 0x2657,
+ 0x5ae1, 0x0fb0,
+ 0x5ae2, 0x2656,
+ 0x5ae3, 0x0fb6,
+ 0x5ae4, 0x3b86,
+ 0x5ae5, 0x264f,
+ 0x5ae6, 0x0fb1,
+ 0x5ae8, 0x265d,
+ 0x5ae9, 0x0fb2,
+ 0x5aea, 0x2651,
+ 0x5aeb, 0x2654,
+ 0x5aec, 0x2659,
+ 0x5aed, 0x2653,
+ 0x5aee, 0x264e,
+ 0x5af0, 0x3ee7,
+ 0x5af2, 0x37f5,
+ 0x5af3, 0x2655,
+ 0x5af4, 0x28ab,
+ 0x5af5, 0x112d,
+ 0x5af6, 0x28ae,
+ 0x5af7, 0x28ad,
+ 0x5af8, 0x28b0,
+ 0x5af9, 0x28b2,
+ 0x5afa, 0x36ee,
+ 0x5afb, 0x112b,
+ 0x5afd, 0x28ac,
+ 0x5afe, 0x3c1d,
+ 0x5aff, 0x28aa,
+ 0x5b01, 0x28b3,
+ 0x5b02, 0x28b1,
+ 0x5b03, 0x28af,
+ 0x5b05, 0x28b5,
+ 0x5b07, 0x28b4,
+ 0x5b08, 0x112f,
+ 0x5b09, 0x112a,
+ 0x5b0b, 0x112c,
+ 0x5b0c, 0x112e,
+ 0x5b0d, 0x48ff,
+ 0x5b0f, 0x28b6,
+ 0x5b10, 0x2b22,
+ 0x5b11, 0x3bf6,
+ 0x5b13, 0x2b21,
+ 0x5b14, 0x2b20,
+ 0x5b16, 0x2b23,
+ 0x5b17, 0x2b1c,
+ 0x5b19, 0x2b1d,
+ 0x5b1a, 0x2b25,
+ 0x5b1b, 0x2b1e,
+ 0x5b1d, 0x12a8,
+ 0x5b1e, 0x2b27,
+ 0x5b1f, 0x4941,
+ 0x5b20, 0x2b26,
+ 0x5b21, 0x2b1f,
+ 0x5b23, 0x2d52,
+ 0x5b24, 0x13c5,
+ 0x5b25, 0x2d50,
+ 0x5b26, 0x2d55,
+ 0x5b27, 0x2d54,
+ 0x5b28, 0x2b24,
+ 0x5b2a, 0x13c4,
+ 0x5b2b, 0x3b84,
+ 0x5b2c, 0x2d53,
+ 0x5b2d, 0x2d4f,
+ 0x5b2e, 0x2d57,
+ 0x5b2f, 0x2d56,
+ 0x5b30, 0x13c3,
+ 0x5b32, 0x2d51,
+ 0x5b34, 0x12a9,
+ 0x5b38, 0x14ce,
+ 0x5b3c, 0x2f18,
+ 0x5b3d, 0x3089,
+ 0x5b40, 0x160f,
+ 0x5b41, 0x38c8,
+ 0x5b43, 0x1610,
+ 0x5b44, 0x3a44,
+ 0x5b45, 0x31cc,
+ 0x5b46, 0x42b2,
+ 0x5b47, 0x32cd,
+ 0x5b48, 0x32cc,
+ 0x5b4a, 0x38cd,
+ 0x5b4b, 0x337c,
+ 0x5b4d, 0x3413,
+ 0x5b4e, 0x3482,
+ 0x5b4f, 0x3a31,
+ 0x5b50, 0x027f,
+ 0x5b53, 0x0281,
+ 0x5b54, 0x02c6,
+ 0x5b55, 0x0333,
+ 0x5b56, 0x17dc,
+ 0x5b57, 0x03bf,
+ 0x5b5a, 0x047f,
+ 0x5b5c, 0x047e,
+ 0x5b5d, 0x047d,
+ 0x5b5f, 0x0597,
+ 0x5b62, 0x1957,
+ 0x5b63, 0x0599,
+ 0x5b64, 0x0598,
+ 0x5b65, 0x1958,
+ 0x5b66, 0x454e,
+ 0x5b68, 0x461d,
+ 0x5b69, 0x0700,
+ 0x5b6b, 0x0891,
+ 0x5b6c, 0x1c78,
+ 0x5b6d, 0x3e5f,
+ 0x5b6e, 0x1eb8,
+ 0x5b70, 0x0a51,
+ 0x5b71, 0x0c2a,
+ 0x5b72, 0x1eb7,
+ 0x5b73, 0x0c29,
+ 0x5b74, 0x3732,
+ 0x5b75, 0x0fb7,
+ 0x5b76, 0x410a,
+ 0x5b77, 0x265f,
+ 0x5b78, 0x12aa,
+ 0x5b7a, 0x13c6,
+ 0x5b7b, 0x2d58,
+ 0x5b7c, 0x410c,
+ 0x5b7d, 0x1611,
+ 0x5b7f, 0x16c0,
+ 0x5b80, 0x0225,
+ 0x5b81, 0x179e,
+ 0x5b82, 0x4044,
+ 0x5b83, 0x0334,
+ 0x5b84, 0x179f,
+ 0x5b85, 0x03c3,
+ 0x5b87, 0x03c1,
+ 0x5b89, 0x03c4,
+ 0x5b8b, 0x0482,
+ 0x5b8c, 0x0481,
+ 0x5b8e, 0x1863,
+ 0x5b8f, 0x0483,
+ 0x5b90, 0x48e9,
+ 0x5b92, 0x1864,
+ 0x5b93, 0x1959,
+ 0x5b95, 0x195a,
+ 0x5b97, 0x059a,
+ 0x5b98, 0x059c,
+ 0x5b99, 0x059e,
+ 0x5b9a, 0x059b,
+ 0x5b9b, 0x059f,
+ 0x5b9c, 0x059d,
+ 0x5b9d, 0x4116,
+ 0x5b9e, 0x454f,
+ 0x5ba2, 0x0704,
+ 0x5ba3, 0x0701,
+ 0x5ba4, 0x0703,
+ 0x5ba5, 0x0705,
+ 0x5ba6, 0x0702,
+ 0x5ba7, 0x1c79,
+ 0x5ba8, 0x1ab3,
+ 0x5baa, 0x417b,
+ 0x5bac, 0x1c7b,
+ 0x5bad, 0x1c7a,
+ 0x5bae, 0x0897,
+ 0x5bb0, 0x0893,
+ 0x5bb3, 0x0894,
+ 0x5bb4, 0x0896,
+ 0x5bb5, 0x0898,
+ 0x5bb6, 0x0895,
+ 0x5bb8, 0x089a,
+ 0x5bb9, 0x0899,
+ 0x5bbf, 0x0a56,
+ 0x5bc0, 0x1eba,
+ 0x5bc1, 0x1eb9,
+ 0x5bc2, 0x0a55,
+ 0x5bc3, 0x3f25,
+ 0x5bc4, 0x0a54,
+ 0x5bc5, 0x0a53,
+ 0x5bc6, 0x0a57,
+ 0x5bc7, 0x0a52,
+ 0x5bca, 0x2110,
+ 0x5bcb, 0x210d,
+ 0x5bcc, 0x0c2c,
+ 0x5bcd, 0x210c,
+ 0x5bce, 0x2111,
+ 0x5bd0, 0x0c2e,
+ 0x5bd1, 0x210f,
+ 0x5bd2, 0x0c2b,
+ 0x5bd3, 0x0c2d,
+ 0x5bd4, 0x210e,
+ 0x5bd5, 0x4111,
+ 0x5bd6, 0x23b7,
+ 0x5bd7, 0x42bb,
+ 0x5bd8, 0x23b8,
+ 0x5bde, 0x0fb8,
+ 0x5bdf, 0x0fc0,
+ 0x5be0, 0x2660,
+ 0x5be1, 0x0fba,
+ 0x5be2, 0x0fbe,
+ 0x5be3, 0x2661,
+ 0x5be4, 0x0fbf,
+ 0x5be5, 0x0fbb,
+ 0x5be7, 0x0fb9,
+ 0x5be8, 0x0fbd,
+ 0x5be9, 0x1132,
+ 0x5bea, 0x210b,
+ 0x5beb, 0x1133,
+ 0x5bec, 0x1131,
+ 0x5bee, 0x1130,
+ 0x5bef, 0x2b28,
+ 0x5bf0, 0x12ab,
+ 0x5bf1, 0x2d59,
+ 0x5bf3, 0x4115,
+ 0x5bf5, 0x157b,
+ 0x5bf6, 0x1612,
+ 0x5bf8, 0x0282,
+ 0x5bfa, 0x03c5,
+ 0x5bff, 0x40dd,
+ 0x5c01, 0x0706,
+ 0x5c03, 0x1c7c,
+ 0x5c04, 0x089b,
+ 0x5c05, 0x4118,
+ 0x5c07, 0x0a5a,
+ 0x5c08, 0x0a59,
+ 0x5c09, 0x0a58,
+ 0x5c0a, 0x0c2f,
+ 0x5c0c, 0x2112,
+ 0x5c0d, 0x0fc1,
+ 0x5c0e, 0x12ac,
+ 0x5c0f, 0x0283,
+ 0x5c10, 0x1787,
+ 0x5c11, 0x02c7,
+ 0x5c12, 0x17a0,
+ 0x5c13, 0x411a,
+ 0x5c14, 0x411c,
+ 0x5c15, 0x17dd,
+ 0x5c16, 0x03c6,
+ 0x5c1a, 0x05a0,
+ 0x5c1c, 0x45ea,
+ 0x5c1e, 0x3a29,
+ 0x5c1f, 0x23ba,
+ 0x5c20, 0x3d89,
+ 0x5c22, 0x0284,
+ 0x5c23, 0x44e8,
+ 0x5c24, 0x02c8,
+ 0x5c25, 0x17de,
+ 0x5c28, 0x1865,
+ 0x5c2a, 0x1866,
+ 0x5c2c, 0x0484,
+ 0x5c30, 0x2113,
+ 0x5c31, 0x0c31,
+ 0x5c33, 0x23bb,
+ 0x5c37, 0x13c7,
+ 0x5c38, 0x0285,
+ 0x5c39, 0x0299,
+ 0x5c3a, 0x02c9,
+ 0x5c3b, 0x17a1,
+ 0x5c3c, 0x0335,
+ 0x5c3e, 0x0488,
+ 0x5c3f, 0x0487,
+ 0x5c40, 0x0485,
+ 0x5c44, 0x195b,
+ 0x5c45, 0x05a2,
+ 0x5c47, 0x195c,
+ 0x5c48, 0x05a1,
+ 0x5c49, 0x411f,
+ 0x5c4a, 0x3f5c,
+ 0x5c4b, 0x070a,
+ 0x5c4c, 0x1ab4,
+ 0x5c4d, 0x0709,
+ 0x5c4e, 0x0707,
+ 0x5c50, 0x089e,
+ 0x5c51, 0x089c,
+ 0x5c53, 0x3f02,
+ 0x5c54, 0x1c7e,
+ 0x5c55, 0x089d,
+ 0x5c56, 0x1c7d,
+ 0x5c58, 0x0892,
+ 0x5c59, 0x1ebb,
+ 0x5c5c, 0x0a5c,
+ 0x5c5e, 0x3d67,
+ 0x5c60, 0x0a5b,
+ 0x5c62, 0x0fc2,
+ 0x5c63, 0x2662,
+ 0x5c64, 0x1134,
+ 0x5c67, 0x28b7,
+ 0x5c68, 0x13c8,
+ 0x5c69, 0x2f19,
+ 0x5c6c, 0x166e,
+ 0x5c6d, 0x3483,
+ 0x5c6e, 0x1776,
+ 0x5c6f, 0x02ca,
+ 0x5c71, 0x0286,
+ 0x5c73, 0x17a3,
+ 0x5c74, 0x17a2,
+ 0x5c79, 0x03c7,
+ 0x5c7a, 0x17e0,
+ 0x5c7c, 0x17df,
+ 0x5c7e, 0x17e2,
+ 0x5c85, 0x4121,
+ 0x5c86, 0x186e,
+ 0x5c88, 0x1869,
+ 0x5c89, 0x186b,
+ 0x5c8a, 0x186d,
+ 0x5c8b, 0x186a,
+ 0x5c8c, 0x048c,
+ 0x5c8d, 0x1867,
+ 0x5c8f, 0x1868,
+ 0x5c90, 0x0489,
+ 0x5c92, 0x186c,
+ 0x5c93, 0x186f,
+ 0x5c94, 0x048b,
+ 0x5c95, 0x1870,
+ 0x5c99, 0x468c,
+ 0x5c9a, 0x4551,
+ 0x5c9c, 0x495a,
+ 0x5c9d, 0x196a,
+ 0x5c9e, 0x3a2a,
+ 0x5c9f, 0x1964,
+ 0x5ca0, 0x195f,
+ 0x5ca1, 0x05a5,
+ 0x5ca2, 0x1967,
+ 0x5ca3, 0x1965,
+ 0x5ca4, 0x195e,
+ 0x5ca5, 0x196b,
+ 0x5ca6, 0x196e,
+ 0x5ca7, 0x1969,
+ 0x5ca8, 0x1962,
+ 0x5ca9, 0x05a7,
+ 0x5caa, 0x1968,
+ 0x5cab, 0x05a8,
+ 0x5cac, 0x1963,
+ 0x5cad, 0x1966,
+ 0x5cae, 0x195d,
+ 0x5caf, 0x1961,
+ 0x5cb0, 0x196d,
+ 0x5cb1, 0x05a9,
+ 0x5cb3, 0x05aa,
+ 0x5cb5, 0x1960,
+ 0x5cb6, 0x196c,
+ 0x5cb7, 0x05a4,
+ 0x5cb8, 0x05a6,
+ 0x5cba, 0x412b,
+ 0x5cc1, 0x43b8,
+ 0x5cc2, 0x3d4c,
+ 0x5cc6, 0x1ac5,
+ 0x5cc7, 0x1abe,
+ 0x5cc8, 0x1ac4,
+ 0x5cc9, 0x1abd,
+ 0x5cca, 0x1abf,
+ 0x5ccb, 0x1ab9,
+ 0x5ccc, 0x1ab7,
+ 0x5cce, 0x1ac6,
+ 0x5ccf, 0x1ac3,
+ 0x5cd0, 0x1ab5,
+ 0x5cd1, 0x3f13,
+ 0x5cd2, 0x070c,
+ 0x5cd3, 0x1ac1,
+ 0x5cd6, 0x1ac0,
+ 0x5cd7, 0x1ab8,
+ 0x5cd8, 0x1ab6,
+ 0x5cd9, 0x070b,
+ 0x5cda, 0x1abc,
+ 0x5cdb, 0x1aba,
+ 0x5cde, 0x1abb,
+ 0x5cdf, 0x1ac7,
+ 0x5ce5, 0x4637,
+ 0x5ce8, 0x08a3,
+ 0x5ce9, 0x4122,
+ 0x5cea, 0x08a2,
+ 0x5cec, 0x1c7f,
+ 0x5ced, 0x089f,
+ 0x5cee, 0x1c81,
+ 0x5cef, 0x4123,
+ 0x5cf0, 0x08a4,
+ 0x5cf1, 0x1c82,
+ 0x5cf4, 0x08a7,
+ 0x5cf6, 0x08a5,
+ 0x5cf7, 0x1c83,
+ 0x5cf8, 0x1ac8,
+ 0x5cf9, 0x1c85,
+ 0x5cfb, 0x08a1,
+ 0x5cfd, 0x08a0,
+ 0x5cff, 0x1c80,
+ 0x5d00, 0x1c84,
+ 0x5d01, 0x08a6,
+ 0x5d06, 0x0a5f,
+ 0x5d07, 0x0a5e,
+ 0x5d0b, 0x1ebd,
+ 0x5d0c, 0x1ec1,
+ 0x5d0d, 0x1ec3,
+ 0x5d0e, 0x0a60,
+ 0x5d0f, 0x1ec6,
+ 0x5d10, 0x4127,
+ 0x5d11, 0x0a64,
+ 0x5d12, 0x1ec8,
+ 0x5d14, 0x0a66,
+ 0x5d15, 0x43b9,
+ 0x5d16, 0x0a62,
+ 0x5d17, 0x0a6a,
+ 0x5d18, 0x4128,
+ 0x5d19, 0x0a67,
+ 0x5d1a, 0x1ebf,
+ 0x5d1b, 0x0a61,
+ 0x5d1d, 0x1ebe,
+ 0x5d1e, 0x1ebc,
+ 0x5d1f, 0x1eca,
+ 0x5d20, 0x1ec0,
+ 0x5d22, 0x0a63,
+ 0x5d23, 0x1ec9,
+ 0x5d24, 0x0a68,
+ 0x5d25, 0x1ec5,
+ 0x5d26, 0x1ec4,
+ 0x5d27, 0x0a69,
+ 0x5d28, 0x1ec2,
+ 0x5d29, 0x0a65,
+ 0x5d2c, 0x3df7,
+ 0x5d2e, 0x1ecb,
+ 0x5d2f, 0x46d3,
+ 0x5d30, 0x1ec7,
+ 0x5d31, 0x2122,
+ 0x5d32, 0x2129,
+ 0x5d33, 0x211e,
+ 0x5d34, 0x0c34,
+ 0x5d35, 0x211a,
+ 0x5d36, 0x212a,
+ 0x5d37, 0x2114,
+ 0x5d38, 0x2127,
+ 0x5d39, 0x2125,
+ 0x5d3a, 0x211f,
+ 0x5d3c, 0x2128,
+ 0x5d3d, 0x2121,
+ 0x5d3e, 0x4629,
+ 0x5d3f, 0x2119,
+ 0x5d40, 0x212b,
+ 0x5d41, 0x2117,
+ 0x5d42, 0x2124,
+ 0x5d43, 0x2115,
+ 0x5d45, 0x212c,
+ 0x5d46, 0x4129,
+ 0x5d47, 0x0c35,
+ 0x5d48, 0x462a,
+ 0x5d49, 0x2126,
+ 0x5d4a, 0x23be,
+ 0x5d4b, 0x2118,
+ 0x5d4c, 0x0c32,
+ 0x5d4e, 0x211c,
+ 0x5d50, 0x0c33,
+ 0x5d51, 0x211b,
+ 0x5d52, 0x2120,
+ 0x5d55, 0x211d,
+ 0x5d56, 0x43ba,
+ 0x5d57, 0x3fca,
+ 0x5d59, 0x2123,
+ 0x5d5b, 0x3dd5,
+ 0x5d5e, 0x23c2,
+ 0x5d62, 0x23c5,
+ 0x5d63, 0x23bd,
+ 0x5d65, 0x23bf,
+ 0x5d67, 0x23c4,
+ 0x5d68, 0x23c3,
+ 0x5d69, 0x0dfd,
+ 0x5d6b, 0x2116,
+ 0x5d6c, 0x23c1,
+ 0x5d6f, 0x0dfe,
+ 0x5d70, 0x46e4,
+ 0x5d71, 0x23bc,
+ 0x5d72, 0x23c0,
+ 0x5d74, 0x3eef,
+ 0x5d77, 0x2669,
+ 0x5d79, 0x2670,
+ 0x5d7a, 0x2667,
+ 0x5d7c, 0x266e,
+ 0x5d7d, 0x2665,
+ 0x5d7e, 0x266d,
+ 0x5d7f, 0x2671,
+ 0x5d80, 0x2664,
+ 0x5d81, 0x2668,
+ 0x5d82, 0x2663,
+ 0x5d84, 0x0fc3,
+ 0x5d85, 0x3e34,
+ 0x5d86, 0x2666,
+ 0x5d87, 0x0fc4,
+ 0x5d88, 0x266c,
+ 0x5d89, 0x266b,
+ 0x5d8a, 0x266a,
+ 0x5d8b, 0x4124,
+ 0x5d8d, 0x266f,
+ 0x5d8e, 0x3f0c,
+ 0x5d92, 0x28bb,
+ 0x5d93, 0x28bd,
+ 0x5d94, 0x1137,
+ 0x5d95, 0x28be,
+ 0x5d97, 0x28b9,
+ 0x5d99, 0x28b8,
+ 0x5d9a, 0x28c2,
+ 0x5d9c, 0x28c0,
+ 0x5d9d, 0x1136,
+ 0x5d9e, 0x28c3,
+ 0x5d9f, 0x28ba,
+ 0x5da0, 0x28bf,
+ 0x5da1, 0x28c1,
+ 0x5da2, 0x28bc,
+ 0x5da4, 0x462d,
+ 0x5da7, 0x2b2c,
+ 0x5da8, 0x2b31,
+ 0x5da9, 0x2b2b,
+ 0x5daa, 0x2b30,
+ 0x5dab, 0x3e39,
+ 0x5dac, 0x2b29,
+ 0x5dad, 0x2b33,
+ 0x5dae, 0x2b2f,
+ 0x5daf, 0x2b34,
+ 0x5db0, 0x2b2e,
+ 0x5db1, 0x2b2a,
+ 0x5db2, 0x2b32,
+ 0x5db4, 0x2b35,
+ 0x5db5, 0x2b2d,
+ 0x5db6, 0x4158,
+ 0x5db7, 0x2d5b,
+ 0x5db8, 0x13cc,
+ 0x5db9, 0x462e,
+ 0x5dba, 0x13ca,
+ 0x5dbc, 0x13c9,
+ 0x5dbd, 0x13cb,
+ 0x5dc0, 0x2f1b,
+ 0x5dc1, 0x3bff,
+ 0x5dc2, 0x3023,
+ 0x5dc3, 0x308c,
+ 0x5dc6, 0x31cd,
+ 0x5dc9, 0x1613,
+ 0x5dcb, 0x32ce,
+ 0x5dcd, 0x166f,
+ 0x5dcf, 0x32cf,
+ 0x5dd1, 0x337f,
+ 0x5dd2, 0x16c2,
+ 0x5dd4, 0x16c1,
+ 0x5dd5, 0x337e,
+ 0x5dd6, 0x16f7,
+ 0x5dd7, 0x412c,
+ 0x5dd8, 0x3414,
+ 0x5ddb, 0x0226,
+ 0x5ddd, 0x0287,
+ 0x5dde, 0x03c8,
+ 0x5ddf, 0x17e3,
+ 0x5de0, 0x1871,
+ 0x5de1, 0x051a,
+ 0x5de2, 0x0a6b,
+ 0x5de5, 0x0288,
+ 0x5de6, 0x0338,
+ 0x5de7, 0x0337,
+ 0x5de8, 0x0336,
+ 0x5deb, 0x048d,
+ 0x5dee, 0x08a8,
+ 0x5df0, 0x23c6,
+ 0x5df1, 0x0289,
+ 0x5df4, 0x02cb,
+ 0x5df5, 0x3f61,
+ 0x5df7, 0x070d,
+ 0x5df9, 0x1ac9,
+ 0x5dfd, 0x0c36,
+ 0x5dfe, 0x028c,
+ 0x5dff, 0x1788,
+ 0x5e02, 0x0339,
+ 0x5e04, 0x17a4,
+ 0x5e06, 0x03c9,
+ 0x5e09, 0x4140,
+ 0x5e0a, 0x1872,
+ 0x5e0b, 0x3d8a,
+ 0x5e0c, 0x048e,
+ 0x5e0e, 0x1873,
+ 0x5e11, 0x05b0,
+ 0x5e12, 0x3f2e,
+ 0x5e14, 0x1970,
+ 0x5e15, 0x05ae,
+ 0x5e16, 0x05ad,
+ 0x5e17, 0x196f,
+ 0x5e18, 0x05ab,
+ 0x5e19, 0x1971,
+ 0x5e1a, 0x05ac,
+ 0x5e1b, 0x05af,
+ 0x5e1d, 0x070e,
+ 0x5e1f, 0x0710,
+ 0x5e20, 0x1acd,
+ 0x5e21, 0x1aca,
+ 0x5e24, 0x1ace,
+ 0x5e25, 0x070f,
+ 0x5e28, 0x1c87,
+ 0x5e29, 0x1c86,
+ 0x5e2b, 0x08aa,
+ 0x5e2d, 0x08a9,
+ 0x5e2e, 0x4135,
+ 0x5e33, 0x0a6e,
+ 0x5e34, 0x1ecd,
+ 0x5e36, 0x0a6d,
+ 0x5e37, 0x0a6f,
+ 0x5e38, 0x0a6c,
+ 0x5e3d, 0x0c38,
+ 0x5e3e, 0x1ecc,
+ 0x5e40, 0x0c39,
+ 0x5e41, 0x212e,
+ 0x5e42, 0x43a0,
+ 0x5e43, 0x0c3a,
+ 0x5e44, 0x212d,
+ 0x5e45, 0x0c37,
+ 0x5e48, 0x3a2c,
+ 0x5e4a, 0x23c9,
+ 0x5e4b, 0x23cb,
+ 0x5e4c, 0x0dff,
+ 0x5e4d, 0x23ca,
+ 0x5e4e, 0x23c8,
+ 0x5e4f, 0x23c7,
+ 0x5e53, 0x2674,
+ 0x5e54, 0x0fc9,
+ 0x5e55, 0x0fc7,
+ 0x5e57, 0x0fc8,
+ 0x5e58, 0x2672,
+ 0x5e5b, 0x0fc5,
+ 0x5e5c, 0x28c7,
+ 0x5e5d, 0x28c5,
+ 0x5e5e, 0x3a2b,
+ 0x5e5f, 0x1139,
+ 0x5e60, 0x28c6,
+ 0x5e61, 0x113a,
+ 0x5e62, 0x1138,
+ 0x5e63, 0x0fc6,
+ 0x5e66, 0x2b38,
+ 0x5e67, 0x2b36,
+ 0x5e69, 0x28c4,
+ 0x5e6a, 0x2d5d,
+ 0x5e6b, 0x13cd,
+ 0x5e6c, 0x2d5c,
+ 0x5e6d, 0x2f1c,
+ 0x5e6f, 0x2b39,
+ 0x5e70, 0x308d,
+ 0x5e72, 0x028d,
+ 0x5e73, 0x033b,
+ 0x5e74, 0x03cb,
+ 0x5e75, 0x17e4,
+ 0x5e76, 0x03ca,
+ 0x5e78, 0x05b1,
+ 0x5e79, 0x0e00,
+ 0x5e7a, 0x0227,
+ 0x5e7b, 0x02cc,
+ 0x5e7c, 0x033c,
+ 0x5e7d, 0x0711,
+ 0x5e7e, 0x0c3b,
+ 0x5e7f, 0x0228,
+ 0x5e80, 0x17a5,
+ 0x5e82, 0x17a6,
+ 0x5e83, 0x4108,
+ 0x5e84, 0x17e5,
+ 0x5e86, 0x4552,
+ 0x5e87, 0x0490,
+ 0x5e88, 0x1877,
+ 0x5e89, 0x1875,
+ 0x5e8a, 0x0491,
+ 0x5e8b, 0x1874,
+ 0x5e8c, 0x1876,
+ 0x5e8d, 0x1878,
+ 0x5e8f, 0x048f,
+ 0x5e95, 0x05b5,
+ 0x5e97, 0x05b3,
+ 0x5e9a, 0x05b2,
+ 0x5e9b, 0x1ad2,
+ 0x5e9c, 0x05b4,
+ 0x5ea0, 0x0712,
+ 0x5ea2, 0x1ad1,
+ 0x5ea3, 0x1ad3,
+ 0x5ea4, 0x1ad0,
+ 0x5ea5, 0x1ad4,
+ 0x5ea6, 0x0713,
+ 0x5ea7, 0x08ad,
+ 0x5ea8, 0x1c88,
+ 0x5eaa, 0x1c8a,
+ 0x5eab, 0x08ab,
+ 0x5eac, 0x1c8b,
+ 0x5ead, 0x08ac,
+ 0x5eae, 0x1c89,
+ 0x5eb0, 0x1acf,
+ 0x5eb1, 0x1ece,
+ 0x5eb2, 0x1ed1,
+ 0x5eb4, 0x1ecf,
+ 0x5eb5, 0x0a73,
+ 0x5eb6, 0x0a72,
+ 0x5eb7, 0x0a70,
+ 0x5eb9, 0x1ed0,
+ 0x5ebd, 0x43bd,
+ 0x5ebe, 0x0a74,
+ 0x5ec1, 0x0c3d,
+ 0x5ec4, 0x0c3f,
+ 0x5ec5, 0x23cc,
+ 0x5ec6, 0x23ce,
+ 0x5ec7, 0x23d0,
+ 0x5ec8, 0x0e02,
+ 0x5ec9, 0x0e01,
+ 0x5eca, 0x0c3c,
+ 0x5ecb, 0x23cf,
+ 0x5ecc, 0x23cd,
+ 0x5ecd, 0x3a30,
+ 0x5ece, 0x2678,
+ 0x5ed0, 0x413d,
+ 0x5ed1, 0x2676,
+ 0x5ed2, 0x267c,
+ 0x5ed3, 0x0fca,
+ 0x5ed4, 0x267d,
+ 0x5ed5, 0x267a,
+ 0x5ed6, 0x0fcb,
+ 0x5ed7, 0x2677,
+ 0x5ed8, 0x2675,
+ 0x5ed9, 0x267b,
+ 0x5eda, 0x113c,
+ 0x5edb, 0x28c9,
+ 0x5edc, 0x2679,
+ 0x5edd, 0x113e,
+ 0x5ede, 0x28ca,
+ 0x5edf, 0x113d,
+ 0x5ee0, 0x1140,
+ 0x5ee1, 0x28cb,
+ 0x5ee2, 0x113b,
+ 0x5ee3, 0x113f,
+ 0x5ee5, 0x2b3e,
+ 0x5ee6, 0x2b3c,
+ 0x5ee7, 0x2b3b,
+ 0x5ee8, 0x2b3d,
+ 0x5ee9, 0x2b3a,
+ 0x5eec, 0x157d,
+ 0x5eee, 0x31cf,
+ 0x5ef1, 0x32d0,
+ 0x5ef2, 0x3380,
+ 0x5ef3, 0x1742,
+ 0x5ef4, 0x0229,
+ 0x5ef6, 0x05b7,
+ 0x5ef7, 0x0492,
+ 0x5ef8, 0x386f,
+ 0x5ef9, 0x4143,
+ 0x5efa, 0x0714,
+ 0x5efb, 0x4144,
+ 0x5efc, 0x4146,
+ 0x5efe, 0x028e,
+ 0x5eff, 0x02cd,
+ 0x5f01, 0x033d,
+ 0x5f02, 0x17e6,
+ 0x5f04, 0x0493,
+ 0x5f05, 0x1879,
+ 0x5f07, 0x1ad5,
+ 0x5f08, 0x0715,
+ 0x5f0a, 0x0fcc,
+ 0x5f0b, 0x028f,
+ 0x5f0c, 0x3a3e,
+ 0x5f0d, 0x4149,
+ 0x5f0e, 0x3a3f,
+ 0x5f0f, 0x03cc,
+ 0x5f12, 0x0e03,
+ 0x5f13, 0x0290,
+ 0x5f14, 0x02ce,
+ 0x5f17, 0x033f,
+ 0x5f18, 0x033e,
+ 0x5f1a, 0x17e7,
+ 0x5f1b, 0x03cd,
+ 0x5f1d, 0x187a,
+ 0x5f1f, 0x0494,
+ 0x5f22, 0x1973,
+ 0x5f25, 0x4630,
+ 0x5f26, 0x05b8,
+ 0x5f28, 0x1972,
+ 0x5f29, 0x05ba,
+ 0x5f2d, 0x0716,
+ 0x5f2e, 0x1ad6,
+ 0x5f30, 0x1c8d,
+ 0x5f31, 0x08ae,
+ 0x5f33, 0x1c8c,
+ 0x5f35, 0x0a75,
+ 0x5f36, 0x1ed3,
+ 0x5f37, 0x0a76,
+ 0x5f38, 0x1ed4,
+ 0x5f3a, 0x414e,
+ 0x5f3c, 0x0c40,
+ 0x5f40, 0x23d1,
+ 0x5f43, 0x267f,
+ 0x5f44, 0x267e,
+ 0x5f46, 0x0fcd,
+ 0x5f48, 0x1141,
+ 0x5f49, 0x28cc,
+ 0x5f4a, 0x12ad,
+ 0x5f4b, 0x2b3f,
+ 0x5f4c, 0x13ce,
+ 0x5f4d, 0x3ba5,
+ 0x5f4e, 0x16c3,
+ 0x5f4f, 0x3416,
+ 0x5f50, 0x022a,
+ 0x5f51, 0x44e9,
+ 0x5f54, 0x1976,
+ 0x5f56, 0x1ad7,
+ 0x5f57, 0x0a77,
+ 0x5f58, 0x212f,
+ 0x5f59, 0x0e04,
+ 0x5f5c, 0x3d5a,
+ 0x5f5d, 0x14cf,
+ 0x5f61, 0x022b,
+ 0x5f62, 0x0496,
+ 0x5f63, 0x4152,
+ 0x5f64, 0x0495,
+ 0x5f65, 0x0717,
+ 0x5f67, 0x1c8e,
+ 0x5f69, 0x0a79,
+ 0x5f6a, 0x0b89,
+ 0x5f6b, 0x0a7a,
+ 0x5f6c, 0x0a78,
+ 0x5f6d, 0x0c41,
+ 0x5f6f, 0x2680,
+ 0x5f70, 0x0fce,
+ 0x5f71, 0x1142,
+ 0x5f72, 0x4154,
+ 0x5f73, 0x1777,
+ 0x5f74, 0x17e8,
+ 0x5f76, 0x187c,
+ 0x5f77, 0x0497,
+ 0x5f78, 0x187b,
+ 0x5f79, 0x0498,
+ 0x5f7b, 0x4058,
+ 0x5f7c, 0x05be,
+ 0x5f7d, 0x1979,
+ 0x5f7e, 0x1978,
+ 0x5f7f, 0x05bd,
+ 0x5f80, 0x05bb,
+ 0x5f82, 0x1977,
+ 0x5f83, 0x4631,
+ 0x5f85, 0x0719,
+ 0x5f86, 0x1ad8,
+ 0x5f87, 0x071c,
+ 0x5f88, 0x0718,
+ 0x5f89, 0x071e,
+ 0x5f8a, 0x071a,
+ 0x5f8c, 0x071d,
+ 0x5f90, 0x08b1,
+ 0x5f91, 0x08b0,
+ 0x5f92, 0x08af,
+ 0x5f96, 0x1ed6,
+ 0x5f97, 0x0a7b,
+ 0x5f98, 0x0a7e,
+ 0x5f99, 0x0a7c,
+ 0x5f9b, 0x1ed5,
+ 0x5f9c, 0x0a81,
+ 0x5f9e, 0x0a7d,
+ 0x5f9f, 0x1ed7,
+ 0x5fa0, 0x0a80,
+ 0x5fa1, 0x0a7f,
+ 0x5fa4, 0x402c,
+ 0x5fa5, 0x2131,
+ 0x5fa6, 0x2130,
+ 0x5fa7, 0x4157,
+ 0x5fa8, 0x0c44,
+ 0x5fa9, 0x0c42,
+ 0x5fab, 0x2132,
+ 0x5fac, 0x0e05,
+ 0x5fad, 0x23d3,
+ 0x5fae, 0x0e06,
+ 0x5faf, 0x23d2,
+ 0x5fb1, 0x3d98,
+ 0x5fb2, 0x28cd,
+ 0x5fb5, 0x1144,
+ 0x5fb6, 0x2681,
+ 0x5fb7, 0x1143,
+ 0x5fb9, 0x0fcf,
+ 0x5fba, 0x3f9f,
+ 0x5fbb, 0x2b41,
+ 0x5fbc, 0x2b40,
+ 0x5fbd, 0x13cf,
+ 0x5fbe, 0x2d5e,
+ 0x5fbf, 0x308e,
+ 0x5fc0, 0x31d1,
+ 0x5fc3, 0x02d0,
+ 0x5fc4, 0x44ea,
+ 0x5fc5, 0x0340,
+ 0x5fc9, 0x17a7,
+ 0x5fcc, 0x049a,
+ 0x5fcd, 0x049c,
+ 0x5fcf, 0x17eb,
+ 0x5fd0, 0x187f,
+ 0x5fd1, 0x187e,
+ 0x5fd2, 0x187d,
+ 0x5fd4, 0x17ea,
+ 0x5fd5, 0x17e9,
+ 0x5fd6, 0x03cf,
+ 0x5fd7, 0x049b,
+ 0x5fd8, 0x0499,
+ 0x5fd9, 0x03ce,
+ 0x5fdb, 0x3a4a,
+ 0x5fdd, 0x05bf,
+ 0x5fde, 0x197a,
+ 0x5fdf, 0x41af,
+ 0x5fe0, 0x05c0,
+ 0x5fe1, 0x1884,
+ 0x5fe3, 0x1886,
+ 0x5fe4, 0x1885,
+ 0x5fe5, 0x197b,
+ 0x5fe8, 0x1881,
+ 0x5fea, 0x04a0,
+ 0x5feb, 0x049e,
+ 0x5fed, 0x1880,
+ 0x5fee, 0x1882,
+ 0x5fef, 0x1888,
+ 0x5ff1, 0x049d,
+ 0x5ff3, 0x1883,
+ 0x5ff4, 0x188c,
+ 0x5ff5, 0x05c2,
+ 0x5ff7, 0x1889,
+ 0x5ff8, 0x049f,
+ 0x5ffa, 0x1887,
+ 0x5ffb, 0x188a,
+ 0x5ffd, 0x05c1,
+ 0x5fff, 0x05c3,
+ 0x6000, 0x188b,
+ 0x6009, 0x198f,
+ 0x600a, 0x1982,
+ 0x600b, 0x1980,
+ 0x600c, 0x198e,
+ 0x600d, 0x1989,
+ 0x600e, 0x0723,
+ 0x600f, 0x05c4,
+ 0x6010, 0x198a,
+ 0x6011, 0x198d,
+ 0x6012, 0x071f,
+ 0x6013, 0x198c,
+ 0x6014, 0x05c5,
+ 0x6015, 0x05ca,
+ 0x6016, 0x05c8,
+ 0x6017, 0x1983,
+ 0x6019, 0x197e,
+ 0x601a, 0x1985,
+ 0x601b, 0x05cf,
+ 0x601c, 0x1990,
+ 0x601d, 0x0720,
+ 0x601e, 0x1986,
+ 0x6020, 0x0721,
+ 0x6021, 0x05cb,
+ 0x6022, 0x1988,
+ 0x6023, 0x4185,
+ 0x6024, 0x1ae7,
+ 0x6025, 0x0722,
+ 0x6026, 0x197d,
+ 0x6027, 0x05cc,
+ 0x6028, 0x0724,
+ 0x6029, 0x05cd,
+ 0x602a, 0x05c9,
+ 0x602b, 0x05ce,
+ 0x602c, 0x1987,
+ 0x602d, 0x197c,
+ 0x602e, 0x198b,
+ 0x602f, 0x05c6,
+ 0x6031, 0x4161,
+ 0x6032, 0x197f,
+ 0x6033, 0x1984,
+ 0x6034, 0x1981,
+ 0x6035, 0x05c7,
+ 0x6037, 0x1ad9,
+ 0x6039, 0x1ada,
+ 0x603b, 0x4553,
+ 0x6040, 0x1ae4,
+ 0x6041, 0x1c92,
+ 0x6042, 0x1ae5,
+ 0x6043, 0x072a,
+ 0x6044, 0x1ae8,
+ 0x6045, 0x1ade,
+ 0x6046, 0x0729,
+ 0x6047, 0x1ae0,
+ 0x6049, 0x1ae1,
+ 0x604a, 0x4074,
+ 0x604c, 0x1ae3,
+ 0x604d, 0x0725,
+ 0x6050, 0x08b5,
+ 0x6052, 0x36ec,
+ 0x6053, 0x1adf,
+ 0x6054, 0x1adb,
+ 0x6055, 0x08b6,
+ 0x6058, 0x1ae9,
+ 0x6059, 0x08b2,
+ 0x605a, 0x1c90,
+ 0x605b, 0x1ae2,
+ 0x605d, 0x1c8f,
+ 0x605e, 0x1add,
+ 0x605f, 0x1ae6,
+ 0x6062, 0x0728,
+ 0x6063, 0x08b3,
+ 0x6064, 0x072e,
+ 0x6065, 0x08b4,
+ 0x6066, 0x1aea,
+ 0x6067, 0x1c91,
+ 0x6068, 0x0727,
+ 0x6069, 0x08b8,
+ 0x606a, 0x072d,
+ 0x606b, 0x072c,
+ 0x606c, 0x072b,
+ 0x606d, 0x08b7,
+ 0x606e, 0x1aeb,
+ 0x606f, 0x08b9,
+ 0x6070, 0x0726,
+ 0x6072, 0x1adc,
+ 0x6075, 0x3a56,
+ 0x6077, 0x4005,
+ 0x607e, 0x3a47,
+ 0x607f, 0x0a82,
+ 0x6080, 0x1c95,
+ 0x6081, 0x1c97,
+ 0x6083, 0x1c99,
+ 0x6084, 0x08ba,
+ 0x6085, 0x08c0,
+ 0x6086, 0x1eda,
+ 0x6087, 0x1c9d,
+ 0x6088, 0x1c94,
+ 0x6089, 0x0a84,
+ 0x608a, 0x1ed8,
+ 0x608c, 0x08bf,
+ 0x608d, 0x08bd,
+ 0x608e, 0x1c9f,
+ 0x6090, 0x1ed9,
+ 0x6092, 0x1c96,
+ 0x6094, 0x08be,
+ 0x6095, 0x1c9a,
+ 0x6096, 0x08c1,
+ 0x6097, 0x1c9c,
+ 0x609a, 0x08bc,
+ 0x609b, 0x1c9b,
+ 0x609c, 0x1c9e,
+ 0x609d, 0x1c98,
+ 0x609e, 0x416a,
+ 0x609f, 0x08bb,
+ 0x60a0, 0x0a85,
+ 0x60a2, 0x1c93,
+ 0x60a3, 0x0a83,
+ 0x60a4, 0x4001,
+ 0x60a7, 0x3adc,
+ 0x60a8, 0x0a86,
+ 0x60b0, 0x1edc,
+ 0x60b1, 0x1ee5,
+ 0x60b2, 0x0c47,
+ 0x60b3, 0x416c,
+ 0x60b4, 0x0a88,
+ 0x60b5, 0x0a8d,
+ 0x60b6, 0x0c48,
+ 0x60b7, 0x1ee7,
+ 0x60b8, 0x0a94,
+ 0x60b9, 0x2134,
+ 0x60ba, 0x1edd,
+ 0x60bb, 0x0a8c,
+ 0x60bc, 0x0a8f,
+ 0x60bd, 0x0a8a,
+ 0x60be, 0x1edb,
+ 0x60bf, 0x1ee9,
+ 0x60c0, 0x1eec,
+ 0x60c1, 0x2143,
+ 0x60c3, 0x1eea,
+ 0x60c4, 0x2138,
+ 0x60c5, 0x0a8b,
+ 0x60c6, 0x0a92,
+ 0x60c7, 0x0a96,
+ 0x60c8, 0x1ee4,
+ 0x60c9, 0x2133,
+ 0x60ca, 0x1ee8,
+ 0x60cb, 0x0a87,
+ 0x60cc, 0x2135,
+ 0x60cd, 0x1eeb,
+ 0x60ce, 0x2137,
+ 0x60cf, 0x1ee0,
+ 0x60d1, 0x0c45,
+ 0x60d3, 0x1ede,
+ 0x60d5, 0x0a91,
+ 0x60d7, 0x4635,
+ 0x60d8, 0x0a90,
+ 0x60d9, 0x1ee2,
+ 0x60da, 0x0a95,
+ 0x60db, 0x1ee6,
+ 0x60dc, 0x0a8e,
+ 0x60dd, 0x1ee3,
+ 0x60de, 0x3dcc,
+ 0x60df, 0x0a93,
+ 0x60e0, 0x0c49,
+ 0x60e1, 0x0c46,
+ 0x60e2, 0x2136,
+ 0x60e3, 0x3d75,
+ 0x60e4, 0x1ee1,
+ 0x60e6, 0x0a89,
+ 0x60e7, 0x3d84,
+ 0x60e8, 0x3d7b,
+ 0x60e9, 0x4009,
+ 0x60f0, 0x0c4e,
+ 0x60f1, 0x0c52,
+ 0x60f2, 0x213a,
+ 0x60f3, 0x0e0b,
+ 0x60f4, 0x0c50,
+ 0x60f5, 0x213e,
+ 0x60f6, 0x0c54,
+ 0x60f7, 0x23d4,
+ 0x60f8, 0x2140,
+ 0x60f9, 0x0e0d,
+ 0x60fa, 0x0c4c,
+ 0x60fb, 0x0c4f,
+ 0x60fc, 0x2141,
+ 0x60fd, 0x3fa8,
+ 0x60fe, 0x2142,
+ 0x60ff, 0x2148,
+ 0x6100, 0x0c56,
+ 0x6101, 0x0e0e,
+ 0x6103, 0x2144,
+ 0x6104, 0x2149,
+ 0x6105, 0x213d,
+ 0x6106, 0x0e18,
+ 0x6107, 0x3c35,
+ 0x6108, 0x0e0f,
+ 0x6109, 0x0c55,
+ 0x610a, 0x213b,
+ 0x610b, 0x214a,
+ 0x610c, 0x3c87,
+ 0x610d, 0x0e17,
+ 0x610e, 0x0c53,
+ 0x610f, 0x0e08,
+ 0x6110, 0x2147,
+ 0x6112, 0x0c57,
+ 0x6113, 0x213f,
+ 0x6114, 0x2139,
+ 0x6115, 0x0c4d,
+ 0x6116, 0x213c,
+ 0x6118, 0x2145,
+ 0x6119, 0x3ef6,
+ 0x611a, 0x0e07,
+ 0x611b, 0x0e0c,
+ 0x611c, 0x0c4a,
+ 0x611d, 0x2146,
+ 0x611f, 0x0e0a,
+ 0x6123, 0x0c4b,
+ 0x6127, 0x0e16,
+ 0x6128, 0x2683,
+ 0x6129, 0x23df,
+ 0x612b, 0x23d7,
+ 0x612c, 0x2682,
+ 0x612e, 0x23db,
+ 0x612f, 0x23dd,
+ 0x6130, 0x3f37,
+ 0x6132, 0x23da,
+ 0x6134, 0x0e15,
+ 0x6136, 0x23d9,
+ 0x6137, 0x0e19,
+ 0x613b, 0x2692,
+ 0x613d, 0x4636,
+ 0x613e, 0x0e14,
+ 0x613f, 0x0fd1,
+ 0x6140, 0x23e0,
+ 0x6141, 0x2684,
+ 0x6142, 0x4174,
+ 0x6144, 0x0e12,
+ 0x6145, 0x23d8,
+ 0x6146, 0x23dc,
+ 0x6147, 0x0fd0,
+ 0x6148, 0x0e09,
+ 0x6149, 0x23d5,
+ 0x614b, 0x0fd2,
+ 0x614c, 0x0e11,
+ 0x614d, 0x0e13,
+ 0x614e, 0x0e10,
+ 0x614f, 0x23de,
+ 0x6150, 0x3c32,
+ 0x6152, 0x2688,
+ 0x6154, 0x268e,
+ 0x6155, 0x1149,
+ 0x6156, 0x2695,
+ 0x6158, 0x0fd8,
+ 0x6159, 0x3fba,
+ 0x615a, 0x0fd7,
+ 0x615b, 0x2690,
+ 0x615c, 0x4186,
+ 0x615d, 0x1148,
+ 0x615e, 0x2685,
+ 0x615f, 0x0fd6,
+ 0x6160, 0x494c,
+ 0x6161, 0x2694,
+ 0x6162, 0x0fd4,
+ 0x6164, 0x4173,
+ 0x6165, 0x2691,
+ 0x6166, 0x28de,
+ 0x6167, 0x1146,
+ 0x6168, 0x0c51,
+ 0x616a, 0x2693,
+ 0x616b, 0x114d,
+ 0x616c, 0x268b,
+ 0x616e, 0x1147,
+ 0x616f, 0x3fc0,
+ 0x6170, 0x114c,
+ 0x6171, 0x2686,
+ 0x6172, 0x268a,
+ 0x6173, 0x2687,
+ 0x6174, 0x268d,
+ 0x6175, 0x0fd9,
+ 0x6176, 0x1145,
+ 0x6177, 0x0fd3,
+ 0x6179, 0x28d0,
+ 0x617a, 0x268f,
+ 0x617c, 0x114b,
+ 0x617d, 0x3fbd,
+ 0x617e, 0x114e,
+ 0x6180, 0x268c,
+ 0x6181, 0x4177,
+ 0x6182, 0x114a,
+ 0x6183, 0x28cf,
+ 0x6187, 0x417a,
+ 0x6189, 0x28d4,
+ 0x618a, 0x12b1,
+ 0x618b, 0x28ce,
+ 0x618c, 0x2b4d,
+ 0x618d, 0x28dd,
+ 0x618e, 0x1152,
+ 0x6190, 0x1150,
+ 0x6191, 0x12af,
+ 0x6192, 0x28da,
+ 0x6193, 0x28d6,
+ 0x6194, 0x1156,
+ 0x6195, 0x3de0,
+ 0x6196, 0x2b44,
+ 0x6198, 0x3a55,
+ 0x6199, 0x3a54,
+ 0x619a, 0x1154,
+ 0x619b, 0x28d5,
+ 0x619c, 0x4002,
+ 0x619d, 0x2b42,
+ 0x619f, 0x28d9,
+ 0x61a1, 0x28dc,
+ 0x61a2, 0x28d3,
+ 0x61a4, 0x1155,
+ 0x61a7, 0x114f,
+ 0x61a8, 0x2b43,
+ 0x61a9, 0x12b0,
+ 0x61aa, 0x28db,
+ 0x61ab, 0x1151,
+ 0x61ac, 0x1153,
+ 0x61ad, 0x28d8,
+ 0x61ae, 0x1157,
+ 0x61af, 0x28d7,
+ 0x61b0, 0x28d2,
+ 0x61b1, 0x28d1,
+ 0x61b2, 0x12ae,
+ 0x61b3, 0x28df,
+ 0x61b4, 0x2b46,
+ 0x61b5, 0x2d60,
+ 0x61b6, 0x12b3,
+ 0x61b7, 0x4639,
+ 0x61b8, 0x2b4c,
+ 0x61b9, 0x43bf,
+ 0x61ba, 0x2b4a,
+ 0x61bc, 0x2d61,
+ 0x61be, 0x12b4,
+ 0x61bf, 0x2b4b,
+ 0x61c0, 0x3a50,
+ 0x61c1, 0x2b48,
+ 0x61c2, 0x13d1,
+ 0x61c3, 0x2d5f,
+ 0x61c5, 0x2b45,
+ 0x61c6, 0x2b47,
+ 0x61c7, 0x13d2,
+ 0x61c8, 0x12b6,
+ 0x61c9, 0x13d0,
+ 0x61ca, 0x12b5,
+ 0x61cb, 0x13d4,
+ 0x61cc, 0x2b49,
+ 0x61cd, 0x12b2,
+ 0x61cf, 0x463a,
+ 0x61d0, 0x4181,
+ 0x61d3, 0x417e,
+ 0x61d6, 0x2f26,
+ 0x61d8, 0x2f1e,
+ 0x61da, 0x38b1,
+ 0x61de, 0x2d67,
+ 0x61df, 0x2f1f,
+ 0x61e0, 0x2d63,
+ 0x61e2, 0x3fc5,
+ 0x61e3, 0x14d0,
+ 0x61e4, 0x2d65,
+ 0x61e5, 0x2d64,
+ 0x61e6, 0x13d3,
+ 0x61e7, 0x2d62,
+ 0x61e8, 0x2d66,
+ 0x61e9, 0x2f27,
+ 0x61ea, 0x2f23,
+ 0x61eb, 0x2f25,
+ 0x61ed, 0x2f20,
+ 0x61f0, 0x2f24,
+ 0x61f1, 0x2f22,
+ 0x61f2, 0x157e,
+ 0x61f5, 0x1581,
+ 0x61f6, 0x1580,
+ 0x61f7, 0x157f,
+ 0x61f8, 0x1614,
+ 0x61f9, 0x31d3,
+ 0x61fa, 0x1615,
+ 0x61fb, 0x308f,
+ 0x61fc, 0x1670,
+ 0x61fd, 0x32d1,
+ 0x61fe, 0x1671,
+ 0x61ff, 0x16c4,
+ 0x6200, 0x16f8,
+ 0x6201, 0x3417,
+ 0x6203, 0x3418,
+ 0x6207, 0x3533,
+ 0x6208, 0x02d1,
+ 0x6209, 0x17a8,
+ 0x620a, 0x0341,
+ 0x620c, 0x03d1,
+ 0x620e, 0x03d0,
+ 0x6210, 0x03d3,
+ 0x6211, 0x04a2,
+ 0x6212, 0x04a1,
+ 0x6214, 0x1991,
+ 0x6215, 0x05d1,
+ 0x6216, 0x05d0,
+ 0x6219, 0x1ca0,
+ 0x621a, 0x0a97,
+ 0x621f, 0x0c58,
+ 0x6220, 0x23e1,
+ 0x6221, 0x0e1a,
+ 0x6223, 0x23e3,
+ 0x6224, 0x23e5,
+ 0x6225, 0x23e4,
+ 0x6227, 0x2697,
+ 0x6229, 0x2696,
+ 0x622a, 0x0fda,
+ 0x622b, 0x2698,
+ 0x622c, 0x463c,
+ 0x622d, 0x28e0,
+ 0x622e, 0x1158,
+ 0x6230, 0x12b7,
+ 0x6232, 0x13d5,
+ 0x6233, 0x14d1,
+ 0x6234, 0x13d6,
+ 0x6236, 0x02d2,
+ 0x6237, 0x451a,
+ 0x6239, 0x3fc2,
+ 0x623a, 0x188d,
+ 0x623d, 0x1992,
+ 0x623e, 0x05d3,
+ 0x623f, 0x05d2,
+ 0x6240, 0x05d4,
+ 0x6241, 0x072f,
+ 0x6242, 0x1aec,
+ 0x6246, 0x1ca1,
+ 0x6247, 0x08c2,
+ 0x6248, 0x0a99,
+ 0x6249, 0x0c59,
+ 0x624a, 0x214b,
+ 0x624b, 0x02d3,
+ 0x624c, 0x44ec,
+ 0x624d, 0x0291,
+ 0x624e, 0x02d4,
+ 0x6250, 0x17a9,
+ 0x6251, 0x0345,
+ 0x6252, 0x0344,
+ 0x6253, 0x0342,
+ 0x6258, 0x03d6,
+ 0x6259, 0x17f2,
+ 0x625a, 0x17f4,
+ 0x625b, 0x03d5,
+ 0x625c, 0x17ec,
+ 0x625e, 0x17ed,
+ 0x6260, 0x17f3,
+ 0x6261, 0x17ef,
+ 0x6262, 0x17f1,
+ 0x6263, 0x03d4,
+ 0x6264, 0x17ee,
+ 0x6265, 0x17f5,
+ 0x6266, 0x17f0,
+ 0x6268, 0x3f15,
+ 0x626d, 0x04a9,
+ 0x626e, 0x04b2,
+ 0x626f, 0x04b0,
+ 0x6270, 0x1897,
+ 0x6271, 0x1894,
+ 0x6272, 0x189c,
+ 0x6273, 0x04ae,
+ 0x6274, 0x189d,
+ 0x6276, 0x04a7,
+ 0x6277, 0x189a,
+ 0x6279, 0x04ad,
+ 0x627a, 0x1896,
+ 0x627b, 0x1895,
+ 0x627c, 0x04ab,
+ 0x627d, 0x189b,
+ 0x627e, 0x04ac,
+ 0x627f, 0x05d5,
+ 0x6280, 0x04a6,
+ 0x6281, 0x1898,
+ 0x6282, 0x3f86,
+ 0x6283, 0x188e,
+ 0x6284, 0x04a3,
+ 0x6285, 0x3f50,
+ 0x6286, 0x04b6,
+ 0x6287, 0x1893,
+ 0x6288, 0x1899,
+ 0x6289, 0x04a8,
+ 0x628a, 0x04aa,
+ 0x628c, 0x188f,
+ 0x628e, 0x1890,
+ 0x6290, 0x43c0,
+ 0x6291, 0x04b5,
+ 0x6292, 0x04af,
+ 0x6293, 0x04b4,
+ 0x6294, 0x1892,
+ 0x6295, 0x04b3,
+ 0x6296, 0x04a5,
+ 0x6297, 0x04a4,
+ 0x6298, 0x04b1,
+ 0x629d, 0x3e96,
+ 0x62a4, 0x3a69,
+ 0x62a6, 0x3fc1,
+ 0x62a8, 0x05e3,
+ 0x62a9, 0x199e,
+ 0x62aa, 0x1997,
+ 0x62ab, 0x05de,
+ 0x62ac, 0x05f1,
+ 0x62ad, 0x1993,
+ 0x62ae, 0x199a,
+ 0x62af, 0x199c,
+ 0x62b0, 0x199f,
+ 0x62b1, 0x05ec,
+ 0x62b3, 0x199b,
+ 0x62b4, 0x1994,
+ 0x62b5, 0x05ea,
+ 0x62b6, 0x1998,
+ 0x62b8, 0x19a0,
+ 0x62b9, 0x05db,
+ 0x62bb, 0x199d,
+ 0x62bc, 0x05e5,
+ 0x62bd, 0x05e4,
+ 0x62be, 0x1996,
+ 0x62bf, 0x05d9,
+ 0x62c2, 0x05da,
+ 0x62c3, 0x3d8f,
+ 0x62c4, 0x05d8,
+ 0x62c5, 0x418a,
+ 0x62c6, 0x05f0,
+ 0x62c7, 0x05e8,
+ 0x62c8, 0x05e2,
+ 0x62c9, 0x05d6,
+ 0x62ca, 0x1999,
+ 0x62cb, 0x05e1,
+ 0x62cc, 0x05d7,
+ 0x62cd, 0x05e9,
+ 0x62ce, 0x05f2,
+ 0x62cf, 0x1aee,
+ 0x62d0, 0x05e6,
+ 0x62d1, 0x1995,
+ 0x62d2, 0x05dc,
+ 0x62d3, 0x05df,
+ 0x62d5, 0x418c,
+ 0x62d6, 0x05ee,
+ 0x62d8, 0x05ed,
+ 0x62d9, 0x05e7,
+ 0x62da, 0x05eb,
+ 0x62db, 0x05dd,
+ 0x62dc, 0x0730,
+ 0x62df, 0x401c,
+ 0x62e5, 0x463d,
+ 0x62eb, 0x1af4,
+ 0x62ec, 0x073c,
+ 0x62ed, 0x0734,
+ 0x62ee, 0x0736,
+ 0x62ef, 0x073b,
+ 0x62f0, 0x1b00,
+ 0x62f1, 0x0739,
+ 0x62f2, 0x1ca2,
+ 0x62f3, 0x08c3,
+ 0x62f4, 0x073e,
+ 0x62f5, 0x1af1,
+ 0x62f6, 0x1af9,
+ 0x62f7, 0x073a,
+ 0x62f8, 0x1af8,
+ 0x62f9, 0x1af5,
+ 0x62fa, 0x1afd,
+ 0x62fb, 0x1aff,
+ 0x62fc, 0x0733,
+ 0x62fd, 0x0737,
+ 0x62fe, 0x073d,
+ 0x62ff, 0x08c5,
+ 0x6300, 0x1afa,
+ 0x6301, 0x0735,
+ 0x6302, 0x0740,
+ 0x6303, 0x1af3,
+ 0x6307, 0x0738,
+ 0x6308, 0x08c4,
+ 0x6309, 0x0732,
+ 0x630b, 0x1af0,
+ 0x630c, 0x1af7,
+ 0x630d, 0x1aef,
+ 0x630e, 0x1af2,
+ 0x630f, 0x1af6,
+ 0x6310, 0x1ca3,
+ 0x6311, 0x073f,
+ 0x6313, 0x1afb,
+ 0x6315, 0x1afe,
+ 0x6316, 0x0731,
+ 0x6318, 0x43c1,
+ 0x6328, 0x08d3,
+ 0x6329, 0x1caf,
+ 0x632a, 0x08d1,
+ 0x632c, 0x1ca5,
+ 0x632d, 0x1cb5,
+ 0x632e, 0x3edd,
+ 0x632f, 0x08c8,
+ 0x6331, 0x3a65,
+ 0x6332, 0x1eed,
+ 0x6333, 0x1cb7,
+ 0x6334, 0x1cb1,
+ 0x6335, 0x3f16,
+ 0x6336, 0x1ca8,
+ 0x6337, 0x3a63,
+ 0x6338, 0x1cba,
+ 0x6339, 0x1cab,
+ 0x633a, 0x08ce,
+ 0x633b, 0x1f04,
+ 0x633c, 0x1cae,
+ 0x633d, 0x08d0,
+ 0x633e, 0x08c7,
+ 0x6340, 0x1cbc,
+ 0x6341, 0x1cb0,
+ 0x6342, 0x08ca,
+ 0x6343, 0x1ca9,
+ 0x6344, 0x1ca6,
+ 0x6346, 0x08cb,
+ 0x6347, 0x1cb6,
+ 0x6348, 0x1cbd,
+ 0x6349, 0x08cd,
+ 0x634a, 0x1cad,
+ 0x634b, 0x1cac,
+ 0x634c, 0x08d5,
+ 0x634d, 0x08d4,
+ 0x634e, 0x08c6,
+ 0x634f, 0x08cc,
+ 0x6350, 0x08cf,
+ 0x6351, 0x1cb9,
+ 0x6354, 0x1cb3,
+ 0x6355, 0x08c9,
+ 0x6356, 0x1ca4,
+ 0x6357, 0x1cbb,
+ 0x6358, 0x1cb2,
+ 0x6359, 0x1cb4,
+ 0x635a, 0x1cb8,
+ 0x6364, 0x3fc7,
+ 0x6365, 0x1eee,
+ 0x6367, 0x0aa1,
+ 0x6368, 0x0ab5,
+ 0x6369, 0x0ab4,
+ 0x636b, 0x0aa9,
+ 0x636c, 0x418e,
+ 0x636d, 0x1f00,
+ 0x636e, 0x1efc,
+ 0x636f, 0x1ef9,
+ 0x6370, 0x1f0b,
+ 0x6371, 0x0aa4,
+ 0x6372, 0x0a9c,
+ 0x6375, 0x1efe,
+ 0x6376, 0x0c69,
+ 0x6377, 0x0aa0,
+ 0x6378, 0x1f06,
+ 0x6379, 0x4367,
+ 0x637a, 0x0ab6,
+ 0x637b, 0x0ab3,
+ 0x637c, 0x1f02,
+ 0x637d, 0x1ef1,
+ 0x637f, 0x3f4b,
+ 0x6380, 0x0ab2,
+ 0x6381, 0x1f08,
+ 0x6382, 0x1ef0,
+ 0x6383, 0x0aa7,
+ 0x6384, 0x0aab,
+ 0x6385, 0x1f07,
+ 0x6387, 0x1efa,
+ 0x6388, 0x0aac,
+ 0x6389, 0x0aa6,
+ 0x638a, 0x1eef,
+ 0x638b, 0x4188,
+ 0x638c, 0x0c5b,
+ 0x638d, 0x1f0a,
+ 0x638e, 0x1ef8,
+ 0x638f, 0x0ab1,
+ 0x6390, 0x1efb,
+ 0x6391, 0x1f09,
+ 0x6392, 0x0ab0,
+ 0x6394, 0x214c,
+ 0x6396, 0x0a9d,
+ 0x6397, 0x1ef6,
+ 0x6398, 0x0aa2,
+ 0x6399, 0x0aad,
+ 0x639b, 0x0aa8,
+ 0x639c, 0x1eff,
+ 0x639d, 0x1ef5,
+ 0x639e, 0x1ef3,
+ 0x639f, 0x1f05,
+ 0x63a0, 0x0a9a,
+ 0x63a1, 0x0aae,
+ 0x63a2, 0x0a9e,
+ 0x63a3, 0x0c5a,
+ 0x63a4, 0x1f03,
+ 0x63a5, 0x0a9f,
+ 0x63a7, 0x0a9b,
+ 0x63a8, 0x0aaa,
+ 0x63a9, 0x0aa5,
+ 0x63aa, 0x0aa3,
+ 0x63ab, 0x1ef7,
+ 0x63ac, 0x0aaf,
+ 0x63ad, 0x1ef4,
+ 0x63ae, 0x1f01,
+ 0x63af, 0x1efd,
+ 0x63b0, 0x214e,
+ 0x63b1, 0x214d,
+ 0x63b9, 0x3e9d,
+ 0x63bd, 0x1ef2,
+ 0x63be, 0x215e,
+ 0x63c0, 0x0c5d,
+ 0x63c1, 0x46a8,
+ 0x63c2, 0x2164,
+ 0x63c3, 0x2153,
+ 0x63c4, 0x2161,
+ 0x63c5, 0x23e6,
+ 0x63c6, 0x0c60,
+ 0x63c7, 0x2165,
+ 0x63c8, 0x2168,
+ 0x63c9, 0x0c5f,
+ 0x63ca, 0x2156,
+ 0x63cb, 0x2167,
+ 0x63cc, 0x2166,
+ 0x63cd, 0x0c61,
+ 0x63ce, 0x214f,
+ 0x63cf, 0x0c5c,
+ 0x63d0, 0x0c64,
+ 0x63d1, 0x3a66,
+ 0x63d2, 0x0c62,
+ 0x63d3, 0x2163,
+ 0x63d5, 0x2159,
+ 0x63d6, 0x0c66,
+ 0x63d7, 0x216a,
+ 0x63d8, 0x2162,
+ 0x63d9, 0x216b,
+ 0x63da, 0x0c6e,
+ 0x63db, 0x0c6c,
+ 0x63dc, 0x2160,
+ 0x63dd, 0x215f,
+ 0x63de, 0x3e60,
+ 0x63df, 0x215d,
+ 0x63e0, 0x2157,
+ 0x63e1, 0x0c65,
+ 0x63e2, 0x4641,
+ 0x63e3, 0x0c63,
+ 0x63e4, 0x1caa,
+ 0x63e5, 0x2150,
+ 0x63e6, 0x489f,
+ 0x63e7, 0x2404,
+ 0x63e8, 0x2151,
+ 0x63e9, 0x0c5e,
+ 0x63ea, 0x0c6b,
+ 0x63eb, 0x23e8,
+ 0x63ed, 0x0c67,
+ 0x63ef, 0x2152,
+ 0x63f0, 0x2169,
+ 0x63f1, 0x23e7,
+ 0x63f2, 0x215a,
+ 0x63f3, 0x2155,
+ 0x63f4, 0x0c6a,
+ 0x63f5, 0x215b,
+ 0x63f6, 0x2158,
+ 0x63f8, 0x4192,
+ 0x63f9, 0x0c6f,
+ 0x63fb, 0x4642,
+ 0x63fc, 0x3e9c,
+ 0x63fe, 0x3e9e,
+ 0x6406, 0x0e2a,
+ 0x6407, 0x4643,
+ 0x6409, 0x23eb,
+ 0x640a, 0x23fe,
+ 0x640b, 0x2403,
+ 0x640c, 0x23f7,
+ 0x640d, 0x0e26,
+ 0x640e, 0x2408,
+ 0x640f, 0x0e23,
+ 0x6410, 0x23e9,
+ 0x6412, 0x23ea,
+ 0x6413, 0x0e1c,
+ 0x6414, 0x0e25,
+ 0x6415, 0x23f1,
+ 0x6416, 0x0e28,
+ 0x6418, 0x23f2,
+ 0x641a, 0x23ff,
+ 0x641b, 0x2405,
+ 0x641c, 0x0e24,
+ 0x641e, 0x0e1e,
+ 0x641f, 0x23f0,
+ 0x6420, 0x23ec,
+ 0x6421, 0x2407,
+ 0x6422, 0x23f5,
+ 0x6424, 0x23ed,
+ 0x6425, 0x2401,
+ 0x6426, 0x23f8,
+ 0x6427, 0x2402,
+ 0x6428, 0x23fa,
+ 0x642a, 0x0e1f,
+ 0x642b, 0x2699,
+ 0x642c, 0x0e22,
+ 0x642d, 0x0e20,
+ 0x642e, 0x2406,
+ 0x642f, 0x23fd,
+ 0x6430, 0x23f9,
+ 0x6432, 0x45d9,
+ 0x6433, 0x23ee,
+ 0x6434, 0x0fe4,
+ 0x6435, 0x23fc,
+ 0x6436, 0x0e27,
+ 0x6437, 0x23f4,
+ 0x6438, 0x4191,
+ 0x6439, 0x23f3,
+ 0x643a, 0x419d,
+ 0x643b, 0x3a6b,
+ 0x643d, 0x0e21,
+ 0x643e, 0x0e1d,
+ 0x643f, 0x26ae,
+ 0x6440, 0x2400,
+ 0x6441, 0x23fb,
+ 0x6443, 0x23ef,
+ 0x644b, 0x26a9,
+ 0x644d, 0x269a,
+ 0x644e, 0x26a5,
+ 0x6450, 0x26ac,
+ 0x6451, 0x0fe2,
+ 0x6452, 0x0c6d,
+ 0x6453, 0x26aa,
+ 0x6454, 0x0fdd,
+ 0x6458, 0x0fdc,
+ 0x6459, 0x26b1,
+ 0x645a, 0x43c2,
+ 0x645b, 0x269b,
+ 0x645c, 0x26a8,
+ 0x645d, 0x269c,
+ 0x645e, 0x26a7,
+ 0x645f, 0x0fe0,
+ 0x6460, 0x26ab,
+ 0x6461, 0x215c,
+ 0x6465, 0x26b2,
+ 0x6466, 0x26a3,
+ 0x6467, 0x0fe3,
+ 0x6468, 0x28ee,
+ 0x6469, 0x1159,
+ 0x646b, 0x26b0,
+ 0x646c, 0x26af,
+ 0x646d, 0x0fe5,
+ 0x646e, 0x28e1,
+ 0x646f, 0x115a,
+ 0x6470, 0x28e2,
+ 0x6471, 0x3a5b,
+ 0x6472, 0x269f,
+ 0x6474, 0x269d,
+ 0x6475, 0x26a2,
+ 0x6476, 0x269e,
+ 0x6477, 0x26b3,
+ 0x6478, 0x0fdf,
+ 0x6479, 0x115b,
+ 0x647a, 0x0fe1,
+ 0x647b, 0x0fe6,
+ 0x647c, 0x436c,
+ 0x647d, 0x26a1,
+ 0x647f, 0x26ad,
+ 0x6482, 0x26a6,
+ 0x6485, 0x28e5,
+ 0x6487, 0x0fdb,
+ 0x6488, 0x115e,
+ 0x6489, 0x2b54,
+ 0x648a, 0x28ea,
+ 0x648b, 0x28e9,
+ 0x648c, 0x28eb,
+ 0x648d, 0x4323,
+ 0x648f, 0x28e8,
+ 0x6490, 0x115f,
+ 0x6491, 0x43c3,
+ 0x6492, 0x1165,
+ 0x6493, 0x1162,
+ 0x6495, 0x1163,
+ 0x6496, 0x28e3,
+ 0x6497, 0x28e6,
+ 0x6498, 0x28f0,
+ 0x6499, 0x116b,
+ 0x649a, 0x1169,
+ 0x649c, 0x28e7,
+ 0x649d, 0x2154,
+ 0x649e, 0x115c,
+ 0x649f, 0x28ed,
+ 0x64a0, 0x28e4,
+ 0x64a2, 0x116c,
+ 0x64a3, 0x28ec,
+ 0x64a4, 0x0fde,
+ 0x64a5, 0x1161,
+ 0x64a6, 0x26a4,
+ 0x64a9, 0x1164,
+ 0x64ab, 0x1168,
+ 0x64ac, 0x116a,
+ 0x64ad, 0x1167,
+ 0x64ae, 0x1166,
+ 0x64af, 0x42e1,
+ 0x64b0, 0x1160,
+ 0x64b1, 0x28ef,
+ 0x64b2, 0x115d,
+ 0x64b3, 0x116d,
+ 0x64b4, 0x4340,
+ 0x64b6, 0x3a64,
+ 0x64bb, 0x12bb,
+ 0x64bd, 0x2b53,
+ 0x64be, 0x12c5,
+ 0x64bf, 0x12c2,
+ 0x64c0, 0x4645,
+ 0x64c1, 0x12b9,
+ 0x64c2, 0x12c0,
+ 0x64c3, 0x2b55,
+ 0x64c4, 0x12be,
+ 0x64c5, 0x12b8,
+ 0x64c7, 0x12bf,
+ 0x64c9, 0x2b52,
+ 0x64ca, 0x13d8,
+ 0x64cb, 0x12ba,
+ 0x64cd, 0x12c1,
+ 0x64ce, 0x13d7,
+ 0x64cf, 0x2b51,
+ 0x64d0, 0x2b50,
+ 0x64d2, 0x12c3,
+ 0x64d3, 0x3f03,
+ 0x64d4, 0x12c4,
+ 0x64d6, 0x2b4f,
+ 0x64d7, 0x2b4e,
+ 0x64d8, 0x13d9,
+ 0x64d9, 0x2b58,
+ 0x64da, 0x12bd,
+ 0x64db, 0x2b56,
+ 0x64dd, 0x431e,
+ 0x64e0, 0x13da,
+ 0x64e1, 0x4199,
+ 0x64e2, 0x13df,
+ 0x64e3, 0x2d6a,
+ 0x64e4, 0x2d6c,
+ 0x64e5, 0x419a,
+ 0x64e6, 0x13dc,
+ 0x64e7, 0x37a8,
+ 0x64e8, 0x2d6d,
+ 0x64e9, 0x2d69,
+ 0x64ea, 0x434a,
+ 0x64eb, 0x2d6b,
+ 0x64ec, 0x13dd,
+ 0x64ed, 0x13e0,
+ 0x64ef, 0x2d68,
+ 0x64f0, 0x13db,
+ 0x64f1, 0x13de,
+ 0x64f2, 0x14d3,
+ 0x64f3, 0x2b57,
+ 0x64f4, 0x14d2,
+ 0x64f7, 0x14d8,
+ 0x64f8, 0x2f2b,
+ 0x64fa, 0x14d6,
+ 0x64fc, 0x2f2e,
+ 0x64fd, 0x2f2a,
+ 0x64fe, 0x14d4,
+ 0x64ff, 0x2f28,
+ 0x6500, 0x1582,
+ 0x6501, 0x2f2c,
+ 0x6503, 0x2f2d,
+ 0x6504, 0x2f29,
+ 0x6506, 0x14d5,
+ 0x6507, 0x3090,
+ 0x6509, 0x3093,
+ 0x650a, 0x4536,
+ 0x650c, 0x3094,
+ 0x650d, 0x3092,
+ 0x650e, 0x3095,
+ 0x650f, 0x1583,
+ 0x6510, 0x3091,
+ 0x6511, 0x3aa9,
+ 0x6513, 0x31d7,
+ 0x6514, 0x1617,
+ 0x6515, 0x31d6,
+ 0x6516, 0x31d5,
+ 0x6517, 0x31d4,
+ 0x6518, 0x1616,
+ 0x6519, 0x1618,
+ 0x651b, 0x32d2,
+ 0x651c, 0x1673,
+ 0x651d, 0x1672,
+ 0x651e, 0x4187,
+ 0x651f, 0x3ec0,
+ 0x6520, 0x3382,
+ 0x6521, 0x3381,
+ 0x6522, 0x3384,
+ 0x6523, 0x16f9,
+ 0x6524, 0x16c5,
+ 0x6525, 0x341b,
+ 0x6526, 0x3383,
+ 0x6529, 0x341a,
+ 0x652a, 0x16fb,
+ 0x652b, 0x16fa,
+ 0x652c, 0x1721,
+ 0x652d, 0x3484,
+ 0x652e, 0x34ca,
+ 0x652f, 0x02d5,
+ 0x6530, 0x3e62,
+ 0x6532, 0x216c,
+ 0x6533, 0x2b59,
+ 0x6534, 0x022c,
+ 0x6535, 0x44ed,
+ 0x6536, 0x03d7,
+ 0x6537, 0x17f6,
+ 0x6538, 0x04b9,
+ 0x6539, 0x04b7,
+ 0x653b, 0x04b8,
+ 0x653d, 0x19a1,
+ 0x653e, 0x05f3,
+ 0x653f, 0x0741,
+ 0x6541, 0x1b01,
+ 0x6543, 0x1b02,
+ 0x6545, 0x0742,
+ 0x6546, 0x1cbf,
+ 0x6548, 0x08d6,
+ 0x654a, 0x1cbe,
+ 0x654d, 0x419f,
+ 0x654f, 0x0abd,
+ 0x6551, 0x0ab9,
+ 0x6553, 0x1f0c,
+ 0x6554, 0x0ac0,
+ 0x6555, 0x0abf,
+ 0x6556, 0x0ab8,
+ 0x6557, 0x0abb,
+ 0x6558, 0x0abe,
+ 0x6559, 0x0aba,
+ 0x655c, 0x2170,
+ 0x655d, 0x0ab7,
+ 0x655e, 0x0c70,
+ 0x655f, 0x41a5,
+ 0x6562, 0x0c72,
+ 0x6564, 0x216f,
+ 0x6565, 0x2172,
+ 0x6566, 0x0c71,
+ 0x6567, 0x216d,
+ 0x6568, 0x2171,
+ 0x656a, 0x216e,
+ 0x656b, 0x3a6c,
+ 0x656c, 0x0e2b,
+ 0x656d, 0x41a4,
+ 0x656f, 0x2409,
+ 0x6572, 0x0fe7,
+ 0x6573, 0x26b4,
+ 0x6574, 0x12c6,
+ 0x6575, 0x116e,
+ 0x6576, 0x28f1,
+ 0x6577, 0x116f,
+ 0x6579, 0x28f3,
+ 0x657a, 0x28f2,
+ 0x657b, 0x28f4,
+ 0x657c, 0x2b5b,
+ 0x657f, 0x2b5a,
+ 0x6580, 0x2d6f,
+ 0x6581, 0x2d6e,
+ 0x6582, 0x13e1,
+ 0x6584, 0x3096,
+ 0x6585, 0x41a3,
+ 0x6586, 0x4648,
+ 0x6587, 0x02d6,
+ 0x6588, 0x410b,
+ 0x6589, 0x4554,
+ 0x658c, 0x2173,
+ 0x6590, 0x0c75,
+ 0x6591, 0x0c74,
+ 0x6592, 0x240a,
+ 0x6594, 0x2f2f,
+ 0x6595, 0x1674,
+ 0x6596, 0x341c,
+ 0x6597, 0x02d7,
+ 0x6599, 0x08d8,
+ 0x659b, 0x0ac2,
+ 0x659c, 0x0ac1,
+ 0x659d, 0x2174,
+ 0x659f, 0x0e2c,
+ 0x65a0, 0x26b5,
+ 0x65a1, 0x0fe8,
+ 0x65a2, 0x2b5c,
+ 0x65a4, 0x02d8,
+ 0x65a5, 0x0346,
+ 0x65a7, 0x05f4,
+ 0x65a8, 0x19a2,
+ 0x65aa, 0x1b03,
+ 0x65ab, 0x0743,
+ 0x65ac, 0x0ac3,
+ 0x65ae, 0x2176,
+ 0x65af, 0x0c76,
+ 0x65b0, 0x0e2d,
+ 0x65b2, 0x28f5,
+ 0x65b5, 0x41a7,
+ 0x65b6, 0x2d70,
+ 0x65b7, 0x14d9,
+ 0x65b8, 0x34cb,
+ 0x65b9, 0x02d9,
+ 0x65bb, 0x19a3,
+ 0x65bc, 0x05f5,
+ 0x65bd, 0x0744,
+ 0x65be, 0x3e3b,
+ 0x65bf, 0x1b04,
+ 0x65c1, 0x08d9,
+ 0x65c2, 0x1cc3,
+ 0x65c3, 0x1cc1,
+ 0x65c5, 0x08da,
+ 0x65c6, 0x1cc0,
+ 0x65cb, 0x0ac5,
+ 0x65cd, 0x1f0d,
+ 0x65ce, 0x0ac7,
+ 0x65cf, 0x0ac4,
+ 0x65d0, 0x2177,
+ 0x65d1, 0x41aa,
+ 0x65d2, 0x2178,
+ 0x65d3, 0x240b,
+ 0x65d4, 0x3ba8,
+ 0x65d6, 0x0fea,
+ 0x65d7, 0x0fe9,
+ 0x65da, 0x2d71,
+ 0x65db, 0x2f30,
+ 0x65dd, 0x3098,
+ 0x65de, 0x3097,
+ 0x65df, 0x31d8,
+ 0x65e0, 0x022d,
+ 0x65e1, 0x1789,
+ 0x65e2, 0x0745,
+ 0x65e3, 0x41ae,
+ 0x65e5, 0x02da,
+ 0x65e6, 0x0347,
+ 0x65e8, 0x03d9,
+ 0x65e9, 0x03d8,
+ 0x65ec, 0x03da,
+ 0x65ee, 0x17f8,
+ 0x65ef, 0x17f7,
+ 0x65f0, 0x189e,
+ 0x65f1, 0x04ba,
+ 0x65f2, 0x18a1,
+ 0x65f3, 0x18a0,
+ 0x65f4, 0x189f,
+ 0x65f5, 0x18a2,
+ 0x65fa, 0x05f6,
+ 0x65fb, 0x19a9,
+ 0x65fc, 0x19a5,
+ 0x65fd, 0x19ae,
+ 0x65ff, 0x464a,
+ 0x6600, 0x05fd,
+ 0x6602, 0x05fb,
+ 0x6603, 0x19aa,
+ 0x6604, 0x19a6,
+ 0x6605, 0x19ad,
+ 0x6606, 0x05fa,
+ 0x6607, 0x0601,
+ 0x6608, 0x19a8,
+ 0x6609, 0x19a4,
+ 0x660a, 0x0600,
+ 0x660b, 0x19ab,
+ 0x660c, 0x05f9,
+ 0x660d, 0x19ac,
+ 0x660e, 0x05fc,
+ 0x660f, 0x05fe,
+ 0x6610, 0x19b0,
+ 0x6611, 0x19af,
+ 0x6612, 0x19a7,
+ 0x6613, 0x05f8,
+ 0x6614, 0x05f7,
+ 0x6615, 0x05ff,
+ 0x6618, 0x41b1,
+ 0x661c, 0x1b09,
+ 0x661d, 0x1b0f,
+ 0x661e, 0x3a93,
+ 0x661f, 0x074b,
+ 0x6620, 0x0748,
+ 0x6621, 0x1b06,
+ 0x6622, 0x1b0b,
+ 0x6623, 0x4295,
+ 0x6624, 0x074e,
+ 0x6625, 0x0746,
+ 0x6626, 0x1b0a,
+ 0x6627, 0x0749,
+ 0x6628, 0x074c,
+ 0x662b, 0x1b0d,
+ 0x662d, 0x0747,
+ 0x662e, 0x1b12,
+ 0x662f, 0x074a,
+ 0x6630, 0x3a8d,
+ 0x6631, 0x074d,
+ 0x6632, 0x1b07,
+ 0x6633, 0x1b0c,
+ 0x6634, 0x1b10,
+ 0x6635, 0x1b08,
+ 0x6636, 0x1b05,
+ 0x6639, 0x1b11,
+ 0x663a, 0x1b0e,
+ 0x6641, 0x08e2,
+ 0x6642, 0x08db,
+ 0x6643, 0x08de,
+ 0x6644, 0x41b4,
+ 0x6645, 0x08e1,
+ 0x6647, 0x1cc6,
+ 0x6648, 0x3d99,
+ 0x6649, 0x08dc,
+ 0x664a, 0x1cc4,
+ 0x664b, 0x41b7,
+ 0x664c, 0x08e0,
+ 0x664f, 0x08dd,
+ 0x6651, 0x1cc7,
+ 0x6652, 0x08df,
+ 0x6653, 0x464b,
+ 0x6657, 0x409b,
+ 0x6659, 0x1f11,
+ 0x665a, 0x0ac9,
+ 0x665b, 0x1f10,
+ 0x665c, 0x1f12,
+ 0x665d, 0x0ac8,
+ 0x665e, 0x0acd,
+ 0x665f, 0x1cc5,
+ 0x6661, 0x1f0f,
+ 0x6662, 0x1f13,
+ 0x6663, 0x3a90,
+ 0x6664, 0x0aca,
+ 0x6665, 0x1f0e,
+ 0x6666, 0x0acc,
+ 0x6667, 0x41b9,
+ 0x6668, 0x0acb,
+ 0x666a, 0x217f,
+ 0x666b, 0x3a8b,
+ 0x666c, 0x217a,
+ 0x666e, 0x0c77,
+ 0x666f, 0x0c7b,
+ 0x6670, 0x0c78,
+ 0x6671, 0x217d,
+ 0x6672, 0x2180,
+ 0x6673, 0x41bb,
+ 0x6674, 0x0c79,
+ 0x6676, 0x0c7a,
+ 0x6677, 0x0c7f,
+ 0x6678, 0x2414,
+ 0x6679, 0x217e,
+ 0x667a, 0x0c7d,
+ 0x667b, 0x217b,
+ 0x667c, 0x2179,
+ 0x667d, 0x469b,
+ 0x667e, 0x0c7e,
+ 0x6680, 0x217c,
+ 0x6684, 0x0e33,
+ 0x6685, 0x4162,
+ 0x6686, 0x240c,
+ 0x6687, 0x0e30,
+ 0x6689, 0x0e2f,
+ 0x668a, 0x2411,
+ 0x668b, 0x2410,
+ 0x668c, 0x240d,
+ 0x668d, 0x0e35,
+ 0x668e, 0x3a89,
+ 0x6690, 0x240f,
+ 0x6691, 0x0c7c,
+ 0x6692, 0x464d,
+ 0x6694, 0x2413,
+ 0x6695, 0x240e,
+ 0x6696, 0x0e32,
+ 0x6697, 0x0e2e,
+ 0x6698, 0x0e34,
+ 0x6699, 0x2412,
+ 0x669a, 0x3d3d,
+ 0x669d, 0x0fed,
+ 0x669f, 0x26b8,
+ 0x66a0, 0x26b7,
+ 0x66a1, 0x26b6,
+ 0x66a2, 0x0feb,
+ 0x66a4, 0x40ba,
+ 0x66a8, 0x0fec,
+ 0x66a9, 0x28f9,
+ 0x66aa, 0x28fc,
+ 0x66ab, 0x1172,
+ 0x66ad, 0x4948,
+ 0x66ae, 0x1171,
+ 0x66af, 0x28fd,
+ 0x66b0, 0x28f8,
+ 0x66b1, 0x1174,
+ 0x66b2, 0x28fa,
+ 0x66b3, 0x40b5,
+ 0x66b4, 0x1173,
+ 0x66b5, 0x28f7,
+ 0x66b6, 0x3e13,
+ 0x66b7, 0x28fb,
+ 0x66b8, 0x12cc,
+ 0x66b9, 0x12c9,
+ 0x66ba, 0x2b65,
+ 0x66bb, 0x2b64,
+ 0x66bd, 0x2b63,
+ 0x66be, 0x2b5e,
+ 0x66bf, 0x3d9a,
+ 0x66c0, 0x2b5f,
+ 0x66c4, 0x12ca,
+ 0x66c6, 0x12c7,
+ 0x66c7, 0x12cb,
+ 0x66c8, 0x2b5d,
+ 0x66c9, 0x12c8,
+ 0x66ca, 0x2b60,
+ 0x66cc, 0x2b66,
+ 0x66cd, 0x40b8,
+ 0x66ce, 0x3a77,
+ 0x66cf, 0x2b62,
+ 0x66d2, 0x2d72,
+ 0x66d6, 0x13e4,
+ 0x66d8, 0x2f33,
+ 0x66d9, 0x13e3,
+ 0x66da, 0x2f31,
+ 0x66dc, 0x14da,
+ 0x66dd, 0x1585,
+ 0x66de, 0x3099,
+ 0x66e0, 0x1584,
+ 0x66e3, 0x31da,
+ 0x66e6, 0x1619,
+ 0x66e8, 0x31d9,
+ 0x66e9, 0x1675,
+ 0x66eb, 0x341d,
+ 0x66ec, 0x16fc,
+ 0x66ed, 0x3485,
+ 0x66f0, 0x02db,
+ 0x66f1, 0x3e84,
+ 0x66f2, 0x03dc,
+ 0x66f4, 0x04bb,
+ 0x66f6, 0x19b1,
+ 0x66f7, 0x074f,
+ 0x66f8, 0x08e3,
+ 0x66f9, 0x0ace,
+ 0x66fc, 0x0a1f,
+ 0x66fe, 0x0c80,
+ 0x6700, 0x0bf0,
+ 0x6701, 0x2181,
+ 0x6702, 0x41c4,
+ 0x6703, 0x0e36,
+ 0x6704, 0x26ba,
+ 0x6705, 0x26b9,
+ 0x6708, 0x02dc,
+ 0x6709, 0x03de,
+ 0x670a, 0x19b2,
+ 0x670b, 0x0603,
+ 0x670c, 0x3fe2,
+ 0x670d, 0x0602,
+ 0x670e, 0x3da1,
+ 0x670f, 0x1b13,
+ 0x6712, 0x1cc8,
+ 0x6714, 0x08e4,
+ 0x6716, 0x464f,
+ 0x6717, 0x08e6,
+ 0x6718, 0x1f14,
+ 0x671b, 0x0ad0,
+ 0x671d, 0x0c83,
+ 0x671e, 0x3d8b,
+ 0x671f, 0x0c82,
+ 0x6720, 0x2415,
+ 0x6721, 0x2522,
+ 0x6722, 0x26bb,
+ 0x6723, 0x2b67,
+ 0x6725, 0x379f,
+ 0x6726, 0x14db,
+ 0x6727, 0x161a,
+ 0x6728, 0x02dd,
+ 0x672a, 0x034a,
+ 0x672c, 0x0349,
+ 0x672d, 0x034c,
+ 0x672e, 0x0348,
+ 0x6731, 0x03e1,
+ 0x6733, 0x1800,
+ 0x6734, 0x03e0,
+ 0x6735, 0x03e2,
+ 0x6736, 0x3e41,
+ 0x6738, 0x17fb,
+ 0x6739, 0x17fa,
+ 0x673a, 0x17fd,
+ 0x673b, 0x17fc,
+ 0x673c, 0x17ff,
+ 0x673d, 0x03df,
+ 0x673e, 0x17f9,
+ 0x673f, 0x17fe,
+ 0x6744, 0x401b,
+ 0x6745, 0x18a3,
+ 0x6746, 0x04c5,
+ 0x6747, 0x18a4,
+ 0x6748, 0x18a8,
+ 0x6749, 0x04c4,
+ 0x674b, 0x18ac,
+ 0x674c, 0x18a7,
+ 0x674d, 0x18aa,
+ 0x674e, 0x04bd,
+ 0x6753, 0x04c7,
+ 0x6755, 0x18a6,
+ 0x6756, 0x04c2,
+ 0x6757, 0x04c8,
+ 0x6759, 0x18a5,
+ 0x675a, 0x18ab,
+ 0x675c, 0x04c1,
+ 0x675d, 0x18a9,
+ 0x675e, 0x04c3,
+ 0x675f, 0x04bc,
+ 0x6760, 0x04c6,
+ 0x6761, 0x3d66,
+ 0x6762, 0x41cb,
+ 0x6767, 0x41ca,
+ 0x676a, 0x0618,
+ 0x676c, 0x19b4,
+ 0x676d, 0x0604,
+ 0x676f, 0x060e,
+ 0x6771, 0x0607,
+ 0x6772, 0x0619,
+ 0x6773, 0x0609,
+ 0x6774, 0x19bc,
+ 0x6775, 0x0614,
+ 0x6776, 0x19b7,
+ 0x6777, 0x060a,
+ 0x6778, 0x19c6,
+ 0x677a, 0x19bf,
+ 0x677b, 0x19b8,
+ 0x677c, 0x0617,
+ 0x677d, 0x19c4,
+ 0x677e, 0x0612,
+ 0x677f, 0x0610,
+ 0x6781, 0x19c5,
+ 0x6783, 0x19c3,
+ 0x6784, 0x19bb,
+ 0x6785, 0x19b3,
+ 0x6786, 0x19ba,
+ 0x6787, 0x060b,
+ 0x6789, 0x0611,
+ 0x678b, 0x0605,
+ 0x678c, 0x19be,
+ 0x678d, 0x19bd,
+ 0x678e, 0x19b5,
+ 0x678f, 0x46c1,
+ 0x6790, 0x0613,
+ 0x6791, 0x19c1,
+ 0x6792, 0x19b6,
+ 0x6793, 0x0616,
+ 0x6794, 0x19c8,
+ 0x6795, 0x0606,
+ 0x6797, 0x060d,
+ 0x6798, 0x19b9,
+ 0x6799, 0x19c2,
+ 0x679a, 0x0615,
+ 0x679c, 0x0608,
+ 0x679d, 0x060c,
+ 0x679f, 0x19c0,
+ 0x67a0, 0x3d7a,
+ 0x67a4, 0x4651,
+ 0x67ac, 0x41e3,
+ 0x67ae, 0x1b34,
+ 0x67af, 0x0757,
+ 0x67b0, 0x0764,
+ 0x67b1, 0x41f4,
+ 0x67b2, 0x1b2f,
+ 0x67b3, 0x1b25,
+ 0x67b4, 0x075d,
+ 0x67b5, 0x1b23,
+ 0x67b6, 0x0756,
+ 0x67b7, 0x1b1e,
+ 0x67b8, 0x0760,
+ 0x67b9, 0x1b2b,
+ 0x67ba, 0x1b18,
+ 0x67bb, 0x1b1a,
+ 0x67bf, 0x37fa,
+ 0x67c0, 0x1b1d,
+ 0x67c1, 0x1b15,
+ 0x67c2, 0x1b2a,
+ 0x67c3, 0x1b3a,
+ 0x67c4, 0x075b,
+ 0x67c5, 0x1b1f,
+ 0x67c6, 0x1b31,
+ 0x67c8, 0x1b17,
+ 0x67c9, 0x1b38,
+ 0x67cb, 0x1b3c,
+ 0x67cc, 0x1b33,
+ 0x67cd, 0x1b24,
+ 0x67ce, 0x1b2c,
+ 0x67cf, 0x0761,
+ 0x67d0, 0x0754,
+ 0x67d1, 0x075c,
+ 0x67d2, 0x0768,
+ 0x67d3, 0x0751,
+ 0x67d4, 0x0753,
+ 0x67d6, 0x3b58,
+ 0x67d7, 0x41ce,
+ 0x67d8, 0x1b1c,
+ 0x67d9, 0x0765,
+ 0x67da, 0x075e,
+ 0x67db, 0x1b36,
+ 0x67dc, 0x1b19,
+ 0x67dd, 0x0767,
+ 0x67de, 0x0762,
+ 0x67df, 0x1b22,
+ 0x67e2, 0x0766,
+ 0x67e3, 0x1b29,
+ 0x67e4, 0x1b21,
+ 0x67e5, 0x075f,
+ 0x67e6, 0x1b35,
+ 0x67e7, 0x1b2d,
+ 0x67e9, 0x0759,
+ 0x67ea, 0x1b3b,
+ 0x67eb, 0x1b20,
+ 0x67ec, 0x0755,
+ 0x67ed, 0x1b32,
+ 0x67ee, 0x1b28,
+ 0x67ef, 0x075a,
+ 0x67f0, 0x1b2e,
+ 0x67f1, 0x0752,
+ 0x67f2, 0x1b16,
+ 0x67f3, 0x0763,
+ 0x67f4, 0x08f5,
+ 0x67f5, 0x0758,
+ 0x67f6, 0x1b27,
+ 0x67f7, 0x1b26,
+ 0x67f8, 0x1b1b,
+ 0x67f9, 0x3996,
+ 0x67fa, 0x1b37,
+ 0x67fc, 0x1b30,
+ 0x67fe, 0x4555,
+ 0x67ff, 0x0750,
+ 0x6800, 0x43c7,
+ 0x6801, 0x41d3,
+ 0x6802, 0x3fc8,
+ 0x6803, 0x3d6a,
+ 0x6804, 0x4556,
+ 0x680d, 0x4281,
+ 0x6810, 0x399c,
+ 0x6812, 0x1cdd,
+ 0x6813, 0x08fc,
+ 0x6814, 0x1cde,
+ 0x6816, 0x1cd2,
+ 0x6817, 0x08f1,
+ 0x6818, 0x08fd,
+ 0x681a, 0x1ccb,
+ 0x681b, 0x4072,
+ 0x681c, 0x1cd4,
+ 0x681d, 0x1cdc,
+ 0x681e, 0x46c2,
+ 0x681f, 0x1cca,
+ 0x6820, 0x1ce5,
+ 0x6821, 0x08e7,
+ 0x6822, 0x41d0,
+ 0x6825, 0x1ce4,
+ 0x6826, 0x1cdf,
+ 0x6828, 0x1ce0,
+ 0x6829, 0x08ef,
+ 0x682a, 0x08fa,
+ 0x682b, 0x1cd6,
+ 0x682d, 0x1cd7,
+ 0x682e, 0x1ce1,
+ 0x682f, 0x1cd8,
+ 0x6831, 0x1cd3,
+ 0x6832, 0x1ccd,
+ 0x6834, 0x1cdb,
+ 0x6835, 0x1cd5,
+ 0x6836, 0x3e2e,
+ 0x6837, 0x421d,
+ 0x6838, 0x08e8,
+ 0x6839, 0x08ec,
+ 0x683a, 0x1ce3,
+ 0x683b, 0x1ccf,
+ 0x683c, 0x08f8,
+ 0x683d, 0x08f4,
+ 0x683e, 0x4147,
+ 0x6840, 0x08f7,
+ 0x6841, 0x08fe,
+ 0x6842, 0x08ed,
+ 0x6843, 0x08f9,
+ 0x6844, 0x1cda,
+ 0x6845, 0x08fb,
+ 0x6846, 0x08ea,
+ 0x6847, 0x3beb,
+ 0x6848, 0x08e9,
+ 0x6849, 0x1ccc,
+ 0x684a, 0x4653,
+ 0x684b, 0x1cd0,
+ 0x684c, 0x08f2,
+ 0x684d, 0x1ce2,
+ 0x684e, 0x1cd9,
+ 0x684f, 0x1cd1,
+ 0x6850, 0x08f6,
+ 0x6851, 0x08f3,
+ 0x6853, 0x08eb,
+ 0x6854, 0x08ee,
+ 0x6855, 0x3d90,
+ 0x6856, 0x3814,
+ 0x685d, 0x41d6,
+ 0x6865, 0x4557,
+ 0x686b, 0x1f29,
+ 0x686d, 0x1f19,
+ 0x686f, 0x1f1e,
+ 0x6871, 0x1f2d,
+ 0x6872, 0x1f2a,
+ 0x6874, 0x1f23,
+ 0x6875, 0x1f22,
+ 0x6876, 0x0ad7,
+ 0x6877, 0x1f26,
+ 0x6878, 0x1f35,
+ 0x6879, 0x1f15,
+ 0x687b, 0x1f36,
+ 0x687c, 0x1f28,
+ 0x687d, 0x1f3a,
+ 0x687e, 0x1f2e,
+ 0x687f, 0x0ad6,
+ 0x6880, 0x1f2c,
+ 0x6881, 0x0ad1,
+ 0x6882, 0x0ae6,
+ 0x6883, 0x0adc,
+ 0x6884, 0x4654,
+ 0x6885, 0x0ae0,
+ 0x6886, 0x0adf,
+ 0x6887, 0x1f16,
+ 0x6888, 0x46b7,
+ 0x6889, 0x1f33,
+ 0x688a, 0x1f39,
+ 0x688b, 0x1f31,
+ 0x688c, 0x1f38,
+ 0x688f, 0x1f25,
+ 0x6890, 0x1f17,
+ 0x6891, 0x1f37,
+ 0x6892, 0x1f27,
+ 0x6893, 0x0ad4,
+ 0x6894, 0x0ae1,
+ 0x6896, 0x1f30,
+ 0x6897, 0x0ada,
+ 0x6898, 0x3aaa,
+ 0x689b, 0x1f2f,
+ 0x689c, 0x1f18,
+ 0x689d, 0x0ae2,
+ 0x689f, 0x0ae4,
+ 0x68a0, 0x1f32,
+ 0x68a1, 0x0ae5,
+ 0x68a2, 0x0ad3,
+ 0x68a3, 0x1f1f,
+ 0x68a4, 0x1f34,
+ 0x68a6, 0x40e4,
+ 0x68a7, 0x0ad9,
+ 0x68a8, 0x0ae3,
+ 0x68a9, 0x1f21,
+ 0x68aa, 0x1f2b,
+ 0x68ab, 0x1f1c,
+ 0x68ac, 0x1f20,
+ 0x68ad, 0x0ade,
+ 0x68ae, 0x1f1b,
+ 0x68af, 0x0ad2,
+ 0x68b0, 0x0adb,
+ 0x68b1, 0x0ad8,
+ 0x68b2, 0x1f24,
+ 0x68b3, 0x08f0,
+ 0x68b4, 0x2198,
+ 0x68b5, 0x0ad5,
+ 0x68b6, 0x3a9e,
+ 0x68b9, 0x3d14,
+ 0x68bd, 0x427c,
+ 0x68c3, 0x41dc,
+ 0x68c4, 0x0add,
+ 0x68c5, 0x3c2e,
+ 0x68c6, 0x219b,
+ 0x68c7, 0x21b1,
+ 0x68c8, 0x21a6,
+ 0x68c9, 0x0c97,
+ 0x68ca, 0x42eb,
+ 0x68cb, 0x0c92,
+ 0x68cc, 0x2195,
+ 0x68cd, 0x0c93,
+ 0x68ce, 0x21a5,
+ 0x68d0, 0x219e,
+ 0x68d1, 0x21ab,
+ 0x68d2, 0x0c8f,
+ 0x68d3, 0x2183,
+ 0x68d4, 0x21ad,
+ 0x68d5, 0x0c85,
+ 0x68d6, 0x218b,
+ 0x68d7, 0x0c88,
+ 0x68d8, 0x0c87,
+ 0x68da, 0x0c98,
+ 0x68dc, 0x2185,
+ 0x68dd, 0x21a7,
+ 0x68df, 0x0c8a,
+ 0x68e0, 0x0c86,
+ 0x68e1, 0x2193,
+ 0x68e3, 0x0c91,
+ 0x68e4, 0x218e,
+ 0x68e6, 0x21a9,
+ 0x68e7, 0x0c8d,
+ 0x68e8, 0x21a1,
+ 0x68e9, 0x21ae,
+ 0x68ea, 0x2188,
+ 0x68eb, 0x218d,
+ 0x68ec, 0x2187,
+ 0x68ee, 0x0c8c,
+ 0x68ef, 0x219a,
+ 0x68f0, 0x242b,
+ 0x68f1, 0x2189,
+ 0x68f2, 0x0c90,
+ 0x68f3, 0x2192,
+ 0x68f4, 0x21aa,
+ 0x68f5, 0x0c8b,
+ 0x68f6, 0x218f,
+ 0x68f7, 0x218c,
+ 0x68f8, 0x219d,
+ 0x68f9, 0x0c8e,
+ 0x68fa, 0x0c84,
+ 0x68fb, 0x0c9a,
+ 0x68fc, 0x21a0,
+ 0x68fd, 0x219f,
+ 0x6900, 0x41df,
+ 0x6901, 0x41de,
+ 0x6902, 0x42fb,
+ 0x6903, 0x429c,
+ 0x6904, 0x2184,
+ 0x6905, 0x0c89,
+ 0x6906, 0x21ac,
+ 0x6907, 0x2194,
+ 0x6908, 0x2196,
+ 0x6909, 0x4658,
+ 0x690a, 0x21a3,
+ 0x690b, 0x21a2,
+ 0x690c, 0x2182,
+ 0x690d, 0x0c94,
+ 0x690e, 0x0c96,
+ 0x690f, 0x218a,
+ 0x6910, 0x2191,
+ 0x6911, 0x2199,
+ 0x6912, 0x0c95,
+ 0x6913, 0x2190,
+ 0x6914, 0x219c,
+ 0x6915, 0x21af,
+ 0x6917, 0x21a4,
+ 0x6918, 0x3da2,
+ 0x691a, 0x3d80,
+ 0x691b, 0x37bd,
+ 0x6925, 0x21b0,
+ 0x692a, 0x2186,
+ 0x692c, 0x3f38,
+ 0x692f, 0x243f,
+ 0x6930, 0x0e3e,
+ 0x6932, 0x243d,
+ 0x6933, 0x2428,
+ 0x6934, 0x242d,
+ 0x6935, 0x2426,
+ 0x6936, 0x41e7,
+ 0x6937, 0x2439,
+ 0x6938, 0x2418,
+ 0x6939, 0x241f,
+ 0x693b, 0x2437,
+ 0x693c, 0x2441,
+ 0x693d, 0x2429,
+ 0x693e, 0x4056,
+ 0x693f, 0x241c,
+ 0x6940, 0x242f,
+ 0x6941, 0x2434,
+ 0x6942, 0x2420,
+ 0x6943, 0x4659,
+ 0x6944, 0x2431,
+ 0x6945, 0x241d,
+ 0x6946, 0x456f,
+ 0x6948, 0x2424,
+ 0x694a, 0x0e40,
+ 0x694b, 0x2438,
+ 0x694c, 0x2436,
+ 0x694e, 0x2419,
+ 0x694f, 0x243b,
+ 0x6951, 0x243c,
+ 0x6952, 0x243e,
+ 0x6953, 0x0e44,
+ 0x6954, 0x0e3c,
+ 0x6955, 0x3d86,
+ 0x6956, 0x1f1d,
+ 0x6957, 0x2421,
+ 0x6958, 0x2433,
+ 0x6959, 0x2422,
+ 0x695a, 0x0e39,
+ 0x695b, 0x0e49,
+ 0x695c, 0x243a,
+ 0x695d, 0x0e47,
+ 0x695e, 0x0e43,
+ 0x695f, 0x2417,
+ 0x6960, 0x0e3b,
+ 0x6961, 0x41e4,
+ 0x6962, 0x241a,
+ 0x6963, 0x0e48,
+ 0x6964, 0x465b,
+ 0x6965, 0x242a,
+ 0x6966, 0x2416,
+ 0x6967, 0x3d15,
+ 0x6968, 0x0e41,
+ 0x6969, 0x242e,
+ 0x696a, 0x241e,
+ 0x696b, 0x0e42,
+ 0x696c, 0x2427,
+ 0x696d, 0x0e38,
+ 0x696e, 0x0c99,
+ 0x696f, 0x2430,
+ 0x6970, 0x2197,
+ 0x6971, 0x241b,
+ 0x6972, 0x3a6d,
+ 0x6973, 0x41db,
+ 0x6974, 0x2435,
+ 0x6975, 0x0e3d,
+ 0x6976, 0x2432,
+ 0x6977, 0x0e3a,
+ 0x6978, 0x242c,
+ 0x6979, 0x0e45,
+ 0x697a, 0x2423,
+ 0x697b, 0x2440,
+ 0x6980, 0x3f3e,
+ 0x6982, 0x0e3f,
+ 0x6983, 0x24af,
+ 0x6985, 0x465d,
+ 0x6986, 0x0e46,
+ 0x698a, 0x3d74,
+ 0x698d, 0x26c9,
+ 0x698e, 0x26c7,
+ 0x6990, 0x26dd,
+ 0x6991, 0x26c5,
+ 0x6993, 0x26d7,
+ 0x6994, 0x0e37,
+ 0x6995, 0x0ff0,
+ 0x6996, 0x26c1,
+ 0x6997, 0x26dc,
+ 0x6998, 0x41e8,
+ 0x6999, 0x26c6,
+ 0x699a, 0x26d4,
+ 0x699b, 0x0ff5,
+ 0x699c, 0x0fee,
+ 0x699e, 0x26da,
+ 0x699f, 0x465c,
+ 0x69a0, 0x26bf,
+ 0x69a1, 0x26d9,
+ 0x69a2, 0x3730,
+ 0x69a3, 0x1000,
+ 0x69a4, 0x26d0,
+ 0x69a5, 0x26e0,
+ 0x69a6, 0x0ffe,
+ 0x69a7, 0x26c8,
+ 0x69a8, 0x0fef,
+ 0x69a9, 0x26ca,
+ 0x69aa, 0x26d8,
+ 0x69ab, 0x0ff8,
+ 0x69ac, 0x26c3,
+ 0x69ad, 0x0ffc,
+ 0x69ae, 0x0ff2,
+ 0x69af, 0x26cc,
+ 0x69b0, 0x26c2,
+ 0x69b1, 0x26bc,
+ 0x69b2, 0x3ff6,
+ 0x69b3, 0x26d6,
+ 0x69b4, 0x0ff9,
+ 0x69b5, 0x26df,
+ 0x69b6, 0x26bd,
+ 0x69b7, 0x0ff6,
+ 0x69b9, 0x26d2,
+ 0x69bb, 0x0ff7,
+ 0x69bc, 0x26c4,
+ 0x69bd, 0x26cf,
+ 0x69be, 0x26cb,
+ 0x69bf, 0x26cd,
+ 0x69c0, 0x3f5d,
+ 0x69c1, 0x0ff1,
+ 0x69c2, 0x26de,
+ 0x69c3, 0x0fff,
+ 0x69c4, 0x26ce,
+ 0x69c6, 0x26e1,
+ 0x69c9, 0x26be,
+ 0x69ca, 0x26d3,
+ 0x69cb, 0x0ff4,
+ 0x69cc, 0x0ffd,
+ 0x69cd, 0x0ffb,
+ 0x69ce, 0x26c0,
+ 0x69cf, 0x26d5,
+ 0x69d0, 0x0ffa,
+ 0x69d1, 0x39ef,
+ 0x69d3, 0x0ff3,
+ 0x69d4, 0x26d1,
+ 0x69d5, 0x3e3c,
+ 0x69d6, 0x465e,
+ 0x69d9, 0x26db,
+ 0x69e1, 0x41d8,
+ 0x69e2, 0x2909,
+ 0x69e4, 0x2905,
+ 0x69e5, 0x2901,
+ 0x69e6, 0x2915,
+ 0x69e7, 0x2912,
+ 0x69e8, 0x1177,
+ 0x69e9, 0x3d91,
+ 0x69eb, 0x2919,
+ 0x69ec, 0x2908,
+ 0x69ed, 0x1182,
+ 0x69ee, 0x290f,
+ 0x69f1, 0x2904,
+ 0x69f2, 0x290e,
+ 0x69f3, 0x117f,
+ 0x69f4, 0x2922,
+ 0x69f6, 0x291f,
+ 0x69f7, 0x2911,
+ 0x69f8, 0x2902,
+ 0x69f9, 0x41ed,
+ 0x69fa, 0x41c7,
+ 0x69fb, 0x2916,
+ 0x69fc, 0x2918,
+ 0x69fd, 0x117b,
+ 0x69fe, 0x290c,
+ 0x69ff, 0x2907,
+ 0x6a00, 0x28fe,
+ 0x6a01, 0x1178,
+ 0x6a02, 0x1180,
+ 0x6a03, 0x3e29,
+ 0x6a04, 0x291b,
+ 0x6a05, 0x1181,
+ 0x6a06, 0x28ff,
+ 0x6a07, 0x2921,
+ 0x6a08, 0x2914,
+ 0x6a09, 0x291a,
+ 0x6a0a, 0x117e,
+ 0x6a0b, 0x41d9,
+ 0x6a0c, 0x3d50,
+ 0x6a0d, 0x2917,
+ 0x6a0f, 0x291e,
+ 0x6a11, 0x1183,
+ 0x6a13, 0x117d,
+ 0x6a14, 0x2910,
+ 0x6a15, 0x2903,
+ 0x6a16, 0x2923,
+ 0x6a17, 0x2900,
+ 0x6a18, 0x291c,
+ 0x6a19, 0x117a,
+ 0x6a1a, 0x3d1e,
+ 0x6a1b, 0x290a,
+ 0x6a1c, 0x3b68,
+ 0x6a1d, 0x290b,
+ 0x6a1e, 0x1179,
+ 0x6a1f, 0x1176,
+ 0x6a20, 0x2906,
+ 0x6a21, 0x117c,
+ 0x6a23, 0x1175,
+ 0x6a25, 0x291d,
+ 0x6a26, 0x2920,
+ 0x6a27, 0x290d,
+ 0x6a28, 0x2b74,
+ 0x6a2b, 0x3d42,
+ 0x6a2c, 0x42ab,
+ 0x6a2d, 0x3b1f,
+ 0x6a32, 0x2b6c,
+ 0x6a33, 0x3aa4,
+ 0x6a34, 0x2b68,
+ 0x6a35, 0x12d9,
+ 0x6a38, 0x12ce,
+ 0x6a39, 0x12d3,
+ 0x6a3a, 0x12cf,
+ 0x6a3b, 0x2b76,
+ 0x6a3c, 0x2b81,
+ 0x6a3d, 0x12cd,
+ 0x6a3e, 0x2b6e,
+ 0x6a3f, 0x2b77,
+ 0x6a40, 0x2913,
+ 0x6a41, 0x2b78,
+ 0x6a44, 0x12d4,
+ 0x6a45, 0x41f0,
+ 0x6a46, 0x2b87,
+ 0x6a47, 0x12d8,
+ 0x6a48, 0x12db,
+ 0x6a49, 0x2b6a,
+ 0x6a4b, 0x12d7,
+ 0x6a4c, 0x3aab,
+ 0x6a4d, 0x2b85,
+ 0x6a4f, 0x2b7c,
+ 0x6a50, 0x2b7b,
+ 0x6a51, 0x2b73,
+ 0x6a52, 0x3aa5,
+ 0x6a53, 0x37ac,
+ 0x6a54, 0x2b7d,
+ 0x6a55, 0x2b84,
+ 0x6a56, 0x2b83,
+ 0x6a57, 0x37da,
+ 0x6a58, 0x12d2,
+ 0x6a59, 0x12d0,
+ 0x6a5a, 0x2b75,
+ 0x6a5b, 0x2b72,
+ 0x6a5d, 0x2b6f,
+ 0x6a5e, 0x2b82,
+ 0x6a5f, 0x12da,
+ 0x6a60, 0x2b80,
+ 0x6a61, 0x12d6,
+ 0x6a62, 0x12d5,
+ 0x6a64, 0x2b7a,
+ 0x6a65, 0x4660,
+ 0x6a66, 0x2b69,
+ 0x6a67, 0x2b6b,
+ 0x6a68, 0x2b6d,
+ 0x6a69, 0x2b7f,
+ 0x6a6a, 0x2b79,
+ 0x6a6b, 0x12d1,
+ 0x6a6d, 0x2b70,
+ 0x6a6f, 0x2b7e,
+ 0x6a71, 0x4662,
+ 0x6a74, 0x4661,
+ 0x6a76, 0x2b71,
+ 0x6a7a, 0x3aad,
+ 0x6a7e, 0x13ec,
+ 0x6a7f, 0x2d84,
+ 0x6a80, 0x13e5,
+ 0x6a81, 0x2d75,
+ 0x6a82, 0x4663,
+ 0x6a83, 0x2d80,
+ 0x6a84, 0x13e7,
+ 0x6a85, 0x2d87,
+ 0x6a87, 0x2d7c,
+ 0x6a89, 0x2d77,
+ 0x6a8a, 0x4136,
+ 0x6a8c, 0x2d88,
+ 0x6a8d, 0x2d73,
+ 0x6a8e, 0x2d7e,
+ 0x6a8f, 0x3c1b,
+ 0x6a90, 0x13ee,
+ 0x6a91, 0x2d83,
+ 0x6a92, 0x2d89,
+ 0x6a93, 0x2d7d,
+ 0x6a94, 0x13e6,
+ 0x6a95, 0x2d7f,
+ 0x6a96, 0x2d74,
+ 0x6a97, 0x13ed,
+ 0x6a99, 0x4665,
+ 0x6a9a, 0x2d86,
+ 0x6a9b, 0x2d79,
+ 0x6a9c, 0x13e9,
+ 0x6a9d, 0x41f2,
+ 0x6a9e, 0x2d7b,
+ 0x6a9f, 0x2d78,
+ 0x6aa0, 0x13ef,
+ 0x6aa1, 0x2d7a,
+ 0x6aa2, 0x13e8,
+ 0x6aa3, 0x13eb,
+ 0x6aa4, 0x2d82,
+ 0x6aa5, 0x2d76,
+ 0x6aa6, 0x2d85,
+ 0x6aa7, 0x37e3,
+ 0x6aa8, 0x2d81,
+ 0x6aab, 0x4667,
+ 0x6aac, 0x14dd,
+ 0x6aad, 0x2f3e,
+ 0x6aae, 0x14e2,
+ 0x6ab1, 0x3e53,
+ 0x6ab2, 0x3b4b,
+ 0x6ab3, 0x14dc,
+ 0x6ab4, 0x2f3d,
+ 0x6ab5, 0x4668,
+ 0x6ab6, 0x2f3a,
+ 0x6ab8, 0x14e0,
+ 0x6ab9, 0x2f35,
+ 0x6aba, 0x2f39,
+ 0x6abb, 0x14df,
+ 0x6abd, 0x2f36,
+ 0x6abe, 0x3aa1,
+ 0x6ac2, 0x14e1,
+ 0x6ac3, 0x14de,
+ 0x6ac5, 0x2f34,
+ 0x6ac6, 0x2f38,
+ 0x6ac7, 0x2f3c,
+ 0x6ac8, 0x41f5,
+ 0x6ac9, 0x3aa6,
+ 0x6aca, 0x3f4c,
+ 0x6acb, 0x309f,
+ 0x6acc, 0x309c,
+ 0x6acd, 0x30a5,
+ 0x6acf, 0x30a4,
+ 0x6ad0, 0x30a2,
+ 0x6ad1, 0x309d,
+ 0x6ad3, 0x1589,
+ 0x6ad4, 0x4669,
+ 0x6ad8, 0x3caa,
+ 0x6ad9, 0x309e,
+ 0x6ada, 0x1588,
+ 0x6adb, 0x13ea,
+ 0x6adc, 0x30a1,
+ 0x6add, 0x1587,
+ 0x6ade, 0x30a6,
+ 0x6adf, 0x30a0,
+ 0x6ae0, 0x309b,
+ 0x6ae1, 0x2f37,
+ 0x6ae5, 0x1586,
+ 0x6ae7, 0x309a,
+ 0x6ae8, 0x31df,
+ 0x6aea, 0x31de,
+ 0x6aeb, 0x30a3,
+ 0x6aec, 0x161b,
+ 0x6aee, 0x31e2,
+ 0x6af0, 0x31dd,
+ 0x6af1, 0x31e1,
+ 0x6af3, 0x31dc,
+ 0x6af6, 0x466a,
+ 0x6af8, 0x32d6,
+ 0x6af9, 0x31e0,
+ 0x6afa, 0x1678,
+ 0x6afb, 0x1676,
+ 0x6afc, 0x32d4,
+ 0x6b00, 0x32d7,
+ 0x6b02, 0x32d3,
+ 0x6b03, 0x32d5,
+ 0x6b04, 0x1677,
+ 0x6b05, 0x3aa7,
+ 0x6b08, 0x3386,
+ 0x6b0a, 0x16c6,
+ 0x6b0b, 0x3385,
+ 0x6b0f, 0x3420,
+ 0x6b10, 0x16fd,
+ 0x6b11, 0x341e,
+ 0x6b13, 0x3487,
+ 0x6b16, 0x1743,
+ 0x6b17, 0x34ce,
+ 0x6b18, 0x34cc,
+ 0x6b1a, 0x34cf,
+ 0x6b1d, 0x41f8,
+ 0x6b1e, 0x3534,
+ 0x6b20, 0x02de,
+ 0x6b21, 0x03e3,
+ 0x6b23, 0x061a,
+ 0x6b25, 0x19c9,
+ 0x6b28, 0x1b3d,
+ 0x6b2c, 0x1ce6,
+ 0x6b2d, 0x1ce8,
+ 0x6b2f, 0x1ce7,
+ 0x6b31, 0x1ce9,
+ 0x6b32, 0x0ae7,
+ 0x6b33, 0x1f3c,
+ 0x6b34, 0x1cea,
+ 0x6b35, 0x41fb,
+ 0x6b36, 0x1f3b,
+ 0x6b37, 0x1f3d,
+ 0x6b39, 0x21b2,
+ 0x6b3a, 0x0c9c,
+ 0x6b3b, 0x21b3,
+ 0x6b3c, 0x21b5,
+ 0x6b3d, 0x0c9d,
+ 0x6b3e, 0x0c9b,
+ 0x6b3f, 0x21b4,
+ 0x6b41, 0x2447,
+ 0x6b42, 0x2445,
+ 0x6b43, 0x2444,
+ 0x6b45, 0x2443,
+ 0x6b46, 0x2442,
+ 0x6b47, 0x0e4a,
+ 0x6b48, 0x2446,
+ 0x6b49, 0x1001,
+ 0x6b4a, 0x26e2,
+ 0x6b4b, 0x26e4,
+ 0x6b4c, 0x1002,
+ 0x6b4d, 0x26e3,
+ 0x6b4e, 0x1185,
+ 0x6b50, 0x1184,
+ 0x6b51, 0x2924,
+ 0x6b52, 0x3f6e,
+ 0x6b54, 0x2b89,
+ 0x6b55, 0x2b88,
+ 0x6b56, 0x2b8a,
+ 0x6b57, 0x3aae,
+ 0x6b59, 0x12dc,
+ 0x6b5b, 0x2d8a,
+ 0x6b5c, 0x13f0,
+ 0x6b5e, 0x2f3f,
+ 0x6b5f, 0x14e4,
+ 0x6b60, 0x30a7,
+ 0x6b61, 0x16c7,
+ 0x6b62, 0x02df,
+ 0x6b63, 0x034d,
+ 0x6b64, 0x03e4,
+ 0x6b65, 0x04c9,
+ 0x6b66, 0x061b,
+ 0x6b6a, 0x0769,
+ 0x6b6d, 0x1ceb,
+ 0x6b6f, 0x4515,
+ 0x6b72, 0x0e4b,
+ 0x6b74, 0x41fc,
+ 0x6b76, 0x29a2,
+ 0x6b77, 0x12dd,
+ 0x6b78, 0x14e5,
+ 0x6b79, 0x02e0,
+ 0x6b7a, 0x44ee,
+ 0x6b7b, 0x03e5,
+ 0x6b7e, 0x19cb,
+ 0x6b7f, 0x061d,
+ 0x6b80, 0x19ca,
+ 0x6b81, 0x466b,
+ 0x6b82, 0x1b3e,
+ 0x6b83, 0x076a,
+ 0x6b84, 0x1b3f,
+ 0x6b86, 0x076b,
+ 0x6b88, 0x1ced,
+ 0x6b89, 0x0900,
+ 0x6b8a, 0x08ff,
+ 0x6b8c, 0x1f43,
+ 0x6b8d, 0x1f41,
+ 0x6b8f, 0x1f40,
+ 0x6b91, 0x1f3f,
+ 0x6b94, 0x21b6,
+ 0x6b95, 0x21b9,
+ 0x6b96, 0x0c9f,
+ 0x6b97, 0x21b7,
+ 0x6b98, 0x0c9e,
+ 0x6b99, 0x21b8,
+ 0x6b9b, 0x2448,
+ 0x6b9e, 0x26e5,
+ 0x6ba2, 0x2927,
+ 0x6ba3, 0x2926,
+ 0x6ba4, 0x1186,
+ 0x6ba5, 0x2925,
+ 0x6ba6, 0x2928,
+ 0x6ba7, 0x2b8b,
+ 0x6baa, 0x2b8c,
+ 0x6bad, 0x2d8b,
+ 0x6bae, 0x13f1,
+ 0x6baf, 0x14e6,
+ 0x6bb0, 0x30a8,
+ 0x6bb2, 0x1679,
+ 0x6bb3, 0x178a,
+ 0x6bb5, 0x076c,
+ 0x6bb6, 0x1b40,
+ 0x6bb7, 0x0901,
+ 0x6bba, 0x0ae8,
+ 0x6bbc, 0x0ca0,
+ 0x6bbd, 0x21ba,
+ 0x6bbf, 0x0e4d,
+ 0x6bc0, 0x0e4c,
+ 0x6bc1, 0x466c,
+ 0x6bc3, 0x26e8,
+ 0x6bc5, 0x1187,
+ 0x6bc7, 0x2b8f,
+ 0x6bc8, 0x2b8e,
+ 0x6bc9, 0x2f40,
+ 0x6bca, 0x3421,
+ 0x6bcb, 0x02e1,
+ 0x6bcc, 0x178b,
+ 0x6bcd, 0x034e,
+ 0x6bcf, 0x04ca,
+ 0x6bd0, 0x18ad,
+ 0x6bd2, 0x076d,
+ 0x6bd3, 0x0e4e,
+ 0x6bd4, 0x02e2,
+ 0x6bd6, 0x1b41,
+ 0x6bd7, 0x076e,
+ 0x6bd8, 0x1b42,
+ 0x6bda, 0x13f2,
+ 0x6bdb, 0x02e3,
+ 0x6bdc, 0x4207,
+ 0x6bde, 0x19cc,
+ 0x6be0, 0x1b43,
+ 0x6be1, 0x4205,
+ 0x6be2, 0x1cf2,
+ 0x6be3, 0x1cf1,
+ 0x6be4, 0x1cef,
+ 0x6be6, 0x1cee,
+ 0x6be7, 0x1cf3,
+ 0x6be8, 0x1cf0,
+ 0x6bea, 0x466d,
+ 0x6beb, 0x0ae9,
+ 0x6bef, 0x0ca1,
+ 0x6bf0, 0x21bb,
+ 0x6bf2, 0x21bc,
+ 0x6bf7, 0x244c,
+ 0x6bf9, 0x244b,
+ 0x6bfa, 0x3f79,
+ 0x6bfb, 0x2449,
+ 0x6bfd, 0x0e4f,
+ 0x6bfe, 0x26ea,
+ 0x6bff, 0x292b,
+ 0x6c00, 0x292a,
+ 0x6c01, 0x2929,
+ 0x6c02, 0x292c,
+ 0x6c03, 0x2b91,
+ 0x6c04, 0x2b90,
+ 0x6c05, 0x12de,
+ 0x6c06, 0x2b92,
+ 0x6c08, 0x13f3,
+ 0x6c09, 0x2d8c,
+ 0x6c0b, 0x2f41,
+ 0x6c0c, 0x30a9,
+ 0x6c0d, 0x3388,
+ 0x6c0f, 0x02e4,
+ 0x6c10, 0x0350,
+ 0x6c11, 0x034f,
+ 0x6c13, 0x061e,
+ 0x6c14, 0x178c,
+ 0x6c15, 0x17aa,
+ 0x6c16, 0x03e6,
+ 0x6c18, 0x1801,
+ 0x6c19, 0x18ae,
+ 0x6c1b, 0x061f,
+ 0x6c1c, 0x38ab,
+ 0x6c1d, 0x19cd,
+ 0x6c1f, 0x076f,
+ 0x6c20, 0x1b44,
+ 0x6c23, 0x0902,
+ 0x6c24, 0x0906,
+ 0x6c25, 0x1cf4,
+ 0x6c26, 0x0905,
+ 0x6c27, 0x0903,
+ 0x6c2a, 0x1f44,
+ 0x6c2b, 0x0aeb,
+ 0x6c2c, 0x0ca4,
+ 0x6c2e, 0x0ca2,
+ 0x6c30, 0x21be,
+ 0x6c31, 0x3f63,
+ 0x6c33, 0x1003,
+ 0x6c34, 0x02e5,
+ 0x6c35, 0x44ef,
+ 0x6c36, 0x17ab,
+ 0x6c37, 0x4208,
+ 0x6c38, 0x0351,
+ 0x6c39, 0x3e05,
+ 0x6c3a, 0x44f0,
+ 0x6c3b, 0x17ae,
+ 0x6c3d, 0x4381,
+ 0x6c3e, 0x0354,
+ 0x6c3f, 0x17ad,
+ 0x6c40, 0x0353,
+ 0x6c41, 0x0352,
+ 0x6c42, 0x04cb,
+ 0x6c43, 0x17ac,
+ 0x6c46, 0x1802,
+ 0x6c49, 0x408d,
+ 0x6c4a, 0x1806,
+ 0x6c4b, 0x1808,
+ 0x6c4d, 0x03f0,
+ 0x6c4f, 0x1805,
+ 0x6c50, 0x03ec,
+ 0x6c52, 0x1803,
+ 0x6c54, 0x1807,
+ 0x6c55, 0x03ed,
+ 0x6c57, 0x03e8,
+ 0x6c58, 0x3bba,
+ 0x6c59, 0x03e9,
+ 0x6c5a, 0x420c,
+ 0x6c5b, 0x03ef,
+ 0x6c5c, 0x1804,
+ 0x6c5d, 0x03e7,
+ 0x6c5e, 0x04cc,
+ 0x6c5f, 0x03ea,
+ 0x6c61, 0x03ee,
+ 0x6c65, 0x18c0,
+ 0x6c66, 0x18be,
+ 0x6c67, 0x18b1,
+ 0x6c68, 0x04d8,
+ 0x6c69, 0x18b8,
+ 0x6c6a, 0x04d3,
+ 0x6c6b, 0x18b2,
+ 0x6c6d, 0x18ba,
+ 0x6c6e, 0x40ca,
+ 0x6c6f, 0x18b7,
+ 0x6c70, 0x04d6,
+ 0x6c71, 0x18b6,
+ 0x6c72, 0x04dd,
+ 0x6c73, 0x18bf,
+ 0x6c74, 0x04df,
+ 0x6c75, 0x466e,
+ 0x6c76, 0x04e1,
+ 0x6c78, 0x18b0,
+ 0x6c79, 0x420e,
+ 0x6c7a, 0x04d4,
+ 0x6c7b, 0x18c1,
+ 0x6c7d, 0x04db,
+ 0x6c7e, 0x04de,
+ 0x6c7f, 0x37a6,
+ 0x6c80, 0x19e4,
+ 0x6c81, 0x04ce,
+ 0x6c82, 0x04e5,
+ 0x6c83, 0x04dc,
+ 0x6c84, 0x18b3,
+ 0x6c85, 0x04d1,
+ 0x6c86, 0x04e0,
+ 0x6c87, 0x18bb,
+ 0x6c88, 0x04cf,
+ 0x6c8a, 0x19e2,
+ 0x6c8b, 0x18b4,
+ 0x6c8c, 0x04d7,
+ 0x6c8d, 0x04e2,
+ 0x6c8e, 0x18c2,
+ 0x6c8f, 0x18b5,
+ 0x6c90, 0x04d5,
+ 0x6c92, 0x04da,
+ 0x6c93, 0x19ce,
+ 0x6c94, 0x04e3,
+ 0x6c95, 0x18bc,
+ 0x6c96, 0x04d9,
+ 0x6c98, 0x04e4,
+ 0x6c99, 0x04cd,
+ 0x6c9a, 0x18b9,
+ 0x6c9b, 0x04d2,
+ 0x6c9c, 0x18bd,
+ 0x6c9d, 0x19e3,
+ 0x6c9f, 0x3889,
+ 0x6ca2, 0x3d63,
+ 0x6caa, 0x466f,
+ 0x6cab, 0x062b,
+ 0x6cac, 0x063b,
+ 0x6cad, 0x19d5,
+ 0x6cae, 0x0632,
+ 0x6caf, 0x3cf6,
+ 0x6cb0, 0x19ea,
+ 0x6cb1, 0x0623,
+ 0x6cb2, 0x3ecc,
+ 0x6cb3, 0x0626,
+ 0x6cb4, 0x19e1,
+ 0x6cb6, 0x19d3,
+ 0x6cb7, 0x19d7,
+ 0x6cb8, 0x062e,
+ 0x6cb9, 0x0630,
+ 0x6cba, 0x19da,
+ 0x6cbb, 0x0637,
+ 0x6cbc, 0x0629,
+ 0x6cbd, 0x0627,
+ 0x6cbf, 0x0636,
+ 0x6cc0, 0x19e6,
+ 0x6cc1, 0x0631,
+ 0x6cc2, 0x19d9,
+ 0x6cc3, 0x19db,
+ 0x6cc4, 0x062f,
+ 0x6cc5, 0x0634,
+ 0x6cc6, 0x19dc,
+ 0x6cc7, 0x19e9,
+ 0x6cc9, 0x0770,
+ 0x6cca, 0x063a,
+ 0x6ccb, 0x4070,
+ 0x6ccc, 0x0624,
+ 0x6ccd, 0x19e8,
+ 0x6cce, 0x3f91,
+ 0x6ccf, 0x19ec,
+ 0x6cd0, 0x19d8,
+ 0x6cd1, 0x19ee,
+ 0x6cd2, 0x19df,
+ 0x6cd3, 0x062d,
+ 0x6cd4, 0x19d4,
+ 0x6cd5, 0x062c,
+ 0x6cd6, 0x063e,
+ 0x6cd7, 0x0633,
+ 0x6cd9, 0x19d2,
+ 0x6cda, 0x1b4e,
+ 0x6cdb, 0x0639,
+ 0x6cdc, 0x063d,
+ 0x6cdd, 0x19e0,
+ 0x6cde, 0x19e5,
+ 0x6cdf, 0x3d57,
+ 0x6ce0, 0x063f,
+ 0x6ce1, 0x0638,
+ 0x6ce2, 0x062a,
+ 0x6ce3, 0x0620,
+ 0x6ce5, 0x0625,
+ 0x6ce7, 0x19d6,
+ 0x6ce8, 0x0621,
+ 0x6ce9, 0x19ed,
+ 0x6cea, 0x3f8d,
+ 0x6ceb, 0x19d0,
+ 0x6cec, 0x19cf,
+ 0x6ced, 0x19dd,
+ 0x6cee, 0x19d1,
+ 0x6cef, 0x063c,
+ 0x6cf0, 0x0907,
+ 0x6cf1, 0x0635,
+ 0x6cf2, 0x19de,
+ 0x6cf3, 0x0622,
+ 0x6cf5, 0x077f,
+ 0x6cf9, 0x19eb,
+ 0x6d00, 0x1b55,
+ 0x6d01, 0x1b58,
+ 0x6d02, 0x4671,
+ 0x6d03, 0x1b5b,
+ 0x6d04, 0x1b50,
+ 0x6d05, 0x3a19,
+ 0x6d06, 0x4672,
+ 0x6d07, 0x1b5e,
+ 0x6d08, 0x1b61,
+ 0x6d09, 0x1b63,
+ 0x6d0a, 0x1b4d,
+ 0x6d0b, 0x0771,
+ 0x6d0c, 0x0776,
+ 0x6d0d, 0x1cf9,
+ 0x6d0e, 0x0786,
+ 0x6d0f, 0x1b5c,
+ 0x6d10, 0x1b64,
+ 0x6d11, 0x1b54,
+ 0x6d12, 0x1b4c,
+ 0x6d16, 0x1d14,
+ 0x6d17, 0x0779,
+ 0x6d18, 0x1b59,
+ 0x6d19, 0x1b51,
+ 0x6d1a, 0x1b53,
+ 0x6d1b, 0x077e,
+ 0x6d1d, 0x1b56,
+ 0x6d1e, 0x0778,
+ 0x6d1f, 0x1b49,
+ 0x6d20, 0x1b5f,
+ 0x6d22, 0x1b62,
+ 0x6d24, 0x3ac3,
+ 0x6d25, 0x0775,
+ 0x6d26, 0x4673,
+ 0x6d27, 0x0781,
+ 0x6d28, 0x1b46,
+ 0x6d29, 0x0783,
+ 0x6d2a, 0x0773,
+ 0x6d2b, 0x0787,
+ 0x6d2c, 0x1b60,
+ 0x6d2d, 0x1b48,
+ 0x6d2e, 0x0784,
+ 0x6d2f, 0x1d0e,
+ 0x6d30, 0x19e7,
+ 0x6d31, 0x0777,
+ 0x6d32, 0x0772,
+ 0x6d33, 0x1b4f,
+ 0x6d34, 0x1b47,
+ 0x6d35, 0x0785,
+ 0x6d36, 0x077d,
+ 0x6d37, 0x1b5a,
+ 0x6d38, 0x0782,
+ 0x6d39, 0x0780,
+ 0x6d3a, 0x1b52,
+ 0x6d3b, 0x077a,
+ 0x6d3c, 0x1b4a,
+ 0x6d3d, 0x077b,
+ 0x6d3f, 0x1b4b,
+ 0x6d40, 0x1b5d,
+ 0x6d41, 0x0774,
+ 0x6d42, 0x1b57,
+ 0x6d4e, 0x4558,
+ 0x6d57, 0x3cf3,
+ 0x6d58, 0x1cfc,
+ 0x6d59, 0x090f,
+ 0x6d5a, 0x0914,
+ 0x6d5b, 0x409c,
+ 0x6d5c, 0x4222,
+ 0x6d5e, 0x1d05,
+ 0x6d5f, 0x1d0b,
+ 0x6d60, 0x1d07,
+ 0x6d61, 0x1cfa,
+ 0x6d62, 0x1cfd,
+ 0x6d63, 0x1cf6,
+ 0x6d65, 0x091b,
+ 0x6d66, 0x090c,
+ 0x6d67, 0x1d06,
+ 0x6d68, 0x1d0f,
+ 0x6d69, 0x0916,
+ 0x6d6a, 0x0908,
+ 0x6d6c, 0x0911,
+ 0x6d6d, 0x1cfe,
+ 0x6d6e, 0x0913,
+ 0x6d6f, 0x1cff,
+ 0x6d70, 0x1d09,
+ 0x6d71, 0x40f5,
+ 0x6d72, 0x39d7,
+ 0x6d74, 0x0915,
+ 0x6d75, 0x1d18,
+ 0x6d76, 0x1cf8,
+ 0x6d77, 0x090e,
+ 0x6d78, 0x090d,
+ 0x6d79, 0x0919,
+ 0x6d7a, 0x1cf5,
+ 0x6d7b, 0x1d16,
+ 0x6d7c, 0x1d0a,
+ 0x6d7d, 0x1d17,
+ 0x6d7e, 0x1d11,
+ 0x6d7f, 0x1d03,
+ 0x6d80, 0x1d12,
+ 0x6d81, 0x4674,
+ 0x6d82, 0x1d0c,
+ 0x6d83, 0x1d15,
+ 0x6d84, 0x1d13,
+ 0x6d85, 0x091a,
+ 0x6d86, 0x1d04,
+ 0x6d87, 0x090b,
+ 0x6d88, 0x090a,
+ 0x6d89, 0x0912,
+ 0x6d8a, 0x0918,
+ 0x6d8b, 0x1d10,
+ 0x6d8c, 0x0917,
+ 0x6d8d, 0x1d01,
+ 0x6d8e, 0x0aec,
+ 0x6d8f, 0x3de8,
+ 0x6d90, 0x1d19,
+ 0x6d91, 0x1d00,
+ 0x6d92, 0x1cfb,
+ 0x6d93, 0x0910,
+ 0x6d94, 0x091c,
+ 0x6d95, 0x0909,
+ 0x6d96, 0x4221,
+ 0x6d97, 0x1d08,
+ 0x6d98, 0x1d0d,
+ 0x6da4, 0x4676,
+ 0x6da5, 0x3ab9,
+ 0x6daa, 0x0b0e,
+ 0x6dab, 0x1f46,
+ 0x6dac, 0x1f4a,
+ 0x6dae, 0x0afb,
+ 0x6daf, 0x0af9,
+ 0x6db1, 0x4677,
+ 0x6db2, 0x0af0,
+ 0x6db3, 0x1f48,
+ 0x6db4, 0x1f47,
+ 0x6db5, 0x0b04,
+ 0x6db7, 0x1f4d,
+ 0x6db8, 0x0afe,
+ 0x6db9, 0x3ffb,
+ 0x6dba, 0x1f5f,
+ 0x6dbb, 0x1f6b,
+ 0x6dbc, 0x0aed,
+ 0x6dbd, 0x1f5c,
+ 0x6dbe, 0x1f55,
+ 0x6dbf, 0x0b10,
+ 0x6dc0, 0x1f45,
+ 0x6dc2, 0x1f61,
+ 0x6dc4, 0x0b0d,
+ 0x6dc5, 0x0b01,
+ 0x6dc6, 0x0b0c,
+ 0x6dc7, 0x0af7,
+ 0x6dc8, 0x1f51,
+ 0x6dc9, 0x1f63,
+ 0x6dca, 0x1f5b,
+ 0x6dcb, 0x0af8,
+ 0x6dcc, 0x0af2,
+ 0x6dcd, 0x1f69,
+ 0x6dcf, 0x1f62,
+ 0x6dd0, 0x1f64,
+ 0x6dd1, 0x0afa,
+ 0x6dd2, 0x0b02,
+ 0x6dd3, 0x1f66,
+ 0x6dd4, 0x1f4f,
+ 0x6dd5, 0x1f60,
+ 0x6dd6, 0x1f54,
+ 0x6dd7, 0x1f68,
+ 0x6dd8, 0x0b07,
+ 0x6dd9, 0x0aef,
+ 0x6dda, 0x0b05,
+ 0x6ddb, 0x1f59,
+ 0x6ddc, 0x1f57,
+ 0x6dde, 0x0afc,
+ 0x6ddf, 0x1f53,
+ 0x6de0, 0x1f52,
+ 0x6de1, 0x0af1,
+ 0x6de2, 0x1f4c,
+ 0x6de3, 0x1f6a,
+ 0x6de4, 0x0af3,
+ 0x6de5, 0x1f56,
+ 0x6de6, 0x0b11,
+ 0x6de8, 0x0b0b,
+ 0x6de9, 0x1f4b,
+ 0x6dea, 0x0b08,
+ 0x6deb, 0x0b06,
+ 0x6dec, 0x0b0f,
+ 0x6ded, 0x1f5d,
+ 0x6dee, 0x0b0a,
+ 0x6def, 0x1d02,
+ 0x6df0, 0x1f5e,
+ 0x6df1, 0x0b09,
+ 0x6df2, 0x1f65,
+ 0x6df3, 0x0aee,
+ 0x6df4, 0x1f5a,
+ 0x6df5, 0x0b00,
+ 0x6df6, 0x1f4e,
+ 0x6df7, 0x0aff,
+ 0x6df9, 0x0afd,
+ 0x6dfa, 0x0af5,
+ 0x6dfb, 0x0af4,
+ 0x6dfc, 0x21bf,
+ 0x6dfd, 0x1f67,
+ 0x6e00, 0x1f50,
+ 0x6e02, 0x3cfa,
+ 0x6e03, 0x21d4,
+ 0x6e04, 0x3abe,
+ 0x6e05, 0x0af6,
+ 0x6e0a, 0x3ac1,
+ 0x6e0f, 0x3cf0,
+ 0x6e15, 0x4678,
+ 0x6e18, 0x4679,
+ 0x6e19, 0x0cc1,
+ 0x6e1a, 0x0b03,
+ 0x6e1b, 0x0caf,
+ 0x6e1c, 0x21ce,
+ 0x6e1d, 0x0cbd,
+ 0x6e1f, 0x21c2,
+ 0x6e20, 0x0cac,
+ 0x6e21, 0x0ca8,
+ 0x6e22, 0x21e0,
+ 0x6e23, 0x0cae,
+ 0x6e24, 0x0cb2,
+ 0x6e25, 0x0cad,
+ 0x6e26, 0x0cb6,
+ 0x6e27, 0x21e4,
+ 0x6e28, 0x21db,
+ 0x6e29, 0x467a,
+ 0x6e2a, 0x4302,
+ 0x6e2b, 0x21c9,
+ 0x6e2c, 0x0cbb,
+ 0x6e2d, 0x0cb5,
+ 0x6e2e, 0x21d5,
+ 0x6e2f, 0x0ca5,
+ 0x6e30, 0x21e1,
+ 0x6e31, 0x21da,
+ 0x6e32, 0x0ca9,
+ 0x6e33, 0x21cf,
+ 0x6e34, 0x0cb8,
+ 0x6e35, 0x21ec,
+ 0x6e38, 0x0ca6,
+ 0x6e39, 0x21df,
+ 0x6e3a, 0x0cba,
+ 0x6e3b, 0x21d3,
+ 0x6e3c, 0x21c5,
+ 0x6e3e, 0x0cbe,
+ 0x6e3f, 0x21ca,
+ 0x6e40, 0x21d1,
+ 0x6e41, 0x21cb,
+ 0x6e43, 0x0cbc,
+ 0x6e44, 0x0cc4,
+ 0x6e45, 0x21c7,
+ 0x6e46, 0x21c0,
+ 0x6e49, 0x21c3,
+ 0x6e4a, 0x0cab,
+ 0x6e4b, 0x21d0,
+ 0x6e4d, 0x0cb9,
+ 0x6e4e, 0x0cc2,
+ 0x6e4f, 0x4234,
+ 0x6e50, 0x41d1,
+ 0x6e51, 0x21d2,
+ 0x6e52, 0x21ea,
+ 0x6e53, 0x21e2,
+ 0x6e54, 0x0ca7,
+ 0x6e55, 0x21e8,
+ 0x6e56, 0x0cb3,
+ 0x6e58, 0x0cb1,
+ 0x6e59, 0x40e6,
+ 0x6e5a, 0x21ee,
+ 0x6e5b, 0x0cb0,
+ 0x6e5c, 0x21d8,
+ 0x6e5d, 0x21cc,
+ 0x6e5e, 0x21d6,
+ 0x6e5f, 0x0cc7,
+ 0x6e60, 0x21dc,
+ 0x6e61, 0x21d9,
+ 0x6e62, 0x21c8,
+ 0x6e63, 0x0cc3,
+ 0x6e64, 0x21e6,
+ 0x6e65, 0x21e3,
+ 0x6e66, 0x21eb,
+ 0x6e67, 0x0caa,
+ 0x6e68, 0x21d7,
+ 0x6e69, 0x0cc6,
+ 0x6e6b, 0x21de,
+ 0x6e6e, 0x0cb4,
+ 0x6e6f, 0x0cb7,
+ 0x6e71, 0x21dd,
+ 0x6e72, 0x0cc5,
+ 0x6e73, 0x21cd,
+ 0x6e74, 0x1f49,
+ 0x6e76, 0x39d3,
+ 0x6e77, 0x21e7,
+ 0x6e78, 0x21e5,
+ 0x6e79, 0x21e9,
+ 0x6e7c, 0x4223,
+ 0x6e86, 0x467b,
+ 0x6e88, 0x21c4,
+ 0x6e89, 0x0cc0,
+ 0x6e8b, 0x3bbf,
+ 0x6e8d, 0x246c,
+ 0x6e8e, 0x246b,
+ 0x6e8f, 0x2451,
+ 0x6e90, 0x0e55,
+ 0x6e92, 0x246a,
+ 0x6e93, 0x2454,
+ 0x6e96, 0x0e5f,
+ 0x6e97, 0x2473,
+ 0x6e98, 0x0e5a,
+ 0x6e99, 0x2469,
+ 0x6e9a, 0x4581,
+ 0x6e9b, 0x244e,
+ 0x6e9c, 0x0e60,
+ 0x6e9d, 0x0e56,
+ 0x6e9e, 0x245d,
+ 0x6e9f, 0x2453,
+ 0x6ea0, 0x2456,
+ 0x6ea1, 0x246e,
+ 0x6ea2, 0x0e50,
+ 0x6ea3, 0x2475,
+ 0x6ea4, 0x246d,
+ 0x6ea5, 0x0e59,
+ 0x6ea6, 0x2462,
+ 0x6ea7, 0x0e64,
+ 0x6eaa, 0x0e63,
+ 0x6eab, 0x0e5d,
+ 0x6eae, 0x2474,
+ 0x6eaf, 0x0e51,
+ 0x6eb0, 0x2460,
+ 0x6eb1, 0x2457,
+ 0x6eb2, 0x2464,
+ 0x6eb3, 0x2470,
+ 0x6eb4, 0x0e65,
+ 0x6eb5, 0x41fe,
+ 0x6eb6, 0x0e53,
+ 0x6eb7, 0x245f,
+ 0x6eb8, 0x3e0c,
+ 0x6eb9, 0x2458,
+ 0x6eba, 0x0e5c,
+ 0x6ebb, 0x467d,
+ 0x6ebc, 0x0e5b,
+ 0x6ebd, 0x245b,
+ 0x6ebe, 0x2465,
+ 0x6ebf, 0x246f,
+ 0x6ec0, 0x2452,
+ 0x6ec1, 0x245c,
+ 0x6ec2, 0x0e54,
+ 0x6ec3, 0x2466,
+ 0x6ec4, 0x0e61,
+ 0x6ec5, 0x0e58,
+ 0x6ec6, 0x2459,
+ 0x6ec7, 0x0e57,
+ 0x6ec8, 0x2450,
+ 0x6ec9, 0x245e,
+ 0x6eca, 0x2472,
+ 0x6ecb, 0x0cbf,
+ 0x6ecc, 0x101f,
+ 0x6ecd, 0x2461,
+ 0x6ece, 0x26eb,
+ 0x6ecf, 0x2463,
+ 0x6ed0, 0x2471,
+ 0x6ed1, 0x0e5e,
+ 0x6ed2, 0x245a,
+ 0x6ed3, 0x0e52,
+ 0x6ed4, 0x0e62,
+ 0x6ed5, 0x119a,
+ 0x6ed6, 0x244f,
+ 0x6ed8, 0x2468,
+ 0x6ed9, 0x4069,
+ 0x6eda, 0x467f,
+ 0x6edb, 0x402f,
+ 0x6edc, 0x2467,
+ 0x6edd, 0x4538,
+ 0x6ee2, 0x467e,
+ 0x6ee8, 0x4681,
+ 0x6eeb, 0x2707,
+ 0x6eec, 0x101c,
+ 0x6eed, 0x26fc,
+ 0x6eee, 0x2701,
+ 0x6eef, 0x1011,
+ 0x6ef1, 0x26ed,
+ 0x6ef2, 0x101e,
+ 0x6ef4, 0x1008,
+ 0x6ef5, 0x26ec,
+ 0x6ef6, 0x270d,
+ 0x6ef7, 0x1020,
+ 0x6ef8, 0x26f0,
+ 0x6ef9, 0x2700,
+ 0x6efa, 0x423b,
+ 0x6efb, 0x26f2,
+ 0x6efc, 0x2710,
+ 0x6efd, 0x270c,
+ 0x6efe, 0x1006,
+ 0x6eff, 0x1010,
+ 0x6f00, 0x2946,
+ 0x6f01, 0x101d,
+ 0x6f02, 0x100e,
+ 0x6f03, 0x26ee,
+ 0x6f04, 0x4224,
+ 0x6f05, 0x270b,
+ 0x6f06, 0x1012,
+ 0x6f07, 0x2708,
+ 0x6f08, 0x2715,
+ 0x6f09, 0x26f4,
+ 0x6f0a, 0x26fd,
+ 0x6f0b, 0x3aba,
+ 0x6f0c, 0x3cfb,
+ 0x6f0d, 0x2713,
+ 0x6f0e, 0x2709,
+ 0x6f0f, 0x100d,
+ 0x6f12, 0x26fb,
+ 0x6f13, 0x1007,
+ 0x6f14, 0x1005,
+ 0x6f15, 0x1017,
+ 0x6f16, 0x41a0,
+ 0x6f17, 0x46ce,
+ 0x6f18, 0x26f9,
+ 0x6f19, 0x26f6,
+ 0x6f1c, 0x270f,
+ 0x6f1e, 0x2714,
+ 0x6f1f, 0x2712,
+ 0x6f20, 0x100b,
+ 0x6f21, 0x2716,
+ 0x6f22, 0x100f,
+ 0x6f23, 0x1016,
+ 0x6f24, 0x4683,
+ 0x6f25, 0x26ef,
+ 0x6f26, 0x292e,
+ 0x6f27, 0x26f8,
+ 0x6f29, 0x1009,
+ 0x6f2a, 0x101b,
+ 0x6f2b, 0x1018,
+ 0x6f2c, 0x100c,
+ 0x6f2d, 0x2702,
+ 0x6f2e, 0x26f3,
+ 0x6f2f, 0x1019,
+ 0x6f30, 0x2704,
+ 0x6f31, 0x1013,
+ 0x6f32, 0x1015,
+ 0x6f33, 0x1004,
+ 0x6f34, 0x4684,
+ 0x6f35, 0x2706,
+ 0x6f36, 0x26fe,
+ 0x6f37, 0x26f1,
+ 0x6f38, 0x1014,
+ 0x6f39, 0x270e,
+ 0x6f3a, 0x2711,
+ 0x6f3b, 0x26fa,
+ 0x6f3c, 0x2705,
+ 0x6f3d, 0x4282,
+ 0x6f3e, 0x100a,
+ 0x6f3f, 0x1189,
+ 0x6f40, 0x2703,
+ 0x6f41, 0x292d,
+ 0x6f43, 0x270a,
+ 0x6f44, 0x4240,
+ 0x6f4e, 0x26f5,
+ 0x6f4f, 0x2937,
+ 0x6f50, 0x2941,
+ 0x6f51, 0x118c,
+ 0x6f52, 0x2940,
+ 0x6f53, 0x294c,
+ 0x6f54, 0x118e,
+ 0x6f55, 0x293e,
+ 0x6f56, 0x3e52,
+ 0x6f57, 0x2942,
+ 0x6f58, 0x1199,
+ 0x6f5a, 0x2939,
+ 0x6f5b, 0x1191,
+ 0x6f5c, 0x4241,
+ 0x6f5d, 0x2945,
+ 0x6f5e, 0x2b9a,
+ 0x6f5f, 0x119d,
+ 0x6f60, 0x119c,
+ 0x6f61, 0x2947,
+ 0x6f62, 0x2936,
+ 0x6f63, 0x2951,
+ 0x6f64, 0x1197,
+ 0x6f66, 0x118d,
+ 0x6f67, 0x294a,
+ 0x6f69, 0x294e,
+ 0x6f6a, 0x2953,
+ 0x6f6b, 0x2948,
+ 0x6f6c, 0x293c,
+ 0x6f6d, 0x1190,
+ 0x6f6e, 0x1193,
+ 0x6f6f, 0x119b,
+ 0x6f70, 0x1196,
+ 0x6f72, 0x293f,
+ 0x6f73, 0x26ff,
+ 0x6f74, 0x4243,
+ 0x6f76, 0x293b,
+ 0x6f77, 0x2952,
+ 0x6f78, 0x1192,
+ 0x6f79, 0x3bbe,
+ 0x6f7a, 0x1195,
+ 0x6f7b, 0x2954,
+ 0x6f7c, 0x118a,
+ 0x6f7d, 0x2949,
+ 0x6f7e, 0x292f,
+ 0x6f7f, 0x294f,
+ 0x6f80, 0x13fc,
+ 0x6f81, 0x4687,
+ 0x6f82, 0x293d,
+ 0x6f84, 0x118b,
+ 0x6f85, 0x2938,
+ 0x6f86, 0x118f,
+ 0x6f87, 0x2930,
+ 0x6f88, 0x101a,
+ 0x6f89, 0x2934,
+ 0x6f8a, 0x4195,
+ 0x6f8b, 0x294d,
+ 0x6f8c, 0x2935,
+ 0x6f8d, 0x2933,
+ 0x6f8e, 0x1194,
+ 0x6f90, 0x294b,
+ 0x6f92, 0x2932,
+ 0x6f93, 0x2944,
+ 0x6f94, 0x2943,
+ 0x6f95, 0x2950,
+ 0x6f96, 0x293a,
+ 0x6f97, 0x1198,
+ 0x6f9d, 0x4239,
+ 0x6f9e, 0x2b9d,
+ 0x6f9f, 0x4246,
+ 0x6fa0, 0x12eb,
+ 0x6fa1, 0x12e1,
+ 0x6fa2, 0x2ba9,
+ 0x6fa3, 0x2b95,
+ 0x6fa4, 0x12e3,
+ 0x6fa5, 0x2ba1,
+ 0x6fa6, 0x12ea,
+ 0x6fa7, 0x12e5,
+ 0x6fa8, 0x2b9f,
+ 0x6fa9, 0x2d8e,
+ 0x6faa, 0x2ba5,
+ 0x6fab, 0x2bab,
+ 0x6fac, 0x2ba4,
+ 0x6fad, 0x2b93,
+ 0x6fae, 0x2ba2,
+ 0x6faf, 0x2bad,
+ 0x6fb0, 0x2baf,
+ 0x6fb1, 0x12e0,
+ 0x6fb2, 0x2bae,
+ 0x6fb3, 0x12e6,
+ 0x6fb4, 0x12ec,
+ 0x6fb5, 0x3e27,
+ 0x6fb6, 0x12e9,
+ 0x6fb8, 0x2ba8,
+ 0x6fb9, 0x12e8,
+ 0x6fba, 0x2ba3,
+ 0x6fbb, 0x3bbb,
+ 0x6fbc, 0x2b97,
+ 0x6fbd, 0x2b9c,
+ 0x6fbe, 0x4688,
+ 0x6fbf, 0x2ba7,
+ 0x6fc0, 0x12e7,
+ 0x6fc1, 0x12e4,
+ 0x6fc2, 0x12df,
+ 0x6fc3, 0x12e2,
+ 0x6fc4, 0x2b9b,
+ 0x6fc6, 0x2931,
+ 0x6fc7, 0x2b96,
+ 0x6fc8, 0x2b99,
+ 0x6fc9, 0x2baa,
+ 0x6fca, 0x2b9e,
+ 0x6fcb, 0x2b94,
+ 0x6fcc, 0x2d8d,
+ 0x6fcd, 0x2bac,
+ 0x6fce, 0x2b98,
+ 0x6fcf, 0x2ba6,
+ 0x6fd3, 0x4248,
+ 0x6fd4, 0x2d90,
+ 0x6fd5, 0x1400,
+ 0x6fd8, 0x13f4,
+ 0x6fd9, 0x3c74,
+ 0x6fda, 0x3c73,
+ 0x6fdb, 0x13f8,
+ 0x6fdc, 0x2d92,
+ 0x6fdd, 0x2d98,
+ 0x6fde, 0x2d96,
+ 0x6fdf, 0x13f6,
+ 0x6fe1, 0x13fe,
+ 0x6fe2, 0x2d99,
+ 0x6fe3, 0x2d91,
+ 0x6fe4, 0x13f9,
+ 0x6fe6, 0x2d95,
+ 0x6fe7, 0x2d94,
+ 0x6fe8, 0x2d9a,
+ 0x6fe9, 0x13ff,
+ 0x6feb, 0x13fa,
+ 0x6fec, 0x13fd,
+ 0x6fed, 0x2d93,
+ 0x6fee, 0x1401,
+ 0x6fef, 0x13fb,
+ 0x6ff0, 0x1402,
+ 0x6ff1, 0x13f5,
+ 0x6ff2, 0x2d97,
+ 0x6ff4, 0x2d8f,
+ 0x6ff6, 0x38a5,
+ 0x6ff7, 0x2f4e,
+ 0x6ff8, 0x4237,
+ 0x6ffa, 0x14eb,
+ 0x6ffb, 0x2f4b,
+ 0x6ffc, 0x2f4d,
+ 0x6ffe, 0x14e9,
+ 0x6fff, 0x2f49,
+ 0x7000, 0x2f4a,
+ 0x7001, 0x2f45,
+ 0x7003, 0x46e2,
+ 0x7004, 0x2ba0,
+ 0x7005, 0x2f46,
+ 0x7006, 0x14ea,
+ 0x7007, 0x2f42,
+ 0x7009, 0x14e7,
+ 0x700a, 0x2f4f,
+ 0x700b, 0x14e8,
+ 0x700c, 0x2f43,
+ 0x700e, 0x2f48,
+ 0x700f, 0x14ed,
+ 0x7011, 0x14ec,
+ 0x7014, 0x2f47,
+ 0x7015, 0x158f,
+ 0x7016, 0x30ad,
+ 0x7017, 0x30b3,
+ 0x7018, 0x1590,
+ 0x7019, 0x30aa,
+ 0x701a, 0x158d,
+ 0x701b, 0x158a,
+ 0x701c, 0x30b5,
+ 0x701d, 0x158e,
+ 0x701e, 0x3c76,
+ 0x701f, 0x158b,
+ 0x7020, 0x30ac,
+ 0x7021, 0x30af,
+ 0x7024, 0x30b4,
+ 0x7026, 0x2f4c,
+ 0x7027, 0x30ab,
+ 0x7028, 0x158c,
+ 0x7029, 0x30b2,
+ 0x702a, 0x31ef,
+ 0x702b, 0x30ae,
+ 0x702c, 0x468e,
+ 0x702f, 0x31e6,
+ 0x7030, 0x161d,
+ 0x7031, 0x31e9,
+ 0x7032, 0x161e,
+ 0x7033, 0x31f2,
+ 0x7034, 0x31e8,
+ 0x7035, 0x31e5,
+ 0x7037, 0x31e7,
+ 0x7038, 0x31eb,
+ 0x7039, 0x31ee,
+ 0x703a, 0x31ed,
+ 0x703b, 0x31f1,
+ 0x703c, 0x31e4,
+ 0x703e, 0x161c,
+ 0x703f, 0x31ec,
+ 0x7040, 0x31f0,
+ 0x7041, 0x31f3,
+ 0x7042, 0x31ea,
+ 0x7043, 0x32d8,
+ 0x7045, 0x32dd,
+ 0x7048, 0x32db,
+ 0x704a, 0x32da,
+ 0x704b, 0x4254,
+ 0x704c, 0x167a,
+ 0x7050, 0x4690,
+ 0x7051, 0x16c8,
+ 0x7052, 0x338c,
+ 0x7054, 0x4691,
+ 0x7055, 0x3389,
+ 0x7058, 0x16c9,
+ 0x705a, 0x3423,
+ 0x705b, 0x3422,
+ 0x705c, 0x3852,
+ 0x705d, 0x348a,
+ 0x705e, 0x1722,
+ 0x705f, 0x3488,
+ 0x7060, 0x348b,
+ 0x7061, 0x3489,
+ 0x7062, 0x34d0,
+ 0x7063, 0x1744,
+ 0x7064, 0x1752,
+ 0x7065, 0x351c,
+ 0x7066, 0x3506,
+ 0x7067, 0x3cf5,
+ 0x7068, 0x351b,
+ 0x7069, 0x3547,
+ 0x706b, 0x02e6,
+ 0x706c, 0x44f1,
+ 0x706f, 0x4692,
+ 0x7070, 0x03f2,
+ 0x7071, 0x180a,
+ 0x7074, 0x18c3,
+ 0x7075, 0x38c7,
+ 0x7076, 0x04e6,
+ 0x7078, 0x04e9,
+ 0x7079, 0x4099,
+ 0x707a, 0x18c4,
+ 0x707c, 0x04e7,
+ 0x707e, 0x4255,
+ 0x707f, 0x4693,
+ 0x7081, 0x4959,
+ 0x7082, 0x19f7,
+ 0x7083, 0x19f9,
+ 0x7084, 0x19f4,
+ 0x7085, 0x19f1,
+ 0x7086, 0x19f3,
+ 0x7089, 0x43f9,
+ 0x708a, 0x0643,
+ 0x708b, 0x40cb,
+ 0x708e, 0x0641,
+ 0x708f, 0x46b3,
+ 0x7091, 0x19f5,
+ 0x7092, 0x0642,
+ 0x7093, 0x19f2,
+ 0x7094, 0x19ef,
+ 0x7095, 0x0640,
+ 0x7096, 0x19f6,
+ 0x7098, 0x19f0,
+ 0x7099, 0x0644,
+ 0x709a, 0x19f8,
+ 0x709f, 0x1b66,
+ 0x70a0, 0x4742,
+ 0x70a1, 0x1b6a,
+ 0x70a3, 0x3972,
+ 0x70a4, 0x0790,
+ 0x70a5, 0x3cb7,
+ 0x70a6, 0x3d53,
+ 0x70a7, 0x4256,
+ 0x70a9, 0x1b6d,
+ 0x70ab, 0x0788,
+ 0x70ac, 0x078b,
+ 0x70ad, 0x078d,
+ 0x70ae, 0x078f,
+ 0x70af, 0x078c,
+ 0x70b0, 0x1b69,
+ 0x70b1, 0x1b68,
+ 0x70b3, 0x078a,
+ 0x70b4, 0x1b6b,
+ 0x70b7, 0x1b65,
+ 0x70b8, 0x078e,
+ 0x70b9, 0x3d69,
+ 0x70ba, 0x0789,
+ 0x70bb, 0x4812,
+ 0x70bc, 0x4559,
+ 0x70bd, 0x4270,
+ 0x70be, 0x1b67,
+ 0x70c0, 0x4733,
+ 0x70c4, 0x3baa,
+ 0x70c5, 0x1d27,
+ 0x70c8, 0x0921,
+ 0x70ca, 0x091d,
+ 0x70cb, 0x1d1e,
+ 0x70cc, 0x4258,
+ 0x70cd, 0x1d26,
+ 0x70ce, 0x1d2b,
+ 0x70cf, 0x0922,
+ 0x70d0, 0x396d,
+ 0x70d1, 0x1d1c,
+ 0x70d2, 0x1d22,
+ 0x70d3, 0x1d1b,
+ 0x70d4, 0x1d25,
+ 0x70d5, 0x4259,
+ 0x70d7, 0x1d21,
+ 0x70d8, 0x091e,
+ 0x70d9, 0x0920,
+ 0x70da, 0x1d2a,
+ 0x70dc, 0x1d1a,
+ 0x70dd, 0x1d1d,
+ 0x70de, 0x1d23,
+ 0x70df, 0x425b,
+ 0x70e0, 0x1d24,
+ 0x70e1, 0x1d2c,
+ 0x70e2, 0x1d20,
+ 0x70e4, 0x091f,
+ 0x70ef, 0x0b16,
+ 0x70f0, 0x1f72,
+ 0x70f1, 0x3ac8,
+ 0x70f3, 0x1f74,
+ 0x70f4, 0x1f70,
+ 0x70f5, 0x4760,
+ 0x70f6, 0x1f7c,
+ 0x70f7, 0x1f6e,
+ 0x70f8, 0x1f7b,
+ 0x70f9, 0x0b12,
+ 0x70fa, 0x1f6c,
+ 0x70fb, 0x21f2,
+ 0x70fc, 0x1f76,
+ 0x70fd, 0x0b15,
+ 0x70fe, 0x3d0e,
+ 0x70ff, 0x1f77,
+ 0x7100, 0x1f7a,
+ 0x7102, 0x1f7e,
+ 0x7104, 0x1f73,
+ 0x7105, 0x3a23,
+ 0x7106, 0x1f78,
+ 0x7109, 0x0b13,
+ 0x710b, 0x1f7d,
+ 0x710c, 0x1f71,
+ 0x710d, 0x1f6d,
+ 0x710e, 0x1f7f,
+ 0x7110, 0x1f75,
+ 0x7113, 0x1f79,
+ 0x7117, 0x1f6f,
+ 0x7119, 0x0cc8,
+ 0x711b, 0x21fc,
+ 0x711c, 0x0ccf,
+ 0x711d, 0x3d47,
+ 0x711e, 0x21f0,
+ 0x711f, 0x21f9,
+ 0x7120, 0x21ef,
+ 0x7121, 0x0ccc,
+ 0x7122, 0x21f7,
+ 0x7123, 0x21f5,
+ 0x7125, 0x21f6,
+ 0x7126, 0x0cca,
+ 0x7128, 0x21fa,
+ 0x7129, 0x3ba9,
+ 0x712b, 0x4261,
+ 0x712c, 0x426a,
+ 0x712e, 0x21f3,
+ 0x712f, 0x21f1,
+ 0x7130, 0x0ccb,
+ 0x7131, 0x21f4,
+ 0x7132, 0x21f8,
+ 0x7133, 0x3d54,
+ 0x7134, 0x3c7e,
+ 0x7135, 0x376d,
+ 0x7136, 0x0ccd,
+ 0x713a, 0x21fb,
+ 0x713b, 0x3ac5,
+ 0x713e, 0x372e,
+ 0x7140, 0x4398,
+ 0x7141, 0x247b,
+ 0x7142, 0x2482,
+ 0x7143, 0x2484,
+ 0x7144, 0x248a,
+ 0x7145, 0x4262,
+ 0x7146, 0x0e72,
+ 0x7147, 0x2476,
+ 0x7149, 0x0e6a,
+ 0x714a, 0x4264,
+ 0x714b, 0x2485,
+ 0x714c, 0x0e6f,
+ 0x714d, 0x248b,
+ 0x714e, 0x0e66,
+ 0x714f, 0x4267,
+ 0x7150, 0x2488,
+ 0x7151, 0x4865,
+ 0x7152, 0x2478,
+ 0x7153, 0x2489,
+ 0x7154, 0x2477,
+ 0x7156, 0x0e74,
+ 0x7158, 0x2483,
+ 0x7159, 0x0e67,
+ 0x715a, 0x248c,
+ 0x715c, 0x0e6c,
+ 0x715d, 0x247c,
+ 0x715e, 0x0e71,
+ 0x715f, 0x2487,
+ 0x7160, 0x247a,
+ 0x7161, 0x2481,
+ 0x7162, 0x247d,
+ 0x7163, 0x2479,
+ 0x7164, 0x0e69,
+ 0x7165, 0x0e70,
+ 0x7166, 0x0e6e,
+ 0x7167, 0x0e6b,
+ 0x7168, 0x0e73,
+ 0x7169, 0x0e68,
+ 0x716a, 0x2480,
+ 0x716b, 0x3cc5,
+ 0x716c, 0x0e6d,
+ 0x716e, 0x0cce,
+ 0x7170, 0x2486,
+ 0x7171, 0x3dc0,
+ 0x7172, 0x247e,
+ 0x7173, 0x47e7,
+ 0x7175, 0x3ced,
+ 0x7176, 0x4000,
+ 0x7177, 0x3957,
+ 0x7178, 0x247f,
+ 0x717a, 0x4924,
+ 0x717b, 0x271e,
+ 0x717c, 0x3835,
+ 0x717d, 0x1023,
+ 0x717e, 0x3970,
+ 0x7180, 0x271a,
+ 0x7181, 0x2720,
+ 0x7182, 0x271c,
+ 0x7184, 0x1025,
+ 0x7185, 0x271b,
+ 0x7186, 0x271f,
+ 0x7187, 0x2717,
+ 0x7188, 0x4706,
+ 0x7189, 0x2719,
+ 0x718a, 0x1024,
+ 0x718c, 0x39ea,
+ 0x718e, 0x3d3b,
+ 0x718f, 0x271d,
+ 0x7190, 0x2718,
+ 0x7192, 0x1026,
+ 0x7194, 0x1021,
+ 0x7196, 0x425f,
+ 0x7197, 0x2721,
+ 0x7198, 0x481d,
+ 0x7199, 0x1022,
+ 0x719a, 0x295a,
+ 0x719b, 0x2957,
+ 0x719c, 0x2963,
+ 0x719d, 0x295d,
+ 0x719e, 0x295f,
+ 0x719f, 0x119e,
+ 0x71a0, 0x2959,
+ 0x71a1, 0x2961,
+ 0x71a2, 0x48c1,
+ 0x71a3, 0x3ec8,
+ 0x71a4, 0x2960,
+ 0x71a5, 0x295e,
+ 0x71a7, 0x2964,
+ 0x71a8, 0x11a1,
+ 0x71a9, 0x295b,
+ 0x71aa, 0x2962,
+ 0x71ac, 0x119f,
+ 0x71ad, 0x3e1d,
+ 0x71af, 0x2956,
+ 0x71b0, 0x2958,
+ 0x71b1, 0x11a0,
+ 0x71b2, 0x2955,
+ 0x71b3, 0x2965,
+ 0x71b4, 0x425e,
+ 0x71b5, 0x295c,
+ 0x71b7, 0x468b,
+ 0x71b8, 0x2bb3,
+ 0x71b9, 0x12f3,
+ 0x71ba, 0x426e,
+ 0x71bc, 0x2bbe,
+ 0x71bd, 0x2bbc,
+ 0x71be, 0x12ed,
+ 0x71bf, 0x2bb2,
+ 0x71c0, 0x2bb5,
+ 0x71c2, 0x2bb1,
+ 0x71c3, 0x12f7,
+ 0x71c5, 0x2bb0,
+ 0x71c6, 0x2bbf,
+ 0x71c7, 0x2bba,
+ 0x71c8, 0x12f1,
+ 0x71c9, 0x12ee,
+ 0x71ca, 0x2bb9,
+ 0x71cb, 0x2bb7,
+ 0x71ce, 0x12f4,
+ 0x71cf, 0x2bbb,
+ 0x71d0, 0x12ef,
+ 0x71d1, 0x373d,
+ 0x71d2, 0x12f0,
+ 0x71d4, 0x2bb8,
+ 0x71d5, 0x12f2,
+ 0x71d6, 0x2bb4,
+ 0x71d8, 0x2bbd,
+ 0x71d9, 0x12f5,
+ 0x71da, 0x2bc0,
+ 0x71dc, 0x12f6,
+ 0x71dd, 0x4078,
+ 0x71df, 0x1404,
+ 0x71e0, 0x140b,
+ 0x71e1, 0x2d9b,
+ 0x71e2, 0x2da1,
+ 0x71e4, 0x2d9f,
+ 0x71e5, 0x1407,
+ 0x71e6, 0x1406,
+ 0x71e7, 0x1403,
+ 0x71e8, 0x2d9d,
+ 0x71eb, 0x3c81,
+ 0x71ec, 0x1409,
+ 0x71ed, 0x1408,
+ 0x71ee, 0x1405,
+ 0x71f0, 0x2da0,
+ 0x71f1, 0x2d9c,
+ 0x71f2, 0x2d9e,
+ 0x71f4, 0x140a,
+ 0x71f5, 0x46ee,
+ 0x71f6, 0x3e9a,
+ 0x71f8, 0x14f1,
+ 0x71f9, 0x2f52,
+ 0x71fb, 0x14ee,
+ 0x71fd, 0x2f54,
+ 0x71fe, 0x14f0,
+ 0x71ff, 0x2f51,
+ 0x7201, 0x2f50,
+ 0x7202, 0x30b9,
+ 0x7203, 0x2f53,
+ 0x7205, 0x30ba,
+ 0x7206, 0x1591,
+ 0x7207, 0x30b8,
+ 0x7209, 0x3dbb,
+ 0x720a, 0x30b7,
+ 0x720c, 0x30b6,
+ 0x720d, 0x1592,
+ 0x720e, 0x4271,
+ 0x720f, 0x39fc,
+ 0x7210, 0x161f,
+ 0x7213, 0x31f4,
+ 0x7215, 0x4273,
+ 0x7216, 0x3953,
+ 0x7217, 0x3969,
+ 0x7219, 0x32e1,
+ 0x721a, 0x32e0,
+ 0x721b, 0x167b,
+ 0x721d, 0x32df,
+ 0x721e, 0x338d,
+ 0x7222, 0x3424,
+ 0x7223, 0x348c,
+ 0x7224, 0x4276,
+ 0x7226, 0x34d1,
+ 0x7227, 0x3535,
+ 0x7228, 0x1766,
+ 0x7229, 0x3549,
+ 0x722a, 0x02e7,
+ 0x722b, 0x44f2,
+ 0x722c, 0x0645,
+ 0x722e, 0x4279,
+ 0x7230, 0x0791,
+ 0x7235, 0x140c,
+ 0x7236, 0x02e8,
+ 0x7238, 0x0647,
+ 0x7239, 0x0923,
+ 0x723a, 0x0e75,
+ 0x723b, 0x02e9,
+ 0x723d, 0x0b17,
+ 0x723e, 0x1027,
+ 0x723f, 0x178d,
+ 0x7240, 0x427a,
+ 0x7241, 0x1b6e,
+ 0x7242, 0x1d2d,
+ 0x7244, 0x2722,
+ 0x7246, 0x140d,
+ 0x7247, 0x02ea,
+ 0x7248, 0x0648,
+ 0x7249, 0x1b6f,
+ 0x724b, 0x21fd,
+ 0x724c, 0x0cd0,
+ 0x724f, 0x248d,
+ 0x7250, 0x3ac9,
+ 0x7252, 0x0e76,
+ 0x7253, 0x2723,
+ 0x7255, 0x427d,
+ 0x7256, 0x11a2,
+ 0x7257, 0x427e,
+ 0x7258, 0x1593,
+ 0x7259, 0x02eb,
+ 0x725a, 0x21fe,
+ 0x725b, 0x02ec,
+ 0x725c, 0x465a,
+ 0x725d, 0x03f4,
+ 0x725e, 0x180b,
+ 0x725f, 0x03f3,
+ 0x7260, 0x04ec,
+ 0x7261, 0x04eb,
+ 0x7262, 0x04ea,
+ 0x7263, 0x18c5,
+ 0x7266, 0x3ebb,
+ 0x7267, 0x0649,
+ 0x7269, 0x064a,
+ 0x726a, 0x19fa,
+ 0x726c, 0x1b71,
+ 0x726e, 0x1b74,
+ 0x726f, 0x0793,
+ 0x7270, 0x1b72,
+ 0x7272, 0x0792,
+ 0x7273, 0x1b73,
+ 0x7274, 0x0794,
+ 0x7276, 0x1d30,
+ 0x7277, 0x1d2f,
+ 0x7278, 0x1d2e,
+ 0x7279, 0x0924,
+ 0x727b, 0x1f81,
+ 0x727d, 0x0b18,
+ 0x727e, 0x1f80,
+ 0x727f, 0x1f83,
+ 0x7280, 0x0cd2,
+ 0x7281, 0x0b19,
+ 0x7282, 0x4283,
+ 0x7284, 0x0cd1,
+ 0x7285, 0x2202,
+ 0x7286, 0x2201,
+ 0x7287, 0x3aca,
+ 0x7288, 0x21ff,
+ 0x728b, 0x2203,
+ 0x728c, 0x248f,
+ 0x728d, 0x248e,
+ 0x728e, 0x2492,
+ 0x728f, 0x43c9,
+ 0x7290, 0x2491,
+ 0x7291, 0x2490,
+ 0x7292, 0x1028,
+ 0x7293, 0x2726,
+ 0x7294, 0x3acb,
+ 0x7295, 0x2725,
+ 0x7296, 0x1029,
+ 0x7297, 0x2724,
+ 0x7298, 0x2966,
+ 0x729a, 0x2967,
+ 0x729b, 0x11a3,
+ 0x729d, 0x2bc2,
+ 0x729f, 0x473a,
+ 0x72a1, 0x30bf,
+ 0x72a2, 0x1594,
+ 0x72a3, 0x30be,
+ 0x72a4, 0x30bd,
+ 0x72a5, 0x30bb,
+ 0x72a7, 0x167c,
+ 0x72a8, 0x31f6,
+ 0x72a9, 0x338f,
+ 0x72aa, 0x34d2,
+ 0x72ac, 0x02ed,
+ 0x72ad, 0x44f4,
+ 0x72ae, 0x17af,
+ 0x72af, 0x0355,
+ 0x72b0, 0x17b0,
+ 0x72b2, 0x3fb6,
+ 0x72b4, 0x180c,
+ 0x72ba, 0x18cb,
+ 0x72bd, 0x18c7,
+ 0x72bf, 0x18c6,
+ 0x72c0, 0x064b,
+ 0x72c1, 0x18ca,
+ 0x72c2, 0x04ee,
+ 0x72c3, 0x18c8,
+ 0x72c4, 0x04ed,
+ 0x72c5, 0x18cc,
+ 0x72c6, 0x18c9,
+ 0x72c9, 0x19fe,
+ 0x72ca, 0x1b75,
+ 0x72cb, 0x19fc,
+ 0x72cc, 0x1a03,
+ 0x72cd, 0x43ca,
+ 0x72ce, 0x064c,
+ 0x72d0, 0x064f,
+ 0x72d1, 0x1a04,
+ 0x72d2, 0x1a00,
+ 0x72d4, 0x1a01,
+ 0x72d6, 0x19fb,
+ 0x72d7, 0x064e,
+ 0x72d8, 0x19fd,
+ 0x72d9, 0x064d,
+ 0x72da, 0x1a02,
+ 0x72dc, 0x19ff,
+ 0x72df, 0x1b79,
+ 0x72e0, 0x0796,
+ 0x72e2, 0x3f97,
+ 0x72e3, 0x1b7c,
+ 0x72e4, 0x1b76,
+ 0x72e6, 0x1b7b,
+ 0x72e8, 0x1b77,
+ 0x72e9, 0x0795,
+ 0x72ea, 0x1b7a,
+ 0x72eb, 0x1b78,
+ 0x72f3, 0x1d36,
+ 0x72f4, 0x1d33,
+ 0x72f6, 0x1d35,
+ 0x72f7, 0x0929,
+ 0x72f8, 0x0928,
+ 0x72f9, 0x0926,
+ 0x72fa, 0x1d32,
+ 0x72fb, 0x1d37,
+ 0x72fc, 0x0925,
+ 0x72fd, 0x0927,
+ 0x72fe, 0x1d34,
+ 0x72ff, 0x1f8b,
+ 0x7300, 0x1d31,
+ 0x7301, 0x1d38,
+ 0x7302, 0x3f9a,
+ 0x7304, 0x3eb5,
+ 0x7307, 0x1f86,
+ 0x7308, 0x1f8a,
+ 0x730a, 0x1f89,
+ 0x730b, 0x2205,
+ 0x730c, 0x2210,
+ 0x730f, 0x1f8c,
+ 0x7310, 0x46ea,
+ 0x7311, 0x1f87,
+ 0x7312, 0x2204,
+ 0x7313, 0x0b1d,
+ 0x7316, 0x0b1c,
+ 0x7317, 0x1f85,
+ 0x7318, 0x1f88,
+ 0x7319, 0x0b1e,
+ 0x731b, 0x0b1b,
+ 0x731c, 0x0b1a,
+ 0x731d, 0x1f84,
+ 0x731e, 0x1f8d,
+ 0x7322, 0x2207,
+ 0x7323, 0x220e,
+ 0x7325, 0x0cd4,
+ 0x7326, 0x220d,
+ 0x7327, 0x220a,
+ 0x7328, 0x428a,
+ 0x7329, 0x0cd6,
+ 0x732a, 0x3d70,
+ 0x732b, 0x4285,
+ 0x732c, 0x3fb2,
+ 0x732d, 0x220c,
+ 0x732e, 0x428b,
+ 0x7330, 0x2206,
+ 0x7331, 0x2208,
+ 0x7332, 0x220b,
+ 0x7333, 0x2209,
+ 0x7334, 0x0cd5,
+ 0x7335, 0x220f,
+ 0x7336, 0x0cd3,
+ 0x7337, 0x0e77,
+ 0x7338, 0x46eb,
+ 0x7339, 0x43cc,
+ 0x733a, 0x2496,
+ 0x733b, 0x2495,
+ 0x733c, 0x2493,
+ 0x733e, 0x0e7a,
+ 0x733f, 0x0e79,
+ 0x7340, 0x2497,
+ 0x7341, 0x46ec,
+ 0x7342, 0x2494,
+ 0x7343, 0x2727,
+ 0x7344, 0x102a,
+ 0x7345, 0x0e78,
+ 0x7348, 0x43fa,
+ 0x7349, 0x2499,
+ 0x734a, 0x2498,
+ 0x734c, 0x272a,
+ 0x734d, 0x2728,
+ 0x734e, 0x11a4,
+ 0x734f, 0x3f51,
+ 0x7350, 0x102b,
+ 0x7351, 0x2729,
+ 0x7352, 0x2969,
+ 0x7357, 0x11a5,
+ 0x7358, 0x2968,
+ 0x7359, 0x2971,
+ 0x735a, 0x2970,
+ 0x735b, 0x296e,
+ 0x735d, 0x296d,
+ 0x735e, 0x296a,
+ 0x7361, 0x296f,
+ 0x7362, 0x2972,
+ 0x7365, 0x2bc8,
+ 0x7366, 0x2bc5,
+ 0x7368, 0x12f9,
+ 0x7369, 0x2bc4,
+ 0x736a, 0x2bca,
+ 0x736b, 0x2bc9,
+ 0x736c, 0x2bc7,
+ 0x736e, 0x2da3,
+ 0x7370, 0x140e,
+ 0x7371, 0x3f98,
+ 0x7372, 0x140f,
+ 0x7373, 0x2da2,
+ 0x7374, 0x3ed4,
+ 0x7375, 0x14f3,
+ 0x7376, 0x2f55,
+ 0x7377, 0x14f2,
+ 0x7378, 0x1595,
+ 0x737a, 0x1596,
+ 0x737b, 0x1620,
+ 0x737c, 0x31f8,
+ 0x737d, 0x31f7,
+ 0x737e, 0x32e2,
+ 0x737f, 0x3390,
+ 0x7380, 0x16ca,
+ 0x7381, 0x3426,
+ 0x7382, 0x3425,
+ 0x7383, 0x3427,
+ 0x7384, 0x0356,
+ 0x7385, 0x1b7d,
+ 0x7386, 0x092a,
+ 0x7387, 0x0b1f,
+ 0x7388, 0x1f8e,
+ 0x7389, 0x0357,
+ 0x738a, 0x17b1,
+ 0x738b, 0x02ee,
+ 0x738e, 0x180e,
+ 0x738f, 0x46e5,
+ 0x7392, 0x18d1,
+ 0x7393, 0x18cf,
+ 0x7395, 0x18cd,
+ 0x7396, 0x04ef,
+ 0x7397, 0x18ce,
+ 0x7398, 0x39f6,
+ 0x739c, 0x408a,
+ 0x739d, 0x1a0c,
+ 0x739e, 0x395b,
+ 0x739f, 0x0652,
+ 0x73a0, 0x1a0a,
+ 0x73a1, 0x1a06,
+ 0x73a2, 0x1a09,
+ 0x73a4, 0x1a05,
+ 0x73a5, 0x0654,
+ 0x73a6, 0x1a08,
+ 0x73a7, 0x4087,
+ 0x73a8, 0x0651,
+ 0x73a9, 0x0650,
+ 0x73aa, 0x428d,
+ 0x73ab, 0x0653,
+ 0x73ac, 0x1a0b,
+ 0x73ad, 0x1a07,
+ 0x73b2, 0x079b,
+ 0x73b3, 0x079e,
+ 0x73b4, 0x1b85,
+ 0x73b5, 0x1b84,
+ 0x73b6, 0x1b83,
+ 0x73b7, 0x0798,
+ 0x73b8, 0x1b8c,
+ 0x73b9, 0x1b82,
+ 0x73bb, 0x079a,
+ 0x73bc, 0x1d3d,
+ 0x73be, 0x1b89,
+ 0x73bf, 0x1b87,
+ 0x73c0, 0x079d,
+ 0x73c2, 0x1b7f,
+ 0x73c3, 0x1b8a,
+ 0x73c5, 0x1b81,
+ 0x73c6, 0x1b8b,
+ 0x73c7, 0x1b88,
+ 0x73c8, 0x1b80,
+ 0x73c9, 0x4290,
+ 0x73ca, 0x0799,
+ 0x73cb, 0x1b8d,
+ 0x73cc, 0x1b7e,
+ 0x73cd, 0x079c,
+ 0x73ce, 0x411b,
+ 0x73cf, 0x428c,
+ 0x73d0, 0x3b17,
+ 0x73d2, 0x1d42,
+ 0x73d3, 0x1d39,
+ 0x73d4, 0x1d44,
+ 0x73d5, 0x4073,
+ 0x73d6, 0x1d3c,
+ 0x73d7, 0x1d47,
+ 0x73d9, 0x1d3a,
+ 0x73da, 0x1d46,
+ 0x73db, 0x1d43,
+ 0x73dc, 0x1d41,
+ 0x73dd, 0x1d45,
+ 0x73de, 0x0930,
+ 0x73e0, 0x092e,
+ 0x73e1, 0x46f0,
+ 0x73e2, 0x3ca3,
+ 0x73e3, 0x1d3f,
+ 0x73e4, 0x42a5,
+ 0x73e5, 0x1d3b,
+ 0x73e6, 0x3cba,
+ 0x73e7, 0x1d3e,
+ 0x73e8, 0x1d49,
+ 0x73e9, 0x1d40,
+ 0x73ea, 0x092f,
+ 0x73eb, 0x1b86,
+ 0x73ed, 0x092b,
+ 0x73ee, 0x092d,
+ 0x73ef, 0x4011,
+ 0x73f3, 0x3cab,
+ 0x73f4, 0x1f9c,
+ 0x73f5, 0x1f91,
+ 0x73f6, 0x1f8f,
+ 0x73f7, 0x429a,
+ 0x73f8, 0x1f90,
+ 0x73f9, 0x3bf9,
+ 0x73fa, 0x1f97,
+ 0x73fb, 0x3cac,
+ 0x73fc, 0x1f98,
+ 0x73fd, 0x1f94,
+ 0x73fe, 0x0b24,
+ 0x73ff, 0x1f99,
+ 0x7400, 0x1f96,
+ 0x7401, 0x1f93,
+ 0x7403, 0x0b22,
+ 0x7404, 0x1f92,
+ 0x7405, 0x0b20,
+ 0x7406, 0x0b23,
+ 0x7407, 0x1f95,
+ 0x7408, 0x1f9d,
+ 0x7409, 0x092c,
+ 0x740a, 0x0b21,
+ 0x740b, 0x1f9b,
+ 0x740c, 0x1f9a,
+ 0x740d, 0x0b25,
+ 0x7411, 0x456c,
+ 0x7412, 0x3be6,
+ 0x7414, 0x39f4,
+ 0x7415, 0x429b,
+ 0x7416, 0x2215,
+ 0x7417, 0x40ad,
+ 0x7419, 0x46f3,
+ 0x741a, 0x2216,
+ 0x741b, 0x0ce0,
+ 0x741c, 0x38dd,
+ 0x741d, 0x221c,
+ 0x741e, 0x46f4,
+ 0x7420, 0x221e,
+ 0x7421, 0x2217,
+ 0x7422, 0x0cda,
+ 0x7423, 0x221b,
+ 0x7424, 0x221a,
+ 0x7425, 0x0cdb,
+ 0x7426, 0x0ce1,
+ 0x7428, 0x0ce2,
+ 0x7429, 0x221d,
+ 0x742a, 0x0cd8,
+ 0x742b, 0x2214,
+ 0x742c, 0x2212,
+ 0x742d, 0x2218,
+ 0x742e, 0x2211,
+ 0x742f, 0x0cdf,
+ 0x7430, 0x2213,
+ 0x7431, 0x2219,
+ 0x7432, 0x221f,
+ 0x7433, 0x0cd9,
+ 0x7434, 0x0cde,
+ 0x7435, 0x0cdc,
+ 0x7437, 0x3ae1,
+ 0x7438, 0x3b09,
+ 0x7439, 0x429e,
+ 0x743a, 0x0cd7,
+ 0x743c, 0x3adf,
+ 0x743f, 0x0e81,
+ 0x7440, 0x24a0,
+ 0x7441, 0x0e80,
+ 0x7442, 0x24a4,
+ 0x7443, 0x3a1a,
+ 0x7444, 0x249a,
+ 0x7445, 0x3bd7,
+ 0x7446, 0x24a5,
+ 0x7447, 0x42a4,
+ 0x7448, 0x3cb5,
+ 0x7449, 0x4291,
+ 0x744a, 0x249b,
+ 0x744d, 0x24a6,
+ 0x744e, 0x24a3,
+ 0x744f, 0x24a1,
+ 0x7451, 0x249e,
+ 0x7452, 0x249d,
+ 0x7453, 0x4231,
+ 0x7454, 0x24a7,
+ 0x7455, 0x0e7d,
+ 0x7456, 0x39f5,
+ 0x7457, 0x249f,
+ 0x7459, 0x0e82,
+ 0x745a, 0x0e7c,
+ 0x745b, 0x0e83,
+ 0x745d, 0x42c6,
+ 0x745e, 0x0e7f,
+ 0x745f, 0x0e7e,
+ 0x7460, 0x42a2,
+ 0x7462, 0x272b,
+ 0x7463, 0x102d,
+ 0x7464, 0x102c,
+ 0x7465, 0x4101,
+ 0x7467, 0x2730,
+ 0x7468, 0x3aee,
+ 0x7469, 0x11a6,
+ 0x746a, 0x102e,
+ 0x746b, 0x3be7,
+ 0x746c, 0x42a8,
+ 0x746d, 0x1030,
+ 0x746e, 0x2731,
+ 0x746f, 0x0e7b,
+ 0x7470, 0x102f,
+ 0x7471, 0x272d,
+ 0x7472, 0x272f,
+ 0x7473, 0x272c,
+ 0x7474, 0x42a9,
+ 0x7475, 0x272e,
+ 0x7476, 0x42a6,
+ 0x7479, 0x297c,
+ 0x747a, 0x3ad1,
+ 0x747c, 0x297b,
+ 0x747d, 0x2978,
+ 0x747e, 0x11a9,
+ 0x747f, 0x2bcb,
+ 0x7480, 0x11aa,
+ 0x7481, 0x2977,
+ 0x7482, 0x42ac,
+ 0x7483, 0x11a8,
+ 0x7485, 0x2979,
+ 0x7486, 0x2976,
+ 0x7487, 0x2973,
+ 0x7488, 0x297a,
+ 0x7489, 0x2974,
+ 0x748b, 0x11a7,
+ 0x748c, 0x3a21,
+ 0x748d, 0x469d,
+ 0x7490, 0x2da8,
+ 0x7492, 0x2bcf,
+ 0x7494, 0x2bce,
+ 0x7495, 0x2bd0,
+ 0x7497, 0x2da5,
+ 0x7498, 0x12fc,
+ 0x7499, 0x39f3,
+ 0x749a, 0x2bcc,
+ 0x749b, 0x3b0a,
+ 0x749c, 0x12fa,
+ 0x749e, 0x12fe,
+ 0x749f, 0x12fd,
+ 0x74a0, 0x2bcd,
+ 0x74a1, 0x2bd1,
+ 0x74a3, 0x12fb,
+ 0x74a4, 0x4170,
+ 0x74a5, 0x2dac,
+ 0x74a6, 0x1412,
+ 0x74a7, 0x14f4,
+ 0x74a8, 0x1413,
+ 0x74a9, 0x1410,
+ 0x74aa, 0x2da9,
+ 0x74ab, 0x2da7,
+ 0x74ad, 0x2daa,
+ 0x74af, 0x2dad,
+ 0x74b0, 0x1411,
+ 0x74b1, 0x2dab,
+ 0x74b2, 0x2da6,
+ 0x74b4, 0x3ca5,
+ 0x74b5, 0x2f58,
+ 0x74b6, 0x2f5b,
+ 0x74b7, 0x30c2,
+ 0x74b8, 0x2f56,
+ 0x74ba, 0x31f9,
+ 0x74bb, 0x2f5c,
+ 0x74bd, 0x1597,
+ 0x74be, 0x2f5a,
+ 0x74bf, 0x14f5,
+ 0x74c0, 0x2f57,
+ 0x74c1, 0x2f59,
+ 0x74c2, 0x2f5d,
+ 0x74c3, 0x30c3,
+ 0x74c5, 0x30c1,
+ 0x74c8, 0x42b5,
+ 0x74ca, 0x1598,
+ 0x74cb, 0x30c0,
+ 0x74cc, 0x3ade,
+ 0x74cf, 0x1621,
+ 0x74d0, 0x3a9b,
+ 0x74d3, 0x46fa,
+ 0x74d4, 0x167e,
+ 0x74d5, 0x3392,
+ 0x74d6, 0x167d,
+ 0x74d7, 0x3394,
+ 0x74d8, 0x3391,
+ 0x74d9, 0x3393,
+ 0x74da, 0x16fe,
+ 0x74db, 0x348d,
+ 0x74dc, 0x0358,
+ 0x74dd, 0x1a0d,
+ 0x74de, 0x1d4a,
+ 0x74e0, 0x0b26,
+ 0x74e1, 0x24a8,
+ 0x74e2, 0x12ff,
+ 0x74e3, 0x1599,
+ 0x74e4, 0x16cb,
+ 0x74e5, 0x348e,
+ 0x74e6, 0x0359,
+ 0x74e7, 0x3ffe,
+ 0x74e8, 0x1a0e,
+ 0x74e9, 0x0120,
+ 0x74ec, 0x1b8e,
+ 0x74ee, 0x1b8f,
+ 0x74f0, 0x3fe6,
+ 0x74f1, 0x3f9b,
+ 0x74f2, 0x3fdf,
+ 0x74f4, 0x1d4c,
+ 0x74f6, 0x0b27,
+ 0x74f8, 0x3ff4,
+ 0x74fb, 0x2220,
+ 0x74fd, 0x24ab,
+ 0x74fe, 0x24aa,
+ 0x74ff, 0x24a9,
+ 0x7500, 0x2732,
+ 0x7502, 0x2733,
+ 0x7504, 0x1031,
+ 0x7505, 0x3fde,
+ 0x7507, 0x297e,
+ 0x7508, 0x297d,
+ 0x750b, 0x2bd2,
+ 0x750c, 0x1300,
+ 0x750e, 0x42b7,
+ 0x750f, 0x2db1,
+ 0x7510, 0x2dae,
+ 0x7513, 0x2f5f,
+ 0x7514, 0x2f5e,
+ 0x7515, 0x14f6,
+ 0x7516, 0x30c4,
+ 0x7517, 0x32e3,
+ 0x7518, 0x035a,
+ 0x7519, 0x4583,
+ 0x751a, 0x079f,
+ 0x751c, 0x0b29,
+ 0x751d, 0x24ac,
+ 0x751e, 0x42b8,
+ 0x751f, 0x035b,
+ 0x7521, 0x1d4e,
+ 0x7522, 0x0b2a,
+ 0x7525, 0x0ce3,
+ 0x7528, 0x035c,
+ 0x752a, 0x180f,
+ 0x752b, 0x04f1,
+ 0x752c, 0x04f0,
+ 0x752d, 0x07a0,
+ 0x752e, 0x1b90,
+ 0x752f, 0x2221,
+ 0x7530, 0x035e,
+ 0x7534, 0x3e87,
+ 0x7535, 0x455a,
+ 0x7537, 0x04f2,
+ 0x7539, 0x18d3,
+ 0x753a, 0x18d2,
+ 0x753b, 0x3dfb,
+ 0x753d, 0x0655,
+ 0x753e, 0x1a11,
+ 0x753f, 0x1a0f,
+ 0x7542, 0x43cd,
+ 0x7546, 0x3f40,
+ 0x7547, 0x1b91,
+ 0x754a, 0x42bf,
+ 0x754b, 0x07a4,
+ 0x754c, 0x07a2,
+ 0x754d, 0x42be,
+ 0x754e, 0x07a3,
+ 0x754f, 0x07a1,
+ 0x7551, 0x3cfe,
+ 0x7553, 0x3feb,
+ 0x7554, 0x0931,
+ 0x7555, 0x3aea,
+ 0x7559, 0x0935,
+ 0x755a, 0x0934,
+ 0x755b, 0x1d4f,
+ 0x755c, 0x0933,
+ 0x755d, 0x0932,
+ 0x755f, 0x1d50,
+ 0x7560, 0x3d71,
+ 0x7562, 0x0b2d,
+ 0x7563, 0x1f9f,
+ 0x7564, 0x1f9e,
+ 0x7565, 0x0b2b,
+ 0x7567, 0x42c0,
+ 0x756a, 0x0ce6,
+ 0x756b, 0x0ce5,
+ 0x756c, 0x2223,
+ 0x756d, 0x46fd,
+ 0x756e, 0x42c1,
+ 0x756f, 0x2222,
+ 0x7570, 0x0b2e,
+ 0x7572, 0x46fe,
+ 0x7576, 0x0e85,
+ 0x7577, 0x24ae,
+ 0x7578, 0x0e86,
+ 0x7579, 0x24ad,
+ 0x757a, 0x3f4f,
+ 0x757d, 0x2735,
+ 0x757e, 0x297f,
+ 0x757f, 0x11ab,
+ 0x7580, 0x2bd3,
+ 0x7583, 0x3ae5,
+ 0x7584, 0x2db2,
+ 0x7586, 0x159b,
+ 0x7587, 0x159a,
+ 0x758a, 0x16cc,
+ 0x758b, 0x0362,
+ 0x758c, 0x1a12,
+ 0x758d, 0x46ff,
+ 0x758e, 0x42c5,
+ 0x758f, 0x0b2f,
+ 0x7590, 0x2736,
+ 0x7591, 0x1032,
+ 0x7592, 0x022e,
+ 0x7594, 0x18d4,
+ 0x7598, 0x1a13,
+ 0x7599, 0x0657,
+ 0x759d, 0x0656,
+ 0x759e, 0x42c7,
+ 0x75a2, 0x07a8,
+ 0x75a4, 0x07a6,
+ 0x75a7, 0x1b93,
+ 0x75aa, 0x1b94,
+ 0x75ab, 0x07a5,
+ 0x75b0, 0x1d51,
+ 0x75b1, 0x3ead,
+ 0x75b2, 0x0939,
+ 0x75b4, 0x42c8,
+ 0x75b5, 0x0b32,
+ 0x75b6, 0x1d57,
+ 0x75b8, 0x093f,
+ 0x75b9, 0x093d,
+ 0x75ba, 0x1d58,
+ 0x75bb, 0x1d53,
+ 0x75bc, 0x093c,
+ 0x75bd, 0x093b,
+ 0x75be, 0x0936,
+ 0x75bf, 0x1d56,
+ 0x75c0, 0x1d55,
+ 0x75c1, 0x1d52,
+ 0x75c2, 0x093e,
+ 0x75c3, 0x3f93,
+ 0x75c4, 0x1d54,
+ 0x75c5, 0x0937,
+ 0x75c7, 0x0938,
+ 0x75c8, 0x4701,
+ 0x75ca, 0x0b33,
+ 0x75cb, 0x1fa3,
+ 0x75cd, 0x0b34,
+ 0x75ce, 0x1fa0,
+ 0x75cf, 0x1fa2,
+ 0x75d0, 0x1fa6,
+ 0x75d1, 0x1fa5,
+ 0x75d2, 0x1fa1,
+ 0x75d4, 0x0b30,
+ 0x75d7, 0x222b,
+ 0x75d8, 0x0ceb,
+ 0x75d9, 0x0cea,
+ 0x75da, 0x2225,
+ 0x75db, 0x0ce8,
+ 0x75dc, 0x43ce,
+ 0x75dd, 0x2228,
+ 0x75de, 0x0cec,
+ 0x75df, 0x2229,
+ 0x75e0, 0x0ced,
+ 0x75e1, 0x2226,
+ 0x75e2, 0x0ce7,
+ 0x75e3, 0x0ce9,
+ 0x75e4, 0x222a,
+ 0x75e6, 0x2227,
+ 0x75e7, 0x2224,
+ 0x75ed, 0x24bb,
+ 0x75ef, 0x24b0,
+ 0x75f0, 0x0e88,
+ 0x75f1, 0x0e8b,
+ 0x75f2, 0x0e8a,
+ 0x75f3, 0x0e8f,
+ 0x75f4, 0x0e8e,
+ 0x75f5, 0x24bc,
+ 0x75f6, 0x24ba,
+ 0x75f7, 0x24b3,
+ 0x75f8, 0x24b7,
+ 0x75f9, 0x24b6,
+ 0x75fa, 0x0e8c,
+ 0x75fb, 0x24b9,
+ 0x75fc, 0x24b5,
+ 0x75fd, 0x24bd,
+ 0x75fe, 0x24b4,
+ 0x75ff, 0x0e8d,
+ 0x7600, 0x0e87,
+ 0x7601, 0x0e89,
+ 0x7602, 0x42c9,
+ 0x7603, 0x24b2,
+ 0x7607, 0x3f8f,
+ 0x7608, 0x2738,
+ 0x7609, 0x1036,
+ 0x760a, 0x273c,
+ 0x760b, 0x1035,
+ 0x760c, 0x2739,
+ 0x760d, 0x1034,
+ 0x760f, 0x24b1,
+ 0x7610, 0x24b8,
+ 0x7611, 0x273b,
+ 0x7613, 0x1037,
+ 0x7614, 0x273d,
+ 0x7615, 0x273a,
+ 0x7616, 0x2737,
+ 0x7619, 0x2982,
+ 0x761a, 0x2986,
+ 0x761b, 0x2988,
+ 0x761c, 0x2984,
+ 0x761d, 0x2983,
+ 0x761e, 0x2981,
+ 0x761f, 0x11ae,
+ 0x7620, 0x11ac,
+ 0x7621, 0x11b1,
+ 0x7623, 0x2985,
+ 0x7624, 0x11af,
+ 0x7625, 0x2980,
+ 0x7626, 0x11b0,
+ 0x7627, 0x1033,
+ 0x7628, 0x2987,
+ 0x7629, 0x11ad,
+ 0x762c, 0x42ca,
+ 0x762d, 0x2bd5,
+ 0x762f, 0x2bd4,
+ 0x7630, 0x2bdc,
+ 0x7631, 0x2bd6,
+ 0x7632, 0x2bdb,
+ 0x7633, 0x2bd8,
+ 0x7634, 0x1302,
+ 0x7635, 0x2bda,
+ 0x7638, 0x1303,
+ 0x763a, 0x1304,
+ 0x763b, 0x3e70,
+ 0x763c, 0x2bd9,
+ 0x763d, 0x2bd7,
+ 0x7640, 0x3ee6,
+ 0x7642, 0x1415,
+ 0x7643, 0x2db3,
+ 0x7646, 0x1414,
+ 0x7647, 0x2db6,
+ 0x7648, 0x2db4,
+ 0x764c, 0x1416,
+ 0x764d, 0x4702,
+ 0x764e, 0x3e72,
+ 0x764f, 0x42cc,
+ 0x7650, 0x2f63,
+ 0x7651, 0x42cb,
+ 0x7652, 0x14f9,
+ 0x7653, 0x2f64,
+ 0x7654, 0x3ef0,
+ 0x7656, 0x14f7,
+ 0x7657, 0x2f65,
+ 0x7658, 0x14f8,
+ 0x7659, 0x2f62,
+ 0x765a, 0x2f66,
+ 0x765c, 0x2f60,
+ 0x765f, 0x159c,
+ 0x7660, 0x30c5,
+ 0x7661, 0x159d,
+ 0x7662, 0x1622,
+ 0x7664, 0x2f61,
+ 0x7665, 0x1623,
+ 0x7666, 0x3eaa,
+ 0x7667, 0x3fa9,
+ 0x7669, 0x167f,
+ 0x766a, 0x32e4,
+ 0x766c, 0x16ce,
+ 0x766d, 0x3395,
+ 0x766e, 0x16cd,
+ 0x766f, 0x42cd,
+ 0x7670, 0x3428,
+ 0x7671, 0x1723,
+ 0x7673, 0x3aeb,
+ 0x7674, 0x4703,
+ 0x7675, 0x3543,
+ 0x7676, 0x022f,
+ 0x7678, 0x07aa,
+ 0x7679, 0x1b95,
+ 0x767a, 0x4705,
+ 0x767b, 0x0cee,
+ 0x767d, 0x0363,
+ 0x767e, 0x03f5,
+ 0x767f, 0x1810,
+ 0x7680, 0x43d3,
+ 0x7681, 0x18d6,
+ 0x7682, 0x04f4,
+ 0x7684, 0x0659,
+ 0x7686, 0x07ab,
+ 0x7689, 0x1fa8,
+ 0x768a, 0x1d59,
+ 0x768b, 0x0940,
+ 0x768c, 0x43d4,
+ 0x768e, 0x0b35,
+ 0x768f, 0x1fa7,
+ 0x7690, 0x42d0,
+ 0x7692, 0x222d,
+ 0x7693, 0x0cf1,
+ 0x7695, 0x222c,
+ 0x7696, 0x0cf0,
+ 0x7699, 0x24be,
+ 0x769a, 0x11b3,
+ 0x769b, 0x298c,
+ 0x769c, 0x2989,
+ 0x76a1, 0x42d5,
+ 0x76a4, 0x2db7,
+ 0x76a5, 0x42d6,
+ 0x76a6, 0x2f67,
+ 0x76aa, 0x31fb,
+ 0x76ab, 0x31fa,
+ 0x76ad, 0x3396,
+ 0x76ae, 0x0364,
+ 0x76af, 0x1a14,
+ 0x76b0, 0x0941,
+ 0x76b4, 0x0cf2,
+ 0x76b5, 0x24bf,
+ 0x76b7, 0x42d7,
+ 0x76b8, 0x273e,
+ 0x76ba, 0x11b4,
+ 0x76bb, 0x2bdd,
+ 0x76bd, 0x2f68,
+ 0x76be, 0x31fc,
+ 0x76bf, 0x0365,
+ 0x76c2, 0x065a,
+ 0x76c3, 0x07b0,
+ 0x76c4, 0x1b96,
+ 0x76c5, 0x07b1,
+ 0x76c6, 0x07af,
+ 0x76c8, 0x07ae,
+ 0x76c9, 0x1d5a,
+ 0x76ca, 0x0942,
+ 0x76cc, 0x42d8,
+ 0x76cd, 0x0943,
+ 0x76d2, 0x0b37,
+ 0x76d3, 0x1fa9,
+ 0x76d4, 0x0b36,
+ 0x76d6, 0x3f55,
+ 0x76da, 0x222e,
+ 0x76db, 0x0b38,
+ 0x76dc, 0x0cf3,
+ 0x76dd, 0x24c0,
+ 0x76de, 0x0e90,
+ 0x76e1, 0x1038,
+ 0x76e3, 0x1039,
+ 0x76e4, 0x11b5,
+ 0x76e5, 0x1306,
+ 0x76e6, 0x2bde,
+ 0x76e7, 0x1305,
+ 0x76e9, 0x2db8,
+ 0x76ea, 0x1417,
+ 0x76ec, 0x2f69,
+ 0x76ed, 0x31fd,
+ 0x76ee, 0x0366,
+ 0x76ef, 0x04f5,
+ 0x76f0, 0x1a17,
+ 0x76f1, 0x1a16,
+ 0x76f2, 0x065b,
+ 0x76f3, 0x1a15,
+ 0x76f4, 0x065c,
+ 0x76f5, 0x1a18,
+ 0x76f7, 0x1b9c,
+ 0x76f8, 0x07b4,
+ 0x76f9, 0x07b3,
+ 0x76fa, 0x1b9e,
+ 0x76fb, 0x1b9d,
+ 0x76fc, 0x07b8,
+ 0x76fe, 0x07b7,
+ 0x7701, 0x07b2,
+ 0x7703, 0x1b98,
+ 0x7707, 0x07b9,
+ 0x7708, 0x1b97,
+ 0x7709, 0x07b5,
+ 0x770a, 0x1b9b,
+ 0x770b, 0x07b6,
+ 0x770c, 0x3d62,
+ 0x770e, 0x3b02,
+ 0x7710, 0x1d5d,
+ 0x7711, 0x1d61,
+ 0x7712, 0x1d5f,
+ 0x7713, 0x1d5e,
+ 0x7715, 0x1d62,
+ 0x7719, 0x1d63,
+ 0x771b, 0x1d5c,
+ 0x771d, 0x1d5b,
+ 0x771e, 0x42de,
+ 0x771f, 0x0946,
+ 0x7722, 0x1d65,
+ 0x7723, 0x1d60,
+ 0x7724, 0x3fe8,
+ 0x7725, 0x1fb2,
+ 0x7726, 0x42df,
+ 0x7727, 0x1d66,
+ 0x7728, 0x0948,
+ 0x7729, 0x0945,
+ 0x772b, 0x3ff3,
+ 0x772d, 0x1fac,
+ 0x772f, 0x1fab,
+ 0x7731, 0x1fad,
+ 0x7733, 0x1fb0,
+ 0x7734, 0x1faf,
+ 0x7735, 0x1fb4,
+ 0x7736, 0x0b3c,
+ 0x7737, 0x0b39,
+ 0x7738, 0x0b3d,
+ 0x7739, 0x1faa,
+ 0x773a, 0x0b3e,
+ 0x773b, 0x1fb3,
+ 0x773c, 0x0b3b,
+ 0x773d, 0x1fb1,
+ 0x773e, 0x0b3a,
+ 0x7740, 0x42e0,
+ 0x7743, 0x470a,
+ 0x7744, 0x2231,
+ 0x7745, 0x2233,
+ 0x7746, 0x222f,
+ 0x774a, 0x2234,
+ 0x774b, 0x2236,
+ 0x774d, 0x2232,
+ 0x774e, 0x2235,
+ 0x774f, 0x0cf4,
+ 0x7752, 0x24c4,
+ 0x7754, 0x24c9,
+ 0x7755, 0x24c1,
+ 0x7756, 0x24c5,
+ 0x7758, 0x42e3,
+ 0x7759, 0x24ca,
+ 0x775a, 0x24c6,
+ 0x775b, 0x0e92,
+ 0x775c, 0x0e9a,
+ 0x775e, 0x0e95,
+ 0x775f, 0x24c2,
+ 0x7761, 0x103d,
+ 0x7762, 0x0e9d,
+ 0x7763, 0x0e96,
+ 0x7765, 0x0e9b,
+ 0x7766, 0x0e94,
+ 0x7767, 0x24c8,
+ 0x7768, 0x0e9c,
+ 0x7769, 0x24c7,
+ 0x776a, 0x0e98,
+ 0x776b, 0x0e93,
+ 0x776c, 0x0e99,
+ 0x776d, 0x24cb,
+ 0x776e, 0x2743,
+ 0x776f, 0x2745,
+ 0x7772, 0x396b,
+ 0x7777, 0x46a9,
+ 0x7778, 0x3b00,
+ 0x7779, 0x0e97,
+ 0x777a, 0x4317,
+ 0x777b, 0x3b04,
+ 0x777c, 0x2740,
+ 0x777d, 0x103b,
+ 0x777e, 0x2746,
+ 0x777f, 0x103c,
+ 0x7780, 0x2744,
+ 0x7781, 0x273f,
+ 0x7782, 0x2742,
+ 0x7783, 0x2747,
+ 0x7784, 0x103a,
+ 0x7785, 0x2741,
+ 0x7787, 0x11b7,
+ 0x7788, 0x2990,
+ 0x7789, 0x298f,
+ 0x778b, 0x11ba,
+ 0x778c, 0x11b8,
+ 0x778d, 0x298d,
+ 0x778e, 0x11b6,
+ 0x778f, 0x298e,
+ 0x7791, 0x11b9,
+ 0x7793, 0x382d,
+ 0x7795, 0x2be6,
+ 0x7797, 0x2be8,
+ 0x7798, 0x470e,
+ 0x7799, 0x2be7,
+ 0x779a, 0x2bdf,
+ 0x779b, 0x2be3,
+ 0x779c, 0x2be2,
+ 0x779d, 0x2be0,
+ 0x779e, 0x1308,
+ 0x77a0, 0x1307,
+ 0x77a1, 0x2be1,
+ 0x77a2, 0x2be4,
+ 0x77a5, 0x130a,
+ 0x77a7, 0x141c,
+ 0x77a8, 0x2dc0,
+ 0x77aa, 0x1419,
+ 0x77ab, 0x2dba,
+ 0x77ac, 0x141b,
+ 0x77ad, 0x141d,
+ 0x77af, 0x42e5,
+ 0x77b0, 0x141a,
+ 0x77b1, 0x2dbf,
+ 0x77b2, 0x2dbb,
+ 0x77b3, 0x1418,
+ 0x77b4, 0x2dbe,
+ 0x77b5, 0x2db9,
+ 0x77b6, 0x2dbd,
+ 0x77b7, 0x2dbc,
+ 0x77b9, 0x3e73,
+ 0x77ba, 0x2f6b,
+ 0x77bb, 0x14fc,
+ 0x77bd, 0x14fa,
+ 0x77be, 0x4711,
+ 0x77bf, 0x14fb,
+ 0x77c2, 0x2f6a,
+ 0x77c3, 0x3bb1,
+ 0x77c4, 0x30c8,
+ 0x77c5, 0x41c1,
+ 0x77c7, 0x159e,
+ 0x77c9, 0x30c6,
+ 0x77cb, 0x4712,
+ 0x77cc, 0x31fe,
+ 0x77cd, 0x3201,
+ 0x77ce, 0x31ff,
+ 0x77d0, 0x32e5,
+ 0x77d3, 0x1680,
+ 0x77d4, 0x3429,
+ 0x77d5, 0x348f,
+ 0x77d7, 0x1725,
+ 0x77d8, 0x34d3,
+ 0x77da, 0x1753,
+ 0x77db, 0x0367,
+ 0x77dc, 0x07ba,
+ 0x77de, 0x2238,
+ 0x77e0, 0x24cc,
+ 0x77e2, 0x0368,
+ 0x77e3, 0x04f6,
+ 0x77e5, 0x065d,
+ 0x77e6, 0x4081,
+ 0x77e7, 0x1b9f,
+ 0x77e9, 0x0949,
+ 0x77ec, 0x2239,
+ 0x77ed, 0x0cf5,
+ 0x77ee, 0x0e9e,
+ 0x77ef, 0x141e,
+ 0x77f0, 0x2dc1,
+ 0x77f1, 0x30c9,
+ 0x77f2, 0x3202,
+ 0x77f3, 0x0369,
+ 0x77f4, 0x42e9,
+ 0x77f7, 0x1a1e,
+ 0x77f8, 0x1a19,
+ 0x77f9, 0x1a1b,
+ 0x77fa, 0x1a1d,
+ 0x77fb, 0x1a1c,
+ 0x77fc, 0x1a1a,
+ 0x77fd, 0x065e,
+ 0x77fe, 0x3fd5,
+ 0x7802, 0x07bb,
+ 0x7803, 0x1ba9,
+ 0x7805, 0x1ba4,
+ 0x7806, 0x1ba1,
+ 0x7808, 0x3e46,
+ 0x7809, 0x1ba8,
+ 0x780c, 0x07bd,
+ 0x780e, 0x1ba7,
+ 0x780f, 0x1ba6,
+ 0x7810, 0x1ba5,
+ 0x7811, 0x1ba2,
+ 0x7813, 0x1baa,
+ 0x7814, 0x07bc,
+ 0x7818, 0x4713,
+ 0x781c, 0x4714,
+ 0x781d, 0x094d,
+ 0x781e, 0x3b13,
+ 0x781f, 0x0953,
+ 0x7820, 0x0952,
+ 0x7821, 0x1d6f,
+ 0x7822, 0x1d69,
+ 0x7823, 0x1d67,
+ 0x7825, 0x0950,
+ 0x7826, 0x1fbb,
+ 0x7827, 0x094b,
+ 0x7828, 0x1d6c,
+ 0x7829, 0x1d70,
+ 0x782a, 0x1d72,
+ 0x782b, 0x1d6e,
+ 0x782c, 0x1d68,
+ 0x782d, 0x0951,
+ 0x782e, 0x1d6d,
+ 0x782f, 0x1d6b,
+ 0x7830, 0x094a,
+ 0x7831, 0x1d73,
+ 0x7832, 0x0954,
+ 0x7833, 0x1d71,
+ 0x7834, 0x094e,
+ 0x7835, 0x1d6a,
+ 0x7837, 0x094f,
+ 0x7838, 0x094c,
+ 0x7839, 0x43d6,
+ 0x783c, 0x401a,
+ 0x783d, 0x3c6a,
+ 0x7842, 0x3ac4,
+ 0x7843, 0x0b40,
+ 0x7844, 0x3c2b,
+ 0x7845, 0x1fbc,
+ 0x7847, 0x4715,
+ 0x7848, 0x1fb5,
+ 0x7849, 0x1fb7,
+ 0x784a, 0x1fb9,
+ 0x784b, 0x3c6d,
+ 0x784c, 0x1fba,
+ 0x784d, 0x1fb8,
+ 0x784e, 0x0b41,
+ 0x7850, 0x1fbd,
+ 0x7851, 0x4716,
+ 0x7852, 0x1fb6,
+ 0x7853, 0x3f95,
+ 0x7854, 0x3c6b,
+ 0x785c, 0x223d,
+ 0x785d, 0x0cf6,
+ 0x785e, 0x2245,
+ 0x7860, 0x223a,
+ 0x7862, 0x2246,
+ 0x7864, 0x223b,
+ 0x7866, 0x4717,
+ 0x7868, 0x2244,
+ 0x7869, 0x2243,
+ 0x786a, 0x2240,
+ 0x786b, 0x0b3f,
+ 0x786c, 0x0cf7,
+ 0x786d, 0x223e,
+ 0x786e, 0x2241,
+ 0x786f, 0x0cf8,
+ 0x7870, 0x2242,
+ 0x7871, 0x223f,
+ 0x7879, 0x24d7,
+ 0x787a, 0x3ee9,
+ 0x787b, 0x24db,
+ 0x787c, 0x0ea5,
+ 0x787e, 0x274d,
+ 0x787f, 0x0ea8,
+ 0x7880, 0x24d9,
+ 0x7881, 0x36e8,
+ 0x7883, 0x24d6,
+ 0x7884, 0x24d1,
+ 0x7885, 0x24d3,
+ 0x7887, 0x24cd,
+ 0x7888, 0x3b15,
+ 0x7889, 0x0ea4,
+ 0x788c, 0x0ea3,
+ 0x788d, 0x3b14,
+ 0x788e, 0x0e9f,
+ 0x788f, 0x24d0,
+ 0x7891, 0x0ea6,
+ 0x7893, 0x0ea7,
+ 0x7894, 0x24cf,
+ 0x7895, 0x24d2,
+ 0x7896, 0x24da,
+ 0x7897, 0x0ea1,
+ 0x7899, 0x24d8,
+ 0x789a, 0x24ce,
+ 0x789e, 0x274f,
+ 0x789f, 0x103f,
+ 0x78a0, 0x2751,
+ 0x78a1, 0x24d5,
+ 0x78a2, 0x2753,
+ 0x78a3, 0x1043,
+ 0x78a4, 0x2754,
+ 0x78a5, 0x2750,
+ 0x78a7, 0x1040,
+ 0x78a8, 0x274c,
+ 0x78a9, 0x1042,
+ 0x78aa, 0x2749,
+ 0x78ab, 0x274e,
+ 0x78ac, 0x2752,
+ 0x78ad, 0x274b,
+ 0x78af, 0x42ec,
+ 0x78b0, 0x0ea0,
+ 0x78b1, 0x42f4,
+ 0x78b2, 0x2748,
+ 0x78b3, 0x1041,
+ 0x78b4, 0x274a,
+ 0x78b6, 0x3c6c,
+ 0x78b8, 0x4571,
+ 0x78b9, 0x3c63,
+ 0x78ba, 0x11bd,
+ 0x78bb, 0x2992,
+ 0x78bc, 0x11c1,
+ 0x78be, 0x11bf,
+ 0x78c1, 0x103e,
+ 0x78c3, 0x2999,
+ 0x78c5, 0x11bc,
+ 0x78c7, 0x42ed,
+ 0x78c8, 0x2998,
+ 0x78c9, 0x299b,
+ 0x78ca, 0x11be,
+ 0x78cb, 0x11bb,
+ 0x78cc, 0x2994,
+ 0x78cd, 0x2991,
+ 0x78ce, 0x2996,
+ 0x78cf, 0x2993,
+ 0x78d0, 0x11c2,
+ 0x78d1, 0x2995,
+ 0x78d2, 0x3b16,
+ 0x78d3, 0x42ee,
+ 0x78d4, 0x2997,
+ 0x78d5, 0x11c0,
+ 0x78d7, 0x42f2,
+ 0x78d8, 0x3f8c,
+ 0x78da, 0x130c,
+ 0x78db, 0x2bef,
+ 0x78dd, 0x2be9,
+ 0x78de, 0x2bed,
+ 0x78df, 0x2bf3,
+ 0x78e1, 0x2bf0,
+ 0x78e3, 0x2bee,
+ 0x78e5, 0x2beb,
+ 0x78e7, 0x130e,
+ 0x78e8, 0x130b,
+ 0x78e9, 0x2bea,
+ 0x78ea, 0x2bec,
+ 0x78ec, 0x130d,
+ 0x78ed, 0x2bf2,
+ 0x78ee, 0x3a81,
+ 0x78ef, 0x1422,
+ 0x78f0, 0x3b3a,
+ 0x78f1, 0x40be,
+ 0x78f2, 0x2dc8,
+ 0x78f3, 0x2dc2,
+ 0x78f4, 0x1421,
+ 0x78f5, 0x38b3,
+ 0x78f7, 0x141f,
+ 0x78f9, 0x2dca,
+ 0x78fa, 0x1420,
+ 0x78fb, 0x2dc5,
+ 0x78fd, 0x2dc3,
+ 0x78fe, 0x2dcb,
+ 0x78ff, 0x2dc7,
+ 0x7901, 0x1423,
+ 0x7902, 0x2dc4,
+ 0x7904, 0x2dcc,
+ 0x7905, 0x2dc9,
+ 0x7906, 0x3fcf,
+ 0x7909, 0x2f6f,
+ 0x790c, 0x2f6c,
+ 0x790e, 0x14fe,
+ 0x7910, 0x2f70,
+ 0x7911, 0x2f72,
+ 0x7912, 0x2f71,
+ 0x7913, 0x2f6d,
+ 0x7917, 0x30ce,
+ 0x7919, 0x159f,
+ 0x791b, 0x30cb,
+ 0x791c, 0x30cd,
+ 0x791d, 0x30ca,
+ 0x791e, 0x30cf,
+ 0x7921, 0x30cc,
+ 0x7923, 0x3204,
+ 0x7924, 0x3207,
+ 0x7925, 0x3203,
+ 0x7926, 0x1624,
+ 0x7927, 0x3205,
+ 0x7929, 0x3208,
+ 0x792a, 0x1625,
+ 0x792b, 0x1627,
+ 0x792c, 0x1626,
+ 0x792d, 0x32e6,
+ 0x792e, 0x42f0,
+ 0x792f, 0x32e8,
+ 0x7931, 0x32e7,
+ 0x7932, 0x471b,
+ 0x7933, 0x471a,
+ 0x7934, 0x42f3,
+ 0x7935, 0x3397,
+ 0x7936, 0x3783,
+ 0x7938, 0x3490,
+ 0x7939, 0x34d5,
+ 0x793a, 0x036a,
+ 0x793b, 0x44f7,
+ 0x793c, 0x4300,
+ 0x793d, 0x18d7,
+ 0x793e, 0x065f,
+ 0x793f, 0x1a20,
+ 0x7940, 0x0660,
+ 0x7942, 0x1a1f,
+ 0x7944, 0x1baf,
+ 0x7945, 0x1bae,
+ 0x7946, 0x07bf,
+ 0x7947, 0x07c2,
+ 0x7948, 0x07c1,
+ 0x7949, 0x07c0,
+ 0x794a, 0x1bab,
+ 0x794b, 0x1bad,
+ 0x794c, 0x1bac,
+ 0x794f, 0x1d76,
+ 0x7950, 0x0956,
+ 0x7951, 0x1d7a,
+ 0x7952, 0x1d79,
+ 0x7953, 0x1d78,
+ 0x7954, 0x1d74,
+ 0x7955, 0x0955,
+ 0x7956, 0x0959,
+ 0x7957, 0x095c,
+ 0x7958, 0x37e5,
+ 0x7959, 0x3b18,
+ 0x795a, 0x095d,
+ 0x795b, 0x1d75,
+ 0x795c, 0x1d77,
+ 0x795d, 0x095b,
+ 0x795e, 0x095a,
+ 0x795f, 0x0958,
+ 0x7960, 0x0957,
+ 0x7961, 0x1fc4,
+ 0x7962, 0x3e7d,
+ 0x7963, 0x1fc2,
+ 0x7964, 0x1fbe,
+ 0x7965, 0x0b42,
+ 0x7967, 0x1fbf,
+ 0x7968, 0x0b43,
+ 0x7969, 0x1fc0,
+ 0x796b, 0x1fc3,
+ 0x796d, 0x0b44,
+ 0x7970, 0x224a,
+ 0x7971, 0x4168,
+ 0x7972, 0x2249,
+ 0x7973, 0x2248,
+ 0x7974, 0x2247,
+ 0x7979, 0x24df,
+ 0x797a, 0x0ea9,
+ 0x797c, 0x24dc,
+ 0x797d, 0x24de,
+ 0x797e, 0x3e26,
+ 0x797f, 0x0eaa,
+ 0x7980, 0x42fc,
+ 0x7981, 0x0eab,
+ 0x7982, 0x24dd,
+ 0x7983, 0x3df6,
+ 0x7986, 0x42f9,
+ 0x7987, 0x4588,
+ 0x7988, 0x275d,
+ 0x798a, 0x2756,
+ 0x798d, 0x1046,
+ 0x798e, 0x1044,
+ 0x7990, 0x275f,
+ 0x7991, 0x471d,
+ 0x7992, 0x275e,
+ 0x7993, 0x275b,
+ 0x7994, 0x275a,
+ 0x7995, 0x2759,
+ 0x7996, 0x2758,
+ 0x7997, 0x275c,
+ 0x7998, 0x2755,
+ 0x7999, 0x43fc,
+ 0x799a, 0x299c,
+ 0x799b, 0x29a1,
+ 0x799c, 0x299f,
+ 0x799d, 0x42fe,
+ 0x799f, 0x395e,
+ 0x79a0, 0x299e,
+ 0x79a1, 0x299d,
+ 0x79a2, 0x29a0,
+ 0x79a4, 0x2bf5,
+ 0x79a5, 0x3b1e,
+ 0x79a6, 0x130f,
+ 0x79a7, 0x1424,
+ 0x79a8, 0x2dce,
+ 0x79a9, 0x4301,
+ 0x79aa, 0x1425,
+ 0x79ab, 0x2dcd,
+ 0x79ac, 0x2f74,
+ 0x79ad, 0x2f73,
+ 0x79ae, 0x14ff,
+ 0x79b0, 0x30d0,
+ 0x79b1, 0x15a0,
+ 0x79b2, 0x3209,
+ 0x79b3, 0x16cf,
+ 0x79b4, 0x3398,
+ 0x79b6, 0x3492,
+ 0x79b7, 0x3491,
+ 0x79b8, 0x17b2,
+ 0x79b9, 0x07c3,
+ 0x79bb, 0x1fc5,
+ 0x79bd, 0x0ead,
+ 0x79be, 0x036b,
+ 0x79bf, 0x04f9,
+ 0x79c0, 0x04f8,
+ 0x79c1, 0x04f7,
+ 0x79c4, 0x3ccd,
+ 0x79c5, 0x1a21,
+ 0x79c6, 0x4305,
+ 0x79c8, 0x0663,
+ 0x79c9, 0x0662,
+ 0x79cb, 0x07c7,
+ 0x79cc, 0x4233,
+ 0x79cd, 0x1bb1,
+ 0x79ce, 0x1bb4,
+ 0x79cf, 0x1bb2,
+ 0x79d1, 0x07c5,
+ 0x79d4, 0x4307,
+ 0x79d5, 0x1bb0,
+ 0x79d6, 0x1bb3,
+ 0x79d8, 0x0964,
+ 0x79dc, 0x1d81,
+ 0x79dd, 0x1d83,
+ 0x79de, 0x1d82,
+ 0x79df, 0x0961,
+ 0x79e0, 0x1d7d,
+ 0x79e2, 0x3c5a,
+ 0x79e3, 0x095f,
+ 0x79e4, 0x095e,
+ 0x79e6, 0x0962,
+ 0x79e7, 0x0960,
+ 0x79e9, 0x0963,
+ 0x79ea, 0x1d80,
+ 0x79eb, 0x1d7b,
+ 0x79ed, 0x1d7f,
+ 0x79ee, 0x1d7e,
+ 0x79f1, 0x3b27,
+ 0x79f4, 0x3b22,
+ 0x79f6, 0x1fc8,
+ 0x79f8, 0x1fc7,
+ 0x79fa, 0x1fc6,
+ 0x79fb, 0x0b45,
+ 0x7a00, 0x0cfd,
+ 0x7a02, 0x224b,
+ 0x7a03, 0x224d,
+ 0x7a04, 0x224f,
+ 0x7a05, 0x0cfc,
+ 0x7a06, 0x471e,
+ 0x7a08, 0x0cfa,
+ 0x7a0a, 0x224c,
+ 0x7a0b, 0x0cfb,
+ 0x7a0c, 0x224e,
+ 0x7a0d, 0x0cf9,
+ 0x7a10, 0x24e9,
+ 0x7a11, 0x24e0,
+ 0x7a12, 0x24e3,
+ 0x7a13, 0x24e7,
+ 0x7a14, 0x0eb1,
+ 0x7a15, 0x24e5,
+ 0x7a17, 0x24e4,
+ 0x7a18, 0x24e1,
+ 0x7a1a, 0x0eaf,
+ 0x7a1b, 0x24e8,
+ 0x7a1c, 0x0eae,
+ 0x7a1e, 0x0eb3,
+ 0x7a1f, 0x0eb2,
+ 0x7a20, 0x0eb0,
+ 0x7a22, 0x24e6,
+ 0x7a26, 0x2765,
+ 0x7a28, 0x2764,
+ 0x7a2b, 0x2760,
+ 0x7a2d, 0x3fda,
+ 0x7a2e, 0x1047,
+ 0x7a2f, 0x2763,
+ 0x7a30, 0x2762,
+ 0x7a31, 0x1048,
+ 0x7a37, 0x11c7,
+ 0x7a39, 0x29a3,
+ 0x7a3a, 0x3b21,
+ 0x7a3b, 0x11c8,
+ 0x7a3c, 0x11c4,
+ 0x7a3d, 0x11c6,
+ 0x7a3e, 0x3f8b,
+ 0x7a3f, 0x11c3,
+ 0x7a40, 0x11c5,
+ 0x7a43, 0x396c,
+ 0x7a44, 0x2bf6,
+ 0x7a45, 0x3df1,
+ 0x7a46, 0x1312,
+ 0x7a47, 0x2bf8,
+ 0x7a48, 0x2bf7,
+ 0x7a49, 0x3733,
+ 0x7a4a, 0x2761,
+ 0x7a4b, 0x1314,
+ 0x7a4c, 0x1313,
+ 0x7a4d, 0x1310,
+ 0x7a54, 0x2dd3,
+ 0x7a56, 0x2dd1,
+ 0x7a57, 0x1426,
+ 0x7a58, 0x2dd2,
+ 0x7a5a, 0x2dd4,
+ 0x7a5b, 0x2dd0,
+ 0x7a5c, 0x2dcf,
+ 0x7a5f, 0x2f75,
+ 0x7a60, 0x1502,
+ 0x7a61, 0x1500,
+ 0x7a65, 0x3736,
+ 0x7a67, 0x30d1,
+ 0x7a69, 0x15a2,
+ 0x7a6b, 0x15a1,
+ 0x7a6c, 0x320b,
+ 0x7a6e, 0x320a,
+ 0x7a70, 0x3399,
+ 0x7a74, 0x036c,
+ 0x7a75, 0x1811,
+ 0x7a76, 0x04fa,
+ 0x7a78, 0x1a22,
+ 0x7a79, 0x0665,
+ 0x7a7a, 0x0664,
+ 0x7a7b, 0x1a23,
+ 0x7a7d, 0x3737,
+ 0x7a7e, 0x1bb6,
+ 0x7a7f, 0x07c8,
+ 0x7a80, 0x1bb5,
+ 0x7a81, 0x07c9,
+ 0x7a83, 0x3d7d,
+ 0x7a84, 0x0965,
+ 0x7a85, 0x1d86,
+ 0x7a86, 0x1d84,
+ 0x7a87, 0x1d8a,
+ 0x7a88, 0x0966,
+ 0x7a89, 0x1d85,
+ 0x7a8a, 0x1d89,
+ 0x7a8b, 0x1d87,
+ 0x7a8f, 0x1fca,
+ 0x7a90, 0x1fcc,
+ 0x7a91, 0x43d8,
+ 0x7a92, 0x0b46,
+ 0x7a94, 0x1fcb,
+ 0x7a95, 0x0b47,
+ 0x7a96, 0x0d00,
+ 0x7a97, 0x0cff,
+ 0x7a98, 0x0cfe,
+ 0x7a99, 0x2250,
+ 0x7a9e, 0x24ec,
+ 0x7a9f, 0x0eb4,
+ 0x7aa2, 0x24eb,
+ 0x7aa3, 0x24ea,
+ 0x7aa8, 0x2766,
+ 0x7aa9, 0x104a,
+ 0x7aaa, 0x1049,
+ 0x7aab, 0x2767,
+ 0x7aae, 0x11ca,
+ 0x7aaf, 0x11c9,
+ 0x7ab0, 0x373a,
+ 0x7ab1, 0x2bfc,
+ 0x7ab2, 0x29a4,
+ 0x7ab3, 0x29a6,
+ 0x7ab4, 0x29a5,
+ 0x7ab5, 0x2bfb,
+ 0x7ab6, 0x2bf9,
+ 0x7ab7, 0x2bfd,
+ 0x7ab8, 0x2bfa,
+ 0x7aba, 0x1315,
+ 0x7abb, 0x3739,
+ 0x7abc, 0x4721,
+ 0x7abe, 0x2dd5,
+ 0x7abf, 0x1427,
+ 0x7ac0, 0x2dd6,
+ 0x7ac2, 0x373b,
+ 0x7ac4, 0x1503,
+ 0x7ac7, 0x1628,
+ 0x7ac8, 0x3d7f,
+ 0x7ac9, 0x4570,
+ 0x7aca, 0x16ff,
+ 0x7acb, 0x036d,
+ 0x7acf, 0x4724,
+ 0x7ad1, 0x1bb7,
+ 0x7ad3, 0x3f8a,
+ 0x7ad8, 0x1d8b,
+ 0x7ad9, 0x0967,
+ 0x7ada, 0x3740,
+ 0x7adb, 0x4725,
+ 0x7adc, 0x3951,
+ 0x7add, 0x3741,
+ 0x7adf, 0x0bde,
+ 0x7ae0, 0x0bdd,
+ 0x7ae2, 0x3b33,
+ 0x7ae3, 0x0d02,
+ 0x7ae4, 0x2252,
+ 0x7ae5, 0x0d01,
+ 0x7ae6, 0x2251,
+ 0x7ae7, 0x385d,
+ 0x7ae9, 0x3831,
+ 0x7aea, 0x3742,
+ 0x7aeb, 0x24ed,
+ 0x7aed, 0x104b,
+ 0x7aee, 0x2769,
+ 0x7aef, 0x104c,
+ 0x7af6, 0x1629,
+ 0x7af7, 0x320d,
+ 0x7af9, 0x03f6,
+ 0x7afa, 0x0666,
+ 0x7afb, 0x1a24,
+ 0x7afd, 0x07cb,
+ 0x7afe, 0x3b3d,
+ 0x7aff, 0x07ca,
+ 0x7b00, 0x1bb8,
+ 0x7b04, 0x1d8d,
+ 0x7b05, 0x1d8f,
+ 0x7b06, 0x0968,
+ 0x7b08, 0x1d91,
+ 0x7b09, 0x1d94,
+ 0x7b0a, 0x1d92,
+ 0x7b0b, 0x3746,
+ 0x7b0c, 0x3b63,
+ 0x7b0e, 0x1d93,
+ 0x7b0f, 0x1d90,
+ 0x7b10, 0x1d8c,
+ 0x7b11, 0x0969,
+ 0x7b12, 0x1d95,
+ 0x7b13, 0x1d8e,
+ 0x7b14, 0x3f77,
+ 0x7b18, 0x1fd5,
+ 0x7b19, 0x0b4d,
+ 0x7b1a, 0x1fde,
+ 0x7b1b, 0x0b4a,
+ 0x7b1d, 0x1fd7,
+ 0x7b1e, 0x0b4e,
+ 0x7b1f, 0x3f11,
+ 0x7b20, 0x0b48,
+ 0x7b22, 0x1fd2,
+ 0x7b23, 0x1fdf,
+ 0x7b24, 0x1fd3,
+ 0x7b25, 0x1fd0,
+ 0x7b26, 0x0b4c,
+ 0x7b27, 0x3b5f,
+ 0x7b28, 0x0b49,
+ 0x7b29, 0x3748,
+ 0x7b2a, 0x1fd6,
+ 0x7b2b, 0x1fd9,
+ 0x7b2c, 0x0b4b,
+ 0x7b2d, 0x1fda,
+ 0x7b2e, 0x0b4f,
+ 0x7b2f, 0x1fdb,
+ 0x7b30, 0x1fd1,
+ 0x7b31, 0x1fd8,
+ 0x7b32, 0x1fdc,
+ 0x7b33, 0x1fd4,
+ 0x7b34, 0x1fcf,
+ 0x7b35, 0x1fcd,
+ 0x7b38, 0x1fdd,
+ 0x7b39, 0x3d6e,
+ 0x7b3b, 0x1fce,
+ 0x7b40, 0x2259,
+ 0x7b42, 0x3ded,
+ 0x7b43, 0x3e25,
+ 0x7b44, 0x2255,
+ 0x7b45, 0x225b,
+ 0x7b46, 0x0d05,
+ 0x7b47, 0x2254,
+ 0x7b48, 0x2256,
+ 0x7b49, 0x0d03,
+ 0x7b4a, 0x2253,
+ 0x7b4b, 0x0d0a,
+ 0x7b4c, 0x2257,
+ 0x7b4d, 0x0d09,
+ 0x7b4e, 0x2258,
+ 0x7b4f, 0x0d0b,
+ 0x7b50, 0x0d06,
+ 0x7b51, 0x0d0c,
+ 0x7b52, 0x0d07,
+ 0x7b54, 0x0d08,
+ 0x7b55, 0x3747,
+ 0x7b56, 0x0d04,
+ 0x7b58, 0x225a,
+ 0x7b60, 0x0eb8,
+ 0x7b61, 0x24f8,
+ 0x7b62, 0x4727,
+ 0x7b63, 0x24fb,
+ 0x7b64, 0x24ef,
+ 0x7b65, 0x24f4,
+ 0x7b66, 0x24ee,
+ 0x7b67, 0x0eba,
+ 0x7b69, 0x24f2,
+ 0x7b6c, 0x4728,
+ 0x7b6d, 0x24f0,
+ 0x7b6e, 0x0eb9,
+ 0x7b6f, 0x374c,
+ 0x7b70, 0x24f7,
+ 0x7b71, 0x24f6,
+ 0x7b72, 0x24f3,
+ 0x7b73, 0x24f5,
+ 0x7b74, 0x24f1,
+ 0x7b75, 0x1050,
+ 0x7b76, 0x24fa,
+ 0x7b77, 0x0eb6,
+ 0x7b78, 0x24f9,
+ 0x7b7b, 0x4729,
+ 0x7b82, 0x2779,
+ 0x7b84, 0x1057,
+ 0x7b85, 0x2774,
+ 0x7b87, 0x1056,
+ 0x7b88, 0x276a,
+ 0x7b8a, 0x276c,
+ 0x7b8b, 0x104f,
+ 0x7b8c, 0x2771,
+ 0x7b8d, 0x2770,
+ 0x7b8e, 0x2773,
+ 0x7b8f, 0x1054,
+ 0x7b90, 0x276e,
+ 0x7b91, 0x276d,
+ 0x7b92, 0x3752,
+ 0x7b94, 0x1053,
+ 0x7b95, 0x104e,
+ 0x7b96, 0x276f,
+ 0x7b97, 0x1051,
+ 0x7b98, 0x2775,
+ 0x7b99, 0x2777,
+ 0x7b9b, 0x2772,
+ 0x7b9c, 0x276b,
+ 0x7b9d, 0x1052,
+ 0x7ba0, 0x11d2,
+ 0x7ba1, 0x104d,
+ 0x7ba2, 0x374b,
+ 0x7ba3, 0x3f14,
+ 0x7ba4, 0x2778,
+ 0x7bac, 0x29aa,
+ 0x7bad, 0x11cb,
+ 0x7baf, 0x29ac,
+ 0x7bb1, 0x11cc,
+ 0x7bb2, 0x461c,
+ 0x7bb4, 0x11ce,
+ 0x7bb5, 0x29af,
+ 0x7bb7, 0x29a7,
+ 0x7bb8, 0x1055,
+ 0x7bb9, 0x29ad,
+ 0x7bbe, 0x29a9,
+ 0x7bc0, 0x0eb7,
+ 0x7bc1, 0x11d1,
+ 0x7bc4, 0x11cd,
+ 0x7bc6, 0x11cf,
+ 0x7bc9, 0x1318,
+ 0x7bca, 0x29ae,
+ 0x7bcb, 0x29a8,
+ 0x7bcc, 0x11d3,
+ 0x7bce, 0x29ab,
+ 0x7bcf, 0x3f18,
+ 0x7bd0, 0x3750,
+ 0x7bd4, 0x2c07,
+ 0x7bd5, 0x2c02,
+ 0x7bd8, 0x2c0c,
+ 0x7bd9, 0x1316,
+ 0x7bda, 0x2c04,
+ 0x7bdb, 0x131a,
+ 0x7bdc, 0x2c0a,
+ 0x7bdd, 0x2c01,
+ 0x7bde, 0x2bfe,
+ 0x7bdf, 0x2c0d,
+ 0x7be0, 0x142d,
+ 0x7be1, 0x131b,
+ 0x7be2, 0x2c09,
+ 0x7be3, 0x2bff,
+ 0x7be4, 0x1319,
+ 0x7be5, 0x2c03,
+ 0x7be6, 0x131d,
+ 0x7be7, 0x2c00,
+ 0x7be8, 0x2c05,
+ 0x7be9, 0x131c,
+ 0x7bea, 0x2c08,
+ 0x7beb, 0x2c0b,
+ 0x7bf0, 0x2de9,
+ 0x7bf2, 0x2dda,
+ 0x7bf3, 0x2de1,
+ 0x7bf4, 0x2ddf,
+ 0x7bf7, 0x142b,
+ 0x7bf8, 0x2de6,
+ 0x7bf9, 0x2c06,
+ 0x7bfa, 0x3757,
+ 0x7bfb, 0x2ddd,
+ 0x7bfc, 0x3f1f,
+ 0x7bfd, 0x2de7,
+ 0x7bfe, 0x142a,
+ 0x7bff, 0x2ddc,
+ 0x7c00, 0x2ddb,
+ 0x7c01, 0x2de5,
+ 0x7c02, 0x2de2,
+ 0x7c03, 0x2de4,
+ 0x7c05, 0x2dd8,
+ 0x7c06, 0x2de8,
+ 0x7c07, 0x1428,
+ 0x7c09, 0x2de3,
+ 0x7c0a, 0x2dec,
+ 0x7c0b, 0x2de0,
+ 0x7c0c, 0x142c,
+ 0x7c0d, 0x1429,
+ 0x7c0e, 0x2dde,
+ 0x7c0f, 0x2dd9,
+ 0x7c10, 0x2deb,
+ 0x7c11, 0x1317,
+ 0x7c12, 0x472a,
+ 0x7c15, 0x4061,
+ 0x7c19, 0x2f78,
+ 0x7c1b, 0x43d9,
+ 0x7c1c, 0x2f76,
+ 0x7c1d, 0x2f7c,
+ 0x7c1e, 0x1508,
+ 0x7c1f, 0x2f7a,
+ 0x7c20, 0x2f79,
+ 0x7c21, 0x150a,
+ 0x7c22, 0x2f7f,
+ 0x7c23, 0x1509,
+ 0x7c25, 0x2f80,
+ 0x7c26, 0x2f7d,
+ 0x7c27, 0x1506,
+ 0x7c28, 0x2f7e,
+ 0x7c29, 0x2f77,
+ 0x7c2a, 0x1507,
+ 0x7c2b, 0x1505,
+ 0x7c2c, 0x30d6,
+ 0x7c2d, 0x2f7b,
+ 0x7c30, 0x2f81,
+ 0x7c33, 0x30d3,
+ 0x7c35, 0x3759,
+ 0x7c37, 0x15a7,
+ 0x7c38, 0x15a5,
+ 0x7c39, 0x30d5,
+ 0x7c3b, 0x30d7,
+ 0x7c3c, 0x30d4,
+ 0x7c3d, 0x15a6,
+ 0x7c3e, 0x15a3,
+ 0x7c40, 0x15a8,
+ 0x7c42, 0x3f1c,
+ 0x7c43, 0x162b,
+ 0x7c44, 0x375b,
+ 0x7c45, 0x3212,
+ 0x7c47, 0x3211,
+ 0x7c48, 0x320f,
+ 0x7c49, 0x320e,
+ 0x7c4a, 0x3210,
+ 0x7c4c, 0x162a,
+ 0x7c4d, 0x162c,
+ 0x7c50, 0x1681,
+ 0x7c51, 0x3fb8,
+ 0x7c53, 0x32ea,
+ 0x7c54, 0x32e9,
+ 0x7c56, 0x3eff,
+ 0x7c57, 0x339b,
+ 0x7c59, 0x339d,
+ 0x7c5a, 0x339f,
+ 0x7c5b, 0x339e,
+ 0x7c5c, 0x339c,
+ 0x7c5d, 0x3b3f,
+ 0x7c5f, 0x16d1,
+ 0x7c60, 0x16d0,
+ 0x7c63, 0x1701,
+ 0x7c64, 0x1700,
+ 0x7c65, 0x1702,
+ 0x7c66, 0x342b,
+ 0x7c67, 0x342a,
+ 0x7c69, 0x34d6,
+ 0x7c6a, 0x3493,
+ 0x7c6b, 0x34d7,
+ 0x7c6c, 0x1745,
+ 0x7c6d, 0x3b40,
+ 0x7c6e, 0x1746,
+ 0x7c6f, 0x3507,
+ 0x7c70, 0x3f52,
+ 0x7c72, 0x176b,
+ 0x7c73, 0x03f7,
+ 0x7c74, 0x469c,
+ 0x7c75, 0x1a25,
+ 0x7c78, 0x1bbb,
+ 0x7c7a, 0x1bba,
+ 0x7c7b, 0x472d,
+ 0x7c7c, 0x3b49,
+ 0x7c7d, 0x07cc,
+ 0x7c7e, 0x3f1a,
+ 0x7c7f, 0x1bbd,
+ 0x7c83, 0x375c,
+ 0x7c84, 0x1d96,
+ 0x7c85, 0x1d9c,
+ 0x7c86, 0x3f1d,
+ 0x7c88, 0x1d9a,
+ 0x7c89, 0x096a,
+ 0x7c8a, 0x1d98,
+ 0x7c8c, 0x1d99,
+ 0x7c8d, 0x1d9b,
+ 0x7c8e, 0x3b48,
+ 0x7c91, 0x1d97,
+ 0x7c92, 0x0b50,
+ 0x7c94, 0x1fe0,
+ 0x7c95, 0x0b52,
+ 0x7c96, 0x1fe2,
+ 0x7c97, 0x0b51,
+ 0x7c98, 0x1fe1,
+ 0x7c9c, 0x472e,
+ 0x7c9e, 0x225d,
+ 0x7c9f, 0x0d0d,
+ 0x7ca1, 0x225f,
+ 0x7ca2, 0x225c,
+ 0x7ca3, 0x1fe3,
+ 0x7ca5, 0x0d0e,
+ 0x7ca6, 0x375e,
+ 0x7ca7, 0x36ed,
+ 0x7ca8, 0x225e,
+ 0x7cac, 0x3885,
+ 0x7cae, 0x3b4a,
+ 0x7caf, 0x24fe,
+ 0x7cb1, 0x0ebb,
+ 0x7cb2, 0x24fc,
+ 0x7cb3, 0x0ebc,
+ 0x7cb4, 0x24fd,
+ 0x7cb5, 0x0ebd,
+ 0x7cb8, 0x4730,
+ 0x7cb9, 0x1058,
+ 0x7cba, 0x277d,
+ 0x7cbb, 0x277a,
+ 0x7cbc, 0x277c,
+ 0x7cbd, 0x1059,
+ 0x7cbf, 0x277b,
+ 0x7cc2, 0x3fd7,
+ 0x7cc5, 0x29b0,
+ 0x7cc7, 0x3761,
+ 0x7cc8, 0x29b1,
+ 0x7cc9, 0x3760,
+ 0x7cca, 0x11d4,
+ 0x7ccb, 0x29b3,
+ 0x7ccc, 0x29b2,
+ 0x7ccd, 0x3b45,
+ 0x7cce, 0x0121,
+ 0x7cd0, 0x2c11,
+ 0x7cd2, 0x2c0e,
+ 0x7cd3, 0x3d5c,
+ 0x7cd4, 0x2c0f,
+ 0x7cd5, 0x131e,
+ 0x7cd7, 0x2c10,
+ 0x7cd9, 0x1433,
+ 0x7cda, 0x3fd9,
+ 0x7cdc, 0x142f,
+ 0x7cdd, 0x1434,
+ 0x7cde, 0x1430,
+ 0x7cdf, 0x1432,
+ 0x7ce0, 0x142e,
+ 0x7ce2, 0x1431,
+ 0x7ce6, 0x3762,
+ 0x7ce7, 0x150b,
+ 0x7ce8, 0x2ded,
+ 0x7cea, 0x30d9,
+ 0x7cec, 0x30d8,
+ 0x7ced, 0x43da,
+ 0x7cee, 0x3213,
+ 0x7cef, 0x162d,
+ 0x7cf1, 0x33a1,
+ 0x7cf2, 0x32eb,
+ 0x7cf3, 0x3764,
+ 0x7cf4, 0x33a0,
+ 0x7cf5, 0x3765,
+ 0x7cf6, 0x34d8,
+ 0x7cf7, 0x351d,
+ 0x7cf8, 0x03f8,
+ 0x7cf9, 0x44f8,
+ 0x7cfb, 0x04fb,
+ 0x7cfc, 0x456d,
+ 0x7cfd, 0x1a26,
+ 0x7cfe, 0x0667,
+ 0x7d00, 0x07cf,
+ 0x7d01, 0x1bc2,
+ 0x7d02, 0x07cd,
+ 0x7d03, 0x1bc0,
+ 0x7d04, 0x07d2,
+ 0x7d05, 0x07ce,
+ 0x7d06, 0x07d3,
+ 0x7d07, 0x07d1,
+ 0x7d08, 0x1bc1,
+ 0x7d09, 0x07d0,
+ 0x7d0a, 0x096e,
+ 0x7d0b, 0x096d,
+ 0x7d0c, 0x1da7,
+ 0x7d0d, 0x0976,
+ 0x7d0e, 0x1da0,
+ 0x7d0f, 0x1da6,
+ 0x7d10, 0x0972,
+ 0x7d11, 0x1d9f,
+ 0x7d12, 0x1da5,
+ 0x7d13, 0x1da3,
+ 0x7d14, 0x0971,
+ 0x7d15, 0x0973,
+ 0x7d16, 0x1da2,
+ 0x7d17, 0x096c,
+ 0x7d18, 0x1da1,
+ 0x7d19, 0x0977,
+ 0x7d1a, 0x0974,
+ 0x7d1b, 0x0978,
+ 0x7d1c, 0x0975,
+ 0x7d1d, 0x1d9e,
+ 0x7d1e, 0x1d9d,
+ 0x7d1f, 0x1da4,
+ 0x7d20, 0x096f,
+ 0x7d21, 0x096b,
+ 0x7d22, 0x0970,
+ 0x7d25, 0x3ede,
+ 0x7d28, 0x1ff2,
+ 0x7d29, 0x1feb,
+ 0x7d2b, 0x0d13,
+ 0x7d2c, 0x1fea,
+ 0x7d2e, 0x0b56,
+ 0x7d2f, 0x0b5d,
+ 0x7d30, 0x0b5a,
+ 0x7d31, 0x0b60,
+ 0x7d32, 0x0b5f,
+ 0x7d33, 0x0b5b,
+ 0x7d35, 0x1fe4,
+ 0x7d36, 0x1fe7,
+ 0x7d38, 0x1fe6,
+ 0x7d39, 0x0b57,
+ 0x7d3a, 0x1fe8,
+ 0x7d3b, 0x1ff1,
+ 0x7d3c, 0x0b58,
+ 0x7d3d, 0x1fe5,
+ 0x7d3e, 0x1fee,
+ 0x7d40, 0x0b59,
+ 0x7d41, 0x1fec,
+ 0x7d42, 0x0b5e,
+ 0x7d43, 0x0b54,
+ 0x7d44, 0x0b5c,
+ 0x7d45, 0x1fe9,
+ 0x7d46, 0x0b53,
+ 0x7d47, 0x1fed,
+ 0x7d4a, 0x1ff0,
+ 0x7d4d, 0x3fdd,
+ 0x7d4e, 0x2270,
+ 0x7d4f, 0x2267,
+ 0x7d50, 0x0d10,
+ 0x7d51, 0x226e,
+ 0x7d52, 0x226b,
+ 0x7d53, 0x2263,
+ 0x7d54, 0x226c,
+ 0x7d55, 0x0d12,
+ 0x7d56, 0x2264,
+ 0x7d58, 0x2260,
+ 0x7d5a, 0x3e93,
+ 0x7d5b, 0x0ec3,
+ 0x7d5c, 0x2269,
+ 0x7d5d, 0x3769,
+ 0x7d5e, 0x0d0f,
+ 0x7d5f, 0x226f,
+ 0x7d61, 0x0d16,
+ 0x7d62, 0x0d18,
+ 0x7d63, 0x2262,
+ 0x7d66, 0x0d17,
+ 0x7d67, 0x2265,
+ 0x7d68, 0x0d11,
+ 0x7d69, 0x226d,
+ 0x7d6a, 0x2266,
+ 0x7d6b, 0x226a,
+ 0x7d6d, 0x2268,
+ 0x7d6e, 0x0d14,
+ 0x7d6f, 0x2261,
+ 0x7d70, 0x0d19,
+ 0x7d71, 0x0b55,
+ 0x7d72, 0x0d15,
+ 0x7d73, 0x0d1a,
+ 0x7d79, 0x0ebf,
+ 0x7d7a, 0x2505,
+ 0x7d7b, 0x2507,
+ 0x7d7c, 0x2509,
+ 0x7d7d, 0x250d,
+ 0x7d7f, 0x2503,
+ 0x7d80, 0x2501,
+ 0x7d81, 0x0ec1,
+ 0x7d83, 0x2508,
+ 0x7d84, 0x250c,
+ 0x7d85, 0x2504,
+ 0x7d86, 0x2500,
+ 0x7d88, 0x24ff,
+ 0x7d89, 0x376b,
+ 0x7d8c, 0x250a,
+ 0x7d8d, 0x2502,
+ 0x7d8e, 0x2506,
+ 0x7d8f, 0x0ec2,
+ 0x7d91, 0x0ec0,
+ 0x7d92, 0x250e,
+ 0x7d93, 0x0ebe,
+ 0x7d94, 0x250b,
+ 0x7d96, 0x278e,
+ 0x7d97, 0x3b53,
+ 0x7d9c, 0x105d,
+ 0x7d9d, 0x2786,
+ 0x7d9e, 0x11e1,
+ 0x7d9f, 0x2790,
+ 0x7da0, 0x1060,
+ 0x7da1, 0x2794,
+ 0x7da2, 0x1066,
+ 0x7da3, 0x2781,
+ 0x7da4, 0x46d7,
+ 0x7da6, 0x2791,
+ 0x7da7, 0x277e,
+ 0x7da8, 0x3c9c,
+ 0x7da9, 0x2793,
+ 0x7daa, 0x2782,
+ 0x7dab, 0x376c,
+ 0x7dac, 0x106d,
+ 0x7dad, 0x106a,
+ 0x7dae, 0x2792,
+ 0x7daf, 0x278c,
+ 0x7db0, 0x105c,
+ 0x7db1, 0x1064,
+ 0x7db2, 0x1063,
+ 0x7db3, 0x376e,
+ 0x7db4, 0x1062,
+ 0x7db5, 0x1068,
+ 0x7db7, 0x277f,
+ 0x7db8, 0x1069,
+ 0x7db9, 0x278d,
+ 0x7dba, 0x1065,
+ 0x7dbb, 0x105b,
+ 0x7dbc, 0x278f,
+ 0x7dbd, 0x105e,
+ 0x7dbf, 0x1067,
+ 0x7dc0, 0x2784,
+ 0x7dc1, 0x2783,
+ 0x7dc2, 0x2780,
+ 0x7dc4, 0x2788,
+ 0x7dc5, 0x2785,
+ 0x7dc6, 0x2789,
+ 0x7dc7, 0x106c,
+ 0x7dc9, 0x2795,
+ 0x7dca, 0x1061,
+ 0x7dcb, 0x278a,
+ 0x7dcd, 0x456e,
+ 0x7dce, 0x2787,
+ 0x7dcf, 0x4735,
+ 0x7dd0, 0x4737,
+ 0x7dd2, 0x106b,
+ 0x7dd3, 0x3b4e,
+ 0x7dd4, 0x4736,
+ 0x7dd6, 0x376f,
+ 0x7dd7, 0x29b8,
+ 0x7dd8, 0x11d9,
+ 0x7dd9, 0x11e2,
+ 0x7dda, 0x11de,
+ 0x7ddb, 0x29b5,
+ 0x7ddc, 0x3b4c,
+ 0x7ddd, 0x11db,
+ 0x7dde, 0x11df,
+ 0x7ddf, 0x29c1,
+ 0x7de0, 0x11d5,
+ 0x7de1, 0x29b9,
+ 0x7de3, 0x11dd,
+ 0x7de4, 0x3772,
+ 0x7de5, 0x3776,
+ 0x7de6, 0x29bc,
+ 0x7de7, 0x29b7,
+ 0x7de8, 0x11dc,
+ 0x7de9, 0x11e0,
+ 0x7dea, 0x29b6,
+ 0x7dec, 0x11da,
+ 0x7dee, 0x29c0,
+ 0x7def, 0x11d7,
+ 0x7df0, 0x29bf,
+ 0x7df1, 0x29be,
+ 0x7df2, 0x11e3,
+ 0x7df3, 0x28c8,
+ 0x7df4, 0x11d6,
+ 0x7df5, 0x3774,
+ 0x7df6, 0x29bd,
+ 0x7df7, 0x29b4,
+ 0x7df9, 0x11e4,
+ 0x7dfa, 0x29bb,
+ 0x7dfb, 0x11d8,
+ 0x7dfd, 0x4738,
+ 0x7dfe, 0x3ccf,
+ 0x7e03, 0x29ba,
+ 0x7e07, 0x3b4d,
+ 0x7e08, 0x1322,
+ 0x7e09, 0x1327,
+ 0x7e0a, 0x1320,
+ 0x7e0b, 0x2c1f,
+ 0x7e0c, 0x2c16,
+ 0x7e0d, 0x2c22,
+ 0x7e0e, 0x2c1a,
+ 0x7e0f, 0x2c20,
+ 0x7e10, 0x1328,
+ 0x7e11, 0x1321,
+ 0x7e12, 0x2c13,
+ 0x7e13, 0x2c19,
+ 0x7e14, 0x2c23,
+ 0x7e15, 0x2c1c,
+ 0x7e16, 0x2c21,
+ 0x7e17, 0x2c15,
+ 0x7e1a, 0x2c1d,
+ 0x7e1b, 0x1323,
+ 0x7e1c, 0x2c1b,
+ 0x7e1d, 0x1326,
+ 0x7e1e, 0x1325,
+ 0x7e1f, 0x2c17,
+ 0x7e21, 0x2c14,
+ 0x7e22, 0x2c1e,
+ 0x7e23, 0x1324,
+ 0x7e24, 0x2c25,
+ 0x7e25, 0x2c24,
+ 0x7e27, 0x377f,
+ 0x7e29, 0x2df8,
+ 0x7e2a, 0x2df4,
+ 0x7e2b, 0x143b,
+ 0x7e2d, 0x2dee,
+ 0x7e2e, 0x1435,
+ 0x7e2f, 0x1445,
+ 0x7e30, 0x2dfa,
+ 0x7e31, 0x143d,
+ 0x7e32, 0x1439,
+ 0x7e33, 0x2df1,
+ 0x7e34, 0x1440,
+ 0x7e35, 0x1443,
+ 0x7e36, 0x2dfc,
+ 0x7e37, 0x1438,
+ 0x7e38, 0x2df3,
+ 0x7e39, 0x1441,
+ 0x7e3a, 0x2dfe,
+ 0x7e3b, 0x2dfb,
+ 0x7e3c, 0x2def,
+ 0x7e3d, 0x143c,
+ 0x7e3e, 0x1436,
+ 0x7e3f, 0x1444,
+ 0x7e40, 0x2df6,
+ 0x7e41, 0x143f,
+ 0x7e42, 0x2df0,
+ 0x7e43, 0x143a,
+ 0x7e44, 0x2dfd,
+ 0x7e45, 0x143e,
+ 0x7e46, 0x1437,
+ 0x7e47, 0x2df7,
+ 0x7e48, 0x1442,
+ 0x7e49, 0x2df5,
+ 0x7e4c, 0x2df9,
+ 0x7e50, 0x2f83,
+ 0x7e51, 0x2f89,
+ 0x7e52, 0x1511,
+ 0x7e53, 0x2f8c,
+ 0x7e54, 0x150c,
+ 0x7e56, 0x2f84,
+ 0x7e57, 0x2f8b,
+ 0x7e58, 0x2f86,
+ 0x7e59, 0x1512,
+ 0x7e5a, 0x150f,
+ 0x7e5c, 0x2f82,
+ 0x7e5e, 0x150e,
+ 0x7e5f, 0x2f88,
+ 0x7e60, 0x2f8a,
+ 0x7e61, 0x1510,
+ 0x7e62, 0x2f87,
+ 0x7e63, 0x2f85,
+ 0x7e65, 0x46d2,
+ 0x7e67, 0x3766,
+ 0x7e68, 0x30e3,
+ 0x7e69, 0x15ac,
+ 0x7e6b, 0x15a9,
+ 0x7e6d, 0x15aa,
+ 0x7e6e, 0x377b,
+ 0x7e6f, 0x30df,
+ 0x7e70, 0x30dd,
+ 0x7e72, 0x30e1,
+ 0x7e73, 0x15ae,
+ 0x7e74, 0x30e2,
+ 0x7e75, 0x30db,
+ 0x7e76, 0x30da,
+ 0x7e77, 0x30de,
+ 0x7e78, 0x30dc,
+ 0x7e79, 0x15ab,
+ 0x7e7a, 0x30e0,
+ 0x7e7b, 0x3214,
+ 0x7e7c, 0x1631,
+ 0x7e7d, 0x1630,
+ 0x7e7e, 0x3215,
+ 0x7e7f, 0x3e51,
+ 0x7e80, 0x3217,
+ 0x7e81, 0x3216,
+ 0x7e82, 0x1632,
+ 0x7e86, 0x32f0,
+ 0x7e87, 0x32ed,
+ 0x7e8a, 0x32ec,
+ 0x7e8b, 0x32ef,
+ 0x7e8c, 0x1683,
+ 0x7e8d, 0x32f1,
+ 0x7e8e, 0x3ec9,
+ 0x7e8f, 0x1682,
+ 0x7e91, 0x33a2,
+ 0x7e92, 0x469e,
+ 0x7e93, 0x1703,
+ 0x7e94, 0x1705,
+ 0x7e95, 0x342c,
+ 0x7e96, 0x1704,
+ 0x7e97, 0x3494,
+ 0x7e98, 0x34da,
+ 0x7e99, 0x34dc,
+ 0x7e9a, 0x34d9,
+ 0x7e9b, 0x34db,
+ 0x7e9c, 0x1759,
+ 0x7e9f, 0x48bb,
+ 0x7ea4, 0x455b,
+ 0x7eac, 0x455c,
+ 0x7eba, 0x455d,
+ 0x7ec7, 0x455e,
+ 0x7ecf, 0x455f,
+ 0x7edf, 0x4560,
+ 0x7f06, 0x4561,
+ 0x7f36, 0x03f9,
+ 0x7f37, 0x4562,
+ 0x7f38, 0x07d4,
+ 0x7f39, 0x1d1f,
+ 0x7f3a, 0x0979,
+ 0x7f3d, 0x0b61,
+ 0x7f3e, 0x2271,
+ 0x7f40, 0x3780,
+ 0x7f43, 0x2c26,
+ 0x7f44, 0x1446,
+ 0x7f45, 0x2dff,
+ 0x7f47, 0x3782,
+ 0x7f48, 0x1513,
+ 0x7f49, 0x3e69,
+ 0x7f4a, 0x30e5,
+ 0x7f4b, 0x30e4,
+ 0x7f4c, 0x1633,
+ 0x7f4d, 0x32f2,
+ 0x7f4e, 0x3b4f,
+ 0x7f4f, 0x33a3,
+ 0x7f50, 0x1726,
+ 0x7f51, 0x1812,
+ 0x7f52, 0x44f6,
+ 0x7f53, 0x44f9,
+ 0x7f54, 0x0668,
+ 0x7f55, 0x04fc,
+ 0x7f58, 0x1bc3,
+ 0x7f5b, 0x1dad,
+ 0x7f5c, 0x1da8,
+ 0x7f5d, 0x1dac,
+ 0x7f5e, 0x1daa,
+ 0x7f5f, 0x097a,
+ 0x7f60, 0x1dab,
+ 0x7f61, 0x1da9,
+ 0x7f63, 0x1ff3,
+ 0x7f65, 0x2273,
+ 0x7f67, 0x2511,
+ 0x7f69, 0x0ec5,
+ 0x7f6b, 0x2510,
+ 0x7f6c, 0x2513,
+ 0x7f6d, 0x250f,
+ 0x7f6e, 0x0ec4,
+ 0x7f70, 0x106e,
+ 0x7f71, 0x4007,
+ 0x7f72, 0x0ec7,
+ 0x7f73, 0x2796,
+ 0x7f75, 0x11e5,
+ 0x7f76, 0x29c2,
+ 0x7f77, 0x11e6,
+ 0x7f78, 0x3f7b,
+ 0x7f79, 0x1329,
+ 0x7f7a, 0x2c29,
+ 0x7f7b, 0x2c27,
+ 0x7f7d, 0x2e02,
+ 0x7f7e, 0x2e01,
+ 0x7f7f, 0x2e00,
+ 0x7f83, 0x30e6,
+ 0x7f85, 0x15af,
+ 0x7f86, 0x30e7,
+ 0x7f87, 0x33a4,
+ 0x7f88, 0x1727,
+ 0x7f89, 0x3495,
+ 0x7f8a, 0x03fa,
+ 0x7f8b, 0x066a,
+ 0x7f8c, 0x0669,
+ 0x7f8d, 0x1bc5,
+ 0x7f8e, 0x07d5,
+ 0x7f8f, 0x421c,
+ 0x7f91, 0x1bc4,
+ 0x7f92, 0x1daf,
+ 0x7f93, 0x43db,
+ 0x7f94, 0x097b,
+ 0x7f95, 0x1ff4,
+ 0x7f96, 0x1dae,
+ 0x7f97, 0x3786,
+ 0x7f9a, 0x0b63,
+ 0x7f9b, 0x1ff7,
+ 0x7f9c, 0x1ff5,
+ 0x7f9e, 0x0b62,
+ 0x7fa0, 0x2276,
+ 0x7fa2, 0x2275,
+ 0x7fa3, 0x3788,
+ 0x7fa4, 0x0eca,
+ 0x7fa5, 0x2515,
+ 0x7fa6, 0x2514,
+ 0x7fa7, 0x2516,
+ 0x7fa8, 0x0ec9,
+ 0x7fa9, 0x0ec8,
+ 0x7fac, 0x29c3,
+ 0x7fad, 0x29c5,
+ 0x7fae, 0x43dc,
+ 0x7faf, 0x11e7,
+ 0x7fb0, 0x29c4,
+ 0x7fb1, 0x2c2a,
+ 0x7fb2, 0x132a,
+ 0x7fb3, 0x2f8e,
+ 0x7fb4, 0x4739,
+ 0x7fb5, 0x2f8d,
+ 0x7fb6, 0x15b0,
+ 0x7fb7, 0x30e8,
+ 0x7fb8, 0x15b2,
+ 0x7fb9, 0x15b1,
+ 0x7fba, 0x3218,
+ 0x7fbb, 0x32f3,
+ 0x7fbc, 0x1684,
+ 0x7fbd, 0x03fb,
+ 0x7fbe, 0x1bc6,
+ 0x7fbf, 0x07d6,
+ 0x7fc0, 0x1db2,
+ 0x7fc1, 0x097d,
+ 0x7fc2, 0x1db1,
+ 0x7fc3, 0x1db0,
+ 0x7fc5, 0x097c,
+ 0x7fc7, 0x1ffd,
+ 0x7fc9, 0x1fff,
+ 0x7fca, 0x1ff8,
+ 0x7fcc, 0x0b64,
+ 0x7fcd, 0x1ffa,
+ 0x7fce, 0x0b65,
+ 0x7fcf, 0x1ffe,
+ 0x7fd0, 0x1ffb,
+ 0x7fd2, 0x0b66,
+ 0x7fd4, 0x0d1c,
+ 0x7fd7, 0x2278,
+ 0x7fdb, 0x2517,
+ 0x7fdd, 0x3b5e,
+ 0x7fde, 0x279a,
+ 0x7fdf, 0x1071,
+ 0x7fe0, 0x106f,
+ 0x7fe2, 0x2797,
+ 0x7fe5, 0x2799,
+ 0x7fe6, 0x29ca,
+ 0x7fe7, 0x46e9,
+ 0x7fe8, 0x29cb,
+ 0x7fe9, 0x11e8,
+ 0x7fea, 0x29c8,
+ 0x7feb, 0x29c7,
+ 0x7fec, 0x29c9,
+ 0x7fed, 0x29c6,
+ 0x7fee, 0x132d,
+ 0x7fef, 0x2c2b,
+ 0x7ff0, 0x132b,
+ 0x7ff2, 0x2e04,
+ 0x7ff3, 0x1447,
+ 0x7ff4, 0x2e03,
+ 0x7ff5, 0x2eff,
+ 0x7ff7, 0x2f8f,
+ 0x7ff9, 0x1514,
+ 0x7ffa, 0x378e,
+ 0x7ffb, 0x1515,
+ 0x7ffc, 0x1448,
+ 0x7ffd, 0x30e9,
+ 0x7fff, 0x3219,
+ 0x8000, 0x1634,
+ 0x8001, 0x03fc,
+ 0x8002, 0x44fd,
+ 0x8003, 0x03fd,
+ 0x8004, 0x097f,
+ 0x8005, 0x066b,
+ 0x8006, 0x097e,
+ 0x8007, 0x1bc7,
+ 0x8008, 0x3791,
+ 0x800b, 0x0d1e,
+ 0x800c, 0x03fe,
+ 0x800d, 0x07d8,
+ 0x800e, 0x1bc8,
+ 0x8010, 0x07d7,
+ 0x8011, 0x07d9,
+ 0x8012, 0x03ff,
+ 0x8014, 0x1bca,
+ 0x8015, 0x0981,
+ 0x8016, 0x1db3,
+ 0x8017, 0x0983,
+ 0x8018, 0x0980,
+ 0x8019, 0x0982,
+ 0x801b, 0x2002,
+ 0x801c, 0x0b67,
+ 0x801d, 0x3792,
+ 0x801e, 0x2001,
+ 0x801f, 0x2000,
+ 0x8020, 0x473c,
+ 0x8021, 0x2519,
+ 0x8024, 0x279b,
+ 0x8025, 0x473d,
+ 0x8026, 0x11e9,
+ 0x8028, 0x132e,
+ 0x8029, 0x2c2d,
+ 0x802a, 0x2c2c,
+ 0x802c, 0x2e05,
+ 0x802e, 0x473e,
+ 0x802f, 0x3794,
+ 0x8030, 0x32f4,
+ 0x8031, 0x473f,
+ 0x8033, 0x0400,
+ 0x8034, 0x18d8,
+ 0x8035, 0x1a27,
+ 0x8036, 0x07da,
+ 0x8037, 0x1bcb,
+ 0x8039, 0x1db5,
+ 0x803b, 0x3797,
+ 0x803d, 0x0984,
+ 0x803e, 0x1db4,
+ 0x803f, 0x0985,
+ 0x8043, 0x2004,
+ 0x8046, 0x0b69,
+ 0x8047, 0x2003,
+ 0x8048, 0x2005,
+ 0x804a, 0x0b68,
+ 0x804f, 0x227a,
+ 0x8051, 0x2279,
+ 0x8052, 0x0d1f,
+ 0x8054, 0x4740,
+ 0x8056, 0x0ecb,
+ 0x8058, 0x0ecc,
+ 0x805a, 0x1073,
+ 0x805b, 0x3fe5,
+ 0x805c, 0x279d,
+ 0x805d, 0x279c,
+ 0x805e, 0x1072,
+ 0x8061, 0x3799,
+ 0x8062, 0x3fe3,
+ 0x8063, 0x3fdc,
+ 0x8064, 0x29cc,
+ 0x8066, 0x3fdb,
+ 0x8067, 0x29cd,
+ 0x806c, 0x2c2e,
+ 0x806f, 0x144c,
+ 0x8070, 0x144b,
+ 0x8071, 0x1449,
+ 0x8073, 0x144d,
+ 0x8075, 0x2f91,
+ 0x8076, 0x1517,
+ 0x8077, 0x1516,
+ 0x8078, 0x30eb,
+ 0x8079, 0x321a,
+ 0x807d, 0x16d3,
+ 0x807e, 0x16d2,
+ 0x807f, 0x0401,
+ 0x8080, 0x44fe,
+ 0x8082, 0x1cec,
+ 0x8084, 0x0ece,
+ 0x8085, 0x0d20,
+ 0x8086, 0x0ecd,
+ 0x8087, 0x1074,
+ 0x8089, 0x0402,
+ 0x808a, 0x17b3,
+ 0x808b, 0x0403,
+ 0x808f, 0x1a28,
+ 0x8090, 0x18db,
+ 0x8092, 0x18dc,
+ 0x8093, 0x04fe,
+ 0x8095, 0x18d9,
+ 0x8096, 0x04fd,
+ 0x8098, 0x0500,
+ 0x8099, 0x18da,
+ 0x809a, 0x0502,
+ 0x809b, 0x0501,
+ 0x809c, 0x18dd,
+ 0x809d, 0x04ff,
+ 0x809f, 0x4576,
+ 0x80a1, 0x0670,
+ 0x80a2, 0x066e,
+ 0x80a3, 0x1a2a,
+ 0x80a5, 0x066d,
+ 0x80a7, 0x37a0,
+ 0x80a9, 0x0672,
+ 0x80aa, 0x0674,
+ 0x80ab, 0x0671,
+ 0x80ad, 0x1a2d,
+ 0x80ae, 0x1a29,
+ 0x80af, 0x0675,
+ 0x80b1, 0x066f,
+ 0x80b2, 0x0503,
+ 0x80b4, 0x0673,
+ 0x80b5, 0x1a2c,
+ 0x80b6, 0x3eae,
+ 0x80b7, 0x4743,
+ 0x80b8, 0x1a2b,
+ 0x80ba, 0x066c,
+ 0x80bc, 0x4572,
+ 0x80bd, 0x3e7b,
+ 0x80c2, 0x1bd1,
+ 0x80c3, 0x07de,
+ 0x80c5, 0x1bd3,
+ 0x80c6, 0x3b74,
+ 0x80c7, 0x1bcd,
+ 0x80c8, 0x1bd0,
+ 0x80c9, 0x1bd9,
+ 0x80ca, 0x1bd7,
+ 0x80cc, 0x07e0,
+ 0x80cd, 0x1bdd,
+ 0x80ce, 0x07e3,
+ 0x80cf, 0x1bda,
+ 0x80d0, 0x1bd2,
+ 0x80d1, 0x1bcf,
+ 0x80d4, 0x227d,
+ 0x80d5, 0x1bd8,
+ 0x80d6, 0x07db,
+ 0x80d7, 0x1bdb,
+ 0x80d8, 0x1bcc,
+ 0x80d9, 0x1bd5,
+ 0x80da, 0x07dd,
+ 0x80db, 0x07e2,
+ 0x80dc, 0x1bd6,
+ 0x80dd, 0x07e6,
+ 0x80de, 0x07e4,
+ 0x80e0, 0x1bce,
+ 0x80e1, 0x07e1,
+ 0x80e3, 0x1bd4,
+ 0x80e4, 0x07e5,
+ 0x80e5, 0x07dc,
+ 0x80e6, 0x1bdc,
+ 0x80e9, 0x4744,
+ 0x80ec, 0x45e9,
+ 0x80ed, 0x098a,
+ 0x80ef, 0x0993,
+ 0x80f0, 0x0988,
+ 0x80f1, 0x0986,
+ 0x80f2, 0x1db7,
+ 0x80f3, 0x098e,
+ 0x80f4, 0x098b,
+ 0x80f5, 0x1db9,
+ 0x80f6, 0x4574,
+ 0x80f8, 0x098d,
+ 0x80f9, 0x1db8,
+ 0x80fa, 0x1db6,
+ 0x80fb, 0x1dbb,
+ 0x80fc, 0x0992,
+ 0x80fd, 0x0990,
+ 0x80fe, 0x227c,
+ 0x8100, 0x1dbc,
+ 0x8101, 0x1dba,
+ 0x8102, 0x0987,
+ 0x8103, 0x3fe7,
+ 0x8105, 0x0989,
+ 0x8106, 0x098c,
+ 0x8107, 0x37a2,
+ 0x8108, 0x098f,
+ 0x8109, 0x3b75,
+ 0x810a, 0x0991,
+ 0x810c, 0x4746,
+ 0x810e, 0x4747,
+ 0x8112, 0x4748,
+ 0x8114, 0x4749,
+ 0x8115, 0x200f,
+ 0x8116, 0x0b6b,
+ 0x8117, 0x3e6d,
+ 0x8118, 0x2006,
+ 0x8119, 0x2008,
+ 0x811a, 0x37a3,
+ 0x811b, 0x2009,
+ 0x811d, 0x2011,
+ 0x811e, 0x200d,
+ 0x811f, 0x200b,
+ 0x8121, 0x200e,
+ 0x8122, 0x2012,
+ 0x8123, 0x0b6c,
+ 0x8124, 0x0b70,
+ 0x8125, 0x2007,
+ 0x8127, 0x2010,
+ 0x8129, 0x0b6e,
+ 0x812a, 0x3a39,
+ 0x812b, 0x0b6d,
+ 0x812c, 0x200c,
+ 0x812d, 0x200a,
+ 0x812f, 0x0b6a,
+ 0x8130, 0x0b6f,
+ 0x8132, 0x3e79,
+ 0x8134, 0x45ec,
+ 0x8137, 0x3b72,
+ 0x8139, 0x0d26,
+ 0x813a, 0x2285,
+ 0x813d, 0x2283,
+ 0x813e, 0x0d28,
+ 0x8142, 0x3b76,
+ 0x8143, 0x227e,
+ 0x8144, 0x2527,
+ 0x8146, 0x0d27,
+ 0x8147, 0x2282,
+ 0x8148, 0x3e76,
+ 0x814a, 0x227f,
+ 0x814b, 0x0d23,
+ 0x814c, 0x0d29,
+ 0x814d, 0x2284,
+ 0x814e, 0x0d25,
+ 0x814f, 0x2281,
+ 0x8150, 0x1075,
+ 0x8151, 0x0d24,
+ 0x8152, 0x2280,
+ 0x8153, 0x0d2a,
+ 0x8154, 0x0d22,
+ 0x8155, 0x0d21,
+ 0x8156, 0x474c,
+ 0x8159, 0x474d,
+ 0x815b, 0x251f,
+ 0x815c, 0x251d,
+ 0x815e, 0x2523,
+ 0x8160, 0x251b,
+ 0x8161, 0x2528,
+ 0x8162, 0x2520,
+ 0x8164, 0x251a,
+ 0x8165, 0x0ed2,
+ 0x8166, 0x0ed8,
+ 0x8167, 0x2525,
+ 0x8169, 0x251e,
+ 0x816b, 0x0ed5,
+ 0x816d, 0x43c4,
+ 0x816e, 0x0ed3,
+ 0x816f, 0x2526,
+ 0x8170, 0x0ed0,
+ 0x8171, 0x0ecf,
+ 0x8172, 0x2521,
+ 0x8173, 0x0ed4,
+ 0x8174, 0x0d2b,
+ 0x8176, 0x2524,
+ 0x8177, 0x251c,
+ 0x8178, 0x0ed1,
+ 0x8179, 0x0ed6,
+ 0x817c, 0x4750,
+ 0x817f, 0x107a,
+ 0x8180, 0x1076,
+ 0x8182, 0x107b,
+ 0x8183, 0x27a0,
+ 0x8184, 0x43c5,
+ 0x8186, 0x279f,
+ 0x8187, 0x27a1,
+ 0x8188, 0x1078,
+ 0x8189, 0x279e,
+ 0x818a, 0x1079,
+ 0x818b, 0x27a4,
+ 0x818c, 0x27a3,
+ 0x818d, 0x27a2,
+ 0x818f, 0x1077,
+ 0x8193, 0x43c6,
+ 0x8195, 0x29d1,
+ 0x8197, 0x29d4,
+ 0x8198, 0x11ef,
+ 0x8199, 0x29d3,
+ 0x819a, 0x11ee,
+ 0x819b, 0x11ea,
+ 0x819e, 0x29d0,
+ 0x819f, 0x29cf,
+ 0x81a0, 0x11ed,
+ 0x81a2, 0x29d2,
+ 0x81a3, 0x29ce,
+ 0x81a5, 0x4753,
+ 0x81a6, 0x2c30,
+ 0x81a7, 0x2c3a,
+ 0x81a8, 0x1331,
+ 0x81a9, 0x1330,
+ 0x81aa, 0x4364,
+ 0x81ab, 0x2c34,
+ 0x81ac, 0x2c36,
+ 0x81ae, 0x2c31,
+ 0x81b0, 0x2c35,
+ 0x81b1, 0x2c2f,
+ 0x81b2, 0x2c38,
+ 0x81b3, 0x132f,
+ 0x81b4, 0x2c37,
+ 0x81b5, 0x2c33,
+ 0x81b6, 0x3eb2,
+ 0x81b7, 0x2c39,
+ 0x81b9, 0x2c32,
+ 0x81ba, 0x1450,
+ 0x81bb, 0x2e06,
+ 0x81bc, 0x2e0c,
+ 0x81bd, 0x1454,
+ 0x81be, 0x1456,
+ 0x81bf, 0x1453,
+ 0x81c0, 0x1452,
+ 0x81c1, 0x4755,
+ 0x81c2, 0x1451,
+ 0x81c3, 0x144f,
+ 0x81c4, 0x2e07,
+ 0x81c5, 0x2e0a,
+ 0x81c6, 0x144e,
+ 0x81c7, 0x2e0b,
+ 0x81c8, 0x3fee,
+ 0x81c9, 0x1455,
+ 0x81ca, 0x2e09,
+ 0x81cc, 0x2e08,
+ 0x81cd, 0x1518,
+ 0x81cf, 0x1519,
+ 0x81d0, 0x2f94,
+ 0x81d1, 0x2f92,
+ 0x81d5, 0x30ed,
+ 0x81d7, 0x30ec,
+ 0x81d8, 0x15b3,
+ 0x81d9, 0x321c,
+ 0x81da, 0x1635,
+ 0x81db, 0x321b,
+ 0x81dd, 0x32f5,
+ 0x81de, 0x33a5,
+ 0x81df, 0x16d4,
+ 0x81e0, 0x34dd,
+ 0x81e2, 0x1706,
+ 0x81e3, 0x0405,
+ 0x81e4, 0x4756,
+ 0x81e5, 0x0676,
+ 0x81e6, 0x2286,
+ 0x81e7, 0x107c,
+ 0x81e8, 0x1457,
+ 0x81e9, 0x2e0d,
+ 0x81ea, 0x0406,
+ 0x81ec, 0x0995,
+ 0x81ed, 0x0994,
+ 0x81ee, 0x2287,
+ 0x81ef, 0x42d1,
+ 0x81f2, 0x2c3b,
+ 0x81f3, 0x0407,
+ 0x81f4, 0x07e7,
+ 0x81f6, 0x3d61,
+ 0x81f7, 0x2288,
+ 0x81fa, 0x107d,
+ 0x81fb, 0x1332,
+ 0x81fc, 0x0408,
+ 0x81fe, 0x0677,
+ 0x81ff, 0x1bde,
+ 0x8200, 0x0996,
+ 0x8201, 0x1dbd,
+ 0x8202, 0x0b71,
+ 0x8204, 0x228b,
+ 0x8205, 0x0ed9,
+ 0x8207, 0x107e,
+ 0x8208, 0x1333,
+ 0x8209, 0x1458,
+ 0x820a, 0x151a,
+ 0x820b, 0x30ee,
+ 0x820c, 0x0409,
+ 0x820d, 0x0678,
+ 0x8210, 0x0997,
+ 0x8211, 0x2013,
+ 0x8212, 0x0d2c,
+ 0x8214, 0x107f,
+ 0x8215, 0x27a5,
+ 0x8216, 0x29d5,
+ 0x8218, 0x37aa,
+ 0x821a, 0x3fe1,
+ 0x821b, 0x040a,
+ 0x821c, 0x0d2d,
+ 0x821d, 0x2529,
+ 0x821e, 0x1080,
+ 0x821f, 0x040b,
+ 0x8220, 0x1a2e,
+ 0x8221, 0x1bdf,
+ 0x8222, 0x07e8,
+ 0x8225, 0x1dbf,
+ 0x8226, 0x420d,
+ 0x8228, 0x099a,
+ 0x8229, 0x37b0,
+ 0x822a, 0x0998,
+ 0x822c, 0x099b,
+ 0x822d, 0x3ed0,
+ 0x822f, 0x1dbe,
+ 0x8232, 0x2018,
+ 0x8233, 0x2015,
+ 0x8234, 0x2017,
+ 0x8235, 0x0b72,
+ 0x8236, 0x0b74,
+ 0x8237, 0x0b73,
+ 0x8238, 0x2014,
+ 0x8239, 0x0b75,
+ 0x823a, 0x2016,
+ 0x823c, 0x228c,
+ 0x823e, 0x4582,
+ 0x823f, 0x228e,
+ 0x8240, 0x252c,
+ 0x8242, 0x252d,
+ 0x8244, 0x252b,
+ 0x8245, 0x252e,
+ 0x8247, 0x0eda,
+ 0x8249, 0x252a,
+ 0x824b, 0x1081,
+ 0x824e, 0x29da,
+ 0x824f, 0x29d6,
+ 0x8250, 0x29d9,
+ 0x8251, 0x29db,
+ 0x8252, 0x29d8,
+ 0x8253, 0x29d7,
+ 0x8254, 0x4757,
+ 0x8255, 0x2c3c,
+ 0x8258, 0x1334,
+ 0x825a, 0x2e0f,
+ 0x825b, 0x2e0e,
+ 0x825c, 0x2e10,
+ 0x825e, 0x2f96,
+ 0x825f, 0x2f95,
+ 0x8261, 0x30f0,
+ 0x8262, 0x3b7a,
+ 0x8263, 0x30f1,
+ 0x8264, 0x30ef,
+ 0x8265, 0x3b7b,
+ 0x8266, 0x1636,
+ 0x8268, 0x321d,
+ 0x826b, 0x33a6,
+ 0x826c, 0x342d,
+ 0x826d, 0x3496,
+ 0x826e, 0x040c,
+ 0x826f, 0x0504,
+ 0x8271, 0x1459,
+ 0x8272, 0x040d,
+ 0x8274, 0x2019,
+ 0x8275, 0x228f,
+ 0x8276, 0x4759,
+ 0x8277, 0x172e,
+ 0x8278, 0x1813,
+ 0x8279, 0x4722,
+ 0x827a, 0x4563,
+ 0x827b, 0x37c8,
+ 0x827c, 0x1814,
+ 0x827d, 0x1816,
+ 0x827e, 0x040e,
+ 0x827f, 0x1817,
+ 0x8280, 0x1815,
+ 0x8283, 0x18e5,
+ 0x8285, 0x18e0,
+ 0x8287, 0x4132,
+ 0x828a, 0x18e4,
+ 0x828b, 0x0506,
+ 0x828d, 0x0507,
+ 0x828e, 0x18e1,
+ 0x828f, 0x18df,
+ 0x8290, 0x18de,
+ 0x8291, 0x18e2,
+ 0x8292, 0x0505,
+ 0x8293, 0x18e3,
+ 0x8294, 0x1be0,
+ 0x8298, 0x1a33,
+ 0x8299, 0x067b,
+ 0x829a, 0x1a32,
+ 0x829b, 0x1a34,
+ 0x829d, 0x067a,
+ 0x829e, 0x1a39,
+ 0x829f, 0x067e,
+ 0x82a0, 0x1a2f,
+ 0x82a1, 0x1a3d,
+ 0x82a2, 0x1a43,
+ 0x82a3, 0x0685,
+ 0x82a4, 0x1a40,
+ 0x82a5, 0x0682,
+ 0x82a6, 0x3d73,
+ 0x82a7, 0x1a36,
+ 0x82a8, 0x1a3c,
+ 0x82a9, 0x1a3e,
+ 0x82aa, 0x37bc,
+ 0x82ab, 0x1a31,
+ 0x82ac, 0x0681,
+ 0x82ad, 0x067c,
+ 0x82ae, 0x1a37,
+ 0x82af, 0x0683,
+ 0x82b0, 0x0686,
+ 0x82b1, 0x0680,
+ 0x82b3, 0x0679,
+ 0x82b4, 0x1a3b,
+ 0x82b5, 0x1a35,
+ 0x82b6, 0x1a42,
+ 0x82b7, 0x0688,
+ 0x82b8, 0x0684,
+ 0x82b9, 0x067f,
+ 0x82ba, 0x1a3a,
+ 0x82bb, 0x099c,
+ 0x82bc, 0x1a38,
+ 0x82bd, 0x067d,
+ 0x82be, 0x0687,
+ 0x82c0, 0x1a30,
+ 0x82c2, 0x1a3f,
+ 0x82c3, 0x1a41,
+ 0x82c4, 0x45e3,
+ 0x82ca, 0x475a,
+ 0x82cf, 0x4564,
+ 0x82d0, 0x37c1,
+ 0x82d1, 0x07f9,
+ 0x82d2, 0x07f3,
+ 0x82d3, 0x07fb,
+ 0x82d4, 0x07f8,
+ 0x82d5, 0x1be7,
+ 0x82d6, 0x1bea,
+ 0x82d7, 0x07f4,
+ 0x82d8, 0x475b,
+ 0x82d9, 0x1be1,
+ 0x82db, 0x07ed,
+ 0x82dc, 0x07f7,
+ 0x82de, 0x07fa,
+ 0x82df, 0x07fc,
+ 0x82e0, 0x1bf6,
+ 0x82e1, 0x1bed,
+ 0x82e2, 0x37c9,
+ 0x82e3, 0x07ec,
+ 0x82e4, 0x1bf5,
+ 0x82e5, 0x07f0,
+ 0x82e6, 0x07ee,
+ 0x82e7, 0x07e9,
+ 0x82e8, 0x1be5,
+ 0x82ea, 0x1bf4,
+ 0x82eb, 0x1be9,
+ 0x82ec, 0x1bec,
+ 0x82ed, 0x1bf9,
+ 0x82ee, 0x4018,
+ 0x82ef, 0x07fd,
+ 0x82f0, 0x1bf3,
+ 0x82f1, 0x07f5,
+ 0x82f2, 0x1bee,
+ 0x82f3, 0x1bf8,
+ 0x82f4, 0x1beb,
+ 0x82f5, 0x1bef,
+ 0x82f6, 0x1bf2,
+ 0x82f7, 0x3e77,
+ 0x82f9, 0x1be3,
+ 0x82fa, 0x1bf7,
+ 0x82fb, 0x1bf1,
+ 0x82fc, 0x412d,
+ 0x82fd, 0x3d92,
+ 0x82fe, 0x1be2,
+ 0x82ff, 0x43de,
+ 0x8300, 0x1be6,
+ 0x8301, 0x07f6,
+ 0x8302, 0x07f1,
+ 0x8303, 0x07ea,
+ 0x8304, 0x07ef,
+ 0x8305, 0x07eb,
+ 0x8306, 0x07fe,
+ 0x8307, 0x1be4,
+ 0x8308, 0x1dd0,
+ 0x8309, 0x07f2,
+ 0x830b, 0x3eb6,
+ 0x830c, 0x1bf0,
+ 0x830d, 0x1a7d,
+ 0x8316, 0x1dd3,
+ 0x8317, 0x09aa,
+ 0x8318, 0x37ca,
+ 0x8319, 0x1dc3,
+ 0x831a, 0x37c2,
+ 0x831b, 0x1dce,
+ 0x831c, 0x1dca,
+ 0x831d, 0x37d1,
+ 0x831e, 0x1ddd,
+ 0x8320, 0x1dd5,
+ 0x8322, 0x1dcb,
+ 0x8324, 0x1dd4,
+ 0x8325, 0x1dc5,
+ 0x8326, 0x1dc9,
+ 0x8327, 0x1de0,
+ 0x8328, 0x09ad,
+ 0x8329, 0x1dd8,
+ 0x832a, 0x1dcf,
+ 0x832b, 0x099d,
+ 0x832c, 0x1dde,
+ 0x832d, 0x1dc1,
+ 0x832f, 0x1dd7,
+ 0x8331, 0x09ac,
+ 0x8332, 0x09a7,
+ 0x8333, 0x1dc0,
+ 0x8334, 0x09a5,
+ 0x8335, 0x09a4,
+ 0x8336, 0x09a9,
+ 0x8337, 0x1dd6,
+ 0x8338, 0x09a1,
+ 0x8339, 0x09a8,
+ 0x833a, 0x1be8,
+ 0x833b, 0x2290,
+ 0x833c, 0x1dd1,
+ 0x833d, 0x3d2a,
+ 0x833f, 0x1dc7,
+ 0x8340, 0x09ab,
+ 0x8341, 0x1dc8,
+ 0x8342, 0x1dcc,
+ 0x8343, 0x09ae,
+ 0x8344, 0x1dc2,
+ 0x8345, 0x1dda,
+ 0x8347, 0x1dd9,
+ 0x8348, 0x1de1,
+ 0x8349, 0x09a3,
+ 0x834a, 0x09a0,
+ 0x834b, 0x1ddf,
+ 0x834c, 0x1ddb,
+ 0x834d, 0x1dd2,
+ 0x834e, 0x1dcd,
+ 0x834f, 0x09a6,
+ 0x8350, 0x09a2,
+ 0x8351, 0x1dc4,
+ 0x8352, 0x099e,
+ 0x8353, 0x1ddc,
+ 0x8354, 0x099f,
+ 0x8356, 0x1dc6,
+ 0x8357, 0x475d,
+ 0x8362, 0x37b6,
+ 0x8363, 0x41eb,
+ 0x8366, 0x3e1e,
+ 0x836f, 0x4565,
+ 0x8373, 0x201f,
+ 0x8374, 0x2021,
+ 0x8375, 0x2026,
+ 0x8376, 0x203a,
+ 0x8377, 0x0b83,
+ 0x8378, 0x0b79,
+ 0x837a, 0x201e,
+ 0x837b, 0x0b84,
+ 0x837d, 0x2029,
+ 0x837e, 0x2030,
+ 0x837f, 0x2036,
+ 0x8381, 0x2023,
+ 0x8383, 0x202a,
+ 0x8385, 0x37d3,
+ 0x8386, 0x0b86,
+ 0x8387, 0x2038,
+ 0x8388, 0x2033,
+ 0x8389, 0x0b81,
+ 0x838a, 0x0b7f,
+ 0x838b, 0x202f,
+ 0x838c, 0x202b,
+ 0x838d, 0x201d,
+ 0x838e, 0x0b76,
+ 0x838f, 0x2022,
+ 0x8390, 0x201a,
+ 0x8391, 0x37ec,
+ 0x8392, 0x0b7e,
+ 0x8393, 0x0b80,
+ 0x8394, 0x2027,
+ 0x8395, 0x2024,
+ 0x8396, 0x0b7b,
+ 0x8397, 0x2034,
+ 0x8398, 0x0b78,
+ 0x8399, 0x2025,
+ 0x839a, 0x22b9,
+ 0x839b, 0x202d,
+ 0x839c, 0x374d,
+ 0x839d, 0x202c,
+ 0x839e, 0x0b77,
+ 0x83a0, 0x0b82,
+ 0x83a2, 0x0b7a,
+ 0x83a3, 0x201b,
+ 0x83a4, 0x2020,
+ 0x83a5, 0x2031,
+ 0x83a6, 0x2037,
+ 0x83a7, 0x0b87,
+ 0x83a8, 0x201c,
+ 0x83a9, 0x2028,
+ 0x83aa, 0x202e,
+ 0x83ab, 0x0b7d,
+ 0x83ac, 0x37d6,
+ 0x83ae, 0x2039,
+ 0x83af, 0x2032,
+ 0x83b0, 0x2035,
+ 0x83b9, 0x42a7,
+ 0x83bd, 0x0b7c,
+ 0x83be, 0x3f59,
+ 0x83bf, 0x22a0,
+ 0x83c0, 0x2294,
+ 0x83c1, 0x0d35,
+ 0x83c2, 0x22b1,
+ 0x83c3, 0x22ba,
+ 0x83c4, 0x22bd,
+ 0x83c5, 0x0d33,
+ 0x83c6, 0x229c,
+ 0x83c7, 0x22b5,
+ 0x83c8, 0x229d,
+ 0x83c9, 0x22ab,
+ 0x83ca, 0x0d40,
+ 0x83cb, 0x22a7,
+ 0x83cc, 0x0d3d,
+ 0x83cd, 0x4055,
+ 0x83ce, 0x22a8,
+ 0x83cf, 0x2291,
+ 0x83d1, 0x22b6,
+ 0x83d3, 0x37d8,
+ 0x83d4, 0x0d46,
+ 0x83d5, 0x22b3,
+ 0x83d6, 0x22a9,
+ 0x83d7, 0x22bf,
+ 0x83d8, 0x22a4,
+ 0x83d9, 0x254e,
+ 0x83db, 0x22c2,
+ 0x83dc, 0x0d44,
+ 0x83dd, 0x22a2,
+ 0x83de, 0x22ae,
+ 0x83df, 0x0d47,
+ 0x83e0, 0x0d32,
+ 0x83e1, 0x22a6,
+ 0x83e2, 0x22c0,
+ 0x83e3, 0x229f,
+ 0x83e4, 0x2298,
+ 0x83e5, 0x22a3,
+ 0x83e7, 0x2297,
+ 0x83e8, 0x2295,
+ 0x83e9, 0x0d2e,
+ 0x83ea, 0x22b7,
+ 0x83eb, 0x229e,
+ 0x83ec, 0x22bb,
+ 0x83ed, 0x3d2c,
+ 0x83ee, 0x22bc,
+ 0x83ef, 0x0d36,
+ 0x83f0, 0x0d3b,
+ 0x83f1, 0x0d37,
+ 0x83f2, 0x0d3f,
+ 0x83f3, 0x22b2,
+ 0x83f4, 0x0d38,
+ 0x83f5, 0x22aa,
+ 0x83f6, 0x229a,
+ 0x83f8, 0x0d30,
+ 0x83f9, 0x2292,
+ 0x83fa, 0x22b4,
+ 0x83fb, 0x22be,
+ 0x83fc, 0x2299,
+ 0x83fd, 0x0d3e,
+ 0x83fe, 0x22c3,
+ 0x83ff, 0x22a5,
+ 0x8401, 0x22a1,
+ 0x8403, 0x0d2f,
+ 0x8404, 0x0d43,
+ 0x8405, 0x475f,
+ 0x8406, 0x22b0,
+ 0x8407, 0x0d45,
+ 0x8409, 0x22ac,
+ 0x840a, 0x0d3a,
+ 0x840b, 0x0d34,
+ 0x840c, 0x0d3c,
+ 0x840d, 0x0d31,
+ 0x840e, 0x0d42,
+ 0x840f, 0x22ad,
+ 0x8410, 0x229b,
+ 0x8411, 0x22af,
+ 0x8412, 0x2296,
+ 0x8413, 0x22b8,
+ 0x8414, 0x3c10,
+ 0x8416, 0x4037,
+ 0x8418, 0x3e7a,
+ 0x841b, 0x22c1,
+ 0x841c, 0x3eb3,
+ 0x8420, 0x3c55,
+ 0x8421, 0x3751,
+ 0x8423, 0x2293,
+ 0x8424, 0x4951,
+ 0x8426, 0x46d8,
+ 0x8429, 0x254d,
+ 0x842b, 0x2563,
+ 0x842c, 0x0eac,
+ 0x842d, 0x2552,
+ 0x842e, 0x422d,
+ 0x842f, 0x2550,
+ 0x8430, 0x253b,
+ 0x8431, 0x0ede,
+ 0x8432, 0x254b,
+ 0x8433, 0x255f,
+ 0x8434, 0x2547,
+ 0x8435, 0x0ee6,
+ 0x8436, 0x255e,
+ 0x8437, 0x2545,
+ 0x8438, 0x0d41,
+ 0x8439, 0x2555,
+ 0x843a, 0x2546,
+ 0x843b, 0x255c,
+ 0x843c, 0x0ee5,
+ 0x843d, 0x0edd,
+ 0x843e, 0x3d21,
+ 0x843f, 0x2530,
+ 0x8440, 0x2538,
+ 0x8442, 0x2551,
+ 0x8443, 0x2549,
+ 0x8444, 0x2562,
+ 0x8445, 0x254c,
+ 0x8446, 0x0eeb,
+ 0x8447, 0x255d,
+ 0x8448, 0x4718,
+ 0x8449, 0x0ee2,
+ 0x844a, 0x37e4,
+ 0x844b, 0x254f,
+ 0x844c, 0x2557,
+ 0x844d, 0x253c,
+ 0x844e, 0x2556,
+ 0x8450, 0x2567,
+ 0x8451, 0x2537,
+ 0x8452, 0x2558,
+ 0x8453, 0x3b7d,
+ 0x8454, 0x2565,
+ 0x8455, 0x398b,
+ 0x8456, 0x2531,
+ 0x8457, 0x0d39,
+ 0x8458, 0x37de,
+ 0x8459, 0x253f,
+ 0x845a, 0x253e,
+ 0x845b, 0x0ee4,
+ 0x845c, 0x3edb,
+ 0x845d, 0x2542,
+ 0x845e, 0x2544,
+ 0x845f, 0x2553,
+ 0x8460, 0x2564,
+ 0x8461, 0x0ee7,
+ 0x8462, 0x42da,
+ 0x8463, 0x0ee8,
+ 0x8464, 0x4761,
+ 0x8465, 0x2536,
+ 0x8466, 0x0ee0,
+ 0x8467, 0x253a,
+ 0x8468, 0x2560,
+ 0x8469, 0x0ee9,
+ 0x846b, 0x0ee1,
+ 0x846c, 0x0ee3,
+ 0x846d, 0x0eea,
+ 0x846e, 0x2566,
+ 0x846f, 0x2559,
+ 0x8470, 0x2554,
+ 0x8471, 0x37e0,
+ 0x8472, 0x3c93,
+ 0x8473, 0x2541,
+ 0x8474, 0x2540,
+ 0x8475, 0x0edf,
+ 0x8476, 0x2532,
+ 0x8477, 0x0edc,
+ 0x8478, 0x254a,
+ 0x8479, 0x2533,
+ 0x847a, 0x2548,
+ 0x847d, 0x253d,
+ 0x847e, 0x2561,
+ 0x847f, 0x394e,
+ 0x8480, 0x3b6e,
+ 0x8482, 0x0edb,
+ 0x8486, 0x2539,
+ 0x8488, 0x4762,
+ 0x848d, 0x2535,
+ 0x848e, 0x255b,
+ 0x848f, 0x2534,
+ 0x8490, 0x108e,
+ 0x8491, 0x27cd,
+ 0x8492, 0x3756,
+ 0x8493, 0x37ee,
+ 0x8494, 0x27bc,
+ 0x8496, 0x3b1d,
+ 0x8497, 0x27a6,
+ 0x8498, 0x27c4,
+ 0x8499, 0x1086,
+ 0x849a, 0x27b5,
+ 0x849b, 0x27bf,
+ 0x849c, 0x1089,
+ 0x849d, 0x27b8,
+ 0x849e, 0x1087,
+ 0x849f, 0x27a9,
+ 0x84a0, 0x27c7,
+ 0x84a1, 0x27a8,
+ 0x84a2, 0x27bb,
+ 0x84a3, 0x3b9e,
+ 0x84a4, 0x27a7,
+ 0x84a7, 0x27b9,
+ 0x84a8, 0x27c2,
+ 0x84a9, 0x27c0,
+ 0x84aa, 0x27b4,
+ 0x84ab, 0x27af,
+ 0x84ac, 0x27ad,
+ 0x84ad, 0x3d8c,
+ 0x84ae, 0x27ae,
+ 0x84af, 0x27c1,
+ 0x84b0, 0x27cc,
+ 0x84b1, 0x27b6,
+ 0x84b2, 0x1088,
+ 0x84b4, 0x27b1,
+ 0x84b6, 0x27c5,
+ 0x84b8, 0x108b,
+ 0x84b9, 0x27b0,
+ 0x84ba, 0x27aa,
+ 0x84bb, 0x27ba,
+ 0x84bc, 0x108f,
+ 0x84bd, 0x3c4c,
+ 0x84be, 0x4764,
+ 0x84bf, 0x1083,
+ 0x84c0, 0x108c,
+ 0x84c1, 0x27b2,
+ 0x84c2, 0x27ac,
+ 0x84c4, 0x1085,
+ 0x84c5, 0x255a,
+ 0x84c6, 0x1084,
+ 0x84c7, 0x27bd,
+ 0x84c9, 0x1082,
+ 0x84ca, 0x1091,
+ 0x84cb, 0x108a,
+ 0x84cc, 0x27be,
+ 0x84cd, 0x27b3,
+ 0x84ce, 0x27ab,
+ 0x84cf, 0x27c6,
+ 0x84d0, 0x27b7,
+ 0x84d1, 0x1090,
+ 0x84d2, 0x27ca,
+ 0x84d3, 0x108d,
+ 0x84d4, 0x27c9,
+ 0x84d6, 0x27c3,
+ 0x84d7, 0x27c8,
+ 0x84da, 0x3ff5,
+ 0x84db, 0x27cb,
+ 0x84de, 0x37ea,
+ 0x84e1, 0x4765,
+ 0x84e2, 0x37b5,
+ 0x84e4, 0x37ef,
+ 0x84e5, 0x3bd0,
+ 0x84e7, 0x2a03,
+ 0x84e9, 0x29f7,
+ 0x84ea, 0x29f6,
+ 0x84eb, 0x29f2,
+ 0x84ec, 0x11fb,
+ 0x84ee, 0x11f3,
+ 0x84ef, 0x2a06,
+ 0x84f0, 0x2a05,
+ 0x84f1, 0x252f,
+ 0x84f2, 0x29ef,
+ 0x84f3, 0x29f3,
+ 0x84f4, 0x29ed,
+ 0x84f6, 0x2a00,
+ 0x84f7, 0x29f1,
+ 0x84f8, 0x4766,
+ 0x84f9, 0x2a07,
+ 0x84fa, 0x29ea,
+ 0x84fb, 0x29e8,
+ 0x84fc, 0x29f4,
+ 0x84fd, 0x29fe,
+ 0x84fe, 0x29f9,
+ 0x84ff, 0x11fd,
+ 0x8500, 0x29df,
+ 0x8502, 0x29fd,
+ 0x8503, 0x398a,
+ 0x8505, 0x40eb,
+ 0x8506, 0x11fe,
+ 0x8507, 0x2543,
+ 0x8508, 0x29eb,
+ 0x8509, 0x29e2,
+ 0x850a, 0x29e5,
+ 0x850b, 0x2a0b,
+ 0x850c, 0x29ec,
+ 0x850d, 0x29e3,
+ 0x850e, 0x29e1,
+ 0x850f, 0x29de,
+ 0x8510, 0x4767,
+ 0x8511, 0x11f7,
+ 0x8512, 0x29f5,
+ 0x8513, 0x11f6,
+ 0x8514, 0x11fa,
+ 0x8515, 0x29f0,
+ 0x8516, 0x29f8,
+ 0x8517, 0x11f0,
+ 0x8518, 0x2a08,
+ 0x8519, 0x2a0c,
+ 0x851a, 0x11f2,
+ 0x851c, 0x29e7,
+ 0x851d, 0x29fb,
+ 0x851e, 0x29ff,
+ 0x851f, 0x29e4,
+ 0x8520, 0x2a09,
+ 0x8521, 0x11f9,
+ 0x8523, 0x11f8,
+ 0x8524, 0x29dc,
+ 0x8525, 0x11fc,
+ 0x8526, 0x2a02,
+ 0x8527, 0x29e6,
+ 0x8528, 0x29fa,
+ 0x8529, 0x29e0,
+ 0x852a, 0x29ee,
+ 0x852b, 0x29e9,
+ 0x852c, 0x11f4,
+ 0x852e, 0x29fc,
+ 0x852f, 0x2a0d,
+ 0x8530, 0x2a0a,
+ 0x8531, 0x2a01,
+ 0x8533, 0x4228,
+ 0x8534, 0x37f4,
+ 0x8538, 0x4768,
+ 0x853b, 0x29dd,
+ 0x853d, 0x11f1,
+ 0x853e, 0x2c4f,
+ 0x8540, 0x2c46,
+ 0x8541, 0x2c49,
+ 0x8542, 0x4062,
+ 0x8543, 0x133b,
+ 0x8544, 0x2c4b,
+ 0x8545, 0x2c40,
+ 0x8546, 0x2c47,
+ 0x8547, 0x2c4d,
+ 0x8548, 0x1338,
+ 0x8549, 0x133c,
+ 0x854a, 0x1336,
+ 0x854b, 0x37c0,
+ 0x854c, 0x400f,
+ 0x854d, 0x2c42,
+ 0x854e, 0x2c52,
+ 0x8551, 0x2c4c,
+ 0x8552, 0x4769,
+ 0x8553, 0x2c43,
+ 0x8554, 0x2c5b,
+ 0x8555, 0x2c55,
+ 0x8556, 0x2c3f,
+ 0x8557, 0x2e23,
+ 0x8558, 0x2c45,
+ 0x8559, 0x1337,
+ 0x855a, 0x37db,
+ 0x855b, 0x2c50,
+ 0x855d, 0x2c5a,
+ 0x855e, 0x133f,
+ 0x8560, 0x2c57,
+ 0x8561, 0x2c44,
+ 0x8562, 0x2c4a,
+ 0x8563, 0x2c4e,
+ 0x8564, 0x2c48,
+ 0x8565, 0x2c5c,
+ 0x8566, 0x2c59,
+ 0x8567, 0x2c56,
+ 0x8568, 0x1339,
+ 0x856a, 0x133e,
+ 0x856b, 0x2c41,
+ 0x856c, 0x2c5d,
+ 0x856d, 0x133d,
+ 0x856e, 0x2c53,
+ 0x856f, 0x476b,
+ 0x8571, 0x2c51,
+ 0x8573, 0x37f8,
+ 0x8575, 0x2c54,
+ 0x8576, 0x2e30,
+ 0x8577, 0x2e1d,
+ 0x8578, 0x2e22,
+ 0x8579, 0x2e2f,
+ 0x857a, 0x2e21,
+ 0x857b, 0x2e19,
+ 0x857c, 0x2e1e,
+ 0x857e, 0x145c,
+ 0x8580, 0x2e12,
+ 0x8581, 0x2e2a,
+ 0x8582, 0x2e2c,
+ 0x8583, 0x2e11,
+ 0x8584, 0x145b,
+ 0x8585, 0x2e2e,
+ 0x8586, 0x2e26,
+ 0x8587, 0x1462,
+ 0x8588, 0x2e2d,
+ 0x8589, 0x2e1f,
+ 0x858a, 0x1464,
+ 0x858b, 0x2e17,
+ 0x858c, 0x2c58,
+ 0x858d, 0x2e27,
+ 0x858e, 0x2e24,
+ 0x858f, 0x2e13,
+ 0x8590, 0x2e32,
+ 0x8591, 0x145e,
+ 0x8594, 0x145f,
+ 0x8595, 0x2e15,
+ 0x8596, 0x2e25,
+ 0x8598, 0x2e31,
+ 0x8599, 0x2e28,
+ 0x859a, 0x2e1b,
+ 0x859b, 0x1461,
+ 0x859c, 0x145d,
+ 0x859d, 0x2e29,
+ 0x859e, 0x2e1c,
+ 0x859f, 0x2e33,
+ 0x85a0, 0x2e16,
+ 0x85a1, 0x2e20,
+ 0x85a2, 0x2e2b,
+ 0x85a3, 0x2e18,
+ 0x85a4, 0x2e1a,
+ 0x85a6, 0x1465,
+ 0x85a7, 0x2e14,
+ 0x85a8, 0x1463,
+ 0x85a9, 0x151c,
+ 0x85aa, 0x145a,
+ 0x85af, 0x1460,
+ 0x85b0, 0x1520,
+ 0x85b1, 0x2fa6,
+ 0x85b3, 0x2f9c,
+ 0x85b4, 0x2f97,
+ 0x85b5, 0x2f9d,
+ 0x85b6, 0x2fa7,
+ 0x85b7, 0x2fab,
+ 0x85b8, 0x2faa,
+ 0x85b9, 0x1522,
+ 0x85ba, 0x1521,
+ 0x85bd, 0x2f9e,
+ 0x85be, 0x2fac,
+ 0x85bf, 0x2fa1,
+ 0x85c0, 0x2f99,
+ 0x85c1, 0x37fe,
+ 0x85c2, 0x2f9b,
+ 0x85c3, 0x2f9a,
+ 0x85c4, 0x2fa0,
+ 0x85c5, 0x2fa5,
+ 0x85c6, 0x2f98,
+ 0x85c7, 0x2f9f,
+ 0x85c8, 0x2fa4,
+ 0x85c9, 0x151f,
+ 0x85cb, 0x2fa2,
+ 0x85cd, 0x151d,
+ 0x85ce, 0x2fa3,
+ 0x85cf, 0x151b,
+ 0x85d0, 0x151e,
+ 0x85d1, 0x3101,
+ 0x85d2, 0x2fa8,
+ 0x85d5, 0x15b7,
+ 0x85d7, 0x30f9,
+ 0x85d8, 0x30fd,
+ 0x85d9, 0x30f5,
+ 0x85da, 0x30f8,
+ 0x85dc, 0x3100,
+ 0x85dd, 0x15b5,
+ 0x85de, 0x3105,
+ 0x85df, 0x30fe,
+ 0x85e0, 0x476d,
+ 0x85e1, 0x30f6,
+ 0x85e2, 0x3106,
+ 0x85e3, 0x30ff,
+ 0x85e4, 0x15b8,
+ 0x85e6, 0x3103,
+ 0x85e8, 0x30f7,
+ 0x85e9, 0x15b4,
+ 0x85ea, 0x15b6,
+ 0x85eb, 0x30f2,
+ 0x85ec, 0x30fa,
+ 0x85ed, 0x30f4,
+ 0x85ee, 0x3c56,
+ 0x85ef, 0x3104,
+ 0x85f0, 0x3102,
+ 0x85f1, 0x30f3,
+ 0x85f2, 0x30fb,
+ 0x85f6, 0x3225,
+ 0x85f7, 0x15ba,
+ 0x85f8, 0x30fc,
+ 0x85f9, 0x1638,
+ 0x85fa, 0x163a,
+ 0x85fb, 0x1637,
+ 0x85fc, 0x3c50,
+ 0x85fd, 0x322a,
+ 0x85fe, 0x3222,
+ 0x85ff, 0x3220,
+ 0x8600, 0x3224,
+ 0x8601, 0x3221,
+ 0x8602, 0x3800,
+ 0x8604, 0x3226,
+ 0x8605, 0x3228,
+ 0x8606, 0x163b,
+ 0x8607, 0x163d,
+ 0x8609, 0x3227,
+ 0x860a, 0x163e,
+ 0x860b, 0x163c,
+ 0x860c, 0x3229,
+ 0x860d, 0x4064,
+ 0x8610, 0x3b7f,
+ 0x8611, 0x1639,
+ 0x8614, 0x46be,
+ 0x8616, 0x37fb,
+ 0x8617, 0x1685,
+ 0x8618, 0x32f6,
+ 0x8619, 0x32fc,
+ 0x861a, 0x1687,
+ 0x861b, 0x3223,
+ 0x861c, 0x32fb,
+ 0x861e, 0x3302,
+ 0x861f, 0x32f9,
+ 0x8620, 0x3300,
+ 0x8621, 0x32ff,
+ 0x8622, 0x321f,
+ 0x8623, 0x32fa,
+ 0x8624, 0x2fa9,
+ 0x8625, 0x3303,
+ 0x8626, 0x32f8,
+ 0x8627, 0x32fd,
+ 0x8628, 0x3805,
+ 0x8629, 0x3301,
+ 0x862a, 0x32f7,
+ 0x862c, 0x33aa,
+ 0x862d, 0x1686,
+ 0x862e, 0x32fe,
+ 0x862f, 0x3f9e,
+ 0x8631, 0x3432,
+ 0x8632, 0x33ab,
+ 0x8633, 0x33a9,
+ 0x8634, 0x33a7,
+ 0x8636, 0x33ac,
+ 0x8638, 0x1707,
+ 0x8639, 0x3430,
+ 0x863a, 0x342e,
+ 0x863b, 0x3433,
+ 0x863c, 0x3431,
+ 0x863e, 0x3434,
+ 0x863f, 0x1708,
+ 0x8640, 0x342f,
+ 0x8642, 0x38c1,
+ 0x8643, 0x3497,
+ 0x8645, 0x3b66,
+ 0x8646, 0x34df,
+ 0x864b, 0x353e,
+ 0x864c, 0x3536,
+ 0x864d, 0x1818,
+ 0x864e, 0x0689,
+ 0x8650, 0x07ff,
+ 0x8652, 0x1de3,
+ 0x8653, 0x1de2,
+ 0x8654, 0x09af,
+ 0x8655, 0x0b88,
+ 0x8656, 0x203c,
+ 0x8659, 0x203b,
+ 0x865b, 0x0d48,
+ 0x865c, 0x0eed,
+ 0x865e, 0x0eec,
+ 0x865f, 0x0eee,
+ 0x8661, 0x27ce,
+ 0x8662, 0x2a0e,
+ 0x8663, 0x2c5e,
+ 0x8664, 0x2c60,
+ 0x8665, 0x2c5f,
+ 0x8667, 0x1466,
+ 0x8668, 0x2e34,
+ 0x8669, 0x2fad,
+ 0x866a, 0x351e,
+ 0x866b, 0x040f,
+ 0x866c, 0x3813,
+ 0x866d, 0x1a46,
+ 0x866f, 0x1a45,
+ 0x8670, 0x1a44,
+ 0x8671, 0x068a,
+ 0x8672, 0x476f,
+ 0x8673, 0x1bfd,
+ 0x8674, 0x1bfb,
+ 0x8677, 0x1bfa,
+ 0x8679, 0x0800,
+ 0x867a, 0x0802,
+ 0x867b, 0x0801,
+ 0x867c, 0x1bfc,
+ 0x867e, 0x380a,
+ 0x8685, 0x1def,
+ 0x8686, 0x1dec,
+ 0x8687, 0x1dea,
+ 0x868a, 0x09b0,
+ 0x868b, 0x1ded,
+ 0x868c, 0x09b5,
+ 0x868d, 0x1de7,
+ 0x868e, 0x1df6,
+ 0x8690, 0x1df8,
+ 0x8691, 0x1de8,
+ 0x8692, 0x4770,
+ 0x8693, 0x09b2,
+ 0x8694, 0x1df9,
+ 0x8695, 0x1df4,
+ 0x8696, 0x1de6,
+ 0x8697, 0x1deb,
+ 0x8698, 0x1df5,
+ 0x8699, 0x1df1,
+ 0x869a, 0x1dee,
+ 0x869c, 0x09b7,
+ 0x869d, 0x1df7,
+ 0x869e, 0x1de9,
+ 0x86a0, 0x3b88,
+ 0x86a1, 0x1df2,
+ 0x86a2, 0x1de4,
+ 0x86a3, 0x09b6,
+ 0x86a4, 0x09b3,
+ 0x86a5, 0x1df0,
+ 0x86a7, 0x1df3,
+ 0x86a8, 0x1de5,
+ 0x86a9, 0x09b4,
+ 0x86aa, 0x09b1,
+ 0x86ad, 0x3f06,
+ 0x86af, 0x0b92,
+ 0x86b0, 0x2043,
+ 0x86b1, 0x0b91,
+ 0x86b2, 0x43e0,
+ 0x86b3, 0x2046,
+ 0x86b4, 0x2049,
+ 0x86b5, 0x0b8e,
+ 0x86b6, 0x0b8c,
+ 0x86b7, 0x203e,
+ 0x86b8, 0x2047,
+ 0x86b9, 0x2045,
+ 0x86ba, 0x2042,
+ 0x86bb, 0x204a,
+ 0x86bd, 0x204d,
+ 0x86bf, 0x203d,
+ 0x86c0, 0x0b8b,
+ 0x86c1, 0x2040,
+ 0x86c2, 0x203f,
+ 0x86c3, 0x204c,
+ 0x86c4, 0x0b8d,
+ 0x86c5, 0x2041,
+ 0x86c6, 0x0b8f,
+ 0x86c7, 0x0b8a,
+ 0x86c8, 0x2044,
+ 0x86c9, 0x0b93,
+ 0x86cb, 0x0b90,
+ 0x86cc, 0x2048,
+ 0x86d0, 0x0d4f,
+ 0x86d1, 0x22d2,
+ 0x86d3, 0x22c7,
+ 0x86d4, 0x0d4c,
+ 0x86d6, 0x256d,
+ 0x86d7, 0x22d0,
+ 0x86d8, 0x22c4,
+ 0x86d9, 0x0d4a,
+ 0x86da, 0x22c9,
+ 0x86db, 0x0d4d,
+ 0x86dc, 0x22cd,
+ 0x86dd, 0x22cb,
+ 0x86de, 0x0d50,
+ 0x86df, 0x0d49,
+ 0x86e2, 0x22c5,
+ 0x86e3, 0x22c8,
+ 0x86e4, 0x0d4e,
+ 0x86e6, 0x22c6,
+ 0x86e8, 0x22d1,
+ 0x86e9, 0x22cf,
+ 0x86ea, 0x22ca,
+ 0x86eb, 0x22cc,
+ 0x86ec, 0x22ce,
+ 0x86ed, 0x0d4b,
+ 0x86ef, 0x4771,
+ 0x86f5, 0x256e,
+ 0x86f6, 0x2574,
+ 0x86f7, 0x256a,
+ 0x86f8, 0x2570,
+ 0x86f9, 0x0eef,
+ 0x86fa, 0x256c,
+ 0x86fb, 0x0ef5,
+ 0x86fe, 0x0ef4,
+ 0x8700, 0x0ef3,
+ 0x8701, 0x2573,
+ 0x8702, 0x0ef6,
+ 0x8704, 0x2569,
+ 0x8705, 0x2576,
+ 0x8706, 0x0ef8,
+ 0x8707, 0x0ef2,
+ 0x8708, 0x0ef1,
+ 0x8709, 0x2572,
+ 0x870a, 0x0ef9,
+ 0x870b, 0x2568,
+ 0x870c, 0x256b,
+ 0x870d, 0x2575,
+ 0x870e, 0x2571,
+ 0x8711, 0x27ee,
+ 0x8712, 0x27e3,
+ 0x8713, 0x0ef0,
+ 0x8718, 0x1098,
+ 0x8719, 0x27d7,
+ 0x871a, 0x27ec,
+ 0x871b, 0x27d8,
+ 0x871c, 0x1093,
+ 0x871e, 0x27d5,
+ 0x8720, 0x27de,
+ 0x8721, 0x27d6,
+ 0x8722, 0x1095,
+ 0x8723, 0x27d0,
+ 0x8724, 0x27eb,
+ 0x8725, 0x1096,
+ 0x8726, 0x27e8,
+ 0x8728, 0x27d1,
+ 0x8729, 0x109b,
+ 0x872a, 0x27e0,
+ 0x872c, 0x27da,
+ 0x872d, 0x27e1,
+ 0x872e, 0x27d4,
+ 0x8730, 0x27ed,
+ 0x8731, 0x27e5,
+ 0x8732, 0x27df,
+ 0x8733, 0x27cf,
+ 0x8734, 0x1097,
+ 0x8735, 0x27e6,
+ 0x8737, 0x109a,
+ 0x8738, 0x27ea,
+ 0x873a, 0x27e4,
+ 0x873b, 0x1094,
+ 0x873c, 0x27e2,
+ 0x873e, 0x27dc,
+ 0x873f, 0x1092,
+ 0x8740, 0x27d3,
+ 0x8741, 0x27db,
+ 0x8742, 0x27e7,
+ 0x8743, 0x27d9,
+ 0x8746, 0x27dd,
+ 0x874c, 0x1208,
+ 0x874d, 0x256f,
+ 0x874e, 0x2a20,
+ 0x874f, 0x2a29,
+ 0x8750, 0x2a1f,
+ 0x8751, 0x2a1b,
+ 0x8752, 0x2a18,
+ 0x8753, 0x1209,
+ 0x8754, 0x2a16,
+ 0x8755, 0x1099,
+ 0x8756, 0x2a0f,
+ 0x8757, 0x1207,
+ 0x8758, 0x2a15,
+ 0x8759, 0x1206,
+ 0x875a, 0x2a1a,
+ 0x875b, 0x2a17,
+ 0x875c, 0x2a27,
+ 0x875d, 0x2a22,
+ 0x875e, 0x2a1c,
+ 0x875f, 0x2a21,
+ 0x8760, 0x1202,
+ 0x8761, 0x2a19,
+ 0x8762, 0x2a2c,
+ 0x8763, 0x2a10,
+ 0x8765, 0x2a28,
+ 0x8766, 0x1203,
+ 0x8767, 0x2a2d,
+ 0x8768, 0x1205,
+ 0x8769, 0x2a2e,
+ 0x876a, 0x2a1e,
+ 0x876b, 0x27d2,
+ 0x876c, 0x2a24,
+ 0x876d, 0x2a1d,
+ 0x876e, 0x2a26,
+ 0x876f, 0x2a23,
+ 0x8770, 0x3e6c,
+ 0x8771, 0x380b,
+ 0x8773, 0x2a14,
+ 0x8774, 0x1200,
+ 0x8775, 0x2a2b,
+ 0x8776, 0x1201,
+ 0x8777, 0x2a12,
+ 0x8778, 0x1204,
+ 0x8779, 0x2c6b,
+ 0x877a, 0x2a25,
+ 0x877b, 0x2a2a,
+ 0x877d, 0x4045,
+ 0x8781, 0x2c68,
+ 0x8782, 0x11ff,
+ 0x8783, 0x1340,
+ 0x8784, 0x2c72,
+ 0x8785, 0x2c6e,
+ 0x8786, 0x3eb0,
+ 0x8787, 0x2c6c,
+ 0x8788, 0x2c67,
+ 0x8789, 0x2c76,
+ 0x878b, 0x43e2,
+ 0x878c, 0x3fef,
+ 0x878d, 0x1344,
+ 0x878f, 0x2c63,
+ 0x8790, 0x2c6f,
+ 0x8792, 0x2c66,
+ 0x8793, 0x2c65,
+ 0x8794, 0x2c73,
+ 0x8796, 0x2c69,
+ 0x8797, 0x2c64,
+ 0x8798, 0x2c6a,
+ 0x879a, 0x2c75,
+ 0x879b, 0x2c62,
+ 0x879c, 0x2c74,
+ 0x879d, 0x2c71,
+ 0x879e, 0x1342,
+ 0x879f, 0x1341,
+ 0x87a2, 0x1343,
+ 0x87a3, 0x2c6d,
+ 0x87a4, 0x2c61,
+ 0x87a5, 0x3d88,
+ 0x87a9, 0x3fec,
+ 0x87aa, 0x2e36,
+ 0x87ab, 0x146c,
+ 0x87ac, 0x2e3a,
+ 0x87ad, 0x2e37,
+ 0x87ae, 0x2e3e,
+ 0x87af, 0x2e44,
+ 0x87b0, 0x2e39,
+ 0x87b1, 0x380f,
+ 0x87b2, 0x2e4d,
+ 0x87b3, 0x1469,
+ 0x87b4, 0x2e47,
+ 0x87b5, 0x2e3c,
+ 0x87b6, 0x2e48,
+ 0x87b7, 0x2e43,
+ 0x87b8, 0x2e4a,
+ 0x87b9, 0x2e3b,
+ 0x87ba, 0x146e,
+ 0x87bb, 0x146d,
+ 0x87bc, 0x2e3d,
+ 0x87bd, 0x2e4b,
+ 0x87be, 0x2e35,
+ 0x87bf, 0x2e49,
+ 0x87c0, 0x1467,
+ 0x87c1, 0x3ffc,
+ 0x87c2, 0x2e41,
+ 0x87c3, 0x2e40,
+ 0x87c4, 0x2e45,
+ 0x87c5, 0x2e38,
+ 0x87c6, 0x146b,
+ 0x87c8, 0x146f,
+ 0x87c9, 0x2e3f,
+ 0x87ca, 0x2e46,
+ 0x87cb, 0x1470,
+ 0x87cc, 0x2e42,
+ 0x87ce, 0x3fed,
+ 0x87d1, 0x1468,
+ 0x87d2, 0x146a,
+ 0x87d3, 0x2fba,
+ 0x87d4, 0x2fb8,
+ 0x87d6, 0x3f92,
+ 0x87d7, 0x2fbe,
+ 0x87d8, 0x2fbc,
+ 0x87d9, 0x2fbf,
+ 0x87da, 0x3810,
+ 0x87db, 0x2fb1,
+ 0x87dc, 0x2fb9,
+ 0x87dd, 0x2fc3,
+ 0x87de, 0x2e4c,
+ 0x87df, 0x2fb5,
+ 0x87e0, 0x1526,
+ 0x87e1, 0x2a13,
+ 0x87e2, 0x2fb0,
+ 0x87e3, 0x2fbd,
+ 0x87e4, 0x2fb7,
+ 0x87e5, 0x2fb4,
+ 0x87e6, 0x2faf,
+ 0x87e7, 0x2fae,
+ 0x87e8, 0x2fc2,
+ 0x87ea, 0x2fb3,
+ 0x87eb, 0x2fb2,
+ 0x87ec, 0x1524,
+ 0x87ed, 0x2fbb,
+ 0x87ee, 0x380d,
+ 0x87ef, 0x1523,
+ 0x87f2, 0x1525,
+ 0x87f3, 0x2fb6,
+ 0x87f4, 0x2fc1,
+ 0x87f5, 0x3fae,
+ 0x87f6, 0x310a,
+ 0x87f9, 0x15be,
+ 0x87fa, 0x3108,
+ 0x87fb, 0x15bb,
+ 0x87fc, 0x3110,
+ 0x87fe, 0x15bf,
+ 0x87ff, 0x3112,
+ 0x8800, 0x3107,
+ 0x8801, 0x2fc0,
+ 0x8802, 0x3114,
+ 0x8803, 0x3109,
+ 0x8804, 0x3eaf,
+ 0x8805, 0x15bc,
+ 0x8806, 0x310f,
+ 0x8808, 0x3111,
+ 0x8809, 0x310c,
+ 0x880a, 0x3113,
+ 0x880b, 0x310e,
+ 0x880c, 0x310d,
+ 0x880d, 0x15bd,
+ 0x880f, 0x3811,
+ 0x8810, 0x322c,
+ 0x8813, 0x322f,
+ 0x8814, 0x163f,
+ 0x8816, 0x3230,
+ 0x8817, 0x322e,
+ 0x8818, 0x3f7a,
+ 0x8819, 0x322b,
+ 0x881b, 0x3306,
+ 0x881c, 0x3309,
+ 0x881d, 0x3305,
+ 0x881f, 0x168b,
+ 0x8820, 0x3307,
+ 0x8821, 0x168a,
+ 0x8822, 0x1689,
+ 0x8823, 0x1688,
+ 0x8824, 0x3308,
+ 0x8825, 0x33b1,
+ 0x8826, 0x33af,
+ 0x8827, 0x3e07,
+ 0x8828, 0x33ae,
+ 0x8829, 0x3304,
+ 0x882a, 0x33b0,
+ 0x882b, 0x330a,
+ 0x882c, 0x33ad,
+ 0x882d, 0x3b8b,
+ 0x882e, 0x3437,
+ 0x882f, 0x3415,
+ 0x8830, 0x3435,
+ 0x8831, 0x1709,
+ 0x8832, 0x3436,
+ 0x8833, 0x3438,
+ 0x8835, 0x349a,
+ 0x8836, 0x1728,
+ 0x8837, 0x3499,
+ 0x8838, 0x3498,
+ 0x8839, 0x1729,
+ 0x883b, 0x1747,
+ 0x883c, 0x3508,
+ 0x883d, 0x3520,
+ 0x883e, 0x351f,
+ 0x883f, 0x3521,
+ 0x8840, 0x0410,
+ 0x8841, 0x1bfe,
+ 0x8842, 0x3f5a,
+ 0x8843, 0x1dfa,
+ 0x8845, 0x3816,
+ 0x8848, 0x22d3,
+ 0x884a, 0x330b,
+ 0x884b, 0x349b,
+ 0x884c, 0x0411,
+ 0x884d, 0x0803,
+ 0x884e, 0x1bff,
+ 0x884f, 0x3844,
+ 0x8852, 0x204f,
+ 0x8853, 0x0b94,
+ 0x8855, 0x22d5,
+ 0x8856, 0x22d4,
+ 0x8857, 0x0d51,
+ 0x8859, 0x0efa,
+ 0x885a, 0x2a2f,
+ 0x885b, 0x120a,
+ 0x885d, 0x120b,
+ 0x885e, 0x381b,
+ 0x8860, 0x3a46,
+ 0x8861, 0x1345,
+ 0x8862, 0x172a,
+ 0x8863, 0x0412,
+ 0x8864, 0x4502,
+ 0x8865, 0x3dfc,
+ 0x8867, 0x1c00,
+ 0x8868, 0x068c,
+ 0x8869, 0x1c02,
+ 0x886a, 0x1c01,
+ 0x886b, 0x0804,
+ 0x886d, 0x1dfc,
+ 0x886e, 0x3b8e,
+ 0x886f, 0x1e03,
+ 0x8870, 0x09b8,
+ 0x8871, 0x1e01,
+ 0x8872, 0x1dff,
+ 0x8874, 0x1e06,
+ 0x8875, 0x1dfd,
+ 0x8877, 0x09b9,
+ 0x8879, 0x09bd,
+ 0x887c, 0x1e07,
+ 0x887d, 0x09bc,
+ 0x887e, 0x1e05,
+ 0x887f, 0x1e02,
+ 0x8880, 0x1e00,
+ 0x8881, 0x09ba,
+ 0x8883, 0x1e04,
+ 0x8884, 0x42f7,
+ 0x8887, 0x3b90,
+ 0x8888, 0x0b96,
+ 0x8889, 0x2050,
+ 0x888b, 0x0b9b,
+ 0x888c, 0x2060,
+ 0x888d, 0x0b9a,
+ 0x888e, 0x2062,
+ 0x8891, 0x2056,
+ 0x8892, 0x0b98,
+ 0x8893, 0x2061,
+ 0x8895, 0x2051,
+ 0x8896, 0x0b99,
+ 0x8897, 0x205d,
+ 0x8898, 0x2059,
+ 0x8899, 0x205b,
+ 0x889a, 0x2055,
+ 0x889b, 0x205c,
+ 0x889c, 0x381c,
+ 0x889e, 0x0b95,
+ 0x889f, 0x2058,
+ 0x88a0, 0x3fa0,
+ 0x88a1, 0x2057,
+ 0x88a2, 0x2053,
+ 0x88a4, 0x205e,
+ 0x88a7, 0x205a,
+ 0x88a8, 0x2052,
+ 0x88aa, 0x2054,
+ 0x88ab, 0x0b97,
+ 0x88ac, 0x205f,
+ 0x88ae, 0x4775,
+ 0x88b1, 0x0d54,
+ 0x88b2, 0x22e0,
+ 0x88b4, 0x381e,
+ 0x88b6, 0x22dc,
+ 0x88b7, 0x22de,
+ 0x88b8, 0x22d9,
+ 0x88b9, 0x22d8,
+ 0x88ba, 0x22d6,
+ 0x88bc, 0x22dd,
+ 0x88bd, 0x22df,
+ 0x88be, 0x22db,
+ 0x88bf, 0x3b91,
+ 0x88c0, 0x22da,
+ 0x88c1, 0x0d52,
+ 0x88c5, 0x3820,
+ 0x88c7, 0x3eb1,
+ 0x88c9, 0x22e2,
+ 0x88ca, 0x0f02,
+ 0x88cb, 0x2578,
+ 0x88cc, 0x257e,
+ 0x88cd, 0x2579,
+ 0x88cf, 0x36ea,
+ 0x88d0, 0x257f,
+ 0x88d2, 0x0f04,
+ 0x88d4, 0x0efc,
+ 0x88d5, 0x0f03,
+ 0x88d6, 0x2577,
+ 0x88d7, 0x22d7,
+ 0x88d8, 0x0eff,
+ 0x88d9, 0x0efd,
+ 0x88da, 0x257d,
+ 0x88db, 0x257c,
+ 0x88dc, 0x0efe,
+ 0x88dd, 0x0f00,
+ 0x88de, 0x257b,
+ 0x88df, 0x0efb,
+ 0x88e1, 0x0f01,
+ 0x88e6, 0x3b92,
+ 0x88e7, 0x27f0,
+ 0x88e8, 0x10a2,
+ 0x88eb, 0x27fb,
+ 0x88ec, 0x27fa,
+ 0x88ee, 0x27f5,
+ 0x88ef, 0x10a4,
+ 0x88f0, 0x27f9,
+ 0x88f1, 0x27f1,
+ 0x88f3, 0x109c,
+ 0x88f4, 0x109e,
+ 0x88f5, 0x3e08,
+ 0x88f6, 0x27f7,
+ 0x88f7, 0x27ef,
+ 0x88f8, 0x10a0,
+ 0x88f9, 0x109f,
+ 0x88fa, 0x27f3,
+ 0x88fb, 0x27f8,
+ 0x88fc, 0x27f6,
+ 0x88fd, 0x10a1,
+ 0x88fe, 0x27f4,
+ 0x88ff, 0x4776,
+ 0x8900, 0x42fa,
+ 0x8901, 0x22e1,
+ 0x8902, 0x109d,
+ 0x8905, 0x2a30,
+ 0x8906, 0x2a37,
+ 0x8907, 0x120d,
+ 0x8909, 0x2a3b,
+ 0x890a, 0x1211,
+ 0x890b, 0x2a33,
+ 0x890c, 0x2a31,
+ 0x890e, 0x2a3a,
+ 0x8910, 0x120c,
+ 0x8911, 0x2a39,
+ 0x8912, 0x120e,
+ 0x8914, 0x2a32,
+ 0x8915, 0x1210,
+ 0x8916, 0x2a38,
+ 0x8917, 0x2a34,
+ 0x891a, 0x10a3,
+ 0x891e, 0x2c77,
+ 0x891f, 0x2c83,
+ 0x8921, 0x134a,
+ 0x8922, 0x2c7e,
+ 0x8923, 0x2c80,
+ 0x8924, 0x4777,
+ 0x8925, 0x1348,
+ 0x8926, 0x2c78,
+ 0x8927, 0x2c7c,
+ 0x8929, 0x2c7f,
+ 0x892a, 0x1346,
+ 0x892b, 0x1349,
+ 0x892c, 0x2c82,
+ 0x892d, 0x2c7a,
+ 0x892f, 0x2c81,
+ 0x8930, 0x2c79,
+ 0x8931, 0x2c7d,
+ 0x8932, 0x1347,
+ 0x8933, 0x2e4f,
+ 0x8935, 0x2e4e,
+ 0x8936, 0x1472,
+ 0x8937, 0x2e54,
+ 0x8938, 0x1474,
+ 0x893b, 0x1471,
+ 0x893c, 0x2e50,
+ 0x893d, 0x1475,
+ 0x893e, 0x2e51,
+ 0x8941, 0x2e52,
+ 0x8942, 0x2e55,
+ 0x8943, 0x3e16,
+ 0x8944, 0x1473,
+ 0x8946, 0x2fc8,
+ 0x8947, 0x43e3,
+ 0x8949, 0x2fcb,
+ 0x894b, 0x2fc5,
+ 0x894c, 0x2fc7,
+ 0x894d, 0x3b94,
+ 0x894f, 0x2fc6,
+ 0x8950, 0x2fc9,
+ 0x8952, 0x2e53,
+ 0x8953, 0x2fc4,
+ 0x8954, 0x3b96,
+ 0x8956, 0x15c2,
+ 0x8957, 0x3118,
+ 0x8958, 0x311b,
+ 0x8959, 0x311d,
+ 0x895a, 0x3116,
+ 0x895c, 0x311a,
+ 0x895d, 0x311c,
+ 0x895e, 0x15c3,
+ 0x895f, 0x15c1,
+ 0x8960, 0x15c0,
+ 0x8961, 0x3119,
+ 0x8962, 0x3115,
+ 0x8963, 0x3231,
+ 0x8964, 0x1641,
+ 0x8965, 0x3b93,
+ 0x8966, 0x3232,
+ 0x8969, 0x330d,
+ 0x896a, 0x168c,
+ 0x896b, 0x330f,
+ 0x896c, 0x168d,
+ 0x896d, 0x330c,
+ 0x896e, 0x330e,
+ 0x896f, 0x16d6,
+ 0x8971, 0x33b2,
+ 0x8972, 0x16d5,
+ 0x8973, 0x343b,
+ 0x8974, 0x343a,
+ 0x8976, 0x3439,
+ 0x8977, 0x3dea,
+ 0x8979, 0x34e2,
+ 0x897b, 0x34e5,
+ 0x897c, 0x34e4,
+ 0x897e, 0x1819,
+ 0x897f, 0x0413,
+ 0x8980, 0x4708,
+ 0x8981, 0x0805,
+ 0x8982, 0x2063,
+ 0x8983, 0x0d55,
+ 0x8985, 0x2580,
+ 0x8986, 0x1527,
+ 0x8987, 0x3822,
+ 0x8988, 0x311e,
+ 0x8989, 0x3fe9,
+ 0x898a, 0x3823,
+ 0x898b, 0x0508,
+ 0x898f, 0x0b9d,
+ 0x8991, 0x4778,
+ 0x8993, 0x0b9c,
+ 0x8994, 0x3fe0,
+ 0x8995, 0x22e3,
+ 0x8996, 0x0d56,
+ 0x8997, 0x22e5,
+ 0x8998, 0x22e4,
+ 0x899b, 0x2581,
+ 0x899c, 0x0f05,
+ 0x899d, 0x27fc,
+ 0x899e, 0x27ff,
+ 0x899f, 0x27fe,
+ 0x89a1, 0x27fd,
+ 0x89a2, 0x2a3c,
+ 0x89a3, 0x2a3e,
+ 0x89a4, 0x2a3d,
+ 0x89a5, 0x3d93,
+ 0x89a6, 0x134c,
+ 0x89a7, 0x3826,
+ 0x89a9, 0x3825,
+ 0x89aa, 0x134b,
+ 0x89ac, 0x1476,
+ 0x89ad, 0x2e56,
+ 0x89ae, 0x2e58,
+ 0x89af, 0x2e57,
+ 0x89b2, 0x1528,
+ 0x89b6, 0x3120,
+ 0x89b7, 0x311f,
+ 0x89b9, 0x3233,
+ 0x89ba, 0x1642,
+ 0x89bc, 0x3827,
+ 0x89bd, 0x168e,
+ 0x89be, 0x33b4,
+ 0x89bf, 0x33b3,
+ 0x89c0, 0x1748,
+ 0x89c1, 0x4503,
+ 0x89c6, 0x4566,
+ 0x89d2, 0x0509,
+ 0x89d3, 0x1c03,
+ 0x89d4, 0x0806,
+ 0x89d5, 0x2066,
+ 0x89d6, 0x2064,
+ 0x89d9, 0x2065,
+ 0x89da, 0x22e7,
+ 0x89dc, 0x2588,
+ 0x89dd, 0x22e6,
+ 0x89df, 0x2582,
+ 0x89e0, 0x2586,
+ 0x89e1, 0x2585,
+ 0x89e2, 0x2587,
+ 0x89e3, 0x0f06,
+ 0x89e4, 0x2584,
+ 0x89e5, 0x2583,
+ 0x89e6, 0x2589,
+ 0x89e7, 0x3829,
+ 0x89e8, 0x2802,
+ 0x89e9, 0x2800,
+ 0x89eb, 0x2801,
+ 0x89ec, 0x2a41,
+ 0x89ed, 0x2a3f,
+ 0x89f0, 0x2a40,
+ 0x89f1, 0x2c84,
+ 0x89f2, 0x2e59,
+ 0x89f4, 0x1529,
+ 0x89f6, 0x3121,
+ 0x89f7, 0x3234,
+ 0x89f8, 0x1643,
+ 0x89fa, 0x3310,
+ 0x89fb, 0x33b5,
+ 0x89fc, 0x16d7,
+ 0x89fe, 0x343c,
+ 0x89ff, 0x34e6,
+ 0x8a00, 0x050a,
+ 0x8a02, 0x0808,
+ 0x8a04, 0x1c04,
+ 0x8a07, 0x1c05,
+ 0x8a08, 0x0807,
+ 0x8a0a, 0x09c3,
+ 0x8a0c, 0x09c1,
+ 0x8a0e, 0x09c0,
+ 0x8a0f, 0x09c7,
+ 0x8a10, 0x09bf,
+ 0x8a11, 0x09c8,
+ 0x8a12, 0x1e08,
+ 0x8a13, 0x09c5,
+ 0x8a15, 0x09c2,
+ 0x8a16, 0x09c6,
+ 0x8a17, 0x09c4,
+ 0x8a18, 0x09be,
+ 0x8a1b, 0x0ba5,
+ 0x8a1c, 0x3ba3,
+ 0x8a1d, 0x0b9f,
+ 0x8a1e, 0x206a,
+ 0x8a1f, 0x0ba4,
+ 0x8a22, 0x0ba6,
+ 0x8a23, 0x0ba0,
+ 0x8a25, 0x0ba1,
+ 0x8a27, 0x2068,
+ 0x8a29, 0x43e5,
+ 0x8a2a, 0x0b9e,
+ 0x8a2b, 0x3bd1,
+ 0x8a2c, 0x2069,
+ 0x8a2d, 0x0ba3,
+ 0x8a30, 0x2067,
+ 0x8a31, 0x0ba2,
+ 0x8a34, 0x0d61,
+ 0x8a36, 0x0d63,
+ 0x8a38, 0x477a,
+ 0x8a39, 0x22eb,
+ 0x8a3a, 0x0d62,
+ 0x8a3b, 0x0d57,
+ 0x8a3c, 0x0d5b,
+ 0x8a3d, 0x3ba2,
+ 0x8a3e, 0x0f19,
+ 0x8a3f, 0x258e,
+ 0x8a40, 0x22ed,
+ 0x8a41, 0x0d5c,
+ 0x8a44, 0x22f0,
+ 0x8a46, 0x0d60,
+ 0x8a48, 0x22f3,
+ 0x8a49, 0x3ff0,
+ 0x8a4a, 0x22f5,
+ 0x8a4c, 0x22f6,
+ 0x8a4d, 0x22ea,
+ 0x8a4e, 0x22e9,
+ 0x8a4f, 0x22f7,
+ 0x8a50, 0x0d5f,
+ 0x8a51, 0x22f4,
+ 0x8a52, 0x22f2,
+ 0x8a54, 0x0d5d,
+ 0x8a55, 0x0d59,
+ 0x8a56, 0x0d64,
+ 0x8a57, 0x22ee,
+ 0x8a59, 0x22ec,
+ 0x8a5b, 0x0d5e,
+ 0x8a5e, 0x0d5a,
+ 0x8a60, 0x0d58,
+ 0x8a61, 0x258d,
+ 0x8a62, 0x0f14,
+ 0x8a63, 0x0f0f,
+ 0x8a66, 0x0f0a,
+ 0x8a67, 0x3f8e,
+ 0x8a68, 0x0f1a,
+ 0x8a69, 0x0f0b,
+ 0x8a6b, 0x0f07,
+ 0x8a6c, 0x0f16,
+ 0x8a6d, 0x0f13,
+ 0x8a6e, 0x0f15,
+ 0x8a70, 0x0f0c,
+ 0x8a71, 0x0f11,
+ 0x8a72, 0x0f08,
+ 0x8a74, 0x2595,
+ 0x8a75, 0x2592,
+ 0x8a76, 0x258a,
+ 0x8a77, 0x258f,
+ 0x8a79, 0x0f17,
+ 0x8a7a, 0x2596,
+ 0x8a7b, 0x0f18,
+ 0x8a7c, 0x0f0e,
+ 0x8a7e, 0x3fa5,
+ 0x8a7f, 0x258c,
+ 0x8a81, 0x2594,
+ 0x8a82, 0x2590,
+ 0x8a83, 0x2593,
+ 0x8a84, 0x2591,
+ 0x8a85, 0x0f12,
+ 0x8a86, 0x258b,
+ 0x8a87, 0x0f0d,
+ 0x8a8b, 0x2805,
+ 0x8a8c, 0x10a6,
+ 0x8a8d, 0x10a9,
+ 0x8a8f, 0x2807,
+ 0x8a90, 0x382f,
+ 0x8a91, 0x10b1,
+ 0x8a92, 0x2806,
+ 0x8a93, 0x10ab,
+ 0x8a94, 0x477b,
+ 0x8a95, 0x1216,
+ 0x8a96, 0x2808,
+ 0x8a98, 0x10b0,
+ 0x8a99, 0x2804,
+ 0x8a9a, 0x10b2,
+ 0x8a9c, 0x382c,
+ 0x8a9e, 0x10a7,
+ 0x8aa0, 0x0f10,
+ 0x8aa1, 0x10aa,
+ 0x8aa3, 0x10a8,
+ 0x8aa4, 0x10ac,
+ 0x8aa5, 0x10ae,
+ 0x8aa6, 0x10a5,
+ 0x8aa7, 0x10b3,
+ 0x8aa8, 0x10af,
+ 0x8aa9, 0x383d,
+ 0x8aaa, 0x10ad,
+ 0x8aab, 0x2803,
+ 0x8aaf, 0x3841,
+ 0x8ab0, 0x121d,
+ 0x8ab2, 0x1219,
+ 0x8ab4, 0x477c,
+ 0x8ab6, 0x1220,
+ 0x8ab8, 0x2a44,
+ 0x8ab9, 0x1221,
+ 0x8aba, 0x2a50,
+ 0x8abb, 0x2a49,
+ 0x8abc, 0x1212,
+ 0x8abd, 0x2a51,
+ 0x8abe, 0x2a4b,
+ 0x8abf, 0x121c,
+ 0x8ac0, 0x2a4c,
+ 0x8ac2, 0x121b,
+ 0x8ac3, 0x2a4f,
+ 0x8ac4, 0x1215,
+ 0x8ac5, 0x2a4d,
+ 0x8ac6, 0x2a43,
+ 0x8ac7, 0x1214,
+ 0x8ac8, 0x2c8f,
+ 0x8ac9, 0x121a,
+ 0x8acb, 0x1217,
+ 0x8acd, 0x121f,
+ 0x8acf, 0x2a42,
+ 0x8ad1, 0x2a46,
+ 0x8ad2, 0x1213,
+ 0x8ad3, 0x2a45,
+ 0x8ad4, 0x2a47,
+ 0x8ad6, 0x121e,
+ 0x8ad7, 0x2a4a,
+ 0x8ad8, 0x2a4e,
+ 0x8ad9, 0x2a52,
+ 0x8ada, 0x39c2,
+ 0x8adb, 0x1222,
+ 0x8adc, 0x1352,
+ 0x8add, 0x2c8a,
+ 0x8ade, 0x2c90,
+ 0x8adf, 0x2c8d,
+ 0x8ae0, 0x2c85,
+ 0x8ae1, 0x2c91,
+ 0x8ae2, 0x2c86,
+ 0x8ae4, 0x2c8c,
+ 0x8ae6, 0x134d,
+ 0x8ae7, 0x1353,
+ 0x8ae8, 0x2c92,
+ 0x8aea, 0x3dd9,
+ 0x8aeb, 0x134f,
+ 0x8aed, 0x1359,
+ 0x8aee, 0x1354,
+ 0x8aef, 0x2c94,
+ 0x8af0, 0x2c8e,
+ 0x8af1, 0x1350,
+ 0x8af2, 0x2c87,
+ 0x8af3, 0x135a,
+ 0x8af4, 0x2c88,
+ 0x8af6, 0x135b,
+ 0x8af7, 0x1358,
+ 0x8af8, 0x1218,
+ 0x8afa, 0x134e,
+ 0x8afb, 0x2c95,
+ 0x8afc, 0x135c,
+ 0x8afe, 0x1355,
+ 0x8aff, 0x2c93,
+ 0x8b00, 0x1351,
+ 0x8b01, 0x1356,
+ 0x8b04, 0x147e,
+ 0x8b05, 0x2e5f,
+ 0x8b06, 0x2e68,
+ 0x8b07, 0x2e65,
+ 0x8b08, 0x2e67,
+ 0x8b0a, 0x147b,
+ 0x8b0b, 0x2e60,
+ 0x8b0c, 0x3836,
+ 0x8b0d, 0x2e66,
+ 0x8b0e, 0x1477,
+ 0x8b0f, 0x2e62,
+ 0x8b10, 0x147f,
+ 0x8b11, 0x2e5e,
+ 0x8b12, 0x2e63,
+ 0x8b13, 0x2e6a,
+ 0x8b14, 0x2c8b,
+ 0x8b15, 0x2e64,
+ 0x8b16, 0x2e5d,
+ 0x8b17, 0x1478,
+ 0x8b18, 0x2e5c,
+ 0x8b19, 0x1479,
+ 0x8b1a, 0x2e6b,
+ 0x8b1b, 0x147a,
+ 0x8b1c, 0x2e69,
+ 0x8b1d, 0x147d,
+ 0x8b1e, 0x2e5b,
+ 0x8b1f, 0x3837,
+ 0x8b20, 0x147c,
+ 0x8b22, 0x2e61,
+ 0x8b23, 0x2fce,
+ 0x8b24, 0x2fdc,
+ 0x8b25, 0x2fd7,
+ 0x8b26, 0x2fd9,
+ 0x8b27, 0x2fcd,
+ 0x8b28, 0x152a,
+ 0x8b2a, 0x2fcc,
+ 0x8b2b, 0x152d,
+ 0x8b2c, 0x152c,
+ 0x8b2d, 0x3f99,
+ 0x8b2e, 0x2fdb,
+ 0x8b2f, 0x2fd3,
+ 0x8b30, 0x2fd0,
+ 0x8b31, 0x2fd6,
+ 0x8b33, 0x2fcf,
+ 0x8b35, 0x2fd1,
+ 0x8b36, 0x2fda,
+ 0x8b37, 0x2fd8,
+ 0x8b39, 0x152b,
+ 0x8b3a, 0x2fdf,
+ 0x8b3b, 0x2fdd,
+ 0x8b3c, 0x2fd4,
+ 0x8b3d, 0x2fde,
+ 0x8b3e, 0x2fd5,
+ 0x8b3f, 0x383a,
+ 0x8b40, 0x3125,
+ 0x8b41, 0x15c4,
+ 0x8b42, 0x312c,
+ 0x8b43, 0x3ff2,
+ 0x8b45, 0x3313,
+ 0x8b46, 0x15cb,
+ 0x8b47, 0x2fd2,
+ 0x8b48, 0x3123,
+ 0x8b49, 0x15c7,
+ 0x8b4a, 0x3124,
+ 0x8b4b, 0x3129,
+ 0x8b4c, 0x383b,
+ 0x8b4e, 0x15c9,
+ 0x8b50, 0x3122,
+ 0x8b51, 0x312b,
+ 0x8b52, 0x312d,
+ 0x8b53, 0x3126,
+ 0x8b54, 0x3128,
+ 0x8b55, 0x312a,
+ 0x8b56, 0x3127,
+ 0x8b57, 0x312e,
+ 0x8b58, 0x15c6,
+ 0x8b59, 0x15cc,
+ 0x8b5a, 0x15c8,
+ 0x8b5c, 0x15c5,
+ 0x8b5d, 0x3237,
+ 0x8b5e, 0x3db8,
+ 0x8b5f, 0x1648,
+ 0x8b60, 0x3235,
+ 0x8b62, 0x3dd4,
+ 0x8b63, 0x3239,
+ 0x8b65, 0x323a,
+ 0x8b66, 0x1646,
+ 0x8b67, 0x323b,
+ 0x8b68, 0x3238,
+ 0x8b69, 0x3bf7,
+ 0x8b6a, 0x3236,
+ 0x8b6b, 0x1649,
+ 0x8b6c, 0x1645,
+ 0x8b6d, 0x323c,
+ 0x8b6f, 0x1647,
+ 0x8b70, 0x1644,
+ 0x8b74, 0x168f,
+ 0x8b77, 0x1690,
+ 0x8b78, 0x3312,
+ 0x8b79, 0x3311,
+ 0x8b7a, 0x3314,
+ 0x8b7d, 0x1691,
+ 0x8b7e, 0x33b6,
+ 0x8b7f, 0x33bb,
+ 0x8b80, 0x16d8,
+ 0x8b81, 0x3d8d,
+ 0x8b82, 0x33b8,
+ 0x8b84, 0x33b7,
+ 0x8b85, 0x33ba,
+ 0x8b86, 0x33b9,
+ 0x8b88, 0x3440,
+ 0x8b8a, 0x170a,
+ 0x8b8b, 0x343f,
+ 0x8b8c, 0x343d,
+ 0x8b8e, 0x343e,
+ 0x8b90, 0x383f,
+ 0x8b92, 0x172c,
+ 0x8b93, 0x172b,
+ 0x8b94, 0x349c,
+ 0x8b96, 0x172d,
+ 0x8b98, 0x34e7,
+ 0x8b9a, 0x1754,
+ 0x8b9b, 0x3840,
+ 0x8b9c, 0x175a,
+ 0x8b9e, 0x3522,
+ 0x8b9f, 0x353f,
+ 0x8ba0, 0x4505,
+ 0x8bbe, 0x4567,
+ 0x8be2, 0x4568,
+ 0x8c37, 0x050b,
+ 0x8c39, 0x206b,
+ 0x8c3b, 0x206c,
+ 0x8c3c, 0x2597,
+ 0x8c3d, 0x2809,
+ 0x8c3e, 0x2a53,
+ 0x8c3f, 0x1481,
+ 0x8c41, 0x1480,
+ 0x8c42, 0x2fe0,
+ 0x8c43, 0x312f,
+ 0x8c45, 0x3441,
+ 0x8c46, 0x050c,
+ 0x8c47, 0x1e09,
+ 0x8c48, 0x09c9,
+ 0x8c49, 0x0ba7,
+ 0x8c4a, 0x2599,
+ 0x8c4b, 0x2598,
+ 0x8c4c, 0x1223,
+ 0x8c4d, 0x2a54,
+ 0x8c4e, 0x1224,
+ 0x8c4f, 0x2e6c,
+ 0x8c50, 0x152e,
+ 0x8c51, 0x477d,
+ 0x8c54, 0x1763,
+ 0x8c55, 0x050d,
+ 0x8c56, 0x1a48,
+ 0x8c57, 0x1e0a,
+ 0x8c5a, 0x0ba8,
+ 0x8c5c, 0x206d,
+ 0x8c5f, 0x22f8,
+ 0x8c61, 0x0d65,
+ 0x8c62, 0x0f1b,
+ 0x8c64, 0x259b,
+ 0x8c65, 0x259a,
+ 0x8c66, 0x259c,
+ 0x8c68, 0x280a,
+ 0x8c6a, 0x10b4,
+ 0x8c6b, 0x135d,
+ 0x8c6c, 0x1225,
+ 0x8c6d, 0x135e,
+ 0x8c6f, 0x2e70,
+ 0x8c70, 0x2e6d,
+ 0x8c71, 0x2e6f,
+ 0x8c72, 0x2e6e,
+ 0x8c73, 0x1482,
+ 0x8c75, 0x2fe1,
+ 0x8c76, 0x3131,
+ 0x8c77, 0x3130,
+ 0x8c78, 0x18e7,
+ 0x8c79, 0x09cb,
+ 0x8c7a, 0x09ca,
+ 0x8c7b, 0x1e0b,
+ 0x8c7d, 0x206f,
+ 0x8c80, 0x22fa,
+ 0x8c81, 0x22f9,
+ 0x8c82, 0x0d66,
+ 0x8c84, 0x259e,
+ 0x8c86, 0x259d,
+ 0x8c89, 0x0f1d,
+ 0x8c8a, 0x0f1c,
+ 0x8c8c, 0x10b6,
+ 0x8c8d, 0x10b5,
+ 0x8c8f, 0x2a55,
+ 0x8c90, 0x2c98,
+ 0x8c91, 0x2c96,
+ 0x8c93, 0x135f,
+ 0x8c94, 0x2e72,
+ 0x8c95, 0x2e71,
+ 0x8c97, 0x2fe4,
+ 0x8c98, 0x2fe3,
+ 0x8c99, 0x2fe2,
+ 0x8c9a, 0x3132,
+ 0x8c9b, 0x3845,
+ 0x8c9c, 0x3523,
+ 0x8c9d, 0x050e,
+ 0x8c9e, 0x080a,
+ 0x8c9f, 0x3bad,
+ 0x8ca0, 0x080b,
+ 0x8ca1, 0x09cc,
+ 0x8ca3, 0x1e0d,
+ 0x8ca4, 0x1e0c,
+ 0x8ca5, 0x2070,
+ 0x8ca7, 0x0bae,
+ 0x8ca8, 0x0bac,
+ 0x8ca9, 0x0ba9,
+ 0x8caa, 0x0bad,
+ 0x8cab, 0x0bab,
+ 0x8cac, 0x0baa,
+ 0x8cad, 0x3ff1,
+ 0x8caf, 0x0d67,
+ 0x8cb0, 0x22fd,
+ 0x8cb2, 0x0f22,
+ 0x8cb3, 0x0d69,
+ 0x8cb4, 0x0d6e,
+ 0x8cb5, 0x22ff,
+ 0x8cb6, 0x0d70,
+ 0x8cb7, 0x0d6f,
+ 0x8cb8, 0x0d72,
+ 0x8cb9, 0x22fe,
+ 0x8cba, 0x22fb,
+ 0x8cbb, 0x0d6c,
+ 0x8cbc, 0x0d68,
+ 0x8cbd, 0x0d6a,
+ 0x8cbe, 0x22fc,
+ 0x8cbf, 0x0d71,
+ 0x8cc0, 0x0d6d,
+ 0x8cc1, 0x0d6b,
+ 0x8cc2, 0x0f24,
+ 0x8cc3, 0x0f23,
+ 0x8cc4, 0x0f21,
+ 0x8cc5, 0x0f25,
+ 0x8cc7, 0x0f1f,
+ 0x8cca, 0x0f1e,
+ 0x8ccc, 0x25a0,
+ 0x8ccd, 0x3e99,
+ 0x8ccf, 0x280d,
+ 0x8cd1, 0x10b8,
+ 0x8cd3, 0x10b7,
+ 0x8cd4, 0x477e,
+ 0x8cd5, 0x280c,
+ 0x8cd6, 0x384b,
+ 0x8cd7, 0x280e,
+ 0x8cd9, 0x2a58,
+ 0x8cda, 0x2a5a,
+ 0x8cdb, 0x3851,
+ 0x8cdc, 0x122e,
+ 0x8cdd, 0x2a5b,
+ 0x8cde, 0x1227,
+ 0x8cdf, 0x2a57,
+ 0x8ce0, 0x1226,
+ 0x8ce1, 0x1230,
+ 0x8ce2, 0x122c,
+ 0x8ce4, 0x1229,
+ 0x8ce5, 0x2a56,
+ 0x8ce6, 0x1228,
+ 0x8ce7, 0x2a5c,
+ 0x8ce8, 0x2a59,
+ 0x8ce9, 0x3bae,
+ 0x8cea, 0x122f,
+ 0x8ceb, 0x3f9c,
+ 0x8cec, 0x122a,
+ 0x8cee, 0x2c9a,
+ 0x8cf0, 0x2c9c,
+ 0x8cf1, 0x2c9b,
+ 0x8cf2, 0x477f,
+ 0x8cf3, 0x2c9d,
+ 0x8cf4, 0x1360,
+ 0x8cf5, 0x2c99,
+ 0x8cf7, 0x3fb1,
+ 0x8cf8, 0x1486,
+ 0x8cf9, 0x2e73,
+ 0x8cfa, 0x1483,
+ 0x8cfb, 0x1487,
+ 0x8cfc, 0x1485,
+ 0x8cfd, 0x1484,
+ 0x8cfe, 0x2fe5,
+ 0x8d00, 0x2fe8,
+ 0x8d02, 0x2fe7,
+ 0x8d03, 0x384f,
+ 0x8d04, 0x2fe6,
+ 0x8d05, 0x152f,
+ 0x8d06, 0x3133,
+ 0x8d08, 0x15cd,
+ 0x8d09, 0x3135,
+ 0x8d0a, 0x15ce,
+ 0x8d0b, 0x4573,
+ 0x8d0c, 0x3f96,
+ 0x8d0d, 0x164b,
+ 0x8d0f, 0x164a,
+ 0x8d10, 0x3316,
+ 0x8d11, 0x3853,
+ 0x8d12, 0x384e,
+ 0x8d13, 0x1692,
+ 0x8d14, 0x3317,
+ 0x8d15, 0x33bc,
+ 0x8d16, 0x16d9,
+ 0x8d18, 0x3e6f,
+ 0x8d19, 0x3442,
+ 0x8d1b, 0x172f,
+ 0x8d1c, 0x4780,
+ 0x8d1d, 0x4506,
+ 0x8d64, 0x050f,
+ 0x8d66, 0x0bb0,
+ 0x8d67, 0x0baf,
+ 0x8d68, 0x25a1,
+ 0x8d6b, 0x10ba,
+ 0x8d6c, 0x2c9e,
+ 0x8d6d, 0x1231,
+ 0x8d6e, 0x2c9f,
+ 0x8d6f, 0x2e74,
+ 0x8d70, 0x0510,
+ 0x8d72, 0x1c06,
+ 0x8d73, 0x080d,
+ 0x8d74, 0x080c,
+ 0x8d76, 0x1e0e,
+ 0x8d77, 0x09ce,
+ 0x8d78, 0x1e0f,
+ 0x8d79, 0x2073,
+ 0x8d7a, 0x39e1,
+ 0x8d7b, 0x2072,
+ 0x8d7d, 0x2071,
+ 0x8d80, 0x2301,
+ 0x8d81, 0x0d75,
+ 0x8d82, 0x3f69,
+ 0x8d84, 0x2300,
+ 0x8d85, 0x0d74,
+ 0x8d89, 0x2302,
+ 0x8d8a, 0x0d73,
+ 0x8d8c, 0x25a4,
+ 0x8d8d, 0x25a7,
+ 0x8d8e, 0x25a5,
+ 0x8d90, 0x25aa,
+ 0x8d91, 0x25a3,
+ 0x8d92, 0x25ab,
+ 0x8d93, 0x25a8,
+ 0x8d95, 0x10bc,
+ 0x8d96, 0x280f,
+ 0x8d99, 0x10bb,
+ 0x8d9b, 0x2a60,
+ 0x8d9c, 0x2a5e,
+ 0x8d9f, 0x1232,
+ 0x8da0, 0x2a5d,
+ 0x8da1, 0x2a5f,
+ 0x8da3, 0x1233,
+ 0x8da5, 0x2ca0,
+ 0x8da6, 0x3ff7,
+ 0x8da7, 0x2ca1,
+ 0x8da8, 0x1488,
+ 0x8da9, 0x3856,
+ 0x8daa, 0x3137,
+ 0x8dab, 0x3139,
+ 0x8dac, 0x3136,
+ 0x8dad, 0x3138,
+ 0x8dae, 0x323d,
+ 0x8daf, 0x3318,
+ 0x8db2, 0x3509,
+ 0x8db3, 0x0511,
+ 0x8db4, 0x080e,
+ 0x8db5, 0x1e10,
+ 0x8db6, 0x1e12,
+ 0x8db7, 0x1e11,
+ 0x8db9, 0x2076,
+ 0x8dba, 0x0bb2,
+ 0x8dbc, 0x2074,
+ 0x8dbe, 0x0bb1,
+ 0x8dbf, 0x2077,
+ 0x8dc0, 0x436a,
+ 0x8dc1, 0x2078,
+ 0x8dc2, 0x2075,
+ 0x8dc3, 0x4782,
+ 0x8dc5, 0x230e,
+ 0x8dc6, 0x0d7d,
+ 0x8dc7, 0x2306,
+ 0x8dc8, 0x230c,
+ 0x8dcb, 0x0d78,
+ 0x8dcc, 0x0d7b,
+ 0x8dcd, 0x2305,
+ 0x8dce, 0x0d76,
+ 0x8dcf, 0x2309,
+ 0x8dd0, 0x25b1,
+ 0x8dd1, 0x0d7a,
+ 0x8dd3, 0x2304,
+ 0x8dd4, 0x3f82,
+ 0x8dd5, 0x230a,
+ 0x8dd6, 0x2307,
+ 0x8dd7, 0x230d,
+ 0x8dd8, 0x2303,
+ 0x8dd9, 0x230b,
+ 0x8dda, 0x0d79,
+ 0x8ddb, 0x0d7c,
+ 0x8ddc, 0x2308,
+ 0x8ddd, 0x0d77,
+ 0x8ddf, 0x0f27,
+ 0x8de0, 0x25ad,
+ 0x8de1, 0x0f26,
+ 0x8de2, 0x25b4,
+ 0x8de3, 0x25b3,
+ 0x8de4, 0x0f2d,
+ 0x8de6, 0x0f2e,
+ 0x8de7, 0x25b5,
+ 0x8de8, 0x0f28,
+ 0x8de9, 0x25b2,
+ 0x8dea, 0x0f2c,
+ 0x8deb, 0x25b7,
+ 0x8dec, 0x25ae,
+ 0x8dee, 0x25b0,
+ 0x8def, 0x0f29,
+ 0x8df0, 0x25ac,
+ 0x8df1, 0x25af,
+ 0x8df2, 0x25b6,
+ 0x8df3, 0x0f2a,
+ 0x8df4, 0x25b8,
+ 0x8dfa, 0x0f2b,
+ 0x8dfc, 0x10bd,
+ 0x8dfd, 0x2814,
+ 0x8dfe, 0x281a,
+ 0x8dff, 0x2812,
+ 0x8e00, 0x281b,
+ 0x8e01, 0x3f85,
+ 0x8e02, 0x2811,
+ 0x8e03, 0x2816,
+ 0x8e04, 0x281c,
+ 0x8e05, 0x2819,
+ 0x8e06, 0x2818,
+ 0x8e07, 0x2817,
+ 0x8e09, 0x2810,
+ 0x8e0a, 0x2815,
+ 0x8e0d, 0x2813,
+ 0x8e0e, 0x3e5e,
+ 0x8e0f, 0x1238,
+ 0x8e10, 0x1235,
+ 0x8e11, 0x2a69,
+ 0x8e12, 0x2a6e,
+ 0x8e13, 0x2a70,
+ 0x8e14, 0x2a6d,
+ 0x8e15, 0x2a66,
+ 0x8e16, 0x2a68,
+ 0x8e17, 0x2a72,
+ 0x8e18, 0x2a6f,
+ 0x8e19, 0x2a6a,
+ 0x8e1a, 0x2a73,
+ 0x8e1b, 0x2a67,
+ 0x8e1c, 0x2a71,
+ 0x8e1d, 0x1236,
+ 0x8e1e, 0x123c,
+ 0x8e1f, 0x123a,
+ 0x8e20, 0x2a61,
+ 0x8e21, 0x123b,
+ 0x8e22, 0x1237,
+ 0x8e23, 0x2a62,
+ 0x8e24, 0x2a64,
+ 0x8e25, 0x2a63,
+ 0x8e26, 0x2a6b,
+ 0x8e28, 0x3f88,
+ 0x8e29, 0x1239,
+ 0x8e2a, 0x3bb4,
+ 0x8e2b, 0x1234,
+ 0x8e2d, 0x3eab,
+ 0x8e2e, 0x2a65,
+ 0x8e30, 0x2cab,
+ 0x8e31, 0x1362,
+ 0x8e33, 0x2ca2,
+ 0x8e34, 0x1363,
+ 0x8e35, 0x1366,
+ 0x8e36, 0x2ca7,
+ 0x8e38, 0x2ca4,
+ 0x8e39, 0x1365,
+ 0x8e3a, 0x4784,
+ 0x8e3c, 0x2ca8,
+ 0x8e3e, 0x2ca3,
+ 0x8e3f, 0x2cac,
+ 0x8e40, 0x2ca5,
+ 0x8e41, 0x2caa,
+ 0x8e42, 0x1364,
+ 0x8e44, 0x1361,
+ 0x8e45, 0x2ca6,
+ 0x8e46, 0x4312,
+ 0x8e47, 0x2e7a,
+ 0x8e48, 0x148b,
+ 0x8e49, 0x1489,
+ 0x8e4a, 0x148c,
+ 0x8e4b, 0x148a,
+ 0x8e4c, 0x2e79,
+ 0x8e4d, 0x2e76,
+ 0x8e4e, 0x2e75,
+ 0x8e4f, 0x3f83,
+ 0x8e50, 0x2e78,
+ 0x8e53, 0x2e77,
+ 0x8e54, 0x2ff6,
+ 0x8e55, 0x1535,
+ 0x8e56, 0x2fed,
+ 0x8e57, 0x2fec,
+ 0x8e59, 0x1530,
+ 0x8e5a, 0x2ff2,
+ 0x8e5b, 0x2ff1,
+ 0x8e5c, 0x2fe9,
+ 0x8e5d, 0x2ff4,
+ 0x8e5e, 0x2fee,
+ 0x8e5f, 0x1534,
+ 0x8e60, 0x2feb,
+ 0x8e61, 0x2ff3,
+ 0x8e62, 0x2fea,
+ 0x8e63, 0x1531,
+ 0x8e64, 0x1533,
+ 0x8e65, 0x2fef,
+ 0x8e66, 0x1532,
+ 0x8e67, 0x2ff0,
+ 0x8e68, 0x434d,
+ 0x8e69, 0x2ff5,
+ 0x8e6a, 0x313d,
+ 0x8e6c, 0x15d3,
+ 0x8e6d, 0x313a,
+ 0x8e6f, 0x313e,
+ 0x8e71, 0x43e7,
+ 0x8e72, 0x15d0,
+ 0x8e73, 0x313c,
+ 0x8e74, 0x15d5,
+ 0x8e75, 0x3f89,
+ 0x8e76, 0x15d2,
+ 0x8e77, 0x3f7f,
+ 0x8e78, 0x313b,
+ 0x8e7a, 0x15d4,
+ 0x8e7b, 0x313f,
+ 0x8e7c, 0x15cf,
+ 0x8e7e, 0x4324,
+ 0x8e80, 0x3e57,
+ 0x8e81, 0x164d,
+ 0x8e82, 0x164f,
+ 0x8e84, 0x3240,
+ 0x8e85, 0x164e,
+ 0x8e86, 0x323e,
+ 0x8e87, 0x15d1,
+ 0x8e88, 0x323f,
+ 0x8e89, 0x164c,
+ 0x8e8a, 0x1693,
+ 0x8e8b, 0x1695,
+ 0x8e8c, 0x331a,
+ 0x8e8d, 0x1694,
+ 0x8e8e, 0x3319,
+ 0x8e90, 0x33c1,
+ 0x8e91, 0x16db,
+ 0x8e92, 0x33c0,
+ 0x8e93, 0x16dc,
+ 0x8e94, 0x33be,
+ 0x8e95, 0x33bd,
+ 0x8e96, 0x33c2,
+ 0x8e98, 0x3443,
+ 0x8e9a, 0x33bf,
+ 0x8e9d, 0x34a1,
+ 0x8e9e, 0x349e,
+ 0x8ea1, 0x1749,
+ 0x8ea3, 0x34eb,
+ 0x8ea4, 0x34ea,
+ 0x8ea5, 0x34e9,
+ 0x8ea6, 0x350a,
+ 0x8ea7, 0x3bb5,
+ 0x8ea8, 0x3537,
+ 0x8ea9, 0x3524,
+ 0x8eaa, 0x175b,
+ 0x8eab, 0x0512,
+ 0x8eac, 0x09cf,
+ 0x8ead, 0x385e,
+ 0x8eb0, 0x43e9,
+ 0x8eb2, 0x0f2f,
+ 0x8eb6, 0x385f,
+ 0x8eba, 0x123d,
+ 0x8ebc, 0x38a0,
+ 0x8ebd, 0x2cad,
+ 0x8ec0, 0x1536,
+ 0x8ec2, 0x3140,
+ 0x8ec3, 0x3860,
+ 0x8ec9, 0x3525,
+ 0x8eca, 0x0513,
+ 0x8ecb, 0x068d,
+ 0x8ecc, 0x0810,
+ 0x8ecd, 0x080f,
+ 0x8ece, 0x4788,
+ 0x8ecf, 0x09d2,
+ 0x8ed1, 0x1e13,
+ 0x8ed2, 0x09d0,
+ 0x8ed3, 0x1e14,
+ 0x8ed4, 0x09d1,
+ 0x8ed7, 0x207d,
+ 0x8ed8, 0x2079,
+ 0x8eda, 0x3dbe,
+ 0x8edb, 0x0bb3,
+ 0x8edc, 0x207c,
+ 0x8edd, 0x207b,
+ 0x8ede, 0x207a,
+ 0x8edf, 0x0bb4,
+ 0x8ee0, 0x207e,
+ 0x8ee2, 0x4789,
+ 0x8ee4, 0x478a,
+ 0x8ee5, 0x2315,
+ 0x8ee6, 0x2313,
+ 0x8ee7, 0x2317,
+ 0x8ee9, 0x231e,
+ 0x8eeb, 0x231a,
+ 0x8eec, 0x231c,
+ 0x8eed, 0x478b,
+ 0x8eee, 0x2314,
+ 0x8eef, 0x230f,
+ 0x8ef1, 0x231b,
+ 0x8ef2, 0x478c,
+ 0x8ef4, 0x231d,
+ 0x8ef5, 0x2316,
+ 0x8ef6, 0x2319,
+ 0x8ef7, 0x2310,
+ 0x8ef8, 0x0d7f,
+ 0x8ef9, 0x2312,
+ 0x8efa, 0x2311,
+ 0x8efb, 0x0d7e,
+ 0x8efc, 0x0d80,
+ 0x8efe, 0x0f32,
+ 0x8eff, 0x25ba,
+ 0x8f00, 0x25bc,
+ 0x8f01, 0x25bb,
+ 0x8f02, 0x25c0,
+ 0x8f03, 0x0f30,
+ 0x8f05, 0x25bd,
+ 0x8f06, 0x25b9,
+ 0x8f07, 0x25be,
+ 0x8f09, 0x0f31,
+ 0x8f0a, 0x0f33,
+ 0x8f0b, 0x25c1,
+ 0x8f0d, 0x2820,
+ 0x8f0e, 0x281f,
+ 0x8f10, 0x281d,
+ 0x8f12, 0x10bf,
+ 0x8f13, 0x10c1,
+ 0x8f14, 0x10be,
+ 0x8f15, 0x10c0,
+ 0x8f16, 0x2a7a,
+ 0x8f18, 0x2a76,
+ 0x8f19, 0x3862,
+ 0x8f1a, 0x2a77,
+ 0x8f1b, 0x123f,
+ 0x8f1c, 0x1244,
+ 0x8f1d, 0x123e,
+ 0x8f1e, 0x1245,
+ 0x8f1f, 0x1240,
+ 0x8f20, 0x2a78,
+ 0x8f23, 0x2a79,
+ 0x8f24, 0x2a75,
+ 0x8f25, 0x1246,
+ 0x8f26, 0x1242,
+ 0x8f29, 0x1241,
+ 0x8f2a, 0x1243,
+ 0x8f2c, 0x2a74,
+ 0x8f2d, 0x3863,
+ 0x8f2e, 0x2caf,
+ 0x8f2f, 0x1368,
+ 0x8f30, 0x3bb7,
+ 0x8f32, 0x2cb1,
+ 0x8f33, 0x136a,
+ 0x8f34, 0x2cb4,
+ 0x8f35, 0x2cb0,
+ 0x8f36, 0x2cae,
+ 0x8f37, 0x2cb3,
+ 0x8f38, 0x1369,
+ 0x8f39, 0x2cb2,
+ 0x8f3b, 0x1367,
+ 0x8f3e, 0x148e,
+ 0x8f3f, 0x1491,
+ 0x8f40, 0x2e7c,
+ 0x8f41, 0x3d07,
+ 0x8f42, 0x148f,
+ 0x8f43, 0x2e7b,
+ 0x8f44, 0x148d,
+ 0x8f45, 0x1490,
+ 0x8f46, 0x2ff7,
+ 0x8f49, 0x1537,
+ 0x8f4a, 0x3bb8,
+ 0x8f4b, 0x2ffa,
+ 0x8f4d, 0x1538,
+ 0x8f4e, 0x15d7,
+ 0x8f4f, 0x3143,
+ 0x8f51, 0x3142,
+ 0x8f52, 0x3141,
+ 0x8f53, 0x3145,
+ 0x8f54, 0x15d6,
+ 0x8f55, 0x3244,
+ 0x8f56, 0x3242,
+ 0x8f58, 0x3245,
+ 0x8f59, 0x3241,
+ 0x8f5a, 0x3246,
+ 0x8f5b, 0x331c,
+ 0x8f5c, 0x3f31,
+ 0x8f5d, 0x331d,
+ 0x8f5e, 0x331b,
+ 0x8f5f, 0x1696,
+ 0x8f60, 0x33c4,
+ 0x8f61, 0x16dd,
+ 0x8f62, 0x33c5,
+ 0x8f63, 0x3445,
+ 0x8f64, 0x3444,
+ 0x8f66, 0x4569,
+ 0x8f6e, 0x456b,
+ 0x8f93, 0x4732,
+ 0x8f9b, 0x0514,
+ 0x8f9c, 0x0d81,
+ 0x8f9f, 0x0f34,
+ 0x8fa0, 0x3d94,
+ 0x8fa3, 0x10c2,
+ 0x8fa5, 0x3866,
+ 0x8fa6, 0x136c,
+ 0x8fa8, 0x136b,
+ 0x8fad, 0x15d8,
+ 0x8fae, 0x162f,
+ 0x8faf, 0x1697,
+ 0x8fb0, 0x0515,
+ 0x8fb1, 0x09d3,
+ 0x8fb2, 0x0f35,
+ 0x8fb3, 0x386a,
+ 0x8fb4, 0x3146,
+ 0x8fb5, 0x0230,
+ 0x8fb6, 0x47d3,
+ 0x8fb7, 0x43fd,
+ 0x8fb8, 0x42f6,
+ 0x8fb9, 0x48c9,
+ 0x8fba, 0x48c7,
+ 0x8fbb, 0x3d6b,
+ 0x8fbe, 0x48c6,
+ 0x8fbf, 0x18e9,
+ 0x8fc1, 0x478d,
+ 0x8fc2, 0x0516,
+ 0x8fc4, 0x0519,
+ 0x8fc5, 0x0518,
+ 0x8fc6, 0x0517,
+ 0x8fc9, 0x18e8,
+ 0x8fca, 0x478e,
+ 0x8fcb, 0x1a4a,
+ 0x8fcc, 0x478f,
+ 0x8fcd, 0x1a4c,
+ 0x8fce, 0x068e,
+ 0x8fd0, 0x48ae,
+ 0x8fd1, 0x0690,
+ 0x8fd2, 0x1a49,
+ 0x8fd3, 0x1a4b,
+ 0x8fd4, 0x068f,
+ 0x8fd5, 0x1a4e,
+ 0x8fd6, 0x1a4d,
+ 0x8fd7, 0x1a4f,
+ 0x8fda, 0x3fcb,
+ 0x8fe0, 0x1c0a,
+ 0x8fe1, 0x1c08,
+ 0x8fe2, 0x0813,
+ 0x8fe3, 0x1c07,
+ 0x8fe4, 0x0818,
+ 0x8fe5, 0x0815,
+ 0x8fe6, 0x0812,
+ 0x8fe8, 0x0819,
+ 0x8fea, 0x0814,
+ 0x8feb, 0x0817,
+ 0x8fed, 0x0816,
+ 0x8fee, 0x1c09,
+ 0x8ff0, 0x0811,
+ 0x8ff4, 0x09d9,
+ 0x8ff5, 0x1e16,
+ 0x8ff6, 0x1e1c,
+ 0x8ff7, 0x09d6,
+ 0x8ff8, 0x09dd,
+ 0x8ff9, 0x3871,
+ 0x8ffa, 0x09d8,
+ 0x8ffb, 0x1e19,
+ 0x8ffc, 0x1e1b,
+ 0x8ffd, 0x09db,
+ 0x8ffe, 0x1e15,
+ 0x8fff, 0x1e18,
+ 0x9000, 0x09d7,
+ 0x9001, 0x09d4,
+ 0x9002, 0x1e17,
+ 0x9003, 0x09da,
+ 0x9004, 0x1e1a,
+ 0x9005, 0x09dc,
+ 0x9006, 0x09d5,
+ 0x9008, 0x3ee0,
+ 0x900b, 0x2081,
+ 0x900c, 0x2084,
+ 0x900d, 0x0bb6,
+ 0x900f, 0x0bc0,
+ 0x9010, 0x0bbc,
+ 0x9011, 0x2082,
+ 0x9012, 0x3e4e,
+ 0x9014, 0x0bc4,
+ 0x9015, 0x0bbd,
+ 0x9016, 0x0bc2,
+ 0x9017, 0x0bb8,
+ 0x9019, 0x0bb5,
+ 0x901a, 0x0bb7,
+ 0x901b, 0x0bc3,
+ 0x901c, 0x2083,
+ 0x901d, 0x0bbb,
+ 0x901e, 0x0bbe,
+ 0x901f, 0x0bba,
+ 0x9020, 0x0bbf,
+ 0x9021, 0x2085,
+ 0x9022, 0x0bc1,
+ 0x9023, 0x0bb9,
+ 0x9024, 0x2080,
+ 0x902d, 0x231f,
+ 0x902e, 0x0d82,
+ 0x902f, 0x2321,
+ 0x9031, 0x0d84,
+ 0x9032, 0x0d86,
+ 0x9033, 0x4790,
+ 0x9034, 0x2320,
+ 0x9035, 0x0d83,
+ 0x9036, 0x0d87,
+ 0x9037, 0x3876,
+ 0x9038, 0x0d85,
+ 0x903c, 0x0f3b,
+ 0x903d, 0x25c6,
+ 0x903e, 0x0f43,
+ 0x903f, 0x25c3,
+ 0x9041, 0x0f44,
+ 0x9042, 0x0f39,
+ 0x9044, 0x25c4,
+ 0x9047, 0x0f3e,
+ 0x9049, 0x25c5,
+ 0x904a, 0x0f37,
+ 0x904b, 0x0f36,
+ 0x904c, 0x3f10,
+ 0x904d, 0x0f41,
+ 0x904e, 0x0f40,
+ 0x904f, 0x0f3f,
+ 0x9050, 0x0f3d,
+ 0x9051, 0x0f42,
+ 0x9052, 0x25c2,
+ 0x9053, 0x0f38,
+ 0x9054, 0x0f3a,
+ 0x9055, 0x0f3c,
+ 0x9056, 0x3dd2,
+ 0x9058, 0x10c4,
+ 0x9059, 0x10c7,
+ 0x905b, 0x10cb,
+ 0x905c, 0x10c5,
+ 0x905d, 0x10ca,
+ 0x905e, 0x10c8,
+ 0x9060, 0x10c3,
+ 0x9061, 0x3879,
+ 0x9062, 0x10c9,
+ 0x9063, 0x10c6,
+ 0x9064, 0x3c68,
+ 0x9067, 0x2a7f,
+ 0x9068, 0x1249,
+ 0x9069, 0x1247,
+ 0x906b, 0x2a80,
+ 0x906c, 0x3d60,
+ 0x906d, 0x124a,
+ 0x906e, 0x1248,
+ 0x906f, 0x2a7e,
+ 0x9070, 0x2a7d,
+ 0x9072, 0x1370,
+ 0x9073, 0x2a7c,
+ 0x9074, 0x136e,
+ 0x9075, 0x136d,
+ 0x9076, 0x2cb5,
+ 0x9077, 0x124b,
+ 0x9078, 0x136f,
+ 0x9079, 0x2cb6,
+ 0x907a, 0x1372,
+ 0x907b, 0x2cb7,
+ 0x907c, 0x1371,
+ 0x907d, 0x1493,
+ 0x907e, 0x2e7e,
+ 0x907f, 0x1492,
+ 0x9080, 0x1497,
+ 0x9081, 0x1495,
+ 0x9083, 0x153a,
+ 0x9084, 0x1494,
+ 0x9085, 0x2e7d,
+ 0x9086, 0x2cb8,
+ 0x9087, 0x1539,
+ 0x9088, 0x153b,
+ 0x908a, 0x15d9,
+ 0x908d, 0x3247,
+ 0x908f, 0x170c,
+ 0x9090, 0x170b,
+ 0x9091, 0x051b,
+ 0x9094, 0x181e,
+ 0x9095, 0x09de,
+ 0x9097, 0x181b,
+ 0x9099, 0x181a,
+ 0x909b, 0x181d,
+ 0x909e, 0x18ed,
+ 0x909f, 0x18ea,
+ 0x90a0, 0x18ef,
+ 0x90a1, 0x18eb,
+ 0x90a2, 0x051c,
+ 0x90a3, 0x051f,
+ 0x90a5, 0x18ec,
+ 0x90a6, 0x051e,
+ 0x90a7, 0x18ee,
+ 0x90a8, 0x387c,
+ 0x90aa, 0x051d,
+ 0x90ae, 0x3880,
+ 0x90af, 0x1a52,
+ 0x90b0, 0x1a54,
+ 0x90b1, 0x0693,
+ 0x90b2, 0x1a50,
+ 0x90b3, 0x1a53,
+ 0x90b4, 0x1a51,
+ 0x90b5, 0x0691,
+ 0x90b6, 0x0694,
+ 0x90b8, 0x0692,
+ 0x90bb, 0x3bc4,
+ 0x90bd, 0x1c0c,
+ 0x90be, 0x1c10,
+ 0x90bf, 0x1c0d,
+ 0x90c1, 0x081c,
+ 0x90c3, 0x081d,
+ 0x90c4, 0x387e,
+ 0x90c5, 0x1c0f,
+ 0x90c7, 0x1c11,
+ 0x90c8, 0x1c13,
+ 0x90ca, 0x081a,
+ 0x90cb, 0x1c12,
+ 0x90ce, 0x081b,
+ 0x90d4, 0x208c,
+ 0x90d5, 0x1c0e,
+ 0x90d6, 0x1e1d,
+ 0x90d7, 0x1e26,
+ 0x90d8, 0x1e24,
+ 0x90d9, 0x1e1f,
+ 0x90db, 0x1e25,
+ 0x90dc, 0x1e27,
+ 0x90dd, 0x09e0,
+ 0x90df, 0x1e22,
+ 0x90e0, 0x1e1e,
+ 0x90e1, 0x09df,
+ 0x90e2, 0x09e1,
+ 0x90e3, 0x1e21,
+ 0x90e4, 0x1e28,
+ 0x90e5, 0x1e23,
+ 0x90e8, 0x0bc5,
+ 0x90e9, 0x208f,
+ 0x90ea, 0x2087,
+ 0x90eb, 0x208d,
+ 0x90ed, 0x0bc6,
+ 0x90ef, 0x2086,
+ 0x90f0, 0x2088,
+ 0x90f1, 0x1c0b,
+ 0x90f2, 0x208a,
+ 0x90f4, 0x2089,
+ 0x90f5, 0x0d89,
+ 0x90f9, 0x2328,
+ 0x90fa, 0x2cb9,
+ 0x90fb, 0x2329,
+ 0x90fc, 0x2326,
+ 0x90fd, 0x0bc7,
+ 0x90fe, 0x0d8b,
+ 0x90ff, 0x2325,
+ 0x9100, 0x232b,
+ 0x9101, 0x232a,
+ 0x9102, 0x0d88,
+ 0x9103, 0x232e,
+ 0x9104, 0x2324,
+ 0x9105, 0x232d,
+ 0x9106, 0x2322,
+ 0x9107, 0x232c,
+ 0x9108, 0x2327,
+ 0x9109, 0x0d8a,
+ 0x910b, 0x25cd,
+ 0x910d, 0x25c8,
+ 0x910e, 0x25ce,
+ 0x910f, 0x25c9,
+ 0x9110, 0x25c7,
+ 0x9111, 0x25ca,
+ 0x9112, 0x0f45,
+ 0x9114, 0x25cc,
+ 0x9116, 0x25cb,
+ 0x9117, 0x0f46,
+ 0x9118, 0x10cd,
+ 0x9119, 0x10cc,
+ 0x911a, 0x2827,
+ 0x911b, 0x282a,
+ 0x911c, 0x2822,
+ 0x911d, 0x2826,
+ 0x911e, 0x10ce,
+ 0x911f, 0x2825,
+ 0x9120, 0x2823,
+ 0x9121, 0x2829,
+ 0x9122, 0x2824,
+ 0x9123, 0x2821,
+ 0x9124, 0x2828,
+ 0x9126, 0x2a86,
+ 0x9127, 0x124e,
+ 0x9128, 0x2ffb,
+ 0x9129, 0x2a83,
+ 0x912b, 0x2a82,
+ 0x912c, 0x2323,
+ 0x912d, 0x124d,
+ 0x912e, 0x2a87,
+ 0x912f, 0x2a81,
+ 0x9130, 0x124c,
+ 0x9131, 0x124f,
+ 0x9132, 0x2a85,
+ 0x9133, 0x2cba,
+ 0x9134, 0x1373,
+ 0x9135, 0x2cbb,
+ 0x9138, 0x2e7f,
+ 0x9139, 0x1498,
+ 0x913a, 0x2ffc,
+ 0x913e, 0x2ffe,
+ 0x913f, 0x3148,
+ 0x9140, 0x3147,
+ 0x9141, 0x3249,
+ 0x9143, 0x3248,
+ 0x9144, 0x331f,
+ 0x9146, 0x331e,
+ 0x9147, 0x33c6,
+ 0x9148, 0x16de,
+ 0x9149, 0x0520,
+ 0x914a, 0x081f,
+ 0x914b, 0x081e,
+ 0x914c, 0x09e4,
+ 0x914d, 0x09e3,
+ 0x914e, 0x1e2a,
+ 0x9150, 0x1e29,
+ 0x9151, 0x3f49,
+ 0x9152, 0x09e2,
+ 0x9153, 0x2093,
+ 0x9155, 0x2094,
+ 0x9156, 0x2090,
+ 0x9157, 0x0bc8,
+ 0x9158, 0x2091,
+ 0x9159, 0x3f45,
+ 0x915a, 0x2092,
+ 0x915c, 0x3f47,
+ 0x915e, 0x43eb,
+ 0x915f, 0x2331,
+ 0x9160, 0x2333,
+ 0x9161, 0x232f,
+ 0x9162, 0x2332,
+ 0x9163, 0x0d8c,
+ 0x9164, 0x2330,
+ 0x9165, 0x0d8d,
+ 0x9167, 0x3882,
+ 0x9168, 0x23e2,
+ 0x9169, 0x0f49,
+ 0x916a, 0x0f48,
+ 0x916c, 0x0f47,
+ 0x916e, 0x25cf,
+ 0x9170, 0x3eb8,
+ 0x9172, 0x282c,
+ 0x9173, 0x282e,
+ 0x9174, 0x10d2,
+ 0x9175, 0x10cf,
+ 0x9176, 0x3e9b,
+ 0x9177, 0x10d1,
+ 0x9178, 0x10d0,
+ 0x9179, 0x282d,
+ 0x917a, 0x282b,
+ 0x917c, 0x3f6f,
+ 0x9180, 0x2a8e,
+ 0x9181, 0x2a8b,
+ 0x9183, 0x1253,
+ 0x9184, 0x2a8d,
+ 0x9185, 0x2a88,
+ 0x9187, 0x1250,
+ 0x9189, 0x1251,
+ 0x918a, 0x2a8a,
+ 0x918b, 0x1252,
+ 0x918c, 0x43ec,
+ 0x918d, 0x2cc0,
+ 0x918e, 0x3f4e,
+ 0x918f, 0x2cc1,
+ 0x9190, 0x2cbe,
+ 0x9192, 0x1374,
+ 0x9193, 0x2cbd,
+ 0x9199, 0x2e83,
+ 0x919a, 0x2e80,
+ 0x919b, 0x2e82,
+ 0x919c, 0x149b,
+ 0x919d, 0x2e86,
+ 0x919e, 0x149a,
+ 0x919f, 0x2e84,
+ 0x91a0, 0x2e87,
+ 0x91a1, 0x2e85,
+ 0x91a2, 0x2e81,
+ 0x91a3, 0x1499,
+ 0x91a5, 0x3000,
+ 0x91a7, 0x3001,
+ 0x91a8, 0x2fff,
+ 0x91a9, 0x3883,
+ 0x91aa, 0x3003,
+ 0x91ab, 0x153c,
+ 0x91ad, 0x314a,
+ 0x91ae, 0x15dc,
+ 0x91af, 0x3002,
+ 0x91b0, 0x3149,
+ 0x91b1, 0x15db,
+ 0x91b2, 0x324c,
+ 0x91b4, 0x1650,
+ 0x91b5, 0x324b,
+ 0x91b6, 0x45ef,
+ 0x91b7, 0x324a,
+ 0x91b9, 0x3321,
+ 0x91ba, 0x1698,
+ 0x91bb, 0x3bc8,
+ 0x91bc, 0x3446,
+ 0x91bd, 0x34a3,
+ 0x91be, 0x34a2,
+ 0x91c0, 0x1730,
+ 0x91c1, 0x174a,
+ 0x91c2, 0x34a4,
+ 0x91c3, 0x350b,
+ 0x91c4, 0x3884,
+ 0x91c5, 0x175c,
+ 0x91c6, 0x0521,
+ 0x91c7, 0x0695,
+ 0x91c9, 0x0f4a,
+ 0x91cb, 0x1651,
+ 0x91cc, 0x0522,
+ 0x91cd, 0x0820,
+ 0x91ce, 0x0bc9,
+ 0x91cf, 0x0d8e,
+ 0x91d0, 0x153e,
+ 0x91d1, 0x0696,
+ 0x91d3, 0x1c15,
+ 0x91d4, 0x1c14,
+ 0x91d5, 0x1e2c,
+ 0x91d6, 0x415e,
+ 0x91d7, 0x09e7,
+ 0x91d8, 0x09e5,
+ 0x91d9, 0x09e9,
+ 0x91da, 0x1e2e,
+ 0x91dc, 0x09e8,
+ 0x91dd, 0x09e6,
+ 0x91df, 0x453a,
+ 0x91e2, 0x1e2d,
+ 0x91e3, 0x0bcc,
+ 0x91e4, 0x209a,
+ 0x91e5, 0x3c06,
+ 0x91e6, 0x0bcb,
+ 0x91e7, 0x0bcd,
+ 0x91e8, 0x209f,
+ 0x91e9, 0x0bcf,
+ 0x91ea, 0x209c,
+ 0x91ec, 0x2095,
+ 0x91ed, 0x0bce,
+ 0x91ee, 0x20a0,
+ 0x91f1, 0x2097,
+ 0x91f3, 0x2098,
+ 0x91f4, 0x2096,
+ 0x91f5, 0x0bca,
+ 0x91f7, 0x209e,
+ 0x91f8, 0x2099,
+ 0x91f9, 0x209b,
+ 0x91fa, 0x3af8,
+ 0x91fd, 0x233f,
+ 0x91fe, 0x382e,
+ 0x91ff, 0x233e,
+ 0x9200, 0x233c,
+ 0x9201, 0x2334,
+ 0x9202, 0x2343,
+ 0x9203, 0x2337,
+ 0x9204, 0x2341,
+ 0x9205, 0x2348,
+ 0x9206, 0x2340,
+ 0x9207, 0x0d96,
+ 0x9208, 0x3eb9,
+ 0x9209, 0x0d92,
+ 0x920a, 0x2335,
+ 0x920c, 0x233b,
+ 0x920d, 0x0d94,
+ 0x920e, 0x3888,
+ 0x920f, 0x233a,
+ 0x9210, 0x0d95,
+ 0x9211, 0x0d97,
+ 0x9212, 0x233d,
+ 0x9213, 0x4793,
+ 0x9214, 0x0d8f,
+ 0x9216, 0x2349,
+ 0x9217, 0x2347,
+ 0x9219, 0x2346,
+ 0x921a, 0x2338,
+ 0x921c, 0x2344,
+ 0x921e, 0x0d93,
+ 0x9223, 0x0d91,
+ 0x9224, 0x2345,
+ 0x9225, 0x2336,
+ 0x9226, 0x2339,
+ 0x9227, 0x2342,
+ 0x9228, 0x4795,
+ 0x922a, 0x3c0e,
+ 0x922b, 0x3ba6,
+ 0x922d, 0x2851,
+ 0x922e, 0x25da,
+ 0x9230, 0x25d3,
+ 0x9231, 0x25e6,
+ 0x9232, 0x25ef,
+ 0x9233, 0x25d6,
+ 0x9234, 0x0f55,
+ 0x9235, 0x3b26,
+ 0x9236, 0x25e3,
+ 0x9237, 0x0f4b,
+ 0x9238, 0x0f4d,
+ 0x9239, 0x0f59,
+ 0x923a, 0x25d4,
+ 0x923c, 0x41d2,
+ 0x923d, 0x0f4e,
+ 0x923e, 0x0f50,
+ 0x923f, 0x0f5a,
+ 0x9240, 0x0f4f,
+ 0x9241, 0x388a,
+ 0x9244, 0x389a,
+ 0x9245, 0x0f58,
+ 0x9246, 0x25dc,
+ 0x9248, 0x25d1,
+ 0x9249, 0x0f56,
+ 0x924a, 0x25db,
+ 0x924b, 0x0f52,
+ 0x924c, 0x25ed,
+ 0x924d, 0x0f57,
+ 0x924e, 0x25eb,
+ 0x924f, 0x25df,
+ 0x9250, 0x25e9,
+ 0x9251, 0x0f54,
+ 0x9252, 0x25d2,
+ 0x9253, 0x25ec,
+ 0x9254, 0x25e7,
+ 0x9255, 0x3e47,
+ 0x9256, 0x25ee,
+ 0x9257, 0x0f4c,
+ 0x9258, 0x4796,
+ 0x925a, 0x0f5b,
+ 0x925b, 0x0f51,
+ 0x925d, 0x3a03,
+ 0x925e, 0x25d8,
+ 0x925f, 0x3ce0,
+ 0x9260, 0x25e0,
+ 0x9261, 0x25e4,
+ 0x9262, 0x388b,
+ 0x9263, 0x25e8,
+ 0x9264, 0x0f53,
+ 0x9265, 0x25d7,
+ 0x9266, 0x25d5,
+ 0x9267, 0x25e1,
+ 0x926b, 0x4797,
+ 0x926c, 0x25de,
+ 0x926d, 0x25dd,
+ 0x926e, 0x3d05,
+ 0x926f, 0x25e2,
+ 0x9270, 0x25e5,
+ 0x9272, 0x25ea,
+ 0x9276, 0x2831,
+ 0x9277, 0x3c64,
+ 0x9278, 0x10d3,
+ 0x9279, 0x283b,
+ 0x927a, 0x2833,
+ 0x927b, 0x10d9,
+ 0x927c, 0x10dd,
+ 0x927d, 0x2844,
+ 0x927e, 0x284c,
+ 0x927f, 0x283d,
+ 0x9280, 0x10d5,
+ 0x9281, 0x3e01,
+ 0x9282, 0x2841,
+ 0x9283, 0x25d9,
+ 0x9284, 0x3cb9,
+ 0x9285, 0x10d6,
+ 0x9286, 0x2848,
+ 0x9287, 0x284d,
+ 0x9288, 0x2845,
+ 0x9289, 0x3ab5,
+ 0x928a, 0x2847,
+ 0x928b, 0x2850,
+ 0x928c, 0x2849,
+ 0x928d, 0x2837,
+ 0x928e, 0x2840,
+ 0x928f, 0x46bd,
+ 0x9291, 0x10de,
+ 0x9293, 0x10da,
+ 0x9294, 0x2835,
+ 0x9295, 0x2842,
+ 0x9296, 0x10d8,
+ 0x9297, 0x283c,
+ 0x9298, 0x10d7,
+ 0x9299, 0x284a,
+ 0x929a, 0x2839,
+ 0x929b, 0x2832,
+ 0x929c, 0x10db,
+ 0x929d, 0x284f,
+ 0x92a0, 0x2834,
+ 0x92a1, 0x2846,
+ 0x92a2, 0x2843,
+ 0x92a3, 0x283e,
+ 0x92a4, 0x2830,
+ 0x92a5, 0x282f,
+ 0x92a6, 0x2838,
+ 0x92a7, 0x284b,
+ 0x92a8, 0x10dc,
+ 0x92a9, 0x284e,
+ 0x92aa, 0x2836,
+ 0x92ab, 0x283a,
+ 0x92ac, 0x10d4,
+ 0x92ae, 0x4799,
+ 0x92b1, 0x4798,
+ 0x92b2, 0x125f,
+ 0x92b3, 0x125a,
+ 0x92b4, 0x2ab0,
+ 0x92b5, 0x2aac,
+ 0x92b6, 0x2a94,
+ 0x92b7, 0x1256,
+ 0x92b9, 0x36e9,
+ 0x92ba, 0x3bf5,
+ 0x92bb, 0x1255,
+ 0x92bc, 0x125b,
+ 0x92be, 0x3c60,
+ 0x92bf, 0x479a,
+ 0x92c0, 0x2a92,
+ 0x92c1, 0x1259,
+ 0x92c2, 0x2a9e,
+ 0x92c3, 0x2a90,
+ 0x92c5, 0x1254,
+ 0x92c6, 0x2aaf,
+ 0x92c7, 0x125d,
+ 0x92c8, 0x2aa1,
+ 0x92c9, 0x2aa6,
+ 0x92ca, 0x2aa0,
+ 0x92cb, 0x2cd3,
+ 0x92cc, 0x2a9c,
+ 0x92cd, 0x2aa4,
+ 0x92ce, 0x2aa2,
+ 0x92cf, 0x2a95,
+ 0x92d0, 0x2a8f,
+ 0x92d1, 0x2aaa,
+ 0x92d2, 0x125c,
+ 0x92d3, 0x2aab,
+ 0x92d4, 0x3861,
+ 0x92d5, 0x2aa5,
+ 0x92d7, 0x2a9a,
+ 0x92d8, 0x2a98,
+ 0x92d9, 0x2a93,
+ 0x92db, 0x400c,
+ 0x92dd, 0x2a9b,
+ 0x92de, 0x2aa8,
+ 0x92df, 0x2a97,
+ 0x92e0, 0x2aa7,
+ 0x92e1, 0x2aad,
+ 0x92e3, 0x479b,
+ 0x92e4, 0x1258,
+ 0x92e5, 0x3ca2,
+ 0x92e6, 0x2aa3,
+ 0x92e7, 0x2aa9,
+ 0x92e8, 0x2a9f,
+ 0x92e9, 0x2a99,
+ 0x92ea, 0x1257,
+ 0x92eb, 0x479c,
+ 0x92ec, 0x3964,
+ 0x92ee, 0x283f,
+ 0x92ef, 0x2a9d,
+ 0x92f0, 0x125e,
+ 0x92f1, 0x2a96,
+ 0x92f2, 0x3ab2,
+ 0x92f3, 0x479d,
+ 0x92f6, 0x3c04,
+ 0x92f7, 0x2cd8,
+ 0x92f8, 0x1377,
+ 0x92f9, 0x2cd7,
+ 0x92fa, 0x2cd5,
+ 0x92fb, 0x2ce7,
+ 0x92fc, 0x137b,
+ 0x92fd, 0x479f,
+ 0x92fe, 0x2ce4,
+ 0x92ff, 0x2cdc,
+ 0x9300, 0x2ce6,
+ 0x9301, 0x2cce,
+ 0x9302, 0x2cda,
+ 0x9303, 0x3867,
+ 0x9304, 0x137d,
+ 0x9306, 0x2cc6,
+ 0x9307, 0x3b11,
+ 0x9308, 0x2cc4,
+ 0x9309, 0x2ce5,
+ 0x930b, 0x2ce3,
+ 0x930c, 0x2ce2,
+ 0x930d, 0x2cd2,
+ 0x930e, 0x2cd1,
+ 0x930f, 0x2cc7,
+ 0x9310, 0x137f,
+ 0x9312, 0x2ccd,
+ 0x9313, 0x2cd6,
+ 0x9314, 0x2ce1,
+ 0x9315, 0x1382,
+ 0x9316, 0x2ce8,
+ 0x9318, 0x14a3,
+ 0x9319, 0x1384,
+ 0x931a, 0x137e,
+ 0x931b, 0x2ccb,
+ 0x931d, 0x2cd4,
+ 0x931e, 0x2cc3,
+ 0x931f, 0x2cc5,
+ 0x9320, 0x1375,
+ 0x9321, 0x1381,
+ 0x9322, 0x137a,
+ 0x9323, 0x2ccc,
+ 0x9324, 0x2cdb,
+ 0x9325, 0x2aae,
+ 0x9326, 0x1380,
+ 0x9327, 0x2cc2,
+ 0x9328, 0x149e,
+ 0x9329, 0x2cdd,
+ 0x932a, 0x2ce0,
+ 0x932b, 0x137c,
+ 0x932c, 0x3892,
+ 0x932d, 0x2cd0,
+ 0x932e, 0x1383,
+ 0x932f, 0x1379,
+ 0x9330, 0x3e03,
+ 0x9331, 0x3cbd,
+ 0x9333, 0x1378,
+ 0x9334, 0x2cd9,
+ 0x9335, 0x2cdf,
+ 0x9336, 0x1376,
+ 0x9338, 0x2cc9,
+ 0x9339, 0x2cde,
+ 0x933c, 0x2cca,
+ 0x9340, 0x4155,
+ 0x9341, 0x4277,
+ 0x9342, 0x3afa,
+ 0x9343, 0x47a0,
+ 0x9344, 0x4016,
+ 0x9345, 0x3e74,
+ 0x9346, 0x2ccf,
+ 0x9347, 0x2e8d,
+ 0x9348, 0x3c61,
+ 0x9349, 0x2e92,
+ 0x934a, 0x14a0,
+ 0x934b, 0x14a2,
+ 0x934c, 0x2e98,
+ 0x934d, 0x149c,
+ 0x934e, 0x2ea6,
+ 0x934f, 0x2e9e,
+ 0x9350, 0x2e93,
+ 0x9352, 0x2e9d,
+ 0x9354, 0x14a9,
+ 0x9355, 0x2e9c,
+ 0x9356, 0x2e8c,
+ 0x9357, 0x2e9b,
+ 0x9358, 0x2e8f,
+ 0x9359, 0x2ea7,
+ 0x935a, 0x14a8,
+ 0x935b, 0x14a6,
+ 0x935c, 0x2e90,
+ 0x935e, 0x2ea3,
+ 0x935f, 0x3cbb,
+ 0x9360, 0x2e95,
+ 0x9361, 0x2ea2,
+ 0x9362, 0x4268,
+ 0x9363, 0x2ea4,
+ 0x9364, 0x2e8b,
+ 0x9365, 0x14a1,
+ 0x9366, 0x46bc,
+ 0x9367, 0x2ea5,
+ 0x9368, 0x3bf0,
+ 0x9369, 0x3961,
+ 0x936a, 0x2e99,
+ 0x936b, 0x3893,
+ 0x936c, 0x14a5,
+ 0x936d, 0x2e96,
+ 0x936e, 0x39e8,
+ 0x9370, 0x14a7,
+ 0x9371, 0x2e9f,
+ 0x9373, 0x389e,
+ 0x9374, 0x3ce4,
+ 0x9375, 0x149f,
+ 0x9376, 0x2e91,
+ 0x9377, 0x2ea0,
+ 0x9378, 0x38f9,
+ 0x9379, 0x2e9a,
+ 0x937a, 0x2cc8,
+ 0x937b, 0x2ea1,
+ 0x937c, 0x2e8e,
+ 0x937d, 0x3c25,
+ 0x937e, 0x14a4,
+ 0x9380, 0x3014,
+ 0x9381, 0x3965,
+ 0x9382, 0x149d,
+ 0x9383, 0x2e89,
+ 0x9384, 0x47a1,
+ 0x9385, 0x42bd,
+ 0x9386, 0x3cc0,
+ 0x9387, 0x3ae0,
+ 0x9388, 0x3011,
+ 0x9389, 0x300a,
+ 0x938a, 0x1540,
+ 0x938c, 0x3005,
+ 0x938d, 0x3015,
+ 0x938e, 0x300c,
+ 0x938f, 0x2e97,
+ 0x9390, 0x3d3c,
+ 0x9391, 0x3017,
+ 0x9392, 0x3006,
+ 0x9394, 0x153f,
+ 0x9395, 0x3010,
+ 0x9396, 0x1541,
+ 0x9397, 0x1549,
+ 0x9398, 0x1547,
+ 0x9399, 0x3012,
+ 0x939a, 0x1548,
+ 0x939b, 0x3008,
+ 0x939c, 0x39ac,
+ 0x939d, 0x3009,
+ 0x939e, 0x300e,
+ 0x939f, 0x3013,
+ 0x93a0, 0x3ab1,
+ 0x93a1, 0x2e88,
+ 0x93a2, 0x1542,
+ 0x93a3, 0x301c,
+ 0x93a4, 0x3019,
+ 0x93a5, 0x3160,
+ 0x93a6, 0x300f,
+ 0x93a7, 0x300b,
+ 0x93a8, 0x301a,
+ 0x93a9, 0x3155,
+ 0x93aa, 0x300d,
+ 0x93ac, 0x1545,
+ 0x93ad, 0x47a2,
+ 0x93ae, 0x1544,
+ 0x93af, 0x2e8a,
+ 0x93b0, 0x1546,
+ 0x93b1, 0x3016,
+ 0x93b2, 0x3018,
+ 0x93b3, 0x1543,
+ 0x93b4, 0x301b,
+ 0x93b5, 0x3004,
+ 0x93b7, 0x3007,
+ 0x93b8, 0x3c90,
+ 0x93ba, 0x43f7,
+ 0x93bb, 0x3c8f,
+ 0x93bd, 0x3a27,
+ 0x93bf, 0x3e2d,
+ 0x93c0, 0x315e,
+ 0x93c2, 0x314e,
+ 0x93c3, 0x15e0,
+ 0x93c4, 0x315c,
+ 0x93c6, 0x39aa,
+ 0x93c7, 0x314c,
+ 0x93c8, 0x15e1,
+ 0x93ca, 0x3157,
+ 0x93cb, 0x3966,
+ 0x93cc, 0x3153,
+ 0x93cd, 0x15e6,
+ 0x93ce, 0x315d,
+ 0x93cf, 0x314d,
+ 0x93d0, 0x3150,
+ 0x93d1, 0x15de,
+ 0x93d2, 0x315f,
+ 0x93d3, 0x40e1,
+ 0x93d4, 0x3158,
+ 0x93d5, 0x315b,
+ 0x93d6, 0x15e4,
+ 0x93d7, 0x15e9,
+ 0x93d8, 0x15e7,
+ 0x93d9, 0x3154,
+ 0x93da, 0x314f,
+ 0x93db, 0x3c5f,
+ 0x93dc, 0x15e2,
+ 0x93de, 0x314b,
+ 0x93df, 0x15df,
+ 0x93e0, 0x3a20,
+ 0x93e1, 0x15dd,
+ 0x93e2, 0x15e5,
+ 0x93e3, 0x315a,
+ 0x93e4, 0x15e8,
+ 0x93e6, 0x3156,
+ 0x93e7, 0x3161,
+ 0x93e8, 0x15ea,
+ 0x93ec, 0x3152,
+ 0x93ee, 0x3159,
+ 0x93f0, 0x423f,
+ 0x93f1, 0x42aa,
+ 0x93f3, 0x3962,
+ 0x93f5, 0x325a,
+ 0x93f6, 0x3269,
+ 0x93f7, 0x325c,
+ 0x93f8, 0x3263,
+ 0x93f9, 0x3151,
+ 0x93fa, 0x3261,
+ 0x93fb, 0x3250,
+ 0x93fc, 0x3267,
+ 0x93fd, 0x1654,
+ 0x93fe, 0x3254,
+ 0x93ff, 0x3266,
+ 0x9400, 0x325b,
+ 0x9401, 0x3cd4,
+ 0x9403, 0x1653,
+ 0x9404, 0x3bc9,
+ 0x9406, 0x326b,
+ 0x9407, 0x325d,
+ 0x9408, 0x3a25,
+ 0x9409, 0x3262,
+ 0x940a, 0x3265,
+ 0x940b, 0x324e,
+ 0x940c, 0x3268,
+ 0x940d, 0x3259,
+ 0x940e, 0x325e,
+ 0x940f, 0x3252,
+ 0x9410, 0x3256,
+ 0x9411, 0x326a,
+ 0x9412, 0x3260,
+ 0x9413, 0x324f,
+ 0x9414, 0x3253,
+ 0x9415, 0x3255,
+ 0x9416, 0x325f,
+ 0x9417, 0x47a5,
+ 0x9418, 0x1652,
+ 0x9419, 0x3258,
+ 0x941b, 0x4148,
+ 0x941d, 0x47a6,
+ 0x9420, 0x3251,
+ 0x9424, 0x3943,
+ 0x9425, 0x38d0,
+ 0x9426, 0x38a3,
+ 0x9427, 0x3bcd,
+ 0x9428, 0x3257,
+ 0x9429, 0x3325,
+ 0x942a, 0x3329,
+ 0x942b, 0x169f,
+ 0x942c, 0x332b,
+ 0x942d, 0x47a7,
+ 0x942e, 0x1699,
+ 0x9430, 0x3327,
+ 0x9431, 0x332d,
+ 0x9432, 0x169e,
+ 0x9433, 0x169a,
+ 0x9435, 0x169b,
+ 0x9436, 0x3324,
+ 0x9437, 0x332a,
+ 0x9438, 0x169d,
+ 0x9439, 0x3328,
+ 0x943a, 0x169c,
+ 0x943b, 0x3323,
+ 0x943c, 0x3264,
+ 0x943d, 0x3326,
+ 0x943e, 0x47a8,
+ 0x943f, 0x3322,
+ 0x9440, 0x332c,
+ 0x9442, 0x4272,
+ 0x9443, 0x4275,
+ 0x9444, 0x16df,
+ 0x9445, 0x33cd,
+ 0x9446, 0x33d0,
+ 0x9447, 0x33cc,
+ 0x9448, 0x33ce,
+ 0x944a, 0x33c9,
+ 0x944c, 0x33c7,
+ 0x944d, 0x3c65,
+ 0x944f, 0x33cb,
+ 0x9450, 0x33c8,
+ 0x9451, 0x16e0,
+ 0x9454, 0x47aa,
+ 0x9455, 0x3448,
+ 0x9457, 0x344a,
+ 0x9458, 0x3c30,
+ 0x945b, 0x389f,
+ 0x945d, 0x3449,
+ 0x945e, 0x344b,
+ 0x9460, 0x170e,
+ 0x9462, 0x3447,
+ 0x9463, 0x170d,
+ 0x9464, 0x170f,
+ 0x9465, 0x3dde,
+ 0x9467, 0x3ab8,
+ 0x9468, 0x34a6,
+ 0x946a, 0x1731,
+ 0x946b, 0x34a5,
+ 0x946c, 0x377e,
+ 0x946d, 0x34ed,
+ 0x946e, 0x34ec,
+ 0x946f, 0x34ee,
+ 0x9470, 0x174c,
+ 0x9471, 0x34ef,
+ 0x9472, 0x174b,
+ 0x9473, 0x34f0,
+ 0x9474, 0x350c,
+ 0x9475, 0x350f,
+ 0x9476, 0x350e,
+ 0x9477, 0x1755,
+ 0x9478, 0x350d,
+ 0x9479, 0x47ab,
+ 0x947b, 0x419b,
+ 0x947c, 0x175f,
+ 0x947d, 0x175d,
+ 0x947f, 0x1764,
+ 0x9480, 0x3539,
+ 0x9482, 0x3538,
+ 0x9483, 0x3540,
+ 0x9485, 0x4507,
+ 0x949f, 0x4885,
+ 0x94a2, 0x451b,
+ 0x94c1, 0x47e1,
+ 0x94c3, 0x47df,
+ 0x94dc, 0x47d7,
+ 0x94f6, 0x47d2,
+ 0x952d, 0x47ac,
+ 0x9547, 0x48bf,
+ 0x9577, 0x0697,
+ 0x9578, 0x4508,
+ 0x957a, 0x20a1,
+ 0x957b, 0x234a,
+ 0x957c, 0x2ab1,
+ 0x957d, 0x3162,
+ 0x957f, 0x4509,
+ 0x9580, 0x0698,
+ 0x9582, 0x0821,
+ 0x9583, 0x09ea,
+ 0x9585, 0x38a1,
+ 0x9586, 0x20a2,
+ 0x9588, 0x20a3,
+ 0x9589, 0x0bd0,
+ 0x958b, 0x0d9a,
+ 0x958c, 0x234c,
+ 0x958d, 0x234b,
+ 0x958e, 0x0d9e,
+ 0x958f, 0x0d99,
+ 0x9590, 0x234d,
+ 0x9591, 0x0d9b,
+ 0x9592, 0x0d9d,
+ 0x9593, 0x0d9c,
+ 0x9594, 0x0d98,
+ 0x9596, 0x3bd5,
+ 0x9597, 0x3bd4,
+ 0x9598, 0x0f5c,
+ 0x9599, 0x3bd2,
+ 0x959b, 0x25f3,
+ 0x959c, 0x25f1,
+ 0x959e, 0x25f2,
+ 0x959f, 0x25f0,
+ 0x95a0, 0x38a4,
+ 0x95a1, 0x10df,
+ 0x95a2, 0x47ad,
+ 0x95a3, 0x10e2,
+ 0x95a4, 0x10e4,
+ 0x95a5, 0x10e3,
+ 0x95a6, 0x38a2,
+ 0x95a7, 0x3bd3,
+ 0x95a8, 0x10e0,
+ 0x95aa, 0x4395,
+ 0x95ab, 0x2ab3,
+ 0x95ac, 0x2ab2,
+ 0x95ad, 0x1260,
+ 0x95ae, 0x2ab4,
+ 0x95b0, 0x2ab5,
+ 0x95b1, 0x1261,
+ 0x95b5, 0x2cf0,
+ 0x95b6, 0x2cee,
+ 0x95b7, 0x2ead,
+ 0x95b9, 0x2cec,
+ 0x95bb, 0x1385,
+ 0x95bc, 0x2ce9,
+ 0x95bd, 0x2cf1,
+ 0x95be, 0x2ceb,
+ 0x95bf, 0x2cef,
+ 0x95c0, 0x2ea9,
+ 0x95c3, 0x2eab,
+ 0x95c5, 0x2eac,
+ 0x95c6, 0x14ae,
+ 0x95c7, 0x2ea8,
+ 0x95c8, 0x14ad,
+ 0x95c9, 0x2eaa,
+ 0x95ca, 0x14aa,
+ 0x95cd, 0x2cea,
+ 0x95d0, 0x154c,
+ 0x95d1, 0x301f,
+ 0x95d2, 0x301d,
+ 0x95d4, 0x154a,
+ 0x95d5, 0x154d,
+ 0x95d6, 0x154b,
+ 0x95da, 0x3163,
+ 0x95dc, 0x15eb,
+ 0x95de, 0x326c,
+ 0x95df, 0x326e,
+ 0x95e0, 0x326d,
+ 0x95e1, 0x1655,
+ 0x95e2, 0x16a0,
+ 0x95e3, 0x3330,
+ 0x95e4, 0x332f,
+ 0x95e5, 0x332e,
+ 0x95e8, 0x450a,
+ 0x95f4, 0x47af,
+ 0x961c, 0x0699,
+ 0x961d, 0x4519,
+ 0x961e, 0x17b4,
+ 0x9620, 0x1821,
+ 0x9621, 0x0414,
+ 0x9622, 0x181f,
+ 0x9623, 0x1822,
+ 0x9624, 0x1820,
+ 0x9628, 0x18f1,
+ 0x962a, 0x0526,
+ 0x962c, 0x0527,
+ 0x962d, 0x18f3,
+ 0x962e, 0x0524,
+ 0x962f, 0x18f2,
+ 0x9630, 0x18f0,
+ 0x9631, 0x0525,
+ 0x9632, 0x0523,
+ 0x9633, 0x47b0,
+ 0x9638, 0x3fd1,
+ 0x9639, 0x1a55,
+ 0x963a, 0x1a58,
+ 0x963b, 0x069c,
+ 0x963c, 0x1a57,
+ 0x963d, 0x1a56,
+ 0x963f, 0x069b,
+ 0x9640, 0x069a,
+ 0x9641, 0x3f3d,
+ 0x9642, 0x069e,
+ 0x9643, 0x1a59,
+ 0x9644, 0x069d,
+ 0x9645, 0x4772,
+ 0x964a, 0x1c1a,
+ 0x964b, 0x0823,
+ 0x964e, 0x1c1b,
+ 0x964f, 0x1c17,
+ 0x9650, 0x0822,
+ 0x9651, 0x1c18,
+ 0x9653, 0x1c19,
+ 0x9654, 0x1c16,
+ 0x9656, 0x3de7,
+ 0x9658, 0x09f1,
+ 0x965b, 0x09ee,
+ 0x965c, 0x1e2f,
+ 0x965d, 0x09ef,
+ 0x965e, 0x09f2,
+ 0x965f, 0x1e30,
+ 0x9661, 0x09ed,
+ 0x9662, 0x09eb,
+ 0x9664, 0x09f0,
+ 0x9669, 0x475e,
+ 0x966a, 0x0bd1,
+ 0x966b, 0x20a6,
+ 0x966c, 0x0bd9,
+ 0x966d, 0x20a5,
+ 0x966f, 0x20a8,
+ 0x9670, 0x0bd5,
+ 0x9671, 0x20a7,
+ 0x9672, 0x0da6,
+ 0x9673, 0x0bd3,
+ 0x9674, 0x0bd6,
+ 0x9675, 0x0bd2,
+ 0x9676, 0x0bd7,
+ 0x9678, 0x0bd4,
+ 0x967b, 0x38ac,
+ 0x967c, 0x20a4,
+ 0x967d, 0x0da2,
+ 0x967e, 0x234f,
+ 0x9680, 0x2353,
+ 0x9681, 0x3f46,
+ 0x9683, 0x2352,
+ 0x9684, 0x0da7,
+ 0x9685, 0x0da3,
+ 0x9687, 0x234e,
+ 0x9688, 0x2350,
+ 0x968a, 0x0d9f,
+ 0x968b, 0x0da1,
+ 0x968d, 0x0da5,
+ 0x968e, 0x0da0,
+ 0x968f, 0x3bde,
+ 0x9691, 0x25f6,
+ 0x9692, 0x25f4,
+ 0x9694, 0x0f5e,
+ 0x9696, 0x38ad,
+ 0x9697, 0x25f7,
+ 0x9698, 0x0f5d,
+ 0x9699, 0x10e5,
+ 0x969b, 0x10e7,
+ 0x969c, 0x10e6,
+ 0x969e, 0x2852,
+ 0x96a1, 0x2853,
+ 0x96a2, 0x2ab7,
+ 0x96a3, 0x38af,
+ 0x96a4, 0x2ab6,
+ 0x96a5, 0x42ef,
+ 0x96a7, 0x1386,
+ 0x96a9, 0x2cf2,
+ 0x96aa, 0x1388,
+ 0x96ac, 0x2eb0,
+ 0x96ae, 0x2eae,
+ 0x96b0, 0x2eaf,
+ 0x96b1, 0x14af,
+ 0x96b3, 0x3020,
+ 0x96b4, 0x15ec,
+ 0x96b6, 0x0231,
+ 0x96b8, 0x14b0,
+ 0x96b9, 0x069f,
+ 0x96bb, 0x09f3,
+ 0x96bc, 0x1e31,
+ 0x96bd, 0x38b5,
+ 0x96bf, 0x20a9,
+ 0x96c0, 0x0bda,
+ 0x96c1, 0x0da8,
+ 0x96c2, 0x2354,
+ 0x96c3, 0x2356,
+ 0x96c4, 0x0daa,
+ 0x96c5, 0x0da9,
+ 0x96c6, 0x0dab,
+ 0x96c8, 0x2355,
+ 0x96c9, 0x0f62,
+ 0x96cb, 0x0f61,
+ 0x96cc, 0x10e8,
+ 0x96cd, 0x0f60,
+ 0x96ce, 0x25f8,
+ 0x96d2, 0x10e9,
+ 0x96d3, 0x2ab8,
+ 0x96d4, 0x2cf3,
+ 0x96d5, 0x1389,
+ 0x96d6, 0x14b1,
+ 0x96d7, 0x3021,
+ 0x96d8, 0x3025,
+ 0x96d9, 0x1550,
+ 0x96da, 0x3022,
+ 0x96db, 0x1551,
+ 0x96dc, 0x154f,
+ 0x96dd, 0x3026,
+ 0x96de, 0x1552,
+ 0x96df, 0x3024,
+ 0x96e1, 0x3165,
+ 0x96e2, 0x154e,
+ 0x96e3, 0x15ed,
+ 0x96e5, 0x34a8,
+ 0x96e8, 0x06a0,
+ 0x96e9, 0x0bdc,
+ 0x96ea, 0x0bdb,
+ 0x96ef, 0x0dad,
+ 0x96f0, 0x2358,
+ 0x96f1, 0x2357,
+ 0x96f2, 0x0dae,
+ 0x96f4, 0x3a04,
+ 0x96f5, 0x25fc,
+ 0x96f6, 0x0f67,
+ 0x96f7, 0x0f64,
+ 0x96f8, 0x25fb,
+ 0x96f9, 0x0f66,
+ 0x96fa, 0x25f9,
+ 0x96fb, 0x0f65,
+ 0x96fd, 0x25fa,
+ 0x96ff, 0x2854,
+ 0x9700, 0x10ea,
+ 0x9702, 0x2abb,
+ 0x9703, 0x3f0d,
+ 0x9704, 0x1262,
+ 0x9705, 0x2ab9,
+ 0x9706, 0x1263,
+ 0x9708, 0x2aba,
+ 0x9709, 0x1265,
+ 0x970b, 0x2cf4,
+ 0x970d, 0x138d,
+ 0x970e, 0x138a,
+ 0x970f, 0x138f,
+ 0x9710, 0x2cf6,
+ 0x9711, 0x138b,
+ 0x9712, 0x2cf5,
+ 0x9713, 0x138e,
+ 0x9716, 0x138c,
+ 0x9718, 0x2eb3,
+ 0x9719, 0x2eb5,
+ 0x971b, 0x38c9,
+ 0x971c, 0x14b2,
+ 0x971d, 0x2eb4,
+ 0x971e, 0x14b3,
+ 0x971f, 0x2eb2,
+ 0x9720, 0x2eb1,
+ 0x9721, 0x3fb3,
+ 0x9722, 0x3028,
+ 0x9723, 0x3027,
+ 0x9724, 0x1553,
+ 0x9725, 0x3029,
+ 0x9726, 0x316a,
+ 0x9727, 0x15ef,
+ 0x9728, 0x3169,
+ 0x9729, 0x3166,
+ 0x972a, 0x15ee,
+ 0x972b, 0x3167,
+ 0x972e, 0x326f,
+ 0x9730, 0x1656,
+ 0x9731, 0x38c0,
+ 0x9732, 0x16a3,
+ 0x9735, 0x3331,
+ 0x9736, 0x38c2,
+ 0x9738, 0x16a1,
+ 0x973a, 0x3332,
+ 0x973d, 0x16e2,
+ 0x973f, 0x33d1,
+ 0x9740, 0x47b3,
+ 0x9741, 0x3be9,
+ 0x9742, 0x1732,
+ 0x9743, 0x34aa,
+ 0x9744, 0x1734,
+ 0x9746, 0x34a9,
+ 0x9747, 0x34ab,
+ 0x9748, 0x1733,
+ 0x9749, 0x34f1,
+ 0x974b, 0x3526,
+ 0x9751, 0x44e3,
+ 0x9752, 0x06a1,
+ 0x9756, 0x0f68,
+ 0x9757, 0x38cc,
+ 0x9758, 0x2855,
+ 0x975a, 0x2abc,
+ 0x975b, 0x1390,
+ 0x975d, 0x3bef,
+ 0x975e, 0x06a2,
+ 0x975f, 0x38cf,
+ 0x9760, 0x1266,
+ 0x9761, 0x15f0,
+ 0x9762, 0x0826,
+ 0x9766, 0x1392,
+ 0x9768, 0x1710,
+ 0x9769, 0x0827,
+ 0x976a, 0x20aa,
+ 0x976c, 0x2359,
+ 0x976d, 0x3e97,
+ 0x976e, 0x235b,
+ 0x9770, 0x235a,
+ 0x9771, 0x3bfc,
+ 0x9772, 0x2600,
+ 0x9773, 0x25fd,
+ 0x9774, 0x0f69,
+ 0x9776, 0x0f6a,
+ 0x9777, 0x25fe,
+ 0x977a, 0x2857,
+ 0x977b, 0x285c,
+ 0x977c, 0x10eb,
+ 0x977d, 0x2856,
+ 0x977e, 0x2858,
+ 0x977f, 0x285f,
+ 0x9780, 0x285a,
+ 0x9781, 0x285e,
+ 0x9782, 0x285b,
+ 0x9783, 0x2859,
+ 0x9784, 0x285d,
+ 0x9785, 0x10ec,
+ 0x9787, 0x40c0,
+ 0x9788, 0x2abf,
+ 0x9789, 0x38d4,
+ 0x978a, 0x2abd,
+ 0x978b, 0x1268,
+ 0x978d, 0x1267,
+ 0x978e, 0x2abe,
+ 0x978f, 0x1269,
+ 0x9794, 0x2cf9,
+ 0x9797, 0x2cf8,
+ 0x9798, 0x1393,
+ 0x9799, 0x2cf7,
+ 0x979a, 0x2eb6,
+ 0x979b, 0x3bfb,
+ 0x979c, 0x2eb8,
+ 0x979d, 0x2eba,
+ 0x979e, 0x2eb9,
+ 0x979f, 0x38d5,
+ 0x97a0, 0x14b4,
+ 0x97a1, 0x2eb7,
+ 0x97a2, 0x3030,
+ 0x97a3, 0x1554,
+ 0x97a4, 0x302e,
+ 0x97a5, 0x3031,
+ 0x97a6, 0x1555,
+ 0x97a8, 0x302c,
+ 0x97aa, 0x302f,
+ 0x97ab, 0x302d,
+ 0x97ac, 0x302a,
+ 0x97ad, 0x1556,
+ 0x97ae, 0x302b,
+ 0x97b1, 0x38d6,
+ 0x97b2, 0x47b5,
+ 0x97b3, 0x316b,
+ 0x97b4, 0x3f33,
+ 0x97b6, 0x316d,
+ 0x97b7, 0x316c,
+ 0x97b8, 0x3d95,
+ 0x97b9, 0x3271,
+ 0x97ba, 0x3f35,
+ 0x97bb, 0x3272,
+ 0x97bd, 0x494e,
+ 0x97be, 0x38d7,
+ 0x97bf, 0x3333,
+ 0x97c0, 0x38d8,
+ 0x97c1, 0x16e5,
+ 0x97c2, 0x47b6,
+ 0x97c3, 0x16e4,
+ 0x97c4, 0x344c,
+ 0x97c6, 0x1735,
+ 0x97c7, 0x34ac,
+ 0x97c8, 0x3f2f,
+ 0x97c9, 0x1756,
+ 0x97cb, 0x0828,
+ 0x97cc, 0x0daf,
+ 0x97cd, 0x2861,
+ 0x97ce, 0x2860,
+ 0x97cf, 0x2ac1,
+ 0x97d0, 0x2ac0,
+ 0x97d2, 0x38d9,
+ 0x97d3, 0x14b5,
+ 0x97d4, 0x2ebc,
+ 0x97d5, 0x2ebb,
+ 0x97d6, 0x3034,
+ 0x97d7, 0x3032,
+ 0x97d8, 0x3035,
+ 0x97d9, 0x3033,
+ 0x97dc, 0x15f1,
+ 0x97dd, 0x316e,
+ 0x97e0, 0x38da,
+ 0x97e1, 0x3334,
+ 0x97e3, 0x33d2,
+ 0x97e5, 0x34ad,
+ 0x97e6, 0x450c,
+ 0x97ed, 0x0829,
+ 0x97ee, 0x38dc,
+ 0x97f0, 0x2cfa,
+ 0x97f1, 0x2ebd,
+ 0x97f2, 0x394d,
+ 0x97f3, 0x082a,
+ 0x97f5, 0x38e0,
+ 0x97f6, 0x10ed,
+ 0x97f8, 0x2cfb,
+ 0x97f9, 0x1557,
+ 0x97fa, 0x3036,
+ 0x97fb, 0x15f2,
+ 0x97fd, 0x3273,
+ 0x97ff, 0x16a4,
+ 0x9800, 0x344e,
+ 0x9801, 0x082b,
+ 0x9802, 0x0bdf,
+ 0x9804, 0x20ab,
+ 0x9805, 0x0db0,
+ 0x9807, 0x235c,
+ 0x9808, 0x0db2,
+ 0x980a, 0x0f6e,
+ 0x980c, 0x0f70,
+ 0x980d, 0x2602,
+ 0x980f, 0x2601,
+ 0x9810, 0x0f6b,
+ 0x9812, 0x0f6f,
+ 0x9813, 0x0f6d,
+ 0x9814, 0x4952,
+ 0x9815, 0x433c,
+ 0x9816, 0x2862,
+ 0x9817, 0x10ee,
+ 0x981b, 0x2ac8,
+ 0x981c, 0x126c,
+ 0x981d, 0x2ac3,
+ 0x981e, 0x2ac2,
+ 0x981f, 0x3c02,
+ 0x9820, 0x2ac7,
+ 0x9821, 0x126a,
+ 0x9823, 0x3e37,
+ 0x9824, 0x139a,
+ 0x9826, 0x2ac4,
+ 0x9827, 0x2ac9,
+ 0x9828, 0x2ac6,
+ 0x9829, 0x2ac5,
+ 0x982b, 0x126b,
+ 0x982d, 0x1398,
+ 0x982e, 0x3f72,
+ 0x982f, 0x2cfd,
+ 0x9830, 0x1394,
+ 0x9832, 0x2cfe,
+ 0x9833, 0x38e5,
+ 0x9834, 0x38e4,
+ 0x9835, 0x2cfc,
+ 0x9837, 0x1397,
+ 0x9838, 0x1395,
+ 0x9839, 0x1399,
+ 0x983b, 0x1396,
+ 0x9841, 0x2ebe,
+ 0x9843, 0x2ec3,
+ 0x9844, 0x2ebf,
+ 0x9845, 0x2ec2,
+ 0x9846, 0x14b6,
+ 0x9847, 0x3d96,
+ 0x9848, 0x2df2,
+ 0x9849, 0x2ec1,
+ 0x984a, 0x2ec0,
+ 0x984b, 0x38e6,
+ 0x984c, 0x155a,
+ 0x984d, 0x1558,
+ 0x984e, 0x155b,
+ 0x984f, 0x1559,
+ 0x9850, 0x3037,
+ 0x9853, 0x155c,
+ 0x9857, 0x3174,
+ 0x9858, 0x15f4,
+ 0x9859, 0x3172,
+ 0x985b, 0x15f5,
+ 0x985c, 0x3171,
+ 0x985d, 0x3173,
+ 0x985e, 0x15f3,
+ 0x985f, 0x3278,
+ 0x9860, 0x3275,
+ 0x9862, 0x3276,
+ 0x9864, 0x3335,
+ 0x9865, 0x16a6,
+ 0x9866, 0x38e7,
+ 0x9867, 0x16a5,
+ 0x9869, 0x33d4,
+ 0x986a, 0x33d3,
+ 0x986b, 0x16e6,
+ 0x986c, 0x4035,
+ 0x986f, 0x1711,
+ 0x9870, 0x1736,
+ 0x9871, 0x174d,
+ 0x9872, 0x34f2,
+ 0x9873, 0x3527,
+ 0x9875, 0x450d,
+ 0x98a8, 0x082c,
+ 0x98a9, 0x235d,
+ 0x98ac, 0x2604,
+ 0x98ad, 0x2863,
+ 0x98af, 0x10f0,
+ 0x98b1, 0x10f1,
+ 0x98b2, 0x2aca,
+ 0x98b3, 0x126d,
+ 0x98b4, 0x3f73,
+ 0x98b6, 0x14b7,
+ 0x98b7, 0x38ef,
+ 0x98b8, 0x303a,
+ 0x98b9, 0x47b8,
+ 0x98ba, 0x155d,
+ 0x98bb, 0x3177,
+ 0x98bc, 0x15f6,
+ 0x98bd, 0x3176,
+ 0x98be, 0x3178,
+ 0x98bf, 0x3175,
+ 0x98c0, 0x3338,
+ 0x98c1, 0x3279,
+ 0x98c3, 0x3b78,
+ 0x98c4, 0x1657,
+ 0x98c6, 0x3337,
+ 0x98c7, 0x38f1,
+ 0x98c8, 0x38f0,
+ 0x98c9, 0x3336,
+ 0x98ca, 0x38ee,
+ 0x98cb, 0x33d5,
+ 0x98cc, 0x3529,
+ 0x98ce, 0x450e,
+ 0x98db, 0x082d,
+ 0x98dc, 0x3c0b,
+ 0x98de, 0x450f,
+ 0x98df, 0x082e,
+ 0x98e0, 0x4792,
+ 0x98e1, 0x38f6,
+ 0x98e2, 0x09f4,
+ 0x98e3, 0x1e32,
+ 0x98e5, 0x20ac,
+ 0x98e6, 0x38f7,
+ 0x98e7, 0x0db3,
+ 0x98e9, 0x0db6,
+ 0x98ea, 0x0db4,
+ 0x98eb, 0x235e,
+ 0x98ec, 0x38f8,
+ 0x98ed, 0x0db8,
+ 0x98ef, 0x0db5,
+ 0x98f1, 0x47ba,
+ 0x98f2, 0x0db7,
+ 0x98f4, 0x0f72,
+ 0x98f5, 0x4365,
+ 0x98f6, 0x2605,
+ 0x98f9, 0x2606,
+ 0x98fa, 0x2acc,
+ 0x98fc, 0x0f71,
+ 0x98fd, 0x0f73,
+ 0x9900, 0x2866,
+ 0x9902, 0x2865,
+ 0x9903, 0x10f2,
+ 0x9905, 0x10f3,
+ 0x9907, 0x2867,
+ 0x9908, 0x2acb,
+ 0x9909, 0x10f5,
+ 0x990a, 0x126e,
+ 0x990c, 0x10f4,
+ 0x990e, 0x43ed,
+ 0x9910, 0x139b,
+ 0x9911, 0x2acd,
+ 0x9912, 0x1270,
+ 0x9913, 0x126f,
+ 0x9914, 0x2ace,
+ 0x9915, 0x2ad1,
+ 0x9916, 0x2acf,
+ 0x9918, 0x1271,
+ 0x9919, 0x47bc,
+ 0x991a, 0x13a0,
+ 0x991b, 0x139e,
+ 0x991c, 0x43ee,
+ 0x991e, 0x139d,
+ 0x991f, 0x2d00,
+ 0x9921, 0x139f,
+ 0x9924, 0x2cff,
+ 0x9925, 0x2ec4,
+ 0x9927, 0x2d01,
+ 0x9928, 0x139c,
+ 0x9929, 0x2d02,
+ 0x992a, 0x2ec7,
+ 0x992b, 0x2ec5,
+ 0x992d, 0x2ecb,
+ 0x992e, 0x1561,
+ 0x992f, 0x2eca,
+ 0x9930, 0x2ecd,
+ 0x9931, 0x2ecc,
+ 0x9932, 0x2ec9,
+ 0x9933, 0x2ec8,
+ 0x9935, 0x14b8,
+ 0x9937, 0x47bd,
+ 0x9938, 0x3bfd,
+ 0x9939, 0x38fa,
+ 0x993a, 0x303d,
+ 0x993b, 0x3c11,
+ 0x993c, 0x303c,
+ 0x993d, 0x1560,
+ 0x993e, 0x155e,
+ 0x9940, 0x3f34,
+ 0x9941, 0x303b,
+ 0x9942, 0x43ff,
+ 0x9943, 0x317b,
+ 0x9945, 0x15f7,
+ 0x9947, 0x317a,
+ 0x9948, 0x3179,
+ 0x9949, 0x15f8,
+ 0x994a, 0x3fb9,
+ 0x994b, 0x327f,
+ 0x994c, 0x327e,
+ 0x994d, 0x3c12,
+ 0x994e, 0x327c,
+ 0x9950, 0x327b,
+ 0x9951, 0x1659,
+ 0x9952, 0x1658,
+ 0x9953, 0x3280,
+ 0x9954, 0x33d6,
+ 0x9955, 0x16e7,
+ 0x9956, 0x333a,
+ 0x9957, 0x16a7,
+ 0x9958, 0x3339,
+ 0x9959, 0x327d,
+ 0x995b, 0x33d7,
+ 0x995c, 0x1712,
+ 0x995d, 0x47be,
+ 0x995e, 0x174e,
+ 0x995f, 0x34f3,
+ 0x9961, 0x352a,
+ 0x9962, 0x43ef,
+ 0x9963, 0x4510,
+ 0x9996, 0x082f,
+ 0x9997, 0x20ad,
+ 0x9998, 0x2ece,
+ 0x9999, 0x0830,
+ 0x999b, 0x3c15,
+ 0x999c, 0x2869,
+ 0x999d, 0x2868,
+ 0x999e, 0x2d03,
+ 0x99a1, 0x2ed0,
+ 0x99a3, 0x2ecf,
+ 0x99a4, 0x41c3,
+ 0x99a5, 0x1562,
+ 0x99a6, 0x317c,
+ 0x99a8, 0x165a,
+ 0x99aa, 0x3c17,
+ 0x99ab, 0x352b,
+ 0x99ac, 0x09f5,
+ 0x99ad, 0x0dba,
+ 0x99ae, 0x0db9,
+ 0x99af, 0x2607,
+ 0x99b0, 0x2609,
+ 0x99b1, 0x0f76,
+ 0x99b2, 0x2608,
+ 0x99b3, 0x0f75,
+ 0x99b4, 0x0f77,
+ 0x99b5, 0x260a,
+ 0x99b8, 0x394b,
+ 0x99b9, 0x286b,
+ 0x99ba, 0x286d,
+ 0x99bb, 0x286c,
+ 0x99bc, 0x3c22,
+ 0x99bd, 0x286f,
+ 0x99c1, 0x10f6,
+ 0x99c2, 0x286e,
+ 0x99c3, 0x286a,
+ 0x99c4, 0x3d77,
+ 0x99c5, 0x47c1,
+ 0x99c7, 0x2870,
+ 0x99c9, 0x2ad8,
+ 0x99cb, 0x2adb,
+ 0x99cc, 0x2add,
+ 0x99cd, 0x2ad3,
+ 0x99ce, 0x2ad7,
+ 0x99cf, 0x2ad4,
+ 0x99d0, 0x1273,
+ 0x99d1, 0x1276,
+ 0x99d2, 0x1278,
+ 0x99d3, 0x2ad5,
+ 0x99d5, 0x1277,
+ 0x99d6, 0x2ad9,
+ 0x99d7, 0x2adc,
+ 0x99d8, 0x2ada,
+ 0x99d9, 0x1279,
+ 0x99da, 0x3f42,
+ 0x99db, 0x1275,
+ 0x99dc, 0x2ad2,
+ 0x99dd, 0x1272,
+ 0x99df, 0x1274,
+ 0x99e1, 0x3785,
+ 0x99e2, 0x13a2,
+ 0x99e3, 0x2d09,
+ 0x99e4, 0x2d07,
+ 0x99e5, 0x2d06,
+ 0x99e6, 0x3b65,
+ 0x99e7, 0x2d0c,
+ 0x99e9, 0x2d0b,
+ 0x99ea, 0x2d0a,
+ 0x99ec, 0x2d05,
+ 0x99ed, 0x13a1,
+ 0x99ee, 0x2d04,
+ 0x99f0, 0x2d08,
+ 0x99f1, 0x13a3,
+ 0x99f4, 0x2ed3,
+ 0x99f5, 0x38ff,
+ 0x99f6, 0x2ed7,
+ 0x99f7, 0x2ed4,
+ 0x99f8, 0x2ed6,
+ 0x99f9, 0x2ed5,
+ 0x99fa, 0x2ed2,
+ 0x99fb, 0x2ed8,
+ 0x99fc, 0x2edb,
+ 0x99fd, 0x2ed9,
+ 0x99ff, 0x14ba,
+ 0x9a01, 0x14b9,
+ 0x9a02, 0x2ed1,
+ 0x9a03, 0x2edc,
+ 0x9a04, 0x3042,
+ 0x9a05, 0x3045,
+ 0x9a06, 0x3047,
+ 0x9a07, 0x3046,
+ 0x9a09, 0x3040,
+ 0x9a0a, 0x3044,
+ 0x9a0b, 0x303f,
+ 0x9a0c, 0x3900,
+ 0x9a0d, 0x3041,
+ 0x9a0e, 0x1563,
+ 0x9a0f, 0x303e,
+ 0x9a10, 0x3902,
+ 0x9a11, 0x3043,
+ 0x9a14, 0x318a,
+ 0x9a15, 0x317f,
+ 0x9a16, 0x15f9,
+ 0x9a19, 0x15fa,
+ 0x9a1a, 0x317e,
+ 0x9a1b, 0x3183,
+ 0x9a1c, 0x3189,
+ 0x9a1d, 0x3181,
+ 0x9a1e, 0x3188,
+ 0x9a1f, 0x3b6c,
+ 0x9a20, 0x3185,
+ 0x9a21, 0x3c1c,
+ 0x9a22, 0x3184,
+ 0x9a23, 0x3187,
+ 0x9a24, 0x3182,
+ 0x9a25, 0x3180,
+ 0x9a26, 0x3df2,
+ 0x9a27, 0x3186,
+ 0x9a29, 0x3287,
+ 0x9a2a, 0x3285,
+ 0x9a2b, 0x165b,
+ 0x9a2c, 0x3284,
+ 0x9a2d, 0x328a,
+ 0x9a2e, 0x3288,
+ 0x9a2f, 0x3c1e,
+ 0x9a30, 0x165c,
+ 0x9a31, 0x3283,
+ 0x9a32, 0x3281,
+ 0x9a34, 0x3282,
+ 0x9a35, 0x165e,
+ 0x9a36, 0x3286,
+ 0x9a37, 0x165d,
+ 0x9a38, 0x3289,
+ 0x9a39, 0x333b,
+ 0x9a3a, 0x3341,
+ 0x9a3b, 0x3901,
+ 0x9a3c, 0x47c3,
+ 0x9a3d, 0x333c,
+ 0x9a3e, 0x16ab,
+ 0x9a3f, 0x3342,
+ 0x9a40, 0x16aa,
+ 0x9a41, 0x3340,
+ 0x9a42, 0x333f,
+ 0x9a43, 0x16a9,
+ 0x9a44, 0x333e,
+ 0x9a45, 0x16a8,
+ 0x9a46, 0x333d,
+ 0x9a48, 0x33dd,
+ 0x9a49, 0x33df,
+ 0x9a4a, 0x33de,
+ 0x9a4c, 0x33db,
+ 0x9a4d, 0x16e9,
+ 0x9a4e, 0x33d8,
+ 0x9a4f, 0x33dc,
+ 0x9a50, 0x33e1,
+ 0x9a52, 0x33e0,
+ 0x9a53, 0x33d9,
+ 0x9a55, 0x16e8,
+ 0x9a56, 0x344f,
+ 0x9a57, 0x1715,
+ 0x9a58, 0x3903,
+ 0x9a59, 0x3450,
+ 0x9a5a, 0x1713,
+ 0x9a5c, 0x3c18,
+ 0x9a5e, 0x34ae,
+ 0x9a5f, 0x1737,
+ 0x9a60, 0x3510,
+ 0x9a62, 0x1757,
+ 0x9a63, 0x3b67,
+ 0x9a64, 0x352c,
+ 0x9a65, 0x1758,
+ 0x9a66, 0x352d,
+ 0x9a68, 0x353c,
+ 0x9a69, 0x353b,
+ 0x9a6a, 0x1767,
+ 0x9a6b, 0x3544,
+ 0x9a6c, 0x4585,
+ 0x9a8f, 0x4586,
+ 0x9aa8, 0x09f6,
+ 0x9aab, 0x260c,
+ 0x9aad, 0x260b,
+ 0x9aaf, 0x10f7,
+ 0x9ab1, 0x2871,
+ 0x9ab2, 0x4332,
+ 0x9ab3, 0x2ade,
+ 0x9ab4, 0x2d0f,
+ 0x9ab6, 0x43f0,
+ 0x9ab7, 0x127a,
+ 0x9ab8, 0x13a4,
+ 0x9ab9, 0x2d0d,
+ 0x9aba, 0x3f74,
+ 0x9abb, 0x2d10,
+ 0x9abc, 0x13a5,
+ 0x9abd, 0x3d97,
+ 0x9abe, 0x2edd,
+ 0x9abf, 0x2d0e,
+ 0x9ac0, 0x3048,
+ 0x9ac1, 0x1564,
+ 0x9ac2, 0x318b,
+ 0x9ac6, 0x328d,
+ 0x9ac7, 0x328b,
+ 0x9aca, 0x328c,
+ 0x9acd, 0x3343,
+ 0x9acf, 0x16ac,
+ 0x9ad0, 0x33e2,
+ 0x9ad1, 0x1718,
+ 0x9ad2, 0x16ea,
+ 0x9ad3, 0x1716,
+ 0x9ad5, 0x34af,
+ 0x9ad6, 0x174f,
+ 0x9ad7, 0x3faa,
+ 0x9ad8, 0x09f7,
+ 0x9adc, 0x3049,
+ 0x9adf, 0x1e33,
+ 0x9ae0, 0x3908,
+ 0x9ae1, 0x0f78,
+ 0x9ae2, 0x3909,
+ 0x9ae3, 0x2872,
+ 0x9ae6, 0x10f9,
+ 0x9ae7, 0x2873,
+ 0x9aeb, 0x2ae0,
+ 0x9aec, 0x2adf,
+ 0x9aed, 0x13a7,
+ 0x9aee, 0x127b,
+ 0x9af1, 0x2ae3,
+ 0x9af2, 0x2ae2,
+ 0x9af3, 0x2ae1,
+ 0x9af4, 0x390b,
+ 0x9af6, 0x2d11,
+ 0x9af7, 0x2d14,
+ 0x9af9, 0x2d13,
+ 0x9afa, 0x2d12,
+ 0x9afb, 0x13a6,
+ 0x9afc, 0x2ee1,
+ 0x9afd, 0x2edf,
+ 0x9afe, 0x2ede,
+ 0x9aff, 0x3f17,
+ 0x9b01, 0x2ee0,
+ 0x9b02, 0x3f12,
+ 0x9b03, 0x1565,
+ 0x9b04, 0x304b,
+ 0x9b06, 0x1566,
+ 0x9b08, 0x304a,
+ 0x9b09, 0x3f20,
+ 0x9b0a, 0x318d,
+ 0x9b0b, 0x318c,
+ 0x9b0c, 0x318f,
+ 0x9b0d, 0x15fb,
+ 0x9b0e, 0x318e,
+ 0x9b0f, 0x47c4,
+ 0x9b10, 0x328e,
+ 0x9b11, 0x3290,
+ 0x9b12, 0x328f,
+ 0x9b14, 0x390d,
+ 0x9b15, 0x3344,
+ 0x9b16, 0x3347,
+ 0x9b17, 0x3345,
+ 0x9b19, 0x33e3,
+ 0x9b1a, 0x16eb,
+ 0x9b1e, 0x3451,
+ 0x9b22, 0x1738,
+ 0x9b23, 0x1750,
+ 0x9b24, 0x352f,
+ 0x9b25, 0x09f8,
+ 0x9b27, 0x127d,
+ 0x9b28, 0x13a8,
+ 0x9b29, 0x304d,
+ 0x9b2a, 0x3f19,
+ 0x9b2b, 0x33e4,
+ 0x9b2d, 0x390e,
+ 0x9b2e, 0x3511,
+ 0x9b2f, 0x1e34,
+ 0x9b31, 0x1768,
+ 0x9b32, 0x09f9,
+ 0x9b33, 0x2d15,
+ 0x9b34, 0x3911,
+ 0x9b35, 0x304e,
+ 0x9b37, 0x3190,
+ 0x9b39, 0x3f00,
+ 0x9b3a, 0x3348,
+ 0x9b3b, 0x33e5,
+ 0x9b3c, 0x09fa,
+ 0x9b3e, 0x2874,
+ 0x9b40, 0x3915,
+ 0x9b41, 0x10fa,
+ 0x9b43, 0x2ae5,
+ 0x9b44, 0x127f,
+ 0x9b45, 0x127e,
+ 0x9b46, 0x2ae4,
+ 0x9b48, 0x2ee2,
+ 0x9b4a, 0x304f,
+ 0x9b4b, 0x3051,
+ 0x9b4c, 0x3050,
+ 0x9b4d, 0x1569,
+ 0x9b4e, 0x1568,
+ 0x9b4f, 0x1567,
+ 0x9b50, 0x3914,
+ 0x9b51, 0x16ae,
+ 0x9b52, 0x3349,
+ 0x9b54, 0x16ad,
+ 0x9b55, 0x33e7,
+ 0x9b56, 0x33e6,
+ 0x9b58, 0x1739,
+ 0x9b59, 0x34b0,
+ 0x9b5a, 0x0be1,
+ 0x9b5b, 0x260d,
+ 0x9b5f, 0x2878,
+ 0x9b60, 0x2876,
+ 0x9b64, 0x2aee,
+ 0x9b66, 0x2ae9,
+ 0x9b67, 0x2ae6,
+ 0x9b68, 0x2aed,
+ 0x9b69, 0x47c5,
+ 0x9b6c, 0x2aef,
+ 0x9b6f, 0x1281,
+ 0x9b70, 0x2aec,
+ 0x9b71, 0x2ae8,
+ 0x9b74, 0x2ae7,
+ 0x9b75, 0x2aeb,
+ 0x9b76, 0x2aea,
+ 0x9b77, 0x1280,
+ 0x9b7a, 0x2d20,
+ 0x9b7b, 0x2d1b,
+ 0x9b7c, 0x2d19,
+ 0x9b7d, 0x2d22,
+ 0x9b7e, 0x2d1a,
+ 0x9b7f, 0x3c3b,
+ 0x9b80, 0x2d16,
+ 0x9b81, 0x43f1,
+ 0x9b82, 0x2d1c,
+ 0x9b83, 0x4219,
+ 0x9b85, 0x2d17,
+ 0x9b86, 0x2eeb,
+ 0x9b87, 0x2d18,
+ 0x9b88, 0x2d23,
+ 0x9b8b, 0x3eee,
+ 0x9b8d, 0x4623,
+ 0x9b8e, 0x3919,
+ 0x9b8f, 0x3fad,
+ 0x9b90, 0x2d1f,
+ 0x9b91, 0x13a9,
+ 0x9b92, 0x2d1e,
+ 0x9b93, 0x2d1d,
+ 0x9b95, 0x2d21,
+ 0x9b97, 0x3f71,
+ 0x9b9a, 0x2ee3,
+ 0x9b9b, 0x2ee6,
+ 0x9b9d, 0x3f56,
+ 0x9b9e, 0x2ee5,
+ 0x9b9f, 0x3c3e,
+ 0x9ba0, 0x2eed,
+ 0x9ba1, 0x2ee8,
+ 0x9ba2, 0x2eec,
+ 0x9ba4, 0x2eea,
+ 0x9ba5, 0x2ee9,
+ 0x9ba6, 0x2ee7,
+ 0x9ba8, 0x2ee4,
+ 0x9baa, 0x14bd,
+ 0x9bab, 0x14bc,
+ 0x9bad, 0x14be,
+ 0x9bae, 0x14bb,
+ 0x9baf, 0x2eee,
+ 0x9bb0, 0x3fb4,
+ 0x9bb5, 0x3057,
+ 0x9bb6, 0x305a,
+ 0x9bb8, 0x3058,
+ 0x9bb9, 0x305c,
+ 0x9bbd, 0x305d,
+ 0x9bbf, 0x3055,
+ 0x9bc0, 0x156e,
+ 0x9bc1, 0x3056,
+ 0x9bc3, 0x3054,
+ 0x9bc4, 0x305b,
+ 0x9bc6, 0x3053,
+ 0x9bc7, 0x3052,
+ 0x9bc8, 0x156d,
+ 0x9bc9, 0x156b,
+ 0x9bca, 0x156a,
+ 0x9bcf, 0x3c3c,
+ 0x9bd3, 0x3059,
+ 0x9bd4, 0x3199,
+ 0x9bd5, 0x319f,
+ 0x9bd6, 0x15fe,
+ 0x9bd7, 0x319a,
+ 0x9bd9, 0x319d,
+ 0x9bda, 0x31a1,
+ 0x9bdb, 0x15ff,
+ 0x9bdc, 0x319c,
+ 0x9bdd, 0x47c6,
+ 0x9bde, 0x3194,
+ 0x9be0, 0x3193,
+ 0x9be1, 0x31a0,
+ 0x9be2, 0x3197,
+ 0x9be4, 0x3195,
+ 0x9be5, 0x319e,
+ 0x9be6, 0x3196,
+ 0x9be7, 0x15fd,
+ 0x9be8, 0x15fc,
+ 0x9be9, 0x3bc1,
+ 0x9bea, 0x3191,
+ 0x9bec, 0x319b,
+ 0x9bed, 0x3ed7,
+ 0x9bf0, 0x3198,
+ 0x9bf1, 0x47c7,
+ 0x9bf4, 0x47c8,
+ 0x9bf7, 0x3293,
+ 0x9bf8, 0x3296,
+ 0x9bfd, 0x156c,
+ 0x9bff, 0x391b,
+ 0x9c02, 0x391a,
+ 0x9c05, 0x3294,
+ 0x9c06, 0x329a,
+ 0x9c07, 0x3298,
+ 0x9c08, 0x3292,
+ 0x9c09, 0x329d,
+ 0x9c0a, 0x3f3a,
+ 0x9c0b, 0x3291,
+ 0x9c0c, 0x391c,
+ 0x9c0d, 0x1660,
+ 0x9c0e, 0x3299,
+ 0x9c10, 0x3c3a,
+ 0x9c12, 0x3295,
+ 0x9c13, 0x165f,
+ 0x9c14, 0x329c,
+ 0x9c15, 0x3f1e,
+ 0x9c17, 0x329b,
+ 0x9c1b, 0x491b,
+ 0x9c1c, 0x334c,
+ 0x9c1d, 0x334b,
+ 0x9c1f, 0x4622,
+ 0x9c20, 0x47ca,
+ 0x9c21, 0x3352,
+ 0x9c23, 0x334e,
+ 0x9c24, 0x3351,
+ 0x9c25, 0x16b0,
+ 0x9c26, 0x45e6,
+ 0x9c28, 0x334f,
+ 0x9c2b, 0x334a,
+ 0x9c2c, 0x334d,
+ 0x9c2d, 0x16af,
+ 0x9c2e, 0x3f22,
+ 0x9c2f, 0x3d87,
+ 0x9c31, 0x16ed,
+ 0x9c32, 0x33f2,
+ 0x9c33, 0x33ed,
+ 0x9c34, 0x33f1,
+ 0x9c35, 0x3c39,
+ 0x9c36, 0x33f4,
+ 0x9c37, 0x33f0,
+ 0x9c39, 0x33ec,
+ 0x9c3a, 0x3d7e,
+ 0x9c3b, 0x16ef,
+ 0x9c3c, 0x33ef,
+ 0x9c3d, 0x33f3,
+ 0x9c3e, 0x16ee,
+ 0x9c3f, 0x33ea,
+ 0x9c40, 0x3297,
+ 0x9c41, 0x33ee,
+ 0x9c44, 0x33eb,
+ 0x9c45, 0x3e71,
+ 0x9c46, 0x33e8,
+ 0x9c48, 0x33e9,
+ 0x9c49, 0x16ec,
+ 0x9c4a, 0x3457,
+ 0x9c4b, 0x3459,
+ 0x9c4c, 0x345c,
+ 0x9c4d, 0x3458,
+ 0x9c4e, 0x345d,
+ 0x9c4f, 0x3c36,
+ 0x9c50, 0x3456,
+ 0x9c52, 0x3454,
+ 0x9c53, 0x3c37,
+ 0x9c54, 0x1719,
+ 0x9c55, 0x345a,
+ 0x9c56, 0x171b,
+ 0x9c57, 0x171a,
+ 0x9c58, 0x3455,
+ 0x9c59, 0x345b,
+ 0x9c5d, 0x3ebf,
+ 0x9c5e, 0x34b5,
+ 0x9c5f, 0x173a,
+ 0x9c60, 0x34b6,
+ 0x9c62, 0x34b4,
+ 0x9c63, 0x34b1,
+ 0x9c66, 0x34b3,
+ 0x9c67, 0x34b2,
+ 0x9c68, 0x34f4,
+ 0x9c6d, 0x34f6,
+ 0x9c6e, 0x34f5,
+ 0x9c71, 0x3514,
+ 0x9c72, 0x3ea1,
+ 0x9c73, 0x3513,
+ 0x9c74, 0x3512,
+ 0x9c75, 0x3515,
+ 0x9c77, 0x1760,
+ 0x9c79, 0x3541,
+ 0x9c7a, 0x3545,
+ 0x9c7b, 0x3c38,
+ 0x9c7c, 0x4512,
+ 0x9ce5, 0x0be2,
+ 0x9ce6, 0x235f,
+ 0x9ce7, 0x2610,
+ 0x9ce9, 0x0f79,
+ 0x9cea, 0x260e,
+ 0x9ced, 0x260f,
+ 0x9cf1, 0x2879,
+ 0x9cf3, 0x10fe,
+ 0x9cf4, 0x10fc,
+ 0x9cf5, 0x287b,
+ 0x9cf6, 0x10fd,
+ 0x9cf7, 0x2af4,
+ 0x9cf9, 0x2af7,
+ 0x9cfa, 0x2af1,
+ 0x9cfb, 0x2af8,
+ 0x9cfc, 0x2af0,
+ 0x9cfd, 0x2af2,
+ 0x9cff, 0x2af3,
+ 0x9d00, 0x2af6,
+ 0x9d02, 0x3f3b,
+ 0x9d03, 0x1284,
+ 0x9d04, 0x2afb,
+ 0x9d05, 0x2afa,
+ 0x9d06, 0x1282,
+ 0x9d07, 0x2af5,
+ 0x9d08, 0x2af9,
+ 0x9d09, 0x1283,
+ 0x9d0c, 0x3c46,
+ 0x9d10, 0x2d2d,
+ 0x9d12, 0x13ae,
+ 0x9d14, 0x2d28,
+ 0x9d15, 0x13aa,
+ 0x9d16, 0x3c7c,
+ 0x9d17, 0x2d25,
+ 0x9d18, 0x2d2b,
+ 0x9d19, 0x2d2e,
+ 0x9d1b, 0x13af,
+ 0x9d1d, 0x2d2a,
+ 0x9d1e, 0x2d27,
+ 0x9d1f, 0x2d2f,
+ 0x9d20, 0x2d26,
+ 0x9d21, 0x3c41,
+ 0x9d22, 0x2d2c,
+ 0x9d23, 0x13ab,
+ 0x9d25, 0x2d24,
+ 0x9d26, 0x13ac,
+ 0x9d28, 0x13ad,
+ 0x9d29, 0x2d29,
+ 0x9d2d, 0x2f00,
+ 0x9d2e, 0x2ef3,
+ 0x9d30, 0x2ef7,
+ 0x9d31, 0x2ef5,
+ 0x9d33, 0x2eef,
+ 0x9d34, 0x404a,
+ 0x9d36, 0x2ef2,
+ 0x9d37, 0x2efc,
+ 0x9d38, 0x2ef6,
+ 0x9d39, 0x392e,
+ 0x9d3b, 0x14bf,
+ 0x9d3d, 0x2efe,
+ 0x9d3e, 0x2efb,
+ 0x9d3f, 0x14c0,
+ 0x9d40, 0x2efd,
+ 0x9d41, 0x2ef0,
+ 0x9d42, 0x2ef9,
+ 0x9d44, 0x3fab,
+ 0x9d45, 0x2ef8,
+ 0x9d49, 0x47cd,
+ 0x9d4a, 0x3061,
+ 0x9d4b, 0x3063,
+ 0x9d4c, 0x3066,
+ 0x9d4e, 0x4539,
+ 0x9d4f, 0x3060,
+ 0x9d50, 0x3eca,
+ 0x9d51, 0x156f,
+ 0x9d52, 0x3068,
+ 0x9d53, 0x305f,
+ 0x9d54, 0x3069,
+ 0x9d56, 0x3065,
+ 0x9d57, 0x3067,
+ 0x9d58, 0x306b,
+ 0x9d59, 0x3064,
+ 0x9d5a, 0x306c,
+ 0x9d5b, 0x3062,
+ 0x9d5c, 0x305e,
+ 0x9d5d, 0x1570,
+ 0x9d5e, 0x3e6e,
+ 0x9d5f, 0x306a,
+ 0x9d60, 0x1571,
+ 0x9d61, 0x1601,
+ 0x9d67, 0x2ef1,
+ 0x9d68, 0x31bb,
+ 0x9d69, 0x31b2,
+ 0x9d6a, 0x1603,
+ 0x9d6b, 0x31ae,
+ 0x9d6c, 0x1604,
+ 0x9d6d, 0x3bac,
+ 0x9d6e, 0x433b,
+ 0x9d6f, 0x31b7,
+ 0x9d70, 0x31b1,
+ 0x9d71, 0x31a7,
+ 0x9d72, 0x1602,
+ 0x9d73, 0x31b4,
+ 0x9d74, 0x31af,
+ 0x9d77, 0x31a2,
+ 0x9d78, 0x31a9,
+ 0x9d79, 0x31b8,
+ 0x9d7b, 0x31b5,
+ 0x9d7c, 0x3efe,
+ 0x9d7d, 0x31ad,
+ 0x9d7e, 0x3925,
+ 0x9d7f, 0x31b9,
+ 0x9d80, 0x31a8,
+ 0x9d81, 0x31a3,
+ 0x9d82, 0x31b6,
+ 0x9d83, 0x3926,
+ 0x9d84, 0x31a5,
+ 0x9d85, 0x31b3,
+ 0x9d86, 0x31aa,
+ 0x9d87, 0x31ba,
+ 0x9d88, 0x31a6,
+ 0x9d89, 0x1600,
+ 0x9d8a, 0x31a4,
+ 0x9d8b, 0x31ab,
+ 0x9d90, 0x32a4,
+ 0x9d92, 0x32a2,
+ 0x9d93, 0x43f3,
+ 0x9d94, 0x32a7,
+ 0x9d96, 0x32b3,
+ 0x9d97, 0x32aa,
+ 0x9d98, 0x32a3,
+ 0x9d99, 0x329f,
+ 0x9d9a, 0x32ac,
+ 0x9d9b, 0x32a5,
+ 0x9d9c, 0x32a8,
+ 0x9d9d, 0x32a1,
+ 0x9d9e, 0x32af,
+ 0x9d9f, 0x329e,
+ 0x9da0, 0x32a6,
+ 0x9da1, 0x32ab,
+ 0x9da2, 0x32ad,
+ 0x9da3, 0x32b0,
+ 0x9da4, 0x32a0,
+ 0x9da5, 0x3c4b,
+ 0x9da6, 0x32b4,
+ 0x9da8, 0x32ae,
+ 0x9da9, 0x32b2,
+ 0x9daa, 0x32a9,
+ 0x9dab, 0x3f30,
+ 0x9dac, 0x3362,
+ 0x9dad, 0x3365,
+ 0x9daf, 0x16b1,
+ 0x9db1, 0x3364,
+ 0x9db2, 0x3369,
+ 0x9db3, 0x3367,
+ 0x9db4, 0x16b2,
+ 0x9db5, 0x335e,
+ 0x9db6, 0x3354,
+ 0x9db7, 0x3353,
+ 0x9db8, 0x16b4,
+ 0x9db9, 0x3360,
+ 0x9dbb, 0x335d,
+ 0x9dbc, 0x3355,
+ 0x9dbd, 0x47d0,
+ 0x9dbe, 0x335a,
+ 0x9dbf, 0x32b1,
+ 0x9dc0, 0x43f2,
+ 0x9dc1, 0x3356,
+ 0x9dc2, 0x16b3,
+ 0x9dc3, 0x335c,
+ 0x9dc4, 0x3929,
+ 0x9dc5, 0x335b,
+ 0x9dc7, 0x3357,
+ 0x9dc8, 0x3363,
+ 0x9dc9, 0x4579,
+ 0x9dca, 0x3358,
+ 0x9dcb, 0x33f9,
+ 0x9dcc, 0x3366,
+ 0x9dcd, 0x3368,
+ 0x9dce, 0x335f,
+ 0x9dcf, 0x3359,
+ 0x9dd0, 0x33fa,
+ 0x9dd1, 0x33fc,
+ 0x9dd2, 0x33f6,
+ 0x9dd3, 0x16f0,
+ 0x9dd4, 0x391e,
+ 0x9dd5, 0x3403,
+ 0x9dd6, 0x3401,
+ 0x9dd7, 0x16f1,
+ 0x9dd8, 0x3400,
+ 0x9dd9, 0x33ff,
+ 0x9dda, 0x33f8,
+ 0x9ddb, 0x33f5,
+ 0x9ddc, 0x33fb,
+ 0x9ddd, 0x3404,
+ 0x9dde, 0x33f7,
+ 0x9ddf, 0x33fd,
+ 0x9de1, 0x3466,
+ 0x9de2, 0x346b,
+ 0x9de3, 0x3461,
+ 0x9de4, 0x3464,
+ 0x9de5, 0x171c,
+ 0x9de6, 0x3468,
+ 0x9de8, 0x346f,
+ 0x9de9, 0x33fe,
+ 0x9deb, 0x3462,
+ 0x9dec, 0x346c,
+ 0x9ded, 0x3470,
+ 0x9dee, 0x3467,
+ 0x9def, 0x3460,
+ 0x9df0, 0x346a,
+ 0x9df2, 0x3469,
+ 0x9df3, 0x346e,
+ 0x9df4, 0x346d,
+ 0x9df5, 0x3402,
+ 0x9df6, 0x3465,
+ 0x9df7, 0x345f,
+ 0x9df8, 0x3463,
+ 0x9df9, 0x173b,
+ 0x9dfb, 0x345e,
+ 0x9dfc, 0x47d1,
+ 0x9dfd, 0x34c1,
+ 0x9dfe, 0x34b8,
+ 0x9dff, 0x34c0,
+ 0x9e00, 0x34bd,
+ 0x9e02, 0x34b7,
+ 0x9e03, 0x34ba,
+ 0x9e04, 0x34c2,
+ 0x9e05, 0x34bc,
+ 0x9e06, 0x34bb,
+ 0x9e07, 0x34b9,
+ 0x9e09, 0x34bf,
+ 0x9e0a, 0x457e,
+ 0x9e0b, 0x34f7,
+ 0x9e0c, 0x457a,
+ 0x9e0d, 0x34f8,
+ 0x9e0e, 0x3928,
+ 0x9e0f, 0x34fa,
+ 0x9e10, 0x34f9,
+ 0x9e11, 0x34fc,
+ 0x9e12, 0x34fb,
+ 0x9e13, 0x3517,
+ 0x9e14, 0x3516,
+ 0x9e15, 0x3530,
+ 0x9e17, 0x3531,
+ 0x9e18, 0x3c44,
+ 0x9e19, 0x353d,
+ 0x9e1a, 0x1765,
+ 0x9e1b, 0x1769,
+ 0x9e1c, 0x3f84,
+ 0x9e1d, 0x3546,
+ 0x9e1e, 0x176a,
+ 0x9e1f, 0x4513,
+ 0x9e75, 0x0be3,
+ 0x9e79, 0x1661,
+ 0x9e7a, 0x336a,
+ 0x9e7b, 0x43f8,
+ 0x9e7c, 0x173d,
+ 0x9e7f, 0x0be4,
+ 0x9e80, 0x2611,
+ 0x9e81, 0x3f0f,
+ 0x9e82, 0x0f7a,
+ 0x9e83, 0x2afc,
+ 0x9e84, 0x3f76,
+ 0x9e85, 0x3ef2,
+ 0x9e86, 0x2d31,
+ 0x9e88, 0x2d30,
+ 0x9e89, 0x2f02,
+ 0x9e8a, 0x2f01,
+ 0x9e8b, 0x14c1,
+ 0x9e8c, 0x306e,
+ 0x9e8d, 0x2f03,
+ 0x9e8e, 0x306d,
+ 0x9e90, 0x3931,
+ 0x9e91, 0x31bd,
+ 0x9e92, 0x1605,
+ 0x9e93, 0x1607,
+ 0x9e94, 0x31bc,
+ 0x9e95, 0x3932,
+ 0x9e96, 0x3fbc,
+ 0x9e97, 0x1606,
+ 0x9e98, 0x3f27,
+ 0x9e99, 0x32b6,
+ 0x9e9a, 0x32b8,
+ 0x9e9b, 0x32b7,
+ 0x9e9c, 0x336b,
+ 0x9e9d, 0x16b5,
+ 0x9e9e, 0x3933,
+ 0x9e9f, 0x171d,
+ 0x9ea0, 0x34c3,
+ 0x9ea1, 0x34fd,
+ 0x9ea2, 0x3934,
+ 0x9ea4, 0x354a,
+ 0x9ea5, 0x0be5,
+ 0x9ea6, 0x4944,
+ 0x9ea7, 0x287c,
+ 0x9ea8, 0x3f75,
+ 0x9ea9, 0x1285,
+ 0x9eaa, 0x3936,
+ 0x9eab, 0x3e92,
+ 0x9eac, 0x43f4,
+ 0x9ead, 0x2d34,
+ 0x9eae, 0x2d33,
+ 0x9eaf, 0x3937,
+ 0x9eb0, 0x2f04,
+ 0x9eb1, 0x47d4,
+ 0x9eb4, 0x1608,
+ 0x9eb5, 0x1662,
+ 0x9eb6, 0x3405,
+ 0x9eb7, 0x3542,
+ 0x9ebb, 0x0be6,
+ 0x9ebc, 0x10ff,
+ 0x9ebd, 0x47d5,
+ 0x9ebe, 0x1286,
+ 0x9ebf, 0x3d78,
+ 0x9ec0, 0x31be,
+ 0x9ec1, 0x3939,
+ 0x9ec2, 0x3471,
+ 0x9ec3, 0x0dbb,
+ 0x9ec4, 0x4514,
+ 0x9ec6, 0x47d6,
+ 0x9ec7, 0x4577,
+ 0x9ec8, 0x2f05,
+ 0x9ecc, 0x1751,
+ 0x9ecd, 0x0dbc,
+ 0x9ece, 0x1287,
+ 0x9ecf, 0x14c2,
+ 0x9ed0, 0x3472,
+ 0x9ed1, 0x0dbd,
+ 0x9ed3, 0x2afd,
+ 0x9ed4, 0x13b1,
+ 0x9ed5, 0x2d35,
+ 0x9ed8, 0x13b0,
+ 0x9eda, 0x2f06,
+ 0x9edb, 0x14c6,
+ 0x9edc, 0x14c4,
+ 0x9ede, 0x14c3,
+ 0x9edf, 0x306f,
+ 0x9ee0, 0x1572,
+ 0x9ee2, 0x47d8,
+ 0x9ee4, 0x32ba,
+ 0x9ee5, 0x32b9,
+ 0x9ee6, 0x32bc,
+ 0x9ee7, 0x32bb,
+ 0x9ee8, 0x1663,
+ 0x9eeb, 0x336c,
+ 0x9eed, 0x336e,
+ 0x9eee, 0x336d,
+ 0x9eef, 0x16b6,
+ 0x9ef0, 0x3406,
+ 0x9ef1, 0x47d9,
+ 0x9ef2, 0x3473,
+ 0x9ef4, 0x171e,
+ 0x9ef5, 0x34fe,
+ 0x9ef6, 0x3518,
+ 0x9ef7, 0x1762,
+ 0x9ef8, 0x47da,
+ 0x9ef9, 0x2360,
+ 0x9efa, 0x2d37,
+ 0x9efb, 0x2f07,
+ 0x9efc, 0x31bf,
+ 0x9efd, 0x2612,
+ 0x9efe, 0x47ce,
+ 0x9eff, 0x2f08,
+ 0x9f00, 0x3071,
+ 0x9f01, 0x3070,
+ 0x9f02, 0x3940,
+ 0x9f06, 0x3475,
+ 0x9f07, 0x173f,
+ 0x9f08, 0x3941,
+ 0x9f09, 0x34ff,
+ 0x9f0a, 0x3519,
+ 0x9f0e, 0x0f7b,
+ 0x9f0f, 0x2afe,
+ 0x9f12, 0x2d38,
+ 0x9f13, 0x0f7c,
+ 0x9f15, 0x1573,
+ 0x9f16, 0x3072,
+ 0x9f17, 0x3945,
+ 0x9f18, 0x3370,
+ 0x9f19, 0x16b7,
+ 0x9f1a, 0x3371,
+ 0x9f1b, 0x336f,
+ 0x9f1c, 0x3476,
+ 0x9f1e, 0x34c4,
+ 0x9f20, 0x0f7d,
+ 0x9f22, 0x2f0b,
+ 0x9f23, 0x2f0a,
+ 0x9f24, 0x2f09,
+ 0x9f25, 0x3073,
+ 0x9f26, 0x3f90,
+ 0x9f27, 0x4620,
+ 0x9f28, 0x3077,
+ 0x9f29, 0x3076,
+ 0x9f2a, 0x3075,
+ 0x9f2b, 0x3074,
+ 0x9f2c, 0x1574,
+ 0x9f2d, 0x31c0,
+ 0x9f2e, 0x32be,
+ 0x9f2f, 0x1664,
+ 0x9f30, 0x32bd,
+ 0x9f31, 0x3372,
+ 0x9f32, 0x3409,
+ 0x9f33, 0x3408,
+ 0x9f34, 0x16f2,
+ 0x9f35, 0x3407,
+ 0x9f36, 0x3479,
+ 0x9f37, 0x3478,
+ 0x9f38, 0x3477,
+ 0x9f39, 0x3947,
+ 0x9f3b, 0x1100,
+ 0x9f3d, 0x2d39,
+ 0x9f3e, 0x14c7,
+ 0x9f40, 0x31c1,
+ 0x9f42, 0x340a,
+ 0x9f43, 0x347a,
+ 0x9f44, 0x47db,
+ 0x9f45, 0x394a,
+ 0x9f46, 0x34c5,
+ 0x9f47, 0x3500,
+ 0x9f48, 0x3532,
+ 0x9f49, 0x354c,
+ 0x9f4a, 0x1101,
+ 0x9f4b, 0x14c8,
+ 0x9f4c, 0x3078,
+ 0x9f4d, 0x31c3,
+ 0x9f4e, 0x3373,
+ 0x9f4f, 0x347b,
+ 0x9f50, 0x4943,
+ 0x9f52, 0x1289,
+ 0x9f53, 0x3f80,
+ 0x9f54, 0x2f0c,
+ 0x9f55, 0x3079,
+ 0x9f56, 0x31c4,
+ 0x9f59, 0x32c3,
+ 0x9f5a, 0x3f23,
+ 0x9f5b, 0x32bf,
+ 0x9f5c, 0x16b8,
+ 0x9f5d, 0x32c2,
+ 0x9f5e, 0x32c1,
+ 0x9f5f, 0x1665,
+ 0x9f60, 0x32c0,
+ 0x9f61, 0x1667,
+ 0x9f62, 0x394f,
+ 0x9f63, 0x1666,
+ 0x9f64, 0x3375,
+ 0x9f65, 0x3374,
+ 0x9f66, 0x16b9,
+ 0x9f69, 0x3950,
+ 0x9f6a, 0x16f4,
+ 0x9f6b, 0x340b,
+ 0x9f6c, 0x16f3,
+ 0x9f6e, 0x347e,
+ 0x9f70, 0x347d,
+ 0x9f71, 0x347c,
+ 0x9f72, 0x1741,
+ 0x9f74, 0x34c6,
+ 0x9f77, 0x1740,
+ 0x9f78, 0x3501,
+ 0x9f79, 0x3504,
+ 0x9f7a, 0x3503,
+ 0x9f7b, 0x3502,
+ 0x9f7e, 0x354b,
+ 0x9f7f, 0x4680,
+ 0x9f8d, 0x13b2,
+ 0x9f8e, 0x3952,
+ 0x9f90, 0x157c,
+ 0x9f91, 0x32c4,
+ 0x9f92, 0x3376,
+ 0x9f94, 0x16f5,
+ 0x9f95, 0x340c,
+ 0x9f98, 0x354d,
+ 0x9f99, 0x4587,
+ 0x9f9c, 0x13b3,
+ 0x9f9f, 0x4646,
+ 0x9fa0, 0x2f0d,
+ 0x9fa2, 0x340d,
+ 0x9fa4, 0x351a,
+ 0x9fa5, 0x3f70,
+ 0xfa0c, 0x0274,
+ 0xfa0d, 0x2381,
+ 0xfe30, 0x006d,
+ 0xfe31, 0x007a,
+ 0xfe33, 0x35af,
+ 0xfe34, 0x35b1,
+ 0xfe35, 0x0082,
+ 0xfe37, 0x0086,
+ 0xfe39, 0x008a,
+ 0xfe3b, 0x008e,
+ 0xfe3d, 0x0092,
+ 0xfe3f, 0x0096,
+ 0xfe41, 0x009a,
+ 0xfe43, 0x009e,
+ 0xfe49, 0x00c7,
+ 0xfe4b, 0x00cb,
+ 0xfe4d, 0x00c9,
+ 0xfe4f, 0x35b2,
+ 0xfe50, 0x0070,
+ 0xfe52, 0x0072,
+ 0xfe54, 0x0074,
+ 0xfe59, 0x00a0,
+ 0xfe5f, 0x00cd,
+ 0xfe62, 0x00df,
+ 0xfe69, 0x010c,
+ 0xff01, 0x006c,
+ 0xff02, 0x36e4,
+ 0xff03, 0x00ae,
+ 0xff04, 0x0103,
+ 0xff05, 0x0108,
+ 0xff06, 0x00af,
+ 0xff07, 0x36e3,
+ 0xff08, 0x0080,
+ 0xff0a, 0x00b0,
+ 0xff0b, 0x00d0,
+ 0xff0c, 0x0064,
+ 0xff0d, 0x00d1,
+ 0xff0e, 0x0067,
+ 0xff0f, 0x0101,
+ 0xff10, 0x014d,
+ 0xff1a, 0x006a,
+ 0xff1b, 0x0069,
+ 0xff1c, 0x00d6,
+ 0xff1d, 0x00d8,
+ 0xff1e, 0x00d7,
+ 0xff1f, 0x006b,
+ 0xff20, 0x0109,
+ 0xff21, 0x016d,
+ 0xff3b, 0x35be,
+ 0xff3c, 0x0102,
+ 0xff3d, 0x35bf,
+ 0xff3e, 0x35b4,
+ 0xff3f, 0x00c5,
+ 0xff41, 0x0187,
+ 0xff5b, 0x0084,
+ 0xff5c, 0x0078,
+ 0xff5d, 0x0085,
+ 0xff64, 0x0071,
+ 0xffe2, 0x36e1,
+ 0xffe4, 0x36e2,
+ 0x2013, 0x0078,
+ 0x2014, 0x007a,
+ 0x2025, 0x006d,
+ 0x300a, 0x0092,
+ 0x3008, 0x0096,
+ 0x300c, 0x009a,
+ 0x300e, 0x009e,
+ 0x3010, 0x008e,
+ 0x3014, 0x008a,
+ 0xfe4f, 0x35b1,
+ 0xff08, 0x0082,
+ 0xff5b, 0x0086,
+ 0xff5d, 0x0087,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13UniCNSUCS2VEnc16 = {
+ 1,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13UniCNSUCS2VMap2, 15468
+};
+
+static Gushort cns13AdobeCNS13VMap2[152] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0x2100, 0x2100,
+ 0x2200, 0x2200,
+ 0x2300, 0x2300,
+ 0x2400, 0x2400,
+ 0x2500, 0x2500,
+ 0x2600, 0x2600,
+ 0x2700, 0x2700,
+ 0x2800, 0x2800,
+ 0x2900, 0x2900,
+ 0x2a00, 0x2a00,
+ 0x2b00, 0x2b00,
+ 0x2c00, 0x2c00,
+ 0x2d00, 0x2d00,
+ 0x2e00, 0x2e00,
+ 0x2f00, 0x2f00,
+ 0x3000, 0x3000,
+ 0x3100, 0x3100,
+ 0x3200, 0x3200,
+ 0x3300, 0x3300,
+ 0x3400, 0x3400,
+ 0x3500, 0x3500,
+ 0x3600, 0x3600,
+ 0x3700, 0x3700,
+ 0x3800, 0x3800,
+ 0x3900, 0x3900,
+ 0x3a00, 0x3a00,
+ 0x3b00, 0x3b00,
+ 0x3c00, 0x3c00,
+ 0x3d00, 0x3d00,
+ 0x3e00, 0x3e00,
+ 0x3f00, 0x3f00,
+ 0x4000, 0x4000,
+ 0x4100, 0x4100,
+ 0x4200, 0x4200,
+ 0x4300, 0x4300,
+ 0x4400, 0x4400,
+ 0x4500, 0x4500,
+ 0x4600, 0x4600,
+ 0x4700, 0x4700,
+ 0x4800, 0x4800,
+ 0x4900, 0x4900,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 cns13AdobeCNS13VEnc16 = {
+ 1,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ cns13AdobeCNS13VMap2, 76
+};
+
+static struct {
+ char *name;
+ GfxFontEncoding16 *enc;
+} gfxCNS13Tab[] = {
+ { "Adobe-CNS1-0", &cns13AdobeCNS10Enc16 },
+ { "Adobe-CNS1-1", &cns13AdobeCNS11Enc16 },
+ { "Adobe-CNS1-2", &cns13AdobeCNS12Enc16 },
+ { "Adobe-CNS1-3", &cns13AdobeCNS13Enc16 },
+ { "B5-H", &cns13B5HEnc16 },
+ { "B5-V", &cns13B5VEnc16 },
+ { "B5pc-H", &cns13B5pcHEnc16 },
+ { "B5pc-V", &cns13B5pcVEnc16 },
+ { "CNS1-H", &cns13CNS1HEnc16 },
+ { "CNS1-V", &cns13CNS1VEnc16 },
+ { "CNS2-H", &cns13CNS2HEnc16 },
+ { "CNS2-V", &cns13CNS2VEnc16 },
+ { "ETHK-B5-H", &cns13ETHKB5HEnc16 },
+ { "ETHK-B5-V", &cns13ETHKB5VEnc16 },
+ { "ETen-B5-H", &cns13ETenB5HEnc16 },
+ { "ETen-B5-V", &cns13ETenB5VEnc16 },
+ { "ETenms-B5-H", &cns13ETenmsB5HEnc16 },
+ { "ETenms-B5-V", &cns13ETenmsB5VEnc16 },
+ { "HKdla-B5-H", &cns13HKdlaB5HEnc16 },
+ { "HKdla-B5-V", &cns13HKdlaB5VEnc16 },
+ { "HKdlb-B5-H", &cns13HKdlbB5HEnc16 },
+ { "HKdlb-B5-V", &cns13HKdlbB5VEnc16 },
+ { "HKgccs-B5-H", &cns13HKgccsB5HEnc16 },
+ { "HKgccs-B5-V", &cns13HKgccsB5VEnc16 },
+ { "HKm314-B5-H", &cns13HKm314B5HEnc16 },
+ { "HKm314-B5-V", &cns13HKm314B5VEnc16 },
+ { "HKm471-B5-H", &cns13HKm471B5HEnc16 },
+ { "HKm471-B5-V", &cns13HKm471B5VEnc16 },
+ { "HKscs-B5-H", &cns13HKscsB5HEnc16 },
+ { "HKscs-B5-V", &cns13HKscsB5VEnc16 },
+ { "UniCNS-UCS2-H", &cns13UniCNSUCS2HEnc16 },
+ { "UniCNS-UCS2-V", &cns13UniCNSUCS2VEnc16 },
+ { "Identity-H", &cns13AdobeCNS13Enc16 },
+ { "Identity-V", &cns13AdobeCNS13VEnc16 },
+ { NULL, NULL }
+};
+
+#endif
diff --git a/pdftops/COPYING b/pdftops/COPYING
new file mode 100644
index 000000000..a43ea2126
--- /dev/null
+++ b/pdftops/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/pdftops/Catalog.cxx b/pdftops/Catalog.cxx
new file mode 100644
index 000000000..fadb4763b
--- /dev/null
+++ b/pdftops/Catalog.cxx
@@ -0,0 +1,308 @@
+//========================================================================
+//
+// Catalog.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stddef.h>
+#include "gmem.h"
+#include "Object.h"
+#include "XRef.h"
+#include "Array.h"
+#include "Dict.h"
+#include "Page.h"
+#include "Error.h"
+#include "Link.h"
+#include "Catalog.h"
+
+//------------------------------------------------------------------------
+// Catalog
+//------------------------------------------------------------------------
+
+Catalog::Catalog(XRef *xrefA, GBool printCommands) {
+ Object catDict, pagesDict;
+ Object obj, obj2;
+ int numPages0;
+ int i;
+
+ ok = gTrue;
+ xref = xrefA;
+ pages = NULL;
+ pageRefs = NULL;
+ numPages = pagesSize = 0;
+ baseURI = NULL;
+
+ xref->getCatalog(&catDict);
+ if (!catDict.isDict()) {
+ error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
+ goto err1;
+ }
+
+ // read page tree
+ catDict.dictLookup("Pages", &pagesDict);
+ // This should really be isDict("Pages"), but I've seen at least one
+ // PDF file where the /Type entry is missing.
+ if (!pagesDict.isDict()) {
+ error(-1, "Top-level pages object is wrong type (%s)",
+ pagesDict.getTypeName());
+ goto err2;
+ }
+ pagesDict.dictLookup("Count", &obj);
+ if (!obj.isInt()) {
+ error(-1, "Page count in top-level pages object is wrong type (%s)",
+ obj.getTypeName());
+ goto err3;
+ }
+ pagesSize = numPages0 = obj.getInt();
+ obj.free();
+ pages = (Page **)gmalloc(pagesSize * sizeof(Page *));
+ pageRefs = (Ref *)gmalloc(pagesSize * sizeof(Ref));
+ for (i = 0; i < pagesSize; ++i) {
+ pages[i] = NULL;
+ pageRefs[i].num = -1;
+ pageRefs[i].gen = -1;
+ }
+ numPages = readPageTree(pagesDict.getDict(), NULL, 0, printCommands);
+ if (numPages != numPages0) {
+ error(-1, "Page count in top-level pages object is incorrect");
+ }
+ pagesDict.free();
+
+ // read named destination dictionary
+ catDict.dictLookup("Dests", &dests);
+
+ // read root of named destination tree
+ if (catDict.dictLookup("Names", &obj)->isDict())
+ obj.dictLookup("Dests", &nameTree);
+ else
+ nameTree.initNull();
+ obj.free();
+
+ // read base URI
+ if (catDict.dictLookup("URI", &obj)->isDict()) {
+ if (obj.dictLookup("Base", &obj2)->isString()) {
+ baseURI = obj2.getString()->copy();
+ }
+ obj2.free();
+ }
+ obj.free();
+
+ catDict.free();
+ return;
+
+ err3:
+ obj.free();
+ err2:
+ pagesDict.free();
+ err1:
+ catDict.free();
+ dests.initNull();
+ nameTree.initNull();
+ ok = gFalse;
+}
+
+Catalog::~Catalog() {
+ int i;
+
+ if (pages) {
+ for (i = 0; i < pagesSize; ++i) {
+ if (pages[i]) {
+ delete pages[i];
+ }
+ }
+ gfree(pages);
+ gfree(pageRefs);
+ }
+ dests.free();
+ nameTree.free();
+ if (baseURI) {
+ delete baseURI;
+ }
+}
+
+int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start,
+ GBool printCommands) {
+ Object kids;
+ Object kid;
+ Object kidRef;
+ PageAttrs *attrs1, *attrs2;
+ Page *page;
+ int i, j;
+
+ attrs1 = new PageAttrs(attrs, pagesDict);
+ pagesDict->lookup("Kids", &kids);
+ if (!kids.isArray()) {
+ error(-1, "Kids object (page %d) is wrong type (%s)",
+ start+1, kids.getTypeName());
+ goto err1;
+ }
+ for (i = 0; i < kids.arrayGetLength(); ++i) {
+ kids.arrayGet(i, &kid);
+ if (kid.isDict("Page")) {
+ attrs2 = new PageAttrs(attrs1, kid.getDict());
+ page = new Page(xref, start+1, kid.getDict(), attrs2, printCommands);
+ if (!page->isOk()) {
+ ++start;
+ goto err3;
+ }
+ if (start >= pagesSize) {
+ pagesSize += 32;
+ pages = (Page **)grealloc(pages, pagesSize * sizeof(Page *));
+ pageRefs = (Ref *)grealloc(pageRefs, pagesSize * sizeof(Ref));
+ for (j = pagesSize - 32; j < pagesSize; ++j) {
+ pages[j] = NULL;
+ pageRefs[j].num = -1;
+ pageRefs[j].gen = -1;
+ }
+ }
+ pages[start] = page;
+ kids.arrayGetNF(i, &kidRef);
+ if (kidRef.isRef()) {
+ pageRefs[start].num = kidRef.getRefNum();
+ pageRefs[start].gen = kidRef.getRefGen();
+ }
+ kidRef.free();
+ ++start;
+ // This should really be isDict("Pages"), but I've seen at least one
+ // PDF file where the /Type entry is missing.
+ } else if (kid.isDict()) {
+ if ((start = readPageTree(kid.getDict(), attrs1, start, printCommands))
+ < 0)
+ goto err2;
+ } else {
+ error(-1, "Kid object (page %d) is wrong type (%s)",
+ start+1, kid.getTypeName());
+ goto err2;
+ }
+ kid.free();
+ }
+ delete attrs1;
+ kids.free();
+ return start;
+
+ err3:
+ delete page;
+ err2:
+ kid.free();
+ err1:
+ kids.free();
+ delete attrs1;
+ ok = gFalse;
+ return -1;
+}
+
+int Catalog::findPage(int num, int gen) {
+ int i;
+
+ for (i = 0; i < numPages; ++i) {
+ if (pageRefs[i].num == num && pageRefs[i].gen == gen)
+ return i + 1;
+ }
+ return 0;
+}
+
+LinkDest *Catalog::findDest(GString *name) {
+ LinkDest *dest;
+ Object obj1, obj2;
+ GBool found;
+
+ // try named destination dictionary then name tree
+ found = gFalse;
+ if (dests.isDict()) {
+ if (!dests.dictLookup(name->getCString(), &obj1)->isNull())
+ found = gTrue;
+ else
+ obj1.free();
+ }
+ if (!found && nameTree.isDict()) {
+ if (!findDestInTree(&nameTree, name, &obj1)->isNull())
+ found = gTrue;
+ else
+ obj1.free();
+ }
+ if (!found)
+ return NULL;
+
+ // construct LinkDest
+ dest = NULL;
+ if (obj1.isArray()) {
+ dest = new LinkDest(obj1.getArray(), gTrue);
+ } else if (obj1.isDict()) {
+ if (obj1.dictLookup("D", &obj2)->isArray())
+ dest = new LinkDest(obj2.getArray(), gTrue);
+ else
+ error(-1, "Bad named destination value");
+ obj2.free();
+ } else {
+ error(-1, "Bad named destination value");
+ }
+ obj1.free();
+
+ return dest;
+}
+
+Object *Catalog::findDestInTree(Object *tree, GString *name, Object *obj) {
+ Object names, name1;
+ Object kids, kid, limits, low, high;
+ GBool done, found;
+ int cmp, i;
+
+ // leaf node
+ if (tree->dictLookup("Names", &names)->isArray()) {
+ done = found = gFalse;
+ for (i = 0; !done && i < names.arrayGetLength(); i += 2) {
+ if (names.arrayGet(i, &name1)->isString()) {
+ cmp = name->cmp(name1.getString());
+ if (cmp == 0) {
+ names.arrayGet(i+1, obj);
+ found = gTrue;
+ done = gTrue;
+ } else if (cmp < 0) {
+ done = gTrue;
+ }
+ name1.free();
+ }
+ }
+ names.free();
+ if (!found)
+ obj->initNull();
+ return obj;
+ }
+ names.free();
+
+ // root or intermediate node
+ done = gFalse;
+ if (tree->dictLookup("Kids", &kids)->isArray()) {
+ for (i = 0; !done && i < kids.arrayGetLength(); ++i) {
+ if (kids.arrayGet(i, &kid)->isDict()) {
+ if (kid.dictLookup("Limits", &limits)->isArray()) {
+ if (limits.arrayGet(0, &low)->isString() &&
+ name->cmp(low.getString()) >= 0) {
+ if (limits.arrayGet(1, &high)->isString() &&
+ name->cmp(high.getString()) <= 0) {
+ findDestInTree(&kid, name, obj);
+ done = gTrue;
+ }
+ high.free();
+ }
+ low.free();
+ }
+ limits.free();
+ }
+ kid.free();
+ }
+ }
+ kids.free();
+
+ // name was outside of ranges of all kids
+ if (!done)
+ obj->initNull();
+
+ return obj;
+}
diff --git a/pdftops/Catalog.h b/pdftops/Catalog.h
new file mode 100644
index 000000000..5bf0c74a7
--- /dev/null
+++ b/pdftops/Catalog.h
@@ -0,0 +1,76 @@
+//========================================================================
+//
+// Catalog.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef CATALOG_H
+#define CATALOG_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+class XRef;
+class Object;
+class Page;
+class PageAttrs;
+struct Ref;
+class LinkDest;
+
+//------------------------------------------------------------------------
+// Catalog
+//------------------------------------------------------------------------
+
+class Catalog {
+public:
+
+ // Constructor.
+ Catalog(XRef *xrefA, GBool printCommands = gFalse);
+
+ // Destructor.
+ ~Catalog();
+
+ // Is catalog valid?
+ GBool isOk() { return ok; }
+
+ // Get number of pages.
+ int getNumPages() { return numPages; }
+
+ // Get a page.
+ Page *getPage(int i) { return pages[i-1]; }
+
+ // Get the reference for a page object.
+ Ref *getPageRef(int i) { return &pageRefs[i-1]; }
+
+ // Return base URI, or NULL if none.
+ GString *getBaseURI() { return baseURI; }
+
+ // Find a page, given its object ID. Returns page number, or 0 if
+ // not found.
+ int findPage(int num, int gen);
+
+ // Find a named destination. Returns the link destination, or
+ // NULL if <name> is not a destination.
+ LinkDest *findDest(GString *name);
+
+private:
+
+ XRef *xref; // the xref table for this PDF file
+ Page **pages; // array of pages
+ Ref *pageRefs; // object ID for each page
+ int numPages; // number of pages
+ int pagesSize; // size of pages array
+ Object dests; // named destination dictionary
+ Object nameTree; // name tree
+ GString *baseURI; // base URI for URI-type links
+ GBool ok; // true if catalog is valid
+
+ int readPageTree(Dict *pages, PageAttrs *attrs, int start,
+ GBool printCommands);
+ Object *findDestInTree(Object *tree, GString *name, Object *obj);
+};
+
+#endif
diff --git a/pdftops/CompactFontInfo.h b/pdftops/CompactFontInfo.h
new file mode 100644
index 000000000..c64266029
--- /dev/null
+++ b/pdftops/CompactFontInfo.h
@@ -0,0 +1,464 @@
+//========================================================================
+//
+// CompactFontInfo.h
+//
+// Copyright 1999 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef COMPACTFONTINFO_H
+#define COMPACTFONTINFO_H
+
+static char *type1CStdStrings[391] = {
+ ".notdef",
+ "space",
+ "exclam",
+ "quotedbl",
+ "numbersign",
+ "dollar",
+ "percent",
+ "ampersand",
+ "quoteright",
+ "parenleft",
+ "parenright",
+ "asterisk",
+ "plus",
+ "comma",
+ "hyphen",
+ "period",
+ "slash",
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less",
+ "equal",
+ "greater",
+ "question",
+ "at",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "bracketleft",
+ "backslash",
+ "bracketright",
+ "asciicircum",
+ "underscore",
+ "quoteleft",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "braceleft",
+ "bar",
+ "braceright",
+ "asciitilde",
+ "exclamdown",
+ "cent",
+ "sterling",
+ "fraction",
+ "yen",
+ "florin",
+ "section",
+ "currency",
+ "quotesingle",
+ "quotedblleft",
+ "guillemotleft",
+ "guilsinglleft",
+ "guilsinglright",
+ "fi",
+ "fl",
+ "endash",
+ "dagger",
+ "daggerdbl",
+ "periodcentered",
+ "paragraph",
+ "bullet",
+ "quotesinglbase",
+ "quotedblbase",
+ "quotedblright",
+ "guillemotright",
+ "ellipsis",
+ "perthousand",
+ "questiondown",
+ "grave",
+ "acute",
+ "circumflex",
+ "tilde",
+ "macron",
+ "breve",
+ "dotaccent",
+ "dieresis",
+ "ring",
+ "cedilla",
+ "hungarumlaut",
+ "ogonek",
+ "caron",
+ "emdash",
+ "AE",
+ "ordfeminine",
+ "Lslash",
+ "Oslash",
+ "OE",
+ "ordmasculine",
+ "ae",
+ "dotlessi",
+ "lslash",
+ "oslash",
+ "oe",
+ "germandbls",
+ "onesuperior",
+ "logicalnot",
+ "mu",
+ "trademark",
+ "Eth",
+ "onehalf",
+ "plusminus",
+ "Thorn",
+ "onequarter",
+ "divide",
+ "brokenbar",
+ "degree",
+ "thorn",
+ "threequarters",
+ "twosuperior",
+ "registered",
+ "minus",
+ "eth",
+ "multiply",
+ "threesuperior",
+ "copyright",
+ "Aacute",
+ "Acircumflex",
+ "Adieresis",
+ "Agrave",
+ "Aring",
+ "Atilde",
+ "Ccedilla",
+ "Eacute",
+ "Ecircumflex",
+ "Edieresis",
+ "Egrave",
+ "Iacute",
+ "Icircumflex",
+ "Idieresis",
+ "Igrave",
+ "Ntilde",
+ "Oacute",
+ "Ocircumflex",
+ "Odieresis",
+ "Ograve",
+ "Otilde",
+ "Scaron",
+ "Uacute",
+ "Ucircumflex",
+ "Udieresis",
+ "Ugrave",
+ "Yacute",
+ "Ydieresis",
+ "Zcaron",
+ "aacute",
+ "acircumflex",
+ "adieresis",
+ "agrave",
+ "aring",
+ "atilde",
+ "ccedilla",
+ "eacute",
+ "ecircumflex",
+ "edieresis",
+ "egrave",
+ "iacute",
+ "icircumflex",
+ "idieresis",
+ "igrave",
+ "ntilde",
+ "oacute",
+ "ocircumflex",
+ "odieresis",
+ "ograve",
+ "otilde",
+ "scaron",
+ "uacute",
+ "ucircumflex",
+ "udieresis",
+ "ugrave",
+ "yacute",
+ "ydieresis",
+ "zcaron",
+ "exclamsmall",
+ "Hungarumlautsmall",
+ "dollaroldstyle",
+ "dollarsuperior",
+ "ampersandsmall",
+ "Acutesmall",
+ "parenleftsuperior",
+ "parenrightsuperior",
+ "twodotenleader",
+ "onedotenleader",
+ "zerooldstyle",
+ "oneoldstyle",
+ "twooldstyle",
+ "threeoldstyle",
+ "fouroldstyle",
+ "fiveoldstyle",
+ "sixoldstyle",
+ "sevenoldstyle",
+ "eightoldstyle",
+ "nineoldstyle",
+ "commasuperior",
+ "threequartersemdash",
+ "periodsuperior",
+ "questionsmall",
+ "asuperior",
+ "bsuperior",
+ "centsuperior",
+ "dsuperior",
+ "esuperior",
+ "isuperior",
+ "lsuperior",
+ "msuperior",
+ "nsuperior",
+ "osuperior",
+ "rsuperior",
+ "ssuperior",
+ "tsuperior",
+ "ff",
+ "ffi",
+ "ffl",
+ "parenleftinferior",
+ "parenrightinferior",
+ "Circumflexsmall",
+ "hyphensuperior",
+ "Gravesmall",
+ "Asmall",
+ "Bsmall",
+ "Csmall",
+ "Dsmall",
+ "Esmall",
+ "Fsmall",
+ "Gsmall",
+ "Hsmall",
+ "Ismall",
+ "Jsmall",
+ "Ksmall",
+ "Lsmall",
+ "Msmall",
+ "Nsmall",
+ "Osmall",
+ "Psmall",
+ "Qsmall",
+ "Rsmall",
+ "Ssmall",
+ "Tsmall",
+ "Usmall",
+ "Vsmall",
+ "Wsmall",
+ "Xsmall",
+ "Ysmall",
+ "Zsmall",
+ "colonmonetary",
+ "onefitted",
+ "rupiah",
+ "Tildesmall",
+ "exclamdownsmall",
+ "centoldstyle",
+ "Lslashsmall",
+ "Scaronsmall",
+ "Zcaronsmall",
+ "Dieresissmall",
+ "Brevesmall",
+ "Caronsmall",
+ "Dotaccentsmall",
+ "Macronsmall",
+ "figuredash",
+ "hypheninferior",
+ "Ogoneksmall",
+ "Ringsmall",
+ "Cedillasmall",
+ "questiondownsmall",
+ "oneeighth",
+ "threeeighths",
+ "fiveeighths",
+ "seveneighths",
+ "onethird",
+ "twothirds",
+ "zerosuperior",
+ "foursuperior",
+ "fivesuperior",
+ "sixsuperior",
+ "sevensuperior",
+ "eightsuperior",
+ "ninesuperior",
+ "zeroinferior",
+ "oneinferior",
+ "twoinferior",
+ "threeinferior",
+ "fourinferior",
+ "fiveinferior",
+ "sixinferior",
+ "seveninferior",
+ "eightinferior",
+ "nineinferior",
+ "centinferior",
+ "dollarinferior",
+ "periodinferior",
+ "commainferior",
+ "Agravesmall",
+ "Aacutesmall",
+ "Acircumflexsmall",
+ "Atildesmall",
+ "Adieresissmall",
+ "Aringsmall",
+ "AEsmall",
+ "Ccedillasmall",
+ "Egravesmall",
+ "Eacutesmall",
+ "Ecircumflexsmall",
+ "Edieresissmall",
+ "Igravesmall",
+ "Iacutesmall",
+ "Icircumflexsmall",
+ "Idieresissmall",
+ "Ethsmall",
+ "Ntildesmall",
+ "Ogravesmall",
+ "Oacutesmall",
+ "Ocircumflexsmall",
+ "Otildesmall",
+ "Odieresissmall",
+ "OEsmall",
+ "Oslashsmall",
+ "Ugravesmall",
+ "Uacutesmall",
+ "Ucircumflexsmall",
+ "Udieresissmall",
+ "Yacutesmall",
+ "Thornsmall",
+ "Ydieresissmall",
+ "001.000",
+ "001.001",
+ "001.002",
+ "001.003",
+ "Black",
+ "Bold",
+ "Book",
+ "Light",
+ "Medium",
+ "Regular",
+ "Roman",
+ "Semibold"
+};
+
+static Gushort type1CISOAdobeCharset[229] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
+ 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
+ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
+ 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
+ 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
+ 220, 221, 222, 223, 224, 225, 226, 227, 228
+};
+
+static Gushort type1CExpertCharset[166] = {
+ 0, 1, 229, 230, 231, 232, 233, 234, 235, 236,
+ 237, 238, 13, 14, 15, 99, 239, 240, 241, 242,
+ 243, 244, 245, 246, 247, 248, 27, 28, 249, 250,
+ 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,
+ 261, 262, 263, 264, 265, 266, 109, 110, 267, 268,
+ 269, 270, 271, 272, 273, 274, 275, 276, 277, 278,
+ 279, 280, 281, 282, 283, 284, 285, 286, 287, 288,
+ 289, 290, 291, 292, 293, 294, 295, 296, 297, 298,
+ 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
+ 309, 310, 311, 312, 313, 314, 315, 316, 317, 318,
+ 158, 155, 163, 319, 320, 321, 322, 323, 324, 325,
+ 326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
+ 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+ 343, 344, 345, 346, 347, 348, 349, 350, 351, 352,
+ 353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
+ 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
+ 373, 374, 375, 376, 377, 378
+};
+
+static Gushort type1CExpertSubsetCharset[87] = {
+ 0, 1, 231, 232, 235, 236, 237, 238, 13, 14,
+ 15, 99, 239, 240, 241, 242, 243, 244, 245, 246,
+ 247, 248, 27, 28, 249, 250, 251, 253, 254, 255,
+ 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
+ 266, 109, 110, 267, 268, 269, 270, 272, 300, 301,
+ 302, 305, 314, 315, 158, 155, 163, 320, 321, 322,
+ 323, 324, 325, 326, 150, 164, 169, 327, 328, 329,
+ 330, 331, 332, 333, 334, 335, 336, 337, 338, 339,
+ 340, 341, 342, 343, 344, 345, 346
+};
+
+#endif
diff --git a/pdftops/Decrypt.cxx b/pdftops/Decrypt.cxx
new file mode 100644
index 000000000..623f59417
--- /dev/null
+++ b/pdftops/Decrypt.cxx
@@ -0,0 +1,384 @@
+//========================================================================
+//
+// Decrypt.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include "gmem.h"
+#include "Decrypt.h"
+
+static void rc4InitKey(Guchar *key, int keyLen, Guchar *state);
+static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c);
+static void md5(Guchar *msg, int msgLen, Guchar *digest);
+
+static Guchar passwordPad[32] = {
+ 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
+ 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
+ 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
+ 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a
+};
+
+//------------------------------------------------------------------------
+// Decrypt
+//------------------------------------------------------------------------
+
+Decrypt::Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen) {
+ int i;
+
+ // construct object key
+ for (i = 0; i < keyLength; ++i) {
+ objKey[i] = fileKey[i];
+ }
+ objKey[keyLength] = objNum & 0xff;
+ objKey[keyLength + 1] = (objNum >> 8) & 0xff;
+ objKey[keyLength + 2] = (objNum >> 16) & 0xff;
+ objKey[keyLength + 3] = objGen & 0xff;
+ objKey[keyLength + 4] = (objGen >> 8) & 0xff;
+ md5(objKey, keyLength + 5, objKey);
+
+ // set up for decryption
+ x = y = 0;
+ if ((objKeyLength = keyLength + 5) > 16) {
+ objKeyLength = 16;
+ }
+ rc4InitKey(objKey, objKeyLength, state);
+}
+
+void Decrypt::reset() {
+ x = y = 0;
+ rc4InitKey(objKey, objKeyLength, state);
+}
+
+Guchar Decrypt::decryptByte(Guchar c) {
+ return rc4DecryptByte(state, &x, &y, c);
+}
+
+GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength,
+ GString *ownerKey, GString *userKey,
+ int permissions, GString *fileID,
+ GString *ownerPassword, GString *userPassword,
+ Guchar *fileKey, GBool *ownerPasswordOk) {
+ Guchar test[32];
+ GString *userPassword2;
+ Guchar fState[256];
+ Guchar fx, fy;
+ int len, i;
+
+ // try using the supplied owner password to generate the user password
+ if (ownerPassword) {
+ len = ownerPassword->getLength();
+ if (len < 32) {
+ memcpy(test, ownerPassword->getCString(), len);
+ memcpy(test + len, passwordPad, 32 - len);
+ } else {
+ memcpy(test, ownerPassword->getCString(), 32);
+ }
+ } else {
+ memcpy(test, passwordPad, 32);
+ }
+ md5(test, 32, test);
+ if (encRevision == 3) {
+ for (i = 0; i < 50; ++i) {
+ md5(test, 16, test);
+ }
+ }
+ rc4InitKey(test, keyLength, fState);
+ fx = fy = 0;
+ for (i = 0; i < 32; ++i) {
+ test[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i));
+ }
+ userPassword2 = new GString((char *)test, 32);
+ if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
+ permissions, fileID, userPassword2, fileKey)) {
+ *ownerPasswordOk = gTrue;
+ delete userPassword2;
+ return gTrue;
+ }
+ *ownerPasswordOk = gFalse;
+ delete userPassword2;
+
+ // try using the supplied user password
+ return makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
+ permissions, fileID, userPassword, fileKey);
+}
+
+GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength,
+ GString *ownerKey, GString *userKey,
+ int permissions, GString *fileID,
+ GString *userPassword, Guchar *fileKey) {
+ Guchar *buf;
+ Guchar test[32];
+ Guchar fState[256];
+ Guchar tmpKey[16];
+ Guchar fx, fy;
+ int len, i, j;
+ GBool ok;
+
+ // generate file key
+ buf = (Guchar *)gmalloc(68 + fileID->getLength());
+ if (userPassword) {
+ len = userPassword->getLength();
+ if (len < 32) {
+ memcpy(buf, userPassword->getCString(), len);
+ memcpy(buf + len, passwordPad, 32 - len);
+ } else {
+ memcpy(buf, userPassword->getCString(), 32);
+ }
+ } else {
+ memcpy(buf, passwordPad, 32);
+ }
+ memcpy(buf + 32, ownerKey->getCString(), 32);
+ buf[64] = permissions & 0xff;
+ buf[65] = (permissions >> 8) & 0xff;
+ buf[66] = (permissions >> 16) & 0xff;
+ buf[67] = (permissions >> 24) & 0xff;
+ memcpy(buf + 68, fileID->getCString(), fileID->getLength());
+ md5(buf, 68 + fileID->getLength(), fileKey);
+ if (encRevision == 3) {
+ for (i = 0; i < 50; ++i) {
+ md5(fileKey, 16, fileKey);
+ }
+ }
+
+ // test user password
+ if (encRevision == 2) {
+ rc4InitKey(fileKey, keyLength, fState);
+ fx = fy = 0;
+ for (i = 0; i < 32; ++i) {
+ test[i] = rc4DecryptByte(fState, &fx, &fy, userKey->getChar(i));
+ }
+ ok = memcmp(test, passwordPad, 32) == 0;
+ } else if (encRevision == 3) {
+ memcpy(test, userKey->getCString(), 32);
+ for (i = 19; i >= 0; --i) {
+ for (j = 0; j < keyLength; ++j) {
+ tmpKey[j] = fileKey[j] ^ i;
+ }
+ rc4InitKey(tmpKey, keyLength, fState);
+ fx = fy = 0;
+ for (j = 0; j < 32; ++j) {
+ test[j] = rc4DecryptByte(fState, &fx, &fy, test[j]);
+ }
+ }
+ memcpy(buf, passwordPad, 32);
+ memcpy(buf + 32, fileID->getCString(), fileID->getLength());
+ md5(buf, 32 + fileID->getLength(), buf);
+ ok = memcmp(test, buf, 16) == 0;
+ } else {
+ ok = gFalse;
+ }
+
+ gfree(buf);
+ return ok;
+}
+
+//------------------------------------------------------------------------
+// RC4-compatible decryption
+//------------------------------------------------------------------------
+
+static void rc4InitKey(Guchar *key, int keyLen, Guchar *state) {
+ Guchar index1, index2;
+ Guchar t;
+ int i;
+
+ for (i = 0; i < 256; ++i)
+ state[i] = i;
+ index1 = index2 = 0;
+ for (i = 0; i < 256; ++i) {
+ index2 = (key[index1] + state[i] + index2) % 256;
+ t = state[i];
+ state[i] = state[index2];
+ state[index2] = t;
+ index1 = (index1 + 1) % keyLen;
+ }
+}
+
+static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c) {
+ Guchar x1, y1, tx, ty;
+
+ x1 = *x = (*x + 1) % 256;
+ y1 = *y = (state[*x] + *y) % 256;
+ tx = state[x1];
+ ty = state[y1];
+ state[x1] = ty;
+ state[y1] = tx;
+ return c ^ state[(tx + ty) % 256];
+}
+
+//------------------------------------------------------------------------
+// MD5 message digest
+//------------------------------------------------------------------------
+
+// this works around a bug in older Sun compilers
+static inline Gulong rotateLeft(Gulong x, int r) {
+ x &= 0xffffffff;
+ return ((x << r) | (x >> (32 - r))) & 0xffffffff;
+}
+
+static inline Gulong md5Round1(Gulong a, Gulong b, Gulong c, Gulong d,
+ Gulong Xk, Gulong s, Gulong Ti) {
+ return b + rotateLeft((a + ((b & c) | (~b & d)) + Xk + Ti), s);
+}
+
+static inline Gulong md5Round2(Gulong a, Gulong b, Gulong c, Gulong d,
+ Gulong Xk, Gulong s, Gulong Ti) {
+ return b + rotateLeft((a + ((b & d) | (c & ~d)) + Xk + Ti), s);
+}
+
+static inline Gulong md5Round3(Gulong a, Gulong b, Gulong c, Gulong d,
+ Gulong Xk, Gulong s, Gulong Ti) {
+ return b + rotateLeft((a + (b ^ c ^ d) + Xk + Ti), s);
+}
+
+static inline Gulong md5Round4(Gulong a, Gulong b, Gulong c, Gulong d,
+ Gulong Xk, Gulong s, Gulong Ti) {
+ return b + rotateLeft((a + (c ^ (b | ~d)) + Xk + Ti), s);
+}
+
+static void md5(Guchar *msg, int msgLen, Guchar *digest) {
+ Gulong x[16];
+ Gulong a, b, c, d, aa, bb, cc, dd;
+ int n64;
+ int i, j, k;
+
+ // compute number of 64-byte blocks
+ // (length + pad byte (0x80) + 8 bytes for length)
+ n64 = (msgLen + 1 + 8 + 63) / 64;
+
+ // initialize a, b, c, d
+ a = 0x67452301;
+ b = 0xefcdab89;
+ c = 0x98badcfe;
+ d = 0x10325476;
+
+ // loop through blocks
+ k = 0;
+ for (i = 0; i < n64; ++i) {
+
+ // grab a 64-byte block
+ for (j = 0; j < 16 && k < msgLen - 3; ++j, k += 4)
+ x[j] = (((((msg[k+3] << 8) + msg[k+2]) << 8) + msg[k+1]) << 8) + msg[k];
+ if (i == n64 - 1) {
+ if (k == msgLen - 3)
+ x[j] = 0x80000000 + (((msg[k+2] << 8) + msg[k+1]) << 8) + msg[k];
+ else if (k == msgLen - 2)
+ x[j] = 0x800000 + (msg[k+1] << 8) + msg[k];
+ else if (k == msgLen - 1)
+ x[j] = 0x8000 + msg[k];
+ else
+ x[j] = 0x80;
+ ++j;
+ while (j < 16)
+ x[j++] = 0;
+ x[14] = msgLen << 3;
+ }
+
+ // save a, b, c, d
+ aa = a;
+ bb = b;
+ cc = c;
+ dd = d;
+
+ // round 1
+ a = md5Round1(a, b, c, d, x[0], 7, 0xd76aa478);
+ d = md5Round1(d, a, b, c, x[1], 12, 0xe8c7b756);
+ c = md5Round1(c, d, a, b, x[2], 17, 0x242070db);
+ b = md5Round1(b, c, d, a, x[3], 22, 0xc1bdceee);
+ a = md5Round1(a, b, c, d, x[4], 7, 0xf57c0faf);
+ d = md5Round1(d, a, b, c, x[5], 12, 0x4787c62a);
+ c = md5Round1(c, d, a, b, x[6], 17, 0xa8304613);
+ b = md5Round1(b, c, d, a, x[7], 22, 0xfd469501);
+ a = md5Round1(a, b, c, d, x[8], 7, 0x698098d8);
+ d = md5Round1(d, a, b, c, x[9], 12, 0x8b44f7af);
+ c = md5Round1(c, d, a, b, x[10], 17, 0xffff5bb1);
+ b = md5Round1(b, c, d, a, x[11], 22, 0x895cd7be);
+ a = md5Round1(a, b, c, d, x[12], 7, 0x6b901122);
+ d = md5Round1(d, a, b, c, x[13], 12, 0xfd987193);
+ c = md5Round1(c, d, a, b, x[14], 17, 0xa679438e);
+ b = md5Round1(b, c, d, a, x[15], 22, 0x49b40821);
+
+ // round 2
+ a = md5Round2(a, b, c, d, x[1], 5, 0xf61e2562);
+ d = md5Round2(d, a, b, c, x[6], 9, 0xc040b340);
+ c = md5Round2(c, d, a, b, x[11], 14, 0x265e5a51);
+ b = md5Round2(b, c, d, a, x[0], 20, 0xe9b6c7aa);
+ a = md5Round2(a, b, c, d, x[5], 5, 0xd62f105d);
+ d = md5Round2(d, a, b, c, x[10], 9, 0x02441453);
+ c = md5Round2(c, d, a, b, x[15], 14, 0xd8a1e681);
+ b = md5Round2(b, c, d, a, x[4], 20, 0xe7d3fbc8);
+ a = md5Round2(a, b, c, d, x[9], 5, 0x21e1cde6);
+ d = md5Round2(d, a, b, c, x[14], 9, 0xc33707d6);
+ c = md5Round2(c, d, a, b, x[3], 14, 0xf4d50d87);
+ b = md5Round2(b, c, d, a, x[8], 20, 0x455a14ed);
+ a = md5Round2(a, b, c, d, x[13], 5, 0xa9e3e905);
+ d = md5Round2(d, a, b, c, x[2], 9, 0xfcefa3f8);
+ c = md5Round2(c, d, a, b, x[7], 14, 0x676f02d9);
+ b = md5Round2(b, c, d, a, x[12], 20, 0x8d2a4c8a);
+
+ // round 3
+ a = md5Round3(a, b, c, d, x[5], 4, 0xfffa3942);
+ d = md5Round3(d, a, b, c, x[8], 11, 0x8771f681);
+ c = md5Round3(c, d, a, b, x[11], 16, 0x6d9d6122);
+ b = md5Round3(b, c, d, a, x[14], 23, 0xfde5380c);
+ a = md5Round3(a, b, c, d, x[1], 4, 0xa4beea44);
+ d = md5Round3(d, a, b, c, x[4], 11, 0x4bdecfa9);
+ c = md5Round3(c, d, a, b, x[7], 16, 0xf6bb4b60);
+ b = md5Round3(b, c, d, a, x[10], 23, 0xbebfbc70);
+ a = md5Round3(a, b, c, d, x[13], 4, 0x289b7ec6);
+ d = md5Round3(d, a, b, c, x[0], 11, 0xeaa127fa);
+ c = md5Round3(c, d, a, b, x[3], 16, 0xd4ef3085);
+ b = md5Round3(b, c, d, a, x[6], 23, 0x04881d05);
+ a = md5Round3(a, b, c, d, x[9], 4, 0xd9d4d039);
+ d = md5Round3(d, a, b, c, x[12], 11, 0xe6db99e5);
+ c = md5Round3(c, d, a, b, x[15], 16, 0x1fa27cf8);
+ b = md5Round3(b, c, d, a, x[2], 23, 0xc4ac5665);
+
+ // round 4
+ a = md5Round4(a, b, c, d, x[0], 6, 0xf4292244);
+ d = md5Round4(d, a, b, c, x[7], 10, 0x432aff97);
+ c = md5Round4(c, d, a, b, x[14], 15, 0xab9423a7);
+ b = md5Round4(b, c, d, a, x[5], 21, 0xfc93a039);
+ a = md5Round4(a, b, c, d, x[12], 6, 0x655b59c3);
+ d = md5Round4(d, a, b, c, x[3], 10, 0x8f0ccc92);
+ c = md5Round4(c, d, a, b, x[10], 15, 0xffeff47d);
+ b = md5Round4(b, c, d, a, x[1], 21, 0x85845dd1);
+ a = md5Round4(a, b, c, d, x[8], 6, 0x6fa87e4f);
+ d = md5Round4(d, a, b, c, x[15], 10, 0xfe2ce6e0);
+ c = md5Round4(c, d, a, b, x[6], 15, 0xa3014314);
+ b = md5Round4(b, c, d, a, x[13], 21, 0x4e0811a1);
+ a = md5Round4(a, b, c, d, x[4], 6, 0xf7537e82);
+ d = md5Round4(d, a, b, c, x[11], 10, 0xbd3af235);
+ c = md5Round4(c, d, a, b, x[2], 15, 0x2ad7d2bb);
+ b = md5Round4(b, c, d, a, x[9], 21, 0xeb86d391);
+
+ // increment a, b, c, d
+ a += aa;
+ b += bb;
+ c += cc;
+ d += dd;
+ }
+
+ // break digest into bytes
+ digest[0] = a & 0xff;
+ digest[1] = (a >>= 8) & 0xff;
+ digest[2] = (a >>= 8) & 0xff;
+ digest[3] = (a >>= 8) & 0xff;
+ digest[4] = b & 0xff;
+ digest[5] = (b >>= 8) & 0xff;
+ digest[6] = (b >>= 8) & 0xff;
+ digest[7] = (b >>= 8) & 0xff;
+ digest[8] = c & 0xff;
+ digest[9] = (c >>= 8) & 0xff;
+ digest[10] = (c >>= 8) & 0xff;
+ digest[11] = (c >>= 8) & 0xff;
+ digest[12] = d & 0xff;
+ digest[13] = (d >>= 8) & 0xff;
+ digest[14] = (d >>= 8) & 0xff;
+ digest[15] = (d >>= 8) & 0xff;
+}
diff --git a/pdftops/Decrypt.h b/pdftops/Decrypt.h
new file mode 100644
index 000000000..1bdb2b7ec
--- /dev/null
+++ b/pdftops/Decrypt.h
@@ -0,0 +1,59 @@
+//========================================================================
+//
+// Decrypt.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef DECRYPT_H
+#define DECRYPT_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "gtypes.h"
+#include "GString.h"
+
+//------------------------------------------------------------------------
+// Decrypt
+//------------------------------------------------------------------------
+
+class Decrypt {
+public:
+
+ // Initialize the decryptor object.
+ Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen);
+
+ // Reset decryption.
+ void reset();
+
+ // Decrypt one byte.
+ Guchar decryptByte(Guchar c);
+
+ // Generate a file key. The <fileKey> buffer must have space for at
+ // least 16 bytes. Checks <ownerPassword> and then <userPassword>
+ // and returns true if either is correct. Sets <ownerPasswordOk> if
+ // the owner password was correct. Either or both of the passwords
+ // may be NULL, which is treated as an empty string.
+ static GBool makeFileKey(int encVersion, int encRevision, int keyLength,
+ GString *ownerKey, GString *userKey,
+ int permissions, GString *fileID,
+ GString *ownerPassword, GString *userPassword,
+ Guchar *fileKey, GBool *ownerPasswordOk);
+
+private:
+
+ static GBool makeFileKey2(int encVersion, int encRevision, int keyLength,
+ GString *ownerKey, GString *userKey,
+ int permissions, GString *fileID,
+ GString *userPassword, Guchar *fileKey);
+
+ int objKeyLength;
+ Guchar objKey[21];
+ Guchar state[256];
+ Guchar x, y;
+};
+
+#endif
diff --git a/pdftops/Dependencies b/pdftops/Dependencies
new file mode 100644
index 000000000..d1a17fc07
--- /dev/null
+++ b/pdftops/Dependencies
@@ -0,0 +1,59 @@
+# DO NOT DELETE
+
+pdftops.o: parseargs.h gtypes.h GString.h gmem.h Object.h Array.h Dict.h
+pdftops.o: Stream.h XRef.h Catalog.h Page.h PDFDoc.h Link.h PSOutputDev.h
+pdftops.o: config.h ../config.h OutputDev.h Params.h Error.h ../cups/cups.h
+pdftops.o: ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h
+Decrypt.o: gmem.h Decrypt.h gtypes.h GString.h
+GString.o: gtypes.h GString.h
+gfile.o: GString.h gfile.h config.h ../config.h gtypes.h ../cups/cups.h
+gfile.o: ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h
+gmempp.o: gmem.h
+Array.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h
+Catalog.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h XRef.h
+Catalog.o: Page.h Error.h config.h ../config.h Link.h Catalog.h
+Dict.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h XRef.h
+Error.o: gtypes.h Params.h Error.h config.h ../config.h
+FontEncoding.o: gmem.h FontEncoding.h gtypes.h
+FontFile.o: gmem.h Error.h config.h ../config.h FontFile.h gtypes.h GString.h
+FontFile.o: FontEncoding.h StdFontInfo.h CompactFontInfo.h
+FormWidget.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h
+FormWidget.o: Gfx.h FormWidget.h
+Function.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h
+Function.o: Error.h config.h ../config.h Function.h
+Gfx.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h Lexer.h
+Gfx.o: Parser.h GfxFont.h FontEncoding.h GfxState.h Function.h OutputDev.h
+Gfx.o: Params.h Page.h Error.h config.h ../config.h Gfx.h
+GfxFont.o: GString.h gmem.h gfile.h config.h ../config.h gtypes.h Object.h
+GfxFont.o: Array.h Dict.h Stream.h Error.h Params.h FontFile.h FontEncoding.h
+GfxFont.o: GfxFont.h FontInfo.h Japan12CMapInfo.h GB12CMapInfo.h
+GfxFont.o: CNS13CMapInfo.h
+GfxState.o: gmem.h Error.h config.h ../config.h Object.h gtypes.h GString.h
+GfxState.o: Array.h Dict.h Stream.h Page.h GfxState.h Function.h
+Lexer.o: Lexer.h Object.h gtypes.h gmem.h GString.h Array.h Dict.h Stream.h
+Lexer.o: Error.h config.h ../config.h
+Link.o: gmem.h GString.h Error.h config.h ../config.h Object.h gtypes.h
+Link.o: Array.h Dict.h Stream.h Link.h
+Object.o: Object.h gtypes.h gmem.h GString.h Array.h Dict.h Stream.h Error.h
+Object.o: config.h ../config.h XRef.h
+OutputDev.o: Object.h gtypes.h gmem.h GString.h Array.h Dict.h Stream.h
+OutputDev.o: GfxState.h Function.h OutputDev.h
+Page.o: Object.h gtypes.h gmem.h GString.h Array.h Dict.h Stream.h XRef.h
+Page.o: Link.h OutputDev.h Gfx.h FormWidget.h Error.h config.h ../config.h
+Page.o: Params.h Page.h
+Params.o: gtypes.h gmem.h GString.h gfile.h config.h ../config.h Params.h
+Parser.o: Object.h gtypes.h gmem.h GString.h Array.h Dict.h Stream.h Parser.h
+Parser.o: Lexer.h XRef.h Error.h config.h ../config.h Decrypt.h
+PDFDoc.o: GString.h config.h ../config.h Page.h Object.h gtypes.h gmem.h
+PDFDoc.o: Array.h Dict.h Stream.h Catalog.h XRef.h Link.h OutputDev.h
+PDFDoc.o: Params.h Error.h Lexer.h Parser.h PDFDoc.h
+PSOutputDev.o: GString.h config.h ../config.h Object.h gtypes.h gmem.h
+PSOutputDev.o: Array.h Dict.h Stream.h Error.h Function.h GfxState.h
+PSOutputDev.o: GfxFont.h FontEncoding.h FontFile.h Catalog.h Page.h
+PSOutputDev.o: FormWidget.h PSOutputDev.h OutputDev.h Japan12ToRKSJ.h
+Stream.o: gmem.h gfile.h config.h ../config.h gtypes.h Error.h Object.h
+Stream.o: GString.h Array.h Dict.h Stream.h Decrypt.h Stream-CCITT.h
+XRef.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h Lexer.h
+XRef.o: Parser.h Decrypt.h Error.h config.h ../config.h XRef.h
+gmem.o: gmem.h
+parseargs.o: parseargs.h gtypes.h
diff --git a/pdftops/Dict.cxx b/pdftops/Dict.cxx
new file mode 100644
index 000000000..1ebadfce0
--- /dev/null
+++ b/pdftops/Dict.cxx
@@ -0,0 +1,89 @@
+//========================================================================
+//
+// Dict.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include "gmem.h"
+#include "Object.h"
+#include "XRef.h"
+#include "Dict.h"
+
+//------------------------------------------------------------------------
+// Dict
+//------------------------------------------------------------------------
+
+Dict::Dict(XRef *xrefA) {
+ xref = xrefA;
+ entries = NULL;
+ size = length = 0;
+ ref = 1;
+}
+
+Dict::~Dict() {
+ int i;
+
+ for (i = 0; i < length; ++i) {
+ gfree(entries[i].key);
+ entries[i].val.free();
+ }
+ gfree(entries);
+}
+
+void Dict::add(char *key, Object *val) {
+ if (length + 1 > size) {
+ size += 8;
+ entries = (DictEntry *)grealloc(entries, size * sizeof(DictEntry));
+ }
+ entries[length].key = key;
+ entries[length].val = *val;
+ ++length;
+}
+
+inline DictEntry *Dict::find(char *key) {
+ int i;
+
+ for (i = 0; i < length; ++i) {
+ if (!strcmp(key, entries[i].key))
+ return &entries[i];
+ }
+ return NULL;
+}
+
+GBool Dict::is(char *type) {
+ DictEntry *e;
+
+ return (e = find("Type")) && e->val.isName(type);
+}
+
+Object *Dict::lookup(char *key, Object *obj) {
+ DictEntry *e;
+
+ return (e = find(key)) ? e->val.fetch(xref, obj) : obj->initNull();
+}
+
+Object *Dict::lookupNF(char *key, Object *obj) {
+ DictEntry *e;
+
+ return (e = find(key)) ? e->val.copy(obj) : obj->initNull();
+}
+
+char *Dict::getKey(int i) {
+ return entries[i].key;
+}
+
+Object *Dict::getVal(int i, Object *obj) {
+ return entries[i].val.fetch(xref, obj);
+}
+
+Object *Dict::getValNF(int i, Object *obj) {
+ return entries[i].val.copy(obj);
+}
diff --git a/pdftops/Dict.h b/pdftops/Dict.h
new file mode 100644
index 000000000..c4f1ea58d
--- /dev/null
+++ b/pdftops/Dict.h
@@ -0,0 +1,75 @@
+//========================================================================
+//
+// Dict.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef DICT_H
+#define DICT_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "Object.h"
+
+//------------------------------------------------------------------------
+// Dict
+//------------------------------------------------------------------------
+
+struct DictEntry {
+ char *key;
+ Object val;
+};
+
+class Dict {
+public:
+
+ // Constructor.
+ Dict(XRef *xrefA);
+
+ // Destructor.
+ ~Dict();
+
+ // Reference counting.
+ int incRef() { return ++ref; }
+ int decRef() { return --ref; }
+
+ // Get number of entries.
+ int getLength() { return length; }
+
+ // Add an entry. NB: does not copy key.
+ void add(char *key, Object *val);
+
+ // Check if dictionary is of specified type.
+ GBool is(char *type);
+
+ // Look up an entry and return the value. Returns a null object
+ // if <key> is not in the dictionary.
+ Object *lookup(char *key, Object *obj);
+ Object *lookupNF(char *key, Object *obj);
+
+ // Iterative accessors.
+ char *getKey(int i);
+ Object *getVal(int i, Object *obj);
+ Object *getValNF(int i, Object *obj);
+
+ // Set the xref pointer. This is only used in one special case: the
+ // trailer dictionary, which is read before the xref table is
+ // parsed.
+ void setXRef(XRef *xrefA) { xref = xrefA; }
+
+private:
+
+ XRef *xref; // the xref table for this PDF file
+ DictEntry *entries; // array of entries
+ int size; // size of <entries> array
+ int length; // number of entries in dictionary
+ int ref; // reference count
+
+ DictEntry *find(char *key);
+};
+
+#endif
diff --git a/pdftops/Error.cxx b/pdftops/Error.cxx
new file mode 100644
index 000000000..81010e019
--- /dev/null
+++ b/pdftops/Error.cxx
@@ -0,0 +1,47 @@
+//========================================================================
+//
+// Error.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include "gtypes.h"
+#include "Params.h"
+#include "Error.h"
+
+FILE *errFile;
+GBool errQuiet;
+
+void errorInit() {
+ if (errQuiet) {
+ errFile = NULL;
+ } else {
+ errFile = stderr;
+ }
+}
+
+void CDECL error(int pos, const char *msg, ...) {
+ va_list args;
+
+ if (errQuiet) {
+ return;
+ }
+ if (pos >= 0) {
+ fprintf(errFile, "Error (%d): ", pos);
+ } else {
+ fprintf(errFile, "Error: ");
+ }
+ va_start(args, msg);
+ vfprintf(errFile, msg, args);
+ va_end(args);
+ fprintf(errFile, "\n");
+ fflush(errFile);
+}
diff --git a/pdftops/Error.h b/pdftops/Error.h
new file mode 100644
index 000000000..926abcd5a
--- /dev/null
+++ b/pdftops/Error.h
@@ -0,0 +1,26 @@
+//========================================================================
+//
+// Error.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef ERROR_H
+#define ERROR_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <stdio.h>
+#include "config.h"
+
+// File to send error (and other) messages to.
+extern FILE *errFile;
+
+extern void errorInit();
+
+extern void CDECL error(int pos, const char *msg, ...);
+
+#endif
diff --git a/pdftops/FontEncoding.cxx b/pdftops/FontEncoding.cxx
new file mode 100644
index 000000000..3d084cc9d
--- /dev/null
+++ b/pdftops/FontEncoding.cxx
@@ -0,0 +1,143 @@
+//========================================================================
+//
+// FontEncoding.cc
+//
+// Copyright 1999 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include "gmem.h"
+#include "FontEncoding.h"
+
+//------------------------------------------------------------------------
+// FontEncoding
+//------------------------------------------------------------------------
+
+inline int FontEncoding::hash(char *name) {
+ Guint h;
+
+ h = (Guint)name[0] & 0xff;
+ if (h && name[1])
+ h = h * 61 + ((Guint)name[1] & 0xff);
+ return (int)(h % (Guint)fontEncHashSize);
+}
+
+FontEncoding::FontEncoding() {
+ int i;
+
+ encoding = (char **)gmalloc(256 * sizeof(char *));
+ size = 256;
+ freeEnc = gTrue;
+ for (i = 0; i < 256; ++i)
+ encoding[i] = NULL;
+ for (i = 0; i < fontEncHashSize; ++i)
+ hashTab[i] = -1;
+}
+
+FontEncoding::FontEncoding(char **encodingA, int sizeA) {
+ int i;
+
+ encoding = encodingA;
+ size = sizeA;
+ freeEnc = gFalse;
+ for (i = 0; i < fontEncHashSize; ++i)
+ hashTab[i] = -1;
+ for (i = 0; i < size; ++i) {
+ if (encoding[i])
+ addChar1(i, encoding[i]);
+ }
+}
+
+FontEncoding::FontEncoding(FontEncoding *fontEnc) {
+ int i;
+
+ encoding = (char **)gmalloc(fontEnc->size * sizeof(char *));
+ size = fontEnc->size;
+ freeEnc = gTrue;
+ for (i = 0; i < size; ++i) {
+ encoding[i] =
+ fontEnc->encoding[i] ? copyString(fontEnc->encoding[i]) : (char *)NULL;
+ }
+ memcpy(hashTab, fontEnc->hashTab, fontEncHashSize * sizeof(short));
+}
+
+void FontEncoding::addChar(int code, char *name) {
+ int h, i;
+
+ // replace character associated with code
+ if (encoding[code]) {
+ h = hash(encoding[code]);
+ for (i = 0; i < fontEncHashSize; ++i) {
+ if (hashTab[h] == code) {
+ hashTab[h] = -2;
+ break;
+ }
+ if (++h == fontEncHashSize)
+ h = 0;
+ }
+ gfree(encoding[code]);
+ }
+
+ // associate name with code
+ encoding[code] = name;
+
+ // insert name in hash table
+ addChar1(code, name);
+}
+
+void FontEncoding::addChar1(int code, char *name) {
+ int h, i, code2;
+
+ // insert name in hash table
+ h = hash(name);
+ for (i = 0; i < fontEncHashSize; ++i) {
+ code2 = hashTab[h];
+ if (code2 < 0) {
+ hashTab[h] = code;
+ break;
+ } else if (encoding[code2] && !strcmp(encoding[code2], name)) {
+ // keep the highest code for each char -- this is needed because
+ // X won't display chars with codes < 32
+ if (code > code2)
+ hashTab[h] = code;
+ break;
+ }
+ if (++h == fontEncHashSize)
+ h = 0;
+ }
+}
+
+FontEncoding::~FontEncoding() {
+ int i;
+
+ if (freeEnc) {
+ for (i = 0; i < size; ++i) {
+ if (encoding[i])
+ gfree(encoding[i]);
+ }
+ gfree(encoding);
+ }
+}
+
+int FontEncoding::getCharCode(char *name) {
+ int h, i, code;
+
+ h = hash(name);
+ for (i = 0; i < fontEncHashSize; ++i) {
+ code = hashTab[h];
+ if (code == -1 ||
+ (code >= 0 && encoding[code] && !strcmp(encoding[code], name)))
+ return code;
+ if (++h >= fontEncHashSize)
+ h = 0;
+ }
+ return -1;
+}
diff --git a/pdftops/FontEncoding.h b/pdftops/FontEncoding.h
new file mode 100644
index 000000000..9a5695dbe
--- /dev/null
+++ b/pdftops/FontEncoding.h
@@ -0,0 +1,64 @@
+//========================================================================
+//
+// FontEncoding.h
+//
+// Copyright 1999 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef FONTENCODING_H
+#define FONTENCODING_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "gtypes.h"
+
+//------------------------------------------------------------------------
+// FontEncoding
+//------------------------------------------------------------------------
+
+#define fontEncHashSize 419
+
+class FontEncoding {
+public:
+
+ // Construct an empty encoding.
+ FontEncoding();
+
+ // Construct an encoding from an array of char names.
+ FontEncoding(char **encodingA, int sizeA);
+
+ // Destructor.
+ ~FontEncoding();
+
+ // Create a copy of the encoding.
+ FontEncoding *copy() { return new FontEncoding(this); }
+
+ // Return number of codes in encoding, i.e., max code + 1.
+ int getSize() { return size; }
+
+ // Add a char to the encoding.
+ void addChar(int code, char *name);
+
+ // Return the character name associated with <code>.
+ char *getCharName(int code) { return encoding[code]; }
+
+ // Return the code associated with <name>.
+ int getCharCode(char *name);
+
+private:
+
+ FontEncoding(FontEncoding *fontEnc);
+ int hash(char *name);
+ void addChar1(int code, char *name);
+
+ char **encoding; // code --> name mapping
+ int size; // number of codes
+ GBool freeEnc; // should we free the encoding array?
+ short // name --> code hash table
+ hashTab[fontEncHashSize];
+};
+
+#endif
diff --git a/pdftops/FontFile.cxx b/pdftops/FontFile.cxx
new file mode 100644
index 000000000..4054db7cd
--- /dev/null
+++ b/pdftops/FontFile.cxx
@@ -0,0 +1,2530 @@
+//========================================================================
+//
+// FontFile.cc
+//
+// Copyright 1999 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <math.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <ctype.h>
+#include "gmem.h"
+#include "Error.h"
+#include "FontFile.h"
+
+#include "StdFontInfo.h"
+#include "CompactFontInfo.h"
+
+//------------------------------------------------------------------------
+
+static Guint getWord(Guchar *ptr, int size);
+static double getNum(Guchar **ptr, GBool *fp);
+static char *getString(int sid, Guchar *stringIdxPtr,
+ Guchar *stringStartPtr, int stringOffSize,
+ char *buf);
+
+//------------------------------------------------------------------------
+
+static inline char *nextLine(char *line, char *end) {
+ while (line < end && *line != '\n' && *line != '\r')
+ ++line;
+ while (line < end && *line == '\n' || *line == '\r')
+ ++line;
+ return line;
+}
+
+static char hexChars[17] = "0123456789ABCDEF";
+
+//------------------------------------------------------------------------
+// FontFile
+//------------------------------------------------------------------------
+
+FontFile::FontFile() {
+}
+
+FontFile::~FontFile() {
+}
+
+//------------------------------------------------------------------------
+// Type1FontFile
+//------------------------------------------------------------------------
+
+Type1FontFile::Type1FontFile(char *file, int len) {
+ char *line, *line1, *p, *p2;
+ char buf[256];
+ char c;
+ int n, code, i;
+
+ name = NULL;
+ encoding = NULL;
+ freeEnc = gTrue;
+
+ for (i = 1, line = file; i <= 100 && line < file + len && !encoding; ++i) {
+
+ // get font name
+ if (!strncmp(line, "/FontName", 9)) {
+ strncpy(buf, line, 255);
+ buf[255] = '\0';
+ if ((p = strchr(buf+9, '/')) &&
+ (p = strtok(p+1, " \t\n\r")))
+ name = copyString(p);
+ line = nextLine(line, file + len);
+
+ // get encoding
+ } else if (!strncmp(line, "/Encoding StandardEncoding def", 30)) {
+ encoding = type1StdEncoding.copy();
+ } else if (!strncmp(line, "/Encoding 256 array", 19)) {
+ encoding = new FontEncoding();
+ for (i = 0; i < 300; ++i) {
+ line1 = nextLine(line, file + len);
+ if ((n = line1 - line) > 255)
+ n = 255;
+ strncpy(buf, line, n);
+ buf[n] = '\0';
+ for (p = buf; *p == ' ' || *p == '\t'; ++p) ;
+ if (!strncmp(p, "dup", 3)) {
+ for (p += 3; *p == ' ' || *p == '\t'; ++p) ;
+ for (p2 = p; *p2 >= '0' && *p2 <= '9'; ++p2) ;
+ if (*p2) {
+ c = *p2;
+ *p2 = '\0';
+ if ((code = atoi(p)) < 256) {
+ *p2 = c;
+ for (p = p2; *p == ' ' || *p == '\t'; ++p) ;
+ if (*p == '/') {
+ ++p;
+ for (p2 = p; *p2 && *p2 != ' ' && *p2 != '\t'; ++p2) ;
+ *p2 = '\0';
+ encoding->addChar(code, copyString(p));
+ }
+ }
+ }
+ } else {
+ if (strtok(buf, " \t") &&
+ (p = strtok(NULL, " \t\n\r")) && !strcmp(p, "def")) {
+ break;
+ }
+ }
+ line = line1;
+ }
+ //~ check for getinterval/putinterval junk
+
+ } else {
+ line = nextLine(line, file + len);
+ }
+ }
+}
+
+Type1FontFile::~Type1FontFile() {
+ if (name)
+ gfree(name);
+ if (encoding && freeEnc)
+ delete encoding;
+}
+
+FontEncoding *Type1FontFile::getEncoding(GBool taken) {
+ if (taken)
+ freeEnc = gFalse;
+ return encoding;
+}
+
+//------------------------------------------------------------------------
+// Type1CFontFile
+//------------------------------------------------------------------------
+
+Type1CFontFile::Type1CFontFile(char *file, int len) {
+ char buf[256];
+ Guchar *topPtr, *idxStartPtr, *idxPtr0, *idxPtr1;
+ Guchar *stringIdxPtr, *stringStartPtr;
+ int topOffSize, idxOffSize, stringOffSize;
+ int nFonts, nStrings, nGlyphs;
+ int nCodes, nRanges, nLeft, nSups;
+ Gushort *glyphNames;
+ int charset, enc, charstrings;
+ int charsetFormat, encFormat;
+ int c, sid;
+ double op[48];
+ double x;
+ GBool isFP;
+ int key;
+ int i, j, n;
+
+ name = NULL;
+ encoding = NULL;
+ freeEnc = gTrue;
+
+ // read header
+ topPtr = (Guchar *)file + (file[2] & 0xff);
+ topOffSize = file[3] & 0xff;
+
+ // read name index (first font only)
+ nFonts = getWord(topPtr, 2);
+ idxOffSize = topPtr[2];
+ topPtr += 3;
+ idxStartPtr = topPtr + (nFonts + 1) * idxOffSize - 1;
+ idxPtr0 = idxStartPtr + getWord(topPtr, idxOffSize);
+ idxPtr1 = idxStartPtr + getWord(topPtr + idxOffSize, idxOffSize);
+ if ((n = idxPtr1 - idxPtr0) > 255)
+ n = 255;
+ strncpy(buf, (char *)idxPtr0, n);
+ buf[n] = '\0';
+ name = copyString(buf);
+ topPtr = idxStartPtr + getWord(topPtr + nFonts * idxOffSize, idxOffSize);
+
+ // read top dict index (first font only)
+ nFonts = getWord(topPtr, 2);
+ idxOffSize = topPtr[2];
+ topPtr += 3;
+ idxStartPtr = topPtr + (nFonts + 1) * idxOffSize - 1;
+ idxPtr0 = idxStartPtr + getWord(topPtr, idxOffSize);
+ idxPtr1 = idxStartPtr + getWord(topPtr + idxOffSize, idxOffSize);
+ charset = 0;
+ enc = 0;
+ charstrings = 0;
+ i = 0;
+ while (idxPtr0 < idxPtr1) {
+ if (*idxPtr0 <= 27 || *idxPtr0 == 31) {
+ key = *idxPtr0++;
+ if (key == 0x0c)
+ key = (key << 8) | *idxPtr0++;
+ if (key == 0x0f) { // charset
+ charset = (int)op[0];
+ } else if (key == 0x10) { // encoding
+ enc = (int)op[0];
+ } else if (key == 0x11) { // charstrings
+ charstrings = (int)op[0];
+ }
+ i = 0;
+ } else {
+ x = getNum(&idxPtr0, &isFP);
+ if (i < 48)
+ op[i++] = x;
+ }
+ }
+ topPtr = idxStartPtr + getWord(topPtr + nFonts * idxOffSize, idxOffSize);
+
+ // read string index
+ nStrings = getWord(topPtr, 2);
+ stringOffSize = topPtr[2];
+ topPtr += 3;
+ stringIdxPtr = topPtr;
+ stringStartPtr = topPtr + (nStrings + 1) * stringOffSize - 1;
+ topPtr = stringStartPtr + getWord(topPtr + nStrings * stringOffSize,
+ stringOffSize);
+
+ // get number of glyphs from charstrings index
+ topPtr = (Guchar *)file + charstrings;
+ nGlyphs = getWord(topPtr, 2);
+
+ // read charset
+ if (charset == 0) {
+ glyphNames = type1CISOAdobeCharset;
+ } else if (charset == 1) {
+ glyphNames = type1CExpertCharset;
+ } else if (charset == 2) {
+ glyphNames = type1CExpertSubsetCharset;
+ } else {
+ glyphNames = (Gushort *)gmalloc(nGlyphs * sizeof(Gushort));
+ glyphNames[0] = 0;
+ topPtr = (Guchar *)file + charset;
+ charsetFormat = *topPtr++;
+ if (charsetFormat == 0) {
+ for (i = 1; i < nGlyphs; ++i) {
+ glyphNames[i] = getWord(topPtr, 2);
+ topPtr += 2;
+ }
+ } else if (charsetFormat == 1) {
+ i = 1;
+ while (i < nGlyphs) {
+ c = getWord(topPtr, 2);
+ topPtr += 2;
+ nLeft = *topPtr++;
+ for (j = 0; j <= nLeft; ++j)
+ glyphNames[i++] = c++;
+ }
+ } else if (charsetFormat == 2) {
+ i = 1;
+ while (i < nGlyphs) {
+ c = getWord(topPtr, 2);
+ topPtr += 2;
+ nLeft = getWord(topPtr, 2);
+ topPtr += 2;
+ for (j = 0; j <= nLeft; ++j)
+ glyphNames[i++] = c++;
+ }
+ }
+ }
+
+ // read encoding (glyph -> code mapping)
+ if (enc == 0) {
+ encoding = type1StdEncoding.copy();
+ } else if (enc == 1) {
+ encoding = type1ExpertEncoding.copy();
+ } else {
+ encoding = new FontEncoding();
+ topPtr = (Guchar *)file + enc;
+ encFormat = *topPtr++;
+ if ((encFormat & 0x7f) == 0) {
+ nCodes = 1 + *topPtr++;
+ if (nCodes > nGlyphs) {
+ nCodes = nGlyphs;
+ }
+ for (i = 1; i < nCodes; ++i) {
+ c = *topPtr++;
+ getString(glyphNames[i], stringIdxPtr, stringStartPtr,
+ stringOffSize, buf);
+ encoding->addChar(c, copyString(buf));
+ }
+ } else if ((encFormat & 0x7f) == 1) {
+ nRanges = *topPtr++;
+ nCodes = 1;
+ for (i = 0; i < nRanges; ++i) {
+ c = *topPtr++;
+ nLeft = *topPtr++;
+ for (j = 0; j <= nLeft && nCodes < nGlyphs; ++j) {
+ getString(glyphNames[nCodes], stringIdxPtr, stringStartPtr,
+ stringOffSize, buf);
+ encoding->addChar(c, copyString(buf));
+ ++nCodes;
+ ++c;
+ }
+ }
+ }
+ if (encFormat & 0x80) {
+ nSups = *topPtr++;
+ for (i = 0; i < nSups; ++i) {
+ c = *topPtr++;
+ sid = getWord(topPtr, 2);
+ topPtr += 2;
+ getString(sid, stringIdxPtr, stringStartPtr,
+ stringOffSize, buf);
+ encoding->addChar(c, copyString(buf));
+ }
+ }
+ }
+
+ if (charset > 2)
+ gfree(glyphNames);
+}
+
+Type1CFontFile::~Type1CFontFile() {
+ if (name)
+ gfree(name);
+ if (encoding && freeEnc)
+ delete encoding;
+}
+
+FontEncoding *Type1CFontFile::getEncoding(GBool taken) {
+ if (taken)
+ freeEnc = gFalse;
+ return encoding;
+}
+
+static Guint getWord(Guchar *ptr, int size) {
+ Guint x;
+ int i;
+
+ x = 0;
+ for (i = 0; i < size; ++i)
+ x = (x << 8) + *ptr++;
+ return x;
+}
+
+static double getNum(Guchar **ptr, GBool *fp) {
+ static char nybChars[16] = "0123456789.ee -";
+ int b0, b, nyb0, nyb1;
+ double x;
+ char buf[65];
+ int i;
+
+ x = 0;
+ *fp = gFalse;
+ b0 = (*ptr)[0];
+ if (b0 < 28) {
+ x = 0;
+ } else if (b0 == 28) {
+ x = ((*ptr)[1] << 8) + (*ptr)[2];
+ *ptr += 3;
+ } else if (b0 == 29) {
+ x = ((*ptr)[1] << 24) + ((*ptr)[2] << 16) + ((*ptr)[3] << 8) + (*ptr)[4];
+ *ptr += 5;
+ } else if (b0 == 30) {
+ *ptr += 1;
+ i = 0;
+ do {
+ b = *(*ptr)++;
+ nyb0 = b >> 4;
+ nyb1 = b & 0x0f;
+ if (nyb0 == 0xf)
+ break;
+ buf[i++] = nybChars[nyb0];
+ if (i == 64)
+ break;
+ if (nyb0 == 0xc)
+ buf[i++] = '-';
+ if (i == 64)
+ break;
+ if (nyb1 == 0xf)
+ break;
+ buf[i++] = nybChars[nyb1];
+ if (i == 64)
+ break;
+ if (nyb1 == 0xc)
+ buf[i++] = '-';
+ } while (i < 64);
+ buf[i] = '\0';
+ x = atof(buf);
+ *fp = gTrue;
+ } else if (b0 == 31) {
+ x = 0;
+ } else if (b0 < 247) {
+ x = b0 - 139;
+ *ptr += 1;
+ } else if (b0 < 251) {
+ x = ((b0 - 247) << 8) + (*ptr)[1] + 108;
+ *ptr += 2;
+ } else {
+ x = -((b0 - 251) << 8) - (*ptr)[1] - 108;
+ *ptr += 2;
+ }
+ return x;
+}
+
+static char *getString(int sid, Guchar *stringIdxPtr,
+ Guchar *stringStartPtr, int stringOffSize,
+ char *buf) {
+ Guchar *idxPtr0, *idxPtr1;
+ int len;
+
+ if (sid < 391) {
+ strcpy(buf, type1CStdStrings[sid]);
+ } else {
+ sid -= 391;
+ idxPtr0 = stringStartPtr + getWord(stringIdxPtr + sid * stringOffSize,
+ stringOffSize);
+ idxPtr1 = stringStartPtr + getWord(stringIdxPtr + (sid+1) * stringOffSize,
+ stringOffSize);
+ if ((len = idxPtr1 - idxPtr0) > 255)
+ len = 255;
+ strncpy(buf, (char *)idxPtr0, len);
+ buf[len] = '\0';
+ }
+ return buf;
+}
+
+//------------------------------------------------------------------------
+// Type1CFontConverter
+//------------------------------------------------------------------------
+
+Type1CFontConverter::Type1CFontConverter(char *fileA, int lenA, FILE *outA) {
+ file = fileA;
+ len = lenA;
+ out = outA;
+ r1 = 55665;
+ line = 0;
+}
+
+Type1CFontConverter::~Type1CFontConverter() {
+}
+
+void Type1CFontConverter::convert() {
+ char *fontName;
+ struct {
+ int version;
+ int notice;
+ int copyright;
+ int fullName;
+ int familyName;
+ int weight;
+ int isFixedPitch;
+ double italicAngle;
+ double underlinePosition;
+ double underlineThickness;
+ int paintType;
+ int charstringType; //~ ???
+ double fontMatrix[6];
+ int uniqueID;
+ double fontBBox[4];
+ double strokeWidth; //~ ???
+ int charset;
+ int encoding;
+ int charStrings;
+ int privateSize;
+ int privateOffset;
+ } dict;
+ char buf[256], eBuf[256];
+ Guchar *topPtr, *idxStartPtr, *idxPtr0, *idxPtr1;
+ Guchar *stringIdxPtr, *stringStartPtr;
+ int topOffSize, idxOffSize, stringOffSize;
+ int nFonts, nStrings, nGlyphs;
+ int nCodes, nRanges, nLeft, nSups;
+ Gushort *glyphNames;
+ int charsetFormat, encFormat;
+ int subrsOffset, nSubrs;
+ int nCharStrings;
+ int c, sid;
+ double x;
+ GBool isFP;
+ int key;
+ int i, j, n;
+
+ // read header
+ topPtr = (Guchar *)file + (file[2] & 0xff);
+ topOffSize = file[3] & 0xff;
+
+ // read name (first font only)
+ nFonts = getWord(topPtr, 2);
+ idxOffSize = topPtr[2];
+ topPtr += 3;
+ idxStartPtr = topPtr + (nFonts + 1) * idxOffSize - 1;
+ idxPtr0 = idxStartPtr + getWord(topPtr, idxOffSize);
+ idxPtr1 = idxStartPtr + getWord(topPtr + idxOffSize, idxOffSize);
+ if ((n = idxPtr1 - idxPtr0) > 255)
+ n = 255;
+ strncpy(buf, (char *)idxPtr0, n);
+ buf[n] = '\0';
+ fontName = copyString(buf);
+ topPtr = idxStartPtr + getWord(topPtr + nFonts * idxOffSize, idxOffSize);
+
+ // read top dict (first font only)
+ nFonts = getWord(topPtr, 2);
+ idxOffSize = topPtr[2];
+ topPtr += 3;
+ idxStartPtr = topPtr + (nFonts + 1) * idxOffSize - 1;
+ idxPtr0 = idxStartPtr + getWord(topPtr, idxOffSize);
+ idxPtr1 = idxStartPtr + getWord(topPtr + idxOffSize, idxOffSize);
+ dict.version = 0;
+ dict.notice = 0;
+ dict.copyright = 0;
+ dict.fullName = 0;
+ dict.familyName = 0;
+ dict.weight = 0;
+ dict.isFixedPitch = 0;
+ dict.italicAngle = 0;
+ dict.underlinePosition = -100;
+ dict.underlineThickness = 50;
+ dict.paintType = 0;
+ dict.charstringType = 2;
+ dict.fontMatrix[0] = 0.001;
+ dict.fontMatrix[1] = 0;
+ dict.fontMatrix[2] = 0;
+ dict.fontMatrix[3] = 0.001;
+ dict.fontMatrix[4] = 0;
+ dict.fontMatrix[5] = 0;
+ dict.uniqueID = 0;
+ dict.fontBBox[0] = 0;
+ dict.fontBBox[1] = 0;
+ dict.fontBBox[2] = 0;
+ dict.fontBBox[3] = 0;
+ dict.strokeWidth = 0;
+ dict.charset = 0;
+ dict.encoding = 0;
+ dict.charStrings = 0;
+ dict.privateSize = 0;
+ dict.privateOffset = 0;
+ i = 0;
+ while (idxPtr0 < idxPtr1) {
+ if (*idxPtr0 <= 27 || *idxPtr0 == 31) {
+ key = *idxPtr0++;
+ if (key == 0x0c)
+ key = (key << 8) | *idxPtr0++;
+ switch (key) {
+ case 0x0000: dict.version = (int)op[0]; break;
+ case 0x0001: dict.notice = (int)op[0]; break;
+ case 0x0c00: dict.copyright = (int)op[0]; break;
+ case 0x0002: dict.fullName = (int)op[0]; break;
+ case 0x0003: dict.familyName = (int)op[0]; break;
+ case 0x0004: dict.weight = (int)op[0]; break;
+ case 0x0c01: dict.isFixedPitch = (int)op[0]; break;
+ case 0x0c02: dict.italicAngle = op[0]; break;
+ case 0x0c03: dict.underlinePosition = op[0]; break;
+ case 0x0c04: dict.underlineThickness = op[0]; break;
+ case 0x0c05: dict.paintType = (int)op[0]; break;
+ case 0x0c06: dict.charstringType = (int)op[0]; break;
+ case 0x0c07: dict.fontMatrix[0] = op[0];
+ dict.fontMatrix[1] = op[1];
+ dict.fontMatrix[2] = op[2];
+ dict.fontMatrix[3] = op[3];
+ dict.fontMatrix[4] = op[4];
+ dict.fontMatrix[5] = op[5]; break;
+ case 0x000d: dict.uniqueID = (int)op[0]; break;
+ case 0x0005: dict.fontBBox[0] = op[0];
+ dict.fontBBox[1] = op[1];
+ dict.fontBBox[2] = op[2];
+ dict.fontBBox[3] = op[3]; break;
+ case 0x0c08: dict.strokeWidth = op[0]; break;
+ case 0x000f: dict.charset = (int)op[0]; break;
+ case 0x0010: dict.encoding = (int)op[0]; break;
+ case 0x0011: dict.charStrings = (int)op[0]; break;
+ case 0x0012: dict.privateSize = (int)op[0];
+ dict.privateOffset = (int)op[1]; break;
+ }
+ i = 0;
+ } else {
+ x = getNum(&idxPtr0, &isFP);
+ if (i < 48) {
+ op[i] = x;
+ fp[i++] = isFP;
+ }
+ }
+ }
+ topPtr = idxStartPtr + getWord(topPtr + nFonts * idxOffSize, idxOffSize);
+
+ // read string index
+ nStrings = getWord(topPtr, 2);
+ stringOffSize = topPtr[2];
+ topPtr += 3;
+ stringIdxPtr = topPtr;
+ stringStartPtr = topPtr + (nStrings + 1) * stringOffSize - 1;
+ topPtr = stringStartPtr + getWord(topPtr + nStrings * stringOffSize,
+ stringOffSize);
+
+#if 1 //~
+ // get global subrs
+ int nGSubrs;
+ int gSubrOffSize;
+
+ nGSubrs = getWord(topPtr, 2);
+ gSubrOffSize = topPtr[2];
+ topPtr += 3;
+#endif
+
+ // write header and font dictionary, up to encoding
+ fprintf(out, "%%!FontType1-1.0: %s", fontName);
+ if (dict.version != 0) {
+ fprintf(out, "%s",
+ getString(dict.version, stringIdxPtr, stringStartPtr,
+ stringOffSize, buf));
+ }
+ fprintf(out, "\n");
+ fprintf(out, "11 dict begin\n");
+ fprintf(out, "/FontInfo 10 dict dup begin\n");
+ if (dict.version != 0) {
+ fprintf(out, "/version (%s) readonly def\n",
+ getString(dict.version, stringIdxPtr, stringStartPtr,
+ stringOffSize, buf));
+ }
+ if (dict.notice != 0) {
+ fprintf(out, "/Notice (%s) readonly def\n",
+ getString(dict.notice, stringIdxPtr, stringStartPtr,
+ stringOffSize, buf));
+ }
+ if (dict.copyright != 0) {
+ fprintf(out, "/Copyright (%s) readonly def\n",
+ getString(dict.copyright, stringIdxPtr, stringStartPtr,
+ stringOffSize, buf));
+ }
+ if (dict.fullName != 0) {
+ fprintf(out, "/FullName (%s) readonly def\n",
+ getString(dict.fullName, stringIdxPtr, stringStartPtr,
+ stringOffSize, buf));
+ }
+ if (dict.familyName != 0) {
+ fprintf(out, "/FamilyName (%s) readonly def\n",
+ getString(dict.familyName, stringIdxPtr, stringStartPtr,
+ stringOffSize, buf));
+ }
+ if (dict.weight != 0) {
+ fprintf(out, "/Weight (%s) readonly def\n",
+ getString(dict.weight, stringIdxPtr, stringStartPtr,
+ stringOffSize, buf));
+ }
+ fprintf(out, "/isFixedPitch %s def\n", dict.isFixedPitch ? "true" : "false");
+ fprintf(out, "/ItalicAngle %g def\n", dict.italicAngle);
+ fprintf(out, "/UnderlinePosition %g def\n", dict.underlinePosition);
+ fprintf(out, "/UnderlineThickness %g def\n", dict.underlineThickness);
+ fprintf(out, "end readonly def\n");
+ fprintf(out, "/FontName /%s def\n", fontName);
+ fprintf(out, "/PaintType %d def\n", dict.paintType);
+ fprintf(out, "/FontType 1 def\n");
+ fprintf(out, "/FontMatrix [%g %g %g %g %g %g] readonly def\n",
+ dict.fontMatrix[0], dict.fontMatrix[1], dict.fontMatrix[2],
+ dict.fontMatrix[3], dict.fontMatrix[4], dict.fontMatrix[5]);
+ fprintf(out, "/FontBBox [%g %g %g %g] readonly def\n",
+ dict.fontBBox[0], dict.fontBBox[1],
+ dict.fontBBox[2], dict.fontBBox[3]);
+ if (dict.uniqueID != 0) {
+ fprintf(out, "/UniqueID %d def\n", dict.uniqueID);
+ }
+
+ // get number of glyphs from charstrings index
+ topPtr = (Guchar *)file + dict.charStrings;
+ nGlyphs = getWord(topPtr, 2);
+
+ // read charset
+ if (dict.charset == 0) {
+ glyphNames = type1CISOAdobeCharset;
+ } else if (dict.charset == 1) {
+ glyphNames = type1CExpertCharset;
+ } else if (dict.charset == 2) {
+ glyphNames = type1CExpertSubsetCharset;
+ } else {
+ glyphNames = (Gushort *)gmalloc(nGlyphs * sizeof(Gushort));
+ glyphNames[0] = 0;
+ topPtr = (Guchar *)file + dict.charset;
+ charsetFormat = *topPtr++;
+ if (charsetFormat == 0) {
+ for (i = 1; i < nGlyphs; ++i) {
+ glyphNames[i] = getWord(topPtr, 2);
+ topPtr += 2;
+ }
+ } else if (charsetFormat == 1) {
+ i = 1;
+ while (i < nGlyphs) {
+ c = getWord(topPtr, 2);
+ topPtr += 2;
+ nLeft = *topPtr++;
+ for (j = 0; j <= nLeft; ++j)
+ glyphNames[i++] = c++;
+ }
+ } else if (charsetFormat == 2) {
+ i = 1;
+ while (i < nGlyphs) {
+ c = getWord(topPtr, 2);
+ topPtr += 2;
+ nLeft = getWord(topPtr, 2);
+ topPtr += 2;
+ for (j = 0; j <= nLeft; ++j)
+ glyphNames[i++] = c++;
+ }
+ }
+ }
+
+ // read encoding (glyph -> code mapping), write Type 1 encoding
+ fprintf(out, "/Encoding ");
+ if (dict.encoding == 0) {
+ fprintf(out, "StandardEncoding def\n");
+ } else {
+ fprintf(out, "256 array\n");
+ fprintf(out, "0 1 255 {1 index exch /.notdef put} for\n");
+ if (dict.encoding == 1) {
+ for (i = 0; i < 256; ++i) {
+ if (type1ExpertEncodingNames[i])
+ fprintf(out, "dup %d /%s put\n", i, type1ExpertEncodingNames[i]);
+ }
+ } else {
+ topPtr = (Guchar *)file + dict.encoding;
+ encFormat = *topPtr++;
+ if ((encFormat & 0x7f) == 0) {
+ nCodes = 1 + *topPtr++;
+ if (nCodes > nGlyphs) {
+ nCodes = nGlyphs;
+ }
+ for (i = 1; i < nCodes; ++i) {
+ c = *topPtr++;
+ fprintf(out, "dup %d /%s put\n", c,
+ getString(glyphNames[i], stringIdxPtr, stringStartPtr,
+ stringOffSize, buf));
+ }
+ } else if ((encFormat & 0x7f) == 1) {
+ nRanges = *topPtr++;
+ nCodes = 1;
+ for (i = 0; i < nRanges; ++i) {
+ c = *topPtr++;
+ nLeft = *topPtr++;
+ for (j = 0; j <= nLeft && nCodes < nGlyphs; ++j) {
+ fprintf(out, "dup %d /%s put\n", c,
+ getString(glyphNames[nCodes], stringIdxPtr, stringStartPtr,
+ stringOffSize, buf));
+ ++nCodes;
+ ++c;
+ }
+ }
+ }
+ if (encFormat & 0x80) {
+ nSups = *topPtr++;
+ for (i = 0; i < nSups; ++i) {
+ c = *topPtr++;
+ sid = getWord(topPtr, 2);
+ topPtr += 2;
+ fprintf(out, "dup %d /%s put\n", c,
+ getString(sid, stringIdxPtr, stringStartPtr,
+ stringOffSize, buf));
+ }
+ }
+ }
+ fprintf(out, "readonly def\n");
+ }
+ fprintf(out, "currentdict end\n");
+ fprintf(out, "currentfile eexec\n");
+
+ // get private dictionary
+ eexecWrite("\x83\xca\x73\xd5");
+ eexecWrite("dup /Private 32 dict dup begin\n");
+ eexecWrite("/RD {string currentfile exch readstring pop} executeonly def\n");
+ eexecWrite("/ND {noaccess def} executeonly def\n");
+ eexecWrite("/NP {noaccess put} executeonly def\n");
+ eexecWrite("/MinFeature {16 16} ND\n");
+ eexecWrite("/password 5839 def\n");
+ subrsOffset = 0;
+ defaultWidthX = 0;
+ nominalWidthX = 0;
+ topPtr = (Guchar *)file + dict.privateOffset;
+ idxPtr0 = topPtr;
+ idxPtr1 = idxPtr0 + dict.privateSize;
+ i = 0;
+ while (idxPtr0 < idxPtr1) {
+ if (*idxPtr0 <= 27 || *idxPtr0 == 31) {
+ key = *idxPtr0++;
+ if (key == 0x0c)
+ key = (key << 8) | *idxPtr0++;
+ switch (key) {
+ case 0x0006:
+ getDeltaInt(eBuf, "BlueValues", op, i);
+ eexecWrite(eBuf);
+ break;
+ case 0x0007:
+ getDeltaInt(eBuf, "OtherBlues", op, i);
+ eexecWrite(eBuf);
+ break;
+ case 0x0008:
+ getDeltaInt(eBuf, "FamilyBlues", op, i);
+ eexecWrite(eBuf);
+ break;
+ case 0x0009:
+ getDeltaInt(eBuf, "FamilyOtherBlues", op, i);
+ eexecWrite(eBuf);
+ break;
+ case 0x0c09:
+ sprintf(eBuf, "/BlueScale %g def\n", op[0]);
+ eexecWrite(eBuf);
+ break;
+ case 0x0c0a:
+ sprintf(eBuf, "/BlueShift %d def\n", (int)op[0]);
+ eexecWrite(eBuf);
+ break;
+ case 0x0c0b:
+ sprintf(eBuf, "/BlueFuzz %d def\n", (int)op[0]);
+ eexecWrite(eBuf);
+ break;
+ case 0x000a:
+ sprintf(eBuf, "/StdHW [%g] def\n", op[0]);
+ eexecWrite(eBuf);
+ break;
+ case 0x000b:
+ sprintf(eBuf, "/StdVW [%g] def\n", op[0]);
+ eexecWrite(eBuf);
+ break;
+ case 0x0c0c:
+ getDeltaReal(eBuf, "StemSnapH", op, i);
+ eexecWrite(eBuf);
+ break;
+ case 0x0c0d:
+ getDeltaReal(eBuf, "StemSnapV", op, i);
+ eexecWrite(eBuf);
+ break;
+ case 0x0c0e:
+ sprintf(eBuf, "/ForceBold %s def\n", op[0] ? "true" : "false");
+ eexecWrite(eBuf);
+ break;
+ case 0x0c0f:
+ sprintf(eBuf, "/ForceBoldThreshold %g def\n", op[0]);
+ eexecWrite(eBuf);
+ break;
+ case 0x0c11:
+ sprintf(eBuf, "/LanguageGroup %d def\n", (int)op[0]);
+ eexecWrite(eBuf);
+ break;
+ case 0x0c12:
+ sprintf(eBuf, "/ExpansionFactor %g def\n", op[0]);
+ eexecWrite(eBuf);
+ break;
+ case 0x0c13:
+ error(-1, "Got Type 1C InitialRandomSeed");
+ break;
+ case 0x0013:
+ subrsOffset = (int)op[0];
+ break;
+ case 0x0014:
+ defaultWidthX = op[0];
+ defaultWidthXFP = fp[0];
+ break;
+ case 0x0015:
+ nominalWidthX = op[0];
+ nominalWidthXFP = fp[0];
+ break;
+ default:
+ error(-1, "Unknown Type 1C private dict entry %04x", key);
+ break;
+ }
+ i = 0;
+ } else {
+ x = getNum(&idxPtr0, &isFP);
+ if (i < 48) {
+ op[i] = x;
+ fp[i++] = isFP;
+ }
+ }
+ }
+
+ // get subrs
+ if (subrsOffset != 0) {
+ topPtr += subrsOffset;
+ nSubrs = getWord(topPtr, 2);
+ idxOffSize = topPtr[2];
+ topPtr += 3;
+ sprintf(eBuf, "/Subrs %d array\n", nSubrs);
+ eexecWrite(eBuf);
+ idxStartPtr = topPtr + (nSubrs + 1) * idxOffSize - 1;
+ idxPtr1 = idxStartPtr + getWord(topPtr, idxOffSize);
+ for (i = 0; i < nSubrs; ++i) {
+ idxPtr0 = idxPtr1;
+ idxPtr1 = idxStartPtr + getWord(topPtr + (i+1)*idxOffSize, idxOffSize);
+ n = idxPtr1 - idxPtr0;
+#if 1 //~
+ error(-1, "Unimplemented Type 2 subrs");
+#else
+ sprintf(eBuf, "dup %d %d RD ", i, n);
+ eexecWrite(eBuf);
+ cvtGlyph(idxPtr0, n);
+ eexecWrite(" NP\n");
+#endif
+ }
+ eexecWrite("ND\n");
+ }
+
+ // get CharStrings
+ topPtr = (Guchar *)file + dict.charStrings;
+ nCharStrings = getWord(topPtr, 2);
+ idxOffSize = topPtr[2];
+ topPtr += 3;
+ sprintf(eBuf, "2 index /CharStrings %d dict dup begin\n", nCharStrings);
+ eexecWrite(eBuf);
+ idxStartPtr = topPtr + (nCharStrings + 1) * idxOffSize - 1;
+ idxPtr1 = idxStartPtr + getWord(topPtr, idxOffSize);
+ for (i = 0; i < nCharStrings; ++i) {
+ idxPtr0 = idxPtr1;
+ idxPtr1 = idxStartPtr + getWord(topPtr + (i+1)*idxOffSize, idxOffSize);
+ n = idxPtr1 - idxPtr0;
+ cvtGlyph(getString(glyphNames[i], stringIdxPtr, stringStartPtr,
+ stringOffSize, buf),
+ idxPtr0, n);
+ }
+ eexecWrite("end\n");
+ eexecWrite("end\n");
+ eexecWrite("readonly put\n");
+ eexecWrite("noaccess put\n");
+ eexecWrite("dup /FontName get exch definefont pop\n");
+ eexecWrite("mark currentfile closefile\n");
+
+ // trailer
+ if (line > 0)
+ fputc('\n', out);
+ for (i = 0; i < 8; ++i) {
+ fprintf(out, "0000000000000000000000000000000000000000000000000000000000000000\n");
+ }
+ fprintf(out, "cleartomark\n");
+
+ // clean up
+ if (dict.charset > 2)
+ gfree(glyphNames);
+ gfree(fontName);
+}
+
+void Type1CFontConverter::eexecWrite(char *s) {
+ Guchar *p;
+ Guchar x;
+
+ for (p = (Guchar *)s; *p; ++p) {
+ x = *p ^ (r1 >> 8);
+ r1 = (x + r1) * 52845 + 22719;
+ fputc(hexChars[x >> 4], out);
+ fputc(hexChars[x & 0x0f], out);
+ line += 2;
+ if (line == 64) {
+ fputc('\n', out);
+ line = 0;
+ }
+ }
+}
+
+void Type1CFontConverter::cvtGlyph(char *name, Guchar *s, int n) {
+ int nHints;
+ int x;
+ GBool first = gTrue;
+ char eBuf[256];
+ double d, dx, dy;
+ GBool dFP;
+ int i, k;
+
+ charBuf = new GString();
+ charBuf->append((char)73);
+ charBuf->append((char)58);
+ charBuf->append((char)147);
+ charBuf->append((char)134);
+
+ i = 0;
+ nOps = 0;
+ nHints = 0;
+ while (i < n) {
+ if (s[i] == 12) {
+ switch (s[i+1]) {
+ case 0: // dotsection (should be Type 1 only?)
+ //~ ignored
+ break;
+ case 34: // hflex
+ if (nOps != 7) {
+ error(-1, "Wrong number of args (%d) to Type 2 hflex", nOps);
+ }
+ eexecDumpNum(op[0], fp[0]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(op[1], fp[1]);
+ eexecDumpNum(op[2], fp[2]);
+ eexecDumpNum(op[3], fp[3]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpOp1(8);
+ eexecDumpNum(op[4], fp[4]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(op[5], fp[5]);
+ eexecDumpNum(-op[2], fp[2]);
+ eexecDumpNum(op[6], fp[6]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpOp1(8);
+ break;
+ case 35: // flex
+ if (nOps != 13) {
+ error(-1, "Wrong number of args (%d) to Type 2 flex", nOps);
+ }
+ eexecDumpNum(op[0], fp[0]);
+ eexecDumpNum(op[1], fp[1]);
+ eexecDumpNum(op[2], fp[2]);
+ eexecDumpNum(op[3], fp[3]);
+ eexecDumpNum(op[4], fp[4]);
+ eexecDumpNum(op[5], fp[5]);
+ eexecDumpOp1(8);
+ eexecDumpNum(op[6], fp[6]);
+ eexecDumpNum(op[7], fp[7]);
+ eexecDumpNum(op[8], fp[8]);
+ eexecDumpNum(op[9], fp[9]);
+ eexecDumpNum(op[10], fp[10]);
+ eexecDumpNum(op[11], fp[11]);
+ eexecDumpOp1(8);
+ break;
+ case 36: // hflex1
+ if (nOps != 9) {
+ error(-1, "Wrong number of args (%d) to Type 2 hflex1", nOps);
+ }
+ eexecDumpNum(op[0], fp[0]);
+ eexecDumpNum(op[1], fp[1]);
+ eexecDumpNum(op[2], fp[2]);
+ eexecDumpNum(op[3], fp[3]);
+ eexecDumpNum(op[4], fp[4]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpOp1(8);
+ eexecDumpNum(op[5], fp[5]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(op[6], fp[6]);
+ eexecDumpNum(op[7], fp[7]);
+ eexecDumpNum(op[8], fp[8]);
+ eexecDumpNum(-(op[1] + op[3] + op[7]), fp[1] | fp[3] | fp[7]);
+ eexecDumpOp1(8);
+ break;
+ case 37: // flex1
+ if (nOps != 11) {
+ error(-1, "Wrong number of args (%d) to Type 2 flex1", nOps);
+ }
+ eexecDumpNum(op[0], fp[0]);
+ eexecDumpNum(op[1], fp[1]);
+ eexecDumpNum(op[2], fp[2]);
+ eexecDumpNum(op[3], fp[3]);
+ eexecDumpNum(op[4], fp[4]);
+ eexecDumpNum(op[5], fp[5]);
+ eexecDumpOp1(8);
+ eexecDumpNum(op[6], fp[6]);
+ eexecDumpNum(op[7], fp[7]);
+ eexecDumpNum(op[8], fp[8]);
+ eexecDumpNum(op[9], fp[9]);
+ dx = op[0] + op[2] + op[4] + op[6] + op[8];
+ dy = op[1] + op[3] + op[5] + op[7] + op[9];
+ if (fabs(dx) > fabs(dy)) {
+ eexecDumpNum(op[10], fp[10]);
+ eexecDumpNum(-dy, fp[1] | fp[3] | fp[5] | fp[7] | fp[9]);
+ } else {
+ eexecDumpNum(-dx, fp[0] | fp[2] | fp[4] | fp[6] | fp[8]);
+ eexecDumpNum(op[10], fp[10]);
+ }
+ eexecDumpOp1(8);
+ break;
+ case 3: // and
+ case 4: // or
+ case 5: // not
+ case 8: // store
+ case 9: // abs
+ case 10: // add
+ case 11: // sub
+ case 12: // div
+ case 13: // load
+ case 14: // neg
+ case 15: // eq
+ case 18: // drop
+ case 20: // put
+ case 21: // get
+ case 22: // ifelse
+ case 23: // random
+ case 24: // mul
+ case 26: // sqrt
+ case 27: // dup
+ case 28: // exch
+ case 29: // index
+ case 30: // roll
+ error(-1, "Unimplemented Type 2 charstring op: 12.%d", s[i+1]);
+ break;
+ default:
+ error(-1, "Illegal Type 2 charstring op: 12.%d", s[i+1]);
+ break;
+ }
+ i += 2;
+ nOps = 0;
+ } else if (s[i] == 19) { // hintmask
+ //~ ignored
+ if (first) {
+ cvtGlyphWidth(nOps == 1);
+ first = gFalse;
+ }
+ if (nOps > 0) {
+ if (nOps & 1) {
+ error(-1, "Wrong number of args (%d) to Type 2 hintmask/vstemhm",
+ nOps);
+ }
+ nHints += nOps / 2;
+ }
+ i += 1 + ((nHints + 7) >> 3);
+ nOps = 0;
+ } else if (s[i] == 20) { // cntrmask
+ //~ ignored
+ if (first) {
+ cvtGlyphWidth(nOps == 1);
+ first = gFalse;
+ }
+ if (nOps > 0) {
+ if (nOps & 1) {
+ error(-1, "Wrong number of args (%d) to Type 2 cntrmask/vstemhm",
+ nOps);
+ }
+ nHints += nOps / 2;
+ }
+ i += 1 + ((nHints + 7) >> 3);
+ nOps = 0;
+ } else if (s[i] == 28) {
+ x = (s[i+1] << 8) + s[i+2];
+ if (x & 0x8000)
+ x |= -1 << 15;
+ if (nOps < 48) {
+ fp[nOps] = gFalse;
+ op[nOps++] = x;
+ }
+ i += 3;
+ } else if (s[i] <= 31) {
+ switch (s[i]) {
+ case 4: // vmoveto
+ if (first) {
+ cvtGlyphWidth(nOps == 2);
+ first = gFalse;
+ }
+ if (nOps != 1)
+ error(-1, "Wrong number of args (%d) to Type 2 vmoveto", nOps);
+ eexecDumpNum(op[0], fp[0]);
+ eexecDumpOp1(4);
+ break;
+ case 5: // rlineto
+ if (nOps < 2 || nOps % 2 != 0)
+ error(-1, "Wrong number of args (%d) to Type 2 rlineto", nOps);
+ for (k = 0; k < nOps; k += 2) {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpOp1(5);
+ }
+ break;
+ case 6: // hlineto
+ if (nOps < 1)
+ error(-1, "Wrong number of args (%d) to Type 2 hlineto", nOps);
+ for (k = 0; k < nOps; ++k) {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpOp1((k & 1) ? 7 : 6);
+ }
+ break;
+ case 7: // vlineto
+ if (nOps < 1)
+ error(-1, "Wrong number of args (%d) to Type 2 vlineto", nOps);
+ for (k = 0; k < nOps; ++k) {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpOp1((k & 1) ? 6 : 7);
+ }
+ break;
+ case 8: // rrcurveto
+ if (nOps < 6 || nOps % 6 != 0)
+ error(-1, "Wrong number of args (%d) to Type 2 rrcurveto", nOps);
+ for (k = 0; k < nOps; k += 6) {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ eexecDumpNum(op[k+4], fp[k+4]);
+ eexecDumpNum(op[k+5], fp[k+5]);
+ eexecDumpOp1(8);
+ }
+ break;
+ case 14: // endchar / seac
+ if (first) {
+ cvtGlyphWidth(nOps == 1 || nOps == 5);
+ first = gFalse;
+ }
+ if (nOps == 4) {
+ eexecDumpNum(0, 0);
+ eexecDumpNum(op[0], fp[0]);
+ eexecDumpNum(op[1], fp[1]);
+ eexecDumpNum(op[2], fp[2]);
+ eexecDumpNum(op[3], fp[3]);
+ eexecDumpOp2(6);
+ } else if (nOps == 0) {
+ eexecDumpOp1(14);
+ } else {
+ error(-1, "Wrong number of args (%d) to Type 2 endchar", nOps);
+ }
+ break;
+ case 21: // rmoveto
+ if (first) {
+ cvtGlyphWidth(nOps == 3);
+ first = gFalse;
+ }
+ if (nOps != 2)
+ error(-1, "Wrong number of args (%d) to Type 2 rmoveto", nOps);
+ eexecDumpNum(op[0], fp[0]);
+ eexecDumpNum(op[1], fp[1]);
+ eexecDumpOp1(21);
+ break;
+ case 22: // hmoveto
+ if (first) {
+ cvtGlyphWidth(nOps == 2);
+ first = gFalse;
+ }
+ if (nOps != 1)
+ error(-1, "Wrong number of args (%d) to Type 2 hmoveto", nOps);
+ eexecDumpNum(op[0], fp[0]);
+ eexecDumpOp1(22);
+ break;
+ case 24: // rcurveline
+ if (nOps < 8 || (nOps - 2) % 6 != 0)
+ error(-1, "Wrong number of args (%d) to Type 2 rcurveline", nOps);
+ for (k = 0; k < nOps - 2; k += 6) {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ eexecDumpNum(op[k+4], fp[k+4]);
+ eexecDumpNum(op[k+5], fp[k+5]);
+ eexecDumpOp1(8);
+ }
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k]);
+ eexecDumpOp1(5);
+ break;
+ case 25: // rlinecurve
+ if (nOps < 8 || (nOps - 6) % 2 != 0)
+ error(-1, "Wrong number of args (%d) to Type 2 rlinecurve", nOps);
+ for (k = 0; k < nOps - 6; k += 2) {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k]);
+ eexecDumpOp1(5);
+ }
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ eexecDumpNum(op[k+4], fp[k+4]);
+ eexecDumpNum(op[k+5], fp[k+5]);
+ eexecDumpOp1(8);
+ break;
+ case 26: // vvcurveto
+ if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0))
+ error(-1, "Wrong number of args (%d) to Type 2 vvcurveto", nOps);
+ if (nOps % 2 == 1) {
+ eexecDumpNum(op[0], fp[0]);
+ eexecDumpNum(op[1], fp[1]);
+ eexecDumpNum(op[2], fp[2]);
+ eexecDumpNum(op[3], fp[3]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(op[4], fp[4]);
+ eexecDumpOp1(8);
+ k = 5;
+ } else {
+ k = 0;
+ }
+ for (; k < nOps; k += 4) {
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ eexecDumpOp1(8);
+ }
+ break;
+ case 27: // hhcurveto
+ if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0))
+ error(-1, "Wrong number of args (%d) to Type 2 hhcurveto", nOps);
+ if (nOps % 2 == 1) {
+ eexecDumpNum(op[1], fp[1]);
+ eexecDumpNum(op[0], fp[0]);
+ eexecDumpNum(op[2], fp[2]);
+ eexecDumpNum(op[3], fp[3]);
+ eexecDumpNum(op[4], fp[4]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpOp1(8);
+ k = 5;
+ } else {
+ k = 0;
+ }
+ for (; k < nOps; k += 4) {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpOp1(8);
+ }
+ break;
+ case 30: // vhcurveto
+ if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0))
+ error(-1, "Wrong number of args (%d) to Type 2 vhcurveto", nOps);
+ for (k = 0; k < nOps && k != nOps-5; k += 4) {
+ if (k % 8 == 0) {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ eexecDumpOp1(30);
+ } else {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ eexecDumpOp1(31);
+ }
+ }
+ if (k == nOps-5) {
+ if (k % 8 == 0) {
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ eexecDumpNum(op[k+4], fp[k+4]);
+ } else {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+4], fp[k+4]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ }
+ eexecDumpOp1(8);
+ }
+ break;
+ case 31: // hvcurveto
+ if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0))
+ error(-1, "Wrong number of args (%d) to Type 2 hvcurveto", nOps);
+ for (k = 0; k < nOps && k != nOps-5; k += 4) {
+ if (k % 8 == 0) {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ eexecDumpOp1(31);
+ } else {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ eexecDumpOp1(30);
+ }
+ }
+ if (k == nOps-5) {
+ if (k % 8 == 0) {
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+4], fp[k+4]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ } else {
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(op[k], fp[k]);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ eexecDumpNum(op[k+2], fp[k+2]);
+ eexecDumpNum(op[k+3], fp[k+3]);
+ eexecDumpNum(op[k+4], fp[k+4]);
+ }
+ eexecDumpOp1(8);
+ }
+ break;
+ case 1: // hstem
+ if (first) {
+ cvtGlyphWidth(nOps & 1);
+ first = gFalse;
+ }
+ if (nOps & 1) {
+ error(-1, "Wrong number of args (%d) to Type 2 hstem", nOps);
+ }
+ d = 0;
+ dFP = gFalse;
+ for (k = 0; k < nOps; k += 2) {
+ if (op[k+1] < 0) {
+ d += op[k] + op[k+1];
+ dFP |= fp[k] | fp[k+1];
+ eexecDumpNum(d, dFP);
+ eexecDumpNum(-op[k+1], fp[k+1]);
+ } else {
+ d += op[k];
+ dFP |= fp[k];
+ eexecDumpNum(d, dFP);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ d += op[k+1];
+ dFP |= fp[k+1];
+ }
+ eexecDumpOp1(1);
+ }
+ nHints += nOps / 2;
+ break;
+ case 3: // vstem
+ if (first) {
+ cvtGlyphWidth(nOps & 1);
+ first = gFalse;
+ }
+ if (nOps & 1) {
+ error(-1, "Wrong number of args (%d) to Type 2 vstem", nOps);
+ }
+ d = 0;
+ dFP = gFalse;
+ for (k = 0; k < nOps; k += 2) {
+ if (op[k+1] < 0) {
+ d += op[k] + op[k+1];
+ dFP |= fp[k] | fp[k+1];
+ eexecDumpNum(d, dFP);
+ eexecDumpNum(-op[k+1], fp[k+1]);
+ } else {
+ d += op[k];
+ dFP |= fp[k];
+ eexecDumpNum(d, dFP);
+ eexecDumpNum(op[k+1], fp[k+1]);
+ d += op[k+1];
+ dFP |= fp[k+1];
+ }
+ eexecDumpOp1(3);
+ }
+ nHints += nOps / 2;
+ break;
+ case 18: // hstemhm
+ //~ ignored
+ if (first) {
+ cvtGlyphWidth(nOps & 1);
+ first = gFalse;
+ }
+ if (nOps & 1) {
+ error(-1, "Wrong number of args (%d) to Type 2 hstemhm", nOps);
+ }
+ nHints += nOps / 2;
+ break;
+ case 23: // vstemhm
+ //~ ignored
+ if (first) {
+ cvtGlyphWidth(nOps & 1);
+ first = gFalse;
+ }
+ if (nOps & 1) {
+ error(-1, "Wrong number of args (%d) to Type 2 vstemhm", nOps);
+ }
+ nHints += nOps / 2;
+ break;
+ case 10: // callsubr
+ case 11: // return
+ case 16: // blend
+ case 29: // callgsubr
+ error(-1, "Unimplemented Type 2 charstring op: %d", s[i]);
+ break;
+ default:
+ error(-1, "Illegal Type 2 charstring op: %d", s[i]);
+ break;
+ }
+ ++i;
+ nOps = 0;
+ } else if (s[i] <= 246) {
+ if (nOps < 48) {
+ fp[nOps] = gFalse;
+ op[nOps++] = (int)s[i] - 139;
+ }
+ ++i;
+ } else if (s[i] <= 250) {
+ if (nOps < 48) {
+ fp[nOps] = gFalse;
+ op[nOps++] = (((int)s[i] - 247) << 8) + (int)s[i+1] + 108;
+ }
+ i += 2;
+ } else if (s[i] <= 254) {
+ if (nOps < 48) {
+ fp[nOps] = gFalse;
+ op[nOps++] = -(((int)s[i] - 251) << 8) - (int)s[i+1] - 108;
+ }
+ i += 2;
+ } else {
+ x = (s[i+1] << 24) | (s[i+2] << 16) | (s[i+3] << 8) | s[i+4];
+ if (x & 0x80000000)
+ x |= -1 << 31;
+ if (nOps < 48) {
+ fp[nOps] = gTrue;
+ op[nOps++] = (double)x / 65536.0;
+ }
+ i += 5;
+ }
+ }
+
+ sprintf(eBuf, "/%s %d RD ", name, charBuf->getLength());
+ eexecWrite(eBuf);
+ eexecWriteCharstring((Guchar *)charBuf->getCString(), charBuf->getLength());
+ eexecWrite(" ND\n");
+ delete charBuf;
+}
+
+void Type1CFontConverter::cvtGlyphWidth(GBool useOp) {
+ double w;
+ GBool wFP;
+ int i;
+
+ if (useOp) {
+ w = nominalWidthX + op[0];
+ wFP = nominalWidthXFP | fp[0];
+ for (i = 1; i < nOps; ++i) {
+ op[i-1] = op[i];
+ fp[i-1] = fp[i];
+ }
+ --nOps;
+ } else {
+ w = defaultWidthX;
+ wFP = defaultWidthXFP;
+ }
+ eexecDumpNum(0, gFalse);
+ eexecDumpNum(w, wFP);
+ eexecDumpOp1(13);
+}
+
+void Type1CFontConverter::eexecDumpNum(double x, GBool fpA) {
+ Guchar buf[12];
+ int y, n;
+
+ n = 0;
+ if (fpA) {
+ if (x >= -32768 && x < 32768) {
+ y = (int)(x * 256.0);
+ buf[0] = 255;
+ buf[1] = (Guchar)(y >> 24);
+ buf[2] = (Guchar)(y >> 16);
+ buf[3] = (Guchar)(y >> 8);
+ buf[4] = (Guchar)y;
+ buf[5] = 255;
+ buf[6] = 0;
+ buf[7] = 0;
+ buf[8] = 1;
+ buf[9] = 0;
+ buf[10] = 12;
+ buf[11] = 12;
+ n = 12;
+ } else {
+ error(-1, "Type 2 fixed point constant out of range");
+ }
+ } else {
+ y = (int)x;
+ if (y >= -107 && y <= 107) {
+ buf[0] = (Guchar)(y + 139);
+ n = 1;
+ } else if (y > 107 && y <= 1131) {
+ y -= 108;
+ buf[0] = (Guchar)((y >> 8) + 247);
+ buf[1] = (Guchar)(y & 0xff);
+ n = 2;
+ } else if (y < -107 && y >= -1131) {
+ y = -y - 108;
+ buf[0] = (Guchar)((y >> 8) + 251);
+ buf[1] = (Guchar)(y & 0xff);
+ n = 2;
+ } else {
+ buf[0] = 255;
+ buf[1] = (Guchar)(y >> 24);
+ buf[2] = (Guchar)(y >> 16);
+ buf[3] = (Guchar)(y >> 8);
+ buf[4] = (Guchar)y;
+ n = 5;
+ }
+ }
+ charBuf->append((char *)buf, n);
+}
+
+void Type1CFontConverter::eexecDumpOp1(int opA) {
+ charBuf->append((char)opA);
+}
+
+void Type1CFontConverter::eexecDumpOp2(int opA) {
+ charBuf->append((char)12);
+ charBuf->append((char)opA);
+}
+
+void Type1CFontConverter::eexecWriteCharstring(Guchar *s, int n) {
+ Gushort r2;
+ Guchar x;
+ int i;
+
+ r2 = 4330;
+
+ for (i = 0; i < n; ++i) {
+ // charstring encryption
+ x = s[i];
+ x ^= (r2 >> 8);
+ r2 = (x + r2) * 52845 + 22719;
+
+ // eexec encryption
+ x ^= (r1 >> 8);
+ r1 = (x + r1) * 52845 + 22719;
+ fputc(hexChars[x >> 4], out);
+ fputc(hexChars[x & 0x0f], out);
+ line += 2;
+ if (line == 64) {
+ fputc('\n', out);
+ line = 0;
+ }
+ }
+}
+
+void Type1CFontConverter::getDeltaInt(char *buf, char *name, double *opA,
+ int n) {
+ int x, i;
+
+ sprintf(buf, "/%s [", name);
+ buf += strlen(buf);
+ x = 0;
+ for (i = 0; i < n; ++i) {
+ x += (int)opA[i];
+ sprintf(buf, "%s%d", i > 0 ? " " : "", x);
+ buf += strlen(buf);
+ }
+ sprintf(buf, "] def\n");
+}
+
+void Type1CFontConverter::getDeltaReal(char *buf, char *name, double *opA,
+ int n) {
+ double x;
+ int i;
+
+ sprintf(buf, "/%s [", name);
+ buf += strlen(buf);
+ x = 0;
+ for (i = 0; i < n; ++i) {
+ x += opA[i];
+ sprintf(buf, "%s%g", i > 0 ? " " : "", x);
+ buf += strlen(buf);
+ }
+ sprintf(buf, "] def\n");
+}
+
+//------------------------------------------------------------------------
+// TrueTypeFontFile
+//------------------------------------------------------------------------
+
+//
+// Terminology
+// -----------
+//
+// character code = number used as an element of a text string
+//
+// character name = glyph name = name for a particular glyph within a
+// font
+//
+// glyph index = position (within some internal table in the font)
+// where the instructions to draw a particular glyph are
+// stored
+//
+// Type 1 fonts
+// ------------
+//
+// Type 1 fonts contain:
+//
+// Encoding: array of glyph names, maps char codes to glyph names
+//
+// Encoding[charCode] = charName
+//
+// CharStrings: dictionary of instructions, keyed by character names,
+// maps character name to glyph data
+//
+// CharStrings[charName] = glyphData
+//
+// TrueType fonts
+// --------------
+//
+// TrueType fonts contain:
+//
+// 'cmap' table: mapping from character code to glyph index; there may
+// be multiple cmaps in a TrueType font
+//
+// cmap[charCode] = glyphIdx
+//
+// 'post' table: mapping from glyph index to glyph name
+//
+// post[glyphIdx] = glyphName
+//
+// Type 42 fonts
+// -------------
+//
+// Type 42 fonts contain:
+//
+// Encoding: array of glyph names, maps char codes to glyph names
+//
+// Encoding[charCode] = charName
+//
+// CharStrings: dictionary of glyph indexes, keyed by character names,
+// maps character name to glyph index
+//
+// CharStrings[charName] = glyphIdx
+//
+
+struct TTFontTableHdr {
+ char tag[4];
+ Guint checksum;
+ Guint offset;
+ Guint length;
+};
+
+// TrueType tables required by the Type 42 spec.
+static char *t42ReqTables[9] = {
+ "head",
+ "hhea",
+ "loca",
+ "maxp",
+ "cvt ",
+ "prep",
+ "glyf",
+ "hmtx",
+ "fpgm"
+};
+
+// Glyph names in some arbitrary standard that Apple uses for their
+// TrueType fonts.
+static char *macGlyphNames[258] = {
+ ".notdef",
+ "null",
+ "CR",
+ "space",
+ "exclam",
+ "quotedbl",
+ "numbersign",
+ "dollar",
+ "percent",
+ "ampersand",
+ "quotesingle",
+ "parenleft",
+ "parenright",
+ "asterisk",
+ "plus",
+ "comma",
+ "hyphen",
+ "period",
+ "slash",
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less",
+ "equal",
+ "greater",
+ "question",
+ "at",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "bracketleft",
+ "backslash",
+ "bracketright",
+ "asciicircum",
+ "underscore",
+ "grave",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "braceleft",
+ "bar",
+ "braceright",
+ "asciitilde",
+ "Adieresis",
+ "Aring",
+ "Ccedilla",
+ "Eacute",
+ "Ntilde",
+ "Odieresis",
+ "Udieresis",
+ "aacute",
+ "agrave",
+ "acircumflex",
+ "adieresis",
+ "atilde",
+ "aring",
+ "ccedilla",
+ "eacute",
+ "egrave",
+ "ecircumflex",
+ "edieresis",
+ "iacute",
+ "igrave",
+ "icircumflex",
+ "idieresis",
+ "ntilde",
+ "oacute",
+ "ograve",
+ "ocircumflex",
+ "odieresis",
+ "otilde",
+ "uacute",
+ "ugrave",
+ "ucircumflex",
+ "udieresis",
+ "dagger",
+ "degree",
+ "cent",
+ "sterling",
+ "section",
+ "bullet",
+ "paragraph",
+ "germandbls",
+ "registered",
+ "copyright",
+ "trademark",
+ "acute",
+ "dieresis",
+ "notequal",
+ "AE",
+ "Oslash",
+ "infinity",
+ "plusminus",
+ "lessequal",
+ "greaterequal",
+ "yen",
+ "mu1",
+ "partialdiff",
+ "summation",
+ "product",
+ "pi",
+ "integral",
+ "ordfeminine",
+ "ordmasculine",
+ "Ohm",
+ "ae",
+ "oslash",
+ "questiondown",
+ "exclamdown",
+ "logicalnot",
+ "radical",
+ "florin",
+ "approxequal",
+ "increment",
+ "guillemotleft",
+ "guillemotright",
+ "ellipsis",
+ "nbspace",
+ "Agrave",
+ "Atilde",
+ "Otilde",
+ "OE",
+ "oe",
+ "endash",
+ "emdash",
+ "quotedblleft",
+ "quotedblright",
+ "quoteleft",
+ "quoteright",
+ "divide",
+ "lozenge",
+ "ydieresis",
+ "Ydieresis",
+ "fraction",
+ "currency",
+ "guilsinglleft",
+ "guilsinglright",
+ "fi",
+ "fl",
+ "daggerdbl",
+ "periodcentered",
+ "quotesinglbase",
+ "quotedblbase",
+ "perthousand",
+ "Acircumflex",
+ "Ecircumflex",
+ "Aacute",
+ "Edieresis",
+ "Egrave",
+ "Iacute",
+ "Icircumflex",
+ "Idieresis",
+ "Igrave",
+ "Oacute",
+ "Ocircumflex",
+ "applelogo",
+ "Ograve",
+ "Uacute",
+ "Ucircumflex",
+ "Ugrave",
+ "dotlessi",
+ "circumflex",
+ "tilde",
+ "overscore",
+ "breve",
+ "dotaccent",
+ "ring",
+ "cedilla",
+ "hungarumlaut",
+ "ogonek",
+ "caron",
+ "Lslash",
+ "lslash",
+ "Scaron",
+ "scaron",
+ "Zcaron",
+ "zcaron",
+ "brokenbar",
+ "Eth",
+ "eth",
+ "Yacute",
+ "yacute",
+ "Thorn",
+ "thorn",
+ "minus",
+ "multiply",
+ "onesuperior",
+ "twosuperior",
+ "threesuperior",
+ "onehalf",
+ "onequarter",
+ "threequarters",
+ "franc",
+ "Gbreve",
+ "gbreve",
+ "Idot",
+ "Scedilla",
+ "scedilla",
+ "Cacute",
+ "cacute",
+ "Ccaron",
+ "ccaron",
+ "dmacron"
+};
+
+TrueTypeFontFile::TrueTypeFontFile(char *fileA, int lenA) {
+ int pos, i;
+
+ file = fileA;
+ len = lenA;
+
+ encoding = NULL;
+ freeEnc = gTrue;
+
+ // read table directory
+ nTables = getUShort(4);
+ tableHdrs = (TTFontTableHdr *)gmalloc(nTables * sizeof(TTFontTableHdr));
+ pos = 12;
+ for (i = 0; i < nTables; ++i) {
+ tableHdrs[i].tag[0] = getByte(pos+0);
+ tableHdrs[i].tag[1] = getByte(pos+1);
+ tableHdrs[i].tag[2] = getByte(pos+2);
+ tableHdrs[i].tag[3] = getByte(pos+3);
+ tableHdrs[i].checksum = getULong(pos+4);
+ tableHdrs[i].offset = getULong(pos+8);
+ tableHdrs[i].length = getULong(pos+12);
+ pos += 16;
+ }
+
+ // check for tables that are required by both the TrueType spec
+ // and the Type 42 spec
+ if (seekTable("head") < 0 ||
+ seekTable("hhea") < 0 ||
+ seekTable("loca") < 0 ||
+ seekTable("maxp") < 0 ||
+ seekTable("glyf") < 0 ||
+ seekTable("hmtx") < 0) {
+ error(-1, "TrueType font file is missing a required table");
+ return;
+ }
+
+ // read the 'head' table
+ pos = seekTable("head");
+ bbox[0] = getShort(pos + 36);
+ bbox[1] = getShort(pos + 38);
+ bbox[2] = getShort(pos + 40);
+ bbox[3] = getShort(pos + 42);
+ locaFmt = getShort(pos + 50);
+
+ // read the 'maxp' table
+ pos = seekTable("maxp");
+ nGlyphs = getUShort(pos + 4);
+}
+
+TrueTypeFontFile::~TrueTypeFontFile() {
+ if (encoding && freeEnc) {
+ delete encoding;
+ }
+ gfree(tableHdrs);
+}
+
+char *TrueTypeFontFile::getName() {
+ return NULL;
+}
+
+FontEncoding *TrueTypeFontFile::getEncoding(GBool taken) {
+ int cmap[256];
+ int nCmaps, cmapPlatform, cmapEncoding, cmapFmt, cmapLen, cmapOffset;
+ int segCnt, segStart, segEnd, segDelta, segOffset;
+ int pos, i, j, k;
+ Guint fmt;
+ GString *s;
+ int stringIdx, stringPos, n;
+
+ //----- construct the (char code) -> (glyph idx) mapping
+
+ // map everything to the missing glyph
+ for (i = 0; i < 256; ++i) {
+ cmap[i] = 0;
+ }
+
+ // look for the 'cmap' table
+ if ((pos = seekTable("cmap")) >= 0) {
+ nCmaps = getUShort(pos+2);
+
+ // if the font has a Windows-symbol cmap, use it;
+ // otherwise, use the first cmap in the table
+ for (i = 0; i < nCmaps; ++i) {
+ cmapPlatform = getUShort(pos + 4 + 8*i);
+ cmapEncoding = getUShort(pos + 4 + 8*i + 2);
+ if (cmapPlatform == 3 && cmapEncoding == 0) {
+ break;
+ }
+ }
+ if (i >= nCmaps) {
+ i = 0;
+ cmapPlatform = getUShort(pos + 4);
+ cmapEncoding = getUShort(pos + 4 + 2);
+ }
+ pos += getULong(pos + 4 + 8*i + 4);
+
+ // read the cmap
+ cmapFmt = getUShort(pos);
+ switch (cmapFmt) {
+ case 0: // byte encoding table (Apple standard)
+ cmapLen = getUShort(pos + 2);
+ for (i = 0; i < cmapLen && i < 256; ++i) {
+ cmap[i] = getByte(pos + 6 + i);
+ }
+ break;
+ case 4: // segment mapping to delta values (Microsoft standard)
+ if (cmapPlatform == 3 && cmapEncoding == 0) {
+ // Windows-symbol uses char codes 0xf000 - 0xf0ff
+ cmapOffset = 0xf000;
+ } else {
+ cmapOffset = 0;
+ }
+ segCnt = getUShort(pos + 6) / 2;
+ for (i = 0; i < segCnt; ++i) {
+ segEnd = getUShort(pos + 14 + 2*i);
+ segStart = getUShort(pos + 16 + 2*segCnt + 2*i);
+ segDelta = getUShort(pos + 16 + 4*segCnt + 2*i);
+ segOffset = getUShort(pos + 16 + 6*segCnt + 2*i);
+ if (segStart - cmapOffset <= 0xff &&
+ segEnd - cmapOffset >= 0) {
+ for (j = (segStart - cmapOffset >= 0) ? segStart : cmapOffset;
+ j <= segEnd && j - cmapOffset <= 0xff;
+ ++j) {
+ if (segOffset == 0) {
+ k = (j + segDelta) & 0xffff;
+ } else {
+ k = getUShort(pos + 16 + 6*segCnt + 2*i +
+ segOffset + 2 * (j - segStart));
+ if (k != 0) {
+ k = (k + segDelta) & 0xffff;
+ }
+ }
+ cmap[j - cmapOffset] = k;
+ }
+ }
+ }
+ break;
+ default:
+ error(-1, "Unimplemented cmap type (%d) in TrueType font file",
+ cmapFmt);
+ break;
+ }
+ }
+
+ //----- construct the (glyph idx) -> (glyph name) mapping
+ //----- and compute the (char code) -> (glyph name) mapping
+
+ encoding = new FontEncoding();
+
+ if ((pos = seekTable("post")) >= 0) {
+ fmt = getULong(pos);
+
+ // Apple font
+ if (fmt == 0x00010000) {
+ for (i = 0; i < 256; ++i) {
+ j = (cmap[i] < 258) ? cmap[i] : 0;
+ encoding->addChar(i, copyString(macGlyphNames[j]));
+ }
+
+ // Microsoft font
+ } else if (fmt == 0x00020000) {
+ stringIdx = 0;
+ stringPos = pos + 34 + 2*nGlyphs;
+ for (i = 0; i < 256; ++i) {
+ if (cmap[i] < nGlyphs) {
+ j = getUShort(pos + 34 + 2 * cmap[i]);
+ if (j < 258) {
+ encoding->addChar(i, copyString(macGlyphNames[j]));
+ } else {
+ j -= 258;
+ if (j != stringIdx) {
+ for (stringIdx = 0, stringPos = pos + 34 + 2*nGlyphs;
+ stringIdx < j;
+ ++stringIdx, stringPos += 1 + getByte(stringPos)) ;
+ }
+ n = getByte(stringPos);
+ s = new GString(file + stringPos + 1, n);
+ encoding->addChar(i, copyString(s->getCString()));
+ delete s;
+ ++stringIdx;
+ stringPos += 1 + n;
+ }
+ } else {
+ encoding->addChar(i, copyString(macGlyphNames[0]));
+ }
+ }
+
+ // Apple subset
+ } else if (fmt == 0x000280000) {
+ for (i = 0; i < 256; ++i) {
+ if (cmap[i] < nGlyphs) {
+ j = i + getChar(pos + 32 + cmap[i]);
+ } else {
+ j = 0;
+ }
+ encoding->addChar(i, copyString(macGlyphNames[j]));
+ }
+
+ // Ugh, just assume the Apple glyph set
+ } else {
+ for (i = 0; i < 256; ++i) {
+ j = (cmap[i] < 258) ? cmap[i] : 0;
+ encoding->addChar(i, copyString(macGlyphNames[j]));
+ }
+ }
+
+ // no "post" table: assume the Apple glyph set
+ } else {
+ for (i = 0; i < 256; ++i) {
+ j = (cmap[i] < 258) ? cmap[i] : 0;
+ encoding->addChar(i, copyString(macGlyphNames[j]));
+ }
+ }
+
+ if (taken) {
+ freeEnc = gFalse;
+ }
+ return encoding;
+}
+
+void TrueTypeFontFile::convertToType42(char *name, FontEncoding *encodingA,
+ FILE *out) {
+ // write the header
+ fprintf(out, "%%!PS-TrueTypeFont-%g\n", getFixed(0));
+
+ // begin the font dictionary
+ fprintf(out, "10 dict begin\n");
+ fprintf(out, "/FontName /%s def\n", name);
+ fprintf(out, "/FontType 42 def\n");
+ fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n");
+ fprintf(out, "/FontBBox [%d %d %d %d] def\n",
+ bbox[0], bbox[1], bbox[2], bbox[3]);
+ fprintf(out, "/PaintType 0 def\n");
+
+ // write the guts of the dictionary
+ cvtEncoding(encodingA, out);
+ cvtCharStrings(encodingA, out);
+ cvtSfnts(out);
+
+ // end the dictionary and define the font
+ fprintf(out, "FontName currentdict end definefont pop\n");
+}
+
+int TrueTypeFontFile::getByte(int pos) {
+ return file[pos] & 0xff;
+}
+
+int TrueTypeFontFile::getChar(int pos) {
+ int x;
+
+ x = file[pos] & 0xff;
+ if (x & 0x80)
+ x |= 0xffffff00;
+ return x;
+}
+
+int TrueTypeFontFile::getUShort(int pos) {
+ int x;
+
+ x = file[pos] & 0xff;
+ x = (x << 8) + (file[pos+1] & 0xff);
+ return x;
+}
+
+int TrueTypeFontFile::getShort(int pos) {
+ int x;
+
+ x = file[pos] & 0xff;
+ x = (x << 8) + (file[pos+1] & 0xff);
+ if (x & 0x8000)
+ x |= 0xffff0000;
+ return x;
+}
+
+Guint TrueTypeFontFile::getULong(int pos) {
+ int x;
+
+ x = file[pos] & 0xff;
+ x = (x << 8) + (file[pos+1] & 0xff);
+ x = (x << 8) + (file[pos+2] & 0xff);
+ x = (x << 8) + (file[pos+3] & 0xff);
+ return x;
+}
+
+double TrueTypeFontFile::getFixed(int pos) {
+ int x, y;
+
+ x = getShort(pos);
+ y = getUShort(pos+2);
+ return (double)x + (double)y / 65536;
+}
+
+int TrueTypeFontFile::seekTable(char *tag) {
+ int i;
+
+ for (i = 0; i < nTables; ++i) {
+ if (!strncmp(tableHdrs[i].tag, tag, 4))
+ return tableHdrs[i].offset;
+ }
+ return -1;
+}
+
+void TrueTypeFontFile::cvtEncoding(FontEncoding *encodingA, FILE *out) {
+ char *name;
+ int i;
+
+ fprintf(out, "/Encoding 256 array\n");
+ for (i = 0; i < 256; ++i) {
+ if (!(name = encodingA->getCharName(i))) {
+ name = ".notdef";
+ }
+ fprintf(out, "dup %d /%s put\n", i, name);
+ }
+ fprintf(out, "readonly def\n");
+}
+
+void TrueTypeFontFile::cvtCharStrings(FontEncoding *encodingA, FILE *out) {
+ int cmap[256];
+ int nCmaps, cmapPlatform, cmapEncoding, cmapFmt, cmapLen, cmapOffset;
+ int segCnt, segStart, segEnd, segDelta, segOffset;
+ char *name;
+ int pos, i, j, k;
+
+ //----- read the cmap: construct the (char code) -> (glyph idx) mapping
+
+ // map everything to the missing glyph
+ for (i = 0; i < 256; ++i) {
+ cmap[i] = 0;
+ }
+
+ // look for the 'cmap' table
+ if ((pos = seekTable("cmap")) >= 0) {
+ nCmaps = getUShort(pos+2);
+
+ // if the font has a Windows-symbol cmap, use it;
+ // otherwise, use the first cmap in the table
+ for (i = 0; i < nCmaps; ++i) {
+ cmapPlatform = getUShort(pos + 4 + 8*i);
+ cmapEncoding = getUShort(pos + 4 + 8*i + 2);
+ if (cmapPlatform == 3 && cmapEncoding == 0) {
+ break;
+ }
+ }
+ if (i >= nCmaps) {
+ i = 0;
+ cmapPlatform = getUShort(pos + 4);
+ cmapEncoding = getUShort(pos + 4 + 2);
+ }
+ pos += getULong(pos + 4 + 8*i + 4);
+
+ // read the cmap
+ cmapFmt = getUShort(pos);
+ switch (cmapFmt) {
+ case 0: // byte encoding table (Apple standard)
+ cmapLen = getUShort(pos + 2);
+ for (i = 0; i < cmapLen && i < 256; ++i) {
+ cmap[i] = getByte(pos + 6 + i);
+ }
+ break;
+ case 4: // segment mapping to delta values (Microsoft standard)
+ if (cmapPlatform == 3 && cmapEncoding == 0) {
+ // Windows-symbol uses char codes 0xf000 - 0xf0ff
+ cmapOffset = 0xf000;
+ } else {
+ cmapOffset = 0;
+ }
+ segCnt = getUShort(pos + 6) / 2;
+ for (i = 0; i < segCnt; ++i) {
+ segEnd = getUShort(pos + 14 + 2*i);
+ segStart = getUShort(pos + 16 + 2*segCnt + 2*i);
+ segDelta = getUShort(pos + 16 + 4*segCnt + 2*i);
+ segOffset = getUShort(pos + 16 + 6*segCnt + 2*i);
+ if (segStart - cmapOffset <= 0xff &&
+ segEnd - cmapOffset >= 0) {
+ for (j = (segStart - cmapOffset >= 0) ? segStart : cmapOffset;
+ j <= segEnd && j - cmapOffset <= 0xff;
+ ++j) {
+ if (segOffset == 0) {
+ k = (j + segDelta) & 0xffff;
+ } else {
+ k = getUShort(pos + 16 + 6*segCnt + 2*i +
+ segOffset + 2 * (j - segStart));
+ if (k != 0) {
+ k = (k + segDelta) & 0xffff;
+ }
+ }
+ cmap[j - cmapOffset] = k;
+ }
+ }
+ }
+ break;
+ default:
+ error(-1, "Unimplemented cmap type (%d) in TrueType font file",
+ cmapFmt);
+ break;
+ }
+ }
+
+ //----- map char code to glyph index
+
+ // 1. use encoding to map name to char code
+ // 2. use cmap to map char code to glyph index
+
+ fprintf(out, "/CharStrings 256 dict dup begin\n");
+ fprintf(out, "/.notdef 0 def\n");
+
+ // kludge: this loop goes backward because the WinAnsi and MacRoman
+ // encodings define certain chars multiple times (space, hyphen,
+ // etc.), and we want the lowest-numbered definition to "stick"
+ // (because the higher-numbered defn(s) may not have valid cmap
+ // entries)
+ i = encodingA->getSize();
+ if (i > 255) {
+ i = 255;
+ }
+ for (; i >= 0; --i) {
+ name = encodingA->getCharName(i);
+ if (name && strcmp(name, ".notdef")) {
+ fprintf(out, "/%s %d def\n", name, cmap[i]);
+ }
+ }
+
+ fprintf(out, "end readonly def\n");
+}
+
+void TrueTypeFontFile::cvtSfnts(FILE *out) {
+ char tableDir[12 + 9*16];
+ int *list;
+ int nTablesOut, pos, destPos, i, j, k1, k2;
+
+ fprintf(out, "/sfnts [\n");
+
+ // count tables
+ nTablesOut = 0;
+ for (i = 0; i < 9; ++i) {
+ for (j = 0; j < nTables; ++j) {
+ if (!strncmp(t42ReqTables[i], tableHdrs[j].tag, 4)) {
+ ++nTablesOut;
+ break;
+ }
+ }
+ }
+
+ // header
+ tableDir[0] = 0x00; // sfnt version
+ tableDir[1] = 0x01;
+ tableDir[2] = 0x00;
+ tableDir[3] = 0x00;
+ tableDir[4] = (nTablesOut >> 8) & 0xff; // numTables
+ tableDir[5] = nTablesOut & 0xff;
+ tableDir[6] = 0; // searchRange
+ tableDir[7] = (char)128;
+ tableDir[8] = 0; // entrySelector
+ tableDir[9] = 3;
+ tableDir[10] = 0; // rangeShift
+ tableDir[11] = 16;
+
+ // table directory
+ pos = 12;
+ destPos = 12 + 16 * nTablesOut;
+ for (i = 0; i < 9; ++i) {
+ for (j = 0; j < nTables; ++j) {
+ if (!strncmp(t42ReqTables[i], tableHdrs[j].tag, 4)) {
+ break;
+ }
+ }
+ if (j < nTables) {
+ memcpy(&tableDir[pos], t42ReqTables[i], 4);
+ tableDir[pos+4] = (tableHdrs[j].checksum >> 24) & 0xff;
+ tableDir[pos+5] = (tableHdrs[j].checksum >> 16) & 0xff;
+ tableDir[pos+6] = (tableHdrs[j].checksum >> 8) & 0xff;
+ tableDir[pos+7] = tableHdrs[j].checksum & 0xff;
+ tableDir[pos+8] = (destPos >> 24) & 0xff;
+ tableDir[pos+9] = (destPos >> 16) & 0xff;
+ tableDir[pos+10] = (destPos >> 8) & 0xff;
+ tableDir[pos+11] = destPos & 0xff;
+ tableDir[pos+12] = (tableHdrs[j].length >> 24) & 0xff;
+ tableDir[pos+13] = (tableHdrs[j].length >> 16) & 0xff;
+ tableDir[pos+14] = (tableHdrs[j].length >> 8) & 0xff;
+ tableDir[pos+15] = tableHdrs[j].length & 0xff;
+ pos += 16;
+ destPos += tableHdrs[j].length;
+ if (tableHdrs[j].length & 3) {
+ destPos += 4 - (tableHdrs[j].length & 3);
+ }
+ }
+ }
+
+ dumpString(tableDir, 12 + 16 * nTablesOut, out);
+
+ for (i = 0; i < 9; ++i) {
+ for (j = 0; j < nTables; ++j) {
+ if (!strncmp(t42ReqTables[i], tableHdrs[j].tag, 4)) {
+ break;
+ }
+ }
+ if (j < nTables) {
+ if (!strcmp(t42ReqTables[i], "glyf") && tableHdrs[j].length > 65532) {
+ // the 'glyf' table won't fit in a single string, and we're only
+ // allowed to break at glyph boundaries
+ list = (int *)gmalloc((nGlyphs + 1) * sizeof(int));
+ pos = seekTable("loca");
+ for (k1 = 0; k1 <= nGlyphs; ++k1) {
+ if (locaFmt) {
+ list[k1] = getULong(pos + 4*k1);
+ } else {
+ list[k1] = 2 * getUShort(pos + 2*k1);
+ }
+ }
+ k1 = 0;
+ while (k1 < nGlyphs) {
+ for (k2 = k1 + 1;
+ k2 < nGlyphs && list[k2+1] - list[k1] <= 65532;
+ ++k2) ;
+ // ghostscript is unhappy if we break at anything other
+ // than a multiple of four bytes
+ while (((list[k2] - list[k1]) & 3) && k2 > k1 + 1) {
+ --k2;
+ }
+ dumpString(file + tableHdrs[j].offset + list[k1],
+ list[k2] - list[k1], out);
+ k1 = k2;
+ }
+ gfree(list);
+ } else {
+ dumpString(file + tableHdrs[j].offset, tableHdrs[j].length, out);
+ }
+ }
+ }
+
+ fprintf(out, "] def\n");
+}
+
+void TrueTypeFontFile::dumpString(char *s, int n, FILE *out) {
+ int i, j;
+
+ fprintf(out, "<");
+ for (i = 0; i < n; i += 32) {
+ for (j = 0; j < 32 && i+j < n; ++j) {
+ fprintf(out, "%02X", s[i+j] & 0xff);
+ }
+ if (i+32 < n) {
+ fprintf(out, "\n");
+ }
+ }
+ if (n & 3) {
+ for (i = 0; i < 4 - (n & 3); ++i) {
+ fprintf(out, "00");
+ }
+ }
+ // append an extra mystery zero byte because the Type 42 spec says so
+ fprintf(out, "00>\n");
+}
diff --git a/pdftops/FontFile.h b/pdftops/FontFile.h
new file mode 100644
index 000000000..b64d827eb
--- /dev/null
+++ b/pdftops/FontFile.h
@@ -0,0 +1,170 @@
+//========================================================================
+//
+// FontFile.h
+//
+// Copyright 1999 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef FONTFILE_H
+#define FONTFILE_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <stdio.h>
+#include "gtypes.h"
+#include "GString.h"
+#include "FontEncoding.h"
+
+//------------------------------------------------------------------------
+// FontFile
+//------------------------------------------------------------------------
+
+class FontFile {
+public:
+
+ FontFile();
+ virtual ~FontFile();
+
+ // Returns the font name, as specified internally by the font file.
+ // Returns NULL if no name is available.
+ virtual char *getName() = 0;
+
+ // Returns the custom font encoding, or NULL if the encoding is
+ // not available. If <taken> is set, the caller of this function
+ // will be responsible for freeing the encoding object.
+ virtual FontEncoding *getEncoding(GBool taken) = 0;
+};
+
+//------------------------------------------------------------------------
+// Type1FontFile
+//------------------------------------------------------------------------
+
+class Type1FontFile: public FontFile {
+public:
+
+ Type1FontFile(char *file, int len);
+ virtual ~Type1FontFile();
+ virtual char *getName() { return name; }
+ virtual FontEncoding *getEncoding(GBool taken);
+
+private:
+
+ char *name;
+ FontEncoding *encoding;
+ GBool freeEnc;
+};
+
+//------------------------------------------------------------------------
+// Type1CFontFile
+//------------------------------------------------------------------------
+
+class Type1CFontFile: public FontFile {
+public:
+
+ Type1CFontFile(char *file, int len);
+ virtual ~Type1CFontFile();
+ virtual char *getName() { return name; }
+ virtual FontEncoding *getEncoding(GBool taken);
+
+private:
+
+ char *name;
+ FontEncoding *encoding;
+ GBool freeEnc;
+};
+
+//------------------------------------------------------------------------
+// Type1CFontConverter
+//------------------------------------------------------------------------
+
+class Type1CFontConverter {
+public:
+
+ Type1CFontConverter(char *fileA, int lenA, FILE *outA);
+ ~Type1CFontConverter();
+ void convert();
+
+private:
+
+ void eexecWrite(char *s);
+ void cvtGlyph(char *name, Guchar *s, int n);
+ void cvtGlyphWidth(GBool useOp);
+ void eexecDumpNum(double x, GBool fpA);
+ void eexecDumpOp1(int opA);
+ void eexecDumpOp2(int opA);
+ void eexecWriteCharstring(Guchar *s, int n);
+ void getDeltaInt(char *buf, char *name, double *opA, int n);
+ void getDeltaReal(char *buf, char *name, double *opA, int n);
+
+ char *file;
+ int len;
+ FILE *out;
+ double op[48]; // operands
+ GBool fp[48]; // true if operand is fixed point
+ int nOps; // number of operands
+ double defaultWidthX; // default glyph width
+ double nominalWidthX; // nominal glyph width
+ GBool defaultWidthXFP; // true if defaultWidthX is fixed point
+ GBool nominalWidthXFP; // true if nominalWidthX is fixed point
+ Gushort r1; // eexec encryption key
+ GString *charBuf; // charstring output buffer
+ int line; // number of eexec chars on current line
+};
+
+//------------------------------------------------------------------------
+// TrueTypeFontFile
+//------------------------------------------------------------------------
+
+struct TTFontTableHdr;
+
+class TrueTypeFontFile: public FontFile {
+public:
+
+ TrueTypeFontFile(char *fileA, int lenA);
+ ~TrueTypeFontFile();
+
+ // This always returns NULL, since it's probably better to trust the
+ // font name in the PDF file rather than the one in the TrueType
+ // font file.
+ virtual char *getName();
+
+ virtual FontEncoding *getEncoding(GBool taken);
+
+ // Convert to a Type 42 font, suitable for embedding in a PostScript
+ // file. The name will be used as the PostScript font name (so we
+ // don't need to depend on the 'name' table in the font). The
+ // encoding is needed because the PDF Font object can modify the
+ // encoding.
+ void convertToType42(char *name, FontEncoding *encodingA, FILE *out);
+
+private:
+
+ char *file;
+ int len;
+
+ FontEncoding *encoding;
+ GBool freeEnc;
+
+ TTFontTableHdr *tableHdrs;
+ int nTables;
+ int bbox[4];
+ int locaFmt;
+ int nGlyphs;
+
+ int getByte(int pos);
+ int getChar(int pos);
+ int getUShort(int pos);
+ int getShort(int pos);
+ Guint getULong(int pos);
+ double getFixed(int pos);
+ int seekTable(char *tag);
+ void cvtEncoding(FontEncoding *encodingA, FILE *out);
+ void cvtCharStrings(FontEncoding *encodingA, FILE *out);
+ void cvtSfnts(FILE *out);
+ void dumpString(char *s, int n, FILE *out);
+};
+
+#endif
diff --git a/pdftops/FontInfo.h b/pdftops/FontInfo.h
new file mode 100644
index 000000000..a5b4cced3
--- /dev/null
+++ b/pdftops/FontInfo.h
@@ -0,0 +1,2070 @@
+//========================================================================
+//
+// FontInfo.h
+//
+// This file was automatically generated by makeFontInfo.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef FONTINFO_H
+#define FONTINFO_H
+
+//------------------------------------------------------------------------
+// Character encodings.
+//------------------------------------------------------------------------
+
+#define standardEncodingSize 335
+static char *standardEncodingNames[standardEncodingSize] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "space",
+ "exclam",
+ "quotedbl",
+ "numbersign",
+ "dollar",
+ "percent",
+ "ampersand",
+ "quoteright",
+ "parenleft",
+ "parenright",
+ "asterisk",
+ "plus",
+ "comma",
+ "hyphen",
+ "period",
+ "slash",
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less",
+ "equal",
+ "greater",
+ "question",
+ "at",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "bracketleft",
+ "backslash",
+ "bracketright",
+ "asciicircum",
+ "underscore",
+ "quoteleft",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "braceleft",
+ "bar",
+ "braceright",
+ "asciitilde",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "exclamdown",
+ "cent",
+ "sterling",
+ "fraction",
+ "yen",
+ "florin",
+ "section",
+ "currency",
+ "quotesingle",
+ "quotedblleft",
+ "guillemotleft",
+ "guilsinglleft",
+ "guilsinglright",
+ "fi",
+ "fl",
+ NULL,
+ "endash",
+ "dagger",
+ "daggerdbl",
+ "periodcentered",
+ NULL,
+ "paragraph",
+ "bullet",
+ "quotesinglbase",
+ "quotedblbase",
+ "quotedblright",
+ "guillemotright",
+ "ellipsis",
+ "perthousand",
+ NULL,
+ "questiondown",
+ NULL,
+ "grave",
+ "acute",
+ "circumflex",
+ "tilde",
+ "macron",
+ "breve",
+ "dotaccent",
+ "dieresis",
+ NULL,
+ "ring",
+ "cedilla",
+ NULL,
+ "hungarumlaut",
+ "ogonek",
+ "caron",
+ "emdash",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "AE",
+ NULL,
+ "ordfeminine",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "Lslash",
+ "Oslash",
+ "OE",
+ "ordmasculine",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "ae",
+ NULL,
+ NULL,
+ NULL,
+ "dotlessi",
+ NULL,
+ NULL,
+ "lslash",
+ "oslash",
+ "oe",
+ "germandbls",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "Aacute",
+ "Acircumflex",
+ "Adieresis",
+ "Agrave",
+ "Aring",
+ "Atilde",
+ "Ccedilla",
+ "Eacute",
+ "Ecircumflex",
+ "Edieresis",
+ "Egrave",
+ "Eth",
+ "Iacute",
+ "Icircumflex",
+ "Idieresis",
+ "Igrave",
+ "Ntilde",
+ "Oacute",
+ "Ocircumflex",
+ "Odieresis",
+ "Ograve",
+ "Otilde",
+ "Scaron",
+ "Thorn",
+ "Uacute",
+ "Ucircumflex",
+ "Udieresis",
+ "Ugrave",
+ "Yacute",
+ "Ydieresis",
+ "Zcaron",
+ "aacute",
+ "acircumflex",
+ "adieresis",
+ "agrave",
+ "aring",
+ "atilde",
+ "brokenbar",
+ "ccedilla",
+ "copyright",
+ "degree",
+ "divide",
+ "eacute",
+ "ecircumflex",
+ "edieresis",
+ "egrave",
+ "eth",
+ "iacute",
+ "icircumflex",
+ "idieresis",
+ "igrave",
+ "logicalnot",
+ "minus",
+ "mu",
+ "multiply",
+ "ntilde",
+ "oacute",
+ "ocircumflex",
+ "odieresis",
+ "ograve",
+ "onehalf",
+ "onequarter",
+ "onesuperior",
+ "otilde",
+ "plusminus",
+ "registered",
+ "scaron",
+ "thorn",
+ "threequarters",
+ "threesuperior",
+ "trademark",
+ "twosuperior",
+ "uacute",
+ "ucircumflex",
+ "udieresis",
+ "ugrave",
+ "yacute",
+ "ydieresis",
+ "zcaron"
+};
+static FontEncoding standardEncoding(standardEncodingNames,
+ standardEncodingSize);
+
+#define symbolEncodingSize 257
+static char *symbolEncodingNames[symbolEncodingSize] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "space",
+ "exclam",
+ "universal",
+ "numbersign",
+ "existential",
+ "percent",
+ "ampersand",
+ "suchthat",
+ "parenleft",
+ "parenright",
+ "asteriskmath",
+ "plus",
+ "comma",
+ "minus",
+ "period",
+ "slash",
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less",
+ "equal",
+ "greater",
+ "question",
+ "congruent",
+ "Alpha",
+ "Beta",
+ "Chi",
+ "Delta",
+ "Epsilon",
+ "Phi",
+ "Gamma",
+ "Eta",
+ "Iota",
+ "theta1",
+ "Kappa",
+ "Lambda",
+ "Mu",
+ "Nu",
+ "Omicron",
+ "Pi",
+ "Theta",
+ "Rho",
+ "Sigma",
+ "Tau",
+ "Upsilon",
+ "sigma1",
+ "Omega",
+ "Xi",
+ "Psi",
+ "Zeta",
+ "bracketleft",
+ "therefore",
+ "bracketright",
+ "perpendicular",
+ "underscore",
+ "radicalex",
+ "alpha",
+ "beta",
+ "chi",
+ "delta",
+ "epsilon",
+ "phi",
+ "gamma",
+ "eta",
+ "iota",
+ "phi1",
+ "kappa",
+ "lambda",
+ "mu",
+ "nu",
+ "omicron",
+ "pi",
+ "theta",
+ "rho",
+ "sigma",
+ "tau",
+ "upsilon",
+ "omega1",
+ "omega",
+ "xi",
+ "psi",
+ "zeta",
+ "braceleft",
+ "bar",
+ "braceright",
+ "similar",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "Upsilon1",
+ "minute",
+ "lessequal",
+ "fraction",
+ "infinity",
+ "florin",
+ "club",
+ "diamond",
+ "heart",
+ "spade",
+ "arrowboth",
+ "arrowleft",
+ "arrowup",
+ "arrowright",
+ "arrowdown",
+ "degree",
+ "plusminus",
+ "second",
+ "greaterequal",
+ "multiply",
+ "proportional",
+ "partialdiff",
+ "bullet",
+ "divide",
+ "notequal",
+ "equivalence",
+ "approxequal",
+ "ellipsis",
+ "arrowvertex",
+ "arrowhorizex",
+ "carriagereturn",
+ "aleph",
+ "Ifraktur",
+ "Rfraktur",
+ "weierstrass",
+ "circlemultiply",
+ "circleplus",
+ "emptyset",
+ "intersection",
+ "union",
+ "propersuperset",
+ "reflexsuperset",
+ "notsubset",
+ "propersubset",
+ "reflexsubset",
+ "element",
+ "notelement",
+ "angle",
+ "gradient",
+ "registerserif",
+ "copyrightserif",
+ "trademarkserif",
+ "product",
+ "radical",
+ "dotmath",
+ "logicalnot",
+ "logicaland",
+ "logicalor",
+ "arrowdblboth",
+ "arrowdblleft",
+ "arrowdblup",
+ "arrowdblright",
+ "arrowdbldown",
+ "lozenge",
+ "angleleft",
+ "registersans",
+ "copyrightsans",
+ "trademarksans",
+ "summation",
+ "parenlefttp",
+ "parenleftex",
+ "parenleftbt",
+ "bracketlefttp",
+ "bracketleftex",
+ "bracketleftbt",
+ "bracelefttp",
+ "braceleftmid",
+ "braceleftbt",
+ "braceex",
+ NULL,
+ "angleright",
+ "integral",
+ "integraltp",
+ "integralex",
+ "integralbt",
+ "parenrighttp",
+ "parenrightex",
+ "parenrightbt",
+ "bracketrighttp",
+ "bracketrightex",
+ "bracketrightbt",
+ "bracerighttp",
+ "bracerightmid",
+ "bracerightbt",
+ NULL,
+ "apple"
+};
+static FontEncoding symbolEncoding(symbolEncodingNames,
+ symbolEncodingSize);
+
+#define zapfDingbatsEncodingSize 270
+static char *zapfDingbatsEncodingNames[zapfDingbatsEncodingSize] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "space",
+ "a1",
+ "a2",
+ "a202",
+ "a3",
+ "a4",
+ "a5",
+ "a119",
+ "a118",
+ "a117",
+ "a11",
+ "a12",
+ "a13",
+ "a14",
+ "a15",
+ "a16",
+ "a105",
+ "a17",
+ "a18",
+ "a19",
+ "a20",
+ "a21",
+ "a22",
+ "a23",
+ "a24",
+ "a25",
+ "a26",
+ "a27",
+ "a28",
+ "a6",
+ "a7",
+ "a8",
+ "a9",
+ "a10",
+ "a29",
+ "a30",
+ "a31",
+ "a32",
+ "a33",
+ "a34",
+ "a35",
+ "a36",
+ "a37",
+ "a38",
+ "a39",
+ "a40",
+ "a41",
+ "a42",
+ "a43",
+ "a44",
+ "a45",
+ "a46",
+ "a47",
+ "a48",
+ "a49",
+ "a50",
+ "a51",
+ "a52",
+ "a53",
+ "a54",
+ "a55",
+ "a56",
+ "a57",
+ "a58",
+ "a59",
+ "a60",
+ "a61",
+ "a62",
+ "a63",
+ "a64",
+ "a65",
+ "a66",
+ "a67",
+ "a68",
+ "a69",
+ "a70",
+ "a71",
+ "a72",
+ "a73",
+ "a74",
+ "a203",
+ "a75",
+ "a204",
+ "a76",
+ "a77",
+ "a78",
+ "a79",
+ "a81",
+ "a82",
+ "a83",
+ "a84",
+ "a97",
+ "a98",
+ "a99",
+ "a100",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "a101",
+ "a102",
+ "a103",
+ "a104",
+ "a106",
+ "a107",
+ "a108",
+ "a112",
+ "a111",
+ "a110",
+ "a109",
+ "a120",
+ "a121",
+ "a122",
+ "a123",
+ "a124",
+ "a125",
+ "a126",
+ "a127",
+ "a128",
+ "a129",
+ "a130",
+ "a131",
+ "a132",
+ "a133",
+ "a134",
+ "a135",
+ "a136",
+ "a137",
+ "a138",
+ "a139",
+ "a140",
+ "a141",
+ "a142",
+ "a143",
+ "a144",
+ "a145",
+ "a146",
+ "a147",
+ "a148",
+ "a149",
+ "a150",
+ "a151",
+ "a152",
+ "a153",
+ "a154",
+ "a155",
+ "a156",
+ "a157",
+ "a158",
+ "a159",
+ "a160",
+ "a161",
+ "a163",
+ "a164",
+ "a196",
+ "a165",
+ "a192",
+ "a166",
+ "a167",
+ "a168",
+ "a169",
+ "a170",
+ "a171",
+ "a172",
+ "a173",
+ "a162",
+ "a174",
+ "a175",
+ "a176",
+ "a177",
+ "a178",
+ "a179",
+ "a193",
+ "a180",
+ "a199",
+ "a181",
+ "a200",
+ "a182",
+ NULL,
+ "a201",
+ "a183",
+ "a184",
+ "a197",
+ "a185",
+ "a194",
+ "a198",
+ "a186",
+ "a195",
+ "a187",
+ "a188",
+ "a189",
+ "a190",
+ "a191",
+ NULL,
+ "a205",
+ "a206",
+ "a85",
+ "a86",
+ "a87",
+ "a88",
+ "a89",
+ "a90",
+ "a91",
+ "a92",
+ "a93",
+ "a94",
+ "a95",
+ "a96"
+};
+static FontEncoding zapfDingbatsEncoding(zapfDingbatsEncodingNames,
+ zapfDingbatsEncodingSize);
+
+#define macRomanEncodingSize 256
+static char *macRomanEncodingNames[macRomanEncodingSize] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "space",
+ "exclam",
+ "quotedbl",
+ "numbersign",
+ "dollar",
+ "percent",
+ "ampersand",
+ "quotesingle",
+ "parenleft",
+ "parenright",
+ "asterisk",
+ "plus",
+ "comma",
+ "hyphen",
+ "period",
+ "slash",
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less",
+ "equal",
+ "greater",
+ "question",
+ "at",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "bracketleft",
+ "backslash",
+ "bracketright",
+ "asciicircum",
+ "underscore",
+ "grave",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "braceleft",
+ "bar",
+ "braceright",
+ "asciitilde",
+ NULL,
+ "Adieresis",
+ "Aring",
+ "Ccedilla",
+ "Eacute",
+ "Ntilde",
+ "Odieresis",
+ "Udieresis",
+ "aacute",
+ "agrave",
+ "acircumflex",
+ "adieresis",
+ "atilde",
+ "aring",
+ "ccedilla",
+ "eacute",
+ "egrave",
+ "ecircumflex",
+ "edieresis",
+ "iacute",
+ "igrave",
+ "icircumflex",
+ "idieresis",
+ "ntilde",
+ "oacute",
+ "ograve",
+ "ocircumflex",
+ "odieresis",
+ "otilde",
+ "uacute",
+ "ugrave",
+ "ucircumflex",
+ "udieresis",
+ "dagger",
+ "degree",
+ "cent",
+ "sterling",
+ "section",
+ "bullet",
+ "paragraph",
+ "germandbls",
+ "registered",
+ "copyright",
+ "trademark",
+ "acute",
+ "dieresis",
+ NULL,
+ "AE",
+ "Oslash",
+ NULL,
+ "plusminus",
+ NULL,
+ NULL,
+ "yen",
+ "mu",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "ordfeminine",
+ "ordmasculine",
+ NULL,
+ "ae",
+ "oslash",
+ "questiondown",
+ "exclamdown",
+ "logicalnot",
+ NULL,
+ "florin",
+ NULL,
+ NULL,
+ "guillemotleft",
+ "guillemotright",
+ "ellipsis",
+ "space",
+ "Agrave",
+ "Atilde",
+ "Otilde",
+ "OE",
+ "oe",
+ "endash",
+ "emdash",
+ "quotedblleft",
+ "quotedblright",
+ "quoteleft",
+ "quoteright",
+ "divide",
+ NULL,
+ "ydieresis",
+ "Ydieresis",
+ "fraction",
+ "currency",
+ "guilsinglleft",
+ "guilsinglright",
+ "fi",
+ "fl",
+ "daggerdbl",
+ "periodcentered",
+ "quotesinglbase",
+ "quotedblbase",
+ "perthousand",
+ "Acircumflex",
+ "Ecircumflex",
+ "Aacute",
+ "Edieresis",
+ "Egrave",
+ "Iacute",
+ "Icircumflex",
+ "Idieresis",
+ "Igrave",
+ "Oacute",
+ "Ocircumflex",
+ NULL,
+ "Ograve",
+ "Uacute",
+ "Ucircumflex",
+ "Ugrave",
+ "dotlessi",
+ "circumflex",
+ "tilde",
+ "macron",
+ "breve",
+ "dotaccent",
+ "ring",
+ "cedilla",
+ "hungarumlaut",
+ "ogonek",
+ "caron"
+};
+static FontEncoding macRomanEncoding(macRomanEncodingNames,
+ macRomanEncodingSize);
+
+#define winAnsiEncodingSize 256
+static char *winAnsiEncodingNames[winAnsiEncodingSize] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "space",
+ "exclam",
+ "quotedbl",
+ "numbersign",
+ "dollar",
+ "percent",
+ "ampersand",
+ "quotesingle",
+ "parenleft",
+ "parenright",
+ "asterisk",
+ "plus",
+ "comma",
+ "hyphen",
+ "period",
+ "slash",
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less",
+ "equal",
+ "greater",
+ "question",
+ "at",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "bracketleft",
+ "backslash",
+ "bracketright",
+ "asciicircum",
+ "underscore",
+ "grave",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "braceleft",
+ "bar",
+ "braceright",
+ "asciitilde",
+ "bullet",
+ "Euro",
+ "bullet",
+ "quotesinglbase",
+ "florin",
+ "quotedblbase",
+ "ellipsis",
+ "dagger",
+ "daggerdbl",
+ "circumflex",
+ "perthousand",
+ "Scaron",
+ "guilsinglleft",
+ "OE",
+ "bullet",
+ "bullet",
+ "bullet",
+ "bullet",
+ "quoteleft",
+ "quoteright",
+ "quotedblleft",
+ "quotedblright",
+ "bullet",
+ "endash",
+ "emdash",
+ "tilde",
+ "trademark",
+ "scaron",
+ "guilsinglright",
+ "oe",
+ "bullet",
+ "bullet",
+ "Ydieresis",
+ "space",
+ "exclamdown",
+ "cent",
+ "sterling",
+ "currency",
+ "yen",
+ "brokenbar",
+ "section",
+ "dieresis",
+ "copyright",
+ "ordfeminine",
+ "guillemotleft",
+ "logicalnot",
+ "hyphen",
+ "registered",
+ "macron",
+ "degree",
+ "plusminus",
+ "twosuperior",
+ "threesuperior",
+ "acute",
+ "mu",
+ "paragraph",
+ "periodcentered",
+ "cedilla",
+ "onesuperior",
+ "ordmasculine",
+ "guillemotright",
+ "onequarter",
+ "onehalf",
+ "threequarters",
+ "questiondown",
+ "Agrave",
+ "Aacute",
+ "Acircumflex",
+ "Atilde",
+ "Adieresis",
+ "Aring",
+ "AE",
+ "Ccedilla",
+ "Egrave",
+ "Eacute",
+ "Ecircumflex",
+ "Edieresis",
+ "Igrave",
+ "Iacute",
+ "Icircumflex",
+ "Idieresis",
+ "Eth",
+ "Ntilde",
+ "Ograve",
+ "Oacute",
+ "Ocircumflex",
+ "Otilde",
+ "Odieresis",
+ "multiply",
+ "Oslash",
+ "Ugrave",
+ "Uacute",
+ "Ucircumflex",
+ "Udieresis",
+ "Yacute",
+ "Thorn",
+ "germandbls",
+ "agrave",
+ "aacute",
+ "acircumflex",
+ "atilde",
+ "adieresis",
+ "aring",
+ "ae",
+ "ccedilla",
+ "egrave",
+ "eacute",
+ "ecircumflex",
+ "edieresis",
+ "igrave",
+ "iacute",
+ "icircumflex",
+ "idieresis",
+ "eth",
+ "ntilde",
+ "ograve",
+ "oacute",
+ "ocircumflex",
+ "otilde",
+ "odieresis",
+ "divide",
+ "oslash",
+ "ugrave",
+ "uacute",
+ "ucircumflex",
+ "udieresis",
+ "yacute",
+ "thorn",
+ "ydieresis"
+};
+static FontEncoding winAnsiEncoding(winAnsiEncodingNames,
+ winAnsiEncodingSize);
+
+//------------------------------------------------------------------------
+// Character widths for built-in fonts.
+//------------------------------------------------------------------------
+
+static Gushort courierWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 0, 600, 600, 600, 600, 0, 600, 600,
+ 600, 600, 600, 600, 600, 600, 0, 600,
+ 0, 600, 600, 600, 600, 600, 600, 600,
+ 600, 0, 600, 600, 0, 600, 600, 600,
+ 600, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 600, 0, 600, 0, 0, 0, 0,
+ 600, 600, 600, 600, 0, 0, 0, 0,
+ 0, 600, 0, 0, 0, 600, 0, 0,
+ 600, 600, 600, 600, 0, 0, 0, 0,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600
+};
+
+static Gushort courierBoldWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 0, 600, 600, 600, 600, 0, 600, 600,
+ 600, 600, 600, 600, 600, 600, 0, 600,
+ 0, 600, 600, 600, 600, 600, 600, 600,
+ 600, 0, 600, 600, 0, 600, 600, 600,
+ 600, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 600, 0, 600, 0, 0, 0, 0,
+ 600, 600, 600, 600, 0, 0, 0, 0,
+ 0, 600, 0, 0, 0, 600, 0, 0,
+ 600, 600, 600, 600, 0, 0, 0, 0,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600
+};
+
+static Gushort courierBoldObliqueWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 0, 600, 600, 600, 600, 0, 600, 600,
+ 600, 600, 600, 600, 600, 600, 0, 600,
+ 0, 600, 600, 600, 600, 600, 600, 600,
+ 600, 0, 600, 600, 0, 600, 600, 600,
+ 600, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 600, 0, 600, 0, 0, 0, 0,
+ 600, 600, 600, 600, 0, 0, 0, 0,
+ 0, 600, 0, 0, 0, 600, 0, 0,
+ 600, 600, 600, 600, 0, 0, 0, 0,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600
+};
+
+static Gushort courierObliqueWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 0, 600, 600, 600, 600, 0, 600, 600,
+ 600, 600, 600, 600, 600, 600, 0, 600,
+ 0, 600, 600, 600, 600, 600, 600, 600,
+ 600, 0, 600, 600, 0, 600, 600, 600,
+ 600, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 600, 0, 600, 0, 0, 0, 0,
+ 600, 600, 600, 600, 0, 0, 0, 0,
+ 0, 600, 0, 0, 0, 600, 0, 0,
+ 600, 600, 600, 600, 0, 0, 0, 0,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600, 600,
+ 600, 600, 600, 600, 600, 600, 600
+};
+
+static Gushort helveticaWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 278, 278, 355, 556, 556, 889, 667, 222,
+ 333, 333, 389, 584, 278, 333, 278, 278,
+ 556, 556, 556, 556, 556, 556, 556, 556,
+ 556, 556, 278, 278, 584, 584, 584, 556,
+ 1015, 667, 667, 722, 722, 667, 611, 778,
+ 722, 278, 500, 667, 556, 833, 722, 778,
+ 667, 778, 722, 667, 611, 722, 667, 944,
+ 667, 667, 611, 278, 278, 278, 469, 556,
+ 222, 556, 556, 500, 556, 556, 278, 556,
+ 556, 222, 222, 500, 222, 833, 556, 556,
+ 556, 556, 333, 500, 278, 556, 500, 722,
+ 500, 500, 500, 334, 260, 334, 584, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 333, 556, 556, 167, 556, 556, 556,
+ 556, 191, 333, 556, 333, 333, 500, 500,
+ 0, 556, 556, 556, 278, 0, 537, 350,
+ 222, 333, 333, 556, 1000, 1000, 0, 611,
+ 0, 333, 333, 333, 333, 333, 333, 333,
+ 333, 0, 333, 333, 0, 333, 333, 333,
+ 1000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1000, 0, 370, 0, 0, 0, 0,
+ 556, 778, 1000, 365, 0, 0, 0, 0,
+ 0, 889, 0, 0, 0, 278, 0, 0,
+ 222, 611, 944, 611, 0, 0, 0, 0,
+ 667, 667, 667, 667, 667, 667, 722, 667,
+ 667, 667, 667, 722, 278, 278, 278, 278,
+ 722, 778, 778, 778, 778, 778, 667, 667,
+ 722, 722, 722, 722, 667, 667, 611, 556,
+ 556, 556, 556, 556, 556, 260, 500, 737,
+ 400, 584, 556, 556, 556, 556, 556, 278,
+ 278, 278, 278, 584, 584, 556, 584, 556,
+ 556, 556, 556, 556, 834, 834, 333, 556,
+ 584, 737, 500, 556, 834, 333, 1000, 333,
+ 556, 556, 556, 556, 500, 500, 500
+};
+
+static Gushort helveticaBoldWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 278, 333, 474, 556, 556, 889, 722, 278,
+ 333, 333, 389, 584, 278, 333, 278, 278,
+ 556, 556, 556, 556, 556, 556, 556, 556,
+ 556, 556, 333, 333, 584, 584, 584, 611,
+ 975, 722, 722, 722, 722, 667, 611, 778,
+ 722, 278, 556, 722, 611, 833, 722, 778,
+ 667, 778, 722, 667, 611, 722, 667, 944,
+ 667, 667, 611, 333, 278, 333, 584, 556,
+ 278, 556, 611, 556, 611, 556, 333, 611,
+ 611, 278, 278, 556, 278, 889, 611, 611,
+ 611, 611, 389, 556, 333, 611, 556, 778,
+ 556, 556, 500, 389, 280, 389, 584, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 333, 556, 556, 167, 556, 556, 556,
+ 556, 238, 500, 556, 333, 333, 611, 611,
+ 0, 556, 556, 556, 278, 0, 556, 350,
+ 278, 500, 500, 556, 1000, 1000, 0, 611,
+ 0, 333, 333, 333, 333, 333, 333, 333,
+ 333, 0, 333, 333, 0, 333, 333, 333,
+ 1000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1000, 0, 370, 0, 0, 0, 0,
+ 611, 778, 1000, 365, 0, 0, 0, 0,
+ 0, 889, 0, 0, 0, 278, 0, 0,
+ 278, 611, 944, 611, 0, 0, 0, 0,
+ 722, 722, 722, 722, 722, 722, 722, 667,
+ 667, 667, 667, 722, 278, 278, 278, 278,
+ 722, 778, 778, 778, 778, 778, 667, 667,
+ 722, 722, 722, 722, 667, 667, 611, 556,
+ 556, 556, 556, 556, 556, 280, 556, 737,
+ 400, 584, 556, 556, 556, 556, 611, 278,
+ 278, 278, 278, 584, 584, 611, 584, 611,
+ 611, 611, 611, 611, 834, 834, 333, 611,
+ 584, 737, 556, 611, 834, 333, 1000, 333,
+ 611, 611, 611, 611, 556, 556, 500
+};
+
+static Gushort helveticaBoldObliqueWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 278, 333, 474, 556, 556, 889, 722, 278,
+ 333, 333, 389, 584, 278, 333, 278, 278,
+ 556, 556, 556, 556, 556, 556, 556, 556,
+ 556, 556, 333, 333, 584, 584, 584, 611,
+ 975, 722, 722, 722, 722, 667, 611, 778,
+ 722, 278, 556, 722, 611, 833, 722, 778,
+ 667, 778, 722, 667, 611, 722, 667, 944,
+ 667, 667, 611, 333, 278, 333, 584, 556,
+ 278, 556, 611, 556, 611, 556, 333, 611,
+ 611, 278, 278, 556, 278, 889, 611, 611,
+ 611, 611, 389, 556, 333, 611, 556, 778,
+ 556, 556, 500, 389, 280, 389, 584, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 333, 556, 556, 167, 556, 556, 556,
+ 556, 238, 500, 556, 333, 333, 611, 611,
+ 0, 556, 556, 556, 278, 0, 556, 350,
+ 278, 500, 500, 556, 1000, 1000, 0, 611,
+ 0, 333, 333, 333, 333, 333, 333, 333,
+ 333, 0, 333, 333, 0, 333, 333, 333,
+ 1000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1000, 0, 370, 0, 0, 0, 0,
+ 611, 778, 1000, 365, 0, 0, 0, 0,
+ 0, 889, 0, 0, 0, 278, 0, 0,
+ 278, 611, 944, 611, 0, 0, 0, 0,
+ 722, 722, 722, 722, 722, 722, 722, 667,
+ 667, 667, 667, 722, 278, 278, 278, 278,
+ 722, 778, 778, 778, 778, 778, 667, 667,
+ 722, 722, 722, 722, 667, 667, 611, 556,
+ 556, 556, 556, 556, 556, 280, 556, 737,
+ 400, 584, 556, 556, 556, 556, 611, 278,
+ 278, 278, 278, 584, 584, 611, 584, 611,
+ 611, 611, 611, 611, 834, 834, 333, 611,
+ 584, 737, 556, 611, 834, 333, 1000, 333,
+ 611, 611, 611, 611, 556, 556, 500
+};
+
+static Gushort helveticaObliqueWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 278, 278, 355, 556, 556, 889, 667, 222,
+ 333, 333, 389, 584, 278, 333, 278, 278,
+ 556, 556, 556, 556, 556, 556, 556, 556,
+ 556, 556, 278, 278, 584, 584, 584, 556,
+ 1015, 667, 667, 722, 722, 667, 611, 778,
+ 722, 278, 500, 667, 556, 833, 722, 778,
+ 667, 778, 722, 667, 611, 722, 667, 944,
+ 667, 667, 611, 278, 278, 278, 469, 556,
+ 222, 556, 556, 500, 556, 556, 278, 556,
+ 556, 222, 222, 500, 222, 833, 556, 556,
+ 556, 556, 333, 500, 278, 556, 500, 722,
+ 500, 500, 500, 334, 260, 334, 584, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 333, 556, 556, 167, 556, 556, 556,
+ 556, 191, 333, 556, 333, 333, 500, 500,
+ 0, 556, 556, 556, 278, 0, 537, 350,
+ 222, 333, 333, 556, 1000, 1000, 0, 611,
+ 0, 333, 333, 333, 333, 333, 333, 333,
+ 333, 0, 333, 333, 0, 333, 333, 333,
+ 1000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1000, 0, 370, 0, 0, 0, 0,
+ 556, 778, 1000, 365, 0, 0, 0, 0,
+ 0, 889, 0, 0, 0, 278, 0, 0,
+ 222, 611, 944, 611, 0, 0, 0, 0,
+ 667, 667, 667, 667, 667, 667, 722, 667,
+ 667, 667, 667, 722, 278, 278, 278, 278,
+ 722, 778, 778, 778, 778, 778, 667, 667,
+ 722, 722, 722, 722, 667, 667, 611, 556,
+ 556, 556, 556, 556, 556, 260, 500, 737,
+ 400, 584, 556, 556, 556, 556, 556, 278,
+ 278, 278, 278, 584, 584, 556, 584, 556,
+ 556, 556, 556, 556, 834, 834, 333, 556,
+ 584, 737, 500, 556, 834, 333, 1000, 333,
+ 556, 556, 556, 556, 500, 500, 500
+};
+
+static Gushort symbolWidths[257] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 250, 333, 713, 500, 549, 833, 778, 439,
+ 333, 333, 500, 549, 250, 549, 250, 278,
+ 500, 500, 500, 500, 500, 500, 500, 500,
+ 500, 500, 278, 278, 549, 549, 549, 444,
+ 549, 722, 667, 722, 612, 611, 763, 603,
+ 722, 333, 631, 722, 686, 889, 722, 722,
+ 768, 741, 556, 592, 611, 690, 439, 768,
+ 645, 795, 611, 333, 863, 333, 658, 500,
+ 500, 631, 549, 549, 494, 439, 521, 411,
+ 603, 329, 603, 549, 549, 576, 521, 549,
+ 549, 521, 549, 603, 439, 576, 713, 686,
+ 493, 686, 494, 480, 200, 480, 549, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 620, 247, 549, 167, 713, 500, 753,
+ 753, 753, 753, 1042, 987, 603, 987, 603,
+ 400, 549, 411, 549, 549, 713, 494, 460,
+ 549, 549, 549, 549, 1000, 603, 1000, 658,
+ 823, 686, 795, 987, 768, 768, 823, 768,
+ 768, 713, 713, 713, 713, 713, 713, 713,
+ 768, 713, 790, 790, 890, 823, 549, 250,
+ 713, 603, 603, 1042, 987, 603, 987, 603,
+ 494, 329, 790, 790, 786, 713, 384, 384,
+ 384, 384, 384, 384, 494, 494, 494, 494,
+ 0, 329, 274, 686, 686, 686, 384, 384,
+ 384, 384, 384, 384, 494, 494, 494, 0,
+ 790
+};
+
+static Gushort timesBoldWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 250, 333, 555, 500, 500, 1000, 833, 333,
+ 333, 333, 500, 570, 250, 333, 250, 278,
+ 500, 500, 500, 500, 500, 500, 500, 500,
+ 500, 500, 333, 333, 570, 570, 570, 500,
+ 930, 722, 667, 722, 722, 667, 611, 778,
+ 778, 389, 500, 778, 667, 944, 722, 778,
+ 611, 778, 722, 556, 667, 722, 722, 1000,
+ 722, 722, 667, 333, 278, 333, 581, 500,
+ 333, 500, 556, 444, 556, 444, 333, 500,
+ 556, 278, 333, 556, 278, 833, 556, 500,
+ 556, 556, 444, 389, 333, 556, 500, 722,
+ 500, 500, 444, 394, 220, 394, 520, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 333, 500, 500, 167, 500, 500, 500,
+ 500, 278, 500, 500, 333, 333, 556, 556,
+ 0, 500, 500, 500, 250, 0, 540, 350,
+ 333, 500, 500, 500, 1000, 1000, 0, 500,
+ 0, 333, 333, 333, 333, 333, 333, 333,
+ 333, 0, 333, 333, 0, 333, 333, 333,
+ 1000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1000, 0, 300, 0, 0, 0, 0,
+ 667, 778, 1000, 330, 0, 0, 0, 0,
+ 0, 722, 0, 0, 0, 278, 0, 0,
+ 278, 500, 722, 556, 0, 0, 0, 0,
+ 722, 722, 722, 722, 722, 722, 722, 667,
+ 667, 667, 667, 722, 389, 389, 389, 389,
+ 722, 778, 778, 778, 778, 778, 556, 611,
+ 722, 722, 722, 722, 722, 722, 667, 500,
+ 500, 500, 500, 500, 500, 220, 444, 747,
+ 400, 570, 444, 444, 444, 444, 500, 278,
+ 278, 278, 278, 570, 570, 556, 570, 556,
+ 500, 500, 500, 500, 750, 750, 300, 500,
+ 570, 747, 389, 556, 750, 300, 1000, 300,
+ 556, 556, 556, 556, 500, 500, 444
+};
+
+static Gushort timesBoldItalicWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 250, 389, 555, 500, 500, 833, 778, 333,
+ 333, 333, 500, 570, 250, 333, 250, 278,
+ 500, 500, 500, 500, 500, 500, 500, 500,
+ 500, 500, 333, 333, 570, 570, 570, 500,
+ 832, 667, 667, 667, 722, 667, 667, 722,
+ 778, 389, 500, 667, 611, 889, 722, 722,
+ 611, 722, 667, 556, 611, 722, 667, 889,
+ 667, 611, 611, 333, 278, 333, 570, 500,
+ 333, 500, 500, 444, 500, 444, 333, 500,
+ 556, 278, 278, 500, 278, 778, 556, 500,
+ 500, 500, 389, 389, 278, 556, 444, 667,
+ 500, 444, 389, 348, 220, 348, 570, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 389, 500, 500, 167, 500, 500, 500,
+ 500, 278, 500, 500, 333, 333, 556, 556,
+ 0, 500, 500, 500, 250, 0, 500, 350,
+ 333, 500, 500, 500, 1000, 1000, 0, 500,
+ 0, 333, 333, 333, 333, 333, 333, 333,
+ 333, 0, 333, 333, 0, 333, 333, 333,
+ 1000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 944, 0, 266, 0, 0, 0, 0,
+ 611, 722, 944, 300, 0, 0, 0, 0,
+ 0, 722, 0, 0, 0, 278, 0, 0,
+ 278, 500, 722, 500, 0, 0, 0, 0,
+ 667, 667, 667, 667, 667, 667, 667, 667,
+ 667, 667, 667, 722, 389, 389, 389, 389,
+ 722, 722, 722, 722, 722, 722, 556, 611,
+ 722, 722, 722, 722, 611, 611, 611, 500,
+ 500, 500, 500, 500, 500, 220, 444, 747,
+ 400, 570, 444, 444, 444, 444, 500, 278,
+ 278, 278, 278, 606, 606, 576, 570, 556,
+ 500, 500, 500, 500, 750, 750, 300, 500,
+ 570, 747, 389, 500, 750, 300, 1000, 300,
+ 556, 556, 556, 556, 444, 444, 389
+};
+
+static Gushort timesItalicWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 250, 333, 420, 500, 500, 833, 778, 333,
+ 333, 333, 500, 675, 250, 333, 250, 278,
+ 500, 500, 500, 500, 500, 500, 500, 500,
+ 500, 500, 333, 333, 675, 675, 675, 500,
+ 920, 611, 611, 667, 722, 611, 611, 722,
+ 722, 333, 444, 667, 556, 833, 667, 722,
+ 611, 722, 611, 500, 556, 722, 611, 833,
+ 611, 556, 556, 389, 278, 389, 422, 500,
+ 333, 500, 500, 444, 500, 444, 278, 500,
+ 500, 278, 278, 444, 278, 722, 500, 500,
+ 500, 500, 389, 389, 278, 500, 444, 667,
+ 444, 444, 389, 400, 275, 400, 541, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 389, 500, 500, 167, 500, 500, 500,
+ 500, 214, 556, 500, 333, 333, 500, 500,
+ 0, 500, 500, 500, 250, 0, 523, 350,
+ 333, 556, 556, 500, 889, 1000, 0, 500,
+ 0, 333, 333, 333, 333, 333, 333, 333,
+ 333, 0, 333, 333, 0, 333, 333, 333,
+ 889, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 889, 0, 276, 0, 0, 0, 0,
+ 556, 722, 944, 310, 0, 0, 0, 0,
+ 0, 667, 0, 0, 0, 278, 0, 0,
+ 278, 500, 667, 500, 0, 0, 0, 0,
+ 611, 611, 611, 611, 611, 611, 667, 611,
+ 611, 611, 611, 722, 333, 333, 333, 333,
+ 667, 722, 722, 722, 722, 722, 500, 611,
+ 722, 722, 722, 722, 556, 556, 556, 500,
+ 500, 500, 500, 500, 500, 275, 444, 760,
+ 400, 675, 444, 444, 444, 444, 500, 278,
+ 278, 278, 278, 675, 675, 500, 675, 500,
+ 500, 500, 500, 500, 750, 750, 300, 500,
+ 675, 760, 389, 500, 750, 300, 980, 300,
+ 500, 500, 500, 500, 444, 444, 389
+};
+
+static Gushort timesRomanWidths[335] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 250, 333, 408, 500, 500, 833, 778, 333,
+ 333, 333, 500, 564, 250, 333, 250, 278,
+ 500, 500, 500, 500, 500, 500, 500, 500,
+ 500, 500, 278, 278, 564, 564, 564, 444,
+ 921, 722, 667, 667, 722, 611, 556, 722,
+ 722, 333, 389, 722, 611, 889, 722, 722,
+ 556, 722, 667, 556, 611, 722, 722, 944,
+ 722, 722, 611, 333, 278, 333, 469, 500,
+ 333, 444, 500, 444, 500, 444, 333, 500,
+ 500, 278, 278, 500, 278, 778, 500, 500,
+ 500, 500, 333, 389, 278, 500, 500, 722,
+ 500, 500, 444, 480, 200, 480, 541, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 333, 500, 500, 167, 500, 500, 500,
+ 500, 180, 444, 500, 333, 333, 556, 556,
+ 0, 500, 500, 500, 250, 0, 453, 350,
+ 333, 444, 444, 500, 1000, 1000, 0, 444,
+ 0, 333, 333, 333, 333, 333, 333, 333,
+ 333, 0, 333, 333, 0, 333, 333, 333,
+ 1000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 889, 0, 276, 0, 0, 0, 0,
+ 611, 722, 889, 310, 0, 0, 0, 0,
+ 0, 667, 0, 0, 0, 278, 0, 0,
+ 278, 500, 722, 500, 0, 0, 0, 0,
+ 722, 722, 722, 722, 722, 722, 667, 611,
+ 611, 611, 611, 722, 333, 333, 333, 333,
+ 722, 722, 722, 722, 722, 722, 556, 556,
+ 722, 722, 722, 722, 722, 722, 611, 444,
+ 444, 444, 444, 444, 444, 200, 444, 760,
+ 400, 564, 444, 444, 444, 444, 500, 278,
+ 278, 278, 278, 564, 564, 500, 564, 500,
+ 500, 500, 500, 500, 750, 750, 300, 500,
+ 564, 760, 389, 500, 750, 300, 980, 300,
+ 500, 500, 500, 500, 500, 500, 444
+};
+
+static Gushort zapfDingbatsWidths[270] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 278, 974, 961, 974, 980, 719, 789, 790,
+ 791, 690, 960, 939, 549, 855, 911, 933,
+ 911, 945, 974, 755, 846, 762, 761, 571,
+ 677, 763, 760, 759, 754, 494, 552, 537,
+ 577, 692, 786, 788, 788, 790, 793, 794,
+ 816, 823, 789, 841, 823, 833, 816, 831,
+ 923, 744, 723, 749, 790, 792, 695, 776,
+ 768, 792, 759, 707, 708, 682, 701, 826,
+ 815, 789, 789, 707, 687, 696, 689, 786,
+ 787, 713, 791, 785, 791, 873, 761, 762,
+ 762, 759, 759, 892, 892, 788, 784, 438,
+ 138, 277, 415, 392, 392, 668, 668, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 732, 544, 544, 910, 667, 760, 760,
+ 776, 595, 694, 626, 788, 788, 788, 788,
+ 788, 788, 788, 788, 788, 788, 788, 788,
+ 788, 788, 788, 788, 788, 788, 788, 788,
+ 788, 788, 788, 788, 788, 788, 788, 788,
+ 788, 788, 788, 788, 788, 788, 788, 788,
+ 788, 788, 788, 788, 894, 838, 1016, 458,
+ 748, 924, 748, 918, 927, 928, 928, 834,
+ 873, 828, 924, 924, 917, 930, 931, 463,
+ 883, 836, 836, 867, 867, 696, 696, 874,
+ 0, 874, 760, 946, 771, 865, 771, 888,
+ 967, 888, 831, 873, 927, 970, 918, 0,
+ 509, 410, 509, 410, 234, 234, 390, 390,
+ 276, 276, 317, 317, 334, 334
+};
+
+//------------------------------------------------------------------------
+// Built-in font table.
+//------------------------------------------------------------------------
+
+struct BuiltinFont {
+ char *name;
+ Gushort *widths;
+ FontEncoding *encoding;
+ short ascent;
+ short descent;
+};
+
+#define numBuiltinFonts ((int)(sizeof(builtinFonts)/sizeof(BuiltinFont)))
+
+static BuiltinFont builtinFonts[] = {
+ {"Courier", courierWidths, &standardEncoding, 624, -207},
+ {"Courier-Bold", courierBoldWidths, &standardEncoding, 674, -257},
+ {"Courier-BoldOblique", courierBoldObliqueWidths, &standardEncoding, 674, -257},
+ {"Courier-Oblique", courierObliqueWidths, &standardEncoding, 624, -207},
+ {"Helvetica", helveticaWidths, &standardEncoding, 729, -219},
+ {"Helvetica-Bold", helveticaBoldWidths, &standardEncoding, 729, -219},
+ {"Helvetica-BoldOblique", helveticaBoldObliqueWidths, &standardEncoding, 729, -219},
+ {"Helvetica-Oblique", helveticaObliqueWidths, &standardEncoding, 729, -219},
+ {"Symbol", symbolWidths, &symbolEncoding, 1010, -293},
+ {"Times-Bold", timesBoldWidths, &standardEncoding, 670, -210},
+ {"Times-BoldItalic", timesBoldItalicWidths, &standardEncoding, 682, -203},
+ {"Times-Italic", timesItalicWidths, &standardEncoding, 684, -206},
+ {"Times-Roman", timesRomanWidths, &standardEncoding, 682, -217},
+ {"ZapfDingbats", zapfDingbatsWidths, &zapfDingbatsEncoding, 820, -143}
+};
+
+#endif
diff --git a/pdftops/FormWidget.cxx b/pdftops/FormWidget.cxx
new file mode 100644
index 000000000..a9f8c0693
--- /dev/null
+++ b/pdftops/FormWidget.cxx
@@ -0,0 +1,130 @@
+//========================================================================
+//
+// FormWidget.cc
+//
+// Copyright 2000 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include "gmem.h"
+#include "Object.h"
+#include "Gfx.h"
+#include "FormWidget.h"
+
+//------------------------------------------------------------------------
+// FormWidget
+//------------------------------------------------------------------------
+
+FormWidget::FormWidget(XRef *xrefA, Dict *dict) {
+ Object obj1, obj2;
+ double t;
+
+ ok = gFalse;
+ xref = xrefA;
+
+ if (dict->lookup("AP", &obj1)->isDict()) {
+ obj1.dictLookupNF("N", &obj2);
+ //~ this doesn't handle appearances with multiple states --
+ //~ need to look at AS key to get state and then get the
+ //~ corresponding entry from the N dict
+ if (obj2.isRef()) {
+ obj2.copy(&appearance);
+ ok = gTrue;
+ }
+ obj2.free();
+ }
+ obj1.free();
+
+ if (dict->lookup("Rect", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 4) {
+ //~ should check object types here
+ obj1.arrayGet(0, &obj2);
+ xMin = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ yMin = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(2, &obj2);
+ xMax = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(3, &obj2);
+ yMax = obj2.getNum();
+ obj2.free();
+ if (xMin > xMax) {
+ t = xMin; xMin = xMax; xMax = t;
+ }
+ if (yMin > yMax) {
+ t = yMin; yMin = yMax; yMax = t;
+ }
+ } else {
+ //~ this should return an error
+ xMin = yMin = 0;
+ xMax = yMax = 1;
+ }
+ obj1.free();
+}
+
+FormWidget::~FormWidget() {
+ appearance.free();
+}
+
+void FormWidget::draw(Gfx *gfx) {
+ Object obj;
+
+ if (appearance.fetch(xref, &obj)->isStream()) {
+ gfx->doWidgetForm(&obj, xMin, yMin, xMax, yMax);
+ }
+ obj.free();
+}
+
+//------------------------------------------------------------------------
+// FormWidgets
+//------------------------------------------------------------------------
+
+FormWidgets::FormWidgets(XRef *xref, Object *annots) {
+ FormWidget *widget;
+ Object obj1, obj2;
+ int size;
+ int i;
+
+ widgets = NULL;
+ size = 0;
+ nWidgets = 0;
+
+ if (annots->isArray()) {
+ for (i = 0; i < annots->arrayGetLength(); ++i) {
+ if (annots->arrayGet(i, &obj1)->isDict()) {
+ obj1.dictLookup("Subtype", &obj2);
+ if (obj2.isName("Widget") ||
+ obj2.isName("Stamp")) {
+ widget = new FormWidget(xref, obj1.getDict());
+ if (widget->isOk()) {
+ if (nWidgets >= size) {
+ size += 16;
+ widgets = (FormWidget **)grealloc(widgets,
+ size * sizeof(FormWidget *));
+ }
+ widgets[nWidgets++] = widget;
+ } else {
+ delete widget;
+ }
+ }
+ obj2.free();
+ }
+ obj1.free();
+ }
+ }
+}
+
+FormWidgets::~FormWidgets() {
+ int i;
+
+ for (i = 0; i < nWidgets; ++i) {
+ delete widgets[i];
+ }
+ gfree(widgets);
+}
diff --git a/pdftops/FormWidget.h b/pdftops/FormWidget.h
new file mode 100644
index 000000000..c14421e81
--- /dev/null
+++ b/pdftops/FormWidget.h
@@ -0,0 +1,67 @@
+//========================================================================
+//
+// FormWidget.h
+//
+// Copyright 2000 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef FORMWIDGET_H
+#define FORMWIDGET_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+class XRef;
+class Gfx;
+
+//------------------------------------------------------------------------
+// FormWidget
+//------------------------------------------------------------------------
+
+class FormWidget {
+public:
+
+ FormWidget(XRef *xrefA, Dict *dict);
+ ~FormWidget();
+ GBool isOk() { return ok; }
+
+ void draw(Gfx *gfx);
+
+ // Get appearance object.
+ Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); }
+
+private:
+
+ XRef *xref; // the xref table for this PDF file
+ Object appearance; // a reference to the Form XObject stream
+ // for the normal appearance
+ double xMin, yMin, // widget rectangle
+ xMax, yMax;
+ GBool ok;
+};
+
+//------------------------------------------------------------------------
+// FormWidgets
+//------------------------------------------------------------------------
+
+class FormWidgets {
+public:
+
+ // Extract widgets from array of annotations.
+ FormWidgets(XRef *xref, Object *annots);
+
+ ~FormWidgets();
+
+ // Iterate through list of widgets.
+ int getNumWidgets() { return nWidgets; }
+ FormWidget *getWidget(int i) { return widgets[i]; }
+
+private:
+
+ FormWidget **widgets;
+ int nWidgets;
+};
+
+#endif
diff --git a/pdftops/Function.cxx b/pdftops/Function.cxx
new file mode 100644
index 000000000..d52088808
--- /dev/null
+++ b/pdftops/Function.cxx
@@ -0,0 +1,1373 @@
+//========================================================================
+//
+// Function.cc
+//
+// Copyright 2001 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include "gmem.h"
+#include "Object.h"
+#include "Dict.h"
+#include "Stream.h"
+#include "Error.h"
+#include "Function.h"
+
+//------------------------------------------------------------------------
+// Function
+//------------------------------------------------------------------------
+
+Function::Function() {
+}
+
+Function::~Function() {
+}
+
+Function *Function::parse(Object *funcObj) {
+ Function *func;
+ Dict *dict;
+ int funcType;
+ Object obj1;
+
+ if (funcObj->isStream()) {
+ dict = funcObj->streamGetDict();
+ } else if (funcObj->isDict()) {
+ dict = funcObj->getDict();
+ } else if (funcObj->isName("Identity")) {
+ return new IdentityFunction();
+ } else {
+ error(-1, "Expected function dictionary or stream");
+ return NULL;
+ }
+
+ if (!dict->lookup("FunctionType", &obj1)->isInt()) {
+ error(-1, "Function type is missing or wrong type");
+ obj1.free();
+ return NULL;
+ }
+ funcType = obj1.getInt();
+ obj1.free();
+
+ if (funcType == 0) {
+ func = new SampledFunction(funcObj, dict);
+ } else if (funcType == 2) {
+ func = new ExponentialFunction(funcObj, dict);
+ } else if (funcType == 4) {
+ func = new PostScriptFunction(funcObj, dict);
+ } else {
+ error(-1, "Unimplemented function type (%d)", funcType);
+ return NULL;
+ }
+ if (!func->isOk()) {
+ delete func;
+ return NULL;
+ }
+
+ return func;
+}
+
+GBool Function::init(Dict *dict) {
+ Object obj1, obj2;
+ int i;
+
+ //----- Domain
+ if (!dict->lookup("Domain", &obj1)->isArray()) {
+ error(-1, "Function is missing domain");
+ goto err2;
+ }
+ m = obj1.arrayGetLength() / 2;
+ if (m > funcMaxInputs) {
+ error(-1, "Functions with more than %d inputs are unsupported",
+ funcMaxInputs);
+ goto err2;
+ }
+ for (i = 0; i < m; ++i) {
+ obj1.arrayGet(2*i, &obj2);
+ if (!obj2.isNum()) {
+ error(-1, "Illegal value in function domain array");
+ goto err1;
+ }
+ domain[i][0] = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(2*i+1, &obj2);
+ if (!obj2.isNum()) {
+ error(-1, "Illegal value in function domain array");
+ goto err1;
+ }
+ domain[i][1] = obj2.getNum();
+ obj2.free();
+ }
+ obj1.free();
+
+ //----- Range
+ hasRange = gFalse;
+ n = 0;
+ if (dict->lookup("Range", &obj1)->isArray()) {
+ hasRange = gTrue;
+ n = obj1.arrayGetLength() / 2;
+ if (n > funcMaxOutputs) {
+ error(-1, "Functions with more than %d outputs are unsupported",
+ funcMaxOutputs);
+ goto err2;
+ }
+ for (i = 0; i < n; ++i) {
+ obj1.arrayGet(2*i, &obj2);
+ if (!obj2.isNum()) {
+ error(-1, "Illegal value in function range array");
+ goto err1;
+ }
+ range[i][0] = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(2*i+1, &obj2);
+ if (!obj2.isNum()) {
+ error(-1, "Illegal value in function range array");
+ goto err1;
+ }
+ range[i][1] = obj2.getNum();
+ obj2.free();
+ }
+ }
+ obj1.free();
+
+ return gTrue;
+
+ err1:
+ obj2.free();
+ err2:
+ obj1.free();
+ return gFalse;
+}
+
+//------------------------------------------------------------------------
+// IdentityFunction
+//------------------------------------------------------------------------
+
+IdentityFunction::IdentityFunction() {
+ int i;
+
+ // fill these in with arbitrary values just in case they get used
+ // somewhere
+ m = funcMaxInputs;
+ n = funcMaxOutputs;
+ for (i = 0; i < funcMaxInputs; ++i) {
+ domain[i][0] = 0;
+ domain[i][1] = 1;
+ }
+ hasRange = gFalse;
+}
+
+IdentityFunction::~IdentityFunction() {
+}
+
+void IdentityFunction::transform(double *in, double *out) {
+ int i;
+
+ for (i = 0; i < funcMaxOutputs; ++i) {
+ out[i] = in[i];
+ }
+}
+
+//------------------------------------------------------------------------
+// SampledFunction
+//------------------------------------------------------------------------
+
+SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
+ Stream *str;
+ int nSamples, sampleBits;
+ double sampleMul;
+ Object obj1, obj2;
+ Guint buf, bitMask;
+ int bits;
+ int s;
+ int i;
+
+ samples = NULL;
+ ok = gFalse;
+
+ //----- initialize the generic stuff
+ if (!init(dict)) {
+ goto err1;
+ }
+ if (!hasRange) {
+ error(-1, "Type 0 function is missing range");
+ goto err1;
+ }
+
+ //----- get the stream
+ if (!funcObj->isStream()) {
+ error(-1, "Type 0 function isn't a stream");
+ goto err1;
+ }
+ str = funcObj->getStream();
+
+ //----- Size
+ if (!dict->lookup("Size", &obj1)->isArray() ||
+ obj1.arrayGetLength() != m) {
+ error(-1, "Function has missing or invalid size array");
+ goto err2;
+ }
+ for (i = 0; i < m; ++i) {
+ obj1.arrayGet(i, &obj2);
+ if (!obj2.isInt()) {
+ error(-1, "Illegal value in function size array");
+ goto err3;
+ }
+ sampleSize[i] = obj2.getInt();
+ obj2.free();
+ }
+ obj1.free();
+
+ //----- BitsPerSample
+ if (!dict->lookup("BitsPerSample", &obj1)->isInt()) {
+ error(-1, "Function has missing or invalid BitsPerSample");
+ goto err2;
+ }
+ sampleBits = obj1.getInt();
+ sampleMul = 1.0 / (double)((1 << sampleBits) - 1);
+ obj1.free();
+
+ //----- Encode
+ if (dict->lookup("Encode", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 2*m) {
+ for (i = 0; i < m; ++i) {
+ obj1.arrayGet(2*i, &obj2);
+ if (!obj2.isNum()) {
+ error(-1, "Illegal value in function encode array");
+ goto err3;
+ }
+ encode[i][0] = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(2*i+1, &obj2);
+ if (!obj2.isNum()) {
+ error(-1, "Illegal value in function encode array");
+ goto err3;
+ }
+ encode[i][1] = obj2.getNum();
+ obj2.free();
+ }
+ } else {
+ for (i = 0; i < m; ++i) {
+ encode[i][0] = 0;
+ encode[i][1] = sampleSize[i] - 1;
+ }
+ }
+ obj1.free();
+
+ //----- Decode
+ if (dict->lookup("Decode", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 2*n) {
+ for (i = 0; i < n; ++i) {
+ obj1.arrayGet(2*i, &obj2);
+ if (!obj2.isNum()) {
+ error(-1, "Illegal value in function decode array");
+ goto err3;
+ }
+ decode[i][0] = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(2*i+1, &obj2);
+ if (!obj2.isNum()) {
+ error(-1, "Illegal value in function decode array");
+ goto err3;
+ }
+ decode[i][1] = obj2.getNum();
+ obj2.free();
+ }
+ } else {
+ for (i = 0; i < n; ++i) {
+ decode[i][0] = range[i][0];
+ decode[i][1] = range[i][1];
+ }
+ }
+ obj1.free();
+
+ //----- samples
+ nSamples = n;
+ for (i = 0; i < m; ++i)
+ nSamples *= sampleSize[i];
+ samples = (double *)gmalloc(nSamples * sizeof(double));
+ buf = 0;
+ bits = 0;
+ bitMask = (1 << sampleBits) - 1;
+ str->reset();
+ for (i = 0; i < nSamples; ++i) {
+ if (sampleBits == 8) {
+ s = str->getChar();
+ } else if (sampleBits == 16) {
+ s = str->getChar();
+ s = (s << 8) + str->getChar();
+ } else if (sampleBits == 32) {
+ s = str->getChar();
+ s = (s << 8) + str->getChar();
+ s = (s << 8) + str->getChar();
+ s = (s << 8) + str->getChar();
+ } else {
+ while (bits < sampleBits) {
+ buf = (buf << 8) | (str->getChar() & 0xff);
+ bits += 8;
+ }
+ s = (buf >> (bits - sampleBits)) & bitMask;
+ bits -= sampleBits;
+ }
+ samples[i] = (double)s * sampleMul;
+ }
+ str->close();
+
+ ok = gTrue;
+ return;
+
+ err3:
+ obj2.free();
+ err2:
+ obj1.free();
+ err1:
+ return;
+}
+
+SampledFunction::~SampledFunction() {
+ if (samples) {
+ gfree(samples);
+ }
+}
+
+SampledFunction::SampledFunction(SampledFunction *func) {
+ int nSamples, i;
+
+ memcpy(this, func, sizeof(SampledFunction));
+
+ nSamples = n;
+ for (i = 0; i < m; ++i) {
+ nSamples *= sampleSize[i];
+ }
+ samples = (double *)gmalloc(nSamples * sizeof(double));
+ memcpy(samples, func->samples, nSamples * sizeof(double));
+}
+
+void SampledFunction::transform(double *in, double *out) {
+ double x;
+ int e[2][funcMaxInputs];
+ double efrac[funcMaxInputs];
+ double s0[1 << funcMaxInputs], s1[1 << funcMaxInputs];
+ int i, j, k, idx;
+
+ // map input values into sample array
+ for (i = 0; i < m; ++i) {
+ x = ((in[i] - domain[i][0]) / (domain[i][1] - domain[i][0])) *
+ (encode[i][1] - encode[i][0]) + encode[i][0];
+ if (x < 0) {
+ x = 0;
+ } else if (x > sampleSize[i] - 1) {
+ x = sampleSize[i] - 1;
+ }
+ e[0][i] = (int)floor(x);
+ e[1][i] = (int)ceil(x);
+ efrac[i] = x - e[0][i];
+ }
+
+ // for each output, do m-linear interpolation
+ for (i = 0; i < n; ++i) {
+
+ // pull 2^m values out of the sample array
+ for (j = 0; j < (1<<m); ++j) {
+ idx = e[j & 1][m - 1];
+ for (k = m - 2; k >= 0; --k) {
+ idx = idx * sampleSize[k] + e[(j >> k) & 1][k];
+ }
+ idx = idx * n + i;
+ s0[j] = samples[idx];
+ }
+
+ // do m sets of interpolations
+ for (j = 0; j < m; ++j) {
+ for (k = 0; k < (1 << (m - j)); k += 2) {
+ s1[k >> 1] = (1 - efrac[j]) * s0[k] + efrac[j] * s0[k+1];
+ }
+ memcpy(s0, s1, (1 << (m - j - 1)) * sizeof(double));
+ }
+
+ // map output value to range
+ out[i] = s0[0] * (decode[i][1] - decode[i][0]) + decode[i][0];
+ if (out[i] < range[i][0]) {
+ out[i] = range[i][0];
+ } else if (out[i] > range[i][1]) {
+ out[i] = range[i][1];
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// ExponentialFunction
+//------------------------------------------------------------------------
+
+ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
+ Object obj1, obj2;
+ GBool hasN;
+ int i;
+
+ ok = gFalse;
+ hasN = gFalse;
+
+ //----- initialize the generic stuff
+ if (!init(dict)) {
+ goto err1;
+ }
+ if (m != 1) {
+ error(-1, "Exponential function with more than one input");
+ goto err1;
+ }
+
+ //----- default values
+ for (i = 0; i < funcMaxOutputs; ++i) {
+ c0[i] = 0;
+ c1[i] = 1;
+ }
+
+ //----- C0
+ if (dict->lookup("C0", &obj1)->isArray()) {
+ if (!hasN) {
+ n = obj1.arrayGetLength();
+ } else if (obj1.arrayGetLength() != n) {
+ error(-1, "Function's C0 array is wrong length");
+ goto err2;
+ }
+ for (i = 0; i < n; ++i) {
+ obj1.arrayGet(i, &obj2);
+ if (!obj2.isNum()) {
+ error(-1, "Illegal value in function C0 array");
+ goto err3;
+ }
+ c0[i] = obj2.getNum();
+ obj2.free();
+ }
+ }
+ obj1.free();
+
+ //----- C1
+ if (dict->lookup("C1", &obj1)->isArray()) {
+ if (!hasN) {
+ n = obj1.arrayGetLength();
+ } else if (obj1.arrayGetLength() != n) {
+ error(-1, "Function's C1 array is wrong length");
+ goto err2;
+ }
+ for (i = 0; i < n; ++i) {
+ obj1.arrayGet(i, &obj2);
+ if (!obj2.isNum()) {
+ error(-1, "Illegal value in function C1 array");
+ goto err3;
+ }
+ c1[i] = obj2.getNum();
+ obj2.free();
+ }
+ }
+ obj1.free();
+
+ //----- N (exponent)
+ if (!dict->lookup("N", &obj1)->isNum()) {
+ error(-1, "Function has missing or invalid N");
+ goto err2;
+ }
+ e = obj1.getNum();
+ obj1.free();
+
+ ok = gTrue;
+ return;
+
+ err3:
+ obj2.free();
+ err2:
+ obj1.free();
+ err1:
+ return;
+}
+
+ExponentialFunction::~ExponentialFunction() {
+}
+
+ExponentialFunction::ExponentialFunction(ExponentialFunction *func) {
+ memcpy(this, func, sizeof(ExponentialFunction));
+}
+
+void ExponentialFunction::transform(double *in, double *out) {
+ double x;
+ int i;
+
+ if (in[0] < domain[0][0]) {
+ x = domain[0][0];
+ } else if (in[0] > domain[0][1]) {
+ x = domain[0][1];
+ } else {
+ x = in[0];
+ }
+ for (i = 0; i < n; ++i) {
+ out[i] = c0[i] + pow(x, e) * (c1[i] - c0[i]);
+ if (hasRange) {
+ if (out[i] < range[i][0]) {
+ out[i] = range[i][0];
+ } else if (out[i] > range[i][1]) {
+ out[i] = range[i][1];
+ }
+ }
+ }
+ return;
+}
+
+//------------------------------------------------------------------------
+// PostScriptFunction
+//------------------------------------------------------------------------
+
+enum PSOp {
+ psOpAbs,
+ psOpAdd,
+ psOpAnd,
+ psOpAtan,
+ psOpBitshift,
+ psOpCeiling,
+ psOpCopy,
+ psOpCos,
+ psOpCvi,
+ psOpCvr,
+ psOpDiv,
+ psOpDup,
+ psOpEq,
+ psOpExch,
+ psOpExp,
+ psOpFalse,
+ psOpFloor,
+ psOpGe,
+ psOpGt,
+ psOpIdiv,
+ psOpIndex,
+ psOpLe,
+ psOpLn,
+ psOpLog,
+ psOpLt,
+ psOpMod,
+ psOpMul,
+ psOpNe,
+ psOpNeg,
+ psOpNot,
+ psOpOr,
+ psOpPop,
+ psOpRoll,
+ psOpRound,
+ psOpSin,
+ psOpSqrt,
+ psOpSub,
+ psOpTrue,
+ psOpTruncate,
+ psOpXor,
+ psOpIf,
+ psOpIfelse,
+ psOpReturn
+};
+
+// Note: 'if' and 'ifelse' are parsed separately.
+// The rest are listed here in alphabetical order.
+// The index in this table is equivalent to the entry in PSOp.
+char *psOpNames[] = {
+ "abs",
+ "add",
+ "and",
+ "atan",
+ "bitshift",
+ "ceiling",
+ "copy",
+ "cos",
+ "cvi",
+ "cvr",
+ "div",
+ "dup",
+ "eq",
+ "exch",
+ "exp",
+ "false",
+ "floor",
+ "ge",
+ "gt",
+ "idiv",
+ "index",
+ "le",
+ "ln",
+ "log",
+ "lt",
+ "mod",
+ "mul",
+ "ne",
+ "neg",
+ "not",
+ "or",
+ "pop",
+ "roll",
+ "round",
+ "sin",
+ "sqrt",
+ "sub",
+ "true",
+ "truncate",
+ "xor"
+};
+
+#define nPSOps (sizeof(psOpNames) / sizeof(char *))
+
+enum PSObjectType {
+ psBool,
+ psInt,
+ psReal,
+ psOperator,
+ psBlock
+};
+
+// In the code array, 'if'/'ifelse' operators take up three slots
+// plus space for the code in the subclause(s).
+//
+// +---------------------------------+
+// | psOperator: psOpIf / psOpIfelse |
+// +---------------------------------+
+// | psBlock: ptr=<A> |
+// +---------------------------------+
+// | psBlock: ptr=<B> |
+// +---------------------------------+
+// | if clause |
+// | ... |
+// | psOperator: psOpReturn |
+// +---------------------------------+
+// <A> | else clause |
+// | ... |
+// | psOperator: psOpReturn |
+// +---------------------------------+
+// <B> | ... |
+//
+// For 'if', pointer <A> is present in the code stream but unused.
+
+struct PSObject {
+ PSObjectType type;
+ union {
+ GBool booln; // boolean (stack only)
+ int intg; // integer (stack and code)
+ double real; // real (stack and code)
+ PSOp op; // operator (code only)
+ int blk; // if/ifelse block pointer (code only)
+ };
+};
+
+#define psStackSize 100
+
+class PSStack {
+public:
+
+ PSStack() { sp = psStackSize; }
+ void pushBool(GBool booln);
+ void pushInt(int intg);
+ void pushReal(double real);
+ GBool popBool();
+ int popInt();
+ double popNum();
+ GBool empty() { return sp == psStackSize; }
+ GBool topIsInt() { return sp < psStackSize && stack[sp].type == psInt; }
+ GBool topTwoAreInts()
+ { return sp < psStackSize - 1 &&
+ stack[sp].type == psInt &&
+ stack[sp+1].type == psInt; }
+ GBool topIsReal() { return sp < psStackSize && stack[sp].type == psReal; }
+ GBool topTwoAreNums()
+ { return sp < psStackSize - 1 &&
+ (stack[sp].type == psInt || stack[sp].type == psReal) &&
+ (stack[sp+1].type == psInt || stack[sp+1].type == psReal); }
+ void copy(int n);
+ void roll(int n, int j);
+ void index(int i);
+ void pop();
+
+private:
+
+ GBool checkOverflow(int n = 1);
+ GBool checkUnderflow();
+ GBool checkType(PSObjectType t1, PSObjectType t2);
+
+ PSObject stack[psStackSize];
+ int sp;
+};
+
+GBool PSStack::checkOverflow(int n) {
+ if (sp - n < 0) {
+ error(-1, "Stack overflow in PostScript function");
+ return gFalse;
+ }
+ return gTrue;
+}
+
+GBool PSStack::checkUnderflow() {
+ if (sp == psStackSize) {
+ error(-1, "Stack underflow in PostScript function");
+ return gFalse;
+ }
+ return gTrue;
+}
+
+GBool PSStack::checkType(PSObjectType t1, PSObjectType t2) {
+ if (stack[sp].type != t1 && stack[sp].type != t2) {
+ error(-1, "Type mismatch in PostScript function");
+ return gFalse;
+ }
+ return gTrue;
+}
+
+void PSStack::pushBool(GBool booln) {
+ if (checkOverflow()) {
+ stack[--sp].type = psBool;
+ stack[sp].booln = booln;
+ }
+}
+
+void PSStack::pushInt(int intg) {
+ if (checkOverflow()) {
+ stack[--sp].type = psInt;
+ stack[sp].intg = intg;
+ }
+}
+
+void PSStack::pushReal(double real) {
+ if (checkOverflow()) {
+ stack[--sp].type = psReal;
+ stack[sp].real = real;
+ }
+}
+
+GBool PSStack::popBool() {
+ if (checkUnderflow() && checkType(psBool, psBool)) {
+ return stack[sp++].booln;
+ }
+ return gFalse;
+}
+
+int PSStack::popInt() {
+ if (checkUnderflow() && checkType(psInt, psInt)) {
+ return stack[sp++].intg;
+ }
+ return 0;
+}
+
+double PSStack::popNum() {
+ double ret;
+
+ if (checkUnderflow() && checkType(psInt, psReal)) {
+ ret = (stack[sp].type == psInt) ? (double)stack[sp].intg : stack[sp].real;
+ ++sp;
+ return ret;
+ }
+ return 0;
+}
+
+void PSStack::copy(int n) {
+ int i;
+
+ if (!checkOverflow(n)) {
+ return;
+ }
+ for (i = sp + n - 1; i <= sp; ++i) {
+ stack[i - n] = stack[i];
+ }
+ sp -= n;
+}
+
+void PSStack::roll(int n, int j) {
+ PSObject obj;
+ int i, k;
+
+ if (j >= 0) {
+ j %= n;
+ } else {
+ j = -j % n;
+ if (j != 0) {
+ j = n - j;
+ }
+ }
+ if (n <= 0 || j == 0) {
+ return;
+ }
+ for (i = 0; i < j; ++i) {
+ obj = stack[sp];
+ for (k = sp; k < sp + n - 1; ++k) {
+ stack[k] = stack[k+1];
+ }
+ stack[sp + n - 1] = obj;
+ }
+}
+
+void PSStack::index(int i) {
+ if (!checkOverflow()) {
+ return;
+ }
+ --sp;
+ stack[sp] = stack[sp + 1 + i];
+}
+
+void PSStack::pop() {
+ if (!checkUnderflow()) {
+ return;
+ }
+ ++sp;
+}
+
+PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict) {
+ Stream *str;
+ int codePtr;
+ GString *tok;
+
+ code = NULL;
+ codeSize = 0;
+ ok = gFalse;
+
+ //----- initialize the generic stuff
+ if (!init(dict)) {
+ goto err1;
+ }
+ if (!hasRange) {
+ error(-1, "Type 4 function is missing range");
+ goto err1;
+ }
+
+ //----- get the stream
+ if (!funcObj->isStream()) {
+ error(-1, "Type 4 function isn't a stream");
+ goto err1;
+ }
+ str = funcObj->getStream();
+
+ //----- parse the function
+ str->reset();
+ if (!(tok = getToken(str)) || tok->cmp("{")) {
+ error(-1, "Expected '{' at start of PostScript function");
+ if (tok) {
+ delete tok;
+ }
+ goto err1;
+ }
+ delete tok;
+ codePtr = 0;
+ if (!parseCode(str, &codePtr)) {
+ goto err2;
+ }
+ str->close();
+
+ ok = gTrue;
+
+ err2:
+ str->close();
+ err1:
+ return;
+}
+
+PostScriptFunction::PostScriptFunction(PostScriptFunction *func) {
+ memcpy(this, func, sizeof(PostScriptFunction));
+ code = (PSObject *)gmalloc(codeSize * sizeof(PSObject));
+ memcpy(code, func->code, codeSize * sizeof(PSObject));
+}
+
+PostScriptFunction::~PostScriptFunction() {
+ gfree(code);
+}
+
+void PostScriptFunction::transform(double *in, double *out) {
+ PSStack *stack;
+ int i;
+
+ stack = new PSStack();
+ for (i = 0; i < m; ++i) {
+ //~ may need to check for integers here
+ stack->pushReal(in[i]);
+ }
+ exec(stack, 0);
+ for (i = n - 1; i >= 0; --i) {
+ out[i] = stack->popNum();
+ if (out[i] < range[i][0]) {
+ out[i] = range[i][0];
+ } else if (out[i] > range[i][1]) {
+ out[i] = range[i][1];
+ }
+ }
+ // if (!stack->empty()) {
+ // error(-1, "Extra values on stack at end of PostScript function");
+ // }
+ delete stack;
+}
+
+GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) {
+ GString *tok;
+ char *p;
+ GBool isReal;
+ int opPtr, elsePtr;
+ int a, b, mid, cmp;
+
+ while (1) {
+ if (!(tok = getToken(str))) {
+ error(-1, "Unexpected end of PostScript function stream");
+ return gFalse;
+ }
+ p = tok->getCString();
+ if (isdigit(*p) || *p == '.' || *p == '-') {
+ isReal = gFalse;
+ for (++p; *p; ++p) {
+ if (*p == '.') {
+ isReal = gTrue;
+ break;
+ }
+ }
+ resizeCode(*codePtr);
+ if (isReal) {
+ code[*codePtr].type = psReal;
+ code[*codePtr].real = atof(tok->getCString());
+ } else {
+ code[*codePtr].type = psInt;
+ code[*codePtr].intg = atoi(tok->getCString());
+ }
+ ++*codePtr;
+ delete tok;
+ } else if (!tok->cmp("{")) {
+ delete tok;
+ opPtr = *codePtr;
+ *codePtr += 3;
+ resizeCode(opPtr + 2);
+ if (!parseCode(str, codePtr)) {
+ return gFalse;
+ }
+ if (!(tok = getToken(str))) {
+ error(-1, "Unexpected end of PostScript function stream");
+ return gFalse;
+ }
+ if (!tok->cmp("{")) {
+ elsePtr = *codePtr;
+ if (!parseCode(str, codePtr)) {
+ return gFalse;
+ }
+ } else {
+ elsePtr = -1;
+ }
+ delete tok;
+ if (!(tok = getToken(str))) {
+ error(-1, "Unexpected end of PostScript function stream");
+ return gFalse;
+ }
+ if (!tok->cmp("if")) {
+ if (elsePtr >= 0) {
+ error(-1, "Got 'if' operator with two blocks in PostScript function");
+ return gFalse;
+ }
+ code[opPtr].type = psOperator;
+ code[opPtr].op = psOpIf;
+ code[opPtr+2].type = psBlock;
+ code[opPtr+2].blk = *codePtr;
+ } else if (!tok->cmp("ifelse")) {
+ if (elsePtr < 0) {
+ error(-1, "Got 'ifelse' operator with one blocks in PostScript function");
+ return gFalse;
+ }
+ code[opPtr].type = psOperator;
+ code[opPtr].op = psOpIfelse;
+ code[opPtr+1].type = psBlock;
+ code[opPtr+1].blk = elsePtr;
+ code[opPtr+2].type = psBlock;
+ code[opPtr+2].blk = *codePtr;
+ } else {
+ error(-1, "Expected if/ifelse operator in PostScript function");
+ delete tok;
+ return gFalse;
+ }
+ delete tok;
+ } else if (!tok->cmp("}")) {
+ delete tok;
+ resizeCode(*codePtr);
+ code[*codePtr].type = psOperator;
+ code[*codePtr].op = psOpReturn;
+ ++*codePtr;
+ break;
+ } else {
+ a = -1;
+ b = nPSOps;
+ // invariant: psOpNames[a] < tok < psOpNames[b]
+ while (b - a > 1) {
+ mid = (a + b) / 2;
+ cmp = tok->cmp(psOpNames[mid]);
+ if (cmp > 0) {
+ a = mid;
+ } else if (cmp < 0) {
+ b = mid;
+ } else {
+ a = b = mid;
+ }
+ }
+ if (cmp != 0) {
+ error(-1, "Unknown operator '%s' in PostScript function",
+ tok->getCString());
+ delete tok;
+ return gFalse;
+ }
+ delete tok;
+ resizeCode(*codePtr);
+ code[*codePtr].type = psOperator;
+ code[*codePtr].op = (PSOp)a;
+ ++*codePtr;
+ }
+ }
+ return gTrue;
+}
+
+GString *PostScriptFunction::getToken(Stream *str) {
+ GString *s;
+ int c;
+
+ s = new GString();
+ do {
+ c = str->getChar();
+ } while (c != EOF && isspace(c));
+ if (c == '{' || c == '}') {
+ s->append((char)c);
+ } else if (isdigit(c) || c == '.' || c == '-') {
+ while (1) {
+ s->append((char)c);
+ c = str->lookChar();
+ if (c == EOF || !(isdigit(c) || c == '.' || c == '-')) {
+ break;
+ }
+ str->getChar();
+ }
+ } else {
+ while (1) {
+ s->append((char)c);
+ c = str->lookChar();
+ if (c == EOF || !isalnum(c)) {
+ break;
+ }
+ str->getChar();
+ }
+ }
+ return s;
+}
+
+void PostScriptFunction::resizeCode(int newSize) {
+ if (newSize >= codeSize) {
+ codeSize += 64;
+ code = (PSObject *)grealloc(code, codeSize * sizeof(PSObject));
+ }
+}
+
+void PostScriptFunction::exec(PSStack *stack, int codePtr) {
+ int i1, i2;
+ double r1, r2;
+ GBool b1, b2;
+
+ while (1) {
+ switch (code[codePtr].type) {
+ case psInt:
+ stack->pushInt(code[codePtr++].intg);
+ break;
+ case psReal:
+ stack->pushReal(code[codePtr++].real);
+ break;
+ case psOperator:
+ switch (code[codePtr++].op) {
+ case psOpAbs:
+ if (stack->topIsInt()) {
+ stack->pushInt(abs(stack->popInt()));
+ } else {
+ stack->pushReal(fabs(stack->popNum()));
+ }
+ break;
+ case psOpAdd:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushInt(i1 + i2);
+ } else {
+ r2 = stack->popNum();
+ r1 = stack->popNum();
+ stack->pushReal(r1 + r2);
+ }
+ break;
+ case psOpAnd:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushInt(i1 & i2);
+ } else {
+ b2 = stack->popBool();
+ b1 = stack->popBool();
+ stack->pushReal(b1 && b2);
+ }
+ break;
+ case psOpAtan:
+ r2 = stack->popNum();
+ r1 = stack->popNum();
+ stack->pushReal(atan2(r1, r2));
+ break;
+ case psOpBitshift:
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ if (i2 > 0) {
+ stack->pushInt(i1 << i2);
+ } else if (i2 < 0) {
+ stack->pushInt((int)((Guint)i1 >> i2));
+ } else {
+ stack->pushInt(i1);
+ }
+ break;
+ case psOpCeiling:
+ if (!stack->topIsInt()) {
+ stack->pushReal(ceil(stack->popNum()));
+ }
+ break;
+ case psOpCopy:
+ stack->copy(stack->popInt());
+ break;
+ case psOpCos:
+ stack->pushReal(cos(stack->popNum()));
+ break;
+ case psOpCvi:
+ if (!stack->topIsInt()) {
+ stack->pushInt((int)stack->popNum());
+ }
+ break;
+ case psOpCvr:
+ if (!stack->topIsReal()) {
+ stack->pushReal(stack->popNum());
+ }
+ break;
+ case psOpDiv:
+ r2 = stack->popNum();
+ r1 = stack->popNum();
+ stack->pushReal(r1 / r2);
+ break;
+ case psOpDup:
+ stack->copy(1);
+ break;
+ case psOpEq:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushBool(i1 == i2);
+ } else if (stack->topTwoAreNums()) {
+ r2 = stack->popNum();
+ r1 = stack->popNum();
+ stack->pushBool(r1 == r2);
+ } else {
+ b2 = stack->popBool();
+ b1 = stack->popBool();
+ stack->pushBool(b1 == b2);
+ }
+ break;
+ case psOpExch:
+ stack->roll(2, 1);
+ break;
+ case psOpExp:
+ r2 = stack->popInt();
+ r1 = stack->popInt();
+ stack->pushReal(pow(r1, r2));
+ break;
+ case psOpFalse:
+ stack->pushBool(gFalse);
+ break;
+ case psOpFloor:
+ if (!stack->topIsInt()) {
+ stack->pushReal(floor(stack->popNum()));
+ }
+ break;
+ case psOpGe:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushBool(i1 >= i2);
+ } else {
+ r2 = stack->popNum();
+ r1 = stack->popNum();
+ stack->pushBool(r1 >= r2);
+ }
+ break;
+ case psOpGt:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushBool(i1 > i2);
+ } else {
+ r2 = stack->popNum();
+ r1 = stack->popNum();
+ stack->pushBool(r1 > r2);
+ }
+ break;
+ case psOpIdiv:
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushInt(i1 / i2);
+ break;
+ case psOpIndex:
+ stack->index(stack->popInt());
+ break;
+ case psOpLe:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushBool(i1 <= i2);
+ } else {
+ r2 = stack->popNum();
+ r1 = stack->popNum();
+ stack->pushBool(r1 <= r2);
+ }
+ break;
+ case psOpLn:
+ stack->pushReal(log(stack->popNum()));
+ break;
+ case psOpLog:
+ stack->pushReal(log10(stack->popNum()));
+ break;
+ case psOpLt:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushBool(i1 < i2);
+ } else {
+ r2 = stack->popNum();
+ r1 = stack->popNum();
+ stack->pushBool(r1 < r2);
+ }
+ break;
+ case psOpMod:
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushInt(i1 % i2);
+ break;
+ case psOpMul:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ //~ should check for out-of-range, and push a real instead
+ stack->pushInt(i1 * i2);
+ } else {
+ r2 = stack->popNum();
+ r1 = stack->popNum();
+ stack->pushReal(r1 * r2);
+ }
+ break;
+ case psOpNe:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushBool(i1 != i2);
+ } else if (stack->topTwoAreNums()) {
+ r2 = stack->popNum();
+ r1 = stack->popNum();
+ stack->pushBool(r1 != r2);
+ } else {
+ b2 = stack->popBool();
+ b1 = stack->popBool();
+ stack->pushBool(b1 != b2);
+ }
+ break;
+ case psOpNeg:
+ if (stack->topIsInt()) {
+ stack->pushInt(-stack->popInt());
+ } else {
+ stack->pushReal(-stack->popNum());
+ }
+ break;
+ case psOpNot:
+ if (stack->topIsInt()) {
+ stack->pushInt(~stack->popInt());
+ } else {
+ stack->pushReal(!stack->popBool());
+ }
+ break;
+ case psOpOr:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushInt(i1 | i2);
+ } else {
+ b2 = stack->popBool();
+ b1 = stack->popBool();
+ stack->pushReal(b1 || b2);
+ }
+ break;
+ case psOpPop:
+ stack->pop();
+ break;
+ case psOpRoll:
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->roll(i1, i2);
+ break;
+ case psOpRound:
+ if (!stack->topIsInt()) {
+ r1 = stack->popNum();
+ stack->pushReal((r1 >= 0) ? floor(r1 + 0.5) : ceil(r1 - 0.5));
+ }
+ break;
+ case psOpSin:
+ stack->pushReal(cos(stack->popNum()));
+ break;
+ case psOpSqrt:
+ stack->pushReal(sqrt(stack->popNum()));
+ break;
+ case psOpSub:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushInt(i1 - i2);
+ } else {
+ r2 = stack->popNum();
+ r1 = stack->popNum();
+ stack->pushReal(r1 - r2);
+ }
+ break;
+ case psOpTrue:
+ stack->pushBool(gTrue);
+ break;
+ case psOpTruncate:
+ if (!stack->topIsInt()) {
+ r1 = stack->popNum();
+ stack->pushReal((r1 >= 0) ? floor(r1) : ceil(r1));
+ }
+ break;
+ case psOpXor:
+ if (stack->topTwoAreInts()) {
+ i2 = stack->popInt();
+ i1 = stack->popInt();
+ stack->pushInt(i1 ^ i2);
+ } else {
+ b2 = stack->popBool();
+ b1 = stack->popBool();
+ stack->pushReal(b1 ^ b2);
+ }
+ break;
+ case psOpIf:
+ b1 = stack->popBool();
+ if (b1) {
+ exec(stack, codePtr + 2);
+ }
+ codePtr = code[codePtr + 1].blk;
+ break;
+ case psOpIfelse:
+ b1 = stack->popBool();
+ if (b1) {
+ exec(stack, codePtr + 2);
+ } else {
+ exec(stack, code[codePtr].blk);
+ }
+ codePtr = code[codePtr + 1].blk;
+ break;
+ case psOpReturn:
+ return;
+ }
+ break;
+ default:
+ error(-1, "Internal: bad object in PostScript function code");
+ break;
+ }
+ }
+}
diff --git a/pdftops/Function.h b/pdftops/Function.h
new file mode 100644
index 000000000..76903488d
--- /dev/null
+++ b/pdftops/Function.h
@@ -0,0 +1,157 @@
+//========================================================================
+//
+// Function.h
+//
+// Copyright 2001 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef FUNCTION_H
+#define FUNCTION_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "gtypes.h"
+#include "Object.h"
+
+class Dict;
+class Stream;
+struct PSObject;
+class PSStack;
+
+//------------------------------------------------------------------------
+// Function
+//------------------------------------------------------------------------
+
+#define funcMaxInputs 8
+#define funcMaxOutputs 8
+
+class Function {
+public:
+
+ Function();
+
+ virtual ~Function();
+
+ // Construct a function. Returns NULL if unsuccessful.
+ static Function *parse(Object *funcObj);
+
+ // Initialize the entries common to all function types.
+ GBool init(Dict *dict);
+
+ virtual Function *copy() = 0;
+
+ // Return size of input and output tuples.
+ int getInputSize() { return m; }
+ int getOutputSize() { return n; }
+
+ // Transform an input tuple into an output tuple.
+ virtual void transform(double *in, double *out) = 0;
+
+ virtual GBool isOk() = 0;
+
+protected:
+
+ int m, n; // size of input and output tuples
+ double // min and max values for function domain
+ domain[funcMaxInputs][2];
+ double // min and max values for function range
+ range[funcMaxOutputs][2];
+ GBool hasRange; // set if range is defined
+};
+
+//------------------------------------------------------------------------
+// IdentityFunction
+//------------------------------------------------------------------------
+
+class IdentityFunction: public Function {
+public:
+
+ IdentityFunction();
+ virtual ~IdentityFunction();
+ virtual Function *copy() { return new IdentityFunction(); }
+ virtual void transform(double *in, double *out);
+ virtual GBool isOk() { return gTrue; }
+
+private:
+};
+
+//------------------------------------------------------------------------
+// SampledFunction
+//------------------------------------------------------------------------
+
+class SampledFunction: public Function {
+public:
+
+ SampledFunction(Object *funcObj, Dict *dict);
+ virtual ~SampledFunction();
+ virtual Function *copy() { return new SampledFunction(this); }
+ virtual void transform(double *in, double *out);
+ virtual GBool isOk() { return ok; }
+
+private:
+
+ SampledFunction(SampledFunction *func);
+
+ int // number of samples for each domain element
+ sampleSize[funcMaxInputs];
+ double // min and max values for domain encoder
+ encode[funcMaxInputs][2];
+ double // min and max values for range decoder
+ decode[funcMaxOutputs][2];
+ double *samples; // the samples
+ GBool ok;
+};
+
+//------------------------------------------------------------------------
+// ExponentialFunction
+//------------------------------------------------------------------------
+
+class ExponentialFunction: public Function {
+public:
+
+ ExponentialFunction(Object *funcObj, Dict *dict);
+ virtual ~ExponentialFunction();
+ virtual Function *copy() { return new ExponentialFunction(this); }
+ virtual void transform(double *in, double *out);
+ virtual GBool isOk() { return ok; }
+
+private:
+
+ ExponentialFunction(ExponentialFunction *func);
+
+ double c0[funcMaxOutputs];
+ double c1[funcMaxOutputs];
+ double e;
+ GBool ok;
+};
+
+//------------------------------------------------------------------------
+// PostScriptFunction
+//------------------------------------------------------------------------
+
+class PostScriptFunction: public Function {
+public:
+
+ PostScriptFunction(Object *funcObj, Dict *dict);
+ virtual ~PostScriptFunction();
+ virtual Function *copy() { return new PostScriptFunction(this); }
+ virtual void transform(double *in, double *out);
+ virtual GBool isOk() { return ok; }
+
+private:
+
+ PostScriptFunction(PostScriptFunction *func);
+ GBool parseCode(Stream *str, int *codePtr);
+ GString *getToken(Stream *str);
+ void resizeCode(int newSize);
+ void exec(PSStack *stack, int codePtr);
+
+ PSObject *code;
+ int codeSize;
+ GBool ok;
+};
+
+#endif
diff --git a/pdftops/GB12CMapInfo.h b/pdftops/GB12CMapInfo.h
new file mode 100644
index 000000000..880375737
--- /dev/null
+++ b/pdftops/GB12CMapInfo.h
@@ -0,0 +1,50880 @@
+//========================================================================
+//
+// GB12CMapInfo.h
+//
+// This file was automatically generated by makeCMapInfo.
+//
+// Copyright 1998 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef GB12CMAPINFO_H
+#define GB12CMAPINFO_H
+
+static Gushort gb12AdobeGB10Map2[66] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12AdobeGB10Enc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12AdobeGB10Map2, 33
+};
+
+static Gushort gb12AdobeGB11Map2[82] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0x2100, 0x2100,
+ 0x2200, 0x2200,
+ 0x2300, 0x2300,
+ 0x2400, 0x2400,
+ 0x2500, 0x2500,
+ 0x2600, 0x2600,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12AdobeGB11Enc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12AdobeGB11Map2, 41
+};
+
+static Gushort gb12AdobeGB12Map2[178] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0x2100, 0x2100,
+ 0x2200, 0x2200,
+ 0x2300, 0x2300,
+ 0x2400, 0x2400,
+ 0x2500, 0x2500,
+ 0x2600, 0x2600,
+ 0x2700, 0x2700,
+ 0x2800, 0x2800,
+ 0x2900, 0x2900,
+ 0x2a00, 0x2a00,
+ 0x2b00, 0x2b00,
+ 0x2c00, 0x2c00,
+ 0x2d00, 0x2d00,
+ 0x2e00, 0x2e00,
+ 0x2f00, 0x2f00,
+ 0x3000, 0x3000,
+ 0x3100, 0x3100,
+ 0x3200, 0x3200,
+ 0x3300, 0x3300,
+ 0x3400, 0x3400,
+ 0x3500, 0x3500,
+ 0x3600, 0x3600,
+ 0x3700, 0x3700,
+ 0x3800, 0x3800,
+ 0x3900, 0x3900,
+ 0x3a00, 0x3a00,
+ 0x3b00, 0x3b00,
+ 0x3c00, 0x3c00,
+ 0x3d00, 0x3d00,
+ 0x3e00, 0x3e00,
+ 0x3f00, 0x3f00,
+ 0x4000, 0x4000,
+ 0x4100, 0x4100,
+ 0x4200, 0x4200,
+ 0x4300, 0x4300,
+ 0x4400, 0x4400,
+ 0x4500, 0x4500,
+ 0x4600, 0x4600,
+ 0x4700, 0x4700,
+ 0x4800, 0x4800,
+ 0x4900, 0x4900,
+ 0x4a00, 0x4a00,
+ 0x4b00, 0x4b00,
+ 0x4c00, 0x4c00,
+ 0x4d00, 0x4d00,
+ 0x4e00, 0x4e00,
+ 0x4f00, 0x4f00,
+ 0x5000, 0x5000,
+ 0x5100, 0x5100,
+ 0x5200, 0x5200,
+ 0x5300, 0x5300,
+ 0x5400, 0x5400,
+ 0x5500, 0x5500,
+ 0x5600, 0x5600,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12AdobeGB12Enc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12AdobeGB12Map2, 89
+};
+
+static Gushort gb12GBEUCHMap2[180] = {
+ 0x0000, 0x0000,
+ 0xa1a1, 0x0060,
+ 0xa2b1, 0x00be,
+ 0xa2e5, 0x00f0,
+ 0xa2f1, 0x00fa,
+ 0xa3a1, 0x0106,
+ 0xa4a1, 0x0164,
+ 0xa5a1, 0x01b7,
+ 0xa6a1, 0x020d,
+ 0xa6c1, 0x0225,
+ 0xa7a1, 0x025a,
+ 0xa7d1, 0x027b,
+ 0xa8a1, 0x029c,
+ 0xa8c5, 0x02bc,
+ 0xa9a4, 0x02e2,
+ 0xaaa1, 0x032e,
+ 0xaba1, 0x038c,
+ 0xb0a1, 0x03ac,
+ 0xb1a1, 0x040a,
+ 0xb2a1, 0x0468,
+ 0xb3a1, 0x04c6,
+ 0xb4a1, 0x0524,
+ 0xb5a1, 0x0582,
+ 0xb6a1, 0x05e0,
+ 0xb7a1, 0x063e,
+ 0xb8a1, 0x069c,
+ 0xb9a1, 0x06fa,
+ 0xbaa1, 0x0758,
+ 0xbba1, 0x07b6,
+ 0xbca1, 0x0814,
+ 0xbda1, 0x0872,
+ 0xbea1, 0x08d0,
+ 0xbfa1, 0x092e,
+ 0xc0a1, 0x098c,
+ 0xc1a1, 0x09ea,
+ 0xc2a1, 0x0a48,
+ 0xc3a1, 0x0aa6,
+ 0xc4a1, 0x0b04,
+ 0xc5a1, 0x0b62,
+ 0xc6a1, 0x0bc0,
+ 0xc7a1, 0x0c1e,
+ 0xc8a1, 0x0c7c,
+ 0xc9a1, 0x0cda,
+ 0xcaa1, 0x0d38,
+ 0xcba1, 0x0d96,
+ 0xcca1, 0x0df4,
+ 0xcda1, 0x0e52,
+ 0xcea1, 0x0eb0,
+ 0xcfa1, 0x0f0e,
+ 0xd0a1, 0x0f6c,
+ 0xd1a1, 0x0fca,
+ 0xd2a1, 0x1028,
+ 0xd3a1, 0x1086,
+ 0xd4a1, 0x10e4,
+ 0xd5a1, 0x1142,
+ 0xd6a1, 0x11a0,
+ 0xd7a1, 0x11fe,
+ 0xd8a1, 0x1257,
+ 0xd9a1, 0x12b5,
+ 0xdaa1, 0x1313,
+ 0xdba1, 0x1371,
+ 0xdca1, 0x13cf,
+ 0xdda1, 0x142d,
+ 0xdea1, 0x148b,
+ 0xdfa1, 0x14e9,
+ 0xe0a1, 0x1547,
+ 0xe1a1, 0x15a5,
+ 0xe2a1, 0x1603,
+ 0xe3a1, 0x1661,
+ 0xe4a1, 0x16bf,
+ 0xe5a1, 0x171d,
+ 0xe6a1, 0x177b,
+ 0xe7a1, 0x17d9,
+ 0xe8a1, 0x1837,
+ 0xe9a1, 0x1895,
+ 0xeaa1, 0x18f3,
+ 0xeba1, 0x1951,
+ 0xeca1, 0x19af,
+ 0xeda1, 0x1a0d,
+ 0xeea1, 0x1a6b,
+ 0xefa1, 0x1ac9,
+ 0xf0a1, 0x1b27,
+ 0xf1a1, 0x1b85,
+ 0xf2a1, 0x1be3,
+ 0xf3a1, 0x1c41,
+ 0xf4a1, 0x1c9f,
+ 0xf5a1, 0x1cfd,
+ 0xf6a1, 0x1d5b,
+ 0xf7a1, 0x1db9,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBEUCHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1e24, 0x032e, 0x032f, 0x0330, 0x0331, 0x0332, 0x0333, 0x0334,
+ 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x033a, 0x033b, 0x033c,
+ 0x033d, 0x033e, 0x033f, 0x0340, 0x0341, 0x0342, 0x0343, 0x0344,
+ 0x0345, 0x0346, 0x0347, 0x0348, 0x0349, 0x034a, 0x034b, 0x034c,
+ 0x034d, 0x034e, 0x034f, 0x0350, 0x0351, 0x0352, 0x0353, 0x0354,
+ 0x0355, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035c,
+ 0x035d, 0x035e, 0x035f, 0x0360, 0x0361, 0x0362, 0x0363, 0x0364,
+ 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c,
+ 0x036d, 0x036e, 0x036f, 0x0370, 0x0371, 0x0372, 0x0373, 0x0374,
+ 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x037a, 0x037b, 0x037c,
+ 0x037d, 0x037e, 0x037f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384,
+ 0x0385, 0x0386, 0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12GBEUCHMap2, 90
+};
+
+static Gushort gb12GBEUCVMap2[220] = {
+ 0x0000, 0x0000,
+ 0xa1a1, 0x0060,
+ 0xa2b1, 0x00be,
+ 0xa2e5, 0x00f0,
+ 0xa2f1, 0x00fa,
+ 0xa3a1, 0x0106,
+ 0xa4a1, 0x0164,
+ 0xa5a1, 0x01b7,
+ 0xa6a1, 0x020d,
+ 0xa6c1, 0x0225,
+ 0xa7a1, 0x025a,
+ 0xa7d1, 0x027b,
+ 0xa8a1, 0x029c,
+ 0xa8c5, 0x02bc,
+ 0xa9a4, 0x02e2,
+ 0xaaa1, 0x032e,
+ 0xaba1, 0x038c,
+ 0xb0a1, 0x03ac,
+ 0xb1a1, 0x040a,
+ 0xb2a1, 0x0468,
+ 0xb3a1, 0x04c6,
+ 0xb4a1, 0x0524,
+ 0xb5a1, 0x0582,
+ 0xb6a1, 0x05e0,
+ 0xb7a1, 0x063e,
+ 0xb8a1, 0x069c,
+ 0xb9a1, 0x06fa,
+ 0xbaa1, 0x0758,
+ 0xbba1, 0x07b6,
+ 0xbca1, 0x0814,
+ 0xbda1, 0x0872,
+ 0xbea1, 0x08d0,
+ 0xbfa1, 0x092e,
+ 0xc0a1, 0x098c,
+ 0xc1a1, 0x09ea,
+ 0xc2a1, 0x0a48,
+ 0xc3a1, 0x0aa6,
+ 0xc4a1, 0x0b04,
+ 0xc5a1, 0x0b62,
+ 0xc6a1, 0x0bc0,
+ 0xc7a1, 0x0c1e,
+ 0xc8a1, 0x0c7c,
+ 0xc9a1, 0x0cda,
+ 0xcaa1, 0x0d38,
+ 0xcba1, 0x0d96,
+ 0xcca1, 0x0df4,
+ 0xcda1, 0x0e52,
+ 0xcea1, 0x0eb0,
+ 0xcfa1, 0x0f0e,
+ 0xd0a1, 0x0f6c,
+ 0xd1a1, 0x0fca,
+ 0xd2a1, 0x1028,
+ 0xd3a1, 0x1086,
+ 0xd4a1, 0x10e4,
+ 0xd5a1, 0x1142,
+ 0xd6a1, 0x11a0,
+ 0xd7a1, 0x11fe,
+ 0xd8a1, 0x1257,
+ 0xd9a1, 0x12b5,
+ 0xdaa1, 0x1313,
+ 0xdba1, 0x1371,
+ 0xdca1, 0x13cf,
+ 0xdda1, 0x142d,
+ 0xdea1, 0x148b,
+ 0xdfa1, 0x14e9,
+ 0xe0a1, 0x1547,
+ 0xe1a1, 0x15a5,
+ 0xe2a1, 0x1603,
+ 0xe3a1, 0x1661,
+ 0xe4a1, 0x16bf,
+ 0xe5a1, 0x171d,
+ 0xe6a1, 0x177b,
+ 0xe7a1, 0x17d9,
+ 0xe8a1, 0x1837,
+ 0xe9a1, 0x1895,
+ 0xeaa1, 0x18f3,
+ 0xeba1, 0x1951,
+ 0xeca1, 0x19af,
+ 0xeda1, 0x1a0d,
+ 0xeea1, 0x1a6b,
+ 0xefa1, 0x1ac9,
+ 0xf0a1, 0x1b27,
+ 0xf1a1, 0x1b85,
+ 0xf2a1, 0x1be3,
+ 0xf3a1, 0x1c41,
+ 0xf4a1, 0x1c9f,
+ 0xf5a1, 0x1cfd,
+ 0xf6a1, 0x1d5b,
+ 0xf7a1, 0x1db9,
+ 0xa1a2, 0x023f,
+ 0xa1a3, 0x023e,
+ 0xa1aa, 0x0256,
+ 0xa1ab, 0x1e18,
+ 0xa1ad, 0x0257,
+ 0xa1b2, 0x0246,
+ 0xa1fe, 0x1e1a,
+ 0xa3a1, 0x0242,
+ 0xa3a8, 0x0244,
+ 0xa3ac, 0x023d,
+ 0xa3ae, 0x1e1b,
+ 0xa3ba, 0x0240,
+ 0xa3bd, 0x1e1c,
+ 0xa3bf, 0x0243,
+ 0xa3db, 0x1e1d,
+ 0xa3dd, 0x1e1e,
+ 0xa3df, 0x0258,
+ 0xa3fb, 0x0254,
+ 0xa3fd, 0x0255,
+ 0xa3fe, 0x1e1f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBEUCVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1e24, 0x032e, 0x032f, 0x0330, 0x0331, 0x0332, 0x0333, 0x0334,
+ 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x033a, 0x033b, 0x033c,
+ 0x033d, 0x033e, 0x033f, 0x0340, 0x0341, 0x0342, 0x0343, 0x0344,
+ 0x0345, 0x0346, 0x0347, 0x0348, 0x0349, 0x034a, 0x034b, 0x034c,
+ 0x034d, 0x034e, 0x034f, 0x0350, 0x0351, 0x0352, 0x0353, 0x0354,
+ 0x0355, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035c,
+ 0x035d, 0x035e, 0x035f, 0x0360, 0x0361, 0x0362, 0x0363, 0x0364,
+ 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c,
+ 0x036d, 0x036e, 0x036f, 0x0370, 0x0371, 0x0372, 0x0373, 0x0374,
+ 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x037a, 0x037b, 0x037c,
+ 0x037d, 0x037e, 0x037f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384,
+ 0x0385, 0x0386, 0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12GBEUCVMap2, 110
+};
+
+static Gushort gb12GBHMap2[180] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0060,
+ 0x2231, 0x00be,
+ 0x2265, 0x00f0,
+ 0x2271, 0x00fa,
+ 0x2321, 0x0106,
+ 0x2421, 0x0164,
+ 0x2521, 0x01b7,
+ 0x2621, 0x020d,
+ 0x2641, 0x0225,
+ 0x2721, 0x025a,
+ 0x2751, 0x027b,
+ 0x2821, 0x029c,
+ 0x2845, 0x02bc,
+ 0x2924, 0x02e2,
+ 0x2a21, 0x032e,
+ 0x2b21, 0x038c,
+ 0x3021, 0x03ac,
+ 0x3121, 0x040a,
+ 0x3221, 0x0468,
+ 0x3321, 0x04c6,
+ 0x3421, 0x0524,
+ 0x3521, 0x0582,
+ 0x3621, 0x05e0,
+ 0x3721, 0x063e,
+ 0x3821, 0x069c,
+ 0x3921, 0x06fa,
+ 0x3a21, 0x0758,
+ 0x3b21, 0x07b6,
+ 0x3c21, 0x0814,
+ 0x3d21, 0x0872,
+ 0x3e21, 0x08d0,
+ 0x3f21, 0x092e,
+ 0x4021, 0x098c,
+ 0x4121, 0x09ea,
+ 0x4221, 0x0a48,
+ 0x4321, 0x0aa6,
+ 0x4421, 0x0b04,
+ 0x4521, 0x0b62,
+ 0x4621, 0x0bc0,
+ 0x4721, 0x0c1e,
+ 0x4821, 0x0c7c,
+ 0x4921, 0x0cda,
+ 0x4a21, 0x0d38,
+ 0x4b21, 0x0d96,
+ 0x4c21, 0x0df4,
+ 0x4d21, 0x0e52,
+ 0x4e21, 0x0eb0,
+ 0x4f21, 0x0f0e,
+ 0x5021, 0x0f6c,
+ 0x5121, 0x0fca,
+ 0x5221, 0x1028,
+ 0x5321, 0x1086,
+ 0x5421, 0x10e4,
+ 0x5521, 0x1142,
+ 0x5621, 0x11a0,
+ 0x5721, 0x11fe,
+ 0x5821, 0x1257,
+ 0x5921, 0x12b5,
+ 0x5a21, 0x1313,
+ 0x5b21, 0x1371,
+ 0x5c21, 0x13cf,
+ 0x5d21, 0x142d,
+ 0x5e21, 0x148b,
+ 0x5f21, 0x14e9,
+ 0x6021, 0x1547,
+ 0x6121, 0x15a5,
+ 0x6221, 0x1603,
+ 0x6321, 0x1661,
+ 0x6421, 0x16bf,
+ 0x6521, 0x171d,
+ 0x6621, 0x177b,
+ 0x6721, 0x17d9,
+ 0x6821, 0x1837,
+ 0x6921, 0x1895,
+ 0x6a21, 0x18f3,
+ 0x6b21, 0x1951,
+ 0x6c21, 0x19af,
+ 0x6d21, 0x1a0d,
+ 0x6e21, 0x1a6b,
+ 0x6f21, 0x1ac9,
+ 0x7021, 0x1b27,
+ 0x7121, 0x1b85,
+ 0x7221, 0x1be3,
+ 0x7321, 0x1c41,
+ 0x7421, 0x1c9f,
+ 0x7521, 0x1cfd,
+ 0x7621, 0x1d5b,
+ 0x7721, 0x1db9,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12GBHMap2, 90
+};
+
+static Gushort gb12GBVMap2[220] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0060,
+ 0x2231, 0x00be,
+ 0x2265, 0x00f0,
+ 0x2271, 0x00fa,
+ 0x2321, 0x0106,
+ 0x2421, 0x0164,
+ 0x2521, 0x01b7,
+ 0x2621, 0x020d,
+ 0x2641, 0x0225,
+ 0x2721, 0x025a,
+ 0x2751, 0x027b,
+ 0x2821, 0x029c,
+ 0x2845, 0x02bc,
+ 0x2924, 0x02e2,
+ 0x2a21, 0x032e,
+ 0x2b21, 0x038c,
+ 0x3021, 0x03ac,
+ 0x3121, 0x040a,
+ 0x3221, 0x0468,
+ 0x3321, 0x04c6,
+ 0x3421, 0x0524,
+ 0x3521, 0x0582,
+ 0x3621, 0x05e0,
+ 0x3721, 0x063e,
+ 0x3821, 0x069c,
+ 0x3921, 0x06fa,
+ 0x3a21, 0x0758,
+ 0x3b21, 0x07b6,
+ 0x3c21, 0x0814,
+ 0x3d21, 0x0872,
+ 0x3e21, 0x08d0,
+ 0x3f21, 0x092e,
+ 0x4021, 0x098c,
+ 0x4121, 0x09ea,
+ 0x4221, 0x0a48,
+ 0x4321, 0x0aa6,
+ 0x4421, 0x0b04,
+ 0x4521, 0x0b62,
+ 0x4621, 0x0bc0,
+ 0x4721, 0x0c1e,
+ 0x4821, 0x0c7c,
+ 0x4921, 0x0cda,
+ 0x4a21, 0x0d38,
+ 0x4b21, 0x0d96,
+ 0x4c21, 0x0df4,
+ 0x4d21, 0x0e52,
+ 0x4e21, 0x0eb0,
+ 0x4f21, 0x0f0e,
+ 0x5021, 0x0f6c,
+ 0x5121, 0x0fca,
+ 0x5221, 0x1028,
+ 0x5321, 0x1086,
+ 0x5421, 0x10e4,
+ 0x5521, 0x1142,
+ 0x5621, 0x11a0,
+ 0x5721, 0x11fe,
+ 0x5821, 0x1257,
+ 0x5921, 0x12b5,
+ 0x5a21, 0x1313,
+ 0x5b21, 0x1371,
+ 0x5c21, 0x13cf,
+ 0x5d21, 0x142d,
+ 0x5e21, 0x148b,
+ 0x5f21, 0x14e9,
+ 0x6021, 0x1547,
+ 0x6121, 0x15a5,
+ 0x6221, 0x1603,
+ 0x6321, 0x1661,
+ 0x6421, 0x16bf,
+ 0x6521, 0x171d,
+ 0x6621, 0x177b,
+ 0x6721, 0x17d9,
+ 0x6821, 0x1837,
+ 0x6921, 0x1895,
+ 0x6a21, 0x18f3,
+ 0x6b21, 0x1951,
+ 0x6c21, 0x19af,
+ 0x6d21, 0x1a0d,
+ 0x6e21, 0x1a6b,
+ 0x6f21, 0x1ac9,
+ 0x7021, 0x1b27,
+ 0x7121, 0x1b85,
+ 0x7221, 0x1be3,
+ 0x7321, 0x1c41,
+ 0x7421, 0x1c9f,
+ 0x7521, 0x1cfd,
+ 0x7621, 0x1d5b,
+ 0x7721, 0x1db9,
+ 0x2122, 0x023f,
+ 0x2123, 0x023e,
+ 0x212a, 0x0256,
+ 0x212b, 0x1e18,
+ 0x212d, 0x0257,
+ 0x2132, 0x0246,
+ 0x217e, 0x1e1a,
+ 0x2321, 0x0242,
+ 0x2328, 0x0244,
+ 0x232c, 0x023d,
+ 0x232e, 0x1e1b,
+ 0x233a, 0x0240,
+ 0x233d, 0x1e1c,
+ 0x233f, 0x0243,
+ 0x235b, 0x1e1d,
+ 0x235d, 0x1e1e,
+ 0x235f, 0x0258,
+ 0x237b, 0x0254,
+ 0x237d, 0x0255,
+ 0x237e, 0x1e1f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12GBVMap2, 110
+};
+
+static Gushort gb12GBKEUCHMap2[8142] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x2758,
+ 0x8179, 0x2059,
+ 0x817a, 0x2791,
+ 0x8180, 0x2796,
+ 0x8186, 0x21f1,
+ 0x8187, 0x279c,
+ 0x81ed, 0x1ff2,
+ 0x81ee, 0x2802,
+ 0x81f6, 0x205d,
+ 0x81f7, 0x280a,
+ 0x8240, 0x2812,
+ 0x8253, 0x269c,
+ 0x8254, 0x2825,
+ 0x8262, 0x21b5,
+ 0x8263, 0x2833,
+ 0x8274, 0x22cc,
+ 0x8275, 0x2844,
+ 0x827a, 0x2016,
+ 0x827b, 0x2849,
+ 0x827d, 0x1e62,
+ 0x827e, 0x284b,
+ 0x8280, 0x1f20,
+ 0x8281, 0x284c,
+ 0x8283, 0x207f,
+ 0x8284, 0x284e,
+ 0x8290, 0x205c,
+ 0x8291, 0x285a,
+ 0x82a5, 0x2194,
+ 0x82a6, 0x286e,
+ 0x82c8, 0x1e65,
+ 0x82c9, 0x2281,
+ 0x82ca, 0x2890,
+ 0x82e1, 0x22cd,
+ 0x82e2, 0x28a7,
+ 0x82e3, 0x210a,
+ 0x82e4, 0x1e3e,
+ 0x82e5, 0x28a8,
+ 0x82ed, 0x267f,
+ 0x82ee, 0x28b0,
+ 0x82f2, 0x222e,
+ 0x82f3, 0x28b4,
+ 0x82f7, 0x1e96,
+ 0x82f8, 0x22cb,
+ 0x82f9, 0x226c,
+ 0x82fa, 0x28b8,
+ 0x82fb, 0x2117,
+ 0x82fc, 0x28b9,
+ 0x8340, 0x28bc,
+ 0x8341, 0x20e8,
+ 0x8342, 0x28bd,
+ 0x8345, 0x22d4,
+ 0x8346, 0x28c0,
+ 0x8348, 0x1fb9,
+ 0x8349, 0x28c2,
+ 0x834c, 0x22d8,
+ 0x834d, 0x28c5,
+ 0x8353, 0x20df,
+ 0x8354, 0x28cb,
+ 0x8357, 0x20c2,
+ 0x8358, 0x28ce,
+ 0x835e, 0x2195,
+ 0x835f, 0x28d4,
+ 0x8365, 0x1fac,
+ 0x8366, 0x22d3,
+ 0x8367, 0x28da,
+ 0x8372, 0x1f81,
+ 0x8373, 0x28e5,
+ 0x8378, 0x2210,
+ 0x8379, 0x28ea,
+ 0x837a, 0x22cf,
+ 0x837b, 0x28eb,
+ 0x837c, 0x2213,
+ 0x837d, 0x28ec,
+ 0x837e, 0x1fe4,
+ 0x8380, 0x1f90,
+ 0x8381, 0x28ed,
+ 0x8386, 0x22d6,
+ 0x8387, 0x28f2,
+ 0x8389, 0x22d0,
+ 0x838a, 0x22ce,
+ 0x838b, 0x28f4,
+ 0x838d, 0x2681,
+ 0x838e, 0x28f6,
+ 0x8394, 0x1e76,
+ 0x8395, 0x28fc,
+ 0x839e, 0x2231,
+ 0x839f, 0x2905,
+ 0x83a6, 0x1e93,
+ 0x83a7, 0x290c,
+ 0x83ab, 0x22d2,
+ 0x83ac, 0x2910,
+ 0x83ae, 0x22d7,
+ 0x83af, 0x22d5,
+ 0x83b0, 0x22d1,
+ 0x83b1, 0x2912,
+ 0x83ba, 0x1ee5,
+ 0x83bb, 0x291b,
+ 0x83c9, 0x2025,
+ 0x83ca, 0x2929,
+ 0x83f6, 0x1ecf,
+ 0x83f7, 0x2955,
+ 0x8440, 0x295d,
+ 0x8450, 0x1fd9,
+ 0x8451, 0x296d,
+ 0x8471, 0x22c8,
+ 0x8472, 0x298d,
+ 0x8474, 0x2263,
+ 0x8475, 0x298f,
+ 0x8477, 0x2683,
+ 0x8478, 0x2991,
+ 0x8480, 0x2998,
+ 0x8482, 0x1f17,
+ 0x8483, 0x299a,
+ 0x848e, 0x1f2b,
+ 0x848f, 0x29a5,
+ 0x8492, 0x22ca,
+ 0x8493, 0x1e99,
+ 0x8494, 0x29a8,
+ 0x849d, 0x1f4f,
+ 0x849e, 0x29b1,
+ 0x84a1, 0x1fcf,
+ 0x84a2, 0x2036,
+ 0x84a3, 0x1f3a,
+ 0x84a4, 0x29b4,
+ 0x84a5, 0x22c9,
+ 0x84a6, 0x1f99,
+ 0x84a7, 0x29b5,
+ 0x84a9, 0x1f75,
+ 0x84aa, 0x29b7,
+ 0x84c5, 0x1fbe,
+ 0x84c6, 0x29d2,
+ 0x84d3, 0x1ecd,
+ 0x84d4, 0x29df,
+ 0x84d5, 0x21a9,
+ 0x84d6, 0x29e0,
+ 0x84d7, 0x21e6,
+ 0x84d8, 0x29e1,
+ 0x84d9, 0x2127,
+ 0x84da, 0x2003,
+ 0x84db, 0x29e2,
+ 0x84dd, 0x2132,
+ 0x84de, 0x29e4,
+ 0x84ea, 0x2323,
+ 0x84eb, 0x29f0,
+ 0x84ee, 0x2011,
+ 0x84ef, 0x29f3,
+ 0x84f1, 0x20f5,
+ 0x84f2, 0x29f5,
+ 0x8540, 0x2a02,
+ 0x8551, 0x22c5,
+ 0x8552, 0x1f5e,
+ 0x8553, 0x2a13,
+ 0x8554, 0x22c6,
+ 0x8555, 0x2a14,
+ 0x855e, 0x20ef,
+ 0x855f, 0x2a1d,
+ 0x8566, 0x21d0,
+ 0x8567, 0x2a24,
+ 0x8580, 0x2a3c,
+ 0x8587, 0x22c1,
+ 0x8588, 0x2a43,
+ 0x858b, 0x1e64,
+ 0x858c, 0x2a46,
+ 0x8592, 0x21f9,
+ 0x8593, 0x2a4c,
+ 0x8596, 0x2010,
+ 0x8597, 0x2a4f,
+ 0x8598, 0x22c2,
+ 0x8599, 0x2a50,
+ 0x85a2, 0x1e5a,
+ 0x85a3, 0x2a59,
+ 0x85b2, 0x1ea2,
+ 0x85b3, 0x2a68,
+ 0x8640, 0x2ab4,
+ 0x864a, 0x236d,
+ 0x864b, 0x2abe,
+ 0x8654, 0x2247,
+ 0x8655, 0x2ac7,
+ 0x8668, 0x236c,
+ 0x8669, 0x2ada,
+ 0x8680, 0x2af0,
+ 0x8696, 0x219c,
+ 0x8697, 0x2b06,
+ 0x8699, 0x20c9,
+ 0x869a, 0x2b08,
+ 0x86a1, 0x21f0,
+ 0x86a2, 0x2b0f,
+ 0x86ca, 0x210b,
+ 0x86cb, 0x2b37,
+ 0x86cc, 0x20de,
+ 0x86cd, 0x2b38,
+ 0x86ce, 0x1eaa,
+ 0x86cf, 0x2b39,
+ 0x86d1, 0x222c,
+ 0x86d2, 0x2b3b,
+ 0x86dc, 0x20d8,
+ 0x86dd, 0x22c0,
+ 0x86de, 0x2b45,
+ 0x86e1, 0x206f,
+ 0x86e2, 0x2b48,
+ 0x86e8, 0x21a1,
+ 0x86e9, 0x2b4e,
+ 0x86ee, 0x2379,
+ 0x86ef, 0x2b53,
+ 0x86f4, 0x2372,
+ 0x86f5, 0x2b58,
+ 0x8740, 0x216a,
+ 0x8741, 0x2b62,
+ 0x8744, 0x237c,
+ 0x8745, 0x2b65,
+ 0x8749, 0x20b0,
+ 0x874a, 0x2b69,
+ 0x874b, 0x237a,
+ 0x874c, 0x1e74,
+ 0x874d, 0x2b6a,
+ 0x874f, 0x2377,
+ 0x8750, 0x2b6c,
+ 0x8757, 0x1f4c,
+ 0x8758, 0x2b73,
+ 0x875a, 0x2378,
+ 0x875b, 0x21cf,
+ 0x875c, 0x2368,
+ 0x875d, 0x2b75,
+ 0x875e, 0x2371,
+ 0x875f, 0x2b76,
+ 0x8760, 0x2369,
+ 0x8761, 0x2b77,
+ 0x8766, 0x2674,
+ 0x8767, 0x2b7c,
+ 0x877a, 0x236f,
+ 0x877b, 0x2b8f,
+ 0x877d, 0x2370,
+ 0x877e, 0x2b91,
+ 0x8780, 0x2b92,
+ 0x8781, 0x2376,
+ 0x8782, 0x2373,
+ 0x8783, 0x2b93,
+ 0x8786, 0x237f,
+ 0x8787, 0x2b96,
+ 0x8788, 0x2374,
+ 0x8789, 0x2b97,
+ 0x878a, 0x20b5,
+ 0x878b, 0x2b98,
+ 0x878d, 0x1edb,
+ 0x878e, 0x2672,
+ 0x878f, 0x2b9a,
+ 0x8793, 0x236e,
+ 0x8794, 0x2b9e,
+ 0x8798, 0x21b7,
+ 0x8799, 0x2ba2,
+ 0x879d, 0x2375,
+ 0x879e, 0x2ba6,
+ 0x87a3, 0x2382,
+ 0x87a4, 0x2bab,
+ 0x87a7, 0x209e,
+ 0x87a8, 0x2bae,
+ 0x87b3, 0x236b,
+ 0x87b4, 0x2bb9,
+ 0x87b5, 0x2039,
+ 0x87b6, 0x2bba,
+ 0x87bb, 0x269f,
+ 0x87bc, 0x2bbf,
+ 0x87bf, 0x237d,
+ 0x87c0, 0x21f5,
+ 0x87c1, 0x2bc2,
+ 0x87c2, 0x2381,
+ 0x87c3, 0x2bc3,
+ 0x87ca, 0x237b,
+ 0x87cb, 0x237e,
+ 0x87cc, 0x21cc,
+ 0x87cd, 0x2bca,
+ 0x87cf, 0x22db,
+ 0x87d0, 0x2bcc,
+ 0x87d2, 0x236a,
+ 0x87d3, 0x2689,
+ 0x87d4, 0x2bce,
+ 0x87d5, 0x2697,
+ 0x87d6, 0x2bcf,
+ 0x87da, 0x22a1,
+ 0x87db, 0x2bd3,
+ 0x87f7, 0x2383,
+ 0x87f8, 0x1f3d,
+ 0x87f9, 0x2bef,
+ 0x87fa, 0x218f,
+ 0x87fb, 0x2bf0,
+ 0x8840, 0x2246,
+ 0x8841, 0x2248,
+ 0x8842, 0x2bf4,
+ 0x8844, 0x217e,
+ 0x8845, 0x2bf6,
+ 0x8846, 0x2180,
+ 0x8847, 0x2bf7,
+ 0x8880, 0x2c2f,
+ 0x88ba, 0x232a,
+ 0x88bb, 0x2c69,
+ 0x88cc, 0x228b,
+ 0x88cd, 0x2c7a,
+ 0x88d4, 0x1f85,
+ 0x88d5, 0x2c81,
+ 0x88d7, 0x2325,
+ 0x88d8, 0x2c83,
+ 0x88df, 0x232c,
+ 0x88e0, 0x2c8a,
+ 0x88e5, 0x232e,
+ 0x88e6, 0x2c8f,
+ 0x88f2, 0x2205,
+ 0x88f3, 0x1e38,
+ 0x88f4, 0x2c9b,
+ 0x88f6, 0x1e73,
+ 0x88f7, 0x2c9d,
+ 0x8940, 0x2ca5,
+ 0x894b, 0x1fe3,
+ 0x894c, 0x2339,
+ 0x894d, 0x2cb0,
+ 0x894e, 0x232b,
+ 0x894f, 0x2cb1,
+ 0x8950, 0x232d,
+ 0x8951, 0x2cb2,
+ 0x8954, 0x217f,
+ 0x8955, 0x2cb5,
+ 0x895d, 0x21a7,
+ 0x895e, 0x2cbd,
+ 0x895f, 0x232f,
+ 0x8960, 0x2cbe,
+ 0x896d, 0x1e7d,
+ 0x896e, 0x2ccb,
+ 0x8971, 0x20d6,
+ 0x8972, 0x2cce,
+ 0x897c, 0x1ec2,
+ 0x897d, 0x2cd8,
+ 0x8980, 0x2cda,
+ 0x898b, 0x22b2,
+ 0x898c, 0x2ce5,
+ 0x8999, 0x1edf,
+ 0x899a, 0x2cf2,
+ 0x899e, 0x1ef9,
+ 0x899f, 0x2cf6,
+ 0x89a6, 0x20d9,
+ 0x89a7, 0x2cfd,
+ 0x89a8, 0x1fdd,
+ 0x89a9, 0x2cfe,
+ 0x89af, 0x2167,
+ 0x89b0, 0x2d04,
+ 0x89ba, 0x21ed,
+ 0x89bb, 0x2d0e,
+ 0x89be, 0x2007,
+ 0x89bf, 0x2326,
+ 0x89c0, 0x2329,
+ 0x89c1, 0x2d11,
+ 0x89c4, 0x1f52,
+ 0x89c5, 0x203b,
+ 0x89c6, 0x2328,
+ 0x89c7, 0x2d14,
+ 0x89c8, 0x2327,
+ 0x89c9, 0x2d15,
+ 0x89ce, 0x1e2b,
+ 0x89cf, 0x2d1a,
+ 0x89d1, 0x22ae,
+ 0x89d2, 0x2d1c,
+ 0x89d8, 0x1f49,
+ 0x89d9, 0x2d22,
+ 0x89db, 0x2138,
+ 0x89dc, 0x2d24,
+ 0x89f4, 0x2081,
+ 0x89f5, 0x2d3c,
+ 0x8a40, 0x2d46,
+ 0x8a41, 0x1f7c,
+ 0x8a42, 0x2d47,
+ 0x8a59, 0x235b,
+ 0x8a5a, 0x1ede,
+ 0x8a5b, 0x2d5e,
+ 0x8a5c, 0x1fa2,
+ 0x8a5d, 0x2d5f,
+ 0x8a5e, 0x1efa,
+ 0x8a5f, 0x2d60,
+ 0x8a79, 0x22ad,
+ 0x8a7a, 0x2d7a,
+ 0x8a80, 0x2d7f,
+ 0x8ae4, 0x203f,
+ 0x8ae5, 0x2de3,
+ 0x8b40, 0x2dfd,
+ 0x8b44, 0x1f0e,
+ 0x8b45, 0x2e01,
+ 0x8b49, 0x23f9,
+ 0x8b4a, 0x2e05,
+ 0x8b7a, 0x23fc,
+ 0x8b7b, 0x2e35,
+ 0x8b80, 0x2e39,
+ 0x8b8c, 0x2069,
+ 0x8b8d, 0x2e45,
+ 0x8b9e, 0x23f7,
+ 0x8b9f, 0x2e56,
+ 0x8bb3, 0x23f6,
+ 0x8bb4, 0x2e6a,
+ 0x8bb9, 0x23fd,
+ 0x8bba, 0x2e6f,
+ 0x8bbe, 0x23f8,
+ 0x8bbf, 0x2e73,
+ 0x8bc6, 0x23fa,
+ 0x8bc7, 0x2e7a,
+ 0x8bc8, 0x23fe,
+ 0x8bc9, 0x1fa8,
+ 0x8bca, 0x2e7b,
+ 0x8bd4, 0x2401,
+ 0x8bd5, 0x2e85,
+ 0x8bdc, 0x23ff,
+ 0x8bdd, 0x2e8c,
+ 0x8be5, 0x2400,
+ 0x8be6, 0x2e94,
+ 0x8beb, 0x2221,
+ 0x8bec, 0x2e99,
+ 0x8bf0, 0x2122,
+ 0x8bf1, 0x2e9d,
+ 0x8c40, 0x2eab,
+ 0x8c44, 0x23fb,
+ 0x8c45, 0x2eaf,
+ 0x8c4f, 0x215a,
+ 0x8c50, 0x2eb9,
+ 0x8c57, 0x21e5,
+ 0x8c58, 0x2ec0,
+ 0x8c5c, 0x2057,
+ 0x8c5d, 0x2ec4,
+ 0x8c80, 0x2ee6,
+ 0x8c8b, 0x20e5,
+ 0x8c8c, 0x2ef1,
+ 0x8c8d, 0x212f,
+ 0x8c8e, 0x20a3,
+ 0x8c8f, 0x2121,
+ 0x8c90, 0x2ef2,
+ 0x8c91, 0x21d4,
+ 0x8c92, 0x1fe5,
+ 0x8c93, 0x2ef3,
+ 0x8c99, 0x1e8a,
+ 0x8c9a, 0x1e37,
+ 0x8c9b, 0x2ef9,
+ 0x8ca2, 0x1f9e,
+ 0x8ca3, 0x22a6,
+ 0x8ca4, 0x21e8,
+ 0x8ca5, 0x2f00,
+ 0x8ca6, 0x1eda,
+ 0x8ca7, 0x1eb9,
+ 0x8ca8, 0x2f01,
+ 0x8cc0, 0x235c,
+ 0x8cc1, 0x2f19,
+ 0x8cd2, 0x2050,
+ 0x8cd3, 0x1e67,
+ 0x8cd4, 0x2f2a,
+ 0x8cd5, 0x23f4,
+ 0x8cd6, 0x2f2b,
+ 0x8cd9, 0x213e,
+ 0x8cda, 0x2f2e,
+ 0x8cf9, 0x1f16,
+ 0x8cfa, 0x2f4d,
+ 0x8d40, 0x2f52,
+ 0x8d73, 0x2389,
+ 0x8d74, 0x2f85,
+ 0x8d75, 0x1eb7,
+ 0x8d76, 0x2f86,
+ 0x8d7b, 0x21b4,
+ 0x8d7c, 0x2f8b,
+ 0x8d80, 0x2f8e,
+ 0x8d88, 0x238f,
+ 0x8d89, 0x2f96,
+ 0x8d8f, 0x1f1a,
+ 0x8d90, 0x2f9c,
+ 0x8d9e, 0x238b,
+ 0x8d9f, 0x2faa,
+ 0x8db9, 0x238a,
+ 0x8dba, 0x2fc4,
+ 0x8de2, 0x2391,
+ 0x8de3, 0x2fec,
+ 0x8de4, 0x2271,
+ 0x8de5, 0x2fed,
+ 0x8de7, 0x2388,
+ 0x8de8, 0x2fef,
+ 0x8df7, 0x238e,
+ 0x8df8, 0x2ffe,
+ 0x8dfe, 0x238d,
+ 0x8e40, 0x3004,
+ 0x8e46, 0x238c,
+ 0x8e47, 0x300a,
+ 0x8e56, 0x2390,
+ 0x8e57, 0x3019,
+ 0x8e58, 0x2033,
+ 0x8e59, 0x301a,
+ 0x8e5a, 0x223c,
+ 0x8e5b, 0x301b,
+ 0x8e68, 0x1fe9,
+ 0x8e69, 0x3028,
+ 0x8e6e, 0x2055,
+ 0x8e6f, 0x302d,
+ 0x8e70, 0x2392,
+ 0x8e71, 0x302e,
+ 0x8e80, 0x2324,
+ 0x8e81, 0x303c,
+ 0x8e9b, 0x2143,
+ 0x8e9c, 0x3056,
+ 0x8e9f, 0x2129,
+ 0x8ea0, 0x3059,
+ 0x8ea4, 0x2277,
+ 0x8ea5, 0x305d,
+ 0x8ea7, 0x1ea7,
+ 0x8ea8, 0x305f,
+ 0x8eac, 0x2285,
+ 0x8ead, 0x3063,
+ 0x8eae, 0x2384,
+ 0x8eaf, 0x3064,
+ 0x8ebd, 0x2387,
+ 0x8ebe, 0x2386,
+ 0x8ebf, 0x3072,
+ 0x8ec3, 0x2290,
+ 0x8ec4, 0x3076,
+ 0x8ec5, 0x1e44,
+ 0x8ec6, 0x3077,
+ 0x8ecd, 0x1e32,
+ 0x8ece, 0x2385,
+ 0x8ecf, 0x307e,
+ 0x8ed6, 0x1f13,
+ 0x8ed7, 0x1f73,
+ 0x8ed8, 0x3085,
+ 0x8eec, 0x1fe0,
+ 0x8eed, 0x3099,
+ 0x8f40, 0x30ab,
+ 0x8f52, 0x2087,
+ 0x8f53, 0x1e78,
+ 0x8f54, 0x23ae,
+ 0x8f55, 0x1ef6,
+ 0x8f56, 0x1f31,
+ 0x8f57, 0x30bd,
+ 0x8f5d, 0x2045,
+ 0x8f5e, 0x30c3,
+ 0x8f64, 0x2178,
+ 0x8f65, 0x30c9,
+ 0x8f80, 0x30e3,
+ 0x8f86, 0x23f5,
+ 0x8f87, 0x30e9,
+ 0x8f88, 0x2275,
+ 0x8f89, 0x30ea,
+ 0x8f95, 0x266e,
+ 0x8f96, 0x30f6,
+ 0x8f97, 0x1eb0,
+ 0x8f98, 0x30f7,
+ 0x8f9b, 0x2083,
+ 0x8f9c, 0x30fa,
+ 0x8f9d, 0x2188,
+ 0x8f9e, 0x30fb,
+ 0x8fa1, 0x267c,
+ 0x8fa2, 0x30fe,
+ 0x8fbd, 0x1fc5,
+ 0x8fbe, 0x3119,
+ 0x8fc4, 0x1ea1,
+ 0x8fc5, 0x311f,
+ 0x8fc6, 0x2393,
+ 0x8fc7, 0x3120,
+ 0x8fcd, 0x1f0b,
+ 0x8fce, 0x3126,
+ 0x8fd8, 0x1e7c,
+ 0x8fd9, 0x3130,
+ 0x9040, 0x3156,
+ 0x9080, 0x3195,
+ 0x909d, 0x23b4,
+ 0x909e, 0x207e,
+ 0x909f, 0x31b2,
+ 0x90ba, 0x1ee3,
+ 0x90bb, 0x31cd,
+ 0x90c0, 0x2095,
+ 0x90c1, 0x23bb,
+ 0x90c2, 0x31d2,
+ 0x90c5, 0x23b9,
+ 0x90c6, 0x31d5,
+ 0x90db, 0x1e28,
+ 0x90dc, 0x23bd,
+ 0x90dd, 0x31ea,
+ 0x90ed, 0x23b5,
+ 0x90ee, 0x31fa,
+ 0x90f0, 0x23ba,
+ 0x90f1, 0x31fc,
+ 0x90f7, 0x23b3,
+ 0x90f8, 0x3202,
+ 0x9140, 0x3209,
+ 0x9142, 0x2162,
+ 0x9143, 0x320b,
+ 0x914b, 0x1e5e,
+ 0x914c, 0x3213,
+ 0x914d, 0x1e5d,
+ 0x914e, 0x3214,
+ 0x9151, 0x23b7,
+ 0x9152, 0x3217,
+ 0x9154, 0x1f2f,
+ 0x9155, 0x24df,
+ 0x9156, 0x3219,
+ 0x9159, 0x23b2,
+ 0x915a, 0x214e,
+ 0x915b, 0x321c,
+ 0x915d, 0x2052,
+ 0x915e, 0x321e,
+ 0x9161, 0x23bc,
+ 0x9162, 0x3221,
+ 0x9163, 0x20eb,
+ 0x9164, 0x3222,
+ 0x916e, 0x2232,
+ 0x916f, 0x322c,
+ 0x9176, 0x1e3f,
+ 0x9177, 0x3233,
+ 0x917a, 0x201b,
+ 0x917b, 0x20bc,
+ 0x917c, 0x23be,
+ 0x917d, 0x3236,
+ 0x9180, 0x3238,
+ 0x9184, 0x1eae,
+ 0x9185, 0x323c,
+ 0x918d, 0x1efb,
+ 0x918e, 0x3244,
+ 0x9191, 0x2089,
+ 0x9192, 0x3247,
+ 0x9193, 0x23b1,
+ 0x9194, 0x3248,
+ 0x9197, 0x21c4,
+ 0x9198, 0x324b,
+ 0x919b, 0x2214,
+ 0x919c, 0x324e,
+ 0x91a9, 0x1fde,
+ 0x91aa, 0x2223,
+ 0x91ab, 0x23b6,
+ 0x91ac, 0x325b,
+ 0x91ba, 0x268c,
+ 0x91bb, 0x24de,
+ 0x91bc, 0x3269,
+ 0x91bf, 0x24e0,
+ 0x91c0, 0x326c,
+ 0x91c3, 0x23b8,
+ 0x91c4, 0x326f,
+ 0x91cd, 0x1e81,
+ 0x91ce, 0x3278,
+ 0x91d0, 0x1ffe,
+ 0x91d1, 0x1f51,
+ 0x91d2, 0x21e1,
+ 0x91d3, 0x327a,
+ 0x91d4, 0x23b0,
+ 0x91d5, 0x327b,
+ 0x91d6, 0x1fce,
+ 0x91d7, 0x327c,
+ 0x91d8, 0x211e,
+ 0x91d9, 0x2021,
+ 0x91da, 0x327d,
+ 0x91df, 0x24e1,
+ 0x91e0, 0x3282,
+ 0x91e2, 0x24a3,
+ 0x91e3, 0x3284,
+ 0x91ea, 0x24a4,
+ 0x91eb, 0x328b,
+ 0x91f0, 0x2273,
+ 0x91f1, 0x3290,
+ 0x91f2, 0x21b0,
+ 0x91f3, 0x3291,
+ 0x9240, 0x329d,
+ 0x9280, 0x32dc,
+ 0x92b6, 0x21d1,
+ 0x92b7, 0x3312,
+ 0x92ce, 0x211c,
+ 0x92cf, 0x3329,
+ 0x92d0, 0x235d,
+ 0x92d1, 0x332a,
+ 0x92d4, 0x2682,
+ 0x92d5, 0x332d,
+ 0x92df, 0x210d,
+ 0x92e0, 0x205a,
+ 0x92e1, 0x3337,
+ 0x92fe, 0x1f8d,
+ 0x9340, 0x3354,
+ 0x9350, 0x21ff,
+ 0x9351, 0x3364,
+ 0x935d, 0x1f58,
+ 0x935e, 0x3370,
+ 0x9370, 0x215b,
+ 0x9371, 0x3382,
+ 0x9376, 0x1eb6,
+ 0x9377, 0x3387,
+ 0x9380, 0x338f,
+ 0x938c, 0x20db,
+ 0x938d, 0x339b,
+ 0x939d, 0x2360,
+ 0x939e, 0x33ab,
+ 0x93a5, 0x2361,
+ 0x93a6, 0x33b2,
+ 0x93a7, 0x2040,
+ 0x93a8, 0x33b3,
+ 0x93b4, 0x228e,
+ 0x93b5, 0x33bf,
+ 0x93b8, 0x1fdf,
+ 0x93b9, 0x33c2,
+ 0x93bb, 0x235e,
+ 0x93bc, 0x33c4,
+ 0x93bd, 0x1e6a,
+ 0x93be, 0x33c5,
+ 0x93c6, 0x2002,
+ 0x93c7, 0x33cd,
+ 0x93cf, 0x2093,
+ 0x93d0, 0x33d5,
+ 0x93d7, 0x235f,
+ 0x93d8, 0x33dc,
+ 0x93db, 0x1eac,
+ 0x93dc, 0x1e54,
+ 0x93dd, 0x33df,
+ 0x93e1, 0x1f08,
+ 0x93e2, 0x33e3,
+ 0x93e4, 0x20c0,
+ 0x93e5, 0x2362,
+ 0x93e6, 0x33e5,
+ 0x93e9, 0x2160,
+ 0x93ea, 0x33e8,
+ 0x93eb, 0x219d,
+ 0x93ec, 0x1f8e,
+ 0x93ed, 0x222d,
+ 0x93ee, 0x33e9,
+ 0x93ef, 0x2047,
+ 0x93f0, 0x33ea,
+ 0x93f1, 0x2262,
+ 0x93f2, 0x33eb,
+ 0x93f4, 0x1f67,
+ 0x93f5, 0x1eb2,
+ 0x93f6, 0x33ed,
+ 0x93fa, 0x1ea9,
+ 0x93fb, 0x33f1,
+ 0x93fe, 0x1fcc,
+ 0x9440, 0x33f4,
+ 0x9444, 0x1f72,
+ 0x9445, 0x33f8,
+ 0x944d, 0x2098,
+ 0x944e, 0x3400,
+ 0x9450, 0x1e52,
+ 0x9451, 0x20a4,
+ 0x9452, 0x1f1c,
+ 0x9453, 0x228f,
+ 0x9454, 0x3402,
+ 0x9455, 0x1fed,
+ 0x9456, 0x3403,
+ 0x9458, 0x2365,
+ 0x9459, 0x3405,
+ 0x945b, 0x1e2d,
+ 0x945c, 0x2152,
+ 0x945d, 0x2366,
+ 0x945e, 0x3407,
+ 0x945f, 0x20fa,
+ 0x9460, 0x3408,
+ 0x9464, 0x2363,
+ 0x9465, 0x340c,
+ 0x9466, 0x209a,
+ 0x9467, 0x340d,
+ 0x946e, 0x203c,
+ 0x946f, 0x3414,
+ 0x9472, 0x1ff6,
+ 0x9473, 0x3417,
+ 0x9474, 0x2364,
+ 0x9475, 0x3418,
+ 0x9476, 0x1e69,
+ 0x9477, 0x3419,
+ 0x9478, 0x2367,
+ 0x9479, 0x341a,
+ 0x947a, 0x211d,
+ 0x947b, 0x341b,
+ 0x9480, 0x2259,
+ 0x9481, 0x2056,
+ 0x9482, 0x2163,
+ 0x9483, 0x341f,
+ 0x9487, 0x1fa9,
+ 0x9488, 0x1ffc,
+ 0x9489, 0x3423,
+ 0x94a1, 0x1e2e,
+ 0x94a2, 0x343b,
+ 0x94b3, 0x1ebc,
+ 0x94b4, 0x344c,
+ 0x94b5, 0x2142,
+ 0x94b6, 0x344d,
+ 0x94bf, 0x201e,
+ 0x94c0, 0x1e43,
+ 0x94c1, 0x3456,
+ 0x94cc, 0x24d4,
+ 0x94cd, 0x3461,
+ 0x94d8, 0x226f,
+ 0x94d9, 0x346c,
+ 0x94e0, 0x1ed7,
+ 0x94e1, 0x3473,
+ 0x9540, 0x3491,
+ 0x9572, 0x212d,
+ 0x9573, 0x34c3,
+ 0x9580, 0x34cf,
+ 0x9583, 0x229b,
+ 0x9584, 0x34d2,
+ 0x959e, 0x2256,
+ 0x959f, 0x24a8,
+ 0x95a0, 0x34ec,
+ 0x95b3, 0x1e79,
+ 0x95b4, 0x34ff,
+ 0x95ba, 0x225a,
+ 0x95bb, 0x3505,
+ 0x95cf, 0x24a7,
+ 0x95d0, 0x3519,
+ 0x95d1, 0x2686,
+ 0x95d2, 0x24a6,
+ 0x95d3, 0x351a,
+ 0x95d4, 0x21ce,
+ 0x95d5, 0x351b,
+ 0x95e1, 0x24a9,
+ 0x95e2, 0x3527,
+ 0x95e7, 0x1fe7,
+ 0x95e8, 0x352c,
+ 0x95f1, 0x2112,
+ 0x95f2, 0x3535,
+ 0x95f8, 0x213c,
+ 0x95f9, 0x353b,
+ 0x95fe, 0x1f5c,
+ 0x9640, 0x3540,
+ 0x9656, 0x24c4,
+ 0x9657, 0x3556,
+ 0x967c, 0x1ecc,
+ 0x967d, 0x357b,
+ 0x9680, 0x357d,
+ 0x9740, 0x35fc,
+ 0x9767, 0x246a,
+ 0x9768, 0x3623,
+ 0x976c, 0x2175,
+ 0x976d, 0x3627,
+ 0x976e, 0x246d,
+ 0x976f, 0x3628,
+ 0x9780, 0x3638,
+ 0x9796, 0x246b,
+ 0x9797, 0x225f,
+ 0x9798, 0x364e,
+ 0x979d, 0x1ece,
+ 0x979e, 0x3653,
+ 0x97a3, 0x2272,
+ 0x97a4, 0x3658,
+ 0x97bf, 0x2473,
+ 0x97c0, 0x3673,
+ 0x97ee, 0x21fe,
+ 0x97ef, 0x36a1,
+ 0x97f7, 0x1efe,
+ 0x97f8, 0x36a9,
+ 0x9840, 0x36b0,
+ 0x9845, 0x2475,
+ 0x9846, 0x36b5,
+ 0x9849, 0x220a,
+ 0x984a, 0x36b8,
+ 0x984f, 0x1f6f,
+ 0x9850, 0x36bd,
+ 0x9871, 0x2468,
+ 0x9872, 0x36de,
+ 0x9873, 0x2100,
+ 0x9874, 0x36df,
+ 0x9880, 0x36ea,
+ 0x9881, 0x2476,
+ 0x9882, 0x36eb,
+ 0x988b, 0x1f27,
+ 0x988c, 0x20d7,
+ 0x988d, 0x36f4,
+ 0x98a0, 0x247c,
+ 0x98a1, 0x3707,
+ 0x98aa, 0x1fa1,
+ 0x98ab, 0x3710,
+ 0x98b6, 0x22aa,
+ 0x98b7, 0x2005,
+ 0x98b8, 0x371b,
+ 0x98ba, 0x246c,
+ 0x98bb, 0x371d,
+ 0x98c7, 0x203e,
+ 0x98c8, 0x3729,
+ 0x98cb, 0x1e4c,
+ 0x98cc, 0x372c,
+ 0x98d0, 0x213a,
+ 0x98d1, 0x3730,
+ 0x98d3, 0x2204,
+ 0x98d4, 0x3732,
+ 0x98e3, 0x20c3,
+ 0x98e4, 0x2140,
+ 0x98e5, 0x2477,
+ 0x98e6, 0x3741,
+ 0x98ef, 0x2474,
+ 0x98f0, 0x374a,
+ 0x98f2, 0x20dd,
+ 0x98f3, 0x374c,
+ 0x9940, 0x3758,
+ 0x9943, 0x1f68,
+ 0x9944, 0x375b,
+ 0x9945, 0x2185,
+ 0x9946, 0x375c,
+ 0x9966, 0x2472,
+ 0x9967, 0x377c,
+ 0x996e, 0x1eb5,
+ 0x996f, 0x3783,
+ 0x9975, 0x2478,
+ 0x9976, 0x3789,
+ 0x997a, 0x1f8b,
+ 0x997b, 0x2484,
+ 0x997c, 0x378d,
+ 0x9980, 0x3790,
+ 0x9985, 0x2699,
+ 0x9986, 0x3795,
+ 0x9989, 0x2482,
+ 0x998a, 0x3798,
+ 0x998e, 0x20a1,
+ 0x998f, 0x379c,
+ 0x9991, 0x1f92,
+ 0x9992, 0x379e,
+ 0x9999, 0x1f38,
+ 0x999a, 0x37a5,
+ 0x99a9, 0x2485,
+ 0x99aa, 0x37b4,
+ 0x99b0, 0x2480,
+ 0x99b1, 0x246e,
+ 0x99b2, 0x37ba,
+ 0x99b3, 0x247b,
+ 0x99b4, 0x2486,
+ 0x99b5, 0x2471,
+ 0x99b6, 0x37bb,
+ 0x99bd, 0x2483,
+ 0x99be, 0x2470,
+ 0x99bf, 0x37c2,
+ 0x99c0, 0x2469,
+ 0x99c1, 0x37c3,
+ 0x99c2, 0x247f,
+ 0x99c3, 0x37c4,
+ 0x99c9, 0x246f,
+ 0x99ca, 0x37ca,
+ 0x99ce, 0x2481,
+ 0x99cf, 0x37ce,
+ 0x99d1, 0x2220,
+ 0x99d2, 0x37d0,
+ 0x99da, 0x1ff5,
+ 0x99db, 0x37d8,
+ 0x99e0, 0x20f4,
+ 0x99e1, 0x37dd,
+ 0x99e5, 0x247d,
+ 0x99e6, 0x37e1,
+ 0x99e8, 0x2479,
+ 0x99e9, 0x37e3,
+ 0x99ec, 0x247e,
+ 0x99ed, 0x37e6,
+ 0x99f4, 0x247a,
+ 0x99f5, 0x37ed,
+ 0x9a40, 0x37f7,
+ 0x9a4a, 0x20e3,
+ 0x9a4b, 0x3801,
+ 0x9a57, 0x20ad,
+ 0x9a58, 0x380d,
+ 0x9a65, 0x24cb,
+ 0x9a66, 0x381a,
+ 0x9a67, 0x1f53,
+ 0x9a68, 0x381b,
+ 0x9a71, 0x2159,
+ 0x9a72, 0x3824,
+ 0x9a76, 0x2013,
+ 0x9a77, 0x1f33,
+ 0x9a78, 0x3828,
+ 0x9a80, 0x382f,
+ 0x9a88, 0x1e5c,
+ 0x9a89, 0x3837,
+ 0x9a8c, 0x2488,
+ 0x9a8d, 0x383a,
+ 0x9a91, 0x2487,
+ 0x9a92, 0x383e,
+ 0x9a97, 0x248a,
+ 0x9a98, 0x3843,
+ 0x9a9a, 0x2489,
+ 0x9a9b, 0x248b,
+ 0x9a9c, 0x3845,
+ 0x9a9e, 0x1f83,
+ 0x9a9f, 0x3847,
+ 0x9aa2, 0x210f,
+ 0x9aa3, 0x1fdb,
+ 0x9aa4, 0x384a,
+ 0x9aaa, 0x20af,
+ 0x9aab, 0x3850,
+ 0x9ad0, 0x24c0,
+ 0x9ad1, 0x3875,
+ 0x9ad6, 0x226d,
+ 0x9ad7, 0x387a,
+ 0x9ada, 0x24c1,
+ 0x9adb, 0x387d,
+ 0x9ae2, 0x20ca,
+ 0x9ae3, 0x3884,
+ 0x9ae4, 0x20e7,
+ 0x9ae5, 0x24c2,
+ 0x9ae6, 0x3885,
+ 0x9b40, 0x389e,
+ 0x9b80, 0x38dd,
+ 0x9bd1, 0x23dc,
+ 0x9bd2, 0x392e,
+ 0x9bdc, 0x23db,
+ 0x9bdd, 0x3938,
+ 0x9c40, 0x395a,
+ 0x9c53, 0x205e,
+ 0x9c54, 0x396d,
+ 0x9c59, 0x2244,
+ 0x9c5a, 0x23e2,
+ 0x9c5b, 0x3972,
+ 0x9c5c, 0x20d4,
+ 0x9c5d, 0x3973,
+ 0x9c75, 0x219f,
+ 0x9c76, 0x398b,
+ 0x9c79, 0x1e66,
+ 0x9c7a, 0x398e,
+ 0x9c80, 0x3993,
+ 0x9c86, 0x1f63,
+ 0x9c87, 0x3999,
+ 0x9c9d, 0x23dd,
+ 0x9c9e, 0x39af,
+ 0x9cab, 0x216b,
+ 0x9cac, 0x39bc,
+ 0x9cca, 0x22b5,
+ 0x9ccb, 0x39da,
+ 0x9ccf, 0x1f26,
+ 0x9cd0, 0x39de,
+ 0x9ce6, 0x1e63,
+ 0x9ce7, 0x2088,
+ 0x9ce8, 0x39f4,
+ 0x9cec, 0x1ebd,
+ 0x9ced, 0x39f8,
+ 0x9cee, 0x2341,
+ 0x9cef, 0x39f9,
+ 0x9cfb, 0x1f4b,
+ 0x9cfc, 0x3a05,
+ 0x9cfe, 0x2292,
+ 0x9d40, 0x3a07,
+ 0x9d42, 0x2124,
+ 0x9d43, 0x3a09,
+ 0x9d46, 0x2048,
+ 0x9d47, 0x23e0,
+ 0x9d48, 0x3a0c,
+ 0x9d4d, 0x2077,
+ 0x9d4e, 0x3a11,
+ 0x9d4f, 0x223a,
+ 0x9d50, 0x3a12,
+ 0x9d61, 0x20b1,
+ 0x9d62, 0x3a23,
+ 0x9d68, 0x1f41,
+ 0x9d69, 0x201c,
+ 0x9d6a, 0x3a29,
+ 0x9d6e, 0x22b8,
+ 0x9d6f, 0x3a2d,
+ 0x9d71, 0x2276,
+ 0x9d72, 0x3a2f,
+ 0x9d75, 0x1f9b,
+ 0x9d76, 0x3a32,
+ 0x9d7b, 0x1f9f,
+ 0x9d7c, 0x3a37,
+ 0x9d7d, 0x25ca,
+ 0x9d7e, 0x3a38,
+ 0x9d80, 0x3a39,
+ 0x9d8a, 0x20be,
+ 0x9d8b, 0x3a43,
+ 0x9d8d, 0x1fb4,
+ 0x9d8e, 0x3a45,
+ 0x9d91, 0x23d7,
+ 0x9d92, 0x3a48,
+ 0x9d99, 0x2105,
+ 0x9d9a, 0x3a4f,
+ 0x9da1, 0x23e1,
+ 0x9da2, 0x1fec,
+ 0x9da3, 0x3a56,
+ 0x9da7, 0x23ea,
+ 0x9da8, 0x3a5a,
+ 0x9dac, 0x23e3,
+ 0x9dad, 0x210e,
+ 0x9dae, 0x3a5e,
+ 0x9db2, 0x1fa6,
+ 0x9db3, 0x2004,
+ 0x9db4, 0x3a62,
+ 0x9dbe, 0x1f9d,
+ 0x9dbf, 0x3a6c,
+ 0x9dc6, 0x23e5,
+ 0x9dc7, 0x3a73,
+ 0x9dc9, 0x2264,
+ 0x9dca, 0x3a75,
+ 0x9dcd, 0x24e2,
+ 0x9dce, 0x3a78,
+ 0x9dd2, 0x23de,
+ 0x9dd3, 0x3a7c,
+ 0x9dd5, 0x1ec4,
+ 0x9dd6, 0x3a7e,
+ 0x9de1, 0x22b6,
+ 0x9de2, 0x20a9,
+ 0x9de3, 0x3a89,
+ 0x9df1, 0x212b,
+ 0x9df2, 0x3a97,
+ 0x9df4, 0x20a5,
+ 0x9df5, 0x3a99,
+ 0x9df7, 0x268b,
+ 0x9df8, 0x3a9b,
+ 0x9dfa, 0x1f76,
+ 0x9dfb, 0x3a9d,
+ 0x9dfd, 0x216d,
+ 0x9dfe, 0x3a9f,
+ 0x9e40, 0x3aa0,
+ 0x9e45, 0x2001,
+ 0x9e46, 0x3aa5,
+ 0x9e48, 0x2191,
+ 0x9e49, 0x1e50,
+ 0x9e4a, 0x3aa7,
+ 0x9e52, 0x1f9c,
+ 0x9e53, 0x3aaf,
+ 0x9e54, 0x23da,
+ 0x9e55, 0x3ab0,
+ 0x9e56, 0x2053,
+ 0x9e57, 0x3ab1,
+ 0x9e5d, 0x23e9,
+ 0x9e5e, 0x23e4,
+ 0x9e5f, 0x3ab7,
+ 0x9e61, 0x21d5,
+ 0x9e62, 0x3ab9,
+ 0x9e63, 0x23e6,
+ 0x9e64, 0x3aba,
+ 0x9e67, 0x23df,
+ 0x9e68, 0x3abd,
+ 0x9e6c, 0x1e4f,
+ 0x9e6d, 0x3ac1,
+ 0x9e6f, 0x23d9,
+ 0x9e70, 0x3ac3,
+ 0x9e72, 0x2014,
+ 0x9e73, 0x3ac5,
+ 0x9e74, 0x23ec,
+ 0x9e75, 0x23eb,
+ 0x9e76, 0x3ac6,
+ 0x9e7b, 0x23d8,
+ 0x9e7c, 0x23ee,
+ 0x9e7d, 0x3acb,
+ 0x9e80, 0x3acd,
+ 0x9e85, 0x268e,
+ 0x9e86, 0x3ad2,
+ 0x9e87, 0x23ed,
+ 0x9e88, 0x3ad3,
+ 0x9e91, 0x1ffa,
+ 0x9e92, 0x3adc,
+ 0x9e96, 0x23d6,
+ 0x9e97, 0x23e8,
+ 0x9e98, 0x3ae0,
+ 0x9ea2, 0x2106,
+ 0x9ea3, 0x3aea,
+ 0x9ea6, 0x200b,
+ 0x9ea7, 0x3aed,
+ 0x9ea9, 0x2166,
+ 0x9eaa, 0x3aef,
+ 0x9eae, 0x23ef,
+ 0x9eaf, 0x3af3,
+ 0x9eb3, 0x2189,
+ 0x9eb4, 0x2058,
+ 0x9eb5, 0x3af7,
+ 0x9eb7, 0x23e7,
+ 0x9eb8, 0x3af9,
+ 0x9ef5, 0x21a3,
+ 0x9ef6, 0x3b36,
+ 0x9f40, 0x3b3f,
+ 0x9f4e, 0x217a,
+ 0x9f4f, 0x3b4d,
+ 0x9f6f, 0x21a5,
+ 0x9f70, 0x3b6d,
+ 0x9f80, 0x3b7c,
+ 0x9f92, 0x2022,
+ 0x9f93, 0x3b8e,
+ 0x9f98, 0x24d6,
+ 0x9f99, 0x3b93,
+ 0x9fa6, 0x233a,
+ 0x9fa7, 0x3ba0,
+ 0x9fa9, 0x1eee,
+ 0x9faa, 0x3ba2,
+ 0x9fac, 0x24d5,
+ 0x9fad, 0x3ba4,
+ 0x9fc9, 0x2228,
+ 0x9fca, 0x3bc0,
+ 0x9fcd, 0x24d7,
+ 0x9fce, 0x3bc3,
+ 0x9fe1, 0x20fc,
+ 0x9fe2, 0x3bd6,
+ 0x9feb, 0x1e87,
+ 0x9fec, 0x3bdf,
+ 0x9fee, 0x24d8,
+ 0x9fef, 0x3be1,
+ 0x9ff4, 0x1eba,
+ 0x9ff5, 0x3be6,
+ 0x9ffd, 0x2119,
+ 0x9ffe, 0x3bee,
+ 0xa040, 0x3bef,
+ 0xa043, 0x216c,
+ 0xa044, 0x3bf2,
+ 0xa046, 0x24d9,
+ 0xa047, 0x3bf4,
+ 0xa049, 0x2227,
+ 0xa04a, 0x3bf6,
+ 0xa04e, 0x1e5f,
+ 0xa04f, 0x3bfa,
+ 0xa054, 0x229f,
+ 0xa055, 0x3bff,
+ 0xa05a, 0x1f5d,
+ 0xa05b, 0x3c04,
+ 0xa061, 0x1fbc,
+ 0xa062, 0x3c0a,
+ 0xa063, 0x24da,
+ 0xa064, 0x3c0b,
+ 0xa071, 0x2149,
+ 0xa072, 0x3c18,
+ 0xa074, 0x2046,
+ 0xa075, 0x3c1a,
+ 0xa080, 0x2000,
+ 0xa081, 0x3c24,
+ 0xa091, 0x2190,
+ 0xa092, 0x3c34,
+ 0xa094, 0x2208,
+ 0xa095, 0x3c36,
+ 0xa096, 0x1ee6,
+ 0xa097, 0x3c37,
+ 0xa0a9, 0x24c3,
+ 0xa0aa, 0x3c49,
+ 0xa0bf, 0x20cc,
+ 0xa0c0, 0x3c5e,
+ 0xa0ce, 0x2340,
+ 0xa0cf, 0x3c6c,
+ 0xa0d9, 0x1ed1,
+ 0xa0da, 0x3c76,
+ 0xa0de, 0x21ac,
+ 0xa0df, 0x3c7a,
+ 0xa0ee, 0x22af,
+ 0xa0ef, 0x3c89,
+ 0xa1a1, 0x0060,
+ 0xa2a1, 0x26a9,
+ 0xa2b1, 0x00be,
+ 0xa2e5, 0x00f0,
+ 0xa2f1, 0x00fa,
+ 0xa3a1, 0x0106,
+ 0xa4a1, 0x0164,
+ 0xa5a1, 0x01b7,
+ 0xa6a1, 0x020d,
+ 0xa6c1, 0x0225,
+ 0xa7a1, 0x025a,
+ 0xa7d1, 0x027b,
+ 0xa840, 0x26b3,
+ 0xa880, 0x26f2,
+ 0xa8a1, 0x029c,
+ 0xa8c5, 0x02bc,
+ 0xa940, 0x2708,
+ 0xa959, 0x2720,
+ 0xa95c, 0x2722,
+ 0xa960, 0x2723,
+ 0xa980, 0x2742,
+ 0xa996, 0x1e17,
+ 0xa9a4, 0x02e2,
+ 0xaa40, 0x3c99,
+ 0xaa4d, 0x21b6,
+ 0xaa4e, 0x1e3d,
+ 0xaa4f, 0x3ca6,
+ 0xaa71, 0x2235,
+ 0xaa72, 0x3cc8,
+ 0xaa73, 0x2397,
+ 0xaa74, 0x3cc9,
+ 0xaa77, 0x2395,
+ 0xaa78, 0x3ccc,
+ 0xaa7a, 0x223f,
+ 0xaa7b, 0x212a,
+ 0xaa7c, 0x3cce,
+ 0xaa80, 0x3cd1,
+ 0xaa9a, 0x1ed2,
+ 0xaa9b, 0x3ceb,
+ 0xaa9c, 0x2396,
+ 0xaa9d, 0x2398,
+ 0xaa9e, 0x3cec,
+ 0xaa9f, 0x20a2,
+ 0xaaa0, 0x3ced,
+ 0xaaa1, 0x032e,
+ 0xab40, 0x1f64,
+ 0xab41, 0x3cee,
+ 0xab43, 0x202b,
+ 0xab44, 0x3cf0,
+ 0xab45, 0x2394,
+ 0xab46, 0x2139,
+ 0xab47, 0x3cf1,
+ 0xab48, 0x215f,
+ 0xab49, 0x21c1,
+ 0xab4a, 0x239a,
+ 0xab4b, 0x3cf2,
+ 0xab4d, 0x2399,
+ 0xab4e, 0x3cf4,
+ 0xab80, 0x3d25,
+ 0xaba1, 0x038c,
+ 0xac40, 0x3d46,
+ 0xac46, 0x21c0,
+ 0xac47, 0x3d4c,
+ 0xac71, 0x2460,
+ 0xac72, 0x3d76,
+ 0xac7c, 0x245c,
+ 0xac7d, 0x3d80,
+ 0xac80, 0x3d82,
+ 0xac8d, 0x215d,
+ 0xac8e, 0x3d8f,
+ 0xac93, 0x2225,
+ 0xac94, 0x206a,
+ 0xac95, 0x3d94,
+ 0xad40, 0x3da0,
+ 0xad49, 0x2461,
+ 0xad4a, 0x3da9,
+ 0xad5e, 0x245b,
+ 0xad5f, 0x3dbd,
+ 0xad61, 0x2462,
+ 0xad62, 0x3dbf,
+ 0xad68, 0x1f54,
+ 0xad69, 0x3dc5,
+ 0xad74, 0x245f,
+ 0xad75, 0x3dd0,
+ 0xad80, 0x3dda,
+ 0xad82, 0x20ec,
+ 0xad83, 0x3ddc,
+ 0xad87, 0x245d,
+ 0xad88, 0x3de0,
+ 0xad8b, 0x2463,
+ 0xad8c, 0x3de3,
+ 0xad91, 0x2464,
+ 0xad92, 0x3de8,
+ 0xae40, 0x3df7,
+ 0xae54, 0x24a5,
+ 0xae55, 0x3e0b,
+ 0xae62, 0x1e70,
+ 0xae63, 0x3e18,
+ 0xae80, 0x208f,
+ 0xae81, 0x3e34,
+ 0xae85, 0x1e42,
+ 0xae86, 0x3e38,
+ 0xae8b, 0x1f4e,
+ 0xae8c, 0x3e3d,
+ 0xae94, 0x1eb1,
+ 0xae95, 0x3e45,
+ 0xaea0, 0x1e8b,
+ 0xaf40, 0x3e50,
+ 0xaf64, 0x1fc6,
+ 0xaf65, 0x3e74,
+ 0xaf7b, 0x25ae,
+ 0xaf7c, 0x3e8a,
+ 0xaf80, 0x3e8d,
+ 0xaf82, 0x1f01,
+ 0xaf83, 0x2200,
+ 0xaf84, 0x3e8f,
+ 0xaf8e, 0x25b2,
+ 0xaf8f, 0x1e97,
+ 0xaf90, 0x3e99,
+ 0xaf91, 0x20ab,
+ 0xaf92, 0x3e9a,
+ 0xaf9c, 0x25b3,
+ 0xaf9d, 0x3ea4,
+ 0xaf9f, 0x2028,
+ 0xafa0, 0x3ea6,
+ 0xb040, 0x3ea7,
+ 0xb041, 0x25af,
+ 0xb043, 0x3ea8,
+ 0xb044, 0x25b1,
+ 0xb045, 0x3ea9,
+ 0xb04f, 0x25ac,
+ 0xb050, 0x3eb3,
+ 0xb054, 0x1e4e,
+ 0xb055, 0x3eb7,
+ 0xb057, 0x2202,
+ 0xb058, 0x25ab,
+ 0xb059, 0x2286,
+ 0xb05a, 0x3eb9,
+ 0xb05b, 0x25ad,
+ 0xb05c, 0x3eba,
+ 0xb05d, 0x25b6,
+ 0xb05e, 0x3ebb,
+ 0xb05f, 0x21e3,
+ 0xb060, 0x25b4,
+ 0xb062, 0x222f,
+ 0xb063, 0x2165,
+ 0xb064, 0x25b7,
+ 0xb065, 0x3ebc,
+ 0xb06c, 0x1ee9,
+ 0xb06d, 0x3ec3,
+ 0xb07d, 0x1e25,
+ 0xb07e, 0x3ed3,
+ 0xb080, 0x3ed4,
+ 0xb097, 0x25c0,
+ 0xb098, 0x3eeb,
+ 0xb099, 0x229a,
+ 0xb09a, 0x3eec,
+ 0xb0a1, 0x03ac,
+ 0xb140, 0x3ef3,
+ 0xb14b, 0x226e,
+ 0xb14c, 0x3efe,
+ 0xb14d, 0x1fbd,
+ 0xb14e, 0x3eff,
+ 0xb14f, 0x1f84,
+ 0xb150, 0x20b2,
+ 0xb151, 0x3f00,
+ 0xb152, 0x2043,
+ 0xb153, 0x3f01,
+ 0xb180, 0x3f2d,
+ 0xb197, 0x2684,
+ 0xb198, 0x3f44,
+ 0xb1a1, 0x040a,
+ 0xb240, 0x3f4d,
+ 0xb241, 0x24ef,
+ 0xb242, 0x3f4e,
+ 0xb267, 0x24ee,
+ 0xb268, 0x3f73,
+ 0xb26d, 0x2074,
+ 0xb26e, 0x3f78,
+ 0xb274, 0x2687,
+ 0xb275, 0x3f7e,
+ 0xb280, 0x24f0,
+ 0xb281, 0x3f88,
+ 0xb289, 0x268d,
+ 0xb28a, 0x3f90,
+ 0xb29a, 0x22a0,
+ 0xb29b, 0x3fa0,
+ 0xb2a1, 0x0468,
+ 0xb340, 0x3fa6,
+ 0xb343, 0x1fab,
+ 0xb344, 0x3fa9,
+ 0xb370, 0x26a8,
+ 0xb371, 0x3fd5,
+ 0xb380, 0x3fe3,
+ 0xb388, 0x24e9,
+ 0xb389, 0x3feb,
+ 0xb38c, 0x24e5,
+ 0xb38d, 0x3fee,
+ 0xb38e, 0x21fa,
+ 0xb38f, 0x3fef,
+ 0xb3a1, 0x04c6,
+ 0xb440, 0x4001,
+ 0xb454, 0x2148,
+ 0xb455, 0x4015,
+ 0xb458, 0x24e4,
+ 0xb459, 0x4018,
+ 0xb45e, 0x24e6,
+ 0xb45f, 0x20f7,
+ 0xb460, 0x401d,
+ 0xb461, 0x206b,
+ 0xb462, 0x401e,
+ 0xb475, 0x22a7,
+ 0xb476, 0x4031,
+ 0xb47e, 0x24ec,
+ 0xb480, 0x4039,
+ 0xb483, 0x24eb,
+ 0xb484, 0x403c,
+ 0xb489, 0x24e3,
+ 0xb48a, 0x4041,
+ 0xb493, 0x24ea,
+ 0xb494, 0x404a,
+ 0xb4a1, 0x0524,
+ 0xb540, 0x4057,
+ 0xb541, 0x1e92,
+ 0xb542, 0x4058,
+ 0xb54b, 0x1e27,
+ 0xb54c, 0x4061,
+ 0xb556, 0x1fe6,
+ 0xb557, 0x406b,
+ 0xb55a, 0x24e7,
+ 0xb55b, 0x2012,
+ 0xb55c, 0x1eec,
+ 0xb55d, 0x406e,
+ 0xb561, 0x24e8,
+ 0xb562, 0x4072,
+ 0xb580, 0x408f,
+ 0xb59c, 0x1f66,
+ 0xb59d, 0x24dc,
+ 0xb59e, 0x40ab,
+ 0xb5a1, 0x0582,
+ 0xb640, 0x40ae,
+ 0xb652, 0x26a2,
+ 0xb653, 0x40c0,
+ 0xb655, 0x24dd,
+ 0xb656, 0x40c2,
+ 0xb659, 0x200e,
+ 0xb65a, 0x40c5,
+ 0xb65b, 0x24db,
+ 0xb65c, 0x1eb8,
+ 0xb65d, 0x40c6,
+ 0xb680, 0x40e8,
+ 0xb6a1, 0x05e0,
+ 0xb740, 0x4109,
+ 0xb74e, 0x2295,
+ 0xb74f, 0x4117,
+ 0xb751, 0x1e80,
+ 0xb752, 0x4119,
+ 0xb759, 0x2677,
+ 0xb75a, 0x4120,
+ 0xb764, 0x2624,
+ 0xb765, 0x1f69,
+ 0xb766, 0x222b,
+ 0xb767, 0x412a,
+ 0xb777, 0x257f,
+ 0xb778, 0x1f5b,
+ 0xb779, 0x413a,
+ 0xb780, 0x219b,
+ 0xb781, 0x4140,
+ 0xb782, 0x267d,
+ 0xb783, 0x4141,
+ 0xb7a1, 0x063e,
+ 0xb840, 0x415f,
+ 0xb843, 0x21a0,
+ 0xb844, 0x2186,
+ 0xb845, 0x4162,
+ 0xb846, 0x20ed,
+ 0xb847, 0x4163,
+ 0xb84d, 0x25b9,
+ 0xb84e, 0x4169,
+ 0xb851, 0x1fea,
+ 0xb852, 0x416c,
+ 0xb85a, 0x1ea4,
+ 0xb85b, 0x20e1,
+ 0xb85c, 0x4174,
+ 0xb85d, 0x25b8,
+ 0xb85e, 0x2260,
+ 0xb85f, 0x4175,
+ 0xb860, 0x20e2,
+ 0xb861, 0x4176,
+ 0xb877, 0x2141,
+ 0xb878, 0x418c,
+ 0xb880, 0x4193,
+ 0xb882, 0x1fc7,
+ 0xb883, 0x4195,
+ 0xb8a1, 0x069c,
+ 0xb940, 0x41b3,
+ 0xb950, 0x1e41,
+ 0xb951, 0x41c3,
+ 0xb961, 0x25e4,
+ 0xb962, 0x41d3,
+ 0xb97b, 0x1f86,
+ 0xb97c, 0x41ec,
+ 0xb980, 0x41ef,
+ 0xb99d, 0x1fb3,
+ 0xb99e, 0x420c,
+ 0xb9a0, 0x1eef,
+ 0xb9a1, 0x06fa,
+ 0xba40, 0x420e,
+ 0xba42, 0x22a4,
+ 0xba43, 0x4210,
+ 0xba44, 0x25e8,
+ 0xba45, 0x4211,
+ 0xba56, 0x25e3,
+ 0xba57, 0x4222,
+ 0xba59, 0x2111,
+ 0xba5a, 0x4224,
+ 0xba60, 0x25e6,
+ 0xba61, 0x422a,
+ 0xba6a, 0x25e7,
+ 0xba6b, 0x4233,
+ 0xba74, 0x2041,
+ 0xba75, 0x423c,
+ 0xba80, 0x4246,
+ 0xba84, 0x25ea,
+ 0xba85, 0x424a,
+ 0xba86, 0x1f8f,
+ 0xba87, 0x424b,
+ 0xba88, 0x25ec,
+ 0xba89, 0x424c,
+ 0xba8d, 0x25eb,
+ 0xba8e, 0x4250,
+ 0xba9e, 0x20d0,
+ 0xba9f, 0x201d,
+ 0xbaa0, 0x4260,
+ 0xbaa1, 0x0758,
+ 0xbb40, 0x1ff7,
+ 0xbb41, 0x4261,
+ 0xbb49, 0x1e8d,
+ 0xbb4a, 0x4269,
+ 0xbb58, 0x25e9,
+ 0xbb59, 0x4277,
+ 0xbb5b, 0x25ee,
+ 0xbb5c, 0x203a,
+ 0xbb5d, 0x4279,
+ 0xbb60, 0x2693,
+ 0xbb61, 0x427c,
+ 0xbb65, 0x25e5,
+ 0xbb66, 0x25ed,
+ 0xbb67, 0x4280,
+ 0xbb68, 0x2009,
+ 0xbb69, 0x4281,
+ 0xbb6a, 0x2065,
+ 0xbb6b, 0x4282,
+ 0xbb6e, 0x26a3,
+ 0xbb6f, 0x4285,
+ 0xbb80, 0x4295,
+ 0xbba1, 0x07b6,
+ 0xbc40, 0x42b6,
+ 0xbc52, 0x25f5,
+ 0xbc53, 0x1efc,
+ 0xbc54, 0x42c8,
+ 0xbc5a, 0x2024,
+ 0xbc5b, 0x42ce,
+ 0xbc61, 0x269b,
+ 0xbc62, 0x42d4,
+ 0xbc63, 0x25f3,
+ 0xbc64, 0x42d5,
+ 0xbc65, 0x22d9,
+ 0xbc66, 0x42d6,
+ 0xbc67, 0x25f4,
+ 0xbc68, 0x42d7,
+ 0xbc69, 0x241b,
+ 0xbc6a, 0x42d8,
+ 0xbc6d, 0x1fc8,
+ 0xbc6e, 0x42db,
+ 0xbc6f, 0x1f7b,
+ 0xbc70, 0x42dc,
+ 0xbc71, 0x241d,
+ 0xbc72, 0x42dd,
+ 0xbc73, 0x224c,
+ 0xbc74, 0x1f48,
+ 0xbc75, 0x241c,
+ 0xbc76, 0x241e,
+ 0xbc78, 0x20ff,
+ 0xbc79, 0x219a,
+ 0xbc7a, 0x42de,
+ 0xbc7b, 0x2091,
+ 0xbc7c, 0x42df,
+ 0xbc7e, 0x20a7,
+ 0xbc80, 0x42e1,
+ 0xbc82, 0x2423,
+ 0xbc83, 0x1e9b,
+ 0xbc84, 0x2422,
+ 0xbc85, 0x42e3,
+ 0xbc86, 0x2110,
+ 0xbc87, 0x42e4,
+ 0xbc88, 0x228d,
+ 0xbc89, 0x1f71,
+ 0xbc8a, 0x1ef8,
+ 0xbc8b, 0x2421,
+ 0xbc8c, 0x42e5,
+ 0xbc8f, 0x1ef3,
+ 0xbc90, 0x42e8,
+ 0xbc9a, 0x21b1,
+ 0xbc9b, 0x2426,
+ 0xbc9c, 0x2425,
+ 0xbc9d, 0x2120,
+ 0xbc9e, 0x42f2,
+ 0xbca1, 0x0814,
+ 0xbd40, 0x42f5,
+ 0xbd42, 0x211a,
+ 0xbd43, 0x2424,
+ 0xbd44, 0x42f7,
+ 0xbd45, 0x2428,
+ 0xbd46, 0x42f8,
+ 0xbd48, 0x242a,
+ 0xbd49, 0x2429,
+ 0xbd4a, 0x42fa,
+ 0xbd4b, 0x2294,
+ 0xbd4c, 0x42fb,
+ 0xbd4d, 0x22be,
+ 0xbd4e, 0x42fc,
+ 0xbd4f, 0x1e31,
+ 0xbd50, 0x42fd,
+ 0xbd57, 0x242c,
+ 0xbd58, 0x4304,
+ 0xbd59, 0x1fb5,
+ 0xbd5a, 0x4305,
+ 0xbd66, 0x242b,
+ 0xbd67, 0x1faf,
+ 0xbd68, 0x4311,
+ 0xbd6a, 0x2068,
+ 0xbd6b, 0x21e4,
+ 0xbd6c, 0x4313,
+ 0xbd6f, 0x1f21,
+ 0xbd70, 0x4316,
+ 0xbd71, 0x2101,
+ 0xbd72, 0x4317,
+ 0xbd79, 0x217c,
+ 0xbd7a, 0x214a,
+ 0xbd7b, 0x242d,
+ 0xbd7c, 0x431e,
+ 0xbd7e, 0x1fd4,
+ 0xbd80, 0x4320,
+ 0xbd81, 0x1fd1,
+ 0xbd82, 0x4321,
+ 0xbd89, 0x1e33,
+ 0xbd8a, 0x4328,
+ 0xbd8b, 0x242f,
+ 0xbd8c, 0x4329,
+ 0xbd8e, 0x242e,
+ 0xbd8f, 0x432b,
+ 0xbd90, 0x2430,
+ 0xbd91, 0x21db,
+ 0xbd92, 0x432c,
+ 0xbd97, 0x2158,
+ 0xbd98, 0x4331,
+ 0xbd9b, 0x1fc2,
+ 0xbd9c, 0x4334,
+ 0xbda1, 0x0872,
+ 0xbe40, 0x4339,
+ 0xbe43, 0x22b9,
+ 0xbe44, 0x433c,
+ 0xbe45, 0x2436,
+ 0xbe46, 0x433d,
+ 0xbe49, 0x1e8e,
+ 0xbe4a, 0x2439,
+ 0xbe4b, 0x4340,
+ 0xbe51, 0x21c5,
+ 0xbe52, 0x2437,
+ 0xbe53, 0x2192,
+ 0xbe54, 0x4346,
+ 0xbe55, 0x243a,
+ 0xbe56, 0x1f19,
+ 0xbe57, 0x218c,
+ 0xbe58, 0x1e40,
+ 0xbe59, 0x22b3,
+ 0xbe5a, 0x4347,
+ 0xbe5d, 0x205f,
+ 0xbe5e, 0x2438,
+ 0xbe5f, 0x2432,
+ 0xbe60, 0x2274,
+ 0xbe61, 0x434a,
+ 0xbe62, 0x1e9c,
+ 0xbe63, 0x2431,
+ 0xbe64, 0x2085,
+ 0xbe65, 0x434b,
+ 0xbe69, 0x2435,
+ 0xbe6a, 0x434f,
+ 0xbe6c, 0x243b,
+ 0xbe6d, 0x4351,
+ 0xbe6f, 0x1fb7,
+ 0xbe70, 0x2433,
+ 0xbe71, 0x4353,
+ 0xbe76, 0x2054,
+ 0xbe77, 0x21de,
+ 0xbe78, 0x4358,
+ 0xbe79, 0x2434,
+ 0xbe7a, 0x4359,
+ 0xbe7c, 0x243d,
+ 0xbe7d, 0x1f89,
+ 0xbe7e, 0x243c,
+ 0xbe80, 0x435b,
+ 0xbe83, 0x1f6e,
+ 0xbe84, 0x1ed8,
+ 0xbe85, 0x435e,
+ 0xbe86, 0x1ebf,
+ 0xbe87, 0x2445,
+ 0xbe88, 0x435f,
+ 0xbe89, 0x2249,
+ 0xbe8a, 0x4360,
+ 0xbe8c, 0x2441,
+ 0xbe8d, 0x4362,
+ 0xbe8e, 0x1e47,
+ 0xbe8f, 0x1f56,
+ 0xbe90, 0x4363,
+ 0xbe92, 0x2086,
+ 0xbe93, 0x4365,
+ 0xbe95, 0x2196,
+ 0xbe96, 0x4367,
+ 0xbe97, 0x2443,
+ 0xbe98, 0x243f,
+ 0xbe99, 0x4368,
+ 0xbe9a, 0x2023,
+ 0xbe9b, 0x4369,
+ 0xbe9c, 0x2442,
+ 0xbe9d, 0x436a,
+ 0xbe9f, 0x243e,
+ 0xbea0, 0x436c,
+ 0xbea1, 0x08d0,
+ 0xbf40, 0x26a6,
+ 0xbf41, 0x436d,
+ 0xbf4d, 0x234e,
+ 0xbf4e, 0x2446,
+ 0xbf4f, 0x244b,
+ 0xbf50, 0x2444,
+ 0xbf51, 0x4379,
+ 0xbf55, 0x2427,
+ 0xbf56, 0x244c,
+ 0xbf57, 0x437d,
+ 0xbf60, 0x1f0f,
+ 0xbf61, 0x4386,
+ 0xbf62, 0x2447,
+ 0xbf63, 0x2449,
+ 0xbf64, 0x2448,
+ 0xbf65, 0x4387,
+ 0xbf68, 0x21c2,
+ 0xbf69, 0x438a,
+ 0xbf6c, 0x216e,
+ 0xbf6d, 0x438d,
+ 0xbf70, 0x1f03,
+ 0xbf71, 0x4390,
+ 0xbf72, 0x244a,
+ 0xbf73, 0x215c,
+ 0xbf74, 0x4391,
+ 0xbf76, 0x22bb,
+ 0xbf77, 0x2450,
+ 0xbf78, 0x4393,
+ 0xbf79, 0x2694,
+ 0xbf7a, 0x244f,
+ 0xbf7b, 0x25f6,
+ 0xbf7c, 0x2051,
+ 0xbf7d, 0x4394,
+ 0xbf7e, 0x244e,
+ 0xbf80, 0x4395,
+ 0xbf82, 0x22ba,
+ 0xbf83, 0x1f6d,
+ 0xbf84, 0x4397,
+ 0xbf89, 0x2452,
+ 0xbf8a, 0x2451,
+ 0xbf8b, 0x439c,
+ 0xbf95, 0x2455,
+ 0xbf96, 0x43a6,
+ 0xbf97, 0x2289,
+ 0xbf98, 0x2116,
+ 0xbf99, 0x43a7,
+ 0xbf9d, 0x2454,
+ 0xbf9e, 0x43ab,
+ 0xbfa1, 0x092e,
+ 0xc040, 0x20fb,
+ 0xc041, 0x43ae,
+ 0xc044, 0x2440,
+ 0xc045, 0x43b1,
+ 0xc04b, 0x2126,
+ 0xc04c, 0x1f61,
+ 0xc04d, 0x269d,
+ 0xc04e, 0x43b7,
+ 0xc04f, 0x1f8a,
+ 0xc050, 0x2456,
+ 0xc051, 0x2459,
+ 0xc052, 0x2458,
+ 0xc053, 0x43b8,
+ 0xc055, 0x1fae,
+ 0xc056, 0x43ba,
+ 0xc05b, 0x221a,
+ 0xc05c, 0x43bf,
+ 0xc05e, 0x1f7a,
+ 0xc05f, 0x244d,
+ 0xc060, 0x2457,
+ 0xc061, 0x43c1,
+ 0xc069, 0x2453,
+ 0xc06a, 0x43c9,
+ 0xc06b, 0x2420,
+ 0xc06c, 0x43ca,
+ 0xc06d, 0x21df,
+ 0xc06e, 0x2685,
+ 0xc06f, 0x43cb,
+ 0xc070, 0x1e6e,
+ 0xc071, 0x43cc,
+ 0xc074, 0x2224,
+ 0xc075, 0x2670,
+ 0xc076, 0x43cf,
+ 0xc077, 0x21ba,
+ 0xc078, 0x43d0,
+ 0xc079, 0x245a,
+ 0xc07a, 0x43d1,
+ 0xc07c, 0x1fff,
+ 0xc07d, 0x43d3,
+ 0xc080, 0x43d5,
+ 0xc09b, 0x25e2,
+ 0xc09c, 0x43f0,
+ 0xc09d, 0x269a,
+ 0xc09e, 0x43f1,
+ 0xc0a1, 0x098c,
+ 0xc140, 0x43f4,
+ 0xc150, 0x1eea,
+ 0xc151, 0x4404,
+ 0xc154, 0x1e2c,
+ 0xc155, 0x4407,
+ 0xc15f, 0x2062,
+ 0xc160, 0x24f1,
+ 0xc161, 0x4411,
+ 0xc162, 0x24f2,
+ 0xc163, 0x4412,
+ 0xc175, 0x25f2,
+ 0xc176, 0x4424,
+ 0xc178, 0x2215,
+ 0xc179, 0x4426,
+ 0xc180, 0x442c,
+ 0xc195, 0x21ae,
+ 0xc196, 0x4441,
+ 0xc1a1, 0x09ea,
+ 0xc240, 0x444c,
+ 0xc24e, 0x20e0,
+ 0xc24f, 0x445a,
+ 0xc265, 0x25c2,
+ 0xc266, 0x4470,
+ 0xc267, 0x25c1,
+ 0xc268, 0x4471,
+ 0xc27d, 0x2128,
+ 0xc27e, 0x4486,
+ 0xc280, 0x4487,
+ 0xc284, 0x2199,
+ 0xc285, 0x448b,
+ 0xc293, 0x2017,
+ 0xc294, 0x1ea0,
+ 0xc295, 0x2125,
+ 0xc296, 0x214d,
+ 0xc297, 0x4499,
+ 0xc298, 0x25c4,
+ 0xc299, 0x209d,
+ 0xc29a, 0x228a,
+ 0xc29b, 0x449a,
+ 0xc29c, 0x25c3,
+ 0xc29d, 0x449b,
+ 0xc2a0, 0x2179,
+ 0xc2a1, 0x0a48,
+ 0xc340, 0x2038,
+ 0xc341, 0x449e,
+ 0xc343, 0x2155,
+ 0xc344, 0x44a0,
+ 0xc37b, 0x21d2,
+ 0xc37c, 0x44d7,
+ 0xc380, 0x44da,
+ 0xc384, 0x24c7,
+ 0xc385, 0x44de,
+ 0xc39b, 0x2279,
+ 0xc39c, 0x44f4,
+ 0xc3a1, 0x0aa6,
+ 0xc440, 0x44f9,
+ 0xc449, 0x2123,
+ 0xc44a, 0x4502,
+ 0xc44c, 0x24c5,
+ 0xc44d, 0x4504,
+ 0xc454, 0x24c9,
+ 0xc455, 0x450b,
+ 0xc458, 0x2094,
+ 0xc459, 0x450e,
+ 0xc45b, 0x2296,
+ 0xc45c, 0x4510,
+ 0xc463, 0x1e77,
+ 0xc464, 0x4517,
+ 0xc477, 0x1f06,
+ 0xc478, 0x452a,
+ 0xc47a, 0x1fa5,
+ 0xc47b, 0x452c,
+ 0xc480, 0x4530,
+ 0xc481, 0x2099,
+ 0xc482, 0x4531,
+ 0xc491, 0x1ead,
+ 0xc492, 0x24c8,
+ 0xc493, 0x20a8,
+ 0xc494, 0x4540,
+ 0xc498, 0x201f,
+ 0xc499, 0x4544,
+ 0xc49a, 0x20c5,
+ 0xc49b, 0x4545,
+ 0xc49c, 0x24ca,
+ 0xc49d, 0x4546,
+ 0xc4a1, 0x0b04,
+ 0xc540, 0x454a,
+ 0xc544, 0x1ff0,
+ 0xc545, 0x454e,
+ 0xc546, 0x24c6,
+ 0xc547, 0x454f,
+ 0xc54b, 0x225d,
+ 0xc54c, 0x22de,
+ 0xc54d, 0x4553,
+ 0xc552, 0x202c,
+ 0xc553, 0x4558,
+ 0xc55f, 0x2161,
+ 0xc560, 0x4564,
+ 0xc563, 0x223b,
+ 0xc564, 0x21d9,
+ 0xc565, 0x1fcb,
+ 0xc566, 0x1fc9,
+ 0xc567, 0x4567,
+ 0xc580, 0x457f,
+ 0xc593, 0x1e61,
+ 0xc594, 0x4592,
+ 0xc59c, 0x25ef,
+ 0xc59d, 0x459a,
+ 0xc59e, 0x1f98,
+ 0xc59f, 0x459b,
+ 0xc5a1, 0x0b62,
+ 0xc640, 0x459d,
+ 0xc641, 0x25f0,
+ 0xc642, 0x459e,
+ 0xc644, 0x1f88,
+ 0xc645, 0x45a0,
+ 0xc647, 0x21f8,
+ 0xc648, 0x45a2,
+ 0xc663, 0x2322,
+ 0xc664, 0x45bd,
+ 0xc672, 0x2336,
+ 0xc673, 0x45cb,
+ 0xc680, 0x45d7,
+ 0xc6a1, 0x0bc0,
+ 0xc740, 0x45f8,
+ 0xc766, 0x22ab,
+ 0xc767, 0x461e,
+ 0xc76f, 0x1fbf,
+ 0xc770, 0x4626,
+ 0xc776, 0x1f7d,
+ 0xc777, 0x462c,
+ 0xc77b, 0x2333,
+ 0xc77c, 0x4630,
+ 0xc780, 0x4633,
+ 0xc7a1, 0x0c1e,
+ 0xc840, 0x4654,
+ 0xc841, 0x1f4d,
+ 0xc842, 0x4655,
+ 0xc84f, 0x2334,
+ 0xc850, 0x4662,
+ 0xc852, 0x1ff1,
+ 0xc853, 0x4664,
+ 0xc866, 0x218b,
+ 0xc867, 0x4677,
+ 0xc86e, 0x2349,
+ 0xc86f, 0x467e,
+ 0xc87e, 0x220b,
+ 0xc880, 0x468d,
+ 0xc887, 0x2346,
+ 0xc888, 0x4694,
+ 0xc892, 0x2347,
+ 0xc893, 0x469e,
+ 0xc894, 0x2193,
+ 0xc895, 0x469f,
+ 0xc899, 0x26a1,
+ 0xc89a, 0x46a3,
+ 0xc89d, 0x1f62,
+ 0xc89e, 0x46a6,
+ 0xc8a1, 0x0c7c,
+ 0xc940, 0x46a9,
+ 0xc94f, 0x234d,
+ 0xc950, 0x2348,
+ 0xc951, 0x46b8,
+ 0xc96e, 0x1e60,
+ 0xc96f, 0x46d5,
+ 0xc970, 0x2345,
+ 0xc971, 0x46d6,
+ 0xc977, 0x1f12,
+ 0xc978, 0x46dc,
+ 0xc980, 0x46e3,
+ 0xc98f, 0x2018,
+ 0xc990, 0x2335,
+ 0xc991, 0x46f2,
+ 0xc99c, 0x233c,
+ 0xc99d, 0x46fd,
+ 0xc9a1, 0x0cda,
+ 0xca40, 0x4701,
+ 0xca4e, 0x266f,
+ 0xca4f, 0x470f,
+ 0xca56, 0x2351,
+ 0xca57, 0x4716,
+ 0xca59, 0x1fa0,
+ 0xca5a, 0x4718,
+ 0xca5c, 0x2338,
+ 0xca5d, 0x471a,
+ 0xca61, 0x221b,
+ 0xca62, 0x471e,
+ 0xca6e, 0x2342,
+ 0xca6f, 0x472a,
+ 0xca72, 0x234f,
+ 0xca73, 0x472d,
+ 0xca77, 0x233d,
+ 0xca78, 0x4731,
+ 0xca7b, 0x2344,
+ 0xca7c, 0x2331,
+ 0xca7d, 0x4734,
+ 0xca7e, 0x234b,
+ 0xca80, 0x4735,
+ 0xca81, 0x233b,
+ 0xca82, 0x4736,
+ 0xca89, 0x2350,
+ 0xca8a, 0x473d,
+ 0xca8e, 0x1eb4,
+ 0xca8f, 0x21a6,
+ 0xca90, 0x4741,
+ 0xca92, 0x21cb,
+ 0xca93, 0x4743,
+ 0xca9a, 0x2355,
+ 0xca9b, 0x474a,
+ 0xcaa1, 0x0d38,
+ 0xcb40, 0x4750,
+ 0xcb43, 0x233e,
+ 0xcb44, 0x4753,
+ 0xcb45, 0x1f74,
+ 0xcb46, 0x4754,
+ 0xcb47, 0x2330,
+ 0xcb48, 0x4755,
+ 0xcb4b, 0x2680,
+ 0xcb4c, 0x4758,
+ 0xcb4e, 0x20da,
+ 0xcb4f, 0x475a,
+ 0xcb57, 0x234a,
+ 0xcb58, 0x4762,
+ 0xcb5d, 0x1f91,
+ 0xcb5e, 0x4767,
+ 0xcb5f, 0x2107,
+ 0xcb60, 0x4768,
+ 0xcb6a, 0x233f,
+ 0xcb6b, 0x4772,
+ 0xcb7b, 0x1ff4,
+ 0xcb7c, 0x2343,
+ 0xcb7d, 0x4782,
+ 0xcb80, 0x4784,
+ 0xcb87, 0x2212,
+ 0xcb88, 0x478b,
+ 0xcb8e, 0x2207,
+ 0xcb8f, 0x4791,
+ 0xcb92, 0x2359,
+ 0xcb93, 0x4794,
+ 0xcb9c, 0x2254,
+ 0xcb9d, 0x479d,
+ 0xcb9e, 0x2332,
+ 0xcb9f, 0x479e,
+ 0xcba1, 0x0d96,
+ 0xcc40, 0x1e26,
+ 0xcc41, 0x2357,
+ 0xcc42, 0x47a0,
+ 0xcc49, 0x2358,
+ 0xcc4a, 0x2042,
+ 0xcc4b, 0x2153,
+ 0xcc4c, 0x47a7,
+ 0xcc4f, 0x20bb,
+ 0xcc50, 0x47aa,
+ 0xcc5c, 0x235a,
+ 0xcc5d, 0x47b6,
+ 0xcc60, 0x2356,
+ 0xcc61, 0x47b9,
+ 0xcc64, 0x2337,
+ 0xcc65, 0x47bc,
+ 0xcc6d, 0x1ff9,
+ 0xcc6e, 0x47c4,
+ 0xcc79, 0x2353,
+ 0xcc7a, 0x47cf,
+ 0xcc7d, 0x2061,
+ 0xcc7e, 0x47d2,
+ 0xcc80, 0x47d3,
+ 0xcc8e, 0x1e95,
+ 0xcc8f, 0x47e1,
+ 0xcc94, 0x2049,
+ 0xcc95, 0x47e6,
+ 0xcc96, 0x1f42,
+ 0xcc97, 0x47e7,
+ 0xcc9d, 0x1fe8,
+ 0xcc9e, 0x47ed,
+ 0xcca1, 0x0df4,
+ 0xcd40, 0x47f0,
+ 0xcd80, 0x482f,
+ 0xcd90, 0x25da,
+ 0xcd91, 0x483f,
+ 0xcd98, 0x25d7,
+ 0xcd99, 0x4846,
+ 0xcda1, 0x0e52,
+ 0xce40, 0x484e,
+ 0xce67, 0x212e,
+ 0xce68, 0x4875,
+ 0xce72, 0x21b2,
+ 0xce73, 0x487f,
+ 0xce80, 0x488b,
+ 0xce81, 0x219e,
+ 0xce82, 0x488c,
+ 0xce87, 0x25dc,
+ 0xce88, 0x4891,
+ 0xce9b, 0x206c,
+ 0xce9c, 0x48a4,
+ 0xce9e, 0x2226,
+ 0xce9f, 0x48a6,
+ 0xcea1, 0x0eb0,
+ 0xcf40, 0x48a8,
+ 0xcf4e, 0x25e0,
+ 0xcf4f, 0x48b6,
+ 0xcf55, 0x227b,
+ 0xcf56, 0x48bc,
+ 0xcf58, 0x25de,
+ 0xcf59, 0x48be,
+ 0xcf5c, 0x25e1,
+ 0xcf5d, 0x48c1,
+ 0xcf6c, 0x25d5,
+ 0xcf6d, 0x48d0,
+ 0xcf73, 0x1e6b,
+ 0xcf74, 0x48d6,
+ 0xcf75, 0x25db,
+ 0xcf76, 0x48d7,
+ 0xcf78, 0x1e89,
+ 0xcf79, 0x48d9,
+ 0xcf7c, 0x25d9,
+ 0xcf7d, 0x48dc,
+ 0xcf80, 0x48de,
+ 0xcf81, 0x2211,
+ 0xcf82, 0x48df,
+ 0xcf89, 0x2229,
+ 0xcf8a, 0x25d6,
+ 0xcf8b, 0x48e6,
+ 0xcf93, 0x25dd,
+ 0xcf94, 0x25df,
+ 0xcf95, 0x48ee,
+ 0xcf9e, 0x1fef,
+ 0xcf9f, 0x48f7,
+ 0xcfa0, 0x25d8,
+ 0xcfa1, 0x0f0e,
+ 0xd040, 0x48f8,
+ 0xd04d, 0x1f29,
+ 0xd04e, 0x4905,
+ 0xd051, 0x1e5b,
+ 0xd052, 0x4908,
+ 0xd055, 0x2076,
+ 0xd056, 0x490b,
+ 0xd05c, 0x2297,
+ 0xd05d, 0x4911,
+ 0xd060, 0x2690,
+ 0xd061, 0x4914,
+ 0xd067, 0x213f,
+ 0xd068, 0x491a,
+ 0xd06c, 0x2198,
+ 0xd06d, 0x491e,
+ 0xd06e, 0x1e88,
+ 0xd06f, 0x491f,
+ 0xd07d, 0x228c,
+ 0xd07e, 0x492d,
+ 0xd080, 0x492e,
+ 0xd0a1, 0x0f6c,
+ 0xd140, 0x494f,
+ 0xd155, 0x25f1,
+ 0xd156, 0x4964,
+ 0xd159, 0x200c,
+ 0xd15a, 0x4967,
+ 0xd161, 0x1e58,
+ 0xd162, 0x22ac,
+ 0xd163, 0x496e,
+ 0xd175, 0x26a7,
+ 0xd176, 0x4980,
+ 0xd17d, 0x2676,
+ 0xd17e, 0x4987,
+ 0xd180, 0x4988,
+ 0xd19d, 0x1fe1,
+ 0xd19e, 0x25bb,
+ 0xd19f, 0x49a5,
+ 0xd1a1, 0x0fca,
+ 0xd240, 0x25be,
+ 0xd241, 0x49a7,
+ 0xd243, 0x22dd,
+ 0xd244, 0x49a9,
+ 0xd24d, 0x25bd,
+ 0xd24e, 0x49b2,
+ 0xd25c, 0x1e2a,
+ 0xd25d, 0x49c0,
+ 0xd263, 0x25bc,
+ 0xd264, 0x25ba,
+ 0xd265, 0x49c6,
+ 0xd268, 0x25bf,
+ 0xd269, 0x49c9,
+ 0xd26d, 0x2187,
+ 0xd26e, 0x49cd,
+ 0xd26f, 0x266b,
+ 0xd270, 0x49ce,
+ 0xd272, 0x1e7f,
+ 0xd273, 0x49d0,
+ 0xd275, 0x21ad,
+ 0xd276, 0x49d2,
+ 0xd280, 0x49db,
+ 0xd28a, 0x1f96,
+ 0xd28b, 0x49e5,
+ 0xd28e, 0x1f32,
+ 0xd28f, 0x49e8,
+ 0xd292, 0x2084,
+ 0xd293, 0x49eb,
+ 0xd295, 0x2136,
+ 0xd296, 0x49ed,
+ 0xd297, 0x24b8,
+ 0xd298, 0x49ee,
+ 0xd2a0, 0x24ba,
+ 0xd2a1, 0x1028,
+ 0xd340, 0x49f6,
+ 0xd344, 0x24bc,
+ 0xd345, 0x49fa,
+ 0xd348, 0x20e4,
+ 0xd349, 0x49fd,
+ 0xd34a, 0x24b9,
+ 0xd34b, 0x49fe,
+ 0xd34d, 0x24bd,
+ 0xd34e, 0x4a00,
+ 0xd350, 0x24be,
+ 0xd351, 0x4a02,
+ 0xd355, 0x24bf,
+ 0xd356, 0x4a06,
+ 0xd358, 0x1fd2,
+ 0xd359, 0x4a08,
+ 0xd35b, 0x1ffd,
+ 0xd35c, 0x4a0a,
+ 0xd35d, 0x24bb,
+ 0xd35e, 0x1f2d,
+ 0xd35f, 0x4a0b,
+ 0xd378, 0x2609,
+ 0xd379, 0x4a24,
+ 0xd37a, 0x260a,
+ 0xd37b, 0x4a25,
+ 0xd37c, 0x1e94,
+ 0xd37d, 0x4a26,
+ 0xd380, 0x4a28,
+ 0xd385, 0x22df,
+ 0xd386, 0x1ecb,
+ 0xd387, 0x1f0d,
+ 0xd388, 0x4a2d,
+ 0xd38b, 0x1f77,
+ 0xd38c, 0x4a30,
+ 0xd38d, 0x21eb,
+ 0xd38e, 0x4a31,
+ 0xd38f, 0x22e1,
+ 0xd390, 0x4a32,
+ 0xd391, 0x216f,
+ 0xd392, 0x4a33,
+ 0xd393, 0x22e0,
+ 0xd394, 0x4a34,
+ 0xd396, 0x21ea,
+ 0xd397, 0x4a36,
+ 0xd398, 0x22e2,
+ 0xd399, 0x20cb,
+ 0xd39a, 0x4a37,
+ 0xd39b, 0x1f78,
+ 0xd39c, 0x4a38,
+ 0xd39e, 0x1ee2,
+ 0xd39f, 0x4a3a,
+ 0xd3a0, 0x21f2,
+ 0xd3a1, 0x1086,
+ 0xd440, 0x4a3b,
+ 0xd441, 0x2150,
+ 0xd442, 0x4a3c,
+ 0xd445, 0x1fd3,
+ 0xd446, 0x4a3f,
+ 0xd447, 0x22e5,
+ 0xd448, 0x4a40,
+ 0xd44c, 0x1ef2,
+ 0xd44d, 0x4a44,
+ 0xd44f, 0x211f,
+ 0xd450, 0x4a46,
+ 0xd453, 0x21dd,
+ 0xd454, 0x4a49,
+ 0xd456, 0x2154,
+ 0xd457, 0x4a4b,
+ 0xd458, 0x22e7,
+ 0xd459, 0x4a4c,
+ 0xd45c, 0x2282,
+ 0xd45d, 0x4a4f,
+ 0xd462, 0x22e6,
+ 0xd463, 0x4a54,
+ 0xd467, 0x22e8,
+ 0xd468, 0x4a58,
+ 0xd46e, 0x22e4,
+ 0xd46f, 0x4a5e,
+ 0xd470, 0x226a,
+ 0xd471, 0x4a5f,
+ 0xd472, 0x22eb,
+ 0xd473, 0x4a60,
+ 0xd474, 0x22e9,
+ 0xd475, 0x20bd,
+ 0xd476, 0x4a61,
+ 0xd478, 0x22ea,
+ 0xd479, 0x4a63,
+ 0xd47b, 0x22bd,
+ 0xd47c, 0x4a65,
+ 0xd47e, 0x1e9e,
+ 0xd480, 0x4a67,
+ 0xd482, 0x22f6,
+ 0xd483, 0x21e7,
+ 0xd484, 0x2216,
+ 0xd485, 0x4a69,
+ 0xd487, 0x2137,
+ 0xd488, 0x4a6b,
+ 0xd48a, 0x212c,
+ 0xd48b, 0x4a6d,
+ 0xd48c, 0x1e68,
+ 0xd48d, 0x22f2,
+ 0xd48e, 0x1f37,
+ 0xd48f, 0x22f3,
+ 0xd490, 0x4a6e,
+ 0xd491, 0x22ef,
+ 0xd492, 0x1f50,
+ 0xd493, 0x1f10,
+ 0xd494, 0x21c8,
+ 0xd495, 0x4a6f,
+ 0xd496, 0x22f1,
+ 0xd497, 0x4a70,
+ 0xd49c, 0x22f0,
+ 0xd49d, 0x4a75,
+ 0xd49f, 0x22ee,
+ 0xd4a0, 0x4a77,
+ 0xd4a1, 0x10e4,
+ 0xd540, 0x4a78,
+ 0xd543, 0x22ed,
+ 0xd544, 0x229e,
+ 0xd545, 0x22ec,
+ 0xd546, 0x1fe2,
+ 0xd547, 0x4a7b,
+ 0xd54a, 0x20fe,
+ 0xd54b, 0x4a7e,
+ 0xd54e, 0x22f9,
+ 0xd550, 0x4a81,
+ 0xd551, 0x1eaf,
+ 0xd552, 0x4a82,
+ 0xd554, 0x2236,
+ 0xd555, 0x4a84,
+ 0xd556, 0x22f7,
+ 0xd557, 0x4a85,
+ 0xd55a, 0x223d,
+ 0xd55b, 0x4a88,
+ 0xd55c, 0x1e82,
+ 0xd55d, 0x1fb6,
+ 0xd55e, 0x4a89,
+ 0xd55f, 0x21a4,
+ 0xd560, 0x21aa,
+ 0xd561, 0x22f8,
+ 0xd562, 0x2151,
+ 0xd563, 0x4a8a,
+ 0xd564, 0x1f60,
+ 0xd565, 0x4a8b,
+ 0xd568, 0x2147,
+ 0xd569, 0x4a8e,
+ 0xd56c, 0x2145,
+ 0xd56d, 0x4a91,
+ 0xd56e, 0x1fdc,
+ 0xd56f, 0x4a92,
+ 0xd572, 0x2301,
+ 0xd573, 0x4a95,
+ 0xd575, 0x1ef5,
+ 0xd576, 0x4a97,
+ 0xd578, 0x2218,
+ 0xd579, 0x4a99,
+ 0xd57b, 0x1ec6,
+ 0xd57c, 0x4a9b,
+ 0xd57e, 0x2300,
+ 0xd580, 0x4a9d,
+ 0xd581, 0x22b4,
+ 0xd582, 0x4a9e,
+ 0xd584, 0x2169,
+ 0xd585, 0x4aa0,
+ 0xd586, 0x22fd,
+ 0xd587, 0x4aa1,
+ 0xd588, 0x20ea,
+ 0xd589, 0x4aa2,
+ 0xd58a, 0x22f4,
+ 0xd58b, 0x4aa3,
+ 0xd58c, 0x22fb,
+ 0xd58d, 0x4aa4,
+ 0xd58e, 0x22fc,
+ 0xd58f, 0x2027,
+ 0xd590, 0x4aa5,
+ 0xd593, 0x2060,
+ 0xd594, 0x22ff,
+ 0xd595, 0x4aa8,
+ 0xd598, 0x22fe,
+ 0xd599, 0x1ec7,
+ 0xd59a, 0x4aab,
+ 0xd59b, 0x230c,
+ 0xd59c, 0x4aac,
+ 0xd59f, 0x22f5,
+ 0xd5a0, 0x4aaf,
+ 0xd5a1, 0x1142,
+ 0xd640, 0x2306,
+ 0xd641, 0x4ab0,
+ 0xd642, 0x230a,
+ 0xd643, 0x21d3,
+ 0xd644, 0x4ab1,
+ 0xd647, 0x2303,
+ 0xd648, 0x4ab4,
+ 0xd649, 0x2307,
+ 0xd64a, 0x230b,
+ 0xd64b, 0x4ab5,
+ 0xd64d, 0x1f5f,
+ 0xd64e, 0x4ab7,
+ 0xd64f, 0x2309,
+ 0xd650, 0x4ab8,
+ 0xd652, 0x2302,
+ 0xd653, 0x1f04,
+ 0xd654, 0x229d,
+ 0xd655, 0x4aba,
+ 0xd656, 0x21fb,
+ 0xd657, 0x4abb,
+ 0xd658, 0x2308,
+ 0xd659, 0x4abc,
+ 0xd65a, 0x20ac,
+ 0xd65b, 0x4abd,
+ 0xd65c, 0x208e,
+ 0xd65d, 0x2305,
+ 0xd65e, 0x2197,
+ 0xd65f, 0x4abe,
+ 0xd660, 0x2171,
+ 0xd661, 0x2298,
+ 0xd662, 0x4abf,
+ 0xd665, 0x1f57,
+ 0xd666, 0x4ac2,
+ 0xd669, 0x2082,
+ 0xd66a, 0x4ac5,
+ 0xd66b, 0x2311,
+ 0xd66c, 0x4ac6,
+ 0xd66f, 0x2304,
+ 0xd670, 0x4ac9,
+ 0xd671, 0x230f,
+ 0xd672, 0x1e35,
+ 0xd673, 0x4aca,
+ 0xd674, 0x20d1,
+ 0xd675, 0x2310,
+ 0xd676, 0x1fa3,
+ 0xd677, 0x4acb,
+ 0xd678, 0x21d6,
+ 0xd679, 0x4acc,
+ 0xd67c, 0x2206,
+ 0xd67d, 0x4acf,
+ 0xd680, 0x4ad1,
+ 0xd683, 0x230d,
+ 0xd684, 0x4ad4,
+ 0xd686, 0x2312,
+ 0xd687, 0x208d,
+ 0xd688, 0x2313,
+ 0xd689, 0x4ad6,
+ 0xd68e, 0x22e3,
+ 0xd68f, 0x4adb,
+ 0xd694, 0x1fba,
+ 0xd695, 0x4ae0,
+ 0xd699, 0x2078,
+ 0xd69a, 0x4ae4,
+ 0xd6a1, 0x11a0,
+ 0xd740, 0x4aeb,
+ 0xd743, 0x2288,
+ 0xd744, 0x4aee,
+ 0xd748, 0x2316,
+ 0xd749, 0x1f6b,
+ 0xd74a, 0x4af2,
+ 0xd750, 0x2314,
+ 0xd751, 0x4af8,
+ 0xd752, 0x2130,
+ 0xd753, 0x2315,
+ 0xd754, 0x2168,
+ 0xd755, 0x4af9,
+ 0xd756, 0x20c4,
+ 0xd757, 0x4afa,
+ 0xd764, 0x2318,
+ 0xd765, 0x4b07,
+ 0xd767, 0x2219,
+ 0xd768, 0x2217,
+ 0xd769, 0x4b09,
+ 0xd76c, 0x20d5,
+ 0xd76d, 0x4b0c,
+ 0xd76f, 0x1f4a,
+ 0xd770, 0x4b0e,
+ 0xd775, 0x2240,
+ 0xd776, 0x4b13,
+ 0xd778, 0x1ed3,
+ 0xd779, 0x4b15,
+ 0xd780, 0x4b1b,
+ 0xd783, 0x1e49,
+ 0xd784, 0x4b1e,
+ 0xd787, 0x261b,
+ 0xd788, 0x4b21,
+ 0xd78b, 0x1e6d,
+ 0xd78c, 0x20f8,
+ 0xd78d, 0x4b24,
+ 0xd78e, 0x1ffb,
+ 0xd78f, 0x2319,
+ 0xd790, 0x4b25,
+ 0xd795, 0x230e,
+ 0xd796, 0x4b2a,
+ 0xd797, 0x2317,
+ 0xd798, 0x4b2b,
+ 0xd7a1, 0x11fe,
+ 0xd840, 0x4b34,
+ 0xd84d, 0x20c8,
+ 0xd84e, 0x4b41,
+ 0xd853, 0x1efd,
+ 0xd854, 0x4b46,
+ 0xd880, 0x4b71,
+ 0xd890, 0x1e3b,
+ 0xd891, 0x227f,
+ 0xd892, 0x4b81,
+ 0xd893, 0x1f0c,
+ 0xd894, 0x1e59,
+ 0xd895, 0x1f24,
+ 0xd896, 0x4b82,
+ 0xd89a, 0x20ba,
+ 0xd89b, 0x1f65,
+ 0xd89c, 0x1ef0,
+ 0xd89d, 0x2164,
+ 0xd89e, 0x1f30,
+ 0xd89f, 0x2261,
+ 0xd8a0, 0x4b86,
+ 0xd8a1, 0x1257,
+ 0xd940, 0x4b87,
+ 0xd941, 0x22a2,
+ 0xd942, 0x24ab,
+ 0xd943, 0x4b88,
+ 0xd944, 0x24af,
+ 0xd945, 0x1ee8,
+ 0xd946, 0x1f39,
+ 0xd947, 0x4b89,
+ 0xd948, 0x1e48,
+ 0xd949, 0x2070,
+ 0xd94a, 0x1ea8,
+ 0xd94b, 0x4b8a,
+ 0xd94c, 0x24ac,
+ 0xd94d, 0x1ef7,
+ 0xd94e, 0x2176,
+ 0xd94f, 0x24ad,
+ 0xd950, 0x4b8b,
+ 0xd951, 0x207b,
+ 0xd952, 0x1f45,
+ 0xd953, 0x24aa,
+ 0xd954, 0x204b,
+ 0xd955, 0x202f,
+ 0xd956, 0x1f5a,
+ 0xd957, 0x24b0,
+ 0xd958, 0x4b8c,
+ 0xd959, 0x22b7,
+ 0xd95a, 0x1f7f,
+ 0xd95b, 0x4b8d,
+ 0xd95c, 0x2265,
+ 0xd95d, 0x4b8e,
+ 0xd963, 0x24b2,
+ 0xd964, 0x211b,
+ 0xd965, 0x1e51,
+ 0xd966, 0x4b94,
+ 0xd967, 0x24b4,
+ 0xd968, 0x4b95,
+ 0xd96c, 0x24b3,
+ 0xd96d, 0x4b99,
+ 0xd96e, 0x1e9f,
+ 0xd96f, 0x4b9a,
+ 0xd970, 0x2118,
+ 0xd971, 0x4b9b,
+ 0xd972, 0x20b4,
+ 0xd973, 0x23af,
+ 0xd974, 0x21bb,
+ 0xd975, 0x2072,
+ 0xd976, 0x1f95,
+ 0xd977, 0x4b9c,
+ 0xd978, 0x1f0a,
+ 0xd979, 0x24b6,
+ 0xd97a, 0x4b9d,
+ 0xd97c, 0x2291,
+ 0xd97d, 0x24b5,
+ 0xd97e, 0x2278,
+ 0xd980, 0x1ed4,
+ 0xd981, 0x4b9f,
+ 0xd987, 0x1ff3,
+ 0xd988, 0x4ba5,
+ 0xd98d, 0x22a9,
+ 0xd98e, 0x24b7,
+ 0xd98f, 0x1f28,
+ 0xd990, 0x2109,
+ 0xd991, 0x22c7,
+ 0xd992, 0x4baa,
+ 0xd997, 0x24ae,
+ 0xd998, 0x22b1,
+ 0xd999, 0x4baf,
+ 0xd99b, 0x2266,
+ 0xd99c, 0x4bb1,
+ 0xd99d, 0x225b,
+ 0xd99e, 0x22c4,
+ 0xd99f, 0x4bb2,
+ 0xd9a0, 0x2115,
+ 0xd9a1, 0x12b5,
+ 0xda40, 0x4bb3,
+ 0xda41, 0x222a,
+ 0xda42, 0x24b1,
+ 0xda43, 0x4bb4,
+ 0xda48, 0x213d,
+ 0xda49, 0x4bb9,
+ 0xda4d, 0x1f15,
+ 0xda4e, 0x225c,
+ 0xda4f, 0x4bbd,
+ 0xda73, 0x1f14,
+ 0xda74, 0x4be1,
+ 0xda77, 0x227a,
+ 0xda78, 0x4be4,
+ 0xda80, 0x4beb,
+ 0xda85, 0x20ee,
+ 0xda86, 0x4bf0,
+ 0xda8e, 0x25f8,
+ 0xda8f, 0x4bf8,
+ 0xdaa1, 0x1313,
+ 0xdb40, 0x4c0a,
+ 0xdb60, 0x1f94,
+ 0xdb61, 0x4c2a,
+ 0xdb78, 0x2230,
+ 0xdb79, 0x4c41,
+ 0xdb80, 0x4c47,
+ 0xdb84, 0x25fd,
+ 0xdb85, 0x4c4b,
+ 0xdb8b, 0x2600,
+ 0xdb8c, 0x4c51,
+ 0xdb98, 0x2606,
+ 0xdb99, 0x4c5d,
+ 0xdba1, 0x1371,
+ 0xdc40, 0x4c65,
+ 0xdc45, 0x25ff,
+ 0xdc46, 0x4c6a,
+ 0xdc4f, 0x25fc,
+ 0xdc50, 0x1e8c,
+ 0xdc51, 0x2602,
+ 0xdc52, 0x4c73,
+ 0xdc53, 0x224d,
+ 0xdc54, 0x4c74,
+ 0xdc55, 0x2604,
+ 0xdc56, 0x25fe,
+ 0xdc57, 0x2603,
+ 0xdc58, 0x4c75,
+ 0xdc5d, 0x2601,
+ 0xdc5e, 0x4c7a,
+ 0xdc62, 0x2605,
+ 0xdc63, 0x4c7e,
+ 0xdc66, 0x1ea3,
+ 0xdc67, 0x2608,
+ 0xdc68, 0x4c81,
+ 0xdc6b, 0x2607,
+ 0xdc6c, 0x4c84,
+ 0xdc7c, 0x20f0,
+ 0xdc7d, 0x4c94,
+ 0xdc80, 0x4c96,
+ 0xdc87, 0x1e7b,
+ 0xdc88, 0x2267,
+ 0xdc89, 0x1f36,
+ 0xdc8a, 0x1fd6,
+ 0xdc8b, 0x4c9d,
+ 0xdc8e, 0x21e0,
+ 0xdc8f, 0x4ca0,
+ 0xdc90, 0x248c,
+ 0xdc91, 0x4ca1,
+ 0xdc97, 0x248d,
+ 0xdc98, 0x4ca7,
+ 0xdc9b, 0x2102,
+ 0xdc9c, 0x4caa,
+ 0xdca0, 0x2494,
+ 0xdca1, 0x13cf,
+ 0xdd40, 0x4cae,
+ 0xdd46, 0x2493,
+ 0xdd47, 0x4cb4,
+ 0xdd4d, 0x248e,
+ 0xdd4e, 0x4cba,
+ 0xdd53, 0x2299,
+ 0xdd54, 0x2491,
+ 0xdd55, 0x2496,
+ 0xdd56, 0x248f,
+ 0xdd57, 0x2492,
+ 0xdd58, 0x4cbf,
+ 0xdd59, 0x2497,
+ 0xdd5a, 0x4cc0,
+ 0xdd5e, 0x1fb1,
+ 0xdd5f, 0x4cc4,
+ 0xdd60, 0x249a,
+ 0xdd61, 0x4cc5,
+ 0xdd62, 0x2499,
+ 0xdd63, 0x4cc6,
+ 0xdd64, 0x2258,
+ 0xdd65, 0x2498,
+ 0xdd66, 0x4cc7,
+ 0xdd6d, 0x249b,
+ 0xdd6e, 0x4cce,
+ 0xdd6f, 0x1f09,
+ 0xdd70, 0x20e6,
+ 0xdd71, 0x4ccf,
+ 0xdd76, 0x2026,
+ 0xdd77, 0x249f,
+ 0xdd78, 0x1f59,
+ 0xdd79, 0x249d,
+ 0xdd7b, 0x4cd4,
+ 0xdd80, 0x4cd8,
+ 0xdd81, 0x1f3b,
+ 0xdd82, 0x249c,
+ 0xdd83, 0x4cd9,
+ 0xdd85, 0x1e3a,
+ 0xdd86, 0x205b,
+ 0xdd87, 0x4cdb,
+ 0xdd8b, 0x1f70,
+ 0xdd8c, 0x4cdf,
+ 0xdd8f, 0x24a0,
+ 0xdd90, 0x4ce2,
+ 0xdd94, 0x213b,
+ 0xdd95, 0x4ce6,
+ 0xdd97, 0x1f07,
+ 0xdd98, 0x4ce8,
+ 0xdd9a, 0x2270,
+ 0xdd9b, 0x2237,
+ 0xdd9c, 0x4cea,
+ 0xdd9e, 0x24d2,
+ 0xdd9f, 0x4cec,
+ 0xdda0, 0x21b3,
+ 0xdda1, 0x142d,
+ 0xde40, 0x2245,
+ 0xde41, 0x24a1,
+ 0xde42, 0x4ced,
+ 0xde44, 0x22a8,
+ 0xde45, 0x4cef,
+ 0xde48, 0x227c,
+ 0xde49, 0x1fb0,
+ 0xde4a, 0x4cf2,
+ 0xde4f, 0x24a2,
+ 0xde50, 0x4cf7,
+ 0xde5a, 0x1f46,
+ 0xde5b, 0x4d01,
+ 0xde5c, 0x2380,
+ 0xde5d, 0x2495,
+ 0xde5e, 0x4d02,
+ 0xde5f, 0x2490,
+ 0xde60, 0x4d03,
+ 0xde6b, 0x1e30,
+ 0xde6c, 0x4d0e,
+ 0xde6f, 0x1e9d,
+ 0xde70, 0x1e4b,
+ 0xde71, 0x1e4a,
+ 0xde72, 0x20aa,
+ 0xde73, 0x4d11,
+ 0xde80, 0x4d1d,
+ 0xde92, 0x267b,
+ 0xde93, 0x4d2f,
+ 0xde9f, 0x23f2,
+ 0xdea0, 0x4d3b,
+ 0xdea1, 0x148b,
+ 0xdf40, 0x227e,
+ 0xdf41, 0x4d3c,
+ 0xdf42, 0x2019,
+ 0xdf43, 0x4d3d,
+ 0xdf4d, 0x1fbb,
+ 0xdf4e, 0x4d47,
+ 0xdf5c, 0x2253,
+ 0xdf5d, 0x4d55,
+ 0xdf5e, 0x1f3e,
+ 0xdf5f, 0x1ea6,
+ 0xdf60, 0x218e,
+ 0xdf61, 0x4d56,
+ 0xdf64, 0x21ec,
+ 0xdf65, 0x4d59,
+ 0xdf66, 0x1ebe,
+ 0xdf67, 0x4d5a,
+ 0xdf68, 0x224a,
+ 0xdf69, 0x4d5b,
+ 0xdf6d, 0x2133,
+ 0xdf6e, 0x4d5f,
+ 0xdf74, 0x1e84,
+ 0xdf75, 0x4d65,
+ 0xdf77, 0x20cf,
+ 0xdf78, 0x21e2,
+ 0xdf79, 0x4d67,
+ 0xdf7a, 0x220f,
+ 0xdf7b, 0x4d68,
+ 0xdf7c, 0x2029,
+ 0xdf7d, 0x4d69,
+ 0xdf7e, 0x2073,
+ 0xdf80, 0x1f55,
+ 0xdf81, 0x4d6a,
+ 0xdf83, 0x23f1,
+ 0xdf84, 0x4d6c,
+ 0xdf85, 0x1e46,
+ 0xdf86, 0x4d6d,
+ 0xdf89, 0x2063,
+ 0xdf8a, 0x23f3,
+ 0xdf8b, 0x4d70,
+ 0xdfa1, 0x14e9,
+ 0xe040, 0x4d86,
+ 0xe050, 0x231e,
+ 0xe051, 0x4d96,
+ 0xe05d, 0x2233,
+ 0xe05e, 0x4da2,
+ 0xe069, 0x2320,
+ 0xe06a, 0x4dad,
+ 0xe06c, 0x21c7,
+ 0xe06d, 0x4daf,
+ 0xe075, 0x22bc,
+ 0xe076, 0x4db7,
+ 0xe077, 0x231c,
+ 0xe078, 0x4db8,
+ 0xe079, 0x2251,
+ 0xe07a, 0x4db9,
+ 0xe080, 0x4dbe,
+ 0xe087, 0x1ebb,
+ 0xe088, 0x4dc5,
+ 0xe08d, 0x2287,
+ 0xe08e, 0x4dca,
+ 0xe08f, 0x202d,
+ 0xe090, 0x1eab,
+ 0xe091, 0x4dcb,
+ 0xe092, 0x231d,
+ 0xe093, 0x4dcc,
+ 0xe094, 0x231f,
+ 0xe095, 0x4dcd,
+ 0xe097, 0x231b,
+ 0xe098, 0x4dcf,
+ 0xe0a1, 0x1547,
+ 0xe140, 0x4dd8,
+ 0xe142, 0x2321,
+ 0xe143, 0x4dda,
+ 0xe164, 0x2255,
+ 0xe165, 0x4dfb,
+ 0xe168, 0x1e8f,
+ 0xe169, 0x4dfe,
+ 0xe174, 0x220c,
+ 0xe175, 0x1fa4,
+ 0xe176, 0x4e09,
+ 0xe180, 0x4e12,
+ 0xe184, 0x209b,
+ 0xe185, 0x21d8,
+ 0xe186, 0x4e16,
+ 0xe187, 0x25fa,
+ 0xe188, 0x4e17,
+ 0xe189, 0x25f9,
+ 0xe18a, 0x4e18,
+ 0xe18c, 0x2134,
+ 0xe18d, 0x4e1a,
+ 0xe18e, 0x24f3,
+ 0xe191, 0x24f8,
+ 0xe192, 0x4e1b,
+ 0xe193, 0x24f7,
+ 0xe194, 0x1ec8,
+ 0xe195, 0x24f6,
+ 0xe196, 0x4e1c,
+ 0xe198, 0x2280,
+ 0xe199, 0x4e1e,
+ 0xe19e, 0x1ec5,
+ 0xe19f, 0x24fb,
+ 0xe1a0, 0x4e23,
+ 0xe1a1, 0x15a5,
+ 0xe240, 0x4e24,
+ 0xe241, 0x24fa,
+ 0xe242, 0x4e25,
+ 0xe243, 0x1eed,
+ 0xe244, 0x4e26,
+ 0xe24f, 0x24fd,
+ 0xe250, 0x4e31,
+ 0xe251, 0x24f9,
+ 0xe252, 0x4e32,
+ 0xe253, 0x24fe,
+ 0xe254, 0x20cd,
+ 0xe255, 0x4e33,
+ 0xe25a, 0x2508,
+ 0xe25b, 0x2504,
+ 0xe25c, 0x4e38,
+ 0xe25e, 0x2506,
+ 0xe25f, 0x4e3a,
+ 0xe262, 0x24ff,
+ 0xe263, 0x2090,
+ 0xe264, 0x4e3d,
+ 0xe267, 0x1edd,
+ 0xe268, 0x1f25,
+ 0xe269, 0x4e40,
+ 0xe26a, 0x2503,
+ 0xe26b, 0x2502,
+ 0xe26c, 0x4e41,
+ 0xe26e, 0x1e7a,
+ 0xe26f, 0x20a6,
+ 0xe270, 0x4e43,
+ 0xe278, 0x1fd5,
+ 0xe279, 0x4e4b,
+ 0xe27d, 0x1f11,
+ 0xe27e, 0x4e4f,
+ 0xe280, 0x2507,
+ 0xe281, 0x2500,
+ 0xe282, 0x2505,
+ 0xe283, 0x4e50,
+ 0xe289, 0x2519,
+ 0xe28a, 0x4e56,
+ 0xe28b, 0x2515,
+ 0xe28c, 0x4e57,
+ 0xe28e, 0x250c,
+ 0xe28f, 0x2031,
+ 0xe290, 0x4e59,
+ 0xe292, 0x250b,
+ 0xe293, 0x250f,
+ 0xe294, 0x251a,
+ 0xe295, 0x2509,
+ 0xe296, 0x4e5b,
+ 0xe298, 0x250e,
+ 0xe299, 0x2234,
+ 0xe29a, 0x2513,
+ 0xe29b, 0x1f80,
+ 0xe29c, 0x4e5d,
+ 0xe2a0, 0x2501,
+ 0xe2a1, 0x1603,
+ 0xe340, 0x4e61,
+ 0xe342, 0x2517,
+ 0xe343, 0x2516,
+ 0xe344, 0x4e63,
+ 0xe347, 0x2518,
+ 0xe348, 0x4e66,
+ 0xe34b, 0x1e56,
+ 0xe34c, 0x4e69,
+ 0xe34f, 0x250d,
+ 0xe350, 0x4e6c,
+ 0xe351, 0x20d3,
+ 0xe352, 0x4e6d,
+ 0xe354, 0x207a,
+ 0xe355, 0x20ce,
+ 0xe356, 0x4e6f,
+ 0xe358, 0x2510,
+ 0xe359, 0x4e71,
+ 0xe35c, 0x1e55,
+ 0xe35d, 0x4e74,
+ 0xe360, 0x250a,
+ 0xe361, 0x4e77,
+ 0xe366, 0x2511,
+ 0xe368, 0x4e7c,
+ 0xe371, 0x1faa,
+ 0xe372, 0x4e85,
+ 0xe373, 0x251e,
+ 0xe374, 0x1f1f,
+ 0xe375, 0x4e86,
+ 0xe378, 0x252d,
+ 0xe379, 0x221d,
+ 0xe37a, 0x4e89,
+ 0xe37c, 0x2532,
+ 0xe37d, 0x4e8b,
+ 0xe37e, 0x217b,
+ 0xe380, 0x4e8c,
+ 0xe38a, 0x21af,
+ 0xe38b, 0x4e96,
+ 0xe38c, 0x252c,
+ 0xe38d, 0x4e97,
+ 0xe38f, 0x2528,
+ 0xe390, 0x4e99,
+ 0xe391, 0x208c,
+ 0xe392, 0x4e9a,
+ 0xe393, 0x252f,
+ 0xe394, 0x4e9b,
+ 0xe395, 0x21bc,
+ 0xe396, 0x4e9c,
+ 0xe399, 0x251d,
+ 0xe39a, 0x4e9f,
+ 0xe39c, 0x2535,
+ 0xe39d, 0x4ea1,
+ 0xe39e, 0x220d,
+ 0xe39f, 0x2526,
+ 0xe3a0, 0x4ea2,
+ 0xe3a1, 0x1661,
+ 0xe440, 0x2534,
+ 0xe441, 0x252a,
+ 0xe442, 0x251f,
+ 0xe443, 0x2531,
+ 0xe444, 0x251c,
+ 0xe445, 0x4ea3,
+ 0xe448, 0x2525,
+ 0xe449, 0x4ea6,
+ 0xe44e, 0x21cd,
+ 0xe44f, 0x4eab,
+ 0xe450, 0x21da,
+ 0xe451, 0x4eac,
+ 0xe452, 0x2172,
+ 0xe453, 0x253e,
+ 0xe454, 0x4ead,
+ 0xe458, 0x204f,
+ 0xe459, 0x4eb1,
+ 0xe45a, 0x2543,
+ 0xe45b, 0x4eb2,
+ 0xe45c, 0x21d7,
+ 0xe45d, 0x4eb3,
+ 0xe45e, 0x1e3c,
+ 0xe45f, 0x4eb4,
+ 0xe462, 0x2529,
+ 0xe463, 0x4eb7,
+ 0xe465, 0x2521,
+ 0xe466, 0x4eb9,
+ 0xe468, 0x1eff,
+ 0xe469, 0x4ebb,
+ 0xe473, 0x253f,
+ 0xe474, 0x4ec5,
+ 0xe475, 0x2544,
+ 0xe476, 0x4ec6,
+ 0xe479, 0x2523,
+ 0xe47a, 0x1e90,
+ 0xe47b, 0x253a,
+ 0xe47c, 0x2545,
+ 0xe47d, 0x4ec9,
+ 0xe47e, 0x253d,
+ 0xe480, 0x4eca,
+ 0xe481, 0x20c1,
+ 0xe482, 0x4ecb,
+ 0xe484, 0x2103,
+ 0xe485, 0x2520,
+ 0xe486, 0x253c,
+ 0xe487, 0x253b,
+ 0xe488, 0x2538,
+ 0xe489, 0x4ecd,
+ 0xe48d, 0x2540,
+ 0xe48e, 0x4ed1,
+ 0xe48f, 0x1fcd,
+ 0xe490, 0x4ed2,
+ 0xe493, 0x1f18,
+ 0xe494, 0x4ed5,
+ 0xe498, 0x254b,
+ 0xe499, 0x4ed9,
+ 0xe49d, 0x2547,
+ 0xe49e, 0x254f,
+ 0xe4a0, 0x4edd,
+ 0xe4a1, 0x16bf,
+ 0xe540, 0x4ede,
+ 0xe546, 0x22b0,
+ 0xe547, 0x4ee4,
+ 0xe548, 0x2546,
+ 0xe549, 0x4ee5,
+ 0xe54b, 0x254c,
+ 0xe54c, 0x4ee7,
+ 0xe54e, 0x1e9a,
+ 0xe54f, 0x2552,
+ 0xe550, 0x2530,
+ 0xe551, 0x2549,
+ 0xe552, 0x4ee9,
+ 0xe555, 0x2551,
+ 0xe556, 0x1eca,
+ 0xe557, 0x4eec,
+ 0xe558, 0x20d2,
+ 0xe559, 0x4eed,
+ 0xe55c, 0x1fb8,
+ 0xe55d, 0x4ef0,
+ 0xe55e, 0x2079,
+ 0xe55f, 0x4ef1,
+ 0xe561, 0x21ab,
+ 0xe562, 0x4ef3,
+ 0xe564, 0x254d,
+ 0xe565, 0x1ea5,
+ 0xe566, 0x4ef5,
+ 0xe568, 0x204c,
+ 0xe569, 0x2080,
+ 0xe56a, 0x4ef7,
+ 0xe56c, 0x266d,
+ 0xe56d, 0x4ef9,
+ 0xe56e, 0x2537,
+ 0xe56f, 0x4efa,
+ 0xe575, 0x254a,
+ 0xe576, 0x21b8,
+ 0xe577, 0x4f00,
+ 0xe578, 0x254e,
+ 0xe579, 0x4f01,
+ 0xe57b, 0x24fc,
+ 0xe57c, 0x2554,
+ 0xe57d, 0x4f03,
+ 0xe580, 0x4f05,
+ 0xe581, 0x1f3c,
+ 0xe582, 0x4f06,
+ 0xe583, 0x1ed5,
+ 0xe584, 0x4f07,
+ 0xe58a, 0x2556,
+ 0xe58b, 0x4f0d,
+ 0xe58e, 0x2268,
+ 0xe58f, 0x4f10,
+ 0xe591, 0x1ed6,
+ 0xe592, 0x4f12,
+ 0xe59a, 0x2557,
+ 0xe59b, 0x2553,
+ 0xe59c, 0x4f1a,
+ 0xe59f, 0x2548,
+ 0xe5a0, 0x4f1d,
+ 0xe5a1, 0x171d,
+ 0xe640, 0x20dc,
+ 0xe641, 0x4f1e,
+ 0xe644, 0x2559,
+ 0xe645, 0x4f21,
+ 0xe649, 0x1f97,
+ 0xe64a, 0x2555,
+ 0xe64b, 0x4f25,
+ 0xe64e, 0x227d,
+ 0xe64f, 0x4f28,
+ 0xe652, 0x257e,
+ 0xe653, 0x4f2b,
+ 0xe656, 0x207c,
+ 0xe657, 0x4f2e,
+ 0xe658, 0x255a,
+ 0xe659, 0x4f2f,
+ 0xe65b, 0x255e,
+ 0xe65c, 0x4f31,
+ 0xe65e, 0x1e34,
+ 0xe65f, 0x4f33,
+ 0xe669, 0x215e,
+ 0xe66a, 0x4f3d,
+ 0xe66b, 0x2560,
+ 0xe66c, 0x4f3e,
+ 0xe675, 0x21a2,
+ 0xe676, 0x2354,
+ 0xe677, 0x4f47,
+ 0xe679, 0x2563,
+ 0xe67a, 0x2527,
+ 0xe67b, 0x4f49,
+ 0xe67c, 0x252e,
+ 0xe67d, 0x2558,
+ 0xe67e, 0x4f4a,
+ 0xe680, 0x1f1b,
+ 0xe681, 0x4f4b,
+ 0xe682, 0x2283,
+ 0xe683, 0x4f4c,
+ 0xe684, 0x2564,
+ 0xe685, 0x4f4d,
+ 0xe687, 0x20a0,
+ 0xe688, 0x4f4f,
+ 0xe689, 0x2565,
+ 0xe68a, 0x4f50,
+ 0xe68c, 0x2561,
+ 0xe68d, 0x4f52,
+ 0xe693, 0x2562,
+ 0xe694, 0x4f58,
+ 0xe697, 0x256c,
+ 0xe698, 0x4f5b,
+ 0xe69b, 0x256d,
+ 0xe69c, 0x2020,
+ 0xe69d, 0x4f5e,
+ 0xe69f, 0x255f,
+ 0xe6a0, 0x256a,
+ 0xe6a1, 0x177b,
+ 0xe740, 0x4f60,
+ 0xe743, 0x256e,
+ 0xe744, 0x4f63,
+ 0xe748, 0x2539,
+ 0xe749, 0x255c,
+ 0xe74a, 0x4f67,
+ 0xe74d, 0x2568,
+ 0xe74f, 0x256b,
+ 0xe750, 0x1e6f,
+ 0xe751, 0x4f6a,
+ 0xe752, 0x1fc4,
+ 0xe753, 0x2567,
+ 0xe754, 0x4f6b,
+ 0xe755, 0x255b,
+ 0xe756, 0x4f6c,
+ 0xe759, 0x261d,
+ 0xe75a, 0x4f6f,
+ 0xe766, 0x252b,
+ 0xe767, 0x4f7b,
+ 0xe768, 0x2571,
+ 0xe769, 0x4f7c,
+ 0xe76a, 0x2577,
+ 0xe76b, 0x4f7d,
+ 0xe774, 0x2522,
+ 0xe775, 0x4f86,
+ 0xe77c, 0x2533,
+ 0xe77d, 0x4f8d,
+ 0xe780, 0x4f8f,
+ 0xe782, 0x202a,
+ 0xe783, 0x4f91,
+ 0xe784, 0x2536,
+ 0xe785, 0x2573,
+ 0xe786, 0x256f,
+ 0xe787, 0x4f92,
+ 0xe78a, 0x2293,
+ 0xe78b, 0x2578,
+ 0xe78c, 0x4f95,
+ 0xe78f, 0x2570,
+ 0xe790, 0x4f98,
+ 0xe792, 0x2575,
+ 0xe793, 0x4f9a,
+ 0xe798, 0x2541,
+ 0xe79a, 0x255d,
+ 0xe79b, 0x4f9f,
+ 0xe7a0, 0x201a,
+ 0xe7a1, 0x17d9,
+ 0xe840, 0x4fa4,
+ 0xe843, 0x257a,
+ 0xe844, 0x2006,
+ 0xe845, 0x4fa7,
+ 0xe846, 0x2177,
+ 0xe847, 0x4fa8,
+ 0xe849, 0x251b,
+ 0xe84a, 0x4faa,
+ 0xe84b, 0x2524,
+ 0xe84c, 0x4fab,
+ 0xe84f, 0x257b,
+ 0xe850, 0x4fae,
+ 0xe854, 0x22a3,
+ 0xe855, 0x4fb2,
+ 0xe85a, 0x2579,
+ 0xe85b, 0x4fb7,
+ 0xe85c, 0x2566,
+ 0xe85d, 0x4fb8,
+ 0xe862, 0x1f93,
+ 0xe863, 0x4fbd,
+ 0xe864, 0x257c,
+ 0xe865, 0x4fbe,
+ 0xe870, 0x2514,
+ 0xe871, 0x4fc9,
+ 0xe873, 0x257d,
+ 0xe874, 0x4fcb,
+ 0xe875, 0x2572,
+ 0xe876, 0x4fcc,
+ 0xe87c, 0x2574,
+ 0xe87d, 0x4fd2,
+ 0xe880, 0x224e,
+ 0xe881, 0x4fd4,
+ 0xe882, 0x21c6,
+ 0xe883, 0x4fd5,
+ 0xe887, 0x209f,
+ 0xe888, 0x4fd9,
+ 0xe889, 0x2576,
+ 0xe88a, 0x4fda,
+ 0xe88c, 0x2064,
+ 0xe88d, 0x22bf,
+ 0xe88e, 0x261c,
+ 0xe88f, 0x225e,
+ 0xe890, 0x4fdc,
+ 0xe8a1, 0x1837,
+ 0xe940, 0x4fed,
+ 0xe94c, 0x1e75,
+ 0xe94d, 0x4ff9,
+ 0xe954, 0x207d,
+ 0xe955, 0x5000,
+ 0xe956, 0x23bf,
+ 0xe957, 0x2113,
+ 0xe958, 0x5001,
+ 0xe95a, 0x23c0,
+ 0xe95b, 0x5003,
+ 0xe95d, 0x1e45,
+ 0xe95e, 0x5005,
+ 0xe95f, 0x1fd8,
+ 0xe960, 0x23c4,
+ 0xe961, 0x5006,
+ 0xe962, 0x23c2,
+ 0xe963, 0x2104,
+ 0xe964, 0x5007,
+ 0xe965, 0x21bd,
+ 0xe966, 0x5008,
+ 0xe967, 0x1f87,
+ 0xe968, 0x23c3,
+ 0xe969, 0x5009,
+ 0xe96c, 0x2269,
+ 0xe96d, 0x500c,
+ 0xe975, 0x1f43,
+ 0xe976, 0x5014,
+ 0xe977, 0x1f1e,
+ 0xe978, 0x2679,
+ 0xe979, 0x1eeb,
+ 0xe97a, 0x5015,
+ 0xe97c, 0x1f35,
+ 0xe97d, 0x208a,
+ 0xe97e, 0x5017,
+ 0xe980, 0x23c7,
+ 0xe981, 0x23c9,
+ 0xe982, 0x23c6,
+ 0xe983, 0x5018,
+ 0xe987, 0x224f,
+ 0xe988, 0x501c,
+ 0xe98b, 0x23cb,
+ 0xe98c, 0x501f,
+ 0xe98e, 0x21f3,
+ 0xe98f, 0x5021,
+ 0xe990, 0x21f7,
+ 0xe991, 0x23cf,
+ 0xe992, 0x23ce,
+ 0xe993, 0x23ca,
+ 0xe994, 0x23cd,
+ 0xe995, 0x5022,
+ 0xe998, 0x23d0,
+ 0xe999, 0x5025,
+ 0xe99b, 0x266c,
+ 0xe99c, 0x5027,
+ 0xe99d, 0x23c1,
+ 0xe99e, 0x5028,
+ 0xe99f, 0x1fee,
+ 0xe9a0, 0x23d1,
+ 0xe9a1, 0x1895,
+ 0xea40, 0x1ff8,
+ 0xea41, 0x5029,
+ 0xea44, 0x23d3,
+ 0xea45, 0x502c,
+ 0xea48, 0x23d2,
+ 0xea49, 0x23d4,
+ 0xea4a, 0x1e98,
+ 0xea4b, 0x502f,
+ 0xea50, 0x1f2c,
+ 0xea51, 0x5034,
+ 0xea52, 0x23d5,
+ 0xea53, 0x5035,
+ 0xea55, 0x1e71,
+ 0xea56, 0x2691,
+ 0xea57, 0x5037,
+ 0xea59, 0x23c5,
+ 0xea5a, 0x5039,
+ 0xea80, 0x231a,
+ 0xea81, 0x505e,
+ 0xea84, 0x2114,
+ 0xea85, 0x5061,
+ 0xea87, 0x2284,
+ 0xea88, 0x5063,
+ 0xea8e, 0x221c,
+ 0xea8f, 0x5069,
+ 0xea90, 0x1e7e,
+ 0xea91, 0x204d,
+ 0xea92, 0x506a,
+ 0xea96, 0x2201,
+ 0xea97, 0x506e,
+ 0xeaa0, 0x1ed9,
+ 0xeaa1, 0x18f3,
+ 0xeb40, 0x5077,
+ 0xeb41, 0x1fb2,
+ 0xeb42, 0x5078,
+ 0xeb45, 0x2252,
+ 0xeb46, 0x507b,
+ 0xeb48, 0x1f79,
+ 0xeb49, 0x507d,
+ 0xeb53, 0x2157,
+ 0xeb54, 0x5087,
+ 0xeb55, 0x21bf,
+ 0xeb56, 0x5088,
+ 0xeb5b, 0x221f,
+ 0xeb5c, 0x508d,
+ 0xeb5d, 0x203d,
+ 0xeb5e, 0x508e,
+ 0xeb60, 0x2015,
+ 0xeb61, 0x5090,
+ 0xeb62, 0x26a5,
+ 0xeb63, 0x5091,
+ 0xeb6d, 0x2156,
+ 0xeb6e, 0x509b,
+ 0xeb70, 0x2144,
+ 0xeb71, 0x509d,
+ 0xeb72, 0x1e91,
+ 0xeb73, 0x2257,
+ 0xeb74, 0x509e,
+ 0xeb78, 0x200a,
+ 0xeb79, 0x2092,
+ 0xeb7a, 0x50a2,
+ 0xeb80, 0x50a7,
+ 0xeb85, 0x2250,
+ 0xeb86, 0x50ac,
+ 0xeb8a, 0x1ec3,
+ 0xeb8b, 0x50b0,
+ 0xeba1, 0x1951,
+ 0xec40, 0x50c6,
+ 0xec46, 0x21a8,
+ 0xec47, 0x50cc,
+ 0xec56, 0x260d,
+ 0xec57, 0x50db,
+ 0xec5a, 0x260c,
+ 0xec5b, 0x50de,
+ 0xec5c, 0x260e,
+ 0xec5d, 0x50df,
+ 0xec60, 0x2032,
+ 0xec61, 0x50e2,
+ 0xec6e, 0x260b,
+ 0xec6f, 0x50ef,
+ 0xec76, 0x22c3,
+ 0xec77, 0x50f6,
+ 0xec80, 0x50fe,
+ 0xec96, 0x1f23,
+ 0xec97, 0x5114,
+ 0xeca1, 0x19af,
+ 0xed40, 0x511e,
+ 0xed46, 0x2695,
+ 0xed47, 0x5124,
+ 0xed58, 0x265e,
+ 0xed59, 0x5135,
+ 0xed5e, 0x265d,
+ 0xed5f, 0x513a,
+ 0xed61, 0x2692,
+ 0xed62, 0x513c,
+ 0xed64, 0x265f,
+ 0xed65, 0x513e,
+ 0xed66, 0x218d,
+ 0xed67, 0x20fd,
+ 0xed68, 0x513f,
+ 0xed6e, 0x1f40,
+ 0xed6f, 0x5145,
+ 0xed74, 0x2465,
+ 0xed75, 0x514a,
+ 0xed77, 0x2467,
+ 0xed78, 0x514c,
+ 0xed79, 0x2466,
+ 0xed7a, 0x514d,
+ 0xed80, 0x5152,
+ 0xed91, 0x21c9,
+ 0xed92, 0x5163,
+ 0xed93, 0x2209,
+ 0xed94, 0x1ec9,
+ 0xed95, 0x20e9,
+ 0xed96, 0x5164,
+ 0xed97, 0x21ca,
+ 0xed98, 0x2146,
+ 0xed99, 0x25c5,
+ 0xed9a, 0x21dc,
+ 0xed9b, 0x5165,
+ 0xed9c, 0x245e,
+ 0xed9d, 0x5166,
+ 0xed9e, 0x214f,
+ 0xed9f, 0x5167,
+ 0xeda0, 0x25c6,
+ 0xeda1, 0x1a0d,
+ 0xee40, 0x25c7,
+ 0xee41, 0x2241,
+ 0xee42, 0x218a,
+ 0xee43, 0x1e2f,
+ 0xee44, 0x1edc,
+ 0xee45, 0x5168,
+ 0xee48, 0x20bf,
+ 0xee49, 0x2034,
+ 0xee4a, 0x516b,
+ 0xee4d, 0x25c9,
+ 0xee4e, 0x516e,
+ 0xee52, 0x25c8,
+ 0xee53, 0x5172,
+ 0xee55, 0x220e,
+ 0xee56, 0x5174,
+ 0xee57, 0x25cb,
+ 0xee58, 0x5175,
+ 0xee5e, 0x217d,
+ 0xee5f, 0x517b,
+ 0xee61, 0x1f7e,
+ 0xee62, 0x517d,
+ 0xee68, 0x25cc,
+ 0xee69, 0x1fc3,
+ 0xee6a, 0x5183,
+ 0xee6c, 0x20b9,
+ 0xee6d, 0x5185,
+ 0xee6e, 0x2181,
+ 0xee6f, 0x5186,
+ 0xee77, 0x1fda,
+ 0xee78, 0x518e,
+ 0xee7d, 0x2173,
+ 0xee7e, 0x1ee1,
+ 0xee80, 0x25cd,
+ 0xee81, 0x5193,
+ 0xee85, 0x25ce,
+ 0xee86, 0x21f6,
+ 0xee87, 0x5197,
+ 0xee8a, 0x224b,
+ 0xee8b, 0x25d1,
+ 0xee8c, 0x519a,
+ 0xee8d, 0x1ec0,
+ 0xee8e, 0x519b,
+ 0xee90, 0x2008,
+ 0xee91, 0x519d,
+ 0xee94, 0x25d0,
+ 0xee95, 0x51a0,
+ 0xee97, 0x25d2,
+ 0xee98, 0x51a2,
+ 0xee99, 0x1f2a,
+ 0xee9a, 0x51a3,
+ 0xee9d, 0x1e72,
+ 0xee9e, 0x25d3,
+ 0xee9f, 0x51a6,
+ 0xeea1, 0x1a6b,
+ 0xef40, 0x21be,
+ 0xef41, 0x25d4,
+ 0xef42, 0x2044,
+ 0xef43, 0x51a8,
+ 0xef44, 0x25cf,
+ 0xef45, 0x20f3,
+ 0xef46, 0x51a9,
+ 0xef4c, 0x1f00,
+ 0xef4d, 0x51af,
+ 0xef52, 0x24cc,
+ 0xef54, 0x51b4,
+ 0xef55, 0x2698,
+ 0xef56, 0x51b5,
+ 0xef57, 0x2678,
+ 0xef58, 0x51b6,
+ 0xef5a, 0x24ce,
+ 0xef5b, 0x51b8,
+ 0xef60, 0x24cf,
+ 0xef61, 0x51bd,
+ 0xef68, 0x20b8,
+ 0xef69, 0x51c4,
+ 0xef6a, 0x24d0,
+ 0xef6b, 0x51c5,
+ 0xef6c, 0x24d1,
+ 0xef6d, 0x51c6,
+ 0xef77, 0x1ef4,
+ 0xef78, 0x51d0,
+ 0xef7a, 0x239b,
+ 0xef7b, 0x51d2,
+ 0xef7c, 0x267e,
+ 0xef7d, 0x51d3,
+ 0xef80, 0x51d5,
+ 0xef82, 0x239d,
+ 0xef83, 0x239f,
+ 0xef85, 0x51d7,
+ 0xef86, 0x23a1,
+ 0xef87, 0x51d8,
+ 0xef88, 0x1ef1,
+ 0xef89, 0x51d9,
+ 0xef8b, 0x221e,
+ 0xef8c, 0x51db,
+ 0xef8d, 0x23a2,
+ 0xef8e, 0x51dc,
+ 0xef95, 0x214b,
+ 0xef96, 0x1e36,
+ 0xef97, 0x2135,
+ 0xef98, 0x51e3,
+ 0xef9c, 0x1fad,
+ 0xef9d, 0x51e7,
+ 0xef9e, 0x1e53,
+ 0xef9f, 0x51e8,
+ 0xefa1, 0x1ac9,
+ 0xf040, 0x51ea,
+ 0xf041, 0x23a3,
+ 0xf042, 0x2203,
+ 0xf043, 0x51eb,
+ 0xf044, 0x1ee7,
+ 0xf045, 0x51ec,
+ 0xf047, 0x23a4,
+ 0xf048, 0x2097,
+ 0xf049, 0x1ee4,
+ 0xf04a, 0x51ee,
+ 0xf04e, 0x2238,
+ 0xf04f, 0x51f2,
+ 0xf051, 0x23a5,
+ 0xf052, 0x51f4,
+ 0xf054, 0x1f9a,
+ 0xf055, 0x51f6,
+ 0xf057, 0x21c3,
+ 0xf058, 0x51f8,
+ 0xf05e, 0x1f2e,
+ 0xf05f, 0x51fe,
+ 0xf068, 0x239c,
+ 0xf069, 0x5207,
+ 0xf06c, 0x23a6,
+ 0xf06d, 0x520a,
+ 0xf071, 0x239e,
+ 0xf072, 0x520e,
+ 0xf073, 0x2035,
+ 0xf074, 0x23a7,
+ 0xf075, 0x520f,
+ 0xf078, 0x23a8,
+ 0xf079, 0x5212,
+ 0xf07a, 0x2075,
+ 0xf07b, 0x5213,
+ 0xf07d, 0x23a9,
+ 0xf080, 0x23ab,
+ 0xf081, 0x1feb,
+ 0xf082, 0x23ac,
+ 0xf083, 0x5215,
+ 0xf087, 0x1f6a,
+ 0xf088, 0x20f9,
+ 0xf089, 0x5219,
+ 0xf08b, 0x2666,
+ 0xf08c, 0x521b,
+ 0xf090, 0x2667,
+ 0xf091, 0x521f,
+ 0xf092, 0x1e6c,
+ 0xf093, 0x5220,
+ 0xf096, 0x23ad,
+ 0xf097, 0x5223,
+ 0xf0a1, 0x1b27,
+ 0xf140, 0x522d,
+ 0xf152, 0x206d,
+ 0xf153, 0x2242,
+ 0xf154, 0x1f02,
+ 0xf155, 0x523f,
+ 0xf157, 0x2183,
+ 0xf158, 0x5241,
+ 0xf159, 0x1e85,
+ 0xf15a, 0x21e9,
+ 0xf15b, 0x5242,
+ 0xf167, 0x1e57,
+ 0xf168, 0x524e,
+ 0xf176, 0x22a5,
+ 0xf177, 0x2407,
+ 0xf178, 0x1fca,
+ 0xf179, 0x525c,
+ 0xf17a, 0x2402,
+ 0xf17b, 0x1f82,
+ 0xf17c, 0x525d,
+ 0xf17e, 0x2408,
+ 0xf180, 0x2404,
+ 0xf181, 0x525f,
+ 0xf182, 0x2131,
+ 0xf183, 0x5260,
+ 0xf184, 0x2184,
+ 0xf185, 0x5261,
+ 0xf186, 0x2403,
+ 0xf187, 0x5262,
+ 0xf188, 0x206e,
+ 0xf189, 0x240b,
+ 0xf18a, 0x5263,
+ 0xf194, 0x1f3f,
+ 0xf195, 0x526d,
+ 0xf198, 0x2067,
+ 0xf199, 0x5270,
+ 0xf1a1, 0x1b85,
+ 0xf240, 0x5278,
+ 0xf245, 0x1fd7,
+ 0xf246, 0x527d,
+ 0xf247, 0x1e83,
+ 0xf248, 0x527e,
+ 0xf24b, 0x240f,
+ 0xf24c, 0x5281,
+ 0xf253, 0x240e,
+ 0xf254, 0x20c7,
+ 0xf255, 0x240d,
+ 0xf256, 0x5288,
+ 0xf25c, 0x2412,
+ 0xf25d, 0x528e,
+ 0xf25f, 0x20b7,
+ 0xf260, 0x5290,
+ 0xf271, 0x23f0,
+ 0xf272, 0x52a1,
+ 0xf273, 0x2411,
+ 0xf274, 0x2414,
+ 0xf275, 0x52a2,
+ 0xf276, 0x2170,
+ 0xf277, 0x52a3,
+ 0xf27c, 0x2405,
+ 0xf27d, 0x210c,
+ 0xf27e, 0x2415,
+ 0xf280, 0x52a8,
+ 0xf285, 0x2066,
+ 0xf286, 0x52ad,
+ 0xf287, 0x2352,
+ 0xf288, 0x2413,
+ 0xf289, 0x2410,
+ 0xf28a, 0x2416,
+ 0xf28c, 0x20f1,
+ 0xf28d, 0x52ae,
+ 0xf291, 0x240a,
+ 0xf292, 0x52b2,
+ 0xf294, 0x2409,
+ 0xf295, 0x52b4,
+ 0xf296, 0x2418,
+ 0xf297, 0x52b5,
+ 0xf29c, 0x1fa7,
+ 0xf29d, 0x52ba,
+ 0xf29e, 0x21fc,
+ 0xf29f, 0x52bb,
+ 0xf2a1, 0x1be3,
+ 0xf340, 0x1fc1,
+ 0xf341, 0x2406,
+ 0xf342, 0x52bd,
+ 0xf345, 0x229c,
+ 0xf346, 0x52c0,
+ 0xf348, 0x204e,
+ 0xf349, 0x52c2,
+ 0xf34a, 0x241a,
+ 0xf34b, 0x2419,
+ 0xf34c, 0x52c3,
+ 0xf350, 0x240c,
+ 0xf351, 0x52c7,
+ 0xf361, 0x1e29,
+ 0xf362, 0x52d7,
+ 0xf374, 0x2661,
+ 0xf375, 0x52e9,
+ 0xf376, 0x26a4,
+ 0xf377, 0x2174,
+ 0xf378, 0x2663,
+ 0xf379, 0x2662,
+ 0xf37a, 0x52ea,
+ 0xf380, 0x52ef,
+ 0xf38c, 0x2675,
+ 0xf38d, 0x52fb,
+ 0xf3a0, 0x214c,
+ 0xf3a1, 0x1c41,
+ 0xf440, 0x530e,
+ 0xf445, 0x267a,
+ 0xf446, 0x5313,
+ 0xf450, 0x26a0,
+ 0xf451, 0x531d,
+ 0xf457, 0x2668,
+ 0xf458, 0x5323,
+ 0xf459, 0x1ed0,
+ 0xf45a, 0x5324,
+ 0xf45b, 0x2096,
+ 0xf45c, 0x5325,
+ 0xf45d, 0x23cc,
+ 0xf45e, 0x5326,
+ 0xf462, 0x23c8,
+ 0xf463, 0x532a,
+ 0xf464, 0x223e,
+ 0xf465, 0x532b,
+ 0xf475, 0x2665,
+ 0xf476, 0x533b,
+ 0xf47c, 0x2664,
+ 0xf47d, 0x5341,
+ 0xf47e, 0x2239,
+ 0xf480, 0x5342,
+ 0xf494, 0x204a,
+ 0xf495, 0x5356,
+ 0xf499, 0x261f,
+ 0xf49a, 0x535a,
+ 0xf49c, 0x261e,
+ 0xf49d, 0x535c,
+ 0xf4a1, 0x1c9f,
+ 0xf540, 0x5360,
+ 0xf545, 0x2620,
+ 0xf546, 0x5365,
+ 0xf547, 0x2621,
+ 0xf548, 0x5366,
+ 0xf552, 0x2622,
+ 0xf553, 0x5370,
+ 0xf554, 0x2627,
+ 0xf555, 0x1e39,
+ 0xf556, 0x2625,
+ 0xf557, 0x5371,
+ 0xf55e, 0x2629,
+ 0xf55f, 0x5378,
+ 0xf561, 0x262e,
+ 0xf562, 0x262b,
+ 0xf563, 0x537a,
+ 0xf56e, 0x262a,
+ 0xf56f, 0x262d,
+ 0xf570, 0x5385,
+ 0xf571, 0x2628,
+ 0xf572, 0x21b9,
+ 0xf573, 0x5386,
+ 0xf580, 0x5392,
+ 0xf585, 0x2636,
+ 0xf586, 0x2630,
+ 0xf587, 0x5397,
+ 0xf58c, 0x2638,
+ 0xf58d, 0x539c,
+ 0xf58e, 0x200d,
+ 0xf58f, 0x2637,
+ 0xf590, 0x539d,
+ 0xf599, 0x2645,
+ 0xf59a, 0x53a6,
+ 0xf59b, 0x263a,
+ 0xf59c, 0x53a7,
+ 0xf5a0, 0x2643,
+ 0xf5a1, 0x1cfd,
+ 0xf640, 0x53ab,
+ 0xf641, 0x2640,
+ 0xf642, 0x53ac,
+ 0xf645, 0x263d,
+ 0xf646, 0x2641,
+ 0xf647, 0x53af,
+ 0xf648, 0x263e,
+ 0xf649, 0x53b0,
+ 0xf64b, 0x263f,
+ 0xf64c, 0x1fc0,
+ 0xf64d, 0x53b2,
+ 0xf64e, 0x263b,
+ 0xf650, 0x53b3,
+ 0xf654, 0x2642,
+ 0xf655, 0x53b7,
+ 0xf658, 0x2644,
+ 0xf659, 0x53ba,
+ 0xf661, 0x2639,
+ 0xf662, 0x53c2,
+ 0xf663, 0x264c,
+ 0xf664, 0x53c3,
+ 0xf66c, 0x2647,
+ 0xf66d, 0x264b,
+ 0xf66e, 0x53cb,
+ 0xf671, 0x2649,
+ 0xf672, 0x53ce,
+ 0xf674, 0x2648,
+ 0xf675, 0x53d0,
+ 0xf676, 0x264a,
+ 0xf677, 0x2108,
+ 0xf678, 0x53d1,
+ 0xf680, 0x53d8,
+ 0xf685, 0x264d,
+ 0xf686, 0x53dd,
+ 0xf688, 0x2634,
+ 0xf689, 0x53df,
+ 0xf68a, 0x2651,
+ 0xf68b, 0x53e0,
+ 0xf68d, 0x2650,
+ 0xf68e, 0x2652,
+ 0xf68f, 0x53e2,
+ 0xf692, 0x264f,
+ 0xf693, 0x53e5,
+ 0xf696, 0x2632,
+ 0xf697, 0x264e,
+ 0xf698, 0x2653,
+ 0xf699, 0x53e8,
+ 0xf69a, 0x2657,
+ 0xf69b, 0x53e9,
+ 0xf69c, 0x2635,
+ 0xf69d, 0x53ea,
+ 0xf69e, 0x2633,
+ 0xf69f, 0x53eb,
+ 0xf6a0, 0x2656,
+ 0xf6a1, 0x1d5b,
+ 0xf740, 0x53ec,
+ 0xf742, 0x2654,
+ 0xf743, 0x53ee,
+ 0xf749, 0x2658,
+ 0xf74a, 0x53f4,
+ 0xf74c, 0x2655,
+ 0xf74d, 0x1e4d,
+ 0xf74e, 0x53f6,
+ 0xf756, 0x265b,
+ 0xf757, 0x53fe,
+ 0xf758, 0x265a,
+ 0xf759, 0x53ff,
+ 0xf75a, 0x2659,
+ 0xf75b, 0x202e,
+ 0xf75c, 0x262f,
+ 0xf75d, 0x5400,
+ 0xf761, 0x2646,
+ 0xf762, 0x5404,
+ 0xf763, 0x2626,
+ 0xf764, 0x5405,
+ 0xf76b, 0x265c,
+ 0xf76c, 0x540c,
+ 0xf771, 0x262c,
+ 0xf772, 0x5411,
+ 0xf77c, 0x2623,
+ 0xf77d, 0x541b,
+ 0xf77e, 0x2631,
+ 0xf780, 0x541c,
+ 0xf7a1, 0x1db9,
+ 0xf840, 0x543d,
+ 0xf842, 0x209c,
+ 0xf843, 0x543f,
+ 0xf846, 0x2580,
+ 0xf847, 0x5442,
+ 0xf849, 0x22dc,
+ 0xf84a, 0x5444,
+ 0xf850, 0x1f05,
+ 0xf851, 0x208b,
+ 0xf852, 0x544a,
+ 0xf853, 0x2581,
+ 0xf854, 0x544b,
+ 0xf863, 0x2583,
+ 0xf864, 0x2582,
+ 0xf865, 0x545a,
+ 0xf866, 0x21ee,
+ 0xf867, 0x545b,
+ 0xf872, 0x2182,
+ 0xf873, 0x5466,
+ 0xf878, 0x2243,
+ 0xf879, 0x546b,
+ 0xf87a, 0x2587,
+ 0xf87b, 0x546c,
+ 0xf87c, 0x2588,
+ 0xf87d, 0x546d,
+ 0xf880, 0x546f,
+ 0xf881, 0x2584,
+ 0xf882, 0x5470,
+ 0xf884, 0x21fd,
+ 0xf885, 0x5472,
+ 0xf886, 0x21ef,
+ 0xf887, 0x5473,
+ 0xf88d, 0x258a,
+ 0xf88e, 0x258c,
+ 0xf88f, 0x5479,
+ 0xf899, 0x1f47,
+ 0xf89a, 0x5483,
+ 0xf89d, 0x1f1d,
+ 0xf89e, 0x5486,
+ 0xf8a0, 0x258d,
+ 0xf940, 0x5488,
+ 0xf94e, 0x1fd0,
+ 0xf94f, 0x2592,
+ 0xf950, 0x258f,
+ 0xf951, 0x5496,
+ 0xf959, 0x2594,
+ 0xf95a, 0x1ee0,
+ 0xf95b, 0x549e,
+ 0xf95d, 0x2591,
+ 0xf95e, 0x2595,
+ 0xf95f, 0x54a0,
+ 0xf967, 0x2597,
+ 0xf968, 0x54a8,
+ 0xf969, 0x20b6,
+ 0xf96a, 0x54a9,
+ 0xf96c, 0x2598,
+ 0xf96d, 0x54ab,
+ 0xf96f, 0x20f6,
+ 0xf970, 0x54ad,
+ 0xf980, 0x54bc,
+ 0xf985, 0x2585,
+ 0xf986, 0x54c1,
+ 0xf987, 0x2599,
+ 0xf988, 0x54c2,
+ 0xf991, 0x2596,
+ 0xf992, 0x54cb,
+ 0xf996, 0x259a,
+ 0xf997, 0x54cf,
+ 0xf998, 0x259b,
+ 0xf999, 0x54d0,
+ 0xfa40, 0x54d8,
+ 0xfa42, 0x259d,
+ 0xfa43, 0x54da,
+ 0xfa46, 0x259e,
+ 0xfa47, 0x54dd,
+ 0xfa4c, 0x234c,
+ 0xfa4d, 0x54e2,
+ 0xfa51, 0x1f44,
+ 0xfa52, 0x54e6,
+ 0xfa58, 0x2660,
+ 0xfa59, 0x25a0,
+ 0xfa5a, 0x54ec,
+ 0xfa5d, 0x259c,
+ 0xfa5e, 0x54ef,
+ 0xfa5f, 0x259f,
+ 0xfa60, 0x54f0,
+ 0xfa61, 0x1f6c,
+ 0xfa62, 0x54f1,
+ 0xfa70, 0x25a2,
+ 0xfa71, 0x54ff,
+ 0xfa74, 0x20ae,
+ 0xfa75, 0x5502,
+ 0xfa76, 0x258b,
+ 0xfa77, 0x25a3,
+ 0xfa78, 0x5503,
+ 0xfa80, 0x550a,
+ 0xfa83, 0x2589,
+ 0xfa84, 0x25a5,
+ 0xfa85, 0x550d,
+ 0xfa8d, 0x25a4,
+ 0xfa8e, 0x5515,
+ 0xfa90, 0x25a6,
+ 0xfa91, 0x2593,
+ 0xfa92, 0x5517,
+ 0xfa96, 0x25a7,
+ 0xfa97, 0x2222,
+ 0xfa98, 0x25a9,
+ 0xfa99, 0x551b,
+ 0xfb40, 0x5523,
+ 0xfb49, 0x25a8,
+ 0xfb4a, 0x552c,
+ 0xfb52, 0x2586,
+ 0xfb53, 0x5534,
+ 0xfb57, 0x25a1,
+ 0xfb58, 0x25aa,
+ 0xfb59, 0x5538,
+ 0xfb5a, 0x2590,
+ 0xfb5b, 0x258e,
+ 0xfb5c, 0x5539,
+ 0xfb75, 0x2688,
+ 0xfb76, 0x5552,
+ 0xfb79, 0x269e,
+ 0xfb7a, 0x25fb,
+ 0xfb7b, 0x5555,
+ 0xfb7c, 0x1f8c,
+ 0xfb7d, 0x21f4,
+ 0xfb7e, 0x5556,
+ 0xfb80, 0x5557,
+ 0xfb90, 0x200f,
+ 0xfb91, 0x5567,
+ 0xfb9c, 0x2071,
+ 0xfb9d, 0x5572,
+ 0xfb9f, 0x25f7,
+ 0xfba0, 0x5574,
+ 0xfc40, 0x5575,
+ 0xfc44, 0x2696,
+ 0xfc45, 0x5579,
+ 0xfc49, 0x268f,
+ 0xfc4a, 0x557d,
+ 0xfc5a, 0x22da,
+ 0xfc5b, 0x558d,
+ 0xfc63, 0x1ec1,
+ 0xfc64, 0x5595,
+ 0xfc68, 0x1eb3,
+ 0xfc69, 0x5599,
+ 0xfc6f, 0x266a,
+ 0xfc70, 0x559f,
+ 0xfc71, 0x268a,
+ 0xfc72, 0x55a0,
+ 0xfc74, 0x2669,
+ 0xfc75, 0x55a2,
+ 0xfc77, 0x2618,
+ 0xfc79, 0x55a4,
+ 0xfc80, 0x55aa,
+ 0xfc83, 0x261a,
+ 0xfc84, 0x55ad,
+ 0xfc8a, 0x2673,
+ 0xfc8b, 0x55b3,
+ 0xfd40, 0x55c9,
+ 0xfd52, 0x20c6,
+ 0xfd53, 0x226b,
+ 0xfd54, 0x55db,
+ 0xfd57, 0x24d3,
+ 0xfd58, 0x1e86,
+ 0xfd59, 0x55de,
+ 0xfd5a, 0x260f,
+ 0xfd5b, 0x55df,
+ 0xfd5f, 0x2611,
+ 0xfd60, 0x55e3,
+ 0xfd62, 0x2613,
+ 0xfd63, 0x55e5,
+ 0xfd65, 0x2610,
+ 0xfd66, 0x2612,
+ 0xfd67, 0x2030,
+ 0xfd68, 0x55e7,
+ 0xfd69, 0x2671,
+ 0xfd6a, 0x55e8,
+ 0xfd6c, 0x2614,
+ 0xfd6d, 0x55ea,
+ 0xfd70, 0x2616,
+ 0xfd71, 0x55ed,
+ 0xfd72, 0x2615,
+ 0xfd73, 0x55ee,
+ 0xfd78, 0x20f2,
+ 0xfd79, 0x55f3,
+ 0xfd7d, 0x2617,
+ 0xfd7e, 0x55f7,
+ 0xfd80, 0x55f8,
+ 0xfd88, 0x2037,
+ 0xfd89, 0x5600,
+ 0xfd8b, 0x20b3,
+ 0xfd8c, 0x5602,
+ 0xfd8f, 0x1f22,
+ 0xfd90, 0x24ed,
+ 0xfd91, 0x5605,
+ 0xfd94, 0x1f34,
+ 0xfd95, 0x5608,
+ 0xfd9d, 0x0a02,
+ 0xfd9e, 0x40d3,
+ 0xfd9f, 0x200c,
+ 0xfda0, 0x5083,
+ 0xfe40, 0x1259,
+ 0xfe41, 0x5610,
+ 0xfe80, 0x564e,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBKEUCHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1e24, 0x032e, 0x032f, 0x0330, 0x0331, 0x0332, 0x0333, 0x0334,
+ 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x033a, 0x033b, 0x033c,
+ 0x033d, 0x033e, 0x033f, 0x0340, 0x0341, 0x0342, 0x0343, 0x0344,
+ 0x0345, 0x0346, 0x0347, 0x0348, 0x0349, 0x034a, 0x034b, 0x034c,
+ 0x034d, 0x034e, 0x034f, 0x0350, 0x0351, 0x0352, 0x0353, 0x0354,
+ 0x0355, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035c,
+ 0x035d, 0x035e, 0x035f, 0x0360, 0x0361, 0x0362, 0x0363, 0x0364,
+ 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c,
+ 0x036d, 0x036e, 0x036f, 0x0370, 0x0371, 0x0372, 0x0373, 0x0374,
+ 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x037a, 0x037b, 0x037c,
+ 0x037d, 0x037e, 0x037f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384,
+ 0x0385, 0x0386, 0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12GBKEUCHMap2, 4071
+};
+
+static Gushort gb12GBKEUCVMap2[8182] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x2758,
+ 0x8179, 0x2059,
+ 0x817a, 0x2791,
+ 0x8180, 0x2796,
+ 0x8186, 0x21f1,
+ 0x8187, 0x279c,
+ 0x81ed, 0x1ff2,
+ 0x81ee, 0x2802,
+ 0x81f6, 0x205d,
+ 0x81f7, 0x280a,
+ 0x8240, 0x2812,
+ 0x8253, 0x269c,
+ 0x8254, 0x2825,
+ 0x8262, 0x21b5,
+ 0x8263, 0x2833,
+ 0x8274, 0x22cc,
+ 0x8275, 0x2844,
+ 0x827a, 0x2016,
+ 0x827b, 0x2849,
+ 0x827d, 0x1e62,
+ 0x827e, 0x284b,
+ 0x8280, 0x1f20,
+ 0x8281, 0x284c,
+ 0x8283, 0x207f,
+ 0x8284, 0x284e,
+ 0x8290, 0x205c,
+ 0x8291, 0x285a,
+ 0x82a5, 0x2194,
+ 0x82a6, 0x286e,
+ 0x82c8, 0x1e65,
+ 0x82c9, 0x2281,
+ 0x82ca, 0x2890,
+ 0x82e1, 0x22cd,
+ 0x82e2, 0x28a7,
+ 0x82e3, 0x210a,
+ 0x82e4, 0x1e3e,
+ 0x82e5, 0x28a8,
+ 0x82ed, 0x267f,
+ 0x82ee, 0x28b0,
+ 0x82f2, 0x222e,
+ 0x82f3, 0x28b4,
+ 0x82f7, 0x1e96,
+ 0x82f8, 0x22cb,
+ 0x82f9, 0x226c,
+ 0x82fa, 0x28b8,
+ 0x82fb, 0x2117,
+ 0x82fc, 0x28b9,
+ 0x8340, 0x28bc,
+ 0x8341, 0x20e8,
+ 0x8342, 0x28bd,
+ 0x8345, 0x22d4,
+ 0x8346, 0x28c0,
+ 0x8348, 0x1fb9,
+ 0x8349, 0x28c2,
+ 0x834c, 0x22d8,
+ 0x834d, 0x28c5,
+ 0x8353, 0x20df,
+ 0x8354, 0x28cb,
+ 0x8357, 0x20c2,
+ 0x8358, 0x28ce,
+ 0x835e, 0x2195,
+ 0x835f, 0x28d4,
+ 0x8365, 0x1fac,
+ 0x8366, 0x22d3,
+ 0x8367, 0x28da,
+ 0x8372, 0x1f81,
+ 0x8373, 0x28e5,
+ 0x8378, 0x2210,
+ 0x8379, 0x28ea,
+ 0x837a, 0x22cf,
+ 0x837b, 0x28eb,
+ 0x837c, 0x2213,
+ 0x837d, 0x28ec,
+ 0x837e, 0x1fe4,
+ 0x8380, 0x1f90,
+ 0x8381, 0x28ed,
+ 0x8386, 0x22d6,
+ 0x8387, 0x28f2,
+ 0x8389, 0x22d0,
+ 0x838a, 0x22ce,
+ 0x838b, 0x28f4,
+ 0x838d, 0x2681,
+ 0x838e, 0x28f6,
+ 0x8394, 0x1e76,
+ 0x8395, 0x28fc,
+ 0x839e, 0x2231,
+ 0x839f, 0x2905,
+ 0x83a6, 0x1e93,
+ 0x83a7, 0x290c,
+ 0x83ab, 0x22d2,
+ 0x83ac, 0x2910,
+ 0x83ae, 0x22d7,
+ 0x83af, 0x22d5,
+ 0x83b0, 0x22d1,
+ 0x83b1, 0x2912,
+ 0x83ba, 0x1ee5,
+ 0x83bb, 0x291b,
+ 0x83c9, 0x2025,
+ 0x83ca, 0x2929,
+ 0x83f6, 0x1ecf,
+ 0x83f7, 0x2955,
+ 0x8440, 0x295d,
+ 0x8450, 0x1fd9,
+ 0x8451, 0x296d,
+ 0x8471, 0x22c8,
+ 0x8472, 0x298d,
+ 0x8474, 0x2263,
+ 0x8475, 0x298f,
+ 0x8477, 0x2683,
+ 0x8478, 0x2991,
+ 0x8480, 0x2998,
+ 0x8482, 0x1f17,
+ 0x8483, 0x299a,
+ 0x848e, 0x1f2b,
+ 0x848f, 0x29a5,
+ 0x8492, 0x22ca,
+ 0x8493, 0x1e99,
+ 0x8494, 0x29a8,
+ 0x849d, 0x1f4f,
+ 0x849e, 0x29b1,
+ 0x84a1, 0x1fcf,
+ 0x84a2, 0x2036,
+ 0x84a3, 0x1f3a,
+ 0x84a4, 0x29b4,
+ 0x84a5, 0x22c9,
+ 0x84a6, 0x1f99,
+ 0x84a7, 0x29b5,
+ 0x84a9, 0x1f75,
+ 0x84aa, 0x29b7,
+ 0x84c5, 0x1fbe,
+ 0x84c6, 0x29d2,
+ 0x84d3, 0x1ecd,
+ 0x84d4, 0x29df,
+ 0x84d5, 0x21a9,
+ 0x84d6, 0x29e0,
+ 0x84d7, 0x21e6,
+ 0x84d8, 0x29e1,
+ 0x84d9, 0x2127,
+ 0x84da, 0x2003,
+ 0x84db, 0x29e2,
+ 0x84dd, 0x2132,
+ 0x84de, 0x29e4,
+ 0x84ea, 0x2323,
+ 0x84eb, 0x29f0,
+ 0x84ee, 0x2011,
+ 0x84ef, 0x29f3,
+ 0x84f1, 0x20f5,
+ 0x84f2, 0x29f5,
+ 0x8540, 0x2a02,
+ 0x8551, 0x22c5,
+ 0x8552, 0x1f5e,
+ 0x8553, 0x2a13,
+ 0x8554, 0x22c6,
+ 0x8555, 0x2a14,
+ 0x855e, 0x20ef,
+ 0x855f, 0x2a1d,
+ 0x8566, 0x21d0,
+ 0x8567, 0x2a24,
+ 0x8580, 0x2a3c,
+ 0x8587, 0x22c1,
+ 0x8588, 0x2a43,
+ 0x858b, 0x1e64,
+ 0x858c, 0x2a46,
+ 0x8592, 0x21f9,
+ 0x8593, 0x2a4c,
+ 0x8596, 0x2010,
+ 0x8597, 0x2a4f,
+ 0x8598, 0x22c2,
+ 0x8599, 0x2a50,
+ 0x85a2, 0x1e5a,
+ 0x85a3, 0x2a59,
+ 0x85b2, 0x1ea2,
+ 0x85b3, 0x2a68,
+ 0x8640, 0x2ab4,
+ 0x864a, 0x236d,
+ 0x864b, 0x2abe,
+ 0x8654, 0x2247,
+ 0x8655, 0x2ac7,
+ 0x8668, 0x236c,
+ 0x8669, 0x2ada,
+ 0x8680, 0x2af0,
+ 0x8696, 0x219c,
+ 0x8697, 0x2b06,
+ 0x8699, 0x20c9,
+ 0x869a, 0x2b08,
+ 0x86a1, 0x21f0,
+ 0x86a2, 0x2b0f,
+ 0x86ca, 0x210b,
+ 0x86cb, 0x2b37,
+ 0x86cc, 0x20de,
+ 0x86cd, 0x2b38,
+ 0x86ce, 0x1eaa,
+ 0x86cf, 0x2b39,
+ 0x86d1, 0x222c,
+ 0x86d2, 0x2b3b,
+ 0x86dc, 0x20d8,
+ 0x86dd, 0x22c0,
+ 0x86de, 0x2b45,
+ 0x86e1, 0x206f,
+ 0x86e2, 0x2b48,
+ 0x86e8, 0x21a1,
+ 0x86e9, 0x2b4e,
+ 0x86ee, 0x2379,
+ 0x86ef, 0x2b53,
+ 0x86f4, 0x2372,
+ 0x86f5, 0x2b58,
+ 0x8740, 0x216a,
+ 0x8741, 0x2b62,
+ 0x8744, 0x237c,
+ 0x8745, 0x2b65,
+ 0x8749, 0x20b0,
+ 0x874a, 0x2b69,
+ 0x874b, 0x237a,
+ 0x874c, 0x1e74,
+ 0x874d, 0x2b6a,
+ 0x874f, 0x2377,
+ 0x8750, 0x2b6c,
+ 0x8757, 0x1f4c,
+ 0x8758, 0x2b73,
+ 0x875a, 0x2378,
+ 0x875b, 0x21cf,
+ 0x875c, 0x2368,
+ 0x875d, 0x2b75,
+ 0x875e, 0x2371,
+ 0x875f, 0x2b76,
+ 0x8760, 0x2369,
+ 0x8761, 0x2b77,
+ 0x8766, 0x2674,
+ 0x8767, 0x2b7c,
+ 0x877a, 0x236f,
+ 0x877b, 0x2b8f,
+ 0x877d, 0x2370,
+ 0x877e, 0x2b91,
+ 0x8780, 0x2b92,
+ 0x8781, 0x2376,
+ 0x8782, 0x2373,
+ 0x8783, 0x2b93,
+ 0x8786, 0x237f,
+ 0x8787, 0x2b96,
+ 0x8788, 0x2374,
+ 0x8789, 0x2b97,
+ 0x878a, 0x20b5,
+ 0x878b, 0x2b98,
+ 0x878d, 0x1edb,
+ 0x878e, 0x2672,
+ 0x878f, 0x2b9a,
+ 0x8793, 0x236e,
+ 0x8794, 0x2b9e,
+ 0x8798, 0x21b7,
+ 0x8799, 0x2ba2,
+ 0x879d, 0x2375,
+ 0x879e, 0x2ba6,
+ 0x87a3, 0x2382,
+ 0x87a4, 0x2bab,
+ 0x87a7, 0x209e,
+ 0x87a8, 0x2bae,
+ 0x87b3, 0x236b,
+ 0x87b4, 0x2bb9,
+ 0x87b5, 0x2039,
+ 0x87b6, 0x2bba,
+ 0x87bb, 0x269f,
+ 0x87bc, 0x2bbf,
+ 0x87bf, 0x237d,
+ 0x87c0, 0x21f5,
+ 0x87c1, 0x2bc2,
+ 0x87c2, 0x2381,
+ 0x87c3, 0x2bc3,
+ 0x87ca, 0x237b,
+ 0x87cb, 0x237e,
+ 0x87cc, 0x21cc,
+ 0x87cd, 0x2bca,
+ 0x87cf, 0x22db,
+ 0x87d0, 0x2bcc,
+ 0x87d2, 0x236a,
+ 0x87d3, 0x2689,
+ 0x87d4, 0x2bce,
+ 0x87d5, 0x2697,
+ 0x87d6, 0x2bcf,
+ 0x87da, 0x22a1,
+ 0x87db, 0x2bd3,
+ 0x87f7, 0x2383,
+ 0x87f8, 0x1f3d,
+ 0x87f9, 0x2bef,
+ 0x87fa, 0x218f,
+ 0x87fb, 0x2bf0,
+ 0x8840, 0x2246,
+ 0x8841, 0x2248,
+ 0x8842, 0x2bf4,
+ 0x8844, 0x217e,
+ 0x8845, 0x2bf6,
+ 0x8846, 0x2180,
+ 0x8847, 0x2bf7,
+ 0x8880, 0x2c2f,
+ 0x88ba, 0x232a,
+ 0x88bb, 0x2c69,
+ 0x88cc, 0x228b,
+ 0x88cd, 0x2c7a,
+ 0x88d4, 0x1f85,
+ 0x88d5, 0x2c81,
+ 0x88d7, 0x2325,
+ 0x88d8, 0x2c83,
+ 0x88df, 0x232c,
+ 0x88e0, 0x2c8a,
+ 0x88e5, 0x232e,
+ 0x88e6, 0x2c8f,
+ 0x88f2, 0x2205,
+ 0x88f3, 0x1e38,
+ 0x88f4, 0x2c9b,
+ 0x88f6, 0x1e73,
+ 0x88f7, 0x2c9d,
+ 0x8940, 0x2ca5,
+ 0x894b, 0x1fe3,
+ 0x894c, 0x2339,
+ 0x894d, 0x2cb0,
+ 0x894e, 0x232b,
+ 0x894f, 0x2cb1,
+ 0x8950, 0x232d,
+ 0x8951, 0x2cb2,
+ 0x8954, 0x217f,
+ 0x8955, 0x2cb5,
+ 0x895d, 0x21a7,
+ 0x895e, 0x2cbd,
+ 0x895f, 0x232f,
+ 0x8960, 0x2cbe,
+ 0x896d, 0x1e7d,
+ 0x896e, 0x2ccb,
+ 0x8971, 0x20d6,
+ 0x8972, 0x2cce,
+ 0x897c, 0x1ec2,
+ 0x897d, 0x2cd8,
+ 0x8980, 0x2cda,
+ 0x898b, 0x22b2,
+ 0x898c, 0x2ce5,
+ 0x8999, 0x1edf,
+ 0x899a, 0x2cf2,
+ 0x899e, 0x1ef9,
+ 0x899f, 0x2cf6,
+ 0x89a6, 0x20d9,
+ 0x89a7, 0x2cfd,
+ 0x89a8, 0x1fdd,
+ 0x89a9, 0x2cfe,
+ 0x89af, 0x2167,
+ 0x89b0, 0x2d04,
+ 0x89ba, 0x21ed,
+ 0x89bb, 0x2d0e,
+ 0x89be, 0x2007,
+ 0x89bf, 0x2326,
+ 0x89c0, 0x2329,
+ 0x89c1, 0x2d11,
+ 0x89c4, 0x1f52,
+ 0x89c5, 0x203b,
+ 0x89c6, 0x2328,
+ 0x89c7, 0x2d14,
+ 0x89c8, 0x2327,
+ 0x89c9, 0x2d15,
+ 0x89ce, 0x1e2b,
+ 0x89cf, 0x2d1a,
+ 0x89d1, 0x22ae,
+ 0x89d2, 0x2d1c,
+ 0x89d8, 0x1f49,
+ 0x89d9, 0x2d22,
+ 0x89db, 0x2138,
+ 0x89dc, 0x2d24,
+ 0x89f4, 0x2081,
+ 0x89f5, 0x2d3c,
+ 0x8a40, 0x2d46,
+ 0x8a41, 0x1f7c,
+ 0x8a42, 0x2d47,
+ 0x8a59, 0x235b,
+ 0x8a5a, 0x1ede,
+ 0x8a5b, 0x2d5e,
+ 0x8a5c, 0x1fa2,
+ 0x8a5d, 0x2d5f,
+ 0x8a5e, 0x1efa,
+ 0x8a5f, 0x2d60,
+ 0x8a79, 0x22ad,
+ 0x8a7a, 0x2d7a,
+ 0x8a80, 0x2d7f,
+ 0x8ae4, 0x203f,
+ 0x8ae5, 0x2de3,
+ 0x8b40, 0x2dfd,
+ 0x8b44, 0x1f0e,
+ 0x8b45, 0x2e01,
+ 0x8b49, 0x23f9,
+ 0x8b4a, 0x2e05,
+ 0x8b7a, 0x23fc,
+ 0x8b7b, 0x2e35,
+ 0x8b80, 0x2e39,
+ 0x8b8c, 0x2069,
+ 0x8b8d, 0x2e45,
+ 0x8b9e, 0x23f7,
+ 0x8b9f, 0x2e56,
+ 0x8bb3, 0x23f6,
+ 0x8bb4, 0x2e6a,
+ 0x8bb9, 0x23fd,
+ 0x8bba, 0x2e6f,
+ 0x8bbe, 0x23f8,
+ 0x8bbf, 0x2e73,
+ 0x8bc6, 0x23fa,
+ 0x8bc7, 0x2e7a,
+ 0x8bc8, 0x23fe,
+ 0x8bc9, 0x1fa8,
+ 0x8bca, 0x2e7b,
+ 0x8bd4, 0x2401,
+ 0x8bd5, 0x2e85,
+ 0x8bdc, 0x23ff,
+ 0x8bdd, 0x2e8c,
+ 0x8be5, 0x2400,
+ 0x8be6, 0x2e94,
+ 0x8beb, 0x2221,
+ 0x8bec, 0x2e99,
+ 0x8bf0, 0x2122,
+ 0x8bf1, 0x2e9d,
+ 0x8c40, 0x2eab,
+ 0x8c44, 0x23fb,
+ 0x8c45, 0x2eaf,
+ 0x8c4f, 0x215a,
+ 0x8c50, 0x2eb9,
+ 0x8c57, 0x21e5,
+ 0x8c58, 0x2ec0,
+ 0x8c5c, 0x2057,
+ 0x8c5d, 0x2ec4,
+ 0x8c80, 0x2ee6,
+ 0x8c8b, 0x20e5,
+ 0x8c8c, 0x2ef1,
+ 0x8c8d, 0x212f,
+ 0x8c8e, 0x20a3,
+ 0x8c8f, 0x2121,
+ 0x8c90, 0x2ef2,
+ 0x8c91, 0x21d4,
+ 0x8c92, 0x1fe5,
+ 0x8c93, 0x2ef3,
+ 0x8c99, 0x1e8a,
+ 0x8c9a, 0x1e37,
+ 0x8c9b, 0x2ef9,
+ 0x8ca2, 0x1f9e,
+ 0x8ca3, 0x22a6,
+ 0x8ca4, 0x21e8,
+ 0x8ca5, 0x2f00,
+ 0x8ca6, 0x1eda,
+ 0x8ca7, 0x1eb9,
+ 0x8ca8, 0x2f01,
+ 0x8cc0, 0x235c,
+ 0x8cc1, 0x2f19,
+ 0x8cd2, 0x2050,
+ 0x8cd3, 0x1e67,
+ 0x8cd4, 0x2f2a,
+ 0x8cd5, 0x23f4,
+ 0x8cd6, 0x2f2b,
+ 0x8cd9, 0x213e,
+ 0x8cda, 0x2f2e,
+ 0x8cf9, 0x1f16,
+ 0x8cfa, 0x2f4d,
+ 0x8d40, 0x2f52,
+ 0x8d73, 0x2389,
+ 0x8d74, 0x2f85,
+ 0x8d75, 0x1eb7,
+ 0x8d76, 0x2f86,
+ 0x8d7b, 0x21b4,
+ 0x8d7c, 0x2f8b,
+ 0x8d80, 0x2f8e,
+ 0x8d88, 0x238f,
+ 0x8d89, 0x2f96,
+ 0x8d8f, 0x1f1a,
+ 0x8d90, 0x2f9c,
+ 0x8d9e, 0x238b,
+ 0x8d9f, 0x2faa,
+ 0x8db9, 0x238a,
+ 0x8dba, 0x2fc4,
+ 0x8de2, 0x2391,
+ 0x8de3, 0x2fec,
+ 0x8de4, 0x2271,
+ 0x8de5, 0x2fed,
+ 0x8de7, 0x2388,
+ 0x8de8, 0x2fef,
+ 0x8df7, 0x238e,
+ 0x8df8, 0x2ffe,
+ 0x8dfe, 0x238d,
+ 0x8e40, 0x3004,
+ 0x8e46, 0x238c,
+ 0x8e47, 0x300a,
+ 0x8e56, 0x2390,
+ 0x8e57, 0x3019,
+ 0x8e58, 0x2033,
+ 0x8e59, 0x301a,
+ 0x8e5a, 0x223c,
+ 0x8e5b, 0x301b,
+ 0x8e68, 0x1fe9,
+ 0x8e69, 0x3028,
+ 0x8e6e, 0x2055,
+ 0x8e6f, 0x302d,
+ 0x8e70, 0x2392,
+ 0x8e71, 0x302e,
+ 0x8e80, 0x2324,
+ 0x8e81, 0x303c,
+ 0x8e9b, 0x2143,
+ 0x8e9c, 0x3056,
+ 0x8e9f, 0x2129,
+ 0x8ea0, 0x3059,
+ 0x8ea4, 0x2277,
+ 0x8ea5, 0x305d,
+ 0x8ea7, 0x1ea7,
+ 0x8ea8, 0x305f,
+ 0x8eac, 0x2285,
+ 0x8ead, 0x3063,
+ 0x8eae, 0x2384,
+ 0x8eaf, 0x3064,
+ 0x8ebd, 0x2387,
+ 0x8ebe, 0x2386,
+ 0x8ebf, 0x3072,
+ 0x8ec3, 0x2290,
+ 0x8ec4, 0x3076,
+ 0x8ec5, 0x1e44,
+ 0x8ec6, 0x3077,
+ 0x8ecd, 0x1e32,
+ 0x8ece, 0x2385,
+ 0x8ecf, 0x307e,
+ 0x8ed6, 0x1f13,
+ 0x8ed7, 0x1f73,
+ 0x8ed8, 0x3085,
+ 0x8eec, 0x1fe0,
+ 0x8eed, 0x3099,
+ 0x8f40, 0x30ab,
+ 0x8f52, 0x2087,
+ 0x8f53, 0x1e78,
+ 0x8f54, 0x23ae,
+ 0x8f55, 0x1ef6,
+ 0x8f56, 0x1f31,
+ 0x8f57, 0x30bd,
+ 0x8f5d, 0x2045,
+ 0x8f5e, 0x30c3,
+ 0x8f64, 0x2178,
+ 0x8f65, 0x30c9,
+ 0x8f80, 0x30e3,
+ 0x8f86, 0x23f5,
+ 0x8f87, 0x30e9,
+ 0x8f88, 0x2275,
+ 0x8f89, 0x30ea,
+ 0x8f95, 0x266e,
+ 0x8f96, 0x30f6,
+ 0x8f97, 0x1eb0,
+ 0x8f98, 0x30f7,
+ 0x8f9b, 0x2083,
+ 0x8f9c, 0x30fa,
+ 0x8f9d, 0x2188,
+ 0x8f9e, 0x30fb,
+ 0x8fa1, 0x267c,
+ 0x8fa2, 0x30fe,
+ 0x8fbd, 0x1fc5,
+ 0x8fbe, 0x3119,
+ 0x8fc4, 0x1ea1,
+ 0x8fc5, 0x311f,
+ 0x8fc6, 0x2393,
+ 0x8fc7, 0x3120,
+ 0x8fcd, 0x1f0b,
+ 0x8fce, 0x3126,
+ 0x8fd8, 0x1e7c,
+ 0x8fd9, 0x3130,
+ 0x9040, 0x3156,
+ 0x9080, 0x3195,
+ 0x909d, 0x23b4,
+ 0x909e, 0x207e,
+ 0x909f, 0x31b2,
+ 0x90ba, 0x1ee3,
+ 0x90bb, 0x31cd,
+ 0x90c0, 0x2095,
+ 0x90c1, 0x23bb,
+ 0x90c2, 0x31d2,
+ 0x90c5, 0x23b9,
+ 0x90c6, 0x31d5,
+ 0x90db, 0x1e28,
+ 0x90dc, 0x23bd,
+ 0x90dd, 0x31ea,
+ 0x90ed, 0x23b5,
+ 0x90ee, 0x31fa,
+ 0x90f0, 0x23ba,
+ 0x90f1, 0x31fc,
+ 0x90f7, 0x23b3,
+ 0x90f8, 0x3202,
+ 0x9140, 0x3209,
+ 0x9142, 0x2162,
+ 0x9143, 0x320b,
+ 0x914b, 0x1e5e,
+ 0x914c, 0x3213,
+ 0x914d, 0x1e5d,
+ 0x914e, 0x3214,
+ 0x9151, 0x23b7,
+ 0x9152, 0x3217,
+ 0x9154, 0x1f2f,
+ 0x9155, 0x24df,
+ 0x9156, 0x3219,
+ 0x9159, 0x23b2,
+ 0x915a, 0x214e,
+ 0x915b, 0x321c,
+ 0x915d, 0x2052,
+ 0x915e, 0x321e,
+ 0x9161, 0x23bc,
+ 0x9162, 0x3221,
+ 0x9163, 0x20eb,
+ 0x9164, 0x3222,
+ 0x916e, 0x2232,
+ 0x916f, 0x322c,
+ 0x9176, 0x1e3f,
+ 0x9177, 0x3233,
+ 0x917a, 0x201b,
+ 0x917b, 0x20bc,
+ 0x917c, 0x23be,
+ 0x917d, 0x3236,
+ 0x9180, 0x3238,
+ 0x9184, 0x1eae,
+ 0x9185, 0x323c,
+ 0x918d, 0x1efb,
+ 0x918e, 0x3244,
+ 0x9191, 0x2089,
+ 0x9192, 0x3247,
+ 0x9193, 0x23b1,
+ 0x9194, 0x3248,
+ 0x9197, 0x21c4,
+ 0x9198, 0x324b,
+ 0x919b, 0x2214,
+ 0x919c, 0x324e,
+ 0x91a9, 0x1fde,
+ 0x91aa, 0x2223,
+ 0x91ab, 0x23b6,
+ 0x91ac, 0x325b,
+ 0x91ba, 0x268c,
+ 0x91bb, 0x24de,
+ 0x91bc, 0x3269,
+ 0x91bf, 0x24e0,
+ 0x91c0, 0x326c,
+ 0x91c3, 0x23b8,
+ 0x91c4, 0x326f,
+ 0x91cd, 0x1e81,
+ 0x91ce, 0x3278,
+ 0x91d0, 0x1ffe,
+ 0x91d1, 0x1f51,
+ 0x91d2, 0x21e1,
+ 0x91d3, 0x327a,
+ 0x91d4, 0x23b0,
+ 0x91d5, 0x327b,
+ 0x91d6, 0x1fce,
+ 0x91d7, 0x327c,
+ 0x91d8, 0x211e,
+ 0x91d9, 0x2021,
+ 0x91da, 0x327d,
+ 0x91df, 0x24e1,
+ 0x91e0, 0x3282,
+ 0x91e2, 0x24a3,
+ 0x91e3, 0x3284,
+ 0x91ea, 0x24a4,
+ 0x91eb, 0x328b,
+ 0x91f0, 0x2273,
+ 0x91f1, 0x3290,
+ 0x91f2, 0x21b0,
+ 0x91f3, 0x3291,
+ 0x9240, 0x329d,
+ 0x9280, 0x32dc,
+ 0x92b6, 0x21d1,
+ 0x92b7, 0x3312,
+ 0x92ce, 0x211c,
+ 0x92cf, 0x3329,
+ 0x92d0, 0x235d,
+ 0x92d1, 0x332a,
+ 0x92d4, 0x2682,
+ 0x92d5, 0x332d,
+ 0x92df, 0x210d,
+ 0x92e0, 0x205a,
+ 0x92e1, 0x3337,
+ 0x92fe, 0x1f8d,
+ 0x9340, 0x3354,
+ 0x9350, 0x21ff,
+ 0x9351, 0x3364,
+ 0x935d, 0x1f58,
+ 0x935e, 0x3370,
+ 0x9370, 0x215b,
+ 0x9371, 0x3382,
+ 0x9376, 0x1eb6,
+ 0x9377, 0x3387,
+ 0x9380, 0x338f,
+ 0x938c, 0x20db,
+ 0x938d, 0x339b,
+ 0x939d, 0x2360,
+ 0x939e, 0x33ab,
+ 0x93a5, 0x2361,
+ 0x93a6, 0x33b2,
+ 0x93a7, 0x2040,
+ 0x93a8, 0x33b3,
+ 0x93b4, 0x228e,
+ 0x93b5, 0x33bf,
+ 0x93b8, 0x1fdf,
+ 0x93b9, 0x33c2,
+ 0x93bb, 0x235e,
+ 0x93bc, 0x33c4,
+ 0x93bd, 0x1e6a,
+ 0x93be, 0x33c5,
+ 0x93c6, 0x2002,
+ 0x93c7, 0x33cd,
+ 0x93cf, 0x2093,
+ 0x93d0, 0x33d5,
+ 0x93d7, 0x235f,
+ 0x93d8, 0x33dc,
+ 0x93db, 0x1eac,
+ 0x93dc, 0x1e54,
+ 0x93dd, 0x33df,
+ 0x93e1, 0x1f08,
+ 0x93e2, 0x33e3,
+ 0x93e4, 0x20c0,
+ 0x93e5, 0x2362,
+ 0x93e6, 0x33e5,
+ 0x93e9, 0x2160,
+ 0x93ea, 0x33e8,
+ 0x93eb, 0x219d,
+ 0x93ec, 0x1f8e,
+ 0x93ed, 0x222d,
+ 0x93ee, 0x33e9,
+ 0x93ef, 0x2047,
+ 0x93f0, 0x33ea,
+ 0x93f1, 0x2262,
+ 0x93f2, 0x33eb,
+ 0x93f4, 0x1f67,
+ 0x93f5, 0x1eb2,
+ 0x93f6, 0x33ed,
+ 0x93fa, 0x1ea9,
+ 0x93fb, 0x33f1,
+ 0x93fe, 0x1fcc,
+ 0x9440, 0x33f4,
+ 0x9444, 0x1f72,
+ 0x9445, 0x33f8,
+ 0x944d, 0x2098,
+ 0x944e, 0x3400,
+ 0x9450, 0x1e52,
+ 0x9451, 0x20a4,
+ 0x9452, 0x1f1c,
+ 0x9453, 0x228f,
+ 0x9454, 0x3402,
+ 0x9455, 0x1fed,
+ 0x9456, 0x3403,
+ 0x9458, 0x2365,
+ 0x9459, 0x3405,
+ 0x945b, 0x1e2d,
+ 0x945c, 0x2152,
+ 0x945d, 0x2366,
+ 0x945e, 0x3407,
+ 0x945f, 0x20fa,
+ 0x9460, 0x3408,
+ 0x9464, 0x2363,
+ 0x9465, 0x340c,
+ 0x9466, 0x209a,
+ 0x9467, 0x340d,
+ 0x946e, 0x203c,
+ 0x946f, 0x3414,
+ 0x9472, 0x1ff6,
+ 0x9473, 0x3417,
+ 0x9474, 0x2364,
+ 0x9475, 0x3418,
+ 0x9476, 0x1e69,
+ 0x9477, 0x3419,
+ 0x9478, 0x2367,
+ 0x9479, 0x341a,
+ 0x947a, 0x211d,
+ 0x947b, 0x341b,
+ 0x9480, 0x2259,
+ 0x9481, 0x2056,
+ 0x9482, 0x2163,
+ 0x9483, 0x341f,
+ 0x9487, 0x1fa9,
+ 0x9488, 0x1ffc,
+ 0x9489, 0x3423,
+ 0x94a1, 0x1e2e,
+ 0x94a2, 0x343b,
+ 0x94b3, 0x1ebc,
+ 0x94b4, 0x344c,
+ 0x94b5, 0x2142,
+ 0x94b6, 0x344d,
+ 0x94bf, 0x201e,
+ 0x94c0, 0x1e43,
+ 0x94c1, 0x3456,
+ 0x94cc, 0x24d4,
+ 0x94cd, 0x3461,
+ 0x94d8, 0x226f,
+ 0x94d9, 0x346c,
+ 0x94e0, 0x1ed7,
+ 0x94e1, 0x3473,
+ 0x9540, 0x3491,
+ 0x9572, 0x212d,
+ 0x9573, 0x34c3,
+ 0x9580, 0x34cf,
+ 0x9583, 0x229b,
+ 0x9584, 0x34d2,
+ 0x959e, 0x2256,
+ 0x959f, 0x24a8,
+ 0x95a0, 0x34ec,
+ 0x95b3, 0x1e79,
+ 0x95b4, 0x34ff,
+ 0x95ba, 0x225a,
+ 0x95bb, 0x3505,
+ 0x95cf, 0x24a7,
+ 0x95d0, 0x3519,
+ 0x95d1, 0x2686,
+ 0x95d2, 0x24a6,
+ 0x95d3, 0x351a,
+ 0x95d4, 0x21ce,
+ 0x95d5, 0x351b,
+ 0x95e1, 0x24a9,
+ 0x95e2, 0x3527,
+ 0x95e7, 0x1fe7,
+ 0x95e8, 0x352c,
+ 0x95f1, 0x2112,
+ 0x95f2, 0x3535,
+ 0x95f8, 0x213c,
+ 0x95f9, 0x353b,
+ 0x95fe, 0x1f5c,
+ 0x9640, 0x3540,
+ 0x9656, 0x24c4,
+ 0x9657, 0x3556,
+ 0x967c, 0x1ecc,
+ 0x967d, 0x357b,
+ 0x9680, 0x357d,
+ 0x9740, 0x35fc,
+ 0x9767, 0x246a,
+ 0x9768, 0x3623,
+ 0x976c, 0x2175,
+ 0x976d, 0x3627,
+ 0x976e, 0x246d,
+ 0x976f, 0x3628,
+ 0x9780, 0x3638,
+ 0x9796, 0x246b,
+ 0x9797, 0x225f,
+ 0x9798, 0x364e,
+ 0x979d, 0x1ece,
+ 0x979e, 0x3653,
+ 0x97a3, 0x2272,
+ 0x97a4, 0x3658,
+ 0x97bf, 0x2473,
+ 0x97c0, 0x3673,
+ 0x97ee, 0x21fe,
+ 0x97ef, 0x36a1,
+ 0x97f7, 0x1efe,
+ 0x97f8, 0x36a9,
+ 0x9840, 0x36b0,
+ 0x9845, 0x2475,
+ 0x9846, 0x36b5,
+ 0x9849, 0x220a,
+ 0x984a, 0x36b8,
+ 0x984f, 0x1f6f,
+ 0x9850, 0x36bd,
+ 0x9871, 0x2468,
+ 0x9872, 0x36de,
+ 0x9873, 0x2100,
+ 0x9874, 0x36df,
+ 0x9880, 0x36ea,
+ 0x9881, 0x2476,
+ 0x9882, 0x36eb,
+ 0x988b, 0x1f27,
+ 0x988c, 0x20d7,
+ 0x988d, 0x36f4,
+ 0x98a0, 0x247c,
+ 0x98a1, 0x3707,
+ 0x98aa, 0x1fa1,
+ 0x98ab, 0x3710,
+ 0x98b6, 0x22aa,
+ 0x98b7, 0x2005,
+ 0x98b8, 0x371b,
+ 0x98ba, 0x246c,
+ 0x98bb, 0x371d,
+ 0x98c7, 0x203e,
+ 0x98c8, 0x3729,
+ 0x98cb, 0x1e4c,
+ 0x98cc, 0x372c,
+ 0x98d0, 0x213a,
+ 0x98d1, 0x3730,
+ 0x98d3, 0x2204,
+ 0x98d4, 0x3732,
+ 0x98e3, 0x20c3,
+ 0x98e4, 0x2140,
+ 0x98e5, 0x2477,
+ 0x98e6, 0x3741,
+ 0x98ef, 0x2474,
+ 0x98f0, 0x374a,
+ 0x98f2, 0x20dd,
+ 0x98f3, 0x374c,
+ 0x9940, 0x3758,
+ 0x9943, 0x1f68,
+ 0x9944, 0x375b,
+ 0x9945, 0x2185,
+ 0x9946, 0x375c,
+ 0x9966, 0x2472,
+ 0x9967, 0x377c,
+ 0x996e, 0x1eb5,
+ 0x996f, 0x3783,
+ 0x9975, 0x2478,
+ 0x9976, 0x3789,
+ 0x997a, 0x1f8b,
+ 0x997b, 0x2484,
+ 0x997c, 0x378d,
+ 0x9980, 0x3790,
+ 0x9985, 0x2699,
+ 0x9986, 0x3795,
+ 0x9989, 0x2482,
+ 0x998a, 0x3798,
+ 0x998e, 0x20a1,
+ 0x998f, 0x379c,
+ 0x9991, 0x1f92,
+ 0x9992, 0x379e,
+ 0x9999, 0x1f38,
+ 0x999a, 0x37a5,
+ 0x99a9, 0x2485,
+ 0x99aa, 0x37b4,
+ 0x99b0, 0x2480,
+ 0x99b1, 0x246e,
+ 0x99b2, 0x37ba,
+ 0x99b3, 0x247b,
+ 0x99b4, 0x2486,
+ 0x99b5, 0x2471,
+ 0x99b6, 0x37bb,
+ 0x99bd, 0x2483,
+ 0x99be, 0x2470,
+ 0x99bf, 0x37c2,
+ 0x99c0, 0x2469,
+ 0x99c1, 0x37c3,
+ 0x99c2, 0x247f,
+ 0x99c3, 0x37c4,
+ 0x99c9, 0x246f,
+ 0x99ca, 0x37ca,
+ 0x99ce, 0x2481,
+ 0x99cf, 0x37ce,
+ 0x99d1, 0x2220,
+ 0x99d2, 0x37d0,
+ 0x99da, 0x1ff5,
+ 0x99db, 0x37d8,
+ 0x99e0, 0x20f4,
+ 0x99e1, 0x37dd,
+ 0x99e5, 0x247d,
+ 0x99e6, 0x37e1,
+ 0x99e8, 0x2479,
+ 0x99e9, 0x37e3,
+ 0x99ec, 0x247e,
+ 0x99ed, 0x37e6,
+ 0x99f4, 0x247a,
+ 0x99f5, 0x37ed,
+ 0x9a40, 0x37f7,
+ 0x9a4a, 0x20e3,
+ 0x9a4b, 0x3801,
+ 0x9a57, 0x20ad,
+ 0x9a58, 0x380d,
+ 0x9a65, 0x24cb,
+ 0x9a66, 0x381a,
+ 0x9a67, 0x1f53,
+ 0x9a68, 0x381b,
+ 0x9a71, 0x2159,
+ 0x9a72, 0x3824,
+ 0x9a76, 0x2013,
+ 0x9a77, 0x1f33,
+ 0x9a78, 0x3828,
+ 0x9a80, 0x382f,
+ 0x9a88, 0x1e5c,
+ 0x9a89, 0x3837,
+ 0x9a8c, 0x2488,
+ 0x9a8d, 0x383a,
+ 0x9a91, 0x2487,
+ 0x9a92, 0x383e,
+ 0x9a97, 0x248a,
+ 0x9a98, 0x3843,
+ 0x9a9a, 0x2489,
+ 0x9a9b, 0x248b,
+ 0x9a9c, 0x3845,
+ 0x9a9e, 0x1f83,
+ 0x9a9f, 0x3847,
+ 0x9aa2, 0x210f,
+ 0x9aa3, 0x1fdb,
+ 0x9aa4, 0x384a,
+ 0x9aaa, 0x20af,
+ 0x9aab, 0x3850,
+ 0x9ad0, 0x24c0,
+ 0x9ad1, 0x3875,
+ 0x9ad6, 0x226d,
+ 0x9ad7, 0x387a,
+ 0x9ada, 0x24c1,
+ 0x9adb, 0x387d,
+ 0x9ae2, 0x20ca,
+ 0x9ae3, 0x3884,
+ 0x9ae4, 0x20e7,
+ 0x9ae5, 0x24c2,
+ 0x9ae6, 0x3885,
+ 0x9b40, 0x389e,
+ 0x9b80, 0x38dd,
+ 0x9bd1, 0x23dc,
+ 0x9bd2, 0x392e,
+ 0x9bdc, 0x23db,
+ 0x9bdd, 0x3938,
+ 0x9c40, 0x395a,
+ 0x9c53, 0x205e,
+ 0x9c54, 0x396d,
+ 0x9c59, 0x2244,
+ 0x9c5a, 0x23e2,
+ 0x9c5b, 0x3972,
+ 0x9c5c, 0x20d4,
+ 0x9c5d, 0x3973,
+ 0x9c75, 0x219f,
+ 0x9c76, 0x398b,
+ 0x9c79, 0x1e66,
+ 0x9c7a, 0x398e,
+ 0x9c80, 0x3993,
+ 0x9c86, 0x1f63,
+ 0x9c87, 0x3999,
+ 0x9c9d, 0x23dd,
+ 0x9c9e, 0x39af,
+ 0x9cab, 0x216b,
+ 0x9cac, 0x39bc,
+ 0x9cca, 0x22b5,
+ 0x9ccb, 0x39da,
+ 0x9ccf, 0x1f26,
+ 0x9cd0, 0x39de,
+ 0x9ce6, 0x1e63,
+ 0x9ce7, 0x2088,
+ 0x9ce8, 0x39f4,
+ 0x9cec, 0x1ebd,
+ 0x9ced, 0x39f8,
+ 0x9cee, 0x2341,
+ 0x9cef, 0x39f9,
+ 0x9cfb, 0x1f4b,
+ 0x9cfc, 0x3a05,
+ 0x9cfe, 0x2292,
+ 0x9d40, 0x3a07,
+ 0x9d42, 0x2124,
+ 0x9d43, 0x3a09,
+ 0x9d46, 0x2048,
+ 0x9d47, 0x23e0,
+ 0x9d48, 0x3a0c,
+ 0x9d4d, 0x2077,
+ 0x9d4e, 0x3a11,
+ 0x9d4f, 0x223a,
+ 0x9d50, 0x3a12,
+ 0x9d61, 0x20b1,
+ 0x9d62, 0x3a23,
+ 0x9d68, 0x1f41,
+ 0x9d69, 0x201c,
+ 0x9d6a, 0x3a29,
+ 0x9d6e, 0x22b8,
+ 0x9d6f, 0x3a2d,
+ 0x9d71, 0x2276,
+ 0x9d72, 0x3a2f,
+ 0x9d75, 0x1f9b,
+ 0x9d76, 0x3a32,
+ 0x9d7b, 0x1f9f,
+ 0x9d7c, 0x3a37,
+ 0x9d7d, 0x25ca,
+ 0x9d7e, 0x3a38,
+ 0x9d80, 0x3a39,
+ 0x9d8a, 0x20be,
+ 0x9d8b, 0x3a43,
+ 0x9d8d, 0x1fb4,
+ 0x9d8e, 0x3a45,
+ 0x9d91, 0x23d7,
+ 0x9d92, 0x3a48,
+ 0x9d99, 0x2105,
+ 0x9d9a, 0x3a4f,
+ 0x9da1, 0x23e1,
+ 0x9da2, 0x1fec,
+ 0x9da3, 0x3a56,
+ 0x9da7, 0x23ea,
+ 0x9da8, 0x3a5a,
+ 0x9dac, 0x23e3,
+ 0x9dad, 0x210e,
+ 0x9dae, 0x3a5e,
+ 0x9db2, 0x1fa6,
+ 0x9db3, 0x2004,
+ 0x9db4, 0x3a62,
+ 0x9dbe, 0x1f9d,
+ 0x9dbf, 0x3a6c,
+ 0x9dc6, 0x23e5,
+ 0x9dc7, 0x3a73,
+ 0x9dc9, 0x2264,
+ 0x9dca, 0x3a75,
+ 0x9dcd, 0x24e2,
+ 0x9dce, 0x3a78,
+ 0x9dd2, 0x23de,
+ 0x9dd3, 0x3a7c,
+ 0x9dd5, 0x1ec4,
+ 0x9dd6, 0x3a7e,
+ 0x9de1, 0x22b6,
+ 0x9de2, 0x20a9,
+ 0x9de3, 0x3a89,
+ 0x9df1, 0x212b,
+ 0x9df2, 0x3a97,
+ 0x9df4, 0x20a5,
+ 0x9df5, 0x3a99,
+ 0x9df7, 0x268b,
+ 0x9df8, 0x3a9b,
+ 0x9dfa, 0x1f76,
+ 0x9dfb, 0x3a9d,
+ 0x9dfd, 0x216d,
+ 0x9dfe, 0x3a9f,
+ 0x9e40, 0x3aa0,
+ 0x9e45, 0x2001,
+ 0x9e46, 0x3aa5,
+ 0x9e48, 0x2191,
+ 0x9e49, 0x1e50,
+ 0x9e4a, 0x3aa7,
+ 0x9e52, 0x1f9c,
+ 0x9e53, 0x3aaf,
+ 0x9e54, 0x23da,
+ 0x9e55, 0x3ab0,
+ 0x9e56, 0x2053,
+ 0x9e57, 0x3ab1,
+ 0x9e5d, 0x23e9,
+ 0x9e5e, 0x23e4,
+ 0x9e5f, 0x3ab7,
+ 0x9e61, 0x21d5,
+ 0x9e62, 0x3ab9,
+ 0x9e63, 0x23e6,
+ 0x9e64, 0x3aba,
+ 0x9e67, 0x23df,
+ 0x9e68, 0x3abd,
+ 0x9e6c, 0x1e4f,
+ 0x9e6d, 0x3ac1,
+ 0x9e6f, 0x23d9,
+ 0x9e70, 0x3ac3,
+ 0x9e72, 0x2014,
+ 0x9e73, 0x3ac5,
+ 0x9e74, 0x23ec,
+ 0x9e75, 0x23eb,
+ 0x9e76, 0x3ac6,
+ 0x9e7b, 0x23d8,
+ 0x9e7c, 0x23ee,
+ 0x9e7d, 0x3acb,
+ 0x9e80, 0x3acd,
+ 0x9e85, 0x268e,
+ 0x9e86, 0x3ad2,
+ 0x9e87, 0x23ed,
+ 0x9e88, 0x3ad3,
+ 0x9e91, 0x1ffa,
+ 0x9e92, 0x3adc,
+ 0x9e96, 0x23d6,
+ 0x9e97, 0x23e8,
+ 0x9e98, 0x3ae0,
+ 0x9ea2, 0x2106,
+ 0x9ea3, 0x3aea,
+ 0x9ea6, 0x200b,
+ 0x9ea7, 0x3aed,
+ 0x9ea9, 0x2166,
+ 0x9eaa, 0x3aef,
+ 0x9eae, 0x23ef,
+ 0x9eaf, 0x3af3,
+ 0x9eb3, 0x2189,
+ 0x9eb4, 0x2058,
+ 0x9eb5, 0x3af7,
+ 0x9eb7, 0x23e7,
+ 0x9eb8, 0x3af9,
+ 0x9ef5, 0x21a3,
+ 0x9ef6, 0x3b36,
+ 0x9f40, 0x3b3f,
+ 0x9f4e, 0x217a,
+ 0x9f4f, 0x3b4d,
+ 0x9f6f, 0x21a5,
+ 0x9f70, 0x3b6d,
+ 0x9f80, 0x3b7c,
+ 0x9f92, 0x2022,
+ 0x9f93, 0x3b8e,
+ 0x9f98, 0x24d6,
+ 0x9f99, 0x3b93,
+ 0x9fa6, 0x233a,
+ 0x9fa7, 0x3ba0,
+ 0x9fa9, 0x1eee,
+ 0x9faa, 0x3ba2,
+ 0x9fac, 0x24d5,
+ 0x9fad, 0x3ba4,
+ 0x9fc9, 0x2228,
+ 0x9fca, 0x3bc0,
+ 0x9fcd, 0x24d7,
+ 0x9fce, 0x3bc3,
+ 0x9fe1, 0x20fc,
+ 0x9fe2, 0x3bd6,
+ 0x9feb, 0x1e87,
+ 0x9fec, 0x3bdf,
+ 0x9fee, 0x24d8,
+ 0x9fef, 0x3be1,
+ 0x9ff4, 0x1eba,
+ 0x9ff5, 0x3be6,
+ 0x9ffd, 0x2119,
+ 0x9ffe, 0x3bee,
+ 0xa040, 0x3bef,
+ 0xa043, 0x216c,
+ 0xa044, 0x3bf2,
+ 0xa046, 0x24d9,
+ 0xa047, 0x3bf4,
+ 0xa049, 0x2227,
+ 0xa04a, 0x3bf6,
+ 0xa04e, 0x1e5f,
+ 0xa04f, 0x3bfa,
+ 0xa054, 0x229f,
+ 0xa055, 0x3bff,
+ 0xa05a, 0x1f5d,
+ 0xa05b, 0x3c04,
+ 0xa061, 0x1fbc,
+ 0xa062, 0x3c0a,
+ 0xa063, 0x24da,
+ 0xa064, 0x3c0b,
+ 0xa071, 0x2149,
+ 0xa072, 0x3c18,
+ 0xa074, 0x2046,
+ 0xa075, 0x3c1a,
+ 0xa080, 0x2000,
+ 0xa081, 0x3c24,
+ 0xa091, 0x2190,
+ 0xa092, 0x3c34,
+ 0xa094, 0x2208,
+ 0xa095, 0x3c36,
+ 0xa096, 0x1ee6,
+ 0xa097, 0x3c37,
+ 0xa0a9, 0x24c3,
+ 0xa0aa, 0x3c49,
+ 0xa0bf, 0x20cc,
+ 0xa0c0, 0x3c5e,
+ 0xa0ce, 0x2340,
+ 0xa0cf, 0x3c6c,
+ 0xa0d9, 0x1ed1,
+ 0xa0da, 0x3c76,
+ 0xa0de, 0x21ac,
+ 0xa0df, 0x3c7a,
+ 0xa0ee, 0x22af,
+ 0xa0ef, 0x3c89,
+ 0xa1a1, 0x0060,
+ 0xa2a1, 0x26a9,
+ 0xa2b1, 0x00be,
+ 0xa2e5, 0x00f0,
+ 0xa2f1, 0x00fa,
+ 0xa3a1, 0x0106,
+ 0xa4a1, 0x0164,
+ 0xa5a1, 0x01b7,
+ 0xa6a1, 0x020d,
+ 0xa6c1, 0x0225,
+ 0xa7a1, 0x025a,
+ 0xa7d1, 0x027b,
+ 0xa840, 0x26b3,
+ 0xa880, 0x26f2,
+ 0xa8a1, 0x029c,
+ 0xa8c5, 0x02bc,
+ 0xa940, 0x2708,
+ 0xa959, 0x2720,
+ 0xa95c, 0x2722,
+ 0xa960, 0x2723,
+ 0xa980, 0x2742,
+ 0xa996, 0x1e17,
+ 0xa9a4, 0x02e2,
+ 0xaa40, 0x3c99,
+ 0xaa4d, 0x21b6,
+ 0xaa4e, 0x1e3d,
+ 0xaa4f, 0x3ca6,
+ 0xaa71, 0x2235,
+ 0xaa72, 0x3cc8,
+ 0xaa73, 0x2397,
+ 0xaa74, 0x3cc9,
+ 0xaa77, 0x2395,
+ 0xaa78, 0x3ccc,
+ 0xaa7a, 0x223f,
+ 0xaa7b, 0x212a,
+ 0xaa7c, 0x3cce,
+ 0xaa80, 0x3cd1,
+ 0xaa9a, 0x1ed2,
+ 0xaa9b, 0x3ceb,
+ 0xaa9c, 0x2396,
+ 0xaa9d, 0x2398,
+ 0xaa9e, 0x3cec,
+ 0xaa9f, 0x20a2,
+ 0xaaa0, 0x3ced,
+ 0xaaa1, 0x032e,
+ 0xab40, 0x1f64,
+ 0xab41, 0x3cee,
+ 0xab43, 0x202b,
+ 0xab44, 0x3cf0,
+ 0xab45, 0x2394,
+ 0xab46, 0x2139,
+ 0xab47, 0x3cf1,
+ 0xab48, 0x215f,
+ 0xab49, 0x21c1,
+ 0xab4a, 0x239a,
+ 0xab4b, 0x3cf2,
+ 0xab4d, 0x2399,
+ 0xab4e, 0x3cf4,
+ 0xab80, 0x3d25,
+ 0xaba1, 0x038c,
+ 0xac40, 0x3d46,
+ 0xac46, 0x21c0,
+ 0xac47, 0x3d4c,
+ 0xac71, 0x2460,
+ 0xac72, 0x3d76,
+ 0xac7c, 0x245c,
+ 0xac7d, 0x3d80,
+ 0xac80, 0x3d82,
+ 0xac8d, 0x215d,
+ 0xac8e, 0x3d8f,
+ 0xac93, 0x2225,
+ 0xac94, 0x206a,
+ 0xac95, 0x3d94,
+ 0xad40, 0x3da0,
+ 0xad49, 0x2461,
+ 0xad4a, 0x3da9,
+ 0xad5e, 0x245b,
+ 0xad5f, 0x3dbd,
+ 0xad61, 0x2462,
+ 0xad62, 0x3dbf,
+ 0xad68, 0x1f54,
+ 0xad69, 0x3dc5,
+ 0xad74, 0x245f,
+ 0xad75, 0x3dd0,
+ 0xad80, 0x3dda,
+ 0xad82, 0x20ec,
+ 0xad83, 0x3ddc,
+ 0xad87, 0x245d,
+ 0xad88, 0x3de0,
+ 0xad8b, 0x2463,
+ 0xad8c, 0x3de3,
+ 0xad91, 0x2464,
+ 0xad92, 0x3de8,
+ 0xae40, 0x3df7,
+ 0xae54, 0x24a5,
+ 0xae55, 0x3e0b,
+ 0xae62, 0x1e70,
+ 0xae63, 0x3e18,
+ 0xae80, 0x208f,
+ 0xae81, 0x3e34,
+ 0xae85, 0x1e42,
+ 0xae86, 0x3e38,
+ 0xae8b, 0x1f4e,
+ 0xae8c, 0x3e3d,
+ 0xae94, 0x1eb1,
+ 0xae95, 0x3e45,
+ 0xaea0, 0x1e8b,
+ 0xaf40, 0x3e50,
+ 0xaf64, 0x1fc6,
+ 0xaf65, 0x3e74,
+ 0xaf7b, 0x25ae,
+ 0xaf7c, 0x3e8a,
+ 0xaf80, 0x3e8d,
+ 0xaf82, 0x1f01,
+ 0xaf83, 0x2200,
+ 0xaf84, 0x3e8f,
+ 0xaf8e, 0x25b2,
+ 0xaf8f, 0x1e97,
+ 0xaf90, 0x3e99,
+ 0xaf91, 0x20ab,
+ 0xaf92, 0x3e9a,
+ 0xaf9c, 0x25b3,
+ 0xaf9d, 0x3ea4,
+ 0xaf9f, 0x2028,
+ 0xafa0, 0x3ea6,
+ 0xb040, 0x3ea7,
+ 0xb041, 0x25af,
+ 0xb043, 0x3ea8,
+ 0xb044, 0x25b1,
+ 0xb045, 0x3ea9,
+ 0xb04f, 0x25ac,
+ 0xb050, 0x3eb3,
+ 0xb054, 0x1e4e,
+ 0xb055, 0x3eb7,
+ 0xb057, 0x2202,
+ 0xb058, 0x25ab,
+ 0xb059, 0x2286,
+ 0xb05a, 0x3eb9,
+ 0xb05b, 0x25ad,
+ 0xb05c, 0x3eba,
+ 0xb05d, 0x25b6,
+ 0xb05e, 0x3ebb,
+ 0xb05f, 0x21e3,
+ 0xb060, 0x25b4,
+ 0xb062, 0x222f,
+ 0xb063, 0x2165,
+ 0xb064, 0x25b7,
+ 0xb065, 0x3ebc,
+ 0xb06c, 0x1ee9,
+ 0xb06d, 0x3ec3,
+ 0xb07d, 0x1e25,
+ 0xb07e, 0x3ed3,
+ 0xb080, 0x3ed4,
+ 0xb097, 0x25c0,
+ 0xb098, 0x3eeb,
+ 0xb099, 0x229a,
+ 0xb09a, 0x3eec,
+ 0xb0a1, 0x03ac,
+ 0xb140, 0x3ef3,
+ 0xb14b, 0x226e,
+ 0xb14c, 0x3efe,
+ 0xb14d, 0x1fbd,
+ 0xb14e, 0x3eff,
+ 0xb14f, 0x1f84,
+ 0xb150, 0x20b2,
+ 0xb151, 0x3f00,
+ 0xb152, 0x2043,
+ 0xb153, 0x3f01,
+ 0xb180, 0x3f2d,
+ 0xb197, 0x2684,
+ 0xb198, 0x3f44,
+ 0xb1a1, 0x040a,
+ 0xb240, 0x3f4d,
+ 0xb241, 0x24ef,
+ 0xb242, 0x3f4e,
+ 0xb267, 0x24ee,
+ 0xb268, 0x3f73,
+ 0xb26d, 0x2074,
+ 0xb26e, 0x3f78,
+ 0xb274, 0x2687,
+ 0xb275, 0x3f7e,
+ 0xb280, 0x24f0,
+ 0xb281, 0x3f88,
+ 0xb289, 0x268d,
+ 0xb28a, 0x3f90,
+ 0xb29a, 0x22a0,
+ 0xb29b, 0x3fa0,
+ 0xb2a1, 0x0468,
+ 0xb340, 0x3fa6,
+ 0xb343, 0x1fab,
+ 0xb344, 0x3fa9,
+ 0xb370, 0x26a8,
+ 0xb371, 0x3fd5,
+ 0xb380, 0x3fe3,
+ 0xb388, 0x24e9,
+ 0xb389, 0x3feb,
+ 0xb38c, 0x24e5,
+ 0xb38d, 0x3fee,
+ 0xb38e, 0x21fa,
+ 0xb38f, 0x3fef,
+ 0xb3a1, 0x04c6,
+ 0xb440, 0x4001,
+ 0xb454, 0x2148,
+ 0xb455, 0x4015,
+ 0xb458, 0x24e4,
+ 0xb459, 0x4018,
+ 0xb45e, 0x24e6,
+ 0xb45f, 0x20f7,
+ 0xb460, 0x401d,
+ 0xb461, 0x206b,
+ 0xb462, 0x401e,
+ 0xb475, 0x22a7,
+ 0xb476, 0x4031,
+ 0xb47e, 0x24ec,
+ 0xb480, 0x4039,
+ 0xb483, 0x24eb,
+ 0xb484, 0x403c,
+ 0xb489, 0x24e3,
+ 0xb48a, 0x4041,
+ 0xb493, 0x24ea,
+ 0xb494, 0x404a,
+ 0xb4a1, 0x0524,
+ 0xb540, 0x4057,
+ 0xb541, 0x1e92,
+ 0xb542, 0x4058,
+ 0xb54b, 0x1e27,
+ 0xb54c, 0x4061,
+ 0xb556, 0x1fe6,
+ 0xb557, 0x406b,
+ 0xb55a, 0x24e7,
+ 0xb55b, 0x2012,
+ 0xb55c, 0x1eec,
+ 0xb55d, 0x406e,
+ 0xb561, 0x24e8,
+ 0xb562, 0x4072,
+ 0xb580, 0x408f,
+ 0xb59c, 0x1f66,
+ 0xb59d, 0x24dc,
+ 0xb59e, 0x40ab,
+ 0xb5a1, 0x0582,
+ 0xb640, 0x40ae,
+ 0xb652, 0x26a2,
+ 0xb653, 0x40c0,
+ 0xb655, 0x24dd,
+ 0xb656, 0x40c2,
+ 0xb659, 0x200e,
+ 0xb65a, 0x40c5,
+ 0xb65b, 0x24db,
+ 0xb65c, 0x1eb8,
+ 0xb65d, 0x40c6,
+ 0xb680, 0x40e8,
+ 0xb6a1, 0x05e0,
+ 0xb740, 0x4109,
+ 0xb74e, 0x2295,
+ 0xb74f, 0x4117,
+ 0xb751, 0x1e80,
+ 0xb752, 0x4119,
+ 0xb759, 0x2677,
+ 0xb75a, 0x4120,
+ 0xb764, 0x2624,
+ 0xb765, 0x1f69,
+ 0xb766, 0x222b,
+ 0xb767, 0x412a,
+ 0xb777, 0x257f,
+ 0xb778, 0x1f5b,
+ 0xb779, 0x413a,
+ 0xb780, 0x219b,
+ 0xb781, 0x4140,
+ 0xb782, 0x267d,
+ 0xb783, 0x4141,
+ 0xb7a1, 0x063e,
+ 0xb840, 0x415f,
+ 0xb843, 0x21a0,
+ 0xb844, 0x2186,
+ 0xb845, 0x4162,
+ 0xb846, 0x20ed,
+ 0xb847, 0x4163,
+ 0xb84d, 0x25b9,
+ 0xb84e, 0x4169,
+ 0xb851, 0x1fea,
+ 0xb852, 0x416c,
+ 0xb85a, 0x1ea4,
+ 0xb85b, 0x20e1,
+ 0xb85c, 0x4174,
+ 0xb85d, 0x25b8,
+ 0xb85e, 0x2260,
+ 0xb85f, 0x4175,
+ 0xb860, 0x20e2,
+ 0xb861, 0x4176,
+ 0xb877, 0x2141,
+ 0xb878, 0x418c,
+ 0xb880, 0x4193,
+ 0xb882, 0x1fc7,
+ 0xb883, 0x4195,
+ 0xb8a1, 0x069c,
+ 0xb940, 0x41b3,
+ 0xb950, 0x1e41,
+ 0xb951, 0x41c3,
+ 0xb961, 0x25e4,
+ 0xb962, 0x41d3,
+ 0xb97b, 0x1f86,
+ 0xb97c, 0x41ec,
+ 0xb980, 0x41ef,
+ 0xb99d, 0x1fb3,
+ 0xb99e, 0x420c,
+ 0xb9a0, 0x1eef,
+ 0xb9a1, 0x06fa,
+ 0xba40, 0x420e,
+ 0xba42, 0x22a4,
+ 0xba43, 0x4210,
+ 0xba44, 0x25e8,
+ 0xba45, 0x4211,
+ 0xba56, 0x25e3,
+ 0xba57, 0x4222,
+ 0xba59, 0x2111,
+ 0xba5a, 0x4224,
+ 0xba60, 0x25e6,
+ 0xba61, 0x422a,
+ 0xba6a, 0x25e7,
+ 0xba6b, 0x4233,
+ 0xba74, 0x2041,
+ 0xba75, 0x423c,
+ 0xba80, 0x4246,
+ 0xba84, 0x25ea,
+ 0xba85, 0x424a,
+ 0xba86, 0x1f8f,
+ 0xba87, 0x424b,
+ 0xba88, 0x25ec,
+ 0xba89, 0x424c,
+ 0xba8d, 0x25eb,
+ 0xba8e, 0x4250,
+ 0xba9e, 0x20d0,
+ 0xba9f, 0x201d,
+ 0xbaa0, 0x4260,
+ 0xbaa1, 0x0758,
+ 0xbb40, 0x1ff7,
+ 0xbb41, 0x4261,
+ 0xbb49, 0x1e8d,
+ 0xbb4a, 0x4269,
+ 0xbb58, 0x25e9,
+ 0xbb59, 0x4277,
+ 0xbb5b, 0x25ee,
+ 0xbb5c, 0x203a,
+ 0xbb5d, 0x4279,
+ 0xbb60, 0x2693,
+ 0xbb61, 0x427c,
+ 0xbb65, 0x25e5,
+ 0xbb66, 0x25ed,
+ 0xbb67, 0x4280,
+ 0xbb68, 0x2009,
+ 0xbb69, 0x4281,
+ 0xbb6a, 0x2065,
+ 0xbb6b, 0x4282,
+ 0xbb6e, 0x26a3,
+ 0xbb6f, 0x4285,
+ 0xbb80, 0x4295,
+ 0xbba1, 0x07b6,
+ 0xbc40, 0x42b6,
+ 0xbc52, 0x25f5,
+ 0xbc53, 0x1efc,
+ 0xbc54, 0x42c8,
+ 0xbc5a, 0x2024,
+ 0xbc5b, 0x42ce,
+ 0xbc61, 0x269b,
+ 0xbc62, 0x42d4,
+ 0xbc63, 0x25f3,
+ 0xbc64, 0x42d5,
+ 0xbc65, 0x22d9,
+ 0xbc66, 0x42d6,
+ 0xbc67, 0x25f4,
+ 0xbc68, 0x42d7,
+ 0xbc69, 0x241b,
+ 0xbc6a, 0x42d8,
+ 0xbc6d, 0x1fc8,
+ 0xbc6e, 0x42db,
+ 0xbc6f, 0x1f7b,
+ 0xbc70, 0x42dc,
+ 0xbc71, 0x241d,
+ 0xbc72, 0x42dd,
+ 0xbc73, 0x224c,
+ 0xbc74, 0x1f48,
+ 0xbc75, 0x241c,
+ 0xbc76, 0x241e,
+ 0xbc78, 0x20ff,
+ 0xbc79, 0x219a,
+ 0xbc7a, 0x42de,
+ 0xbc7b, 0x2091,
+ 0xbc7c, 0x42df,
+ 0xbc7e, 0x20a7,
+ 0xbc80, 0x42e1,
+ 0xbc82, 0x2423,
+ 0xbc83, 0x1e9b,
+ 0xbc84, 0x2422,
+ 0xbc85, 0x42e3,
+ 0xbc86, 0x2110,
+ 0xbc87, 0x42e4,
+ 0xbc88, 0x228d,
+ 0xbc89, 0x1f71,
+ 0xbc8a, 0x1ef8,
+ 0xbc8b, 0x2421,
+ 0xbc8c, 0x42e5,
+ 0xbc8f, 0x1ef3,
+ 0xbc90, 0x42e8,
+ 0xbc9a, 0x21b1,
+ 0xbc9b, 0x2426,
+ 0xbc9c, 0x2425,
+ 0xbc9d, 0x2120,
+ 0xbc9e, 0x42f2,
+ 0xbca1, 0x0814,
+ 0xbd40, 0x42f5,
+ 0xbd42, 0x211a,
+ 0xbd43, 0x2424,
+ 0xbd44, 0x42f7,
+ 0xbd45, 0x2428,
+ 0xbd46, 0x42f8,
+ 0xbd48, 0x242a,
+ 0xbd49, 0x2429,
+ 0xbd4a, 0x42fa,
+ 0xbd4b, 0x2294,
+ 0xbd4c, 0x42fb,
+ 0xbd4d, 0x22be,
+ 0xbd4e, 0x42fc,
+ 0xbd4f, 0x1e31,
+ 0xbd50, 0x42fd,
+ 0xbd57, 0x242c,
+ 0xbd58, 0x4304,
+ 0xbd59, 0x1fb5,
+ 0xbd5a, 0x4305,
+ 0xbd66, 0x242b,
+ 0xbd67, 0x1faf,
+ 0xbd68, 0x4311,
+ 0xbd6a, 0x2068,
+ 0xbd6b, 0x21e4,
+ 0xbd6c, 0x4313,
+ 0xbd6f, 0x1f21,
+ 0xbd70, 0x4316,
+ 0xbd71, 0x2101,
+ 0xbd72, 0x4317,
+ 0xbd79, 0x217c,
+ 0xbd7a, 0x214a,
+ 0xbd7b, 0x242d,
+ 0xbd7c, 0x431e,
+ 0xbd7e, 0x1fd4,
+ 0xbd80, 0x4320,
+ 0xbd81, 0x1fd1,
+ 0xbd82, 0x4321,
+ 0xbd89, 0x1e33,
+ 0xbd8a, 0x4328,
+ 0xbd8b, 0x242f,
+ 0xbd8c, 0x4329,
+ 0xbd8e, 0x242e,
+ 0xbd8f, 0x432b,
+ 0xbd90, 0x2430,
+ 0xbd91, 0x21db,
+ 0xbd92, 0x432c,
+ 0xbd97, 0x2158,
+ 0xbd98, 0x4331,
+ 0xbd9b, 0x1fc2,
+ 0xbd9c, 0x4334,
+ 0xbda1, 0x0872,
+ 0xbe40, 0x4339,
+ 0xbe43, 0x22b9,
+ 0xbe44, 0x433c,
+ 0xbe45, 0x2436,
+ 0xbe46, 0x433d,
+ 0xbe49, 0x1e8e,
+ 0xbe4a, 0x2439,
+ 0xbe4b, 0x4340,
+ 0xbe51, 0x21c5,
+ 0xbe52, 0x2437,
+ 0xbe53, 0x2192,
+ 0xbe54, 0x4346,
+ 0xbe55, 0x243a,
+ 0xbe56, 0x1f19,
+ 0xbe57, 0x218c,
+ 0xbe58, 0x1e40,
+ 0xbe59, 0x22b3,
+ 0xbe5a, 0x4347,
+ 0xbe5d, 0x205f,
+ 0xbe5e, 0x2438,
+ 0xbe5f, 0x2432,
+ 0xbe60, 0x2274,
+ 0xbe61, 0x434a,
+ 0xbe62, 0x1e9c,
+ 0xbe63, 0x2431,
+ 0xbe64, 0x2085,
+ 0xbe65, 0x434b,
+ 0xbe69, 0x2435,
+ 0xbe6a, 0x434f,
+ 0xbe6c, 0x243b,
+ 0xbe6d, 0x4351,
+ 0xbe6f, 0x1fb7,
+ 0xbe70, 0x2433,
+ 0xbe71, 0x4353,
+ 0xbe76, 0x2054,
+ 0xbe77, 0x21de,
+ 0xbe78, 0x4358,
+ 0xbe79, 0x2434,
+ 0xbe7a, 0x4359,
+ 0xbe7c, 0x243d,
+ 0xbe7d, 0x1f89,
+ 0xbe7e, 0x243c,
+ 0xbe80, 0x435b,
+ 0xbe83, 0x1f6e,
+ 0xbe84, 0x1ed8,
+ 0xbe85, 0x435e,
+ 0xbe86, 0x1ebf,
+ 0xbe87, 0x2445,
+ 0xbe88, 0x435f,
+ 0xbe89, 0x2249,
+ 0xbe8a, 0x4360,
+ 0xbe8c, 0x2441,
+ 0xbe8d, 0x4362,
+ 0xbe8e, 0x1e47,
+ 0xbe8f, 0x1f56,
+ 0xbe90, 0x4363,
+ 0xbe92, 0x2086,
+ 0xbe93, 0x4365,
+ 0xbe95, 0x2196,
+ 0xbe96, 0x4367,
+ 0xbe97, 0x2443,
+ 0xbe98, 0x243f,
+ 0xbe99, 0x4368,
+ 0xbe9a, 0x2023,
+ 0xbe9b, 0x4369,
+ 0xbe9c, 0x2442,
+ 0xbe9d, 0x436a,
+ 0xbe9f, 0x243e,
+ 0xbea0, 0x436c,
+ 0xbea1, 0x08d0,
+ 0xbf40, 0x26a6,
+ 0xbf41, 0x436d,
+ 0xbf4d, 0x234e,
+ 0xbf4e, 0x2446,
+ 0xbf4f, 0x244b,
+ 0xbf50, 0x2444,
+ 0xbf51, 0x4379,
+ 0xbf55, 0x2427,
+ 0xbf56, 0x244c,
+ 0xbf57, 0x437d,
+ 0xbf60, 0x1f0f,
+ 0xbf61, 0x4386,
+ 0xbf62, 0x2447,
+ 0xbf63, 0x2449,
+ 0xbf64, 0x2448,
+ 0xbf65, 0x4387,
+ 0xbf68, 0x21c2,
+ 0xbf69, 0x438a,
+ 0xbf6c, 0x216e,
+ 0xbf6d, 0x438d,
+ 0xbf70, 0x1f03,
+ 0xbf71, 0x4390,
+ 0xbf72, 0x244a,
+ 0xbf73, 0x215c,
+ 0xbf74, 0x4391,
+ 0xbf76, 0x22bb,
+ 0xbf77, 0x2450,
+ 0xbf78, 0x4393,
+ 0xbf79, 0x2694,
+ 0xbf7a, 0x244f,
+ 0xbf7b, 0x25f6,
+ 0xbf7c, 0x2051,
+ 0xbf7d, 0x4394,
+ 0xbf7e, 0x244e,
+ 0xbf80, 0x4395,
+ 0xbf82, 0x22ba,
+ 0xbf83, 0x1f6d,
+ 0xbf84, 0x4397,
+ 0xbf89, 0x2452,
+ 0xbf8a, 0x2451,
+ 0xbf8b, 0x439c,
+ 0xbf95, 0x2455,
+ 0xbf96, 0x43a6,
+ 0xbf97, 0x2289,
+ 0xbf98, 0x2116,
+ 0xbf99, 0x43a7,
+ 0xbf9d, 0x2454,
+ 0xbf9e, 0x43ab,
+ 0xbfa1, 0x092e,
+ 0xc040, 0x20fb,
+ 0xc041, 0x43ae,
+ 0xc044, 0x2440,
+ 0xc045, 0x43b1,
+ 0xc04b, 0x2126,
+ 0xc04c, 0x1f61,
+ 0xc04d, 0x269d,
+ 0xc04e, 0x43b7,
+ 0xc04f, 0x1f8a,
+ 0xc050, 0x2456,
+ 0xc051, 0x2459,
+ 0xc052, 0x2458,
+ 0xc053, 0x43b8,
+ 0xc055, 0x1fae,
+ 0xc056, 0x43ba,
+ 0xc05b, 0x221a,
+ 0xc05c, 0x43bf,
+ 0xc05e, 0x1f7a,
+ 0xc05f, 0x244d,
+ 0xc060, 0x2457,
+ 0xc061, 0x43c1,
+ 0xc069, 0x2453,
+ 0xc06a, 0x43c9,
+ 0xc06b, 0x2420,
+ 0xc06c, 0x43ca,
+ 0xc06d, 0x21df,
+ 0xc06e, 0x2685,
+ 0xc06f, 0x43cb,
+ 0xc070, 0x1e6e,
+ 0xc071, 0x43cc,
+ 0xc074, 0x2224,
+ 0xc075, 0x2670,
+ 0xc076, 0x43cf,
+ 0xc077, 0x21ba,
+ 0xc078, 0x43d0,
+ 0xc079, 0x245a,
+ 0xc07a, 0x43d1,
+ 0xc07c, 0x1fff,
+ 0xc07d, 0x43d3,
+ 0xc080, 0x43d5,
+ 0xc09b, 0x25e2,
+ 0xc09c, 0x43f0,
+ 0xc09d, 0x269a,
+ 0xc09e, 0x43f1,
+ 0xc0a1, 0x098c,
+ 0xc140, 0x43f4,
+ 0xc150, 0x1eea,
+ 0xc151, 0x4404,
+ 0xc154, 0x1e2c,
+ 0xc155, 0x4407,
+ 0xc15f, 0x2062,
+ 0xc160, 0x24f1,
+ 0xc161, 0x4411,
+ 0xc162, 0x24f2,
+ 0xc163, 0x4412,
+ 0xc175, 0x25f2,
+ 0xc176, 0x4424,
+ 0xc178, 0x2215,
+ 0xc179, 0x4426,
+ 0xc180, 0x442c,
+ 0xc195, 0x21ae,
+ 0xc196, 0x4441,
+ 0xc1a1, 0x09ea,
+ 0xc240, 0x444c,
+ 0xc24e, 0x20e0,
+ 0xc24f, 0x445a,
+ 0xc265, 0x25c2,
+ 0xc266, 0x4470,
+ 0xc267, 0x25c1,
+ 0xc268, 0x4471,
+ 0xc27d, 0x2128,
+ 0xc27e, 0x4486,
+ 0xc280, 0x4487,
+ 0xc284, 0x2199,
+ 0xc285, 0x448b,
+ 0xc293, 0x2017,
+ 0xc294, 0x1ea0,
+ 0xc295, 0x2125,
+ 0xc296, 0x214d,
+ 0xc297, 0x4499,
+ 0xc298, 0x25c4,
+ 0xc299, 0x209d,
+ 0xc29a, 0x228a,
+ 0xc29b, 0x449a,
+ 0xc29c, 0x25c3,
+ 0xc29d, 0x449b,
+ 0xc2a0, 0x2179,
+ 0xc2a1, 0x0a48,
+ 0xc340, 0x2038,
+ 0xc341, 0x449e,
+ 0xc343, 0x2155,
+ 0xc344, 0x44a0,
+ 0xc37b, 0x21d2,
+ 0xc37c, 0x44d7,
+ 0xc380, 0x44da,
+ 0xc384, 0x24c7,
+ 0xc385, 0x44de,
+ 0xc39b, 0x2279,
+ 0xc39c, 0x44f4,
+ 0xc3a1, 0x0aa6,
+ 0xc440, 0x44f9,
+ 0xc449, 0x2123,
+ 0xc44a, 0x4502,
+ 0xc44c, 0x24c5,
+ 0xc44d, 0x4504,
+ 0xc454, 0x24c9,
+ 0xc455, 0x450b,
+ 0xc458, 0x2094,
+ 0xc459, 0x450e,
+ 0xc45b, 0x2296,
+ 0xc45c, 0x4510,
+ 0xc463, 0x1e77,
+ 0xc464, 0x4517,
+ 0xc477, 0x1f06,
+ 0xc478, 0x452a,
+ 0xc47a, 0x1fa5,
+ 0xc47b, 0x452c,
+ 0xc480, 0x4530,
+ 0xc481, 0x2099,
+ 0xc482, 0x4531,
+ 0xc491, 0x1ead,
+ 0xc492, 0x24c8,
+ 0xc493, 0x20a8,
+ 0xc494, 0x4540,
+ 0xc498, 0x201f,
+ 0xc499, 0x4544,
+ 0xc49a, 0x20c5,
+ 0xc49b, 0x4545,
+ 0xc49c, 0x24ca,
+ 0xc49d, 0x4546,
+ 0xc4a1, 0x0b04,
+ 0xc540, 0x454a,
+ 0xc544, 0x1ff0,
+ 0xc545, 0x454e,
+ 0xc546, 0x24c6,
+ 0xc547, 0x454f,
+ 0xc54b, 0x225d,
+ 0xc54c, 0x22de,
+ 0xc54d, 0x4553,
+ 0xc552, 0x202c,
+ 0xc553, 0x4558,
+ 0xc55f, 0x2161,
+ 0xc560, 0x4564,
+ 0xc563, 0x223b,
+ 0xc564, 0x21d9,
+ 0xc565, 0x1fcb,
+ 0xc566, 0x1fc9,
+ 0xc567, 0x4567,
+ 0xc580, 0x457f,
+ 0xc593, 0x1e61,
+ 0xc594, 0x4592,
+ 0xc59c, 0x25ef,
+ 0xc59d, 0x459a,
+ 0xc59e, 0x1f98,
+ 0xc59f, 0x459b,
+ 0xc5a1, 0x0b62,
+ 0xc640, 0x459d,
+ 0xc641, 0x25f0,
+ 0xc642, 0x459e,
+ 0xc644, 0x1f88,
+ 0xc645, 0x45a0,
+ 0xc647, 0x21f8,
+ 0xc648, 0x45a2,
+ 0xc663, 0x2322,
+ 0xc664, 0x45bd,
+ 0xc672, 0x2336,
+ 0xc673, 0x45cb,
+ 0xc680, 0x45d7,
+ 0xc6a1, 0x0bc0,
+ 0xc740, 0x45f8,
+ 0xc766, 0x22ab,
+ 0xc767, 0x461e,
+ 0xc76f, 0x1fbf,
+ 0xc770, 0x4626,
+ 0xc776, 0x1f7d,
+ 0xc777, 0x462c,
+ 0xc77b, 0x2333,
+ 0xc77c, 0x4630,
+ 0xc780, 0x4633,
+ 0xc7a1, 0x0c1e,
+ 0xc840, 0x4654,
+ 0xc841, 0x1f4d,
+ 0xc842, 0x4655,
+ 0xc84f, 0x2334,
+ 0xc850, 0x4662,
+ 0xc852, 0x1ff1,
+ 0xc853, 0x4664,
+ 0xc866, 0x218b,
+ 0xc867, 0x4677,
+ 0xc86e, 0x2349,
+ 0xc86f, 0x467e,
+ 0xc87e, 0x220b,
+ 0xc880, 0x468d,
+ 0xc887, 0x2346,
+ 0xc888, 0x4694,
+ 0xc892, 0x2347,
+ 0xc893, 0x469e,
+ 0xc894, 0x2193,
+ 0xc895, 0x469f,
+ 0xc899, 0x26a1,
+ 0xc89a, 0x46a3,
+ 0xc89d, 0x1f62,
+ 0xc89e, 0x46a6,
+ 0xc8a1, 0x0c7c,
+ 0xc940, 0x46a9,
+ 0xc94f, 0x234d,
+ 0xc950, 0x2348,
+ 0xc951, 0x46b8,
+ 0xc96e, 0x1e60,
+ 0xc96f, 0x46d5,
+ 0xc970, 0x2345,
+ 0xc971, 0x46d6,
+ 0xc977, 0x1f12,
+ 0xc978, 0x46dc,
+ 0xc980, 0x46e3,
+ 0xc98f, 0x2018,
+ 0xc990, 0x2335,
+ 0xc991, 0x46f2,
+ 0xc99c, 0x233c,
+ 0xc99d, 0x46fd,
+ 0xc9a1, 0x0cda,
+ 0xca40, 0x4701,
+ 0xca4e, 0x266f,
+ 0xca4f, 0x470f,
+ 0xca56, 0x2351,
+ 0xca57, 0x4716,
+ 0xca59, 0x1fa0,
+ 0xca5a, 0x4718,
+ 0xca5c, 0x2338,
+ 0xca5d, 0x471a,
+ 0xca61, 0x221b,
+ 0xca62, 0x471e,
+ 0xca6e, 0x2342,
+ 0xca6f, 0x472a,
+ 0xca72, 0x234f,
+ 0xca73, 0x472d,
+ 0xca77, 0x233d,
+ 0xca78, 0x4731,
+ 0xca7b, 0x2344,
+ 0xca7c, 0x2331,
+ 0xca7d, 0x4734,
+ 0xca7e, 0x234b,
+ 0xca80, 0x4735,
+ 0xca81, 0x233b,
+ 0xca82, 0x4736,
+ 0xca89, 0x2350,
+ 0xca8a, 0x473d,
+ 0xca8e, 0x1eb4,
+ 0xca8f, 0x21a6,
+ 0xca90, 0x4741,
+ 0xca92, 0x21cb,
+ 0xca93, 0x4743,
+ 0xca9a, 0x2355,
+ 0xca9b, 0x474a,
+ 0xcaa1, 0x0d38,
+ 0xcb40, 0x4750,
+ 0xcb43, 0x233e,
+ 0xcb44, 0x4753,
+ 0xcb45, 0x1f74,
+ 0xcb46, 0x4754,
+ 0xcb47, 0x2330,
+ 0xcb48, 0x4755,
+ 0xcb4b, 0x2680,
+ 0xcb4c, 0x4758,
+ 0xcb4e, 0x20da,
+ 0xcb4f, 0x475a,
+ 0xcb57, 0x234a,
+ 0xcb58, 0x4762,
+ 0xcb5d, 0x1f91,
+ 0xcb5e, 0x4767,
+ 0xcb5f, 0x2107,
+ 0xcb60, 0x4768,
+ 0xcb6a, 0x233f,
+ 0xcb6b, 0x4772,
+ 0xcb7b, 0x1ff4,
+ 0xcb7c, 0x2343,
+ 0xcb7d, 0x4782,
+ 0xcb80, 0x4784,
+ 0xcb87, 0x2212,
+ 0xcb88, 0x478b,
+ 0xcb8e, 0x2207,
+ 0xcb8f, 0x4791,
+ 0xcb92, 0x2359,
+ 0xcb93, 0x4794,
+ 0xcb9c, 0x2254,
+ 0xcb9d, 0x479d,
+ 0xcb9e, 0x2332,
+ 0xcb9f, 0x479e,
+ 0xcba1, 0x0d96,
+ 0xcc40, 0x1e26,
+ 0xcc41, 0x2357,
+ 0xcc42, 0x47a0,
+ 0xcc49, 0x2358,
+ 0xcc4a, 0x2042,
+ 0xcc4b, 0x2153,
+ 0xcc4c, 0x47a7,
+ 0xcc4f, 0x20bb,
+ 0xcc50, 0x47aa,
+ 0xcc5c, 0x235a,
+ 0xcc5d, 0x47b6,
+ 0xcc60, 0x2356,
+ 0xcc61, 0x47b9,
+ 0xcc64, 0x2337,
+ 0xcc65, 0x47bc,
+ 0xcc6d, 0x1ff9,
+ 0xcc6e, 0x47c4,
+ 0xcc79, 0x2353,
+ 0xcc7a, 0x47cf,
+ 0xcc7d, 0x2061,
+ 0xcc7e, 0x47d2,
+ 0xcc80, 0x47d3,
+ 0xcc8e, 0x1e95,
+ 0xcc8f, 0x47e1,
+ 0xcc94, 0x2049,
+ 0xcc95, 0x47e6,
+ 0xcc96, 0x1f42,
+ 0xcc97, 0x47e7,
+ 0xcc9d, 0x1fe8,
+ 0xcc9e, 0x47ed,
+ 0xcca1, 0x0df4,
+ 0xcd40, 0x47f0,
+ 0xcd80, 0x482f,
+ 0xcd90, 0x25da,
+ 0xcd91, 0x483f,
+ 0xcd98, 0x25d7,
+ 0xcd99, 0x4846,
+ 0xcda1, 0x0e52,
+ 0xce40, 0x484e,
+ 0xce67, 0x212e,
+ 0xce68, 0x4875,
+ 0xce72, 0x21b2,
+ 0xce73, 0x487f,
+ 0xce80, 0x488b,
+ 0xce81, 0x219e,
+ 0xce82, 0x488c,
+ 0xce87, 0x25dc,
+ 0xce88, 0x4891,
+ 0xce9b, 0x206c,
+ 0xce9c, 0x48a4,
+ 0xce9e, 0x2226,
+ 0xce9f, 0x48a6,
+ 0xcea1, 0x0eb0,
+ 0xcf40, 0x48a8,
+ 0xcf4e, 0x25e0,
+ 0xcf4f, 0x48b6,
+ 0xcf55, 0x227b,
+ 0xcf56, 0x48bc,
+ 0xcf58, 0x25de,
+ 0xcf59, 0x48be,
+ 0xcf5c, 0x25e1,
+ 0xcf5d, 0x48c1,
+ 0xcf6c, 0x25d5,
+ 0xcf6d, 0x48d0,
+ 0xcf73, 0x1e6b,
+ 0xcf74, 0x48d6,
+ 0xcf75, 0x25db,
+ 0xcf76, 0x48d7,
+ 0xcf78, 0x1e89,
+ 0xcf79, 0x48d9,
+ 0xcf7c, 0x25d9,
+ 0xcf7d, 0x48dc,
+ 0xcf80, 0x48de,
+ 0xcf81, 0x2211,
+ 0xcf82, 0x48df,
+ 0xcf89, 0x2229,
+ 0xcf8a, 0x25d6,
+ 0xcf8b, 0x48e6,
+ 0xcf93, 0x25dd,
+ 0xcf94, 0x25df,
+ 0xcf95, 0x48ee,
+ 0xcf9e, 0x1fef,
+ 0xcf9f, 0x48f7,
+ 0xcfa0, 0x25d8,
+ 0xcfa1, 0x0f0e,
+ 0xd040, 0x48f8,
+ 0xd04d, 0x1f29,
+ 0xd04e, 0x4905,
+ 0xd051, 0x1e5b,
+ 0xd052, 0x4908,
+ 0xd055, 0x2076,
+ 0xd056, 0x490b,
+ 0xd05c, 0x2297,
+ 0xd05d, 0x4911,
+ 0xd060, 0x2690,
+ 0xd061, 0x4914,
+ 0xd067, 0x213f,
+ 0xd068, 0x491a,
+ 0xd06c, 0x2198,
+ 0xd06d, 0x491e,
+ 0xd06e, 0x1e88,
+ 0xd06f, 0x491f,
+ 0xd07d, 0x228c,
+ 0xd07e, 0x492d,
+ 0xd080, 0x492e,
+ 0xd0a1, 0x0f6c,
+ 0xd140, 0x494f,
+ 0xd155, 0x25f1,
+ 0xd156, 0x4964,
+ 0xd159, 0x200c,
+ 0xd15a, 0x4967,
+ 0xd161, 0x1e58,
+ 0xd162, 0x22ac,
+ 0xd163, 0x496e,
+ 0xd175, 0x26a7,
+ 0xd176, 0x4980,
+ 0xd17d, 0x2676,
+ 0xd17e, 0x4987,
+ 0xd180, 0x4988,
+ 0xd19d, 0x1fe1,
+ 0xd19e, 0x25bb,
+ 0xd19f, 0x49a5,
+ 0xd1a1, 0x0fca,
+ 0xd240, 0x25be,
+ 0xd241, 0x49a7,
+ 0xd243, 0x22dd,
+ 0xd244, 0x49a9,
+ 0xd24d, 0x25bd,
+ 0xd24e, 0x49b2,
+ 0xd25c, 0x1e2a,
+ 0xd25d, 0x49c0,
+ 0xd263, 0x25bc,
+ 0xd264, 0x25ba,
+ 0xd265, 0x49c6,
+ 0xd268, 0x25bf,
+ 0xd269, 0x49c9,
+ 0xd26d, 0x2187,
+ 0xd26e, 0x49cd,
+ 0xd26f, 0x266b,
+ 0xd270, 0x49ce,
+ 0xd272, 0x1e7f,
+ 0xd273, 0x49d0,
+ 0xd275, 0x21ad,
+ 0xd276, 0x49d2,
+ 0xd280, 0x49db,
+ 0xd28a, 0x1f96,
+ 0xd28b, 0x49e5,
+ 0xd28e, 0x1f32,
+ 0xd28f, 0x49e8,
+ 0xd292, 0x2084,
+ 0xd293, 0x49eb,
+ 0xd295, 0x2136,
+ 0xd296, 0x49ed,
+ 0xd297, 0x24b8,
+ 0xd298, 0x49ee,
+ 0xd2a0, 0x24ba,
+ 0xd2a1, 0x1028,
+ 0xd340, 0x49f6,
+ 0xd344, 0x24bc,
+ 0xd345, 0x49fa,
+ 0xd348, 0x20e4,
+ 0xd349, 0x49fd,
+ 0xd34a, 0x24b9,
+ 0xd34b, 0x49fe,
+ 0xd34d, 0x24bd,
+ 0xd34e, 0x4a00,
+ 0xd350, 0x24be,
+ 0xd351, 0x4a02,
+ 0xd355, 0x24bf,
+ 0xd356, 0x4a06,
+ 0xd358, 0x1fd2,
+ 0xd359, 0x4a08,
+ 0xd35b, 0x1ffd,
+ 0xd35c, 0x4a0a,
+ 0xd35d, 0x24bb,
+ 0xd35e, 0x1f2d,
+ 0xd35f, 0x4a0b,
+ 0xd378, 0x2609,
+ 0xd379, 0x4a24,
+ 0xd37a, 0x260a,
+ 0xd37b, 0x4a25,
+ 0xd37c, 0x1e94,
+ 0xd37d, 0x4a26,
+ 0xd380, 0x4a28,
+ 0xd385, 0x22df,
+ 0xd386, 0x1ecb,
+ 0xd387, 0x1f0d,
+ 0xd388, 0x4a2d,
+ 0xd38b, 0x1f77,
+ 0xd38c, 0x4a30,
+ 0xd38d, 0x21eb,
+ 0xd38e, 0x4a31,
+ 0xd38f, 0x22e1,
+ 0xd390, 0x4a32,
+ 0xd391, 0x216f,
+ 0xd392, 0x4a33,
+ 0xd393, 0x22e0,
+ 0xd394, 0x4a34,
+ 0xd396, 0x21ea,
+ 0xd397, 0x4a36,
+ 0xd398, 0x22e2,
+ 0xd399, 0x20cb,
+ 0xd39a, 0x4a37,
+ 0xd39b, 0x1f78,
+ 0xd39c, 0x4a38,
+ 0xd39e, 0x1ee2,
+ 0xd39f, 0x4a3a,
+ 0xd3a0, 0x21f2,
+ 0xd3a1, 0x1086,
+ 0xd440, 0x4a3b,
+ 0xd441, 0x2150,
+ 0xd442, 0x4a3c,
+ 0xd445, 0x1fd3,
+ 0xd446, 0x4a3f,
+ 0xd447, 0x22e5,
+ 0xd448, 0x4a40,
+ 0xd44c, 0x1ef2,
+ 0xd44d, 0x4a44,
+ 0xd44f, 0x211f,
+ 0xd450, 0x4a46,
+ 0xd453, 0x21dd,
+ 0xd454, 0x4a49,
+ 0xd456, 0x2154,
+ 0xd457, 0x4a4b,
+ 0xd458, 0x22e7,
+ 0xd459, 0x4a4c,
+ 0xd45c, 0x2282,
+ 0xd45d, 0x4a4f,
+ 0xd462, 0x22e6,
+ 0xd463, 0x4a54,
+ 0xd467, 0x22e8,
+ 0xd468, 0x4a58,
+ 0xd46e, 0x22e4,
+ 0xd46f, 0x4a5e,
+ 0xd470, 0x226a,
+ 0xd471, 0x4a5f,
+ 0xd472, 0x22eb,
+ 0xd473, 0x4a60,
+ 0xd474, 0x22e9,
+ 0xd475, 0x20bd,
+ 0xd476, 0x4a61,
+ 0xd478, 0x22ea,
+ 0xd479, 0x4a63,
+ 0xd47b, 0x22bd,
+ 0xd47c, 0x4a65,
+ 0xd47e, 0x1e9e,
+ 0xd480, 0x4a67,
+ 0xd482, 0x22f6,
+ 0xd483, 0x21e7,
+ 0xd484, 0x2216,
+ 0xd485, 0x4a69,
+ 0xd487, 0x2137,
+ 0xd488, 0x4a6b,
+ 0xd48a, 0x212c,
+ 0xd48b, 0x4a6d,
+ 0xd48c, 0x1e68,
+ 0xd48d, 0x22f2,
+ 0xd48e, 0x1f37,
+ 0xd48f, 0x22f3,
+ 0xd490, 0x4a6e,
+ 0xd491, 0x22ef,
+ 0xd492, 0x1f50,
+ 0xd493, 0x1f10,
+ 0xd494, 0x21c8,
+ 0xd495, 0x4a6f,
+ 0xd496, 0x22f1,
+ 0xd497, 0x4a70,
+ 0xd49c, 0x22f0,
+ 0xd49d, 0x4a75,
+ 0xd49f, 0x22ee,
+ 0xd4a0, 0x4a77,
+ 0xd4a1, 0x10e4,
+ 0xd540, 0x4a78,
+ 0xd543, 0x22ed,
+ 0xd544, 0x229e,
+ 0xd545, 0x22ec,
+ 0xd546, 0x1fe2,
+ 0xd547, 0x4a7b,
+ 0xd54a, 0x20fe,
+ 0xd54b, 0x4a7e,
+ 0xd54e, 0x22f9,
+ 0xd550, 0x4a81,
+ 0xd551, 0x1eaf,
+ 0xd552, 0x4a82,
+ 0xd554, 0x2236,
+ 0xd555, 0x4a84,
+ 0xd556, 0x22f7,
+ 0xd557, 0x4a85,
+ 0xd55a, 0x223d,
+ 0xd55b, 0x4a88,
+ 0xd55c, 0x1e82,
+ 0xd55d, 0x1fb6,
+ 0xd55e, 0x4a89,
+ 0xd55f, 0x21a4,
+ 0xd560, 0x21aa,
+ 0xd561, 0x22f8,
+ 0xd562, 0x2151,
+ 0xd563, 0x4a8a,
+ 0xd564, 0x1f60,
+ 0xd565, 0x4a8b,
+ 0xd568, 0x2147,
+ 0xd569, 0x4a8e,
+ 0xd56c, 0x2145,
+ 0xd56d, 0x4a91,
+ 0xd56e, 0x1fdc,
+ 0xd56f, 0x4a92,
+ 0xd572, 0x2301,
+ 0xd573, 0x4a95,
+ 0xd575, 0x1ef5,
+ 0xd576, 0x4a97,
+ 0xd578, 0x2218,
+ 0xd579, 0x4a99,
+ 0xd57b, 0x1ec6,
+ 0xd57c, 0x4a9b,
+ 0xd57e, 0x2300,
+ 0xd580, 0x4a9d,
+ 0xd581, 0x22b4,
+ 0xd582, 0x4a9e,
+ 0xd584, 0x2169,
+ 0xd585, 0x4aa0,
+ 0xd586, 0x22fd,
+ 0xd587, 0x4aa1,
+ 0xd588, 0x20ea,
+ 0xd589, 0x4aa2,
+ 0xd58a, 0x22f4,
+ 0xd58b, 0x4aa3,
+ 0xd58c, 0x22fb,
+ 0xd58d, 0x4aa4,
+ 0xd58e, 0x22fc,
+ 0xd58f, 0x2027,
+ 0xd590, 0x4aa5,
+ 0xd593, 0x2060,
+ 0xd594, 0x22ff,
+ 0xd595, 0x4aa8,
+ 0xd598, 0x22fe,
+ 0xd599, 0x1ec7,
+ 0xd59a, 0x4aab,
+ 0xd59b, 0x230c,
+ 0xd59c, 0x4aac,
+ 0xd59f, 0x22f5,
+ 0xd5a0, 0x4aaf,
+ 0xd5a1, 0x1142,
+ 0xd640, 0x2306,
+ 0xd641, 0x4ab0,
+ 0xd642, 0x230a,
+ 0xd643, 0x21d3,
+ 0xd644, 0x4ab1,
+ 0xd647, 0x2303,
+ 0xd648, 0x4ab4,
+ 0xd649, 0x2307,
+ 0xd64a, 0x230b,
+ 0xd64b, 0x4ab5,
+ 0xd64d, 0x1f5f,
+ 0xd64e, 0x4ab7,
+ 0xd64f, 0x2309,
+ 0xd650, 0x4ab8,
+ 0xd652, 0x2302,
+ 0xd653, 0x1f04,
+ 0xd654, 0x229d,
+ 0xd655, 0x4aba,
+ 0xd656, 0x21fb,
+ 0xd657, 0x4abb,
+ 0xd658, 0x2308,
+ 0xd659, 0x4abc,
+ 0xd65a, 0x20ac,
+ 0xd65b, 0x4abd,
+ 0xd65c, 0x208e,
+ 0xd65d, 0x2305,
+ 0xd65e, 0x2197,
+ 0xd65f, 0x4abe,
+ 0xd660, 0x2171,
+ 0xd661, 0x2298,
+ 0xd662, 0x4abf,
+ 0xd665, 0x1f57,
+ 0xd666, 0x4ac2,
+ 0xd669, 0x2082,
+ 0xd66a, 0x4ac5,
+ 0xd66b, 0x2311,
+ 0xd66c, 0x4ac6,
+ 0xd66f, 0x2304,
+ 0xd670, 0x4ac9,
+ 0xd671, 0x230f,
+ 0xd672, 0x1e35,
+ 0xd673, 0x4aca,
+ 0xd674, 0x20d1,
+ 0xd675, 0x2310,
+ 0xd676, 0x1fa3,
+ 0xd677, 0x4acb,
+ 0xd678, 0x21d6,
+ 0xd679, 0x4acc,
+ 0xd67c, 0x2206,
+ 0xd67d, 0x4acf,
+ 0xd680, 0x4ad1,
+ 0xd683, 0x230d,
+ 0xd684, 0x4ad4,
+ 0xd686, 0x2312,
+ 0xd687, 0x208d,
+ 0xd688, 0x2313,
+ 0xd689, 0x4ad6,
+ 0xd68e, 0x22e3,
+ 0xd68f, 0x4adb,
+ 0xd694, 0x1fba,
+ 0xd695, 0x4ae0,
+ 0xd699, 0x2078,
+ 0xd69a, 0x4ae4,
+ 0xd6a1, 0x11a0,
+ 0xd740, 0x4aeb,
+ 0xd743, 0x2288,
+ 0xd744, 0x4aee,
+ 0xd748, 0x2316,
+ 0xd749, 0x1f6b,
+ 0xd74a, 0x4af2,
+ 0xd750, 0x2314,
+ 0xd751, 0x4af8,
+ 0xd752, 0x2130,
+ 0xd753, 0x2315,
+ 0xd754, 0x2168,
+ 0xd755, 0x4af9,
+ 0xd756, 0x20c4,
+ 0xd757, 0x4afa,
+ 0xd764, 0x2318,
+ 0xd765, 0x4b07,
+ 0xd767, 0x2219,
+ 0xd768, 0x2217,
+ 0xd769, 0x4b09,
+ 0xd76c, 0x20d5,
+ 0xd76d, 0x4b0c,
+ 0xd76f, 0x1f4a,
+ 0xd770, 0x4b0e,
+ 0xd775, 0x2240,
+ 0xd776, 0x4b13,
+ 0xd778, 0x1ed3,
+ 0xd779, 0x4b15,
+ 0xd780, 0x4b1b,
+ 0xd783, 0x1e49,
+ 0xd784, 0x4b1e,
+ 0xd787, 0x261b,
+ 0xd788, 0x4b21,
+ 0xd78b, 0x1e6d,
+ 0xd78c, 0x20f8,
+ 0xd78d, 0x4b24,
+ 0xd78e, 0x1ffb,
+ 0xd78f, 0x2319,
+ 0xd790, 0x4b25,
+ 0xd795, 0x230e,
+ 0xd796, 0x4b2a,
+ 0xd797, 0x2317,
+ 0xd798, 0x4b2b,
+ 0xd7a1, 0x11fe,
+ 0xd840, 0x4b34,
+ 0xd84d, 0x20c8,
+ 0xd84e, 0x4b41,
+ 0xd853, 0x1efd,
+ 0xd854, 0x4b46,
+ 0xd880, 0x4b71,
+ 0xd890, 0x1e3b,
+ 0xd891, 0x227f,
+ 0xd892, 0x4b81,
+ 0xd893, 0x1f0c,
+ 0xd894, 0x1e59,
+ 0xd895, 0x1f24,
+ 0xd896, 0x4b82,
+ 0xd89a, 0x20ba,
+ 0xd89b, 0x1f65,
+ 0xd89c, 0x1ef0,
+ 0xd89d, 0x2164,
+ 0xd89e, 0x1f30,
+ 0xd89f, 0x2261,
+ 0xd8a0, 0x4b86,
+ 0xd8a1, 0x1257,
+ 0xd940, 0x4b87,
+ 0xd941, 0x22a2,
+ 0xd942, 0x24ab,
+ 0xd943, 0x4b88,
+ 0xd944, 0x24af,
+ 0xd945, 0x1ee8,
+ 0xd946, 0x1f39,
+ 0xd947, 0x4b89,
+ 0xd948, 0x1e48,
+ 0xd949, 0x2070,
+ 0xd94a, 0x1ea8,
+ 0xd94b, 0x4b8a,
+ 0xd94c, 0x24ac,
+ 0xd94d, 0x1ef7,
+ 0xd94e, 0x2176,
+ 0xd94f, 0x24ad,
+ 0xd950, 0x4b8b,
+ 0xd951, 0x207b,
+ 0xd952, 0x1f45,
+ 0xd953, 0x24aa,
+ 0xd954, 0x204b,
+ 0xd955, 0x202f,
+ 0xd956, 0x1f5a,
+ 0xd957, 0x24b0,
+ 0xd958, 0x4b8c,
+ 0xd959, 0x22b7,
+ 0xd95a, 0x1f7f,
+ 0xd95b, 0x4b8d,
+ 0xd95c, 0x2265,
+ 0xd95d, 0x4b8e,
+ 0xd963, 0x24b2,
+ 0xd964, 0x211b,
+ 0xd965, 0x1e51,
+ 0xd966, 0x4b94,
+ 0xd967, 0x24b4,
+ 0xd968, 0x4b95,
+ 0xd96c, 0x24b3,
+ 0xd96d, 0x4b99,
+ 0xd96e, 0x1e9f,
+ 0xd96f, 0x4b9a,
+ 0xd970, 0x2118,
+ 0xd971, 0x4b9b,
+ 0xd972, 0x20b4,
+ 0xd973, 0x23af,
+ 0xd974, 0x21bb,
+ 0xd975, 0x2072,
+ 0xd976, 0x1f95,
+ 0xd977, 0x4b9c,
+ 0xd978, 0x1f0a,
+ 0xd979, 0x24b6,
+ 0xd97a, 0x4b9d,
+ 0xd97c, 0x2291,
+ 0xd97d, 0x24b5,
+ 0xd97e, 0x2278,
+ 0xd980, 0x1ed4,
+ 0xd981, 0x4b9f,
+ 0xd987, 0x1ff3,
+ 0xd988, 0x4ba5,
+ 0xd98d, 0x22a9,
+ 0xd98e, 0x24b7,
+ 0xd98f, 0x1f28,
+ 0xd990, 0x2109,
+ 0xd991, 0x22c7,
+ 0xd992, 0x4baa,
+ 0xd997, 0x24ae,
+ 0xd998, 0x22b1,
+ 0xd999, 0x4baf,
+ 0xd99b, 0x2266,
+ 0xd99c, 0x4bb1,
+ 0xd99d, 0x225b,
+ 0xd99e, 0x22c4,
+ 0xd99f, 0x4bb2,
+ 0xd9a0, 0x2115,
+ 0xd9a1, 0x12b5,
+ 0xda40, 0x4bb3,
+ 0xda41, 0x222a,
+ 0xda42, 0x24b1,
+ 0xda43, 0x4bb4,
+ 0xda48, 0x213d,
+ 0xda49, 0x4bb9,
+ 0xda4d, 0x1f15,
+ 0xda4e, 0x225c,
+ 0xda4f, 0x4bbd,
+ 0xda73, 0x1f14,
+ 0xda74, 0x4be1,
+ 0xda77, 0x227a,
+ 0xda78, 0x4be4,
+ 0xda80, 0x4beb,
+ 0xda85, 0x20ee,
+ 0xda86, 0x4bf0,
+ 0xda8e, 0x25f8,
+ 0xda8f, 0x4bf8,
+ 0xdaa1, 0x1313,
+ 0xdb40, 0x4c0a,
+ 0xdb60, 0x1f94,
+ 0xdb61, 0x4c2a,
+ 0xdb78, 0x2230,
+ 0xdb79, 0x4c41,
+ 0xdb80, 0x4c47,
+ 0xdb84, 0x25fd,
+ 0xdb85, 0x4c4b,
+ 0xdb8b, 0x2600,
+ 0xdb8c, 0x4c51,
+ 0xdb98, 0x2606,
+ 0xdb99, 0x4c5d,
+ 0xdba1, 0x1371,
+ 0xdc40, 0x4c65,
+ 0xdc45, 0x25ff,
+ 0xdc46, 0x4c6a,
+ 0xdc4f, 0x25fc,
+ 0xdc50, 0x1e8c,
+ 0xdc51, 0x2602,
+ 0xdc52, 0x4c73,
+ 0xdc53, 0x224d,
+ 0xdc54, 0x4c74,
+ 0xdc55, 0x2604,
+ 0xdc56, 0x25fe,
+ 0xdc57, 0x2603,
+ 0xdc58, 0x4c75,
+ 0xdc5d, 0x2601,
+ 0xdc5e, 0x4c7a,
+ 0xdc62, 0x2605,
+ 0xdc63, 0x4c7e,
+ 0xdc66, 0x1ea3,
+ 0xdc67, 0x2608,
+ 0xdc68, 0x4c81,
+ 0xdc6b, 0x2607,
+ 0xdc6c, 0x4c84,
+ 0xdc7c, 0x20f0,
+ 0xdc7d, 0x4c94,
+ 0xdc80, 0x4c96,
+ 0xdc87, 0x1e7b,
+ 0xdc88, 0x2267,
+ 0xdc89, 0x1f36,
+ 0xdc8a, 0x1fd6,
+ 0xdc8b, 0x4c9d,
+ 0xdc8e, 0x21e0,
+ 0xdc8f, 0x4ca0,
+ 0xdc90, 0x248c,
+ 0xdc91, 0x4ca1,
+ 0xdc97, 0x248d,
+ 0xdc98, 0x4ca7,
+ 0xdc9b, 0x2102,
+ 0xdc9c, 0x4caa,
+ 0xdca0, 0x2494,
+ 0xdca1, 0x13cf,
+ 0xdd40, 0x4cae,
+ 0xdd46, 0x2493,
+ 0xdd47, 0x4cb4,
+ 0xdd4d, 0x248e,
+ 0xdd4e, 0x4cba,
+ 0xdd53, 0x2299,
+ 0xdd54, 0x2491,
+ 0xdd55, 0x2496,
+ 0xdd56, 0x248f,
+ 0xdd57, 0x2492,
+ 0xdd58, 0x4cbf,
+ 0xdd59, 0x2497,
+ 0xdd5a, 0x4cc0,
+ 0xdd5e, 0x1fb1,
+ 0xdd5f, 0x4cc4,
+ 0xdd60, 0x249a,
+ 0xdd61, 0x4cc5,
+ 0xdd62, 0x2499,
+ 0xdd63, 0x4cc6,
+ 0xdd64, 0x2258,
+ 0xdd65, 0x2498,
+ 0xdd66, 0x4cc7,
+ 0xdd6d, 0x249b,
+ 0xdd6e, 0x4cce,
+ 0xdd6f, 0x1f09,
+ 0xdd70, 0x20e6,
+ 0xdd71, 0x4ccf,
+ 0xdd76, 0x2026,
+ 0xdd77, 0x249f,
+ 0xdd78, 0x1f59,
+ 0xdd79, 0x249d,
+ 0xdd7b, 0x4cd4,
+ 0xdd80, 0x4cd8,
+ 0xdd81, 0x1f3b,
+ 0xdd82, 0x249c,
+ 0xdd83, 0x4cd9,
+ 0xdd85, 0x1e3a,
+ 0xdd86, 0x205b,
+ 0xdd87, 0x4cdb,
+ 0xdd8b, 0x1f70,
+ 0xdd8c, 0x4cdf,
+ 0xdd8f, 0x24a0,
+ 0xdd90, 0x4ce2,
+ 0xdd94, 0x213b,
+ 0xdd95, 0x4ce6,
+ 0xdd97, 0x1f07,
+ 0xdd98, 0x4ce8,
+ 0xdd9a, 0x2270,
+ 0xdd9b, 0x2237,
+ 0xdd9c, 0x4cea,
+ 0xdd9e, 0x24d2,
+ 0xdd9f, 0x4cec,
+ 0xdda0, 0x21b3,
+ 0xdda1, 0x142d,
+ 0xde40, 0x2245,
+ 0xde41, 0x24a1,
+ 0xde42, 0x4ced,
+ 0xde44, 0x22a8,
+ 0xde45, 0x4cef,
+ 0xde48, 0x227c,
+ 0xde49, 0x1fb0,
+ 0xde4a, 0x4cf2,
+ 0xde4f, 0x24a2,
+ 0xde50, 0x4cf7,
+ 0xde5a, 0x1f46,
+ 0xde5b, 0x4d01,
+ 0xde5c, 0x2380,
+ 0xde5d, 0x2495,
+ 0xde5e, 0x4d02,
+ 0xde5f, 0x2490,
+ 0xde60, 0x4d03,
+ 0xde6b, 0x1e30,
+ 0xde6c, 0x4d0e,
+ 0xde6f, 0x1e9d,
+ 0xde70, 0x1e4b,
+ 0xde71, 0x1e4a,
+ 0xde72, 0x20aa,
+ 0xde73, 0x4d11,
+ 0xde80, 0x4d1d,
+ 0xde92, 0x267b,
+ 0xde93, 0x4d2f,
+ 0xde9f, 0x23f2,
+ 0xdea0, 0x4d3b,
+ 0xdea1, 0x148b,
+ 0xdf40, 0x227e,
+ 0xdf41, 0x4d3c,
+ 0xdf42, 0x2019,
+ 0xdf43, 0x4d3d,
+ 0xdf4d, 0x1fbb,
+ 0xdf4e, 0x4d47,
+ 0xdf5c, 0x2253,
+ 0xdf5d, 0x4d55,
+ 0xdf5e, 0x1f3e,
+ 0xdf5f, 0x1ea6,
+ 0xdf60, 0x218e,
+ 0xdf61, 0x4d56,
+ 0xdf64, 0x21ec,
+ 0xdf65, 0x4d59,
+ 0xdf66, 0x1ebe,
+ 0xdf67, 0x4d5a,
+ 0xdf68, 0x224a,
+ 0xdf69, 0x4d5b,
+ 0xdf6d, 0x2133,
+ 0xdf6e, 0x4d5f,
+ 0xdf74, 0x1e84,
+ 0xdf75, 0x4d65,
+ 0xdf77, 0x20cf,
+ 0xdf78, 0x21e2,
+ 0xdf79, 0x4d67,
+ 0xdf7a, 0x220f,
+ 0xdf7b, 0x4d68,
+ 0xdf7c, 0x2029,
+ 0xdf7d, 0x4d69,
+ 0xdf7e, 0x2073,
+ 0xdf80, 0x1f55,
+ 0xdf81, 0x4d6a,
+ 0xdf83, 0x23f1,
+ 0xdf84, 0x4d6c,
+ 0xdf85, 0x1e46,
+ 0xdf86, 0x4d6d,
+ 0xdf89, 0x2063,
+ 0xdf8a, 0x23f3,
+ 0xdf8b, 0x4d70,
+ 0xdfa1, 0x14e9,
+ 0xe040, 0x4d86,
+ 0xe050, 0x231e,
+ 0xe051, 0x4d96,
+ 0xe05d, 0x2233,
+ 0xe05e, 0x4da2,
+ 0xe069, 0x2320,
+ 0xe06a, 0x4dad,
+ 0xe06c, 0x21c7,
+ 0xe06d, 0x4daf,
+ 0xe075, 0x22bc,
+ 0xe076, 0x4db7,
+ 0xe077, 0x231c,
+ 0xe078, 0x4db8,
+ 0xe079, 0x2251,
+ 0xe07a, 0x4db9,
+ 0xe080, 0x4dbe,
+ 0xe087, 0x1ebb,
+ 0xe088, 0x4dc5,
+ 0xe08d, 0x2287,
+ 0xe08e, 0x4dca,
+ 0xe08f, 0x202d,
+ 0xe090, 0x1eab,
+ 0xe091, 0x4dcb,
+ 0xe092, 0x231d,
+ 0xe093, 0x4dcc,
+ 0xe094, 0x231f,
+ 0xe095, 0x4dcd,
+ 0xe097, 0x231b,
+ 0xe098, 0x4dcf,
+ 0xe0a1, 0x1547,
+ 0xe140, 0x4dd8,
+ 0xe142, 0x2321,
+ 0xe143, 0x4dda,
+ 0xe164, 0x2255,
+ 0xe165, 0x4dfb,
+ 0xe168, 0x1e8f,
+ 0xe169, 0x4dfe,
+ 0xe174, 0x220c,
+ 0xe175, 0x1fa4,
+ 0xe176, 0x4e09,
+ 0xe180, 0x4e12,
+ 0xe184, 0x209b,
+ 0xe185, 0x21d8,
+ 0xe186, 0x4e16,
+ 0xe187, 0x25fa,
+ 0xe188, 0x4e17,
+ 0xe189, 0x25f9,
+ 0xe18a, 0x4e18,
+ 0xe18c, 0x2134,
+ 0xe18d, 0x4e1a,
+ 0xe18e, 0x24f3,
+ 0xe191, 0x24f8,
+ 0xe192, 0x4e1b,
+ 0xe193, 0x24f7,
+ 0xe194, 0x1ec8,
+ 0xe195, 0x24f6,
+ 0xe196, 0x4e1c,
+ 0xe198, 0x2280,
+ 0xe199, 0x4e1e,
+ 0xe19e, 0x1ec5,
+ 0xe19f, 0x24fb,
+ 0xe1a0, 0x4e23,
+ 0xe1a1, 0x15a5,
+ 0xe240, 0x4e24,
+ 0xe241, 0x24fa,
+ 0xe242, 0x4e25,
+ 0xe243, 0x1eed,
+ 0xe244, 0x4e26,
+ 0xe24f, 0x24fd,
+ 0xe250, 0x4e31,
+ 0xe251, 0x24f9,
+ 0xe252, 0x4e32,
+ 0xe253, 0x24fe,
+ 0xe254, 0x20cd,
+ 0xe255, 0x4e33,
+ 0xe25a, 0x2508,
+ 0xe25b, 0x2504,
+ 0xe25c, 0x4e38,
+ 0xe25e, 0x2506,
+ 0xe25f, 0x4e3a,
+ 0xe262, 0x24ff,
+ 0xe263, 0x2090,
+ 0xe264, 0x4e3d,
+ 0xe267, 0x1edd,
+ 0xe268, 0x1f25,
+ 0xe269, 0x4e40,
+ 0xe26a, 0x2503,
+ 0xe26b, 0x2502,
+ 0xe26c, 0x4e41,
+ 0xe26e, 0x1e7a,
+ 0xe26f, 0x20a6,
+ 0xe270, 0x4e43,
+ 0xe278, 0x1fd5,
+ 0xe279, 0x4e4b,
+ 0xe27d, 0x1f11,
+ 0xe27e, 0x4e4f,
+ 0xe280, 0x2507,
+ 0xe281, 0x2500,
+ 0xe282, 0x2505,
+ 0xe283, 0x4e50,
+ 0xe289, 0x2519,
+ 0xe28a, 0x4e56,
+ 0xe28b, 0x2515,
+ 0xe28c, 0x4e57,
+ 0xe28e, 0x250c,
+ 0xe28f, 0x2031,
+ 0xe290, 0x4e59,
+ 0xe292, 0x250b,
+ 0xe293, 0x250f,
+ 0xe294, 0x251a,
+ 0xe295, 0x2509,
+ 0xe296, 0x4e5b,
+ 0xe298, 0x250e,
+ 0xe299, 0x2234,
+ 0xe29a, 0x2513,
+ 0xe29b, 0x1f80,
+ 0xe29c, 0x4e5d,
+ 0xe2a0, 0x2501,
+ 0xe2a1, 0x1603,
+ 0xe340, 0x4e61,
+ 0xe342, 0x2517,
+ 0xe343, 0x2516,
+ 0xe344, 0x4e63,
+ 0xe347, 0x2518,
+ 0xe348, 0x4e66,
+ 0xe34b, 0x1e56,
+ 0xe34c, 0x4e69,
+ 0xe34f, 0x250d,
+ 0xe350, 0x4e6c,
+ 0xe351, 0x20d3,
+ 0xe352, 0x4e6d,
+ 0xe354, 0x207a,
+ 0xe355, 0x20ce,
+ 0xe356, 0x4e6f,
+ 0xe358, 0x2510,
+ 0xe359, 0x4e71,
+ 0xe35c, 0x1e55,
+ 0xe35d, 0x4e74,
+ 0xe360, 0x250a,
+ 0xe361, 0x4e77,
+ 0xe366, 0x2511,
+ 0xe368, 0x4e7c,
+ 0xe371, 0x1faa,
+ 0xe372, 0x4e85,
+ 0xe373, 0x251e,
+ 0xe374, 0x1f1f,
+ 0xe375, 0x4e86,
+ 0xe378, 0x252d,
+ 0xe379, 0x221d,
+ 0xe37a, 0x4e89,
+ 0xe37c, 0x2532,
+ 0xe37d, 0x4e8b,
+ 0xe37e, 0x217b,
+ 0xe380, 0x4e8c,
+ 0xe38a, 0x21af,
+ 0xe38b, 0x4e96,
+ 0xe38c, 0x252c,
+ 0xe38d, 0x4e97,
+ 0xe38f, 0x2528,
+ 0xe390, 0x4e99,
+ 0xe391, 0x208c,
+ 0xe392, 0x4e9a,
+ 0xe393, 0x252f,
+ 0xe394, 0x4e9b,
+ 0xe395, 0x21bc,
+ 0xe396, 0x4e9c,
+ 0xe399, 0x251d,
+ 0xe39a, 0x4e9f,
+ 0xe39c, 0x2535,
+ 0xe39d, 0x4ea1,
+ 0xe39e, 0x220d,
+ 0xe39f, 0x2526,
+ 0xe3a0, 0x4ea2,
+ 0xe3a1, 0x1661,
+ 0xe440, 0x2534,
+ 0xe441, 0x252a,
+ 0xe442, 0x251f,
+ 0xe443, 0x2531,
+ 0xe444, 0x251c,
+ 0xe445, 0x4ea3,
+ 0xe448, 0x2525,
+ 0xe449, 0x4ea6,
+ 0xe44e, 0x21cd,
+ 0xe44f, 0x4eab,
+ 0xe450, 0x21da,
+ 0xe451, 0x4eac,
+ 0xe452, 0x2172,
+ 0xe453, 0x253e,
+ 0xe454, 0x4ead,
+ 0xe458, 0x204f,
+ 0xe459, 0x4eb1,
+ 0xe45a, 0x2543,
+ 0xe45b, 0x4eb2,
+ 0xe45c, 0x21d7,
+ 0xe45d, 0x4eb3,
+ 0xe45e, 0x1e3c,
+ 0xe45f, 0x4eb4,
+ 0xe462, 0x2529,
+ 0xe463, 0x4eb7,
+ 0xe465, 0x2521,
+ 0xe466, 0x4eb9,
+ 0xe468, 0x1eff,
+ 0xe469, 0x4ebb,
+ 0xe473, 0x253f,
+ 0xe474, 0x4ec5,
+ 0xe475, 0x2544,
+ 0xe476, 0x4ec6,
+ 0xe479, 0x2523,
+ 0xe47a, 0x1e90,
+ 0xe47b, 0x253a,
+ 0xe47c, 0x2545,
+ 0xe47d, 0x4ec9,
+ 0xe47e, 0x253d,
+ 0xe480, 0x4eca,
+ 0xe481, 0x20c1,
+ 0xe482, 0x4ecb,
+ 0xe484, 0x2103,
+ 0xe485, 0x2520,
+ 0xe486, 0x253c,
+ 0xe487, 0x253b,
+ 0xe488, 0x2538,
+ 0xe489, 0x4ecd,
+ 0xe48d, 0x2540,
+ 0xe48e, 0x4ed1,
+ 0xe48f, 0x1fcd,
+ 0xe490, 0x4ed2,
+ 0xe493, 0x1f18,
+ 0xe494, 0x4ed5,
+ 0xe498, 0x254b,
+ 0xe499, 0x4ed9,
+ 0xe49d, 0x2547,
+ 0xe49e, 0x254f,
+ 0xe4a0, 0x4edd,
+ 0xe4a1, 0x16bf,
+ 0xe540, 0x4ede,
+ 0xe546, 0x22b0,
+ 0xe547, 0x4ee4,
+ 0xe548, 0x2546,
+ 0xe549, 0x4ee5,
+ 0xe54b, 0x254c,
+ 0xe54c, 0x4ee7,
+ 0xe54e, 0x1e9a,
+ 0xe54f, 0x2552,
+ 0xe550, 0x2530,
+ 0xe551, 0x2549,
+ 0xe552, 0x4ee9,
+ 0xe555, 0x2551,
+ 0xe556, 0x1eca,
+ 0xe557, 0x4eec,
+ 0xe558, 0x20d2,
+ 0xe559, 0x4eed,
+ 0xe55c, 0x1fb8,
+ 0xe55d, 0x4ef0,
+ 0xe55e, 0x2079,
+ 0xe55f, 0x4ef1,
+ 0xe561, 0x21ab,
+ 0xe562, 0x4ef3,
+ 0xe564, 0x254d,
+ 0xe565, 0x1ea5,
+ 0xe566, 0x4ef5,
+ 0xe568, 0x204c,
+ 0xe569, 0x2080,
+ 0xe56a, 0x4ef7,
+ 0xe56c, 0x266d,
+ 0xe56d, 0x4ef9,
+ 0xe56e, 0x2537,
+ 0xe56f, 0x4efa,
+ 0xe575, 0x254a,
+ 0xe576, 0x21b8,
+ 0xe577, 0x4f00,
+ 0xe578, 0x254e,
+ 0xe579, 0x4f01,
+ 0xe57b, 0x24fc,
+ 0xe57c, 0x2554,
+ 0xe57d, 0x4f03,
+ 0xe580, 0x4f05,
+ 0xe581, 0x1f3c,
+ 0xe582, 0x4f06,
+ 0xe583, 0x1ed5,
+ 0xe584, 0x4f07,
+ 0xe58a, 0x2556,
+ 0xe58b, 0x4f0d,
+ 0xe58e, 0x2268,
+ 0xe58f, 0x4f10,
+ 0xe591, 0x1ed6,
+ 0xe592, 0x4f12,
+ 0xe59a, 0x2557,
+ 0xe59b, 0x2553,
+ 0xe59c, 0x4f1a,
+ 0xe59f, 0x2548,
+ 0xe5a0, 0x4f1d,
+ 0xe5a1, 0x171d,
+ 0xe640, 0x20dc,
+ 0xe641, 0x4f1e,
+ 0xe644, 0x2559,
+ 0xe645, 0x4f21,
+ 0xe649, 0x1f97,
+ 0xe64a, 0x2555,
+ 0xe64b, 0x4f25,
+ 0xe64e, 0x227d,
+ 0xe64f, 0x4f28,
+ 0xe652, 0x257e,
+ 0xe653, 0x4f2b,
+ 0xe656, 0x207c,
+ 0xe657, 0x4f2e,
+ 0xe658, 0x255a,
+ 0xe659, 0x4f2f,
+ 0xe65b, 0x255e,
+ 0xe65c, 0x4f31,
+ 0xe65e, 0x1e34,
+ 0xe65f, 0x4f33,
+ 0xe669, 0x215e,
+ 0xe66a, 0x4f3d,
+ 0xe66b, 0x2560,
+ 0xe66c, 0x4f3e,
+ 0xe675, 0x21a2,
+ 0xe676, 0x2354,
+ 0xe677, 0x4f47,
+ 0xe679, 0x2563,
+ 0xe67a, 0x2527,
+ 0xe67b, 0x4f49,
+ 0xe67c, 0x252e,
+ 0xe67d, 0x2558,
+ 0xe67e, 0x4f4a,
+ 0xe680, 0x1f1b,
+ 0xe681, 0x4f4b,
+ 0xe682, 0x2283,
+ 0xe683, 0x4f4c,
+ 0xe684, 0x2564,
+ 0xe685, 0x4f4d,
+ 0xe687, 0x20a0,
+ 0xe688, 0x4f4f,
+ 0xe689, 0x2565,
+ 0xe68a, 0x4f50,
+ 0xe68c, 0x2561,
+ 0xe68d, 0x4f52,
+ 0xe693, 0x2562,
+ 0xe694, 0x4f58,
+ 0xe697, 0x256c,
+ 0xe698, 0x4f5b,
+ 0xe69b, 0x256d,
+ 0xe69c, 0x2020,
+ 0xe69d, 0x4f5e,
+ 0xe69f, 0x255f,
+ 0xe6a0, 0x256a,
+ 0xe6a1, 0x177b,
+ 0xe740, 0x4f60,
+ 0xe743, 0x256e,
+ 0xe744, 0x4f63,
+ 0xe748, 0x2539,
+ 0xe749, 0x255c,
+ 0xe74a, 0x4f67,
+ 0xe74d, 0x2568,
+ 0xe74f, 0x256b,
+ 0xe750, 0x1e6f,
+ 0xe751, 0x4f6a,
+ 0xe752, 0x1fc4,
+ 0xe753, 0x2567,
+ 0xe754, 0x4f6b,
+ 0xe755, 0x255b,
+ 0xe756, 0x4f6c,
+ 0xe759, 0x261d,
+ 0xe75a, 0x4f6f,
+ 0xe766, 0x252b,
+ 0xe767, 0x4f7b,
+ 0xe768, 0x2571,
+ 0xe769, 0x4f7c,
+ 0xe76a, 0x2577,
+ 0xe76b, 0x4f7d,
+ 0xe774, 0x2522,
+ 0xe775, 0x4f86,
+ 0xe77c, 0x2533,
+ 0xe77d, 0x4f8d,
+ 0xe780, 0x4f8f,
+ 0xe782, 0x202a,
+ 0xe783, 0x4f91,
+ 0xe784, 0x2536,
+ 0xe785, 0x2573,
+ 0xe786, 0x256f,
+ 0xe787, 0x4f92,
+ 0xe78a, 0x2293,
+ 0xe78b, 0x2578,
+ 0xe78c, 0x4f95,
+ 0xe78f, 0x2570,
+ 0xe790, 0x4f98,
+ 0xe792, 0x2575,
+ 0xe793, 0x4f9a,
+ 0xe798, 0x2541,
+ 0xe79a, 0x255d,
+ 0xe79b, 0x4f9f,
+ 0xe7a0, 0x201a,
+ 0xe7a1, 0x17d9,
+ 0xe840, 0x4fa4,
+ 0xe843, 0x257a,
+ 0xe844, 0x2006,
+ 0xe845, 0x4fa7,
+ 0xe846, 0x2177,
+ 0xe847, 0x4fa8,
+ 0xe849, 0x251b,
+ 0xe84a, 0x4faa,
+ 0xe84b, 0x2524,
+ 0xe84c, 0x4fab,
+ 0xe84f, 0x257b,
+ 0xe850, 0x4fae,
+ 0xe854, 0x22a3,
+ 0xe855, 0x4fb2,
+ 0xe85a, 0x2579,
+ 0xe85b, 0x4fb7,
+ 0xe85c, 0x2566,
+ 0xe85d, 0x4fb8,
+ 0xe862, 0x1f93,
+ 0xe863, 0x4fbd,
+ 0xe864, 0x257c,
+ 0xe865, 0x4fbe,
+ 0xe870, 0x2514,
+ 0xe871, 0x4fc9,
+ 0xe873, 0x257d,
+ 0xe874, 0x4fcb,
+ 0xe875, 0x2572,
+ 0xe876, 0x4fcc,
+ 0xe87c, 0x2574,
+ 0xe87d, 0x4fd2,
+ 0xe880, 0x224e,
+ 0xe881, 0x4fd4,
+ 0xe882, 0x21c6,
+ 0xe883, 0x4fd5,
+ 0xe887, 0x209f,
+ 0xe888, 0x4fd9,
+ 0xe889, 0x2576,
+ 0xe88a, 0x4fda,
+ 0xe88c, 0x2064,
+ 0xe88d, 0x22bf,
+ 0xe88e, 0x261c,
+ 0xe88f, 0x225e,
+ 0xe890, 0x4fdc,
+ 0xe8a1, 0x1837,
+ 0xe940, 0x4fed,
+ 0xe94c, 0x1e75,
+ 0xe94d, 0x4ff9,
+ 0xe954, 0x207d,
+ 0xe955, 0x5000,
+ 0xe956, 0x23bf,
+ 0xe957, 0x2113,
+ 0xe958, 0x5001,
+ 0xe95a, 0x23c0,
+ 0xe95b, 0x5003,
+ 0xe95d, 0x1e45,
+ 0xe95e, 0x5005,
+ 0xe95f, 0x1fd8,
+ 0xe960, 0x23c4,
+ 0xe961, 0x5006,
+ 0xe962, 0x23c2,
+ 0xe963, 0x2104,
+ 0xe964, 0x5007,
+ 0xe965, 0x21bd,
+ 0xe966, 0x5008,
+ 0xe967, 0x1f87,
+ 0xe968, 0x23c3,
+ 0xe969, 0x5009,
+ 0xe96c, 0x2269,
+ 0xe96d, 0x500c,
+ 0xe975, 0x1f43,
+ 0xe976, 0x5014,
+ 0xe977, 0x1f1e,
+ 0xe978, 0x2679,
+ 0xe979, 0x1eeb,
+ 0xe97a, 0x5015,
+ 0xe97c, 0x1f35,
+ 0xe97d, 0x208a,
+ 0xe97e, 0x5017,
+ 0xe980, 0x23c7,
+ 0xe981, 0x23c9,
+ 0xe982, 0x23c6,
+ 0xe983, 0x5018,
+ 0xe987, 0x224f,
+ 0xe988, 0x501c,
+ 0xe98b, 0x23cb,
+ 0xe98c, 0x501f,
+ 0xe98e, 0x21f3,
+ 0xe98f, 0x5021,
+ 0xe990, 0x21f7,
+ 0xe991, 0x23cf,
+ 0xe992, 0x23ce,
+ 0xe993, 0x23ca,
+ 0xe994, 0x23cd,
+ 0xe995, 0x5022,
+ 0xe998, 0x23d0,
+ 0xe999, 0x5025,
+ 0xe99b, 0x266c,
+ 0xe99c, 0x5027,
+ 0xe99d, 0x23c1,
+ 0xe99e, 0x5028,
+ 0xe99f, 0x1fee,
+ 0xe9a0, 0x23d1,
+ 0xe9a1, 0x1895,
+ 0xea40, 0x1ff8,
+ 0xea41, 0x5029,
+ 0xea44, 0x23d3,
+ 0xea45, 0x502c,
+ 0xea48, 0x23d2,
+ 0xea49, 0x23d4,
+ 0xea4a, 0x1e98,
+ 0xea4b, 0x502f,
+ 0xea50, 0x1f2c,
+ 0xea51, 0x5034,
+ 0xea52, 0x23d5,
+ 0xea53, 0x5035,
+ 0xea55, 0x1e71,
+ 0xea56, 0x2691,
+ 0xea57, 0x5037,
+ 0xea59, 0x23c5,
+ 0xea5a, 0x5039,
+ 0xea80, 0x231a,
+ 0xea81, 0x505e,
+ 0xea84, 0x2114,
+ 0xea85, 0x5061,
+ 0xea87, 0x2284,
+ 0xea88, 0x5063,
+ 0xea8e, 0x221c,
+ 0xea8f, 0x5069,
+ 0xea90, 0x1e7e,
+ 0xea91, 0x204d,
+ 0xea92, 0x506a,
+ 0xea96, 0x2201,
+ 0xea97, 0x506e,
+ 0xeaa0, 0x1ed9,
+ 0xeaa1, 0x18f3,
+ 0xeb40, 0x5077,
+ 0xeb41, 0x1fb2,
+ 0xeb42, 0x5078,
+ 0xeb45, 0x2252,
+ 0xeb46, 0x507b,
+ 0xeb48, 0x1f79,
+ 0xeb49, 0x507d,
+ 0xeb53, 0x2157,
+ 0xeb54, 0x5087,
+ 0xeb55, 0x21bf,
+ 0xeb56, 0x5088,
+ 0xeb5b, 0x221f,
+ 0xeb5c, 0x508d,
+ 0xeb5d, 0x203d,
+ 0xeb5e, 0x508e,
+ 0xeb60, 0x2015,
+ 0xeb61, 0x5090,
+ 0xeb62, 0x26a5,
+ 0xeb63, 0x5091,
+ 0xeb6d, 0x2156,
+ 0xeb6e, 0x509b,
+ 0xeb70, 0x2144,
+ 0xeb71, 0x509d,
+ 0xeb72, 0x1e91,
+ 0xeb73, 0x2257,
+ 0xeb74, 0x509e,
+ 0xeb78, 0x200a,
+ 0xeb79, 0x2092,
+ 0xeb7a, 0x50a2,
+ 0xeb80, 0x50a7,
+ 0xeb85, 0x2250,
+ 0xeb86, 0x50ac,
+ 0xeb8a, 0x1ec3,
+ 0xeb8b, 0x50b0,
+ 0xeba1, 0x1951,
+ 0xec40, 0x50c6,
+ 0xec46, 0x21a8,
+ 0xec47, 0x50cc,
+ 0xec56, 0x260d,
+ 0xec57, 0x50db,
+ 0xec5a, 0x260c,
+ 0xec5b, 0x50de,
+ 0xec5c, 0x260e,
+ 0xec5d, 0x50df,
+ 0xec60, 0x2032,
+ 0xec61, 0x50e2,
+ 0xec6e, 0x260b,
+ 0xec6f, 0x50ef,
+ 0xec76, 0x22c3,
+ 0xec77, 0x50f6,
+ 0xec80, 0x50fe,
+ 0xec96, 0x1f23,
+ 0xec97, 0x5114,
+ 0xeca1, 0x19af,
+ 0xed40, 0x511e,
+ 0xed46, 0x2695,
+ 0xed47, 0x5124,
+ 0xed58, 0x265e,
+ 0xed59, 0x5135,
+ 0xed5e, 0x265d,
+ 0xed5f, 0x513a,
+ 0xed61, 0x2692,
+ 0xed62, 0x513c,
+ 0xed64, 0x265f,
+ 0xed65, 0x513e,
+ 0xed66, 0x218d,
+ 0xed67, 0x20fd,
+ 0xed68, 0x513f,
+ 0xed6e, 0x1f40,
+ 0xed6f, 0x5145,
+ 0xed74, 0x2465,
+ 0xed75, 0x514a,
+ 0xed77, 0x2467,
+ 0xed78, 0x514c,
+ 0xed79, 0x2466,
+ 0xed7a, 0x514d,
+ 0xed80, 0x5152,
+ 0xed91, 0x21c9,
+ 0xed92, 0x5163,
+ 0xed93, 0x2209,
+ 0xed94, 0x1ec9,
+ 0xed95, 0x20e9,
+ 0xed96, 0x5164,
+ 0xed97, 0x21ca,
+ 0xed98, 0x2146,
+ 0xed99, 0x25c5,
+ 0xed9a, 0x21dc,
+ 0xed9b, 0x5165,
+ 0xed9c, 0x245e,
+ 0xed9d, 0x5166,
+ 0xed9e, 0x214f,
+ 0xed9f, 0x5167,
+ 0xeda0, 0x25c6,
+ 0xeda1, 0x1a0d,
+ 0xee40, 0x25c7,
+ 0xee41, 0x2241,
+ 0xee42, 0x218a,
+ 0xee43, 0x1e2f,
+ 0xee44, 0x1edc,
+ 0xee45, 0x5168,
+ 0xee48, 0x20bf,
+ 0xee49, 0x2034,
+ 0xee4a, 0x516b,
+ 0xee4d, 0x25c9,
+ 0xee4e, 0x516e,
+ 0xee52, 0x25c8,
+ 0xee53, 0x5172,
+ 0xee55, 0x220e,
+ 0xee56, 0x5174,
+ 0xee57, 0x25cb,
+ 0xee58, 0x5175,
+ 0xee5e, 0x217d,
+ 0xee5f, 0x517b,
+ 0xee61, 0x1f7e,
+ 0xee62, 0x517d,
+ 0xee68, 0x25cc,
+ 0xee69, 0x1fc3,
+ 0xee6a, 0x5183,
+ 0xee6c, 0x20b9,
+ 0xee6d, 0x5185,
+ 0xee6e, 0x2181,
+ 0xee6f, 0x5186,
+ 0xee77, 0x1fda,
+ 0xee78, 0x518e,
+ 0xee7d, 0x2173,
+ 0xee7e, 0x1ee1,
+ 0xee80, 0x25cd,
+ 0xee81, 0x5193,
+ 0xee85, 0x25ce,
+ 0xee86, 0x21f6,
+ 0xee87, 0x5197,
+ 0xee8a, 0x224b,
+ 0xee8b, 0x25d1,
+ 0xee8c, 0x519a,
+ 0xee8d, 0x1ec0,
+ 0xee8e, 0x519b,
+ 0xee90, 0x2008,
+ 0xee91, 0x519d,
+ 0xee94, 0x25d0,
+ 0xee95, 0x51a0,
+ 0xee97, 0x25d2,
+ 0xee98, 0x51a2,
+ 0xee99, 0x1f2a,
+ 0xee9a, 0x51a3,
+ 0xee9d, 0x1e72,
+ 0xee9e, 0x25d3,
+ 0xee9f, 0x51a6,
+ 0xeea1, 0x1a6b,
+ 0xef40, 0x21be,
+ 0xef41, 0x25d4,
+ 0xef42, 0x2044,
+ 0xef43, 0x51a8,
+ 0xef44, 0x25cf,
+ 0xef45, 0x20f3,
+ 0xef46, 0x51a9,
+ 0xef4c, 0x1f00,
+ 0xef4d, 0x51af,
+ 0xef52, 0x24cc,
+ 0xef54, 0x51b4,
+ 0xef55, 0x2698,
+ 0xef56, 0x51b5,
+ 0xef57, 0x2678,
+ 0xef58, 0x51b6,
+ 0xef5a, 0x24ce,
+ 0xef5b, 0x51b8,
+ 0xef60, 0x24cf,
+ 0xef61, 0x51bd,
+ 0xef68, 0x20b8,
+ 0xef69, 0x51c4,
+ 0xef6a, 0x24d0,
+ 0xef6b, 0x51c5,
+ 0xef6c, 0x24d1,
+ 0xef6d, 0x51c6,
+ 0xef77, 0x1ef4,
+ 0xef78, 0x51d0,
+ 0xef7a, 0x239b,
+ 0xef7b, 0x51d2,
+ 0xef7c, 0x267e,
+ 0xef7d, 0x51d3,
+ 0xef80, 0x51d5,
+ 0xef82, 0x239d,
+ 0xef83, 0x239f,
+ 0xef85, 0x51d7,
+ 0xef86, 0x23a1,
+ 0xef87, 0x51d8,
+ 0xef88, 0x1ef1,
+ 0xef89, 0x51d9,
+ 0xef8b, 0x221e,
+ 0xef8c, 0x51db,
+ 0xef8d, 0x23a2,
+ 0xef8e, 0x51dc,
+ 0xef95, 0x214b,
+ 0xef96, 0x1e36,
+ 0xef97, 0x2135,
+ 0xef98, 0x51e3,
+ 0xef9c, 0x1fad,
+ 0xef9d, 0x51e7,
+ 0xef9e, 0x1e53,
+ 0xef9f, 0x51e8,
+ 0xefa1, 0x1ac9,
+ 0xf040, 0x51ea,
+ 0xf041, 0x23a3,
+ 0xf042, 0x2203,
+ 0xf043, 0x51eb,
+ 0xf044, 0x1ee7,
+ 0xf045, 0x51ec,
+ 0xf047, 0x23a4,
+ 0xf048, 0x2097,
+ 0xf049, 0x1ee4,
+ 0xf04a, 0x51ee,
+ 0xf04e, 0x2238,
+ 0xf04f, 0x51f2,
+ 0xf051, 0x23a5,
+ 0xf052, 0x51f4,
+ 0xf054, 0x1f9a,
+ 0xf055, 0x51f6,
+ 0xf057, 0x21c3,
+ 0xf058, 0x51f8,
+ 0xf05e, 0x1f2e,
+ 0xf05f, 0x51fe,
+ 0xf068, 0x239c,
+ 0xf069, 0x5207,
+ 0xf06c, 0x23a6,
+ 0xf06d, 0x520a,
+ 0xf071, 0x239e,
+ 0xf072, 0x520e,
+ 0xf073, 0x2035,
+ 0xf074, 0x23a7,
+ 0xf075, 0x520f,
+ 0xf078, 0x23a8,
+ 0xf079, 0x5212,
+ 0xf07a, 0x2075,
+ 0xf07b, 0x5213,
+ 0xf07d, 0x23a9,
+ 0xf080, 0x23ab,
+ 0xf081, 0x1feb,
+ 0xf082, 0x23ac,
+ 0xf083, 0x5215,
+ 0xf087, 0x1f6a,
+ 0xf088, 0x20f9,
+ 0xf089, 0x5219,
+ 0xf08b, 0x2666,
+ 0xf08c, 0x521b,
+ 0xf090, 0x2667,
+ 0xf091, 0x521f,
+ 0xf092, 0x1e6c,
+ 0xf093, 0x5220,
+ 0xf096, 0x23ad,
+ 0xf097, 0x5223,
+ 0xf0a1, 0x1b27,
+ 0xf140, 0x522d,
+ 0xf152, 0x206d,
+ 0xf153, 0x2242,
+ 0xf154, 0x1f02,
+ 0xf155, 0x523f,
+ 0xf157, 0x2183,
+ 0xf158, 0x5241,
+ 0xf159, 0x1e85,
+ 0xf15a, 0x21e9,
+ 0xf15b, 0x5242,
+ 0xf167, 0x1e57,
+ 0xf168, 0x524e,
+ 0xf176, 0x22a5,
+ 0xf177, 0x2407,
+ 0xf178, 0x1fca,
+ 0xf179, 0x525c,
+ 0xf17a, 0x2402,
+ 0xf17b, 0x1f82,
+ 0xf17c, 0x525d,
+ 0xf17e, 0x2408,
+ 0xf180, 0x2404,
+ 0xf181, 0x525f,
+ 0xf182, 0x2131,
+ 0xf183, 0x5260,
+ 0xf184, 0x2184,
+ 0xf185, 0x5261,
+ 0xf186, 0x2403,
+ 0xf187, 0x5262,
+ 0xf188, 0x206e,
+ 0xf189, 0x240b,
+ 0xf18a, 0x5263,
+ 0xf194, 0x1f3f,
+ 0xf195, 0x526d,
+ 0xf198, 0x2067,
+ 0xf199, 0x5270,
+ 0xf1a1, 0x1b85,
+ 0xf240, 0x5278,
+ 0xf245, 0x1fd7,
+ 0xf246, 0x527d,
+ 0xf247, 0x1e83,
+ 0xf248, 0x527e,
+ 0xf24b, 0x240f,
+ 0xf24c, 0x5281,
+ 0xf253, 0x240e,
+ 0xf254, 0x20c7,
+ 0xf255, 0x240d,
+ 0xf256, 0x5288,
+ 0xf25c, 0x2412,
+ 0xf25d, 0x528e,
+ 0xf25f, 0x20b7,
+ 0xf260, 0x5290,
+ 0xf271, 0x23f0,
+ 0xf272, 0x52a1,
+ 0xf273, 0x2411,
+ 0xf274, 0x2414,
+ 0xf275, 0x52a2,
+ 0xf276, 0x2170,
+ 0xf277, 0x52a3,
+ 0xf27c, 0x2405,
+ 0xf27d, 0x210c,
+ 0xf27e, 0x2415,
+ 0xf280, 0x52a8,
+ 0xf285, 0x2066,
+ 0xf286, 0x52ad,
+ 0xf287, 0x2352,
+ 0xf288, 0x2413,
+ 0xf289, 0x2410,
+ 0xf28a, 0x2416,
+ 0xf28c, 0x20f1,
+ 0xf28d, 0x52ae,
+ 0xf291, 0x240a,
+ 0xf292, 0x52b2,
+ 0xf294, 0x2409,
+ 0xf295, 0x52b4,
+ 0xf296, 0x2418,
+ 0xf297, 0x52b5,
+ 0xf29c, 0x1fa7,
+ 0xf29d, 0x52ba,
+ 0xf29e, 0x21fc,
+ 0xf29f, 0x52bb,
+ 0xf2a1, 0x1be3,
+ 0xf340, 0x1fc1,
+ 0xf341, 0x2406,
+ 0xf342, 0x52bd,
+ 0xf345, 0x229c,
+ 0xf346, 0x52c0,
+ 0xf348, 0x204e,
+ 0xf349, 0x52c2,
+ 0xf34a, 0x241a,
+ 0xf34b, 0x2419,
+ 0xf34c, 0x52c3,
+ 0xf350, 0x240c,
+ 0xf351, 0x52c7,
+ 0xf361, 0x1e29,
+ 0xf362, 0x52d7,
+ 0xf374, 0x2661,
+ 0xf375, 0x52e9,
+ 0xf376, 0x26a4,
+ 0xf377, 0x2174,
+ 0xf378, 0x2663,
+ 0xf379, 0x2662,
+ 0xf37a, 0x52ea,
+ 0xf380, 0x52ef,
+ 0xf38c, 0x2675,
+ 0xf38d, 0x52fb,
+ 0xf3a0, 0x214c,
+ 0xf3a1, 0x1c41,
+ 0xf440, 0x530e,
+ 0xf445, 0x267a,
+ 0xf446, 0x5313,
+ 0xf450, 0x26a0,
+ 0xf451, 0x531d,
+ 0xf457, 0x2668,
+ 0xf458, 0x5323,
+ 0xf459, 0x1ed0,
+ 0xf45a, 0x5324,
+ 0xf45b, 0x2096,
+ 0xf45c, 0x5325,
+ 0xf45d, 0x23cc,
+ 0xf45e, 0x5326,
+ 0xf462, 0x23c8,
+ 0xf463, 0x532a,
+ 0xf464, 0x223e,
+ 0xf465, 0x532b,
+ 0xf475, 0x2665,
+ 0xf476, 0x533b,
+ 0xf47c, 0x2664,
+ 0xf47d, 0x5341,
+ 0xf47e, 0x2239,
+ 0xf480, 0x5342,
+ 0xf494, 0x204a,
+ 0xf495, 0x5356,
+ 0xf499, 0x261f,
+ 0xf49a, 0x535a,
+ 0xf49c, 0x261e,
+ 0xf49d, 0x535c,
+ 0xf4a1, 0x1c9f,
+ 0xf540, 0x5360,
+ 0xf545, 0x2620,
+ 0xf546, 0x5365,
+ 0xf547, 0x2621,
+ 0xf548, 0x5366,
+ 0xf552, 0x2622,
+ 0xf553, 0x5370,
+ 0xf554, 0x2627,
+ 0xf555, 0x1e39,
+ 0xf556, 0x2625,
+ 0xf557, 0x5371,
+ 0xf55e, 0x2629,
+ 0xf55f, 0x5378,
+ 0xf561, 0x262e,
+ 0xf562, 0x262b,
+ 0xf563, 0x537a,
+ 0xf56e, 0x262a,
+ 0xf56f, 0x262d,
+ 0xf570, 0x5385,
+ 0xf571, 0x2628,
+ 0xf572, 0x21b9,
+ 0xf573, 0x5386,
+ 0xf580, 0x5392,
+ 0xf585, 0x2636,
+ 0xf586, 0x2630,
+ 0xf587, 0x5397,
+ 0xf58c, 0x2638,
+ 0xf58d, 0x539c,
+ 0xf58e, 0x200d,
+ 0xf58f, 0x2637,
+ 0xf590, 0x539d,
+ 0xf599, 0x2645,
+ 0xf59a, 0x53a6,
+ 0xf59b, 0x263a,
+ 0xf59c, 0x53a7,
+ 0xf5a0, 0x2643,
+ 0xf5a1, 0x1cfd,
+ 0xf640, 0x53ab,
+ 0xf641, 0x2640,
+ 0xf642, 0x53ac,
+ 0xf645, 0x263d,
+ 0xf646, 0x2641,
+ 0xf647, 0x53af,
+ 0xf648, 0x263e,
+ 0xf649, 0x53b0,
+ 0xf64b, 0x263f,
+ 0xf64c, 0x1fc0,
+ 0xf64d, 0x53b2,
+ 0xf64e, 0x263b,
+ 0xf650, 0x53b3,
+ 0xf654, 0x2642,
+ 0xf655, 0x53b7,
+ 0xf658, 0x2644,
+ 0xf659, 0x53ba,
+ 0xf661, 0x2639,
+ 0xf662, 0x53c2,
+ 0xf663, 0x264c,
+ 0xf664, 0x53c3,
+ 0xf66c, 0x2647,
+ 0xf66d, 0x264b,
+ 0xf66e, 0x53cb,
+ 0xf671, 0x2649,
+ 0xf672, 0x53ce,
+ 0xf674, 0x2648,
+ 0xf675, 0x53d0,
+ 0xf676, 0x264a,
+ 0xf677, 0x2108,
+ 0xf678, 0x53d1,
+ 0xf680, 0x53d8,
+ 0xf685, 0x264d,
+ 0xf686, 0x53dd,
+ 0xf688, 0x2634,
+ 0xf689, 0x53df,
+ 0xf68a, 0x2651,
+ 0xf68b, 0x53e0,
+ 0xf68d, 0x2650,
+ 0xf68e, 0x2652,
+ 0xf68f, 0x53e2,
+ 0xf692, 0x264f,
+ 0xf693, 0x53e5,
+ 0xf696, 0x2632,
+ 0xf697, 0x264e,
+ 0xf698, 0x2653,
+ 0xf699, 0x53e8,
+ 0xf69a, 0x2657,
+ 0xf69b, 0x53e9,
+ 0xf69c, 0x2635,
+ 0xf69d, 0x53ea,
+ 0xf69e, 0x2633,
+ 0xf69f, 0x53eb,
+ 0xf6a0, 0x2656,
+ 0xf6a1, 0x1d5b,
+ 0xf740, 0x53ec,
+ 0xf742, 0x2654,
+ 0xf743, 0x53ee,
+ 0xf749, 0x2658,
+ 0xf74a, 0x53f4,
+ 0xf74c, 0x2655,
+ 0xf74d, 0x1e4d,
+ 0xf74e, 0x53f6,
+ 0xf756, 0x265b,
+ 0xf757, 0x53fe,
+ 0xf758, 0x265a,
+ 0xf759, 0x53ff,
+ 0xf75a, 0x2659,
+ 0xf75b, 0x202e,
+ 0xf75c, 0x262f,
+ 0xf75d, 0x5400,
+ 0xf761, 0x2646,
+ 0xf762, 0x5404,
+ 0xf763, 0x2626,
+ 0xf764, 0x5405,
+ 0xf76b, 0x265c,
+ 0xf76c, 0x540c,
+ 0xf771, 0x262c,
+ 0xf772, 0x5411,
+ 0xf77c, 0x2623,
+ 0xf77d, 0x541b,
+ 0xf77e, 0x2631,
+ 0xf780, 0x541c,
+ 0xf7a1, 0x1db9,
+ 0xf840, 0x543d,
+ 0xf842, 0x209c,
+ 0xf843, 0x543f,
+ 0xf846, 0x2580,
+ 0xf847, 0x5442,
+ 0xf849, 0x22dc,
+ 0xf84a, 0x5444,
+ 0xf850, 0x1f05,
+ 0xf851, 0x208b,
+ 0xf852, 0x544a,
+ 0xf853, 0x2581,
+ 0xf854, 0x544b,
+ 0xf863, 0x2583,
+ 0xf864, 0x2582,
+ 0xf865, 0x545a,
+ 0xf866, 0x21ee,
+ 0xf867, 0x545b,
+ 0xf872, 0x2182,
+ 0xf873, 0x5466,
+ 0xf878, 0x2243,
+ 0xf879, 0x546b,
+ 0xf87a, 0x2587,
+ 0xf87b, 0x546c,
+ 0xf87c, 0x2588,
+ 0xf87d, 0x546d,
+ 0xf880, 0x546f,
+ 0xf881, 0x2584,
+ 0xf882, 0x5470,
+ 0xf884, 0x21fd,
+ 0xf885, 0x5472,
+ 0xf886, 0x21ef,
+ 0xf887, 0x5473,
+ 0xf88d, 0x258a,
+ 0xf88e, 0x258c,
+ 0xf88f, 0x5479,
+ 0xf899, 0x1f47,
+ 0xf89a, 0x5483,
+ 0xf89d, 0x1f1d,
+ 0xf89e, 0x5486,
+ 0xf8a0, 0x258d,
+ 0xf940, 0x5488,
+ 0xf94e, 0x1fd0,
+ 0xf94f, 0x2592,
+ 0xf950, 0x258f,
+ 0xf951, 0x5496,
+ 0xf959, 0x2594,
+ 0xf95a, 0x1ee0,
+ 0xf95b, 0x549e,
+ 0xf95d, 0x2591,
+ 0xf95e, 0x2595,
+ 0xf95f, 0x54a0,
+ 0xf967, 0x2597,
+ 0xf968, 0x54a8,
+ 0xf969, 0x20b6,
+ 0xf96a, 0x54a9,
+ 0xf96c, 0x2598,
+ 0xf96d, 0x54ab,
+ 0xf96f, 0x20f6,
+ 0xf970, 0x54ad,
+ 0xf980, 0x54bc,
+ 0xf985, 0x2585,
+ 0xf986, 0x54c1,
+ 0xf987, 0x2599,
+ 0xf988, 0x54c2,
+ 0xf991, 0x2596,
+ 0xf992, 0x54cb,
+ 0xf996, 0x259a,
+ 0xf997, 0x54cf,
+ 0xf998, 0x259b,
+ 0xf999, 0x54d0,
+ 0xfa40, 0x54d8,
+ 0xfa42, 0x259d,
+ 0xfa43, 0x54da,
+ 0xfa46, 0x259e,
+ 0xfa47, 0x54dd,
+ 0xfa4c, 0x234c,
+ 0xfa4d, 0x54e2,
+ 0xfa51, 0x1f44,
+ 0xfa52, 0x54e6,
+ 0xfa58, 0x2660,
+ 0xfa59, 0x25a0,
+ 0xfa5a, 0x54ec,
+ 0xfa5d, 0x259c,
+ 0xfa5e, 0x54ef,
+ 0xfa5f, 0x259f,
+ 0xfa60, 0x54f0,
+ 0xfa61, 0x1f6c,
+ 0xfa62, 0x54f1,
+ 0xfa70, 0x25a2,
+ 0xfa71, 0x54ff,
+ 0xfa74, 0x20ae,
+ 0xfa75, 0x5502,
+ 0xfa76, 0x258b,
+ 0xfa77, 0x25a3,
+ 0xfa78, 0x5503,
+ 0xfa80, 0x550a,
+ 0xfa83, 0x2589,
+ 0xfa84, 0x25a5,
+ 0xfa85, 0x550d,
+ 0xfa8d, 0x25a4,
+ 0xfa8e, 0x5515,
+ 0xfa90, 0x25a6,
+ 0xfa91, 0x2593,
+ 0xfa92, 0x5517,
+ 0xfa96, 0x25a7,
+ 0xfa97, 0x2222,
+ 0xfa98, 0x25a9,
+ 0xfa99, 0x551b,
+ 0xfb40, 0x5523,
+ 0xfb49, 0x25a8,
+ 0xfb4a, 0x552c,
+ 0xfb52, 0x2586,
+ 0xfb53, 0x5534,
+ 0xfb57, 0x25a1,
+ 0xfb58, 0x25aa,
+ 0xfb59, 0x5538,
+ 0xfb5a, 0x2590,
+ 0xfb5b, 0x258e,
+ 0xfb5c, 0x5539,
+ 0xfb75, 0x2688,
+ 0xfb76, 0x5552,
+ 0xfb79, 0x269e,
+ 0xfb7a, 0x25fb,
+ 0xfb7b, 0x5555,
+ 0xfb7c, 0x1f8c,
+ 0xfb7d, 0x21f4,
+ 0xfb7e, 0x5556,
+ 0xfb80, 0x5557,
+ 0xfb90, 0x200f,
+ 0xfb91, 0x5567,
+ 0xfb9c, 0x2071,
+ 0xfb9d, 0x5572,
+ 0xfb9f, 0x25f7,
+ 0xfba0, 0x5574,
+ 0xfc40, 0x5575,
+ 0xfc44, 0x2696,
+ 0xfc45, 0x5579,
+ 0xfc49, 0x268f,
+ 0xfc4a, 0x557d,
+ 0xfc5a, 0x22da,
+ 0xfc5b, 0x558d,
+ 0xfc63, 0x1ec1,
+ 0xfc64, 0x5595,
+ 0xfc68, 0x1eb3,
+ 0xfc69, 0x5599,
+ 0xfc6f, 0x266a,
+ 0xfc70, 0x559f,
+ 0xfc71, 0x268a,
+ 0xfc72, 0x55a0,
+ 0xfc74, 0x2669,
+ 0xfc75, 0x55a2,
+ 0xfc77, 0x2618,
+ 0xfc79, 0x55a4,
+ 0xfc80, 0x55aa,
+ 0xfc83, 0x261a,
+ 0xfc84, 0x55ad,
+ 0xfc8a, 0x2673,
+ 0xfc8b, 0x55b3,
+ 0xfd40, 0x55c9,
+ 0xfd52, 0x20c6,
+ 0xfd53, 0x226b,
+ 0xfd54, 0x55db,
+ 0xfd57, 0x24d3,
+ 0xfd58, 0x1e86,
+ 0xfd59, 0x55de,
+ 0xfd5a, 0x260f,
+ 0xfd5b, 0x55df,
+ 0xfd5f, 0x2611,
+ 0xfd60, 0x55e3,
+ 0xfd62, 0x2613,
+ 0xfd63, 0x55e5,
+ 0xfd65, 0x2610,
+ 0xfd66, 0x2612,
+ 0xfd67, 0x2030,
+ 0xfd68, 0x55e7,
+ 0xfd69, 0x2671,
+ 0xfd6a, 0x55e8,
+ 0xfd6c, 0x2614,
+ 0xfd6d, 0x55ea,
+ 0xfd70, 0x2616,
+ 0xfd71, 0x55ed,
+ 0xfd72, 0x2615,
+ 0xfd73, 0x55ee,
+ 0xfd78, 0x20f2,
+ 0xfd79, 0x55f3,
+ 0xfd7d, 0x2617,
+ 0xfd7e, 0x55f7,
+ 0xfd80, 0x55f8,
+ 0xfd88, 0x2037,
+ 0xfd89, 0x5600,
+ 0xfd8b, 0x20b3,
+ 0xfd8c, 0x5602,
+ 0xfd8f, 0x1f22,
+ 0xfd90, 0x24ed,
+ 0xfd91, 0x5605,
+ 0xfd94, 0x1f34,
+ 0xfd95, 0x5608,
+ 0xfd9d, 0x0a02,
+ 0xfd9e, 0x40d3,
+ 0xfd9f, 0x200c,
+ 0xfda0, 0x5083,
+ 0xfe40, 0x1259,
+ 0xfe41, 0x5610,
+ 0xfe80, 0x564e,
+ 0xa1a2, 0x023f,
+ 0xa1a3, 0x023e,
+ 0xa1aa, 0x0256,
+ 0xa1ab, 0x1e18,
+ 0xa1ad, 0x0257,
+ 0xa1b2, 0x0246,
+ 0xa1fe, 0x1e1a,
+ 0xa3a1, 0x0242,
+ 0xa3a8, 0x0244,
+ 0xa3ac, 0x023d,
+ 0xa3ae, 0x1e1b,
+ 0xa3ba, 0x0240,
+ 0xa3bd, 0x1e1c,
+ 0xa3bf, 0x0243,
+ 0xa3db, 0x1e1d,
+ 0xa3dd, 0x1e1e,
+ 0xa3df, 0x0258,
+ 0xa3fb, 0x0254,
+ 0xa3fd, 0x0255,
+ 0xa3fe, 0x1e1f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBKEUCVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1e24, 0x032e, 0x032f, 0x0330, 0x0331, 0x0332, 0x0333, 0x0334,
+ 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x033a, 0x033b, 0x033c,
+ 0x033d, 0x033e, 0x033f, 0x0340, 0x0341, 0x0342, 0x0343, 0x0344,
+ 0x0345, 0x0346, 0x0347, 0x0348, 0x0349, 0x034a, 0x034b, 0x034c,
+ 0x034d, 0x034e, 0x034f, 0x0350, 0x0351, 0x0352, 0x0353, 0x0354,
+ 0x0355, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035c,
+ 0x035d, 0x035e, 0x035f, 0x0360, 0x0361, 0x0362, 0x0363, 0x0364,
+ 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c,
+ 0x036d, 0x036e, 0x036f, 0x0370, 0x0371, 0x0372, 0x0373, 0x0374,
+ 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x037a, 0x037b, 0x037c,
+ 0x037d, 0x037e, 0x037f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384,
+ 0x0385, 0x0386, 0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12GBKEUCVMap2, 4091
+};
+
+static Gushort gb12GBTEUCHMap2[4566] = {
+ 0x0000, 0x0000,
+ 0xa1a1, 0x0060,
+ 0xa2b1, 0x00be,
+ 0xa2e5, 0x00f0,
+ 0xa2f1, 0x00fa,
+ 0xa3a1, 0x0106,
+ 0xa4a1, 0x0164,
+ 0xa5a1, 0x01b7,
+ 0xa6a1, 0x020d,
+ 0xa6c1, 0x0225,
+ 0xa7a1, 0x025a,
+ 0xa7d1, 0x027b,
+ 0xa8a1, 0x029c,
+ 0xa8c5, 0x02bc,
+ 0xa9a4, 0x02e2,
+ 0xaaa1, 0x032e,
+ 0xaba1, 0x038c,
+ 0xb0a1, 0x03ac,
+ 0xb0a8, 0x1e25,
+ 0xb0a9, 0x03b4,
+ 0xb0aa, 0x1e26,
+ 0xb0ab, 0x03b6,
+ 0xb0ad, 0x1e27,
+ 0xb0af, 0x03ba,
+ 0xb0b9, 0x1e29,
+ 0xb0ba, 0x03c5,
+ 0xb0c0, 0x1e2a,
+ 0xb0c1, 0x03cc,
+ 0xb0d3, 0x1e2b,
+ 0xb0d4, 0x03df,
+ 0xb0d5, 0x1e2c,
+ 0xb0d6, 0x03e1,
+ 0xb0da, 0x1e2d,
+ 0xb0db, 0x03e6,
+ 0xb0dc, 0x1e2e,
+ 0xb0dd, 0x03e8,
+ 0xb0e4, 0x1e2f,
+ 0xb0e5, 0x03f0,
+ 0xb0ec, 0x1e30,
+ 0xb0ee, 0x03f9,
+ 0xb0ef, 0x1e32,
+ 0xb0f0, 0x03fb,
+ 0xb0f3, 0x1e33,
+ 0xb0f4, 0x03ff,
+ 0xb0f7, 0x1e34,
+ 0xb0f8, 0x0403,
+ 0xb0f9, 0x1e35,
+ 0xb0fa, 0x0405,
+ 0xb1a1, 0x040a,
+ 0xb1a5, 0x1e36,
+ 0xb1a7, 0x0410,
+ 0xb1a8, 0x1e38,
+ 0xb1a9, 0x0412,
+ 0xb1ab, 0x1e39,
+ 0xb1ac, 0x0415,
+ 0xb1b2, 0x1e3a,
+ 0xb1b3, 0x041c,
+ 0xb1b4, 0x1e3b,
+ 0xb1b6, 0x041f,
+ 0xb1b7, 0x1e3d,
+ 0xb1ba, 0x0423,
+ 0xb1c1, 0x1e40,
+ 0xb1c2, 0x042b,
+ 0xb1ca, 0x1e41,
+ 0xb1cb, 0x0434,
+ 0xb1cf, 0x1e42,
+ 0xb1d1, 0x043a,
+ 0xb1d2, 0x1e44,
+ 0xb1d3, 0x043c,
+ 0xb1d5, 0x1e45,
+ 0xb1d6, 0x043f,
+ 0xb1df, 0x1e46,
+ 0xb1e2, 0x044b,
+ 0xb1e4, 0x1e49,
+ 0xb1e5, 0x044e,
+ 0xb1e7, 0x1e4a,
+ 0xb1e9, 0x0452,
+ 0xb1ea, 0x1e4c,
+ 0xb1eb, 0x0454,
+ 0xb1ee, 0x1e4d,
+ 0xb1ef, 0x0458,
+ 0xb1f1, 0x1e4e,
+ 0xb1f2, 0x045b,
+ 0xb1f4, 0x1e4f,
+ 0xb1f8, 0x0461,
+ 0xb1fd, 0x1e53,
+ 0xb1fe, 0x0467,
+ 0xb2a1, 0x0468,
+ 0xb2a6, 0x1e54,
+ 0xb2a8, 0x046f,
+ 0xb2ac, 0x1e56,
+ 0xb2ad, 0x0474,
+ 0xb2b5, 0x1e57,
+ 0xb2b6, 0x047d,
+ 0xb2b9, 0x1e58,
+ 0xb2ba, 0x0481,
+ 0xb2c6, 0x1e59,
+ 0xb2c7, 0x048e,
+ 0xb2ce, 0x1e5a,
+ 0xb2d8, 0x049f,
+ 0xb2de, 0x1e64,
+ 0xb2df, 0x04a6,
+ 0xb2e0, 0x1e65,
+ 0xb2e1, 0x04a8,
+ 0xb2e2, 0x1e66,
+ 0xb2e4, 0x04ab,
+ 0xb2ef, 0x1e68,
+ 0xb2f0, 0x04b7,
+ 0xb2f3, 0x1e69,
+ 0xb2fd, 0x04c4,
+ 0xb3a1, 0x1e73,
+ 0xb3a3, 0x04c8,
+ 0xb3a4, 0x1e75,
+ 0xb3a8, 0x04cd,
+ 0xb3a9, 0x1e79,
+ 0xb3aa, 0x04cf,
+ 0xb3ae, 0x1e7a,
+ 0xb3af, 0x04d4,
+ 0xb3b5, 0x1e7b,
+ 0xb3b6, 0x04db,
+ 0xb3b9, 0x1e7c,
+ 0xb3ba, 0x04df,
+ 0xb3be, 0x1e7d,
+ 0xb3bf, 0x04e4,
+ 0xb3c2, 0x1e7e,
+ 0xb3c3, 0x04e8,
+ 0xb3c4, 0x1e7f,
+ 0xb3c5, 0x04ea,
+ 0xb3c6, 0x1e80,
+ 0xb3c7, 0x04ec,
+ 0xb3cd, 0x1e81,
+ 0xb3ce, 0x04f3,
+ 0xb3cf, 0x1e82,
+ 0xb3d0, 0x04f5,
+ 0xb3d2, 0x1e83,
+ 0xb3d3, 0x04f8,
+ 0xb3d9, 0x1e84,
+ 0xb3da, 0x04ff,
+ 0xb3db, 0x1e85,
+ 0xb3dc, 0x0501,
+ 0xb3dd, 0x1e86,
+ 0xb3de, 0x0503,
+ 0xb3e3, 0x1e87,
+ 0xb3e4, 0x0509,
+ 0xb3e5, 0x1e88,
+ 0xb3e7, 0x050c,
+ 0xb3e8, 0x1e8a,
+ 0xb3e9, 0x050e,
+ 0xb3eb, 0x1e8b,
+ 0xb3ed, 0x0512,
+ 0xb3ef, 0x1e8d,
+ 0xb3f0, 0x0515,
+ 0xb3f1, 0x1e8e,
+ 0xb3f2, 0x0517,
+ 0xb3f3, 0x1e8f,
+ 0xb3f4, 0x0519,
+ 0xb3fa, 0x1e90,
+ 0xb3fc, 0x0521,
+ 0xb4a1, 0x1e92,
+ 0xb4a3, 0x0526,
+ 0xb4a5, 0x1e94,
+ 0xb4a7, 0x052a,
+ 0xb4ab, 0x1e96,
+ 0xb4ac, 0x052f,
+ 0xb4af, 0x1e97,
+ 0xb4b0, 0x0533,
+ 0xb4b3, 0x1e98,
+ 0xb4b5, 0x0538,
+ 0xb4b8, 0x1e9a,
+ 0xb4b9, 0x053c,
+ 0xb4bf, 0x1e9b,
+ 0xb4c0, 0x0543,
+ 0xb4c2, 0x1e9c,
+ 0xb4c3, 0x0546,
+ 0xb4c7, 0x1e9d,
+ 0xb4c8, 0x054b,
+ 0xb4ca, 0x1e9e,
+ 0xb4cb, 0x054e,
+ 0xb4cd, 0x1e9f,
+ 0xb4ce, 0x0551,
+ 0xb4cf, 0x1ea0,
+ 0xb4d0, 0x0553,
+ 0xb4d3, 0x1ea1,
+ 0xb4d5, 0x0558,
+ 0xb4da, 0x1ea3,
+ 0xb4db, 0x055e,
+ 0xb4dc, 0x1ea4,
+ 0xb4dd, 0x0560,
+ 0xb4ed, 0x1ea5,
+ 0xb4ee, 0x0571,
+ 0xb4ef, 0x1ea6,
+ 0xb4f0, 0x0573,
+ 0xb4f8, 0x1ea7,
+ 0xb4f9, 0x057c,
+ 0xb4fb, 0x1ea8,
+ 0xb4fc, 0x057f,
+ 0xb5a1, 0x0582,
+ 0xb5a3, 0x1ea9,
+ 0xb5a4, 0x0585,
+ 0xb5a5, 0x1eaa,
+ 0xb5a9, 0x058a,
+ 0xb5ac, 0x1eae,
+ 0xb5ad, 0x058e,
+ 0xb5ae, 0x1eaf,
+ 0xb5b0, 0x0591,
+ 0xb5b1, 0x1eb1,
+ 0xb5b6, 0x0597,
+ 0xb5b7, 0x1eb6,
+ 0xb5b8, 0x0599,
+ 0xb5ba, 0x1eb7,
+ 0xb5bd, 0x059e,
+ 0xb5c6, 0x1eba,
+ 0xb5c7, 0x05a8,
+ 0xb5cb, 0x1ebb,
+ 0xb5cc, 0x05ad,
+ 0xb5d0, 0x1ebc,
+ 0xb5d1, 0x05b2,
+ 0xb5d3, 0x1ebd,
+ 0xb5d4, 0x05b5,
+ 0xb5dd, 0x1ebe,
+ 0xb5e0, 0x05c1,
+ 0xb5e3, 0x1ec1,
+ 0xb5e4, 0x05c5,
+ 0xb5e6, 0x1ec2,
+ 0xb5e8, 0x05c9,
+ 0xb5ed, 0x1ec4,
+ 0xb5ee, 0x05cf,
+ 0xb5f6, 0x1ec5,
+ 0xb5f8, 0x05d9,
+ 0xb5fd, 0x1ec7,
+ 0xb5fe, 0x05df,
+ 0xb6a1, 0x05e0,
+ 0xb6a4, 0x1ec8,
+ 0xb6a6, 0x05e5,
+ 0xb6a7, 0x1eca,
+ 0xb6a8, 0x05e7,
+ 0xb6a9, 0x1ecb,
+ 0xb6aa, 0x05e9,
+ 0xb6ab, 0x1ecc,
+ 0xb6ac, 0x05eb,
+ 0xb6af, 0x1ecd,
+ 0xb6b1, 0x05f0,
+ 0xb6b3, 0x1ecf,
+ 0xb6b4, 0x05f3,
+ 0xb6b7, 0x1ed0,
+ 0xb6b8, 0x05f7,
+ 0xb6bf, 0x1ed1,
+ 0xb6c2, 0x0601,
+ 0xb6c4, 0x1ed4,
+ 0xb6c5, 0x0604,
+ 0xb6c6, 0x1ed5,
+ 0xb6c7, 0x0606,
+ 0xb6cd, 0x1ed6,
+ 0xb6ce, 0x060d,
+ 0xb6cf, 0x1ed7,
+ 0xb6d1, 0x0610,
+ 0xb6d3, 0x1ed9,
+ 0xb6d5, 0x0614,
+ 0xb6d6, 0x1edb,
+ 0xb6d7, 0x0616,
+ 0xb6d9, 0x1edc,
+ 0xb6da, 0x0619,
+ 0xb6db, 0x1edd,
+ 0xb6dc, 0x061b,
+ 0xb6e1, 0x1ede,
+ 0xb6e2, 0x0621,
+ 0xb6e9, 0x1edf,
+ 0xb6ea, 0x0629,
+ 0xb6ec, 0x1ee0,
+ 0xb6ed, 0x062c,
+ 0xb6ee, 0x1ee1,
+ 0xb6f0, 0x062f,
+ 0xb6f1, 0x1ee3,
+ 0xb6f2, 0x0631,
+ 0xb6f6, 0x1ee4,
+ 0xb6f7, 0x0636,
+ 0xb6f9, 0x1ee5,
+ 0xb6fa, 0x0639,
+ 0xb6fb, 0x1ee6,
+ 0xb6fd, 0x063c,
+ 0xb7a1, 0x1ee8,
+ 0xb7a4, 0x0641,
+ 0xb7a7, 0x1eeb,
+ 0xb7a8, 0x0645,
+ 0xb7af, 0x1eec,
+ 0xb7b1, 0x064e,
+ 0xb7b3, 0x1eee,
+ 0xb7b4, 0x0651,
+ 0xb7b6, 0x1eef,
+ 0xb7b8, 0x0655,
+ 0xb7b9, 0x1ef1,
+ 0xb7ba, 0x0657,
+ 0xb7c3, 0x1ef2,
+ 0xb7c5, 0x0662,
+ 0xb7c9, 0x1ef4,
+ 0xb7ca, 0x0667,
+ 0xb7cc, 0x1ef5,
+ 0xb7cd, 0x066a,
+ 0xb7cf, 0x1ef6,
+ 0xb7d0, 0x066d,
+ 0xb7d1, 0x1ef7,
+ 0xb7d2, 0x066f,
+ 0xb7d7, 0x1ef8,
+ 0xb7d9, 0x0676,
+ 0xb7dc, 0x1efa,
+ 0xb7dd, 0x067a,
+ 0xb7df, 0x1efb,
+ 0xb7e2, 0x067f,
+ 0xb7e3, 0x1efe,
+ 0xb7e4, 0x0681,
+ 0xb7e6, 0x1eff,
+ 0xb7e9, 0x0686,
+ 0xb7eb, 0x1f02,
+ 0xb7ee, 0x068b,
+ 0xb7ef, 0x1f05,
+ 0xb7f0, 0x068d,
+ 0xb7f4, 0x1f06,
+ 0xb7f5, 0x0692,
+ 0xb7f8, 0x1f07,
+ 0xb7f9, 0x0696,
+ 0xb8a1, 0x069c,
+ 0xb8a7, 0x1f08,
+ 0xb8a9, 0x06a4,
+ 0xb8b3, 0x1f0a,
+ 0xb8b5, 0x06b0,
+ 0xb8ba, 0x1f0c,
+ 0xb8bb, 0x06b6,
+ 0xb8bc, 0x1f0d,
+ 0xb8bd, 0x06b8,
+ 0xb8be, 0x1f0e,
+ 0xb8c0, 0x06bb,
+ 0xb8c3, 0x1f10,
+ 0xb8c4, 0x06bf,
+ 0xb8c6, 0x1f11,
+ 0xb8c8, 0x06c3,
+ 0xb8c9, 0x1f13,
+ 0xb8ca, 0x06c5,
+ 0xb8cf, 0x1f14,
+ 0xb8d0, 0x06cb,
+ 0xb8d3, 0x1f15,
+ 0xb8d7, 0x06d2,
+ 0xb8d9, 0x1f19,
+ 0xb8db, 0x06d6,
+ 0xb8e4, 0x1f1b,
+ 0xb8e5, 0x06e0,
+ 0xb8e9, 0x1f1c,
+ 0xb8ea, 0x06e5,
+ 0xb8eb, 0x1f1d,
+ 0xb8ec, 0x06e7,
+ 0xb8f3, 0x1f1e,
+ 0xb8f4, 0x06ef,
+ 0xb8f5, 0x1f1f,
+ 0xb8f7, 0x06f2,
+ 0xb8f8, 0x1f21,
+ 0xb8f9, 0x06f4,
+ 0xb9a1, 0x06fa,
+ 0xb9a8, 0x1f22,
+ 0xb9a9, 0x0702,
+ 0xb9ae, 0x1f23,
+ 0xb9af, 0x0708,
+ 0xb9b1, 0x1f24,
+ 0xb9b2, 0x070b,
+ 0xb9b3, 0x1f25,
+ 0xb9b4, 0x070d,
+ 0xb9b5, 0x1f26,
+ 0xb9b6, 0x070f,
+ 0xb9b9, 0x1f27,
+ 0xb9bb, 0x0714,
+ 0xb9c6, 0x1f29,
+ 0xb9c7, 0x0720,
+ 0xb9cb, 0x1f2a,
+ 0xb9cc, 0x0725,
+ 0xb9d0, 0x1f2b,
+ 0xb9d1, 0x072a,
+ 0xb9d8, 0x1f2c,
+ 0xb9d9, 0x0732,
+ 0xb9db, 0x1f2d,
+ 0xb9dc, 0x0735,
+ 0xb9dd, 0x1f2e,
+ 0xb9de, 0x0737,
+ 0xb9df, 0x1f2f,
+ 0xb9e0, 0x0739,
+ 0xb9e1, 0x1f30,
+ 0xb9e2, 0x073b,
+ 0xb9e3, 0x1f31,
+ 0xb9e4, 0x073d,
+ 0xb9e6, 0x1f32,
+ 0xb9e7, 0x0740,
+ 0xb9e9, 0x1f33,
+ 0xb9ed, 0x0746,
+ 0xb9ee, 0x1f37,
+ 0xb9ef, 0x0748,
+ 0xb9f1, 0x1f38,
+ 0xb9f2, 0x074b,
+ 0xb9f3, 0x1f39,
+ 0xb9f6, 0x074f,
+ 0xb9f8, 0x1f3c,
+ 0xb9f9, 0x0752,
+ 0xb9fa, 0x1f3d,
+ 0xb9fb, 0x0754,
+ 0xb9fd, 0x1f3e,
+ 0xb9fe, 0x0757,
+ 0xbaa1, 0x0758,
+ 0xbaa7, 0x1f3f,
+ 0xbaa8, 0x075f,
+ 0xbaab, 0x1f40,
+ 0xbaac, 0x0763,
+ 0xbaba, 0x1f41,
+ 0xbabb, 0x0772,
+ 0xbac5, 0x1f42,
+ 0xbac6, 0x077d,
+ 0xbad2, 0x1f43,
+ 0xbad3, 0x078a,
+ 0xbad7, 0x1f44,
+ 0xbad9, 0x0790,
+ 0xbae4, 0x1f46,
+ 0xbae5, 0x079c,
+ 0xbae8, 0x1f47,
+ 0xbae9, 0x07a0,
+ 0xbaec, 0x1f48,
+ 0xbaed, 0x07a4,
+ 0xbaf3, 0x15e5,
+ 0xbaf4, 0x07ab,
+ 0xbaf8, 0x1f49,
+ 0xbaf9, 0x07b0,
+ 0xbba1, 0x07b6,
+ 0xbba4, 0x1f4a,
+ 0xbba5, 0x07ba,
+ 0xbba6, 0x1f4b,
+ 0xbba7, 0x07bc,
+ 0xbba9, 0x1f4c,
+ 0xbbab, 0x07c0,
+ 0xbbad, 0x1f4e,
+ 0xbbaf, 0x07c4,
+ 0xbbb0, 0x1f50,
+ 0xbbb1, 0x07c6,
+ 0xbbb3, 0x1f51,
+ 0xbbb4, 0x07c9,
+ 0xbbb5, 0x1f52,
+ 0xbbb8, 0x07cd,
+ 0xbbb9, 0x1f55,
+ 0xbbbb, 0x07d0,
+ 0xbbd1, 0x1f57,
+ 0xbbd2, 0x07e7,
+ 0xbbd3, 0x1f58,
+ 0xbbd5, 0x07ea,
+ 0xbbdf, 0x1f5a,
+ 0xbbe8, 0x07fd,
+ 0xbbeb, 0x1f63,
+ 0xbbec, 0x0801,
+ 0xbbf1, 0x1f64,
+ 0xbbf2, 0x0807,
+ 0xbbf5, 0x1f65,
+ 0xbbf8, 0x080d,
+ 0xbbfa, 0x1f68,
+ 0xbbfb, 0x0810,
+ 0xbbfd, 0x1f69,
+ 0xbbfe, 0x0813,
+ 0xbca1, 0x0814,
+ 0xbca2, 0x1f6a,
+ 0xbca3, 0x0816,
+ 0xbca5, 0x1f6b,
+ 0xbca7, 0x081a,
+ 0xbca8, 0x1f6d,
+ 0xbcaa, 0x081d,
+ 0xbcab, 0x1f6f,
+ 0xbcac, 0x081f,
+ 0xbcad, 0x1f70,
+ 0xbcae, 0x0821,
+ 0xbcb6, 0x1f71,
+ 0xbcb9, 0x082c,
+ 0xbcbb, 0x1f74,
+ 0xbcbc, 0x082f,
+ 0xbcc1, 0x1f75,
+ 0xbcc2, 0x0835,
+ 0xbcc3, 0x1f76,
+ 0xbcc4, 0x0837,
+ 0xbcc6, 0x1f77,
+ 0xbcc8, 0x083b,
+ 0xbcca, 0x1f79,
+ 0xbccb, 0x083e,
+ 0xbccc, 0x1f7a,
+ 0xbcce, 0x0841,
+ 0xbcd0, 0x1f7c,
+ 0xbcd1, 0x0844,
+ 0xbcd4, 0x1f7d,
+ 0xbcd7, 0x084a,
+ 0xbcd8, 0x1f80,
+ 0xbcd9, 0x084c,
+ 0xbcdb, 0x1f81,
+ 0xbcdc, 0x084f,
+ 0xbcdd, 0x1f82,
+ 0xbcde, 0x0851,
+ 0xbcdf, 0x1f83,
+ 0xbce2, 0x0855,
+ 0xbce3, 0x1f86,
+ 0xbce5, 0x0858,
+ 0xbce8, 0x1f88,
+ 0xbce9, 0x085c,
+ 0xbcea, 0x1f89,
+ 0xbced, 0x0860,
+ 0xbcef, 0x1f8c,
+ 0xbcf4, 0x0867,
+ 0xbcf6, 0x1f91,
+ 0xbcfd, 0x0870,
+ 0xbda1, 0x0872,
+ 0xbda2, 0x1f98,
+ 0xbda8, 0x0879,
+ 0xbdab, 0x1f9e,
+ 0xbdad, 0x087e,
+ 0xbdaf, 0x1fa0,
+ 0xbdb3, 0x0884,
+ 0xbdb4, 0x1fa4,
+ 0xbdb5, 0x0886,
+ 0xbdba, 0x1fa5,
+ 0xbdbb, 0x088c,
+ 0xbdbd, 0x1fa6,
+ 0xbdc0, 0x0891,
+ 0xbdc1, 0x1fa9,
+ 0xbdc5, 0x0896,
+ 0xbdc8, 0x1fad,
+ 0xbdcb, 0x089c,
+ 0xbdce, 0x1fb0,
+ 0xbdd0, 0x08a1,
+ 0xbdd7, 0x1fb2,
+ 0xbdd8, 0x08a9,
+ 0xbdda, 0x1fb3,
+ 0xbddb, 0x08ac,
+ 0xbde0, 0x1fb4,
+ 0xbde2, 0x08b3,
+ 0xbdeb, 0x1fb6,
+ 0xbdec, 0x08bd,
+ 0xbdf4, 0x1fb7,
+ 0xbdf9, 0x08ca,
+ 0xbdfd, 0x1fbc,
+ 0xbdfe, 0x08cf,
+ 0xbea1, 0x1fbd,
+ 0xbea3, 0x08d2,
+ 0xbea5, 0x1fbf,
+ 0xbea6, 0x08d5,
+ 0xbea8, 0x1fc0,
+ 0xbea9, 0x08d8,
+ 0xbeaa, 0x1fc1,
+ 0xbeab, 0x08da,
+ 0xbead, 0x1fc2,
+ 0xbeae, 0x08dd,
+ 0xbeb1, 0x1fc3,
+ 0xbeb2, 0x08e1,
+ 0xbeb5, 0x1fc4,
+ 0xbeb8, 0x08e7,
+ 0xbeba, 0x1fc7,
+ 0xbebb, 0x08ea,
+ 0xbec0, 0x1fc8,
+ 0xbec1, 0x08f0,
+ 0xbec9, 0x1fc9,
+ 0xbeca, 0x08f9,
+ 0xbed4, 0x1fca,
+ 0xbed5, 0x0904,
+ 0xbed9, 0x1fcb,
+ 0xbeda, 0x0909,
+ 0xbedd, 0x1fcc,
+ 0xbede, 0x090d,
+ 0xbee2, 0x1fcd,
+ 0xbee3, 0x0912,
+ 0xbee5, 0x1fce,
+ 0xbee6, 0x0915,
+ 0xbee7, 0x1fcf,
+ 0xbee8, 0x0917,
+ 0xbee9, 0x1fd0,
+ 0xbeea, 0x0919,
+ 0xbeee, 0x1fd1,
+ 0xbeef, 0x091e,
+ 0xbef5, 0x1fd2,
+ 0xbef6, 0x0925,
+ 0xbef7, 0x1fd3,
+ 0xbef9, 0x0928,
+ 0xbefb, 0x1fd5,
+ 0xbefd, 0x092c,
+ 0xbfa1, 0x092e,
+ 0xbfa5, 0x1fd7,
+ 0xbfa6, 0x0933,
+ 0xbfaa, 0x1fd8,
+ 0xbfab, 0x0938,
+ 0xbfad, 0x1fd9,
+ 0xbfae, 0x093b,
+ 0xbfc5, 0x1fda,
+ 0xbfc6, 0x0953,
+ 0xbfc7, 0x1fdb,
+ 0xbfc8, 0x0955,
+ 0xbfce, 0x1fdc,
+ 0xbfcf, 0x095c,
+ 0xbfd1, 0x1fdd,
+ 0xbfd3, 0x0960,
+ 0xbfd9, 0x1fdf,
+ 0xbfda, 0x0967,
+ 0xbfe2, 0x1fe0,
+ 0xbfe5, 0x0972,
+ 0xbfe9, 0x1fe3,
+ 0xbfea, 0x0977,
+ 0xbfeb, 0x1fe4,
+ 0xbfec, 0x0979,
+ 0xbfed, 0x1fe5,
+ 0xbfee, 0x097b,
+ 0xbff3, 0x1fe6,
+ 0xbff4, 0x0981,
+ 0xbff5, 0x1fe7,
+ 0xbff6, 0x0983,
+ 0xbff7, 0x1fe8,
+ 0xbff8, 0x0985,
+ 0xbff9, 0x1fe9,
+ 0xbffb, 0x0988,
+ 0xc0a1, 0x1feb,
+ 0xc0a2, 0x098d,
+ 0xc0a3, 0x1fec,
+ 0xc0a4, 0x098f,
+ 0xc0a9, 0x1fed,
+ 0xc0aa, 0x0995,
+ 0xc0ab, 0x1fee,
+ 0xc0ac, 0x0997,
+ 0xc0af, 0x1fef,
+ 0xc0b1, 0x099c,
+ 0xc0b3, 0x1ff1,
+ 0xc0b7, 0x09a2,
+ 0xc0b8, 0x1ff5,
+ 0xc0c5, 0x09b0,
+ 0xc0cc, 0x2002,
+ 0xc0ce, 0x09b9,
+ 0xc0d4, 0x2004,
+ 0xc0d5, 0x09c0,
+ 0xc0d6, 0x2005,
+ 0xc0d7, 0x09c2,
+ 0xc0d8, 0x2006,
+ 0xc0d9, 0x09c4,
+ 0xc0dd, 0x2007,
+ 0xc0de, 0x09c9,
+ 0xc0e0, 0x2008,
+ 0xc0e1, 0x09cc,
+ 0xc0e9, 0x2009,
+ 0xc0ea, 0x09d5,
+ 0xc0eb, 0x200a,
+ 0xc0ed, 0x09d8,
+ 0xc0ef, 0x200c,
+ 0xc0f2, 0x09dd,
+ 0xc0f6, 0x200f,
+ 0xc0fb, 0x09e6,
+ 0xc1a1, 0x09ea,
+ 0xc1a4, 0x2014,
+ 0xc1a6, 0x09ef,
+ 0xc1a9, 0x2016,
+ 0xc1ae, 0x09f7,
+ 0xc1af, 0x201b,
+ 0xc1b9, 0x0a02,
+ 0xc1bd, 0x2025,
+ 0xc1bf, 0x0a08,
+ 0xc1c2, 0x2027,
+ 0xc1c3, 0x0a0c,
+ 0xc1c6, 0x2028,
+ 0xc1c7, 0x0a10,
+ 0xc1c9, 0x2029,
+ 0xc1ca, 0x0a13,
+ 0xc1cd, 0x202a,
+ 0xc1ce, 0x0a17,
+ 0xc1d4, 0x202b,
+ 0xc1d5, 0x0a1e,
+ 0xc1d9, 0x202c,
+ 0xc1dc, 0x0a25,
+ 0xc1de, 0x202f,
+ 0xc1df, 0x0a28,
+ 0xc1e4, 0x2030,
+ 0xc1e6, 0x0a2f,
+ 0xc1e9, 0x2032,
+ 0xc1ea, 0x0a33,
+ 0xc1eb, 0x2033,
+ 0xc1ed, 0x0a36,
+ 0xc1f3, 0x2035,
+ 0xc1f4, 0x0a3d,
+ 0xc1f5, 0x2036,
+ 0xc1f6, 0x0a3f,
+ 0xc1fa, 0x2037,
+ 0xc1fe, 0x0a47,
+ 0xc2a1, 0x0a48,
+ 0xc2a2, 0x203b,
+ 0xc2a9, 0x0a50,
+ 0xc2ab, 0x2042,
+ 0xc2b4, 0x0a5b,
+ 0xc2b8, 0x204b,
+ 0xc2b9, 0x0a60,
+ 0xc2bc, 0x204c,
+ 0xc2be, 0x0a65,
+ 0xc2bf, 0x204e,
+ 0xc2c0, 0x0a67,
+ 0xc2c1, 0x204f,
+ 0xc2c2, 0x0a69,
+ 0xc2c5, 0x2050,
+ 0xc2c8, 0x0a6f,
+ 0xc2cb, 0x2053,
+ 0xc2d1, 0x0a78,
+ 0xc2d2, 0x2059,
+ 0xc2d3, 0x0a7a,
+ 0xc2d5, 0x205a,
+ 0xc2dd, 0x0a84,
+ 0xc2de, 0x2062,
+ 0xc2e3, 0x0a8a,
+ 0xc2e6, 0x2067,
+ 0xc2e9, 0x0a90,
+ 0xc2ea, 0x206a,
+ 0xc2ef, 0x0a96,
+ 0xc2f0, 0x206f,
+ 0xc2f1, 0x0a98,
+ 0xc2f2, 0x2070,
+ 0xc2f6, 0x0a9d,
+ 0xc2f7, 0x2074,
+ 0xc2fb, 0x0aa2,
+ 0xc3a1, 0x2078,
+ 0xc3a2, 0x0aa7,
+ 0xc3aa, 0x2079,
+ 0xc3ab, 0x0ab0,
+ 0xc3ad, 0x207a,
+ 0xc3ae, 0x0ab3,
+ 0xc3b3, 0x207b,
+ 0xc3b4, 0x1df9,
+ 0xc3b5, 0x0aba,
+ 0xc3be, 0x207c,
+ 0xc3bf, 0x0ac4,
+ 0xc3c5, 0x207d,
+ 0xc3c8, 0x0acd,
+ 0xc3cc, 0x2080,
+ 0xc3cd, 0x0ad2,
+ 0xc3ce, 0x2081,
+ 0xc3cf, 0x0ad4,
+ 0xc3d5, 0x2082,
+ 0xc3d7, 0x0adc,
+ 0xc3d9, 0x2084,
+ 0xc3da, 0x0adf,
+ 0xc3e0, 0x2085,
+ 0xc3e1, 0x0ae6,
+ 0xc3e5, 0x2086,
+ 0xc3e6, 0x0aeb,
+ 0xc3ed, 0x2087,
+ 0xc3ee, 0x0af3,
+ 0xc3f0, 0x2088,
+ 0xc3f1, 0x0af6,
+ 0xc3f5, 0x2089,
+ 0xc3f7, 0x0afc,
+ 0xc3f9, 0x208b,
+ 0xc3fb, 0x0b00,
+ 0xc3fd, 0x208d,
+ 0xc3fe, 0x0b03,
+ 0xc4a1, 0x0b04,
+ 0xc4b1, 0x208e,
+ 0xc4b2, 0x0b15,
+ 0xc4b6, 0x208f,
+ 0xc4b7, 0x0b1a,
+ 0xc4c6, 0x2090,
+ 0xc4c7, 0x0b2a,
+ 0xc4c9, 0x2091,
+ 0xc4ca, 0x0b2d,
+ 0xc4d1, 0x2092,
+ 0xc4d2, 0x0b35,
+ 0xc4d3, 0x2093,
+ 0xc4d7, 0x0b3a,
+ 0xc4d9, 0x2097,
+ 0xc4da, 0x0b3d,
+ 0xc4e2, 0x2098,
+ 0xc4e3, 0x0b46,
+ 0xc4e5, 0x2099,
+ 0xc4e6, 0x0b49,
+ 0xc4ec, 0x209a,
+ 0xc4ed, 0x0b50,
+ 0xc4f0, 0x209b,
+ 0xc4f2, 0x0b55,
+ 0xc4f4, 0x209d,
+ 0xc4f5, 0x0b58,
+ 0xc4f6, 0x209e,
+ 0xc4f9, 0x0b5c,
+ 0xc4fb, 0x20a1,
+ 0xc4fd, 0x0b60,
+ 0xc4fe, 0x20a3,
+ 0xc5a1, 0x20a4,
+ 0xc5a3, 0x0b64,
+ 0xc5a5, 0x20a6,
+ 0xc5aa, 0x0b6b,
+ 0xc5b1, 0x20ab,
+ 0xc5b2, 0x0b73,
+ 0xc5b5, 0x20ac,
+ 0xc5b6, 0x0b77,
+ 0xc5b7, 0x20ad,
+ 0xc5ba, 0x0b7b,
+ 0xc5bb, 0x20b0,
+ 0xc5bc, 0x0b7d,
+ 0xc5bd, 0x20b1,
+ 0xc5be, 0x0b7f,
+ 0xc5cc, 0x20b2,
+ 0xc5cd, 0x0b8e,
+ 0xc5d3, 0x20b3,
+ 0xc5d4, 0x0b95,
+ 0xc5e2, 0x20b4,
+ 0xc5e3, 0x0ba4,
+ 0xc5e7, 0x20b5,
+ 0xc5e8, 0x0ba9,
+ 0xc5f4, 0x20b6,
+ 0xc5f5, 0x0bb6,
+ 0xc6a1, 0x0bc0,
+ 0xc6ad, 0x20b7,
+ 0xc6af, 0x0bce,
+ 0xc6b5, 0x20b9,
+ 0xc6b7, 0x0bd6,
+ 0xc6bb, 0x20bb,
+ 0xc6bc, 0x0bdb,
+ 0xc6be, 0x20bc,
+ 0xc6bf, 0x0bde,
+ 0xc6c0, 0x20bd,
+ 0xc6c1, 0x0be0,
+ 0xc6c3, 0x20be,
+ 0xc6c5, 0x0be4,
+ 0xc6cb, 0x20c0,
+ 0xc6ce, 0x0bed,
+ 0xc6d3, 0x20c3,
+ 0xc6d4, 0x0bf3,
+ 0xc6d7, 0x20c4,
+ 0xc6d8, 0x0bf7,
+ 0xc6ea, 0x20c5,
+ 0xc6ec, 0x0c0b,
+ 0xc6ef, 0x20c7,
+ 0xc6f0, 0x0c0f,
+ 0xc6f1, 0x20c8,
+ 0xc6f2, 0x0c11,
+ 0xc6f4, 0x20c9,
+ 0xc6f5, 0x0c14,
+ 0xc6f8, 0x20ca,
+ 0xc6f9, 0x0c18,
+ 0xc6fd, 0x20cb,
+ 0xc6fe, 0x0c1d,
+ 0xc7a1, 0x0c1e,
+ 0xc7a3, 0x20cc,
+ 0xc7a4, 0x0c21,
+ 0xc7a5, 0x20cd,
+ 0xc7a7, 0x0c24,
+ 0xc7a8, 0x20cf,
+ 0xc7aa, 0x0c27,
+ 0xc7ab, 0x20d1,
+ 0xc7ac, 0x0c29,
+ 0xc7ae, 0x20d2,
+ 0xc7b0, 0x0c2d,
+ 0xc7b3, 0x20d4,
+ 0xc7b6, 0x0c33,
+ 0xc7b9, 0x20d7,
+ 0xc7bb, 0x0c38,
+ 0xc7bd, 0x20d9,
+ 0xc7bf, 0x0c3c,
+ 0xc7c0, 0x20db,
+ 0xc7c1, 0x0c3e,
+ 0xc7c2, 0x20dc,
+ 0xc7c3, 0x0c40,
+ 0xc7c5, 0x20dd,
+ 0xc7c6, 0x0c43,
+ 0xc7c7, 0x20de,
+ 0xc7c9, 0x0c46,
+ 0xc7cc, 0x20e0,
+ 0xc7cd, 0x0c4a,
+ 0xc7cf, 0x20e1,
+ 0xc7d0, 0x0c4d,
+ 0xc7d4, 0x20e2,
+ 0xc7d6, 0x0c53,
+ 0xc7d7, 0x20e4,
+ 0xc7d8, 0x0c55,
+ 0xc7de, 0x20e5,
+ 0xc7df, 0x0c5c,
+ 0xc7e1, 0x20e6,
+ 0xc7e4, 0x0c61,
+ 0xc7ea, 0x20e9,
+ 0xc7ef, 0x0c6c,
+ 0xc7f7, 0x20ee,
+ 0xc7f9, 0x0c76,
+ 0xc7fb, 0x20f0,
+ 0xc7fc, 0x0c79,
+ 0xc7fd, 0x20f1,
+ 0xc7fe, 0x0c7b,
+ 0xc8a1, 0x0c7c,
+ 0xc8a3, 0x20f2,
+ 0xc8a4, 0x0c7f,
+ 0xc8a7, 0x20f3,
+ 0xc8a9, 0x0c84,
+ 0xc8b0, 0x20f5,
+ 0xc8b1, 0x0c8c,
+ 0xc8b5, 0x20f6,
+ 0xc8b6, 0x0c91,
+ 0xc8b7, 0x20f7,
+ 0xc8b8, 0x0c93,
+ 0xc8c3, 0x20f8,
+ 0xc8c7, 0x0ca2,
+ 0xc8c8, 0x20fc,
+ 0xc8c9, 0x0ca4,
+ 0xc8cd, 0x20fd,
+ 0xc8ce, 0x0ca9,
+ 0xc8cf, 0x20fe,
+ 0xc8d0, 0x0cab,
+ 0xc8d2, 0x20ff,
+ 0xc8d3, 0x0cae,
+ 0xc8d9, 0x2100,
+ 0xc8da, 0x0cb5,
+ 0xc8de, 0x2101,
+ 0xc8df, 0x0cba,
+ 0xc8ed, 0x2102,
+ 0xc8ee, 0x0cc9,
+ 0xc8f1, 0x2103,
+ 0xc8f4, 0x0ccf,
+ 0xc8f7, 0x2106,
+ 0xc8f9, 0x0cd4,
+ 0xc8fa, 0x2108,
+ 0xc8fb, 0x0cd6,
+ 0xc8fc, 0x2109,
+ 0xc8fd, 0x0cd8,
+ 0xc9a1, 0x210a,
+ 0xc9a2, 0x0cdb,
+ 0xc9a5, 0x210b,
+ 0xc9a6, 0x0cdf,
+ 0xc9a7, 0x210c,
+ 0xc9a9, 0x0ce2,
+ 0xc9ac, 0x210e,
+ 0xc9ad, 0x0ce6,
+ 0xc9b1, 0x210f,
+ 0xc9b2, 0x0ceb,
+ 0xc9b4, 0x2110,
+ 0xc9b5, 0x0cee,
+ 0xc9b8, 0x2111,
+ 0xc9ba, 0x0cf3,
+ 0xc9c1, 0x2113,
+ 0xc9c3, 0x0cfc,
+ 0xc9c4, 0x2115,
+ 0xc9c5, 0x0cfe,
+ 0xc9c9, 0x2116,
+ 0xc9ca, 0x0d03,
+ 0xc9cb, 0x2117,
+ 0xc9cc, 0x0d05,
+ 0xc9cd, 0x2118,
+ 0xc9ce, 0x0d07,
+ 0xc9d5, 0x2119,
+ 0xc9d6, 0x0d0f,
+ 0xc9dc, 0x211a,
+ 0xc9dd, 0x0d16,
+ 0xc9de, 0x211b,
+ 0xc9df, 0x0d18,
+ 0xc9e1, 0x211c,
+ 0xc9e2, 0x0d1b,
+ 0xc9e3, 0x211d,
+ 0xc9e4, 0x0d1d,
+ 0xc9e5, 0x211e,
+ 0xc9e6, 0x0d1f,
+ 0xc9e8, 0x211f,
+ 0xc9e9, 0x0d22,
+ 0xc9f0, 0x2120,
+ 0xc9f1, 0x0d2a,
+ 0xc9f3, 0x2121,
+ 0xc9f5, 0x0d2e,
+ 0xc9f6, 0x2123,
+ 0xc9f7, 0x0d30,
+ 0xc9f8, 0x2124,
+ 0xc9fa, 0x0d33,
+ 0xc9fe, 0x2126,
+ 0xcaa1, 0x0d38,
+ 0xcaa4, 0x2127,
+ 0xcaa7, 0x0d3e,
+ 0xcaa8, 0x212a,
+ 0xcaa9, 0x0d40,
+ 0xcaaa, 0x212b,
+ 0xcaac, 0x0d43,
+ 0xcab1, 0x212d,
+ 0xcab2, 0x0d49,
+ 0xcab4, 0x212e,
+ 0xcab7, 0x0d4e,
+ 0xcabb, 0x2131,
+ 0xcabc, 0x0d53,
+ 0xcac6, 0x2132,
+ 0xcac7, 0x0d5e,
+ 0xcaca, 0x2133,
+ 0xcacb, 0x0d62,
+ 0xcacd, 0x2134,
+ 0xcacf, 0x0d66,
+ 0xcad3, 0x2136,
+ 0xcad5, 0x0d6c,
+ 0xcad9, 0x2138,
+ 0xcada, 0x0d71,
+ 0xcade, 0x2139,
+ 0xcadf, 0x0d76,
+ 0xcae0, 0x213a,
+ 0xcae1, 0x0d78,
+ 0xcae4, 0x213b,
+ 0xcae5, 0x0d7c,
+ 0xcae9, 0x213c,
+ 0xcaeb, 0x0d82,
+ 0xcaf4, 0x213e,
+ 0xcaf6, 0x0d8d,
+ 0xcaf7, 0x2140,
+ 0xcaf8, 0x0d8f,
+ 0xcafa, 0x2141,
+ 0xcafb, 0x0d92,
+ 0xcafd, 0x2142,
+ 0xcafe, 0x0d95,
+ 0xcba1, 0x0d96,
+ 0xcba7, 0x2143,
+ 0xcba8, 0x0d9d,
+ 0xcbab, 0x2144,
+ 0xcbac, 0x0da1,
+ 0xcbad, 0x2145,
+ 0xcbae, 0x0da3,
+ 0xcbb3, 0x2146,
+ 0xcbb4, 0x0da9,
+ 0xcbb5, 0x2147,
+ 0xcbb7, 0x0dac,
+ 0xcbb8, 0x2149,
+ 0xcbb9, 0x0dae,
+ 0xcbbf, 0x214a,
+ 0xcbc0, 0x0db5,
+ 0xcbc7, 0x214b,
+ 0xcbc8, 0x0dbd,
+ 0xcbc9, 0x214c,
+ 0xcbcd, 0x0dc2,
+ 0xcbcf, 0x2150,
+ 0xcbd1, 0x0dc6,
+ 0xcbd3, 0x2152,
+ 0xcbd4, 0x0dc9,
+ 0xcbd5, 0x2153,
+ 0xcbd6, 0x0dcb,
+ 0xcbdf, 0x2154,
+ 0xcbe1, 0x0dd6,
+ 0xcbe4, 0x2156,
+ 0xcbe5, 0x0dda,
+ 0xcbe6, 0x2157,
+ 0xcbe8, 0x0ddd,
+ 0xcbea, 0x2159,
+ 0xcbeb, 0x0de0,
+ 0xcbef, 0x215a,
+ 0xcbf1, 0x0de6,
+ 0xcbf5, 0x215c,
+ 0xcbf7, 0x0dec,
+ 0xcbf8, 0x215e,
+ 0xcbf9, 0x0dee,
+ 0xcca1, 0x215f,
+ 0xcca3, 0x0df6,
+ 0xcca8, 0x2161,
+ 0xcca9, 0x0dfc,
+ 0xccac, 0x2162,
+ 0xccad, 0x0e00,
+ 0xccaf, 0x2163,
+ 0xccb4, 0x0e07,
+ 0xccb7, 0x2168,
+ 0xccb9, 0x0e0c,
+ 0xccbe, 0x216a,
+ 0xccbf, 0x0e12,
+ 0xccc0, 0x216b,
+ 0xccc1, 0x0e14,
+ 0xcccc, 0x216c,
+ 0xcccd, 0x0e20,
+ 0xccce, 0x216d,
+ 0xcccf, 0x0e22,
+ 0xccd0, 0x216e,
+ 0xccd1, 0x0e24,
+ 0xccd6, 0x216f,
+ 0xccd7, 0x0e2a,
+ 0xccda, 0x2170,
+ 0xccdb, 0x0e2e,
+ 0xccdc, 0x2171,
+ 0xccdd, 0x0e30,
+ 0xcce0, 0x2172,
+ 0xcce1, 0x0e34,
+ 0xcce2, 0x2173,
+ 0xcce3, 0x0e36,
+ 0xcce5, 0x2174,
+ 0xcce6, 0x0e39,
+ 0xccf5, 0x2175,
+ 0xccf6, 0x0e49,
+ 0xccf9, 0x2176,
+ 0xccfb, 0x0e4e,
+ 0xccfc, 0x2178,
+ 0xcda1, 0x0e52,
+ 0xcdad, 0x217b,
+ 0xcdae, 0x0e5f,
+ 0xcdb3, 0x217c,
+ 0xcdb4, 0x0e65,
+ 0xcdb7, 0x217d,
+ 0xcdb8, 0x0e69,
+ 0xcdbc, 0x217e,
+ 0xcdbd, 0x0e6e,
+ 0xcdbf, 0x217f,
+ 0xcdc0, 0x0e71,
+ 0xcdc5, 0x2180,
+ 0xcdc6, 0x0e77,
+ 0xcdc7, 0x2181,
+ 0xcdc8, 0x0e79,
+ 0xcdd2, 0x2182,
+ 0xcdd3, 0x0e84,
+ 0xcdd4, 0x2183,
+ 0xcdd7, 0x0e88,
+ 0xcddd, 0x2186,
+ 0xcdde, 0x0e8f,
+ 0xcde0, 0x2187,
+ 0xcde1, 0x0e92,
+ 0xcde4, 0x2188,
+ 0xcde6, 0x0e97,
+ 0xcde7, 0x218a,
+ 0xcde8, 0x0e99,
+ 0xcdf2, 0x218b,
+ 0xcdf3, 0x0ea4,
+ 0xcdf8, 0x218c,
+ 0xcdf9, 0x0eaa,
+ 0xcea1, 0x0eb0,
+ 0xcea4, 0x218d,
+ 0xcea6, 0x0eb5,
+ 0xcea7, 0x218f,
+ 0xcea8, 0x0eb7,
+ 0xceaa, 0x2190,
+ 0xceae, 0x0ebd,
+ 0xceb0, 0x2194,
+ 0xceb2, 0x0ec1,
+ 0xceb3, 0x2196,
+ 0xceb4, 0x0ec3,
+ 0xcebd, 0x2197,
+ 0xcebe, 0x0ecd,
+ 0xcec0, 0x2198,
+ 0xcec1, 0x0ed0,
+ 0xcec5, 0x2199,
+ 0xcec7, 0x0ed6,
+ 0xcec8, 0x219b,
+ 0xcec9, 0x0ed8,
+ 0xceca, 0x219c,
+ 0xcecb, 0x0eda,
+ 0xcece, 0x219d,
+ 0xced2, 0x0ee1,
+ 0xced8, 0x21a1,
+ 0xcedb, 0x0eea,
+ 0xcedc, 0x21a4,
+ 0xcedd, 0x0eec,
+ 0xcede, 0x21a5,
+ 0xcee0, 0x0eef,
+ 0xceeb, 0x21a7,
+ 0xceec, 0x0efb,
+ 0xceed, 0x21a8,
+ 0xceee, 0x0efd,
+ 0xcef1, 0x21a9,
+ 0xcef2, 0x0f01,
+ 0xcef3, 0x21aa,
+ 0xcef4, 0x0f03,
+ 0xcefd, 0x21ab,
+ 0xcfa1, 0x0f0e,
+ 0xcfae, 0x21ad,
+ 0xcfaf, 0x0f1c,
+ 0xcfb0, 0x21ae,
+ 0xcfb1, 0x0f1e,
+ 0xcfb3, 0x21af,
+ 0xcfb4, 0x0f21,
+ 0xcfb7, 0x21b0,
+ 0xcfb9, 0x0f26,
+ 0xcfba, 0x21b2,
+ 0xcfbb, 0x0f28,
+ 0xcfbd, 0x21b3,
+ 0xcfbe, 0x0f2b,
+ 0xcfbf, 0x21b4,
+ 0xcfc2, 0x0f2f,
+ 0xcfc5, 0x21b7,
+ 0xcfc6, 0x0f33,
+ 0xcfc7, 0x21b8,
+ 0xcfc8, 0x0f35,
+ 0xcfca, 0x21b9,
+ 0xcfcc, 0x0f39,
+ 0xcfcd, 0x21bb,
+ 0xcfcf, 0x0f3c,
+ 0xcfd0, 0x21bd,
+ 0xcfd1, 0x0f3e,
+ 0xcfd4, 0x21be,
+ 0xcfd9, 0x0f46,
+ 0xcfda, 0x21c3,
+ 0xcfdb, 0x0f48,
+ 0xcfdc, 0x21c4,
+ 0xcfdd, 0x0f4a,
+ 0xcfdf, 0x21c5,
+ 0xcfe0, 0x0f4d,
+ 0xcfe2, 0x21c6,
+ 0xcfe3, 0x0f50,
+ 0xcfe7, 0x21c7,
+ 0xcfe8, 0x0f55,
+ 0xcfea, 0x21c8,
+ 0xcfeb, 0x0f58,
+ 0xcfec, 0x21c9,
+ 0xcfed, 0x0f5a,
+ 0xcfee, 0x21ca,
+ 0xcfef, 0x0f5c,
+ 0xcff4, 0x21cb,
+ 0xcff5, 0x0f62,
+ 0xcff9, 0x21cc,
+ 0xcffb, 0x0f68,
+ 0xcffe, 0x21ce,
+ 0xd0a1, 0x0f6c,
+ 0xd0a5, 0x21cf,
+ 0xd0a6, 0x0f71,
+ 0xd0ad, 0x21d0,
+ 0xd0af, 0x0f7a,
+ 0xd0b2, 0x21d2,
+ 0xd0b5, 0x0f80,
+ 0xd0ba, 0x21d5,
+ 0xd0bc, 0x0f87,
+ 0xd0bf, 0x21d7,
+ 0xd0c0, 0x0f8b,
+ 0xd0c6, 0x21d8,
+ 0xd0c7, 0x0f92,
+ 0xd0cb, 0x21d9,
+ 0xd0cc, 0x0f97,
+ 0xd0e2, 0x21da,
+ 0xd0e3, 0x0fae,
+ 0xd0e5, 0x21db,
+ 0xd0e6, 0x0fb1,
+ 0xd0eb, 0x21dc,
+ 0xd0ec, 0x0fb7,
+ 0xd0ed, 0x21dd,
+ 0xd0ee, 0x0fb9,
+ 0xd0f7, 0x21de,
+ 0xd0fa, 0x0fc5,
+ 0xd0fc, 0x21e1,
+ 0xd0fd, 0x0fc8,
+ 0xd1a1, 0x21e2,
+ 0xd1a3, 0x0fcc,
+ 0xd1a4, 0x21e4,
+ 0xd1a5, 0x0fce,
+ 0xd1a7, 0x21e5,
+ 0xd1a8, 0x0fd1,
+ 0xd1ab, 0x21e6,
+ 0xd1ac, 0x0fd5,
+ 0xd1af, 0x21e7,
+ 0xd1b2, 0x0fdb,
+ 0xd1b5, 0x21ea,
+ 0xd1b8, 0x0fe1,
+ 0xd1b9, 0x21ed,
+ 0xd1ba, 0x0fe3,
+ 0xd1bb, 0x21ee,
+ 0xd1bd, 0x0fe6,
+ 0xd1c6, 0x21f0,
+ 0xd1c9, 0x0ff2,
+ 0xd1cb, 0x21f3,
+ 0xd1cc, 0x0ff5,
+ 0xd1ce, 0x21f4,
+ 0xd1d0, 0x0ff9,
+ 0xd1d5, 0x21f6,
+ 0xd1d7, 0x1000,
+ 0xd1de, 0x21f8,
+ 0xd1df, 0x1008,
+ 0xd1e1, 0x21f9,
+ 0xd1e3, 0x100c,
+ 0xd1e8, 0x21fb,
+ 0xd1ea, 0x1013,
+ 0xd1ec, 0x21fd,
+ 0xd1ed, 0x1016,
+ 0xd1ee, 0x21fe,
+ 0xd1f0, 0x1019,
+ 0xd1f1, 0x2200,
+ 0xd1f2, 0x101b,
+ 0xd1f4, 0x2201,
+ 0xd1f5, 0x101e,
+ 0xd1f7, 0x2202,
+ 0xd1fa, 0x1023,
+ 0xd2a1, 0x1028,
+ 0xd2a2, 0x2205,
+ 0xd2a3, 0x102a,
+ 0xd2a5, 0x2206,
+ 0xd2a6, 0x102d,
+ 0xd2a9, 0x2207,
+ 0xd2aa, 0x1031,
+ 0xd2af, 0x2208,
+ 0xd2b0, 0x1037,
+ 0xd2b3, 0x2209,
+ 0xd2b4, 0x103b,
+ 0xd2b5, 0x220a,
+ 0xd2b7, 0x103e,
+ 0xd2bd, 0x220c,
+ 0xd2be, 0x1045,
+ 0xd2bf, 0x220d,
+ 0xd2c0, 0x1047,
+ 0xd2c3, 0x220e,
+ 0xd2c4, 0x104b,
+ 0xd2c5, 0x220f,
+ 0xd2c6, 0x104d,
+ 0xd2c7, 0x2210,
+ 0xd2c8, 0x104f,
+ 0xd2cf, 0x2211,
+ 0xd2d0, 0x1057,
+ 0xd2d5, 0x2212,
+ 0xd2d6, 0x105d,
+ 0xd2da, 0x2213,
+ 0xd2db, 0x1062,
+ 0xd2e4, 0x2214,
+ 0xd2e6, 0x106d,
+ 0xd2e8, 0x2216,
+ 0xd2ec, 0x1073,
+ 0xd2ef, 0x221a,
+ 0xd2f0, 0x1077,
+ 0xd2f1, 0x221b,
+ 0xd2f2, 0x1079,
+ 0xd2f5, 0x221c,
+ 0xd2f6, 0x107d,
+ 0xd2f8, 0x221d,
+ 0xd2f9, 0x1080,
+ 0xd2fb, 0x221e,
+ 0xd2fc, 0x1083,
+ 0xd2fe, 0x221f,
+ 0xd3a1, 0x1086,
+ 0xd3a3, 0x2220,
+ 0xd3ad, 0x1092,
+ 0xd3ae, 0x222a,
+ 0xd3af, 0x1094,
+ 0xd3b1, 0x222b,
+ 0xd3b2, 0x1097,
+ 0xd3b4, 0x222c,
+ 0xd3b7, 0x109c,
+ 0xd3b8, 0x222f,
+ 0xd3b9, 0x109e,
+ 0xd3bb, 0x2230,
+ 0xd3bc, 0x10a1,
+ 0xd3c5, 0x2231,
+ 0xd3c6, 0x10ab,
+ 0xd3c7, 0x2232,
+ 0xd3c8, 0x10ad,
+ 0xd3ca, 0x2233,
+ 0xd3cd, 0x10b2,
+ 0xd3d5, 0x2236,
+ 0xd3d6, 0x10bb,
+ 0xd3df, 0x2237,
+ 0xd3e1, 0x10c6,
+ 0xd3e3, 0x2239,
+ 0xd3e4, 0x10c9,
+ 0xd3e6, 0x223a,
+ 0xd3e7, 0x10cc,
+ 0xd3eb, 0x223b,
+ 0xd3ed, 0x10d2,
+ 0xd3ef, 0x223d,
+ 0xd3f0, 0x10d5,
+ 0xd3f4, 0x223e,
+ 0xd3f5, 0x10da,
+ 0xd3fc, 0x223f,
+ 0xd3fd, 0x10e2,
+ 0xd3fe, 0x2240,
+ 0xd4a1, 0x10e4,
+ 0xd4a4, 0x2241,
+ 0xd4a5, 0x10e8,
+ 0xd4a6, 0x2242,
+ 0xd4a9, 0x10ec,
+ 0xd4af, 0x2245,
+ 0xd4b3, 0x10f6,
+ 0xd4b5, 0x2249,
+ 0xd4b7, 0x10fa,
+ 0xd4b8, 0x224b,
+ 0xd4b9, 0x10fc,
+ 0xd4bc, 0x224c,
+ 0xd4bd, 0x1100,
+ 0xd4be, 0x224d,
+ 0xd4c0, 0x1103,
+ 0xd4c4, 0x224f,
+ 0xd4c5, 0x1108,
+ 0xd4c6, 0x2250,
+ 0xd4c8, 0x110b,
+ 0xd4c9, 0x2252,
+ 0xd4ca, 0x110d,
+ 0xd4cb, 0x2253,
+ 0xd4cf, 0x1112,
+ 0xd4d3, 0x2257,
+ 0xd4d4, 0x1117,
+ 0xd4d8, 0x2258,
+ 0xd4d9, 0x111c,
+ 0xd4dc, 0x2259,
+ 0xd4e1, 0x1124,
+ 0xd4e4, 0x225e,
+ 0xd4e5, 0x1128,
+ 0xd4e6, 0x225f,
+ 0xd4e7, 0x112a,
+ 0xd4ee, 0x2260,
+ 0xd4ef, 0x1132,
+ 0xd4f0, 0x2261,
+ 0xd4f5, 0x1138,
+ 0xd4f9, 0x2266,
+ 0xd4fa, 0x113d,
+ 0xd4fe, 0x2267,
+ 0xd5a1, 0x2268,
+ 0xd5a3, 0x1144,
+ 0xd5a9, 0x226a,
+ 0xd5aa, 0x114b,
+ 0xd5ab, 0x226b,
+ 0xd5ac, 0x114d,
+ 0xd5ae, 0x226c,
+ 0xd5af, 0x1150,
+ 0xd5b1, 0x226d,
+ 0xd5b2, 0x1153,
+ 0xd5b5, 0x226e,
+ 0xd5b9, 0x115a,
+ 0xd5bb, 0x2272,
+ 0xd5bc, 0x115d,
+ 0xd5bd, 0x2273,
+ 0xd5be, 0x115f,
+ 0xd5c0, 0x2274,
+ 0xd5c1, 0x1162,
+ 0xd5c5, 0x2275,
+ 0xd5c6, 0x1167,
+ 0xd5c7, 0x2276,
+ 0xd5c8, 0x1169,
+ 0xd5ca, 0x2277,
+ 0xd5cc, 0x116d,
+ 0xd5cd, 0x2279,
+ 0xd5ce, 0x116f,
+ 0xd5d4, 0x227a,
+ 0xd5d5, 0x1176,
+ 0xd5dd, 0x227b,
+ 0xd5df, 0x1180,
+ 0xd5e0, 0x227d,
+ 0xd5e1, 0x1182,
+ 0xd5e2, 0x227e,
+ 0xd5e3, 0x1184,
+ 0xd5ea, 0x227f,
+ 0xd5ed, 0x118e,
+ 0xd5ef, 0x2282,
+ 0xd5f0, 0x1191,
+ 0xd5f2, 0x2283,
+ 0xd5f4, 0x1195,
+ 0xd5f7, 0x15eb,
+ 0xd5f8, 0x1199,
+ 0xd6a1, 0x2285,
+ 0xd6a5, 0x11a4,
+ 0xd6af, 0x2289,
+ 0xd6b1, 0x11b0,
+ 0xd6b4, 0x228b,
+ 0xd6b5, 0x11b4,
+ 0xd6bb, 0x228c,
+ 0xd6bc, 0x11bb,
+ 0xd6bd, 0x228d,
+ 0xd6be, 0x11bd,
+ 0xd6bf, 0x228e,
+ 0xd6c1, 0x11c0,
+ 0xd6c4, 0x2290,
+ 0xd6c5, 0x11c4,
+ 0xd6ca, 0x2291,
+ 0xd6cb, 0x11ca,
+ 0xd6cd, 0x2292,
+ 0xd6ce, 0x11cd,
+ 0xd6d3, 0x2293,
+ 0xd6d4, 0x11d3,
+ 0xd6d5, 0x2294,
+ 0xd6d8, 0x11d7,
+ 0xd6da, 0x2297,
+ 0xd6db, 0x11da,
+ 0xd6df, 0x2298,
+ 0xd6e0, 0x11df,
+ 0xd6e1, 0x2299,
+ 0xd6e2, 0x11e1,
+ 0xd6e5, 0x229a,
+ 0xd6e6, 0x11e5,
+ 0xd6e7, 0x229b,
+ 0xd6e9, 0x11e8,
+ 0xd6ee, 0x229d,
+ 0xd6f0, 0x11ef,
+ 0xd6f2, 0x229f,
+ 0xd6f3, 0x11f2,
+ 0xd6f5, 0x22a0,
+ 0xd6f7, 0x11f6,
+ 0xd6fc, 0x22a2,
+ 0xd7a1, 0x11fe,
+ 0xd7a4, 0x22a5,
+ 0xd7a5, 0x1202,
+ 0xd7a8, 0x22a6,
+ 0xd7ab, 0x1208,
+ 0xd7ac, 0x22a9,
+ 0xd7ad, 0x120a,
+ 0xd7ae, 0x22aa,
+ 0xd7b2, 0x120f,
+ 0xd7b3, 0x22ae,
+ 0xd7b5, 0x1212,
+ 0xd7b6, 0x22b0,
+ 0xd7b7, 0x1214,
+ 0xd7b8, 0x22b1,
+ 0xd7bd, 0x121a,
+ 0xd7c7, 0x22b6,
+ 0xd7c8, 0x1225,
+ 0xd7ca, 0x22b7,
+ 0xd7cb, 0x1228,
+ 0xd7d5, 0x22b8,
+ 0xd7d6, 0x1233,
+ 0xd7db, 0x22b9,
+ 0xd7df, 0x123c,
+ 0xd7e7, 0x22bd,
+ 0xd7e8, 0x1245,
+ 0xd7e9, 0x22be,
+ 0xd7eb, 0x1248,
+ 0xd8a1, 0x1257,
+ 0xd8c4, 0x22c0,
+ 0xd8c5, 0x127b,
+ 0xd8c7, 0x22c1,
+ 0xd8c8, 0x127e,
+ 0xd8c9, 0x22c2,
+ 0xd8ca, 0x1280,
+ 0xd8cc, 0x22c3,
+ 0xd8ce, 0x1284,
+ 0xd8d0, 0x22c5,
+ 0xd8d2, 0x1288,
+ 0xd8d3, 0x22c7,
+ 0xd8d4, 0x128a,
+ 0xd8d9, 0x22c8,
+ 0xd8da, 0x1290,
+ 0xd8db, 0x22c9,
+ 0xd8dd, 0x1293,
+ 0xd8f1, 0x22cb,
+ 0xd8f2, 0x12a8,
+ 0xd8f6, 0x22cc,
+ 0xd8f8, 0x12ae,
+ 0xd9a1, 0x12b5,
+ 0xd9ad, 0x22ce,
+ 0xd9ae, 0x12c2,
+ 0xd9af, 0x22cf,
+ 0xd9b0, 0x12c4,
+ 0xd9b1, 0x22d0,
+ 0xd9b4, 0x12c8,
+ 0xd9c7, 0x22d3,
+ 0xd9c8, 0x12dc,
+ 0xd9cd, 0x22d4,
+ 0xd9d1, 0x12e5,
+ 0xd9dd, 0x22d8,
+ 0xd9de, 0x12f2,
+ 0xd9e1, 0x22d9,
+ 0xd9e2, 0x12f6,
+ 0xd9e4, 0x22da,
+ 0xd9e5, 0x12f9,
+ 0xd9e6, 0x22db,
+ 0xd9e7, 0x12fb,
+ 0xd9ec, 0x22dc,
+ 0xd9ed, 0x1301,
+ 0xd9f4, 0x22dd,
+ 0xd9f6, 0x130a,
+ 0xdaa1, 0x1313,
+ 0xdaa5, 0x22df,
+ 0xdae0, 0x1352,
+ 0xdaea, 0x231a,
+ 0xdaeb, 0x135d,
+ 0xdaf7, 0x231b,
+ 0xdaf8, 0x136a,
+ 0xdaf9, 0x231c,
+ 0xdafa, 0x136c,
+ 0xdafe, 0x231d,
+ 0xdba1, 0x1371,
+ 0xdba3, 0x231e,
+ 0xdba4, 0x1374,
+ 0xdba6, 0x231f,
+ 0xdba7, 0x1377,
+ 0xdba9, 0x2320,
+ 0xdbab, 0x137b,
+ 0xdbbb, 0x2322,
+ 0xdbbc, 0x138c,
+ 0xdbbd, 0x2323,
+ 0xdbbe, 0x138e,
+ 0xdbcf, 0x2324,
+ 0xdbd0, 0x13a0,
+ 0xdbd1, 0x2325,
+ 0xdbd2, 0x13a2,
+ 0xdbdb, 0x2326,
+ 0xdbdc, 0x13ac,
+ 0xdbde, 0x2327,
+ 0xdbdf, 0x13af,
+ 0xdbe2, 0x2328,
+ 0xdbe3, 0x13b3,
+ 0xdbe4, 0x2329,
+ 0xdbe5, 0x13b5,
+ 0xdbeb, 0x232a,
+ 0xdbec, 0x13bc,
+ 0xdbee, 0x232b,
+ 0xdbef, 0x13bf,
+ 0xdbf1, 0x232c,
+ 0xdbf2, 0x13c2,
+ 0xdbf5, 0x232d,
+ 0xdbf8, 0x13c8,
+ 0xdca1, 0x13cf,
+ 0xdcbc, 0x2330,
+ 0xdcbd, 0x13eb,
+ 0xdcbf, 0x2331,
+ 0xdcc0, 0x13ee,
+ 0xdcc2, 0x2332,
+ 0xdcc3, 0x13f1,
+ 0xdcc8, 0x2333,
+ 0xdccb, 0x13f9,
+ 0xdcd1, 0x2336,
+ 0xdcd2, 0x1400,
+ 0xdcd7, 0x2337,
+ 0xdcd8, 0x1406,
+ 0xdce0, 0x2338,
+ 0xdce1, 0x140f,
+ 0xdce3, 0x2339,
+ 0xdce5, 0x1413,
+ 0xdce9, 0x233b,
+ 0xdceb, 0x1419,
+ 0xdcf1, 0x233d,
+ 0xdcf2, 0x1420,
+ 0xdcf6, 0x233e,
+ 0xdcf7, 0x1425,
+ 0xdcf9, 0x233f,
+ 0xdcfa, 0x1428,
+ 0xdcfd, 0x2340,
+ 0xdda1, 0x2342,
+ 0xdda2, 0x142e,
+ 0xdda3, 0x2343,
+ 0xdda8, 0x1434,
+ 0xddaa, 0x2348,
+ 0xddac, 0x1438,
+ 0xddb2, 0x234a,
+ 0xddb3, 0x143f,
+ 0xddb5, 0x234b,
+ 0xddb6, 0x1442,
+ 0xddba, 0x234c,
+ 0xddbc, 0x1448,
+ 0xddd3, 0x234e,
+ 0xddd4, 0x1460,
+ 0xdddb, 0x234f,
+ 0xdddc, 0x1468,
+ 0xddde, 0x2350,
+ 0xdddf, 0x146b,
+ 0xdde4, 0x2351,
+ 0xdde5, 0x1471,
+ 0xddeb, 0x2352,
+ 0xddec, 0x1478,
+ 0xddf1, 0x2353,
+ 0xddf2, 0x147e,
+ 0xddf6, 0x2354,
+ 0xddf8, 0x1484,
+ 0xddfc, 0x2356,
+ 0xddfd, 0x1489,
+ 0xddfe, 0x2357,
+ 0xdea1, 0x148b,
+ 0xdead, 0x2358,
+ 0xdeae, 0x1498,
+ 0xdeb4, 0x2359,
+ 0xdeb5, 0x149f,
+ 0xdeba, 0x235a,
+ 0xdebb, 0x14a5,
+ 0xdec6, 0x235b,
+ 0xdec7, 0x14b1,
+ 0xdecf, 0x235c,
+ 0xded0, 0x14ba,
+ 0xded1, 0x235d,
+ 0xded3, 0x14bd,
+ 0xded8, 0x235f,
+ 0xded9, 0x14c3,
+ 0xdee2, 0x2360,
+ 0xdee3, 0x14cd,
+ 0xdee8, 0x2361,
+ 0xdee9, 0x14d3,
+ 0xdeec, 0x2362,
+ 0xdeed, 0x14d7,
+ 0xdef3, 0x2363,
+ 0xdef4, 0x14de,
+ 0xdefc, 0x2364,
+ 0xdefd, 0x14e7,
+ 0xdfa1, 0x14e9,
+ 0xdfa2, 0x2365,
+ 0xdfa4, 0x14ec,
+ 0xdfa5, 0x2367,
+ 0xdfa6, 0x14ee,
+ 0xdfb4, 0x2368,
+ 0xdfb5, 0x14fd,
+ 0xdfbc, 0x2369,
+ 0xdfbe, 0x1506,
+ 0xdfbf, 0x236b,
+ 0xdfc0, 0x1508,
+ 0xdfc2, 0x236c,
+ 0xdfc4, 0x150c,
+ 0xdfcc, 0x236e,
+ 0xdfcd, 0x1515,
+ 0xdfd0, 0x236f,
+ 0xdfd1, 0x1519,
+ 0xdfd5, 0x2370,
+ 0xdfd6, 0x151e,
+ 0xdfd8, 0x2371,
+ 0xdfda, 0x1522,
+ 0xdfdc, 0x2373,
+ 0xdfdd, 0x1525,
+ 0xdfe0, 0x2374,
+ 0xdfe1, 0x1529,
+ 0xdfe2, 0x2375,
+ 0xdfe3, 0x152b,
+ 0xdfe6, 0x2376,
+ 0xdfe7, 0x152f,
+ 0xdfe9, 0x2377,
+ 0xdfea, 0x1532,
+ 0xdfeb, 0x2378,
+ 0xdfec, 0x1534,
+ 0xdfef, 0x2379,
+ 0xdff0, 0x1538,
+ 0xdff5, 0x237a,
+ 0xdff6, 0x153e,
+ 0xdff9, 0x237b,
+ 0xdffa, 0x1542,
+ 0xe0a1, 0x1547,
+ 0xe0b6, 0x237c,
+ 0xe0b8, 0x155e,
+ 0xe0bf, 0x237e,
+ 0xe0c0, 0x1566,
+ 0xe0c8, 0x237f,
+ 0xe0c9, 0x156f,
+ 0xe0ce, 0x2380,
+ 0xe0cf, 0x1575,
+ 0xe0d3, 0x2381,
+ 0xe0d4, 0x157a,
+ 0xe0e0, 0x2382,
+ 0xe0e1, 0x1587,
+ 0xe0f0, 0x2383,
+ 0xe0f1, 0x1597,
+ 0xe0f8, 0x2384,
+ 0xe0f9, 0x159f,
+ 0xe0fc, 0x2385,
+ 0xe1a1, 0x15a5,
+ 0xe1ab, 0x2388,
+ 0xe1ac, 0x15b0,
+ 0xe1ad, 0x2389,
+ 0xe1ae, 0x15b2,
+ 0xe1b0, 0x238a,
+ 0xe1b1, 0x15b5,
+ 0xe1b4, 0x238b,
+ 0xe1b5, 0x15b9,
+ 0xe1bb, 0x238c,
+ 0xe1bc, 0x15c0,
+ 0xe1bd, 0x238d,
+ 0xe1be, 0x15c2,
+ 0xe1c0, 0x238e,
+ 0xe1c2, 0x15c6,
+ 0xe1c9, 0x2390,
+ 0xe1ca, 0x15ce,
+ 0xe1d0, 0x2391,
+ 0xe1d1, 0x15d5,
+ 0xe1db, 0x2392,
+ 0xe1dc, 0x15e0,
+ 0xe1e1, 0x07aa,
+ 0xe1e2, 0x2393,
+ 0xe1e3, 0x15e7,
+ 0xe1e7, 0x1198,
+ 0xe1e8, 0x15ec,
+ 0xe1ee, 0x2394,
+ 0xe1f0, 0x15f4,
+ 0xe1f6, 0x2396,
+ 0xe1f7, 0x15fb,
+ 0xe1f8, 0x2397,
+ 0xe1f9, 0x15fd,
+ 0xe1fd, 0x2398,
+ 0xe1fe, 0x1602,
+ 0xe2a1, 0x1603,
+ 0xe2a4, 0x2399,
+ 0xe2a5, 0x1607,
+ 0xe2a8, 0x239a,
+ 0xe2a9, 0x160b,
+ 0xe2bb, 0x239b,
+ 0xe2c5, 0x10c5,
+ 0xe2c6, 0x23a5,
+ 0xe2cf, 0x1631,
+ 0xe2d0, 0x23ae,
+ 0xe2d1, 0x1633,
+ 0xe2d9, 0x23af,
+ 0xe2da, 0x163c,
+ 0xe2e3, 0x23b0,
+ 0xe2e5, 0x1647,
+ 0xe2e6, 0x23b2,
+ 0xe2e7, 0x1649,
+ 0xe2e9, 0x23b3,
+ 0xe2ec, 0x164e,
+ 0xe2f8, 0x23b6,
+ 0xe2f9, 0x165b,
+ 0xe2fa, 0x23b7,
+ 0xe2fe, 0x1660,
+ 0xe3a1, 0x1661,
+ 0xe3a2, 0x23bb,
+ 0xe3a3, 0x1663,
+ 0xe3a5, 0x23bc,
+ 0xe3a6, 0x1666,
+ 0xe3ab, 0x23bd,
+ 0xe3ac, 0x166c,
+ 0xe3b4, 0x23be,
+ 0xe3b5, 0x1675,
+ 0xe3c5, 0x23bf,
+ 0xe3dc, 0x169c,
+ 0xe3e3, 0x23d6,
+ 0xe3e4, 0x16a4,
+ 0xe3ed, 0x23d7,
+ 0xe3ee, 0x16ae,
+ 0xe3f1, 0x23d8,
+ 0xe3f3, 0x16b3,
+ 0xe3f8, 0x23da,
+ 0xe3f9, 0x16b9,
+ 0xe3fe, 0x23db,
+ 0xe4a1, 0x16bf,
+ 0xe4a4, 0x23dc,
+ 0xe4a6, 0x16c4,
+ 0xe4ab, 0x23de,
+ 0xe4ac, 0x16ca,
+ 0xe4af, 0x23df,
+ 0xe4b2, 0x16d0,
+ 0xe4b5, 0x23e2,
+ 0xe4b7, 0x16d5,
+ 0xe4c2, 0x23e4,
+ 0xe4c3, 0x16e1,
+ 0xe4c5, 0x23e5,
+ 0xe4c6, 0x16e4,
+ 0xe4c9, 0x23e6,
+ 0xe4ca, 0x16e8,
+ 0xe4d9, 0x23e7,
+ 0xe4da, 0x16f8,
+ 0xe4dc, 0x23e8,
+ 0xe4dd, 0x16fb,
+ 0xe4de, 0x23e9,
+ 0xe4df, 0x16fd,
+ 0xe4e4, 0x23ea,
+ 0xe4e5, 0x1703,
+ 0xe4eb, 0x23eb,
+ 0xe4ed, 0x170b,
+ 0xe4f2, 0x23ed,
+ 0xe4f3, 0x1711,
+ 0xe4fe, 0x23ee,
+ 0xe5a1, 0x171d,
+ 0xe5b0, 0x23ef,
+ 0xe5b1, 0x172d,
+ 0xe5b9, 0x23f0,
+ 0xe5ba, 0x1736,
+ 0xe5c7, 0x23f1,
+ 0xe5c8, 0x1744,
+ 0xe5c9, 0x23f2,
+ 0xe5ca, 0x1746,
+ 0xe5ce, 0x23f3,
+ 0xe5cf, 0x174b,
+ 0xe5f0, 0x23f4,
+ 0xe5f1, 0x176d,
+ 0xe5f2, 0x23f5,
+ 0xe5f3, 0x176f,
+ 0xe5fc, 0x23f6,
+ 0xe5fe, 0x177a,
+ 0xe6a1, 0x177b,
+ 0xe6a3, 0x23f8,
+ 0xe6a4, 0x177e,
+ 0xe6ab, 0x23f9,
+ 0xe6ad, 0x1787,
+ 0xe6ae, 0x23fb,
+ 0xe6af, 0x1789,
+ 0xe6b4, 0x23fc,
+ 0xe6b6, 0x1790,
+ 0xe6bf, 0x23fe,
+ 0xe6c0, 0x179a,
+ 0xe6c8, 0x23ff,
+ 0xe6ca, 0x17a4,
+ 0xe6cd, 0x2401,
+ 0xe6ce, 0x17a8,
+ 0xe6e0, 0x2402,
+ 0xe7a1, 0x2421,
+ 0xe7db, 0x1813,
+ 0xe7e1, 0x245b,
+ 0xe7e3, 0x181b,
+ 0xe7e7, 0x245d,
+ 0xe7e8, 0x1820,
+ 0xe7ef, 0x245e,
+ 0xe7f0, 0x1828,
+ 0xe7f4, 0x245f,
+ 0xe7f7, 0x182f,
+ 0xe8a1, 0x1837,
+ 0xe8a8, 0x2462,
+ 0xe8a9, 0x183f,
+ 0xe8ac, 0x2463,
+ 0xe8ad, 0x1843,
+ 0xe8b6, 0x2464,
+ 0xe8b7, 0x184d,
+ 0xe8b8, 0x2465,
+ 0xe8bb, 0x1851,
+ 0xe8bf, 0x2468,
+ 0xe8c1, 0x1857,
+ 0xe8c5, 0x246a,
+ 0xe8c6, 0x185c,
+ 0xe8c7, 0x246b,
+ 0xe8ca, 0x1860,
+ 0xe8ce, 0x246e,
+ 0xe8cf, 0x1865,
+ 0xe8d0, 0x246f,
+ 0xe8d1, 0x1867,
+ 0xe8d3, 0x2470,
+ 0xe8d4, 0x186a,
+ 0xe8dd, 0x2471,
+ 0xe8de, 0x1874,
+ 0xe8df, 0x2472,
+ 0xe8e0, 0x1876,
+ 0xe8e2, 0x2473,
+ 0xe8e4, 0x187a,
+ 0xe8e5, 0x2475,
+ 0xe8e6, 0x187c,
+ 0xe8e7, 0x2476,
+ 0xe8e8, 0x187e,
+ 0xe8eb, 0x2477,
+ 0xe8ec, 0x1882,
+ 0xe8ed, 0x2478,
+ 0xe8ee, 0x1884,
+ 0xe8ef, 0x2479,
+ 0xe8f0, 0x1886,
+ 0xe8f9, 0x247a,
+ 0xe8fa, 0x1890,
+ 0xe8fc, 0x247b,
+ 0xe8fe, 0x1894,
+ 0xe9a1, 0x247d,
+ 0xe9a2, 0x1896,
+ 0xe9ad, 0x247e,
+ 0xe9ae, 0x18a2,
+ 0xe9b4, 0x247f,
+ 0xe9b6, 0x18aa,
+ 0xe9b7, 0x2481,
+ 0xe9b8, 0x18ac,
+ 0xe9c4, 0x2482,
+ 0xe9c5, 0x18b9,
+ 0xe9c6, 0x2483,
+ 0xe9c7, 0x18bb,
+ 0xe9c9, 0x2484,
+ 0xe9ca, 0x18be,
+ 0xe9d6, 0x2485,
+ 0xe9d7, 0x18cb,
+ 0xe9da, 0x2486,
+ 0xe9db, 0x18cf,
+ 0xe9e4, 0x2487,
+ 0xe9e5, 0x18d9,
+ 0xe9e6, 0x2488,
+ 0xe9e8, 0x18dc,
+ 0xe9e9, 0x248a,
+ 0xe9ea, 0x18de,
+ 0xe9eb, 0x248b,
+ 0xe9ec, 0x18e0,
+ 0xe9ed, 0x248c,
+ 0xeaa1, 0x249e,
+ 0xeaa6, 0x18f8,
+ 0xeaa7, 0x24a3,
+ 0xeaa9, 0x18fb,
+ 0xeab1, 0x24a5,
+ 0xeab2, 0x1904,
+ 0xeabc, 0x24a6,
+ 0xeabd, 0x190f,
+ 0xeaca, 0x24a7,
+ 0xeacb, 0x191d,
+ 0xeacd, 0x24a8,
+ 0xeace, 0x1920,
+ 0xead3, 0x24a9,
+ 0xead4, 0x1926,
+ 0xeada, 0x24aa,
+ 0xeaf0, 0x1942,
+ 0xeba1, 0x1951,
+ 0xeba7, 0x24c0,
+ 0xeba8, 0x1958,
+ 0xebaa, 0x24c1,
+ 0xebab, 0x195b,
+ 0xebb2, 0x24c2,
+ 0xebb3, 0x1963,
+ 0xebb9, 0x24c3,
+ 0xebba, 0x196a,
+ 0xebca, 0x24c4,
+ 0xebcc, 0x197c,
+ 0xebcd, 0x24c6,
+ 0xebce, 0x197e,
+ 0xebd6, 0x24c7,
+ 0xebd7, 0x1987,
+ 0xebda, 0x24c8,
+ 0xebdb, 0x198b,
+ 0xebe1, 0x24c9,
+ 0xebe2, 0x1992,
+ 0xebf7, 0x24ca,
+ 0xebf8, 0x19a8,
+ 0xeca1, 0x19af,
+ 0xeca3, 0x24cb,
+ 0xeca4, 0x19b2,
+ 0xeca9, 0x24cc,
+ 0xecaf, 0x19bd,
+ 0xecb1, 0x24d2,
+ 0xecb2, 0x19c0,
+ 0xecb4, 0x24d3,
+ 0xecb6, 0x19c4,
+ 0xecbe, 0x24d5,
+ 0xecc0, 0x19ce,
+ 0xecc1, 0x24d7,
+ 0xecc2, 0x19d0,
+ 0xecc7, 0x24d8,
+ 0xecc8, 0x19d6,
+ 0xeccb, 0x24d9,
+ 0xeccc, 0x19da,
+ 0xece2, 0x24da,
+ 0xece3, 0x19f1,
+ 0xecf2, 0x24db,
+ 0xecf3, 0x1a01,
+ 0xecf5, 0x24dc,
+ 0xecf6, 0x1a04,
+ 0xecf8, 0x24dd,
+ 0xecf9, 0x1a07,
+ 0xeda1, 0x24de,
+ 0xeda2, 0x1a0e,
+ 0xeda8, 0x24df,
+ 0xeda9, 0x1a15,
+ 0xedaf, 0x24e0,
+ 0xedb1, 0x1a1d,
+ 0xedb4, 0x24e2,
+ 0xedb5, 0x1a21,
+ 0xedb6, 0x24e3,
+ 0xedb7, 0x1a23,
+ 0xedb8, 0x24e4,
+ 0xedb9, 0x1a25,
+ 0xedba, 0x24e5,
+ 0xedbb, 0x1a27,
+ 0xedbf, 0x24e6,
+ 0xedc0, 0x1a2c,
+ 0xedc2, 0x24e7,
+ 0xedc4, 0x1a30,
+ 0xedcc, 0x24e9,
+ 0xedce, 0x1a3a,
+ 0xedd3, 0x24eb,
+ 0xedd4, 0x1a40,
+ 0xedd7, 0x24ec,
+ 0xedd8, 0x1a44,
+ 0xede8, 0x24ed,
+ 0xede9, 0x1a55,
+ 0xedee, 0x24ee,
+ 0xedef, 0x1a5b,
+ 0xedf9, 0x24ef,
+ 0xedfb, 0x1a67,
+ 0xeea1, 0x1a6b,
+ 0xeebc, 0x24f1,
+ 0xeebd, 0x1a87,
+ 0xeebf, 0x24f2,
+ 0xeec0, 0x1a8a,
+ 0xeec4, 0x24f3,
+ 0xefa1, 0x252e,
+ 0xeff2, 0x1b1a,
+ 0xf0a1, 0x1b27,
+ 0xf0a3, 0x257f,
+ 0xf0a4, 0x1b2a,
+ 0xf0af, 0x2580,
+ 0xf0da, 0x1b60,
+ 0xf0dc, 0x25ab,
+ 0xf0de, 0x1b64,
+ 0xf0df, 0x25ad,
+ 0xf0e0, 0x1b66,
+ 0xf0e9, 0x25ae,
+ 0xf0ea, 0x1b70,
+ 0xf0ec, 0x25af,
+ 0xf0ed, 0x1b73,
+ 0xf0ef, 0x25b0,
+ 0xf0f0, 0x1b76,
+ 0xf0f7, 0x25b1,
+ 0xf0f8, 0x1b7e,
+ 0xf0f9, 0x25b2,
+ 0xf0fa, 0x1b80,
+ 0xf0fc, 0x25b3,
+ 0xf0fd, 0x1b83,
+ 0xf1a1, 0x1b85,
+ 0xf1a8, 0x25b4,
+ 0xf1a9, 0x1b8d,
+ 0xf1ab, 0x25b5,
+ 0xf1ac, 0x1b90,
+ 0xf1ae, 0x25b6,
+ 0xf1af, 0x1b93,
+ 0xf1b2, 0x25b7,
+ 0xf1b3, 0x1b97,
+ 0xf1bc, 0x25b8,
+ 0xf1bd, 0x1ba1,
+ 0xf1c0, 0x25b9,
+ 0xf1c1, 0x1ba5,
+ 0xf1c9, 0x25ba,
+ 0xf1ca, 0x1bae,
+ 0xf1cd, 0x25bb,
+ 0xf1ce, 0x1bb2,
+ 0xf1cf, 0x25bc,
+ 0xf1d1, 0x1bb5,
+ 0xf1da, 0x25be,
+ 0xf1db, 0x1bbf,
+ 0xf1dc, 0x25bf,
+ 0xf1dd, 0x1bc1,
+ 0xf1e4, 0x25c0,
+ 0xf1e5, 0x1bc9,
+ 0xf1ec, 0x25c1,
+ 0xf1ed, 0x1bd1,
+ 0xf1ef, 0x25c2,
+ 0xf1f0, 0x1bd4,
+ 0xf1f7, 0x25c3,
+ 0xf1f8, 0x1bdc,
+ 0xf1f9, 0x25c4,
+ 0xf1fa, 0x1bde,
+ 0xf1fc, 0x25c5,
+ 0xf2a1, 0x25c8,
+ 0xf2ae, 0x1bf0,
+ 0xf2b1, 0x25d5,
+ 0xf2b3, 0x1bf5,
+ 0xf2b9, 0x25d7,
+ 0xf2ba, 0x1bfc,
+ 0xf2c3, 0x25d8,
+ 0xf2c4, 0x1c06,
+ 0xf2c9, 0x25d9,
+ 0xf2ca, 0x1c0c,
+ 0xf2cc, 0x25da,
+ 0xf2ce, 0x1c10,
+ 0xf2cf, 0x25dc,
+ 0xf2d0, 0x1c12,
+ 0xf2d3, 0x25dd,
+ 0xf2d4, 0x1c16,
+ 0xf2e5, 0x25de,
+ 0xf2e6, 0x1c28,
+ 0xf2ee, 0x25df,
+ 0xf2ef, 0x1c31,
+ 0xf2f7, 0x25e0,
+ 0xf2f8, 0x1c3a,
+ 0xf2fd, 0x25e1,
+ 0xf2fe, 0x1c40,
+ 0xf3a1, 0x1c41,
+ 0xf3bf, 0x25e2,
+ 0xf3c0, 0x1c60,
+ 0xf3c6, 0x25e3,
+ 0xf3c7, 0x1c67,
+ 0xf3c8, 0x25e4,
+ 0xf3c9, 0x1c69,
+ 0xf3d6, 0x25e5,
+ 0xf3d7, 0x1c77,
+ 0xf3d9, 0x25e6,
+ 0xf3da, 0x1c7a,
+ 0xf3e5, 0x25e7,
+ 0xf3e7, 0x1c87,
+ 0xf3ea, 0x25e9,
+ 0xf3eb, 0x1c8b,
+ 0xf3ec, 0x25ea,
+ 0xf3ed, 0x1c8d,
+ 0xf3ef, 0x25eb,
+ 0xf3f0, 0x1c90,
+ 0xf3f1, 0x25ec,
+ 0xf3f2, 0x1c92,
+ 0xf3fd, 0x25ed,
+ 0xf3fe, 0x1c9e,
+ 0xf4a1, 0x1c9f,
+ 0xf4a5, 0x25ee,
+ 0xf4a6, 0x1ca4,
+ 0xf4af, 0x25ef,
+ 0xf4b0, 0x1cae,
+ 0xf4b5, 0x25f0,
+ 0xf4b6, 0x1cb4,
+ 0xf4c1, 0x25f1,
+ 0xf4c2, 0x1cc0,
+ 0xf4c7, 0x25f2,
+ 0xf4c8, 0x1cc6,
+ 0xf4cf, 0x25f3,
+ 0xf4d1, 0x1ccf,
+ 0xf4d6, 0x25f5,
+ 0xf4d7, 0x1cd5,
+ 0xf4ea, 0x25f6,
+ 0xf4eb, 0x1ce9,
+ 0xf4ef, 0x25f7,
+ 0xf4f0, 0x1cee,
+ 0xf4f5, 0x25f8,
+ 0xf4f6, 0x1cf4,
+ 0xf5a1, 0x1cfd,
+ 0xf5a6, 0x25f9,
+ 0xf5a8, 0x1d04,
+ 0xf5ba, 0x25fb,
+ 0xf5bc, 0x1d18,
+ 0xf5c4, 0x25fd,
+ 0xf5c5, 0x1d21,
+ 0xf5c8, 0x25fe,
+ 0xf5c9, 0x1d25,
+ 0xf5ce, 0x25ff,
+ 0xf5d0, 0x1d2c,
+ 0xf5d1, 0x2601,
+ 0xf5d3, 0x1d2f,
+ 0xf5d9, 0x2603,
+ 0xf5da, 0x1d36,
+ 0xf5dc, 0x2604,
+ 0xf5dd, 0x1d39,
+ 0xf5e6, 0x2605,
+ 0xf5e8, 0x1d44,
+ 0xf5ef, 0x2607,
+ 0xf5f0, 0x1d4c,
+ 0xf5f2, 0x2608,
+ 0xf5f3, 0x1d4f,
+ 0xf5fc, 0x2609,
+ 0xf5fd, 0x1d59,
+ 0xf6a1, 0x1d5b,
+ 0xf6a3, 0x260a,
+ 0xf6a4, 0x1d5e,
+ 0xf6a6, 0x260b,
+ 0xf6a7, 0x1d61,
+ 0xf6a8, 0x260c,
+ 0xf6a9, 0x1d63,
+ 0xf6ab, 0x260d,
+ 0xf6ac, 0x1d66,
+ 0xf6b0, 0x260e,
+ 0xf6b1, 0x1d6b,
+ 0xf6b3, 0x260f,
+ 0xf6bf, 0x1d79,
+ 0xf6c5, 0x261b,
+ 0xf6c6, 0x1d80,
+ 0xf6c7, 0x261c,
+ 0xf6c8, 0x1d82,
+ 0xf6c9, 0x261d,
+ 0xf6ca, 0x1d84,
+ 0xf6cf, 0x261e,
+ 0xf7a1, 0x264e,
+ 0xf7b0, 0x1dc8,
+ 0xf7b2, 0x265d,
+ 0xf7b4, 0x1dcc,
+ 0xf7b5, 0x265f,
+ 0xf7b6, 0x1dce,
+ 0xf7bd, 0x2660,
+ 0xf7be, 0x1dd6,
+ 0xf7c3, 0x2661,
+ 0xf7c4, 0x1ddc,
+ 0xf7c5, 0x2662,
+ 0xf7c7, 0x1ddf,
+ 0xf7ca, 0x2664,
+ 0xf7cc, 0x1de4,
+ 0xf7cf, 0x2666,
+ 0xf7d1, 0x1de9,
+ 0xf7de, 0x2668,
+ 0xf7df, 0x1df7,
+ 0xf7e1, 0x0ab9,
+ 0xf7e2, 0x1dfa,
+ 0xf7f2, 0x2669,
+ 0xf7f3, 0x1e0b,
+ 0xf7f5, 0x266a,
+ 0xf7f6, 0x1e0e,
+ 0xf8a1, 0x266b,
+ 0xf8a7, 0x04cc,
+ 0xf8a8, 0x050a,
+ 0xf8a9, 0x0518,
+ 0xf8aa, 0x2671,
+ 0xf8ac, 0x0594,
+ 0xf8ad, 0x05ce,
+ 0xf8ae, 0x2673,
+ 0xf8af, 0x05f6,
+ 0xf8b0, 0x2674,
+ 0xf8b2, 0x0653,
+ 0xf8b3, 0x067e,
+ 0xf8b4, 0x2676,
+ 0xf8b5, 0x06c4,
+ 0xf8b6, 0x2677,
+ 0xf8b8, 0x073c,
+ 0xf8b9, 0x2679,
+ 0xf8bb, 0x07c3,
+ 0xf8bc, 0x267b,
+ 0xf8c0, 0x082b,
+ 0xf8c1, 0x267f,
+ 0xf8c2, 0x084e,
+ 0xf8c3, 0x0869,
+ 0xf8c4, 0x2680,
+ 0xf8c6, 0x090c,
+ 0xf8c7, 0x2682,
+ 0xf8c9, 0x0971,
+ 0xf8ca, 0x2684,
+ 0xf8cb, 0x099a,
+ 0xf8cd, 0x2685,
+ 0xf8ce, 0x09da,
+ 0xf8cf, 0x2686,
+ 0xf8d0, 0x09fa,
+ 0xf8d1, 0x2687,
+ 0xf8dc, 0x0bda,
+ 0xf8dd, 0x0bdd,
+ 0xf8de, 0x0bea,
+ 0xf8df, 0x0bec,
+ 0xf8e0, 0x0bf2,
+ 0xf8e1, 0x2692,
+ 0xf8e6, 0x0c92,
+ 0xf8e7, 0x0d1a,
+ 0xf8e8, 0x0d8c,
+ 0xf8e9, 0x0dbe,
+ 0xf8ea, 0x2697,
+ 0xf8eb, 0x0dfb,
+ 0xf8ec, 0x2698,
+ 0xf8ef, 0x0e70,
+ 0xf8f0, 0x269b,
+ 0xf8f1, 0x0ea3,
+ 0xf8f2, 0x269c,
+ 0xf8f8, 0x103d,
+ 0xf8f9, 0x10d9,
+ 0xf8fa, 0x26a2,
+ 0xf8fc, 0x10fb,
+ 0xf8fd, 0x1109,
+ 0xf8fe, 0x26a4,
+ 0xf9a1, 0x11a1,
+ 0xf9a2, 0x26a5,
+ 0xf9a3, 0x11ba,
+ 0xf9a4, 0x26a6,
+ 0xf9a6, 0x11d5,
+ 0xf9a7, 0x26a8,
+ 0xf9a8, 0x11fd,
+ 0xf9a9, 0x1219,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBTEUCHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1e24, 0x032e, 0x032f, 0x0330, 0x0331, 0x0332, 0x0333, 0x0334,
+ 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x033a, 0x033b, 0x033c,
+ 0x033d, 0x033e, 0x033f, 0x0340, 0x0341, 0x0342, 0x0343, 0x0344,
+ 0x0345, 0x0346, 0x0347, 0x0348, 0x0349, 0x034a, 0x034b, 0x034c,
+ 0x034d, 0x034e, 0x034f, 0x0350, 0x0351, 0x0352, 0x0353, 0x0354,
+ 0x0355, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035c,
+ 0x035d, 0x035e, 0x035f, 0x0360, 0x0361, 0x0362, 0x0363, 0x0364,
+ 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c,
+ 0x036d, 0x036e, 0x036f, 0x0370, 0x0371, 0x0372, 0x0373, 0x0374,
+ 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x037a, 0x037b, 0x037c,
+ 0x037d, 0x037e, 0x037f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384,
+ 0x0385, 0x0386, 0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12GBTEUCHMap2, 2283
+};
+
+static Gushort gb12GBTEUCVMap2[4606] = {
+ 0x0000, 0x0000,
+ 0xa1a1, 0x0060,
+ 0xa2b1, 0x00be,
+ 0xa2e5, 0x00f0,
+ 0xa2f1, 0x00fa,
+ 0xa3a1, 0x0106,
+ 0xa4a1, 0x0164,
+ 0xa5a1, 0x01b7,
+ 0xa6a1, 0x020d,
+ 0xa6c1, 0x0225,
+ 0xa7a1, 0x025a,
+ 0xa7d1, 0x027b,
+ 0xa8a1, 0x029c,
+ 0xa8c5, 0x02bc,
+ 0xa9a4, 0x02e2,
+ 0xaaa1, 0x032e,
+ 0xaba1, 0x038c,
+ 0xb0a1, 0x03ac,
+ 0xb0a8, 0x1e25,
+ 0xb0a9, 0x03b4,
+ 0xb0aa, 0x1e26,
+ 0xb0ab, 0x03b6,
+ 0xb0ad, 0x1e27,
+ 0xb0af, 0x03ba,
+ 0xb0b9, 0x1e29,
+ 0xb0ba, 0x03c5,
+ 0xb0c0, 0x1e2a,
+ 0xb0c1, 0x03cc,
+ 0xb0d3, 0x1e2b,
+ 0xb0d4, 0x03df,
+ 0xb0d5, 0x1e2c,
+ 0xb0d6, 0x03e1,
+ 0xb0da, 0x1e2d,
+ 0xb0db, 0x03e6,
+ 0xb0dc, 0x1e2e,
+ 0xb0dd, 0x03e8,
+ 0xb0e4, 0x1e2f,
+ 0xb0e5, 0x03f0,
+ 0xb0ec, 0x1e30,
+ 0xb0ee, 0x03f9,
+ 0xb0ef, 0x1e32,
+ 0xb0f0, 0x03fb,
+ 0xb0f3, 0x1e33,
+ 0xb0f4, 0x03ff,
+ 0xb0f7, 0x1e34,
+ 0xb0f8, 0x0403,
+ 0xb0f9, 0x1e35,
+ 0xb0fa, 0x0405,
+ 0xb1a1, 0x040a,
+ 0xb1a5, 0x1e36,
+ 0xb1a7, 0x0410,
+ 0xb1a8, 0x1e38,
+ 0xb1a9, 0x0412,
+ 0xb1ab, 0x1e39,
+ 0xb1ac, 0x0415,
+ 0xb1b2, 0x1e3a,
+ 0xb1b3, 0x041c,
+ 0xb1b4, 0x1e3b,
+ 0xb1b6, 0x041f,
+ 0xb1b7, 0x1e3d,
+ 0xb1ba, 0x0423,
+ 0xb1c1, 0x1e40,
+ 0xb1c2, 0x042b,
+ 0xb1ca, 0x1e41,
+ 0xb1cb, 0x0434,
+ 0xb1cf, 0x1e42,
+ 0xb1d1, 0x043a,
+ 0xb1d2, 0x1e44,
+ 0xb1d3, 0x043c,
+ 0xb1d5, 0x1e45,
+ 0xb1d6, 0x043f,
+ 0xb1df, 0x1e46,
+ 0xb1e2, 0x044b,
+ 0xb1e4, 0x1e49,
+ 0xb1e5, 0x044e,
+ 0xb1e7, 0x1e4a,
+ 0xb1e9, 0x0452,
+ 0xb1ea, 0x1e4c,
+ 0xb1eb, 0x0454,
+ 0xb1ee, 0x1e4d,
+ 0xb1ef, 0x0458,
+ 0xb1f1, 0x1e4e,
+ 0xb1f2, 0x045b,
+ 0xb1f4, 0x1e4f,
+ 0xb1f8, 0x0461,
+ 0xb1fd, 0x1e53,
+ 0xb1fe, 0x0467,
+ 0xb2a1, 0x0468,
+ 0xb2a6, 0x1e54,
+ 0xb2a8, 0x046f,
+ 0xb2ac, 0x1e56,
+ 0xb2ad, 0x0474,
+ 0xb2b5, 0x1e57,
+ 0xb2b6, 0x047d,
+ 0xb2b9, 0x1e58,
+ 0xb2ba, 0x0481,
+ 0xb2c6, 0x1e59,
+ 0xb2c7, 0x048e,
+ 0xb2ce, 0x1e5a,
+ 0xb2d8, 0x049f,
+ 0xb2de, 0x1e64,
+ 0xb2df, 0x04a6,
+ 0xb2e0, 0x1e65,
+ 0xb2e1, 0x04a8,
+ 0xb2e2, 0x1e66,
+ 0xb2e4, 0x04ab,
+ 0xb2ef, 0x1e68,
+ 0xb2f0, 0x04b7,
+ 0xb2f3, 0x1e69,
+ 0xb2fd, 0x04c4,
+ 0xb3a1, 0x1e73,
+ 0xb3a3, 0x04c8,
+ 0xb3a4, 0x1e75,
+ 0xb3a8, 0x04cd,
+ 0xb3a9, 0x1e79,
+ 0xb3aa, 0x04cf,
+ 0xb3ae, 0x1e7a,
+ 0xb3af, 0x04d4,
+ 0xb3b5, 0x1e7b,
+ 0xb3b6, 0x04db,
+ 0xb3b9, 0x1e7c,
+ 0xb3ba, 0x04df,
+ 0xb3be, 0x1e7d,
+ 0xb3bf, 0x04e4,
+ 0xb3c2, 0x1e7e,
+ 0xb3c3, 0x04e8,
+ 0xb3c4, 0x1e7f,
+ 0xb3c5, 0x04ea,
+ 0xb3c6, 0x1e80,
+ 0xb3c7, 0x04ec,
+ 0xb3cd, 0x1e81,
+ 0xb3ce, 0x04f3,
+ 0xb3cf, 0x1e82,
+ 0xb3d0, 0x04f5,
+ 0xb3d2, 0x1e83,
+ 0xb3d3, 0x04f8,
+ 0xb3d9, 0x1e84,
+ 0xb3da, 0x04ff,
+ 0xb3db, 0x1e85,
+ 0xb3dc, 0x0501,
+ 0xb3dd, 0x1e86,
+ 0xb3de, 0x0503,
+ 0xb3e3, 0x1e87,
+ 0xb3e4, 0x0509,
+ 0xb3e5, 0x1e88,
+ 0xb3e7, 0x050c,
+ 0xb3e8, 0x1e8a,
+ 0xb3e9, 0x050e,
+ 0xb3eb, 0x1e8b,
+ 0xb3ed, 0x0512,
+ 0xb3ef, 0x1e8d,
+ 0xb3f0, 0x0515,
+ 0xb3f1, 0x1e8e,
+ 0xb3f2, 0x0517,
+ 0xb3f3, 0x1e8f,
+ 0xb3f4, 0x0519,
+ 0xb3fa, 0x1e90,
+ 0xb3fc, 0x0521,
+ 0xb4a1, 0x1e92,
+ 0xb4a3, 0x0526,
+ 0xb4a5, 0x1e94,
+ 0xb4a7, 0x052a,
+ 0xb4ab, 0x1e96,
+ 0xb4ac, 0x052f,
+ 0xb4af, 0x1e97,
+ 0xb4b0, 0x0533,
+ 0xb4b3, 0x1e98,
+ 0xb4b5, 0x0538,
+ 0xb4b8, 0x1e9a,
+ 0xb4b9, 0x053c,
+ 0xb4bf, 0x1e9b,
+ 0xb4c0, 0x0543,
+ 0xb4c2, 0x1e9c,
+ 0xb4c3, 0x0546,
+ 0xb4c7, 0x1e9d,
+ 0xb4c8, 0x054b,
+ 0xb4ca, 0x1e9e,
+ 0xb4cb, 0x054e,
+ 0xb4cd, 0x1e9f,
+ 0xb4ce, 0x0551,
+ 0xb4cf, 0x1ea0,
+ 0xb4d0, 0x0553,
+ 0xb4d3, 0x1ea1,
+ 0xb4d5, 0x0558,
+ 0xb4da, 0x1ea3,
+ 0xb4db, 0x055e,
+ 0xb4dc, 0x1ea4,
+ 0xb4dd, 0x0560,
+ 0xb4ed, 0x1ea5,
+ 0xb4ee, 0x0571,
+ 0xb4ef, 0x1ea6,
+ 0xb4f0, 0x0573,
+ 0xb4f8, 0x1ea7,
+ 0xb4f9, 0x057c,
+ 0xb4fb, 0x1ea8,
+ 0xb4fc, 0x057f,
+ 0xb5a1, 0x0582,
+ 0xb5a3, 0x1ea9,
+ 0xb5a4, 0x0585,
+ 0xb5a5, 0x1eaa,
+ 0xb5a9, 0x058a,
+ 0xb5ac, 0x1eae,
+ 0xb5ad, 0x058e,
+ 0xb5ae, 0x1eaf,
+ 0xb5b0, 0x0591,
+ 0xb5b1, 0x1eb1,
+ 0xb5b6, 0x0597,
+ 0xb5b7, 0x1eb6,
+ 0xb5b8, 0x0599,
+ 0xb5ba, 0x1eb7,
+ 0xb5bd, 0x059e,
+ 0xb5c6, 0x1eba,
+ 0xb5c7, 0x05a8,
+ 0xb5cb, 0x1ebb,
+ 0xb5cc, 0x05ad,
+ 0xb5d0, 0x1ebc,
+ 0xb5d1, 0x05b2,
+ 0xb5d3, 0x1ebd,
+ 0xb5d4, 0x05b5,
+ 0xb5dd, 0x1ebe,
+ 0xb5e0, 0x05c1,
+ 0xb5e3, 0x1ec1,
+ 0xb5e4, 0x05c5,
+ 0xb5e6, 0x1ec2,
+ 0xb5e8, 0x05c9,
+ 0xb5ed, 0x1ec4,
+ 0xb5ee, 0x05cf,
+ 0xb5f6, 0x1ec5,
+ 0xb5f8, 0x05d9,
+ 0xb5fd, 0x1ec7,
+ 0xb5fe, 0x05df,
+ 0xb6a1, 0x05e0,
+ 0xb6a4, 0x1ec8,
+ 0xb6a6, 0x05e5,
+ 0xb6a7, 0x1eca,
+ 0xb6a8, 0x05e7,
+ 0xb6a9, 0x1ecb,
+ 0xb6aa, 0x05e9,
+ 0xb6ab, 0x1ecc,
+ 0xb6ac, 0x05eb,
+ 0xb6af, 0x1ecd,
+ 0xb6b1, 0x05f0,
+ 0xb6b3, 0x1ecf,
+ 0xb6b4, 0x05f3,
+ 0xb6b7, 0x1ed0,
+ 0xb6b8, 0x05f7,
+ 0xb6bf, 0x1ed1,
+ 0xb6c2, 0x0601,
+ 0xb6c4, 0x1ed4,
+ 0xb6c5, 0x0604,
+ 0xb6c6, 0x1ed5,
+ 0xb6c7, 0x0606,
+ 0xb6cd, 0x1ed6,
+ 0xb6ce, 0x060d,
+ 0xb6cf, 0x1ed7,
+ 0xb6d1, 0x0610,
+ 0xb6d3, 0x1ed9,
+ 0xb6d5, 0x0614,
+ 0xb6d6, 0x1edb,
+ 0xb6d7, 0x0616,
+ 0xb6d9, 0x1edc,
+ 0xb6da, 0x0619,
+ 0xb6db, 0x1edd,
+ 0xb6dc, 0x061b,
+ 0xb6e1, 0x1ede,
+ 0xb6e2, 0x0621,
+ 0xb6e9, 0x1edf,
+ 0xb6ea, 0x0629,
+ 0xb6ec, 0x1ee0,
+ 0xb6ed, 0x062c,
+ 0xb6ee, 0x1ee1,
+ 0xb6f0, 0x062f,
+ 0xb6f1, 0x1ee3,
+ 0xb6f2, 0x0631,
+ 0xb6f6, 0x1ee4,
+ 0xb6f7, 0x0636,
+ 0xb6f9, 0x1ee5,
+ 0xb6fa, 0x0639,
+ 0xb6fb, 0x1ee6,
+ 0xb6fd, 0x063c,
+ 0xb7a1, 0x1ee8,
+ 0xb7a4, 0x0641,
+ 0xb7a7, 0x1eeb,
+ 0xb7a8, 0x0645,
+ 0xb7af, 0x1eec,
+ 0xb7b1, 0x064e,
+ 0xb7b3, 0x1eee,
+ 0xb7b4, 0x0651,
+ 0xb7b6, 0x1eef,
+ 0xb7b8, 0x0655,
+ 0xb7b9, 0x1ef1,
+ 0xb7ba, 0x0657,
+ 0xb7c3, 0x1ef2,
+ 0xb7c5, 0x0662,
+ 0xb7c9, 0x1ef4,
+ 0xb7ca, 0x0667,
+ 0xb7cc, 0x1ef5,
+ 0xb7cd, 0x066a,
+ 0xb7cf, 0x1ef6,
+ 0xb7d0, 0x066d,
+ 0xb7d1, 0x1ef7,
+ 0xb7d2, 0x066f,
+ 0xb7d7, 0x1ef8,
+ 0xb7d9, 0x0676,
+ 0xb7dc, 0x1efa,
+ 0xb7dd, 0x067a,
+ 0xb7df, 0x1efb,
+ 0xb7e2, 0x067f,
+ 0xb7e3, 0x1efe,
+ 0xb7e4, 0x0681,
+ 0xb7e6, 0x1eff,
+ 0xb7e9, 0x0686,
+ 0xb7eb, 0x1f02,
+ 0xb7ee, 0x068b,
+ 0xb7ef, 0x1f05,
+ 0xb7f0, 0x068d,
+ 0xb7f4, 0x1f06,
+ 0xb7f5, 0x0692,
+ 0xb7f8, 0x1f07,
+ 0xb7f9, 0x0696,
+ 0xb8a1, 0x069c,
+ 0xb8a7, 0x1f08,
+ 0xb8a9, 0x06a4,
+ 0xb8b3, 0x1f0a,
+ 0xb8b5, 0x06b0,
+ 0xb8ba, 0x1f0c,
+ 0xb8bb, 0x06b6,
+ 0xb8bc, 0x1f0d,
+ 0xb8bd, 0x06b8,
+ 0xb8be, 0x1f0e,
+ 0xb8c0, 0x06bb,
+ 0xb8c3, 0x1f10,
+ 0xb8c4, 0x06bf,
+ 0xb8c6, 0x1f11,
+ 0xb8c8, 0x06c3,
+ 0xb8c9, 0x1f13,
+ 0xb8ca, 0x06c5,
+ 0xb8cf, 0x1f14,
+ 0xb8d0, 0x06cb,
+ 0xb8d3, 0x1f15,
+ 0xb8d7, 0x06d2,
+ 0xb8d9, 0x1f19,
+ 0xb8db, 0x06d6,
+ 0xb8e4, 0x1f1b,
+ 0xb8e5, 0x06e0,
+ 0xb8e9, 0x1f1c,
+ 0xb8ea, 0x06e5,
+ 0xb8eb, 0x1f1d,
+ 0xb8ec, 0x06e7,
+ 0xb8f3, 0x1f1e,
+ 0xb8f4, 0x06ef,
+ 0xb8f5, 0x1f1f,
+ 0xb8f7, 0x06f2,
+ 0xb8f8, 0x1f21,
+ 0xb8f9, 0x06f4,
+ 0xb9a1, 0x06fa,
+ 0xb9a8, 0x1f22,
+ 0xb9a9, 0x0702,
+ 0xb9ae, 0x1f23,
+ 0xb9af, 0x0708,
+ 0xb9b1, 0x1f24,
+ 0xb9b2, 0x070b,
+ 0xb9b3, 0x1f25,
+ 0xb9b4, 0x070d,
+ 0xb9b5, 0x1f26,
+ 0xb9b6, 0x070f,
+ 0xb9b9, 0x1f27,
+ 0xb9bb, 0x0714,
+ 0xb9c6, 0x1f29,
+ 0xb9c7, 0x0720,
+ 0xb9cb, 0x1f2a,
+ 0xb9cc, 0x0725,
+ 0xb9d0, 0x1f2b,
+ 0xb9d1, 0x072a,
+ 0xb9d8, 0x1f2c,
+ 0xb9d9, 0x0732,
+ 0xb9db, 0x1f2d,
+ 0xb9dc, 0x0735,
+ 0xb9dd, 0x1f2e,
+ 0xb9de, 0x0737,
+ 0xb9df, 0x1f2f,
+ 0xb9e0, 0x0739,
+ 0xb9e1, 0x1f30,
+ 0xb9e2, 0x073b,
+ 0xb9e3, 0x1f31,
+ 0xb9e4, 0x073d,
+ 0xb9e6, 0x1f32,
+ 0xb9e7, 0x0740,
+ 0xb9e9, 0x1f33,
+ 0xb9ed, 0x0746,
+ 0xb9ee, 0x1f37,
+ 0xb9ef, 0x0748,
+ 0xb9f1, 0x1f38,
+ 0xb9f2, 0x074b,
+ 0xb9f3, 0x1f39,
+ 0xb9f6, 0x074f,
+ 0xb9f8, 0x1f3c,
+ 0xb9f9, 0x0752,
+ 0xb9fa, 0x1f3d,
+ 0xb9fb, 0x0754,
+ 0xb9fd, 0x1f3e,
+ 0xb9fe, 0x0757,
+ 0xbaa1, 0x0758,
+ 0xbaa7, 0x1f3f,
+ 0xbaa8, 0x075f,
+ 0xbaab, 0x1f40,
+ 0xbaac, 0x0763,
+ 0xbaba, 0x1f41,
+ 0xbabb, 0x0772,
+ 0xbac5, 0x1f42,
+ 0xbac6, 0x077d,
+ 0xbad2, 0x1f43,
+ 0xbad3, 0x078a,
+ 0xbad7, 0x1f44,
+ 0xbad9, 0x0790,
+ 0xbae4, 0x1f46,
+ 0xbae5, 0x079c,
+ 0xbae8, 0x1f47,
+ 0xbae9, 0x07a0,
+ 0xbaec, 0x1f48,
+ 0xbaed, 0x07a4,
+ 0xbaf3, 0x15e5,
+ 0xbaf4, 0x07ab,
+ 0xbaf8, 0x1f49,
+ 0xbaf9, 0x07b0,
+ 0xbba1, 0x07b6,
+ 0xbba4, 0x1f4a,
+ 0xbba5, 0x07ba,
+ 0xbba6, 0x1f4b,
+ 0xbba7, 0x07bc,
+ 0xbba9, 0x1f4c,
+ 0xbbab, 0x07c0,
+ 0xbbad, 0x1f4e,
+ 0xbbaf, 0x07c4,
+ 0xbbb0, 0x1f50,
+ 0xbbb1, 0x07c6,
+ 0xbbb3, 0x1f51,
+ 0xbbb4, 0x07c9,
+ 0xbbb5, 0x1f52,
+ 0xbbb8, 0x07cd,
+ 0xbbb9, 0x1f55,
+ 0xbbbb, 0x07d0,
+ 0xbbd1, 0x1f57,
+ 0xbbd2, 0x07e7,
+ 0xbbd3, 0x1f58,
+ 0xbbd5, 0x07ea,
+ 0xbbdf, 0x1f5a,
+ 0xbbe8, 0x07fd,
+ 0xbbeb, 0x1f63,
+ 0xbbec, 0x0801,
+ 0xbbf1, 0x1f64,
+ 0xbbf2, 0x0807,
+ 0xbbf5, 0x1f65,
+ 0xbbf8, 0x080d,
+ 0xbbfa, 0x1f68,
+ 0xbbfb, 0x0810,
+ 0xbbfd, 0x1f69,
+ 0xbbfe, 0x0813,
+ 0xbca1, 0x0814,
+ 0xbca2, 0x1f6a,
+ 0xbca3, 0x0816,
+ 0xbca5, 0x1f6b,
+ 0xbca7, 0x081a,
+ 0xbca8, 0x1f6d,
+ 0xbcaa, 0x081d,
+ 0xbcab, 0x1f6f,
+ 0xbcac, 0x081f,
+ 0xbcad, 0x1f70,
+ 0xbcae, 0x0821,
+ 0xbcb6, 0x1f71,
+ 0xbcb9, 0x082c,
+ 0xbcbb, 0x1f74,
+ 0xbcbc, 0x082f,
+ 0xbcc1, 0x1f75,
+ 0xbcc2, 0x0835,
+ 0xbcc3, 0x1f76,
+ 0xbcc4, 0x0837,
+ 0xbcc6, 0x1f77,
+ 0xbcc8, 0x083b,
+ 0xbcca, 0x1f79,
+ 0xbccb, 0x083e,
+ 0xbccc, 0x1f7a,
+ 0xbcce, 0x0841,
+ 0xbcd0, 0x1f7c,
+ 0xbcd1, 0x0844,
+ 0xbcd4, 0x1f7d,
+ 0xbcd7, 0x084a,
+ 0xbcd8, 0x1f80,
+ 0xbcd9, 0x084c,
+ 0xbcdb, 0x1f81,
+ 0xbcdc, 0x084f,
+ 0xbcdd, 0x1f82,
+ 0xbcde, 0x0851,
+ 0xbcdf, 0x1f83,
+ 0xbce2, 0x0855,
+ 0xbce3, 0x1f86,
+ 0xbce5, 0x0858,
+ 0xbce8, 0x1f88,
+ 0xbce9, 0x085c,
+ 0xbcea, 0x1f89,
+ 0xbced, 0x0860,
+ 0xbcef, 0x1f8c,
+ 0xbcf4, 0x0867,
+ 0xbcf6, 0x1f91,
+ 0xbcfd, 0x0870,
+ 0xbda1, 0x0872,
+ 0xbda2, 0x1f98,
+ 0xbda8, 0x0879,
+ 0xbdab, 0x1f9e,
+ 0xbdad, 0x087e,
+ 0xbdaf, 0x1fa0,
+ 0xbdb3, 0x0884,
+ 0xbdb4, 0x1fa4,
+ 0xbdb5, 0x0886,
+ 0xbdba, 0x1fa5,
+ 0xbdbb, 0x088c,
+ 0xbdbd, 0x1fa6,
+ 0xbdc0, 0x0891,
+ 0xbdc1, 0x1fa9,
+ 0xbdc5, 0x0896,
+ 0xbdc8, 0x1fad,
+ 0xbdcb, 0x089c,
+ 0xbdce, 0x1fb0,
+ 0xbdd0, 0x08a1,
+ 0xbdd7, 0x1fb2,
+ 0xbdd8, 0x08a9,
+ 0xbdda, 0x1fb3,
+ 0xbddb, 0x08ac,
+ 0xbde0, 0x1fb4,
+ 0xbde2, 0x08b3,
+ 0xbdeb, 0x1fb6,
+ 0xbdec, 0x08bd,
+ 0xbdf4, 0x1fb7,
+ 0xbdf9, 0x08ca,
+ 0xbdfd, 0x1fbc,
+ 0xbdfe, 0x08cf,
+ 0xbea1, 0x1fbd,
+ 0xbea3, 0x08d2,
+ 0xbea5, 0x1fbf,
+ 0xbea6, 0x08d5,
+ 0xbea8, 0x1fc0,
+ 0xbea9, 0x08d8,
+ 0xbeaa, 0x1fc1,
+ 0xbeab, 0x08da,
+ 0xbead, 0x1fc2,
+ 0xbeae, 0x08dd,
+ 0xbeb1, 0x1fc3,
+ 0xbeb2, 0x08e1,
+ 0xbeb5, 0x1fc4,
+ 0xbeb8, 0x08e7,
+ 0xbeba, 0x1fc7,
+ 0xbebb, 0x08ea,
+ 0xbec0, 0x1fc8,
+ 0xbec1, 0x08f0,
+ 0xbec9, 0x1fc9,
+ 0xbeca, 0x08f9,
+ 0xbed4, 0x1fca,
+ 0xbed5, 0x0904,
+ 0xbed9, 0x1fcb,
+ 0xbeda, 0x0909,
+ 0xbedd, 0x1fcc,
+ 0xbede, 0x090d,
+ 0xbee2, 0x1fcd,
+ 0xbee3, 0x0912,
+ 0xbee5, 0x1fce,
+ 0xbee6, 0x0915,
+ 0xbee7, 0x1fcf,
+ 0xbee8, 0x0917,
+ 0xbee9, 0x1fd0,
+ 0xbeea, 0x0919,
+ 0xbeee, 0x1fd1,
+ 0xbeef, 0x091e,
+ 0xbef5, 0x1fd2,
+ 0xbef6, 0x0925,
+ 0xbef7, 0x1fd3,
+ 0xbef9, 0x0928,
+ 0xbefb, 0x1fd5,
+ 0xbefd, 0x092c,
+ 0xbfa1, 0x092e,
+ 0xbfa5, 0x1fd7,
+ 0xbfa6, 0x0933,
+ 0xbfaa, 0x1fd8,
+ 0xbfab, 0x0938,
+ 0xbfad, 0x1fd9,
+ 0xbfae, 0x093b,
+ 0xbfc5, 0x1fda,
+ 0xbfc6, 0x0953,
+ 0xbfc7, 0x1fdb,
+ 0xbfc8, 0x0955,
+ 0xbfce, 0x1fdc,
+ 0xbfcf, 0x095c,
+ 0xbfd1, 0x1fdd,
+ 0xbfd3, 0x0960,
+ 0xbfd9, 0x1fdf,
+ 0xbfda, 0x0967,
+ 0xbfe2, 0x1fe0,
+ 0xbfe5, 0x0972,
+ 0xbfe9, 0x1fe3,
+ 0xbfea, 0x0977,
+ 0xbfeb, 0x1fe4,
+ 0xbfec, 0x0979,
+ 0xbfed, 0x1fe5,
+ 0xbfee, 0x097b,
+ 0xbff3, 0x1fe6,
+ 0xbff4, 0x0981,
+ 0xbff5, 0x1fe7,
+ 0xbff6, 0x0983,
+ 0xbff7, 0x1fe8,
+ 0xbff8, 0x0985,
+ 0xbff9, 0x1fe9,
+ 0xbffb, 0x0988,
+ 0xc0a1, 0x1feb,
+ 0xc0a2, 0x098d,
+ 0xc0a3, 0x1fec,
+ 0xc0a4, 0x098f,
+ 0xc0a9, 0x1fed,
+ 0xc0aa, 0x0995,
+ 0xc0ab, 0x1fee,
+ 0xc0ac, 0x0997,
+ 0xc0af, 0x1fef,
+ 0xc0b1, 0x099c,
+ 0xc0b3, 0x1ff1,
+ 0xc0b7, 0x09a2,
+ 0xc0b8, 0x1ff5,
+ 0xc0c5, 0x09b0,
+ 0xc0cc, 0x2002,
+ 0xc0ce, 0x09b9,
+ 0xc0d4, 0x2004,
+ 0xc0d5, 0x09c0,
+ 0xc0d6, 0x2005,
+ 0xc0d7, 0x09c2,
+ 0xc0d8, 0x2006,
+ 0xc0d9, 0x09c4,
+ 0xc0dd, 0x2007,
+ 0xc0de, 0x09c9,
+ 0xc0e0, 0x2008,
+ 0xc0e1, 0x09cc,
+ 0xc0e9, 0x2009,
+ 0xc0ea, 0x09d5,
+ 0xc0eb, 0x200a,
+ 0xc0ed, 0x09d8,
+ 0xc0ef, 0x200c,
+ 0xc0f2, 0x09dd,
+ 0xc0f6, 0x200f,
+ 0xc0fb, 0x09e6,
+ 0xc1a1, 0x09ea,
+ 0xc1a4, 0x2014,
+ 0xc1a6, 0x09ef,
+ 0xc1a9, 0x2016,
+ 0xc1ae, 0x09f7,
+ 0xc1af, 0x201b,
+ 0xc1b9, 0x0a02,
+ 0xc1bd, 0x2025,
+ 0xc1bf, 0x0a08,
+ 0xc1c2, 0x2027,
+ 0xc1c3, 0x0a0c,
+ 0xc1c6, 0x2028,
+ 0xc1c7, 0x0a10,
+ 0xc1c9, 0x2029,
+ 0xc1ca, 0x0a13,
+ 0xc1cd, 0x202a,
+ 0xc1ce, 0x0a17,
+ 0xc1d4, 0x202b,
+ 0xc1d5, 0x0a1e,
+ 0xc1d9, 0x202c,
+ 0xc1dc, 0x0a25,
+ 0xc1de, 0x202f,
+ 0xc1df, 0x0a28,
+ 0xc1e4, 0x2030,
+ 0xc1e6, 0x0a2f,
+ 0xc1e9, 0x2032,
+ 0xc1ea, 0x0a33,
+ 0xc1eb, 0x2033,
+ 0xc1ed, 0x0a36,
+ 0xc1f3, 0x2035,
+ 0xc1f4, 0x0a3d,
+ 0xc1f5, 0x2036,
+ 0xc1f6, 0x0a3f,
+ 0xc1fa, 0x2037,
+ 0xc1fe, 0x0a47,
+ 0xc2a1, 0x0a48,
+ 0xc2a2, 0x203b,
+ 0xc2a9, 0x0a50,
+ 0xc2ab, 0x2042,
+ 0xc2b4, 0x0a5b,
+ 0xc2b8, 0x204b,
+ 0xc2b9, 0x0a60,
+ 0xc2bc, 0x204c,
+ 0xc2be, 0x0a65,
+ 0xc2bf, 0x204e,
+ 0xc2c0, 0x0a67,
+ 0xc2c1, 0x204f,
+ 0xc2c2, 0x0a69,
+ 0xc2c5, 0x2050,
+ 0xc2c8, 0x0a6f,
+ 0xc2cb, 0x2053,
+ 0xc2d1, 0x0a78,
+ 0xc2d2, 0x2059,
+ 0xc2d3, 0x0a7a,
+ 0xc2d5, 0x205a,
+ 0xc2dd, 0x0a84,
+ 0xc2de, 0x2062,
+ 0xc2e3, 0x0a8a,
+ 0xc2e6, 0x2067,
+ 0xc2e9, 0x0a90,
+ 0xc2ea, 0x206a,
+ 0xc2ef, 0x0a96,
+ 0xc2f0, 0x206f,
+ 0xc2f1, 0x0a98,
+ 0xc2f2, 0x2070,
+ 0xc2f6, 0x0a9d,
+ 0xc2f7, 0x2074,
+ 0xc2fb, 0x0aa2,
+ 0xc3a1, 0x2078,
+ 0xc3a2, 0x0aa7,
+ 0xc3aa, 0x2079,
+ 0xc3ab, 0x0ab0,
+ 0xc3ad, 0x207a,
+ 0xc3ae, 0x0ab3,
+ 0xc3b3, 0x207b,
+ 0xc3b4, 0x1df9,
+ 0xc3b5, 0x0aba,
+ 0xc3be, 0x207c,
+ 0xc3bf, 0x0ac4,
+ 0xc3c5, 0x207d,
+ 0xc3c8, 0x0acd,
+ 0xc3cc, 0x2080,
+ 0xc3cd, 0x0ad2,
+ 0xc3ce, 0x2081,
+ 0xc3cf, 0x0ad4,
+ 0xc3d5, 0x2082,
+ 0xc3d7, 0x0adc,
+ 0xc3d9, 0x2084,
+ 0xc3da, 0x0adf,
+ 0xc3e0, 0x2085,
+ 0xc3e1, 0x0ae6,
+ 0xc3e5, 0x2086,
+ 0xc3e6, 0x0aeb,
+ 0xc3ed, 0x2087,
+ 0xc3ee, 0x0af3,
+ 0xc3f0, 0x2088,
+ 0xc3f1, 0x0af6,
+ 0xc3f5, 0x2089,
+ 0xc3f7, 0x0afc,
+ 0xc3f9, 0x208b,
+ 0xc3fb, 0x0b00,
+ 0xc3fd, 0x208d,
+ 0xc3fe, 0x0b03,
+ 0xc4a1, 0x0b04,
+ 0xc4b1, 0x208e,
+ 0xc4b2, 0x0b15,
+ 0xc4b6, 0x208f,
+ 0xc4b7, 0x0b1a,
+ 0xc4c6, 0x2090,
+ 0xc4c7, 0x0b2a,
+ 0xc4c9, 0x2091,
+ 0xc4ca, 0x0b2d,
+ 0xc4d1, 0x2092,
+ 0xc4d2, 0x0b35,
+ 0xc4d3, 0x2093,
+ 0xc4d7, 0x0b3a,
+ 0xc4d9, 0x2097,
+ 0xc4da, 0x0b3d,
+ 0xc4e2, 0x2098,
+ 0xc4e3, 0x0b46,
+ 0xc4e5, 0x2099,
+ 0xc4e6, 0x0b49,
+ 0xc4ec, 0x209a,
+ 0xc4ed, 0x0b50,
+ 0xc4f0, 0x209b,
+ 0xc4f2, 0x0b55,
+ 0xc4f4, 0x209d,
+ 0xc4f5, 0x0b58,
+ 0xc4f6, 0x209e,
+ 0xc4f9, 0x0b5c,
+ 0xc4fb, 0x20a1,
+ 0xc4fd, 0x0b60,
+ 0xc4fe, 0x20a3,
+ 0xc5a1, 0x20a4,
+ 0xc5a3, 0x0b64,
+ 0xc5a5, 0x20a6,
+ 0xc5aa, 0x0b6b,
+ 0xc5b1, 0x20ab,
+ 0xc5b2, 0x0b73,
+ 0xc5b5, 0x20ac,
+ 0xc5b6, 0x0b77,
+ 0xc5b7, 0x20ad,
+ 0xc5ba, 0x0b7b,
+ 0xc5bb, 0x20b0,
+ 0xc5bc, 0x0b7d,
+ 0xc5bd, 0x20b1,
+ 0xc5be, 0x0b7f,
+ 0xc5cc, 0x20b2,
+ 0xc5cd, 0x0b8e,
+ 0xc5d3, 0x20b3,
+ 0xc5d4, 0x0b95,
+ 0xc5e2, 0x20b4,
+ 0xc5e3, 0x0ba4,
+ 0xc5e7, 0x20b5,
+ 0xc5e8, 0x0ba9,
+ 0xc5f4, 0x20b6,
+ 0xc5f5, 0x0bb6,
+ 0xc6a1, 0x0bc0,
+ 0xc6ad, 0x20b7,
+ 0xc6af, 0x0bce,
+ 0xc6b5, 0x20b9,
+ 0xc6b7, 0x0bd6,
+ 0xc6bb, 0x20bb,
+ 0xc6bc, 0x0bdb,
+ 0xc6be, 0x20bc,
+ 0xc6bf, 0x0bde,
+ 0xc6c0, 0x20bd,
+ 0xc6c1, 0x0be0,
+ 0xc6c3, 0x20be,
+ 0xc6c5, 0x0be4,
+ 0xc6cb, 0x20c0,
+ 0xc6ce, 0x0bed,
+ 0xc6d3, 0x20c3,
+ 0xc6d4, 0x0bf3,
+ 0xc6d7, 0x20c4,
+ 0xc6d8, 0x0bf7,
+ 0xc6ea, 0x20c5,
+ 0xc6ec, 0x0c0b,
+ 0xc6ef, 0x20c7,
+ 0xc6f0, 0x0c0f,
+ 0xc6f1, 0x20c8,
+ 0xc6f2, 0x0c11,
+ 0xc6f4, 0x20c9,
+ 0xc6f5, 0x0c14,
+ 0xc6f8, 0x20ca,
+ 0xc6f9, 0x0c18,
+ 0xc6fd, 0x20cb,
+ 0xc6fe, 0x0c1d,
+ 0xc7a1, 0x0c1e,
+ 0xc7a3, 0x20cc,
+ 0xc7a4, 0x0c21,
+ 0xc7a5, 0x20cd,
+ 0xc7a7, 0x0c24,
+ 0xc7a8, 0x20cf,
+ 0xc7aa, 0x0c27,
+ 0xc7ab, 0x20d1,
+ 0xc7ac, 0x0c29,
+ 0xc7ae, 0x20d2,
+ 0xc7b0, 0x0c2d,
+ 0xc7b3, 0x20d4,
+ 0xc7b6, 0x0c33,
+ 0xc7b9, 0x20d7,
+ 0xc7bb, 0x0c38,
+ 0xc7bd, 0x20d9,
+ 0xc7bf, 0x0c3c,
+ 0xc7c0, 0x20db,
+ 0xc7c1, 0x0c3e,
+ 0xc7c2, 0x20dc,
+ 0xc7c3, 0x0c40,
+ 0xc7c5, 0x20dd,
+ 0xc7c6, 0x0c43,
+ 0xc7c7, 0x20de,
+ 0xc7c9, 0x0c46,
+ 0xc7cc, 0x20e0,
+ 0xc7cd, 0x0c4a,
+ 0xc7cf, 0x20e1,
+ 0xc7d0, 0x0c4d,
+ 0xc7d4, 0x20e2,
+ 0xc7d6, 0x0c53,
+ 0xc7d7, 0x20e4,
+ 0xc7d8, 0x0c55,
+ 0xc7de, 0x20e5,
+ 0xc7df, 0x0c5c,
+ 0xc7e1, 0x20e6,
+ 0xc7e4, 0x0c61,
+ 0xc7ea, 0x20e9,
+ 0xc7ef, 0x0c6c,
+ 0xc7f7, 0x20ee,
+ 0xc7f9, 0x0c76,
+ 0xc7fb, 0x20f0,
+ 0xc7fc, 0x0c79,
+ 0xc7fd, 0x20f1,
+ 0xc7fe, 0x0c7b,
+ 0xc8a1, 0x0c7c,
+ 0xc8a3, 0x20f2,
+ 0xc8a4, 0x0c7f,
+ 0xc8a7, 0x20f3,
+ 0xc8a9, 0x0c84,
+ 0xc8b0, 0x20f5,
+ 0xc8b1, 0x0c8c,
+ 0xc8b5, 0x20f6,
+ 0xc8b6, 0x0c91,
+ 0xc8b7, 0x20f7,
+ 0xc8b8, 0x0c93,
+ 0xc8c3, 0x20f8,
+ 0xc8c7, 0x0ca2,
+ 0xc8c8, 0x20fc,
+ 0xc8c9, 0x0ca4,
+ 0xc8cd, 0x20fd,
+ 0xc8ce, 0x0ca9,
+ 0xc8cf, 0x20fe,
+ 0xc8d0, 0x0cab,
+ 0xc8d2, 0x20ff,
+ 0xc8d3, 0x0cae,
+ 0xc8d9, 0x2100,
+ 0xc8da, 0x0cb5,
+ 0xc8de, 0x2101,
+ 0xc8df, 0x0cba,
+ 0xc8ed, 0x2102,
+ 0xc8ee, 0x0cc9,
+ 0xc8f1, 0x2103,
+ 0xc8f4, 0x0ccf,
+ 0xc8f7, 0x2106,
+ 0xc8f9, 0x0cd4,
+ 0xc8fa, 0x2108,
+ 0xc8fb, 0x0cd6,
+ 0xc8fc, 0x2109,
+ 0xc8fd, 0x0cd8,
+ 0xc9a1, 0x210a,
+ 0xc9a2, 0x0cdb,
+ 0xc9a5, 0x210b,
+ 0xc9a6, 0x0cdf,
+ 0xc9a7, 0x210c,
+ 0xc9a9, 0x0ce2,
+ 0xc9ac, 0x210e,
+ 0xc9ad, 0x0ce6,
+ 0xc9b1, 0x210f,
+ 0xc9b2, 0x0ceb,
+ 0xc9b4, 0x2110,
+ 0xc9b5, 0x0cee,
+ 0xc9b8, 0x2111,
+ 0xc9ba, 0x0cf3,
+ 0xc9c1, 0x2113,
+ 0xc9c3, 0x0cfc,
+ 0xc9c4, 0x2115,
+ 0xc9c5, 0x0cfe,
+ 0xc9c9, 0x2116,
+ 0xc9ca, 0x0d03,
+ 0xc9cb, 0x2117,
+ 0xc9cc, 0x0d05,
+ 0xc9cd, 0x2118,
+ 0xc9ce, 0x0d07,
+ 0xc9d5, 0x2119,
+ 0xc9d6, 0x0d0f,
+ 0xc9dc, 0x211a,
+ 0xc9dd, 0x0d16,
+ 0xc9de, 0x211b,
+ 0xc9df, 0x0d18,
+ 0xc9e1, 0x211c,
+ 0xc9e2, 0x0d1b,
+ 0xc9e3, 0x211d,
+ 0xc9e4, 0x0d1d,
+ 0xc9e5, 0x211e,
+ 0xc9e6, 0x0d1f,
+ 0xc9e8, 0x211f,
+ 0xc9e9, 0x0d22,
+ 0xc9f0, 0x2120,
+ 0xc9f1, 0x0d2a,
+ 0xc9f3, 0x2121,
+ 0xc9f5, 0x0d2e,
+ 0xc9f6, 0x2123,
+ 0xc9f7, 0x0d30,
+ 0xc9f8, 0x2124,
+ 0xc9fa, 0x0d33,
+ 0xc9fe, 0x2126,
+ 0xcaa1, 0x0d38,
+ 0xcaa4, 0x2127,
+ 0xcaa7, 0x0d3e,
+ 0xcaa8, 0x212a,
+ 0xcaa9, 0x0d40,
+ 0xcaaa, 0x212b,
+ 0xcaac, 0x0d43,
+ 0xcab1, 0x212d,
+ 0xcab2, 0x0d49,
+ 0xcab4, 0x212e,
+ 0xcab7, 0x0d4e,
+ 0xcabb, 0x2131,
+ 0xcabc, 0x0d53,
+ 0xcac6, 0x2132,
+ 0xcac7, 0x0d5e,
+ 0xcaca, 0x2133,
+ 0xcacb, 0x0d62,
+ 0xcacd, 0x2134,
+ 0xcacf, 0x0d66,
+ 0xcad3, 0x2136,
+ 0xcad5, 0x0d6c,
+ 0xcad9, 0x2138,
+ 0xcada, 0x0d71,
+ 0xcade, 0x2139,
+ 0xcadf, 0x0d76,
+ 0xcae0, 0x213a,
+ 0xcae1, 0x0d78,
+ 0xcae4, 0x213b,
+ 0xcae5, 0x0d7c,
+ 0xcae9, 0x213c,
+ 0xcaeb, 0x0d82,
+ 0xcaf4, 0x213e,
+ 0xcaf6, 0x0d8d,
+ 0xcaf7, 0x2140,
+ 0xcaf8, 0x0d8f,
+ 0xcafa, 0x2141,
+ 0xcafb, 0x0d92,
+ 0xcafd, 0x2142,
+ 0xcafe, 0x0d95,
+ 0xcba1, 0x0d96,
+ 0xcba7, 0x2143,
+ 0xcba8, 0x0d9d,
+ 0xcbab, 0x2144,
+ 0xcbac, 0x0da1,
+ 0xcbad, 0x2145,
+ 0xcbae, 0x0da3,
+ 0xcbb3, 0x2146,
+ 0xcbb4, 0x0da9,
+ 0xcbb5, 0x2147,
+ 0xcbb7, 0x0dac,
+ 0xcbb8, 0x2149,
+ 0xcbb9, 0x0dae,
+ 0xcbbf, 0x214a,
+ 0xcbc0, 0x0db5,
+ 0xcbc7, 0x214b,
+ 0xcbc8, 0x0dbd,
+ 0xcbc9, 0x214c,
+ 0xcbcd, 0x0dc2,
+ 0xcbcf, 0x2150,
+ 0xcbd1, 0x0dc6,
+ 0xcbd3, 0x2152,
+ 0xcbd4, 0x0dc9,
+ 0xcbd5, 0x2153,
+ 0xcbd6, 0x0dcb,
+ 0xcbdf, 0x2154,
+ 0xcbe1, 0x0dd6,
+ 0xcbe4, 0x2156,
+ 0xcbe5, 0x0dda,
+ 0xcbe6, 0x2157,
+ 0xcbe8, 0x0ddd,
+ 0xcbea, 0x2159,
+ 0xcbeb, 0x0de0,
+ 0xcbef, 0x215a,
+ 0xcbf1, 0x0de6,
+ 0xcbf5, 0x215c,
+ 0xcbf7, 0x0dec,
+ 0xcbf8, 0x215e,
+ 0xcbf9, 0x0dee,
+ 0xcca1, 0x215f,
+ 0xcca3, 0x0df6,
+ 0xcca8, 0x2161,
+ 0xcca9, 0x0dfc,
+ 0xccac, 0x2162,
+ 0xccad, 0x0e00,
+ 0xccaf, 0x2163,
+ 0xccb4, 0x0e07,
+ 0xccb7, 0x2168,
+ 0xccb9, 0x0e0c,
+ 0xccbe, 0x216a,
+ 0xccbf, 0x0e12,
+ 0xccc0, 0x216b,
+ 0xccc1, 0x0e14,
+ 0xcccc, 0x216c,
+ 0xcccd, 0x0e20,
+ 0xccce, 0x216d,
+ 0xcccf, 0x0e22,
+ 0xccd0, 0x216e,
+ 0xccd1, 0x0e24,
+ 0xccd6, 0x216f,
+ 0xccd7, 0x0e2a,
+ 0xccda, 0x2170,
+ 0xccdb, 0x0e2e,
+ 0xccdc, 0x2171,
+ 0xccdd, 0x0e30,
+ 0xcce0, 0x2172,
+ 0xcce1, 0x0e34,
+ 0xcce2, 0x2173,
+ 0xcce3, 0x0e36,
+ 0xcce5, 0x2174,
+ 0xcce6, 0x0e39,
+ 0xccf5, 0x2175,
+ 0xccf6, 0x0e49,
+ 0xccf9, 0x2176,
+ 0xccfb, 0x0e4e,
+ 0xccfc, 0x2178,
+ 0xcda1, 0x0e52,
+ 0xcdad, 0x217b,
+ 0xcdae, 0x0e5f,
+ 0xcdb3, 0x217c,
+ 0xcdb4, 0x0e65,
+ 0xcdb7, 0x217d,
+ 0xcdb8, 0x0e69,
+ 0xcdbc, 0x217e,
+ 0xcdbd, 0x0e6e,
+ 0xcdbf, 0x217f,
+ 0xcdc0, 0x0e71,
+ 0xcdc5, 0x2180,
+ 0xcdc6, 0x0e77,
+ 0xcdc7, 0x2181,
+ 0xcdc8, 0x0e79,
+ 0xcdd2, 0x2182,
+ 0xcdd3, 0x0e84,
+ 0xcdd4, 0x2183,
+ 0xcdd7, 0x0e88,
+ 0xcddd, 0x2186,
+ 0xcdde, 0x0e8f,
+ 0xcde0, 0x2187,
+ 0xcde1, 0x0e92,
+ 0xcde4, 0x2188,
+ 0xcde6, 0x0e97,
+ 0xcde7, 0x218a,
+ 0xcde8, 0x0e99,
+ 0xcdf2, 0x218b,
+ 0xcdf3, 0x0ea4,
+ 0xcdf8, 0x218c,
+ 0xcdf9, 0x0eaa,
+ 0xcea1, 0x0eb0,
+ 0xcea4, 0x218d,
+ 0xcea6, 0x0eb5,
+ 0xcea7, 0x218f,
+ 0xcea8, 0x0eb7,
+ 0xceaa, 0x2190,
+ 0xceae, 0x0ebd,
+ 0xceb0, 0x2194,
+ 0xceb2, 0x0ec1,
+ 0xceb3, 0x2196,
+ 0xceb4, 0x0ec3,
+ 0xcebd, 0x2197,
+ 0xcebe, 0x0ecd,
+ 0xcec0, 0x2198,
+ 0xcec1, 0x0ed0,
+ 0xcec5, 0x2199,
+ 0xcec7, 0x0ed6,
+ 0xcec8, 0x219b,
+ 0xcec9, 0x0ed8,
+ 0xceca, 0x219c,
+ 0xcecb, 0x0eda,
+ 0xcece, 0x219d,
+ 0xced2, 0x0ee1,
+ 0xced8, 0x21a1,
+ 0xcedb, 0x0eea,
+ 0xcedc, 0x21a4,
+ 0xcedd, 0x0eec,
+ 0xcede, 0x21a5,
+ 0xcee0, 0x0eef,
+ 0xceeb, 0x21a7,
+ 0xceec, 0x0efb,
+ 0xceed, 0x21a8,
+ 0xceee, 0x0efd,
+ 0xcef1, 0x21a9,
+ 0xcef2, 0x0f01,
+ 0xcef3, 0x21aa,
+ 0xcef4, 0x0f03,
+ 0xcefd, 0x21ab,
+ 0xcfa1, 0x0f0e,
+ 0xcfae, 0x21ad,
+ 0xcfaf, 0x0f1c,
+ 0xcfb0, 0x21ae,
+ 0xcfb1, 0x0f1e,
+ 0xcfb3, 0x21af,
+ 0xcfb4, 0x0f21,
+ 0xcfb7, 0x21b0,
+ 0xcfb9, 0x0f26,
+ 0xcfba, 0x21b2,
+ 0xcfbb, 0x0f28,
+ 0xcfbd, 0x21b3,
+ 0xcfbe, 0x0f2b,
+ 0xcfbf, 0x21b4,
+ 0xcfc2, 0x0f2f,
+ 0xcfc5, 0x21b7,
+ 0xcfc6, 0x0f33,
+ 0xcfc7, 0x21b8,
+ 0xcfc8, 0x0f35,
+ 0xcfca, 0x21b9,
+ 0xcfcc, 0x0f39,
+ 0xcfcd, 0x21bb,
+ 0xcfcf, 0x0f3c,
+ 0xcfd0, 0x21bd,
+ 0xcfd1, 0x0f3e,
+ 0xcfd4, 0x21be,
+ 0xcfd9, 0x0f46,
+ 0xcfda, 0x21c3,
+ 0xcfdb, 0x0f48,
+ 0xcfdc, 0x21c4,
+ 0xcfdd, 0x0f4a,
+ 0xcfdf, 0x21c5,
+ 0xcfe0, 0x0f4d,
+ 0xcfe2, 0x21c6,
+ 0xcfe3, 0x0f50,
+ 0xcfe7, 0x21c7,
+ 0xcfe8, 0x0f55,
+ 0xcfea, 0x21c8,
+ 0xcfeb, 0x0f58,
+ 0xcfec, 0x21c9,
+ 0xcfed, 0x0f5a,
+ 0xcfee, 0x21ca,
+ 0xcfef, 0x0f5c,
+ 0xcff4, 0x21cb,
+ 0xcff5, 0x0f62,
+ 0xcff9, 0x21cc,
+ 0xcffb, 0x0f68,
+ 0xcffe, 0x21ce,
+ 0xd0a1, 0x0f6c,
+ 0xd0a5, 0x21cf,
+ 0xd0a6, 0x0f71,
+ 0xd0ad, 0x21d0,
+ 0xd0af, 0x0f7a,
+ 0xd0b2, 0x21d2,
+ 0xd0b5, 0x0f80,
+ 0xd0ba, 0x21d5,
+ 0xd0bc, 0x0f87,
+ 0xd0bf, 0x21d7,
+ 0xd0c0, 0x0f8b,
+ 0xd0c6, 0x21d8,
+ 0xd0c7, 0x0f92,
+ 0xd0cb, 0x21d9,
+ 0xd0cc, 0x0f97,
+ 0xd0e2, 0x21da,
+ 0xd0e3, 0x0fae,
+ 0xd0e5, 0x21db,
+ 0xd0e6, 0x0fb1,
+ 0xd0eb, 0x21dc,
+ 0xd0ec, 0x0fb7,
+ 0xd0ed, 0x21dd,
+ 0xd0ee, 0x0fb9,
+ 0xd0f7, 0x21de,
+ 0xd0fa, 0x0fc5,
+ 0xd0fc, 0x21e1,
+ 0xd0fd, 0x0fc8,
+ 0xd1a1, 0x21e2,
+ 0xd1a3, 0x0fcc,
+ 0xd1a4, 0x21e4,
+ 0xd1a5, 0x0fce,
+ 0xd1a7, 0x21e5,
+ 0xd1a8, 0x0fd1,
+ 0xd1ab, 0x21e6,
+ 0xd1ac, 0x0fd5,
+ 0xd1af, 0x21e7,
+ 0xd1b2, 0x0fdb,
+ 0xd1b5, 0x21ea,
+ 0xd1b8, 0x0fe1,
+ 0xd1b9, 0x21ed,
+ 0xd1ba, 0x0fe3,
+ 0xd1bb, 0x21ee,
+ 0xd1bd, 0x0fe6,
+ 0xd1c6, 0x21f0,
+ 0xd1c9, 0x0ff2,
+ 0xd1cb, 0x21f3,
+ 0xd1cc, 0x0ff5,
+ 0xd1ce, 0x21f4,
+ 0xd1d0, 0x0ff9,
+ 0xd1d5, 0x21f6,
+ 0xd1d7, 0x1000,
+ 0xd1de, 0x21f8,
+ 0xd1df, 0x1008,
+ 0xd1e1, 0x21f9,
+ 0xd1e3, 0x100c,
+ 0xd1e8, 0x21fb,
+ 0xd1ea, 0x1013,
+ 0xd1ec, 0x21fd,
+ 0xd1ed, 0x1016,
+ 0xd1ee, 0x21fe,
+ 0xd1f0, 0x1019,
+ 0xd1f1, 0x2200,
+ 0xd1f2, 0x101b,
+ 0xd1f4, 0x2201,
+ 0xd1f5, 0x101e,
+ 0xd1f7, 0x2202,
+ 0xd1fa, 0x1023,
+ 0xd2a1, 0x1028,
+ 0xd2a2, 0x2205,
+ 0xd2a3, 0x102a,
+ 0xd2a5, 0x2206,
+ 0xd2a6, 0x102d,
+ 0xd2a9, 0x2207,
+ 0xd2aa, 0x1031,
+ 0xd2af, 0x2208,
+ 0xd2b0, 0x1037,
+ 0xd2b3, 0x2209,
+ 0xd2b4, 0x103b,
+ 0xd2b5, 0x220a,
+ 0xd2b7, 0x103e,
+ 0xd2bd, 0x220c,
+ 0xd2be, 0x1045,
+ 0xd2bf, 0x220d,
+ 0xd2c0, 0x1047,
+ 0xd2c3, 0x220e,
+ 0xd2c4, 0x104b,
+ 0xd2c5, 0x220f,
+ 0xd2c6, 0x104d,
+ 0xd2c7, 0x2210,
+ 0xd2c8, 0x104f,
+ 0xd2cf, 0x2211,
+ 0xd2d0, 0x1057,
+ 0xd2d5, 0x2212,
+ 0xd2d6, 0x105d,
+ 0xd2da, 0x2213,
+ 0xd2db, 0x1062,
+ 0xd2e4, 0x2214,
+ 0xd2e6, 0x106d,
+ 0xd2e8, 0x2216,
+ 0xd2ec, 0x1073,
+ 0xd2ef, 0x221a,
+ 0xd2f0, 0x1077,
+ 0xd2f1, 0x221b,
+ 0xd2f2, 0x1079,
+ 0xd2f5, 0x221c,
+ 0xd2f6, 0x107d,
+ 0xd2f8, 0x221d,
+ 0xd2f9, 0x1080,
+ 0xd2fb, 0x221e,
+ 0xd2fc, 0x1083,
+ 0xd2fe, 0x221f,
+ 0xd3a1, 0x1086,
+ 0xd3a3, 0x2220,
+ 0xd3ad, 0x1092,
+ 0xd3ae, 0x222a,
+ 0xd3af, 0x1094,
+ 0xd3b1, 0x222b,
+ 0xd3b2, 0x1097,
+ 0xd3b4, 0x222c,
+ 0xd3b7, 0x109c,
+ 0xd3b8, 0x222f,
+ 0xd3b9, 0x109e,
+ 0xd3bb, 0x2230,
+ 0xd3bc, 0x10a1,
+ 0xd3c5, 0x2231,
+ 0xd3c6, 0x10ab,
+ 0xd3c7, 0x2232,
+ 0xd3c8, 0x10ad,
+ 0xd3ca, 0x2233,
+ 0xd3cd, 0x10b2,
+ 0xd3d5, 0x2236,
+ 0xd3d6, 0x10bb,
+ 0xd3df, 0x2237,
+ 0xd3e1, 0x10c6,
+ 0xd3e3, 0x2239,
+ 0xd3e4, 0x10c9,
+ 0xd3e6, 0x223a,
+ 0xd3e7, 0x10cc,
+ 0xd3eb, 0x223b,
+ 0xd3ed, 0x10d2,
+ 0xd3ef, 0x223d,
+ 0xd3f0, 0x10d5,
+ 0xd3f4, 0x223e,
+ 0xd3f5, 0x10da,
+ 0xd3fc, 0x223f,
+ 0xd3fd, 0x10e2,
+ 0xd3fe, 0x2240,
+ 0xd4a1, 0x10e4,
+ 0xd4a4, 0x2241,
+ 0xd4a5, 0x10e8,
+ 0xd4a6, 0x2242,
+ 0xd4a9, 0x10ec,
+ 0xd4af, 0x2245,
+ 0xd4b3, 0x10f6,
+ 0xd4b5, 0x2249,
+ 0xd4b7, 0x10fa,
+ 0xd4b8, 0x224b,
+ 0xd4b9, 0x10fc,
+ 0xd4bc, 0x224c,
+ 0xd4bd, 0x1100,
+ 0xd4be, 0x224d,
+ 0xd4c0, 0x1103,
+ 0xd4c4, 0x224f,
+ 0xd4c5, 0x1108,
+ 0xd4c6, 0x2250,
+ 0xd4c8, 0x110b,
+ 0xd4c9, 0x2252,
+ 0xd4ca, 0x110d,
+ 0xd4cb, 0x2253,
+ 0xd4cf, 0x1112,
+ 0xd4d3, 0x2257,
+ 0xd4d4, 0x1117,
+ 0xd4d8, 0x2258,
+ 0xd4d9, 0x111c,
+ 0xd4dc, 0x2259,
+ 0xd4e1, 0x1124,
+ 0xd4e4, 0x225e,
+ 0xd4e5, 0x1128,
+ 0xd4e6, 0x225f,
+ 0xd4e7, 0x112a,
+ 0xd4ee, 0x2260,
+ 0xd4ef, 0x1132,
+ 0xd4f0, 0x2261,
+ 0xd4f5, 0x1138,
+ 0xd4f9, 0x2266,
+ 0xd4fa, 0x113d,
+ 0xd4fe, 0x2267,
+ 0xd5a1, 0x2268,
+ 0xd5a3, 0x1144,
+ 0xd5a9, 0x226a,
+ 0xd5aa, 0x114b,
+ 0xd5ab, 0x226b,
+ 0xd5ac, 0x114d,
+ 0xd5ae, 0x226c,
+ 0xd5af, 0x1150,
+ 0xd5b1, 0x226d,
+ 0xd5b2, 0x1153,
+ 0xd5b5, 0x226e,
+ 0xd5b9, 0x115a,
+ 0xd5bb, 0x2272,
+ 0xd5bc, 0x115d,
+ 0xd5bd, 0x2273,
+ 0xd5be, 0x115f,
+ 0xd5c0, 0x2274,
+ 0xd5c1, 0x1162,
+ 0xd5c5, 0x2275,
+ 0xd5c6, 0x1167,
+ 0xd5c7, 0x2276,
+ 0xd5c8, 0x1169,
+ 0xd5ca, 0x2277,
+ 0xd5cc, 0x116d,
+ 0xd5cd, 0x2279,
+ 0xd5ce, 0x116f,
+ 0xd5d4, 0x227a,
+ 0xd5d5, 0x1176,
+ 0xd5dd, 0x227b,
+ 0xd5df, 0x1180,
+ 0xd5e0, 0x227d,
+ 0xd5e1, 0x1182,
+ 0xd5e2, 0x227e,
+ 0xd5e3, 0x1184,
+ 0xd5ea, 0x227f,
+ 0xd5ed, 0x118e,
+ 0xd5ef, 0x2282,
+ 0xd5f0, 0x1191,
+ 0xd5f2, 0x2283,
+ 0xd5f4, 0x1195,
+ 0xd5f7, 0x15eb,
+ 0xd5f8, 0x1199,
+ 0xd6a1, 0x2285,
+ 0xd6a5, 0x11a4,
+ 0xd6af, 0x2289,
+ 0xd6b1, 0x11b0,
+ 0xd6b4, 0x228b,
+ 0xd6b5, 0x11b4,
+ 0xd6bb, 0x228c,
+ 0xd6bc, 0x11bb,
+ 0xd6bd, 0x228d,
+ 0xd6be, 0x11bd,
+ 0xd6bf, 0x228e,
+ 0xd6c1, 0x11c0,
+ 0xd6c4, 0x2290,
+ 0xd6c5, 0x11c4,
+ 0xd6ca, 0x2291,
+ 0xd6cb, 0x11ca,
+ 0xd6cd, 0x2292,
+ 0xd6ce, 0x11cd,
+ 0xd6d3, 0x2293,
+ 0xd6d4, 0x11d3,
+ 0xd6d5, 0x2294,
+ 0xd6d8, 0x11d7,
+ 0xd6da, 0x2297,
+ 0xd6db, 0x11da,
+ 0xd6df, 0x2298,
+ 0xd6e0, 0x11df,
+ 0xd6e1, 0x2299,
+ 0xd6e2, 0x11e1,
+ 0xd6e5, 0x229a,
+ 0xd6e6, 0x11e5,
+ 0xd6e7, 0x229b,
+ 0xd6e9, 0x11e8,
+ 0xd6ee, 0x229d,
+ 0xd6f0, 0x11ef,
+ 0xd6f2, 0x229f,
+ 0xd6f3, 0x11f2,
+ 0xd6f5, 0x22a0,
+ 0xd6f7, 0x11f6,
+ 0xd6fc, 0x22a2,
+ 0xd7a1, 0x11fe,
+ 0xd7a4, 0x22a5,
+ 0xd7a5, 0x1202,
+ 0xd7a8, 0x22a6,
+ 0xd7ab, 0x1208,
+ 0xd7ac, 0x22a9,
+ 0xd7ad, 0x120a,
+ 0xd7ae, 0x22aa,
+ 0xd7b2, 0x120f,
+ 0xd7b3, 0x22ae,
+ 0xd7b5, 0x1212,
+ 0xd7b6, 0x22b0,
+ 0xd7b7, 0x1214,
+ 0xd7b8, 0x22b1,
+ 0xd7bd, 0x121a,
+ 0xd7c7, 0x22b6,
+ 0xd7c8, 0x1225,
+ 0xd7ca, 0x22b7,
+ 0xd7cb, 0x1228,
+ 0xd7d5, 0x22b8,
+ 0xd7d6, 0x1233,
+ 0xd7db, 0x22b9,
+ 0xd7df, 0x123c,
+ 0xd7e7, 0x22bd,
+ 0xd7e8, 0x1245,
+ 0xd7e9, 0x22be,
+ 0xd7eb, 0x1248,
+ 0xd8a1, 0x1257,
+ 0xd8c4, 0x22c0,
+ 0xd8c5, 0x127b,
+ 0xd8c7, 0x22c1,
+ 0xd8c8, 0x127e,
+ 0xd8c9, 0x22c2,
+ 0xd8ca, 0x1280,
+ 0xd8cc, 0x22c3,
+ 0xd8ce, 0x1284,
+ 0xd8d0, 0x22c5,
+ 0xd8d2, 0x1288,
+ 0xd8d3, 0x22c7,
+ 0xd8d4, 0x128a,
+ 0xd8d9, 0x22c8,
+ 0xd8da, 0x1290,
+ 0xd8db, 0x22c9,
+ 0xd8dd, 0x1293,
+ 0xd8f1, 0x22cb,
+ 0xd8f2, 0x12a8,
+ 0xd8f6, 0x22cc,
+ 0xd8f8, 0x12ae,
+ 0xd9a1, 0x12b5,
+ 0xd9ad, 0x22ce,
+ 0xd9ae, 0x12c2,
+ 0xd9af, 0x22cf,
+ 0xd9b0, 0x12c4,
+ 0xd9b1, 0x22d0,
+ 0xd9b4, 0x12c8,
+ 0xd9c7, 0x22d3,
+ 0xd9c8, 0x12dc,
+ 0xd9cd, 0x22d4,
+ 0xd9d1, 0x12e5,
+ 0xd9dd, 0x22d8,
+ 0xd9de, 0x12f2,
+ 0xd9e1, 0x22d9,
+ 0xd9e2, 0x12f6,
+ 0xd9e4, 0x22da,
+ 0xd9e5, 0x12f9,
+ 0xd9e6, 0x22db,
+ 0xd9e7, 0x12fb,
+ 0xd9ec, 0x22dc,
+ 0xd9ed, 0x1301,
+ 0xd9f4, 0x22dd,
+ 0xd9f6, 0x130a,
+ 0xdaa1, 0x1313,
+ 0xdaa5, 0x22df,
+ 0xdae0, 0x1352,
+ 0xdaea, 0x231a,
+ 0xdaeb, 0x135d,
+ 0xdaf7, 0x231b,
+ 0xdaf8, 0x136a,
+ 0xdaf9, 0x231c,
+ 0xdafa, 0x136c,
+ 0xdafe, 0x231d,
+ 0xdba1, 0x1371,
+ 0xdba3, 0x231e,
+ 0xdba4, 0x1374,
+ 0xdba6, 0x231f,
+ 0xdba7, 0x1377,
+ 0xdba9, 0x2320,
+ 0xdbab, 0x137b,
+ 0xdbbb, 0x2322,
+ 0xdbbc, 0x138c,
+ 0xdbbd, 0x2323,
+ 0xdbbe, 0x138e,
+ 0xdbcf, 0x2324,
+ 0xdbd0, 0x13a0,
+ 0xdbd1, 0x2325,
+ 0xdbd2, 0x13a2,
+ 0xdbdb, 0x2326,
+ 0xdbdc, 0x13ac,
+ 0xdbde, 0x2327,
+ 0xdbdf, 0x13af,
+ 0xdbe2, 0x2328,
+ 0xdbe3, 0x13b3,
+ 0xdbe4, 0x2329,
+ 0xdbe5, 0x13b5,
+ 0xdbeb, 0x232a,
+ 0xdbec, 0x13bc,
+ 0xdbee, 0x232b,
+ 0xdbef, 0x13bf,
+ 0xdbf1, 0x232c,
+ 0xdbf2, 0x13c2,
+ 0xdbf5, 0x232d,
+ 0xdbf8, 0x13c8,
+ 0xdca1, 0x13cf,
+ 0xdcbc, 0x2330,
+ 0xdcbd, 0x13eb,
+ 0xdcbf, 0x2331,
+ 0xdcc0, 0x13ee,
+ 0xdcc2, 0x2332,
+ 0xdcc3, 0x13f1,
+ 0xdcc8, 0x2333,
+ 0xdccb, 0x13f9,
+ 0xdcd1, 0x2336,
+ 0xdcd2, 0x1400,
+ 0xdcd7, 0x2337,
+ 0xdcd8, 0x1406,
+ 0xdce0, 0x2338,
+ 0xdce1, 0x140f,
+ 0xdce3, 0x2339,
+ 0xdce5, 0x1413,
+ 0xdce9, 0x233b,
+ 0xdceb, 0x1419,
+ 0xdcf1, 0x233d,
+ 0xdcf2, 0x1420,
+ 0xdcf6, 0x233e,
+ 0xdcf7, 0x1425,
+ 0xdcf9, 0x233f,
+ 0xdcfa, 0x1428,
+ 0xdcfd, 0x2340,
+ 0xdda1, 0x2342,
+ 0xdda2, 0x142e,
+ 0xdda3, 0x2343,
+ 0xdda8, 0x1434,
+ 0xddaa, 0x2348,
+ 0xddac, 0x1438,
+ 0xddb2, 0x234a,
+ 0xddb3, 0x143f,
+ 0xddb5, 0x234b,
+ 0xddb6, 0x1442,
+ 0xddba, 0x234c,
+ 0xddbc, 0x1448,
+ 0xddd3, 0x234e,
+ 0xddd4, 0x1460,
+ 0xdddb, 0x234f,
+ 0xdddc, 0x1468,
+ 0xddde, 0x2350,
+ 0xdddf, 0x146b,
+ 0xdde4, 0x2351,
+ 0xdde5, 0x1471,
+ 0xddeb, 0x2352,
+ 0xddec, 0x1478,
+ 0xddf1, 0x2353,
+ 0xddf2, 0x147e,
+ 0xddf6, 0x2354,
+ 0xddf8, 0x1484,
+ 0xddfc, 0x2356,
+ 0xddfd, 0x1489,
+ 0xddfe, 0x2357,
+ 0xdea1, 0x148b,
+ 0xdead, 0x2358,
+ 0xdeae, 0x1498,
+ 0xdeb4, 0x2359,
+ 0xdeb5, 0x149f,
+ 0xdeba, 0x235a,
+ 0xdebb, 0x14a5,
+ 0xdec6, 0x235b,
+ 0xdec7, 0x14b1,
+ 0xdecf, 0x235c,
+ 0xded0, 0x14ba,
+ 0xded1, 0x235d,
+ 0xded3, 0x14bd,
+ 0xded8, 0x235f,
+ 0xded9, 0x14c3,
+ 0xdee2, 0x2360,
+ 0xdee3, 0x14cd,
+ 0xdee8, 0x2361,
+ 0xdee9, 0x14d3,
+ 0xdeec, 0x2362,
+ 0xdeed, 0x14d7,
+ 0xdef3, 0x2363,
+ 0xdef4, 0x14de,
+ 0xdefc, 0x2364,
+ 0xdefd, 0x14e7,
+ 0xdfa1, 0x14e9,
+ 0xdfa2, 0x2365,
+ 0xdfa4, 0x14ec,
+ 0xdfa5, 0x2367,
+ 0xdfa6, 0x14ee,
+ 0xdfb4, 0x2368,
+ 0xdfb5, 0x14fd,
+ 0xdfbc, 0x2369,
+ 0xdfbe, 0x1506,
+ 0xdfbf, 0x236b,
+ 0xdfc0, 0x1508,
+ 0xdfc2, 0x236c,
+ 0xdfc4, 0x150c,
+ 0xdfcc, 0x236e,
+ 0xdfcd, 0x1515,
+ 0xdfd0, 0x236f,
+ 0xdfd1, 0x1519,
+ 0xdfd5, 0x2370,
+ 0xdfd6, 0x151e,
+ 0xdfd8, 0x2371,
+ 0xdfda, 0x1522,
+ 0xdfdc, 0x2373,
+ 0xdfdd, 0x1525,
+ 0xdfe0, 0x2374,
+ 0xdfe1, 0x1529,
+ 0xdfe2, 0x2375,
+ 0xdfe3, 0x152b,
+ 0xdfe6, 0x2376,
+ 0xdfe7, 0x152f,
+ 0xdfe9, 0x2377,
+ 0xdfea, 0x1532,
+ 0xdfeb, 0x2378,
+ 0xdfec, 0x1534,
+ 0xdfef, 0x2379,
+ 0xdff0, 0x1538,
+ 0xdff5, 0x237a,
+ 0xdff6, 0x153e,
+ 0xdff9, 0x237b,
+ 0xdffa, 0x1542,
+ 0xe0a1, 0x1547,
+ 0xe0b6, 0x237c,
+ 0xe0b8, 0x155e,
+ 0xe0bf, 0x237e,
+ 0xe0c0, 0x1566,
+ 0xe0c8, 0x237f,
+ 0xe0c9, 0x156f,
+ 0xe0ce, 0x2380,
+ 0xe0cf, 0x1575,
+ 0xe0d3, 0x2381,
+ 0xe0d4, 0x157a,
+ 0xe0e0, 0x2382,
+ 0xe0e1, 0x1587,
+ 0xe0f0, 0x2383,
+ 0xe0f1, 0x1597,
+ 0xe0f8, 0x2384,
+ 0xe0f9, 0x159f,
+ 0xe0fc, 0x2385,
+ 0xe1a1, 0x15a5,
+ 0xe1ab, 0x2388,
+ 0xe1ac, 0x15b0,
+ 0xe1ad, 0x2389,
+ 0xe1ae, 0x15b2,
+ 0xe1b0, 0x238a,
+ 0xe1b1, 0x15b5,
+ 0xe1b4, 0x238b,
+ 0xe1b5, 0x15b9,
+ 0xe1bb, 0x238c,
+ 0xe1bc, 0x15c0,
+ 0xe1bd, 0x238d,
+ 0xe1be, 0x15c2,
+ 0xe1c0, 0x238e,
+ 0xe1c2, 0x15c6,
+ 0xe1c9, 0x2390,
+ 0xe1ca, 0x15ce,
+ 0xe1d0, 0x2391,
+ 0xe1d1, 0x15d5,
+ 0xe1db, 0x2392,
+ 0xe1dc, 0x15e0,
+ 0xe1e1, 0x07aa,
+ 0xe1e2, 0x2393,
+ 0xe1e3, 0x15e7,
+ 0xe1e7, 0x1198,
+ 0xe1e8, 0x15ec,
+ 0xe1ee, 0x2394,
+ 0xe1f0, 0x15f4,
+ 0xe1f6, 0x2396,
+ 0xe1f7, 0x15fb,
+ 0xe1f8, 0x2397,
+ 0xe1f9, 0x15fd,
+ 0xe1fd, 0x2398,
+ 0xe1fe, 0x1602,
+ 0xe2a1, 0x1603,
+ 0xe2a4, 0x2399,
+ 0xe2a5, 0x1607,
+ 0xe2a8, 0x239a,
+ 0xe2a9, 0x160b,
+ 0xe2bb, 0x239b,
+ 0xe2c5, 0x10c5,
+ 0xe2c6, 0x23a5,
+ 0xe2cf, 0x1631,
+ 0xe2d0, 0x23ae,
+ 0xe2d1, 0x1633,
+ 0xe2d9, 0x23af,
+ 0xe2da, 0x163c,
+ 0xe2e3, 0x23b0,
+ 0xe2e5, 0x1647,
+ 0xe2e6, 0x23b2,
+ 0xe2e7, 0x1649,
+ 0xe2e9, 0x23b3,
+ 0xe2ec, 0x164e,
+ 0xe2f8, 0x23b6,
+ 0xe2f9, 0x165b,
+ 0xe2fa, 0x23b7,
+ 0xe2fe, 0x1660,
+ 0xe3a1, 0x1661,
+ 0xe3a2, 0x23bb,
+ 0xe3a3, 0x1663,
+ 0xe3a5, 0x23bc,
+ 0xe3a6, 0x1666,
+ 0xe3ab, 0x23bd,
+ 0xe3ac, 0x166c,
+ 0xe3b4, 0x23be,
+ 0xe3b5, 0x1675,
+ 0xe3c5, 0x23bf,
+ 0xe3dc, 0x169c,
+ 0xe3e3, 0x23d6,
+ 0xe3e4, 0x16a4,
+ 0xe3ed, 0x23d7,
+ 0xe3ee, 0x16ae,
+ 0xe3f1, 0x23d8,
+ 0xe3f3, 0x16b3,
+ 0xe3f8, 0x23da,
+ 0xe3f9, 0x16b9,
+ 0xe3fe, 0x23db,
+ 0xe4a1, 0x16bf,
+ 0xe4a4, 0x23dc,
+ 0xe4a6, 0x16c4,
+ 0xe4ab, 0x23de,
+ 0xe4ac, 0x16ca,
+ 0xe4af, 0x23df,
+ 0xe4b2, 0x16d0,
+ 0xe4b5, 0x23e2,
+ 0xe4b7, 0x16d5,
+ 0xe4c2, 0x23e4,
+ 0xe4c3, 0x16e1,
+ 0xe4c5, 0x23e5,
+ 0xe4c6, 0x16e4,
+ 0xe4c9, 0x23e6,
+ 0xe4ca, 0x16e8,
+ 0xe4d9, 0x23e7,
+ 0xe4da, 0x16f8,
+ 0xe4dc, 0x23e8,
+ 0xe4dd, 0x16fb,
+ 0xe4de, 0x23e9,
+ 0xe4df, 0x16fd,
+ 0xe4e4, 0x23ea,
+ 0xe4e5, 0x1703,
+ 0xe4eb, 0x23eb,
+ 0xe4ed, 0x170b,
+ 0xe4f2, 0x23ed,
+ 0xe4f3, 0x1711,
+ 0xe4fe, 0x23ee,
+ 0xe5a1, 0x171d,
+ 0xe5b0, 0x23ef,
+ 0xe5b1, 0x172d,
+ 0xe5b9, 0x23f0,
+ 0xe5ba, 0x1736,
+ 0xe5c7, 0x23f1,
+ 0xe5c8, 0x1744,
+ 0xe5c9, 0x23f2,
+ 0xe5ca, 0x1746,
+ 0xe5ce, 0x23f3,
+ 0xe5cf, 0x174b,
+ 0xe5f0, 0x23f4,
+ 0xe5f1, 0x176d,
+ 0xe5f2, 0x23f5,
+ 0xe5f3, 0x176f,
+ 0xe5fc, 0x23f6,
+ 0xe5fe, 0x177a,
+ 0xe6a1, 0x177b,
+ 0xe6a3, 0x23f8,
+ 0xe6a4, 0x177e,
+ 0xe6ab, 0x23f9,
+ 0xe6ad, 0x1787,
+ 0xe6ae, 0x23fb,
+ 0xe6af, 0x1789,
+ 0xe6b4, 0x23fc,
+ 0xe6b6, 0x1790,
+ 0xe6bf, 0x23fe,
+ 0xe6c0, 0x179a,
+ 0xe6c8, 0x23ff,
+ 0xe6ca, 0x17a4,
+ 0xe6cd, 0x2401,
+ 0xe6ce, 0x17a8,
+ 0xe6e0, 0x2402,
+ 0xe7a1, 0x2421,
+ 0xe7db, 0x1813,
+ 0xe7e1, 0x245b,
+ 0xe7e3, 0x181b,
+ 0xe7e7, 0x245d,
+ 0xe7e8, 0x1820,
+ 0xe7ef, 0x245e,
+ 0xe7f0, 0x1828,
+ 0xe7f4, 0x245f,
+ 0xe7f7, 0x182f,
+ 0xe8a1, 0x1837,
+ 0xe8a8, 0x2462,
+ 0xe8a9, 0x183f,
+ 0xe8ac, 0x2463,
+ 0xe8ad, 0x1843,
+ 0xe8b6, 0x2464,
+ 0xe8b7, 0x184d,
+ 0xe8b8, 0x2465,
+ 0xe8bb, 0x1851,
+ 0xe8bf, 0x2468,
+ 0xe8c1, 0x1857,
+ 0xe8c5, 0x246a,
+ 0xe8c6, 0x185c,
+ 0xe8c7, 0x246b,
+ 0xe8ca, 0x1860,
+ 0xe8ce, 0x246e,
+ 0xe8cf, 0x1865,
+ 0xe8d0, 0x246f,
+ 0xe8d1, 0x1867,
+ 0xe8d3, 0x2470,
+ 0xe8d4, 0x186a,
+ 0xe8dd, 0x2471,
+ 0xe8de, 0x1874,
+ 0xe8df, 0x2472,
+ 0xe8e0, 0x1876,
+ 0xe8e2, 0x2473,
+ 0xe8e4, 0x187a,
+ 0xe8e5, 0x2475,
+ 0xe8e6, 0x187c,
+ 0xe8e7, 0x2476,
+ 0xe8e8, 0x187e,
+ 0xe8eb, 0x2477,
+ 0xe8ec, 0x1882,
+ 0xe8ed, 0x2478,
+ 0xe8ee, 0x1884,
+ 0xe8ef, 0x2479,
+ 0xe8f0, 0x1886,
+ 0xe8f9, 0x247a,
+ 0xe8fa, 0x1890,
+ 0xe8fc, 0x247b,
+ 0xe8fe, 0x1894,
+ 0xe9a1, 0x247d,
+ 0xe9a2, 0x1896,
+ 0xe9ad, 0x247e,
+ 0xe9ae, 0x18a2,
+ 0xe9b4, 0x247f,
+ 0xe9b6, 0x18aa,
+ 0xe9b7, 0x2481,
+ 0xe9b8, 0x18ac,
+ 0xe9c4, 0x2482,
+ 0xe9c5, 0x18b9,
+ 0xe9c6, 0x2483,
+ 0xe9c7, 0x18bb,
+ 0xe9c9, 0x2484,
+ 0xe9ca, 0x18be,
+ 0xe9d6, 0x2485,
+ 0xe9d7, 0x18cb,
+ 0xe9da, 0x2486,
+ 0xe9db, 0x18cf,
+ 0xe9e4, 0x2487,
+ 0xe9e5, 0x18d9,
+ 0xe9e6, 0x2488,
+ 0xe9e8, 0x18dc,
+ 0xe9e9, 0x248a,
+ 0xe9ea, 0x18de,
+ 0xe9eb, 0x248b,
+ 0xe9ec, 0x18e0,
+ 0xe9ed, 0x248c,
+ 0xeaa1, 0x249e,
+ 0xeaa6, 0x18f8,
+ 0xeaa7, 0x24a3,
+ 0xeaa9, 0x18fb,
+ 0xeab1, 0x24a5,
+ 0xeab2, 0x1904,
+ 0xeabc, 0x24a6,
+ 0xeabd, 0x190f,
+ 0xeaca, 0x24a7,
+ 0xeacb, 0x191d,
+ 0xeacd, 0x24a8,
+ 0xeace, 0x1920,
+ 0xead3, 0x24a9,
+ 0xead4, 0x1926,
+ 0xeada, 0x24aa,
+ 0xeaf0, 0x1942,
+ 0xeba1, 0x1951,
+ 0xeba7, 0x24c0,
+ 0xeba8, 0x1958,
+ 0xebaa, 0x24c1,
+ 0xebab, 0x195b,
+ 0xebb2, 0x24c2,
+ 0xebb3, 0x1963,
+ 0xebb9, 0x24c3,
+ 0xebba, 0x196a,
+ 0xebca, 0x24c4,
+ 0xebcc, 0x197c,
+ 0xebcd, 0x24c6,
+ 0xebce, 0x197e,
+ 0xebd6, 0x24c7,
+ 0xebd7, 0x1987,
+ 0xebda, 0x24c8,
+ 0xebdb, 0x198b,
+ 0xebe1, 0x24c9,
+ 0xebe2, 0x1992,
+ 0xebf7, 0x24ca,
+ 0xebf8, 0x19a8,
+ 0xeca1, 0x19af,
+ 0xeca3, 0x24cb,
+ 0xeca4, 0x19b2,
+ 0xeca9, 0x24cc,
+ 0xecaf, 0x19bd,
+ 0xecb1, 0x24d2,
+ 0xecb2, 0x19c0,
+ 0xecb4, 0x24d3,
+ 0xecb6, 0x19c4,
+ 0xecbe, 0x24d5,
+ 0xecc0, 0x19ce,
+ 0xecc1, 0x24d7,
+ 0xecc2, 0x19d0,
+ 0xecc7, 0x24d8,
+ 0xecc8, 0x19d6,
+ 0xeccb, 0x24d9,
+ 0xeccc, 0x19da,
+ 0xece2, 0x24da,
+ 0xece3, 0x19f1,
+ 0xecf2, 0x24db,
+ 0xecf3, 0x1a01,
+ 0xecf5, 0x24dc,
+ 0xecf6, 0x1a04,
+ 0xecf8, 0x24dd,
+ 0xecf9, 0x1a07,
+ 0xeda1, 0x24de,
+ 0xeda2, 0x1a0e,
+ 0xeda8, 0x24df,
+ 0xeda9, 0x1a15,
+ 0xedaf, 0x24e0,
+ 0xedb1, 0x1a1d,
+ 0xedb4, 0x24e2,
+ 0xedb5, 0x1a21,
+ 0xedb6, 0x24e3,
+ 0xedb7, 0x1a23,
+ 0xedb8, 0x24e4,
+ 0xedb9, 0x1a25,
+ 0xedba, 0x24e5,
+ 0xedbb, 0x1a27,
+ 0xedbf, 0x24e6,
+ 0xedc0, 0x1a2c,
+ 0xedc2, 0x24e7,
+ 0xedc4, 0x1a30,
+ 0xedcc, 0x24e9,
+ 0xedce, 0x1a3a,
+ 0xedd3, 0x24eb,
+ 0xedd4, 0x1a40,
+ 0xedd7, 0x24ec,
+ 0xedd8, 0x1a44,
+ 0xede8, 0x24ed,
+ 0xede9, 0x1a55,
+ 0xedee, 0x24ee,
+ 0xedef, 0x1a5b,
+ 0xedf9, 0x24ef,
+ 0xedfb, 0x1a67,
+ 0xeea1, 0x1a6b,
+ 0xeebc, 0x24f1,
+ 0xeebd, 0x1a87,
+ 0xeebf, 0x24f2,
+ 0xeec0, 0x1a8a,
+ 0xeec4, 0x24f3,
+ 0xefa1, 0x252e,
+ 0xeff2, 0x1b1a,
+ 0xf0a1, 0x1b27,
+ 0xf0a3, 0x257f,
+ 0xf0a4, 0x1b2a,
+ 0xf0af, 0x2580,
+ 0xf0da, 0x1b60,
+ 0xf0dc, 0x25ab,
+ 0xf0de, 0x1b64,
+ 0xf0df, 0x25ad,
+ 0xf0e0, 0x1b66,
+ 0xf0e9, 0x25ae,
+ 0xf0ea, 0x1b70,
+ 0xf0ec, 0x25af,
+ 0xf0ed, 0x1b73,
+ 0xf0ef, 0x25b0,
+ 0xf0f0, 0x1b76,
+ 0xf0f7, 0x25b1,
+ 0xf0f8, 0x1b7e,
+ 0xf0f9, 0x25b2,
+ 0xf0fa, 0x1b80,
+ 0xf0fc, 0x25b3,
+ 0xf0fd, 0x1b83,
+ 0xf1a1, 0x1b85,
+ 0xf1a8, 0x25b4,
+ 0xf1a9, 0x1b8d,
+ 0xf1ab, 0x25b5,
+ 0xf1ac, 0x1b90,
+ 0xf1ae, 0x25b6,
+ 0xf1af, 0x1b93,
+ 0xf1b2, 0x25b7,
+ 0xf1b3, 0x1b97,
+ 0xf1bc, 0x25b8,
+ 0xf1bd, 0x1ba1,
+ 0xf1c0, 0x25b9,
+ 0xf1c1, 0x1ba5,
+ 0xf1c9, 0x25ba,
+ 0xf1ca, 0x1bae,
+ 0xf1cd, 0x25bb,
+ 0xf1ce, 0x1bb2,
+ 0xf1cf, 0x25bc,
+ 0xf1d1, 0x1bb5,
+ 0xf1da, 0x25be,
+ 0xf1db, 0x1bbf,
+ 0xf1dc, 0x25bf,
+ 0xf1dd, 0x1bc1,
+ 0xf1e4, 0x25c0,
+ 0xf1e5, 0x1bc9,
+ 0xf1ec, 0x25c1,
+ 0xf1ed, 0x1bd1,
+ 0xf1ef, 0x25c2,
+ 0xf1f0, 0x1bd4,
+ 0xf1f7, 0x25c3,
+ 0xf1f8, 0x1bdc,
+ 0xf1f9, 0x25c4,
+ 0xf1fa, 0x1bde,
+ 0xf1fc, 0x25c5,
+ 0xf2a1, 0x25c8,
+ 0xf2ae, 0x1bf0,
+ 0xf2b1, 0x25d5,
+ 0xf2b3, 0x1bf5,
+ 0xf2b9, 0x25d7,
+ 0xf2ba, 0x1bfc,
+ 0xf2c3, 0x25d8,
+ 0xf2c4, 0x1c06,
+ 0xf2c9, 0x25d9,
+ 0xf2ca, 0x1c0c,
+ 0xf2cc, 0x25da,
+ 0xf2ce, 0x1c10,
+ 0xf2cf, 0x25dc,
+ 0xf2d0, 0x1c12,
+ 0xf2d3, 0x25dd,
+ 0xf2d4, 0x1c16,
+ 0xf2e5, 0x25de,
+ 0xf2e6, 0x1c28,
+ 0xf2ee, 0x25df,
+ 0xf2ef, 0x1c31,
+ 0xf2f7, 0x25e0,
+ 0xf2f8, 0x1c3a,
+ 0xf2fd, 0x25e1,
+ 0xf2fe, 0x1c40,
+ 0xf3a1, 0x1c41,
+ 0xf3bf, 0x25e2,
+ 0xf3c0, 0x1c60,
+ 0xf3c6, 0x25e3,
+ 0xf3c7, 0x1c67,
+ 0xf3c8, 0x25e4,
+ 0xf3c9, 0x1c69,
+ 0xf3d6, 0x25e5,
+ 0xf3d7, 0x1c77,
+ 0xf3d9, 0x25e6,
+ 0xf3da, 0x1c7a,
+ 0xf3e5, 0x25e7,
+ 0xf3e7, 0x1c87,
+ 0xf3ea, 0x25e9,
+ 0xf3eb, 0x1c8b,
+ 0xf3ec, 0x25ea,
+ 0xf3ed, 0x1c8d,
+ 0xf3ef, 0x25eb,
+ 0xf3f0, 0x1c90,
+ 0xf3f1, 0x25ec,
+ 0xf3f2, 0x1c92,
+ 0xf3fd, 0x25ed,
+ 0xf3fe, 0x1c9e,
+ 0xf4a1, 0x1c9f,
+ 0xf4a5, 0x25ee,
+ 0xf4a6, 0x1ca4,
+ 0xf4af, 0x25ef,
+ 0xf4b0, 0x1cae,
+ 0xf4b5, 0x25f0,
+ 0xf4b6, 0x1cb4,
+ 0xf4c1, 0x25f1,
+ 0xf4c2, 0x1cc0,
+ 0xf4c7, 0x25f2,
+ 0xf4c8, 0x1cc6,
+ 0xf4cf, 0x25f3,
+ 0xf4d1, 0x1ccf,
+ 0xf4d6, 0x25f5,
+ 0xf4d7, 0x1cd5,
+ 0xf4ea, 0x25f6,
+ 0xf4eb, 0x1ce9,
+ 0xf4ef, 0x25f7,
+ 0xf4f0, 0x1cee,
+ 0xf4f5, 0x25f8,
+ 0xf4f6, 0x1cf4,
+ 0xf5a1, 0x1cfd,
+ 0xf5a6, 0x25f9,
+ 0xf5a8, 0x1d04,
+ 0xf5ba, 0x25fb,
+ 0xf5bc, 0x1d18,
+ 0xf5c4, 0x25fd,
+ 0xf5c5, 0x1d21,
+ 0xf5c8, 0x25fe,
+ 0xf5c9, 0x1d25,
+ 0xf5ce, 0x25ff,
+ 0xf5d0, 0x1d2c,
+ 0xf5d1, 0x2601,
+ 0xf5d3, 0x1d2f,
+ 0xf5d9, 0x2603,
+ 0xf5da, 0x1d36,
+ 0xf5dc, 0x2604,
+ 0xf5dd, 0x1d39,
+ 0xf5e6, 0x2605,
+ 0xf5e8, 0x1d44,
+ 0xf5ef, 0x2607,
+ 0xf5f0, 0x1d4c,
+ 0xf5f2, 0x2608,
+ 0xf5f3, 0x1d4f,
+ 0xf5fc, 0x2609,
+ 0xf5fd, 0x1d59,
+ 0xf6a1, 0x1d5b,
+ 0xf6a3, 0x260a,
+ 0xf6a4, 0x1d5e,
+ 0xf6a6, 0x260b,
+ 0xf6a7, 0x1d61,
+ 0xf6a8, 0x260c,
+ 0xf6a9, 0x1d63,
+ 0xf6ab, 0x260d,
+ 0xf6ac, 0x1d66,
+ 0xf6b0, 0x260e,
+ 0xf6b1, 0x1d6b,
+ 0xf6b3, 0x260f,
+ 0xf6bf, 0x1d79,
+ 0xf6c5, 0x261b,
+ 0xf6c6, 0x1d80,
+ 0xf6c7, 0x261c,
+ 0xf6c8, 0x1d82,
+ 0xf6c9, 0x261d,
+ 0xf6ca, 0x1d84,
+ 0xf6cf, 0x261e,
+ 0xf7a1, 0x264e,
+ 0xf7b0, 0x1dc8,
+ 0xf7b2, 0x265d,
+ 0xf7b4, 0x1dcc,
+ 0xf7b5, 0x265f,
+ 0xf7b6, 0x1dce,
+ 0xf7bd, 0x2660,
+ 0xf7be, 0x1dd6,
+ 0xf7c3, 0x2661,
+ 0xf7c4, 0x1ddc,
+ 0xf7c5, 0x2662,
+ 0xf7c7, 0x1ddf,
+ 0xf7ca, 0x2664,
+ 0xf7cc, 0x1de4,
+ 0xf7cf, 0x2666,
+ 0xf7d1, 0x1de9,
+ 0xf7de, 0x2668,
+ 0xf7df, 0x1df7,
+ 0xf7e1, 0x0ab9,
+ 0xf7e2, 0x1dfa,
+ 0xf7f2, 0x2669,
+ 0xf7f3, 0x1e0b,
+ 0xf7f5, 0x266a,
+ 0xf7f6, 0x1e0e,
+ 0xf8a1, 0x266b,
+ 0xf8a7, 0x04cc,
+ 0xf8a8, 0x050a,
+ 0xf8a9, 0x0518,
+ 0xf8aa, 0x2671,
+ 0xf8ac, 0x0594,
+ 0xf8ad, 0x05ce,
+ 0xf8ae, 0x2673,
+ 0xf8af, 0x05f6,
+ 0xf8b0, 0x2674,
+ 0xf8b2, 0x0653,
+ 0xf8b3, 0x067e,
+ 0xf8b4, 0x2676,
+ 0xf8b5, 0x06c4,
+ 0xf8b6, 0x2677,
+ 0xf8b8, 0x073c,
+ 0xf8b9, 0x2679,
+ 0xf8bb, 0x07c3,
+ 0xf8bc, 0x267b,
+ 0xf8c0, 0x082b,
+ 0xf8c1, 0x267f,
+ 0xf8c2, 0x084e,
+ 0xf8c3, 0x0869,
+ 0xf8c4, 0x2680,
+ 0xf8c6, 0x090c,
+ 0xf8c7, 0x2682,
+ 0xf8c9, 0x0971,
+ 0xf8ca, 0x2684,
+ 0xf8cb, 0x099a,
+ 0xf8cd, 0x2685,
+ 0xf8ce, 0x09da,
+ 0xf8cf, 0x2686,
+ 0xf8d0, 0x09fa,
+ 0xf8d1, 0x2687,
+ 0xf8dc, 0x0bda,
+ 0xf8dd, 0x0bdd,
+ 0xf8de, 0x0bea,
+ 0xf8df, 0x0bec,
+ 0xf8e0, 0x0bf2,
+ 0xf8e1, 0x2692,
+ 0xf8e6, 0x0c92,
+ 0xf8e7, 0x0d1a,
+ 0xf8e8, 0x0d8c,
+ 0xf8e9, 0x0dbe,
+ 0xf8ea, 0x2697,
+ 0xf8eb, 0x0dfb,
+ 0xf8ec, 0x2698,
+ 0xf8ef, 0x0e70,
+ 0xf8f0, 0x269b,
+ 0xf8f1, 0x0ea3,
+ 0xf8f2, 0x269c,
+ 0xf8f8, 0x103d,
+ 0xf8f9, 0x10d9,
+ 0xf8fa, 0x26a2,
+ 0xf8fc, 0x10fb,
+ 0xf8fd, 0x1109,
+ 0xf8fe, 0x26a4,
+ 0xf9a1, 0x11a1,
+ 0xf9a2, 0x26a5,
+ 0xf9a3, 0x11ba,
+ 0xf9a4, 0x26a6,
+ 0xf9a6, 0x11d5,
+ 0xf9a7, 0x26a8,
+ 0xf9a8, 0x11fd,
+ 0xf9a9, 0x1219,
+ 0xa1a2, 0x023f,
+ 0xa1a3, 0x023e,
+ 0xa1aa, 0x0256,
+ 0xa1ab, 0x1e18,
+ 0xa1ad, 0x0257,
+ 0xa1b2, 0x0246,
+ 0xa1fe, 0x1e1a,
+ 0xa3a1, 0x0242,
+ 0xa3a8, 0x0244,
+ 0xa3ac, 0x023d,
+ 0xa3ae, 0x1e1b,
+ 0xa3ba, 0x0240,
+ 0xa3bd, 0x1e1c,
+ 0xa3bf, 0x0243,
+ 0xa3db, 0x1e1d,
+ 0xa3dd, 0x1e1e,
+ 0xa3df, 0x0258,
+ 0xa3fb, 0x0254,
+ 0xa3fd, 0x0255,
+ 0xa3fe, 0x1e1f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBTEUCVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1e24, 0x032e, 0x032f, 0x0330, 0x0331, 0x0332, 0x0333, 0x0334,
+ 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x033a, 0x033b, 0x033c,
+ 0x033d, 0x033e, 0x033f, 0x0340, 0x0341, 0x0342, 0x0343, 0x0344,
+ 0x0345, 0x0346, 0x0347, 0x0348, 0x0349, 0x034a, 0x034b, 0x034c,
+ 0x034d, 0x034e, 0x034f, 0x0350, 0x0351, 0x0352, 0x0353, 0x0354,
+ 0x0355, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035c,
+ 0x035d, 0x035e, 0x035f, 0x0360, 0x0361, 0x0362, 0x0363, 0x0364,
+ 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c,
+ 0x036d, 0x036e, 0x036f, 0x0370, 0x0371, 0x0372, 0x0373, 0x0374,
+ 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x037a, 0x037b, 0x037c,
+ 0x037d, 0x037e, 0x037f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384,
+ 0x0385, 0x0386, 0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12GBTEUCVMap2, 2303
+};
+
+static Gushort gb12GBTHMap2[4566] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0060,
+ 0x2231, 0x00be,
+ 0x2265, 0x00f0,
+ 0x2271, 0x00fa,
+ 0x2321, 0x0106,
+ 0x2421, 0x0164,
+ 0x2521, 0x01b7,
+ 0x2621, 0x020d,
+ 0x2641, 0x0225,
+ 0x2721, 0x025a,
+ 0x2751, 0x027b,
+ 0x2821, 0x029c,
+ 0x2845, 0x02bc,
+ 0x2924, 0x02e2,
+ 0x2a21, 0x032e,
+ 0x2b21, 0x038c,
+ 0x3021, 0x03ac,
+ 0x3028, 0x1e25,
+ 0x3029, 0x03b4,
+ 0x302a, 0x1e26,
+ 0x302b, 0x03b6,
+ 0x302d, 0x1e27,
+ 0x302f, 0x03ba,
+ 0x3039, 0x1e29,
+ 0x303a, 0x03c5,
+ 0x3040, 0x1e2a,
+ 0x3041, 0x03cc,
+ 0x3053, 0x1e2b,
+ 0x3054, 0x03df,
+ 0x3055, 0x1e2c,
+ 0x3056, 0x03e1,
+ 0x305a, 0x1e2d,
+ 0x305b, 0x03e6,
+ 0x305c, 0x1e2e,
+ 0x305d, 0x03e8,
+ 0x3064, 0x1e2f,
+ 0x3065, 0x03f0,
+ 0x306c, 0x1e30,
+ 0x306e, 0x03f9,
+ 0x306f, 0x1e32,
+ 0x3070, 0x03fb,
+ 0x3073, 0x1e33,
+ 0x3074, 0x03ff,
+ 0x3077, 0x1e34,
+ 0x3078, 0x0403,
+ 0x3079, 0x1e35,
+ 0x307a, 0x0405,
+ 0x3121, 0x040a,
+ 0x3125, 0x1e36,
+ 0x3127, 0x0410,
+ 0x3128, 0x1e38,
+ 0x3129, 0x0412,
+ 0x312b, 0x1e39,
+ 0x312c, 0x0415,
+ 0x3132, 0x1e3a,
+ 0x3133, 0x041c,
+ 0x3134, 0x1e3b,
+ 0x3136, 0x041f,
+ 0x3137, 0x1e3d,
+ 0x313a, 0x0423,
+ 0x3141, 0x1e40,
+ 0x3142, 0x042b,
+ 0x314a, 0x1e41,
+ 0x314b, 0x0434,
+ 0x314f, 0x1e42,
+ 0x3151, 0x043a,
+ 0x3152, 0x1e44,
+ 0x3153, 0x043c,
+ 0x3155, 0x1e45,
+ 0x3156, 0x043f,
+ 0x315f, 0x1e46,
+ 0x3162, 0x044b,
+ 0x3164, 0x1e49,
+ 0x3165, 0x044e,
+ 0x3167, 0x1e4a,
+ 0x3169, 0x0452,
+ 0x316a, 0x1e4c,
+ 0x316b, 0x0454,
+ 0x316e, 0x1e4d,
+ 0x316f, 0x0458,
+ 0x3171, 0x1e4e,
+ 0x3172, 0x045b,
+ 0x3174, 0x1e4f,
+ 0x3178, 0x0461,
+ 0x317d, 0x1e53,
+ 0x317e, 0x0467,
+ 0x3221, 0x0468,
+ 0x3226, 0x1e54,
+ 0x3228, 0x046f,
+ 0x322c, 0x1e56,
+ 0x322d, 0x0474,
+ 0x3235, 0x1e57,
+ 0x3236, 0x047d,
+ 0x3239, 0x1e58,
+ 0x323a, 0x0481,
+ 0x3246, 0x1e59,
+ 0x3247, 0x048e,
+ 0x324e, 0x1e5a,
+ 0x3258, 0x049f,
+ 0x325e, 0x1e64,
+ 0x325f, 0x04a6,
+ 0x3260, 0x1e65,
+ 0x3261, 0x04a8,
+ 0x3262, 0x1e66,
+ 0x3264, 0x04ab,
+ 0x326f, 0x1e68,
+ 0x3270, 0x04b7,
+ 0x3273, 0x1e69,
+ 0x327d, 0x04c4,
+ 0x3321, 0x1e73,
+ 0x3323, 0x04c8,
+ 0x3324, 0x1e75,
+ 0x3328, 0x04cd,
+ 0x3329, 0x1e79,
+ 0x332a, 0x04cf,
+ 0x332e, 0x1e7a,
+ 0x332f, 0x04d4,
+ 0x3335, 0x1e7b,
+ 0x3336, 0x04db,
+ 0x3339, 0x1e7c,
+ 0x333a, 0x04df,
+ 0x333e, 0x1e7d,
+ 0x333f, 0x04e4,
+ 0x3342, 0x1e7e,
+ 0x3343, 0x04e8,
+ 0x3344, 0x1e7f,
+ 0x3345, 0x04ea,
+ 0x3346, 0x1e80,
+ 0x3347, 0x04ec,
+ 0x334d, 0x1e81,
+ 0x334e, 0x04f3,
+ 0x334f, 0x1e82,
+ 0x3350, 0x04f5,
+ 0x3352, 0x1e83,
+ 0x3353, 0x04f8,
+ 0x3359, 0x1e84,
+ 0x335a, 0x04ff,
+ 0x335b, 0x1e85,
+ 0x335c, 0x0501,
+ 0x335d, 0x1e86,
+ 0x335e, 0x0503,
+ 0x3363, 0x1e87,
+ 0x3364, 0x0509,
+ 0x3365, 0x1e88,
+ 0x3367, 0x050c,
+ 0x3368, 0x1e8a,
+ 0x3369, 0x050e,
+ 0x336b, 0x1e8b,
+ 0x336d, 0x0512,
+ 0x336f, 0x1e8d,
+ 0x3370, 0x0515,
+ 0x3371, 0x1e8e,
+ 0x3372, 0x0517,
+ 0x3373, 0x1e8f,
+ 0x3374, 0x0519,
+ 0x337a, 0x1e90,
+ 0x337c, 0x0521,
+ 0x3421, 0x1e92,
+ 0x3423, 0x0526,
+ 0x3425, 0x1e94,
+ 0x3427, 0x052a,
+ 0x342b, 0x1e96,
+ 0x342c, 0x052f,
+ 0x342f, 0x1e97,
+ 0x3430, 0x0533,
+ 0x3433, 0x1e98,
+ 0x3435, 0x0538,
+ 0x3438, 0x1e9a,
+ 0x3439, 0x053c,
+ 0x343f, 0x1e9b,
+ 0x3440, 0x0543,
+ 0x3442, 0x1e9c,
+ 0x3443, 0x0546,
+ 0x3447, 0x1e9d,
+ 0x3448, 0x054b,
+ 0x344a, 0x1e9e,
+ 0x344b, 0x054e,
+ 0x344d, 0x1e9f,
+ 0x344e, 0x0551,
+ 0x344f, 0x1ea0,
+ 0x3450, 0x0553,
+ 0x3453, 0x1ea1,
+ 0x3455, 0x0558,
+ 0x345a, 0x1ea3,
+ 0x345b, 0x055e,
+ 0x345c, 0x1ea4,
+ 0x345d, 0x0560,
+ 0x346d, 0x1ea5,
+ 0x346e, 0x0571,
+ 0x346f, 0x1ea6,
+ 0x3470, 0x0573,
+ 0x3478, 0x1ea7,
+ 0x3479, 0x057c,
+ 0x347b, 0x1ea8,
+ 0x347c, 0x057f,
+ 0x3521, 0x0582,
+ 0x3523, 0x1ea9,
+ 0x3524, 0x0585,
+ 0x3525, 0x1eaa,
+ 0x3529, 0x058a,
+ 0x352c, 0x1eae,
+ 0x352d, 0x058e,
+ 0x352e, 0x1eaf,
+ 0x3530, 0x0591,
+ 0x3531, 0x1eb1,
+ 0x3536, 0x0597,
+ 0x3537, 0x1eb6,
+ 0x3538, 0x0599,
+ 0x353a, 0x1eb7,
+ 0x353d, 0x059e,
+ 0x3546, 0x1eba,
+ 0x3547, 0x05a8,
+ 0x354b, 0x1ebb,
+ 0x354c, 0x05ad,
+ 0x3550, 0x1ebc,
+ 0x3551, 0x05b2,
+ 0x3553, 0x1ebd,
+ 0x3554, 0x05b5,
+ 0x355d, 0x1ebe,
+ 0x3560, 0x05c1,
+ 0x3563, 0x1ec1,
+ 0x3564, 0x05c5,
+ 0x3566, 0x1ec2,
+ 0x3568, 0x05c9,
+ 0x356d, 0x1ec4,
+ 0x356e, 0x05cf,
+ 0x3576, 0x1ec5,
+ 0x3578, 0x05d9,
+ 0x357d, 0x1ec7,
+ 0x357e, 0x05df,
+ 0x3621, 0x05e0,
+ 0x3624, 0x1ec8,
+ 0x3626, 0x05e5,
+ 0x3627, 0x1eca,
+ 0x3628, 0x05e7,
+ 0x3629, 0x1ecb,
+ 0x362a, 0x05e9,
+ 0x362b, 0x1ecc,
+ 0x362c, 0x05eb,
+ 0x362f, 0x1ecd,
+ 0x3631, 0x05f0,
+ 0x3633, 0x1ecf,
+ 0x3634, 0x05f3,
+ 0x3637, 0x1ed0,
+ 0x3638, 0x05f7,
+ 0x363f, 0x1ed1,
+ 0x3642, 0x0601,
+ 0x3644, 0x1ed4,
+ 0x3645, 0x0604,
+ 0x3646, 0x1ed5,
+ 0x3647, 0x0606,
+ 0x364d, 0x1ed6,
+ 0x364e, 0x060d,
+ 0x364f, 0x1ed7,
+ 0x3651, 0x0610,
+ 0x3653, 0x1ed9,
+ 0x3655, 0x0614,
+ 0x3656, 0x1edb,
+ 0x3657, 0x0616,
+ 0x3659, 0x1edc,
+ 0x365a, 0x0619,
+ 0x365b, 0x1edd,
+ 0x365c, 0x061b,
+ 0x3661, 0x1ede,
+ 0x3662, 0x0621,
+ 0x3669, 0x1edf,
+ 0x366a, 0x0629,
+ 0x366c, 0x1ee0,
+ 0x366d, 0x062c,
+ 0x366e, 0x1ee1,
+ 0x3670, 0x062f,
+ 0x3671, 0x1ee3,
+ 0x3672, 0x0631,
+ 0x3676, 0x1ee4,
+ 0x3677, 0x0636,
+ 0x3679, 0x1ee5,
+ 0x367a, 0x0639,
+ 0x367b, 0x1ee6,
+ 0x367d, 0x063c,
+ 0x3721, 0x1ee8,
+ 0x3724, 0x0641,
+ 0x3727, 0x1eeb,
+ 0x3728, 0x0645,
+ 0x372f, 0x1eec,
+ 0x3731, 0x064e,
+ 0x3733, 0x1eee,
+ 0x3734, 0x0651,
+ 0x3736, 0x1eef,
+ 0x3738, 0x0655,
+ 0x3739, 0x1ef1,
+ 0x373a, 0x0657,
+ 0x3743, 0x1ef2,
+ 0x3745, 0x0662,
+ 0x3749, 0x1ef4,
+ 0x374a, 0x0667,
+ 0x374c, 0x1ef5,
+ 0x374d, 0x066a,
+ 0x374f, 0x1ef6,
+ 0x3750, 0x066d,
+ 0x3751, 0x1ef7,
+ 0x3752, 0x066f,
+ 0x3757, 0x1ef8,
+ 0x3759, 0x0676,
+ 0x375c, 0x1efa,
+ 0x375d, 0x067a,
+ 0x375f, 0x1efb,
+ 0x3762, 0x067f,
+ 0x3763, 0x1efe,
+ 0x3764, 0x0681,
+ 0x3766, 0x1eff,
+ 0x3769, 0x0686,
+ 0x376b, 0x1f02,
+ 0x376e, 0x068b,
+ 0x376f, 0x1f05,
+ 0x3770, 0x068d,
+ 0x3774, 0x1f06,
+ 0x3775, 0x0692,
+ 0x3778, 0x1f07,
+ 0x3779, 0x0696,
+ 0x3821, 0x069c,
+ 0x3827, 0x1f08,
+ 0x3829, 0x06a4,
+ 0x3833, 0x1f0a,
+ 0x3835, 0x06b0,
+ 0x383a, 0x1f0c,
+ 0x383b, 0x06b6,
+ 0x383c, 0x1f0d,
+ 0x383d, 0x06b8,
+ 0x383e, 0x1f0e,
+ 0x3840, 0x06bb,
+ 0x3843, 0x1f10,
+ 0x3844, 0x06bf,
+ 0x3846, 0x1f11,
+ 0x3848, 0x06c3,
+ 0x3849, 0x1f13,
+ 0x384a, 0x06c5,
+ 0x384f, 0x1f14,
+ 0x3850, 0x06cb,
+ 0x3853, 0x1f15,
+ 0x3857, 0x06d2,
+ 0x3859, 0x1f19,
+ 0x385b, 0x06d6,
+ 0x3864, 0x1f1b,
+ 0x3865, 0x06e0,
+ 0x3869, 0x1f1c,
+ 0x386a, 0x06e5,
+ 0x386b, 0x1f1d,
+ 0x386c, 0x06e7,
+ 0x3873, 0x1f1e,
+ 0x3874, 0x06ef,
+ 0x3875, 0x1f1f,
+ 0x3877, 0x06f2,
+ 0x3878, 0x1f21,
+ 0x3879, 0x06f4,
+ 0x3921, 0x06fa,
+ 0x3928, 0x1f22,
+ 0x3929, 0x0702,
+ 0x392e, 0x1f23,
+ 0x392f, 0x0708,
+ 0x3931, 0x1f24,
+ 0x3932, 0x070b,
+ 0x3933, 0x1f25,
+ 0x3934, 0x070d,
+ 0x3935, 0x1f26,
+ 0x3936, 0x070f,
+ 0x3939, 0x1f27,
+ 0x393b, 0x0714,
+ 0x3946, 0x1f29,
+ 0x3947, 0x0720,
+ 0x394b, 0x1f2a,
+ 0x394c, 0x0725,
+ 0x3950, 0x1f2b,
+ 0x3951, 0x072a,
+ 0x3958, 0x1f2c,
+ 0x3959, 0x0732,
+ 0x395b, 0x1f2d,
+ 0x395c, 0x0735,
+ 0x395d, 0x1f2e,
+ 0x395e, 0x0737,
+ 0x395f, 0x1f2f,
+ 0x3960, 0x0739,
+ 0x3961, 0x1f30,
+ 0x3962, 0x073b,
+ 0x3963, 0x1f31,
+ 0x3964, 0x073d,
+ 0x3966, 0x1f32,
+ 0x3967, 0x0740,
+ 0x3969, 0x1f33,
+ 0x396d, 0x0746,
+ 0x396e, 0x1f37,
+ 0x396f, 0x0748,
+ 0x3971, 0x1f38,
+ 0x3972, 0x074b,
+ 0x3973, 0x1f39,
+ 0x3976, 0x074f,
+ 0x3978, 0x1f3c,
+ 0x3979, 0x0752,
+ 0x397a, 0x1f3d,
+ 0x397b, 0x0754,
+ 0x397d, 0x1f3e,
+ 0x397e, 0x0757,
+ 0x3a21, 0x0758,
+ 0x3a27, 0x1f3f,
+ 0x3a28, 0x075f,
+ 0x3a2b, 0x1f40,
+ 0x3a2c, 0x0763,
+ 0x3a3a, 0x1f41,
+ 0x3a3b, 0x0772,
+ 0x3a45, 0x1f42,
+ 0x3a46, 0x077d,
+ 0x3a52, 0x1f43,
+ 0x3a53, 0x078a,
+ 0x3a57, 0x1f44,
+ 0x3a59, 0x0790,
+ 0x3a64, 0x1f46,
+ 0x3a65, 0x079c,
+ 0x3a68, 0x1f47,
+ 0x3a69, 0x07a0,
+ 0x3a6c, 0x1f48,
+ 0x3a6d, 0x07a4,
+ 0x3a73, 0x15e5,
+ 0x3a74, 0x07ab,
+ 0x3a78, 0x1f49,
+ 0x3a79, 0x07b0,
+ 0x3b21, 0x07b6,
+ 0x3b24, 0x1f4a,
+ 0x3b25, 0x07ba,
+ 0x3b26, 0x1f4b,
+ 0x3b27, 0x07bc,
+ 0x3b29, 0x1f4c,
+ 0x3b2b, 0x07c0,
+ 0x3b2d, 0x1f4e,
+ 0x3b2f, 0x07c4,
+ 0x3b30, 0x1f50,
+ 0x3b31, 0x07c6,
+ 0x3b33, 0x1f51,
+ 0x3b34, 0x07c9,
+ 0x3b35, 0x1f52,
+ 0x3b38, 0x07cd,
+ 0x3b39, 0x1f55,
+ 0x3b3b, 0x07d0,
+ 0x3b51, 0x1f57,
+ 0x3b52, 0x07e7,
+ 0x3b53, 0x1f58,
+ 0x3b55, 0x07ea,
+ 0x3b5f, 0x1f5a,
+ 0x3b68, 0x07fd,
+ 0x3b6b, 0x1f63,
+ 0x3b6c, 0x0801,
+ 0x3b71, 0x1f64,
+ 0x3b72, 0x0807,
+ 0x3b75, 0x1f65,
+ 0x3b78, 0x080d,
+ 0x3b7a, 0x1f68,
+ 0x3b7b, 0x0810,
+ 0x3b7d, 0x1f69,
+ 0x3b7e, 0x0813,
+ 0x3c21, 0x0814,
+ 0x3c22, 0x1f6a,
+ 0x3c23, 0x0816,
+ 0x3c25, 0x1f6b,
+ 0x3c27, 0x081a,
+ 0x3c28, 0x1f6d,
+ 0x3c2a, 0x081d,
+ 0x3c2b, 0x1f6f,
+ 0x3c2c, 0x081f,
+ 0x3c2d, 0x1f70,
+ 0x3c2e, 0x0821,
+ 0x3c36, 0x1f71,
+ 0x3c39, 0x082c,
+ 0x3c3b, 0x1f74,
+ 0x3c3c, 0x082f,
+ 0x3c41, 0x1f75,
+ 0x3c42, 0x0835,
+ 0x3c43, 0x1f76,
+ 0x3c44, 0x0837,
+ 0x3c46, 0x1f77,
+ 0x3c48, 0x083b,
+ 0x3c4a, 0x1f79,
+ 0x3c4b, 0x083e,
+ 0x3c4c, 0x1f7a,
+ 0x3c4e, 0x0841,
+ 0x3c50, 0x1f7c,
+ 0x3c51, 0x0844,
+ 0x3c54, 0x1f7d,
+ 0x3c57, 0x084a,
+ 0x3c58, 0x1f80,
+ 0x3c59, 0x084c,
+ 0x3c5b, 0x1f81,
+ 0x3c5c, 0x084f,
+ 0x3c5d, 0x1f82,
+ 0x3c5e, 0x0851,
+ 0x3c5f, 0x1f83,
+ 0x3c62, 0x0855,
+ 0x3c63, 0x1f86,
+ 0x3c65, 0x0858,
+ 0x3c68, 0x1f88,
+ 0x3c69, 0x085c,
+ 0x3c6a, 0x1f89,
+ 0x3c6d, 0x0860,
+ 0x3c6f, 0x1f8c,
+ 0x3c74, 0x0867,
+ 0x3c76, 0x1f91,
+ 0x3c7d, 0x0870,
+ 0x3d21, 0x0872,
+ 0x3d22, 0x1f98,
+ 0x3d28, 0x0879,
+ 0x3d2b, 0x1f9e,
+ 0x3d2d, 0x087e,
+ 0x3d2f, 0x1fa0,
+ 0x3d33, 0x0884,
+ 0x3d34, 0x1fa4,
+ 0x3d35, 0x0886,
+ 0x3d3a, 0x1fa5,
+ 0x3d3b, 0x088c,
+ 0x3d3d, 0x1fa6,
+ 0x3d40, 0x0891,
+ 0x3d41, 0x1fa9,
+ 0x3d45, 0x0896,
+ 0x3d48, 0x1fad,
+ 0x3d4b, 0x089c,
+ 0x3d4e, 0x1fb0,
+ 0x3d50, 0x08a1,
+ 0x3d57, 0x1fb2,
+ 0x3d58, 0x08a9,
+ 0x3d5a, 0x1fb3,
+ 0x3d5b, 0x08ac,
+ 0x3d60, 0x1fb4,
+ 0x3d62, 0x08b3,
+ 0x3d6b, 0x1fb6,
+ 0x3d6c, 0x08bd,
+ 0x3d74, 0x1fb7,
+ 0x3d79, 0x08ca,
+ 0x3d7d, 0x1fbc,
+ 0x3d7e, 0x08cf,
+ 0x3e21, 0x1fbd,
+ 0x3e23, 0x08d2,
+ 0x3e25, 0x1fbf,
+ 0x3e26, 0x08d5,
+ 0x3e28, 0x1fc0,
+ 0x3e29, 0x08d8,
+ 0x3e2a, 0x1fc1,
+ 0x3e2b, 0x08da,
+ 0x3e2d, 0x1fc2,
+ 0x3e2e, 0x08dd,
+ 0x3e31, 0x1fc3,
+ 0x3e32, 0x08e1,
+ 0x3e35, 0x1fc4,
+ 0x3e38, 0x08e7,
+ 0x3e3a, 0x1fc7,
+ 0x3e3b, 0x08ea,
+ 0x3e40, 0x1fc8,
+ 0x3e41, 0x08f0,
+ 0x3e49, 0x1fc9,
+ 0x3e4a, 0x08f9,
+ 0x3e54, 0x1fca,
+ 0x3e55, 0x0904,
+ 0x3e59, 0x1fcb,
+ 0x3e5a, 0x0909,
+ 0x3e5d, 0x1fcc,
+ 0x3e5e, 0x090d,
+ 0x3e62, 0x1fcd,
+ 0x3e63, 0x0912,
+ 0x3e65, 0x1fce,
+ 0x3e66, 0x0915,
+ 0x3e67, 0x1fcf,
+ 0x3e68, 0x0917,
+ 0x3e69, 0x1fd0,
+ 0x3e6a, 0x0919,
+ 0x3e6e, 0x1fd1,
+ 0x3e6f, 0x091e,
+ 0x3e75, 0x1fd2,
+ 0x3e76, 0x0925,
+ 0x3e77, 0x1fd3,
+ 0x3e79, 0x0928,
+ 0x3e7b, 0x1fd5,
+ 0x3e7d, 0x092c,
+ 0x3f21, 0x092e,
+ 0x3f25, 0x1fd7,
+ 0x3f26, 0x0933,
+ 0x3f2a, 0x1fd8,
+ 0x3f2b, 0x0938,
+ 0x3f2d, 0x1fd9,
+ 0x3f2e, 0x093b,
+ 0x3f45, 0x1fda,
+ 0x3f46, 0x0953,
+ 0x3f47, 0x1fdb,
+ 0x3f48, 0x0955,
+ 0x3f4e, 0x1fdc,
+ 0x3f4f, 0x095c,
+ 0x3f51, 0x1fdd,
+ 0x3f53, 0x0960,
+ 0x3f59, 0x1fdf,
+ 0x3f5a, 0x0967,
+ 0x3f62, 0x1fe0,
+ 0x3f65, 0x0972,
+ 0x3f69, 0x1fe3,
+ 0x3f6a, 0x0977,
+ 0x3f6b, 0x1fe4,
+ 0x3f6c, 0x0979,
+ 0x3f6d, 0x1fe5,
+ 0x3f6e, 0x097b,
+ 0x3f73, 0x1fe6,
+ 0x3f74, 0x0981,
+ 0x3f75, 0x1fe7,
+ 0x3f76, 0x0983,
+ 0x3f77, 0x1fe8,
+ 0x3f78, 0x0985,
+ 0x3f79, 0x1fe9,
+ 0x3f7b, 0x0988,
+ 0x4021, 0x1feb,
+ 0x4022, 0x098d,
+ 0x4023, 0x1fec,
+ 0x4024, 0x098f,
+ 0x4029, 0x1fed,
+ 0x402a, 0x0995,
+ 0x402b, 0x1fee,
+ 0x402c, 0x0997,
+ 0x402f, 0x1fef,
+ 0x4031, 0x099c,
+ 0x4033, 0x1ff1,
+ 0x4037, 0x09a2,
+ 0x4038, 0x1ff5,
+ 0x4045, 0x09b0,
+ 0x404c, 0x2002,
+ 0x404e, 0x09b9,
+ 0x4054, 0x2004,
+ 0x4055, 0x09c0,
+ 0x4056, 0x2005,
+ 0x4057, 0x09c2,
+ 0x4058, 0x2006,
+ 0x4059, 0x09c4,
+ 0x405d, 0x2007,
+ 0x405e, 0x09c9,
+ 0x4060, 0x2008,
+ 0x4061, 0x09cc,
+ 0x4069, 0x2009,
+ 0x406a, 0x09d5,
+ 0x406b, 0x200a,
+ 0x406d, 0x09d8,
+ 0x406f, 0x200c,
+ 0x4072, 0x09dd,
+ 0x4076, 0x200f,
+ 0x407b, 0x09e6,
+ 0x4121, 0x09ea,
+ 0x4124, 0x2014,
+ 0x4126, 0x09ef,
+ 0x4129, 0x2016,
+ 0x412e, 0x09f7,
+ 0x412f, 0x201b,
+ 0x4139, 0x0a02,
+ 0x413d, 0x2025,
+ 0x413f, 0x0a08,
+ 0x4142, 0x2027,
+ 0x4143, 0x0a0c,
+ 0x4146, 0x2028,
+ 0x4147, 0x0a10,
+ 0x4149, 0x2029,
+ 0x414a, 0x0a13,
+ 0x414d, 0x202a,
+ 0x414e, 0x0a17,
+ 0x4154, 0x202b,
+ 0x4155, 0x0a1e,
+ 0x4159, 0x202c,
+ 0x415c, 0x0a25,
+ 0x415e, 0x202f,
+ 0x415f, 0x0a28,
+ 0x4164, 0x2030,
+ 0x4166, 0x0a2f,
+ 0x4169, 0x2032,
+ 0x416a, 0x0a33,
+ 0x416b, 0x2033,
+ 0x416d, 0x0a36,
+ 0x4173, 0x2035,
+ 0x4174, 0x0a3d,
+ 0x4175, 0x2036,
+ 0x4176, 0x0a3f,
+ 0x417a, 0x2037,
+ 0x417e, 0x0a47,
+ 0x4221, 0x0a48,
+ 0x4222, 0x203b,
+ 0x4229, 0x0a50,
+ 0x422b, 0x2042,
+ 0x4234, 0x0a5b,
+ 0x4238, 0x204b,
+ 0x4239, 0x0a60,
+ 0x423c, 0x204c,
+ 0x423e, 0x0a65,
+ 0x423f, 0x204e,
+ 0x4240, 0x0a67,
+ 0x4241, 0x204f,
+ 0x4242, 0x0a69,
+ 0x4245, 0x2050,
+ 0x4248, 0x0a6f,
+ 0x424b, 0x2053,
+ 0x4251, 0x0a78,
+ 0x4252, 0x2059,
+ 0x4253, 0x0a7a,
+ 0x4255, 0x205a,
+ 0x425d, 0x0a84,
+ 0x425e, 0x2062,
+ 0x4263, 0x0a8a,
+ 0x4266, 0x2067,
+ 0x4269, 0x0a90,
+ 0x426a, 0x206a,
+ 0x426f, 0x0a96,
+ 0x4270, 0x206f,
+ 0x4271, 0x0a98,
+ 0x4272, 0x2070,
+ 0x4276, 0x0a9d,
+ 0x4277, 0x2074,
+ 0x427b, 0x0aa2,
+ 0x4321, 0x2078,
+ 0x4322, 0x0aa7,
+ 0x432a, 0x2079,
+ 0x432b, 0x0ab0,
+ 0x432d, 0x207a,
+ 0x432e, 0x0ab3,
+ 0x4333, 0x207b,
+ 0x4334, 0x1df9,
+ 0x4335, 0x0aba,
+ 0x433e, 0x207c,
+ 0x433f, 0x0ac4,
+ 0x4345, 0x207d,
+ 0x4348, 0x0acd,
+ 0x434c, 0x2080,
+ 0x434d, 0x0ad2,
+ 0x434e, 0x2081,
+ 0x434f, 0x0ad4,
+ 0x4355, 0x2082,
+ 0x4357, 0x0adc,
+ 0x4359, 0x2084,
+ 0x435a, 0x0adf,
+ 0x4360, 0x2085,
+ 0x4361, 0x0ae6,
+ 0x4365, 0x2086,
+ 0x4366, 0x0aeb,
+ 0x436d, 0x2087,
+ 0x436e, 0x0af3,
+ 0x4370, 0x2088,
+ 0x4371, 0x0af6,
+ 0x4375, 0x2089,
+ 0x4377, 0x0afc,
+ 0x4379, 0x208b,
+ 0x437b, 0x0b00,
+ 0x437d, 0x208d,
+ 0x437e, 0x0b03,
+ 0x4421, 0x0b04,
+ 0x4431, 0x208e,
+ 0x4432, 0x0b15,
+ 0x4436, 0x208f,
+ 0x4437, 0x0b1a,
+ 0x4446, 0x2090,
+ 0x4447, 0x0b2a,
+ 0x4449, 0x2091,
+ 0x444a, 0x0b2d,
+ 0x4451, 0x2092,
+ 0x4452, 0x0b35,
+ 0x4453, 0x2093,
+ 0x4457, 0x0b3a,
+ 0x4459, 0x2097,
+ 0x445a, 0x0b3d,
+ 0x4462, 0x2098,
+ 0x4463, 0x0b46,
+ 0x4465, 0x2099,
+ 0x4466, 0x0b49,
+ 0x446c, 0x209a,
+ 0x446d, 0x0b50,
+ 0x4470, 0x209b,
+ 0x4472, 0x0b55,
+ 0x4474, 0x209d,
+ 0x4475, 0x0b58,
+ 0x4476, 0x209e,
+ 0x4479, 0x0b5c,
+ 0x447b, 0x20a1,
+ 0x447d, 0x0b60,
+ 0x447e, 0x20a3,
+ 0x4521, 0x20a4,
+ 0x4523, 0x0b64,
+ 0x4525, 0x20a6,
+ 0x452a, 0x0b6b,
+ 0x4531, 0x20ab,
+ 0x4532, 0x0b73,
+ 0x4535, 0x20ac,
+ 0x4536, 0x0b77,
+ 0x4537, 0x20ad,
+ 0x453a, 0x0b7b,
+ 0x453b, 0x20b0,
+ 0x453c, 0x0b7d,
+ 0x453d, 0x20b1,
+ 0x453e, 0x0b7f,
+ 0x454c, 0x20b2,
+ 0x454d, 0x0b8e,
+ 0x4553, 0x20b3,
+ 0x4554, 0x0b95,
+ 0x4562, 0x20b4,
+ 0x4563, 0x0ba4,
+ 0x4567, 0x20b5,
+ 0x4568, 0x0ba9,
+ 0x4574, 0x20b6,
+ 0x4575, 0x0bb6,
+ 0x4621, 0x0bc0,
+ 0x462d, 0x20b7,
+ 0x462f, 0x0bce,
+ 0x4635, 0x20b9,
+ 0x4637, 0x0bd6,
+ 0x463b, 0x20bb,
+ 0x463c, 0x0bdb,
+ 0x463e, 0x20bc,
+ 0x463f, 0x0bde,
+ 0x4640, 0x20bd,
+ 0x4641, 0x0be0,
+ 0x4643, 0x20be,
+ 0x4645, 0x0be4,
+ 0x464b, 0x20c0,
+ 0x464e, 0x0bed,
+ 0x4653, 0x20c3,
+ 0x4654, 0x0bf3,
+ 0x4657, 0x20c4,
+ 0x4658, 0x0bf7,
+ 0x466a, 0x20c5,
+ 0x466c, 0x0c0b,
+ 0x466f, 0x20c7,
+ 0x4670, 0x0c0f,
+ 0x4671, 0x20c8,
+ 0x4672, 0x0c11,
+ 0x4674, 0x20c9,
+ 0x4675, 0x0c14,
+ 0x4678, 0x20ca,
+ 0x4679, 0x0c18,
+ 0x467d, 0x20cb,
+ 0x467e, 0x0c1d,
+ 0x4721, 0x0c1e,
+ 0x4723, 0x20cc,
+ 0x4724, 0x0c21,
+ 0x4725, 0x20cd,
+ 0x4727, 0x0c24,
+ 0x4728, 0x20cf,
+ 0x472a, 0x0c27,
+ 0x472b, 0x20d1,
+ 0x472c, 0x0c29,
+ 0x472e, 0x20d2,
+ 0x4730, 0x0c2d,
+ 0x4733, 0x20d4,
+ 0x4736, 0x0c33,
+ 0x4739, 0x20d7,
+ 0x473b, 0x0c38,
+ 0x473d, 0x20d9,
+ 0x473f, 0x0c3c,
+ 0x4740, 0x20db,
+ 0x4741, 0x0c3e,
+ 0x4742, 0x20dc,
+ 0x4743, 0x0c40,
+ 0x4745, 0x20dd,
+ 0x4746, 0x0c43,
+ 0x4747, 0x20de,
+ 0x4749, 0x0c46,
+ 0x474c, 0x20e0,
+ 0x474d, 0x0c4a,
+ 0x474f, 0x20e1,
+ 0x4750, 0x0c4d,
+ 0x4754, 0x20e2,
+ 0x4756, 0x0c53,
+ 0x4757, 0x20e4,
+ 0x4758, 0x0c55,
+ 0x475e, 0x20e5,
+ 0x475f, 0x0c5c,
+ 0x4761, 0x20e6,
+ 0x4764, 0x0c61,
+ 0x476a, 0x20e9,
+ 0x476f, 0x0c6c,
+ 0x4777, 0x20ee,
+ 0x4779, 0x0c76,
+ 0x477b, 0x20f0,
+ 0x477c, 0x0c79,
+ 0x477d, 0x20f1,
+ 0x477e, 0x0c7b,
+ 0x4821, 0x0c7c,
+ 0x4823, 0x20f2,
+ 0x4824, 0x0c7f,
+ 0x4827, 0x20f3,
+ 0x4829, 0x0c84,
+ 0x4830, 0x20f5,
+ 0x4831, 0x0c8c,
+ 0x4835, 0x20f6,
+ 0x4836, 0x0c91,
+ 0x4837, 0x20f7,
+ 0x4838, 0x0c93,
+ 0x4843, 0x20f8,
+ 0x4847, 0x0ca2,
+ 0x4848, 0x20fc,
+ 0x4849, 0x0ca4,
+ 0x484d, 0x20fd,
+ 0x484e, 0x0ca9,
+ 0x484f, 0x20fe,
+ 0x4850, 0x0cab,
+ 0x4852, 0x20ff,
+ 0x4853, 0x0cae,
+ 0x4859, 0x2100,
+ 0x485a, 0x0cb5,
+ 0x485e, 0x2101,
+ 0x485f, 0x0cba,
+ 0x486d, 0x2102,
+ 0x486e, 0x0cc9,
+ 0x4871, 0x2103,
+ 0x4874, 0x0ccf,
+ 0x4877, 0x2106,
+ 0x4879, 0x0cd4,
+ 0x487a, 0x2108,
+ 0x487b, 0x0cd6,
+ 0x487c, 0x2109,
+ 0x487d, 0x0cd8,
+ 0x4921, 0x210a,
+ 0x4922, 0x0cdb,
+ 0x4925, 0x210b,
+ 0x4926, 0x0cdf,
+ 0x4927, 0x210c,
+ 0x4929, 0x0ce2,
+ 0x492c, 0x210e,
+ 0x492d, 0x0ce6,
+ 0x4931, 0x210f,
+ 0x4932, 0x0ceb,
+ 0x4934, 0x2110,
+ 0x4935, 0x0cee,
+ 0x4938, 0x2111,
+ 0x493a, 0x0cf3,
+ 0x4941, 0x2113,
+ 0x4943, 0x0cfc,
+ 0x4944, 0x2115,
+ 0x4945, 0x0cfe,
+ 0x4949, 0x2116,
+ 0x494a, 0x0d03,
+ 0x494b, 0x2117,
+ 0x494c, 0x0d05,
+ 0x494d, 0x2118,
+ 0x494e, 0x0d07,
+ 0x4955, 0x2119,
+ 0x4956, 0x0d0f,
+ 0x495c, 0x211a,
+ 0x495d, 0x0d16,
+ 0x495e, 0x211b,
+ 0x495f, 0x0d18,
+ 0x4961, 0x211c,
+ 0x4962, 0x0d1b,
+ 0x4963, 0x211d,
+ 0x4964, 0x0d1d,
+ 0x4965, 0x211e,
+ 0x4966, 0x0d1f,
+ 0x4968, 0x211f,
+ 0x4969, 0x0d22,
+ 0x4970, 0x2120,
+ 0x4971, 0x0d2a,
+ 0x4973, 0x2121,
+ 0x4975, 0x0d2e,
+ 0x4976, 0x2123,
+ 0x4977, 0x0d30,
+ 0x4978, 0x2124,
+ 0x497a, 0x0d33,
+ 0x497e, 0x2126,
+ 0x4a21, 0x0d38,
+ 0x4a24, 0x2127,
+ 0x4a27, 0x0d3e,
+ 0x4a28, 0x212a,
+ 0x4a29, 0x0d40,
+ 0x4a2a, 0x212b,
+ 0x4a2c, 0x0d43,
+ 0x4a31, 0x212d,
+ 0x4a32, 0x0d49,
+ 0x4a34, 0x212e,
+ 0x4a37, 0x0d4e,
+ 0x4a3b, 0x2131,
+ 0x4a3c, 0x0d53,
+ 0x4a46, 0x2132,
+ 0x4a47, 0x0d5e,
+ 0x4a4a, 0x2133,
+ 0x4a4b, 0x0d62,
+ 0x4a4d, 0x2134,
+ 0x4a4f, 0x0d66,
+ 0x4a53, 0x2136,
+ 0x4a55, 0x0d6c,
+ 0x4a59, 0x2138,
+ 0x4a5a, 0x0d71,
+ 0x4a5e, 0x2139,
+ 0x4a5f, 0x0d76,
+ 0x4a60, 0x213a,
+ 0x4a61, 0x0d78,
+ 0x4a64, 0x213b,
+ 0x4a65, 0x0d7c,
+ 0x4a69, 0x213c,
+ 0x4a6b, 0x0d82,
+ 0x4a74, 0x213e,
+ 0x4a76, 0x0d8d,
+ 0x4a77, 0x2140,
+ 0x4a78, 0x0d8f,
+ 0x4a7a, 0x2141,
+ 0x4a7b, 0x0d92,
+ 0x4a7d, 0x2142,
+ 0x4a7e, 0x0d95,
+ 0x4b21, 0x0d96,
+ 0x4b27, 0x2143,
+ 0x4b28, 0x0d9d,
+ 0x4b2b, 0x2144,
+ 0x4b2c, 0x0da1,
+ 0x4b2d, 0x2145,
+ 0x4b2e, 0x0da3,
+ 0x4b33, 0x2146,
+ 0x4b34, 0x0da9,
+ 0x4b35, 0x2147,
+ 0x4b37, 0x0dac,
+ 0x4b38, 0x2149,
+ 0x4b39, 0x0dae,
+ 0x4b3f, 0x214a,
+ 0x4b40, 0x0db5,
+ 0x4b47, 0x214b,
+ 0x4b48, 0x0dbd,
+ 0x4b49, 0x214c,
+ 0x4b4d, 0x0dc2,
+ 0x4b4f, 0x2150,
+ 0x4b51, 0x0dc6,
+ 0x4b53, 0x2152,
+ 0x4b54, 0x0dc9,
+ 0x4b55, 0x2153,
+ 0x4b56, 0x0dcb,
+ 0x4b5f, 0x2154,
+ 0x4b61, 0x0dd6,
+ 0x4b64, 0x2156,
+ 0x4b65, 0x0dda,
+ 0x4b66, 0x2157,
+ 0x4b68, 0x0ddd,
+ 0x4b6a, 0x2159,
+ 0x4b6b, 0x0de0,
+ 0x4b6f, 0x215a,
+ 0x4b71, 0x0de6,
+ 0x4b75, 0x215c,
+ 0x4b77, 0x0dec,
+ 0x4b78, 0x215e,
+ 0x4b79, 0x0dee,
+ 0x4c21, 0x215f,
+ 0x4c23, 0x0df6,
+ 0x4c28, 0x2161,
+ 0x4c29, 0x0dfc,
+ 0x4c2c, 0x2162,
+ 0x4c2d, 0x0e00,
+ 0x4c2f, 0x2163,
+ 0x4c34, 0x0e07,
+ 0x4c37, 0x2168,
+ 0x4c39, 0x0e0c,
+ 0x4c3e, 0x216a,
+ 0x4c3f, 0x0e12,
+ 0x4c40, 0x216b,
+ 0x4c41, 0x0e14,
+ 0x4c4c, 0x216c,
+ 0x4c4d, 0x0e20,
+ 0x4c4e, 0x216d,
+ 0x4c4f, 0x0e22,
+ 0x4c50, 0x216e,
+ 0x4c51, 0x0e24,
+ 0x4c56, 0x216f,
+ 0x4c57, 0x0e2a,
+ 0x4c5a, 0x2170,
+ 0x4c5b, 0x0e2e,
+ 0x4c5c, 0x2171,
+ 0x4c5d, 0x0e30,
+ 0x4c60, 0x2172,
+ 0x4c61, 0x0e34,
+ 0x4c62, 0x2173,
+ 0x4c63, 0x0e36,
+ 0x4c65, 0x2174,
+ 0x4c66, 0x0e39,
+ 0x4c75, 0x2175,
+ 0x4c76, 0x0e49,
+ 0x4c79, 0x2176,
+ 0x4c7b, 0x0e4e,
+ 0x4c7c, 0x2178,
+ 0x4d21, 0x0e52,
+ 0x4d2d, 0x217b,
+ 0x4d2e, 0x0e5f,
+ 0x4d33, 0x217c,
+ 0x4d34, 0x0e65,
+ 0x4d37, 0x217d,
+ 0x4d38, 0x0e69,
+ 0x4d3c, 0x217e,
+ 0x4d3d, 0x0e6e,
+ 0x4d3f, 0x217f,
+ 0x4d40, 0x0e71,
+ 0x4d45, 0x2180,
+ 0x4d46, 0x0e77,
+ 0x4d47, 0x2181,
+ 0x4d48, 0x0e79,
+ 0x4d52, 0x2182,
+ 0x4d53, 0x0e84,
+ 0x4d54, 0x2183,
+ 0x4d57, 0x0e88,
+ 0x4d5d, 0x2186,
+ 0x4d5e, 0x0e8f,
+ 0x4d60, 0x2187,
+ 0x4d61, 0x0e92,
+ 0x4d64, 0x2188,
+ 0x4d66, 0x0e97,
+ 0x4d67, 0x218a,
+ 0x4d68, 0x0e99,
+ 0x4d72, 0x218b,
+ 0x4d73, 0x0ea4,
+ 0x4d78, 0x218c,
+ 0x4d79, 0x0eaa,
+ 0x4e21, 0x0eb0,
+ 0x4e24, 0x218d,
+ 0x4e26, 0x0eb5,
+ 0x4e27, 0x218f,
+ 0x4e28, 0x0eb7,
+ 0x4e2a, 0x2190,
+ 0x4e2e, 0x0ebd,
+ 0x4e30, 0x2194,
+ 0x4e32, 0x0ec1,
+ 0x4e33, 0x2196,
+ 0x4e34, 0x0ec3,
+ 0x4e3d, 0x2197,
+ 0x4e3e, 0x0ecd,
+ 0x4e40, 0x2198,
+ 0x4e41, 0x0ed0,
+ 0x4e45, 0x2199,
+ 0x4e47, 0x0ed6,
+ 0x4e48, 0x219b,
+ 0x4e49, 0x0ed8,
+ 0x4e4a, 0x219c,
+ 0x4e4b, 0x0eda,
+ 0x4e4e, 0x219d,
+ 0x4e52, 0x0ee1,
+ 0x4e58, 0x21a1,
+ 0x4e5b, 0x0eea,
+ 0x4e5c, 0x21a4,
+ 0x4e5d, 0x0eec,
+ 0x4e5e, 0x21a5,
+ 0x4e60, 0x0eef,
+ 0x4e6b, 0x21a7,
+ 0x4e6c, 0x0efb,
+ 0x4e6d, 0x21a8,
+ 0x4e6e, 0x0efd,
+ 0x4e71, 0x21a9,
+ 0x4e72, 0x0f01,
+ 0x4e73, 0x21aa,
+ 0x4e74, 0x0f03,
+ 0x4e7d, 0x21ab,
+ 0x4f21, 0x0f0e,
+ 0x4f2e, 0x21ad,
+ 0x4f2f, 0x0f1c,
+ 0x4f30, 0x21ae,
+ 0x4f31, 0x0f1e,
+ 0x4f33, 0x21af,
+ 0x4f34, 0x0f21,
+ 0x4f37, 0x21b0,
+ 0x4f39, 0x0f26,
+ 0x4f3a, 0x21b2,
+ 0x4f3b, 0x0f28,
+ 0x4f3d, 0x21b3,
+ 0x4f3e, 0x0f2b,
+ 0x4f3f, 0x21b4,
+ 0x4f42, 0x0f2f,
+ 0x4f45, 0x21b7,
+ 0x4f46, 0x0f33,
+ 0x4f47, 0x21b8,
+ 0x4f48, 0x0f35,
+ 0x4f4a, 0x21b9,
+ 0x4f4c, 0x0f39,
+ 0x4f4d, 0x21bb,
+ 0x4f4f, 0x0f3c,
+ 0x4f50, 0x21bd,
+ 0x4f51, 0x0f3e,
+ 0x4f54, 0x21be,
+ 0x4f59, 0x0f46,
+ 0x4f5a, 0x21c3,
+ 0x4f5b, 0x0f48,
+ 0x4f5c, 0x21c4,
+ 0x4f5d, 0x0f4a,
+ 0x4f5f, 0x21c5,
+ 0x4f60, 0x0f4d,
+ 0x4f62, 0x21c6,
+ 0x4f63, 0x0f50,
+ 0x4f67, 0x21c7,
+ 0x4f68, 0x0f55,
+ 0x4f6a, 0x21c8,
+ 0x4f6b, 0x0f58,
+ 0x4f6c, 0x21c9,
+ 0x4f6d, 0x0f5a,
+ 0x4f6e, 0x21ca,
+ 0x4f6f, 0x0f5c,
+ 0x4f74, 0x21cb,
+ 0x4f75, 0x0f62,
+ 0x4f79, 0x21cc,
+ 0x4f7b, 0x0f68,
+ 0x4f7e, 0x21ce,
+ 0x5021, 0x0f6c,
+ 0x5025, 0x21cf,
+ 0x5026, 0x0f71,
+ 0x502d, 0x21d0,
+ 0x502f, 0x0f7a,
+ 0x5032, 0x21d2,
+ 0x5035, 0x0f80,
+ 0x503a, 0x21d5,
+ 0x503c, 0x0f87,
+ 0x503f, 0x21d7,
+ 0x5040, 0x0f8b,
+ 0x5046, 0x21d8,
+ 0x5047, 0x0f92,
+ 0x504b, 0x21d9,
+ 0x504c, 0x0f97,
+ 0x5062, 0x21da,
+ 0x5063, 0x0fae,
+ 0x5065, 0x21db,
+ 0x5066, 0x0fb1,
+ 0x506b, 0x21dc,
+ 0x506c, 0x0fb7,
+ 0x506d, 0x21dd,
+ 0x506e, 0x0fb9,
+ 0x5077, 0x21de,
+ 0x507a, 0x0fc5,
+ 0x507c, 0x21e1,
+ 0x507d, 0x0fc8,
+ 0x5121, 0x21e2,
+ 0x5123, 0x0fcc,
+ 0x5124, 0x21e4,
+ 0x5125, 0x0fce,
+ 0x5127, 0x21e5,
+ 0x5128, 0x0fd1,
+ 0x512b, 0x21e6,
+ 0x512c, 0x0fd5,
+ 0x512f, 0x21e7,
+ 0x5132, 0x0fdb,
+ 0x5135, 0x21ea,
+ 0x5138, 0x0fe1,
+ 0x5139, 0x21ed,
+ 0x513a, 0x0fe3,
+ 0x513b, 0x21ee,
+ 0x513d, 0x0fe6,
+ 0x5146, 0x21f0,
+ 0x5149, 0x0ff2,
+ 0x514b, 0x21f3,
+ 0x514c, 0x0ff5,
+ 0x514e, 0x21f4,
+ 0x5150, 0x0ff9,
+ 0x5155, 0x21f6,
+ 0x5157, 0x1000,
+ 0x515e, 0x21f8,
+ 0x515f, 0x1008,
+ 0x5161, 0x21f9,
+ 0x5163, 0x100c,
+ 0x5168, 0x21fb,
+ 0x516a, 0x1013,
+ 0x516c, 0x21fd,
+ 0x516d, 0x1016,
+ 0x516e, 0x21fe,
+ 0x5170, 0x1019,
+ 0x5171, 0x2200,
+ 0x5172, 0x101b,
+ 0x5174, 0x2201,
+ 0x5175, 0x101e,
+ 0x5177, 0x2202,
+ 0x517a, 0x1023,
+ 0x5221, 0x1028,
+ 0x5222, 0x2205,
+ 0x5223, 0x102a,
+ 0x5225, 0x2206,
+ 0x5226, 0x102d,
+ 0x5229, 0x2207,
+ 0x522a, 0x1031,
+ 0x522f, 0x2208,
+ 0x5230, 0x1037,
+ 0x5233, 0x2209,
+ 0x5234, 0x103b,
+ 0x5235, 0x220a,
+ 0x5237, 0x103e,
+ 0x523d, 0x220c,
+ 0x523e, 0x1045,
+ 0x523f, 0x220d,
+ 0x5240, 0x1047,
+ 0x5243, 0x220e,
+ 0x5244, 0x104b,
+ 0x5245, 0x220f,
+ 0x5246, 0x104d,
+ 0x5247, 0x2210,
+ 0x5248, 0x104f,
+ 0x524f, 0x2211,
+ 0x5250, 0x1057,
+ 0x5255, 0x2212,
+ 0x5256, 0x105d,
+ 0x525a, 0x2213,
+ 0x525b, 0x1062,
+ 0x5264, 0x2214,
+ 0x5266, 0x106d,
+ 0x5268, 0x2216,
+ 0x526c, 0x1073,
+ 0x526f, 0x221a,
+ 0x5270, 0x1077,
+ 0x5271, 0x221b,
+ 0x5272, 0x1079,
+ 0x5275, 0x221c,
+ 0x5276, 0x107d,
+ 0x5278, 0x221d,
+ 0x5279, 0x1080,
+ 0x527b, 0x221e,
+ 0x527c, 0x1083,
+ 0x527e, 0x221f,
+ 0x5321, 0x1086,
+ 0x5323, 0x2220,
+ 0x532d, 0x1092,
+ 0x532e, 0x222a,
+ 0x532f, 0x1094,
+ 0x5331, 0x222b,
+ 0x5332, 0x1097,
+ 0x5334, 0x222c,
+ 0x5337, 0x109c,
+ 0x5338, 0x222f,
+ 0x5339, 0x109e,
+ 0x533b, 0x2230,
+ 0x533c, 0x10a1,
+ 0x5345, 0x2231,
+ 0x5346, 0x10ab,
+ 0x5347, 0x2232,
+ 0x5348, 0x10ad,
+ 0x534a, 0x2233,
+ 0x534d, 0x10b2,
+ 0x5355, 0x2236,
+ 0x5356, 0x10bb,
+ 0x535f, 0x2237,
+ 0x5361, 0x10c6,
+ 0x5363, 0x2239,
+ 0x5364, 0x10c9,
+ 0x5366, 0x223a,
+ 0x5367, 0x10cc,
+ 0x536b, 0x223b,
+ 0x536d, 0x10d2,
+ 0x536f, 0x223d,
+ 0x5370, 0x10d5,
+ 0x5374, 0x223e,
+ 0x5375, 0x10da,
+ 0x537c, 0x223f,
+ 0x537d, 0x10e2,
+ 0x537e, 0x2240,
+ 0x5421, 0x10e4,
+ 0x5424, 0x2241,
+ 0x5425, 0x10e8,
+ 0x5426, 0x2242,
+ 0x5429, 0x10ec,
+ 0x542f, 0x2245,
+ 0x5433, 0x10f6,
+ 0x5435, 0x2249,
+ 0x5437, 0x10fa,
+ 0x5438, 0x224b,
+ 0x5439, 0x10fc,
+ 0x543c, 0x224c,
+ 0x543d, 0x1100,
+ 0x543e, 0x224d,
+ 0x5440, 0x1103,
+ 0x5444, 0x224f,
+ 0x5445, 0x1108,
+ 0x5446, 0x2250,
+ 0x5448, 0x110b,
+ 0x5449, 0x2252,
+ 0x544a, 0x110d,
+ 0x544b, 0x2253,
+ 0x544f, 0x1112,
+ 0x5453, 0x2257,
+ 0x5454, 0x1117,
+ 0x5458, 0x2258,
+ 0x5459, 0x111c,
+ 0x545c, 0x2259,
+ 0x5461, 0x1124,
+ 0x5464, 0x225e,
+ 0x5465, 0x1128,
+ 0x5466, 0x225f,
+ 0x5467, 0x112a,
+ 0x546e, 0x2260,
+ 0x546f, 0x1132,
+ 0x5470, 0x2261,
+ 0x5475, 0x1138,
+ 0x5479, 0x2266,
+ 0x547a, 0x113d,
+ 0x547e, 0x2267,
+ 0x5521, 0x2268,
+ 0x5523, 0x1144,
+ 0x5529, 0x226a,
+ 0x552a, 0x114b,
+ 0x552b, 0x226b,
+ 0x552c, 0x114d,
+ 0x552e, 0x226c,
+ 0x552f, 0x1150,
+ 0x5531, 0x226d,
+ 0x5532, 0x1153,
+ 0x5535, 0x226e,
+ 0x5539, 0x115a,
+ 0x553b, 0x2272,
+ 0x553c, 0x115d,
+ 0x553d, 0x2273,
+ 0x553e, 0x115f,
+ 0x5540, 0x2274,
+ 0x5541, 0x1162,
+ 0x5545, 0x2275,
+ 0x5546, 0x1167,
+ 0x5547, 0x2276,
+ 0x5548, 0x1169,
+ 0x554a, 0x2277,
+ 0x554c, 0x116d,
+ 0x554d, 0x2279,
+ 0x554e, 0x116f,
+ 0x5554, 0x227a,
+ 0x5555, 0x1176,
+ 0x555d, 0x227b,
+ 0x555f, 0x1180,
+ 0x5560, 0x227d,
+ 0x5561, 0x1182,
+ 0x5562, 0x227e,
+ 0x5563, 0x1184,
+ 0x556a, 0x227f,
+ 0x556d, 0x118e,
+ 0x556f, 0x2282,
+ 0x5570, 0x1191,
+ 0x5572, 0x2283,
+ 0x5574, 0x1195,
+ 0x5577, 0x15eb,
+ 0x5578, 0x1199,
+ 0x5621, 0x2285,
+ 0x5625, 0x11a4,
+ 0x562f, 0x2289,
+ 0x5631, 0x11b0,
+ 0x5634, 0x228b,
+ 0x5635, 0x11b4,
+ 0x563b, 0x228c,
+ 0x563c, 0x11bb,
+ 0x563d, 0x228d,
+ 0x563e, 0x11bd,
+ 0x563f, 0x228e,
+ 0x5641, 0x11c0,
+ 0x5644, 0x2290,
+ 0x5645, 0x11c4,
+ 0x564a, 0x2291,
+ 0x564b, 0x11ca,
+ 0x564d, 0x2292,
+ 0x564e, 0x11cd,
+ 0x5653, 0x2293,
+ 0x5654, 0x11d3,
+ 0x5655, 0x2294,
+ 0x5658, 0x11d7,
+ 0x565a, 0x2297,
+ 0x565b, 0x11da,
+ 0x565f, 0x2298,
+ 0x5660, 0x11df,
+ 0x5661, 0x2299,
+ 0x5662, 0x11e1,
+ 0x5665, 0x229a,
+ 0x5666, 0x11e5,
+ 0x5667, 0x229b,
+ 0x5669, 0x11e8,
+ 0x566e, 0x229d,
+ 0x5670, 0x11ef,
+ 0x5672, 0x229f,
+ 0x5673, 0x11f2,
+ 0x5675, 0x22a0,
+ 0x5677, 0x11f6,
+ 0x567c, 0x22a2,
+ 0x5721, 0x11fe,
+ 0x5724, 0x22a5,
+ 0x5725, 0x1202,
+ 0x5728, 0x22a6,
+ 0x572b, 0x1208,
+ 0x572c, 0x22a9,
+ 0x572d, 0x120a,
+ 0x572e, 0x22aa,
+ 0x5732, 0x120f,
+ 0x5733, 0x22ae,
+ 0x5735, 0x1212,
+ 0x5736, 0x22b0,
+ 0x5737, 0x1214,
+ 0x5738, 0x22b1,
+ 0x573d, 0x121a,
+ 0x5747, 0x22b6,
+ 0x5748, 0x1225,
+ 0x574a, 0x22b7,
+ 0x574b, 0x1228,
+ 0x5755, 0x22b8,
+ 0x5756, 0x1233,
+ 0x575b, 0x22b9,
+ 0x575f, 0x123c,
+ 0x5767, 0x22bd,
+ 0x5768, 0x1245,
+ 0x5769, 0x22be,
+ 0x576b, 0x1248,
+ 0x5821, 0x1257,
+ 0x5844, 0x22c0,
+ 0x5845, 0x127b,
+ 0x5847, 0x22c1,
+ 0x5848, 0x127e,
+ 0x5849, 0x22c2,
+ 0x584a, 0x1280,
+ 0x584c, 0x22c3,
+ 0x584e, 0x1284,
+ 0x5850, 0x22c5,
+ 0x5852, 0x1288,
+ 0x5853, 0x22c7,
+ 0x5854, 0x128a,
+ 0x5859, 0x22c8,
+ 0x585a, 0x1290,
+ 0x585b, 0x22c9,
+ 0x585d, 0x1293,
+ 0x5871, 0x22cb,
+ 0x5872, 0x12a8,
+ 0x5876, 0x22cc,
+ 0x5878, 0x12ae,
+ 0x5921, 0x12b5,
+ 0x592d, 0x22ce,
+ 0x592e, 0x12c2,
+ 0x592f, 0x22cf,
+ 0x5930, 0x12c4,
+ 0x5931, 0x22d0,
+ 0x5934, 0x12c8,
+ 0x5947, 0x22d3,
+ 0x5948, 0x12dc,
+ 0x594d, 0x22d4,
+ 0x5951, 0x12e5,
+ 0x595d, 0x22d8,
+ 0x595e, 0x12f2,
+ 0x5961, 0x22d9,
+ 0x5962, 0x12f6,
+ 0x5964, 0x22da,
+ 0x5965, 0x12f9,
+ 0x5966, 0x22db,
+ 0x5967, 0x12fb,
+ 0x596c, 0x22dc,
+ 0x596d, 0x1301,
+ 0x5974, 0x22dd,
+ 0x5976, 0x130a,
+ 0x5a21, 0x1313,
+ 0x5a25, 0x22df,
+ 0x5a60, 0x1352,
+ 0x5a6a, 0x231a,
+ 0x5a6b, 0x135d,
+ 0x5a77, 0x231b,
+ 0x5a78, 0x136a,
+ 0x5a79, 0x231c,
+ 0x5a7a, 0x136c,
+ 0x5a7e, 0x231d,
+ 0x5b21, 0x1371,
+ 0x5b23, 0x231e,
+ 0x5b24, 0x1374,
+ 0x5b26, 0x231f,
+ 0x5b27, 0x1377,
+ 0x5b29, 0x2320,
+ 0x5b2b, 0x137b,
+ 0x5b3b, 0x2322,
+ 0x5b3c, 0x138c,
+ 0x5b3d, 0x2323,
+ 0x5b3e, 0x138e,
+ 0x5b4f, 0x2324,
+ 0x5b50, 0x13a0,
+ 0x5b51, 0x2325,
+ 0x5b52, 0x13a2,
+ 0x5b5b, 0x2326,
+ 0x5b5c, 0x13ac,
+ 0x5b5e, 0x2327,
+ 0x5b5f, 0x13af,
+ 0x5b62, 0x2328,
+ 0x5b63, 0x13b3,
+ 0x5b64, 0x2329,
+ 0x5b65, 0x13b5,
+ 0x5b6b, 0x232a,
+ 0x5b6c, 0x13bc,
+ 0x5b6e, 0x232b,
+ 0x5b6f, 0x13bf,
+ 0x5b71, 0x232c,
+ 0x5b72, 0x13c2,
+ 0x5b75, 0x232d,
+ 0x5b78, 0x13c8,
+ 0x5c21, 0x13cf,
+ 0x5c3c, 0x2330,
+ 0x5c3d, 0x13eb,
+ 0x5c3f, 0x2331,
+ 0x5c40, 0x13ee,
+ 0x5c42, 0x2332,
+ 0x5c43, 0x13f1,
+ 0x5c48, 0x2333,
+ 0x5c4b, 0x13f9,
+ 0x5c51, 0x2336,
+ 0x5c52, 0x1400,
+ 0x5c57, 0x2337,
+ 0x5c58, 0x1406,
+ 0x5c60, 0x2338,
+ 0x5c61, 0x140f,
+ 0x5c63, 0x2339,
+ 0x5c65, 0x1413,
+ 0x5c69, 0x233b,
+ 0x5c6b, 0x1419,
+ 0x5c71, 0x233d,
+ 0x5c72, 0x1420,
+ 0x5c76, 0x233e,
+ 0x5c77, 0x1425,
+ 0x5c79, 0x233f,
+ 0x5c7a, 0x1428,
+ 0x5c7d, 0x2340,
+ 0x5d21, 0x2342,
+ 0x5d22, 0x142e,
+ 0x5d23, 0x2343,
+ 0x5d28, 0x1434,
+ 0x5d2a, 0x2348,
+ 0x5d2c, 0x1438,
+ 0x5d32, 0x234a,
+ 0x5d33, 0x143f,
+ 0x5d35, 0x234b,
+ 0x5d36, 0x1442,
+ 0x5d3a, 0x234c,
+ 0x5d3c, 0x1448,
+ 0x5d53, 0x234e,
+ 0x5d54, 0x1460,
+ 0x5d5b, 0x234f,
+ 0x5d5c, 0x1468,
+ 0x5d5e, 0x2350,
+ 0x5d5f, 0x146b,
+ 0x5d64, 0x2351,
+ 0x5d65, 0x1471,
+ 0x5d6b, 0x2352,
+ 0x5d6c, 0x1478,
+ 0x5d71, 0x2353,
+ 0x5d72, 0x147e,
+ 0x5d76, 0x2354,
+ 0x5d78, 0x1484,
+ 0x5d7c, 0x2356,
+ 0x5d7d, 0x1489,
+ 0x5d7e, 0x2357,
+ 0x5e21, 0x148b,
+ 0x5e2d, 0x2358,
+ 0x5e2e, 0x1498,
+ 0x5e34, 0x2359,
+ 0x5e35, 0x149f,
+ 0x5e3a, 0x235a,
+ 0x5e3b, 0x14a5,
+ 0x5e46, 0x235b,
+ 0x5e47, 0x14b1,
+ 0x5e4f, 0x235c,
+ 0x5e50, 0x14ba,
+ 0x5e51, 0x235d,
+ 0x5e53, 0x14bd,
+ 0x5e58, 0x235f,
+ 0x5e59, 0x14c3,
+ 0x5e62, 0x2360,
+ 0x5e63, 0x14cd,
+ 0x5e68, 0x2361,
+ 0x5e69, 0x14d3,
+ 0x5e6c, 0x2362,
+ 0x5e6d, 0x14d7,
+ 0x5e73, 0x2363,
+ 0x5e74, 0x14de,
+ 0x5e7c, 0x2364,
+ 0x5e7d, 0x14e7,
+ 0x5f21, 0x14e9,
+ 0x5f22, 0x2365,
+ 0x5f24, 0x14ec,
+ 0x5f25, 0x2367,
+ 0x5f26, 0x14ee,
+ 0x5f34, 0x2368,
+ 0x5f35, 0x14fd,
+ 0x5f3c, 0x2369,
+ 0x5f3e, 0x1506,
+ 0x5f3f, 0x236b,
+ 0x5f40, 0x1508,
+ 0x5f42, 0x236c,
+ 0x5f44, 0x150c,
+ 0x5f4c, 0x236e,
+ 0x5f4d, 0x1515,
+ 0x5f50, 0x236f,
+ 0x5f51, 0x1519,
+ 0x5f55, 0x2370,
+ 0x5f56, 0x151e,
+ 0x5f58, 0x2371,
+ 0x5f5a, 0x1522,
+ 0x5f5c, 0x2373,
+ 0x5f5d, 0x1525,
+ 0x5f60, 0x2374,
+ 0x5f61, 0x1529,
+ 0x5f62, 0x2375,
+ 0x5f63, 0x152b,
+ 0x5f66, 0x2376,
+ 0x5f67, 0x152f,
+ 0x5f69, 0x2377,
+ 0x5f6a, 0x1532,
+ 0x5f6b, 0x2378,
+ 0x5f6c, 0x1534,
+ 0x5f6f, 0x2379,
+ 0x5f70, 0x1538,
+ 0x5f75, 0x237a,
+ 0x5f76, 0x153e,
+ 0x5f79, 0x237b,
+ 0x5f7a, 0x1542,
+ 0x6021, 0x1547,
+ 0x6036, 0x237c,
+ 0x6038, 0x155e,
+ 0x603f, 0x237e,
+ 0x6040, 0x1566,
+ 0x6048, 0x237f,
+ 0x6049, 0x156f,
+ 0x604e, 0x2380,
+ 0x604f, 0x1575,
+ 0x6053, 0x2381,
+ 0x6054, 0x157a,
+ 0x6060, 0x2382,
+ 0x6061, 0x1587,
+ 0x6070, 0x2383,
+ 0x6071, 0x1597,
+ 0x6078, 0x2384,
+ 0x6079, 0x159f,
+ 0x607c, 0x2385,
+ 0x6121, 0x15a5,
+ 0x612b, 0x2388,
+ 0x612c, 0x15b0,
+ 0x612d, 0x2389,
+ 0x612e, 0x15b2,
+ 0x6130, 0x238a,
+ 0x6131, 0x15b5,
+ 0x6134, 0x238b,
+ 0x6135, 0x15b9,
+ 0x613b, 0x238c,
+ 0x613c, 0x15c0,
+ 0x613d, 0x238d,
+ 0x613e, 0x15c2,
+ 0x6140, 0x238e,
+ 0x6142, 0x15c6,
+ 0x6149, 0x2390,
+ 0x614a, 0x15ce,
+ 0x6150, 0x2391,
+ 0x6151, 0x15d5,
+ 0x615b, 0x2392,
+ 0x615c, 0x15e0,
+ 0x6161, 0x07aa,
+ 0x6162, 0x2393,
+ 0x6163, 0x15e7,
+ 0x6167, 0x1198,
+ 0x6168, 0x15ec,
+ 0x616e, 0x2394,
+ 0x6170, 0x15f4,
+ 0x6176, 0x2396,
+ 0x6177, 0x15fb,
+ 0x6178, 0x2397,
+ 0x6179, 0x15fd,
+ 0x617d, 0x2398,
+ 0x617e, 0x1602,
+ 0x6221, 0x1603,
+ 0x6224, 0x2399,
+ 0x6225, 0x1607,
+ 0x6228, 0x239a,
+ 0x6229, 0x160b,
+ 0x623b, 0x239b,
+ 0x6245, 0x10c5,
+ 0x6246, 0x23a5,
+ 0x624f, 0x1631,
+ 0x6250, 0x23ae,
+ 0x6251, 0x1633,
+ 0x6259, 0x23af,
+ 0x625a, 0x163c,
+ 0x6263, 0x23b0,
+ 0x6265, 0x1647,
+ 0x6266, 0x23b2,
+ 0x6267, 0x1649,
+ 0x6269, 0x23b3,
+ 0x626c, 0x164e,
+ 0x6278, 0x23b6,
+ 0x6279, 0x165b,
+ 0x627a, 0x23b7,
+ 0x627e, 0x1660,
+ 0x6321, 0x1661,
+ 0x6322, 0x23bb,
+ 0x6323, 0x1663,
+ 0x6325, 0x23bc,
+ 0x6326, 0x1666,
+ 0x632b, 0x23bd,
+ 0x632c, 0x166c,
+ 0x6334, 0x23be,
+ 0x6335, 0x1675,
+ 0x6345, 0x23bf,
+ 0x635c, 0x169c,
+ 0x6363, 0x23d6,
+ 0x6364, 0x16a4,
+ 0x636d, 0x23d7,
+ 0x636e, 0x16ae,
+ 0x6371, 0x23d8,
+ 0x6373, 0x16b3,
+ 0x6378, 0x23da,
+ 0x6379, 0x16b9,
+ 0x637e, 0x23db,
+ 0x6421, 0x16bf,
+ 0x6424, 0x23dc,
+ 0x6426, 0x16c4,
+ 0x642b, 0x23de,
+ 0x642c, 0x16ca,
+ 0x642f, 0x23df,
+ 0x6432, 0x16d0,
+ 0x6435, 0x23e2,
+ 0x6437, 0x16d5,
+ 0x6442, 0x23e4,
+ 0x6443, 0x16e1,
+ 0x6445, 0x23e5,
+ 0x6446, 0x16e4,
+ 0x6449, 0x23e6,
+ 0x644a, 0x16e8,
+ 0x6459, 0x23e7,
+ 0x645a, 0x16f8,
+ 0x645c, 0x23e8,
+ 0x645d, 0x16fb,
+ 0x645e, 0x23e9,
+ 0x645f, 0x16fd,
+ 0x6464, 0x23ea,
+ 0x6465, 0x1703,
+ 0x646b, 0x23eb,
+ 0x646d, 0x170b,
+ 0x6472, 0x23ed,
+ 0x6473, 0x1711,
+ 0x647e, 0x23ee,
+ 0x6521, 0x171d,
+ 0x6530, 0x23ef,
+ 0x6531, 0x172d,
+ 0x6539, 0x23f0,
+ 0x653a, 0x1736,
+ 0x6547, 0x23f1,
+ 0x6548, 0x1744,
+ 0x6549, 0x23f2,
+ 0x654a, 0x1746,
+ 0x654e, 0x23f3,
+ 0x654f, 0x174b,
+ 0x6570, 0x23f4,
+ 0x6571, 0x176d,
+ 0x6572, 0x23f5,
+ 0x6573, 0x176f,
+ 0x657c, 0x23f6,
+ 0x657e, 0x177a,
+ 0x6621, 0x177b,
+ 0x6623, 0x23f8,
+ 0x6624, 0x177e,
+ 0x662b, 0x23f9,
+ 0x662d, 0x1787,
+ 0x662e, 0x23fb,
+ 0x662f, 0x1789,
+ 0x6634, 0x23fc,
+ 0x6636, 0x1790,
+ 0x663f, 0x23fe,
+ 0x6640, 0x179a,
+ 0x6648, 0x23ff,
+ 0x664a, 0x17a4,
+ 0x664d, 0x2401,
+ 0x664e, 0x17a8,
+ 0x6660, 0x2402,
+ 0x6721, 0x2421,
+ 0x675b, 0x1813,
+ 0x6761, 0x245b,
+ 0x6763, 0x181b,
+ 0x6767, 0x245d,
+ 0x6768, 0x1820,
+ 0x676f, 0x245e,
+ 0x6770, 0x1828,
+ 0x6774, 0x245f,
+ 0x6777, 0x182f,
+ 0x6821, 0x1837,
+ 0x6828, 0x2462,
+ 0x6829, 0x183f,
+ 0x682c, 0x2463,
+ 0x682d, 0x1843,
+ 0x6836, 0x2464,
+ 0x6837, 0x184d,
+ 0x6838, 0x2465,
+ 0x683b, 0x1851,
+ 0x683f, 0x2468,
+ 0x6841, 0x1857,
+ 0x6845, 0x246a,
+ 0x6846, 0x185c,
+ 0x6847, 0x246b,
+ 0x684a, 0x1860,
+ 0x684e, 0x246e,
+ 0x684f, 0x1865,
+ 0x6850, 0x246f,
+ 0x6851, 0x1867,
+ 0x6853, 0x2470,
+ 0x6854, 0x186a,
+ 0x685d, 0x2471,
+ 0x685e, 0x1874,
+ 0x685f, 0x2472,
+ 0x6860, 0x1876,
+ 0x6862, 0x2473,
+ 0x6864, 0x187a,
+ 0x6865, 0x2475,
+ 0x6866, 0x187c,
+ 0x6867, 0x2476,
+ 0x6868, 0x187e,
+ 0x686b, 0x2477,
+ 0x686c, 0x1882,
+ 0x686d, 0x2478,
+ 0x686e, 0x1884,
+ 0x686f, 0x2479,
+ 0x6870, 0x1886,
+ 0x6879, 0x247a,
+ 0x687a, 0x1890,
+ 0x687c, 0x247b,
+ 0x687e, 0x1894,
+ 0x6921, 0x247d,
+ 0x6922, 0x1896,
+ 0x692d, 0x247e,
+ 0x692e, 0x18a2,
+ 0x6934, 0x247f,
+ 0x6936, 0x18aa,
+ 0x6937, 0x2481,
+ 0x6938, 0x18ac,
+ 0x6944, 0x2482,
+ 0x6945, 0x18b9,
+ 0x6946, 0x2483,
+ 0x6947, 0x18bb,
+ 0x6949, 0x2484,
+ 0x694a, 0x18be,
+ 0x6956, 0x2485,
+ 0x6957, 0x18cb,
+ 0x695a, 0x2486,
+ 0x695b, 0x18cf,
+ 0x6964, 0x2487,
+ 0x6965, 0x18d9,
+ 0x6966, 0x2488,
+ 0x6968, 0x18dc,
+ 0x6969, 0x248a,
+ 0x696a, 0x18de,
+ 0x696b, 0x248b,
+ 0x696c, 0x18e0,
+ 0x696d, 0x248c,
+ 0x6a21, 0x249e,
+ 0x6a26, 0x18f8,
+ 0x6a27, 0x24a3,
+ 0x6a29, 0x18fb,
+ 0x6a31, 0x24a5,
+ 0x6a32, 0x1904,
+ 0x6a3c, 0x24a6,
+ 0x6a3d, 0x190f,
+ 0x6a4a, 0x24a7,
+ 0x6a4b, 0x191d,
+ 0x6a4d, 0x24a8,
+ 0x6a4e, 0x1920,
+ 0x6a53, 0x24a9,
+ 0x6a54, 0x1926,
+ 0x6a5a, 0x24aa,
+ 0x6a70, 0x1942,
+ 0x6b21, 0x1951,
+ 0x6b27, 0x24c0,
+ 0x6b28, 0x1958,
+ 0x6b2a, 0x24c1,
+ 0x6b2b, 0x195b,
+ 0x6b32, 0x24c2,
+ 0x6b33, 0x1963,
+ 0x6b39, 0x24c3,
+ 0x6b3a, 0x196a,
+ 0x6b4a, 0x24c4,
+ 0x6b4c, 0x197c,
+ 0x6b4d, 0x24c6,
+ 0x6b4e, 0x197e,
+ 0x6b56, 0x24c7,
+ 0x6b57, 0x1987,
+ 0x6b5a, 0x24c8,
+ 0x6b5b, 0x198b,
+ 0x6b61, 0x24c9,
+ 0x6b62, 0x1992,
+ 0x6b77, 0x24ca,
+ 0x6b78, 0x19a8,
+ 0x6c21, 0x19af,
+ 0x6c23, 0x24cb,
+ 0x6c24, 0x19b2,
+ 0x6c29, 0x24cc,
+ 0x6c2f, 0x19bd,
+ 0x6c31, 0x24d2,
+ 0x6c32, 0x19c0,
+ 0x6c34, 0x24d3,
+ 0x6c36, 0x19c4,
+ 0x6c3e, 0x24d5,
+ 0x6c40, 0x19ce,
+ 0x6c41, 0x24d7,
+ 0x6c42, 0x19d0,
+ 0x6c47, 0x24d8,
+ 0x6c48, 0x19d6,
+ 0x6c4b, 0x24d9,
+ 0x6c4c, 0x19da,
+ 0x6c62, 0x24da,
+ 0x6c63, 0x19f1,
+ 0x6c72, 0x24db,
+ 0x6c73, 0x1a01,
+ 0x6c75, 0x24dc,
+ 0x6c76, 0x1a04,
+ 0x6c78, 0x24dd,
+ 0x6c79, 0x1a07,
+ 0x6d21, 0x24de,
+ 0x6d22, 0x1a0e,
+ 0x6d28, 0x24df,
+ 0x6d29, 0x1a15,
+ 0x6d2f, 0x24e0,
+ 0x6d31, 0x1a1d,
+ 0x6d34, 0x24e2,
+ 0x6d35, 0x1a21,
+ 0x6d36, 0x24e3,
+ 0x6d37, 0x1a23,
+ 0x6d38, 0x24e4,
+ 0x6d39, 0x1a25,
+ 0x6d3a, 0x24e5,
+ 0x6d3b, 0x1a27,
+ 0x6d3f, 0x24e6,
+ 0x6d40, 0x1a2c,
+ 0x6d42, 0x24e7,
+ 0x6d44, 0x1a30,
+ 0x6d4c, 0x24e9,
+ 0x6d4e, 0x1a3a,
+ 0x6d53, 0x24eb,
+ 0x6d54, 0x1a40,
+ 0x6d57, 0x24ec,
+ 0x6d58, 0x1a44,
+ 0x6d68, 0x24ed,
+ 0x6d69, 0x1a55,
+ 0x6d6e, 0x24ee,
+ 0x6d6f, 0x1a5b,
+ 0x6d79, 0x24ef,
+ 0x6d7b, 0x1a67,
+ 0x6e21, 0x1a6b,
+ 0x6e3c, 0x24f1,
+ 0x6e3d, 0x1a87,
+ 0x6e3f, 0x24f2,
+ 0x6e40, 0x1a8a,
+ 0x6e44, 0x24f3,
+ 0x6f21, 0x252e,
+ 0x6f72, 0x1b1a,
+ 0x7021, 0x1b27,
+ 0x7023, 0x257f,
+ 0x7024, 0x1b2a,
+ 0x702f, 0x2580,
+ 0x705a, 0x1b60,
+ 0x705c, 0x25ab,
+ 0x705e, 0x1b64,
+ 0x705f, 0x25ad,
+ 0x7060, 0x1b66,
+ 0x7069, 0x25ae,
+ 0x706a, 0x1b70,
+ 0x706c, 0x25af,
+ 0x706d, 0x1b73,
+ 0x706f, 0x25b0,
+ 0x7070, 0x1b76,
+ 0x7077, 0x25b1,
+ 0x7078, 0x1b7e,
+ 0x7079, 0x25b2,
+ 0x707a, 0x1b80,
+ 0x707c, 0x25b3,
+ 0x707d, 0x1b83,
+ 0x7121, 0x1b85,
+ 0x7128, 0x25b4,
+ 0x7129, 0x1b8d,
+ 0x712b, 0x25b5,
+ 0x712c, 0x1b90,
+ 0x712e, 0x25b6,
+ 0x712f, 0x1b93,
+ 0x7132, 0x25b7,
+ 0x7133, 0x1b97,
+ 0x713c, 0x25b8,
+ 0x713d, 0x1ba1,
+ 0x7140, 0x25b9,
+ 0x7141, 0x1ba5,
+ 0x7149, 0x25ba,
+ 0x714a, 0x1bae,
+ 0x714d, 0x25bb,
+ 0x714e, 0x1bb2,
+ 0x714f, 0x25bc,
+ 0x7151, 0x1bb5,
+ 0x715a, 0x25be,
+ 0x715b, 0x1bbf,
+ 0x715c, 0x25bf,
+ 0x715d, 0x1bc1,
+ 0x7164, 0x25c0,
+ 0x7165, 0x1bc9,
+ 0x716c, 0x25c1,
+ 0x716d, 0x1bd1,
+ 0x716f, 0x25c2,
+ 0x7170, 0x1bd4,
+ 0x7177, 0x25c3,
+ 0x7178, 0x1bdc,
+ 0x7179, 0x25c4,
+ 0x717a, 0x1bde,
+ 0x717c, 0x25c5,
+ 0x7221, 0x25c8,
+ 0x722e, 0x1bf0,
+ 0x7231, 0x25d5,
+ 0x7233, 0x1bf5,
+ 0x7239, 0x25d7,
+ 0x723a, 0x1bfc,
+ 0x7243, 0x25d8,
+ 0x7244, 0x1c06,
+ 0x7249, 0x25d9,
+ 0x724a, 0x1c0c,
+ 0x724c, 0x25da,
+ 0x724e, 0x1c10,
+ 0x724f, 0x25dc,
+ 0x7250, 0x1c12,
+ 0x7253, 0x25dd,
+ 0x7254, 0x1c16,
+ 0x7265, 0x25de,
+ 0x7266, 0x1c28,
+ 0x726e, 0x25df,
+ 0x726f, 0x1c31,
+ 0x7277, 0x25e0,
+ 0x7278, 0x1c3a,
+ 0x727d, 0x25e1,
+ 0x727e, 0x1c40,
+ 0x7321, 0x1c41,
+ 0x733f, 0x25e2,
+ 0x7340, 0x1c60,
+ 0x7346, 0x25e3,
+ 0x7347, 0x1c67,
+ 0x7348, 0x25e4,
+ 0x7349, 0x1c69,
+ 0x7356, 0x25e5,
+ 0x7357, 0x1c77,
+ 0x7359, 0x25e6,
+ 0x735a, 0x1c7a,
+ 0x7365, 0x25e7,
+ 0x7367, 0x1c87,
+ 0x736a, 0x25e9,
+ 0x736b, 0x1c8b,
+ 0x736c, 0x25ea,
+ 0x736d, 0x1c8d,
+ 0x736f, 0x25eb,
+ 0x7370, 0x1c90,
+ 0x7371, 0x25ec,
+ 0x7372, 0x1c92,
+ 0x737d, 0x25ed,
+ 0x737e, 0x1c9e,
+ 0x7421, 0x1c9f,
+ 0x7425, 0x25ee,
+ 0x7426, 0x1ca4,
+ 0x742f, 0x25ef,
+ 0x7430, 0x1cae,
+ 0x7435, 0x25f0,
+ 0x7436, 0x1cb4,
+ 0x7441, 0x25f1,
+ 0x7442, 0x1cc0,
+ 0x7447, 0x25f2,
+ 0x7448, 0x1cc6,
+ 0x744f, 0x25f3,
+ 0x7451, 0x1ccf,
+ 0x7456, 0x25f5,
+ 0x7457, 0x1cd5,
+ 0x746a, 0x25f6,
+ 0x746b, 0x1ce9,
+ 0x746f, 0x25f7,
+ 0x7470, 0x1cee,
+ 0x7475, 0x25f8,
+ 0x7476, 0x1cf4,
+ 0x7521, 0x1cfd,
+ 0x7526, 0x25f9,
+ 0x7528, 0x1d04,
+ 0x753a, 0x25fb,
+ 0x753c, 0x1d18,
+ 0x7544, 0x25fd,
+ 0x7545, 0x1d21,
+ 0x7548, 0x25fe,
+ 0x7549, 0x1d25,
+ 0x754e, 0x25ff,
+ 0x7550, 0x1d2c,
+ 0x7551, 0x2601,
+ 0x7553, 0x1d2f,
+ 0x7559, 0x2603,
+ 0x755a, 0x1d36,
+ 0x755c, 0x2604,
+ 0x755d, 0x1d39,
+ 0x7566, 0x2605,
+ 0x7568, 0x1d44,
+ 0x756f, 0x2607,
+ 0x7570, 0x1d4c,
+ 0x7572, 0x2608,
+ 0x7573, 0x1d4f,
+ 0x757c, 0x2609,
+ 0x757d, 0x1d59,
+ 0x7621, 0x1d5b,
+ 0x7623, 0x260a,
+ 0x7624, 0x1d5e,
+ 0x7626, 0x260b,
+ 0x7627, 0x1d61,
+ 0x7628, 0x260c,
+ 0x7629, 0x1d63,
+ 0x762b, 0x260d,
+ 0x762c, 0x1d66,
+ 0x7630, 0x260e,
+ 0x7631, 0x1d6b,
+ 0x7633, 0x260f,
+ 0x763f, 0x1d79,
+ 0x7645, 0x261b,
+ 0x7646, 0x1d80,
+ 0x7647, 0x261c,
+ 0x7648, 0x1d82,
+ 0x7649, 0x261d,
+ 0x764a, 0x1d84,
+ 0x764f, 0x261e,
+ 0x7721, 0x264e,
+ 0x7730, 0x1dc8,
+ 0x7732, 0x265d,
+ 0x7734, 0x1dcc,
+ 0x7735, 0x265f,
+ 0x7736, 0x1dce,
+ 0x773d, 0x2660,
+ 0x773e, 0x1dd6,
+ 0x7743, 0x2661,
+ 0x7744, 0x1ddc,
+ 0x7745, 0x2662,
+ 0x7747, 0x1ddf,
+ 0x774a, 0x2664,
+ 0x774c, 0x1de4,
+ 0x774f, 0x2666,
+ 0x7751, 0x1de9,
+ 0x775e, 0x2668,
+ 0x775f, 0x1df7,
+ 0x7761, 0x0ab9,
+ 0x7762, 0x1dfa,
+ 0x7772, 0x2669,
+ 0x7773, 0x1e0b,
+ 0x7775, 0x266a,
+ 0x7776, 0x1e0e,
+ 0x7821, 0x266b,
+ 0x7827, 0x04cc,
+ 0x7828, 0x050a,
+ 0x7829, 0x0518,
+ 0x782a, 0x2671,
+ 0x782c, 0x0594,
+ 0x782d, 0x05ce,
+ 0x782e, 0x2673,
+ 0x782f, 0x05f6,
+ 0x7830, 0x2674,
+ 0x7832, 0x0653,
+ 0x7833, 0x067e,
+ 0x7834, 0x2676,
+ 0x7835, 0x06c4,
+ 0x7836, 0x2677,
+ 0x7838, 0x073c,
+ 0x7839, 0x2679,
+ 0x783b, 0x07c3,
+ 0x783c, 0x267b,
+ 0x7840, 0x082b,
+ 0x7841, 0x267f,
+ 0x7842, 0x084e,
+ 0x7843, 0x0869,
+ 0x7844, 0x2680,
+ 0x7846, 0x090c,
+ 0x7847, 0x2682,
+ 0x7849, 0x0971,
+ 0x784a, 0x2684,
+ 0x784b, 0x099a,
+ 0x784d, 0x2685,
+ 0x784e, 0x09da,
+ 0x784f, 0x2686,
+ 0x7850, 0x09fa,
+ 0x7851, 0x2687,
+ 0x785c, 0x0bda,
+ 0x785d, 0x0bdd,
+ 0x785e, 0x0bea,
+ 0x785f, 0x0bec,
+ 0x7860, 0x0bf2,
+ 0x7861, 0x2692,
+ 0x7866, 0x0c92,
+ 0x7867, 0x0d1a,
+ 0x7868, 0x0d8c,
+ 0x7869, 0x0dbe,
+ 0x786a, 0x2697,
+ 0x786b, 0x0dfb,
+ 0x786c, 0x2698,
+ 0x786f, 0x0e70,
+ 0x7870, 0x269b,
+ 0x7871, 0x0ea3,
+ 0x7872, 0x269c,
+ 0x7878, 0x103d,
+ 0x7879, 0x10d9,
+ 0x787a, 0x26a2,
+ 0x787c, 0x10fb,
+ 0x787d, 0x1109,
+ 0x787e, 0x26a4,
+ 0x7921, 0x11a1,
+ 0x7922, 0x26a5,
+ 0x7923, 0x11ba,
+ 0x7924, 0x26a6,
+ 0x7926, 0x11d5,
+ 0x7927, 0x26a8,
+ 0x7928, 0x11fd,
+ 0x7929, 0x1219,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBTHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12GBTHMap2, 2283
+};
+
+static Gushort gb12GBTVMap2[4606] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0060,
+ 0x2231, 0x00be,
+ 0x2265, 0x00f0,
+ 0x2271, 0x00fa,
+ 0x2321, 0x0106,
+ 0x2421, 0x0164,
+ 0x2521, 0x01b7,
+ 0x2621, 0x020d,
+ 0x2641, 0x0225,
+ 0x2721, 0x025a,
+ 0x2751, 0x027b,
+ 0x2821, 0x029c,
+ 0x2845, 0x02bc,
+ 0x2924, 0x02e2,
+ 0x2a21, 0x032e,
+ 0x2b21, 0x038c,
+ 0x3021, 0x03ac,
+ 0x3028, 0x1e25,
+ 0x3029, 0x03b4,
+ 0x302a, 0x1e26,
+ 0x302b, 0x03b6,
+ 0x302d, 0x1e27,
+ 0x302f, 0x03ba,
+ 0x3039, 0x1e29,
+ 0x303a, 0x03c5,
+ 0x3040, 0x1e2a,
+ 0x3041, 0x03cc,
+ 0x3053, 0x1e2b,
+ 0x3054, 0x03df,
+ 0x3055, 0x1e2c,
+ 0x3056, 0x03e1,
+ 0x305a, 0x1e2d,
+ 0x305b, 0x03e6,
+ 0x305c, 0x1e2e,
+ 0x305d, 0x03e8,
+ 0x3064, 0x1e2f,
+ 0x3065, 0x03f0,
+ 0x306c, 0x1e30,
+ 0x306e, 0x03f9,
+ 0x306f, 0x1e32,
+ 0x3070, 0x03fb,
+ 0x3073, 0x1e33,
+ 0x3074, 0x03ff,
+ 0x3077, 0x1e34,
+ 0x3078, 0x0403,
+ 0x3079, 0x1e35,
+ 0x307a, 0x0405,
+ 0x3121, 0x040a,
+ 0x3125, 0x1e36,
+ 0x3127, 0x0410,
+ 0x3128, 0x1e38,
+ 0x3129, 0x0412,
+ 0x312b, 0x1e39,
+ 0x312c, 0x0415,
+ 0x3132, 0x1e3a,
+ 0x3133, 0x041c,
+ 0x3134, 0x1e3b,
+ 0x3136, 0x041f,
+ 0x3137, 0x1e3d,
+ 0x313a, 0x0423,
+ 0x3141, 0x1e40,
+ 0x3142, 0x042b,
+ 0x314a, 0x1e41,
+ 0x314b, 0x0434,
+ 0x314f, 0x1e42,
+ 0x3151, 0x043a,
+ 0x3152, 0x1e44,
+ 0x3153, 0x043c,
+ 0x3155, 0x1e45,
+ 0x3156, 0x043f,
+ 0x315f, 0x1e46,
+ 0x3162, 0x044b,
+ 0x3164, 0x1e49,
+ 0x3165, 0x044e,
+ 0x3167, 0x1e4a,
+ 0x3169, 0x0452,
+ 0x316a, 0x1e4c,
+ 0x316b, 0x0454,
+ 0x316e, 0x1e4d,
+ 0x316f, 0x0458,
+ 0x3171, 0x1e4e,
+ 0x3172, 0x045b,
+ 0x3174, 0x1e4f,
+ 0x3178, 0x0461,
+ 0x317d, 0x1e53,
+ 0x317e, 0x0467,
+ 0x3221, 0x0468,
+ 0x3226, 0x1e54,
+ 0x3228, 0x046f,
+ 0x322c, 0x1e56,
+ 0x322d, 0x0474,
+ 0x3235, 0x1e57,
+ 0x3236, 0x047d,
+ 0x3239, 0x1e58,
+ 0x323a, 0x0481,
+ 0x3246, 0x1e59,
+ 0x3247, 0x048e,
+ 0x324e, 0x1e5a,
+ 0x3258, 0x049f,
+ 0x325e, 0x1e64,
+ 0x325f, 0x04a6,
+ 0x3260, 0x1e65,
+ 0x3261, 0x04a8,
+ 0x3262, 0x1e66,
+ 0x3264, 0x04ab,
+ 0x326f, 0x1e68,
+ 0x3270, 0x04b7,
+ 0x3273, 0x1e69,
+ 0x327d, 0x04c4,
+ 0x3321, 0x1e73,
+ 0x3323, 0x04c8,
+ 0x3324, 0x1e75,
+ 0x3328, 0x04cd,
+ 0x3329, 0x1e79,
+ 0x332a, 0x04cf,
+ 0x332e, 0x1e7a,
+ 0x332f, 0x04d4,
+ 0x3335, 0x1e7b,
+ 0x3336, 0x04db,
+ 0x3339, 0x1e7c,
+ 0x333a, 0x04df,
+ 0x333e, 0x1e7d,
+ 0x333f, 0x04e4,
+ 0x3342, 0x1e7e,
+ 0x3343, 0x04e8,
+ 0x3344, 0x1e7f,
+ 0x3345, 0x04ea,
+ 0x3346, 0x1e80,
+ 0x3347, 0x04ec,
+ 0x334d, 0x1e81,
+ 0x334e, 0x04f3,
+ 0x334f, 0x1e82,
+ 0x3350, 0x04f5,
+ 0x3352, 0x1e83,
+ 0x3353, 0x04f8,
+ 0x3359, 0x1e84,
+ 0x335a, 0x04ff,
+ 0x335b, 0x1e85,
+ 0x335c, 0x0501,
+ 0x335d, 0x1e86,
+ 0x335e, 0x0503,
+ 0x3363, 0x1e87,
+ 0x3364, 0x0509,
+ 0x3365, 0x1e88,
+ 0x3367, 0x050c,
+ 0x3368, 0x1e8a,
+ 0x3369, 0x050e,
+ 0x336b, 0x1e8b,
+ 0x336d, 0x0512,
+ 0x336f, 0x1e8d,
+ 0x3370, 0x0515,
+ 0x3371, 0x1e8e,
+ 0x3372, 0x0517,
+ 0x3373, 0x1e8f,
+ 0x3374, 0x0519,
+ 0x337a, 0x1e90,
+ 0x337c, 0x0521,
+ 0x3421, 0x1e92,
+ 0x3423, 0x0526,
+ 0x3425, 0x1e94,
+ 0x3427, 0x052a,
+ 0x342b, 0x1e96,
+ 0x342c, 0x052f,
+ 0x342f, 0x1e97,
+ 0x3430, 0x0533,
+ 0x3433, 0x1e98,
+ 0x3435, 0x0538,
+ 0x3438, 0x1e9a,
+ 0x3439, 0x053c,
+ 0x343f, 0x1e9b,
+ 0x3440, 0x0543,
+ 0x3442, 0x1e9c,
+ 0x3443, 0x0546,
+ 0x3447, 0x1e9d,
+ 0x3448, 0x054b,
+ 0x344a, 0x1e9e,
+ 0x344b, 0x054e,
+ 0x344d, 0x1e9f,
+ 0x344e, 0x0551,
+ 0x344f, 0x1ea0,
+ 0x3450, 0x0553,
+ 0x3453, 0x1ea1,
+ 0x3455, 0x0558,
+ 0x345a, 0x1ea3,
+ 0x345b, 0x055e,
+ 0x345c, 0x1ea4,
+ 0x345d, 0x0560,
+ 0x346d, 0x1ea5,
+ 0x346e, 0x0571,
+ 0x346f, 0x1ea6,
+ 0x3470, 0x0573,
+ 0x3478, 0x1ea7,
+ 0x3479, 0x057c,
+ 0x347b, 0x1ea8,
+ 0x347c, 0x057f,
+ 0x3521, 0x0582,
+ 0x3523, 0x1ea9,
+ 0x3524, 0x0585,
+ 0x3525, 0x1eaa,
+ 0x3529, 0x058a,
+ 0x352c, 0x1eae,
+ 0x352d, 0x058e,
+ 0x352e, 0x1eaf,
+ 0x3530, 0x0591,
+ 0x3531, 0x1eb1,
+ 0x3536, 0x0597,
+ 0x3537, 0x1eb6,
+ 0x3538, 0x0599,
+ 0x353a, 0x1eb7,
+ 0x353d, 0x059e,
+ 0x3546, 0x1eba,
+ 0x3547, 0x05a8,
+ 0x354b, 0x1ebb,
+ 0x354c, 0x05ad,
+ 0x3550, 0x1ebc,
+ 0x3551, 0x05b2,
+ 0x3553, 0x1ebd,
+ 0x3554, 0x05b5,
+ 0x355d, 0x1ebe,
+ 0x3560, 0x05c1,
+ 0x3563, 0x1ec1,
+ 0x3564, 0x05c5,
+ 0x3566, 0x1ec2,
+ 0x3568, 0x05c9,
+ 0x356d, 0x1ec4,
+ 0x356e, 0x05cf,
+ 0x3576, 0x1ec5,
+ 0x3578, 0x05d9,
+ 0x357d, 0x1ec7,
+ 0x357e, 0x05df,
+ 0x3621, 0x05e0,
+ 0x3624, 0x1ec8,
+ 0x3626, 0x05e5,
+ 0x3627, 0x1eca,
+ 0x3628, 0x05e7,
+ 0x3629, 0x1ecb,
+ 0x362a, 0x05e9,
+ 0x362b, 0x1ecc,
+ 0x362c, 0x05eb,
+ 0x362f, 0x1ecd,
+ 0x3631, 0x05f0,
+ 0x3633, 0x1ecf,
+ 0x3634, 0x05f3,
+ 0x3637, 0x1ed0,
+ 0x3638, 0x05f7,
+ 0x363f, 0x1ed1,
+ 0x3642, 0x0601,
+ 0x3644, 0x1ed4,
+ 0x3645, 0x0604,
+ 0x3646, 0x1ed5,
+ 0x3647, 0x0606,
+ 0x364d, 0x1ed6,
+ 0x364e, 0x060d,
+ 0x364f, 0x1ed7,
+ 0x3651, 0x0610,
+ 0x3653, 0x1ed9,
+ 0x3655, 0x0614,
+ 0x3656, 0x1edb,
+ 0x3657, 0x0616,
+ 0x3659, 0x1edc,
+ 0x365a, 0x0619,
+ 0x365b, 0x1edd,
+ 0x365c, 0x061b,
+ 0x3661, 0x1ede,
+ 0x3662, 0x0621,
+ 0x3669, 0x1edf,
+ 0x366a, 0x0629,
+ 0x366c, 0x1ee0,
+ 0x366d, 0x062c,
+ 0x366e, 0x1ee1,
+ 0x3670, 0x062f,
+ 0x3671, 0x1ee3,
+ 0x3672, 0x0631,
+ 0x3676, 0x1ee4,
+ 0x3677, 0x0636,
+ 0x3679, 0x1ee5,
+ 0x367a, 0x0639,
+ 0x367b, 0x1ee6,
+ 0x367d, 0x063c,
+ 0x3721, 0x1ee8,
+ 0x3724, 0x0641,
+ 0x3727, 0x1eeb,
+ 0x3728, 0x0645,
+ 0x372f, 0x1eec,
+ 0x3731, 0x064e,
+ 0x3733, 0x1eee,
+ 0x3734, 0x0651,
+ 0x3736, 0x1eef,
+ 0x3738, 0x0655,
+ 0x3739, 0x1ef1,
+ 0x373a, 0x0657,
+ 0x3743, 0x1ef2,
+ 0x3745, 0x0662,
+ 0x3749, 0x1ef4,
+ 0x374a, 0x0667,
+ 0x374c, 0x1ef5,
+ 0x374d, 0x066a,
+ 0x374f, 0x1ef6,
+ 0x3750, 0x066d,
+ 0x3751, 0x1ef7,
+ 0x3752, 0x066f,
+ 0x3757, 0x1ef8,
+ 0x3759, 0x0676,
+ 0x375c, 0x1efa,
+ 0x375d, 0x067a,
+ 0x375f, 0x1efb,
+ 0x3762, 0x067f,
+ 0x3763, 0x1efe,
+ 0x3764, 0x0681,
+ 0x3766, 0x1eff,
+ 0x3769, 0x0686,
+ 0x376b, 0x1f02,
+ 0x376e, 0x068b,
+ 0x376f, 0x1f05,
+ 0x3770, 0x068d,
+ 0x3774, 0x1f06,
+ 0x3775, 0x0692,
+ 0x3778, 0x1f07,
+ 0x3779, 0x0696,
+ 0x3821, 0x069c,
+ 0x3827, 0x1f08,
+ 0x3829, 0x06a4,
+ 0x3833, 0x1f0a,
+ 0x3835, 0x06b0,
+ 0x383a, 0x1f0c,
+ 0x383b, 0x06b6,
+ 0x383c, 0x1f0d,
+ 0x383d, 0x06b8,
+ 0x383e, 0x1f0e,
+ 0x3840, 0x06bb,
+ 0x3843, 0x1f10,
+ 0x3844, 0x06bf,
+ 0x3846, 0x1f11,
+ 0x3848, 0x06c3,
+ 0x3849, 0x1f13,
+ 0x384a, 0x06c5,
+ 0x384f, 0x1f14,
+ 0x3850, 0x06cb,
+ 0x3853, 0x1f15,
+ 0x3857, 0x06d2,
+ 0x3859, 0x1f19,
+ 0x385b, 0x06d6,
+ 0x3864, 0x1f1b,
+ 0x3865, 0x06e0,
+ 0x3869, 0x1f1c,
+ 0x386a, 0x06e5,
+ 0x386b, 0x1f1d,
+ 0x386c, 0x06e7,
+ 0x3873, 0x1f1e,
+ 0x3874, 0x06ef,
+ 0x3875, 0x1f1f,
+ 0x3877, 0x06f2,
+ 0x3878, 0x1f21,
+ 0x3879, 0x06f4,
+ 0x3921, 0x06fa,
+ 0x3928, 0x1f22,
+ 0x3929, 0x0702,
+ 0x392e, 0x1f23,
+ 0x392f, 0x0708,
+ 0x3931, 0x1f24,
+ 0x3932, 0x070b,
+ 0x3933, 0x1f25,
+ 0x3934, 0x070d,
+ 0x3935, 0x1f26,
+ 0x3936, 0x070f,
+ 0x3939, 0x1f27,
+ 0x393b, 0x0714,
+ 0x3946, 0x1f29,
+ 0x3947, 0x0720,
+ 0x394b, 0x1f2a,
+ 0x394c, 0x0725,
+ 0x3950, 0x1f2b,
+ 0x3951, 0x072a,
+ 0x3958, 0x1f2c,
+ 0x3959, 0x0732,
+ 0x395b, 0x1f2d,
+ 0x395c, 0x0735,
+ 0x395d, 0x1f2e,
+ 0x395e, 0x0737,
+ 0x395f, 0x1f2f,
+ 0x3960, 0x0739,
+ 0x3961, 0x1f30,
+ 0x3962, 0x073b,
+ 0x3963, 0x1f31,
+ 0x3964, 0x073d,
+ 0x3966, 0x1f32,
+ 0x3967, 0x0740,
+ 0x3969, 0x1f33,
+ 0x396d, 0x0746,
+ 0x396e, 0x1f37,
+ 0x396f, 0x0748,
+ 0x3971, 0x1f38,
+ 0x3972, 0x074b,
+ 0x3973, 0x1f39,
+ 0x3976, 0x074f,
+ 0x3978, 0x1f3c,
+ 0x3979, 0x0752,
+ 0x397a, 0x1f3d,
+ 0x397b, 0x0754,
+ 0x397d, 0x1f3e,
+ 0x397e, 0x0757,
+ 0x3a21, 0x0758,
+ 0x3a27, 0x1f3f,
+ 0x3a28, 0x075f,
+ 0x3a2b, 0x1f40,
+ 0x3a2c, 0x0763,
+ 0x3a3a, 0x1f41,
+ 0x3a3b, 0x0772,
+ 0x3a45, 0x1f42,
+ 0x3a46, 0x077d,
+ 0x3a52, 0x1f43,
+ 0x3a53, 0x078a,
+ 0x3a57, 0x1f44,
+ 0x3a59, 0x0790,
+ 0x3a64, 0x1f46,
+ 0x3a65, 0x079c,
+ 0x3a68, 0x1f47,
+ 0x3a69, 0x07a0,
+ 0x3a6c, 0x1f48,
+ 0x3a6d, 0x07a4,
+ 0x3a73, 0x15e5,
+ 0x3a74, 0x07ab,
+ 0x3a78, 0x1f49,
+ 0x3a79, 0x07b0,
+ 0x3b21, 0x07b6,
+ 0x3b24, 0x1f4a,
+ 0x3b25, 0x07ba,
+ 0x3b26, 0x1f4b,
+ 0x3b27, 0x07bc,
+ 0x3b29, 0x1f4c,
+ 0x3b2b, 0x07c0,
+ 0x3b2d, 0x1f4e,
+ 0x3b2f, 0x07c4,
+ 0x3b30, 0x1f50,
+ 0x3b31, 0x07c6,
+ 0x3b33, 0x1f51,
+ 0x3b34, 0x07c9,
+ 0x3b35, 0x1f52,
+ 0x3b38, 0x07cd,
+ 0x3b39, 0x1f55,
+ 0x3b3b, 0x07d0,
+ 0x3b51, 0x1f57,
+ 0x3b52, 0x07e7,
+ 0x3b53, 0x1f58,
+ 0x3b55, 0x07ea,
+ 0x3b5f, 0x1f5a,
+ 0x3b68, 0x07fd,
+ 0x3b6b, 0x1f63,
+ 0x3b6c, 0x0801,
+ 0x3b71, 0x1f64,
+ 0x3b72, 0x0807,
+ 0x3b75, 0x1f65,
+ 0x3b78, 0x080d,
+ 0x3b7a, 0x1f68,
+ 0x3b7b, 0x0810,
+ 0x3b7d, 0x1f69,
+ 0x3b7e, 0x0813,
+ 0x3c21, 0x0814,
+ 0x3c22, 0x1f6a,
+ 0x3c23, 0x0816,
+ 0x3c25, 0x1f6b,
+ 0x3c27, 0x081a,
+ 0x3c28, 0x1f6d,
+ 0x3c2a, 0x081d,
+ 0x3c2b, 0x1f6f,
+ 0x3c2c, 0x081f,
+ 0x3c2d, 0x1f70,
+ 0x3c2e, 0x0821,
+ 0x3c36, 0x1f71,
+ 0x3c39, 0x082c,
+ 0x3c3b, 0x1f74,
+ 0x3c3c, 0x082f,
+ 0x3c41, 0x1f75,
+ 0x3c42, 0x0835,
+ 0x3c43, 0x1f76,
+ 0x3c44, 0x0837,
+ 0x3c46, 0x1f77,
+ 0x3c48, 0x083b,
+ 0x3c4a, 0x1f79,
+ 0x3c4b, 0x083e,
+ 0x3c4c, 0x1f7a,
+ 0x3c4e, 0x0841,
+ 0x3c50, 0x1f7c,
+ 0x3c51, 0x0844,
+ 0x3c54, 0x1f7d,
+ 0x3c57, 0x084a,
+ 0x3c58, 0x1f80,
+ 0x3c59, 0x084c,
+ 0x3c5b, 0x1f81,
+ 0x3c5c, 0x084f,
+ 0x3c5d, 0x1f82,
+ 0x3c5e, 0x0851,
+ 0x3c5f, 0x1f83,
+ 0x3c62, 0x0855,
+ 0x3c63, 0x1f86,
+ 0x3c65, 0x0858,
+ 0x3c68, 0x1f88,
+ 0x3c69, 0x085c,
+ 0x3c6a, 0x1f89,
+ 0x3c6d, 0x0860,
+ 0x3c6f, 0x1f8c,
+ 0x3c74, 0x0867,
+ 0x3c76, 0x1f91,
+ 0x3c7d, 0x0870,
+ 0x3d21, 0x0872,
+ 0x3d22, 0x1f98,
+ 0x3d28, 0x0879,
+ 0x3d2b, 0x1f9e,
+ 0x3d2d, 0x087e,
+ 0x3d2f, 0x1fa0,
+ 0x3d33, 0x0884,
+ 0x3d34, 0x1fa4,
+ 0x3d35, 0x0886,
+ 0x3d3a, 0x1fa5,
+ 0x3d3b, 0x088c,
+ 0x3d3d, 0x1fa6,
+ 0x3d40, 0x0891,
+ 0x3d41, 0x1fa9,
+ 0x3d45, 0x0896,
+ 0x3d48, 0x1fad,
+ 0x3d4b, 0x089c,
+ 0x3d4e, 0x1fb0,
+ 0x3d50, 0x08a1,
+ 0x3d57, 0x1fb2,
+ 0x3d58, 0x08a9,
+ 0x3d5a, 0x1fb3,
+ 0x3d5b, 0x08ac,
+ 0x3d60, 0x1fb4,
+ 0x3d62, 0x08b3,
+ 0x3d6b, 0x1fb6,
+ 0x3d6c, 0x08bd,
+ 0x3d74, 0x1fb7,
+ 0x3d79, 0x08ca,
+ 0x3d7d, 0x1fbc,
+ 0x3d7e, 0x08cf,
+ 0x3e21, 0x1fbd,
+ 0x3e23, 0x08d2,
+ 0x3e25, 0x1fbf,
+ 0x3e26, 0x08d5,
+ 0x3e28, 0x1fc0,
+ 0x3e29, 0x08d8,
+ 0x3e2a, 0x1fc1,
+ 0x3e2b, 0x08da,
+ 0x3e2d, 0x1fc2,
+ 0x3e2e, 0x08dd,
+ 0x3e31, 0x1fc3,
+ 0x3e32, 0x08e1,
+ 0x3e35, 0x1fc4,
+ 0x3e38, 0x08e7,
+ 0x3e3a, 0x1fc7,
+ 0x3e3b, 0x08ea,
+ 0x3e40, 0x1fc8,
+ 0x3e41, 0x08f0,
+ 0x3e49, 0x1fc9,
+ 0x3e4a, 0x08f9,
+ 0x3e54, 0x1fca,
+ 0x3e55, 0x0904,
+ 0x3e59, 0x1fcb,
+ 0x3e5a, 0x0909,
+ 0x3e5d, 0x1fcc,
+ 0x3e5e, 0x090d,
+ 0x3e62, 0x1fcd,
+ 0x3e63, 0x0912,
+ 0x3e65, 0x1fce,
+ 0x3e66, 0x0915,
+ 0x3e67, 0x1fcf,
+ 0x3e68, 0x0917,
+ 0x3e69, 0x1fd0,
+ 0x3e6a, 0x0919,
+ 0x3e6e, 0x1fd1,
+ 0x3e6f, 0x091e,
+ 0x3e75, 0x1fd2,
+ 0x3e76, 0x0925,
+ 0x3e77, 0x1fd3,
+ 0x3e79, 0x0928,
+ 0x3e7b, 0x1fd5,
+ 0x3e7d, 0x092c,
+ 0x3f21, 0x092e,
+ 0x3f25, 0x1fd7,
+ 0x3f26, 0x0933,
+ 0x3f2a, 0x1fd8,
+ 0x3f2b, 0x0938,
+ 0x3f2d, 0x1fd9,
+ 0x3f2e, 0x093b,
+ 0x3f45, 0x1fda,
+ 0x3f46, 0x0953,
+ 0x3f47, 0x1fdb,
+ 0x3f48, 0x0955,
+ 0x3f4e, 0x1fdc,
+ 0x3f4f, 0x095c,
+ 0x3f51, 0x1fdd,
+ 0x3f53, 0x0960,
+ 0x3f59, 0x1fdf,
+ 0x3f5a, 0x0967,
+ 0x3f62, 0x1fe0,
+ 0x3f65, 0x0972,
+ 0x3f69, 0x1fe3,
+ 0x3f6a, 0x0977,
+ 0x3f6b, 0x1fe4,
+ 0x3f6c, 0x0979,
+ 0x3f6d, 0x1fe5,
+ 0x3f6e, 0x097b,
+ 0x3f73, 0x1fe6,
+ 0x3f74, 0x0981,
+ 0x3f75, 0x1fe7,
+ 0x3f76, 0x0983,
+ 0x3f77, 0x1fe8,
+ 0x3f78, 0x0985,
+ 0x3f79, 0x1fe9,
+ 0x3f7b, 0x0988,
+ 0x4021, 0x1feb,
+ 0x4022, 0x098d,
+ 0x4023, 0x1fec,
+ 0x4024, 0x098f,
+ 0x4029, 0x1fed,
+ 0x402a, 0x0995,
+ 0x402b, 0x1fee,
+ 0x402c, 0x0997,
+ 0x402f, 0x1fef,
+ 0x4031, 0x099c,
+ 0x4033, 0x1ff1,
+ 0x4037, 0x09a2,
+ 0x4038, 0x1ff5,
+ 0x4045, 0x09b0,
+ 0x404c, 0x2002,
+ 0x404e, 0x09b9,
+ 0x4054, 0x2004,
+ 0x4055, 0x09c0,
+ 0x4056, 0x2005,
+ 0x4057, 0x09c2,
+ 0x4058, 0x2006,
+ 0x4059, 0x09c4,
+ 0x405d, 0x2007,
+ 0x405e, 0x09c9,
+ 0x4060, 0x2008,
+ 0x4061, 0x09cc,
+ 0x4069, 0x2009,
+ 0x406a, 0x09d5,
+ 0x406b, 0x200a,
+ 0x406d, 0x09d8,
+ 0x406f, 0x200c,
+ 0x4072, 0x09dd,
+ 0x4076, 0x200f,
+ 0x407b, 0x09e6,
+ 0x4121, 0x09ea,
+ 0x4124, 0x2014,
+ 0x4126, 0x09ef,
+ 0x4129, 0x2016,
+ 0x412e, 0x09f7,
+ 0x412f, 0x201b,
+ 0x4139, 0x0a02,
+ 0x413d, 0x2025,
+ 0x413f, 0x0a08,
+ 0x4142, 0x2027,
+ 0x4143, 0x0a0c,
+ 0x4146, 0x2028,
+ 0x4147, 0x0a10,
+ 0x4149, 0x2029,
+ 0x414a, 0x0a13,
+ 0x414d, 0x202a,
+ 0x414e, 0x0a17,
+ 0x4154, 0x202b,
+ 0x4155, 0x0a1e,
+ 0x4159, 0x202c,
+ 0x415c, 0x0a25,
+ 0x415e, 0x202f,
+ 0x415f, 0x0a28,
+ 0x4164, 0x2030,
+ 0x4166, 0x0a2f,
+ 0x4169, 0x2032,
+ 0x416a, 0x0a33,
+ 0x416b, 0x2033,
+ 0x416d, 0x0a36,
+ 0x4173, 0x2035,
+ 0x4174, 0x0a3d,
+ 0x4175, 0x2036,
+ 0x4176, 0x0a3f,
+ 0x417a, 0x2037,
+ 0x417e, 0x0a47,
+ 0x4221, 0x0a48,
+ 0x4222, 0x203b,
+ 0x4229, 0x0a50,
+ 0x422b, 0x2042,
+ 0x4234, 0x0a5b,
+ 0x4238, 0x204b,
+ 0x4239, 0x0a60,
+ 0x423c, 0x204c,
+ 0x423e, 0x0a65,
+ 0x423f, 0x204e,
+ 0x4240, 0x0a67,
+ 0x4241, 0x204f,
+ 0x4242, 0x0a69,
+ 0x4245, 0x2050,
+ 0x4248, 0x0a6f,
+ 0x424b, 0x2053,
+ 0x4251, 0x0a78,
+ 0x4252, 0x2059,
+ 0x4253, 0x0a7a,
+ 0x4255, 0x205a,
+ 0x425d, 0x0a84,
+ 0x425e, 0x2062,
+ 0x4263, 0x0a8a,
+ 0x4266, 0x2067,
+ 0x4269, 0x0a90,
+ 0x426a, 0x206a,
+ 0x426f, 0x0a96,
+ 0x4270, 0x206f,
+ 0x4271, 0x0a98,
+ 0x4272, 0x2070,
+ 0x4276, 0x0a9d,
+ 0x4277, 0x2074,
+ 0x427b, 0x0aa2,
+ 0x4321, 0x2078,
+ 0x4322, 0x0aa7,
+ 0x432a, 0x2079,
+ 0x432b, 0x0ab0,
+ 0x432d, 0x207a,
+ 0x432e, 0x0ab3,
+ 0x4333, 0x207b,
+ 0x4334, 0x1df9,
+ 0x4335, 0x0aba,
+ 0x433e, 0x207c,
+ 0x433f, 0x0ac4,
+ 0x4345, 0x207d,
+ 0x4348, 0x0acd,
+ 0x434c, 0x2080,
+ 0x434d, 0x0ad2,
+ 0x434e, 0x2081,
+ 0x434f, 0x0ad4,
+ 0x4355, 0x2082,
+ 0x4357, 0x0adc,
+ 0x4359, 0x2084,
+ 0x435a, 0x0adf,
+ 0x4360, 0x2085,
+ 0x4361, 0x0ae6,
+ 0x4365, 0x2086,
+ 0x4366, 0x0aeb,
+ 0x436d, 0x2087,
+ 0x436e, 0x0af3,
+ 0x4370, 0x2088,
+ 0x4371, 0x0af6,
+ 0x4375, 0x2089,
+ 0x4377, 0x0afc,
+ 0x4379, 0x208b,
+ 0x437b, 0x0b00,
+ 0x437d, 0x208d,
+ 0x437e, 0x0b03,
+ 0x4421, 0x0b04,
+ 0x4431, 0x208e,
+ 0x4432, 0x0b15,
+ 0x4436, 0x208f,
+ 0x4437, 0x0b1a,
+ 0x4446, 0x2090,
+ 0x4447, 0x0b2a,
+ 0x4449, 0x2091,
+ 0x444a, 0x0b2d,
+ 0x4451, 0x2092,
+ 0x4452, 0x0b35,
+ 0x4453, 0x2093,
+ 0x4457, 0x0b3a,
+ 0x4459, 0x2097,
+ 0x445a, 0x0b3d,
+ 0x4462, 0x2098,
+ 0x4463, 0x0b46,
+ 0x4465, 0x2099,
+ 0x4466, 0x0b49,
+ 0x446c, 0x209a,
+ 0x446d, 0x0b50,
+ 0x4470, 0x209b,
+ 0x4472, 0x0b55,
+ 0x4474, 0x209d,
+ 0x4475, 0x0b58,
+ 0x4476, 0x209e,
+ 0x4479, 0x0b5c,
+ 0x447b, 0x20a1,
+ 0x447d, 0x0b60,
+ 0x447e, 0x20a3,
+ 0x4521, 0x20a4,
+ 0x4523, 0x0b64,
+ 0x4525, 0x20a6,
+ 0x452a, 0x0b6b,
+ 0x4531, 0x20ab,
+ 0x4532, 0x0b73,
+ 0x4535, 0x20ac,
+ 0x4536, 0x0b77,
+ 0x4537, 0x20ad,
+ 0x453a, 0x0b7b,
+ 0x453b, 0x20b0,
+ 0x453c, 0x0b7d,
+ 0x453d, 0x20b1,
+ 0x453e, 0x0b7f,
+ 0x454c, 0x20b2,
+ 0x454d, 0x0b8e,
+ 0x4553, 0x20b3,
+ 0x4554, 0x0b95,
+ 0x4562, 0x20b4,
+ 0x4563, 0x0ba4,
+ 0x4567, 0x20b5,
+ 0x4568, 0x0ba9,
+ 0x4574, 0x20b6,
+ 0x4575, 0x0bb6,
+ 0x4621, 0x0bc0,
+ 0x462d, 0x20b7,
+ 0x462f, 0x0bce,
+ 0x4635, 0x20b9,
+ 0x4637, 0x0bd6,
+ 0x463b, 0x20bb,
+ 0x463c, 0x0bdb,
+ 0x463e, 0x20bc,
+ 0x463f, 0x0bde,
+ 0x4640, 0x20bd,
+ 0x4641, 0x0be0,
+ 0x4643, 0x20be,
+ 0x4645, 0x0be4,
+ 0x464b, 0x20c0,
+ 0x464e, 0x0bed,
+ 0x4653, 0x20c3,
+ 0x4654, 0x0bf3,
+ 0x4657, 0x20c4,
+ 0x4658, 0x0bf7,
+ 0x466a, 0x20c5,
+ 0x466c, 0x0c0b,
+ 0x466f, 0x20c7,
+ 0x4670, 0x0c0f,
+ 0x4671, 0x20c8,
+ 0x4672, 0x0c11,
+ 0x4674, 0x20c9,
+ 0x4675, 0x0c14,
+ 0x4678, 0x20ca,
+ 0x4679, 0x0c18,
+ 0x467d, 0x20cb,
+ 0x467e, 0x0c1d,
+ 0x4721, 0x0c1e,
+ 0x4723, 0x20cc,
+ 0x4724, 0x0c21,
+ 0x4725, 0x20cd,
+ 0x4727, 0x0c24,
+ 0x4728, 0x20cf,
+ 0x472a, 0x0c27,
+ 0x472b, 0x20d1,
+ 0x472c, 0x0c29,
+ 0x472e, 0x20d2,
+ 0x4730, 0x0c2d,
+ 0x4733, 0x20d4,
+ 0x4736, 0x0c33,
+ 0x4739, 0x20d7,
+ 0x473b, 0x0c38,
+ 0x473d, 0x20d9,
+ 0x473f, 0x0c3c,
+ 0x4740, 0x20db,
+ 0x4741, 0x0c3e,
+ 0x4742, 0x20dc,
+ 0x4743, 0x0c40,
+ 0x4745, 0x20dd,
+ 0x4746, 0x0c43,
+ 0x4747, 0x20de,
+ 0x4749, 0x0c46,
+ 0x474c, 0x20e0,
+ 0x474d, 0x0c4a,
+ 0x474f, 0x20e1,
+ 0x4750, 0x0c4d,
+ 0x4754, 0x20e2,
+ 0x4756, 0x0c53,
+ 0x4757, 0x20e4,
+ 0x4758, 0x0c55,
+ 0x475e, 0x20e5,
+ 0x475f, 0x0c5c,
+ 0x4761, 0x20e6,
+ 0x4764, 0x0c61,
+ 0x476a, 0x20e9,
+ 0x476f, 0x0c6c,
+ 0x4777, 0x20ee,
+ 0x4779, 0x0c76,
+ 0x477b, 0x20f0,
+ 0x477c, 0x0c79,
+ 0x477d, 0x20f1,
+ 0x477e, 0x0c7b,
+ 0x4821, 0x0c7c,
+ 0x4823, 0x20f2,
+ 0x4824, 0x0c7f,
+ 0x4827, 0x20f3,
+ 0x4829, 0x0c84,
+ 0x4830, 0x20f5,
+ 0x4831, 0x0c8c,
+ 0x4835, 0x20f6,
+ 0x4836, 0x0c91,
+ 0x4837, 0x20f7,
+ 0x4838, 0x0c93,
+ 0x4843, 0x20f8,
+ 0x4847, 0x0ca2,
+ 0x4848, 0x20fc,
+ 0x4849, 0x0ca4,
+ 0x484d, 0x20fd,
+ 0x484e, 0x0ca9,
+ 0x484f, 0x20fe,
+ 0x4850, 0x0cab,
+ 0x4852, 0x20ff,
+ 0x4853, 0x0cae,
+ 0x4859, 0x2100,
+ 0x485a, 0x0cb5,
+ 0x485e, 0x2101,
+ 0x485f, 0x0cba,
+ 0x486d, 0x2102,
+ 0x486e, 0x0cc9,
+ 0x4871, 0x2103,
+ 0x4874, 0x0ccf,
+ 0x4877, 0x2106,
+ 0x4879, 0x0cd4,
+ 0x487a, 0x2108,
+ 0x487b, 0x0cd6,
+ 0x487c, 0x2109,
+ 0x487d, 0x0cd8,
+ 0x4921, 0x210a,
+ 0x4922, 0x0cdb,
+ 0x4925, 0x210b,
+ 0x4926, 0x0cdf,
+ 0x4927, 0x210c,
+ 0x4929, 0x0ce2,
+ 0x492c, 0x210e,
+ 0x492d, 0x0ce6,
+ 0x4931, 0x210f,
+ 0x4932, 0x0ceb,
+ 0x4934, 0x2110,
+ 0x4935, 0x0cee,
+ 0x4938, 0x2111,
+ 0x493a, 0x0cf3,
+ 0x4941, 0x2113,
+ 0x4943, 0x0cfc,
+ 0x4944, 0x2115,
+ 0x4945, 0x0cfe,
+ 0x4949, 0x2116,
+ 0x494a, 0x0d03,
+ 0x494b, 0x2117,
+ 0x494c, 0x0d05,
+ 0x494d, 0x2118,
+ 0x494e, 0x0d07,
+ 0x4955, 0x2119,
+ 0x4956, 0x0d0f,
+ 0x495c, 0x211a,
+ 0x495d, 0x0d16,
+ 0x495e, 0x211b,
+ 0x495f, 0x0d18,
+ 0x4961, 0x211c,
+ 0x4962, 0x0d1b,
+ 0x4963, 0x211d,
+ 0x4964, 0x0d1d,
+ 0x4965, 0x211e,
+ 0x4966, 0x0d1f,
+ 0x4968, 0x211f,
+ 0x4969, 0x0d22,
+ 0x4970, 0x2120,
+ 0x4971, 0x0d2a,
+ 0x4973, 0x2121,
+ 0x4975, 0x0d2e,
+ 0x4976, 0x2123,
+ 0x4977, 0x0d30,
+ 0x4978, 0x2124,
+ 0x497a, 0x0d33,
+ 0x497e, 0x2126,
+ 0x4a21, 0x0d38,
+ 0x4a24, 0x2127,
+ 0x4a27, 0x0d3e,
+ 0x4a28, 0x212a,
+ 0x4a29, 0x0d40,
+ 0x4a2a, 0x212b,
+ 0x4a2c, 0x0d43,
+ 0x4a31, 0x212d,
+ 0x4a32, 0x0d49,
+ 0x4a34, 0x212e,
+ 0x4a37, 0x0d4e,
+ 0x4a3b, 0x2131,
+ 0x4a3c, 0x0d53,
+ 0x4a46, 0x2132,
+ 0x4a47, 0x0d5e,
+ 0x4a4a, 0x2133,
+ 0x4a4b, 0x0d62,
+ 0x4a4d, 0x2134,
+ 0x4a4f, 0x0d66,
+ 0x4a53, 0x2136,
+ 0x4a55, 0x0d6c,
+ 0x4a59, 0x2138,
+ 0x4a5a, 0x0d71,
+ 0x4a5e, 0x2139,
+ 0x4a5f, 0x0d76,
+ 0x4a60, 0x213a,
+ 0x4a61, 0x0d78,
+ 0x4a64, 0x213b,
+ 0x4a65, 0x0d7c,
+ 0x4a69, 0x213c,
+ 0x4a6b, 0x0d82,
+ 0x4a74, 0x213e,
+ 0x4a76, 0x0d8d,
+ 0x4a77, 0x2140,
+ 0x4a78, 0x0d8f,
+ 0x4a7a, 0x2141,
+ 0x4a7b, 0x0d92,
+ 0x4a7d, 0x2142,
+ 0x4a7e, 0x0d95,
+ 0x4b21, 0x0d96,
+ 0x4b27, 0x2143,
+ 0x4b28, 0x0d9d,
+ 0x4b2b, 0x2144,
+ 0x4b2c, 0x0da1,
+ 0x4b2d, 0x2145,
+ 0x4b2e, 0x0da3,
+ 0x4b33, 0x2146,
+ 0x4b34, 0x0da9,
+ 0x4b35, 0x2147,
+ 0x4b37, 0x0dac,
+ 0x4b38, 0x2149,
+ 0x4b39, 0x0dae,
+ 0x4b3f, 0x214a,
+ 0x4b40, 0x0db5,
+ 0x4b47, 0x214b,
+ 0x4b48, 0x0dbd,
+ 0x4b49, 0x214c,
+ 0x4b4d, 0x0dc2,
+ 0x4b4f, 0x2150,
+ 0x4b51, 0x0dc6,
+ 0x4b53, 0x2152,
+ 0x4b54, 0x0dc9,
+ 0x4b55, 0x2153,
+ 0x4b56, 0x0dcb,
+ 0x4b5f, 0x2154,
+ 0x4b61, 0x0dd6,
+ 0x4b64, 0x2156,
+ 0x4b65, 0x0dda,
+ 0x4b66, 0x2157,
+ 0x4b68, 0x0ddd,
+ 0x4b6a, 0x2159,
+ 0x4b6b, 0x0de0,
+ 0x4b6f, 0x215a,
+ 0x4b71, 0x0de6,
+ 0x4b75, 0x215c,
+ 0x4b77, 0x0dec,
+ 0x4b78, 0x215e,
+ 0x4b79, 0x0dee,
+ 0x4c21, 0x215f,
+ 0x4c23, 0x0df6,
+ 0x4c28, 0x2161,
+ 0x4c29, 0x0dfc,
+ 0x4c2c, 0x2162,
+ 0x4c2d, 0x0e00,
+ 0x4c2f, 0x2163,
+ 0x4c34, 0x0e07,
+ 0x4c37, 0x2168,
+ 0x4c39, 0x0e0c,
+ 0x4c3e, 0x216a,
+ 0x4c3f, 0x0e12,
+ 0x4c40, 0x216b,
+ 0x4c41, 0x0e14,
+ 0x4c4c, 0x216c,
+ 0x4c4d, 0x0e20,
+ 0x4c4e, 0x216d,
+ 0x4c4f, 0x0e22,
+ 0x4c50, 0x216e,
+ 0x4c51, 0x0e24,
+ 0x4c56, 0x216f,
+ 0x4c57, 0x0e2a,
+ 0x4c5a, 0x2170,
+ 0x4c5b, 0x0e2e,
+ 0x4c5c, 0x2171,
+ 0x4c5d, 0x0e30,
+ 0x4c60, 0x2172,
+ 0x4c61, 0x0e34,
+ 0x4c62, 0x2173,
+ 0x4c63, 0x0e36,
+ 0x4c65, 0x2174,
+ 0x4c66, 0x0e39,
+ 0x4c75, 0x2175,
+ 0x4c76, 0x0e49,
+ 0x4c79, 0x2176,
+ 0x4c7b, 0x0e4e,
+ 0x4c7c, 0x2178,
+ 0x4d21, 0x0e52,
+ 0x4d2d, 0x217b,
+ 0x4d2e, 0x0e5f,
+ 0x4d33, 0x217c,
+ 0x4d34, 0x0e65,
+ 0x4d37, 0x217d,
+ 0x4d38, 0x0e69,
+ 0x4d3c, 0x217e,
+ 0x4d3d, 0x0e6e,
+ 0x4d3f, 0x217f,
+ 0x4d40, 0x0e71,
+ 0x4d45, 0x2180,
+ 0x4d46, 0x0e77,
+ 0x4d47, 0x2181,
+ 0x4d48, 0x0e79,
+ 0x4d52, 0x2182,
+ 0x4d53, 0x0e84,
+ 0x4d54, 0x2183,
+ 0x4d57, 0x0e88,
+ 0x4d5d, 0x2186,
+ 0x4d5e, 0x0e8f,
+ 0x4d60, 0x2187,
+ 0x4d61, 0x0e92,
+ 0x4d64, 0x2188,
+ 0x4d66, 0x0e97,
+ 0x4d67, 0x218a,
+ 0x4d68, 0x0e99,
+ 0x4d72, 0x218b,
+ 0x4d73, 0x0ea4,
+ 0x4d78, 0x218c,
+ 0x4d79, 0x0eaa,
+ 0x4e21, 0x0eb0,
+ 0x4e24, 0x218d,
+ 0x4e26, 0x0eb5,
+ 0x4e27, 0x218f,
+ 0x4e28, 0x0eb7,
+ 0x4e2a, 0x2190,
+ 0x4e2e, 0x0ebd,
+ 0x4e30, 0x2194,
+ 0x4e32, 0x0ec1,
+ 0x4e33, 0x2196,
+ 0x4e34, 0x0ec3,
+ 0x4e3d, 0x2197,
+ 0x4e3e, 0x0ecd,
+ 0x4e40, 0x2198,
+ 0x4e41, 0x0ed0,
+ 0x4e45, 0x2199,
+ 0x4e47, 0x0ed6,
+ 0x4e48, 0x219b,
+ 0x4e49, 0x0ed8,
+ 0x4e4a, 0x219c,
+ 0x4e4b, 0x0eda,
+ 0x4e4e, 0x219d,
+ 0x4e52, 0x0ee1,
+ 0x4e58, 0x21a1,
+ 0x4e5b, 0x0eea,
+ 0x4e5c, 0x21a4,
+ 0x4e5d, 0x0eec,
+ 0x4e5e, 0x21a5,
+ 0x4e60, 0x0eef,
+ 0x4e6b, 0x21a7,
+ 0x4e6c, 0x0efb,
+ 0x4e6d, 0x21a8,
+ 0x4e6e, 0x0efd,
+ 0x4e71, 0x21a9,
+ 0x4e72, 0x0f01,
+ 0x4e73, 0x21aa,
+ 0x4e74, 0x0f03,
+ 0x4e7d, 0x21ab,
+ 0x4f21, 0x0f0e,
+ 0x4f2e, 0x21ad,
+ 0x4f2f, 0x0f1c,
+ 0x4f30, 0x21ae,
+ 0x4f31, 0x0f1e,
+ 0x4f33, 0x21af,
+ 0x4f34, 0x0f21,
+ 0x4f37, 0x21b0,
+ 0x4f39, 0x0f26,
+ 0x4f3a, 0x21b2,
+ 0x4f3b, 0x0f28,
+ 0x4f3d, 0x21b3,
+ 0x4f3e, 0x0f2b,
+ 0x4f3f, 0x21b4,
+ 0x4f42, 0x0f2f,
+ 0x4f45, 0x21b7,
+ 0x4f46, 0x0f33,
+ 0x4f47, 0x21b8,
+ 0x4f48, 0x0f35,
+ 0x4f4a, 0x21b9,
+ 0x4f4c, 0x0f39,
+ 0x4f4d, 0x21bb,
+ 0x4f4f, 0x0f3c,
+ 0x4f50, 0x21bd,
+ 0x4f51, 0x0f3e,
+ 0x4f54, 0x21be,
+ 0x4f59, 0x0f46,
+ 0x4f5a, 0x21c3,
+ 0x4f5b, 0x0f48,
+ 0x4f5c, 0x21c4,
+ 0x4f5d, 0x0f4a,
+ 0x4f5f, 0x21c5,
+ 0x4f60, 0x0f4d,
+ 0x4f62, 0x21c6,
+ 0x4f63, 0x0f50,
+ 0x4f67, 0x21c7,
+ 0x4f68, 0x0f55,
+ 0x4f6a, 0x21c8,
+ 0x4f6b, 0x0f58,
+ 0x4f6c, 0x21c9,
+ 0x4f6d, 0x0f5a,
+ 0x4f6e, 0x21ca,
+ 0x4f6f, 0x0f5c,
+ 0x4f74, 0x21cb,
+ 0x4f75, 0x0f62,
+ 0x4f79, 0x21cc,
+ 0x4f7b, 0x0f68,
+ 0x4f7e, 0x21ce,
+ 0x5021, 0x0f6c,
+ 0x5025, 0x21cf,
+ 0x5026, 0x0f71,
+ 0x502d, 0x21d0,
+ 0x502f, 0x0f7a,
+ 0x5032, 0x21d2,
+ 0x5035, 0x0f80,
+ 0x503a, 0x21d5,
+ 0x503c, 0x0f87,
+ 0x503f, 0x21d7,
+ 0x5040, 0x0f8b,
+ 0x5046, 0x21d8,
+ 0x5047, 0x0f92,
+ 0x504b, 0x21d9,
+ 0x504c, 0x0f97,
+ 0x5062, 0x21da,
+ 0x5063, 0x0fae,
+ 0x5065, 0x21db,
+ 0x5066, 0x0fb1,
+ 0x506b, 0x21dc,
+ 0x506c, 0x0fb7,
+ 0x506d, 0x21dd,
+ 0x506e, 0x0fb9,
+ 0x5077, 0x21de,
+ 0x507a, 0x0fc5,
+ 0x507c, 0x21e1,
+ 0x507d, 0x0fc8,
+ 0x5121, 0x21e2,
+ 0x5123, 0x0fcc,
+ 0x5124, 0x21e4,
+ 0x5125, 0x0fce,
+ 0x5127, 0x21e5,
+ 0x5128, 0x0fd1,
+ 0x512b, 0x21e6,
+ 0x512c, 0x0fd5,
+ 0x512f, 0x21e7,
+ 0x5132, 0x0fdb,
+ 0x5135, 0x21ea,
+ 0x5138, 0x0fe1,
+ 0x5139, 0x21ed,
+ 0x513a, 0x0fe3,
+ 0x513b, 0x21ee,
+ 0x513d, 0x0fe6,
+ 0x5146, 0x21f0,
+ 0x5149, 0x0ff2,
+ 0x514b, 0x21f3,
+ 0x514c, 0x0ff5,
+ 0x514e, 0x21f4,
+ 0x5150, 0x0ff9,
+ 0x5155, 0x21f6,
+ 0x5157, 0x1000,
+ 0x515e, 0x21f8,
+ 0x515f, 0x1008,
+ 0x5161, 0x21f9,
+ 0x5163, 0x100c,
+ 0x5168, 0x21fb,
+ 0x516a, 0x1013,
+ 0x516c, 0x21fd,
+ 0x516d, 0x1016,
+ 0x516e, 0x21fe,
+ 0x5170, 0x1019,
+ 0x5171, 0x2200,
+ 0x5172, 0x101b,
+ 0x5174, 0x2201,
+ 0x5175, 0x101e,
+ 0x5177, 0x2202,
+ 0x517a, 0x1023,
+ 0x5221, 0x1028,
+ 0x5222, 0x2205,
+ 0x5223, 0x102a,
+ 0x5225, 0x2206,
+ 0x5226, 0x102d,
+ 0x5229, 0x2207,
+ 0x522a, 0x1031,
+ 0x522f, 0x2208,
+ 0x5230, 0x1037,
+ 0x5233, 0x2209,
+ 0x5234, 0x103b,
+ 0x5235, 0x220a,
+ 0x5237, 0x103e,
+ 0x523d, 0x220c,
+ 0x523e, 0x1045,
+ 0x523f, 0x220d,
+ 0x5240, 0x1047,
+ 0x5243, 0x220e,
+ 0x5244, 0x104b,
+ 0x5245, 0x220f,
+ 0x5246, 0x104d,
+ 0x5247, 0x2210,
+ 0x5248, 0x104f,
+ 0x524f, 0x2211,
+ 0x5250, 0x1057,
+ 0x5255, 0x2212,
+ 0x5256, 0x105d,
+ 0x525a, 0x2213,
+ 0x525b, 0x1062,
+ 0x5264, 0x2214,
+ 0x5266, 0x106d,
+ 0x5268, 0x2216,
+ 0x526c, 0x1073,
+ 0x526f, 0x221a,
+ 0x5270, 0x1077,
+ 0x5271, 0x221b,
+ 0x5272, 0x1079,
+ 0x5275, 0x221c,
+ 0x5276, 0x107d,
+ 0x5278, 0x221d,
+ 0x5279, 0x1080,
+ 0x527b, 0x221e,
+ 0x527c, 0x1083,
+ 0x527e, 0x221f,
+ 0x5321, 0x1086,
+ 0x5323, 0x2220,
+ 0x532d, 0x1092,
+ 0x532e, 0x222a,
+ 0x532f, 0x1094,
+ 0x5331, 0x222b,
+ 0x5332, 0x1097,
+ 0x5334, 0x222c,
+ 0x5337, 0x109c,
+ 0x5338, 0x222f,
+ 0x5339, 0x109e,
+ 0x533b, 0x2230,
+ 0x533c, 0x10a1,
+ 0x5345, 0x2231,
+ 0x5346, 0x10ab,
+ 0x5347, 0x2232,
+ 0x5348, 0x10ad,
+ 0x534a, 0x2233,
+ 0x534d, 0x10b2,
+ 0x5355, 0x2236,
+ 0x5356, 0x10bb,
+ 0x535f, 0x2237,
+ 0x5361, 0x10c6,
+ 0x5363, 0x2239,
+ 0x5364, 0x10c9,
+ 0x5366, 0x223a,
+ 0x5367, 0x10cc,
+ 0x536b, 0x223b,
+ 0x536d, 0x10d2,
+ 0x536f, 0x223d,
+ 0x5370, 0x10d5,
+ 0x5374, 0x223e,
+ 0x5375, 0x10da,
+ 0x537c, 0x223f,
+ 0x537d, 0x10e2,
+ 0x537e, 0x2240,
+ 0x5421, 0x10e4,
+ 0x5424, 0x2241,
+ 0x5425, 0x10e8,
+ 0x5426, 0x2242,
+ 0x5429, 0x10ec,
+ 0x542f, 0x2245,
+ 0x5433, 0x10f6,
+ 0x5435, 0x2249,
+ 0x5437, 0x10fa,
+ 0x5438, 0x224b,
+ 0x5439, 0x10fc,
+ 0x543c, 0x224c,
+ 0x543d, 0x1100,
+ 0x543e, 0x224d,
+ 0x5440, 0x1103,
+ 0x5444, 0x224f,
+ 0x5445, 0x1108,
+ 0x5446, 0x2250,
+ 0x5448, 0x110b,
+ 0x5449, 0x2252,
+ 0x544a, 0x110d,
+ 0x544b, 0x2253,
+ 0x544f, 0x1112,
+ 0x5453, 0x2257,
+ 0x5454, 0x1117,
+ 0x5458, 0x2258,
+ 0x5459, 0x111c,
+ 0x545c, 0x2259,
+ 0x5461, 0x1124,
+ 0x5464, 0x225e,
+ 0x5465, 0x1128,
+ 0x5466, 0x225f,
+ 0x5467, 0x112a,
+ 0x546e, 0x2260,
+ 0x546f, 0x1132,
+ 0x5470, 0x2261,
+ 0x5475, 0x1138,
+ 0x5479, 0x2266,
+ 0x547a, 0x113d,
+ 0x547e, 0x2267,
+ 0x5521, 0x2268,
+ 0x5523, 0x1144,
+ 0x5529, 0x226a,
+ 0x552a, 0x114b,
+ 0x552b, 0x226b,
+ 0x552c, 0x114d,
+ 0x552e, 0x226c,
+ 0x552f, 0x1150,
+ 0x5531, 0x226d,
+ 0x5532, 0x1153,
+ 0x5535, 0x226e,
+ 0x5539, 0x115a,
+ 0x553b, 0x2272,
+ 0x553c, 0x115d,
+ 0x553d, 0x2273,
+ 0x553e, 0x115f,
+ 0x5540, 0x2274,
+ 0x5541, 0x1162,
+ 0x5545, 0x2275,
+ 0x5546, 0x1167,
+ 0x5547, 0x2276,
+ 0x5548, 0x1169,
+ 0x554a, 0x2277,
+ 0x554c, 0x116d,
+ 0x554d, 0x2279,
+ 0x554e, 0x116f,
+ 0x5554, 0x227a,
+ 0x5555, 0x1176,
+ 0x555d, 0x227b,
+ 0x555f, 0x1180,
+ 0x5560, 0x227d,
+ 0x5561, 0x1182,
+ 0x5562, 0x227e,
+ 0x5563, 0x1184,
+ 0x556a, 0x227f,
+ 0x556d, 0x118e,
+ 0x556f, 0x2282,
+ 0x5570, 0x1191,
+ 0x5572, 0x2283,
+ 0x5574, 0x1195,
+ 0x5577, 0x15eb,
+ 0x5578, 0x1199,
+ 0x5621, 0x2285,
+ 0x5625, 0x11a4,
+ 0x562f, 0x2289,
+ 0x5631, 0x11b0,
+ 0x5634, 0x228b,
+ 0x5635, 0x11b4,
+ 0x563b, 0x228c,
+ 0x563c, 0x11bb,
+ 0x563d, 0x228d,
+ 0x563e, 0x11bd,
+ 0x563f, 0x228e,
+ 0x5641, 0x11c0,
+ 0x5644, 0x2290,
+ 0x5645, 0x11c4,
+ 0x564a, 0x2291,
+ 0x564b, 0x11ca,
+ 0x564d, 0x2292,
+ 0x564e, 0x11cd,
+ 0x5653, 0x2293,
+ 0x5654, 0x11d3,
+ 0x5655, 0x2294,
+ 0x5658, 0x11d7,
+ 0x565a, 0x2297,
+ 0x565b, 0x11da,
+ 0x565f, 0x2298,
+ 0x5660, 0x11df,
+ 0x5661, 0x2299,
+ 0x5662, 0x11e1,
+ 0x5665, 0x229a,
+ 0x5666, 0x11e5,
+ 0x5667, 0x229b,
+ 0x5669, 0x11e8,
+ 0x566e, 0x229d,
+ 0x5670, 0x11ef,
+ 0x5672, 0x229f,
+ 0x5673, 0x11f2,
+ 0x5675, 0x22a0,
+ 0x5677, 0x11f6,
+ 0x567c, 0x22a2,
+ 0x5721, 0x11fe,
+ 0x5724, 0x22a5,
+ 0x5725, 0x1202,
+ 0x5728, 0x22a6,
+ 0x572b, 0x1208,
+ 0x572c, 0x22a9,
+ 0x572d, 0x120a,
+ 0x572e, 0x22aa,
+ 0x5732, 0x120f,
+ 0x5733, 0x22ae,
+ 0x5735, 0x1212,
+ 0x5736, 0x22b0,
+ 0x5737, 0x1214,
+ 0x5738, 0x22b1,
+ 0x573d, 0x121a,
+ 0x5747, 0x22b6,
+ 0x5748, 0x1225,
+ 0x574a, 0x22b7,
+ 0x574b, 0x1228,
+ 0x5755, 0x22b8,
+ 0x5756, 0x1233,
+ 0x575b, 0x22b9,
+ 0x575f, 0x123c,
+ 0x5767, 0x22bd,
+ 0x5768, 0x1245,
+ 0x5769, 0x22be,
+ 0x576b, 0x1248,
+ 0x5821, 0x1257,
+ 0x5844, 0x22c0,
+ 0x5845, 0x127b,
+ 0x5847, 0x22c1,
+ 0x5848, 0x127e,
+ 0x5849, 0x22c2,
+ 0x584a, 0x1280,
+ 0x584c, 0x22c3,
+ 0x584e, 0x1284,
+ 0x5850, 0x22c5,
+ 0x5852, 0x1288,
+ 0x5853, 0x22c7,
+ 0x5854, 0x128a,
+ 0x5859, 0x22c8,
+ 0x585a, 0x1290,
+ 0x585b, 0x22c9,
+ 0x585d, 0x1293,
+ 0x5871, 0x22cb,
+ 0x5872, 0x12a8,
+ 0x5876, 0x22cc,
+ 0x5878, 0x12ae,
+ 0x5921, 0x12b5,
+ 0x592d, 0x22ce,
+ 0x592e, 0x12c2,
+ 0x592f, 0x22cf,
+ 0x5930, 0x12c4,
+ 0x5931, 0x22d0,
+ 0x5934, 0x12c8,
+ 0x5947, 0x22d3,
+ 0x5948, 0x12dc,
+ 0x594d, 0x22d4,
+ 0x5951, 0x12e5,
+ 0x595d, 0x22d8,
+ 0x595e, 0x12f2,
+ 0x5961, 0x22d9,
+ 0x5962, 0x12f6,
+ 0x5964, 0x22da,
+ 0x5965, 0x12f9,
+ 0x5966, 0x22db,
+ 0x5967, 0x12fb,
+ 0x596c, 0x22dc,
+ 0x596d, 0x1301,
+ 0x5974, 0x22dd,
+ 0x5976, 0x130a,
+ 0x5a21, 0x1313,
+ 0x5a25, 0x22df,
+ 0x5a60, 0x1352,
+ 0x5a6a, 0x231a,
+ 0x5a6b, 0x135d,
+ 0x5a77, 0x231b,
+ 0x5a78, 0x136a,
+ 0x5a79, 0x231c,
+ 0x5a7a, 0x136c,
+ 0x5a7e, 0x231d,
+ 0x5b21, 0x1371,
+ 0x5b23, 0x231e,
+ 0x5b24, 0x1374,
+ 0x5b26, 0x231f,
+ 0x5b27, 0x1377,
+ 0x5b29, 0x2320,
+ 0x5b2b, 0x137b,
+ 0x5b3b, 0x2322,
+ 0x5b3c, 0x138c,
+ 0x5b3d, 0x2323,
+ 0x5b3e, 0x138e,
+ 0x5b4f, 0x2324,
+ 0x5b50, 0x13a0,
+ 0x5b51, 0x2325,
+ 0x5b52, 0x13a2,
+ 0x5b5b, 0x2326,
+ 0x5b5c, 0x13ac,
+ 0x5b5e, 0x2327,
+ 0x5b5f, 0x13af,
+ 0x5b62, 0x2328,
+ 0x5b63, 0x13b3,
+ 0x5b64, 0x2329,
+ 0x5b65, 0x13b5,
+ 0x5b6b, 0x232a,
+ 0x5b6c, 0x13bc,
+ 0x5b6e, 0x232b,
+ 0x5b6f, 0x13bf,
+ 0x5b71, 0x232c,
+ 0x5b72, 0x13c2,
+ 0x5b75, 0x232d,
+ 0x5b78, 0x13c8,
+ 0x5c21, 0x13cf,
+ 0x5c3c, 0x2330,
+ 0x5c3d, 0x13eb,
+ 0x5c3f, 0x2331,
+ 0x5c40, 0x13ee,
+ 0x5c42, 0x2332,
+ 0x5c43, 0x13f1,
+ 0x5c48, 0x2333,
+ 0x5c4b, 0x13f9,
+ 0x5c51, 0x2336,
+ 0x5c52, 0x1400,
+ 0x5c57, 0x2337,
+ 0x5c58, 0x1406,
+ 0x5c60, 0x2338,
+ 0x5c61, 0x140f,
+ 0x5c63, 0x2339,
+ 0x5c65, 0x1413,
+ 0x5c69, 0x233b,
+ 0x5c6b, 0x1419,
+ 0x5c71, 0x233d,
+ 0x5c72, 0x1420,
+ 0x5c76, 0x233e,
+ 0x5c77, 0x1425,
+ 0x5c79, 0x233f,
+ 0x5c7a, 0x1428,
+ 0x5c7d, 0x2340,
+ 0x5d21, 0x2342,
+ 0x5d22, 0x142e,
+ 0x5d23, 0x2343,
+ 0x5d28, 0x1434,
+ 0x5d2a, 0x2348,
+ 0x5d2c, 0x1438,
+ 0x5d32, 0x234a,
+ 0x5d33, 0x143f,
+ 0x5d35, 0x234b,
+ 0x5d36, 0x1442,
+ 0x5d3a, 0x234c,
+ 0x5d3c, 0x1448,
+ 0x5d53, 0x234e,
+ 0x5d54, 0x1460,
+ 0x5d5b, 0x234f,
+ 0x5d5c, 0x1468,
+ 0x5d5e, 0x2350,
+ 0x5d5f, 0x146b,
+ 0x5d64, 0x2351,
+ 0x5d65, 0x1471,
+ 0x5d6b, 0x2352,
+ 0x5d6c, 0x1478,
+ 0x5d71, 0x2353,
+ 0x5d72, 0x147e,
+ 0x5d76, 0x2354,
+ 0x5d78, 0x1484,
+ 0x5d7c, 0x2356,
+ 0x5d7d, 0x1489,
+ 0x5d7e, 0x2357,
+ 0x5e21, 0x148b,
+ 0x5e2d, 0x2358,
+ 0x5e2e, 0x1498,
+ 0x5e34, 0x2359,
+ 0x5e35, 0x149f,
+ 0x5e3a, 0x235a,
+ 0x5e3b, 0x14a5,
+ 0x5e46, 0x235b,
+ 0x5e47, 0x14b1,
+ 0x5e4f, 0x235c,
+ 0x5e50, 0x14ba,
+ 0x5e51, 0x235d,
+ 0x5e53, 0x14bd,
+ 0x5e58, 0x235f,
+ 0x5e59, 0x14c3,
+ 0x5e62, 0x2360,
+ 0x5e63, 0x14cd,
+ 0x5e68, 0x2361,
+ 0x5e69, 0x14d3,
+ 0x5e6c, 0x2362,
+ 0x5e6d, 0x14d7,
+ 0x5e73, 0x2363,
+ 0x5e74, 0x14de,
+ 0x5e7c, 0x2364,
+ 0x5e7d, 0x14e7,
+ 0x5f21, 0x14e9,
+ 0x5f22, 0x2365,
+ 0x5f24, 0x14ec,
+ 0x5f25, 0x2367,
+ 0x5f26, 0x14ee,
+ 0x5f34, 0x2368,
+ 0x5f35, 0x14fd,
+ 0x5f3c, 0x2369,
+ 0x5f3e, 0x1506,
+ 0x5f3f, 0x236b,
+ 0x5f40, 0x1508,
+ 0x5f42, 0x236c,
+ 0x5f44, 0x150c,
+ 0x5f4c, 0x236e,
+ 0x5f4d, 0x1515,
+ 0x5f50, 0x236f,
+ 0x5f51, 0x1519,
+ 0x5f55, 0x2370,
+ 0x5f56, 0x151e,
+ 0x5f58, 0x2371,
+ 0x5f5a, 0x1522,
+ 0x5f5c, 0x2373,
+ 0x5f5d, 0x1525,
+ 0x5f60, 0x2374,
+ 0x5f61, 0x1529,
+ 0x5f62, 0x2375,
+ 0x5f63, 0x152b,
+ 0x5f66, 0x2376,
+ 0x5f67, 0x152f,
+ 0x5f69, 0x2377,
+ 0x5f6a, 0x1532,
+ 0x5f6b, 0x2378,
+ 0x5f6c, 0x1534,
+ 0x5f6f, 0x2379,
+ 0x5f70, 0x1538,
+ 0x5f75, 0x237a,
+ 0x5f76, 0x153e,
+ 0x5f79, 0x237b,
+ 0x5f7a, 0x1542,
+ 0x6021, 0x1547,
+ 0x6036, 0x237c,
+ 0x6038, 0x155e,
+ 0x603f, 0x237e,
+ 0x6040, 0x1566,
+ 0x6048, 0x237f,
+ 0x6049, 0x156f,
+ 0x604e, 0x2380,
+ 0x604f, 0x1575,
+ 0x6053, 0x2381,
+ 0x6054, 0x157a,
+ 0x6060, 0x2382,
+ 0x6061, 0x1587,
+ 0x6070, 0x2383,
+ 0x6071, 0x1597,
+ 0x6078, 0x2384,
+ 0x6079, 0x159f,
+ 0x607c, 0x2385,
+ 0x6121, 0x15a5,
+ 0x612b, 0x2388,
+ 0x612c, 0x15b0,
+ 0x612d, 0x2389,
+ 0x612e, 0x15b2,
+ 0x6130, 0x238a,
+ 0x6131, 0x15b5,
+ 0x6134, 0x238b,
+ 0x6135, 0x15b9,
+ 0x613b, 0x238c,
+ 0x613c, 0x15c0,
+ 0x613d, 0x238d,
+ 0x613e, 0x15c2,
+ 0x6140, 0x238e,
+ 0x6142, 0x15c6,
+ 0x6149, 0x2390,
+ 0x614a, 0x15ce,
+ 0x6150, 0x2391,
+ 0x6151, 0x15d5,
+ 0x615b, 0x2392,
+ 0x615c, 0x15e0,
+ 0x6161, 0x07aa,
+ 0x6162, 0x2393,
+ 0x6163, 0x15e7,
+ 0x6167, 0x1198,
+ 0x6168, 0x15ec,
+ 0x616e, 0x2394,
+ 0x6170, 0x15f4,
+ 0x6176, 0x2396,
+ 0x6177, 0x15fb,
+ 0x6178, 0x2397,
+ 0x6179, 0x15fd,
+ 0x617d, 0x2398,
+ 0x617e, 0x1602,
+ 0x6221, 0x1603,
+ 0x6224, 0x2399,
+ 0x6225, 0x1607,
+ 0x6228, 0x239a,
+ 0x6229, 0x160b,
+ 0x623b, 0x239b,
+ 0x6245, 0x10c5,
+ 0x6246, 0x23a5,
+ 0x624f, 0x1631,
+ 0x6250, 0x23ae,
+ 0x6251, 0x1633,
+ 0x6259, 0x23af,
+ 0x625a, 0x163c,
+ 0x6263, 0x23b0,
+ 0x6265, 0x1647,
+ 0x6266, 0x23b2,
+ 0x6267, 0x1649,
+ 0x6269, 0x23b3,
+ 0x626c, 0x164e,
+ 0x6278, 0x23b6,
+ 0x6279, 0x165b,
+ 0x627a, 0x23b7,
+ 0x627e, 0x1660,
+ 0x6321, 0x1661,
+ 0x6322, 0x23bb,
+ 0x6323, 0x1663,
+ 0x6325, 0x23bc,
+ 0x6326, 0x1666,
+ 0x632b, 0x23bd,
+ 0x632c, 0x166c,
+ 0x6334, 0x23be,
+ 0x6335, 0x1675,
+ 0x6345, 0x23bf,
+ 0x635c, 0x169c,
+ 0x6363, 0x23d6,
+ 0x6364, 0x16a4,
+ 0x636d, 0x23d7,
+ 0x636e, 0x16ae,
+ 0x6371, 0x23d8,
+ 0x6373, 0x16b3,
+ 0x6378, 0x23da,
+ 0x6379, 0x16b9,
+ 0x637e, 0x23db,
+ 0x6421, 0x16bf,
+ 0x6424, 0x23dc,
+ 0x6426, 0x16c4,
+ 0x642b, 0x23de,
+ 0x642c, 0x16ca,
+ 0x642f, 0x23df,
+ 0x6432, 0x16d0,
+ 0x6435, 0x23e2,
+ 0x6437, 0x16d5,
+ 0x6442, 0x23e4,
+ 0x6443, 0x16e1,
+ 0x6445, 0x23e5,
+ 0x6446, 0x16e4,
+ 0x6449, 0x23e6,
+ 0x644a, 0x16e8,
+ 0x6459, 0x23e7,
+ 0x645a, 0x16f8,
+ 0x645c, 0x23e8,
+ 0x645d, 0x16fb,
+ 0x645e, 0x23e9,
+ 0x645f, 0x16fd,
+ 0x6464, 0x23ea,
+ 0x6465, 0x1703,
+ 0x646b, 0x23eb,
+ 0x646d, 0x170b,
+ 0x6472, 0x23ed,
+ 0x6473, 0x1711,
+ 0x647e, 0x23ee,
+ 0x6521, 0x171d,
+ 0x6530, 0x23ef,
+ 0x6531, 0x172d,
+ 0x6539, 0x23f0,
+ 0x653a, 0x1736,
+ 0x6547, 0x23f1,
+ 0x6548, 0x1744,
+ 0x6549, 0x23f2,
+ 0x654a, 0x1746,
+ 0x654e, 0x23f3,
+ 0x654f, 0x174b,
+ 0x6570, 0x23f4,
+ 0x6571, 0x176d,
+ 0x6572, 0x23f5,
+ 0x6573, 0x176f,
+ 0x657c, 0x23f6,
+ 0x657e, 0x177a,
+ 0x6621, 0x177b,
+ 0x6623, 0x23f8,
+ 0x6624, 0x177e,
+ 0x662b, 0x23f9,
+ 0x662d, 0x1787,
+ 0x662e, 0x23fb,
+ 0x662f, 0x1789,
+ 0x6634, 0x23fc,
+ 0x6636, 0x1790,
+ 0x663f, 0x23fe,
+ 0x6640, 0x179a,
+ 0x6648, 0x23ff,
+ 0x664a, 0x17a4,
+ 0x664d, 0x2401,
+ 0x664e, 0x17a8,
+ 0x6660, 0x2402,
+ 0x6721, 0x2421,
+ 0x675b, 0x1813,
+ 0x6761, 0x245b,
+ 0x6763, 0x181b,
+ 0x6767, 0x245d,
+ 0x6768, 0x1820,
+ 0x676f, 0x245e,
+ 0x6770, 0x1828,
+ 0x6774, 0x245f,
+ 0x6777, 0x182f,
+ 0x6821, 0x1837,
+ 0x6828, 0x2462,
+ 0x6829, 0x183f,
+ 0x682c, 0x2463,
+ 0x682d, 0x1843,
+ 0x6836, 0x2464,
+ 0x6837, 0x184d,
+ 0x6838, 0x2465,
+ 0x683b, 0x1851,
+ 0x683f, 0x2468,
+ 0x6841, 0x1857,
+ 0x6845, 0x246a,
+ 0x6846, 0x185c,
+ 0x6847, 0x246b,
+ 0x684a, 0x1860,
+ 0x684e, 0x246e,
+ 0x684f, 0x1865,
+ 0x6850, 0x246f,
+ 0x6851, 0x1867,
+ 0x6853, 0x2470,
+ 0x6854, 0x186a,
+ 0x685d, 0x2471,
+ 0x685e, 0x1874,
+ 0x685f, 0x2472,
+ 0x6860, 0x1876,
+ 0x6862, 0x2473,
+ 0x6864, 0x187a,
+ 0x6865, 0x2475,
+ 0x6866, 0x187c,
+ 0x6867, 0x2476,
+ 0x6868, 0x187e,
+ 0x686b, 0x2477,
+ 0x686c, 0x1882,
+ 0x686d, 0x2478,
+ 0x686e, 0x1884,
+ 0x686f, 0x2479,
+ 0x6870, 0x1886,
+ 0x6879, 0x247a,
+ 0x687a, 0x1890,
+ 0x687c, 0x247b,
+ 0x687e, 0x1894,
+ 0x6921, 0x247d,
+ 0x6922, 0x1896,
+ 0x692d, 0x247e,
+ 0x692e, 0x18a2,
+ 0x6934, 0x247f,
+ 0x6936, 0x18aa,
+ 0x6937, 0x2481,
+ 0x6938, 0x18ac,
+ 0x6944, 0x2482,
+ 0x6945, 0x18b9,
+ 0x6946, 0x2483,
+ 0x6947, 0x18bb,
+ 0x6949, 0x2484,
+ 0x694a, 0x18be,
+ 0x6956, 0x2485,
+ 0x6957, 0x18cb,
+ 0x695a, 0x2486,
+ 0x695b, 0x18cf,
+ 0x6964, 0x2487,
+ 0x6965, 0x18d9,
+ 0x6966, 0x2488,
+ 0x6968, 0x18dc,
+ 0x6969, 0x248a,
+ 0x696a, 0x18de,
+ 0x696b, 0x248b,
+ 0x696c, 0x18e0,
+ 0x696d, 0x248c,
+ 0x6a21, 0x249e,
+ 0x6a26, 0x18f8,
+ 0x6a27, 0x24a3,
+ 0x6a29, 0x18fb,
+ 0x6a31, 0x24a5,
+ 0x6a32, 0x1904,
+ 0x6a3c, 0x24a6,
+ 0x6a3d, 0x190f,
+ 0x6a4a, 0x24a7,
+ 0x6a4b, 0x191d,
+ 0x6a4d, 0x24a8,
+ 0x6a4e, 0x1920,
+ 0x6a53, 0x24a9,
+ 0x6a54, 0x1926,
+ 0x6a5a, 0x24aa,
+ 0x6a70, 0x1942,
+ 0x6b21, 0x1951,
+ 0x6b27, 0x24c0,
+ 0x6b28, 0x1958,
+ 0x6b2a, 0x24c1,
+ 0x6b2b, 0x195b,
+ 0x6b32, 0x24c2,
+ 0x6b33, 0x1963,
+ 0x6b39, 0x24c3,
+ 0x6b3a, 0x196a,
+ 0x6b4a, 0x24c4,
+ 0x6b4c, 0x197c,
+ 0x6b4d, 0x24c6,
+ 0x6b4e, 0x197e,
+ 0x6b56, 0x24c7,
+ 0x6b57, 0x1987,
+ 0x6b5a, 0x24c8,
+ 0x6b5b, 0x198b,
+ 0x6b61, 0x24c9,
+ 0x6b62, 0x1992,
+ 0x6b77, 0x24ca,
+ 0x6b78, 0x19a8,
+ 0x6c21, 0x19af,
+ 0x6c23, 0x24cb,
+ 0x6c24, 0x19b2,
+ 0x6c29, 0x24cc,
+ 0x6c2f, 0x19bd,
+ 0x6c31, 0x24d2,
+ 0x6c32, 0x19c0,
+ 0x6c34, 0x24d3,
+ 0x6c36, 0x19c4,
+ 0x6c3e, 0x24d5,
+ 0x6c40, 0x19ce,
+ 0x6c41, 0x24d7,
+ 0x6c42, 0x19d0,
+ 0x6c47, 0x24d8,
+ 0x6c48, 0x19d6,
+ 0x6c4b, 0x24d9,
+ 0x6c4c, 0x19da,
+ 0x6c62, 0x24da,
+ 0x6c63, 0x19f1,
+ 0x6c72, 0x24db,
+ 0x6c73, 0x1a01,
+ 0x6c75, 0x24dc,
+ 0x6c76, 0x1a04,
+ 0x6c78, 0x24dd,
+ 0x6c79, 0x1a07,
+ 0x6d21, 0x24de,
+ 0x6d22, 0x1a0e,
+ 0x6d28, 0x24df,
+ 0x6d29, 0x1a15,
+ 0x6d2f, 0x24e0,
+ 0x6d31, 0x1a1d,
+ 0x6d34, 0x24e2,
+ 0x6d35, 0x1a21,
+ 0x6d36, 0x24e3,
+ 0x6d37, 0x1a23,
+ 0x6d38, 0x24e4,
+ 0x6d39, 0x1a25,
+ 0x6d3a, 0x24e5,
+ 0x6d3b, 0x1a27,
+ 0x6d3f, 0x24e6,
+ 0x6d40, 0x1a2c,
+ 0x6d42, 0x24e7,
+ 0x6d44, 0x1a30,
+ 0x6d4c, 0x24e9,
+ 0x6d4e, 0x1a3a,
+ 0x6d53, 0x24eb,
+ 0x6d54, 0x1a40,
+ 0x6d57, 0x24ec,
+ 0x6d58, 0x1a44,
+ 0x6d68, 0x24ed,
+ 0x6d69, 0x1a55,
+ 0x6d6e, 0x24ee,
+ 0x6d6f, 0x1a5b,
+ 0x6d79, 0x24ef,
+ 0x6d7b, 0x1a67,
+ 0x6e21, 0x1a6b,
+ 0x6e3c, 0x24f1,
+ 0x6e3d, 0x1a87,
+ 0x6e3f, 0x24f2,
+ 0x6e40, 0x1a8a,
+ 0x6e44, 0x24f3,
+ 0x6f21, 0x252e,
+ 0x6f72, 0x1b1a,
+ 0x7021, 0x1b27,
+ 0x7023, 0x257f,
+ 0x7024, 0x1b2a,
+ 0x702f, 0x2580,
+ 0x705a, 0x1b60,
+ 0x705c, 0x25ab,
+ 0x705e, 0x1b64,
+ 0x705f, 0x25ad,
+ 0x7060, 0x1b66,
+ 0x7069, 0x25ae,
+ 0x706a, 0x1b70,
+ 0x706c, 0x25af,
+ 0x706d, 0x1b73,
+ 0x706f, 0x25b0,
+ 0x7070, 0x1b76,
+ 0x7077, 0x25b1,
+ 0x7078, 0x1b7e,
+ 0x7079, 0x25b2,
+ 0x707a, 0x1b80,
+ 0x707c, 0x25b3,
+ 0x707d, 0x1b83,
+ 0x7121, 0x1b85,
+ 0x7128, 0x25b4,
+ 0x7129, 0x1b8d,
+ 0x712b, 0x25b5,
+ 0x712c, 0x1b90,
+ 0x712e, 0x25b6,
+ 0x712f, 0x1b93,
+ 0x7132, 0x25b7,
+ 0x7133, 0x1b97,
+ 0x713c, 0x25b8,
+ 0x713d, 0x1ba1,
+ 0x7140, 0x25b9,
+ 0x7141, 0x1ba5,
+ 0x7149, 0x25ba,
+ 0x714a, 0x1bae,
+ 0x714d, 0x25bb,
+ 0x714e, 0x1bb2,
+ 0x714f, 0x25bc,
+ 0x7151, 0x1bb5,
+ 0x715a, 0x25be,
+ 0x715b, 0x1bbf,
+ 0x715c, 0x25bf,
+ 0x715d, 0x1bc1,
+ 0x7164, 0x25c0,
+ 0x7165, 0x1bc9,
+ 0x716c, 0x25c1,
+ 0x716d, 0x1bd1,
+ 0x716f, 0x25c2,
+ 0x7170, 0x1bd4,
+ 0x7177, 0x25c3,
+ 0x7178, 0x1bdc,
+ 0x7179, 0x25c4,
+ 0x717a, 0x1bde,
+ 0x717c, 0x25c5,
+ 0x7221, 0x25c8,
+ 0x722e, 0x1bf0,
+ 0x7231, 0x25d5,
+ 0x7233, 0x1bf5,
+ 0x7239, 0x25d7,
+ 0x723a, 0x1bfc,
+ 0x7243, 0x25d8,
+ 0x7244, 0x1c06,
+ 0x7249, 0x25d9,
+ 0x724a, 0x1c0c,
+ 0x724c, 0x25da,
+ 0x724e, 0x1c10,
+ 0x724f, 0x25dc,
+ 0x7250, 0x1c12,
+ 0x7253, 0x25dd,
+ 0x7254, 0x1c16,
+ 0x7265, 0x25de,
+ 0x7266, 0x1c28,
+ 0x726e, 0x25df,
+ 0x726f, 0x1c31,
+ 0x7277, 0x25e0,
+ 0x7278, 0x1c3a,
+ 0x727d, 0x25e1,
+ 0x727e, 0x1c40,
+ 0x7321, 0x1c41,
+ 0x733f, 0x25e2,
+ 0x7340, 0x1c60,
+ 0x7346, 0x25e3,
+ 0x7347, 0x1c67,
+ 0x7348, 0x25e4,
+ 0x7349, 0x1c69,
+ 0x7356, 0x25e5,
+ 0x7357, 0x1c77,
+ 0x7359, 0x25e6,
+ 0x735a, 0x1c7a,
+ 0x7365, 0x25e7,
+ 0x7367, 0x1c87,
+ 0x736a, 0x25e9,
+ 0x736b, 0x1c8b,
+ 0x736c, 0x25ea,
+ 0x736d, 0x1c8d,
+ 0x736f, 0x25eb,
+ 0x7370, 0x1c90,
+ 0x7371, 0x25ec,
+ 0x7372, 0x1c92,
+ 0x737d, 0x25ed,
+ 0x737e, 0x1c9e,
+ 0x7421, 0x1c9f,
+ 0x7425, 0x25ee,
+ 0x7426, 0x1ca4,
+ 0x742f, 0x25ef,
+ 0x7430, 0x1cae,
+ 0x7435, 0x25f0,
+ 0x7436, 0x1cb4,
+ 0x7441, 0x25f1,
+ 0x7442, 0x1cc0,
+ 0x7447, 0x25f2,
+ 0x7448, 0x1cc6,
+ 0x744f, 0x25f3,
+ 0x7451, 0x1ccf,
+ 0x7456, 0x25f5,
+ 0x7457, 0x1cd5,
+ 0x746a, 0x25f6,
+ 0x746b, 0x1ce9,
+ 0x746f, 0x25f7,
+ 0x7470, 0x1cee,
+ 0x7475, 0x25f8,
+ 0x7476, 0x1cf4,
+ 0x7521, 0x1cfd,
+ 0x7526, 0x25f9,
+ 0x7528, 0x1d04,
+ 0x753a, 0x25fb,
+ 0x753c, 0x1d18,
+ 0x7544, 0x25fd,
+ 0x7545, 0x1d21,
+ 0x7548, 0x25fe,
+ 0x7549, 0x1d25,
+ 0x754e, 0x25ff,
+ 0x7550, 0x1d2c,
+ 0x7551, 0x2601,
+ 0x7553, 0x1d2f,
+ 0x7559, 0x2603,
+ 0x755a, 0x1d36,
+ 0x755c, 0x2604,
+ 0x755d, 0x1d39,
+ 0x7566, 0x2605,
+ 0x7568, 0x1d44,
+ 0x756f, 0x2607,
+ 0x7570, 0x1d4c,
+ 0x7572, 0x2608,
+ 0x7573, 0x1d4f,
+ 0x757c, 0x2609,
+ 0x757d, 0x1d59,
+ 0x7621, 0x1d5b,
+ 0x7623, 0x260a,
+ 0x7624, 0x1d5e,
+ 0x7626, 0x260b,
+ 0x7627, 0x1d61,
+ 0x7628, 0x260c,
+ 0x7629, 0x1d63,
+ 0x762b, 0x260d,
+ 0x762c, 0x1d66,
+ 0x7630, 0x260e,
+ 0x7631, 0x1d6b,
+ 0x7633, 0x260f,
+ 0x763f, 0x1d79,
+ 0x7645, 0x261b,
+ 0x7646, 0x1d80,
+ 0x7647, 0x261c,
+ 0x7648, 0x1d82,
+ 0x7649, 0x261d,
+ 0x764a, 0x1d84,
+ 0x764f, 0x261e,
+ 0x7721, 0x264e,
+ 0x7730, 0x1dc8,
+ 0x7732, 0x265d,
+ 0x7734, 0x1dcc,
+ 0x7735, 0x265f,
+ 0x7736, 0x1dce,
+ 0x773d, 0x2660,
+ 0x773e, 0x1dd6,
+ 0x7743, 0x2661,
+ 0x7744, 0x1ddc,
+ 0x7745, 0x2662,
+ 0x7747, 0x1ddf,
+ 0x774a, 0x2664,
+ 0x774c, 0x1de4,
+ 0x774f, 0x2666,
+ 0x7751, 0x1de9,
+ 0x775e, 0x2668,
+ 0x775f, 0x1df7,
+ 0x7761, 0x0ab9,
+ 0x7762, 0x1dfa,
+ 0x7772, 0x2669,
+ 0x7773, 0x1e0b,
+ 0x7775, 0x266a,
+ 0x7776, 0x1e0e,
+ 0x7821, 0x266b,
+ 0x7827, 0x04cc,
+ 0x7828, 0x050a,
+ 0x7829, 0x0518,
+ 0x782a, 0x2671,
+ 0x782c, 0x0594,
+ 0x782d, 0x05ce,
+ 0x782e, 0x2673,
+ 0x782f, 0x05f6,
+ 0x7830, 0x2674,
+ 0x7832, 0x0653,
+ 0x7833, 0x067e,
+ 0x7834, 0x2676,
+ 0x7835, 0x06c4,
+ 0x7836, 0x2677,
+ 0x7838, 0x073c,
+ 0x7839, 0x2679,
+ 0x783b, 0x07c3,
+ 0x783c, 0x267b,
+ 0x7840, 0x082b,
+ 0x7841, 0x267f,
+ 0x7842, 0x084e,
+ 0x7843, 0x0869,
+ 0x7844, 0x2680,
+ 0x7846, 0x090c,
+ 0x7847, 0x2682,
+ 0x7849, 0x0971,
+ 0x784a, 0x2684,
+ 0x784b, 0x099a,
+ 0x784d, 0x2685,
+ 0x784e, 0x09da,
+ 0x784f, 0x2686,
+ 0x7850, 0x09fa,
+ 0x7851, 0x2687,
+ 0x785c, 0x0bda,
+ 0x785d, 0x0bdd,
+ 0x785e, 0x0bea,
+ 0x785f, 0x0bec,
+ 0x7860, 0x0bf2,
+ 0x7861, 0x2692,
+ 0x7866, 0x0c92,
+ 0x7867, 0x0d1a,
+ 0x7868, 0x0d8c,
+ 0x7869, 0x0dbe,
+ 0x786a, 0x2697,
+ 0x786b, 0x0dfb,
+ 0x786c, 0x2698,
+ 0x786f, 0x0e70,
+ 0x7870, 0x269b,
+ 0x7871, 0x0ea3,
+ 0x7872, 0x269c,
+ 0x7878, 0x103d,
+ 0x7879, 0x10d9,
+ 0x787a, 0x26a2,
+ 0x787c, 0x10fb,
+ 0x787d, 0x1109,
+ 0x787e, 0x26a4,
+ 0x7921, 0x11a1,
+ 0x7922, 0x26a5,
+ 0x7923, 0x11ba,
+ 0x7924, 0x26a6,
+ 0x7926, 0x11d5,
+ 0x7927, 0x26a8,
+ 0x7928, 0x11fd,
+ 0x7929, 0x1219,
+ 0x2122, 0x023f,
+ 0x2123, 0x023e,
+ 0x212a, 0x0256,
+ 0x212b, 0x1e18,
+ 0x212d, 0x0257,
+ 0x2132, 0x0246,
+ 0x217e, 0x1e1a,
+ 0x2321, 0x0242,
+ 0x2328, 0x0244,
+ 0x232c, 0x023d,
+ 0x232e, 0x1e1b,
+ 0x233a, 0x0240,
+ 0x233d, 0x1e1c,
+ 0x233f, 0x0243,
+ 0x235b, 0x1e1d,
+ 0x235d, 0x1e1e,
+ 0x235f, 0x0258,
+ 0x237b, 0x0254,
+ 0x237d, 0x0255,
+ 0x237e, 0x1e1f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBTVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12GBTVMap2, 2303
+};
+
+static Gushort gb12GBTpcEUCHMap2[4566] = {
+ 0x0000, 0x0000,
+ 0xa1a1, 0x0060,
+ 0xa2b1, 0x00be,
+ 0xa2e5, 0x00f0,
+ 0xa2f1, 0x00fa,
+ 0xa3a1, 0x0106,
+ 0xa4a1, 0x0164,
+ 0xa5a1, 0x01b7,
+ 0xa6a1, 0x020d,
+ 0xa6c1, 0x0225,
+ 0xa7a1, 0x025a,
+ 0xa7d1, 0x027b,
+ 0xa8a1, 0x029c,
+ 0xa8c5, 0x02bc,
+ 0xa9a4, 0x02e2,
+ 0xaaa1, 0x032e,
+ 0xaba1, 0x038c,
+ 0xb0a1, 0x03ac,
+ 0xb0a8, 0x1e25,
+ 0xb0a9, 0x03b4,
+ 0xb0aa, 0x1e26,
+ 0xb0ab, 0x03b6,
+ 0xb0ad, 0x1e27,
+ 0xb0af, 0x03ba,
+ 0xb0b9, 0x1e29,
+ 0xb0ba, 0x03c5,
+ 0xb0c0, 0x1e2a,
+ 0xb0c1, 0x03cc,
+ 0xb0d3, 0x1e2b,
+ 0xb0d4, 0x03df,
+ 0xb0d5, 0x1e2c,
+ 0xb0d6, 0x03e1,
+ 0xb0da, 0x1e2d,
+ 0xb0db, 0x03e6,
+ 0xb0dc, 0x1e2e,
+ 0xb0dd, 0x03e8,
+ 0xb0e4, 0x1e2f,
+ 0xb0e5, 0x03f0,
+ 0xb0ec, 0x1e30,
+ 0xb0ee, 0x03f9,
+ 0xb0ef, 0x1e32,
+ 0xb0f0, 0x03fb,
+ 0xb0f3, 0x1e33,
+ 0xb0f4, 0x03ff,
+ 0xb0f7, 0x1e34,
+ 0xb0f8, 0x0403,
+ 0xb0f9, 0x1e35,
+ 0xb0fa, 0x0405,
+ 0xb1a1, 0x040a,
+ 0xb1a5, 0x1e36,
+ 0xb1a7, 0x0410,
+ 0xb1a8, 0x1e38,
+ 0xb1a9, 0x0412,
+ 0xb1ab, 0x1e39,
+ 0xb1ac, 0x0415,
+ 0xb1b2, 0x1e3a,
+ 0xb1b3, 0x041c,
+ 0xb1b4, 0x1e3b,
+ 0xb1b6, 0x041f,
+ 0xb1b7, 0x1e3d,
+ 0xb1ba, 0x0423,
+ 0xb1c1, 0x1e40,
+ 0xb1c2, 0x042b,
+ 0xb1ca, 0x1e41,
+ 0xb1cb, 0x0434,
+ 0xb1cf, 0x1e42,
+ 0xb1d1, 0x043a,
+ 0xb1d2, 0x1e44,
+ 0xb1d3, 0x043c,
+ 0xb1d5, 0x1e45,
+ 0xb1d6, 0x043f,
+ 0xb1df, 0x1e46,
+ 0xb1e2, 0x044b,
+ 0xb1e4, 0x1e49,
+ 0xb1e5, 0x044e,
+ 0xb1e7, 0x1e4a,
+ 0xb1e9, 0x0452,
+ 0xb1ea, 0x1e4c,
+ 0xb1eb, 0x0454,
+ 0xb1ee, 0x1e4d,
+ 0xb1ef, 0x0458,
+ 0xb1f1, 0x1e4e,
+ 0xb1f2, 0x045b,
+ 0xb1f4, 0x1e4f,
+ 0xb1f8, 0x0461,
+ 0xb1fd, 0x1e53,
+ 0xb1fe, 0x0467,
+ 0xb2a1, 0x0468,
+ 0xb2a6, 0x1e54,
+ 0xb2a8, 0x046f,
+ 0xb2ac, 0x1e56,
+ 0xb2ad, 0x0474,
+ 0xb2b5, 0x1e57,
+ 0xb2b6, 0x047d,
+ 0xb2b9, 0x1e58,
+ 0xb2ba, 0x0481,
+ 0xb2c6, 0x1e59,
+ 0xb2c7, 0x048e,
+ 0xb2ce, 0x1e5a,
+ 0xb2d8, 0x049f,
+ 0xb2de, 0x1e64,
+ 0xb2df, 0x04a6,
+ 0xb2e0, 0x1e65,
+ 0xb2e1, 0x04a8,
+ 0xb2e2, 0x1e66,
+ 0xb2e4, 0x04ab,
+ 0xb2ef, 0x1e68,
+ 0xb2f0, 0x04b7,
+ 0xb2f3, 0x1e69,
+ 0xb2fd, 0x04c4,
+ 0xb3a1, 0x1e73,
+ 0xb3a3, 0x04c8,
+ 0xb3a4, 0x1e75,
+ 0xb3a8, 0x04cd,
+ 0xb3a9, 0x1e79,
+ 0xb3aa, 0x04cf,
+ 0xb3ae, 0x1e7a,
+ 0xb3af, 0x04d4,
+ 0xb3b5, 0x1e7b,
+ 0xb3b6, 0x04db,
+ 0xb3b9, 0x1e7c,
+ 0xb3ba, 0x04df,
+ 0xb3be, 0x1e7d,
+ 0xb3bf, 0x04e4,
+ 0xb3c2, 0x1e7e,
+ 0xb3c3, 0x04e8,
+ 0xb3c4, 0x1e7f,
+ 0xb3c5, 0x04ea,
+ 0xb3c6, 0x1e80,
+ 0xb3c7, 0x04ec,
+ 0xb3cd, 0x1e81,
+ 0xb3ce, 0x04f3,
+ 0xb3cf, 0x1e82,
+ 0xb3d0, 0x04f5,
+ 0xb3d2, 0x1e83,
+ 0xb3d3, 0x04f8,
+ 0xb3d9, 0x1e84,
+ 0xb3da, 0x04ff,
+ 0xb3db, 0x1e85,
+ 0xb3dc, 0x0501,
+ 0xb3dd, 0x1e86,
+ 0xb3de, 0x0503,
+ 0xb3e3, 0x1e87,
+ 0xb3e4, 0x0509,
+ 0xb3e5, 0x1e88,
+ 0xb3e7, 0x050c,
+ 0xb3e8, 0x1e8a,
+ 0xb3e9, 0x050e,
+ 0xb3eb, 0x1e8b,
+ 0xb3ed, 0x0512,
+ 0xb3ef, 0x1e8d,
+ 0xb3f0, 0x0515,
+ 0xb3f1, 0x1e8e,
+ 0xb3f2, 0x0517,
+ 0xb3f3, 0x1e8f,
+ 0xb3f4, 0x0519,
+ 0xb3fa, 0x1e90,
+ 0xb3fc, 0x0521,
+ 0xb4a1, 0x1e92,
+ 0xb4a3, 0x0526,
+ 0xb4a5, 0x1e94,
+ 0xb4a7, 0x052a,
+ 0xb4ab, 0x1e96,
+ 0xb4ac, 0x052f,
+ 0xb4af, 0x1e97,
+ 0xb4b0, 0x0533,
+ 0xb4b3, 0x1e98,
+ 0xb4b5, 0x0538,
+ 0xb4b8, 0x1e9a,
+ 0xb4b9, 0x053c,
+ 0xb4bf, 0x1e9b,
+ 0xb4c0, 0x0543,
+ 0xb4c2, 0x1e9c,
+ 0xb4c3, 0x0546,
+ 0xb4c7, 0x1e9d,
+ 0xb4c8, 0x054b,
+ 0xb4ca, 0x1e9e,
+ 0xb4cb, 0x054e,
+ 0xb4cd, 0x1e9f,
+ 0xb4ce, 0x0551,
+ 0xb4cf, 0x1ea0,
+ 0xb4d0, 0x0553,
+ 0xb4d3, 0x1ea1,
+ 0xb4d5, 0x0558,
+ 0xb4da, 0x1ea3,
+ 0xb4db, 0x055e,
+ 0xb4dc, 0x1ea4,
+ 0xb4dd, 0x0560,
+ 0xb4ed, 0x1ea5,
+ 0xb4ee, 0x0571,
+ 0xb4ef, 0x1ea6,
+ 0xb4f0, 0x0573,
+ 0xb4f8, 0x1ea7,
+ 0xb4f9, 0x057c,
+ 0xb4fb, 0x1ea8,
+ 0xb4fc, 0x057f,
+ 0xb5a1, 0x0582,
+ 0xb5a3, 0x1ea9,
+ 0xb5a4, 0x0585,
+ 0xb5a5, 0x1eaa,
+ 0xb5a9, 0x058a,
+ 0xb5ac, 0x1eae,
+ 0xb5ad, 0x058e,
+ 0xb5ae, 0x1eaf,
+ 0xb5b0, 0x0591,
+ 0xb5b1, 0x1eb1,
+ 0xb5b6, 0x0597,
+ 0xb5b7, 0x1eb6,
+ 0xb5b8, 0x0599,
+ 0xb5ba, 0x1eb7,
+ 0xb5bd, 0x059e,
+ 0xb5c6, 0x1eba,
+ 0xb5c7, 0x05a8,
+ 0xb5cb, 0x1ebb,
+ 0xb5cc, 0x05ad,
+ 0xb5d0, 0x1ebc,
+ 0xb5d1, 0x05b2,
+ 0xb5d3, 0x1ebd,
+ 0xb5d4, 0x05b5,
+ 0xb5dd, 0x1ebe,
+ 0xb5e0, 0x05c1,
+ 0xb5e3, 0x1ec1,
+ 0xb5e4, 0x05c5,
+ 0xb5e6, 0x1ec2,
+ 0xb5e8, 0x05c9,
+ 0xb5ed, 0x1ec4,
+ 0xb5ee, 0x05cf,
+ 0xb5f6, 0x1ec5,
+ 0xb5f8, 0x05d9,
+ 0xb5fd, 0x1ec7,
+ 0xb5fe, 0x05df,
+ 0xb6a1, 0x05e0,
+ 0xb6a4, 0x1ec8,
+ 0xb6a6, 0x05e5,
+ 0xb6a7, 0x1eca,
+ 0xb6a8, 0x05e7,
+ 0xb6a9, 0x1ecb,
+ 0xb6aa, 0x05e9,
+ 0xb6ab, 0x1ecc,
+ 0xb6ac, 0x05eb,
+ 0xb6af, 0x1ecd,
+ 0xb6b1, 0x05f0,
+ 0xb6b3, 0x1ecf,
+ 0xb6b4, 0x05f3,
+ 0xb6b7, 0x1ed0,
+ 0xb6b8, 0x05f7,
+ 0xb6bf, 0x1ed1,
+ 0xb6c2, 0x0601,
+ 0xb6c4, 0x1ed4,
+ 0xb6c5, 0x0604,
+ 0xb6c6, 0x1ed5,
+ 0xb6c7, 0x0606,
+ 0xb6cd, 0x1ed6,
+ 0xb6ce, 0x060d,
+ 0xb6cf, 0x1ed7,
+ 0xb6d1, 0x0610,
+ 0xb6d3, 0x1ed9,
+ 0xb6d5, 0x0614,
+ 0xb6d6, 0x1edb,
+ 0xb6d7, 0x0616,
+ 0xb6d9, 0x1edc,
+ 0xb6da, 0x0619,
+ 0xb6db, 0x1edd,
+ 0xb6dc, 0x061b,
+ 0xb6e1, 0x1ede,
+ 0xb6e2, 0x0621,
+ 0xb6e9, 0x1edf,
+ 0xb6ea, 0x0629,
+ 0xb6ec, 0x1ee0,
+ 0xb6ed, 0x062c,
+ 0xb6ee, 0x1ee1,
+ 0xb6f0, 0x062f,
+ 0xb6f1, 0x1ee3,
+ 0xb6f2, 0x0631,
+ 0xb6f6, 0x1ee4,
+ 0xb6f7, 0x0636,
+ 0xb6f9, 0x1ee5,
+ 0xb6fa, 0x0639,
+ 0xb6fb, 0x1ee6,
+ 0xb6fd, 0x063c,
+ 0xb7a1, 0x1ee8,
+ 0xb7a4, 0x0641,
+ 0xb7a7, 0x1eeb,
+ 0xb7a8, 0x0645,
+ 0xb7af, 0x1eec,
+ 0xb7b1, 0x064e,
+ 0xb7b3, 0x1eee,
+ 0xb7b4, 0x0651,
+ 0xb7b6, 0x1eef,
+ 0xb7b8, 0x0655,
+ 0xb7b9, 0x1ef1,
+ 0xb7ba, 0x0657,
+ 0xb7c3, 0x1ef2,
+ 0xb7c5, 0x0662,
+ 0xb7c9, 0x1ef4,
+ 0xb7ca, 0x0667,
+ 0xb7cc, 0x1ef5,
+ 0xb7cd, 0x066a,
+ 0xb7cf, 0x1ef6,
+ 0xb7d0, 0x066d,
+ 0xb7d1, 0x1ef7,
+ 0xb7d2, 0x066f,
+ 0xb7d7, 0x1ef8,
+ 0xb7d9, 0x0676,
+ 0xb7dc, 0x1efa,
+ 0xb7dd, 0x067a,
+ 0xb7df, 0x1efb,
+ 0xb7e2, 0x067f,
+ 0xb7e3, 0x1efe,
+ 0xb7e4, 0x0681,
+ 0xb7e6, 0x1eff,
+ 0xb7e9, 0x0686,
+ 0xb7eb, 0x1f02,
+ 0xb7ee, 0x068b,
+ 0xb7ef, 0x1f05,
+ 0xb7f0, 0x068d,
+ 0xb7f4, 0x1f06,
+ 0xb7f5, 0x0692,
+ 0xb7f8, 0x1f07,
+ 0xb7f9, 0x0696,
+ 0xb8a1, 0x069c,
+ 0xb8a7, 0x1f08,
+ 0xb8a9, 0x06a4,
+ 0xb8b3, 0x1f0a,
+ 0xb8b5, 0x06b0,
+ 0xb8ba, 0x1f0c,
+ 0xb8bb, 0x06b6,
+ 0xb8bc, 0x1f0d,
+ 0xb8bd, 0x06b8,
+ 0xb8be, 0x1f0e,
+ 0xb8c0, 0x06bb,
+ 0xb8c3, 0x1f10,
+ 0xb8c4, 0x06bf,
+ 0xb8c6, 0x1f11,
+ 0xb8c8, 0x06c3,
+ 0xb8c9, 0x1f13,
+ 0xb8ca, 0x06c5,
+ 0xb8cf, 0x1f14,
+ 0xb8d0, 0x06cb,
+ 0xb8d3, 0x1f15,
+ 0xb8d7, 0x06d2,
+ 0xb8d9, 0x1f19,
+ 0xb8db, 0x06d6,
+ 0xb8e4, 0x1f1b,
+ 0xb8e5, 0x06e0,
+ 0xb8e9, 0x1f1c,
+ 0xb8ea, 0x06e5,
+ 0xb8eb, 0x1f1d,
+ 0xb8ec, 0x06e7,
+ 0xb8f3, 0x1f1e,
+ 0xb8f4, 0x06ef,
+ 0xb8f5, 0x1f1f,
+ 0xb8f7, 0x06f2,
+ 0xb8f8, 0x1f21,
+ 0xb8f9, 0x06f4,
+ 0xb9a1, 0x06fa,
+ 0xb9a8, 0x1f22,
+ 0xb9a9, 0x0702,
+ 0xb9ae, 0x1f23,
+ 0xb9af, 0x0708,
+ 0xb9b1, 0x1f24,
+ 0xb9b2, 0x070b,
+ 0xb9b3, 0x1f25,
+ 0xb9b4, 0x070d,
+ 0xb9b5, 0x1f26,
+ 0xb9b6, 0x070f,
+ 0xb9b9, 0x1f27,
+ 0xb9bb, 0x0714,
+ 0xb9c6, 0x1f29,
+ 0xb9c7, 0x0720,
+ 0xb9cb, 0x1f2a,
+ 0xb9cc, 0x0725,
+ 0xb9d0, 0x1f2b,
+ 0xb9d1, 0x072a,
+ 0xb9d8, 0x1f2c,
+ 0xb9d9, 0x0732,
+ 0xb9db, 0x1f2d,
+ 0xb9dc, 0x0735,
+ 0xb9dd, 0x1f2e,
+ 0xb9de, 0x0737,
+ 0xb9df, 0x1f2f,
+ 0xb9e0, 0x0739,
+ 0xb9e1, 0x1f30,
+ 0xb9e2, 0x073b,
+ 0xb9e3, 0x1f31,
+ 0xb9e4, 0x073d,
+ 0xb9e6, 0x1f32,
+ 0xb9e7, 0x0740,
+ 0xb9e9, 0x1f33,
+ 0xb9ed, 0x0746,
+ 0xb9ee, 0x1f37,
+ 0xb9ef, 0x0748,
+ 0xb9f1, 0x1f38,
+ 0xb9f2, 0x074b,
+ 0xb9f3, 0x1f39,
+ 0xb9f6, 0x074f,
+ 0xb9f8, 0x1f3c,
+ 0xb9f9, 0x0752,
+ 0xb9fa, 0x1f3d,
+ 0xb9fb, 0x0754,
+ 0xb9fd, 0x1f3e,
+ 0xb9fe, 0x0757,
+ 0xbaa1, 0x0758,
+ 0xbaa7, 0x1f3f,
+ 0xbaa8, 0x075f,
+ 0xbaab, 0x1f40,
+ 0xbaac, 0x0763,
+ 0xbaba, 0x1f41,
+ 0xbabb, 0x0772,
+ 0xbac5, 0x1f42,
+ 0xbac6, 0x077d,
+ 0xbad2, 0x1f43,
+ 0xbad3, 0x078a,
+ 0xbad7, 0x1f44,
+ 0xbad9, 0x0790,
+ 0xbae4, 0x1f46,
+ 0xbae5, 0x079c,
+ 0xbae8, 0x1f47,
+ 0xbae9, 0x07a0,
+ 0xbaec, 0x1f48,
+ 0xbaed, 0x07a4,
+ 0xbaf3, 0x15e5,
+ 0xbaf4, 0x07ab,
+ 0xbaf8, 0x1f49,
+ 0xbaf9, 0x07b0,
+ 0xbba1, 0x07b6,
+ 0xbba4, 0x1f4a,
+ 0xbba5, 0x07ba,
+ 0xbba6, 0x1f4b,
+ 0xbba7, 0x07bc,
+ 0xbba9, 0x1f4c,
+ 0xbbab, 0x07c0,
+ 0xbbad, 0x1f4e,
+ 0xbbaf, 0x07c4,
+ 0xbbb0, 0x1f50,
+ 0xbbb1, 0x07c6,
+ 0xbbb3, 0x1f51,
+ 0xbbb4, 0x07c9,
+ 0xbbb5, 0x1f52,
+ 0xbbb8, 0x07cd,
+ 0xbbb9, 0x1f55,
+ 0xbbbb, 0x07d0,
+ 0xbbd1, 0x1f57,
+ 0xbbd2, 0x07e7,
+ 0xbbd3, 0x1f58,
+ 0xbbd5, 0x07ea,
+ 0xbbdf, 0x1f5a,
+ 0xbbe8, 0x07fd,
+ 0xbbeb, 0x1f63,
+ 0xbbec, 0x0801,
+ 0xbbf1, 0x1f64,
+ 0xbbf2, 0x0807,
+ 0xbbf5, 0x1f65,
+ 0xbbf8, 0x080d,
+ 0xbbfa, 0x1f68,
+ 0xbbfb, 0x0810,
+ 0xbbfd, 0x1f69,
+ 0xbbfe, 0x0813,
+ 0xbca1, 0x0814,
+ 0xbca2, 0x1f6a,
+ 0xbca3, 0x0816,
+ 0xbca5, 0x1f6b,
+ 0xbca7, 0x081a,
+ 0xbca8, 0x1f6d,
+ 0xbcaa, 0x081d,
+ 0xbcab, 0x1f6f,
+ 0xbcac, 0x081f,
+ 0xbcad, 0x1f70,
+ 0xbcae, 0x0821,
+ 0xbcb6, 0x1f71,
+ 0xbcb9, 0x082c,
+ 0xbcbb, 0x1f74,
+ 0xbcbc, 0x082f,
+ 0xbcc1, 0x1f75,
+ 0xbcc2, 0x0835,
+ 0xbcc3, 0x1f76,
+ 0xbcc4, 0x0837,
+ 0xbcc6, 0x1f77,
+ 0xbcc8, 0x083b,
+ 0xbcca, 0x1f79,
+ 0xbccb, 0x083e,
+ 0xbccc, 0x1f7a,
+ 0xbcce, 0x0841,
+ 0xbcd0, 0x1f7c,
+ 0xbcd1, 0x0844,
+ 0xbcd4, 0x1f7d,
+ 0xbcd7, 0x084a,
+ 0xbcd8, 0x1f80,
+ 0xbcd9, 0x084c,
+ 0xbcdb, 0x1f81,
+ 0xbcdc, 0x084f,
+ 0xbcdd, 0x1f82,
+ 0xbcde, 0x0851,
+ 0xbcdf, 0x1f83,
+ 0xbce2, 0x0855,
+ 0xbce3, 0x1f86,
+ 0xbce5, 0x0858,
+ 0xbce8, 0x1f88,
+ 0xbce9, 0x085c,
+ 0xbcea, 0x1f89,
+ 0xbced, 0x0860,
+ 0xbcef, 0x1f8c,
+ 0xbcf4, 0x0867,
+ 0xbcf6, 0x1f91,
+ 0xbcfd, 0x0870,
+ 0xbda1, 0x0872,
+ 0xbda2, 0x1f98,
+ 0xbda8, 0x0879,
+ 0xbdab, 0x1f9e,
+ 0xbdad, 0x087e,
+ 0xbdaf, 0x1fa0,
+ 0xbdb3, 0x0884,
+ 0xbdb4, 0x1fa4,
+ 0xbdb5, 0x0886,
+ 0xbdba, 0x1fa5,
+ 0xbdbb, 0x088c,
+ 0xbdbd, 0x1fa6,
+ 0xbdc0, 0x0891,
+ 0xbdc1, 0x1fa9,
+ 0xbdc5, 0x0896,
+ 0xbdc8, 0x1fad,
+ 0xbdcb, 0x089c,
+ 0xbdce, 0x1fb0,
+ 0xbdd0, 0x08a1,
+ 0xbdd7, 0x1fb2,
+ 0xbdd8, 0x08a9,
+ 0xbdda, 0x1fb3,
+ 0xbddb, 0x08ac,
+ 0xbde0, 0x1fb4,
+ 0xbde2, 0x08b3,
+ 0xbdeb, 0x1fb6,
+ 0xbdec, 0x08bd,
+ 0xbdf4, 0x1fb7,
+ 0xbdf9, 0x08ca,
+ 0xbdfd, 0x1fbc,
+ 0xbdfe, 0x08cf,
+ 0xbea1, 0x1fbd,
+ 0xbea3, 0x08d2,
+ 0xbea5, 0x1fbf,
+ 0xbea6, 0x08d5,
+ 0xbea8, 0x1fc0,
+ 0xbea9, 0x08d8,
+ 0xbeaa, 0x1fc1,
+ 0xbeab, 0x08da,
+ 0xbead, 0x1fc2,
+ 0xbeae, 0x08dd,
+ 0xbeb1, 0x1fc3,
+ 0xbeb2, 0x08e1,
+ 0xbeb5, 0x1fc4,
+ 0xbeb8, 0x08e7,
+ 0xbeba, 0x1fc7,
+ 0xbebb, 0x08ea,
+ 0xbec0, 0x1fc8,
+ 0xbec1, 0x08f0,
+ 0xbec9, 0x1fc9,
+ 0xbeca, 0x08f9,
+ 0xbed4, 0x1fca,
+ 0xbed5, 0x0904,
+ 0xbed9, 0x1fcb,
+ 0xbeda, 0x0909,
+ 0xbedd, 0x1fcc,
+ 0xbede, 0x090d,
+ 0xbee2, 0x1fcd,
+ 0xbee3, 0x0912,
+ 0xbee5, 0x1fce,
+ 0xbee6, 0x0915,
+ 0xbee7, 0x1fcf,
+ 0xbee8, 0x0917,
+ 0xbee9, 0x1fd0,
+ 0xbeea, 0x0919,
+ 0xbeee, 0x1fd1,
+ 0xbeef, 0x091e,
+ 0xbef5, 0x1fd2,
+ 0xbef6, 0x0925,
+ 0xbef7, 0x1fd3,
+ 0xbef9, 0x0928,
+ 0xbefb, 0x1fd5,
+ 0xbefd, 0x092c,
+ 0xbfa1, 0x092e,
+ 0xbfa5, 0x1fd7,
+ 0xbfa6, 0x0933,
+ 0xbfaa, 0x1fd8,
+ 0xbfab, 0x0938,
+ 0xbfad, 0x1fd9,
+ 0xbfae, 0x093b,
+ 0xbfc5, 0x1fda,
+ 0xbfc6, 0x0953,
+ 0xbfc7, 0x1fdb,
+ 0xbfc8, 0x0955,
+ 0xbfce, 0x1fdc,
+ 0xbfcf, 0x095c,
+ 0xbfd1, 0x1fdd,
+ 0xbfd3, 0x0960,
+ 0xbfd9, 0x1fdf,
+ 0xbfda, 0x0967,
+ 0xbfe2, 0x1fe0,
+ 0xbfe5, 0x0972,
+ 0xbfe9, 0x1fe3,
+ 0xbfea, 0x0977,
+ 0xbfeb, 0x1fe4,
+ 0xbfec, 0x0979,
+ 0xbfed, 0x1fe5,
+ 0xbfee, 0x097b,
+ 0xbff3, 0x1fe6,
+ 0xbff4, 0x0981,
+ 0xbff5, 0x1fe7,
+ 0xbff6, 0x0983,
+ 0xbff7, 0x1fe8,
+ 0xbff8, 0x0985,
+ 0xbff9, 0x1fe9,
+ 0xbffb, 0x0988,
+ 0xc0a1, 0x1feb,
+ 0xc0a2, 0x098d,
+ 0xc0a3, 0x1fec,
+ 0xc0a4, 0x098f,
+ 0xc0a9, 0x1fed,
+ 0xc0aa, 0x0995,
+ 0xc0ab, 0x1fee,
+ 0xc0ac, 0x0997,
+ 0xc0af, 0x1fef,
+ 0xc0b1, 0x099c,
+ 0xc0b3, 0x1ff1,
+ 0xc0b7, 0x09a2,
+ 0xc0b8, 0x1ff5,
+ 0xc0c5, 0x09b0,
+ 0xc0cc, 0x2002,
+ 0xc0ce, 0x09b9,
+ 0xc0d4, 0x2004,
+ 0xc0d5, 0x09c0,
+ 0xc0d6, 0x2005,
+ 0xc0d7, 0x09c2,
+ 0xc0d8, 0x2006,
+ 0xc0d9, 0x09c4,
+ 0xc0dd, 0x2007,
+ 0xc0de, 0x09c9,
+ 0xc0e0, 0x2008,
+ 0xc0e1, 0x09cc,
+ 0xc0e9, 0x2009,
+ 0xc0ea, 0x09d5,
+ 0xc0eb, 0x200a,
+ 0xc0ed, 0x09d8,
+ 0xc0ef, 0x200c,
+ 0xc0f2, 0x09dd,
+ 0xc0f6, 0x200f,
+ 0xc0fb, 0x09e6,
+ 0xc1a1, 0x09ea,
+ 0xc1a4, 0x2014,
+ 0xc1a6, 0x09ef,
+ 0xc1a9, 0x2016,
+ 0xc1ae, 0x09f7,
+ 0xc1af, 0x201b,
+ 0xc1b9, 0x0a02,
+ 0xc1bd, 0x2025,
+ 0xc1bf, 0x0a08,
+ 0xc1c2, 0x2027,
+ 0xc1c3, 0x0a0c,
+ 0xc1c6, 0x2028,
+ 0xc1c7, 0x0a10,
+ 0xc1c9, 0x2029,
+ 0xc1ca, 0x0a13,
+ 0xc1cd, 0x202a,
+ 0xc1ce, 0x0a17,
+ 0xc1d4, 0x202b,
+ 0xc1d5, 0x0a1e,
+ 0xc1d9, 0x202c,
+ 0xc1dc, 0x0a25,
+ 0xc1de, 0x202f,
+ 0xc1df, 0x0a28,
+ 0xc1e4, 0x2030,
+ 0xc1e6, 0x0a2f,
+ 0xc1e9, 0x2032,
+ 0xc1ea, 0x0a33,
+ 0xc1eb, 0x2033,
+ 0xc1ed, 0x0a36,
+ 0xc1f3, 0x2035,
+ 0xc1f4, 0x0a3d,
+ 0xc1f5, 0x2036,
+ 0xc1f6, 0x0a3f,
+ 0xc1fa, 0x2037,
+ 0xc1fe, 0x0a47,
+ 0xc2a1, 0x0a48,
+ 0xc2a2, 0x203b,
+ 0xc2a9, 0x0a50,
+ 0xc2ab, 0x2042,
+ 0xc2b4, 0x0a5b,
+ 0xc2b8, 0x204b,
+ 0xc2b9, 0x0a60,
+ 0xc2bc, 0x204c,
+ 0xc2be, 0x0a65,
+ 0xc2bf, 0x204e,
+ 0xc2c0, 0x0a67,
+ 0xc2c1, 0x204f,
+ 0xc2c2, 0x0a69,
+ 0xc2c5, 0x2050,
+ 0xc2c8, 0x0a6f,
+ 0xc2cb, 0x2053,
+ 0xc2d1, 0x0a78,
+ 0xc2d2, 0x2059,
+ 0xc2d3, 0x0a7a,
+ 0xc2d5, 0x205a,
+ 0xc2dd, 0x0a84,
+ 0xc2de, 0x2062,
+ 0xc2e3, 0x0a8a,
+ 0xc2e6, 0x2067,
+ 0xc2e9, 0x0a90,
+ 0xc2ea, 0x206a,
+ 0xc2ef, 0x0a96,
+ 0xc2f0, 0x206f,
+ 0xc2f1, 0x0a98,
+ 0xc2f2, 0x2070,
+ 0xc2f6, 0x0a9d,
+ 0xc2f7, 0x2074,
+ 0xc2fb, 0x0aa2,
+ 0xc3a1, 0x2078,
+ 0xc3a2, 0x0aa7,
+ 0xc3aa, 0x2079,
+ 0xc3ab, 0x0ab0,
+ 0xc3ad, 0x207a,
+ 0xc3ae, 0x0ab3,
+ 0xc3b3, 0x207b,
+ 0xc3b4, 0x1df9,
+ 0xc3b5, 0x0aba,
+ 0xc3be, 0x207c,
+ 0xc3bf, 0x0ac4,
+ 0xc3c5, 0x207d,
+ 0xc3c8, 0x0acd,
+ 0xc3cc, 0x2080,
+ 0xc3cd, 0x0ad2,
+ 0xc3ce, 0x2081,
+ 0xc3cf, 0x0ad4,
+ 0xc3d5, 0x2082,
+ 0xc3d7, 0x0adc,
+ 0xc3d9, 0x2084,
+ 0xc3da, 0x0adf,
+ 0xc3e0, 0x2085,
+ 0xc3e1, 0x0ae6,
+ 0xc3e5, 0x2086,
+ 0xc3e6, 0x0aeb,
+ 0xc3ed, 0x2087,
+ 0xc3ee, 0x0af3,
+ 0xc3f0, 0x2088,
+ 0xc3f1, 0x0af6,
+ 0xc3f5, 0x2089,
+ 0xc3f7, 0x0afc,
+ 0xc3f9, 0x208b,
+ 0xc3fb, 0x0b00,
+ 0xc3fd, 0x208d,
+ 0xc3fe, 0x0b03,
+ 0xc4a1, 0x0b04,
+ 0xc4b1, 0x208e,
+ 0xc4b2, 0x0b15,
+ 0xc4b6, 0x208f,
+ 0xc4b7, 0x0b1a,
+ 0xc4c6, 0x2090,
+ 0xc4c7, 0x0b2a,
+ 0xc4c9, 0x2091,
+ 0xc4ca, 0x0b2d,
+ 0xc4d1, 0x2092,
+ 0xc4d2, 0x0b35,
+ 0xc4d3, 0x2093,
+ 0xc4d7, 0x0b3a,
+ 0xc4d9, 0x2097,
+ 0xc4da, 0x0b3d,
+ 0xc4e2, 0x2098,
+ 0xc4e3, 0x0b46,
+ 0xc4e5, 0x2099,
+ 0xc4e6, 0x0b49,
+ 0xc4ec, 0x209a,
+ 0xc4ed, 0x0b50,
+ 0xc4f0, 0x209b,
+ 0xc4f2, 0x0b55,
+ 0xc4f4, 0x209d,
+ 0xc4f5, 0x0b58,
+ 0xc4f6, 0x209e,
+ 0xc4f9, 0x0b5c,
+ 0xc4fb, 0x20a1,
+ 0xc4fd, 0x0b60,
+ 0xc4fe, 0x20a3,
+ 0xc5a1, 0x20a4,
+ 0xc5a3, 0x0b64,
+ 0xc5a5, 0x20a6,
+ 0xc5aa, 0x0b6b,
+ 0xc5b1, 0x20ab,
+ 0xc5b2, 0x0b73,
+ 0xc5b5, 0x20ac,
+ 0xc5b6, 0x0b77,
+ 0xc5b7, 0x20ad,
+ 0xc5ba, 0x0b7b,
+ 0xc5bb, 0x20b0,
+ 0xc5bc, 0x0b7d,
+ 0xc5bd, 0x20b1,
+ 0xc5be, 0x0b7f,
+ 0xc5cc, 0x20b2,
+ 0xc5cd, 0x0b8e,
+ 0xc5d3, 0x20b3,
+ 0xc5d4, 0x0b95,
+ 0xc5e2, 0x20b4,
+ 0xc5e3, 0x0ba4,
+ 0xc5e7, 0x20b5,
+ 0xc5e8, 0x0ba9,
+ 0xc5f4, 0x20b6,
+ 0xc5f5, 0x0bb6,
+ 0xc6a1, 0x0bc0,
+ 0xc6ad, 0x20b7,
+ 0xc6af, 0x0bce,
+ 0xc6b5, 0x20b9,
+ 0xc6b7, 0x0bd6,
+ 0xc6bb, 0x20bb,
+ 0xc6bc, 0x0bdb,
+ 0xc6be, 0x20bc,
+ 0xc6bf, 0x0bde,
+ 0xc6c0, 0x20bd,
+ 0xc6c1, 0x0be0,
+ 0xc6c3, 0x20be,
+ 0xc6c5, 0x0be4,
+ 0xc6cb, 0x20c0,
+ 0xc6ce, 0x0bed,
+ 0xc6d3, 0x20c3,
+ 0xc6d4, 0x0bf3,
+ 0xc6d7, 0x20c4,
+ 0xc6d8, 0x0bf7,
+ 0xc6ea, 0x20c5,
+ 0xc6ec, 0x0c0b,
+ 0xc6ef, 0x20c7,
+ 0xc6f0, 0x0c0f,
+ 0xc6f1, 0x20c8,
+ 0xc6f2, 0x0c11,
+ 0xc6f4, 0x20c9,
+ 0xc6f5, 0x0c14,
+ 0xc6f8, 0x20ca,
+ 0xc6f9, 0x0c18,
+ 0xc6fd, 0x20cb,
+ 0xc6fe, 0x0c1d,
+ 0xc7a1, 0x0c1e,
+ 0xc7a3, 0x20cc,
+ 0xc7a4, 0x0c21,
+ 0xc7a5, 0x20cd,
+ 0xc7a7, 0x0c24,
+ 0xc7a8, 0x20cf,
+ 0xc7aa, 0x0c27,
+ 0xc7ab, 0x20d1,
+ 0xc7ac, 0x0c29,
+ 0xc7ae, 0x20d2,
+ 0xc7b0, 0x0c2d,
+ 0xc7b3, 0x20d4,
+ 0xc7b6, 0x0c33,
+ 0xc7b9, 0x20d7,
+ 0xc7bb, 0x0c38,
+ 0xc7bd, 0x20d9,
+ 0xc7bf, 0x0c3c,
+ 0xc7c0, 0x20db,
+ 0xc7c1, 0x0c3e,
+ 0xc7c2, 0x20dc,
+ 0xc7c3, 0x0c40,
+ 0xc7c5, 0x20dd,
+ 0xc7c6, 0x0c43,
+ 0xc7c7, 0x20de,
+ 0xc7c9, 0x0c46,
+ 0xc7cc, 0x20e0,
+ 0xc7cd, 0x0c4a,
+ 0xc7cf, 0x20e1,
+ 0xc7d0, 0x0c4d,
+ 0xc7d4, 0x20e2,
+ 0xc7d6, 0x0c53,
+ 0xc7d7, 0x20e4,
+ 0xc7d8, 0x0c55,
+ 0xc7de, 0x20e5,
+ 0xc7df, 0x0c5c,
+ 0xc7e1, 0x20e6,
+ 0xc7e4, 0x0c61,
+ 0xc7ea, 0x20e9,
+ 0xc7ef, 0x0c6c,
+ 0xc7f7, 0x20ee,
+ 0xc7f9, 0x0c76,
+ 0xc7fb, 0x20f0,
+ 0xc7fc, 0x0c79,
+ 0xc7fd, 0x20f1,
+ 0xc7fe, 0x0c7b,
+ 0xc8a1, 0x0c7c,
+ 0xc8a3, 0x20f2,
+ 0xc8a4, 0x0c7f,
+ 0xc8a7, 0x20f3,
+ 0xc8a9, 0x0c84,
+ 0xc8b0, 0x20f5,
+ 0xc8b1, 0x0c8c,
+ 0xc8b5, 0x20f6,
+ 0xc8b6, 0x0c91,
+ 0xc8b7, 0x20f7,
+ 0xc8b8, 0x0c93,
+ 0xc8c3, 0x20f8,
+ 0xc8c7, 0x0ca2,
+ 0xc8c8, 0x20fc,
+ 0xc8c9, 0x0ca4,
+ 0xc8cd, 0x20fd,
+ 0xc8ce, 0x0ca9,
+ 0xc8cf, 0x20fe,
+ 0xc8d0, 0x0cab,
+ 0xc8d2, 0x20ff,
+ 0xc8d3, 0x0cae,
+ 0xc8d9, 0x2100,
+ 0xc8da, 0x0cb5,
+ 0xc8de, 0x2101,
+ 0xc8df, 0x0cba,
+ 0xc8ed, 0x2102,
+ 0xc8ee, 0x0cc9,
+ 0xc8f1, 0x2103,
+ 0xc8f4, 0x0ccf,
+ 0xc8f7, 0x2106,
+ 0xc8f9, 0x0cd4,
+ 0xc8fa, 0x2108,
+ 0xc8fb, 0x0cd6,
+ 0xc8fc, 0x2109,
+ 0xc8fd, 0x0cd8,
+ 0xc9a1, 0x210a,
+ 0xc9a2, 0x0cdb,
+ 0xc9a5, 0x210b,
+ 0xc9a6, 0x0cdf,
+ 0xc9a7, 0x210c,
+ 0xc9a9, 0x0ce2,
+ 0xc9ac, 0x210e,
+ 0xc9ad, 0x0ce6,
+ 0xc9b1, 0x210f,
+ 0xc9b2, 0x0ceb,
+ 0xc9b4, 0x2110,
+ 0xc9b5, 0x0cee,
+ 0xc9b8, 0x2111,
+ 0xc9ba, 0x0cf3,
+ 0xc9c1, 0x2113,
+ 0xc9c3, 0x0cfc,
+ 0xc9c4, 0x2115,
+ 0xc9c5, 0x0cfe,
+ 0xc9c9, 0x2116,
+ 0xc9ca, 0x0d03,
+ 0xc9cb, 0x2117,
+ 0xc9cc, 0x0d05,
+ 0xc9cd, 0x2118,
+ 0xc9ce, 0x0d07,
+ 0xc9d5, 0x2119,
+ 0xc9d6, 0x0d0f,
+ 0xc9dc, 0x211a,
+ 0xc9dd, 0x0d16,
+ 0xc9de, 0x211b,
+ 0xc9df, 0x0d18,
+ 0xc9e1, 0x211c,
+ 0xc9e2, 0x0d1b,
+ 0xc9e3, 0x211d,
+ 0xc9e4, 0x0d1d,
+ 0xc9e5, 0x211e,
+ 0xc9e6, 0x0d1f,
+ 0xc9e8, 0x211f,
+ 0xc9e9, 0x0d22,
+ 0xc9f0, 0x2120,
+ 0xc9f1, 0x0d2a,
+ 0xc9f3, 0x2121,
+ 0xc9f5, 0x0d2e,
+ 0xc9f6, 0x2123,
+ 0xc9f7, 0x0d30,
+ 0xc9f8, 0x2124,
+ 0xc9fa, 0x0d33,
+ 0xc9fe, 0x2126,
+ 0xcaa1, 0x0d38,
+ 0xcaa4, 0x2127,
+ 0xcaa7, 0x0d3e,
+ 0xcaa8, 0x212a,
+ 0xcaa9, 0x0d40,
+ 0xcaaa, 0x212b,
+ 0xcaac, 0x0d43,
+ 0xcab1, 0x212d,
+ 0xcab2, 0x0d49,
+ 0xcab4, 0x212e,
+ 0xcab7, 0x0d4e,
+ 0xcabb, 0x2131,
+ 0xcabc, 0x0d53,
+ 0xcac6, 0x2132,
+ 0xcac7, 0x0d5e,
+ 0xcaca, 0x2133,
+ 0xcacb, 0x0d62,
+ 0xcacd, 0x2134,
+ 0xcacf, 0x0d66,
+ 0xcad3, 0x2136,
+ 0xcad5, 0x0d6c,
+ 0xcad9, 0x2138,
+ 0xcada, 0x0d71,
+ 0xcade, 0x2139,
+ 0xcadf, 0x0d76,
+ 0xcae0, 0x213a,
+ 0xcae1, 0x0d78,
+ 0xcae4, 0x213b,
+ 0xcae5, 0x0d7c,
+ 0xcae9, 0x213c,
+ 0xcaeb, 0x0d82,
+ 0xcaf4, 0x213e,
+ 0xcaf6, 0x0d8d,
+ 0xcaf7, 0x2140,
+ 0xcaf8, 0x0d8f,
+ 0xcafa, 0x2141,
+ 0xcafb, 0x0d92,
+ 0xcafd, 0x2142,
+ 0xcafe, 0x0d95,
+ 0xcba1, 0x0d96,
+ 0xcba7, 0x2143,
+ 0xcba8, 0x0d9d,
+ 0xcbab, 0x2144,
+ 0xcbac, 0x0da1,
+ 0xcbad, 0x2145,
+ 0xcbae, 0x0da3,
+ 0xcbb3, 0x2146,
+ 0xcbb4, 0x0da9,
+ 0xcbb5, 0x2147,
+ 0xcbb7, 0x0dac,
+ 0xcbb8, 0x2149,
+ 0xcbb9, 0x0dae,
+ 0xcbbf, 0x214a,
+ 0xcbc0, 0x0db5,
+ 0xcbc7, 0x214b,
+ 0xcbc8, 0x0dbd,
+ 0xcbc9, 0x214c,
+ 0xcbcd, 0x0dc2,
+ 0xcbcf, 0x2150,
+ 0xcbd1, 0x0dc6,
+ 0xcbd3, 0x2152,
+ 0xcbd4, 0x0dc9,
+ 0xcbd5, 0x2153,
+ 0xcbd6, 0x0dcb,
+ 0xcbdf, 0x2154,
+ 0xcbe1, 0x0dd6,
+ 0xcbe4, 0x2156,
+ 0xcbe5, 0x0dda,
+ 0xcbe6, 0x2157,
+ 0xcbe8, 0x0ddd,
+ 0xcbea, 0x2159,
+ 0xcbeb, 0x0de0,
+ 0xcbef, 0x215a,
+ 0xcbf1, 0x0de6,
+ 0xcbf5, 0x215c,
+ 0xcbf7, 0x0dec,
+ 0xcbf8, 0x215e,
+ 0xcbf9, 0x0dee,
+ 0xcca1, 0x215f,
+ 0xcca3, 0x0df6,
+ 0xcca8, 0x2161,
+ 0xcca9, 0x0dfc,
+ 0xccac, 0x2162,
+ 0xccad, 0x0e00,
+ 0xccaf, 0x2163,
+ 0xccb4, 0x0e07,
+ 0xccb7, 0x2168,
+ 0xccb9, 0x0e0c,
+ 0xccbe, 0x216a,
+ 0xccbf, 0x0e12,
+ 0xccc0, 0x216b,
+ 0xccc1, 0x0e14,
+ 0xcccc, 0x216c,
+ 0xcccd, 0x0e20,
+ 0xccce, 0x216d,
+ 0xcccf, 0x0e22,
+ 0xccd0, 0x216e,
+ 0xccd1, 0x0e24,
+ 0xccd6, 0x216f,
+ 0xccd7, 0x0e2a,
+ 0xccda, 0x2170,
+ 0xccdb, 0x0e2e,
+ 0xccdc, 0x2171,
+ 0xccdd, 0x0e30,
+ 0xcce0, 0x2172,
+ 0xcce1, 0x0e34,
+ 0xcce2, 0x2173,
+ 0xcce3, 0x0e36,
+ 0xcce5, 0x2174,
+ 0xcce6, 0x0e39,
+ 0xccf5, 0x2175,
+ 0xccf6, 0x0e49,
+ 0xccf9, 0x2176,
+ 0xccfb, 0x0e4e,
+ 0xccfc, 0x2178,
+ 0xcda1, 0x0e52,
+ 0xcdad, 0x217b,
+ 0xcdae, 0x0e5f,
+ 0xcdb3, 0x217c,
+ 0xcdb4, 0x0e65,
+ 0xcdb7, 0x217d,
+ 0xcdb8, 0x0e69,
+ 0xcdbc, 0x217e,
+ 0xcdbd, 0x0e6e,
+ 0xcdbf, 0x217f,
+ 0xcdc0, 0x0e71,
+ 0xcdc5, 0x2180,
+ 0xcdc6, 0x0e77,
+ 0xcdc7, 0x2181,
+ 0xcdc8, 0x0e79,
+ 0xcdd2, 0x2182,
+ 0xcdd3, 0x0e84,
+ 0xcdd4, 0x2183,
+ 0xcdd7, 0x0e88,
+ 0xcddd, 0x2186,
+ 0xcdde, 0x0e8f,
+ 0xcde0, 0x2187,
+ 0xcde1, 0x0e92,
+ 0xcde4, 0x2188,
+ 0xcde6, 0x0e97,
+ 0xcde7, 0x218a,
+ 0xcde8, 0x0e99,
+ 0xcdf2, 0x218b,
+ 0xcdf3, 0x0ea4,
+ 0xcdf8, 0x218c,
+ 0xcdf9, 0x0eaa,
+ 0xcea1, 0x0eb0,
+ 0xcea4, 0x218d,
+ 0xcea6, 0x0eb5,
+ 0xcea7, 0x218f,
+ 0xcea8, 0x0eb7,
+ 0xceaa, 0x2190,
+ 0xceae, 0x0ebd,
+ 0xceb0, 0x2194,
+ 0xceb2, 0x0ec1,
+ 0xceb3, 0x2196,
+ 0xceb4, 0x0ec3,
+ 0xcebd, 0x2197,
+ 0xcebe, 0x0ecd,
+ 0xcec0, 0x2198,
+ 0xcec1, 0x0ed0,
+ 0xcec5, 0x2199,
+ 0xcec7, 0x0ed6,
+ 0xcec8, 0x219b,
+ 0xcec9, 0x0ed8,
+ 0xceca, 0x219c,
+ 0xcecb, 0x0eda,
+ 0xcece, 0x219d,
+ 0xced2, 0x0ee1,
+ 0xced8, 0x21a1,
+ 0xcedb, 0x0eea,
+ 0xcedc, 0x21a4,
+ 0xcedd, 0x0eec,
+ 0xcede, 0x21a5,
+ 0xcee0, 0x0eef,
+ 0xceeb, 0x21a7,
+ 0xceec, 0x0efb,
+ 0xceed, 0x21a8,
+ 0xceee, 0x0efd,
+ 0xcef1, 0x21a9,
+ 0xcef2, 0x0f01,
+ 0xcef3, 0x21aa,
+ 0xcef4, 0x0f03,
+ 0xcefd, 0x21ab,
+ 0xcfa1, 0x0f0e,
+ 0xcfae, 0x21ad,
+ 0xcfaf, 0x0f1c,
+ 0xcfb0, 0x21ae,
+ 0xcfb1, 0x0f1e,
+ 0xcfb3, 0x21af,
+ 0xcfb4, 0x0f21,
+ 0xcfb7, 0x21b0,
+ 0xcfb9, 0x0f26,
+ 0xcfba, 0x21b2,
+ 0xcfbb, 0x0f28,
+ 0xcfbd, 0x21b3,
+ 0xcfbe, 0x0f2b,
+ 0xcfbf, 0x21b4,
+ 0xcfc2, 0x0f2f,
+ 0xcfc5, 0x21b7,
+ 0xcfc6, 0x0f33,
+ 0xcfc7, 0x21b8,
+ 0xcfc8, 0x0f35,
+ 0xcfca, 0x21b9,
+ 0xcfcc, 0x0f39,
+ 0xcfcd, 0x21bb,
+ 0xcfcf, 0x0f3c,
+ 0xcfd0, 0x21bd,
+ 0xcfd1, 0x0f3e,
+ 0xcfd4, 0x21be,
+ 0xcfd9, 0x0f46,
+ 0xcfda, 0x21c3,
+ 0xcfdb, 0x0f48,
+ 0xcfdc, 0x21c4,
+ 0xcfdd, 0x0f4a,
+ 0xcfdf, 0x21c5,
+ 0xcfe0, 0x0f4d,
+ 0xcfe2, 0x21c6,
+ 0xcfe3, 0x0f50,
+ 0xcfe7, 0x21c7,
+ 0xcfe8, 0x0f55,
+ 0xcfea, 0x21c8,
+ 0xcfeb, 0x0f58,
+ 0xcfec, 0x21c9,
+ 0xcfed, 0x0f5a,
+ 0xcfee, 0x21ca,
+ 0xcfef, 0x0f5c,
+ 0xcff4, 0x21cb,
+ 0xcff5, 0x0f62,
+ 0xcff9, 0x21cc,
+ 0xcffb, 0x0f68,
+ 0xcffe, 0x21ce,
+ 0xd0a1, 0x0f6c,
+ 0xd0a5, 0x21cf,
+ 0xd0a6, 0x0f71,
+ 0xd0ad, 0x21d0,
+ 0xd0af, 0x0f7a,
+ 0xd0b2, 0x21d2,
+ 0xd0b5, 0x0f80,
+ 0xd0ba, 0x21d5,
+ 0xd0bc, 0x0f87,
+ 0xd0bf, 0x21d7,
+ 0xd0c0, 0x0f8b,
+ 0xd0c6, 0x21d8,
+ 0xd0c7, 0x0f92,
+ 0xd0cb, 0x21d9,
+ 0xd0cc, 0x0f97,
+ 0xd0e2, 0x21da,
+ 0xd0e3, 0x0fae,
+ 0xd0e5, 0x21db,
+ 0xd0e6, 0x0fb1,
+ 0xd0eb, 0x21dc,
+ 0xd0ec, 0x0fb7,
+ 0xd0ed, 0x21dd,
+ 0xd0ee, 0x0fb9,
+ 0xd0f7, 0x21de,
+ 0xd0fa, 0x0fc5,
+ 0xd0fc, 0x21e1,
+ 0xd0fd, 0x0fc8,
+ 0xd1a1, 0x21e2,
+ 0xd1a3, 0x0fcc,
+ 0xd1a4, 0x21e4,
+ 0xd1a5, 0x0fce,
+ 0xd1a7, 0x21e5,
+ 0xd1a8, 0x0fd1,
+ 0xd1ab, 0x21e6,
+ 0xd1ac, 0x0fd5,
+ 0xd1af, 0x21e7,
+ 0xd1b2, 0x0fdb,
+ 0xd1b5, 0x21ea,
+ 0xd1b8, 0x0fe1,
+ 0xd1b9, 0x21ed,
+ 0xd1ba, 0x0fe3,
+ 0xd1bb, 0x21ee,
+ 0xd1bd, 0x0fe6,
+ 0xd1c6, 0x21f0,
+ 0xd1c9, 0x0ff2,
+ 0xd1cb, 0x21f3,
+ 0xd1cc, 0x0ff5,
+ 0xd1ce, 0x21f4,
+ 0xd1d0, 0x0ff9,
+ 0xd1d5, 0x21f6,
+ 0xd1d7, 0x1000,
+ 0xd1de, 0x21f8,
+ 0xd1df, 0x1008,
+ 0xd1e1, 0x21f9,
+ 0xd1e3, 0x100c,
+ 0xd1e8, 0x21fb,
+ 0xd1ea, 0x1013,
+ 0xd1ec, 0x21fd,
+ 0xd1ed, 0x1016,
+ 0xd1ee, 0x21fe,
+ 0xd1f0, 0x1019,
+ 0xd1f1, 0x2200,
+ 0xd1f2, 0x101b,
+ 0xd1f4, 0x2201,
+ 0xd1f5, 0x101e,
+ 0xd1f7, 0x2202,
+ 0xd1fa, 0x1023,
+ 0xd2a1, 0x1028,
+ 0xd2a2, 0x2205,
+ 0xd2a3, 0x102a,
+ 0xd2a5, 0x2206,
+ 0xd2a6, 0x102d,
+ 0xd2a9, 0x2207,
+ 0xd2aa, 0x1031,
+ 0xd2af, 0x2208,
+ 0xd2b0, 0x1037,
+ 0xd2b3, 0x2209,
+ 0xd2b4, 0x103b,
+ 0xd2b5, 0x220a,
+ 0xd2b7, 0x103e,
+ 0xd2bd, 0x220c,
+ 0xd2be, 0x1045,
+ 0xd2bf, 0x220d,
+ 0xd2c0, 0x1047,
+ 0xd2c3, 0x220e,
+ 0xd2c4, 0x104b,
+ 0xd2c5, 0x220f,
+ 0xd2c6, 0x104d,
+ 0xd2c7, 0x2210,
+ 0xd2c8, 0x104f,
+ 0xd2cf, 0x2211,
+ 0xd2d0, 0x1057,
+ 0xd2d5, 0x2212,
+ 0xd2d6, 0x105d,
+ 0xd2da, 0x2213,
+ 0xd2db, 0x1062,
+ 0xd2e4, 0x2214,
+ 0xd2e6, 0x106d,
+ 0xd2e8, 0x2216,
+ 0xd2ec, 0x1073,
+ 0xd2ef, 0x221a,
+ 0xd2f0, 0x1077,
+ 0xd2f1, 0x221b,
+ 0xd2f2, 0x1079,
+ 0xd2f5, 0x221c,
+ 0xd2f6, 0x107d,
+ 0xd2f8, 0x221d,
+ 0xd2f9, 0x1080,
+ 0xd2fb, 0x221e,
+ 0xd2fc, 0x1083,
+ 0xd2fe, 0x221f,
+ 0xd3a1, 0x1086,
+ 0xd3a3, 0x2220,
+ 0xd3ad, 0x1092,
+ 0xd3ae, 0x222a,
+ 0xd3af, 0x1094,
+ 0xd3b1, 0x222b,
+ 0xd3b2, 0x1097,
+ 0xd3b4, 0x222c,
+ 0xd3b7, 0x109c,
+ 0xd3b8, 0x222f,
+ 0xd3b9, 0x109e,
+ 0xd3bb, 0x2230,
+ 0xd3bc, 0x10a1,
+ 0xd3c5, 0x2231,
+ 0xd3c6, 0x10ab,
+ 0xd3c7, 0x2232,
+ 0xd3c8, 0x10ad,
+ 0xd3ca, 0x2233,
+ 0xd3cd, 0x10b2,
+ 0xd3d5, 0x2236,
+ 0xd3d6, 0x10bb,
+ 0xd3df, 0x2237,
+ 0xd3e1, 0x10c6,
+ 0xd3e3, 0x2239,
+ 0xd3e4, 0x10c9,
+ 0xd3e6, 0x223a,
+ 0xd3e7, 0x10cc,
+ 0xd3eb, 0x223b,
+ 0xd3ed, 0x10d2,
+ 0xd3ef, 0x223d,
+ 0xd3f0, 0x10d5,
+ 0xd3f4, 0x223e,
+ 0xd3f5, 0x10da,
+ 0xd3fc, 0x223f,
+ 0xd3fd, 0x10e2,
+ 0xd3fe, 0x2240,
+ 0xd4a1, 0x10e4,
+ 0xd4a4, 0x2241,
+ 0xd4a5, 0x10e8,
+ 0xd4a6, 0x2242,
+ 0xd4a9, 0x10ec,
+ 0xd4af, 0x2245,
+ 0xd4b3, 0x10f6,
+ 0xd4b5, 0x2249,
+ 0xd4b7, 0x10fa,
+ 0xd4b8, 0x224b,
+ 0xd4b9, 0x10fc,
+ 0xd4bc, 0x224c,
+ 0xd4bd, 0x1100,
+ 0xd4be, 0x224d,
+ 0xd4c0, 0x1103,
+ 0xd4c4, 0x224f,
+ 0xd4c5, 0x1108,
+ 0xd4c6, 0x2250,
+ 0xd4c8, 0x110b,
+ 0xd4c9, 0x2252,
+ 0xd4ca, 0x110d,
+ 0xd4cb, 0x2253,
+ 0xd4cf, 0x1112,
+ 0xd4d3, 0x2257,
+ 0xd4d4, 0x1117,
+ 0xd4d8, 0x2258,
+ 0xd4d9, 0x111c,
+ 0xd4dc, 0x2259,
+ 0xd4e1, 0x1124,
+ 0xd4e4, 0x225e,
+ 0xd4e5, 0x1128,
+ 0xd4e6, 0x225f,
+ 0xd4e7, 0x112a,
+ 0xd4ee, 0x2260,
+ 0xd4ef, 0x1132,
+ 0xd4f0, 0x2261,
+ 0xd4f5, 0x1138,
+ 0xd4f9, 0x2266,
+ 0xd4fa, 0x113d,
+ 0xd4fe, 0x2267,
+ 0xd5a1, 0x2268,
+ 0xd5a3, 0x1144,
+ 0xd5a9, 0x226a,
+ 0xd5aa, 0x114b,
+ 0xd5ab, 0x226b,
+ 0xd5ac, 0x114d,
+ 0xd5ae, 0x226c,
+ 0xd5af, 0x1150,
+ 0xd5b1, 0x226d,
+ 0xd5b2, 0x1153,
+ 0xd5b5, 0x226e,
+ 0xd5b9, 0x115a,
+ 0xd5bb, 0x2272,
+ 0xd5bc, 0x115d,
+ 0xd5bd, 0x2273,
+ 0xd5be, 0x115f,
+ 0xd5c0, 0x2274,
+ 0xd5c1, 0x1162,
+ 0xd5c5, 0x2275,
+ 0xd5c6, 0x1167,
+ 0xd5c7, 0x2276,
+ 0xd5c8, 0x1169,
+ 0xd5ca, 0x2277,
+ 0xd5cc, 0x116d,
+ 0xd5cd, 0x2279,
+ 0xd5ce, 0x116f,
+ 0xd5d4, 0x227a,
+ 0xd5d5, 0x1176,
+ 0xd5dd, 0x227b,
+ 0xd5df, 0x1180,
+ 0xd5e0, 0x227d,
+ 0xd5e1, 0x1182,
+ 0xd5e2, 0x227e,
+ 0xd5e3, 0x1184,
+ 0xd5ea, 0x227f,
+ 0xd5ed, 0x118e,
+ 0xd5ef, 0x2282,
+ 0xd5f0, 0x1191,
+ 0xd5f2, 0x2283,
+ 0xd5f4, 0x1195,
+ 0xd5f7, 0x15eb,
+ 0xd5f8, 0x1199,
+ 0xd6a1, 0x2285,
+ 0xd6a5, 0x11a4,
+ 0xd6af, 0x2289,
+ 0xd6b1, 0x11b0,
+ 0xd6b4, 0x228b,
+ 0xd6b5, 0x11b4,
+ 0xd6bb, 0x228c,
+ 0xd6bc, 0x11bb,
+ 0xd6bd, 0x228d,
+ 0xd6be, 0x11bd,
+ 0xd6bf, 0x228e,
+ 0xd6c1, 0x11c0,
+ 0xd6c4, 0x2290,
+ 0xd6c5, 0x11c4,
+ 0xd6ca, 0x2291,
+ 0xd6cb, 0x11ca,
+ 0xd6cd, 0x2292,
+ 0xd6ce, 0x11cd,
+ 0xd6d3, 0x2293,
+ 0xd6d4, 0x11d3,
+ 0xd6d5, 0x2294,
+ 0xd6d8, 0x11d7,
+ 0xd6da, 0x2297,
+ 0xd6db, 0x11da,
+ 0xd6df, 0x2298,
+ 0xd6e0, 0x11df,
+ 0xd6e1, 0x2299,
+ 0xd6e2, 0x11e1,
+ 0xd6e5, 0x229a,
+ 0xd6e6, 0x11e5,
+ 0xd6e7, 0x229b,
+ 0xd6e9, 0x11e8,
+ 0xd6ee, 0x229d,
+ 0xd6f0, 0x11ef,
+ 0xd6f2, 0x229f,
+ 0xd6f3, 0x11f2,
+ 0xd6f5, 0x22a0,
+ 0xd6f7, 0x11f6,
+ 0xd6fc, 0x22a2,
+ 0xd7a1, 0x11fe,
+ 0xd7a4, 0x22a5,
+ 0xd7a5, 0x1202,
+ 0xd7a8, 0x22a6,
+ 0xd7ab, 0x1208,
+ 0xd7ac, 0x22a9,
+ 0xd7ad, 0x120a,
+ 0xd7ae, 0x22aa,
+ 0xd7b2, 0x120f,
+ 0xd7b3, 0x22ae,
+ 0xd7b5, 0x1212,
+ 0xd7b6, 0x22b0,
+ 0xd7b7, 0x1214,
+ 0xd7b8, 0x22b1,
+ 0xd7bd, 0x121a,
+ 0xd7c7, 0x22b6,
+ 0xd7c8, 0x1225,
+ 0xd7ca, 0x22b7,
+ 0xd7cb, 0x1228,
+ 0xd7d5, 0x22b8,
+ 0xd7d6, 0x1233,
+ 0xd7db, 0x22b9,
+ 0xd7df, 0x123c,
+ 0xd7e7, 0x22bd,
+ 0xd7e8, 0x1245,
+ 0xd7e9, 0x22be,
+ 0xd7eb, 0x1248,
+ 0xd8a1, 0x1257,
+ 0xd8c4, 0x22c0,
+ 0xd8c5, 0x127b,
+ 0xd8c7, 0x22c1,
+ 0xd8c8, 0x127e,
+ 0xd8c9, 0x22c2,
+ 0xd8ca, 0x1280,
+ 0xd8cc, 0x22c3,
+ 0xd8ce, 0x1284,
+ 0xd8d0, 0x22c5,
+ 0xd8d2, 0x1288,
+ 0xd8d3, 0x22c7,
+ 0xd8d4, 0x128a,
+ 0xd8d9, 0x22c8,
+ 0xd8da, 0x1290,
+ 0xd8db, 0x22c9,
+ 0xd8dd, 0x1293,
+ 0xd8f1, 0x22cb,
+ 0xd8f2, 0x12a8,
+ 0xd8f6, 0x22cc,
+ 0xd8f8, 0x12ae,
+ 0xd9a1, 0x12b5,
+ 0xd9ad, 0x22ce,
+ 0xd9ae, 0x12c2,
+ 0xd9af, 0x22cf,
+ 0xd9b0, 0x12c4,
+ 0xd9b1, 0x22d0,
+ 0xd9b4, 0x12c8,
+ 0xd9c7, 0x22d3,
+ 0xd9c8, 0x12dc,
+ 0xd9cd, 0x22d4,
+ 0xd9d1, 0x12e5,
+ 0xd9dd, 0x22d8,
+ 0xd9de, 0x12f2,
+ 0xd9e1, 0x22d9,
+ 0xd9e2, 0x12f6,
+ 0xd9e4, 0x22da,
+ 0xd9e5, 0x12f9,
+ 0xd9e6, 0x22db,
+ 0xd9e7, 0x12fb,
+ 0xd9ec, 0x22dc,
+ 0xd9ed, 0x1301,
+ 0xd9f4, 0x22dd,
+ 0xd9f6, 0x130a,
+ 0xdaa1, 0x1313,
+ 0xdaa5, 0x22df,
+ 0xdae0, 0x1352,
+ 0xdaea, 0x231a,
+ 0xdaeb, 0x135d,
+ 0xdaf7, 0x231b,
+ 0xdaf8, 0x136a,
+ 0xdaf9, 0x231c,
+ 0xdafa, 0x136c,
+ 0xdafe, 0x231d,
+ 0xdba1, 0x1371,
+ 0xdba3, 0x231e,
+ 0xdba4, 0x1374,
+ 0xdba6, 0x231f,
+ 0xdba7, 0x1377,
+ 0xdba9, 0x2320,
+ 0xdbab, 0x137b,
+ 0xdbbb, 0x2322,
+ 0xdbbc, 0x138c,
+ 0xdbbd, 0x2323,
+ 0xdbbe, 0x138e,
+ 0xdbcf, 0x2324,
+ 0xdbd0, 0x13a0,
+ 0xdbd1, 0x2325,
+ 0xdbd2, 0x13a2,
+ 0xdbdb, 0x2326,
+ 0xdbdc, 0x13ac,
+ 0xdbde, 0x2327,
+ 0xdbdf, 0x13af,
+ 0xdbe2, 0x2328,
+ 0xdbe3, 0x13b3,
+ 0xdbe4, 0x2329,
+ 0xdbe5, 0x13b5,
+ 0xdbeb, 0x232a,
+ 0xdbec, 0x13bc,
+ 0xdbee, 0x232b,
+ 0xdbef, 0x13bf,
+ 0xdbf1, 0x232c,
+ 0xdbf2, 0x13c2,
+ 0xdbf5, 0x232d,
+ 0xdbf8, 0x13c8,
+ 0xdca1, 0x13cf,
+ 0xdcbc, 0x2330,
+ 0xdcbd, 0x13eb,
+ 0xdcbf, 0x2331,
+ 0xdcc0, 0x13ee,
+ 0xdcc2, 0x2332,
+ 0xdcc3, 0x13f1,
+ 0xdcc8, 0x2333,
+ 0xdccb, 0x13f9,
+ 0xdcd1, 0x2336,
+ 0xdcd2, 0x1400,
+ 0xdcd7, 0x2337,
+ 0xdcd8, 0x1406,
+ 0xdce0, 0x2338,
+ 0xdce1, 0x140f,
+ 0xdce3, 0x2339,
+ 0xdce5, 0x1413,
+ 0xdce9, 0x233b,
+ 0xdceb, 0x1419,
+ 0xdcf1, 0x233d,
+ 0xdcf2, 0x1420,
+ 0xdcf6, 0x233e,
+ 0xdcf7, 0x1425,
+ 0xdcf9, 0x233f,
+ 0xdcfa, 0x1428,
+ 0xdcfd, 0x2340,
+ 0xdda1, 0x2342,
+ 0xdda2, 0x142e,
+ 0xdda3, 0x2343,
+ 0xdda8, 0x1434,
+ 0xddaa, 0x2348,
+ 0xddac, 0x1438,
+ 0xddb2, 0x234a,
+ 0xddb3, 0x143f,
+ 0xddb5, 0x234b,
+ 0xddb6, 0x1442,
+ 0xddba, 0x234c,
+ 0xddbc, 0x1448,
+ 0xddd3, 0x234e,
+ 0xddd4, 0x1460,
+ 0xdddb, 0x234f,
+ 0xdddc, 0x1468,
+ 0xddde, 0x2350,
+ 0xdddf, 0x146b,
+ 0xdde4, 0x2351,
+ 0xdde5, 0x1471,
+ 0xddeb, 0x2352,
+ 0xddec, 0x1478,
+ 0xddf1, 0x2353,
+ 0xddf2, 0x147e,
+ 0xddf6, 0x2354,
+ 0xddf8, 0x1484,
+ 0xddfc, 0x2356,
+ 0xddfd, 0x1489,
+ 0xddfe, 0x2357,
+ 0xdea1, 0x148b,
+ 0xdead, 0x2358,
+ 0xdeae, 0x1498,
+ 0xdeb4, 0x2359,
+ 0xdeb5, 0x149f,
+ 0xdeba, 0x235a,
+ 0xdebb, 0x14a5,
+ 0xdec6, 0x235b,
+ 0xdec7, 0x14b1,
+ 0xdecf, 0x235c,
+ 0xded0, 0x14ba,
+ 0xded1, 0x235d,
+ 0xded3, 0x14bd,
+ 0xded8, 0x235f,
+ 0xded9, 0x14c3,
+ 0xdee2, 0x2360,
+ 0xdee3, 0x14cd,
+ 0xdee8, 0x2361,
+ 0xdee9, 0x14d3,
+ 0xdeec, 0x2362,
+ 0xdeed, 0x14d7,
+ 0xdef3, 0x2363,
+ 0xdef4, 0x14de,
+ 0xdefc, 0x2364,
+ 0xdefd, 0x14e7,
+ 0xdfa1, 0x14e9,
+ 0xdfa2, 0x2365,
+ 0xdfa4, 0x14ec,
+ 0xdfa5, 0x2367,
+ 0xdfa6, 0x14ee,
+ 0xdfb4, 0x2368,
+ 0xdfb5, 0x14fd,
+ 0xdfbc, 0x2369,
+ 0xdfbe, 0x1506,
+ 0xdfbf, 0x236b,
+ 0xdfc0, 0x1508,
+ 0xdfc2, 0x236c,
+ 0xdfc4, 0x150c,
+ 0xdfcc, 0x236e,
+ 0xdfcd, 0x1515,
+ 0xdfd0, 0x236f,
+ 0xdfd1, 0x1519,
+ 0xdfd5, 0x2370,
+ 0xdfd6, 0x151e,
+ 0xdfd8, 0x2371,
+ 0xdfda, 0x1522,
+ 0xdfdc, 0x2373,
+ 0xdfdd, 0x1525,
+ 0xdfe0, 0x2374,
+ 0xdfe1, 0x1529,
+ 0xdfe2, 0x2375,
+ 0xdfe3, 0x152b,
+ 0xdfe6, 0x2376,
+ 0xdfe7, 0x152f,
+ 0xdfe9, 0x2377,
+ 0xdfea, 0x1532,
+ 0xdfeb, 0x2378,
+ 0xdfec, 0x1534,
+ 0xdfef, 0x2379,
+ 0xdff0, 0x1538,
+ 0xdff5, 0x237a,
+ 0xdff6, 0x153e,
+ 0xdff9, 0x237b,
+ 0xdffa, 0x1542,
+ 0xe0a1, 0x1547,
+ 0xe0b6, 0x237c,
+ 0xe0b8, 0x155e,
+ 0xe0bf, 0x237e,
+ 0xe0c0, 0x1566,
+ 0xe0c8, 0x237f,
+ 0xe0c9, 0x156f,
+ 0xe0ce, 0x2380,
+ 0xe0cf, 0x1575,
+ 0xe0d3, 0x2381,
+ 0xe0d4, 0x157a,
+ 0xe0e0, 0x2382,
+ 0xe0e1, 0x1587,
+ 0xe0f0, 0x2383,
+ 0xe0f1, 0x1597,
+ 0xe0f8, 0x2384,
+ 0xe0f9, 0x159f,
+ 0xe0fc, 0x2385,
+ 0xe1a1, 0x15a5,
+ 0xe1ab, 0x2388,
+ 0xe1ac, 0x15b0,
+ 0xe1ad, 0x2389,
+ 0xe1ae, 0x15b2,
+ 0xe1b0, 0x238a,
+ 0xe1b1, 0x15b5,
+ 0xe1b4, 0x238b,
+ 0xe1b5, 0x15b9,
+ 0xe1bb, 0x238c,
+ 0xe1bc, 0x15c0,
+ 0xe1bd, 0x238d,
+ 0xe1be, 0x15c2,
+ 0xe1c0, 0x238e,
+ 0xe1c2, 0x15c6,
+ 0xe1c9, 0x2390,
+ 0xe1ca, 0x15ce,
+ 0xe1d0, 0x2391,
+ 0xe1d1, 0x15d5,
+ 0xe1db, 0x2392,
+ 0xe1dc, 0x15e0,
+ 0xe1e1, 0x07aa,
+ 0xe1e2, 0x2393,
+ 0xe1e3, 0x15e7,
+ 0xe1e7, 0x1198,
+ 0xe1e8, 0x15ec,
+ 0xe1ee, 0x2394,
+ 0xe1f0, 0x15f4,
+ 0xe1f6, 0x2396,
+ 0xe1f7, 0x15fb,
+ 0xe1f8, 0x2397,
+ 0xe1f9, 0x15fd,
+ 0xe1fd, 0x2398,
+ 0xe1fe, 0x1602,
+ 0xe2a1, 0x1603,
+ 0xe2a4, 0x2399,
+ 0xe2a5, 0x1607,
+ 0xe2a8, 0x239a,
+ 0xe2a9, 0x160b,
+ 0xe2bb, 0x239b,
+ 0xe2c5, 0x10c5,
+ 0xe2c6, 0x23a5,
+ 0xe2cf, 0x1631,
+ 0xe2d0, 0x23ae,
+ 0xe2d1, 0x1633,
+ 0xe2d9, 0x23af,
+ 0xe2da, 0x163c,
+ 0xe2e3, 0x23b0,
+ 0xe2e5, 0x1647,
+ 0xe2e6, 0x23b2,
+ 0xe2e7, 0x1649,
+ 0xe2e9, 0x23b3,
+ 0xe2ec, 0x164e,
+ 0xe2f8, 0x23b6,
+ 0xe2f9, 0x165b,
+ 0xe2fa, 0x23b7,
+ 0xe2fe, 0x1660,
+ 0xe3a1, 0x1661,
+ 0xe3a2, 0x23bb,
+ 0xe3a3, 0x1663,
+ 0xe3a5, 0x23bc,
+ 0xe3a6, 0x1666,
+ 0xe3ab, 0x23bd,
+ 0xe3ac, 0x166c,
+ 0xe3b4, 0x23be,
+ 0xe3b5, 0x1675,
+ 0xe3c5, 0x23bf,
+ 0xe3dc, 0x169c,
+ 0xe3e3, 0x23d6,
+ 0xe3e4, 0x16a4,
+ 0xe3ed, 0x23d7,
+ 0xe3ee, 0x16ae,
+ 0xe3f1, 0x23d8,
+ 0xe3f3, 0x16b3,
+ 0xe3f8, 0x23da,
+ 0xe3f9, 0x16b9,
+ 0xe3fe, 0x23db,
+ 0xe4a1, 0x16bf,
+ 0xe4a4, 0x23dc,
+ 0xe4a6, 0x16c4,
+ 0xe4ab, 0x23de,
+ 0xe4ac, 0x16ca,
+ 0xe4af, 0x23df,
+ 0xe4b2, 0x16d0,
+ 0xe4b5, 0x23e2,
+ 0xe4b7, 0x16d5,
+ 0xe4c2, 0x23e4,
+ 0xe4c3, 0x16e1,
+ 0xe4c5, 0x23e5,
+ 0xe4c6, 0x16e4,
+ 0xe4c9, 0x23e6,
+ 0xe4ca, 0x16e8,
+ 0xe4d9, 0x23e7,
+ 0xe4da, 0x16f8,
+ 0xe4dc, 0x23e8,
+ 0xe4dd, 0x16fb,
+ 0xe4de, 0x23e9,
+ 0xe4df, 0x16fd,
+ 0xe4e4, 0x23ea,
+ 0xe4e5, 0x1703,
+ 0xe4eb, 0x23eb,
+ 0xe4ed, 0x170b,
+ 0xe4f2, 0x23ed,
+ 0xe4f3, 0x1711,
+ 0xe4fe, 0x23ee,
+ 0xe5a1, 0x171d,
+ 0xe5b0, 0x23ef,
+ 0xe5b1, 0x172d,
+ 0xe5b9, 0x23f0,
+ 0xe5ba, 0x1736,
+ 0xe5c7, 0x23f1,
+ 0xe5c8, 0x1744,
+ 0xe5c9, 0x23f2,
+ 0xe5ca, 0x1746,
+ 0xe5ce, 0x23f3,
+ 0xe5cf, 0x174b,
+ 0xe5f0, 0x23f4,
+ 0xe5f1, 0x176d,
+ 0xe5f2, 0x23f5,
+ 0xe5f3, 0x176f,
+ 0xe5fc, 0x23f6,
+ 0xe5fe, 0x177a,
+ 0xe6a1, 0x177b,
+ 0xe6a3, 0x23f8,
+ 0xe6a4, 0x177e,
+ 0xe6ab, 0x23f9,
+ 0xe6ad, 0x1787,
+ 0xe6ae, 0x23fb,
+ 0xe6af, 0x1789,
+ 0xe6b4, 0x23fc,
+ 0xe6b6, 0x1790,
+ 0xe6bf, 0x23fe,
+ 0xe6c0, 0x179a,
+ 0xe6c8, 0x23ff,
+ 0xe6ca, 0x17a4,
+ 0xe6cd, 0x2401,
+ 0xe6ce, 0x17a8,
+ 0xe6e0, 0x2402,
+ 0xe7a1, 0x2421,
+ 0xe7db, 0x1813,
+ 0xe7e1, 0x245b,
+ 0xe7e3, 0x181b,
+ 0xe7e7, 0x245d,
+ 0xe7e8, 0x1820,
+ 0xe7ef, 0x245e,
+ 0xe7f0, 0x1828,
+ 0xe7f4, 0x245f,
+ 0xe7f7, 0x182f,
+ 0xe8a1, 0x1837,
+ 0xe8a8, 0x2462,
+ 0xe8a9, 0x183f,
+ 0xe8ac, 0x2463,
+ 0xe8ad, 0x1843,
+ 0xe8b6, 0x2464,
+ 0xe8b7, 0x184d,
+ 0xe8b8, 0x2465,
+ 0xe8bb, 0x1851,
+ 0xe8bf, 0x2468,
+ 0xe8c1, 0x1857,
+ 0xe8c5, 0x246a,
+ 0xe8c6, 0x185c,
+ 0xe8c7, 0x246b,
+ 0xe8ca, 0x1860,
+ 0xe8ce, 0x246e,
+ 0xe8cf, 0x1865,
+ 0xe8d0, 0x246f,
+ 0xe8d1, 0x1867,
+ 0xe8d3, 0x2470,
+ 0xe8d4, 0x186a,
+ 0xe8dd, 0x2471,
+ 0xe8de, 0x1874,
+ 0xe8df, 0x2472,
+ 0xe8e0, 0x1876,
+ 0xe8e2, 0x2473,
+ 0xe8e4, 0x187a,
+ 0xe8e5, 0x2475,
+ 0xe8e6, 0x187c,
+ 0xe8e7, 0x2476,
+ 0xe8e8, 0x187e,
+ 0xe8eb, 0x2477,
+ 0xe8ec, 0x1882,
+ 0xe8ed, 0x2478,
+ 0xe8ee, 0x1884,
+ 0xe8ef, 0x2479,
+ 0xe8f0, 0x1886,
+ 0xe8f9, 0x247a,
+ 0xe8fa, 0x1890,
+ 0xe8fc, 0x247b,
+ 0xe8fe, 0x1894,
+ 0xe9a1, 0x247d,
+ 0xe9a2, 0x1896,
+ 0xe9ad, 0x247e,
+ 0xe9ae, 0x18a2,
+ 0xe9b4, 0x247f,
+ 0xe9b6, 0x18aa,
+ 0xe9b7, 0x2481,
+ 0xe9b8, 0x18ac,
+ 0xe9c4, 0x2482,
+ 0xe9c5, 0x18b9,
+ 0xe9c6, 0x2483,
+ 0xe9c7, 0x18bb,
+ 0xe9c9, 0x2484,
+ 0xe9ca, 0x18be,
+ 0xe9d6, 0x2485,
+ 0xe9d7, 0x18cb,
+ 0xe9da, 0x2486,
+ 0xe9db, 0x18cf,
+ 0xe9e4, 0x2487,
+ 0xe9e5, 0x18d9,
+ 0xe9e6, 0x2488,
+ 0xe9e8, 0x18dc,
+ 0xe9e9, 0x248a,
+ 0xe9ea, 0x18de,
+ 0xe9eb, 0x248b,
+ 0xe9ec, 0x18e0,
+ 0xe9ed, 0x248c,
+ 0xeaa1, 0x249e,
+ 0xeaa6, 0x18f8,
+ 0xeaa7, 0x24a3,
+ 0xeaa9, 0x18fb,
+ 0xeab1, 0x24a5,
+ 0xeab2, 0x1904,
+ 0xeabc, 0x24a6,
+ 0xeabd, 0x190f,
+ 0xeaca, 0x24a7,
+ 0xeacb, 0x191d,
+ 0xeacd, 0x24a8,
+ 0xeace, 0x1920,
+ 0xead3, 0x24a9,
+ 0xead4, 0x1926,
+ 0xeada, 0x24aa,
+ 0xeaf0, 0x1942,
+ 0xeba1, 0x1951,
+ 0xeba7, 0x24c0,
+ 0xeba8, 0x1958,
+ 0xebaa, 0x24c1,
+ 0xebab, 0x195b,
+ 0xebb2, 0x24c2,
+ 0xebb3, 0x1963,
+ 0xebb9, 0x24c3,
+ 0xebba, 0x196a,
+ 0xebca, 0x24c4,
+ 0xebcc, 0x197c,
+ 0xebcd, 0x24c6,
+ 0xebce, 0x197e,
+ 0xebd6, 0x24c7,
+ 0xebd7, 0x1987,
+ 0xebda, 0x24c8,
+ 0xebdb, 0x198b,
+ 0xebe1, 0x24c9,
+ 0xebe2, 0x1992,
+ 0xebf7, 0x24ca,
+ 0xebf8, 0x19a8,
+ 0xeca1, 0x19af,
+ 0xeca3, 0x24cb,
+ 0xeca4, 0x19b2,
+ 0xeca9, 0x24cc,
+ 0xecaf, 0x19bd,
+ 0xecb1, 0x24d2,
+ 0xecb2, 0x19c0,
+ 0xecb4, 0x24d3,
+ 0xecb6, 0x19c4,
+ 0xecbe, 0x24d5,
+ 0xecc0, 0x19ce,
+ 0xecc1, 0x24d7,
+ 0xecc2, 0x19d0,
+ 0xecc7, 0x24d8,
+ 0xecc8, 0x19d6,
+ 0xeccb, 0x24d9,
+ 0xeccc, 0x19da,
+ 0xece2, 0x24da,
+ 0xece3, 0x19f1,
+ 0xecf2, 0x24db,
+ 0xecf3, 0x1a01,
+ 0xecf5, 0x24dc,
+ 0xecf6, 0x1a04,
+ 0xecf8, 0x24dd,
+ 0xecf9, 0x1a07,
+ 0xeda1, 0x24de,
+ 0xeda2, 0x1a0e,
+ 0xeda8, 0x24df,
+ 0xeda9, 0x1a15,
+ 0xedaf, 0x24e0,
+ 0xedb1, 0x1a1d,
+ 0xedb4, 0x24e2,
+ 0xedb5, 0x1a21,
+ 0xedb6, 0x24e3,
+ 0xedb7, 0x1a23,
+ 0xedb8, 0x24e4,
+ 0xedb9, 0x1a25,
+ 0xedba, 0x24e5,
+ 0xedbb, 0x1a27,
+ 0xedbf, 0x24e6,
+ 0xedc0, 0x1a2c,
+ 0xedc2, 0x24e7,
+ 0xedc4, 0x1a30,
+ 0xedcc, 0x24e9,
+ 0xedce, 0x1a3a,
+ 0xedd3, 0x24eb,
+ 0xedd4, 0x1a40,
+ 0xedd7, 0x24ec,
+ 0xedd8, 0x1a44,
+ 0xede8, 0x24ed,
+ 0xede9, 0x1a55,
+ 0xedee, 0x24ee,
+ 0xedef, 0x1a5b,
+ 0xedf9, 0x24ef,
+ 0xedfb, 0x1a67,
+ 0xeea1, 0x1a6b,
+ 0xeebc, 0x24f1,
+ 0xeebd, 0x1a87,
+ 0xeebf, 0x24f2,
+ 0xeec0, 0x1a8a,
+ 0xeec4, 0x24f3,
+ 0xefa1, 0x252e,
+ 0xeff2, 0x1b1a,
+ 0xf0a1, 0x1b27,
+ 0xf0a3, 0x257f,
+ 0xf0a4, 0x1b2a,
+ 0xf0af, 0x2580,
+ 0xf0da, 0x1b60,
+ 0xf0dc, 0x25ab,
+ 0xf0de, 0x1b64,
+ 0xf0df, 0x25ad,
+ 0xf0e0, 0x1b66,
+ 0xf0e9, 0x25ae,
+ 0xf0ea, 0x1b70,
+ 0xf0ec, 0x25af,
+ 0xf0ed, 0x1b73,
+ 0xf0ef, 0x25b0,
+ 0xf0f0, 0x1b76,
+ 0xf0f7, 0x25b1,
+ 0xf0f8, 0x1b7e,
+ 0xf0f9, 0x25b2,
+ 0xf0fa, 0x1b80,
+ 0xf0fc, 0x25b3,
+ 0xf0fd, 0x1b83,
+ 0xf1a1, 0x1b85,
+ 0xf1a8, 0x25b4,
+ 0xf1a9, 0x1b8d,
+ 0xf1ab, 0x25b5,
+ 0xf1ac, 0x1b90,
+ 0xf1ae, 0x25b6,
+ 0xf1af, 0x1b93,
+ 0xf1b2, 0x25b7,
+ 0xf1b3, 0x1b97,
+ 0xf1bc, 0x25b8,
+ 0xf1bd, 0x1ba1,
+ 0xf1c0, 0x25b9,
+ 0xf1c1, 0x1ba5,
+ 0xf1c9, 0x25ba,
+ 0xf1ca, 0x1bae,
+ 0xf1cd, 0x25bb,
+ 0xf1ce, 0x1bb2,
+ 0xf1cf, 0x25bc,
+ 0xf1d1, 0x1bb5,
+ 0xf1da, 0x25be,
+ 0xf1db, 0x1bbf,
+ 0xf1dc, 0x25bf,
+ 0xf1dd, 0x1bc1,
+ 0xf1e4, 0x25c0,
+ 0xf1e5, 0x1bc9,
+ 0xf1ec, 0x25c1,
+ 0xf1ed, 0x1bd1,
+ 0xf1ef, 0x25c2,
+ 0xf1f0, 0x1bd4,
+ 0xf1f7, 0x25c3,
+ 0xf1f8, 0x1bdc,
+ 0xf1f9, 0x25c4,
+ 0xf1fa, 0x1bde,
+ 0xf1fc, 0x25c5,
+ 0xf2a1, 0x25c8,
+ 0xf2ae, 0x1bf0,
+ 0xf2b1, 0x25d5,
+ 0xf2b3, 0x1bf5,
+ 0xf2b9, 0x25d7,
+ 0xf2ba, 0x1bfc,
+ 0xf2c3, 0x25d8,
+ 0xf2c4, 0x1c06,
+ 0xf2c9, 0x25d9,
+ 0xf2ca, 0x1c0c,
+ 0xf2cc, 0x25da,
+ 0xf2ce, 0x1c10,
+ 0xf2cf, 0x25dc,
+ 0xf2d0, 0x1c12,
+ 0xf2d3, 0x25dd,
+ 0xf2d4, 0x1c16,
+ 0xf2e5, 0x25de,
+ 0xf2e6, 0x1c28,
+ 0xf2ee, 0x25df,
+ 0xf2ef, 0x1c31,
+ 0xf2f7, 0x25e0,
+ 0xf2f8, 0x1c3a,
+ 0xf2fd, 0x25e1,
+ 0xf2fe, 0x1c40,
+ 0xf3a1, 0x1c41,
+ 0xf3bf, 0x25e2,
+ 0xf3c0, 0x1c60,
+ 0xf3c6, 0x25e3,
+ 0xf3c7, 0x1c67,
+ 0xf3c8, 0x25e4,
+ 0xf3c9, 0x1c69,
+ 0xf3d6, 0x25e5,
+ 0xf3d7, 0x1c77,
+ 0xf3d9, 0x25e6,
+ 0xf3da, 0x1c7a,
+ 0xf3e5, 0x25e7,
+ 0xf3e7, 0x1c87,
+ 0xf3ea, 0x25e9,
+ 0xf3eb, 0x1c8b,
+ 0xf3ec, 0x25ea,
+ 0xf3ed, 0x1c8d,
+ 0xf3ef, 0x25eb,
+ 0xf3f0, 0x1c90,
+ 0xf3f1, 0x25ec,
+ 0xf3f2, 0x1c92,
+ 0xf3fd, 0x25ed,
+ 0xf3fe, 0x1c9e,
+ 0xf4a1, 0x1c9f,
+ 0xf4a5, 0x25ee,
+ 0xf4a6, 0x1ca4,
+ 0xf4af, 0x25ef,
+ 0xf4b0, 0x1cae,
+ 0xf4b5, 0x25f0,
+ 0xf4b6, 0x1cb4,
+ 0xf4c1, 0x25f1,
+ 0xf4c2, 0x1cc0,
+ 0xf4c7, 0x25f2,
+ 0xf4c8, 0x1cc6,
+ 0xf4cf, 0x25f3,
+ 0xf4d1, 0x1ccf,
+ 0xf4d6, 0x25f5,
+ 0xf4d7, 0x1cd5,
+ 0xf4ea, 0x25f6,
+ 0xf4eb, 0x1ce9,
+ 0xf4ef, 0x25f7,
+ 0xf4f0, 0x1cee,
+ 0xf4f5, 0x25f8,
+ 0xf4f6, 0x1cf4,
+ 0xf5a1, 0x1cfd,
+ 0xf5a6, 0x25f9,
+ 0xf5a8, 0x1d04,
+ 0xf5ba, 0x25fb,
+ 0xf5bc, 0x1d18,
+ 0xf5c4, 0x25fd,
+ 0xf5c5, 0x1d21,
+ 0xf5c8, 0x25fe,
+ 0xf5c9, 0x1d25,
+ 0xf5ce, 0x25ff,
+ 0xf5d0, 0x1d2c,
+ 0xf5d1, 0x2601,
+ 0xf5d3, 0x1d2f,
+ 0xf5d9, 0x2603,
+ 0xf5da, 0x1d36,
+ 0xf5dc, 0x2604,
+ 0xf5dd, 0x1d39,
+ 0xf5e6, 0x2605,
+ 0xf5e8, 0x1d44,
+ 0xf5ef, 0x2607,
+ 0xf5f0, 0x1d4c,
+ 0xf5f2, 0x2608,
+ 0xf5f3, 0x1d4f,
+ 0xf5fc, 0x2609,
+ 0xf5fd, 0x1d59,
+ 0xf6a1, 0x1d5b,
+ 0xf6a3, 0x260a,
+ 0xf6a4, 0x1d5e,
+ 0xf6a6, 0x260b,
+ 0xf6a7, 0x1d61,
+ 0xf6a8, 0x260c,
+ 0xf6a9, 0x1d63,
+ 0xf6ab, 0x260d,
+ 0xf6ac, 0x1d66,
+ 0xf6b0, 0x260e,
+ 0xf6b1, 0x1d6b,
+ 0xf6b3, 0x260f,
+ 0xf6bf, 0x1d79,
+ 0xf6c5, 0x261b,
+ 0xf6c6, 0x1d80,
+ 0xf6c7, 0x261c,
+ 0xf6c8, 0x1d82,
+ 0xf6c9, 0x261d,
+ 0xf6ca, 0x1d84,
+ 0xf6cf, 0x261e,
+ 0xf7a1, 0x264e,
+ 0xf7b0, 0x1dc8,
+ 0xf7b2, 0x265d,
+ 0xf7b4, 0x1dcc,
+ 0xf7b5, 0x265f,
+ 0xf7b6, 0x1dce,
+ 0xf7bd, 0x2660,
+ 0xf7be, 0x1dd6,
+ 0xf7c3, 0x2661,
+ 0xf7c4, 0x1ddc,
+ 0xf7c5, 0x2662,
+ 0xf7c7, 0x1ddf,
+ 0xf7ca, 0x2664,
+ 0xf7cc, 0x1de4,
+ 0xf7cf, 0x2666,
+ 0xf7d1, 0x1de9,
+ 0xf7de, 0x2668,
+ 0xf7df, 0x1df7,
+ 0xf7e1, 0x0ab9,
+ 0xf7e2, 0x1dfa,
+ 0xf7f2, 0x2669,
+ 0xf7f3, 0x1e0b,
+ 0xf7f5, 0x266a,
+ 0xf7f6, 0x1e0e,
+ 0xf8a1, 0x266b,
+ 0xf8a7, 0x04cc,
+ 0xf8a8, 0x050a,
+ 0xf8a9, 0x0518,
+ 0xf8aa, 0x2671,
+ 0xf8ac, 0x0594,
+ 0xf8ad, 0x05ce,
+ 0xf8ae, 0x2673,
+ 0xf8af, 0x05f6,
+ 0xf8b0, 0x2674,
+ 0xf8b2, 0x0653,
+ 0xf8b3, 0x067e,
+ 0xf8b4, 0x2676,
+ 0xf8b5, 0x06c4,
+ 0xf8b6, 0x2677,
+ 0xf8b8, 0x073c,
+ 0xf8b9, 0x2679,
+ 0xf8bb, 0x07c3,
+ 0xf8bc, 0x267b,
+ 0xf8c0, 0x082b,
+ 0xf8c1, 0x267f,
+ 0xf8c2, 0x084e,
+ 0xf8c3, 0x0869,
+ 0xf8c4, 0x2680,
+ 0xf8c6, 0x090c,
+ 0xf8c7, 0x2682,
+ 0xf8c9, 0x0971,
+ 0xf8ca, 0x2684,
+ 0xf8cb, 0x099a,
+ 0xf8cd, 0x2685,
+ 0xf8ce, 0x09da,
+ 0xf8cf, 0x2686,
+ 0xf8d0, 0x09fa,
+ 0xf8d1, 0x2687,
+ 0xf8dc, 0x0bda,
+ 0xf8dd, 0x0bdd,
+ 0xf8de, 0x0bea,
+ 0xf8df, 0x0bec,
+ 0xf8e0, 0x0bf2,
+ 0xf8e1, 0x2692,
+ 0xf8e6, 0x0c92,
+ 0xf8e7, 0x0d1a,
+ 0xf8e8, 0x0d8c,
+ 0xf8e9, 0x0dbe,
+ 0xf8ea, 0x2697,
+ 0xf8eb, 0x0dfb,
+ 0xf8ec, 0x2698,
+ 0xf8ef, 0x0e70,
+ 0xf8f0, 0x269b,
+ 0xf8f1, 0x0ea3,
+ 0xf8f2, 0x269c,
+ 0xf8f8, 0x103d,
+ 0xf8f9, 0x10d9,
+ 0xf8fa, 0x26a2,
+ 0xf8fc, 0x10fb,
+ 0xf8fd, 0x1109,
+ 0xf8fe, 0x26a4,
+ 0xf9a1, 0x11a1,
+ 0xf9a2, 0x26a5,
+ 0xf9a3, 0x11ba,
+ 0xf9a4, 0x26a6,
+ 0xf9a6, 0x11d5,
+ 0xf9a7, 0x26a8,
+ 0xf9a8, 0x11fd,
+ 0xf9a9, 0x1219,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBTpcEUCHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x1e20, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e21, 0x1e22, 0x1e23 },
+ gb12GBTpcEUCHMap2, 2283
+};
+
+static Gushort gb12GBTpcEUCVMap2[4606] = {
+ 0x0000, 0x0000,
+ 0xa1a1, 0x0060,
+ 0xa2b1, 0x00be,
+ 0xa2e5, 0x00f0,
+ 0xa2f1, 0x00fa,
+ 0xa3a1, 0x0106,
+ 0xa4a1, 0x0164,
+ 0xa5a1, 0x01b7,
+ 0xa6a1, 0x020d,
+ 0xa6c1, 0x0225,
+ 0xa7a1, 0x025a,
+ 0xa7d1, 0x027b,
+ 0xa8a1, 0x029c,
+ 0xa8c5, 0x02bc,
+ 0xa9a4, 0x02e2,
+ 0xaaa1, 0x032e,
+ 0xaba1, 0x038c,
+ 0xb0a1, 0x03ac,
+ 0xb0a8, 0x1e25,
+ 0xb0a9, 0x03b4,
+ 0xb0aa, 0x1e26,
+ 0xb0ab, 0x03b6,
+ 0xb0ad, 0x1e27,
+ 0xb0af, 0x03ba,
+ 0xb0b9, 0x1e29,
+ 0xb0ba, 0x03c5,
+ 0xb0c0, 0x1e2a,
+ 0xb0c1, 0x03cc,
+ 0xb0d3, 0x1e2b,
+ 0xb0d4, 0x03df,
+ 0xb0d5, 0x1e2c,
+ 0xb0d6, 0x03e1,
+ 0xb0da, 0x1e2d,
+ 0xb0db, 0x03e6,
+ 0xb0dc, 0x1e2e,
+ 0xb0dd, 0x03e8,
+ 0xb0e4, 0x1e2f,
+ 0xb0e5, 0x03f0,
+ 0xb0ec, 0x1e30,
+ 0xb0ee, 0x03f9,
+ 0xb0ef, 0x1e32,
+ 0xb0f0, 0x03fb,
+ 0xb0f3, 0x1e33,
+ 0xb0f4, 0x03ff,
+ 0xb0f7, 0x1e34,
+ 0xb0f8, 0x0403,
+ 0xb0f9, 0x1e35,
+ 0xb0fa, 0x0405,
+ 0xb1a1, 0x040a,
+ 0xb1a5, 0x1e36,
+ 0xb1a7, 0x0410,
+ 0xb1a8, 0x1e38,
+ 0xb1a9, 0x0412,
+ 0xb1ab, 0x1e39,
+ 0xb1ac, 0x0415,
+ 0xb1b2, 0x1e3a,
+ 0xb1b3, 0x041c,
+ 0xb1b4, 0x1e3b,
+ 0xb1b6, 0x041f,
+ 0xb1b7, 0x1e3d,
+ 0xb1ba, 0x0423,
+ 0xb1c1, 0x1e40,
+ 0xb1c2, 0x042b,
+ 0xb1ca, 0x1e41,
+ 0xb1cb, 0x0434,
+ 0xb1cf, 0x1e42,
+ 0xb1d1, 0x043a,
+ 0xb1d2, 0x1e44,
+ 0xb1d3, 0x043c,
+ 0xb1d5, 0x1e45,
+ 0xb1d6, 0x043f,
+ 0xb1df, 0x1e46,
+ 0xb1e2, 0x044b,
+ 0xb1e4, 0x1e49,
+ 0xb1e5, 0x044e,
+ 0xb1e7, 0x1e4a,
+ 0xb1e9, 0x0452,
+ 0xb1ea, 0x1e4c,
+ 0xb1eb, 0x0454,
+ 0xb1ee, 0x1e4d,
+ 0xb1ef, 0x0458,
+ 0xb1f1, 0x1e4e,
+ 0xb1f2, 0x045b,
+ 0xb1f4, 0x1e4f,
+ 0xb1f8, 0x0461,
+ 0xb1fd, 0x1e53,
+ 0xb1fe, 0x0467,
+ 0xb2a1, 0x0468,
+ 0xb2a6, 0x1e54,
+ 0xb2a8, 0x046f,
+ 0xb2ac, 0x1e56,
+ 0xb2ad, 0x0474,
+ 0xb2b5, 0x1e57,
+ 0xb2b6, 0x047d,
+ 0xb2b9, 0x1e58,
+ 0xb2ba, 0x0481,
+ 0xb2c6, 0x1e59,
+ 0xb2c7, 0x048e,
+ 0xb2ce, 0x1e5a,
+ 0xb2d8, 0x049f,
+ 0xb2de, 0x1e64,
+ 0xb2df, 0x04a6,
+ 0xb2e0, 0x1e65,
+ 0xb2e1, 0x04a8,
+ 0xb2e2, 0x1e66,
+ 0xb2e4, 0x04ab,
+ 0xb2ef, 0x1e68,
+ 0xb2f0, 0x04b7,
+ 0xb2f3, 0x1e69,
+ 0xb2fd, 0x04c4,
+ 0xb3a1, 0x1e73,
+ 0xb3a3, 0x04c8,
+ 0xb3a4, 0x1e75,
+ 0xb3a8, 0x04cd,
+ 0xb3a9, 0x1e79,
+ 0xb3aa, 0x04cf,
+ 0xb3ae, 0x1e7a,
+ 0xb3af, 0x04d4,
+ 0xb3b5, 0x1e7b,
+ 0xb3b6, 0x04db,
+ 0xb3b9, 0x1e7c,
+ 0xb3ba, 0x04df,
+ 0xb3be, 0x1e7d,
+ 0xb3bf, 0x04e4,
+ 0xb3c2, 0x1e7e,
+ 0xb3c3, 0x04e8,
+ 0xb3c4, 0x1e7f,
+ 0xb3c5, 0x04ea,
+ 0xb3c6, 0x1e80,
+ 0xb3c7, 0x04ec,
+ 0xb3cd, 0x1e81,
+ 0xb3ce, 0x04f3,
+ 0xb3cf, 0x1e82,
+ 0xb3d0, 0x04f5,
+ 0xb3d2, 0x1e83,
+ 0xb3d3, 0x04f8,
+ 0xb3d9, 0x1e84,
+ 0xb3da, 0x04ff,
+ 0xb3db, 0x1e85,
+ 0xb3dc, 0x0501,
+ 0xb3dd, 0x1e86,
+ 0xb3de, 0x0503,
+ 0xb3e3, 0x1e87,
+ 0xb3e4, 0x0509,
+ 0xb3e5, 0x1e88,
+ 0xb3e7, 0x050c,
+ 0xb3e8, 0x1e8a,
+ 0xb3e9, 0x050e,
+ 0xb3eb, 0x1e8b,
+ 0xb3ed, 0x0512,
+ 0xb3ef, 0x1e8d,
+ 0xb3f0, 0x0515,
+ 0xb3f1, 0x1e8e,
+ 0xb3f2, 0x0517,
+ 0xb3f3, 0x1e8f,
+ 0xb3f4, 0x0519,
+ 0xb3fa, 0x1e90,
+ 0xb3fc, 0x0521,
+ 0xb4a1, 0x1e92,
+ 0xb4a3, 0x0526,
+ 0xb4a5, 0x1e94,
+ 0xb4a7, 0x052a,
+ 0xb4ab, 0x1e96,
+ 0xb4ac, 0x052f,
+ 0xb4af, 0x1e97,
+ 0xb4b0, 0x0533,
+ 0xb4b3, 0x1e98,
+ 0xb4b5, 0x0538,
+ 0xb4b8, 0x1e9a,
+ 0xb4b9, 0x053c,
+ 0xb4bf, 0x1e9b,
+ 0xb4c0, 0x0543,
+ 0xb4c2, 0x1e9c,
+ 0xb4c3, 0x0546,
+ 0xb4c7, 0x1e9d,
+ 0xb4c8, 0x054b,
+ 0xb4ca, 0x1e9e,
+ 0xb4cb, 0x054e,
+ 0xb4cd, 0x1e9f,
+ 0xb4ce, 0x0551,
+ 0xb4cf, 0x1ea0,
+ 0xb4d0, 0x0553,
+ 0xb4d3, 0x1ea1,
+ 0xb4d5, 0x0558,
+ 0xb4da, 0x1ea3,
+ 0xb4db, 0x055e,
+ 0xb4dc, 0x1ea4,
+ 0xb4dd, 0x0560,
+ 0xb4ed, 0x1ea5,
+ 0xb4ee, 0x0571,
+ 0xb4ef, 0x1ea6,
+ 0xb4f0, 0x0573,
+ 0xb4f8, 0x1ea7,
+ 0xb4f9, 0x057c,
+ 0xb4fb, 0x1ea8,
+ 0xb4fc, 0x057f,
+ 0xb5a1, 0x0582,
+ 0xb5a3, 0x1ea9,
+ 0xb5a4, 0x0585,
+ 0xb5a5, 0x1eaa,
+ 0xb5a9, 0x058a,
+ 0xb5ac, 0x1eae,
+ 0xb5ad, 0x058e,
+ 0xb5ae, 0x1eaf,
+ 0xb5b0, 0x0591,
+ 0xb5b1, 0x1eb1,
+ 0xb5b6, 0x0597,
+ 0xb5b7, 0x1eb6,
+ 0xb5b8, 0x0599,
+ 0xb5ba, 0x1eb7,
+ 0xb5bd, 0x059e,
+ 0xb5c6, 0x1eba,
+ 0xb5c7, 0x05a8,
+ 0xb5cb, 0x1ebb,
+ 0xb5cc, 0x05ad,
+ 0xb5d0, 0x1ebc,
+ 0xb5d1, 0x05b2,
+ 0xb5d3, 0x1ebd,
+ 0xb5d4, 0x05b5,
+ 0xb5dd, 0x1ebe,
+ 0xb5e0, 0x05c1,
+ 0xb5e3, 0x1ec1,
+ 0xb5e4, 0x05c5,
+ 0xb5e6, 0x1ec2,
+ 0xb5e8, 0x05c9,
+ 0xb5ed, 0x1ec4,
+ 0xb5ee, 0x05cf,
+ 0xb5f6, 0x1ec5,
+ 0xb5f8, 0x05d9,
+ 0xb5fd, 0x1ec7,
+ 0xb5fe, 0x05df,
+ 0xb6a1, 0x05e0,
+ 0xb6a4, 0x1ec8,
+ 0xb6a6, 0x05e5,
+ 0xb6a7, 0x1eca,
+ 0xb6a8, 0x05e7,
+ 0xb6a9, 0x1ecb,
+ 0xb6aa, 0x05e9,
+ 0xb6ab, 0x1ecc,
+ 0xb6ac, 0x05eb,
+ 0xb6af, 0x1ecd,
+ 0xb6b1, 0x05f0,
+ 0xb6b3, 0x1ecf,
+ 0xb6b4, 0x05f3,
+ 0xb6b7, 0x1ed0,
+ 0xb6b8, 0x05f7,
+ 0xb6bf, 0x1ed1,
+ 0xb6c2, 0x0601,
+ 0xb6c4, 0x1ed4,
+ 0xb6c5, 0x0604,
+ 0xb6c6, 0x1ed5,
+ 0xb6c7, 0x0606,
+ 0xb6cd, 0x1ed6,
+ 0xb6ce, 0x060d,
+ 0xb6cf, 0x1ed7,
+ 0xb6d1, 0x0610,
+ 0xb6d3, 0x1ed9,
+ 0xb6d5, 0x0614,
+ 0xb6d6, 0x1edb,
+ 0xb6d7, 0x0616,
+ 0xb6d9, 0x1edc,
+ 0xb6da, 0x0619,
+ 0xb6db, 0x1edd,
+ 0xb6dc, 0x061b,
+ 0xb6e1, 0x1ede,
+ 0xb6e2, 0x0621,
+ 0xb6e9, 0x1edf,
+ 0xb6ea, 0x0629,
+ 0xb6ec, 0x1ee0,
+ 0xb6ed, 0x062c,
+ 0xb6ee, 0x1ee1,
+ 0xb6f0, 0x062f,
+ 0xb6f1, 0x1ee3,
+ 0xb6f2, 0x0631,
+ 0xb6f6, 0x1ee4,
+ 0xb6f7, 0x0636,
+ 0xb6f9, 0x1ee5,
+ 0xb6fa, 0x0639,
+ 0xb6fb, 0x1ee6,
+ 0xb6fd, 0x063c,
+ 0xb7a1, 0x1ee8,
+ 0xb7a4, 0x0641,
+ 0xb7a7, 0x1eeb,
+ 0xb7a8, 0x0645,
+ 0xb7af, 0x1eec,
+ 0xb7b1, 0x064e,
+ 0xb7b3, 0x1eee,
+ 0xb7b4, 0x0651,
+ 0xb7b6, 0x1eef,
+ 0xb7b8, 0x0655,
+ 0xb7b9, 0x1ef1,
+ 0xb7ba, 0x0657,
+ 0xb7c3, 0x1ef2,
+ 0xb7c5, 0x0662,
+ 0xb7c9, 0x1ef4,
+ 0xb7ca, 0x0667,
+ 0xb7cc, 0x1ef5,
+ 0xb7cd, 0x066a,
+ 0xb7cf, 0x1ef6,
+ 0xb7d0, 0x066d,
+ 0xb7d1, 0x1ef7,
+ 0xb7d2, 0x066f,
+ 0xb7d7, 0x1ef8,
+ 0xb7d9, 0x0676,
+ 0xb7dc, 0x1efa,
+ 0xb7dd, 0x067a,
+ 0xb7df, 0x1efb,
+ 0xb7e2, 0x067f,
+ 0xb7e3, 0x1efe,
+ 0xb7e4, 0x0681,
+ 0xb7e6, 0x1eff,
+ 0xb7e9, 0x0686,
+ 0xb7eb, 0x1f02,
+ 0xb7ee, 0x068b,
+ 0xb7ef, 0x1f05,
+ 0xb7f0, 0x068d,
+ 0xb7f4, 0x1f06,
+ 0xb7f5, 0x0692,
+ 0xb7f8, 0x1f07,
+ 0xb7f9, 0x0696,
+ 0xb8a1, 0x069c,
+ 0xb8a7, 0x1f08,
+ 0xb8a9, 0x06a4,
+ 0xb8b3, 0x1f0a,
+ 0xb8b5, 0x06b0,
+ 0xb8ba, 0x1f0c,
+ 0xb8bb, 0x06b6,
+ 0xb8bc, 0x1f0d,
+ 0xb8bd, 0x06b8,
+ 0xb8be, 0x1f0e,
+ 0xb8c0, 0x06bb,
+ 0xb8c3, 0x1f10,
+ 0xb8c4, 0x06bf,
+ 0xb8c6, 0x1f11,
+ 0xb8c8, 0x06c3,
+ 0xb8c9, 0x1f13,
+ 0xb8ca, 0x06c5,
+ 0xb8cf, 0x1f14,
+ 0xb8d0, 0x06cb,
+ 0xb8d3, 0x1f15,
+ 0xb8d7, 0x06d2,
+ 0xb8d9, 0x1f19,
+ 0xb8db, 0x06d6,
+ 0xb8e4, 0x1f1b,
+ 0xb8e5, 0x06e0,
+ 0xb8e9, 0x1f1c,
+ 0xb8ea, 0x06e5,
+ 0xb8eb, 0x1f1d,
+ 0xb8ec, 0x06e7,
+ 0xb8f3, 0x1f1e,
+ 0xb8f4, 0x06ef,
+ 0xb8f5, 0x1f1f,
+ 0xb8f7, 0x06f2,
+ 0xb8f8, 0x1f21,
+ 0xb8f9, 0x06f4,
+ 0xb9a1, 0x06fa,
+ 0xb9a8, 0x1f22,
+ 0xb9a9, 0x0702,
+ 0xb9ae, 0x1f23,
+ 0xb9af, 0x0708,
+ 0xb9b1, 0x1f24,
+ 0xb9b2, 0x070b,
+ 0xb9b3, 0x1f25,
+ 0xb9b4, 0x070d,
+ 0xb9b5, 0x1f26,
+ 0xb9b6, 0x070f,
+ 0xb9b9, 0x1f27,
+ 0xb9bb, 0x0714,
+ 0xb9c6, 0x1f29,
+ 0xb9c7, 0x0720,
+ 0xb9cb, 0x1f2a,
+ 0xb9cc, 0x0725,
+ 0xb9d0, 0x1f2b,
+ 0xb9d1, 0x072a,
+ 0xb9d8, 0x1f2c,
+ 0xb9d9, 0x0732,
+ 0xb9db, 0x1f2d,
+ 0xb9dc, 0x0735,
+ 0xb9dd, 0x1f2e,
+ 0xb9de, 0x0737,
+ 0xb9df, 0x1f2f,
+ 0xb9e0, 0x0739,
+ 0xb9e1, 0x1f30,
+ 0xb9e2, 0x073b,
+ 0xb9e3, 0x1f31,
+ 0xb9e4, 0x073d,
+ 0xb9e6, 0x1f32,
+ 0xb9e7, 0x0740,
+ 0xb9e9, 0x1f33,
+ 0xb9ed, 0x0746,
+ 0xb9ee, 0x1f37,
+ 0xb9ef, 0x0748,
+ 0xb9f1, 0x1f38,
+ 0xb9f2, 0x074b,
+ 0xb9f3, 0x1f39,
+ 0xb9f6, 0x074f,
+ 0xb9f8, 0x1f3c,
+ 0xb9f9, 0x0752,
+ 0xb9fa, 0x1f3d,
+ 0xb9fb, 0x0754,
+ 0xb9fd, 0x1f3e,
+ 0xb9fe, 0x0757,
+ 0xbaa1, 0x0758,
+ 0xbaa7, 0x1f3f,
+ 0xbaa8, 0x075f,
+ 0xbaab, 0x1f40,
+ 0xbaac, 0x0763,
+ 0xbaba, 0x1f41,
+ 0xbabb, 0x0772,
+ 0xbac5, 0x1f42,
+ 0xbac6, 0x077d,
+ 0xbad2, 0x1f43,
+ 0xbad3, 0x078a,
+ 0xbad7, 0x1f44,
+ 0xbad9, 0x0790,
+ 0xbae4, 0x1f46,
+ 0xbae5, 0x079c,
+ 0xbae8, 0x1f47,
+ 0xbae9, 0x07a0,
+ 0xbaec, 0x1f48,
+ 0xbaed, 0x07a4,
+ 0xbaf3, 0x15e5,
+ 0xbaf4, 0x07ab,
+ 0xbaf8, 0x1f49,
+ 0xbaf9, 0x07b0,
+ 0xbba1, 0x07b6,
+ 0xbba4, 0x1f4a,
+ 0xbba5, 0x07ba,
+ 0xbba6, 0x1f4b,
+ 0xbba7, 0x07bc,
+ 0xbba9, 0x1f4c,
+ 0xbbab, 0x07c0,
+ 0xbbad, 0x1f4e,
+ 0xbbaf, 0x07c4,
+ 0xbbb0, 0x1f50,
+ 0xbbb1, 0x07c6,
+ 0xbbb3, 0x1f51,
+ 0xbbb4, 0x07c9,
+ 0xbbb5, 0x1f52,
+ 0xbbb8, 0x07cd,
+ 0xbbb9, 0x1f55,
+ 0xbbbb, 0x07d0,
+ 0xbbd1, 0x1f57,
+ 0xbbd2, 0x07e7,
+ 0xbbd3, 0x1f58,
+ 0xbbd5, 0x07ea,
+ 0xbbdf, 0x1f5a,
+ 0xbbe8, 0x07fd,
+ 0xbbeb, 0x1f63,
+ 0xbbec, 0x0801,
+ 0xbbf1, 0x1f64,
+ 0xbbf2, 0x0807,
+ 0xbbf5, 0x1f65,
+ 0xbbf8, 0x080d,
+ 0xbbfa, 0x1f68,
+ 0xbbfb, 0x0810,
+ 0xbbfd, 0x1f69,
+ 0xbbfe, 0x0813,
+ 0xbca1, 0x0814,
+ 0xbca2, 0x1f6a,
+ 0xbca3, 0x0816,
+ 0xbca5, 0x1f6b,
+ 0xbca7, 0x081a,
+ 0xbca8, 0x1f6d,
+ 0xbcaa, 0x081d,
+ 0xbcab, 0x1f6f,
+ 0xbcac, 0x081f,
+ 0xbcad, 0x1f70,
+ 0xbcae, 0x0821,
+ 0xbcb6, 0x1f71,
+ 0xbcb9, 0x082c,
+ 0xbcbb, 0x1f74,
+ 0xbcbc, 0x082f,
+ 0xbcc1, 0x1f75,
+ 0xbcc2, 0x0835,
+ 0xbcc3, 0x1f76,
+ 0xbcc4, 0x0837,
+ 0xbcc6, 0x1f77,
+ 0xbcc8, 0x083b,
+ 0xbcca, 0x1f79,
+ 0xbccb, 0x083e,
+ 0xbccc, 0x1f7a,
+ 0xbcce, 0x0841,
+ 0xbcd0, 0x1f7c,
+ 0xbcd1, 0x0844,
+ 0xbcd4, 0x1f7d,
+ 0xbcd7, 0x084a,
+ 0xbcd8, 0x1f80,
+ 0xbcd9, 0x084c,
+ 0xbcdb, 0x1f81,
+ 0xbcdc, 0x084f,
+ 0xbcdd, 0x1f82,
+ 0xbcde, 0x0851,
+ 0xbcdf, 0x1f83,
+ 0xbce2, 0x0855,
+ 0xbce3, 0x1f86,
+ 0xbce5, 0x0858,
+ 0xbce8, 0x1f88,
+ 0xbce9, 0x085c,
+ 0xbcea, 0x1f89,
+ 0xbced, 0x0860,
+ 0xbcef, 0x1f8c,
+ 0xbcf4, 0x0867,
+ 0xbcf6, 0x1f91,
+ 0xbcfd, 0x0870,
+ 0xbda1, 0x0872,
+ 0xbda2, 0x1f98,
+ 0xbda8, 0x0879,
+ 0xbdab, 0x1f9e,
+ 0xbdad, 0x087e,
+ 0xbdaf, 0x1fa0,
+ 0xbdb3, 0x0884,
+ 0xbdb4, 0x1fa4,
+ 0xbdb5, 0x0886,
+ 0xbdba, 0x1fa5,
+ 0xbdbb, 0x088c,
+ 0xbdbd, 0x1fa6,
+ 0xbdc0, 0x0891,
+ 0xbdc1, 0x1fa9,
+ 0xbdc5, 0x0896,
+ 0xbdc8, 0x1fad,
+ 0xbdcb, 0x089c,
+ 0xbdce, 0x1fb0,
+ 0xbdd0, 0x08a1,
+ 0xbdd7, 0x1fb2,
+ 0xbdd8, 0x08a9,
+ 0xbdda, 0x1fb3,
+ 0xbddb, 0x08ac,
+ 0xbde0, 0x1fb4,
+ 0xbde2, 0x08b3,
+ 0xbdeb, 0x1fb6,
+ 0xbdec, 0x08bd,
+ 0xbdf4, 0x1fb7,
+ 0xbdf9, 0x08ca,
+ 0xbdfd, 0x1fbc,
+ 0xbdfe, 0x08cf,
+ 0xbea1, 0x1fbd,
+ 0xbea3, 0x08d2,
+ 0xbea5, 0x1fbf,
+ 0xbea6, 0x08d5,
+ 0xbea8, 0x1fc0,
+ 0xbea9, 0x08d8,
+ 0xbeaa, 0x1fc1,
+ 0xbeab, 0x08da,
+ 0xbead, 0x1fc2,
+ 0xbeae, 0x08dd,
+ 0xbeb1, 0x1fc3,
+ 0xbeb2, 0x08e1,
+ 0xbeb5, 0x1fc4,
+ 0xbeb8, 0x08e7,
+ 0xbeba, 0x1fc7,
+ 0xbebb, 0x08ea,
+ 0xbec0, 0x1fc8,
+ 0xbec1, 0x08f0,
+ 0xbec9, 0x1fc9,
+ 0xbeca, 0x08f9,
+ 0xbed4, 0x1fca,
+ 0xbed5, 0x0904,
+ 0xbed9, 0x1fcb,
+ 0xbeda, 0x0909,
+ 0xbedd, 0x1fcc,
+ 0xbede, 0x090d,
+ 0xbee2, 0x1fcd,
+ 0xbee3, 0x0912,
+ 0xbee5, 0x1fce,
+ 0xbee6, 0x0915,
+ 0xbee7, 0x1fcf,
+ 0xbee8, 0x0917,
+ 0xbee9, 0x1fd0,
+ 0xbeea, 0x0919,
+ 0xbeee, 0x1fd1,
+ 0xbeef, 0x091e,
+ 0xbef5, 0x1fd2,
+ 0xbef6, 0x0925,
+ 0xbef7, 0x1fd3,
+ 0xbef9, 0x0928,
+ 0xbefb, 0x1fd5,
+ 0xbefd, 0x092c,
+ 0xbfa1, 0x092e,
+ 0xbfa5, 0x1fd7,
+ 0xbfa6, 0x0933,
+ 0xbfaa, 0x1fd8,
+ 0xbfab, 0x0938,
+ 0xbfad, 0x1fd9,
+ 0xbfae, 0x093b,
+ 0xbfc5, 0x1fda,
+ 0xbfc6, 0x0953,
+ 0xbfc7, 0x1fdb,
+ 0xbfc8, 0x0955,
+ 0xbfce, 0x1fdc,
+ 0xbfcf, 0x095c,
+ 0xbfd1, 0x1fdd,
+ 0xbfd3, 0x0960,
+ 0xbfd9, 0x1fdf,
+ 0xbfda, 0x0967,
+ 0xbfe2, 0x1fe0,
+ 0xbfe5, 0x0972,
+ 0xbfe9, 0x1fe3,
+ 0xbfea, 0x0977,
+ 0xbfeb, 0x1fe4,
+ 0xbfec, 0x0979,
+ 0xbfed, 0x1fe5,
+ 0xbfee, 0x097b,
+ 0xbff3, 0x1fe6,
+ 0xbff4, 0x0981,
+ 0xbff5, 0x1fe7,
+ 0xbff6, 0x0983,
+ 0xbff7, 0x1fe8,
+ 0xbff8, 0x0985,
+ 0xbff9, 0x1fe9,
+ 0xbffb, 0x0988,
+ 0xc0a1, 0x1feb,
+ 0xc0a2, 0x098d,
+ 0xc0a3, 0x1fec,
+ 0xc0a4, 0x098f,
+ 0xc0a9, 0x1fed,
+ 0xc0aa, 0x0995,
+ 0xc0ab, 0x1fee,
+ 0xc0ac, 0x0997,
+ 0xc0af, 0x1fef,
+ 0xc0b1, 0x099c,
+ 0xc0b3, 0x1ff1,
+ 0xc0b7, 0x09a2,
+ 0xc0b8, 0x1ff5,
+ 0xc0c5, 0x09b0,
+ 0xc0cc, 0x2002,
+ 0xc0ce, 0x09b9,
+ 0xc0d4, 0x2004,
+ 0xc0d5, 0x09c0,
+ 0xc0d6, 0x2005,
+ 0xc0d7, 0x09c2,
+ 0xc0d8, 0x2006,
+ 0xc0d9, 0x09c4,
+ 0xc0dd, 0x2007,
+ 0xc0de, 0x09c9,
+ 0xc0e0, 0x2008,
+ 0xc0e1, 0x09cc,
+ 0xc0e9, 0x2009,
+ 0xc0ea, 0x09d5,
+ 0xc0eb, 0x200a,
+ 0xc0ed, 0x09d8,
+ 0xc0ef, 0x200c,
+ 0xc0f2, 0x09dd,
+ 0xc0f6, 0x200f,
+ 0xc0fb, 0x09e6,
+ 0xc1a1, 0x09ea,
+ 0xc1a4, 0x2014,
+ 0xc1a6, 0x09ef,
+ 0xc1a9, 0x2016,
+ 0xc1ae, 0x09f7,
+ 0xc1af, 0x201b,
+ 0xc1b9, 0x0a02,
+ 0xc1bd, 0x2025,
+ 0xc1bf, 0x0a08,
+ 0xc1c2, 0x2027,
+ 0xc1c3, 0x0a0c,
+ 0xc1c6, 0x2028,
+ 0xc1c7, 0x0a10,
+ 0xc1c9, 0x2029,
+ 0xc1ca, 0x0a13,
+ 0xc1cd, 0x202a,
+ 0xc1ce, 0x0a17,
+ 0xc1d4, 0x202b,
+ 0xc1d5, 0x0a1e,
+ 0xc1d9, 0x202c,
+ 0xc1dc, 0x0a25,
+ 0xc1de, 0x202f,
+ 0xc1df, 0x0a28,
+ 0xc1e4, 0x2030,
+ 0xc1e6, 0x0a2f,
+ 0xc1e9, 0x2032,
+ 0xc1ea, 0x0a33,
+ 0xc1eb, 0x2033,
+ 0xc1ed, 0x0a36,
+ 0xc1f3, 0x2035,
+ 0xc1f4, 0x0a3d,
+ 0xc1f5, 0x2036,
+ 0xc1f6, 0x0a3f,
+ 0xc1fa, 0x2037,
+ 0xc1fe, 0x0a47,
+ 0xc2a1, 0x0a48,
+ 0xc2a2, 0x203b,
+ 0xc2a9, 0x0a50,
+ 0xc2ab, 0x2042,
+ 0xc2b4, 0x0a5b,
+ 0xc2b8, 0x204b,
+ 0xc2b9, 0x0a60,
+ 0xc2bc, 0x204c,
+ 0xc2be, 0x0a65,
+ 0xc2bf, 0x204e,
+ 0xc2c0, 0x0a67,
+ 0xc2c1, 0x204f,
+ 0xc2c2, 0x0a69,
+ 0xc2c5, 0x2050,
+ 0xc2c8, 0x0a6f,
+ 0xc2cb, 0x2053,
+ 0xc2d1, 0x0a78,
+ 0xc2d2, 0x2059,
+ 0xc2d3, 0x0a7a,
+ 0xc2d5, 0x205a,
+ 0xc2dd, 0x0a84,
+ 0xc2de, 0x2062,
+ 0xc2e3, 0x0a8a,
+ 0xc2e6, 0x2067,
+ 0xc2e9, 0x0a90,
+ 0xc2ea, 0x206a,
+ 0xc2ef, 0x0a96,
+ 0xc2f0, 0x206f,
+ 0xc2f1, 0x0a98,
+ 0xc2f2, 0x2070,
+ 0xc2f6, 0x0a9d,
+ 0xc2f7, 0x2074,
+ 0xc2fb, 0x0aa2,
+ 0xc3a1, 0x2078,
+ 0xc3a2, 0x0aa7,
+ 0xc3aa, 0x2079,
+ 0xc3ab, 0x0ab0,
+ 0xc3ad, 0x207a,
+ 0xc3ae, 0x0ab3,
+ 0xc3b3, 0x207b,
+ 0xc3b4, 0x1df9,
+ 0xc3b5, 0x0aba,
+ 0xc3be, 0x207c,
+ 0xc3bf, 0x0ac4,
+ 0xc3c5, 0x207d,
+ 0xc3c8, 0x0acd,
+ 0xc3cc, 0x2080,
+ 0xc3cd, 0x0ad2,
+ 0xc3ce, 0x2081,
+ 0xc3cf, 0x0ad4,
+ 0xc3d5, 0x2082,
+ 0xc3d7, 0x0adc,
+ 0xc3d9, 0x2084,
+ 0xc3da, 0x0adf,
+ 0xc3e0, 0x2085,
+ 0xc3e1, 0x0ae6,
+ 0xc3e5, 0x2086,
+ 0xc3e6, 0x0aeb,
+ 0xc3ed, 0x2087,
+ 0xc3ee, 0x0af3,
+ 0xc3f0, 0x2088,
+ 0xc3f1, 0x0af6,
+ 0xc3f5, 0x2089,
+ 0xc3f7, 0x0afc,
+ 0xc3f9, 0x208b,
+ 0xc3fb, 0x0b00,
+ 0xc3fd, 0x208d,
+ 0xc3fe, 0x0b03,
+ 0xc4a1, 0x0b04,
+ 0xc4b1, 0x208e,
+ 0xc4b2, 0x0b15,
+ 0xc4b6, 0x208f,
+ 0xc4b7, 0x0b1a,
+ 0xc4c6, 0x2090,
+ 0xc4c7, 0x0b2a,
+ 0xc4c9, 0x2091,
+ 0xc4ca, 0x0b2d,
+ 0xc4d1, 0x2092,
+ 0xc4d2, 0x0b35,
+ 0xc4d3, 0x2093,
+ 0xc4d7, 0x0b3a,
+ 0xc4d9, 0x2097,
+ 0xc4da, 0x0b3d,
+ 0xc4e2, 0x2098,
+ 0xc4e3, 0x0b46,
+ 0xc4e5, 0x2099,
+ 0xc4e6, 0x0b49,
+ 0xc4ec, 0x209a,
+ 0xc4ed, 0x0b50,
+ 0xc4f0, 0x209b,
+ 0xc4f2, 0x0b55,
+ 0xc4f4, 0x209d,
+ 0xc4f5, 0x0b58,
+ 0xc4f6, 0x209e,
+ 0xc4f9, 0x0b5c,
+ 0xc4fb, 0x20a1,
+ 0xc4fd, 0x0b60,
+ 0xc4fe, 0x20a3,
+ 0xc5a1, 0x20a4,
+ 0xc5a3, 0x0b64,
+ 0xc5a5, 0x20a6,
+ 0xc5aa, 0x0b6b,
+ 0xc5b1, 0x20ab,
+ 0xc5b2, 0x0b73,
+ 0xc5b5, 0x20ac,
+ 0xc5b6, 0x0b77,
+ 0xc5b7, 0x20ad,
+ 0xc5ba, 0x0b7b,
+ 0xc5bb, 0x20b0,
+ 0xc5bc, 0x0b7d,
+ 0xc5bd, 0x20b1,
+ 0xc5be, 0x0b7f,
+ 0xc5cc, 0x20b2,
+ 0xc5cd, 0x0b8e,
+ 0xc5d3, 0x20b3,
+ 0xc5d4, 0x0b95,
+ 0xc5e2, 0x20b4,
+ 0xc5e3, 0x0ba4,
+ 0xc5e7, 0x20b5,
+ 0xc5e8, 0x0ba9,
+ 0xc5f4, 0x20b6,
+ 0xc5f5, 0x0bb6,
+ 0xc6a1, 0x0bc0,
+ 0xc6ad, 0x20b7,
+ 0xc6af, 0x0bce,
+ 0xc6b5, 0x20b9,
+ 0xc6b7, 0x0bd6,
+ 0xc6bb, 0x20bb,
+ 0xc6bc, 0x0bdb,
+ 0xc6be, 0x20bc,
+ 0xc6bf, 0x0bde,
+ 0xc6c0, 0x20bd,
+ 0xc6c1, 0x0be0,
+ 0xc6c3, 0x20be,
+ 0xc6c5, 0x0be4,
+ 0xc6cb, 0x20c0,
+ 0xc6ce, 0x0bed,
+ 0xc6d3, 0x20c3,
+ 0xc6d4, 0x0bf3,
+ 0xc6d7, 0x20c4,
+ 0xc6d8, 0x0bf7,
+ 0xc6ea, 0x20c5,
+ 0xc6ec, 0x0c0b,
+ 0xc6ef, 0x20c7,
+ 0xc6f0, 0x0c0f,
+ 0xc6f1, 0x20c8,
+ 0xc6f2, 0x0c11,
+ 0xc6f4, 0x20c9,
+ 0xc6f5, 0x0c14,
+ 0xc6f8, 0x20ca,
+ 0xc6f9, 0x0c18,
+ 0xc6fd, 0x20cb,
+ 0xc6fe, 0x0c1d,
+ 0xc7a1, 0x0c1e,
+ 0xc7a3, 0x20cc,
+ 0xc7a4, 0x0c21,
+ 0xc7a5, 0x20cd,
+ 0xc7a7, 0x0c24,
+ 0xc7a8, 0x20cf,
+ 0xc7aa, 0x0c27,
+ 0xc7ab, 0x20d1,
+ 0xc7ac, 0x0c29,
+ 0xc7ae, 0x20d2,
+ 0xc7b0, 0x0c2d,
+ 0xc7b3, 0x20d4,
+ 0xc7b6, 0x0c33,
+ 0xc7b9, 0x20d7,
+ 0xc7bb, 0x0c38,
+ 0xc7bd, 0x20d9,
+ 0xc7bf, 0x0c3c,
+ 0xc7c0, 0x20db,
+ 0xc7c1, 0x0c3e,
+ 0xc7c2, 0x20dc,
+ 0xc7c3, 0x0c40,
+ 0xc7c5, 0x20dd,
+ 0xc7c6, 0x0c43,
+ 0xc7c7, 0x20de,
+ 0xc7c9, 0x0c46,
+ 0xc7cc, 0x20e0,
+ 0xc7cd, 0x0c4a,
+ 0xc7cf, 0x20e1,
+ 0xc7d0, 0x0c4d,
+ 0xc7d4, 0x20e2,
+ 0xc7d6, 0x0c53,
+ 0xc7d7, 0x20e4,
+ 0xc7d8, 0x0c55,
+ 0xc7de, 0x20e5,
+ 0xc7df, 0x0c5c,
+ 0xc7e1, 0x20e6,
+ 0xc7e4, 0x0c61,
+ 0xc7ea, 0x20e9,
+ 0xc7ef, 0x0c6c,
+ 0xc7f7, 0x20ee,
+ 0xc7f9, 0x0c76,
+ 0xc7fb, 0x20f0,
+ 0xc7fc, 0x0c79,
+ 0xc7fd, 0x20f1,
+ 0xc7fe, 0x0c7b,
+ 0xc8a1, 0x0c7c,
+ 0xc8a3, 0x20f2,
+ 0xc8a4, 0x0c7f,
+ 0xc8a7, 0x20f3,
+ 0xc8a9, 0x0c84,
+ 0xc8b0, 0x20f5,
+ 0xc8b1, 0x0c8c,
+ 0xc8b5, 0x20f6,
+ 0xc8b6, 0x0c91,
+ 0xc8b7, 0x20f7,
+ 0xc8b8, 0x0c93,
+ 0xc8c3, 0x20f8,
+ 0xc8c7, 0x0ca2,
+ 0xc8c8, 0x20fc,
+ 0xc8c9, 0x0ca4,
+ 0xc8cd, 0x20fd,
+ 0xc8ce, 0x0ca9,
+ 0xc8cf, 0x20fe,
+ 0xc8d0, 0x0cab,
+ 0xc8d2, 0x20ff,
+ 0xc8d3, 0x0cae,
+ 0xc8d9, 0x2100,
+ 0xc8da, 0x0cb5,
+ 0xc8de, 0x2101,
+ 0xc8df, 0x0cba,
+ 0xc8ed, 0x2102,
+ 0xc8ee, 0x0cc9,
+ 0xc8f1, 0x2103,
+ 0xc8f4, 0x0ccf,
+ 0xc8f7, 0x2106,
+ 0xc8f9, 0x0cd4,
+ 0xc8fa, 0x2108,
+ 0xc8fb, 0x0cd6,
+ 0xc8fc, 0x2109,
+ 0xc8fd, 0x0cd8,
+ 0xc9a1, 0x210a,
+ 0xc9a2, 0x0cdb,
+ 0xc9a5, 0x210b,
+ 0xc9a6, 0x0cdf,
+ 0xc9a7, 0x210c,
+ 0xc9a9, 0x0ce2,
+ 0xc9ac, 0x210e,
+ 0xc9ad, 0x0ce6,
+ 0xc9b1, 0x210f,
+ 0xc9b2, 0x0ceb,
+ 0xc9b4, 0x2110,
+ 0xc9b5, 0x0cee,
+ 0xc9b8, 0x2111,
+ 0xc9ba, 0x0cf3,
+ 0xc9c1, 0x2113,
+ 0xc9c3, 0x0cfc,
+ 0xc9c4, 0x2115,
+ 0xc9c5, 0x0cfe,
+ 0xc9c9, 0x2116,
+ 0xc9ca, 0x0d03,
+ 0xc9cb, 0x2117,
+ 0xc9cc, 0x0d05,
+ 0xc9cd, 0x2118,
+ 0xc9ce, 0x0d07,
+ 0xc9d5, 0x2119,
+ 0xc9d6, 0x0d0f,
+ 0xc9dc, 0x211a,
+ 0xc9dd, 0x0d16,
+ 0xc9de, 0x211b,
+ 0xc9df, 0x0d18,
+ 0xc9e1, 0x211c,
+ 0xc9e2, 0x0d1b,
+ 0xc9e3, 0x211d,
+ 0xc9e4, 0x0d1d,
+ 0xc9e5, 0x211e,
+ 0xc9e6, 0x0d1f,
+ 0xc9e8, 0x211f,
+ 0xc9e9, 0x0d22,
+ 0xc9f0, 0x2120,
+ 0xc9f1, 0x0d2a,
+ 0xc9f3, 0x2121,
+ 0xc9f5, 0x0d2e,
+ 0xc9f6, 0x2123,
+ 0xc9f7, 0x0d30,
+ 0xc9f8, 0x2124,
+ 0xc9fa, 0x0d33,
+ 0xc9fe, 0x2126,
+ 0xcaa1, 0x0d38,
+ 0xcaa4, 0x2127,
+ 0xcaa7, 0x0d3e,
+ 0xcaa8, 0x212a,
+ 0xcaa9, 0x0d40,
+ 0xcaaa, 0x212b,
+ 0xcaac, 0x0d43,
+ 0xcab1, 0x212d,
+ 0xcab2, 0x0d49,
+ 0xcab4, 0x212e,
+ 0xcab7, 0x0d4e,
+ 0xcabb, 0x2131,
+ 0xcabc, 0x0d53,
+ 0xcac6, 0x2132,
+ 0xcac7, 0x0d5e,
+ 0xcaca, 0x2133,
+ 0xcacb, 0x0d62,
+ 0xcacd, 0x2134,
+ 0xcacf, 0x0d66,
+ 0xcad3, 0x2136,
+ 0xcad5, 0x0d6c,
+ 0xcad9, 0x2138,
+ 0xcada, 0x0d71,
+ 0xcade, 0x2139,
+ 0xcadf, 0x0d76,
+ 0xcae0, 0x213a,
+ 0xcae1, 0x0d78,
+ 0xcae4, 0x213b,
+ 0xcae5, 0x0d7c,
+ 0xcae9, 0x213c,
+ 0xcaeb, 0x0d82,
+ 0xcaf4, 0x213e,
+ 0xcaf6, 0x0d8d,
+ 0xcaf7, 0x2140,
+ 0xcaf8, 0x0d8f,
+ 0xcafa, 0x2141,
+ 0xcafb, 0x0d92,
+ 0xcafd, 0x2142,
+ 0xcafe, 0x0d95,
+ 0xcba1, 0x0d96,
+ 0xcba7, 0x2143,
+ 0xcba8, 0x0d9d,
+ 0xcbab, 0x2144,
+ 0xcbac, 0x0da1,
+ 0xcbad, 0x2145,
+ 0xcbae, 0x0da3,
+ 0xcbb3, 0x2146,
+ 0xcbb4, 0x0da9,
+ 0xcbb5, 0x2147,
+ 0xcbb7, 0x0dac,
+ 0xcbb8, 0x2149,
+ 0xcbb9, 0x0dae,
+ 0xcbbf, 0x214a,
+ 0xcbc0, 0x0db5,
+ 0xcbc7, 0x214b,
+ 0xcbc8, 0x0dbd,
+ 0xcbc9, 0x214c,
+ 0xcbcd, 0x0dc2,
+ 0xcbcf, 0x2150,
+ 0xcbd1, 0x0dc6,
+ 0xcbd3, 0x2152,
+ 0xcbd4, 0x0dc9,
+ 0xcbd5, 0x2153,
+ 0xcbd6, 0x0dcb,
+ 0xcbdf, 0x2154,
+ 0xcbe1, 0x0dd6,
+ 0xcbe4, 0x2156,
+ 0xcbe5, 0x0dda,
+ 0xcbe6, 0x2157,
+ 0xcbe8, 0x0ddd,
+ 0xcbea, 0x2159,
+ 0xcbeb, 0x0de0,
+ 0xcbef, 0x215a,
+ 0xcbf1, 0x0de6,
+ 0xcbf5, 0x215c,
+ 0xcbf7, 0x0dec,
+ 0xcbf8, 0x215e,
+ 0xcbf9, 0x0dee,
+ 0xcca1, 0x215f,
+ 0xcca3, 0x0df6,
+ 0xcca8, 0x2161,
+ 0xcca9, 0x0dfc,
+ 0xccac, 0x2162,
+ 0xccad, 0x0e00,
+ 0xccaf, 0x2163,
+ 0xccb4, 0x0e07,
+ 0xccb7, 0x2168,
+ 0xccb9, 0x0e0c,
+ 0xccbe, 0x216a,
+ 0xccbf, 0x0e12,
+ 0xccc0, 0x216b,
+ 0xccc1, 0x0e14,
+ 0xcccc, 0x216c,
+ 0xcccd, 0x0e20,
+ 0xccce, 0x216d,
+ 0xcccf, 0x0e22,
+ 0xccd0, 0x216e,
+ 0xccd1, 0x0e24,
+ 0xccd6, 0x216f,
+ 0xccd7, 0x0e2a,
+ 0xccda, 0x2170,
+ 0xccdb, 0x0e2e,
+ 0xccdc, 0x2171,
+ 0xccdd, 0x0e30,
+ 0xcce0, 0x2172,
+ 0xcce1, 0x0e34,
+ 0xcce2, 0x2173,
+ 0xcce3, 0x0e36,
+ 0xcce5, 0x2174,
+ 0xcce6, 0x0e39,
+ 0xccf5, 0x2175,
+ 0xccf6, 0x0e49,
+ 0xccf9, 0x2176,
+ 0xccfb, 0x0e4e,
+ 0xccfc, 0x2178,
+ 0xcda1, 0x0e52,
+ 0xcdad, 0x217b,
+ 0xcdae, 0x0e5f,
+ 0xcdb3, 0x217c,
+ 0xcdb4, 0x0e65,
+ 0xcdb7, 0x217d,
+ 0xcdb8, 0x0e69,
+ 0xcdbc, 0x217e,
+ 0xcdbd, 0x0e6e,
+ 0xcdbf, 0x217f,
+ 0xcdc0, 0x0e71,
+ 0xcdc5, 0x2180,
+ 0xcdc6, 0x0e77,
+ 0xcdc7, 0x2181,
+ 0xcdc8, 0x0e79,
+ 0xcdd2, 0x2182,
+ 0xcdd3, 0x0e84,
+ 0xcdd4, 0x2183,
+ 0xcdd7, 0x0e88,
+ 0xcddd, 0x2186,
+ 0xcdde, 0x0e8f,
+ 0xcde0, 0x2187,
+ 0xcde1, 0x0e92,
+ 0xcde4, 0x2188,
+ 0xcde6, 0x0e97,
+ 0xcde7, 0x218a,
+ 0xcde8, 0x0e99,
+ 0xcdf2, 0x218b,
+ 0xcdf3, 0x0ea4,
+ 0xcdf8, 0x218c,
+ 0xcdf9, 0x0eaa,
+ 0xcea1, 0x0eb0,
+ 0xcea4, 0x218d,
+ 0xcea6, 0x0eb5,
+ 0xcea7, 0x218f,
+ 0xcea8, 0x0eb7,
+ 0xceaa, 0x2190,
+ 0xceae, 0x0ebd,
+ 0xceb0, 0x2194,
+ 0xceb2, 0x0ec1,
+ 0xceb3, 0x2196,
+ 0xceb4, 0x0ec3,
+ 0xcebd, 0x2197,
+ 0xcebe, 0x0ecd,
+ 0xcec0, 0x2198,
+ 0xcec1, 0x0ed0,
+ 0xcec5, 0x2199,
+ 0xcec7, 0x0ed6,
+ 0xcec8, 0x219b,
+ 0xcec9, 0x0ed8,
+ 0xceca, 0x219c,
+ 0xcecb, 0x0eda,
+ 0xcece, 0x219d,
+ 0xced2, 0x0ee1,
+ 0xced8, 0x21a1,
+ 0xcedb, 0x0eea,
+ 0xcedc, 0x21a4,
+ 0xcedd, 0x0eec,
+ 0xcede, 0x21a5,
+ 0xcee0, 0x0eef,
+ 0xceeb, 0x21a7,
+ 0xceec, 0x0efb,
+ 0xceed, 0x21a8,
+ 0xceee, 0x0efd,
+ 0xcef1, 0x21a9,
+ 0xcef2, 0x0f01,
+ 0xcef3, 0x21aa,
+ 0xcef4, 0x0f03,
+ 0xcefd, 0x21ab,
+ 0xcfa1, 0x0f0e,
+ 0xcfae, 0x21ad,
+ 0xcfaf, 0x0f1c,
+ 0xcfb0, 0x21ae,
+ 0xcfb1, 0x0f1e,
+ 0xcfb3, 0x21af,
+ 0xcfb4, 0x0f21,
+ 0xcfb7, 0x21b0,
+ 0xcfb9, 0x0f26,
+ 0xcfba, 0x21b2,
+ 0xcfbb, 0x0f28,
+ 0xcfbd, 0x21b3,
+ 0xcfbe, 0x0f2b,
+ 0xcfbf, 0x21b4,
+ 0xcfc2, 0x0f2f,
+ 0xcfc5, 0x21b7,
+ 0xcfc6, 0x0f33,
+ 0xcfc7, 0x21b8,
+ 0xcfc8, 0x0f35,
+ 0xcfca, 0x21b9,
+ 0xcfcc, 0x0f39,
+ 0xcfcd, 0x21bb,
+ 0xcfcf, 0x0f3c,
+ 0xcfd0, 0x21bd,
+ 0xcfd1, 0x0f3e,
+ 0xcfd4, 0x21be,
+ 0xcfd9, 0x0f46,
+ 0xcfda, 0x21c3,
+ 0xcfdb, 0x0f48,
+ 0xcfdc, 0x21c4,
+ 0xcfdd, 0x0f4a,
+ 0xcfdf, 0x21c5,
+ 0xcfe0, 0x0f4d,
+ 0xcfe2, 0x21c6,
+ 0xcfe3, 0x0f50,
+ 0xcfe7, 0x21c7,
+ 0xcfe8, 0x0f55,
+ 0xcfea, 0x21c8,
+ 0xcfeb, 0x0f58,
+ 0xcfec, 0x21c9,
+ 0xcfed, 0x0f5a,
+ 0xcfee, 0x21ca,
+ 0xcfef, 0x0f5c,
+ 0xcff4, 0x21cb,
+ 0xcff5, 0x0f62,
+ 0xcff9, 0x21cc,
+ 0xcffb, 0x0f68,
+ 0xcffe, 0x21ce,
+ 0xd0a1, 0x0f6c,
+ 0xd0a5, 0x21cf,
+ 0xd0a6, 0x0f71,
+ 0xd0ad, 0x21d0,
+ 0xd0af, 0x0f7a,
+ 0xd0b2, 0x21d2,
+ 0xd0b5, 0x0f80,
+ 0xd0ba, 0x21d5,
+ 0xd0bc, 0x0f87,
+ 0xd0bf, 0x21d7,
+ 0xd0c0, 0x0f8b,
+ 0xd0c6, 0x21d8,
+ 0xd0c7, 0x0f92,
+ 0xd0cb, 0x21d9,
+ 0xd0cc, 0x0f97,
+ 0xd0e2, 0x21da,
+ 0xd0e3, 0x0fae,
+ 0xd0e5, 0x21db,
+ 0xd0e6, 0x0fb1,
+ 0xd0eb, 0x21dc,
+ 0xd0ec, 0x0fb7,
+ 0xd0ed, 0x21dd,
+ 0xd0ee, 0x0fb9,
+ 0xd0f7, 0x21de,
+ 0xd0fa, 0x0fc5,
+ 0xd0fc, 0x21e1,
+ 0xd0fd, 0x0fc8,
+ 0xd1a1, 0x21e2,
+ 0xd1a3, 0x0fcc,
+ 0xd1a4, 0x21e4,
+ 0xd1a5, 0x0fce,
+ 0xd1a7, 0x21e5,
+ 0xd1a8, 0x0fd1,
+ 0xd1ab, 0x21e6,
+ 0xd1ac, 0x0fd5,
+ 0xd1af, 0x21e7,
+ 0xd1b2, 0x0fdb,
+ 0xd1b5, 0x21ea,
+ 0xd1b8, 0x0fe1,
+ 0xd1b9, 0x21ed,
+ 0xd1ba, 0x0fe3,
+ 0xd1bb, 0x21ee,
+ 0xd1bd, 0x0fe6,
+ 0xd1c6, 0x21f0,
+ 0xd1c9, 0x0ff2,
+ 0xd1cb, 0x21f3,
+ 0xd1cc, 0x0ff5,
+ 0xd1ce, 0x21f4,
+ 0xd1d0, 0x0ff9,
+ 0xd1d5, 0x21f6,
+ 0xd1d7, 0x1000,
+ 0xd1de, 0x21f8,
+ 0xd1df, 0x1008,
+ 0xd1e1, 0x21f9,
+ 0xd1e3, 0x100c,
+ 0xd1e8, 0x21fb,
+ 0xd1ea, 0x1013,
+ 0xd1ec, 0x21fd,
+ 0xd1ed, 0x1016,
+ 0xd1ee, 0x21fe,
+ 0xd1f0, 0x1019,
+ 0xd1f1, 0x2200,
+ 0xd1f2, 0x101b,
+ 0xd1f4, 0x2201,
+ 0xd1f5, 0x101e,
+ 0xd1f7, 0x2202,
+ 0xd1fa, 0x1023,
+ 0xd2a1, 0x1028,
+ 0xd2a2, 0x2205,
+ 0xd2a3, 0x102a,
+ 0xd2a5, 0x2206,
+ 0xd2a6, 0x102d,
+ 0xd2a9, 0x2207,
+ 0xd2aa, 0x1031,
+ 0xd2af, 0x2208,
+ 0xd2b0, 0x1037,
+ 0xd2b3, 0x2209,
+ 0xd2b4, 0x103b,
+ 0xd2b5, 0x220a,
+ 0xd2b7, 0x103e,
+ 0xd2bd, 0x220c,
+ 0xd2be, 0x1045,
+ 0xd2bf, 0x220d,
+ 0xd2c0, 0x1047,
+ 0xd2c3, 0x220e,
+ 0xd2c4, 0x104b,
+ 0xd2c5, 0x220f,
+ 0xd2c6, 0x104d,
+ 0xd2c7, 0x2210,
+ 0xd2c8, 0x104f,
+ 0xd2cf, 0x2211,
+ 0xd2d0, 0x1057,
+ 0xd2d5, 0x2212,
+ 0xd2d6, 0x105d,
+ 0xd2da, 0x2213,
+ 0xd2db, 0x1062,
+ 0xd2e4, 0x2214,
+ 0xd2e6, 0x106d,
+ 0xd2e8, 0x2216,
+ 0xd2ec, 0x1073,
+ 0xd2ef, 0x221a,
+ 0xd2f0, 0x1077,
+ 0xd2f1, 0x221b,
+ 0xd2f2, 0x1079,
+ 0xd2f5, 0x221c,
+ 0xd2f6, 0x107d,
+ 0xd2f8, 0x221d,
+ 0xd2f9, 0x1080,
+ 0xd2fb, 0x221e,
+ 0xd2fc, 0x1083,
+ 0xd2fe, 0x221f,
+ 0xd3a1, 0x1086,
+ 0xd3a3, 0x2220,
+ 0xd3ad, 0x1092,
+ 0xd3ae, 0x222a,
+ 0xd3af, 0x1094,
+ 0xd3b1, 0x222b,
+ 0xd3b2, 0x1097,
+ 0xd3b4, 0x222c,
+ 0xd3b7, 0x109c,
+ 0xd3b8, 0x222f,
+ 0xd3b9, 0x109e,
+ 0xd3bb, 0x2230,
+ 0xd3bc, 0x10a1,
+ 0xd3c5, 0x2231,
+ 0xd3c6, 0x10ab,
+ 0xd3c7, 0x2232,
+ 0xd3c8, 0x10ad,
+ 0xd3ca, 0x2233,
+ 0xd3cd, 0x10b2,
+ 0xd3d5, 0x2236,
+ 0xd3d6, 0x10bb,
+ 0xd3df, 0x2237,
+ 0xd3e1, 0x10c6,
+ 0xd3e3, 0x2239,
+ 0xd3e4, 0x10c9,
+ 0xd3e6, 0x223a,
+ 0xd3e7, 0x10cc,
+ 0xd3eb, 0x223b,
+ 0xd3ed, 0x10d2,
+ 0xd3ef, 0x223d,
+ 0xd3f0, 0x10d5,
+ 0xd3f4, 0x223e,
+ 0xd3f5, 0x10da,
+ 0xd3fc, 0x223f,
+ 0xd3fd, 0x10e2,
+ 0xd3fe, 0x2240,
+ 0xd4a1, 0x10e4,
+ 0xd4a4, 0x2241,
+ 0xd4a5, 0x10e8,
+ 0xd4a6, 0x2242,
+ 0xd4a9, 0x10ec,
+ 0xd4af, 0x2245,
+ 0xd4b3, 0x10f6,
+ 0xd4b5, 0x2249,
+ 0xd4b7, 0x10fa,
+ 0xd4b8, 0x224b,
+ 0xd4b9, 0x10fc,
+ 0xd4bc, 0x224c,
+ 0xd4bd, 0x1100,
+ 0xd4be, 0x224d,
+ 0xd4c0, 0x1103,
+ 0xd4c4, 0x224f,
+ 0xd4c5, 0x1108,
+ 0xd4c6, 0x2250,
+ 0xd4c8, 0x110b,
+ 0xd4c9, 0x2252,
+ 0xd4ca, 0x110d,
+ 0xd4cb, 0x2253,
+ 0xd4cf, 0x1112,
+ 0xd4d3, 0x2257,
+ 0xd4d4, 0x1117,
+ 0xd4d8, 0x2258,
+ 0xd4d9, 0x111c,
+ 0xd4dc, 0x2259,
+ 0xd4e1, 0x1124,
+ 0xd4e4, 0x225e,
+ 0xd4e5, 0x1128,
+ 0xd4e6, 0x225f,
+ 0xd4e7, 0x112a,
+ 0xd4ee, 0x2260,
+ 0xd4ef, 0x1132,
+ 0xd4f0, 0x2261,
+ 0xd4f5, 0x1138,
+ 0xd4f9, 0x2266,
+ 0xd4fa, 0x113d,
+ 0xd4fe, 0x2267,
+ 0xd5a1, 0x2268,
+ 0xd5a3, 0x1144,
+ 0xd5a9, 0x226a,
+ 0xd5aa, 0x114b,
+ 0xd5ab, 0x226b,
+ 0xd5ac, 0x114d,
+ 0xd5ae, 0x226c,
+ 0xd5af, 0x1150,
+ 0xd5b1, 0x226d,
+ 0xd5b2, 0x1153,
+ 0xd5b5, 0x226e,
+ 0xd5b9, 0x115a,
+ 0xd5bb, 0x2272,
+ 0xd5bc, 0x115d,
+ 0xd5bd, 0x2273,
+ 0xd5be, 0x115f,
+ 0xd5c0, 0x2274,
+ 0xd5c1, 0x1162,
+ 0xd5c5, 0x2275,
+ 0xd5c6, 0x1167,
+ 0xd5c7, 0x2276,
+ 0xd5c8, 0x1169,
+ 0xd5ca, 0x2277,
+ 0xd5cc, 0x116d,
+ 0xd5cd, 0x2279,
+ 0xd5ce, 0x116f,
+ 0xd5d4, 0x227a,
+ 0xd5d5, 0x1176,
+ 0xd5dd, 0x227b,
+ 0xd5df, 0x1180,
+ 0xd5e0, 0x227d,
+ 0xd5e1, 0x1182,
+ 0xd5e2, 0x227e,
+ 0xd5e3, 0x1184,
+ 0xd5ea, 0x227f,
+ 0xd5ed, 0x118e,
+ 0xd5ef, 0x2282,
+ 0xd5f0, 0x1191,
+ 0xd5f2, 0x2283,
+ 0xd5f4, 0x1195,
+ 0xd5f7, 0x15eb,
+ 0xd5f8, 0x1199,
+ 0xd6a1, 0x2285,
+ 0xd6a5, 0x11a4,
+ 0xd6af, 0x2289,
+ 0xd6b1, 0x11b0,
+ 0xd6b4, 0x228b,
+ 0xd6b5, 0x11b4,
+ 0xd6bb, 0x228c,
+ 0xd6bc, 0x11bb,
+ 0xd6bd, 0x228d,
+ 0xd6be, 0x11bd,
+ 0xd6bf, 0x228e,
+ 0xd6c1, 0x11c0,
+ 0xd6c4, 0x2290,
+ 0xd6c5, 0x11c4,
+ 0xd6ca, 0x2291,
+ 0xd6cb, 0x11ca,
+ 0xd6cd, 0x2292,
+ 0xd6ce, 0x11cd,
+ 0xd6d3, 0x2293,
+ 0xd6d4, 0x11d3,
+ 0xd6d5, 0x2294,
+ 0xd6d8, 0x11d7,
+ 0xd6da, 0x2297,
+ 0xd6db, 0x11da,
+ 0xd6df, 0x2298,
+ 0xd6e0, 0x11df,
+ 0xd6e1, 0x2299,
+ 0xd6e2, 0x11e1,
+ 0xd6e5, 0x229a,
+ 0xd6e6, 0x11e5,
+ 0xd6e7, 0x229b,
+ 0xd6e9, 0x11e8,
+ 0xd6ee, 0x229d,
+ 0xd6f0, 0x11ef,
+ 0xd6f2, 0x229f,
+ 0xd6f3, 0x11f2,
+ 0xd6f5, 0x22a0,
+ 0xd6f7, 0x11f6,
+ 0xd6fc, 0x22a2,
+ 0xd7a1, 0x11fe,
+ 0xd7a4, 0x22a5,
+ 0xd7a5, 0x1202,
+ 0xd7a8, 0x22a6,
+ 0xd7ab, 0x1208,
+ 0xd7ac, 0x22a9,
+ 0xd7ad, 0x120a,
+ 0xd7ae, 0x22aa,
+ 0xd7b2, 0x120f,
+ 0xd7b3, 0x22ae,
+ 0xd7b5, 0x1212,
+ 0xd7b6, 0x22b0,
+ 0xd7b7, 0x1214,
+ 0xd7b8, 0x22b1,
+ 0xd7bd, 0x121a,
+ 0xd7c7, 0x22b6,
+ 0xd7c8, 0x1225,
+ 0xd7ca, 0x22b7,
+ 0xd7cb, 0x1228,
+ 0xd7d5, 0x22b8,
+ 0xd7d6, 0x1233,
+ 0xd7db, 0x22b9,
+ 0xd7df, 0x123c,
+ 0xd7e7, 0x22bd,
+ 0xd7e8, 0x1245,
+ 0xd7e9, 0x22be,
+ 0xd7eb, 0x1248,
+ 0xd8a1, 0x1257,
+ 0xd8c4, 0x22c0,
+ 0xd8c5, 0x127b,
+ 0xd8c7, 0x22c1,
+ 0xd8c8, 0x127e,
+ 0xd8c9, 0x22c2,
+ 0xd8ca, 0x1280,
+ 0xd8cc, 0x22c3,
+ 0xd8ce, 0x1284,
+ 0xd8d0, 0x22c5,
+ 0xd8d2, 0x1288,
+ 0xd8d3, 0x22c7,
+ 0xd8d4, 0x128a,
+ 0xd8d9, 0x22c8,
+ 0xd8da, 0x1290,
+ 0xd8db, 0x22c9,
+ 0xd8dd, 0x1293,
+ 0xd8f1, 0x22cb,
+ 0xd8f2, 0x12a8,
+ 0xd8f6, 0x22cc,
+ 0xd8f8, 0x12ae,
+ 0xd9a1, 0x12b5,
+ 0xd9ad, 0x22ce,
+ 0xd9ae, 0x12c2,
+ 0xd9af, 0x22cf,
+ 0xd9b0, 0x12c4,
+ 0xd9b1, 0x22d0,
+ 0xd9b4, 0x12c8,
+ 0xd9c7, 0x22d3,
+ 0xd9c8, 0x12dc,
+ 0xd9cd, 0x22d4,
+ 0xd9d1, 0x12e5,
+ 0xd9dd, 0x22d8,
+ 0xd9de, 0x12f2,
+ 0xd9e1, 0x22d9,
+ 0xd9e2, 0x12f6,
+ 0xd9e4, 0x22da,
+ 0xd9e5, 0x12f9,
+ 0xd9e6, 0x22db,
+ 0xd9e7, 0x12fb,
+ 0xd9ec, 0x22dc,
+ 0xd9ed, 0x1301,
+ 0xd9f4, 0x22dd,
+ 0xd9f6, 0x130a,
+ 0xdaa1, 0x1313,
+ 0xdaa5, 0x22df,
+ 0xdae0, 0x1352,
+ 0xdaea, 0x231a,
+ 0xdaeb, 0x135d,
+ 0xdaf7, 0x231b,
+ 0xdaf8, 0x136a,
+ 0xdaf9, 0x231c,
+ 0xdafa, 0x136c,
+ 0xdafe, 0x231d,
+ 0xdba1, 0x1371,
+ 0xdba3, 0x231e,
+ 0xdba4, 0x1374,
+ 0xdba6, 0x231f,
+ 0xdba7, 0x1377,
+ 0xdba9, 0x2320,
+ 0xdbab, 0x137b,
+ 0xdbbb, 0x2322,
+ 0xdbbc, 0x138c,
+ 0xdbbd, 0x2323,
+ 0xdbbe, 0x138e,
+ 0xdbcf, 0x2324,
+ 0xdbd0, 0x13a0,
+ 0xdbd1, 0x2325,
+ 0xdbd2, 0x13a2,
+ 0xdbdb, 0x2326,
+ 0xdbdc, 0x13ac,
+ 0xdbde, 0x2327,
+ 0xdbdf, 0x13af,
+ 0xdbe2, 0x2328,
+ 0xdbe3, 0x13b3,
+ 0xdbe4, 0x2329,
+ 0xdbe5, 0x13b5,
+ 0xdbeb, 0x232a,
+ 0xdbec, 0x13bc,
+ 0xdbee, 0x232b,
+ 0xdbef, 0x13bf,
+ 0xdbf1, 0x232c,
+ 0xdbf2, 0x13c2,
+ 0xdbf5, 0x232d,
+ 0xdbf8, 0x13c8,
+ 0xdca1, 0x13cf,
+ 0xdcbc, 0x2330,
+ 0xdcbd, 0x13eb,
+ 0xdcbf, 0x2331,
+ 0xdcc0, 0x13ee,
+ 0xdcc2, 0x2332,
+ 0xdcc3, 0x13f1,
+ 0xdcc8, 0x2333,
+ 0xdccb, 0x13f9,
+ 0xdcd1, 0x2336,
+ 0xdcd2, 0x1400,
+ 0xdcd7, 0x2337,
+ 0xdcd8, 0x1406,
+ 0xdce0, 0x2338,
+ 0xdce1, 0x140f,
+ 0xdce3, 0x2339,
+ 0xdce5, 0x1413,
+ 0xdce9, 0x233b,
+ 0xdceb, 0x1419,
+ 0xdcf1, 0x233d,
+ 0xdcf2, 0x1420,
+ 0xdcf6, 0x233e,
+ 0xdcf7, 0x1425,
+ 0xdcf9, 0x233f,
+ 0xdcfa, 0x1428,
+ 0xdcfd, 0x2340,
+ 0xdda1, 0x2342,
+ 0xdda2, 0x142e,
+ 0xdda3, 0x2343,
+ 0xdda8, 0x1434,
+ 0xddaa, 0x2348,
+ 0xddac, 0x1438,
+ 0xddb2, 0x234a,
+ 0xddb3, 0x143f,
+ 0xddb5, 0x234b,
+ 0xddb6, 0x1442,
+ 0xddba, 0x234c,
+ 0xddbc, 0x1448,
+ 0xddd3, 0x234e,
+ 0xddd4, 0x1460,
+ 0xdddb, 0x234f,
+ 0xdddc, 0x1468,
+ 0xddde, 0x2350,
+ 0xdddf, 0x146b,
+ 0xdde4, 0x2351,
+ 0xdde5, 0x1471,
+ 0xddeb, 0x2352,
+ 0xddec, 0x1478,
+ 0xddf1, 0x2353,
+ 0xddf2, 0x147e,
+ 0xddf6, 0x2354,
+ 0xddf8, 0x1484,
+ 0xddfc, 0x2356,
+ 0xddfd, 0x1489,
+ 0xddfe, 0x2357,
+ 0xdea1, 0x148b,
+ 0xdead, 0x2358,
+ 0xdeae, 0x1498,
+ 0xdeb4, 0x2359,
+ 0xdeb5, 0x149f,
+ 0xdeba, 0x235a,
+ 0xdebb, 0x14a5,
+ 0xdec6, 0x235b,
+ 0xdec7, 0x14b1,
+ 0xdecf, 0x235c,
+ 0xded0, 0x14ba,
+ 0xded1, 0x235d,
+ 0xded3, 0x14bd,
+ 0xded8, 0x235f,
+ 0xded9, 0x14c3,
+ 0xdee2, 0x2360,
+ 0xdee3, 0x14cd,
+ 0xdee8, 0x2361,
+ 0xdee9, 0x14d3,
+ 0xdeec, 0x2362,
+ 0xdeed, 0x14d7,
+ 0xdef3, 0x2363,
+ 0xdef4, 0x14de,
+ 0xdefc, 0x2364,
+ 0xdefd, 0x14e7,
+ 0xdfa1, 0x14e9,
+ 0xdfa2, 0x2365,
+ 0xdfa4, 0x14ec,
+ 0xdfa5, 0x2367,
+ 0xdfa6, 0x14ee,
+ 0xdfb4, 0x2368,
+ 0xdfb5, 0x14fd,
+ 0xdfbc, 0x2369,
+ 0xdfbe, 0x1506,
+ 0xdfbf, 0x236b,
+ 0xdfc0, 0x1508,
+ 0xdfc2, 0x236c,
+ 0xdfc4, 0x150c,
+ 0xdfcc, 0x236e,
+ 0xdfcd, 0x1515,
+ 0xdfd0, 0x236f,
+ 0xdfd1, 0x1519,
+ 0xdfd5, 0x2370,
+ 0xdfd6, 0x151e,
+ 0xdfd8, 0x2371,
+ 0xdfda, 0x1522,
+ 0xdfdc, 0x2373,
+ 0xdfdd, 0x1525,
+ 0xdfe0, 0x2374,
+ 0xdfe1, 0x1529,
+ 0xdfe2, 0x2375,
+ 0xdfe3, 0x152b,
+ 0xdfe6, 0x2376,
+ 0xdfe7, 0x152f,
+ 0xdfe9, 0x2377,
+ 0xdfea, 0x1532,
+ 0xdfeb, 0x2378,
+ 0xdfec, 0x1534,
+ 0xdfef, 0x2379,
+ 0xdff0, 0x1538,
+ 0xdff5, 0x237a,
+ 0xdff6, 0x153e,
+ 0xdff9, 0x237b,
+ 0xdffa, 0x1542,
+ 0xe0a1, 0x1547,
+ 0xe0b6, 0x237c,
+ 0xe0b8, 0x155e,
+ 0xe0bf, 0x237e,
+ 0xe0c0, 0x1566,
+ 0xe0c8, 0x237f,
+ 0xe0c9, 0x156f,
+ 0xe0ce, 0x2380,
+ 0xe0cf, 0x1575,
+ 0xe0d3, 0x2381,
+ 0xe0d4, 0x157a,
+ 0xe0e0, 0x2382,
+ 0xe0e1, 0x1587,
+ 0xe0f0, 0x2383,
+ 0xe0f1, 0x1597,
+ 0xe0f8, 0x2384,
+ 0xe0f9, 0x159f,
+ 0xe0fc, 0x2385,
+ 0xe1a1, 0x15a5,
+ 0xe1ab, 0x2388,
+ 0xe1ac, 0x15b0,
+ 0xe1ad, 0x2389,
+ 0xe1ae, 0x15b2,
+ 0xe1b0, 0x238a,
+ 0xe1b1, 0x15b5,
+ 0xe1b4, 0x238b,
+ 0xe1b5, 0x15b9,
+ 0xe1bb, 0x238c,
+ 0xe1bc, 0x15c0,
+ 0xe1bd, 0x238d,
+ 0xe1be, 0x15c2,
+ 0xe1c0, 0x238e,
+ 0xe1c2, 0x15c6,
+ 0xe1c9, 0x2390,
+ 0xe1ca, 0x15ce,
+ 0xe1d0, 0x2391,
+ 0xe1d1, 0x15d5,
+ 0xe1db, 0x2392,
+ 0xe1dc, 0x15e0,
+ 0xe1e1, 0x07aa,
+ 0xe1e2, 0x2393,
+ 0xe1e3, 0x15e7,
+ 0xe1e7, 0x1198,
+ 0xe1e8, 0x15ec,
+ 0xe1ee, 0x2394,
+ 0xe1f0, 0x15f4,
+ 0xe1f6, 0x2396,
+ 0xe1f7, 0x15fb,
+ 0xe1f8, 0x2397,
+ 0xe1f9, 0x15fd,
+ 0xe1fd, 0x2398,
+ 0xe1fe, 0x1602,
+ 0xe2a1, 0x1603,
+ 0xe2a4, 0x2399,
+ 0xe2a5, 0x1607,
+ 0xe2a8, 0x239a,
+ 0xe2a9, 0x160b,
+ 0xe2bb, 0x239b,
+ 0xe2c5, 0x10c5,
+ 0xe2c6, 0x23a5,
+ 0xe2cf, 0x1631,
+ 0xe2d0, 0x23ae,
+ 0xe2d1, 0x1633,
+ 0xe2d9, 0x23af,
+ 0xe2da, 0x163c,
+ 0xe2e3, 0x23b0,
+ 0xe2e5, 0x1647,
+ 0xe2e6, 0x23b2,
+ 0xe2e7, 0x1649,
+ 0xe2e9, 0x23b3,
+ 0xe2ec, 0x164e,
+ 0xe2f8, 0x23b6,
+ 0xe2f9, 0x165b,
+ 0xe2fa, 0x23b7,
+ 0xe2fe, 0x1660,
+ 0xe3a1, 0x1661,
+ 0xe3a2, 0x23bb,
+ 0xe3a3, 0x1663,
+ 0xe3a5, 0x23bc,
+ 0xe3a6, 0x1666,
+ 0xe3ab, 0x23bd,
+ 0xe3ac, 0x166c,
+ 0xe3b4, 0x23be,
+ 0xe3b5, 0x1675,
+ 0xe3c5, 0x23bf,
+ 0xe3dc, 0x169c,
+ 0xe3e3, 0x23d6,
+ 0xe3e4, 0x16a4,
+ 0xe3ed, 0x23d7,
+ 0xe3ee, 0x16ae,
+ 0xe3f1, 0x23d8,
+ 0xe3f3, 0x16b3,
+ 0xe3f8, 0x23da,
+ 0xe3f9, 0x16b9,
+ 0xe3fe, 0x23db,
+ 0xe4a1, 0x16bf,
+ 0xe4a4, 0x23dc,
+ 0xe4a6, 0x16c4,
+ 0xe4ab, 0x23de,
+ 0xe4ac, 0x16ca,
+ 0xe4af, 0x23df,
+ 0xe4b2, 0x16d0,
+ 0xe4b5, 0x23e2,
+ 0xe4b7, 0x16d5,
+ 0xe4c2, 0x23e4,
+ 0xe4c3, 0x16e1,
+ 0xe4c5, 0x23e5,
+ 0xe4c6, 0x16e4,
+ 0xe4c9, 0x23e6,
+ 0xe4ca, 0x16e8,
+ 0xe4d9, 0x23e7,
+ 0xe4da, 0x16f8,
+ 0xe4dc, 0x23e8,
+ 0xe4dd, 0x16fb,
+ 0xe4de, 0x23e9,
+ 0xe4df, 0x16fd,
+ 0xe4e4, 0x23ea,
+ 0xe4e5, 0x1703,
+ 0xe4eb, 0x23eb,
+ 0xe4ed, 0x170b,
+ 0xe4f2, 0x23ed,
+ 0xe4f3, 0x1711,
+ 0xe4fe, 0x23ee,
+ 0xe5a1, 0x171d,
+ 0xe5b0, 0x23ef,
+ 0xe5b1, 0x172d,
+ 0xe5b9, 0x23f0,
+ 0xe5ba, 0x1736,
+ 0xe5c7, 0x23f1,
+ 0xe5c8, 0x1744,
+ 0xe5c9, 0x23f2,
+ 0xe5ca, 0x1746,
+ 0xe5ce, 0x23f3,
+ 0xe5cf, 0x174b,
+ 0xe5f0, 0x23f4,
+ 0xe5f1, 0x176d,
+ 0xe5f2, 0x23f5,
+ 0xe5f3, 0x176f,
+ 0xe5fc, 0x23f6,
+ 0xe5fe, 0x177a,
+ 0xe6a1, 0x177b,
+ 0xe6a3, 0x23f8,
+ 0xe6a4, 0x177e,
+ 0xe6ab, 0x23f9,
+ 0xe6ad, 0x1787,
+ 0xe6ae, 0x23fb,
+ 0xe6af, 0x1789,
+ 0xe6b4, 0x23fc,
+ 0xe6b6, 0x1790,
+ 0xe6bf, 0x23fe,
+ 0xe6c0, 0x179a,
+ 0xe6c8, 0x23ff,
+ 0xe6ca, 0x17a4,
+ 0xe6cd, 0x2401,
+ 0xe6ce, 0x17a8,
+ 0xe6e0, 0x2402,
+ 0xe7a1, 0x2421,
+ 0xe7db, 0x1813,
+ 0xe7e1, 0x245b,
+ 0xe7e3, 0x181b,
+ 0xe7e7, 0x245d,
+ 0xe7e8, 0x1820,
+ 0xe7ef, 0x245e,
+ 0xe7f0, 0x1828,
+ 0xe7f4, 0x245f,
+ 0xe7f7, 0x182f,
+ 0xe8a1, 0x1837,
+ 0xe8a8, 0x2462,
+ 0xe8a9, 0x183f,
+ 0xe8ac, 0x2463,
+ 0xe8ad, 0x1843,
+ 0xe8b6, 0x2464,
+ 0xe8b7, 0x184d,
+ 0xe8b8, 0x2465,
+ 0xe8bb, 0x1851,
+ 0xe8bf, 0x2468,
+ 0xe8c1, 0x1857,
+ 0xe8c5, 0x246a,
+ 0xe8c6, 0x185c,
+ 0xe8c7, 0x246b,
+ 0xe8ca, 0x1860,
+ 0xe8ce, 0x246e,
+ 0xe8cf, 0x1865,
+ 0xe8d0, 0x246f,
+ 0xe8d1, 0x1867,
+ 0xe8d3, 0x2470,
+ 0xe8d4, 0x186a,
+ 0xe8dd, 0x2471,
+ 0xe8de, 0x1874,
+ 0xe8df, 0x2472,
+ 0xe8e0, 0x1876,
+ 0xe8e2, 0x2473,
+ 0xe8e4, 0x187a,
+ 0xe8e5, 0x2475,
+ 0xe8e6, 0x187c,
+ 0xe8e7, 0x2476,
+ 0xe8e8, 0x187e,
+ 0xe8eb, 0x2477,
+ 0xe8ec, 0x1882,
+ 0xe8ed, 0x2478,
+ 0xe8ee, 0x1884,
+ 0xe8ef, 0x2479,
+ 0xe8f0, 0x1886,
+ 0xe8f9, 0x247a,
+ 0xe8fa, 0x1890,
+ 0xe8fc, 0x247b,
+ 0xe8fe, 0x1894,
+ 0xe9a1, 0x247d,
+ 0xe9a2, 0x1896,
+ 0xe9ad, 0x247e,
+ 0xe9ae, 0x18a2,
+ 0xe9b4, 0x247f,
+ 0xe9b6, 0x18aa,
+ 0xe9b7, 0x2481,
+ 0xe9b8, 0x18ac,
+ 0xe9c4, 0x2482,
+ 0xe9c5, 0x18b9,
+ 0xe9c6, 0x2483,
+ 0xe9c7, 0x18bb,
+ 0xe9c9, 0x2484,
+ 0xe9ca, 0x18be,
+ 0xe9d6, 0x2485,
+ 0xe9d7, 0x18cb,
+ 0xe9da, 0x2486,
+ 0xe9db, 0x18cf,
+ 0xe9e4, 0x2487,
+ 0xe9e5, 0x18d9,
+ 0xe9e6, 0x2488,
+ 0xe9e8, 0x18dc,
+ 0xe9e9, 0x248a,
+ 0xe9ea, 0x18de,
+ 0xe9eb, 0x248b,
+ 0xe9ec, 0x18e0,
+ 0xe9ed, 0x248c,
+ 0xeaa1, 0x249e,
+ 0xeaa6, 0x18f8,
+ 0xeaa7, 0x24a3,
+ 0xeaa9, 0x18fb,
+ 0xeab1, 0x24a5,
+ 0xeab2, 0x1904,
+ 0xeabc, 0x24a6,
+ 0xeabd, 0x190f,
+ 0xeaca, 0x24a7,
+ 0xeacb, 0x191d,
+ 0xeacd, 0x24a8,
+ 0xeace, 0x1920,
+ 0xead3, 0x24a9,
+ 0xead4, 0x1926,
+ 0xeada, 0x24aa,
+ 0xeaf0, 0x1942,
+ 0xeba1, 0x1951,
+ 0xeba7, 0x24c0,
+ 0xeba8, 0x1958,
+ 0xebaa, 0x24c1,
+ 0xebab, 0x195b,
+ 0xebb2, 0x24c2,
+ 0xebb3, 0x1963,
+ 0xebb9, 0x24c3,
+ 0xebba, 0x196a,
+ 0xebca, 0x24c4,
+ 0xebcc, 0x197c,
+ 0xebcd, 0x24c6,
+ 0xebce, 0x197e,
+ 0xebd6, 0x24c7,
+ 0xebd7, 0x1987,
+ 0xebda, 0x24c8,
+ 0xebdb, 0x198b,
+ 0xebe1, 0x24c9,
+ 0xebe2, 0x1992,
+ 0xebf7, 0x24ca,
+ 0xebf8, 0x19a8,
+ 0xeca1, 0x19af,
+ 0xeca3, 0x24cb,
+ 0xeca4, 0x19b2,
+ 0xeca9, 0x24cc,
+ 0xecaf, 0x19bd,
+ 0xecb1, 0x24d2,
+ 0xecb2, 0x19c0,
+ 0xecb4, 0x24d3,
+ 0xecb6, 0x19c4,
+ 0xecbe, 0x24d5,
+ 0xecc0, 0x19ce,
+ 0xecc1, 0x24d7,
+ 0xecc2, 0x19d0,
+ 0xecc7, 0x24d8,
+ 0xecc8, 0x19d6,
+ 0xeccb, 0x24d9,
+ 0xeccc, 0x19da,
+ 0xece2, 0x24da,
+ 0xece3, 0x19f1,
+ 0xecf2, 0x24db,
+ 0xecf3, 0x1a01,
+ 0xecf5, 0x24dc,
+ 0xecf6, 0x1a04,
+ 0xecf8, 0x24dd,
+ 0xecf9, 0x1a07,
+ 0xeda1, 0x24de,
+ 0xeda2, 0x1a0e,
+ 0xeda8, 0x24df,
+ 0xeda9, 0x1a15,
+ 0xedaf, 0x24e0,
+ 0xedb1, 0x1a1d,
+ 0xedb4, 0x24e2,
+ 0xedb5, 0x1a21,
+ 0xedb6, 0x24e3,
+ 0xedb7, 0x1a23,
+ 0xedb8, 0x24e4,
+ 0xedb9, 0x1a25,
+ 0xedba, 0x24e5,
+ 0xedbb, 0x1a27,
+ 0xedbf, 0x24e6,
+ 0xedc0, 0x1a2c,
+ 0xedc2, 0x24e7,
+ 0xedc4, 0x1a30,
+ 0xedcc, 0x24e9,
+ 0xedce, 0x1a3a,
+ 0xedd3, 0x24eb,
+ 0xedd4, 0x1a40,
+ 0xedd7, 0x24ec,
+ 0xedd8, 0x1a44,
+ 0xede8, 0x24ed,
+ 0xede9, 0x1a55,
+ 0xedee, 0x24ee,
+ 0xedef, 0x1a5b,
+ 0xedf9, 0x24ef,
+ 0xedfb, 0x1a67,
+ 0xeea1, 0x1a6b,
+ 0xeebc, 0x24f1,
+ 0xeebd, 0x1a87,
+ 0xeebf, 0x24f2,
+ 0xeec0, 0x1a8a,
+ 0xeec4, 0x24f3,
+ 0xefa1, 0x252e,
+ 0xeff2, 0x1b1a,
+ 0xf0a1, 0x1b27,
+ 0xf0a3, 0x257f,
+ 0xf0a4, 0x1b2a,
+ 0xf0af, 0x2580,
+ 0xf0da, 0x1b60,
+ 0xf0dc, 0x25ab,
+ 0xf0de, 0x1b64,
+ 0xf0df, 0x25ad,
+ 0xf0e0, 0x1b66,
+ 0xf0e9, 0x25ae,
+ 0xf0ea, 0x1b70,
+ 0xf0ec, 0x25af,
+ 0xf0ed, 0x1b73,
+ 0xf0ef, 0x25b0,
+ 0xf0f0, 0x1b76,
+ 0xf0f7, 0x25b1,
+ 0xf0f8, 0x1b7e,
+ 0xf0f9, 0x25b2,
+ 0xf0fa, 0x1b80,
+ 0xf0fc, 0x25b3,
+ 0xf0fd, 0x1b83,
+ 0xf1a1, 0x1b85,
+ 0xf1a8, 0x25b4,
+ 0xf1a9, 0x1b8d,
+ 0xf1ab, 0x25b5,
+ 0xf1ac, 0x1b90,
+ 0xf1ae, 0x25b6,
+ 0xf1af, 0x1b93,
+ 0xf1b2, 0x25b7,
+ 0xf1b3, 0x1b97,
+ 0xf1bc, 0x25b8,
+ 0xf1bd, 0x1ba1,
+ 0xf1c0, 0x25b9,
+ 0xf1c1, 0x1ba5,
+ 0xf1c9, 0x25ba,
+ 0xf1ca, 0x1bae,
+ 0xf1cd, 0x25bb,
+ 0xf1ce, 0x1bb2,
+ 0xf1cf, 0x25bc,
+ 0xf1d1, 0x1bb5,
+ 0xf1da, 0x25be,
+ 0xf1db, 0x1bbf,
+ 0xf1dc, 0x25bf,
+ 0xf1dd, 0x1bc1,
+ 0xf1e4, 0x25c0,
+ 0xf1e5, 0x1bc9,
+ 0xf1ec, 0x25c1,
+ 0xf1ed, 0x1bd1,
+ 0xf1ef, 0x25c2,
+ 0xf1f0, 0x1bd4,
+ 0xf1f7, 0x25c3,
+ 0xf1f8, 0x1bdc,
+ 0xf1f9, 0x25c4,
+ 0xf1fa, 0x1bde,
+ 0xf1fc, 0x25c5,
+ 0xf2a1, 0x25c8,
+ 0xf2ae, 0x1bf0,
+ 0xf2b1, 0x25d5,
+ 0xf2b3, 0x1bf5,
+ 0xf2b9, 0x25d7,
+ 0xf2ba, 0x1bfc,
+ 0xf2c3, 0x25d8,
+ 0xf2c4, 0x1c06,
+ 0xf2c9, 0x25d9,
+ 0xf2ca, 0x1c0c,
+ 0xf2cc, 0x25da,
+ 0xf2ce, 0x1c10,
+ 0xf2cf, 0x25dc,
+ 0xf2d0, 0x1c12,
+ 0xf2d3, 0x25dd,
+ 0xf2d4, 0x1c16,
+ 0xf2e5, 0x25de,
+ 0xf2e6, 0x1c28,
+ 0xf2ee, 0x25df,
+ 0xf2ef, 0x1c31,
+ 0xf2f7, 0x25e0,
+ 0xf2f8, 0x1c3a,
+ 0xf2fd, 0x25e1,
+ 0xf2fe, 0x1c40,
+ 0xf3a1, 0x1c41,
+ 0xf3bf, 0x25e2,
+ 0xf3c0, 0x1c60,
+ 0xf3c6, 0x25e3,
+ 0xf3c7, 0x1c67,
+ 0xf3c8, 0x25e4,
+ 0xf3c9, 0x1c69,
+ 0xf3d6, 0x25e5,
+ 0xf3d7, 0x1c77,
+ 0xf3d9, 0x25e6,
+ 0xf3da, 0x1c7a,
+ 0xf3e5, 0x25e7,
+ 0xf3e7, 0x1c87,
+ 0xf3ea, 0x25e9,
+ 0xf3eb, 0x1c8b,
+ 0xf3ec, 0x25ea,
+ 0xf3ed, 0x1c8d,
+ 0xf3ef, 0x25eb,
+ 0xf3f0, 0x1c90,
+ 0xf3f1, 0x25ec,
+ 0xf3f2, 0x1c92,
+ 0xf3fd, 0x25ed,
+ 0xf3fe, 0x1c9e,
+ 0xf4a1, 0x1c9f,
+ 0xf4a5, 0x25ee,
+ 0xf4a6, 0x1ca4,
+ 0xf4af, 0x25ef,
+ 0xf4b0, 0x1cae,
+ 0xf4b5, 0x25f0,
+ 0xf4b6, 0x1cb4,
+ 0xf4c1, 0x25f1,
+ 0xf4c2, 0x1cc0,
+ 0xf4c7, 0x25f2,
+ 0xf4c8, 0x1cc6,
+ 0xf4cf, 0x25f3,
+ 0xf4d1, 0x1ccf,
+ 0xf4d6, 0x25f5,
+ 0xf4d7, 0x1cd5,
+ 0xf4ea, 0x25f6,
+ 0xf4eb, 0x1ce9,
+ 0xf4ef, 0x25f7,
+ 0xf4f0, 0x1cee,
+ 0xf4f5, 0x25f8,
+ 0xf4f6, 0x1cf4,
+ 0xf5a1, 0x1cfd,
+ 0xf5a6, 0x25f9,
+ 0xf5a8, 0x1d04,
+ 0xf5ba, 0x25fb,
+ 0xf5bc, 0x1d18,
+ 0xf5c4, 0x25fd,
+ 0xf5c5, 0x1d21,
+ 0xf5c8, 0x25fe,
+ 0xf5c9, 0x1d25,
+ 0xf5ce, 0x25ff,
+ 0xf5d0, 0x1d2c,
+ 0xf5d1, 0x2601,
+ 0xf5d3, 0x1d2f,
+ 0xf5d9, 0x2603,
+ 0xf5da, 0x1d36,
+ 0xf5dc, 0x2604,
+ 0xf5dd, 0x1d39,
+ 0xf5e6, 0x2605,
+ 0xf5e8, 0x1d44,
+ 0xf5ef, 0x2607,
+ 0xf5f0, 0x1d4c,
+ 0xf5f2, 0x2608,
+ 0xf5f3, 0x1d4f,
+ 0xf5fc, 0x2609,
+ 0xf5fd, 0x1d59,
+ 0xf6a1, 0x1d5b,
+ 0xf6a3, 0x260a,
+ 0xf6a4, 0x1d5e,
+ 0xf6a6, 0x260b,
+ 0xf6a7, 0x1d61,
+ 0xf6a8, 0x260c,
+ 0xf6a9, 0x1d63,
+ 0xf6ab, 0x260d,
+ 0xf6ac, 0x1d66,
+ 0xf6b0, 0x260e,
+ 0xf6b1, 0x1d6b,
+ 0xf6b3, 0x260f,
+ 0xf6bf, 0x1d79,
+ 0xf6c5, 0x261b,
+ 0xf6c6, 0x1d80,
+ 0xf6c7, 0x261c,
+ 0xf6c8, 0x1d82,
+ 0xf6c9, 0x261d,
+ 0xf6ca, 0x1d84,
+ 0xf6cf, 0x261e,
+ 0xf7a1, 0x264e,
+ 0xf7b0, 0x1dc8,
+ 0xf7b2, 0x265d,
+ 0xf7b4, 0x1dcc,
+ 0xf7b5, 0x265f,
+ 0xf7b6, 0x1dce,
+ 0xf7bd, 0x2660,
+ 0xf7be, 0x1dd6,
+ 0xf7c3, 0x2661,
+ 0xf7c4, 0x1ddc,
+ 0xf7c5, 0x2662,
+ 0xf7c7, 0x1ddf,
+ 0xf7ca, 0x2664,
+ 0xf7cc, 0x1de4,
+ 0xf7cf, 0x2666,
+ 0xf7d1, 0x1de9,
+ 0xf7de, 0x2668,
+ 0xf7df, 0x1df7,
+ 0xf7e1, 0x0ab9,
+ 0xf7e2, 0x1dfa,
+ 0xf7f2, 0x2669,
+ 0xf7f3, 0x1e0b,
+ 0xf7f5, 0x266a,
+ 0xf7f6, 0x1e0e,
+ 0xf8a1, 0x266b,
+ 0xf8a7, 0x04cc,
+ 0xf8a8, 0x050a,
+ 0xf8a9, 0x0518,
+ 0xf8aa, 0x2671,
+ 0xf8ac, 0x0594,
+ 0xf8ad, 0x05ce,
+ 0xf8ae, 0x2673,
+ 0xf8af, 0x05f6,
+ 0xf8b0, 0x2674,
+ 0xf8b2, 0x0653,
+ 0xf8b3, 0x067e,
+ 0xf8b4, 0x2676,
+ 0xf8b5, 0x06c4,
+ 0xf8b6, 0x2677,
+ 0xf8b8, 0x073c,
+ 0xf8b9, 0x2679,
+ 0xf8bb, 0x07c3,
+ 0xf8bc, 0x267b,
+ 0xf8c0, 0x082b,
+ 0xf8c1, 0x267f,
+ 0xf8c2, 0x084e,
+ 0xf8c3, 0x0869,
+ 0xf8c4, 0x2680,
+ 0xf8c6, 0x090c,
+ 0xf8c7, 0x2682,
+ 0xf8c9, 0x0971,
+ 0xf8ca, 0x2684,
+ 0xf8cb, 0x099a,
+ 0xf8cd, 0x2685,
+ 0xf8ce, 0x09da,
+ 0xf8cf, 0x2686,
+ 0xf8d0, 0x09fa,
+ 0xf8d1, 0x2687,
+ 0xf8dc, 0x0bda,
+ 0xf8dd, 0x0bdd,
+ 0xf8de, 0x0bea,
+ 0xf8df, 0x0bec,
+ 0xf8e0, 0x0bf2,
+ 0xf8e1, 0x2692,
+ 0xf8e6, 0x0c92,
+ 0xf8e7, 0x0d1a,
+ 0xf8e8, 0x0d8c,
+ 0xf8e9, 0x0dbe,
+ 0xf8ea, 0x2697,
+ 0xf8eb, 0x0dfb,
+ 0xf8ec, 0x2698,
+ 0xf8ef, 0x0e70,
+ 0xf8f0, 0x269b,
+ 0xf8f1, 0x0ea3,
+ 0xf8f2, 0x269c,
+ 0xf8f8, 0x103d,
+ 0xf8f9, 0x10d9,
+ 0xf8fa, 0x26a2,
+ 0xf8fc, 0x10fb,
+ 0xf8fd, 0x1109,
+ 0xf8fe, 0x26a4,
+ 0xf9a1, 0x11a1,
+ 0xf9a2, 0x26a5,
+ 0xf9a3, 0x11ba,
+ 0xf9a4, 0x26a6,
+ 0xf9a6, 0x11d5,
+ 0xf9a7, 0x26a8,
+ 0xf9a8, 0x11fd,
+ 0xf9a9, 0x1219,
+ 0xa1a2, 0x023f,
+ 0xa1a3, 0x023e,
+ 0xa1aa, 0x0256,
+ 0xa1ab, 0x1e18,
+ 0xa1ad, 0x0257,
+ 0xa1b2, 0x0246,
+ 0xa1fe, 0x1e1a,
+ 0xa3a1, 0x0242,
+ 0xa3a8, 0x0244,
+ 0xa3ac, 0x023d,
+ 0xa3ae, 0x1e1b,
+ 0xa3ba, 0x0240,
+ 0xa3bd, 0x1e1c,
+ 0xa3bf, 0x0243,
+ 0xa3db, 0x1e1d,
+ 0xa3dd, 0x1e1e,
+ 0xa3df, 0x0258,
+ 0xa3fb, 0x0254,
+ 0xa3fd, 0x0255,
+ 0xa3fe, 0x1e1f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBTpcEUCVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x1e20, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e21, 0x1e22, 0x1e23 },
+ gb12GBTpcEUCVMap2, 2303
+};
+
+static Gushort gb12GBpcEUCHMap2[180] = {
+ 0x0000, 0x0000,
+ 0xa1a1, 0x0060,
+ 0xa2b1, 0x00be,
+ 0xa2e5, 0x00f0,
+ 0xa2f1, 0x00fa,
+ 0xa3a1, 0x0106,
+ 0xa4a1, 0x0164,
+ 0xa5a1, 0x01b7,
+ 0xa6a1, 0x020d,
+ 0xa6c1, 0x0225,
+ 0xa7a1, 0x025a,
+ 0xa7d1, 0x027b,
+ 0xa8a1, 0x029c,
+ 0xa8c5, 0x02bc,
+ 0xa9a4, 0x02e2,
+ 0xaaa1, 0x032e,
+ 0xaba1, 0x038c,
+ 0xb0a1, 0x03ac,
+ 0xb1a1, 0x040a,
+ 0xb2a1, 0x0468,
+ 0xb3a1, 0x04c6,
+ 0xb4a1, 0x0524,
+ 0xb5a1, 0x0582,
+ 0xb6a1, 0x05e0,
+ 0xb7a1, 0x063e,
+ 0xb8a1, 0x069c,
+ 0xb9a1, 0x06fa,
+ 0xbaa1, 0x0758,
+ 0xbba1, 0x07b6,
+ 0xbca1, 0x0814,
+ 0xbda1, 0x0872,
+ 0xbea1, 0x08d0,
+ 0xbfa1, 0x092e,
+ 0xc0a1, 0x098c,
+ 0xc1a1, 0x09ea,
+ 0xc2a1, 0x0a48,
+ 0xc3a1, 0x0aa6,
+ 0xc4a1, 0x0b04,
+ 0xc5a1, 0x0b62,
+ 0xc6a1, 0x0bc0,
+ 0xc7a1, 0x0c1e,
+ 0xc8a1, 0x0c7c,
+ 0xc9a1, 0x0cda,
+ 0xcaa1, 0x0d38,
+ 0xcba1, 0x0d96,
+ 0xcca1, 0x0df4,
+ 0xcda1, 0x0e52,
+ 0xcea1, 0x0eb0,
+ 0xcfa1, 0x0f0e,
+ 0xd0a1, 0x0f6c,
+ 0xd1a1, 0x0fca,
+ 0xd2a1, 0x1028,
+ 0xd3a1, 0x1086,
+ 0xd4a1, 0x10e4,
+ 0xd5a1, 0x1142,
+ 0xd6a1, 0x11a0,
+ 0xd7a1, 0x11fe,
+ 0xd8a1, 0x1257,
+ 0xd9a1, 0x12b5,
+ 0xdaa1, 0x1313,
+ 0xdba1, 0x1371,
+ 0xdca1, 0x13cf,
+ 0xdda1, 0x142d,
+ 0xdea1, 0x148b,
+ 0xdfa1, 0x14e9,
+ 0xe0a1, 0x1547,
+ 0xe1a1, 0x15a5,
+ 0xe2a1, 0x1603,
+ 0xe3a1, 0x1661,
+ 0xe4a1, 0x16bf,
+ 0xe5a1, 0x171d,
+ 0xe6a1, 0x177b,
+ 0xe7a1, 0x17d9,
+ 0xe8a1, 0x1837,
+ 0xe9a1, 0x1895,
+ 0xeaa1, 0x18f3,
+ 0xeba1, 0x1951,
+ 0xeca1, 0x19af,
+ 0xeda1, 0x1a0d,
+ 0xeea1, 0x1a6b,
+ 0xefa1, 0x1ac9,
+ 0xf0a1, 0x1b27,
+ 0xf1a1, 0x1b85,
+ 0xf2a1, 0x1be3,
+ 0xf3a1, 0x1c41,
+ 0xf4a1, 0x1c9f,
+ 0xf5a1, 0x1cfd,
+ 0xf6a1, 0x1d5b,
+ 0xf7a1, 0x1db9,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBpcEUCHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x1e20, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e21, 0x1e22, 0x1e23 },
+ gb12GBpcEUCHMap2, 90
+};
+
+static Gushort gb12GBpcEUCVMap2[220] = {
+ 0x0000, 0x0000,
+ 0xa1a1, 0x0060,
+ 0xa2b1, 0x00be,
+ 0xa2e5, 0x00f0,
+ 0xa2f1, 0x00fa,
+ 0xa3a1, 0x0106,
+ 0xa4a1, 0x0164,
+ 0xa5a1, 0x01b7,
+ 0xa6a1, 0x020d,
+ 0xa6c1, 0x0225,
+ 0xa7a1, 0x025a,
+ 0xa7d1, 0x027b,
+ 0xa8a1, 0x029c,
+ 0xa8c5, 0x02bc,
+ 0xa9a4, 0x02e2,
+ 0xaaa1, 0x032e,
+ 0xaba1, 0x038c,
+ 0xb0a1, 0x03ac,
+ 0xb1a1, 0x040a,
+ 0xb2a1, 0x0468,
+ 0xb3a1, 0x04c6,
+ 0xb4a1, 0x0524,
+ 0xb5a1, 0x0582,
+ 0xb6a1, 0x05e0,
+ 0xb7a1, 0x063e,
+ 0xb8a1, 0x069c,
+ 0xb9a1, 0x06fa,
+ 0xbaa1, 0x0758,
+ 0xbba1, 0x07b6,
+ 0xbca1, 0x0814,
+ 0xbda1, 0x0872,
+ 0xbea1, 0x08d0,
+ 0xbfa1, 0x092e,
+ 0xc0a1, 0x098c,
+ 0xc1a1, 0x09ea,
+ 0xc2a1, 0x0a48,
+ 0xc3a1, 0x0aa6,
+ 0xc4a1, 0x0b04,
+ 0xc5a1, 0x0b62,
+ 0xc6a1, 0x0bc0,
+ 0xc7a1, 0x0c1e,
+ 0xc8a1, 0x0c7c,
+ 0xc9a1, 0x0cda,
+ 0xcaa1, 0x0d38,
+ 0xcba1, 0x0d96,
+ 0xcca1, 0x0df4,
+ 0xcda1, 0x0e52,
+ 0xcea1, 0x0eb0,
+ 0xcfa1, 0x0f0e,
+ 0xd0a1, 0x0f6c,
+ 0xd1a1, 0x0fca,
+ 0xd2a1, 0x1028,
+ 0xd3a1, 0x1086,
+ 0xd4a1, 0x10e4,
+ 0xd5a1, 0x1142,
+ 0xd6a1, 0x11a0,
+ 0xd7a1, 0x11fe,
+ 0xd8a1, 0x1257,
+ 0xd9a1, 0x12b5,
+ 0xdaa1, 0x1313,
+ 0xdba1, 0x1371,
+ 0xdca1, 0x13cf,
+ 0xdda1, 0x142d,
+ 0xdea1, 0x148b,
+ 0xdfa1, 0x14e9,
+ 0xe0a1, 0x1547,
+ 0xe1a1, 0x15a5,
+ 0xe2a1, 0x1603,
+ 0xe3a1, 0x1661,
+ 0xe4a1, 0x16bf,
+ 0xe5a1, 0x171d,
+ 0xe6a1, 0x177b,
+ 0xe7a1, 0x17d9,
+ 0xe8a1, 0x1837,
+ 0xe9a1, 0x1895,
+ 0xeaa1, 0x18f3,
+ 0xeba1, 0x1951,
+ 0xeca1, 0x19af,
+ 0xeda1, 0x1a0d,
+ 0xeea1, 0x1a6b,
+ 0xefa1, 0x1ac9,
+ 0xf0a1, 0x1b27,
+ 0xf1a1, 0x1b85,
+ 0xf2a1, 0x1be3,
+ 0xf3a1, 0x1c41,
+ 0xf4a1, 0x1c9f,
+ 0xf5a1, 0x1cfd,
+ 0xf6a1, 0x1d5b,
+ 0xf7a1, 0x1db9,
+ 0xa1a2, 0x023f,
+ 0xa1a3, 0x023e,
+ 0xa1aa, 0x0256,
+ 0xa1ab, 0x1e18,
+ 0xa1ad, 0x0257,
+ 0xa1b2, 0x0246,
+ 0xa1fe, 0x1e1a,
+ 0xa3a1, 0x0242,
+ 0xa3a8, 0x0244,
+ 0xa3ac, 0x023d,
+ 0xa3ae, 0x1e1b,
+ 0xa3ba, 0x0240,
+ 0xa3bd, 0x1e1c,
+ 0xa3bf, 0x0243,
+ 0xa3db, 0x1e1d,
+ 0xa3dd, 0x1e1e,
+ 0xa3df, 0x0258,
+ 0xa3fb, 0x0254,
+ 0xa3fd, 0x0255,
+ 0xa3fe, 0x1e1f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12GBpcEUCVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x1e20, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e21, 0x1e22, 0x1e23 },
+ gb12GBpcEUCVMap2, 110
+};
+
+static Gushort gb12UniGBUCS2HMap2[26922] = {
+ 0x0000, 0x0000,
+ 0x0020, 0x0001,
+ 0x00a4, 0x00a7,
+ 0x00a7, 0x00ab,
+ 0x00a8, 0x0066,
+ 0x00b0, 0x00a2,
+ 0x00b1, 0x007f,
+ 0x00d7, 0x0080,
+ 0x00e0, 0x029f,
+ 0x00e1, 0x029d,
+ 0x00e8, 0x02a3,
+ 0x00e9, 0x02a1,
+ 0x00ea, 0x02b5,
+ 0x00ec, 0x02a7,
+ 0x00ed, 0x02a5,
+ 0x00f2, 0x02ab,
+ 0x00f3, 0x02a9,
+ 0x00f7, 0x0081,
+ 0x00f9, 0x02af,
+ 0x00fa, 0x02ad,
+ 0x00fc, 0x02b4,
+ 0x0101, 0x029c,
+ 0x0113, 0x02a0,
+ 0x011b, 0x02a2,
+ 0x012b, 0x02a4,
+ 0x014d, 0x02a8,
+ 0x016b, 0x02ac,
+ 0x01ce, 0x029e,
+ 0x01d0, 0x02a6,
+ 0x01d2, 0x02aa,
+ 0x01d4, 0x02ae,
+ 0x01d6, 0x02b0,
+ 0x01d8, 0x02b1,
+ 0x01da, 0x02b2,
+ 0x01dc, 0x02b3,
+ 0x02c7, 0x0065,
+ 0x02c9, 0x0064,
+ 0x02ca, 0x26b3,
+ 0x02d9, 0x26b5,
+ 0x0391, 0x020d,
+ 0x03a3, 0x021e,
+ 0x03b1, 0x0225,
+ 0x03c3, 0x0236,
+ 0x0401, 0x0260,
+ 0x0410, 0x025a,
+ 0x0416, 0x0261,
+ 0x0436, 0x0282,
+ 0x0451, 0x0281,
+ 0x1e3f, 0x02b7,
+ 0x2010, 0x2722,
+ 0x2013, 0x26b6,
+ 0x2014, 0x0069,
+ 0x2015, 0x26b7,
+ 0x2016, 0x006b,
+ 0x2018, 0x006d,
+ 0x201c, 0x006f,
+ 0x2025, 0x26b8,
+ 0x2026, 0x006c,
+ 0x2030, 0x00aa,
+ 0x2032, 0x00a3,
+ 0x2035, 0x26b9,
+ 0x203b, 0x00b8,
+ 0x2103, 0x00a5,
+ 0x2105, 0x26ba,
+ 0x2109, 0x26bb,
+ 0x2116, 0x00ac,
+ 0x2121, 0x2720,
+ 0x2160, 0x00fa,
+ 0x2170, 0x26a9,
+ 0x2190, 0x00ba,
+ 0x2192, 0x00b9,
+ 0x2193, 0x00bc,
+ 0x2196, 0x26bc,
+ 0x2208, 0x0089,
+ 0x220f, 0x0086,
+ 0x2211, 0x0085,
+ 0x2215, 0x26c0,
+ 0x221a, 0x008b,
+ 0x221d, 0x0097,
+ 0x221e, 0x009d,
+ 0x221f, 0x26c1,
+ 0x2220, 0x008e,
+ 0x2223, 0x26c2,
+ 0x2225, 0x008d,
+ 0x2227, 0x0083,
+ 0x2229, 0x0088,
+ 0x222a, 0x0087,
+ 0x222b, 0x0091,
+ 0x222e, 0x0092,
+ 0x2234, 0x009f,
+ 0x2235, 0x009e,
+ 0x2236, 0x0082,
+ 0x2237, 0x008a,
+ 0x223d, 0x0096,
+ 0x2248, 0x0095,
+ 0x224c, 0x0094,
+ 0x2252, 0x26c3,
+ 0x2260, 0x0098,
+ 0x2261, 0x0093,
+ 0x2264, 0x009b,
+ 0x2266, 0x26c4,
+ 0x226e, 0x0099,
+ 0x2295, 0x2704,
+ 0x2299, 0x0090,
+ 0x22a5, 0x008c,
+ 0x22bf, 0x26c6,
+ 0x22ef, 0x006c,
+ 0x2312, 0x008f,
+ 0x2460, 0x00e6,
+ 0x2474, 0x00d2,
+ 0x2488, 0x00be,
+ 0x2500, 0x02e2,
+ 0x2550, 0x26c7,
+ 0x2581, 0x26eb,
+ 0x2593, 0x26fa,
+ 0x25a0, 0x00b5,
+ 0x25a1, 0x00b4,
+ 0x25b2, 0x00b7,
+ 0x25b3, 0x00b6,
+ 0x25bc, 0x26fd,
+ 0x25c6, 0x00b3,
+ 0x25c7, 0x00b2,
+ 0x25cb, 0x00af,
+ 0x25ce, 0x00b1,
+ 0x25cf, 0x00b0,
+ 0x25e2, 0x26ff,
+ 0x2605, 0x00ae,
+ 0x2606, 0x00ad,
+ 0x2609, 0x2703,
+ 0x2640, 0x00a1,
+ 0x2642, 0x00a0,
+ 0x3000, 0x0060,
+ 0x3003, 0x0067,
+ 0x3005, 0x0068,
+ 0x3006, 0x2728,
+ 0x3007, 0x1e17,
+ 0x3008, 0x0073,
+ 0x3010, 0x007d,
+ 0x3012, 0x2705,
+ 0x3013, 0x00bd,
+ 0x3014, 0x0071,
+ 0x3016, 0x007b,
+ 0x301d, 0x2706,
+ 0x3021, 0x2708,
+ 0x3041, 0x0164,
+ 0x309b, 0x2724,
+ 0x309d, 0x2729,
+ 0x30a1, 0x01b7,
+ 0x30fb, 0x0063,
+ 0x30fc, 0x2723,
+ 0x30fd, 0x2726,
+ 0x3105, 0x02bc,
+ 0x3220, 0x00f0,
+ 0x3231, 0x2721,
+ 0x32a3, 0x2711,
+ 0x338e, 0x2712,
+ 0x339c, 0x2714,
+ 0x33a1, 0x2717,
+ 0x33c4, 0x2718,
+ 0x33ce, 0x2719,
+ 0x33d1, 0x271a,
+ 0x33d5, 0x271c,
+ 0x4e00, 0x1042,
+ 0x4e01, 0x05e0,
+ 0x4e02, 0x2758,
+ 0x4e03, 0x0bfe,
+ 0x4e04, 0x2759,
+ 0x4e07, 0x0ea3,
+ 0x4e08, 0x116a,
+ 0x4e09, 0x0cd8,
+ 0x4e0a, 0x0d08,
+ 0x4e0b, 0x0f2f,
+ 0x4e0c, 0x1258,
+ 0x4e0d, 0x0482,
+ 0x4e0e, 0x10d0,
+ 0x4e0f, 0x275c,
+ 0x4e10, 0x125a,
+ 0x4e11, 0x0518,
+ 0x4e12, 0x275d,
+ 0x4e13, 0x1205,
+ 0x4e14, 0x0c4f,
+ 0x4e15, 0x125d,
+ 0x4e16, 0x0d57,
+ 0x4e17, 0x275e,
+ 0x4e18, 0x0c6d,
+ 0x4e19, 0x0464,
+ 0x4e1a, 0x103c,
+ 0x4e1b, 0x0557,
+ 0x4e1c, 0x05ea,
+ 0x4e1d, 0x0db4,
+ 0x4e1e, 0x125f,
+ 0x4e1f, 0x275f,
+ 0x4e22, 0x05e9,
+ 0x4e23, 0x2762,
+ 0x4e24, 0x0a06,
+ 0x4e25, 0x0ff8,
+ 0x4e26, 0x2763,
+ 0x4e27, 0x0cde,
+ 0x4e28, 0x1263,
+ 0x4e29, 0x2764,
+ 0x4e2a, 0x06f1,
+ 0x4e2b, 0x0fe7,
+ 0x4e2c, 0x169c,
+ 0x4e2d, 0x11cf,
+ 0x4e2e, 0x2765,
+ 0x4e30, 0x067e,
+ 0x4e31, 0x2767,
+ 0x4e32, 0x0531,
+ 0x4e33, 0x2768,
+ 0x4e34, 0x0a22,
+ 0x4e35, 0x2769,
+ 0x4e36, 0x1272,
+ 0x4e37, 0x276a,
+ 0x4e38, 0x0e99,
+ 0x4e39, 0x0585,
+ 0x4e3a, 0x0eb9,
+ 0x4e3b, 0x11f6,
+ 0x4e3c, 0x276b,
+ 0x4e3d, 0x09e1,
+ 0x4e3e, 0x0908,
+ 0x4e3f, 0x1265,
+ 0x4e40, 0x276c,
+ 0x4e43, 0x0b2e,
+ 0x4e44, 0x276f,
+ 0x4e45, 0x08f2,
+ 0x4e46, 0x2770,
+ 0x4e47, 0x1267,
+ 0x4e48, 0x0ab9,
+ 0x4e49, 0x106c,
+ 0x4e4a, 0x2771,
+ 0x4e4b, 0x11ad,
+ 0x4e4c, 0x0ee9,
+ 0x4e4d, 0x1148,
+ 0x4e4e, 0x07ac,
+ 0x4e4f, 0x0643,
+ 0x4e50, 0x09c1,
+ 0x4e51, 0x2772,
+ 0x4e52, 0x0bd8,
+ 0x4e53, 0x0b93,
+ 0x4e54, 0x0c44,
+ 0x4e55, 0x2773,
+ 0x4e56, 0x072d,
+ 0x4e57, 0x2774,
+ 0x4e58, 0x04f0,
+ 0x4e59, 0x1059,
+ 0x4e5a, 0x2775,
+ 0x4e5c, 0x1275,
+ 0x4e5d, 0x08f4,
+ 0x4e5e, 0x0c11,
+ 0x4e5f, 0x1039,
+ 0x4e60, 0x0f1d,
+ 0x4e61, 0x0f54,
+ 0x4e62, 0x2777,
+ 0x4e66, 0x0d80,
+ 0x4e67, 0x277b,
+ 0x4e69, 0x1276,
+ 0x4e6a, 0x277d,
+ 0x4e70, 0x0a99,
+ 0x4e71, 0x0a79,
+ 0x4e72, 0x2783,
+ 0x4e73, 0x0cc4,
+ 0x4e74, 0x2784,
+ 0x4e7e, 0x0c29,
+ 0x4e7f, 0x278e,
+ 0x4e82, 0x2059,
+ 0x4e83, 0x2791,
+ 0x4e86, 0x0a14,
+ 0x4e87, 0x2794,
+ 0x4e88, 0x10cd,
+ 0x4e89, 0x119a,
+ 0x4e8a, 0x2795,
+ 0x4e8b, 0x0d59,
+ 0x4e8c, 0x063d,
+ 0x4e8d, 0x1257,
+ 0x4e8e, 0x10bf,
+ 0x4e8f, 0x0984,
+ 0x4e90, 0x2796,
+ 0x4e91, 0x1109,
+ 0x4e92, 0x07ba,
+ 0x4e93, 0x1277,
+ 0x4e94, 0x0ef4,
+ 0x4e95, 0x08dd,
+ 0x4e96, 0x2797,
+ 0x4e98, 0x125e,
+ 0x4e99, 0x2799,
+ 0x4e9a, 0x0ff0,
+ 0x4e9b, 0x0f74,
+ 0x4e9c, 0x279a,
+ 0x4e9e, 0x21f1,
+ 0x4e9f, 0x1273,
+ 0x4ea0, 0x1303,
+ 0x4ea1, 0x0ea7,
+ 0x4ea2, 0x0947,
+ 0x4ea3, 0x279c,
+ 0x4ea4, 0x088c,
+ 0x4ea5, 0x075c,
+ 0x4ea6, 0x1067,
+ 0x4ea7, 0x04c1,
+ 0x4ea8, 0x0797,
+ 0x4ea9, 0x0b19,
+ 0x4eaa, 0x279d,
+ 0x4eab, 0x0f5a,
+ 0x4eac, 0x08d8,
+ 0x4ead, 0x0e55,
+ 0x4eae, 0x0a0a,
+ 0x4eaf, 0x279e,
+ 0x4eb2, 0x0c54,
+ 0x4eb3, 0x1305,
+ 0x4eb4, 0x27a1,
+ 0x4eb5, 0x1308,
+ 0x4eb6, 0x27a2,
+ 0x4eba, 0x0ca6,
+ 0x4ebb, 0x129f,
+ 0x4ebc, 0x27a6,
+ 0x4ebf, 0x1061,
+ 0x4ec0, 0x0d49,
+ 0x4ec1, 0x0ca5,
+ 0x4ec2, 0x12a2,
+ 0x4ec3, 0x12a0,
+ 0x4ec4, 0x127c,
+ 0x4ec5, 0x08c7,
+ 0x4ec6, 0x0bec,
+ 0x4ec7, 0x0515,
+ 0x4ec8, 0x27a9,
+ 0x4ec9, 0x12a1,
+ 0x4eca, 0x08c2,
+ 0x4ecb, 0x08ba,
+ 0x4ecc, 0x27aa,
+ 0x4ecd, 0x0caf,
+ 0x4ece, 0x0556,
+ 0x4ecf, 0x27ab,
+ 0x4ed1, 0x0a7f,
+ 0x4ed2, 0x27ad,
+ 0x4ed3, 0x049d,
+ 0x4ed4, 0x122d,
+ 0x4ed5, 0x0d62,
+ 0x4ed6, 0x0df0,
+ 0x4ed7, 0x116d,
+ 0x4ed8, 0x06b1,
+ 0x4ed9, 0x0f36,
+ 0x4eda, 0x27ae,
+ 0x4edd, 0x12ee,
+ 0x4ede, 0x12a6,
+ 0x4edf, 0x0c27,
+ 0x4ee0, 0x27b1,
+ 0x4ee1, 0x12a4,
+ 0x4ee2, 0x27b2,
+ 0x4ee3, 0x057d,
+ 0x4ee4, 0x0a37,
+ 0x4ee5, 0x105b,
+ 0x4ee6, 0x27b3,
+ 0x4ee8, 0x12a3,
+ 0x4ee9, 0x27b5,
+ 0x4eea, 0x104e,
+ 0x4eeb, 0x12a5,
+ 0x4eec, 0x0acc,
+ 0x4eed, 0x27b6,
+ 0x4ef0, 0x101f,
+ 0x4ef1, 0x27b9,
+ 0x4ef2, 0x11d8,
+ 0x4ef3, 0x12a8,
+ 0x4ef4, 0x27ba,
+ 0x4ef5, 0x12ab,
+ 0x4ef6, 0x0871,
+ 0x4ef7, 0x084e,
+ 0x4ef8, 0x27bb,
+ 0x4efb, 0x0ca9,
+ 0x4efc, 0x27be,
+ 0x4efd, 0x067a,
+ 0x4efe, 0x27bf,
+ 0x4eff, 0x065f,
+ 0x4f00, 0x27c0,
+ 0x4f01, 0x0c12,
+ 0x4f02, 0x27c1,
+ 0x4f09, 0x12ae,
+ 0x4f0a, 0x1048,
+ 0x4f0b, 0x27c8,
+ 0x4f0d, 0x0ef8,
+ 0x4f0e, 0x0832,
+ 0x4f0f, 0x0699,
+ 0x4f10, 0x0642,
+ 0x4f11, 0x0fa8,
+ 0x4f12, 0x27ca,
+ 0x4f17, 0x11d9,
+ 0x4f18, 0x10aa,
+ 0x4f19, 0x0804,
+ 0x4f1a, 0x07f6,
+ 0x4f1b, 0x12a7,
+ 0x4f1c, 0x27cf,
+ 0x4f1e, 0x0cda,
+ 0x4f1f, 0x0ebf,
+ 0x4f20, 0x052e,
+ 0x4f21, 0x27d1,
+ 0x4f22, 0x12a9,
+ 0x4f23, 0x27d2,
+ 0x4f24, 0x0d04,
+ 0x4f25, 0x12ac,
+ 0x4f26, 0x0a7e,
+ 0x4f27, 0x12ad,
+ 0x4f28, 0x27d3,
+ 0x4f2a, 0x0ec0,
+ 0x4f2b, 0x12af,
+ 0x4f2c, 0x27d5,
+ 0x4f2f, 0x0475,
+ 0x4f30, 0x0719,
+ 0x4f31, 0x27d8,
+ 0x4f32, 0x12b7,
+ 0x4f33, 0x27d9,
+ 0x4f34, 0x03f4,
+ 0x4f35, 0x27da,
+ 0x4f36, 0x0a2f,
+ 0x4f37, 0x27db,
+ 0x4f38, 0x0d25,
+ 0x4f39, 0x27dc,
+ 0x4f3a, 0x0dba,
+ 0x4f3b, 0x27dd,
+ 0x4f3c, 0x0dbb,
+ 0x4f3d, 0x12b8,
+ 0x4f3e, 0x27de,
+ 0x4f43, 0x05c9,
+ 0x4f44, 0x27e3,
+ 0x4f46, 0x058c,
+ 0x4f47, 0x27e5,
+ 0x4f4d, 0x0eca,
+ 0x4f4e, 0x05ae,
+ 0x4f4f, 0x11fe,
+ 0x4f50, 0x1251,
+ 0x4f51, 0x10b8,
+ 0x4f52, 0x27eb,
+ 0x4f53, 0x0e38,
+ 0x4f54, 0x27ec,
+ 0x4f55, 0x0785,
+ 0x4f56, 0x27ed,
+ 0x4f57, 0x12b6,
+ 0x4f58, 0x12f0,
+ 0x4f59, 0x10c5,
+ 0x4f5a, 0x12b3,
+ 0x4f5b, 0x068d,
+ 0x4f5c, 0x1254,
+ 0x4f5d, 0x12b4,
+ 0x4f5e, 0x12b0,
+ 0x4f5f, 0x12b5,
+ 0x4f60, 0x0b46,
+ 0x4f61, 0x27ee,
+ 0x4f63, 0x109b,
+ 0x4f64, 0x12aa,
+ 0x4f65, 0x12f1,
+ 0x4f66, 0x27f0,
+ 0x4f67, 0x12b1,
+ 0x4f68, 0x27f1,
+ 0x4f69, 0x0ba6,
+ 0x4f6a, 0x27f2,
+ 0x4f6c, 0x09bb,
+ 0x4f6d, 0x27f4,
+ 0x4f6f, 0x1019,
+ 0x4f70, 0x03e6,
+ 0x4f71, 0x27f6,
+ 0x4f73, 0x0844,
+ 0x4f74, 0x12ba,
+ 0x4f75, 0x27f8,
+ 0x4f76, 0x12b9,
+ 0x4f77, 0x27f9,
+ 0x4f7b, 0x12c0,
+ 0x4f7c, 0x12c2,
+ 0x4f7d, 0x27fd,
+ 0x4f7e, 0x12bf,
+ 0x4f7f, 0x0d50,
+ 0x4f80, 0x27fe,
+ 0x4f83, 0x12bd,
+ 0x4f84, 0x11b5,
+ 0x4f85, 0x2801,
+ 0x4f86, 0x1ff2,
+ 0x4f87, 0x2802,
+ 0x4f88, 0x0503,
+ 0x4f89, 0x12bc,
+ 0x4f8a, 0x2803,
+ 0x4f8b, 0x09e8,
+ 0x4f8c, 0x2804,
+ 0x4f8d, 0x0d63,
+ 0x4f8e, 0x2805,
+ 0x4f8f, 0x12be,
+ 0x4f90, 0x2806,
+ 0x4f91, 0x12bb,
+ 0x4f92, 0x2807,
+ 0x4f94, 0x12c4,
+ 0x4f95, 0x2809,
+ 0x4f96, 0x205d,
+ 0x4f97, 0x05f0,
+ 0x4f98, 0x280a,
+ 0x4f9b, 0x0702,
+ 0x4f9c, 0x280d,
+ 0x4f9d, 0x1047,
+ 0x4f9e, 0x280e,
+ 0x4fa0, 0x0f2d,
+ 0x4fa1, 0x2810,
+ 0x4fa3, 0x0a69,
+ 0x4fa4, 0x2812,
+ 0x4fa5, 0x0895,
+ 0x4fa6, 0x118d,
+ 0x4fa7, 0x04a7,
+ 0x4fa8, 0x0c45,
+ 0x4fa9, 0x0978,
+ 0x4faa, 0x12c1,
+ 0x4fab, 0x2813,
+ 0x4fac, 0x12c3,
+ 0x4fad, 0x2814,
+ 0x4fae, 0x0ef9,
+ 0x4faf, 0x07a5,
+ 0x4fb0, 0x2815,
+ 0x4fb5, 0x0c53,
+ 0x4fb6, 0x281a,
+ 0x4fbf, 0x044c,
+ 0x4fc0, 0x2823,
+ 0x4fc2, 0x269c,
+ 0x4fc3, 0x055c,
+ 0x4fc4, 0x062c,
+ 0x4fc5, 0x12c8,
+ 0x4fc6, 0x2825,
+ 0x4fca, 0x092e,
+ 0x4fcb, 0x2829,
+ 0x4fce, 0x12f2,
+ 0x4fcf, 0x0c4b,
+ 0x4fd0, 0x09e9,
+ 0x4fd1, 0x12cc,
+ 0x4fd2, 0x282c,
+ 0x4fd7, 0x0dcc,
+ 0x4fd8, 0x069a,
+ 0x4fd9, 0x2831,
+ 0x4fda, 0x12c9,
+ 0x4fdb, 0x2832,
+ 0x4fdc, 0x12cb,
+ 0x4fdd, 0x040c,
+ 0x4fde, 0x10c6,
+ 0x4fdf, 0x12cd,
+ 0x4fe0, 0x21b5,
+ 0x4fe1, 0x0f90,
+ 0x4fe2, 0x2833,
+ 0x4fe3, 0x12ca,
+ 0x4fe4, 0x2834,
+ 0x4fe6, 0x12c5,
+ 0x4fe7, 0x2836,
+ 0x4fe8, 0x12c6,
+ 0x4fe9, 0x09f2,
+ 0x4fea, 0x12c7,
+ 0x4feb, 0x2837,
+ 0x4fed, 0x0866,
+ 0x4fee, 0x0fa9,
+ 0x4fef, 0x06a4,
+ 0x4ff0, 0x2839,
+ 0x4ff1, 0x0912,
+ 0x4ff2, 0x283a,
+ 0x4ff3, 0x12d1,
+ 0x4ff4, 0x283b,
+ 0x4ff8, 0x12ce,
+ 0x4ff9, 0x283f,
+ 0x4ffa, 0x03be,
+ 0x4ffb, 0x2840,
+ 0x4ffe, 0x12d6,
+ 0x4fff, 0x2843,
+ 0x5000, 0x22cc,
+ 0x5001, 0x2844,
+ 0x5006, 0x2016,
+ 0x5007, 0x2849,
+ 0x5009, 0x1e62,
+ 0x500a, 0x284b,
+ 0x500b, 0x1f20,
+ 0x500c, 0x12d8,
+ 0x500d, 0x041f,
+ 0x500e, 0x284c,
+ 0x500f, 0x12d3,
+ 0x5010, 0x284d,
+ 0x5011, 0x207f,
+ 0x5012, 0x059a,
+ 0x5013, 0x284e,
+ 0x5014, 0x0922,
+ 0x5015, 0x284f,
+ 0x5018, 0x0e1b,
+ 0x5019, 0x07a9,
+ 0x501a, 0x1057,
+ 0x501b, 0x2852,
+ 0x501c, 0x12d7,
+ 0x501d, 0x2853,
+ 0x501f, 0x08b9,
+ 0x5020, 0x2855,
+ 0x5021, 0x04d0,
+ 0x5022, 0x2856,
+ 0x5025, 0x12d9,
+ 0x5026, 0x091a,
+ 0x5027, 0x2859,
+ 0x5028, 0x12da,
+ 0x5029, 0x12cf,
+ 0x502a, 0x0b42,
+ 0x502b, 0x205c,
+ 0x502c, 0x12d2,
+ 0x502d, 0x12d5,
+ 0x502e, 0x12d4,
+ 0x502f, 0x285a,
+ 0x503a, 0x114f,
+ 0x503b, 0x2865,
+ 0x503c, 0x11b4,
+ 0x503d, 0x2866,
+ 0x503e, 0x0c60,
+ 0x503f, 0x2867,
+ 0x5043, 0x12dc,
+ 0x5044, 0x286b,
+ 0x5047, 0x084c,
+ 0x5048, 0x12de,
+ 0x5049, 0x2194,
+ 0x504a, 0x286e,
+ 0x504c, 0x12d0,
+ 0x504d, 0x2870,
+ 0x504e, 0x12df,
+ 0x504f, 0x0bca,
+ 0x5050, 0x2871,
+ 0x5055, 0x12dd,
+ 0x5056, 0x2876,
+ 0x505a, 0x1253,
+ 0x505b, 0x287a,
+ 0x505c, 0x0e54,
+ 0x505d, 0x287b,
+ 0x5065, 0x0872,
+ 0x5066, 0x2883,
+ 0x506c, 0x12e0,
+ 0x506d, 0x2889,
+ 0x5074, 0x1e65,
+ 0x5075, 0x2281,
+ 0x5076, 0x0b7d,
+ 0x5077, 0x0e66,
+ 0x5078, 0x2890,
+ 0x507b, 0x12e1,
+ 0x507c, 0x2893,
+ 0x507e, 0x12db,
+ 0x507f, 0x04ca,
+ 0x5080, 0x098b,
+ 0x5081, 0x2895,
+ 0x5085, 0x06b0,
+ 0x5086, 0x2899,
+ 0x5088, 0x09e7,
+ 0x5089, 0x289b,
+ 0x508d, 0x0403,
+ 0x508e, 0x289f,
+ 0x5096, 0x22cd,
+ 0x5097, 0x28a7,
+ 0x5098, 0x210a,
+ 0x5099, 0x1e3e,
+ 0x509a, 0x28a8,
+ 0x50a2, 0x267f,
+ 0x50a3, 0x0579,
+ 0x50a4, 0x28b0,
+ 0x50a5, 0x12e2,
+ 0x50a6, 0x28b1,
+ 0x50a7, 0x12e3,
+ 0x50a8, 0x0525,
+ 0x50a9, 0x12e4,
+ 0x50aa, 0x28b2,
+ 0x50ac, 0x0562,
+ 0x50ad, 0x222e,
+ 0x50ae, 0x28b4,
+ 0x50b2, 0x03cc,
+ 0x50b3, 0x1e96,
+ 0x50b4, 0x22cb,
+ 0x50b5, 0x226c,
+ 0x50b6, 0x28b8,
+ 0x50b7, 0x2117,
+ 0x50b8, 0x28b9,
+ 0x50ba, 0x12e5,
+ 0x50bb, 0x0cee,
+ 0x50bc, 0x28bb,
+ 0x50be, 0x20e8,
+ 0x50bf, 0x28bd,
+ 0x50c2, 0x22d4,
+ 0x50c3, 0x28c0,
+ 0x50c5, 0x1fb9,
+ 0x50c6, 0x28c2,
+ 0x50c9, 0x22d8,
+ 0x50ca, 0x28c5,
+ 0x50cf, 0x0f5e,
+ 0x50d0, 0x28ca,
+ 0x50d1, 0x20df,
+ 0x50d2, 0x28cb,
+ 0x50d5, 0x20c2,
+ 0x50d6, 0x12e6,
+ 0x50d7, 0x28ce,
+ 0x50da, 0x0a0e,
+ 0x50db, 0x28d1,
+ 0x50de, 0x2195,
+ 0x50df, 0x28d4,
+ 0x50e5, 0x1fac,
+ 0x50e6, 0x12ea,
+ 0x50e7, 0x0ce7,
+ 0x50e8, 0x22d3,
+ 0x50e9, 0x28da,
+ 0x50ec, 0x12e9,
+ 0x50ed, 0x12e8,
+ 0x50ee, 0x12eb,
+ 0x50ef, 0x28dd,
+ 0x50f3, 0x0dd0,
+ 0x50f4, 0x28e1,
+ 0x50f5, 0x087a,
+ 0x50f6, 0x28e2,
+ 0x50f9, 0x1f81,
+ 0x50fa, 0x28e5,
+ 0x50fb, 0x0bc6,
+ 0x50fc, 0x28e6,
+ 0x5100, 0x2210,
+ 0x5101, 0x28ea,
+ 0x5102, 0x22cf,
+ 0x5103, 0x28eb,
+ 0x5104, 0x2213,
+ 0x5105, 0x28ec,
+ 0x5106, 0x12e7,
+ 0x5107, 0x12ec,
+ 0x5108, 0x1fe4,
+ 0x5109, 0x1f90,
+ 0x510a, 0x28ed,
+ 0x510b, 0x12ed,
+ 0x510c, 0x28ee,
+ 0x5110, 0x22d6,
+ 0x5111, 0x28f2,
+ 0x5112, 0x0cc0,
+ 0x5113, 0x28f3,
+ 0x5114, 0x22d0,
+ 0x5115, 0x22ce,
+ 0x5116, 0x28f4,
+ 0x5118, 0x2681,
+ 0x5119, 0x28f6,
+ 0x511f, 0x1e76,
+ 0x5120, 0x28fc,
+ 0x5121, 0x09c7,
+ 0x5122, 0x28fd,
+ 0x512a, 0x2231,
+ 0x512b, 0x2905,
+ 0x5132, 0x1e93,
+ 0x5133, 0x290c,
+ 0x5137, 0x22d2,
+ 0x5138, 0x2910,
+ 0x513a, 0x22d7,
+ 0x513b, 0x22d5,
+ 0x513c, 0x22d1,
+ 0x513d, 0x2912,
+ 0x513f, 0x0638,
+ 0x5140, 0x1259,
+ 0x5141, 0x110d,
+ 0x5142, 0x2914,
+ 0x5143, 0x10ed,
+ 0x5144, 0x0fa1,
+ 0x5145, 0x0509,
+ 0x5146, 0x1178,
+ 0x5147, 0x2915,
+ 0x5148, 0x0f35,
+ 0x5149, 0x073b,
+ 0x514a, 0x2916,
+ 0x514b, 0x0958,
+ 0x514c, 0x2917,
+ 0x514d, 0x0ae7,
+ 0x514e, 0x2918,
+ 0x5151, 0x0611,
+ 0x5152, 0x1ee5,
+ 0x5153, 0x291b,
+ 0x5154, 0x0e74,
+ 0x5155, 0x1302,
+ 0x5156, 0x1304,
+ 0x5157, 0x291c,
+ 0x515a, 0x0594,
+ 0x515b, 0x291f,
+ 0x515c, 0x05f4,
+ 0x515d, 0x2920,
+ 0x5162, 0x08d3,
+ 0x5163, 0x2925,
+ 0x5165, 0x0cc6,
+ 0x5166, 0x2927,
+ 0x5168, 0x0c86,
+ 0x5169, 0x2025,
+ 0x516a, 0x2929,
+ 0x516b, 0x03d6,
+ 0x516c, 0x0704,
+ 0x516d, 0x0a42,
+ 0x516e, 0x12f6,
+ 0x516f, 0x292a,
+ 0x5170, 0x09a7,
+ 0x5171, 0x070b,
+ 0x5172, 0x292b,
+ 0x5173, 0x0731,
+ 0x5174, 0x0f96,
+ 0x5175, 0x0461,
+ 0x5176, 0x0c03,
+ 0x5177, 0x090e,
+ 0x5178, 0x05c5,
+ 0x5179, 0x1225,
+ 0x517a, 0x292c,
+ 0x517b, 0x1021,
+ 0x517c, 0x0859,
+ 0x517d, 0x0d75,
+ 0x517e, 0x292d,
+ 0x5180, 0x0830,
+ 0x5181, 0x12fa,
+ 0x5182, 0x129d,
+ 0x5183, 0x292f,
+ 0x5185, 0x0b3d,
+ 0x5186, 0x2931,
+ 0x5188, 0x06cf,
+ 0x5189, 0x0c98,
+ 0x518a, 0x2933,
+ 0x518c, 0x04a8,
+ 0x518d, 0x111c,
+ 0x518e, 0x2935,
+ 0x5192, 0x0ab5,
+ 0x5193, 0x2939,
+ 0x5195, 0x0ae6,
+ 0x5196, 0x1314,
+ 0x5197, 0x0cba,
+ 0x5198, 0x293b,
+ 0x5199, 0x0f7f,
+ 0x519a, 0x293c,
+ 0x519b, 0x092b,
+ 0x519c, 0x0b6a,
+ 0x519d, 0x293d,
+ 0x51a0, 0x0733,
+ 0x51a1, 0x2940,
+ 0x51a2, 0x1315,
+ 0x51a3, 0x2941,
+ 0x51a4, 0x10ec,
+ 0x51a5, 0x1316,
+ 0x51a6, 0x2942,
+ 0x51ab, 0x130f,
+ 0x51ac, 0x05eb,
+ 0x51ad, 0x2947,
+ 0x51af, 0x0688,
+ 0x51b0, 0x0462,
+ 0x51b1, 0x1310,
+ 0x51b2, 0x050a,
+ 0x51b3, 0x0925,
+ 0x51b4, 0x2949,
+ 0x51b5, 0x0983,
+ 0x51b6, 0x1038,
+ 0x51b7, 0x09cf,
+ 0x51b8, 0x294a,
+ 0x51bb, 0x05f2,
+ 0x51bc, 0x1312,
+ 0x51bd, 0x1311,
+ 0x51be, 0x294d,
+ 0x51c0, 0x08ea,
+ 0x51c1, 0x294f,
+ 0x51c4, 0x0bff,
+ 0x51c5, 0x2952,
+ 0x51c6, 0x1219,
+ 0x51c7, 0x1313,
+ 0x51c8, 0x2953,
+ 0x51c9, 0x0a02,
+ 0x51ca, 0x2954,
+ 0x51cb, 0x05d3,
+ 0x51cc, 0x0a31,
+ 0x51cd, 0x1ecf,
+ 0x51ce, 0x2955,
+ 0x51cf, 0x0868,
+ 0x51d0, 0x2956,
+ 0x51d1, 0x0558,
+ 0x51d2, 0x2957,
+ 0x51db, 0x0a26,
+ 0x51dc, 0x2960,
+ 0x51dd, 0x0b60,
+ 0x51de, 0x2961,
+ 0x51e0, 0x082b,
+ 0x51e1, 0x064f,
+ 0x51e2, 0x2963,
+ 0x51e4, 0x068c,
+ 0x51e5, 0x2965,
+ 0x51eb, 0x1300,
+ 0x51ec, 0x296b,
+ 0x51ed, 0x0bdd,
+ 0x51ee, 0x296c,
+ 0x51ef, 0x093a,
+ 0x51f0, 0x07e0,
+ 0x51f1, 0x1fd9,
+ 0x51f2, 0x296d,
+ 0x51f3, 0x05ab,
+ 0x51f4, 0x296e,
+ 0x51f5, 0x1399,
+ 0x51f6, 0x0fa2,
+ 0x51f7, 0x296f,
+ 0x51f8, 0x0e6a,
+ 0x51f9, 0x03c7,
+ 0x51fa, 0x051b,
+ 0x51fb, 0x080c,
+ 0x51fc, 0x139a,
+ 0x51fd, 0x0766,
+ 0x51fe, 0x2970,
+ 0x51ff, 0x1127,
+ 0x5200, 0x0597,
+ 0x5201, 0x05d4,
+ 0x5202, 0x128c,
+ 0x5203, 0x0cab,
+ 0x5204, 0x2971,
+ 0x5206, 0x0673,
+ 0x5207, 0x0c4d,
+ 0x5208, 0x128d,
+ 0x5209, 0x2973,
+ 0x520a, 0x093c,
+ 0x520b, 0x2974,
+ 0x520d, 0x138b,
+ 0x520e, 0x128e,
+ 0x520f, 0x2976,
+ 0x5211, 0x0f97,
+ 0x5212, 0x07c3,
+ 0x5213, 0x2978,
+ 0x5216, 0x196e,
+ 0x5217, 0x0a19,
+ 0x5218, 0x0a3e,
+ 0x5219, 0x1135,
+ 0x521a, 0x06d0,
+ 0x521b, 0x0537,
+ 0x521c, 0x297b,
+ 0x521d, 0x051a,
+ 0x521e, 0x297c,
+ 0x5220, 0x0cf7,
+ 0x5221, 0x297e,
+ 0x5224, 0x0b91,
+ 0x5225, 0x2981,
+ 0x5228, 0x0b9a,
+ 0x5229, 0x09e6,
+ 0x522a, 0x2984,
+ 0x522b, 0x0459,
+ 0x522c, 0x2985,
+ 0x522d, 0x128f,
+ 0x522e, 0x0727,
+ 0x522f, 0x2986,
+ 0x5230, 0x059e,
+ 0x5231, 0x2987,
+ 0x5233, 0x1290,
+ 0x5234, 0x2989,
+ 0x5236, 0x11c5,
+ 0x5237, 0x0d97,
+ 0x5238, 0x0c8a,
+ 0x5239, 0x0ceb,
+ 0x523a, 0x054f,
+ 0x523b, 0x0959,
+ 0x523c, 0x298b,
+ 0x523d, 0x074d,
+ 0x523e, 0x298c,
+ 0x523f, 0x1291,
+ 0x5241, 0x0626,
+ 0x5242, 0x0834,
+ 0x5243, 0x0e3d,
+ 0x5244, 0x22c8,
+ 0x5245, 0x298d,
+ 0x5247, 0x2263,
+ 0x5248, 0x298f,
+ 0x524a, 0x0f64,
+ 0x524b, 0x2683,
+ 0x524c, 0x1293,
+ 0x524d, 0x0c2d,
+ 0x524e, 0x2991,
+ 0x5250, 0x0729,
+ 0x5251, 0x0874,
+ 0x5252, 0x2993,
+ 0x5254, 0x0e31,
+ 0x5255, 0x2995,
+ 0x5256, 0x0be9,
+ 0x5257, 0x2996,
+ 0x525b, 0x1f17,
+ 0x525c, 0x1296,
+ 0x525d, 0x299a,
+ 0x525e, 0x1294,
+ 0x525f, 0x299b,
+ 0x5261, 0x1295,
+ 0x5262, 0x299d,
+ 0x5265, 0x0409,
+ 0x5266, 0x29a0,
+ 0x5267, 0x0916,
+ 0x5268, 0x29a1,
+ 0x5269, 0x0d3a,
+ 0x526a, 0x0867,
+ 0x526b, 0x29a2,
+ 0x526e, 0x1f2b,
+ 0x526f, 0x06ac,
+ 0x5270, 0x29a5,
+ 0x5272, 0x06e9,
+ 0x5273, 0x29a7,
+ 0x5274, 0x22ca,
+ 0x5275, 0x1e99,
+ 0x5276, 0x29a8,
+ 0x527d, 0x1298,
+ 0x527e, 0x29af,
+ 0x527f, 0x089c,
+ 0x5280, 0x29b0,
+ 0x5281, 0x129a,
+ 0x5282, 0x1299,
+ 0x5283, 0x1f4f,
+ 0x5284, 0x29b1,
+ 0x5287, 0x1fcf,
+ 0x5288, 0x0bbd,
+ 0x5289, 0x2036,
+ 0x528a, 0x1f3a,
+ 0x528b, 0x29b4,
+ 0x528c, 0x22c9,
+ 0x528d, 0x1f99,
+ 0x528e, 0x29b5,
+ 0x5290, 0x129b,
+ 0x5291, 0x1f75,
+ 0x5292, 0x29b7,
+ 0x5293, 0x129c,
+ 0x5294, 0x29b8,
+ 0x529b, 0x09ef,
+ 0x529c, 0x29bf,
+ 0x529d, 0x0c8b,
+ 0x529e, 0x03f7,
+ 0x529f, 0x06ff,
+ 0x52a0, 0x0846,
+ 0x52a1, 0x0f00,
+ 0x52a2, 0x138d,
+ 0x52a3, 0x0a1c,
+ 0x52a4, 0x29c0,
+ 0x52a8, 0x05ee,
+ 0x52a9, 0x11f9,
+ 0x52aa, 0x0b6d,
+ 0x52ab, 0x08aa,
+ 0x52ac, 0x138e,
+ 0x52ae, 0x29c4,
+ 0x52b1, 0x09e3,
+ 0x52b2, 0x08d1,
+ 0x52b3, 0x09b8,
+ 0x52b4, 0x29c7,
+ 0x52be, 0x1390,
+ 0x52bf, 0x0d5d,
+ 0x52c0, 0x29d1,
+ 0x52c1, 0x1fbe,
+ 0x52c2, 0x29d2,
+ 0x52c3, 0x0471,
+ 0x52c4, 0x29d3,
+ 0x52c7, 0x10a7,
+ 0x52c8, 0x29d6,
+ 0x52c9, 0x0ae8,
+ 0x52ca, 0x29d7,
+ 0x52cb, 0x0fd4,
+ 0x52cc, 0x29d8,
+ 0x52d0, 0x1392,
+ 0x52d1, 0x29dc,
+ 0x52d2, 0x09c0,
+ 0x52d3, 0x29dd,
+ 0x52d5, 0x1ecd,
+ 0x52d6, 0x1393,
+ 0x52d7, 0x29df,
+ 0x52d8, 0x093e,
+ 0x52d9, 0x21a9,
+ 0x52da, 0x29e0,
+ 0x52db, 0x21e6,
+ 0x52dc, 0x29e1,
+ 0x52dd, 0x2127,
+ 0x52de, 0x2003,
+ 0x52df, 0x0b1f,
+ 0x52e0, 0x29e2,
+ 0x52e2, 0x2132,
+ 0x52e3, 0x29e4,
+ 0x52e4, 0x0c57,
+ 0x52e5, 0x29e5,
+ 0x52f0, 0x1394,
+ 0x52f1, 0x2323,
+ 0x52f2, 0x29f0,
+ 0x52f5, 0x2011,
+ 0x52f6, 0x29f3,
+ 0x52f8, 0x20f5,
+ 0x52f9, 0x12fc,
+ 0x52fa, 0x0d10,
+ 0x52fb, 0x29f5,
+ 0x52fe, 0x070d,
+ 0x52ff, 0x0eff,
+ 0x5300, 0x110b,
+ 0x5301, 0x29f8,
+ 0x5305, 0x0407,
+ 0x5306, 0x0555,
+ 0x5307, 0x29fc,
+ 0x5308, 0x0fa4,
+ 0x5309, 0x29fd,
+ 0x530d, 0x12fd,
+ 0x530e, 0x2a01,
+ 0x530f, 0x14b5,
+ 0x5310, 0x12ff,
+ 0x5311, 0x2a02,
+ 0x5315, 0x1266,
+ 0x5316, 0x07c4,
+ 0x5317, 0x041a,
+ 0x5318, 0x2a06,
+ 0x5319, 0x04fc,
+ 0x531a, 0x1284,
+ 0x531b, 0x2a07,
+ 0x531d, 0x1114,
+ 0x531e, 0x2a09,
+ 0x5320, 0x0884,
+ 0x5321, 0x097c,
+ 0x5322, 0x2a0b,
+ 0x5323, 0x0f28,
+ 0x5324, 0x2a0c,
+ 0x5326, 0x1286,
+ 0x5327, 0x2a0e,
+ 0x532a, 0x0668,
+ 0x532b, 0x2a11,
+ 0x532d, 0x22c5,
+ 0x532e, 0x1287,
+ 0x532f, 0x1f5e,
+ 0x5330, 0x2a13,
+ 0x5331, 0x22c6,
+ 0x5332, 0x2a14,
+ 0x5339, 0x0bc4,
+ 0x533a, 0x0c75,
+ 0x533b, 0x1044,
+ 0x533c, 0x2a1b,
+ 0x533e, 0x1288,
+ 0x533f, 0x0b47,
+ 0x5340, 0x20ef,
+ 0x5341, 0x0d45,
+ 0x5342, 0x2a1d,
+ 0x5343, 0x0c24,
+ 0x5344, 0x2a1e,
+ 0x5345, 0x125c,
+ 0x5346, 0x2a1f,
+ 0x5347, 0x0d36,
+ 0x5348, 0x0ef6,
+ 0x5349, 0x07f1,
+ 0x534a, 0x03f6,
+ 0x534b, 0x2a20,
+ 0x534e, 0x07bf,
+ 0x534f, 0x0f78,
+ 0x5350, 0x2a23,
+ 0x5351, 0x0419,
+ 0x5352, 0x1241,
+ 0x5353, 0x121c,
+ 0x5354, 0x21d0,
+ 0x5355, 0x0586,
+ 0x5356, 0x0a9b,
+ 0x5357, 0x0b32,
+ 0x5358, 0x2a24,
+ 0x535a, 0x0470,
+ 0x535b, 0x2a26,
+ 0x535c, 0x047e,
+ 0x535d, 0x2a27,
+ 0x535e, 0x044e,
+ 0x535f, 0x14fa,
+ 0x5360, 0x115d,
+ 0x5361, 0x0935,
+ 0x5362, 0x0a53,
+ 0x5363, 0x128b,
+ 0x5364, 0x0a58,
+ 0x5365, 0x2a28,
+ 0x5366, 0x128a,
+ 0x5367, 0x0ee3,
+ 0x5368, 0x2a29,
+ 0x5369, 0x1352,
+ 0x536a, 0x2a2a,
+ 0x536b, 0x0ecf,
+ 0x536c, 0x2a2b,
+ 0x536e, 0x126a,
+ 0x536f, 0x0ab3,
+ 0x5370, 0x1086,
+ 0x5371, 0x0eb2,
+ 0x5372, 0x2a2d,
+ 0x5373, 0x0827,
+ 0x5374, 0x0c8f,
+ 0x5375, 0x0a78,
+ 0x5376, 0x2a2e,
+ 0x5377, 0x091c,
+ 0x5378, 0x0f81,
+ 0x5379, 0x2a2f,
+ 0x537a, 0x1353,
+ 0x537b, 0x2a30,
+ 0x537f, 0x0c61,
+ 0x5380, 0x2a34,
+ 0x5382, 0x04cc,
+ 0x5383, 0x2a36,
+ 0x5384, 0x0631,
+ 0x5385, 0x0e4f,
+ 0x5386, 0x09e5,
+ 0x5387, 0x2a37,
+ 0x5389, 0x09e2,
+ 0x538a, 0x2a39,
+ 0x538b, 0x0fe2,
+ 0x538c, 0x100a,
+ 0x538d, 0x127d,
+ 0x538e, 0x2a3a,
+ 0x5395, 0x04a5,
+ 0x5396, 0x2a41,
+ 0x5398, 0x09d0,
+ 0x5399, 0x22c1,
+ 0x539a, 0x07a8,
+ 0x539b, 0x2a43,
+ 0x539d, 0x127e,
+ 0x539e, 0x2a45,
+ 0x539f, 0x10f0,
+ 0x53a0, 0x1e64,
+ 0x53a1, 0x2a46,
+ 0x53a2, 0x0f4e,
+ 0x53a3, 0x127f,
+ 0x53a4, 0x2a47,
+ 0x53a5, 0x1280,
+ 0x53a6, 0x0f30,
+ 0x53a7, 0x2a48,
+ 0x53a8, 0x051d,
+ 0x53a9, 0x08f6,
+ 0x53aa, 0x2a49,
+ 0x53ad, 0x21f9,
+ 0x53ae, 0x1281,
+ 0x53af, 0x2a4c,
+ 0x53b2, 0x2010,
+ 0x53b3, 0x2a4f,
+ 0x53b4, 0x22c2,
+ 0x53b5, 0x2a50,
+ 0x53b6, 0x139c,
+ 0x53b7, 0x2a51,
+ 0x53bb, 0x0c80,
+ 0x53bc, 0x2a55,
+ 0x53bf, 0x0f45,
+ 0x53c0, 0x2a58,
+ 0x53c1, 0x0cd9,
+ 0x53c2, 0x0495,
+ 0x53c3, 0x1e5a,
+ 0x53c4, 0x2a59,
+ 0x53c8, 0x10bb,
+ 0x53c9, 0x04ad,
+ 0x53ca, 0x0823,
+ 0x53cb, 0x10b6,
+ 0x53cc, 0x0da0,
+ 0x53cd, 0x0651,
+ 0x53ce, 0x2a5d,
+ 0x53d1, 0x063f,
+ 0x53d2, 0x2a60,
+ 0x53d4, 0x0d7c,
+ 0x53d5, 0x2a62,
+ 0x53d6, 0x0c7c,
+ 0x53d7, 0x0d73,
+ 0x53d8, 0x044d,
+ 0x53d9, 0x0fbb,
+ 0x53da, 0x2a63,
+ 0x53db, 0x0b92,
+ 0x53dc, 0x2a64,
+ 0x53df, 0x1395,
+ 0x53e0, 0x05df,
+ 0x53e1, 0x2a67,
+ 0x53e2, 0x1ea2,
+ 0x53e3, 0x0967,
+ 0x53e4, 0x071e,
+ 0x53e5, 0x0913,
+ 0x53e6, 0x0a36,
+ 0x53e7, 0x2a68,
+ 0x53e8, 0x14fe,
+ 0x53e9, 0x14fd,
+ 0x53ea, 0x11ba,
+ 0x53eb, 0x08a1,
+ 0x53ec, 0x117a,
+ 0x53ed, 0x03d3,
+ 0x53ee, 0x05e2,
+ 0x53ef, 0x0956,
+ 0x53f0, 0x0dfb,
+ 0x53f1, 0x14fb,
+ 0x53f2, 0x0d4e,
+ 0x53f3, 0x10b7,
+ 0x53f4, 0x2a69,
+ 0x53f5, 0x1285,
+ 0x53f6, 0x103d,
+ 0x53f7, 0x077c,
+ 0x53f8, 0x0db3,
+ 0x53f9, 0x0e11,
+ 0x53fa, 0x2a6a,
+ 0x53fb, 0x14ff,
+ 0x53fc, 0x05d1,
+ 0x53fd, 0x14fc,
+ 0x53fe, 0x2a6b,
+ 0x5400, 0x2a6d,
+ 0x5401, 0x10da,
+ 0x5402, 0x2a6e,
+ 0x5403, 0x04f9,
+ 0x5404, 0x06f2,
+ 0x5405, 0x2a6f,
+ 0x5406, 0x1502,
+ 0x5407, 0x2a70,
+ 0x5408, 0x0786,
+ 0x5409, 0x081d,
+ 0x540a, 0x05d6,
+ 0x540b, 0x2a71,
+ 0x540c, 0x0e5d,
+ 0x540d, 0x0b00,
+ 0x540e, 0x07aa,
+ 0x540f, 0x09df,
+ 0x5410, 0x0e73,
+ 0x5411, 0x0f5f,
+ 0x5412, 0x1500,
+ 0x5413, 0x0f32,
+ 0x5414, 0x2a72,
+ 0x5415, 0x0a67,
+ 0x5416, 0x1501,
+ 0x5417, 0x0a97,
+ 0x5418, 0x2a73,
+ 0x541b, 0x092c,
+ 0x541c, 0x2a76,
+ 0x541d, 0x0a28,
+ 0x541e, 0x0e7d,
+ 0x541f, 0x107e,
+ 0x5420, 0x066a,
+ 0x5421, 0x1509,
+ 0x5422, 0x2a77,
+ 0x5423, 0x150c,
+ 0x5424, 0x2a78,
+ 0x5426, 0x068e,
+ 0x5427, 0x03d4,
+ 0x5428, 0x0615,
+ 0x5429, 0x0671,
+ 0x542a, 0x2a7a,
+ 0x542b, 0x0763,
+ 0x542c, 0x0e50,
+ 0x542d, 0x0961,
+ 0x542e, 0x0da6,
+ 0x542f, 0x0c13,
+ 0x5430, 0x2a7b,
+ 0x5431, 0x11a7,
+ 0x5432, 0x150d,
+ 0x5433, 0x2a7c,
+ 0x5434, 0x0ef1,
+ 0x5435, 0x04d8,
+ 0x5436, 0x2a7d,
+ 0x5438, 0x0f0b,
+ 0x5439, 0x0538,
+ 0x543a, 0x2a7f,
+ 0x543b, 0x0ed6,
+ 0x543c, 0x07a7,
+ 0x543d, 0x2a80,
+ 0x543e, 0x0ef0,
+ 0x543f, 0x2a81,
+ 0x5440, 0x0fe6,
+ 0x5441, 0x2a82,
+ 0x5443, 0x1508,
+ 0x5444, 0x2a84,
+ 0x5446, 0x0577,
+ 0x5447, 0x2a86,
+ 0x5448, 0x04ef,
+ 0x5449, 0x2a87,
+ 0x544a, 0x06e1,
+ 0x544b, 0x1503,
+ 0x544c, 0x2a88,
+ 0x5450, 0x0b28,
+ 0x5451, 0x2a8c,
+ 0x5452, 0x1504,
+ 0x5455, 0x0b7c,
+ 0x5456, 0x1507,
+ 0x5457, 0x150a,
+ 0x5458, 0x10f4,
+ 0x5459, 0x150b,
+ 0x545a, 0x2a8d,
+ 0x545b, 0x0c37,
+ 0x545c, 0x0ee7,
+ 0x545d, 0x2a8e,
+ 0x5462, 0x0b3b,
+ 0x5463, 0x2a93,
+ 0x5464, 0x1512,
+ 0x5465, 0x2a94,
+ 0x5466, 0x1517,
+ 0x5467, 0x2a95,
+ 0x5468, 0x11db,
+ 0x5469, 0x2a96,
+ 0x5471, 0x1511,
+ 0x5472, 0x1522,
+ 0x5473, 0x0ec5,
+ 0x5474, 0x2a9e,
+ 0x5475, 0x077e,
+ 0x5476, 0x1516,
+ 0x5477, 0x1510,
+ 0x5478, 0x0b9f,
+ 0x5479, 0x2a9f,
+ 0x547b, 0x0d24,
+ 0x547c, 0x07ab,
+ 0x547d, 0x0b01,
+ 0x547e, 0x2aa1,
+ 0x5480, 0x0906,
+ 0x5481, 0x2aa3,
+ 0x5482, 0x150e,
+ 0x5483, 0x2aa4,
+ 0x5484, 0x1515,
+ 0x5485, 0x2aa5,
+ 0x5486, 0x0b99,
+ 0x5487, 0x2aa6,
+ 0x548b, 0x1147,
+ 0x548c, 0x0784,
+ 0x548d, 0x2aaa,
+ 0x548e, 0x08fb,
+ 0x548f, 0x10a2,
+ 0x5490, 0x06bb,
+ 0x5491, 0x2aab,
+ 0x5492, 0x11e3,
+ 0x5493, 0x2aac,
+ 0x5494, 0x150f,
+ 0x5495, 0x0717,
+ 0x5496, 0x0934,
+ 0x5497, 0x2aad,
+ 0x5499, 0x0a45,
+ 0x549a, 0x1513,
+ 0x549c, 0x2aaf,
+ 0x549d, 0x1518,
+ 0x549e, 0x2ab0,
+ 0x54a3, 0x1523,
+ 0x54a4, 0x152d,
+ 0x54a5, 0x2ab5,
+ 0x54a6, 0x151f,
+ 0x54a7, 0x151e,
+ 0x54a8, 0x1226,
+ 0x54a9, 0x152b,
+ 0x54ab, 0x1767,
+ 0x54ac, 0x102e,
+ 0x54ad, 0x151a,
+ 0x54ae, 0x2ab6,
+ 0x54af, 0x0936,
+ 0x54b0, 0x2ab7,
+ 0x54b1, 0x111e,
+ 0x54b2, 0x2ab8,
+ 0x54b3, 0x0955,
+ 0x54b4, 0x151c,
+ 0x54b5, 0x2ab9,
+ 0x54b8, 0x0f39,
+ 0x54b9, 0x2abc,
+ 0x54bb, 0x1525,
+ 0x54bc, 0x236d,
+ 0x54bd, 0x0ff3,
+ 0x54be, 0x2abe,
+ 0x54bf, 0x1526,
+ 0x54c0, 0x03b2,
+ 0x54c1, 0x0bd6,
+ 0x54c2, 0x151b,
+ 0x54c3, 0x2abf,
+ 0x54c4, 0x079c,
+ 0x54c5, 0x2ac0,
+ 0x54c6, 0x061e,
+ 0x54c7, 0x0e8c,
+ 0x54c8, 0x0757,
+ 0x54c9, 0x1118,
+ 0x54ca, 0x2ac1,
+ 0x54cc, 0x1527,
+ 0x54cd, 0x0f59,
+ 0x54ce, 0x03b0,
+ 0x54cf, 0x152f,
+ 0x54d0, 0x1519,
+ 0x54d1, 0x0fef,
+ 0x54d2, 0x151d,
+ 0x54d3, 0x1520,
+ 0x54d5, 0x1524,
+ 0x54d6, 0x2ac3,
+ 0x54d7, 0x07be,
+ 0x54d8, 0x2ac4,
+ 0x54d9, 0x1528,
+ 0x54db, 0x2ac5,
+ 0x54dc, 0x152a,
+ 0x54dd, 0x152e,
+ 0x54de, 0x1530,
+ 0x54df, 0x1099,
+ 0x54e0, 0x2ac6,
+ 0x54e1, 0x2247,
+ 0x54e2, 0x2ac7,
+ 0x54e5, 0x06e2,
+ 0x54e6, 0x0b77,
+ 0x54e7, 0x1532,
+ 0x54e8, 0x0d13,
+ 0x54e9, 0x09f1,
+ 0x54ea, 0x0b27,
+ 0x54eb, 0x2aca,
+ 0x54ed, 0x096b,
+ 0x54ee, 0x0f65,
+ 0x54ef, 0x2acc,
+ 0x54f2, 0x117d,
+ 0x54f3, 0x1536,
+ 0x54f4, 0x2acf,
+ 0x54fa, 0x047f,
+ 0x54fb, 0x2ad5,
+ 0x54fc, 0x0796,
+ 0x54fd, 0x1534,
+ 0x54fe, 0x2ad6,
+ 0x54ff, 0x1391,
+ 0x5500, 0x2ad7,
+ 0x5501, 0x100d,
+ 0x5502, 0x2ad8,
+ 0x5504, 0x236c,
+ 0x5505, 0x2ada,
+ 0x5506, 0x0de9,
+ 0x5507, 0x0540,
+ 0x5508, 0x2adb,
+ 0x5509, 0x03b1,
+ 0x550a, 0x2adc,
+ 0x550f, 0x1539,
+ 0x5510, 0x0e19,
+ 0x5511, 0x153a,
+ 0x5512, 0x2ae1,
+ 0x5514, 0x1535,
+ 0x5515, 0x2ae3,
+ 0x551b, 0x1531,
+ 0x551c, 0x2ae9,
+ 0x5520, 0x1533,
+ 0x5521, 0x2aed,
+ 0x5522, 0x1537,
+ 0x5524, 0x07d2,
+ 0x5525, 0x2aee,
+ 0x5527, 0x153b,
+ 0x5528, 0x2af0,
+ 0x552a, 0x153c,
+ 0x552b, 0x2af2,
+ 0x552c, 0x07b8,
+ 0x552d, 0x2af3,
+ 0x552e, 0x0d72,
+ 0x552f, 0x0eb7,
+ 0x5530, 0x154d,
+ 0x5531, 0x04cf,
+ 0x5532, 0x2af4,
+ 0x5533, 0x154c,
+ 0x5534, 0x2af5,
+ 0x5537, 0x1547,
+ 0x5538, 0x2af8,
+ 0x553c, 0x1546,
+ 0x553d, 0x2afc,
+ 0x553e, 0x0e8a,
+ 0x553f, 0x1544,
+ 0x5540, 0x2afd,
+ 0x5541, 0x1542,
+ 0x5542, 0x2afe,
+ 0x5543, 0x095d,
+ 0x5544, 0x1221,
+ 0x5545, 0x2aff,
+ 0x5546, 0x0d05,
+ 0x5547, 0x2b00,
+ 0x5549, 0x1540,
+ 0x554a, 0x03ac,
+ 0x554b, 0x2b02,
+ 0x554f, 0x219c,
+ 0x5550, 0x1545,
+ 0x5551, 0x2b06,
+ 0x5553, 0x20c9,
+ 0x5554, 0x2b08,
+ 0x5555, 0x1543,
+ 0x5556, 0x1548,
+ 0x5557, 0x2b09,
+ 0x555c, 0x154e,
+ 0x555d, 0x2b0e,
+ 0x555e, 0x21f0,
+ 0x555f, 0x2b0f,
+ 0x5561, 0x0665,
+ 0x5562, 0x2b11,
+ 0x5564, 0x0bc0,
+ 0x5565, 0x0cef,
+ 0x5566, 0x099d,
+ 0x5567, 0x153d,
+ 0x5568, 0x2b13,
+ 0x556a, 0x0b7f,
+ 0x556b, 0x2b15,
+ 0x556c, 0x127a,
+ 0x556d, 0x1541,
+ 0x556e, 0x0b59,
+ 0x556f, 0x2b16,
+ 0x5575, 0x1549,
+ 0x5578, 0x0f70,
+ 0x5579, 0x2b1c,
+ 0x557b, 0x155a,
+ 0x557c, 0x0e37,
+ 0x557d, 0x2b1e,
+ 0x557e, 0x1557,
+ 0x557f, 0x2b1f,
+ 0x5580, 0x0933,
+ 0x5581, 0x1555,
+ 0x5582, 0x0ec8,
+ 0x5583, 0x1551,
+ 0x5584, 0x0cff,
+ 0x5585, 0x2b20,
+ 0x5587, 0x0999,
+ 0x5588, 0x1554,
+ 0x5589, 0x07a4,
+ 0x558a, 0x0767,
+ 0x558b, 0x154f,
+ 0x558c, 0x2b22,
+ 0x558f, 0x153e,
+ 0x5590, 0x2b25,
+ 0x5591, 0x1559,
+ 0x5592, 0x2b26,
+ 0x5594, 0x155e,
+ 0x5595, 0x2b28,
+ 0x5598, 0x0530,
+ 0x5599, 0x155f,
+ 0x559a, 0x2b2b,
+ 0x559c, 0x0f1f,
+ 0x559d, 0x077f,
+ 0x559e, 0x2b2d,
+ 0x559f, 0x1556,
+ 0x55a0, 0x2b2e,
+ 0x55a7, 0x0fc5,
+ 0x55a8, 0x2b35,
+ 0x55aa, 0x210b,
+ 0x55ab, 0x2b37,
+ 0x55ac, 0x20de,
+ 0x55ad, 0x2b38,
+ 0x55ae, 0x1eaa,
+ 0x55af, 0x2b39,
+ 0x55b1, 0x1552,
+ 0x55b2, 0x222c,
+ 0x55b3, 0x113e,
+ 0x55b4, 0x2b3b,
+ 0x55b5, 0x153f,
+ 0x55b6, 0x2b3c,
+ 0x55b7, 0x0ba8,
+ 0x55b8, 0x2b3d,
+ 0x55b9, 0x1553,
+ 0x55ba, 0x2b3e,
+ 0x55bb, 0x10dc,
+ 0x55bc, 0x2b3f,
+ 0x55bd, 0x155c,
+ 0x55bf, 0x2b40,
+ 0x55c4, 0x156a,
+ 0x55c5, 0x0fac,
+ 0x55c6, 0x20d8,
+ 0x55c7, 0x22c0,
+ 0x55c8, 0x2b45,
+ 0x55c9, 0x1562,
+ 0x55ca, 0x2b46,
+ 0x55cc, 0x156f,
+ 0x55ce, 0x206f,
+ 0x55cf, 0x2b48,
+ 0x55d1, 0x1564,
+ 0x55d2, 0x1550,
+ 0x55d3, 0x0cdd,
+ 0x55d4, 0x1567,
+ 0x55d5, 0x2b4a,
+ 0x55d6, 0x1558,
+ 0x55d7, 0x2b4b,
+ 0x55da, 0x21a1,
+ 0x55db, 0x2b4e,
+ 0x55dc, 0x0d5f,
+ 0x55dd, 0x1569,
+ 0x55de, 0x2b4f,
+ 0x55df, 0x155b,
+ 0x55e0, 0x2b50,
+ 0x55e1, 0x0eda,
+ 0x55e2, 0x2b51,
+ 0x55e3, 0x0db8,
+ 0x55e4, 0x1573,
+ 0x55e5, 0x156c,
+ 0x55e6, 0x1568,
+ 0x55e7, 0x2b52,
+ 0x55e8, 0x1571,
+ 0x55e9, 0x2379,
+ 0x55ea, 0x1560,
+ 0x55eb, 0x1565,
+ 0x55ed, 0x2b53,
+ 0x55ef, 0x156b,
+ 0x55f0, 0x2b55,
+ 0x55f2, 0x156d,
+ 0x55f4, 0x2b57,
+ 0x55f5, 0x1572,
+ 0x55f6, 0x2372,
+ 0x55f7, 0x1561,
+ 0x55f8, 0x2b58,
+ 0x55fd, 0x0dc9,
+ 0x55fe, 0x157b,
+ 0x55ff, 0x2b5d,
+ 0x5600, 0x157c,
+ 0x5601, 0x1578,
+ 0x5602, 0x2b5e,
+ 0x5606, 0x216a,
+ 0x5607, 0x2b62,
+ 0x5608, 0x1576,
+ 0x5609, 0x0841,
+ 0x560a, 0x2b63,
+ 0x560c, 0x1577,
+ 0x560d, 0x237c,
+ 0x560e, 0x06bd,
+ 0x560f, 0x127b,
+ 0x5610, 0x2b65,
+ 0x5614, 0x20b0,
+ 0x5615, 0x2b69,
+ 0x5616, 0x237a,
+ 0x5617, 0x1e74,
+ 0x5618, 0x0fb5,
+ 0x5619, 0x2b6a,
+ 0x561b, 0x0a96,
+ 0x561c, 0x2377,
+ 0x561d, 0x2b6c,
+ 0x561e, 0x1575,
+ 0x561f, 0x1563,
+ 0x5620, 0x2b6d,
+ 0x5623, 0x157a,
+ 0x5624, 0x1579,
+ 0x5625, 0x2b70,
+ 0x5627, 0x157d,
+ 0x5628, 0x2b72,
+ 0x5629, 0x1f4c,
+ 0x562a, 0x2b73,
+ 0x562c, 0x1582,
+ 0x562d, 0x157e,
+ 0x562e, 0x2378,
+ 0x562f, 0x21cf,
+ 0x5630, 0x2368,
+ 0x5631, 0x11f5,
+ 0x5632, 0x04d5,
+ 0x5633, 0x2b75,
+ 0x5634, 0x1249,
+ 0x5635, 0x2371,
+ 0x5636, 0x0db0,
+ 0x5637, 0x2b76,
+ 0x5638, 0x2369,
+ 0x5639, 0x1580,
+ 0x563a, 0x2b77,
+ 0x563b, 0x0f0a,
+ 0x563c, 0x2b78,
+ 0x563f, 0x0790,
+ 0x5640, 0x2b7b,
+ 0x5641, 0x2674,
+ 0x5642, 0x2b7c,
+ 0x564c, 0x1587,
+ 0x564d, 0x1583,
+ 0x564e, 0x1034,
+ 0x564f, 0x2b86,
+ 0x5654, 0x1588,
+ 0x5655, 0x2b8b,
+ 0x5657, 0x1581,
+ 0x5658, 0x157f,
+ 0x5659, 0x1585,
+ 0x565a, 0x2b8d,
+ 0x565c, 0x1586,
+ 0x565d, 0x236f,
+ 0x565e, 0x2b8f,
+ 0x5660, 0x2370,
+ 0x5661, 0x2b91,
+ 0x5662, 0x1584,
+ 0x5663, 0x2b92,
+ 0x5664, 0x158a,
+ 0x5665, 0x2376,
+ 0x5666, 0x2373,
+ 0x5667, 0x2b93,
+ 0x5668, 0x0c16,
+ 0x5669, 0x1262,
+ 0x566a, 0x112e,
+ 0x566b, 0x158c,
+ 0x566c, 0x0d60,
+ 0x566d, 0x2b94,
+ 0x566f, 0x237f,
+ 0x5670, 0x2b96,
+ 0x5671, 0x158b,
+ 0x5672, 0x2374,
+ 0x5673, 0x2b97,
+ 0x5674, 0x20b5,
+ 0x5675, 0x2b98,
+ 0x5676, 0x06bc,
+ 0x5677, 0x2b99,
+ 0x5678, 0x1edb,
+ 0x5679, 0x2672,
+ 0x567a, 0x2b9a,
+ 0x567b, 0x158d,
+ 0x567d, 0x2b9b,
+ 0x5680, 0x236e,
+ 0x5681, 0x2b9e,
+ 0x5685, 0x158f,
+ 0x5686, 0x1589,
+ 0x5687, 0x21b7,
+ 0x5688, 0x2ba2,
+ 0x568c, 0x2375,
+ 0x568d, 0x2ba6,
+ 0x568e, 0x0776,
+ 0x568f, 0x0e3a,
+ 0x5690, 0x2ba7,
+ 0x5693, 0x1590,
+ 0x5694, 0x2baa,
+ 0x5695, 0x2382,
+ 0x5696, 0x2bab,
+ 0x5699, 0x209e,
+ 0x569a, 0x2bae,
+ 0x56a3, 0x0f66,
+ 0x56a4, 0x2bb7,
+ 0x56a6, 0x236b,
+ 0x56a7, 0x2bb9,
+ 0x56a8, 0x2039,
+ 0x56a9, 0x2bba,
+ 0x56ae, 0x269f,
+ 0x56af, 0x1591,
+ 0x56b0, 0x2bbf,
+ 0x56b3, 0x237d,
+ 0x56b4, 0x21f5,
+ 0x56b5, 0x2bc2,
+ 0x56b6, 0x2381,
+ 0x56b7, 0x0c9d,
+ 0x56b8, 0x2bc3,
+ 0x56bc, 0x0891,
+ 0x56bd, 0x2bc7,
+ 0x56c0, 0x237b,
+ 0x56c1, 0x237e,
+ 0x56c2, 0x21cc,
+ 0x56c3, 0x2bca,
+ 0x56c5, 0x22db,
+ 0x56c6, 0x2bcc,
+ 0x56c8, 0x236a,
+ 0x56c9, 0x2689,
+ 0x56ca, 0x0b35,
+ 0x56cb, 0x2bce,
+ 0x56cc, 0x2697,
+ 0x56cd, 0x2bcf,
+ 0x56d1, 0x22a1,
+ 0x56d2, 0x2bd3,
+ 0x56d4, 0x1592,
+ 0x56d5, 0x2bd5,
+ 0x56d7, 0x1593,
+ 0x56d8, 0x2bd7,
+ 0x56da, 0x0c71,
+ 0x56db, 0x0db9,
+ 0x56dc, 0x2bd9,
+ 0x56dd, 0x1594,
+ 0x56de, 0x07ed,
+ 0x56df, 0x126c,
+ 0x56e0, 0x1079,
+ 0x56e1, 0x1595,
+ 0x56e2, 0x0e76,
+ 0x56e3, 0x2bda,
+ 0x56e4, 0x0619,
+ 0x56e5, 0x2bdb,
+ 0x56eb, 0x1597,
+ 0x56ec, 0x2be1,
+ 0x56ed, 0x10f3,
+ 0x56ee, 0x2be2,
+ 0x56f0, 0x0992,
+ 0x56f1, 0x0554,
+ 0x56f2, 0x2be4,
+ 0x56f4, 0x0eb6,
+ 0x56f5, 0x1596,
+ 0x56f6, 0x2be6,
+ 0x56f9, 0x1598,
+ 0x56fa, 0x0725,
+ 0x56fb, 0x2be9,
+ 0x56fd, 0x0753,
+ 0x56fe, 0x0e6d,
+ 0x56ff, 0x1599,
+ 0x5700, 0x2beb,
+ 0x5703, 0x0bf3,
+ 0x5704, 0x159a,
+ 0x5705, 0x2bee,
+ 0x5706, 0x10f5,
+ 0x5707, 0x2383,
+ 0x5708, 0x0c81,
+ 0x5709, 0x159c,
+ 0x570a, 0x159b,
+ 0x570b, 0x1f3d,
+ 0x570c, 0x2bef,
+ 0x570d, 0x218f,
+ 0x570e, 0x2bf0,
+ 0x5712, 0x2246,
+ 0x5713, 0x2248,
+ 0x5714, 0x2bf4,
+ 0x5716, 0x217e,
+ 0x5717, 0x2bf6,
+ 0x5718, 0x2180,
+ 0x5719, 0x2bf7,
+ 0x571c, 0x159d,
+ 0x571d, 0x2bfa,
+ 0x571f, 0x0e72,
+ 0x5720, 0x2bfc,
+ 0x5723, 0x0d3c,
+ 0x5724, 0x2bff,
+ 0x5728, 0x111d,
+ 0x5729, 0x13a7,
+ 0x572a, 0x13a9,
+ 0x572b, 0x2c03,
+ 0x572c, 0x13a8,
+ 0x572d, 0x0740,
+ 0x572e, 0x13ac,
+ 0x5730, 0x05b9,
+ 0x5731, 0x2c04,
+ 0x5733, 0x13aa,
+ 0x5734, 0x2c06,
+ 0x5739, 0x13ab,
+ 0x573a, 0x04c6,
+ 0x573b, 0x13af,
+ 0x573c, 0x2c0b,
+ 0x573e, 0x080d,
+ 0x573f, 0x2c0d,
+ 0x5740, 0x11b6,
+ 0x5741, 0x2c0e,
+ 0x5742, 0x13b0,
+ 0x5743, 0x2c0f,
+ 0x5747, 0x0928,
+ 0x5748, 0x2c13,
+ 0x574a, 0x0658,
+ 0x574b, 0x2c15,
+ 0x574c, 0x13a0,
+ 0x574d, 0x0e01,
+ 0x574e, 0x093f,
+ 0x574f, 0x07ca,
+ 0x5750, 0x1255,
+ 0x5751, 0x0960,
+ 0x5752, 0x2c16,
+ 0x5757, 0x0976,
+ 0x5758, 0x2c1b,
+ 0x575a, 0x0854,
+ 0x575b, 0x0e06,
+ 0x575c, 0x13ae,
+ 0x575d, 0x03de,
+ 0x575e, 0x0efa,
+ 0x575f, 0x0675,
+ 0x5760, 0x1216,
+ 0x5761, 0x0be1,
+ 0x5762, 0x2c1d,
+ 0x5764, 0x098f,
+ 0x5765, 0x2c1f,
+ 0x5766, 0x0e0c,
+ 0x5767, 0x2c20,
+ 0x5768, 0x13b7,
+ 0x5769, 0x13b1,
+ 0x576a, 0x0bd9,
+ 0x576b, 0x13b3,
+ 0x576c, 0x2c21,
+ 0x576d, 0x13b8,
+ 0x576e, 0x2c22,
+ 0x576f, 0x0bb8,
+ 0x5770, 0x2c23,
+ 0x5773, 0x13ba,
+ 0x5774, 0x2c26,
+ 0x5776, 0x13b9,
+ 0x5777, 0x094d,
+ 0x5778, 0x2c28,
+ 0x577b, 0x13b6,
+ 0x577c, 0x13b5,
+ 0x577d, 0x2c2b,
+ 0x5782, 0x053c,
+ 0x5783, 0x0997,
+ 0x5784, 0x0a49,
+ 0x5785, 0x13b2,
+ 0x5786, 0x13b4,
+ 0x5787, 0x2c30,
+ 0x578b, 0x0f98,
+ 0x578c, 0x13bd,
+ 0x578d, 0x2c34,
+ 0x5792, 0x09c8,
+ 0x5793, 0x13c2,
+ 0x5794, 0x2c39,
+ 0x579b, 0x0621,
+ 0x579c, 0x2c40,
+ 0x57a0, 0x13c3,
+ 0x57a1, 0x13a2,
+ 0x57a2, 0x0711,
+ 0x57a3, 0x10ee,
+ 0x57a4, 0x13bc,
+ 0x57a5, 0x2c44,
+ 0x57a6, 0x095e,
+ 0x57a7, 0x13c0,
+ 0x57a8, 0x2c45,
+ 0x57a9, 0x13a1,
+ 0x57aa, 0x2c46,
+ 0x57ab, 0x05c7,
+ 0x57ac, 0x2c47,
+ 0x57ad, 0x13bb,
+ 0x57ae, 0x0972,
+ 0x57af, 0x2c48,
+ 0x57b2, 0x13be,
+ 0x57b3, 0x2c4b,
+ 0x57b4, 0x13c1,
+ 0x57b5, 0x2c4c,
+ 0x57b8, 0x13c9,
+ 0x57b9, 0x2c4f,
+ 0x57c2, 0x06fa,
+ 0x57c3, 0x03ae,
+ 0x57c4, 0x2c58,
+ 0x57cb, 0x0a98,
+ 0x57cc, 0x2c5f,
+ 0x57ce, 0x04ec,
+ 0x57cf, 0x13bf,
+ 0x57d0, 0x2c61,
+ 0x57d2, 0x13c8,
+ 0x57d3, 0x2c63,
+ 0x57d4, 0x0bf1,
+ 0x57d5, 0x13c4,
+ 0x57d6, 0x2c64,
+ 0x57d8, 0x13c5,
+ 0x57d9, 0x13c7,
+ 0x57da, 0x13c6,
+ 0x57db, 0x2c66,
+ 0x57dd, 0x13ce,
+ 0x57de, 0x2c68,
+ 0x57df, 0x10d7,
+ 0x57e0, 0x0481,
+ 0x57e1, 0x232a,
+ 0x57e2, 0x2c69,
+ 0x57e4, 0x13cd,
+ 0x57e5, 0x2c6b,
+ 0x57ed, 0x13d2,
+ 0x57ee, 0x2c73,
+ 0x57ef, 0x13cb,
+ 0x57f0, 0x2c74,
+ 0x57f4, 0x13ca,
+ 0x57f5, 0x2c78,
+ 0x57f7, 0x228b,
+ 0x57f8, 0x13cc,
+ 0x57f9, 0x0ba1,
+ 0x57fa, 0x080e,
+ 0x57fb, 0x2c7a,
+ 0x57fd, 0x13d1,
+ 0x57fe, 0x2c7c,
+ 0x5800, 0x13d3,
+ 0x5801, 0x2c7e,
+ 0x5802, 0x0e16,
+ 0x5803, 0x2c7f,
+ 0x5805, 0x1f85,
+ 0x5806, 0x0610,
+ 0x5807, 0x144c,
+ 0x5808, 0x2c81,
+ 0x580a, 0x2325,
+ 0x580b, 0x13cf,
+ 0x580c, 0x2c83,
+ 0x580d, 0x13d0,
+ 0x580e, 0x2c84,
+ 0x5811, 0x0c32,
+ 0x5812, 0x2c87,
+ 0x5815, 0x0628,
+ 0x5816, 0x232c,
+ 0x5817, 0x2c8a,
+ 0x5819, 0x13d5,
+ 0x581a, 0x2c8c,
+ 0x581d, 0x232e,
+ 0x581e, 0x13d4,
+ 0x581f, 0x2c8f,
+ 0x5820, 0x13d7,
+ 0x5821, 0x040d,
+ 0x5822, 0x2c90,
+ 0x5824, 0x05ad,
+ 0x5825, 0x2c92,
+ 0x582a, 0x093d,
+ 0x582b, 0x2c97,
+ 0x582f, 0x2205,
+ 0x5830, 0x1008,
+ 0x5831, 0x1e38,
+ 0x5832, 0x2c9b,
+ 0x5834, 0x1e73,
+ 0x5835, 0x0601,
+ 0x5836, 0x2c9d,
+ 0x5844, 0x13d6,
+ 0x5845, 0x2cab,
+ 0x584a, 0x1fe3,
+ 0x584b, 0x2339,
+ 0x584c, 0x0def,
+ 0x584d, 0x19a3,
+ 0x584e, 0x2cb0,
+ 0x584f, 0x232b,
+ 0x5850, 0x2cb1,
+ 0x5851, 0x0dd1,
+ 0x5852, 0x232d,
+ 0x5853, 0x2cb2,
+ 0x5854, 0x0df3,
+ 0x5855, 0x2cb3,
+ 0x5857, 0x217f,
+ 0x5858, 0x0e14,
+ 0x5859, 0x2cb5,
+ 0x585e, 0x0cd6,
+ 0x585f, 0x2cba,
+ 0x5862, 0x21a7,
+ 0x5863, 0x2cbd,
+ 0x5864, 0x232f,
+ 0x5865, 0x13d8,
+ 0x5866, 0x2cbe,
+ 0x586b, 0x0e41,
+ 0x586c, 0x13d9,
+ 0x586d, 0x2cc3,
+ 0x5875, 0x1e7d,
+ 0x5876, 0x2ccb,
+ 0x5879, 0x20d6,
+ 0x587a, 0x2cce,
+ 0x587e, 0x13a3,
+ 0x587f, 0x2cd2,
+ 0x5880, 0x13dd,
+ 0x5881, 0x13da,
+ 0x5882, 0x2cd3,
+ 0x5883, 0x08e2,
+ 0x5884, 0x2cd4,
+ 0x5885, 0x0d92,
+ 0x5886, 0x2cd5,
+ 0x5889, 0x13db,
+ 0x588a, 0x1ec2,
+ 0x588b, 0x2cd8,
+ 0x5892, 0x0d03,
+ 0x5893, 0x0b1c,
+ 0x5894, 0x2cdf,
+ 0x5899, 0x0c3a,
+ 0x589a, 0x13dc,
+ 0x589b, 0x2ce4,
+ 0x589c, 0x22b2,
+ 0x589d, 0x2ce5,
+ 0x589e, 0x1139,
+ 0x589f, 0x0fb1,
+ 0x58a0, 0x2ce6,
+ 0x58a8, 0x0b0e,
+ 0x58a9, 0x0614,
+ 0x58aa, 0x2cee,
+ 0x58ae, 0x1edf,
+ 0x58af, 0x2cf2,
+ 0x58b3, 0x1ef9,
+ 0x58b4, 0x2cf6,
+ 0x58bb, 0x20d9,
+ 0x58bc, 0x13a4,
+ 0x58bd, 0x2cfd,
+ 0x58be, 0x1fdd,
+ 0x58bf, 0x2cfe,
+ 0x58c1, 0x0443,
+ 0x58c2, 0x2d00,
+ 0x58c5, 0x13a5,
+ 0x58c6, 0x2d03,
+ 0x58c7, 0x2167,
+ 0x58c8, 0x2d04,
+ 0x58d1, 0x13a6,
+ 0x58d2, 0x2d0d,
+ 0x58d3, 0x21ed,
+ 0x58d4, 0x2d0e,
+ 0x58d5, 0x0775,
+ 0x58d6, 0x2d0f,
+ 0x58d8, 0x2007,
+ 0x58d9, 0x2326,
+ 0x58da, 0x2329,
+ 0x58db, 0x2d11,
+ 0x58de, 0x1f52,
+ 0x58df, 0x203b,
+ 0x58e0, 0x2328,
+ 0x58e1, 0x2d14,
+ 0x58e2, 0x2327,
+ 0x58e3, 0x2d15,
+ 0x58e4, 0x0c9b,
+ 0x58e5, 0x2d16,
+ 0x58e9, 0x1e2b,
+ 0x58ea, 0x2d1a,
+ 0x58eb, 0x0d56,
+ 0x58ec, 0x0ca4,
+ 0x58ed, 0x2d1b,
+ 0x58ee, 0x1210,
+ 0x58ef, 0x22ae,
+ 0x58f0, 0x0d32,
+ 0x58f1, 0x2d1c,
+ 0x58f3, 0x0954,
+ 0x58f4, 0x2d1e,
+ 0x58f6, 0x07af,
+ 0x58f7, 0x2d20,
+ 0x58f9, 0x1043,
+ 0x58fa, 0x1f49,
+ 0x58fb, 0x2d22,
+ 0x58fd, 0x2138,
+ 0x58fe, 0x2d24,
+ 0x5900, 0x2d26,
+ 0x5902, 0x161c,
+ 0x5903, 0x2d28,
+ 0x5904, 0x0529,
+ 0x5905, 0x2d29,
+ 0x5907, 0x0421,
+ 0x5908, 0x2d2b,
+ 0x590d, 0x06af,
+ 0x590e, 0x2d30,
+ 0x590f, 0x0f31,
+ 0x5910, 0x2d31,
+ 0x5914, 0x12fb,
+ 0x5915, 0x0f13,
+ 0x5916, 0x0e93,
+ 0x5917, 0x2d35,
+ 0x5919, 0x1301,
+ 0x591a, 0x061f,
+ 0x591b, 0x2d37,
+ 0x591c, 0x1040,
+ 0x591d, 0x2d38,
+ 0x591f, 0x0714,
+ 0x5920, 0x2d3a,
+ 0x5922, 0x2081,
+ 0x5923, 0x2d3c,
+ 0x5924, 0x161b,
+ 0x5925, 0x1619,
+ 0x5926, 0x2d3d,
+ 0x5927, 0x0576,
+ 0x5928, 0x2d3e,
+ 0x5929, 0x0e3f,
+ 0x592a, 0x0dfe,
+ 0x592b, 0x068f,
+ 0x592c, 0x2d3f,
+ 0x592d, 0x1268,
+ 0x592e, 0x1014,
+ 0x592f, 0x0772,
+ 0x5930, 0x2d40,
+ 0x5931, 0x0d3e,
+ 0x5932, 0x2d41,
+ 0x5934, 0x0e68,
+ 0x5935, 0x2d43,
+ 0x5937, 0x104b,
+ 0x5938, 0x0971,
+ 0x5939, 0x0843,
+ 0x593a, 0x0620,
+ 0x593b, 0x2d45,
+ 0x593c, 0x14af,
+ 0x593d, 0x2d46,
+ 0x593e, 0x1f7c,
+ 0x593f, 0x2d47,
+ 0x5941, 0x14b0,
+ 0x5942, 0x138c,
+ 0x5943, 0x2d49,
+ 0x5944, 0x1002,
+ 0x5945, 0x2d4a,
+ 0x5947, 0x0c05,
+ 0x5948, 0x0b31,
+ 0x5949, 0x068b,
+ 0x594a, 0x2d4c,
+ 0x594b, 0x0679,
+ 0x594c, 0x2d4d,
+ 0x594e, 0x0989,
+ 0x594f, 0x123d,
+ 0x5950, 0x2d4f,
+ 0x5951, 0x0c14,
+ 0x5952, 0x2d50,
+ 0x5954, 0x0425,
+ 0x5955, 0x14b2,
+ 0x5956, 0x0882,
+ 0x5957, 0x0e2a,
+ 0x5958, 0x14b4,
+ 0x5959, 0x2d52,
+ 0x595a, 0x14b3,
+ 0x595b, 0x2d53,
+ 0x5960, 0x05cd,
+ 0x5961, 0x2d58,
+ 0x5962, 0x0d16,
+ 0x5963, 0x2d59,
+ 0x5965, 0x03cd,
+ 0x5966, 0x2d5b,
+ 0x5969, 0x235b,
+ 0x596a, 0x1ede,
+ 0x596b, 0x2d5e,
+ 0x596c, 0x1fa2,
+ 0x596d, 0x2d5f,
+ 0x596e, 0x1efa,
+ 0x596f, 0x2d60,
+ 0x5973, 0x0b6f,
+ 0x5974, 0x0b6c,
+ 0x5975, 0x2d64,
+ 0x5976, 0x0b2f,
+ 0x5977, 0x2d65,
+ 0x5978, 0x085c,
+ 0x5979, 0x0df2,
+ 0x597a, 0x2d66,
+ 0x597d, 0x077a,
+ 0x597e, 0x2d69,
+ 0x5981, 0x1775,
+ 0x5982, 0x0cc2,
+ 0x5983, 0x1776,
+ 0x5984, 0x0eae,
+ 0x5985, 0x2d6c,
+ 0x5986, 0x120e,
+ 0x5987, 0x06b9,
+ 0x5988, 0x0a8f,
+ 0x5989, 0x2d6d,
+ 0x598a, 0x0cac,
+ 0x598b, 0x2d6e,
+ 0x598d, 0x1777,
+ 0x598e, 0x2d70,
+ 0x5992, 0x0609,
+ 0x5993, 0x083e,
+ 0x5994, 0x2d74,
+ 0x5996, 0x1026,
+ 0x5997, 0x177b,
+ 0x5998, 0x2d76,
+ 0x5999, 0x0af3,
+ 0x599a, 0x2d77,
+ 0x599d, 0x22ad,
+ 0x599e, 0x177e,
+ 0x599f, 0x2d7a,
+ 0x59a3, 0x177a,
+ 0x59a4, 0x177f,
+ 0x59a5, 0x0e88,
+ 0x59a6, 0x2d7e,
+ 0x59a8, 0x065e,
+ 0x59a9, 0x1778,
+ 0x59ab, 0x177d,
+ 0x59ac, 0x2d80,
+ 0x59ae, 0x0b40,
+ 0x59af, 0x1782,
+ 0x59b0, 0x2d82,
+ 0x59b2, 0x1781,
+ 0x59b3, 0x2d84,
+ 0x59b9, 0x0ac8,
+ 0x59ba, 0x2d8a,
+ 0x59bb, 0x0bfd,
+ 0x59bc, 0x2d8b,
+ 0x59be, 0x1784,
+ 0x59bf, 0x2d8d,
+ 0x59c6, 0x0b1a,
+ 0x59c7, 0x2d94,
+ 0x59ca, 0x177c,
+ 0x59cb, 0x0d53,
+ 0x59cc, 0x2d97,
+ 0x59d0, 0x08b4,
+ 0x59d1, 0x071c,
+ 0x59d2, 0x1780,
+ 0x59d3, 0x0fa0,
+ 0x59d4, 0x0ebe,
+ 0x59d5, 0x2d9b,
+ 0x59d7, 0x1783,
+ 0x59d8, 0x178a,
+ 0x59d9, 0x2d9d,
+ 0x59da, 0x102d,
+ 0x59db, 0x2d9e,
+ 0x59dc, 0x087b,
+ 0x59dd, 0x1787,
+ 0x59de, 0x2d9f,
+ 0x59e3, 0x1789,
+ 0x59e4, 0x2da4,
+ 0x59e5, 0x09bc,
+ 0x59e6, 0x2da5,
+ 0x59e8, 0x1053,
+ 0x59e9, 0x2da7,
+ 0x59ec, 0x081a,
+ 0x59ed, 0x2daa,
+ 0x59f9, 0x178b,
+ 0x59fa, 0x2db6,
+ 0x59fb, 0x107d,
+ 0x59fc, 0x2db7,
+ 0x59ff, 0x1228,
+ 0x5a00, 0x2dba,
+ 0x5a01, 0x0eaf,
+ 0x5a02, 0x2dbb,
+ 0x5a03, 0x0e8f,
+ 0x5a04, 0x0a4d,
+ 0x5a05, 0x1785,
+ 0x5a07, 0x0890,
+ 0x5a08, 0x1788,
+ 0x5a09, 0x178d,
+ 0x5a0a, 0x2dbc,
+ 0x5a0c, 0x178c,
+ 0x5a0d, 0x2dbe,
+ 0x5a11, 0x1790,
+ 0x5a12, 0x2dc2,
+ 0x5a13, 0x1792,
+ 0x5a14, 0x2dc3,
+ 0x5a18, 0x0b52,
+ 0x5a19, 0x2dc7,
+ 0x5a1c, 0x0b2b,
+ 0x5a1d, 0x2dca,
+ 0x5a1f, 0x0919,
+ 0x5a20, 0x0d28,
+ 0x5a21, 0x2dcc,
+ 0x5a23, 0x1791,
+ 0x5a24, 0x2dce,
+ 0x5a25, 0x062f,
+ 0x5a26, 0x2dcf,
+ 0x5a29, 0x0ae9,
+ 0x5a2a, 0x2dd2,
+ 0x5a31, 0x10ce,
+ 0x5a32, 0x178e,
+ 0x5a33, 0x2dd9,
+ 0x5a34, 0x178f,
+ 0x5a35, 0x2dda,
+ 0x5a36, 0x0c7d,
+ 0x5a37, 0x2ddb,
+ 0x5a3c, 0x1797,
+ 0x5a3d, 0x2de0,
+ 0x5a40, 0x1793,
+ 0x5a41, 0x203f,
+ 0x5a42, 0x2de3,
+ 0x5a46, 0x0be4,
+ 0x5a47, 0x2de7,
+ 0x5a49, 0x0ea2,
+ 0x5a4a, 0x1795,
+ 0x5a4b, 0x2de9,
+ 0x5a55, 0x1796,
+ 0x5a56, 0x2df3,
+ 0x5a5a, 0x07fe,
+ 0x5a5b, 0x2df7,
+ 0x5a62, 0x1798,
+ 0x5a63, 0x2dfe,
+ 0x5a66, 0x1f0e,
+ 0x5a67, 0x1794,
+ 0x5a68, 0x2e01,
+ 0x5a6a, 0x09a2,
+ 0x5a6b, 0x2e03,
+ 0x5a6d, 0x23f9,
+ 0x5a6e, 0x2e05,
+ 0x5a74, 0x1089,
+ 0x5a75, 0x1799,
+ 0x5a76, 0x0d2d,
+ 0x5a77, 0x179d,
+ 0x5a78, 0x2e0b,
+ 0x5a7a, 0x179e,
+ 0x5a7b, 0x2e0d,
+ 0x5a7f, 0x0fc1,
+ 0x5a80, 0x2e11,
+ 0x5a92, 0x0ac2,
+ 0x5a93, 0x2e23,
+ 0x5a9a, 0x0ac9,
+ 0x5a9b, 0x179c,
+ 0x5a9c, 0x2e2a,
+ 0x5aa7, 0x23fc,
+ 0x5aa8, 0x2e35,
+ 0x5aaa, 0x179b,
+ 0x5aab, 0x2e37,
+ 0x5ab2, 0x17a1,
+ 0x5ab3, 0x0f1e,
+ 0x5ab4, 0x2e3e,
+ 0x5ab5, 0x19a4,
+ 0x5ab6, 0x2e3f,
+ 0x5ab8, 0x17a4,
+ 0x5ab9, 0x2e41,
+ 0x5abd, 0x2069,
+ 0x5abe, 0x179f,
+ 0x5abf, 0x2e45,
+ 0x5ac1, 0x0851,
+ 0x5ac2, 0x0ce2,
+ 0x5ac3, 0x2e47,
+ 0x5ac9, 0x0828,
+ 0x5aca, 0x2e4d,
+ 0x5acc, 0x0f40,
+ 0x5acd, 0x2e4f,
+ 0x5ad2, 0x17a2,
+ 0x5ad3, 0x2e54,
+ 0x5ad4, 0x17a3,
+ 0x5ad5, 0x2e55,
+ 0x5ad6, 0x17a8,
+ 0x5ad7, 0x23f7,
+ 0x5ad8, 0x17aa,
+ 0x5ad9, 0x2e56,
+ 0x5adc, 0x17ab,
+ 0x5add, 0x2e59,
+ 0x5ae0, 0x17a5,
+ 0x5ae1, 0x05b6,
+ 0x5ae2, 0x2e5c,
+ 0x5ae3, 0x17a6,
+ 0x5ae4, 0x2e5d,
+ 0x5ae6, 0x17a9,
+ 0x5ae7, 0x2e5f,
+ 0x5ae9, 0x0b3e,
+ 0x5aea, 0x2e61,
+ 0x5aeb, 0x17a0,
+ 0x5aec, 0x2e62,
+ 0x5af1, 0x17a7,
+ 0x5af2, 0x2e67,
+ 0x5af5, 0x23f6,
+ 0x5af6, 0x2e6a,
+ 0x5afb, 0x23fd,
+ 0x5afc, 0x2e6f,
+ 0x5b00, 0x23f8,
+ 0x5b01, 0x2e73,
+ 0x5b08, 0x23fa,
+ 0x5b09, 0x17ac,
+ 0x5b0a, 0x2e7a,
+ 0x5b0b, 0x23fe,
+ 0x5b0c, 0x1fa8,
+ 0x5b0d, 0x2e7b,
+ 0x5b16, 0x17ae,
+ 0x5b17, 0x17ad,
+ 0x5b18, 0x2e84,
+ 0x5b19, 0x2401,
+ 0x5b1a, 0x2e85,
+ 0x5b21, 0x23ff,
+ 0x5b22, 0x2e8c,
+ 0x5b2a, 0x2400,
+ 0x5b2b, 0x2e94,
+ 0x5b30, 0x2221,
+ 0x5b31, 0x2e99,
+ 0x5b32, 0x17af,
+ 0x5b33, 0x2e9a,
+ 0x5b34, 0x130c,
+ 0x5b35, 0x2e9b,
+ 0x5b37, 0x17b0,
+ 0x5b38, 0x2122,
+ 0x5b39, 0x2e9d,
+ 0x5b40, 0x17b1,
+ 0x5b41, 0x2ea4,
+ 0x5b4c, 0x23fb,
+ 0x5b4d, 0x2eaf,
+ 0x5b50, 0x1230,
+ 0x5b51, 0x17b7,
+ 0x5b52, 0x2eb2,
+ 0x5b53, 0x17b8,
+ 0x5b54, 0x0964,
+ 0x5b55, 0x1113,
+ 0x5b56, 0x2eb3,
+ 0x5b57, 0x1233,
+ 0x5b58, 0x0569,
+ 0x5b59, 0x0de4,
+ 0x5b5a, 0x17b4,
+ 0x5b5b, 0x1279,
+ 0x5b5c, 0x122b,
+ 0x5b5d, 0x0f6d,
+ 0x5b5e, 0x2eb4,
+ 0x5b5f, 0x0ad4,
+ 0x5b60, 0x2eb5,
+ 0x5b62, 0x17b9,
+ 0x5b63, 0x0831,
+ 0x5b64, 0x071b,
+ 0x5b65, 0x17b5,
+ 0x5b66, 0x0fd0,
+ 0x5b67, 0x2eb7,
+ 0x5b69, 0x0759,
+ 0x5b6a, 0x0a76,
+ 0x5b6b, 0x215a,
+ 0x5b6c, 0x1261,
+ 0x5b6d, 0x2eb9,
+ 0x5b70, 0x0d82,
+ 0x5b71, 0x176a,
+ 0x5b72, 0x2ebc,
+ 0x5b73, 0x17b6,
+ 0x5b74, 0x2ebd,
+ 0x5b75, 0x0692,
+ 0x5b76, 0x2ebe,
+ 0x5b78, 0x21e5,
+ 0x5b79, 0x2ec0,
+ 0x5b7a, 0x0cc1,
+ 0x5b7b, 0x2ec1,
+ 0x5b7d, 0x0b58,
+ 0x5b7e, 0x2ec3,
+ 0x5b7f, 0x2057,
+ 0x5b80, 0x172e,
+ 0x5b81, 0x0b61,
+ 0x5b82, 0x2ec4,
+ 0x5b83, 0x0df1,
+ 0x5b84, 0x172f,
+ 0x5b85, 0x114d,
+ 0x5b86, 0x2ec5,
+ 0x5b87, 0x10d3,
+ 0x5b88, 0x0d6f,
+ 0x5b89, 0x03bd,
+ 0x5b8a, 0x2ec6,
+ 0x5b8b, 0x0dc3,
+ 0x5b8c, 0x0e9b,
+ 0x5b8d, 0x2ec7,
+ 0x5b8f, 0x07a1,
+ 0x5b90, 0x2ec9,
+ 0x5b93, 0x1731,
+ 0x5b94, 0x2ecc,
+ 0x5b95, 0x1730,
+ 0x5b96, 0x2ecd,
+ 0x5b97, 0x1237,
+ 0x5b98, 0x0732,
+ 0x5b99, 0x11e5,
+ 0x5b9a, 0x05e7,
+ 0x5b9b, 0x0ea1,
+ 0x5b9c, 0x1052,
+ 0x5b9d, 0x040f,
+ 0x5b9e, 0x0d4c,
+ 0x5b9f, 0x2ece,
+ 0x5ba0, 0x050d,
+ 0x5ba1, 0x0d2c,
+ 0x5ba2, 0x095a,
+ 0x5ba3, 0x0fc6,
+ 0x5ba4, 0x0d69,
+ 0x5ba5, 0x1732,
+ 0x5ba6, 0x07d7,
+ 0x5ba7, 0x2ecf,
+ 0x5baa, 0x0f49,
+ 0x5bab, 0x0705,
+ 0x5bac, 0x2ed2,
+ 0x5bb0, 0x111a,
+ 0x5bb1, 0x2ed6,
+ 0x5bb3, 0x075d,
+ 0x5bb4, 0x1010,
+ 0x5bb5, 0x0f69,
+ 0x5bb6, 0x0845,
+ 0x5bb7, 0x2ed8,
+ 0x5bb8, 0x1733,
+ 0x5bb9, 0x0cb8,
+ 0x5bba, 0x2ed9,
+ 0x5bbd, 0x097a,
+ 0x5bbe, 0x045f,
+ 0x5bbf, 0x0dd3,
+ 0x5bc0, 0x2edc,
+ 0x5bc2, 0x0838,
+ 0x5bc3, 0x2ede,
+ 0x5bc4, 0x0837,
+ 0x5bc5, 0x1081,
+ 0x5bc6, 0x0ae1,
+ 0x5bc7, 0x0969,
+ 0x5bc8, 0x2edf,
+ 0x5bcc, 0x06b6,
+ 0x5bcd, 0x2ee3,
+ 0x5bd0, 0x0ac7,
+ 0x5bd1, 0x2ee6,
+ 0x5bd2, 0x0765,
+ 0x5bd3, 0x10e5,
+ 0x5bd4, 0x2ee7,
+ 0x5bdd, 0x0c5b,
+ 0x5bde, 0x0b12,
+ 0x5bdf, 0x04b3,
+ 0x5be0, 0x2ef0,
+ 0x5be1, 0x072a,
+ 0x5be2, 0x20e5,
+ 0x5be3, 0x2ef1,
+ 0x5be4, 0x1737,
+ 0x5be5, 0x0a11,
+ 0x5be6, 0x212f,
+ 0x5be7, 0x20a3,
+ 0x5be8, 0x1150,
+ 0x5be9, 0x2121,
+ 0x5bea, 0x2ef2,
+ 0x5beb, 0x21d4,
+ 0x5bec, 0x1fe5,
+ 0x5bed, 0x2ef3,
+ 0x5bee, 0x1738,
+ 0x5bef, 0x2ef4,
+ 0x5bf0, 0x173a,
+ 0x5bf1, 0x2ef5,
+ 0x5bf5, 0x1e8a,
+ 0x5bf6, 0x1e37,
+ 0x5bf7, 0x2ef9,
+ 0x5bf8, 0x056a,
+ 0x5bf9, 0x0613,
+ 0x5bfa, 0x0db7,
+ 0x5bfb, 0x0fd9,
+ 0x5bfc, 0x059d,
+ 0x5bfd, 0x2efa,
+ 0x5bff, 0x0d70,
+ 0x5c00, 0x2efc,
+ 0x5c01, 0x067f,
+ 0x5c02, 0x2efd,
+ 0x5c04, 0x0d1d,
+ 0x5c05, 0x2eff,
+ 0x5c06, 0x087c,
+ 0x5c07, 0x1f9e,
+ 0x5c08, 0x22a6,
+ 0x5c09, 0x0ecd,
+ 0x5c0a, 0x124d,
+ 0x5c0b, 0x21e8,
+ 0x5c0c, 0x2f00,
+ 0x5c0d, 0x1eda,
+ 0x5c0e, 0x1eb9,
+ 0x5c0f, 0x0f6c,
+ 0x5c10, 0x2f01,
+ 0x5c11, 0x0d12,
+ 0x5c12, 0x2f02,
+ 0x5c14, 0x063a,
+ 0x5c15, 0x17b2,
+ 0x5c16, 0x0855,
+ 0x5c17, 0x2f04,
+ 0x5c18, 0x04e3,
+ 0x5c19, 0x2f05,
+ 0x5c1a, 0x0d09,
+ 0x5c1b, 0x2f06,
+ 0x5c1c, 0x17b3,
+ 0x5c1d, 0x04c7,
+ 0x5c1e, 0x2f07,
+ 0x5c22, 0x14b6,
+ 0x5c23, 0x2f0b,
+ 0x5c24, 0x10ad,
+ 0x5c25, 0x14b7,
+ 0x5c26, 0x2f0c,
+ 0x5c27, 0x1029,
+ 0x5c28, 0x2f0d,
+ 0x5c2c, 0x14b8,
+ 0x5c2d, 0x2f11,
+ 0x5c31, 0x08fc,
+ 0x5c32, 0x2f15,
+ 0x5c34, 0x14b9,
+ 0x5c35, 0x2f17,
+ 0x5c37, 0x235c,
+ 0x5c38, 0x0d43,
+ 0x5c39, 0x1083,
+ 0x5c3a, 0x0504,
+ 0x5c3b, 0x1766,
+ 0x5c3c, 0x0b44,
+ 0x5c3d, 0x08d0,
+ 0x5c3e, 0x0ec1,
+ 0x5c3f, 0x0b55,
+ 0x5c40, 0x0905,
+ 0x5c41, 0x0bc7,
+ 0x5c42, 0x04aa,
+ 0x5c43, 0x2f19,
+ 0x5c45, 0x0902,
+ 0x5c46, 0x2f1b,
+ 0x5c48, 0x0c79,
+ 0x5c49, 0x0e3e,
+ 0x5c4a, 0x08bd,
+ 0x5c4b, 0x0eec,
+ 0x5c4c, 0x2f1d,
+ 0x5c4e, 0x0d51,
+ 0x5c4f, 0x0be0,
+ 0x5c50, 0x1768,
+ 0x5c51, 0x0f87,
+ 0x5c52, 0x2f1f,
+ 0x5c55, 0x115a,
+ 0x5c56, 0x2f22,
+ 0x5c59, 0x1769,
+ 0x5c5a, 0x2f25,
+ 0x5c5e, 0x0d8b,
+ 0x5c5f, 0x2f29,
+ 0x5c60, 0x0e71,
+ 0x5c61, 0x0a6c,
+ 0x5c62, 0x2050,
+ 0x5c63, 0x176b,
+ 0x5c64, 0x1e67,
+ 0x5c65, 0x0a6b,
+ 0x5c66, 0x176c,
+ 0x5c67, 0x2f2a,
+ 0x5c68, 0x23f4,
+ 0x5c69, 0x2f2b,
+ 0x5c6c, 0x213e,
+ 0x5c6d, 0x2f2e,
+ 0x5c6e, 0x1774,
+ 0x5c6f, 0x0e7e,
+ 0x5c70, 0x2f2f,
+ 0x5c71, 0x0cf6,
+ 0x5c72, 0x2f30,
+ 0x5c79, 0x1060,
+ 0x5c7a, 0x15ac,
+ 0x5c7b, 0x2f37,
+ 0x5c7f, 0x10d1,
+ 0x5c80, 0x2f3b,
+ 0x5c81, 0x0ddf,
+ 0x5c82, 0x0c10,
+ 0x5c83, 0x2f3c,
+ 0x5c88, 0x15b0,
+ 0x5c89, 0x2f41,
+ 0x5c8c, 0x15ab,
+ 0x5c8d, 0x15ad,
+ 0x5c8e, 0x2f44,
+ 0x5c90, 0x15ae,
+ 0x5c91, 0x15b3,
+ 0x5c92, 0x2f46,
+ 0x5c94, 0x04b4,
+ 0x5c95, 0x2f48,
+ 0x5c96, 0x15af,
+ 0x5c97, 0x06d5,
+ 0x5c98, 0x15b1,
+ 0x5c9a, 0x15b4,
+ 0x5c9b, 0x059b,
+ 0x5c9c, 0x15b5,
+ 0x5c9d, 0x2f49,
+ 0x5ca1, 0x1f16,
+ 0x5ca2, 0x15b7,
+ 0x5ca3, 0x15bc,
+ 0x5ca4, 0x2f4d,
+ 0x5ca9, 0x0ffb,
+ 0x5caa, 0x2f52,
+ 0x5cab, 0x15ba,
+ 0x5cac, 0x15b9,
+ 0x5cad, 0x0a34,
+ 0x5cae, 0x2f53,
+ 0x5cb1, 0x15bb,
+ 0x5cb2, 0x2f56,
+ 0x5cb3, 0x1103,
+ 0x5cb4, 0x2f57,
+ 0x5cb5, 0x15b6,
+ 0x5cb6, 0x2f58,
+ 0x5cb7, 0x15be,
+ 0x5cb8, 0x03c1,
+ 0x5cb9, 0x2f59,
+ 0x5cbd, 0x15b8,
+ 0x5cbe, 0x2f5d,
+ 0x5cbf, 0x0986,
+ 0x5cc0, 0x2f5e,
+ 0x5cc1, 0x15bd,
+ 0x5cc2, 0x2f5f,
+ 0x5cc4, 0x15bf,
+ 0x5cc5, 0x2f61,
+ 0x5ccb, 0x15c2,
+ 0x5ccc, 0x2f67,
+ 0x5cd2, 0x15c0,
+ 0x5cd3, 0x2f6d,
+ 0x5cd9, 0x11c4,
+ 0x5cda, 0x2f73,
+ 0x5ce1, 0x0f2c,
+ 0x5ce2, 0x2f7a,
+ 0x5ce4, 0x15c1,
+ 0x5ce5, 0x15c3,
+ 0x5ce6, 0x0a74,
+ 0x5ce7, 0x2f7c,
+ 0x5ce8, 0x062a,
+ 0x5ce9, 0x2f7d,
+ 0x5cea, 0x10dd,
+ 0x5ceb, 0x2f7e,
+ 0x5ced, 0x0c4a,
+ 0x5cee, 0x2f80,
+ 0x5cf0, 0x0682,
+ 0x5cf1, 0x2f82,
+ 0x5cf4, 0x2389,
+ 0x5cf5, 0x2f85,
+ 0x5cf6, 0x1eb7,
+ 0x5cf7, 0x2f86,
+ 0x5cfb, 0x092d,
+ 0x5cfc, 0x2f8a,
+ 0x5cfd, 0x21b4,
+ 0x5cfe, 0x2f8b,
+ 0x5d00, 0x2f8d,
+ 0x5d02, 0x15c4,
+ 0x5d04, 0x2f8f,
+ 0x5d06, 0x15cb,
+ 0x5d07, 0x050c,
+ 0x5d08, 0x2f91,
+ 0x5d0d, 0x238f,
+ 0x5d0e, 0x0c08,
+ 0x5d0f, 0x2f96,
+ 0x5d14, 0x0561,
+ 0x5d15, 0x2f9b,
+ 0x5d16, 0x0feb,
+ 0x5d17, 0x1f1a,
+ 0x5d18, 0x2f9c,
+ 0x5d1b, 0x15cc,
+ 0x5d1c, 0x2f9f,
+ 0x5d1e, 0x15ca,
+ 0x5d1f, 0x2fa1,
+ 0x5d24, 0x15c9,
+ 0x5d25, 0x2fa6,
+ 0x5d26, 0x15c7,
+ 0x5d27, 0x15c6,
+ 0x5d28, 0x2fa7,
+ 0x5d29, 0x0429,
+ 0x5d2a, 0x2fa8,
+ 0x5d2c, 0x238b,
+ 0x5d2d, 0x1159,
+ 0x5d2e, 0x15c8,
+ 0x5d2f, 0x2faa,
+ 0x5d34, 0x15cf,
+ 0x5d35, 0x2faf,
+ 0x5d3d, 0x15d0,
+ 0x5d3e, 0x15ce,
+ 0x5d3f, 0x2fb7,
+ 0x5d47, 0x1b22,
+ 0x5d48, 0x2fbf,
+ 0x5d4a, 0x15d7,
+ 0x5d4b, 0x15d6,
+ 0x5d4c, 0x0c33,
+ 0x5d4d, 0x2fc1,
+ 0x5d50, 0x238a,
+ 0x5d51, 0x2fc4,
+ 0x5d58, 0x15cd,
+ 0x5d59, 0x2fcb,
+ 0x5d5b, 0x15d2,
+ 0x5d5c, 0x2fcd,
+ 0x5d5d, 0x15d4,
+ 0x5d5e, 0x2fce,
+ 0x5d69, 0x15d8,
+ 0x5d6a, 0x2fd9,
+ 0x5d6b, 0x15d5,
+ 0x5d6c, 0x15d1,
+ 0x5d6d, 0x2fda,
+ 0x5d6f, 0x15d3,
+ 0x5d70, 0x2fdc,
+ 0x5d74, 0x15d9,
+ 0x5d75, 0x2fe0,
+ 0x5d81, 0x2391,
+ 0x5d82, 0x15da,
+ 0x5d83, 0x2fec,
+ 0x5d84, 0x2271,
+ 0x5d85, 0x2fed,
+ 0x5d87, 0x2388,
+ 0x5d88, 0x2fef,
+ 0x5d97, 0x238e,
+ 0x5d98, 0x2ffe,
+ 0x5d99, 0x15db,
+ 0x5d9a, 0x2fff,
+ 0x5d9d, 0x15dc,
+ 0x5d9e, 0x3002,
+ 0x5da0, 0x238d,
+ 0x5da1, 0x3004,
+ 0x5da7, 0x238c,
+ 0x5da8, 0x300a,
+ 0x5db7, 0x15de,
+ 0x5db8, 0x2390,
+ 0x5db9, 0x3019,
+ 0x5dba, 0x2033,
+ 0x5dbb, 0x301a,
+ 0x5dbc, 0x223c,
+ 0x5dbd, 0x301b,
+ 0x5dc5, 0x15df,
+ 0x5dc6, 0x3023,
+ 0x5dcb, 0x1fe9,
+ 0x5dcc, 0x3028,
+ 0x5dcd, 0x0eb0,
+ 0x5dce, 0x3029,
+ 0x5dd2, 0x2055,
+ 0x5dd3, 0x302d,
+ 0x5dd4, 0x2392,
+ 0x5dd5, 0x302e,
+ 0x5ddb, 0x1815,
+ 0x5ddc, 0x3034,
+ 0x5ddd, 0x052b,
+ 0x5dde, 0x11dc,
+ 0x5ddf, 0x3035,
+ 0x5de1, 0x0fdb,
+ 0x5de2, 0x04d7,
+ 0x5de3, 0x3037,
+ 0x5de5, 0x06fd,
+ 0x5de6, 0x1250,
+ 0x5de7, 0x0c46,
+ 0x5de8, 0x090d,
+ 0x5de9, 0x0707,
+ 0x5dea, 0x3039,
+ 0x5deb, 0x0ee6,
+ 0x5dec, 0x303a,
+ 0x5dee, 0x04b5,
+ 0x5def, 0x139f,
+ 0x5df0, 0x2324,
+ 0x5df1, 0x082d,
+ 0x5df2, 0x1058,
+ 0x5df3, 0x0dbd,
+ 0x5df4, 0x03d8,
+ 0x5df5, 0x303c,
+ 0x5df7, 0x0f5c,
+ 0x5df8, 0x303e,
+ 0x5dfd, 0x12f7,
+ 0x5dfe, 0x08be,
+ 0x5dff, 0x3043,
+ 0x5e00, 0x3044,
+ 0x5e01, 0x043b,
+ 0x5e02, 0x0d67,
+ 0x5e03, 0x0483,
+ 0x5e04, 0x3045,
+ 0x5e05, 0x0d9c,
+ 0x5e06, 0x0648,
+ 0x5e07, 0x3046,
+ 0x5e08, 0x0d3d,
+ 0x5e09, 0x3047,
+ 0x5e0c, 0x0f10,
+ 0x5e0d, 0x304a,
+ 0x5e0f, 0x159e,
+ 0x5e10, 0x116b,
+ 0x5e11, 0x15a1,
+ 0x5e12, 0x304c,
+ 0x5e14, 0x15a0,
+ 0x5e15, 0x0b82,
+ 0x5e16, 0x0e4e,
+ 0x5e17, 0x304e,
+ 0x5e18, 0x09fa,
+ 0x5e19, 0x159f,
+ 0x5e1a, 0x11e2,
+ 0x5e1b, 0x0476,
+ 0x5e1c, 0x11c3,
+ 0x5e1d, 0x05bc,
+ 0x5e1e, 0x304f,
+ 0x5e25, 0x2143,
+ 0x5e26, 0x057b,
+ 0x5e27, 0x11a0,
+ 0x5e28, 0x3056,
+ 0x5e2b, 0x2129,
+ 0x5e2c, 0x3059,
+ 0x5e2d, 0x0f1c,
+ 0x5e2e, 0x03fa,
+ 0x5e2f, 0x305a,
+ 0x5e31, 0x15a2,
+ 0x5e32, 0x305c,
+ 0x5e33, 0x2277,
+ 0x5e34, 0x305d,
+ 0x5e36, 0x1ea7,
+ 0x5e37, 0x15a5,
+ 0x5e38, 0x04c8,
+ 0x5e39, 0x305f,
+ 0x5e3b, 0x15a3,
+ 0x5e3d, 0x0ab6,
+ 0x5e3e, 0x3061,
+ 0x5e40, 0x2285,
+ 0x5e41, 0x3063,
+ 0x5e42, 0x0ae2,
+ 0x5e43, 0x2384,
+ 0x5e44, 0x15a6,
+ 0x5e45, 0x0696,
+ 0x5e46, 0x3064,
+ 0x5e4c, 0x07e4,
+ 0x5e4d, 0x306a,
+ 0x5e54, 0x15a7,
+ 0x5e55, 0x0b1e,
+ 0x5e56, 0x3071,
+ 0x5e57, 0x2387,
+ 0x5e58, 0x2386,
+ 0x5e59, 0x3072,
+ 0x5e5b, 0x15a8,
+ 0x5e5c, 0x3074,
+ 0x5e5e, 0x15a9,
+ 0x5e5f, 0x2290,
+ 0x5e60, 0x3076,
+ 0x5e61, 0x15aa,
+ 0x5e62, 0x0534,
+ 0x5e63, 0x1e44,
+ 0x5e64, 0x3077,
+ 0x5e6b, 0x1e32,
+ 0x5e6c, 0x2385,
+ 0x5e6d, 0x307e,
+ 0x5e72, 0x06c4,
+ 0x5e73, 0x0bdc,
+ 0x5e74, 0x0b4d,
+ 0x5e75, 0x3083,
+ 0x5e76, 0x0469,
+ 0x5e77, 0x3084,
+ 0x5e78, 0x0f9d,
+ 0x5e79, 0x1f13,
+ 0x5e7a, 0x1813,
+ 0x5e7b, 0x07d8,
+ 0x5e7c, 0x10bc,
+ 0x5e7d, 0x10a9,
+ 0x5e7e, 0x1f73,
+ 0x5e7f, 0x073c,
+ 0x5e80, 0x1631,
+ 0x5e81, 0x3085,
+ 0x5e84, 0x120c,
+ 0x5e85, 0x3088,
+ 0x5e86, 0x0c69,
+ 0x5e87, 0x043c,
+ 0x5e88, 0x3089,
+ 0x5e8a, 0x0535,
+ 0x5e8b, 0x1633,
+ 0x5e8c, 0x308b,
+ 0x5e8f, 0x0fbd,
+ 0x5e90, 0x0a55,
+ 0x5e91, 0x1632,
+ 0x5e92, 0x308e,
+ 0x5e93, 0x096f,
+ 0x5e94, 0x108b,
+ 0x5e95, 0x05b8,
+ 0x5e96, 0x1634,
+ 0x5e97, 0x05cb,
+ 0x5e98, 0x308f,
+ 0x5e99, 0x0af2,
+ 0x5e9a, 0x06f8,
+ 0x5e9b, 0x3090,
+ 0x5e9c, 0x06a9,
+ 0x5e9d, 0x3091,
+ 0x5e9e, 0x0b94,
+ 0x5e9f, 0x066c,
+ 0x5ea0, 0x1636,
+ 0x5ea1, 0x3092,
+ 0x5ea5, 0x1635,
+ 0x5ea6, 0x0607,
+ 0x5ea7, 0x1256,
+ 0x5ea8, 0x3096,
+ 0x5eab, 0x1fe0,
+ 0x5eac, 0x3099,
+ 0x5ead, 0x0e56,
+ 0x5eae, 0x309a,
+ 0x5eb3, 0x163a,
+ 0x5eb4, 0x309f,
+ 0x5eb5, 0x1638,
+ 0x5eb6, 0x0d93,
+ 0x5eb7, 0x0942,
+ 0x5eb8, 0x109e,
+ 0x5eb9, 0x1637,
+ 0x5eba, 0x30a0,
+ 0x5ebe, 0x1639,
+ 0x5ebf, 0x30a4,
+ 0x5ec9, 0x09f7,
+ 0x5eca, 0x09b3,
+ 0x5ecb, 0x30ae,
+ 0x5ed1, 0x163d,
+ 0x5ed2, 0x163c,
+ 0x5ed3, 0x0995,
+ 0x5ed4, 0x30b4,
+ 0x5ed6, 0x0a17,
+ 0x5ed7, 0x30b6,
+ 0x5edb, 0x163e,
+ 0x5edc, 0x30ba,
+ 0x5edf, 0x2087,
+ 0x5ee0, 0x1e78,
+ 0x5ee1, 0x23ae,
+ 0x5ee2, 0x1ef6,
+ 0x5ee3, 0x1f31,
+ 0x5ee4, 0x30bd,
+ 0x5ee8, 0x163f,
+ 0x5ee9, 0x30c1,
+ 0x5eea, 0x1640,
+ 0x5eeb, 0x30c2,
+ 0x5eec, 0x2045,
+ 0x5eed, 0x30c3,
+ 0x5ef3, 0x2178,
+ 0x5ef4, 0x1398,
+ 0x5ef5, 0x30c9,
+ 0x5ef6, 0x0ffc,
+ 0x5ef7, 0x0e53,
+ 0x5ef8, 0x30ca,
+ 0x5efa, 0x0879,
+ 0x5efb, 0x30cc,
+ 0x5efe, 0x14ad,
+ 0x5eff, 0x125b,
+ 0x5f00, 0x0937,
+ 0x5f01, 0x139d,
+ 0x5f02, 0x1073,
+ 0x5f03, 0x0c19,
+ 0x5f04, 0x0b6b,
+ 0x5f05, 0x30cf,
+ 0x5f08, 0x14ae,
+ 0x5f09, 0x30d2,
+ 0x5f0a, 0x0440,
+ 0x5f0b, 0x14f6,
+ 0x5f0c, 0x30d3,
+ 0x5f0f, 0x0d54,
+ 0x5f10, 0x30d6,
+ 0x5f11, 0x14f9,
+ 0x5f12, 0x30d7,
+ 0x5f13, 0x0706,
+ 0x5f14, 0x30d8,
+ 0x5f15, 0x1084,
+ 0x5f16, 0x30d9,
+ 0x5f17, 0x06a0,
+ 0x5f18, 0x07a2,
+ 0x5f19, 0x30da,
+ 0x5f1b, 0x04ff,
+ 0x5f1c, 0x30dc,
+ 0x5f1f, 0x05bd,
+ 0x5f20, 0x1166,
+ 0x5f21, 0x30df,
+ 0x5f25, 0x0adb,
+ 0x5f26, 0x0f3f,
+ 0x5f27, 0x07b6,
+ 0x5f28, 0x30e3,
+ 0x5f29, 0x176f,
+ 0x5f2a, 0x176e,
+ 0x5f2b, 0x30e4,
+ 0x5f2d, 0x1770,
+ 0x5f2e, 0x30e6,
+ 0x5f2f, 0x0e95,
+ 0x5f30, 0x30e7,
+ 0x5f31, 0x0cd0,
+ 0x5f32, 0x30e8,
+ 0x5f33, 0x23f5,
+ 0x5f34, 0x30e9,
+ 0x5f35, 0x2275,
+ 0x5f36, 0x30ea,
+ 0x5f39, 0x0590,
+ 0x5f3a, 0x0c3c,
+ 0x5f3b, 0x30ed,
+ 0x5f3c, 0x1772,
+ 0x5f3d, 0x30ee,
+ 0x5f40, 0x19be,
+ 0x5f41, 0x30f1,
+ 0x5f46, 0x266e,
+ 0x5f47, 0x30f6,
+ 0x5f48, 0x1eb0,
+ 0x5f49, 0x30f7,
+ 0x5f4c, 0x2083,
+ 0x5f4d, 0x30fa,
+ 0x5f4e, 0x2188,
+ 0x5f4f, 0x30fb,
+ 0x5f50, 0x1762,
+ 0x5f51, 0x30fc,
+ 0x5f52, 0x0742,
+ 0x5f53, 0x0592,
+ 0x5f54, 0x30fd,
+ 0x5f55, 0x0a63,
+ 0x5f56, 0x1764,
+ 0x5f57, 0x1763,
+ 0x5f58, 0x1765,
+ 0x5f59, 0x267c,
+ 0x5f5a, 0x30fe,
+ 0x5f5d, 0x1054,
+ 0x5f5e, 0x3101,
+ 0x5f61, 0x15ee,
+ 0x5f62, 0x0f99,
+ 0x5f63, 0x3104,
+ 0x5f64, 0x0e5f,
+ 0x5f65, 0x3105,
+ 0x5f66, 0x100e,
+ 0x5f67, 0x3106,
+ 0x5f69, 0x0491,
+ 0x5f6a, 0x0454,
+ 0x5f6b, 0x3108,
+ 0x5f6c, 0x045b,
+ 0x5f6d, 0x0bae,
+ 0x5f6e, 0x3109,
+ 0x5f70, 0x1164,
+ 0x5f71, 0x1095,
+ 0x5f72, 0x310b,
+ 0x5f73, 0x15e0,
+ 0x5f74, 0x310c,
+ 0x5f77, 0x15e1,
+ 0x5f78, 0x310f,
+ 0x5f79, 0x1062,
+ 0x5f7a, 0x3110,
+ 0x5f7b, 0x04de,
+ 0x5f7c, 0x0434,
+ 0x5f7d, 0x3111,
+ 0x5f80, 0x0eaa,
+ 0x5f81, 0x1198,
+ 0x5f82, 0x15e2,
+ 0x5f83, 0x3114,
+ 0x5f84, 0x08e5,
+ 0x5f85, 0x0580,
+ 0x5f86, 0x3115,
+ 0x5f87, 0x15e3,
+ 0x5f88, 0x0793,
+ 0x5f89, 0x15e4,
+ 0x5f8a, 0x07c7,
+ 0x5f8b, 0x0a70,
+ 0x5f8c, 0x15e5,
+ 0x5f8d, 0x3116,
+ 0x5f90, 0x0fb7,
+ 0x5f91, 0x1fc5,
+ 0x5f92, 0x0e6e,
+ 0x5f93, 0x3119,
+ 0x5f95, 0x15e6,
+ 0x5f96, 0x311b,
+ 0x5f97, 0x05a4,
+ 0x5f98, 0x0b88,
+ 0x5f99, 0x15e7,
+ 0x5f9a, 0x311c,
+ 0x5f9c, 0x15e8,
+ 0x5f9d, 0x311e,
+ 0x5f9e, 0x1ea1,
+ 0x5f9f, 0x311f,
+ 0x5fa0, 0x2393,
+ 0x5fa1, 0x10de,
+ 0x5fa2, 0x3120,
+ 0x5fa8, 0x15e9,
+ 0x5fa9, 0x1f0b,
+ 0x5faa, 0x0fd6,
+ 0x5fab, 0x3126,
+ 0x5fad, 0x15ea,
+ 0x5fae, 0x0eb1,
+ 0x5faf, 0x3128,
+ 0x5fb5, 0x15eb,
+ 0x5fb6, 0x312e,
+ 0x5fb7, 0x05a3,
+ 0x5fb8, 0x312f,
+ 0x5fb9, 0x1e7c,
+ 0x5fba, 0x3130,
+ 0x5fbc, 0x15ec,
+ 0x5fbd, 0x07ea,
+ 0x5fbe, 0x3132,
+ 0x5fc3, 0x0f8f,
+ 0x5fc4, 0x1642,
+ 0x5fc5, 0x0441,
+ 0x5fc6, 0x106b,
+ 0x5fc7, 0x3137,
+ 0x5fc9, 0x1643,
+ 0x5fca, 0x3139,
+ 0x5fcc, 0x083c,
+ 0x5fcd, 0x0ca7,
+ 0x5fce, 0x313b,
+ 0x5fcf, 0x1645,
+ 0x5fd0, 0x1a0c,
+ 0x5fd1, 0x1a0b,
+ 0x5fd2, 0x14f7,
+ 0x5fd3, 0x313c,
+ 0x5fd6, 0x1644,
+ 0x5fd7, 0x11bd,
+ 0x5fd8, 0x0ead,
+ 0x5fd9, 0x0aab,
+ 0x5fda, 0x313f,
+ 0x5fdd, 0x1683,
+ 0x5fde, 0x3142,
+ 0x5fe0, 0x11d1,
+ 0x5fe1, 0x1649,
+ 0x5fe2, 0x3144,
+ 0x5fe4, 0x164a,
+ 0x5fe5, 0x3146,
+ 0x5fe7, 0x10ac,
+ 0x5fe8, 0x3148,
+ 0x5fea, 0x164e,
+ 0x5feb, 0x0979,
+ 0x5fec, 0x314a,
+ 0x5fed, 0x164f,
+ 0x5fee, 0x1647,
+ 0x5fef, 0x314b,
+ 0x5ff1, 0x04e5,
+ 0x5ff2, 0x314d,
+ 0x5ff5, 0x0b51,
+ 0x5ff6, 0x3150,
+ 0x5ff8, 0x1650,
+ 0x5ff9, 0x3152,
+ 0x5ffb, 0x0f8e,
+ 0x5ffc, 0x3154,
+ 0x5ffd, 0x07ad,
+ 0x5ffe, 0x164b,
+ 0x5fff, 0x067b,
+ 0x6000, 0x07c8,
+ 0x6001, 0x0dff,
+ 0x6002, 0x0dc0,
+ 0x6003, 0x1646,
+ 0x6004, 0x1648,
+ 0x6005, 0x164c,
+ 0x6007, 0x3155,
+ 0x600a, 0x1659,
+ 0x600b, 0x3158,
+ 0x600d, 0x1656,
+ 0x600e, 0x1138,
+ 0x600f, 0x1655,
+ 0x6010, 0x315a,
+ 0x6012, 0x0b6e,
+ 0x6013, 0x315c,
+ 0x6014, 0x119b,
+ 0x6015, 0x0b83,
+ 0x6016, 0x0487,
+ 0x6017, 0x315d,
+ 0x6019, 0x1651,
+ 0x601a, 0x315f,
+ 0x601b, 0x1654,
+ 0x601c, 0x09f8,
+ 0x601d, 0x0db1,
+ 0x601e, 0x3160,
+ 0x6020, 0x0582,
+ 0x6021, 0x165b,
+ 0x6022, 0x3162,
+ 0x6025, 0x0824,
+ 0x6026, 0x1653,
+ 0x6027, 0x0f9f,
+ 0x6028, 0x10fc,
+ 0x6029, 0x1657,
+ 0x602a, 0x072f,
+ 0x602b, 0x1658,
+ 0x602c, 0x3165,
+ 0x602f, 0x0c50,
+ 0x6030, 0x3168,
+ 0x6035, 0x1652,
+ 0x6036, 0x316d,
+ 0x603b, 0x1239,
+ 0x603c, 0x1a0d,
+ 0x603d, 0x3172,
+ 0x603f, 0x165a,
+ 0x6040, 0x3174,
+ 0x6041, 0x1a11,
+ 0x6042, 0x1660,
+ 0x6043, 0x0d68,
+ 0x6044, 0x3175,
+ 0x604b, 0x09fe,
+ 0x604c, 0x317c,
+ 0x604d, 0x07e5,
+ 0x604e, 0x317d,
+ 0x6050, 0x0963,
+ 0x6051, 0x317f,
+ 0x6052, 0x079a,
+ 0x6053, 0x3180,
+ 0x6055, 0x0d96,
+ 0x6056, 0x3182,
+ 0x6059, 0x1a12,
+ 0x605a, 0x1a0f,
+ 0x605b, 0x3185,
+ 0x605d, 0x1a0e,
+ 0x605e, 0x3187,
+ 0x6062, 0x07eb,
+ 0x6063, 0x1a13,
+ 0x6064, 0x0fbf,
+ 0x6065, 0x318b,
+ 0x6067, 0x1a10,
+ 0x6068, 0x0795,
+ 0x6069, 0x0636,
+ 0x606a, 0x1661,
+ 0x606b, 0x05f1,
+ 0x606c, 0x0e44,
+ 0x606d, 0x0700,
+ 0x606e, 0x318d,
+ 0x606f, 0x0f0f,
+ 0x6070, 0x0c1e,
+ 0x6071, 0x318e,
+ 0x6073, 0x095f,
+ 0x6074, 0x3190,
+ 0x6076, 0x0630,
+ 0x6077, 0x3192,
+ 0x6078, 0x165c,
+ 0x607a, 0x165f,
+ 0x607b, 0x165e,
+ 0x607c, 0x0b38,
+ 0x607d, 0x1662,
+ 0x607e, 0x3193,
+ 0x607f, 0x10a6,
+ 0x6080, 0x3194,
+ 0x6083, 0x1667,
+ 0x6084, 0x0c41,
+ 0x6085, 0x3197,
+ 0x6089, 0x0f11,
+ 0x608a, 0x319b,
+ 0x608c, 0x1669,
+ 0x608d, 0x076e,
+ 0x608e, 0x319d,
+ 0x6092, 0x1668,
+ 0x6093, 0x31a1,
+ 0x6094, 0x07ef,
+ 0x6095, 0x31a2,
+ 0x6096, 0x1663,
+ 0x6097, 0x31a3,
+ 0x609a, 0x1664,
+ 0x609b, 0x166a,
+ 0x609c, 0x31a6,
+ 0x609d, 0x1666,
+ 0x609e, 0x31a7,
+ 0x609f, 0x0f01,
+ 0x60a0, 0x10ab,
+ 0x60a1, 0x31a8,
+ 0x60a3, 0x07d1,
+ 0x60a4, 0x31aa,
+ 0x60a6, 0x1106,
+ 0x60a7, 0x31ac,
+ 0x60a8, 0x0b5d,
+ 0x60a9, 0x31ad,
+ 0x60ab, 0x1a14,
+ 0x60ac, 0x0fc7,
+ 0x60ad, 0x1665,
+ 0x60ae, 0x31af,
+ 0x60af, 0x0afa,
+ 0x60b0, 0x31b0,
+ 0x60b1, 0x166d,
+ 0x60b2, 0x0418,
+ 0x60b3, 0x31b1,
+ 0x60b4, 0x1672,
+ 0x60b5, 0x23b4,
+ 0x60b6, 0x207e,
+ 0x60b7, 0x31b2,
+ 0x60b8, 0x0835,
+ 0x60b9, 0x31b3,
+ 0x60bb, 0x166c,
+ 0x60bc, 0x05a0,
+ 0x60bd, 0x31b5,
+ 0x60c5, 0x0c66,
+ 0x60c6, 0x1670,
+ 0x60c7, 0x31bd,
+ 0x60ca, 0x08d9,
+ 0x60cb, 0x0ea0,
+ 0x60cc, 0x31c0,
+ 0x60d1, 0x0808,
+ 0x60d2, 0x31c5,
+ 0x60d5, 0x0e3b,
+ 0x60d6, 0x31c8,
+ 0x60d8, 0x166f,
+ 0x60d9, 0x31ca,
+ 0x60da, 0x1671,
+ 0x60db, 0x31cb,
+ 0x60dc, 0x0f14,
+ 0x60dd, 0x166e,
+ 0x60de, 0x31cc,
+ 0x60df, 0x0eb8,
+ 0x60e0, 0x07f2,
+ 0x60e1, 0x1ee3,
+ 0x60e2, 0x31cd,
+ 0x60e6, 0x05cc,
+ 0x60e7, 0x0914,
+ 0x60e8, 0x0499,
+ 0x60e9, 0x04f2,
+ 0x60ea, 0x31d1,
+ 0x60eb, 0x0422,
+ 0x60ec, 0x166b,
+ 0x60ed, 0x0498,
+ 0x60ee, 0x058d,
+ 0x60ef, 0x0738,
+ 0x60f0, 0x0627,
+ 0x60f1, 0x2095,
+ 0x60f2, 0x23bb,
+ 0x60f3, 0x0f58,
+ 0x60f4, 0x1677,
+ 0x60f5, 0x31d2,
+ 0x60f6, 0x07e1,
+ 0x60f7, 0x31d3,
+ 0x60f9, 0x0ca2,
+ 0x60fa, 0x0f95,
+ 0x60fb, 0x23b9,
+ 0x60fc, 0x31d5,
+ 0x6100, 0x1678,
+ 0x6101, 0x0513,
+ 0x6102, 0x31d9,
+ 0x6106, 0x1a15,
+ 0x6107, 0x31dd,
+ 0x6108, 0x10df,
+ 0x6109, 0x10c9,
+ 0x610a, 0x31de,
+ 0x610d, 0x1a16,
+ 0x610e, 0x1679,
+ 0x610f, 0x1069,
+ 0x6110, 0x31e1,
+ 0x6115, 0x1675,
+ 0x6116, 0x31e6,
+ 0x611a, 0x10c3,
+ 0x611b, 0x1e28,
+ 0x611c, 0x23bd,
+ 0x611d, 0x31ea,
+ 0x611f, 0x06cb,
+ 0x6120, 0x1673,
+ 0x6121, 0x31ec,
+ 0x6123, 0x1676,
+ 0x6124, 0x067c,
+ 0x6125, 0x31ee,
+ 0x6126, 0x1674,
+ 0x6127, 0x098d,
+ 0x6128, 0x31ef,
+ 0x612b, 0x167a,
+ 0x612c, 0x31f2,
+ 0x6134, 0x23b5,
+ 0x6135, 0x31fa,
+ 0x6137, 0x23ba,
+ 0x6138, 0x31fc,
+ 0x613e, 0x23b3,
+ 0x613f, 0x10fb,
+ 0x6140, 0x3202,
+ 0x6148, 0x054b,
+ 0x6149, 0x320a,
+ 0x614a, 0x167b,
+ 0x614b, 0x2162,
+ 0x614c, 0x07da,
+ 0x614d, 0x320b,
+ 0x614e, 0x0d30,
+ 0x614f, 0x320c,
+ 0x6151, 0x0d1e,
+ 0x6152, 0x320e,
+ 0x6155, 0x0b20,
+ 0x6156, 0x3211,
+ 0x6158, 0x1e5e,
+ 0x6159, 0x3213,
+ 0x615a, 0x1e5d,
+ 0x615b, 0x3214,
+ 0x615d, 0x1a17,
+ 0x615e, 0x3216,
+ 0x615f, 0x23b7,
+ 0x6160, 0x3217,
+ 0x6162, 0x0aa4,
+ 0x6163, 0x1f2f,
+ 0x6164, 0x24df,
+ 0x6165, 0x3219,
+ 0x6167, 0x07f0,
+ 0x6168, 0x093b,
+ 0x6169, 0x321b,
+ 0x616a, 0x23b2,
+ 0x616b, 0x214e,
+ 0x616c, 0x321c,
+ 0x616e, 0x2052,
+ 0x616f, 0x321e,
+ 0x6170, 0x0ece,
+ 0x6171, 0x321f,
+ 0x6173, 0x23bc,
+ 0x6174, 0x3221,
+ 0x6175, 0x167c,
+ 0x6176, 0x20eb,
+ 0x6177, 0x0943,
+ 0x6178, 0x3222,
+ 0x6182, 0x2232,
+ 0x6183, 0x322c,
+ 0x618a, 0x1e3f,
+ 0x618b, 0x0458,
+ 0x618c, 0x3233,
+ 0x618e, 0x113a,
+ 0x618f, 0x3235,
+ 0x6190, 0x201b,
+ 0x6191, 0x20bc,
+ 0x6192, 0x23be,
+ 0x6193, 0x3236,
+ 0x6194, 0x167e,
+ 0x6195, 0x3237,
+ 0x619a, 0x1eae,
+ 0x619b, 0x323c,
+ 0x619d, 0x1a19,
+ 0x619e, 0x323e,
+ 0x61a4, 0x1efb,
+ 0x61a5, 0x3244,
+ 0x61a7, 0x167f,
+ 0x61a8, 0x0760,
+ 0x61a9, 0x1a18,
+ 0x61aa, 0x3246,
+ 0x61ab, 0x2089,
+ 0x61ac, 0x167d,
+ 0x61ad, 0x3247,
+ 0x61ae, 0x23b1,
+ 0x61af, 0x3248,
+ 0x61b2, 0x21c4,
+ 0x61b3, 0x324b,
+ 0x61b6, 0x2214,
+ 0x61b7, 0x1680,
+ 0x61b8, 0x324e,
+ 0x61be, 0x076d,
+ 0x61bf, 0x3254,
+ 0x61c2, 0x05ed,
+ 0x61c3, 0x3257,
+ 0x61c7, 0x1fde,
+ 0x61c8, 0x0f83,
+ 0x61c9, 0x2223,
+ 0x61ca, 0x03ce,
+ 0x61cb, 0x1a1a,
+ 0x61cc, 0x23b6,
+ 0x61cd, 0x325b,
+ 0x61d1, 0x1a1b,
+ 0x61d2, 0x09ac,
+ 0x61d3, 0x325f,
+ 0x61d4, 0x1681,
+ 0x61d5, 0x3260,
+ 0x61de, 0x268c,
+ 0x61df, 0x24de,
+ 0x61e0, 0x3269,
+ 0x61e3, 0x24e0,
+ 0x61e4, 0x326c,
+ 0x61e6, 0x0b74,
+ 0x61e7, 0x326e,
+ 0x61e8, 0x23b8,
+ 0x61e9, 0x326f,
+ 0x61f2, 0x1e81,
+ 0x61f3, 0x3278,
+ 0x61f5, 0x1682,
+ 0x61f6, 0x1ffe,
+ 0x61f7, 0x1f51,
+ 0x61f8, 0x21e1,
+ 0x61f9, 0x327a,
+ 0x61fa, 0x23b0,
+ 0x61fb, 0x327b,
+ 0x61fc, 0x1fce,
+ 0x61fd, 0x327c,
+ 0x61fe, 0x211e,
+ 0x61ff, 0x13e0,
+ 0x6200, 0x2021,
+ 0x6201, 0x327d,
+ 0x6206, 0x1a1c,
+ 0x6207, 0x24e1,
+ 0x6208, 0x06e5,
+ 0x6209, 0x3282,
+ 0x620a, 0x0efb,
+ 0x620b, 0x18f9,
+ 0x620c, 0x0fb2,
+ 0x620d, 0x0d90,
+ 0x620e, 0x0cb1,
+ 0x620f, 0x0f24,
+ 0x6210, 0x04ee,
+ 0x6211, 0x0ee1,
+ 0x6212, 0x08b5,
+ 0x6213, 0x3283,
+ 0x6214, 0x24a3,
+ 0x6215, 0x169e,
+ 0x6216, 0x0807,
+ 0x6217, 0x18fa,
+ 0x6218, 0x115e,
+ 0x6219, 0x3284,
+ 0x621a, 0x0bfc,
+ 0x621b, 0x18fb,
+ 0x621c, 0x3285,
+ 0x621f, 0x18fc,
+ 0x6220, 0x3288,
+ 0x6221, 0x18fe,
+ 0x6222, 0x18fd,
+ 0x6223, 0x3289,
+ 0x6224, 0x1900,
+ 0x6225, 0x18ff,
+ 0x6226, 0x328a,
+ 0x6227, 0x24a4,
+ 0x6228, 0x328b,
+ 0x622a, 0x08a9,
+ 0x622b, 0x328d,
+ 0x622c, 0x1901,
+ 0x622d, 0x328e,
+ 0x622e, 0x0a65,
+ 0x622f, 0x328f,
+ 0x6230, 0x2273,
+ 0x6231, 0x3290,
+ 0x6232, 0x21b0,
+ 0x6233, 0x0544,
+ 0x6234, 0x057a,
+ 0x6235, 0x3291,
+ 0x6237, 0x07bc,
+ 0x6238, 0x3293,
+ 0x623d, 0x19f4,
+ 0x623e, 0x19f3,
+ 0x623f, 0x065c,
+ 0x6240, 0x0dee,
+ 0x6241, 0x044b,
+ 0x6242, 0x3298,
+ 0x6243, 0x19f5,
+ 0x6244, 0x3299,
+ 0x6247, 0x0d01,
+ 0x6248, 0x19f6,
+ 0x624a, 0x329c,
+ 0x624b, 0x0d6d,
+ 0x624c, 0x14ba,
+ 0x624d, 0x048c,
+ 0x624e, 0x113d,
+ 0x624f, 0x329d,
+ 0x6251, 0x0bea,
+ 0x6252, 0x03d2,
+ 0x6253, 0x0575,
+ 0x6254, 0x0cae,
+ 0x6255, 0x329f,
+ 0x6258, 0x0e81,
+ 0x6259, 0x32a2,
+ 0x625b, 0x0945,
+ 0x625c, 0x32a4,
+ 0x6263, 0x0968,
+ 0x6264, 0x32ab,
+ 0x6266, 0x0c21,
+ 0x6267, 0x11b3,
+ 0x6268, 0x32ad,
+ 0x6269, 0x0994,
+ 0x626a, 0x14bb,
+ 0x626b, 0x0ce1,
+ 0x626c, 0x1018,
+ 0x626d, 0x0b65,
+ 0x626e, 0x03f2,
+ 0x626f, 0x04db,
+ 0x6270, 0x0ca0,
+ 0x6271, 0x32ae,
+ 0x6273, 0x03ed,
+ 0x6274, 0x32b0,
+ 0x6276, 0x0693,
+ 0x6277, 0x32b2,
+ 0x6279, 0x0bbb,
+ 0x627a, 0x32b4,
+ 0x627c, 0x0632,
+ 0x627d, 0x32b6,
+ 0x627e, 0x1173,
+ 0x627f, 0x04f5,
+ 0x6280, 0x082f,
+ 0x6281, 0x32b7,
+ 0x6284, 0x04d2,
+ 0x6285, 0x32ba,
+ 0x6289, 0x0920,
+ 0x628a, 0x03dc,
+ 0x628b, 0x32be,
+ 0x6291, 0x105d,
+ 0x6292, 0x0d7a,
+ 0x6293, 0x1202,
+ 0x6294, 0x32c4,
+ 0x6295, 0x0e67,
+ 0x6296, 0x05f5,
+ 0x6297, 0x0946,
+ 0x6298, 0x117c,
+ 0x6299, 0x32c5,
+ 0x629a, 0x06a2,
+ 0x629b, 0x0b98,
+ 0x629c, 0x32c6,
+ 0x629f, 0x14bc,
+ 0x62a0, 0x0966,
+ 0x62a1, 0x0a7c,
+ 0x62a2, 0x0c3d,
+ 0x62a3, 0x32c9,
+ 0x62a4, 0x07b9,
+ 0x62a5, 0x0411,
+ 0x62a6, 0x32ca,
+ 0x62a8, 0x0bab,
+ 0x62a9, 0x32cc,
+ 0x62ab, 0x0bbc,
+ 0x62ac, 0x0dfa,
+ 0x62ad, 0x32ce,
+ 0x62b1, 0x0410,
+ 0x62b2, 0x32d2,
+ 0x62b5, 0x05b7,
+ 0x62b6, 0x32d5,
+ 0x62b9, 0x0b0b,
+ 0x62ba, 0x32d8,
+ 0x62bb, 0x14bd,
+ 0x62bc, 0x0fe3,
+ 0x62bd, 0x050e,
+ 0x62be, 0x32d9,
+ 0x62bf, 0x0af7,
+ 0x62c0, 0x32da,
+ 0x62c2, 0x0694,
+ 0x62c3, 0x32dc,
+ 0x62c4, 0x11f3,
+ 0x62c5, 0x0584,
+ 0x62c6, 0x04b7,
+ 0x62c7, 0x0b17,
+ 0x62c8, 0x0b4c,
+ 0x62c9, 0x0998,
+ 0x62ca, 0x14be,
+ 0x62cb, 0x32dd,
+ 0x62cc, 0x03f3,
+ 0x62cd, 0x0b85,
+ 0x62ce, 0x0a29,
+ 0x62cf, 0x32de,
+ 0x62d0, 0x072e,
+ 0x62d1, 0x32df,
+ 0x62d2, 0x090b,
+ 0x62d3, 0x0e89,
+ 0x62d4, 0x03d9,
+ 0x62d5, 0x32e0,
+ 0x62d6, 0x0e80,
+ 0x62d7, 0x14c0,
+ 0x62d8, 0x08ff,
+ 0x62d9, 0x121b,
+ 0x62da, 0x14bf,
+ 0x62db, 0x1171,
+ 0x62dc, 0x03e8,
+ 0x62dd, 0x32e1,
+ 0x62df, 0x0b45,
+ 0x62e0, 0x32e3,
+ 0x62e2, 0x0a4a,
+ 0x62e3, 0x0863,
+ 0x62e4, 0x32e5,
+ 0x62e5, 0x109a,
+ 0x62e6, 0x09a4,
+ 0x62e7, 0x0b62,
+ 0x62e8, 0x046d,
+ 0x62e9, 0x1134,
+ 0x62ea, 0x32e6,
+ 0x62ec, 0x0993,
+ 0x62ed, 0x0d5a,
+ 0x62ee, 0x14c1,
+ 0x62ef, 0x119d,
+ 0x62f0, 0x32e8,
+ 0x62f1, 0x0709,
+ 0x62f2, 0x32e9,
+ 0x62f3, 0x0c88,
+ 0x62f4, 0x0d9e,
+ 0x62f5, 0x32ea,
+ 0x62f6, 0x14c3,
+ 0x62f7, 0x094a,
+ 0x62f8, 0x32eb,
+ 0x62fc, 0x0bd3,
+ 0x62fd, 0x1204,
+ 0x62fe, 0x0d47,
+ 0x62ff, 0x0b26,
+ 0x6300, 0x32ef,
+ 0x6301, 0x04fb,
+ 0x6302, 0x072b,
+ 0x6303, 0x32f0,
+ 0x6307, 0x11b7,
+ 0x6308, 0x194e,
+ 0x6309, 0x03bf,
+ 0x630a, 0x32f4,
+ 0x630e, 0x0973,
+ 0x630f, 0x32f8,
+ 0x6311, 0x0e47,
+ 0x6312, 0x32fa,
+ 0x6316, 0x0e8b,
+ 0x6317, 0x32fe,
+ 0x631a, 0x11be,
+ 0x631b, 0x0a75,
+ 0x631c, 0x3301,
+ 0x631d, 0x0edd,
+ 0x631e, 0x0df5,
+ 0x631f, 0x0f79,
+ 0x6320, 0x0b36,
+ 0x6321, 0x0593,
+ 0x6322, 0x14c2,
+ 0x6323, 0x1196,
+ 0x6324, 0x082a,
+ 0x6325, 0x07e8,
+ 0x6326, 0x3302,
+ 0x6328, 0x03af,
+ 0x6329, 0x3304,
+ 0x632a, 0x0b73,
+ 0x632b, 0x056f,
+ 0x632c, 0x3305,
+ 0x632f, 0x1192,
+ 0x6330, 0x3308,
+ 0x6332, 0x194f,
+ 0x6333, 0x330a,
+ 0x6339, 0x14c4,
+ 0x633a, 0x0e57,
+ 0x633b, 0x3310,
+ 0x633d, 0x0e9d,
+ 0x633e, 0x21d1,
+ 0x633f, 0x3312,
+ 0x6342, 0x0ef5,
+ 0x6343, 0x14c6,
+ 0x6344, 0x3315,
+ 0x6345, 0x0e62,
+ 0x6346, 0x0991,
+ 0x6347, 0x3316,
+ 0x6349, 0x121a,
+ 0x634a, 0x3318,
+ 0x634b, 0x14c5,
+ 0x634c, 0x03d1,
+ 0x634d, 0x076b,
+ 0x634e, 0x0d0c,
+ 0x634f, 0x0b56,
+ 0x6350, 0x0917,
+ 0x6351, 0x3319,
+ 0x6355, 0x047d,
+ 0x6356, 0x331d,
+ 0x635e, 0x09b7,
+ 0x635f, 0x0de5,
+ 0x6360, 0x3325,
+ 0x6361, 0x0864,
+ 0x6362, 0x07d0,
+ 0x6363, 0x0598,
+ 0x6364, 0x3326,
+ 0x6367, 0x0bb6,
+ 0x6368, 0x211c,
+ 0x6369, 0x14d0,
+ 0x636a, 0x3329,
+ 0x636b, 0x235d,
+ 0x636c, 0x332a,
+ 0x636d, 0x14cd,
+ 0x636e, 0x090c,
+ 0x636f, 0x332b,
+ 0x6371, 0x14c9,
+ 0x6372, 0x2682,
+ 0x6373, 0x332d,
+ 0x6376, 0x053a,
+ 0x6377, 0x08ae,
+ 0x6378, 0x3330,
+ 0x637a, 0x14ca,
+ 0x637b, 0x0b50,
+ 0x637c, 0x3332,
+ 0x6380, 0x0f33,
+ 0x6381, 0x3336,
+ 0x6382, 0x05c1,
+ 0x6383, 0x210d,
+ 0x6384, 0x205a,
+ 0x6385, 0x3337,
+ 0x6387, 0x061d,
+ 0x6388, 0x0d71,
+ 0x6389, 0x05d5,
+ 0x638a, 0x14cf,
+ 0x638b, 0x3339,
+ 0x638c, 0x1167,
+ 0x638d, 0x333a,
+ 0x638e, 0x14cb,
+ 0x638f, 0x0e20,
+ 0x6390, 0x0c1d,
+ 0x6391, 0x333b,
+ 0x6392, 0x0b86,
+ 0x6393, 0x333c,
+ 0x6396, 0x103b,
+ 0x6397, 0x333f,
+ 0x6398, 0x0921,
+ 0x6399, 0x3340,
+ 0x63a0, 0x0a7a,
+ 0x63a1, 0x3347,
+ 0x63a2, 0x0e10,
+ 0x63a3, 0x04dd,
+ 0x63a4, 0x3348,
+ 0x63a5, 0x08a4,
+ 0x63a6, 0x3349,
+ 0x63a7, 0x0965,
+ 0x63a8, 0x0e77,
+ 0x63a9, 0x1003,
+ 0x63aa, 0x056e,
+ 0x63ab, 0x334a,
+ 0x63ac, 0x14ce,
+ 0x63ad, 0x14c7,
+ 0x63ae, 0x14d1,
+ 0x63af, 0x334b,
+ 0x63b0, 0x1950,
+ 0x63b1, 0x334c,
+ 0x63b3, 0x0a57,
+ 0x63b4, 0x14cc,
+ 0x63b5, 0x334e,
+ 0x63b7, 0x11bf,
+ 0x63b8, 0x0588,
+ 0x63b9, 0x3350,
+ 0x63ba, 0x04bb,
+ 0x63bb, 0x3351,
+ 0x63bc, 0x14d2,
+ 0x63bd, 0x3352,
+ 0x63be, 0x14dc,
+ 0x63bf, 0x3353,
+ 0x63c0, 0x1f8d,
+ 0x63c1, 0x3354,
+ 0x63c4, 0x14d7,
+ 0x63c5, 0x3357,
+ 0x63c6, 0x14db,
+ 0x63c7, 0x3358,
+ 0x63c9, 0x0cbb,
+ 0x63ca, 0x335a,
+ 0x63cd, 0x123e,
+ 0x63ce, 0x14d9,
+ 0x63cf, 0x0aed,
+ 0x63d0, 0x0e34,
+ 0x63d1, 0x335d,
+ 0x63d2, 0x04ac,
+ 0x63d3, 0x335e,
+ 0x63d6, 0x1045,
+ 0x63d7, 0x3361,
+ 0x63da, 0x21ff,
+ 0x63db, 0x3364,
+ 0x63de, 0x14d8,
+ 0x63df, 0x3367,
+ 0x63e0, 0x14d5,
+ 0x63e1, 0x0ee4,
+ 0x63e2, 0x3368,
+ 0x63e3, 0x052a,
+ 0x63e4, 0x3369,
+ 0x63e9, 0x0938,
+ 0x63ea, 0x08ed,
+ 0x63eb, 0x336e,
+ 0x63ed, 0x08a3,
+ 0x63ee, 0x1f58,
+ 0x63ef, 0x3370,
+ 0x63f2, 0x14d3,
+ 0x63f3, 0x3373,
+ 0x63f4, 0x10f1,
+ 0x63f5, 0x3374,
+ 0x63f6, 0x14c8,
+ 0x63f7, 0x3375,
+ 0x63f8, 0x14d4,
+ 0x63f9, 0x3376,
+ 0x63fd, 0x09aa,
+ 0x63fe, 0x337a,
+ 0x63ff, 0x14d6,
+ 0x6400, 0x04ba,
+ 0x6401, 0x06e4,
+ 0x6402, 0x0a4e,
+ 0x6403, 0x337b,
+ 0x6405, 0x0892,
+ 0x6406, 0x337d,
+ 0x640b, 0x14df,
+ 0x640c, 0x14e2,
+ 0x640d, 0x215b,
+ 0x640e, 0x3382,
+ 0x640f, 0x0472,
+ 0x6410, 0x0527,
+ 0x6411, 0x3383,
+ 0x6413, 0x056d,
+ 0x6414, 0x0cdf,
+ 0x6415, 0x3385,
+ 0x6417, 0x1eb6,
+ 0x6418, 0x3387,
+ 0x641b, 0x14e0,
+ 0x641c, 0x0dc6,
+ 0x641d, 0x338a,
+ 0x641e, 0x06de,
+ 0x641f, 0x338b,
+ 0x6420, 0x14e1,
+ 0x6421, 0x14e4,
+ 0x6422, 0x338c,
+ 0x6426, 0x14e3,
+ 0x6427, 0x3390,
+ 0x642a, 0x0e15,
+ 0x642b, 0x3393,
+ 0x642c, 0x03ec,
+ 0x642d, 0x0571,
+ 0x642e, 0x3394,
+ 0x6434, 0x1736,
+ 0x6435, 0x339a,
+ 0x6436, 0x20db,
+ 0x6437, 0x339b,
+ 0x643a, 0x0f7a,
+ 0x643b, 0x339e,
+ 0x643d, 0x04b2,
+ 0x643e, 0x33a0,
+ 0x643f, 0x1951,
+ 0x6440, 0x33a1,
+ 0x6441, 0x14de,
+ 0x6442, 0x33a2,
+ 0x6444, 0x0d1c,
+ 0x6445, 0x14dd,
+ 0x6446, 0x03e5,
+ 0x6447, 0x1028,
+ 0x6448, 0x0460,
+ 0x6449, 0x33a4,
+ 0x644a, 0x0e02,
+ 0x644b, 0x33a5,
+ 0x6451, 0x2360,
+ 0x6452, 0x14da,
+ 0x6453, 0x33ab,
+ 0x6454, 0x0d99,
+ 0x6455, 0x33ac,
+ 0x6458, 0x114b,
+ 0x6459, 0x33af,
+ 0x645c, 0x2361,
+ 0x645d, 0x33b2,
+ 0x645e, 0x14e5,
+ 0x645f, 0x2040,
+ 0x6460, 0x33b3,
+ 0x6467, 0x0560,
+ 0x6468, 0x33ba,
+ 0x6469, 0x0b09,
+ 0x646a, 0x33bb,
+ 0x646d, 0x14e7,
+ 0x646e, 0x33be,
+ 0x646f, 0x228e,
+ 0x6470, 0x33bf,
+ 0x6473, 0x1fdf,
+ 0x6474, 0x33c2,
+ 0x6476, 0x235e,
+ 0x6477, 0x33c4,
+ 0x6478, 0x0b03,
+ 0x647a, 0x14e9,
+ 0x647b, 0x1e6a,
+ 0x647c, 0x33c5,
+ 0x6482, 0x0a15,
+ 0x6483, 0x33cb,
+ 0x6484, 0x14e6,
+ 0x6485, 0x091e,
+ 0x6486, 0x33cc,
+ 0x6487, 0x0bd1,
+ 0x6488, 0x2002,
+ 0x6489, 0x33cd,
+ 0x6491, 0x04ea,
+ 0x6492, 0x0cd1,
+ 0x6493, 0x2093,
+ 0x6494, 0x33d5,
+ 0x6495, 0x0daf,
+ 0x6496, 0x14e8,
+ 0x6497, 0x33d6,
+ 0x6499, 0x14ec,
+ 0x649a, 0x33d8,
+ 0x649e, 0x120f,
+ 0x649f, 0x235f,
+ 0x64a0, 0x33dc,
+ 0x64a3, 0x1eac,
+ 0x64a4, 0x04dc,
+ 0x64a5, 0x1e54,
+ 0x64a6, 0x33df,
+ 0x64a9, 0x0a0c,
+ 0x64aa, 0x33e2,
+ 0x64ab, 0x1f08,
+ 0x64ac, 0x0c48,
+ 0x64ad, 0x046c,
+ 0x64ae, 0x056c,
+ 0x64af, 0x33e3,
+ 0x64b0, 0x1208,
+ 0x64b1, 0x33e4,
+ 0x64b2, 0x20c0,
+ 0x64b3, 0x2362,
+ 0x64b4, 0x33e5,
+ 0x64b5, 0x0b4f,
+ 0x64b6, 0x33e6,
+ 0x64b7, 0x14ea,
+ 0x64b9, 0x33e7,
+ 0x64ba, 0x14ed,
+ 0x64bb, 0x2160,
+ 0x64bc, 0x076a,
+ 0x64bd, 0x33e8,
+ 0x64be, 0x219d,
+ 0x64bf, 0x1f8e,
+ 0x64c0, 0x14ee,
+ 0x64c1, 0x222d,
+ 0x64c2, 0x09c9,
+ 0x64c3, 0x33e9,
+ 0x64c4, 0x2047,
+ 0x64c5, 0x0cfc,
+ 0x64c6, 0x33ea,
+ 0x64c7, 0x2262,
+ 0x64c8, 0x33eb,
+ 0x64ca, 0x1f67,
+ 0x64cb, 0x1eb2,
+ 0x64cc, 0x33ed,
+ 0x64cd, 0x04a0,
+ 0x64ce, 0x0c63,
+ 0x64cf, 0x33ee,
+ 0x64d0, 0x14ef,
+ 0x64d1, 0x33ef,
+ 0x64d2, 0x0c59,
+ 0x64d3, 0x33f0,
+ 0x64d4, 0x1ea9,
+ 0x64d5, 0x33f1,
+ 0x64d7, 0x14f0,
+ 0x64d8, 0x1952,
+ 0x64d9, 0x33f3,
+ 0x64da, 0x1fcc,
+ 0x64db, 0x33f4,
+ 0x64de, 0x0dc8,
+ 0x64df, 0x33f7,
+ 0x64e0, 0x1f72,
+ 0x64e1, 0x33f8,
+ 0x64e2, 0x14f2,
+ 0x64e3, 0x33f9,
+ 0x64e4, 0x14f1,
+ 0x64e5, 0x33fa,
+ 0x64e6, 0x0488,
+ 0x64e7, 0x33fb,
+ 0x64ec, 0x2098,
+ 0x64ed, 0x3400,
+ 0x64ef, 0x1e52,
+ 0x64f0, 0x20a4,
+ 0x64f1, 0x1f1c,
+ 0x64f2, 0x228f,
+ 0x64f3, 0x3402,
+ 0x64f4, 0x1fed,
+ 0x64f5, 0x3403,
+ 0x64f7, 0x2365,
+ 0x64f8, 0x3405,
+ 0x64fa, 0x1e2d,
+ 0x64fb, 0x2152,
+ 0x64fc, 0x2366,
+ 0x64fd, 0x3407,
+ 0x64fe, 0x20fa,
+ 0x64ff, 0x3408,
+ 0x6500, 0x0b8b,
+ 0x6501, 0x3409,
+ 0x6504, 0x2363,
+ 0x6505, 0x340c,
+ 0x6506, 0x209a,
+ 0x6507, 0x340d,
+ 0x6509, 0x14f3,
+ 0x650a, 0x340f,
+ 0x650f, 0x203c,
+ 0x6510, 0x3414,
+ 0x6512, 0x111f,
+ 0x6513, 0x3416,
+ 0x6514, 0x1ff6,
+ 0x6515, 0x3417,
+ 0x6516, 0x2364,
+ 0x6517, 0x3418,
+ 0x6518, 0x0c9c,
+ 0x6519, 0x1e69,
+ 0x651a, 0x3419,
+ 0x651b, 0x2367,
+ 0x651c, 0x341a,
+ 0x651d, 0x211d,
+ 0x651e, 0x341b,
+ 0x6522, 0x2259,
+ 0x6523, 0x2056,
+ 0x6524, 0x2163,
+ 0x6525, 0x14f4,
+ 0x6526, 0x341f,
+ 0x652a, 0x1fa9,
+ 0x652b, 0x091f,
+ 0x652c, 0x1ffc,
+ 0x652d, 0x3423,
+ 0x652e, 0x14f5,
+ 0x652f, 0x11a6,
+ 0x6530, 0x3424,
+ 0x6534, 0x1909,
+ 0x6535, 0x1966,
+ 0x6536, 0x0d6c,
+ 0x6537, 0x3428,
+ 0x6538, 0x12b2,
+ 0x6539, 0x06bf,
+ 0x653a, 0x3429,
+ 0x653b, 0x06fe,
+ 0x653c, 0x342a,
+ 0x653e, 0x0662,
+ 0x653f, 0x119f,
+ 0x6540, 0x342c,
+ 0x6545, 0x0723,
+ 0x6546, 0x3431,
+ 0x6548, 0x0f72,
+ 0x6549, 0x1ccb,
+ 0x654a, 0x3433,
+ 0x654c, 0x05b1,
+ 0x654d, 0x3435,
+ 0x654f, 0x0af9,
+ 0x6550, 0x3437,
+ 0x6551, 0x08f7,
+ 0x6552, 0x3438,
+ 0x6555, 0x1967,
+ 0x6556, 0x03c8,
+ 0x6557, 0x1e2e,
+ 0x6558, 0x343b,
+ 0x6559, 0x089d,
+ 0x655a, 0x343c,
+ 0x655b, 0x09fb,
+ 0x655c, 0x343d,
+ 0x655d, 0x043f,
+ 0x655e, 0x04cd,
+ 0x655f, 0x343e,
+ 0x6562, 0x06cd,
+ 0x6563, 0x0cdb,
+ 0x6564, 0x3441,
+ 0x6566, 0x0617,
+ 0x6567, 0x3443,
+ 0x656b, 0x1968,
+ 0x656c, 0x08e3,
+ 0x656d, 0x3447,
+ 0x6570, 0x0d94,
+ 0x6571, 0x344a,
+ 0x6572, 0x0c40,
+ 0x6573, 0x344b,
+ 0x6574, 0x119c,
+ 0x6575, 0x1ebc,
+ 0x6576, 0x344c,
+ 0x6577, 0x0690,
+ 0x6578, 0x2142,
+ 0x6579, 0x344d,
+ 0x6582, 0x201e,
+ 0x6583, 0x1e43,
+ 0x6584, 0x3456,
+ 0x6587, 0x0ed3,
+ 0x6588, 0x3459,
+ 0x658b, 0x114c,
+ 0x658c, 0x045c,
+ 0x658d, 0x345c,
+ 0x6590, 0x19c1,
+ 0x6591, 0x03ea,
+ 0x6592, 0x345f,
+ 0x6593, 0x19c3,
+ 0x6594, 0x3460,
+ 0x6595, 0x24d4,
+ 0x6596, 0x3461,
+ 0x6597, 0x05f6,
+ 0x6598, 0x3462,
+ 0x6599, 0x0a18,
+ 0x659a, 0x3463,
+ 0x659b, 0x1d56,
+ 0x659c, 0x0f7c,
+ 0x659d, 0x3464,
+ 0x659f, 0x1186,
+ 0x65a0, 0x3466,
+ 0x65a1, 0x0ee2,
+ 0x65a2, 0x3467,
+ 0x65a4, 0x08c0,
+ 0x65a5, 0x0507,
+ 0x65a6, 0x3469,
+ 0x65a7, 0x06a6,
+ 0x65a8, 0x346a,
+ 0x65a9, 0x1157,
+ 0x65aa, 0x346b,
+ 0x65ab, 0x1a29,
+ 0x65ac, 0x226f,
+ 0x65ad, 0x060e,
+ 0x65ae, 0x346c,
+ 0x65af, 0x0dae,
+ 0x65b0, 0x0f8d,
+ 0x65b1, 0x346d,
+ 0x65b7, 0x1ed7,
+ 0x65b8, 0x3473,
+ 0x65b9, 0x065a,
+ 0x65ba, 0x3474,
+ 0x65bc, 0x19c4,
+ 0x65bd, 0x0d40,
+ 0x65be, 0x3476,
+ 0x65c1, 0x0b95,
+ 0x65c2, 0x3479,
+ 0x65c3, 0x19c7,
+ 0x65c4, 0x19c6,
+ 0x65c5, 0x0a6a,
+ 0x65c6, 0x19c5,
+ 0x65c7, 0x347a,
+ 0x65cb, 0x0fc8,
+ 0x65cc, 0x19c8,
+ 0x65cd, 0x347e,
+ 0x65ce, 0x19c9,
+ 0x65cf, 0x1242,
+ 0x65d0, 0x347f,
+ 0x65d2, 0x19ca,
+ 0x65d3, 0x3481,
+ 0x65d6, 0x19cb,
+ 0x65d7, 0x0c0b,
+ 0x65d8, 0x3484,
+ 0x65e0, 0x0eed,
+ 0x65e1, 0x348c,
+ 0x65e2, 0x083b,
+ 0x65e3, 0x348d,
+ 0x65e5, 0x0cb0,
+ 0x65e6, 0x058a,
+ 0x65e7, 0x08f8,
+ 0x65e8, 0x11bb,
+ 0x65e9, 0x112a,
+ 0x65ea, 0x348f,
+ 0x65ec, 0x0fd7,
+ 0x65ed, 0x0fbc,
+ 0x65ee, 0x190a,
+ 0x65f1, 0x076c,
+ 0x65f2, 0x3491,
+ 0x65f6, 0x0d48,
+ 0x65f7, 0x0982,
+ 0x65f8, 0x3495,
+ 0x65fa, 0x0eab,
+ 0x65fb, 0x3497,
+ 0x6600, 0x1912,
+ 0x6601, 0x349c,
+ 0x6602, 0x03c5,
+ 0x6603, 0x1910,
+ 0x6604, 0x349d,
+ 0x6606, 0x0990,
+ 0x6607, 0x349f,
+ 0x660a, 0x190d,
+ 0x660b, 0x34a2,
+ 0x660c, 0x04c4,
+ 0x660d, 0x34a3,
+ 0x660e, 0x0afc,
+ 0x660f, 0x07fd,
+ 0x6610, 0x34a4,
+ 0x6613, 0x105e,
+ 0x6614, 0x0f03,
+ 0x6615, 0x1911,
+ 0x6616, 0x34a7,
+ 0x6619, 0x190e,
+ 0x661a, 0x34aa,
+ 0x661d, 0x1915,
+ 0x661e, 0x34ad,
+ 0x661f, 0x0f92,
+ 0x6620, 0x1098,
+ 0x6621, 0x34ae,
+ 0x6625, 0x053d,
+ 0x6626, 0x34b2,
+ 0x6627, 0x0ac6,
+ 0x6628, 0x124f,
+ 0x6629, 0x34b3,
+ 0x662d, 0x1172,
+ 0x662e, 0x34b7,
+ 0x662f, 0x0d5e,
+ 0x6630, 0x34b8,
+ 0x6631, 0x1917,
+ 0x6632, 0x34b9,
+ 0x6634, 0x1916,
+ 0x6635, 0x1919,
+ 0x6636, 0x1918,
+ 0x6637, 0x34bb,
+ 0x663c, 0x11e6,
+ 0x663d, 0x34c0,
+ 0x663e, 0x0f41,
+ 0x663f, 0x34c1,
+ 0x6641, 0x191d,
+ 0x6642, 0x212d,
+ 0x6643, 0x07e3,
+ 0x6644, 0x34c3,
+ 0x664b, 0x08cb,
+ 0x664c, 0x0d07,
+ 0x664d, 0x34ca,
+ 0x664f, 0x191e,
+ 0x6650, 0x34cc,
+ 0x6652, 0x0cf2,
+ 0x6653, 0x0f6b,
+ 0x6654, 0x191c,
+ 0x6655, 0x1111,
+ 0x6656, 0x191f,
+ 0x6657, 0x1921,
+ 0x6658, 0x34ce,
+ 0x665a, 0x0e9e,
+ 0x665b, 0x34d0,
+ 0x665d, 0x229b,
+ 0x665e, 0x34d2,
+ 0x665f, 0x191b,
+ 0x6660, 0x34d3,
+ 0x6661, 0x1920,
+ 0x6662, 0x34d4,
+ 0x6664, 0x0efd,
+ 0x6665, 0x34d6,
+ 0x6666, 0x07f3,
+ 0x6667, 0x34d7,
+ 0x6668, 0x04e4,
+ 0x6669, 0x34d8,
+ 0x666e, 0x0bf4,
+ 0x666f, 0x08df,
+ 0x6670, 0x0f09,
+ 0x6671, 0x34dd,
+ 0x6674, 0x0c64,
+ 0x6675, 0x34e0,
+ 0x6676, 0x08d6,
+ 0x6677, 0x1922,
+ 0x6678, 0x34e1,
+ 0x667a, 0x11c6,
+ 0x667b, 0x34e3,
+ 0x667e, 0x0a09,
+ 0x667f, 0x34e6,
+ 0x6682, 0x1120,
+ 0x6683, 0x34e9,
+ 0x6684, 0x1923,
+ 0x6685, 0x34ea,
+ 0x6687, 0x0f2b,
+ 0x6688, 0x2256,
+ 0x6689, 0x24a8,
+ 0x668a, 0x34ec,
+ 0x668c, 0x1924,
+ 0x668d, 0x34ee,
+ 0x6691, 0x0d85,
+ 0x6692, 0x34f2,
+ 0x6696, 0x0b70,
+ 0x6697, 0x03c0,
+ 0x6698, 0x34f6,
+ 0x669d, 0x1926,
+ 0x669e, 0x34fb,
+ 0x66a2, 0x1e79,
+ 0x66a3, 0x34ff,
+ 0x66a7, 0x1925,
+ 0x66a8, 0x1cdd,
+ 0x66a9, 0x3503,
+ 0x66ab, 0x225a,
+ 0x66ac, 0x3505,
+ 0x66ae, 0x0b1d,
+ 0x66af, 0x3507,
+ 0x66b4, 0x0412,
+ 0x66b5, 0x350c,
+ 0x66b9, 0x175b,
+ 0x66ba, 0x3510,
+ 0x66be, 0x1927,
+ 0x66bf, 0x3514,
+ 0x66c4, 0x24a7,
+ 0x66c5, 0x3519,
+ 0x66c6, 0x2686,
+ 0x66c7, 0x24a6,
+ 0x66c8, 0x351a,
+ 0x66c9, 0x21ce,
+ 0x66ca, 0x351b,
+ 0x66d6, 0x24a9,
+ 0x66d7, 0x3527,
+ 0x66d9, 0x0d86,
+ 0x66da, 0x3529,
+ 0x66db, 0x1928,
+ 0x66dd, 0x0bf7,
+ 0x66de, 0x352a,
+ 0x66e0, 0x1fe7,
+ 0x66e1, 0x352c,
+ 0x66e6, 0x192a,
+ 0x66e7, 0x3531,
+ 0x66e9, 0x192b,
+ 0x66ea, 0x3533,
+ 0x66ec, 0x2112,
+ 0x66ed, 0x3535,
+ 0x66f0, 0x10fe,
+ 0x66f1, 0x3538,
+ 0x66f2, 0x0c77,
+ 0x66f3, 0x103e,
+ 0x66f4, 0x06f7,
+ 0x66f5, 0x3539,
+ 0x66f7, 0x1914,
+ 0x66f8, 0x213c,
+ 0x66f9, 0x04a3,
+ 0x66fa, 0x353b,
+ 0x66fc, 0x0aa3,
+ 0x66fd, 0x353d,
+ 0x66fe, 0x113b,
+ 0x66ff, 0x0e39,
+ 0x6700, 0x124b,
+ 0x6701, 0x353e,
+ 0x6703, 0x1f5c,
+ 0x6704, 0x3540,
+ 0x6708, 0x1105,
+ 0x6709, 0x10b5,
+ 0x670a, 0x1973,
+ 0x670b, 0x0bb4,
+ 0x670c, 0x3544,
+ 0x670d, 0x069b,
+ 0x670e, 0x3545,
+ 0x6710, 0x1984,
+ 0x6711, 0x3547,
+ 0x6714, 0x0dac,
+ 0x6715, 0x198e,
+ 0x6716, 0x354a,
+ 0x6717, 0x09b5,
+ 0x6718, 0x354b,
+ 0x671b, 0x0eac,
+ 0x671c, 0x354e,
+ 0x671d, 0x04d4,
+ 0x671e, 0x354f,
+ 0x671f, 0x0bf9,
+ 0x6720, 0x3550,
+ 0x6726, 0x19ac,
+ 0x6727, 0x24c4,
+ 0x6728, 0x0b21,
+ 0x6729, 0x3556,
+ 0x672a, 0x0ec3,
+ 0x672b, 0x0b0c,
+ 0x672c, 0x0427,
+ 0x672d, 0x1140,
+ 0x672e, 0x3557,
+ 0x672f, 0x0d8c,
+ 0x6730, 0x3558,
+ 0x6731, 0x11eb,
+ 0x6732, 0x3559,
+ 0x6734, 0x0bf2,
+ 0x6735, 0x0623,
+ 0x6736, 0x355b,
+ 0x673a, 0x080f,
+ 0x673b, 0x355f,
+ 0x673d, 0x0fab,
+ 0x673e, 0x3561,
+ 0x6740, 0x0cea,
+ 0x6741, 0x3563,
+ 0x6742, 0x1116,
+ 0x6743, 0x0c83,
+ 0x6744, 0x3564,
+ 0x6746, 0x06c6,
+ 0x6747, 0x3566,
+ 0x6748, 0x1854,
+ 0x6749, 0x0cf5,
+ 0x674a, 0x3567,
+ 0x674c, 0x1851,
+ 0x674d, 0x3569,
+ 0x674e, 0x09d9,
+ 0x674f, 0x0f9e,
+ 0x6750, 0x048b,
+ 0x6751, 0x0568,
+ 0x6752, 0x356a,
+ 0x6753, 0x1852,
+ 0x6754, 0x356b,
+ 0x6756, 0x1169,
+ 0x6757, 0x356d,
+ 0x675c, 0x0604,
+ 0x675d, 0x3572,
+ 0x675e, 0x1853,
+ 0x675f, 0x0d8f,
+ 0x6760, 0x06d7,
+ 0x6761, 0x0e48,
+ 0x6762, 0x3573,
+ 0x6765, 0x099f,
+ 0x6766, 0x3576,
+ 0x6768, 0x1017,
+ 0x6769, 0x1855,
+ 0x676a, 0x1858,
+ 0x676b, 0x3578,
+ 0x676d, 0x0773,
+ 0x676e, 0x357a,
+ 0x676f, 0x0416,
+ 0x6770, 0x08ad,
+ 0x6771, 0x1ecc,
+ 0x6772, 0x190f,
+ 0x6773, 0x1859,
+ 0x6774, 0x357b,
+ 0x6775, 0x185c,
+ 0x6776, 0x357c,
+ 0x6777, 0x1861,
+ 0x6778, 0x357d,
+ 0x677c, 0x1862,
+ 0x677d, 0x3581,
+ 0x677e, 0x0dbe,
+ 0x677f, 0x03f0,
+ 0x6780, 0x3582,
+ 0x6781, 0x081e,
+ 0x6782, 0x3583,
+ 0x6784, 0x0712,
+ 0x6785, 0x3585,
+ 0x6787, 0x1857,
+ 0x6788, 0x3587,
+ 0x6789, 0x0ea8,
+ 0x678a, 0x3588,
+ 0x678b, 0x1860,
+ 0x678c, 0x3589,
+ 0x6790, 0x0f05,
+ 0x6791, 0x358d,
+ 0x6795, 0x118e,
+ 0x6796, 0x3591,
+ 0x6797, 0x0a1f,
+ 0x6798, 0x185a,
+ 0x6799, 0x3592,
+ 0x679a, 0x0abb,
+ 0x679b, 0x3593,
+ 0x679c, 0x0754,
+ 0x679d, 0x11a5,
+ 0x679e, 0x185e,
+ 0x679f, 0x3594,
+ 0x67a2, 0x0d77,
+ 0x67a3, 0x1129,
+ 0x67a4, 0x3597,
+ 0x67a5, 0x1856,
+ 0x67a6, 0x3598,
+ 0x67a7, 0x185b,
+ 0x67a8, 0x185d,
+ 0x67a9, 0x3599,
+ 0x67aa, 0x0c36,
+ 0x67ab, 0x0680,
+ 0x67ac, 0x359a,
+ 0x67ad, 0x185f,
+ 0x67ae, 0x359b,
+ 0x67af, 0x096a,
+ 0x67b0, 0x1868,
+ 0x67b1, 0x359c,
+ 0x67b3, 0x186d,
+ 0x67b4, 0x359e,
+ 0x67b5, 0x186b,
+ 0x67b6, 0x084f,
+ 0x67b7, 0x0842,
+ 0x67b8, 0x1871,
+ 0x67b9, 0x359f,
+ 0x67c1, 0x1874,
+ 0x67c2, 0x35a7,
+ 0x67c3, 0x1870,
+ 0x67c4, 0x0463,
+ 0x67c5, 0x35a8,
+ 0x67cf, 0x03e3,
+ 0x67d0, 0x0b16,
+ 0x67d1, 0x06c7,
+ 0x67d2, 0x0c01,
+ 0x67d3, 0x0c99,
+ 0x67d4, 0x0cbc,
+ 0x67d5, 0x35b2,
+ 0x67d8, 0x1865,
+ 0x67d9, 0x186a,
+ 0x67da, 0x186c,
+ 0x67db, 0x35b5,
+ 0x67dc, 0x074a,
+ 0x67dd, 0x186e,
+ 0x67de, 0x1252,
+ 0x67df, 0x35b6,
+ 0x67e0, 0x0b5e,
+ 0x67e1, 0x35b7,
+ 0x67e2, 0x1872,
+ 0x67e3, 0x35b8,
+ 0x67e5, 0x04b0,
+ 0x67e6, 0x35ba,
+ 0x67e9, 0x1867,
+ 0x67ea, 0x35bd,
+ 0x67ec, 0x0860,
+ 0x67ed, 0x35bf,
+ 0x67ef, 0x094f,
+ 0x67f0, 0x1863,
+ 0x67f1, 0x11f8,
+ 0x67f2, 0x35c1,
+ 0x67f3, 0x0a41,
+ 0x67f4, 0x04b8,
+ 0x67f5, 0x35c2,
+ 0x67fd, 0x1875,
+ 0x67fe, 0x35ca,
+ 0x67ff, 0x0d58,
+ 0x6800, 0x186f,
+ 0x6801, 0x35cb,
+ 0x6805, 0x1145,
+ 0x6806, 0x35cf,
+ 0x6807, 0x0453,
+ 0x6808, 0x115c,
+ 0x6809, 0x1864,
+ 0x680a, 0x1866,
+ 0x680b, 0x05ef,
+ 0x680c, 0x1869,
+ 0x680d, 0x35d0,
+ 0x680e, 0x1873,
+ 0x680f, 0x09a3,
+ 0x6810, 0x35d1,
+ 0x6811, 0x0d8e,
+ 0x6812, 0x35d2,
+ 0x6813, 0x0d9d,
+ 0x6814, 0x35d3,
+ 0x6816, 0x0bfb,
+ 0x6817, 0x09e0,
+ 0x6818, 0x35d5,
+ 0x681d, 0x187f,
+ 0x681e, 0x35da,
+ 0x6821, 0x0f6e,
+ 0x6822, 0x35dd,
+ 0x6829, 0x1888,
+ 0x682a, 0x11e9,
+ 0x682b, 0x35e4,
+ 0x6832, 0x1876,
+ 0x6834, 0x35eb,
+ 0x6837, 0x1022,
+ 0x6838, 0x0782,
+ 0x6839, 0x06f4,
+ 0x683a, 0x35ee,
+ 0x683c, 0x06ec,
+ 0x683d, 0x1117,
+ 0x683e, 0x1885,
+ 0x683f, 0x35f0,
+ 0x6840, 0x1884,
+ 0x6841, 0x1882,
+ 0x6842, 0x0749,
+ 0x6843, 0x0e25,
+ 0x6844, 0x187c,
+ 0x6845, 0x0eb5,
+ 0x6846, 0x097f,
+ 0x6847, 0x35f1,
+ 0x6848, 0x03c3,
+ 0x6849, 0x1887,
+ 0x684a, 0x1886,
+ 0x684b, 0x35f2,
+ 0x684c, 0x121d,
+ 0x684d, 0x35f3,
+ 0x684e, 0x187a,
+ 0x684f, 0x35f4,
+ 0x6850, 0x0e5a,
+ 0x6851, 0x0cdc,
+ 0x6852, 0x35f5,
+ 0x6853, 0x07cd,
+ 0x6854, 0x08ac,
+ 0x6855, 0x1880,
+ 0x6856, 0x35f6,
+ 0x6860, 0x1878,
+ 0x6862, 0x187b,
+ 0x6863, 0x0596,
+ 0x6864, 0x187d,
+ 0x6865, 0x0c42,
+ 0x6866, 0x1881,
+ 0x6867, 0x1883,
+ 0x6868, 0x0881,
+ 0x6869, 0x120b,
+ 0x686a, 0x3600,
+ 0x686b, 0x188e,
+ 0x686c, 0x3601,
+ 0x6874, 0x188b,
+ 0x6875, 0x3609,
+ 0x6876, 0x0e61,
+ 0x6877, 0x188c,
+ 0x6878, 0x360a,
+ 0x6881, 0x0a03,
+ 0x6882, 0x3613,
+ 0x6883, 0x187e,
+ 0x6884, 0x3614,
+ 0x6885, 0x0abc,
+ 0x6886, 0x03fb,
+ 0x6887, 0x3615,
+ 0x688f, 0x188a,
+ 0x6890, 0x361d,
+ 0x6893, 0x188d,
+ 0x6894, 0x3620,
+ 0x6897, 0x06fc,
+ 0x6898, 0x246a,
+ 0x6899, 0x3623,
+ 0x689d, 0x2175,
+ 0x689e, 0x3627,
+ 0x689f, 0x246d,
+ 0x68a0, 0x3628,
+ 0x68a2, 0x0d0b,
+ 0x68a3, 0x362a,
+ 0x68a6, 0x0ad3,
+ 0x68a7, 0x0eef,
+ 0x68a8, 0x09d1,
+ 0x68a9, 0x362d,
+ 0x68ad, 0x0de8,
+ 0x68ae, 0x3631,
+ 0x68af, 0x0e30,
+ 0x68b0, 0x0f80,
+ 0x68b1, 0x3632,
+ 0x68b3, 0x0d78,
+ 0x68b4, 0x3634,
+ 0x68b5, 0x1889,
+ 0x68b6, 0x3635,
+ 0x68c0, 0x085f,
+ 0x68c1, 0x363f,
+ 0x68c2, 0x188f,
+ 0x68c3, 0x3640,
+ 0x68c9, 0x0ae3,
+ 0x68ca, 0x3646,
+ 0x68cb, 0x0c04,
+ 0x68cc, 0x3647,
+ 0x68cd, 0x0750,
+ 0x68ce, 0x3648,
+ 0x68d2, 0x03ff,
+ 0x68d3, 0x364c,
+ 0x68d5, 0x1235,
+ 0x68d6, 0x246b,
+ 0x68d7, 0x225f,
+ 0x68d8, 0x081f,
+ 0x68d9, 0x364e,
+ 0x68da, 0x0bb0,
+ 0x68db, 0x364f,
+ 0x68df, 0x1ece,
+ 0x68e0, 0x0e17,
+ 0x68e1, 0x3653,
+ 0x68e3, 0x189a,
+ 0x68e4, 0x3655,
+ 0x68e7, 0x2272,
+ 0x68e8, 0x3658,
+ 0x68ee, 0x0ce6,
+ 0x68ef, 0x365e,
+ 0x68f0, 0x1896,
+ 0x68f1, 0x09cd,
+ 0x68f2, 0x365f,
+ 0x68f5, 0x0950,
+ 0x68f6, 0x3662,
+ 0x68f9, 0x1894,
+ 0x68fa, 0x0730,
+ 0x68fb, 0x3665,
+ 0x68fc, 0x1891,
+ 0x68fd, 0x3666,
+ 0x6900, 0x3669,
+ 0x6901, 0x1898,
+ 0x6902, 0x366a,
+ 0x6905, 0x1055,
+ 0x6906, 0x366d,
+ 0x690b, 0x1897,
+ 0x690c, 0x3672,
+ 0x690d, 0x11b1,
+ 0x690e, 0x1212,
+ 0x690f, 0x2473,
+ 0x6910, 0x189b,
+ 0x6911, 0x3673,
+ 0x6912, 0x0888,
+ 0x6913, 0x3674,
+ 0x691f, 0x1892,
+ 0x6921, 0x3680,
+ 0x6924, 0x1895,
+ 0x6925, 0x3683,
+ 0x692d, 0x0e87,
+ 0x692e, 0x368b,
+ 0x6930, 0x1033,
+ 0x6931, 0x368d,
+ 0x6934, 0x18a6,
+ 0x6935, 0x3690,
+ 0x6939, 0x189d,
+ 0x693a, 0x3694,
+ 0x693d, 0x052d,
+ 0x693e, 0x3697,
+ 0x693f, 0x053e,
+ 0x6940, 0x3698,
+ 0x6942, 0x189f,
+ 0x6943, 0x369a,
+ 0x694a, 0x21fe,
+ 0x694b, 0x36a1,
+ 0x6953, 0x1efe,
+ 0x6954, 0x0f73,
+ 0x6955, 0x36a9,
+ 0x6957, 0x1899,
+ 0x6958, 0x36ab,
+ 0x695a, 0x0523,
+ 0x695b, 0x36ad,
+ 0x695d, 0x18a0,
+ 0x695e, 0x09ce,
+ 0x695f, 0x36af,
+ 0x6960, 0x189e,
+ 0x6961, 0x36b0,
+ 0x6963, 0x18ad,
+ 0x6964, 0x36b2,
+ 0x6966, 0x18ac,
+ 0x6967, 0x36b4,
+ 0x6968, 0x2475,
+ 0x6969, 0x36b5,
+ 0x696b, 0x18a2,
+ 0x696c, 0x36b7,
+ 0x696d, 0x220a,
+ 0x696e, 0x1890,
+ 0x696f, 0x36b8,
+ 0x6971, 0x189c,
+ 0x6972, 0x36ba,
+ 0x6975, 0x1f6f,
+ 0x6976, 0x36bd,
+ 0x6977, 0x0939,
+ 0x6978, 0x18a5,
+ 0x6979, 0x18ae,
+ 0x697a, 0x36be,
+ 0x697c, 0x0a4c,
+ 0x697d, 0x36c0,
+ 0x6980, 0x18a3,
+ 0x6981, 0x36c3,
+ 0x6982, 0x06c0,
+ 0x6983, 0x36c4,
+ 0x6984, 0x18a1,
+ 0x6985, 0x36c5,
+ 0x6986, 0x10c1,
+ 0x6987, 0x18a8,
+ 0x6989, 0x18ab,
+ 0x698a, 0x36c6,
+ 0x698d, 0x18bb,
+ 0x698e, 0x36c9,
+ 0x6994, 0x09b1,
+ 0x6995, 0x18b9,
+ 0x6996, 0x36cf,
+ 0x6998, 0x18a4,
+ 0x6999, 0x36d1,
+ 0x699b, 0x18af,
+ 0x699c, 0x03fc,
+ 0x699d, 0x36d3,
+ 0x69a7, 0x18b0,
+ 0x69a8, 0x1146,
+ 0x69a9, 0x36dd,
+ 0x69aa, 0x2468,
+ 0x69ab, 0x18b2,
+ 0x69ac, 0x36de,
+ 0x69ad, 0x18b3,
+ 0x69ae, 0x2100,
+ 0x69af, 0x36df,
+ 0x69b1, 0x18b5,
+ 0x69b2, 0x36e1,
+ 0x69b4, 0x0a3a,
+ 0x69b5, 0x36e3,
+ 0x69b7, 0x0c91,
+ 0x69b8, 0x36e5,
+ 0x69bb, 0x18b1,
+ 0x69bc, 0x36e8,
+ 0x69bf, 0x2476,
+ 0x69c0, 0x36eb,
+ 0x69c1, 0x18b6,
+ 0x69c2, 0x36ec,
+ 0x69ca, 0x18b7,
+ 0x69cb, 0x1f27,
+ 0x69cc, 0x18a7,
+ 0x69cd, 0x20d7,
+ 0x69ce, 0x18aa,
+ 0x69cf, 0x36f4,
+ 0x69d0, 0x07c6,
+ 0x69d1, 0x36f5,
+ 0x69d4, 0x18b4,
+ 0x69d5, 0x36f8,
+ 0x69db, 0x086a,
+ 0x69dc, 0x36fe,
+ 0x69df, 0x18b8,
+ 0x69e0, 0x18ba,
+ 0x69e1, 0x3701,
+ 0x69e7, 0x247c,
+ 0x69e8, 0x3707,
+ 0x69ed, 0x18be,
+ 0x69ee, 0x370c,
+ 0x69f2, 0x18c2,
+ 0x69f3, 0x1fa1,
+ 0x69f4, 0x3710,
+ 0x69fd, 0x04a2,
+ 0x69fe, 0x3719,
+ 0x69ff, 0x18bc,
+ 0x6a00, 0x371a,
+ 0x6a01, 0x22aa,
+ 0x6a02, 0x2005,
+ 0x6a03, 0x371b,
+ 0x6a05, 0x246c,
+ 0x6a06, 0x371d,
+ 0x6a0a, 0x064b,
+ 0x6a0b, 0x3721,
+ 0x6a13, 0x203e,
+ 0x6a14, 0x3729,
+ 0x6a17, 0x18bf,
+ 0x6a19, 0x1e4c,
+ 0x6a1a, 0x372c,
+ 0x6a1e, 0x213a,
+ 0x6a1f, 0x1162,
+ 0x6a20, 0x3730,
+ 0x6a21, 0x0b06,
+ 0x6a22, 0x3731,
+ 0x6a23, 0x2204,
+ 0x6a24, 0x3732,
+ 0x6a28, 0x18cc,
+ 0x6a29, 0x3736,
+ 0x6a2a, 0x0798,
+ 0x6a2b, 0x3737,
+ 0x6a2f, 0x18bd,
+ 0x6a30, 0x373b,
+ 0x6a31, 0x1088,
+ 0x6a32, 0x373c,
+ 0x6a35, 0x18c8,
+ 0x6a36, 0x373f,
+ 0x6a38, 0x20c3,
+ 0x6a39, 0x2140,
+ 0x6a3a, 0x2477,
+ 0x6a3b, 0x3741,
+ 0x6a3d, 0x18cb,
+ 0x6a3e, 0x18c4,
+ 0x6a3f, 0x3743,
+ 0x6a44, 0x18c3,
+ 0x6a45, 0x3748,
+ 0x6a47, 0x0c3e,
+ 0x6a48, 0x2474,
+ 0x6a49, 0x374a,
+ 0x6a4b, 0x20dd,
+ 0x6a4c, 0x374c,
+ 0x6a50, 0x18c6,
+ 0x6a51, 0x3750,
+ 0x6a58, 0x18cd,
+ 0x6a59, 0x04ed,
+ 0x6a5a, 0x3757,
+ 0x6a5b, 0x18c7,
+ 0x6a5c, 0x3758,
+ 0x6a5f, 0x1f68,
+ 0x6a60, 0x375b,
+ 0x6a61, 0x0f5d,
+ 0x6a62, 0x2185,
+ 0x6a63, 0x375c,
+ 0x6a65, 0x18c1,
+ 0x6a66, 0x375e,
+ 0x6a71, 0x051c,
+ 0x6a72, 0x3769,
+ 0x6a79, 0x18ca,
+ 0x6a7a, 0x3770,
+ 0x6a7c, 0x18ce,
+ 0x6a7d, 0x3772,
+ 0x6a80, 0x0e07,
+ 0x6a81, 0x3775,
+ 0x6a84, 0x0f1a,
+ 0x6a85, 0x3778,
+ 0x6a89, 0x2472,
+ 0x6a8a, 0x377c,
+ 0x6a8e, 0x18c9,
+ 0x6a8f, 0x3780,
+ 0x6a90, 0x18d0,
+ 0x6a91, 0x18cf,
+ 0x6a92, 0x3781,
+ 0x6a94, 0x1eb5,
+ 0x6a95, 0x3783,
+ 0x6a97, 0x18d2,
+ 0x6a98, 0x3785,
+ 0x6a9c, 0x2478,
+ 0x6a9d, 0x3789,
+ 0x6aa0, 0x18c5,
+ 0x6aa1, 0x378c,
+ 0x6aa2, 0x1f8b,
+ 0x6aa3, 0x2484,
+ 0x6aa4, 0x378d,
+ 0x6aa9, 0x18d1,
+ 0x6aaa, 0x3792,
+ 0x6aab, 0x18d3,
+ 0x6aac, 0x0acf,
+ 0x6aad, 0x3793,
+ 0x6aaf, 0x2699,
+ 0x6ab0, 0x3795,
+ 0x6ab3, 0x2482,
+ 0x6ab4, 0x3798,
+ 0x6ab8, 0x20a1,
+ 0x6ab9, 0x379c,
+ 0x6abb, 0x1f92,
+ 0x6abc, 0x379e,
+ 0x6ac3, 0x1f38,
+ 0x6ac4, 0x37a5,
+ 0x6ad3, 0x2485,
+ 0x6ad4, 0x37b4,
+ 0x6ada, 0x2480,
+ 0x6adb, 0x246e,
+ 0x6adc, 0x37ba,
+ 0x6add, 0x247b,
+ 0x6ade, 0x2486,
+ 0x6adf, 0x2471,
+ 0x6ae0, 0x37bb,
+ 0x6ae7, 0x2483,
+ 0x6ae8, 0x2470,
+ 0x6ae9, 0x37c2,
+ 0x6aea, 0x2469,
+ 0x6aeb, 0x37c3,
+ 0x6aec, 0x247f,
+ 0x6aed, 0x37c4,
+ 0x6af3, 0x246f,
+ 0x6af4, 0x37ca,
+ 0x6af8, 0x2481,
+ 0x6af9, 0x37ce,
+ 0x6afb, 0x2220,
+ 0x6afc, 0x37d0,
+ 0x6b00, 0x37d4,
+ 0x6b04, 0x1ff5,
+ 0x6b05, 0x37d8,
+ 0x6b0a, 0x20f4,
+ 0x6b0b, 0x37dd,
+ 0x6b0f, 0x247d,
+ 0x6b10, 0x37e1,
+ 0x6b12, 0x2479,
+ 0x6b13, 0x37e3,
+ 0x6b16, 0x247e,
+ 0x6b17, 0x37e6,
+ 0x6b1e, 0x247a,
+ 0x6b1f, 0x37ed,
+ 0x6b20, 0x0c34,
+ 0x6b21, 0x0551,
+ 0x6b22, 0x07cb,
+ 0x6b23, 0x0f8b,
+ 0x6b24, 0x19b1,
+ 0x6b25, 0x37ee,
+ 0x6b27, 0x0b78,
+ 0x6b28, 0x37f0,
+ 0x6b32, 0x10e0,
+ 0x6b33, 0x37fa,
+ 0x6b37, 0x19b2,
+ 0x6b38, 0x37fe,
+ 0x6b39, 0x19b3,
+ 0x6b3a, 0x0bfa,
+ 0x6b3b, 0x37ff,
+ 0x6b3d, 0x20e3,
+ 0x6b3e, 0x097b,
+ 0x6b3f, 0x3801,
+ 0x6b43, 0x19b4,
+ 0x6b44, 0x3805,
+ 0x6b46, 0x19b5,
+ 0x6b47, 0x0f75,
+ 0x6b48, 0x3807,
+ 0x6b49, 0x0c35,
+ 0x6b4a, 0x3808,
+ 0x6b4c, 0x06e3,
+ 0x6b4d, 0x380a,
+ 0x6b50, 0x20ad,
+ 0x6b51, 0x380d,
+ 0x6b59, 0x19b6,
+ 0x6b5a, 0x3815,
+ 0x6b5f, 0x24cb,
+ 0x6b60, 0x381a,
+ 0x6b61, 0x1f53,
+ 0x6b62, 0x11b8,
+ 0x6b63, 0x119e,
+ 0x6b64, 0x054e,
+ 0x6b65, 0x0484,
+ 0x6b66, 0x0ef3,
+ 0x6b67, 0x0c06,
+ 0x6b68, 0x381b,
+ 0x6b6a, 0x0e92,
+ 0x6b6b, 0x381d,
+ 0x6b72, 0x2159,
+ 0x6b73, 0x3824,
+ 0x6b77, 0x2013,
+ 0x6b78, 0x1f33,
+ 0x6b79, 0x0578,
+ 0x6b7a, 0x3828,
+ 0x6b7b, 0x0db5,
+ 0x6b7c, 0x0852,
+ 0x6b7d, 0x3829,
+ 0x6b81, 0x18d6,
+ 0x6b83, 0x1013,
+ 0x6b84, 0x18d9,
+ 0x6b85, 0x382d,
+ 0x6b86, 0x057c,
+ 0x6b87, 0x18d8,
+ 0x6b88, 0x382e,
+ 0x6b89, 0x0fdc,
+ 0x6b8a, 0x0d79,
+ 0x6b8b, 0x0497,
+ 0x6b8c, 0x382f,
+ 0x6b8d, 0x18dc,
+ 0x6b8e, 0x3830,
+ 0x6b92, 0x18da,
+ 0x6b94, 0x3834,
+ 0x6b96, 0x11b2,
+ 0x6b97, 0x3836,
+ 0x6b98, 0x1e5c,
+ 0x6b99, 0x3837,
+ 0x6b9a, 0x18dd,
+ 0x6b9c, 0x3838,
+ 0x6b9e, 0x2488,
+ 0x6b9f, 0x383a,
+ 0x6ba1, 0x18df,
+ 0x6ba2, 0x383c,
+ 0x6ba4, 0x2487,
+ 0x6ba5, 0x383e,
+ 0x6baa, 0x18e0,
+ 0x6bab, 0x248a,
+ 0x6bac, 0x3843,
+ 0x6bae, 0x2489,
+ 0x6baf, 0x248b,
+ 0x6bb0, 0x3845,
+ 0x6bb2, 0x1f83,
+ 0x6bb3, 0x19bd,
+ 0x6bb4, 0x0b7a,
+ 0x6bb5, 0x060d,
+ 0x6bb6, 0x3847,
+ 0x6bb7, 0x107a,
+ 0x6bb8, 0x3848,
+ 0x6bba, 0x210f,
+ 0x6bbb, 0x1fdb,
+ 0x6bbc, 0x384a,
+ 0x6bbf, 0x05cf,
+ 0x6bc0, 0x384d,
+ 0x6bc1, 0x07ee,
+ 0x6bc2, 0x19bf,
+ 0x6bc3, 0x384e,
+ 0x6bc5, 0x106a,
+ 0x6bc6, 0x20af,
+ 0x6bc7, 0x3850,
+ 0x6bcb, 0x0ef2,
+ 0x6bcc, 0x3854,
+ 0x6bcd, 0x0b1b,
+ 0x6bce, 0x3855,
+ 0x6bcf, 0x0ac4,
+ 0x6bd0, 0x3856,
+ 0x6bd2, 0x05fd,
+ 0x6bd3, 0x126f,
+ 0x6bd4, 0x0431,
+ 0x6bd5, 0x0438,
+ 0x6bd6, 0x043a,
+ 0x6bd7, 0x0bbf,
+ 0x6bd8, 0x3858,
+ 0x6bd9, 0x0439,
+ 0x6bda, 0x3859,
+ 0x6bdb, 0x0ab0,
+ 0x6bdc, 0x385a,
+ 0x6be1, 0x1152,
+ 0x6be2, 0x385f,
+ 0x6bea, 0x1954,
+ 0x6beb, 0x0778,
+ 0x6bec, 0x3867,
+ 0x6bef, 0x0e0d,
+ 0x6bf0, 0x386a,
+ 0x6bf3, 0x1955,
+ 0x6bf4, 0x386d,
+ 0x6bf5, 0x1957,
+ 0x6bf6, 0x386e,
+ 0x6bf9, 0x1958,
+ 0x6bfa, 0x3871,
+ 0x6bfd, 0x1956,
+ 0x6bfe, 0x3874,
+ 0x6bff, 0x24c0,
+ 0x6c00, 0x3875,
+ 0x6c05, 0x1959,
+ 0x6c06, 0x195b,
+ 0x6c07, 0x195a,
+ 0x6c08, 0x226d,
+ 0x6c09, 0x387a,
+ 0x6c0c, 0x24c1,
+ 0x6c0d, 0x195c,
+ 0x6c0e, 0x387d,
+ 0x6c0f, 0x0d66,
+ 0x6c10, 0x126b,
+ 0x6c11, 0x0af6,
+ 0x6c12, 0x387e,
+ 0x6c13, 0x0aaa,
+ 0x6c14, 0x0c17,
+ 0x6c15, 0x195d,
+ 0x6c16, 0x0b2d,
+ 0x6c17, 0x387f,
+ 0x6c18, 0x195e,
+ 0x6c1b, 0x0672,
+ 0x6c1c, 0x3880,
+ 0x6c1f, 0x0697,
+ 0x6c20, 0x3883,
+ 0x6c21, 0x1961,
+ 0x6c22, 0x0c5f,
+ 0x6c23, 0x20ca,
+ 0x6c24, 0x1963,
+ 0x6c25, 0x3884,
+ 0x6c26, 0x075b,
+ 0x6c27, 0x101e,
+ 0x6c28, 0x03bc,
+ 0x6c29, 0x1962,
+ 0x6c2a, 0x1964,
+ 0x6c2b, 0x20e7,
+ 0x6c2c, 0x24c2,
+ 0x6c2d, 0x3885,
+ 0x6c2e, 0x058b,
+ 0x6c2f, 0x0a6f,
+ 0x6c30, 0x0c65,
+ 0x6c31, 0x3886,
+ 0x6c32, 0x1965,
+ 0x6c33, 0x3887,
+ 0x6c34, 0x0da3,
+ 0x6c35, 0x169f,
+ 0x6c36, 0x3888,
+ 0x6c38, 0x10a5,
+ 0x6c39, 0x388a,
+ 0x6c3d, 0x12ef,
+ 0x6c3e, 0x388e,
+ 0x6c40, 0x0e52,
+ 0x6c41, 0x11ac,
+ 0x6c42, 0x0c70,
+ 0x6c43, 0x3890,
+ 0x6c46, 0x12f4,
+ 0x6c47, 0x07f8,
+ 0x6c48, 0x3893,
+ 0x6c49, 0x0771,
+ 0x6c4a, 0x16a2,
+ 0x6c4b, 0x3894,
+ 0x6c50, 0x0f18,
+ 0x6c51, 0x3899,
+ 0x6c54, 0x16a0,
+ 0x6c55, 0x0d00,
+ 0x6c56, 0x389c,
+ 0x6c57, 0x0770,
+ 0x6c58, 0x389d,
+ 0x6c5b, 0x0fdd,
+ 0x6c5c, 0x16a1,
+ 0x6c5d, 0x0cc5,
+ 0x6c5e, 0x0708,
+ 0x6c5f, 0x087e,
+ 0x6c60, 0x04fd,
+ 0x6c61, 0x0eea,
+ 0x6c62, 0x38a0,
+ 0x6c64, 0x0e13,
+ 0x6c65, 0x38a2,
+ 0x6c68, 0x16a8,
+ 0x6c6a, 0x0ea5,
+ 0x6c6b, 0x38a5,
+ 0x6c70, 0x0e00,
+ 0x6c71, 0x38aa,
+ 0x6c72, 0x0826,
+ 0x6c73, 0x38ab,
+ 0x6c74, 0x16aa,
+ 0x6c75, 0x38ac,
+ 0x6c76, 0x16ab,
+ 0x6c77, 0x38ad,
+ 0x6c79, 0x0fa5,
+ 0x6c7a, 0x38af,
+ 0x6c7d, 0x0c1a,
+ 0x6c7e, 0x0677,
+ 0x6c7f, 0x38b2,
+ 0x6c81, 0x0c5c,
+ 0x6c82, 0x1051,
+ 0x6c83, 0x0ee5,
+ 0x6c84, 0x38b4,
+ 0x6c85, 0x16a4,
+ 0x6c86, 0x16ac,
+ 0x6c87, 0x38b5,
+ 0x6c88, 0x0d2b,
+ 0x6c89, 0x04e6,
+ 0x6c8a, 0x38b6,
+ 0x6c8c, 0x16a7,
+ 0x6c8d, 0x38b8,
+ 0x6c8f, 0x0c02,
+ 0x6c90, 0x16a5,
+ 0x6c91, 0x38ba,
+ 0x6c93, 0x1a1f,
+ 0x6c94, 0x16a6,
+ 0x6c95, 0x38bc,
+ 0x6c99, 0x0cec,
+ 0x6c9a, 0x38c0,
+ 0x6c9b, 0x0ba7,
+ 0x6c9c, 0x38c1,
+ 0x6c9f, 0x070e,
+ 0x6ca0, 0x38c4,
+ 0x6ca1, 0x0ac0,
+ 0x6ca2, 0x38c5,
+ 0x6ca3, 0x16a3,
+ 0x6ca4, 0x0b7e,
+ 0x6ca5, 0x09ed,
+ 0x6ca6, 0x0a80,
+ 0x6ca7, 0x049e,
+ 0x6ca8, 0x38c6,
+ 0x6ca9, 0x16ad,
+ 0x6caa, 0x07bb,
+ 0x6cab, 0x0b10,
+ 0x6cac, 0x38c7,
+ 0x6cad, 0x16b0,
+ 0x6cae, 0x0909,
+ 0x6caf, 0x38c8,
+ 0x6cb1, 0x16bb,
+ 0x6cb2, 0x16b5,
+ 0x6cb3, 0x078a,
+ 0x6cb4, 0x38ca,
+ 0x6cb8, 0x066d,
+ 0x6cb9, 0x10b2,
+ 0x6cba, 0x38ce,
+ 0x6cbb, 0x11cd,
+ 0x6cbc, 0x1174,
+ 0x6cbd, 0x071a,
+ 0x6cbe, 0x1155,
+ 0x6cbf, 0x1001,
+ 0x6cc0, 0x38cf,
+ 0x6cc4, 0x0f84,
+ 0x6cc5, 0x0c73,
+ 0x6cc6, 0x38d3,
+ 0x6cc9, 0x0c85,
+ 0x6cca, 0x047b,
+ 0x6ccb, 0x38d6,
+ 0x6ccc, 0x0adf,
+ 0x6ccd, 0x38d7,
+ 0x6cd0, 0x16ae,
+ 0x6cd1, 0x38da,
+ 0x6cd3, 0x16bc,
+ 0x6cd4, 0x16af,
+ 0x6cd5, 0x0645,
+ 0x6cd6, 0x16b7,
+ 0x6cd7, 0x16b4,
+ 0x6cd8, 0x38dc,
+ 0x6cdb, 0x0657,
+ 0x6cdc, 0x38df,
+ 0x6cde, 0x0b63,
+ 0x6cdf, 0x38e1,
+ 0x6ce0, 0x16b6,
+ 0x6ce1, 0x0b9e,
+ 0x6ce2, 0x046f,
+ 0x6ce3, 0x0c1b,
+ 0x6ce4, 0x38e2,
+ 0x6ce5, 0x0b43,
+ 0x6ce6, 0x38e3,
+ 0x6ce8, 0x11ff,
+ 0x6ce9, 0x38e5,
+ 0x6cea, 0x09cc,
+ 0x6ceb, 0x16b9,
+ 0x6cec, 0x38e6,
+ 0x6cee, 0x16ba,
+ 0x6cef, 0x16bd,
+ 0x6cf0, 0x0dfc,
+ 0x6cf1, 0x16b3,
+ 0x6cf2, 0x38e8,
+ 0x6cf3, 0x10a3,
+ 0x6cf4, 0x38e9,
+ 0x6cf5, 0x042c,
+ 0x6cf6, 0x1a20,
+ 0x6cf7, 0x16b1,
+ 0x6cf9, 0x38ea,
+ 0x6cfa, 0x16b8,
+ 0x6cfb, 0x0f85,
+ 0x6cfc, 0x0be2,
+ 0x6cfd, 0x1136,
+ 0x6cfe, 0x16be,
+ 0x6cff, 0x38eb,
+ 0x6d00, 0x38ec,
+ 0x6d01, 0x08b1,
+ 0x6d02, 0x38ed,
+ 0x6d04, 0x16c5,
+ 0x6d05, 0x38ef,
+ 0x6d07, 0x16c4,
+ 0x6d08, 0x38f1,
+ 0x6d0b, 0x101c,
+ 0x6d0c, 0x16c1,
+ 0x6d0d, 0x38f4,
+ 0x6d0e, 0x16c7,
+ 0x6d0f, 0x38f5,
+ 0x6d12, 0x0cd2,
+ 0x6d13, 0x38f8,
+ 0x6d17, 0x0f21,
+ 0x6d18, 0x38fc,
+ 0x6d19, 0x16c6,
+ 0x6d1a, 0x16cc,
+ 0x6d1b, 0x0a8c,
+ 0x6d1c, 0x38fd,
+ 0x6d1e, 0x05f3,
+ 0x6d1f, 0x38ff,
+ 0x6d25, 0x08c3,
+ 0x6d26, 0x3905,
+ 0x6d27, 0x16c0,
+ 0x6d28, 0x3906,
+ 0x6d2a, 0x07a0,
+ 0x6d2b, 0x16c8,
+ 0x6d2c, 0x3908,
+ 0x6d2e, 0x16ca,
+ 0x6d2f, 0x390a,
+ 0x6d31, 0x063c,
+ 0x6d32, 0x11dd,
+ 0x6d33, 0x16d0,
+ 0x6d34, 0x390c,
+ 0x6d35, 0x16cb,
+ 0x6d36, 0x390d,
+ 0x6d39, 0x16bf,
+ 0x6d3a, 0x3910,
+ 0x6d3b, 0x0803,
+ 0x6d3c, 0x0e8e,
+ 0x6d3d, 0x0c1f,
+ 0x6d3e, 0x0b8a,
+ 0x6d3f, 0x3911,
+ 0x6d41, 0x0a40,
+ 0x6d42, 0x3913,
+ 0x6d43, 0x16c2,
+ 0x6d44, 0x3914,
+ 0x6d45, 0x0c30,
+ 0x6d46, 0x087d,
+ 0x6d47, 0x088e,
+ 0x6d48, 0x16c3,
+ 0x6d49, 0x3915,
+ 0x6d4a, 0x1224,
+ 0x6d4b, 0x04a9,
+ 0x6d4c, 0x3916,
+ 0x6d4d, 0x16c9,
+ 0x6d4e, 0x0836,
+ 0x6d4f, 0x16cd,
+ 0x6d50, 0x3917,
+ 0x6d51, 0x0800,
+ 0x6d52, 0x16ce,
+ 0x6d53, 0x0b69,
+ 0x6d54, 0x16cf,
+ 0x6d55, 0x3918,
+ 0x6d59, 0x1184,
+ 0x6d5a, 0x0930,
+ 0x6d5b, 0x391c,
+ 0x6d5c, 0x16d8,
+ 0x6d5d, 0x391d,
+ 0x6d5e, 0x16d5,
+ 0x6d5f, 0x391e,
+ 0x6d60, 0x16d9,
+ 0x6d61, 0x391f,
+ 0x6d63, 0x16db,
+ 0x6d64, 0x3921,
+ 0x6d66, 0x0bf5,
+ 0x6d67, 0x3923,
+ 0x6d69, 0x077d,
+ 0x6d6a, 0x09b6,
+ 0x6d6b, 0x3925,
+ 0x6d6e, 0x069c,
+ 0x6d6f, 0x16d2,
+ 0x6d70, 0x3928,
+ 0x6d74, 0x10e4,
+ 0x6d75, 0x392c,
+ 0x6d77, 0x075a,
+ 0x6d78, 0x08cf,
+ 0x6d79, 0x23dc,
+ 0x6d7a, 0x392e,
+ 0x6d7c, 0x16da,
+ 0x6d7d, 0x3930,
+ 0x6d82, 0x0e70,
+ 0x6d83, 0x3935,
+ 0x6d85, 0x0b5c,
+ 0x6d86, 0x3937,
+ 0x6d87, 0x23db,
+ 0x6d88, 0x0f68,
+ 0x6d89, 0x0d1f,
+ 0x6d8a, 0x3938,
+ 0x6d8c, 0x10a4,
+ 0x6d8d, 0x393a,
+ 0x6d8e, 0x0f3e,
+ 0x6d8f, 0x393b,
+ 0x6d91, 0x16d1,
+ 0x6d92, 0x393d,
+ 0x6d93, 0x16d6,
+ 0x6d95, 0x0e3c,
+ 0x6d96, 0x393e,
+ 0x6d9b, 0x0e21,
+ 0x6d9c, 0x3943,
+ 0x6d9d, 0x09bf,
+ 0x6d9e, 0x16d3,
+ 0x6d9f, 0x09f9,
+ 0x6da0, 0x16d4,
+ 0x6da1, 0x0edf,
+ 0x6da2, 0x3944,
+ 0x6da3, 0x07d6,
+ 0x6da4, 0x05b4,
+ 0x6da5, 0x3945,
+ 0x6da6, 0x0cce,
+ 0x6da7, 0x0878,
+ 0x6da8, 0x1168,
+ 0x6da9, 0x0ce5,
+ 0x6daa, 0x069d,
+ 0x6dab, 0x16e8,
+ 0x6dac, 0x3946,
+ 0x6dae, 0x16ea,
+ 0x6daf, 0x0fed,
+ 0x6db0, 0x3948,
+ 0x6db2, 0x1041,
+ 0x6db3, 0x394a,
+ 0x6db5, 0x0764,
+ 0x6db6, 0x394c,
+ 0x6db8, 0x078b,
+ 0x6db9, 0x394e,
+ 0x6dbf, 0x16e1,
+ 0x6dc0, 0x05ce,
+ 0x6dc1, 0x3954,
+ 0x6dc4, 0x122a,
+ 0x6dc5, 0x16de,
+ 0x6dc6, 0x0f6a,
+ 0x6dc7, 0x16dd,
+ 0x6dc8, 0x3957,
+ 0x6dcb, 0x0a25,
+ 0x6dcc, 0x0e1d,
+ 0x6dcd, 0x395a,
+ 0x6dd1, 0x0d7e,
+ 0x6dd2, 0x395e,
+ 0x6dd6, 0x0b3a,
+ 0x6dd7, 0x3962,
+ 0x6dd8, 0x0e27,
+ 0x6dd9, 0x16e6,
+ 0x6dda, 0x3963,
+ 0x6ddd, 0x16e5,
+ 0x6dde, 0x16df,
+ 0x6ddf, 0x3966,
+ 0x6de0, 0x16e2,
+ 0x6de1, 0x058e,
+ 0x6de2, 0x3967,
+ 0x6de4, 0x10be,
+ 0x6de5, 0x3969,
+ 0x6de6, 0x16e4,
+ 0x6de7, 0x396a,
+ 0x6dea, 0x205e,
+ 0x6deb, 0x1080,
+ 0x6dec, 0x0566,
+ 0x6ded, 0x396d,
+ 0x6dee, 0x07c9,
+ 0x6def, 0x396e,
+ 0x6df1, 0x0d27,
+ 0x6df2, 0x3970,
+ 0x6df3, 0x0541,
+ 0x6df4, 0x3971,
+ 0x6df5, 0x2244,
+ 0x6df6, 0x23e2,
+ 0x6df7, 0x0801,
+ 0x6df8, 0x3972,
+ 0x6df9, 0x0ff6,
+ 0x6dfa, 0x20d4,
+ 0x6dfb, 0x0e40,
+ 0x6dfc, 0x1a21,
+ 0x6dfd, 0x3973,
+ 0x6e00, 0x3976,
+ 0x6e05, 0x0c62,
+ 0x6e06, 0x397b,
+ 0x6e0a, 0x10eb,
+ 0x6e0b, 0x397f,
+ 0x6e0c, 0x16e9,
+ 0x6e0d, 0x1232,
+ 0x6e0e, 0x16e0,
+ 0x6e0f, 0x3980,
+ 0x6e10, 0x0876,
+ 0x6e11, 0x16e3,
+ 0x6e12, 0x3981,
+ 0x6e14, 0x10cb,
+ 0x6e15, 0x3983,
+ 0x6e16, 0x16e7,
+ 0x6e17, 0x0d31,
+ 0x6e18, 0x3984,
+ 0x6e1a, 0x16dc,
+ 0x6e1b, 0x3986,
+ 0x6e1d, 0x10ca,
+ 0x6e1e, 0x3988,
+ 0x6e20, 0x0c7b,
+ 0x6e21, 0x0608,
+ 0x6e22, 0x398a,
+ 0x6e23, 0x113f,
+ 0x6e24, 0x047a,
+ 0x6e25, 0x16f5,
+ 0x6e26, 0x219f,
+ 0x6e27, 0x398b,
+ 0x6e29, 0x0ed1,
+ 0x6e2a, 0x398d,
+ 0x6e2b, 0x16eb,
+ 0x6e2c, 0x1e66,
+ 0x6e2d, 0x0ecb,
+ 0x6e2e, 0x398e,
+ 0x6e2f, 0x06d6,
+ 0x6e30, 0x398f,
+ 0x6e32, 0x16f4,
+ 0x6e33, 0x3991,
+ 0x6e34, 0x0957,
+ 0x6e35, 0x3992,
+ 0x6e38, 0x10b3,
+ 0x6e39, 0x3995,
+ 0x6e3a, 0x0af1,
+ 0x6e3b, 0x3996,
+ 0x6e3e, 0x1f63,
+ 0x6e3f, 0x3999,
+ 0x6e43, 0x0b89,
+ 0x6e44, 0x16f6,
+ 0x6e45, 0x399d,
+ 0x6e4d, 0x0e75,
+ 0x6e4e, 0x16ed,
+ 0x6e4f, 0x39a5,
+ 0x6e53, 0x16f2,
+ 0x6e55, 0x39a9,
+ 0x6e56, 0x07b5,
+ 0x6e57, 0x39aa,
+ 0x6e58, 0x0f53,
+ 0x6e59, 0x39ab,
+ 0x6e5b, 0x1160,
+ 0x6e5c, 0x39ad,
+ 0x6e5e, 0x23dd,
+ 0x6e5f, 0x16f0,
+ 0x6e60, 0x39af,
+ 0x6e6b, 0x16ee,
+ 0x6e6c, 0x39ba,
+ 0x6e6e, 0x16ec,
+ 0x6e6f, 0x216b,
+ 0x6e70, 0x39bc,
+ 0x6e7e, 0x0e96,
+ 0x6e7f, 0x0d41,
+ 0x6e80, 0x39ca,
+ 0x6e83, 0x098e,
+ 0x6e84, 0x39cd,
+ 0x6e85, 0x0877,
+ 0x6e86, 0x16f1,
+ 0x6e87, 0x39ce,
+ 0x6e89, 0x06c3,
+ 0x6e8a, 0x39d0,
+ 0x6e8f, 0x1705,
+ 0x6e90, 0x10f7,
+ 0x6e91, 0x39d5,
+ 0x6e96, 0x22b5,
+ 0x6e97, 0x39da,
+ 0x6e98, 0x16f9,
+ 0x6e99, 0x39db,
+ 0x6e9c, 0x0a38,
+ 0x6e9d, 0x1f26,
+ 0x6e9e, 0x39de,
+ 0x6e9f, 0x1707,
+ 0x6ea0, 0x39df,
+ 0x6ea2, 0x106e,
+ 0x6ea3, 0x39e1,
+ 0x6ea5, 0x16fd,
+ 0x6ea6, 0x39e3,
+ 0x6ea7, 0x16fe,
+ 0x6ea8, 0x39e4,
+ 0x6eaa, 0x0f17,
+ 0x6eab, 0x39e6,
+ 0x6eaf, 0x0dd2,
+ 0x6eb0, 0x39ea,
+ 0x6eb1, 0x16f8,
+ 0x6eb2, 0x16ef,
+ 0x6eb3, 0x39eb,
+ 0x6eb4, 0x1703,
+ 0x6eb5, 0x39ec,
+ 0x6eb6, 0x0cb7,
+ 0x6eb7, 0x1701,
+ 0x6eb8, 0x39ed,
+ 0x6eba, 0x0b4a,
+ 0x6ebb, 0x1700,
+ 0x6ebc, 0x39ef,
+ 0x6ebd, 0x16ff,
+ 0x6ebe, 0x39f0,
+ 0x6ec1, 0x0521,
+ 0x6ec2, 0x1706,
+ 0x6ec3, 0x39f3,
+ 0x6ec4, 0x1e63,
+ 0x6ec5, 0x2088,
+ 0x6ec6, 0x39f4,
+ 0x6ec7, 0x05c2,
+ 0x6ec8, 0x39f5,
+ 0x6ecb, 0x1229,
+ 0x6ecc, 0x1ebd,
+ 0x6ecd, 0x39f8,
+ 0x6ece, 0x2341,
+ 0x6ecf, 0x1704,
+ 0x6ed0, 0x39f9,
+ 0x6ed1, 0x07c1,
+ 0x6ed2, 0x39fa,
+ 0x6ed3, 0x122f,
+ 0x6ed4, 0x0e22,
+ 0x6ed5, 0x19a8,
+ 0x6ed6, 0x39fb,
+ 0x6ed7, 0x1702,
+ 0x6ed8, 0x39fc,
+ 0x6eda, 0x074f,
+ 0x6edb, 0x39fe,
+ 0x6ede, 0x11cc,
+ 0x6edf, 0x16f7,
+ 0x6ee0, 0x16fa,
+ 0x6ee1, 0x0aa1,
+ 0x6ee2, 0x16fc,
+ 0x6ee3, 0x3a01,
+ 0x6ee4, 0x0a72,
+ 0x6ee5, 0x09af,
+ 0x6ee6, 0x0a77,
+ 0x6ee7, 0x3a02,
+ 0x6ee8, 0x045e,
+ 0x6ee9, 0x0e05,
+ 0x6eea, 0x3a03,
+ 0x6eec, 0x1f4b,
+ 0x6eed, 0x3a05,
+ 0x6eef, 0x2292,
+ 0x6ef0, 0x3a07,
+ 0x6ef2, 0x2124,
+ 0x6ef3, 0x3a09,
+ 0x6ef4, 0x05af,
+ 0x6ef5, 0x3a0a,
+ 0x6ef7, 0x2048,
+ 0x6ef8, 0x23e0,
+ 0x6ef9, 0x170d,
+ 0x6efa, 0x3a0c,
+ 0x6eff, 0x2077,
+ 0x6f00, 0x3a11,
+ 0x6f01, 0x223a,
+ 0x6f02, 0x0bce,
+ 0x6f03, 0x3a12,
+ 0x6f06, 0x0c00,
+ 0x6f07, 0x3a15,
+ 0x6f09, 0x1713,
+ 0x6f0a, 0x3a17,
+ 0x6f0f, 0x0a50,
+ 0x6f10, 0x3a1c,
+ 0x6f13, 0x09d7,
+ 0x6f14, 0x1006,
+ 0x6f15, 0x170c,
+ 0x6f16, 0x3a1f,
+ 0x6f1a, 0x20b1,
+ 0x6f1b, 0x3a23,
+ 0x6f20, 0x0b11,
+ 0x6f21, 0x3a28,
+ 0x6f22, 0x1f41,
+ 0x6f23, 0x201c,
+ 0x6f24, 0x170b,
+ 0x6f25, 0x3a29,
+ 0x6f29, 0x1714,
+ 0x6f2a, 0x1712,
+ 0x6f2b, 0x0aa5,
+ 0x6f2c, 0x22b8,
+ 0x6f2d, 0x16fb,
+ 0x6f2e, 0x3a2d,
+ 0x6f2f, 0x170e,
+ 0x6f30, 0x3a2e,
+ 0x6f31, 0x0d95,
+ 0x6f32, 0x2276,
+ 0x6f33, 0x1165,
+ 0x6f34, 0x3a2f,
+ 0x6f36, 0x170f,
+ 0x6f37, 0x3a31,
+ 0x6f38, 0x1f9b,
+ 0x6f39, 0x3a32,
+ 0x6f3e, 0x1023,
+ 0x6f3f, 0x1f9f,
+ 0x6f40, 0x3a37,
+ 0x6f41, 0x25ca,
+ 0x6f42, 0x3a38,
+ 0x6f46, 0x1709,
+ 0x6f48, 0x3a3c,
+ 0x6f4b, 0x1710,
+ 0x6f4c, 0x3a3f,
+ 0x6f4d, 0x0eba,
+ 0x6f4e, 0x3a40,
+ 0x6f51, 0x20be,
+ 0x6f52, 0x3a43,
+ 0x6f54, 0x1fb4,
+ 0x6f55, 0x3a45,
+ 0x6f58, 0x0b8c,
+ 0x6f59, 0x23d7,
+ 0x6f5a, 0x3a48,
+ 0x6f5c, 0x0c2e,
+ 0x6f5d, 0x3a4a,
+ 0x6f5e, 0x0a61,
+ 0x6f5f, 0x3a4b,
+ 0x6f62, 0x1708,
+ 0x6f63, 0x3a4e,
+ 0x6f64, 0x2105,
+ 0x6f65, 0x3a4f,
+ 0x6f66, 0x0a13,
+ 0x6f67, 0x3a50,
+ 0x6f6d, 0x0e09,
+ 0x6f6e, 0x04d6,
+ 0x6f6f, 0x23e1,
+ 0x6f70, 0x1fec,
+ 0x6f71, 0x3a56,
+ 0x6f72, 0x1719,
+ 0x6f73, 0x3a57,
+ 0x6f74, 0x1711,
+ 0x6f75, 0x3a58,
+ 0x6f77, 0x23ea,
+ 0x6f78, 0x1718,
+ 0x6f79, 0x3a5a,
+ 0x6f7a, 0x171b,
+ 0x6f7b, 0x3a5b,
+ 0x6f7c, 0x171a,
+ 0x6f7d, 0x3a5c,
+ 0x6f7f, 0x23e3,
+ 0x6f80, 0x210e,
+ 0x6f81, 0x3a5e,
+ 0x6f84, 0x04f3,
+ 0x6f85, 0x3a61,
+ 0x6f86, 0x1fa6,
+ 0x6f87, 0x2004,
+ 0x6f88, 0x04df,
+ 0x6f89, 0x1715,
+ 0x6f8a, 0x3a62,
+ 0x6f8c, 0x1717,
+ 0x6f8d, 0x1716,
+ 0x6f8e, 0x0bad,
+ 0x6f8f, 0x3a64,
+ 0x6f97, 0x1f9d,
+ 0x6f98, 0x3a6c,
+ 0x6f9c, 0x09a8,
+ 0x6f9d, 0x3a70,
+ 0x6fa0, 0x23e5,
+ 0x6fa1, 0x112b,
+ 0x6fa2, 0x3a73,
+ 0x6fa4, 0x2264,
+ 0x6fa5, 0x3a75,
+ 0x6fa7, 0x171e,
+ 0x6fa8, 0x3a77,
+ 0x6fa9, 0x24e2,
+ 0x6faa, 0x3a78,
+ 0x6fae, 0x23de,
+ 0x6faf, 0x3a7c,
+ 0x6fb1, 0x1ec4,
+ 0x6fb2, 0x3a7e,
+ 0x6fb3, 0x03cf,
+ 0x6fb4, 0x3a7f,
+ 0x6fb6, 0x1720,
+ 0x6fb7, 0x3a81,
+ 0x6fb9, 0x171f,
+ 0x6fba, 0x3a83,
+ 0x6fc0, 0x0817,
+ 0x6fc1, 0x22b6,
+ 0x6fc2, 0x1721,
+ 0x6fc3, 0x20a9,
+ 0x6fc4, 0x3a89,
+ 0x6fc9, 0x171d,
+ 0x6fca, 0x3a8e,
+ 0x6fd1, 0x171c,
+ 0x6fd2, 0x045d,
+ 0x6fd3, 0x3a95,
+ 0x6fd5, 0x212b,
+ 0x6fd6, 0x3a97,
+ 0x6fd8, 0x20a5,
+ 0x6fd9, 0x3a99,
+ 0x6fdb, 0x268b,
+ 0x6fdc, 0x3a9b,
+ 0x6fde, 0x1724,
+ 0x6fdf, 0x1f76,
+ 0x6fe0, 0x1725,
+ 0x6fe1, 0x1722,
+ 0x6fe2, 0x3a9d,
+ 0x6fe4, 0x216d,
+ 0x6fe5, 0x3a9f,
+ 0x6feb, 0x2001,
+ 0x6fec, 0x3aa5,
+ 0x6fee, 0x1723,
+ 0x6fef, 0x1726,
+ 0x6ff0, 0x2191,
+ 0x6ff1, 0x1e50,
+ 0x6ff2, 0x3aa7,
+ 0x6ffa, 0x1f9c,
+ 0x6ffb, 0x3aaf,
+ 0x6ffc, 0x23da,
+ 0x6ffd, 0x3ab0,
+ 0x6ffe, 0x2053,
+ 0x6fff, 0x3ab1,
+ 0x7000, 0x3ab2,
+ 0x7005, 0x23e9,
+ 0x7006, 0x23e4,
+ 0x7007, 0x3ab7,
+ 0x7009, 0x21d5,
+ 0x700a, 0x3ab9,
+ 0x700b, 0x23e6,
+ 0x700c, 0x3aba,
+ 0x700f, 0x23df,
+ 0x7010, 0x3abd,
+ 0x7011, 0x0bf8,
+ 0x7012, 0x3abe,
+ 0x7015, 0x1e4f,
+ 0x7016, 0x3ac1,
+ 0x7018, 0x23d9,
+ 0x7019, 0x3ac3,
+ 0x701a, 0x1727,
+ 0x701b, 0x1729,
+ 0x701c, 0x3ac4,
+ 0x701d, 0x2014,
+ 0x701e, 0x3ac5,
+ 0x701f, 0x23ec,
+ 0x7020, 0x23eb,
+ 0x7021, 0x3ac6,
+ 0x7023, 0x1728,
+ 0x7024, 0x3ac8,
+ 0x7027, 0x23d8,
+ 0x7028, 0x23ee,
+ 0x7029, 0x3acb,
+ 0x7030, 0x268e,
+ 0x7031, 0x3ad2,
+ 0x7032, 0x23ed,
+ 0x7033, 0x3ad3,
+ 0x7035, 0x172b,
+ 0x7036, 0x3ad5,
+ 0x7039, 0x172a,
+ 0x703a, 0x3ad8,
+ 0x703e, 0x1ffa,
+ 0x703f, 0x3adc,
+ 0x7043, 0x23d6,
+ 0x7044, 0x23e8,
+ 0x7045, 0x3ae0,
+ 0x704c, 0x0739,
+ 0x704d, 0x3ae7,
+ 0x704f, 0x172c,
+ 0x7050, 0x3ae9,
+ 0x7051, 0x2106,
+ 0x7052, 0x3aea,
+ 0x7055, 0x200b,
+ 0x7056, 0x3aed,
+ 0x7058, 0x2166,
+ 0x7059, 0x3aef,
+ 0x705d, 0x23ef,
+ 0x705e, 0x172d,
+ 0x705f, 0x3af3,
+ 0x7063, 0x2189,
+ 0x7064, 0x2058,
+ 0x7065, 0x3af7,
+ 0x7067, 0x23e7,
+ 0x7068, 0x3af9,
+ 0x706b, 0x0805,
+ 0x706c, 0x19ef,
+ 0x706d, 0x0af5,
+ 0x706e, 0x3afc,
+ 0x706f, 0x05a7,
+ 0x7070, 0x07e7,
+ 0x7071, 0x3afd,
+ 0x7075, 0x0a32,
+ 0x7076, 0x1131,
+ 0x7077, 0x3b01,
+ 0x7078, 0x08f3,
+ 0x7079, 0x3b02,
+ 0x707c, 0x1223,
+ 0x707d, 0x3b05,
+ 0x707e, 0x1119,
+ 0x707f, 0x049a,
+ 0x7080, 0x19cc,
+ 0x7081, 0x3b06,
+ 0x7085, 0x1913,
+ 0x7086, 0x3b0a,
+ 0x7089, 0x0a56,
+ 0x708a, 0x0539,
+ 0x708b, 0x3b0d,
+ 0x708e, 0x1000,
+ 0x708f, 0x3b10,
+ 0x7092, 0x04d9,
+ 0x7093, 0x3b13,
+ 0x7094, 0x0c8d,
+ 0x7095, 0x0948,
+ 0x7096, 0x19ce,
+ 0x7097, 0x3b14,
+ 0x7099, 0x11ca,
+ 0x709a, 0x3b16,
+ 0x709c, 0x19cd,
+ 0x709d, 0x19cf,
+ 0x709e, 0x3b18,
+ 0x70ab, 0x19d3,
+ 0x70ac, 0x0915,
+ 0x70ad, 0x0e12,
+ 0x70ae, 0x0b9b,
+ 0x70af, 0x08eb,
+ 0x70b0, 0x3b25,
+ 0x70b1, 0x19d4,
+ 0x70b2, 0x3b26,
+ 0x70b3, 0x0467,
+ 0x70b4, 0x3b27,
+ 0x70b7, 0x19d2,
+ 0x70b8, 0x1149,
+ 0x70b9, 0x05c4,
+ 0x70ba, 0x3b2a,
+ 0x70bb, 0x19d0,
+ 0x70bc, 0x09ff,
+ 0x70bd, 0x0508,
+ 0x70be, 0x3b2b,
+ 0x70c0, 0x19d1,
+ 0x70c1, 0x0dad,
+ 0x70c2, 0x09ae,
+ 0x70c3, 0x0e51,
+ 0x70c4, 0x3b2d,
+ 0x70c8, 0x0a1b,
+ 0x70c9, 0x3b31,
+ 0x70ca, 0x19d6,
+ 0x70cb, 0x3b32,
+ 0x70cf, 0x21a3,
+ 0x70d0, 0x3b36,
+ 0x70d8, 0x079d,
+ 0x70d9, 0x09be,
+ 0x70da, 0x3b3e,
+ 0x70db, 0x11f1,
+ 0x70dc, 0x3b3f,
+ 0x70df, 0x0ff5,
+ 0x70e0, 0x3b42,
+ 0x70e4, 0x094b,
+ 0x70e5, 0x3b46,
+ 0x70e6, 0x0650,
+ 0x70e7, 0x0d0e,
+ 0x70e8, 0x19d5,
+ 0x70e9, 0x07f7,
+ 0x70ea, 0x3b47,
+ 0x70eb, 0x0e1f,
+ 0x70ec, 0x08ce,
+ 0x70ed, 0x0ca3,
+ 0x70ee, 0x3b48,
+ 0x70ef, 0x0f16,
+ 0x70f0, 0x3b49,
+ 0x70f4, 0x217a,
+ 0x70f5, 0x3b4d,
+ 0x70f7, 0x0e9a,
+ 0x70f8, 0x3b4f,
+ 0x70f9, 0x0bac,
+ 0x70fa, 0x3b50,
+ 0x70fd, 0x0686,
+ 0x70fe, 0x3b53,
+ 0x7100, 0x3b55,
+ 0x7109, 0x0ff2,
+ 0x710a, 0x076f,
+ 0x710b, 0x3b5e,
+ 0x7110, 0x19d7,
+ 0x7111, 0x3b63,
+ 0x7113, 0x19d8,
+ 0x7114, 0x3b65,
+ 0x7115, 0x07d5,
+ 0x7116, 0x19d9,
+ 0x7117, 0x3b66,
+ 0x7118, 0x19f0,
+ 0x7119, 0x0423,
+ 0x711a, 0x0676,
+ 0x711b, 0x3b67,
+ 0x7121, 0x21a5,
+ 0x7122, 0x3b6d,
+ 0x7126, 0x088a,
+ 0x7127, 0x3b71,
+ 0x712f, 0x19da,
+ 0x7130, 0x100f,
+ 0x7131, 0x19db,
+ 0x7132, 0x3b79,
+ 0x7136, 0x0c96,
+ 0x7137, 0x3b7d,
+ 0x7145, 0x19df,
+ 0x7146, 0x3b8b,
+ 0x7149, 0x2022,
+ 0x714a, 0x19e1,
+ 0x714b, 0x3b8e,
+ 0x714c, 0x07e2,
+ 0x714d, 0x3b8f,
+ 0x714e, 0x0858,
+ 0x714f, 0x3b90,
+ 0x7152, 0x24d6,
+ 0x7153, 0x3b93,
+ 0x715c, 0x19dd,
+ 0x715d, 0x3b9c,
+ 0x715e, 0x0cf0,
+ 0x715f, 0x3b9d,
+ 0x7162, 0x233a,
+ 0x7163, 0x3ba0,
+ 0x7164, 0x0abf,
+ 0x7165, 0x3ba1,
+ 0x7166, 0x19f1,
+ 0x7167, 0x1176,
+ 0x7168, 0x19de,
+ 0x7169, 0x1eee,
+ 0x716a, 0x3ba2,
+ 0x716c, 0x24d5,
+ 0x716d, 0x3ba4,
+ 0x716e, 0x11f2,
+ 0x716f, 0x3ba5,
+ 0x7172, 0x19e0,
+ 0x7173, 0x19dc,
+ 0x7174, 0x3ba8,
+ 0x7178, 0x19e2,
+ 0x7179, 0x3bac,
+ 0x717a, 0x19e3,
+ 0x717b, 0x3bad,
+ 0x717d, 0x0cf8,
+ 0x717e, 0x3baf,
+ 0x7184, 0x0f15,
+ 0x7185, 0x3bb5,
+ 0x718a, 0x0fa7,
+ 0x718b, 0x3bba,
+ 0x718f, 0x0fd5,
+ 0x7190, 0x3bbe,
+ 0x7192, 0x2228,
+ 0x7193, 0x3bc0,
+ 0x7194, 0x0cb6,
+ 0x7195, 0x3bc1,
+ 0x7197, 0x24d7,
+ 0x7198, 0x19e4,
+ 0x7199, 0x0f04,
+ 0x719a, 0x3bc3,
+ 0x719f, 0x0d83,
+ 0x71a0, 0x19e8,
+ 0x71a1, 0x3bc8,
+ 0x71a8, 0x19e7,
+ 0x71a9, 0x3bcf,
+ 0x71ac, 0x03c9,
+ 0x71ad, 0x3bd2,
+ 0x71b1, 0x20fc,
+ 0x71b2, 0x3bd6,
+ 0x71b3, 0x19e5,
+ 0x71b4, 0x3bd7,
+ 0x71b5, 0x19e6,
+ 0x71b6, 0x3bd8,
+ 0x71b9, 0x19f2,
+ 0x71ba, 0x3bdb,
+ 0x71be, 0x1e87,
+ 0x71bf, 0x3bdf,
+ 0x71c1, 0x24d8,
+ 0x71c2, 0x3be1,
+ 0x71c3, 0x0c97,
+ 0x71c4, 0x3be2,
+ 0x71c8, 0x1eba,
+ 0x71c9, 0x3be6,
+ 0x71ce, 0x0a10,
+ 0x71cf, 0x3beb,
+ 0x71d2, 0x2119,
+ 0x71d3, 0x3bee,
+ 0x71d4, 0x19ea,
+ 0x71d5, 0x1009,
+ 0x71d6, 0x3bef,
+ 0x71d9, 0x216c,
+ 0x71da, 0x3bf2,
+ 0x71dc, 0x24d9,
+ 0x71dd, 0x3bf4,
+ 0x71df, 0x2227,
+ 0x71e0, 0x19e9,
+ 0x71e1, 0x3bf6,
+ 0x71e5, 0x1132,
+ 0x71e6, 0x1e5f,
+ 0x71e7, 0x19eb,
+ 0x71e8, 0x3bfa,
+ 0x71ed, 0x229f,
+ 0x71ee, 0x1396,
+ 0x71ef, 0x3bff,
+ 0x71f4, 0x1f5d,
+ 0x71f5, 0x3c04,
+ 0x71f9, 0x19ec,
+ 0x71fa, 0x3c08,
+ 0x71fc, 0x1fbc,
+ 0x71fd, 0x3c0a,
+ 0x71fe, 0x24da,
+ 0x71ff, 0x3c0b,
+ 0x7200, 0x3c0c,
+ 0x7206, 0x0415,
+ 0x7207, 0x3c12,
+ 0x720d, 0x2149,
+ 0x720e, 0x3c18,
+ 0x7210, 0x2046,
+ 0x7211, 0x3c1a,
+ 0x721b, 0x2000,
+ 0x721c, 0x3c24,
+ 0x721d, 0x19ed,
+ 0x721e, 0x3c25,
+ 0x7228, 0x19ee,
+ 0x7229, 0x3c2f,
+ 0x722a, 0x1203,
+ 0x722b, 0x3c30,
+ 0x722c, 0x0b81,
+ 0x722d, 0x3c31,
+ 0x7230, 0x196c,
+ 0x7231, 0x03b9,
+ 0x7232, 0x2190,
+ 0x7233, 0x3c34,
+ 0x7235, 0x0923,
+ 0x7236, 0x06b3,
+ 0x7237, 0x1036,
+ 0x7238, 0x03e1,
+ 0x7239, 0x05da,
+ 0x723a, 0x2208,
+ 0x723b, 0x1269,
+ 0x723c, 0x3c36,
+ 0x723d, 0x0da1,
+ 0x723e, 0x1ee6,
+ 0x723f, 0x169d,
+ 0x7240, 0x3c37,
+ 0x7247, 0x0bcb,
+ 0x7248, 0x03f1,
+ 0x7249, 0x3c3e,
+ 0x724c, 0x0b87,
+ 0x724d, 0x1969,
+ 0x724e, 0x3c41,
+ 0x7252, 0x196a,
+ 0x7253, 0x3c45,
+ 0x7256, 0x196b,
+ 0x7257, 0x3c48,
+ 0x7258, 0x24c3,
+ 0x7259, 0x0fe9,
+ 0x725a, 0x3c49,
+ 0x725b, 0x0b64,
+ 0x725c, 0x3c4a,
+ 0x725d, 0x1944,
+ 0x725e, 0x3c4b,
+ 0x725f, 0x0b15,
+ 0x7260, 0x3c4c,
+ 0x7261, 0x0b18,
+ 0x7262, 0x09b9,
+ 0x7263, 0x3c4d,
+ 0x7266, 0x1945,
+ 0x7267, 0x0b24,
+ 0x7268, 0x3c50,
+ 0x7269, 0x0efe,
+ 0x726a, 0x3c51,
+ 0x726e, 0x1942,
+ 0x726f, 0x1946,
+ 0x7270, 0x3c55,
+ 0x7272, 0x0d35,
+ 0x7273, 0x3c57,
+ 0x7275, 0x0c20,
+ 0x7276, 0x3c59,
+ 0x7279, 0x0e2b,
+ 0x727a, 0x0f0d,
+ 0x727b, 0x3c5c,
+ 0x727d, 0x20cc,
+ 0x727e, 0x1947,
+ 0x7280, 0x0f19,
+ 0x7281, 0x09d2,
+ 0x7282, 0x3c5e,
+ 0x7284, 0x1949,
+ 0x7285, 0x3c60,
+ 0x728a, 0x05fe,
+ 0x728b, 0x194a,
+ 0x728c, 0x3c65,
+ 0x728d, 0x194b,
+ 0x728e, 0x3c66,
+ 0x728f, 0x194c,
+ 0x7290, 0x3c67,
+ 0x7292, 0x194d,
+ 0x7293, 0x3c69,
+ 0x7296, 0x2340,
+ 0x7297, 0x3c6c,
+ 0x729f, 0x1943,
+ 0x72a0, 0x3c74,
+ 0x72a2, 0x1ed1,
+ 0x72a3, 0x3c76,
+ 0x72a7, 0x21ac,
+ 0x72a8, 0x3c7a,
+ 0x72ac, 0x0c89,
+ 0x72ad, 0x15ef,
+ 0x72ae, 0x3c7e,
+ 0x72af, 0x0655,
+ 0x72b0, 0x15f0,
+ 0x72b1, 0x3c7f,
+ 0x72b4, 0x15f1,
+ 0x72b5, 0x3c82,
+ 0x72b6, 0x1211,
+ 0x72b7, 0x15f2,
+ 0x72b9, 0x10b1,
+ 0x72ba, 0x3c83,
+ 0x72c0, 0x22af,
+ 0x72c1, 0x15f5,
+ 0x72c2, 0x097e,
+ 0x72c3, 0x15f4,
+ 0x72c4, 0x05b3,
+ 0x72c5, 0x3c89,
+ 0x72c8, 0x0420,
+ 0x72c9, 0x3c8c,
+ 0x72cd, 0x15f7,
+ 0x72ce, 0x15f6,
+ 0x72cf, 0x3c90,
+ 0x72d0, 0x07b3,
+ 0x72d1, 0x3c91,
+ 0x72d2, 0x15f8,
+ 0x72d3, 0x3c92,
+ 0x72d7, 0x0710,
+ 0x72d8, 0x3c96,
+ 0x72d9, 0x0900,
+ 0x72da, 0x3c97,
+ 0x72de, 0x0b5f,
+ 0x72df, 0x3c9b,
+ 0x72e0, 0x0794,
+ 0x72e1, 0x0897,
+ 0x72e2, 0x3c9c,
+ 0x72e8, 0x15f9,
+ 0x72e9, 0x15fb,
+ 0x72ea, 0x3ca2,
+ 0x72ec, 0x05ff,
+ 0x72ed, 0x0f2e,
+ 0x72ee, 0x0d3f,
+ 0x72ef, 0x15fa,
+ 0x72f0, 0x1199,
+ 0x72f1, 0x10e1,
+ 0x72f2, 0x15fc,
+ 0x72f3, 0x1600,
+ 0x72f4, 0x15fd,
+ 0x72f5, 0x3ca4,
+ 0x72f7, 0x15fe,
+ 0x72f8, 0x09d5,
+ 0x72f9, 0x21b6,
+ 0x72fa, 0x1602,
+ 0x72fc, 0x09b2,
+ 0x72fd, 0x1e3d,
+ 0x72fe, 0x3ca6,
+ 0x7300, 0x3ca8,
+ 0x7301, 0x15ff,
+ 0x7302, 0x3ca9,
+ 0x7303, 0x1601,
+ 0x7304, 0x3caa,
+ 0x730a, 0x1607,
+ 0x730b, 0x3cb0,
+ 0x730e, 0x0a1d,
+ 0x730f, 0x3cb3,
+ 0x7313, 0x1605,
+ 0x7314, 0x3cb7,
+ 0x7315, 0x160a,
+ 0x7316, 0x04c5,
+ 0x7317, 0x1604,
+ 0x7318, 0x3cb8,
+ 0x731b, 0x0ad2,
+ 0x731c, 0x0489,
+ 0x731d, 0x1609,
+ 0x731e, 0x1608,
+ 0x731f, 0x3cbb,
+ 0x7321, 0x1606,
+ 0x7322, 0x160b,
+ 0x7323, 0x3cbd,
+ 0x7325, 0x160d,
+ 0x7326, 0x3cbf,
+ 0x7329, 0x0f94,
+ 0x732a, 0x11ec,
+ 0x732b, 0x0aad,
+ 0x732c, 0x160e,
+ 0x732d, 0x3cc2,
+ 0x732e, 0x0f44,
+ 0x732f, 0x3cc3,
+ 0x7331, 0x1610,
+ 0x7332, 0x3cc5,
+ 0x7334, 0x07a6,
+ 0x7335, 0x3cc7,
+ 0x7336, 0x2235,
+ 0x7337, 0x18d4,
+ 0x7338, 0x160f,
+ 0x7339, 0x160c,
+ 0x733a, 0x3cc8,
+ 0x733b, 0x2397,
+ 0x733c, 0x3cc9,
+ 0x733e, 0x07c0,
+ 0x733f, 0x10f6,
+ 0x7340, 0x3ccb,
+ 0x7341, 0x2395,
+ 0x7342, 0x3ccc,
+ 0x7344, 0x223f,
+ 0x7345, 0x212a,
+ 0x7346, 0x3cce,
+ 0x734d, 0x1612,
+ 0x734e, 0x3cd5,
+ 0x7350, 0x1611,
+ 0x7351, 0x3cd7,
+ 0x7352, 0x18d5,
+ 0x7353, 0x3cd8,
+ 0x7357, 0x1613,
+ 0x7358, 0x3cdc,
+ 0x7360, 0x1614,
+ 0x7361, 0x3ce4,
+ 0x7368, 0x1ed2,
+ 0x7369, 0x3ceb,
+ 0x736a, 0x2396,
+ 0x736b, 0x2398,
+ 0x736c, 0x1615,
+ 0x736d, 0x0df4,
+ 0x736e, 0x3cec,
+ 0x736f, 0x1616,
+ 0x7370, 0x20a2,
+ 0x7371, 0x3ced,
+ 0x7372, 0x1f64,
+ 0x7373, 0x3cee,
+ 0x7375, 0x202b,
+ 0x7376, 0x3cf0,
+ 0x7377, 0x2394,
+ 0x7378, 0x2139,
+ 0x7379, 0x3cf1,
+ 0x737a, 0x215f,
+ 0x737b, 0x21c1,
+ 0x737c, 0x239a,
+ 0x737d, 0x3cf2,
+ 0x737e, 0x1617,
+ 0x737f, 0x3cf3,
+ 0x7380, 0x2399,
+ 0x7381, 0x3cf4,
+ 0x7384, 0x0fc9,
+ 0x7385, 0x3cf7,
+ 0x7387, 0x0a71,
+ 0x7388, 0x3cf9,
+ 0x7389, 0x10d6,
+ 0x738a, 0x3cfa,
+ 0x738b, 0x0ea6,
+ 0x738c, 0x3cfb,
+ 0x738e, 0x1818,
+ 0x738f, 0x3cfd,
+ 0x7391, 0x1819,
+ 0x7392, 0x3cff,
+ 0x7396, 0x08f0,
+ 0x7397, 0x3d03,
+ 0x739b, 0x0a91,
+ 0x739c, 0x3d07,
+ 0x739f, 0x181c,
+ 0x73a0, 0x3d0a,
+ 0x73a2, 0x181b,
+ 0x73a3, 0x3d0c,
+ 0x73a9, 0x0e97,
+ 0x73aa, 0x3d12,
+ 0x73ab, 0x0aba,
+ 0x73ac, 0x3d13,
+ 0x73ae, 0x181a,
+ 0x73af, 0x07cc,
+ 0x73b0, 0x0f43,
+ 0x73b1, 0x3d15,
+ 0x73b2, 0x0a2a,
+ 0x73b3, 0x1821,
+ 0x73b4, 0x3d16,
+ 0x73b7, 0x1820,
+ 0x73b8, 0x3d19,
+ 0x73ba, 0x182c,
+ 0x73bb, 0x046a,
+ 0x73bc, 0x3d1b,
+ 0x73c0, 0x1822,
+ 0x73c1, 0x3d1f,
+ 0x73c2, 0x181e,
+ 0x73c3, 0x3d20,
+ 0x73c8, 0x1824,
+ 0x73c9, 0x1823,
+ 0x73ca, 0x0cf3,
+ 0x73cb, 0x3d25,
+ 0x73cd, 0x1185,
+ 0x73ce, 0x3d27,
+ 0x73cf, 0x181d,
+ 0x73d0, 0x0646,
+ 0x73d1, 0x181f,
+ 0x73d2, 0x3d28,
+ 0x73d9, 0x1826,
+ 0x73da, 0x3d2f,
+ 0x73de, 0x182b,
+ 0x73df, 0x3d33,
+ 0x73e0, 0x11e8,
+ 0x73e1, 0x3d34,
+ 0x73e5, 0x1825,
+ 0x73e6, 0x3d38,
+ 0x73e7, 0x182a,
+ 0x73e8, 0x3d39,
+ 0x73e9, 0x1829,
+ 0x73ea, 0x3d3a,
+ 0x73ed, 0x03eb,
+ 0x73ee, 0x3d3d,
+ 0x73f2, 0x182d,
+ 0x73f3, 0x3d41,
+ 0x73fe, 0x21c0,
+ 0x73ff, 0x3d4c,
+ 0x7400, 0x3d4d,
+ 0x7403, 0x0c6f,
+ 0x7404, 0x3d50,
+ 0x7405, 0x09b0,
+ 0x7406, 0x09d8,
+ 0x7407, 0x3d51,
+ 0x7409, 0x0a39,
+ 0x740a, 0x1828,
+ 0x740b, 0x3d53,
+ 0x740f, 0x182e,
+ 0x7410, 0x0deb,
+ 0x7411, 0x3d57,
+ 0x741a, 0x1838,
+ 0x741b, 0x1837,
+ 0x741c, 0x3d60,
+ 0x7422, 0x121e,
+ 0x7423, 0x3d66,
+ 0x7425, 0x1832,
+ 0x7426, 0x1831,
+ 0x7427, 0x3d68,
+ 0x7428, 0x1833,
+ 0x7429, 0x3d69,
+ 0x742a, 0x182f,
+ 0x742b, 0x3d6a,
+ 0x742c, 0x1836,
+ 0x742d, 0x3d6b,
+ 0x742e, 0x1835,
+ 0x742f, 0x3d6c,
+ 0x7430, 0x1834,
+ 0x7431, 0x3d6d,
+ 0x7433, 0x0a1e,
+ 0x7434, 0x0c56,
+ 0x7435, 0x0bbe,
+ 0x7436, 0x0b84,
+ 0x7437, 0x3d6f,
+ 0x743c, 0x0c6a,
+ 0x743d, 0x3d74,
+ 0x743f, 0x2460,
+ 0x7440, 0x3d76,
+ 0x7441, 0x1839,
+ 0x7442, 0x3d77,
+ 0x744b, 0x245c,
+ 0x744c, 0x3d80,
+ 0x7455, 0x183c,
+ 0x7456, 0x3d89,
+ 0x7457, 0x183b,
+ 0x7458, 0x3d8a,
+ 0x7459, 0x183d,
+ 0x745a, 0x07ae,
+ 0x745b, 0x1830,
+ 0x745c, 0x183a,
+ 0x745d, 0x3d8b,
+ 0x745e, 0x0ccb,
+ 0x745f, 0x0ce3,
+ 0x7460, 0x3d8c,
+ 0x7463, 0x215d,
+ 0x7464, 0x3d8f,
+ 0x7469, 0x2225,
+ 0x746a, 0x206a,
+ 0x746b, 0x3d94,
+ 0x746d, 0x183f,
+ 0x746e, 0x3d96,
+ 0x7470, 0x073e,
+ 0x7471, 0x3d98,
+ 0x7476, 0x1027,
+ 0x7477, 0x183e,
+ 0x7478, 0x3d9d,
+ 0x747e, 0x1840,
+ 0x747f, 0x3da3,
+ 0x7480, 0x1843,
+ 0x7482, 0x3da4,
+ 0x7483, 0x09f0,
+ 0x7484, 0x3da5,
+ 0x7487, 0x1845,
+ 0x7488, 0x3da8,
+ 0x7489, 0x2461,
+ 0x748a, 0x3da9,
+ 0x748b, 0x1846,
+ 0x748c, 0x3daa,
+ 0x748e, 0x1842,
+ 0x748f, 0x3dac,
+ 0x7490, 0x184a,
+ 0x7491, 0x3dad,
+ 0x749c, 0x1841,
+ 0x749d, 0x3db8,
+ 0x749e, 0x1847,
+ 0x749f, 0x3db9,
+ 0x74a3, 0x245b,
+ 0x74a4, 0x3dbd,
+ 0x74a6, 0x2462,
+ 0x74a7, 0x184b,
+ 0x74a8, 0x1848,
+ 0x74aa, 0x3dbf,
+ 0x74b0, 0x1f54,
+ 0x74b1, 0x3dc5,
+ 0x74ba, 0x184d,
+ 0x74bb, 0x3dce,
+ 0x74bd, 0x245f,
+ 0x74be, 0x3dd0,
+ 0x74ca, 0x20ec,
+ 0x74cb, 0x3ddc,
+ 0x74cf, 0x245d,
+ 0x74d0, 0x3de0,
+ 0x74d2, 0x184c,
+ 0x74d3, 0x3de2,
+ 0x74d4, 0x2463,
+ 0x74d5, 0x3de3,
+ 0x74da, 0x2464,
+ 0x74db, 0x3de8,
+ 0x74dc, 0x0728,
+ 0x74dd, 0x3de9,
+ 0x74de, 0x1b32,
+ 0x74df, 0x3dea,
+ 0x74e0, 0x1b33,
+ 0x74e1, 0x3deb,
+ 0x74e2, 0x0bcf,
+ 0x74e3, 0x03f5,
+ 0x74e4, 0x0c9a,
+ 0x74e5, 0x3dec,
+ 0x74e6, 0x0e90,
+ 0x74e7, 0x3ded,
+ 0x74ee, 0x0edc,
+ 0x74ef, 0x1903,
+ 0x74f0, 0x3df4,
+ 0x74f4, 0x1904,
+ 0x74f5, 0x3df8,
+ 0x74f6, 0x0bde,
+ 0x74f7, 0x054c,
+ 0x74f8, 0x3df9,
+ 0x74ff, 0x1905,
+ 0x7500, 0x3e00,
+ 0x7504, 0x1188,
+ 0x7505, 0x3e04,
+ 0x750c, 0x24a5,
+ 0x750d, 0x1485,
+ 0x750e, 0x3e0b,
+ 0x750f, 0x1906,
+ 0x7510, 0x3e0c,
+ 0x7511, 0x1907,
+ 0x7512, 0x3e0d,
+ 0x7513, 0x1908,
+ 0x7514, 0x3e0e,
+ 0x7518, 0x06c5,
+ 0x7519, 0x14f8,
+ 0x751a, 0x0d2e,
+ 0x751b, 0x3e12,
+ 0x751c, 0x0e43,
+ 0x751d, 0x3e13,
+ 0x751f, 0x0d33,
+ 0x7520, 0x3e15,
+ 0x7523, 0x1e70,
+ 0x7524, 0x3e18,
+ 0x7525, 0x0d34,
+ 0x7526, 0x3e19,
+ 0x7528, 0x10a8,
+ 0x7529, 0x0d9b,
+ 0x752a, 0x3e1b,
+ 0x752b, 0x06a1,
+ 0x752c, 0x1b34,
+ 0x752d, 0x042b,
+ 0x752e, 0x3e1c,
+ 0x752f, 0x1734,
+ 0x7530, 0x0e42,
+ 0x7531, 0x10ae,
+ 0x7532, 0x084a,
+ 0x7533, 0x0d23,
+ 0x7534, 0x3e1d,
+ 0x7535, 0x05c8,
+ 0x7536, 0x3e1e,
+ 0x7537, 0x0b33,
+ 0x7538, 0x05ca,
+ 0x7539, 0x3e1f,
+ 0x753a, 0x1a78,
+ 0x753b, 0x07c2,
+ 0x753c, 0x3e20,
+ 0x753e, 0x1816,
+ 0x753f, 0x3e22,
+ 0x7540, 0x1a79,
+ 0x7541, 0x3e23,
+ 0x7545, 0x04ce,
+ 0x7546, 0x3e27,
+ 0x7548, 0x1a7c,
+ 0x7549, 0x3e29,
+ 0x754b, 0x1a7b,
+ 0x754c, 0x08b8,
+ 0x754d, 0x3e2b,
+ 0x754e, 0x1a7a,
+ 0x754f, 0x0ec6,
+ 0x7550, 0x3e2c,
+ 0x7554, 0x0b90,
+ 0x7555, 0x3e30,
+ 0x7559, 0x0a3d,
+ 0x755a, 0x139e,
+ 0x755b, 0x1a7d,
+ 0x755c, 0x0fbe,
+ 0x755d, 0x208f,
+ 0x755e, 0x3e34,
+ 0x7562, 0x1e42,
+ 0x7563, 0x3e38,
+ 0x7565, 0x0a7b,
+ 0x7566, 0x0c07,
+ 0x7567, 0x3e3a,
+ 0x756a, 0x0649,
+ 0x756b, 0x1f4e,
+ 0x756c, 0x3e3d,
+ 0x7572, 0x1a7e,
+ 0x7573, 0x3e43,
+ 0x7574, 0x0510,
+ 0x7575, 0x3e44,
+ 0x7576, 0x1eb1,
+ 0x7577, 0x3e45,
+ 0x7578, 0x0810,
+ 0x7579, 0x1a7f,
+ 0x757a, 0x3e46,
+ 0x757f, 0x1814,
+ 0x7580, 0x3e4b,
+ 0x7583, 0x1a80,
+ 0x7584, 0x3e4e,
+ 0x7586, 0x087f,
+ 0x7587, 0x1e8b,
+ 0x7588, 0x3e50,
+ 0x758b, 0x1bc6,
+ 0x758c, 0x3e53,
+ 0x758f, 0x0d7f,
+ 0x7590, 0x3e56,
+ 0x7591, 0x1050,
+ 0x7592, 0x1b60,
+ 0x7593, 0x3e57,
+ 0x7594, 0x1b61,
+ 0x7595, 0x3e58,
+ 0x7596, 0x1b62,
+ 0x7597, 0x0a0f,
+ 0x7598, 0x3e59,
+ 0x7599, 0x06e8,
+ 0x759a, 0x08fd,
+ 0x759b, 0x3e5a,
+ 0x759d, 0x1b64,
+ 0x759e, 0x3e5c,
+ 0x759f, 0x0b72,
+ 0x75a0, 0x1b63,
+ 0x75a1, 0x101a,
+ 0x75a2, 0x3e5d,
+ 0x75a3, 0x1b66,
+ 0x75a4, 0x03d7,
+ 0x75a5, 0x08bb,
+ 0x75a6, 0x3e5e,
+ 0x75ab, 0x1066,
+ 0x75ac, 0x1b65,
+ 0x75ad, 0x3e63,
+ 0x75ae, 0x0532,
+ 0x75af, 0x0685,
+ 0x75b0, 0x1b6c,
+ 0x75b1, 0x1b6b,
+ 0x75b2, 0x0bc2,
+ 0x75b3, 0x1b67,
+ 0x75b5, 0x0546,
+ 0x75b6, 0x3e64,
+ 0x75b8, 0x1b69,
+ 0x75b9, 0x118f,
+ 0x75ba, 0x3e66,
+ 0x75bc, 0x0e2e,
+ 0x75bd, 0x0901,
+ 0x75be, 0x0825,
+ 0x75bf, 0x3e68,
+ 0x75c2, 0x1b6e,
+ 0x75c3, 0x1b6d,
+ 0x75c4, 0x1b6a,
+ 0x75c5, 0x0468,
+ 0x75c6, 0x3e6b,
+ 0x75c7, 0x11a1,
+ 0x75c8, 0x109d,
+ 0x75c9, 0x08e6,
+ 0x75ca, 0x0c87,
+ 0x75cb, 0x3e6c,
+ 0x75cd, 0x1b70,
+ 0x75ce, 0x3e6e,
+ 0x75d2, 0x1020,
+ 0x75d3, 0x3e72,
+ 0x75d4, 0x11cb,
+ 0x75d5, 0x0792,
+ 0x75d6, 0x1b6f,
+ 0x75d7, 0x3e73,
+ 0x75d8, 0x05fa,
+ 0x75d9, 0x1fc6,
+ 0x75da, 0x3e74,
+ 0x75db, 0x0e65,
+ 0x75dc, 0x3e75,
+ 0x75de, 0x0bc5,
+ 0x75df, 0x3e77,
+ 0x75e2, 0x09ea,
+ 0x75e3, 0x1b71,
+ 0x75e4, 0x1b74,
+ 0x75e5, 0x3e7a,
+ 0x75e6, 0x1b73,
+ 0x75e7, 0x1b76,
+ 0x75e8, 0x1b72,
+ 0x75e9, 0x3e7b,
+ 0x75ea, 0x07d3,
+ 0x75eb, 0x1b75,
+ 0x75ec, 0x3e7c,
+ 0x75f0, 0x0e08,
+ 0x75f1, 0x1b78,
+ 0x75f2, 0x3e80,
+ 0x75f4, 0x04fa,
+ 0x75f5, 0x3e82,
+ 0x75f9, 0x043d,
+ 0x75fa, 0x3e86,
+ 0x75fc, 0x1b79,
+ 0x75fd, 0x3e88,
+ 0x75ff, 0x1b7a,
+ 0x7600, 0x1b7c,
+ 0x7601, 0x0564,
+ 0x7602, 0x25ae,
+ 0x7603, 0x1b77,
+ 0x7604, 0x3e8a,
+ 0x7605, 0x1b7d,
+ 0x7606, 0x3e8b,
+ 0x760a, 0x1b80,
+ 0x760b, 0x1f01,
+ 0x760c, 0x1b7e,
+ 0x760d, 0x2200,
+ 0x760e, 0x3e8f,
+ 0x7610, 0x1b7b,
+ 0x7611, 0x3e91,
+ 0x7615, 0x1b83,
+ 0x7616, 0x3e95,
+ 0x7617, 0x1b7f,
+ 0x7618, 0x1b82,
+ 0x7619, 0x1b84,
+ 0x761a, 0x3e96,
+ 0x761b, 0x1b85,
+ 0x761c, 0x3e97,
+ 0x761e, 0x25b2,
+ 0x761f, 0x0ed0,
+ 0x7620, 0x1b88,
+ 0x7621, 0x1e97,
+ 0x7622, 0x1b87,
+ 0x7623, 0x3e99,
+ 0x7624, 0x0a3f,
+ 0x7625, 0x1b81,
+ 0x7626, 0x0d74,
+ 0x7627, 0x20ab,
+ 0x7628, 0x3e9a,
+ 0x7629, 0x0574,
+ 0x762a, 0x045a,
+ 0x762b, 0x0e04,
+ 0x762c, 0x3e9b,
+ 0x762d, 0x1b8a,
+ 0x762e, 0x3e9c,
+ 0x7630, 0x1b8b,
+ 0x7631, 0x3e9e,
+ 0x7633, 0x1b90,
+ 0x7634, 0x116f,
+ 0x7635, 0x1b8d,
+ 0x7636, 0x3ea0,
+ 0x7638, 0x0c8e,
+ 0x7639, 0x3ea2,
+ 0x763b, 0x25b3,
+ 0x763c, 0x1b86,
+ 0x763d, 0x3ea4,
+ 0x763e, 0x1b8f,
+ 0x763f, 0x1b8c,
+ 0x7640, 0x1b89,
+ 0x7641, 0x3ea5,
+ 0x7642, 0x2028,
+ 0x7643, 0x1b8e,
+ 0x7644, 0x3ea6,
+ 0x7646, 0x25af,
+ 0x7648, 0x3ea8,
+ 0x7649, 0x25b1,
+ 0x764a, 0x3ea9,
+ 0x764c, 0x03b4,
+ 0x764d, 0x1b91,
+ 0x764e, 0x3eab,
+ 0x7654, 0x1b93,
+ 0x7655, 0x3eb1,
+ 0x7656, 0x1b95,
+ 0x7657, 0x3eb2,
+ 0x7658, 0x25ac,
+ 0x7659, 0x3eb3,
+ 0x765c, 0x1b94,
+ 0x765d, 0x3eb6,
+ 0x765e, 0x1b92,
+ 0x765f, 0x1e4e,
+ 0x7660, 0x3eb7,
+ 0x7662, 0x2202,
+ 0x7663, 0x0fcb,
+ 0x7664, 0x25ab,
+ 0x7665, 0x2286,
+ 0x7666, 0x3eb9,
+ 0x7667, 0x25ad,
+ 0x7668, 0x3eba,
+ 0x7669, 0x25b6,
+ 0x766a, 0x3ebb,
+ 0x766b, 0x1b96,
+ 0x766c, 0x21e3,
+ 0x766d, 0x25b4,
+ 0x766f, 0x1b97,
+ 0x7670, 0x222f,
+ 0x7671, 0x2165,
+ 0x7672, 0x25b7,
+ 0x7673, 0x3ebc,
+ 0x7678, 0x0748,
+ 0x7679, 0x3ec1,
+ 0x767b, 0x05a8,
+ 0x767c, 0x1ee9,
+ 0x767d, 0x03e2,
+ 0x767e, 0x03e4,
+ 0x767f, 0x3ec3,
+ 0x7682, 0x1130,
+ 0x7683, 0x3ec6,
+ 0x7684, 0x05a5,
+ 0x7685, 0x3ec7,
+ 0x7686, 0x08a5,
+ 0x7687, 0x07df,
+ 0x7688, 0x1b2d,
+ 0x7689, 0x3ec8,
+ 0x768b, 0x06d9,
+ 0x768c, 0x3eca,
+ 0x768e, 0x1b2e,
+ 0x768f, 0x3ecc,
+ 0x7691, 0x03b3,
+ 0x7692, 0x3ece,
+ 0x7693, 0x1b2f,
+ 0x7694, 0x3ecf,
+ 0x7696, 0x0e9f,
+ 0x7697, 0x3ed1,
+ 0x7699, 0x1b30,
+ 0x769a, 0x1e25,
+ 0x769b, 0x3ed3,
+ 0x76a4, 0x1b31,
+ 0x76a5, 0x3edc,
+ 0x76ae, 0x0bc3,
+ 0x76af, 0x3ee5,
+ 0x76b1, 0x11e4,
+ 0x76b2, 0x1bc8,
+ 0x76b3, 0x3ee7,
+ 0x76b4, 0x1bc9,
+ 0x76b5, 0x3ee8,
+ 0x76b8, 0x25c0,
+ 0x76b9, 0x3eeb,
+ 0x76ba, 0x229a,
+ 0x76bb, 0x3eec,
+ 0x76bf, 0x0af8,
+ 0x76c0, 0x3ef0,
+ 0x76c2, 0x10c0,
+ 0x76c3, 0x3ef2,
+ 0x76c5, 0x11d0,
+ 0x76c6, 0x0ba9,
+ 0x76c7, 0x3ef4,
+ 0x76c8, 0x1094,
+ 0x76c9, 0x3ef5,
+ 0x76ca, 0x106d,
+ 0x76cb, 0x3ef6,
+ 0x76cd, 0x1a8b,
+ 0x76ce, 0x03c6,
+ 0x76cf, 0x1156,
+ 0x76d0, 0x0ff7,
+ 0x76d1, 0x0853,
+ 0x76d2, 0x0787,
+ 0x76d3, 0x3ef8,
+ 0x76d4, 0x0985,
+ 0x76d5, 0x3ef9,
+ 0x76d6, 0x06c2,
+ 0x76d7, 0x05a2,
+ 0x76d8, 0x0b8d,
+ 0x76d9, 0x3efa,
+ 0x76db, 0x0d39,
+ 0x76dc, 0x3efc,
+ 0x76de, 0x226e,
+ 0x76df, 0x0ad0,
+ 0x76e0, 0x3efe,
+ 0x76e1, 0x1fbd,
+ 0x76e2, 0x3eff,
+ 0x76e3, 0x1f84,
+ 0x76e4, 0x20b2,
+ 0x76e5, 0x1a8c,
+ 0x76e6, 0x3f00,
+ 0x76e7, 0x2043,
+ 0x76e8, 0x3f01,
+ 0x76ee, 0x0b22,
+ 0x76ef, 0x05e1,
+ 0x76f0, 0x3f07,
+ 0x76f1, 0x1a58,
+ 0x76f2, 0x0aa9,
+ 0x76f3, 0x3f08,
+ 0x76f4, 0x11b0,
+ 0x76f5, 0x3f09,
+ 0x76f8, 0x0f4d,
+ 0x76f9, 0x1a5b,
+ 0x76fa, 0x3f0c,
+ 0x76fc, 0x0b8f,
+ 0x76fd, 0x3f0e,
+ 0x76fe, 0x061b,
+ 0x76ff, 0x3f0f,
+ 0x7700, 0x3f10,
+ 0x7701, 0x0d38,
+ 0x7702, 0x3f11,
+ 0x7704, 0x1a59,
+ 0x7705, 0x3f13,
+ 0x7707, 0x1a5c,
+ 0x7709, 0x0ac1,
+ 0x770a, 0x3f15,
+ 0x770b, 0x0941,
+ 0x770c, 0x3f16,
+ 0x770d, 0x1a5a,
+ 0x770e, 0x3f17,
+ 0x7719, 0x1a60,
+ 0x771a, 0x1a5e,
+ 0x771b, 0x3f22,
+ 0x771f, 0x1187,
+ 0x7720, 0x0ae4,
+ 0x7721, 0x3f26,
+ 0x7722, 0x1a5f,
+ 0x7723, 0x3f27,
+ 0x7726, 0x1a62,
+ 0x7727, 0x3f2a,
+ 0x7728, 0x1144,
+ 0x7729, 0x0fcc,
+ 0x772a, 0x3f2b,
+ 0x772d, 0x1a61,
+ 0x772e, 0x3f2e,
+ 0x772f, 0x0ad5,
+ 0x7730, 0x3f2f,
+ 0x7735, 0x1a63,
+ 0x7736, 0x0981,
+ 0x7737, 0x091b,
+ 0x7738, 0x1a64,
+ 0x7739, 0x3f34,
+ 0x773a, 0x0e4a,
+ 0x773b, 0x3f35,
+ 0x773c, 0x1004,
+ 0x773d, 0x3f36,
+ 0x7740, 0x1222,
+ 0x7741, 0x1197,
+ 0x7742, 0x3f39,
+ 0x7743, 0x1a68,
+ 0x7744, 0x3f3a,
+ 0x7747, 0x1a67,
+ 0x7748, 0x3f3d,
+ 0x774f, 0x2684,
+ 0x7750, 0x1a65,
+ 0x7752, 0x3f44,
+ 0x775a, 0x1a69,
+ 0x775b, 0x08d5,
+ 0x775c, 0x3f4c,
+ 0x775e, 0x24ef,
+ 0x775f, 0x3f4e,
+ 0x7761, 0x0da4,
+ 0x7762, 0x1a6b,
+ 0x7763, 0x05fc,
+ 0x7764, 0x3f50,
+ 0x7765, 0x1a6c,
+ 0x7766, 0x0b23,
+ 0x7767, 0x3f51,
+ 0x7768, 0x1a6a,
+ 0x7769, 0x3f52,
+ 0x776b, 0x08af,
+ 0x776c, 0x048e,
+ 0x776d, 0x3f54,
+ 0x7779, 0x0602,
+ 0x777a, 0x3f60,
+ 0x777d, 0x1a6f,
+ 0x777e, 0x1270,
+ 0x777f, 0x1a6d,
+ 0x7780, 0x1a70,
+ 0x7781, 0x3f63,
+ 0x7784, 0x0aee,
+ 0x7785, 0x0517,
+ 0x7786, 0x3f66,
+ 0x778c, 0x1a71,
+ 0x778d, 0x1a6e,
+ 0x778e, 0x0f26,
+ 0x778f, 0x3f6c,
+ 0x7791, 0x1a72,
+ 0x7792, 0x0a9e,
+ 0x7793, 0x3f6e,
+ 0x7798, 0x24ee,
+ 0x7799, 0x3f73,
+ 0x779e, 0x2074,
+ 0x779f, 0x1a73,
+ 0x77a1, 0x3f78,
+ 0x77a2, 0x1495,
+ 0x77a3, 0x3f79,
+ 0x77a5, 0x0bd2,
+ 0x77a6, 0x3f7b,
+ 0x77a7, 0x0c43,
+ 0x77a8, 0x3f7c,
+ 0x77a9, 0x11f4,
+ 0x77aa, 0x05aa,
+ 0x77ab, 0x3f7d,
+ 0x77ac, 0x0da7,
+ 0x77ad, 0x2687,
+ 0x77ae, 0x3f7e,
+ 0x77b0, 0x1a75,
+ 0x77b1, 0x3f80,
+ 0x77b3, 0x0e5c,
+ 0x77b4, 0x3f82,
+ 0x77b5, 0x1a76,
+ 0x77b6, 0x3f83,
+ 0x77bb, 0x1151,
+ 0x77bc, 0x24f0,
+ 0x77bd, 0x1a77,
+ 0x77be, 0x3f88,
+ 0x77bf, 0x1d7e,
+ 0x77c0, 0x3f89,
+ 0x77c7, 0x268d,
+ 0x77c8, 0x3f90,
+ 0x77cd, 0x1397,
+ 0x77ce, 0x3f95,
+ 0x77d7, 0x0526,
+ 0x77d8, 0x3f9e,
+ 0x77da, 0x22a0,
+ 0x77db, 0x0ab1,
+ 0x77dc, 0x1bca,
+ 0x77dd, 0x3fa0,
+ 0x77e2, 0x0d4f,
+ 0x77e3, 0x105a,
+ 0x77e4, 0x3fa5,
+ 0x77e5, 0x11a9,
+ 0x77e6, 0x3fa6,
+ 0x77e7, 0x1b1a,
+ 0x77e8, 0x3fa7,
+ 0x77e9, 0x0907,
+ 0x77ea, 0x3fa8,
+ 0x77eb, 0x0894,
+ 0x77ec, 0x1b1b,
+ 0x77ed, 0x060b,
+ 0x77ee, 0x03b6,
+ 0x77ef, 0x1fab,
+ 0x77f0, 0x3fa9,
+ 0x77f3, 0x0d46,
+ 0x77f4, 0x3fac,
+ 0x77f6, 0x1a22,
+ 0x77f7, 0x3fae,
+ 0x77f8, 0x1a23,
+ 0x77f9, 0x3faf,
+ 0x77fd, 0x0f08,
+ 0x77fe, 0x064c,
+ 0x77ff, 0x0980,
+ 0x7800, 0x1a24,
+ 0x7801, 0x0a92,
+ 0x7802, 0x0ce9,
+ 0x7803, 0x3fb3,
+ 0x7809, 0x1a25,
+ 0x780a, 0x3fb9,
+ 0x780c, 0x0c15,
+ 0x780d, 0x0940,
+ 0x780e, 0x3fbb,
+ 0x7811, 0x1a28,
+ 0x7812, 0x0bb9,
+ 0x7813, 0x3fbe,
+ 0x7814, 0x0ff9,
+ 0x7815, 0x3fbf,
+ 0x7816, 0x1206,
+ 0x7817, 0x1a26,
+ 0x7819, 0x3fc0,
+ 0x781a, 0x100b,
+ 0x781b, 0x3fc1,
+ 0x781c, 0x1a2b,
+ 0x781e, 0x3fc2,
+ 0x781f, 0x1a30,
+ 0x7820, 0x3fc3,
+ 0x7823, 0x1a34,
+ 0x7824, 0x3fc6,
+ 0x7825, 0x1a32,
+ 0x7826, 0x1a3a,
+ 0x7827, 0x1189,
+ 0x7828, 0x3fc7,
+ 0x7829, 0x1a35,
+ 0x782a, 0x3fc8,
+ 0x782c, 0x1a33,
+ 0x782d, 0x1a2a,
+ 0x782e, 0x3fca,
+ 0x7830, 0x0baa,
+ 0x7831, 0x3fcc,
+ 0x7834, 0x0be5,
+ 0x7835, 0x3fcf,
+ 0x7837, 0x0d22,
+ 0x7838, 0x1115,
+ 0x7839, 0x1a2d,
+ 0x783c, 0x1a31,
+ 0x783d, 0x3fd1,
+ 0x783e, 0x09e4,
+ 0x783f, 0x3fd2,
+ 0x7840, 0x0524,
+ 0x7841, 0x3fd3,
+ 0x7843, 0x26a8,
+ 0x7844, 0x3fd5,
+ 0x7845, 0x0741,
+ 0x7846, 0x3fd6,
+ 0x7847, 0x1a3c,
+ 0x7848, 0x3fd7,
+ 0x784c, 0x1a3d,
+ 0x784d, 0x3fdb,
+ 0x784e, 0x1a36,
+ 0x784f, 0x3fdc,
+ 0x7850, 0x1a3b,
+ 0x7851, 0x3fdd,
+ 0x7852, 0x0f07,
+ 0x7853, 0x3fde,
+ 0x7855, 0x0dab,
+ 0x7856, 0x1a38,
+ 0x7858, 0x3fe0,
+ 0x785d, 0x0f62,
+ 0x785e, 0x3fe5,
+ 0x7864, 0x24e9,
+ 0x7865, 0x3feb,
+ 0x7868, 0x24e5,
+ 0x7869, 0x3fee,
+ 0x786a, 0x1a3e,
+ 0x786b, 0x0a3b,
+ 0x786c, 0x1097,
+ 0x786d, 0x1a37,
+ 0x786e, 0x0c92,
+ 0x786f, 0x21fa,
+ 0x7870, 0x3fef,
+ 0x7877, 0x0862,
+ 0x7878, 0x3ff6,
+ 0x787c, 0x0bb1,
+ 0x787d, 0x3ffa,
+ 0x7887, 0x1a42,
+ 0x7888, 0x4004,
+ 0x7889, 0x05d0,
+ 0x788a, 0x4005,
+ 0x788c, 0x0a5c,
+ 0x788d, 0x03b8,
+ 0x788e, 0x0dde,
+ 0x788f, 0x4007,
+ 0x7891, 0x0417,
+ 0x7892, 0x4009,
+ 0x7893, 0x1a40,
+ 0x7894, 0x400a,
+ 0x7897, 0x0e9c,
+ 0x7898, 0x05c3,
+ 0x7899, 0x400d,
+ 0x789a, 0x1a41,
+ 0x789b, 0x1a3f,
+ 0x789c, 0x1a43,
+ 0x789d, 0x400e,
+ 0x789f, 0x05db,
+ 0x78a0, 0x4010,
+ 0x78a1, 0x1a44,
+ 0x78a2, 0x4011,
+ 0x78a3, 0x1a45,
+ 0x78a4, 0x4012,
+ 0x78a5, 0x1a48,
+ 0x78a6, 0x4013,
+ 0x78a7, 0x0435,
+ 0x78a8, 0x4014,
+ 0x78a9, 0x2148,
+ 0x78aa, 0x4015,
+ 0x78ad, 0x24e4,
+ 0x78ae, 0x4018,
+ 0x78b0, 0x0bb7,
+ 0x78b1, 0x0861,
+ 0x78b2, 0x1a46,
+ 0x78b3, 0x0e0f,
+ 0x78b4, 0x04b1,
+ 0x78b5, 0x401a,
+ 0x78b8, 0x24e6,
+ 0x78b9, 0x1a47,
+ 0x78ba, 0x20f7,
+ 0x78bb, 0x401d,
+ 0x78bc, 0x206b,
+ 0x78bd, 0x401e,
+ 0x78be, 0x0b4e,
+ 0x78bf, 0x401f,
+ 0x78c1, 0x0548,
+ 0x78c2, 0x4021,
+ 0x78c5, 0x0400,
+ 0x78c6, 0x4024,
+ 0x78c9, 0x1a4b,
+ 0x78ca, 0x09c5,
+ 0x78cb, 0x056b,
+ 0x78cc, 0x4027,
+ 0x78d0, 0x0b8e,
+ 0x78d1, 0x402b,
+ 0x78d4, 0x1a49,
+ 0x78d5, 0x0951,
+ 0x78d6, 0x402e,
+ 0x78d9, 0x1a4a,
+ 0x78da, 0x22a7,
+ 0x78db, 0x4031,
+ 0x78e3, 0x24ec,
+ 0x78e4, 0x4039,
+ 0x78e7, 0x24eb,
+ 0x78e8, 0x0b08,
+ 0x78e9, 0x403c,
+ 0x78ec, 0x1a4c,
+ 0x78ed, 0x403f,
+ 0x78ef, 0x24e3,
+ 0x78f0, 0x4041,
+ 0x78f2, 0x1a4d,
+ 0x78f3, 0x4043,
+ 0x78f4, 0x1a4f,
+ 0x78f5, 0x4044,
+ 0x78f7, 0x0a20,
+ 0x78f8, 0x4046,
+ 0x78fa, 0x07dc,
+ 0x78fb, 0x4048,
+ 0x78fd, 0x24ea,
+ 0x78fe, 0x404a,
+ 0x7900, 0x404c,
+ 0x7901, 0x0889,
+ 0x7902, 0x404d,
+ 0x7905, 0x1a4e,
+ 0x7906, 0x4050,
+ 0x790e, 0x1e92,
+ 0x790f, 0x4058,
+ 0x7913, 0x1a50,
+ 0x7914, 0x405c,
+ 0x7919, 0x1e27,
+ 0x791a, 0x4061,
+ 0x791e, 0x1a52,
+ 0x791f, 0x4065,
+ 0x7924, 0x1a51,
+ 0x7925, 0x406a,
+ 0x7926, 0x1fe6,
+ 0x7927, 0x406b,
+ 0x792a, 0x24e7,
+ 0x792b, 0x2012,
+ 0x792c, 0x1eec,
+ 0x792d, 0x406e,
+ 0x7931, 0x24e8,
+ 0x7932, 0x4072,
+ 0x7934, 0x1a53,
+ 0x7935, 0x4074,
+ 0x793a, 0x0d55,
+ 0x793b, 0x19f8,
+ 0x793c, 0x09dc,
+ 0x793d, 0x4079,
+ 0x793e, 0x0d20,
+ 0x793f, 0x407a,
+ 0x7940, 0x19f9,
+ 0x7941, 0x0c0d,
+ 0x7942, 0x407b,
+ 0x7946, 0x19fa,
+ 0x7947, 0x407f,
+ 0x7948, 0x0c0c,
+ 0x7949, 0x19fb,
+ 0x794a, 0x4080,
+ 0x7953, 0x19fe,
+ 0x7954, 0x4089,
+ 0x7956, 0x1243,
+ 0x7957, 0x1a01,
+ 0x7958, 0x408b,
+ 0x795a, 0x19ff,
+ 0x795b, 0x19fc,
+ 0x795d, 0x1200,
+ 0x795e, 0x0d2a,
+ 0x795f, 0x0de3,
+ 0x7960, 0x1a02,
+ 0x7961, 0x408d,
+ 0x7962, 0x1a00,
+ 0x7963, 0x408e,
+ 0x7965, 0x0f56,
+ 0x7966, 0x4090,
+ 0x7967, 0x1a04,
+ 0x7968, 0x0bd0,
+ 0x7969, 0x4091,
+ 0x796d, 0x0833,
+ 0x796e, 0x4095,
+ 0x796f, 0x1a03,
+ 0x7970, 0x4096,
+ 0x7977, 0x059c,
+ 0x7978, 0x080b,
+ 0x7979, 0x409d,
+ 0x797a, 0x1a05,
+ 0x797b, 0x409e,
+ 0x7980, 0x130b,
+ 0x7981, 0x08cc,
+ 0x7982, 0x40a3,
+ 0x7984, 0x0a62,
+ 0x7985, 0x1a06,
+ 0x7986, 0x40a5,
+ 0x798a, 0x1a07,
+ 0x798b, 0x40a9,
+ 0x798d, 0x1f66,
+ 0x798e, 0x24dc,
+ 0x798f, 0x069e,
+ 0x7990, 0x40ab,
+ 0x799a, 0x1a08,
+ 0x799b, 0x40b5,
+ 0x79a6, 0x26a2,
+ 0x79a7, 0x1a09,
+ 0x79a8, 0x40c0,
+ 0x79aa, 0x24dd,
+ 0x79ab, 0x40c2,
+ 0x79ae, 0x200e,
+ 0x79af, 0x40c5,
+ 0x79b0, 0x24db,
+ 0x79b1, 0x1eb8,
+ 0x79b2, 0x40c6,
+ 0x79b3, 0x1a0a,
+ 0x79b4, 0x40c7,
+ 0x79b9, 0x10d2,
+ 0x79ba, 0x1264,
+ 0x79bb, 0x09d6,
+ 0x79bc, 0x40cc,
+ 0x79bd, 0x0c5a,
+ 0x79be, 0x0783,
+ 0x79bf, 0x40cd,
+ 0x79c0, 0x0fae,
+ 0x79c1, 0x0db2,
+ 0x79c2, 0x40ce,
+ 0x79c3, 0x0e6b,
+ 0x79c4, 0x40cf,
+ 0x79c6, 0x06cc,
+ 0x79c7, 0x40d1,
+ 0x79c9, 0x0465,
+ 0x79ca, 0x40d3,
+ 0x79cb, 0x0c6c,
+ 0x79cc, 0x40d4,
+ 0x79cd, 0x11d5,
+ 0x79ce, 0x40d5,
+ 0x79d1, 0x0953,
+ 0x79d2, 0x0af0,
+ 0x79d3, 0x40d8,
+ 0x79d5, 0x1b1d,
+ 0x79d6, 0x40da,
+ 0x79d8, 0x0add,
+ 0x79d9, 0x40dc,
+ 0x79df, 0x123f,
+ 0x79e0, 0x40e2,
+ 0x79e3, 0x1b1f,
+ 0x79e4, 0x04f8,
+ 0x79e5, 0x40e5,
+ 0x79e6, 0x0c55,
+ 0x79e7, 0x1016,
+ 0x79e8, 0x40e6,
+ 0x79e9, 0x11c7,
+ 0x79ea, 0x40e7,
+ 0x79eb, 0x1b20,
+ 0x79ec, 0x40e8,
+ 0x79ed, 0x1b1e,
+ 0x79ee, 0x40e9,
+ 0x79ef, 0x0812,
+ 0x79f0, 0x04eb,
+ 0x79f1, 0x40ea,
+ 0x79f8, 0x08a6,
+ 0x79f9, 0x40f1,
+ 0x79fb, 0x104d,
+ 0x79fc, 0x40f3,
+ 0x79fd, 0x07f5,
+ 0x79fe, 0x40f4,
+ 0x7a00, 0x0f0e,
+ 0x7a01, 0x40f6,
+ 0x7a02, 0x1b24,
+ 0x7a03, 0x1b23,
+ 0x7a04, 0x40f7,
+ 0x7a06, 0x1b21,
+ 0x7a07, 0x40f9,
+ 0x7a0b, 0x04f1,
+ 0x7a0c, 0x40fd,
+ 0x7a0d, 0x0d0d,
+ 0x7a0e, 0x0da5,
+ 0x7a0f, 0x40fe,
+ 0x7a14, 0x1b26,
+ 0x7a15, 0x4103,
+ 0x7a17, 0x03e9,
+ 0x7a18, 0x4105,
+ 0x7a1a, 0x11c8,
+ 0x7a1b, 0x4107,
+ 0x7a1e, 0x1b25,
+ 0x7a1f, 0x410a,
+ 0x7a20, 0x0512,
+ 0x7a21, 0x410b,
+ 0x7a23, 0x1d8f,
+ 0x7a24, 0x410d,
+ 0x7a2e, 0x2295,
+ 0x7a2f, 0x4117,
+ 0x7a31, 0x1e80,
+ 0x7a32, 0x4119,
+ 0x7a33, 0x0ed7,
+ 0x7a34, 0x411a,
+ 0x7a37, 0x1b28,
+ 0x7a38, 0x411d,
+ 0x7a39, 0x1b27,
+ 0x7a3a, 0x411e,
+ 0x7a3b, 0x059f,
+ 0x7a3c, 0x084d,
+ 0x7a3d, 0x0811,
+ 0x7a3e, 0x411f,
+ 0x7a3f, 0x06e0,
+ 0x7a40, 0x2677,
+ 0x7a41, 0x4120,
+ 0x7a46, 0x0b25,
+ 0x7a47, 0x4125,
+ 0x7a4c, 0x2624,
+ 0x7a4d, 0x1f69,
+ 0x7a4e, 0x222b,
+ 0x7a4f, 0x412a,
+ 0x7a51, 0x1b29,
+ 0x7a52, 0x412c,
+ 0x7a57, 0x0de0,
+ 0x7a58, 0x4131,
+ 0x7a61, 0x257f,
+ 0x7a62, 0x1f5b,
+ 0x7a63, 0x413a,
+ 0x7a69, 0x219b,
+ 0x7a6a, 0x4140,
+ 0x7a6b, 0x267d,
+ 0x7a6c, 0x4141,
+ 0x7a70, 0x1b2c,
+ 0x7a71, 0x4145,
+ 0x7a74, 0x0fd1,
+ 0x7a75, 0x4148,
+ 0x7a76, 0x08ee,
+ 0x7a77, 0x0c6b,
+ 0x7a78, 0x1b9a,
+ 0x7a7a, 0x0962,
+ 0x7a7b, 0x4149,
+ 0x7a7f, 0x052c,
+ 0x7a80, 0x1b9c,
+ 0x7a81, 0x0e6c,
+ 0x7a82, 0x414d,
+ 0x7a83, 0x0c51,
+ 0x7a84, 0x114e,
+ 0x7a85, 0x414e,
+ 0x7a86, 0x1b9d,
+ 0x7a87, 0x414f,
+ 0x7a88, 0x1b9e,
+ 0x7a89, 0x4150,
+ 0x7a8d, 0x0c4c,
+ 0x7a8e, 0x4154,
+ 0x7a91, 0x102b,
+ 0x7a92, 0x11ce,
+ 0x7a93, 0x4157,
+ 0x7a95, 0x1b9f,
+ 0x7a96, 0x08a2,
+ 0x7a97, 0x0533,
+ 0x7a98, 0x08ec,
+ 0x7a99, 0x4159,
+ 0x7a9c, 0x055f,
+ 0x7a9d, 0x0ee0,
+ 0x7a9e, 0x415c,
+ 0x7a9f, 0x096c,
+ 0x7aa0, 0x1ba1,
+ 0x7aa1, 0x415d,
+ 0x7aa5, 0x0987,
+ 0x7aa6, 0x1ba0,
+ 0x7aa7, 0x4161,
+ 0x7aa8, 0x1ba3,
+ 0x7aa9, 0x21a0,
+ 0x7aaa, 0x2186,
+ 0x7aab, 0x4162,
+ 0x7aac, 0x1ba2,
+ 0x7aad, 0x1ba4,
+ 0x7aae, 0x20ed,
+ 0x7aaf, 0x4163,
+ 0x7ab3, 0x1ba5,
+ 0x7ab4, 0x4167,
+ 0x7ab6, 0x25b9,
+ 0x7ab7, 0x4169,
+ 0x7aba, 0x1fea,
+ 0x7abb, 0x416c,
+ 0x7abf, 0x0a47,
+ 0x7ac0, 0x4170,
+ 0x7ac4, 0x1ea4,
+ 0x7ac5, 0x20e1,
+ 0x7ac6, 0x4174,
+ 0x7ac7, 0x25b8,
+ 0x7ac8, 0x2260,
+ 0x7ac9, 0x4175,
+ 0x7aca, 0x20e2,
+ 0x7acb, 0x09eb,
+ 0x7acc, 0x4176,
+ 0x7ad6, 0x0d91,
+ 0x7ad7, 0x4180,
+ 0x7ad9, 0x115f,
+ 0x7ada, 0x4182,
+ 0x7ade, 0x08e9,
+ 0x7adf, 0x08e8,
+ 0x7ae0, 0x1163,
+ 0x7ae1, 0x4186,
+ 0x7ae3, 0x092f,
+ 0x7ae4, 0x4188,
+ 0x7ae5, 0x0e60,
+ 0x7ae6, 0x1b99,
+ 0x7ae7, 0x4189,
+ 0x7aea, 0x2141,
+ 0x7aeb, 0x418c,
+ 0x7aed, 0x08b0,
+ 0x7aee, 0x418e,
+ 0x7aef, 0x060a,
+ 0x7af0, 0x418f,
+ 0x7af6, 0x1fc7,
+ 0x7af7, 0x4195,
+ 0x7af9, 0x11f0,
+ 0x7afa, 0x1c63,
+ 0x7afb, 0x4197,
+ 0x7afd, 0x1c64,
+ 0x7afe, 0x4199,
+ 0x7aff, 0x06c8,
+ 0x7b00, 0x419a,
+ 0x7b03, 0x1c66,
+ 0x7b05, 0x419d,
+ 0x7b06, 0x03d5,
+ 0x7b07, 0x419e,
+ 0x7b08, 0x1c65,
+ 0x7b09, 0x419f,
+ 0x7b0a, 0x1c69,
+ 0x7b0b, 0x0de6,
+ 0x7b0c, 0x41a0,
+ 0x7b0f, 0x1c6b,
+ 0x7b10, 0x41a3,
+ 0x7b11, 0x0f71,
+ 0x7b12, 0x41a4,
+ 0x7b14, 0x0433,
+ 0x7b15, 0x1c68,
+ 0x7b16, 0x41a6,
+ 0x7b19, 0x1c6f,
+ 0x7b1a, 0x41a9,
+ 0x7b1b, 0x05b2,
+ 0x7b1c, 0x41aa,
+ 0x7b1e, 0x1c77,
+ 0x7b1f, 0x41ac,
+ 0x7b20, 0x1c72,
+ 0x7b21, 0x41ad,
+ 0x7b24, 0x1c74,
+ 0x7b25, 0x1c73,
+ 0x7b26, 0x0698,
+ 0x7b27, 0x41b0,
+ 0x7b28, 0x0428,
+ 0x7b29, 0x41b1,
+ 0x7b2a, 0x1c6e,
+ 0x7b2b, 0x1c6a,
+ 0x7b2c, 0x05bb,
+ 0x7b2d, 0x41b2,
+ 0x7b2e, 0x1c70,
+ 0x7b2f, 0x41b3,
+ 0x7b31, 0x1c71,
+ 0x7b32, 0x41b5,
+ 0x7b33, 0x1c75,
+ 0x7b34, 0x41b6,
+ 0x7b38, 0x1c6d,
+ 0x7b39, 0x41ba,
+ 0x7b3a, 0x0856,
+ 0x7b3b, 0x41bb,
+ 0x7b3c, 0x0a46,
+ 0x7b3d, 0x41bc,
+ 0x7b3e, 0x1c76,
+ 0x7b3f, 0x41bd,
+ 0x7b45, 0x1c7a,
+ 0x7b46, 0x1e41,
+ 0x7b47, 0x1c6c,
+ 0x7b48, 0x41c3,
+ 0x7b49, 0x05a9,
+ 0x7b4a, 0x41c4,
+ 0x7b4b, 0x08bf,
+ 0x7b4c, 0x1c7c,
+ 0x7b4d, 0x41c5,
+ 0x7b4f, 0x0641,
+ 0x7b50, 0x097d,
+ 0x7b51, 0x11fd,
+ 0x7b52, 0x0e63,
+ 0x7b53, 0x41c7,
+ 0x7b54, 0x0573,
+ 0x7b55, 0x41c8,
+ 0x7b56, 0x04a6,
+ 0x7b57, 0x41c9,
+ 0x7b58, 0x1c78,
+ 0x7b59, 0x41ca,
+ 0x7b5a, 0x1c79,
+ 0x7b5b, 0x0cf1,
+ 0x7b5c, 0x41cb,
+ 0x7b5d, 0x1c7d,
+ 0x7b5e, 0x41cc,
+ 0x7b60, 0x1c7e,
+ 0x7b61, 0x41ce,
+ 0x7b62, 0x1c81,
+ 0x7b63, 0x41cf,
+ 0x7b67, 0x25e4,
+ 0x7b68, 0x41d3,
+ 0x7b6e, 0x1c7f,
+ 0x7b6f, 0x41d9,
+ 0x7b71, 0x1c83,
+ 0x7b72, 0x1c82,
+ 0x7b73, 0x41db,
+ 0x7b75, 0x1c7b,
+ 0x7b76, 0x41dd,
+ 0x7b77, 0x0977,
+ 0x7b78, 0x41de,
+ 0x7b79, 0x0514,
+ 0x7b7a, 0x41df,
+ 0x7b7b, 0x1c80,
+ 0x7b7c, 0x41e0,
+ 0x7b7e, 0x0c26,
+ 0x7b7f, 0x41e2,
+ 0x7b80, 0x0865,
+ 0x7b81, 0x41e3,
+ 0x7b85, 0x1c8b,
+ 0x7b86, 0x41e7,
+ 0x7b8b, 0x1f86,
+ 0x7b8c, 0x41ec,
+ 0x7b8d, 0x0718,
+ 0x7b8e, 0x41ed,
+ 0x7b90, 0x1c84,
+ 0x7b91, 0x41ef,
+ 0x7b94, 0x0474,
+ 0x7b95, 0x0813,
+ 0x7b96, 0x41f2,
+ 0x7b97, 0x0dd8,
+ 0x7b98, 0x41f3,
+ 0x7b9c, 0x1c8d,
+ 0x7b9d, 0x1c89,
+ 0x7b9e, 0x41f7,
+ 0x7ba1, 0x0735,
+ 0x7ba2, 0x1c8e,
+ 0x7ba3, 0x41fa,
+ 0x7ba6, 0x1c85,
+ 0x7ba8, 0x1c8a,
+ 0x7ba9, 0x0a88,
+ 0x7baa, 0x1c8c,
+ 0x7bab, 0x1c8f,
+ 0x7bac, 0x1c88,
+ 0x7bad, 0x0870,
+ 0x7bae, 0x41fd,
+ 0x7bb1, 0x0f51,
+ 0x7bb2, 0x4200,
+ 0x7bb4, 0x1c90,
+ 0x7bb5, 0x4202,
+ 0x7bb8, 0x1c87,
+ 0x7bb9, 0x4205,
+ 0x7bc0, 0x1fb3,
+ 0x7bc1, 0x1c92,
+ 0x7bc2, 0x420c,
+ 0x7bc4, 0x1eef,
+ 0x7bc5, 0x420e,
+ 0x7bc6, 0x120a,
+ 0x7bc7, 0x0bc9,
+ 0x7bc8, 0x420f,
+ 0x7bc9, 0x22a4,
+ 0x7bca, 0x4210,
+ 0x7bcb, 0x25e8,
+ 0x7bcc, 0x1c93,
+ 0x7bcd, 0x4211,
+ 0x7bd1, 0x1c91,
+ 0x7bd2, 0x4215,
+ 0x7bd3, 0x0a4f,
+ 0x7bd4, 0x4216,
+ 0x7bd9, 0x06d8,
+ 0x7bda, 0x1c95,
+ 0x7bdb, 0x421b,
+ 0x7bdd, 0x1c94,
+ 0x7bde, 0x421d,
+ 0x7be1, 0x055e,
+ 0x7be2, 0x4220,
+ 0x7be4, 0x25e3,
+ 0x7be5, 0x1c96,
+ 0x7be7, 0x4222,
+ 0x7be9, 0x2111,
+ 0x7bea, 0x1c98,
+ 0x7beb, 0x4224,
+ 0x7bee, 0x09a5,
+ 0x7bef, 0x4227,
+ 0x7bf1, 0x09d4,
+ 0x7bf2, 0x4229,
+ 0x7bf3, 0x25e6,
+ 0x7bf4, 0x422a,
+ 0x7bf7, 0x0bb2,
+ 0x7bf8, 0x422d,
+ 0x7bfc, 0x1c9b,
+ 0x7bfd, 0x4231,
+ 0x7bfe, 0x1c9a,
+ 0x7bff, 0x4232,
+ 0x7c00, 0x25e7,
+ 0x7c01, 0x4233,
+ 0x7c07, 0x055b,
+ 0x7c08, 0x4239,
+ 0x7c0b, 0x1c9e,
+ 0x7c0c, 0x1c99,
+ 0x7c0d, 0x2041,
+ 0x7c0e, 0x423c,
+ 0x7c0f, 0x1c9c,
+ 0x7c10, 0x423d,
+ 0x7c16, 0x1c9d,
+ 0x7c17, 0x4243,
+ 0x7c1e, 0x25ea,
+ 0x7c1f, 0x1c9f,
+ 0x7c20, 0x424a,
+ 0x7c21, 0x1f8f,
+ 0x7c22, 0x424b,
+ 0x7c23, 0x25ec,
+ 0x7c24, 0x424c,
+ 0x7c26, 0x1ca1,
+ 0x7c27, 0x07de,
+ 0x7c28, 0x424e,
+ 0x7c2a, 0x1ca0,
+ 0x7c2b, 0x25eb,
+ 0x7c2c, 0x4250,
+ 0x7c38, 0x1ca2,
+ 0x7c39, 0x425c,
+ 0x7c3d, 0x20d0,
+ 0x7c3e, 0x201d,
+ 0x7c3f, 0x0485,
+ 0x7c40, 0x1ca4,
+ 0x7c41, 0x1ca3,
+ 0x7c42, 0x4260,
+ 0x7c43, 0x1ff7,
+ 0x7c44, 0x4261,
+ 0x7c4c, 0x1e8d,
+ 0x7c4d, 0x0821,
+ 0x7c4e, 0x4269,
+ 0x7c5c, 0x25e9,
+ 0x7c5d, 0x4277,
+ 0x7c5f, 0x25ee,
+ 0x7c60, 0x203a,
+ 0x7c61, 0x4279,
+ 0x7c64, 0x2693,
+ 0x7c65, 0x427c,
+ 0x7c69, 0x25e5,
+ 0x7c6a, 0x25ed,
+ 0x7c6b, 0x4280,
+ 0x7c6c, 0x2009,
+ 0x7c6d, 0x4281,
+ 0x7c6e, 0x2065,
+ 0x7c6f, 0x4282,
+ 0x7c72, 0x26a3,
+ 0x7c73, 0x0adc,
+ 0x7c74, 0x12f5,
+ 0x7c75, 0x4285,
+ 0x7c7b, 0x09cb,
+ 0x7c7c, 0x1cca,
+ 0x7c7d, 0x122e,
+ 0x7c7e, 0x428b,
+ 0x7c89, 0x0678,
+ 0x7c8a, 0x4296,
+ 0x7c91, 0x1ccc,
+ 0x7c92, 0x09ec,
+ 0x7c93, 0x429d,
+ 0x7c95, 0x0be8,
+ 0x7c96, 0x429f,
+ 0x7c97, 0x0559,
+ 0x7c98, 0x1154,
+ 0x7c99, 0x42a0,
+ 0x7c9c, 0x1cce,
+ 0x7c9d, 0x1ccd,
+ 0x7c9e, 0x1ccf,
+ 0x7c9f, 0x0dcf,
+ 0x7ca0, 0x42a3,
+ 0x7ca2, 0x1cd0,
+ 0x7ca3, 0x42a5,
+ 0x7ca4, 0x1104,
+ 0x7ca5, 0x11df,
+ 0x7ca6, 0x42a6,
+ 0x7caa, 0x067d,
+ 0x7cab, 0x42aa,
+ 0x7cae, 0x0a01,
+ 0x7caf, 0x42ad,
+ 0x7cb1, 0x0a04,
+ 0x7cb2, 0x1cd1,
+ 0x7cb3, 0x08db,
+ 0x7cb4, 0x42af,
+ 0x7cb9, 0x0565,
+ 0x7cba, 0x42b4,
+ 0x7cbc, 0x1cd2,
+ 0x7cbe, 0x08da,
+ 0x7cbf, 0x42b6,
+ 0x7cc1, 0x1cd4,
+ 0x7cc2, 0x42b8,
+ 0x7cc5, 0x1cd9,
+ 0x7cc6, 0x42bb,
+ 0x7cc7, 0x1cd5,
+ 0x7cc8, 0x1cd8,
+ 0x7cc9, 0x42bc,
+ 0x7cca, 0x07b4,
+ 0x7ccb, 0x42bd,
+ 0x7ccc, 0x1cd6,
+ 0x7cce, 0x42be,
+ 0x7cd5, 0x06dd,
+ 0x7cd6, 0x0e1a,
+ 0x7cd7, 0x1cda,
+ 0x7cd8, 0x42c5,
+ 0x7cd9, 0x04a1,
+ 0x7cda, 0x42c6,
+ 0x7cdc, 0x0ad8,
+ 0x7cdd, 0x25f5,
+ 0x7cde, 0x1efc,
+ 0x7cdf, 0x1126,
+ 0x7ce0, 0x0944,
+ 0x7ce1, 0x42c8,
+ 0x7ce7, 0x2024,
+ 0x7ce8, 0x1cdb,
+ 0x7ce9, 0x42ce,
+ 0x7cef, 0x0b75,
+ 0x7cf0, 0x269b,
+ 0x7cf1, 0x42d4,
+ 0x7cf2, 0x25f3,
+ 0x7cf3, 0x42d5,
+ 0x7cf4, 0x22d9,
+ 0x7cf5, 0x42d6,
+ 0x7cf6, 0x25f4,
+ 0x7cf7, 0x42d7,
+ 0x7cf8, 0x1ce7,
+ 0x7cf9, 0x241b,
+ 0x7cfa, 0x42d8,
+ 0x7cfb, 0x0f22,
+ 0x7cfc, 0x42d9,
+ 0x7cfe, 0x1fc8,
+ 0x7cff, 0x42db,
+ 0x7d00, 0x1f7b,
+ 0x7d01, 0x42dc,
+ 0x7d02, 0x241d,
+ 0x7d03, 0x42dd,
+ 0x7d04, 0x224c,
+ 0x7d05, 0x1f48,
+ 0x7d06, 0x241c,
+ 0x7d07, 0x241e,
+ 0x7d09, 0x20ff,
+ 0x7d0a, 0x0ed8,
+ 0x7d0b, 0x219a,
+ 0x7d0c, 0x42de,
+ 0x7d0d, 0x2091,
+ 0x7d0e, 0x42df,
+ 0x7d10, 0x20a7,
+ 0x7d11, 0x42e1,
+ 0x7d13, 0x2423,
+ 0x7d14, 0x1e9b,
+ 0x7d15, 0x2422,
+ 0x7d16, 0x42e3,
+ 0x7d17, 0x2110,
+ 0x7d18, 0x42e4,
+ 0x7d19, 0x228d,
+ 0x7d1a, 0x1f71,
+ 0x7d1b, 0x1ef8,
+ 0x7d1c, 0x2421,
+ 0x7d1d, 0x42e5,
+ 0x7d20, 0x0dcd,
+ 0x7d21, 0x1ef3,
+ 0x7d22, 0x0dec,
+ 0x7d23, 0x42e8,
+ 0x7d27, 0x08c5,
+ 0x7d28, 0x42ec,
+ 0x7d2b, 0x122c,
+ 0x7d2c, 0x42ef,
+ 0x7d2f, 0x09c6,
+ 0x7d30, 0x21b1,
+ 0x7d31, 0x2426,
+ 0x7d32, 0x2425,
+ 0x7d33, 0x2120,
+ 0x7d34, 0x42f2,
+ 0x7d39, 0x211a,
+ 0x7d3a, 0x2424,
+ 0x7d3b, 0x42f7,
+ 0x7d3c, 0x2428,
+ 0x7d3d, 0x42f8,
+ 0x7d3f, 0x242a,
+ 0x7d40, 0x2429,
+ 0x7d41, 0x42fa,
+ 0x7d42, 0x2294,
+ 0x7d43, 0x42fb,
+ 0x7d44, 0x22be,
+ 0x7d45, 0x42fc,
+ 0x7d46, 0x1e31,
+ 0x7d47, 0x42fd,
+ 0x7d4e, 0x242c,
+ 0x7d4f, 0x4304,
+ 0x7d50, 0x1fb5,
+ 0x7d51, 0x4305,
+ 0x7d5d, 0x242b,
+ 0x7d5e, 0x1faf,
+ 0x7d5f, 0x4311,
+ 0x7d61, 0x2068,
+ 0x7d62, 0x21e4,
+ 0x7d63, 0x4313,
+ 0x7d66, 0x1f21,
+ 0x7d67, 0x4316,
+ 0x7d68, 0x2101,
+ 0x7d69, 0x4317,
+ 0x7d6e, 0x0fc0,
+ 0x7d6f, 0x431c,
+ 0x7d71, 0x217c,
+ 0x7d72, 0x214a,
+ 0x7d73, 0x242d,
+ 0x7d74, 0x431e,
+ 0x7d76, 0x1fd4,
+ 0x7d77, 0x1ce8,
+ 0x7d78, 0x4320,
+ 0x7d79, 0x1fd1,
+ 0x7d7a, 0x4321,
+ 0x7d81, 0x1e33,
+ 0x7d82, 0x4328,
+ 0x7d83, 0x242f,
+ 0x7d84, 0x4329,
+ 0x7d86, 0x242e,
+ 0x7d87, 0x432b,
+ 0x7d88, 0x2430,
+ 0x7d89, 0x21db,
+ 0x7d8a, 0x432c,
+ 0x7d8f, 0x2158,
+ 0x7d90, 0x4331,
+ 0x7d93, 0x1fc2,
+ 0x7d94, 0x4334,
+ 0x7d9c, 0x22b9,
+ 0x7d9d, 0x433c,
+ 0x7d9e, 0x2436,
+ 0x7d9f, 0x433d,
+ 0x7da2, 0x1e8e,
+ 0x7da3, 0x2439,
+ 0x7da4, 0x4340,
+ 0x7da6, 0x1ce9,
+ 0x7da7, 0x4342,
+ 0x7dab, 0x21c5,
+ 0x7dac, 0x2437,
+ 0x7dad, 0x2192,
+ 0x7dae, 0x1cea,
+ 0x7daf, 0x4346,
+ 0x7db0, 0x243a,
+ 0x7db1, 0x1f19,
+ 0x7db2, 0x218c,
+ 0x7db3, 0x1e40,
+ 0x7db4, 0x22b3,
+ 0x7db5, 0x4347,
+ 0x7db8, 0x205f,
+ 0x7db9, 0x2438,
+ 0x7dba, 0x2432,
+ 0x7dbb, 0x2274,
+ 0x7dbc, 0x434a,
+ 0x7dbd, 0x1e9c,
+ 0x7dbe, 0x2431,
+ 0x7dbf, 0x2085,
+ 0x7dc0, 0x434b,
+ 0x7dc4, 0x2435,
+ 0x7dc5, 0x434f,
+ 0x7dc7, 0x243b,
+ 0x7dc8, 0x4351,
+ 0x7dca, 0x1fb7,
+ 0x7dcb, 0x2433,
+ 0x7dcc, 0x4353,
+ 0x7dd1, 0x2054,
+ 0x7dd2, 0x21de,
+ 0x7dd3, 0x4358,
+ 0x7dd4, 0x2434,
+ 0x7dd5, 0x4359,
+ 0x7dd7, 0x243d,
+ 0x7dd8, 0x1f89,
+ 0x7dd9, 0x243c,
+ 0x7dda, 0x435b,
+ 0x7ddd, 0x1f6e,
+ 0x7dde, 0x1ed8,
+ 0x7ddf, 0x435e,
+ 0x7de0, 0x1ebf,
+ 0x7de1, 0x2445,
+ 0x7de2, 0x435f,
+ 0x7de3, 0x2249,
+ 0x7de4, 0x4360,
+ 0x7de6, 0x2441,
+ 0x7de7, 0x4362,
+ 0x7de8, 0x1e47,
+ 0x7de9, 0x1f56,
+ 0x7dea, 0x4363,
+ 0x7dec, 0x2086,
+ 0x7ded, 0x4365,
+ 0x7def, 0x2196,
+ 0x7df0, 0x4367,
+ 0x7df1, 0x2443,
+ 0x7df2, 0x243f,
+ 0x7df3, 0x4368,
+ 0x7df4, 0x2023,
+ 0x7df5, 0x4369,
+ 0x7df6, 0x2442,
+ 0x7df7, 0x436a,
+ 0x7df9, 0x243e,
+ 0x7dfa, 0x436c,
+ 0x7dfb, 0x26a6,
+ 0x7dfc, 0x436d,
+ 0x7e00, 0x4371,
+ 0x7e08, 0x234e,
+ 0x7e09, 0x2446,
+ 0x7e0a, 0x244b,
+ 0x7e0b, 0x2444,
+ 0x7e0c, 0x4379,
+ 0x7e10, 0x2427,
+ 0x7e11, 0x244c,
+ 0x7e12, 0x437d,
+ 0x7e1b, 0x1f0f,
+ 0x7e1c, 0x4386,
+ 0x7e1d, 0x2447,
+ 0x7e1e, 0x2449,
+ 0x7e1f, 0x2448,
+ 0x7e20, 0x4387,
+ 0x7e23, 0x21c2,
+ 0x7e24, 0x438a,
+ 0x7e27, 0x216e,
+ 0x7e28, 0x438d,
+ 0x7e2b, 0x1f03,
+ 0x7e2c, 0x4390,
+ 0x7e2d, 0x244a,
+ 0x7e2e, 0x215c,
+ 0x7e2f, 0x4391,
+ 0x7e31, 0x22bb,
+ 0x7e32, 0x2450,
+ 0x7e33, 0x4393,
+ 0x7e34, 0x2694,
+ 0x7e35, 0x244f,
+ 0x7e36, 0x25f6,
+ 0x7e37, 0x2051,
+ 0x7e38, 0x4394,
+ 0x7e39, 0x244e,
+ 0x7e3a, 0x4395,
+ 0x7e3b, 0x1dfb,
+ 0x7e3c, 0x4396,
+ 0x7e3d, 0x22ba,
+ 0x7e3e, 0x1f6d,
+ 0x7e3f, 0x4397,
+ 0x7e41, 0x064e,
+ 0x7e42, 0x4399,
+ 0x7e45, 0x2452,
+ 0x7e46, 0x2451,
+ 0x7e47, 0x1ceb,
+ 0x7e48, 0x439c,
+ 0x7e52, 0x2455,
+ 0x7e53, 0x43a6,
+ 0x7e54, 0x2289,
+ 0x7e55, 0x2116,
+ 0x7e56, 0x43a7,
+ 0x7e5a, 0x2454,
+ 0x7e5b, 0x43ab,
+ 0x7e5e, 0x20fb,
+ 0x7e5f, 0x43ae,
+ 0x7e62, 0x2440,
+ 0x7e63, 0x43b1,
+ 0x7e69, 0x2126,
+ 0x7e6a, 0x1f61,
+ 0x7e6b, 0x269d,
+ 0x7e6c, 0x43b7,
+ 0x7e6d, 0x1f8a,
+ 0x7e6e, 0x2456,
+ 0x7e6f, 0x2459,
+ 0x7e70, 0x2458,
+ 0x7e71, 0x43b8,
+ 0x7e73, 0x1fae,
+ 0x7e74, 0x43ba,
+ 0x7e79, 0x221a,
+ 0x7e7a, 0x43bf,
+ 0x7e7c, 0x1f7a,
+ 0x7e7d, 0x244d,
+ 0x7e7e, 0x2457,
+ 0x7e7f, 0x43c1,
+ 0x7e82, 0x1248,
+ 0x7e83, 0x43c4,
+ 0x7e88, 0x2453,
+ 0x7e89, 0x43c9,
+ 0x7e8a, 0x2420,
+ 0x7e8b, 0x43ca,
+ 0x7e8c, 0x21df,
+ 0x7e8d, 0x2685,
+ 0x7e8e, 0x43cb,
+ 0x7e8f, 0x1e6e,
+ 0x7e90, 0x43cc,
+ 0x7e93, 0x2224,
+ 0x7e94, 0x2670,
+ 0x7e95, 0x43cf,
+ 0x7e96, 0x21ba,
+ 0x7e97, 0x43d0,
+ 0x7e98, 0x245a,
+ 0x7e99, 0x43d1,
+ 0x7e9b, 0x1cec,
+ 0x7e9c, 0x1fff,
+ 0x7e9d, 0x43d3,
+ 0x7e9f, 0x17d3,
+ 0x7ea0, 0x08ef,
+ 0x7ea1, 0x17d4,
+ 0x7ea2, 0x07a3,
+ 0x7ea3, 0x17d5,
+ 0x7ea4, 0x0f38,
+ 0x7ea5, 0x17d6,
+ 0x7ea6, 0x10ff,
+ 0x7ea7, 0x0829,
+ 0x7ea8, 0x17d7,
+ 0x7eaa, 0x0840,
+ 0x7eab, 0x0cad,
+ 0x7eac, 0x0ec2,
+ 0x7ead, 0x17d9,
+ 0x7eae, 0x43d5,
+ 0x7eaf, 0x0542,
+ 0x7eb0, 0x17da,
+ 0x7eb1, 0x0ced,
+ 0x7eb2, 0x06d4,
+ 0x7eb3, 0x0b2c,
+ 0x7eb4, 0x43d6,
+ 0x7eb5, 0x123a,
+ 0x7eb6, 0x0a81,
+ 0x7eb7, 0x0674,
+ 0x7eb8, 0x11bc,
+ 0x7eb9, 0x0ed5,
+ 0x7eba, 0x0661,
+ 0x7ebb, 0x43d7,
+ 0x7ebd, 0x0b67,
+ 0x7ebe, 0x17db,
+ 0x7ebf, 0x0f4c,
+ 0x7ec0, 0x17dc,
+ 0x7ec3, 0x0a00,
+ 0x7ec4, 0x1246,
+ 0x7ec5, 0x0d29,
+ 0x7ec6, 0x0f25,
+ 0x7ec7, 0x11ae,
+ 0x7ec8, 0x11d4,
+ 0x7ec9, 0x17df,
+ 0x7eca, 0x03f8,
+ 0x7ecb, 0x17e0,
+ 0x7ecd, 0x0d15,
+ 0x7ece, 0x1076,
+ 0x7ecf, 0x08dc,
+ 0x7ed0, 0x17e2,
+ 0x7ed1, 0x03fe,
+ 0x7ed2, 0x0cb9,
+ 0x7ed3, 0x08b2,
+ 0x7ed4, 0x17e3,
+ 0x7ed5, 0x0ca1,
+ 0x7ed6, 0x43d9,
+ 0x7ed7, 0x17e4,
+ 0x7ed8, 0x07fb,
+ 0x7ed9, 0x06f3,
+ 0x7eda, 0x0fcd,
+ 0x7edb, 0x17e5,
+ 0x7edc, 0x0a8e,
+ 0x7edd, 0x0927,
+ 0x7ede, 0x089b,
+ 0x7edf, 0x0e64,
+ 0x7ee0, 0x17e6,
+ 0x7ee2, 0x091d,
+ 0x7ee3, 0x0fb0,
+ 0x7ee4, 0x43da,
+ 0x7ee5, 0x0ddc,
+ 0x7ee6, 0x0e23,
+ 0x7ee7, 0x083f,
+ 0x7ee8, 0x17e8,
+ 0x7ee9, 0x081b,
+ 0x7eea, 0x0fc2,
+ 0x7eeb, 0x17e9,
+ 0x7eec, 0x43db,
+ 0x7eed, 0x0fc3,
+ 0x7eee, 0x17ea,
+ 0x7ef0, 0x0545,
+ 0x7ef1, 0x17ec,
+ 0x7ef3, 0x0d37,
+ 0x7ef4, 0x0ebb,
+ 0x7ef5, 0x0ae5,
+ 0x7ef6, 0x17ef,
+ 0x7ef7, 0x042a,
+ 0x7ef8, 0x0516,
+ 0x7ef9, 0x43dc,
+ 0x7efa, 0x17f0,
+ 0x7efc, 0x1238,
+ 0x7efd, 0x1161,
+ 0x7efe, 0x17f2,
+ 0x7eff, 0x0a73,
+ 0x7f00, 0x1217,
+ 0x7f01, 0x17f3,
+ 0x7f04, 0x085d,
+ 0x7f05, 0x0aea,
+ 0x7f06, 0x09ad,
+ 0x7f07, 0x17f6,
+ 0x7f09, 0x081c,
+ 0x7f0a, 0x43dd,
+ 0x7f0b, 0x17f8,
+ 0x7f0d, 0x17ee,
+ 0x7f0e, 0x060f,
+ 0x7f0f, 0x17fa,
+ 0x7f10, 0x43de,
+ 0x7f11, 0x17fb,
+ 0x7f13, 0x07cf,
+ 0x7f14, 0x05bf,
+ 0x7f15, 0x0a6d,
+ 0x7f16, 0x0449,
+ 0x7f17, 0x17fd,
+ 0x7f18, 0x10f8,
+ 0x7f19, 0x17fe,
+ 0x7f1a, 0x06ba,
+ 0x7f1b, 0x1800,
+ 0x7f1c, 0x17ff,
+ 0x7f1d, 0x0689,
+ 0x7f1e, 0x43df,
+ 0x7f1f, 0x1801,
+ 0x7f20, 0x04bf,
+ 0x7f21, 0x1802,
+ 0x7f28, 0x108c,
+ 0x7f29, 0x0dea,
+ 0x7f2a, 0x1809,
+ 0x7f2e, 0x0d02,
+ 0x7f2f, 0x180d,
+ 0x7f34, 0x089a,
+ 0x7f35, 0x1812,
+ 0x7f36, 0x1c5e,
+ 0x7f37, 0x43e0,
+ 0x7f38, 0x06d2,
+ 0x7f39, 0x43e1,
+ 0x7f3a, 0x0c8c,
+ 0x7f3b, 0x43e2,
+ 0x7f42, 0x1c5f,
+ 0x7f43, 0x43e9,
+ 0x7f44, 0x1c60,
+ 0x7f46, 0x43ea,
+ 0x7f4c, 0x25e2,
+ 0x7f4d, 0x43f0,
+ 0x7f4e, 0x269a,
+ 0x7f4f, 0x43f1,
+ 0x7f50, 0x0737,
+ 0x7f51, 0x0ea9,
+ 0x7f52, 0x43f2,
+ 0x7f54, 0x129e,
+ 0x7f55, 0x0768,
+ 0x7f56, 0x43f4,
+ 0x7f57, 0x0a85,
+ 0x7f58, 0x1a81,
+ 0x7f59, 0x43f5,
+ 0x7f5a, 0x0640,
+ 0x7f5b, 0x43f6,
+ 0x7f5f, 0x1a83,
+ 0x7f60, 0x43fa,
+ 0x7f61, 0x1a82,
+ 0x7f62, 0x03e0,
+ 0x7f63, 0x43fb,
+ 0x7f68, 0x1a85,
+ 0x7f69, 0x1177,
+ 0x7f6a, 0x124c,
+ 0x7f6b, 0x4400,
+ 0x7f6e, 0x11c2,
+ 0x7f6f, 0x4403,
+ 0x7f70, 0x1eea,
+ 0x7f71, 0x1a87,
+ 0x7f72, 0x0d87,
+ 0x7f73, 0x4404,
+ 0x7f74, 0x1a86,
+ 0x7f75, 0x4405,
+ 0x7f77, 0x1e2c,
+ 0x7f78, 0x4407,
+ 0x7f79, 0x1a88,
+ 0x7f7a, 0x4408,
+ 0x7f7e, 0x1a8a,
+ 0x7f7f, 0x440c,
+ 0x7f81, 0x1a89,
+ 0x7f82, 0x440e,
+ 0x7f85, 0x2062,
+ 0x7f86, 0x24f1,
+ 0x7f87, 0x4411,
+ 0x7f88, 0x24f2,
+ 0x7f89, 0x4412,
+ 0x7f8a, 0x101b,
+ 0x7f8b, 0x4413,
+ 0x7f8c, 0x0c39,
+ 0x7f8d, 0x4414,
+ 0x7f8e, 0x0ac5,
+ 0x7f8f, 0x4415,
+ 0x7f94, 0x06dc,
+ 0x7f95, 0x441a,
+ 0x7f9a, 0x0a30,
+ 0x7f9b, 0x441f,
+ 0x7f9d, 0x1cc4,
+ 0x7f9e, 0x0faa,
+ 0x7f9f, 0x1cc5,
+ 0x7fa0, 0x4421,
+ 0x7fa1, 0x0f48,
+ 0x7fa2, 0x4422,
+ 0x7fa4, 0x0c95,
+ 0x7fa5, 0x25f2,
+ 0x7fa6, 0x4424,
+ 0x7fa7, 0x1cc6,
+ 0x7fa8, 0x4425,
+ 0x7fa9, 0x2215,
+ 0x7faa, 0x4426,
+ 0x7faf, 0x1cc7,
+ 0x7fb1, 0x442b,
+ 0x7fb2, 0x1cc9,
+ 0x7fb3, 0x442c,
+ 0x7fb8, 0x130e,
+ 0x7fb9, 0x06f9,
+ 0x7fba, 0x4431,
+ 0x7fbc, 0x176d,
+ 0x7fbd, 0x10d5,
+ 0x7fbe, 0x4433,
+ 0x7fbf, 0x1cde,
+ 0x7fc0, 0x4434,
+ 0x7fc1, 0x0edb,
+ 0x7fc2, 0x4435,
+ 0x7fc5, 0x0506,
+ 0x7fc6, 0x4438,
+ 0x7fca, 0x1b98,
+ 0x7fcb, 0x443c,
+ 0x7fcc, 0x1075,
+ 0x7fcd, 0x443d,
+ 0x7fce, 0x1cdf,
+ 0x7fcf, 0x443e,
+ 0x7fd2, 0x21ae,
+ 0x7fd3, 0x4441,
+ 0x7fd4, 0x0f55,
+ 0x7fd5, 0x1ce0,
+ 0x7fd6, 0x4442,
+ 0x7fd8, 0x0c49,
+ 0x7fd9, 0x4444,
+ 0x7fdf, 0x05b5,
+ 0x7fe0, 0x0567,
+ 0x7fe1, 0x1ce2,
+ 0x7fe2, 0x444a,
+ 0x7fe5, 0x1ce1,
+ 0x7fe6, 0x1ce3,
+ 0x7fe7, 0x444d,
+ 0x7fe9, 0x1ce4,
+ 0x7fea, 0x444f,
+ 0x7fee, 0x1ce5,
+ 0x7fef, 0x4453,
+ 0x7ff0, 0x0769,
+ 0x7ff1, 0x03ca,
+ 0x7ff2, 0x4454,
+ 0x7ff3, 0x1ce6,
+ 0x7ff4, 0x4455,
+ 0x7ff9, 0x20e0,
+ 0x7ffa, 0x445a,
+ 0x7ffb, 0x064a,
+ 0x7ffc, 0x1074,
+ 0x7ffd, 0x445b,
+ 0x8000, 0x1032,
+ 0x8001, 0x09ba,
+ 0x8002, 0x445e,
+ 0x8003, 0x0949,
+ 0x8004, 0x1953,
+ 0x8005, 0x1180,
+ 0x8006, 0x191a,
+ 0x8007, 0x445f,
+ 0x800b, 0x1bd7,
+ 0x800c, 0x0637,
+ 0x800d, 0x0d98,
+ 0x800e, 0x4463,
+ 0x8010, 0x0b30,
+ 0x8011, 0x4465,
+ 0x8012, 0x1bcb,
+ 0x8013, 0x4466,
+ 0x8014, 0x1bcc,
+ 0x8015, 0x06f6,
+ 0x8016, 0x1bcd,
+ 0x8017, 0x077b,
+ 0x8018, 0x1108,
+ 0x8019, 0x03dd,
+ 0x801a, 0x4467,
+ 0x801c, 0x1bce,
+ 0x801d, 0x4469,
+ 0x8020, 0x1bcf,
+ 0x8021, 0x446c,
+ 0x8022, 0x1bd0,
+ 0x8023, 0x446d,
+ 0x8025, 0x1bd1,
+ 0x8028, 0x1bd5,
+ 0x8029, 0x1bd4,
+ 0x802a, 0x0b96,
+ 0x802b, 0x446f,
+ 0x802c, 0x25c2,
+ 0x802d, 0x4470,
+ 0x802e, 0x25c1,
+ 0x802f, 0x4471,
+ 0x8031, 0x1bd6,
+ 0x8032, 0x4473,
+ 0x8033, 0x0639,
+ 0x8034, 0x4474,
+ 0x8035, 0x1bd8,
+ 0x8036, 0x1035,
+ 0x8037, 0x14b1,
+ 0x8038, 0x0dbf,
+ 0x8039, 0x4475,
+ 0x803b, 0x0501,
+ 0x803c, 0x4477,
+ 0x803d, 0x0583,
+ 0x803e, 0x4478,
+ 0x803f, 0x06fb,
+ 0x8040, 0x4479,
+ 0x8042, 0x0b57,
+ 0x8043, 0x1bd9,
+ 0x8044, 0x447b,
+ 0x8046, 0x1bda,
+ 0x8047, 0x447d,
+ 0x804a, 0x0a0d,
+ 0x804b, 0x0a44,
+ 0x804c, 0x11af,
+ 0x804d, 0x1bdb,
+ 0x804e, 0x4480,
+ 0x8052, 0x1bdc,
+ 0x8053, 0x4484,
+ 0x8054, 0x09f3,
+ 0x8055, 0x4485,
+ 0x8056, 0x2128,
+ 0x8057, 0x4486,
+ 0x8058, 0x0bd7,
+ 0x8059, 0x4487,
+ 0x805a, 0x090a,
+ 0x805b, 0x4488,
+ 0x805e, 0x2199,
+ 0x805f, 0x448b,
+ 0x8069, 0x1bdd,
+ 0x806a, 0x0552,
+ 0x806b, 0x4495,
+ 0x806f, 0x2017,
+ 0x8070, 0x1ea0,
+ 0x8071, 0x1bde,
+ 0x8072, 0x2125,
+ 0x8073, 0x214d,
+ 0x8074, 0x4499,
+ 0x8075, 0x25c4,
+ 0x8076, 0x209d,
+ 0x8077, 0x228a,
+ 0x8078, 0x449a,
+ 0x8079, 0x25c3,
+ 0x807a, 0x449b,
+ 0x807d, 0x2179,
+ 0x807e, 0x2038,
+ 0x807f, 0x1a1e,
+ 0x8080, 0x1a1d,
+ 0x8081, 0x449e,
+ 0x8083, 0x0dd5,
+ 0x8084, 0x1065,
+ 0x8085, 0x2155,
+ 0x8086, 0x0db6,
+ 0x8087, 0x1179,
+ 0x8088, 0x44a0,
+ 0x8089, 0x0cbd,
+ 0x808a, 0x44a1,
+ 0x808b, 0x09ca,
+ 0x808c, 0x0814,
+ 0x808d, 0x44a2,
+ 0x8093, 0x1971,
+ 0x8094, 0x44a8,
+ 0x8096, 0x0f6f,
+ 0x8097, 0x44aa,
+ 0x8098, 0x11e1,
+ 0x8099, 0x44ab,
+ 0x809a, 0x0606,
+ 0x809b, 0x06d3,
+ 0x809c, 0x1970,
+ 0x809d, 0x06c9,
+ 0x809e, 0x44ac,
+ 0x809f, 0x196f,
+ 0x80a0, 0x04cb,
+ 0x80a1, 0x0722,
+ 0x80a2, 0x11aa,
+ 0x80a3, 0x44ad,
+ 0x80a4, 0x0691,
+ 0x80a5, 0x0667,
+ 0x80a6, 0x44ae,
+ 0x80a9, 0x085a,
+ 0x80aa, 0x065b,
+ 0x80ab, 0x1976,
+ 0x80ac, 0x44b1,
+ 0x80ad, 0x1977,
+ 0x80ae, 0x03c4,
+ 0x80af, 0x095c,
+ 0x80b0, 0x44b2,
+ 0x80b1, 0x1975,
+ 0x80b2, 0x10e2,
+ 0x80b3, 0x44b3,
+ 0x80b4, 0x1978,
+ 0x80b5, 0x44b4,
+ 0x80b7, 0x1979,
+ 0x80b8, 0x44b6,
+ 0x80ba, 0x066b,
+ 0x80bb, 0x44b8,
+ 0x80bc, 0x1972,
+ 0x80bd, 0x1974,
+ 0x80be, 0x0d2f,
+ 0x80bf, 0x11d6,
+ 0x80c0, 0x116e,
+ 0x80c1, 0x0f7d,
+ 0x80c2, 0x197f,
+ 0x80c3, 0x0ec7,
+ 0x80c4, 0x1980,
+ 0x80c5, 0x44b9,
+ 0x80c6, 0x0589,
+ 0x80c7, 0x44ba,
+ 0x80cc, 0x041c,
+ 0x80cd, 0x1982,
+ 0x80ce, 0x0df8,
+ 0x80cf, 0x44bf,
+ 0x80d6, 0x0b97,
+ 0x80d7, 0x1983,
+ 0x80d8, 0x44c6,
+ 0x80d9, 0x1981,
+ 0x80da, 0x0ba0,
+ 0x80db, 0x197e,
+ 0x80dc, 0x0d3b,
+ 0x80dd, 0x1985,
+ 0x80de, 0x0406,
+ 0x80df, 0x44c7,
+ 0x80e1, 0x07b1,
+ 0x80e2, 0x44c9,
+ 0x80e4, 0x126d,
+ 0x80e5, 0x1bc7,
+ 0x80e6, 0x44cb,
+ 0x80e7, 0x197a,
+ 0x80eb, 0x1986,
+ 0x80ec, 0x179a,
+ 0x80ed, 0x1989,
+ 0x80ee, 0x44cc,
+ 0x80ef, 0x0975,
+ 0x80f0, 0x104f,
+ 0x80f1, 0x1987,
+ 0x80f2, 0x198c,
+ 0x80f3, 0x06e7,
+ 0x80f4, 0x1988,
+ 0x80f5, 0x44cd,
+ 0x80f6, 0x088b,
+ 0x80f7, 0x44ce,
+ 0x80f8, 0x0fa3,
+ 0x80f9, 0x44cf,
+ 0x80fa, 0x03c2,
+ 0x80fb, 0x44d0,
+ 0x80fc, 0x198d,
+ 0x80fd, 0x0b3f,
+ 0x80fe, 0x44d1,
+ 0x8100, 0x44d3,
+ 0x8102, 0x11ab,
+ 0x8103, 0x44d5,
+ 0x8105, 0x21d2,
+ 0x8106, 0x0563,
+ 0x8107, 0x44d7,
+ 0x8109, 0x0a9d,
+ 0x810a, 0x082c,
+ 0x810b, 0x44d9,
+ 0x810d, 0x198a,
+ 0x810f, 0x1123,
+ 0x8110, 0x0c09,
+ 0x8111, 0x0b37,
+ 0x8112, 0x198f,
+ 0x8113, 0x0b68,
+ 0x8114, 0x1309,
+ 0x8115, 0x44db,
+ 0x8116, 0x0478,
+ 0x8117, 0x44dc,
+ 0x8118, 0x1994,
+ 0x8119, 0x44dd,
+ 0x811a, 0x0896,
+ 0x811b, 0x24c7,
+ 0x811c, 0x44de,
+ 0x811e, 0x1992,
+ 0x811f, 0x44e0,
+ 0x812c, 0x1993,
+ 0x812d, 0x44ed,
+ 0x812f, 0x06a7,
+ 0x8130, 0x44ef,
+ 0x8131, 0x0e82,
+ 0x8132, 0x1995,
+ 0x8133, 0x44f0,
+ 0x8136, 0x1991,
+ 0x8137, 0x44f3,
+ 0x8138, 0x09fc,
+ 0x8139, 0x2279,
+ 0x813a, 0x44f4,
+ 0x813e, 0x0bc1,
+ 0x813f, 0x44f8,
+ 0x8146, 0x0e46,
+ 0x8147, 0x44ff,
+ 0x8148, 0x1996,
+ 0x8149, 0x4500,
+ 0x814a, 0x099b,
+ 0x814b, 0x103f,
+ 0x814c, 0x1997,
+ 0x814d, 0x4501,
+ 0x814e, 0x2123,
+ 0x814f, 0x4502,
+ 0x8150, 0x06aa,
+ 0x8151, 0x06a8,
+ 0x8152, 0x4503,
+ 0x8153, 0x1998,
+ 0x8154, 0x0c38,
+ 0x8155, 0x0ea4,
+ 0x8156, 0x24c5,
+ 0x8157, 0x4504,
+ 0x8159, 0x199a,
+ 0x815b, 0x4506,
+ 0x8160, 0x199d,
+ 0x8161, 0x24c9,
+ 0x8162, 0x450b,
+ 0x8165, 0x0f93,
+ 0x8166, 0x2094,
+ 0x8167, 0x19a2,
+ 0x8168, 0x450e,
+ 0x8169, 0x199e,
+ 0x816a, 0x450f,
+ 0x816b, 0x2296,
+ 0x816c, 0x4510,
+ 0x816d, 0x19a1,
+ 0x816e, 0x0cd4,
+ 0x816f, 0x4511,
+ 0x8170, 0x1025,
+ 0x8171, 0x199c,
+ 0x8172, 0x4512,
+ 0x8174, 0x1999,
+ 0x8175, 0x4514,
+ 0x8178, 0x1e77,
+ 0x8179, 0x06b4,
+ 0x817a, 0x0f46,
+ 0x817b, 0x0b48,
+ 0x817c, 0x199f,
+ 0x817e, 0x0e2d,
+ 0x817f, 0x0e79,
+ 0x8180, 0x03fd,
+ 0x8181, 0x4517,
+ 0x8182, 0x19a6,
+ 0x8183, 0x4518,
+ 0x8188, 0x19a5,
+ 0x8189, 0x451d,
+ 0x818a, 0x0479,
+ 0x818b, 0x451e,
+ 0x818f, 0x06db,
+ 0x8190, 0x4522,
+ 0x8191, 0x19a7,
+ 0x8192, 0x4523,
+ 0x8198, 0x0455,
+ 0x8199, 0x4529,
+ 0x819a, 0x1f06,
+ 0x819b, 0x0e18,
+ 0x819c, 0x0b07,
+ 0x819d, 0x0f12,
+ 0x819e, 0x452a,
+ 0x81a0, 0x1fa5,
+ 0x81a1, 0x452c,
+ 0x81a3, 0x19a9,
+ 0x81a4, 0x452e,
+ 0x81a6, 0x19b0,
+ 0x81a7, 0x4530,
+ 0x81a8, 0x0bb3,
+ 0x81a9, 0x2099,
+ 0x81aa, 0x19aa,
+ 0x81ab, 0x4531,
+ 0x81b3, 0x0cfe,
+ 0x81b4, 0x4539,
+ 0x81ba, 0x1641,
+ 0x81bb, 0x19ae,
+ 0x81bc, 0x453f,
+ 0x81bd, 0x1ead,
+ 0x81be, 0x24c8,
+ 0x81bf, 0x20a8,
+ 0x81c0, 0x0e7f,
+ 0x81c1, 0x19af,
+ 0x81c2, 0x0444,
+ 0x81c3, 0x109c,
+ 0x81c4, 0x4540,
+ 0x81c6, 0x1063,
+ 0x81c7, 0x4542,
+ 0x81c9, 0x201f,
+ 0x81ca, 0x19ad,
+ 0x81cb, 0x4544,
+ 0x81cc, 0x19ab,
+ 0x81cd, 0x20c5,
+ 0x81ce, 0x4545,
+ 0x81cf, 0x24ca,
+ 0x81d0, 0x4546,
+ 0x81d8, 0x1ff0,
+ 0x81d9, 0x454e,
+ 0x81da, 0x24c6,
+ 0x81db, 0x454f,
+ 0x81df, 0x225d,
+ 0x81e0, 0x22de,
+ 0x81e1, 0x4553,
+ 0x81e3, 0x04e1,
+ 0x81e4, 0x4555,
+ 0x81e7, 0x1902,
+ 0x81e8, 0x202c,
+ 0x81e9, 0x4558,
+ 0x81ea, 0x1231,
+ 0x81eb, 0x4559,
+ 0x81ec, 0x1ca9,
+ 0x81ed, 0x0519,
+ 0x81ee, 0x455a,
+ 0x81f3, 0x11c0,
+ 0x81f5, 0x455f,
+ 0x81fa, 0x2161,
+ 0x81fb, 0x118a,
+ 0x81fc, 0x08f9,
+ 0x81fd, 0x4564,
+ 0x81fe, 0x1ca5,
+ 0x81ff, 0x4565,
+ 0x8200, 0x102f,
+ 0x8201, 0x1ca6,
+ 0x8203, 0x4566,
+ 0x8204, 0x1ca8,
+ 0x8205, 0x08fa,
+ 0x8206, 0x10c4,
+ 0x8207, 0x223b,
+ 0x8208, 0x21d9,
+ 0x8209, 0x1fcb,
+ 0x820a, 0x1fc9,
+ 0x820b, 0x4567,
+ 0x820c, 0x0d19,
+ 0x820e, 0x4568,
+ 0x8210, 0x1c62,
+ 0x8211, 0x456a,
+ 0x8212, 0x0d7d,
+ 0x8213, 0x456b,
+ 0x8214, 0x0e45,
+ 0x8215, 0x456c,
+ 0x821b, 0x1618,
+ 0x821c, 0x0da9,
+ 0x821d, 0x4572,
+ 0x821e, 0x0ef7,
+ 0x821f, 0x11da,
+ 0x8220, 0x4573,
+ 0x8221, 0x1cab,
+ 0x8224, 0x4574,
+ 0x8228, 0x1cb0,
+ 0x8229, 0x4578,
+ 0x822a, 0x0774,
+ 0x822b, 0x1cb1,
+ 0x822c, 0x03ee,
+ 0x822d, 0x1cae,
+ 0x822e, 0x4579,
+ 0x822f, 0x1caf,
+ 0x8230, 0x0873,
+ 0x8231, 0x049c,
+ 0x8232, 0x457a,
+ 0x8233, 0x1cb4,
+ 0x8235, 0x0625,
+ 0x8236, 0x0477,
+ 0x8237, 0x0f3c,
+ 0x8238, 0x1cb2,
+ 0x8239, 0x052f,
+ 0x823a, 0x457b,
+ 0x823b, 0x1cb3,
+ 0x823c, 0x457c,
+ 0x823e, 0x1cb6,
+ 0x823f, 0x457e,
+ 0x8244, 0x1cb7,
+ 0x8245, 0x4583,
+ 0x8247, 0x0e58,
+ 0x8248, 0x4585,
+ 0x8249, 0x1cb8,
+ 0x824a, 0x4586,
+ 0x824b, 0x1cb9,
+ 0x824c, 0x4587,
+ 0x824f, 0x1cba,
+ 0x8250, 0x458a,
+ 0x8258, 0x0dc7,
+ 0x8259, 0x1e61,
+ 0x825a, 0x1cbb,
+ 0x825b, 0x4592,
+ 0x825f, 0x1cbc,
+ 0x8260, 0x4596,
+ 0x8264, 0x25ef,
+ 0x8265, 0x459a,
+ 0x8266, 0x1f98,
+ 0x8267, 0x459b,
+ 0x8268, 0x1cbd,
+ 0x8269, 0x459c,
+ 0x826b, 0x25f0,
+ 0x826c, 0x459e,
+ 0x826e, 0x1cdc,
+ 0x826f, 0x0a05,
+ 0x8270, 0x085b,
+ 0x8271, 0x1f88,
+ 0x8272, 0x0ce4,
+ 0x8273, 0x1007,
+ 0x8274, 0x1771,
+ 0x8275, 0x45a0,
+ 0x8277, 0x21f8,
+ 0x8278, 0x45a2,
+ 0x8279, 0x13e1,
+ 0x827a, 0x105c,
+ 0x827b, 0x45a3,
+ 0x827d, 0x13e2,
+ 0x827e, 0x03b7,
+ 0x827f, 0x13e3,
+ 0x8280, 0x45a5,
+ 0x8282, 0x08ab,
+ 0x8283, 0x45a7,
+ 0x8284, 0x13e7,
+ 0x8285, 0x45a8,
+ 0x8288, 0x1278,
+ 0x8289, 0x45ab,
+ 0x828a, 0x13e5,
+ 0x828b, 0x10d8,
+ 0x828c, 0x45ac,
+ 0x828d, 0x0d0f,
+ 0x828e, 0x13e8,
+ 0x828f, 0x13e4,
+ 0x8290, 0x45ad,
+ 0x8291, 0x13e9,
+ 0x8292, 0x0aa7,
+ 0x8293, 0x45ae,
+ 0x8297, 0x13ea,
+ 0x8298, 0x13f3,
+ 0x8299, 0x13eb,
+ 0x829a, 0x45b2,
+ 0x829c, 0x0eee,
+ 0x829d, 0x11a4,
+ 0x829e, 0x45b4,
+ 0x829f, 0x13fd,
+ 0x82a0, 0x45b5,
+ 0x82a1, 0x13fb,
+ 0x82a2, 0x45b6,
+ 0x82a4, 0x1400,
+ 0x82a5, 0x08b7,
+ 0x82a6, 0x0a52,
+ 0x82a7, 0x45b8,
+ 0x82a8, 0x13e6,
+ 0x82a9, 0x13f9,
+ 0x82aa, 0x13fc,
+ 0x82ab, 0x13ec,
+ 0x82ac, 0x066f,
+ 0x82ad, 0x03d0,
+ 0x82ae, 0x13f5,
+ 0x82af, 0x0f89,
+ 0x82b0, 0x13ef,
+ 0x82b1, 0x07bd,
+ 0x82b2, 0x45b9,
+ 0x82b3, 0x0659,
+ 0x82b4, 0x13fa,
+ 0x82b5, 0x45ba,
+ 0x82b7, 0x13f4,
+ 0x82b8, 0x13ed,
+ 0x82b9, 0x0c58,
+ 0x82ba, 0x45bc,
+ 0x82bb, 0x2322,
+ 0x82bc, 0x45bd,
+ 0x82bd, 0x0fe8,
+ 0x82be, 0x13ee,
+ 0x82bf, 0x45be,
+ 0x82c1, 0x13f8,
+ 0x82c2, 0x45c0,
+ 0x82c4, 0x13fe,
+ 0x82c5, 0x45c2,
+ 0x82c7, 0x0ebc,
+ 0x82c8, 0x13f0,
+ 0x82c9, 0x45c4,
+ 0x82ca, 0x13f1,
+ 0x82cb, 0x13f6,
+ 0x82cd, 0x049b,
+ 0x82ce, 0x13ff,
+ 0x82cf, 0x0dca,
+ 0x82d0, 0x45c5,
+ 0x82d1, 0x10fa,
+ 0x82d2, 0x1409,
+ 0x82d3, 0x140d,
+ 0x82d4, 0x0df9,
+ 0x82d5, 0x1414,
+ 0x82d6, 0x45c6,
+ 0x82d7, 0x0aec,
+ 0x82d8, 0x140a,
+ 0x82d9, 0x45c7,
+ 0x82db, 0x094e,
+ 0x82dc, 0x1407,
+ 0x82dd, 0x45c9,
+ 0x82de, 0x0405,
+ 0x82df, 0x070f,
+ 0x82e0, 0x1413,
+ 0x82e1, 0x1401,
+ 0x82e2, 0x45ca,
+ 0x82e3, 0x13f2,
+ 0x82e4, 0x1404,
+ 0x82e5, 0x0ccf,
+ 0x82e6, 0x096d,
+ 0x82e7, 0x2336,
+ 0x82e8, 0x45cb,
+ 0x82eb, 0x0cf4,
+ 0x82ec, 0x45ce,
+ 0x82ef, 0x0426,
+ 0x82f0, 0x45d1,
+ 0x82f1, 0x1087,
+ 0x82f2, 0x45d2,
+ 0x82f4, 0x1408,
+ 0x82f5, 0x45d4,
+ 0x82f7, 0x1403,
+ 0x82f8, 0x45d6,
+ 0x82f9, 0x0bda,
+ 0x82fa, 0x45d7,
+ 0x82fb, 0x140c,
+ 0x82fc, 0x45d8,
+ 0x8300, 0x45dc,
+ 0x8301, 0x121f,
+ 0x8302, 0x0ab4,
+ 0x8303, 0x0653,
+ 0x8304, 0x0c4e,
+ 0x8305, 0x0aae,
+ 0x8306, 0x1410,
+ 0x8307, 0x1406,
+ 0x8308, 0x1419,
+ 0x8309, 0x1402,
+ 0x830a, 0x45dd,
+ 0x830c, 0x140b,
+ 0x830d, 0x45df,
+ 0x830e, 0x08d4,
+ 0x830f, 0x1405,
+ 0x8310, 0x45e0,
+ 0x8311, 0x140e,
+ 0x8312, 0x45e1,
+ 0x8314, 0x1411,
+ 0x8316, 0x45e3,
+ 0x8317, 0x1426,
+ 0x8318, 0x45e4,
+ 0x831a, 0x140f,
+ 0x831b, 0x142e,
+ 0x831c, 0x1415,
+ 0x831d, 0x45e6,
+ 0x8327, 0x085e,
+ 0x8328, 0x0547,
+ 0x8329, 0x45f0,
+ 0x832b, 0x0aa8,
+ 0x832c, 0x04ae,
+ 0x832d, 0x1428,
+ 0x832e, 0x45f2,
+ 0x832f, 0x1420,
+ 0x8330, 0x45f3,
+ 0x8331, 0x141d,
+ 0x8332, 0x45f4,
+ 0x8333, 0x142a,
+ 0x8334, 0x141c,
+ 0x8335, 0x1077,
+ 0x8336, 0x04af,
+ 0x8337, 0x45f5,
+ 0x8338, 0x0cb2,
+ 0x8339, 0x0cbe,
+ 0x833a, 0x1429,
+ 0x833b, 0x45f6,
+ 0x833c, 0x141b,
+ 0x833d, 0x45f7,
+ 0x8340, 0x1425,
+ 0x8341, 0x45fa,
+ 0x8343, 0x1423,
+ 0x8344, 0x45fc,
+ 0x8346, 0x08d2,
+ 0x8347, 0x1422,
+ 0x8348, 0x45fe,
+ 0x8349, 0x04a4,
+ 0x834a, 0x45ff,
+ 0x834f, 0x1421,
+ 0x8350, 0x0869,
+ 0x8351, 0x1416,
+ 0x8352, 0x07d9,
+ 0x8353, 0x4604,
+ 0x8354, 0x09de,
+ 0x8355, 0x4605,
+ 0x835a, 0x0847,
+ 0x835b, 0x1417,
+ 0x835d, 0x460a,
+ 0x835e, 0x141f,
+ 0x835f, 0x1424,
+ 0x8360, 0x1427,
+ 0x8361, 0x0595,
+ 0x8362, 0x460b,
+ 0x8363, 0x0cb4,
+ 0x8364, 0x07fc,
+ 0x8365, 0x142c,
+ 0x8366, 0x142b,
+ 0x8367, 0x1090,
+ 0x8368, 0x142d,
+ 0x8369, 0x142f,
+ 0x836a, 0x1431,
+ 0x836b, 0x1078,
+ 0x836c, 0x1430,
+ 0x836d, 0x1432,
+ 0x836f, 0x1030,
+ 0x8370, 0x460c,
+ 0x8377, 0x0780,
+ 0x8378, 0x1435,
+ 0x8379, 0x4613,
+ 0x837b, 0x1442,
+ 0x837c, 0x143d,
+ 0x837d, 0x1440,
+ 0x837e, 0x4615,
+ 0x8385, 0x143c,
+ 0x8386, 0x0bed,
+ 0x8387, 0x461c,
+ 0x8389, 0x09dd,
+ 0x838a, 0x22ab,
+ 0x838b, 0x461e,
+ 0x838e, 0x0ce8,
+ 0x838f, 0x4621,
+ 0x8392, 0x141a,
+ 0x8393, 0x143a,
+ 0x8394, 0x4624,
+ 0x8396, 0x1fbf,
+ 0x8397, 0x4626,
+ 0x8398, 0x1443,
+ 0x8399, 0x4627,
+ 0x839b, 0x141e,
+ 0x839c, 0x143b,
+ 0x839d, 0x4629,
+ 0x839e, 0x1444,
+ 0x839f, 0x462a,
+ 0x83a0, 0x1438,
+ 0x83a1, 0x462b,
+ 0x83a2, 0x1f7d,
+ 0x83a3, 0x462c,
+ 0x83a7, 0x2333,
+ 0x83a8, 0x1445,
+ 0x83a9, 0x143f,
+ 0x83aa, 0x1439,
+ 0x83ab, 0x0b0d,
+ 0x83ac, 0x4630,
+ 0x83b0, 0x1434,
+ 0x83b1, 0x099e,
+ 0x83b2, 0x09f4,
+ 0x83b3, 0x1436,
+ 0x83b5, 0x4634,
+ 0x83b6, 0x143e,
+ 0x83b7, 0x0806,
+ 0x83b8, 0x1441,
+ 0x83b9, 0x108d,
+ 0x83ba, 0x1446,
+ 0x83bb, 0x4635,
+ 0x83bc, 0x1447,
+ 0x83bd, 0x0aac,
+ 0x83be, 0x4636,
+ 0x83c0, 0x145e,
+ 0x83c1, 0x1448,
+ 0x83c2, 0x4638,
+ 0x83c5, 0x145d,
+ 0x83c6, 0x463b,
+ 0x83c7, 0x0716,
+ 0x83c8, 0x463c,
+ 0x83ca, 0x0904,
+ 0x83cb, 0x463e,
+ 0x83cc, 0x0929,
+ 0x83cd, 0x463f,
+ 0x83cf, 0x0781,
+ 0x83d0, 0x4641,
+ 0x83d4, 0x1456,
+ 0x83d5, 0x4645,
+ 0x83d6, 0x1451,
+ 0x83d7, 0x4646,
+ 0x83d8, 0x144b,
+ 0x83d9, 0x4647,
+ 0x83dc, 0x0492,
+ 0x83dd, 0x144f,
+ 0x83de, 0x464a,
+ 0x83df, 0x1457,
+ 0x83e0, 0x046b,
+ 0x83e1, 0x1461,
+ 0x83e2, 0x464b,
+ 0x83e5, 0x144a,
+ 0x83e6, 0x464e,
+ 0x83e9, 0x0bef,
+ 0x83ea, 0x145c,
+ 0x83eb, 0x4651,
+ 0x83ef, 0x1f4d,
+ 0x83f0, 0x1460,
+ 0x83f1, 0x0a2b,
+ 0x83f2, 0x0663,
+ 0x83f3, 0x4655,
+ 0x83f8, 0x145a,
+ 0x83fa, 0x465a,
+ 0x83fd, 0x1450,
+ 0x83fe, 0x465d,
+ 0x8400, 0x465f,
+ 0x8401, 0x1449,
+ 0x8402, 0x4660,
+ 0x8403, 0x1459,
+ 0x8404, 0x0e24,
+ 0x8405, 0x4661,
+ 0x8406, 0x1455,
+ 0x8407, 0x2334,
+ 0x8408, 0x4662,
+ 0x840a, 0x1ff1,
+ 0x840b, 0x144e,
+ 0x840c, 0x0acd,
+ 0x840d, 0x0bdb,
+ 0x840e, 0x0ebd,
+ 0x840f, 0x1458,
+ 0x8410, 0x4664,
+ 0x8411, 0x1454,
+ 0x8412, 0x4665,
+ 0x8418, 0x144d,
+ 0x8419, 0x466b,
+ 0x841c, 0x1452,
+ 0x841d, 0x0a83,
+ 0x841e, 0x466e,
+ 0x8424, 0x108e,
+ 0x8426, 0x145f,
+ 0x8427, 0x0f61,
+ 0x8428, 0x0cd3,
+ 0x8429, 0x4674,
+ 0x842c, 0x218b,
+ 0x842d, 0x4677,
+ 0x8431, 0x1472,
+ 0x8432, 0x467b,
+ 0x8435, 0x2349,
+ 0x8436, 0x467e,
+ 0x8438, 0x1453,
+ 0x8439, 0x4680,
+ 0x843c, 0x146c,
+ 0x843d, 0x0a8b,
+ 0x843e, 0x4683,
+ 0x8446, 0x146d,
+ 0x8447, 0x468b,
+ 0x8449, 0x220b,
+ 0x844a, 0x468d,
+ 0x8451, 0x1463,
+ 0x8452, 0x2346,
+ 0x8453, 0x4694,
+ 0x8457, 0x11f7,
+ 0x8458, 0x4698,
+ 0x8459, 0x1465,
+ 0x845a, 0x1464,
+ 0x845b, 0x06eb,
+ 0x845c, 0x1462,
+ 0x845d, 0x4699,
+ 0x8461, 0x0bee,
+ 0x8462, 0x469d,
+ 0x8463, 0x05ec,
+ 0x8464, 0x2347,
+ 0x8465, 0x469e,
+ 0x8466, 0x2193,
+ 0x8467, 0x469f,
+ 0x8469, 0x146e,
+ 0x846a, 0x46a1,
+ 0x846b, 0x07b0,
+ 0x846c, 0x1124,
+ 0x846d, 0x1473,
+ 0x846e, 0x46a2,
+ 0x846f, 0x26a1,
+ 0x8470, 0x46a3,
+ 0x8471, 0x0553,
+ 0x8472, 0x46a4,
+ 0x8473, 0x1466,
+ 0x8474, 0x46a5,
+ 0x8475, 0x0988,
+ 0x8476, 0x146f,
+ 0x8477, 0x1f62,
+ 0x8478, 0x146b,
+ 0x8479, 0x46a6,
+ 0x847a, 0x1469,
+ 0x847b, 0x46a7,
+ 0x8482, 0x05ba,
+ 0x8483, 0x46ae,
+ 0x8487, 0x1467,
+ 0x8489, 0x146a,
+ 0x848a, 0x46b2,
+ 0x848b, 0x0880,
+ 0x848c, 0x1470,
+ 0x848d, 0x46b3,
+ 0x848e, 0x1471,
+ 0x848f, 0x46b4,
+ 0x8493, 0x234d,
+ 0x8494, 0x2348,
+ 0x8495, 0x46b8,
+ 0x8497, 0x1481,
+ 0x8498, 0x46ba,
+ 0x8499, 0x0ace,
+ 0x849a, 0x46bb,
+ 0x849c, 0x0dd7,
+ 0x849d, 0x46bd,
+ 0x84a1, 0x147e,
+ 0x84a2, 0x46c1,
+ 0x84af, 0x1297,
+ 0x84b0, 0x46ce,
+ 0x84b2, 0x0bf0,
+ 0x84b3, 0x46d0,
+ 0x84b4, 0x1480,
+ 0x84b5, 0x46d1,
+ 0x84b8, 0x1195,
+ 0x84b9, 0x147f,
+ 0x84ba, 0x147c,
+ 0x84bb, 0x46d4,
+ 0x84bc, 0x1e60,
+ 0x84bd, 0x1478,
+ 0x84be, 0x46d5,
+ 0x84bf, 0x147b,
+ 0x84c0, 0x2345,
+ 0x84c1, 0x1474,
+ 0x84c2, 0x46d6,
+ 0x84c4, 0x0fb9,
+ 0x84c5, 0x46d8,
+ 0x84c9, 0x0cb3,
+ 0x84ca, 0x147a,
+ 0x84cb, 0x1f12,
+ 0x84cc, 0x46dc,
+ 0x84cd, 0x1475,
+ 0x84ce, 0x46dd,
+ 0x84d0, 0x1476,
+ 0x84d1, 0x0de7,
+ 0x84d2, 0x46df,
+ 0x84d3, 0x1479,
+ 0x84d4, 0x46e0,
+ 0x84d6, 0x0436,
+ 0x84d7, 0x46e2,
+ 0x84dd, 0x09a1,
+ 0x84de, 0x46e8,
+ 0x84df, 0x082e,
+ 0x84e0, 0x147d,
+ 0x84e1, 0x46e9,
+ 0x84e3, 0x1483,
+ 0x84e4, 0x46eb,
+ 0x84e5, 0x1482,
+ 0x84e6, 0x1477,
+ 0x84e7, 0x46ec,
+ 0x84ec, 0x0baf,
+ 0x84ed, 0x46f1,
+ 0x84ee, 0x2018,
+ 0x84ef, 0x2335,
+ 0x84f0, 0x1487,
+ 0x84f1, 0x46f2,
+ 0x84fc, 0x148e,
+ 0x84fd, 0x233c,
+ 0x84fe, 0x46fd,
+ 0x84ff, 0x148d,
+ 0x8500, 0x46fe,
+ 0x850c, 0x1484,
+ 0x850d, 0x470a,
+ 0x8511, 0x0af4,
+ 0x8512, 0x470e,
+ 0x8513, 0x0aa2,
+ 0x8514, 0x266f,
+ 0x8515, 0x470f,
+ 0x8517, 0x1182,
+ 0x8518, 0x4711,
+ 0x851a, 0x0ec4,
+ 0x851b, 0x4713,
+ 0x851e, 0x2351,
+ 0x851f, 0x1489,
+ 0x8520, 0x4716,
+ 0x8521, 0x0493,
+ 0x8522, 0x4717,
+ 0x8523, 0x1fa0,
+ 0x8524, 0x4718,
+ 0x8526, 0x2338,
+ 0x8527, 0x471a,
+ 0x852b, 0x0b4b,
+ 0x852c, 0x0d76,
+ 0x852d, 0x221b,
+ 0x852e, 0x471e,
+ 0x8537, 0x0c3b,
+ 0x8538, 0x1486,
+ 0x8539, 0x1488,
+ 0x853a, 0x148a,
+ 0x853b, 0x148c,
+ 0x853c, 0x03b5,
+ 0x853d, 0x0437,
+ 0x853e, 0x4727,
+ 0x8541, 0x2342,
+ 0x8542, 0x472a,
+ 0x8543, 0x1496,
+ 0x8544, 0x472b,
+ 0x8546, 0x234f,
+ 0x8547, 0x472d,
+ 0x8548, 0x1490,
+ 0x8549, 0x0887,
+ 0x854a, 0x0cca,
+ 0x854b, 0x472e,
+ 0x854e, 0x233d,
+ 0x854f, 0x4731,
+ 0x8552, 0x2344,
+ 0x8553, 0x2331,
+ 0x8554, 0x4734,
+ 0x8555, 0x234b,
+ 0x8556, 0x148b,
+ 0x8557, 0x4735,
+ 0x8558, 0x233b,
+ 0x8559, 0x148f,
+ 0x855a, 0x4736,
+ 0x855e, 0x1493,
+ 0x855f, 0x473a,
+ 0x8562, 0x2350,
+ 0x8563, 0x473d,
+ 0x8564, 0x1492,
+ 0x8565, 0x473e,
+ 0x8568, 0x1491,
+ 0x8569, 0x1eb4,
+ 0x856a, 0x21a6,
+ 0x856b, 0x4741,
+ 0x856d, 0x21cb,
+ 0x856e, 0x4743,
+ 0x8572, 0x1497,
+ 0x8573, 0x4747,
+ 0x8574, 0x110f,
+ 0x8575, 0x4748,
+ 0x8577, 0x2355,
+ 0x8578, 0x474a,
+ 0x8579, 0x149d,
+ 0x857a, 0x1494,
+ 0x857b, 0x1498,
+ 0x857c, 0x474b,
+ 0x857e, 0x09c4,
+ 0x857f, 0x474d,
+ 0x8584, 0x040a,
+ 0x8585, 0x14a0,
+ 0x8586, 0x4752,
+ 0x8587, 0x149b,
+ 0x8588, 0x233e,
+ 0x8589, 0x4753,
+ 0x858a, 0x1f74,
+ 0x858b, 0x4754,
+ 0x858c, 0x2330,
+ 0x858d, 0x4755,
+ 0x858f, 0x149c,
+ 0x8590, 0x4757,
+ 0x8591, 0x2680,
+ 0x8592, 0x4758,
+ 0x8594, 0x20da,
+ 0x8595, 0x475a,
+ 0x859b, 0x0fcf,
+ 0x859c, 0x149f,
+ 0x859d, 0x4760,
+ 0x859f, 0x234a,
+ 0x85a0, 0x4762,
+ 0x85a4, 0x1499,
+ 0x85a5, 0x4766,
+ 0x85a6, 0x1f91,
+ 0x85a7, 0x4767,
+ 0x85a8, 0x149a,
+ 0x85a9, 0x2107,
+ 0x85aa, 0x0f88,
+ 0x85ab, 0x4768,
+ 0x85ae, 0x149e,
+ 0x85af, 0x0d84,
+ 0x85b0, 0x14a3,
+ 0x85b1, 0x476b,
+ 0x85b7, 0x14a2,
+ 0x85b8, 0x4771,
+ 0x85b9, 0x14a1,
+ 0x85ba, 0x233f,
+ 0x85bb, 0x4772,
+ 0x85c1, 0x14a5,
+ 0x85c2, 0x4778,
+ 0x85c9, 0x08b6,
+ 0x85ca, 0x477f,
+ 0x85cd, 0x1ff4,
+ 0x85ce, 0x2343,
+ 0x85cf, 0x049f,
+ 0x85d0, 0x0aef,
+ 0x85d1, 0x4782,
+ 0x85d3, 0x14a4,
+ 0x85d4, 0x4784,
+ 0x85d5, 0x0b7b,
+ 0x85d6, 0x4785,
+ 0x85dc, 0x14a6,
+ 0x85dd, 0x2212,
+ 0x85de, 0x478b,
+ 0x85e4, 0x0e2c,
+ 0x85e5, 0x2207,
+ 0x85e6, 0x4791,
+ 0x85e9, 0x0647,
+ 0x85ea, 0x2359,
+ 0x85eb, 0x4794,
+ 0x85f4, 0x2254,
+ 0x85f5, 0x479d,
+ 0x85f6, 0x2332,
+ 0x85f7, 0x479e,
+ 0x85f9, 0x1e26,
+ 0x85fa, 0x2357,
+ 0x85fb, 0x1128,
+ 0x85fc, 0x47a0,
+ 0x85ff, 0x14a7,
+ 0x8600, 0x47a3,
+ 0x8604, 0x2358,
+ 0x8605, 0x14a9,
+ 0x8606, 0x2042,
+ 0x8607, 0x2153,
+ 0x8608, 0x47a7,
+ 0x860b, 0x20bb,
+ 0x860c, 0x47aa,
+ 0x8611, 0x0b05,
+ 0x8612, 0x47af,
+ 0x8616, 0x14ab,
+ 0x8617, 0x47b3,
+ 0x861a, 0x235a,
+ 0x861b, 0x47b6,
+ 0x861e, 0x2356,
+ 0x861f, 0x47b9,
+ 0x8622, 0x2337,
+ 0x8623, 0x47bc,
+ 0x8627, 0x14a8,
+ 0x8628, 0x47c0,
+ 0x8629, 0x14aa,
+ 0x862a, 0x47c1,
+ 0x862d, 0x1ff9,
+ 0x862e, 0x47c4,
+ 0x8638, 0x115b,
+ 0x8639, 0x47ce,
+ 0x863a, 0x2353,
+ 0x863b, 0x47cf,
+ 0x863c, 0x14ac,
+ 0x863d, 0x47d0,
+ 0x863f, 0x2061,
+ 0x8640, 0x47d2,
+ 0x864d, 0x1bf0,
+ 0x864e, 0x07b7,
+ 0x864f, 0x0a59,
+ 0x8650, 0x0b71,
+ 0x8651, 0x0a6e,
+ 0x8652, 0x47df,
+ 0x8654, 0x1bf1,
+ 0x8655, 0x1e95,
+ 0x8656, 0x47e1,
+ 0x865a, 0x0fb4,
+ 0x865b, 0x47e5,
+ 0x865c, 0x2049,
+ 0x865d, 0x47e6,
+ 0x865e, 0x10c2,
+ 0x865f, 0x1f42,
+ 0x8660, 0x47e7,
+ 0x8662, 0x196d,
+ 0x8663, 0x47e9,
+ 0x8667, 0x1fe8,
+ 0x8668, 0x47ed,
+ 0x866b, 0x050b,
+ 0x866c, 0x1bf2,
+ 0x866d, 0x47f0,
+ 0x866e, 0x1bf3,
+ 0x866f, 0x47f1,
+ 0x8671, 0x0d44,
+ 0x8672, 0x47f3,
+ 0x8679, 0x079e,
+ 0x867a, 0x1bf5,
+ 0x867b, 0x1bf7,
+ 0x867c, 0x1bf6,
+ 0x867d, 0x0dd9,
+ 0x867e, 0x0f27,
+ 0x867f, 0x1bf4,
+ 0x8680, 0x0d4b,
+ 0x8681, 0x1056,
+ 0x8682, 0x0a93,
+ 0x8683, 0x47fa,
+ 0x868a, 0x0ed2,
+ 0x868b, 0x1bfa,
+ 0x868c, 0x0401,
+ 0x868d, 0x1bf9,
+ 0x868e, 0x4801,
+ 0x8693, 0x1c00,
+ 0x8694, 0x4806,
+ 0x8695, 0x0496,
+ 0x8696, 0x4807,
+ 0x869c, 0x0fea,
+ 0x869d, 0x1bfc,
+ 0x869e, 0x480d,
+ 0x86a3, 0x1bfe,
+ 0x86a4, 0x112c,
+ 0x86a5, 0x4812,
+ 0x86a7, 0x1bfd,
+ 0x86a8, 0x1bf8,
+ 0x86a9, 0x1c01,
+ 0x86aa, 0x1bff,
+ 0x86ab, 0x4814,
+ 0x86ac, 0x1bfb,
+ 0x86ad, 0x4815,
+ 0x86af, 0x1c09,
+ 0x86b0, 0x1c06,
+ 0x86b1, 0x1c08,
+ 0x86b2, 0x4817,
+ 0x86b4, 0x1c0c,
+ 0x86b5, 0x1c04,
+ 0x86b6, 0x1c02,
+ 0x86b7, 0x4819,
+ 0x86ba, 0x1c07,
+ 0x86bb, 0x481c,
+ 0x86c0, 0x11fa,
+ 0x86c1, 0x4821,
+ 0x86c4, 0x1c03,
+ 0x86c5, 0x4824,
+ 0x86c6, 0x0c76,
+ 0x86c7, 0x0d18,
+ 0x86c8, 0x4825,
+ 0x86c9, 0x1c0a,
+ 0x86ca, 0x071f,
+ 0x86cb, 0x0591,
+ 0x86cc, 0x4826,
+ 0x86ce, 0x1c05,
+ 0x86cf, 0x1c0b,
+ 0x86d0, 0x1c12,
+ 0x86d1, 0x1c18,
+ 0x86d2, 0x4828,
+ 0x86d4, 0x07ec,
+ 0x86d5, 0x482a,
+ 0x86d8, 0x1c17,
+ 0x86d9, 0x0e8d,
+ 0x86da, 0x482d,
+ 0x86db, 0x11ea,
+ 0x86dc, 0x482e,
+ 0x86de, 0x1c14,
+ 0x86df, 0x1c16,
+ 0x86e0, 0x4830,
+ 0x86e4, 0x06ed,
+ 0x86e5, 0x4834,
+ 0x86e9, 0x1c0d,
+ 0x86ea, 0x4838,
+ 0x86ed, 0x1c10,
+ 0x86ee, 0x0aa0,
+ 0x86ef, 0x483b,
+ 0x86f0, 0x117e,
+ 0x86f1, 0x1c0e,
+ 0x86f3, 0x1c11,
+ 0x86f4, 0x1c15,
+ 0x86f5, 0x483c,
+ 0x86f8, 0x1c1b,
+ 0x86f9, 0x10a1,
+ 0x86fa, 0x25da,
+ 0x86fb, 0x483f,
+ 0x86fe, 0x0629,
+ 0x86ff, 0x4842,
+ 0x8700, 0x0d88,
+ 0x8701, 0x4843,
+ 0x8702, 0x0681,
+ 0x8703, 0x1c19,
+ 0x8704, 0x4844,
+ 0x8706, 0x25d7,
+ 0x8707, 0x1c1a,
+ 0x8708, 0x1c1c,
+ 0x8709, 0x1c1f,
+ 0x870a, 0x1c1d,
+ 0x870b, 0x4846,
+ 0x870d, 0x1c1e,
+ 0x870e, 0x4848,
+ 0x8712, 0x0ffa,
+ 0x8713, 0x1c13,
+ 0x8714, 0x484c,
+ 0x8715, 0x0e7a,
+ 0x8716, 0x484d,
+ 0x8717, 0x0ede,
+ 0x8718, 0x11a8,
+ 0x8719, 0x484e,
+ 0x871a, 0x1c25,
+ 0x871b, 0x484f,
+ 0x871c, 0x0ae0,
+ 0x871d, 0x4850,
+ 0x871e, 0x1c22,
+ 0x871f, 0x4851,
+ 0x8721, 0x099a,
+ 0x8722, 0x1c2e,
+ 0x8723, 0x1c20,
+ 0x8724, 0x4853,
+ 0x8725, 0x1c23,
+ 0x8726, 0x4854,
+ 0x8729, 0x1c2a,
+ 0x872a, 0x4857,
+ 0x872e, 0x1c24,
+ 0x872f, 0x485b,
+ 0x8731, 0x1c29,
+ 0x8732, 0x485d,
+ 0x8734, 0x1c28,
+ 0x8735, 0x485f,
+ 0x8737, 0x1c2b,
+ 0x8738, 0x4861,
+ 0x873b, 0x1c21,
+ 0x873c, 0x4864,
+ 0x873e, 0x1c26,
+ 0x873f, 0x1c2c,
+ 0x8740, 0x4866,
+ 0x8747, 0x1091,
+ 0x8748, 0x1c27,
+ 0x8749, 0x04bc,
+ 0x874a, 0x486d,
+ 0x874c, 0x1c34,
+ 0x874d, 0x486f,
+ 0x874e, 0x0f76,
+ 0x874f, 0x4870,
+ 0x8753, 0x1c37,
+ 0x8754, 0x4874,
+ 0x8755, 0x212e,
+ 0x8756, 0x4875,
+ 0x8757, 0x07dd,
+ 0x8758, 0x4876,
+ 0x8759, 0x1c3b,
+ 0x875a, 0x4877,
+ 0x8760, 0x1c32,
+ 0x8761, 0x487d,
+ 0x8763, 0x1c38,
+ 0x8764, 0x1c3a,
+ 0x8765, 0x1c3c,
+ 0x8766, 0x21b2,
+ 0x8767, 0x487f,
+ 0x876e, 0x1c35,
+ 0x876f, 0x4886,
+ 0x8770, 0x1c33,
+ 0x8771, 0x4887,
+ 0x8774, 0x07b2,
+ 0x8775, 0x488a,
+ 0x8776, 0x05dc,
+ 0x8777, 0x488b,
+ 0x8778, 0x219e,
+ 0x8779, 0x488c,
+ 0x877b, 0x1c31,
+ 0x877c, 0x1c39,
+ 0x877d, 0x1c2f,
+ 0x877f, 0x488e,
+ 0x8782, 0x1c2d,
+ 0x8783, 0x1c46,
+ 0x8784, 0x25dc,
+ 0x8785, 0x1c43,
+ 0x8786, 0x4891,
+ 0x8788, 0x1c42,
+ 0x8789, 0x4893,
+ 0x878b, 0x1c36,
+ 0x878c, 0x4895,
+ 0x878d, 0x0cb5,
+ 0x878e, 0x4896,
+ 0x8793, 0x1c3d,
+ 0x8794, 0x489b,
+ 0x8797, 0x1c45,
+ 0x8798, 0x489e,
+ 0x879e, 0x206c,
+ 0x879f, 0x0afd,
+ 0x87a0, 0x48a4,
+ 0x87a2, 0x2226,
+ 0x87a3, 0x48a6,
+ 0x87a8, 0x1c3f,
+ 0x87a9, 0x48ab,
+ 0x87ab, 0x1c47,
+ 0x87ac, 0x1c49,
+ 0x87ad, 0x1c44,
+ 0x87ae, 0x48ad,
+ 0x87af, 0x1c3e,
+ 0x87b0, 0x48ae,
+ 0x87b3, 0x1c4b,
+ 0x87b4, 0x48b1,
+ 0x87b5, 0x1c4a,
+ 0x87b6, 0x48b2,
+ 0x87ba, 0x0a84,
+ 0x87bb, 0x25e0,
+ 0x87bc, 0x48b6,
+ 0x87bd, 0x1c4e,
+ 0x87be, 0x48b7,
+ 0x87c0, 0x1c50,
+ 0x87c1, 0x48b9,
+ 0x87c4, 0x227b,
+ 0x87c5, 0x48bc,
+ 0x87c6, 0x1c41,
+ 0x87c7, 0x48bd,
+ 0x87c8, 0x25de,
+ 0x87c9, 0x48be,
+ 0x87ca, 0x1c51,
+ 0x87cb, 0x1c4c,
+ 0x87cc, 0x48bf,
+ 0x87ce, 0x25e1,
+ 0x87cf, 0x48c1,
+ 0x87d1, 0x1c4f,
+ 0x87d2, 0x1c40,
+ 0x87d3, 0x1c4d,
+ 0x87d4, 0x48c3,
+ 0x87db, 0x1c52,
+ 0x87dc, 0x48ca,
+ 0x87e0, 0x1c54,
+ 0x87e1, 0x48ce,
+ 0x87e3, 0x25d5,
+ 0x87e4, 0x48d0,
+ 0x87e5, 0x1c48,
+ 0x87e6, 0x48d1,
+ 0x87ea, 0x1c53,
+ 0x87eb, 0x48d5,
+ 0x87ec, 0x1e6b,
+ 0x87ed, 0x48d6,
+ 0x87ee, 0x1c55,
+ 0x87ef, 0x25db,
+ 0x87f0, 0x48d7,
+ 0x87f2, 0x1e89,
+ 0x87f3, 0x48d9,
+ 0x87f6, 0x25d9,
+ 0x87f7, 0x48dc,
+ 0x87f9, 0x0f82,
+ 0x87fa, 0x48de,
+ 0x87fb, 0x2211,
+ 0x87fc, 0x48df,
+ 0x87fe, 0x1c58,
+ 0x87ff, 0x48e1,
+ 0x8800, 0x48e2,
+ 0x8803, 0x130d,
+ 0x8804, 0x48e5,
+ 0x8805, 0x2229,
+ 0x8806, 0x25d6,
+ 0x8807, 0x48e6,
+ 0x880a, 0x1c59,
+ 0x880b, 0x48e9,
+ 0x8810, 0x25dd,
+ 0x8811, 0x25df,
+ 0x8812, 0x48ee,
+ 0x8813, 0x1c57,
+ 0x8814, 0x48ef,
+ 0x8815, 0x0cbf,
+ 0x8816, 0x1c56,
+ 0x8817, 0x48f0,
+ 0x881b, 0x1c5a,
+ 0x881c, 0x48f4,
+ 0x881f, 0x1fef,
+ 0x8820, 0x48f7,
+ 0x8821, 0x1c5b,
+ 0x8822, 0x0543,
+ 0x8823, 0x25d8,
+ 0x8824, 0x48f8,
+ 0x8831, 0x1f29,
+ 0x8832, 0x1a8d,
+ 0x8833, 0x4905,
+ 0x8836, 0x1e5b,
+ 0x8837, 0x4908,
+ 0x8839, 0x1c5c,
+ 0x883a, 0x490a,
+ 0x883b, 0x2076,
+ 0x883c, 0x1c5d,
+ 0x883d, 0x490b,
+ 0x8840, 0x0fd3,
+ 0x8841, 0x490e,
+ 0x8844, 0x1caa,
+ 0x8845, 0x0f91,
+ 0x8846, 0x2297,
+ 0x8847, 0x4911,
+ 0x884a, 0x2690,
+ 0x884b, 0x4914,
+ 0x884c, 0x0f9b,
+ 0x884d, 0x1005,
+ 0x884e, 0x4915,
+ 0x8853, 0x213f,
+ 0x8854, 0x0f3b,
+ 0x8855, 0x491a,
+ 0x8857, 0x08a7,
+ 0x8858, 0x491c,
+ 0x8859, 0x0fec,
+ 0x885a, 0x491d,
+ 0x885b, 0x2198,
+ 0x885c, 0x491e,
+ 0x885d, 0x1e88,
+ 0x885e, 0x491f,
+ 0x8861, 0x0799,
+ 0x8862, 0x15ed,
+ 0x8863, 0x1049,
+ 0x8864, 0x1ba6,
+ 0x8865, 0x0480,
+ 0x8866, 0x4922,
+ 0x8868, 0x0456,
+ 0x8869, 0x1ba7,
+ 0x886a, 0x4924,
+ 0x886b, 0x0cf9,
+ 0x886c, 0x04e9,
+ 0x886d, 0x4925,
+ 0x886e, 0x1306,
+ 0x886f, 0x4926,
+ 0x8870, 0x0d9a,
+ 0x8871, 0x4927,
+ 0x8872, 0x1ba8,
+ 0x8873, 0x4928,
+ 0x8877, 0x11d3,
+ 0x8878, 0x492c,
+ 0x8879, 0x228c,
+ 0x887a, 0x492d,
+ 0x887d, 0x1ba9,
+ 0x887e, 0x1cbe,
+ 0x887f, 0x1baa,
+ 0x8880, 0x4930,
+ 0x8881, 0x10ef,
+ 0x8882, 0x1bab,
+ 0x8883, 0x4931,
+ 0x8884, 0x03cb,
+ 0x8885, 0x1cbf,
+ 0x8886, 0x4932,
+ 0x8888, 0x1cc0,
+ 0x8889, 0x4934,
+ 0x888b, 0x057f,
+ 0x888c, 0x4936,
+ 0x888d, 0x0b9c,
+ 0x888e, 0x4937,
+ 0x8892, 0x0e0e,
+ 0x8893, 0x493b,
+ 0x8896, 0x0faf,
+ 0x8897, 0x493e,
+ 0x889c, 0x0e91,
+ 0x889d, 0x4943,
+ 0x88a2, 0x1bac,
+ 0x88a3, 0x4948,
+ 0x88a4, 0x1307,
+ 0x88a5, 0x4949,
+ 0x88ab, 0x0424,
+ 0x88ac, 0x494f,
+ 0x88ad, 0x0f1b,
+ 0x88ae, 0x4950,
+ 0x88b1, 0x069f,
+ 0x88b2, 0x4953,
+ 0x88b7, 0x1bae,
+ 0x88b8, 0x4958,
+ 0x88bc, 0x1baf,
+ 0x88bd, 0x495c,
+ 0x88c1, 0x048a,
+ 0x88c2, 0x0a1a,
+ 0x88c3, 0x4960,
+ 0x88c5, 0x120d,
+ 0x88c6, 0x1bad,
+ 0x88c7, 0x4962,
+ 0x88c9, 0x1bb0,
+ 0x88ca, 0x25f1,
+ 0x88cb, 0x4964,
+ 0x88ce, 0x1bb2,
+ 0x88cf, 0x200c,
+ 0x88d0, 0x4967,
+ 0x88d2, 0x130a,
+ 0x88d3, 0x4969,
+ 0x88d4, 0x1068,
+ 0x88d5, 0x10e6,
+ 0x88d6, 0x496a,
+ 0x88d8, 0x1cc1,
+ 0x88d9, 0x0c94,
+ 0x88da, 0x496c,
+ 0x88dc, 0x1e58,
+ 0x88dd, 0x22ac,
+ 0x88de, 0x496e,
+ 0x88df, 0x1cc2,
+ 0x88e0, 0x496f,
+ 0x88e2, 0x1bb1,
+ 0x88e3, 0x1bb3,
+ 0x88e4, 0x0970,
+ 0x88e5, 0x1bb4,
+ 0x88e6, 0x4971,
+ 0x88e8, 0x1bb8,
+ 0x88e9, 0x4973,
+ 0x88f0, 0x1bba,
+ 0x88f1, 0x1bb5,
+ 0x88f2, 0x497a,
+ 0x88f3, 0x0d0a,
+ 0x88f4, 0x0ba2,
+ 0x88f5, 0x497b,
+ 0x88f8, 0x0a8a,
+ 0x88f9, 0x0755,
+ 0x88fa, 0x497e,
+ 0x88fc, 0x1bb7,
+ 0x88fd, 0x26a7,
+ 0x88fe, 0x1bb9,
+ 0x88ff, 0x4980,
+ 0x8900, 0x4981,
+ 0x8902, 0x072c,
+ 0x8903, 0x4983,
+ 0x8907, 0x2676,
+ 0x8908, 0x4987,
+ 0x890a, 0x1bbf,
+ 0x890b, 0x4989,
+ 0x8910, 0x078d,
+ 0x8911, 0x498e,
+ 0x8912, 0x0408,
+ 0x8913, 0x1bbd,
+ 0x8914, 0x498f,
+ 0x8919, 0x1bbc,
+ 0x891a, 0x1bb6,
+ 0x891b, 0x1bbe,
+ 0x891c, 0x4994,
+ 0x8921, 0x1bbb,
+ 0x8922, 0x4999,
+ 0x8925, 0x0cc7,
+ 0x8926, 0x499c,
+ 0x892a, 0x0e7b,
+ 0x892b, 0x1bc1,
+ 0x892c, 0x49a0,
+ 0x8930, 0x1739,
+ 0x8931, 0x49a4,
+ 0x8932, 0x1fe1,
+ 0x8933, 0x25bb,
+ 0x8934, 0x1bc0,
+ 0x8935, 0x49a5,
+ 0x8936, 0x1bc2,
+ 0x8937, 0x49a6,
+ 0x8938, 0x25be,
+ 0x8939, 0x49a7,
+ 0x893b, 0x22dd,
+ 0x893c, 0x49a9,
+ 0x8941, 0x1bc3,
+ 0x8942, 0x49ae,
+ 0x8944, 0x0f52,
+ 0x8945, 0x49b0,
+ 0x8947, 0x25bd,
+ 0x8948, 0x49b2,
+ 0x8956, 0x1e2a,
+ 0x8957, 0x49c0,
+ 0x895d, 0x25bc,
+ 0x895e, 0x1cc3,
+ 0x895f, 0x08c4,
+ 0x8960, 0x25ba,
+ 0x8961, 0x49c6,
+ 0x8964, 0x25bf,
+ 0x8965, 0x49c9,
+ 0x8966, 0x1bc4,
+ 0x8967, 0x49ca,
+ 0x896a, 0x2187,
+ 0x896b, 0x49cd,
+ 0x896c, 0x266b,
+ 0x896d, 0x49ce,
+ 0x896f, 0x1e7f,
+ 0x8970, 0x49d0,
+ 0x8972, 0x21ad,
+ 0x8973, 0x49d2,
+ 0x897b, 0x1bc5,
+ 0x897c, 0x49da,
+ 0x897f, 0x0f06,
+ 0x8980, 0x49dd,
+ 0x8981, 0x1031,
+ 0x8982, 0x49de,
+ 0x8983, 0x1bdf,
+ 0x8984, 0x49df,
+ 0x8986, 0x06ad,
+ 0x8987, 0x49e1,
+ 0x898b, 0x1f96,
+ 0x898c, 0x49e5,
+ 0x898f, 0x1f32,
+ 0x8990, 0x49e8,
+ 0x8993, 0x2084,
+ 0x8994, 0x49eb,
+ 0x8996, 0x2136,
+ 0x8997, 0x49ed,
+ 0x8998, 0x24b8,
+ 0x8999, 0x49ee,
+ 0x89a1, 0x24ba,
+ 0x89a2, 0x49f6,
+ 0x89a6, 0x24bc,
+ 0x89a7, 0x49fa,
+ 0x89aa, 0x20e4,
+ 0x89ab, 0x49fd,
+ 0x89ac, 0x24b9,
+ 0x89ad, 0x49fe,
+ 0x89af, 0x24bd,
+ 0x89b0, 0x4a00,
+ 0x89b2, 0x24be,
+ 0x89b3, 0x4a02,
+ 0x89b7, 0x24bf,
+ 0x89b8, 0x4a06,
+ 0x89ba, 0x1fd2,
+ 0x89bb, 0x4a08,
+ 0x89bd, 0x1ffd,
+ 0x89be, 0x4a0a,
+ 0x89bf, 0x24bb,
+ 0x89c0, 0x1f2d,
+ 0x89c1, 0x086e,
+ 0x89c2, 0x0734,
+ 0x89c3, 0x4a0b,
+ 0x89c4, 0x073f,
+ 0x89c5, 0x0ade,
+ 0x89c6, 0x0d6a,
+ 0x89c7, 0x193a,
+ 0x89c8, 0x09ab,
+ 0x89c9, 0x0924,
+ 0x89ca, 0x193b,
+ 0x89cd, 0x4a0c,
+ 0x89ce, 0x193e,
+ 0x89d2, 0x0898,
+ 0x89d3, 0x4a0d,
+ 0x89d6, 0x1d57,
+ 0x89d7, 0x4a10,
+ 0x89da, 0x1d59,
+ 0x89db, 0x4a13,
+ 0x89dc, 0x1d5a,
+ 0x89dd, 0x4a14,
+ 0x89de, 0x1d58,
+ 0x89df, 0x4a15,
+ 0x89e3, 0x08b3,
+ 0x89e4, 0x4a19,
+ 0x89e5, 0x1d5b,
+ 0x89e6, 0x0528,
+ 0x89e7, 0x4a1a,
+ 0x89eb, 0x1d5c,
+ 0x89ec, 0x4a1e,
+ 0x89ef, 0x1d5d,
+ 0x89f0, 0x4a21,
+ 0x89f3, 0x19c0,
+ 0x89f4, 0x2609,
+ 0x89f5, 0x4a24,
+ 0x89f6, 0x260a,
+ 0x89f7, 0x4a25,
+ 0x89f8, 0x1e94,
+ 0x89f9, 0x4a26,
+ 0x8a00, 0x0ffd,
+ 0x8a01, 0x22df,
+ 0x8a02, 0x1ecb,
+ 0x8a03, 0x1f0d,
+ 0x8a04, 0x4a2d,
+ 0x8a07, 0x12fe,
+ 0x8a08, 0x1f77,
+ 0x8a09, 0x4a30,
+ 0x8a0a, 0x21eb,
+ 0x8a0b, 0x4a31,
+ 0x8a0c, 0x22e1,
+ 0x8a0d, 0x4a32,
+ 0x8a0e, 0x216f,
+ 0x8a0f, 0x4a33,
+ 0x8a10, 0x22e0,
+ 0x8a11, 0x4a34,
+ 0x8a13, 0x21ea,
+ 0x8a14, 0x4a36,
+ 0x8a15, 0x22e2,
+ 0x8a16, 0x20cb,
+ 0x8a17, 0x4a37,
+ 0x8a18, 0x1f78,
+ 0x8a19, 0x4a38,
+ 0x8a1b, 0x1ee2,
+ 0x8a1c, 0x4a3a,
+ 0x8a1d, 0x21f2,
+ 0x8a1e, 0x4a3b,
+ 0x8a1f, 0x2150,
+ 0x8a20, 0x4a3c,
+ 0x8a23, 0x1fd3,
+ 0x8a24, 0x4a3f,
+ 0x8a25, 0x22e5,
+ 0x8a26, 0x4a40,
+ 0x8a2a, 0x1ef2,
+ 0x8a2b, 0x4a44,
+ 0x8a2d, 0x211f,
+ 0x8a2e, 0x4a46,
+ 0x8a31, 0x21dd,
+ 0x8a32, 0x4a49,
+ 0x8a34, 0x2154,
+ 0x8a35, 0x4a4b,
+ 0x8a36, 0x22e7,
+ 0x8a37, 0x4a4c,
+ 0x8a3a, 0x2282,
+ 0x8a3b, 0x4a4f,
+ 0x8a3e, 0x1d5e,
+ 0x8a3f, 0x4a52,
+ 0x8a41, 0x22e6,
+ 0x8a42, 0x4a54,
+ 0x8a46, 0x22e8,
+ 0x8a47, 0x4a58,
+ 0x8a48, 0x1a84,
+ 0x8a49, 0x4a59,
+ 0x8a4e, 0x22e4,
+ 0x8a4f, 0x4a5e,
+ 0x8a50, 0x226a,
+ 0x8a51, 0x4a5f,
+ 0x8a52, 0x22eb,
+ 0x8a53, 0x4a60,
+ 0x8a54, 0x22e9,
+ 0x8a55, 0x20bd,
+ 0x8a56, 0x4a61,
+ 0x8a58, 0x22ea,
+ 0x8a59, 0x4a63,
+ 0x8a5b, 0x22bd,
+ 0x8a5c, 0x4a65,
+ 0x8a5e, 0x1e9e,
+ 0x8a5f, 0x4a67,
+ 0x8a61, 0x22f6,
+ 0x8a62, 0x21e7,
+ 0x8a63, 0x2216,
+ 0x8a64, 0x4a69,
+ 0x8a66, 0x2137,
+ 0x8a67, 0x4a6b,
+ 0x8a69, 0x212c,
+ 0x8a6a, 0x4a6d,
+ 0x8a6b, 0x1e68,
+ 0x8a6c, 0x22f2,
+ 0x8a6d, 0x1f37,
+ 0x8a6e, 0x22f3,
+ 0x8a6f, 0x4a6e,
+ 0x8a70, 0x22ef,
+ 0x8a71, 0x1f50,
+ 0x8a72, 0x1f10,
+ 0x8a73, 0x21c8,
+ 0x8a74, 0x4a6f,
+ 0x8a75, 0x22f1,
+ 0x8a76, 0x4a70,
+ 0x8a79, 0x1153,
+ 0x8a7a, 0x4a73,
+ 0x8a7c, 0x22f0,
+ 0x8a7d, 0x4a75,
+ 0x8a7f, 0x22ee,
+ 0x8a80, 0x4a77,
+ 0x8a84, 0x22ed,
+ 0x8a85, 0x229e,
+ 0x8a86, 0x22ec,
+ 0x8a87, 0x1fe2,
+ 0x8a88, 0x4a7b,
+ 0x8a89, 0x10e3,
+ 0x8a8a, 0x0e2f,
+ 0x8a8b, 0x4a7c,
+ 0x8a8d, 0x20fe,
+ 0x8a8e, 0x4a7e,
+ 0x8a91, 0x22f9,
+ 0x8a93, 0x0d5b,
+ 0x8a94, 0x4a81,
+ 0x8a95, 0x1eaf,
+ 0x8a96, 0x4a82,
+ 0x8a98, 0x2236,
+ 0x8a99, 0x4a84,
+ 0x8a9a, 0x22f7,
+ 0x8a9b, 0x4a85,
+ 0x8a9e, 0x223d,
+ 0x8a9f, 0x4a88,
+ 0x8aa0, 0x1e82,
+ 0x8aa1, 0x1fb6,
+ 0x8aa2, 0x4a89,
+ 0x8aa3, 0x21a4,
+ 0x8aa4, 0x21aa,
+ 0x8aa5, 0x22f8,
+ 0x8aa6, 0x2151,
+ 0x8aa7, 0x4a8a,
+ 0x8aa8, 0x1f60,
+ 0x8aa9, 0x4a8b,
+ 0x8aac, 0x2147,
+ 0x8aad, 0x4a8e,
+ 0x8ab0, 0x2145,
+ 0x8ab1, 0x4a91,
+ 0x8ab2, 0x1fdc,
+ 0x8ab3, 0x4a92,
+ 0x8ab6, 0x2301,
+ 0x8ab7, 0x4a95,
+ 0x8ab9, 0x1ef5,
+ 0x8aba, 0x4a97,
+ 0x8abc, 0x2218,
+ 0x8abd, 0x4a99,
+ 0x8abf, 0x1ec6,
+ 0x8ac0, 0x4a9b,
+ 0x8ac2, 0x2300,
+ 0x8ac3, 0x4a9d,
+ 0x8ac4, 0x22b4,
+ 0x8ac5, 0x4a9e,
+ 0x8ac7, 0x2169,
+ 0x8ac8, 0x4aa0,
+ 0x8ac9, 0x22fd,
+ 0x8aca, 0x4aa1,
+ 0x8acb, 0x20ea,
+ 0x8acc, 0x4aa2,
+ 0x8acd, 0x22f4,
+ 0x8ace, 0x4aa3,
+ 0x8acf, 0x22fb,
+ 0x8ad0, 0x4aa4,
+ 0x8ad1, 0x22fc,
+ 0x8ad2, 0x2027,
+ 0x8ad3, 0x4aa5,
+ 0x8ad6, 0x2060,
+ 0x8ad7, 0x22ff,
+ 0x8ad8, 0x4aa8,
+ 0x8adb, 0x22fe,
+ 0x8adc, 0x1ec7,
+ 0x8add, 0x4aab,
+ 0x8ade, 0x230c,
+ 0x8adf, 0x4aac,
+ 0x8ae2, 0x22f5,
+ 0x8ae3, 0x4aaf,
+ 0x8ae4, 0x2306,
+ 0x8ae5, 0x4ab0,
+ 0x8ae6, 0x230a,
+ 0x8ae7, 0x21d3,
+ 0x8ae8, 0x4ab1,
+ 0x8aeb, 0x2303,
+ 0x8aec, 0x4ab4,
+ 0x8aed, 0x2307,
+ 0x8aee, 0x230b,
+ 0x8aef, 0x4ab5,
+ 0x8af1, 0x1f5f,
+ 0x8af2, 0x4ab7,
+ 0x8af3, 0x2309,
+ 0x8af4, 0x4ab8,
+ 0x8af6, 0x2302,
+ 0x8af7, 0x1f04,
+ 0x8af8, 0x229d,
+ 0x8af9, 0x4aba,
+ 0x8afa, 0x21fb,
+ 0x8afb, 0x4abb,
+ 0x8afc, 0x2308,
+ 0x8afd, 0x4abc,
+ 0x8afe, 0x20ac,
+ 0x8aff, 0x4abd,
+ 0x8b00, 0x208e,
+ 0x8b01, 0x2305,
+ 0x8b02, 0x2197,
+ 0x8b03, 0x4abe,
+ 0x8b04, 0x2171,
+ 0x8b05, 0x2298,
+ 0x8b06, 0x4abf,
+ 0x8b07, 0x173c,
+ 0x8b08, 0x4ac0,
+ 0x8b0a, 0x1f57,
+ 0x8b0b, 0x4ac2,
+ 0x8b0e, 0x2082,
+ 0x8b0f, 0x4ac5,
+ 0x8b10, 0x2311,
+ 0x8b11, 0x4ac6,
+ 0x8b14, 0x2304,
+ 0x8b15, 0x4ac9,
+ 0x8b16, 0x230f,
+ 0x8b17, 0x1e35,
+ 0x8b18, 0x4aca,
+ 0x8b19, 0x20d1,
+ 0x8b1a, 0x2310,
+ 0x8b1b, 0x1fa3,
+ 0x8b1c, 0x4acb,
+ 0x8b1d, 0x21d6,
+ 0x8b1e, 0x4acc,
+ 0x8b21, 0x2206,
+ 0x8b22, 0x4acf,
+ 0x8b26, 0x1d5f,
+ 0x8b27, 0x4ad3,
+ 0x8b28, 0x230d,
+ 0x8b29, 0x4ad4,
+ 0x8b2b, 0x2312,
+ 0x8b2c, 0x208d,
+ 0x8b2d, 0x2313,
+ 0x8b2e, 0x4ad6,
+ 0x8b33, 0x22e3,
+ 0x8b34, 0x4adb,
+ 0x8b39, 0x1fba,
+ 0x8b3a, 0x4ae0,
+ 0x8b3e, 0x2078,
+ 0x8b3f, 0x4ae4,
+ 0x8b49, 0x2288,
+ 0x8b4a, 0x4aee,
+ 0x8b4e, 0x2316,
+ 0x8b4f, 0x1f6b,
+ 0x8b50, 0x4af2,
+ 0x8b56, 0x2314,
+ 0x8b57, 0x4af8,
+ 0x8b58, 0x2130,
+ 0x8b59, 0x2315,
+ 0x8b5a, 0x2168,
+ 0x8b5b, 0x4af9,
+ 0x8b5c, 0x20c4,
+ 0x8b5d, 0x4afa,
+ 0x8b66, 0x08de,
+ 0x8b67, 0x4b03,
+ 0x8b6b, 0x2318,
+ 0x8b6c, 0x0bc8,
+ 0x8b6d, 0x4b07,
+ 0x8b6f, 0x2219,
+ 0x8b70, 0x2217,
+ 0x8b71, 0x4b09,
+ 0x8b74, 0x20d5,
+ 0x8b75, 0x4b0c,
+ 0x8b77, 0x1f4a,
+ 0x8b78, 0x4b0e,
+ 0x8b7d, 0x2240,
+ 0x8b7e, 0x4b13,
+ 0x8b80, 0x1ed3,
+ 0x8b81, 0x4b15,
+ 0x8b8a, 0x1e49,
+ 0x8b8b, 0x4b1e,
+ 0x8b8e, 0x261b,
+ 0x8b8f, 0x4b21,
+ 0x8b92, 0x1e6d,
+ 0x8b93, 0x20f8,
+ 0x8b94, 0x4b24,
+ 0x8b95, 0x1ffb,
+ 0x8b96, 0x2319,
+ 0x8b97, 0x4b25,
+ 0x8b9c, 0x230e,
+ 0x8b9d, 0x4b2a,
+ 0x8b9e, 0x2317,
+ 0x8b9f, 0x4b2b,
+ 0x8ba0, 0x1317,
+ 0x8ba1, 0x0839,
+ 0x8ba2, 0x05e8,
+ 0x8ba3, 0x06b7,
+ 0x8ba4, 0x0caa,
+ 0x8ba5, 0x0818,
+ 0x8ba6, 0x1318,
+ 0x8ba8, 0x0e29,
+ 0x8ba9, 0x0c9e,
+ 0x8baa, 0x131a,
+ 0x8bab, 0x0c1c,
+ 0x8bac, 0x4b2c,
+ 0x8bad, 0x0fde,
+ 0x8bae, 0x1070,
+ 0x8baf, 0x0fdf,
+ 0x8bb0, 0x083a,
+ 0x8bb1, 0x4b2d,
+ 0x8bb2, 0x0883,
+ 0x8bb3, 0x07f9,
+ 0x8bb4, 0x131b,
+ 0x8bb6, 0x0ff1,
+ 0x8bb7, 0x131d,
+ 0x8bb8, 0x0fb8,
+ 0x8bb9, 0x062e,
+ 0x8bba, 0x0a82,
+ 0x8bbb, 0x4b2e,
+ 0x8bbc, 0x0dc4,
+ 0x8bbd, 0x068a,
+ 0x8bbe, 0x0d21,
+ 0x8bbf, 0x0660,
+ 0x8bc0, 0x0926,
+ 0x8bc1, 0x11a3,
+ 0x8bc2, 0x131e,
+ 0x8bc4, 0x0bdf,
+ 0x8bc5, 0x1244,
+ 0x8bc6, 0x0d4d,
+ 0x8bc7, 0x4b2f,
+ 0x8bc8, 0x114a,
+ 0x8bc9, 0x0dd4,
+ 0x8bca, 0x1190,
+ 0x8bcb, 0x1320,
+ 0x8bcc, 0x11de,
+ 0x8bcd, 0x054d,
+ 0x8bce, 0x1322,
+ 0x8bcf, 0x1321,
+ 0x8bd0, 0x4b30,
+ 0x8bd1, 0x1072,
+ 0x8bd2, 0x1323,
+ 0x8bd5, 0x0d6b,
+ 0x8bd6, 0x1326,
+ 0x8bd7, 0x0d42,
+ 0x8bd8, 0x1327,
+ 0x8bda, 0x04f4,
+ 0x8bdb, 0x11ee,
+ 0x8bdc, 0x1329,
+ 0x8bdd, 0x07c5,
+ 0x8bde, 0x058f,
+ 0x8bdf, 0x132a,
+ 0x8be1, 0x0747,
+ 0x8be2, 0x0fd8,
+ 0x8be3, 0x106f,
+ 0x8be4, 0x132c,
+ 0x8be5, 0x06be,
+ 0x8be6, 0x0f57,
+ 0x8be7, 0x04b6,
+ 0x8be8, 0x132d,
+ 0x8bea, 0x4b31,
+ 0x8beb, 0x08bc,
+ 0x8bec, 0x0eeb,
+ 0x8bed, 0x10d4,
+ 0x8bee, 0x132f,
+ 0x8bef, 0x0f02,
+ 0x8bf0, 0x1330,
+ 0x8bf1, 0x10ba,
+ 0x8bf2, 0x07fa,
+ 0x8bf3, 0x1331,
+ 0x8bf4, 0x0daa,
+ 0x8bf5, 0x0dc5,
+ 0x8bf6, 0x1332,
+ 0x8bf7, 0x0c68,
+ 0x8bf8, 0x11ed,
+ 0x8bf9, 0x1333,
+ 0x8bfa, 0x0b76,
+ 0x8bfb, 0x0600,
+ 0x8bfc, 0x1334,
+ 0x8bfd, 0x0669,
+ 0x8bfe, 0x095b,
+ 0x8bff, 0x1335,
+ 0x8c00, 0x1336,
+ 0x8c01, 0x0da2,
+ 0x8c02, 0x1337,
+ 0x8c03, 0x05d8,
+ 0x8c04, 0x1338,
+ 0x8c05, 0x0a0b,
+ 0x8c06, 0x1218,
+ 0x8c07, 0x1339,
+ 0x8c08, 0x0e0b,
+ 0x8c09, 0x4b32,
+ 0x8c0a, 0x1071,
+ 0x8c0b, 0x0b14,
+ 0x8c0c, 0x133a,
+ 0x8c0d, 0x05de,
+ 0x8c0e, 0x07e6,
+ 0x8c0f, 0x133b,
+ 0x8c10, 0x0f7e,
+ 0x8c11, 0x133c,
+ 0x8c13, 0x0ecc,
+ 0x8c14, 0x133e,
+ 0x8c17, 0x04be,
+ 0x8c18, 0x1343,
+ 0x8c19, 0x1341,
+ 0x8c1a, 0x1011,
+ 0x8c1b, 0x1342,
+ 0x8c1c, 0x0ada,
+ 0x8c1d, 0x1344,
+ 0x8c1e, 0x4b33,
+ 0x8c1f, 0x1345,
+ 0x8c22, 0x0f86,
+ 0x8c23, 0x102c,
+ 0x8c24, 0x0404,
+ 0x8c25, 0x1348,
+ 0x8c26, 0x0c28,
+ 0x8c27, 0x1349,
+ 0x8c28, 0x08c8,
+ 0x8c29, 0x0aa6,
+ 0x8c2a, 0x134a,
+ 0x8c2c, 0x0b02,
+ 0x8c2d, 0x0e0a,
+ 0x8c2e, 0x134c,
+ 0x8c30, 0x09a9,
+ 0x8c31, 0x0bf6,
+ 0x8c32, 0x134e,
+ 0x8c34, 0x0c31,
+ 0x8c35, 0x1350,
+ 0x8c37, 0x0721,
+ 0x8c38, 0x4b34,
+ 0x8c41, 0x0802,
+ 0x8c42, 0x4b3d,
+ 0x8c46, 0x05f8,
+ 0x8c47, 0x1cf6,
+ 0x8c48, 0x20c8,
+ 0x8c49, 0x1cf7,
+ 0x8c4a, 0x4b41,
+ 0x8c4c, 0x0e94,
+ 0x8c4d, 0x4b43,
+ 0x8c50, 0x1efd,
+ 0x8c51, 0x4b46,
+ 0x8c55, 0x1d15,
+ 0x8c56, 0x4b4a,
+ 0x8c5a, 0x1990,
+ 0x8c5b, 0x4b4e,
+ 0x8c61, 0x0f60,
+ 0x8c62, 0x07d4,
+ 0x8c63, 0x4b54,
+ 0x8c6a, 0x0777,
+ 0x8c6b, 0x10e8,
+ 0x8c6c, 0x4b5b,
+ 0x8c73, 0x15dd,
+ 0x8c74, 0x4b62,
+ 0x8c78, 0x1d50,
+ 0x8c79, 0x0413,
+ 0x8c7a, 0x04b9,
+ 0x8c7b, 0x4b66,
+ 0x8c82, 0x1d51,
+ 0x8c83, 0x4b6d,
+ 0x8c85, 0x1d53,
+ 0x8c86, 0x4b6f,
+ 0x8c89, 0x0788,
+ 0x8c8a, 0x1d52,
+ 0x8c8b, 0x4b72,
+ 0x8c8c, 0x0ab7,
+ 0x8c8d, 0x4b73,
+ 0x8c94, 0x1d55,
+ 0x8c95, 0x4b7a,
+ 0x8c98, 0x1d54,
+ 0x8c99, 0x4b7d,
+ 0x8c9d, 0x1e3b,
+ 0x8c9e, 0x227f,
+ 0x8c9f, 0x4b81,
+ 0x8ca0, 0x1f0c,
+ 0x8ca1, 0x1e59,
+ 0x8ca2, 0x1f24,
+ 0x8ca3, 0x4b82,
+ 0x8ca7, 0x20ba,
+ 0x8ca8, 0x1f65,
+ 0x8ca9, 0x1ef0,
+ 0x8caa, 0x2164,
+ 0x8cab, 0x1f30,
+ 0x8cac, 0x2261,
+ 0x8cad, 0x4b86,
+ 0x8caf, 0x22a2,
+ 0x8cb0, 0x24ab,
+ 0x8cb1, 0x4b88,
+ 0x8cb2, 0x24af,
+ 0x8cb3, 0x1ee8,
+ 0x8cb4, 0x1f39,
+ 0x8cb5, 0x4b89,
+ 0x8cb6, 0x1e48,
+ 0x8cb7, 0x2070,
+ 0x8cb8, 0x1ea8,
+ 0x8cb9, 0x4b8a,
+ 0x8cba, 0x24ac,
+ 0x8cbb, 0x1ef7,
+ 0x8cbc, 0x2176,
+ 0x8cbd, 0x24ad,
+ 0x8cbe, 0x4b8b,
+ 0x8cbf, 0x207b,
+ 0x8cc0, 0x1f45,
+ 0x8cc1, 0x24aa,
+ 0x8cc2, 0x204b,
+ 0x8cc3, 0x202f,
+ 0x8cc4, 0x1f5a,
+ 0x8cc5, 0x24b0,
+ 0x8cc6, 0x4b8c,
+ 0x8cc7, 0x22b7,
+ 0x8cc8, 0x1f7f,
+ 0x8cc9, 0x4b8d,
+ 0x8cca, 0x2265,
+ 0x8ccb, 0x4b8e,
+ 0x8cd1, 0x24b2,
+ 0x8cd2, 0x211b,
+ 0x8cd3, 0x1e51,
+ 0x8cd4, 0x4b94,
+ 0x8cd5, 0x24b4,
+ 0x8cd6, 0x4b95,
+ 0x8cda, 0x24b3,
+ 0x8cdb, 0x4b99,
+ 0x8cdc, 0x1e9f,
+ 0x8cdd, 0x4b9a,
+ 0x8cde, 0x2118,
+ 0x8cdf, 0x4b9b,
+ 0x8ce0, 0x20b4,
+ 0x8ce1, 0x23af,
+ 0x8ce2, 0x21bb,
+ 0x8ce3, 0x2072,
+ 0x8ce4, 0x1f95,
+ 0x8ce5, 0x4b9c,
+ 0x8ce6, 0x1f0a,
+ 0x8ce7, 0x24b6,
+ 0x8ce8, 0x4b9d,
+ 0x8cea, 0x2291,
+ 0x8ceb, 0x24b5,
+ 0x8cec, 0x2278,
+ 0x8ced, 0x1ed4,
+ 0x8cee, 0x4b9f,
+ 0x8cf4, 0x1ff3,
+ 0x8cf5, 0x4ba5,
+ 0x8cfa, 0x22a9,
+ 0x8cfb, 0x24b7,
+ 0x8cfc, 0x1f28,
+ 0x8cfd, 0x2109,
+ 0x8cfe, 0x22c7,
+ 0x8cff, 0x4baa,
+ 0x8d00, 0x4bab,
+ 0x8d04, 0x24ae,
+ 0x8d05, 0x22b1,
+ 0x8d06, 0x4baf,
+ 0x8d08, 0x2266,
+ 0x8d09, 0x4bb1,
+ 0x8d0a, 0x225b,
+ 0x8d0b, 0x22c4,
+ 0x8d0c, 0x4bb2,
+ 0x8d0d, 0x2115,
+ 0x8d0e, 0x4bb3,
+ 0x8d0f, 0x222a,
+ 0x8d10, 0x24b1,
+ 0x8d11, 0x4bb4,
+ 0x8d16, 0x213d,
+ 0x8d17, 0x4bb9,
+ 0x8d1b, 0x1f15,
+ 0x8d1c, 0x225c,
+ 0x8d1d, 0x041d,
+ 0x8d1e, 0x118b,
+ 0x8d1f, 0x06b5,
+ 0x8d20, 0x4bbd,
+ 0x8d21, 0x070a,
+ 0x8d22, 0x048d,
+ 0x8d23, 0x1133,
+ 0x8d24, 0x0f3a,
+ 0x8d25, 0x03e7,
+ 0x8d26, 0x116c,
+ 0x8d27, 0x080a,
+ 0x8d28, 0x11c9,
+ 0x8d29, 0x0654,
+ 0x8d2a, 0x0e03,
+ 0x8d2b, 0x0bd5,
+ 0x8d2c, 0x044a,
+ 0x8d2d, 0x0713,
+ 0x8d2e, 0x11fb,
+ 0x8d2f, 0x073a,
+ 0x8d30, 0x063e,
+ 0x8d31, 0x086d,
+ 0x8d32, 0x192c,
+ 0x8d34, 0x0e4c,
+ 0x8d35, 0x074c,
+ 0x8d36, 0x192e,
+ 0x8d37, 0x057e,
+ 0x8d38, 0x0ab8,
+ 0x8d39, 0x066e,
+ 0x8d3a, 0x078f,
+ 0x8d3b, 0x192f,
+ 0x8d3c, 0x1137,
+ 0x8d3d, 0x1930,
+ 0x8d3e, 0x0849,
+ 0x8d3f, 0x07f4,
+ 0x8d40, 0x1931,
+ 0x8d41, 0x0a27,
+ 0x8d42, 0x0a5f,
+ 0x8d43, 0x1122,
+ 0x8d44, 0x1227,
+ 0x8d45, 0x1932,
+ 0x8d47, 0x1936,
+ 0x8d48, 0x1934,
+ 0x8d4a, 0x0d17,
+ 0x8d4b, 0x06ae,
+ 0x8d4c, 0x0603,
+ 0x8d4d, 0x1937,
+ 0x8d4e, 0x0d81,
+ 0x8d4f, 0x0d06,
+ 0x8d50, 0x0550,
+ 0x8d51, 0x4bbe,
+ 0x8d53, 0x163b,
+ 0x8d54, 0x0ba3,
+ 0x8d55, 0x1938,
+ 0x8d56, 0x09a0,
+ 0x8d57, 0x4bc0,
+ 0x8d58, 0x1215,
+ 0x8d59, 0x1939,
+ 0x8d5a, 0x1209,
+ 0x8d5b, 0x0cd7,
+ 0x8d5c, 0x1289,
+ 0x8d5d, 0x1283,
+ 0x8d5e, 0x1121,
+ 0x8d5f, 0x4bc1,
+ 0x8d60, 0x113c,
+ 0x8d61, 0x0cfd,
+ 0x8d62, 0x1093,
+ 0x8d63, 0x06ce,
+ 0x8d64, 0x0505,
+ 0x8d65, 0x4bc2,
+ 0x8d66, 0x0d1b,
+ 0x8d67, 0x1cf4,
+ 0x8d68, 0x4bc3,
+ 0x8d6b, 0x078c,
+ 0x8d6c, 0x4bc6,
+ 0x8d6d, 0x1cf5,
+ 0x8d6e, 0x4bc7,
+ 0x8d70, 0x123c,
+ 0x8d71, 0x4bc9,
+ 0x8d73, 0x1cef,
+ 0x8d74, 0x06ab,
+ 0x8d75, 0x1175,
+ 0x8d76, 0x06ca,
+ 0x8d77, 0x0c0f,
+ 0x8d78, 0x4bcb,
+ 0x8d81, 0x04e8,
+ 0x8d82, 0x4bd4,
+ 0x8d84, 0x1cf0,
+ 0x8d85, 0x04d1,
+ 0x8d86, 0x4bd6,
+ 0x8d8a, 0x1100,
+ 0x8d8b, 0x0c74,
+ 0x8d8c, 0x4bda,
+ 0x8d91, 0x1cf2,
+ 0x8d92, 0x4bdf,
+ 0x8d94, 0x1cf1,
+ 0x8d95, 0x1f14,
+ 0x8d96, 0x4be1,
+ 0x8d99, 0x227a,
+ 0x8d9a, 0x4be4,
+ 0x8d9f, 0x0e1e,
+ 0x8da0, 0x4be9,
+ 0x8da3, 0x0c7f,
+ 0x8da4, 0x4bec,
+ 0x8da8, 0x20ee,
+ 0x8da9, 0x4bf0,
+ 0x8db1, 0x1cf3,
+ 0x8db2, 0x25f8,
+ 0x8db3, 0x1240,
+ 0x8db4, 0x0b80,
+ 0x8db5, 0x1d1c,
+ 0x8db6, 0x4bf8,
+ 0x8db8, 0x1d17,
+ 0x8db9, 0x4bfa,
+ 0x8dba, 0x1d1f,
+ 0x8dbb, 0x4bfb,
+ 0x8dbc, 0x1d1e,
+ 0x8dbd, 0x4bfc,
+ 0x8dbe, 0x11b9,
+ 0x8dbf, 0x1d1d,
+ 0x8dc0, 0x4bfd,
+ 0x8dc3, 0x1101,
+ 0x8dc4, 0x1d20,
+ 0x8dc5, 0x4c00,
+ 0x8dc6, 0x1d28,
+ 0x8dc7, 0x4c01,
+ 0x8dcb, 0x03da,
+ 0x8dcc, 0x05d9,
+ 0x8dcd, 0x4c05,
+ 0x8dce, 0x1d25,
+ 0x8dd0, 0x4c06,
+ 0x8dd1, 0x0b9d,
+ 0x8dd2, 0x4c07,
+ 0x8dd6, 0x1d21,
+ 0x8dd8, 0x4c0b,
+ 0x8dda, 0x1d23,
+ 0x8ddb, 0x1d27,
+ 0x8ddc, 0x4c0d,
+ 0x8ddd, 0x090f,
+ 0x8dde, 0x1d24,
+ 0x8ddf, 0x06f5,
+ 0x8de0, 0x4c0e,
+ 0x8de3, 0x1d2c,
+ 0x8de4, 0x1d2f,
+ 0x8de5, 0x4c11,
+ 0x8de8, 0x0974,
+ 0x8de9, 0x4c14,
+ 0x8dea, 0x074b,
+ 0x8deb, 0x1d18,
+ 0x8dec, 0x1d29,
+ 0x8ded, 0x4c15,
+ 0x8def, 0x0a5e,
+ 0x8df0, 0x4c17,
+ 0x8df3, 0x0e4b,
+ 0x8df4, 0x4c1a,
+ 0x8df5, 0x086c,
+ 0x8df6, 0x4c1b,
+ 0x8df7, 0x1d2a,
+ 0x8df9, 0x1d2d,
+ 0x8dfa, 0x0624,
+ 0x8dfb, 0x1d2e,
+ 0x8dfc, 0x4c1c,
+ 0x8dfd, 0x1d31,
+ 0x8dfe, 0x4c1d,
+ 0x8e00, 0x4c1f,
+ 0x8e05, 0x1d19,
+ 0x8e06, 0x4c24,
+ 0x8e09, 0x1d30,
+ 0x8e0a, 0x10a0,
+ 0x8e0b, 0x4c27,
+ 0x8e0c, 0x0511,
+ 0x8e0d, 0x4c28,
+ 0x8e0f, 0x0df7,
+ 0x8e10, 0x1f94,
+ 0x8e11, 0x4c2a,
+ 0x8e14, 0x1d32,
+ 0x8e15, 0x4c2d,
+ 0x8e1d, 0x1d33,
+ 0x8e1e, 0x0910,
+ 0x8e1f, 0x1d34,
+ 0x8e20, 0x4c35,
+ 0x8e22, 0x0e32,
+ 0x8e23, 0x1d37,
+ 0x8e24, 0x4c37,
+ 0x8e29, 0x048f,
+ 0x8e2a, 0x1236,
+ 0x8e2b, 0x4c3c,
+ 0x8e2c, 0x1d35,
+ 0x8e2d, 0x4c3d,
+ 0x8e2e, 0x1d36,
+ 0x8e2f, 0x1d38,
+ 0x8e30, 0x4c3e,
+ 0x8e31, 0x1d3e,
+ 0x8e32, 0x4c3f,
+ 0x8e34, 0x2230,
+ 0x8e35, 0x1d3c,
+ 0x8e36, 0x4c41,
+ 0x8e39, 0x1d3b,
+ 0x8e3a, 0x1d39,
+ 0x8e3b, 0x4c44,
+ 0x8e3d, 0x1d3d,
+ 0x8e3e, 0x4c46,
+ 0x8e40, 0x1d3a,
+ 0x8e41, 0x1d40,
+ 0x8e43, 0x4c48,
+ 0x8e44, 0x0e36,
+ 0x8e45, 0x4c49,
+ 0x8e47, 0x173b,
+ 0x8e48, 0x0599,
+ 0x8e49, 0x1d3f,
+ 0x8e4a, 0x1d44,
+ 0x8e4b, 0x0df6,
+ 0x8e4c, 0x25fd,
+ 0x8e4d, 0x4c4b,
+ 0x8e51, 0x1d42,
+ 0x8e53, 0x4c4f,
+ 0x8e55, 0x2600,
+ 0x8e56, 0x4c51,
+ 0x8e59, 0x1d1a,
+ 0x8e5a, 0x4c54,
+ 0x8e63, 0x2606,
+ 0x8e64, 0x4c5d,
+ 0x8e66, 0x042d,
+ 0x8e67, 0x4c5f,
+ 0x8e69, 0x1d1b,
+ 0x8e6a, 0x4c61,
+ 0x8e6c, 0x05a6,
+ 0x8e6d, 0x04ab,
+ 0x8e6e, 0x4c63,
+ 0x8e6f, 0x1d48,
+ 0x8e70, 0x1d45,
+ 0x8e71, 0x4c64,
+ 0x8e72, 0x0616,
+ 0x8e73, 0x4c65,
+ 0x8e74, 0x1d49,
+ 0x8e75, 0x4c66,
+ 0x8e76, 0x1d46,
+ 0x8e77, 0x4c67,
+ 0x8e7a, 0x25ff,
+ 0x8e7b, 0x4c6a,
+ 0x8e7c, 0x1d47,
+ 0x8e7d, 0x4c6b,
+ 0x8e7f, 0x055d,
+ 0x8e80, 0x4c6d,
+ 0x8e81, 0x112d,
+ 0x8e82, 0x4c6e,
+ 0x8e85, 0x1d4a,
+ 0x8e86, 0x4c71,
+ 0x8e87, 0x051e,
+ 0x8e88, 0x4c72,
+ 0x8e89, 0x25fc,
+ 0x8e8a, 0x1e8c,
+ 0x8e8b, 0x2602,
+ 0x8e8c, 0x4c73,
+ 0x8e8d, 0x224d,
+ 0x8e8e, 0x4c74,
+ 0x8e8f, 0x1d4b,
+ 0x8e90, 0x1d4d,
+ 0x8e91, 0x2604,
+ 0x8e92, 0x25fe,
+ 0x8e93, 0x2603,
+ 0x8e94, 0x1d4c,
+ 0x8e95, 0x4c75,
+ 0x8e9a, 0x2601,
+ 0x8e9b, 0x4c7a,
+ 0x8e9c, 0x1d4e,
+ 0x8e9d, 0x4c7b,
+ 0x8e9e, 0x1d4f,
+ 0x8e9f, 0x4c7c,
+ 0x8ea1, 0x2605,
+ 0x8ea2, 0x4c7e,
+ 0x8ea5, 0x1ea3,
+ 0x8ea6, 0x2608,
+ 0x8ea7, 0x4c81,
+ 0x8eaa, 0x2607,
+ 0x8eab, 0x0d26,
+ 0x8eac, 0x0703,
+ 0x8ead, 0x4c84,
+ 0x8eaf, 0x0c78,
+ 0x8eb0, 0x4c86,
+ 0x8eb2, 0x0622,
+ 0x8eb3, 0x4c88,
+ 0x8eba, 0x0e1c,
+ 0x8ebb, 0x4c8f,
+ 0x8ec0, 0x20f0,
+ 0x8ec1, 0x4c94,
+ 0x8eca, 0x1e7b,
+ 0x8ecb, 0x2267,
+ 0x8ecc, 0x1f36,
+ 0x8ecd, 0x1fd6,
+ 0x8ece, 0x18f8,
+ 0x8ecf, 0x4c9d,
+ 0x8ed2, 0x21e0,
+ 0x8ed3, 0x4ca0,
+ 0x8ed4, 0x248c,
+ 0x8ed5, 0x4ca1,
+ 0x8edb, 0x248d,
+ 0x8edc, 0x4ca7,
+ 0x8edf, 0x2102,
+ 0x8ee0, 0x4caa,
+ 0x8ee4, 0x2494,
+ 0x8ee5, 0x4cae,
+ 0x8eeb, 0x2493,
+ 0x8eec, 0x4cb4,
+ 0x8ef2, 0x248e,
+ 0x8ef3, 0x4cba,
+ 0x8ef8, 0x2299,
+ 0x8ef9, 0x2491,
+ 0x8efa, 0x2496,
+ 0x8efb, 0x248f,
+ 0x8efc, 0x2492,
+ 0x8efd, 0x4cbf,
+ 0x8efe, 0x2497,
+ 0x8eff, 0x4cc0,
+ 0x8f00, 0x4cc1,
+ 0x8f03, 0x1fb1,
+ 0x8f04, 0x4cc4,
+ 0x8f05, 0x249a,
+ 0x8f06, 0x4cc5,
+ 0x8f07, 0x2499,
+ 0x8f08, 0x4cc6,
+ 0x8f09, 0x2258,
+ 0x8f0a, 0x2498,
+ 0x8f0b, 0x4cc7,
+ 0x8f12, 0x249b,
+ 0x8f13, 0x4cce,
+ 0x8f14, 0x1f09,
+ 0x8f15, 0x20e6,
+ 0x8f16, 0x4ccf,
+ 0x8f1b, 0x2026,
+ 0x8f1c, 0x249f,
+ 0x8f1d, 0x1f59,
+ 0x8f1e, 0x249d,
+ 0x8f20, 0x4cd4,
+ 0x8f25, 0x1f3b,
+ 0x8f26, 0x249c,
+ 0x8f27, 0x4cd9,
+ 0x8f29, 0x1e3a,
+ 0x8f2a, 0x205b,
+ 0x8f2b, 0x4cdb,
+ 0x8f2f, 0x1f70,
+ 0x8f30, 0x4cdf,
+ 0x8f33, 0x24a0,
+ 0x8f34, 0x4ce2,
+ 0x8f38, 0x213b,
+ 0x8f39, 0x4ce6,
+ 0x8f3b, 0x1f07,
+ 0x8f3c, 0x4ce8,
+ 0x8f3e, 0x2270,
+ 0x8f3f, 0x2237,
+ 0x8f40, 0x4cea,
+ 0x8f42, 0x24d2,
+ 0x8f43, 0x4cec,
+ 0x8f44, 0x21b3,
+ 0x8f45, 0x2245,
+ 0x8f46, 0x24a1,
+ 0x8f47, 0x4ced,
+ 0x8f49, 0x22a8,
+ 0x8f4a, 0x4cef,
+ 0x8f4d, 0x227c,
+ 0x8f4e, 0x1fb0,
+ 0x8f4f, 0x4cf2,
+ 0x8f54, 0x24a2,
+ 0x8f55, 0x4cf7,
+ 0x8f5f, 0x1f46,
+ 0x8f60, 0x4d01,
+ 0x8f61, 0x2380,
+ 0x8f62, 0x2495,
+ 0x8f63, 0x4d02,
+ 0x8f64, 0x2490,
+ 0x8f65, 0x4d03,
+ 0x8f66, 0x04da,
+ 0x8f67, 0x1141,
+ 0x8f68, 0x0745,
+ 0x8f69, 0x0fc4,
+ 0x8f6a, 0x4d04,
+ 0x8f6b, 0x18e1,
+ 0x8f6c, 0x1207,
+ 0x8f6d, 0x18e2,
+ 0x8f6e, 0x0a7d,
+ 0x8f6f, 0x0cc8,
+ 0x8f70, 0x079b,
+ 0x8f71, 0x18e3,
+ 0x8f74, 0x11e0,
+ 0x8f75, 0x18e6,
+ 0x8f77, 0x18e9,
+ 0x8f78, 0x18e8,
+ 0x8f79, 0x18ea,
+ 0x8f7b, 0x0c5e,
+ 0x8f7c, 0x18ec,
+ 0x8f7d, 0x111b,
+ 0x8f7e, 0x18ed,
+ 0x8f7f, 0x089f,
+ 0x8f80, 0x4d05,
+ 0x8f81, 0x18ee,
+ 0x8f83, 0x08a0,
+ 0x8f84, 0x18f0,
+ 0x8f85, 0x06a3,
+ 0x8f86, 0x0a07,
+ 0x8f87, 0x18f1,
+ 0x8f88, 0x041b,
+ 0x8f89, 0x07e9,
+ 0x8f8a, 0x074e,
+ 0x8f8b, 0x18f2,
+ 0x8f8c, 0x4d06,
+ 0x8f8d, 0x18f3,
+ 0x8f90, 0x0695,
+ 0x8f91, 0x0820,
+ 0x8f92, 0x4d07,
+ 0x8f93, 0x0d7b,
+ 0x8f94, 0x1574,
+ 0x8f95, 0x10f2,
+ 0x8f96, 0x0f2a,
+ 0x8f97, 0x1158,
+ 0x8f98, 0x18f6,
+ 0x8f99, 0x117f,
+ 0x8f9a, 0x18f7,
+ 0x8f9b, 0x0f8c,
+ 0x8f9c, 0x0715,
+ 0x8f9d, 0x4d08,
+ 0x8f9e, 0x054a,
+ 0x8f9f, 0x0442,
+ 0x8fa0, 0x4d09,
+ 0x8fa3, 0x099c,
+ 0x8fa4, 0x4d0c,
+ 0x8fa6, 0x1e30,
+ 0x8fa7, 0x4d0e,
+ 0x8fa8, 0x044f,
+ 0x8faa, 0x4d0f,
+ 0x8fab, 0x0451,
+ 0x8fac, 0x4d10,
+ 0x8fad, 0x1e9d,
+ 0x8fae, 0x1e4b,
+ 0x8faf, 0x1e4a,
+ 0x8fb0, 0x04e2,
+ 0x8fb1, 0x0cc3,
+ 0x8fb2, 0x20aa,
+ 0x8fb3, 0x4d11,
+ 0x8fb6, 0x173d,
+ 0x8fb7, 0x4d14,
+ 0x8fb9, 0x0448,
+ 0x8fba, 0x4d16,
+ 0x8fbd, 0x0a12,
+ 0x8fbe, 0x0572,
+ 0x8fbf, 0x4d19,
+ 0x8fc1, 0x0c25,
+ 0x8fc2, 0x10bd,
+ 0x8fc3, 0x4d1b,
+ 0x8fc4, 0x0c18,
+ 0x8fc5, 0x0fe1,
+ 0x8fc6, 0x4d1c,
+ 0x8fc7, 0x0756,
+ 0x8fc8, 0x0a9c,
+ 0x8fc9, 0x4d1d,
+ 0x8fce, 0x1092,
+ 0x8fcf, 0x4d22,
+ 0x8fd0, 0x110e,
+ 0x8fd1, 0x08cd,
+ 0x8fd2, 0x4d23,
+ 0x8fd3, 0x173e,
+ 0x8fd4, 0x0652,
+ 0x8fd5, 0x173f,
+ 0x8fd6, 0x4d24,
+ 0x8fd8, 0x07ce,
+ 0x8fd9, 0x1183,
+ 0x8fda, 0x4d26,
+ 0x8fdb, 0x08c9,
+ 0x8fdc, 0x10f9,
+ 0x8fdd, 0x0eb4,
+ 0x8fde, 0x09f5,
+ 0x8fdf, 0x04fe,
+ 0x8fe0, 0x4d27,
+ 0x8fe2, 0x0e49,
+ 0x8fe3, 0x4d29,
+ 0x8fe4, 0x1742,
+ 0x8fe5, 0x1740,
+ 0x8fe6, 0x1744,
+ 0x8fe7, 0x4d2a,
+ 0x8fe8, 0x1746,
+ 0x8fe9, 0x1743,
+ 0x8fea, 0x05b0,
+ 0x8feb, 0x0be7,
+ 0x8fec, 0x4d2b,
+ 0x8fed, 0x05dd,
+ 0x8fee, 0x1741,
+ 0x8fef, 0x4d2c,
+ 0x8ff0, 0x0d8d,
+ 0x8ff1, 0x4d2d,
+ 0x8ff3, 0x1745,
+ 0x8ff4, 0x267b,
+ 0x8ff5, 0x4d2f,
+ 0x8ff7, 0x0ad9,
+ 0x8ff8, 0x042e,
+ 0x8ff9, 0x0816,
+ 0x8ffa, 0x4d31,
+ 0x8ffd, 0x1214,
+ 0x8ffe, 0x4d34,
+ 0x9000, 0x0e7c,
+ 0x9001, 0x0dc2,
+ 0x9002, 0x0d61,
+ 0x9003, 0x0e26,
+ 0x9004, 0x1748,
+ 0x9005, 0x1747,
+ 0x9006, 0x0b49,
+ 0x9007, 0x4d36,
+ 0x9009, 0x0fca,
+ 0x900a, 0x0fe0,
+ 0x900b, 0x1749,
+ 0x900c, 0x4d38,
+ 0x900d, 0x174c,
+ 0x900e, 0x4d39,
+ 0x900f, 0x0e69,
+ 0x9010, 0x11ef,
+ 0x9011, 0x174b,
+ 0x9012, 0x05be,
+ 0x9013, 0x4d3a,
+ 0x9014, 0x0e6f,
+ 0x9015, 0x23f2,
+ 0x9016, 0x174d,
+ 0x9017, 0x05f9,
+ 0x9018, 0x4d3b,
+ 0x9019, 0x227e,
+ 0x901a, 0x0e59,
+ 0x901b, 0x073d,
+ 0x901c, 0x4d3c,
+ 0x901d, 0x0d5c,
+ 0x901e, 0x04f6,
+ 0x901f, 0x0dce,
+ 0x9020, 0x112f,
+ 0x9021, 0x174e,
+ 0x9022, 0x0687,
+ 0x9023, 0x2019,
+ 0x9024, 0x4d3d,
+ 0x9026, 0x174a,
+ 0x9027, 0x4d3f,
+ 0x902d, 0x1751,
+ 0x902e, 0x0581,
+ 0x902f, 0x1752,
+ 0x9030, 0x4d45,
+ 0x9032, 0x1fbb,
+ 0x9033, 0x4d47,
+ 0x9035, 0x174f,
+ 0x9037, 0x4d49,
+ 0x9038, 0x1064,
+ 0x9039, 0x4d4a,
+ 0x903b, 0x0a86,
+ 0x903c, 0x042f,
+ 0x903d, 0x4d4c,
+ 0x903e, 0x10c7,
+ 0x903f, 0x4d4d,
+ 0x9041, 0x061c,
+ 0x9042, 0x0de1,
+ 0x9043, 0x4d4f,
+ 0x9044, 0x1753,
+ 0x9045, 0x4d50,
+ 0x9047, 0x10db,
+ 0x9048, 0x4d52,
+ 0x904b, 0x2253,
+ 0x904c, 0x4d55,
+ 0x904d, 0x0452,
+ 0x904e, 0x1f3e,
+ 0x904f, 0x0633,
+ 0x9050, 0x1756,
+ 0x9051, 0x1754,
+ 0x9053, 0x05a1,
+ 0x9054, 0x1ea6,
+ 0x9055, 0x218e,
+ 0x9056, 0x4d56,
+ 0x9057, 0x104c,
+ 0x9058, 0x1758,
+ 0x9059, 0x4d57,
+ 0x905b, 0x175a,
+ 0x905c, 0x21ec,
+ 0x905d, 0x4d59,
+ 0x905e, 0x1ebe,
+ 0x905f, 0x4d5a,
+ 0x9060, 0x224a,
+ 0x9061, 0x4d5b,
+ 0x9062, 0x1759,
+ 0x9063, 0x0c2f,
+ 0x9064, 0x4d5c,
+ 0x9065, 0x102a,
+ 0x9066, 0x4d5d,
+ 0x9068, 0x1757,
+ 0x9069, 0x2133,
+ 0x906a, 0x4d5f,
+ 0x906d, 0x1125,
+ 0x906e, 0x117b,
+ 0x906f, 0x4d62,
+ 0x9072, 0x1e84,
+ 0x9073, 0x4d65,
+ 0x9074, 0x175c,
+ 0x9075, 0x124e,
+ 0x9076, 0x4d66,
+ 0x9077, 0x20cf,
+ 0x9078, 0x21e2,
+ 0x9079, 0x4d67,
+ 0x907a, 0x220f,
+ 0x907b, 0x4d68,
+ 0x907c, 0x2029,
+ 0x907d, 0x175d,
+ 0x907e, 0x4d69,
+ 0x907f, 0x0445,
+ 0x9080, 0x1024,
+ 0x9081, 0x2073,
+ 0x9082, 0x175e,
+ 0x9083, 0x1760,
+ 0x9084, 0x1f55,
+ 0x9085, 0x4d6a,
+ 0x9087, 0x23f1,
+ 0x9088, 0x175f,
+ 0x9089, 0x4d6c,
+ 0x908a, 0x1e46,
+ 0x908b, 0x1761,
+ 0x908c, 0x4d6d,
+ 0x908f, 0x2063,
+ 0x9090, 0x23f3,
+ 0x9091, 0x105f,
+ 0x9092, 0x4d70,
+ 0x9093, 0x05ac,
+ 0x9094, 0x4d71,
+ 0x9095, 0x1817,
+ 0x9096, 0x4d72,
+ 0x9097, 0x1367,
+ 0x9098, 0x4d73,
+ 0x9099, 0x136a,
+ 0x909a, 0x4d74,
+ 0x909b, 0x1368,
+ 0x909c, 0x4d75,
+ 0x909d, 0x1369,
+ 0x909e, 0x4d76,
+ 0x90a1, 0x136c,
+ 0x90a2, 0x0f9a,
+ 0x90a3, 0x0b2a,
+ 0x90a4, 0x4d79,
+ 0x90a6, 0x03f9,
+ 0x90a7, 0x4d7b,
+ 0x90aa, 0x0f7b,
+ 0x90ab, 0x4d7e,
+ 0x90ac, 0x136b,
+ 0x90ad, 0x4d7f,
+ 0x90ae, 0x10af,
+ 0x90af, 0x0761,
+ 0x90b0, 0x1372,
+ 0x90b1, 0x0c6e,
+ 0x90b2, 0x4d80,
+ 0x90b3, 0x136e,
+ 0x90b4, 0x136d,
+ 0x90b5, 0x0d14,
+ 0x90b6, 0x136f,
+ 0x90b7, 0x4d81,
+ 0x90b8, 0x1371,
+ 0x90b9, 0x123b,
+ 0x90ba, 0x1370,
+ 0x90bb, 0x0a23,
+ 0x90bc, 0x4d82,
+ 0x90be, 0x1375,
+ 0x90bf, 0x4d84,
+ 0x90c1, 0x10d9,
+ 0x90c2, 0x4d86,
+ 0x90c4, 0x1377,
+ 0x90c5, 0x1374,
+ 0x90c6, 0x4d88,
+ 0x90c7, 0x1378,
+ 0x90c8, 0x4d89,
+ 0x90ca, 0x088d,
+ 0x90cb, 0x4d8b,
+ 0x90ce, 0x09b4,
+ 0x90cf, 0x1373,
+ 0x90d0, 0x1376,
+ 0x90d1, 0x11a2,
+ 0x90d2, 0x4d8e,
+ 0x90d3, 0x1379,
+ 0x90d4, 0x4d8f,
+ 0x90d7, 0x137d,
+ 0x90d8, 0x4d92,
+ 0x90db, 0x137e,
+ 0x90dc, 0x137c,
+ 0x90dd, 0x0779,
+ 0x90de, 0x4d95,
+ 0x90df, 0x231e,
+ 0x90e0, 0x4d96,
+ 0x90e1, 0x0931,
+ 0x90e2, 0x137b,
+ 0x90e3, 0x4d97,
+ 0x90e6, 0x137a,
+ 0x90e7, 0x110a,
+ 0x90e8, 0x0486,
+ 0x90e9, 0x4d9a,
+ 0x90eb, 0x137f,
+ 0x90ec, 0x4d9c,
+ 0x90ed, 0x0752,
+ 0x90ee, 0x4d9d,
+ 0x90ef, 0x1380,
+ 0x90f0, 0x4d9e,
+ 0x90f4, 0x04e0,
+ 0x90f5, 0x2233,
+ 0x90f6, 0x4da2,
+ 0x90f8, 0x0587,
+ 0x90f9, 0x4da4,
+ 0x90fd, 0x05fb,
+ 0x90fe, 0x1381,
+ 0x90ff, 0x4da8,
+ 0x9100, 0x4da9,
+ 0x9102, 0x0634,
+ 0x9103, 0x4dab,
+ 0x9104, 0x1382,
+ 0x9105, 0x4dac,
+ 0x9106, 0x2320,
+ 0x9107, 0x4dad,
+ 0x9109, 0x21c7,
+ 0x910a, 0x4daf,
+ 0x9112, 0x22bc,
+ 0x9113, 0x4db7,
+ 0x9114, 0x231c,
+ 0x9115, 0x4db8,
+ 0x9116, 0x2251,
+ 0x9117, 0x4db9,
+ 0x9119, 0x0432,
+ 0x911a, 0x4dbb,
+ 0x911e, 0x1384,
+ 0x911f, 0x4dbf,
+ 0x9122, 0x1383,
+ 0x9123, 0x1385,
+ 0x9124, 0x4dc2,
+ 0x9127, 0x1ebb,
+ 0x9128, 0x4dc5,
+ 0x912d, 0x2287,
+ 0x912e, 0x4dca,
+ 0x912f, 0x1387,
+ 0x9130, 0x202d,
+ 0x9131, 0x1386,
+ 0x9132, 0x1eab,
+ 0x9133, 0x4dcb,
+ 0x9134, 0x231d,
+ 0x9135, 0x4dcc,
+ 0x9136, 0x231f,
+ 0x9137, 0x4dcd,
+ 0x9139, 0x1388,
+ 0x913a, 0x231b,
+ 0x913b, 0x4dcf,
+ 0x9143, 0x1389,
+ 0x9144, 0x4dd7,
+ 0x9146, 0x138a,
+ 0x9147, 0x4dd9,
+ 0x9148, 0x2321,
+ 0x9149, 0x10b4,
+ 0x914a, 0x1cf8,
+ 0x914b, 0x0c72,
+ 0x914c, 0x1220,
+ 0x914d, 0x0ba5,
+ 0x914e, 0x1cfa,
+ 0x9150, 0x1cf9,
+ 0x9151, 0x4dda,
+ 0x9152, 0x08f5,
+ 0x9153, 0x4ddb,
+ 0x9157, 0x0fba,
+ 0x9158, 0x4ddf,
+ 0x915a, 0x0670,
+ 0x915b, 0x4de1,
+ 0x915d, 0x1110,
+ 0x915e, 0x0dfd,
+ 0x915f, 0x4de3,
+ 0x9161, 0x1cfe,
+ 0x9162, 0x1cfd,
+ 0x9163, 0x075f,
+ 0x9164, 0x1cfc,
+ 0x9165, 0x0dcb,
+ 0x9166, 0x4de5,
+ 0x9169, 0x1d00,
+ 0x916a, 0x09bd,
+ 0x916b, 0x4de8,
+ 0x916c, 0x050f,
+ 0x916d, 0x4de9,
+ 0x916e, 0x0e5b,
+ 0x916f, 0x1d01,
+ 0x9170, 0x1cff,
+ 0x9171, 0x0885,
+ 0x9172, 0x1d04,
+ 0x9173, 0x4dea,
+ 0x9174, 0x1d05,
+ 0x9175, 0x089e,
+ 0x9176, 0x0abd,
+ 0x9177, 0x096e,
+ 0x9178, 0x0dd6,
+ 0x9179, 0x1d06,
+ 0x917a, 0x4deb,
+ 0x917d, 0x1d02,
+ 0x917f, 0x0b53,
+ 0x9180, 0x4dee,
+ 0x9185, 0x1d08,
+ 0x9186, 0x4df3,
+ 0x9187, 0x053f,
+ 0x9188, 0x4df4,
+ 0x9189, 0x124a,
+ 0x918a, 0x4df5,
+ 0x918b, 0x055a,
+ 0x918c, 0x1d07,
+ 0x918d, 0x1d0a,
+ 0x918e, 0x4df6,
+ 0x9190, 0x1d09,
+ 0x9191, 0x1d0b,
+ 0x9192, 0x0f9c,
+ 0x9193, 0x4df8,
+ 0x9196, 0x2255,
+ 0x9197, 0x4dfb,
+ 0x919a, 0x0ad6,
+ 0x919b, 0x0c84,
+ 0x919c, 0x1e8f,
+ 0x919d, 0x4dfe,
+ 0x91a2, 0x1d0c,
+ 0x91a4, 0x4e03,
+ 0x91aa, 0x1d0e,
+ 0x91ab, 0x220c,
+ 0x91ac, 0x1fa4,
+ 0x91ad, 0x1d0f,
+ 0x91b0, 0x4e09,
+ 0x91b4, 0x1d13,
+ 0x91b5, 0x1d12,
+ 0x91b6, 0x4e0d,
+ 0x91ba, 0x1d14,
+ 0x91bb, 0x4e11,
+ 0x91c0, 0x209b,
+ 0x91c1, 0x21d8,
+ 0x91c2, 0x4e16,
+ 0x91c3, 0x25fa,
+ 0x91c4, 0x4e17,
+ 0x91c5, 0x25f9,
+ 0x91c6, 0x4e18,
+ 0x91c7, 0x0490,
+ 0x91c8, 0x4e19,
+ 0x91c9, 0x10b9,
+ 0x91ca, 0x0d64,
+ 0x91cb, 0x2134,
+ 0x91cc, 0x09da,
+ 0x91cd, 0x11d7,
+ 0x91ce, 0x1037,
+ 0x91cf, 0x0a08,
+ 0x91d0, 0x4e1a,
+ 0x91d1, 0x08c1,
+ 0x91d2, 0x24f3,
+ 0x91d5, 0x24f8,
+ 0x91d6, 0x4e1b,
+ 0x91d7, 0x24f7,
+ 0x91d8, 0x1ec8,
+ 0x91d9, 0x24f6,
+ 0x91da, 0x4e1c,
+ 0x91dc, 0x06a5,
+ 0x91dd, 0x2280,
+ 0x91de, 0x4e1e,
+ 0x91e3, 0x1ec5,
+ 0x91e4, 0x24fb,
+ 0x91e5, 0x4e23,
+ 0x91e7, 0x24fa,
+ 0x91e8, 0x4e25,
+ 0x91e9, 0x1eed,
+ 0x91ea, 0x4e26,
+ 0x91f5, 0x24fd,
+ 0x91f6, 0x4e31,
+ 0x91f7, 0x24f9,
+ 0x91f8, 0x4e32,
+ 0x91f9, 0x24fe,
+ 0x91fa, 0x20cd,
+ 0x91fb, 0x4e33,
+ 0x9200, 0x2508,
+ 0x9201, 0x2504,
+ 0x9202, 0x4e38,
+ 0x9204, 0x2506,
+ 0x9205, 0x4e3a,
+ 0x9208, 0x24ff,
+ 0x9209, 0x2090,
+ 0x920a, 0x4e3d,
+ 0x920d, 0x1edd,
+ 0x920e, 0x1f25,
+ 0x920f, 0x4e40,
+ 0x9210, 0x2503,
+ 0x9211, 0x2502,
+ 0x9212, 0x4e41,
+ 0x9214, 0x1e7a,
+ 0x9215, 0x20a6,
+ 0x9216, 0x4e43,
+ 0x921e, 0x1fd5,
+ 0x921f, 0x4e4b,
+ 0x9223, 0x1f11,
+ 0x9224, 0x4e4f,
+ 0x9225, 0x2507,
+ 0x9226, 0x2500,
+ 0x9227, 0x2505,
+ 0x9228, 0x4e50,
+ 0x922e, 0x2519,
+ 0x922f, 0x4e56,
+ 0x9230, 0x2515,
+ 0x9231, 0x4e57,
+ 0x9233, 0x250c,
+ 0x9234, 0x2031,
+ 0x9235, 0x4e59,
+ 0x9237, 0x250b,
+ 0x9238, 0x250f,
+ 0x9239, 0x251a,
+ 0x923a, 0x2509,
+ 0x923b, 0x4e5b,
+ 0x923d, 0x250e,
+ 0x923e, 0x2234,
+ 0x923f, 0x2513,
+ 0x9240, 0x1f80,
+ 0x9241, 0x4e5d,
+ 0x9245, 0x2501,
+ 0x9246, 0x4e61,
+ 0x9248, 0x2517,
+ 0x9249, 0x2516,
+ 0x924a, 0x4e63,
+ 0x924d, 0x2518,
+ 0x924e, 0x4e66,
+ 0x9251, 0x1e56,
+ 0x9252, 0x4e69,
+ 0x9255, 0x250d,
+ 0x9256, 0x4e6c,
+ 0x9257, 0x20d3,
+ 0x9258, 0x4e6d,
+ 0x925a, 0x207a,
+ 0x925b, 0x20ce,
+ 0x925c, 0x4e6f,
+ 0x925e, 0x2510,
+ 0x925f, 0x4e71,
+ 0x9262, 0x1e55,
+ 0x9263, 0x4e74,
+ 0x9266, 0x250a,
+ 0x9267, 0x4e77,
+ 0x926c, 0x2511,
+ 0x926e, 0x4e7c,
+ 0x9274, 0x086b,
+ 0x9275, 0x4e82,
+ 0x9278, 0x1faa,
+ 0x9279, 0x4e85,
+ 0x927a, 0x251e,
+ 0x927b, 0x1f1f,
+ 0x927c, 0x4e86,
+ 0x927f, 0x252d,
+ 0x9280, 0x221d,
+ 0x9281, 0x4e89,
+ 0x9283, 0x2532,
+ 0x9284, 0x4e8b,
+ 0x9285, 0x217b,
+ 0x9286, 0x4e8c,
+ 0x928e, 0x1d80,
+ 0x928f, 0x4e94,
+ 0x9291, 0x21af,
+ 0x9292, 0x4e96,
+ 0x9293, 0x252c,
+ 0x9294, 0x4e97,
+ 0x9296, 0x2528,
+ 0x9297, 0x4e99,
+ 0x9298, 0x208c,
+ 0x9299, 0x4e9a,
+ 0x929a, 0x252f,
+ 0x929b, 0x4e9b,
+ 0x929c, 0x21bc,
+ 0x929d, 0x4e9c,
+ 0x92a0, 0x251d,
+ 0x92a1, 0x4e9f,
+ 0x92a3, 0x2535,
+ 0x92a4, 0x4ea1,
+ 0x92a5, 0x220d,
+ 0x92a6, 0x2526,
+ 0x92a7, 0x4ea2,
+ 0x92a8, 0x2534,
+ 0x92a9, 0x252a,
+ 0x92aa, 0x251f,
+ 0x92ab, 0x2531,
+ 0x92ac, 0x251c,
+ 0x92ad, 0x4ea3,
+ 0x92ae, 0x1d81,
+ 0x92af, 0x4ea4,
+ 0x92b1, 0x2525,
+ 0x92b2, 0x4ea6,
+ 0x92b7, 0x21cd,
+ 0x92b8, 0x4eab,
+ 0x92b9, 0x21da,
+ 0x92ba, 0x4eac,
+ 0x92bb, 0x2172,
+ 0x92bc, 0x253e,
+ 0x92bd, 0x4ead,
+ 0x92c1, 0x204f,
+ 0x92c2, 0x4eb1,
+ 0x92c3, 0x2543,
+ 0x92c4, 0x4eb2,
+ 0x92c5, 0x21d7,
+ 0x92c6, 0x4eb3,
+ 0x92c7, 0x1e3c,
+ 0x92c8, 0x1d82,
+ 0x92c9, 0x4eb4,
+ 0x92cc, 0x2529,
+ 0x92cd, 0x4eb7,
+ 0x92cf, 0x2521,
+ 0x92d0, 0x4eb9,
+ 0x92d2, 0x1eff,
+ 0x92d3, 0x4ebb,
+ 0x92dd, 0x253f,
+ 0x92de, 0x4ec5,
+ 0x92df, 0x2544,
+ 0x92e0, 0x4ec6,
+ 0x92e3, 0x2523,
+ 0x92e4, 0x1e90,
+ 0x92e5, 0x253a,
+ 0x92e6, 0x2545,
+ 0x92e7, 0x4ec9,
+ 0x92e8, 0x253d,
+ 0x92e9, 0x4eca,
+ 0x92ea, 0x20c1,
+ 0x92eb, 0x4ecb,
+ 0x92ed, 0x2103,
+ 0x92ee, 0x2520,
+ 0x92ef, 0x253c,
+ 0x92f0, 0x253b,
+ 0x92f1, 0x2538,
+ 0x92f2, 0x4ecd,
+ 0x92f6, 0x2540,
+ 0x92f7, 0x4ed1,
+ 0x92f8, 0x1fcd,
+ 0x92f9, 0x4ed2,
+ 0x92fc, 0x1f18,
+ 0x92fd, 0x4ed5,
+ 0x9300, 0x4ed8,
+ 0x9301, 0x254b,
+ 0x9302, 0x4ed9,
+ 0x9306, 0x2547,
+ 0x9307, 0x254f,
+ 0x9309, 0x4edd,
+ 0x9310, 0x22b0,
+ 0x9311, 0x4ee4,
+ 0x9312, 0x2546,
+ 0x9313, 0x4ee5,
+ 0x9315, 0x254c,
+ 0x9316, 0x4ee7,
+ 0x9318, 0x1e9a,
+ 0x9319, 0x2552,
+ 0x931a, 0x2530,
+ 0x931b, 0x2549,
+ 0x931c, 0x4ee9,
+ 0x931f, 0x2551,
+ 0x9320, 0x1eca,
+ 0x9321, 0x4eec,
+ 0x9322, 0x20d2,
+ 0x9323, 0x4eed,
+ 0x9326, 0x1fb8,
+ 0x9327, 0x4ef0,
+ 0x9328, 0x2079,
+ 0x9329, 0x4ef1,
+ 0x932b, 0x21ab,
+ 0x932c, 0x4ef3,
+ 0x932e, 0x254d,
+ 0x932f, 0x1ea5,
+ 0x9330, 0x4ef5,
+ 0x9332, 0x204c,
+ 0x9333, 0x2080,
+ 0x9334, 0x4ef7,
+ 0x9336, 0x266d,
+ 0x9337, 0x4ef9,
+ 0x9338, 0x2537,
+ 0x9339, 0x4efa,
+ 0x933e, 0x1d83,
+ 0x933f, 0x4eff,
+ 0x9340, 0x254a,
+ 0x9341, 0x21b8,
+ 0x9342, 0x4f00,
+ 0x9343, 0x254e,
+ 0x9344, 0x4f01,
+ 0x9346, 0x24fc,
+ 0x9347, 0x2554,
+ 0x9348, 0x4f03,
+ 0x934b, 0x1f3c,
+ 0x934c, 0x4f06,
+ 0x934d, 0x1ed5,
+ 0x934e, 0x4f07,
+ 0x9354, 0x2556,
+ 0x9355, 0x4f0d,
+ 0x9358, 0x2268,
+ 0x9359, 0x4f10,
+ 0x935b, 0x1ed6,
+ 0x935c, 0x4f12,
+ 0x9364, 0x2557,
+ 0x9365, 0x2553,
+ 0x9366, 0x4f1a,
+ 0x9369, 0x2548,
+ 0x936a, 0x1d84,
+ 0x936b, 0x4f1d,
+ 0x936c, 0x20dc,
+ 0x936d, 0x4f1e,
+ 0x9370, 0x2559,
+ 0x9371, 0x4f21,
+ 0x9375, 0x1f97,
+ 0x9376, 0x2555,
+ 0x9377, 0x4f25,
+ 0x937a, 0x227d,
+ 0x937b, 0x4f28,
+ 0x937e, 0x257e,
+ 0x937f, 0x4f2b,
+ 0x9382, 0x207c,
+ 0x9383, 0x4f2e,
+ 0x9384, 0x255a,
+ 0x9385, 0x4f2f,
+ 0x9387, 0x255e,
+ 0x9388, 0x4f31,
+ 0x938a, 0x1e34,
+ 0x938b, 0x4f33,
+ 0x938f, 0x1d86,
+ 0x9390, 0x4f37,
+ 0x9396, 0x215e,
+ 0x9397, 0x4f3d,
+ 0x9398, 0x2560,
+ 0x9399, 0x4f3e,
+ 0x93a2, 0x21a2,
+ 0x93a3, 0x2354,
+ 0x93a4, 0x4f47,
+ 0x93a6, 0x2563,
+ 0x93a7, 0x2527,
+ 0x93a8, 0x4f49,
+ 0x93a9, 0x252e,
+ 0x93aa, 0x2558,
+ 0x93ab, 0x4f4a,
+ 0x93ac, 0x1f1b,
+ 0x93ad, 0x4f4b,
+ 0x93ae, 0x2283,
+ 0x93af, 0x4f4c,
+ 0x93b0, 0x2564,
+ 0x93b1, 0x4f4d,
+ 0x93b3, 0x20a0,
+ 0x93b4, 0x4f4f,
+ 0x93b5, 0x2565,
+ 0x93b6, 0x4f50,
+ 0x93b8, 0x2561,
+ 0x93b9, 0x4f52,
+ 0x93bf, 0x2562,
+ 0x93c0, 0x4f58,
+ 0x93c3, 0x256c,
+ 0x93c4, 0x4f5b,
+ 0x93c7, 0x256d,
+ 0x93c8, 0x2020,
+ 0x93c9, 0x4f5e,
+ 0x93ca, 0x1d85,
+ 0x93cb, 0x4f5f,
+ 0x93cc, 0x255f,
+ 0x93cd, 0x256a,
+ 0x93ce, 0x4f60,
+ 0x93d1, 0x256e,
+ 0x93d2, 0x4f63,
+ 0x93d6, 0x1e01,
+ 0x93d7, 0x2539,
+ 0x93d8, 0x255c,
+ 0x93d9, 0x4f67,
+ 0x93dc, 0x2568,
+ 0x93de, 0x256b,
+ 0x93df, 0x1e6f,
+ 0x93e0, 0x4f6a,
+ 0x93e1, 0x1fc4,
+ 0x93e2, 0x2567,
+ 0x93e3, 0x4f6b,
+ 0x93e4, 0x255b,
+ 0x93e5, 0x4f6c,
+ 0x93e8, 0x261d,
+ 0x93e9, 0x4f6f,
+ 0x93f5, 0x252b,
+ 0x93f6, 0x4f7b,
+ 0x93f7, 0x2571,
+ 0x93f8, 0x4f7c,
+ 0x93f9, 0x2577,
+ 0x93fa, 0x4f7d,
+ 0x9400, 0x4f83,
+ 0x9403, 0x2522,
+ 0x9404, 0x4f86,
+ 0x940b, 0x2533,
+ 0x940c, 0x4f8d,
+ 0x9410, 0x202a,
+ 0x9411, 0x4f91,
+ 0x9412, 0x2536,
+ 0x9413, 0x2573,
+ 0x9414, 0x256f,
+ 0x9415, 0x4f92,
+ 0x9418, 0x2293,
+ 0x9419, 0x2578,
+ 0x941a, 0x4f95,
+ 0x941d, 0x2570,
+ 0x941e, 0x4f98,
+ 0x9420, 0x2575,
+ 0x9421, 0x4f9a,
+ 0x9426, 0x2541,
+ 0x9428, 0x255d,
+ 0x9429, 0x4f9f,
+ 0x942e, 0x201a,
+ 0x942f, 0x4fa4,
+ 0x9432, 0x257a,
+ 0x9433, 0x2006,
+ 0x9434, 0x4fa7,
+ 0x9435, 0x2177,
+ 0x9436, 0x4fa8,
+ 0x9438, 0x251b,
+ 0x9439, 0x4faa,
+ 0x943a, 0x2524,
+ 0x943b, 0x4fab,
+ 0x943e, 0x1d87,
+ 0x943f, 0x257b,
+ 0x9440, 0x4fae,
+ 0x9444, 0x22a3,
+ 0x9445, 0x4fb2,
+ 0x944a, 0x2579,
+ 0x944b, 0x4fb7,
+ 0x944c, 0x2566,
+ 0x944d, 0x4fb8,
+ 0x9452, 0x1f93,
+ 0x9453, 0x4fbd,
+ 0x9454, 0x257c,
+ 0x9455, 0x4fbe,
+ 0x9460, 0x2514,
+ 0x9461, 0x4fc9,
+ 0x9463, 0x257d,
+ 0x9464, 0x4fcb,
+ 0x9465, 0x2572,
+ 0x9466, 0x4fcc,
+ 0x946b, 0x1d88,
+ 0x946c, 0x4fd1,
+ 0x946d, 0x2574,
+ 0x946e, 0x4fd2,
+ 0x9470, 0x224e,
+ 0x9471, 0x4fd4,
+ 0x9472, 0x21c6,
+ 0x9473, 0x4fd5,
+ 0x9477, 0x209f,
+ 0x9478, 0x4fd9,
+ 0x9479, 0x2576,
+ 0x947a, 0x4fda,
+ 0x947c, 0x2064,
+ 0x947d, 0x22bf,
+ 0x947e, 0x261c,
+ 0x947f, 0x225e,
+ 0x9480, 0x4fdc,
+ 0x9485, 0x1a8e,
+ 0x9488, 0x118c,
+ 0x9489, 0x05e3,
+ 0x948a, 0x1a92,
+ 0x948b, 0x1a91,
+ 0x948c, 0x1a93,
+ 0x948e, 0x0c22,
+ 0x948f, 0x1a95,
+ 0x9491, 0x4fe1,
+ 0x9492, 0x064d,
+ 0x9493, 0x05d7,
+ 0x9494, 0x1a97,
+ 0x9495, 0x1a99,
+ 0x9496, 0x4fe2,
+ 0x9497, 0x1a98,
+ 0x9498, 0x4fe3,
+ 0x9499, 0x06c1,
+ 0x949a, 0x1a9a,
+ 0x949d, 0x061a,
+ 0x949e, 0x04d3,
+ 0x949f, 0x11d2,
+ 0x94a0, 0x0b29,
+ 0x94a1, 0x041e,
+ 0x94a2, 0x06d1,
+ 0x94a3, 0x1a9d,
+ 0x94a5, 0x1102,
+ 0x94a6, 0x0c52,
+ 0x94a7, 0x092a,
+ 0x94a8, 0x0ee8,
+ 0x94a9, 0x070c,
+ 0x94aa, 0x1aa0,
+ 0x94ab, 0x1a9f,
+ 0x94ac, 0x1aa2,
+ 0x94ad, 0x1aa1,
+ 0x94ae, 0x0b66,
+ 0x94af, 0x1aa3,
+ 0x94b1, 0x0c2b,
+ 0x94b2, 0x1aa5,
+ 0x94b3, 0x0c2c,
+ 0x94b4, 0x1aa6,
+ 0x94b5, 0x046e,
+ 0x94b6, 0x1aa7,
+ 0x94bb, 0x1247,
+ 0x94bc, 0x1aac,
+ 0x94be, 0x084b,
+ 0x94bf, 0x1aae,
+ 0x94c0, 0x10b0,
+ 0x94c1, 0x0e4d,
+ 0x94c2, 0x0473,
+ 0x94c3, 0x0a2e,
+ 0x94c4, 0x1aaf,
+ 0x94c5, 0x0c23,
+ 0x94c6, 0x0ab2,
+ 0x94c7, 0x4fe4,
+ 0x94c8, 0x1ab0,
+ 0x94cf, 0x4fe5,
+ 0x94d0, 0x1ab7,
+ 0x94d3, 0x4fe6,
+ 0x94d5, 0x1aba,
+ 0x94d8, 0x1abe,
+ 0x94d9, 0x1abd,
+ 0x94da, 0x4fe8,
+ 0x94db, 0x1abf,
+ 0x94dc, 0x0e5e,
+ 0x94dd, 0x0a68,
+ 0x94de, 0x1ac0,
+ 0x94e1, 0x1142,
+ 0x94e2, 0x1ac3,
+ 0x94e3, 0x0f20,
+ 0x94e4, 0x1ac4,
+ 0x94e6, 0x4fe9,
+ 0x94e7, 0x1ac6,
+ 0x94e9, 0x1ac9,
+ 0x94ea, 0x1ac8,
+ 0x94eb, 0x1aca,
+ 0x94ec, 0x06f0,
+ 0x94ed, 0x0aff,
+ 0x94ee, 0x1acb,
+ 0x94f0, 0x0893,
+ 0x94f1, 0x1046,
+ 0x94f2, 0x04c0,
+ 0x94f3, 0x1acd,
+ 0x94f6, 0x107f,
+ 0x94f7, 0x1ad0,
+ 0x94f8, 0x11fc,
+ 0x94f9, 0x1ad1,
+ 0x94fa, 0x0beb,
+ 0x94fb, 0x4fea,
+ 0x94fc, 0x1ad2,
+ 0x94fe, 0x09fd,
+ 0x94ff, 0x1ad4,
+ 0x9500, 0x0f67,
+ 0x9501, 0x0ded,
+ 0x9502, 0x1ad6,
+ 0x9503, 0x1ad5,
+ 0x9504, 0x051f,
+ 0x9505, 0x0751,
+ 0x9506, 0x1ad7,
+ 0x9508, 0x0fad,
+ 0x9509, 0x1ad9,
+ 0x950b, 0x0683,
+ 0x950c, 0x0f8a,
+ 0x950d, 0x1adb,
+ 0x9510, 0x0ccc,
+ 0x9511, 0x0e33,
+ 0x9512, 0x1ade,
+ 0x9517, 0x1181,
+ 0x9518, 0x1ae3,
+ 0x9519, 0x0570,
+ 0x951a, 0x0aaf,
+ 0x951b, 0x1ae4,
+ 0x951c, 0x4feb,
+ 0x951d, 0x1ae5,
+ 0x9520, 0x4fec,
+ 0x9521, 0x0f0c,
+ 0x9522, 0x1ae8,
+ 0x9523, 0x0a87,
+ 0x9524, 0x053b,
+ 0x9525, 0x1213,
+ 0x9526, 0x08c6,
+ 0x9527, 0x4fed,
+ 0x9528, 0x0f34,
+ 0x9529, 0x1aeb,
+ 0x952a, 0x1ae9,
+ 0x952c, 0x1aec,
+ 0x952d, 0x05e6,
+ 0x952e, 0x086f,
+ 0x952f, 0x0911,
+ 0x9530, 0x0ad1,
+ 0x9531, 0x1aed,
+ 0x9533, 0x4fee,
+ 0x9534, 0x1aef,
+ 0x9535, 0x1af7,
+ 0x9536, 0x1af0,
+ 0x9539, 0x0c3f,
+ 0x953a, 0x1b19,
+ 0x953b, 0x060c,
+ 0x953c, 0x1af3,
+ 0x953d, 0x4fef,
+ 0x953e, 0x1af4,
+ 0x9540, 0x0605,
+ 0x9541, 0x0ac3,
+ 0x9542, 0x1af6,
+ 0x9543, 0x4ff0,
+ 0x9544, 0x1af8,
+ 0x9547, 0x1193,
+ 0x9548, 0x4ff1,
+ 0x9549, 0x1afb,
+ 0x954a, 0x0b5a,
+ 0x954b, 0x4ff2,
+ 0x954c, 0x1afc,
+ 0x954d, 0x0b5b,
+ 0x954e, 0x1afd,
+ 0x9550, 0x06df,
+ 0x9551, 0x0402,
+ 0x9552, 0x1aff,
+ 0x9555, 0x4ff3,
+ 0x9556, 0x1b02,
+ 0x955a, 0x4ff4,
+ 0x955b, 0x1b06,
+ 0x955c, 0x08e4,
+ 0x955d, 0x1b09,
+ 0x955e, 0x1b07,
+ 0x9560, 0x4ff5,
+ 0x9561, 0x1b0a,
+ 0x9563, 0x0a16,
+ 0x9564, 0x1b0c,
+ 0x956d, 0x09c3,
+ 0x956e, 0x4ff6,
+ 0x956f, 0x1b15,
+ 0x9570, 0x09f6,
+ 0x9571, 0x1b16,
+ 0x9574, 0x4ff7,
+ 0x9576, 0x0f4f,
+ 0x9577, 0x1e75,
+ 0x9578, 0x4ff9,
+ 0x957f, 0x04c9,
+ 0x9580, 0x207d,
+ 0x9581, 0x5000,
+ 0x9582, 0x23bf,
+ 0x9583, 0x2113,
+ 0x9584, 0x5001,
+ 0x9586, 0x23c0,
+ 0x9587, 0x5003,
+ 0x9589, 0x1e45,
+ 0x958a, 0x5005,
+ 0x958b, 0x1fd8,
+ 0x958c, 0x23c4,
+ 0x958d, 0x5006,
+ 0x958e, 0x23c2,
+ 0x958f, 0x2104,
+ 0x9590, 0x5007,
+ 0x9591, 0x21bd,
+ 0x9592, 0x5008,
+ 0x9593, 0x1f87,
+ 0x9594, 0x23c3,
+ 0x9595, 0x5009,
+ 0x9598, 0x2269,
+ 0x9599, 0x500c,
+ 0x95a1, 0x1f43,
+ 0x95a2, 0x5014,
+ 0x95a3, 0x1f1e,
+ 0x95a4, 0x2679,
+ 0x95a5, 0x1eeb,
+ 0x95a6, 0x5015,
+ 0x95a8, 0x1f35,
+ 0x95a9, 0x208a,
+ 0x95aa, 0x5017,
+ 0x95ab, 0x23c7,
+ 0x95ac, 0x23c9,
+ 0x95ad, 0x23c6,
+ 0x95ae, 0x5018,
+ 0x95b2, 0x224f,
+ 0x95b3, 0x501c,
+ 0x95b6, 0x23cb,
+ 0x95b7, 0x501f,
+ 0x95b9, 0x21f3,
+ 0x95ba, 0x5021,
+ 0x95bb, 0x21f7,
+ 0x95bc, 0x23cf,
+ 0x95bd, 0x23ce,
+ 0x95be, 0x23ca,
+ 0x95bf, 0x23cd,
+ 0x95c0, 0x5022,
+ 0x95c3, 0x23d0,
+ 0x95c4, 0x5025,
+ 0x95c6, 0x266c,
+ 0x95c7, 0x5027,
+ 0x95c8, 0x23c1,
+ 0x95c9, 0x5028,
+ 0x95ca, 0x1fee,
+ 0x95cb, 0x23d1,
+ 0x95cc, 0x1ff8,
+ 0x95cd, 0x5029,
+ 0x95d0, 0x23d3,
+ 0x95d1, 0x502c,
+ 0x95d4, 0x23d2,
+ 0x95d5, 0x23d4,
+ 0x95d6, 0x1e98,
+ 0x95d7, 0x502f,
+ 0x95dc, 0x1f2c,
+ 0x95dd, 0x5034,
+ 0x95de, 0x23d5,
+ 0x95df, 0x5035,
+ 0x95e1, 0x1e71,
+ 0x95e2, 0x2691,
+ 0x95e3, 0x5037,
+ 0x95e5, 0x23c5,
+ 0x95e6, 0x5039,
+ 0x95e8, 0x0aca,
+ 0x95e9, 0x1685,
+ 0x95ea, 0x0cfa,
+ 0x95eb, 0x1686,
+ 0x95ec, 0x503b,
+ 0x95ed, 0x043e,
+ 0x95ee, 0x0ed9,
+ 0x95ef, 0x0536,
+ 0x95f0, 0x0ccd,
+ 0x95f1, 0x1687,
+ 0x95f2, 0x0f3d,
+ 0x95f3, 0x1688,
+ 0x95f4, 0x0857,
+ 0x95f5, 0x1689,
+ 0x95f7, 0x0acb,
+ 0x95f8, 0x1143,
+ 0x95f9, 0x0b39,
+ 0x95fa, 0x0744,
+ 0x95fb, 0x0ed4,
+ 0x95fc, 0x168b,
+ 0x95fd, 0x0afb,
+ 0x95fe, 0x168c,
+ 0x95ff, 0x503c,
+ 0x9600, 0x0644,
+ 0x9601, 0x06ee,
+ 0x9602, 0x0789,
+ 0x9603, 0x168d,
+ 0x9605, 0x1107,
+ 0x9606, 0x168f,
+ 0x9607, 0x503d,
+ 0x9608, 0x1690,
+ 0x9609, 0x0ff4,
+ 0x960a, 0x1691,
+ 0x960e, 0x0fff,
+ 0x960f, 0x1695,
+ 0x9610, 0x04c2,
+ 0x9611, 0x09a6,
+ 0x9612, 0x1696,
+ 0x9613, 0x503e,
+ 0x9614, 0x0996,
+ 0x9615, 0x1697,
+ 0x9618, 0x503f,
+ 0x9619, 0x169a,
+ 0x961b, 0x5040,
+ 0x961c, 0x06b2,
+ 0x961d, 0x1354,
+ 0x961e, 0x5041,
+ 0x961f, 0x0612,
+ 0x9620, 0x5042,
+ 0x9621, 0x1356,
+ 0x9622, 0x1355,
+ 0x9623, 0x5043,
+ 0x962a, 0x1358,
+ 0x962b, 0x504a,
+ 0x962e, 0x0cc9,
+ 0x962f, 0x504d,
+ 0x9631, 0x1357,
+ 0x9632, 0x065d,
+ 0x9633, 0x101d,
+ 0x9634, 0x107c,
+ 0x9635, 0x1194,
+ 0x9636, 0x08a8,
+ 0x9637, 0x504f,
+ 0x963b, 0x1245,
+ 0x963c, 0x135a,
+ 0x963d, 0x1359,
+ 0x963e, 0x5053,
+ 0x963f, 0x03ad,
+ 0x9640, 0x0e84,
+ 0x9641, 0x5054,
+ 0x9642, 0x135b,
+ 0x9643, 0x5055,
+ 0x9644, 0x06b8,
+ 0x9645, 0x083d,
+ 0x9646, 0x0a64,
+ 0x9647, 0x0a4b,
+ 0x9648, 0x04e7,
+ 0x9649, 0x135c,
+ 0x964a, 0x5056,
+ 0x964b, 0x0a51,
+ 0x964c, 0x0b13,
+ 0x964d, 0x0886,
+ 0x964e, 0x5057,
+ 0x9650, 0x0f4b,
+ 0x9651, 0x5059,
+ 0x9654, 0x135d,
+ 0x9655, 0x0cfb,
+ 0x9656, 0x505c,
+ 0x9658, 0x231a,
+ 0x9659, 0x505e,
+ 0x965b, 0x0446,
+ 0x965c, 0x5060,
+ 0x965d, 0x2114,
+ 0x965e, 0x5061,
+ 0x965f, 0x135e,
+ 0x9660, 0x5062,
+ 0x9661, 0x05f7,
+ 0x9662, 0x10fd,
+ 0x9663, 0x2284,
+ 0x9664, 0x0522,
+ 0x9665, 0x5063,
+ 0x9667, 0x135f,
+ 0x9668, 0x110c,
+ 0x9669, 0x0f42,
+ 0x966a, 0x0ba4,
+ 0x966b, 0x5065,
+ 0x966c, 0x1360,
+ 0x966d, 0x5066,
+ 0x9670, 0x221c,
+ 0x9671, 0x5069,
+ 0x9672, 0x1361,
+ 0x9673, 0x1e7e,
+ 0x9674, 0x1362,
+ 0x9675, 0x0a33,
+ 0x9676, 0x0e28,
+ 0x9677, 0x0f4a,
+ 0x9678, 0x204d,
+ 0x9679, 0x506a,
+ 0x967d, 0x2201,
+ 0x967e, 0x506e,
+ 0x9685, 0x10cc,
+ 0x9686, 0x0a48,
+ 0x9687, 0x5075,
+ 0x9688, 0x1363,
+ 0x9689, 0x5076,
+ 0x968a, 0x1ed9,
+ 0x968b, 0x0dda,
+ 0x968c, 0x5077,
+ 0x968d, 0x1364,
+ 0x968e, 0x1fb2,
+ 0x968f, 0x0ddb,
+ 0x9690, 0x1085,
+ 0x9691, 0x5078,
+ 0x9694, 0x06ef,
+ 0x9695, 0x2252,
+ 0x9696, 0x507b,
+ 0x9697, 0x1365,
+ 0x9698, 0x03ba,
+ 0x9699, 0x0f23,
+ 0x969a, 0x507c,
+ 0x969b, 0x1f79,
+ 0x969c, 0x1170,
+ 0x969d, 0x507d,
+ 0x96a7, 0x0de2,
+ 0x96a8, 0x2157,
+ 0x96a9, 0x5087,
+ 0x96aa, 0x21bf,
+ 0x96ab, 0x5088,
+ 0x96b0, 0x1366,
+ 0x96b1, 0x221f,
+ 0x96b2, 0x508d,
+ 0x96b3, 0x1684,
+ 0x96b4, 0x203d,
+ 0x96b5, 0x508e,
+ 0x96b6, 0x09ee,
+ 0x96b7, 0x508f,
+ 0x96b8, 0x2015,
+ 0x96b9, 0x1d79,
+ 0x96ba, 0x5090,
+ 0x96bb, 0x26a5,
+ 0x96bc, 0x1d7a,
+ 0x96be, 0x0b34,
+ 0x96bf, 0x5091,
+ 0x96c0, 0x0c93,
+ 0x96c1, 0x100c,
+ 0x96c2, 0x5092,
+ 0x96c4, 0x0fa6,
+ 0x96c5, 0x0fee,
+ 0x96c6, 0x0822,
+ 0x96c7, 0x0726,
+ 0x96c8, 0x5094,
+ 0x96c9, 0x1b1c,
+ 0x96ca, 0x5095,
+ 0x96cc, 0x0549,
+ 0x96cd, 0x109f,
+ 0x96ce, 0x1d7c,
+ 0x96cf, 0x0520,
+ 0x96d0, 0x5097,
+ 0x96d2, 0x1d7d,
+ 0x96d3, 0x5099,
+ 0x96d5, 0x05d2,
+ 0x96d6, 0x2156,
+ 0x96d7, 0x509b,
+ 0x96d9, 0x2144,
+ 0x96da, 0x509d,
+ 0x96db, 0x1e91,
+ 0x96dc, 0x2257,
+ 0x96dd, 0x509e,
+ 0x96e0, 0x1d7f,
+ 0x96e1, 0x50a1,
+ 0x96e2, 0x200a,
+ 0x96e3, 0x2092,
+ 0x96e4, 0x50a2,
+ 0x96e8, 0x10cf,
+ 0x96e9, 0x1d61,
+ 0x96ea, 0x0fd2,
+ 0x96eb, 0x50a6,
+ 0x96ef, 0x1d63,
+ 0x96f0, 0x50aa,
+ 0x96f2, 0x2250,
+ 0x96f3, 0x1d62,
+ 0x96f4, 0x50ac,
+ 0x96f6, 0x0a2c,
+ 0x96f7, 0x09c2,
+ 0x96f8, 0x50ae,
+ 0x96f9, 0x040b,
+ 0x96fa, 0x50af,
+ 0x96fb, 0x1ec3,
+ 0x96fc, 0x50b0,
+ 0x96fe, 0x0efc,
+ 0x96ff, 0x50b2,
+ 0x9700, 0x0fb3,
+ 0x9701, 0x1d65,
+ 0x9702, 0x50b3,
+ 0x9704, 0x0f63,
+ 0x9705, 0x50b5,
+ 0x9706, 0x1d64,
+ 0x9707, 0x1191,
+ 0x9708, 0x1d66,
+ 0x9709, 0x0abe,
+ 0x970a, 0x50b6,
+ 0x970d, 0x0809,
+ 0x970e, 0x1d68,
+ 0x970f, 0x1d67,
+ 0x9710, 0x50b9,
+ 0x9713, 0x0b41,
+ 0x9714, 0x50bc,
+ 0x9716, 0x0a21,
+ 0x9717, 0x50be,
+ 0x971c, 0x0d9f,
+ 0x971d, 0x50c3,
+ 0x971e, 0x0f29,
+ 0x971f, 0x50c4,
+ 0x9727, 0x21a8,
+ 0x9728, 0x50cc,
+ 0x972a, 0x1d69,
+ 0x972b, 0x50ce,
+ 0x972d, 0x1d6a,
+ 0x972e, 0x50d0,
+ 0x9730, 0x1d6b,
+ 0x9731, 0x50d2,
+ 0x9732, 0x0a5d,
+ 0x9733, 0x50d3,
+ 0x9738, 0x03df,
+ 0x9739, 0x0bba,
+ 0x973a, 0x50d8,
+ 0x973d, 0x260d,
+ 0x973e, 0x1d6c,
+ 0x973f, 0x50db,
+ 0x9742, 0x260c,
+ 0x9743, 0x50de,
+ 0x9744, 0x260e,
+ 0x9745, 0x50df,
+ 0x9748, 0x2032,
+ 0x9749, 0x50e2,
+ 0x9752, 0x0c5d,
+ 0x9753, 0x1d60,
+ 0x9754, 0x50eb,
+ 0x9756, 0x08e7,
+ 0x9757, 0x50ed,
+ 0x9759, 0x08e1,
+ 0x975a, 0x260b,
+ 0x975b, 0x05c6,
+ 0x975c, 0x50ef,
+ 0x975e, 0x0664,
+ 0x975f, 0x50f1,
+ 0x9760, 0x094c,
+ 0x9761, 0x0ad7,
+ 0x9762, 0x0aeb,
+ 0x9763, 0x50f2,
+ 0x9765, 0x1282,
+ 0x9766, 0x50f4,
+ 0x9768, 0x22c3,
+ 0x9769, 0x06ea,
+ 0x976a, 0x50f6,
+ 0x9773, 0x08ca,
+ 0x9774, 0x0fce,
+ 0x9775, 0x50ff,
+ 0x9776, 0x03db,
+ 0x9777, 0x5100,
+ 0x977c, 0x1dc8,
+ 0x977d, 0x5105,
+ 0x9785, 0x1dc9,
+ 0x9786, 0x510d,
+ 0x978b, 0x0f77,
+ 0x978c, 0x5112,
+ 0x978d, 0x03bb,
+ 0x978e, 0x5113,
+ 0x978f, 0x1f23,
+ 0x9790, 0x5114,
+ 0x9791, 0x1dca,
+ 0x9793, 0x5115,
+ 0x9794, 0x1dcc,
+ 0x9795, 0x5116,
+ 0x9798, 0x0c47,
+ 0x9799, 0x5119,
+ 0x97a0, 0x08fe,
+ 0x97a1, 0x5120,
+ 0x97a3, 0x1dcf,
+ 0x97a4, 0x5122,
+ 0x97a6, 0x2695,
+ 0x97a7, 0x5124,
+ 0x97ab, 0x1dce,
+ 0x97ac, 0x5128,
+ 0x97ad, 0x0447,
+ 0x97ae, 0x5129,
+ 0x97af, 0x1dcd,
+ 0x97b0, 0x512a,
+ 0x97b2, 0x1dd0,
+ 0x97b3, 0x512c,
+ 0x97b4, 0x1dd1,
+ 0x97b5, 0x512d,
+ 0x97bd, 0x265e,
+ 0x97be, 0x5135,
+ 0x97c3, 0x265d,
+ 0x97c4, 0x513a,
+ 0x97c6, 0x2692,
+ 0x97c7, 0x513c,
+ 0x97c9, 0x265f,
+ 0x97ca, 0x513e,
+ 0x97cb, 0x218d,
+ 0x97cc, 0x20fd,
+ 0x97cd, 0x513f,
+ 0x97d3, 0x1f40,
+ 0x97d4, 0x5145,
+ 0x97d9, 0x2465,
+ 0x97da, 0x514a,
+ 0x97dc, 0x2467,
+ 0x97dd, 0x514c,
+ 0x97de, 0x2466,
+ 0x97df, 0x514d,
+ 0x97e6, 0x0eb3,
+ 0x97e7, 0x0ca8,
+ 0x97e8, 0x5154,
+ 0x97e9, 0x0762,
+ 0x97ea, 0x184e,
+ 0x97ed, 0x08f1,
+ 0x97ee, 0x5155,
+ 0x97f3, 0x107b,
+ 0x97f4, 0x515a,
+ 0x97f5, 0x1112,
+ 0x97f6, 0x0d11,
+ 0x97f7, 0x515b,
+ 0x97ff, 0x21c9,
+ 0x9800, 0x5163,
+ 0x9801, 0x2209,
+ 0x9802, 0x1ec9,
+ 0x9803, 0x20e9,
+ 0x9804, 0x5164,
+ 0x9805, 0x21ca,
+ 0x9806, 0x2146,
+ 0x9807, 0x25c5,
+ 0x9808, 0x21dc,
+ 0x9809, 0x5165,
+ 0x980a, 0x245e,
+ 0x980b, 0x5166,
+ 0x980c, 0x214f,
+ 0x980d, 0x5167,
+ 0x980e, 0x25c6,
+ 0x9810, 0x2241,
+ 0x9811, 0x218a,
+ 0x9812, 0x1e2f,
+ 0x9813, 0x1edc,
+ 0x9814, 0x5168,
+ 0x9817, 0x20bf,
+ 0x9818, 0x2034,
+ 0x9819, 0x516b,
+ 0x981c, 0x25c9,
+ 0x981d, 0x516e,
+ 0x9821, 0x25c8,
+ 0x9822, 0x5172,
+ 0x9824, 0x220e,
+ 0x9825, 0x5174,
+ 0x9826, 0x25cb,
+ 0x9827, 0x5175,
+ 0x982d, 0x217d,
+ 0x982e, 0x517b,
+ 0x9830, 0x1f7e,
+ 0x9831, 0x517d,
+ 0x9837, 0x25cc,
+ 0x9838, 0x1fc3,
+ 0x9839, 0x5183,
+ 0x983b, 0x20b9,
+ 0x983c, 0x5185,
+ 0x983d, 0x2181,
+ 0x983e, 0x5186,
+ 0x9846, 0x1fda,
+ 0x9847, 0x518e,
+ 0x984c, 0x2173,
+ 0x984d, 0x1ee1,
+ 0x984e, 0x25cd,
+ 0x984f, 0x5193,
+ 0x9853, 0x25ce,
+ 0x9854, 0x21f6,
+ 0x9855, 0x5197,
+ 0x9858, 0x224b,
+ 0x9859, 0x25d1,
+ 0x985a, 0x519a,
+ 0x985b, 0x1ec0,
+ 0x985c, 0x519b,
+ 0x985e, 0x2008,
+ 0x985f, 0x519d,
+ 0x9862, 0x25d0,
+ 0x9863, 0x51a0,
+ 0x9865, 0x25d2,
+ 0x9866, 0x51a2,
+ 0x9867, 0x1f2a,
+ 0x9868, 0x51a3,
+ 0x986b, 0x1e72,
+ 0x986c, 0x25d3,
+ 0x986d, 0x51a6,
+ 0x986f, 0x21be,
+ 0x9870, 0x25d4,
+ 0x9871, 0x2044,
+ 0x9872, 0x51a8,
+ 0x9873, 0x25cf,
+ 0x9874, 0x20f3,
+ 0x9875, 0x103a,
+ 0x9876, 0x05e4,
+ 0x9877, 0x0c67,
+ 0x9878, 0x1be0,
+ 0x9879, 0x0f5b,
+ 0x987a, 0x0da8,
+ 0x987b, 0x0fb6,
+ 0x987c, 0x1827,
+ 0x987d, 0x0e98,
+ 0x987e, 0x0724,
+ 0x987f, 0x0618,
+ 0x9880, 0x1be1,
+ 0x9881, 0x03ef,
+ 0x9882, 0x0dc1,
+ 0x9883, 0x1be2,
+ 0x9884, 0x10e7,
+ 0x9885, 0x0a54,
+ 0x9886, 0x0a35,
+ 0x9887, 0x0be3,
+ 0x9888, 0x08e0,
+ 0x9889, 0x1be3,
+ 0x988a, 0x0848,
+ 0x988b, 0x51a9,
+ 0x988c, 0x1be4,
+ 0x988e, 0x51aa,
+ 0x988f, 0x1be6,
+ 0x9890, 0x104a,
+ 0x9891, 0x0bd4,
+ 0x9892, 0x51ab,
+ 0x9893, 0x0e78,
+ 0x9894, 0x1be7,
+ 0x9895, 0x51ac,
+ 0x9896, 0x1096,
+ 0x9897, 0x0952,
+ 0x9898, 0x0e35,
+ 0x9899, 0x51ad,
+ 0x989a, 0x1be8,
+ 0x989c, 0x0ffe,
+ 0x989d, 0x062d,
+ 0x989e, 0x1bea,
+ 0x98a0, 0x05c0,
+ 0x98a1, 0x1bec,
+ 0x98a3, 0x51ae,
+ 0x98a4, 0x04c3,
+ 0x98a5, 0x1bee,
+ 0x98a7, 0x0c82,
+ 0x98a8, 0x1f00,
+ 0x98a9, 0x51af,
+ 0x98ae, 0x24cc,
+ 0x98b0, 0x51b4,
+ 0x98b1, 0x2698,
+ 0x98b2, 0x51b5,
+ 0x98b3, 0x2678,
+ 0x98b4, 0x51b6,
+ 0x98b6, 0x24ce,
+ 0x98b7, 0x51b8,
+ 0x98bc, 0x24cf,
+ 0x98bd, 0x51bd,
+ 0x98c4, 0x20b8,
+ 0x98c5, 0x51c4,
+ 0x98c6, 0x24d0,
+ 0x98c7, 0x51c5,
+ 0x98c8, 0x24d1,
+ 0x98c9, 0x51c6,
+ 0x98ce, 0x0684,
+ 0x98cf, 0x51cb,
+ 0x98d1, 0x19b7,
+ 0x98d4, 0x51cd,
+ 0x98d5, 0x19ba,
+ 0x98d6, 0x51ce,
+ 0x98d8, 0x0bcd,
+ 0x98d9, 0x19bb,
+ 0x98db, 0x1ef4,
+ 0x98dc, 0x51d0,
+ 0x98de, 0x0666,
+ 0x98df, 0x0d4a,
+ 0x98e0, 0x239b,
+ 0x98e1, 0x51d2,
+ 0x98e2, 0x267e,
+ 0x98e3, 0x51d3,
+ 0x98e7, 0x161a,
+ 0x98e8, 0x1de7,
+ 0x98e9, 0x239d,
+ 0x98ea, 0x239f,
+ 0x98ec, 0x51d7,
+ 0x98ed, 0x23a1,
+ 0x98ee, 0x51d8,
+ 0x98ef, 0x1ef1,
+ 0x98f0, 0x51d9,
+ 0x98f2, 0x221e,
+ 0x98f3, 0x51db,
+ 0x98f4, 0x23a2,
+ 0x98f5, 0x51dc,
+ 0x98fc, 0x214b,
+ 0x98fd, 0x1e36,
+ 0x98fe, 0x2135,
+ 0x98ff, 0x51e3,
+ 0x9900, 0x51e4,
+ 0x9903, 0x1fad,
+ 0x9904, 0x51e7,
+ 0x9905, 0x1e53,
+ 0x9906, 0x51e8,
+ 0x9909, 0x23a3,
+ 0x990a, 0x2203,
+ 0x990b, 0x51eb,
+ 0x990c, 0x1ee7,
+ 0x990d, 0x1de8,
+ 0x990e, 0x51ec,
+ 0x9910, 0x0494,
+ 0x9911, 0x23a4,
+ 0x9912, 0x2097,
+ 0x9913, 0x1ee4,
+ 0x9914, 0x51ee,
+ 0x9918, 0x2238,
+ 0x9919, 0x51f2,
+ 0x991b, 0x23a5,
+ 0x991c, 0x51f4,
+ 0x991e, 0x1f9a,
+ 0x991f, 0x51f6,
+ 0x9921, 0x21c3,
+ 0x9922, 0x51f8,
+ 0x9928, 0x1f2e,
+ 0x9929, 0x51fe,
+ 0x992e, 0x1de9,
+ 0x992f, 0x5203,
+ 0x9933, 0x239c,
+ 0x9934, 0x5207,
+ 0x9937, 0x23a6,
+ 0x9938, 0x520a,
+ 0x993c, 0x239e,
+ 0x993d, 0x520e,
+ 0x993e, 0x2035,
+ 0x993f, 0x23a7,
+ 0x9940, 0x520f,
+ 0x9943, 0x23a8,
+ 0x9944, 0x5212,
+ 0x9945, 0x2075,
+ 0x9946, 0x5213,
+ 0x9948, 0x23a9,
+ 0x994b, 0x1feb,
+ 0x994c, 0x23ac,
+ 0x994d, 0x5215,
+ 0x9951, 0x1f6a,
+ 0x9952, 0x20f9,
+ 0x9953, 0x5219,
+ 0x9954, 0x1deb,
+ 0x9955, 0x1dea,
+ 0x9956, 0x521a,
+ 0x9957, 0x2666,
+ 0x9958, 0x521b,
+ 0x995c, 0x2667,
+ 0x995d, 0x521f,
+ 0x995e, 0x1e6c,
+ 0x995f, 0x5220,
+ 0x9962, 0x23ad,
+ 0x9963, 0x161d,
+ 0x9964, 0x5223,
+ 0x9965, 0x0815,
+ 0x9966, 0x5224,
+ 0x9967, 0x161e,
+ 0x996d, 0x0656,
+ 0x996e, 0x1082,
+ 0x996f, 0x0875,
+ 0x9970, 0x0d65,
+ 0x9971, 0x040e,
+ 0x9972, 0x0dbc,
+ 0x9973, 0x5225,
+ 0x9974, 0x1624,
+ 0x9975, 0x063b,
+ 0x9976, 0x0c9f,
+ 0x9977, 0x1625,
+ 0x9978, 0x5226,
+ 0x997a, 0x0899,
+ 0x997b, 0x5228,
+ 0x997c, 0x0466,
+ 0x997d, 0x1626,
+ 0x997e, 0x5229,
+ 0x997f, 0x0635,
+ 0x9980, 0x1627,
+ 0x9981, 0x0b3c,
+ 0x9982, 0x522a,
+ 0x9984, 0x1628,
+ 0x9985, 0x0f47,
+ 0x9986, 0x0736,
+ 0x9987, 0x1629,
+ 0x9988, 0x098c,
+ 0x9989, 0x522c,
+ 0x998a, 0x162a,
+ 0x998b, 0x04bd,
+ 0x998c, 0x522d,
+ 0x998d, 0x162b,
+ 0x998e, 0x522e,
+ 0x998f, 0x0a3c,
+ 0x9990, 0x162c,
+ 0x9992, 0x0a9f,
+ 0x9993, 0x162e,
+ 0x9996, 0x0d6e,
+ 0x9997, 0x126e,
+ 0x9998, 0x12f9,
+ 0x9999, 0x0f50,
+ 0x999a, 0x522f,
+ 0x99a5, 0x1b2b,
+ 0x99a6, 0x523a,
+ 0x99a8, 0x13de,
+ 0x99a9, 0x523c,
+ 0x99ac, 0x206d,
+ 0x99ad, 0x2242,
+ 0x99ae, 0x1f02,
+ 0x99af, 0x523f,
+ 0x99b1, 0x2183,
+ 0x99b2, 0x5241,
+ 0x99b3, 0x1e85,
+ 0x99b4, 0x21e9,
+ 0x99b5, 0x5242,
+ 0x99c1, 0x1e57,
+ 0x99c2, 0x524e,
+ 0x99d0, 0x22a5,
+ 0x99d1, 0x2407,
+ 0x99d2, 0x1fca,
+ 0x99d3, 0x525c,
+ 0x99d4, 0x2402,
+ 0x99d5, 0x1f82,
+ 0x99d6, 0x525d,
+ 0x99d8, 0x2408,
+ 0x99d9, 0x2404,
+ 0x99da, 0x525f,
+ 0x99db, 0x2131,
+ 0x99dc, 0x5260,
+ 0x99dd, 0x2184,
+ 0x99de, 0x5261,
+ 0x99df, 0x2403,
+ 0x99e0, 0x5262,
+ 0x99e1, 0x206e,
+ 0x99e2, 0x240b,
+ 0x99e3, 0x5263,
+ 0x99ed, 0x1f3f,
+ 0x99ee, 0x526d,
+ 0x99f1, 0x2067,
+ 0x99f2, 0x5270,
+ 0x99ff, 0x1fd7,
+ 0x9a00, 0x527d,
+ 0x9a01, 0x1e83,
+ 0x9a02, 0x527e,
+ 0x9a05, 0x240f,
+ 0x9a06, 0x5281,
+ 0x9a0d, 0x240e,
+ 0x9a0e, 0x20c7,
+ 0x9a0f, 0x240d,
+ 0x9a10, 0x5288,
+ 0x9a16, 0x2412,
+ 0x9a17, 0x528e,
+ 0x9a19, 0x20b7,
+ 0x9a1a, 0x5290,
+ 0x9a2b, 0x23f0,
+ 0x9a2c, 0x52a1,
+ 0x9a2d, 0x2411,
+ 0x9a2e, 0x2414,
+ 0x9a2f, 0x52a2,
+ 0x9a30, 0x2170,
+ 0x9a31, 0x52a3,
+ 0x9a36, 0x2405,
+ 0x9a37, 0x210c,
+ 0x9a38, 0x2415,
+ 0x9a39, 0x52a8,
+ 0x9a3e, 0x2066,
+ 0x9a3f, 0x52ad,
+ 0x9a40, 0x2352,
+ 0x9a41, 0x2413,
+ 0x9a42, 0x2410,
+ 0x9a43, 0x2416,
+ 0x9a45, 0x20f1,
+ 0x9a46, 0x52ae,
+ 0x9a4a, 0x240a,
+ 0x9a4b, 0x52b2,
+ 0x9a4d, 0x2409,
+ 0x9a4e, 0x52b4,
+ 0x9a4f, 0x2418,
+ 0x9a50, 0x52b5,
+ 0x9a55, 0x1fa7,
+ 0x9a56, 0x52ba,
+ 0x9a57, 0x21fc,
+ 0x9a58, 0x52bb,
+ 0x9a5a, 0x1fc1,
+ 0x9a5b, 0x2406,
+ 0x9a5c, 0x52bd,
+ 0x9a5f, 0x229c,
+ 0x9a60, 0x52c0,
+ 0x9a62, 0x204e,
+ 0x9a63, 0x52c2,
+ 0x9a64, 0x241a,
+ 0x9a65, 0x2419,
+ 0x9a66, 0x52c3,
+ 0x9a6a, 0x240c,
+ 0x9a6b, 0x52c7,
+ 0x9a6c, 0x0a94,
+ 0x9a6d, 0x10e9,
+ 0x9a6e, 0x0e85,
+ 0x9a6f, 0x0fda,
+ 0x9a70, 0x0500,
+ 0x9a71, 0x0c7a,
+ 0x9a72, 0x52c8,
+ 0x9a73, 0x047c,
+ 0x9a74, 0x0a66,
+ 0x9a75, 0x17ba,
+ 0x9a76, 0x0d52,
+ 0x9a77, 0x17bb,
+ 0x9a79, 0x0903,
+ 0x9a7a, 0x17bd,
+ 0x9a7b, 0x1201,
+ 0x9a7c, 0x0e86,
+ 0x9a7d, 0x17bf,
+ 0x9a7e, 0x0850,
+ 0x9a7f, 0x17be,
+ 0x9a80, 0x17c0,
+ 0x9a82, 0x0a95,
+ 0x9a83, 0x52c9,
+ 0x9a84, 0x088f,
+ 0x9a85, 0x17c2,
+ 0x9a86, 0x0a8d,
+ 0x9a87, 0x075e,
+ 0x9a88, 0x17c3,
+ 0x9a89, 0x52ca,
+ 0x9a8a, 0x17c4,
+ 0x9a8b, 0x04f7,
+ 0x9a8c, 0x1012,
+ 0x9a8d, 0x52cb,
+ 0x9a8f, 0x0932,
+ 0x9a90, 0x17c5,
+ 0x9a91, 0x0c0e,
+ 0x9a92, 0x17c6,
+ 0x9a94, 0x52cd,
+ 0x9a96, 0x17c8,
+ 0x9a97, 0x0bcc,
+ 0x9a98, 0x17c9,
+ 0x9a99, 0x52cf,
+ 0x9a9a, 0x0ce0,
+ 0x9a9b, 0x17ca,
+ 0x9a9e, 0x1735,
+ 0x9a9f, 0x17cd,
+ 0x9aa1, 0x0a89,
+ 0x9aa2, 0x17cf,
+ 0x9aa4, 0x11e7,
+ 0x9aa5, 0x17d1,
+ 0x9aa6, 0x52d0,
+ 0x9aa7, 0x17d2,
+ 0x9aa8, 0x0720,
+ 0x9aa9, 0x52d1,
+ 0x9aaf, 0x1e29,
+ 0x9ab0, 0x1dd3,
+ 0x9ab1, 0x1dd2,
+ 0x9ab2, 0x52d7,
+ 0x9ab6, 0x1dd6,
+ 0x9ab7, 0x1dd4,
+ 0x9ab8, 0x0758,
+ 0x9ab9, 0x52db,
+ 0x9aba, 0x1dd7,
+ 0x9abb, 0x52dc,
+ 0x9abc, 0x1dd8,
+ 0x9abd, 0x52dd,
+ 0x9ac0, 0x1dda,
+ 0x9ac1, 0x1dd9,
+ 0x9ac2, 0x1ddc,
+ 0x9ac3, 0x52e0,
+ 0x9ac5, 0x1ddb,
+ 0x9ac6, 0x52e2,
+ 0x9acb, 0x1ddd,
+ 0x9acd, 0x52e7,
+ 0x9acf, 0x2661,
+ 0x9ad0, 0x52e9,
+ 0x9ad1, 0x1ddf,
+ 0x9ad2, 0x26a4,
+ 0x9ad3, 0x0ddd,
+ 0x9ad4, 0x2174,
+ 0x9ad5, 0x2663,
+ 0x9ad6, 0x2662,
+ 0x9ad7, 0x52ea,
+ 0x9ad8, 0x06da,
+ 0x9ad9, 0x52eb,
+ 0x9adf, 0x1dec,
+ 0x9ae0, 0x52f1,
+ 0x9ae1, 0x1ded,
+ 0x9ae2, 0x52f2,
+ 0x9ae6, 0x1dee,
+ 0x9ae7, 0x52f6,
+ 0x9aeb, 0x1df0,
+ 0x9aec, 0x52fa,
+ 0x9aed, 0x1df2,
+ 0x9aee, 0x2675,
+ 0x9aef, 0x1def,
+ 0x9af0, 0x52fb,
+ 0x9af9, 0x1df3,
+ 0x9afa, 0x5304,
+ 0x9afb, 0x1df1,
+ 0x9afc, 0x5305,
+ 0x9b00, 0x5309,
+ 0x9b03, 0x1234,
+ 0x9b04, 0x530c,
+ 0x9b06, 0x214c,
+ 0x9b07, 0x530e,
+ 0x9b08, 0x1df4,
+ 0x9b09, 0x530f,
+ 0x9b0d, 0x267a,
+ 0x9b0e, 0x5313,
+ 0x9b0f, 0x1df5,
+ 0x9b10, 0x5314,
+ 0x9b13, 0x1df6,
+ 0x9b14, 0x5317,
+ 0x9b1a, 0x26a0,
+ 0x9b1b, 0x531d,
+ 0x9b1f, 0x1df7,
+ 0x9b20, 0x5321,
+ 0x9b22, 0x2668,
+ 0x9b23, 0x1df8,
+ 0x9b24, 0x5323,
+ 0x9b25, 0x1ed0,
+ 0x9b26, 0x5324,
+ 0x9b27, 0x2096,
+ 0x9b28, 0x5325,
+ 0x9b29, 0x23cc,
+ 0x9b2a, 0x5326,
+ 0x9b2e, 0x23c8,
+ 0x9b2f, 0x139b,
+ 0x9b30, 0x532a,
+ 0x9b31, 0x223e,
+ 0x9b32, 0x1260,
+ 0x9b33, 0x532b,
+ 0x9b3b, 0x1773,
+ 0x9b3c, 0x0746,
+ 0x9b3d, 0x5333,
+ 0x9b41, 0x098a,
+ 0x9b42, 0x07ff,
+ 0x9b43, 0x1de1,
+ 0x9b44, 0x0be6,
+ 0x9b45, 0x1de0,
+ 0x9b46, 0x5337,
+ 0x9b47, 0x1de2,
+ 0x9b48, 0x1de4,
+ 0x9b49, 0x1de3,
+ 0x9b4a, 0x5338,
+ 0x9b4d, 0x1de5,
+ 0x9b4e, 0x2665,
+ 0x9b4f, 0x0ec9,
+ 0x9b50, 0x533b,
+ 0x9b51, 0x1de6,
+ 0x9b52, 0x533c,
+ 0x9b54, 0x0b0a,
+ 0x9b55, 0x533e,
+ 0x9b58, 0x2664,
+ 0x9b59, 0x5341,
+ 0x9b5a, 0x2239,
+ 0x9b5b, 0x5342,
+ 0x9b6f, 0x204a,
+ 0x9b70, 0x5356,
+ 0x9b74, 0x261f,
+ 0x9b75, 0x535a,
+ 0x9b77, 0x261e,
+ 0x9b78, 0x535c,
+ 0x9b81, 0x2620,
+ 0x9b82, 0x5365,
+ 0x9b83, 0x2621,
+ 0x9b84, 0x5366,
+ 0x9b8e, 0x2622,
+ 0x9b8f, 0x5370,
+ 0x9b90, 0x2627,
+ 0x9b91, 0x1e39,
+ 0x9b92, 0x2625,
+ 0x9b93, 0x5371,
+ 0x9b9a, 0x2629,
+ 0x9b9b, 0x5378,
+ 0x9b9d, 0x262e,
+ 0x9b9e, 0x262b,
+ 0x9b9f, 0x537a,
+ 0x9baa, 0x262a,
+ 0x9bab, 0x262d,
+ 0x9bac, 0x5385,
+ 0x9bad, 0x2628,
+ 0x9bae, 0x21b9,
+ 0x9baf, 0x5386,
+ 0x9bc0, 0x2636,
+ 0x9bc1, 0x2630,
+ 0x9bc2, 0x5397,
+ 0x9bc7, 0x2638,
+ 0x9bc8, 0x539c,
+ 0x9bc9, 0x200d,
+ 0x9bca, 0x2637,
+ 0x9bcb, 0x539d,
+ 0x9bd4, 0x2645,
+ 0x9bd5, 0x53a6,
+ 0x9bd6, 0x263a,
+ 0x9bd7, 0x53a7,
+ 0x9bdb, 0x2643,
+ 0x9bdc, 0x53ab,
+ 0x9bdd, 0x2640,
+ 0x9bde, 0x53ac,
+ 0x9be1, 0x263d,
+ 0x9be2, 0x2641,
+ 0x9be3, 0x53af,
+ 0x9be4, 0x263e,
+ 0x9be5, 0x53b0,
+ 0x9be7, 0x263f,
+ 0x9be8, 0x1fc0,
+ 0x9be9, 0x53b2,
+ 0x9bea, 0x263b,
+ 0x9bec, 0x53b3,
+ 0x9bf0, 0x2642,
+ 0x9bf1, 0x53b7,
+ 0x9bf4, 0x2644,
+ 0x9bf5, 0x53ba,
+ 0x9bfd, 0x2639,
+ 0x9bfe, 0x53c2,
+ 0x9bff, 0x264c,
+ 0x9c00, 0x53c3,
+ 0x9c08, 0x2647,
+ 0x9c09, 0x264b,
+ 0x9c0a, 0x53cb,
+ 0x9c0d, 0x2649,
+ 0x9c0e, 0x53ce,
+ 0x9c10, 0x2648,
+ 0x9c11, 0x53d0,
+ 0x9c12, 0x264a,
+ 0x9c13, 0x2108,
+ 0x9c14, 0x53d1,
+ 0x9c20, 0x264d,
+ 0x9c21, 0x53dd,
+ 0x9c23, 0x2634,
+ 0x9c24, 0x53df,
+ 0x9c25, 0x2651,
+ 0x9c26, 0x53e0,
+ 0x9c28, 0x2650,
+ 0x9c29, 0x2652,
+ 0x9c2a, 0x53e2,
+ 0x9c2d, 0x264f,
+ 0x9c2e, 0x53e5,
+ 0x9c31, 0x2632,
+ 0x9c32, 0x264e,
+ 0x9c33, 0x2653,
+ 0x9c34, 0x53e8,
+ 0x9c35, 0x2657,
+ 0x9c36, 0x53e9,
+ 0x9c37, 0x2635,
+ 0x9c38, 0x53ea,
+ 0x9c39, 0x2633,
+ 0x9c3a, 0x53eb,
+ 0x9c3b, 0x2656,
+ 0x9c3c, 0x53ec,
+ 0x9c3e, 0x2654,
+ 0x9c3f, 0x53ee,
+ 0x9c45, 0x2658,
+ 0x9c46, 0x53f4,
+ 0x9c48, 0x2655,
+ 0x9c49, 0x1e4d,
+ 0x9c4a, 0x53f6,
+ 0x9c52, 0x265b,
+ 0x9c53, 0x53fe,
+ 0x9c54, 0x265a,
+ 0x9c55, 0x53ff,
+ 0x9c56, 0x2659,
+ 0x9c57, 0x202e,
+ 0x9c58, 0x262f,
+ 0x9c59, 0x5400,
+ 0x9c5d, 0x2646,
+ 0x9c5e, 0x5404,
+ 0x9c5f, 0x2626,
+ 0x9c60, 0x5405,
+ 0x9c67, 0x265c,
+ 0x9c68, 0x540c,
+ 0x9c6d, 0x262c,
+ 0x9c6e, 0x5411,
+ 0x9c78, 0x2623,
+ 0x9c79, 0x541b,
+ 0x9c7a, 0x2631,
+ 0x9c7b, 0x541c,
+ 0x9c7c, 0x10c8,
+ 0x9c7d, 0x541d,
+ 0x9c7f, 0x1d89,
+ 0x9c80, 0x541f,
+ 0x9c81, 0x0a5a,
+ 0x9c82, 0x1d8a,
+ 0x9c83, 0x5420,
+ 0x9c85, 0x1d8b,
+ 0x9c89, 0x5422,
+ 0x9c8b, 0x1d90,
+ 0x9c8c, 0x5424,
+ 0x9c8d, 0x0414,
+ 0x9c8e, 0x1d91,
+ 0x9c8f, 0x5425,
+ 0x9c90, 0x1d92,
+ 0x9c93, 0x5426,
+ 0x9c94, 0x1d95,
+ 0x9c96, 0x5427,
+ 0x9c9a, 0x1d97,
+ 0x9c9c, 0x0f37,
+ 0x9c9d, 0x542b,
+ 0x9c9e, 0x1d99,
+ 0x9ca4, 0x09db,
+ 0x9ca5, 0x1d9f,
+ 0x9caa, 0x542c,
+ 0x9cab, 0x1da4,
+ 0x9cac, 0x542d,
+ 0x9cad, 0x1da5,
+ 0x9caf, 0x542e,
+ 0x9cb0, 0x1da7,
+ 0x9cb8, 0x08d7,
+ 0x9cb9, 0x542f,
+ 0x9cba, 0x1daf,
+ 0x9cbe, 0x5430,
+ 0x9cc3, 0x0cd5,
+ 0x9cc4, 0x1db3,
+ 0x9cc8, 0x5435,
+ 0x9cca, 0x1db7,
+ 0x9cd1, 0x5437,
+ 0x9cd3, 0x1dbe,
+ 0x9cd6, 0x0457,
+ 0x9cd7, 0x1dc1,
+ 0x9cda, 0x5439,
+ 0x9cdc, 0x1dc4,
+ 0x9cde, 0x0a24,
+ 0x9cdf, 0x1dc6,
+ 0x9ce0, 0x543b,
+ 0x9ce2, 0x1dc7,
+ 0x9ce3, 0x543d,
+ 0x9ce5, 0x209c,
+ 0x9ce6, 0x543f,
+ 0x9ce9, 0x2580,
+ 0x9cea, 0x5442,
+ 0x9cec, 0x22dc,
+ 0x9ced, 0x5444,
+ 0x9cf3, 0x1f05,
+ 0x9cf4, 0x208b,
+ 0x9cf5, 0x544a,
+ 0x9cf6, 0x2581,
+ 0x9cf7, 0x544b,
+ 0x9d00, 0x5454,
+ 0x9d06, 0x2583,
+ 0x9d07, 0x2582,
+ 0x9d08, 0x545a,
+ 0x9d09, 0x21ee,
+ 0x9d0a, 0x545b,
+ 0x9d15, 0x2182,
+ 0x9d16, 0x5466,
+ 0x9d1b, 0x2243,
+ 0x9d1c, 0x546b,
+ 0x9d1d, 0x2587,
+ 0x9d1e, 0x546c,
+ 0x9d1f, 0x2588,
+ 0x9d20, 0x546d,
+ 0x9d23, 0x2584,
+ 0x9d24, 0x5470,
+ 0x9d26, 0x21fd,
+ 0x9d27, 0x5472,
+ 0x9d28, 0x21ef,
+ 0x9d29, 0x5473,
+ 0x9d2f, 0x258a,
+ 0x9d30, 0x258c,
+ 0x9d31, 0x5479,
+ 0x9d3b, 0x1f47,
+ 0x9d3c, 0x5483,
+ 0x9d3f, 0x1f1d,
+ 0x9d40, 0x5486,
+ 0x9d42, 0x258d,
+ 0x9d43, 0x5488,
+ 0x9d51, 0x1fd0,
+ 0x9d52, 0x2592,
+ 0x9d53, 0x258f,
+ 0x9d54, 0x5496,
+ 0x9d5c, 0x2594,
+ 0x9d5d, 0x1ee0,
+ 0x9d5e, 0x549e,
+ 0x9d60, 0x2591,
+ 0x9d61, 0x2595,
+ 0x9d62, 0x54a0,
+ 0x9d6a, 0x2597,
+ 0x9d6b, 0x54a8,
+ 0x9d6c, 0x20b6,
+ 0x9d6d, 0x54a9,
+ 0x9d6f, 0x2598,
+ 0x9d70, 0x54ab,
+ 0x9d72, 0x20f6,
+ 0x9d73, 0x54ad,
+ 0x9d87, 0x2585,
+ 0x9d88, 0x54c1,
+ 0x9d89, 0x2599,
+ 0x9d8a, 0x54c2,
+ 0x9d93, 0x2596,
+ 0x9d94, 0x54cb,
+ 0x9d98, 0x259a,
+ 0x9d99, 0x54cf,
+ 0x9d9a, 0x259b,
+ 0x9d9b, 0x54d0,
+ 0x9da5, 0x259d,
+ 0x9da6, 0x54da,
+ 0x9da9, 0x259e,
+ 0x9daa, 0x54dd,
+ 0x9daf, 0x234c,
+ 0x9db0, 0x54e2,
+ 0x9db4, 0x1f44,
+ 0x9db5, 0x54e6,
+ 0x9dbb, 0x2660,
+ 0x9dbc, 0x25a0,
+ 0x9dbd, 0x54ec,
+ 0x9dc0, 0x259c,
+ 0x9dc1, 0x54ef,
+ 0x9dc2, 0x259f,
+ 0x9dc3, 0x54f0,
+ 0x9dc4, 0x1f6c,
+ 0x9dc5, 0x54f1,
+ 0x9dd3, 0x25a2,
+ 0x9dd4, 0x54ff,
+ 0x9dd7, 0x20ae,
+ 0x9dd8, 0x5502,
+ 0x9dd9, 0x258b,
+ 0x9dda, 0x25a3,
+ 0x9ddb, 0x5503,
+ 0x9de5, 0x2589,
+ 0x9de6, 0x25a5,
+ 0x9de7, 0x550d,
+ 0x9def, 0x25a4,
+ 0x9df0, 0x5515,
+ 0x9df2, 0x25a6,
+ 0x9df3, 0x2593,
+ 0x9df4, 0x5517,
+ 0x9df8, 0x25a7,
+ 0x9df9, 0x2222,
+ 0x9dfa, 0x25a9,
+ 0x9dfb, 0x551b,
+ 0x9e00, 0x5520,
+ 0x9e0c, 0x25a8,
+ 0x9e0d, 0x552c,
+ 0x9e15, 0x2586,
+ 0x9e16, 0x5534,
+ 0x9e1a, 0x25a1,
+ 0x9e1b, 0x25aa,
+ 0x9e1c, 0x5538,
+ 0x9e1d, 0x2590,
+ 0x9e1e, 0x258e,
+ 0x9e1f, 0x0b54,
+ 0x9e20, 0x1b35,
+ 0x9e21, 0x0819,
+ 0x9e22, 0x1b36,
+ 0x9e23, 0x0afe,
+ 0x9e24, 0x5539,
+ 0x9e25, 0x0b79,
+ 0x9e26, 0x0fe4,
+ 0x9e27, 0x553a,
+ 0x9e28, 0x1b37,
+ 0x9e2d, 0x0fe5,
+ 0x9e2e, 0x553b,
+ 0x9e2f, 0x1015,
+ 0x9e30, 0x553c,
+ 0x9e31, 0x1b3d,
+ 0x9e32, 0x1b3c,
+ 0x9e33, 0x10ea,
+ 0x9e34, 0x553d,
+ 0x9e35, 0x0e83,
+ 0x9e36, 0x1b3e,
+ 0x9e37, 0x1b40,
+ 0x9e38, 0x1b3f,
+ 0x9e39, 0x1b41,
+ 0x9e3b, 0x553e,
+ 0x9e3d, 0x06e6,
+ 0x9e3e, 0x1b43,
+ 0x9e3f, 0x079f,
+ 0x9e40, 0x5540,
+ 0x9e41, 0x1b44,
+ 0x9e43, 0x0918,
+ 0x9e44, 0x1b46,
+ 0x9e45, 0x062b,
+ 0x9e46, 0x1b47,
+ 0x9e4a, 0x0c90,
+ 0x9e4b, 0x1b4b,
+ 0x9e4d, 0x5541,
+ 0x9e4e, 0x1b4d,
+ 0x9e4f, 0x0bb5,
+ 0x9e50, 0x5542,
+ 0x9e51, 0x1b4e,
+ 0x9e52, 0x5543,
+ 0x9e55, 0x1b4f,
+ 0x9e56, 0x5546,
+ 0x9e57, 0x1b50,
+ 0x9e58, 0x1dd5,
+ 0x9e59, 0x5547,
+ 0x9e5a, 0x1b51,
+ 0x9e5d, 0x5548,
+ 0x9e5e, 0x1b54,
+ 0x9e5f, 0x5549,
+ 0x9e63, 0x1b55,
+ 0x9e64, 0x078e,
+ 0x9e65, 0x554d,
+ 0x9e66, 0x1b56,
+ 0x9e6d, 0x1b5e,
+ 0x9e6e, 0x554e,
+ 0x9e70, 0x108a,
+ 0x9e71, 0x1b5d,
+ 0x9e72, 0x5550,
+ 0x9e73, 0x1b5f,
+ 0x9e74, 0x5551,
+ 0x9e75, 0x2688,
+ 0x9e76, 0x5552,
+ 0x9e79, 0x269e,
+ 0x9e7a, 0x25fb,
+ 0x9e7b, 0x5555,
+ 0x9e7c, 0x1f8c,
+ 0x9e7d, 0x21f4,
+ 0x9e7e, 0x1d16,
+ 0x9e7f, 0x0a60,
+ 0x9e80, 0x5556,
+ 0x9e82, 0x1dfc,
+ 0x9e83, 0x5558,
+ 0x9e87, 0x1dfd,
+ 0x9e89, 0x555c,
+ 0x9e8b, 0x1dff,
+ 0x9e8c, 0x555e,
+ 0x9e92, 0x1e00,
+ 0x9e93, 0x0a5b,
+ 0x9e94, 0x5564,
+ 0x9e97, 0x200f,
+ 0x9e98, 0x5567,
+ 0x9e9d, 0x1e02,
+ 0x9e9e, 0x556c,
+ 0x9e9f, 0x1e03,
+ 0x9ea0, 0x556d,
+ 0x9ea5, 0x2071,
+ 0x9ea6, 0x0a9a,
+ 0x9ea7, 0x5572,
+ 0x9ea9, 0x25f7,
+ 0x9eaa, 0x5574,
+ 0x9eaf, 0x2696,
+ 0x9eb0, 0x5579,
+ 0x9eb4, 0x1cee,
+ 0x9eb5, 0x268f,
+ 0x9eb6, 0x557d,
+ 0x9eb8, 0x1ced,
+ 0x9eb9, 0x557f,
+ 0x9ebb, 0x0a90,
+ 0x9ebc, 0x5581,
+ 0x9ebd, 0x1df9,
+ 0x9ebf, 0x5582,
+ 0x9ec4, 0x07db,
+ 0x9ec5, 0x5587,
+ 0x9ec9, 0x12f8,
+ 0x9eca, 0x558b,
+ 0x9ecc, 0x22da,
+ 0x9ecd, 0x0d89,
+ 0x9ece, 0x09d3,
+ 0x9ecf, 0x1b2a,
+ 0x9ed0, 0x558d,
+ 0x9ed1, 0x0791,
+ 0x9ed2, 0x558e,
+ 0x9ed4, 0x0c2a,
+ 0x9ed5, 0x5590,
+ 0x9ed8, 0x0b0f,
+ 0x9ed9, 0x5593,
+ 0x9edb, 0x1e04,
+ 0x9ede, 0x1ec1,
+ 0x9edf, 0x1e08,
+ 0x9ee0, 0x1e07,
+ 0x9ee1, 0x5595,
+ 0x9ee2, 0x1e09,
+ 0x9ee3, 0x5596,
+ 0x9ee5, 0x1e0c,
+ 0x9ee6, 0x5598,
+ 0x9ee7, 0x1e0b,
+ 0x9ee8, 0x1eb3,
+ 0x9ee9, 0x1e0a,
+ 0x9eea, 0x1e0d,
+ 0x9eeb, 0x5599,
+ 0x9eef, 0x1e0e,
+ 0x9ef0, 0x559d,
+ 0x9ef2, 0x266a,
+ 0x9ef3, 0x559f,
+ 0x9ef4, 0x268a,
+ 0x9ef5, 0x55a0,
+ 0x9ef7, 0x2669,
+ 0x9ef8, 0x55a2,
+ 0x9ef9, 0x1a55,
+ 0x9efa, 0x55a3,
+ 0x9efb, 0x1a56,
+ 0x9efd, 0x2618,
+ 0x9efe, 0x1d76,
+ 0x9eff, 0x2619,
+ 0x9f00, 0x55a4,
+ 0x9f09, 0x261a,
+ 0x9f0a, 0x55ad,
+ 0x9f0b, 0x1d77,
+ 0x9f0c, 0x55ae,
+ 0x9f0d, 0x1d78,
+ 0x9f0e, 0x05e5,
+ 0x9f0f, 0x55af,
+ 0x9f10, 0x1274,
+ 0x9f11, 0x55b0,
+ 0x9f13, 0x071d,
+ 0x9f14, 0x55b2,
+ 0x9f15, 0x2673,
+ 0x9f16, 0x55b3,
+ 0x9f17, 0x1271,
+ 0x9f18, 0x55b4,
+ 0x9f19, 0x13df,
+ 0x9f1a, 0x55b5,
+ 0x9f20, 0x0d8a,
+ 0x9f21, 0x55bb,
+ 0x9f22, 0x1e0f,
+ 0x9f23, 0x55bc,
+ 0x9f2c, 0x1e10,
+ 0x9f2d, 0x55c5,
+ 0x9f2f, 0x1e11,
+ 0x9f30, 0x55c7,
+ 0x9f37, 0x1e13,
+ 0x9f38, 0x55ce,
+ 0x9f39, 0x1e12,
+ 0x9f3a, 0x55cf,
+ 0x9f3b, 0x0430,
+ 0x9f3c, 0x55d0,
+ 0x9f3d, 0x1e14,
+ 0x9f3f, 0x55d1,
+ 0x9f44, 0x1e16,
+ 0x9f45, 0x55d6,
+ 0x9f4a, 0x20c6,
+ 0x9f4b, 0x226b,
+ 0x9f4c, 0x55db,
+ 0x9f4f, 0x24d3,
+ 0x9f50, 0x0c0a,
+ 0x9f51, 0x19c2,
+ 0x9f52, 0x1e86,
+ 0x9f53, 0x55de,
+ 0x9f54, 0x260f,
+ 0x9f55, 0x55df,
+ 0x9f59, 0x2611,
+ 0x9f5a, 0x55e3,
+ 0x9f5c, 0x2613,
+ 0x9f5d, 0x55e5,
+ 0x9f5f, 0x2610,
+ 0x9f60, 0x2612,
+ 0x9f61, 0x2030,
+ 0x9f62, 0x55e7,
+ 0x9f63, 0x2671,
+ 0x9f64, 0x55e8,
+ 0x9f66, 0x2614,
+ 0x9f67, 0x55ea,
+ 0x9f6a, 0x2616,
+ 0x9f6b, 0x55ed,
+ 0x9f6c, 0x2615,
+ 0x9f6d, 0x55ee,
+ 0x9f72, 0x20f2,
+ 0x9f73, 0x55f3,
+ 0x9f77, 0x2617,
+ 0x9f78, 0x55f7,
+ 0x9f7f, 0x0502,
+ 0x9f80, 0x1d6d,
+ 0x9f81, 0x55fe,
+ 0x9f83, 0x1d6e,
+ 0x9f84, 0x0a2d,
+ 0x9f85, 0x1d6f,
+ 0x9f8b, 0x0c7e,
+ 0x9f8c, 0x1d75,
+ 0x9f8d, 0x2037,
+ 0x9f8e, 0x5600,
+ 0x9f90, 0x20b3,
+ 0x9f91, 0x5602,
+ 0x9f94, 0x1f22,
+ 0x9f95, 0x24ed,
+ 0x9f96, 0x5605,
+ 0x9f99, 0x0a43,
+ 0x9f9a, 0x0701,
+ 0x9f9b, 0x1a54,
+ 0x9f9c, 0x1f34,
+ 0x9f9d, 0x5608,
+ 0x9f9f, 0x0743,
+ 0x9fa0, 0x12f3,
+ 0x9fa1, 0x560a,
+ 0xe7e7, 0x274b,
+ 0xe815, 0x561f,
+ 0xf92c, 0x560f,
+ 0xfa0d, 0x5610,
+ 0xfa11, 0x5613,
+ 0xfa13, 0x5614,
+ 0xfa18, 0x5616,
+ 0xfa1f, 0x5617,
+ 0xfa23, 0x561a,
+ 0xfa27, 0x561c,
+ 0xfe30, 0x271d,
+ 0xfe49, 0x272b,
+ 0xfe54, 0x2735,
+ 0xfe59, 0x2739,
+ 0xfe68, 0x2747,
+ 0xff01, 0x0106,
+ 0xff04, 0x00a6,
+ 0xff05, 0x010a,
+ 0xff5e, 0x006a,
+ 0xffe0, 0x00a8,
+ 0xffe2, 0x271e,
+ 0xffe3, 0x0163,
+ 0xffe4, 0x271f,
+ 0xffe5, 0x0109,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12UniGBUCS2HEnc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12UniGBUCS2HMap2, 13461
+};
+
+static Gushort gb12UniGBUCS2VMap2[26970] = {
+ 0x0000, 0x0000,
+ 0x0020, 0x0001,
+ 0x00a4, 0x00a7,
+ 0x00a7, 0x00ab,
+ 0x00a8, 0x0066,
+ 0x00b0, 0x00a2,
+ 0x00b1, 0x007f,
+ 0x00d7, 0x0080,
+ 0x00e0, 0x029f,
+ 0x00e1, 0x029d,
+ 0x00e8, 0x02a3,
+ 0x00e9, 0x02a1,
+ 0x00ea, 0x02b5,
+ 0x00ec, 0x02a7,
+ 0x00ed, 0x02a5,
+ 0x00f2, 0x02ab,
+ 0x00f3, 0x02a9,
+ 0x00f7, 0x0081,
+ 0x00f9, 0x02af,
+ 0x00fa, 0x02ad,
+ 0x00fc, 0x02b4,
+ 0x0101, 0x029c,
+ 0x0113, 0x02a0,
+ 0x011b, 0x02a2,
+ 0x012b, 0x02a4,
+ 0x014d, 0x02a8,
+ 0x016b, 0x02ac,
+ 0x01ce, 0x029e,
+ 0x01d0, 0x02a6,
+ 0x01d2, 0x02aa,
+ 0x01d4, 0x02ae,
+ 0x01d6, 0x02b0,
+ 0x01d8, 0x02b1,
+ 0x01da, 0x02b2,
+ 0x01dc, 0x02b3,
+ 0x02c7, 0x0065,
+ 0x02c9, 0x0064,
+ 0x02ca, 0x26b3,
+ 0x02d9, 0x26b5,
+ 0x0391, 0x020d,
+ 0x03a3, 0x021e,
+ 0x03b1, 0x0225,
+ 0x03c3, 0x0236,
+ 0x0401, 0x0260,
+ 0x0410, 0x025a,
+ 0x0416, 0x0261,
+ 0x0436, 0x0282,
+ 0x0451, 0x0281,
+ 0x1e3f, 0x02b7,
+ 0x2010, 0x2722,
+ 0x2013, 0x26b6,
+ 0x2014, 0x0069,
+ 0x2015, 0x26b7,
+ 0x2016, 0x006b,
+ 0x2018, 0x006d,
+ 0x201c, 0x006f,
+ 0x2025, 0x26b8,
+ 0x2026, 0x006c,
+ 0x2030, 0x00aa,
+ 0x2032, 0x00a3,
+ 0x2035, 0x26b9,
+ 0x203b, 0x00b8,
+ 0x2103, 0x00a5,
+ 0x2105, 0x26ba,
+ 0x2109, 0x26bb,
+ 0x2116, 0x00ac,
+ 0x2121, 0x2720,
+ 0x2160, 0x00fa,
+ 0x2170, 0x26a9,
+ 0x2190, 0x00ba,
+ 0x2192, 0x00b9,
+ 0x2193, 0x00bc,
+ 0x2196, 0x26bc,
+ 0x2208, 0x0089,
+ 0x220f, 0x0086,
+ 0x2211, 0x0085,
+ 0x2215, 0x26c0,
+ 0x221a, 0x008b,
+ 0x221d, 0x0097,
+ 0x221e, 0x009d,
+ 0x221f, 0x26c1,
+ 0x2220, 0x008e,
+ 0x2223, 0x26c2,
+ 0x2225, 0x008d,
+ 0x2227, 0x0083,
+ 0x2229, 0x0088,
+ 0x222a, 0x0087,
+ 0x222b, 0x0091,
+ 0x222e, 0x0092,
+ 0x2234, 0x009f,
+ 0x2235, 0x009e,
+ 0x2236, 0x0082,
+ 0x2237, 0x008a,
+ 0x223d, 0x0096,
+ 0x2248, 0x0095,
+ 0x224c, 0x0094,
+ 0x2252, 0x26c3,
+ 0x2260, 0x0098,
+ 0x2261, 0x0093,
+ 0x2264, 0x009b,
+ 0x2266, 0x26c4,
+ 0x226e, 0x0099,
+ 0x2295, 0x2704,
+ 0x2299, 0x0090,
+ 0x22a5, 0x008c,
+ 0x22bf, 0x26c6,
+ 0x22ef, 0x006c,
+ 0x2312, 0x008f,
+ 0x2460, 0x00e6,
+ 0x2474, 0x00d2,
+ 0x2488, 0x00be,
+ 0x2500, 0x02e2,
+ 0x2550, 0x26c7,
+ 0x2581, 0x26eb,
+ 0x2593, 0x26fa,
+ 0x25a0, 0x00b5,
+ 0x25a1, 0x00b4,
+ 0x25b2, 0x00b7,
+ 0x25b3, 0x00b6,
+ 0x25bc, 0x26fd,
+ 0x25c6, 0x00b3,
+ 0x25c7, 0x00b2,
+ 0x25cb, 0x00af,
+ 0x25ce, 0x00b1,
+ 0x25cf, 0x00b0,
+ 0x25e2, 0x26ff,
+ 0x2605, 0x00ae,
+ 0x2606, 0x00ad,
+ 0x2609, 0x2703,
+ 0x2640, 0x00a1,
+ 0x2642, 0x00a0,
+ 0x3000, 0x0060,
+ 0x3003, 0x0067,
+ 0x3005, 0x0068,
+ 0x3006, 0x2728,
+ 0x3007, 0x1e17,
+ 0x3008, 0x0073,
+ 0x3010, 0x007d,
+ 0x3012, 0x2705,
+ 0x3013, 0x00bd,
+ 0x3014, 0x0071,
+ 0x3016, 0x007b,
+ 0x301d, 0x2706,
+ 0x3021, 0x2708,
+ 0x3041, 0x0164,
+ 0x309b, 0x2724,
+ 0x309d, 0x2729,
+ 0x30a1, 0x01b7,
+ 0x30fb, 0x0063,
+ 0x30fc, 0x2723,
+ 0x30fd, 0x2726,
+ 0x3105, 0x02bc,
+ 0x3220, 0x00f0,
+ 0x3231, 0x2721,
+ 0x32a3, 0x2711,
+ 0x338e, 0x2712,
+ 0x339c, 0x2714,
+ 0x33a1, 0x2717,
+ 0x33c4, 0x2718,
+ 0x33ce, 0x2719,
+ 0x33d1, 0x271a,
+ 0x33d5, 0x271c,
+ 0x4e00, 0x1042,
+ 0x4e01, 0x05e0,
+ 0x4e02, 0x2758,
+ 0x4e03, 0x0bfe,
+ 0x4e04, 0x2759,
+ 0x4e07, 0x0ea3,
+ 0x4e08, 0x116a,
+ 0x4e09, 0x0cd8,
+ 0x4e0a, 0x0d08,
+ 0x4e0b, 0x0f2f,
+ 0x4e0c, 0x1258,
+ 0x4e0d, 0x0482,
+ 0x4e0e, 0x10d0,
+ 0x4e0f, 0x275c,
+ 0x4e10, 0x125a,
+ 0x4e11, 0x0518,
+ 0x4e12, 0x275d,
+ 0x4e13, 0x1205,
+ 0x4e14, 0x0c4f,
+ 0x4e15, 0x125d,
+ 0x4e16, 0x0d57,
+ 0x4e17, 0x275e,
+ 0x4e18, 0x0c6d,
+ 0x4e19, 0x0464,
+ 0x4e1a, 0x103c,
+ 0x4e1b, 0x0557,
+ 0x4e1c, 0x05ea,
+ 0x4e1d, 0x0db4,
+ 0x4e1e, 0x125f,
+ 0x4e1f, 0x275f,
+ 0x4e22, 0x05e9,
+ 0x4e23, 0x2762,
+ 0x4e24, 0x0a06,
+ 0x4e25, 0x0ff8,
+ 0x4e26, 0x2763,
+ 0x4e27, 0x0cde,
+ 0x4e28, 0x1263,
+ 0x4e29, 0x2764,
+ 0x4e2a, 0x06f1,
+ 0x4e2b, 0x0fe7,
+ 0x4e2c, 0x169c,
+ 0x4e2d, 0x11cf,
+ 0x4e2e, 0x2765,
+ 0x4e30, 0x067e,
+ 0x4e31, 0x2767,
+ 0x4e32, 0x0531,
+ 0x4e33, 0x2768,
+ 0x4e34, 0x0a22,
+ 0x4e35, 0x2769,
+ 0x4e36, 0x1272,
+ 0x4e37, 0x276a,
+ 0x4e38, 0x0e99,
+ 0x4e39, 0x0585,
+ 0x4e3a, 0x0eb9,
+ 0x4e3b, 0x11f6,
+ 0x4e3c, 0x276b,
+ 0x4e3d, 0x09e1,
+ 0x4e3e, 0x0908,
+ 0x4e3f, 0x1265,
+ 0x4e40, 0x276c,
+ 0x4e43, 0x0b2e,
+ 0x4e44, 0x276f,
+ 0x4e45, 0x08f2,
+ 0x4e46, 0x2770,
+ 0x4e47, 0x1267,
+ 0x4e48, 0x0ab9,
+ 0x4e49, 0x106c,
+ 0x4e4a, 0x2771,
+ 0x4e4b, 0x11ad,
+ 0x4e4c, 0x0ee9,
+ 0x4e4d, 0x1148,
+ 0x4e4e, 0x07ac,
+ 0x4e4f, 0x0643,
+ 0x4e50, 0x09c1,
+ 0x4e51, 0x2772,
+ 0x4e52, 0x0bd8,
+ 0x4e53, 0x0b93,
+ 0x4e54, 0x0c44,
+ 0x4e55, 0x2773,
+ 0x4e56, 0x072d,
+ 0x4e57, 0x2774,
+ 0x4e58, 0x04f0,
+ 0x4e59, 0x1059,
+ 0x4e5a, 0x2775,
+ 0x4e5c, 0x1275,
+ 0x4e5d, 0x08f4,
+ 0x4e5e, 0x0c11,
+ 0x4e5f, 0x1039,
+ 0x4e60, 0x0f1d,
+ 0x4e61, 0x0f54,
+ 0x4e62, 0x2777,
+ 0x4e66, 0x0d80,
+ 0x4e67, 0x277b,
+ 0x4e69, 0x1276,
+ 0x4e6a, 0x277d,
+ 0x4e70, 0x0a99,
+ 0x4e71, 0x0a79,
+ 0x4e72, 0x2783,
+ 0x4e73, 0x0cc4,
+ 0x4e74, 0x2784,
+ 0x4e7e, 0x0c29,
+ 0x4e7f, 0x278e,
+ 0x4e82, 0x2059,
+ 0x4e83, 0x2791,
+ 0x4e86, 0x0a14,
+ 0x4e87, 0x2794,
+ 0x4e88, 0x10cd,
+ 0x4e89, 0x119a,
+ 0x4e8a, 0x2795,
+ 0x4e8b, 0x0d59,
+ 0x4e8c, 0x063d,
+ 0x4e8d, 0x1257,
+ 0x4e8e, 0x10bf,
+ 0x4e8f, 0x0984,
+ 0x4e90, 0x2796,
+ 0x4e91, 0x1109,
+ 0x4e92, 0x07ba,
+ 0x4e93, 0x1277,
+ 0x4e94, 0x0ef4,
+ 0x4e95, 0x08dd,
+ 0x4e96, 0x2797,
+ 0x4e98, 0x125e,
+ 0x4e99, 0x2799,
+ 0x4e9a, 0x0ff0,
+ 0x4e9b, 0x0f74,
+ 0x4e9c, 0x279a,
+ 0x4e9e, 0x21f1,
+ 0x4e9f, 0x1273,
+ 0x4ea0, 0x1303,
+ 0x4ea1, 0x0ea7,
+ 0x4ea2, 0x0947,
+ 0x4ea3, 0x279c,
+ 0x4ea4, 0x088c,
+ 0x4ea5, 0x075c,
+ 0x4ea6, 0x1067,
+ 0x4ea7, 0x04c1,
+ 0x4ea8, 0x0797,
+ 0x4ea9, 0x0b19,
+ 0x4eaa, 0x279d,
+ 0x4eab, 0x0f5a,
+ 0x4eac, 0x08d8,
+ 0x4ead, 0x0e55,
+ 0x4eae, 0x0a0a,
+ 0x4eaf, 0x279e,
+ 0x4eb2, 0x0c54,
+ 0x4eb3, 0x1305,
+ 0x4eb4, 0x27a1,
+ 0x4eb5, 0x1308,
+ 0x4eb6, 0x27a2,
+ 0x4eba, 0x0ca6,
+ 0x4ebb, 0x129f,
+ 0x4ebc, 0x27a6,
+ 0x4ebf, 0x1061,
+ 0x4ec0, 0x0d49,
+ 0x4ec1, 0x0ca5,
+ 0x4ec2, 0x12a2,
+ 0x4ec3, 0x12a0,
+ 0x4ec4, 0x127c,
+ 0x4ec5, 0x08c7,
+ 0x4ec6, 0x0bec,
+ 0x4ec7, 0x0515,
+ 0x4ec8, 0x27a9,
+ 0x4ec9, 0x12a1,
+ 0x4eca, 0x08c2,
+ 0x4ecb, 0x08ba,
+ 0x4ecc, 0x27aa,
+ 0x4ecd, 0x0caf,
+ 0x4ece, 0x0556,
+ 0x4ecf, 0x27ab,
+ 0x4ed1, 0x0a7f,
+ 0x4ed2, 0x27ad,
+ 0x4ed3, 0x049d,
+ 0x4ed4, 0x122d,
+ 0x4ed5, 0x0d62,
+ 0x4ed6, 0x0df0,
+ 0x4ed7, 0x116d,
+ 0x4ed8, 0x06b1,
+ 0x4ed9, 0x0f36,
+ 0x4eda, 0x27ae,
+ 0x4edd, 0x12ee,
+ 0x4ede, 0x12a6,
+ 0x4edf, 0x0c27,
+ 0x4ee0, 0x27b1,
+ 0x4ee1, 0x12a4,
+ 0x4ee2, 0x27b2,
+ 0x4ee3, 0x057d,
+ 0x4ee4, 0x0a37,
+ 0x4ee5, 0x105b,
+ 0x4ee6, 0x27b3,
+ 0x4ee8, 0x12a3,
+ 0x4ee9, 0x27b5,
+ 0x4eea, 0x104e,
+ 0x4eeb, 0x12a5,
+ 0x4eec, 0x0acc,
+ 0x4eed, 0x27b6,
+ 0x4ef0, 0x101f,
+ 0x4ef1, 0x27b9,
+ 0x4ef2, 0x11d8,
+ 0x4ef3, 0x12a8,
+ 0x4ef4, 0x27ba,
+ 0x4ef5, 0x12ab,
+ 0x4ef6, 0x0871,
+ 0x4ef7, 0x084e,
+ 0x4ef8, 0x27bb,
+ 0x4efb, 0x0ca9,
+ 0x4efc, 0x27be,
+ 0x4efd, 0x067a,
+ 0x4efe, 0x27bf,
+ 0x4eff, 0x065f,
+ 0x4f00, 0x27c0,
+ 0x4f01, 0x0c12,
+ 0x4f02, 0x27c1,
+ 0x4f09, 0x12ae,
+ 0x4f0a, 0x1048,
+ 0x4f0b, 0x27c8,
+ 0x4f0d, 0x0ef8,
+ 0x4f0e, 0x0832,
+ 0x4f0f, 0x0699,
+ 0x4f10, 0x0642,
+ 0x4f11, 0x0fa8,
+ 0x4f12, 0x27ca,
+ 0x4f17, 0x11d9,
+ 0x4f18, 0x10aa,
+ 0x4f19, 0x0804,
+ 0x4f1a, 0x07f6,
+ 0x4f1b, 0x12a7,
+ 0x4f1c, 0x27cf,
+ 0x4f1e, 0x0cda,
+ 0x4f1f, 0x0ebf,
+ 0x4f20, 0x052e,
+ 0x4f21, 0x27d1,
+ 0x4f22, 0x12a9,
+ 0x4f23, 0x27d2,
+ 0x4f24, 0x0d04,
+ 0x4f25, 0x12ac,
+ 0x4f26, 0x0a7e,
+ 0x4f27, 0x12ad,
+ 0x4f28, 0x27d3,
+ 0x4f2a, 0x0ec0,
+ 0x4f2b, 0x12af,
+ 0x4f2c, 0x27d5,
+ 0x4f2f, 0x0475,
+ 0x4f30, 0x0719,
+ 0x4f31, 0x27d8,
+ 0x4f32, 0x12b7,
+ 0x4f33, 0x27d9,
+ 0x4f34, 0x03f4,
+ 0x4f35, 0x27da,
+ 0x4f36, 0x0a2f,
+ 0x4f37, 0x27db,
+ 0x4f38, 0x0d25,
+ 0x4f39, 0x27dc,
+ 0x4f3a, 0x0dba,
+ 0x4f3b, 0x27dd,
+ 0x4f3c, 0x0dbb,
+ 0x4f3d, 0x12b8,
+ 0x4f3e, 0x27de,
+ 0x4f43, 0x05c9,
+ 0x4f44, 0x27e3,
+ 0x4f46, 0x058c,
+ 0x4f47, 0x27e5,
+ 0x4f4d, 0x0eca,
+ 0x4f4e, 0x05ae,
+ 0x4f4f, 0x11fe,
+ 0x4f50, 0x1251,
+ 0x4f51, 0x10b8,
+ 0x4f52, 0x27eb,
+ 0x4f53, 0x0e38,
+ 0x4f54, 0x27ec,
+ 0x4f55, 0x0785,
+ 0x4f56, 0x27ed,
+ 0x4f57, 0x12b6,
+ 0x4f58, 0x12f0,
+ 0x4f59, 0x10c5,
+ 0x4f5a, 0x12b3,
+ 0x4f5b, 0x068d,
+ 0x4f5c, 0x1254,
+ 0x4f5d, 0x12b4,
+ 0x4f5e, 0x12b0,
+ 0x4f5f, 0x12b5,
+ 0x4f60, 0x0b46,
+ 0x4f61, 0x27ee,
+ 0x4f63, 0x109b,
+ 0x4f64, 0x12aa,
+ 0x4f65, 0x12f1,
+ 0x4f66, 0x27f0,
+ 0x4f67, 0x12b1,
+ 0x4f68, 0x27f1,
+ 0x4f69, 0x0ba6,
+ 0x4f6a, 0x27f2,
+ 0x4f6c, 0x09bb,
+ 0x4f6d, 0x27f4,
+ 0x4f6f, 0x1019,
+ 0x4f70, 0x03e6,
+ 0x4f71, 0x27f6,
+ 0x4f73, 0x0844,
+ 0x4f74, 0x12ba,
+ 0x4f75, 0x27f8,
+ 0x4f76, 0x12b9,
+ 0x4f77, 0x27f9,
+ 0x4f7b, 0x12c0,
+ 0x4f7c, 0x12c2,
+ 0x4f7d, 0x27fd,
+ 0x4f7e, 0x12bf,
+ 0x4f7f, 0x0d50,
+ 0x4f80, 0x27fe,
+ 0x4f83, 0x12bd,
+ 0x4f84, 0x11b5,
+ 0x4f85, 0x2801,
+ 0x4f86, 0x1ff2,
+ 0x4f87, 0x2802,
+ 0x4f88, 0x0503,
+ 0x4f89, 0x12bc,
+ 0x4f8a, 0x2803,
+ 0x4f8b, 0x09e8,
+ 0x4f8c, 0x2804,
+ 0x4f8d, 0x0d63,
+ 0x4f8e, 0x2805,
+ 0x4f8f, 0x12be,
+ 0x4f90, 0x2806,
+ 0x4f91, 0x12bb,
+ 0x4f92, 0x2807,
+ 0x4f94, 0x12c4,
+ 0x4f95, 0x2809,
+ 0x4f96, 0x205d,
+ 0x4f97, 0x05f0,
+ 0x4f98, 0x280a,
+ 0x4f9b, 0x0702,
+ 0x4f9c, 0x280d,
+ 0x4f9d, 0x1047,
+ 0x4f9e, 0x280e,
+ 0x4fa0, 0x0f2d,
+ 0x4fa1, 0x2810,
+ 0x4fa3, 0x0a69,
+ 0x4fa4, 0x2812,
+ 0x4fa5, 0x0895,
+ 0x4fa6, 0x118d,
+ 0x4fa7, 0x04a7,
+ 0x4fa8, 0x0c45,
+ 0x4fa9, 0x0978,
+ 0x4faa, 0x12c1,
+ 0x4fab, 0x2813,
+ 0x4fac, 0x12c3,
+ 0x4fad, 0x2814,
+ 0x4fae, 0x0ef9,
+ 0x4faf, 0x07a5,
+ 0x4fb0, 0x2815,
+ 0x4fb5, 0x0c53,
+ 0x4fb6, 0x281a,
+ 0x4fbf, 0x044c,
+ 0x4fc0, 0x2823,
+ 0x4fc2, 0x269c,
+ 0x4fc3, 0x055c,
+ 0x4fc4, 0x062c,
+ 0x4fc5, 0x12c8,
+ 0x4fc6, 0x2825,
+ 0x4fca, 0x092e,
+ 0x4fcb, 0x2829,
+ 0x4fce, 0x12f2,
+ 0x4fcf, 0x0c4b,
+ 0x4fd0, 0x09e9,
+ 0x4fd1, 0x12cc,
+ 0x4fd2, 0x282c,
+ 0x4fd7, 0x0dcc,
+ 0x4fd8, 0x069a,
+ 0x4fd9, 0x2831,
+ 0x4fda, 0x12c9,
+ 0x4fdb, 0x2832,
+ 0x4fdc, 0x12cb,
+ 0x4fdd, 0x040c,
+ 0x4fde, 0x10c6,
+ 0x4fdf, 0x12cd,
+ 0x4fe0, 0x21b5,
+ 0x4fe1, 0x0f90,
+ 0x4fe2, 0x2833,
+ 0x4fe3, 0x12ca,
+ 0x4fe4, 0x2834,
+ 0x4fe6, 0x12c5,
+ 0x4fe7, 0x2836,
+ 0x4fe8, 0x12c6,
+ 0x4fe9, 0x09f2,
+ 0x4fea, 0x12c7,
+ 0x4feb, 0x2837,
+ 0x4fed, 0x0866,
+ 0x4fee, 0x0fa9,
+ 0x4fef, 0x06a4,
+ 0x4ff0, 0x2839,
+ 0x4ff1, 0x0912,
+ 0x4ff2, 0x283a,
+ 0x4ff3, 0x12d1,
+ 0x4ff4, 0x283b,
+ 0x4ff8, 0x12ce,
+ 0x4ff9, 0x283f,
+ 0x4ffa, 0x03be,
+ 0x4ffb, 0x2840,
+ 0x4ffe, 0x12d6,
+ 0x4fff, 0x2843,
+ 0x5000, 0x22cc,
+ 0x5001, 0x2844,
+ 0x5006, 0x2016,
+ 0x5007, 0x2849,
+ 0x5009, 0x1e62,
+ 0x500a, 0x284b,
+ 0x500b, 0x1f20,
+ 0x500c, 0x12d8,
+ 0x500d, 0x041f,
+ 0x500e, 0x284c,
+ 0x500f, 0x12d3,
+ 0x5010, 0x284d,
+ 0x5011, 0x207f,
+ 0x5012, 0x059a,
+ 0x5013, 0x284e,
+ 0x5014, 0x0922,
+ 0x5015, 0x284f,
+ 0x5018, 0x0e1b,
+ 0x5019, 0x07a9,
+ 0x501a, 0x1057,
+ 0x501b, 0x2852,
+ 0x501c, 0x12d7,
+ 0x501d, 0x2853,
+ 0x501f, 0x08b9,
+ 0x5020, 0x2855,
+ 0x5021, 0x04d0,
+ 0x5022, 0x2856,
+ 0x5025, 0x12d9,
+ 0x5026, 0x091a,
+ 0x5027, 0x2859,
+ 0x5028, 0x12da,
+ 0x5029, 0x12cf,
+ 0x502a, 0x0b42,
+ 0x502b, 0x205c,
+ 0x502c, 0x12d2,
+ 0x502d, 0x12d5,
+ 0x502e, 0x12d4,
+ 0x502f, 0x285a,
+ 0x503a, 0x114f,
+ 0x503b, 0x2865,
+ 0x503c, 0x11b4,
+ 0x503d, 0x2866,
+ 0x503e, 0x0c60,
+ 0x503f, 0x2867,
+ 0x5043, 0x12dc,
+ 0x5044, 0x286b,
+ 0x5047, 0x084c,
+ 0x5048, 0x12de,
+ 0x5049, 0x2194,
+ 0x504a, 0x286e,
+ 0x504c, 0x12d0,
+ 0x504d, 0x2870,
+ 0x504e, 0x12df,
+ 0x504f, 0x0bca,
+ 0x5050, 0x2871,
+ 0x5055, 0x12dd,
+ 0x5056, 0x2876,
+ 0x505a, 0x1253,
+ 0x505b, 0x287a,
+ 0x505c, 0x0e54,
+ 0x505d, 0x287b,
+ 0x5065, 0x0872,
+ 0x5066, 0x2883,
+ 0x506c, 0x12e0,
+ 0x506d, 0x2889,
+ 0x5074, 0x1e65,
+ 0x5075, 0x2281,
+ 0x5076, 0x0b7d,
+ 0x5077, 0x0e66,
+ 0x5078, 0x2890,
+ 0x507b, 0x12e1,
+ 0x507c, 0x2893,
+ 0x507e, 0x12db,
+ 0x507f, 0x04ca,
+ 0x5080, 0x098b,
+ 0x5081, 0x2895,
+ 0x5085, 0x06b0,
+ 0x5086, 0x2899,
+ 0x5088, 0x09e7,
+ 0x5089, 0x289b,
+ 0x508d, 0x0403,
+ 0x508e, 0x289f,
+ 0x5096, 0x22cd,
+ 0x5097, 0x28a7,
+ 0x5098, 0x210a,
+ 0x5099, 0x1e3e,
+ 0x509a, 0x28a8,
+ 0x50a2, 0x267f,
+ 0x50a3, 0x0579,
+ 0x50a4, 0x28b0,
+ 0x50a5, 0x12e2,
+ 0x50a6, 0x28b1,
+ 0x50a7, 0x12e3,
+ 0x50a8, 0x0525,
+ 0x50a9, 0x12e4,
+ 0x50aa, 0x28b2,
+ 0x50ac, 0x0562,
+ 0x50ad, 0x222e,
+ 0x50ae, 0x28b4,
+ 0x50b2, 0x03cc,
+ 0x50b3, 0x1e96,
+ 0x50b4, 0x22cb,
+ 0x50b5, 0x226c,
+ 0x50b6, 0x28b8,
+ 0x50b7, 0x2117,
+ 0x50b8, 0x28b9,
+ 0x50ba, 0x12e5,
+ 0x50bb, 0x0cee,
+ 0x50bc, 0x28bb,
+ 0x50be, 0x20e8,
+ 0x50bf, 0x28bd,
+ 0x50c2, 0x22d4,
+ 0x50c3, 0x28c0,
+ 0x50c5, 0x1fb9,
+ 0x50c6, 0x28c2,
+ 0x50c9, 0x22d8,
+ 0x50ca, 0x28c5,
+ 0x50cf, 0x0f5e,
+ 0x50d0, 0x28ca,
+ 0x50d1, 0x20df,
+ 0x50d2, 0x28cb,
+ 0x50d5, 0x20c2,
+ 0x50d6, 0x12e6,
+ 0x50d7, 0x28ce,
+ 0x50da, 0x0a0e,
+ 0x50db, 0x28d1,
+ 0x50de, 0x2195,
+ 0x50df, 0x28d4,
+ 0x50e5, 0x1fac,
+ 0x50e6, 0x12ea,
+ 0x50e7, 0x0ce7,
+ 0x50e8, 0x22d3,
+ 0x50e9, 0x28da,
+ 0x50ec, 0x12e9,
+ 0x50ed, 0x12e8,
+ 0x50ee, 0x12eb,
+ 0x50ef, 0x28dd,
+ 0x50f3, 0x0dd0,
+ 0x50f4, 0x28e1,
+ 0x50f5, 0x087a,
+ 0x50f6, 0x28e2,
+ 0x50f9, 0x1f81,
+ 0x50fa, 0x28e5,
+ 0x50fb, 0x0bc6,
+ 0x50fc, 0x28e6,
+ 0x5100, 0x2210,
+ 0x5101, 0x28ea,
+ 0x5102, 0x22cf,
+ 0x5103, 0x28eb,
+ 0x5104, 0x2213,
+ 0x5105, 0x28ec,
+ 0x5106, 0x12e7,
+ 0x5107, 0x12ec,
+ 0x5108, 0x1fe4,
+ 0x5109, 0x1f90,
+ 0x510a, 0x28ed,
+ 0x510b, 0x12ed,
+ 0x510c, 0x28ee,
+ 0x5110, 0x22d6,
+ 0x5111, 0x28f2,
+ 0x5112, 0x0cc0,
+ 0x5113, 0x28f3,
+ 0x5114, 0x22d0,
+ 0x5115, 0x22ce,
+ 0x5116, 0x28f4,
+ 0x5118, 0x2681,
+ 0x5119, 0x28f6,
+ 0x511f, 0x1e76,
+ 0x5120, 0x28fc,
+ 0x5121, 0x09c7,
+ 0x5122, 0x28fd,
+ 0x512a, 0x2231,
+ 0x512b, 0x2905,
+ 0x5132, 0x1e93,
+ 0x5133, 0x290c,
+ 0x5137, 0x22d2,
+ 0x5138, 0x2910,
+ 0x513a, 0x22d7,
+ 0x513b, 0x22d5,
+ 0x513c, 0x22d1,
+ 0x513d, 0x2912,
+ 0x513f, 0x0638,
+ 0x5140, 0x1259,
+ 0x5141, 0x110d,
+ 0x5142, 0x2914,
+ 0x5143, 0x10ed,
+ 0x5144, 0x0fa1,
+ 0x5145, 0x0509,
+ 0x5146, 0x1178,
+ 0x5147, 0x2915,
+ 0x5148, 0x0f35,
+ 0x5149, 0x073b,
+ 0x514a, 0x2916,
+ 0x514b, 0x0958,
+ 0x514c, 0x2917,
+ 0x514d, 0x0ae7,
+ 0x514e, 0x2918,
+ 0x5151, 0x0611,
+ 0x5152, 0x1ee5,
+ 0x5153, 0x291b,
+ 0x5154, 0x0e74,
+ 0x5155, 0x1302,
+ 0x5156, 0x1304,
+ 0x5157, 0x291c,
+ 0x515a, 0x0594,
+ 0x515b, 0x291f,
+ 0x515c, 0x05f4,
+ 0x515d, 0x2920,
+ 0x5162, 0x08d3,
+ 0x5163, 0x2925,
+ 0x5165, 0x0cc6,
+ 0x5166, 0x2927,
+ 0x5168, 0x0c86,
+ 0x5169, 0x2025,
+ 0x516a, 0x2929,
+ 0x516b, 0x03d6,
+ 0x516c, 0x0704,
+ 0x516d, 0x0a42,
+ 0x516e, 0x12f6,
+ 0x516f, 0x292a,
+ 0x5170, 0x09a7,
+ 0x5171, 0x070b,
+ 0x5172, 0x292b,
+ 0x5173, 0x0731,
+ 0x5174, 0x0f96,
+ 0x5175, 0x0461,
+ 0x5176, 0x0c03,
+ 0x5177, 0x090e,
+ 0x5178, 0x05c5,
+ 0x5179, 0x1225,
+ 0x517a, 0x292c,
+ 0x517b, 0x1021,
+ 0x517c, 0x0859,
+ 0x517d, 0x0d75,
+ 0x517e, 0x292d,
+ 0x5180, 0x0830,
+ 0x5181, 0x12fa,
+ 0x5182, 0x129d,
+ 0x5183, 0x292f,
+ 0x5185, 0x0b3d,
+ 0x5186, 0x2931,
+ 0x5188, 0x06cf,
+ 0x5189, 0x0c98,
+ 0x518a, 0x2933,
+ 0x518c, 0x04a8,
+ 0x518d, 0x111c,
+ 0x518e, 0x2935,
+ 0x5192, 0x0ab5,
+ 0x5193, 0x2939,
+ 0x5195, 0x0ae6,
+ 0x5196, 0x1314,
+ 0x5197, 0x0cba,
+ 0x5198, 0x293b,
+ 0x5199, 0x0f7f,
+ 0x519a, 0x293c,
+ 0x519b, 0x092b,
+ 0x519c, 0x0b6a,
+ 0x519d, 0x293d,
+ 0x51a0, 0x0733,
+ 0x51a1, 0x2940,
+ 0x51a2, 0x1315,
+ 0x51a3, 0x2941,
+ 0x51a4, 0x10ec,
+ 0x51a5, 0x1316,
+ 0x51a6, 0x2942,
+ 0x51ab, 0x130f,
+ 0x51ac, 0x05eb,
+ 0x51ad, 0x2947,
+ 0x51af, 0x0688,
+ 0x51b0, 0x0462,
+ 0x51b1, 0x1310,
+ 0x51b2, 0x050a,
+ 0x51b3, 0x0925,
+ 0x51b4, 0x2949,
+ 0x51b5, 0x0983,
+ 0x51b6, 0x1038,
+ 0x51b7, 0x09cf,
+ 0x51b8, 0x294a,
+ 0x51bb, 0x05f2,
+ 0x51bc, 0x1312,
+ 0x51bd, 0x1311,
+ 0x51be, 0x294d,
+ 0x51c0, 0x08ea,
+ 0x51c1, 0x294f,
+ 0x51c4, 0x0bff,
+ 0x51c5, 0x2952,
+ 0x51c6, 0x1219,
+ 0x51c7, 0x1313,
+ 0x51c8, 0x2953,
+ 0x51c9, 0x0a02,
+ 0x51ca, 0x2954,
+ 0x51cb, 0x05d3,
+ 0x51cc, 0x0a31,
+ 0x51cd, 0x1ecf,
+ 0x51ce, 0x2955,
+ 0x51cf, 0x0868,
+ 0x51d0, 0x2956,
+ 0x51d1, 0x0558,
+ 0x51d2, 0x2957,
+ 0x51db, 0x0a26,
+ 0x51dc, 0x2960,
+ 0x51dd, 0x0b60,
+ 0x51de, 0x2961,
+ 0x51e0, 0x082b,
+ 0x51e1, 0x064f,
+ 0x51e2, 0x2963,
+ 0x51e4, 0x068c,
+ 0x51e5, 0x2965,
+ 0x51eb, 0x1300,
+ 0x51ec, 0x296b,
+ 0x51ed, 0x0bdd,
+ 0x51ee, 0x296c,
+ 0x51ef, 0x093a,
+ 0x51f0, 0x07e0,
+ 0x51f1, 0x1fd9,
+ 0x51f2, 0x296d,
+ 0x51f3, 0x05ab,
+ 0x51f4, 0x296e,
+ 0x51f5, 0x1399,
+ 0x51f6, 0x0fa2,
+ 0x51f7, 0x296f,
+ 0x51f8, 0x0e6a,
+ 0x51f9, 0x03c7,
+ 0x51fa, 0x051b,
+ 0x51fb, 0x080c,
+ 0x51fc, 0x139a,
+ 0x51fd, 0x0766,
+ 0x51fe, 0x2970,
+ 0x51ff, 0x1127,
+ 0x5200, 0x0597,
+ 0x5201, 0x05d4,
+ 0x5202, 0x128c,
+ 0x5203, 0x0cab,
+ 0x5204, 0x2971,
+ 0x5206, 0x0673,
+ 0x5207, 0x0c4d,
+ 0x5208, 0x128d,
+ 0x5209, 0x2973,
+ 0x520a, 0x093c,
+ 0x520b, 0x2974,
+ 0x520d, 0x138b,
+ 0x520e, 0x128e,
+ 0x520f, 0x2976,
+ 0x5211, 0x0f97,
+ 0x5212, 0x07c3,
+ 0x5213, 0x2978,
+ 0x5216, 0x196e,
+ 0x5217, 0x0a19,
+ 0x5218, 0x0a3e,
+ 0x5219, 0x1135,
+ 0x521a, 0x06d0,
+ 0x521b, 0x0537,
+ 0x521c, 0x297b,
+ 0x521d, 0x051a,
+ 0x521e, 0x297c,
+ 0x5220, 0x0cf7,
+ 0x5221, 0x297e,
+ 0x5224, 0x0b91,
+ 0x5225, 0x2981,
+ 0x5228, 0x0b9a,
+ 0x5229, 0x09e6,
+ 0x522a, 0x2984,
+ 0x522b, 0x0459,
+ 0x522c, 0x2985,
+ 0x522d, 0x128f,
+ 0x522e, 0x0727,
+ 0x522f, 0x2986,
+ 0x5230, 0x059e,
+ 0x5231, 0x2987,
+ 0x5233, 0x1290,
+ 0x5234, 0x2989,
+ 0x5236, 0x11c5,
+ 0x5237, 0x0d97,
+ 0x5238, 0x0c8a,
+ 0x5239, 0x0ceb,
+ 0x523a, 0x054f,
+ 0x523b, 0x0959,
+ 0x523c, 0x298b,
+ 0x523d, 0x074d,
+ 0x523e, 0x298c,
+ 0x523f, 0x1291,
+ 0x5241, 0x0626,
+ 0x5242, 0x0834,
+ 0x5243, 0x0e3d,
+ 0x5244, 0x22c8,
+ 0x5245, 0x298d,
+ 0x5247, 0x2263,
+ 0x5248, 0x298f,
+ 0x524a, 0x0f64,
+ 0x524b, 0x2683,
+ 0x524c, 0x1293,
+ 0x524d, 0x0c2d,
+ 0x524e, 0x2991,
+ 0x5250, 0x0729,
+ 0x5251, 0x0874,
+ 0x5252, 0x2993,
+ 0x5254, 0x0e31,
+ 0x5255, 0x2995,
+ 0x5256, 0x0be9,
+ 0x5257, 0x2996,
+ 0x525b, 0x1f17,
+ 0x525c, 0x1296,
+ 0x525d, 0x299a,
+ 0x525e, 0x1294,
+ 0x525f, 0x299b,
+ 0x5261, 0x1295,
+ 0x5262, 0x299d,
+ 0x5265, 0x0409,
+ 0x5266, 0x29a0,
+ 0x5267, 0x0916,
+ 0x5268, 0x29a1,
+ 0x5269, 0x0d3a,
+ 0x526a, 0x0867,
+ 0x526b, 0x29a2,
+ 0x526e, 0x1f2b,
+ 0x526f, 0x06ac,
+ 0x5270, 0x29a5,
+ 0x5272, 0x06e9,
+ 0x5273, 0x29a7,
+ 0x5274, 0x22ca,
+ 0x5275, 0x1e99,
+ 0x5276, 0x29a8,
+ 0x527d, 0x1298,
+ 0x527e, 0x29af,
+ 0x527f, 0x089c,
+ 0x5280, 0x29b0,
+ 0x5281, 0x129a,
+ 0x5282, 0x1299,
+ 0x5283, 0x1f4f,
+ 0x5284, 0x29b1,
+ 0x5287, 0x1fcf,
+ 0x5288, 0x0bbd,
+ 0x5289, 0x2036,
+ 0x528a, 0x1f3a,
+ 0x528b, 0x29b4,
+ 0x528c, 0x22c9,
+ 0x528d, 0x1f99,
+ 0x528e, 0x29b5,
+ 0x5290, 0x129b,
+ 0x5291, 0x1f75,
+ 0x5292, 0x29b7,
+ 0x5293, 0x129c,
+ 0x5294, 0x29b8,
+ 0x529b, 0x09ef,
+ 0x529c, 0x29bf,
+ 0x529d, 0x0c8b,
+ 0x529e, 0x03f7,
+ 0x529f, 0x06ff,
+ 0x52a0, 0x0846,
+ 0x52a1, 0x0f00,
+ 0x52a2, 0x138d,
+ 0x52a3, 0x0a1c,
+ 0x52a4, 0x29c0,
+ 0x52a8, 0x05ee,
+ 0x52a9, 0x11f9,
+ 0x52aa, 0x0b6d,
+ 0x52ab, 0x08aa,
+ 0x52ac, 0x138e,
+ 0x52ae, 0x29c4,
+ 0x52b1, 0x09e3,
+ 0x52b2, 0x08d1,
+ 0x52b3, 0x09b8,
+ 0x52b4, 0x29c7,
+ 0x52be, 0x1390,
+ 0x52bf, 0x0d5d,
+ 0x52c0, 0x29d1,
+ 0x52c1, 0x1fbe,
+ 0x52c2, 0x29d2,
+ 0x52c3, 0x0471,
+ 0x52c4, 0x29d3,
+ 0x52c7, 0x10a7,
+ 0x52c8, 0x29d6,
+ 0x52c9, 0x0ae8,
+ 0x52ca, 0x29d7,
+ 0x52cb, 0x0fd4,
+ 0x52cc, 0x29d8,
+ 0x52d0, 0x1392,
+ 0x52d1, 0x29dc,
+ 0x52d2, 0x09c0,
+ 0x52d3, 0x29dd,
+ 0x52d5, 0x1ecd,
+ 0x52d6, 0x1393,
+ 0x52d7, 0x29df,
+ 0x52d8, 0x093e,
+ 0x52d9, 0x21a9,
+ 0x52da, 0x29e0,
+ 0x52db, 0x21e6,
+ 0x52dc, 0x29e1,
+ 0x52dd, 0x2127,
+ 0x52de, 0x2003,
+ 0x52df, 0x0b1f,
+ 0x52e0, 0x29e2,
+ 0x52e2, 0x2132,
+ 0x52e3, 0x29e4,
+ 0x52e4, 0x0c57,
+ 0x52e5, 0x29e5,
+ 0x52f0, 0x1394,
+ 0x52f1, 0x2323,
+ 0x52f2, 0x29f0,
+ 0x52f5, 0x2011,
+ 0x52f6, 0x29f3,
+ 0x52f8, 0x20f5,
+ 0x52f9, 0x12fc,
+ 0x52fa, 0x0d10,
+ 0x52fb, 0x29f5,
+ 0x52fe, 0x070d,
+ 0x52ff, 0x0eff,
+ 0x5300, 0x110b,
+ 0x5301, 0x29f8,
+ 0x5305, 0x0407,
+ 0x5306, 0x0555,
+ 0x5307, 0x29fc,
+ 0x5308, 0x0fa4,
+ 0x5309, 0x29fd,
+ 0x530d, 0x12fd,
+ 0x530e, 0x2a01,
+ 0x530f, 0x14b5,
+ 0x5310, 0x12ff,
+ 0x5311, 0x2a02,
+ 0x5315, 0x1266,
+ 0x5316, 0x07c4,
+ 0x5317, 0x041a,
+ 0x5318, 0x2a06,
+ 0x5319, 0x04fc,
+ 0x531a, 0x1284,
+ 0x531b, 0x2a07,
+ 0x531d, 0x1114,
+ 0x531e, 0x2a09,
+ 0x5320, 0x0884,
+ 0x5321, 0x097c,
+ 0x5322, 0x2a0b,
+ 0x5323, 0x0f28,
+ 0x5324, 0x2a0c,
+ 0x5326, 0x1286,
+ 0x5327, 0x2a0e,
+ 0x532a, 0x0668,
+ 0x532b, 0x2a11,
+ 0x532d, 0x22c5,
+ 0x532e, 0x1287,
+ 0x532f, 0x1f5e,
+ 0x5330, 0x2a13,
+ 0x5331, 0x22c6,
+ 0x5332, 0x2a14,
+ 0x5339, 0x0bc4,
+ 0x533a, 0x0c75,
+ 0x533b, 0x1044,
+ 0x533c, 0x2a1b,
+ 0x533e, 0x1288,
+ 0x533f, 0x0b47,
+ 0x5340, 0x20ef,
+ 0x5341, 0x0d45,
+ 0x5342, 0x2a1d,
+ 0x5343, 0x0c24,
+ 0x5344, 0x2a1e,
+ 0x5345, 0x125c,
+ 0x5346, 0x2a1f,
+ 0x5347, 0x0d36,
+ 0x5348, 0x0ef6,
+ 0x5349, 0x07f1,
+ 0x534a, 0x03f6,
+ 0x534b, 0x2a20,
+ 0x534e, 0x07bf,
+ 0x534f, 0x0f78,
+ 0x5350, 0x2a23,
+ 0x5351, 0x0419,
+ 0x5352, 0x1241,
+ 0x5353, 0x121c,
+ 0x5354, 0x21d0,
+ 0x5355, 0x0586,
+ 0x5356, 0x0a9b,
+ 0x5357, 0x0b32,
+ 0x5358, 0x2a24,
+ 0x535a, 0x0470,
+ 0x535b, 0x2a26,
+ 0x535c, 0x047e,
+ 0x535d, 0x2a27,
+ 0x535e, 0x044e,
+ 0x535f, 0x14fa,
+ 0x5360, 0x115d,
+ 0x5361, 0x0935,
+ 0x5362, 0x0a53,
+ 0x5363, 0x128b,
+ 0x5364, 0x0a58,
+ 0x5365, 0x2a28,
+ 0x5366, 0x128a,
+ 0x5367, 0x0ee3,
+ 0x5368, 0x2a29,
+ 0x5369, 0x1352,
+ 0x536a, 0x2a2a,
+ 0x536b, 0x0ecf,
+ 0x536c, 0x2a2b,
+ 0x536e, 0x126a,
+ 0x536f, 0x0ab3,
+ 0x5370, 0x1086,
+ 0x5371, 0x0eb2,
+ 0x5372, 0x2a2d,
+ 0x5373, 0x0827,
+ 0x5374, 0x0c8f,
+ 0x5375, 0x0a78,
+ 0x5376, 0x2a2e,
+ 0x5377, 0x091c,
+ 0x5378, 0x0f81,
+ 0x5379, 0x2a2f,
+ 0x537a, 0x1353,
+ 0x537b, 0x2a30,
+ 0x537f, 0x0c61,
+ 0x5380, 0x2a34,
+ 0x5382, 0x04cc,
+ 0x5383, 0x2a36,
+ 0x5384, 0x0631,
+ 0x5385, 0x0e4f,
+ 0x5386, 0x09e5,
+ 0x5387, 0x2a37,
+ 0x5389, 0x09e2,
+ 0x538a, 0x2a39,
+ 0x538b, 0x0fe2,
+ 0x538c, 0x100a,
+ 0x538d, 0x127d,
+ 0x538e, 0x2a3a,
+ 0x5395, 0x04a5,
+ 0x5396, 0x2a41,
+ 0x5398, 0x09d0,
+ 0x5399, 0x22c1,
+ 0x539a, 0x07a8,
+ 0x539b, 0x2a43,
+ 0x539d, 0x127e,
+ 0x539e, 0x2a45,
+ 0x539f, 0x10f0,
+ 0x53a0, 0x1e64,
+ 0x53a1, 0x2a46,
+ 0x53a2, 0x0f4e,
+ 0x53a3, 0x127f,
+ 0x53a4, 0x2a47,
+ 0x53a5, 0x1280,
+ 0x53a6, 0x0f30,
+ 0x53a7, 0x2a48,
+ 0x53a8, 0x051d,
+ 0x53a9, 0x08f6,
+ 0x53aa, 0x2a49,
+ 0x53ad, 0x21f9,
+ 0x53ae, 0x1281,
+ 0x53af, 0x2a4c,
+ 0x53b2, 0x2010,
+ 0x53b3, 0x2a4f,
+ 0x53b4, 0x22c2,
+ 0x53b5, 0x2a50,
+ 0x53b6, 0x139c,
+ 0x53b7, 0x2a51,
+ 0x53bb, 0x0c80,
+ 0x53bc, 0x2a55,
+ 0x53bf, 0x0f45,
+ 0x53c0, 0x2a58,
+ 0x53c1, 0x0cd9,
+ 0x53c2, 0x0495,
+ 0x53c3, 0x1e5a,
+ 0x53c4, 0x2a59,
+ 0x53c8, 0x10bb,
+ 0x53c9, 0x04ad,
+ 0x53ca, 0x0823,
+ 0x53cb, 0x10b6,
+ 0x53cc, 0x0da0,
+ 0x53cd, 0x0651,
+ 0x53ce, 0x2a5d,
+ 0x53d1, 0x063f,
+ 0x53d2, 0x2a60,
+ 0x53d4, 0x0d7c,
+ 0x53d5, 0x2a62,
+ 0x53d6, 0x0c7c,
+ 0x53d7, 0x0d73,
+ 0x53d8, 0x044d,
+ 0x53d9, 0x0fbb,
+ 0x53da, 0x2a63,
+ 0x53db, 0x0b92,
+ 0x53dc, 0x2a64,
+ 0x53df, 0x1395,
+ 0x53e0, 0x05df,
+ 0x53e1, 0x2a67,
+ 0x53e2, 0x1ea2,
+ 0x53e3, 0x0967,
+ 0x53e4, 0x071e,
+ 0x53e5, 0x0913,
+ 0x53e6, 0x0a36,
+ 0x53e7, 0x2a68,
+ 0x53e8, 0x14fe,
+ 0x53e9, 0x14fd,
+ 0x53ea, 0x11ba,
+ 0x53eb, 0x08a1,
+ 0x53ec, 0x117a,
+ 0x53ed, 0x03d3,
+ 0x53ee, 0x05e2,
+ 0x53ef, 0x0956,
+ 0x53f0, 0x0dfb,
+ 0x53f1, 0x14fb,
+ 0x53f2, 0x0d4e,
+ 0x53f3, 0x10b7,
+ 0x53f4, 0x2a69,
+ 0x53f5, 0x1285,
+ 0x53f6, 0x103d,
+ 0x53f7, 0x077c,
+ 0x53f8, 0x0db3,
+ 0x53f9, 0x0e11,
+ 0x53fa, 0x2a6a,
+ 0x53fb, 0x14ff,
+ 0x53fc, 0x05d1,
+ 0x53fd, 0x14fc,
+ 0x53fe, 0x2a6b,
+ 0x5400, 0x2a6d,
+ 0x5401, 0x10da,
+ 0x5402, 0x2a6e,
+ 0x5403, 0x04f9,
+ 0x5404, 0x06f2,
+ 0x5405, 0x2a6f,
+ 0x5406, 0x1502,
+ 0x5407, 0x2a70,
+ 0x5408, 0x0786,
+ 0x5409, 0x081d,
+ 0x540a, 0x05d6,
+ 0x540b, 0x2a71,
+ 0x540c, 0x0e5d,
+ 0x540d, 0x0b00,
+ 0x540e, 0x07aa,
+ 0x540f, 0x09df,
+ 0x5410, 0x0e73,
+ 0x5411, 0x0f5f,
+ 0x5412, 0x1500,
+ 0x5413, 0x0f32,
+ 0x5414, 0x2a72,
+ 0x5415, 0x0a67,
+ 0x5416, 0x1501,
+ 0x5417, 0x0a97,
+ 0x5418, 0x2a73,
+ 0x541b, 0x092c,
+ 0x541c, 0x2a76,
+ 0x541d, 0x0a28,
+ 0x541e, 0x0e7d,
+ 0x541f, 0x107e,
+ 0x5420, 0x066a,
+ 0x5421, 0x1509,
+ 0x5422, 0x2a77,
+ 0x5423, 0x150c,
+ 0x5424, 0x2a78,
+ 0x5426, 0x068e,
+ 0x5427, 0x03d4,
+ 0x5428, 0x0615,
+ 0x5429, 0x0671,
+ 0x542a, 0x2a7a,
+ 0x542b, 0x0763,
+ 0x542c, 0x0e50,
+ 0x542d, 0x0961,
+ 0x542e, 0x0da6,
+ 0x542f, 0x0c13,
+ 0x5430, 0x2a7b,
+ 0x5431, 0x11a7,
+ 0x5432, 0x150d,
+ 0x5433, 0x2a7c,
+ 0x5434, 0x0ef1,
+ 0x5435, 0x04d8,
+ 0x5436, 0x2a7d,
+ 0x5438, 0x0f0b,
+ 0x5439, 0x0538,
+ 0x543a, 0x2a7f,
+ 0x543b, 0x0ed6,
+ 0x543c, 0x07a7,
+ 0x543d, 0x2a80,
+ 0x543e, 0x0ef0,
+ 0x543f, 0x2a81,
+ 0x5440, 0x0fe6,
+ 0x5441, 0x2a82,
+ 0x5443, 0x1508,
+ 0x5444, 0x2a84,
+ 0x5446, 0x0577,
+ 0x5447, 0x2a86,
+ 0x5448, 0x04ef,
+ 0x5449, 0x2a87,
+ 0x544a, 0x06e1,
+ 0x544b, 0x1503,
+ 0x544c, 0x2a88,
+ 0x5450, 0x0b28,
+ 0x5451, 0x2a8c,
+ 0x5452, 0x1504,
+ 0x5455, 0x0b7c,
+ 0x5456, 0x1507,
+ 0x5457, 0x150a,
+ 0x5458, 0x10f4,
+ 0x5459, 0x150b,
+ 0x545a, 0x2a8d,
+ 0x545b, 0x0c37,
+ 0x545c, 0x0ee7,
+ 0x545d, 0x2a8e,
+ 0x5462, 0x0b3b,
+ 0x5463, 0x2a93,
+ 0x5464, 0x1512,
+ 0x5465, 0x2a94,
+ 0x5466, 0x1517,
+ 0x5467, 0x2a95,
+ 0x5468, 0x11db,
+ 0x5469, 0x2a96,
+ 0x5471, 0x1511,
+ 0x5472, 0x1522,
+ 0x5473, 0x0ec5,
+ 0x5474, 0x2a9e,
+ 0x5475, 0x077e,
+ 0x5476, 0x1516,
+ 0x5477, 0x1510,
+ 0x5478, 0x0b9f,
+ 0x5479, 0x2a9f,
+ 0x547b, 0x0d24,
+ 0x547c, 0x07ab,
+ 0x547d, 0x0b01,
+ 0x547e, 0x2aa1,
+ 0x5480, 0x0906,
+ 0x5481, 0x2aa3,
+ 0x5482, 0x150e,
+ 0x5483, 0x2aa4,
+ 0x5484, 0x1515,
+ 0x5485, 0x2aa5,
+ 0x5486, 0x0b99,
+ 0x5487, 0x2aa6,
+ 0x548b, 0x1147,
+ 0x548c, 0x0784,
+ 0x548d, 0x2aaa,
+ 0x548e, 0x08fb,
+ 0x548f, 0x10a2,
+ 0x5490, 0x06bb,
+ 0x5491, 0x2aab,
+ 0x5492, 0x11e3,
+ 0x5493, 0x2aac,
+ 0x5494, 0x150f,
+ 0x5495, 0x0717,
+ 0x5496, 0x0934,
+ 0x5497, 0x2aad,
+ 0x5499, 0x0a45,
+ 0x549a, 0x1513,
+ 0x549c, 0x2aaf,
+ 0x549d, 0x1518,
+ 0x549e, 0x2ab0,
+ 0x54a3, 0x1523,
+ 0x54a4, 0x152d,
+ 0x54a5, 0x2ab5,
+ 0x54a6, 0x151f,
+ 0x54a7, 0x151e,
+ 0x54a8, 0x1226,
+ 0x54a9, 0x152b,
+ 0x54ab, 0x1767,
+ 0x54ac, 0x102e,
+ 0x54ad, 0x151a,
+ 0x54ae, 0x2ab6,
+ 0x54af, 0x0936,
+ 0x54b0, 0x2ab7,
+ 0x54b1, 0x111e,
+ 0x54b2, 0x2ab8,
+ 0x54b3, 0x0955,
+ 0x54b4, 0x151c,
+ 0x54b5, 0x2ab9,
+ 0x54b8, 0x0f39,
+ 0x54b9, 0x2abc,
+ 0x54bb, 0x1525,
+ 0x54bc, 0x236d,
+ 0x54bd, 0x0ff3,
+ 0x54be, 0x2abe,
+ 0x54bf, 0x1526,
+ 0x54c0, 0x03b2,
+ 0x54c1, 0x0bd6,
+ 0x54c2, 0x151b,
+ 0x54c3, 0x2abf,
+ 0x54c4, 0x079c,
+ 0x54c5, 0x2ac0,
+ 0x54c6, 0x061e,
+ 0x54c7, 0x0e8c,
+ 0x54c8, 0x0757,
+ 0x54c9, 0x1118,
+ 0x54ca, 0x2ac1,
+ 0x54cc, 0x1527,
+ 0x54cd, 0x0f59,
+ 0x54ce, 0x03b0,
+ 0x54cf, 0x152f,
+ 0x54d0, 0x1519,
+ 0x54d1, 0x0fef,
+ 0x54d2, 0x151d,
+ 0x54d3, 0x1520,
+ 0x54d5, 0x1524,
+ 0x54d6, 0x2ac3,
+ 0x54d7, 0x07be,
+ 0x54d8, 0x2ac4,
+ 0x54d9, 0x1528,
+ 0x54db, 0x2ac5,
+ 0x54dc, 0x152a,
+ 0x54dd, 0x152e,
+ 0x54de, 0x1530,
+ 0x54df, 0x1099,
+ 0x54e0, 0x2ac6,
+ 0x54e1, 0x2247,
+ 0x54e2, 0x2ac7,
+ 0x54e5, 0x06e2,
+ 0x54e6, 0x0b77,
+ 0x54e7, 0x1532,
+ 0x54e8, 0x0d13,
+ 0x54e9, 0x09f1,
+ 0x54ea, 0x0b27,
+ 0x54eb, 0x2aca,
+ 0x54ed, 0x096b,
+ 0x54ee, 0x0f65,
+ 0x54ef, 0x2acc,
+ 0x54f2, 0x117d,
+ 0x54f3, 0x1536,
+ 0x54f4, 0x2acf,
+ 0x54fa, 0x047f,
+ 0x54fb, 0x2ad5,
+ 0x54fc, 0x0796,
+ 0x54fd, 0x1534,
+ 0x54fe, 0x2ad6,
+ 0x54ff, 0x1391,
+ 0x5500, 0x2ad7,
+ 0x5501, 0x100d,
+ 0x5502, 0x2ad8,
+ 0x5504, 0x236c,
+ 0x5505, 0x2ada,
+ 0x5506, 0x0de9,
+ 0x5507, 0x0540,
+ 0x5508, 0x2adb,
+ 0x5509, 0x03b1,
+ 0x550a, 0x2adc,
+ 0x550f, 0x1539,
+ 0x5510, 0x0e19,
+ 0x5511, 0x153a,
+ 0x5512, 0x2ae1,
+ 0x5514, 0x1535,
+ 0x5515, 0x2ae3,
+ 0x551b, 0x1531,
+ 0x551c, 0x2ae9,
+ 0x5520, 0x1533,
+ 0x5521, 0x2aed,
+ 0x5522, 0x1537,
+ 0x5524, 0x07d2,
+ 0x5525, 0x2aee,
+ 0x5527, 0x153b,
+ 0x5528, 0x2af0,
+ 0x552a, 0x153c,
+ 0x552b, 0x2af2,
+ 0x552c, 0x07b8,
+ 0x552d, 0x2af3,
+ 0x552e, 0x0d72,
+ 0x552f, 0x0eb7,
+ 0x5530, 0x154d,
+ 0x5531, 0x04cf,
+ 0x5532, 0x2af4,
+ 0x5533, 0x154c,
+ 0x5534, 0x2af5,
+ 0x5537, 0x1547,
+ 0x5538, 0x2af8,
+ 0x553c, 0x1546,
+ 0x553d, 0x2afc,
+ 0x553e, 0x0e8a,
+ 0x553f, 0x1544,
+ 0x5540, 0x2afd,
+ 0x5541, 0x1542,
+ 0x5542, 0x2afe,
+ 0x5543, 0x095d,
+ 0x5544, 0x1221,
+ 0x5545, 0x2aff,
+ 0x5546, 0x0d05,
+ 0x5547, 0x2b00,
+ 0x5549, 0x1540,
+ 0x554a, 0x03ac,
+ 0x554b, 0x2b02,
+ 0x554f, 0x219c,
+ 0x5550, 0x1545,
+ 0x5551, 0x2b06,
+ 0x5553, 0x20c9,
+ 0x5554, 0x2b08,
+ 0x5555, 0x1543,
+ 0x5556, 0x1548,
+ 0x5557, 0x2b09,
+ 0x555c, 0x154e,
+ 0x555d, 0x2b0e,
+ 0x555e, 0x21f0,
+ 0x555f, 0x2b0f,
+ 0x5561, 0x0665,
+ 0x5562, 0x2b11,
+ 0x5564, 0x0bc0,
+ 0x5565, 0x0cef,
+ 0x5566, 0x099d,
+ 0x5567, 0x153d,
+ 0x5568, 0x2b13,
+ 0x556a, 0x0b7f,
+ 0x556b, 0x2b15,
+ 0x556c, 0x127a,
+ 0x556d, 0x1541,
+ 0x556e, 0x0b59,
+ 0x556f, 0x2b16,
+ 0x5575, 0x1549,
+ 0x5578, 0x0f70,
+ 0x5579, 0x2b1c,
+ 0x557b, 0x155a,
+ 0x557c, 0x0e37,
+ 0x557d, 0x2b1e,
+ 0x557e, 0x1557,
+ 0x557f, 0x2b1f,
+ 0x5580, 0x0933,
+ 0x5581, 0x1555,
+ 0x5582, 0x0ec8,
+ 0x5583, 0x1551,
+ 0x5584, 0x0cff,
+ 0x5585, 0x2b20,
+ 0x5587, 0x0999,
+ 0x5588, 0x1554,
+ 0x5589, 0x07a4,
+ 0x558a, 0x0767,
+ 0x558b, 0x154f,
+ 0x558c, 0x2b22,
+ 0x558f, 0x153e,
+ 0x5590, 0x2b25,
+ 0x5591, 0x1559,
+ 0x5592, 0x2b26,
+ 0x5594, 0x155e,
+ 0x5595, 0x2b28,
+ 0x5598, 0x0530,
+ 0x5599, 0x155f,
+ 0x559a, 0x2b2b,
+ 0x559c, 0x0f1f,
+ 0x559d, 0x077f,
+ 0x559e, 0x2b2d,
+ 0x559f, 0x1556,
+ 0x55a0, 0x2b2e,
+ 0x55a7, 0x0fc5,
+ 0x55a8, 0x2b35,
+ 0x55aa, 0x210b,
+ 0x55ab, 0x2b37,
+ 0x55ac, 0x20de,
+ 0x55ad, 0x2b38,
+ 0x55ae, 0x1eaa,
+ 0x55af, 0x2b39,
+ 0x55b1, 0x1552,
+ 0x55b2, 0x222c,
+ 0x55b3, 0x113e,
+ 0x55b4, 0x2b3b,
+ 0x55b5, 0x153f,
+ 0x55b6, 0x2b3c,
+ 0x55b7, 0x0ba8,
+ 0x55b8, 0x2b3d,
+ 0x55b9, 0x1553,
+ 0x55ba, 0x2b3e,
+ 0x55bb, 0x10dc,
+ 0x55bc, 0x2b3f,
+ 0x55bd, 0x155c,
+ 0x55bf, 0x2b40,
+ 0x55c4, 0x156a,
+ 0x55c5, 0x0fac,
+ 0x55c6, 0x20d8,
+ 0x55c7, 0x22c0,
+ 0x55c8, 0x2b45,
+ 0x55c9, 0x1562,
+ 0x55ca, 0x2b46,
+ 0x55cc, 0x156f,
+ 0x55ce, 0x206f,
+ 0x55cf, 0x2b48,
+ 0x55d1, 0x1564,
+ 0x55d2, 0x1550,
+ 0x55d3, 0x0cdd,
+ 0x55d4, 0x1567,
+ 0x55d5, 0x2b4a,
+ 0x55d6, 0x1558,
+ 0x55d7, 0x2b4b,
+ 0x55da, 0x21a1,
+ 0x55db, 0x2b4e,
+ 0x55dc, 0x0d5f,
+ 0x55dd, 0x1569,
+ 0x55de, 0x2b4f,
+ 0x55df, 0x155b,
+ 0x55e0, 0x2b50,
+ 0x55e1, 0x0eda,
+ 0x55e2, 0x2b51,
+ 0x55e3, 0x0db8,
+ 0x55e4, 0x1573,
+ 0x55e5, 0x156c,
+ 0x55e6, 0x1568,
+ 0x55e7, 0x2b52,
+ 0x55e8, 0x1571,
+ 0x55e9, 0x2379,
+ 0x55ea, 0x1560,
+ 0x55eb, 0x1565,
+ 0x55ed, 0x2b53,
+ 0x55ef, 0x156b,
+ 0x55f0, 0x2b55,
+ 0x55f2, 0x156d,
+ 0x55f4, 0x2b57,
+ 0x55f5, 0x1572,
+ 0x55f6, 0x2372,
+ 0x55f7, 0x1561,
+ 0x55f8, 0x2b58,
+ 0x55fd, 0x0dc9,
+ 0x55fe, 0x157b,
+ 0x55ff, 0x2b5d,
+ 0x5600, 0x157c,
+ 0x5601, 0x1578,
+ 0x5602, 0x2b5e,
+ 0x5606, 0x216a,
+ 0x5607, 0x2b62,
+ 0x5608, 0x1576,
+ 0x5609, 0x0841,
+ 0x560a, 0x2b63,
+ 0x560c, 0x1577,
+ 0x560d, 0x237c,
+ 0x560e, 0x06bd,
+ 0x560f, 0x127b,
+ 0x5610, 0x2b65,
+ 0x5614, 0x20b0,
+ 0x5615, 0x2b69,
+ 0x5616, 0x237a,
+ 0x5617, 0x1e74,
+ 0x5618, 0x0fb5,
+ 0x5619, 0x2b6a,
+ 0x561b, 0x0a96,
+ 0x561c, 0x2377,
+ 0x561d, 0x2b6c,
+ 0x561e, 0x1575,
+ 0x561f, 0x1563,
+ 0x5620, 0x2b6d,
+ 0x5623, 0x157a,
+ 0x5624, 0x1579,
+ 0x5625, 0x2b70,
+ 0x5627, 0x157d,
+ 0x5628, 0x2b72,
+ 0x5629, 0x1f4c,
+ 0x562a, 0x2b73,
+ 0x562c, 0x1582,
+ 0x562d, 0x157e,
+ 0x562e, 0x2378,
+ 0x562f, 0x21cf,
+ 0x5630, 0x2368,
+ 0x5631, 0x11f5,
+ 0x5632, 0x04d5,
+ 0x5633, 0x2b75,
+ 0x5634, 0x1249,
+ 0x5635, 0x2371,
+ 0x5636, 0x0db0,
+ 0x5637, 0x2b76,
+ 0x5638, 0x2369,
+ 0x5639, 0x1580,
+ 0x563a, 0x2b77,
+ 0x563b, 0x0f0a,
+ 0x563c, 0x2b78,
+ 0x563f, 0x0790,
+ 0x5640, 0x2b7b,
+ 0x5641, 0x2674,
+ 0x5642, 0x2b7c,
+ 0x564c, 0x1587,
+ 0x564d, 0x1583,
+ 0x564e, 0x1034,
+ 0x564f, 0x2b86,
+ 0x5654, 0x1588,
+ 0x5655, 0x2b8b,
+ 0x5657, 0x1581,
+ 0x5658, 0x157f,
+ 0x5659, 0x1585,
+ 0x565a, 0x2b8d,
+ 0x565c, 0x1586,
+ 0x565d, 0x236f,
+ 0x565e, 0x2b8f,
+ 0x5660, 0x2370,
+ 0x5661, 0x2b91,
+ 0x5662, 0x1584,
+ 0x5663, 0x2b92,
+ 0x5664, 0x158a,
+ 0x5665, 0x2376,
+ 0x5666, 0x2373,
+ 0x5667, 0x2b93,
+ 0x5668, 0x0c16,
+ 0x5669, 0x1262,
+ 0x566a, 0x112e,
+ 0x566b, 0x158c,
+ 0x566c, 0x0d60,
+ 0x566d, 0x2b94,
+ 0x566f, 0x237f,
+ 0x5670, 0x2b96,
+ 0x5671, 0x158b,
+ 0x5672, 0x2374,
+ 0x5673, 0x2b97,
+ 0x5674, 0x20b5,
+ 0x5675, 0x2b98,
+ 0x5676, 0x06bc,
+ 0x5677, 0x2b99,
+ 0x5678, 0x1edb,
+ 0x5679, 0x2672,
+ 0x567a, 0x2b9a,
+ 0x567b, 0x158d,
+ 0x567d, 0x2b9b,
+ 0x5680, 0x236e,
+ 0x5681, 0x2b9e,
+ 0x5685, 0x158f,
+ 0x5686, 0x1589,
+ 0x5687, 0x21b7,
+ 0x5688, 0x2ba2,
+ 0x568c, 0x2375,
+ 0x568d, 0x2ba6,
+ 0x568e, 0x0776,
+ 0x568f, 0x0e3a,
+ 0x5690, 0x2ba7,
+ 0x5693, 0x1590,
+ 0x5694, 0x2baa,
+ 0x5695, 0x2382,
+ 0x5696, 0x2bab,
+ 0x5699, 0x209e,
+ 0x569a, 0x2bae,
+ 0x56a3, 0x0f66,
+ 0x56a4, 0x2bb7,
+ 0x56a6, 0x236b,
+ 0x56a7, 0x2bb9,
+ 0x56a8, 0x2039,
+ 0x56a9, 0x2bba,
+ 0x56ae, 0x269f,
+ 0x56af, 0x1591,
+ 0x56b0, 0x2bbf,
+ 0x56b3, 0x237d,
+ 0x56b4, 0x21f5,
+ 0x56b5, 0x2bc2,
+ 0x56b6, 0x2381,
+ 0x56b7, 0x0c9d,
+ 0x56b8, 0x2bc3,
+ 0x56bc, 0x0891,
+ 0x56bd, 0x2bc7,
+ 0x56c0, 0x237b,
+ 0x56c1, 0x237e,
+ 0x56c2, 0x21cc,
+ 0x56c3, 0x2bca,
+ 0x56c5, 0x22db,
+ 0x56c6, 0x2bcc,
+ 0x56c8, 0x236a,
+ 0x56c9, 0x2689,
+ 0x56ca, 0x0b35,
+ 0x56cb, 0x2bce,
+ 0x56cc, 0x2697,
+ 0x56cd, 0x2bcf,
+ 0x56d1, 0x22a1,
+ 0x56d2, 0x2bd3,
+ 0x56d4, 0x1592,
+ 0x56d5, 0x2bd5,
+ 0x56d7, 0x1593,
+ 0x56d8, 0x2bd7,
+ 0x56da, 0x0c71,
+ 0x56db, 0x0db9,
+ 0x56dc, 0x2bd9,
+ 0x56dd, 0x1594,
+ 0x56de, 0x07ed,
+ 0x56df, 0x126c,
+ 0x56e0, 0x1079,
+ 0x56e1, 0x1595,
+ 0x56e2, 0x0e76,
+ 0x56e3, 0x2bda,
+ 0x56e4, 0x0619,
+ 0x56e5, 0x2bdb,
+ 0x56eb, 0x1597,
+ 0x56ec, 0x2be1,
+ 0x56ed, 0x10f3,
+ 0x56ee, 0x2be2,
+ 0x56f0, 0x0992,
+ 0x56f1, 0x0554,
+ 0x56f2, 0x2be4,
+ 0x56f4, 0x0eb6,
+ 0x56f5, 0x1596,
+ 0x56f6, 0x2be6,
+ 0x56f9, 0x1598,
+ 0x56fa, 0x0725,
+ 0x56fb, 0x2be9,
+ 0x56fd, 0x0753,
+ 0x56fe, 0x0e6d,
+ 0x56ff, 0x1599,
+ 0x5700, 0x2beb,
+ 0x5703, 0x0bf3,
+ 0x5704, 0x159a,
+ 0x5705, 0x2bee,
+ 0x5706, 0x10f5,
+ 0x5707, 0x2383,
+ 0x5708, 0x0c81,
+ 0x5709, 0x159c,
+ 0x570a, 0x159b,
+ 0x570b, 0x1f3d,
+ 0x570c, 0x2bef,
+ 0x570d, 0x218f,
+ 0x570e, 0x2bf0,
+ 0x5712, 0x2246,
+ 0x5713, 0x2248,
+ 0x5714, 0x2bf4,
+ 0x5716, 0x217e,
+ 0x5717, 0x2bf6,
+ 0x5718, 0x2180,
+ 0x5719, 0x2bf7,
+ 0x571c, 0x159d,
+ 0x571d, 0x2bfa,
+ 0x571f, 0x0e72,
+ 0x5720, 0x2bfc,
+ 0x5723, 0x0d3c,
+ 0x5724, 0x2bff,
+ 0x5728, 0x111d,
+ 0x5729, 0x13a7,
+ 0x572a, 0x13a9,
+ 0x572b, 0x2c03,
+ 0x572c, 0x13a8,
+ 0x572d, 0x0740,
+ 0x572e, 0x13ac,
+ 0x5730, 0x05b9,
+ 0x5731, 0x2c04,
+ 0x5733, 0x13aa,
+ 0x5734, 0x2c06,
+ 0x5739, 0x13ab,
+ 0x573a, 0x04c6,
+ 0x573b, 0x13af,
+ 0x573c, 0x2c0b,
+ 0x573e, 0x080d,
+ 0x573f, 0x2c0d,
+ 0x5740, 0x11b6,
+ 0x5741, 0x2c0e,
+ 0x5742, 0x13b0,
+ 0x5743, 0x2c0f,
+ 0x5747, 0x0928,
+ 0x5748, 0x2c13,
+ 0x574a, 0x0658,
+ 0x574b, 0x2c15,
+ 0x574c, 0x13a0,
+ 0x574d, 0x0e01,
+ 0x574e, 0x093f,
+ 0x574f, 0x07ca,
+ 0x5750, 0x1255,
+ 0x5751, 0x0960,
+ 0x5752, 0x2c16,
+ 0x5757, 0x0976,
+ 0x5758, 0x2c1b,
+ 0x575a, 0x0854,
+ 0x575b, 0x0e06,
+ 0x575c, 0x13ae,
+ 0x575d, 0x03de,
+ 0x575e, 0x0efa,
+ 0x575f, 0x0675,
+ 0x5760, 0x1216,
+ 0x5761, 0x0be1,
+ 0x5762, 0x2c1d,
+ 0x5764, 0x098f,
+ 0x5765, 0x2c1f,
+ 0x5766, 0x0e0c,
+ 0x5767, 0x2c20,
+ 0x5768, 0x13b7,
+ 0x5769, 0x13b1,
+ 0x576a, 0x0bd9,
+ 0x576b, 0x13b3,
+ 0x576c, 0x2c21,
+ 0x576d, 0x13b8,
+ 0x576e, 0x2c22,
+ 0x576f, 0x0bb8,
+ 0x5770, 0x2c23,
+ 0x5773, 0x13ba,
+ 0x5774, 0x2c26,
+ 0x5776, 0x13b9,
+ 0x5777, 0x094d,
+ 0x5778, 0x2c28,
+ 0x577b, 0x13b6,
+ 0x577c, 0x13b5,
+ 0x577d, 0x2c2b,
+ 0x5782, 0x053c,
+ 0x5783, 0x0997,
+ 0x5784, 0x0a49,
+ 0x5785, 0x13b2,
+ 0x5786, 0x13b4,
+ 0x5787, 0x2c30,
+ 0x578b, 0x0f98,
+ 0x578c, 0x13bd,
+ 0x578d, 0x2c34,
+ 0x5792, 0x09c8,
+ 0x5793, 0x13c2,
+ 0x5794, 0x2c39,
+ 0x579b, 0x0621,
+ 0x579c, 0x2c40,
+ 0x57a0, 0x13c3,
+ 0x57a1, 0x13a2,
+ 0x57a2, 0x0711,
+ 0x57a3, 0x10ee,
+ 0x57a4, 0x13bc,
+ 0x57a5, 0x2c44,
+ 0x57a6, 0x095e,
+ 0x57a7, 0x13c0,
+ 0x57a8, 0x2c45,
+ 0x57a9, 0x13a1,
+ 0x57aa, 0x2c46,
+ 0x57ab, 0x05c7,
+ 0x57ac, 0x2c47,
+ 0x57ad, 0x13bb,
+ 0x57ae, 0x0972,
+ 0x57af, 0x2c48,
+ 0x57b2, 0x13be,
+ 0x57b3, 0x2c4b,
+ 0x57b4, 0x13c1,
+ 0x57b5, 0x2c4c,
+ 0x57b8, 0x13c9,
+ 0x57b9, 0x2c4f,
+ 0x57c2, 0x06fa,
+ 0x57c3, 0x03ae,
+ 0x57c4, 0x2c58,
+ 0x57cb, 0x0a98,
+ 0x57cc, 0x2c5f,
+ 0x57ce, 0x04ec,
+ 0x57cf, 0x13bf,
+ 0x57d0, 0x2c61,
+ 0x57d2, 0x13c8,
+ 0x57d3, 0x2c63,
+ 0x57d4, 0x0bf1,
+ 0x57d5, 0x13c4,
+ 0x57d6, 0x2c64,
+ 0x57d8, 0x13c5,
+ 0x57d9, 0x13c7,
+ 0x57da, 0x13c6,
+ 0x57db, 0x2c66,
+ 0x57dd, 0x13ce,
+ 0x57de, 0x2c68,
+ 0x57df, 0x10d7,
+ 0x57e0, 0x0481,
+ 0x57e1, 0x232a,
+ 0x57e2, 0x2c69,
+ 0x57e4, 0x13cd,
+ 0x57e5, 0x2c6b,
+ 0x57ed, 0x13d2,
+ 0x57ee, 0x2c73,
+ 0x57ef, 0x13cb,
+ 0x57f0, 0x2c74,
+ 0x57f4, 0x13ca,
+ 0x57f5, 0x2c78,
+ 0x57f7, 0x228b,
+ 0x57f8, 0x13cc,
+ 0x57f9, 0x0ba1,
+ 0x57fa, 0x080e,
+ 0x57fb, 0x2c7a,
+ 0x57fd, 0x13d1,
+ 0x57fe, 0x2c7c,
+ 0x5800, 0x13d3,
+ 0x5801, 0x2c7e,
+ 0x5802, 0x0e16,
+ 0x5803, 0x2c7f,
+ 0x5805, 0x1f85,
+ 0x5806, 0x0610,
+ 0x5807, 0x144c,
+ 0x5808, 0x2c81,
+ 0x580a, 0x2325,
+ 0x580b, 0x13cf,
+ 0x580c, 0x2c83,
+ 0x580d, 0x13d0,
+ 0x580e, 0x2c84,
+ 0x5811, 0x0c32,
+ 0x5812, 0x2c87,
+ 0x5815, 0x0628,
+ 0x5816, 0x232c,
+ 0x5817, 0x2c8a,
+ 0x5819, 0x13d5,
+ 0x581a, 0x2c8c,
+ 0x581d, 0x232e,
+ 0x581e, 0x13d4,
+ 0x581f, 0x2c8f,
+ 0x5820, 0x13d7,
+ 0x5821, 0x040d,
+ 0x5822, 0x2c90,
+ 0x5824, 0x05ad,
+ 0x5825, 0x2c92,
+ 0x582a, 0x093d,
+ 0x582b, 0x2c97,
+ 0x582f, 0x2205,
+ 0x5830, 0x1008,
+ 0x5831, 0x1e38,
+ 0x5832, 0x2c9b,
+ 0x5834, 0x1e73,
+ 0x5835, 0x0601,
+ 0x5836, 0x2c9d,
+ 0x5844, 0x13d6,
+ 0x5845, 0x2cab,
+ 0x584a, 0x1fe3,
+ 0x584b, 0x2339,
+ 0x584c, 0x0def,
+ 0x584d, 0x19a3,
+ 0x584e, 0x2cb0,
+ 0x584f, 0x232b,
+ 0x5850, 0x2cb1,
+ 0x5851, 0x0dd1,
+ 0x5852, 0x232d,
+ 0x5853, 0x2cb2,
+ 0x5854, 0x0df3,
+ 0x5855, 0x2cb3,
+ 0x5857, 0x217f,
+ 0x5858, 0x0e14,
+ 0x5859, 0x2cb5,
+ 0x585e, 0x0cd6,
+ 0x585f, 0x2cba,
+ 0x5862, 0x21a7,
+ 0x5863, 0x2cbd,
+ 0x5864, 0x232f,
+ 0x5865, 0x13d8,
+ 0x5866, 0x2cbe,
+ 0x586b, 0x0e41,
+ 0x586c, 0x13d9,
+ 0x586d, 0x2cc3,
+ 0x5875, 0x1e7d,
+ 0x5876, 0x2ccb,
+ 0x5879, 0x20d6,
+ 0x587a, 0x2cce,
+ 0x587e, 0x13a3,
+ 0x587f, 0x2cd2,
+ 0x5880, 0x13dd,
+ 0x5881, 0x13da,
+ 0x5882, 0x2cd3,
+ 0x5883, 0x08e2,
+ 0x5884, 0x2cd4,
+ 0x5885, 0x0d92,
+ 0x5886, 0x2cd5,
+ 0x5889, 0x13db,
+ 0x588a, 0x1ec2,
+ 0x588b, 0x2cd8,
+ 0x5892, 0x0d03,
+ 0x5893, 0x0b1c,
+ 0x5894, 0x2cdf,
+ 0x5899, 0x0c3a,
+ 0x589a, 0x13dc,
+ 0x589b, 0x2ce4,
+ 0x589c, 0x22b2,
+ 0x589d, 0x2ce5,
+ 0x589e, 0x1139,
+ 0x589f, 0x0fb1,
+ 0x58a0, 0x2ce6,
+ 0x58a8, 0x0b0e,
+ 0x58a9, 0x0614,
+ 0x58aa, 0x2cee,
+ 0x58ae, 0x1edf,
+ 0x58af, 0x2cf2,
+ 0x58b3, 0x1ef9,
+ 0x58b4, 0x2cf6,
+ 0x58bb, 0x20d9,
+ 0x58bc, 0x13a4,
+ 0x58bd, 0x2cfd,
+ 0x58be, 0x1fdd,
+ 0x58bf, 0x2cfe,
+ 0x58c1, 0x0443,
+ 0x58c2, 0x2d00,
+ 0x58c5, 0x13a5,
+ 0x58c6, 0x2d03,
+ 0x58c7, 0x2167,
+ 0x58c8, 0x2d04,
+ 0x58d1, 0x13a6,
+ 0x58d2, 0x2d0d,
+ 0x58d3, 0x21ed,
+ 0x58d4, 0x2d0e,
+ 0x58d5, 0x0775,
+ 0x58d6, 0x2d0f,
+ 0x58d8, 0x2007,
+ 0x58d9, 0x2326,
+ 0x58da, 0x2329,
+ 0x58db, 0x2d11,
+ 0x58de, 0x1f52,
+ 0x58df, 0x203b,
+ 0x58e0, 0x2328,
+ 0x58e1, 0x2d14,
+ 0x58e2, 0x2327,
+ 0x58e3, 0x2d15,
+ 0x58e4, 0x0c9b,
+ 0x58e5, 0x2d16,
+ 0x58e9, 0x1e2b,
+ 0x58ea, 0x2d1a,
+ 0x58eb, 0x0d56,
+ 0x58ec, 0x0ca4,
+ 0x58ed, 0x2d1b,
+ 0x58ee, 0x1210,
+ 0x58ef, 0x22ae,
+ 0x58f0, 0x0d32,
+ 0x58f1, 0x2d1c,
+ 0x58f3, 0x0954,
+ 0x58f4, 0x2d1e,
+ 0x58f6, 0x07af,
+ 0x58f7, 0x2d20,
+ 0x58f9, 0x1043,
+ 0x58fa, 0x1f49,
+ 0x58fb, 0x2d22,
+ 0x58fd, 0x2138,
+ 0x58fe, 0x2d24,
+ 0x5900, 0x2d26,
+ 0x5902, 0x161c,
+ 0x5903, 0x2d28,
+ 0x5904, 0x0529,
+ 0x5905, 0x2d29,
+ 0x5907, 0x0421,
+ 0x5908, 0x2d2b,
+ 0x590d, 0x06af,
+ 0x590e, 0x2d30,
+ 0x590f, 0x0f31,
+ 0x5910, 0x2d31,
+ 0x5914, 0x12fb,
+ 0x5915, 0x0f13,
+ 0x5916, 0x0e93,
+ 0x5917, 0x2d35,
+ 0x5919, 0x1301,
+ 0x591a, 0x061f,
+ 0x591b, 0x2d37,
+ 0x591c, 0x1040,
+ 0x591d, 0x2d38,
+ 0x591f, 0x0714,
+ 0x5920, 0x2d3a,
+ 0x5922, 0x2081,
+ 0x5923, 0x2d3c,
+ 0x5924, 0x161b,
+ 0x5925, 0x1619,
+ 0x5926, 0x2d3d,
+ 0x5927, 0x0576,
+ 0x5928, 0x2d3e,
+ 0x5929, 0x0e3f,
+ 0x592a, 0x0dfe,
+ 0x592b, 0x068f,
+ 0x592c, 0x2d3f,
+ 0x592d, 0x1268,
+ 0x592e, 0x1014,
+ 0x592f, 0x0772,
+ 0x5930, 0x2d40,
+ 0x5931, 0x0d3e,
+ 0x5932, 0x2d41,
+ 0x5934, 0x0e68,
+ 0x5935, 0x2d43,
+ 0x5937, 0x104b,
+ 0x5938, 0x0971,
+ 0x5939, 0x0843,
+ 0x593a, 0x0620,
+ 0x593b, 0x2d45,
+ 0x593c, 0x14af,
+ 0x593d, 0x2d46,
+ 0x593e, 0x1f7c,
+ 0x593f, 0x2d47,
+ 0x5941, 0x14b0,
+ 0x5942, 0x138c,
+ 0x5943, 0x2d49,
+ 0x5944, 0x1002,
+ 0x5945, 0x2d4a,
+ 0x5947, 0x0c05,
+ 0x5948, 0x0b31,
+ 0x5949, 0x068b,
+ 0x594a, 0x2d4c,
+ 0x594b, 0x0679,
+ 0x594c, 0x2d4d,
+ 0x594e, 0x0989,
+ 0x594f, 0x123d,
+ 0x5950, 0x2d4f,
+ 0x5951, 0x0c14,
+ 0x5952, 0x2d50,
+ 0x5954, 0x0425,
+ 0x5955, 0x14b2,
+ 0x5956, 0x0882,
+ 0x5957, 0x0e2a,
+ 0x5958, 0x14b4,
+ 0x5959, 0x2d52,
+ 0x595a, 0x14b3,
+ 0x595b, 0x2d53,
+ 0x5960, 0x05cd,
+ 0x5961, 0x2d58,
+ 0x5962, 0x0d16,
+ 0x5963, 0x2d59,
+ 0x5965, 0x03cd,
+ 0x5966, 0x2d5b,
+ 0x5969, 0x235b,
+ 0x596a, 0x1ede,
+ 0x596b, 0x2d5e,
+ 0x596c, 0x1fa2,
+ 0x596d, 0x2d5f,
+ 0x596e, 0x1efa,
+ 0x596f, 0x2d60,
+ 0x5973, 0x0b6f,
+ 0x5974, 0x0b6c,
+ 0x5975, 0x2d64,
+ 0x5976, 0x0b2f,
+ 0x5977, 0x2d65,
+ 0x5978, 0x085c,
+ 0x5979, 0x0df2,
+ 0x597a, 0x2d66,
+ 0x597d, 0x077a,
+ 0x597e, 0x2d69,
+ 0x5981, 0x1775,
+ 0x5982, 0x0cc2,
+ 0x5983, 0x1776,
+ 0x5984, 0x0eae,
+ 0x5985, 0x2d6c,
+ 0x5986, 0x120e,
+ 0x5987, 0x06b9,
+ 0x5988, 0x0a8f,
+ 0x5989, 0x2d6d,
+ 0x598a, 0x0cac,
+ 0x598b, 0x2d6e,
+ 0x598d, 0x1777,
+ 0x598e, 0x2d70,
+ 0x5992, 0x0609,
+ 0x5993, 0x083e,
+ 0x5994, 0x2d74,
+ 0x5996, 0x1026,
+ 0x5997, 0x177b,
+ 0x5998, 0x2d76,
+ 0x5999, 0x0af3,
+ 0x599a, 0x2d77,
+ 0x599d, 0x22ad,
+ 0x599e, 0x177e,
+ 0x599f, 0x2d7a,
+ 0x59a3, 0x177a,
+ 0x59a4, 0x177f,
+ 0x59a5, 0x0e88,
+ 0x59a6, 0x2d7e,
+ 0x59a8, 0x065e,
+ 0x59a9, 0x1778,
+ 0x59ab, 0x177d,
+ 0x59ac, 0x2d80,
+ 0x59ae, 0x0b40,
+ 0x59af, 0x1782,
+ 0x59b0, 0x2d82,
+ 0x59b2, 0x1781,
+ 0x59b3, 0x2d84,
+ 0x59b9, 0x0ac8,
+ 0x59ba, 0x2d8a,
+ 0x59bb, 0x0bfd,
+ 0x59bc, 0x2d8b,
+ 0x59be, 0x1784,
+ 0x59bf, 0x2d8d,
+ 0x59c6, 0x0b1a,
+ 0x59c7, 0x2d94,
+ 0x59ca, 0x177c,
+ 0x59cb, 0x0d53,
+ 0x59cc, 0x2d97,
+ 0x59d0, 0x08b4,
+ 0x59d1, 0x071c,
+ 0x59d2, 0x1780,
+ 0x59d3, 0x0fa0,
+ 0x59d4, 0x0ebe,
+ 0x59d5, 0x2d9b,
+ 0x59d7, 0x1783,
+ 0x59d8, 0x178a,
+ 0x59d9, 0x2d9d,
+ 0x59da, 0x102d,
+ 0x59db, 0x2d9e,
+ 0x59dc, 0x087b,
+ 0x59dd, 0x1787,
+ 0x59de, 0x2d9f,
+ 0x59e3, 0x1789,
+ 0x59e4, 0x2da4,
+ 0x59e5, 0x09bc,
+ 0x59e6, 0x2da5,
+ 0x59e8, 0x1053,
+ 0x59e9, 0x2da7,
+ 0x59ec, 0x081a,
+ 0x59ed, 0x2daa,
+ 0x59f9, 0x178b,
+ 0x59fa, 0x2db6,
+ 0x59fb, 0x107d,
+ 0x59fc, 0x2db7,
+ 0x59ff, 0x1228,
+ 0x5a00, 0x2dba,
+ 0x5a01, 0x0eaf,
+ 0x5a02, 0x2dbb,
+ 0x5a03, 0x0e8f,
+ 0x5a04, 0x0a4d,
+ 0x5a05, 0x1785,
+ 0x5a07, 0x0890,
+ 0x5a08, 0x1788,
+ 0x5a09, 0x178d,
+ 0x5a0a, 0x2dbc,
+ 0x5a0c, 0x178c,
+ 0x5a0d, 0x2dbe,
+ 0x5a11, 0x1790,
+ 0x5a12, 0x2dc2,
+ 0x5a13, 0x1792,
+ 0x5a14, 0x2dc3,
+ 0x5a18, 0x0b52,
+ 0x5a19, 0x2dc7,
+ 0x5a1c, 0x0b2b,
+ 0x5a1d, 0x2dca,
+ 0x5a1f, 0x0919,
+ 0x5a20, 0x0d28,
+ 0x5a21, 0x2dcc,
+ 0x5a23, 0x1791,
+ 0x5a24, 0x2dce,
+ 0x5a25, 0x062f,
+ 0x5a26, 0x2dcf,
+ 0x5a29, 0x0ae9,
+ 0x5a2a, 0x2dd2,
+ 0x5a31, 0x10ce,
+ 0x5a32, 0x178e,
+ 0x5a33, 0x2dd9,
+ 0x5a34, 0x178f,
+ 0x5a35, 0x2dda,
+ 0x5a36, 0x0c7d,
+ 0x5a37, 0x2ddb,
+ 0x5a3c, 0x1797,
+ 0x5a3d, 0x2de0,
+ 0x5a40, 0x1793,
+ 0x5a41, 0x203f,
+ 0x5a42, 0x2de3,
+ 0x5a46, 0x0be4,
+ 0x5a47, 0x2de7,
+ 0x5a49, 0x0ea2,
+ 0x5a4a, 0x1795,
+ 0x5a4b, 0x2de9,
+ 0x5a55, 0x1796,
+ 0x5a56, 0x2df3,
+ 0x5a5a, 0x07fe,
+ 0x5a5b, 0x2df7,
+ 0x5a62, 0x1798,
+ 0x5a63, 0x2dfe,
+ 0x5a66, 0x1f0e,
+ 0x5a67, 0x1794,
+ 0x5a68, 0x2e01,
+ 0x5a6a, 0x09a2,
+ 0x5a6b, 0x2e03,
+ 0x5a6d, 0x23f9,
+ 0x5a6e, 0x2e05,
+ 0x5a74, 0x1089,
+ 0x5a75, 0x1799,
+ 0x5a76, 0x0d2d,
+ 0x5a77, 0x179d,
+ 0x5a78, 0x2e0b,
+ 0x5a7a, 0x179e,
+ 0x5a7b, 0x2e0d,
+ 0x5a7f, 0x0fc1,
+ 0x5a80, 0x2e11,
+ 0x5a92, 0x0ac2,
+ 0x5a93, 0x2e23,
+ 0x5a9a, 0x0ac9,
+ 0x5a9b, 0x179c,
+ 0x5a9c, 0x2e2a,
+ 0x5aa7, 0x23fc,
+ 0x5aa8, 0x2e35,
+ 0x5aaa, 0x179b,
+ 0x5aab, 0x2e37,
+ 0x5ab2, 0x17a1,
+ 0x5ab3, 0x0f1e,
+ 0x5ab4, 0x2e3e,
+ 0x5ab5, 0x19a4,
+ 0x5ab6, 0x2e3f,
+ 0x5ab8, 0x17a4,
+ 0x5ab9, 0x2e41,
+ 0x5abd, 0x2069,
+ 0x5abe, 0x179f,
+ 0x5abf, 0x2e45,
+ 0x5ac1, 0x0851,
+ 0x5ac2, 0x0ce2,
+ 0x5ac3, 0x2e47,
+ 0x5ac9, 0x0828,
+ 0x5aca, 0x2e4d,
+ 0x5acc, 0x0f40,
+ 0x5acd, 0x2e4f,
+ 0x5ad2, 0x17a2,
+ 0x5ad3, 0x2e54,
+ 0x5ad4, 0x17a3,
+ 0x5ad5, 0x2e55,
+ 0x5ad6, 0x17a8,
+ 0x5ad7, 0x23f7,
+ 0x5ad8, 0x17aa,
+ 0x5ad9, 0x2e56,
+ 0x5adc, 0x17ab,
+ 0x5add, 0x2e59,
+ 0x5ae0, 0x17a5,
+ 0x5ae1, 0x05b6,
+ 0x5ae2, 0x2e5c,
+ 0x5ae3, 0x17a6,
+ 0x5ae4, 0x2e5d,
+ 0x5ae6, 0x17a9,
+ 0x5ae7, 0x2e5f,
+ 0x5ae9, 0x0b3e,
+ 0x5aea, 0x2e61,
+ 0x5aeb, 0x17a0,
+ 0x5aec, 0x2e62,
+ 0x5af1, 0x17a7,
+ 0x5af2, 0x2e67,
+ 0x5af5, 0x23f6,
+ 0x5af6, 0x2e6a,
+ 0x5afb, 0x23fd,
+ 0x5afc, 0x2e6f,
+ 0x5b00, 0x23f8,
+ 0x5b01, 0x2e73,
+ 0x5b08, 0x23fa,
+ 0x5b09, 0x17ac,
+ 0x5b0a, 0x2e7a,
+ 0x5b0b, 0x23fe,
+ 0x5b0c, 0x1fa8,
+ 0x5b0d, 0x2e7b,
+ 0x5b16, 0x17ae,
+ 0x5b17, 0x17ad,
+ 0x5b18, 0x2e84,
+ 0x5b19, 0x2401,
+ 0x5b1a, 0x2e85,
+ 0x5b21, 0x23ff,
+ 0x5b22, 0x2e8c,
+ 0x5b2a, 0x2400,
+ 0x5b2b, 0x2e94,
+ 0x5b30, 0x2221,
+ 0x5b31, 0x2e99,
+ 0x5b32, 0x17af,
+ 0x5b33, 0x2e9a,
+ 0x5b34, 0x130c,
+ 0x5b35, 0x2e9b,
+ 0x5b37, 0x17b0,
+ 0x5b38, 0x2122,
+ 0x5b39, 0x2e9d,
+ 0x5b40, 0x17b1,
+ 0x5b41, 0x2ea4,
+ 0x5b4c, 0x23fb,
+ 0x5b4d, 0x2eaf,
+ 0x5b50, 0x1230,
+ 0x5b51, 0x17b7,
+ 0x5b52, 0x2eb2,
+ 0x5b53, 0x17b8,
+ 0x5b54, 0x0964,
+ 0x5b55, 0x1113,
+ 0x5b56, 0x2eb3,
+ 0x5b57, 0x1233,
+ 0x5b58, 0x0569,
+ 0x5b59, 0x0de4,
+ 0x5b5a, 0x17b4,
+ 0x5b5b, 0x1279,
+ 0x5b5c, 0x122b,
+ 0x5b5d, 0x0f6d,
+ 0x5b5e, 0x2eb4,
+ 0x5b5f, 0x0ad4,
+ 0x5b60, 0x2eb5,
+ 0x5b62, 0x17b9,
+ 0x5b63, 0x0831,
+ 0x5b64, 0x071b,
+ 0x5b65, 0x17b5,
+ 0x5b66, 0x0fd0,
+ 0x5b67, 0x2eb7,
+ 0x5b69, 0x0759,
+ 0x5b6a, 0x0a76,
+ 0x5b6b, 0x215a,
+ 0x5b6c, 0x1261,
+ 0x5b6d, 0x2eb9,
+ 0x5b70, 0x0d82,
+ 0x5b71, 0x176a,
+ 0x5b72, 0x2ebc,
+ 0x5b73, 0x17b6,
+ 0x5b74, 0x2ebd,
+ 0x5b75, 0x0692,
+ 0x5b76, 0x2ebe,
+ 0x5b78, 0x21e5,
+ 0x5b79, 0x2ec0,
+ 0x5b7a, 0x0cc1,
+ 0x5b7b, 0x2ec1,
+ 0x5b7d, 0x0b58,
+ 0x5b7e, 0x2ec3,
+ 0x5b7f, 0x2057,
+ 0x5b80, 0x172e,
+ 0x5b81, 0x0b61,
+ 0x5b82, 0x2ec4,
+ 0x5b83, 0x0df1,
+ 0x5b84, 0x172f,
+ 0x5b85, 0x114d,
+ 0x5b86, 0x2ec5,
+ 0x5b87, 0x10d3,
+ 0x5b88, 0x0d6f,
+ 0x5b89, 0x03bd,
+ 0x5b8a, 0x2ec6,
+ 0x5b8b, 0x0dc3,
+ 0x5b8c, 0x0e9b,
+ 0x5b8d, 0x2ec7,
+ 0x5b8f, 0x07a1,
+ 0x5b90, 0x2ec9,
+ 0x5b93, 0x1731,
+ 0x5b94, 0x2ecc,
+ 0x5b95, 0x1730,
+ 0x5b96, 0x2ecd,
+ 0x5b97, 0x1237,
+ 0x5b98, 0x0732,
+ 0x5b99, 0x11e5,
+ 0x5b9a, 0x05e7,
+ 0x5b9b, 0x0ea1,
+ 0x5b9c, 0x1052,
+ 0x5b9d, 0x040f,
+ 0x5b9e, 0x0d4c,
+ 0x5b9f, 0x2ece,
+ 0x5ba0, 0x050d,
+ 0x5ba1, 0x0d2c,
+ 0x5ba2, 0x095a,
+ 0x5ba3, 0x0fc6,
+ 0x5ba4, 0x0d69,
+ 0x5ba5, 0x1732,
+ 0x5ba6, 0x07d7,
+ 0x5ba7, 0x2ecf,
+ 0x5baa, 0x0f49,
+ 0x5bab, 0x0705,
+ 0x5bac, 0x2ed2,
+ 0x5bb0, 0x111a,
+ 0x5bb1, 0x2ed6,
+ 0x5bb3, 0x075d,
+ 0x5bb4, 0x1010,
+ 0x5bb5, 0x0f69,
+ 0x5bb6, 0x0845,
+ 0x5bb7, 0x2ed8,
+ 0x5bb8, 0x1733,
+ 0x5bb9, 0x0cb8,
+ 0x5bba, 0x2ed9,
+ 0x5bbd, 0x097a,
+ 0x5bbe, 0x045f,
+ 0x5bbf, 0x0dd3,
+ 0x5bc0, 0x2edc,
+ 0x5bc2, 0x0838,
+ 0x5bc3, 0x2ede,
+ 0x5bc4, 0x0837,
+ 0x5bc5, 0x1081,
+ 0x5bc6, 0x0ae1,
+ 0x5bc7, 0x0969,
+ 0x5bc8, 0x2edf,
+ 0x5bcc, 0x06b6,
+ 0x5bcd, 0x2ee3,
+ 0x5bd0, 0x0ac7,
+ 0x5bd1, 0x2ee6,
+ 0x5bd2, 0x0765,
+ 0x5bd3, 0x10e5,
+ 0x5bd4, 0x2ee7,
+ 0x5bdd, 0x0c5b,
+ 0x5bde, 0x0b12,
+ 0x5bdf, 0x04b3,
+ 0x5be0, 0x2ef0,
+ 0x5be1, 0x072a,
+ 0x5be2, 0x20e5,
+ 0x5be3, 0x2ef1,
+ 0x5be4, 0x1737,
+ 0x5be5, 0x0a11,
+ 0x5be6, 0x212f,
+ 0x5be7, 0x20a3,
+ 0x5be8, 0x1150,
+ 0x5be9, 0x2121,
+ 0x5bea, 0x2ef2,
+ 0x5beb, 0x21d4,
+ 0x5bec, 0x1fe5,
+ 0x5bed, 0x2ef3,
+ 0x5bee, 0x1738,
+ 0x5bef, 0x2ef4,
+ 0x5bf0, 0x173a,
+ 0x5bf1, 0x2ef5,
+ 0x5bf5, 0x1e8a,
+ 0x5bf6, 0x1e37,
+ 0x5bf7, 0x2ef9,
+ 0x5bf8, 0x056a,
+ 0x5bf9, 0x0613,
+ 0x5bfa, 0x0db7,
+ 0x5bfb, 0x0fd9,
+ 0x5bfc, 0x059d,
+ 0x5bfd, 0x2efa,
+ 0x5bff, 0x0d70,
+ 0x5c00, 0x2efc,
+ 0x5c01, 0x067f,
+ 0x5c02, 0x2efd,
+ 0x5c04, 0x0d1d,
+ 0x5c05, 0x2eff,
+ 0x5c06, 0x087c,
+ 0x5c07, 0x1f9e,
+ 0x5c08, 0x22a6,
+ 0x5c09, 0x0ecd,
+ 0x5c0a, 0x124d,
+ 0x5c0b, 0x21e8,
+ 0x5c0c, 0x2f00,
+ 0x5c0d, 0x1eda,
+ 0x5c0e, 0x1eb9,
+ 0x5c0f, 0x0f6c,
+ 0x5c10, 0x2f01,
+ 0x5c11, 0x0d12,
+ 0x5c12, 0x2f02,
+ 0x5c14, 0x063a,
+ 0x5c15, 0x17b2,
+ 0x5c16, 0x0855,
+ 0x5c17, 0x2f04,
+ 0x5c18, 0x04e3,
+ 0x5c19, 0x2f05,
+ 0x5c1a, 0x0d09,
+ 0x5c1b, 0x2f06,
+ 0x5c1c, 0x17b3,
+ 0x5c1d, 0x04c7,
+ 0x5c1e, 0x2f07,
+ 0x5c22, 0x14b6,
+ 0x5c23, 0x2f0b,
+ 0x5c24, 0x10ad,
+ 0x5c25, 0x14b7,
+ 0x5c26, 0x2f0c,
+ 0x5c27, 0x1029,
+ 0x5c28, 0x2f0d,
+ 0x5c2c, 0x14b8,
+ 0x5c2d, 0x2f11,
+ 0x5c31, 0x08fc,
+ 0x5c32, 0x2f15,
+ 0x5c34, 0x14b9,
+ 0x5c35, 0x2f17,
+ 0x5c37, 0x235c,
+ 0x5c38, 0x0d43,
+ 0x5c39, 0x1083,
+ 0x5c3a, 0x0504,
+ 0x5c3b, 0x1766,
+ 0x5c3c, 0x0b44,
+ 0x5c3d, 0x08d0,
+ 0x5c3e, 0x0ec1,
+ 0x5c3f, 0x0b55,
+ 0x5c40, 0x0905,
+ 0x5c41, 0x0bc7,
+ 0x5c42, 0x04aa,
+ 0x5c43, 0x2f19,
+ 0x5c45, 0x0902,
+ 0x5c46, 0x2f1b,
+ 0x5c48, 0x0c79,
+ 0x5c49, 0x0e3e,
+ 0x5c4a, 0x08bd,
+ 0x5c4b, 0x0eec,
+ 0x5c4c, 0x2f1d,
+ 0x5c4e, 0x0d51,
+ 0x5c4f, 0x0be0,
+ 0x5c50, 0x1768,
+ 0x5c51, 0x0f87,
+ 0x5c52, 0x2f1f,
+ 0x5c55, 0x115a,
+ 0x5c56, 0x2f22,
+ 0x5c59, 0x1769,
+ 0x5c5a, 0x2f25,
+ 0x5c5e, 0x0d8b,
+ 0x5c5f, 0x2f29,
+ 0x5c60, 0x0e71,
+ 0x5c61, 0x0a6c,
+ 0x5c62, 0x2050,
+ 0x5c63, 0x176b,
+ 0x5c64, 0x1e67,
+ 0x5c65, 0x0a6b,
+ 0x5c66, 0x176c,
+ 0x5c67, 0x2f2a,
+ 0x5c68, 0x23f4,
+ 0x5c69, 0x2f2b,
+ 0x5c6c, 0x213e,
+ 0x5c6d, 0x2f2e,
+ 0x5c6e, 0x1774,
+ 0x5c6f, 0x0e7e,
+ 0x5c70, 0x2f2f,
+ 0x5c71, 0x0cf6,
+ 0x5c72, 0x2f30,
+ 0x5c79, 0x1060,
+ 0x5c7a, 0x15ac,
+ 0x5c7b, 0x2f37,
+ 0x5c7f, 0x10d1,
+ 0x5c80, 0x2f3b,
+ 0x5c81, 0x0ddf,
+ 0x5c82, 0x0c10,
+ 0x5c83, 0x2f3c,
+ 0x5c88, 0x15b0,
+ 0x5c89, 0x2f41,
+ 0x5c8c, 0x15ab,
+ 0x5c8d, 0x15ad,
+ 0x5c8e, 0x2f44,
+ 0x5c90, 0x15ae,
+ 0x5c91, 0x15b3,
+ 0x5c92, 0x2f46,
+ 0x5c94, 0x04b4,
+ 0x5c95, 0x2f48,
+ 0x5c96, 0x15af,
+ 0x5c97, 0x06d5,
+ 0x5c98, 0x15b1,
+ 0x5c9a, 0x15b4,
+ 0x5c9b, 0x059b,
+ 0x5c9c, 0x15b5,
+ 0x5c9d, 0x2f49,
+ 0x5ca1, 0x1f16,
+ 0x5ca2, 0x15b7,
+ 0x5ca3, 0x15bc,
+ 0x5ca4, 0x2f4d,
+ 0x5ca9, 0x0ffb,
+ 0x5caa, 0x2f52,
+ 0x5cab, 0x15ba,
+ 0x5cac, 0x15b9,
+ 0x5cad, 0x0a34,
+ 0x5cae, 0x2f53,
+ 0x5cb1, 0x15bb,
+ 0x5cb2, 0x2f56,
+ 0x5cb3, 0x1103,
+ 0x5cb4, 0x2f57,
+ 0x5cb5, 0x15b6,
+ 0x5cb6, 0x2f58,
+ 0x5cb7, 0x15be,
+ 0x5cb8, 0x03c1,
+ 0x5cb9, 0x2f59,
+ 0x5cbd, 0x15b8,
+ 0x5cbe, 0x2f5d,
+ 0x5cbf, 0x0986,
+ 0x5cc0, 0x2f5e,
+ 0x5cc1, 0x15bd,
+ 0x5cc2, 0x2f5f,
+ 0x5cc4, 0x15bf,
+ 0x5cc5, 0x2f61,
+ 0x5ccb, 0x15c2,
+ 0x5ccc, 0x2f67,
+ 0x5cd2, 0x15c0,
+ 0x5cd3, 0x2f6d,
+ 0x5cd9, 0x11c4,
+ 0x5cda, 0x2f73,
+ 0x5ce1, 0x0f2c,
+ 0x5ce2, 0x2f7a,
+ 0x5ce4, 0x15c1,
+ 0x5ce5, 0x15c3,
+ 0x5ce6, 0x0a74,
+ 0x5ce7, 0x2f7c,
+ 0x5ce8, 0x062a,
+ 0x5ce9, 0x2f7d,
+ 0x5cea, 0x10dd,
+ 0x5ceb, 0x2f7e,
+ 0x5ced, 0x0c4a,
+ 0x5cee, 0x2f80,
+ 0x5cf0, 0x0682,
+ 0x5cf1, 0x2f82,
+ 0x5cf4, 0x2389,
+ 0x5cf5, 0x2f85,
+ 0x5cf6, 0x1eb7,
+ 0x5cf7, 0x2f86,
+ 0x5cfb, 0x092d,
+ 0x5cfc, 0x2f8a,
+ 0x5cfd, 0x21b4,
+ 0x5cfe, 0x2f8b,
+ 0x5d00, 0x2f8d,
+ 0x5d02, 0x15c4,
+ 0x5d04, 0x2f8f,
+ 0x5d06, 0x15cb,
+ 0x5d07, 0x050c,
+ 0x5d08, 0x2f91,
+ 0x5d0d, 0x238f,
+ 0x5d0e, 0x0c08,
+ 0x5d0f, 0x2f96,
+ 0x5d14, 0x0561,
+ 0x5d15, 0x2f9b,
+ 0x5d16, 0x0feb,
+ 0x5d17, 0x1f1a,
+ 0x5d18, 0x2f9c,
+ 0x5d1b, 0x15cc,
+ 0x5d1c, 0x2f9f,
+ 0x5d1e, 0x15ca,
+ 0x5d1f, 0x2fa1,
+ 0x5d24, 0x15c9,
+ 0x5d25, 0x2fa6,
+ 0x5d26, 0x15c7,
+ 0x5d27, 0x15c6,
+ 0x5d28, 0x2fa7,
+ 0x5d29, 0x0429,
+ 0x5d2a, 0x2fa8,
+ 0x5d2c, 0x238b,
+ 0x5d2d, 0x1159,
+ 0x5d2e, 0x15c8,
+ 0x5d2f, 0x2faa,
+ 0x5d34, 0x15cf,
+ 0x5d35, 0x2faf,
+ 0x5d3d, 0x15d0,
+ 0x5d3e, 0x15ce,
+ 0x5d3f, 0x2fb7,
+ 0x5d47, 0x1b22,
+ 0x5d48, 0x2fbf,
+ 0x5d4a, 0x15d7,
+ 0x5d4b, 0x15d6,
+ 0x5d4c, 0x0c33,
+ 0x5d4d, 0x2fc1,
+ 0x5d50, 0x238a,
+ 0x5d51, 0x2fc4,
+ 0x5d58, 0x15cd,
+ 0x5d59, 0x2fcb,
+ 0x5d5b, 0x15d2,
+ 0x5d5c, 0x2fcd,
+ 0x5d5d, 0x15d4,
+ 0x5d5e, 0x2fce,
+ 0x5d69, 0x15d8,
+ 0x5d6a, 0x2fd9,
+ 0x5d6b, 0x15d5,
+ 0x5d6c, 0x15d1,
+ 0x5d6d, 0x2fda,
+ 0x5d6f, 0x15d3,
+ 0x5d70, 0x2fdc,
+ 0x5d74, 0x15d9,
+ 0x5d75, 0x2fe0,
+ 0x5d81, 0x2391,
+ 0x5d82, 0x15da,
+ 0x5d83, 0x2fec,
+ 0x5d84, 0x2271,
+ 0x5d85, 0x2fed,
+ 0x5d87, 0x2388,
+ 0x5d88, 0x2fef,
+ 0x5d97, 0x238e,
+ 0x5d98, 0x2ffe,
+ 0x5d99, 0x15db,
+ 0x5d9a, 0x2fff,
+ 0x5d9d, 0x15dc,
+ 0x5d9e, 0x3002,
+ 0x5da0, 0x238d,
+ 0x5da1, 0x3004,
+ 0x5da7, 0x238c,
+ 0x5da8, 0x300a,
+ 0x5db7, 0x15de,
+ 0x5db8, 0x2390,
+ 0x5db9, 0x3019,
+ 0x5dba, 0x2033,
+ 0x5dbb, 0x301a,
+ 0x5dbc, 0x223c,
+ 0x5dbd, 0x301b,
+ 0x5dc5, 0x15df,
+ 0x5dc6, 0x3023,
+ 0x5dcb, 0x1fe9,
+ 0x5dcc, 0x3028,
+ 0x5dcd, 0x0eb0,
+ 0x5dce, 0x3029,
+ 0x5dd2, 0x2055,
+ 0x5dd3, 0x302d,
+ 0x5dd4, 0x2392,
+ 0x5dd5, 0x302e,
+ 0x5ddb, 0x1815,
+ 0x5ddc, 0x3034,
+ 0x5ddd, 0x052b,
+ 0x5dde, 0x11dc,
+ 0x5ddf, 0x3035,
+ 0x5de1, 0x0fdb,
+ 0x5de2, 0x04d7,
+ 0x5de3, 0x3037,
+ 0x5de5, 0x06fd,
+ 0x5de6, 0x1250,
+ 0x5de7, 0x0c46,
+ 0x5de8, 0x090d,
+ 0x5de9, 0x0707,
+ 0x5dea, 0x3039,
+ 0x5deb, 0x0ee6,
+ 0x5dec, 0x303a,
+ 0x5dee, 0x04b5,
+ 0x5def, 0x139f,
+ 0x5df0, 0x2324,
+ 0x5df1, 0x082d,
+ 0x5df2, 0x1058,
+ 0x5df3, 0x0dbd,
+ 0x5df4, 0x03d8,
+ 0x5df5, 0x303c,
+ 0x5df7, 0x0f5c,
+ 0x5df8, 0x303e,
+ 0x5dfd, 0x12f7,
+ 0x5dfe, 0x08be,
+ 0x5dff, 0x3043,
+ 0x5e00, 0x3044,
+ 0x5e01, 0x043b,
+ 0x5e02, 0x0d67,
+ 0x5e03, 0x0483,
+ 0x5e04, 0x3045,
+ 0x5e05, 0x0d9c,
+ 0x5e06, 0x0648,
+ 0x5e07, 0x3046,
+ 0x5e08, 0x0d3d,
+ 0x5e09, 0x3047,
+ 0x5e0c, 0x0f10,
+ 0x5e0d, 0x304a,
+ 0x5e0f, 0x159e,
+ 0x5e10, 0x116b,
+ 0x5e11, 0x15a1,
+ 0x5e12, 0x304c,
+ 0x5e14, 0x15a0,
+ 0x5e15, 0x0b82,
+ 0x5e16, 0x0e4e,
+ 0x5e17, 0x304e,
+ 0x5e18, 0x09fa,
+ 0x5e19, 0x159f,
+ 0x5e1a, 0x11e2,
+ 0x5e1b, 0x0476,
+ 0x5e1c, 0x11c3,
+ 0x5e1d, 0x05bc,
+ 0x5e1e, 0x304f,
+ 0x5e25, 0x2143,
+ 0x5e26, 0x057b,
+ 0x5e27, 0x11a0,
+ 0x5e28, 0x3056,
+ 0x5e2b, 0x2129,
+ 0x5e2c, 0x3059,
+ 0x5e2d, 0x0f1c,
+ 0x5e2e, 0x03fa,
+ 0x5e2f, 0x305a,
+ 0x5e31, 0x15a2,
+ 0x5e32, 0x305c,
+ 0x5e33, 0x2277,
+ 0x5e34, 0x305d,
+ 0x5e36, 0x1ea7,
+ 0x5e37, 0x15a5,
+ 0x5e38, 0x04c8,
+ 0x5e39, 0x305f,
+ 0x5e3b, 0x15a3,
+ 0x5e3d, 0x0ab6,
+ 0x5e3e, 0x3061,
+ 0x5e40, 0x2285,
+ 0x5e41, 0x3063,
+ 0x5e42, 0x0ae2,
+ 0x5e43, 0x2384,
+ 0x5e44, 0x15a6,
+ 0x5e45, 0x0696,
+ 0x5e46, 0x3064,
+ 0x5e4c, 0x07e4,
+ 0x5e4d, 0x306a,
+ 0x5e54, 0x15a7,
+ 0x5e55, 0x0b1e,
+ 0x5e56, 0x3071,
+ 0x5e57, 0x2387,
+ 0x5e58, 0x2386,
+ 0x5e59, 0x3072,
+ 0x5e5b, 0x15a8,
+ 0x5e5c, 0x3074,
+ 0x5e5e, 0x15a9,
+ 0x5e5f, 0x2290,
+ 0x5e60, 0x3076,
+ 0x5e61, 0x15aa,
+ 0x5e62, 0x0534,
+ 0x5e63, 0x1e44,
+ 0x5e64, 0x3077,
+ 0x5e6b, 0x1e32,
+ 0x5e6c, 0x2385,
+ 0x5e6d, 0x307e,
+ 0x5e72, 0x06c4,
+ 0x5e73, 0x0bdc,
+ 0x5e74, 0x0b4d,
+ 0x5e75, 0x3083,
+ 0x5e76, 0x0469,
+ 0x5e77, 0x3084,
+ 0x5e78, 0x0f9d,
+ 0x5e79, 0x1f13,
+ 0x5e7a, 0x1813,
+ 0x5e7b, 0x07d8,
+ 0x5e7c, 0x10bc,
+ 0x5e7d, 0x10a9,
+ 0x5e7e, 0x1f73,
+ 0x5e7f, 0x073c,
+ 0x5e80, 0x1631,
+ 0x5e81, 0x3085,
+ 0x5e84, 0x120c,
+ 0x5e85, 0x3088,
+ 0x5e86, 0x0c69,
+ 0x5e87, 0x043c,
+ 0x5e88, 0x3089,
+ 0x5e8a, 0x0535,
+ 0x5e8b, 0x1633,
+ 0x5e8c, 0x308b,
+ 0x5e8f, 0x0fbd,
+ 0x5e90, 0x0a55,
+ 0x5e91, 0x1632,
+ 0x5e92, 0x308e,
+ 0x5e93, 0x096f,
+ 0x5e94, 0x108b,
+ 0x5e95, 0x05b8,
+ 0x5e96, 0x1634,
+ 0x5e97, 0x05cb,
+ 0x5e98, 0x308f,
+ 0x5e99, 0x0af2,
+ 0x5e9a, 0x06f8,
+ 0x5e9b, 0x3090,
+ 0x5e9c, 0x06a9,
+ 0x5e9d, 0x3091,
+ 0x5e9e, 0x0b94,
+ 0x5e9f, 0x066c,
+ 0x5ea0, 0x1636,
+ 0x5ea1, 0x3092,
+ 0x5ea5, 0x1635,
+ 0x5ea6, 0x0607,
+ 0x5ea7, 0x1256,
+ 0x5ea8, 0x3096,
+ 0x5eab, 0x1fe0,
+ 0x5eac, 0x3099,
+ 0x5ead, 0x0e56,
+ 0x5eae, 0x309a,
+ 0x5eb3, 0x163a,
+ 0x5eb4, 0x309f,
+ 0x5eb5, 0x1638,
+ 0x5eb6, 0x0d93,
+ 0x5eb7, 0x0942,
+ 0x5eb8, 0x109e,
+ 0x5eb9, 0x1637,
+ 0x5eba, 0x30a0,
+ 0x5ebe, 0x1639,
+ 0x5ebf, 0x30a4,
+ 0x5ec9, 0x09f7,
+ 0x5eca, 0x09b3,
+ 0x5ecb, 0x30ae,
+ 0x5ed1, 0x163d,
+ 0x5ed2, 0x163c,
+ 0x5ed3, 0x0995,
+ 0x5ed4, 0x30b4,
+ 0x5ed6, 0x0a17,
+ 0x5ed7, 0x30b6,
+ 0x5edb, 0x163e,
+ 0x5edc, 0x30ba,
+ 0x5edf, 0x2087,
+ 0x5ee0, 0x1e78,
+ 0x5ee1, 0x23ae,
+ 0x5ee2, 0x1ef6,
+ 0x5ee3, 0x1f31,
+ 0x5ee4, 0x30bd,
+ 0x5ee8, 0x163f,
+ 0x5ee9, 0x30c1,
+ 0x5eea, 0x1640,
+ 0x5eeb, 0x30c2,
+ 0x5eec, 0x2045,
+ 0x5eed, 0x30c3,
+ 0x5ef3, 0x2178,
+ 0x5ef4, 0x1398,
+ 0x5ef5, 0x30c9,
+ 0x5ef6, 0x0ffc,
+ 0x5ef7, 0x0e53,
+ 0x5ef8, 0x30ca,
+ 0x5efa, 0x0879,
+ 0x5efb, 0x30cc,
+ 0x5efe, 0x14ad,
+ 0x5eff, 0x125b,
+ 0x5f00, 0x0937,
+ 0x5f01, 0x139d,
+ 0x5f02, 0x1073,
+ 0x5f03, 0x0c19,
+ 0x5f04, 0x0b6b,
+ 0x5f05, 0x30cf,
+ 0x5f08, 0x14ae,
+ 0x5f09, 0x30d2,
+ 0x5f0a, 0x0440,
+ 0x5f0b, 0x14f6,
+ 0x5f0c, 0x30d3,
+ 0x5f0f, 0x0d54,
+ 0x5f10, 0x30d6,
+ 0x5f11, 0x14f9,
+ 0x5f12, 0x30d7,
+ 0x5f13, 0x0706,
+ 0x5f14, 0x30d8,
+ 0x5f15, 0x1084,
+ 0x5f16, 0x30d9,
+ 0x5f17, 0x06a0,
+ 0x5f18, 0x07a2,
+ 0x5f19, 0x30da,
+ 0x5f1b, 0x04ff,
+ 0x5f1c, 0x30dc,
+ 0x5f1f, 0x05bd,
+ 0x5f20, 0x1166,
+ 0x5f21, 0x30df,
+ 0x5f25, 0x0adb,
+ 0x5f26, 0x0f3f,
+ 0x5f27, 0x07b6,
+ 0x5f28, 0x30e3,
+ 0x5f29, 0x176f,
+ 0x5f2a, 0x176e,
+ 0x5f2b, 0x30e4,
+ 0x5f2d, 0x1770,
+ 0x5f2e, 0x30e6,
+ 0x5f2f, 0x0e95,
+ 0x5f30, 0x30e7,
+ 0x5f31, 0x0cd0,
+ 0x5f32, 0x30e8,
+ 0x5f33, 0x23f5,
+ 0x5f34, 0x30e9,
+ 0x5f35, 0x2275,
+ 0x5f36, 0x30ea,
+ 0x5f39, 0x0590,
+ 0x5f3a, 0x0c3c,
+ 0x5f3b, 0x30ed,
+ 0x5f3c, 0x1772,
+ 0x5f3d, 0x30ee,
+ 0x5f40, 0x19be,
+ 0x5f41, 0x30f1,
+ 0x5f46, 0x266e,
+ 0x5f47, 0x30f6,
+ 0x5f48, 0x1eb0,
+ 0x5f49, 0x30f7,
+ 0x5f4c, 0x2083,
+ 0x5f4d, 0x30fa,
+ 0x5f4e, 0x2188,
+ 0x5f4f, 0x30fb,
+ 0x5f50, 0x1762,
+ 0x5f51, 0x30fc,
+ 0x5f52, 0x0742,
+ 0x5f53, 0x0592,
+ 0x5f54, 0x30fd,
+ 0x5f55, 0x0a63,
+ 0x5f56, 0x1764,
+ 0x5f57, 0x1763,
+ 0x5f58, 0x1765,
+ 0x5f59, 0x267c,
+ 0x5f5a, 0x30fe,
+ 0x5f5d, 0x1054,
+ 0x5f5e, 0x3101,
+ 0x5f61, 0x15ee,
+ 0x5f62, 0x0f99,
+ 0x5f63, 0x3104,
+ 0x5f64, 0x0e5f,
+ 0x5f65, 0x3105,
+ 0x5f66, 0x100e,
+ 0x5f67, 0x3106,
+ 0x5f69, 0x0491,
+ 0x5f6a, 0x0454,
+ 0x5f6b, 0x3108,
+ 0x5f6c, 0x045b,
+ 0x5f6d, 0x0bae,
+ 0x5f6e, 0x3109,
+ 0x5f70, 0x1164,
+ 0x5f71, 0x1095,
+ 0x5f72, 0x310b,
+ 0x5f73, 0x15e0,
+ 0x5f74, 0x310c,
+ 0x5f77, 0x15e1,
+ 0x5f78, 0x310f,
+ 0x5f79, 0x1062,
+ 0x5f7a, 0x3110,
+ 0x5f7b, 0x04de,
+ 0x5f7c, 0x0434,
+ 0x5f7d, 0x3111,
+ 0x5f80, 0x0eaa,
+ 0x5f81, 0x1198,
+ 0x5f82, 0x15e2,
+ 0x5f83, 0x3114,
+ 0x5f84, 0x08e5,
+ 0x5f85, 0x0580,
+ 0x5f86, 0x3115,
+ 0x5f87, 0x15e3,
+ 0x5f88, 0x0793,
+ 0x5f89, 0x15e4,
+ 0x5f8a, 0x07c7,
+ 0x5f8b, 0x0a70,
+ 0x5f8c, 0x15e5,
+ 0x5f8d, 0x3116,
+ 0x5f90, 0x0fb7,
+ 0x5f91, 0x1fc5,
+ 0x5f92, 0x0e6e,
+ 0x5f93, 0x3119,
+ 0x5f95, 0x15e6,
+ 0x5f96, 0x311b,
+ 0x5f97, 0x05a4,
+ 0x5f98, 0x0b88,
+ 0x5f99, 0x15e7,
+ 0x5f9a, 0x311c,
+ 0x5f9c, 0x15e8,
+ 0x5f9d, 0x311e,
+ 0x5f9e, 0x1ea1,
+ 0x5f9f, 0x311f,
+ 0x5fa0, 0x2393,
+ 0x5fa1, 0x10de,
+ 0x5fa2, 0x3120,
+ 0x5fa8, 0x15e9,
+ 0x5fa9, 0x1f0b,
+ 0x5faa, 0x0fd6,
+ 0x5fab, 0x3126,
+ 0x5fad, 0x15ea,
+ 0x5fae, 0x0eb1,
+ 0x5faf, 0x3128,
+ 0x5fb5, 0x15eb,
+ 0x5fb6, 0x312e,
+ 0x5fb7, 0x05a3,
+ 0x5fb8, 0x312f,
+ 0x5fb9, 0x1e7c,
+ 0x5fba, 0x3130,
+ 0x5fbc, 0x15ec,
+ 0x5fbd, 0x07ea,
+ 0x5fbe, 0x3132,
+ 0x5fc3, 0x0f8f,
+ 0x5fc4, 0x1642,
+ 0x5fc5, 0x0441,
+ 0x5fc6, 0x106b,
+ 0x5fc7, 0x3137,
+ 0x5fc9, 0x1643,
+ 0x5fca, 0x3139,
+ 0x5fcc, 0x083c,
+ 0x5fcd, 0x0ca7,
+ 0x5fce, 0x313b,
+ 0x5fcf, 0x1645,
+ 0x5fd0, 0x1a0c,
+ 0x5fd1, 0x1a0b,
+ 0x5fd2, 0x14f7,
+ 0x5fd3, 0x313c,
+ 0x5fd6, 0x1644,
+ 0x5fd7, 0x11bd,
+ 0x5fd8, 0x0ead,
+ 0x5fd9, 0x0aab,
+ 0x5fda, 0x313f,
+ 0x5fdd, 0x1683,
+ 0x5fde, 0x3142,
+ 0x5fe0, 0x11d1,
+ 0x5fe1, 0x1649,
+ 0x5fe2, 0x3144,
+ 0x5fe4, 0x164a,
+ 0x5fe5, 0x3146,
+ 0x5fe7, 0x10ac,
+ 0x5fe8, 0x3148,
+ 0x5fea, 0x164e,
+ 0x5feb, 0x0979,
+ 0x5fec, 0x314a,
+ 0x5fed, 0x164f,
+ 0x5fee, 0x1647,
+ 0x5fef, 0x314b,
+ 0x5ff1, 0x04e5,
+ 0x5ff2, 0x314d,
+ 0x5ff5, 0x0b51,
+ 0x5ff6, 0x3150,
+ 0x5ff8, 0x1650,
+ 0x5ff9, 0x3152,
+ 0x5ffb, 0x0f8e,
+ 0x5ffc, 0x3154,
+ 0x5ffd, 0x07ad,
+ 0x5ffe, 0x164b,
+ 0x5fff, 0x067b,
+ 0x6000, 0x07c8,
+ 0x6001, 0x0dff,
+ 0x6002, 0x0dc0,
+ 0x6003, 0x1646,
+ 0x6004, 0x1648,
+ 0x6005, 0x164c,
+ 0x6007, 0x3155,
+ 0x600a, 0x1659,
+ 0x600b, 0x3158,
+ 0x600d, 0x1656,
+ 0x600e, 0x1138,
+ 0x600f, 0x1655,
+ 0x6010, 0x315a,
+ 0x6012, 0x0b6e,
+ 0x6013, 0x315c,
+ 0x6014, 0x119b,
+ 0x6015, 0x0b83,
+ 0x6016, 0x0487,
+ 0x6017, 0x315d,
+ 0x6019, 0x1651,
+ 0x601a, 0x315f,
+ 0x601b, 0x1654,
+ 0x601c, 0x09f8,
+ 0x601d, 0x0db1,
+ 0x601e, 0x3160,
+ 0x6020, 0x0582,
+ 0x6021, 0x165b,
+ 0x6022, 0x3162,
+ 0x6025, 0x0824,
+ 0x6026, 0x1653,
+ 0x6027, 0x0f9f,
+ 0x6028, 0x10fc,
+ 0x6029, 0x1657,
+ 0x602a, 0x072f,
+ 0x602b, 0x1658,
+ 0x602c, 0x3165,
+ 0x602f, 0x0c50,
+ 0x6030, 0x3168,
+ 0x6035, 0x1652,
+ 0x6036, 0x316d,
+ 0x603b, 0x1239,
+ 0x603c, 0x1a0d,
+ 0x603d, 0x3172,
+ 0x603f, 0x165a,
+ 0x6040, 0x3174,
+ 0x6041, 0x1a11,
+ 0x6042, 0x1660,
+ 0x6043, 0x0d68,
+ 0x6044, 0x3175,
+ 0x604b, 0x09fe,
+ 0x604c, 0x317c,
+ 0x604d, 0x07e5,
+ 0x604e, 0x317d,
+ 0x6050, 0x0963,
+ 0x6051, 0x317f,
+ 0x6052, 0x079a,
+ 0x6053, 0x3180,
+ 0x6055, 0x0d96,
+ 0x6056, 0x3182,
+ 0x6059, 0x1a12,
+ 0x605a, 0x1a0f,
+ 0x605b, 0x3185,
+ 0x605d, 0x1a0e,
+ 0x605e, 0x3187,
+ 0x6062, 0x07eb,
+ 0x6063, 0x1a13,
+ 0x6064, 0x0fbf,
+ 0x6065, 0x318b,
+ 0x6067, 0x1a10,
+ 0x6068, 0x0795,
+ 0x6069, 0x0636,
+ 0x606a, 0x1661,
+ 0x606b, 0x05f1,
+ 0x606c, 0x0e44,
+ 0x606d, 0x0700,
+ 0x606e, 0x318d,
+ 0x606f, 0x0f0f,
+ 0x6070, 0x0c1e,
+ 0x6071, 0x318e,
+ 0x6073, 0x095f,
+ 0x6074, 0x3190,
+ 0x6076, 0x0630,
+ 0x6077, 0x3192,
+ 0x6078, 0x165c,
+ 0x607a, 0x165f,
+ 0x607b, 0x165e,
+ 0x607c, 0x0b38,
+ 0x607d, 0x1662,
+ 0x607e, 0x3193,
+ 0x607f, 0x10a6,
+ 0x6080, 0x3194,
+ 0x6083, 0x1667,
+ 0x6084, 0x0c41,
+ 0x6085, 0x3197,
+ 0x6089, 0x0f11,
+ 0x608a, 0x319b,
+ 0x608c, 0x1669,
+ 0x608d, 0x076e,
+ 0x608e, 0x319d,
+ 0x6092, 0x1668,
+ 0x6093, 0x31a1,
+ 0x6094, 0x07ef,
+ 0x6095, 0x31a2,
+ 0x6096, 0x1663,
+ 0x6097, 0x31a3,
+ 0x609a, 0x1664,
+ 0x609b, 0x166a,
+ 0x609c, 0x31a6,
+ 0x609d, 0x1666,
+ 0x609e, 0x31a7,
+ 0x609f, 0x0f01,
+ 0x60a0, 0x10ab,
+ 0x60a1, 0x31a8,
+ 0x60a3, 0x07d1,
+ 0x60a4, 0x31aa,
+ 0x60a6, 0x1106,
+ 0x60a7, 0x31ac,
+ 0x60a8, 0x0b5d,
+ 0x60a9, 0x31ad,
+ 0x60ab, 0x1a14,
+ 0x60ac, 0x0fc7,
+ 0x60ad, 0x1665,
+ 0x60ae, 0x31af,
+ 0x60af, 0x0afa,
+ 0x60b0, 0x31b0,
+ 0x60b1, 0x166d,
+ 0x60b2, 0x0418,
+ 0x60b3, 0x31b1,
+ 0x60b4, 0x1672,
+ 0x60b5, 0x23b4,
+ 0x60b6, 0x207e,
+ 0x60b7, 0x31b2,
+ 0x60b8, 0x0835,
+ 0x60b9, 0x31b3,
+ 0x60bb, 0x166c,
+ 0x60bc, 0x05a0,
+ 0x60bd, 0x31b5,
+ 0x60c5, 0x0c66,
+ 0x60c6, 0x1670,
+ 0x60c7, 0x31bd,
+ 0x60ca, 0x08d9,
+ 0x60cb, 0x0ea0,
+ 0x60cc, 0x31c0,
+ 0x60d1, 0x0808,
+ 0x60d2, 0x31c5,
+ 0x60d5, 0x0e3b,
+ 0x60d6, 0x31c8,
+ 0x60d8, 0x166f,
+ 0x60d9, 0x31ca,
+ 0x60da, 0x1671,
+ 0x60db, 0x31cb,
+ 0x60dc, 0x0f14,
+ 0x60dd, 0x166e,
+ 0x60de, 0x31cc,
+ 0x60df, 0x0eb8,
+ 0x60e0, 0x07f2,
+ 0x60e1, 0x1ee3,
+ 0x60e2, 0x31cd,
+ 0x60e6, 0x05cc,
+ 0x60e7, 0x0914,
+ 0x60e8, 0x0499,
+ 0x60e9, 0x04f2,
+ 0x60ea, 0x31d1,
+ 0x60eb, 0x0422,
+ 0x60ec, 0x166b,
+ 0x60ed, 0x0498,
+ 0x60ee, 0x058d,
+ 0x60ef, 0x0738,
+ 0x60f0, 0x0627,
+ 0x60f1, 0x2095,
+ 0x60f2, 0x23bb,
+ 0x60f3, 0x0f58,
+ 0x60f4, 0x1677,
+ 0x60f5, 0x31d2,
+ 0x60f6, 0x07e1,
+ 0x60f7, 0x31d3,
+ 0x60f9, 0x0ca2,
+ 0x60fa, 0x0f95,
+ 0x60fb, 0x23b9,
+ 0x60fc, 0x31d5,
+ 0x6100, 0x1678,
+ 0x6101, 0x0513,
+ 0x6102, 0x31d9,
+ 0x6106, 0x1a15,
+ 0x6107, 0x31dd,
+ 0x6108, 0x10df,
+ 0x6109, 0x10c9,
+ 0x610a, 0x31de,
+ 0x610d, 0x1a16,
+ 0x610e, 0x1679,
+ 0x610f, 0x1069,
+ 0x6110, 0x31e1,
+ 0x6115, 0x1675,
+ 0x6116, 0x31e6,
+ 0x611a, 0x10c3,
+ 0x611b, 0x1e28,
+ 0x611c, 0x23bd,
+ 0x611d, 0x31ea,
+ 0x611f, 0x06cb,
+ 0x6120, 0x1673,
+ 0x6121, 0x31ec,
+ 0x6123, 0x1676,
+ 0x6124, 0x067c,
+ 0x6125, 0x31ee,
+ 0x6126, 0x1674,
+ 0x6127, 0x098d,
+ 0x6128, 0x31ef,
+ 0x612b, 0x167a,
+ 0x612c, 0x31f2,
+ 0x6134, 0x23b5,
+ 0x6135, 0x31fa,
+ 0x6137, 0x23ba,
+ 0x6138, 0x31fc,
+ 0x613e, 0x23b3,
+ 0x613f, 0x10fb,
+ 0x6140, 0x3202,
+ 0x6148, 0x054b,
+ 0x6149, 0x320a,
+ 0x614a, 0x167b,
+ 0x614b, 0x2162,
+ 0x614c, 0x07da,
+ 0x614d, 0x320b,
+ 0x614e, 0x0d30,
+ 0x614f, 0x320c,
+ 0x6151, 0x0d1e,
+ 0x6152, 0x320e,
+ 0x6155, 0x0b20,
+ 0x6156, 0x3211,
+ 0x6158, 0x1e5e,
+ 0x6159, 0x3213,
+ 0x615a, 0x1e5d,
+ 0x615b, 0x3214,
+ 0x615d, 0x1a17,
+ 0x615e, 0x3216,
+ 0x615f, 0x23b7,
+ 0x6160, 0x3217,
+ 0x6162, 0x0aa4,
+ 0x6163, 0x1f2f,
+ 0x6164, 0x24df,
+ 0x6165, 0x3219,
+ 0x6167, 0x07f0,
+ 0x6168, 0x093b,
+ 0x6169, 0x321b,
+ 0x616a, 0x23b2,
+ 0x616b, 0x214e,
+ 0x616c, 0x321c,
+ 0x616e, 0x2052,
+ 0x616f, 0x321e,
+ 0x6170, 0x0ece,
+ 0x6171, 0x321f,
+ 0x6173, 0x23bc,
+ 0x6174, 0x3221,
+ 0x6175, 0x167c,
+ 0x6176, 0x20eb,
+ 0x6177, 0x0943,
+ 0x6178, 0x3222,
+ 0x6182, 0x2232,
+ 0x6183, 0x322c,
+ 0x618a, 0x1e3f,
+ 0x618b, 0x0458,
+ 0x618c, 0x3233,
+ 0x618e, 0x113a,
+ 0x618f, 0x3235,
+ 0x6190, 0x201b,
+ 0x6191, 0x20bc,
+ 0x6192, 0x23be,
+ 0x6193, 0x3236,
+ 0x6194, 0x167e,
+ 0x6195, 0x3237,
+ 0x619a, 0x1eae,
+ 0x619b, 0x323c,
+ 0x619d, 0x1a19,
+ 0x619e, 0x323e,
+ 0x61a4, 0x1efb,
+ 0x61a5, 0x3244,
+ 0x61a7, 0x167f,
+ 0x61a8, 0x0760,
+ 0x61a9, 0x1a18,
+ 0x61aa, 0x3246,
+ 0x61ab, 0x2089,
+ 0x61ac, 0x167d,
+ 0x61ad, 0x3247,
+ 0x61ae, 0x23b1,
+ 0x61af, 0x3248,
+ 0x61b2, 0x21c4,
+ 0x61b3, 0x324b,
+ 0x61b6, 0x2214,
+ 0x61b7, 0x1680,
+ 0x61b8, 0x324e,
+ 0x61be, 0x076d,
+ 0x61bf, 0x3254,
+ 0x61c2, 0x05ed,
+ 0x61c3, 0x3257,
+ 0x61c7, 0x1fde,
+ 0x61c8, 0x0f83,
+ 0x61c9, 0x2223,
+ 0x61ca, 0x03ce,
+ 0x61cb, 0x1a1a,
+ 0x61cc, 0x23b6,
+ 0x61cd, 0x325b,
+ 0x61d1, 0x1a1b,
+ 0x61d2, 0x09ac,
+ 0x61d3, 0x325f,
+ 0x61d4, 0x1681,
+ 0x61d5, 0x3260,
+ 0x61de, 0x268c,
+ 0x61df, 0x24de,
+ 0x61e0, 0x3269,
+ 0x61e3, 0x24e0,
+ 0x61e4, 0x326c,
+ 0x61e6, 0x0b74,
+ 0x61e7, 0x326e,
+ 0x61e8, 0x23b8,
+ 0x61e9, 0x326f,
+ 0x61f2, 0x1e81,
+ 0x61f3, 0x3278,
+ 0x61f5, 0x1682,
+ 0x61f6, 0x1ffe,
+ 0x61f7, 0x1f51,
+ 0x61f8, 0x21e1,
+ 0x61f9, 0x327a,
+ 0x61fa, 0x23b0,
+ 0x61fb, 0x327b,
+ 0x61fc, 0x1fce,
+ 0x61fd, 0x327c,
+ 0x61fe, 0x211e,
+ 0x61ff, 0x13e0,
+ 0x6200, 0x2021,
+ 0x6201, 0x327d,
+ 0x6206, 0x1a1c,
+ 0x6207, 0x24e1,
+ 0x6208, 0x06e5,
+ 0x6209, 0x3282,
+ 0x620a, 0x0efb,
+ 0x620b, 0x18f9,
+ 0x620c, 0x0fb2,
+ 0x620d, 0x0d90,
+ 0x620e, 0x0cb1,
+ 0x620f, 0x0f24,
+ 0x6210, 0x04ee,
+ 0x6211, 0x0ee1,
+ 0x6212, 0x08b5,
+ 0x6213, 0x3283,
+ 0x6214, 0x24a3,
+ 0x6215, 0x169e,
+ 0x6216, 0x0807,
+ 0x6217, 0x18fa,
+ 0x6218, 0x115e,
+ 0x6219, 0x3284,
+ 0x621a, 0x0bfc,
+ 0x621b, 0x18fb,
+ 0x621c, 0x3285,
+ 0x621f, 0x18fc,
+ 0x6220, 0x3288,
+ 0x6221, 0x18fe,
+ 0x6222, 0x18fd,
+ 0x6223, 0x3289,
+ 0x6224, 0x1900,
+ 0x6225, 0x18ff,
+ 0x6226, 0x328a,
+ 0x6227, 0x24a4,
+ 0x6228, 0x328b,
+ 0x622a, 0x08a9,
+ 0x622b, 0x328d,
+ 0x622c, 0x1901,
+ 0x622d, 0x328e,
+ 0x622e, 0x0a65,
+ 0x622f, 0x328f,
+ 0x6230, 0x2273,
+ 0x6231, 0x3290,
+ 0x6232, 0x21b0,
+ 0x6233, 0x0544,
+ 0x6234, 0x057a,
+ 0x6235, 0x3291,
+ 0x6237, 0x07bc,
+ 0x6238, 0x3293,
+ 0x623d, 0x19f4,
+ 0x623e, 0x19f3,
+ 0x623f, 0x065c,
+ 0x6240, 0x0dee,
+ 0x6241, 0x044b,
+ 0x6242, 0x3298,
+ 0x6243, 0x19f5,
+ 0x6244, 0x3299,
+ 0x6247, 0x0d01,
+ 0x6248, 0x19f6,
+ 0x624a, 0x329c,
+ 0x624b, 0x0d6d,
+ 0x624c, 0x14ba,
+ 0x624d, 0x048c,
+ 0x624e, 0x113d,
+ 0x624f, 0x329d,
+ 0x6251, 0x0bea,
+ 0x6252, 0x03d2,
+ 0x6253, 0x0575,
+ 0x6254, 0x0cae,
+ 0x6255, 0x329f,
+ 0x6258, 0x0e81,
+ 0x6259, 0x32a2,
+ 0x625b, 0x0945,
+ 0x625c, 0x32a4,
+ 0x6263, 0x0968,
+ 0x6264, 0x32ab,
+ 0x6266, 0x0c21,
+ 0x6267, 0x11b3,
+ 0x6268, 0x32ad,
+ 0x6269, 0x0994,
+ 0x626a, 0x14bb,
+ 0x626b, 0x0ce1,
+ 0x626c, 0x1018,
+ 0x626d, 0x0b65,
+ 0x626e, 0x03f2,
+ 0x626f, 0x04db,
+ 0x6270, 0x0ca0,
+ 0x6271, 0x32ae,
+ 0x6273, 0x03ed,
+ 0x6274, 0x32b0,
+ 0x6276, 0x0693,
+ 0x6277, 0x32b2,
+ 0x6279, 0x0bbb,
+ 0x627a, 0x32b4,
+ 0x627c, 0x0632,
+ 0x627d, 0x32b6,
+ 0x627e, 0x1173,
+ 0x627f, 0x04f5,
+ 0x6280, 0x082f,
+ 0x6281, 0x32b7,
+ 0x6284, 0x04d2,
+ 0x6285, 0x32ba,
+ 0x6289, 0x0920,
+ 0x628a, 0x03dc,
+ 0x628b, 0x32be,
+ 0x6291, 0x105d,
+ 0x6292, 0x0d7a,
+ 0x6293, 0x1202,
+ 0x6294, 0x32c4,
+ 0x6295, 0x0e67,
+ 0x6296, 0x05f5,
+ 0x6297, 0x0946,
+ 0x6298, 0x117c,
+ 0x6299, 0x32c5,
+ 0x629a, 0x06a2,
+ 0x629b, 0x0b98,
+ 0x629c, 0x32c6,
+ 0x629f, 0x14bc,
+ 0x62a0, 0x0966,
+ 0x62a1, 0x0a7c,
+ 0x62a2, 0x0c3d,
+ 0x62a3, 0x32c9,
+ 0x62a4, 0x07b9,
+ 0x62a5, 0x0411,
+ 0x62a6, 0x32ca,
+ 0x62a8, 0x0bab,
+ 0x62a9, 0x32cc,
+ 0x62ab, 0x0bbc,
+ 0x62ac, 0x0dfa,
+ 0x62ad, 0x32ce,
+ 0x62b1, 0x0410,
+ 0x62b2, 0x32d2,
+ 0x62b5, 0x05b7,
+ 0x62b6, 0x32d5,
+ 0x62b9, 0x0b0b,
+ 0x62ba, 0x32d8,
+ 0x62bb, 0x14bd,
+ 0x62bc, 0x0fe3,
+ 0x62bd, 0x050e,
+ 0x62be, 0x32d9,
+ 0x62bf, 0x0af7,
+ 0x62c0, 0x32da,
+ 0x62c2, 0x0694,
+ 0x62c3, 0x32dc,
+ 0x62c4, 0x11f3,
+ 0x62c5, 0x0584,
+ 0x62c6, 0x04b7,
+ 0x62c7, 0x0b17,
+ 0x62c8, 0x0b4c,
+ 0x62c9, 0x0998,
+ 0x62ca, 0x14be,
+ 0x62cb, 0x32dd,
+ 0x62cc, 0x03f3,
+ 0x62cd, 0x0b85,
+ 0x62ce, 0x0a29,
+ 0x62cf, 0x32de,
+ 0x62d0, 0x072e,
+ 0x62d1, 0x32df,
+ 0x62d2, 0x090b,
+ 0x62d3, 0x0e89,
+ 0x62d4, 0x03d9,
+ 0x62d5, 0x32e0,
+ 0x62d6, 0x0e80,
+ 0x62d7, 0x14c0,
+ 0x62d8, 0x08ff,
+ 0x62d9, 0x121b,
+ 0x62da, 0x14bf,
+ 0x62db, 0x1171,
+ 0x62dc, 0x03e8,
+ 0x62dd, 0x32e1,
+ 0x62df, 0x0b45,
+ 0x62e0, 0x32e3,
+ 0x62e2, 0x0a4a,
+ 0x62e3, 0x0863,
+ 0x62e4, 0x32e5,
+ 0x62e5, 0x109a,
+ 0x62e6, 0x09a4,
+ 0x62e7, 0x0b62,
+ 0x62e8, 0x046d,
+ 0x62e9, 0x1134,
+ 0x62ea, 0x32e6,
+ 0x62ec, 0x0993,
+ 0x62ed, 0x0d5a,
+ 0x62ee, 0x14c1,
+ 0x62ef, 0x119d,
+ 0x62f0, 0x32e8,
+ 0x62f1, 0x0709,
+ 0x62f2, 0x32e9,
+ 0x62f3, 0x0c88,
+ 0x62f4, 0x0d9e,
+ 0x62f5, 0x32ea,
+ 0x62f6, 0x14c3,
+ 0x62f7, 0x094a,
+ 0x62f8, 0x32eb,
+ 0x62fc, 0x0bd3,
+ 0x62fd, 0x1204,
+ 0x62fe, 0x0d47,
+ 0x62ff, 0x0b26,
+ 0x6300, 0x32ef,
+ 0x6301, 0x04fb,
+ 0x6302, 0x072b,
+ 0x6303, 0x32f0,
+ 0x6307, 0x11b7,
+ 0x6308, 0x194e,
+ 0x6309, 0x03bf,
+ 0x630a, 0x32f4,
+ 0x630e, 0x0973,
+ 0x630f, 0x32f8,
+ 0x6311, 0x0e47,
+ 0x6312, 0x32fa,
+ 0x6316, 0x0e8b,
+ 0x6317, 0x32fe,
+ 0x631a, 0x11be,
+ 0x631b, 0x0a75,
+ 0x631c, 0x3301,
+ 0x631d, 0x0edd,
+ 0x631e, 0x0df5,
+ 0x631f, 0x0f79,
+ 0x6320, 0x0b36,
+ 0x6321, 0x0593,
+ 0x6322, 0x14c2,
+ 0x6323, 0x1196,
+ 0x6324, 0x082a,
+ 0x6325, 0x07e8,
+ 0x6326, 0x3302,
+ 0x6328, 0x03af,
+ 0x6329, 0x3304,
+ 0x632a, 0x0b73,
+ 0x632b, 0x056f,
+ 0x632c, 0x3305,
+ 0x632f, 0x1192,
+ 0x6330, 0x3308,
+ 0x6332, 0x194f,
+ 0x6333, 0x330a,
+ 0x6339, 0x14c4,
+ 0x633a, 0x0e57,
+ 0x633b, 0x3310,
+ 0x633d, 0x0e9d,
+ 0x633e, 0x21d1,
+ 0x633f, 0x3312,
+ 0x6342, 0x0ef5,
+ 0x6343, 0x14c6,
+ 0x6344, 0x3315,
+ 0x6345, 0x0e62,
+ 0x6346, 0x0991,
+ 0x6347, 0x3316,
+ 0x6349, 0x121a,
+ 0x634a, 0x3318,
+ 0x634b, 0x14c5,
+ 0x634c, 0x03d1,
+ 0x634d, 0x076b,
+ 0x634e, 0x0d0c,
+ 0x634f, 0x0b56,
+ 0x6350, 0x0917,
+ 0x6351, 0x3319,
+ 0x6355, 0x047d,
+ 0x6356, 0x331d,
+ 0x635e, 0x09b7,
+ 0x635f, 0x0de5,
+ 0x6360, 0x3325,
+ 0x6361, 0x0864,
+ 0x6362, 0x07d0,
+ 0x6363, 0x0598,
+ 0x6364, 0x3326,
+ 0x6367, 0x0bb6,
+ 0x6368, 0x211c,
+ 0x6369, 0x14d0,
+ 0x636a, 0x3329,
+ 0x636b, 0x235d,
+ 0x636c, 0x332a,
+ 0x636d, 0x14cd,
+ 0x636e, 0x090c,
+ 0x636f, 0x332b,
+ 0x6371, 0x14c9,
+ 0x6372, 0x2682,
+ 0x6373, 0x332d,
+ 0x6376, 0x053a,
+ 0x6377, 0x08ae,
+ 0x6378, 0x3330,
+ 0x637a, 0x14ca,
+ 0x637b, 0x0b50,
+ 0x637c, 0x3332,
+ 0x6380, 0x0f33,
+ 0x6381, 0x3336,
+ 0x6382, 0x05c1,
+ 0x6383, 0x210d,
+ 0x6384, 0x205a,
+ 0x6385, 0x3337,
+ 0x6387, 0x061d,
+ 0x6388, 0x0d71,
+ 0x6389, 0x05d5,
+ 0x638a, 0x14cf,
+ 0x638b, 0x3339,
+ 0x638c, 0x1167,
+ 0x638d, 0x333a,
+ 0x638e, 0x14cb,
+ 0x638f, 0x0e20,
+ 0x6390, 0x0c1d,
+ 0x6391, 0x333b,
+ 0x6392, 0x0b86,
+ 0x6393, 0x333c,
+ 0x6396, 0x103b,
+ 0x6397, 0x333f,
+ 0x6398, 0x0921,
+ 0x6399, 0x3340,
+ 0x63a0, 0x0a7a,
+ 0x63a1, 0x3347,
+ 0x63a2, 0x0e10,
+ 0x63a3, 0x04dd,
+ 0x63a4, 0x3348,
+ 0x63a5, 0x08a4,
+ 0x63a6, 0x3349,
+ 0x63a7, 0x0965,
+ 0x63a8, 0x0e77,
+ 0x63a9, 0x1003,
+ 0x63aa, 0x056e,
+ 0x63ab, 0x334a,
+ 0x63ac, 0x14ce,
+ 0x63ad, 0x14c7,
+ 0x63ae, 0x14d1,
+ 0x63af, 0x334b,
+ 0x63b0, 0x1950,
+ 0x63b1, 0x334c,
+ 0x63b3, 0x0a57,
+ 0x63b4, 0x14cc,
+ 0x63b5, 0x334e,
+ 0x63b7, 0x11bf,
+ 0x63b8, 0x0588,
+ 0x63b9, 0x3350,
+ 0x63ba, 0x04bb,
+ 0x63bb, 0x3351,
+ 0x63bc, 0x14d2,
+ 0x63bd, 0x3352,
+ 0x63be, 0x14dc,
+ 0x63bf, 0x3353,
+ 0x63c0, 0x1f8d,
+ 0x63c1, 0x3354,
+ 0x63c4, 0x14d7,
+ 0x63c5, 0x3357,
+ 0x63c6, 0x14db,
+ 0x63c7, 0x3358,
+ 0x63c9, 0x0cbb,
+ 0x63ca, 0x335a,
+ 0x63cd, 0x123e,
+ 0x63ce, 0x14d9,
+ 0x63cf, 0x0aed,
+ 0x63d0, 0x0e34,
+ 0x63d1, 0x335d,
+ 0x63d2, 0x04ac,
+ 0x63d3, 0x335e,
+ 0x63d6, 0x1045,
+ 0x63d7, 0x3361,
+ 0x63da, 0x21ff,
+ 0x63db, 0x3364,
+ 0x63de, 0x14d8,
+ 0x63df, 0x3367,
+ 0x63e0, 0x14d5,
+ 0x63e1, 0x0ee4,
+ 0x63e2, 0x3368,
+ 0x63e3, 0x052a,
+ 0x63e4, 0x3369,
+ 0x63e9, 0x0938,
+ 0x63ea, 0x08ed,
+ 0x63eb, 0x336e,
+ 0x63ed, 0x08a3,
+ 0x63ee, 0x1f58,
+ 0x63ef, 0x3370,
+ 0x63f2, 0x14d3,
+ 0x63f3, 0x3373,
+ 0x63f4, 0x10f1,
+ 0x63f5, 0x3374,
+ 0x63f6, 0x14c8,
+ 0x63f7, 0x3375,
+ 0x63f8, 0x14d4,
+ 0x63f9, 0x3376,
+ 0x63fd, 0x09aa,
+ 0x63fe, 0x337a,
+ 0x63ff, 0x14d6,
+ 0x6400, 0x04ba,
+ 0x6401, 0x06e4,
+ 0x6402, 0x0a4e,
+ 0x6403, 0x337b,
+ 0x6405, 0x0892,
+ 0x6406, 0x337d,
+ 0x640b, 0x14df,
+ 0x640c, 0x14e2,
+ 0x640d, 0x215b,
+ 0x640e, 0x3382,
+ 0x640f, 0x0472,
+ 0x6410, 0x0527,
+ 0x6411, 0x3383,
+ 0x6413, 0x056d,
+ 0x6414, 0x0cdf,
+ 0x6415, 0x3385,
+ 0x6417, 0x1eb6,
+ 0x6418, 0x3387,
+ 0x641b, 0x14e0,
+ 0x641c, 0x0dc6,
+ 0x641d, 0x338a,
+ 0x641e, 0x06de,
+ 0x641f, 0x338b,
+ 0x6420, 0x14e1,
+ 0x6421, 0x14e4,
+ 0x6422, 0x338c,
+ 0x6426, 0x14e3,
+ 0x6427, 0x3390,
+ 0x642a, 0x0e15,
+ 0x642b, 0x3393,
+ 0x642c, 0x03ec,
+ 0x642d, 0x0571,
+ 0x642e, 0x3394,
+ 0x6434, 0x1736,
+ 0x6435, 0x339a,
+ 0x6436, 0x20db,
+ 0x6437, 0x339b,
+ 0x643a, 0x0f7a,
+ 0x643b, 0x339e,
+ 0x643d, 0x04b2,
+ 0x643e, 0x33a0,
+ 0x643f, 0x1951,
+ 0x6440, 0x33a1,
+ 0x6441, 0x14de,
+ 0x6442, 0x33a2,
+ 0x6444, 0x0d1c,
+ 0x6445, 0x14dd,
+ 0x6446, 0x03e5,
+ 0x6447, 0x1028,
+ 0x6448, 0x0460,
+ 0x6449, 0x33a4,
+ 0x644a, 0x0e02,
+ 0x644b, 0x33a5,
+ 0x6451, 0x2360,
+ 0x6452, 0x14da,
+ 0x6453, 0x33ab,
+ 0x6454, 0x0d99,
+ 0x6455, 0x33ac,
+ 0x6458, 0x114b,
+ 0x6459, 0x33af,
+ 0x645c, 0x2361,
+ 0x645d, 0x33b2,
+ 0x645e, 0x14e5,
+ 0x645f, 0x2040,
+ 0x6460, 0x33b3,
+ 0x6467, 0x0560,
+ 0x6468, 0x33ba,
+ 0x6469, 0x0b09,
+ 0x646a, 0x33bb,
+ 0x646d, 0x14e7,
+ 0x646e, 0x33be,
+ 0x646f, 0x228e,
+ 0x6470, 0x33bf,
+ 0x6473, 0x1fdf,
+ 0x6474, 0x33c2,
+ 0x6476, 0x235e,
+ 0x6477, 0x33c4,
+ 0x6478, 0x0b03,
+ 0x647a, 0x14e9,
+ 0x647b, 0x1e6a,
+ 0x647c, 0x33c5,
+ 0x6482, 0x0a15,
+ 0x6483, 0x33cb,
+ 0x6484, 0x14e6,
+ 0x6485, 0x091e,
+ 0x6486, 0x33cc,
+ 0x6487, 0x0bd1,
+ 0x6488, 0x2002,
+ 0x6489, 0x33cd,
+ 0x6491, 0x04ea,
+ 0x6492, 0x0cd1,
+ 0x6493, 0x2093,
+ 0x6494, 0x33d5,
+ 0x6495, 0x0daf,
+ 0x6496, 0x14e8,
+ 0x6497, 0x33d6,
+ 0x6499, 0x14ec,
+ 0x649a, 0x33d8,
+ 0x649e, 0x120f,
+ 0x649f, 0x235f,
+ 0x64a0, 0x33dc,
+ 0x64a3, 0x1eac,
+ 0x64a4, 0x04dc,
+ 0x64a5, 0x1e54,
+ 0x64a6, 0x33df,
+ 0x64a9, 0x0a0c,
+ 0x64aa, 0x33e2,
+ 0x64ab, 0x1f08,
+ 0x64ac, 0x0c48,
+ 0x64ad, 0x046c,
+ 0x64ae, 0x056c,
+ 0x64af, 0x33e3,
+ 0x64b0, 0x1208,
+ 0x64b1, 0x33e4,
+ 0x64b2, 0x20c0,
+ 0x64b3, 0x2362,
+ 0x64b4, 0x33e5,
+ 0x64b5, 0x0b4f,
+ 0x64b6, 0x33e6,
+ 0x64b7, 0x14ea,
+ 0x64b9, 0x33e7,
+ 0x64ba, 0x14ed,
+ 0x64bb, 0x2160,
+ 0x64bc, 0x076a,
+ 0x64bd, 0x33e8,
+ 0x64be, 0x219d,
+ 0x64bf, 0x1f8e,
+ 0x64c0, 0x14ee,
+ 0x64c1, 0x222d,
+ 0x64c2, 0x09c9,
+ 0x64c3, 0x33e9,
+ 0x64c4, 0x2047,
+ 0x64c5, 0x0cfc,
+ 0x64c6, 0x33ea,
+ 0x64c7, 0x2262,
+ 0x64c8, 0x33eb,
+ 0x64ca, 0x1f67,
+ 0x64cb, 0x1eb2,
+ 0x64cc, 0x33ed,
+ 0x64cd, 0x04a0,
+ 0x64ce, 0x0c63,
+ 0x64cf, 0x33ee,
+ 0x64d0, 0x14ef,
+ 0x64d1, 0x33ef,
+ 0x64d2, 0x0c59,
+ 0x64d3, 0x33f0,
+ 0x64d4, 0x1ea9,
+ 0x64d5, 0x33f1,
+ 0x64d7, 0x14f0,
+ 0x64d8, 0x1952,
+ 0x64d9, 0x33f3,
+ 0x64da, 0x1fcc,
+ 0x64db, 0x33f4,
+ 0x64de, 0x0dc8,
+ 0x64df, 0x33f7,
+ 0x64e0, 0x1f72,
+ 0x64e1, 0x33f8,
+ 0x64e2, 0x14f2,
+ 0x64e3, 0x33f9,
+ 0x64e4, 0x14f1,
+ 0x64e5, 0x33fa,
+ 0x64e6, 0x0488,
+ 0x64e7, 0x33fb,
+ 0x64ec, 0x2098,
+ 0x64ed, 0x3400,
+ 0x64ef, 0x1e52,
+ 0x64f0, 0x20a4,
+ 0x64f1, 0x1f1c,
+ 0x64f2, 0x228f,
+ 0x64f3, 0x3402,
+ 0x64f4, 0x1fed,
+ 0x64f5, 0x3403,
+ 0x64f7, 0x2365,
+ 0x64f8, 0x3405,
+ 0x64fa, 0x1e2d,
+ 0x64fb, 0x2152,
+ 0x64fc, 0x2366,
+ 0x64fd, 0x3407,
+ 0x64fe, 0x20fa,
+ 0x64ff, 0x3408,
+ 0x6500, 0x0b8b,
+ 0x6501, 0x3409,
+ 0x6504, 0x2363,
+ 0x6505, 0x340c,
+ 0x6506, 0x209a,
+ 0x6507, 0x340d,
+ 0x6509, 0x14f3,
+ 0x650a, 0x340f,
+ 0x650f, 0x203c,
+ 0x6510, 0x3414,
+ 0x6512, 0x111f,
+ 0x6513, 0x3416,
+ 0x6514, 0x1ff6,
+ 0x6515, 0x3417,
+ 0x6516, 0x2364,
+ 0x6517, 0x3418,
+ 0x6518, 0x0c9c,
+ 0x6519, 0x1e69,
+ 0x651a, 0x3419,
+ 0x651b, 0x2367,
+ 0x651c, 0x341a,
+ 0x651d, 0x211d,
+ 0x651e, 0x341b,
+ 0x6522, 0x2259,
+ 0x6523, 0x2056,
+ 0x6524, 0x2163,
+ 0x6525, 0x14f4,
+ 0x6526, 0x341f,
+ 0x652a, 0x1fa9,
+ 0x652b, 0x091f,
+ 0x652c, 0x1ffc,
+ 0x652d, 0x3423,
+ 0x652e, 0x14f5,
+ 0x652f, 0x11a6,
+ 0x6530, 0x3424,
+ 0x6534, 0x1909,
+ 0x6535, 0x1966,
+ 0x6536, 0x0d6c,
+ 0x6537, 0x3428,
+ 0x6538, 0x12b2,
+ 0x6539, 0x06bf,
+ 0x653a, 0x3429,
+ 0x653b, 0x06fe,
+ 0x653c, 0x342a,
+ 0x653e, 0x0662,
+ 0x653f, 0x119f,
+ 0x6540, 0x342c,
+ 0x6545, 0x0723,
+ 0x6546, 0x3431,
+ 0x6548, 0x0f72,
+ 0x6549, 0x1ccb,
+ 0x654a, 0x3433,
+ 0x654c, 0x05b1,
+ 0x654d, 0x3435,
+ 0x654f, 0x0af9,
+ 0x6550, 0x3437,
+ 0x6551, 0x08f7,
+ 0x6552, 0x3438,
+ 0x6555, 0x1967,
+ 0x6556, 0x03c8,
+ 0x6557, 0x1e2e,
+ 0x6558, 0x343b,
+ 0x6559, 0x089d,
+ 0x655a, 0x343c,
+ 0x655b, 0x09fb,
+ 0x655c, 0x343d,
+ 0x655d, 0x043f,
+ 0x655e, 0x04cd,
+ 0x655f, 0x343e,
+ 0x6562, 0x06cd,
+ 0x6563, 0x0cdb,
+ 0x6564, 0x3441,
+ 0x6566, 0x0617,
+ 0x6567, 0x3443,
+ 0x656b, 0x1968,
+ 0x656c, 0x08e3,
+ 0x656d, 0x3447,
+ 0x6570, 0x0d94,
+ 0x6571, 0x344a,
+ 0x6572, 0x0c40,
+ 0x6573, 0x344b,
+ 0x6574, 0x119c,
+ 0x6575, 0x1ebc,
+ 0x6576, 0x344c,
+ 0x6577, 0x0690,
+ 0x6578, 0x2142,
+ 0x6579, 0x344d,
+ 0x6582, 0x201e,
+ 0x6583, 0x1e43,
+ 0x6584, 0x3456,
+ 0x6587, 0x0ed3,
+ 0x6588, 0x3459,
+ 0x658b, 0x114c,
+ 0x658c, 0x045c,
+ 0x658d, 0x345c,
+ 0x6590, 0x19c1,
+ 0x6591, 0x03ea,
+ 0x6592, 0x345f,
+ 0x6593, 0x19c3,
+ 0x6594, 0x3460,
+ 0x6595, 0x24d4,
+ 0x6596, 0x3461,
+ 0x6597, 0x05f6,
+ 0x6598, 0x3462,
+ 0x6599, 0x0a18,
+ 0x659a, 0x3463,
+ 0x659b, 0x1d56,
+ 0x659c, 0x0f7c,
+ 0x659d, 0x3464,
+ 0x659f, 0x1186,
+ 0x65a0, 0x3466,
+ 0x65a1, 0x0ee2,
+ 0x65a2, 0x3467,
+ 0x65a4, 0x08c0,
+ 0x65a5, 0x0507,
+ 0x65a6, 0x3469,
+ 0x65a7, 0x06a6,
+ 0x65a8, 0x346a,
+ 0x65a9, 0x1157,
+ 0x65aa, 0x346b,
+ 0x65ab, 0x1a29,
+ 0x65ac, 0x226f,
+ 0x65ad, 0x060e,
+ 0x65ae, 0x346c,
+ 0x65af, 0x0dae,
+ 0x65b0, 0x0f8d,
+ 0x65b1, 0x346d,
+ 0x65b7, 0x1ed7,
+ 0x65b8, 0x3473,
+ 0x65b9, 0x065a,
+ 0x65ba, 0x3474,
+ 0x65bc, 0x19c4,
+ 0x65bd, 0x0d40,
+ 0x65be, 0x3476,
+ 0x65c1, 0x0b95,
+ 0x65c2, 0x3479,
+ 0x65c3, 0x19c7,
+ 0x65c4, 0x19c6,
+ 0x65c5, 0x0a6a,
+ 0x65c6, 0x19c5,
+ 0x65c7, 0x347a,
+ 0x65cb, 0x0fc8,
+ 0x65cc, 0x19c8,
+ 0x65cd, 0x347e,
+ 0x65ce, 0x19c9,
+ 0x65cf, 0x1242,
+ 0x65d0, 0x347f,
+ 0x65d2, 0x19ca,
+ 0x65d3, 0x3481,
+ 0x65d6, 0x19cb,
+ 0x65d7, 0x0c0b,
+ 0x65d8, 0x3484,
+ 0x65e0, 0x0eed,
+ 0x65e1, 0x348c,
+ 0x65e2, 0x083b,
+ 0x65e3, 0x348d,
+ 0x65e5, 0x0cb0,
+ 0x65e6, 0x058a,
+ 0x65e7, 0x08f8,
+ 0x65e8, 0x11bb,
+ 0x65e9, 0x112a,
+ 0x65ea, 0x348f,
+ 0x65ec, 0x0fd7,
+ 0x65ed, 0x0fbc,
+ 0x65ee, 0x190a,
+ 0x65f1, 0x076c,
+ 0x65f2, 0x3491,
+ 0x65f6, 0x0d48,
+ 0x65f7, 0x0982,
+ 0x65f8, 0x3495,
+ 0x65fa, 0x0eab,
+ 0x65fb, 0x3497,
+ 0x6600, 0x1912,
+ 0x6601, 0x349c,
+ 0x6602, 0x03c5,
+ 0x6603, 0x1910,
+ 0x6604, 0x349d,
+ 0x6606, 0x0990,
+ 0x6607, 0x349f,
+ 0x660a, 0x190d,
+ 0x660b, 0x34a2,
+ 0x660c, 0x04c4,
+ 0x660d, 0x34a3,
+ 0x660e, 0x0afc,
+ 0x660f, 0x07fd,
+ 0x6610, 0x34a4,
+ 0x6613, 0x105e,
+ 0x6614, 0x0f03,
+ 0x6615, 0x1911,
+ 0x6616, 0x34a7,
+ 0x6619, 0x190e,
+ 0x661a, 0x34aa,
+ 0x661d, 0x1915,
+ 0x661e, 0x34ad,
+ 0x661f, 0x0f92,
+ 0x6620, 0x1098,
+ 0x6621, 0x34ae,
+ 0x6625, 0x053d,
+ 0x6626, 0x34b2,
+ 0x6627, 0x0ac6,
+ 0x6628, 0x124f,
+ 0x6629, 0x34b3,
+ 0x662d, 0x1172,
+ 0x662e, 0x34b7,
+ 0x662f, 0x0d5e,
+ 0x6630, 0x34b8,
+ 0x6631, 0x1917,
+ 0x6632, 0x34b9,
+ 0x6634, 0x1916,
+ 0x6635, 0x1919,
+ 0x6636, 0x1918,
+ 0x6637, 0x34bb,
+ 0x663c, 0x11e6,
+ 0x663d, 0x34c0,
+ 0x663e, 0x0f41,
+ 0x663f, 0x34c1,
+ 0x6641, 0x191d,
+ 0x6642, 0x212d,
+ 0x6643, 0x07e3,
+ 0x6644, 0x34c3,
+ 0x664b, 0x08cb,
+ 0x664c, 0x0d07,
+ 0x664d, 0x34ca,
+ 0x664f, 0x191e,
+ 0x6650, 0x34cc,
+ 0x6652, 0x0cf2,
+ 0x6653, 0x0f6b,
+ 0x6654, 0x191c,
+ 0x6655, 0x1111,
+ 0x6656, 0x191f,
+ 0x6657, 0x1921,
+ 0x6658, 0x34ce,
+ 0x665a, 0x0e9e,
+ 0x665b, 0x34d0,
+ 0x665d, 0x229b,
+ 0x665e, 0x34d2,
+ 0x665f, 0x191b,
+ 0x6660, 0x34d3,
+ 0x6661, 0x1920,
+ 0x6662, 0x34d4,
+ 0x6664, 0x0efd,
+ 0x6665, 0x34d6,
+ 0x6666, 0x07f3,
+ 0x6667, 0x34d7,
+ 0x6668, 0x04e4,
+ 0x6669, 0x34d8,
+ 0x666e, 0x0bf4,
+ 0x666f, 0x08df,
+ 0x6670, 0x0f09,
+ 0x6671, 0x34dd,
+ 0x6674, 0x0c64,
+ 0x6675, 0x34e0,
+ 0x6676, 0x08d6,
+ 0x6677, 0x1922,
+ 0x6678, 0x34e1,
+ 0x667a, 0x11c6,
+ 0x667b, 0x34e3,
+ 0x667e, 0x0a09,
+ 0x667f, 0x34e6,
+ 0x6682, 0x1120,
+ 0x6683, 0x34e9,
+ 0x6684, 0x1923,
+ 0x6685, 0x34ea,
+ 0x6687, 0x0f2b,
+ 0x6688, 0x2256,
+ 0x6689, 0x24a8,
+ 0x668a, 0x34ec,
+ 0x668c, 0x1924,
+ 0x668d, 0x34ee,
+ 0x6691, 0x0d85,
+ 0x6692, 0x34f2,
+ 0x6696, 0x0b70,
+ 0x6697, 0x03c0,
+ 0x6698, 0x34f6,
+ 0x669d, 0x1926,
+ 0x669e, 0x34fb,
+ 0x66a2, 0x1e79,
+ 0x66a3, 0x34ff,
+ 0x66a7, 0x1925,
+ 0x66a8, 0x1cdd,
+ 0x66a9, 0x3503,
+ 0x66ab, 0x225a,
+ 0x66ac, 0x3505,
+ 0x66ae, 0x0b1d,
+ 0x66af, 0x3507,
+ 0x66b4, 0x0412,
+ 0x66b5, 0x350c,
+ 0x66b9, 0x175b,
+ 0x66ba, 0x3510,
+ 0x66be, 0x1927,
+ 0x66bf, 0x3514,
+ 0x66c4, 0x24a7,
+ 0x66c5, 0x3519,
+ 0x66c6, 0x2686,
+ 0x66c7, 0x24a6,
+ 0x66c8, 0x351a,
+ 0x66c9, 0x21ce,
+ 0x66ca, 0x351b,
+ 0x66d6, 0x24a9,
+ 0x66d7, 0x3527,
+ 0x66d9, 0x0d86,
+ 0x66da, 0x3529,
+ 0x66db, 0x1928,
+ 0x66dd, 0x0bf7,
+ 0x66de, 0x352a,
+ 0x66e0, 0x1fe7,
+ 0x66e1, 0x352c,
+ 0x66e6, 0x192a,
+ 0x66e7, 0x3531,
+ 0x66e9, 0x192b,
+ 0x66ea, 0x3533,
+ 0x66ec, 0x2112,
+ 0x66ed, 0x3535,
+ 0x66f0, 0x10fe,
+ 0x66f1, 0x3538,
+ 0x66f2, 0x0c77,
+ 0x66f3, 0x103e,
+ 0x66f4, 0x06f7,
+ 0x66f5, 0x3539,
+ 0x66f7, 0x1914,
+ 0x66f8, 0x213c,
+ 0x66f9, 0x04a3,
+ 0x66fa, 0x353b,
+ 0x66fc, 0x0aa3,
+ 0x66fd, 0x353d,
+ 0x66fe, 0x113b,
+ 0x66ff, 0x0e39,
+ 0x6700, 0x124b,
+ 0x6701, 0x353e,
+ 0x6703, 0x1f5c,
+ 0x6704, 0x3540,
+ 0x6708, 0x1105,
+ 0x6709, 0x10b5,
+ 0x670a, 0x1973,
+ 0x670b, 0x0bb4,
+ 0x670c, 0x3544,
+ 0x670d, 0x069b,
+ 0x670e, 0x3545,
+ 0x6710, 0x1984,
+ 0x6711, 0x3547,
+ 0x6714, 0x0dac,
+ 0x6715, 0x198e,
+ 0x6716, 0x354a,
+ 0x6717, 0x09b5,
+ 0x6718, 0x354b,
+ 0x671b, 0x0eac,
+ 0x671c, 0x354e,
+ 0x671d, 0x04d4,
+ 0x671e, 0x354f,
+ 0x671f, 0x0bf9,
+ 0x6720, 0x3550,
+ 0x6726, 0x19ac,
+ 0x6727, 0x24c4,
+ 0x6728, 0x0b21,
+ 0x6729, 0x3556,
+ 0x672a, 0x0ec3,
+ 0x672b, 0x0b0c,
+ 0x672c, 0x0427,
+ 0x672d, 0x1140,
+ 0x672e, 0x3557,
+ 0x672f, 0x0d8c,
+ 0x6730, 0x3558,
+ 0x6731, 0x11eb,
+ 0x6732, 0x3559,
+ 0x6734, 0x0bf2,
+ 0x6735, 0x0623,
+ 0x6736, 0x355b,
+ 0x673a, 0x080f,
+ 0x673b, 0x355f,
+ 0x673d, 0x0fab,
+ 0x673e, 0x3561,
+ 0x6740, 0x0cea,
+ 0x6741, 0x3563,
+ 0x6742, 0x1116,
+ 0x6743, 0x0c83,
+ 0x6744, 0x3564,
+ 0x6746, 0x06c6,
+ 0x6747, 0x3566,
+ 0x6748, 0x1854,
+ 0x6749, 0x0cf5,
+ 0x674a, 0x3567,
+ 0x674c, 0x1851,
+ 0x674d, 0x3569,
+ 0x674e, 0x09d9,
+ 0x674f, 0x0f9e,
+ 0x6750, 0x048b,
+ 0x6751, 0x0568,
+ 0x6752, 0x356a,
+ 0x6753, 0x1852,
+ 0x6754, 0x356b,
+ 0x6756, 0x1169,
+ 0x6757, 0x356d,
+ 0x675c, 0x0604,
+ 0x675d, 0x3572,
+ 0x675e, 0x1853,
+ 0x675f, 0x0d8f,
+ 0x6760, 0x06d7,
+ 0x6761, 0x0e48,
+ 0x6762, 0x3573,
+ 0x6765, 0x099f,
+ 0x6766, 0x3576,
+ 0x6768, 0x1017,
+ 0x6769, 0x1855,
+ 0x676a, 0x1858,
+ 0x676b, 0x3578,
+ 0x676d, 0x0773,
+ 0x676e, 0x357a,
+ 0x676f, 0x0416,
+ 0x6770, 0x08ad,
+ 0x6771, 0x1ecc,
+ 0x6772, 0x190f,
+ 0x6773, 0x1859,
+ 0x6774, 0x357b,
+ 0x6775, 0x185c,
+ 0x6776, 0x357c,
+ 0x6777, 0x1861,
+ 0x6778, 0x357d,
+ 0x677c, 0x1862,
+ 0x677d, 0x3581,
+ 0x677e, 0x0dbe,
+ 0x677f, 0x03f0,
+ 0x6780, 0x3582,
+ 0x6781, 0x081e,
+ 0x6782, 0x3583,
+ 0x6784, 0x0712,
+ 0x6785, 0x3585,
+ 0x6787, 0x1857,
+ 0x6788, 0x3587,
+ 0x6789, 0x0ea8,
+ 0x678a, 0x3588,
+ 0x678b, 0x1860,
+ 0x678c, 0x3589,
+ 0x6790, 0x0f05,
+ 0x6791, 0x358d,
+ 0x6795, 0x118e,
+ 0x6796, 0x3591,
+ 0x6797, 0x0a1f,
+ 0x6798, 0x185a,
+ 0x6799, 0x3592,
+ 0x679a, 0x0abb,
+ 0x679b, 0x3593,
+ 0x679c, 0x0754,
+ 0x679d, 0x11a5,
+ 0x679e, 0x185e,
+ 0x679f, 0x3594,
+ 0x67a2, 0x0d77,
+ 0x67a3, 0x1129,
+ 0x67a4, 0x3597,
+ 0x67a5, 0x1856,
+ 0x67a6, 0x3598,
+ 0x67a7, 0x185b,
+ 0x67a8, 0x185d,
+ 0x67a9, 0x3599,
+ 0x67aa, 0x0c36,
+ 0x67ab, 0x0680,
+ 0x67ac, 0x359a,
+ 0x67ad, 0x185f,
+ 0x67ae, 0x359b,
+ 0x67af, 0x096a,
+ 0x67b0, 0x1868,
+ 0x67b1, 0x359c,
+ 0x67b3, 0x186d,
+ 0x67b4, 0x359e,
+ 0x67b5, 0x186b,
+ 0x67b6, 0x084f,
+ 0x67b7, 0x0842,
+ 0x67b8, 0x1871,
+ 0x67b9, 0x359f,
+ 0x67c1, 0x1874,
+ 0x67c2, 0x35a7,
+ 0x67c3, 0x1870,
+ 0x67c4, 0x0463,
+ 0x67c5, 0x35a8,
+ 0x67cf, 0x03e3,
+ 0x67d0, 0x0b16,
+ 0x67d1, 0x06c7,
+ 0x67d2, 0x0c01,
+ 0x67d3, 0x0c99,
+ 0x67d4, 0x0cbc,
+ 0x67d5, 0x35b2,
+ 0x67d8, 0x1865,
+ 0x67d9, 0x186a,
+ 0x67da, 0x186c,
+ 0x67db, 0x35b5,
+ 0x67dc, 0x074a,
+ 0x67dd, 0x186e,
+ 0x67de, 0x1252,
+ 0x67df, 0x35b6,
+ 0x67e0, 0x0b5e,
+ 0x67e1, 0x35b7,
+ 0x67e2, 0x1872,
+ 0x67e3, 0x35b8,
+ 0x67e5, 0x04b0,
+ 0x67e6, 0x35ba,
+ 0x67e9, 0x1867,
+ 0x67ea, 0x35bd,
+ 0x67ec, 0x0860,
+ 0x67ed, 0x35bf,
+ 0x67ef, 0x094f,
+ 0x67f0, 0x1863,
+ 0x67f1, 0x11f8,
+ 0x67f2, 0x35c1,
+ 0x67f3, 0x0a41,
+ 0x67f4, 0x04b8,
+ 0x67f5, 0x35c2,
+ 0x67fd, 0x1875,
+ 0x67fe, 0x35ca,
+ 0x67ff, 0x0d58,
+ 0x6800, 0x186f,
+ 0x6801, 0x35cb,
+ 0x6805, 0x1145,
+ 0x6806, 0x35cf,
+ 0x6807, 0x0453,
+ 0x6808, 0x115c,
+ 0x6809, 0x1864,
+ 0x680a, 0x1866,
+ 0x680b, 0x05ef,
+ 0x680c, 0x1869,
+ 0x680d, 0x35d0,
+ 0x680e, 0x1873,
+ 0x680f, 0x09a3,
+ 0x6810, 0x35d1,
+ 0x6811, 0x0d8e,
+ 0x6812, 0x35d2,
+ 0x6813, 0x0d9d,
+ 0x6814, 0x35d3,
+ 0x6816, 0x0bfb,
+ 0x6817, 0x09e0,
+ 0x6818, 0x35d5,
+ 0x681d, 0x187f,
+ 0x681e, 0x35da,
+ 0x6821, 0x0f6e,
+ 0x6822, 0x35dd,
+ 0x6829, 0x1888,
+ 0x682a, 0x11e9,
+ 0x682b, 0x35e4,
+ 0x6832, 0x1876,
+ 0x6834, 0x35eb,
+ 0x6837, 0x1022,
+ 0x6838, 0x0782,
+ 0x6839, 0x06f4,
+ 0x683a, 0x35ee,
+ 0x683c, 0x06ec,
+ 0x683d, 0x1117,
+ 0x683e, 0x1885,
+ 0x683f, 0x35f0,
+ 0x6840, 0x1884,
+ 0x6841, 0x1882,
+ 0x6842, 0x0749,
+ 0x6843, 0x0e25,
+ 0x6844, 0x187c,
+ 0x6845, 0x0eb5,
+ 0x6846, 0x097f,
+ 0x6847, 0x35f1,
+ 0x6848, 0x03c3,
+ 0x6849, 0x1887,
+ 0x684a, 0x1886,
+ 0x684b, 0x35f2,
+ 0x684c, 0x121d,
+ 0x684d, 0x35f3,
+ 0x684e, 0x187a,
+ 0x684f, 0x35f4,
+ 0x6850, 0x0e5a,
+ 0x6851, 0x0cdc,
+ 0x6852, 0x35f5,
+ 0x6853, 0x07cd,
+ 0x6854, 0x08ac,
+ 0x6855, 0x1880,
+ 0x6856, 0x35f6,
+ 0x6860, 0x1878,
+ 0x6862, 0x187b,
+ 0x6863, 0x0596,
+ 0x6864, 0x187d,
+ 0x6865, 0x0c42,
+ 0x6866, 0x1881,
+ 0x6867, 0x1883,
+ 0x6868, 0x0881,
+ 0x6869, 0x120b,
+ 0x686a, 0x3600,
+ 0x686b, 0x188e,
+ 0x686c, 0x3601,
+ 0x6874, 0x188b,
+ 0x6875, 0x3609,
+ 0x6876, 0x0e61,
+ 0x6877, 0x188c,
+ 0x6878, 0x360a,
+ 0x6881, 0x0a03,
+ 0x6882, 0x3613,
+ 0x6883, 0x187e,
+ 0x6884, 0x3614,
+ 0x6885, 0x0abc,
+ 0x6886, 0x03fb,
+ 0x6887, 0x3615,
+ 0x688f, 0x188a,
+ 0x6890, 0x361d,
+ 0x6893, 0x188d,
+ 0x6894, 0x3620,
+ 0x6897, 0x06fc,
+ 0x6898, 0x246a,
+ 0x6899, 0x3623,
+ 0x689d, 0x2175,
+ 0x689e, 0x3627,
+ 0x689f, 0x246d,
+ 0x68a0, 0x3628,
+ 0x68a2, 0x0d0b,
+ 0x68a3, 0x362a,
+ 0x68a6, 0x0ad3,
+ 0x68a7, 0x0eef,
+ 0x68a8, 0x09d1,
+ 0x68a9, 0x362d,
+ 0x68ad, 0x0de8,
+ 0x68ae, 0x3631,
+ 0x68af, 0x0e30,
+ 0x68b0, 0x0f80,
+ 0x68b1, 0x3632,
+ 0x68b3, 0x0d78,
+ 0x68b4, 0x3634,
+ 0x68b5, 0x1889,
+ 0x68b6, 0x3635,
+ 0x68c0, 0x085f,
+ 0x68c1, 0x363f,
+ 0x68c2, 0x188f,
+ 0x68c3, 0x3640,
+ 0x68c9, 0x0ae3,
+ 0x68ca, 0x3646,
+ 0x68cb, 0x0c04,
+ 0x68cc, 0x3647,
+ 0x68cd, 0x0750,
+ 0x68ce, 0x3648,
+ 0x68d2, 0x03ff,
+ 0x68d3, 0x364c,
+ 0x68d5, 0x1235,
+ 0x68d6, 0x246b,
+ 0x68d7, 0x225f,
+ 0x68d8, 0x081f,
+ 0x68d9, 0x364e,
+ 0x68da, 0x0bb0,
+ 0x68db, 0x364f,
+ 0x68df, 0x1ece,
+ 0x68e0, 0x0e17,
+ 0x68e1, 0x3653,
+ 0x68e3, 0x189a,
+ 0x68e4, 0x3655,
+ 0x68e7, 0x2272,
+ 0x68e8, 0x3658,
+ 0x68ee, 0x0ce6,
+ 0x68ef, 0x365e,
+ 0x68f0, 0x1896,
+ 0x68f1, 0x09cd,
+ 0x68f2, 0x365f,
+ 0x68f5, 0x0950,
+ 0x68f6, 0x3662,
+ 0x68f9, 0x1894,
+ 0x68fa, 0x0730,
+ 0x68fb, 0x3665,
+ 0x68fc, 0x1891,
+ 0x68fd, 0x3666,
+ 0x6900, 0x3669,
+ 0x6901, 0x1898,
+ 0x6902, 0x366a,
+ 0x6905, 0x1055,
+ 0x6906, 0x366d,
+ 0x690b, 0x1897,
+ 0x690c, 0x3672,
+ 0x690d, 0x11b1,
+ 0x690e, 0x1212,
+ 0x690f, 0x2473,
+ 0x6910, 0x189b,
+ 0x6911, 0x3673,
+ 0x6912, 0x0888,
+ 0x6913, 0x3674,
+ 0x691f, 0x1892,
+ 0x6921, 0x3680,
+ 0x6924, 0x1895,
+ 0x6925, 0x3683,
+ 0x692d, 0x0e87,
+ 0x692e, 0x368b,
+ 0x6930, 0x1033,
+ 0x6931, 0x368d,
+ 0x6934, 0x18a6,
+ 0x6935, 0x3690,
+ 0x6939, 0x189d,
+ 0x693a, 0x3694,
+ 0x693d, 0x052d,
+ 0x693e, 0x3697,
+ 0x693f, 0x053e,
+ 0x6940, 0x3698,
+ 0x6942, 0x189f,
+ 0x6943, 0x369a,
+ 0x694a, 0x21fe,
+ 0x694b, 0x36a1,
+ 0x6953, 0x1efe,
+ 0x6954, 0x0f73,
+ 0x6955, 0x36a9,
+ 0x6957, 0x1899,
+ 0x6958, 0x36ab,
+ 0x695a, 0x0523,
+ 0x695b, 0x36ad,
+ 0x695d, 0x18a0,
+ 0x695e, 0x09ce,
+ 0x695f, 0x36af,
+ 0x6960, 0x189e,
+ 0x6961, 0x36b0,
+ 0x6963, 0x18ad,
+ 0x6964, 0x36b2,
+ 0x6966, 0x18ac,
+ 0x6967, 0x36b4,
+ 0x6968, 0x2475,
+ 0x6969, 0x36b5,
+ 0x696b, 0x18a2,
+ 0x696c, 0x36b7,
+ 0x696d, 0x220a,
+ 0x696e, 0x1890,
+ 0x696f, 0x36b8,
+ 0x6971, 0x189c,
+ 0x6972, 0x36ba,
+ 0x6975, 0x1f6f,
+ 0x6976, 0x36bd,
+ 0x6977, 0x0939,
+ 0x6978, 0x18a5,
+ 0x6979, 0x18ae,
+ 0x697a, 0x36be,
+ 0x697c, 0x0a4c,
+ 0x697d, 0x36c0,
+ 0x6980, 0x18a3,
+ 0x6981, 0x36c3,
+ 0x6982, 0x06c0,
+ 0x6983, 0x36c4,
+ 0x6984, 0x18a1,
+ 0x6985, 0x36c5,
+ 0x6986, 0x10c1,
+ 0x6987, 0x18a8,
+ 0x6989, 0x18ab,
+ 0x698a, 0x36c6,
+ 0x698d, 0x18bb,
+ 0x698e, 0x36c9,
+ 0x6994, 0x09b1,
+ 0x6995, 0x18b9,
+ 0x6996, 0x36cf,
+ 0x6998, 0x18a4,
+ 0x6999, 0x36d1,
+ 0x699b, 0x18af,
+ 0x699c, 0x03fc,
+ 0x699d, 0x36d3,
+ 0x69a7, 0x18b0,
+ 0x69a8, 0x1146,
+ 0x69a9, 0x36dd,
+ 0x69aa, 0x2468,
+ 0x69ab, 0x18b2,
+ 0x69ac, 0x36de,
+ 0x69ad, 0x18b3,
+ 0x69ae, 0x2100,
+ 0x69af, 0x36df,
+ 0x69b1, 0x18b5,
+ 0x69b2, 0x36e1,
+ 0x69b4, 0x0a3a,
+ 0x69b5, 0x36e3,
+ 0x69b7, 0x0c91,
+ 0x69b8, 0x36e5,
+ 0x69bb, 0x18b1,
+ 0x69bc, 0x36e8,
+ 0x69bf, 0x2476,
+ 0x69c0, 0x36eb,
+ 0x69c1, 0x18b6,
+ 0x69c2, 0x36ec,
+ 0x69ca, 0x18b7,
+ 0x69cb, 0x1f27,
+ 0x69cc, 0x18a7,
+ 0x69cd, 0x20d7,
+ 0x69ce, 0x18aa,
+ 0x69cf, 0x36f4,
+ 0x69d0, 0x07c6,
+ 0x69d1, 0x36f5,
+ 0x69d4, 0x18b4,
+ 0x69d5, 0x36f8,
+ 0x69db, 0x086a,
+ 0x69dc, 0x36fe,
+ 0x69df, 0x18b8,
+ 0x69e0, 0x18ba,
+ 0x69e1, 0x3701,
+ 0x69e7, 0x247c,
+ 0x69e8, 0x3707,
+ 0x69ed, 0x18be,
+ 0x69ee, 0x370c,
+ 0x69f2, 0x18c2,
+ 0x69f3, 0x1fa1,
+ 0x69f4, 0x3710,
+ 0x69fd, 0x04a2,
+ 0x69fe, 0x3719,
+ 0x69ff, 0x18bc,
+ 0x6a00, 0x371a,
+ 0x6a01, 0x22aa,
+ 0x6a02, 0x2005,
+ 0x6a03, 0x371b,
+ 0x6a05, 0x246c,
+ 0x6a06, 0x371d,
+ 0x6a0a, 0x064b,
+ 0x6a0b, 0x3721,
+ 0x6a13, 0x203e,
+ 0x6a14, 0x3729,
+ 0x6a17, 0x18bf,
+ 0x6a19, 0x1e4c,
+ 0x6a1a, 0x372c,
+ 0x6a1e, 0x213a,
+ 0x6a1f, 0x1162,
+ 0x6a20, 0x3730,
+ 0x6a21, 0x0b06,
+ 0x6a22, 0x3731,
+ 0x6a23, 0x2204,
+ 0x6a24, 0x3732,
+ 0x6a28, 0x18cc,
+ 0x6a29, 0x3736,
+ 0x6a2a, 0x0798,
+ 0x6a2b, 0x3737,
+ 0x6a2f, 0x18bd,
+ 0x6a30, 0x373b,
+ 0x6a31, 0x1088,
+ 0x6a32, 0x373c,
+ 0x6a35, 0x18c8,
+ 0x6a36, 0x373f,
+ 0x6a38, 0x20c3,
+ 0x6a39, 0x2140,
+ 0x6a3a, 0x2477,
+ 0x6a3b, 0x3741,
+ 0x6a3d, 0x18cb,
+ 0x6a3e, 0x18c4,
+ 0x6a3f, 0x3743,
+ 0x6a44, 0x18c3,
+ 0x6a45, 0x3748,
+ 0x6a47, 0x0c3e,
+ 0x6a48, 0x2474,
+ 0x6a49, 0x374a,
+ 0x6a4b, 0x20dd,
+ 0x6a4c, 0x374c,
+ 0x6a50, 0x18c6,
+ 0x6a51, 0x3750,
+ 0x6a58, 0x18cd,
+ 0x6a59, 0x04ed,
+ 0x6a5a, 0x3757,
+ 0x6a5b, 0x18c7,
+ 0x6a5c, 0x3758,
+ 0x6a5f, 0x1f68,
+ 0x6a60, 0x375b,
+ 0x6a61, 0x0f5d,
+ 0x6a62, 0x2185,
+ 0x6a63, 0x375c,
+ 0x6a65, 0x18c1,
+ 0x6a66, 0x375e,
+ 0x6a71, 0x051c,
+ 0x6a72, 0x3769,
+ 0x6a79, 0x18ca,
+ 0x6a7a, 0x3770,
+ 0x6a7c, 0x18ce,
+ 0x6a7d, 0x3772,
+ 0x6a80, 0x0e07,
+ 0x6a81, 0x3775,
+ 0x6a84, 0x0f1a,
+ 0x6a85, 0x3778,
+ 0x6a89, 0x2472,
+ 0x6a8a, 0x377c,
+ 0x6a8e, 0x18c9,
+ 0x6a8f, 0x3780,
+ 0x6a90, 0x18d0,
+ 0x6a91, 0x18cf,
+ 0x6a92, 0x3781,
+ 0x6a94, 0x1eb5,
+ 0x6a95, 0x3783,
+ 0x6a97, 0x18d2,
+ 0x6a98, 0x3785,
+ 0x6a9c, 0x2478,
+ 0x6a9d, 0x3789,
+ 0x6aa0, 0x18c5,
+ 0x6aa1, 0x378c,
+ 0x6aa2, 0x1f8b,
+ 0x6aa3, 0x2484,
+ 0x6aa4, 0x378d,
+ 0x6aa9, 0x18d1,
+ 0x6aaa, 0x3792,
+ 0x6aab, 0x18d3,
+ 0x6aac, 0x0acf,
+ 0x6aad, 0x3793,
+ 0x6aaf, 0x2699,
+ 0x6ab0, 0x3795,
+ 0x6ab3, 0x2482,
+ 0x6ab4, 0x3798,
+ 0x6ab8, 0x20a1,
+ 0x6ab9, 0x379c,
+ 0x6abb, 0x1f92,
+ 0x6abc, 0x379e,
+ 0x6ac3, 0x1f38,
+ 0x6ac4, 0x37a5,
+ 0x6ad3, 0x2485,
+ 0x6ad4, 0x37b4,
+ 0x6ada, 0x2480,
+ 0x6adb, 0x246e,
+ 0x6adc, 0x37ba,
+ 0x6add, 0x247b,
+ 0x6ade, 0x2486,
+ 0x6adf, 0x2471,
+ 0x6ae0, 0x37bb,
+ 0x6ae7, 0x2483,
+ 0x6ae8, 0x2470,
+ 0x6ae9, 0x37c2,
+ 0x6aea, 0x2469,
+ 0x6aeb, 0x37c3,
+ 0x6aec, 0x247f,
+ 0x6aed, 0x37c4,
+ 0x6af3, 0x246f,
+ 0x6af4, 0x37ca,
+ 0x6af8, 0x2481,
+ 0x6af9, 0x37ce,
+ 0x6afb, 0x2220,
+ 0x6afc, 0x37d0,
+ 0x6b00, 0x37d4,
+ 0x6b04, 0x1ff5,
+ 0x6b05, 0x37d8,
+ 0x6b0a, 0x20f4,
+ 0x6b0b, 0x37dd,
+ 0x6b0f, 0x247d,
+ 0x6b10, 0x37e1,
+ 0x6b12, 0x2479,
+ 0x6b13, 0x37e3,
+ 0x6b16, 0x247e,
+ 0x6b17, 0x37e6,
+ 0x6b1e, 0x247a,
+ 0x6b1f, 0x37ed,
+ 0x6b20, 0x0c34,
+ 0x6b21, 0x0551,
+ 0x6b22, 0x07cb,
+ 0x6b23, 0x0f8b,
+ 0x6b24, 0x19b1,
+ 0x6b25, 0x37ee,
+ 0x6b27, 0x0b78,
+ 0x6b28, 0x37f0,
+ 0x6b32, 0x10e0,
+ 0x6b33, 0x37fa,
+ 0x6b37, 0x19b2,
+ 0x6b38, 0x37fe,
+ 0x6b39, 0x19b3,
+ 0x6b3a, 0x0bfa,
+ 0x6b3b, 0x37ff,
+ 0x6b3d, 0x20e3,
+ 0x6b3e, 0x097b,
+ 0x6b3f, 0x3801,
+ 0x6b43, 0x19b4,
+ 0x6b44, 0x3805,
+ 0x6b46, 0x19b5,
+ 0x6b47, 0x0f75,
+ 0x6b48, 0x3807,
+ 0x6b49, 0x0c35,
+ 0x6b4a, 0x3808,
+ 0x6b4c, 0x06e3,
+ 0x6b4d, 0x380a,
+ 0x6b50, 0x20ad,
+ 0x6b51, 0x380d,
+ 0x6b59, 0x19b6,
+ 0x6b5a, 0x3815,
+ 0x6b5f, 0x24cb,
+ 0x6b60, 0x381a,
+ 0x6b61, 0x1f53,
+ 0x6b62, 0x11b8,
+ 0x6b63, 0x119e,
+ 0x6b64, 0x054e,
+ 0x6b65, 0x0484,
+ 0x6b66, 0x0ef3,
+ 0x6b67, 0x0c06,
+ 0x6b68, 0x381b,
+ 0x6b6a, 0x0e92,
+ 0x6b6b, 0x381d,
+ 0x6b72, 0x2159,
+ 0x6b73, 0x3824,
+ 0x6b77, 0x2013,
+ 0x6b78, 0x1f33,
+ 0x6b79, 0x0578,
+ 0x6b7a, 0x3828,
+ 0x6b7b, 0x0db5,
+ 0x6b7c, 0x0852,
+ 0x6b7d, 0x3829,
+ 0x6b81, 0x18d6,
+ 0x6b83, 0x1013,
+ 0x6b84, 0x18d9,
+ 0x6b85, 0x382d,
+ 0x6b86, 0x057c,
+ 0x6b87, 0x18d8,
+ 0x6b88, 0x382e,
+ 0x6b89, 0x0fdc,
+ 0x6b8a, 0x0d79,
+ 0x6b8b, 0x0497,
+ 0x6b8c, 0x382f,
+ 0x6b8d, 0x18dc,
+ 0x6b8e, 0x3830,
+ 0x6b92, 0x18da,
+ 0x6b94, 0x3834,
+ 0x6b96, 0x11b2,
+ 0x6b97, 0x3836,
+ 0x6b98, 0x1e5c,
+ 0x6b99, 0x3837,
+ 0x6b9a, 0x18dd,
+ 0x6b9c, 0x3838,
+ 0x6b9e, 0x2488,
+ 0x6b9f, 0x383a,
+ 0x6ba1, 0x18df,
+ 0x6ba2, 0x383c,
+ 0x6ba4, 0x2487,
+ 0x6ba5, 0x383e,
+ 0x6baa, 0x18e0,
+ 0x6bab, 0x248a,
+ 0x6bac, 0x3843,
+ 0x6bae, 0x2489,
+ 0x6baf, 0x248b,
+ 0x6bb0, 0x3845,
+ 0x6bb2, 0x1f83,
+ 0x6bb3, 0x19bd,
+ 0x6bb4, 0x0b7a,
+ 0x6bb5, 0x060d,
+ 0x6bb6, 0x3847,
+ 0x6bb7, 0x107a,
+ 0x6bb8, 0x3848,
+ 0x6bba, 0x210f,
+ 0x6bbb, 0x1fdb,
+ 0x6bbc, 0x384a,
+ 0x6bbf, 0x05cf,
+ 0x6bc0, 0x384d,
+ 0x6bc1, 0x07ee,
+ 0x6bc2, 0x19bf,
+ 0x6bc3, 0x384e,
+ 0x6bc5, 0x106a,
+ 0x6bc6, 0x20af,
+ 0x6bc7, 0x3850,
+ 0x6bcb, 0x0ef2,
+ 0x6bcc, 0x3854,
+ 0x6bcd, 0x0b1b,
+ 0x6bce, 0x3855,
+ 0x6bcf, 0x0ac4,
+ 0x6bd0, 0x3856,
+ 0x6bd2, 0x05fd,
+ 0x6bd3, 0x126f,
+ 0x6bd4, 0x0431,
+ 0x6bd5, 0x0438,
+ 0x6bd6, 0x043a,
+ 0x6bd7, 0x0bbf,
+ 0x6bd8, 0x3858,
+ 0x6bd9, 0x0439,
+ 0x6bda, 0x3859,
+ 0x6bdb, 0x0ab0,
+ 0x6bdc, 0x385a,
+ 0x6be1, 0x1152,
+ 0x6be2, 0x385f,
+ 0x6bea, 0x1954,
+ 0x6beb, 0x0778,
+ 0x6bec, 0x3867,
+ 0x6bef, 0x0e0d,
+ 0x6bf0, 0x386a,
+ 0x6bf3, 0x1955,
+ 0x6bf4, 0x386d,
+ 0x6bf5, 0x1957,
+ 0x6bf6, 0x386e,
+ 0x6bf9, 0x1958,
+ 0x6bfa, 0x3871,
+ 0x6bfd, 0x1956,
+ 0x6bfe, 0x3874,
+ 0x6bff, 0x24c0,
+ 0x6c00, 0x3875,
+ 0x6c05, 0x1959,
+ 0x6c06, 0x195b,
+ 0x6c07, 0x195a,
+ 0x6c08, 0x226d,
+ 0x6c09, 0x387a,
+ 0x6c0c, 0x24c1,
+ 0x6c0d, 0x195c,
+ 0x6c0e, 0x387d,
+ 0x6c0f, 0x0d66,
+ 0x6c10, 0x126b,
+ 0x6c11, 0x0af6,
+ 0x6c12, 0x387e,
+ 0x6c13, 0x0aaa,
+ 0x6c14, 0x0c17,
+ 0x6c15, 0x195d,
+ 0x6c16, 0x0b2d,
+ 0x6c17, 0x387f,
+ 0x6c18, 0x195e,
+ 0x6c1b, 0x0672,
+ 0x6c1c, 0x3880,
+ 0x6c1f, 0x0697,
+ 0x6c20, 0x3883,
+ 0x6c21, 0x1961,
+ 0x6c22, 0x0c5f,
+ 0x6c23, 0x20ca,
+ 0x6c24, 0x1963,
+ 0x6c25, 0x3884,
+ 0x6c26, 0x075b,
+ 0x6c27, 0x101e,
+ 0x6c28, 0x03bc,
+ 0x6c29, 0x1962,
+ 0x6c2a, 0x1964,
+ 0x6c2b, 0x20e7,
+ 0x6c2c, 0x24c2,
+ 0x6c2d, 0x3885,
+ 0x6c2e, 0x058b,
+ 0x6c2f, 0x0a6f,
+ 0x6c30, 0x0c65,
+ 0x6c31, 0x3886,
+ 0x6c32, 0x1965,
+ 0x6c33, 0x3887,
+ 0x6c34, 0x0da3,
+ 0x6c35, 0x169f,
+ 0x6c36, 0x3888,
+ 0x6c38, 0x10a5,
+ 0x6c39, 0x388a,
+ 0x6c3d, 0x12ef,
+ 0x6c3e, 0x388e,
+ 0x6c40, 0x0e52,
+ 0x6c41, 0x11ac,
+ 0x6c42, 0x0c70,
+ 0x6c43, 0x3890,
+ 0x6c46, 0x12f4,
+ 0x6c47, 0x07f8,
+ 0x6c48, 0x3893,
+ 0x6c49, 0x0771,
+ 0x6c4a, 0x16a2,
+ 0x6c4b, 0x3894,
+ 0x6c50, 0x0f18,
+ 0x6c51, 0x3899,
+ 0x6c54, 0x16a0,
+ 0x6c55, 0x0d00,
+ 0x6c56, 0x389c,
+ 0x6c57, 0x0770,
+ 0x6c58, 0x389d,
+ 0x6c5b, 0x0fdd,
+ 0x6c5c, 0x16a1,
+ 0x6c5d, 0x0cc5,
+ 0x6c5e, 0x0708,
+ 0x6c5f, 0x087e,
+ 0x6c60, 0x04fd,
+ 0x6c61, 0x0eea,
+ 0x6c62, 0x38a0,
+ 0x6c64, 0x0e13,
+ 0x6c65, 0x38a2,
+ 0x6c68, 0x16a8,
+ 0x6c6a, 0x0ea5,
+ 0x6c6b, 0x38a5,
+ 0x6c70, 0x0e00,
+ 0x6c71, 0x38aa,
+ 0x6c72, 0x0826,
+ 0x6c73, 0x38ab,
+ 0x6c74, 0x16aa,
+ 0x6c75, 0x38ac,
+ 0x6c76, 0x16ab,
+ 0x6c77, 0x38ad,
+ 0x6c79, 0x0fa5,
+ 0x6c7a, 0x38af,
+ 0x6c7d, 0x0c1a,
+ 0x6c7e, 0x0677,
+ 0x6c7f, 0x38b2,
+ 0x6c81, 0x0c5c,
+ 0x6c82, 0x1051,
+ 0x6c83, 0x0ee5,
+ 0x6c84, 0x38b4,
+ 0x6c85, 0x16a4,
+ 0x6c86, 0x16ac,
+ 0x6c87, 0x38b5,
+ 0x6c88, 0x0d2b,
+ 0x6c89, 0x04e6,
+ 0x6c8a, 0x38b6,
+ 0x6c8c, 0x16a7,
+ 0x6c8d, 0x38b8,
+ 0x6c8f, 0x0c02,
+ 0x6c90, 0x16a5,
+ 0x6c91, 0x38ba,
+ 0x6c93, 0x1a1f,
+ 0x6c94, 0x16a6,
+ 0x6c95, 0x38bc,
+ 0x6c99, 0x0cec,
+ 0x6c9a, 0x38c0,
+ 0x6c9b, 0x0ba7,
+ 0x6c9c, 0x38c1,
+ 0x6c9f, 0x070e,
+ 0x6ca0, 0x38c4,
+ 0x6ca1, 0x0ac0,
+ 0x6ca2, 0x38c5,
+ 0x6ca3, 0x16a3,
+ 0x6ca4, 0x0b7e,
+ 0x6ca5, 0x09ed,
+ 0x6ca6, 0x0a80,
+ 0x6ca7, 0x049e,
+ 0x6ca8, 0x38c6,
+ 0x6ca9, 0x16ad,
+ 0x6caa, 0x07bb,
+ 0x6cab, 0x0b10,
+ 0x6cac, 0x38c7,
+ 0x6cad, 0x16b0,
+ 0x6cae, 0x0909,
+ 0x6caf, 0x38c8,
+ 0x6cb1, 0x16bb,
+ 0x6cb2, 0x16b5,
+ 0x6cb3, 0x078a,
+ 0x6cb4, 0x38ca,
+ 0x6cb8, 0x066d,
+ 0x6cb9, 0x10b2,
+ 0x6cba, 0x38ce,
+ 0x6cbb, 0x11cd,
+ 0x6cbc, 0x1174,
+ 0x6cbd, 0x071a,
+ 0x6cbe, 0x1155,
+ 0x6cbf, 0x1001,
+ 0x6cc0, 0x38cf,
+ 0x6cc4, 0x0f84,
+ 0x6cc5, 0x0c73,
+ 0x6cc6, 0x38d3,
+ 0x6cc9, 0x0c85,
+ 0x6cca, 0x047b,
+ 0x6ccb, 0x38d6,
+ 0x6ccc, 0x0adf,
+ 0x6ccd, 0x38d7,
+ 0x6cd0, 0x16ae,
+ 0x6cd1, 0x38da,
+ 0x6cd3, 0x16bc,
+ 0x6cd4, 0x16af,
+ 0x6cd5, 0x0645,
+ 0x6cd6, 0x16b7,
+ 0x6cd7, 0x16b4,
+ 0x6cd8, 0x38dc,
+ 0x6cdb, 0x0657,
+ 0x6cdc, 0x38df,
+ 0x6cde, 0x0b63,
+ 0x6cdf, 0x38e1,
+ 0x6ce0, 0x16b6,
+ 0x6ce1, 0x0b9e,
+ 0x6ce2, 0x046f,
+ 0x6ce3, 0x0c1b,
+ 0x6ce4, 0x38e2,
+ 0x6ce5, 0x0b43,
+ 0x6ce6, 0x38e3,
+ 0x6ce8, 0x11ff,
+ 0x6ce9, 0x38e5,
+ 0x6cea, 0x09cc,
+ 0x6ceb, 0x16b9,
+ 0x6cec, 0x38e6,
+ 0x6cee, 0x16ba,
+ 0x6cef, 0x16bd,
+ 0x6cf0, 0x0dfc,
+ 0x6cf1, 0x16b3,
+ 0x6cf2, 0x38e8,
+ 0x6cf3, 0x10a3,
+ 0x6cf4, 0x38e9,
+ 0x6cf5, 0x042c,
+ 0x6cf6, 0x1a20,
+ 0x6cf7, 0x16b1,
+ 0x6cf9, 0x38ea,
+ 0x6cfa, 0x16b8,
+ 0x6cfb, 0x0f85,
+ 0x6cfc, 0x0be2,
+ 0x6cfd, 0x1136,
+ 0x6cfe, 0x16be,
+ 0x6cff, 0x38eb,
+ 0x6d00, 0x38ec,
+ 0x6d01, 0x08b1,
+ 0x6d02, 0x38ed,
+ 0x6d04, 0x16c5,
+ 0x6d05, 0x38ef,
+ 0x6d07, 0x16c4,
+ 0x6d08, 0x38f1,
+ 0x6d0b, 0x101c,
+ 0x6d0c, 0x16c1,
+ 0x6d0d, 0x38f4,
+ 0x6d0e, 0x16c7,
+ 0x6d0f, 0x38f5,
+ 0x6d12, 0x0cd2,
+ 0x6d13, 0x38f8,
+ 0x6d17, 0x0f21,
+ 0x6d18, 0x38fc,
+ 0x6d19, 0x16c6,
+ 0x6d1a, 0x16cc,
+ 0x6d1b, 0x0a8c,
+ 0x6d1c, 0x38fd,
+ 0x6d1e, 0x05f3,
+ 0x6d1f, 0x38ff,
+ 0x6d25, 0x08c3,
+ 0x6d26, 0x3905,
+ 0x6d27, 0x16c0,
+ 0x6d28, 0x3906,
+ 0x6d2a, 0x07a0,
+ 0x6d2b, 0x16c8,
+ 0x6d2c, 0x3908,
+ 0x6d2e, 0x16ca,
+ 0x6d2f, 0x390a,
+ 0x6d31, 0x063c,
+ 0x6d32, 0x11dd,
+ 0x6d33, 0x16d0,
+ 0x6d34, 0x390c,
+ 0x6d35, 0x16cb,
+ 0x6d36, 0x390d,
+ 0x6d39, 0x16bf,
+ 0x6d3a, 0x3910,
+ 0x6d3b, 0x0803,
+ 0x6d3c, 0x0e8e,
+ 0x6d3d, 0x0c1f,
+ 0x6d3e, 0x0b8a,
+ 0x6d3f, 0x3911,
+ 0x6d41, 0x0a40,
+ 0x6d42, 0x3913,
+ 0x6d43, 0x16c2,
+ 0x6d44, 0x3914,
+ 0x6d45, 0x0c30,
+ 0x6d46, 0x087d,
+ 0x6d47, 0x088e,
+ 0x6d48, 0x16c3,
+ 0x6d49, 0x3915,
+ 0x6d4a, 0x1224,
+ 0x6d4b, 0x04a9,
+ 0x6d4c, 0x3916,
+ 0x6d4d, 0x16c9,
+ 0x6d4e, 0x0836,
+ 0x6d4f, 0x16cd,
+ 0x6d50, 0x3917,
+ 0x6d51, 0x0800,
+ 0x6d52, 0x16ce,
+ 0x6d53, 0x0b69,
+ 0x6d54, 0x16cf,
+ 0x6d55, 0x3918,
+ 0x6d59, 0x1184,
+ 0x6d5a, 0x0930,
+ 0x6d5b, 0x391c,
+ 0x6d5c, 0x16d8,
+ 0x6d5d, 0x391d,
+ 0x6d5e, 0x16d5,
+ 0x6d5f, 0x391e,
+ 0x6d60, 0x16d9,
+ 0x6d61, 0x391f,
+ 0x6d63, 0x16db,
+ 0x6d64, 0x3921,
+ 0x6d66, 0x0bf5,
+ 0x6d67, 0x3923,
+ 0x6d69, 0x077d,
+ 0x6d6a, 0x09b6,
+ 0x6d6b, 0x3925,
+ 0x6d6e, 0x069c,
+ 0x6d6f, 0x16d2,
+ 0x6d70, 0x3928,
+ 0x6d74, 0x10e4,
+ 0x6d75, 0x392c,
+ 0x6d77, 0x075a,
+ 0x6d78, 0x08cf,
+ 0x6d79, 0x23dc,
+ 0x6d7a, 0x392e,
+ 0x6d7c, 0x16da,
+ 0x6d7d, 0x3930,
+ 0x6d82, 0x0e70,
+ 0x6d83, 0x3935,
+ 0x6d85, 0x0b5c,
+ 0x6d86, 0x3937,
+ 0x6d87, 0x23db,
+ 0x6d88, 0x0f68,
+ 0x6d89, 0x0d1f,
+ 0x6d8a, 0x3938,
+ 0x6d8c, 0x10a4,
+ 0x6d8d, 0x393a,
+ 0x6d8e, 0x0f3e,
+ 0x6d8f, 0x393b,
+ 0x6d91, 0x16d1,
+ 0x6d92, 0x393d,
+ 0x6d93, 0x16d6,
+ 0x6d95, 0x0e3c,
+ 0x6d96, 0x393e,
+ 0x6d9b, 0x0e21,
+ 0x6d9c, 0x3943,
+ 0x6d9d, 0x09bf,
+ 0x6d9e, 0x16d3,
+ 0x6d9f, 0x09f9,
+ 0x6da0, 0x16d4,
+ 0x6da1, 0x0edf,
+ 0x6da2, 0x3944,
+ 0x6da3, 0x07d6,
+ 0x6da4, 0x05b4,
+ 0x6da5, 0x3945,
+ 0x6da6, 0x0cce,
+ 0x6da7, 0x0878,
+ 0x6da8, 0x1168,
+ 0x6da9, 0x0ce5,
+ 0x6daa, 0x069d,
+ 0x6dab, 0x16e8,
+ 0x6dac, 0x3946,
+ 0x6dae, 0x16ea,
+ 0x6daf, 0x0fed,
+ 0x6db0, 0x3948,
+ 0x6db2, 0x1041,
+ 0x6db3, 0x394a,
+ 0x6db5, 0x0764,
+ 0x6db6, 0x394c,
+ 0x6db8, 0x078b,
+ 0x6db9, 0x394e,
+ 0x6dbf, 0x16e1,
+ 0x6dc0, 0x05ce,
+ 0x6dc1, 0x3954,
+ 0x6dc4, 0x122a,
+ 0x6dc5, 0x16de,
+ 0x6dc6, 0x0f6a,
+ 0x6dc7, 0x16dd,
+ 0x6dc8, 0x3957,
+ 0x6dcb, 0x0a25,
+ 0x6dcc, 0x0e1d,
+ 0x6dcd, 0x395a,
+ 0x6dd1, 0x0d7e,
+ 0x6dd2, 0x395e,
+ 0x6dd6, 0x0b3a,
+ 0x6dd7, 0x3962,
+ 0x6dd8, 0x0e27,
+ 0x6dd9, 0x16e6,
+ 0x6dda, 0x3963,
+ 0x6ddd, 0x16e5,
+ 0x6dde, 0x16df,
+ 0x6ddf, 0x3966,
+ 0x6de0, 0x16e2,
+ 0x6de1, 0x058e,
+ 0x6de2, 0x3967,
+ 0x6de4, 0x10be,
+ 0x6de5, 0x3969,
+ 0x6de6, 0x16e4,
+ 0x6de7, 0x396a,
+ 0x6dea, 0x205e,
+ 0x6deb, 0x1080,
+ 0x6dec, 0x0566,
+ 0x6ded, 0x396d,
+ 0x6dee, 0x07c9,
+ 0x6def, 0x396e,
+ 0x6df1, 0x0d27,
+ 0x6df2, 0x3970,
+ 0x6df3, 0x0541,
+ 0x6df4, 0x3971,
+ 0x6df5, 0x2244,
+ 0x6df6, 0x23e2,
+ 0x6df7, 0x0801,
+ 0x6df8, 0x3972,
+ 0x6df9, 0x0ff6,
+ 0x6dfa, 0x20d4,
+ 0x6dfb, 0x0e40,
+ 0x6dfc, 0x1a21,
+ 0x6dfd, 0x3973,
+ 0x6e00, 0x3976,
+ 0x6e05, 0x0c62,
+ 0x6e06, 0x397b,
+ 0x6e0a, 0x10eb,
+ 0x6e0b, 0x397f,
+ 0x6e0c, 0x16e9,
+ 0x6e0d, 0x1232,
+ 0x6e0e, 0x16e0,
+ 0x6e0f, 0x3980,
+ 0x6e10, 0x0876,
+ 0x6e11, 0x16e3,
+ 0x6e12, 0x3981,
+ 0x6e14, 0x10cb,
+ 0x6e15, 0x3983,
+ 0x6e16, 0x16e7,
+ 0x6e17, 0x0d31,
+ 0x6e18, 0x3984,
+ 0x6e1a, 0x16dc,
+ 0x6e1b, 0x3986,
+ 0x6e1d, 0x10ca,
+ 0x6e1e, 0x3988,
+ 0x6e20, 0x0c7b,
+ 0x6e21, 0x0608,
+ 0x6e22, 0x398a,
+ 0x6e23, 0x113f,
+ 0x6e24, 0x047a,
+ 0x6e25, 0x16f5,
+ 0x6e26, 0x219f,
+ 0x6e27, 0x398b,
+ 0x6e29, 0x0ed1,
+ 0x6e2a, 0x398d,
+ 0x6e2b, 0x16eb,
+ 0x6e2c, 0x1e66,
+ 0x6e2d, 0x0ecb,
+ 0x6e2e, 0x398e,
+ 0x6e2f, 0x06d6,
+ 0x6e30, 0x398f,
+ 0x6e32, 0x16f4,
+ 0x6e33, 0x3991,
+ 0x6e34, 0x0957,
+ 0x6e35, 0x3992,
+ 0x6e38, 0x10b3,
+ 0x6e39, 0x3995,
+ 0x6e3a, 0x0af1,
+ 0x6e3b, 0x3996,
+ 0x6e3e, 0x1f63,
+ 0x6e3f, 0x3999,
+ 0x6e43, 0x0b89,
+ 0x6e44, 0x16f6,
+ 0x6e45, 0x399d,
+ 0x6e4d, 0x0e75,
+ 0x6e4e, 0x16ed,
+ 0x6e4f, 0x39a5,
+ 0x6e53, 0x16f2,
+ 0x6e55, 0x39a9,
+ 0x6e56, 0x07b5,
+ 0x6e57, 0x39aa,
+ 0x6e58, 0x0f53,
+ 0x6e59, 0x39ab,
+ 0x6e5b, 0x1160,
+ 0x6e5c, 0x39ad,
+ 0x6e5e, 0x23dd,
+ 0x6e5f, 0x16f0,
+ 0x6e60, 0x39af,
+ 0x6e6b, 0x16ee,
+ 0x6e6c, 0x39ba,
+ 0x6e6e, 0x16ec,
+ 0x6e6f, 0x216b,
+ 0x6e70, 0x39bc,
+ 0x6e7e, 0x0e96,
+ 0x6e7f, 0x0d41,
+ 0x6e80, 0x39ca,
+ 0x6e83, 0x098e,
+ 0x6e84, 0x39cd,
+ 0x6e85, 0x0877,
+ 0x6e86, 0x16f1,
+ 0x6e87, 0x39ce,
+ 0x6e89, 0x06c3,
+ 0x6e8a, 0x39d0,
+ 0x6e8f, 0x1705,
+ 0x6e90, 0x10f7,
+ 0x6e91, 0x39d5,
+ 0x6e96, 0x22b5,
+ 0x6e97, 0x39da,
+ 0x6e98, 0x16f9,
+ 0x6e99, 0x39db,
+ 0x6e9c, 0x0a38,
+ 0x6e9d, 0x1f26,
+ 0x6e9e, 0x39de,
+ 0x6e9f, 0x1707,
+ 0x6ea0, 0x39df,
+ 0x6ea2, 0x106e,
+ 0x6ea3, 0x39e1,
+ 0x6ea5, 0x16fd,
+ 0x6ea6, 0x39e3,
+ 0x6ea7, 0x16fe,
+ 0x6ea8, 0x39e4,
+ 0x6eaa, 0x0f17,
+ 0x6eab, 0x39e6,
+ 0x6eaf, 0x0dd2,
+ 0x6eb0, 0x39ea,
+ 0x6eb1, 0x16f8,
+ 0x6eb2, 0x16ef,
+ 0x6eb3, 0x39eb,
+ 0x6eb4, 0x1703,
+ 0x6eb5, 0x39ec,
+ 0x6eb6, 0x0cb7,
+ 0x6eb7, 0x1701,
+ 0x6eb8, 0x39ed,
+ 0x6eba, 0x0b4a,
+ 0x6ebb, 0x1700,
+ 0x6ebc, 0x39ef,
+ 0x6ebd, 0x16ff,
+ 0x6ebe, 0x39f0,
+ 0x6ec1, 0x0521,
+ 0x6ec2, 0x1706,
+ 0x6ec3, 0x39f3,
+ 0x6ec4, 0x1e63,
+ 0x6ec5, 0x2088,
+ 0x6ec6, 0x39f4,
+ 0x6ec7, 0x05c2,
+ 0x6ec8, 0x39f5,
+ 0x6ecb, 0x1229,
+ 0x6ecc, 0x1ebd,
+ 0x6ecd, 0x39f8,
+ 0x6ece, 0x2341,
+ 0x6ecf, 0x1704,
+ 0x6ed0, 0x39f9,
+ 0x6ed1, 0x07c1,
+ 0x6ed2, 0x39fa,
+ 0x6ed3, 0x122f,
+ 0x6ed4, 0x0e22,
+ 0x6ed5, 0x19a8,
+ 0x6ed6, 0x39fb,
+ 0x6ed7, 0x1702,
+ 0x6ed8, 0x39fc,
+ 0x6eda, 0x074f,
+ 0x6edb, 0x39fe,
+ 0x6ede, 0x11cc,
+ 0x6edf, 0x16f7,
+ 0x6ee0, 0x16fa,
+ 0x6ee1, 0x0aa1,
+ 0x6ee2, 0x16fc,
+ 0x6ee3, 0x3a01,
+ 0x6ee4, 0x0a72,
+ 0x6ee5, 0x09af,
+ 0x6ee6, 0x0a77,
+ 0x6ee7, 0x3a02,
+ 0x6ee8, 0x045e,
+ 0x6ee9, 0x0e05,
+ 0x6eea, 0x3a03,
+ 0x6eec, 0x1f4b,
+ 0x6eed, 0x3a05,
+ 0x6eef, 0x2292,
+ 0x6ef0, 0x3a07,
+ 0x6ef2, 0x2124,
+ 0x6ef3, 0x3a09,
+ 0x6ef4, 0x05af,
+ 0x6ef5, 0x3a0a,
+ 0x6ef7, 0x2048,
+ 0x6ef8, 0x23e0,
+ 0x6ef9, 0x170d,
+ 0x6efa, 0x3a0c,
+ 0x6eff, 0x2077,
+ 0x6f00, 0x3a11,
+ 0x6f01, 0x223a,
+ 0x6f02, 0x0bce,
+ 0x6f03, 0x3a12,
+ 0x6f06, 0x0c00,
+ 0x6f07, 0x3a15,
+ 0x6f09, 0x1713,
+ 0x6f0a, 0x3a17,
+ 0x6f0f, 0x0a50,
+ 0x6f10, 0x3a1c,
+ 0x6f13, 0x09d7,
+ 0x6f14, 0x1006,
+ 0x6f15, 0x170c,
+ 0x6f16, 0x3a1f,
+ 0x6f1a, 0x20b1,
+ 0x6f1b, 0x3a23,
+ 0x6f20, 0x0b11,
+ 0x6f21, 0x3a28,
+ 0x6f22, 0x1f41,
+ 0x6f23, 0x201c,
+ 0x6f24, 0x170b,
+ 0x6f25, 0x3a29,
+ 0x6f29, 0x1714,
+ 0x6f2a, 0x1712,
+ 0x6f2b, 0x0aa5,
+ 0x6f2c, 0x22b8,
+ 0x6f2d, 0x16fb,
+ 0x6f2e, 0x3a2d,
+ 0x6f2f, 0x170e,
+ 0x6f30, 0x3a2e,
+ 0x6f31, 0x0d95,
+ 0x6f32, 0x2276,
+ 0x6f33, 0x1165,
+ 0x6f34, 0x3a2f,
+ 0x6f36, 0x170f,
+ 0x6f37, 0x3a31,
+ 0x6f38, 0x1f9b,
+ 0x6f39, 0x3a32,
+ 0x6f3e, 0x1023,
+ 0x6f3f, 0x1f9f,
+ 0x6f40, 0x3a37,
+ 0x6f41, 0x25ca,
+ 0x6f42, 0x3a38,
+ 0x6f46, 0x1709,
+ 0x6f48, 0x3a3c,
+ 0x6f4b, 0x1710,
+ 0x6f4c, 0x3a3f,
+ 0x6f4d, 0x0eba,
+ 0x6f4e, 0x3a40,
+ 0x6f51, 0x20be,
+ 0x6f52, 0x3a43,
+ 0x6f54, 0x1fb4,
+ 0x6f55, 0x3a45,
+ 0x6f58, 0x0b8c,
+ 0x6f59, 0x23d7,
+ 0x6f5a, 0x3a48,
+ 0x6f5c, 0x0c2e,
+ 0x6f5d, 0x3a4a,
+ 0x6f5e, 0x0a61,
+ 0x6f5f, 0x3a4b,
+ 0x6f62, 0x1708,
+ 0x6f63, 0x3a4e,
+ 0x6f64, 0x2105,
+ 0x6f65, 0x3a4f,
+ 0x6f66, 0x0a13,
+ 0x6f67, 0x3a50,
+ 0x6f6d, 0x0e09,
+ 0x6f6e, 0x04d6,
+ 0x6f6f, 0x23e1,
+ 0x6f70, 0x1fec,
+ 0x6f71, 0x3a56,
+ 0x6f72, 0x1719,
+ 0x6f73, 0x3a57,
+ 0x6f74, 0x1711,
+ 0x6f75, 0x3a58,
+ 0x6f77, 0x23ea,
+ 0x6f78, 0x1718,
+ 0x6f79, 0x3a5a,
+ 0x6f7a, 0x171b,
+ 0x6f7b, 0x3a5b,
+ 0x6f7c, 0x171a,
+ 0x6f7d, 0x3a5c,
+ 0x6f7f, 0x23e3,
+ 0x6f80, 0x210e,
+ 0x6f81, 0x3a5e,
+ 0x6f84, 0x04f3,
+ 0x6f85, 0x3a61,
+ 0x6f86, 0x1fa6,
+ 0x6f87, 0x2004,
+ 0x6f88, 0x04df,
+ 0x6f89, 0x1715,
+ 0x6f8a, 0x3a62,
+ 0x6f8c, 0x1717,
+ 0x6f8d, 0x1716,
+ 0x6f8e, 0x0bad,
+ 0x6f8f, 0x3a64,
+ 0x6f97, 0x1f9d,
+ 0x6f98, 0x3a6c,
+ 0x6f9c, 0x09a8,
+ 0x6f9d, 0x3a70,
+ 0x6fa0, 0x23e5,
+ 0x6fa1, 0x112b,
+ 0x6fa2, 0x3a73,
+ 0x6fa4, 0x2264,
+ 0x6fa5, 0x3a75,
+ 0x6fa7, 0x171e,
+ 0x6fa8, 0x3a77,
+ 0x6fa9, 0x24e2,
+ 0x6faa, 0x3a78,
+ 0x6fae, 0x23de,
+ 0x6faf, 0x3a7c,
+ 0x6fb1, 0x1ec4,
+ 0x6fb2, 0x3a7e,
+ 0x6fb3, 0x03cf,
+ 0x6fb4, 0x3a7f,
+ 0x6fb6, 0x1720,
+ 0x6fb7, 0x3a81,
+ 0x6fb9, 0x171f,
+ 0x6fba, 0x3a83,
+ 0x6fc0, 0x0817,
+ 0x6fc1, 0x22b6,
+ 0x6fc2, 0x1721,
+ 0x6fc3, 0x20a9,
+ 0x6fc4, 0x3a89,
+ 0x6fc9, 0x171d,
+ 0x6fca, 0x3a8e,
+ 0x6fd1, 0x171c,
+ 0x6fd2, 0x045d,
+ 0x6fd3, 0x3a95,
+ 0x6fd5, 0x212b,
+ 0x6fd6, 0x3a97,
+ 0x6fd8, 0x20a5,
+ 0x6fd9, 0x3a99,
+ 0x6fdb, 0x268b,
+ 0x6fdc, 0x3a9b,
+ 0x6fde, 0x1724,
+ 0x6fdf, 0x1f76,
+ 0x6fe0, 0x1725,
+ 0x6fe1, 0x1722,
+ 0x6fe2, 0x3a9d,
+ 0x6fe4, 0x216d,
+ 0x6fe5, 0x3a9f,
+ 0x6feb, 0x2001,
+ 0x6fec, 0x3aa5,
+ 0x6fee, 0x1723,
+ 0x6fef, 0x1726,
+ 0x6ff0, 0x2191,
+ 0x6ff1, 0x1e50,
+ 0x6ff2, 0x3aa7,
+ 0x6ffa, 0x1f9c,
+ 0x6ffb, 0x3aaf,
+ 0x6ffc, 0x23da,
+ 0x6ffd, 0x3ab0,
+ 0x6ffe, 0x2053,
+ 0x6fff, 0x3ab1,
+ 0x7000, 0x3ab2,
+ 0x7005, 0x23e9,
+ 0x7006, 0x23e4,
+ 0x7007, 0x3ab7,
+ 0x7009, 0x21d5,
+ 0x700a, 0x3ab9,
+ 0x700b, 0x23e6,
+ 0x700c, 0x3aba,
+ 0x700f, 0x23df,
+ 0x7010, 0x3abd,
+ 0x7011, 0x0bf8,
+ 0x7012, 0x3abe,
+ 0x7015, 0x1e4f,
+ 0x7016, 0x3ac1,
+ 0x7018, 0x23d9,
+ 0x7019, 0x3ac3,
+ 0x701a, 0x1727,
+ 0x701b, 0x1729,
+ 0x701c, 0x3ac4,
+ 0x701d, 0x2014,
+ 0x701e, 0x3ac5,
+ 0x701f, 0x23ec,
+ 0x7020, 0x23eb,
+ 0x7021, 0x3ac6,
+ 0x7023, 0x1728,
+ 0x7024, 0x3ac8,
+ 0x7027, 0x23d8,
+ 0x7028, 0x23ee,
+ 0x7029, 0x3acb,
+ 0x7030, 0x268e,
+ 0x7031, 0x3ad2,
+ 0x7032, 0x23ed,
+ 0x7033, 0x3ad3,
+ 0x7035, 0x172b,
+ 0x7036, 0x3ad5,
+ 0x7039, 0x172a,
+ 0x703a, 0x3ad8,
+ 0x703e, 0x1ffa,
+ 0x703f, 0x3adc,
+ 0x7043, 0x23d6,
+ 0x7044, 0x23e8,
+ 0x7045, 0x3ae0,
+ 0x704c, 0x0739,
+ 0x704d, 0x3ae7,
+ 0x704f, 0x172c,
+ 0x7050, 0x3ae9,
+ 0x7051, 0x2106,
+ 0x7052, 0x3aea,
+ 0x7055, 0x200b,
+ 0x7056, 0x3aed,
+ 0x7058, 0x2166,
+ 0x7059, 0x3aef,
+ 0x705d, 0x23ef,
+ 0x705e, 0x172d,
+ 0x705f, 0x3af3,
+ 0x7063, 0x2189,
+ 0x7064, 0x2058,
+ 0x7065, 0x3af7,
+ 0x7067, 0x23e7,
+ 0x7068, 0x3af9,
+ 0x706b, 0x0805,
+ 0x706c, 0x19ef,
+ 0x706d, 0x0af5,
+ 0x706e, 0x3afc,
+ 0x706f, 0x05a7,
+ 0x7070, 0x07e7,
+ 0x7071, 0x3afd,
+ 0x7075, 0x0a32,
+ 0x7076, 0x1131,
+ 0x7077, 0x3b01,
+ 0x7078, 0x08f3,
+ 0x7079, 0x3b02,
+ 0x707c, 0x1223,
+ 0x707d, 0x3b05,
+ 0x707e, 0x1119,
+ 0x707f, 0x049a,
+ 0x7080, 0x19cc,
+ 0x7081, 0x3b06,
+ 0x7085, 0x1913,
+ 0x7086, 0x3b0a,
+ 0x7089, 0x0a56,
+ 0x708a, 0x0539,
+ 0x708b, 0x3b0d,
+ 0x708e, 0x1000,
+ 0x708f, 0x3b10,
+ 0x7092, 0x04d9,
+ 0x7093, 0x3b13,
+ 0x7094, 0x0c8d,
+ 0x7095, 0x0948,
+ 0x7096, 0x19ce,
+ 0x7097, 0x3b14,
+ 0x7099, 0x11ca,
+ 0x709a, 0x3b16,
+ 0x709c, 0x19cd,
+ 0x709d, 0x19cf,
+ 0x709e, 0x3b18,
+ 0x70ab, 0x19d3,
+ 0x70ac, 0x0915,
+ 0x70ad, 0x0e12,
+ 0x70ae, 0x0b9b,
+ 0x70af, 0x08eb,
+ 0x70b0, 0x3b25,
+ 0x70b1, 0x19d4,
+ 0x70b2, 0x3b26,
+ 0x70b3, 0x0467,
+ 0x70b4, 0x3b27,
+ 0x70b7, 0x19d2,
+ 0x70b8, 0x1149,
+ 0x70b9, 0x05c4,
+ 0x70ba, 0x3b2a,
+ 0x70bb, 0x19d0,
+ 0x70bc, 0x09ff,
+ 0x70bd, 0x0508,
+ 0x70be, 0x3b2b,
+ 0x70c0, 0x19d1,
+ 0x70c1, 0x0dad,
+ 0x70c2, 0x09ae,
+ 0x70c3, 0x0e51,
+ 0x70c4, 0x3b2d,
+ 0x70c8, 0x0a1b,
+ 0x70c9, 0x3b31,
+ 0x70ca, 0x19d6,
+ 0x70cb, 0x3b32,
+ 0x70cf, 0x21a3,
+ 0x70d0, 0x3b36,
+ 0x70d8, 0x079d,
+ 0x70d9, 0x09be,
+ 0x70da, 0x3b3e,
+ 0x70db, 0x11f1,
+ 0x70dc, 0x3b3f,
+ 0x70df, 0x0ff5,
+ 0x70e0, 0x3b42,
+ 0x70e4, 0x094b,
+ 0x70e5, 0x3b46,
+ 0x70e6, 0x0650,
+ 0x70e7, 0x0d0e,
+ 0x70e8, 0x19d5,
+ 0x70e9, 0x07f7,
+ 0x70ea, 0x3b47,
+ 0x70eb, 0x0e1f,
+ 0x70ec, 0x08ce,
+ 0x70ed, 0x0ca3,
+ 0x70ee, 0x3b48,
+ 0x70ef, 0x0f16,
+ 0x70f0, 0x3b49,
+ 0x70f4, 0x217a,
+ 0x70f5, 0x3b4d,
+ 0x70f7, 0x0e9a,
+ 0x70f8, 0x3b4f,
+ 0x70f9, 0x0bac,
+ 0x70fa, 0x3b50,
+ 0x70fd, 0x0686,
+ 0x70fe, 0x3b53,
+ 0x7100, 0x3b55,
+ 0x7109, 0x0ff2,
+ 0x710a, 0x076f,
+ 0x710b, 0x3b5e,
+ 0x7110, 0x19d7,
+ 0x7111, 0x3b63,
+ 0x7113, 0x19d8,
+ 0x7114, 0x3b65,
+ 0x7115, 0x07d5,
+ 0x7116, 0x19d9,
+ 0x7117, 0x3b66,
+ 0x7118, 0x19f0,
+ 0x7119, 0x0423,
+ 0x711a, 0x0676,
+ 0x711b, 0x3b67,
+ 0x7121, 0x21a5,
+ 0x7122, 0x3b6d,
+ 0x7126, 0x088a,
+ 0x7127, 0x3b71,
+ 0x712f, 0x19da,
+ 0x7130, 0x100f,
+ 0x7131, 0x19db,
+ 0x7132, 0x3b79,
+ 0x7136, 0x0c96,
+ 0x7137, 0x3b7d,
+ 0x7145, 0x19df,
+ 0x7146, 0x3b8b,
+ 0x7149, 0x2022,
+ 0x714a, 0x19e1,
+ 0x714b, 0x3b8e,
+ 0x714c, 0x07e2,
+ 0x714d, 0x3b8f,
+ 0x714e, 0x0858,
+ 0x714f, 0x3b90,
+ 0x7152, 0x24d6,
+ 0x7153, 0x3b93,
+ 0x715c, 0x19dd,
+ 0x715d, 0x3b9c,
+ 0x715e, 0x0cf0,
+ 0x715f, 0x3b9d,
+ 0x7162, 0x233a,
+ 0x7163, 0x3ba0,
+ 0x7164, 0x0abf,
+ 0x7165, 0x3ba1,
+ 0x7166, 0x19f1,
+ 0x7167, 0x1176,
+ 0x7168, 0x19de,
+ 0x7169, 0x1eee,
+ 0x716a, 0x3ba2,
+ 0x716c, 0x24d5,
+ 0x716d, 0x3ba4,
+ 0x716e, 0x11f2,
+ 0x716f, 0x3ba5,
+ 0x7172, 0x19e0,
+ 0x7173, 0x19dc,
+ 0x7174, 0x3ba8,
+ 0x7178, 0x19e2,
+ 0x7179, 0x3bac,
+ 0x717a, 0x19e3,
+ 0x717b, 0x3bad,
+ 0x717d, 0x0cf8,
+ 0x717e, 0x3baf,
+ 0x7184, 0x0f15,
+ 0x7185, 0x3bb5,
+ 0x718a, 0x0fa7,
+ 0x718b, 0x3bba,
+ 0x718f, 0x0fd5,
+ 0x7190, 0x3bbe,
+ 0x7192, 0x2228,
+ 0x7193, 0x3bc0,
+ 0x7194, 0x0cb6,
+ 0x7195, 0x3bc1,
+ 0x7197, 0x24d7,
+ 0x7198, 0x19e4,
+ 0x7199, 0x0f04,
+ 0x719a, 0x3bc3,
+ 0x719f, 0x0d83,
+ 0x71a0, 0x19e8,
+ 0x71a1, 0x3bc8,
+ 0x71a8, 0x19e7,
+ 0x71a9, 0x3bcf,
+ 0x71ac, 0x03c9,
+ 0x71ad, 0x3bd2,
+ 0x71b1, 0x20fc,
+ 0x71b2, 0x3bd6,
+ 0x71b3, 0x19e5,
+ 0x71b4, 0x3bd7,
+ 0x71b5, 0x19e6,
+ 0x71b6, 0x3bd8,
+ 0x71b9, 0x19f2,
+ 0x71ba, 0x3bdb,
+ 0x71be, 0x1e87,
+ 0x71bf, 0x3bdf,
+ 0x71c1, 0x24d8,
+ 0x71c2, 0x3be1,
+ 0x71c3, 0x0c97,
+ 0x71c4, 0x3be2,
+ 0x71c8, 0x1eba,
+ 0x71c9, 0x3be6,
+ 0x71ce, 0x0a10,
+ 0x71cf, 0x3beb,
+ 0x71d2, 0x2119,
+ 0x71d3, 0x3bee,
+ 0x71d4, 0x19ea,
+ 0x71d5, 0x1009,
+ 0x71d6, 0x3bef,
+ 0x71d9, 0x216c,
+ 0x71da, 0x3bf2,
+ 0x71dc, 0x24d9,
+ 0x71dd, 0x3bf4,
+ 0x71df, 0x2227,
+ 0x71e0, 0x19e9,
+ 0x71e1, 0x3bf6,
+ 0x71e5, 0x1132,
+ 0x71e6, 0x1e5f,
+ 0x71e7, 0x19eb,
+ 0x71e8, 0x3bfa,
+ 0x71ed, 0x229f,
+ 0x71ee, 0x1396,
+ 0x71ef, 0x3bff,
+ 0x71f4, 0x1f5d,
+ 0x71f5, 0x3c04,
+ 0x71f9, 0x19ec,
+ 0x71fa, 0x3c08,
+ 0x71fc, 0x1fbc,
+ 0x71fd, 0x3c0a,
+ 0x71fe, 0x24da,
+ 0x71ff, 0x3c0b,
+ 0x7200, 0x3c0c,
+ 0x7206, 0x0415,
+ 0x7207, 0x3c12,
+ 0x720d, 0x2149,
+ 0x720e, 0x3c18,
+ 0x7210, 0x2046,
+ 0x7211, 0x3c1a,
+ 0x721b, 0x2000,
+ 0x721c, 0x3c24,
+ 0x721d, 0x19ed,
+ 0x721e, 0x3c25,
+ 0x7228, 0x19ee,
+ 0x7229, 0x3c2f,
+ 0x722a, 0x1203,
+ 0x722b, 0x3c30,
+ 0x722c, 0x0b81,
+ 0x722d, 0x3c31,
+ 0x7230, 0x196c,
+ 0x7231, 0x03b9,
+ 0x7232, 0x2190,
+ 0x7233, 0x3c34,
+ 0x7235, 0x0923,
+ 0x7236, 0x06b3,
+ 0x7237, 0x1036,
+ 0x7238, 0x03e1,
+ 0x7239, 0x05da,
+ 0x723a, 0x2208,
+ 0x723b, 0x1269,
+ 0x723c, 0x3c36,
+ 0x723d, 0x0da1,
+ 0x723e, 0x1ee6,
+ 0x723f, 0x169d,
+ 0x7240, 0x3c37,
+ 0x7247, 0x0bcb,
+ 0x7248, 0x03f1,
+ 0x7249, 0x3c3e,
+ 0x724c, 0x0b87,
+ 0x724d, 0x1969,
+ 0x724e, 0x3c41,
+ 0x7252, 0x196a,
+ 0x7253, 0x3c45,
+ 0x7256, 0x196b,
+ 0x7257, 0x3c48,
+ 0x7258, 0x24c3,
+ 0x7259, 0x0fe9,
+ 0x725a, 0x3c49,
+ 0x725b, 0x0b64,
+ 0x725c, 0x3c4a,
+ 0x725d, 0x1944,
+ 0x725e, 0x3c4b,
+ 0x725f, 0x0b15,
+ 0x7260, 0x3c4c,
+ 0x7261, 0x0b18,
+ 0x7262, 0x09b9,
+ 0x7263, 0x3c4d,
+ 0x7266, 0x1945,
+ 0x7267, 0x0b24,
+ 0x7268, 0x3c50,
+ 0x7269, 0x0efe,
+ 0x726a, 0x3c51,
+ 0x726e, 0x1942,
+ 0x726f, 0x1946,
+ 0x7270, 0x3c55,
+ 0x7272, 0x0d35,
+ 0x7273, 0x3c57,
+ 0x7275, 0x0c20,
+ 0x7276, 0x3c59,
+ 0x7279, 0x0e2b,
+ 0x727a, 0x0f0d,
+ 0x727b, 0x3c5c,
+ 0x727d, 0x20cc,
+ 0x727e, 0x1947,
+ 0x7280, 0x0f19,
+ 0x7281, 0x09d2,
+ 0x7282, 0x3c5e,
+ 0x7284, 0x1949,
+ 0x7285, 0x3c60,
+ 0x728a, 0x05fe,
+ 0x728b, 0x194a,
+ 0x728c, 0x3c65,
+ 0x728d, 0x194b,
+ 0x728e, 0x3c66,
+ 0x728f, 0x194c,
+ 0x7290, 0x3c67,
+ 0x7292, 0x194d,
+ 0x7293, 0x3c69,
+ 0x7296, 0x2340,
+ 0x7297, 0x3c6c,
+ 0x729f, 0x1943,
+ 0x72a0, 0x3c74,
+ 0x72a2, 0x1ed1,
+ 0x72a3, 0x3c76,
+ 0x72a7, 0x21ac,
+ 0x72a8, 0x3c7a,
+ 0x72ac, 0x0c89,
+ 0x72ad, 0x15ef,
+ 0x72ae, 0x3c7e,
+ 0x72af, 0x0655,
+ 0x72b0, 0x15f0,
+ 0x72b1, 0x3c7f,
+ 0x72b4, 0x15f1,
+ 0x72b5, 0x3c82,
+ 0x72b6, 0x1211,
+ 0x72b7, 0x15f2,
+ 0x72b9, 0x10b1,
+ 0x72ba, 0x3c83,
+ 0x72c0, 0x22af,
+ 0x72c1, 0x15f5,
+ 0x72c2, 0x097e,
+ 0x72c3, 0x15f4,
+ 0x72c4, 0x05b3,
+ 0x72c5, 0x3c89,
+ 0x72c8, 0x0420,
+ 0x72c9, 0x3c8c,
+ 0x72cd, 0x15f7,
+ 0x72ce, 0x15f6,
+ 0x72cf, 0x3c90,
+ 0x72d0, 0x07b3,
+ 0x72d1, 0x3c91,
+ 0x72d2, 0x15f8,
+ 0x72d3, 0x3c92,
+ 0x72d7, 0x0710,
+ 0x72d8, 0x3c96,
+ 0x72d9, 0x0900,
+ 0x72da, 0x3c97,
+ 0x72de, 0x0b5f,
+ 0x72df, 0x3c9b,
+ 0x72e0, 0x0794,
+ 0x72e1, 0x0897,
+ 0x72e2, 0x3c9c,
+ 0x72e8, 0x15f9,
+ 0x72e9, 0x15fb,
+ 0x72ea, 0x3ca2,
+ 0x72ec, 0x05ff,
+ 0x72ed, 0x0f2e,
+ 0x72ee, 0x0d3f,
+ 0x72ef, 0x15fa,
+ 0x72f0, 0x1199,
+ 0x72f1, 0x10e1,
+ 0x72f2, 0x15fc,
+ 0x72f3, 0x1600,
+ 0x72f4, 0x15fd,
+ 0x72f5, 0x3ca4,
+ 0x72f7, 0x15fe,
+ 0x72f8, 0x09d5,
+ 0x72f9, 0x21b6,
+ 0x72fa, 0x1602,
+ 0x72fc, 0x09b2,
+ 0x72fd, 0x1e3d,
+ 0x72fe, 0x3ca6,
+ 0x7300, 0x3ca8,
+ 0x7301, 0x15ff,
+ 0x7302, 0x3ca9,
+ 0x7303, 0x1601,
+ 0x7304, 0x3caa,
+ 0x730a, 0x1607,
+ 0x730b, 0x3cb0,
+ 0x730e, 0x0a1d,
+ 0x730f, 0x3cb3,
+ 0x7313, 0x1605,
+ 0x7314, 0x3cb7,
+ 0x7315, 0x160a,
+ 0x7316, 0x04c5,
+ 0x7317, 0x1604,
+ 0x7318, 0x3cb8,
+ 0x731b, 0x0ad2,
+ 0x731c, 0x0489,
+ 0x731d, 0x1609,
+ 0x731e, 0x1608,
+ 0x731f, 0x3cbb,
+ 0x7321, 0x1606,
+ 0x7322, 0x160b,
+ 0x7323, 0x3cbd,
+ 0x7325, 0x160d,
+ 0x7326, 0x3cbf,
+ 0x7329, 0x0f94,
+ 0x732a, 0x11ec,
+ 0x732b, 0x0aad,
+ 0x732c, 0x160e,
+ 0x732d, 0x3cc2,
+ 0x732e, 0x0f44,
+ 0x732f, 0x3cc3,
+ 0x7331, 0x1610,
+ 0x7332, 0x3cc5,
+ 0x7334, 0x07a6,
+ 0x7335, 0x3cc7,
+ 0x7336, 0x2235,
+ 0x7337, 0x18d4,
+ 0x7338, 0x160f,
+ 0x7339, 0x160c,
+ 0x733a, 0x3cc8,
+ 0x733b, 0x2397,
+ 0x733c, 0x3cc9,
+ 0x733e, 0x07c0,
+ 0x733f, 0x10f6,
+ 0x7340, 0x3ccb,
+ 0x7341, 0x2395,
+ 0x7342, 0x3ccc,
+ 0x7344, 0x223f,
+ 0x7345, 0x212a,
+ 0x7346, 0x3cce,
+ 0x734d, 0x1612,
+ 0x734e, 0x3cd5,
+ 0x7350, 0x1611,
+ 0x7351, 0x3cd7,
+ 0x7352, 0x18d5,
+ 0x7353, 0x3cd8,
+ 0x7357, 0x1613,
+ 0x7358, 0x3cdc,
+ 0x7360, 0x1614,
+ 0x7361, 0x3ce4,
+ 0x7368, 0x1ed2,
+ 0x7369, 0x3ceb,
+ 0x736a, 0x2396,
+ 0x736b, 0x2398,
+ 0x736c, 0x1615,
+ 0x736d, 0x0df4,
+ 0x736e, 0x3cec,
+ 0x736f, 0x1616,
+ 0x7370, 0x20a2,
+ 0x7371, 0x3ced,
+ 0x7372, 0x1f64,
+ 0x7373, 0x3cee,
+ 0x7375, 0x202b,
+ 0x7376, 0x3cf0,
+ 0x7377, 0x2394,
+ 0x7378, 0x2139,
+ 0x7379, 0x3cf1,
+ 0x737a, 0x215f,
+ 0x737b, 0x21c1,
+ 0x737c, 0x239a,
+ 0x737d, 0x3cf2,
+ 0x737e, 0x1617,
+ 0x737f, 0x3cf3,
+ 0x7380, 0x2399,
+ 0x7381, 0x3cf4,
+ 0x7384, 0x0fc9,
+ 0x7385, 0x3cf7,
+ 0x7387, 0x0a71,
+ 0x7388, 0x3cf9,
+ 0x7389, 0x10d6,
+ 0x738a, 0x3cfa,
+ 0x738b, 0x0ea6,
+ 0x738c, 0x3cfb,
+ 0x738e, 0x1818,
+ 0x738f, 0x3cfd,
+ 0x7391, 0x1819,
+ 0x7392, 0x3cff,
+ 0x7396, 0x08f0,
+ 0x7397, 0x3d03,
+ 0x739b, 0x0a91,
+ 0x739c, 0x3d07,
+ 0x739f, 0x181c,
+ 0x73a0, 0x3d0a,
+ 0x73a2, 0x181b,
+ 0x73a3, 0x3d0c,
+ 0x73a9, 0x0e97,
+ 0x73aa, 0x3d12,
+ 0x73ab, 0x0aba,
+ 0x73ac, 0x3d13,
+ 0x73ae, 0x181a,
+ 0x73af, 0x07cc,
+ 0x73b0, 0x0f43,
+ 0x73b1, 0x3d15,
+ 0x73b2, 0x0a2a,
+ 0x73b3, 0x1821,
+ 0x73b4, 0x3d16,
+ 0x73b7, 0x1820,
+ 0x73b8, 0x3d19,
+ 0x73ba, 0x182c,
+ 0x73bb, 0x046a,
+ 0x73bc, 0x3d1b,
+ 0x73c0, 0x1822,
+ 0x73c1, 0x3d1f,
+ 0x73c2, 0x181e,
+ 0x73c3, 0x3d20,
+ 0x73c8, 0x1824,
+ 0x73c9, 0x1823,
+ 0x73ca, 0x0cf3,
+ 0x73cb, 0x3d25,
+ 0x73cd, 0x1185,
+ 0x73ce, 0x3d27,
+ 0x73cf, 0x181d,
+ 0x73d0, 0x0646,
+ 0x73d1, 0x181f,
+ 0x73d2, 0x3d28,
+ 0x73d9, 0x1826,
+ 0x73da, 0x3d2f,
+ 0x73de, 0x182b,
+ 0x73df, 0x3d33,
+ 0x73e0, 0x11e8,
+ 0x73e1, 0x3d34,
+ 0x73e5, 0x1825,
+ 0x73e6, 0x3d38,
+ 0x73e7, 0x182a,
+ 0x73e8, 0x3d39,
+ 0x73e9, 0x1829,
+ 0x73ea, 0x3d3a,
+ 0x73ed, 0x03eb,
+ 0x73ee, 0x3d3d,
+ 0x73f2, 0x182d,
+ 0x73f3, 0x3d41,
+ 0x73fe, 0x21c0,
+ 0x73ff, 0x3d4c,
+ 0x7400, 0x3d4d,
+ 0x7403, 0x0c6f,
+ 0x7404, 0x3d50,
+ 0x7405, 0x09b0,
+ 0x7406, 0x09d8,
+ 0x7407, 0x3d51,
+ 0x7409, 0x0a39,
+ 0x740a, 0x1828,
+ 0x740b, 0x3d53,
+ 0x740f, 0x182e,
+ 0x7410, 0x0deb,
+ 0x7411, 0x3d57,
+ 0x741a, 0x1838,
+ 0x741b, 0x1837,
+ 0x741c, 0x3d60,
+ 0x7422, 0x121e,
+ 0x7423, 0x3d66,
+ 0x7425, 0x1832,
+ 0x7426, 0x1831,
+ 0x7427, 0x3d68,
+ 0x7428, 0x1833,
+ 0x7429, 0x3d69,
+ 0x742a, 0x182f,
+ 0x742b, 0x3d6a,
+ 0x742c, 0x1836,
+ 0x742d, 0x3d6b,
+ 0x742e, 0x1835,
+ 0x742f, 0x3d6c,
+ 0x7430, 0x1834,
+ 0x7431, 0x3d6d,
+ 0x7433, 0x0a1e,
+ 0x7434, 0x0c56,
+ 0x7435, 0x0bbe,
+ 0x7436, 0x0b84,
+ 0x7437, 0x3d6f,
+ 0x743c, 0x0c6a,
+ 0x743d, 0x3d74,
+ 0x743f, 0x2460,
+ 0x7440, 0x3d76,
+ 0x7441, 0x1839,
+ 0x7442, 0x3d77,
+ 0x744b, 0x245c,
+ 0x744c, 0x3d80,
+ 0x7455, 0x183c,
+ 0x7456, 0x3d89,
+ 0x7457, 0x183b,
+ 0x7458, 0x3d8a,
+ 0x7459, 0x183d,
+ 0x745a, 0x07ae,
+ 0x745b, 0x1830,
+ 0x745c, 0x183a,
+ 0x745d, 0x3d8b,
+ 0x745e, 0x0ccb,
+ 0x745f, 0x0ce3,
+ 0x7460, 0x3d8c,
+ 0x7463, 0x215d,
+ 0x7464, 0x3d8f,
+ 0x7469, 0x2225,
+ 0x746a, 0x206a,
+ 0x746b, 0x3d94,
+ 0x746d, 0x183f,
+ 0x746e, 0x3d96,
+ 0x7470, 0x073e,
+ 0x7471, 0x3d98,
+ 0x7476, 0x1027,
+ 0x7477, 0x183e,
+ 0x7478, 0x3d9d,
+ 0x747e, 0x1840,
+ 0x747f, 0x3da3,
+ 0x7480, 0x1843,
+ 0x7482, 0x3da4,
+ 0x7483, 0x09f0,
+ 0x7484, 0x3da5,
+ 0x7487, 0x1845,
+ 0x7488, 0x3da8,
+ 0x7489, 0x2461,
+ 0x748a, 0x3da9,
+ 0x748b, 0x1846,
+ 0x748c, 0x3daa,
+ 0x748e, 0x1842,
+ 0x748f, 0x3dac,
+ 0x7490, 0x184a,
+ 0x7491, 0x3dad,
+ 0x749c, 0x1841,
+ 0x749d, 0x3db8,
+ 0x749e, 0x1847,
+ 0x749f, 0x3db9,
+ 0x74a3, 0x245b,
+ 0x74a4, 0x3dbd,
+ 0x74a6, 0x2462,
+ 0x74a7, 0x184b,
+ 0x74a8, 0x1848,
+ 0x74aa, 0x3dbf,
+ 0x74b0, 0x1f54,
+ 0x74b1, 0x3dc5,
+ 0x74ba, 0x184d,
+ 0x74bb, 0x3dce,
+ 0x74bd, 0x245f,
+ 0x74be, 0x3dd0,
+ 0x74ca, 0x20ec,
+ 0x74cb, 0x3ddc,
+ 0x74cf, 0x245d,
+ 0x74d0, 0x3de0,
+ 0x74d2, 0x184c,
+ 0x74d3, 0x3de2,
+ 0x74d4, 0x2463,
+ 0x74d5, 0x3de3,
+ 0x74da, 0x2464,
+ 0x74db, 0x3de8,
+ 0x74dc, 0x0728,
+ 0x74dd, 0x3de9,
+ 0x74de, 0x1b32,
+ 0x74df, 0x3dea,
+ 0x74e0, 0x1b33,
+ 0x74e1, 0x3deb,
+ 0x74e2, 0x0bcf,
+ 0x74e3, 0x03f5,
+ 0x74e4, 0x0c9a,
+ 0x74e5, 0x3dec,
+ 0x74e6, 0x0e90,
+ 0x74e7, 0x3ded,
+ 0x74ee, 0x0edc,
+ 0x74ef, 0x1903,
+ 0x74f0, 0x3df4,
+ 0x74f4, 0x1904,
+ 0x74f5, 0x3df8,
+ 0x74f6, 0x0bde,
+ 0x74f7, 0x054c,
+ 0x74f8, 0x3df9,
+ 0x74ff, 0x1905,
+ 0x7500, 0x3e00,
+ 0x7504, 0x1188,
+ 0x7505, 0x3e04,
+ 0x750c, 0x24a5,
+ 0x750d, 0x1485,
+ 0x750e, 0x3e0b,
+ 0x750f, 0x1906,
+ 0x7510, 0x3e0c,
+ 0x7511, 0x1907,
+ 0x7512, 0x3e0d,
+ 0x7513, 0x1908,
+ 0x7514, 0x3e0e,
+ 0x7518, 0x06c5,
+ 0x7519, 0x14f8,
+ 0x751a, 0x0d2e,
+ 0x751b, 0x3e12,
+ 0x751c, 0x0e43,
+ 0x751d, 0x3e13,
+ 0x751f, 0x0d33,
+ 0x7520, 0x3e15,
+ 0x7523, 0x1e70,
+ 0x7524, 0x3e18,
+ 0x7525, 0x0d34,
+ 0x7526, 0x3e19,
+ 0x7528, 0x10a8,
+ 0x7529, 0x0d9b,
+ 0x752a, 0x3e1b,
+ 0x752b, 0x06a1,
+ 0x752c, 0x1b34,
+ 0x752d, 0x042b,
+ 0x752e, 0x3e1c,
+ 0x752f, 0x1734,
+ 0x7530, 0x0e42,
+ 0x7531, 0x10ae,
+ 0x7532, 0x084a,
+ 0x7533, 0x0d23,
+ 0x7534, 0x3e1d,
+ 0x7535, 0x05c8,
+ 0x7536, 0x3e1e,
+ 0x7537, 0x0b33,
+ 0x7538, 0x05ca,
+ 0x7539, 0x3e1f,
+ 0x753a, 0x1a78,
+ 0x753b, 0x07c2,
+ 0x753c, 0x3e20,
+ 0x753e, 0x1816,
+ 0x753f, 0x3e22,
+ 0x7540, 0x1a79,
+ 0x7541, 0x3e23,
+ 0x7545, 0x04ce,
+ 0x7546, 0x3e27,
+ 0x7548, 0x1a7c,
+ 0x7549, 0x3e29,
+ 0x754b, 0x1a7b,
+ 0x754c, 0x08b8,
+ 0x754d, 0x3e2b,
+ 0x754e, 0x1a7a,
+ 0x754f, 0x0ec6,
+ 0x7550, 0x3e2c,
+ 0x7554, 0x0b90,
+ 0x7555, 0x3e30,
+ 0x7559, 0x0a3d,
+ 0x755a, 0x139e,
+ 0x755b, 0x1a7d,
+ 0x755c, 0x0fbe,
+ 0x755d, 0x208f,
+ 0x755e, 0x3e34,
+ 0x7562, 0x1e42,
+ 0x7563, 0x3e38,
+ 0x7565, 0x0a7b,
+ 0x7566, 0x0c07,
+ 0x7567, 0x3e3a,
+ 0x756a, 0x0649,
+ 0x756b, 0x1f4e,
+ 0x756c, 0x3e3d,
+ 0x7572, 0x1a7e,
+ 0x7573, 0x3e43,
+ 0x7574, 0x0510,
+ 0x7575, 0x3e44,
+ 0x7576, 0x1eb1,
+ 0x7577, 0x3e45,
+ 0x7578, 0x0810,
+ 0x7579, 0x1a7f,
+ 0x757a, 0x3e46,
+ 0x757f, 0x1814,
+ 0x7580, 0x3e4b,
+ 0x7583, 0x1a80,
+ 0x7584, 0x3e4e,
+ 0x7586, 0x087f,
+ 0x7587, 0x1e8b,
+ 0x7588, 0x3e50,
+ 0x758b, 0x1bc6,
+ 0x758c, 0x3e53,
+ 0x758f, 0x0d7f,
+ 0x7590, 0x3e56,
+ 0x7591, 0x1050,
+ 0x7592, 0x1b60,
+ 0x7593, 0x3e57,
+ 0x7594, 0x1b61,
+ 0x7595, 0x3e58,
+ 0x7596, 0x1b62,
+ 0x7597, 0x0a0f,
+ 0x7598, 0x3e59,
+ 0x7599, 0x06e8,
+ 0x759a, 0x08fd,
+ 0x759b, 0x3e5a,
+ 0x759d, 0x1b64,
+ 0x759e, 0x3e5c,
+ 0x759f, 0x0b72,
+ 0x75a0, 0x1b63,
+ 0x75a1, 0x101a,
+ 0x75a2, 0x3e5d,
+ 0x75a3, 0x1b66,
+ 0x75a4, 0x03d7,
+ 0x75a5, 0x08bb,
+ 0x75a6, 0x3e5e,
+ 0x75ab, 0x1066,
+ 0x75ac, 0x1b65,
+ 0x75ad, 0x3e63,
+ 0x75ae, 0x0532,
+ 0x75af, 0x0685,
+ 0x75b0, 0x1b6c,
+ 0x75b1, 0x1b6b,
+ 0x75b2, 0x0bc2,
+ 0x75b3, 0x1b67,
+ 0x75b5, 0x0546,
+ 0x75b6, 0x3e64,
+ 0x75b8, 0x1b69,
+ 0x75b9, 0x118f,
+ 0x75ba, 0x3e66,
+ 0x75bc, 0x0e2e,
+ 0x75bd, 0x0901,
+ 0x75be, 0x0825,
+ 0x75bf, 0x3e68,
+ 0x75c2, 0x1b6e,
+ 0x75c3, 0x1b6d,
+ 0x75c4, 0x1b6a,
+ 0x75c5, 0x0468,
+ 0x75c6, 0x3e6b,
+ 0x75c7, 0x11a1,
+ 0x75c8, 0x109d,
+ 0x75c9, 0x08e6,
+ 0x75ca, 0x0c87,
+ 0x75cb, 0x3e6c,
+ 0x75cd, 0x1b70,
+ 0x75ce, 0x3e6e,
+ 0x75d2, 0x1020,
+ 0x75d3, 0x3e72,
+ 0x75d4, 0x11cb,
+ 0x75d5, 0x0792,
+ 0x75d6, 0x1b6f,
+ 0x75d7, 0x3e73,
+ 0x75d8, 0x05fa,
+ 0x75d9, 0x1fc6,
+ 0x75da, 0x3e74,
+ 0x75db, 0x0e65,
+ 0x75dc, 0x3e75,
+ 0x75de, 0x0bc5,
+ 0x75df, 0x3e77,
+ 0x75e2, 0x09ea,
+ 0x75e3, 0x1b71,
+ 0x75e4, 0x1b74,
+ 0x75e5, 0x3e7a,
+ 0x75e6, 0x1b73,
+ 0x75e7, 0x1b76,
+ 0x75e8, 0x1b72,
+ 0x75e9, 0x3e7b,
+ 0x75ea, 0x07d3,
+ 0x75eb, 0x1b75,
+ 0x75ec, 0x3e7c,
+ 0x75f0, 0x0e08,
+ 0x75f1, 0x1b78,
+ 0x75f2, 0x3e80,
+ 0x75f4, 0x04fa,
+ 0x75f5, 0x3e82,
+ 0x75f9, 0x043d,
+ 0x75fa, 0x3e86,
+ 0x75fc, 0x1b79,
+ 0x75fd, 0x3e88,
+ 0x75ff, 0x1b7a,
+ 0x7600, 0x1b7c,
+ 0x7601, 0x0564,
+ 0x7602, 0x25ae,
+ 0x7603, 0x1b77,
+ 0x7604, 0x3e8a,
+ 0x7605, 0x1b7d,
+ 0x7606, 0x3e8b,
+ 0x760a, 0x1b80,
+ 0x760b, 0x1f01,
+ 0x760c, 0x1b7e,
+ 0x760d, 0x2200,
+ 0x760e, 0x3e8f,
+ 0x7610, 0x1b7b,
+ 0x7611, 0x3e91,
+ 0x7615, 0x1b83,
+ 0x7616, 0x3e95,
+ 0x7617, 0x1b7f,
+ 0x7618, 0x1b82,
+ 0x7619, 0x1b84,
+ 0x761a, 0x3e96,
+ 0x761b, 0x1b85,
+ 0x761c, 0x3e97,
+ 0x761e, 0x25b2,
+ 0x761f, 0x0ed0,
+ 0x7620, 0x1b88,
+ 0x7621, 0x1e97,
+ 0x7622, 0x1b87,
+ 0x7623, 0x3e99,
+ 0x7624, 0x0a3f,
+ 0x7625, 0x1b81,
+ 0x7626, 0x0d74,
+ 0x7627, 0x20ab,
+ 0x7628, 0x3e9a,
+ 0x7629, 0x0574,
+ 0x762a, 0x045a,
+ 0x762b, 0x0e04,
+ 0x762c, 0x3e9b,
+ 0x762d, 0x1b8a,
+ 0x762e, 0x3e9c,
+ 0x7630, 0x1b8b,
+ 0x7631, 0x3e9e,
+ 0x7633, 0x1b90,
+ 0x7634, 0x116f,
+ 0x7635, 0x1b8d,
+ 0x7636, 0x3ea0,
+ 0x7638, 0x0c8e,
+ 0x7639, 0x3ea2,
+ 0x763b, 0x25b3,
+ 0x763c, 0x1b86,
+ 0x763d, 0x3ea4,
+ 0x763e, 0x1b8f,
+ 0x763f, 0x1b8c,
+ 0x7640, 0x1b89,
+ 0x7641, 0x3ea5,
+ 0x7642, 0x2028,
+ 0x7643, 0x1b8e,
+ 0x7644, 0x3ea6,
+ 0x7646, 0x25af,
+ 0x7648, 0x3ea8,
+ 0x7649, 0x25b1,
+ 0x764a, 0x3ea9,
+ 0x764c, 0x03b4,
+ 0x764d, 0x1b91,
+ 0x764e, 0x3eab,
+ 0x7654, 0x1b93,
+ 0x7655, 0x3eb1,
+ 0x7656, 0x1b95,
+ 0x7657, 0x3eb2,
+ 0x7658, 0x25ac,
+ 0x7659, 0x3eb3,
+ 0x765c, 0x1b94,
+ 0x765d, 0x3eb6,
+ 0x765e, 0x1b92,
+ 0x765f, 0x1e4e,
+ 0x7660, 0x3eb7,
+ 0x7662, 0x2202,
+ 0x7663, 0x0fcb,
+ 0x7664, 0x25ab,
+ 0x7665, 0x2286,
+ 0x7666, 0x3eb9,
+ 0x7667, 0x25ad,
+ 0x7668, 0x3eba,
+ 0x7669, 0x25b6,
+ 0x766a, 0x3ebb,
+ 0x766b, 0x1b96,
+ 0x766c, 0x21e3,
+ 0x766d, 0x25b4,
+ 0x766f, 0x1b97,
+ 0x7670, 0x222f,
+ 0x7671, 0x2165,
+ 0x7672, 0x25b7,
+ 0x7673, 0x3ebc,
+ 0x7678, 0x0748,
+ 0x7679, 0x3ec1,
+ 0x767b, 0x05a8,
+ 0x767c, 0x1ee9,
+ 0x767d, 0x03e2,
+ 0x767e, 0x03e4,
+ 0x767f, 0x3ec3,
+ 0x7682, 0x1130,
+ 0x7683, 0x3ec6,
+ 0x7684, 0x05a5,
+ 0x7685, 0x3ec7,
+ 0x7686, 0x08a5,
+ 0x7687, 0x07df,
+ 0x7688, 0x1b2d,
+ 0x7689, 0x3ec8,
+ 0x768b, 0x06d9,
+ 0x768c, 0x3eca,
+ 0x768e, 0x1b2e,
+ 0x768f, 0x3ecc,
+ 0x7691, 0x03b3,
+ 0x7692, 0x3ece,
+ 0x7693, 0x1b2f,
+ 0x7694, 0x3ecf,
+ 0x7696, 0x0e9f,
+ 0x7697, 0x3ed1,
+ 0x7699, 0x1b30,
+ 0x769a, 0x1e25,
+ 0x769b, 0x3ed3,
+ 0x76a4, 0x1b31,
+ 0x76a5, 0x3edc,
+ 0x76ae, 0x0bc3,
+ 0x76af, 0x3ee5,
+ 0x76b1, 0x11e4,
+ 0x76b2, 0x1bc8,
+ 0x76b3, 0x3ee7,
+ 0x76b4, 0x1bc9,
+ 0x76b5, 0x3ee8,
+ 0x76b8, 0x25c0,
+ 0x76b9, 0x3eeb,
+ 0x76ba, 0x229a,
+ 0x76bb, 0x3eec,
+ 0x76bf, 0x0af8,
+ 0x76c0, 0x3ef0,
+ 0x76c2, 0x10c0,
+ 0x76c3, 0x3ef2,
+ 0x76c5, 0x11d0,
+ 0x76c6, 0x0ba9,
+ 0x76c7, 0x3ef4,
+ 0x76c8, 0x1094,
+ 0x76c9, 0x3ef5,
+ 0x76ca, 0x106d,
+ 0x76cb, 0x3ef6,
+ 0x76cd, 0x1a8b,
+ 0x76ce, 0x03c6,
+ 0x76cf, 0x1156,
+ 0x76d0, 0x0ff7,
+ 0x76d1, 0x0853,
+ 0x76d2, 0x0787,
+ 0x76d3, 0x3ef8,
+ 0x76d4, 0x0985,
+ 0x76d5, 0x3ef9,
+ 0x76d6, 0x06c2,
+ 0x76d7, 0x05a2,
+ 0x76d8, 0x0b8d,
+ 0x76d9, 0x3efa,
+ 0x76db, 0x0d39,
+ 0x76dc, 0x3efc,
+ 0x76de, 0x226e,
+ 0x76df, 0x0ad0,
+ 0x76e0, 0x3efe,
+ 0x76e1, 0x1fbd,
+ 0x76e2, 0x3eff,
+ 0x76e3, 0x1f84,
+ 0x76e4, 0x20b2,
+ 0x76e5, 0x1a8c,
+ 0x76e6, 0x3f00,
+ 0x76e7, 0x2043,
+ 0x76e8, 0x3f01,
+ 0x76ee, 0x0b22,
+ 0x76ef, 0x05e1,
+ 0x76f0, 0x3f07,
+ 0x76f1, 0x1a58,
+ 0x76f2, 0x0aa9,
+ 0x76f3, 0x3f08,
+ 0x76f4, 0x11b0,
+ 0x76f5, 0x3f09,
+ 0x76f8, 0x0f4d,
+ 0x76f9, 0x1a5b,
+ 0x76fa, 0x3f0c,
+ 0x76fc, 0x0b8f,
+ 0x76fd, 0x3f0e,
+ 0x76fe, 0x061b,
+ 0x76ff, 0x3f0f,
+ 0x7700, 0x3f10,
+ 0x7701, 0x0d38,
+ 0x7702, 0x3f11,
+ 0x7704, 0x1a59,
+ 0x7705, 0x3f13,
+ 0x7707, 0x1a5c,
+ 0x7709, 0x0ac1,
+ 0x770a, 0x3f15,
+ 0x770b, 0x0941,
+ 0x770c, 0x3f16,
+ 0x770d, 0x1a5a,
+ 0x770e, 0x3f17,
+ 0x7719, 0x1a60,
+ 0x771a, 0x1a5e,
+ 0x771b, 0x3f22,
+ 0x771f, 0x1187,
+ 0x7720, 0x0ae4,
+ 0x7721, 0x3f26,
+ 0x7722, 0x1a5f,
+ 0x7723, 0x3f27,
+ 0x7726, 0x1a62,
+ 0x7727, 0x3f2a,
+ 0x7728, 0x1144,
+ 0x7729, 0x0fcc,
+ 0x772a, 0x3f2b,
+ 0x772d, 0x1a61,
+ 0x772e, 0x3f2e,
+ 0x772f, 0x0ad5,
+ 0x7730, 0x3f2f,
+ 0x7735, 0x1a63,
+ 0x7736, 0x0981,
+ 0x7737, 0x091b,
+ 0x7738, 0x1a64,
+ 0x7739, 0x3f34,
+ 0x773a, 0x0e4a,
+ 0x773b, 0x3f35,
+ 0x773c, 0x1004,
+ 0x773d, 0x3f36,
+ 0x7740, 0x1222,
+ 0x7741, 0x1197,
+ 0x7742, 0x3f39,
+ 0x7743, 0x1a68,
+ 0x7744, 0x3f3a,
+ 0x7747, 0x1a67,
+ 0x7748, 0x3f3d,
+ 0x774f, 0x2684,
+ 0x7750, 0x1a65,
+ 0x7752, 0x3f44,
+ 0x775a, 0x1a69,
+ 0x775b, 0x08d5,
+ 0x775c, 0x3f4c,
+ 0x775e, 0x24ef,
+ 0x775f, 0x3f4e,
+ 0x7761, 0x0da4,
+ 0x7762, 0x1a6b,
+ 0x7763, 0x05fc,
+ 0x7764, 0x3f50,
+ 0x7765, 0x1a6c,
+ 0x7766, 0x0b23,
+ 0x7767, 0x3f51,
+ 0x7768, 0x1a6a,
+ 0x7769, 0x3f52,
+ 0x776b, 0x08af,
+ 0x776c, 0x048e,
+ 0x776d, 0x3f54,
+ 0x7779, 0x0602,
+ 0x777a, 0x3f60,
+ 0x777d, 0x1a6f,
+ 0x777e, 0x1270,
+ 0x777f, 0x1a6d,
+ 0x7780, 0x1a70,
+ 0x7781, 0x3f63,
+ 0x7784, 0x0aee,
+ 0x7785, 0x0517,
+ 0x7786, 0x3f66,
+ 0x778c, 0x1a71,
+ 0x778d, 0x1a6e,
+ 0x778e, 0x0f26,
+ 0x778f, 0x3f6c,
+ 0x7791, 0x1a72,
+ 0x7792, 0x0a9e,
+ 0x7793, 0x3f6e,
+ 0x7798, 0x24ee,
+ 0x7799, 0x3f73,
+ 0x779e, 0x2074,
+ 0x779f, 0x1a73,
+ 0x77a1, 0x3f78,
+ 0x77a2, 0x1495,
+ 0x77a3, 0x3f79,
+ 0x77a5, 0x0bd2,
+ 0x77a6, 0x3f7b,
+ 0x77a7, 0x0c43,
+ 0x77a8, 0x3f7c,
+ 0x77a9, 0x11f4,
+ 0x77aa, 0x05aa,
+ 0x77ab, 0x3f7d,
+ 0x77ac, 0x0da7,
+ 0x77ad, 0x2687,
+ 0x77ae, 0x3f7e,
+ 0x77b0, 0x1a75,
+ 0x77b1, 0x3f80,
+ 0x77b3, 0x0e5c,
+ 0x77b4, 0x3f82,
+ 0x77b5, 0x1a76,
+ 0x77b6, 0x3f83,
+ 0x77bb, 0x1151,
+ 0x77bc, 0x24f0,
+ 0x77bd, 0x1a77,
+ 0x77be, 0x3f88,
+ 0x77bf, 0x1d7e,
+ 0x77c0, 0x3f89,
+ 0x77c7, 0x268d,
+ 0x77c8, 0x3f90,
+ 0x77cd, 0x1397,
+ 0x77ce, 0x3f95,
+ 0x77d7, 0x0526,
+ 0x77d8, 0x3f9e,
+ 0x77da, 0x22a0,
+ 0x77db, 0x0ab1,
+ 0x77dc, 0x1bca,
+ 0x77dd, 0x3fa0,
+ 0x77e2, 0x0d4f,
+ 0x77e3, 0x105a,
+ 0x77e4, 0x3fa5,
+ 0x77e5, 0x11a9,
+ 0x77e6, 0x3fa6,
+ 0x77e7, 0x1b1a,
+ 0x77e8, 0x3fa7,
+ 0x77e9, 0x0907,
+ 0x77ea, 0x3fa8,
+ 0x77eb, 0x0894,
+ 0x77ec, 0x1b1b,
+ 0x77ed, 0x060b,
+ 0x77ee, 0x03b6,
+ 0x77ef, 0x1fab,
+ 0x77f0, 0x3fa9,
+ 0x77f3, 0x0d46,
+ 0x77f4, 0x3fac,
+ 0x77f6, 0x1a22,
+ 0x77f7, 0x3fae,
+ 0x77f8, 0x1a23,
+ 0x77f9, 0x3faf,
+ 0x77fd, 0x0f08,
+ 0x77fe, 0x064c,
+ 0x77ff, 0x0980,
+ 0x7800, 0x1a24,
+ 0x7801, 0x0a92,
+ 0x7802, 0x0ce9,
+ 0x7803, 0x3fb3,
+ 0x7809, 0x1a25,
+ 0x780a, 0x3fb9,
+ 0x780c, 0x0c15,
+ 0x780d, 0x0940,
+ 0x780e, 0x3fbb,
+ 0x7811, 0x1a28,
+ 0x7812, 0x0bb9,
+ 0x7813, 0x3fbe,
+ 0x7814, 0x0ff9,
+ 0x7815, 0x3fbf,
+ 0x7816, 0x1206,
+ 0x7817, 0x1a26,
+ 0x7819, 0x3fc0,
+ 0x781a, 0x100b,
+ 0x781b, 0x3fc1,
+ 0x781c, 0x1a2b,
+ 0x781e, 0x3fc2,
+ 0x781f, 0x1a30,
+ 0x7820, 0x3fc3,
+ 0x7823, 0x1a34,
+ 0x7824, 0x3fc6,
+ 0x7825, 0x1a32,
+ 0x7826, 0x1a3a,
+ 0x7827, 0x1189,
+ 0x7828, 0x3fc7,
+ 0x7829, 0x1a35,
+ 0x782a, 0x3fc8,
+ 0x782c, 0x1a33,
+ 0x782d, 0x1a2a,
+ 0x782e, 0x3fca,
+ 0x7830, 0x0baa,
+ 0x7831, 0x3fcc,
+ 0x7834, 0x0be5,
+ 0x7835, 0x3fcf,
+ 0x7837, 0x0d22,
+ 0x7838, 0x1115,
+ 0x7839, 0x1a2d,
+ 0x783c, 0x1a31,
+ 0x783d, 0x3fd1,
+ 0x783e, 0x09e4,
+ 0x783f, 0x3fd2,
+ 0x7840, 0x0524,
+ 0x7841, 0x3fd3,
+ 0x7843, 0x26a8,
+ 0x7844, 0x3fd5,
+ 0x7845, 0x0741,
+ 0x7846, 0x3fd6,
+ 0x7847, 0x1a3c,
+ 0x7848, 0x3fd7,
+ 0x784c, 0x1a3d,
+ 0x784d, 0x3fdb,
+ 0x784e, 0x1a36,
+ 0x784f, 0x3fdc,
+ 0x7850, 0x1a3b,
+ 0x7851, 0x3fdd,
+ 0x7852, 0x0f07,
+ 0x7853, 0x3fde,
+ 0x7855, 0x0dab,
+ 0x7856, 0x1a38,
+ 0x7858, 0x3fe0,
+ 0x785d, 0x0f62,
+ 0x785e, 0x3fe5,
+ 0x7864, 0x24e9,
+ 0x7865, 0x3feb,
+ 0x7868, 0x24e5,
+ 0x7869, 0x3fee,
+ 0x786a, 0x1a3e,
+ 0x786b, 0x0a3b,
+ 0x786c, 0x1097,
+ 0x786d, 0x1a37,
+ 0x786e, 0x0c92,
+ 0x786f, 0x21fa,
+ 0x7870, 0x3fef,
+ 0x7877, 0x0862,
+ 0x7878, 0x3ff6,
+ 0x787c, 0x0bb1,
+ 0x787d, 0x3ffa,
+ 0x7887, 0x1a42,
+ 0x7888, 0x4004,
+ 0x7889, 0x05d0,
+ 0x788a, 0x4005,
+ 0x788c, 0x0a5c,
+ 0x788d, 0x03b8,
+ 0x788e, 0x0dde,
+ 0x788f, 0x4007,
+ 0x7891, 0x0417,
+ 0x7892, 0x4009,
+ 0x7893, 0x1a40,
+ 0x7894, 0x400a,
+ 0x7897, 0x0e9c,
+ 0x7898, 0x05c3,
+ 0x7899, 0x400d,
+ 0x789a, 0x1a41,
+ 0x789b, 0x1a3f,
+ 0x789c, 0x1a43,
+ 0x789d, 0x400e,
+ 0x789f, 0x05db,
+ 0x78a0, 0x4010,
+ 0x78a1, 0x1a44,
+ 0x78a2, 0x4011,
+ 0x78a3, 0x1a45,
+ 0x78a4, 0x4012,
+ 0x78a5, 0x1a48,
+ 0x78a6, 0x4013,
+ 0x78a7, 0x0435,
+ 0x78a8, 0x4014,
+ 0x78a9, 0x2148,
+ 0x78aa, 0x4015,
+ 0x78ad, 0x24e4,
+ 0x78ae, 0x4018,
+ 0x78b0, 0x0bb7,
+ 0x78b1, 0x0861,
+ 0x78b2, 0x1a46,
+ 0x78b3, 0x0e0f,
+ 0x78b4, 0x04b1,
+ 0x78b5, 0x401a,
+ 0x78b8, 0x24e6,
+ 0x78b9, 0x1a47,
+ 0x78ba, 0x20f7,
+ 0x78bb, 0x401d,
+ 0x78bc, 0x206b,
+ 0x78bd, 0x401e,
+ 0x78be, 0x0b4e,
+ 0x78bf, 0x401f,
+ 0x78c1, 0x0548,
+ 0x78c2, 0x4021,
+ 0x78c5, 0x0400,
+ 0x78c6, 0x4024,
+ 0x78c9, 0x1a4b,
+ 0x78ca, 0x09c5,
+ 0x78cb, 0x056b,
+ 0x78cc, 0x4027,
+ 0x78d0, 0x0b8e,
+ 0x78d1, 0x402b,
+ 0x78d4, 0x1a49,
+ 0x78d5, 0x0951,
+ 0x78d6, 0x402e,
+ 0x78d9, 0x1a4a,
+ 0x78da, 0x22a7,
+ 0x78db, 0x4031,
+ 0x78e3, 0x24ec,
+ 0x78e4, 0x4039,
+ 0x78e7, 0x24eb,
+ 0x78e8, 0x0b08,
+ 0x78e9, 0x403c,
+ 0x78ec, 0x1a4c,
+ 0x78ed, 0x403f,
+ 0x78ef, 0x24e3,
+ 0x78f0, 0x4041,
+ 0x78f2, 0x1a4d,
+ 0x78f3, 0x4043,
+ 0x78f4, 0x1a4f,
+ 0x78f5, 0x4044,
+ 0x78f7, 0x0a20,
+ 0x78f8, 0x4046,
+ 0x78fa, 0x07dc,
+ 0x78fb, 0x4048,
+ 0x78fd, 0x24ea,
+ 0x78fe, 0x404a,
+ 0x7900, 0x404c,
+ 0x7901, 0x0889,
+ 0x7902, 0x404d,
+ 0x7905, 0x1a4e,
+ 0x7906, 0x4050,
+ 0x790e, 0x1e92,
+ 0x790f, 0x4058,
+ 0x7913, 0x1a50,
+ 0x7914, 0x405c,
+ 0x7919, 0x1e27,
+ 0x791a, 0x4061,
+ 0x791e, 0x1a52,
+ 0x791f, 0x4065,
+ 0x7924, 0x1a51,
+ 0x7925, 0x406a,
+ 0x7926, 0x1fe6,
+ 0x7927, 0x406b,
+ 0x792a, 0x24e7,
+ 0x792b, 0x2012,
+ 0x792c, 0x1eec,
+ 0x792d, 0x406e,
+ 0x7931, 0x24e8,
+ 0x7932, 0x4072,
+ 0x7934, 0x1a53,
+ 0x7935, 0x4074,
+ 0x793a, 0x0d55,
+ 0x793b, 0x19f8,
+ 0x793c, 0x09dc,
+ 0x793d, 0x4079,
+ 0x793e, 0x0d20,
+ 0x793f, 0x407a,
+ 0x7940, 0x19f9,
+ 0x7941, 0x0c0d,
+ 0x7942, 0x407b,
+ 0x7946, 0x19fa,
+ 0x7947, 0x407f,
+ 0x7948, 0x0c0c,
+ 0x7949, 0x19fb,
+ 0x794a, 0x4080,
+ 0x7953, 0x19fe,
+ 0x7954, 0x4089,
+ 0x7956, 0x1243,
+ 0x7957, 0x1a01,
+ 0x7958, 0x408b,
+ 0x795a, 0x19ff,
+ 0x795b, 0x19fc,
+ 0x795d, 0x1200,
+ 0x795e, 0x0d2a,
+ 0x795f, 0x0de3,
+ 0x7960, 0x1a02,
+ 0x7961, 0x408d,
+ 0x7962, 0x1a00,
+ 0x7963, 0x408e,
+ 0x7965, 0x0f56,
+ 0x7966, 0x4090,
+ 0x7967, 0x1a04,
+ 0x7968, 0x0bd0,
+ 0x7969, 0x4091,
+ 0x796d, 0x0833,
+ 0x796e, 0x4095,
+ 0x796f, 0x1a03,
+ 0x7970, 0x4096,
+ 0x7977, 0x059c,
+ 0x7978, 0x080b,
+ 0x7979, 0x409d,
+ 0x797a, 0x1a05,
+ 0x797b, 0x409e,
+ 0x7980, 0x130b,
+ 0x7981, 0x08cc,
+ 0x7982, 0x40a3,
+ 0x7984, 0x0a62,
+ 0x7985, 0x1a06,
+ 0x7986, 0x40a5,
+ 0x798a, 0x1a07,
+ 0x798b, 0x40a9,
+ 0x798d, 0x1f66,
+ 0x798e, 0x24dc,
+ 0x798f, 0x069e,
+ 0x7990, 0x40ab,
+ 0x799a, 0x1a08,
+ 0x799b, 0x40b5,
+ 0x79a6, 0x26a2,
+ 0x79a7, 0x1a09,
+ 0x79a8, 0x40c0,
+ 0x79aa, 0x24dd,
+ 0x79ab, 0x40c2,
+ 0x79ae, 0x200e,
+ 0x79af, 0x40c5,
+ 0x79b0, 0x24db,
+ 0x79b1, 0x1eb8,
+ 0x79b2, 0x40c6,
+ 0x79b3, 0x1a0a,
+ 0x79b4, 0x40c7,
+ 0x79b9, 0x10d2,
+ 0x79ba, 0x1264,
+ 0x79bb, 0x09d6,
+ 0x79bc, 0x40cc,
+ 0x79bd, 0x0c5a,
+ 0x79be, 0x0783,
+ 0x79bf, 0x40cd,
+ 0x79c0, 0x0fae,
+ 0x79c1, 0x0db2,
+ 0x79c2, 0x40ce,
+ 0x79c3, 0x0e6b,
+ 0x79c4, 0x40cf,
+ 0x79c6, 0x06cc,
+ 0x79c7, 0x40d1,
+ 0x79c9, 0x0465,
+ 0x79ca, 0x40d3,
+ 0x79cb, 0x0c6c,
+ 0x79cc, 0x40d4,
+ 0x79cd, 0x11d5,
+ 0x79ce, 0x40d5,
+ 0x79d1, 0x0953,
+ 0x79d2, 0x0af0,
+ 0x79d3, 0x40d8,
+ 0x79d5, 0x1b1d,
+ 0x79d6, 0x40da,
+ 0x79d8, 0x0add,
+ 0x79d9, 0x40dc,
+ 0x79df, 0x123f,
+ 0x79e0, 0x40e2,
+ 0x79e3, 0x1b1f,
+ 0x79e4, 0x04f8,
+ 0x79e5, 0x40e5,
+ 0x79e6, 0x0c55,
+ 0x79e7, 0x1016,
+ 0x79e8, 0x40e6,
+ 0x79e9, 0x11c7,
+ 0x79ea, 0x40e7,
+ 0x79eb, 0x1b20,
+ 0x79ec, 0x40e8,
+ 0x79ed, 0x1b1e,
+ 0x79ee, 0x40e9,
+ 0x79ef, 0x0812,
+ 0x79f0, 0x04eb,
+ 0x79f1, 0x40ea,
+ 0x79f8, 0x08a6,
+ 0x79f9, 0x40f1,
+ 0x79fb, 0x104d,
+ 0x79fc, 0x40f3,
+ 0x79fd, 0x07f5,
+ 0x79fe, 0x40f4,
+ 0x7a00, 0x0f0e,
+ 0x7a01, 0x40f6,
+ 0x7a02, 0x1b24,
+ 0x7a03, 0x1b23,
+ 0x7a04, 0x40f7,
+ 0x7a06, 0x1b21,
+ 0x7a07, 0x40f9,
+ 0x7a0b, 0x04f1,
+ 0x7a0c, 0x40fd,
+ 0x7a0d, 0x0d0d,
+ 0x7a0e, 0x0da5,
+ 0x7a0f, 0x40fe,
+ 0x7a14, 0x1b26,
+ 0x7a15, 0x4103,
+ 0x7a17, 0x03e9,
+ 0x7a18, 0x4105,
+ 0x7a1a, 0x11c8,
+ 0x7a1b, 0x4107,
+ 0x7a1e, 0x1b25,
+ 0x7a1f, 0x410a,
+ 0x7a20, 0x0512,
+ 0x7a21, 0x410b,
+ 0x7a23, 0x1d8f,
+ 0x7a24, 0x410d,
+ 0x7a2e, 0x2295,
+ 0x7a2f, 0x4117,
+ 0x7a31, 0x1e80,
+ 0x7a32, 0x4119,
+ 0x7a33, 0x0ed7,
+ 0x7a34, 0x411a,
+ 0x7a37, 0x1b28,
+ 0x7a38, 0x411d,
+ 0x7a39, 0x1b27,
+ 0x7a3a, 0x411e,
+ 0x7a3b, 0x059f,
+ 0x7a3c, 0x084d,
+ 0x7a3d, 0x0811,
+ 0x7a3e, 0x411f,
+ 0x7a3f, 0x06e0,
+ 0x7a40, 0x2677,
+ 0x7a41, 0x4120,
+ 0x7a46, 0x0b25,
+ 0x7a47, 0x4125,
+ 0x7a4c, 0x2624,
+ 0x7a4d, 0x1f69,
+ 0x7a4e, 0x222b,
+ 0x7a4f, 0x412a,
+ 0x7a51, 0x1b29,
+ 0x7a52, 0x412c,
+ 0x7a57, 0x0de0,
+ 0x7a58, 0x4131,
+ 0x7a61, 0x257f,
+ 0x7a62, 0x1f5b,
+ 0x7a63, 0x413a,
+ 0x7a69, 0x219b,
+ 0x7a6a, 0x4140,
+ 0x7a6b, 0x267d,
+ 0x7a6c, 0x4141,
+ 0x7a70, 0x1b2c,
+ 0x7a71, 0x4145,
+ 0x7a74, 0x0fd1,
+ 0x7a75, 0x4148,
+ 0x7a76, 0x08ee,
+ 0x7a77, 0x0c6b,
+ 0x7a78, 0x1b9a,
+ 0x7a7a, 0x0962,
+ 0x7a7b, 0x4149,
+ 0x7a7f, 0x052c,
+ 0x7a80, 0x1b9c,
+ 0x7a81, 0x0e6c,
+ 0x7a82, 0x414d,
+ 0x7a83, 0x0c51,
+ 0x7a84, 0x114e,
+ 0x7a85, 0x414e,
+ 0x7a86, 0x1b9d,
+ 0x7a87, 0x414f,
+ 0x7a88, 0x1b9e,
+ 0x7a89, 0x4150,
+ 0x7a8d, 0x0c4c,
+ 0x7a8e, 0x4154,
+ 0x7a91, 0x102b,
+ 0x7a92, 0x11ce,
+ 0x7a93, 0x4157,
+ 0x7a95, 0x1b9f,
+ 0x7a96, 0x08a2,
+ 0x7a97, 0x0533,
+ 0x7a98, 0x08ec,
+ 0x7a99, 0x4159,
+ 0x7a9c, 0x055f,
+ 0x7a9d, 0x0ee0,
+ 0x7a9e, 0x415c,
+ 0x7a9f, 0x096c,
+ 0x7aa0, 0x1ba1,
+ 0x7aa1, 0x415d,
+ 0x7aa5, 0x0987,
+ 0x7aa6, 0x1ba0,
+ 0x7aa7, 0x4161,
+ 0x7aa8, 0x1ba3,
+ 0x7aa9, 0x21a0,
+ 0x7aaa, 0x2186,
+ 0x7aab, 0x4162,
+ 0x7aac, 0x1ba2,
+ 0x7aad, 0x1ba4,
+ 0x7aae, 0x20ed,
+ 0x7aaf, 0x4163,
+ 0x7ab3, 0x1ba5,
+ 0x7ab4, 0x4167,
+ 0x7ab6, 0x25b9,
+ 0x7ab7, 0x4169,
+ 0x7aba, 0x1fea,
+ 0x7abb, 0x416c,
+ 0x7abf, 0x0a47,
+ 0x7ac0, 0x4170,
+ 0x7ac4, 0x1ea4,
+ 0x7ac5, 0x20e1,
+ 0x7ac6, 0x4174,
+ 0x7ac7, 0x25b8,
+ 0x7ac8, 0x2260,
+ 0x7ac9, 0x4175,
+ 0x7aca, 0x20e2,
+ 0x7acb, 0x09eb,
+ 0x7acc, 0x4176,
+ 0x7ad6, 0x0d91,
+ 0x7ad7, 0x4180,
+ 0x7ad9, 0x115f,
+ 0x7ada, 0x4182,
+ 0x7ade, 0x08e9,
+ 0x7adf, 0x08e8,
+ 0x7ae0, 0x1163,
+ 0x7ae1, 0x4186,
+ 0x7ae3, 0x092f,
+ 0x7ae4, 0x4188,
+ 0x7ae5, 0x0e60,
+ 0x7ae6, 0x1b99,
+ 0x7ae7, 0x4189,
+ 0x7aea, 0x2141,
+ 0x7aeb, 0x418c,
+ 0x7aed, 0x08b0,
+ 0x7aee, 0x418e,
+ 0x7aef, 0x060a,
+ 0x7af0, 0x418f,
+ 0x7af6, 0x1fc7,
+ 0x7af7, 0x4195,
+ 0x7af9, 0x11f0,
+ 0x7afa, 0x1c63,
+ 0x7afb, 0x4197,
+ 0x7afd, 0x1c64,
+ 0x7afe, 0x4199,
+ 0x7aff, 0x06c8,
+ 0x7b00, 0x419a,
+ 0x7b03, 0x1c66,
+ 0x7b05, 0x419d,
+ 0x7b06, 0x03d5,
+ 0x7b07, 0x419e,
+ 0x7b08, 0x1c65,
+ 0x7b09, 0x419f,
+ 0x7b0a, 0x1c69,
+ 0x7b0b, 0x0de6,
+ 0x7b0c, 0x41a0,
+ 0x7b0f, 0x1c6b,
+ 0x7b10, 0x41a3,
+ 0x7b11, 0x0f71,
+ 0x7b12, 0x41a4,
+ 0x7b14, 0x0433,
+ 0x7b15, 0x1c68,
+ 0x7b16, 0x41a6,
+ 0x7b19, 0x1c6f,
+ 0x7b1a, 0x41a9,
+ 0x7b1b, 0x05b2,
+ 0x7b1c, 0x41aa,
+ 0x7b1e, 0x1c77,
+ 0x7b1f, 0x41ac,
+ 0x7b20, 0x1c72,
+ 0x7b21, 0x41ad,
+ 0x7b24, 0x1c74,
+ 0x7b25, 0x1c73,
+ 0x7b26, 0x0698,
+ 0x7b27, 0x41b0,
+ 0x7b28, 0x0428,
+ 0x7b29, 0x41b1,
+ 0x7b2a, 0x1c6e,
+ 0x7b2b, 0x1c6a,
+ 0x7b2c, 0x05bb,
+ 0x7b2d, 0x41b2,
+ 0x7b2e, 0x1c70,
+ 0x7b2f, 0x41b3,
+ 0x7b31, 0x1c71,
+ 0x7b32, 0x41b5,
+ 0x7b33, 0x1c75,
+ 0x7b34, 0x41b6,
+ 0x7b38, 0x1c6d,
+ 0x7b39, 0x41ba,
+ 0x7b3a, 0x0856,
+ 0x7b3b, 0x41bb,
+ 0x7b3c, 0x0a46,
+ 0x7b3d, 0x41bc,
+ 0x7b3e, 0x1c76,
+ 0x7b3f, 0x41bd,
+ 0x7b45, 0x1c7a,
+ 0x7b46, 0x1e41,
+ 0x7b47, 0x1c6c,
+ 0x7b48, 0x41c3,
+ 0x7b49, 0x05a9,
+ 0x7b4a, 0x41c4,
+ 0x7b4b, 0x08bf,
+ 0x7b4c, 0x1c7c,
+ 0x7b4d, 0x41c5,
+ 0x7b4f, 0x0641,
+ 0x7b50, 0x097d,
+ 0x7b51, 0x11fd,
+ 0x7b52, 0x0e63,
+ 0x7b53, 0x41c7,
+ 0x7b54, 0x0573,
+ 0x7b55, 0x41c8,
+ 0x7b56, 0x04a6,
+ 0x7b57, 0x41c9,
+ 0x7b58, 0x1c78,
+ 0x7b59, 0x41ca,
+ 0x7b5a, 0x1c79,
+ 0x7b5b, 0x0cf1,
+ 0x7b5c, 0x41cb,
+ 0x7b5d, 0x1c7d,
+ 0x7b5e, 0x41cc,
+ 0x7b60, 0x1c7e,
+ 0x7b61, 0x41ce,
+ 0x7b62, 0x1c81,
+ 0x7b63, 0x41cf,
+ 0x7b67, 0x25e4,
+ 0x7b68, 0x41d3,
+ 0x7b6e, 0x1c7f,
+ 0x7b6f, 0x41d9,
+ 0x7b71, 0x1c83,
+ 0x7b72, 0x1c82,
+ 0x7b73, 0x41db,
+ 0x7b75, 0x1c7b,
+ 0x7b76, 0x41dd,
+ 0x7b77, 0x0977,
+ 0x7b78, 0x41de,
+ 0x7b79, 0x0514,
+ 0x7b7a, 0x41df,
+ 0x7b7b, 0x1c80,
+ 0x7b7c, 0x41e0,
+ 0x7b7e, 0x0c26,
+ 0x7b7f, 0x41e2,
+ 0x7b80, 0x0865,
+ 0x7b81, 0x41e3,
+ 0x7b85, 0x1c8b,
+ 0x7b86, 0x41e7,
+ 0x7b8b, 0x1f86,
+ 0x7b8c, 0x41ec,
+ 0x7b8d, 0x0718,
+ 0x7b8e, 0x41ed,
+ 0x7b90, 0x1c84,
+ 0x7b91, 0x41ef,
+ 0x7b94, 0x0474,
+ 0x7b95, 0x0813,
+ 0x7b96, 0x41f2,
+ 0x7b97, 0x0dd8,
+ 0x7b98, 0x41f3,
+ 0x7b9c, 0x1c8d,
+ 0x7b9d, 0x1c89,
+ 0x7b9e, 0x41f7,
+ 0x7ba1, 0x0735,
+ 0x7ba2, 0x1c8e,
+ 0x7ba3, 0x41fa,
+ 0x7ba6, 0x1c85,
+ 0x7ba8, 0x1c8a,
+ 0x7ba9, 0x0a88,
+ 0x7baa, 0x1c8c,
+ 0x7bab, 0x1c8f,
+ 0x7bac, 0x1c88,
+ 0x7bad, 0x0870,
+ 0x7bae, 0x41fd,
+ 0x7bb1, 0x0f51,
+ 0x7bb2, 0x4200,
+ 0x7bb4, 0x1c90,
+ 0x7bb5, 0x4202,
+ 0x7bb8, 0x1c87,
+ 0x7bb9, 0x4205,
+ 0x7bc0, 0x1fb3,
+ 0x7bc1, 0x1c92,
+ 0x7bc2, 0x420c,
+ 0x7bc4, 0x1eef,
+ 0x7bc5, 0x420e,
+ 0x7bc6, 0x120a,
+ 0x7bc7, 0x0bc9,
+ 0x7bc8, 0x420f,
+ 0x7bc9, 0x22a4,
+ 0x7bca, 0x4210,
+ 0x7bcb, 0x25e8,
+ 0x7bcc, 0x1c93,
+ 0x7bcd, 0x4211,
+ 0x7bd1, 0x1c91,
+ 0x7bd2, 0x4215,
+ 0x7bd3, 0x0a4f,
+ 0x7bd4, 0x4216,
+ 0x7bd9, 0x06d8,
+ 0x7bda, 0x1c95,
+ 0x7bdb, 0x421b,
+ 0x7bdd, 0x1c94,
+ 0x7bde, 0x421d,
+ 0x7be1, 0x055e,
+ 0x7be2, 0x4220,
+ 0x7be4, 0x25e3,
+ 0x7be5, 0x1c96,
+ 0x7be7, 0x4222,
+ 0x7be9, 0x2111,
+ 0x7bea, 0x1c98,
+ 0x7beb, 0x4224,
+ 0x7bee, 0x09a5,
+ 0x7bef, 0x4227,
+ 0x7bf1, 0x09d4,
+ 0x7bf2, 0x4229,
+ 0x7bf3, 0x25e6,
+ 0x7bf4, 0x422a,
+ 0x7bf7, 0x0bb2,
+ 0x7bf8, 0x422d,
+ 0x7bfc, 0x1c9b,
+ 0x7bfd, 0x4231,
+ 0x7bfe, 0x1c9a,
+ 0x7bff, 0x4232,
+ 0x7c00, 0x25e7,
+ 0x7c01, 0x4233,
+ 0x7c07, 0x055b,
+ 0x7c08, 0x4239,
+ 0x7c0b, 0x1c9e,
+ 0x7c0c, 0x1c99,
+ 0x7c0d, 0x2041,
+ 0x7c0e, 0x423c,
+ 0x7c0f, 0x1c9c,
+ 0x7c10, 0x423d,
+ 0x7c16, 0x1c9d,
+ 0x7c17, 0x4243,
+ 0x7c1e, 0x25ea,
+ 0x7c1f, 0x1c9f,
+ 0x7c20, 0x424a,
+ 0x7c21, 0x1f8f,
+ 0x7c22, 0x424b,
+ 0x7c23, 0x25ec,
+ 0x7c24, 0x424c,
+ 0x7c26, 0x1ca1,
+ 0x7c27, 0x07de,
+ 0x7c28, 0x424e,
+ 0x7c2a, 0x1ca0,
+ 0x7c2b, 0x25eb,
+ 0x7c2c, 0x4250,
+ 0x7c38, 0x1ca2,
+ 0x7c39, 0x425c,
+ 0x7c3d, 0x20d0,
+ 0x7c3e, 0x201d,
+ 0x7c3f, 0x0485,
+ 0x7c40, 0x1ca4,
+ 0x7c41, 0x1ca3,
+ 0x7c42, 0x4260,
+ 0x7c43, 0x1ff7,
+ 0x7c44, 0x4261,
+ 0x7c4c, 0x1e8d,
+ 0x7c4d, 0x0821,
+ 0x7c4e, 0x4269,
+ 0x7c5c, 0x25e9,
+ 0x7c5d, 0x4277,
+ 0x7c5f, 0x25ee,
+ 0x7c60, 0x203a,
+ 0x7c61, 0x4279,
+ 0x7c64, 0x2693,
+ 0x7c65, 0x427c,
+ 0x7c69, 0x25e5,
+ 0x7c6a, 0x25ed,
+ 0x7c6b, 0x4280,
+ 0x7c6c, 0x2009,
+ 0x7c6d, 0x4281,
+ 0x7c6e, 0x2065,
+ 0x7c6f, 0x4282,
+ 0x7c72, 0x26a3,
+ 0x7c73, 0x0adc,
+ 0x7c74, 0x12f5,
+ 0x7c75, 0x4285,
+ 0x7c7b, 0x09cb,
+ 0x7c7c, 0x1cca,
+ 0x7c7d, 0x122e,
+ 0x7c7e, 0x428b,
+ 0x7c89, 0x0678,
+ 0x7c8a, 0x4296,
+ 0x7c91, 0x1ccc,
+ 0x7c92, 0x09ec,
+ 0x7c93, 0x429d,
+ 0x7c95, 0x0be8,
+ 0x7c96, 0x429f,
+ 0x7c97, 0x0559,
+ 0x7c98, 0x1154,
+ 0x7c99, 0x42a0,
+ 0x7c9c, 0x1cce,
+ 0x7c9d, 0x1ccd,
+ 0x7c9e, 0x1ccf,
+ 0x7c9f, 0x0dcf,
+ 0x7ca0, 0x42a3,
+ 0x7ca2, 0x1cd0,
+ 0x7ca3, 0x42a5,
+ 0x7ca4, 0x1104,
+ 0x7ca5, 0x11df,
+ 0x7ca6, 0x42a6,
+ 0x7caa, 0x067d,
+ 0x7cab, 0x42aa,
+ 0x7cae, 0x0a01,
+ 0x7caf, 0x42ad,
+ 0x7cb1, 0x0a04,
+ 0x7cb2, 0x1cd1,
+ 0x7cb3, 0x08db,
+ 0x7cb4, 0x42af,
+ 0x7cb9, 0x0565,
+ 0x7cba, 0x42b4,
+ 0x7cbc, 0x1cd2,
+ 0x7cbe, 0x08da,
+ 0x7cbf, 0x42b6,
+ 0x7cc1, 0x1cd4,
+ 0x7cc2, 0x42b8,
+ 0x7cc5, 0x1cd9,
+ 0x7cc6, 0x42bb,
+ 0x7cc7, 0x1cd5,
+ 0x7cc8, 0x1cd8,
+ 0x7cc9, 0x42bc,
+ 0x7cca, 0x07b4,
+ 0x7ccb, 0x42bd,
+ 0x7ccc, 0x1cd6,
+ 0x7cce, 0x42be,
+ 0x7cd5, 0x06dd,
+ 0x7cd6, 0x0e1a,
+ 0x7cd7, 0x1cda,
+ 0x7cd8, 0x42c5,
+ 0x7cd9, 0x04a1,
+ 0x7cda, 0x42c6,
+ 0x7cdc, 0x0ad8,
+ 0x7cdd, 0x25f5,
+ 0x7cde, 0x1efc,
+ 0x7cdf, 0x1126,
+ 0x7ce0, 0x0944,
+ 0x7ce1, 0x42c8,
+ 0x7ce7, 0x2024,
+ 0x7ce8, 0x1cdb,
+ 0x7ce9, 0x42ce,
+ 0x7cef, 0x0b75,
+ 0x7cf0, 0x269b,
+ 0x7cf1, 0x42d4,
+ 0x7cf2, 0x25f3,
+ 0x7cf3, 0x42d5,
+ 0x7cf4, 0x22d9,
+ 0x7cf5, 0x42d6,
+ 0x7cf6, 0x25f4,
+ 0x7cf7, 0x42d7,
+ 0x7cf8, 0x1ce7,
+ 0x7cf9, 0x241b,
+ 0x7cfa, 0x42d8,
+ 0x7cfb, 0x0f22,
+ 0x7cfc, 0x42d9,
+ 0x7cfe, 0x1fc8,
+ 0x7cff, 0x42db,
+ 0x7d00, 0x1f7b,
+ 0x7d01, 0x42dc,
+ 0x7d02, 0x241d,
+ 0x7d03, 0x42dd,
+ 0x7d04, 0x224c,
+ 0x7d05, 0x1f48,
+ 0x7d06, 0x241c,
+ 0x7d07, 0x241e,
+ 0x7d09, 0x20ff,
+ 0x7d0a, 0x0ed8,
+ 0x7d0b, 0x219a,
+ 0x7d0c, 0x42de,
+ 0x7d0d, 0x2091,
+ 0x7d0e, 0x42df,
+ 0x7d10, 0x20a7,
+ 0x7d11, 0x42e1,
+ 0x7d13, 0x2423,
+ 0x7d14, 0x1e9b,
+ 0x7d15, 0x2422,
+ 0x7d16, 0x42e3,
+ 0x7d17, 0x2110,
+ 0x7d18, 0x42e4,
+ 0x7d19, 0x228d,
+ 0x7d1a, 0x1f71,
+ 0x7d1b, 0x1ef8,
+ 0x7d1c, 0x2421,
+ 0x7d1d, 0x42e5,
+ 0x7d20, 0x0dcd,
+ 0x7d21, 0x1ef3,
+ 0x7d22, 0x0dec,
+ 0x7d23, 0x42e8,
+ 0x7d27, 0x08c5,
+ 0x7d28, 0x42ec,
+ 0x7d2b, 0x122c,
+ 0x7d2c, 0x42ef,
+ 0x7d2f, 0x09c6,
+ 0x7d30, 0x21b1,
+ 0x7d31, 0x2426,
+ 0x7d32, 0x2425,
+ 0x7d33, 0x2120,
+ 0x7d34, 0x42f2,
+ 0x7d39, 0x211a,
+ 0x7d3a, 0x2424,
+ 0x7d3b, 0x42f7,
+ 0x7d3c, 0x2428,
+ 0x7d3d, 0x42f8,
+ 0x7d3f, 0x242a,
+ 0x7d40, 0x2429,
+ 0x7d41, 0x42fa,
+ 0x7d42, 0x2294,
+ 0x7d43, 0x42fb,
+ 0x7d44, 0x22be,
+ 0x7d45, 0x42fc,
+ 0x7d46, 0x1e31,
+ 0x7d47, 0x42fd,
+ 0x7d4e, 0x242c,
+ 0x7d4f, 0x4304,
+ 0x7d50, 0x1fb5,
+ 0x7d51, 0x4305,
+ 0x7d5d, 0x242b,
+ 0x7d5e, 0x1faf,
+ 0x7d5f, 0x4311,
+ 0x7d61, 0x2068,
+ 0x7d62, 0x21e4,
+ 0x7d63, 0x4313,
+ 0x7d66, 0x1f21,
+ 0x7d67, 0x4316,
+ 0x7d68, 0x2101,
+ 0x7d69, 0x4317,
+ 0x7d6e, 0x0fc0,
+ 0x7d6f, 0x431c,
+ 0x7d71, 0x217c,
+ 0x7d72, 0x214a,
+ 0x7d73, 0x242d,
+ 0x7d74, 0x431e,
+ 0x7d76, 0x1fd4,
+ 0x7d77, 0x1ce8,
+ 0x7d78, 0x4320,
+ 0x7d79, 0x1fd1,
+ 0x7d7a, 0x4321,
+ 0x7d81, 0x1e33,
+ 0x7d82, 0x4328,
+ 0x7d83, 0x242f,
+ 0x7d84, 0x4329,
+ 0x7d86, 0x242e,
+ 0x7d87, 0x432b,
+ 0x7d88, 0x2430,
+ 0x7d89, 0x21db,
+ 0x7d8a, 0x432c,
+ 0x7d8f, 0x2158,
+ 0x7d90, 0x4331,
+ 0x7d93, 0x1fc2,
+ 0x7d94, 0x4334,
+ 0x7d9c, 0x22b9,
+ 0x7d9d, 0x433c,
+ 0x7d9e, 0x2436,
+ 0x7d9f, 0x433d,
+ 0x7da2, 0x1e8e,
+ 0x7da3, 0x2439,
+ 0x7da4, 0x4340,
+ 0x7da6, 0x1ce9,
+ 0x7da7, 0x4342,
+ 0x7dab, 0x21c5,
+ 0x7dac, 0x2437,
+ 0x7dad, 0x2192,
+ 0x7dae, 0x1cea,
+ 0x7daf, 0x4346,
+ 0x7db0, 0x243a,
+ 0x7db1, 0x1f19,
+ 0x7db2, 0x218c,
+ 0x7db3, 0x1e40,
+ 0x7db4, 0x22b3,
+ 0x7db5, 0x4347,
+ 0x7db8, 0x205f,
+ 0x7db9, 0x2438,
+ 0x7dba, 0x2432,
+ 0x7dbb, 0x2274,
+ 0x7dbc, 0x434a,
+ 0x7dbd, 0x1e9c,
+ 0x7dbe, 0x2431,
+ 0x7dbf, 0x2085,
+ 0x7dc0, 0x434b,
+ 0x7dc4, 0x2435,
+ 0x7dc5, 0x434f,
+ 0x7dc7, 0x243b,
+ 0x7dc8, 0x4351,
+ 0x7dca, 0x1fb7,
+ 0x7dcb, 0x2433,
+ 0x7dcc, 0x4353,
+ 0x7dd1, 0x2054,
+ 0x7dd2, 0x21de,
+ 0x7dd3, 0x4358,
+ 0x7dd4, 0x2434,
+ 0x7dd5, 0x4359,
+ 0x7dd7, 0x243d,
+ 0x7dd8, 0x1f89,
+ 0x7dd9, 0x243c,
+ 0x7dda, 0x435b,
+ 0x7ddd, 0x1f6e,
+ 0x7dde, 0x1ed8,
+ 0x7ddf, 0x435e,
+ 0x7de0, 0x1ebf,
+ 0x7de1, 0x2445,
+ 0x7de2, 0x435f,
+ 0x7de3, 0x2249,
+ 0x7de4, 0x4360,
+ 0x7de6, 0x2441,
+ 0x7de7, 0x4362,
+ 0x7de8, 0x1e47,
+ 0x7de9, 0x1f56,
+ 0x7dea, 0x4363,
+ 0x7dec, 0x2086,
+ 0x7ded, 0x4365,
+ 0x7def, 0x2196,
+ 0x7df0, 0x4367,
+ 0x7df1, 0x2443,
+ 0x7df2, 0x243f,
+ 0x7df3, 0x4368,
+ 0x7df4, 0x2023,
+ 0x7df5, 0x4369,
+ 0x7df6, 0x2442,
+ 0x7df7, 0x436a,
+ 0x7df9, 0x243e,
+ 0x7dfa, 0x436c,
+ 0x7dfb, 0x26a6,
+ 0x7dfc, 0x436d,
+ 0x7e00, 0x4371,
+ 0x7e08, 0x234e,
+ 0x7e09, 0x2446,
+ 0x7e0a, 0x244b,
+ 0x7e0b, 0x2444,
+ 0x7e0c, 0x4379,
+ 0x7e10, 0x2427,
+ 0x7e11, 0x244c,
+ 0x7e12, 0x437d,
+ 0x7e1b, 0x1f0f,
+ 0x7e1c, 0x4386,
+ 0x7e1d, 0x2447,
+ 0x7e1e, 0x2449,
+ 0x7e1f, 0x2448,
+ 0x7e20, 0x4387,
+ 0x7e23, 0x21c2,
+ 0x7e24, 0x438a,
+ 0x7e27, 0x216e,
+ 0x7e28, 0x438d,
+ 0x7e2b, 0x1f03,
+ 0x7e2c, 0x4390,
+ 0x7e2d, 0x244a,
+ 0x7e2e, 0x215c,
+ 0x7e2f, 0x4391,
+ 0x7e31, 0x22bb,
+ 0x7e32, 0x2450,
+ 0x7e33, 0x4393,
+ 0x7e34, 0x2694,
+ 0x7e35, 0x244f,
+ 0x7e36, 0x25f6,
+ 0x7e37, 0x2051,
+ 0x7e38, 0x4394,
+ 0x7e39, 0x244e,
+ 0x7e3a, 0x4395,
+ 0x7e3b, 0x1dfb,
+ 0x7e3c, 0x4396,
+ 0x7e3d, 0x22ba,
+ 0x7e3e, 0x1f6d,
+ 0x7e3f, 0x4397,
+ 0x7e41, 0x064e,
+ 0x7e42, 0x4399,
+ 0x7e45, 0x2452,
+ 0x7e46, 0x2451,
+ 0x7e47, 0x1ceb,
+ 0x7e48, 0x439c,
+ 0x7e52, 0x2455,
+ 0x7e53, 0x43a6,
+ 0x7e54, 0x2289,
+ 0x7e55, 0x2116,
+ 0x7e56, 0x43a7,
+ 0x7e5a, 0x2454,
+ 0x7e5b, 0x43ab,
+ 0x7e5e, 0x20fb,
+ 0x7e5f, 0x43ae,
+ 0x7e62, 0x2440,
+ 0x7e63, 0x43b1,
+ 0x7e69, 0x2126,
+ 0x7e6a, 0x1f61,
+ 0x7e6b, 0x269d,
+ 0x7e6c, 0x43b7,
+ 0x7e6d, 0x1f8a,
+ 0x7e6e, 0x2456,
+ 0x7e6f, 0x2459,
+ 0x7e70, 0x2458,
+ 0x7e71, 0x43b8,
+ 0x7e73, 0x1fae,
+ 0x7e74, 0x43ba,
+ 0x7e79, 0x221a,
+ 0x7e7a, 0x43bf,
+ 0x7e7c, 0x1f7a,
+ 0x7e7d, 0x244d,
+ 0x7e7e, 0x2457,
+ 0x7e7f, 0x43c1,
+ 0x7e82, 0x1248,
+ 0x7e83, 0x43c4,
+ 0x7e88, 0x2453,
+ 0x7e89, 0x43c9,
+ 0x7e8a, 0x2420,
+ 0x7e8b, 0x43ca,
+ 0x7e8c, 0x21df,
+ 0x7e8d, 0x2685,
+ 0x7e8e, 0x43cb,
+ 0x7e8f, 0x1e6e,
+ 0x7e90, 0x43cc,
+ 0x7e93, 0x2224,
+ 0x7e94, 0x2670,
+ 0x7e95, 0x43cf,
+ 0x7e96, 0x21ba,
+ 0x7e97, 0x43d0,
+ 0x7e98, 0x245a,
+ 0x7e99, 0x43d1,
+ 0x7e9b, 0x1cec,
+ 0x7e9c, 0x1fff,
+ 0x7e9d, 0x43d3,
+ 0x7e9f, 0x17d3,
+ 0x7ea0, 0x08ef,
+ 0x7ea1, 0x17d4,
+ 0x7ea2, 0x07a3,
+ 0x7ea3, 0x17d5,
+ 0x7ea4, 0x0f38,
+ 0x7ea5, 0x17d6,
+ 0x7ea6, 0x10ff,
+ 0x7ea7, 0x0829,
+ 0x7ea8, 0x17d7,
+ 0x7eaa, 0x0840,
+ 0x7eab, 0x0cad,
+ 0x7eac, 0x0ec2,
+ 0x7ead, 0x17d9,
+ 0x7eae, 0x43d5,
+ 0x7eaf, 0x0542,
+ 0x7eb0, 0x17da,
+ 0x7eb1, 0x0ced,
+ 0x7eb2, 0x06d4,
+ 0x7eb3, 0x0b2c,
+ 0x7eb4, 0x43d6,
+ 0x7eb5, 0x123a,
+ 0x7eb6, 0x0a81,
+ 0x7eb7, 0x0674,
+ 0x7eb8, 0x11bc,
+ 0x7eb9, 0x0ed5,
+ 0x7eba, 0x0661,
+ 0x7ebb, 0x43d7,
+ 0x7ebd, 0x0b67,
+ 0x7ebe, 0x17db,
+ 0x7ebf, 0x0f4c,
+ 0x7ec0, 0x17dc,
+ 0x7ec3, 0x0a00,
+ 0x7ec4, 0x1246,
+ 0x7ec5, 0x0d29,
+ 0x7ec6, 0x0f25,
+ 0x7ec7, 0x11ae,
+ 0x7ec8, 0x11d4,
+ 0x7ec9, 0x17df,
+ 0x7eca, 0x03f8,
+ 0x7ecb, 0x17e0,
+ 0x7ecd, 0x0d15,
+ 0x7ece, 0x1076,
+ 0x7ecf, 0x08dc,
+ 0x7ed0, 0x17e2,
+ 0x7ed1, 0x03fe,
+ 0x7ed2, 0x0cb9,
+ 0x7ed3, 0x08b2,
+ 0x7ed4, 0x17e3,
+ 0x7ed5, 0x0ca1,
+ 0x7ed6, 0x43d9,
+ 0x7ed7, 0x17e4,
+ 0x7ed8, 0x07fb,
+ 0x7ed9, 0x06f3,
+ 0x7eda, 0x0fcd,
+ 0x7edb, 0x17e5,
+ 0x7edc, 0x0a8e,
+ 0x7edd, 0x0927,
+ 0x7ede, 0x089b,
+ 0x7edf, 0x0e64,
+ 0x7ee0, 0x17e6,
+ 0x7ee2, 0x091d,
+ 0x7ee3, 0x0fb0,
+ 0x7ee4, 0x43da,
+ 0x7ee5, 0x0ddc,
+ 0x7ee6, 0x0e23,
+ 0x7ee7, 0x083f,
+ 0x7ee8, 0x17e8,
+ 0x7ee9, 0x081b,
+ 0x7eea, 0x0fc2,
+ 0x7eeb, 0x17e9,
+ 0x7eec, 0x43db,
+ 0x7eed, 0x0fc3,
+ 0x7eee, 0x17ea,
+ 0x7ef0, 0x0545,
+ 0x7ef1, 0x17ec,
+ 0x7ef3, 0x0d37,
+ 0x7ef4, 0x0ebb,
+ 0x7ef5, 0x0ae5,
+ 0x7ef6, 0x17ef,
+ 0x7ef7, 0x042a,
+ 0x7ef8, 0x0516,
+ 0x7ef9, 0x43dc,
+ 0x7efa, 0x17f0,
+ 0x7efc, 0x1238,
+ 0x7efd, 0x1161,
+ 0x7efe, 0x17f2,
+ 0x7eff, 0x0a73,
+ 0x7f00, 0x1217,
+ 0x7f01, 0x17f3,
+ 0x7f04, 0x085d,
+ 0x7f05, 0x0aea,
+ 0x7f06, 0x09ad,
+ 0x7f07, 0x17f6,
+ 0x7f09, 0x081c,
+ 0x7f0a, 0x43dd,
+ 0x7f0b, 0x17f8,
+ 0x7f0d, 0x17ee,
+ 0x7f0e, 0x060f,
+ 0x7f0f, 0x17fa,
+ 0x7f10, 0x43de,
+ 0x7f11, 0x17fb,
+ 0x7f13, 0x07cf,
+ 0x7f14, 0x05bf,
+ 0x7f15, 0x0a6d,
+ 0x7f16, 0x0449,
+ 0x7f17, 0x17fd,
+ 0x7f18, 0x10f8,
+ 0x7f19, 0x17fe,
+ 0x7f1a, 0x06ba,
+ 0x7f1b, 0x1800,
+ 0x7f1c, 0x17ff,
+ 0x7f1d, 0x0689,
+ 0x7f1e, 0x43df,
+ 0x7f1f, 0x1801,
+ 0x7f20, 0x04bf,
+ 0x7f21, 0x1802,
+ 0x7f28, 0x108c,
+ 0x7f29, 0x0dea,
+ 0x7f2a, 0x1809,
+ 0x7f2e, 0x0d02,
+ 0x7f2f, 0x180d,
+ 0x7f34, 0x089a,
+ 0x7f35, 0x1812,
+ 0x7f36, 0x1c5e,
+ 0x7f37, 0x43e0,
+ 0x7f38, 0x06d2,
+ 0x7f39, 0x43e1,
+ 0x7f3a, 0x0c8c,
+ 0x7f3b, 0x43e2,
+ 0x7f42, 0x1c5f,
+ 0x7f43, 0x43e9,
+ 0x7f44, 0x1c60,
+ 0x7f46, 0x43ea,
+ 0x7f4c, 0x25e2,
+ 0x7f4d, 0x43f0,
+ 0x7f4e, 0x269a,
+ 0x7f4f, 0x43f1,
+ 0x7f50, 0x0737,
+ 0x7f51, 0x0ea9,
+ 0x7f52, 0x43f2,
+ 0x7f54, 0x129e,
+ 0x7f55, 0x0768,
+ 0x7f56, 0x43f4,
+ 0x7f57, 0x0a85,
+ 0x7f58, 0x1a81,
+ 0x7f59, 0x43f5,
+ 0x7f5a, 0x0640,
+ 0x7f5b, 0x43f6,
+ 0x7f5f, 0x1a83,
+ 0x7f60, 0x43fa,
+ 0x7f61, 0x1a82,
+ 0x7f62, 0x03e0,
+ 0x7f63, 0x43fb,
+ 0x7f68, 0x1a85,
+ 0x7f69, 0x1177,
+ 0x7f6a, 0x124c,
+ 0x7f6b, 0x4400,
+ 0x7f6e, 0x11c2,
+ 0x7f6f, 0x4403,
+ 0x7f70, 0x1eea,
+ 0x7f71, 0x1a87,
+ 0x7f72, 0x0d87,
+ 0x7f73, 0x4404,
+ 0x7f74, 0x1a86,
+ 0x7f75, 0x4405,
+ 0x7f77, 0x1e2c,
+ 0x7f78, 0x4407,
+ 0x7f79, 0x1a88,
+ 0x7f7a, 0x4408,
+ 0x7f7e, 0x1a8a,
+ 0x7f7f, 0x440c,
+ 0x7f81, 0x1a89,
+ 0x7f82, 0x440e,
+ 0x7f85, 0x2062,
+ 0x7f86, 0x24f1,
+ 0x7f87, 0x4411,
+ 0x7f88, 0x24f2,
+ 0x7f89, 0x4412,
+ 0x7f8a, 0x101b,
+ 0x7f8b, 0x4413,
+ 0x7f8c, 0x0c39,
+ 0x7f8d, 0x4414,
+ 0x7f8e, 0x0ac5,
+ 0x7f8f, 0x4415,
+ 0x7f94, 0x06dc,
+ 0x7f95, 0x441a,
+ 0x7f9a, 0x0a30,
+ 0x7f9b, 0x441f,
+ 0x7f9d, 0x1cc4,
+ 0x7f9e, 0x0faa,
+ 0x7f9f, 0x1cc5,
+ 0x7fa0, 0x4421,
+ 0x7fa1, 0x0f48,
+ 0x7fa2, 0x4422,
+ 0x7fa4, 0x0c95,
+ 0x7fa5, 0x25f2,
+ 0x7fa6, 0x4424,
+ 0x7fa7, 0x1cc6,
+ 0x7fa8, 0x4425,
+ 0x7fa9, 0x2215,
+ 0x7faa, 0x4426,
+ 0x7faf, 0x1cc7,
+ 0x7fb1, 0x442b,
+ 0x7fb2, 0x1cc9,
+ 0x7fb3, 0x442c,
+ 0x7fb8, 0x130e,
+ 0x7fb9, 0x06f9,
+ 0x7fba, 0x4431,
+ 0x7fbc, 0x176d,
+ 0x7fbd, 0x10d5,
+ 0x7fbe, 0x4433,
+ 0x7fbf, 0x1cde,
+ 0x7fc0, 0x4434,
+ 0x7fc1, 0x0edb,
+ 0x7fc2, 0x4435,
+ 0x7fc5, 0x0506,
+ 0x7fc6, 0x4438,
+ 0x7fca, 0x1b98,
+ 0x7fcb, 0x443c,
+ 0x7fcc, 0x1075,
+ 0x7fcd, 0x443d,
+ 0x7fce, 0x1cdf,
+ 0x7fcf, 0x443e,
+ 0x7fd2, 0x21ae,
+ 0x7fd3, 0x4441,
+ 0x7fd4, 0x0f55,
+ 0x7fd5, 0x1ce0,
+ 0x7fd6, 0x4442,
+ 0x7fd8, 0x0c49,
+ 0x7fd9, 0x4444,
+ 0x7fdf, 0x05b5,
+ 0x7fe0, 0x0567,
+ 0x7fe1, 0x1ce2,
+ 0x7fe2, 0x444a,
+ 0x7fe5, 0x1ce1,
+ 0x7fe6, 0x1ce3,
+ 0x7fe7, 0x444d,
+ 0x7fe9, 0x1ce4,
+ 0x7fea, 0x444f,
+ 0x7fee, 0x1ce5,
+ 0x7fef, 0x4453,
+ 0x7ff0, 0x0769,
+ 0x7ff1, 0x03ca,
+ 0x7ff2, 0x4454,
+ 0x7ff3, 0x1ce6,
+ 0x7ff4, 0x4455,
+ 0x7ff9, 0x20e0,
+ 0x7ffa, 0x445a,
+ 0x7ffb, 0x064a,
+ 0x7ffc, 0x1074,
+ 0x7ffd, 0x445b,
+ 0x8000, 0x1032,
+ 0x8001, 0x09ba,
+ 0x8002, 0x445e,
+ 0x8003, 0x0949,
+ 0x8004, 0x1953,
+ 0x8005, 0x1180,
+ 0x8006, 0x191a,
+ 0x8007, 0x445f,
+ 0x800b, 0x1bd7,
+ 0x800c, 0x0637,
+ 0x800d, 0x0d98,
+ 0x800e, 0x4463,
+ 0x8010, 0x0b30,
+ 0x8011, 0x4465,
+ 0x8012, 0x1bcb,
+ 0x8013, 0x4466,
+ 0x8014, 0x1bcc,
+ 0x8015, 0x06f6,
+ 0x8016, 0x1bcd,
+ 0x8017, 0x077b,
+ 0x8018, 0x1108,
+ 0x8019, 0x03dd,
+ 0x801a, 0x4467,
+ 0x801c, 0x1bce,
+ 0x801d, 0x4469,
+ 0x8020, 0x1bcf,
+ 0x8021, 0x446c,
+ 0x8022, 0x1bd0,
+ 0x8023, 0x446d,
+ 0x8025, 0x1bd1,
+ 0x8028, 0x1bd5,
+ 0x8029, 0x1bd4,
+ 0x802a, 0x0b96,
+ 0x802b, 0x446f,
+ 0x802c, 0x25c2,
+ 0x802d, 0x4470,
+ 0x802e, 0x25c1,
+ 0x802f, 0x4471,
+ 0x8031, 0x1bd6,
+ 0x8032, 0x4473,
+ 0x8033, 0x0639,
+ 0x8034, 0x4474,
+ 0x8035, 0x1bd8,
+ 0x8036, 0x1035,
+ 0x8037, 0x14b1,
+ 0x8038, 0x0dbf,
+ 0x8039, 0x4475,
+ 0x803b, 0x0501,
+ 0x803c, 0x4477,
+ 0x803d, 0x0583,
+ 0x803e, 0x4478,
+ 0x803f, 0x06fb,
+ 0x8040, 0x4479,
+ 0x8042, 0x0b57,
+ 0x8043, 0x1bd9,
+ 0x8044, 0x447b,
+ 0x8046, 0x1bda,
+ 0x8047, 0x447d,
+ 0x804a, 0x0a0d,
+ 0x804b, 0x0a44,
+ 0x804c, 0x11af,
+ 0x804d, 0x1bdb,
+ 0x804e, 0x4480,
+ 0x8052, 0x1bdc,
+ 0x8053, 0x4484,
+ 0x8054, 0x09f3,
+ 0x8055, 0x4485,
+ 0x8056, 0x2128,
+ 0x8057, 0x4486,
+ 0x8058, 0x0bd7,
+ 0x8059, 0x4487,
+ 0x805a, 0x090a,
+ 0x805b, 0x4488,
+ 0x805e, 0x2199,
+ 0x805f, 0x448b,
+ 0x8069, 0x1bdd,
+ 0x806a, 0x0552,
+ 0x806b, 0x4495,
+ 0x806f, 0x2017,
+ 0x8070, 0x1ea0,
+ 0x8071, 0x1bde,
+ 0x8072, 0x2125,
+ 0x8073, 0x214d,
+ 0x8074, 0x4499,
+ 0x8075, 0x25c4,
+ 0x8076, 0x209d,
+ 0x8077, 0x228a,
+ 0x8078, 0x449a,
+ 0x8079, 0x25c3,
+ 0x807a, 0x449b,
+ 0x807d, 0x2179,
+ 0x807e, 0x2038,
+ 0x807f, 0x1a1e,
+ 0x8080, 0x1a1d,
+ 0x8081, 0x449e,
+ 0x8083, 0x0dd5,
+ 0x8084, 0x1065,
+ 0x8085, 0x2155,
+ 0x8086, 0x0db6,
+ 0x8087, 0x1179,
+ 0x8088, 0x44a0,
+ 0x8089, 0x0cbd,
+ 0x808a, 0x44a1,
+ 0x808b, 0x09ca,
+ 0x808c, 0x0814,
+ 0x808d, 0x44a2,
+ 0x8093, 0x1971,
+ 0x8094, 0x44a8,
+ 0x8096, 0x0f6f,
+ 0x8097, 0x44aa,
+ 0x8098, 0x11e1,
+ 0x8099, 0x44ab,
+ 0x809a, 0x0606,
+ 0x809b, 0x06d3,
+ 0x809c, 0x1970,
+ 0x809d, 0x06c9,
+ 0x809e, 0x44ac,
+ 0x809f, 0x196f,
+ 0x80a0, 0x04cb,
+ 0x80a1, 0x0722,
+ 0x80a2, 0x11aa,
+ 0x80a3, 0x44ad,
+ 0x80a4, 0x0691,
+ 0x80a5, 0x0667,
+ 0x80a6, 0x44ae,
+ 0x80a9, 0x085a,
+ 0x80aa, 0x065b,
+ 0x80ab, 0x1976,
+ 0x80ac, 0x44b1,
+ 0x80ad, 0x1977,
+ 0x80ae, 0x03c4,
+ 0x80af, 0x095c,
+ 0x80b0, 0x44b2,
+ 0x80b1, 0x1975,
+ 0x80b2, 0x10e2,
+ 0x80b3, 0x44b3,
+ 0x80b4, 0x1978,
+ 0x80b5, 0x44b4,
+ 0x80b7, 0x1979,
+ 0x80b8, 0x44b6,
+ 0x80ba, 0x066b,
+ 0x80bb, 0x44b8,
+ 0x80bc, 0x1972,
+ 0x80bd, 0x1974,
+ 0x80be, 0x0d2f,
+ 0x80bf, 0x11d6,
+ 0x80c0, 0x116e,
+ 0x80c1, 0x0f7d,
+ 0x80c2, 0x197f,
+ 0x80c3, 0x0ec7,
+ 0x80c4, 0x1980,
+ 0x80c5, 0x44b9,
+ 0x80c6, 0x0589,
+ 0x80c7, 0x44ba,
+ 0x80cc, 0x041c,
+ 0x80cd, 0x1982,
+ 0x80ce, 0x0df8,
+ 0x80cf, 0x44bf,
+ 0x80d6, 0x0b97,
+ 0x80d7, 0x1983,
+ 0x80d8, 0x44c6,
+ 0x80d9, 0x1981,
+ 0x80da, 0x0ba0,
+ 0x80db, 0x197e,
+ 0x80dc, 0x0d3b,
+ 0x80dd, 0x1985,
+ 0x80de, 0x0406,
+ 0x80df, 0x44c7,
+ 0x80e1, 0x07b1,
+ 0x80e2, 0x44c9,
+ 0x80e4, 0x126d,
+ 0x80e5, 0x1bc7,
+ 0x80e6, 0x44cb,
+ 0x80e7, 0x197a,
+ 0x80eb, 0x1986,
+ 0x80ec, 0x179a,
+ 0x80ed, 0x1989,
+ 0x80ee, 0x44cc,
+ 0x80ef, 0x0975,
+ 0x80f0, 0x104f,
+ 0x80f1, 0x1987,
+ 0x80f2, 0x198c,
+ 0x80f3, 0x06e7,
+ 0x80f4, 0x1988,
+ 0x80f5, 0x44cd,
+ 0x80f6, 0x088b,
+ 0x80f7, 0x44ce,
+ 0x80f8, 0x0fa3,
+ 0x80f9, 0x44cf,
+ 0x80fa, 0x03c2,
+ 0x80fb, 0x44d0,
+ 0x80fc, 0x198d,
+ 0x80fd, 0x0b3f,
+ 0x80fe, 0x44d1,
+ 0x8100, 0x44d3,
+ 0x8102, 0x11ab,
+ 0x8103, 0x44d5,
+ 0x8105, 0x21d2,
+ 0x8106, 0x0563,
+ 0x8107, 0x44d7,
+ 0x8109, 0x0a9d,
+ 0x810a, 0x082c,
+ 0x810b, 0x44d9,
+ 0x810d, 0x198a,
+ 0x810f, 0x1123,
+ 0x8110, 0x0c09,
+ 0x8111, 0x0b37,
+ 0x8112, 0x198f,
+ 0x8113, 0x0b68,
+ 0x8114, 0x1309,
+ 0x8115, 0x44db,
+ 0x8116, 0x0478,
+ 0x8117, 0x44dc,
+ 0x8118, 0x1994,
+ 0x8119, 0x44dd,
+ 0x811a, 0x0896,
+ 0x811b, 0x24c7,
+ 0x811c, 0x44de,
+ 0x811e, 0x1992,
+ 0x811f, 0x44e0,
+ 0x812c, 0x1993,
+ 0x812d, 0x44ed,
+ 0x812f, 0x06a7,
+ 0x8130, 0x44ef,
+ 0x8131, 0x0e82,
+ 0x8132, 0x1995,
+ 0x8133, 0x44f0,
+ 0x8136, 0x1991,
+ 0x8137, 0x44f3,
+ 0x8138, 0x09fc,
+ 0x8139, 0x2279,
+ 0x813a, 0x44f4,
+ 0x813e, 0x0bc1,
+ 0x813f, 0x44f8,
+ 0x8146, 0x0e46,
+ 0x8147, 0x44ff,
+ 0x8148, 0x1996,
+ 0x8149, 0x4500,
+ 0x814a, 0x099b,
+ 0x814b, 0x103f,
+ 0x814c, 0x1997,
+ 0x814d, 0x4501,
+ 0x814e, 0x2123,
+ 0x814f, 0x4502,
+ 0x8150, 0x06aa,
+ 0x8151, 0x06a8,
+ 0x8152, 0x4503,
+ 0x8153, 0x1998,
+ 0x8154, 0x0c38,
+ 0x8155, 0x0ea4,
+ 0x8156, 0x24c5,
+ 0x8157, 0x4504,
+ 0x8159, 0x199a,
+ 0x815b, 0x4506,
+ 0x8160, 0x199d,
+ 0x8161, 0x24c9,
+ 0x8162, 0x450b,
+ 0x8165, 0x0f93,
+ 0x8166, 0x2094,
+ 0x8167, 0x19a2,
+ 0x8168, 0x450e,
+ 0x8169, 0x199e,
+ 0x816a, 0x450f,
+ 0x816b, 0x2296,
+ 0x816c, 0x4510,
+ 0x816d, 0x19a1,
+ 0x816e, 0x0cd4,
+ 0x816f, 0x4511,
+ 0x8170, 0x1025,
+ 0x8171, 0x199c,
+ 0x8172, 0x4512,
+ 0x8174, 0x1999,
+ 0x8175, 0x4514,
+ 0x8178, 0x1e77,
+ 0x8179, 0x06b4,
+ 0x817a, 0x0f46,
+ 0x817b, 0x0b48,
+ 0x817c, 0x199f,
+ 0x817e, 0x0e2d,
+ 0x817f, 0x0e79,
+ 0x8180, 0x03fd,
+ 0x8181, 0x4517,
+ 0x8182, 0x19a6,
+ 0x8183, 0x4518,
+ 0x8188, 0x19a5,
+ 0x8189, 0x451d,
+ 0x818a, 0x0479,
+ 0x818b, 0x451e,
+ 0x818f, 0x06db,
+ 0x8190, 0x4522,
+ 0x8191, 0x19a7,
+ 0x8192, 0x4523,
+ 0x8198, 0x0455,
+ 0x8199, 0x4529,
+ 0x819a, 0x1f06,
+ 0x819b, 0x0e18,
+ 0x819c, 0x0b07,
+ 0x819d, 0x0f12,
+ 0x819e, 0x452a,
+ 0x81a0, 0x1fa5,
+ 0x81a1, 0x452c,
+ 0x81a3, 0x19a9,
+ 0x81a4, 0x452e,
+ 0x81a6, 0x19b0,
+ 0x81a7, 0x4530,
+ 0x81a8, 0x0bb3,
+ 0x81a9, 0x2099,
+ 0x81aa, 0x19aa,
+ 0x81ab, 0x4531,
+ 0x81b3, 0x0cfe,
+ 0x81b4, 0x4539,
+ 0x81ba, 0x1641,
+ 0x81bb, 0x19ae,
+ 0x81bc, 0x453f,
+ 0x81bd, 0x1ead,
+ 0x81be, 0x24c8,
+ 0x81bf, 0x20a8,
+ 0x81c0, 0x0e7f,
+ 0x81c1, 0x19af,
+ 0x81c2, 0x0444,
+ 0x81c3, 0x109c,
+ 0x81c4, 0x4540,
+ 0x81c6, 0x1063,
+ 0x81c7, 0x4542,
+ 0x81c9, 0x201f,
+ 0x81ca, 0x19ad,
+ 0x81cb, 0x4544,
+ 0x81cc, 0x19ab,
+ 0x81cd, 0x20c5,
+ 0x81ce, 0x4545,
+ 0x81cf, 0x24ca,
+ 0x81d0, 0x4546,
+ 0x81d8, 0x1ff0,
+ 0x81d9, 0x454e,
+ 0x81da, 0x24c6,
+ 0x81db, 0x454f,
+ 0x81df, 0x225d,
+ 0x81e0, 0x22de,
+ 0x81e1, 0x4553,
+ 0x81e3, 0x04e1,
+ 0x81e4, 0x4555,
+ 0x81e7, 0x1902,
+ 0x81e8, 0x202c,
+ 0x81e9, 0x4558,
+ 0x81ea, 0x1231,
+ 0x81eb, 0x4559,
+ 0x81ec, 0x1ca9,
+ 0x81ed, 0x0519,
+ 0x81ee, 0x455a,
+ 0x81f3, 0x11c0,
+ 0x81f5, 0x455f,
+ 0x81fa, 0x2161,
+ 0x81fb, 0x118a,
+ 0x81fc, 0x08f9,
+ 0x81fd, 0x4564,
+ 0x81fe, 0x1ca5,
+ 0x81ff, 0x4565,
+ 0x8200, 0x102f,
+ 0x8201, 0x1ca6,
+ 0x8203, 0x4566,
+ 0x8204, 0x1ca8,
+ 0x8205, 0x08fa,
+ 0x8206, 0x10c4,
+ 0x8207, 0x223b,
+ 0x8208, 0x21d9,
+ 0x8209, 0x1fcb,
+ 0x820a, 0x1fc9,
+ 0x820b, 0x4567,
+ 0x820c, 0x0d19,
+ 0x820e, 0x4568,
+ 0x8210, 0x1c62,
+ 0x8211, 0x456a,
+ 0x8212, 0x0d7d,
+ 0x8213, 0x456b,
+ 0x8214, 0x0e45,
+ 0x8215, 0x456c,
+ 0x821b, 0x1618,
+ 0x821c, 0x0da9,
+ 0x821d, 0x4572,
+ 0x821e, 0x0ef7,
+ 0x821f, 0x11da,
+ 0x8220, 0x4573,
+ 0x8221, 0x1cab,
+ 0x8224, 0x4574,
+ 0x8228, 0x1cb0,
+ 0x8229, 0x4578,
+ 0x822a, 0x0774,
+ 0x822b, 0x1cb1,
+ 0x822c, 0x03ee,
+ 0x822d, 0x1cae,
+ 0x822e, 0x4579,
+ 0x822f, 0x1caf,
+ 0x8230, 0x0873,
+ 0x8231, 0x049c,
+ 0x8232, 0x457a,
+ 0x8233, 0x1cb4,
+ 0x8235, 0x0625,
+ 0x8236, 0x0477,
+ 0x8237, 0x0f3c,
+ 0x8238, 0x1cb2,
+ 0x8239, 0x052f,
+ 0x823a, 0x457b,
+ 0x823b, 0x1cb3,
+ 0x823c, 0x457c,
+ 0x823e, 0x1cb6,
+ 0x823f, 0x457e,
+ 0x8244, 0x1cb7,
+ 0x8245, 0x4583,
+ 0x8247, 0x0e58,
+ 0x8248, 0x4585,
+ 0x8249, 0x1cb8,
+ 0x824a, 0x4586,
+ 0x824b, 0x1cb9,
+ 0x824c, 0x4587,
+ 0x824f, 0x1cba,
+ 0x8250, 0x458a,
+ 0x8258, 0x0dc7,
+ 0x8259, 0x1e61,
+ 0x825a, 0x1cbb,
+ 0x825b, 0x4592,
+ 0x825f, 0x1cbc,
+ 0x8260, 0x4596,
+ 0x8264, 0x25ef,
+ 0x8265, 0x459a,
+ 0x8266, 0x1f98,
+ 0x8267, 0x459b,
+ 0x8268, 0x1cbd,
+ 0x8269, 0x459c,
+ 0x826b, 0x25f0,
+ 0x826c, 0x459e,
+ 0x826e, 0x1cdc,
+ 0x826f, 0x0a05,
+ 0x8270, 0x085b,
+ 0x8271, 0x1f88,
+ 0x8272, 0x0ce4,
+ 0x8273, 0x1007,
+ 0x8274, 0x1771,
+ 0x8275, 0x45a0,
+ 0x8277, 0x21f8,
+ 0x8278, 0x45a2,
+ 0x8279, 0x13e1,
+ 0x827a, 0x105c,
+ 0x827b, 0x45a3,
+ 0x827d, 0x13e2,
+ 0x827e, 0x03b7,
+ 0x827f, 0x13e3,
+ 0x8280, 0x45a5,
+ 0x8282, 0x08ab,
+ 0x8283, 0x45a7,
+ 0x8284, 0x13e7,
+ 0x8285, 0x45a8,
+ 0x8288, 0x1278,
+ 0x8289, 0x45ab,
+ 0x828a, 0x13e5,
+ 0x828b, 0x10d8,
+ 0x828c, 0x45ac,
+ 0x828d, 0x0d0f,
+ 0x828e, 0x13e8,
+ 0x828f, 0x13e4,
+ 0x8290, 0x45ad,
+ 0x8291, 0x13e9,
+ 0x8292, 0x0aa7,
+ 0x8293, 0x45ae,
+ 0x8297, 0x13ea,
+ 0x8298, 0x13f3,
+ 0x8299, 0x13eb,
+ 0x829a, 0x45b2,
+ 0x829c, 0x0eee,
+ 0x829d, 0x11a4,
+ 0x829e, 0x45b4,
+ 0x829f, 0x13fd,
+ 0x82a0, 0x45b5,
+ 0x82a1, 0x13fb,
+ 0x82a2, 0x45b6,
+ 0x82a4, 0x1400,
+ 0x82a5, 0x08b7,
+ 0x82a6, 0x0a52,
+ 0x82a7, 0x45b8,
+ 0x82a8, 0x13e6,
+ 0x82a9, 0x13f9,
+ 0x82aa, 0x13fc,
+ 0x82ab, 0x13ec,
+ 0x82ac, 0x066f,
+ 0x82ad, 0x03d0,
+ 0x82ae, 0x13f5,
+ 0x82af, 0x0f89,
+ 0x82b0, 0x13ef,
+ 0x82b1, 0x07bd,
+ 0x82b2, 0x45b9,
+ 0x82b3, 0x0659,
+ 0x82b4, 0x13fa,
+ 0x82b5, 0x45ba,
+ 0x82b7, 0x13f4,
+ 0x82b8, 0x13ed,
+ 0x82b9, 0x0c58,
+ 0x82ba, 0x45bc,
+ 0x82bb, 0x2322,
+ 0x82bc, 0x45bd,
+ 0x82bd, 0x0fe8,
+ 0x82be, 0x13ee,
+ 0x82bf, 0x45be,
+ 0x82c1, 0x13f8,
+ 0x82c2, 0x45c0,
+ 0x82c4, 0x13fe,
+ 0x82c5, 0x45c2,
+ 0x82c7, 0x0ebc,
+ 0x82c8, 0x13f0,
+ 0x82c9, 0x45c4,
+ 0x82ca, 0x13f1,
+ 0x82cb, 0x13f6,
+ 0x82cd, 0x049b,
+ 0x82ce, 0x13ff,
+ 0x82cf, 0x0dca,
+ 0x82d0, 0x45c5,
+ 0x82d1, 0x10fa,
+ 0x82d2, 0x1409,
+ 0x82d3, 0x140d,
+ 0x82d4, 0x0df9,
+ 0x82d5, 0x1414,
+ 0x82d6, 0x45c6,
+ 0x82d7, 0x0aec,
+ 0x82d8, 0x140a,
+ 0x82d9, 0x45c7,
+ 0x82db, 0x094e,
+ 0x82dc, 0x1407,
+ 0x82dd, 0x45c9,
+ 0x82de, 0x0405,
+ 0x82df, 0x070f,
+ 0x82e0, 0x1413,
+ 0x82e1, 0x1401,
+ 0x82e2, 0x45ca,
+ 0x82e3, 0x13f2,
+ 0x82e4, 0x1404,
+ 0x82e5, 0x0ccf,
+ 0x82e6, 0x096d,
+ 0x82e7, 0x2336,
+ 0x82e8, 0x45cb,
+ 0x82eb, 0x0cf4,
+ 0x82ec, 0x45ce,
+ 0x82ef, 0x0426,
+ 0x82f0, 0x45d1,
+ 0x82f1, 0x1087,
+ 0x82f2, 0x45d2,
+ 0x82f4, 0x1408,
+ 0x82f5, 0x45d4,
+ 0x82f7, 0x1403,
+ 0x82f8, 0x45d6,
+ 0x82f9, 0x0bda,
+ 0x82fa, 0x45d7,
+ 0x82fb, 0x140c,
+ 0x82fc, 0x45d8,
+ 0x8300, 0x45dc,
+ 0x8301, 0x121f,
+ 0x8302, 0x0ab4,
+ 0x8303, 0x0653,
+ 0x8304, 0x0c4e,
+ 0x8305, 0x0aae,
+ 0x8306, 0x1410,
+ 0x8307, 0x1406,
+ 0x8308, 0x1419,
+ 0x8309, 0x1402,
+ 0x830a, 0x45dd,
+ 0x830c, 0x140b,
+ 0x830d, 0x45df,
+ 0x830e, 0x08d4,
+ 0x830f, 0x1405,
+ 0x8310, 0x45e0,
+ 0x8311, 0x140e,
+ 0x8312, 0x45e1,
+ 0x8314, 0x1411,
+ 0x8316, 0x45e3,
+ 0x8317, 0x1426,
+ 0x8318, 0x45e4,
+ 0x831a, 0x140f,
+ 0x831b, 0x142e,
+ 0x831c, 0x1415,
+ 0x831d, 0x45e6,
+ 0x8327, 0x085e,
+ 0x8328, 0x0547,
+ 0x8329, 0x45f0,
+ 0x832b, 0x0aa8,
+ 0x832c, 0x04ae,
+ 0x832d, 0x1428,
+ 0x832e, 0x45f2,
+ 0x832f, 0x1420,
+ 0x8330, 0x45f3,
+ 0x8331, 0x141d,
+ 0x8332, 0x45f4,
+ 0x8333, 0x142a,
+ 0x8334, 0x141c,
+ 0x8335, 0x1077,
+ 0x8336, 0x04af,
+ 0x8337, 0x45f5,
+ 0x8338, 0x0cb2,
+ 0x8339, 0x0cbe,
+ 0x833a, 0x1429,
+ 0x833b, 0x45f6,
+ 0x833c, 0x141b,
+ 0x833d, 0x45f7,
+ 0x8340, 0x1425,
+ 0x8341, 0x45fa,
+ 0x8343, 0x1423,
+ 0x8344, 0x45fc,
+ 0x8346, 0x08d2,
+ 0x8347, 0x1422,
+ 0x8348, 0x45fe,
+ 0x8349, 0x04a4,
+ 0x834a, 0x45ff,
+ 0x834f, 0x1421,
+ 0x8350, 0x0869,
+ 0x8351, 0x1416,
+ 0x8352, 0x07d9,
+ 0x8353, 0x4604,
+ 0x8354, 0x09de,
+ 0x8355, 0x4605,
+ 0x835a, 0x0847,
+ 0x835b, 0x1417,
+ 0x835d, 0x460a,
+ 0x835e, 0x141f,
+ 0x835f, 0x1424,
+ 0x8360, 0x1427,
+ 0x8361, 0x0595,
+ 0x8362, 0x460b,
+ 0x8363, 0x0cb4,
+ 0x8364, 0x07fc,
+ 0x8365, 0x142c,
+ 0x8366, 0x142b,
+ 0x8367, 0x1090,
+ 0x8368, 0x142d,
+ 0x8369, 0x142f,
+ 0x836a, 0x1431,
+ 0x836b, 0x1078,
+ 0x836c, 0x1430,
+ 0x836d, 0x1432,
+ 0x836f, 0x1030,
+ 0x8370, 0x460c,
+ 0x8377, 0x0780,
+ 0x8378, 0x1435,
+ 0x8379, 0x4613,
+ 0x837b, 0x1442,
+ 0x837c, 0x143d,
+ 0x837d, 0x1440,
+ 0x837e, 0x4615,
+ 0x8385, 0x143c,
+ 0x8386, 0x0bed,
+ 0x8387, 0x461c,
+ 0x8389, 0x09dd,
+ 0x838a, 0x22ab,
+ 0x838b, 0x461e,
+ 0x838e, 0x0ce8,
+ 0x838f, 0x4621,
+ 0x8392, 0x141a,
+ 0x8393, 0x143a,
+ 0x8394, 0x4624,
+ 0x8396, 0x1fbf,
+ 0x8397, 0x4626,
+ 0x8398, 0x1443,
+ 0x8399, 0x4627,
+ 0x839b, 0x141e,
+ 0x839c, 0x143b,
+ 0x839d, 0x4629,
+ 0x839e, 0x1444,
+ 0x839f, 0x462a,
+ 0x83a0, 0x1438,
+ 0x83a1, 0x462b,
+ 0x83a2, 0x1f7d,
+ 0x83a3, 0x462c,
+ 0x83a7, 0x2333,
+ 0x83a8, 0x1445,
+ 0x83a9, 0x143f,
+ 0x83aa, 0x1439,
+ 0x83ab, 0x0b0d,
+ 0x83ac, 0x4630,
+ 0x83b0, 0x1434,
+ 0x83b1, 0x099e,
+ 0x83b2, 0x09f4,
+ 0x83b3, 0x1436,
+ 0x83b5, 0x4634,
+ 0x83b6, 0x143e,
+ 0x83b7, 0x0806,
+ 0x83b8, 0x1441,
+ 0x83b9, 0x108d,
+ 0x83ba, 0x1446,
+ 0x83bb, 0x4635,
+ 0x83bc, 0x1447,
+ 0x83bd, 0x0aac,
+ 0x83be, 0x4636,
+ 0x83c0, 0x145e,
+ 0x83c1, 0x1448,
+ 0x83c2, 0x4638,
+ 0x83c5, 0x145d,
+ 0x83c6, 0x463b,
+ 0x83c7, 0x0716,
+ 0x83c8, 0x463c,
+ 0x83ca, 0x0904,
+ 0x83cb, 0x463e,
+ 0x83cc, 0x0929,
+ 0x83cd, 0x463f,
+ 0x83cf, 0x0781,
+ 0x83d0, 0x4641,
+ 0x83d4, 0x1456,
+ 0x83d5, 0x4645,
+ 0x83d6, 0x1451,
+ 0x83d7, 0x4646,
+ 0x83d8, 0x144b,
+ 0x83d9, 0x4647,
+ 0x83dc, 0x0492,
+ 0x83dd, 0x144f,
+ 0x83de, 0x464a,
+ 0x83df, 0x1457,
+ 0x83e0, 0x046b,
+ 0x83e1, 0x1461,
+ 0x83e2, 0x464b,
+ 0x83e5, 0x144a,
+ 0x83e6, 0x464e,
+ 0x83e9, 0x0bef,
+ 0x83ea, 0x145c,
+ 0x83eb, 0x4651,
+ 0x83ef, 0x1f4d,
+ 0x83f0, 0x1460,
+ 0x83f1, 0x0a2b,
+ 0x83f2, 0x0663,
+ 0x83f3, 0x4655,
+ 0x83f8, 0x145a,
+ 0x83fa, 0x465a,
+ 0x83fd, 0x1450,
+ 0x83fe, 0x465d,
+ 0x8400, 0x465f,
+ 0x8401, 0x1449,
+ 0x8402, 0x4660,
+ 0x8403, 0x1459,
+ 0x8404, 0x0e24,
+ 0x8405, 0x4661,
+ 0x8406, 0x1455,
+ 0x8407, 0x2334,
+ 0x8408, 0x4662,
+ 0x840a, 0x1ff1,
+ 0x840b, 0x144e,
+ 0x840c, 0x0acd,
+ 0x840d, 0x0bdb,
+ 0x840e, 0x0ebd,
+ 0x840f, 0x1458,
+ 0x8410, 0x4664,
+ 0x8411, 0x1454,
+ 0x8412, 0x4665,
+ 0x8418, 0x144d,
+ 0x8419, 0x466b,
+ 0x841c, 0x1452,
+ 0x841d, 0x0a83,
+ 0x841e, 0x466e,
+ 0x8424, 0x108e,
+ 0x8426, 0x145f,
+ 0x8427, 0x0f61,
+ 0x8428, 0x0cd3,
+ 0x8429, 0x4674,
+ 0x842c, 0x218b,
+ 0x842d, 0x4677,
+ 0x8431, 0x1472,
+ 0x8432, 0x467b,
+ 0x8435, 0x2349,
+ 0x8436, 0x467e,
+ 0x8438, 0x1453,
+ 0x8439, 0x4680,
+ 0x843c, 0x146c,
+ 0x843d, 0x0a8b,
+ 0x843e, 0x4683,
+ 0x8446, 0x146d,
+ 0x8447, 0x468b,
+ 0x8449, 0x220b,
+ 0x844a, 0x468d,
+ 0x8451, 0x1463,
+ 0x8452, 0x2346,
+ 0x8453, 0x4694,
+ 0x8457, 0x11f7,
+ 0x8458, 0x4698,
+ 0x8459, 0x1465,
+ 0x845a, 0x1464,
+ 0x845b, 0x06eb,
+ 0x845c, 0x1462,
+ 0x845d, 0x4699,
+ 0x8461, 0x0bee,
+ 0x8462, 0x469d,
+ 0x8463, 0x05ec,
+ 0x8464, 0x2347,
+ 0x8465, 0x469e,
+ 0x8466, 0x2193,
+ 0x8467, 0x469f,
+ 0x8469, 0x146e,
+ 0x846a, 0x46a1,
+ 0x846b, 0x07b0,
+ 0x846c, 0x1124,
+ 0x846d, 0x1473,
+ 0x846e, 0x46a2,
+ 0x846f, 0x26a1,
+ 0x8470, 0x46a3,
+ 0x8471, 0x0553,
+ 0x8472, 0x46a4,
+ 0x8473, 0x1466,
+ 0x8474, 0x46a5,
+ 0x8475, 0x0988,
+ 0x8476, 0x146f,
+ 0x8477, 0x1f62,
+ 0x8478, 0x146b,
+ 0x8479, 0x46a6,
+ 0x847a, 0x1469,
+ 0x847b, 0x46a7,
+ 0x8482, 0x05ba,
+ 0x8483, 0x46ae,
+ 0x8487, 0x1467,
+ 0x8489, 0x146a,
+ 0x848a, 0x46b2,
+ 0x848b, 0x0880,
+ 0x848c, 0x1470,
+ 0x848d, 0x46b3,
+ 0x848e, 0x1471,
+ 0x848f, 0x46b4,
+ 0x8493, 0x234d,
+ 0x8494, 0x2348,
+ 0x8495, 0x46b8,
+ 0x8497, 0x1481,
+ 0x8498, 0x46ba,
+ 0x8499, 0x0ace,
+ 0x849a, 0x46bb,
+ 0x849c, 0x0dd7,
+ 0x849d, 0x46bd,
+ 0x84a1, 0x147e,
+ 0x84a2, 0x46c1,
+ 0x84af, 0x1297,
+ 0x84b0, 0x46ce,
+ 0x84b2, 0x0bf0,
+ 0x84b3, 0x46d0,
+ 0x84b4, 0x1480,
+ 0x84b5, 0x46d1,
+ 0x84b8, 0x1195,
+ 0x84b9, 0x147f,
+ 0x84ba, 0x147c,
+ 0x84bb, 0x46d4,
+ 0x84bc, 0x1e60,
+ 0x84bd, 0x1478,
+ 0x84be, 0x46d5,
+ 0x84bf, 0x147b,
+ 0x84c0, 0x2345,
+ 0x84c1, 0x1474,
+ 0x84c2, 0x46d6,
+ 0x84c4, 0x0fb9,
+ 0x84c5, 0x46d8,
+ 0x84c9, 0x0cb3,
+ 0x84ca, 0x147a,
+ 0x84cb, 0x1f12,
+ 0x84cc, 0x46dc,
+ 0x84cd, 0x1475,
+ 0x84ce, 0x46dd,
+ 0x84d0, 0x1476,
+ 0x84d1, 0x0de7,
+ 0x84d2, 0x46df,
+ 0x84d3, 0x1479,
+ 0x84d4, 0x46e0,
+ 0x84d6, 0x0436,
+ 0x84d7, 0x46e2,
+ 0x84dd, 0x09a1,
+ 0x84de, 0x46e8,
+ 0x84df, 0x082e,
+ 0x84e0, 0x147d,
+ 0x84e1, 0x46e9,
+ 0x84e3, 0x1483,
+ 0x84e4, 0x46eb,
+ 0x84e5, 0x1482,
+ 0x84e6, 0x1477,
+ 0x84e7, 0x46ec,
+ 0x84ec, 0x0baf,
+ 0x84ed, 0x46f1,
+ 0x84ee, 0x2018,
+ 0x84ef, 0x2335,
+ 0x84f0, 0x1487,
+ 0x84f1, 0x46f2,
+ 0x84fc, 0x148e,
+ 0x84fd, 0x233c,
+ 0x84fe, 0x46fd,
+ 0x84ff, 0x148d,
+ 0x8500, 0x46fe,
+ 0x850c, 0x1484,
+ 0x850d, 0x470a,
+ 0x8511, 0x0af4,
+ 0x8512, 0x470e,
+ 0x8513, 0x0aa2,
+ 0x8514, 0x266f,
+ 0x8515, 0x470f,
+ 0x8517, 0x1182,
+ 0x8518, 0x4711,
+ 0x851a, 0x0ec4,
+ 0x851b, 0x4713,
+ 0x851e, 0x2351,
+ 0x851f, 0x1489,
+ 0x8520, 0x4716,
+ 0x8521, 0x0493,
+ 0x8522, 0x4717,
+ 0x8523, 0x1fa0,
+ 0x8524, 0x4718,
+ 0x8526, 0x2338,
+ 0x8527, 0x471a,
+ 0x852b, 0x0b4b,
+ 0x852c, 0x0d76,
+ 0x852d, 0x221b,
+ 0x852e, 0x471e,
+ 0x8537, 0x0c3b,
+ 0x8538, 0x1486,
+ 0x8539, 0x1488,
+ 0x853a, 0x148a,
+ 0x853b, 0x148c,
+ 0x853c, 0x03b5,
+ 0x853d, 0x0437,
+ 0x853e, 0x4727,
+ 0x8541, 0x2342,
+ 0x8542, 0x472a,
+ 0x8543, 0x1496,
+ 0x8544, 0x472b,
+ 0x8546, 0x234f,
+ 0x8547, 0x472d,
+ 0x8548, 0x1490,
+ 0x8549, 0x0887,
+ 0x854a, 0x0cca,
+ 0x854b, 0x472e,
+ 0x854e, 0x233d,
+ 0x854f, 0x4731,
+ 0x8552, 0x2344,
+ 0x8553, 0x2331,
+ 0x8554, 0x4734,
+ 0x8555, 0x234b,
+ 0x8556, 0x148b,
+ 0x8557, 0x4735,
+ 0x8558, 0x233b,
+ 0x8559, 0x148f,
+ 0x855a, 0x4736,
+ 0x855e, 0x1493,
+ 0x855f, 0x473a,
+ 0x8562, 0x2350,
+ 0x8563, 0x473d,
+ 0x8564, 0x1492,
+ 0x8565, 0x473e,
+ 0x8568, 0x1491,
+ 0x8569, 0x1eb4,
+ 0x856a, 0x21a6,
+ 0x856b, 0x4741,
+ 0x856d, 0x21cb,
+ 0x856e, 0x4743,
+ 0x8572, 0x1497,
+ 0x8573, 0x4747,
+ 0x8574, 0x110f,
+ 0x8575, 0x4748,
+ 0x8577, 0x2355,
+ 0x8578, 0x474a,
+ 0x8579, 0x149d,
+ 0x857a, 0x1494,
+ 0x857b, 0x1498,
+ 0x857c, 0x474b,
+ 0x857e, 0x09c4,
+ 0x857f, 0x474d,
+ 0x8584, 0x040a,
+ 0x8585, 0x14a0,
+ 0x8586, 0x4752,
+ 0x8587, 0x149b,
+ 0x8588, 0x233e,
+ 0x8589, 0x4753,
+ 0x858a, 0x1f74,
+ 0x858b, 0x4754,
+ 0x858c, 0x2330,
+ 0x858d, 0x4755,
+ 0x858f, 0x149c,
+ 0x8590, 0x4757,
+ 0x8591, 0x2680,
+ 0x8592, 0x4758,
+ 0x8594, 0x20da,
+ 0x8595, 0x475a,
+ 0x859b, 0x0fcf,
+ 0x859c, 0x149f,
+ 0x859d, 0x4760,
+ 0x859f, 0x234a,
+ 0x85a0, 0x4762,
+ 0x85a4, 0x1499,
+ 0x85a5, 0x4766,
+ 0x85a6, 0x1f91,
+ 0x85a7, 0x4767,
+ 0x85a8, 0x149a,
+ 0x85a9, 0x2107,
+ 0x85aa, 0x0f88,
+ 0x85ab, 0x4768,
+ 0x85ae, 0x149e,
+ 0x85af, 0x0d84,
+ 0x85b0, 0x14a3,
+ 0x85b1, 0x476b,
+ 0x85b7, 0x14a2,
+ 0x85b8, 0x4771,
+ 0x85b9, 0x14a1,
+ 0x85ba, 0x233f,
+ 0x85bb, 0x4772,
+ 0x85c1, 0x14a5,
+ 0x85c2, 0x4778,
+ 0x85c9, 0x08b6,
+ 0x85ca, 0x477f,
+ 0x85cd, 0x1ff4,
+ 0x85ce, 0x2343,
+ 0x85cf, 0x049f,
+ 0x85d0, 0x0aef,
+ 0x85d1, 0x4782,
+ 0x85d3, 0x14a4,
+ 0x85d4, 0x4784,
+ 0x85d5, 0x0b7b,
+ 0x85d6, 0x4785,
+ 0x85dc, 0x14a6,
+ 0x85dd, 0x2212,
+ 0x85de, 0x478b,
+ 0x85e4, 0x0e2c,
+ 0x85e5, 0x2207,
+ 0x85e6, 0x4791,
+ 0x85e9, 0x0647,
+ 0x85ea, 0x2359,
+ 0x85eb, 0x4794,
+ 0x85f4, 0x2254,
+ 0x85f5, 0x479d,
+ 0x85f6, 0x2332,
+ 0x85f7, 0x479e,
+ 0x85f9, 0x1e26,
+ 0x85fa, 0x2357,
+ 0x85fb, 0x1128,
+ 0x85fc, 0x47a0,
+ 0x85ff, 0x14a7,
+ 0x8600, 0x47a3,
+ 0x8604, 0x2358,
+ 0x8605, 0x14a9,
+ 0x8606, 0x2042,
+ 0x8607, 0x2153,
+ 0x8608, 0x47a7,
+ 0x860b, 0x20bb,
+ 0x860c, 0x47aa,
+ 0x8611, 0x0b05,
+ 0x8612, 0x47af,
+ 0x8616, 0x14ab,
+ 0x8617, 0x47b3,
+ 0x861a, 0x235a,
+ 0x861b, 0x47b6,
+ 0x861e, 0x2356,
+ 0x861f, 0x47b9,
+ 0x8622, 0x2337,
+ 0x8623, 0x47bc,
+ 0x8627, 0x14a8,
+ 0x8628, 0x47c0,
+ 0x8629, 0x14aa,
+ 0x862a, 0x47c1,
+ 0x862d, 0x1ff9,
+ 0x862e, 0x47c4,
+ 0x8638, 0x115b,
+ 0x8639, 0x47ce,
+ 0x863a, 0x2353,
+ 0x863b, 0x47cf,
+ 0x863c, 0x14ac,
+ 0x863d, 0x47d0,
+ 0x863f, 0x2061,
+ 0x8640, 0x47d2,
+ 0x864d, 0x1bf0,
+ 0x864e, 0x07b7,
+ 0x864f, 0x0a59,
+ 0x8650, 0x0b71,
+ 0x8651, 0x0a6e,
+ 0x8652, 0x47df,
+ 0x8654, 0x1bf1,
+ 0x8655, 0x1e95,
+ 0x8656, 0x47e1,
+ 0x865a, 0x0fb4,
+ 0x865b, 0x47e5,
+ 0x865c, 0x2049,
+ 0x865d, 0x47e6,
+ 0x865e, 0x10c2,
+ 0x865f, 0x1f42,
+ 0x8660, 0x47e7,
+ 0x8662, 0x196d,
+ 0x8663, 0x47e9,
+ 0x8667, 0x1fe8,
+ 0x8668, 0x47ed,
+ 0x866b, 0x050b,
+ 0x866c, 0x1bf2,
+ 0x866d, 0x47f0,
+ 0x866e, 0x1bf3,
+ 0x866f, 0x47f1,
+ 0x8671, 0x0d44,
+ 0x8672, 0x47f3,
+ 0x8679, 0x079e,
+ 0x867a, 0x1bf5,
+ 0x867b, 0x1bf7,
+ 0x867c, 0x1bf6,
+ 0x867d, 0x0dd9,
+ 0x867e, 0x0f27,
+ 0x867f, 0x1bf4,
+ 0x8680, 0x0d4b,
+ 0x8681, 0x1056,
+ 0x8682, 0x0a93,
+ 0x8683, 0x47fa,
+ 0x868a, 0x0ed2,
+ 0x868b, 0x1bfa,
+ 0x868c, 0x0401,
+ 0x868d, 0x1bf9,
+ 0x868e, 0x4801,
+ 0x8693, 0x1c00,
+ 0x8694, 0x4806,
+ 0x8695, 0x0496,
+ 0x8696, 0x4807,
+ 0x869c, 0x0fea,
+ 0x869d, 0x1bfc,
+ 0x869e, 0x480d,
+ 0x86a3, 0x1bfe,
+ 0x86a4, 0x112c,
+ 0x86a5, 0x4812,
+ 0x86a7, 0x1bfd,
+ 0x86a8, 0x1bf8,
+ 0x86a9, 0x1c01,
+ 0x86aa, 0x1bff,
+ 0x86ab, 0x4814,
+ 0x86ac, 0x1bfb,
+ 0x86ad, 0x4815,
+ 0x86af, 0x1c09,
+ 0x86b0, 0x1c06,
+ 0x86b1, 0x1c08,
+ 0x86b2, 0x4817,
+ 0x86b4, 0x1c0c,
+ 0x86b5, 0x1c04,
+ 0x86b6, 0x1c02,
+ 0x86b7, 0x4819,
+ 0x86ba, 0x1c07,
+ 0x86bb, 0x481c,
+ 0x86c0, 0x11fa,
+ 0x86c1, 0x4821,
+ 0x86c4, 0x1c03,
+ 0x86c5, 0x4824,
+ 0x86c6, 0x0c76,
+ 0x86c7, 0x0d18,
+ 0x86c8, 0x4825,
+ 0x86c9, 0x1c0a,
+ 0x86ca, 0x071f,
+ 0x86cb, 0x0591,
+ 0x86cc, 0x4826,
+ 0x86ce, 0x1c05,
+ 0x86cf, 0x1c0b,
+ 0x86d0, 0x1c12,
+ 0x86d1, 0x1c18,
+ 0x86d2, 0x4828,
+ 0x86d4, 0x07ec,
+ 0x86d5, 0x482a,
+ 0x86d8, 0x1c17,
+ 0x86d9, 0x0e8d,
+ 0x86da, 0x482d,
+ 0x86db, 0x11ea,
+ 0x86dc, 0x482e,
+ 0x86de, 0x1c14,
+ 0x86df, 0x1c16,
+ 0x86e0, 0x4830,
+ 0x86e4, 0x06ed,
+ 0x86e5, 0x4834,
+ 0x86e9, 0x1c0d,
+ 0x86ea, 0x4838,
+ 0x86ed, 0x1c10,
+ 0x86ee, 0x0aa0,
+ 0x86ef, 0x483b,
+ 0x86f0, 0x117e,
+ 0x86f1, 0x1c0e,
+ 0x86f3, 0x1c11,
+ 0x86f4, 0x1c15,
+ 0x86f5, 0x483c,
+ 0x86f8, 0x1c1b,
+ 0x86f9, 0x10a1,
+ 0x86fa, 0x25da,
+ 0x86fb, 0x483f,
+ 0x86fe, 0x0629,
+ 0x86ff, 0x4842,
+ 0x8700, 0x0d88,
+ 0x8701, 0x4843,
+ 0x8702, 0x0681,
+ 0x8703, 0x1c19,
+ 0x8704, 0x4844,
+ 0x8706, 0x25d7,
+ 0x8707, 0x1c1a,
+ 0x8708, 0x1c1c,
+ 0x8709, 0x1c1f,
+ 0x870a, 0x1c1d,
+ 0x870b, 0x4846,
+ 0x870d, 0x1c1e,
+ 0x870e, 0x4848,
+ 0x8712, 0x0ffa,
+ 0x8713, 0x1c13,
+ 0x8714, 0x484c,
+ 0x8715, 0x0e7a,
+ 0x8716, 0x484d,
+ 0x8717, 0x0ede,
+ 0x8718, 0x11a8,
+ 0x8719, 0x484e,
+ 0x871a, 0x1c25,
+ 0x871b, 0x484f,
+ 0x871c, 0x0ae0,
+ 0x871d, 0x4850,
+ 0x871e, 0x1c22,
+ 0x871f, 0x4851,
+ 0x8721, 0x099a,
+ 0x8722, 0x1c2e,
+ 0x8723, 0x1c20,
+ 0x8724, 0x4853,
+ 0x8725, 0x1c23,
+ 0x8726, 0x4854,
+ 0x8729, 0x1c2a,
+ 0x872a, 0x4857,
+ 0x872e, 0x1c24,
+ 0x872f, 0x485b,
+ 0x8731, 0x1c29,
+ 0x8732, 0x485d,
+ 0x8734, 0x1c28,
+ 0x8735, 0x485f,
+ 0x8737, 0x1c2b,
+ 0x8738, 0x4861,
+ 0x873b, 0x1c21,
+ 0x873c, 0x4864,
+ 0x873e, 0x1c26,
+ 0x873f, 0x1c2c,
+ 0x8740, 0x4866,
+ 0x8747, 0x1091,
+ 0x8748, 0x1c27,
+ 0x8749, 0x04bc,
+ 0x874a, 0x486d,
+ 0x874c, 0x1c34,
+ 0x874d, 0x486f,
+ 0x874e, 0x0f76,
+ 0x874f, 0x4870,
+ 0x8753, 0x1c37,
+ 0x8754, 0x4874,
+ 0x8755, 0x212e,
+ 0x8756, 0x4875,
+ 0x8757, 0x07dd,
+ 0x8758, 0x4876,
+ 0x8759, 0x1c3b,
+ 0x875a, 0x4877,
+ 0x8760, 0x1c32,
+ 0x8761, 0x487d,
+ 0x8763, 0x1c38,
+ 0x8764, 0x1c3a,
+ 0x8765, 0x1c3c,
+ 0x8766, 0x21b2,
+ 0x8767, 0x487f,
+ 0x876e, 0x1c35,
+ 0x876f, 0x4886,
+ 0x8770, 0x1c33,
+ 0x8771, 0x4887,
+ 0x8774, 0x07b2,
+ 0x8775, 0x488a,
+ 0x8776, 0x05dc,
+ 0x8777, 0x488b,
+ 0x8778, 0x219e,
+ 0x8779, 0x488c,
+ 0x877b, 0x1c31,
+ 0x877c, 0x1c39,
+ 0x877d, 0x1c2f,
+ 0x877f, 0x488e,
+ 0x8782, 0x1c2d,
+ 0x8783, 0x1c46,
+ 0x8784, 0x25dc,
+ 0x8785, 0x1c43,
+ 0x8786, 0x4891,
+ 0x8788, 0x1c42,
+ 0x8789, 0x4893,
+ 0x878b, 0x1c36,
+ 0x878c, 0x4895,
+ 0x878d, 0x0cb5,
+ 0x878e, 0x4896,
+ 0x8793, 0x1c3d,
+ 0x8794, 0x489b,
+ 0x8797, 0x1c45,
+ 0x8798, 0x489e,
+ 0x879e, 0x206c,
+ 0x879f, 0x0afd,
+ 0x87a0, 0x48a4,
+ 0x87a2, 0x2226,
+ 0x87a3, 0x48a6,
+ 0x87a8, 0x1c3f,
+ 0x87a9, 0x48ab,
+ 0x87ab, 0x1c47,
+ 0x87ac, 0x1c49,
+ 0x87ad, 0x1c44,
+ 0x87ae, 0x48ad,
+ 0x87af, 0x1c3e,
+ 0x87b0, 0x48ae,
+ 0x87b3, 0x1c4b,
+ 0x87b4, 0x48b1,
+ 0x87b5, 0x1c4a,
+ 0x87b6, 0x48b2,
+ 0x87ba, 0x0a84,
+ 0x87bb, 0x25e0,
+ 0x87bc, 0x48b6,
+ 0x87bd, 0x1c4e,
+ 0x87be, 0x48b7,
+ 0x87c0, 0x1c50,
+ 0x87c1, 0x48b9,
+ 0x87c4, 0x227b,
+ 0x87c5, 0x48bc,
+ 0x87c6, 0x1c41,
+ 0x87c7, 0x48bd,
+ 0x87c8, 0x25de,
+ 0x87c9, 0x48be,
+ 0x87ca, 0x1c51,
+ 0x87cb, 0x1c4c,
+ 0x87cc, 0x48bf,
+ 0x87ce, 0x25e1,
+ 0x87cf, 0x48c1,
+ 0x87d1, 0x1c4f,
+ 0x87d2, 0x1c40,
+ 0x87d3, 0x1c4d,
+ 0x87d4, 0x48c3,
+ 0x87db, 0x1c52,
+ 0x87dc, 0x48ca,
+ 0x87e0, 0x1c54,
+ 0x87e1, 0x48ce,
+ 0x87e3, 0x25d5,
+ 0x87e4, 0x48d0,
+ 0x87e5, 0x1c48,
+ 0x87e6, 0x48d1,
+ 0x87ea, 0x1c53,
+ 0x87eb, 0x48d5,
+ 0x87ec, 0x1e6b,
+ 0x87ed, 0x48d6,
+ 0x87ee, 0x1c55,
+ 0x87ef, 0x25db,
+ 0x87f0, 0x48d7,
+ 0x87f2, 0x1e89,
+ 0x87f3, 0x48d9,
+ 0x87f6, 0x25d9,
+ 0x87f7, 0x48dc,
+ 0x87f9, 0x0f82,
+ 0x87fa, 0x48de,
+ 0x87fb, 0x2211,
+ 0x87fc, 0x48df,
+ 0x87fe, 0x1c58,
+ 0x87ff, 0x48e1,
+ 0x8800, 0x48e2,
+ 0x8803, 0x130d,
+ 0x8804, 0x48e5,
+ 0x8805, 0x2229,
+ 0x8806, 0x25d6,
+ 0x8807, 0x48e6,
+ 0x880a, 0x1c59,
+ 0x880b, 0x48e9,
+ 0x8810, 0x25dd,
+ 0x8811, 0x25df,
+ 0x8812, 0x48ee,
+ 0x8813, 0x1c57,
+ 0x8814, 0x48ef,
+ 0x8815, 0x0cbf,
+ 0x8816, 0x1c56,
+ 0x8817, 0x48f0,
+ 0x881b, 0x1c5a,
+ 0x881c, 0x48f4,
+ 0x881f, 0x1fef,
+ 0x8820, 0x48f7,
+ 0x8821, 0x1c5b,
+ 0x8822, 0x0543,
+ 0x8823, 0x25d8,
+ 0x8824, 0x48f8,
+ 0x8831, 0x1f29,
+ 0x8832, 0x1a8d,
+ 0x8833, 0x4905,
+ 0x8836, 0x1e5b,
+ 0x8837, 0x4908,
+ 0x8839, 0x1c5c,
+ 0x883a, 0x490a,
+ 0x883b, 0x2076,
+ 0x883c, 0x1c5d,
+ 0x883d, 0x490b,
+ 0x8840, 0x0fd3,
+ 0x8841, 0x490e,
+ 0x8844, 0x1caa,
+ 0x8845, 0x0f91,
+ 0x8846, 0x2297,
+ 0x8847, 0x4911,
+ 0x884a, 0x2690,
+ 0x884b, 0x4914,
+ 0x884c, 0x0f9b,
+ 0x884d, 0x1005,
+ 0x884e, 0x4915,
+ 0x8853, 0x213f,
+ 0x8854, 0x0f3b,
+ 0x8855, 0x491a,
+ 0x8857, 0x08a7,
+ 0x8858, 0x491c,
+ 0x8859, 0x0fec,
+ 0x885a, 0x491d,
+ 0x885b, 0x2198,
+ 0x885c, 0x491e,
+ 0x885d, 0x1e88,
+ 0x885e, 0x491f,
+ 0x8861, 0x0799,
+ 0x8862, 0x15ed,
+ 0x8863, 0x1049,
+ 0x8864, 0x1ba6,
+ 0x8865, 0x0480,
+ 0x8866, 0x4922,
+ 0x8868, 0x0456,
+ 0x8869, 0x1ba7,
+ 0x886a, 0x4924,
+ 0x886b, 0x0cf9,
+ 0x886c, 0x04e9,
+ 0x886d, 0x4925,
+ 0x886e, 0x1306,
+ 0x886f, 0x4926,
+ 0x8870, 0x0d9a,
+ 0x8871, 0x4927,
+ 0x8872, 0x1ba8,
+ 0x8873, 0x4928,
+ 0x8877, 0x11d3,
+ 0x8878, 0x492c,
+ 0x8879, 0x228c,
+ 0x887a, 0x492d,
+ 0x887d, 0x1ba9,
+ 0x887e, 0x1cbe,
+ 0x887f, 0x1baa,
+ 0x8880, 0x4930,
+ 0x8881, 0x10ef,
+ 0x8882, 0x1bab,
+ 0x8883, 0x4931,
+ 0x8884, 0x03cb,
+ 0x8885, 0x1cbf,
+ 0x8886, 0x4932,
+ 0x8888, 0x1cc0,
+ 0x8889, 0x4934,
+ 0x888b, 0x057f,
+ 0x888c, 0x4936,
+ 0x888d, 0x0b9c,
+ 0x888e, 0x4937,
+ 0x8892, 0x0e0e,
+ 0x8893, 0x493b,
+ 0x8896, 0x0faf,
+ 0x8897, 0x493e,
+ 0x889c, 0x0e91,
+ 0x889d, 0x4943,
+ 0x88a2, 0x1bac,
+ 0x88a3, 0x4948,
+ 0x88a4, 0x1307,
+ 0x88a5, 0x4949,
+ 0x88ab, 0x0424,
+ 0x88ac, 0x494f,
+ 0x88ad, 0x0f1b,
+ 0x88ae, 0x4950,
+ 0x88b1, 0x069f,
+ 0x88b2, 0x4953,
+ 0x88b7, 0x1bae,
+ 0x88b8, 0x4958,
+ 0x88bc, 0x1baf,
+ 0x88bd, 0x495c,
+ 0x88c1, 0x048a,
+ 0x88c2, 0x0a1a,
+ 0x88c3, 0x4960,
+ 0x88c5, 0x120d,
+ 0x88c6, 0x1bad,
+ 0x88c7, 0x4962,
+ 0x88c9, 0x1bb0,
+ 0x88ca, 0x25f1,
+ 0x88cb, 0x4964,
+ 0x88ce, 0x1bb2,
+ 0x88cf, 0x200c,
+ 0x88d0, 0x4967,
+ 0x88d2, 0x130a,
+ 0x88d3, 0x4969,
+ 0x88d4, 0x1068,
+ 0x88d5, 0x10e6,
+ 0x88d6, 0x496a,
+ 0x88d8, 0x1cc1,
+ 0x88d9, 0x0c94,
+ 0x88da, 0x496c,
+ 0x88dc, 0x1e58,
+ 0x88dd, 0x22ac,
+ 0x88de, 0x496e,
+ 0x88df, 0x1cc2,
+ 0x88e0, 0x496f,
+ 0x88e2, 0x1bb1,
+ 0x88e3, 0x1bb3,
+ 0x88e4, 0x0970,
+ 0x88e5, 0x1bb4,
+ 0x88e6, 0x4971,
+ 0x88e8, 0x1bb8,
+ 0x88e9, 0x4973,
+ 0x88f0, 0x1bba,
+ 0x88f1, 0x1bb5,
+ 0x88f2, 0x497a,
+ 0x88f3, 0x0d0a,
+ 0x88f4, 0x0ba2,
+ 0x88f5, 0x497b,
+ 0x88f8, 0x0a8a,
+ 0x88f9, 0x0755,
+ 0x88fa, 0x497e,
+ 0x88fc, 0x1bb7,
+ 0x88fd, 0x26a7,
+ 0x88fe, 0x1bb9,
+ 0x88ff, 0x4980,
+ 0x8900, 0x4981,
+ 0x8902, 0x072c,
+ 0x8903, 0x4983,
+ 0x8907, 0x2676,
+ 0x8908, 0x4987,
+ 0x890a, 0x1bbf,
+ 0x890b, 0x4989,
+ 0x8910, 0x078d,
+ 0x8911, 0x498e,
+ 0x8912, 0x0408,
+ 0x8913, 0x1bbd,
+ 0x8914, 0x498f,
+ 0x8919, 0x1bbc,
+ 0x891a, 0x1bb6,
+ 0x891b, 0x1bbe,
+ 0x891c, 0x4994,
+ 0x8921, 0x1bbb,
+ 0x8922, 0x4999,
+ 0x8925, 0x0cc7,
+ 0x8926, 0x499c,
+ 0x892a, 0x0e7b,
+ 0x892b, 0x1bc1,
+ 0x892c, 0x49a0,
+ 0x8930, 0x1739,
+ 0x8931, 0x49a4,
+ 0x8932, 0x1fe1,
+ 0x8933, 0x25bb,
+ 0x8934, 0x1bc0,
+ 0x8935, 0x49a5,
+ 0x8936, 0x1bc2,
+ 0x8937, 0x49a6,
+ 0x8938, 0x25be,
+ 0x8939, 0x49a7,
+ 0x893b, 0x22dd,
+ 0x893c, 0x49a9,
+ 0x8941, 0x1bc3,
+ 0x8942, 0x49ae,
+ 0x8944, 0x0f52,
+ 0x8945, 0x49b0,
+ 0x8947, 0x25bd,
+ 0x8948, 0x49b2,
+ 0x8956, 0x1e2a,
+ 0x8957, 0x49c0,
+ 0x895d, 0x25bc,
+ 0x895e, 0x1cc3,
+ 0x895f, 0x08c4,
+ 0x8960, 0x25ba,
+ 0x8961, 0x49c6,
+ 0x8964, 0x25bf,
+ 0x8965, 0x49c9,
+ 0x8966, 0x1bc4,
+ 0x8967, 0x49ca,
+ 0x896a, 0x2187,
+ 0x896b, 0x49cd,
+ 0x896c, 0x266b,
+ 0x896d, 0x49ce,
+ 0x896f, 0x1e7f,
+ 0x8970, 0x49d0,
+ 0x8972, 0x21ad,
+ 0x8973, 0x49d2,
+ 0x897b, 0x1bc5,
+ 0x897c, 0x49da,
+ 0x897f, 0x0f06,
+ 0x8980, 0x49dd,
+ 0x8981, 0x1031,
+ 0x8982, 0x49de,
+ 0x8983, 0x1bdf,
+ 0x8984, 0x49df,
+ 0x8986, 0x06ad,
+ 0x8987, 0x49e1,
+ 0x898b, 0x1f96,
+ 0x898c, 0x49e5,
+ 0x898f, 0x1f32,
+ 0x8990, 0x49e8,
+ 0x8993, 0x2084,
+ 0x8994, 0x49eb,
+ 0x8996, 0x2136,
+ 0x8997, 0x49ed,
+ 0x8998, 0x24b8,
+ 0x8999, 0x49ee,
+ 0x89a1, 0x24ba,
+ 0x89a2, 0x49f6,
+ 0x89a6, 0x24bc,
+ 0x89a7, 0x49fa,
+ 0x89aa, 0x20e4,
+ 0x89ab, 0x49fd,
+ 0x89ac, 0x24b9,
+ 0x89ad, 0x49fe,
+ 0x89af, 0x24bd,
+ 0x89b0, 0x4a00,
+ 0x89b2, 0x24be,
+ 0x89b3, 0x4a02,
+ 0x89b7, 0x24bf,
+ 0x89b8, 0x4a06,
+ 0x89ba, 0x1fd2,
+ 0x89bb, 0x4a08,
+ 0x89bd, 0x1ffd,
+ 0x89be, 0x4a0a,
+ 0x89bf, 0x24bb,
+ 0x89c0, 0x1f2d,
+ 0x89c1, 0x086e,
+ 0x89c2, 0x0734,
+ 0x89c3, 0x4a0b,
+ 0x89c4, 0x073f,
+ 0x89c5, 0x0ade,
+ 0x89c6, 0x0d6a,
+ 0x89c7, 0x193a,
+ 0x89c8, 0x09ab,
+ 0x89c9, 0x0924,
+ 0x89ca, 0x193b,
+ 0x89cd, 0x4a0c,
+ 0x89ce, 0x193e,
+ 0x89d2, 0x0898,
+ 0x89d3, 0x4a0d,
+ 0x89d6, 0x1d57,
+ 0x89d7, 0x4a10,
+ 0x89da, 0x1d59,
+ 0x89db, 0x4a13,
+ 0x89dc, 0x1d5a,
+ 0x89dd, 0x4a14,
+ 0x89de, 0x1d58,
+ 0x89df, 0x4a15,
+ 0x89e3, 0x08b3,
+ 0x89e4, 0x4a19,
+ 0x89e5, 0x1d5b,
+ 0x89e6, 0x0528,
+ 0x89e7, 0x4a1a,
+ 0x89eb, 0x1d5c,
+ 0x89ec, 0x4a1e,
+ 0x89ef, 0x1d5d,
+ 0x89f0, 0x4a21,
+ 0x89f3, 0x19c0,
+ 0x89f4, 0x2609,
+ 0x89f5, 0x4a24,
+ 0x89f6, 0x260a,
+ 0x89f7, 0x4a25,
+ 0x89f8, 0x1e94,
+ 0x89f9, 0x4a26,
+ 0x8a00, 0x0ffd,
+ 0x8a01, 0x22df,
+ 0x8a02, 0x1ecb,
+ 0x8a03, 0x1f0d,
+ 0x8a04, 0x4a2d,
+ 0x8a07, 0x12fe,
+ 0x8a08, 0x1f77,
+ 0x8a09, 0x4a30,
+ 0x8a0a, 0x21eb,
+ 0x8a0b, 0x4a31,
+ 0x8a0c, 0x22e1,
+ 0x8a0d, 0x4a32,
+ 0x8a0e, 0x216f,
+ 0x8a0f, 0x4a33,
+ 0x8a10, 0x22e0,
+ 0x8a11, 0x4a34,
+ 0x8a13, 0x21ea,
+ 0x8a14, 0x4a36,
+ 0x8a15, 0x22e2,
+ 0x8a16, 0x20cb,
+ 0x8a17, 0x4a37,
+ 0x8a18, 0x1f78,
+ 0x8a19, 0x4a38,
+ 0x8a1b, 0x1ee2,
+ 0x8a1c, 0x4a3a,
+ 0x8a1d, 0x21f2,
+ 0x8a1e, 0x4a3b,
+ 0x8a1f, 0x2150,
+ 0x8a20, 0x4a3c,
+ 0x8a23, 0x1fd3,
+ 0x8a24, 0x4a3f,
+ 0x8a25, 0x22e5,
+ 0x8a26, 0x4a40,
+ 0x8a2a, 0x1ef2,
+ 0x8a2b, 0x4a44,
+ 0x8a2d, 0x211f,
+ 0x8a2e, 0x4a46,
+ 0x8a31, 0x21dd,
+ 0x8a32, 0x4a49,
+ 0x8a34, 0x2154,
+ 0x8a35, 0x4a4b,
+ 0x8a36, 0x22e7,
+ 0x8a37, 0x4a4c,
+ 0x8a3a, 0x2282,
+ 0x8a3b, 0x4a4f,
+ 0x8a3e, 0x1d5e,
+ 0x8a3f, 0x4a52,
+ 0x8a41, 0x22e6,
+ 0x8a42, 0x4a54,
+ 0x8a46, 0x22e8,
+ 0x8a47, 0x4a58,
+ 0x8a48, 0x1a84,
+ 0x8a49, 0x4a59,
+ 0x8a4e, 0x22e4,
+ 0x8a4f, 0x4a5e,
+ 0x8a50, 0x226a,
+ 0x8a51, 0x4a5f,
+ 0x8a52, 0x22eb,
+ 0x8a53, 0x4a60,
+ 0x8a54, 0x22e9,
+ 0x8a55, 0x20bd,
+ 0x8a56, 0x4a61,
+ 0x8a58, 0x22ea,
+ 0x8a59, 0x4a63,
+ 0x8a5b, 0x22bd,
+ 0x8a5c, 0x4a65,
+ 0x8a5e, 0x1e9e,
+ 0x8a5f, 0x4a67,
+ 0x8a61, 0x22f6,
+ 0x8a62, 0x21e7,
+ 0x8a63, 0x2216,
+ 0x8a64, 0x4a69,
+ 0x8a66, 0x2137,
+ 0x8a67, 0x4a6b,
+ 0x8a69, 0x212c,
+ 0x8a6a, 0x4a6d,
+ 0x8a6b, 0x1e68,
+ 0x8a6c, 0x22f2,
+ 0x8a6d, 0x1f37,
+ 0x8a6e, 0x22f3,
+ 0x8a6f, 0x4a6e,
+ 0x8a70, 0x22ef,
+ 0x8a71, 0x1f50,
+ 0x8a72, 0x1f10,
+ 0x8a73, 0x21c8,
+ 0x8a74, 0x4a6f,
+ 0x8a75, 0x22f1,
+ 0x8a76, 0x4a70,
+ 0x8a79, 0x1153,
+ 0x8a7a, 0x4a73,
+ 0x8a7c, 0x22f0,
+ 0x8a7d, 0x4a75,
+ 0x8a7f, 0x22ee,
+ 0x8a80, 0x4a77,
+ 0x8a84, 0x22ed,
+ 0x8a85, 0x229e,
+ 0x8a86, 0x22ec,
+ 0x8a87, 0x1fe2,
+ 0x8a88, 0x4a7b,
+ 0x8a89, 0x10e3,
+ 0x8a8a, 0x0e2f,
+ 0x8a8b, 0x4a7c,
+ 0x8a8d, 0x20fe,
+ 0x8a8e, 0x4a7e,
+ 0x8a91, 0x22f9,
+ 0x8a93, 0x0d5b,
+ 0x8a94, 0x4a81,
+ 0x8a95, 0x1eaf,
+ 0x8a96, 0x4a82,
+ 0x8a98, 0x2236,
+ 0x8a99, 0x4a84,
+ 0x8a9a, 0x22f7,
+ 0x8a9b, 0x4a85,
+ 0x8a9e, 0x223d,
+ 0x8a9f, 0x4a88,
+ 0x8aa0, 0x1e82,
+ 0x8aa1, 0x1fb6,
+ 0x8aa2, 0x4a89,
+ 0x8aa3, 0x21a4,
+ 0x8aa4, 0x21aa,
+ 0x8aa5, 0x22f8,
+ 0x8aa6, 0x2151,
+ 0x8aa7, 0x4a8a,
+ 0x8aa8, 0x1f60,
+ 0x8aa9, 0x4a8b,
+ 0x8aac, 0x2147,
+ 0x8aad, 0x4a8e,
+ 0x8ab0, 0x2145,
+ 0x8ab1, 0x4a91,
+ 0x8ab2, 0x1fdc,
+ 0x8ab3, 0x4a92,
+ 0x8ab6, 0x2301,
+ 0x8ab7, 0x4a95,
+ 0x8ab9, 0x1ef5,
+ 0x8aba, 0x4a97,
+ 0x8abc, 0x2218,
+ 0x8abd, 0x4a99,
+ 0x8abf, 0x1ec6,
+ 0x8ac0, 0x4a9b,
+ 0x8ac2, 0x2300,
+ 0x8ac3, 0x4a9d,
+ 0x8ac4, 0x22b4,
+ 0x8ac5, 0x4a9e,
+ 0x8ac7, 0x2169,
+ 0x8ac8, 0x4aa0,
+ 0x8ac9, 0x22fd,
+ 0x8aca, 0x4aa1,
+ 0x8acb, 0x20ea,
+ 0x8acc, 0x4aa2,
+ 0x8acd, 0x22f4,
+ 0x8ace, 0x4aa3,
+ 0x8acf, 0x22fb,
+ 0x8ad0, 0x4aa4,
+ 0x8ad1, 0x22fc,
+ 0x8ad2, 0x2027,
+ 0x8ad3, 0x4aa5,
+ 0x8ad6, 0x2060,
+ 0x8ad7, 0x22ff,
+ 0x8ad8, 0x4aa8,
+ 0x8adb, 0x22fe,
+ 0x8adc, 0x1ec7,
+ 0x8add, 0x4aab,
+ 0x8ade, 0x230c,
+ 0x8adf, 0x4aac,
+ 0x8ae2, 0x22f5,
+ 0x8ae3, 0x4aaf,
+ 0x8ae4, 0x2306,
+ 0x8ae5, 0x4ab0,
+ 0x8ae6, 0x230a,
+ 0x8ae7, 0x21d3,
+ 0x8ae8, 0x4ab1,
+ 0x8aeb, 0x2303,
+ 0x8aec, 0x4ab4,
+ 0x8aed, 0x2307,
+ 0x8aee, 0x230b,
+ 0x8aef, 0x4ab5,
+ 0x8af1, 0x1f5f,
+ 0x8af2, 0x4ab7,
+ 0x8af3, 0x2309,
+ 0x8af4, 0x4ab8,
+ 0x8af6, 0x2302,
+ 0x8af7, 0x1f04,
+ 0x8af8, 0x229d,
+ 0x8af9, 0x4aba,
+ 0x8afa, 0x21fb,
+ 0x8afb, 0x4abb,
+ 0x8afc, 0x2308,
+ 0x8afd, 0x4abc,
+ 0x8afe, 0x20ac,
+ 0x8aff, 0x4abd,
+ 0x8b00, 0x208e,
+ 0x8b01, 0x2305,
+ 0x8b02, 0x2197,
+ 0x8b03, 0x4abe,
+ 0x8b04, 0x2171,
+ 0x8b05, 0x2298,
+ 0x8b06, 0x4abf,
+ 0x8b07, 0x173c,
+ 0x8b08, 0x4ac0,
+ 0x8b0a, 0x1f57,
+ 0x8b0b, 0x4ac2,
+ 0x8b0e, 0x2082,
+ 0x8b0f, 0x4ac5,
+ 0x8b10, 0x2311,
+ 0x8b11, 0x4ac6,
+ 0x8b14, 0x2304,
+ 0x8b15, 0x4ac9,
+ 0x8b16, 0x230f,
+ 0x8b17, 0x1e35,
+ 0x8b18, 0x4aca,
+ 0x8b19, 0x20d1,
+ 0x8b1a, 0x2310,
+ 0x8b1b, 0x1fa3,
+ 0x8b1c, 0x4acb,
+ 0x8b1d, 0x21d6,
+ 0x8b1e, 0x4acc,
+ 0x8b21, 0x2206,
+ 0x8b22, 0x4acf,
+ 0x8b26, 0x1d5f,
+ 0x8b27, 0x4ad3,
+ 0x8b28, 0x230d,
+ 0x8b29, 0x4ad4,
+ 0x8b2b, 0x2312,
+ 0x8b2c, 0x208d,
+ 0x8b2d, 0x2313,
+ 0x8b2e, 0x4ad6,
+ 0x8b33, 0x22e3,
+ 0x8b34, 0x4adb,
+ 0x8b39, 0x1fba,
+ 0x8b3a, 0x4ae0,
+ 0x8b3e, 0x2078,
+ 0x8b3f, 0x4ae4,
+ 0x8b49, 0x2288,
+ 0x8b4a, 0x4aee,
+ 0x8b4e, 0x2316,
+ 0x8b4f, 0x1f6b,
+ 0x8b50, 0x4af2,
+ 0x8b56, 0x2314,
+ 0x8b57, 0x4af8,
+ 0x8b58, 0x2130,
+ 0x8b59, 0x2315,
+ 0x8b5a, 0x2168,
+ 0x8b5b, 0x4af9,
+ 0x8b5c, 0x20c4,
+ 0x8b5d, 0x4afa,
+ 0x8b66, 0x08de,
+ 0x8b67, 0x4b03,
+ 0x8b6b, 0x2318,
+ 0x8b6c, 0x0bc8,
+ 0x8b6d, 0x4b07,
+ 0x8b6f, 0x2219,
+ 0x8b70, 0x2217,
+ 0x8b71, 0x4b09,
+ 0x8b74, 0x20d5,
+ 0x8b75, 0x4b0c,
+ 0x8b77, 0x1f4a,
+ 0x8b78, 0x4b0e,
+ 0x8b7d, 0x2240,
+ 0x8b7e, 0x4b13,
+ 0x8b80, 0x1ed3,
+ 0x8b81, 0x4b15,
+ 0x8b8a, 0x1e49,
+ 0x8b8b, 0x4b1e,
+ 0x8b8e, 0x261b,
+ 0x8b8f, 0x4b21,
+ 0x8b92, 0x1e6d,
+ 0x8b93, 0x20f8,
+ 0x8b94, 0x4b24,
+ 0x8b95, 0x1ffb,
+ 0x8b96, 0x2319,
+ 0x8b97, 0x4b25,
+ 0x8b9c, 0x230e,
+ 0x8b9d, 0x4b2a,
+ 0x8b9e, 0x2317,
+ 0x8b9f, 0x4b2b,
+ 0x8ba0, 0x1317,
+ 0x8ba1, 0x0839,
+ 0x8ba2, 0x05e8,
+ 0x8ba3, 0x06b7,
+ 0x8ba4, 0x0caa,
+ 0x8ba5, 0x0818,
+ 0x8ba6, 0x1318,
+ 0x8ba8, 0x0e29,
+ 0x8ba9, 0x0c9e,
+ 0x8baa, 0x131a,
+ 0x8bab, 0x0c1c,
+ 0x8bac, 0x4b2c,
+ 0x8bad, 0x0fde,
+ 0x8bae, 0x1070,
+ 0x8baf, 0x0fdf,
+ 0x8bb0, 0x083a,
+ 0x8bb1, 0x4b2d,
+ 0x8bb2, 0x0883,
+ 0x8bb3, 0x07f9,
+ 0x8bb4, 0x131b,
+ 0x8bb6, 0x0ff1,
+ 0x8bb7, 0x131d,
+ 0x8bb8, 0x0fb8,
+ 0x8bb9, 0x062e,
+ 0x8bba, 0x0a82,
+ 0x8bbb, 0x4b2e,
+ 0x8bbc, 0x0dc4,
+ 0x8bbd, 0x068a,
+ 0x8bbe, 0x0d21,
+ 0x8bbf, 0x0660,
+ 0x8bc0, 0x0926,
+ 0x8bc1, 0x11a3,
+ 0x8bc2, 0x131e,
+ 0x8bc4, 0x0bdf,
+ 0x8bc5, 0x1244,
+ 0x8bc6, 0x0d4d,
+ 0x8bc7, 0x4b2f,
+ 0x8bc8, 0x114a,
+ 0x8bc9, 0x0dd4,
+ 0x8bca, 0x1190,
+ 0x8bcb, 0x1320,
+ 0x8bcc, 0x11de,
+ 0x8bcd, 0x054d,
+ 0x8bce, 0x1322,
+ 0x8bcf, 0x1321,
+ 0x8bd0, 0x4b30,
+ 0x8bd1, 0x1072,
+ 0x8bd2, 0x1323,
+ 0x8bd5, 0x0d6b,
+ 0x8bd6, 0x1326,
+ 0x8bd7, 0x0d42,
+ 0x8bd8, 0x1327,
+ 0x8bda, 0x04f4,
+ 0x8bdb, 0x11ee,
+ 0x8bdc, 0x1329,
+ 0x8bdd, 0x07c5,
+ 0x8bde, 0x058f,
+ 0x8bdf, 0x132a,
+ 0x8be1, 0x0747,
+ 0x8be2, 0x0fd8,
+ 0x8be3, 0x106f,
+ 0x8be4, 0x132c,
+ 0x8be5, 0x06be,
+ 0x8be6, 0x0f57,
+ 0x8be7, 0x04b6,
+ 0x8be8, 0x132d,
+ 0x8bea, 0x4b31,
+ 0x8beb, 0x08bc,
+ 0x8bec, 0x0eeb,
+ 0x8bed, 0x10d4,
+ 0x8bee, 0x132f,
+ 0x8bef, 0x0f02,
+ 0x8bf0, 0x1330,
+ 0x8bf1, 0x10ba,
+ 0x8bf2, 0x07fa,
+ 0x8bf3, 0x1331,
+ 0x8bf4, 0x0daa,
+ 0x8bf5, 0x0dc5,
+ 0x8bf6, 0x1332,
+ 0x8bf7, 0x0c68,
+ 0x8bf8, 0x11ed,
+ 0x8bf9, 0x1333,
+ 0x8bfa, 0x0b76,
+ 0x8bfb, 0x0600,
+ 0x8bfc, 0x1334,
+ 0x8bfd, 0x0669,
+ 0x8bfe, 0x095b,
+ 0x8bff, 0x1335,
+ 0x8c00, 0x1336,
+ 0x8c01, 0x0da2,
+ 0x8c02, 0x1337,
+ 0x8c03, 0x05d8,
+ 0x8c04, 0x1338,
+ 0x8c05, 0x0a0b,
+ 0x8c06, 0x1218,
+ 0x8c07, 0x1339,
+ 0x8c08, 0x0e0b,
+ 0x8c09, 0x4b32,
+ 0x8c0a, 0x1071,
+ 0x8c0b, 0x0b14,
+ 0x8c0c, 0x133a,
+ 0x8c0d, 0x05de,
+ 0x8c0e, 0x07e6,
+ 0x8c0f, 0x133b,
+ 0x8c10, 0x0f7e,
+ 0x8c11, 0x133c,
+ 0x8c13, 0x0ecc,
+ 0x8c14, 0x133e,
+ 0x8c17, 0x04be,
+ 0x8c18, 0x1343,
+ 0x8c19, 0x1341,
+ 0x8c1a, 0x1011,
+ 0x8c1b, 0x1342,
+ 0x8c1c, 0x0ada,
+ 0x8c1d, 0x1344,
+ 0x8c1e, 0x4b33,
+ 0x8c1f, 0x1345,
+ 0x8c22, 0x0f86,
+ 0x8c23, 0x102c,
+ 0x8c24, 0x0404,
+ 0x8c25, 0x1348,
+ 0x8c26, 0x0c28,
+ 0x8c27, 0x1349,
+ 0x8c28, 0x08c8,
+ 0x8c29, 0x0aa6,
+ 0x8c2a, 0x134a,
+ 0x8c2c, 0x0b02,
+ 0x8c2d, 0x0e0a,
+ 0x8c2e, 0x134c,
+ 0x8c30, 0x09a9,
+ 0x8c31, 0x0bf6,
+ 0x8c32, 0x134e,
+ 0x8c34, 0x0c31,
+ 0x8c35, 0x1350,
+ 0x8c37, 0x0721,
+ 0x8c38, 0x4b34,
+ 0x8c41, 0x0802,
+ 0x8c42, 0x4b3d,
+ 0x8c46, 0x05f8,
+ 0x8c47, 0x1cf6,
+ 0x8c48, 0x20c8,
+ 0x8c49, 0x1cf7,
+ 0x8c4a, 0x4b41,
+ 0x8c4c, 0x0e94,
+ 0x8c4d, 0x4b43,
+ 0x8c50, 0x1efd,
+ 0x8c51, 0x4b46,
+ 0x8c55, 0x1d15,
+ 0x8c56, 0x4b4a,
+ 0x8c5a, 0x1990,
+ 0x8c5b, 0x4b4e,
+ 0x8c61, 0x0f60,
+ 0x8c62, 0x07d4,
+ 0x8c63, 0x4b54,
+ 0x8c6a, 0x0777,
+ 0x8c6b, 0x10e8,
+ 0x8c6c, 0x4b5b,
+ 0x8c73, 0x15dd,
+ 0x8c74, 0x4b62,
+ 0x8c78, 0x1d50,
+ 0x8c79, 0x0413,
+ 0x8c7a, 0x04b9,
+ 0x8c7b, 0x4b66,
+ 0x8c82, 0x1d51,
+ 0x8c83, 0x4b6d,
+ 0x8c85, 0x1d53,
+ 0x8c86, 0x4b6f,
+ 0x8c89, 0x0788,
+ 0x8c8a, 0x1d52,
+ 0x8c8b, 0x4b72,
+ 0x8c8c, 0x0ab7,
+ 0x8c8d, 0x4b73,
+ 0x8c94, 0x1d55,
+ 0x8c95, 0x4b7a,
+ 0x8c98, 0x1d54,
+ 0x8c99, 0x4b7d,
+ 0x8c9d, 0x1e3b,
+ 0x8c9e, 0x227f,
+ 0x8c9f, 0x4b81,
+ 0x8ca0, 0x1f0c,
+ 0x8ca1, 0x1e59,
+ 0x8ca2, 0x1f24,
+ 0x8ca3, 0x4b82,
+ 0x8ca7, 0x20ba,
+ 0x8ca8, 0x1f65,
+ 0x8ca9, 0x1ef0,
+ 0x8caa, 0x2164,
+ 0x8cab, 0x1f30,
+ 0x8cac, 0x2261,
+ 0x8cad, 0x4b86,
+ 0x8caf, 0x22a2,
+ 0x8cb0, 0x24ab,
+ 0x8cb1, 0x4b88,
+ 0x8cb2, 0x24af,
+ 0x8cb3, 0x1ee8,
+ 0x8cb4, 0x1f39,
+ 0x8cb5, 0x4b89,
+ 0x8cb6, 0x1e48,
+ 0x8cb7, 0x2070,
+ 0x8cb8, 0x1ea8,
+ 0x8cb9, 0x4b8a,
+ 0x8cba, 0x24ac,
+ 0x8cbb, 0x1ef7,
+ 0x8cbc, 0x2176,
+ 0x8cbd, 0x24ad,
+ 0x8cbe, 0x4b8b,
+ 0x8cbf, 0x207b,
+ 0x8cc0, 0x1f45,
+ 0x8cc1, 0x24aa,
+ 0x8cc2, 0x204b,
+ 0x8cc3, 0x202f,
+ 0x8cc4, 0x1f5a,
+ 0x8cc5, 0x24b0,
+ 0x8cc6, 0x4b8c,
+ 0x8cc7, 0x22b7,
+ 0x8cc8, 0x1f7f,
+ 0x8cc9, 0x4b8d,
+ 0x8cca, 0x2265,
+ 0x8ccb, 0x4b8e,
+ 0x8cd1, 0x24b2,
+ 0x8cd2, 0x211b,
+ 0x8cd3, 0x1e51,
+ 0x8cd4, 0x4b94,
+ 0x8cd5, 0x24b4,
+ 0x8cd6, 0x4b95,
+ 0x8cda, 0x24b3,
+ 0x8cdb, 0x4b99,
+ 0x8cdc, 0x1e9f,
+ 0x8cdd, 0x4b9a,
+ 0x8cde, 0x2118,
+ 0x8cdf, 0x4b9b,
+ 0x8ce0, 0x20b4,
+ 0x8ce1, 0x23af,
+ 0x8ce2, 0x21bb,
+ 0x8ce3, 0x2072,
+ 0x8ce4, 0x1f95,
+ 0x8ce5, 0x4b9c,
+ 0x8ce6, 0x1f0a,
+ 0x8ce7, 0x24b6,
+ 0x8ce8, 0x4b9d,
+ 0x8cea, 0x2291,
+ 0x8ceb, 0x24b5,
+ 0x8cec, 0x2278,
+ 0x8ced, 0x1ed4,
+ 0x8cee, 0x4b9f,
+ 0x8cf4, 0x1ff3,
+ 0x8cf5, 0x4ba5,
+ 0x8cfa, 0x22a9,
+ 0x8cfb, 0x24b7,
+ 0x8cfc, 0x1f28,
+ 0x8cfd, 0x2109,
+ 0x8cfe, 0x22c7,
+ 0x8cff, 0x4baa,
+ 0x8d00, 0x4bab,
+ 0x8d04, 0x24ae,
+ 0x8d05, 0x22b1,
+ 0x8d06, 0x4baf,
+ 0x8d08, 0x2266,
+ 0x8d09, 0x4bb1,
+ 0x8d0a, 0x225b,
+ 0x8d0b, 0x22c4,
+ 0x8d0c, 0x4bb2,
+ 0x8d0d, 0x2115,
+ 0x8d0e, 0x4bb3,
+ 0x8d0f, 0x222a,
+ 0x8d10, 0x24b1,
+ 0x8d11, 0x4bb4,
+ 0x8d16, 0x213d,
+ 0x8d17, 0x4bb9,
+ 0x8d1b, 0x1f15,
+ 0x8d1c, 0x225c,
+ 0x8d1d, 0x041d,
+ 0x8d1e, 0x118b,
+ 0x8d1f, 0x06b5,
+ 0x8d20, 0x4bbd,
+ 0x8d21, 0x070a,
+ 0x8d22, 0x048d,
+ 0x8d23, 0x1133,
+ 0x8d24, 0x0f3a,
+ 0x8d25, 0x03e7,
+ 0x8d26, 0x116c,
+ 0x8d27, 0x080a,
+ 0x8d28, 0x11c9,
+ 0x8d29, 0x0654,
+ 0x8d2a, 0x0e03,
+ 0x8d2b, 0x0bd5,
+ 0x8d2c, 0x044a,
+ 0x8d2d, 0x0713,
+ 0x8d2e, 0x11fb,
+ 0x8d2f, 0x073a,
+ 0x8d30, 0x063e,
+ 0x8d31, 0x086d,
+ 0x8d32, 0x192c,
+ 0x8d34, 0x0e4c,
+ 0x8d35, 0x074c,
+ 0x8d36, 0x192e,
+ 0x8d37, 0x057e,
+ 0x8d38, 0x0ab8,
+ 0x8d39, 0x066e,
+ 0x8d3a, 0x078f,
+ 0x8d3b, 0x192f,
+ 0x8d3c, 0x1137,
+ 0x8d3d, 0x1930,
+ 0x8d3e, 0x0849,
+ 0x8d3f, 0x07f4,
+ 0x8d40, 0x1931,
+ 0x8d41, 0x0a27,
+ 0x8d42, 0x0a5f,
+ 0x8d43, 0x1122,
+ 0x8d44, 0x1227,
+ 0x8d45, 0x1932,
+ 0x8d47, 0x1936,
+ 0x8d48, 0x1934,
+ 0x8d4a, 0x0d17,
+ 0x8d4b, 0x06ae,
+ 0x8d4c, 0x0603,
+ 0x8d4d, 0x1937,
+ 0x8d4e, 0x0d81,
+ 0x8d4f, 0x0d06,
+ 0x8d50, 0x0550,
+ 0x8d51, 0x4bbe,
+ 0x8d53, 0x163b,
+ 0x8d54, 0x0ba3,
+ 0x8d55, 0x1938,
+ 0x8d56, 0x09a0,
+ 0x8d57, 0x4bc0,
+ 0x8d58, 0x1215,
+ 0x8d59, 0x1939,
+ 0x8d5a, 0x1209,
+ 0x8d5b, 0x0cd7,
+ 0x8d5c, 0x1289,
+ 0x8d5d, 0x1283,
+ 0x8d5e, 0x1121,
+ 0x8d5f, 0x4bc1,
+ 0x8d60, 0x113c,
+ 0x8d61, 0x0cfd,
+ 0x8d62, 0x1093,
+ 0x8d63, 0x06ce,
+ 0x8d64, 0x0505,
+ 0x8d65, 0x4bc2,
+ 0x8d66, 0x0d1b,
+ 0x8d67, 0x1cf4,
+ 0x8d68, 0x4bc3,
+ 0x8d6b, 0x078c,
+ 0x8d6c, 0x4bc6,
+ 0x8d6d, 0x1cf5,
+ 0x8d6e, 0x4bc7,
+ 0x8d70, 0x123c,
+ 0x8d71, 0x4bc9,
+ 0x8d73, 0x1cef,
+ 0x8d74, 0x06ab,
+ 0x8d75, 0x1175,
+ 0x8d76, 0x06ca,
+ 0x8d77, 0x0c0f,
+ 0x8d78, 0x4bcb,
+ 0x8d81, 0x04e8,
+ 0x8d82, 0x4bd4,
+ 0x8d84, 0x1cf0,
+ 0x8d85, 0x04d1,
+ 0x8d86, 0x4bd6,
+ 0x8d8a, 0x1100,
+ 0x8d8b, 0x0c74,
+ 0x8d8c, 0x4bda,
+ 0x8d91, 0x1cf2,
+ 0x8d92, 0x4bdf,
+ 0x8d94, 0x1cf1,
+ 0x8d95, 0x1f14,
+ 0x8d96, 0x4be1,
+ 0x8d99, 0x227a,
+ 0x8d9a, 0x4be4,
+ 0x8d9f, 0x0e1e,
+ 0x8da0, 0x4be9,
+ 0x8da3, 0x0c7f,
+ 0x8da4, 0x4bec,
+ 0x8da8, 0x20ee,
+ 0x8da9, 0x4bf0,
+ 0x8db1, 0x1cf3,
+ 0x8db2, 0x25f8,
+ 0x8db3, 0x1240,
+ 0x8db4, 0x0b80,
+ 0x8db5, 0x1d1c,
+ 0x8db6, 0x4bf8,
+ 0x8db8, 0x1d17,
+ 0x8db9, 0x4bfa,
+ 0x8dba, 0x1d1f,
+ 0x8dbb, 0x4bfb,
+ 0x8dbc, 0x1d1e,
+ 0x8dbd, 0x4bfc,
+ 0x8dbe, 0x11b9,
+ 0x8dbf, 0x1d1d,
+ 0x8dc0, 0x4bfd,
+ 0x8dc3, 0x1101,
+ 0x8dc4, 0x1d20,
+ 0x8dc5, 0x4c00,
+ 0x8dc6, 0x1d28,
+ 0x8dc7, 0x4c01,
+ 0x8dcb, 0x03da,
+ 0x8dcc, 0x05d9,
+ 0x8dcd, 0x4c05,
+ 0x8dce, 0x1d25,
+ 0x8dd0, 0x4c06,
+ 0x8dd1, 0x0b9d,
+ 0x8dd2, 0x4c07,
+ 0x8dd6, 0x1d21,
+ 0x8dd8, 0x4c0b,
+ 0x8dda, 0x1d23,
+ 0x8ddb, 0x1d27,
+ 0x8ddc, 0x4c0d,
+ 0x8ddd, 0x090f,
+ 0x8dde, 0x1d24,
+ 0x8ddf, 0x06f5,
+ 0x8de0, 0x4c0e,
+ 0x8de3, 0x1d2c,
+ 0x8de4, 0x1d2f,
+ 0x8de5, 0x4c11,
+ 0x8de8, 0x0974,
+ 0x8de9, 0x4c14,
+ 0x8dea, 0x074b,
+ 0x8deb, 0x1d18,
+ 0x8dec, 0x1d29,
+ 0x8ded, 0x4c15,
+ 0x8def, 0x0a5e,
+ 0x8df0, 0x4c17,
+ 0x8df3, 0x0e4b,
+ 0x8df4, 0x4c1a,
+ 0x8df5, 0x086c,
+ 0x8df6, 0x4c1b,
+ 0x8df7, 0x1d2a,
+ 0x8df9, 0x1d2d,
+ 0x8dfa, 0x0624,
+ 0x8dfb, 0x1d2e,
+ 0x8dfc, 0x4c1c,
+ 0x8dfd, 0x1d31,
+ 0x8dfe, 0x4c1d,
+ 0x8e00, 0x4c1f,
+ 0x8e05, 0x1d19,
+ 0x8e06, 0x4c24,
+ 0x8e09, 0x1d30,
+ 0x8e0a, 0x10a0,
+ 0x8e0b, 0x4c27,
+ 0x8e0c, 0x0511,
+ 0x8e0d, 0x4c28,
+ 0x8e0f, 0x0df7,
+ 0x8e10, 0x1f94,
+ 0x8e11, 0x4c2a,
+ 0x8e14, 0x1d32,
+ 0x8e15, 0x4c2d,
+ 0x8e1d, 0x1d33,
+ 0x8e1e, 0x0910,
+ 0x8e1f, 0x1d34,
+ 0x8e20, 0x4c35,
+ 0x8e22, 0x0e32,
+ 0x8e23, 0x1d37,
+ 0x8e24, 0x4c37,
+ 0x8e29, 0x048f,
+ 0x8e2a, 0x1236,
+ 0x8e2b, 0x4c3c,
+ 0x8e2c, 0x1d35,
+ 0x8e2d, 0x4c3d,
+ 0x8e2e, 0x1d36,
+ 0x8e2f, 0x1d38,
+ 0x8e30, 0x4c3e,
+ 0x8e31, 0x1d3e,
+ 0x8e32, 0x4c3f,
+ 0x8e34, 0x2230,
+ 0x8e35, 0x1d3c,
+ 0x8e36, 0x4c41,
+ 0x8e39, 0x1d3b,
+ 0x8e3a, 0x1d39,
+ 0x8e3b, 0x4c44,
+ 0x8e3d, 0x1d3d,
+ 0x8e3e, 0x4c46,
+ 0x8e40, 0x1d3a,
+ 0x8e41, 0x1d40,
+ 0x8e43, 0x4c48,
+ 0x8e44, 0x0e36,
+ 0x8e45, 0x4c49,
+ 0x8e47, 0x173b,
+ 0x8e48, 0x0599,
+ 0x8e49, 0x1d3f,
+ 0x8e4a, 0x1d44,
+ 0x8e4b, 0x0df6,
+ 0x8e4c, 0x25fd,
+ 0x8e4d, 0x4c4b,
+ 0x8e51, 0x1d42,
+ 0x8e53, 0x4c4f,
+ 0x8e55, 0x2600,
+ 0x8e56, 0x4c51,
+ 0x8e59, 0x1d1a,
+ 0x8e5a, 0x4c54,
+ 0x8e63, 0x2606,
+ 0x8e64, 0x4c5d,
+ 0x8e66, 0x042d,
+ 0x8e67, 0x4c5f,
+ 0x8e69, 0x1d1b,
+ 0x8e6a, 0x4c61,
+ 0x8e6c, 0x05a6,
+ 0x8e6d, 0x04ab,
+ 0x8e6e, 0x4c63,
+ 0x8e6f, 0x1d48,
+ 0x8e70, 0x1d45,
+ 0x8e71, 0x4c64,
+ 0x8e72, 0x0616,
+ 0x8e73, 0x4c65,
+ 0x8e74, 0x1d49,
+ 0x8e75, 0x4c66,
+ 0x8e76, 0x1d46,
+ 0x8e77, 0x4c67,
+ 0x8e7a, 0x25ff,
+ 0x8e7b, 0x4c6a,
+ 0x8e7c, 0x1d47,
+ 0x8e7d, 0x4c6b,
+ 0x8e7f, 0x055d,
+ 0x8e80, 0x4c6d,
+ 0x8e81, 0x112d,
+ 0x8e82, 0x4c6e,
+ 0x8e85, 0x1d4a,
+ 0x8e86, 0x4c71,
+ 0x8e87, 0x051e,
+ 0x8e88, 0x4c72,
+ 0x8e89, 0x25fc,
+ 0x8e8a, 0x1e8c,
+ 0x8e8b, 0x2602,
+ 0x8e8c, 0x4c73,
+ 0x8e8d, 0x224d,
+ 0x8e8e, 0x4c74,
+ 0x8e8f, 0x1d4b,
+ 0x8e90, 0x1d4d,
+ 0x8e91, 0x2604,
+ 0x8e92, 0x25fe,
+ 0x8e93, 0x2603,
+ 0x8e94, 0x1d4c,
+ 0x8e95, 0x4c75,
+ 0x8e9a, 0x2601,
+ 0x8e9b, 0x4c7a,
+ 0x8e9c, 0x1d4e,
+ 0x8e9d, 0x4c7b,
+ 0x8e9e, 0x1d4f,
+ 0x8e9f, 0x4c7c,
+ 0x8ea1, 0x2605,
+ 0x8ea2, 0x4c7e,
+ 0x8ea5, 0x1ea3,
+ 0x8ea6, 0x2608,
+ 0x8ea7, 0x4c81,
+ 0x8eaa, 0x2607,
+ 0x8eab, 0x0d26,
+ 0x8eac, 0x0703,
+ 0x8ead, 0x4c84,
+ 0x8eaf, 0x0c78,
+ 0x8eb0, 0x4c86,
+ 0x8eb2, 0x0622,
+ 0x8eb3, 0x4c88,
+ 0x8eba, 0x0e1c,
+ 0x8ebb, 0x4c8f,
+ 0x8ec0, 0x20f0,
+ 0x8ec1, 0x4c94,
+ 0x8eca, 0x1e7b,
+ 0x8ecb, 0x2267,
+ 0x8ecc, 0x1f36,
+ 0x8ecd, 0x1fd6,
+ 0x8ece, 0x18f8,
+ 0x8ecf, 0x4c9d,
+ 0x8ed2, 0x21e0,
+ 0x8ed3, 0x4ca0,
+ 0x8ed4, 0x248c,
+ 0x8ed5, 0x4ca1,
+ 0x8edb, 0x248d,
+ 0x8edc, 0x4ca7,
+ 0x8edf, 0x2102,
+ 0x8ee0, 0x4caa,
+ 0x8ee4, 0x2494,
+ 0x8ee5, 0x4cae,
+ 0x8eeb, 0x2493,
+ 0x8eec, 0x4cb4,
+ 0x8ef2, 0x248e,
+ 0x8ef3, 0x4cba,
+ 0x8ef8, 0x2299,
+ 0x8ef9, 0x2491,
+ 0x8efa, 0x2496,
+ 0x8efb, 0x248f,
+ 0x8efc, 0x2492,
+ 0x8efd, 0x4cbf,
+ 0x8efe, 0x2497,
+ 0x8eff, 0x4cc0,
+ 0x8f00, 0x4cc1,
+ 0x8f03, 0x1fb1,
+ 0x8f04, 0x4cc4,
+ 0x8f05, 0x249a,
+ 0x8f06, 0x4cc5,
+ 0x8f07, 0x2499,
+ 0x8f08, 0x4cc6,
+ 0x8f09, 0x2258,
+ 0x8f0a, 0x2498,
+ 0x8f0b, 0x4cc7,
+ 0x8f12, 0x249b,
+ 0x8f13, 0x4cce,
+ 0x8f14, 0x1f09,
+ 0x8f15, 0x20e6,
+ 0x8f16, 0x4ccf,
+ 0x8f1b, 0x2026,
+ 0x8f1c, 0x249f,
+ 0x8f1d, 0x1f59,
+ 0x8f1e, 0x249d,
+ 0x8f20, 0x4cd4,
+ 0x8f25, 0x1f3b,
+ 0x8f26, 0x249c,
+ 0x8f27, 0x4cd9,
+ 0x8f29, 0x1e3a,
+ 0x8f2a, 0x205b,
+ 0x8f2b, 0x4cdb,
+ 0x8f2f, 0x1f70,
+ 0x8f30, 0x4cdf,
+ 0x8f33, 0x24a0,
+ 0x8f34, 0x4ce2,
+ 0x8f38, 0x213b,
+ 0x8f39, 0x4ce6,
+ 0x8f3b, 0x1f07,
+ 0x8f3c, 0x4ce8,
+ 0x8f3e, 0x2270,
+ 0x8f3f, 0x2237,
+ 0x8f40, 0x4cea,
+ 0x8f42, 0x24d2,
+ 0x8f43, 0x4cec,
+ 0x8f44, 0x21b3,
+ 0x8f45, 0x2245,
+ 0x8f46, 0x24a1,
+ 0x8f47, 0x4ced,
+ 0x8f49, 0x22a8,
+ 0x8f4a, 0x4cef,
+ 0x8f4d, 0x227c,
+ 0x8f4e, 0x1fb0,
+ 0x8f4f, 0x4cf2,
+ 0x8f54, 0x24a2,
+ 0x8f55, 0x4cf7,
+ 0x8f5f, 0x1f46,
+ 0x8f60, 0x4d01,
+ 0x8f61, 0x2380,
+ 0x8f62, 0x2495,
+ 0x8f63, 0x4d02,
+ 0x8f64, 0x2490,
+ 0x8f65, 0x4d03,
+ 0x8f66, 0x04da,
+ 0x8f67, 0x1141,
+ 0x8f68, 0x0745,
+ 0x8f69, 0x0fc4,
+ 0x8f6a, 0x4d04,
+ 0x8f6b, 0x18e1,
+ 0x8f6c, 0x1207,
+ 0x8f6d, 0x18e2,
+ 0x8f6e, 0x0a7d,
+ 0x8f6f, 0x0cc8,
+ 0x8f70, 0x079b,
+ 0x8f71, 0x18e3,
+ 0x8f74, 0x11e0,
+ 0x8f75, 0x18e6,
+ 0x8f77, 0x18e9,
+ 0x8f78, 0x18e8,
+ 0x8f79, 0x18ea,
+ 0x8f7b, 0x0c5e,
+ 0x8f7c, 0x18ec,
+ 0x8f7d, 0x111b,
+ 0x8f7e, 0x18ed,
+ 0x8f7f, 0x089f,
+ 0x8f80, 0x4d05,
+ 0x8f81, 0x18ee,
+ 0x8f83, 0x08a0,
+ 0x8f84, 0x18f0,
+ 0x8f85, 0x06a3,
+ 0x8f86, 0x0a07,
+ 0x8f87, 0x18f1,
+ 0x8f88, 0x041b,
+ 0x8f89, 0x07e9,
+ 0x8f8a, 0x074e,
+ 0x8f8b, 0x18f2,
+ 0x8f8c, 0x4d06,
+ 0x8f8d, 0x18f3,
+ 0x8f90, 0x0695,
+ 0x8f91, 0x0820,
+ 0x8f92, 0x4d07,
+ 0x8f93, 0x0d7b,
+ 0x8f94, 0x1574,
+ 0x8f95, 0x10f2,
+ 0x8f96, 0x0f2a,
+ 0x8f97, 0x1158,
+ 0x8f98, 0x18f6,
+ 0x8f99, 0x117f,
+ 0x8f9a, 0x18f7,
+ 0x8f9b, 0x0f8c,
+ 0x8f9c, 0x0715,
+ 0x8f9d, 0x4d08,
+ 0x8f9e, 0x054a,
+ 0x8f9f, 0x0442,
+ 0x8fa0, 0x4d09,
+ 0x8fa3, 0x099c,
+ 0x8fa4, 0x4d0c,
+ 0x8fa6, 0x1e30,
+ 0x8fa7, 0x4d0e,
+ 0x8fa8, 0x044f,
+ 0x8faa, 0x4d0f,
+ 0x8fab, 0x0451,
+ 0x8fac, 0x4d10,
+ 0x8fad, 0x1e9d,
+ 0x8fae, 0x1e4b,
+ 0x8faf, 0x1e4a,
+ 0x8fb0, 0x04e2,
+ 0x8fb1, 0x0cc3,
+ 0x8fb2, 0x20aa,
+ 0x8fb3, 0x4d11,
+ 0x8fb6, 0x173d,
+ 0x8fb7, 0x4d14,
+ 0x8fb9, 0x0448,
+ 0x8fba, 0x4d16,
+ 0x8fbd, 0x0a12,
+ 0x8fbe, 0x0572,
+ 0x8fbf, 0x4d19,
+ 0x8fc1, 0x0c25,
+ 0x8fc2, 0x10bd,
+ 0x8fc3, 0x4d1b,
+ 0x8fc4, 0x0c18,
+ 0x8fc5, 0x0fe1,
+ 0x8fc6, 0x4d1c,
+ 0x8fc7, 0x0756,
+ 0x8fc8, 0x0a9c,
+ 0x8fc9, 0x4d1d,
+ 0x8fce, 0x1092,
+ 0x8fcf, 0x4d22,
+ 0x8fd0, 0x110e,
+ 0x8fd1, 0x08cd,
+ 0x8fd2, 0x4d23,
+ 0x8fd3, 0x173e,
+ 0x8fd4, 0x0652,
+ 0x8fd5, 0x173f,
+ 0x8fd6, 0x4d24,
+ 0x8fd8, 0x07ce,
+ 0x8fd9, 0x1183,
+ 0x8fda, 0x4d26,
+ 0x8fdb, 0x08c9,
+ 0x8fdc, 0x10f9,
+ 0x8fdd, 0x0eb4,
+ 0x8fde, 0x09f5,
+ 0x8fdf, 0x04fe,
+ 0x8fe0, 0x4d27,
+ 0x8fe2, 0x0e49,
+ 0x8fe3, 0x4d29,
+ 0x8fe4, 0x1742,
+ 0x8fe5, 0x1740,
+ 0x8fe6, 0x1744,
+ 0x8fe7, 0x4d2a,
+ 0x8fe8, 0x1746,
+ 0x8fe9, 0x1743,
+ 0x8fea, 0x05b0,
+ 0x8feb, 0x0be7,
+ 0x8fec, 0x4d2b,
+ 0x8fed, 0x05dd,
+ 0x8fee, 0x1741,
+ 0x8fef, 0x4d2c,
+ 0x8ff0, 0x0d8d,
+ 0x8ff1, 0x4d2d,
+ 0x8ff3, 0x1745,
+ 0x8ff4, 0x267b,
+ 0x8ff5, 0x4d2f,
+ 0x8ff7, 0x0ad9,
+ 0x8ff8, 0x042e,
+ 0x8ff9, 0x0816,
+ 0x8ffa, 0x4d31,
+ 0x8ffd, 0x1214,
+ 0x8ffe, 0x4d34,
+ 0x9000, 0x0e7c,
+ 0x9001, 0x0dc2,
+ 0x9002, 0x0d61,
+ 0x9003, 0x0e26,
+ 0x9004, 0x1748,
+ 0x9005, 0x1747,
+ 0x9006, 0x0b49,
+ 0x9007, 0x4d36,
+ 0x9009, 0x0fca,
+ 0x900a, 0x0fe0,
+ 0x900b, 0x1749,
+ 0x900c, 0x4d38,
+ 0x900d, 0x174c,
+ 0x900e, 0x4d39,
+ 0x900f, 0x0e69,
+ 0x9010, 0x11ef,
+ 0x9011, 0x174b,
+ 0x9012, 0x05be,
+ 0x9013, 0x4d3a,
+ 0x9014, 0x0e6f,
+ 0x9015, 0x23f2,
+ 0x9016, 0x174d,
+ 0x9017, 0x05f9,
+ 0x9018, 0x4d3b,
+ 0x9019, 0x227e,
+ 0x901a, 0x0e59,
+ 0x901b, 0x073d,
+ 0x901c, 0x4d3c,
+ 0x901d, 0x0d5c,
+ 0x901e, 0x04f6,
+ 0x901f, 0x0dce,
+ 0x9020, 0x112f,
+ 0x9021, 0x174e,
+ 0x9022, 0x0687,
+ 0x9023, 0x2019,
+ 0x9024, 0x4d3d,
+ 0x9026, 0x174a,
+ 0x9027, 0x4d3f,
+ 0x902d, 0x1751,
+ 0x902e, 0x0581,
+ 0x902f, 0x1752,
+ 0x9030, 0x4d45,
+ 0x9032, 0x1fbb,
+ 0x9033, 0x4d47,
+ 0x9035, 0x174f,
+ 0x9037, 0x4d49,
+ 0x9038, 0x1064,
+ 0x9039, 0x4d4a,
+ 0x903b, 0x0a86,
+ 0x903c, 0x042f,
+ 0x903d, 0x4d4c,
+ 0x903e, 0x10c7,
+ 0x903f, 0x4d4d,
+ 0x9041, 0x061c,
+ 0x9042, 0x0de1,
+ 0x9043, 0x4d4f,
+ 0x9044, 0x1753,
+ 0x9045, 0x4d50,
+ 0x9047, 0x10db,
+ 0x9048, 0x4d52,
+ 0x904b, 0x2253,
+ 0x904c, 0x4d55,
+ 0x904d, 0x0452,
+ 0x904e, 0x1f3e,
+ 0x904f, 0x0633,
+ 0x9050, 0x1756,
+ 0x9051, 0x1754,
+ 0x9053, 0x05a1,
+ 0x9054, 0x1ea6,
+ 0x9055, 0x218e,
+ 0x9056, 0x4d56,
+ 0x9057, 0x104c,
+ 0x9058, 0x1758,
+ 0x9059, 0x4d57,
+ 0x905b, 0x175a,
+ 0x905c, 0x21ec,
+ 0x905d, 0x4d59,
+ 0x905e, 0x1ebe,
+ 0x905f, 0x4d5a,
+ 0x9060, 0x224a,
+ 0x9061, 0x4d5b,
+ 0x9062, 0x1759,
+ 0x9063, 0x0c2f,
+ 0x9064, 0x4d5c,
+ 0x9065, 0x102a,
+ 0x9066, 0x4d5d,
+ 0x9068, 0x1757,
+ 0x9069, 0x2133,
+ 0x906a, 0x4d5f,
+ 0x906d, 0x1125,
+ 0x906e, 0x117b,
+ 0x906f, 0x4d62,
+ 0x9072, 0x1e84,
+ 0x9073, 0x4d65,
+ 0x9074, 0x175c,
+ 0x9075, 0x124e,
+ 0x9076, 0x4d66,
+ 0x9077, 0x20cf,
+ 0x9078, 0x21e2,
+ 0x9079, 0x4d67,
+ 0x907a, 0x220f,
+ 0x907b, 0x4d68,
+ 0x907c, 0x2029,
+ 0x907d, 0x175d,
+ 0x907e, 0x4d69,
+ 0x907f, 0x0445,
+ 0x9080, 0x1024,
+ 0x9081, 0x2073,
+ 0x9082, 0x175e,
+ 0x9083, 0x1760,
+ 0x9084, 0x1f55,
+ 0x9085, 0x4d6a,
+ 0x9087, 0x23f1,
+ 0x9088, 0x175f,
+ 0x9089, 0x4d6c,
+ 0x908a, 0x1e46,
+ 0x908b, 0x1761,
+ 0x908c, 0x4d6d,
+ 0x908f, 0x2063,
+ 0x9090, 0x23f3,
+ 0x9091, 0x105f,
+ 0x9092, 0x4d70,
+ 0x9093, 0x05ac,
+ 0x9094, 0x4d71,
+ 0x9095, 0x1817,
+ 0x9096, 0x4d72,
+ 0x9097, 0x1367,
+ 0x9098, 0x4d73,
+ 0x9099, 0x136a,
+ 0x909a, 0x4d74,
+ 0x909b, 0x1368,
+ 0x909c, 0x4d75,
+ 0x909d, 0x1369,
+ 0x909e, 0x4d76,
+ 0x90a1, 0x136c,
+ 0x90a2, 0x0f9a,
+ 0x90a3, 0x0b2a,
+ 0x90a4, 0x4d79,
+ 0x90a6, 0x03f9,
+ 0x90a7, 0x4d7b,
+ 0x90aa, 0x0f7b,
+ 0x90ab, 0x4d7e,
+ 0x90ac, 0x136b,
+ 0x90ad, 0x4d7f,
+ 0x90ae, 0x10af,
+ 0x90af, 0x0761,
+ 0x90b0, 0x1372,
+ 0x90b1, 0x0c6e,
+ 0x90b2, 0x4d80,
+ 0x90b3, 0x136e,
+ 0x90b4, 0x136d,
+ 0x90b5, 0x0d14,
+ 0x90b6, 0x136f,
+ 0x90b7, 0x4d81,
+ 0x90b8, 0x1371,
+ 0x90b9, 0x123b,
+ 0x90ba, 0x1370,
+ 0x90bb, 0x0a23,
+ 0x90bc, 0x4d82,
+ 0x90be, 0x1375,
+ 0x90bf, 0x4d84,
+ 0x90c1, 0x10d9,
+ 0x90c2, 0x4d86,
+ 0x90c4, 0x1377,
+ 0x90c5, 0x1374,
+ 0x90c6, 0x4d88,
+ 0x90c7, 0x1378,
+ 0x90c8, 0x4d89,
+ 0x90ca, 0x088d,
+ 0x90cb, 0x4d8b,
+ 0x90ce, 0x09b4,
+ 0x90cf, 0x1373,
+ 0x90d0, 0x1376,
+ 0x90d1, 0x11a2,
+ 0x90d2, 0x4d8e,
+ 0x90d3, 0x1379,
+ 0x90d4, 0x4d8f,
+ 0x90d7, 0x137d,
+ 0x90d8, 0x4d92,
+ 0x90db, 0x137e,
+ 0x90dc, 0x137c,
+ 0x90dd, 0x0779,
+ 0x90de, 0x4d95,
+ 0x90df, 0x231e,
+ 0x90e0, 0x4d96,
+ 0x90e1, 0x0931,
+ 0x90e2, 0x137b,
+ 0x90e3, 0x4d97,
+ 0x90e6, 0x137a,
+ 0x90e7, 0x110a,
+ 0x90e8, 0x0486,
+ 0x90e9, 0x4d9a,
+ 0x90eb, 0x137f,
+ 0x90ec, 0x4d9c,
+ 0x90ed, 0x0752,
+ 0x90ee, 0x4d9d,
+ 0x90ef, 0x1380,
+ 0x90f0, 0x4d9e,
+ 0x90f4, 0x04e0,
+ 0x90f5, 0x2233,
+ 0x90f6, 0x4da2,
+ 0x90f8, 0x0587,
+ 0x90f9, 0x4da4,
+ 0x90fd, 0x05fb,
+ 0x90fe, 0x1381,
+ 0x90ff, 0x4da8,
+ 0x9100, 0x4da9,
+ 0x9102, 0x0634,
+ 0x9103, 0x4dab,
+ 0x9104, 0x1382,
+ 0x9105, 0x4dac,
+ 0x9106, 0x2320,
+ 0x9107, 0x4dad,
+ 0x9109, 0x21c7,
+ 0x910a, 0x4daf,
+ 0x9112, 0x22bc,
+ 0x9113, 0x4db7,
+ 0x9114, 0x231c,
+ 0x9115, 0x4db8,
+ 0x9116, 0x2251,
+ 0x9117, 0x4db9,
+ 0x9119, 0x0432,
+ 0x911a, 0x4dbb,
+ 0x911e, 0x1384,
+ 0x911f, 0x4dbf,
+ 0x9122, 0x1383,
+ 0x9123, 0x1385,
+ 0x9124, 0x4dc2,
+ 0x9127, 0x1ebb,
+ 0x9128, 0x4dc5,
+ 0x912d, 0x2287,
+ 0x912e, 0x4dca,
+ 0x912f, 0x1387,
+ 0x9130, 0x202d,
+ 0x9131, 0x1386,
+ 0x9132, 0x1eab,
+ 0x9133, 0x4dcb,
+ 0x9134, 0x231d,
+ 0x9135, 0x4dcc,
+ 0x9136, 0x231f,
+ 0x9137, 0x4dcd,
+ 0x9139, 0x1388,
+ 0x913a, 0x231b,
+ 0x913b, 0x4dcf,
+ 0x9143, 0x1389,
+ 0x9144, 0x4dd7,
+ 0x9146, 0x138a,
+ 0x9147, 0x4dd9,
+ 0x9148, 0x2321,
+ 0x9149, 0x10b4,
+ 0x914a, 0x1cf8,
+ 0x914b, 0x0c72,
+ 0x914c, 0x1220,
+ 0x914d, 0x0ba5,
+ 0x914e, 0x1cfa,
+ 0x9150, 0x1cf9,
+ 0x9151, 0x4dda,
+ 0x9152, 0x08f5,
+ 0x9153, 0x4ddb,
+ 0x9157, 0x0fba,
+ 0x9158, 0x4ddf,
+ 0x915a, 0x0670,
+ 0x915b, 0x4de1,
+ 0x915d, 0x1110,
+ 0x915e, 0x0dfd,
+ 0x915f, 0x4de3,
+ 0x9161, 0x1cfe,
+ 0x9162, 0x1cfd,
+ 0x9163, 0x075f,
+ 0x9164, 0x1cfc,
+ 0x9165, 0x0dcb,
+ 0x9166, 0x4de5,
+ 0x9169, 0x1d00,
+ 0x916a, 0x09bd,
+ 0x916b, 0x4de8,
+ 0x916c, 0x050f,
+ 0x916d, 0x4de9,
+ 0x916e, 0x0e5b,
+ 0x916f, 0x1d01,
+ 0x9170, 0x1cff,
+ 0x9171, 0x0885,
+ 0x9172, 0x1d04,
+ 0x9173, 0x4dea,
+ 0x9174, 0x1d05,
+ 0x9175, 0x089e,
+ 0x9176, 0x0abd,
+ 0x9177, 0x096e,
+ 0x9178, 0x0dd6,
+ 0x9179, 0x1d06,
+ 0x917a, 0x4deb,
+ 0x917d, 0x1d02,
+ 0x917f, 0x0b53,
+ 0x9180, 0x4dee,
+ 0x9185, 0x1d08,
+ 0x9186, 0x4df3,
+ 0x9187, 0x053f,
+ 0x9188, 0x4df4,
+ 0x9189, 0x124a,
+ 0x918a, 0x4df5,
+ 0x918b, 0x055a,
+ 0x918c, 0x1d07,
+ 0x918d, 0x1d0a,
+ 0x918e, 0x4df6,
+ 0x9190, 0x1d09,
+ 0x9191, 0x1d0b,
+ 0x9192, 0x0f9c,
+ 0x9193, 0x4df8,
+ 0x9196, 0x2255,
+ 0x9197, 0x4dfb,
+ 0x919a, 0x0ad6,
+ 0x919b, 0x0c84,
+ 0x919c, 0x1e8f,
+ 0x919d, 0x4dfe,
+ 0x91a2, 0x1d0c,
+ 0x91a4, 0x4e03,
+ 0x91aa, 0x1d0e,
+ 0x91ab, 0x220c,
+ 0x91ac, 0x1fa4,
+ 0x91ad, 0x1d0f,
+ 0x91b0, 0x4e09,
+ 0x91b4, 0x1d13,
+ 0x91b5, 0x1d12,
+ 0x91b6, 0x4e0d,
+ 0x91ba, 0x1d14,
+ 0x91bb, 0x4e11,
+ 0x91c0, 0x209b,
+ 0x91c1, 0x21d8,
+ 0x91c2, 0x4e16,
+ 0x91c3, 0x25fa,
+ 0x91c4, 0x4e17,
+ 0x91c5, 0x25f9,
+ 0x91c6, 0x4e18,
+ 0x91c7, 0x0490,
+ 0x91c8, 0x4e19,
+ 0x91c9, 0x10b9,
+ 0x91ca, 0x0d64,
+ 0x91cb, 0x2134,
+ 0x91cc, 0x09da,
+ 0x91cd, 0x11d7,
+ 0x91ce, 0x1037,
+ 0x91cf, 0x0a08,
+ 0x91d0, 0x4e1a,
+ 0x91d1, 0x08c1,
+ 0x91d2, 0x24f3,
+ 0x91d5, 0x24f8,
+ 0x91d6, 0x4e1b,
+ 0x91d7, 0x24f7,
+ 0x91d8, 0x1ec8,
+ 0x91d9, 0x24f6,
+ 0x91da, 0x4e1c,
+ 0x91dc, 0x06a5,
+ 0x91dd, 0x2280,
+ 0x91de, 0x4e1e,
+ 0x91e3, 0x1ec5,
+ 0x91e4, 0x24fb,
+ 0x91e5, 0x4e23,
+ 0x91e7, 0x24fa,
+ 0x91e8, 0x4e25,
+ 0x91e9, 0x1eed,
+ 0x91ea, 0x4e26,
+ 0x91f5, 0x24fd,
+ 0x91f6, 0x4e31,
+ 0x91f7, 0x24f9,
+ 0x91f8, 0x4e32,
+ 0x91f9, 0x24fe,
+ 0x91fa, 0x20cd,
+ 0x91fb, 0x4e33,
+ 0x9200, 0x2508,
+ 0x9201, 0x2504,
+ 0x9202, 0x4e38,
+ 0x9204, 0x2506,
+ 0x9205, 0x4e3a,
+ 0x9208, 0x24ff,
+ 0x9209, 0x2090,
+ 0x920a, 0x4e3d,
+ 0x920d, 0x1edd,
+ 0x920e, 0x1f25,
+ 0x920f, 0x4e40,
+ 0x9210, 0x2503,
+ 0x9211, 0x2502,
+ 0x9212, 0x4e41,
+ 0x9214, 0x1e7a,
+ 0x9215, 0x20a6,
+ 0x9216, 0x4e43,
+ 0x921e, 0x1fd5,
+ 0x921f, 0x4e4b,
+ 0x9223, 0x1f11,
+ 0x9224, 0x4e4f,
+ 0x9225, 0x2507,
+ 0x9226, 0x2500,
+ 0x9227, 0x2505,
+ 0x9228, 0x4e50,
+ 0x922e, 0x2519,
+ 0x922f, 0x4e56,
+ 0x9230, 0x2515,
+ 0x9231, 0x4e57,
+ 0x9233, 0x250c,
+ 0x9234, 0x2031,
+ 0x9235, 0x4e59,
+ 0x9237, 0x250b,
+ 0x9238, 0x250f,
+ 0x9239, 0x251a,
+ 0x923a, 0x2509,
+ 0x923b, 0x4e5b,
+ 0x923d, 0x250e,
+ 0x923e, 0x2234,
+ 0x923f, 0x2513,
+ 0x9240, 0x1f80,
+ 0x9241, 0x4e5d,
+ 0x9245, 0x2501,
+ 0x9246, 0x4e61,
+ 0x9248, 0x2517,
+ 0x9249, 0x2516,
+ 0x924a, 0x4e63,
+ 0x924d, 0x2518,
+ 0x924e, 0x4e66,
+ 0x9251, 0x1e56,
+ 0x9252, 0x4e69,
+ 0x9255, 0x250d,
+ 0x9256, 0x4e6c,
+ 0x9257, 0x20d3,
+ 0x9258, 0x4e6d,
+ 0x925a, 0x207a,
+ 0x925b, 0x20ce,
+ 0x925c, 0x4e6f,
+ 0x925e, 0x2510,
+ 0x925f, 0x4e71,
+ 0x9262, 0x1e55,
+ 0x9263, 0x4e74,
+ 0x9266, 0x250a,
+ 0x9267, 0x4e77,
+ 0x926c, 0x2511,
+ 0x926e, 0x4e7c,
+ 0x9274, 0x086b,
+ 0x9275, 0x4e82,
+ 0x9278, 0x1faa,
+ 0x9279, 0x4e85,
+ 0x927a, 0x251e,
+ 0x927b, 0x1f1f,
+ 0x927c, 0x4e86,
+ 0x927f, 0x252d,
+ 0x9280, 0x221d,
+ 0x9281, 0x4e89,
+ 0x9283, 0x2532,
+ 0x9284, 0x4e8b,
+ 0x9285, 0x217b,
+ 0x9286, 0x4e8c,
+ 0x928e, 0x1d80,
+ 0x928f, 0x4e94,
+ 0x9291, 0x21af,
+ 0x9292, 0x4e96,
+ 0x9293, 0x252c,
+ 0x9294, 0x4e97,
+ 0x9296, 0x2528,
+ 0x9297, 0x4e99,
+ 0x9298, 0x208c,
+ 0x9299, 0x4e9a,
+ 0x929a, 0x252f,
+ 0x929b, 0x4e9b,
+ 0x929c, 0x21bc,
+ 0x929d, 0x4e9c,
+ 0x92a0, 0x251d,
+ 0x92a1, 0x4e9f,
+ 0x92a3, 0x2535,
+ 0x92a4, 0x4ea1,
+ 0x92a5, 0x220d,
+ 0x92a6, 0x2526,
+ 0x92a7, 0x4ea2,
+ 0x92a8, 0x2534,
+ 0x92a9, 0x252a,
+ 0x92aa, 0x251f,
+ 0x92ab, 0x2531,
+ 0x92ac, 0x251c,
+ 0x92ad, 0x4ea3,
+ 0x92ae, 0x1d81,
+ 0x92af, 0x4ea4,
+ 0x92b1, 0x2525,
+ 0x92b2, 0x4ea6,
+ 0x92b7, 0x21cd,
+ 0x92b8, 0x4eab,
+ 0x92b9, 0x21da,
+ 0x92ba, 0x4eac,
+ 0x92bb, 0x2172,
+ 0x92bc, 0x253e,
+ 0x92bd, 0x4ead,
+ 0x92c1, 0x204f,
+ 0x92c2, 0x4eb1,
+ 0x92c3, 0x2543,
+ 0x92c4, 0x4eb2,
+ 0x92c5, 0x21d7,
+ 0x92c6, 0x4eb3,
+ 0x92c7, 0x1e3c,
+ 0x92c8, 0x1d82,
+ 0x92c9, 0x4eb4,
+ 0x92cc, 0x2529,
+ 0x92cd, 0x4eb7,
+ 0x92cf, 0x2521,
+ 0x92d0, 0x4eb9,
+ 0x92d2, 0x1eff,
+ 0x92d3, 0x4ebb,
+ 0x92dd, 0x253f,
+ 0x92de, 0x4ec5,
+ 0x92df, 0x2544,
+ 0x92e0, 0x4ec6,
+ 0x92e3, 0x2523,
+ 0x92e4, 0x1e90,
+ 0x92e5, 0x253a,
+ 0x92e6, 0x2545,
+ 0x92e7, 0x4ec9,
+ 0x92e8, 0x253d,
+ 0x92e9, 0x4eca,
+ 0x92ea, 0x20c1,
+ 0x92eb, 0x4ecb,
+ 0x92ed, 0x2103,
+ 0x92ee, 0x2520,
+ 0x92ef, 0x253c,
+ 0x92f0, 0x253b,
+ 0x92f1, 0x2538,
+ 0x92f2, 0x4ecd,
+ 0x92f6, 0x2540,
+ 0x92f7, 0x4ed1,
+ 0x92f8, 0x1fcd,
+ 0x92f9, 0x4ed2,
+ 0x92fc, 0x1f18,
+ 0x92fd, 0x4ed5,
+ 0x9300, 0x4ed8,
+ 0x9301, 0x254b,
+ 0x9302, 0x4ed9,
+ 0x9306, 0x2547,
+ 0x9307, 0x254f,
+ 0x9309, 0x4edd,
+ 0x9310, 0x22b0,
+ 0x9311, 0x4ee4,
+ 0x9312, 0x2546,
+ 0x9313, 0x4ee5,
+ 0x9315, 0x254c,
+ 0x9316, 0x4ee7,
+ 0x9318, 0x1e9a,
+ 0x9319, 0x2552,
+ 0x931a, 0x2530,
+ 0x931b, 0x2549,
+ 0x931c, 0x4ee9,
+ 0x931f, 0x2551,
+ 0x9320, 0x1eca,
+ 0x9321, 0x4eec,
+ 0x9322, 0x20d2,
+ 0x9323, 0x4eed,
+ 0x9326, 0x1fb8,
+ 0x9327, 0x4ef0,
+ 0x9328, 0x2079,
+ 0x9329, 0x4ef1,
+ 0x932b, 0x21ab,
+ 0x932c, 0x4ef3,
+ 0x932e, 0x254d,
+ 0x932f, 0x1ea5,
+ 0x9330, 0x4ef5,
+ 0x9332, 0x204c,
+ 0x9333, 0x2080,
+ 0x9334, 0x4ef7,
+ 0x9336, 0x266d,
+ 0x9337, 0x4ef9,
+ 0x9338, 0x2537,
+ 0x9339, 0x4efa,
+ 0x933e, 0x1d83,
+ 0x933f, 0x4eff,
+ 0x9340, 0x254a,
+ 0x9341, 0x21b8,
+ 0x9342, 0x4f00,
+ 0x9343, 0x254e,
+ 0x9344, 0x4f01,
+ 0x9346, 0x24fc,
+ 0x9347, 0x2554,
+ 0x9348, 0x4f03,
+ 0x934b, 0x1f3c,
+ 0x934c, 0x4f06,
+ 0x934d, 0x1ed5,
+ 0x934e, 0x4f07,
+ 0x9354, 0x2556,
+ 0x9355, 0x4f0d,
+ 0x9358, 0x2268,
+ 0x9359, 0x4f10,
+ 0x935b, 0x1ed6,
+ 0x935c, 0x4f12,
+ 0x9364, 0x2557,
+ 0x9365, 0x2553,
+ 0x9366, 0x4f1a,
+ 0x9369, 0x2548,
+ 0x936a, 0x1d84,
+ 0x936b, 0x4f1d,
+ 0x936c, 0x20dc,
+ 0x936d, 0x4f1e,
+ 0x9370, 0x2559,
+ 0x9371, 0x4f21,
+ 0x9375, 0x1f97,
+ 0x9376, 0x2555,
+ 0x9377, 0x4f25,
+ 0x937a, 0x227d,
+ 0x937b, 0x4f28,
+ 0x937e, 0x257e,
+ 0x937f, 0x4f2b,
+ 0x9382, 0x207c,
+ 0x9383, 0x4f2e,
+ 0x9384, 0x255a,
+ 0x9385, 0x4f2f,
+ 0x9387, 0x255e,
+ 0x9388, 0x4f31,
+ 0x938a, 0x1e34,
+ 0x938b, 0x4f33,
+ 0x938f, 0x1d86,
+ 0x9390, 0x4f37,
+ 0x9396, 0x215e,
+ 0x9397, 0x4f3d,
+ 0x9398, 0x2560,
+ 0x9399, 0x4f3e,
+ 0x93a2, 0x21a2,
+ 0x93a3, 0x2354,
+ 0x93a4, 0x4f47,
+ 0x93a6, 0x2563,
+ 0x93a7, 0x2527,
+ 0x93a8, 0x4f49,
+ 0x93a9, 0x252e,
+ 0x93aa, 0x2558,
+ 0x93ab, 0x4f4a,
+ 0x93ac, 0x1f1b,
+ 0x93ad, 0x4f4b,
+ 0x93ae, 0x2283,
+ 0x93af, 0x4f4c,
+ 0x93b0, 0x2564,
+ 0x93b1, 0x4f4d,
+ 0x93b3, 0x20a0,
+ 0x93b4, 0x4f4f,
+ 0x93b5, 0x2565,
+ 0x93b6, 0x4f50,
+ 0x93b8, 0x2561,
+ 0x93b9, 0x4f52,
+ 0x93bf, 0x2562,
+ 0x93c0, 0x4f58,
+ 0x93c3, 0x256c,
+ 0x93c4, 0x4f5b,
+ 0x93c7, 0x256d,
+ 0x93c8, 0x2020,
+ 0x93c9, 0x4f5e,
+ 0x93ca, 0x1d85,
+ 0x93cb, 0x4f5f,
+ 0x93cc, 0x255f,
+ 0x93cd, 0x256a,
+ 0x93ce, 0x4f60,
+ 0x93d1, 0x256e,
+ 0x93d2, 0x4f63,
+ 0x93d6, 0x1e01,
+ 0x93d7, 0x2539,
+ 0x93d8, 0x255c,
+ 0x93d9, 0x4f67,
+ 0x93dc, 0x2568,
+ 0x93de, 0x256b,
+ 0x93df, 0x1e6f,
+ 0x93e0, 0x4f6a,
+ 0x93e1, 0x1fc4,
+ 0x93e2, 0x2567,
+ 0x93e3, 0x4f6b,
+ 0x93e4, 0x255b,
+ 0x93e5, 0x4f6c,
+ 0x93e8, 0x261d,
+ 0x93e9, 0x4f6f,
+ 0x93f5, 0x252b,
+ 0x93f6, 0x4f7b,
+ 0x93f7, 0x2571,
+ 0x93f8, 0x4f7c,
+ 0x93f9, 0x2577,
+ 0x93fa, 0x4f7d,
+ 0x9400, 0x4f83,
+ 0x9403, 0x2522,
+ 0x9404, 0x4f86,
+ 0x940b, 0x2533,
+ 0x940c, 0x4f8d,
+ 0x9410, 0x202a,
+ 0x9411, 0x4f91,
+ 0x9412, 0x2536,
+ 0x9413, 0x2573,
+ 0x9414, 0x256f,
+ 0x9415, 0x4f92,
+ 0x9418, 0x2293,
+ 0x9419, 0x2578,
+ 0x941a, 0x4f95,
+ 0x941d, 0x2570,
+ 0x941e, 0x4f98,
+ 0x9420, 0x2575,
+ 0x9421, 0x4f9a,
+ 0x9426, 0x2541,
+ 0x9428, 0x255d,
+ 0x9429, 0x4f9f,
+ 0x942e, 0x201a,
+ 0x942f, 0x4fa4,
+ 0x9432, 0x257a,
+ 0x9433, 0x2006,
+ 0x9434, 0x4fa7,
+ 0x9435, 0x2177,
+ 0x9436, 0x4fa8,
+ 0x9438, 0x251b,
+ 0x9439, 0x4faa,
+ 0x943a, 0x2524,
+ 0x943b, 0x4fab,
+ 0x943e, 0x1d87,
+ 0x943f, 0x257b,
+ 0x9440, 0x4fae,
+ 0x9444, 0x22a3,
+ 0x9445, 0x4fb2,
+ 0x944a, 0x2579,
+ 0x944b, 0x4fb7,
+ 0x944c, 0x2566,
+ 0x944d, 0x4fb8,
+ 0x9452, 0x1f93,
+ 0x9453, 0x4fbd,
+ 0x9454, 0x257c,
+ 0x9455, 0x4fbe,
+ 0x9460, 0x2514,
+ 0x9461, 0x4fc9,
+ 0x9463, 0x257d,
+ 0x9464, 0x4fcb,
+ 0x9465, 0x2572,
+ 0x9466, 0x4fcc,
+ 0x946b, 0x1d88,
+ 0x946c, 0x4fd1,
+ 0x946d, 0x2574,
+ 0x946e, 0x4fd2,
+ 0x9470, 0x224e,
+ 0x9471, 0x4fd4,
+ 0x9472, 0x21c6,
+ 0x9473, 0x4fd5,
+ 0x9477, 0x209f,
+ 0x9478, 0x4fd9,
+ 0x9479, 0x2576,
+ 0x947a, 0x4fda,
+ 0x947c, 0x2064,
+ 0x947d, 0x22bf,
+ 0x947e, 0x261c,
+ 0x947f, 0x225e,
+ 0x9480, 0x4fdc,
+ 0x9485, 0x1a8e,
+ 0x9488, 0x118c,
+ 0x9489, 0x05e3,
+ 0x948a, 0x1a92,
+ 0x948b, 0x1a91,
+ 0x948c, 0x1a93,
+ 0x948e, 0x0c22,
+ 0x948f, 0x1a95,
+ 0x9491, 0x4fe1,
+ 0x9492, 0x064d,
+ 0x9493, 0x05d7,
+ 0x9494, 0x1a97,
+ 0x9495, 0x1a99,
+ 0x9496, 0x4fe2,
+ 0x9497, 0x1a98,
+ 0x9498, 0x4fe3,
+ 0x9499, 0x06c1,
+ 0x949a, 0x1a9a,
+ 0x949d, 0x061a,
+ 0x949e, 0x04d3,
+ 0x949f, 0x11d2,
+ 0x94a0, 0x0b29,
+ 0x94a1, 0x041e,
+ 0x94a2, 0x06d1,
+ 0x94a3, 0x1a9d,
+ 0x94a5, 0x1102,
+ 0x94a6, 0x0c52,
+ 0x94a7, 0x092a,
+ 0x94a8, 0x0ee8,
+ 0x94a9, 0x070c,
+ 0x94aa, 0x1aa0,
+ 0x94ab, 0x1a9f,
+ 0x94ac, 0x1aa2,
+ 0x94ad, 0x1aa1,
+ 0x94ae, 0x0b66,
+ 0x94af, 0x1aa3,
+ 0x94b1, 0x0c2b,
+ 0x94b2, 0x1aa5,
+ 0x94b3, 0x0c2c,
+ 0x94b4, 0x1aa6,
+ 0x94b5, 0x046e,
+ 0x94b6, 0x1aa7,
+ 0x94bb, 0x1247,
+ 0x94bc, 0x1aac,
+ 0x94be, 0x084b,
+ 0x94bf, 0x1aae,
+ 0x94c0, 0x10b0,
+ 0x94c1, 0x0e4d,
+ 0x94c2, 0x0473,
+ 0x94c3, 0x0a2e,
+ 0x94c4, 0x1aaf,
+ 0x94c5, 0x0c23,
+ 0x94c6, 0x0ab2,
+ 0x94c7, 0x4fe4,
+ 0x94c8, 0x1ab0,
+ 0x94cf, 0x4fe5,
+ 0x94d0, 0x1ab7,
+ 0x94d3, 0x4fe6,
+ 0x94d5, 0x1aba,
+ 0x94d8, 0x1abe,
+ 0x94d9, 0x1abd,
+ 0x94da, 0x4fe8,
+ 0x94db, 0x1abf,
+ 0x94dc, 0x0e5e,
+ 0x94dd, 0x0a68,
+ 0x94de, 0x1ac0,
+ 0x94e1, 0x1142,
+ 0x94e2, 0x1ac3,
+ 0x94e3, 0x0f20,
+ 0x94e4, 0x1ac4,
+ 0x94e6, 0x4fe9,
+ 0x94e7, 0x1ac6,
+ 0x94e9, 0x1ac9,
+ 0x94ea, 0x1ac8,
+ 0x94eb, 0x1aca,
+ 0x94ec, 0x06f0,
+ 0x94ed, 0x0aff,
+ 0x94ee, 0x1acb,
+ 0x94f0, 0x0893,
+ 0x94f1, 0x1046,
+ 0x94f2, 0x04c0,
+ 0x94f3, 0x1acd,
+ 0x94f6, 0x107f,
+ 0x94f7, 0x1ad0,
+ 0x94f8, 0x11fc,
+ 0x94f9, 0x1ad1,
+ 0x94fa, 0x0beb,
+ 0x94fb, 0x4fea,
+ 0x94fc, 0x1ad2,
+ 0x94fe, 0x09fd,
+ 0x94ff, 0x1ad4,
+ 0x9500, 0x0f67,
+ 0x9501, 0x0ded,
+ 0x9502, 0x1ad6,
+ 0x9503, 0x1ad5,
+ 0x9504, 0x051f,
+ 0x9505, 0x0751,
+ 0x9506, 0x1ad7,
+ 0x9508, 0x0fad,
+ 0x9509, 0x1ad9,
+ 0x950b, 0x0683,
+ 0x950c, 0x0f8a,
+ 0x950d, 0x1adb,
+ 0x9510, 0x0ccc,
+ 0x9511, 0x0e33,
+ 0x9512, 0x1ade,
+ 0x9517, 0x1181,
+ 0x9518, 0x1ae3,
+ 0x9519, 0x0570,
+ 0x951a, 0x0aaf,
+ 0x951b, 0x1ae4,
+ 0x951c, 0x4feb,
+ 0x951d, 0x1ae5,
+ 0x9520, 0x4fec,
+ 0x9521, 0x0f0c,
+ 0x9522, 0x1ae8,
+ 0x9523, 0x0a87,
+ 0x9524, 0x053b,
+ 0x9525, 0x1213,
+ 0x9526, 0x08c6,
+ 0x9527, 0x4fed,
+ 0x9528, 0x0f34,
+ 0x9529, 0x1aeb,
+ 0x952a, 0x1ae9,
+ 0x952c, 0x1aec,
+ 0x952d, 0x05e6,
+ 0x952e, 0x086f,
+ 0x952f, 0x0911,
+ 0x9530, 0x0ad1,
+ 0x9531, 0x1aed,
+ 0x9533, 0x4fee,
+ 0x9534, 0x1aef,
+ 0x9535, 0x1af7,
+ 0x9536, 0x1af0,
+ 0x9539, 0x0c3f,
+ 0x953a, 0x1b19,
+ 0x953b, 0x060c,
+ 0x953c, 0x1af3,
+ 0x953d, 0x4fef,
+ 0x953e, 0x1af4,
+ 0x9540, 0x0605,
+ 0x9541, 0x0ac3,
+ 0x9542, 0x1af6,
+ 0x9543, 0x4ff0,
+ 0x9544, 0x1af8,
+ 0x9547, 0x1193,
+ 0x9548, 0x4ff1,
+ 0x9549, 0x1afb,
+ 0x954a, 0x0b5a,
+ 0x954b, 0x4ff2,
+ 0x954c, 0x1afc,
+ 0x954d, 0x0b5b,
+ 0x954e, 0x1afd,
+ 0x9550, 0x06df,
+ 0x9551, 0x0402,
+ 0x9552, 0x1aff,
+ 0x9555, 0x4ff3,
+ 0x9556, 0x1b02,
+ 0x955a, 0x4ff4,
+ 0x955b, 0x1b06,
+ 0x955c, 0x08e4,
+ 0x955d, 0x1b09,
+ 0x955e, 0x1b07,
+ 0x9560, 0x4ff5,
+ 0x9561, 0x1b0a,
+ 0x9563, 0x0a16,
+ 0x9564, 0x1b0c,
+ 0x956d, 0x09c3,
+ 0x956e, 0x4ff6,
+ 0x956f, 0x1b15,
+ 0x9570, 0x09f6,
+ 0x9571, 0x1b16,
+ 0x9574, 0x4ff7,
+ 0x9576, 0x0f4f,
+ 0x9577, 0x1e75,
+ 0x9578, 0x4ff9,
+ 0x957f, 0x04c9,
+ 0x9580, 0x207d,
+ 0x9581, 0x5000,
+ 0x9582, 0x23bf,
+ 0x9583, 0x2113,
+ 0x9584, 0x5001,
+ 0x9586, 0x23c0,
+ 0x9587, 0x5003,
+ 0x9589, 0x1e45,
+ 0x958a, 0x5005,
+ 0x958b, 0x1fd8,
+ 0x958c, 0x23c4,
+ 0x958d, 0x5006,
+ 0x958e, 0x23c2,
+ 0x958f, 0x2104,
+ 0x9590, 0x5007,
+ 0x9591, 0x21bd,
+ 0x9592, 0x5008,
+ 0x9593, 0x1f87,
+ 0x9594, 0x23c3,
+ 0x9595, 0x5009,
+ 0x9598, 0x2269,
+ 0x9599, 0x500c,
+ 0x95a1, 0x1f43,
+ 0x95a2, 0x5014,
+ 0x95a3, 0x1f1e,
+ 0x95a4, 0x2679,
+ 0x95a5, 0x1eeb,
+ 0x95a6, 0x5015,
+ 0x95a8, 0x1f35,
+ 0x95a9, 0x208a,
+ 0x95aa, 0x5017,
+ 0x95ab, 0x23c7,
+ 0x95ac, 0x23c9,
+ 0x95ad, 0x23c6,
+ 0x95ae, 0x5018,
+ 0x95b2, 0x224f,
+ 0x95b3, 0x501c,
+ 0x95b6, 0x23cb,
+ 0x95b7, 0x501f,
+ 0x95b9, 0x21f3,
+ 0x95ba, 0x5021,
+ 0x95bb, 0x21f7,
+ 0x95bc, 0x23cf,
+ 0x95bd, 0x23ce,
+ 0x95be, 0x23ca,
+ 0x95bf, 0x23cd,
+ 0x95c0, 0x5022,
+ 0x95c3, 0x23d0,
+ 0x95c4, 0x5025,
+ 0x95c6, 0x266c,
+ 0x95c7, 0x5027,
+ 0x95c8, 0x23c1,
+ 0x95c9, 0x5028,
+ 0x95ca, 0x1fee,
+ 0x95cb, 0x23d1,
+ 0x95cc, 0x1ff8,
+ 0x95cd, 0x5029,
+ 0x95d0, 0x23d3,
+ 0x95d1, 0x502c,
+ 0x95d4, 0x23d2,
+ 0x95d5, 0x23d4,
+ 0x95d6, 0x1e98,
+ 0x95d7, 0x502f,
+ 0x95dc, 0x1f2c,
+ 0x95dd, 0x5034,
+ 0x95de, 0x23d5,
+ 0x95df, 0x5035,
+ 0x95e1, 0x1e71,
+ 0x95e2, 0x2691,
+ 0x95e3, 0x5037,
+ 0x95e5, 0x23c5,
+ 0x95e6, 0x5039,
+ 0x95e8, 0x0aca,
+ 0x95e9, 0x1685,
+ 0x95ea, 0x0cfa,
+ 0x95eb, 0x1686,
+ 0x95ec, 0x503b,
+ 0x95ed, 0x043e,
+ 0x95ee, 0x0ed9,
+ 0x95ef, 0x0536,
+ 0x95f0, 0x0ccd,
+ 0x95f1, 0x1687,
+ 0x95f2, 0x0f3d,
+ 0x95f3, 0x1688,
+ 0x95f4, 0x0857,
+ 0x95f5, 0x1689,
+ 0x95f7, 0x0acb,
+ 0x95f8, 0x1143,
+ 0x95f9, 0x0b39,
+ 0x95fa, 0x0744,
+ 0x95fb, 0x0ed4,
+ 0x95fc, 0x168b,
+ 0x95fd, 0x0afb,
+ 0x95fe, 0x168c,
+ 0x95ff, 0x503c,
+ 0x9600, 0x0644,
+ 0x9601, 0x06ee,
+ 0x9602, 0x0789,
+ 0x9603, 0x168d,
+ 0x9605, 0x1107,
+ 0x9606, 0x168f,
+ 0x9607, 0x503d,
+ 0x9608, 0x1690,
+ 0x9609, 0x0ff4,
+ 0x960a, 0x1691,
+ 0x960e, 0x0fff,
+ 0x960f, 0x1695,
+ 0x9610, 0x04c2,
+ 0x9611, 0x09a6,
+ 0x9612, 0x1696,
+ 0x9613, 0x503e,
+ 0x9614, 0x0996,
+ 0x9615, 0x1697,
+ 0x9618, 0x503f,
+ 0x9619, 0x169a,
+ 0x961b, 0x5040,
+ 0x961c, 0x06b2,
+ 0x961d, 0x1354,
+ 0x961e, 0x5041,
+ 0x961f, 0x0612,
+ 0x9620, 0x5042,
+ 0x9621, 0x1356,
+ 0x9622, 0x1355,
+ 0x9623, 0x5043,
+ 0x962a, 0x1358,
+ 0x962b, 0x504a,
+ 0x962e, 0x0cc9,
+ 0x962f, 0x504d,
+ 0x9631, 0x1357,
+ 0x9632, 0x065d,
+ 0x9633, 0x101d,
+ 0x9634, 0x107c,
+ 0x9635, 0x1194,
+ 0x9636, 0x08a8,
+ 0x9637, 0x504f,
+ 0x963b, 0x1245,
+ 0x963c, 0x135a,
+ 0x963d, 0x1359,
+ 0x963e, 0x5053,
+ 0x963f, 0x03ad,
+ 0x9640, 0x0e84,
+ 0x9641, 0x5054,
+ 0x9642, 0x135b,
+ 0x9643, 0x5055,
+ 0x9644, 0x06b8,
+ 0x9645, 0x083d,
+ 0x9646, 0x0a64,
+ 0x9647, 0x0a4b,
+ 0x9648, 0x04e7,
+ 0x9649, 0x135c,
+ 0x964a, 0x5056,
+ 0x964b, 0x0a51,
+ 0x964c, 0x0b13,
+ 0x964d, 0x0886,
+ 0x964e, 0x5057,
+ 0x9650, 0x0f4b,
+ 0x9651, 0x5059,
+ 0x9654, 0x135d,
+ 0x9655, 0x0cfb,
+ 0x9656, 0x505c,
+ 0x9658, 0x231a,
+ 0x9659, 0x505e,
+ 0x965b, 0x0446,
+ 0x965c, 0x5060,
+ 0x965d, 0x2114,
+ 0x965e, 0x5061,
+ 0x965f, 0x135e,
+ 0x9660, 0x5062,
+ 0x9661, 0x05f7,
+ 0x9662, 0x10fd,
+ 0x9663, 0x2284,
+ 0x9664, 0x0522,
+ 0x9665, 0x5063,
+ 0x9667, 0x135f,
+ 0x9668, 0x110c,
+ 0x9669, 0x0f42,
+ 0x966a, 0x0ba4,
+ 0x966b, 0x5065,
+ 0x966c, 0x1360,
+ 0x966d, 0x5066,
+ 0x9670, 0x221c,
+ 0x9671, 0x5069,
+ 0x9672, 0x1361,
+ 0x9673, 0x1e7e,
+ 0x9674, 0x1362,
+ 0x9675, 0x0a33,
+ 0x9676, 0x0e28,
+ 0x9677, 0x0f4a,
+ 0x9678, 0x204d,
+ 0x9679, 0x506a,
+ 0x967d, 0x2201,
+ 0x967e, 0x506e,
+ 0x9685, 0x10cc,
+ 0x9686, 0x0a48,
+ 0x9687, 0x5075,
+ 0x9688, 0x1363,
+ 0x9689, 0x5076,
+ 0x968a, 0x1ed9,
+ 0x968b, 0x0dda,
+ 0x968c, 0x5077,
+ 0x968d, 0x1364,
+ 0x968e, 0x1fb2,
+ 0x968f, 0x0ddb,
+ 0x9690, 0x1085,
+ 0x9691, 0x5078,
+ 0x9694, 0x06ef,
+ 0x9695, 0x2252,
+ 0x9696, 0x507b,
+ 0x9697, 0x1365,
+ 0x9698, 0x03ba,
+ 0x9699, 0x0f23,
+ 0x969a, 0x507c,
+ 0x969b, 0x1f79,
+ 0x969c, 0x1170,
+ 0x969d, 0x507d,
+ 0x96a7, 0x0de2,
+ 0x96a8, 0x2157,
+ 0x96a9, 0x5087,
+ 0x96aa, 0x21bf,
+ 0x96ab, 0x5088,
+ 0x96b0, 0x1366,
+ 0x96b1, 0x221f,
+ 0x96b2, 0x508d,
+ 0x96b3, 0x1684,
+ 0x96b4, 0x203d,
+ 0x96b5, 0x508e,
+ 0x96b6, 0x09ee,
+ 0x96b7, 0x508f,
+ 0x96b8, 0x2015,
+ 0x96b9, 0x1d79,
+ 0x96ba, 0x5090,
+ 0x96bb, 0x26a5,
+ 0x96bc, 0x1d7a,
+ 0x96be, 0x0b34,
+ 0x96bf, 0x5091,
+ 0x96c0, 0x0c93,
+ 0x96c1, 0x100c,
+ 0x96c2, 0x5092,
+ 0x96c4, 0x0fa6,
+ 0x96c5, 0x0fee,
+ 0x96c6, 0x0822,
+ 0x96c7, 0x0726,
+ 0x96c8, 0x5094,
+ 0x96c9, 0x1b1c,
+ 0x96ca, 0x5095,
+ 0x96cc, 0x0549,
+ 0x96cd, 0x109f,
+ 0x96ce, 0x1d7c,
+ 0x96cf, 0x0520,
+ 0x96d0, 0x5097,
+ 0x96d2, 0x1d7d,
+ 0x96d3, 0x5099,
+ 0x96d5, 0x05d2,
+ 0x96d6, 0x2156,
+ 0x96d7, 0x509b,
+ 0x96d9, 0x2144,
+ 0x96da, 0x509d,
+ 0x96db, 0x1e91,
+ 0x96dc, 0x2257,
+ 0x96dd, 0x509e,
+ 0x96e0, 0x1d7f,
+ 0x96e1, 0x50a1,
+ 0x96e2, 0x200a,
+ 0x96e3, 0x2092,
+ 0x96e4, 0x50a2,
+ 0x96e8, 0x10cf,
+ 0x96e9, 0x1d61,
+ 0x96ea, 0x0fd2,
+ 0x96eb, 0x50a6,
+ 0x96ef, 0x1d63,
+ 0x96f0, 0x50aa,
+ 0x96f2, 0x2250,
+ 0x96f3, 0x1d62,
+ 0x96f4, 0x50ac,
+ 0x96f6, 0x0a2c,
+ 0x96f7, 0x09c2,
+ 0x96f8, 0x50ae,
+ 0x96f9, 0x040b,
+ 0x96fa, 0x50af,
+ 0x96fb, 0x1ec3,
+ 0x96fc, 0x50b0,
+ 0x96fe, 0x0efc,
+ 0x96ff, 0x50b2,
+ 0x9700, 0x0fb3,
+ 0x9701, 0x1d65,
+ 0x9702, 0x50b3,
+ 0x9704, 0x0f63,
+ 0x9705, 0x50b5,
+ 0x9706, 0x1d64,
+ 0x9707, 0x1191,
+ 0x9708, 0x1d66,
+ 0x9709, 0x0abe,
+ 0x970a, 0x50b6,
+ 0x970d, 0x0809,
+ 0x970e, 0x1d68,
+ 0x970f, 0x1d67,
+ 0x9710, 0x50b9,
+ 0x9713, 0x0b41,
+ 0x9714, 0x50bc,
+ 0x9716, 0x0a21,
+ 0x9717, 0x50be,
+ 0x971c, 0x0d9f,
+ 0x971d, 0x50c3,
+ 0x971e, 0x0f29,
+ 0x971f, 0x50c4,
+ 0x9727, 0x21a8,
+ 0x9728, 0x50cc,
+ 0x972a, 0x1d69,
+ 0x972b, 0x50ce,
+ 0x972d, 0x1d6a,
+ 0x972e, 0x50d0,
+ 0x9730, 0x1d6b,
+ 0x9731, 0x50d2,
+ 0x9732, 0x0a5d,
+ 0x9733, 0x50d3,
+ 0x9738, 0x03df,
+ 0x9739, 0x0bba,
+ 0x973a, 0x50d8,
+ 0x973d, 0x260d,
+ 0x973e, 0x1d6c,
+ 0x973f, 0x50db,
+ 0x9742, 0x260c,
+ 0x9743, 0x50de,
+ 0x9744, 0x260e,
+ 0x9745, 0x50df,
+ 0x9748, 0x2032,
+ 0x9749, 0x50e2,
+ 0x9752, 0x0c5d,
+ 0x9753, 0x1d60,
+ 0x9754, 0x50eb,
+ 0x9756, 0x08e7,
+ 0x9757, 0x50ed,
+ 0x9759, 0x08e1,
+ 0x975a, 0x260b,
+ 0x975b, 0x05c6,
+ 0x975c, 0x50ef,
+ 0x975e, 0x0664,
+ 0x975f, 0x50f1,
+ 0x9760, 0x094c,
+ 0x9761, 0x0ad7,
+ 0x9762, 0x0aeb,
+ 0x9763, 0x50f2,
+ 0x9765, 0x1282,
+ 0x9766, 0x50f4,
+ 0x9768, 0x22c3,
+ 0x9769, 0x06ea,
+ 0x976a, 0x50f6,
+ 0x9773, 0x08ca,
+ 0x9774, 0x0fce,
+ 0x9775, 0x50ff,
+ 0x9776, 0x03db,
+ 0x9777, 0x5100,
+ 0x977c, 0x1dc8,
+ 0x977d, 0x5105,
+ 0x9785, 0x1dc9,
+ 0x9786, 0x510d,
+ 0x978b, 0x0f77,
+ 0x978c, 0x5112,
+ 0x978d, 0x03bb,
+ 0x978e, 0x5113,
+ 0x978f, 0x1f23,
+ 0x9790, 0x5114,
+ 0x9791, 0x1dca,
+ 0x9793, 0x5115,
+ 0x9794, 0x1dcc,
+ 0x9795, 0x5116,
+ 0x9798, 0x0c47,
+ 0x9799, 0x5119,
+ 0x97a0, 0x08fe,
+ 0x97a1, 0x5120,
+ 0x97a3, 0x1dcf,
+ 0x97a4, 0x5122,
+ 0x97a6, 0x2695,
+ 0x97a7, 0x5124,
+ 0x97ab, 0x1dce,
+ 0x97ac, 0x5128,
+ 0x97ad, 0x0447,
+ 0x97ae, 0x5129,
+ 0x97af, 0x1dcd,
+ 0x97b0, 0x512a,
+ 0x97b2, 0x1dd0,
+ 0x97b3, 0x512c,
+ 0x97b4, 0x1dd1,
+ 0x97b5, 0x512d,
+ 0x97bd, 0x265e,
+ 0x97be, 0x5135,
+ 0x97c3, 0x265d,
+ 0x97c4, 0x513a,
+ 0x97c6, 0x2692,
+ 0x97c7, 0x513c,
+ 0x97c9, 0x265f,
+ 0x97ca, 0x513e,
+ 0x97cb, 0x218d,
+ 0x97cc, 0x20fd,
+ 0x97cd, 0x513f,
+ 0x97d3, 0x1f40,
+ 0x97d4, 0x5145,
+ 0x97d9, 0x2465,
+ 0x97da, 0x514a,
+ 0x97dc, 0x2467,
+ 0x97dd, 0x514c,
+ 0x97de, 0x2466,
+ 0x97df, 0x514d,
+ 0x97e6, 0x0eb3,
+ 0x97e7, 0x0ca8,
+ 0x97e8, 0x5154,
+ 0x97e9, 0x0762,
+ 0x97ea, 0x184e,
+ 0x97ed, 0x08f1,
+ 0x97ee, 0x5155,
+ 0x97f3, 0x107b,
+ 0x97f4, 0x515a,
+ 0x97f5, 0x1112,
+ 0x97f6, 0x0d11,
+ 0x97f7, 0x515b,
+ 0x97ff, 0x21c9,
+ 0x9800, 0x5163,
+ 0x9801, 0x2209,
+ 0x9802, 0x1ec9,
+ 0x9803, 0x20e9,
+ 0x9804, 0x5164,
+ 0x9805, 0x21ca,
+ 0x9806, 0x2146,
+ 0x9807, 0x25c5,
+ 0x9808, 0x21dc,
+ 0x9809, 0x5165,
+ 0x980a, 0x245e,
+ 0x980b, 0x5166,
+ 0x980c, 0x214f,
+ 0x980d, 0x5167,
+ 0x980e, 0x25c6,
+ 0x9810, 0x2241,
+ 0x9811, 0x218a,
+ 0x9812, 0x1e2f,
+ 0x9813, 0x1edc,
+ 0x9814, 0x5168,
+ 0x9817, 0x20bf,
+ 0x9818, 0x2034,
+ 0x9819, 0x516b,
+ 0x981c, 0x25c9,
+ 0x981d, 0x516e,
+ 0x9821, 0x25c8,
+ 0x9822, 0x5172,
+ 0x9824, 0x220e,
+ 0x9825, 0x5174,
+ 0x9826, 0x25cb,
+ 0x9827, 0x5175,
+ 0x982d, 0x217d,
+ 0x982e, 0x517b,
+ 0x9830, 0x1f7e,
+ 0x9831, 0x517d,
+ 0x9837, 0x25cc,
+ 0x9838, 0x1fc3,
+ 0x9839, 0x5183,
+ 0x983b, 0x20b9,
+ 0x983c, 0x5185,
+ 0x983d, 0x2181,
+ 0x983e, 0x5186,
+ 0x9846, 0x1fda,
+ 0x9847, 0x518e,
+ 0x984c, 0x2173,
+ 0x984d, 0x1ee1,
+ 0x984e, 0x25cd,
+ 0x984f, 0x5193,
+ 0x9853, 0x25ce,
+ 0x9854, 0x21f6,
+ 0x9855, 0x5197,
+ 0x9858, 0x224b,
+ 0x9859, 0x25d1,
+ 0x985a, 0x519a,
+ 0x985b, 0x1ec0,
+ 0x985c, 0x519b,
+ 0x985e, 0x2008,
+ 0x985f, 0x519d,
+ 0x9862, 0x25d0,
+ 0x9863, 0x51a0,
+ 0x9865, 0x25d2,
+ 0x9866, 0x51a2,
+ 0x9867, 0x1f2a,
+ 0x9868, 0x51a3,
+ 0x986b, 0x1e72,
+ 0x986c, 0x25d3,
+ 0x986d, 0x51a6,
+ 0x986f, 0x21be,
+ 0x9870, 0x25d4,
+ 0x9871, 0x2044,
+ 0x9872, 0x51a8,
+ 0x9873, 0x25cf,
+ 0x9874, 0x20f3,
+ 0x9875, 0x103a,
+ 0x9876, 0x05e4,
+ 0x9877, 0x0c67,
+ 0x9878, 0x1be0,
+ 0x9879, 0x0f5b,
+ 0x987a, 0x0da8,
+ 0x987b, 0x0fb6,
+ 0x987c, 0x1827,
+ 0x987d, 0x0e98,
+ 0x987e, 0x0724,
+ 0x987f, 0x0618,
+ 0x9880, 0x1be1,
+ 0x9881, 0x03ef,
+ 0x9882, 0x0dc1,
+ 0x9883, 0x1be2,
+ 0x9884, 0x10e7,
+ 0x9885, 0x0a54,
+ 0x9886, 0x0a35,
+ 0x9887, 0x0be3,
+ 0x9888, 0x08e0,
+ 0x9889, 0x1be3,
+ 0x988a, 0x0848,
+ 0x988b, 0x51a9,
+ 0x988c, 0x1be4,
+ 0x988e, 0x51aa,
+ 0x988f, 0x1be6,
+ 0x9890, 0x104a,
+ 0x9891, 0x0bd4,
+ 0x9892, 0x51ab,
+ 0x9893, 0x0e78,
+ 0x9894, 0x1be7,
+ 0x9895, 0x51ac,
+ 0x9896, 0x1096,
+ 0x9897, 0x0952,
+ 0x9898, 0x0e35,
+ 0x9899, 0x51ad,
+ 0x989a, 0x1be8,
+ 0x989c, 0x0ffe,
+ 0x989d, 0x062d,
+ 0x989e, 0x1bea,
+ 0x98a0, 0x05c0,
+ 0x98a1, 0x1bec,
+ 0x98a3, 0x51ae,
+ 0x98a4, 0x04c3,
+ 0x98a5, 0x1bee,
+ 0x98a7, 0x0c82,
+ 0x98a8, 0x1f00,
+ 0x98a9, 0x51af,
+ 0x98ae, 0x24cc,
+ 0x98b0, 0x51b4,
+ 0x98b1, 0x2698,
+ 0x98b2, 0x51b5,
+ 0x98b3, 0x2678,
+ 0x98b4, 0x51b6,
+ 0x98b6, 0x24ce,
+ 0x98b7, 0x51b8,
+ 0x98bc, 0x24cf,
+ 0x98bd, 0x51bd,
+ 0x98c4, 0x20b8,
+ 0x98c5, 0x51c4,
+ 0x98c6, 0x24d0,
+ 0x98c7, 0x51c5,
+ 0x98c8, 0x24d1,
+ 0x98c9, 0x51c6,
+ 0x98ce, 0x0684,
+ 0x98cf, 0x51cb,
+ 0x98d1, 0x19b7,
+ 0x98d4, 0x51cd,
+ 0x98d5, 0x19ba,
+ 0x98d6, 0x51ce,
+ 0x98d8, 0x0bcd,
+ 0x98d9, 0x19bb,
+ 0x98db, 0x1ef4,
+ 0x98dc, 0x51d0,
+ 0x98de, 0x0666,
+ 0x98df, 0x0d4a,
+ 0x98e0, 0x239b,
+ 0x98e1, 0x51d2,
+ 0x98e2, 0x267e,
+ 0x98e3, 0x51d3,
+ 0x98e7, 0x161a,
+ 0x98e8, 0x1de7,
+ 0x98e9, 0x239d,
+ 0x98ea, 0x239f,
+ 0x98ec, 0x51d7,
+ 0x98ed, 0x23a1,
+ 0x98ee, 0x51d8,
+ 0x98ef, 0x1ef1,
+ 0x98f0, 0x51d9,
+ 0x98f2, 0x221e,
+ 0x98f3, 0x51db,
+ 0x98f4, 0x23a2,
+ 0x98f5, 0x51dc,
+ 0x98fc, 0x214b,
+ 0x98fd, 0x1e36,
+ 0x98fe, 0x2135,
+ 0x98ff, 0x51e3,
+ 0x9900, 0x51e4,
+ 0x9903, 0x1fad,
+ 0x9904, 0x51e7,
+ 0x9905, 0x1e53,
+ 0x9906, 0x51e8,
+ 0x9909, 0x23a3,
+ 0x990a, 0x2203,
+ 0x990b, 0x51eb,
+ 0x990c, 0x1ee7,
+ 0x990d, 0x1de8,
+ 0x990e, 0x51ec,
+ 0x9910, 0x0494,
+ 0x9911, 0x23a4,
+ 0x9912, 0x2097,
+ 0x9913, 0x1ee4,
+ 0x9914, 0x51ee,
+ 0x9918, 0x2238,
+ 0x9919, 0x51f2,
+ 0x991b, 0x23a5,
+ 0x991c, 0x51f4,
+ 0x991e, 0x1f9a,
+ 0x991f, 0x51f6,
+ 0x9921, 0x21c3,
+ 0x9922, 0x51f8,
+ 0x9928, 0x1f2e,
+ 0x9929, 0x51fe,
+ 0x992e, 0x1de9,
+ 0x992f, 0x5203,
+ 0x9933, 0x239c,
+ 0x9934, 0x5207,
+ 0x9937, 0x23a6,
+ 0x9938, 0x520a,
+ 0x993c, 0x239e,
+ 0x993d, 0x520e,
+ 0x993e, 0x2035,
+ 0x993f, 0x23a7,
+ 0x9940, 0x520f,
+ 0x9943, 0x23a8,
+ 0x9944, 0x5212,
+ 0x9945, 0x2075,
+ 0x9946, 0x5213,
+ 0x9948, 0x23a9,
+ 0x994b, 0x1feb,
+ 0x994c, 0x23ac,
+ 0x994d, 0x5215,
+ 0x9951, 0x1f6a,
+ 0x9952, 0x20f9,
+ 0x9953, 0x5219,
+ 0x9954, 0x1deb,
+ 0x9955, 0x1dea,
+ 0x9956, 0x521a,
+ 0x9957, 0x2666,
+ 0x9958, 0x521b,
+ 0x995c, 0x2667,
+ 0x995d, 0x521f,
+ 0x995e, 0x1e6c,
+ 0x995f, 0x5220,
+ 0x9962, 0x23ad,
+ 0x9963, 0x161d,
+ 0x9964, 0x5223,
+ 0x9965, 0x0815,
+ 0x9966, 0x5224,
+ 0x9967, 0x161e,
+ 0x996d, 0x0656,
+ 0x996e, 0x1082,
+ 0x996f, 0x0875,
+ 0x9970, 0x0d65,
+ 0x9971, 0x040e,
+ 0x9972, 0x0dbc,
+ 0x9973, 0x5225,
+ 0x9974, 0x1624,
+ 0x9975, 0x063b,
+ 0x9976, 0x0c9f,
+ 0x9977, 0x1625,
+ 0x9978, 0x5226,
+ 0x997a, 0x0899,
+ 0x997b, 0x5228,
+ 0x997c, 0x0466,
+ 0x997d, 0x1626,
+ 0x997e, 0x5229,
+ 0x997f, 0x0635,
+ 0x9980, 0x1627,
+ 0x9981, 0x0b3c,
+ 0x9982, 0x522a,
+ 0x9984, 0x1628,
+ 0x9985, 0x0f47,
+ 0x9986, 0x0736,
+ 0x9987, 0x1629,
+ 0x9988, 0x098c,
+ 0x9989, 0x522c,
+ 0x998a, 0x162a,
+ 0x998b, 0x04bd,
+ 0x998c, 0x522d,
+ 0x998d, 0x162b,
+ 0x998e, 0x522e,
+ 0x998f, 0x0a3c,
+ 0x9990, 0x162c,
+ 0x9992, 0x0a9f,
+ 0x9993, 0x162e,
+ 0x9996, 0x0d6e,
+ 0x9997, 0x126e,
+ 0x9998, 0x12f9,
+ 0x9999, 0x0f50,
+ 0x999a, 0x522f,
+ 0x99a5, 0x1b2b,
+ 0x99a6, 0x523a,
+ 0x99a8, 0x13de,
+ 0x99a9, 0x523c,
+ 0x99ac, 0x206d,
+ 0x99ad, 0x2242,
+ 0x99ae, 0x1f02,
+ 0x99af, 0x523f,
+ 0x99b1, 0x2183,
+ 0x99b2, 0x5241,
+ 0x99b3, 0x1e85,
+ 0x99b4, 0x21e9,
+ 0x99b5, 0x5242,
+ 0x99c1, 0x1e57,
+ 0x99c2, 0x524e,
+ 0x99d0, 0x22a5,
+ 0x99d1, 0x2407,
+ 0x99d2, 0x1fca,
+ 0x99d3, 0x525c,
+ 0x99d4, 0x2402,
+ 0x99d5, 0x1f82,
+ 0x99d6, 0x525d,
+ 0x99d8, 0x2408,
+ 0x99d9, 0x2404,
+ 0x99da, 0x525f,
+ 0x99db, 0x2131,
+ 0x99dc, 0x5260,
+ 0x99dd, 0x2184,
+ 0x99de, 0x5261,
+ 0x99df, 0x2403,
+ 0x99e0, 0x5262,
+ 0x99e1, 0x206e,
+ 0x99e2, 0x240b,
+ 0x99e3, 0x5263,
+ 0x99ed, 0x1f3f,
+ 0x99ee, 0x526d,
+ 0x99f1, 0x2067,
+ 0x99f2, 0x5270,
+ 0x99ff, 0x1fd7,
+ 0x9a00, 0x527d,
+ 0x9a01, 0x1e83,
+ 0x9a02, 0x527e,
+ 0x9a05, 0x240f,
+ 0x9a06, 0x5281,
+ 0x9a0d, 0x240e,
+ 0x9a0e, 0x20c7,
+ 0x9a0f, 0x240d,
+ 0x9a10, 0x5288,
+ 0x9a16, 0x2412,
+ 0x9a17, 0x528e,
+ 0x9a19, 0x20b7,
+ 0x9a1a, 0x5290,
+ 0x9a2b, 0x23f0,
+ 0x9a2c, 0x52a1,
+ 0x9a2d, 0x2411,
+ 0x9a2e, 0x2414,
+ 0x9a2f, 0x52a2,
+ 0x9a30, 0x2170,
+ 0x9a31, 0x52a3,
+ 0x9a36, 0x2405,
+ 0x9a37, 0x210c,
+ 0x9a38, 0x2415,
+ 0x9a39, 0x52a8,
+ 0x9a3e, 0x2066,
+ 0x9a3f, 0x52ad,
+ 0x9a40, 0x2352,
+ 0x9a41, 0x2413,
+ 0x9a42, 0x2410,
+ 0x9a43, 0x2416,
+ 0x9a45, 0x20f1,
+ 0x9a46, 0x52ae,
+ 0x9a4a, 0x240a,
+ 0x9a4b, 0x52b2,
+ 0x9a4d, 0x2409,
+ 0x9a4e, 0x52b4,
+ 0x9a4f, 0x2418,
+ 0x9a50, 0x52b5,
+ 0x9a55, 0x1fa7,
+ 0x9a56, 0x52ba,
+ 0x9a57, 0x21fc,
+ 0x9a58, 0x52bb,
+ 0x9a5a, 0x1fc1,
+ 0x9a5b, 0x2406,
+ 0x9a5c, 0x52bd,
+ 0x9a5f, 0x229c,
+ 0x9a60, 0x52c0,
+ 0x9a62, 0x204e,
+ 0x9a63, 0x52c2,
+ 0x9a64, 0x241a,
+ 0x9a65, 0x2419,
+ 0x9a66, 0x52c3,
+ 0x9a6a, 0x240c,
+ 0x9a6b, 0x52c7,
+ 0x9a6c, 0x0a94,
+ 0x9a6d, 0x10e9,
+ 0x9a6e, 0x0e85,
+ 0x9a6f, 0x0fda,
+ 0x9a70, 0x0500,
+ 0x9a71, 0x0c7a,
+ 0x9a72, 0x52c8,
+ 0x9a73, 0x047c,
+ 0x9a74, 0x0a66,
+ 0x9a75, 0x17ba,
+ 0x9a76, 0x0d52,
+ 0x9a77, 0x17bb,
+ 0x9a79, 0x0903,
+ 0x9a7a, 0x17bd,
+ 0x9a7b, 0x1201,
+ 0x9a7c, 0x0e86,
+ 0x9a7d, 0x17bf,
+ 0x9a7e, 0x0850,
+ 0x9a7f, 0x17be,
+ 0x9a80, 0x17c0,
+ 0x9a82, 0x0a95,
+ 0x9a83, 0x52c9,
+ 0x9a84, 0x088f,
+ 0x9a85, 0x17c2,
+ 0x9a86, 0x0a8d,
+ 0x9a87, 0x075e,
+ 0x9a88, 0x17c3,
+ 0x9a89, 0x52ca,
+ 0x9a8a, 0x17c4,
+ 0x9a8b, 0x04f7,
+ 0x9a8c, 0x1012,
+ 0x9a8d, 0x52cb,
+ 0x9a8f, 0x0932,
+ 0x9a90, 0x17c5,
+ 0x9a91, 0x0c0e,
+ 0x9a92, 0x17c6,
+ 0x9a94, 0x52cd,
+ 0x9a96, 0x17c8,
+ 0x9a97, 0x0bcc,
+ 0x9a98, 0x17c9,
+ 0x9a99, 0x52cf,
+ 0x9a9a, 0x0ce0,
+ 0x9a9b, 0x17ca,
+ 0x9a9e, 0x1735,
+ 0x9a9f, 0x17cd,
+ 0x9aa1, 0x0a89,
+ 0x9aa2, 0x17cf,
+ 0x9aa4, 0x11e7,
+ 0x9aa5, 0x17d1,
+ 0x9aa6, 0x52d0,
+ 0x9aa7, 0x17d2,
+ 0x9aa8, 0x0720,
+ 0x9aa9, 0x52d1,
+ 0x9aaf, 0x1e29,
+ 0x9ab0, 0x1dd3,
+ 0x9ab1, 0x1dd2,
+ 0x9ab2, 0x52d7,
+ 0x9ab6, 0x1dd6,
+ 0x9ab7, 0x1dd4,
+ 0x9ab8, 0x0758,
+ 0x9ab9, 0x52db,
+ 0x9aba, 0x1dd7,
+ 0x9abb, 0x52dc,
+ 0x9abc, 0x1dd8,
+ 0x9abd, 0x52dd,
+ 0x9ac0, 0x1dda,
+ 0x9ac1, 0x1dd9,
+ 0x9ac2, 0x1ddc,
+ 0x9ac3, 0x52e0,
+ 0x9ac5, 0x1ddb,
+ 0x9ac6, 0x52e2,
+ 0x9acb, 0x1ddd,
+ 0x9acd, 0x52e7,
+ 0x9acf, 0x2661,
+ 0x9ad0, 0x52e9,
+ 0x9ad1, 0x1ddf,
+ 0x9ad2, 0x26a4,
+ 0x9ad3, 0x0ddd,
+ 0x9ad4, 0x2174,
+ 0x9ad5, 0x2663,
+ 0x9ad6, 0x2662,
+ 0x9ad7, 0x52ea,
+ 0x9ad8, 0x06da,
+ 0x9ad9, 0x52eb,
+ 0x9adf, 0x1dec,
+ 0x9ae0, 0x52f1,
+ 0x9ae1, 0x1ded,
+ 0x9ae2, 0x52f2,
+ 0x9ae6, 0x1dee,
+ 0x9ae7, 0x52f6,
+ 0x9aeb, 0x1df0,
+ 0x9aec, 0x52fa,
+ 0x9aed, 0x1df2,
+ 0x9aee, 0x2675,
+ 0x9aef, 0x1def,
+ 0x9af0, 0x52fb,
+ 0x9af9, 0x1df3,
+ 0x9afa, 0x5304,
+ 0x9afb, 0x1df1,
+ 0x9afc, 0x5305,
+ 0x9b00, 0x5309,
+ 0x9b03, 0x1234,
+ 0x9b04, 0x530c,
+ 0x9b06, 0x214c,
+ 0x9b07, 0x530e,
+ 0x9b08, 0x1df4,
+ 0x9b09, 0x530f,
+ 0x9b0d, 0x267a,
+ 0x9b0e, 0x5313,
+ 0x9b0f, 0x1df5,
+ 0x9b10, 0x5314,
+ 0x9b13, 0x1df6,
+ 0x9b14, 0x5317,
+ 0x9b1a, 0x26a0,
+ 0x9b1b, 0x531d,
+ 0x9b1f, 0x1df7,
+ 0x9b20, 0x5321,
+ 0x9b22, 0x2668,
+ 0x9b23, 0x1df8,
+ 0x9b24, 0x5323,
+ 0x9b25, 0x1ed0,
+ 0x9b26, 0x5324,
+ 0x9b27, 0x2096,
+ 0x9b28, 0x5325,
+ 0x9b29, 0x23cc,
+ 0x9b2a, 0x5326,
+ 0x9b2e, 0x23c8,
+ 0x9b2f, 0x139b,
+ 0x9b30, 0x532a,
+ 0x9b31, 0x223e,
+ 0x9b32, 0x1260,
+ 0x9b33, 0x532b,
+ 0x9b3b, 0x1773,
+ 0x9b3c, 0x0746,
+ 0x9b3d, 0x5333,
+ 0x9b41, 0x098a,
+ 0x9b42, 0x07ff,
+ 0x9b43, 0x1de1,
+ 0x9b44, 0x0be6,
+ 0x9b45, 0x1de0,
+ 0x9b46, 0x5337,
+ 0x9b47, 0x1de2,
+ 0x9b48, 0x1de4,
+ 0x9b49, 0x1de3,
+ 0x9b4a, 0x5338,
+ 0x9b4d, 0x1de5,
+ 0x9b4e, 0x2665,
+ 0x9b4f, 0x0ec9,
+ 0x9b50, 0x533b,
+ 0x9b51, 0x1de6,
+ 0x9b52, 0x533c,
+ 0x9b54, 0x0b0a,
+ 0x9b55, 0x533e,
+ 0x9b58, 0x2664,
+ 0x9b59, 0x5341,
+ 0x9b5a, 0x2239,
+ 0x9b5b, 0x5342,
+ 0x9b6f, 0x204a,
+ 0x9b70, 0x5356,
+ 0x9b74, 0x261f,
+ 0x9b75, 0x535a,
+ 0x9b77, 0x261e,
+ 0x9b78, 0x535c,
+ 0x9b81, 0x2620,
+ 0x9b82, 0x5365,
+ 0x9b83, 0x2621,
+ 0x9b84, 0x5366,
+ 0x9b8e, 0x2622,
+ 0x9b8f, 0x5370,
+ 0x9b90, 0x2627,
+ 0x9b91, 0x1e39,
+ 0x9b92, 0x2625,
+ 0x9b93, 0x5371,
+ 0x9b9a, 0x2629,
+ 0x9b9b, 0x5378,
+ 0x9b9d, 0x262e,
+ 0x9b9e, 0x262b,
+ 0x9b9f, 0x537a,
+ 0x9baa, 0x262a,
+ 0x9bab, 0x262d,
+ 0x9bac, 0x5385,
+ 0x9bad, 0x2628,
+ 0x9bae, 0x21b9,
+ 0x9baf, 0x5386,
+ 0x9bc0, 0x2636,
+ 0x9bc1, 0x2630,
+ 0x9bc2, 0x5397,
+ 0x9bc7, 0x2638,
+ 0x9bc8, 0x539c,
+ 0x9bc9, 0x200d,
+ 0x9bca, 0x2637,
+ 0x9bcb, 0x539d,
+ 0x9bd4, 0x2645,
+ 0x9bd5, 0x53a6,
+ 0x9bd6, 0x263a,
+ 0x9bd7, 0x53a7,
+ 0x9bdb, 0x2643,
+ 0x9bdc, 0x53ab,
+ 0x9bdd, 0x2640,
+ 0x9bde, 0x53ac,
+ 0x9be1, 0x263d,
+ 0x9be2, 0x2641,
+ 0x9be3, 0x53af,
+ 0x9be4, 0x263e,
+ 0x9be5, 0x53b0,
+ 0x9be7, 0x263f,
+ 0x9be8, 0x1fc0,
+ 0x9be9, 0x53b2,
+ 0x9bea, 0x263b,
+ 0x9bec, 0x53b3,
+ 0x9bf0, 0x2642,
+ 0x9bf1, 0x53b7,
+ 0x9bf4, 0x2644,
+ 0x9bf5, 0x53ba,
+ 0x9bfd, 0x2639,
+ 0x9bfe, 0x53c2,
+ 0x9bff, 0x264c,
+ 0x9c00, 0x53c3,
+ 0x9c08, 0x2647,
+ 0x9c09, 0x264b,
+ 0x9c0a, 0x53cb,
+ 0x9c0d, 0x2649,
+ 0x9c0e, 0x53ce,
+ 0x9c10, 0x2648,
+ 0x9c11, 0x53d0,
+ 0x9c12, 0x264a,
+ 0x9c13, 0x2108,
+ 0x9c14, 0x53d1,
+ 0x9c20, 0x264d,
+ 0x9c21, 0x53dd,
+ 0x9c23, 0x2634,
+ 0x9c24, 0x53df,
+ 0x9c25, 0x2651,
+ 0x9c26, 0x53e0,
+ 0x9c28, 0x2650,
+ 0x9c29, 0x2652,
+ 0x9c2a, 0x53e2,
+ 0x9c2d, 0x264f,
+ 0x9c2e, 0x53e5,
+ 0x9c31, 0x2632,
+ 0x9c32, 0x264e,
+ 0x9c33, 0x2653,
+ 0x9c34, 0x53e8,
+ 0x9c35, 0x2657,
+ 0x9c36, 0x53e9,
+ 0x9c37, 0x2635,
+ 0x9c38, 0x53ea,
+ 0x9c39, 0x2633,
+ 0x9c3a, 0x53eb,
+ 0x9c3b, 0x2656,
+ 0x9c3c, 0x53ec,
+ 0x9c3e, 0x2654,
+ 0x9c3f, 0x53ee,
+ 0x9c45, 0x2658,
+ 0x9c46, 0x53f4,
+ 0x9c48, 0x2655,
+ 0x9c49, 0x1e4d,
+ 0x9c4a, 0x53f6,
+ 0x9c52, 0x265b,
+ 0x9c53, 0x53fe,
+ 0x9c54, 0x265a,
+ 0x9c55, 0x53ff,
+ 0x9c56, 0x2659,
+ 0x9c57, 0x202e,
+ 0x9c58, 0x262f,
+ 0x9c59, 0x5400,
+ 0x9c5d, 0x2646,
+ 0x9c5e, 0x5404,
+ 0x9c5f, 0x2626,
+ 0x9c60, 0x5405,
+ 0x9c67, 0x265c,
+ 0x9c68, 0x540c,
+ 0x9c6d, 0x262c,
+ 0x9c6e, 0x5411,
+ 0x9c78, 0x2623,
+ 0x9c79, 0x541b,
+ 0x9c7a, 0x2631,
+ 0x9c7b, 0x541c,
+ 0x9c7c, 0x10c8,
+ 0x9c7d, 0x541d,
+ 0x9c7f, 0x1d89,
+ 0x9c80, 0x541f,
+ 0x9c81, 0x0a5a,
+ 0x9c82, 0x1d8a,
+ 0x9c83, 0x5420,
+ 0x9c85, 0x1d8b,
+ 0x9c89, 0x5422,
+ 0x9c8b, 0x1d90,
+ 0x9c8c, 0x5424,
+ 0x9c8d, 0x0414,
+ 0x9c8e, 0x1d91,
+ 0x9c8f, 0x5425,
+ 0x9c90, 0x1d92,
+ 0x9c93, 0x5426,
+ 0x9c94, 0x1d95,
+ 0x9c96, 0x5427,
+ 0x9c9a, 0x1d97,
+ 0x9c9c, 0x0f37,
+ 0x9c9d, 0x542b,
+ 0x9c9e, 0x1d99,
+ 0x9ca4, 0x09db,
+ 0x9ca5, 0x1d9f,
+ 0x9caa, 0x542c,
+ 0x9cab, 0x1da4,
+ 0x9cac, 0x542d,
+ 0x9cad, 0x1da5,
+ 0x9caf, 0x542e,
+ 0x9cb0, 0x1da7,
+ 0x9cb8, 0x08d7,
+ 0x9cb9, 0x542f,
+ 0x9cba, 0x1daf,
+ 0x9cbe, 0x5430,
+ 0x9cc3, 0x0cd5,
+ 0x9cc4, 0x1db3,
+ 0x9cc8, 0x5435,
+ 0x9cca, 0x1db7,
+ 0x9cd1, 0x5437,
+ 0x9cd3, 0x1dbe,
+ 0x9cd6, 0x0457,
+ 0x9cd7, 0x1dc1,
+ 0x9cda, 0x5439,
+ 0x9cdc, 0x1dc4,
+ 0x9cde, 0x0a24,
+ 0x9cdf, 0x1dc6,
+ 0x9ce0, 0x543b,
+ 0x9ce2, 0x1dc7,
+ 0x9ce3, 0x543d,
+ 0x9ce5, 0x209c,
+ 0x9ce6, 0x543f,
+ 0x9ce9, 0x2580,
+ 0x9cea, 0x5442,
+ 0x9cec, 0x22dc,
+ 0x9ced, 0x5444,
+ 0x9cf3, 0x1f05,
+ 0x9cf4, 0x208b,
+ 0x9cf5, 0x544a,
+ 0x9cf6, 0x2581,
+ 0x9cf7, 0x544b,
+ 0x9d00, 0x5454,
+ 0x9d06, 0x2583,
+ 0x9d07, 0x2582,
+ 0x9d08, 0x545a,
+ 0x9d09, 0x21ee,
+ 0x9d0a, 0x545b,
+ 0x9d15, 0x2182,
+ 0x9d16, 0x5466,
+ 0x9d1b, 0x2243,
+ 0x9d1c, 0x546b,
+ 0x9d1d, 0x2587,
+ 0x9d1e, 0x546c,
+ 0x9d1f, 0x2588,
+ 0x9d20, 0x546d,
+ 0x9d23, 0x2584,
+ 0x9d24, 0x5470,
+ 0x9d26, 0x21fd,
+ 0x9d27, 0x5472,
+ 0x9d28, 0x21ef,
+ 0x9d29, 0x5473,
+ 0x9d2f, 0x258a,
+ 0x9d30, 0x258c,
+ 0x9d31, 0x5479,
+ 0x9d3b, 0x1f47,
+ 0x9d3c, 0x5483,
+ 0x9d3f, 0x1f1d,
+ 0x9d40, 0x5486,
+ 0x9d42, 0x258d,
+ 0x9d43, 0x5488,
+ 0x9d51, 0x1fd0,
+ 0x9d52, 0x2592,
+ 0x9d53, 0x258f,
+ 0x9d54, 0x5496,
+ 0x9d5c, 0x2594,
+ 0x9d5d, 0x1ee0,
+ 0x9d5e, 0x549e,
+ 0x9d60, 0x2591,
+ 0x9d61, 0x2595,
+ 0x9d62, 0x54a0,
+ 0x9d6a, 0x2597,
+ 0x9d6b, 0x54a8,
+ 0x9d6c, 0x20b6,
+ 0x9d6d, 0x54a9,
+ 0x9d6f, 0x2598,
+ 0x9d70, 0x54ab,
+ 0x9d72, 0x20f6,
+ 0x9d73, 0x54ad,
+ 0x9d87, 0x2585,
+ 0x9d88, 0x54c1,
+ 0x9d89, 0x2599,
+ 0x9d8a, 0x54c2,
+ 0x9d93, 0x2596,
+ 0x9d94, 0x54cb,
+ 0x9d98, 0x259a,
+ 0x9d99, 0x54cf,
+ 0x9d9a, 0x259b,
+ 0x9d9b, 0x54d0,
+ 0x9da5, 0x259d,
+ 0x9da6, 0x54da,
+ 0x9da9, 0x259e,
+ 0x9daa, 0x54dd,
+ 0x9daf, 0x234c,
+ 0x9db0, 0x54e2,
+ 0x9db4, 0x1f44,
+ 0x9db5, 0x54e6,
+ 0x9dbb, 0x2660,
+ 0x9dbc, 0x25a0,
+ 0x9dbd, 0x54ec,
+ 0x9dc0, 0x259c,
+ 0x9dc1, 0x54ef,
+ 0x9dc2, 0x259f,
+ 0x9dc3, 0x54f0,
+ 0x9dc4, 0x1f6c,
+ 0x9dc5, 0x54f1,
+ 0x9dd3, 0x25a2,
+ 0x9dd4, 0x54ff,
+ 0x9dd7, 0x20ae,
+ 0x9dd8, 0x5502,
+ 0x9dd9, 0x258b,
+ 0x9dda, 0x25a3,
+ 0x9ddb, 0x5503,
+ 0x9de5, 0x2589,
+ 0x9de6, 0x25a5,
+ 0x9de7, 0x550d,
+ 0x9def, 0x25a4,
+ 0x9df0, 0x5515,
+ 0x9df2, 0x25a6,
+ 0x9df3, 0x2593,
+ 0x9df4, 0x5517,
+ 0x9df8, 0x25a7,
+ 0x9df9, 0x2222,
+ 0x9dfa, 0x25a9,
+ 0x9dfb, 0x551b,
+ 0x9e00, 0x5520,
+ 0x9e0c, 0x25a8,
+ 0x9e0d, 0x552c,
+ 0x9e15, 0x2586,
+ 0x9e16, 0x5534,
+ 0x9e1a, 0x25a1,
+ 0x9e1b, 0x25aa,
+ 0x9e1c, 0x5538,
+ 0x9e1d, 0x2590,
+ 0x9e1e, 0x258e,
+ 0x9e1f, 0x0b54,
+ 0x9e20, 0x1b35,
+ 0x9e21, 0x0819,
+ 0x9e22, 0x1b36,
+ 0x9e23, 0x0afe,
+ 0x9e24, 0x5539,
+ 0x9e25, 0x0b79,
+ 0x9e26, 0x0fe4,
+ 0x9e27, 0x553a,
+ 0x9e28, 0x1b37,
+ 0x9e2d, 0x0fe5,
+ 0x9e2e, 0x553b,
+ 0x9e2f, 0x1015,
+ 0x9e30, 0x553c,
+ 0x9e31, 0x1b3d,
+ 0x9e32, 0x1b3c,
+ 0x9e33, 0x10ea,
+ 0x9e34, 0x553d,
+ 0x9e35, 0x0e83,
+ 0x9e36, 0x1b3e,
+ 0x9e37, 0x1b40,
+ 0x9e38, 0x1b3f,
+ 0x9e39, 0x1b41,
+ 0x9e3b, 0x553e,
+ 0x9e3d, 0x06e6,
+ 0x9e3e, 0x1b43,
+ 0x9e3f, 0x079f,
+ 0x9e40, 0x5540,
+ 0x9e41, 0x1b44,
+ 0x9e43, 0x0918,
+ 0x9e44, 0x1b46,
+ 0x9e45, 0x062b,
+ 0x9e46, 0x1b47,
+ 0x9e4a, 0x0c90,
+ 0x9e4b, 0x1b4b,
+ 0x9e4d, 0x5541,
+ 0x9e4e, 0x1b4d,
+ 0x9e4f, 0x0bb5,
+ 0x9e50, 0x5542,
+ 0x9e51, 0x1b4e,
+ 0x9e52, 0x5543,
+ 0x9e55, 0x1b4f,
+ 0x9e56, 0x5546,
+ 0x9e57, 0x1b50,
+ 0x9e58, 0x1dd5,
+ 0x9e59, 0x5547,
+ 0x9e5a, 0x1b51,
+ 0x9e5d, 0x5548,
+ 0x9e5e, 0x1b54,
+ 0x9e5f, 0x5549,
+ 0x9e63, 0x1b55,
+ 0x9e64, 0x078e,
+ 0x9e65, 0x554d,
+ 0x9e66, 0x1b56,
+ 0x9e6d, 0x1b5e,
+ 0x9e6e, 0x554e,
+ 0x9e70, 0x108a,
+ 0x9e71, 0x1b5d,
+ 0x9e72, 0x5550,
+ 0x9e73, 0x1b5f,
+ 0x9e74, 0x5551,
+ 0x9e75, 0x2688,
+ 0x9e76, 0x5552,
+ 0x9e79, 0x269e,
+ 0x9e7a, 0x25fb,
+ 0x9e7b, 0x5555,
+ 0x9e7c, 0x1f8c,
+ 0x9e7d, 0x21f4,
+ 0x9e7e, 0x1d16,
+ 0x9e7f, 0x0a60,
+ 0x9e80, 0x5556,
+ 0x9e82, 0x1dfc,
+ 0x9e83, 0x5558,
+ 0x9e87, 0x1dfd,
+ 0x9e89, 0x555c,
+ 0x9e8b, 0x1dff,
+ 0x9e8c, 0x555e,
+ 0x9e92, 0x1e00,
+ 0x9e93, 0x0a5b,
+ 0x9e94, 0x5564,
+ 0x9e97, 0x200f,
+ 0x9e98, 0x5567,
+ 0x9e9d, 0x1e02,
+ 0x9e9e, 0x556c,
+ 0x9e9f, 0x1e03,
+ 0x9ea0, 0x556d,
+ 0x9ea5, 0x2071,
+ 0x9ea6, 0x0a9a,
+ 0x9ea7, 0x5572,
+ 0x9ea9, 0x25f7,
+ 0x9eaa, 0x5574,
+ 0x9eaf, 0x2696,
+ 0x9eb0, 0x5579,
+ 0x9eb4, 0x1cee,
+ 0x9eb5, 0x268f,
+ 0x9eb6, 0x557d,
+ 0x9eb8, 0x1ced,
+ 0x9eb9, 0x557f,
+ 0x9ebb, 0x0a90,
+ 0x9ebc, 0x5581,
+ 0x9ebd, 0x1df9,
+ 0x9ebf, 0x5582,
+ 0x9ec4, 0x07db,
+ 0x9ec5, 0x5587,
+ 0x9ec9, 0x12f8,
+ 0x9eca, 0x558b,
+ 0x9ecc, 0x22da,
+ 0x9ecd, 0x0d89,
+ 0x9ece, 0x09d3,
+ 0x9ecf, 0x1b2a,
+ 0x9ed0, 0x558d,
+ 0x9ed1, 0x0791,
+ 0x9ed2, 0x558e,
+ 0x9ed4, 0x0c2a,
+ 0x9ed5, 0x5590,
+ 0x9ed8, 0x0b0f,
+ 0x9ed9, 0x5593,
+ 0x9edb, 0x1e04,
+ 0x9ede, 0x1ec1,
+ 0x9edf, 0x1e08,
+ 0x9ee0, 0x1e07,
+ 0x9ee1, 0x5595,
+ 0x9ee2, 0x1e09,
+ 0x9ee3, 0x5596,
+ 0x9ee5, 0x1e0c,
+ 0x9ee6, 0x5598,
+ 0x9ee7, 0x1e0b,
+ 0x9ee8, 0x1eb3,
+ 0x9ee9, 0x1e0a,
+ 0x9eea, 0x1e0d,
+ 0x9eeb, 0x5599,
+ 0x9eef, 0x1e0e,
+ 0x9ef0, 0x559d,
+ 0x9ef2, 0x266a,
+ 0x9ef3, 0x559f,
+ 0x9ef4, 0x268a,
+ 0x9ef5, 0x55a0,
+ 0x9ef7, 0x2669,
+ 0x9ef8, 0x55a2,
+ 0x9ef9, 0x1a55,
+ 0x9efa, 0x55a3,
+ 0x9efb, 0x1a56,
+ 0x9efd, 0x2618,
+ 0x9efe, 0x1d76,
+ 0x9eff, 0x2619,
+ 0x9f00, 0x55a4,
+ 0x9f09, 0x261a,
+ 0x9f0a, 0x55ad,
+ 0x9f0b, 0x1d77,
+ 0x9f0c, 0x55ae,
+ 0x9f0d, 0x1d78,
+ 0x9f0e, 0x05e5,
+ 0x9f0f, 0x55af,
+ 0x9f10, 0x1274,
+ 0x9f11, 0x55b0,
+ 0x9f13, 0x071d,
+ 0x9f14, 0x55b2,
+ 0x9f15, 0x2673,
+ 0x9f16, 0x55b3,
+ 0x9f17, 0x1271,
+ 0x9f18, 0x55b4,
+ 0x9f19, 0x13df,
+ 0x9f1a, 0x55b5,
+ 0x9f20, 0x0d8a,
+ 0x9f21, 0x55bb,
+ 0x9f22, 0x1e0f,
+ 0x9f23, 0x55bc,
+ 0x9f2c, 0x1e10,
+ 0x9f2d, 0x55c5,
+ 0x9f2f, 0x1e11,
+ 0x9f30, 0x55c7,
+ 0x9f37, 0x1e13,
+ 0x9f38, 0x55ce,
+ 0x9f39, 0x1e12,
+ 0x9f3a, 0x55cf,
+ 0x9f3b, 0x0430,
+ 0x9f3c, 0x55d0,
+ 0x9f3d, 0x1e14,
+ 0x9f3f, 0x55d1,
+ 0x9f44, 0x1e16,
+ 0x9f45, 0x55d6,
+ 0x9f4a, 0x20c6,
+ 0x9f4b, 0x226b,
+ 0x9f4c, 0x55db,
+ 0x9f4f, 0x24d3,
+ 0x9f50, 0x0c0a,
+ 0x9f51, 0x19c2,
+ 0x9f52, 0x1e86,
+ 0x9f53, 0x55de,
+ 0x9f54, 0x260f,
+ 0x9f55, 0x55df,
+ 0x9f59, 0x2611,
+ 0x9f5a, 0x55e3,
+ 0x9f5c, 0x2613,
+ 0x9f5d, 0x55e5,
+ 0x9f5f, 0x2610,
+ 0x9f60, 0x2612,
+ 0x9f61, 0x2030,
+ 0x9f62, 0x55e7,
+ 0x9f63, 0x2671,
+ 0x9f64, 0x55e8,
+ 0x9f66, 0x2614,
+ 0x9f67, 0x55ea,
+ 0x9f6a, 0x2616,
+ 0x9f6b, 0x55ed,
+ 0x9f6c, 0x2615,
+ 0x9f6d, 0x55ee,
+ 0x9f72, 0x20f2,
+ 0x9f73, 0x55f3,
+ 0x9f77, 0x2617,
+ 0x9f78, 0x55f7,
+ 0x9f7f, 0x0502,
+ 0x9f80, 0x1d6d,
+ 0x9f81, 0x55fe,
+ 0x9f83, 0x1d6e,
+ 0x9f84, 0x0a2d,
+ 0x9f85, 0x1d6f,
+ 0x9f8b, 0x0c7e,
+ 0x9f8c, 0x1d75,
+ 0x9f8d, 0x2037,
+ 0x9f8e, 0x5600,
+ 0x9f90, 0x20b3,
+ 0x9f91, 0x5602,
+ 0x9f94, 0x1f22,
+ 0x9f95, 0x24ed,
+ 0x9f96, 0x5605,
+ 0x9f99, 0x0a43,
+ 0x9f9a, 0x0701,
+ 0x9f9b, 0x1a54,
+ 0x9f9c, 0x1f34,
+ 0x9f9d, 0x5608,
+ 0x9f9f, 0x0743,
+ 0x9fa0, 0x12f3,
+ 0x9fa1, 0x560a,
+ 0xe7e7, 0x274b,
+ 0xe815, 0x561f,
+ 0xf92c, 0x560f,
+ 0xfa0d, 0x5610,
+ 0xfa11, 0x5613,
+ 0xfa13, 0x5614,
+ 0xfa18, 0x5616,
+ 0xfa1f, 0x5617,
+ 0xfa23, 0x561a,
+ 0xfa27, 0x561c,
+ 0xfe30, 0x271d,
+ 0xfe49, 0x272b,
+ 0xfe54, 0x2735,
+ 0xfe59, 0x2739,
+ 0xfe68, 0x2747,
+ 0xff01, 0x0106,
+ 0xff04, 0x00a6,
+ 0xff05, 0x010a,
+ 0xff5e, 0x006a,
+ 0xffe0, 0x00a8,
+ 0xffe2, 0x271e,
+ 0xffe3, 0x0163,
+ 0xffe4, 0x271f,
+ 0xffe5, 0x0109,
+ 0x2014, 0x0256,
+ 0x2026, 0x0257,
+ 0x2225, 0x1e1c,
+ 0x3001, 0x023f,
+ 0x3002, 0x023e,
+ 0x3008, 0x0248,
+ 0x3010, 0x0252,
+ 0x3013, 0x1e1a,
+ 0x3014, 0x0246,
+ 0x3016, 0x0250,
+ 0xff01, 0x0242,
+ 0xff08, 0x0244,
+ 0xff0c, 0x023d,
+ 0xff0e, 0x1e1b,
+ 0xff1a, 0x0240,
+ 0xff1d, 0x1e1c,
+ 0xff1f, 0x0243,
+ 0xff3b, 0x1e1d,
+ 0xff3d, 0x1e1e,
+ 0xff3f, 0x0258,
+ 0xff5b, 0x0254,
+ 0xff5d, 0x0255,
+ 0xff5e, 0x1e18,
+ 0xffe3, 0x1e1f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12UniGBUCS2VEnc16 = {
+ 1,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12UniGBUCS2VMap2, 13485
+};
+
+static Gushort gb12AdobeGB12VMap2[178] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0x2100, 0x2100,
+ 0x2200, 0x2200,
+ 0x2300, 0x2300,
+ 0x2400, 0x2400,
+ 0x2500, 0x2500,
+ 0x2600, 0x2600,
+ 0x2700, 0x2700,
+ 0x2800, 0x2800,
+ 0x2900, 0x2900,
+ 0x2a00, 0x2a00,
+ 0x2b00, 0x2b00,
+ 0x2c00, 0x2c00,
+ 0x2d00, 0x2d00,
+ 0x2e00, 0x2e00,
+ 0x2f00, 0x2f00,
+ 0x3000, 0x3000,
+ 0x3100, 0x3100,
+ 0x3200, 0x3200,
+ 0x3300, 0x3300,
+ 0x3400, 0x3400,
+ 0x3500, 0x3500,
+ 0x3600, 0x3600,
+ 0x3700, 0x3700,
+ 0x3800, 0x3800,
+ 0x3900, 0x3900,
+ 0x3a00, 0x3a00,
+ 0x3b00, 0x3b00,
+ 0x3c00, 0x3c00,
+ 0x3d00, 0x3d00,
+ 0x3e00, 0x3e00,
+ 0x3f00, 0x3f00,
+ 0x4000, 0x4000,
+ 0x4100, 0x4100,
+ 0x4200, 0x4200,
+ 0x4300, 0x4300,
+ 0x4400, 0x4400,
+ 0x4500, 0x4500,
+ 0x4600, 0x4600,
+ 0x4700, 0x4700,
+ 0x4800, 0x4800,
+ 0x4900, 0x4900,
+ 0x4a00, 0x4a00,
+ 0x4b00, 0x4b00,
+ 0x4c00, 0x4c00,
+ 0x4d00, 0x4d00,
+ 0x4e00, 0x4e00,
+ 0x4f00, 0x4f00,
+ 0x5000, 0x5000,
+ 0x5100, 0x5100,
+ 0x5200, 0x5200,
+ 0x5300, 0x5300,
+ 0x5400, 0x5400,
+ 0x5500, 0x5500,
+ 0x5600, 0x5600,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 gb12AdobeGB12VEnc16 = {
+ 1,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ gb12AdobeGB12VMap2, 89
+};
+
+static struct {
+ char *name;
+ GfxFontEncoding16 *enc;
+} gfxGB12Tab[] = {
+ { "Adobe-GB1-0", &gb12AdobeGB10Enc16 },
+ { "Adobe-GB1-1", &gb12AdobeGB11Enc16 },
+ { "Adobe-GB1-2", &gb12AdobeGB12Enc16 },
+ { "GB-EUC-H", &gb12GBEUCHEnc16 },
+ { "GB-EUC-V", &gb12GBEUCVEnc16 },
+ { "GB-H", &gb12GBHEnc16 },
+ { "GB-V", &gb12GBVEnc16 },
+ { "GBK-EUC-H", &gb12GBKEUCHEnc16 },
+ { "GBK-EUC-V", &gb12GBKEUCVEnc16 },
+ { "GBT-EUC-H", &gb12GBTEUCHEnc16 },
+ { "GBT-EUC-V", &gb12GBTEUCVEnc16 },
+ { "GBT-H", &gb12GBTHEnc16 },
+ { "GBT-V", &gb12GBTVEnc16 },
+ { "GBTpc-EUC-H", &gb12GBTpcEUCHEnc16 },
+ { "GBTpc-EUC-V", &gb12GBTpcEUCVEnc16 },
+ { "GBpc-EUC-H", &gb12GBpcEUCHEnc16 },
+ { "GBpc-EUC-V", &gb12GBpcEUCVEnc16 },
+ { "UniGB-UCS2-H", &gb12UniGBUCS2HEnc16 },
+ { "UniGB-UCS2-V", &gb12UniGBUCS2VEnc16 },
+ { "Identity-H", &gb12AdobeGB12Enc16 },
+ { "Identity-V", &gb12AdobeGB12VEnc16 },
+ { NULL, NULL }
+};
+
+#endif
diff --git a/pdftops/GString.cxx b/pdftops/GString.cxx
new file mode 100644
index 000000000..7b8f27184
--- /dev/null
+++ b/pdftops/GString.cxx
@@ -0,0 +1,223 @@
+//========================================================================
+//
+// GString.cc
+//
+// Simple variable-length string type.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <ctype.h>
+#include "gtypes.h"
+#include "GString.h"
+
+static inline int size(int len) {
+ int delta;
+
+ delta = len < 256 ? 7 : 255;
+ return ((len + 1) + delta) & ~delta;
+}
+
+inline void GString::resize(int length1) {
+ char *s1;
+
+ if (!s) {
+ s = new char[size(length1)];
+ } else if (size(length1) != size(length)) {
+ s1 = new char[size(length1)];
+ memcpy(s1, s, length + 1);
+ delete[] s;
+ s = s1;
+ }
+}
+
+GString::GString() {
+ s = NULL;
+ resize(length = 0);
+ s[0] = '\0';
+}
+
+GString::GString(const char *s1) {
+ int n = strlen(s1);
+
+ s = NULL;
+ resize(length = n);
+ memcpy(s, s1, n + 1);
+}
+
+GString::GString(const char *s1, int length1) {
+ s = NULL;
+ resize(length = length1);
+ memcpy(s, s1, length * sizeof(char));
+ s[length] = '\0';
+}
+
+GString::GString(GString *str) {
+ s = NULL;
+ resize(length = str->getLength());
+ memcpy(s, str->getCString(), length + 1);
+}
+
+GString::GString(GString *str1, GString *str2) {
+ int n1 = str1->getLength();
+ int n2 = str2->getLength();
+
+ s = NULL;
+ resize(length = n1 + n2);
+ memcpy(s, str1->getCString(), n1);
+ memcpy(s + n1, str2->getCString(), n2 + 1);
+}
+
+GString *GString::fromInt(int x) {
+ char buf[24]; // enough space for 64-bit ints plus a little extra
+ GBool neg;
+ Guint y;
+ int i;
+
+ i = 24;
+ if (x == 0) {
+ buf[--i] = '0';
+ } else {
+ if ((neg = x < 0)) {
+ y = (Guint)-x;
+ } else {
+ y = (Guint)x;
+ }
+ while (i > 0 && y > 0) {
+ buf[--i] = '0' + y % 10;
+ y /= 10;
+ }
+ if (neg && i > 0) {
+ buf[--i] = '-';
+ }
+ }
+ return new GString(buf + i, 24 - i);
+}
+
+GString::~GString() {
+ delete[] s;
+}
+
+GString *GString::clear() {
+ s[length = 0] = '\0';
+ resize(0);
+ return this;
+}
+
+GString *GString::append(char c) {
+ resize(length + 1);
+ s[length++] = c;
+ s[length] = '\0';
+ return this;
+}
+
+GString *GString::append(GString *str) {
+ int n = str->getLength();
+
+ resize(length + n);
+ memcpy(s + length, str->getCString(), n + 1);
+ length += n;
+ return this;
+}
+
+GString *GString::append(const char *str) {
+ int n = strlen(str);
+
+ resize(length + n);
+ memcpy(s + length, str, n + 1);
+ length += n;
+ return this;
+}
+
+GString *GString::append(const char *str, int length1) {
+ resize(length + length1);
+ memcpy(s + length, str, length1);
+ length += length1;
+ s[length] = '\0';
+ return this;
+}
+
+GString *GString::insert(int i, char c) {
+ int j;
+
+ resize(length + 1);
+ for (j = length + 1; j > i; --j)
+ s[j] = s[j-1];
+ s[i] = c;
+ ++length;
+ return this;
+}
+
+GString *GString::insert(int i, GString *str) {
+ int n = str->getLength();
+ int j;
+
+ resize(length + n);
+ for (j = length; j >= i; --j)
+ s[j+n] = s[j];
+ memcpy(s+i, str->getCString(), n);
+ length += n;
+ return this;
+}
+
+GString *GString::insert(int i, const char *str) {
+ int n = strlen(str);
+ int j;
+
+ resize(length + n);
+ for (j = length; j >= i; --j)
+ s[j+n] = s[j];
+ memcpy(s+i, str, n);
+ length += n;
+ return this;
+}
+
+GString *GString::insert(int i, const char *str, int length1) {
+ int j;
+
+ resize(length + length1);
+ for (j = length; j >= i; --j)
+ s[j+length1] = s[j];
+ memcpy(s+i, str, length1);
+ length += length1;
+ return this;
+}
+
+GString *GString::del(int i, int n) {
+ int j;
+
+ if (n > 0) {
+ for (j = i; j <= length - n; ++j)
+ s[j] = s[j + n];
+ resize(length -= n);
+ }
+ return this;
+}
+
+GString *GString::upperCase() {
+ int i;
+
+ for (i = 0; i < length; ++i) {
+ if (islower(s[i]))
+ s[i] = toupper(s[i]);
+ }
+ return this;
+}
+
+GString *GString::lowerCase() {
+ int i;
+
+ for (i = 0; i < length; ++i) {
+ if (isupper(s[i]))
+ s[i] = tolower(s[i]);
+ }
+ return this;
+}
diff --git a/pdftops/GString.h b/pdftops/GString.h
new file mode 100644
index 000000000..4c3b95f34
--- /dev/null
+++ b/pdftops/GString.h
@@ -0,0 +1,95 @@
+//========================================================================
+//
+// GString.h
+//
+// Simple variable-length string type.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef GSTRING_H
+#define GSTRING_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <string.h>
+
+class GString {
+public:
+
+ // Create an empty string.
+ GString();
+
+ // Create a string from a C string.
+ GString(const char *s1);
+
+ // Create a string from <length1> chars at <s1>. This string
+ // can contain null characters.
+ GString (const char *s1, int length1);
+
+ // Copy a string.
+ GString(GString *str);
+ GString *copy() { return new GString(this); }
+
+ // Concatenate two strings.
+ GString(GString *str1, GString *str2);
+
+ // Convert an integer to a string.
+ static GString *fromInt(int x);
+
+ // Destructor.
+ ~GString();
+
+ // Get length.
+ int getLength() { return length; }
+
+ // Get C string.
+ char *getCString() { return s; }
+
+ // Get <i>th character.
+ char getChar(int i) { return s[i]; }
+
+ // Change <i>th character.
+ void setChar(int i, char c) { s[i] = c; }
+
+ // Clear string to zero length.
+ GString *clear();
+
+ // Append a character or string.
+ GString *append(char c);
+ GString *append(GString *str);
+ GString *append(const char *str);
+ GString *append(const char *str, int length1);
+
+ // Insert a character or string.
+ GString *insert(int i, char c);
+ GString *insert(int i, GString *str);
+ GString *insert(int i, const char *str);
+ GString *insert(int i, const char *str, int length1);
+
+ // Delete a character or range of characters.
+ GString *del(int i, int n = 1);
+
+ // Convert string to all-upper/all-lower case.
+ GString *upperCase();
+ GString *lowerCase();
+
+ // Compare two strings: -1:< 0:= +1:>
+ // These functions assume the strings do not contain null characters.
+ int cmp(GString *str) { return strcmp(s, str->getCString()); }
+ int cmpN(GString *str, int n) { return strncmp(s, str->getCString(), n); }
+ int cmp(const char *s1) { return strcmp(s, s1); }
+ int cmpN(const char *s1, int n) { return strncmp(s, s1, n); }
+
+private:
+
+ int length;
+ char *s;
+
+ void resize(int length1);
+};
+
+#endif
diff --git a/pdftops/Gfx.cxx b/pdftops/Gfx.cxx
new file mode 100644
index 000000000..822e6c810
--- /dev/null
+++ b/pdftops/Gfx.cxx
@@ -0,0 +1,2566 @@
+//========================================================================
+//
+// Gfx.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <math.h>
+#include "gmem.h"
+#include "Object.h"
+#include "Array.h"
+#include "Dict.h"
+#include "Stream.h"
+#include "Lexer.h"
+#include "Parser.h"
+#include "GfxFont.h"
+#include "GfxState.h"
+#include "OutputDev.h"
+#include "Params.h"
+#include "Page.h"
+#include "Error.h"
+#include "Gfx.h"
+
+//------------------------------------------------------------------------
+// constants
+//------------------------------------------------------------------------
+
+// Max number of splits along the t axis for an axial shading fill.
+#define axialMaxSplits 256
+
+// Max delta allowed in any color component for an axial shading fill.
+#define axialColorDelta (1 / 256.0)
+
+// Some systems don't define the constant for PI...
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif // !M_PI
+
+//------------------------------------------------------------------------
+// Operator table
+//------------------------------------------------------------------------
+
+Operator Gfx::opTab[] = {
+ {"\"", 3, {tchkNum, tchkNum, tchkString},
+ &Gfx::opMoveSetShowText},
+ {"'", 1, {tchkString},
+ &Gfx::opMoveShowText},
+ {"B", 0, {tchkNone},
+ &Gfx::opFillStroke},
+ {"B*", 0, {tchkNone},
+ &Gfx::opEOFillStroke},
+ {"BDC", 2, {tchkName, tchkProps},
+ &Gfx::opBeginMarkedContent},
+ {"BI", 0, {tchkNone},
+ &Gfx::opBeginImage},
+ {"BMC", 1, {tchkName},
+ &Gfx::opBeginMarkedContent},
+ {"BT", 0, {tchkNone},
+ &Gfx::opBeginText},
+ {"BX", 0, {tchkNone},
+ &Gfx::opBeginIgnoreUndef},
+ {"CS", 1, {tchkName},
+ &Gfx::opSetStrokeColorSpace},
+ {"DP", 2, {tchkName, tchkProps},
+ &Gfx::opMarkPoint},
+ {"Do", 1, {tchkName},
+ &Gfx::opXObject},
+ {"EI", 0, {tchkNone},
+ &Gfx::opEndImage},
+ {"EMC", 0, {tchkNone},
+ &Gfx::opEndMarkedContent},
+ {"ET", 0, {tchkNone},
+ &Gfx::opEndText},
+ {"EX", 0, {tchkNone},
+ &Gfx::opEndIgnoreUndef},
+ {"F", 0, {tchkNone},
+ &Gfx::opFill},
+ {"G", 1, {tchkNum},
+ &Gfx::opSetStrokeGray},
+ {"ID", 0, {tchkNone},
+ &Gfx::opImageData},
+ {"J", 1, {tchkInt},
+ &Gfx::opSetLineCap},
+ {"K", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
+ &Gfx::opSetStrokeCMYKColor},
+ {"M", 1, {tchkNum},
+ &Gfx::opSetMiterLimit},
+ {"MP", 1, {tchkName},
+ &Gfx::opMarkPoint},
+ {"Q", 0, {tchkNone},
+ &Gfx::opRestore},
+ {"RG", 3, {tchkNum, tchkNum, tchkNum},
+ &Gfx::opSetStrokeRGBColor},
+ {"S", 0, {tchkNone},
+ &Gfx::opStroke},
+ {"SC", -4, {tchkNum, tchkNum, tchkNum, tchkNum},
+ &Gfx::opSetStrokeColor},
+ {"SCN", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN,
+ tchkSCN},
+ &Gfx::opSetStrokeColorN},
+ {"T*", 0, {tchkNone},
+ &Gfx::opTextNextLine},
+ {"TD", 2, {tchkNum, tchkNum},
+ &Gfx::opTextMoveSet},
+ {"TJ", 1, {tchkArray},
+ &Gfx::opShowSpaceText},
+ {"TL", 1, {tchkNum},
+ &Gfx::opSetTextLeading},
+ {"Tc", 1, {tchkNum},
+ &Gfx::opSetCharSpacing},
+ {"Td", 2, {tchkNum, tchkNum},
+ &Gfx::opTextMove},
+ {"Tf", 2, {tchkName, tchkNum},
+ &Gfx::opSetFont},
+ {"Tj", 1, {tchkString},
+ &Gfx::opShowText},
+ {"Tm", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
+ tchkNum, tchkNum},
+ &Gfx::opSetTextMatrix},
+ {"Tr", 1, {tchkInt},
+ &Gfx::opSetTextRender},
+ {"Ts", 1, {tchkNum},
+ &Gfx::opSetTextRise},
+ {"Tw", 1, {tchkNum},
+ &Gfx::opSetWordSpacing},
+ {"Tz", 1, {tchkNum},
+ &Gfx::opSetHorizScaling},
+ {"W", 0, {tchkNone},
+ &Gfx::opClip},
+ {"W*", 0, {tchkNone},
+ &Gfx::opEOClip},
+ {"b", 0, {tchkNone},
+ &Gfx::opCloseFillStroke},
+ {"b*", 0, {tchkNone},
+ &Gfx::opCloseEOFillStroke},
+ {"c", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
+ tchkNum, tchkNum},
+ &Gfx::opCurveTo},
+ {"cm", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
+ tchkNum, tchkNum},
+ &Gfx::opConcat},
+ {"cs", 1, {tchkName},
+ &Gfx::opSetFillColorSpace},
+ {"d", 2, {tchkArray, tchkNum},
+ &Gfx::opSetDash},
+ {"d0", 2, {tchkNum, tchkNum},
+ &Gfx::opSetCharWidth},
+ {"d1", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
+ tchkNum, tchkNum},
+ &Gfx::opSetCacheDevice},
+ {"f", 0, {tchkNone},
+ &Gfx::opFill},
+ {"f*", 0, {tchkNone},
+ &Gfx::opEOFill},
+ {"g", 1, {tchkNum},
+ &Gfx::opSetFillGray},
+ {"gs", 1, {tchkName},
+ &Gfx::opSetExtGState},
+ {"h", 0, {tchkNone},
+ &Gfx::opClosePath},
+ {"i", 1, {tchkNum},
+ &Gfx::opSetFlat},
+ {"j", 1, {tchkInt},
+ &Gfx::opSetLineJoin},
+ {"k", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
+ &Gfx::opSetFillCMYKColor},
+ {"l", 2, {tchkNum, tchkNum},
+ &Gfx::opLineTo},
+ {"m", 2, {tchkNum, tchkNum},
+ &Gfx::opMoveTo},
+ {"n", 0, {tchkNone},
+ &Gfx::opEndPath},
+ {"q", 0, {tchkNone},
+ &Gfx::opSave},
+ {"re", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
+ &Gfx::opRectangle},
+ {"rg", 3, {tchkNum, tchkNum, tchkNum},
+ &Gfx::opSetFillRGBColor},
+ {"ri", 1, {tchkName},
+ &Gfx::opSetRenderingIntent},
+ {"s", 0, {tchkNone},
+ &Gfx::opCloseStroke},
+ {"sc", -4, {tchkNum, tchkNum, tchkNum, tchkNum},
+ &Gfx::opSetFillColor},
+ {"scn", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN,
+ tchkSCN},
+ &Gfx::opSetFillColorN},
+ {"sh", 1, {tchkName},
+ &Gfx::opShFill},
+ {"v", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
+ &Gfx::opCurveTo1},
+ {"w", 1, {tchkNum},
+ &Gfx::opSetLineWidth},
+ {"y", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
+ &Gfx::opCurveTo2},
+};
+
+#define numOps (sizeof(opTab) / sizeof(Operator))
+
+//------------------------------------------------------------------------
+// GfxResources
+//------------------------------------------------------------------------
+
+GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) {
+ Object obj1;
+
+ if (resDict) {
+
+ // build font dictionary
+ fonts = NULL;
+ resDict->lookup("Font", &obj1);
+ if (obj1.isDict()) {
+ fonts = new GfxFontDict(xref, obj1.getDict());
+ }
+ obj1.free();
+
+ // get XObject dictionary
+ resDict->lookup("XObject", &xObjDict);
+
+ // get color space dictionary
+ resDict->lookup("ColorSpace", &colorSpaceDict);
+
+ // get pattern dictionary
+ resDict->lookup("Pattern", &patternDict);
+
+ // get shading dictionary
+ resDict->lookup("Shading", &shadingDict);
+
+ // get graphics state parameter dictionary
+ resDict->lookup("ExtGState", &gStateDict);
+
+ } else {
+ fonts = NULL;
+ xObjDict.initNull();
+ colorSpaceDict.initNull();
+ patternDict.initNull();
+ gStateDict.initNull();
+ }
+
+ next = nextA;
+}
+
+GfxResources::~GfxResources() {
+ if (fonts) {
+ delete fonts;
+ }
+ xObjDict.free();
+ colorSpaceDict.free();
+ patternDict.free();
+ shadingDict.free();
+ gStateDict.free();
+}
+
+GfxFont *GfxResources::lookupFont(char *name) {
+ GfxFont *font;
+ GfxResources *resPtr;
+
+ for (resPtr = this; resPtr; resPtr = resPtr->next) {
+ if (resPtr->fonts) {
+ if ((font = resPtr->fonts->lookup(name)))
+ return font;
+ }
+ }
+ error(-1, "Unknown font tag '%s'", name);
+ return NULL;
+}
+
+GBool GfxResources::lookupXObject(char *name, Object *obj) {
+ GfxResources *resPtr;
+
+ for (resPtr = this; resPtr; resPtr = resPtr->next) {
+ if (resPtr->xObjDict.isDict()) {
+ if (!resPtr->xObjDict.dictLookup(name, obj)->isNull())
+ return gTrue;
+ obj->free();
+ }
+ }
+ error(-1, "XObject '%s' is unknown", name);
+ return gFalse;
+}
+
+GBool GfxResources::lookupXObjectNF(char *name, Object *obj) {
+ GfxResources *resPtr;
+
+ for (resPtr = this; resPtr; resPtr = resPtr->next) {
+ if (resPtr->xObjDict.isDict()) {
+ if (!resPtr->xObjDict.dictLookupNF(name, obj)->isNull())
+ return gTrue;
+ obj->free();
+ }
+ }
+ error(-1, "XObject '%s' is unknown", name);
+ return gFalse;
+}
+
+void GfxResources::lookupColorSpace(char *name, Object *obj) {
+ GfxResources *resPtr;
+
+ for (resPtr = this; resPtr; resPtr = resPtr->next) {
+ if (resPtr->colorSpaceDict.isDict()) {
+ if (!resPtr->colorSpaceDict.dictLookup(name, obj)->isNull()) {
+ return;
+ }
+ obj->free();
+ }
+ }
+ obj->initNull();
+}
+
+GfxPattern *GfxResources::lookupPattern(char *name) {
+ GfxResources *resPtr;
+ GfxPattern *pattern;
+ Object obj;
+
+ for (resPtr = this; resPtr; resPtr = resPtr->next) {
+ if (resPtr->patternDict.isDict()) {
+ if (!resPtr->patternDict.dictLookup(name, &obj)->isNull()) {
+ pattern = GfxPattern::parse(&obj);
+ obj.free();
+ return pattern;
+ }
+ obj.free();
+ }
+ }
+ error(-1, "Unknown pattern '%s'", name);
+ return NULL;
+}
+
+GfxShading *GfxResources::lookupShading(char *name) {
+ GfxResources *resPtr;
+ GfxShading *shading;
+ Object obj;
+
+ for (resPtr = this; resPtr; resPtr = resPtr->next) {
+ if (resPtr->shadingDict.isDict()) {
+ if (!resPtr->shadingDict.dictLookup(name, &obj)->isNull()) {
+ shading = GfxShading::parse(&obj);
+ obj.free();
+ return shading;
+ }
+ obj.free();
+ }
+ }
+ error(-1, "Unknown shading '%s'", name);
+ return NULL;
+}
+
+GBool GfxResources::lookupGState(char *name, Object *obj) {
+ GfxResources *resPtr;
+
+ for (resPtr = this; resPtr; resPtr = resPtr->next) {
+ if (resPtr->gStateDict.isDict()) {
+ if (!resPtr->gStateDict.dictLookup(name, obj)->isNull()) {
+ return gTrue;
+ }
+ obj->free();
+ }
+ }
+ error(-1, "ExtGState '%s' is unknown", name);
+ return gFalse;
+}
+
+//------------------------------------------------------------------------
+// Gfx
+//------------------------------------------------------------------------
+
+Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, double dpi,
+ PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate,
+ GBool printCommandsA) {
+ int i;
+
+ xref = xrefA;
+ printCommands = printCommandsA;
+
+ // start the resource stack
+ res = new GfxResources(xref, resDict, NULL);
+
+ // initialize
+ out = outA;
+ state = new GfxState(dpi, box, rotate, out->upsideDown());
+ fontChanged = gFalse;
+ clip = clipNone;
+ ignoreUndef = 0;
+ out->startPage(pageNum, state);
+ out->setDefaultCTM(state->getCTM());
+ out->updateAll(state);
+ for (i = 0; i < 6; ++i) {
+ baseMatrix[i] = state->getCTM()[i];
+ }
+
+ // set crop box
+ if (crop) {
+ state->moveTo(cropBox->x1, cropBox->y1);
+ state->lineTo(cropBox->x2, cropBox->y1);
+ state->lineTo(cropBox->x2, cropBox->y2);
+ state->lineTo(cropBox->x1, cropBox->y2);
+ state->closePath();
+ state->clip();
+ out->clip(state);
+ state->clearPath();
+ }
+}
+
+Gfx::~Gfx() {
+ GfxResources *resPtr;
+
+ while (state->hasSaves()) {
+ state = state->restore();
+ out->restoreState(state);
+ }
+ out->endPage();
+ while (res) {
+ resPtr = res->getNext();
+ delete res;
+ res = resPtr;
+ }
+ if (state)
+ delete state;
+}
+
+void Gfx::display(Object *obj, GBool topLevel) {
+ Object obj2;
+ int i;
+
+ if (obj->isArray()) {
+ for (i = 0; i < obj->arrayGetLength(); ++i) {
+ obj->arrayGet(i, &obj2);
+ if (!obj2.isStream()) {
+ error(-1, "Weird page contents");
+ obj2.free();
+ return;
+ }
+ obj2.free();
+ }
+ } else if (!obj->isStream()) {
+ error(-1, "Weird page contents");
+ return;
+ }
+ parser = new Parser(xref, new Lexer(xref, obj));
+ go(topLevel);
+ delete parser;
+ parser = NULL;
+}
+
+void Gfx::go(GBool topLevel) {
+ Object obj;
+ Object args[maxArgs];
+ int numCmds, numArgs;
+ int i;
+
+ // scan a sequence of objects
+ numCmds = 0;
+ numArgs = 0;
+ parser->getObj(&obj);
+ while (!obj.isEOF()) {
+
+ // got a command - execute it
+ if (obj.isCmd()) {
+ if (printCommands) {
+ obj.print(stdout);
+ for (i = 0; i < numArgs; ++i) {
+ printf(" ");
+ args[i].print(stdout);
+ }
+ printf("\n");
+ fflush(stdout);
+ }
+ execOp(&obj, args, numArgs);
+ obj.free();
+ for (i = 0; i < numArgs; ++i)
+ args[i].free();
+ numArgs = 0;
+
+ // periodically update display
+ if (++numCmds == 200) {
+ out->dump();
+ numCmds = 0;
+ }
+
+ // got an argument - save it
+ } else if (numArgs < maxArgs) {
+ args[numArgs++] = obj;
+
+ // too many arguments - something is wrong
+ } else {
+ error(getPos(), "Too many args in content stream");
+ if (printCommands) {
+ printf("throwing away arg: ");
+ obj.print(stdout);
+ printf("\n");
+ fflush(stdout);
+ }
+ obj.free();
+ }
+
+ // grab the next object
+ parser->getObj(&obj);
+ }
+ obj.free();
+
+ // args at end with no command
+ if (numArgs > 0) {
+ error(getPos(), "Leftover args in content stream");
+ if (printCommands) {
+ printf("%d leftovers:", numArgs);
+ for (i = 0; i < numArgs; ++i) {
+ printf(" ");
+ args[i].print(stdout);
+ }
+ printf("\n");
+ fflush(stdout);
+ }
+ for (i = 0; i < numArgs; ++i)
+ args[i].free();
+ }
+
+ // update display
+ if (topLevel && numCmds > 0) {
+ out->dump();
+ }
+}
+
+void Gfx::execOp(Object *cmd, Object args[], int numArgs) {
+ Operator *op;
+ char *name;
+ int i;
+
+ // find operator
+ name = cmd->getName();
+ if (!(op = findOp(name))) {
+ if (ignoreUndef == 0)
+ error(getPos(), "Unknown operator '%s'", name);
+ return;
+ }
+
+ // type check args
+ if (op->numArgs >= 0) {
+ if (numArgs != op->numArgs) {
+ error(getPos(), "Wrong number (%d) of args to '%s' operator",
+ numArgs, name);
+ return;
+ }
+ } else {
+ if (numArgs > -op->numArgs) {
+ error(getPos(), "Too many (%d) args to '%s' operator",
+ numArgs, name);
+ return;
+ }
+ }
+ for (i = 0; i < numArgs; ++i) {
+ if (!checkArg(&args[i], op->tchk[i])) {
+ error(getPos(), "Arg #%d to '%s' operator is wrong type (%s)",
+ i, name, args[i].getTypeName());
+ return;
+ }
+ }
+
+ // do it
+ (this->*op->func)(args, numArgs);
+}
+
+Operator *Gfx::findOp(char *name) {
+ int a, b, m, cmp;
+
+ a = -1;
+ b = numOps;
+ // invariant: opTab[a] < name < opTab[b]
+ while (b - a > 1) {
+ m = (a + b) / 2;
+ cmp = strcmp(opTab[m].name, name);
+ if (cmp < 0)
+ a = m;
+ else if (cmp > 0)
+ b = m;
+ else
+ a = b = m;
+ }
+ if (cmp != 0)
+ return NULL;
+ return &opTab[a];
+}
+
+GBool Gfx::checkArg(Object *arg, TchkType type) {
+ switch (type) {
+ case tchkBool: return arg->isBool();
+ case tchkInt: return arg->isInt();
+ case tchkNum: return arg->isNum();
+ case tchkString: return arg->isString();
+ case tchkName: return arg->isName();
+ case tchkArray: return arg->isArray();
+ case tchkProps: return arg->isDict() || arg->isName();
+ case tchkSCN: return arg->isNum() || arg->isName();
+ case tchkNone: return gFalse;
+ }
+ return gFalse;
+}
+
+int Gfx::getPos() {
+ return parser ? parser->getPos() : -1;
+}
+
+//------------------------------------------------------------------------
+// graphics state operators
+//------------------------------------------------------------------------
+
+void Gfx::opSave(Object args[], int numArgs) {
+ out->saveState(state);
+ state = state->save();
+}
+
+void Gfx::opRestore(Object args[], int numArgs) {
+ state = state->restore();
+ out->restoreState(state);
+
+ // Some PDF producers (Macromedia FreeHand) generate a save (q) and
+ // restore (Q) inside a path sequence. The PDF spec seems to imply
+ // that this is illegal. Calling clearPath() here implements the
+ // behavior apparently expected by this software.
+ state->clearPath();
+}
+
+void Gfx::opConcat(Object args[], int numArgs) {
+ state->concatCTM(args[0].getNum(), args[1].getNum(),
+ args[2].getNum(), args[3].getNum(),
+ args[4].getNum(), args[5].getNum());
+ out->updateCTM(state, args[0].getNum(), args[1].getNum(),
+ args[2].getNum(), args[3].getNum(),
+ args[4].getNum(), args[5].getNum());
+ fontChanged = gTrue;
+}
+
+void Gfx::opSetDash(Object args[], int numArgs) {
+ Array *a;
+ int length;
+ Object obj;
+ double *dash;
+ int i;
+
+ a = args[0].getArray();
+ length = a->getLength();
+ if (length == 0) {
+ dash = NULL;
+ } else {
+ dash = (double *)gmalloc(length * sizeof(double));
+ for (i = 0; i < length; ++i) {
+ dash[i] = a->get(i, &obj)->getNum();
+ obj.free();
+ }
+ }
+ state->setLineDash(dash, length, args[1].getNum());
+ out->updateLineDash(state);
+}
+
+void Gfx::opSetFlat(Object args[], int numArgs) {
+ state->setFlatness((int)args[0].getNum());
+ out->updateFlatness(state);
+}
+
+void Gfx::opSetLineJoin(Object args[], int numArgs) {
+ state->setLineJoin(args[0].getInt());
+ out->updateLineJoin(state);
+}
+
+void Gfx::opSetLineCap(Object args[], int numArgs) {
+ state->setLineCap(args[0].getInt());
+ out->updateLineCap(state);
+}
+
+void Gfx::opSetMiterLimit(Object args[], int numArgs) {
+ state->setMiterLimit(args[0].getNum());
+ out->updateMiterLimit(state);
+}
+
+void Gfx::opSetLineWidth(Object args[], int numArgs) {
+ state->setLineWidth(args[0].getNum());
+ out->updateLineWidth(state);
+}
+
+void Gfx::opSetExtGState(Object args[], int numArgs) {
+ Object obj1, obj2;
+
+ if (!res->lookupGState(args[0].getName(), &obj1)) {
+ return;
+ }
+ if (!obj1.isDict()) {
+ error(getPos(), "ExtGState '%s' is wrong type", args[0].getName());
+ obj1.free();
+ return;
+ }
+ if (obj1.dictLookup("ca", &obj2)->isNum()) {
+ state->setFillOpacity(obj2.getNum());
+ out->updateFillOpacity(state);
+ }
+ obj2.free();
+ if (obj1.dictLookup("CA", &obj2)->isNum()) {
+ state->setStrokeOpacity(obj2.getNum());
+ out->updateStrokeOpacity(state);
+ }
+ obj2.free();
+ obj1.free();
+}
+
+void Gfx::opSetRenderingIntent(Object args[], int numArgs) {
+}
+
+//------------------------------------------------------------------------
+// color operators
+//------------------------------------------------------------------------
+
+void Gfx::opSetFillGray(Object args[], int numArgs) {
+ GfxColor color;
+
+ state->setFillPattern(NULL);
+ state->setFillColorSpace(new GfxDeviceGrayColorSpace());
+ color.c[0] = args[0].getNum();
+ state->setFillColor(&color);
+ out->updateFillColor(state);
+}
+
+void Gfx::opSetStrokeGray(Object args[], int numArgs) {
+ GfxColor color;
+
+ state->setStrokePattern(NULL);
+ state->setStrokeColorSpace(new GfxDeviceGrayColorSpace());
+ color.c[0] = args[0].getNum();
+ state->setStrokeColor(&color);
+ out->updateStrokeColor(state);
+}
+
+void Gfx::opSetFillCMYKColor(Object args[], int numArgs) {
+ GfxColor color;
+ int i;
+
+ state->setFillPattern(NULL);
+ state->setFillColorSpace(new GfxDeviceCMYKColorSpace());
+ for (i = 0; i < 4; ++i) {
+ color.c[i] = args[i].getNum();
+ }
+ state->setFillColor(&color);
+ out->updateFillColor(state);
+}
+
+void Gfx::opSetStrokeCMYKColor(Object args[], int numArgs) {
+ GfxColor color;
+ int i;
+
+ state->setStrokePattern(NULL);
+ state->setStrokeColorSpace(new GfxDeviceCMYKColorSpace());
+ for (i = 0; i < 4; ++i) {
+ color.c[i] = args[i].getNum();
+ }
+ state->setStrokeColor(&color);
+ out->updateStrokeColor(state);
+}
+
+void Gfx::opSetFillRGBColor(Object args[], int numArgs) {
+ GfxColor color;
+ int i;
+
+ state->setFillPattern(NULL);
+ state->setFillColorSpace(new GfxDeviceRGBColorSpace());
+ for (i = 0; i < 3; ++i) {
+ color.c[i] = args[i].getNum();
+ }
+ state->setFillColor(&color);
+ out->updateFillColor(state);
+}
+
+void Gfx::opSetStrokeRGBColor(Object args[], int numArgs) {
+ GfxColor color;
+ int i;
+
+ state->setStrokePattern(NULL);
+ state->setStrokeColorSpace(new GfxDeviceRGBColorSpace());
+ for (i = 0; i < 3; ++i) {
+ color.c[i] = args[i].getNum();
+ }
+ state->setStrokeColor(&color);
+ out->updateStrokeColor(state);
+}
+
+void Gfx::opSetFillColorSpace(Object args[], int numArgs) {
+ Object obj;
+ GfxColorSpace *colorSpace;
+ GfxColor color;
+ int i;
+
+ state->setFillPattern(NULL);
+ res->lookupColorSpace(args[0].getName(), &obj);
+ if (obj.isNull()) {
+ colorSpace = GfxColorSpace::parse(&args[0]);
+ } else {
+ colorSpace = GfxColorSpace::parse(&obj);
+ }
+ obj.free();
+ if (colorSpace) {
+ state->setFillColorSpace(colorSpace);
+ } else {
+ error(getPos(), "Bad color space (fill)");
+ }
+ for (i = 0; i < gfxColorMaxComps; ++i) {
+ color.c[i] = 0;
+ }
+ state->setFillColor(&color);
+ out->updateFillColor(state);
+}
+
+void Gfx::opSetStrokeColorSpace(Object args[], int numArgs) {
+ Object obj;
+ GfxColorSpace *colorSpace;
+ GfxColor color;
+ int i;
+
+ state->setStrokePattern(NULL);
+ res->lookupColorSpace(args[0].getName(), &obj);
+ if (obj.isNull()) {
+ colorSpace = GfxColorSpace::parse(&args[0]);
+ } else {
+ colorSpace = GfxColorSpace::parse(&obj);
+ }
+ obj.free();
+ if (colorSpace) {
+ state->setStrokeColorSpace(colorSpace);
+ } else {
+ error(getPos(), "Bad color space (stroke)");
+ }
+ for (i = 0; i < gfxColorMaxComps; ++i) {
+ color.c[i] = 0;
+ }
+ state->setStrokeColor(&color);
+ out->updateStrokeColor(state);
+}
+
+void Gfx::opSetFillColor(Object args[], int numArgs) {
+ GfxColor color;
+ int i;
+
+ state->setFillPattern(NULL);
+ for (i = 0; i < numArgs; ++i) {
+ color.c[i] = args[i].getNum();
+ }
+ state->setFillColor(&color);
+ out->updateFillColor(state);
+}
+
+void Gfx::opSetStrokeColor(Object args[], int numArgs) {
+ GfxColor color;
+ int i;
+
+ state->setStrokePattern(NULL);
+ for (i = 0; i < numArgs; ++i) {
+ color.c[i] = args[i].getNum();
+ }
+ state->setStrokeColor(&color);
+ out->updateStrokeColor(state);
+}
+
+void Gfx::opSetFillColorN(Object args[], int numArgs) {
+ GfxColor color;
+ GfxPattern *pattern;
+ int i;
+
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ if (numArgs > 1) {
+ for (i = 0; i < numArgs && i < 4; ++i) {
+ if (args[i].isNum()) {
+ color.c[i] = args[i].getNum();
+ }
+ }
+ state->setFillColor(&color);
+ out->updateFillColor(state);
+ }
+ if (args[numArgs-1].isName() &&
+ (pattern = res->lookupPattern(args[numArgs-1].getName()))) {
+ state->setFillPattern(pattern);
+ }
+
+ } else {
+ state->setFillPattern(NULL);
+ for (i = 0; i < numArgs && i < 4; ++i) {
+ if (args[i].isNum()) {
+ color.c[i] = args[i].getNum();
+ }
+ }
+ state->setFillColor(&color);
+ out->updateFillColor(state);
+ }
+}
+
+void Gfx::opSetStrokeColorN(Object args[], int numArgs) {
+ GfxColor color;
+ GfxPattern *pattern;
+ int i;
+
+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
+ if (numArgs > 1) {
+ for (i = 0; i < numArgs && i < 4; ++i) {
+ if (args[i].isNum()) {
+ color.c[i] = args[i].getNum();
+ }
+ }
+ state->setStrokeColor(&color);
+ out->updateStrokeColor(state);
+ }
+ if (args[numArgs-1].isName() &&
+ (pattern = res->lookupPattern(args[numArgs-1].getName()))) {
+ state->setStrokePattern(pattern);
+ }
+
+ } else {
+ state->setStrokePattern(NULL);
+ for (i = 0; i < numArgs && i < 4; ++i) {
+ if (args[i].isNum()) {
+ color.c[i] = args[i].getNum();
+ }
+ }
+ state->setStrokeColor(&color);
+ out->updateStrokeColor(state);
+ }
+}
+
+//------------------------------------------------------------------------
+// path segment operators
+//------------------------------------------------------------------------
+
+void Gfx::opMoveTo(Object args[], int numArgs) {
+ state->moveTo(args[0].getNum(), args[1].getNum());
+}
+
+void Gfx::opLineTo(Object args[], int numArgs) {
+ if (!state->isCurPt()) {
+ error(getPos(), "No current point in lineto");
+ return;
+ }
+ state->lineTo(args[0].getNum(), args[1].getNum());
+}
+
+void Gfx::opCurveTo(Object args[], int numArgs) {
+ double x1, y1, x2, y2, x3, y3;
+
+ if (!state->isCurPt()) {
+ error(getPos(), "No current point in curveto");
+ return;
+ }
+ x1 = args[0].getNum();
+ y1 = args[1].getNum();
+ x2 = args[2].getNum();
+ y2 = args[3].getNum();
+ x3 = args[4].getNum();
+ y3 = args[5].getNum();
+ state->curveTo(x1, y1, x2, y2, x3, y3);
+}
+
+void Gfx::opCurveTo1(Object args[], int numArgs) {
+ double x1, y1, x2, y2, x3, y3;
+
+ if (!state->isCurPt()) {
+ error(getPos(), "No current point in curveto1");
+ return;
+ }
+ x1 = state->getCurX();
+ y1 = state->getCurY();
+ x2 = args[0].getNum();
+ y2 = args[1].getNum();
+ x3 = args[2].getNum();
+ y3 = args[3].getNum();
+ state->curveTo(x1, y1, x2, y2, x3, y3);
+}
+
+void Gfx::opCurveTo2(Object args[], int numArgs) {
+ double x1, y1, x2, y2, x3, y3;
+
+ if (!state->isCurPt()) {
+ error(getPos(), "No current point in curveto2");
+ return;
+ }
+ x1 = args[0].getNum();
+ y1 = args[1].getNum();
+ x2 = args[2].getNum();
+ y2 = args[3].getNum();
+ x3 = x2;
+ y3 = y2;
+ state->curveTo(x1, y1, x2, y2, x3, y3);
+}
+
+void Gfx::opRectangle(Object args[], int numArgs) {
+ double x, y, w, h;
+
+ x = args[0].getNum();
+ y = args[1].getNum();
+ w = args[2].getNum();
+ h = args[3].getNum();
+ state->moveTo(x, y);
+ state->lineTo(x + w, y);
+ state->lineTo(x + w, y + h);
+ state->lineTo(x, y + h);
+ state->closePath();
+}
+
+void Gfx::opClosePath(Object args[], int numArgs) {
+ if (!state->isPath()) {
+ error(getPos(), "No current point in closepath");
+ return;
+ }
+ state->closePath();
+}
+
+//------------------------------------------------------------------------
+// path painting operators
+//------------------------------------------------------------------------
+
+void Gfx::opEndPath(Object args[], int numArgs) {
+ doEndPath();
+}
+
+void Gfx::opStroke(Object args[], int numArgs) {
+ if (!state->isCurPt()) {
+ //error(getPos(), "No path in stroke");
+ return;
+ }
+ if (state->isPath())
+ out->stroke(state);
+ doEndPath();
+}
+
+void Gfx::opCloseStroke(Object args[], int numArgs) {
+ if (!state->isCurPt()) {
+ //error(getPos(), "No path in closepath/stroke");
+ return;
+ }
+ if (state->isPath()) {
+ state->closePath();
+ out->stroke(state);
+ }
+ doEndPath();
+}
+
+void Gfx::opFill(Object args[], int numArgs) {
+ if (!state->isCurPt()) {
+ //error(getPos(), "No path in fill");
+ return;
+ }
+ if (state->isPath()) {
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ doPatternFill(gFalse);
+ } else {
+ out->fill(state);
+ }
+ }
+ doEndPath();
+}
+
+void Gfx::opEOFill(Object args[], int numArgs) {
+ if (!state->isCurPt()) {
+ //error(getPos(), "No path in eofill");
+ return;
+ }
+ if (state->isPath()) {
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ doPatternFill(gTrue);
+ } else {
+ out->eoFill(state);
+ }
+ }
+ doEndPath();
+}
+
+void Gfx::opFillStroke(Object args[], int numArgs) {
+ if (!state->isCurPt()) {
+ //error(getPos(), "No path in fill/stroke");
+ return;
+ }
+ if (state->isPath()) {
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ doPatternFill(gFalse);
+ } else {
+ out->fill(state);
+ }
+ out->stroke(state);
+ }
+ doEndPath();
+}
+
+void Gfx::opCloseFillStroke(Object args[], int numArgs) {
+ if (!state->isCurPt()) {
+ //error(getPos(), "No path in closepath/fill/stroke");
+ return;
+ }
+ if (state->isPath()) {
+ state->closePath();
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ doPatternFill(gFalse);
+ } else {
+ out->fill(state);
+ }
+ out->stroke(state);
+ }
+ doEndPath();
+}
+
+void Gfx::opEOFillStroke(Object args[], int numArgs) {
+ if (!state->isCurPt()) {
+ //error(getPos(), "No path in eofill/stroke");
+ return;
+ }
+ if (state->isPath()) {
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ doPatternFill(gTrue);
+ } else {
+ out->eoFill(state);
+ }
+ out->stroke(state);
+ }
+ doEndPath();
+}
+
+void Gfx::opCloseEOFillStroke(Object args[], int numArgs) {
+ if (!state->isCurPt()) {
+ //error(getPos(), "No path in closepath/eofill/stroke");
+ return;
+ }
+ if (state->isPath()) {
+ state->closePath();
+ if (state->getFillColorSpace()->getMode() == csPattern) {
+ doPatternFill(gTrue);
+ } else {
+ out->eoFill(state);
+ }
+ out->stroke(state);
+ }
+ doEndPath();
+}
+
+void Gfx::doPatternFill(GBool eoFill) {
+ GfxPatternColorSpace *patCS;
+ GfxPattern *pattern;
+ GfxTilingPattern *tPat;
+ GfxColorSpace *cs;
+ double xMin, yMin, xMax, yMax, x, y, x1, y1;
+ double cxMin, cyMin, cxMax, cyMax;
+ int xi0, yi0, xi1, yi1, xi, yi;
+ double *ctm, *btm, *ptm;
+ double m[6], ictm[6], m1[6], im[6], imb[6];
+ double det;
+ double xstep, ystep;
+ int i;
+
+ // get color space
+ patCS = (GfxPatternColorSpace *)state->getFillColorSpace();
+
+ // get pattern
+ if (!(pattern = state->getFillPattern())) {
+ return;
+ }
+ if (pattern->getType() != 1) {
+ return;
+ }
+ tPat = (GfxTilingPattern *)pattern;
+
+ // construct a (pattern space) -> (current space) transform matrix
+ ctm = state->getCTM();
+ btm = baseMatrix;
+ ptm = tPat->getMatrix();
+ // iCTM = invert CTM
+ det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
+ ictm[0] = ctm[3] * det;
+ ictm[1] = -ctm[1] * det;
+ ictm[2] = -ctm[2] * det;
+ ictm[3] = ctm[0] * det;
+ ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
+ ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
+ // m1 = PTM * BTM = PTM * base transform matrix
+ m1[0] = ptm[0] * btm[0] + ptm[1] * btm[2];
+ m1[1] = ptm[0] * btm[1] + ptm[1] * btm[3];
+ m1[2] = ptm[2] * btm[0] + ptm[3] * btm[2];
+ m1[3] = ptm[2] * btm[1] + ptm[3] * btm[3];
+ m1[4] = ptm[4] * btm[0] + ptm[5] * btm[2] + btm[4];
+ m1[5] = ptm[4] * btm[1] + ptm[5] * btm[3] + btm[5];
+ // m = m1 * iCTM = (PTM * BTM) * (iCTM)
+ m[0] = m1[0] * ictm[0] + m1[1] * ictm[2];
+ m[1] = m1[0] * ictm[1] + m1[1] * ictm[3];
+ m[2] = m1[2] * ictm[0] + m1[3] * ictm[2];
+ m[3] = m1[2] * ictm[1] + m1[3] * ictm[3];
+ m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4];
+ m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5];
+
+ // construct a (current space) -> (pattern space) transform matrix
+ det = 1 / (m[0] * m[3] - m[1] * m[2]);
+ im[0] = m[3] * det;
+ im[1] = -m[1] * det;
+ im[2] = -m[2] * det;
+ im[3] = m[0] * det;
+ im[4] = (m[2] * m[5] - m[3] * m[4]) * det;
+ im[5] = (m[1] * m[4] - m[0] * m[5]) * det;
+
+ // construct a (base space) -> (pattern space) transform matrix
+ det = 1 / (m1[0] * m1[3] - m1[1] * m1[2]);
+ imb[0] = m1[3] * det;
+ imb[1] = -m1[1] * det;
+ imb[2] = -m1[2] * det;
+ imb[3] = m1[0] * det;
+ imb[4] = (m1[2] * m1[5] - m1[3] * m1[4]) * det;
+ imb[5] = (m1[1] * m1[4] - m1[0] * m1[5]) * det;
+
+ // save current graphics state
+ out->saveState(state);
+ state = state->save();
+
+ // set underlying color space (for uncolored tiling patterns)
+ if (tPat->getPaintType() == 2 && (cs = patCS->getUnder())) {
+ state->setFillColorSpace(cs->copy());
+ } else {
+ state->setFillColorSpace(new GfxDeviceGrayColorSpace());
+ }
+ state->setFillPattern(NULL);
+ out->updateFillColor(state);
+
+ // clip to current path
+ state->clip();
+ if (eoFill) {
+ out->eoClip(state);
+ } else {
+ out->clip(state);
+ }
+ state->clearPath();
+
+ // transform clip region bbox to pattern space
+ state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax);
+ xMin = xMax = cxMin * imb[0] + cyMin * imb[2] + imb[4];
+ yMin = yMax = cxMin * imb[1] + cyMin * imb[3] + imb[5];
+ x1 = cxMin * imb[0] + cyMax * imb[2] + imb[4];
+ y1 = cxMin * imb[1] + cyMax * imb[3] + imb[5];
+ if (x1 < xMin) {
+ xMin = x1;
+ } else if (x1 > xMax) {
+ xMax = x1;
+ }
+ if (y1 < yMin) {
+ yMin = y1;
+ } else if (y1 > yMax) {
+ yMax = y1;
+ }
+ x1 = cxMax * imb[0] + cyMin * imb[2] + imb[4];
+ y1 = cxMax * imb[1] + cyMin * imb[3] + imb[5];
+ if (x1 < xMin) {
+ xMin = x1;
+ } else if (x1 > xMax) {
+ xMax = x1;
+ }
+ if (y1 < yMin) {
+ yMin = y1;
+ } else if (y1 > yMax) {
+ yMax = y1;
+ }
+ x1 = cxMax * imb[0] + cyMax * imb[2] + imb[4];
+ y1 = cxMax * imb[1] + cyMax * imb[3] + imb[5];
+ if (x1 < xMin) {
+ xMin = x1;
+ } else if (x1 > xMax) {
+ xMax = x1;
+ }
+ if (y1 < yMin) {
+ yMin = y1;
+ } else if (y1 > yMax) {
+ yMax = y1;
+ }
+
+ // draw the pattern
+ //~ this should treat negative steps differently -- start at right/top
+ //~ edge instead of left/bottom (?)
+ xstep = fabs(tPat->getXStep());
+ ystep = fabs(tPat->getYStep());
+ xi0 = (int)floor(xMin / xstep);
+ xi1 = (int)ceil(xMax / xstep);
+ yi0 = (int)floor(yMin / ystep);
+ yi1 = (int)ceil(yMax / ystep);
+ for (i = 0; i < 4; ++i) {
+ m1[i] = m[i];
+ }
+ for (yi = yi0; yi < yi1; ++yi) {
+ for (xi = xi0; xi < xi1; ++xi) {
+ x = xi * xstep;
+ y = yi * ystep;
+ m1[4] = x * m[0] + y * m[2] + m[4];
+ m1[5] = x * m[1] + y * m[3] + m[5];
+ doForm1(tPat->getContentStream(), tPat->getResDict(),
+ m1, tPat->getBBox());
+ }
+ }
+
+ // restore graphics state
+ state = state->restore();
+ out->restoreState(state);
+}
+
+void Gfx::opShFill(Object args[], int numArgs) {
+ GfxShading *shading;
+ double xMin, yMin, xMax, yMax;
+
+ if (!(shading = res->lookupShading(args[0].getName()))) {
+ return;
+ }
+
+ // save current graphics state
+ out->saveState(state);
+ state = state->save();
+
+ // clip to bbox
+ if (shading->getHasBBox()) {
+ shading->getBBox(&xMin, &yMin, &xMax, &yMax);
+ state->moveTo(xMin, yMin);
+ state->lineTo(xMax, yMin);
+ state->lineTo(xMax, yMax);
+ state->lineTo(xMin, yMax);
+ state->closePath();
+ state->clip();
+ out->clip(state);
+ state->clearPath();
+ }
+
+ // set the color space
+ state->setFillColorSpace(shading->getColorSpace()->copy());
+
+ // do shading type-specific operations
+ switch (shading->getType()) {
+ case 2:
+ doAxialShFill((GfxAxialShading *)shading);
+ break;
+ case 3:
+ doRadialShFill((GfxRadialShading *)shading);
+ break;
+ }
+
+ // restore graphics state
+ state = state->restore();
+ out->restoreState(state);
+
+ delete shading;
+}
+
+void Gfx::doAxialShFill(GfxAxialShading *shading) {
+ double xMin, yMin, xMax, yMax;
+ double x0, y0, x1, y1;
+ double det;
+ double *ctm;
+ double ictm[6];
+ double dx, dy, mul;
+ double tMin, tMax, t, tx, ty;
+ double s[4], sMin, sMax, tmp;
+ double ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1;
+ double t0, t1, tt;
+ double ta[axialMaxSplits + 1];
+ int next[axialMaxSplits + 1];
+ GfxColor color0, color1;
+ int nComps;
+ int i, j, k, kk;
+
+ // get clip region bbox and transform to current user space
+ state->getClipBBox(&x0, &y0, &x1, &y1);
+ ctm = state->getCTM();
+ det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
+ ictm[0] = ctm[3] * det;
+ ictm[1] = -ctm[1] * det;
+ ictm[2] = -ctm[2] * det;
+ ictm[3] = ctm[0] * det;
+ ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
+ ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
+ xMin = xMax = x0 * ictm[0] + y0 * ictm[2] + ictm[4];
+ yMin = yMax = x0 * ictm[1] + y0 * ictm[3] + ictm[5];
+ tx = x0 * ictm[0] + y1 * ictm[2] + ictm[4];
+ ty = x0 * ictm[1] + y1 * ictm[3] + ictm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+ tx = x1 * ictm[0] + y0 * ictm[2] + ictm[4];
+ ty = x1 * ictm[1] + y0 * ictm[3] + ictm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+ tx = x1 * ictm[0] + y1 * ictm[2] + ictm[4];
+ ty = x1 * ictm[1] + y1 * ictm[3] + ictm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+
+ // compute min and max t values, based on the four corners of the
+ // clip region bbox
+ shading->getCoords(&x0, &y0, &x1, &y1);
+ dx = x1 - x0;
+ dy = y1 - y0;
+ mul = 1 / (dx * dx + dy * dy);
+ tMin = tMax = ((xMin - x0) * dx + (yMin - y0) * dy) * mul;
+ t = ((xMin - x0) * dx + (yMax - y0) * dy) * mul;
+ if (t < tMin) {
+ tMin = t;
+ } else if (t > tMax) {
+ tMax = t;
+ }
+ t = ((xMax - x0) * dx + (yMin - y0) * dy) * mul;
+ if (t < tMin) {
+ tMin = t;
+ } else if (t > tMax) {
+ tMax = t;
+ }
+ t = ((xMax - x0) * dx + (yMax - y0) * dy) * mul;
+ if (t < tMin) {
+ tMin = t;
+ } else if (t > tMax) {
+ tMax = t;
+ }
+ if (tMin < 0 && !shading->getExtend0()) {
+ tMin = 0;
+ }
+ if (tMax > 1 && !shading->getExtend1()) {
+ tMax = 1;
+ }
+
+ // get the function domain
+ t0 = shading->getDomain0();
+ t1 = shading->getDomain1();
+
+ // Traverse the t axis and do the shading.
+ //
+ // For each point (tx, ty) on the t axis, consider a line through
+ // that point perpendicular to the t axis:
+ //
+ // x(s) = tx + s * -dy --> s = (x - tx) / -dy
+ // y(s) = ty + s * dx --> s = (y - ty) / dx
+ //
+ // Then look at the intersection of this line with the bounding box
+ // (xMin, yMin, xMax, yMax). In the general case, there are four
+ // intersection points:
+ //
+ // s0 = (xMin - tx) / -dy
+ // s1 = (xMax - tx) / -dy
+ // s2 = (yMin - ty) / dx
+ // s3 = (yMax - ty) / dx
+ //
+ // and we want the middle two s values.
+ //
+ // In the case where dx = 0, take s0 and s1; in the case where dy =
+ // 0, take s2 and s3.
+ //
+ // Each filled polygon is bounded by two of these line segments
+ // perpdendicular to the t axis.
+ //
+ // The t axis is bisected into smaller regions until the color
+ // difference across a region is small enough, and then the region
+ // is painted with a single color.
+
+ // set up
+ nComps = shading->getColorSpace()->getNComps();
+ ta[0] = tMin;
+ ta[axialMaxSplits] = tMax;
+ next[0] = axialMaxSplits;
+
+ // compute the color at t = tMin
+ if (tMin < 0) {
+ tt = t0;
+ } else if (tMin > 1) {
+ tt = t1;
+ } else {
+ tt = t0 + (t1 - t0) * tMin;
+ }
+ shading->getColor(tt, &color0);
+
+ // compute the coordinates of the point on the t axis at t = tMin;
+ // then compute the intersection of the perpendicular line with the
+ // bounding box
+ tx = x0 + tMin * dx;
+ ty = y0 + tMin * dy;
+ if (dx == 0 && dy == 0) {
+ sMin = sMax = 0;
+ } if (dx == 0) {
+ sMin = (xMin - tx) / -dy;
+ sMax = (xMax - tx) / -dy;
+ if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
+ } else if (dy == 0) {
+ sMin = (yMin - ty) / dx;
+ sMax = (yMax - ty) / dx;
+ if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
+ } else {
+ s[0] = (yMin - ty) / dx;
+ s[1] = (yMax - ty) / dx;
+ s[2] = (xMin - tx) / -dy;
+ s[3] = (xMax - tx) / -dy;
+ for (j = 0; j < 3; ++j) {
+ kk = j;
+ for (k = j + 1; k < 4; ++k) {
+ if (s[k] < s[kk]) {
+ kk = k;
+ }
+ }
+ tmp = s[j]; s[j] = s[kk]; s[kk] = tmp;
+ }
+ sMin = s[1];
+ sMax = s[2];
+ }
+ ux0 = tx - sMin * dy;
+ uy0 = ty + sMin * dx;
+ vx0 = tx - sMax * dy;
+ vy0 = ty + sMax * dx;
+
+ i = 0;
+ while (i < axialMaxSplits) {
+
+ // bisect until color difference is small enough or we hit the
+ // bisection limit
+ j = next[i];
+ while (j > i + 1) {
+ if (ta[j] < 0) {
+ tt = t0;
+ } else if (ta[j] > 1) {
+ tt = t1;
+ } else {
+ tt = t0 + (t1 - t0) * ta[j];
+ }
+ shading->getColor(tt, &color1);
+ for (k = 0; k < nComps; ++k) {
+ if (fabs(color1.c[k] - color0.c[k]) > axialColorDelta) {
+ break;
+ }
+ }
+ if (k == nComps) {
+ break;
+ }
+ k = (i + j) / 2;
+ ta[k] = 0.5 * (ta[i] + ta[j]);
+ next[i] = k;
+ next[k] = j;
+ j = k;
+ }
+
+ // use the average of the colors of the two sides of the region
+ for (k = 0; k < nComps; ++k) {
+ color0.c[k] = 0.5 * (color0.c[k] + color1.c[k]);
+ }
+
+ // compute the coordinates of the point on the t axis; then
+ // compute the intersection of the perpendicular line with the
+ // bounding box
+ tx = x0 + ta[j] * dx;
+ ty = y0 + ta[j] * dy;
+ if (dx == 0 && dy == 0) {
+ sMin = sMax = 0;
+ } if (dx == 0) {
+ sMin = (xMin - tx) / -dy;
+ sMax = (xMax - tx) / -dy;
+ if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
+ } else if (dy == 0) {
+ sMin = (yMin - ty) / dx;
+ sMax = (yMax - ty) / dx;
+ if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
+ } else {
+ s[0] = (yMin - ty) / dx;
+ s[1] = (yMax - ty) / dx;
+ s[2] = (xMin - tx) / -dy;
+ s[3] = (xMax - tx) / -dy;
+ for (j = 0; j < 3; ++j) {
+ kk = j;
+ for (k = j + 1; k < 4; ++k) {
+ if (s[k] < s[kk]) {
+ kk = k;
+ }
+ }
+ tmp = s[j]; s[j] = s[kk]; s[kk] = tmp;
+ }
+ sMin = s[1];
+ sMax = s[2];
+ }
+ ux1 = tx - sMin * dy;
+ uy1 = ty + sMin * dx;
+ vx1 = tx - sMax * dy;
+ vy1 = ty + sMax * dx;
+
+ // set the color
+ state->setFillColor(&color0);
+ out->updateFillColor(state);
+
+ // fill the region
+ state->moveTo(ux0, uy0);
+ state->lineTo(vx0, vy0);
+ state->lineTo(vx1, vy1);
+ state->lineTo(ux1, uy1);
+ state->closePath();
+ out->fill(state);
+ state->clearPath();
+
+ // set up for next region
+ ux0 = ux1;
+ uy0 = uy1;
+ vx0 = vx1;
+ vy0 = vy1;
+ color0 = color1;
+ i = next[i];
+ }
+}
+
+void Gfx::doRadialShFill(GfxRadialShading *shading) {
+ double x0, y0, x1, y1, r0, r1;
+ double xx, yy, rr, dr, dt;
+ double cx, cy, th;
+ double t0, t1, tt;
+ GfxColor color;
+
+ // Find the centers and radii of the two circles...
+ shading->getCoords(&x0, &y0, &x1, &y1);
+ shading->getRadii(&r0, &r1);
+
+ if (r0 == 0.0f && r1 == 0.0f) return;
+
+ // get the function domain
+ t0 = shading->getDomain0();
+ t1 = shading->getDomain1();
+
+ // draw circles, stepping in small increments...
+ for (dr = (r1 - r0); dr > 0.1; dr *= 0.1);
+ if (dr < 0.001) dr = 1.0;
+
+ for (rr = r1; rr >= r0; rr -= dr) {
+ // get the current center/color
+ dt = (rr - r0) / (r1 - r0);
+
+ xx = x0 + (x1 - x0) * dt;
+ yy = y0 + (y1 - y0) * dt;
+ tt = t0 + (t1 - t0) * dt;
+
+ shading->getColor(tt, &color);
+
+ // set the color
+ state->setFillColor(&color);
+ out->updateFillColor(state);
+
+ // stroke the circle
+ for (th = 0.0; th < 2 * M_PI; th += M_PI * 0.05) {
+ cx = xx + rr * cos(th);
+ cy = yy + rr * sin(th);
+
+ if (th == 0.0) state->moveTo(cx, cy);
+ else state->lineTo(cx, cy);
+ }
+
+ state->closePath();
+ out->fill(state);
+ state->clearPath();
+ }
+}
+
+void Gfx::doEndPath() {
+ if (state->isPath() && clip != clipNone) {
+ state->clip();
+ if (clip == clipNormal) {
+ out->clip(state);
+ } else {
+ out->eoClip(state);
+ }
+ }
+ clip = clipNone;
+ state->clearPath();
+}
+
+//------------------------------------------------------------------------
+// path clipping operators
+//------------------------------------------------------------------------
+
+void Gfx::opClip(Object args[], int numArgs) {
+ clip = clipNormal;
+}
+
+void Gfx::opEOClip(Object args[], int numArgs) {
+ clip = clipEO;
+}
+
+//------------------------------------------------------------------------
+// text object operators
+//------------------------------------------------------------------------
+
+void Gfx::opBeginText(Object args[], int numArgs) {
+ state->setTextMat(1, 0, 0, 1, 0, 0);
+ state->textMoveTo(0, 0);
+ out->updateTextMat(state);
+ out->updateTextPos(state);
+ fontChanged = gTrue;
+}
+
+void Gfx::opEndText(Object args[], int numArgs) {
+}
+
+//------------------------------------------------------------------------
+// text state operators
+//------------------------------------------------------------------------
+
+void Gfx::opSetCharSpacing(Object args[], int numArgs) {
+ state->setCharSpace(args[0].getNum());
+ out->updateCharSpace(state);
+}
+
+void Gfx::opSetFont(Object args[], int numArgs) {
+ GfxFont *font;
+
+ if (!(font = res->lookupFont(args[0].getName()))) {
+ return;
+ }
+ if (printCommands) {
+ printf(" font: '%s' %g\n",
+ font->getName() ? font->getName()->getCString() : "???",
+ args[1].getNum());
+ fflush(stdout);
+ }
+ state->setFont(font, args[1].getNum());
+ fontChanged = gTrue;
+}
+
+void Gfx::opSetTextLeading(Object args[], int numArgs) {
+ state->setLeading(args[0].getNum());
+}
+
+void Gfx::opSetTextRender(Object args[], int numArgs) {
+ state->setRender(args[0].getInt());
+ out->updateRender(state);
+}
+
+void Gfx::opSetTextRise(Object args[], int numArgs) {
+ state->setRise(args[0].getNum());
+ out->updateRise(state);
+}
+
+void Gfx::opSetWordSpacing(Object args[], int numArgs) {
+ state->setWordSpace(args[0].getNum());
+ out->updateWordSpace(state);
+}
+
+void Gfx::opSetHorizScaling(Object args[], int numArgs) {
+ state->setHorizScaling(args[0].getNum());
+ out->updateHorizScaling(state);
+ fontChanged = gTrue;
+}
+
+//------------------------------------------------------------------------
+// text positioning operators
+//------------------------------------------------------------------------
+
+void Gfx::opTextMove(Object args[], int numArgs) {
+ double tx, ty;
+
+ tx = state->getLineX() + args[0].getNum();
+ ty = state->getLineY() + args[1].getNum();
+ state->textMoveTo(tx, ty);
+ out->updateTextPos(state);
+}
+
+void Gfx::opTextMoveSet(Object args[], int numArgs) {
+ double tx, ty;
+
+ tx = state->getLineX() + args[0].getNum();
+ ty = args[1].getNum();
+ state->setLeading(-ty);
+ ty += state->getLineY();
+ state->textMoveTo(tx, ty);
+ out->updateTextPos(state);
+}
+
+void Gfx::opSetTextMatrix(Object args[], int numArgs) {
+ state->setTextMat(args[0].getNum(), args[1].getNum(),
+ args[2].getNum(), args[3].getNum(),
+ args[4].getNum(), args[5].getNum());
+ state->textMoveTo(0, 0);
+ out->updateTextMat(state);
+ out->updateTextPos(state);
+ fontChanged = gTrue;
+}
+
+void Gfx::opTextNextLine(Object args[], int numArgs) {
+ double tx, ty;
+
+ tx = state->getLineX();
+ ty = state->getLineY() - state->getLeading();
+ state->textMoveTo(tx, ty);
+ out->updateTextPos(state);
+}
+
+//------------------------------------------------------------------------
+// text string operators
+//------------------------------------------------------------------------
+
+void Gfx::opShowText(Object args[], int numArgs) {
+ if (!state->getFont()) {
+ error(getPos(), "No font in show");
+ return;
+ }
+ doShowText(args[0].getString());
+}
+
+void Gfx::opMoveShowText(Object args[], int numArgs) {
+ double tx, ty;
+
+ if (!state->getFont()) {
+ error(getPos(), "No font in move/show");
+ return;
+ }
+ tx = state->getLineX();
+ ty = state->getLineY() - state->getLeading();
+ state->textMoveTo(tx, ty);
+ out->updateTextPos(state);
+ doShowText(args[0].getString());
+}
+
+void Gfx::opMoveSetShowText(Object args[], int numArgs) {
+ double tx, ty;
+
+ if (!state->getFont()) {
+ error(getPos(), "No font in move/set/show");
+ return;
+ }
+ state->setWordSpace(args[0].getNum());
+ state->setCharSpace(args[1].getNum());
+ tx = state->getLineX();
+ ty = state->getLineY() - state->getLeading();
+ state->textMoveTo(tx, ty);
+ out->updateWordSpace(state);
+ out->updateCharSpace(state);
+ out->updateTextPos(state);
+ doShowText(args[2].getString());
+}
+
+void Gfx::opShowSpaceText(Object args[], int numArgs) {
+ Array *a;
+ Object obj;
+ int i;
+
+ if (!state->getFont()) {
+ error(getPos(), "No font in show/space");
+ return;
+ }
+ a = args[0].getArray();
+ for (i = 0; i < a->getLength(); ++i) {
+ a->get(i, &obj);
+ if (obj.isNum()) {
+ state->textShift(-obj.getNum() * 0.001 * state->getFontSize());
+ out->updateTextShift(state, obj.getNum());
+ } else if (obj.isString()) {
+ doShowText(obj.getString());
+ } else {
+ error(getPos(), "Element of show/space array must be number or string");
+ }
+ obj.free();
+ }
+}
+
+void Gfx::doShowText(GString *s) {
+ GfxFont *font;
+ GfxFontEncoding16 *enc;
+ Guchar *p;
+ Guchar c8;
+ int c16;
+ GString *s16;
+ char s16a[2];
+ int m, n;
+#if 1 //~type3
+ double dx, dy, width, height, w, h, x, y;
+ double oldCTM[6], newCTM[6];
+ double *mat;
+ Object charProc;
+ Parser *oldParser;
+ int i;
+#else
+ double dx, dy, width, height, w, h;
+#endif
+ double sWidth, sHeight;
+
+ if (fontChanged) {
+ out->updateFont(state);
+ fontChanged = gFalse;
+ }
+ font = state->getFont();
+
+ //----- 16-bit font
+ if (font->is16Bit()) {
+ enc = font->getEncoding16();
+ if (out->useDrawChar()) {
+ out->beginString(state, s);
+ s16 = NULL;
+ } else {
+ s16 = new GString();
+ }
+ sWidth = sHeight = 0;
+ state->textTransformDelta(0, state->getRise(), &dx, &dy);
+ p = (Guchar *)s->getCString();
+ n = s->getLength();
+ while (n > 0) {
+ m = getNextChar16(enc, p, &c16);
+ if (enc->wMode == 0) {
+ width = state->getFontSize() * font->getWidth16(c16) +
+ state->getCharSpace();
+ if (m == 1 && c16 == ' ') {
+ width += state->getWordSpace();
+ }
+ width *= state->getHorizScaling();
+ height = 0;
+ } else {
+ width = 0;
+ height = state->getFontSize() * font->getHeight16(c16);
+ }
+ state->textTransformDelta(width, height, &w, &h);
+ if (out->useDrawChar()) {
+ out->drawChar16(state, state->getCurX() + dx, state->getCurY() + dy,
+ w, h, c16);
+ state->textShift(width, height);
+ } else {
+ s16a[0] = (char)(c16 >> 8);
+ s16a[1] = (char)c16;
+ s16->append(s16a, 2);
+ sWidth += w;
+ sHeight += h;
+ }
+ n -= m;
+ p += m;
+ }
+ if (out->useDrawChar()) {
+ out->endString(state);
+ } else {
+ out->drawString16(state, s16);
+ delete s16;
+ state->textShift(sWidth, sHeight);
+ }
+
+ //----- 8-bit font
+ } else {
+#if 1 //~type3
+ //~ also check out->renderType3()
+ if (font->getType() == fontType3) {
+ out->beginString(state, s);
+ mat = state->getCTM();
+ for (i = 0; i < 6; ++i) {
+ oldCTM[i] = mat[i];
+ }
+ mat = state->getTextMat();
+ newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2];
+ newCTM[1] = mat[0] * oldCTM[1] + mat[1] * oldCTM[3];
+ newCTM[2] = mat[2] * oldCTM[0] + mat[3] * oldCTM[2];
+ newCTM[3] = mat[2] * oldCTM[1] + mat[3] * oldCTM[3];
+ mat = font->getFontMatrix();
+ newCTM[0] = mat[0] * newCTM[0] + mat[1] * newCTM[2];
+ newCTM[1] = mat[0] * newCTM[1] + mat[1] * newCTM[3];
+ newCTM[2] = mat[2] * newCTM[0] + mat[3] * newCTM[2];
+ newCTM[3] = mat[2] * newCTM[1] + mat[3] * newCTM[3];
+ newCTM[0] *= state->getFontSize();
+ newCTM[3] *= state->getFontSize();
+ newCTM[0] *= state->getHorizScaling();
+ newCTM[2] *= state->getHorizScaling();
+ state->textTransformDelta(0, state->getRise(), &dx, &dy);
+ oldParser = parser;
+ for (p = (Guchar *)s->getCString(), n = s->getLength(); n; ++p, --n) {
+ c8 = *p;
+ font->getCharProc(c8, &charProc);
+ state->transform(state->getCurX() + dx, state->getCurY() + dy, &x, &y);
+ out->saveState(state);
+ state = state->save();
+ state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y);
+ //~ out->updateCTM(???)
+ if (charProc.isStream()) {
+ display(&charProc, gFalse);
+ } else {
+ error(getPos(), "Missing or bad Type3 CharProc entry");
+ }
+ state = state->restore();
+ out->restoreState(state);
+ charProc.free();
+ width = state->getFontSize() * font->getWidth(c8) +
+ state->getCharSpace();
+ if (c8 == ' ') {
+ width += state->getWordSpace();
+ }
+ width *= state->getHorizScaling();
+ state->textShift(width);
+ }
+ parser = oldParser;
+ out->endString(state);
+ } else
+#endif
+ if (out->useDrawChar()) {
+ out->beginString(state, s);
+ state->textTransformDelta(0, state->getRise(), &dx, &dy);
+ for (p = (Guchar *)s->getCString(), n = s->getLength(); n; ++p, --n) {
+ c8 = *p;
+ width = state->getFontSize() * font->getWidth(c8) +
+ state->getCharSpace();
+ if (c8 == ' ') {
+ width += state->getWordSpace();
+ }
+ width *= state->getHorizScaling();
+ state->textTransformDelta(width, 0, &w, &h);
+ out->drawChar(state, state->getCurX() + dx, state->getCurY() + dy,
+ w, h, c8);
+ state->textShift(width);
+ }
+ out->endString(state);
+ } else {
+ out->drawString(state, s);
+ width = state->getFontSize() * font->getWidth(s) +
+ s->getLength() * state->getCharSpace();
+ for (p = (Guchar *)s->getCString(), n = s->getLength(); n; ++p, --n) {
+ if (*p == ' ') {
+ width += state->getWordSpace();
+ }
+ }
+ width *= state->getHorizScaling();
+ state->textShift(width);
+ }
+ }
+}
+
+int Gfx::getNextChar16(GfxFontEncoding16 *enc, Guchar *p, int *c16) {
+ int n;
+ int code;
+ int a, b, m;
+
+ n = enc->codeLen[*p];
+ if (n == 1) {
+ *c16 = enc->map1[*p];
+ } else {
+ code = (p[0] << 8) + p[1];
+ a = 0;
+ b = enc->map2Len;
+ // invariant: map2[2*a] <= code < map2[2*b]
+ while (b - a > 1) {
+ m = (a + b) / 2;
+ if (enc->map2[2*m] <= code)
+ a = m;
+ else if (enc->map2[2*m] > code)
+ b = m;
+ else
+ break;
+ }
+ *c16 = enc->map2[2*a+1] + (code - enc->map2[2*a]);
+ }
+ return n;
+}
+
+//------------------------------------------------------------------------
+// XObject operators
+//------------------------------------------------------------------------
+
+void Gfx::opXObject(Object args[], int numArgs) {
+ Object obj1, obj2, refObj;
+#if OPI_SUPPORT
+ Object opiDict;
+#endif
+
+ if (!res->lookupXObject(args[0].getName(), &obj1)) {
+ return;
+ }
+ if (!obj1.isStream()) {
+ error(getPos(), "XObject '%s' is wrong type", args[0].getName());
+ obj1.free();
+ return;
+ }
+#if OPI_SUPPORT
+ obj1.streamGetDict()->lookup("OPI", &opiDict);
+ if (opiDict.isDict()) {
+ out->opiBegin(state, opiDict.getDict());
+ }
+#endif
+ obj1.streamGetDict()->lookup("Subtype", &obj2);
+ if (obj2.isName("Image")) {
+ res->lookupXObjectNF(args[0].getName(), &refObj);
+ doImage(&refObj, obj1.getStream(), gFalse);
+ refObj.free();
+ } else if (obj2.isName("Form")) {
+ doForm(&obj1);
+ } else if (obj2.isName()) {
+ error(getPos(), "Unknown XObject subtype '%s'", obj2.getName());
+ } else {
+ error(getPos(), "XObject subtype is missing or wrong type");
+ }
+ obj2.free();
+#if OPI_SUPPORT
+ if (opiDict.isDict()) {
+ out->opiEnd(state, opiDict.getDict());
+ }
+ opiDict.free();
+#endif
+ obj1.free();
+}
+
+void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
+ Dict *dict;
+ int width, height;
+ int bits;
+ GBool mask;
+ GBool invert;
+ GfxColorSpace *colorSpace;
+ GfxImageColorMap *colorMap;
+ Object maskObj;
+ GBool haveMask;
+ int maskColors[2*gfxColorMaxComps];
+ Object obj1, obj2;
+ int i;
+
+ // get stream dict
+ dict = str->getDict();
+
+ // get size
+ dict->lookup("Width", &obj1);
+ if (obj1.isNull()) {
+ obj1.free();
+ dict->lookup("W", &obj1);
+ }
+ if (!obj1.isInt())
+ goto err2;
+ width = obj1.getInt();
+ obj1.free();
+ dict->lookup("Height", &obj1);
+ if (obj1.isNull()) {
+ obj1.free();
+ dict->lookup("H", &obj1);
+ }
+ if (!obj1.isInt())
+ goto err2;
+ height = obj1.getInt();
+ obj1.free();
+
+ // image or mask?
+ dict->lookup("ImageMask", &obj1);
+ if (obj1.isNull()) {
+ obj1.free();
+ dict->lookup("IM", &obj1);
+ }
+ mask = gFalse;
+ if (obj1.isBool())
+ mask = obj1.getBool();
+ else if (!obj1.isNull())
+ goto err2;
+ obj1.free();
+
+ // bit depth
+ dict->lookup("BitsPerComponent", &obj1);
+ if (obj1.isNull()) {
+ obj1.free();
+ dict->lookup("BPC", &obj1);
+ }
+ if (!obj1.isInt())
+ goto err2;
+ bits = obj1.getInt();
+ obj1.free();
+
+ // display a mask
+ if (mask) {
+
+ // check for inverted mask
+ if (bits != 1)
+ goto err1;
+ invert = gFalse;
+ dict->lookup("Decode", &obj1);
+ if (obj1.isNull()) {
+ obj1.free();
+ dict->lookup("D", &obj1);
+ }
+ if (obj1.isArray()) {
+ obj1.arrayGet(0, &obj2);
+ if (obj2.isInt() && obj2.getInt() == 1)
+ invert = gTrue;
+ obj2.free();
+ } else if (!obj1.isNull()) {
+ goto err2;
+ }
+ obj1.free();
+
+ // draw it
+ out->drawImageMask(state, ref, str, width, height, invert, inlineImg);
+
+ } else {
+
+ // get color space and color map
+ dict->lookup("ColorSpace", &obj1);
+ if (obj1.isNull()) {
+ obj1.free();
+ dict->lookup("CS", &obj1);
+ }
+ if (obj1.isName()) {
+ res->lookupColorSpace(obj1.getName(), &obj2);
+ if (!obj2.isNull()) {
+ obj1.free();
+ obj1 = obj2;
+ } else {
+ obj2.free();
+ }
+ }
+ colorSpace = GfxColorSpace::parse(&obj1);
+ obj1.free();
+ if (!colorSpace) {
+ goto err1;
+ }
+ dict->lookup("Decode", &obj1);
+ if (obj1.isNull()) {
+ obj1.free();
+ dict->lookup("D", &obj1);
+ }
+ colorMap = new GfxImageColorMap(bits, &obj1, colorSpace);
+ obj1.free();
+ if (!colorMap->isOk()) {
+ delete colorMap;
+ goto err1;
+ }
+
+ // get the mask
+ haveMask = gFalse;
+ dict->lookup("Mask", &maskObj);
+ if (maskObj.isArray()) {
+ for (i = 0; i < maskObj.arrayGetLength(); ++i) {
+ maskObj.arrayGet(i, &obj1);
+ maskColors[i] = obj1.getInt();
+ obj1.free();
+ }
+ haveMask = gTrue;
+ }
+
+ // draw it
+ out->drawImage(state, ref, str, width, height, colorMap,
+ haveMask ? maskColors : (int *)NULL, inlineImg);
+ delete colorMap;
+ str->close();
+
+ maskObj.free();
+ }
+
+ return;
+
+ err2:
+ obj1.free();
+ err1:
+ error(getPos(), "Bad image parameters");
+}
+
+void Gfx::doForm(Object *str) {
+ Dict *dict;
+ Object matrixObj, bboxObj;
+ double m[6], bbox[6];
+ Object resObj;
+ Dict *resDict;
+ Object obj1;
+ int i;
+
+ // get stream dict
+ dict = str->streamGetDict();
+
+ // check form type
+ dict->lookup("FormType", &obj1);
+ if (!(obj1.isInt() && obj1.getInt() == 1)) {
+ error(getPos(), "Unknown form type");
+ }
+ obj1.free();
+
+ // get bounding box
+ dict->lookup("BBox", &bboxObj);
+ if (!bboxObj.isArray()) {
+ matrixObj.free();
+ bboxObj.free();
+ error(getPos(), "Bad form bounding box");
+ return;
+ }
+ for (i = 0; i < 4; ++i) {
+ bboxObj.arrayGet(i, &obj1);
+ bbox[i] = obj1.getNum();
+ obj1.free();
+ }
+ bboxObj.free();
+
+ // get matrix
+ dict->lookup("Matrix", &matrixObj);
+ if (matrixObj.isArray()) {
+ for (i = 0; i < 6; ++i) {
+ matrixObj.arrayGet(i, &obj1);
+ m[i] = obj1.getNum();
+ obj1.free();
+ }
+ } else {
+ m[0] = 1; m[1] = 0;
+ m[2] = 0; m[3] = 1;
+ m[4] = 0; m[5] = 0;
+ }
+ matrixObj.free();
+
+ // get resources
+ dict->lookup("Resources", &resObj);
+ resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL;
+
+ // draw it
+ doForm1(str, resDict, m, bbox);
+
+ resObj.free();
+}
+
+void Gfx::doWidgetForm(Object *str, double xMin, double yMin,
+ double xMax, double yMax) {
+ Dict *dict, *resDict;
+ Object matrixObj, bboxObj, resObj;
+ Object obj1;
+ double m[6], bbox[6];
+ double sx, sy;
+ int i;
+
+ // get stream dict
+ dict = str->streamGetDict();
+
+ // get bounding box
+ dict->lookup("BBox", &bboxObj);
+ if (!bboxObj.isArray()) {
+ bboxObj.free();
+ error(getPos(), "Bad form bounding box");
+ return;
+ }
+ for (i = 0; i < 4; ++i) {
+ bboxObj.arrayGet(i, &obj1);
+ bbox[i] = obj1.getNum();
+ obj1.free();
+ }
+ bboxObj.free();
+
+ // get matrix
+ dict->lookup("Matrix", &matrixObj);
+ if (matrixObj.isArray()) {
+ for (i = 0; i < 6; ++i) {
+ matrixObj.arrayGet(i, &obj1);
+ m[i] = obj1.getNum();
+ obj1.free();
+ }
+ } else {
+ m[0] = 1; m[1] = 0;
+ m[2] = 0; m[3] = 1;
+ m[4] = 0; m[5] = 0;
+ }
+ matrixObj.free();
+
+ // scale form bbox to widget rectangle
+ sx = fabs((xMax - xMin) / (bbox[2] - bbox[0]));
+ sy = fabs((yMax - yMin) / (bbox[3] - bbox[1]));
+ m[0] *= sx; m[1] *= sy;
+ m[2] *= sx; m[3] *= sy;
+ m[4] *= sx; m[5] *= sy;
+
+ // translate to widget rectangle
+ m[4] += xMin;
+ m[5] += yMin;
+
+ // get resources
+ dict->lookup("Resources", &resObj);
+ resDict = resObj.isDict() ? resObj.getDict() : (Dict *)NULL;
+
+ // draw it
+ doForm1(str, resDict, m, bbox);
+
+ resObj.free();
+ bboxObj.free();
+}
+
+void Gfx::doForm1(Object *str, Dict *resDict, double *matrix, double *bbox) {
+ Parser *oldParser;
+ double oldBaseMatrix[6];
+ GfxResources *resPtr;
+ int i;
+
+ // push new resources on stack
+ res = new GfxResources(xref, resDict, res);
+
+ // save current graphics state
+ out->saveState(state);
+ state = state->save();
+
+ // save current parser
+ oldParser = parser;
+
+ // set form transformation matrix
+ state->concatCTM(matrix[0], matrix[1], matrix[2],
+ matrix[3], matrix[4], matrix[5]);
+ out->updateCTM(state, matrix[0], matrix[1], matrix[2],
+ matrix[3], matrix[4], matrix[5]);
+
+ // set new base matrix
+ for (i = 0; i < 6; ++i) {
+ oldBaseMatrix[i] = baseMatrix[i];
+ baseMatrix[i] = state->getCTM()[i];
+ }
+
+ // set form bounding box
+ state->moveTo(bbox[0], bbox[1]);
+ state->lineTo(bbox[2], bbox[1]);
+ state->lineTo(bbox[2], bbox[3]);
+ state->lineTo(bbox[0], bbox[3]);
+ state->closePath();
+ state->clip();
+ out->clip(state);
+ state->clearPath();
+
+ // draw the form
+ display(str, gFalse);
+
+ // restore base matrix
+ for (i = 0; i < 6; ++i) {
+ baseMatrix[i] = oldBaseMatrix[i];
+ }
+
+ // restore parser
+ parser = oldParser;
+
+ // restore graphics state
+ state = state->restore();
+ out->restoreState(state);
+
+ // pop resource stack
+ resPtr = res->getNext();
+ delete res;
+ res = resPtr;
+
+ return;
+}
+
+//------------------------------------------------------------------------
+// in-line image operators
+//------------------------------------------------------------------------
+
+void Gfx::opBeginImage(Object args[], int numArgs) {
+ Stream *str;
+ int c1, c2;
+
+ // build dict/stream
+ str = buildImageStream();
+
+ // display the image
+ if (str) {
+ doImage(NULL, str, gTrue);
+
+ // skip 'EI' tag
+ c1 = str->getBaseStream()->getChar();
+ c2 = str->getBaseStream()->getChar();
+ while (!(c1 == 'E' && c2 == 'I') && c2 != EOF) {
+ c1 = c2;
+ c2 = str->getBaseStream()->getChar();
+ }
+ delete str;
+ }
+}
+
+Stream *Gfx::buildImageStream() {
+ Object dict;
+ Object obj;
+ char *key;
+ Stream *str;
+
+ // build dictionary
+ dict.initDict(xref);
+ parser->getObj(&obj);
+ while (!obj.isCmd("ID") && !obj.isEOF()) {
+ if (!obj.isName()) {
+ error(getPos(), "Inline image dictionary key must be a name object");
+ obj.free();
+ parser->getObj(&obj);
+ } else {
+ key = copyString(obj.getName());
+ obj.free();
+ parser->getObj(&obj);
+ if (obj.isEOF() || obj.isError())
+ break;
+ dict.dictAdd(key, &obj);
+ }
+ parser->getObj(&obj);
+ }
+ if (obj.isEOF())
+ error(getPos(), "End of file in inline image");
+ obj.free();
+
+ // make stream
+ str = new EmbedStream(parser->getStream(), &dict);
+ str = str->addFilters(&dict);
+
+ return str;
+}
+
+void Gfx::opImageData(Object args[], int numArgs) {
+ error(getPos(), "Internal: got 'ID' operator");
+}
+
+void Gfx::opEndImage(Object args[], int numArgs) {
+ error(getPos(), "Internal: got 'EI' operator");
+}
+
+//------------------------------------------------------------------------
+// type 3 font operators
+//------------------------------------------------------------------------
+
+void Gfx::opSetCharWidth(Object args[], int numArgs) {
+// error(getPos(), "Encountered 'd0' operator in content stream");
+}
+
+void Gfx::opSetCacheDevice(Object args[], int numArgs) {
+// error(getPos(), "Encountered 'd1' operator in content stream");
+}
+
+//------------------------------------------------------------------------
+// compatibility operators
+//------------------------------------------------------------------------
+
+void Gfx::opBeginIgnoreUndef(Object args[], int numArgs) {
+ ++ignoreUndef;
+}
+
+void Gfx::opEndIgnoreUndef(Object args[], int numArgs) {
+ if (ignoreUndef > 0)
+ --ignoreUndef;
+}
+
+//------------------------------------------------------------------------
+// marked content operators
+//------------------------------------------------------------------------
+
+void Gfx::opBeginMarkedContent(Object args[], int numArgs) {
+ if (printCommands) {
+ printf(" marked content: %s ", args[0].getName());
+ if (numArgs == 2)
+ args[2].print(stdout);
+ printf("\n");
+ fflush(stdout);
+ }
+}
+
+void Gfx::opEndMarkedContent(Object args[], int numArgs) {
+}
+
+void Gfx::opMarkPoint(Object args[], int numArgs) {
+ if (printCommands) {
+ printf(" mark point: %s ", args[0].getName());
+ if (numArgs == 2)
+ args[2].print(stdout);
+ printf("\n");
+ fflush(stdout);
+ }
+}
diff --git a/pdftops/Gfx.h b/pdftops/Gfx.h
new file mode 100644
index 000000000..8abc9a59b
--- /dev/null
+++ b/pdftops/Gfx.h
@@ -0,0 +1,244 @@
+//========================================================================
+//
+// Gfx.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef GFX_H
+#define GFX_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "gtypes.h"
+
+class GString;
+class XRef;
+class Array;
+class Stream;
+class Parser;
+class Dict;
+class OutputDev;
+class GfxFontDict;
+class GfxFont;
+struct GfxFontEncoding16;
+class GfxPattern;
+class GfxShading;
+class GfxAxialShading;
+class GfxRadialShading;
+class GfxState;
+class Gfx;
+struct PDFRectangle;
+
+//------------------------------------------------------------------------
+// Gfx
+//------------------------------------------------------------------------
+
+enum GfxClipType {
+ clipNone,
+ clipNormal,
+ clipEO
+};
+
+enum TchkType {
+ tchkBool, // boolean
+ tchkInt, // integer
+ tchkNum, // number (integer or real)
+ tchkString, // string
+ tchkName, // name
+ tchkArray, // array
+ tchkProps, // properties (dictionary or name)
+ tchkSCN, // scn/SCN args (number of name)
+ tchkNone // used to avoid empty initializer lists
+};
+
+#define maxArgs 8
+
+struct Operator {
+ char name[4];
+ int numArgs;
+ TchkType tchk[maxArgs];
+ void (Gfx::*func)(Object args[], int numArgs);
+};
+
+class GfxResources {
+public:
+
+ GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA);
+ ~GfxResources();
+
+ GfxFont *lookupFont(char *name);
+ GBool lookupXObject(char *name, Object *obj);
+ GBool lookupXObjectNF(char *name, Object *obj);
+ void lookupColorSpace(char *name, Object *obj);
+ GfxPattern *lookupPattern(char *name);
+ GfxShading *lookupShading(char *name);
+ GBool lookupGState(char *name, Object *obj);
+
+ GfxResources *getNext() { return next; }
+
+private:
+
+ GfxFontDict *fonts;
+ Object xObjDict;
+ Object colorSpaceDict;
+ Object patternDict;
+ Object shadingDict;
+ Object gStateDict;
+ GfxResources *next;
+};
+
+class Gfx {
+public:
+
+ // Constructor for regular output.
+ Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, double dpi,
+ PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate,
+ GBool printCommandsA);
+
+ // Destructor.
+ ~Gfx();
+
+ // Interpret a stream or array of streams.
+ void display(Object *obj, GBool topLevel = gTrue);
+
+ void doWidgetForm(Object *str, double xMin, double yMin,
+ double xMax, double yMax);
+
+private:
+
+ XRef *xref; // the xref table for this PDF file
+ OutputDev *out; // output device
+ GBool printCommands; // print the drawing commands (for debugging)
+ GfxResources *res; // resource stack
+
+ GfxState *state; // current graphics state
+ GBool fontChanged; // set if font or text matrix has changed
+ GfxClipType clip; // do a clip?
+ int ignoreUndef; // current BX/EX nesting level
+ double baseMatrix[6]; // default matrix for most recent
+ // page/form/pattern
+
+ Parser *parser; // parser for page content stream(s)
+
+ static Operator opTab[]; // table of operators
+
+ void go(GBool topLevel);
+ void execOp(Object *cmd, Object args[], int numArgs);
+ Operator *findOp(char *name);
+ GBool checkArg(Object *arg, TchkType type);
+ int getPos();
+
+ // graphics state operators
+ void opSave(Object args[], int numArgs);
+ void opRestore(Object args[], int numArgs);
+ void opConcat(Object args[], int numArgs);
+ void opSetDash(Object args[], int numArgs);
+ void opSetFlat(Object args[], int numArgs);
+ void opSetLineJoin(Object args[], int numArgs);
+ void opSetLineCap(Object args[], int numArgs);
+ void opSetMiterLimit(Object args[], int numArgs);
+ void opSetLineWidth(Object args[], int numArgs);
+ void opSetExtGState(Object args[], int numArgs);
+ void opSetRenderingIntent(Object args[], int numArgs);
+
+ // color operators
+ void opSetFillGray(Object args[], int numArgs);
+ void opSetStrokeGray(Object args[], int numArgs);
+ void opSetFillCMYKColor(Object args[], int numArgs);
+ void opSetStrokeCMYKColor(Object args[], int numArgs);
+ void opSetFillRGBColor(Object args[], int numArgs);
+ void opSetStrokeRGBColor(Object args[], int numArgs);
+ void opSetFillColorSpace(Object args[], int numArgs);
+ void opSetStrokeColorSpace(Object args[], int numArgs);
+ void opSetFillColor(Object args[], int numArgs);
+ void opSetStrokeColor(Object args[], int numArgs);
+ void opSetFillColorN(Object args[], int numArgs);
+ void opSetStrokeColorN(Object args[], int numArgs);
+
+ // path segment operators
+ void opMoveTo(Object args[], int numArgs);
+ void opLineTo(Object args[], int numArgs);
+ void opCurveTo(Object args[], int numArgs);
+ void opCurveTo1(Object args[], int numArgs);
+ void opCurveTo2(Object args[], int numArgs);
+ void opRectangle(Object args[], int numArgs);
+ void opClosePath(Object args[], int numArgs);
+
+ // path painting operators
+ void opEndPath(Object args[], int numArgs);
+ void opStroke(Object args[], int numArgs);
+ void opCloseStroke(Object args[], int numArgs);
+ void opFill(Object args[], int numArgs);
+ void opEOFill(Object args[], int numArgs);
+ void opFillStroke(Object args[], int numArgs);
+ void opCloseFillStroke(Object args[], int numArgs);
+ void opEOFillStroke(Object args[], int numArgs);
+ void opCloseEOFillStroke(Object args[], int numArgs);
+ void doPatternFill(GBool eoFill);
+ void opShFill(Object args[], int numArgs);
+ void doAxialShFill(GfxAxialShading *shading);
+ void doRadialShFill(GfxRadialShading *shading);
+ void doEndPath();
+
+ // path clipping operators
+ void opClip(Object args[], int numArgs);
+ void opEOClip(Object args[], int numArgs);
+
+ // text object operators
+ void opBeginText(Object args[], int numArgs);
+ void opEndText(Object args[], int numArgs);
+
+ // text state operators
+ void opSetCharSpacing(Object args[], int numArgs);
+ void opSetFont(Object args[], int numArgs);
+ void opSetTextLeading(Object args[], int numArgs);
+ void opSetTextRender(Object args[], int numArgs);
+ void opSetTextRise(Object args[], int numArgs);
+ void opSetWordSpacing(Object args[], int numArgs);
+ void opSetHorizScaling(Object args[], int numArgs);
+
+ // text positioning operators
+ void opTextMove(Object args[], int numArgs);
+ void opTextMoveSet(Object args[], int numArgs);
+ void opSetTextMatrix(Object args[], int numArgs);
+ void opTextNextLine(Object args[], int numArgs);
+
+ // text string operators
+ void opShowText(Object args[], int numArgs);
+ void opMoveShowText(Object args[], int numArgs);
+ void opMoveSetShowText(Object args[], int numArgs);
+ void opShowSpaceText(Object args[], int numArgs);
+ void doShowText(GString *s);
+ int getNextChar16(GfxFontEncoding16 *enc, Guchar *p, int *c16);
+
+ // XObject operators
+ void opXObject(Object args[], int numArgs);
+ void doImage(Object *ref, Stream *str, GBool inlineImg);
+ void doForm(Object *str);
+ void doForm1(Object *str, Dict *resDict, double *matrix, double *bbox);
+
+ // in-line image operators
+ void opBeginImage(Object args[], int numArgs);
+ Stream *buildImageStream();
+ void opImageData(Object args[], int numArgs);
+ void opEndImage(Object args[], int numArgs);
+
+ // type 3 font operators
+ void opSetCharWidth(Object args[], int numArgs);
+ void opSetCacheDevice(Object args[], int numArgs);
+
+ // compatibility operators
+ void opBeginIgnoreUndef(Object args[], int numArgs);
+ void opEndIgnoreUndef(Object args[], int numArgs);
+
+ // marked content operators
+ void opBeginMarkedContent(Object args[], int numArgs);
+ void opEndMarkedContent(Object args[], int numArgs);
+ void opMarkPoint(Object args[], int numArgs);
+};
+
+#endif
diff --git a/pdftops/GfxFont.cxx b/pdftops/GfxFont.cxx
new file mode 100644
index 000000000..96b802e14
--- /dev/null
+++ b/pdftops/GfxFont.cxx
@@ -0,0 +1,1081 @@
+//========================================================================
+//
+// GfxFont.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "GString.h"
+#include "gmem.h"
+#include "gfile.h"
+#include "config.h"
+#include "Object.h"
+#include "Array.h"
+#include "Dict.h"
+#include "Error.h"
+#include "Params.h"
+#include "FontFile.h"
+#include "GfxFont.h"
+
+#include "FontInfo.h"
+#if JAPANESE_SUPPORT
+#include "Japan12CMapInfo.h"
+#endif
+#if CHINESE_GB_SUPPORT
+#include "GB12CMapInfo.h"
+#endif
+#if CHINESE_CNS_SUPPORT
+#include "CNS13CMapInfo.h"
+#endif
+
+//------------------------------------------------------------------------
+
+extern "C" {
+static int CDECL cmpWidthExcep(const void *w1, const void *w2);
+static int CDECL cmpWidthExcepV(const void *w1, const void *w2);
+}
+
+//------------------------------------------------------------------------
+
+static Gushort *defCharWidths[12] = {
+ courierWidths,
+ courierObliqueWidths,
+ courierBoldWidths,
+ courierBoldObliqueWidths,
+ helveticaWidths,
+ helveticaObliqueWidths,
+ helveticaBoldWidths,
+ helveticaBoldObliqueWidths,
+ timesRomanWidths,
+ timesItalicWidths,
+ timesBoldWidths,
+ timesBoldItalicWidths
+};
+
+//------------------------------------------------------------------------
+// GfxFont
+//------------------------------------------------------------------------
+
+GfxFont::GfxFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict) {
+ BuiltinFont *builtinFont;
+ Object obj1, obj2, obj3, obj4;
+ int missingWidth;
+ char *name2, *p;
+ int i;
+
+ // get font tag and ID
+ tag = new GString(tagA);
+ id = idA;
+
+ // get font type
+ type = fontUnknownType;
+ fontDict->lookup("Subtype", &obj1);
+ if (obj1.isName("Type1"))
+ type = fontType1;
+ else if (obj1.isName("Type1C"))
+ type = fontType1C;
+ else if (obj1.isName("Type3"))
+ type = fontType3;
+ else if (obj1.isName("TrueType"))
+ type = fontTrueType;
+ else if (obj1.isName("Type0"))
+ type = fontType0;
+ obj1.free();
+ is16 = gFalse;
+
+ // get base font name
+ name = NULL;
+ fontDict->lookup("BaseFont", &obj1);
+ if (obj1.isName())
+ name = new GString(obj1.getName());
+ obj1.free();
+
+ // Newer Adobe tools are using Base14-compatible TrueType fonts
+ // without embedding them, so munge the names into the equivalent
+ // PostScript names. This is a kludge -- it would be nice if Adobe
+ // followed their own spec.
+ if (type == fontTrueType && name) {
+ p = name->getCString();
+ name2 = NULL;
+ if (!strncmp(p, "Arial", 5)) {
+ if (!strcmp(p+5, ",Bold")) {
+ name2 = "Helvetica-Bold";
+ } else if (!strcmp(p+5, ",Italic")) {
+ name2 = "Helvetica-Oblique";
+ } else if (!strcmp(p+5, ",BoldItalic")) {
+ name2 = "Helvetica-BoldOblique";
+ } else {
+ name2 = "Helvetica";
+ }
+ } else if (!strncmp(p, "TimesNewRoman", 13)) {
+ if (!strcmp(p+13, ",Bold")) {
+ name2 = "Times-Bold";
+ } else if (!strcmp(p+13, ",Italic")) {
+ name2 = "Times-Italic";
+ } else if (!strcmp(p+13, ",BoldItalic")) {
+ name2 = "Times-BoldItalic";
+ } else {
+ name2 = "Times-Roman";
+ }
+ } else if (!strncmp(p, "CourierNew", 10)) {
+ if (!strcmp(p+10, ",Bold")) {
+ name2 = "Courier-Bold";
+ } else if (!strcmp(p+10, ",Italic")) {
+ name2 = "Courier-Oblique";
+ } else if (!strcmp(p+10, ",BoldItalic")) {
+ name2 = "Courier-BoldOblique";
+ } else {
+ name2 = "Courier";
+ }
+ }
+ if (name2) {
+ delete name;
+ name = new GString(name2);
+ }
+ }
+
+ // is it a built-in font?
+ builtinFont = NULL;
+ if (name) {
+ for (i = 0; i < numBuiltinFonts; ++i) {
+ if (!strcmp(builtinFonts[i].name, name->getCString())) {
+ builtinFont = &builtinFonts[i];
+ break;
+ }
+ }
+ }
+
+ // assume Times-Roman by default (for substitution purposes)
+ flags = fontSerif;
+
+ // default ascent/descent values
+ if (builtinFont) {
+ ascent = 0.001 * builtinFont->ascent;
+ descent = 0.001 * builtinFont->descent;
+ } else {
+ ascent = 0.95;
+ descent = -0.35;
+ }
+
+ // get info from font descriptor
+ embFontName = NULL;
+ embFontID.num = -1;
+ embFontID.gen = -1;
+ missingWidth = 0;
+ if (type == fontType0) {
+ fontDict->lookup("DescendantFonts", &obj2);
+ if (obj2.isArray()) {
+ obj2.arrayGet(0, &obj3);
+ if (obj3.isDict()) {
+ obj3.dictLookup("FontDescriptor", &obj1);
+ } else {
+ error(-1, "Bad descendant font in Type 0 font");
+ obj1.initNull();
+ }
+ obj3.free();
+ } else {
+ error(-1, "Missing DescendantFonts entry in Type 0 font");
+ obj1.initNull();
+ }
+ obj2.free();
+ } else {
+ fontDict->lookup("FontDescriptor", &obj1);
+ }
+ if (obj1.isDict()) {
+
+ // get flags
+ obj1.dictLookup("Flags", &obj2);
+ if (obj2.isInt())
+ flags = obj2.getInt();
+ obj2.free();
+
+ // get name
+ obj1.dictLookup("FontName", &obj2);
+ if (obj2.isName())
+ embFontName = new GString(obj2.getName());
+ obj2.free();
+
+ // look for embedded font file
+ if (type == fontType1) {
+ obj1.dictLookupNF("FontFile", &obj2);
+ if (obj2.isRef())
+ embFontID = obj2.getRef();
+ obj2.free();
+ }
+ if (embFontID.num == -1 && type == fontTrueType) {
+ obj1.dictLookupNF("FontFile2", &obj2);
+ if (obj2.isRef())
+ embFontID = obj2.getRef();
+ obj2.free();
+ }
+ if (embFontID.num == -1) {
+ obj1.dictLookupNF("FontFile3", &obj2);
+ if (obj2.isRef()) {
+ embFontID = obj2.getRef();
+ obj2.fetch(xref, &obj3);
+ if (obj3.isStream()) {
+ obj3.streamGetDict()->lookup("Subtype", &obj4);
+ if (obj4.isName("Type1"))
+ type = fontType1;
+ else if (obj4.isName("Type1C"))
+ type = fontType1C;
+ else if (obj4.isName("Type3"))
+ type = fontType3;
+ else if (obj4.isName("TrueType"))
+ type = fontTrueType;
+ else if (obj4.isName("Type0"))
+ type = fontType0;
+ obj4.free();
+ }
+ obj3.free();
+ }
+ obj2.free();
+ }
+
+ // look for MissingWidth
+ obj1.dictLookup("MissingWidth", &obj2);
+ if (obj2.isInt()) {
+ missingWidth = obj2.getInt();
+ }
+ obj2.free();
+
+ // get Ascent and Descent
+ obj1.dictLookup("Ascent", &obj2);
+ if (obj2.isNum()) {
+ ascent = 0.001 * obj2.getNum();
+ }
+ obj2.free();
+ obj1.dictLookup("Descent", &obj2);
+ if (obj2.isNum()) {
+ descent = 0.001 * obj2.getNum();
+ }
+ obj2.free();
+
+ // font FontBBox
+ fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0;
+ if (obj1.dictLookup("FontBBox", &obj2)->isArray()) {
+ for (i = 0; i < 4 && i < obj2.arrayGetLength(); ++i) {
+ if (obj2.arrayGet(i, &obj3)->isNum()) {
+ fontBBox[i] = obj3.getNum();
+ }
+ obj3.free();
+ }
+ }
+ obj2.free();
+ }
+ obj1.free();
+
+ // get Type3 font definition
+ if (type == fontType3) {
+ fontDict->lookup("CharProcs", &charProcs);
+ if (!charProcs.isDict()) {
+ error(-1, "Missing or invalid CharProcs dictionary in Type 3 font");
+ charProcs.free();
+ }
+ }
+
+ // look for an external font file
+ extFontFile = NULL;
+ if (type == fontType1 && name)
+ findExtFontFile();
+
+ // get font matrix
+ fontMat[0] = fontMat[3] = 1;
+ fontMat[1] = fontMat[2] = fontMat[4] = fontMat[5] = 0;
+ if (fontDict->lookup("FontMatrix", &obj1)->isArray()) {
+ for (i = 0; i < 6 && i < obj1.arrayGetLength(); ++i) {
+ if (obj1.arrayGet(i, &obj2)->isNum())
+ fontMat[i] = obj2.getNum();
+ obj2.free();
+ }
+ }
+ obj1.free();
+
+ // get encoding and character widths
+ if (type == fontType0) {
+ getType0EncAndWidths(fontDict);
+ } else {
+ getEncAndWidths(xref, fontDict, builtinFont, missingWidth);
+ }
+}
+
+GfxFont::~GfxFont() {
+ delete tag;
+ if (name) {
+ delete name;
+ }
+ if (!is16 && encoding) {
+ delete encoding;
+ }
+ if (embFontName) {
+ delete embFontName;
+ }
+ if (extFontFile) {
+ delete extFontFile;
+ }
+ if (charProcs.isDict()) {
+ charProcs.free();
+ }
+ if (is16) {
+ gfree(widths16.exceps);
+ gfree(widths16.excepsV);
+ }
+}
+
+double GfxFont::getWidth(GString *s) {
+ double w;
+ int i;
+
+ w = 0;
+ for (i = 0; i < s->getLength(); ++i)
+ w += widths[s->getChar(i) & 0xff];
+ return w;
+}
+
+double GfxFont::getWidth16(int c) {
+ double w;
+ int a, b, m;
+
+ w = widths16.defWidth;
+ a = -1;
+ b = widths16.numExceps;
+ // invariant: widths16.exceps[a].last < c < widths16.exceps[b].first
+ while (b - a > 1) {
+ m = (a + b) / 2;
+ if (widths16.exceps[m].last < c) {
+ a = m;
+ } else if (c < widths16.exceps[m].first) {
+ b = m;
+ } else {
+ w = widths16.exceps[m].width;
+ break;
+ }
+ }
+ return w;
+}
+
+double GfxFont::getHeight16(int c) {
+ double h;
+ int a, b, m;
+
+ h = widths16.defHeight;
+ a = -1;
+ b = widths16.numExcepsV;
+ // invariant: widths16.excepsV[a].last < c < widths16.excepsV[b].first
+ while (b - a > 1) {
+ m = (a + b) / 2;
+ if (widths16.excepsV[m].last < c) {
+ a = m;
+ } else if (c < widths16.excepsV[m].first) {
+ b = m;
+ } else {
+ h = widths16.excepsV[m].height;
+ break;
+ }
+ }
+ return h;
+}
+
+double GfxFont::getOriginX16(int c) {
+ double vx;
+ int a, b, m;
+
+ vx = widths16.defWidth / 2;
+ a = -1;
+ b = widths16.numExcepsV;
+ // invariant: widths16.excepsV[a].last < c < widths16.excepsV[b].first
+ while (b - a > 1) {
+ m = (a + b) / 2;
+ if (widths16.excepsV[m].last < c) {
+ a = m;
+ } else if (c < widths16.excepsV[m].first) {
+ b = m;
+ } else {
+ vx = widths16.excepsV[m].vx;
+ break;
+ }
+ }
+ return vx;
+}
+
+double GfxFont::getOriginY16(int c) {
+ double vy;
+ int a, b, m;
+
+ vy = widths16.defVY;
+ a = -1;
+ b = widths16.numExcepsV;
+ // invariant: widths16.excepsV[a].last < c < widths16.excepsV[b].first
+ while (b - a > 1) {
+ m = (a + b) / 2;
+ if (widths16.excepsV[m].last < c) {
+ a = m;
+ } else if (c < widths16.excepsV[m].first) {
+ b = m;
+ } else {
+ vy = widths16.excepsV[m].vy;
+ break;
+ }
+ }
+ return vy;
+}
+
+Object *GfxFont::getCharProc(int code, Object *proc) {
+ if (charProcs.isDict()) {
+ charProcs.dictLookup(encoding->getCharName(code), proc);
+ } else {
+ proc->initNull();
+ }
+ return proc;
+}
+
+void GfxFont::getEncAndWidths(XRef *xref, Dict *fontDict,
+ BuiltinFont *builtinFont, int missingWidth) {
+ Object obj1, obj2, obj3;
+ char *buf;
+ int len;
+ FontFile *fontFile;
+ int code, i;
+
+ // Encodings start with a base encoding, which can come from
+ // (in order of priority):
+ // 1. FontDict.Encoding or FontDict.Encoding.BaseEncoding
+ // - MacRoman / WinAnsi / Standard
+ // 2. embedded font file
+ // 3. default:
+ // - builtin --> builtin encoding
+ // - TrueType --> MacRomanEncoding
+ // - others --> StandardEncoding
+ // and then add a list of differences from
+ // FontDict.Encoding.Differences.
+
+ // check FontDict for base encoding
+ encoding = NULL;
+ fontDict->lookup("Encoding", &obj1);
+ if (obj1.isDict()) {
+ obj1.dictLookup("BaseEncoding", &obj2);
+ if (obj2.isName("MacRomanEncoding")) {
+ encoding = macRomanEncoding.copy();
+ } else if (obj2.isName("WinAnsiEncoding")) {
+ encoding = winAnsiEncoding.copy();
+ } else if (obj2.isName("StandardEncoding")) {
+ encoding = standardEncoding.copy();
+ }
+ obj2.free();
+ } else if (obj1.isName("MacRomanEncoding")) {
+ encoding = macRomanEncoding.copy();
+ } else if (obj1.isName("WinAnsiEncoding")) {
+ encoding = winAnsiEncoding.copy();
+ } else if (obj1.isName("StandardEncoding")) {
+ encoding = standardEncoding.copy();
+ }
+ obj1.free();
+
+ // check embedded or external font file for base encoding
+ if ((type == fontType1 || type == fontType1C || type == fontTrueType) &&
+ (extFontFile || embFontID.num >= 0)) {
+ if (extFontFile) {
+ buf = readExtFontFile(&len);
+ } else {
+ buf = readEmbFontFile(xref, &len);
+ }
+ if (buf) {
+ if (type == fontType1) {
+ fontFile = new Type1FontFile(buf, len);
+ } else if (type == fontType1C) {
+ fontFile = new Type1CFontFile(buf, len);
+ } else {
+ fontFile = new TrueTypeFontFile(buf, len);
+ }
+ if (fontFile->getName()) {
+ if (embFontName)
+ delete embFontName;
+ embFontName = new GString(fontFile->getName());
+ }
+ if (!encoding) {
+ encoding = fontFile->getEncoding(gTrue);
+ }
+ delete fontFile;
+ gfree(buf);
+ }
+ }
+
+ // get default base encoding
+ if (!encoding) {
+ if (builtinFont)
+ encoding = builtinFont->encoding->copy();
+ else if (type == fontTrueType)
+ encoding = macRomanEncoding.copy();
+ else
+ encoding = standardEncoding.copy();
+ }
+
+ // merge differences into encoding
+ fontDict->lookup("Encoding", &obj1);
+ if (obj1.isDict()) {
+ obj1.dictLookup("Differences", &obj2);
+ if (obj2.isArray()) {
+ code = 0;
+ for (i = 0; i < obj2.arrayGetLength(); ++i) {
+ obj2.arrayGet(i, &obj3);
+ if (obj3.isInt()) {
+ code = obj3.getInt();
+ } else if (obj3.isName()) {
+ if (code < 256)
+ encoding->addChar(code, copyString(obj3.getName()));
+ ++code;
+ } else {
+ error(-1, "Wrong type in font encoding resource differences (%s)",
+ obj3.getTypeName());
+ }
+ obj3.free();
+ }
+ }
+ obj2.free();
+ }
+ obj1.free();
+
+ // get character widths
+ if (builtinFont)
+ makeWidths(fontDict, builtinFont->encoding, builtinFont->widths,
+ missingWidth);
+ else
+ makeWidths(fontDict, NULL, NULL, missingWidth);
+}
+
+void GfxFont::findExtFontFile() {
+ char **path;
+ FILE *f;
+
+ for (path = fontPath; *path; ++path) {
+ extFontFile = appendToPath(new GString(*path), name->getCString());
+ f = fopen(extFontFile->getCString(), "rb");
+ if (!f) {
+ extFontFile->append(".pfb");
+ f = fopen(extFontFile->getCString(), "rb");
+ }
+ if (!f) {
+ extFontFile->del(extFontFile->getLength() - 4, 4);
+ extFontFile->append(".pfa");
+ f = fopen(extFontFile->getCString(), "rb");
+ }
+ if (f) {
+ fclose(f);
+ break;
+ }
+ delete extFontFile;
+ extFontFile = NULL;
+ }
+}
+
+char *GfxFont::readExtFontFile(int *len) {
+ FILE *f;
+ char *buf;
+
+ if (!(f = fopen(extFontFile->getCString(), "rb"))) {
+ error(-1, "Internal: external font file '%s' vanished", extFontFile);
+ return NULL;
+ }
+ fseek(f, 0, SEEK_END);
+ *len = (int)ftell(f);
+ fseek(f, 0, SEEK_SET);
+ buf = (char *)gmalloc(*len);
+ if ((int)fread(buf, 1, *len, f) != *len)
+ error(-1, "Error reading external font file '%s'", extFontFile);
+ fclose(f);
+ return buf;
+}
+
+char *GfxFont::readEmbFontFile(XRef *xref, int *len) {
+ char *buf;
+ Object obj1, obj2;
+ Stream *str;
+ int c;
+ int size, i;
+
+ obj1.initRef(embFontID.num, embFontID.gen);
+ obj1.fetch(xref, &obj2);
+ if (!obj2.isStream()) {
+ error(-1, "Embedded font file is not a stream");
+ obj2.free();
+ obj1.free();
+ embFontID.num = -1;
+ return NULL;
+ }
+ str = obj2.getStream();
+
+ buf = NULL;
+ i = size = 0;
+ str->reset();
+ while ((c = str->getChar()) != EOF) {
+ if (i == size) {
+ size += 4096;
+ buf = (char *)grealloc(buf, size);
+ }
+ buf[i++] = c;
+ }
+ *len = i;
+ str->close();
+
+ obj2.free();
+ obj1.free();
+
+ return buf;
+}
+
+void GfxFont::makeWidths(Dict *fontDict, FontEncoding *builtinEncoding,
+ Gushort *builtinWidths, int missingWidth) {
+ Object obj1, obj2;
+ int firstChar, lastChar;
+ int code, code2;
+ char *charName;
+ Gushort *defWidths;
+ int index;
+ double mult;
+
+ // initialize all widths
+ for (code = 0; code < 256; ++code) {
+ widths[code] = missingWidth * 0.001;
+ }
+
+ // use widths from font dict, if present
+ fontDict->lookup("FirstChar", &obj1);
+ firstChar = obj1.isInt() ? obj1.getInt() : 0;
+ obj1.free();
+ fontDict->lookup("LastChar", &obj1);
+ lastChar = obj1.isInt() ? obj1.getInt() : 255;
+ obj1.free();
+ if (type == fontType3)
+ mult = fontMat[0];
+ else
+ mult = 0.001;
+ fontDict->lookup("Widths", &obj1);
+ if (obj1.isArray()) {
+ for (code = firstChar; code <= lastChar; ++code) {
+ obj1.arrayGet(code - firstChar, &obj2);
+ if (obj2.isNum())
+ widths[code] = obj2.getNum() * mult;
+ obj2.free();
+ }
+
+ // use widths from built-in font
+ } else if (builtinEncoding) {
+ code2 = 0; // to make gcc happy
+ for (code = 0; code < 256; ++code) {
+ if ((charName = encoding->getCharName(code)) &&
+ (code2 = builtinEncoding->getCharCode(charName)) >= 0) {
+ widths[code] = builtinWidths[code2] * 0.001;
+ } else if (code == 32) {
+ // this is a kludge for broken PDF files that encode char 32
+ // as .notdef
+ widths[code] = builtinWidths[' '] * 0.001;
+ }
+ }
+
+ // couldn't find widths -- use defaults
+ } else {
+#if 0 //~
+ //~ certain PDF generators apparently don't include widths
+ //~ for Arial and TimesNewRoman -- and this error message
+ //~ is a nuisance
+ error(-1, "No character widths resource for non-builtin font");
+#endif
+ if (isFixedWidth())
+ index = 0;
+ else if (isSerif())
+ index = 8;
+ else
+ index = 4;
+ if (isBold())
+ index += 2;
+ if (isItalic())
+ index += 1;
+ defWidths = defCharWidths[index];
+ code2 = 0; // to make gcc happy
+ for (code = 0; code < 256; ++code) {
+ if ((charName = encoding->getCharName(code)) &&
+ (code2 = standardEncoding.getCharCode(charName)) >= 0)
+ widths[code] = defWidths[code2] * 0.001;
+ }
+ }
+ obj1.free();
+}
+
+void GfxFont::getType0EncAndWidths(Dict *fontDict) {
+ Object obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8;
+ int excepsSize;
+ int i, j, k, n;
+
+ widths16.exceps = NULL;
+ widths16.excepsV = NULL;
+
+ // get the CIDFont
+ fontDict->lookup("DescendantFonts", &obj1);
+ if (!obj1.isArray() || obj1.arrayGetLength() != 1) {
+ error(-1, "Bad DescendantFonts entry for Type 0 font");
+ goto err1;
+ }
+ obj1.arrayGet(0, &obj2);
+ if (!obj2.isDict()) {
+ error(-1, "Bad descendant font of Type 0 font");
+ goto err2;
+ }
+
+ // get font info
+ obj2.dictLookup("CIDSystemInfo", &obj3);
+ if (!obj3.isDict()) {
+ error(-1, "Bad CIDSystemInfo in Type 0 font descendant");
+ goto err3;
+ }
+ obj3.dictLookup("Registry", &obj4);
+ obj3.dictLookup("Ordering", &obj5);
+ if (obj4.isString() && obj5.isString()) {
+ if (obj4.getString()->cmp("Adobe") == 0 &&
+ obj5.getString()->cmp("Japan1") == 0) {
+#if JAPANESE_SUPPORT
+ is16 = gTrue;
+ enc16.charSet = font16AdobeJapan12;
+#else
+ error(-1, "Xpdf was compiled without Japanese font support");
+ goto err4;
+#endif
+ } else if (obj4.getString()->cmp("Adobe") == 0 &&
+ obj5.getString()->cmp("GB1") == 0) {
+#if CHINESE_GB_SUPPORT
+ is16 = gTrue;
+ enc16.charSet = font16AdobeGB12;
+#else
+ error(-1, "Xpdf was compiled without Chinese GB font support");
+ goto err4;
+#endif
+ } else if (obj4.getString()->cmp("Adobe") == 0 &&
+ obj5.getString()->cmp("CNS1") == 0) {
+#if CHINESE_CNS_SUPPORT
+ is16 = gTrue;
+ enc16.charSet = font16AdobeCNS13;
+#else
+ error(-1, "Xpdf was compiled without Chinese CNS font support");
+ goto err4;
+#endif
+ } else {
+ error(-1, "Unknown Type 0 character set: %s-%s",
+ obj4.getString()->getCString(), obj5.getString()->getCString());
+ goto err4;
+ }
+ } else {
+ error(-1, "Unknown Type 0 character set");
+ goto err4;
+ }
+ obj5.free();
+ obj4.free();
+ obj3.free();
+
+ // get default char width
+ obj2.dictLookup("DW", &obj3);
+ if (obj3.isInt())
+ widths16.defWidth = obj3.getInt() * 0.001;
+ else
+ widths16.defWidth = 1.0;
+ obj3.free();
+
+ // get default char metrics for vertical font
+ obj2.dictLookup("DW2", &obj3);
+ widths16.defVY = 0.880;
+ widths16.defHeight = -1;
+ if (obj3.isArray() && obj3.arrayGetLength() == 2) {
+ obj3.arrayGet(0, &obj4);
+ if (obj4.isInt()) {
+ widths16.defVY = obj4.getInt() * 0.001;
+ }
+ obj4.free();
+ obj3.arrayGet(1, &obj4);
+ if (obj4.isInt()) {
+ widths16.defHeight = obj4.getInt() * 0.001;
+ }
+ obj4.free();
+ }
+ obj3.free();
+
+ // get char width exceptions
+ widths16.exceps = NULL;
+ widths16.numExceps = 0;
+ obj2.dictLookup("W", &obj3);
+ if (obj3.isArray()) {
+ excepsSize = 0;
+ k = 0;
+ i = 0;
+ while (i+1 < obj3.arrayGetLength()) {
+ obj3.arrayGet(i, &obj4);
+ obj3.arrayGet(i+1, &obj5);
+ if (obj4.isInt() && obj5.isInt()) {
+ obj3.arrayGet(i+2, &obj6);
+ if (!obj6.isNum()) {
+ error(-1, "Bad widths array in Type 0 font");
+ obj6.free();
+ obj5.free();
+ obj4.free();
+ break;
+ }
+ if (k == excepsSize) {
+ excepsSize += 16;
+ widths16.exceps = (GfxFontWidthExcep *)
+ grealloc(widths16.exceps,
+ excepsSize * sizeof(GfxFontWidthExcep));
+ }
+ widths16.exceps[k].first = obj4.getInt();
+ widths16.exceps[k].last = obj5.getInt();
+ widths16.exceps[k].width = obj6.getNum() * 0.001;
+ obj6.free();
+ ++k;
+ i += 3;
+ } else if (obj4.isInt() && obj5.isArray()) {
+ if (k + obj5.arrayGetLength() >= excepsSize) {
+ excepsSize = (k + obj5.arrayGetLength() + 15) & ~15;
+ widths16.exceps = (GfxFontWidthExcep *)
+ grealloc(widths16.exceps,
+ excepsSize * sizeof(GfxFontWidthExcep));
+ }
+ n = obj4.getInt();
+ for (j = 0; j < obj5.arrayGetLength(); ++j) {
+ obj5.arrayGet(j, &obj6);
+ if (!obj6.isNum()) {
+ error(-1, "Bad widths array in Type 0 font");
+ obj6.free();
+ break;
+ }
+ widths16.exceps[k].first = widths16.exceps[k].last = n++;
+ widths16.exceps[k].width = obj6.getNum() * 0.001;
+ obj6.free();
+ ++k;
+ }
+ i += 2;
+ } else {
+ error(-1, "Bad widths array in Type 0 font");
+ obj6.free();
+ obj5.free();
+ obj4.free();
+ break;
+ }
+ obj5.free();
+ obj4.free();
+ }
+ widths16.numExceps = k;
+ if (k > 0)
+ qsort(widths16.exceps, k, sizeof(GfxFontWidthExcep), &cmpWidthExcep);
+ }
+ obj3.free();
+
+ // get char metric exceptions for vertical font
+ widths16.excepsV = NULL;
+ widths16.numExcepsV = 0;
+ obj2.dictLookup("W2", &obj3);
+ if (obj3.isArray()) {
+ excepsSize = 0;
+ k = 0;
+ i = 0;
+ while (i+1 < obj3.arrayGetLength()) {
+ obj3.arrayGet(i, &obj4);
+ obj3.arrayGet(i+1, &obj5);
+ if (obj4.isInt() && obj5.isInt()) {
+ obj3.arrayGet(i+2, &obj6);
+ obj3.arrayGet(i+3, &obj7);
+ obj3.arrayGet(i+4, &obj8);
+ if (!obj6.isNum() || !obj7.isNum() || !obj8.isNum()) {
+ error(-1, "Bad widths (W2) array in Type 0 font");
+ obj8.free();
+ obj7.free();
+ obj6.free();
+ obj5.free();
+ obj4.free();
+ break;
+ }
+ if (k == excepsSize) {
+ excepsSize += 16;
+ widths16.excepsV = (GfxFontWidthExcepV *)
+ grealloc(widths16.excepsV,
+ excepsSize * sizeof(GfxFontWidthExcepV));
+ }
+ widths16.excepsV[k].first = obj4.getInt();
+ widths16.excepsV[k].last = obj5.getInt();
+ widths16.excepsV[k].height = obj6.getNum() * 0.001;
+ widths16.excepsV[k].vx = obj7.getNum() * 0.001;
+ widths16.excepsV[k].vy = obj8.getNum() * 0.001;
+ obj8.free();
+ obj7.free();
+ obj6.free();
+ ++k;
+ i += 5;
+ } else if (obj4.isInt() && obj5.isArray()) {
+ if (k + obj5.arrayGetLength() / 3 >= excepsSize) {
+ excepsSize = (k + obj5.arrayGetLength() / 3 + 15) & ~15;
+ widths16.excepsV = (GfxFontWidthExcepV *)
+ grealloc(widths16.excepsV,
+ excepsSize * sizeof(GfxFontWidthExcepV));
+ }
+ n = obj4.getInt();
+ for (j = 0; j < obj5.arrayGetLength(); j += 3) {
+ obj5.arrayGet(j, &obj6);
+ obj5.arrayGet(j+1, &obj7);
+ obj5.arrayGet(j+1, &obj8);
+ if (!obj6.isNum() || !obj7.isNum() || !obj8.isNum()) {
+ error(-1, "Bad widths (W2) array in Type 0 font");
+ obj6.free();
+ break;
+ }
+ widths16.excepsV[k].first = widths16.exceps[k].last = n++;
+ widths16.excepsV[k].height = obj6.getNum() * 0.001;
+ widths16.excepsV[k].vx = obj7.getNum() * 0.001;
+ widths16.excepsV[k].vy = obj8.getNum() * 0.001;
+ obj8.free();
+ obj7.free();
+ obj6.free();
+ ++k;
+ }
+ i += 2;
+ } else {
+ error(-1, "Bad widths array in Type 0 font");
+ obj5.free();
+ obj4.free();
+ break;
+ }
+ obj5.free();
+ obj4.free();
+ }
+ widths16.numExcepsV = k;
+ if (k > 0) {
+ qsort(widths16.excepsV, k, sizeof(GfxFontWidthExcepV), &cmpWidthExcepV);
+ }
+ }
+ obj3.free();
+
+ obj2.free();
+ obj1.free();
+
+ // get encoding (CMap)
+ fontDict->lookup("Encoding", &obj1);
+ if (!obj1.isName()) {
+ error(-1, "Bad encoding for Type 0 font");
+ goto err1;
+ }
+#if JAPANESE_SUPPORT
+ if (enc16.charSet == font16AdobeJapan12) {
+ for (i = 0; gfxJapan12Tab[i].name; ++i) {
+ if (!strcmp(obj1.getName(), gfxJapan12Tab[i].name))
+ break;
+ }
+ if (!gfxJapan12Tab[i].name) {
+ error(-1, "Unknown encoding '%s' for Adobe-Japan1-2 font",
+ obj1.getName());
+ goto err1;
+ }
+ enc16.enc = gfxJapan12Tab[i].enc;
+ }
+#endif
+#if CHINESE_GB_SUPPORT
+ if (enc16.charSet == font16AdobeGB12) {
+ for (i = 0; gfxGB12Tab[i].name; ++i) {
+ if (!strcmp(obj1.getName(), gfxGB12Tab[i].name))
+ break;
+ }
+ if (!gfxGB12Tab[i].name) {
+ error(-1, "Unknown encoding '%s' for Adobe-GB1-2 font",
+ obj1.getName());
+ goto err1;
+ }
+ enc16.enc = gfxGB12Tab[i].enc;
+ }
+#endif
+#if CHINESE_CNS_SUPPORT
+ if (enc16.charSet == font16AdobeCNS13) {
+ for (i = 0; gfxCNS13Tab[i].name; ++i) {
+ if (!strcmp(obj1.getName(), gfxCNS13Tab[i].name))
+ break;
+ }
+ if (!gfxCNS13Tab[i].name) {
+ error(-1, "Unknown encoding '%s' for Adobe-CNS1-3 font",
+ obj1.getName());
+ goto err1;
+ }
+ enc16.enc = gfxCNS13Tab[i].enc;
+ }
+#endif
+ obj1.free();
+
+ return;
+
+ err4:
+ obj5.free();
+ obj4.free();
+ err3:
+ obj3.free();
+ err2:
+ obj2.free();
+ err1:
+ obj1.free();
+ //~ fix this --> add 16-bit font support to FontFile
+ encoding = new FontEncoding();
+ makeWidths(fontDict, NULL, NULL, 0);
+}
+
+extern "C" {
+static int CDECL cmpWidthExcep(const void *w1, const void *w2) {
+ return ((GfxFontWidthExcep *)w1)->first - ((GfxFontWidthExcep *)w2)->first;
+}
+
+static int CDECL cmpWidthExcepV(const void *w1, const void *w2) {
+ return ((GfxFontWidthExcepV *)w1)->first - ((GfxFontWidthExcepV *)w2)->first;
+}
+}
+
+//------------------------------------------------------------------------
+// GfxFontDict
+//------------------------------------------------------------------------
+
+GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) {
+ int i;
+ Object obj1, obj2;
+
+ numFonts = fontDict->getLength();
+ fonts = (GfxFont **)gmalloc(numFonts * sizeof(GfxFont *));
+ for (i = 0; i < numFonts; ++i) {
+ fontDict->getValNF(i, &obj1);
+ obj1.fetch(xref, &obj2);
+ if (obj1.isRef() && obj2.isDict()) {
+ fonts[i] = new GfxFont(xref, fontDict->getKey(i),
+ obj1.getRef(), obj2.getDict());
+ } else {
+ error(-1, "font resource is not a dictionary");
+ fonts[i] = NULL;
+ }
+ obj1.free();
+ obj2.free();
+ }
+}
+
+GfxFontDict::~GfxFontDict() {
+ int i;
+
+ for (i = 0; i < numFonts; ++i)
+ delete fonts[i];
+ gfree(fonts);
+}
+
+GfxFont *GfxFontDict::lookup(char *tag) {
+ int i;
+
+ for (i = 0; i < numFonts; ++i) {
+ if (fonts[i]->matches(tag))
+ return fonts[i];
+ }
+ return NULL;
+}
diff --git a/pdftops/GfxFont.h b/pdftops/GfxFont.h
new file mode 100644
index 000000000..e51635632
--- /dev/null
+++ b/pdftops/GfxFont.h
@@ -0,0 +1,250 @@
+//========================================================================
+//
+// GfxFont.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef GFXFONT_H
+#define GFXFONT_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "gtypes.h"
+#include "GString.h"
+#include "Object.h"
+#include "FontEncoding.h"
+
+class Dict;
+struct BuiltinFont;
+
+//------------------------------------------------------------------------
+// GfxFontCharSet16
+//------------------------------------------------------------------------
+
+enum GfxFontCharSet16 {
+ font16AdobeJapan12, // Adobe-Japan1-2
+ font16AdobeGB12, // Adobe-GB1-2 (Chinese)
+ font16AdobeCNS13 // Adobe-CNS1-3 (Chinese)
+};
+
+//------------------------------------------------------------------------
+// GfxFontEncoding16
+//------------------------------------------------------------------------
+
+struct GfxFontEncoding16 {
+ int wMode; // writing mode (0=horizontal, 1=vertical)
+ Guchar codeLen[256]; // length of codes, in bytes, indexed by
+ // first byte of code
+ Gushort map1[256]; // one-byte code mapping:
+ // map1[code] --> 16-bit char selector
+ Gushort *map2; // two-byte code mapping
+ // map2[2*i] --> first code in range
+ // map2[2*i+1] --> 16-bit char selector
+ // for map2[2*i]
+ int map2Len; // length of map2 array (divided by 2)
+};
+
+//------------------------------------------------------------------------
+// GfxFontWidths16
+//------------------------------------------------------------------------
+
+struct GfxFontWidthExcep {
+ int first; // this record applies to
+ int last; // chars <first>..<last>
+ double width; // char width
+};
+
+struct GfxFontWidthExcepV {
+ int first; // this record applies to
+ int last; // chars <first>..<last>
+ double height; // char height
+ double vx, vy; // origin position
+};
+
+struct GfxFontWidths16 {
+ double defWidth; // default char width
+ double defHeight; // default char height
+ double defVY; // default origin position
+ GfxFontWidthExcep *exceps; // exceptions
+ int numExceps; // number of valid entries in exceps
+ GfxFontWidthExcepV *excepsV; // exceptions for vertical font
+ int numExcepsV; // number of valid entries in excepsV
+};
+
+//------------------------------------------------------------------------
+// GfxFont
+//------------------------------------------------------------------------
+
+#define fontFixedWidth (1 << 0)
+#define fontSerif (1 << 1)
+#define fontSymbolic (1 << 2)
+#define fontItalic (1 << 6)
+#define fontBold (1 << 18)
+
+enum GfxFontType {
+ fontUnknownType,
+ fontType1,
+ fontType1C,
+ fontType3,
+ fontTrueType,
+ fontType0
+};
+
+class GfxFont {
+public:
+
+ // Constructor.
+ GfxFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict);
+
+ // Destructor.
+ ~GfxFont();
+
+ // Get font tag.
+ GString *getTag() { return tag; }
+
+ // Get font dictionary ID.
+ Ref getID() { return id; }
+
+ // Does this font match the tag?
+ GBool matches(char *tagA) { return !tag->cmp(tagA); }
+
+ // Get base font name.
+ GString *getName() { return name; }
+
+ // Get font type.
+ GfxFontType getType() { return type; }
+
+ // Does this font use 16-bit characters?
+ GBool is16Bit() { return is16; }
+
+ // Get embedded font ID, i.e., a ref for the font file stream.
+ // Returns false if there is no embedded font.
+ GBool getEmbeddedFontID(Ref *embID)
+ { *embID = embFontID; return embFontID.num >= 0; }
+
+ // Get the PostScript font name for the embedded font. Returns
+ // NULL if there is no embedded font.
+ char *getEmbeddedFontName()
+ { return embFontName ? embFontName->getCString() : (char *)NULL; }
+
+ // Get the name of the external font file. Returns NULL if there
+ // is no external font file.
+ GString *getExtFontFile() { return extFontFile; }
+
+ // Get font descriptor flags.
+ GBool isFixedWidth() { return flags & fontFixedWidth; }
+ GBool isSerif() { return flags & fontSerif; }
+ GBool isSymbolic() { return flags & fontSymbolic; }
+ GBool isItalic() { return flags & fontItalic; }
+ GBool isBold() { return flags & fontBold; }
+
+ // Get width of a character or string.
+ double getWidth(Guchar c) { return widths[c]; }
+ double getWidth(GString *s);
+
+ // Get character metrics for 16-bit font.
+ double getWidth16(int c);
+ double getHeight16(int c);
+ double getOriginX16(int c);
+ double getOriginY16(int c);
+
+ // Return the encoding.
+ FontEncoding *getEncoding() { return encoding; }
+
+ // Return the character name associated with <code>.
+ char *getCharName(int code) { return encoding->getCharName(code); }
+
+ // Return the code associated with <name>.
+ int getCharCode(char *charName) { return encoding->getCharCode(charName); }
+
+ // Return the Type 3 CharProc for the character associated with <code>.
+ Object *getCharProc(int code, Object *proc);
+
+ // Return the 16-bit character set and encoding.
+ GfxFontCharSet16 getCharSet16() { return enc16.charSet; }
+ GfxFontEncoding16 *getEncoding16() { return enc16.enc; }
+
+ // Get the writing mode (0=horizontal, 1=vertical).
+ int getWMode16() { return enc16.enc->wMode; }
+
+ // Return the font matrix.
+ double *getFontMatrix() { return fontMat; }
+
+ // Return the font bounding box.
+ double *getFontBBox() { return fontBBox; }
+
+ // Return the ascent and descent values.
+ double getAscent() { return ascent; }
+ double getDescent() { return descent; }
+
+ // Read an external or embedded font file into a buffer.
+ char *readExtFontFile(int *len);
+ char *readEmbFontFile(XRef *xref, int *len);
+
+private:
+
+ void getEncAndWidths(XRef *xref, Dict *fontDict,
+ BuiltinFont *builtinFont, int missingWidth);
+ void findExtFontFile();
+ void makeWidths(Dict *fontDict, FontEncoding *builtinEncoding,
+ Gushort *builtinWidths, int missingWidth);
+ void getType0EncAndWidths(Dict *fontDict);
+
+ GString *tag; // PDF font tag
+ Ref id; // reference (used as unique ID)
+ GString *name; // font name
+ int flags; // font descriptor flags
+ GfxFontType type; // type of font
+ GBool is16; // set if font uses 16-bit chars
+ GString *embFontName; // name of embedded font
+ Ref embFontID; // ref to embedded font file stream
+ GString *extFontFile; // external font file name
+ Object charProcs; // Type3 CharProcs dictionary
+ double fontMat[6]; // font matrix
+ double fontBBox[4]; // font bounding box
+ double ascent; // max height above baseline
+ double descent; // max depth below baseline
+ union {
+ FontEncoding *encoding; // 8-bit font encoding
+ struct {
+ GfxFontCharSet16 charSet; // 16-bit character set
+ GfxFontEncoding16 *enc; // 16-bit encoding (CMap)
+ } enc16;
+ };
+ union {
+ double widths[256]; // width of each char for 8-bit font
+ GfxFontWidths16 widths16; // char widths for 16-bit font
+ };
+};
+
+//------------------------------------------------------------------------
+// GfxFontDict
+//------------------------------------------------------------------------
+
+class GfxFontDict {
+public:
+
+ // Build the font dictionary, given the PDF font dictionary.
+ GfxFontDict(XRef *xref, Dict *fontDict);
+
+ // Destructor.
+ ~GfxFontDict();
+
+ // Get the specified font.
+ GfxFont *lookup(char *tag);
+
+ // Iterative access.
+ int getNumFonts() { return numFonts; }
+ GfxFont *getFont(int i) { return fonts[i]; }
+
+private:
+
+ GfxFont **fonts; // list of fonts
+ int numFonts; // number of fonts
+};
+
+#endif
diff --git a/pdftops/GfxState.cxx b/pdftops/GfxState.cxx
new file mode 100644
index 000000000..13ce17845
--- /dev/null
+++ b/pdftops/GfxState.cxx
@@ -0,0 +1,2235 @@
+//========================================================================
+//
+// GfxState.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stddef.h>
+#include <math.h>
+#include <string.h> // for memcpy()
+#include "gmem.h"
+#include "Error.h"
+#include "Object.h"
+#include "Array.h"
+#include "Page.h"
+#include "GfxState.h"
+
+//------------------------------------------------------------------------
+
+static inline double clip01(double x) {
+ return (x < 0) ? 0 : ((x > 1) ? 1 : x);
+}
+
+//------------------------------------------------------------------------
+// GfxColorSpace
+//------------------------------------------------------------------------
+
+GfxColorSpace::GfxColorSpace() {
+}
+
+GfxColorSpace::~GfxColorSpace() {
+}
+
+GfxColorSpace *GfxColorSpace::parse(Object *csObj) {
+ GfxColorSpace *cs;
+ Object obj1;
+
+ cs = NULL;
+ if (csObj->isName()) {
+ if (csObj->isName("DeviceGray") || csObj->isName("G")) {
+ cs = new GfxDeviceGrayColorSpace();
+ } else if (csObj->isName("DeviceRGB") || csObj->isName("RGB")) {
+ cs = new GfxDeviceRGBColorSpace();
+ } else if (csObj->isName("DeviceCMYK") || csObj->isName("CMYK")) {
+ cs = new GfxDeviceCMYKColorSpace();
+ } else if (csObj->isName("Pattern")) {
+ cs = new GfxPatternColorSpace(NULL);
+ } else {
+ error(-1, "Bad color space '%s'", csObj->getName());
+ }
+ } else if (csObj->isArray()) {
+ csObj->arrayGet(0, &obj1);
+ if (obj1.isName("DeviceGray") || obj1.isName("G")) {
+ cs = new GfxDeviceGrayColorSpace();
+ } else if (obj1.isName("DeviceRGB") || obj1.isName("RGB")) {
+ cs = new GfxDeviceRGBColorSpace();
+ } else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) {
+ cs = new GfxDeviceCMYKColorSpace();
+ } else if (obj1.isName("CalGray")) {
+ cs = GfxCalGrayColorSpace::parse(csObj->getArray());
+ } else if (obj1.isName("CalRGB")) {
+ cs = GfxCalRGBColorSpace::parse(csObj->getArray());
+ } else if (obj1.isName("Lab")) {
+ cs = GfxLabColorSpace::parse(csObj->getArray());
+ } else if (obj1.isName("ICCBased")) {
+ cs = GfxICCBasedColorSpace::parse(csObj->getArray());
+ } else if (obj1.isName("Indexed") || obj1.isName("I")) {
+ cs = GfxIndexedColorSpace::parse(csObj->getArray());
+ } else if (obj1.isName("Separation")) {
+ cs = GfxSeparationColorSpace::parse(csObj->getArray());
+ } else if (obj1.isName("DeviceN")) {
+ cs = GfxDeviceNColorSpace::parse(csObj->getArray());
+ } else if (obj1.isName("Pattern")) {
+ cs = GfxPatternColorSpace::parse(csObj->getArray());
+ } else {
+ error(-1, "Bad color space '%s'", csObj->getName());
+ }
+ obj1.free();
+ } else {
+ error(-1, "Bad color space - expected name or array");
+ }
+ return cs;
+}
+
+void GfxColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
+ int maxImgPixel) {
+ int i;
+
+ for (i = 0; i < getNComps(); ++i) {
+ decodeLow[i] = 0;
+ decodeRange[i] = 1;
+ }
+}
+
+//------------------------------------------------------------------------
+// GfxDeviceGrayColorSpace
+//------------------------------------------------------------------------
+
+GfxDeviceGrayColorSpace::GfxDeviceGrayColorSpace() {
+}
+
+GfxDeviceGrayColorSpace::~GfxDeviceGrayColorSpace() {
+}
+
+GfxColorSpace *GfxDeviceGrayColorSpace::copy() {
+ return new GfxDeviceGrayColorSpace();
+}
+
+void GfxDeviceGrayColorSpace::getGray(GfxColor *color, double *gray) {
+ *gray = clip01(color->c[0]);
+}
+
+void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ rgb->r = rgb->g = rgb->b = clip01(color->c[0]);
+}
+
+void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+ cmyk->c = cmyk->m = cmyk->y = 0;
+ cmyk->k = clip01(1 - color->c[0]);
+}
+
+//------------------------------------------------------------------------
+// GfxCalGrayColorSpace
+//------------------------------------------------------------------------
+
+GfxCalGrayColorSpace::GfxCalGrayColorSpace() {
+ whiteX = whiteY = whiteZ = 1;
+ blackX = blackY = blackZ = 0;
+ gamma = 1;
+}
+
+GfxCalGrayColorSpace::~GfxCalGrayColorSpace() {
+}
+
+GfxColorSpace *GfxCalGrayColorSpace::copy() {
+ GfxCalGrayColorSpace *cs;
+
+ cs = new GfxCalGrayColorSpace();
+ cs->whiteX = whiteX;
+ cs->whiteY = whiteY;
+ cs->whiteZ = whiteZ;
+ cs->blackX = blackX;
+ cs->blackY = blackY;
+ cs->blackZ = blackZ;
+ cs->gamma = gamma;
+ return cs;
+}
+
+GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) {
+ GfxCalGrayColorSpace *cs;
+ Object obj1, obj2, obj3;
+
+ arr->get(1, &obj1);
+ if (!obj1.isDict()) {
+ error(-1, "Bad CalGray color space");
+ obj1.free();
+ return NULL;
+ }
+ cs = new GfxCalGrayColorSpace();
+ if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&
+ obj2.arrayGetLength() == 3) {
+ obj2.arrayGet(0, &obj3);
+ cs->whiteX = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(1, &obj3);
+ cs->whiteY = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(2, &obj3);
+ cs->whiteZ = obj3.getNum();
+ obj3.free();
+ }
+ obj2.free();
+ if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&
+ obj2.arrayGetLength() == 3) {
+ obj2.arrayGet(0, &obj3);
+ cs->blackX = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(1, &obj3);
+ cs->blackY = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(2, &obj3);
+ cs->blackZ = obj3.getNum();
+ obj3.free();
+ }
+ obj2.free();
+ if (obj1.dictLookup("Gamma", &obj2)->isNum()) {
+ cs->gamma = obj2.getNum();
+ }
+ obj2.free();
+ obj1.free();
+ return cs;
+}
+
+void GfxCalGrayColorSpace::getGray(GfxColor *color, double *gray) {
+ *gray = clip01(color->c[0]);
+}
+
+void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ rgb->r = rgb->g = rgb->b = clip01(color->c[0]);
+}
+
+void GfxCalGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+ cmyk->c = cmyk->m = cmyk->y = 0;
+ cmyk->k = clip01(1 - color->c[0]);
+}
+
+//------------------------------------------------------------------------
+// GfxDeviceRGBColorSpace
+//------------------------------------------------------------------------
+
+GfxDeviceRGBColorSpace::GfxDeviceRGBColorSpace() {
+}
+
+GfxDeviceRGBColorSpace::~GfxDeviceRGBColorSpace() {
+}
+
+GfxColorSpace *GfxDeviceRGBColorSpace::copy() {
+ return new GfxDeviceRGBColorSpace();
+}
+
+void GfxDeviceRGBColorSpace::getGray(GfxColor *color, double *gray) {
+ *gray = clip01(0.299 * color->c[0] +
+ 0.587 * color->c[1] +
+ 0.114 * color->c[2]);
+}
+
+void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ rgb->r = clip01(color->c[0]);
+ rgb->g = clip01(color->c[1]);
+ rgb->b = clip01(color->c[2]);
+}
+
+void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+ double c, m, y, k;
+
+ c = clip01(1 - color->c[0]);
+ m = clip01(1 - color->c[1]);
+ y = clip01(1 - color->c[2]);
+ k = c;
+ if (m < k) {
+ k = m;
+ }
+ if (y < k) {
+ k = y;
+ }
+ cmyk->c = c - k;
+ cmyk->m = m - k;
+ cmyk->y = y - k;
+ cmyk->k = k;
+}
+
+//------------------------------------------------------------------------
+// GfxCalRGBColorSpace
+//------------------------------------------------------------------------
+
+GfxCalRGBColorSpace::GfxCalRGBColorSpace() {
+ whiteX = whiteY = whiteZ = 1;
+ blackX = blackY = blackZ = 0;
+ gammaR = gammaG = gammaB = 1;
+ mat[0] = 1; mat[1] = 0; mat[2] = 0;
+ mat[3] = 0; mat[4] = 1; mat[5] = 0;
+ mat[6] = 0; mat[7] = 0; mat[8] = 1;
+}
+
+GfxCalRGBColorSpace::~GfxCalRGBColorSpace() {
+}
+
+GfxColorSpace *GfxCalRGBColorSpace::copy() {
+ GfxCalRGBColorSpace *cs;
+ int i;
+
+ cs = new GfxCalRGBColorSpace();
+ cs->whiteX = whiteX;
+ cs->whiteY = whiteY;
+ cs->whiteZ = whiteZ;
+ cs->blackX = blackX;
+ cs->blackY = blackY;
+ cs->blackZ = blackZ;
+ cs->gammaR = gammaR;
+ cs->gammaG = gammaG;
+ cs->gammaB = gammaB;
+ for (i = 0; i < 9; ++i) {
+ cs->mat[i] = mat[i];
+ }
+ return cs;
+}
+
+GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) {
+ GfxCalRGBColorSpace *cs;
+ Object obj1, obj2, obj3;
+ int i;
+
+ arr->get(1, &obj1);
+ if (!obj1.isDict()) {
+ error(-1, "Bad CalRGB color space");
+ obj1.free();
+ return NULL;
+ }
+ cs = new GfxCalRGBColorSpace();
+ if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&
+ obj2.arrayGetLength() == 3) {
+ obj2.arrayGet(0, &obj3);
+ cs->whiteX = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(1, &obj3);
+ cs->whiteY = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(2, &obj3);
+ cs->whiteZ = obj3.getNum();
+ obj3.free();
+ }
+ obj2.free();
+ if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&
+ obj2.arrayGetLength() == 3) {
+ obj2.arrayGet(0, &obj3);
+ cs->blackX = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(1, &obj3);
+ cs->blackY = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(2, &obj3);
+ cs->blackZ = obj3.getNum();
+ obj3.free();
+ }
+ obj2.free();
+ if (obj1.dictLookup("Gamma", &obj2)->isArray() &&
+ obj2.arrayGetLength() == 3) {
+ obj2.arrayGet(0, &obj3);
+ cs->gammaR = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(1, &obj3);
+ cs->gammaG = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(2, &obj3);
+ cs->gammaB = obj3.getNum();
+ obj3.free();
+ }
+ obj2.free();
+ if (obj1.dictLookup("Matrix", &obj2)->isArray() &&
+ obj2.arrayGetLength() == 9) {
+ for (i = 0; i < 9; ++i) {
+ obj2.arrayGet(i, &obj3);
+ cs->mat[i] = obj3.getNum();
+ obj3.free();
+ }
+ }
+ obj2.free();
+ obj1.free();
+ return cs;
+}
+
+void GfxCalRGBColorSpace::getGray(GfxColor *color, double *gray) {
+ *gray = clip01(0.299 * color->c[0] +
+ 0.587 * color->c[1] +
+ 0.114 * color->c[2]);
+}
+
+void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ rgb->r = clip01(color->c[0]);
+ rgb->g = clip01(color->c[1]);
+ rgb->b = clip01(color->c[2]);
+}
+
+void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+ double c, m, y, k;
+
+ c = clip01(1 - color->c[0]);
+ m = clip01(1 - color->c[1]);
+ y = clip01(1 - color->c[2]);
+ k = c;
+ if (m < k) {
+ k = m;
+ }
+ if (y < k) {
+ k = y;
+ }
+ cmyk->c = c - k;
+ cmyk->m = m - k;
+ cmyk->y = y - k;
+ cmyk->k = k;
+}
+
+//------------------------------------------------------------------------
+// GfxDeviceCMYKColorSpace
+//------------------------------------------------------------------------
+
+GfxDeviceCMYKColorSpace::GfxDeviceCMYKColorSpace() {
+}
+
+GfxDeviceCMYKColorSpace::~GfxDeviceCMYKColorSpace() {
+}
+
+GfxColorSpace *GfxDeviceCMYKColorSpace::copy() {
+ return new GfxDeviceCMYKColorSpace();
+}
+
+void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, double *gray) {
+ *gray = clip01(1 - color->c[3]
+ - 0.299 * color->c[0]
+ - 0.587 * color->c[1]
+ - 0.114 * color->c[2]);
+}
+
+void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ rgb->r = clip01(1 - (color->c[0] + color->c[3]));
+ rgb->g = clip01(1 - (color->c[1] + color->c[3]));
+ rgb->b = clip01(1 - (color->c[2] + color->c[3]));
+}
+
+void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+ cmyk->c = clip01(color->c[0]);
+ cmyk->m = clip01(color->c[1]);
+ cmyk->y = clip01(color->c[2]);
+ cmyk->k = clip01(color->c[3]);
+}
+
+//------------------------------------------------------------------------
+// GfxLabColorSpace
+//------------------------------------------------------------------------
+
+// This is the inverse of MatrixLMN in Example 4.10 from the PostScript
+// Language Reference, Third Edition.
+static double xyzrgb[3][3] = {
+ { 3.240449, -1.537136, -0.498531 },
+ { -0.969265, 1.876011, 0.041556 },
+ { 0.055643, -0.204026, 1.057229 }
+};
+
+GfxLabColorSpace::GfxLabColorSpace() {
+ whiteX = whiteY = whiteZ = 1;
+ blackX = blackY = blackZ = 0;
+ aMin = bMin = -100;
+ aMax = bMax = 100;
+}
+
+GfxLabColorSpace::~GfxLabColorSpace() {
+}
+
+GfxColorSpace *GfxLabColorSpace::copy() {
+ GfxLabColorSpace *cs;
+
+ cs = new GfxLabColorSpace();
+ cs->whiteX = whiteX;
+ cs->whiteY = whiteY;
+ cs->whiteZ = whiteZ;
+ cs->blackX = blackX;
+ cs->blackY = blackY;
+ cs->blackZ = blackZ;
+ cs->aMin = aMin;
+ cs->aMax = aMax;
+ cs->bMin = bMin;
+ cs->bMax = bMax;
+ cs->kr = kr;
+ cs->kg = kg;
+ cs->kb = kb;
+ return cs;
+}
+
+GfxColorSpace *GfxLabColorSpace::parse(Array *arr) {
+ GfxLabColorSpace *cs;
+ Object obj1, obj2, obj3;
+
+ arr->get(1, &obj1);
+ if (!obj1.isDict()) {
+ error(-1, "Bad Lab color space");
+ obj1.free();
+ return NULL;
+ }
+ cs = new GfxLabColorSpace();
+ if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&
+ obj2.arrayGetLength() == 3) {
+ obj2.arrayGet(0, &obj3);
+ cs->whiteX = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(1, &obj3);
+ cs->whiteY = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(2, &obj3);
+ cs->whiteZ = obj3.getNum();
+ obj3.free();
+ }
+ obj2.free();
+ if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&
+ obj2.arrayGetLength() == 3) {
+ obj2.arrayGet(0, &obj3);
+ cs->blackX = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(1, &obj3);
+ cs->blackY = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(2, &obj3);
+ cs->blackZ = obj3.getNum();
+ obj3.free();
+ }
+ obj2.free();
+ if (obj1.dictLookup("Range", &obj2)->isArray() &&
+ obj2.arrayGetLength() == 4) {
+ obj2.arrayGet(0, &obj3);
+ cs->aMin = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(1, &obj3);
+ cs->aMax = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(2, &obj3);
+ cs->bMin = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(3, &obj3);
+ cs->bMax = obj3.getNum();
+ obj3.free();
+ }
+ obj2.free();
+ obj1.free();
+
+ cs->kr = 1 / (xyzrgb[0][0] * cs->whiteX +
+ xyzrgb[0][1] * cs->whiteY +
+ xyzrgb[0][2] * cs->whiteZ);
+ cs->kg = 1 / (xyzrgb[1][0] * cs->whiteX +
+ xyzrgb[1][1] * cs->whiteY +
+ xyzrgb[1][2] * cs->whiteZ);
+ cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX +
+ xyzrgb[2][1] * cs->whiteY +
+ xyzrgb[2][2] * cs->whiteZ);
+
+ return cs;
+}
+
+void GfxLabColorSpace::getGray(GfxColor *color, double *gray) {
+ GfxRGB rgb;
+
+ getRGB(color, &rgb);
+ *gray = clip01(0.299 * rgb.r +
+ 0.587 * rgb.g +
+ 0.114 * rgb.b);
+}
+
+void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ double X, Y, Z;
+ double t1, t2;
+ double r, g, b;
+
+ // convert L*a*b* to CIE 1931 XYZ color space
+ t1 = (color->c[0] + 16) / 116;
+ t2 = t1 + color->c[1] / 500;
+ if (t2 >= (6.0 / 29.0)) {
+ X = t2 * t2 * t2;
+ } else {
+ X = (108.0 / 841.0) * (t2 - (4.0 / 29.0));
+ }
+ X *= whiteX;
+ if (t1 >= (6.0 / 29.0)) {
+ Y = t1 * t1 * t1;
+ } else {
+ Y = (108.0 / 841.0) * (t1 - (4.0 / 29.0));
+ }
+ Y *= whiteY;
+ t2 = t1 - color->c[2] / 200;
+ if (t2 >= (6.0 / 29.0)) {
+ Z = t2 * t2 * t2;
+ } else {
+ Z = (108.0 / 841.0) * (t2 - (4.0 / 29.0));
+ }
+ Z *= whiteZ;
+
+ // convert XYZ to RGB, including gamut mapping and gamma correction
+ r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
+ g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
+ b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z;
+ rgb->r = pow(clip01(r * kr), 0.5);
+ rgb->g = pow(clip01(g * kg), 0.5);
+ rgb->b = pow(clip01(b * kb), 0.5);
+}
+
+void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+ GfxRGB rgb;
+ double c, m, y, k;
+
+ getRGB(color, &rgb);
+ c = clip01(1 - rgb.r);
+ m = clip01(1 - rgb.g);
+ y = clip01(1 - rgb.b);
+ k = c;
+ if (m < k) {
+ k = m;
+ }
+ if (y < k) {
+ k = y;
+ }
+ cmyk->c = c - k;
+ cmyk->m = m - k;
+ cmyk->y = y - k;
+ cmyk->k = k;
+}
+
+void GfxLabColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
+ int maxImgPixel) {
+ decodeLow[0] = 0;
+ decodeRange[0] = 100;
+ decodeLow[1] = aMin;
+ decodeRange[1] = aMax - aMin;
+ decodeLow[2] = bMin;
+ decodeRange[2] = bMax - bMin;
+}
+
+//------------------------------------------------------------------------
+// GfxICCBasedColorSpace
+//------------------------------------------------------------------------
+
+GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
+ Ref *iccProfileStreamA) {
+ nComps = nCompsA;
+ alt = altA;
+ iccProfileStream = *iccProfileStreamA;
+ rangeMin[0] = rangeMin[1] = rangeMin[2] = rangeMin[3] = 0;
+ rangeMax[0] = rangeMax[1] = rangeMax[2] = rangeMax[3] = 1;
+}
+
+GfxICCBasedColorSpace::~GfxICCBasedColorSpace() {
+ delete alt;
+}
+
+GfxColorSpace *GfxICCBasedColorSpace::copy() {
+ GfxICCBasedColorSpace *cs;
+ int i;
+
+ cs = new GfxICCBasedColorSpace(nComps, alt->copy(), &iccProfileStream);
+ for (i = 0; i < 4; ++i) {
+ cs->rangeMin[i] = rangeMin[i];
+ cs->rangeMax[i] = rangeMax[i];
+ }
+ return cs;
+}
+
+GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) {
+ GfxICCBasedColorSpace *cs;
+ Ref iccProfileStreamA;
+ int nCompsA;
+ GfxColorSpace *altA;
+ Dict *dict;
+ Object obj1, obj2, obj3;
+ int i;
+
+ arr->getNF(1, &obj1);
+ if (obj1.isRef()) {
+ iccProfileStreamA = obj1.getRef();
+ } else {
+ iccProfileStreamA.num = 0;
+ iccProfileStreamA.gen = 0;
+ }
+ obj1.free();
+ arr->get(1, &obj1);
+ if (!obj1.isStream()) {
+ error(-1, "Bad ICCBased color space (stream)");
+ obj1.free();
+ return NULL;
+ }
+ dict = obj1.streamGetDict();
+ if (!dict->lookup("N", &obj2)->isInt()) {
+ error(-1, "Bad ICCBased color space (N)");
+ obj2.free();
+ obj1.free();
+ return NULL;
+ }
+ nCompsA = obj2.getInt();
+ obj2.free();
+ if (dict->lookup("Alternate", &obj2)->isNull() ||
+ !(altA = GfxColorSpace::parse(&obj2))) {
+ switch (nCompsA) {
+ case 1:
+ altA = new GfxDeviceGrayColorSpace();
+ break;
+ case 3:
+ altA = new GfxDeviceRGBColorSpace();
+ break;
+ case 4:
+ altA = new GfxDeviceCMYKColorSpace();
+ break;
+ default:
+ error(-1, "Bad ICCBased color space - invalid N");
+ obj2.free();
+ obj1.free();
+ return NULL;
+ }
+ }
+ obj2.free();
+ cs = new GfxICCBasedColorSpace(nCompsA, altA, &iccProfileStreamA);
+ if (dict->lookup("Range", &obj2)->isArray() &&
+ obj2.arrayGetLength() == 2 * nCompsA) {
+ for (i = 0; i < nCompsA; ++i) {
+ obj2.arrayGet(2*i, &obj3);
+ cs->rangeMin[i] = obj3.getNum();
+ obj3.free();
+ obj2.arrayGet(2*i+1, &obj3);
+ cs->rangeMax[i] = obj3.getNum();
+ obj3.free();
+ }
+ }
+ obj2.free();
+ obj1.free();
+ return cs;
+}
+
+void GfxICCBasedColorSpace::getGray(GfxColor *color, double *gray) {
+ alt->getGray(color, gray);
+}
+
+void GfxICCBasedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ alt->getRGB(color, rgb);
+}
+
+void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+ alt->getCMYK(color, cmyk);
+}
+
+void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow,
+ double *decodeRange,
+ int maxImgPixel) {
+ int i;
+
+ for (i = 0; i < nComps; ++i) {
+ decodeLow[i] = rangeMin[i];
+ decodeRange[i] = rangeMax[i] - rangeMin[i];
+ }
+}
+
+//------------------------------------------------------------------------
+// GfxIndexedColorSpace
+//------------------------------------------------------------------------
+
+GfxIndexedColorSpace::GfxIndexedColorSpace(GfxColorSpace *baseA,
+ int indexHighA) {
+ base = baseA;
+ indexHigh = indexHighA;
+ lookup = (Guchar *)gmalloc((indexHigh + 1) * base->getNComps() *
+ sizeof(Guchar));
+}
+
+GfxIndexedColorSpace::~GfxIndexedColorSpace() {
+ delete base;
+ gfree(lookup);
+}
+
+GfxColorSpace *GfxIndexedColorSpace::copy() {
+ GfxIndexedColorSpace *cs;
+
+ cs = new GfxIndexedColorSpace(base->copy(), indexHigh);
+ memcpy(cs->lookup, lookup,
+ (indexHigh + 1) * base->getNComps() * sizeof(Guchar));
+ return cs;
+}
+
+GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr) {
+ GfxIndexedColorSpace *cs;
+ GfxColorSpace *baseA;
+ int indexHighA;
+ Object obj1;
+ int x;
+ char *s;
+ int n, i, j;
+
+ if (arr->getLength() != 4) {
+ error(-1, "Bad Indexed color space");
+ goto err1;
+ }
+ arr->get(1, &obj1);
+ if (!(baseA = GfxColorSpace::parse(&obj1))) {
+ error(-1, "Bad Indexed color space (base color space)");
+ goto err2;
+ }
+ obj1.free();
+ if (!arr->get(2, &obj1)->isInt()) {
+ error(-1, "Bad Indexed color space (hival)");
+ goto err2;
+ }
+ indexHighA = obj1.getInt();
+ obj1.free();
+ cs = new GfxIndexedColorSpace(baseA, indexHighA);
+ arr->get(3, &obj1);
+ n = baseA->getNComps();
+ if (obj1.isStream()) {
+ obj1.streamReset();
+ for (i = 0; i <= indexHighA; ++i) {
+ for (j = 0; j < n; ++j) {
+ if ((x = obj1.streamGetChar()) == EOF) {
+ error(-1, "Bad Indexed color space (lookup table stream too short)");
+ goto err3;
+ }
+ cs->lookup[i*n + j] = (Guchar)x;
+ }
+ }
+ obj1.streamClose();
+ } else if (obj1.isString()) {
+ if (obj1.getString()->getLength() < (indexHighA + 1) * n) {
+ error(-1, "Bad Indexed color space (lookup table string too short)");
+ goto err3;
+ }
+ s = obj1.getString()->getCString();
+ for (i = 0; i <= indexHighA; ++i) {
+ for (j = 0; j < n; ++j) {
+ cs->lookup[i*n + j] = (Guchar)*s++;
+ }
+ }
+ } else {
+ error(-1, "Bad Indexed color space (lookup table)");
+ goto err3;
+ }
+ obj1.free();
+ return cs;
+
+ err3:
+ delete cs;
+ err2:
+ obj1.free();
+ err1:
+ return NULL;
+}
+
+void GfxIndexedColorSpace::getGray(GfxColor *color, double *gray) {
+ Guchar *p;
+ GfxColor color2;
+ int n, i;
+
+ n = base->getNComps();
+ p = &lookup[(int)(color->c[0] + 0.5) * n];
+ for (i = 0; i < n; ++i) {
+ color2.c[i] = p[i] / 255.0;
+ }
+ base->getGray(&color2, gray);
+}
+
+void GfxIndexedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ Guchar *p;
+ GfxColor color2;
+ int n, i;
+
+ n = base->getNComps();
+ p = &lookup[(int)(color->c[0] + 0.5) * n];
+ for (i = 0; i < n; ++i) {
+ color2.c[i] = p[i] / 255.0;
+ }
+ base->getRGB(&color2, rgb);
+}
+
+void GfxIndexedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+ Guchar *p;
+ GfxColor color2;
+ int n, i;
+
+ n = base->getNComps();
+ p = &lookup[(int)(color->c[0] + 0.5) * n];
+ for (i = 0; i < n; ++i) {
+ color2.c[i] = p[i] / 255.0;
+ }
+ base->getCMYK(&color2, cmyk);
+}
+
+void GfxIndexedColorSpace::getDefaultRanges(double *decodeLow,
+ double *decodeRange,
+ int maxImgPixel) {
+ decodeLow[0] = 0;
+ decodeRange[0] = maxImgPixel;
+}
+
+//------------------------------------------------------------------------
+// GfxSeparationColorSpace
+//------------------------------------------------------------------------
+
+GfxSeparationColorSpace::GfxSeparationColorSpace(GString *nameA,
+ GfxColorSpace *altA,
+ Function *funcA) {
+ name = nameA;
+ alt = altA;
+ func = funcA;
+}
+
+GfxSeparationColorSpace::~GfxSeparationColorSpace() {
+ delete name;
+ delete alt;
+ delete func;
+}
+
+GfxColorSpace *GfxSeparationColorSpace::copy() {
+ return new GfxSeparationColorSpace(name->copy(), alt->copy(), func->copy());
+}
+
+//~ handle the 'All' and 'None' colorants
+GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr) {
+ GfxSeparationColorSpace *cs;
+ GString *nameA;
+ GfxColorSpace *altA;
+ Function *funcA;
+ Object obj1;
+
+ if (arr->getLength() != 4) {
+ error(-1, "Bad Separation color space");
+ goto err1;
+ }
+ if (!arr->get(1, &obj1)->isName()) {
+ error(-1, "Bad Separation color space (name)");
+ goto err2;
+ }
+ nameA = new GString(obj1.getName());
+ obj1.free();
+ arr->get(2, &obj1);
+ if (!(altA = GfxColorSpace::parse(&obj1))) {
+ error(-1, "Bad Separation color space (alternate color space)");
+ goto err3;
+ }
+ obj1.free();
+ arr->get(3, &obj1);
+ if (!(funcA = Function::parse(&obj1))) {
+ goto err4;
+ }
+ if (!funcA->isOk()) {
+ goto err5;
+ }
+ obj1.free();
+ cs = new GfxSeparationColorSpace(nameA, altA, funcA);
+ return cs;
+
+ err5:
+ delete funcA;
+ err4:
+ delete altA;
+ err3:
+ delete nameA;
+ err2:
+ obj1.free();
+ err1:
+ return NULL;
+}
+
+void GfxSeparationColorSpace::getGray(GfxColor *color, double *gray) {
+ GfxColor color2;
+
+ func->transform(color->c, color2.c);
+ alt->getGray(&color2, gray);
+}
+
+void GfxSeparationColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ GfxColor color2;
+
+ func->transform(color->c, color2.c);
+ alt->getRGB(&color2, rgb);
+}
+
+void GfxSeparationColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+ GfxColor color2;
+
+ func->transform(color->c, color2.c);
+ alt->getCMYK(&color2, cmyk);
+}
+
+//------------------------------------------------------------------------
+// GfxDeviceNColorSpace
+//------------------------------------------------------------------------
+
+GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA,
+ GfxColorSpace *altA,
+ Function *funcA) {
+ nComps = nCompsA;
+ alt = altA;
+ func = funcA;
+}
+
+GfxDeviceNColorSpace::~GfxDeviceNColorSpace() {
+ int i;
+
+ for (i = 0; i < nComps; ++i) {
+ delete names[i];
+ }
+ delete alt;
+ delete func;
+}
+
+GfxColorSpace *GfxDeviceNColorSpace::copy() {
+ GfxDeviceNColorSpace *cs;
+ int i;
+
+ cs = new GfxDeviceNColorSpace(nComps, alt->copy(), func->copy());
+ for (i = 0; i < nComps; ++i) {
+ cs->names[i] = names[i]->copy();
+ }
+ return cs;
+}
+
+//~ handle the 'None' colorant
+GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr) {
+ GfxDeviceNColorSpace *cs;
+ int nCompsA;
+ GString *namesA[gfxColorMaxComps];
+ GfxColorSpace *altA;
+ Function *funcA;
+ Object obj1, obj2;
+ int i;
+
+ if (arr->getLength() != 4 && arr->getLength() != 5) {
+ error(-1, "Bad DeviceN color space");
+ goto err1;
+ }
+ if (!arr->get(1, &obj1)->isArray()) {
+ error(-1, "Bad DeviceN color space (names)");
+ goto err2;
+ }
+ nCompsA = obj1.arrayGetLength();
+ for (i = 0; i < nCompsA; ++i) {
+ if (!obj1.arrayGet(i, &obj2)->isName()) {
+ error(-1, "Bad DeviceN color space (names)");
+ obj2.free();
+ goto err2;
+ }
+ namesA[i] = new GString(obj2.getName());
+ obj2.free();
+ }
+ obj1.free();
+ arr->get(2, &obj1);
+ if (!(altA = GfxColorSpace::parse(&obj1))) {
+ error(-1, "Bad DeviceN color space (alternate color space)");
+ goto err3;
+ }
+ obj1.free();
+ arr->get(3, &obj1);
+ if (!(funcA = Function::parse(&obj1))) {
+ goto err4;
+ }
+ if (!funcA->isOk()) {
+ goto err5;
+ }
+ obj1.free();
+ cs = new GfxDeviceNColorSpace(nCompsA, altA, funcA);
+ for (i = 0; i < nCompsA; ++i) {
+ cs->names[i] = namesA[i];
+ }
+ return cs;
+
+ err5:
+ delete funcA;
+ err4:
+ delete altA;
+ err3:
+ for (i = 0; i < nCompsA; ++i) {
+ delete namesA[i];
+ }
+ err2:
+ obj1.free();
+ err1:
+ return NULL;
+}
+
+void GfxDeviceNColorSpace::getGray(GfxColor *color, double *gray) {
+ GfxColor color2;
+
+ func->transform(color->c, color2.c);
+ alt->getGray(&color2, gray);
+}
+
+void GfxDeviceNColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ GfxColor color2;
+
+ func->transform(color->c, color2.c);
+ alt->getRGB(&color2, rgb);
+}
+
+void GfxDeviceNColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+ GfxColor color2;
+
+ func->transform(color->c, color2.c);
+ alt->getCMYK(&color2, cmyk);
+}
+
+//------------------------------------------------------------------------
+// GfxPatternColorSpace
+//------------------------------------------------------------------------
+
+GfxPatternColorSpace::GfxPatternColorSpace(GfxColorSpace *underA) {
+ under = underA;
+}
+
+GfxPatternColorSpace::~GfxPatternColorSpace() {
+ if (under) {
+ delete under;
+ }
+}
+
+GfxColorSpace *GfxPatternColorSpace::copy() {
+ return new GfxPatternColorSpace(under ? under->copy() :
+ (GfxColorSpace *)NULL);
+}
+
+GfxColorSpace *GfxPatternColorSpace::parse(Array *arr) {
+ GfxPatternColorSpace *cs;
+ GfxColorSpace *underA;
+ Object obj1;
+
+ if (arr->getLength() != 1 && arr->getLength() != 2) {
+ error(-1, "Bad Pattern color space");
+ return NULL;
+ }
+ underA = NULL;
+ if (arr->getLength() == 2) {
+ arr->get(1, &obj1);
+ if (!(underA = GfxColorSpace::parse(&obj1))) {
+ error(-1, "Bad Pattern color space (underlying color space)");
+ obj1.free();
+ return NULL;
+ }
+ obj1.free();
+ }
+ cs = new GfxPatternColorSpace(underA);
+ return cs;
+}
+
+void GfxPatternColorSpace::getGray(GfxColor *color, double *gray) {
+ *gray = 0;
+}
+
+void GfxPatternColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ rgb->r = rgb->g = rgb->b = 0;
+}
+
+void GfxPatternColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+ cmyk->c = cmyk->m = cmyk->y = 0;
+ cmyk->k = 1;
+}
+
+//------------------------------------------------------------------------
+// Pattern
+//------------------------------------------------------------------------
+
+GfxPattern::GfxPattern(int typeA) {
+ type = typeA;
+}
+
+GfxPattern::~GfxPattern() {
+}
+
+GfxPattern *GfxPattern::parse(Object *obj) {
+ GfxPattern *pattern;
+ Dict *dict;
+ Object obj1;
+
+ pattern = NULL;
+ if (obj->isStream()) {
+ dict = obj->streamGetDict();
+ dict->lookup("PatternType", &obj1);
+ if (obj1.isInt() && obj1.getInt() == 1) {
+ pattern = new GfxTilingPattern(dict, obj);
+ }
+ obj1.free();
+ }
+ return pattern;
+}
+
+//------------------------------------------------------------------------
+// GfxTilingPattern
+//------------------------------------------------------------------------
+
+GfxTilingPattern::GfxTilingPattern(Dict *streamDict, Object *stream):
+ GfxPattern(1)
+{
+ Object obj1, obj2;
+ int i;
+
+ if (streamDict->lookup("PaintType", &obj1)->isInt()) {
+ paintType = obj1.getInt();
+ } else {
+ paintType = 1;
+ error(-1, "Invalid or missing PaintType in pattern");
+ }
+ obj1.free();
+ if (streamDict->lookup("TilingType", &obj1)->isInt()) {
+ tilingType = obj1.getInt();
+ } else {
+ tilingType = 1;
+ error(-1, "Invalid or missing TilingType in pattern");
+ }
+ obj1.free();
+ bbox[0] = bbox[1] = 0;
+ bbox[2] = bbox[3] = 1;
+ if (streamDict->lookup("BBox", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 4) {
+ for (i = 0; i < 4; ++i) {
+ if (obj1.arrayGet(i, &obj2)->isNum()) {
+ bbox[i] = obj2.getNum();
+ }
+ obj2.free();
+ }
+ } else {
+ error(-1, "Invalid or missing BBox in pattern");
+ }
+ obj1.free();
+ if (streamDict->lookup("XStep", &obj1)->isNum()) {
+ xStep = obj1.getNum();
+ } else {
+ xStep = 1;
+ error(-1, "Invalid or missing XStep in pattern");
+ }
+ obj1.free();
+ if (streamDict->lookup("YStep", &obj1)->isNum()) {
+ yStep = obj1.getNum();
+ } else {
+ yStep = 1;
+ error(-1, "Invalid or missing YStep in pattern");
+ }
+ obj1.free();
+ if (!streamDict->lookup("Resources", &resDict)->isDict()) {
+ resDict.free();
+ resDict.initNull();
+ error(-1, "Invalid or missing Resources in pattern");
+ }
+ matrix[0] = 1; matrix[1] = 0;
+ matrix[2] = 0; matrix[3] = 1;
+ matrix[4] = 0; matrix[5] = 0;
+ if (streamDict->lookup("Matrix", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 6) {
+ for (i = 0; i < 6; ++i) {
+ if (obj1.arrayGet(i, &obj2)->isNum()) {
+ matrix[i] = obj2.getNum();
+ }
+ obj2.free();
+ }
+ }
+ obj1.free();
+ stream->copy(&contentStream);
+}
+
+GfxTilingPattern::~GfxTilingPattern() {
+ resDict.free();
+ contentStream.free();
+}
+
+GfxPattern *GfxTilingPattern::copy() {
+ return new GfxTilingPattern(this);
+}
+
+GfxTilingPattern::GfxTilingPattern(GfxTilingPattern *pat):
+ GfxPattern(1)
+{
+ memcpy(this, pat, sizeof(GfxTilingPattern));
+ pat->resDict.copy(&resDict);
+ pat->contentStream.copy(&contentStream);
+}
+
+//------------------------------------------------------------------------
+// GfxShading
+//------------------------------------------------------------------------
+
+GfxShading::GfxShading() {
+}
+
+GfxShading::~GfxShading() {
+ delete colorSpace;
+}
+
+GfxShading *GfxShading::parse(Object *obj) {
+ GfxShading *shading;
+ int typeA;
+ GfxColorSpace *colorSpaceA;
+ GfxColor backgroundA;
+ GBool hasBackgroundA;
+ double xMinA, yMinA, xMaxA, yMaxA;
+ GBool hasBBoxA;
+ Object obj1, obj2;
+ int i;
+
+ shading = NULL;
+ if (obj->isDict()) {
+
+ if (!obj->dictLookup("ShadingType", &obj1)->isInt()) {
+ error(-1, "Invalid ShadingType in shading dictionary");
+ obj1.free();
+ goto err1;
+ }
+ typeA = obj1.getInt();
+ obj1.free();
+ if (typeA < 2 || typeA > 3) {
+ error(-1, "Unimplemented shading type %d", typeA);
+ goto err1;
+ }
+
+ obj->dictLookup("ColorSpace", &obj1);
+ if (!(colorSpaceA = GfxColorSpace::parse(&obj1))) {
+ error(-1, "Bad color space in shading dictionary");
+ obj1.free();
+ goto err1;
+ }
+ obj1.free();
+
+ for (i = 0; i < gfxColorMaxComps; ++i) {
+ backgroundA.c[i] = 0;
+ }
+ hasBackgroundA = gFalse;
+ if (obj->dictLookup("Background", &obj1)->isArray()) {
+ if (obj1.arrayGetLength() == colorSpaceA->getNComps()) {
+ hasBackgroundA = gTrue;
+ for (i = 0; i < colorSpaceA->getNComps(); ++i) {
+ backgroundA.c[i] = obj1.arrayGet(i, &obj2)->getNum();
+ obj2.free();
+ }
+ } else {
+ error(-1, "Bad Background in shading dictionary");
+ }
+ }
+ obj1.free();
+
+ xMinA = yMinA = xMaxA = yMaxA = 0;
+ hasBBoxA = gFalse;
+ if (obj->dictLookup("BBox", &obj1)->isArray()) {
+ if (obj1.arrayGetLength() == 4) {
+ hasBBoxA = gTrue;
+ xMinA = obj1.arrayGet(0, &obj2)->getNum();
+ obj2.free();
+ yMinA = obj1.arrayGet(1, &obj2)->getNum();
+ obj2.free();
+ xMaxA = obj1.arrayGet(2, &obj2)->getNum();
+ obj2.free();
+ yMaxA = obj1.arrayGet(3, &obj2)->getNum();
+ obj2.free();
+ } else {
+ error(-1, "Bad BBox in shading dictionary");
+ }
+ }
+ obj1.free();
+
+ if (typeA == 2)
+ shading = GfxAxialShading::parse(obj->getDict());
+ else
+ shading = GfxRadialShading::parse(obj->getDict());
+
+ if (shading) {
+ shading->type = typeA;
+ shading->colorSpace = colorSpaceA;
+ shading->background = backgroundA;
+ shading->hasBackground = hasBackgroundA;
+ shading->xMin = xMinA;
+ shading->yMin = yMinA;
+ shading->xMax = xMaxA;
+ shading->yMax = yMaxA;
+ shading->hasBBox = hasBBoxA;
+ }
+ }
+
+ return shading;
+
+ err1:
+ return NULL;
+}
+
+//------------------------------------------------------------------------
+// GfxAxialShading
+//------------------------------------------------------------------------
+
+GfxAxialShading::GfxAxialShading(double x0A, double y0A,
+ double x1A, double y1A,
+ double t0A, double t1A,
+ Function **funcsA, int nFuncsA,
+ GBool extend0A, GBool extend1A) {
+ int i;
+
+ x0 = x0A;
+ y0 = y0A;
+ x1 = x1A;
+ y1 = y1A;
+ t0 = t0A;
+ t1 = t1A;
+ nFuncs = nFuncsA;
+ for (i = 0; i < nFuncs; ++i) {
+ funcs[i] = funcsA[i];
+ }
+ extend0 = extend0A;
+ extend1 = extend1A;
+}
+
+GfxAxialShading::~GfxAxialShading() {
+ int i;
+
+ for (i = 0; i < nFuncs; ++i) {
+ delete funcs[i];
+ }
+}
+
+GfxAxialShading *GfxAxialShading::parse(Dict *dict) {
+ double x0A, y0A, x1A, y1A;
+ double t0A, t1A;
+ Function *funcsA[gfxColorMaxComps];
+ int nFuncsA;
+ GBool extend0A, extend1A;
+ Object obj1, obj2;
+ int i;
+
+ x0A = y0A = x1A = y1A = 0;
+ if (dict->lookup("Coords", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 4) {
+ x0A = obj1.arrayGet(0, &obj2)->getNum();
+ obj2.free();
+ y0A = obj1.arrayGet(1, &obj2)->getNum();
+ obj2.free();
+ x1A = obj1.arrayGet(2, &obj2)->getNum();
+ obj2.free();
+ y1A = obj1.arrayGet(3, &obj2)->getNum();
+ obj2.free();
+ } else {
+ error(-1, "Missing or invalid Coords in shading dictionary");
+ goto err1;
+ }
+ obj1.free();
+
+ t0A = 0;
+ t1A = 1;
+ if (dict->lookup("Domain", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 2) {
+ t0A = obj1.arrayGet(0, &obj2)->getNum();
+ obj2.free();
+ t1A = obj1.arrayGet(1, &obj2)->getNum();
+ obj2.free();
+ }
+ obj1.free();
+
+ dict->lookup("Function", &obj1);
+ if (obj1.isArray()) {
+ nFuncsA = obj1.arrayGetLength();
+ for (i = 0; i < nFuncsA; ++i) {
+ obj1.arrayGet(i, &obj2);
+ if (!(funcsA[i] = Function::parse(&obj2))) {
+ obj1.free();
+ obj2.free();
+ goto err1;
+ }
+ obj2.free();
+ }
+ } else {
+ nFuncsA = 1;
+ if (!(funcsA[0] = Function::parse(&obj1))) {
+ obj1.free();
+ goto err1;
+ }
+ }
+ obj1.free();
+ for (i = 0; i < nFuncsA; ++i) {
+ if (!funcsA[i]->isOk()) {
+ goto err2;
+ }
+ }
+
+ extend0A = extend1A = gFalse;
+ if (dict->lookup("Extend", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 2) {
+ extend0A = obj1.arrayGet(0, &obj2)->getBool();
+ obj2.free();
+ extend1A = obj1.arrayGet(1, &obj2)->getBool();
+ obj2.free();
+ }
+ obj1.free();
+
+ return new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A,
+ funcsA, nFuncsA, extend0A, extend1A);
+
+ err2:
+ for (i = 0; i < nFuncsA; ++i) {
+ delete funcsA[i];
+ }
+ err1:
+ return NULL;
+}
+
+void GfxAxialShading::getColor(double t, GfxColor *color) {
+ int i;
+
+ for (i = 0; i < nFuncs; ++i) {
+ funcs[i]->transform(&t, &color->c[i]);
+ }
+}
+
+//------------------------------------------------------------------------
+// GfxRadialShading
+//------------------------------------------------------------------------
+
+GfxRadialShading::GfxRadialShading(double x0A, double y0A, double r0A,
+ double x1A, double y1A, double r1A,
+ double t0A, double t1A,
+ Function **funcsA, int nFuncsA,
+ GBool extend0A, GBool extend1A) {
+ int i;
+
+ x0 = x0A;
+ y0 = y0A;
+ x1 = x1A;
+ y1 = y1A;
+ r0 = r0A;
+ r1 = r1A;
+ t0 = t0A;
+ t1 = t1A;
+ nFuncs = nFuncsA;
+ for (i = 0; i < nFuncs; ++i) {
+ funcs[i] = funcsA[i];
+ }
+ extend0 = extend0A;
+ extend1 = extend1A;
+}
+
+GfxRadialShading::~GfxRadialShading() {
+ int i;
+
+ for (i = 0; i < nFuncs; ++i) {
+ delete funcs[i];
+ }
+}
+
+GfxRadialShading *GfxRadialShading::parse(Dict *dict) {
+ double x0A, y0A, x1A, y1A;
+ double r0A, r1A;
+ double t0A, t1A;
+ Function *funcsA[gfxColorMaxComps];
+ int nFuncsA;
+ GBool extend0A, extend1A;
+ Object obj1, obj2;
+ int i;
+
+ x0A = y0A = x1A = y1A = r0A = r1A = 0;
+ if (dict->lookup("Coords", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 6) {
+ x0A = obj1.arrayGet(0, &obj2)->getNum();
+ obj2.free();
+ y0A = obj1.arrayGet(1, &obj2)->getNum();
+ obj2.free();
+ r0A = obj1.arrayGet(2, &obj2)->getNum();
+ obj2.free();
+ x1A = obj1.arrayGet(3, &obj2)->getNum();
+ obj2.free();
+ y1A = obj1.arrayGet(4, &obj2)->getNum();
+ obj2.free();
+ r1A = obj1.arrayGet(5, &obj2)->getNum();
+ obj2.free();
+ } else {
+ error(-1, "Missing or invalid Coords in shading dictionary");
+ goto err1;
+ }
+ obj1.free();
+
+ t0A = 0;
+ t1A = 1;
+ if (dict->lookup("Domain", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 2) {
+ t0A = obj1.arrayGet(0, &obj2)->getNum();
+ obj2.free();
+ t1A = obj1.arrayGet(1, &obj2)->getNum();
+ obj2.free();
+ }
+ obj1.free();
+
+ dict->lookup("Function", &obj1);
+ if (obj1.isArray()) {
+ nFuncsA = obj1.arrayGetLength();
+ for (i = 0; i < nFuncsA; ++i) {
+ obj1.arrayGet(i, &obj2);
+ if (!(funcsA[i] = Function::parse(&obj2))) {
+ obj1.free();
+ obj2.free();
+ goto err1;
+ }
+ obj2.free();
+ }
+ } else {
+ nFuncsA = 1;
+ if (!(funcsA[0] = Function::parse(&obj1))) {
+ obj1.free();
+ goto err1;
+ }
+ }
+ obj1.free();
+ for (i = 0; i < nFuncsA; ++i) {
+ if (!funcsA[i]->isOk()) {
+ goto err2;
+ }
+ }
+
+ extend0A = extend1A = gFalse;
+ if (dict->lookup("Extend", &obj1)->isArray() &&
+ obj1.arrayGetLength() == 2) {
+ extend0A = obj1.arrayGet(0, &obj2)->getBool();
+ obj2.free();
+ extend1A = obj1.arrayGet(1, &obj2)->getBool();
+ obj2.free();
+ }
+ obj1.free();
+
+ return new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A,
+ funcsA, nFuncsA, extend0A, extend1A);
+
+ err2:
+ for (i = 0; i < nFuncsA; ++i) {
+ delete funcsA[i];
+ }
+ err1:
+ return NULL;
+}
+
+void GfxRadialShading::getColor(double t, GfxColor *color) {
+ int i;
+
+ for (i = 0; i < nFuncs; ++i) {
+ funcs[i]->transform(&t, &color->c[i]);
+ }
+}
+
+//------------------------------------------------------------------------
+// GfxImageColorMap
+//------------------------------------------------------------------------
+
+GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode,
+ GfxColorSpace *colorSpaceA) {
+ GfxIndexedColorSpace *indexedCS;
+ GfxSeparationColorSpace *sepCS;
+ int maxPixel, indexHigh;
+ Guchar *lookup2;
+ Function *sepFunc;
+ Object obj;
+ double x[gfxColorMaxComps];
+ double y[gfxColorMaxComps];
+ int i, j, k;
+
+ ok = gTrue;
+
+ // bits per component and color space
+ bits = bitsA;
+ maxPixel = (1 << bits) - 1;
+ colorSpace = colorSpaceA;
+
+ // get decode map
+ if (decode->isNull()) {
+ nComps = colorSpace->getNComps();
+ colorSpace->getDefaultRanges(decodeLow, decodeRange, maxPixel);
+ } else if (decode->isArray()) {
+ nComps = decode->arrayGetLength() / 2;
+ if (nComps != colorSpace->getNComps()) {
+ goto err1;
+ }
+ for (i = 0; i < nComps; ++i) {
+ decode->arrayGet(2*i, &obj);
+ if (!obj.isNum()) {
+ goto err2;
+ }
+ decodeLow[i] = obj.getNum();
+ obj.free();
+ decode->arrayGet(2*i+1, &obj);
+ if (!obj.isNum()) {
+ goto err2;
+ }
+ decodeRange[i] = obj.getNum() - decodeLow[i];
+ obj.free();
+ }
+ } else {
+ goto err1;
+ }
+
+#if 0 //~
+ // handle the case where fewer than 2^n palette entries of an n-bit
+ // indexed color space are populated (this happens, e.g., in files
+ // optimized by Distiller)
+ if (colorSpace->getMode() == csIndexed) {
+ i = ((GfxIndexedColorSpace *)colorSpace)->getIndexHigh();
+ if (i < maxPixel) {
+ maxPixel = i;
+ }
+ }
+#endif
+
+ // Construct a lookup table -- this stores pre-computed decoded
+ // values for each component, i.e., the result of applying the
+ // decode mapping to each possible image pixel component value.
+ //
+ // Optimization: for Indexed and Separation color spaces (which have
+ // only one component), we store color values in the lookup table
+ // rather than component values.
+ colorSpace2 = NULL;
+ nComps2 = 0;
+ if (colorSpace->getMode() == csIndexed) {
+ // Note that indexHigh may not be the same as maxPixel --
+ // Distiller will remove unused palette entries, resulting in
+ // indexHigh < maxPixel.
+ indexedCS = (GfxIndexedColorSpace *)colorSpace;
+ colorSpace2 = indexedCS->getBase();
+ indexHigh = indexedCS->getIndexHigh();
+ nComps2 = colorSpace2->getNComps();
+ lookup = (double *)gmalloc((indexHigh + 1) * nComps2 * sizeof(double));
+ lookup2 = indexedCS->getLookup();
+ for (i = 0; i <= indexHigh; ++i) {
+ j = (int)(decodeLow[0] +(i * decodeRange[0]) / maxPixel + 0.5);
+ for (k = 0; k < nComps2; ++k) {
+ lookup[i*nComps2 + k] = lookup2[i*nComps2 + k] / 255.0;
+ }
+ }
+ } else if (colorSpace->getMode() == csSeparation) {
+ sepCS = (GfxSeparationColorSpace *)colorSpace;
+ colorSpace2 = sepCS->getAlt();
+ nComps2 = colorSpace2->getNComps();
+ lookup = (double *)gmalloc((maxPixel + 1) * nComps2 * sizeof(double));
+ sepFunc = sepCS->getFunc();
+ for (i = 0; i <= maxPixel; ++i) {
+ x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel;
+ sepFunc->transform(x, y);
+ for (k = 0; k < nComps2; ++k) {
+ lookup[i*nComps2 + k] = y[k];
+ }
+ }
+ } else {
+ lookup = (double *)gmalloc((maxPixel + 1) * nComps * sizeof(double));
+ for (i = 0; i <= maxPixel; ++i) {
+ for (k = 0; k < nComps; ++k) {
+ lookup[i*nComps + k] = decodeLow[k] +
+ (i * decodeRange[k]) / maxPixel;
+ }
+ }
+ }
+
+ return;
+
+ err2:
+ obj.free();
+ err1:
+ ok = gFalse;
+}
+
+GfxImageColorMap::~GfxImageColorMap() {
+ delete colorSpace;
+ gfree(lookup);
+}
+
+void GfxImageColorMap::getGray(Guchar *x, double *gray) {
+ GfxColor color;
+ double *p;
+ int i;
+
+ if (colorSpace2) {
+ p = &lookup[x[0] * nComps2];
+ for (i = 0; i < nComps2; ++i) {
+ color.c[i] = *p++;
+ }
+ colorSpace2->getGray(&color, gray);
+ } else {
+ for (i = 0; i < nComps; ++i) {
+ color.c[i] = lookup[x[i] * nComps + i];
+ }
+ colorSpace->getGray(&color, gray);
+ }
+}
+
+void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) {
+ GfxColor color;
+ double *p;
+ int i;
+
+ if (colorSpace2) {
+ p = &lookup[x[0] * nComps2];
+ for (i = 0; i < nComps2; ++i) {
+ color.c[i] = *p++;
+ }
+ colorSpace2->getRGB(&color, rgb);
+ } else {
+ for (i = 0; i < nComps; ++i) {
+ color.c[i] = lookup[x[i] * nComps + i];
+ }
+ colorSpace->getRGB(&color, rgb);
+ }
+}
+
+void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) {
+ GfxColor color;
+ double *p;
+ int i;
+
+ if (colorSpace2) {
+ p = &lookup[x[0] * nComps2];
+ for (i = 0; i < nComps2; ++i) {
+ color.c[i] = *p++;
+ }
+ colorSpace2->getCMYK(&color, cmyk);
+ } else {
+ for (i = 0; i < nComps; ++i) {
+ color.c[i] = lookup[x[i] * nComps + i];
+ }
+ colorSpace->getCMYK(&color, cmyk);
+ }
+}
+
+//------------------------------------------------------------------------
+// GfxSubpath and GfxPath
+//------------------------------------------------------------------------
+
+GfxSubpath::GfxSubpath(double x1, double y1) {
+ size = 16;
+ x = (double *)gmalloc(size * sizeof(double));
+ y = (double *)gmalloc(size * sizeof(double));
+ curve = (GBool *)gmalloc(size * sizeof(GBool));
+ n = 1;
+ x[0] = x1;
+ y[0] = y1;
+ curve[0] = gFalse;
+ closed = gFalse;
+}
+
+GfxSubpath::~GfxSubpath() {
+ gfree(x);
+ gfree(y);
+ gfree(curve);
+}
+
+// Used for copy().
+GfxSubpath::GfxSubpath(GfxSubpath *subpath) {
+ size = subpath->size;
+ n = subpath->n;
+ x = (double *)gmalloc(size * sizeof(double));
+ y = (double *)gmalloc(size * sizeof(double));
+ curve = (GBool *)gmalloc(size * sizeof(GBool));
+ memcpy(x, subpath->x, n * sizeof(double));
+ memcpy(y, subpath->y, n * sizeof(double));
+ memcpy(curve, subpath->curve, n * sizeof(GBool));
+ closed = subpath->closed;
+}
+
+void GfxSubpath::lineTo(double x1, double y1) {
+ if (n >= size) {
+ size += 16;
+ x = (double *)grealloc(x, size * sizeof(double));
+ y = (double *)grealloc(y, size * sizeof(double));
+ curve = (GBool *)grealloc(curve, size * sizeof(GBool));
+ }
+ x[n] = x1;
+ y[n] = y1;
+ curve[n] = gFalse;
+ ++n;
+}
+
+void GfxSubpath::curveTo(double x1, double y1, double x2, double y2,
+ double x3, double y3) {
+ if (n+3 > size) {
+ size += 16;
+ x = (double *)grealloc(x, size * sizeof(double));
+ y = (double *)grealloc(y, size * sizeof(double));
+ curve = (GBool *)grealloc(curve, size * sizeof(GBool));
+ }
+ x[n] = x1;
+ y[n] = y1;
+ x[n+1] = x2;
+ y[n+1] = y2;
+ x[n+2] = x3;
+ y[n+2] = y3;
+ curve[n] = curve[n+1] = gTrue;
+ curve[n+2] = gFalse;
+ n += 3;
+}
+
+void GfxSubpath::close() {
+ if (x[n-1] != x[0] || y[n-1] != y[0]) {
+ lineTo(x[0], y[0]);
+ }
+ closed = gTrue;
+}
+
+GfxPath::GfxPath() {
+ justMoved = gFalse;
+ size = 16;
+ n = 0;
+ firstX = firstY = 0;
+ subpaths = (GfxSubpath **)gmalloc(size * sizeof(GfxSubpath *));
+}
+
+GfxPath::~GfxPath() {
+ int i;
+
+ for (i = 0; i < n; ++i)
+ delete subpaths[i];
+ gfree(subpaths);
+}
+
+// Used for copy().
+GfxPath::GfxPath(GBool justMoved1, double firstX1, double firstY1,
+ GfxSubpath **subpaths1, int n1, int size1) {
+ int i;
+
+ justMoved = justMoved1;
+ firstX = firstX1;
+ firstY = firstY1;
+ size = size1;
+ n = n1;
+ subpaths = (GfxSubpath **)gmalloc(size * sizeof(GfxSubpath *));
+ for (i = 0; i < n; ++i)
+ subpaths[i] = subpaths1[i]->copy();
+}
+
+void GfxPath::moveTo(double x, double y) {
+ justMoved = gTrue;
+ firstX = x;
+ firstY = y;
+}
+
+void GfxPath::lineTo(double x, double y) {
+ if (justMoved) {
+ if (n >= size) {
+ size += 16;
+ subpaths = (GfxSubpath **)
+ grealloc(subpaths, size * sizeof(GfxSubpath *));
+ }
+ subpaths[n] = new GfxSubpath(firstX, firstY);
+ ++n;
+ justMoved = gFalse;
+ }
+ subpaths[n-1]->lineTo(x, y);
+}
+
+void GfxPath::curveTo(double x1, double y1, double x2, double y2,
+ double x3, double y3) {
+ if (justMoved) {
+ if (n >= size) {
+ size += 16;
+ subpaths = (GfxSubpath **)
+ grealloc(subpaths, size * sizeof(GfxSubpath *));
+ }
+ subpaths[n] = new GfxSubpath(firstX, firstY);
+ ++n;
+ justMoved = gFalse;
+ }
+ subpaths[n-1]->curveTo(x1, y1, x2, y2, x3, y3);
+}
+
+
+//------------------------------------------------------------------------
+// GfxState
+//------------------------------------------------------------------------
+
+GfxState::GfxState(double dpi, PDFRectangle *pageBox, int rotate,
+ GBool upsideDown) {
+ double k;
+
+ px1 = pageBox->x1;
+ py1 = pageBox->y1;
+ px2 = pageBox->x2;
+ py2 = pageBox->y2;
+ k = dpi / 72.0;
+ if (rotate == 90) {
+ ctm[0] = 0;
+ ctm[1] = upsideDown ? k : -k;
+ ctm[2] = k;
+ ctm[3] = 0;
+ ctm[4] = -k * py1;
+ ctm[5] = k * (upsideDown ? -px1 : px2);
+ pageWidth = k * (py2 - py1);
+ pageHeight = k * (px2 - px1);
+ } else if (rotate == 180) {
+ ctm[0] = -k;
+ ctm[1] = 0;
+ ctm[2] = 0;
+ ctm[3] = upsideDown ? k : -k;
+ ctm[4] = k * px2;
+ ctm[5] = k * (upsideDown ? -py1 : py2);
+ pageWidth = k * (px2 - px1);
+ pageHeight = k * (py2 - py1);
+ } else if (rotate == 270) {
+ ctm[0] = 0;
+ ctm[1] = upsideDown ? -k : k;
+ ctm[2] = -k;
+ ctm[3] = 0;
+ ctm[4] = k * py2;
+ ctm[5] = k * (upsideDown ? px2 : -px1);
+ pageWidth = k * (py2 - py1);
+ pageHeight = k * (px2 - px1);
+ } else {
+ ctm[0] = k;
+ ctm[1] = 0;
+ ctm[2] = 0;
+ ctm[3] = upsideDown ? -k : k;
+ ctm[4] = -k * px1;
+ ctm[5] = k * (upsideDown ? py2 : -py1);
+ pageWidth = k * (px2 - px1);
+ pageHeight = k * (py2 - py1);
+ }
+
+ fillColorSpace = new GfxDeviceGrayColorSpace();
+ strokeColorSpace = new GfxDeviceGrayColorSpace();
+ fillColor.c[0] = 0;
+ strokeColor.c[0] = 0;
+ fillPattern = NULL;
+ strokePattern = NULL;
+ fillOpacity = 1;
+ strokeOpacity = 1;
+
+ lineWidth = 1;
+ lineDash = NULL;
+ lineDashLength = 0;
+ lineDashStart = 0;
+ flatness = 0;
+ lineJoin = 0;
+ lineCap = 0;
+ miterLimit = 10;
+
+ font = NULL;
+ fontSize = 0;
+ textMat[0] = 1; textMat[1] = 0;
+ textMat[2] = 0; textMat[3] = 1;
+ textMat[4] = 0; textMat[5] = 0;
+ charSpace = 0;
+ wordSpace = 0;
+ horizScaling = 1;
+ leading = 0;
+ rise = 0;
+ render = 0;
+
+ path = new GfxPath();
+ curX = curY = 0;
+ lineX = lineY = 0;
+
+ clipXMin = 0;
+ clipYMin = 0;
+ clipXMax = pageWidth;
+ clipYMax = pageHeight;
+
+ saved = NULL;
+}
+
+GfxState::~GfxState() {
+ if (fillColorSpace) {
+ delete fillColorSpace;
+ }
+ if (strokeColorSpace) {
+ delete strokeColorSpace;
+ }
+ if (fillPattern) {
+ delete fillPattern;
+ }
+ if (strokePattern) {
+ delete strokePattern;
+ }
+ gfree(lineDash);
+ delete path;
+ if (saved) {
+ delete saved;
+ }
+}
+
+// Used for copy();
+GfxState::GfxState(GfxState *state) {
+ memcpy(this, state, sizeof(GfxState));
+ if (fillColorSpace) {
+ fillColorSpace = state->fillColorSpace->copy();
+ }
+ if (strokeColorSpace) {
+ strokeColorSpace = state->strokeColorSpace->copy();
+ }
+ if (fillPattern) {
+ fillPattern = state->fillPattern->copy();
+ }
+ if (strokePattern) {
+ strokePattern = state->strokePattern->copy();
+ }
+ if (lineDashLength > 0) {
+ lineDash = (double *)gmalloc(lineDashLength * sizeof(double));
+ memcpy(lineDash, state->lineDash, lineDashLength * sizeof(double));
+ }
+ path = state->path->copy();
+ saved = NULL;
+}
+
+double GfxState::transformWidth(double w) {
+ double x, y;
+
+ x = ctm[0] + ctm[2];
+ y = ctm[1] + ctm[3];
+ return w * sqrt(0.5 * (x * x + y * y));
+}
+
+double GfxState::getTransformedFontSize() {
+ double x1, y1, x2, y2;
+
+ x1 = textMat[2] * fontSize;
+ y1 = textMat[3] * fontSize;
+ x2 = ctm[0] * x1 + ctm[2] * y1;
+ y2 = ctm[1] * x1 + ctm[3] * y1;
+ return sqrt(x2 * x2 + y2 * y2);
+}
+
+void GfxState::getFontTransMat(double *m11, double *m12,
+ double *m21, double *m22) {
+ *m11 = (textMat[0] * ctm[0] + textMat[1] * ctm[2]) * fontSize;
+ *m12 = (textMat[0] * ctm[1] + textMat[1] * ctm[3]) * fontSize;
+ *m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize;
+ *m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize;
+}
+
+void GfxState::setCTM(double a, double b, double c,
+ double d, double e, double f) {
+ ctm[0] = a;
+ ctm[1] = b;
+ ctm[2] = c;
+ ctm[3] = d;
+ ctm[4] = e;
+ ctm[5] = f;
+}
+
+void GfxState::concatCTM(double a, double b, double c,
+ double d, double e, double f) {
+ double a1 = ctm[0];
+ double b1 = ctm[1];
+ double c1 = ctm[2];
+ double d1 = ctm[3];
+
+ ctm[0] = a * a1 + b * c1;
+ ctm[1] = a * b1 + b * d1;
+ ctm[2] = c * a1 + d * c1;
+ ctm[3] = c * b1 + d * d1;
+ ctm[4] = e * a1 + f * c1 + ctm[4];
+ ctm[5] = e * b1 + f * d1 + ctm[5];
+}
+
+void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) {
+ if (fillColorSpace) {
+ delete fillColorSpace;
+ }
+ fillColorSpace = colorSpace;
+}
+
+void GfxState::setStrokeColorSpace(GfxColorSpace *colorSpace) {
+ if (strokeColorSpace) {
+ delete strokeColorSpace;
+ }
+ strokeColorSpace = colorSpace;
+}
+
+void GfxState::setFillPattern(GfxPattern *pattern) {
+ if (fillPattern) {
+ delete fillPattern;
+ }
+ fillPattern = pattern;
+}
+
+void GfxState::setStrokePattern(GfxPattern *pattern) {
+ if (strokePattern) {
+ delete strokePattern;
+ }
+ strokePattern = pattern;
+}
+
+void GfxState::setLineDash(double *dash, int length, double start) {
+ if (lineDash)
+ gfree(lineDash);
+ lineDash = dash;
+ lineDashLength = length;
+ lineDashStart = start;
+}
+
+void GfxState::clearPath() {
+ delete path;
+ path = new GfxPath();
+}
+
+void GfxState::clip() {
+ double xMin, yMin, xMax, yMax, x, y;
+ GfxSubpath *subpath;
+ int i, j;
+
+ xMin = xMax = yMin = yMax = 0; // make gcc happy
+ for (i = 0; i < path->getNumSubpaths(); ++i) {
+ subpath = path->getSubpath(i);
+ for (j = 0; j < subpath->getNumPoints(); ++j) {
+ transform(subpath->getX(j), subpath->getY(j), &x, &y);
+ if (i == 0 && j == 0) {
+ xMin = xMax = x;
+ yMin = yMax = y;
+ } else {
+ if (x < xMin) {
+ xMin = x;
+ } else if (x > xMax) {
+ xMax = x;
+ }
+ if (y < yMin) {
+ yMin = y;
+ } else if (y > yMax) {
+ yMax = y;
+ }
+ }
+ }
+ }
+ if (xMin > clipXMin) {
+ clipXMin = xMin;
+ }
+ if (yMin > clipYMin) {
+ clipYMin = yMin;
+ }
+ if (xMax < clipXMax) {
+ clipXMax = xMax;
+ }
+ if (yMax < clipYMax) {
+ clipYMax = yMax;
+ }
+}
+
+void GfxState::textShift(double tx) {
+ double dx, dy;
+
+ textTransformDelta(tx, 0, &dx, &dy);
+ curX += dx;
+ curY += dy;
+}
+
+void GfxState::textShift(double tx, double ty) {
+ double dx, dy;
+
+ textTransformDelta(tx, ty, &dx, &dy);
+ curX += dx;
+ curY += dy;
+}
+
+GfxState *GfxState::save() {
+ GfxState *newState;
+
+ newState = copy();
+ newState->saved = this;
+ return newState;
+}
+
+GfxState *GfxState::restore() {
+ GfxState *oldState;
+
+ if (saved) {
+ oldState = saved;
+ saved = NULL;
+ delete this;
+ } else {
+ oldState = this;
+ }
+ return oldState;
+}
diff --git a/pdftops/GfxState.h b/pdftops/GfxState.h
new file mode 100644
index 000000000..4e5941cc2
--- /dev/null
+++ b/pdftops/GfxState.h
@@ -0,0 +1,958 @@
+//========================================================================
+//
+// GfxState.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef GFXSTATE_H
+#define GFXSTATE_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "gtypes.h"
+#include "Object.h"
+#include "Function.h"
+
+class Array;
+class GfxFont;
+struct PDFRectangle;
+
+//------------------------------------------------------------------------
+// GfxColor
+//------------------------------------------------------------------------
+
+#define gfxColorMaxComps funcMaxOutputs
+
+struct GfxColor {
+ double c[gfxColorMaxComps];
+};
+
+//------------------------------------------------------------------------
+// GfxRGB
+//------------------------------------------------------------------------
+
+struct GfxRGB {
+ double r, g, b;
+};
+
+//------------------------------------------------------------------------
+// GfxCMYK
+//------------------------------------------------------------------------
+
+struct GfxCMYK {
+ double c, m, y, k;
+};
+
+//------------------------------------------------------------------------
+// GfxColorSpace
+//------------------------------------------------------------------------
+
+enum GfxColorSpaceMode {
+ csDeviceGray,
+ csCalGray,
+ csDeviceRGB,
+ csCalRGB,
+ csDeviceCMYK,
+ csLab,
+ csICCBased,
+ csIndexed,
+ csSeparation,
+ csDeviceN,
+ csPattern
+};
+
+class GfxColorSpace {
+public:
+
+ GfxColorSpace();
+ virtual ~GfxColorSpace();
+ virtual GfxColorSpace *copy() = 0;
+ virtual GfxColorSpaceMode getMode() = 0;
+
+ // Construct a color space. Returns NULL if unsuccessful.
+ static GfxColorSpace *parse(Object *csObj);
+
+ // Convert to gray, RGB, or CMYK.
+ virtual void getGray(GfxColor *color, double *gray) = 0;
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0;
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0;
+
+ // Return the number of color components.
+ virtual int getNComps() = 0;
+
+ // Return the default ranges for each component, assuming an image
+ // with a max pixel value of <maxImgPixel>.
+ virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
+ int maxImgPixel);
+
+private:
+};
+
+//------------------------------------------------------------------------
+// GfxDeviceGrayColorSpace
+//------------------------------------------------------------------------
+
+class GfxDeviceGrayColorSpace: public GfxColorSpace {
+public:
+
+ GfxDeviceGrayColorSpace();
+ virtual ~GfxDeviceGrayColorSpace();
+ virtual GfxColorSpace *copy();
+ virtual GfxColorSpaceMode getMode() { return csDeviceGray; }
+
+ virtual void getGray(GfxColor *color, double *gray);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+ virtual int getNComps() { return 1; }
+
+private:
+};
+
+//------------------------------------------------------------------------
+// GfxCalGrayColorSpace
+//------------------------------------------------------------------------
+
+class GfxCalGrayColorSpace: public GfxColorSpace {
+public:
+
+ GfxCalGrayColorSpace();
+ virtual ~GfxCalGrayColorSpace();
+ virtual GfxColorSpace *copy();
+ virtual GfxColorSpaceMode getMode() { return csCalGray; }
+
+ // Construct a CalGray color space. Returns NULL if unsuccessful.
+ static GfxColorSpace *parse(Array *arr);
+
+ virtual void getGray(GfxColor *color, double *gray);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+ virtual int getNComps() { return 1; }
+
+ // CalGray-specific access.
+ double getWhiteX() { return whiteX; }
+ double getWhiteY() { return whiteY; }
+ double getWhiteZ() { return whiteZ; }
+ double getBlackX() { return blackX; }
+ double getBlackY() { return blackY; }
+ double getBlackZ() { return blackZ; }
+ double getGamma() { return gamma; }
+
+private:
+
+ double whiteX, whiteY, whiteZ; // white point
+ double blackX, blackY, blackZ; // black point
+ double gamma; // gamma value
+};
+
+//------------------------------------------------------------------------
+// GfxDeviceRGBColorSpace
+//------------------------------------------------------------------------
+
+class GfxDeviceRGBColorSpace: public GfxColorSpace {
+public:
+
+ GfxDeviceRGBColorSpace();
+ virtual ~GfxDeviceRGBColorSpace();
+ virtual GfxColorSpace *copy();
+ virtual GfxColorSpaceMode getMode() { return csDeviceRGB; }
+
+ virtual void getGray(GfxColor *color, double *gray);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+ virtual int getNComps() { return 3; }
+
+private:
+};
+
+//------------------------------------------------------------------------
+// GfxCalRGBColorSpace
+//------------------------------------------------------------------------
+
+class GfxCalRGBColorSpace: public GfxColorSpace {
+public:
+
+ GfxCalRGBColorSpace();
+ virtual ~GfxCalRGBColorSpace();
+ virtual GfxColorSpace *copy();
+ virtual GfxColorSpaceMode getMode() { return csCalRGB; }
+
+ // Construct a CalRGB color space. Returns NULL if unsuccessful.
+ static GfxColorSpace *parse(Array *arr);
+
+ virtual void getGray(GfxColor *color, double *gray);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+ virtual int getNComps() { return 3; }
+
+ // CalRGB-specific access.
+ double getWhiteX() { return whiteX; }
+ double getWhiteY() { return whiteY; }
+ double getWhiteZ() { return whiteZ; }
+ double getBlackX() { return blackX; }
+ double getBlackY() { return blackY; }
+ double getBlackZ() { return blackZ; }
+ double getGammaR() { return gammaR; }
+ double getGammaG() { return gammaG; }
+ double getGammaB() { return gammaB; }
+ double *getMatrix() { return mat; }
+
+private:
+
+ double whiteX, whiteY, whiteZ; // white point
+ double blackX, blackY, blackZ; // black point
+ double gammaR, gammaG, gammaB; // gamma values
+ double mat[9]; // ABC -> XYZ transform matrix
+};
+
+//------------------------------------------------------------------------
+// GfxDeviceCMYKColorSpace
+//------------------------------------------------------------------------
+
+class GfxDeviceCMYKColorSpace: public GfxColorSpace {
+public:
+
+ GfxDeviceCMYKColorSpace();
+ virtual ~GfxDeviceCMYKColorSpace();
+ virtual GfxColorSpace *copy();
+ virtual GfxColorSpaceMode getMode() { return csDeviceCMYK; }
+
+ virtual void getGray(GfxColor *color, double *gray);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+ virtual int getNComps() { return 4; }
+
+private:
+};
+
+//------------------------------------------------------------------------
+// GfxLabColorSpace
+//------------------------------------------------------------------------
+
+class GfxLabColorSpace: public GfxColorSpace {
+public:
+
+ GfxLabColorSpace();
+ virtual ~GfxLabColorSpace();
+ virtual GfxColorSpace *copy();
+ virtual GfxColorSpaceMode getMode() { return csLab; }
+
+ // Construct a Lab color space. Returns NULL if unsuccessful.
+ static GfxColorSpace *parse(Array *arr);
+
+ virtual void getGray(GfxColor *color, double *gray);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+ virtual int getNComps() { return 3; }
+
+ virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
+ int maxImgPixel);
+
+ // Lab-specific access.
+ double getWhiteX() { return whiteX; }
+ double getWhiteY() { return whiteY; }
+ double getWhiteZ() { return whiteZ; }
+ double getBlackX() { return blackX; }
+ double getBlackY() { return blackY; }
+ double getBlackZ() { return blackZ; }
+ double getAMin() { return aMin; }
+ double getAMax() { return aMax; }
+ double getBMin() { return bMin; }
+ double getBMax() { return bMax; }
+
+private:
+
+ double whiteX, whiteY, whiteZ; // white point
+ double blackX, blackY, blackZ; // black point
+ double aMin, aMax, bMin, bMax; // range for the a and b components
+ double kr, kg, kb; // gamut mapping mulitpliers
+};
+
+//------------------------------------------------------------------------
+// GfxICCBasedColorSpace
+//------------------------------------------------------------------------
+
+class GfxICCBasedColorSpace: public GfxColorSpace {
+public:
+
+ GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
+ Ref *iccProfileStreamA);
+ virtual ~GfxICCBasedColorSpace();
+ virtual GfxColorSpace *copy();
+ virtual GfxColorSpaceMode getMode() { return csICCBased; }
+
+ // Construct an ICCBased color space. Returns NULL if unsuccessful.
+ static GfxColorSpace *parse(Array *arr);
+
+ virtual void getGray(GfxColor *color, double *gray);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+ virtual int getNComps() { return nComps; }
+
+ virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
+ int maxImgPixel);
+
+ // ICCBased-specific access.
+ GfxColorSpace *getAlt() { return alt; }
+
+private:
+
+ int nComps; // number of color components (1, 3, or 4)
+ GfxColorSpace *alt; // alternate color space
+ double rangeMin[4]; // min values for each component
+ double rangeMax[4]; // max values for each component
+ Ref iccProfileStream; // the ICC profile
+};
+
+//------------------------------------------------------------------------
+// GfxIndexedColorSpace
+//------------------------------------------------------------------------
+
+class GfxIndexedColorSpace: public GfxColorSpace {
+public:
+
+ GfxIndexedColorSpace(GfxColorSpace *baseA, int indexHighA);
+ virtual ~GfxIndexedColorSpace();
+ virtual GfxColorSpace *copy();
+ virtual GfxColorSpaceMode getMode() { return csIndexed; }
+
+ // Construct a Lab color space. Returns NULL if unsuccessful.
+ static GfxColorSpace *parse(Array *arr);
+
+ virtual void getGray(GfxColor *color, double *gray);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+ virtual int getNComps() { return 1; }
+
+ virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
+ int maxImgPixel);
+
+ // Indexed-specific access.
+ GfxColorSpace *getBase() { return base; }
+ int getIndexHigh() { return indexHigh; }
+ Guchar *getLookup() { return lookup; }
+
+private:
+
+ GfxColorSpace *base; // base color space
+ int indexHigh; // max pixel value
+ Guchar *lookup; // lookup table
+};
+
+//------------------------------------------------------------------------
+// GfxSeparationColorSpace
+//------------------------------------------------------------------------
+
+class GfxSeparationColorSpace: public GfxColorSpace {
+public:
+
+ GfxSeparationColorSpace(GString *nameA, GfxColorSpace *altA,
+ Function *funcA);
+ virtual ~GfxSeparationColorSpace();
+ virtual GfxColorSpace *copy();
+ virtual GfxColorSpaceMode getMode() { return csSeparation; }
+
+ // Construct a Separation color space. Returns NULL if unsuccessful.
+ static GfxColorSpace *parse(Array *arr);
+
+ virtual void getGray(GfxColor *color, double *gray);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+ virtual int getNComps() { return 1; }
+
+ // Separation-specific access.
+ GString *getName() { return name; }
+ GfxColorSpace *getAlt() { return alt; }
+ Function *getFunc() { return func; }
+
+private:
+
+ GString *name; // colorant name
+ GfxColorSpace *alt; // alternate color space
+ Function *func; // tint transform (into alternate color space)
+};
+
+//------------------------------------------------------------------------
+// GfxDeviceNColorSpace
+//------------------------------------------------------------------------
+
+class GfxDeviceNColorSpace: public GfxColorSpace {
+public:
+
+ GfxDeviceNColorSpace(int nComps, GfxColorSpace *alt, Function *func);
+ virtual ~GfxDeviceNColorSpace();
+ virtual GfxColorSpace *copy();
+ virtual GfxColorSpaceMode getMode() { return csDeviceN; }
+
+ // Construct a DeviceN color space. Returns NULL if unsuccessful.
+ static GfxColorSpace *parse(Array *arr);
+
+ virtual void getGray(GfxColor *color, double *gray);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+ virtual int getNComps() { return nComps; }
+
+ // DeviceN-specific access.
+ GfxColorSpace *getAlt() { return alt; }
+
+private:
+
+ int nComps; // number of components
+ GString // colorant names
+ *names[gfxColorMaxComps];
+ GfxColorSpace *alt; // alternate color space
+ Function *func; // tint transform (into alternate color space)
+
+};
+
+//------------------------------------------------------------------------
+// GfxPatternColorSpace
+//------------------------------------------------------------------------
+
+class GfxPatternColorSpace: public GfxColorSpace {
+public:
+
+ GfxPatternColorSpace(GfxColorSpace *underA);
+ virtual ~GfxPatternColorSpace();
+ virtual GfxColorSpace *copy();
+ virtual GfxColorSpaceMode getMode() { return csPattern; }
+
+ // Construct a Pattern color space. Returns NULL if unsuccessful.
+ static GfxColorSpace *parse(Array *arr);
+
+ virtual void getGray(GfxColor *color, double *gray);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+ virtual int getNComps() { return 0; }
+
+ // Pattern-specific access.
+ GfxColorSpace *getUnder() { return under; }
+
+private:
+
+ GfxColorSpace *under; // underlying color space (for uncolored
+ // patterns)
+};
+
+//------------------------------------------------------------------------
+// GfxPattern
+//------------------------------------------------------------------------
+
+class GfxPattern {
+public:
+
+ GfxPattern(int typeA);
+ virtual ~GfxPattern();
+
+ static GfxPattern *parse(Object *obj);
+
+ virtual GfxPattern *copy() = 0;
+
+ int getType() { return type; }
+
+private:
+
+ int type;
+};
+
+//------------------------------------------------------------------------
+// GfxTilingPattern
+//------------------------------------------------------------------------
+
+class GfxTilingPattern: public GfxPattern {
+public:
+
+ GfxTilingPattern(Dict *streamDict, Object *stream);
+ virtual ~GfxTilingPattern();
+
+ virtual GfxPattern *copy();
+
+ int getPaintType() { return paintType; }
+ int getTilingType() { return tilingType; }
+ double *getBBox() { return bbox; }
+ double getXStep() { return xStep; }
+ double getYStep() { return yStep; }
+ Dict *getResDict()
+ { return resDict.isDict() ? resDict.getDict() : (Dict *)NULL; }
+ double *getMatrix() { return matrix; }
+ Object *getContentStream() { return &contentStream; }
+
+private:
+
+ GfxTilingPattern(GfxTilingPattern *pat);
+
+ int paintType;
+ int tilingType;
+ double bbox[4];
+ double xStep, yStep;
+ Object resDict;
+ double matrix[6];
+ Object contentStream;
+};
+
+//------------------------------------------------------------------------
+// GfxShading
+//------------------------------------------------------------------------
+
+class GfxShading {
+public:
+
+ GfxShading();
+ virtual ~GfxShading();
+
+ static GfxShading *parse(Object *obj);
+
+ int getType() { return type; }
+ GfxColorSpace *getColorSpace() { return colorSpace; }
+ GfxColor *getBackground() { return &background; }
+ GBool getHasBackground() { return hasBackground; }
+ void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA)
+ { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
+ GBool getHasBBox() { return hasBBox; }
+
+private:
+
+ int type;
+ GfxColorSpace *colorSpace;
+ GfxColor background;
+ GBool hasBackground;
+ double xMin, yMin, xMax, yMax;
+ GBool hasBBox;
+};
+
+//------------------------------------------------------------------------
+// GfxAxialShading
+//------------------------------------------------------------------------
+
+class GfxAxialShading: public GfxShading {
+public:
+
+ GfxAxialShading(double x0A, double y0A,
+ double x1A, double y1A,
+ double t0A, double t1A,
+ Function **funcsA, int nFuncsA,
+ GBool extend0A, GBool extend1A);
+ virtual ~GfxAxialShading();
+
+ static GfxAxialShading *parse(Dict *dict);
+
+ void getCoords(double *x0A, double *y0A, double *x1A, double *y1A)
+ { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
+ double getDomain0() { return t0; }
+ double getDomain1() { return t1; }
+ void getColor(double t, GfxColor *color);
+ GBool getExtend0() { return extend0; }
+ GBool getExtend1() { return extend1; }
+
+private:
+
+ double x0, y0, x1, y1;
+ double t0, t1;
+ Function *funcs[gfxColorMaxComps];
+ int nFuncs;
+ GBool extend0, extend1;
+};
+
+//------------------------------------------------------------------------
+// GfxRadialShading
+//------------------------------------------------------------------------
+
+class GfxRadialShading: public GfxShading {
+public:
+
+ GfxRadialShading(double x0A, double y0A, double r0A,
+ double x1A, double y1A, double r1A,
+ double t0A, double t1A,
+ Function **funcsA, int nFuncsA,
+ GBool extend0A, GBool extend1A);
+ virtual ~GfxRadialShading();
+
+ static GfxRadialShading *parse(Dict *dict);
+
+ void getCoords(double *x0A, double *y0A, double *x1A, double *y1A)
+ { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
+ void getRadii(double *r0A, double *r1A)
+ { *r0A = r0; *r1A = r1; }
+ double getDomain0() { return t0; }
+ double getDomain1() { return t1; }
+ void getColor(double t, GfxColor *color);
+ GBool getExtend0() { return extend0; }
+ GBool getExtend1() { return extend1; }
+
+private:
+
+ double x0, y0, x1, y1;
+ double r0, r1;
+ double t0, t1;
+ Function *funcs[gfxColorMaxComps];
+ int nFuncs;
+ GBool extend0, extend1;
+};
+
+//------------------------------------------------------------------------
+// GfxImageColorMap
+//------------------------------------------------------------------------
+
+class GfxImageColorMap {
+public:
+
+ // Constructor.
+ GfxImageColorMap(int bitsA, Object *decode, GfxColorSpace *colorSpaceA);
+
+ // Destructor.
+ ~GfxImageColorMap();
+
+ // Is color map valid?
+ GBool isOk() { return ok; }
+
+ // Get the color space.
+ GfxColorSpace *getColorSpace() { return colorSpace; }
+
+ // Get stream decoding info.
+ int getNumPixelComps() { return nComps; }
+ int getBits() { return bits; }
+
+ // Get decode table.
+ double getDecodeLow(int i) { return decodeLow[i]; }
+ double getDecodeHigh(int i) { return decodeLow[i] + decodeRange[i]; }
+
+ // Convert an image pixel to a color.
+ void getGray(Guchar *x, double *gray);
+ void getRGB(Guchar *x, GfxRGB *rgb);
+ void getCMYK(Guchar *x, GfxCMYK *cmyk);
+
+private:
+
+ GfxColorSpace *colorSpace; // the image color space
+ int bits; // bits per component
+ int nComps; // number of components in a pixel
+ GfxColorSpace *colorSpace2; // secondary color space
+ int nComps2; // number of components in colorSpace2
+ double *lookup; // lookup table
+ double // minimum values for each component
+ decodeLow[gfxColorMaxComps];
+ double // max - min value for each component
+ decodeRange[gfxColorMaxComps];
+ GBool ok;
+};
+
+//------------------------------------------------------------------------
+// GfxSubpath and GfxPath
+//------------------------------------------------------------------------
+
+class GfxSubpath {
+public:
+
+ // Constructor.
+ GfxSubpath(double x1, double y1);
+
+ // Destructor.
+ ~GfxSubpath();
+
+ // Copy.
+ GfxSubpath *copy() { return new GfxSubpath(this); }
+
+ // Get points.
+ int getNumPoints() { return n; }
+ double getX(int i) { return x[i]; }
+ double getY(int i) { return y[i]; }
+ GBool getCurve(int i) { return curve[i]; }
+
+ // Get last point.
+ double getLastX() { return x[n-1]; }
+ double getLastY() { return y[n-1]; }
+
+ // Add a line segment.
+ void lineTo(double x1, double y1);
+
+ // Add a Bezier curve.
+ void curveTo(double x1, double y1, double x2, double y2,
+ double x3, double y3);
+
+ // Close the subpath.
+ void close();
+ GBool isClosed() { return closed; }
+
+private:
+
+ double *x, *y; // points
+ GBool *curve; // curve[i] => point i is a control point
+ // for a Bezier curve
+ int n; // number of points
+ int size; // size of x/y arrays
+ GBool closed; // set if path is closed
+
+ GfxSubpath(GfxSubpath *subpath);
+};
+
+class GfxPath {
+public:
+
+ // Constructor.
+ GfxPath();
+
+ // Destructor.
+ ~GfxPath();
+
+ // Copy.
+ GfxPath *copy()
+ { return new GfxPath(justMoved, firstX, firstY, subpaths, n, size); }
+
+ // Is there a current point?
+ GBool isCurPt() { return n > 0 || justMoved; }
+
+ // Is the path non-empty, i.e., is there at least one segment?
+ GBool isPath() { return n > 0; }
+
+ // Get subpaths.
+ int getNumSubpaths() { return n; }
+ GfxSubpath *getSubpath(int i) { return subpaths[i]; }
+
+ // Get last point on last subpath.
+ double getLastX() { return subpaths[n-1]->getLastX(); }
+ double getLastY() { return subpaths[n-1]->getLastY(); }
+
+ // Move the current point.
+ void moveTo(double x, double y);
+
+ // Add a segment to the last subpath.
+ void lineTo(double x, double y);
+
+ // Add a Bezier curve to the last subpath
+ void curveTo(double x1, double y1, double x2, double y2,
+ double x3, double y3);
+
+ // Close the last subpath.
+ void close() { subpaths[n-1]->close(); }
+
+private:
+
+ GBool justMoved; // set if a new subpath was just started
+ double firstX, firstY; // first point in new subpath
+ GfxSubpath **subpaths; // subpaths
+ int n; // number of subpaths
+ int size; // size of subpaths array
+
+ GfxPath(GBool justMoved1, double firstX1, double firstY1,
+ GfxSubpath **subpaths1, int n1, int size1);
+};
+
+//------------------------------------------------------------------------
+// GfxState
+//------------------------------------------------------------------------
+
+class GfxState {
+public:
+
+ // Construct a default GfxState, for a device with resolution <dpi>,
+ // page box <pageBox>, page rotation <rotate>, and coordinate system
+ // specified by <upsideDown>.
+ GfxState(double dpi, PDFRectangle *pageBox, int rotate,
+ GBool upsideDown);
+
+ // Destructor.
+ ~GfxState();
+
+ // Copy.
+ GfxState *copy() { return new GfxState(this); }
+
+ // Accessors.
+ double *getCTM() { return ctm; }
+ double getX1() { return px1; }
+ double getY1() { return py1; }
+ double getX2() { return px2; }
+ double getY2() { return py2; }
+ double getPageWidth() { return pageWidth; }
+ double getPageHeight() { return pageHeight; }
+ GfxColor *getFillColor() { return &fillColor; }
+ GfxColor *getStrokeColor() { return &strokeColor; }
+ void getFillGray(double *gray)
+ { fillColorSpace->getGray(&fillColor, gray); }
+ void getStrokeGray(double *gray)
+ { strokeColorSpace->getGray(&fillColor, gray); }
+ void getFillRGB(GfxRGB *rgb)
+ { fillColorSpace->getRGB(&fillColor, rgb); }
+ void getStrokeRGB(GfxRGB *rgb)
+ { strokeColorSpace->getRGB(&strokeColor, rgb); }
+ void getFillCMYK(GfxCMYK *cmyk)
+ { fillColorSpace->getCMYK(&fillColor, cmyk); }
+ void getStrokeCMYK(GfxCMYK *cmyk)
+ { strokeColorSpace->getCMYK(&strokeColor, cmyk); }
+ GfxColorSpace *getFillColorSpace() { return fillColorSpace; }
+ GfxColorSpace *getStrokeColorSpace() { return strokeColorSpace; }
+ GfxPattern *getFillPattern() { return fillPattern; }
+ GfxPattern *getStrokePattern() { return strokePattern; }
+ double getFillOpacity() { return fillOpacity; }
+ double getStrokeOpacity() { return strokeOpacity; }
+ double getLineWidth() { return lineWidth; }
+ void getLineDash(double **dash, int *length, double *start)
+ { *dash = lineDash; *length = lineDashLength; *start = lineDashStart; }
+ int getFlatness() { return flatness; }
+ int getLineJoin() { return lineJoin; }
+ int getLineCap() { return lineCap; }
+ double getMiterLimit() { return miterLimit; }
+ GfxFont *getFont() { return font; }
+ double getFontSize() { return fontSize; }
+ double *getTextMat() { return textMat; }
+ double getCharSpace() { return charSpace; }
+ double getWordSpace() { return wordSpace; }
+ double getHorizScaling() { return horizScaling; }
+ double getLeading() { return leading; }
+ double getRise() { return rise; }
+ int getRender() { return render; }
+ GfxPath *getPath() { return path; }
+ double getCurX() { return curX; }
+ double getCurY() { return curY; }
+ void getClipBBox(double *xMin, double *yMin, double *xMax, double *yMax)
+ { *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; }
+ double getLineX() { return lineX; }
+ double getLineY() { return lineY; }
+
+ // Is there a current point/path?
+ GBool isCurPt() { return path->isCurPt(); }
+ GBool isPath() { return path->isPath(); }
+
+ // Transforms.
+ void transform(double x1, double y1, double *x2, double *y2)
+ { *x2 = ctm[0] * x1 + ctm[2] * y1 + ctm[4];
+ *y2 = ctm[1] * x1 + ctm[3] * y1 + ctm[5]; }
+ void transformDelta(double x1, double y1, double *x2, double *y2)
+ { *x2 = ctm[0] * x1 + ctm[2] * y1;
+ *y2 = ctm[1] * x1 + ctm[3] * y1; }
+ void textTransform(double x1, double y1, double *x2, double *y2)
+ { *x2 = textMat[0] * x1 + textMat[2] * y1 + textMat[4];
+ *y2 = textMat[1] * x1 + textMat[3] * y1 + textMat[5]; }
+ void textTransformDelta(double x1, double y1, double *x2, double *y2)
+ { *x2 = textMat[0] * x1 + textMat[2] * y1;
+ *y2 = textMat[1] * x1 + textMat[3] * y1; }
+ double transformWidth(double w);
+ double getTransformedLineWidth()
+ { return transformWidth(lineWidth); }
+ double getTransformedFontSize();
+ void getFontTransMat(double *m11, double *m12, double *m21, double *m22);
+
+ // Change state parameters.
+ void setCTM(double a, double b, double c,
+ double d, double e, double f);
+ void concatCTM(double a, double b, double c,
+ double d, double e, double f);
+ void setFillColorSpace(GfxColorSpace *colorSpace);
+ void setStrokeColorSpace(GfxColorSpace *colorSpace);
+ void setFillColor(GfxColor *color) { fillColor = *color; }
+ void setStrokeColor(GfxColor *color) { strokeColor = *color; }
+ void setFillPattern(GfxPattern *pattern);
+ void setStrokePattern(GfxPattern *pattern);
+ void setFillOpacity(double opac) { fillOpacity = opac; }
+ void setStrokeOpacity(double opac) { strokeOpacity = opac; }
+ void setLineWidth(double width) { lineWidth = width; }
+ void setLineDash(double *dash, int length, double start);
+ void setFlatness(int flatness1) { flatness = flatness1; }
+ void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; }
+ void setLineCap(int lineCap1) { lineCap = lineCap1; }
+ void setMiterLimit(double limit) { miterLimit = limit; }
+ void setFont(GfxFont *fontA, double fontSizeA)
+ { font = fontA; fontSize = fontSizeA; }
+ void setTextMat(double a, double b, double c,
+ double d, double e, double f)
+ { textMat[0] = a; textMat[1] = b; textMat[2] = c;
+ textMat[3] = d; textMat[4] = e; textMat[5] = f; }
+ void setCharSpace(double space)
+ { charSpace = space; }
+ void setWordSpace(double space)
+ { wordSpace = space; }
+ void setHorizScaling(double scale)
+ { horizScaling = 0.01 * scale; }
+ void setLeading(double leadingA)
+ { leading = leadingA; }
+ void setRise(double riseA)
+ { rise = riseA; }
+ void setRender(int renderA)
+ { render = renderA; }
+
+ // Add to path.
+ void moveTo(double x, double y)
+ { path->moveTo(curX = x, curY = y); }
+ void lineTo(double x, double y)
+ { path->lineTo(curX = x, curY = y); }
+ void curveTo(double x1, double y1, double x2, double y2,
+ double x3, double y3)
+ { path->curveTo(x1, y1, x2, y2, curX = x3, curY = y3); }
+ void closePath()
+ { path->close(); curX = path->getLastX(); curY = path->getLastY(); }
+ void clearPath();
+
+ // Update clip region.
+ void clip();
+
+ // Text position.
+ void textMoveTo(double tx, double ty)
+ { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); }
+ void textShift(double tx);
+ void textShift(double tx, double ty);
+
+ // Push/pop GfxState on/off stack.
+ GfxState *save();
+ GfxState *restore();
+ GBool hasSaves() { return saved != NULL; }
+
+private:
+
+ double ctm[6]; // coord transform matrix
+ double px1, py1, px2, py2; // page corners (user coords)
+ double pageWidth, pageHeight; // page size (pixels)
+
+ GfxColorSpace *fillColorSpace; // fill color space
+ GfxColorSpace *strokeColorSpace; // stroke color space
+ GfxColor fillColor; // fill color
+ GfxColor strokeColor; // stroke color
+ GfxPattern *fillPattern; // fill pattern
+ GfxPattern *strokePattern; // stroke pattern
+ double fillOpacity; // fill opacity
+ double strokeOpacity; // stroke opacity
+
+ double lineWidth; // line width
+ double *lineDash; // line dash
+ int lineDashLength;
+ double lineDashStart;
+ int flatness; // curve flatness
+ int lineJoin; // line join style
+ int lineCap; // line cap style
+ double miterLimit; // line miter limit
+
+ GfxFont *font; // font
+ double fontSize; // font size
+ double textMat[6]; // text matrix
+ double charSpace; // character spacing
+ double wordSpace; // word spacing
+ double horizScaling; // horizontal scaling
+ double leading; // text leading
+ double rise; // text rise
+ int render; // text rendering mode
+
+ GfxPath *path; // array of path elements
+ double curX, curY; // current point (user coords)
+ double lineX, lineY; // start of current text line (text coords)
+
+ double clipXMin, clipYMin, // bounding box for clip region
+ clipXMax, clipYMax;
+
+ GfxState *saved; // next GfxState on stack
+
+ GfxState(GfxState *state);
+};
+
+#endif
diff --git a/pdftops/Japan12CMapInfo.h b/pdftops/Japan12CMapInfo.h
new file mode 100644
index 000000000..ae4ef9c9d
--- /dev/null
+++ b/pdftops/Japan12CMapInfo.h
@@ -0,0 +1,31362 @@
+//========================================================================
+//
+// Japan12CMapInfo.h
+//
+// This file was automatically generated by makeCMapInfo.
+//
+// Copyright 1998 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef JAPAN12CMAPINFO_H
+#define JAPAN12CMAPINFO_H
+
+static Gushort japan1278EUCHMap2[1252] = {
+ 0x0000, 0x0000,
+ 0x8ea0, 0x0146,
+ 0xa1a1, 0x0279,
+ 0xa2a1, 0x02d7,
+ 0xa3b0, 0x030c,
+ 0xa3c1, 0x0316,
+ 0xa3e1, 0x0330,
+ 0xa4a1, 0x034a,
+ 0xa5a1, 0x039d,
+ 0xa6a1, 0x03f3,
+ 0xa6c1, 0x040b,
+ 0xa7a1, 0x0423,
+ 0xa7d1, 0x0444,
+ 0xb0a1, 0x0465,
+ 0xb0a2, 0x1dd1,
+ 0xb0a3, 0x0467,
+ 0xb0a9, 0x204a,
+ 0xb0aa, 0x046e,
+ 0xb0b2, 0x1f19,
+ 0xb0b3, 0x1ca2,
+ 0xb0b4, 0x0478,
+ 0xb0bb, 0x1dd2,
+ 0xb0bc, 0x0480,
+ 0xb0ee, 0x1dd3,
+ 0xb0ef, 0x04b3,
+ 0xb0f3, 0x1dd4,
+ 0xb0f4, 0x04b8,
+ 0xb0fc, 0x1dd5,
+ 0xb0fd, 0x04c1,
+ 0xb1a1, 0x04c3,
+ 0xb1aa, 0x1dd6,
+ 0xb1ab, 0x04cd,
+ 0xb1b5, 0x1dd7,
+ 0xb1b6, 0x04d8,
+ 0xb1b9, 0x1dd8,
+ 0xb1ba, 0x04dc,
+ 0xb1bd, 0x1dda,
+ 0xb1be, 0x04e0,
+ 0xb1c2, 0x1ddb,
+ 0xb1c3, 0x04e5,
+ 0xb1eb, 0x1ddc,
+ 0xb1ec, 0x050e,
+ 0xb2a1, 0x0521,
+ 0xb2a8, 0x1ddd,
+ 0xb2a9, 0x1cc9,
+ 0xb2aa, 0x1dde,
+ 0xb2ab, 0x052b,
+ 0xb2e0, 0x1ddf,
+ 0xb2e1, 0x0561,
+ 0xb2fa, 0x1de0,
+ 0xb2fb, 0x057b,
+ 0xb2fd, 0x1de1,
+ 0xb2fe, 0x057e,
+ 0xb3a1, 0x057f,
+ 0xb3a2, 0x1de2,
+ 0xb3a3, 0x0581,
+ 0xb3c2, 0x1961,
+ 0xb3c3, 0x05a1,
+ 0xb3c9, 0x139f,
+ 0xb3ca, 0x05a8,
+ 0xb3e5, 0x1de3,
+ 0xb3e6, 0x05c4,
+ 0xb3eb, 0x1de4,
+ 0xb3ec, 0x05ca,
+ 0xb3f3, 0x1de5,
+ 0xb3f4, 0x05d2,
+ 0xb3f6, 0x1731,
+ 0xb3f7, 0x05d5,
+ 0xb3fa, 0x1de6,
+ 0xb3fb, 0x05d9,
+ 0xb4a1, 0x05dd,
+ 0xb4c2, 0x1de7,
+ 0xb4c3, 0x1572,
+ 0xb4c4, 0x0600,
+ 0xb4cd, 0x1de8,
+ 0xb4ce, 0x060a,
+ 0xb4d2, 0x1a20,
+ 0xb4d3, 0x060f,
+ 0xb4e5, 0x1de9,
+ 0xb4e6, 0x0622,
+ 0xb5a1, 0x063b,
+ 0xb5ab, 0x1dea,
+ 0xb5ac, 0x0646,
+ 0xb5c0, 0x1deb,
+ 0xb5c1, 0x065b,
+ 0xb6a1, 0x0699,
+ 0xb6a2, 0x1dec,
+ 0xb6a3, 0x069b,
+ 0xb6aa, 0x1ded,
+ 0xb6ab, 0x06a3,
+ 0xb6c6, 0x1d32,
+ 0xb6c7, 0x06bf,
+ 0xb6cf, 0x1dee,
+ 0xb6d0, 0x06c8,
+ 0xb6ed, 0x1def,
+ 0xb6ee, 0x06e6,
+ 0xb6f4, 0x1df0,
+ 0xb6f5, 0x06ed,
+ 0xb6fb, 0x1df1,
+ 0xb6fc, 0x06f4,
+ 0xb6fd, 0x1df2,
+ 0xb6fe, 0x06f6,
+ 0xb7a1, 0x06f7,
+ 0xb7a4, 0x1df3,
+ 0xb7a5, 0x06fb,
+ 0xb7b7, 0x1df4,
+ 0xb7b8, 0x070e,
+ 0xb7c5, 0x1df5,
+ 0xb7c6, 0x071c,
+ 0xb7ce, 0x1df6,
+ 0xb7cf, 0x0725,
+ 0xb7d2, 0x1df7,
+ 0xb7d3, 0x0729,
+ 0xb7d5, 0x1df8,
+ 0xb7d6, 0x072c,
+ 0xb7db, 0x1c0d,
+ 0xb7dc, 0x0732,
+ 0xb7e4, 0x1df9,
+ 0xb7e5, 0x073b,
+ 0xb7f1, 0x1dfa,
+ 0xb7f2, 0x0748,
+ 0xb7f9, 0x1dfb,
+ 0xb7fa, 0x0750,
+ 0xb7fe, 0x1dfc,
+ 0xb8a1, 0x0755,
+ 0xb8b4, 0x1dfd,
+ 0xb8b5, 0x0769,
+ 0xb8c1, 0x1dfe,
+ 0xb8c2, 0x0776,
+ 0xb9a1, 0x07b3,
+ 0xb9ab, 0x1dff,
+ 0xb9ac, 0x07be,
+ 0xb9b7, 0x1e00,
+ 0xb9b8, 0x07ca,
+ 0xb9c2, 0x1e01,
+ 0xb9c3, 0x07d5,
+ 0xb9dc, 0x16dd,
+ 0xb9dd, 0x07ef,
+ 0xb9ed, 0x1e02,
+ 0xb9ee, 0x0800,
+ 0xb9f4, 0x1e03,
+ 0xb9f5, 0x0807,
+ 0xb9f9, 0x1e04,
+ 0xb9fa, 0x080c,
+ 0xbaa1, 0x0811,
+ 0xbad3, 0x1e05,
+ 0xbad4, 0x0844,
+ 0xbae7, 0x1e06,
+ 0xbae8, 0x0858,
+ 0xbaf4, 0x1e07,
+ 0xbaf5, 0x0865,
+ 0xbba1, 0x086f,
+ 0xbba7, 0x1e08,
+ 0xbba8, 0x0876,
+ 0xbbaa, 0x1e09,
+ 0xbbab, 0x0879,
+ 0xbbac, 0x1e0a,
+ 0xbbad, 0x087b,
+ 0xbbb9, 0x1e0b,
+ 0xbbba, 0x0888,
+ 0xbca1, 0x08cd,
+ 0xbcc8, 0x1e0d,
+ 0xbcc9, 0x1929,
+ 0xbcca, 0x08f6,
+ 0xbcd7, 0x1e0e,
+ 0xbcd8, 0x0904,
+ 0xbcdd, 0x1e0f,
+ 0xbcdf, 0x090b,
+ 0xbda1, 0x092b,
+ 0xbdab, 0x1e11,
+ 0xbdac, 0x0936,
+ 0xbdb6, 0x1e12,
+ 0xbdb7, 0x0941,
+ 0xbdec, 0x1e13,
+ 0xbdee, 0x0978,
+ 0xbdf2, 0x1e15,
+ 0xbdf4, 0x097e,
+ 0xbea1, 0x0989,
+ 0xbea5, 0x1e17,
+ 0xbea6, 0x098e,
+ 0xbeb3, 0x1e18,
+ 0xbeb4, 0x099c,
+ 0xbebf, 0x1e19,
+ 0xbec0, 0x09a8,
+ 0xbed5, 0x1e1a,
+ 0xbed6, 0x09be,
+ 0xbedf, 0x1e1b,
+ 0xbee0, 0x09c8,
+ 0xbee4, 0x1e1c,
+ 0xbee5, 0x09cd,
+ 0xbfa1, 0x09e7,
+ 0xbfaa, 0x1e1d,
+ 0xbfab, 0x09f1,
+ 0xbfd9, 0x1e1e,
+ 0xbfda, 0x0a20,
+ 0xbfe0, 0x1e1f,
+ 0xbfe1, 0x0a27,
+ 0xbfe9, 0x1e20,
+ 0xbfea, 0x0a30,
+ 0xc0a1, 0x0a45,
+ 0xc0a2, 0x1e21,
+ 0xc0a3, 0x0a47,
+ 0xc0c2, 0x1e22,
+ 0xc0c3, 0x0a67,
+ 0xc0e6, 0x1e23,
+ 0xc0e7, 0x0a8b,
+ 0xc0f1, 0x1e24,
+ 0xc0f3, 0x0a97,
+ 0xc0f9, 0x1e26,
+ 0xc0fb, 0x0a9f,
+ 0xc1a1, 0x0aa3,
+ 0xc1a7, 0x1e28,
+ 0xc1a8, 0x1a6e,
+ 0xc1a9, 0x0aab,
+ 0xc1b9, 0x1e29,
+ 0xc1ba, 0x0abc,
+ 0xc1cc, 0x1e2a,
+ 0xc1cd, 0x0acf,
+ 0xc1cf, 0x1e2b,
+ 0xc1d0, 0x0ad2,
+ 0xc1df, 0x1e2c,
+ 0xc1e0, 0x0ae2,
+ 0xc1e9, 0x1e2d,
+ 0xc1ea, 0x0aec,
+ 0xc2a1, 0x0b01,
+ 0xc2bd, 0x1e2e,
+ 0xc2be, 0x0b1e,
+ 0xc2cd, 0x1e2f,
+ 0xc2ce, 0x0b2e,
+ 0xc2dc, 0x1e30,
+ 0xc2dd, 0x0b3d,
+ 0xc2e3, 0x1e31,
+ 0xc2e4, 0x0b44,
+ 0xc2ef, 0x1e32,
+ 0xc2f0, 0x0b50,
+ 0xc2f5, 0x1e33,
+ 0xc2f7, 0x0b57,
+ 0xc2fd, 0x1e35,
+ 0xc2fe, 0x0b5e,
+ 0xc3a1, 0x0b5f,
+ 0xc3a7, 0x1e36,
+ 0xc3a8, 0x0b66,
+ 0xc3a9, 0x1e37,
+ 0xc3ab, 0x0b69,
+ 0xc3ad, 0x1e39,
+ 0xc3af, 0x0b6d,
+ 0xc3bd, 0x1e3b,
+ 0xc3be, 0x0b7c,
+ 0xc3f0, 0x1e3c,
+ 0xc3f1, 0x0baf,
+ 0xc3f5, 0x1e3d,
+ 0xc3f6, 0x0bb4,
+ 0xc3fc, 0x1e3e,
+ 0xc3fd, 0x0bbb,
+ 0xc4a1, 0x0bbd,
+ 0xc4bd, 0x1e3f,
+ 0xc4be, 0x0bda,
+ 0xc4c8, 0x1e40,
+ 0xc4c9, 0x0be5,
+ 0xc4ca, 0x1e41,
+ 0xc4cb, 0x0be7,
+ 0xc4cd, 0x1e42,
+ 0xc4ce, 0x0bea,
+ 0xc4cf, 0x1e43,
+ 0xc4d0, 0x0bec,
+ 0xc4d4, 0x204b,
+ 0xc4d5, 0x0bf1,
+ 0xc4db, 0x11b5,
+ 0xc4dc, 0x0bf8,
+ 0xc5a1, 0x0c1b,
+ 0xc5a2, 0x1e44,
+ 0xc5a3, 0x0c1d,
+ 0xc5a7, 0x1e45,
+ 0xc5a8, 0x0c22,
+ 0xc5ae, 0x1e46,
+ 0xc5af, 0x0c29,
+ 0xc5b6, 0x1e47,
+ 0xc5b7, 0x0c31,
+ 0xc5bf, 0x1e48,
+ 0xc5c0, 0x0c3a,
+ 0xc5c8, 0x1e49,
+ 0xc5c9, 0x0c43,
+ 0xc5cb, 0x1e4a,
+ 0xc5cc, 0x0c46,
+ 0xc5d1, 0x1e4b,
+ 0xc5d3, 0x0c4d,
+ 0xc5d7, 0x16df,
+ 0xc5d8, 0x0c52,
+ 0xc5e4, 0x1e4d,
+ 0xc5e5, 0x0c5f,
+ 0xc5ee, 0x1450,
+ 0xc5ef, 0x0c69,
+ 0xc5f3, 0x1536,
+ 0xc5f4, 0x0c6e,
+ 0xc5f8, 0x1e4e,
+ 0xc5f9, 0x0c73,
+ 0xc6a1, 0x0c79,
+ 0xc6be, 0x1e4f,
+ 0xc6bf, 0x0c97,
+ 0xc6c2, 0x1e50,
+ 0xc6c3, 0x0c9b,
+ 0xc6d4, 0x1e51,
+ 0xc6d6, 0x0cae,
+ 0xc6db, 0x1e53,
+ 0xc6dd, 0x0cb5,
+ 0xc6e1, 0x1e55,
+ 0xc6e2, 0x0cba,
+ 0xc6e6, 0x1e56,
+ 0xc6e8, 0x0cc0,
+ 0xc6ea, 0x1e58,
+ 0xc6eb, 0x0cc3,
+ 0xc6f6, 0x1aed,
+ 0xc6f7, 0x0ccf,
+ 0xc7a1, 0x0cd7,
+ 0xc7a9, 0x1e59,
+ 0xc7aa, 0x0ce0,
+ 0xc7b9, 0x1e5a,
+ 0xc7ba, 0x0cf0,
+ 0xc7d7, 0x1e5b,
+ 0xc7d8, 0x0d0e,
+ 0xc7e7, 0x1e5c,
+ 0xc7e8, 0x1989,
+ 0xc7e9, 0x1e5d,
+ 0xc7ea, 0x0d20,
+ 0xc7ed, 0x1e5e,
+ 0xc7ee, 0x0d24,
+ 0xc8a1, 0x0d35,
+ 0xc8a4, 0x1e5f,
+ 0xc8a5, 0x0d39,
+ 0xc8ae, 0x1e60,
+ 0xc8af, 0x0d43,
+ 0xc8b0, 0x1e61,
+ 0xc8b1, 0x0d45,
+ 0xc8d4, 0x1e62,
+ 0xc8d5, 0x0d69,
+ 0xc8e2, 0x1e63,
+ 0xc8e3, 0x0d77,
+ 0xc8f5, 0x1e64,
+ 0xc8f6, 0x0d8a,
+ 0xc9a1, 0x0d93,
+ 0xc9a2, 0x1e65,
+ 0xc9a4, 0x0d96,
+ 0xc9af, 0x1e67,
+ 0xc9b0, 0x143b,
+ 0xc9b1, 0x0da3,
+ 0xc9b2, 0x1e68,
+ 0xc9b3, 0x0da5,
+ 0xc9b5, 0x1e69,
+ 0xc9b6, 0x0da8,
+ 0xc9c0, 0x1e6a,
+ 0xc9c1, 0x0db3,
+ 0xc9ce, 0x1e6b,
+ 0xc9cf, 0x0dc1,
+ 0xc9d1, 0x1e6c,
+ 0xc9d2, 0x0dc4,
+ 0xcaa1, 0x0df1,
+ 0xcac3, 0x1e6d,
+ 0xcac4, 0x0e14,
+ 0xcacd, 0x1e6e,
+ 0xcace, 0x0e1e,
+ 0xcada, 0x1e6f,
+ 0xcadb, 0x0e2b,
+ 0xcaf9, 0x1e70,
+ 0xcafa, 0x0e4a,
+ 0xcba1, 0x0e4f,
+ 0xcba2, 0x1e71,
+ 0xcba3, 0x0e51,
+ 0xcba9, 0x1e72,
+ 0xcbaa, 0x0e58,
+ 0xcbcb, 0x1e73,
+ 0xcbcc, 0x0e7a,
+ 0xcbea, 0x1d33,
+ 0xcbeb, 0x0e99,
+ 0xcbf0, 0x1e74,
+ 0xcbf1, 0x0e9f,
+ 0xcbf8, 0x1f2c,
+ 0xcbf9, 0x102f,
+ 0xcbfa, 0x0ea8,
+ 0xcca1, 0x0ead,
+ 0xcccd, 0x1e75,
+ 0xccce, 0x0eda,
+ 0xccd9, 0x1e76,
+ 0xccda, 0x0ee6,
+ 0xccdf, 0x1e77,
+ 0xcce0, 0x0eec,
+ 0xcce2, 0x1e78,
+ 0xcce3, 0x0eef,
+ 0xccf9, 0x1935,
+ 0xccfa, 0x1e79,
+ 0xccfb, 0x0f07,
+ 0xccfc, 0x1e7a,
+ 0xccfd, 0x0f09,
+ 0xccfe, 0x1e7b,
+ 0xcda1, 0x0f0b,
+ 0xcdb2, 0x1e7c,
+ 0xcdb3, 0x0f1d,
+ 0xcdd0, 0x1e7d,
+ 0xcdd1, 0x0f3b,
+ 0xcdd4, 0x1e7e,
+ 0xcdd5, 0x0f3f,
+ 0xcdda, 0x1d34,
+ 0xcddb, 0x0f45,
+ 0xcde9, 0x1e7f,
+ 0xcdea, 0x0f54,
+ 0xcea1, 0x0f69,
+ 0xcecb, 0x1e80,
+ 0xcecc, 0x0f94,
+ 0xcefa, 0x1e81,
+ 0xcefc, 0x0fc4,
+ 0xcfa1, 0x1e83,
+ 0xcfa2, 0x0fc8,
+ 0xcfb1, 0x1e84,
+ 0xcfb2, 0x0fd8,
+ 0xcfb6, 0x1777,
+ 0xcfb7, 0x0fdd,
+ 0xcfb9, 0x1e85,
+ 0xcfba, 0x0fe0,
+ 0xd0a1, 0x0ffa,
+ 0xd0d6, 0x0ea7,
+ 0xd0d7, 0x1030,
+ 0xd1a1, 0x1058,
+ 0xd1bd, 0x1e86,
+ 0xd1be, 0x1075,
+ 0xd1c7, 0x1e87,
+ 0xd1c8, 0x107f,
+ 0xd1cb, 0x1e88,
+ 0xd1cc, 0x1083,
+ 0xd1cd, 0x1e89,
+ 0xd1ce, 0x1085,
+ 0xd2a1, 0x10b6,
+ 0xd3a1, 0x1114,
+ 0xd3b0, 0x1e8a,
+ 0xd3b1, 0x1124,
+ 0xd3ba, 0x1e8b,
+ 0xd3bb, 0x112e,
+ 0xd3de, 0x1e8d,
+ 0xd3df, 0x1152,
+ 0xd3eb, 0x1e8e,
+ 0xd3ec, 0x115f,
+ 0xd4a1, 0x1172,
+ 0xd4c4, 0x1e8f,
+ 0xd4c5, 0x1196,
+ 0xd4e4, 0x0bf7,
+ 0xd4e5, 0x11b6,
+ 0xd5a1, 0x11d0,
+ 0xd5bd, 0x1e90,
+ 0xd5be, 0x11ed,
+ 0xd5e3, 0x1e91,
+ 0xd5e4, 0x1213,
+ 0xd6a1, 0x122e,
+ 0xd6a2, 0x1e92,
+ 0xd6a3, 0x1230,
+ 0xd7a1, 0x128c,
+ 0xd8a1, 0x12ea,
+ 0xd8a4, 0x1e94,
+ 0xd8a5, 0x12ee,
+ 0xd9a1, 0x1348,
+ 0xd9e0, 0x1e95,
+ 0xd9e1, 0x1388,
+ 0xd9ec, 0x1e96,
+ 0xd9ed, 0x1394,
+ 0xd9f8, 0x05a7,
+ 0xd9f9, 0x13a0,
+ 0xdaa1, 0x13a6,
+ 0xdab9, 0x1e97,
+ 0xdaba, 0x13bf,
+ 0xdacd, 0x1e98,
+ 0xdace, 0x13d3,
+ 0xdba1, 0x1404,
+ 0xdbc5, 0x1e99,
+ 0xdbc6, 0x1429,
+ 0xdbca, 0x1e9a,
+ 0xdbcb, 0x142e,
+ 0xdbd8, 0x0da2,
+ 0xdbd9, 0x143c,
+ 0xdbeb, 0x1e9b,
+ 0xdbec, 0x144f,
+ 0xdbed, 0x0c68,
+ 0xdbee, 0x1451,
+ 0xdbf4, 0x1e9c,
+ 0xdbf5, 0x1458,
+ 0xdca1, 0x1462,
+ 0xdda1, 0x14c0,
+ 0xdea1, 0x151e,
+ 0xdeb9, 0x0c6d,
+ 0xdeba, 0x1537,
+ 0xded0, 0x1e9d,
+ 0xded1, 0x154e,
+ 0xdef5, 0x05ff,
+ 0xdef6, 0x1573,
+ 0xdfa1, 0x157c,
+ 0xe0a1, 0x15da,
+ 0xe0a6, 0x1e9f,
+ 0xe0a7, 0x15e0,
+ 0xe0df, 0x1ea0,
+ 0xe0e0, 0x1619,
+ 0xe0f6, 0x1d35,
+ 0xe0f7, 0x1630,
+ 0xe1a1, 0x1638,
+ 0xe1ab, 0x1ea1,
+ 0xe1ac, 0x1643,
+ 0xe1b0, 0x1ea2,
+ 0xe1b2, 0x1649,
+ 0xe2a1, 0x1696,
+ 0xe2ab, 0x1ea4,
+ 0xe2ac, 0x16a1,
+ 0xe2e8, 0x07ee,
+ 0xe2e9, 0x16de,
+ 0xe2ea, 0x0c51,
+ 0xe2eb, 0x16e0,
+ 0xe2ef, 0x1ea5,
+ 0xe2f0, 0x16e5,
+ 0xe3a1, 0x16f4,
+ 0xe3ca, 0x1ea6,
+ 0xe3cb, 0x171e,
+ 0xe3d4, 0x1ea7,
+ 0xe3d5, 0x1728,
+ 0xe3de, 0x05d4,
+ 0xe3df, 0x1732,
+ 0xe4a1, 0x1752,
+ 0xe4b9, 0x1ea8,
+ 0xe4ba, 0x176b,
+ 0xe4c6, 0x0fdc,
+ 0xe4c7, 0x1778,
+ 0xe4e4, 0x1ea9,
+ 0xe4e5, 0x1796,
+ 0xe4ee, 0x1eaa,
+ 0xe4ef, 0x17a0,
+ 0xe5a1, 0x17b0,
+ 0xe5b9, 0x1eab,
+ 0xe5ba, 0x17c9,
+ 0xe5bb, 0x1eac,
+ 0xe5bc, 0x17cb,
+ 0xe5c6, 0x1ead,
+ 0xe5c7, 0x17d6,
+ 0xe6a1, 0x180e,
+ 0xe6c6, 0x1eae,
+ 0xe6c7, 0x1834,
+ 0xe7a1, 0x186c,
+ 0xe7e4, 0x1eaf,
+ 0xe7e5, 0x18b0,
+ 0xe7e9, 0x1eb0,
+ 0xe7ea, 0x18b5,
+ 0xe7f2, 0x1eb1,
+ 0xe7f3, 0x18be,
+ 0xe8a1, 0x18ca,
+ 0xe8b4, 0x1eb2,
+ 0xe8b5, 0x18de,
+ 0xe8bb, 0x1eb3,
+ 0xe8bc, 0x18e5,
+ 0xe8f4, 0x1eb4,
+ 0xe8f5, 0x191e,
+ 0xe9a1, 0x1928,
+ 0xe9a2, 0x08f5,
+ 0xe9a3, 0x192a,
+ 0xe9ae, 0x0f05,
+ 0xe9af, 0x1936,
+ 0xe9da, 0x05a0,
+ 0xe9db, 0x1962,
+ 0xeaa1, 0x1986,
+ 0xeaa4, 0x0d1e,
+ 0xeaa5, 0x198a,
+ 0xeaa7, 0x1eb6,
+ 0xeaa8, 0x198d,
+ 0xeabd, 0x1eb7,
+ 0xeabe, 0x19a3,
+ 0xeaef, 0x1eb8,
+ 0xeaf0, 0x19d5,
+ 0xeba1, 0x19e4,
+ 0xebb2, 0x1eb9,
+ 0xebb3, 0x19f6,
+ 0xebdd, 0x060e,
+ 0xebde, 0x1a21,
+ 0xebe6, 0x1eba,
+ 0xebe7, 0x1a2a,
+ 0xebf6, 0x1ebb,
+ 0xebf7, 0x1a3a,
+ 0xeca1, 0x1a42,
+ 0xeccd, 0x0aaa,
+ 0xecce, 0x1a6f,
+ 0xece9, 0x1ebc,
+ 0xecea, 0x1a8b,
+ 0xecf4, 0x1ebd,
+ 0xecf5, 0x1a96,
+ 0xeda1, 0x1aa0,
+ 0xedce, 0x1ebe,
+ 0xedcf, 0x1ace,
+ 0xedec, 0x1ebf,
+ 0xeded, 0x1aec,
+ 0xedee, 0x1ec0,
+ 0xedef, 0x1aee,
+ 0xeea1, 0x1afe,
+ 0xeea9, 0x1ec1,
+ 0xeeaa, 0x1b07,
+ 0xeebd, 0x1ec2,
+ 0xeebe, 0x1b1b,
+ 0xeed7, 0x1ec3,
+ 0xeed8, 0x1b35,
+ 0xefa1, 0x1b5c,
+ 0xf0a1, 0x1bba,
+ 0xf0c5, 0x1ec6,
+ 0xf0c6, 0x1bdf,
+ 0xf0d1, 0x1ec7,
+ 0xf0d2, 0x1beb,
+ 0xf0d7, 0x1ec8,
+ 0xf0d8, 0x1bf1,
+ 0xf0f4, 0x0731,
+ 0xf0f5, 0x1ec9,
+ 0xf0f6, 0x1c0f,
+ 0xf1a1, 0x1c18,
+ 0xf2a1, 0x1c76,
+ 0xf2ad, 0x1eca,
+ 0xf2ae, 0x1c83,
+ 0xf2bc, 0x1ecb,
+ 0xf2bd, 0x1c92,
+ 0xf2cd, 0x0477,
+ 0xf2ce, 0x1ecc,
+ 0xf2cf, 0x1ca4,
+ 0xf2f4, 0x0529,
+ 0xf2f5, 0x1cca,
+ 0xf3a1, 0x1cd4,
+ 0xf3d1, 0x1ecd,
+ 0xf3d2, 0x1d05,
+ 0xf3fd, 0x1ece,
+ 0xf3fe, 0x1d31,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1278EUCHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1278EUCHMap2, 626
+};
+
+static Gushort japan1278EUCVMap2[1306] = {
+ 0x0000, 0x0000,
+ 0x8ea0, 0x0146,
+ 0xa1a1, 0x0279,
+ 0xa2a1, 0x02d7,
+ 0xa3b0, 0x030c,
+ 0xa3c1, 0x0316,
+ 0xa3e1, 0x0330,
+ 0xa4a1, 0x034a,
+ 0xa5a1, 0x039d,
+ 0xa6a1, 0x03f3,
+ 0xa6c1, 0x040b,
+ 0xa7a1, 0x0423,
+ 0xa7d1, 0x0444,
+ 0xb0a1, 0x0465,
+ 0xb0a2, 0x1dd1,
+ 0xb0a3, 0x0467,
+ 0xb0a9, 0x204a,
+ 0xb0aa, 0x046e,
+ 0xb0b2, 0x1f19,
+ 0xb0b3, 0x1ca2,
+ 0xb0b4, 0x0478,
+ 0xb0bb, 0x1dd2,
+ 0xb0bc, 0x0480,
+ 0xb0ee, 0x1dd3,
+ 0xb0ef, 0x04b3,
+ 0xb0f3, 0x1dd4,
+ 0xb0f4, 0x04b8,
+ 0xb0fc, 0x1dd5,
+ 0xb0fd, 0x04c1,
+ 0xb1a1, 0x04c3,
+ 0xb1aa, 0x1dd6,
+ 0xb1ab, 0x04cd,
+ 0xb1b5, 0x1dd7,
+ 0xb1b6, 0x04d8,
+ 0xb1b9, 0x1dd8,
+ 0xb1ba, 0x04dc,
+ 0xb1bd, 0x1dda,
+ 0xb1be, 0x04e0,
+ 0xb1c2, 0x1ddb,
+ 0xb1c3, 0x04e5,
+ 0xb1eb, 0x1ddc,
+ 0xb1ec, 0x050e,
+ 0xb2a1, 0x0521,
+ 0xb2a8, 0x1ddd,
+ 0xb2a9, 0x1cc9,
+ 0xb2aa, 0x1dde,
+ 0xb2ab, 0x052b,
+ 0xb2e0, 0x1ddf,
+ 0xb2e1, 0x0561,
+ 0xb2fa, 0x1de0,
+ 0xb2fb, 0x057b,
+ 0xb2fd, 0x1de1,
+ 0xb2fe, 0x057e,
+ 0xb3a1, 0x057f,
+ 0xb3a2, 0x1de2,
+ 0xb3a3, 0x0581,
+ 0xb3c2, 0x1961,
+ 0xb3c3, 0x05a1,
+ 0xb3c9, 0x139f,
+ 0xb3ca, 0x05a8,
+ 0xb3e5, 0x1de3,
+ 0xb3e6, 0x05c4,
+ 0xb3eb, 0x1de4,
+ 0xb3ec, 0x05ca,
+ 0xb3f3, 0x1de5,
+ 0xb3f4, 0x05d2,
+ 0xb3f6, 0x1731,
+ 0xb3f7, 0x05d5,
+ 0xb3fa, 0x1de6,
+ 0xb3fb, 0x05d9,
+ 0xb4a1, 0x05dd,
+ 0xb4c2, 0x1de7,
+ 0xb4c3, 0x1572,
+ 0xb4c4, 0x0600,
+ 0xb4cd, 0x1de8,
+ 0xb4ce, 0x060a,
+ 0xb4d2, 0x1a20,
+ 0xb4d3, 0x060f,
+ 0xb4e5, 0x1de9,
+ 0xb4e6, 0x0622,
+ 0xb5a1, 0x063b,
+ 0xb5ab, 0x1dea,
+ 0xb5ac, 0x0646,
+ 0xb5c0, 0x1deb,
+ 0xb5c1, 0x065b,
+ 0xb6a1, 0x0699,
+ 0xb6a2, 0x1dec,
+ 0xb6a3, 0x069b,
+ 0xb6aa, 0x1ded,
+ 0xb6ab, 0x06a3,
+ 0xb6c6, 0x1d32,
+ 0xb6c7, 0x06bf,
+ 0xb6cf, 0x1dee,
+ 0xb6d0, 0x06c8,
+ 0xb6ed, 0x1def,
+ 0xb6ee, 0x06e6,
+ 0xb6f4, 0x1df0,
+ 0xb6f5, 0x06ed,
+ 0xb6fb, 0x1df1,
+ 0xb6fc, 0x06f4,
+ 0xb6fd, 0x1df2,
+ 0xb6fe, 0x06f6,
+ 0xb7a1, 0x06f7,
+ 0xb7a4, 0x1df3,
+ 0xb7a5, 0x06fb,
+ 0xb7b7, 0x1df4,
+ 0xb7b8, 0x070e,
+ 0xb7c5, 0x1df5,
+ 0xb7c6, 0x071c,
+ 0xb7ce, 0x1df6,
+ 0xb7cf, 0x0725,
+ 0xb7d2, 0x1df7,
+ 0xb7d3, 0x0729,
+ 0xb7d5, 0x1df8,
+ 0xb7d6, 0x072c,
+ 0xb7db, 0x1c0d,
+ 0xb7dc, 0x0732,
+ 0xb7e4, 0x1df9,
+ 0xb7e5, 0x073b,
+ 0xb7f1, 0x1dfa,
+ 0xb7f2, 0x0748,
+ 0xb7f9, 0x1dfb,
+ 0xb7fa, 0x0750,
+ 0xb7fe, 0x1dfc,
+ 0xb8a1, 0x0755,
+ 0xb8b4, 0x1dfd,
+ 0xb8b5, 0x0769,
+ 0xb8c1, 0x1dfe,
+ 0xb8c2, 0x0776,
+ 0xb9a1, 0x07b3,
+ 0xb9ab, 0x1dff,
+ 0xb9ac, 0x07be,
+ 0xb9b7, 0x1e00,
+ 0xb9b8, 0x07ca,
+ 0xb9c2, 0x1e01,
+ 0xb9c3, 0x07d5,
+ 0xb9dc, 0x16dd,
+ 0xb9dd, 0x07ef,
+ 0xb9ed, 0x1e02,
+ 0xb9ee, 0x0800,
+ 0xb9f4, 0x1e03,
+ 0xb9f5, 0x0807,
+ 0xb9f9, 0x1e04,
+ 0xb9fa, 0x080c,
+ 0xbaa1, 0x0811,
+ 0xbad3, 0x1e05,
+ 0xbad4, 0x0844,
+ 0xbae7, 0x1e06,
+ 0xbae8, 0x0858,
+ 0xbaf4, 0x1e07,
+ 0xbaf5, 0x0865,
+ 0xbba1, 0x086f,
+ 0xbba7, 0x1e08,
+ 0xbba8, 0x0876,
+ 0xbbaa, 0x1e09,
+ 0xbbab, 0x0879,
+ 0xbbac, 0x1e0a,
+ 0xbbad, 0x087b,
+ 0xbbb9, 0x1e0b,
+ 0xbbba, 0x0888,
+ 0xbca1, 0x08cd,
+ 0xbcc8, 0x1e0d,
+ 0xbcc9, 0x1929,
+ 0xbcca, 0x08f6,
+ 0xbcd7, 0x1e0e,
+ 0xbcd8, 0x0904,
+ 0xbcdd, 0x1e0f,
+ 0xbcdf, 0x090b,
+ 0xbda1, 0x092b,
+ 0xbdab, 0x1e11,
+ 0xbdac, 0x0936,
+ 0xbdb6, 0x1e12,
+ 0xbdb7, 0x0941,
+ 0xbdec, 0x1e13,
+ 0xbdee, 0x0978,
+ 0xbdf2, 0x1e15,
+ 0xbdf4, 0x097e,
+ 0xbea1, 0x0989,
+ 0xbea5, 0x1e17,
+ 0xbea6, 0x098e,
+ 0xbeb3, 0x1e18,
+ 0xbeb4, 0x099c,
+ 0xbebf, 0x1e19,
+ 0xbec0, 0x09a8,
+ 0xbed5, 0x1e1a,
+ 0xbed6, 0x09be,
+ 0xbedf, 0x1e1b,
+ 0xbee0, 0x09c8,
+ 0xbee4, 0x1e1c,
+ 0xbee5, 0x09cd,
+ 0xbfa1, 0x09e7,
+ 0xbfaa, 0x1e1d,
+ 0xbfab, 0x09f1,
+ 0xbfd9, 0x1e1e,
+ 0xbfda, 0x0a20,
+ 0xbfe0, 0x1e1f,
+ 0xbfe1, 0x0a27,
+ 0xbfe9, 0x1e20,
+ 0xbfea, 0x0a30,
+ 0xc0a1, 0x0a45,
+ 0xc0a2, 0x1e21,
+ 0xc0a3, 0x0a47,
+ 0xc0c2, 0x1e22,
+ 0xc0c3, 0x0a67,
+ 0xc0e6, 0x1e23,
+ 0xc0e7, 0x0a8b,
+ 0xc0f1, 0x1e24,
+ 0xc0f3, 0x0a97,
+ 0xc0f9, 0x1e26,
+ 0xc0fb, 0x0a9f,
+ 0xc1a1, 0x0aa3,
+ 0xc1a7, 0x1e28,
+ 0xc1a8, 0x1a6e,
+ 0xc1a9, 0x0aab,
+ 0xc1b9, 0x1e29,
+ 0xc1ba, 0x0abc,
+ 0xc1cc, 0x1e2a,
+ 0xc1cd, 0x0acf,
+ 0xc1cf, 0x1e2b,
+ 0xc1d0, 0x0ad2,
+ 0xc1df, 0x1e2c,
+ 0xc1e0, 0x0ae2,
+ 0xc1e9, 0x1e2d,
+ 0xc1ea, 0x0aec,
+ 0xc2a1, 0x0b01,
+ 0xc2bd, 0x1e2e,
+ 0xc2be, 0x0b1e,
+ 0xc2cd, 0x1e2f,
+ 0xc2ce, 0x0b2e,
+ 0xc2dc, 0x1e30,
+ 0xc2dd, 0x0b3d,
+ 0xc2e3, 0x1e31,
+ 0xc2e4, 0x0b44,
+ 0xc2ef, 0x1e32,
+ 0xc2f0, 0x0b50,
+ 0xc2f5, 0x1e33,
+ 0xc2f7, 0x0b57,
+ 0xc2fd, 0x1e35,
+ 0xc2fe, 0x0b5e,
+ 0xc3a1, 0x0b5f,
+ 0xc3a7, 0x1e36,
+ 0xc3a8, 0x0b66,
+ 0xc3a9, 0x1e37,
+ 0xc3ab, 0x0b69,
+ 0xc3ad, 0x1e39,
+ 0xc3af, 0x0b6d,
+ 0xc3bd, 0x1e3b,
+ 0xc3be, 0x0b7c,
+ 0xc3f0, 0x1e3c,
+ 0xc3f1, 0x0baf,
+ 0xc3f5, 0x1e3d,
+ 0xc3f6, 0x0bb4,
+ 0xc3fc, 0x1e3e,
+ 0xc3fd, 0x0bbb,
+ 0xc4a1, 0x0bbd,
+ 0xc4bd, 0x1e3f,
+ 0xc4be, 0x0bda,
+ 0xc4c8, 0x1e40,
+ 0xc4c9, 0x0be5,
+ 0xc4ca, 0x1e41,
+ 0xc4cb, 0x0be7,
+ 0xc4cd, 0x1e42,
+ 0xc4ce, 0x0bea,
+ 0xc4cf, 0x1e43,
+ 0xc4d0, 0x0bec,
+ 0xc4d4, 0x204b,
+ 0xc4d5, 0x0bf1,
+ 0xc4db, 0x11b5,
+ 0xc4dc, 0x0bf8,
+ 0xc5a1, 0x0c1b,
+ 0xc5a2, 0x1e44,
+ 0xc5a3, 0x0c1d,
+ 0xc5a7, 0x1e45,
+ 0xc5a8, 0x0c22,
+ 0xc5ae, 0x1e46,
+ 0xc5af, 0x0c29,
+ 0xc5b6, 0x1e47,
+ 0xc5b7, 0x0c31,
+ 0xc5bf, 0x1e48,
+ 0xc5c0, 0x0c3a,
+ 0xc5c8, 0x1e49,
+ 0xc5c9, 0x0c43,
+ 0xc5cb, 0x1e4a,
+ 0xc5cc, 0x0c46,
+ 0xc5d1, 0x1e4b,
+ 0xc5d3, 0x0c4d,
+ 0xc5d7, 0x16df,
+ 0xc5d8, 0x0c52,
+ 0xc5e4, 0x1e4d,
+ 0xc5e5, 0x0c5f,
+ 0xc5ee, 0x1450,
+ 0xc5ef, 0x0c69,
+ 0xc5f3, 0x1536,
+ 0xc5f4, 0x0c6e,
+ 0xc5f8, 0x1e4e,
+ 0xc5f9, 0x0c73,
+ 0xc6a1, 0x0c79,
+ 0xc6be, 0x1e4f,
+ 0xc6bf, 0x0c97,
+ 0xc6c2, 0x1e50,
+ 0xc6c3, 0x0c9b,
+ 0xc6d4, 0x1e51,
+ 0xc6d6, 0x0cae,
+ 0xc6db, 0x1e53,
+ 0xc6dd, 0x0cb5,
+ 0xc6e1, 0x1e55,
+ 0xc6e2, 0x0cba,
+ 0xc6e6, 0x1e56,
+ 0xc6e8, 0x0cc0,
+ 0xc6ea, 0x1e58,
+ 0xc6eb, 0x0cc3,
+ 0xc6f6, 0x1aed,
+ 0xc6f7, 0x0ccf,
+ 0xc7a1, 0x0cd7,
+ 0xc7a9, 0x1e59,
+ 0xc7aa, 0x0ce0,
+ 0xc7b9, 0x1e5a,
+ 0xc7ba, 0x0cf0,
+ 0xc7d7, 0x1e5b,
+ 0xc7d8, 0x0d0e,
+ 0xc7e7, 0x1e5c,
+ 0xc7e8, 0x1989,
+ 0xc7e9, 0x1e5d,
+ 0xc7ea, 0x0d20,
+ 0xc7ed, 0x1e5e,
+ 0xc7ee, 0x0d24,
+ 0xc8a1, 0x0d35,
+ 0xc8a4, 0x1e5f,
+ 0xc8a5, 0x0d39,
+ 0xc8ae, 0x1e60,
+ 0xc8af, 0x0d43,
+ 0xc8b0, 0x1e61,
+ 0xc8b1, 0x0d45,
+ 0xc8d4, 0x1e62,
+ 0xc8d5, 0x0d69,
+ 0xc8e2, 0x1e63,
+ 0xc8e3, 0x0d77,
+ 0xc8f5, 0x1e64,
+ 0xc8f6, 0x0d8a,
+ 0xc9a1, 0x0d93,
+ 0xc9a2, 0x1e65,
+ 0xc9a4, 0x0d96,
+ 0xc9af, 0x1e67,
+ 0xc9b0, 0x143b,
+ 0xc9b1, 0x0da3,
+ 0xc9b2, 0x1e68,
+ 0xc9b3, 0x0da5,
+ 0xc9b5, 0x1e69,
+ 0xc9b6, 0x0da8,
+ 0xc9c0, 0x1e6a,
+ 0xc9c1, 0x0db3,
+ 0xc9ce, 0x1e6b,
+ 0xc9cf, 0x0dc1,
+ 0xc9d1, 0x1e6c,
+ 0xc9d2, 0x0dc4,
+ 0xcaa1, 0x0df1,
+ 0xcac3, 0x1e6d,
+ 0xcac4, 0x0e14,
+ 0xcacd, 0x1e6e,
+ 0xcace, 0x0e1e,
+ 0xcada, 0x1e6f,
+ 0xcadb, 0x0e2b,
+ 0xcaf9, 0x1e70,
+ 0xcafa, 0x0e4a,
+ 0xcba1, 0x0e4f,
+ 0xcba2, 0x1e71,
+ 0xcba3, 0x0e51,
+ 0xcba9, 0x1e72,
+ 0xcbaa, 0x0e58,
+ 0xcbcb, 0x1e73,
+ 0xcbcc, 0x0e7a,
+ 0xcbea, 0x1d33,
+ 0xcbeb, 0x0e99,
+ 0xcbf0, 0x1e74,
+ 0xcbf1, 0x0e9f,
+ 0xcbf8, 0x1f2c,
+ 0xcbf9, 0x102f,
+ 0xcbfa, 0x0ea8,
+ 0xcca1, 0x0ead,
+ 0xcccd, 0x1e75,
+ 0xccce, 0x0eda,
+ 0xccd9, 0x1e76,
+ 0xccda, 0x0ee6,
+ 0xccdf, 0x1e77,
+ 0xcce0, 0x0eec,
+ 0xcce2, 0x1e78,
+ 0xcce3, 0x0eef,
+ 0xccf9, 0x1935,
+ 0xccfa, 0x1e79,
+ 0xccfb, 0x0f07,
+ 0xccfc, 0x1e7a,
+ 0xccfd, 0x0f09,
+ 0xccfe, 0x1e7b,
+ 0xcda1, 0x0f0b,
+ 0xcdb2, 0x1e7c,
+ 0xcdb3, 0x0f1d,
+ 0xcdd0, 0x1e7d,
+ 0xcdd1, 0x0f3b,
+ 0xcdd4, 0x1e7e,
+ 0xcdd5, 0x0f3f,
+ 0xcdda, 0x1d34,
+ 0xcddb, 0x0f45,
+ 0xcde9, 0x1e7f,
+ 0xcdea, 0x0f54,
+ 0xcea1, 0x0f69,
+ 0xcecb, 0x1e80,
+ 0xcecc, 0x0f94,
+ 0xcefa, 0x1e81,
+ 0xcefc, 0x0fc4,
+ 0xcfa1, 0x1e83,
+ 0xcfa2, 0x0fc8,
+ 0xcfb1, 0x1e84,
+ 0xcfb2, 0x0fd8,
+ 0xcfb6, 0x1777,
+ 0xcfb7, 0x0fdd,
+ 0xcfb9, 0x1e85,
+ 0xcfba, 0x0fe0,
+ 0xd0a1, 0x0ffa,
+ 0xd0d6, 0x0ea7,
+ 0xd0d7, 0x1030,
+ 0xd1a1, 0x1058,
+ 0xd1bd, 0x1e86,
+ 0xd1be, 0x1075,
+ 0xd1c7, 0x1e87,
+ 0xd1c8, 0x107f,
+ 0xd1cb, 0x1e88,
+ 0xd1cc, 0x1083,
+ 0xd1cd, 0x1e89,
+ 0xd1ce, 0x1085,
+ 0xd2a1, 0x10b6,
+ 0xd3a1, 0x1114,
+ 0xd3b0, 0x1e8a,
+ 0xd3b1, 0x1124,
+ 0xd3ba, 0x1e8b,
+ 0xd3bb, 0x112e,
+ 0xd3de, 0x1e8d,
+ 0xd3df, 0x1152,
+ 0xd3eb, 0x1e8e,
+ 0xd3ec, 0x115f,
+ 0xd4a1, 0x1172,
+ 0xd4c4, 0x1e8f,
+ 0xd4c5, 0x1196,
+ 0xd4e4, 0x0bf7,
+ 0xd4e5, 0x11b6,
+ 0xd5a1, 0x11d0,
+ 0xd5bd, 0x1e90,
+ 0xd5be, 0x11ed,
+ 0xd5e3, 0x1e91,
+ 0xd5e4, 0x1213,
+ 0xd6a1, 0x122e,
+ 0xd6a2, 0x1e92,
+ 0xd6a3, 0x1230,
+ 0xd7a1, 0x128c,
+ 0xd8a1, 0x12ea,
+ 0xd8a4, 0x1e94,
+ 0xd8a5, 0x12ee,
+ 0xd9a1, 0x1348,
+ 0xd9e0, 0x1e95,
+ 0xd9e1, 0x1388,
+ 0xd9ec, 0x1e96,
+ 0xd9ed, 0x1394,
+ 0xd9f8, 0x05a7,
+ 0xd9f9, 0x13a0,
+ 0xdaa1, 0x13a6,
+ 0xdab9, 0x1e97,
+ 0xdaba, 0x13bf,
+ 0xdacd, 0x1e98,
+ 0xdace, 0x13d3,
+ 0xdba1, 0x1404,
+ 0xdbc5, 0x1e99,
+ 0xdbc6, 0x1429,
+ 0xdbca, 0x1e9a,
+ 0xdbcb, 0x142e,
+ 0xdbd8, 0x0da2,
+ 0xdbd9, 0x143c,
+ 0xdbeb, 0x1e9b,
+ 0xdbec, 0x144f,
+ 0xdbed, 0x0c68,
+ 0xdbee, 0x1451,
+ 0xdbf4, 0x1e9c,
+ 0xdbf5, 0x1458,
+ 0xdca1, 0x1462,
+ 0xdda1, 0x14c0,
+ 0xdea1, 0x151e,
+ 0xdeb9, 0x0c6d,
+ 0xdeba, 0x1537,
+ 0xded0, 0x1e9d,
+ 0xded1, 0x154e,
+ 0xdef5, 0x05ff,
+ 0xdef6, 0x1573,
+ 0xdfa1, 0x157c,
+ 0xe0a1, 0x15da,
+ 0xe0a6, 0x1e9f,
+ 0xe0a7, 0x15e0,
+ 0xe0df, 0x1ea0,
+ 0xe0e0, 0x1619,
+ 0xe0f6, 0x1d35,
+ 0xe0f7, 0x1630,
+ 0xe1a1, 0x1638,
+ 0xe1ab, 0x1ea1,
+ 0xe1ac, 0x1643,
+ 0xe1b0, 0x1ea2,
+ 0xe1b2, 0x1649,
+ 0xe2a1, 0x1696,
+ 0xe2ab, 0x1ea4,
+ 0xe2ac, 0x16a1,
+ 0xe2e8, 0x07ee,
+ 0xe2e9, 0x16de,
+ 0xe2ea, 0x0c51,
+ 0xe2eb, 0x16e0,
+ 0xe2ef, 0x1ea5,
+ 0xe2f0, 0x16e5,
+ 0xe3a1, 0x16f4,
+ 0xe3ca, 0x1ea6,
+ 0xe3cb, 0x171e,
+ 0xe3d4, 0x1ea7,
+ 0xe3d5, 0x1728,
+ 0xe3de, 0x05d4,
+ 0xe3df, 0x1732,
+ 0xe4a1, 0x1752,
+ 0xe4b9, 0x1ea8,
+ 0xe4ba, 0x176b,
+ 0xe4c6, 0x0fdc,
+ 0xe4c7, 0x1778,
+ 0xe4e4, 0x1ea9,
+ 0xe4e5, 0x1796,
+ 0xe4ee, 0x1eaa,
+ 0xe4ef, 0x17a0,
+ 0xe5a1, 0x17b0,
+ 0xe5b9, 0x1eab,
+ 0xe5ba, 0x17c9,
+ 0xe5bb, 0x1eac,
+ 0xe5bc, 0x17cb,
+ 0xe5c6, 0x1ead,
+ 0xe5c7, 0x17d6,
+ 0xe6a1, 0x180e,
+ 0xe6c6, 0x1eae,
+ 0xe6c7, 0x1834,
+ 0xe7a1, 0x186c,
+ 0xe7e4, 0x1eaf,
+ 0xe7e5, 0x18b0,
+ 0xe7e9, 0x1eb0,
+ 0xe7ea, 0x18b5,
+ 0xe7f2, 0x1eb1,
+ 0xe7f3, 0x18be,
+ 0xe8a1, 0x18ca,
+ 0xe8b4, 0x1eb2,
+ 0xe8b5, 0x18de,
+ 0xe8bb, 0x1eb3,
+ 0xe8bc, 0x18e5,
+ 0xe8f4, 0x1eb4,
+ 0xe8f5, 0x191e,
+ 0xe9a1, 0x1928,
+ 0xe9a2, 0x08f5,
+ 0xe9a3, 0x192a,
+ 0xe9ae, 0x0f05,
+ 0xe9af, 0x1936,
+ 0xe9da, 0x05a0,
+ 0xe9db, 0x1962,
+ 0xeaa1, 0x1986,
+ 0xeaa4, 0x0d1e,
+ 0xeaa5, 0x198a,
+ 0xeaa7, 0x1eb6,
+ 0xeaa8, 0x198d,
+ 0xeabd, 0x1eb7,
+ 0xeabe, 0x19a3,
+ 0xeaef, 0x1eb8,
+ 0xeaf0, 0x19d5,
+ 0xeba1, 0x19e4,
+ 0xebb2, 0x1eb9,
+ 0xebb3, 0x19f6,
+ 0xebdd, 0x060e,
+ 0xebde, 0x1a21,
+ 0xebe6, 0x1eba,
+ 0xebe7, 0x1a2a,
+ 0xebf6, 0x1ebb,
+ 0xebf7, 0x1a3a,
+ 0xeca1, 0x1a42,
+ 0xeccd, 0x0aaa,
+ 0xecce, 0x1a6f,
+ 0xece9, 0x1ebc,
+ 0xecea, 0x1a8b,
+ 0xecf4, 0x1ebd,
+ 0xecf5, 0x1a96,
+ 0xeda1, 0x1aa0,
+ 0xedce, 0x1ebe,
+ 0xedcf, 0x1ace,
+ 0xedec, 0x1ebf,
+ 0xeded, 0x1aec,
+ 0xedee, 0x1ec0,
+ 0xedef, 0x1aee,
+ 0xeea1, 0x1afe,
+ 0xeea9, 0x1ec1,
+ 0xeeaa, 0x1b07,
+ 0xeebd, 0x1ec2,
+ 0xeebe, 0x1b1b,
+ 0xeed7, 0x1ec3,
+ 0xeed8, 0x1b35,
+ 0xefa1, 0x1b5c,
+ 0xf0a1, 0x1bba,
+ 0xf0c5, 0x1ec6,
+ 0xf0c6, 0x1bdf,
+ 0xf0d1, 0x1ec7,
+ 0xf0d2, 0x1beb,
+ 0xf0d7, 0x1ec8,
+ 0xf0d8, 0x1bf1,
+ 0xf0f4, 0x0731,
+ 0xf0f5, 0x1ec9,
+ 0xf0f6, 0x1c0f,
+ 0xf1a1, 0x1c18,
+ 0xf2a1, 0x1c76,
+ 0xf2ad, 0x1eca,
+ 0xf2ae, 0x1c83,
+ 0xf2bc, 0x1ecb,
+ 0xf2bd, 0x1c92,
+ 0xf2cd, 0x0477,
+ 0xf2ce, 0x1ecc,
+ 0xf2cf, 0x1ca4,
+ 0xf2f4, 0x0529,
+ 0xf2f5, 0x1cca,
+ 0xf3a1, 0x1cd4,
+ 0xf3d1, 0x1ecd,
+ 0xf3d2, 0x1d05,
+ 0xf3fd, 0x1ece,
+ 0xf3fe, 0x1d31,
+ 0xa1a2, 0x1ecf,
+ 0xa1b1, 0x1ed1,
+ 0xa1bc, 0x1ed3,
+ 0xa1c1, 0x1ed6,
+ 0xa1ca, 0x1edb,
+ 0xa1e1, 0x1eed,
+ 0xa4a1, 0x1eee,
+ 0xa4a3, 0x1eef,
+ 0xa4a5, 0x1ef0,
+ 0xa4a7, 0x1ef1,
+ 0xa4a9, 0x1ef2,
+ 0xa4c3, 0x1ef3,
+ 0xa4e3, 0x1ef4,
+ 0xa4e5, 0x1ef5,
+ 0xa4e7, 0x1ef6,
+ 0xa4ee, 0x1ef7,
+ 0xa5a1, 0x1ef8,
+ 0xa5a3, 0x1ef9,
+ 0xa5a5, 0x1efa,
+ 0xa5a7, 0x1efb,
+ 0xa5a9, 0x1efc,
+ 0xa5c3, 0x1efd,
+ 0xa5e3, 0x1efe,
+ 0xa5e5, 0x1eff,
+ 0xa5e7, 0x1f00,
+ 0xa5ee, 0x1f01,
+ 0xa5f5, 0x1f02,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1278EUCVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1278EUCVMap2, 653
+};
+
+static Gushort japan1278HMap2[1250] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0279,
+ 0x2221, 0x02d7,
+ 0x2330, 0x030c,
+ 0x2341, 0x0316,
+ 0x2361, 0x0330,
+ 0x2421, 0x034a,
+ 0x2521, 0x039d,
+ 0x2621, 0x03f3,
+ 0x2641, 0x040b,
+ 0x2721, 0x0423,
+ 0x2751, 0x0444,
+ 0x3021, 0x0465,
+ 0x3022, 0x1dd1,
+ 0x3023, 0x0467,
+ 0x3029, 0x204a,
+ 0x302a, 0x046e,
+ 0x3032, 0x1f19,
+ 0x3033, 0x1ca2,
+ 0x3034, 0x0478,
+ 0x303b, 0x1dd2,
+ 0x303c, 0x0480,
+ 0x306e, 0x1dd3,
+ 0x306f, 0x04b3,
+ 0x3073, 0x1dd4,
+ 0x3074, 0x04b8,
+ 0x307c, 0x1dd5,
+ 0x307d, 0x04c1,
+ 0x3121, 0x04c3,
+ 0x312a, 0x1dd6,
+ 0x312b, 0x04cd,
+ 0x3135, 0x1dd7,
+ 0x3136, 0x04d8,
+ 0x3139, 0x1dd8,
+ 0x313a, 0x04dc,
+ 0x313d, 0x1dda,
+ 0x313e, 0x04e0,
+ 0x3142, 0x1ddb,
+ 0x3143, 0x04e5,
+ 0x316b, 0x1ddc,
+ 0x316c, 0x050e,
+ 0x3221, 0x0521,
+ 0x3228, 0x1ddd,
+ 0x3229, 0x1cc9,
+ 0x322a, 0x1dde,
+ 0x322b, 0x052b,
+ 0x3260, 0x1ddf,
+ 0x3261, 0x0561,
+ 0x327a, 0x1de0,
+ 0x327b, 0x057b,
+ 0x327d, 0x1de1,
+ 0x327e, 0x057e,
+ 0x3321, 0x057f,
+ 0x3322, 0x1de2,
+ 0x3323, 0x0581,
+ 0x3342, 0x1961,
+ 0x3343, 0x05a1,
+ 0x3349, 0x139f,
+ 0x334a, 0x05a8,
+ 0x3365, 0x1de3,
+ 0x3366, 0x05c4,
+ 0x336b, 0x1de4,
+ 0x336c, 0x05ca,
+ 0x3373, 0x1de5,
+ 0x3374, 0x05d2,
+ 0x3376, 0x1731,
+ 0x3377, 0x05d5,
+ 0x337a, 0x1de6,
+ 0x337b, 0x05d9,
+ 0x3421, 0x05dd,
+ 0x3442, 0x1de7,
+ 0x3443, 0x1572,
+ 0x3444, 0x0600,
+ 0x344d, 0x1de8,
+ 0x344e, 0x060a,
+ 0x3452, 0x1a20,
+ 0x3453, 0x060f,
+ 0x3465, 0x1de9,
+ 0x3466, 0x0622,
+ 0x3521, 0x063b,
+ 0x352b, 0x1dea,
+ 0x352c, 0x0646,
+ 0x3540, 0x1deb,
+ 0x3541, 0x065b,
+ 0x3621, 0x0699,
+ 0x3622, 0x1dec,
+ 0x3623, 0x069b,
+ 0x362a, 0x1ded,
+ 0x362b, 0x06a3,
+ 0x3646, 0x1d32,
+ 0x3647, 0x06bf,
+ 0x364f, 0x1dee,
+ 0x3650, 0x06c8,
+ 0x366d, 0x1def,
+ 0x366e, 0x06e6,
+ 0x3674, 0x1df0,
+ 0x3675, 0x06ed,
+ 0x367b, 0x1df1,
+ 0x367c, 0x06f4,
+ 0x367d, 0x1df2,
+ 0x367e, 0x06f6,
+ 0x3721, 0x06f7,
+ 0x3724, 0x1df3,
+ 0x3725, 0x06fb,
+ 0x3737, 0x1df4,
+ 0x3738, 0x070e,
+ 0x3745, 0x1df5,
+ 0x3746, 0x071c,
+ 0x374e, 0x1df6,
+ 0x374f, 0x0725,
+ 0x3752, 0x1df7,
+ 0x3753, 0x0729,
+ 0x3755, 0x1df8,
+ 0x3756, 0x072c,
+ 0x375b, 0x1c0d,
+ 0x375c, 0x0732,
+ 0x3764, 0x1df9,
+ 0x3765, 0x073b,
+ 0x3771, 0x1dfa,
+ 0x3772, 0x0748,
+ 0x3779, 0x1dfb,
+ 0x377a, 0x0750,
+ 0x377e, 0x1dfc,
+ 0x3821, 0x0755,
+ 0x3834, 0x1dfd,
+ 0x3835, 0x0769,
+ 0x3841, 0x1dfe,
+ 0x3842, 0x0776,
+ 0x3921, 0x07b3,
+ 0x392b, 0x1dff,
+ 0x392c, 0x07be,
+ 0x3937, 0x1e00,
+ 0x3938, 0x07ca,
+ 0x3942, 0x1e01,
+ 0x3943, 0x07d5,
+ 0x395c, 0x16dd,
+ 0x395d, 0x07ef,
+ 0x396d, 0x1e02,
+ 0x396e, 0x0800,
+ 0x3974, 0x1e03,
+ 0x3975, 0x0807,
+ 0x3979, 0x1e04,
+ 0x397a, 0x080c,
+ 0x3a21, 0x0811,
+ 0x3a53, 0x1e05,
+ 0x3a54, 0x0844,
+ 0x3a67, 0x1e06,
+ 0x3a68, 0x0858,
+ 0x3a74, 0x1e07,
+ 0x3a75, 0x0865,
+ 0x3b21, 0x086f,
+ 0x3b27, 0x1e08,
+ 0x3b28, 0x0876,
+ 0x3b2a, 0x1e09,
+ 0x3b2b, 0x0879,
+ 0x3b2c, 0x1e0a,
+ 0x3b2d, 0x087b,
+ 0x3b39, 0x1e0b,
+ 0x3b3a, 0x0888,
+ 0x3c21, 0x08cd,
+ 0x3c48, 0x1e0d,
+ 0x3c49, 0x1929,
+ 0x3c4a, 0x08f6,
+ 0x3c57, 0x1e0e,
+ 0x3c58, 0x0904,
+ 0x3c5d, 0x1e0f,
+ 0x3c5f, 0x090b,
+ 0x3d21, 0x092b,
+ 0x3d2b, 0x1e11,
+ 0x3d2c, 0x0936,
+ 0x3d36, 0x1e12,
+ 0x3d37, 0x0941,
+ 0x3d6c, 0x1e13,
+ 0x3d6e, 0x0978,
+ 0x3d72, 0x1e15,
+ 0x3d74, 0x097e,
+ 0x3e21, 0x0989,
+ 0x3e25, 0x1e17,
+ 0x3e26, 0x098e,
+ 0x3e33, 0x1e18,
+ 0x3e34, 0x099c,
+ 0x3e3f, 0x1e19,
+ 0x3e40, 0x09a8,
+ 0x3e55, 0x1e1a,
+ 0x3e56, 0x09be,
+ 0x3e5f, 0x1e1b,
+ 0x3e60, 0x09c8,
+ 0x3e64, 0x1e1c,
+ 0x3e65, 0x09cd,
+ 0x3f21, 0x09e7,
+ 0x3f2a, 0x1e1d,
+ 0x3f2b, 0x09f1,
+ 0x3f59, 0x1e1e,
+ 0x3f5a, 0x0a20,
+ 0x3f60, 0x1e1f,
+ 0x3f61, 0x0a27,
+ 0x3f69, 0x1e20,
+ 0x3f6a, 0x0a30,
+ 0x4021, 0x0a45,
+ 0x4022, 0x1e21,
+ 0x4023, 0x0a47,
+ 0x4042, 0x1e22,
+ 0x4043, 0x0a67,
+ 0x4066, 0x1e23,
+ 0x4067, 0x0a8b,
+ 0x4071, 0x1e24,
+ 0x4073, 0x0a97,
+ 0x4079, 0x1e26,
+ 0x407b, 0x0a9f,
+ 0x4121, 0x0aa3,
+ 0x4127, 0x1e28,
+ 0x4128, 0x1a6e,
+ 0x4129, 0x0aab,
+ 0x4139, 0x1e29,
+ 0x413a, 0x0abc,
+ 0x414c, 0x1e2a,
+ 0x414d, 0x0acf,
+ 0x414f, 0x1e2b,
+ 0x4150, 0x0ad2,
+ 0x415f, 0x1e2c,
+ 0x4160, 0x0ae2,
+ 0x4169, 0x1e2d,
+ 0x416a, 0x0aec,
+ 0x4221, 0x0b01,
+ 0x423d, 0x1e2e,
+ 0x423e, 0x0b1e,
+ 0x424d, 0x1e2f,
+ 0x424e, 0x0b2e,
+ 0x425c, 0x1e30,
+ 0x425d, 0x0b3d,
+ 0x4263, 0x1e31,
+ 0x4264, 0x0b44,
+ 0x426f, 0x1e32,
+ 0x4270, 0x0b50,
+ 0x4275, 0x1e33,
+ 0x4277, 0x0b57,
+ 0x427d, 0x1e35,
+ 0x427e, 0x0b5e,
+ 0x4321, 0x0b5f,
+ 0x4327, 0x1e36,
+ 0x4328, 0x0b66,
+ 0x4329, 0x1e37,
+ 0x432b, 0x0b69,
+ 0x432d, 0x1e39,
+ 0x432f, 0x0b6d,
+ 0x433d, 0x1e3b,
+ 0x433e, 0x0b7c,
+ 0x4370, 0x1e3c,
+ 0x4371, 0x0baf,
+ 0x4375, 0x1e3d,
+ 0x4376, 0x0bb4,
+ 0x437c, 0x1e3e,
+ 0x437d, 0x0bbb,
+ 0x4421, 0x0bbd,
+ 0x443d, 0x1e3f,
+ 0x443e, 0x0bda,
+ 0x4448, 0x1e40,
+ 0x4449, 0x0be5,
+ 0x444a, 0x1e41,
+ 0x444b, 0x0be7,
+ 0x444d, 0x1e42,
+ 0x444e, 0x0bea,
+ 0x444f, 0x1e43,
+ 0x4450, 0x0bec,
+ 0x4454, 0x204b,
+ 0x4455, 0x0bf1,
+ 0x445b, 0x11b5,
+ 0x445c, 0x0bf8,
+ 0x4521, 0x0c1b,
+ 0x4522, 0x1e44,
+ 0x4523, 0x0c1d,
+ 0x4527, 0x1e45,
+ 0x4528, 0x0c22,
+ 0x452e, 0x1e46,
+ 0x452f, 0x0c29,
+ 0x4536, 0x1e47,
+ 0x4537, 0x0c31,
+ 0x453f, 0x1e48,
+ 0x4540, 0x0c3a,
+ 0x4548, 0x1e49,
+ 0x4549, 0x0c43,
+ 0x454b, 0x1e4a,
+ 0x454c, 0x0c46,
+ 0x4551, 0x1e4b,
+ 0x4553, 0x0c4d,
+ 0x4557, 0x16df,
+ 0x4558, 0x0c52,
+ 0x4564, 0x1e4d,
+ 0x4565, 0x0c5f,
+ 0x456e, 0x1450,
+ 0x456f, 0x0c69,
+ 0x4573, 0x1536,
+ 0x4574, 0x0c6e,
+ 0x4578, 0x1e4e,
+ 0x4579, 0x0c73,
+ 0x4621, 0x0c79,
+ 0x463e, 0x1e4f,
+ 0x463f, 0x0c97,
+ 0x4642, 0x1e50,
+ 0x4643, 0x0c9b,
+ 0x4654, 0x1e51,
+ 0x4656, 0x0cae,
+ 0x465b, 0x1e53,
+ 0x465d, 0x0cb5,
+ 0x4661, 0x1e55,
+ 0x4662, 0x0cba,
+ 0x4666, 0x1e56,
+ 0x4668, 0x0cc0,
+ 0x466a, 0x1e58,
+ 0x466b, 0x0cc3,
+ 0x4676, 0x1aed,
+ 0x4677, 0x0ccf,
+ 0x4721, 0x0cd7,
+ 0x4729, 0x1e59,
+ 0x472a, 0x0ce0,
+ 0x4739, 0x1e5a,
+ 0x473a, 0x0cf0,
+ 0x4757, 0x1e5b,
+ 0x4758, 0x0d0e,
+ 0x4767, 0x1e5c,
+ 0x4768, 0x1989,
+ 0x4769, 0x1e5d,
+ 0x476a, 0x0d20,
+ 0x476d, 0x1e5e,
+ 0x476e, 0x0d24,
+ 0x4821, 0x0d35,
+ 0x4824, 0x1e5f,
+ 0x4825, 0x0d39,
+ 0x482e, 0x1e60,
+ 0x482f, 0x0d43,
+ 0x4830, 0x1e61,
+ 0x4831, 0x0d45,
+ 0x4854, 0x1e62,
+ 0x4855, 0x0d69,
+ 0x4862, 0x1e63,
+ 0x4863, 0x0d77,
+ 0x4875, 0x1e64,
+ 0x4876, 0x0d8a,
+ 0x4921, 0x0d93,
+ 0x4922, 0x1e65,
+ 0x4924, 0x0d96,
+ 0x492f, 0x1e67,
+ 0x4930, 0x143b,
+ 0x4931, 0x0da3,
+ 0x4932, 0x1e68,
+ 0x4933, 0x0da5,
+ 0x4935, 0x1e69,
+ 0x4936, 0x0da8,
+ 0x4940, 0x1e6a,
+ 0x4941, 0x0db3,
+ 0x494e, 0x1e6b,
+ 0x494f, 0x0dc1,
+ 0x4951, 0x1e6c,
+ 0x4952, 0x0dc4,
+ 0x4a21, 0x0df1,
+ 0x4a43, 0x1e6d,
+ 0x4a44, 0x0e14,
+ 0x4a4d, 0x1e6e,
+ 0x4a4e, 0x0e1e,
+ 0x4a5a, 0x1e6f,
+ 0x4a5b, 0x0e2b,
+ 0x4a79, 0x1e70,
+ 0x4a7a, 0x0e4a,
+ 0x4b21, 0x0e4f,
+ 0x4b22, 0x1e71,
+ 0x4b23, 0x0e51,
+ 0x4b29, 0x1e72,
+ 0x4b2a, 0x0e58,
+ 0x4b4b, 0x1e73,
+ 0x4b4c, 0x0e7a,
+ 0x4b6a, 0x1d33,
+ 0x4b6b, 0x0e99,
+ 0x4b70, 0x1e74,
+ 0x4b71, 0x0e9f,
+ 0x4b78, 0x1f2c,
+ 0x4b79, 0x102f,
+ 0x4b7a, 0x0ea8,
+ 0x4c21, 0x0ead,
+ 0x4c4d, 0x1e75,
+ 0x4c4e, 0x0eda,
+ 0x4c59, 0x1e76,
+ 0x4c5a, 0x0ee6,
+ 0x4c5f, 0x1e77,
+ 0x4c60, 0x0eec,
+ 0x4c62, 0x1e78,
+ 0x4c63, 0x0eef,
+ 0x4c79, 0x1935,
+ 0x4c7a, 0x1e79,
+ 0x4c7b, 0x0f07,
+ 0x4c7c, 0x1e7a,
+ 0x4c7d, 0x0f09,
+ 0x4c7e, 0x1e7b,
+ 0x4d21, 0x0f0b,
+ 0x4d32, 0x1e7c,
+ 0x4d33, 0x0f1d,
+ 0x4d50, 0x1e7d,
+ 0x4d51, 0x0f3b,
+ 0x4d54, 0x1e7e,
+ 0x4d55, 0x0f3f,
+ 0x4d5a, 0x1d34,
+ 0x4d5b, 0x0f45,
+ 0x4d69, 0x1e7f,
+ 0x4d6a, 0x0f54,
+ 0x4e21, 0x0f69,
+ 0x4e4b, 0x1e80,
+ 0x4e4c, 0x0f94,
+ 0x4e7a, 0x1e81,
+ 0x4e7c, 0x0fc4,
+ 0x4f21, 0x1e83,
+ 0x4f22, 0x0fc8,
+ 0x4f31, 0x1e84,
+ 0x4f32, 0x0fd8,
+ 0x4f36, 0x1777,
+ 0x4f37, 0x0fdd,
+ 0x4f39, 0x1e85,
+ 0x4f3a, 0x0fe0,
+ 0x5021, 0x0ffa,
+ 0x5056, 0x0ea7,
+ 0x5057, 0x1030,
+ 0x5121, 0x1058,
+ 0x513d, 0x1e86,
+ 0x513e, 0x1075,
+ 0x5147, 0x1e87,
+ 0x5148, 0x107f,
+ 0x514b, 0x1e88,
+ 0x514c, 0x1083,
+ 0x514d, 0x1e89,
+ 0x514e, 0x1085,
+ 0x5221, 0x10b6,
+ 0x5321, 0x1114,
+ 0x5330, 0x1e8a,
+ 0x5331, 0x1124,
+ 0x533a, 0x1e8b,
+ 0x533b, 0x112e,
+ 0x535e, 0x1e8d,
+ 0x535f, 0x1152,
+ 0x536b, 0x1e8e,
+ 0x536c, 0x115f,
+ 0x5421, 0x1172,
+ 0x5444, 0x1e8f,
+ 0x5445, 0x1196,
+ 0x5464, 0x0bf7,
+ 0x5465, 0x11b6,
+ 0x5521, 0x11d0,
+ 0x553d, 0x1e90,
+ 0x553e, 0x11ed,
+ 0x5563, 0x1e91,
+ 0x5564, 0x1213,
+ 0x5621, 0x122e,
+ 0x5622, 0x1e92,
+ 0x5623, 0x1230,
+ 0x5721, 0x128c,
+ 0x5821, 0x12ea,
+ 0x5824, 0x1e94,
+ 0x5825, 0x12ee,
+ 0x5921, 0x1348,
+ 0x5960, 0x1e95,
+ 0x5961, 0x1388,
+ 0x596c, 0x1e96,
+ 0x596d, 0x1394,
+ 0x5978, 0x05a7,
+ 0x5979, 0x13a0,
+ 0x5a21, 0x13a6,
+ 0x5a39, 0x1e97,
+ 0x5a3a, 0x13bf,
+ 0x5a4d, 0x1e98,
+ 0x5a4e, 0x13d3,
+ 0x5b21, 0x1404,
+ 0x5b45, 0x1e99,
+ 0x5b46, 0x1429,
+ 0x5b4a, 0x1e9a,
+ 0x5b4b, 0x142e,
+ 0x5b58, 0x0da2,
+ 0x5b59, 0x143c,
+ 0x5b6b, 0x1e9b,
+ 0x5b6c, 0x144f,
+ 0x5b6d, 0x0c68,
+ 0x5b6e, 0x1451,
+ 0x5b74, 0x1e9c,
+ 0x5b75, 0x1458,
+ 0x5c21, 0x1462,
+ 0x5d21, 0x14c0,
+ 0x5e21, 0x151e,
+ 0x5e39, 0x0c6d,
+ 0x5e3a, 0x1537,
+ 0x5e50, 0x1e9d,
+ 0x5e51, 0x154e,
+ 0x5e75, 0x05ff,
+ 0x5e76, 0x1573,
+ 0x5f21, 0x157c,
+ 0x6021, 0x15da,
+ 0x6026, 0x1e9f,
+ 0x6027, 0x15e0,
+ 0x605f, 0x1ea0,
+ 0x6060, 0x1619,
+ 0x6076, 0x1d35,
+ 0x6077, 0x1630,
+ 0x6121, 0x1638,
+ 0x612b, 0x1ea1,
+ 0x612c, 0x1643,
+ 0x6130, 0x1ea2,
+ 0x6132, 0x1649,
+ 0x6221, 0x1696,
+ 0x622b, 0x1ea4,
+ 0x622c, 0x16a1,
+ 0x6268, 0x07ee,
+ 0x6269, 0x16de,
+ 0x626a, 0x0c51,
+ 0x626b, 0x16e0,
+ 0x626f, 0x1ea5,
+ 0x6270, 0x16e5,
+ 0x6321, 0x16f4,
+ 0x634a, 0x1ea6,
+ 0x634b, 0x171e,
+ 0x6354, 0x1ea7,
+ 0x6355, 0x1728,
+ 0x635e, 0x05d4,
+ 0x635f, 0x1732,
+ 0x6421, 0x1752,
+ 0x6439, 0x1ea8,
+ 0x643a, 0x176b,
+ 0x6446, 0x0fdc,
+ 0x6447, 0x1778,
+ 0x6464, 0x1ea9,
+ 0x6465, 0x1796,
+ 0x646e, 0x1eaa,
+ 0x646f, 0x17a0,
+ 0x6521, 0x17b0,
+ 0x6539, 0x1eab,
+ 0x653a, 0x17c9,
+ 0x653b, 0x1eac,
+ 0x653c, 0x17cb,
+ 0x6546, 0x1ead,
+ 0x6547, 0x17d6,
+ 0x6621, 0x180e,
+ 0x6646, 0x1eae,
+ 0x6647, 0x1834,
+ 0x6721, 0x186c,
+ 0x6764, 0x1eaf,
+ 0x6765, 0x18b0,
+ 0x6769, 0x1eb0,
+ 0x676a, 0x18b5,
+ 0x6772, 0x1eb1,
+ 0x6773, 0x18be,
+ 0x6821, 0x18ca,
+ 0x6834, 0x1eb2,
+ 0x6835, 0x18de,
+ 0x683b, 0x1eb3,
+ 0x683c, 0x18e5,
+ 0x6874, 0x1eb4,
+ 0x6875, 0x191e,
+ 0x6921, 0x1928,
+ 0x6922, 0x08f5,
+ 0x6923, 0x192a,
+ 0x692e, 0x0f05,
+ 0x692f, 0x1936,
+ 0x695a, 0x05a0,
+ 0x695b, 0x1962,
+ 0x6a21, 0x1986,
+ 0x6a24, 0x0d1e,
+ 0x6a25, 0x198a,
+ 0x6a27, 0x1eb6,
+ 0x6a28, 0x198d,
+ 0x6a3d, 0x1eb7,
+ 0x6a3e, 0x19a3,
+ 0x6a6f, 0x1eb8,
+ 0x6a70, 0x19d5,
+ 0x6b21, 0x19e4,
+ 0x6b32, 0x1eb9,
+ 0x6b33, 0x19f6,
+ 0x6b5d, 0x060e,
+ 0x6b5e, 0x1a21,
+ 0x6b66, 0x1eba,
+ 0x6b67, 0x1a2a,
+ 0x6b76, 0x1ebb,
+ 0x6b77, 0x1a3a,
+ 0x6c21, 0x1a42,
+ 0x6c4d, 0x0aaa,
+ 0x6c4e, 0x1a6f,
+ 0x6c69, 0x1ebc,
+ 0x6c6a, 0x1a8b,
+ 0x6c74, 0x1ebd,
+ 0x6c75, 0x1a96,
+ 0x6d21, 0x1aa0,
+ 0x6d4e, 0x1ebe,
+ 0x6d4f, 0x1ace,
+ 0x6d6c, 0x1ebf,
+ 0x6d6d, 0x1aec,
+ 0x6d6e, 0x1ec0,
+ 0x6d6f, 0x1aee,
+ 0x6e21, 0x1afe,
+ 0x6e29, 0x1ec1,
+ 0x6e2a, 0x1b07,
+ 0x6e3d, 0x1ec2,
+ 0x6e3e, 0x1b1b,
+ 0x6e57, 0x1ec3,
+ 0x6e58, 0x1b35,
+ 0x6f21, 0x1b5c,
+ 0x7021, 0x1bba,
+ 0x7045, 0x1ec6,
+ 0x7046, 0x1bdf,
+ 0x7051, 0x1ec7,
+ 0x7052, 0x1beb,
+ 0x7057, 0x1ec8,
+ 0x7058, 0x1bf1,
+ 0x7074, 0x0731,
+ 0x7075, 0x1ec9,
+ 0x7076, 0x1c0f,
+ 0x7121, 0x1c18,
+ 0x7221, 0x1c76,
+ 0x722d, 0x1eca,
+ 0x722e, 0x1c83,
+ 0x723c, 0x1ecb,
+ 0x723d, 0x1c92,
+ 0x724d, 0x0477,
+ 0x724e, 0x1ecc,
+ 0x724f, 0x1ca4,
+ 0x7274, 0x0529,
+ 0x7275, 0x1cca,
+ 0x7321, 0x1cd4,
+ 0x7351, 0x1ecd,
+ 0x7352, 0x1d05,
+ 0x737d, 0x1ece,
+ 0x737e, 0x1d31,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1278HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1278HMap2, 625
+};
+
+static Gushort japan1278RKSJHMap2[1252] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x889f, 0x0465,
+ 0x88a0, 0x1dd1,
+ 0x88a1, 0x0467,
+ 0x88a7, 0x204a,
+ 0x88a8, 0x046e,
+ 0x88b0, 0x1f19,
+ 0x88b1, 0x1ca2,
+ 0x88b2, 0x0478,
+ 0x88b9, 0x1dd2,
+ 0x88ba, 0x0480,
+ 0x88ec, 0x1dd3,
+ 0x88ed, 0x04b3,
+ 0x88f1, 0x1dd4,
+ 0x88f2, 0x04b8,
+ 0x88fa, 0x1dd5,
+ 0x88fb, 0x04c1,
+ 0x8940, 0x04c3,
+ 0x8949, 0x1dd6,
+ 0x894a, 0x04cd,
+ 0x8954, 0x1dd7,
+ 0x8955, 0x04d8,
+ 0x8958, 0x1dd8,
+ 0x8959, 0x04dc,
+ 0x895c, 0x1dda,
+ 0x895d, 0x04e0,
+ 0x8961, 0x1ddb,
+ 0x8962, 0x04e5,
+ 0x8980, 0x0502,
+ 0x898b, 0x1ddc,
+ 0x898c, 0x050e,
+ 0x89a6, 0x1ddd,
+ 0x89a7, 0x1cc9,
+ 0x89a8, 0x1dde,
+ 0x89a9, 0x052b,
+ 0x89de, 0x1ddf,
+ 0x89df, 0x0561,
+ 0x89f8, 0x1de0,
+ 0x89f9, 0x057b,
+ 0x89fb, 0x1de1,
+ 0x89fc, 0x057e,
+ 0x8a40, 0x057f,
+ 0x8a41, 0x1de2,
+ 0x8a42, 0x0581,
+ 0x8a61, 0x1961,
+ 0x8a62, 0x05a1,
+ 0x8a68, 0x139f,
+ 0x8a69, 0x05a8,
+ 0x8a80, 0x05be,
+ 0x8a85, 0x1de3,
+ 0x8a86, 0x05c4,
+ 0x8a8b, 0x1de4,
+ 0x8a8c, 0x05ca,
+ 0x8a93, 0x1de5,
+ 0x8a94, 0x05d2,
+ 0x8a96, 0x1731,
+ 0x8a97, 0x05d5,
+ 0x8a9a, 0x1de6,
+ 0x8a9b, 0x05d9,
+ 0x8ac0, 0x1de7,
+ 0x8ac1, 0x1572,
+ 0x8ac2, 0x0600,
+ 0x8acb, 0x1de8,
+ 0x8acc, 0x060a,
+ 0x8ad0, 0x1a20,
+ 0x8ad1, 0x060f,
+ 0x8ae3, 0x1de9,
+ 0x8ae4, 0x0622,
+ 0x8b40, 0x063b,
+ 0x8b4a, 0x1dea,
+ 0x8b4b, 0x0646,
+ 0x8b5f, 0x1deb,
+ 0x8b60, 0x065b,
+ 0x8b80, 0x067a,
+ 0x8ba0, 0x1dec,
+ 0x8ba1, 0x069b,
+ 0x8ba8, 0x1ded,
+ 0x8ba9, 0x06a3,
+ 0x8bc4, 0x1d32,
+ 0x8bc5, 0x06bf,
+ 0x8bcd, 0x1dee,
+ 0x8bce, 0x06c8,
+ 0x8beb, 0x1def,
+ 0x8bec, 0x06e6,
+ 0x8bf2, 0x1df0,
+ 0x8bf3, 0x06ed,
+ 0x8bf9, 0x1df1,
+ 0x8bfa, 0x06f4,
+ 0x8bfb, 0x1df2,
+ 0x8bfc, 0x06f6,
+ 0x8c40, 0x06f7,
+ 0x8c43, 0x1df3,
+ 0x8c44, 0x06fb,
+ 0x8c56, 0x1df4,
+ 0x8c57, 0x070e,
+ 0x8c64, 0x1df5,
+ 0x8c65, 0x071c,
+ 0x8c6d, 0x1df6,
+ 0x8c6e, 0x0725,
+ 0x8c71, 0x1df7,
+ 0x8c72, 0x0729,
+ 0x8c74, 0x1df8,
+ 0x8c75, 0x072c,
+ 0x8c7a, 0x1c0d,
+ 0x8c7b, 0x0732,
+ 0x8c80, 0x0736,
+ 0x8c84, 0x1df9,
+ 0x8c85, 0x073b,
+ 0x8c91, 0x1dfa,
+ 0x8c92, 0x0748,
+ 0x8c99, 0x1dfb,
+ 0x8c9a, 0x0750,
+ 0x8c9e, 0x1dfc,
+ 0x8c9f, 0x0755,
+ 0x8cb2, 0x1dfd,
+ 0x8cb3, 0x0769,
+ 0x8cbf, 0x1dfe,
+ 0x8cc0, 0x0776,
+ 0x8d40, 0x07b3,
+ 0x8d4a, 0x1dff,
+ 0x8d4b, 0x07be,
+ 0x8d56, 0x1e00,
+ 0x8d57, 0x07ca,
+ 0x8d61, 0x1e01,
+ 0x8d62, 0x07d5,
+ 0x8d7b, 0x16dd,
+ 0x8d7c, 0x07ef,
+ 0x8d80, 0x07f2,
+ 0x8d8d, 0x1e02,
+ 0x8d8e, 0x0800,
+ 0x8d94, 0x1e03,
+ 0x8d95, 0x0807,
+ 0x8d99, 0x1e04,
+ 0x8d9a, 0x080c,
+ 0x8dd1, 0x1e05,
+ 0x8dd2, 0x0844,
+ 0x8de5, 0x1e06,
+ 0x8de6, 0x0858,
+ 0x8df2, 0x1e07,
+ 0x8df3, 0x0865,
+ 0x8e40, 0x086f,
+ 0x8e46, 0x1e08,
+ 0x8e47, 0x0876,
+ 0x8e49, 0x1e09,
+ 0x8e4a, 0x0879,
+ 0x8e4b, 0x1e0a,
+ 0x8e4c, 0x087b,
+ 0x8e58, 0x1e0b,
+ 0x8e59, 0x0888,
+ 0x8e80, 0x08ae,
+ 0x8ec6, 0x1e0d,
+ 0x8ec7, 0x1929,
+ 0x8ec8, 0x08f6,
+ 0x8ed5, 0x1e0e,
+ 0x8ed6, 0x0904,
+ 0x8edb, 0x1e0f,
+ 0x8edd, 0x090b,
+ 0x8f40, 0x092b,
+ 0x8f4a, 0x1e11,
+ 0x8f4b, 0x0936,
+ 0x8f55, 0x1e12,
+ 0x8f56, 0x0941,
+ 0x8f80, 0x096a,
+ 0x8f8c, 0x1e13,
+ 0x8f8e, 0x0978,
+ 0x8f92, 0x1e15,
+ 0x8f94, 0x097e,
+ 0x8fa3, 0x1e17,
+ 0x8fa4, 0x098e,
+ 0x8fb1, 0x1e18,
+ 0x8fb2, 0x099c,
+ 0x8fbd, 0x1e19,
+ 0x8fbe, 0x09a8,
+ 0x8fd3, 0x1e1a,
+ 0x8fd4, 0x09be,
+ 0x8fdd, 0x1e1b,
+ 0x8fde, 0x09c8,
+ 0x8fe2, 0x1e1c,
+ 0x8fe3, 0x09cd,
+ 0x9040, 0x09e7,
+ 0x9049, 0x1e1d,
+ 0x904a, 0x09f1,
+ 0x9078, 0x1e1e,
+ 0x9079, 0x0a20,
+ 0x9080, 0x1e1f,
+ 0x9081, 0x0a27,
+ 0x9089, 0x1e20,
+ 0x908a, 0x0a30,
+ 0x90a0, 0x1e21,
+ 0x90a1, 0x0a47,
+ 0x90c0, 0x1e22,
+ 0x90c1, 0x0a67,
+ 0x90e4, 0x1e23,
+ 0x90e5, 0x0a8b,
+ 0x90ef, 0x1e24,
+ 0x90f1, 0x0a97,
+ 0x90f7, 0x1e26,
+ 0x90f9, 0x0a9f,
+ 0x9140, 0x0aa3,
+ 0x9146, 0x1e28,
+ 0x9147, 0x1a6e,
+ 0x9148, 0x0aab,
+ 0x9158, 0x1e29,
+ 0x9159, 0x0abc,
+ 0x916b, 0x1e2a,
+ 0x916c, 0x0acf,
+ 0x916e, 0x1e2b,
+ 0x916f, 0x0ad2,
+ 0x917e, 0x1e2c,
+ 0x9180, 0x0ae2,
+ 0x9189, 0x1e2d,
+ 0x918a, 0x0aec,
+ 0x91bb, 0x1e2e,
+ 0x91bc, 0x0b1e,
+ 0x91cb, 0x1e2f,
+ 0x91cc, 0x0b2e,
+ 0x91da, 0x1e30,
+ 0x91db, 0x0b3d,
+ 0x91e1, 0x1e31,
+ 0x91e2, 0x0b44,
+ 0x91ed, 0x1e32,
+ 0x91ee, 0x0b50,
+ 0x91f3, 0x1e33,
+ 0x91f5, 0x0b57,
+ 0x91fb, 0x1e35,
+ 0x91fc, 0x0b5e,
+ 0x9240, 0x0b5f,
+ 0x9246, 0x1e36,
+ 0x9247, 0x0b66,
+ 0x9248, 0x1e37,
+ 0x924a, 0x0b69,
+ 0x924c, 0x1e39,
+ 0x924e, 0x0b6d,
+ 0x925c, 0x1e3b,
+ 0x925d, 0x0b7c,
+ 0x9280, 0x0b9e,
+ 0x9290, 0x1e3c,
+ 0x9291, 0x0baf,
+ 0x9295, 0x1e3d,
+ 0x9296, 0x0bb4,
+ 0x929c, 0x1e3e,
+ 0x929d, 0x0bbb,
+ 0x92bb, 0x1e3f,
+ 0x92bc, 0x0bda,
+ 0x92c6, 0x1e40,
+ 0x92c7, 0x0be5,
+ 0x92c8, 0x1e41,
+ 0x92c9, 0x0be7,
+ 0x92cb, 0x1e42,
+ 0x92cc, 0x0bea,
+ 0x92cd, 0x1e43,
+ 0x92ce, 0x0bec,
+ 0x92d2, 0x204b,
+ 0x92d3, 0x0bf1,
+ 0x92d9, 0x11b5,
+ 0x92da, 0x0bf8,
+ 0x9340, 0x0c1b,
+ 0x9341, 0x1e44,
+ 0x9342, 0x0c1d,
+ 0x9346, 0x1e45,
+ 0x9347, 0x0c22,
+ 0x934d, 0x1e46,
+ 0x934e, 0x0c29,
+ 0x9355, 0x1e47,
+ 0x9356, 0x0c31,
+ 0x935e, 0x1e48,
+ 0x935f, 0x0c3a,
+ 0x9367, 0x1e49,
+ 0x9368, 0x0c43,
+ 0x936a, 0x1e4a,
+ 0x936b, 0x0c46,
+ 0x9370, 0x1e4b,
+ 0x9372, 0x0c4d,
+ 0x9376, 0x16df,
+ 0x9377, 0x0c52,
+ 0x9380, 0x0c5a,
+ 0x9384, 0x1e4d,
+ 0x9385, 0x0c5f,
+ 0x938e, 0x1450,
+ 0x938f, 0x0c69,
+ 0x9393, 0x1536,
+ 0x9394, 0x0c6e,
+ 0x9398, 0x1e4e,
+ 0x9399, 0x0c73,
+ 0x93bc, 0x1e4f,
+ 0x93bd, 0x0c97,
+ 0x93c0, 0x1e50,
+ 0x93c1, 0x0c9b,
+ 0x93d2, 0x1e51,
+ 0x93d4, 0x0cae,
+ 0x93d9, 0x1e53,
+ 0x93db, 0x0cb5,
+ 0x93df, 0x1e55,
+ 0x93e0, 0x0cba,
+ 0x93e4, 0x1e56,
+ 0x93e6, 0x0cc0,
+ 0x93e8, 0x1e58,
+ 0x93e9, 0x0cc3,
+ 0x93f4, 0x1aed,
+ 0x93f5, 0x0ccf,
+ 0x9440, 0x0cd7,
+ 0x9448, 0x1e59,
+ 0x9449, 0x0ce0,
+ 0x9458, 0x1e5a,
+ 0x9459, 0x0cf0,
+ 0x9476, 0x1e5b,
+ 0x9477, 0x0d0e,
+ 0x9480, 0x0d16,
+ 0x9487, 0x1e5c,
+ 0x9488, 0x1989,
+ 0x9489, 0x1e5d,
+ 0x948a, 0x0d20,
+ 0x948d, 0x1e5e,
+ 0x948e, 0x0d24,
+ 0x94a2, 0x1e5f,
+ 0x94a3, 0x0d39,
+ 0x94ac, 0x1e60,
+ 0x94ad, 0x0d43,
+ 0x94ae, 0x1e61,
+ 0x94af, 0x0d45,
+ 0x94d2, 0x1e62,
+ 0x94d3, 0x0d69,
+ 0x94e0, 0x1e63,
+ 0x94e1, 0x0d77,
+ 0x94f3, 0x1e64,
+ 0x94f4, 0x0d8a,
+ 0x9540, 0x0d93,
+ 0x9541, 0x1e65,
+ 0x9543, 0x0d96,
+ 0x954e, 0x1e67,
+ 0x954f, 0x143b,
+ 0x9550, 0x0da3,
+ 0x9551, 0x1e68,
+ 0x9552, 0x0da5,
+ 0x9554, 0x1e69,
+ 0x9555, 0x0da8,
+ 0x955f, 0x1e6a,
+ 0x9560, 0x0db3,
+ 0x956d, 0x1e6b,
+ 0x956e, 0x0dc1,
+ 0x9570, 0x1e6c,
+ 0x9571, 0x0dc4,
+ 0x9580, 0x0dd2,
+ 0x95c1, 0x1e6d,
+ 0x95c2, 0x0e14,
+ 0x95cb, 0x1e6e,
+ 0x95cc, 0x0e1e,
+ 0x95d8, 0x1e6f,
+ 0x95d9, 0x0e2b,
+ 0x95f7, 0x1e70,
+ 0x95f8, 0x0e4a,
+ 0x9640, 0x0e4f,
+ 0x9641, 0x1e71,
+ 0x9642, 0x0e51,
+ 0x9648, 0x1e72,
+ 0x9649, 0x0e58,
+ 0x966a, 0x1e73,
+ 0x966b, 0x0e7a,
+ 0x9680, 0x0e8e,
+ 0x968a, 0x1d33,
+ 0x968b, 0x0e99,
+ 0x9690, 0x1e74,
+ 0x9691, 0x0e9f,
+ 0x9698, 0x1f2c,
+ 0x9699, 0x102f,
+ 0x969a, 0x0ea8,
+ 0x96cb, 0x1e75,
+ 0x96cc, 0x0eda,
+ 0x96d7, 0x1e76,
+ 0x96d8, 0x0ee6,
+ 0x96dd, 0x1e77,
+ 0x96de, 0x0eec,
+ 0x96e0, 0x1e78,
+ 0x96e1, 0x0eef,
+ 0x96f7, 0x1935,
+ 0x96f8, 0x1e79,
+ 0x96f9, 0x0f07,
+ 0x96fa, 0x1e7a,
+ 0x96fb, 0x0f09,
+ 0x96fc, 0x1e7b,
+ 0x9740, 0x0f0b,
+ 0x9751, 0x1e7c,
+ 0x9752, 0x0f1d,
+ 0x976f, 0x1e7d,
+ 0x9770, 0x0f3b,
+ 0x9773, 0x1e7e,
+ 0x9774, 0x0f3f,
+ 0x9779, 0x1d34,
+ 0x977a, 0x0f45,
+ 0x9780, 0x0f4a,
+ 0x9789, 0x1e7f,
+ 0x978a, 0x0f54,
+ 0x97c9, 0x1e80,
+ 0x97ca, 0x0f94,
+ 0x97f8, 0x1e81,
+ 0x97fa, 0x0fc4,
+ 0x9840, 0x1e83,
+ 0x9841, 0x0fc8,
+ 0x9850, 0x1e84,
+ 0x9851, 0x0fd8,
+ 0x9855, 0x1777,
+ 0x9856, 0x0fdd,
+ 0x9858, 0x1e85,
+ 0x9859, 0x0fe0,
+ 0x989f, 0x0ffa,
+ 0x98d4, 0x0ea7,
+ 0x98d5, 0x1030,
+ 0x9940, 0x1058,
+ 0x995c, 0x1e86,
+ 0x995d, 0x1075,
+ 0x9966, 0x1e87,
+ 0x9967, 0x107f,
+ 0x996a, 0x1e88,
+ 0x996b, 0x1083,
+ 0x996c, 0x1e89,
+ 0x996d, 0x1085,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a4f, 0x1e8a,
+ 0x9a50, 0x1124,
+ 0x9a59, 0x1e8b,
+ 0x9a5a, 0x112e,
+ 0x9a7d, 0x1e8d,
+ 0x9a7e, 0x1152,
+ 0x9a80, 0x1153,
+ 0x9a8b, 0x1e8e,
+ 0x9a8c, 0x115f,
+ 0x9ac2, 0x1e8f,
+ 0x9ac3, 0x1196,
+ 0x9ae2, 0x0bf7,
+ 0x9ae3, 0x11b6,
+ 0x9b40, 0x11d0,
+ 0x9b5c, 0x1e90,
+ 0x9b5d, 0x11ed,
+ 0x9b80, 0x120f,
+ 0x9b83, 0x1e91,
+ 0x9b84, 0x1213,
+ 0x9ba0, 0x1e92,
+ 0x9ba1, 0x1230,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9ca2, 0x1e94,
+ 0x9ca3, 0x12ee,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1e95,
+ 0x9d81, 0x1388,
+ 0x9d8c, 0x1e96,
+ 0x9d8d, 0x1394,
+ 0x9d98, 0x05a7,
+ 0x9d99, 0x13a0,
+ 0x9db7, 0x1e97,
+ 0x9db8, 0x13bf,
+ 0x9dcb, 0x1e98,
+ 0x9dcc, 0x13d3,
+ 0x9e40, 0x1404,
+ 0x9e64, 0x1e99,
+ 0x9e65, 0x1429,
+ 0x9e69, 0x1e9a,
+ 0x9e6a, 0x142e,
+ 0x9e77, 0x0da2,
+ 0x9e78, 0x143c,
+ 0x9e80, 0x1443,
+ 0x9e8b, 0x1e9b,
+ 0x9e8c, 0x144f,
+ 0x9e8d, 0x0c68,
+ 0x9e8e, 0x1451,
+ 0x9e94, 0x1e9c,
+ 0x9e95, 0x1458,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0x9fb7, 0x0c6d,
+ 0x9fb8, 0x1537,
+ 0x9fce, 0x1e9d,
+ 0x9fcf, 0x154e,
+ 0x9ff3, 0x05ff,
+ 0x9ff4, 0x1573,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe0a4, 0x1e9f,
+ 0xe0a5, 0x15e0,
+ 0xe0dd, 0x1ea0,
+ 0xe0de, 0x1619,
+ 0xe0f4, 0x1d35,
+ 0xe0f5, 0x1630,
+ 0xe140, 0x1638,
+ 0xe14a, 0x1ea1,
+ 0xe14b, 0x1643,
+ 0xe14f, 0x1ea2,
+ 0xe151, 0x1649,
+ 0xe180, 0x1677,
+ 0xe1a9, 0x1ea4,
+ 0xe1aa, 0x16a1,
+ 0xe1e6, 0x07ee,
+ 0xe1e7, 0x16de,
+ 0xe1e8, 0x0c51,
+ 0xe1e9, 0x16e0,
+ 0xe1ed, 0x1ea5,
+ 0xe1ee, 0x16e5,
+ 0xe240, 0x16f4,
+ 0xe269, 0x1ea6,
+ 0xe26a, 0x171e,
+ 0xe273, 0x1ea7,
+ 0xe274, 0x1728,
+ 0xe27d, 0x05d4,
+ 0xe27e, 0x1732,
+ 0xe280, 0x1733,
+ 0xe2b7, 0x1ea8,
+ 0xe2b8, 0x176b,
+ 0xe2c4, 0x0fdc,
+ 0xe2c5, 0x1778,
+ 0xe2e2, 0x1ea9,
+ 0xe2e3, 0x1796,
+ 0xe2ec, 0x1eaa,
+ 0xe2ed, 0x17a0,
+ 0xe340, 0x17b0,
+ 0xe358, 0x1eab,
+ 0xe359, 0x17c9,
+ 0xe35a, 0x1eac,
+ 0xe35b, 0x17cb,
+ 0xe365, 0x1ead,
+ 0xe366, 0x17d6,
+ 0xe380, 0x17ef,
+ 0xe3c4, 0x1eae,
+ 0xe3c5, 0x1834,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe484, 0x1eaf,
+ 0xe485, 0x18b0,
+ 0xe489, 0x1eb0,
+ 0xe48a, 0x18b5,
+ 0xe492, 0x1eb1,
+ 0xe493, 0x18be,
+ 0xe4b2, 0x1eb2,
+ 0xe4b3, 0x18de,
+ 0xe4b9, 0x1eb3,
+ 0xe4ba, 0x18e5,
+ 0xe4f2, 0x1eb4,
+ 0xe4f3, 0x191e,
+ 0xe540, 0x1928,
+ 0xe541, 0x08f5,
+ 0xe542, 0x192a,
+ 0xe54d, 0x0f05,
+ 0xe54e, 0x1936,
+ 0xe579, 0x05a0,
+ 0xe57a, 0x1962,
+ 0xe580, 0x1967,
+ 0xe5a2, 0x0d1e,
+ 0xe5a3, 0x198a,
+ 0xe5a5, 0x1eb6,
+ 0xe5a6, 0x198d,
+ 0xe5bb, 0x1eb7,
+ 0xe5bc, 0x19a3,
+ 0xe5ed, 0x1eb8,
+ 0xe5ee, 0x19d5,
+ 0xe640, 0x19e4,
+ 0xe651, 0x1eb9,
+ 0xe652, 0x19f6,
+ 0xe67c, 0x060e,
+ 0xe67d, 0x1a21,
+ 0xe680, 0x1a23,
+ 0xe686, 0x1eba,
+ 0xe687, 0x1a2a,
+ 0xe696, 0x1ebb,
+ 0xe697, 0x1a3a,
+ 0xe6cb, 0x0aaa,
+ 0xe6cc, 0x1a6f,
+ 0xe6e7, 0x1ebc,
+ 0xe6e8, 0x1a8b,
+ 0xe6f2, 0x1ebd,
+ 0xe6f3, 0x1a96,
+ 0xe740, 0x1aa0,
+ 0xe76d, 0x1ebe,
+ 0xe76e, 0x1ace,
+ 0xe780, 0x1adf,
+ 0xe78c, 0x1ebf,
+ 0xe78d, 0x1aec,
+ 0xe78e, 0x1ec0,
+ 0xe78f, 0x1aee,
+ 0xe7a7, 0x1ec1,
+ 0xe7a8, 0x1b07,
+ 0xe7bb, 0x1ec2,
+ 0xe7bc, 0x1b1b,
+ 0xe7d5, 0x1ec3,
+ 0xe7d6, 0x1b35,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe8c3, 0x1ec6,
+ 0xe8c4, 0x1bdf,
+ 0xe8cf, 0x1ec7,
+ 0xe8d0, 0x1beb,
+ 0xe8d5, 0x1ec8,
+ 0xe8d6, 0x1bf1,
+ 0xe8f2, 0x0731,
+ 0xe8f3, 0x1ec9,
+ 0xe8f4, 0x1c0f,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xe9ab, 0x1eca,
+ 0xe9ac, 0x1c83,
+ 0xe9ba, 0x1ecb,
+ 0xe9bb, 0x1c92,
+ 0xe9cb, 0x0477,
+ 0xe9cc, 0x1ecc,
+ 0xe9cd, 0x1ca4,
+ 0xe9f2, 0x0529,
+ 0xe9f3, 0x1cca,
+ 0xea40, 0x1cd4,
+ 0xea70, 0x1ecd,
+ 0xea71, 0x1d05,
+ 0xea80, 0x1d13,
+ 0xea9d, 0x1ece,
+ 0xea9e, 0x1d31,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1278RKSJHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1278RKSJHMap2, 626
+};
+
+static Gushort japan1278RKSJVMap2[1306] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x889f, 0x0465,
+ 0x88a0, 0x1dd1,
+ 0x88a1, 0x0467,
+ 0x88a7, 0x204a,
+ 0x88a8, 0x046e,
+ 0x88b0, 0x1f19,
+ 0x88b1, 0x1ca2,
+ 0x88b2, 0x0478,
+ 0x88b9, 0x1dd2,
+ 0x88ba, 0x0480,
+ 0x88ec, 0x1dd3,
+ 0x88ed, 0x04b3,
+ 0x88f1, 0x1dd4,
+ 0x88f2, 0x04b8,
+ 0x88fa, 0x1dd5,
+ 0x88fb, 0x04c1,
+ 0x8940, 0x04c3,
+ 0x8949, 0x1dd6,
+ 0x894a, 0x04cd,
+ 0x8954, 0x1dd7,
+ 0x8955, 0x04d8,
+ 0x8958, 0x1dd8,
+ 0x8959, 0x04dc,
+ 0x895c, 0x1dda,
+ 0x895d, 0x04e0,
+ 0x8961, 0x1ddb,
+ 0x8962, 0x04e5,
+ 0x8980, 0x0502,
+ 0x898b, 0x1ddc,
+ 0x898c, 0x050e,
+ 0x89a6, 0x1ddd,
+ 0x89a7, 0x1cc9,
+ 0x89a8, 0x1dde,
+ 0x89a9, 0x052b,
+ 0x89de, 0x1ddf,
+ 0x89df, 0x0561,
+ 0x89f8, 0x1de0,
+ 0x89f9, 0x057b,
+ 0x89fb, 0x1de1,
+ 0x89fc, 0x057e,
+ 0x8a40, 0x057f,
+ 0x8a41, 0x1de2,
+ 0x8a42, 0x0581,
+ 0x8a61, 0x1961,
+ 0x8a62, 0x05a1,
+ 0x8a68, 0x139f,
+ 0x8a69, 0x05a8,
+ 0x8a80, 0x05be,
+ 0x8a85, 0x1de3,
+ 0x8a86, 0x05c4,
+ 0x8a8b, 0x1de4,
+ 0x8a8c, 0x05ca,
+ 0x8a93, 0x1de5,
+ 0x8a94, 0x05d2,
+ 0x8a96, 0x1731,
+ 0x8a97, 0x05d5,
+ 0x8a9a, 0x1de6,
+ 0x8a9b, 0x05d9,
+ 0x8ac0, 0x1de7,
+ 0x8ac1, 0x1572,
+ 0x8ac2, 0x0600,
+ 0x8acb, 0x1de8,
+ 0x8acc, 0x060a,
+ 0x8ad0, 0x1a20,
+ 0x8ad1, 0x060f,
+ 0x8ae3, 0x1de9,
+ 0x8ae4, 0x0622,
+ 0x8b40, 0x063b,
+ 0x8b4a, 0x1dea,
+ 0x8b4b, 0x0646,
+ 0x8b5f, 0x1deb,
+ 0x8b60, 0x065b,
+ 0x8b80, 0x067a,
+ 0x8ba0, 0x1dec,
+ 0x8ba1, 0x069b,
+ 0x8ba8, 0x1ded,
+ 0x8ba9, 0x06a3,
+ 0x8bc4, 0x1d32,
+ 0x8bc5, 0x06bf,
+ 0x8bcd, 0x1dee,
+ 0x8bce, 0x06c8,
+ 0x8beb, 0x1def,
+ 0x8bec, 0x06e6,
+ 0x8bf2, 0x1df0,
+ 0x8bf3, 0x06ed,
+ 0x8bf9, 0x1df1,
+ 0x8bfa, 0x06f4,
+ 0x8bfb, 0x1df2,
+ 0x8bfc, 0x06f6,
+ 0x8c40, 0x06f7,
+ 0x8c43, 0x1df3,
+ 0x8c44, 0x06fb,
+ 0x8c56, 0x1df4,
+ 0x8c57, 0x070e,
+ 0x8c64, 0x1df5,
+ 0x8c65, 0x071c,
+ 0x8c6d, 0x1df6,
+ 0x8c6e, 0x0725,
+ 0x8c71, 0x1df7,
+ 0x8c72, 0x0729,
+ 0x8c74, 0x1df8,
+ 0x8c75, 0x072c,
+ 0x8c7a, 0x1c0d,
+ 0x8c7b, 0x0732,
+ 0x8c80, 0x0736,
+ 0x8c84, 0x1df9,
+ 0x8c85, 0x073b,
+ 0x8c91, 0x1dfa,
+ 0x8c92, 0x0748,
+ 0x8c99, 0x1dfb,
+ 0x8c9a, 0x0750,
+ 0x8c9e, 0x1dfc,
+ 0x8c9f, 0x0755,
+ 0x8cb2, 0x1dfd,
+ 0x8cb3, 0x0769,
+ 0x8cbf, 0x1dfe,
+ 0x8cc0, 0x0776,
+ 0x8d40, 0x07b3,
+ 0x8d4a, 0x1dff,
+ 0x8d4b, 0x07be,
+ 0x8d56, 0x1e00,
+ 0x8d57, 0x07ca,
+ 0x8d61, 0x1e01,
+ 0x8d62, 0x07d5,
+ 0x8d7b, 0x16dd,
+ 0x8d7c, 0x07ef,
+ 0x8d80, 0x07f2,
+ 0x8d8d, 0x1e02,
+ 0x8d8e, 0x0800,
+ 0x8d94, 0x1e03,
+ 0x8d95, 0x0807,
+ 0x8d99, 0x1e04,
+ 0x8d9a, 0x080c,
+ 0x8dd1, 0x1e05,
+ 0x8dd2, 0x0844,
+ 0x8de5, 0x1e06,
+ 0x8de6, 0x0858,
+ 0x8df2, 0x1e07,
+ 0x8df3, 0x0865,
+ 0x8e40, 0x086f,
+ 0x8e46, 0x1e08,
+ 0x8e47, 0x0876,
+ 0x8e49, 0x1e09,
+ 0x8e4a, 0x0879,
+ 0x8e4b, 0x1e0a,
+ 0x8e4c, 0x087b,
+ 0x8e58, 0x1e0b,
+ 0x8e59, 0x0888,
+ 0x8e80, 0x08ae,
+ 0x8ec6, 0x1e0d,
+ 0x8ec7, 0x1929,
+ 0x8ec8, 0x08f6,
+ 0x8ed5, 0x1e0e,
+ 0x8ed6, 0x0904,
+ 0x8edb, 0x1e0f,
+ 0x8edd, 0x090b,
+ 0x8f40, 0x092b,
+ 0x8f4a, 0x1e11,
+ 0x8f4b, 0x0936,
+ 0x8f55, 0x1e12,
+ 0x8f56, 0x0941,
+ 0x8f80, 0x096a,
+ 0x8f8c, 0x1e13,
+ 0x8f8e, 0x0978,
+ 0x8f92, 0x1e15,
+ 0x8f94, 0x097e,
+ 0x8fa3, 0x1e17,
+ 0x8fa4, 0x098e,
+ 0x8fb1, 0x1e18,
+ 0x8fb2, 0x099c,
+ 0x8fbd, 0x1e19,
+ 0x8fbe, 0x09a8,
+ 0x8fd3, 0x1e1a,
+ 0x8fd4, 0x09be,
+ 0x8fdd, 0x1e1b,
+ 0x8fde, 0x09c8,
+ 0x8fe2, 0x1e1c,
+ 0x8fe3, 0x09cd,
+ 0x9040, 0x09e7,
+ 0x9049, 0x1e1d,
+ 0x904a, 0x09f1,
+ 0x9078, 0x1e1e,
+ 0x9079, 0x0a20,
+ 0x9080, 0x1e1f,
+ 0x9081, 0x0a27,
+ 0x9089, 0x1e20,
+ 0x908a, 0x0a30,
+ 0x90a0, 0x1e21,
+ 0x90a1, 0x0a47,
+ 0x90c0, 0x1e22,
+ 0x90c1, 0x0a67,
+ 0x90e4, 0x1e23,
+ 0x90e5, 0x0a8b,
+ 0x90ef, 0x1e24,
+ 0x90f1, 0x0a97,
+ 0x90f7, 0x1e26,
+ 0x90f9, 0x0a9f,
+ 0x9140, 0x0aa3,
+ 0x9146, 0x1e28,
+ 0x9147, 0x1a6e,
+ 0x9148, 0x0aab,
+ 0x9158, 0x1e29,
+ 0x9159, 0x0abc,
+ 0x916b, 0x1e2a,
+ 0x916c, 0x0acf,
+ 0x916e, 0x1e2b,
+ 0x916f, 0x0ad2,
+ 0x917e, 0x1e2c,
+ 0x9180, 0x0ae2,
+ 0x9189, 0x1e2d,
+ 0x918a, 0x0aec,
+ 0x91bb, 0x1e2e,
+ 0x91bc, 0x0b1e,
+ 0x91cb, 0x1e2f,
+ 0x91cc, 0x0b2e,
+ 0x91da, 0x1e30,
+ 0x91db, 0x0b3d,
+ 0x91e1, 0x1e31,
+ 0x91e2, 0x0b44,
+ 0x91ed, 0x1e32,
+ 0x91ee, 0x0b50,
+ 0x91f3, 0x1e33,
+ 0x91f5, 0x0b57,
+ 0x91fb, 0x1e35,
+ 0x91fc, 0x0b5e,
+ 0x9240, 0x0b5f,
+ 0x9246, 0x1e36,
+ 0x9247, 0x0b66,
+ 0x9248, 0x1e37,
+ 0x924a, 0x0b69,
+ 0x924c, 0x1e39,
+ 0x924e, 0x0b6d,
+ 0x925c, 0x1e3b,
+ 0x925d, 0x0b7c,
+ 0x9280, 0x0b9e,
+ 0x9290, 0x1e3c,
+ 0x9291, 0x0baf,
+ 0x9295, 0x1e3d,
+ 0x9296, 0x0bb4,
+ 0x929c, 0x1e3e,
+ 0x929d, 0x0bbb,
+ 0x92bb, 0x1e3f,
+ 0x92bc, 0x0bda,
+ 0x92c6, 0x1e40,
+ 0x92c7, 0x0be5,
+ 0x92c8, 0x1e41,
+ 0x92c9, 0x0be7,
+ 0x92cb, 0x1e42,
+ 0x92cc, 0x0bea,
+ 0x92cd, 0x1e43,
+ 0x92ce, 0x0bec,
+ 0x92d2, 0x204b,
+ 0x92d3, 0x0bf1,
+ 0x92d9, 0x11b5,
+ 0x92da, 0x0bf8,
+ 0x9340, 0x0c1b,
+ 0x9341, 0x1e44,
+ 0x9342, 0x0c1d,
+ 0x9346, 0x1e45,
+ 0x9347, 0x0c22,
+ 0x934d, 0x1e46,
+ 0x934e, 0x0c29,
+ 0x9355, 0x1e47,
+ 0x9356, 0x0c31,
+ 0x935e, 0x1e48,
+ 0x935f, 0x0c3a,
+ 0x9367, 0x1e49,
+ 0x9368, 0x0c43,
+ 0x936a, 0x1e4a,
+ 0x936b, 0x0c46,
+ 0x9370, 0x1e4b,
+ 0x9372, 0x0c4d,
+ 0x9376, 0x16df,
+ 0x9377, 0x0c52,
+ 0x9380, 0x0c5a,
+ 0x9384, 0x1e4d,
+ 0x9385, 0x0c5f,
+ 0x938e, 0x1450,
+ 0x938f, 0x0c69,
+ 0x9393, 0x1536,
+ 0x9394, 0x0c6e,
+ 0x9398, 0x1e4e,
+ 0x9399, 0x0c73,
+ 0x93bc, 0x1e4f,
+ 0x93bd, 0x0c97,
+ 0x93c0, 0x1e50,
+ 0x93c1, 0x0c9b,
+ 0x93d2, 0x1e51,
+ 0x93d4, 0x0cae,
+ 0x93d9, 0x1e53,
+ 0x93db, 0x0cb5,
+ 0x93df, 0x1e55,
+ 0x93e0, 0x0cba,
+ 0x93e4, 0x1e56,
+ 0x93e6, 0x0cc0,
+ 0x93e8, 0x1e58,
+ 0x93e9, 0x0cc3,
+ 0x93f4, 0x1aed,
+ 0x93f5, 0x0ccf,
+ 0x9440, 0x0cd7,
+ 0x9448, 0x1e59,
+ 0x9449, 0x0ce0,
+ 0x9458, 0x1e5a,
+ 0x9459, 0x0cf0,
+ 0x9476, 0x1e5b,
+ 0x9477, 0x0d0e,
+ 0x9480, 0x0d16,
+ 0x9487, 0x1e5c,
+ 0x9488, 0x1989,
+ 0x9489, 0x1e5d,
+ 0x948a, 0x0d20,
+ 0x948d, 0x1e5e,
+ 0x948e, 0x0d24,
+ 0x94a2, 0x1e5f,
+ 0x94a3, 0x0d39,
+ 0x94ac, 0x1e60,
+ 0x94ad, 0x0d43,
+ 0x94ae, 0x1e61,
+ 0x94af, 0x0d45,
+ 0x94d2, 0x1e62,
+ 0x94d3, 0x0d69,
+ 0x94e0, 0x1e63,
+ 0x94e1, 0x0d77,
+ 0x94f3, 0x1e64,
+ 0x94f4, 0x0d8a,
+ 0x9540, 0x0d93,
+ 0x9541, 0x1e65,
+ 0x9543, 0x0d96,
+ 0x954e, 0x1e67,
+ 0x954f, 0x143b,
+ 0x9550, 0x0da3,
+ 0x9551, 0x1e68,
+ 0x9552, 0x0da5,
+ 0x9554, 0x1e69,
+ 0x9555, 0x0da8,
+ 0x955f, 0x1e6a,
+ 0x9560, 0x0db3,
+ 0x956d, 0x1e6b,
+ 0x956e, 0x0dc1,
+ 0x9570, 0x1e6c,
+ 0x9571, 0x0dc4,
+ 0x9580, 0x0dd2,
+ 0x95c1, 0x1e6d,
+ 0x95c2, 0x0e14,
+ 0x95cb, 0x1e6e,
+ 0x95cc, 0x0e1e,
+ 0x95d8, 0x1e6f,
+ 0x95d9, 0x0e2b,
+ 0x95f7, 0x1e70,
+ 0x95f8, 0x0e4a,
+ 0x9640, 0x0e4f,
+ 0x9641, 0x1e71,
+ 0x9642, 0x0e51,
+ 0x9648, 0x1e72,
+ 0x9649, 0x0e58,
+ 0x966a, 0x1e73,
+ 0x966b, 0x0e7a,
+ 0x9680, 0x0e8e,
+ 0x968a, 0x1d33,
+ 0x968b, 0x0e99,
+ 0x9690, 0x1e74,
+ 0x9691, 0x0e9f,
+ 0x9698, 0x1f2c,
+ 0x9699, 0x102f,
+ 0x969a, 0x0ea8,
+ 0x96cb, 0x1e75,
+ 0x96cc, 0x0eda,
+ 0x96d7, 0x1e76,
+ 0x96d8, 0x0ee6,
+ 0x96dd, 0x1e77,
+ 0x96de, 0x0eec,
+ 0x96e0, 0x1e78,
+ 0x96e1, 0x0eef,
+ 0x96f7, 0x1935,
+ 0x96f8, 0x1e79,
+ 0x96f9, 0x0f07,
+ 0x96fa, 0x1e7a,
+ 0x96fb, 0x0f09,
+ 0x96fc, 0x1e7b,
+ 0x9740, 0x0f0b,
+ 0x9751, 0x1e7c,
+ 0x9752, 0x0f1d,
+ 0x976f, 0x1e7d,
+ 0x9770, 0x0f3b,
+ 0x9773, 0x1e7e,
+ 0x9774, 0x0f3f,
+ 0x9779, 0x1d34,
+ 0x977a, 0x0f45,
+ 0x9780, 0x0f4a,
+ 0x9789, 0x1e7f,
+ 0x978a, 0x0f54,
+ 0x97c9, 0x1e80,
+ 0x97ca, 0x0f94,
+ 0x97f8, 0x1e81,
+ 0x97fa, 0x0fc4,
+ 0x9840, 0x1e83,
+ 0x9841, 0x0fc8,
+ 0x9850, 0x1e84,
+ 0x9851, 0x0fd8,
+ 0x9855, 0x1777,
+ 0x9856, 0x0fdd,
+ 0x9858, 0x1e85,
+ 0x9859, 0x0fe0,
+ 0x989f, 0x0ffa,
+ 0x98d4, 0x0ea7,
+ 0x98d5, 0x1030,
+ 0x9940, 0x1058,
+ 0x995c, 0x1e86,
+ 0x995d, 0x1075,
+ 0x9966, 0x1e87,
+ 0x9967, 0x107f,
+ 0x996a, 0x1e88,
+ 0x996b, 0x1083,
+ 0x996c, 0x1e89,
+ 0x996d, 0x1085,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a4f, 0x1e8a,
+ 0x9a50, 0x1124,
+ 0x9a59, 0x1e8b,
+ 0x9a5a, 0x112e,
+ 0x9a7d, 0x1e8d,
+ 0x9a7e, 0x1152,
+ 0x9a80, 0x1153,
+ 0x9a8b, 0x1e8e,
+ 0x9a8c, 0x115f,
+ 0x9ac2, 0x1e8f,
+ 0x9ac3, 0x1196,
+ 0x9ae2, 0x0bf7,
+ 0x9ae3, 0x11b6,
+ 0x9b40, 0x11d0,
+ 0x9b5c, 0x1e90,
+ 0x9b5d, 0x11ed,
+ 0x9b80, 0x120f,
+ 0x9b83, 0x1e91,
+ 0x9b84, 0x1213,
+ 0x9ba0, 0x1e92,
+ 0x9ba1, 0x1230,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9ca2, 0x1e94,
+ 0x9ca3, 0x12ee,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1e95,
+ 0x9d81, 0x1388,
+ 0x9d8c, 0x1e96,
+ 0x9d8d, 0x1394,
+ 0x9d98, 0x05a7,
+ 0x9d99, 0x13a0,
+ 0x9db7, 0x1e97,
+ 0x9db8, 0x13bf,
+ 0x9dcb, 0x1e98,
+ 0x9dcc, 0x13d3,
+ 0x9e40, 0x1404,
+ 0x9e64, 0x1e99,
+ 0x9e65, 0x1429,
+ 0x9e69, 0x1e9a,
+ 0x9e6a, 0x142e,
+ 0x9e77, 0x0da2,
+ 0x9e78, 0x143c,
+ 0x9e80, 0x1443,
+ 0x9e8b, 0x1e9b,
+ 0x9e8c, 0x144f,
+ 0x9e8d, 0x0c68,
+ 0x9e8e, 0x1451,
+ 0x9e94, 0x1e9c,
+ 0x9e95, 0x1458,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0x9fb7, 0x0c6d,
+ 0x9fb8, 0x1537,
+ 0x9fce, 0x1e9d,
+ 0x9fcf, 0x154e,
+ 0x9ff3, 0x05ff,
+ 0x9ff4, 0x1573,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe0a4, 0x1e9f,
+ 0xe0a5, 0x15e0,
+ 0xe0dd, 0x1ea0,
+ 0xe0de, 0x1619,
+ 0xe0f4, 0x1d35,
+ 0xe0f5, 0x1630,
+ 0xe140, 0x1638,
+ 0xe14a, 0x1ea1,
+ 0xe14b, 0x1643,
+ 0xe14f, 0x1ea2,
+ 0xe151, 0x1649,
+ 0xe180, 0x1677,
+ 0xe1a9, 0x1ea4,
+ 0xe1aa, 0x16a1,
+ 0xe1e6, 0x07ee,
+ 0xe1e7, 0x16de,
+ 0xe1e8, 0x0c51,
+ 0xe1e9, 0x16e0,
+ 0xe1ed, 0x1ea5,
+ 0xe1ee, 0x16e5,
+ 0xe240, 0x16f4,
+ 0xe269, 0x1ea6,
+ 0xe26a, 0x171e,
+ 0xe273, 0x1ea7,
+ 0xe274, 0x1728,
+ 0xe27d, 0x05d4,
+ 0xe27e, 0x1732,
+ 0xe280, 0x1733,
+ 0xe2b7, 0x1ea8,
+ 0xe2b8, 0x176b,
+ 0xe2c4, 0x0fdc,
+ 0xe2c5, 0x1778,
+ 0xe2e2, 0x1ea9,
+ 0xe2e3, 0x1796,
+ 0xe2ec, 0x1eaa,
+ 0xe2ed, 0x17a0,
+ 0xe340, 0x17b0,
+ 0xe358, 0x1eab,
+ 0xe359, 0x17c9,
+ 0xe35a, 0x1eac,
+ 0xe35b, 0x17cb,
+ 0xe365, 0x1ead,
+ 0xe366, 0x17d6,
+ 0xe380, 0x17ef,
+ 0xe3c4, 0x1eae,
+ 0xe3c5, 0x1834,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe484, 0x1eaf,
+ 0xe485, 0x18b0,
+ 0xe489, 0x1eb0,
+ 0xe48a, 0x18b5,
+ 0xe492, 0x1eb1,
+ 0xe493, 0x18be,
+ 0xe4b2, 0x1eb2,
+ 0xe4b3, 0x18de,
+ 0xe4b9, 0x1eb3,
+ 0xe4ba, 0x18e5,
+ 0xe4f2, 0x1eb4,
+ 0xe4f3, 0x191e,
+ 0xe540, 0x1928,
+ 0xe541, 0x08f5,
+ 0xe542, 0x192a,
+ 0xe54d, 0x0f05,
+ 0xe54e, 0x1936,
+ 0xe579, 0x05a0,
+ 0xe57a, 0x1962,
+ 0xe580, 0x1967,
+ 0xe5a2, 0x0d1e,
+ 0xe5a3, 0x198a,
+ 0xe5a5, 0x1eb6,
+ 0xe5a6, 0x198d,
+ 0xe5bb, 0x1eb7,
+ 0xe5bc, 0x19a3,
+ 0xe5ed, 0x1eb8,
+ 0xe5ee, 0x19d5,
+ 0xe640, 0x19e4,
+ 0xe651, 0x1eb9,
+ 0xe652, 0x19f6,
+ 0xe67c, 0x060e,
+ 0xe67d, 0x1a21,
+ 0xe680, 0x1a23,
+ 0xe686, 0x1eba,
+ 0xe687, 0x1a2a,
+ 0xe696, 0x1ebb,
+ 0xe697, 0x1a3a,
+ 0xe6cb, 0x0aaa,
+ 0xe6cc, 0x1a6f,
+ 0xe6e7, 0x1ebc,
+ 0xe6e8, 0x1a8b,
+ 0xe6f2, 0x1ebd,
+ 0xe6f3, 0x1a96,
+ 0xe740, 0x1aa0,
+ 0xe76d, 0x1ebe,
+ 0xe76e, 0x1ace,
+ 0xe780, 0x1adf,
+ 0xe78c, 0x1ebf,
+ 0xe78d, 0x1aec,
+ 0xe78e, 0x1ec0,
+ 0xe78f, 0x1aee,
+ 0xe7a7, 0x1ec1,
+ 0xe7a8, 0x1b07,
+ 0xe7bb, 0x1ec2,
+ 0xe7bc, 0x1b1b,
+ 0xe7d5, 0x1ec3,
+ 0xe7d6, 0x1b35,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe8c3, 0x1ec6,
+ 0xe8c4, 0x1bdf,
+ 0xe8cf, 0x1ec7,
+ 0xe8d0, 0x1beb,
+ 0xe8d5, 0x1ec8,
+ 0xe8d6, 0x1bf1,
+ 0xe8f2, 0x0731,
+ 0xe8f3, 0x1ec9,
+ 0xe8f4, 0x1c0f,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xe9ab, 0x1eca,
+ 0xe9ac, 0x1c83,
+ 0xe9ba, 0x1ecb,
+ 0xe9bb, 0x1c92,
+ 0xe9cb, 0x0477,
+ 0xe9cc, 0x1ecc,
+ 0xe9cd, 0x1ca4,
+ 0xe9f2, 0x0529,
+ 0xe9f3, 0x1cca,
+ 0xea40, 0x1cd4,
+ 0xea70, 0x1ecd,
+ 0xea71, 0x1d05,
+ 0xea80, 0x1d13,
+ 0xea9d, 0x1ece,
+ 0xea9e, 0x1d31,
+ 0x8141, 0x1ecf,
+ 0x8150, 0x1ed1,
+ 0x815b, 0x1ed3,
+ 0x8160, 0x1ed6,
+ 0x8169, 0x1edb,
+ 0x8181, 0x1eed,
+ 0x829f, 0x1eee,
+ 0x82a1, 0x1eef,
+ 0x82a3, 0x1ef0,
+ 0x82a5, 0x1ef1,
+ 0x82a7, 0x1ef2,
+ 0x82c1, 0x1ef3,
+ 0x82e1, 0x1ef4,
+ 0x82e3, 0x1ef5,
+ 0x82e5, 0x1ef6,
+ 0x82ec, 0x1ef7,
+ 0x8340, 0x1ef8,
+ 0x8342, 0x1ef9,
+ 0x8344, 0x1efa,
+ 0x8346, 0x1efb,
+ 0x8348, 0x1efc,
+ 0x8362, 0x1efd,
+ 0x8383, 0x1efe,
+ 0x8385, 0x1eff,
+ 0x8387, 0x1f00,
+ 0x838e, 0x1f01,
+ 0x8395, 0x1f02,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1278RKSJVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1278RKSJVMap2, 653
+};
+
+static Gushort japan1278VMap2[1304] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0279,
+ 0x2221, 0x02d7,
+ 0x2330, 0x030c,
+ 0x2341, 0x0316,
+ 0x2361, 0x0330,
+ 0x2421, 0x034a,
+ 0x2521, 0x039d,
+ 0x2621, 0x03f3,
+ 0x2641, 0x040b,
+ 0x2721, 0x0423,
+ 0x2751, 0x0444,
+ 0x3021, 0x0465,
+ 0x3022, 0x1dd1,
+ 0x3023, 0x0467,
+ 0x3029, 0x204a,
+ 0x302a, 0x046e,
+ 0x3032, 0x1f19,
+ 0x3033, 0x1ca2,
+ 0x3034, 0x0478,
+ 0x303b, 0x1dd2,
+ 0x303c, 0x0480,
+ 0x306e, 0x1dd3,
+ 0x306f, 0x04b3,
+ 0x3073, 0x1dd4,
+ 0x3074, 0x04b8,
+ 0x307c, 0x1dd5,
+ 0x307d, 0x04c1,
+ 0x3121, 0x04c3,
+ 0x312a, 0x1dd6,
+ 0x312b, 0x04cd,
+ 0x3135, 0x1dd7,
+ 0x3136, 0x04d8,
+ 0x3139, 0x1dd8,
+ 0x313a, 0x04dc,
+ 0x313d, 0x1dda,
+ 0x313e, 0x04e0,
+ 0x3142, 0x1ddb,
+ 0x3143, 0x04e5,
+ 0x316b, 0x1ddc,
+ 0x316c, 0x050e,
+ 0x3221, 0x0521,
+ 0x3228, 0x1ddd,
+ 0x3229, 0x1cc9,
+ 0x322a, 0x1dde,
+ 0x322b, 0x052b,
+ 0x3260, 0x1ddf,
+ 0x3261, 0x0561,
+ 0x327a, 0x1de0,
+ 0x327b, 0x057b,
+ 0x327d, 0x1de1,
+ 0x327e, 0x057e,
+ 0x3321, 0x057f,
+ 0x3322, 0x1de2,
+ 0x3323, 0x0581,
+ 0x3342, 0x1961,
+ 0x3343, 0x05a1,
+ 0x3349, 0x139f,
+ 0x334a, 0x05a8,
+ 0x3365, 0x1de3,
+ 0x3366, 0x05c4,
+ 0x336b, 0x1de4,
+ 0x336c, 0x05ca,
+ 0x3373, 0x1de5,
+ 0x3374, 0x05d2,
+ 0x3376, 0x1731,
+ 0x3377, 0x05d5,
+ 0x337a, 0x1de6,
+ 0x337b, 0x05d9,
+ 0x3421, 0x05dd,
+ 0x3442, 0x1de7,
+ 0x3443, 0x1572,
+ 0x3444, 0x0600,
+ 0x344d, 0x1de8,
+ 0x344e, 0x060a,
+ 0x3452, 0x1a20,
+ 0x3453, 0x060f,
+ 0x3465, 0x1de9,
+ 0x3466, 0x0622,
+ 0x3521, 0x063b,
+ 0x352b, 0x1dea,
+ 0x352c, 0x0646,
+ 0x3540, 0x1deb,
+ 0x3541, 0x065b,
+ 0x3621, 0x0699,
+ 0x3622, 0x1dec,
+ 0x3623, 0x069b,
+ 0x362a, 0x1ded,
+ 0x362b, 0x06a3,
+ 0x3646, 0x1d32,
+ 0x3647, 0x06bf,
+ 0x364f, 0x1dee,
+ 0x3650, 0x06c8,
+ 0x366d, 0x1def,
+ 0x366e, 0x06e6,
+ 0x3674, 0x1df0,
+ 0x3675, 0x06ed,
+ 0x367b, 0x1df1,
+ 0x367c, 0x06f4,
+ 0x367d, 0x1df2,
+ 0x367e, 0x06f6,
+ 0x3721, 0x06f7,
+ 0x3724, 0x1df3,
+ 0x3725, 0x06fb,
+ 0x3737, 0x1df4,
+ 0x3738, 0x070e,
+ 0x3745, 0x1df5,
+ 0x3746, 0x071c,
+ 0x374e, 0x1df6,
+ 0x374f, 0x0725,
+ 0x3752, 0x1df7,
+ 0x3753, 0x0729,
+ 0x3755, 0x1df8,
+ 0x3756, 0x072c,
+ 0x375b, 0x1c0d,
+ 0x375c, 0x0732,
+ 0x3764, 0x1df9,
+ 0x3765, 0x073b,
+ 0x3771, 0x1dfa,
+ 0x3772, 0x0748,
+ 0x3779, 0x1dfb,
+ 0x377a, 0x0750,
+ 0x377e, 0x1dfc,
+ 0x3821, 0x0755,
+ 0x3834, 0x1dfd,
+ 0x3835, 0x0769,
+ 0x3841, 0x1dfe,
+ 0x3842, 0x0776,
+ 0x3921, 0x07b3,
+ 0x392b, 0x1dff,
+ 0x392c, 0x07be,
+ 0x3937, 0x1e00,
+ 0x3938, 0x07ca,
+ 0x3942, 0x1e01,
+ 0x3943, 0x07d5,
+ 0x395c, 0x16dd,
+ 0x395d, 0x07ef,
+ 0x396d, 0x1e02,
+ 0x396e, 0x0800,
+ 0x3974, 0x1e03,
+ 0x3975, 0x0807,
+ 0x3979, 0x1e04,
+ 0x397a, 0x080c,
+ 0x3a21, 0x0811,
+ 0x3a53, 0x1e05,
+ 0x3a54, 0x0844,
+ 0x3a67, 0x1e06,
+ 0x3a68, 0x0858,
+ 0x3a74, 0x1e07,
+ 0x3a75, 0x0865,
+ 0x3b21, 0x086f,
+ 0x3b27, 0x1e08,
+ 0x3b28, 0x0876,
+ 0x3b2a, 0x1e09,
+ 0x3b2b, 0x0879,
+ 0x3b2c, 0x1e0a,
+ 0x3b2d, 0x087b,
+ 0x3b39, 0x1e0b,
+ 0x3b3a, 0x0888,
+ 0x3c21, 0x08cd,
+ 0x3c48, 0x1e0d,
+ 0x3c49, 0x1929,
+ 0x3c4a, 0x08f6,
+ 0x3c57, 0x1e0e,
+ 0x3c58, 0x0904,
+ 0x3c5d, 0x1e0f,
+ 0x3c5f, 0x090b,
+ 0x3d21, 0x092b,
+ 0x3d2b, 0x1e11,
+ 0x3d2c, 0x0936,
+ 0x3d36, 0x1e12,
+ 0x3d37, 0x0941,
+ 0x3d6c, 0x1e13,
+ 0x3d6e, 0x0978,
+ 0x3d72, 0x1e15,
+ 0x3d74, 0x097e,
+ 0x3e21, 0x0989,
+ 0x3e25, 0x1e17,
+ 0x3e26, 0x098e,
+ 0x3e33, 0x1e18,
+ 0x3e34, 0x099c,
+ 0x3e3f, 0x1e19,
+ 0x3e40, 0x09a8,
+ 0x3e55, 0x1e1a,
+ 0x3e56, 0x09be,
+ 0x3e5f, 0x1e1b,
+ 0x3e60, 0x09c8,
+ 0x3e64, 0x1e1c,
+ 0x3e65, 0x09cd,
+ 0x3f21, 0x09e7,
+ 0x3f2a, 0x1e1d,
+ 0x3f2b, 0x09f1,
+ 0x3f59, 0x1e1e,
+ 0x3f5a, 0x0a20,
+ 0x3f60, 0x1e1f,
+ 0x3f61, 0x0a27,
+ 0x3f69, 0x1e20,
+ 0x3f6a, 0x0a30,
+ 0x4021, 0x0a45,
+ 0x4022, 0x1e21,
+ 0x4023, 0x0a47,
+ 0x4042, 0x1e22,
+ 0x4043, 0x0a67,
+ 0x4066, 0x1e23,
+ 0x4067, 0x0a8b,
+ 0x4071, 0x1e24,
+ 0x4073, 0x0a97,
+ 0x4079, 0x1e26,
+ 0x407b, 0x0a9f,
+ 0x4121, 0x0aa3,
+ 0x4127, 0x1e28,
+ 0x4128, 0x1a6e,
+ 0x4129, 0x0aab,
+ 0x4139, 0x1e29,
+ 0x413a, 0x0abc,
+ 0x414c, 0x1e2a,
+ 0x414d, 0x0acf,
+ 0x414f, 0x1e2b,
+ 0x4150, 0x0ad2,
+ 0x415f, 0x1e2c,
+ 0x4160, 0x0ae2,
+ 0x4169, 0x1e2d,
+ 0x416a, 0x0aec,
+ 0x4221, 0x0b01,
+ 0x423d, 0x1e2e,
+ 0x423e, 0x0b1e,
+ 0x424d, 0x1e2f,
+ 0x424e, 0x0b2e,
+ 0x425c, 0x1e30,
+ 0x425d, 0x0b3d,
+ 0x4263, 0x1e31,
+ 0x4264, 0x0b44,
+ 0x426f, 0x1e32,
+ 0x4270, 0x0b50,
+ 0x4275, 0x1e33,
+ 0x4277, 0x0b57,
+ 0x427d, 0x1e35,
+ 0x427e, 0x0b5e,
+ 0x4321, 0x0b5f,
+ 0x4327, 0x1e36,
+ 0x4328, 0x0b66,
+ 0x4329, 0x1e37,
+ 0x432b, 0x0b69,
+ 0x432d, 0x1e39,
+ 0x432f, 0x0b6d,
+ 0x433d, 0x1e3b,
+ 0x433e, 0x0b7c,
+ 0x4370, 0x1e3c,
+ 0x4371, 0x0baf,
+ 0x4375, 0x1e3d,
+ 0x4376, 0x0bb4,
+ 0x437c, 0x1e3e,
+ 0x437d, 0x0bbb,
+ 0x4421, 0x0bbd,
+ 0x443d, 0x1e3f,
+ 0x443e, 0x0bda,
+ 0x4448, 0x1e40,
+ 0x4449, 0x0be5,
+ 0x444a, 0x1e41,
+ 0x444b, 0x0be7,
+ 0x444d, 0x1e42,
+ 0x444e, 0x0bea,
+ 0x444f, 0x1e43,
+ 0x4450, 0x0bec,
+ 0x4454, 0x204b,
+ 0x4455, 0x0bf1,
+ 0x445b, 0x11b5,
+ 0x445c, 0x0bf8,
+ 0x4521, 0x0c1b,
+ 0x4522, 0x1e44,
+ 0x4523, 0x0c1d,
+ 0x4527, 0x1e45,
+ 0x4528, 0x0c22,
+ 0x452e, 0x1e46,
+ 0x452f, 0x0c29,
+ 0x4536, 0x1e47,
+ 0x4537, 0x0c31,
+ 0x453f, 0x1e48,
+ 0x4540, 0x0c3a,
+ 0x4548, 0x1e49,
+ 0x4549, 0x0c43,
+ 0x454b, 0x1e4a,
+ 0x454c, 0x0c46,
+ 0x4551, 0x1e4b,
+ 0x4553, 0x0c4d,
+ 0x4557, 0x16df,
+ 0x4558, 0x0c52,
+ 0x4564, 0x1e4d,
+ 0x4565, 0x0c5f,
+ 0x456e, 0x1450,
+ 0x456f, 0x0c69,
+ 0x4573, 0x1536,
+ 0x4574, 0x0c6e,
+ 0x4578, 0x1e4e,
+ 0x4579, 0x0c73,
+ 0x4621, 0x0c79,
+ 0x463e, 0x1e4f,
+ 0x463f, 0x0c97,
+ 0x4642, 0x1e50,
+ 0x4643, 0x0c9b,
+ 0x4654, 0x1e51,
+ 0x4656, 0x0cae,
+ 0x465b, 0x1e53,
+ 0x465d, 0x0cb5,
+ 0x4661, 0x1e55,
+ 0x4662, 0x0cba,
+ 0x4666, 0x1e56,
+ 0x4668, 0x0cc0,
+ 0x466a, 0x1e58,
+ 0x466b, 0x0cc3,
+ 0x4676, 0x1aed,
+ 0x4677, 0x0ccf,
+ 0x4721, 0x0cd7,
+ 0x4729, 0x1e59,
+ 0x472a, 0x0ce0,
+ 0x4739, 0x1e5a,
+ 0x473a, 0x0cf0,
+ 0x4757, 0x1e5b,
+ 0x4758, 0x0d0e,
+ 0x4767, 0x1e5c,
+ 0x4768, 0x1989,
+ 0x4769, 0x1e5d,
+ 0x476a, 0x0d20,
+ 0x476d, 0x1e5e,
+ 0x476e, 0x0d24,
+ 0x4821, 0x0d35,
+ 0x4824, 0x1e5f,
+ 0x4825, 0x0d39,
+ 0x482e, 0x1e60,
+ 0x482f, 0x0d43,
+ 0x4830, 0x1e61,
+ 0x4831, 0x0d45,
+ 0x4854, 0x1e62,
+ 0x4855, 0x0d69,
+ 0x4862, 0x1e63,
+ 0x4863, 0x0d77,
+ 0x4875, 0x1e64,
+ 0x4876, 0x0d8a,
+ 0x4921, 0x0d93,
+ 0x4922, 0x1e65,
+ 0x4924, 0x0d96,
+ 0x492f, 0x1e67,
+ 0x4930, 0x143b,
+ 0x4931, 0x0da3,
+ 0x4932, 0x1e68,
+ 0x4933, 0x0da5,
+ 0x4935, 0x1e69,
+ 0x4936, 0x0da8,
+ 0x4940, 0x1e6a,
+ 0x4941, 0x0db3,
+ 0x494e, 0x1e6b,
+ 0x494f, 0x0dc1,
+ 0x4951, 0x1e6c,
+ 0x4952, 0x0dc4,
+ 0x4a21, 0x0df1,
+ 0x4a43, 0x1e6d,
+ 0x4a44, 0x0e14,
+ 0x4a4d, 0x1e6e,
+ 0x4a4e, 0x0e1e,
+ 0x4a5a, 0x1e6f,
+ 0x4a5b, 0x0e2b,
+ 0x4a79, 0x1e70,
+ 0x4a7a, 0x0e4a,
+ 0x4b21, 0x0e4f,
+ 0x4b22, 0x1e71,
+ 0x4b23, 0x0e51,
+ 0x4b29, 0x1e72,
+ 0x4b2a, 0x0e58,
+ 0x4b4b, 0x1e73,
+ 0x4b4c, 0x0e7a,
+ 0x4b6a, 0x1d33,
+ 0x4b6b, 0x0e99,
+ 0x4b70, 0x1e74,
+ 0x4b71, 0x0e9f,
+ 0x4b78, 0x1f2c,
+ 0x4b79, 0x102f,
+ 0x4b7a, 0x0ea8,
+ 0x4c21, 0x0ead,
+ 0x4c4d, 0x1e75,
+ 0x4c4e, 0x0eda,
+ 0x4c59, 0x1e76,
+ 0x4c5a, 0x0ee6,
+ 0x4c5f, 0x1e77,
+ 0x4c60, 0x0eec,
+ 0x4c62, 0x1e78,
+ 0x4c63, 0x0eef,
+ 0x4c79, 0x1935,
+ 0x4c7a, 0x1e79,
+ 0x4c7b, 0x0f07,
+ 0x4c7c, 0x1e7a,
+ 0x4c7d, 0x0f09,
+ 0x4c7e, 0x1e7b,
+ 0x4d21, 0x0f0b,
+ 0x4d32, 0x1e7c,
+ 0x4d33, 0x0f1d,
+ 0x4d50, 0x1e7d,
+ 0x4d51, 0x0f3b,
+ 0x4d54, 0x1e7e,
+ 0x4d55, 0x0f3f,
+ 0x4d5a, 0x1d34,
+ 0x4d5b, 0x0f45,
+ 0x4d69, 0x1e7f,
+ 0x4d6a, 0x0f54,
+ 0x4e21, 0x0f69,
+ 0x4e4b, 0x1e80,
+ 0x4e4c, 0x0f94,
+ 0x4e7a, 0x1e81,
+ 0x4e7c, 0x0fc4,
+ 0x4f21, 0x1e83,
+ 0x4f22, 0x0fc8,
+ 0x4f31, 0x1e84,
+ 0x4f32, 0x0fd8,
+ 0x4f36, 0x1777,
+ 0x4f37, 0x0fdd,
+ 0x4f39, 0x1e85,
+ 0x4f3a, 0x0fe0,
+ 0x5021, 0x0ffa,
+ 0x5056, 0x0ea7,
+ 0x5057, 0x1030,
+ 0x5121, 0x1058,
+ 0x513d, 0x1e86,
+ 0x513e, 0x1075,
+ 0x5147, 0x1e87,
+ 0x5148, 0x107f,
+ 0x514b, 0x1e88,
+ 0x514c, 0x1083,
+ 0x514d, 0x1e89,
+ 0x514e, 0x1085,
+ 0x5221, 0x10b6,
+ 0x5321, 0x1114,
+ 0x5330, 0x1e8a,
+ 0x5331, 0x1124,
+ 0x533a, 0x1e8b,
+ 0x533b, 0x112e,
+ 0x535e, 0x1e8d,
+ 0x535f, 0x1152,
+ 0x536b, 0x1e8e,
+ 0x536c, 0x115f,
+ 0x5421, 0x1172,
+ 0x5444, 0x1e8f,
+ 0x5445, 0x1196,
+ 0x5464, 0x0bf7,
+ 0x5465, 0x11b6,
+ 0x5521, 0x11d0,
+ 0x553d, 0x1e90,
+ 0x553e, 0x11ed,
+ 0x5563, 0x1e91,
+ 0x5564, 0x1213,
+ 0x5621, 0x122e,
+ 0x5622, 0x1e92,
+ 0x5623, 0x1230,
+ 0x5721, 0x128c,
+ 0x5821, 0x12ea,
+ 0x5824, 0x1e94,
+ 0x5825, 0x12ee,
+ 0x5921, 0x1348,
+ 0x5960, 0x1e95,
+ 0x5961, 0x1388,
+ 0x596c, 0x1e96,
+ 0x596d, 0x1394,
+ 0x5978, 0x05a7,
+ 0x5979, 0x13a0,
+ 0x5a21, 0x13a6,
+ 0x5a39, 0x1e97,
+ 0x5a3a, 0x13bf,
+ 0x5a4d, 0x1e98,
+ 0x5a4e, 0x13d3,
+ 0x5b21, 0x1404,
+ 0x5b45, 0x1e99,
+ 0x5b46, 0x1429,
+ 0x5b4a, 0x1e9a,
+ 0x5b4b, 0x142e,
+ 0x5b58, 0x0da2,
+ 0x5b59, 0x143c,
+ 0x5b6b, 0x1e9b,
+ 0x5b6c, 0x144f,
+ 0x5b6d, 0x0c68,
+ 0x5b6e, 0x1451,
+ 0x5b74, 0x1e9c,
+ 0x5b75, 0x1458,
+ 0x5c21, 0x1462,
+ 0x5d21, 0x14c0,
+ 0x5e21, 0x151e,
+ 0x5e39, 0x0c6d,
+ 0x5e3a, 0x1537,
+ 0x5e50, 0x1e9d,
+ 0x5e51, 0x154e,
+ 0x5e75, 0x05ff,
+ 0x5e76, 0x1573,
+ 0x5f21, 0x157c,
+ 0x6021, 0x15da,
+ 0x6026, 0x1e9f,
+ 0x6027, 0x15e0,
+ 0x605f, 0x1ea0,
+ 0x6060, 0x1619,
+ 0x6076, 0x1d35,
+ 0x6077, 0x1630,
+ 0x6121, 0x1638,
+ 0x612b, 0x1ea1,
+ 0x612c, 0x1643,
+ 0x6130, 0x1ea2,
+ 0x6132, 0x1649,
+ 0x6221, 0x1696,
+ 0x622b, 0x1ea4,
+ 0x622c, 0x16a1,
+ 0x6268, 0x07ee,
+ 0x6269, 0x16de,
+ 0x626a, 0x0c51,
+ 0x626b, 0x16e0,
+ 0x626f, 0x1ea5,
+ 0x6270, 0x16e5,
+ 0x6321, 0x16f4,
+ 0x634a, 0x1ea6,
+ 0x634b, 0x171e,
+ 0x6354, 0x1ea7,
+ 0x6355, 0x1728,
+ 0x635e, 0x05d4,
+ 0x635f, 0x1732,
+ 0x6421, 0x1752,
+ 0x6439, 0x1ea8,
+ 0x643a, 0x176b,
+ 0x6446, 0x0fdc,
+ 0x6447, 0x1778,
+ 0x6464, 0x1ea9,
+ 0x6465, 0x1796,
+ 0x646e, 0x1eaa,
+ 0x646f, 0x17a0,
+ 0x6521, 0x17b0,
+ 0x6539, 0x1eab,
+ 0x653a, 0x17c9,
+ 0x653b, 0x1eac,
+ 0x653c, 0x17cb,
+ 0x6546, 0x1ead,
+ 0x6547, 0x17d6,
+ 0x6621, 0x180e,
+ 0x6646, 0x1eae,
+ 0x6647, 0x1834,
+ 0x6721, 0x186c,
+ 0x6764, 0x1eaf,
+ 0x6765, 0x18b0,
+ 0x6769, 0x1eb0,
+ 0x676a, 0x18b5,
+ 0x6772, 0x1eb1,
+ 0x6773, 0x18be,
+ 0x6821, 0x18ca,
+ 0x6834, 0x1eb2,
+ 0x6835, 0x18de,
+ 0x683b, 0x1eb3,
+ 0x683c, 0x18e5,
+ 0x6874, 0x1eb4,
+ 0x6875, 0x191e,
+ 0x6921, 0x1928,
+ 0x6922, 0x08f5,
+ 0x6923, 0x192a,
+ 0x692e, 0x0f05,
+ 0x692f, 0x1936,
+ 0x695a, 0x05a0,
+ 0x695b, 0x1962,
+ 0x6a21, 0x1986,
+ 0x6a24, 0x0d1e,
+ 0x6a25, 0x198a,
+ 0x6a27, 0x1eb6,
+ 0x6a28, 0x198d,
+ 0x6a3d, 0x1eb7,
+ 0x6a3e, 0x19a3,
+ 0x6a6f, 0x1eb8,
+ 0x6a70, 0x19d5,
+ 0x6b21, 0x19e4,
+ 0x6b32, 0x1eb9,
+ 0x6b33, 0x19f6,
+ 0x6b5d, 0x060e,
+ 0x6b5e, 0x1a21,
+ 0x6b66, 0x1eba,
+ 0x6b67, 0x1a2a,
+ 0x6b76, 0x1ebb,
+ 0x6b77, 0x1a3a,
+ 0x6c21, 0x1a42,
+ 0x6c4d, 0x0aaa,
+ 0x6c4e, 0x1a6f,
+ 0x6c69, 0x1ebc,
+ 0x6c6a, 0x1a8b,
+ 0x6c74, 0x1ebd,
+ 0x6c75, 0x1a96,
+ 0x6d21, 0x1aa0,
+ 0x6d4e, 0x1ebe,
+ 0x6d4f, 0x1ace,
+ 0x6d6c, 0x1ebf,
+ 0x6d6d, 0x1aec,
+ 0x6d6e, 0x1ec0,
+ 0x6d6f, 0x1aee,
+ 0x6e21, 0x1afe,
+ 0x6e29, 0x1ec1,
+ 0x6e2a, 0x1b07,
+ 0x6e3d, 0x1ec2,
+ 0x6e3e, 0x1b1b,
+ 0x6e57, 0x1ec3,
+ 0x6e58, 0x1b35,
+ 0x6f21, 0x1b5c,
+ 0x7021, 0x1bba,
+ 0x7045, 0x1ec6,
+ 0x7046, 0x1bdf,
+ 0x7051, 0x1ec7,
+ 0x7052, 0x1beb,
+ 0x7057, 0x1ec8,
+ 0x7058, 0x1bf1,
+ 0x7074, 0x0731,
+ 0x7075, 0x1ec9,
+ 0x7076, 0x1c0f,
+ 0x7121, 0x1c18,
+ 0x7221, 0x1c76,
+ 0x722d, 0x1eca,
+ 0x722e, 0x1c83,
+ 0x723c, 0x1ecb,
+ 0x723d, 0x1c92,
+ 0x724d, 0x0477,
+ 0x724e, 0x1ecc,
+ 0x724f, 0x1ca4,
+ 0x7274, 0x0529,
+ 0x7275, 0x1cca,
+ 0x7321, 0x1cd4,
+ 0x7351, 0x1ecd,
+ 0x7352, 0x1d05,
+ 0x737d, 0x1ece,
+ 0x737e, 0x1d31,
+ 0x2122, 0x1ecf,
+ 0x2131, 0x1ed1,
+ 0x213c, 0x1ed3,
+ 0x2141, 0x1ed6,
+ 0x214a, 0x1edb,
+ 0x2161, 0x1eed,
+ 0x2421, 0x1eee,
+ 0x2423, 0x1eef,
+ 0x2425, 0x1ef0,
+ 0x2427, 0x1ef1,
+ 0x2429, 0x1ef2,
+ 0x2443, 0x1ef3,
+ 0x2463, 0x1ef4,
+ 0x2465, 0x1ef5,
+ 0x2467, 0x1ef6,
+ 0x246e, 0x1ef7,
+ 0x2521, 0x1ef8,
+ 0x2523, 0x1ef9,
+ 0x2525, 0x1efa,
+ 0x2527, 0x1efb,
+ 0x2529, 0x1efc,
+ 0x2543, 0x1efd,
+ 0x2563, 0x1efe,
+ 0x2565, 0x1eff,
+ 0x2567, 0x1f00,
+ 0x256e, 0x1f01,
+ 0x2575, 0x1f02,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1278VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1278VMap2, 652
+};
+
+static Gushort japan1278msRKSJHMap2[1424] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x8740, 0x1d83,
+ 0x875f, 0x1da1,
+ 0x8761, 0x1f66,
+ 0x8762, 0x1da4,
+ 0x8763, 0x1f68,
+ 0x8764, 0x1da6,
+ 0x8765, 0x1f6a,
+ 0x8766, 0x1da8,
+ 0x8768, 0x1f6c,
+ 0x8769, 0x1dab,
+ 0x876b, 0x1f6b,
+ 0x876c, 0x1dae,
+ 0x876e, 0x1f6f,
+ 0x876f, 0x1db1,
+ 0x877e, 0x2083,
+ 0x8780, 0x1db8,
+ 0x8784, 0x1f77,
+ 0x8785, 0x1dbd,
+ 0x8790, 0x02fa,
+ 0x8791, 0x02f9,
+ 0x8792, 0x0301,
+ 0x8793, 0x1dc8,
+ 0x879a, 0x0300,
+ 0x879b, 0x1dcf,
+ 0x889f, 0x0465,
+ 0x88a0, 0x1dd1,
+ 0x88a1, 0x0467,
+ 0x88a7, 0x204a,
+ 0x88a8, 0x046e,
+ 0x88b0, 0x1f19,
+ 0x88b1, 0x1ca2,
+ 0x88b2, 0x0478,
+ 0x88b9, 0x1dd2,
+ 0x88ba, 0x0480,
+ 0x88ec, 0x1dd3,
+ 0x88ed, 0x04b3,
+ 0x88f1, 0x1dd4,
+ 0x88f2, 0x04b8,
+ 0x88fa, 0x1dd5,
+ 0x88fb, 0x04c1,
+ 0x8940, 0x04c3,
+ 0x8949, 0x1dd6,
+ 0x894a, 0x04cd,
+ 0x8954, 0x1dd7,
+ 0x8955, 0x04d8,
+ 0x8958, 0x1dd8,
+ 0x8959, 0x04dc,
+ 0x895c, 0x1dda,
+ 0x895d, 0x04e0,
+ 0x8961, 0x1ddb,
+ 0x8962, 0x04e5,
+ 0x8980, 0x0502,
+ 0x898b, 0x1ddc,
+ 0x898c, 0x050e,
+ 0x89a6, 0x1ddd,
+ 0x89a7, 0x1cc9,
+ 0x89a8, 0x1dde,
+ 0x89a9, 0x052b,
+ 0x89de, 0x1ddf,
+ 0x89df, 0x0561,
+ 0x89f8, 0x1de0,
+ 0x89f9, 0x057b,
+ 0x89fb, 0x1de1,
+ 0x89fc, 0x057e,
+ 0x8a40, 0x057f,
+ 0x8a41, 0x1de2,
+ 0x8a42, 0x0581,
+ 0x8a61, 0x1961,
+ 0x8a62, 0x05a1,
+ 0x8a68, 0x139f,
+ 0x8a69, 0x05a8,
+ 0x8a80, 0x05be,
+ 0x8a85, 0x1de3,
+ 0x8a86, 0x05c4,
+ 0x8a8b, 0x1de4,
+ 0x8a8c, 0x05ca,
+ 0x8a93, 0x1de5,
+ 0x8a94, 0x05d2,
+ 0x8a96, 0x1731,
+ 0x8a97, 0x05d5,
+ 0x8a9a, 0x1de6,
+ 0x8a9b, 0x05d9,
+ 0x8ac0, 0x1de7,
+ 0x8ac1, 0x1572,
+ 0x8ac2, 0x0600,
+ 0x8acb, 0x1de8,
+ 0x8acc, 0x060a,
+ 0x8ad0, 0x1a20,
+ 0x8ad1, 0x060f,
+ 0x8ae3, 0x1de9,
+ 0x8ae4, 0x0622,
+ 0x8b40, 0x063b,
+ 0x8b4a, 0x1dea,
+ 0x8b4b, 0x0646,
+ 0x8b5f, 0x1deb,
+ 0x8b60, 0x065b,
+ 0x8b80, 0x067a,
+ 0x8ba0, 0x1dec,
+ 0x8ba1, 0x069b,
+ 0x8ba8, 0x1ded,
+ 0x8ba9, 0x06a3,
+ 0x8bc4, 0x1d32,
+ 0x8bc5, 0x06bf,
+ 0x8bcd, 0x1dee,
+ 0x8bce, 0x06c8,
+ 0x8beb, 0x1def,
+ 0x8bec, 0x06e6,
+ 0x8bf2, 0x1df0,
+ 0x8bf3, 0x06ed,
+ 0x8bf9, 0x1df1,
+ 0x8bfa, 0x06f4,
+ 0x8bfb, 0x1df2,
+ 0x8bfc, 0x06f6,
+ 0x8c40, 0x06f7,
+ 0x8c43, 0x1df3,
+ 0x8c44, 0x06fb,
+ 0x8c56, 0x1df4,
+ 0x8c57, 0x070e,
+ 0x8c64, 0x1df5,
+ 0x8c65, 0x071c,
+ 0x8c6d, 0x1df6,
+ 0x8c6e, 0x0725,
+ 0x8c71, 0x1df7,
+ 0x8c72, 0x0729,
+ 0x8c74, 0x1df8,
+ 0x8c75, 0x072c,
+ 0x8c7a, 0x1c0d,
+ 0x8c7b, 0x0732,
+ 0x8c80, 0x0736,
+ 0x8c84, 0x1df9,
+ 0x8c85, 0x073b,
+ 0x8c91, 0x1dfa,
+ 0x8c92, 0x0748,
+ 0x8c99, 0x1dfb,
+ 0x8c9a, 0x0750,
+ 0x8c9e, 0x1dfc,
+ 0x8c9f, 0x0755,
+ 0x8cb2, 0x1dfd,
+ 0x8cb3, 0x0769,
+ 0x8cbf, 0x1dfe,
+ 0x8cc0, 0x0776,
+ 0x8d40, 0x07b3,
+ 0x8d4a, 0x1dff,
+ 0x8d4b, 0x07be,
+ 0x8d56, 0x1e00,
+ 0x8d57, 0x07ca,
+ 0x8d61, 0x1e01,
+ 0x8d62, 0x07d5,
+ 0x8d7b, 0x16dd,
+ 0x8d7c, 0x07ef,
+ 0x8d80, 0x07f2,
+ 0x8d8d, 0x1e02,
+ 0x8d8e, 0x0800,
+ 0x8d94, 0x1e03,
+ 0x8d95, 0x0807,
+ 0x8d99, 0x1e04,
+ 0x8d9a, 0x080c,
+ 0x8dd1, 0x1e05,
+ 0x8dd2, 0x0844,
+ 0x8de5, 0x1e06,
+ 0x8de6, 0x0858,
+ 0x8df2, 0x1e07,
+ 0x8df3, 0x0865,
+ 0x8e40, 0x086f,
+ 0x8e46, 0x1e08,
+ 0x8e47, 0x0876,
+ 0x8e49, 0x1e09,
+ 0x8e4a, 0x0879,
+ 0x8e4b, 0x1e0a,
+ 0x8e4c, 0x087b,
+ 0x8e58, 0x1e0b,
+ 0x8e59, 0x0888,
+ 0x8e80, 0x08ae,
+ 0x8ec6, 0x1e0d,
+ 0x8ec7, 0x1929,
+ 0x8ec8, 0x08f6,
+ 0x8ed5, 0x1e0e,
+ 0x8ed6, 0x0904,
+ 0x8edb, 0x1e0f,
+ 0x8edd, 0x090b,
+ 0x8f40, 0x092b,
+ 0x8f4a, 0x1e11,
+ 0x8f4b, 0x0936,
+ 0x8f55, 0x1e12,
+ 0x8f56, 0x0941,
+ 0x8f80, 0x096a,
+ 0x8f8c, 0x1e13,
+ 0x8f8e, 0x0978,
+ 0x8f92, 0x1e15,
+ 0x8f94, 0x097e,
+ 0x8fa3, 0x1e17,
+ 0x8fa4, 0x098e,
+ 0x8fb1, 0x1e18,
+ 0x8fb2, 0x099c,
+ 0x8fbd, 0x1e19,
+ 0x8fbe, 0x09a8,
+ 0x8fd3, 0x1e1a,
+ 0x8fd4, 0x09be,
+ 0x8fdd, 0x1e1b,
+ 0x8fde, 0x09c8,
+ 0x8fe2, 0x1e1c,
+ 0x8fe3, 0x09cd,
+ 0x9040, 0x09e7,
+ 0x9049, 0x1e1d,
+ 0x904a, 0x09f1,
+ 0x9078, 0x1e1e,
+ 0x9079, 0x0a20,
+ 0x9080, 0x1e1f,
+ 0x9081, 0x0a27,
+ 0x9089, 0x1e20,
+ 0x908a, 0x0a30,
+ 0x90a0, 0x1e21,
+ 0x90a1, 0x0a47,
+ 0x90c0, 0x1e22,
+ 0x90c1, 0x0a67,
+ 0x90e4, 0x1e23,
+ 0x90e5, 0x0a8b,
+ 0x90ef, 0x1e24,
+ 0x90f1, 0x0a97,
+ 0x90f7, 0x1e26,
+ 0x90f9, 0x0a9f,
+ 0x9140, 0x0aa3,
+ 0x9146, 0x1e28,
+ 0x9147, 0x1a6e,
+ 0x9148, 0x0aab,
+ 0x9158, 0x1e29,
+ 0x9159, 0x0abc,
+ 0x916b, 0x1e2a,
+ 0x916c, 0x0acf,
+ 0x916e, 0x1e2b,
+ 0x916f, 0x0ad2,
+ 0x917e, 0x1e2c,
+ 0x9180, 0x0ae2,
+ 0x9189, 0x1e2d,
+ 0x918a, 0x0aec,
+ 0x91bb, 0x1e2e,
+ 0x91bc, 0x0b1e,
+ 0x91cb, 0x1e2f,
+ 0x91cc, 0x0b2e,
+ 0x91da, 0x1e30,
+ 0x91db, 0x0b3d,
+ 0x91e1, 0x1e31,
+ 0x91e2, 0x0b44,
+ 0x91ed, 0x1e32,
+ 0x91ee, 0x0b50,
+ 0x91f3, 0x1e33,
+ 0x91f5, 0x0b57,
+ 0x91fb, 0x1e35,
+ 0x91fc, 0x0b5e,
+ 0x9240, 0x0b5f,
+ 0x9246, 0x1e36,
+ 0x9247, 0x0b66,
+ 0x9248, 0x1e37,
+ 0x924a, 0x0b69,
+ 0x924c, 0x1e39,
+ 0x924e, 0x0b6d,
+ 0x925c, 0x1e3b,
+ 0x925d, 0x0b7c,
+ 0x9280, 0x0b9e,
+ 0x9290, 0x1e3c,
+ 0x9291, 0x0baf,
+ 0x9295, 0x1e3d,
+ 0x9296, 0x0bb4,
+ 0x929c, 0x1e3e,
+ 0x929d, 0x0bbb,
+ 0x92bb, 0x1e3f,
+ 0x92bc, 0x0bda,
+ 0x92c6, 0x1e40,
+ 0x92c7, 0x0be5,
+ 0x92c8, 0x1e41,
+ 0x92c9, 0x0be7,
+ 0x92cb, 0x1e42,
+ 0x92cc, 0x0bea,
+ 0x92cd, 0x1e43,
+ 0x92ce, 0x0bec,
+ 0x92d2, 0x204b,
+ 0x92d3, 0x0bf1,
+ 0x92d9, 0x11b5,
+ 0x92da, 0x0bf8,
+ 0x9340, 0x0c1b,
+ 0x9341, 0x1e44,
+ 0x9342, 0x0c1d,
+ 0x9346, 0x1e45,
+ 0x9347, 0x0c22,
+ 0x934d, 0x1e46,
+ 0x934e, 0x0c29,
+ 0x9355, 0x1e47,
+ 0x9356, 0x0c31,
+ 0x935e, 0x1e48,
+ 0x935f, 0x0c3a,
+ 0x9367, 0x1e49,
+ 0x9368, 0x0c43,
+ 0x936a, 0x1e4a,
+ 0x936b, 0x0c46,
+ 0x9370, 0x1e4b,
+ 0x9372, 0x0c4d,
+ 0x9376, 0x16df,
+ 0x9377, 0x0c52,
+ 0x9380, 0x0c5a,
+ 0x9384, 0x1e4d,
+ 0x9385, 0x0c5f,
+ 0x938e, 0x1450,
+ 0x938f, 0x0c69,
+ 0x9393, 0x1536,
+ 0x9394, 0x0c6e,
+ 0x9398, 0x1e4e,
+ 0x9399, 0x0c73,
+ 0x93bc, 0x1e4f,
+ 0x93bd, 0x0c97,
+ 0x93c0, 0x1e50,
+ 0x93c1, 0x0c9b,
+ 0x93d2, 0x1e51,
+ 0x93d4, 0x0cae,
+ 0x93d9, 0x1e53,
+ 0x93db, 0x0cb5,
+ 0x93df, 0x1e55,
+ 0x93e0, 0x0cba,
+ 0x93e4, 0x1e56,
+ 0x93e6, 0x0cc0,
+ 0x93e8, 0x1e58,
+ 0x93e9, 0x0cc3,
+ 0x93f4, 0x1aed,
+ 0x93f5, 0x0ccf,
+ 0x9440, 0x0cd7,
+ 0x9448, 0x1e59,
+ 0x9449, 0x0ce0,
+ 0x9458, 0x1e5a,
+ 0x9459, 0x0cf0,
+ 0x9476, 0x1e5b,
+ 0x9477, 0x0d0e,
+ 0x9480, 0x0d16,
+ 0x9487, 0x1e5c,
+ 0x9488, 0x1989,
+ 0x9489, 0x1e5d,
+ 0x948a, 0x0d20,
+ 0x948d, 0x1e5e,
+ 0x948e, 0x0d24,
+ 0x94a2, 0x1e5f,
+ 0x94a3, 0x0d39,
+ 0x94ac, 0x1e60,
+ 0x94ad, 0x0d43,
+ 0x94ae, 0x1e61,
+ 0x94af, 0x0d45,
+ 0x94d2, 0x1e62,
+ 0x94d3, 0x0d69,
+ 0x94e0, 0x1e63,
+ 0x94e1, 0x0d77,
+ 0x94f3, 0x1e64,
+ 0x94f4, 0x0d8a,
+ 0x9540, 0x0d93,
+ 0x9541, 0x1e65,
+ 0x9543, 0x0d96,
+ 0x954e, 0x1e67,
+ 0x954f, 0x143b,
+ 0x9550, 0x0da3,
+ 0x9551, 0x1e68,
+ 0x9552, 0x0da5,
+ 0x9554, 0x1e69,
+ 0x9555, 0x0da8,
+ 0x955f, 0x1e6a,
+ 0x9560, 0x0db3,
+ 0x956d, 0x1e6b,
+ 0x956e, 0x0dc1,
+ 0x9570, 0x1e6c,
+ 0x9571, 0x0dc4,
+ 0x9580, 0x0dd2,
+ 0x95c1, 0x1e6d,
+ 0x95c2, 0x0e14,
+ 0x95cb, 0x1e6e,
+ 0x95cc, 0x0e1e,
+ 0x95d8, 0x1e6f,
+ 0x95d9, 0x0e2b,
+ 0x95f7, 0x1e70,
+ 0x95f8, 0x0e4a,
+ 0x9640, 0x0e4f,
+ 0x9641, 0x1e71,
+ 0x9642, 0x0e51,
+ 0x9648, 0x1e72,
+ 0x9649, 0x0e58,
+ 0x966a, 0x1e73,
+ 0x966b, 0x0e7a,
+ 0x9680, 0x0e8e,
+ 0x968a, 0x1d33,
+ 0x968b, 0x0e99,
+ 0x9690, 0x1e74,
+ 0x9691, 0x0e9f,
+ 0x9698, 0x1f2c,
+ 0x9699, 0x102f,
+ 0x969a, 0x0ea8,
+ 0x96cb, 0x1e75,
+ 0x96cc, 0x0eda,
+ 0x96d7, 0x1e76,
+ 0x96d8, 0x0ee6,
+ 0x96dd, 0x1e77,
+ 0x96de, 0x0eec,
+ 0x96e0, 0x1e78,
+ 0x96e1, 0x0eef,
+ 0x96f7, 0x1935,
+ 0x96f8, 0x1e79,
+ 0x96f9, 0x0f07,
+ 0x96fa, 0x1e7a,
+ 0x96fb, 0x0f09,
+ 0x96fc, 0x1e7b,
+ 0x9740, 0x0f0b,
+ 0x9751, 0x1e7c,
+ 0x9752, 0x0f1d,
+ 0x976f, 0x1e7d,
+ 0x9770, 0x0f3b,
+ 0x9773, 0x1e7e,
+ 0x9774, 0x0f3f,
+ 0x9779, 0x1d34,
+ 0x977a, 0x0f45,
+ 0x9780, 0x0f4a,
+ 0x9789, 0x1e7f,
+ 0x978a, 0x0f54,
+ 0x97c9, 0x1e80,
+ 0x97ca, 0x0f94,
+ 0x97f8, 0x1e81,
+ 0x97fa, 0x0fc4,
+ 0x9840, 0x1e83,
+ 0x9841, 0x0fc8,
+ 0x9850, 0x1e84,
+ 0x9851, 0x0fd8,
+ 0x9855, 0x1777,
+ 0x9856, 0x0fdd,
+ 0x9858, 0x1e85,
+ 0x9859, 0x0fe0,
+ 0x989f, 0x0ffa,
+ 0x98d4, 0x0ea7,
+ 0x98d5, 0x1030,
+ 0x9940, 0x1058,
+ 0x995c, 0x1e86,
+ 0x995d, 0x1075,
+ 0x9966, 0x1e87,
+ 0x9967, 0x107f,
+ 0x996a, 0x1e88,
+ 0x996b, 0x1083,
+ 0x996c, 0x1e89,
+ 0x996d, 0x1085,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a4f, 0x1e8a,
+ 0x9a50, 0x1124,
+ 0x9a59, 0x1e8b,
+ 0x9a5a, 0x112e,
+ 0x9a7d, 0x1e8d,
+ 0x9a7e, 0x1152,
+ 0x9a80, 0x1153,
+ 0x9a8b, 0x1e8e,
+ 0x9a8c, 0x115f,
+ 0x9ac2, 0x1e8f,
+ 0x9ac3, 0x1196,
+ 0x9ae2, 0x0bf7,
+ 0x9ae3, 0x11b6,
+ 0x9b40, 0x11d0,
+ 0x9b5c, 0x1e90,
+ 0x9b5d, 0x11ed,
+ 0x9b80, 0x120f,
+ 0x9b83, 0x1e91,
+ 0x9b84, 0x1213,
+ 0x9ba0, 0x1e92,
+ 0x9ba1, 0x1230,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9ca2, 0x1e94,
+ 0x9ca3, 0x12ee,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1e95,
+ 0x9d81, 0x1388,
+ 0x9d8c, 0x1e96,
+ 0x9d8d, 0x1394,
+ 0x9d98, 0x05a7,
+ 0x9d99, 0x13a0,
+ 0x9db7, 0x1e97,
+ 0x9db8, 0x13bf,
+ 0x9dcb, 0x1e98,
+ 0x9dcc, 0x13d3,
+ 0x9e40, 0x1404,
+ 0x9e64, 0x1e99,
+ 0x9e65, 0x1429,
+ 0x9e69, 0x1e9a,
+ 0x9e6a, 0x142e,
+ 0x9e77, 0x0da2,
+ 0x9e78, 0x143c,
+ 0x9e80, 0x1443,
+ 0x9e8b, 0x1e9b,
+ 0x9e8c, 0x144f,
+ 0x9e8d, 0x0c68,
+ 0x9e8e, 0x1451,
+ 0x9e94, 0x1e9c,
+ 0x9e95, 0x1458,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0x9fb7, 0x0c6d,
+ 0x9fb8, 0x1537,
+ 0x9fce, 0x1e9d,
+ 0x9fcf, 0x154e,
+ 0x9ff3, 0x05ff,
+ 0x9ff4, 0x1573,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe0a4, 0x1e9f,
+ 0xe0a5, 0x15e0,
+ 0xe0dd, 0x1ea0,
+ 0xe0de, 0x1619,
+ 0xe0f4, 0x1d35,
+ 0xe0f5, 0x1630,
+ 0xe140, 0x1638,
+ 0xe14a, 0x1ea1,
+ 0xe14b, 0x1643,
+ 0xe14f, 0x1ea2,
+ 0xe151, 0x1649,
+ 0xe180, 0x1677,
+ 0xe1a9, 0x1ea4,
+ 0xe1aa, 0x16a1,
+ 0xe1e6, 0x07ee,
+ 0xe1e7, 0x16de,
+ 0xe1e8, 0x0c51,
+ 0xe1e9, 0x16e0,
+ 0xe1ed, 0x1ea5,
+ 0xe1ee, 0x16e5,
+ 0xe240, 0x16f4,
+ 0xe269, 0x1ea6,
+ 0xe26a, 0x171e,
+ 0xe273, 0x1ea7,
+ 0xe274, 0x1728,
+ 0xe27d, 0x05d4,
+ 0xe27e, 0x1732,
+ 0xe280, 0x1733,
+ 0xe2b7, 0x1ea8,
+ 0xe2b8, 0x176b,
+ 0xe2c4, 0x0fdc,
+ 0xe2c5, 0x1778,
+ 0xe2e2, 0x1ea9,
+ 0xe2e3, 0x1796,
+ 0xe2ec, 0x1eaa,
+ 0xe2ed, 0x17a0,
+ 0xe340, 0x17b0,
+ 0xe358, 0x1eab,
+ 0xe359, 0x17c9,
+ 0xe35a, 0x1eac,
+ 0xe35b, 0x17cb,
+ 0xe365, 0x1ead,
+ 0xe366, 0x17d6,
+ 0xe380, 0x17ef,
+ 0xe3c4, 0x1eae,
+ 0xe3c5, 0x1834,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe484, 0x1eaf,
+ 0xe485, 0x18b0,
+ 0xe489, 0x1eb0,
+ 0xe48a, 0x18b5,
+ 0xe492, 0x1eb1,
+ 0xe493, 0x18be,
+ 0xe4b2, 0x1eb2,
+ 0xe4b3, 0x18de,
+ 0xe4b9, 0x1eb3,
+ 0xe4ba, 0x18e5,
+ 0xe4f2, 0x1eb4,
+ 0xe4f3, 0x191e,
+ 0xe540, 0x1928,
+ 0xe541, 0x08f5,
+ 0xe542, 0x192a,
+ 0xe54d, 0x0f05,
+ 0xe54e, 0x1936,
+ 0xe579, 0x05a0,
+ 0xe57a, 0x1962,
+ 0xe580, 0x1967,
+ 0xe5a2, 0x0d1e,
+ 0xe5a3, 0x198a,
+ 0xe5a5, 0x1eb6,
+ 0xe5a6, 0x198d,
+ 0xe5bb, 0x1eb7,
+ 0xe5bc, 0x19a3,
+ 0xe5ed, 0x1eb8,
+ 0xe5ee, 0x19d5,
+ 0xe640, 0x19e4,
+ 0xe651, 0x1eb9,
+ 0xe652, 0x19f6,
+ 0xe67c, 0x060e,
+ 0xe67d, 0x1a21,
+ 0xe680, 0x1a23,
+ 0xe686, 0x1eba,
+ 0xe687, 0x1a2a,
+ 0xe696, 0x1ebb,
+ 0xe697, 0x1a3a,
+ 0xe6cb, 0x0aaa,
+ 0xe6cc, 0x1a6f,
+ 0xe6e7, 0x1ebc,
+ 0xe6e8, 0x1a8b,
+ 0xe6f2, 0x1ebd,
+ 0xe6f3, 0x1a96,
+ 0xe740, 0x1aa0,
+ 0xe76d, 0x1ebe,
+ 0xe76e, 0x1ace,
+ 0xe780, 0x1adf,
+ 0xe78c, 0x1ebf,
+ 0xe78d, 0x1aec,
+ 0xe78e, 0x1ec0,
+ 0xe78f, 0x1aee,
+ 0xe7a7, 0x1ec1,
+ 0xe7a8, 0x1b07,
+ 0xe7bb, 0x1ec2,
+ 0xe7bc, 0x1b1b,
+ 0xe7d5, 0x1ec3,
+ 0xe7d6, 0x1b35,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe8c3, 0x1ec6,
+ 0xe8c4, 0x1bdf,
+ 0xe8cf, 0x1ec7,
+ 0xe8d0, 0x1beb,
+ 0xe8d5, 0x1ec8,
+ 0xe8d6, 0x1bf1,
+ 0xe8f2, 0x0731,
+ 0xe8f3, 0x1ec9,
+ 0xe8f4, 0x1c0f,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xe9ab, 0x1eca,
+ 0xe9ac, 0x1c83,
+ 0xe9ba, 0x1ecb,
+ 0xe9bb, 0x1c92,
+ 0xe9cb, 0x0477,
+ 0xe9cc, 0x1ecc,
+ 0xe9cd, 0x1ca4,
+ 0xe9f2, 0x0529,
+ 0xe9f3, 0x1cca,
+ 0xea40, 0x1cd4,
+ 0xea70, 0x1ecd,
+ 0xea71, 0x1d05,
+ 0xea80, 0x1d13,
+ 0xea9d, 0x1ece,
+ 0xea9e, 0x1d31,
+ 0xeaa3, 0x205c,
+ 0xed40, 0x20a7,
+ 0xed80, 0x20e6,
+ 0xedb4, 0x07c9,
+ 0xedb5, 0x211a,
+ 0xee40, 0x2162,
+ 0xee80, 0x21a1,
+ 0xeeef, 0x1f9c,
+ 0xeef9, 0x02ef,
+ 0xeefa, 0x1f45,
+ 0xfa40, 0x1f9c,
+ 0xfa4a, 0x1d97,
+ 0xfa54, 0x02ef,
+ 0xfa55, 0x1f45,
+ 0xfa58, 0x1dc2,
+ 0xfa59, 0x1dba,
+ 0xfa5a, 0x1f77,
+ 0xfa5b, 0x0300,
+ 0xfa5c, 0x20a7,
+ 0xfa80, 0x20ca,
+ 0xfad0, 0x07c9,
+ 0xfad1, 0x211a,
+ 0xfb40, 0x2146,
+ 0xfb80, 0x2185,
+ 0xfc40, 0x2202,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1278msRKSJHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0277, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1278msRKSJHMap2, 712
+};
+
+static Gushort japan1278msRKSJVMap2[1580] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x8740, 0x1d83,
+ 0x875f, 0x1da1,
+ 0x8761, 0x1f66,
+ 0x8762, 0x1da4,
+ 0x8763, 0x1f68,
+ 0x8764, 0x1da6,
+ 0x8765, 0x1f6a,
+ 0x8766, 0x1da8,
+ 0x8768, 0x1f6c,
+ 0x8769, 0x1dab,
+ 0x876b, 0x1f6b,
+ 0x876c, 0x1dae,
+ 0x876e, 0x1f6f,
+ 0x876f, 0x1db1,
+ 0x877e, 0x2083,
+ 0x8780, 0x1db8,
+ 0x8784, 0x1f77,
+ 0x8785, 0x1dbd,
+ 0x8790, 0x02fa,
+ 0x8791, 0x02f9,
+ 0x8792, 0x0301,
+ 0x8793, 0x1dc8,
+ 0x879a, 0x0300,
+ 0x879b, 0x1dcf,
+ 0x889f, 0x0465,
+ 0x88a0, 0x1dd1,
+ 0x88a1, 0x0467,
+ 0x88a7, 0x204a,
+ 0x88a8, 0x046e,
+ 0x88b0, 0x1f19,
+ 0x88b1, 0x1ca2,
+ 0x88b2, 0x0478,
+ 0x88b9, 0x1dd2,
+ 0x88ba, 0x0480,
+ 0x88ec, 0x1dd3,
+ 0x88ed, 0x04b3,
+ 0x88f1, 0x1dd4,
+ 0x88f2, 0x04b8,
+ 0x88fa, 0x1dd5,
+ 0x88fb, 0x04c1,
+ 0x8940, 0x04c3,
+ 0x8949, 0x1dd6,
+ 0x894a, 0x04cd,
+ 0x8954, 0x1dd7,
+ 0x8955, 0x04d8,
+ 0x8958, 0x1dd8,
+ 0x8959, 0x04dc,
+ 0x895c, 0x1dda,
+ 0x895d, 0x04e0,
+ 0x8961, 0x1ddb,
+ 0x8962, 0x04e5,
+ 0x8980, 0x0502,
+ 0x898b, 0x1ddc,
+ 0x898c, 0x050e,
+ 0x89a6, 0x1ddd,
+ 0x89a7, 0x1cc9,
+ 0x89a8, 0x1dde,
+ 0x89a9, 0x052b,
+ 0x89de, 0x1ddf,
+ 0x89df, 0x0561,
+ 0x89f8, 0x1de0,
+ 0x89f9, 0x057b,
+ 0x89fb, 0x1de1,
+ 0x89fc, 0x057e,
+ 0x8a40, 0x057f,
+ 0x8a41, 0x1de2,
+ 0x8a42, 0x0581,
+ 0x8a61, 0x1961,
+ 0x8a62, 0x05a1,
+ 0x8a68, 0x139f,
+ 0x8a69, 0x05a8,
+ 0x8a80, 0x05be,
+ 0x8a85, 0x1de3,
+ 0x8a86, 0x05c4,
+ 0x8a8b, 0x1de4,
+ 0x8a8c, 0x05ca,
+ 0x8a93, 0x1de5,
+ 0x8a94, 0x05d2,
+ 0x8a96, 0x1731,
+ 0x8a97, 0x05d5,
+ 0x8a9a, 0x1de6,
+ 0x8a9b, 0x05d9,
+ 0x8ac0, 0x1de7,
+ 0x8ac1, 0x1572,
+ 0x8ac2, 0x0600,
+ 0x8acb, 0x1de8,
+ 0x8acc, 0x060a,
+ 0x8ad0, 0x1a20,
+ 0x8ad1, 0x060f,
+ 0x8ae3, 0x1de9,
+ 0x8ae4, 0x0622,
+ 0x8b40, 0x063b,
+ 0x8b4a, 0x1dea,
+ 0x8b4b, 0x0646,
+ 0x8b5f, 0x1deb,
+ 0x8b60, 0x065b,
+ 0x8b80, 0x067a,
+ 0x8ba0, 0x1dec,
+ 0x8ba1, 0x069b,
+ 0x8ba8, 0x1ded,
+ 0x8ba9, 0x06a3,
+ 0x8bc4, 0x1d32,
+ 0x8bc5, 0x06bf,
+ 0x8bcd, 0x1dee,
+ 0x8bce, 0x06c8,
+ 0x8beb, 0x1def,
+ 0x8bec, 0x06e6,
+ 0x8bf2, 0x1df0,
+ 0x8bf3, 0x06ed,
+ 0x8bf9, 0x1df1,
+ 0x8bfa, 0x06f4,
+ 0x8bfb, 0x1df2,
+ 0x8bfc, 0x06f6,
+ 0x8c40, 0x06f7,
+ 0x8c43, 0x1df3,
+ 0x8c44, 0x06fb,
+ 0x8c56, 0x1df4,
+ 0x8c57, 0x070e,
+ 0x8c64, 0x1df5,
+ 0x8c65, 0x071c,
+ 0x8c6d, 0x1df6,
+ 0x8c6e, 0x0725,
+ 0x8c71, 0x1df7,
+ 0x8c72, 0x0729,
+ 0x8c74, 0x1df8,
+ 0x8c75, 0x072c,
+ 0x8c7a, 0x1c0d,
+ 0x8c7b, 0x0732,
+ 0x8c80, 0x0736,
+ 0x8c84, 0x1df9,
+ 0x8c85, 0x073b,
+ 0x8c91, 0x1dfa,
+ 0x8c92, 0x0748,
+ 0x8c99, 0x1dfb,
+ 0x8c9a, 0x0750,
+ 0x8c9e, 0x1dfc,
+ 0x8c9f, 0x0755,
+ 0x8cb2, 0x1dfd,
+ 0x8cb3, 0x0769,
+ 0x8cbf, 0x1dfe,
+ 0x8cc0, 0x0776,
+ 0x8d40, 0x07b3,
+ 0x8d4a, 0x1dff,
+ 0x8d4b, 0x07be,
+ 0x8d56, 0x1e00,
+ 0x8d57, 0x07ca,
+ 0x8d61, 0x1e01,
+ 0x8d62, 0x07d5,
+ 0x8d7b, 0x16dd,
+ 0x8d7c, 0x07ef,
+ 0x8d80, 0x07f2,
+ 0x8d8d, 0x1e02,
+ 0x8d8e, 0x0800,
+ 0x8d94, 0x1e03,
+ 0x8d95, 0x0807,
+ 0x8d99, 0x1e04,
+ 0x8d9a, 0x080c,
+ 0x8dd1, 0x1e05,
+ 0x8dd2, 0x0844,
+ 0x8de5, 0x1e06,
+ 0x8de6, 0x0858,
+ 0x8df2, 0x1e07,
+ 0x8df3, 0x0865,
+ 0x8e40, 0x086f,
+ 0x8e46, 0x1e08,
+ 0x8e47, 0x0876,
+ 0x8e49, 0x1e09,
+ 0x8e4a, 0x0879,
+ 0x8e4b, 0x1e0a,
+ 0x8e4c, 0x087b,
+ 0x8e58, 0x1e0b,
+ 0x8e59, 0x0888,
+ 0x8e80, 0x08ae,
+ 0x8ec6, 0x1e0d,
+ 0x8ec7, 0x1929,
+ 0x8ec8, 0x08f6,
+ 0x8ed5, 0x1e0e,
+ 0x8ed6, 0x0904,
+ 0x8edb, 0x1e0f,
+ 0x8edd, 0x090b,
+ 0x8f40, 0x092b,
+ 0x8f4a, 0x1e11,
+ 0x8f4b, 0x0936,
+ 0x8f55, 0x1e12,
+ 0x8f56, 0x0941,
+ 0x8f80, 0x096a,
+ 0x8f8c, 0x1e13,
+ 0x8f8e, 0x0978,
+ 0x8f92, 0x1e15,
+ 0x8f94, 0x097e,
+ 0x8fa3, 0x1e17,
+ 0x8fa4, 0x098e,
+ 0x8fb1, 0x1e18,
+ 0x8fb2, 0x099c,
+ 0x8fbd, 0x1e19,
+ 0x8fbe, 0x09a8,
+ 0x8fd3, 0x1e1a,
+ 0x8fd4, 0x09be,
+ 0x8fdd, 0x1e1b,
+ 0x8fde, 0x09c8,
+ 0x8fe2, 0x1e1c,
+ 0x8fe3, 0x09cd,
+ 0x9040, 0x09e7,
+ 0x9049, 0x1e1d,
+ 0x904a, 0x09f1,
+ 0x9078, 0x1e1e,
+ 0x9079, 0x0a20,
+ 0x9080, 0x1e1f,
+ 0x9081, 0x0a27,
+ 0x9089, 0x1e20,
+ 0x908a, 0x0a30,
+ 0x90a0, 0x1e21,
+ 0x90a1, 0x0a47,
+ 0x90c0, 0x1e22,
+ 0x90c1, 0x0a67,
+ 0x90e4, 0x1e23,
+ 0x90e5, 0x0a8b,
+ 0x90ef, 0x1e24,
+ 0x90f1, 0x0a97,
+ 0x90f7, 0x1e26,
+ 0x90f9, 0x0a9f,
+ 0x9140, 0x0aa3,
+ 0x9146, 0x1e28,
+ 0x9147, 0x1a6e,
+ 0x9148, 0x0aab,
+ 0x9158, 0x1e29,
+ 0x9159, 0x0abc,
+ 0x916b, 0x1e2a,
+ 0x916c, 0x0acf,
+ 0x916e, 0x1e2b,
+ 0x916f, 0x0ad2,
+ 0x917e, 0x1e2c,
+ 0x9180, 0x0ae2,
+ 0x9189, 0x1e2d,
+ 0x918a, 0x0aec,
+ 0x91bb, 0x1e2e,
+ 0x91bc, 0x0b1e,
+ 0x91cb, 0x1e2f,
+ 0x91cc, 0x0b2e,
+ 0x91da, 0x1e30,
+ 0x91db, 0x0b3d,
+ 0x91e1, 0x1e31,
+ 0x91e2, 0x0b44,
+ 0x91ed, 0x1e32,
+ 0x91ee, 0x0b50,
+ 0x91f3, 0x1e33,
+ 0x91f5, 0x0b57,
+ 0x91fb, 0x1e35,
+ 0x91fc, 0x0b5e,
+ 0x9240, 0x0b5f,
+ 0x9246, 0x1e36,
+ 0x9247, 0x0b66,
+ 0x9248, 0x1e37,
+ 0x924a, 0x0b69,
+ 0x924c, 0x1e39,
+ 0x924e, 0x0b6d,
+ 0x925c, 0x1e3b,
+ 0x925d, 0x0b7c,
+ 0x9280, 0x0b9e,
+ 0x9290, 0x1e3c,
+ 0x9291, 0x0baf,
+ 0x9295, 0x1e3d,
+ 0x9296, 0x0bb4,
+ 0x929c, 0x1e3e,
+ 0x929d, 0x0bbb,
+ 0x92bb, 0x1e3f,
+ 0x92bc, 0x0bda,
+ 0x92c6, 0x1e40,
+ 0x92c7, 0x0be5,
+ 0x92c8, 0x1e41,
+ 0x92c9, 0x0be7,
+ 0x92cb, 0x1e42,
+ 0x92cc, 0x0bea,
+ 0x92cd, 0x1e43,
+ 0x92ce, 0x0bec,
+ 0x92d2, 0x204b,
+ 0x92d3, 0x0bf1,
+ 0x92d9, 0x11b5,
+ 0x92da, 0x0bf8,
+ 0x9340, 0x0c1b,
+ 0x9341, 0x1e44,
+ 0x9342, 0x0c1d,
+ 0x9346, 0x1e45,
+ 0x9347, 0x0c22,
+ 0x934d, 0x1e46,
+ 0x934e, 0x0c29,
+ 0x9355, 0x1e47,
+ 0x9356, 0x0c31,
+ 0x935e, 0x1e48,
+ 0x935f, 0x0c3a,
+ 0x9367, 0x1e49,
+ 0x9368, 0x0c43,
+ 0x936a, 0x1e4a,
+ 0x936b, 0x0c46,
+ 0x9370, 0x1e4b,
+ 0x9372, 0x0c4d,
+ 0x9376, 0x16df,
+ 0x9377, 0x0c52,
+ 0x9380, 0x0c5a,
+ 0x9384, 0x1e4d,
+ 0x9385, 0x0c5f,
+ 0x938e, 0x1450,
+ 0x938f, 0x0c69,
+ 0x9393, 0x1536,
+ 0x9394, 0x0c6e,
+ 0x9398, 0x1e4e,
+ 0x9399, 0x0c73,
+ 0x93bc, 0x1e4f,
+ 0x93bd, 0x0c97,
+ 0x93c0, 0x1e50,
+ 0x93c1, 0x0c9b,
+ 0x93d2, 0x1e51,
+ 0x93d4, 0x0cae,
+ 0x93d9, 0x1e53,
+ 0x93db, 0x0cb5,
+ 0x93df, 0x1e55,
+ 0x93e0, 0x0cba,
+ 0x93e4, 0x1e56,
+ 0x93e6, 0x0cc0,
+ 0x93e8, 0x1e58,
+ 0x93e9, 0x0cc3,
+ 0x93f4, 0x1aed,
+ 0x93f5, 0x0ccf,
+ 0x9440, 0x0cd7,
+ 0x9448, 0x1e59,
+ 0x9449, 0x0ce0,
+ 0x9458, 0x1e5a,
+ 0x9459, 0x0cf0,
+ 0x9476, 0x1e5b,
+ 0x9477, 0x0d0e,
+ 0x9480, 0x0d16,
+ 0x9487, 0x1e5c,
+ 0x9488, 0x1989,
+ 0x9489, 0x1e5d,
+ 0x948a, 0x0d20,
+ 0x948d, 0x1e5e,
+ 0x948e, 0x0d24,
+ 0x94a2, 0x1e5f,
+ 0x94a3, 0x0d39,
+ 0x94ac, 0x1e60,
+ 0x94ad, 0x0d43,
+ 0x94ae, 0x1e61,
+ 0x94af, 0x0d45,
+ 0x94d2, 0x1e62,
+ 0x94d3, 0x0d69,
+ 0x94e0, 0x1e63,
+ 0x94e1, 0x0d77,
+ 0x94f3, 0x1e64,
+ 0x94f4, 0x0d8a,
+ 0x9540, 0x0d93,
+ 0x9541, 0x1e65,
+ 0x9543, 0x0d96,
+ 0x954e, 0x1e67,
+ 0x954f, 0x143b,
+ 0x9550, 0x0da3,
+ 0x9551, 0x1e68,
+ 0x9552, 0x0da5,
+ 0x9554, 0x1e69,
+ 0x9555, 0x0da8,
+ 0x955f, 0x1e6a,
+ 0x9560, 0x0db3,
+ 0x956d, 0x1e6b,
+ 0x956e, 0x0dc1,
+ 0x9570, 0x1e6c,
+ 0x9571, 0x0dc4,
+ 0x9580, 0x0dd2,
+ 0x95c1, 0x1e6d,
+ 0x95c2, 0x0e14,
+ 0x95cb, 0x1e6e,
+ 0x95cc, 0x0e1e,
+ 0x95d8, 0x1e6f,
+ 0x95d9, 0x0e2b,
+ 0x95f7, 0x1e70,
+ 0x95f8, 0x0e4a,
+ 0x9640, 0x0e4f,
+ 0x9641, 0x1e71,
+ 0x9642, 0x0e51,
+ 0x9648, 0x1e72,
+ 0x9649, 0x0e58,
+ 0x966a, 0x1e73,
+ 0x966b, 0x0e7a,
+ 0x9680, 0x0e8e,
+ 0x968a, 0x1d33,
+ 0x968b, 0x0e99,
+ 0x9690, 0x1e74,
+ 0x9691, 0x0e9f,
+ 0x9698, 0x1f2c,
+ 0x9699, 0x102f,
+ 0x969a, 0x0ea8,
+ 0x96cb, 0x1e75,
+ 0x96cc, 0x0eda,
+ 0x96d7, 0x1e76,
+ 0x96d8, 0x0ee6,
+ 0x96dd, 0x1e77,
+ 0x96de, 0x0eec,
+ 0x96e0, 0x1e78,
+ 0x96e1, 0x0eef,
+ 0x96f7, 0x1935,
+ 0x96f8, 0x1e79,
+ 0x96f9, 0x0f07,
+ 0x96fa, 0x1e7a,
+ 0x96fb, 0x0f09,
+ 0x96fc, 0x1e7b,
+ 0x9740, 0x0f0b,
+ 0x9751, 0x1e7c,
+ 0x9752, 0x0f1d,
+ 0x976f, 0x1e7d,
+ 0x9770, 0x0f3b,
+ 0x9773, 0x1e7e,
+ 0x9774, 0x0f3f,
+ 0x9779, 0x1d34,
+ 0x977a, 0x0f45,
+ 0x9780, 0x0f4a,
+ 0x9789, 0x1e7f,
+ 0x978a, 0x0f54,
+ 0x97c9, 0x1e80,
+ 0x97ca, 0x0f94,
+ 0x97f8, 0x1e81,
+ 0x97fa, 0x0fc4,
+ 0x9840, 0x1e83,
+ 0x9841, 0x0fc8,
+ 0x9850, 0x1e84,
+ 0x9851, 0x0fd8,
+ 0x9855, 0x1777,
+ 0x9856, 0x0fdd,
+ 0x9858, 0x1e85,
+ 0x9859, 0x0fe0,
+ 0x989f, 0x0ffa,
+ 0x98d4, 0x0ea7,
+ 0x98d5, 0x1030,
+ 0x9940, 0x1058,
+ 0x995c, 0x1e86,
+ 0x995d, 0x1075,
+ 0x9966, 0x1e87,
+ 0x9967, 0x107f,
+ 0x996a, 0x1e88,
+ 0x996b, 0x1083,
+ 0x996c, 0x1e89,
+ 0x996d, 0x1085,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a4f, 0x1e8a,
+ 0x9a50, 0x1124,
+ 0x9a59, 0x1e8b,
+ 0x9a5a, 0x112e,
+ 0x9a7d, 0x1e8d,
+ 0x9a7e, 0x1152,
+ 0x9a80, 0x1153,
+ 0x9a8b, 0x1e8e,
+ 0x9a8c, 0x115f,
+ 0x9ac2, 0x1e8f,
+ 0x9ac3, 0x1196,
+ 0x9ae2, 0x0bf7,
+ 0x9ae3, 0x11b6,
+ 0x9b40, 0x11d0,
+ 0x9b5c, 0x1e90,
+ 0x9b5d, 0x11ed,
+ 0x9b80, 0x120f,
+ 0x9b83, 0x1e91,
+ 0x9b84, 0x1213,
+ 0x9ba0, 0x1e92,
+ 0x9ba1, 0x1230,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9ca2, 0x1e94,
+ 0x9ca3, 0x12ee,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1e95,
+ 0x9d81, 0x1388,
+ 0x9d8c, 0x1e96,
+ 0x9d8d, 0x1394,
+ 0x9d98, 0x05a7,
+ 0x9d99, 0x13a0,
+ 0x9db7, 0x1e97,
+ 0x9db8, 0x13bf,
+ 0x9dcb, 0x1e98,
+ 0x9dcc, 0x13d3,
+ 0x9e40, 0x1404,
+ 0x9e64, 0x1e99,
+ 0x9e65, 0x1429,
+ 0x9e69, 0x1e9a,
+ 0x9e6a, 0x142e,
+ 0x9e77, 0x0da2,
+ 0x9e78, 0x143c,
+ 0x9e80, 0x1443,
+ 0x9e8b, 0x1e9b,
+ 0x9e8c, 0x144f,
+ 0x9e8d, 0x0c68,
+ 0x9e8e, 0x1451,
+ 0x9e94, 0x1e9c,
+ 0x9e95, 0x1458,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0x9fb7, 0x0c6d,
+ 0x9fb8, 0x1537,
+ 0x9fce, 0x1e9d,
+ 0x9fcf, 0x154e,
+ 0x9ff3, 0x05ff,
+ 0x9ff4, 0x1573,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe0a4, 0x1e9f,
+ 0xe0a5, 0x15e0,
+ 0xe0dd, 0x1ea0,
+ 0xe0de, 0x1619,
+ 0xe0f4, 0x1d35,
+ 0xe0f5, 0x1630,
+ 0xe140, 0x1638,
+ 0xe14a, 0x1ea1,
+ 0xe14b, 0x1643,
+ 0xe14f, 0x1ea2,
+ 0xe151, 0x1649,
+ 0xe180, 0x1677,
+ 0xe1a9, 0x1ea4,
+ 0xe1aa, 0x16a1,
+ 0xe1e6, 0x07ee,
+ 0xe1e7, 0x16de,
+ 0xe1e8, 0x0c51,
+ 0xe1e9, 0x16e0,
+ 0xe1ed, 0x1ea5,
+ 0xe1ee, 0x16e5,
+ 0xe240, 0x16f4,
+ 0xe269, 0x1ea6,
+ 0xe26a, 0x171e,
+ 0xe273, 0x1ea7,
+ 0xe274, 0x1728,
+ 0xe27d, 0x05d4,
+ 0xe27e, 0x1732,
+ 0xe280, 0x1733,
+ 0xe2b7, 0x1ea8,
+ 0xe2b8, 0x176b,
+ 0xe2c4, 0x0fdc,
+ 0xe2c5, 0x1778,
+ 0xe2e2, 0x1ea9,
+ 0xe2e3, 0x1796,
+ 0xe2ec, 0x1eaa,
+ 0xe2ed, 0x17a0,
+ 0xe340, 0x17b0,
+ 0xe358, 0x1eab,
+ 0xe359, 0x17c9,
+ 0xe35a, 0x1eac,
+ 0xe35b, 0x17cb,
+ 0xe365, 0x1ead,
+ 0xe366, 0x17d6,
+ 0xe380, 0x17ef,
+ 0xe3c4, 0x1eae,
+ 0xe3c5, 0x1834,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe484, 0x1eaf,
+ 0xe485, 0x18b0,
+ 0xe489, 0x1eb0,
+ 0xe48a, 0x18b5,
+ 0xe492, 0x1eb1,
+ 0xe493, 0x18be,
+ 0xe4b2, 0x1eb2,
+ 0xe4b3, 0x18de,
+ 0xe4b9, 0x1eb3,
+ 0xe4ba, 0x18e5,
+ 0xe4f2, 0x1eb4,
+ 0xe4f3, 0x191e,
+ 0xe540, 0x1928,
+ 0xe541, 0x08f5,
+ 0xe542, 0x192a,
+ 0xe54d, 0x0f05,
+ 0xe54e, 0x1936,
+ 0xe579, 0x05a0,
+ 0xe57a, 0x1962,
+ 0xe580, 0x1967,
+ 0xe5a2, 0x0d1e,
+ 0xe5a3, 0x198a,
+ 0xe5a5, 0x1eb6,
+ 0xe5a6, 0x198d,
+ 0xe5bb, 0x1eb7,
+ 0xe5bc, 0x19a3,
+ 0xe5ed, 0x1eb8,
+ 0xe5ee, 0x19d5,
+ 0xe640, 0x19e4,
+ 0xe651, 0x1eb9,
+ 0xe652, 0x19f6,
+ 0xe67c, 0x060e,
+ 0xe67d, 0x1a21,
+ 0xe680, 0x1a23,
+ 0xe686, 0x1eba,
+ 0xe687, 0x1a2a,
+ 0xe696, 0x1ebb,
+ 0xe697, 0x1a3a,
+ 0xe6cb, 0x0aaa,
+ 0xe6cc, 0x1a6f,
+ 0xe6e7, 0x1ebc,
+ 0xe6e8, 0x1a8b,
+ 0xe6f2, 0x1ebd,
+ 0xe6f3, 0x1a96,
+ 0xe740, 0x1aa0,
+ 0xe76d, 0x1ebe,
+ 0xe76e, 0x1ace,
+ 0xe780, 0x1adf,
+ 0xe78c, 0x1ebf,
+ 0xe78d, 0x1aec,
+ 0xe78e, 0x1ec0,
+ 0xe78f, 0x1aee,
+ 0xe7a7, 0x1ec1,
+ 0xe7a8, 0x1b07,
+ 0xe7bb, 0x1ec2,
+ 0xe7bc, 0x1b1b,
+ 0xe7d5, 0x1ec3,
+ 0xe7d6, 0x1b35,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe8c3, 0x1ec6,
+ 0xe8c4, 0x1bdf,
+ 0xe8cf, 0x1ec7,
+ 0xe8d0, 0x1beb,
+ 0xe8d5, 0x1ec8,
+ 0xe8d6, 0x1bf1,
+ 0xe8f2, 0x0731,
+ 0xe8f3, 0x1ec9,
+ 0xe8f4, 0x1c0f,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xe9ab, 0x1eca,
+ 0xe9ac, 0x1c83,
+ 0xe9ba, 0x1ecb,
+ 0xe9bb, 0x1c92,
+ 0xe9cb, 0x0477,
+ 0xe9cc, 0x1ecc,
+ 0xe9cd, 0x1ca4,
+ 0xe9f2, 0x0529,
+ 0xe9f3, 0x1cca,
+ 0xea40, 0x1cd4,
+ 0xea70, 0x1ecd,
+ 0xea71, 0x1d05,
+ 0xea80, 0x1d13,
+ 0xea9d, 0x1ece,
+ 0xea9e, 0x1d31,
+ 0xeaa3, 0x205c,
+ 0xed40, 0x20a7,
+ 0xed80, 0x20e6,
+ 0xedb4, 0x07c9,
+ 0xedb5, 0x211a,
+ 0xee40, 0x2162,
+ 0xee80, 0x21a1,
+ 0xeeef, 0x1f9c,
+ 0xeef9, 0x02ef,
+ 0xeefa, 0x1f45,
+ 0xfa40, 0x1f9c,
+ 0xfa4a, 0x1d97,
+ 0xfa54, 0x02ef,
+ 0xfa55, 0x1f45,
+ 0xfa58, 0x1dc2,
+ 0xfa59, 0x1dba,
+ 0xfa5a, 0x1f77,
+ 0xfa5b, 0x0300,
+ 0xfa5c, 0x20a7,
+ 0xfa80, 0x20ca,
+ 0xfad0, 0x07c9,
+ 0xfad1, 0x211a,
+ 0xfb40, 0x2146,
+ 0xfb80, 0x2185,
+ 0xfc40, 0x2202,
+ 0x8141, 0x1ecf,
+ 0x8143, 0x204c,
+ 0x8144, 0x2052,
+ 0x8150, 0x1ed1,
+ 0x815b, 0x1ed3,
+ 0x8160, 0x1ed6,
+ 0x8169, 0x1edb,
+ 0x8181, 0x1eed,
+ 0x81a8, 0x02e3,
+ 0x81a9, 0x02e2,
+ 0x81aa, 0x02e0,
+ 0x81ac, 0x204e,
+ 0x829f, 0x1eee,
+ 0x82a1, 0x1eef,
+ 0x82a3, 0x1ef0,
+ 0x82a5, 0x1ef1,
+ 0x82a7, 0x1ef2,
+ 0x82c1, 0x1ef3,
+ 0x82e1, 0x1ef4,
+ 0x82e3, 0x1ef5,
+ 0x82e5, 0x1ef6,
+ 0x82ec, 0x1ef7,
+ 0x8340, 0x1ef8,
+ 0x8342, 0x1ef9,
+ 0x8344, 0x1efa,
+ 0x8346, 0x1efb,
+ 0x8348, 0x1efc,
+ 0x8362, 0x1efd,
+ 0x8383, 0x1efe,
+ 0x8385, 0x1eff,
+ 0x8387, 0x1f00,
+ 0x838e, 0x1f01,
+ 0x8395, 0x1f02,
+ 0x849f, 0x1d39,
+ 0x84a0, 0x1d37,
+ 0x84a1, 0x1d47,
+ 0x84a2, 0x1d4f,
+ 0x84a3, 0x1d4b,
+ 0x84a4, 0x1d43,
+ 0x84a5, 0x1d63,
+ 0x84a6, 0x1d5b,
+ 0x84a7, 0x1d6b,
+ 0x84a8, 0x1d53,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d3a,
+ 0x84ab, 0x1d38,
+ 0x84ac, 0x1d4a,
+ 0x84ad, 0x1d52,
+ 0x84ae, 0x1d4e,
+ 0x84af, 0x1d46,
+ 0x84b0, 0x1d6a,
+ 0x84b1, 0x1d62,
+ 0x84b2, 0x1d72,
+ 0x84b3, 0x1d5a,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d66,
+ 0x84b6, 0x1d5f,
+ 0x84b7, 0x1d6e,
+ 0x84b8, 0x1d57,
+ 0x84b9, 0x1d79,
+ 0x84ba, 0x1d67,
+ 0x84bb, 0x1d5c,
+ 0x84bc, 0x1d6f,
+ 0x84bd, 0x1d54,
+ 0x84be, 0x1d76,
+ 0x875f, 0x1f04,
+ 0x8761, 0x2089,
+ 0x8762, 0x1f07,
+ 0x8763, 0x2093,
+ 0x8764, 0x1f09,
+ 0x8765, 0x2092,
+ 0x8766, 0x1f0b,
+ 0x8768, 0x2098,
+ 0x8769, 0x1f0e,
+ 0x876b, 0x209c,
+ 0x876c, 0x1f11,
+ 0x876e, 0x209d,
+ 0x8780, 0x1f14,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1278msRKSJVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0277, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1278msRKSJVMap2, 790
+};
+
+static Gushort japan1283pvRKSJHMap2[436] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x8540, 0x00e8,
+ 0x8580, 0x0186,
+ 0x8581, 0x0128,
+ 0x859f, 0x0147,
+ 0x85de, 0x0187,
+ 0x8640, 0x01a6,
+ 0x8680, 0x01e5,
+ 0x8692, 0x0127,
+ 0x8693, 0x01f7,
+ 0x86a2, 0x1d37,
+ 0x8740, 0x1d83,
+ 0x875f, 0x1da1,
+ 0x8780, 0x1db8,
+ 0x8790, 0x02fa,
+ 0x8791, 0x02f9,
+ 0x8792, 0x0301,
+ 0x8793, 0x1dc8,
+ 0x879a, 0x0300,
+ 0x879b, 0x1dcf,
+ 0x889f, 0x0465,
+ 0x8940, 0x04c3,
+ 0x8980, 0x0502,
+ 0x8a40, 0x057f,
+ 0x8a80, 0x05be,
+ 0x8b40, 0x063b,
+ 0x8b80, 0x067a,
+ 0x8c40, 0x06f7,
+ 0x8c80, 0x0736,
+ 0x8d40, 0x07b3,
+ 0x8d80, 0x07f2,
+ 0x8e40, 0x086f,
+ 0x8e80, 0x08ae,
+ 0x8f40, 0x092b,
+ 0x8f80, 0x096a,
+ 0x9040, 0x09e7,
+ 0x9080, 0x0a26,
+ 0x9140, 0x0aa3,
+ 0x9180, 0x0ae2,
+ 0x9240, 0x0b5f,
+ 0x9280, 0x0b9e,
+ 0x9340, 0x0c1b,
+ 0x9380, 0x0c5a,
+ 0x9440, 0x0cd7,
+ 0x9480, 0x0d16,
+ 0x9540, 0x0d93,
+ 0x9580, 0x0dd2,
+ 0x9640, 0x0e4f,
+ 0x9680, 0x0e8e,
+ 0x9740, 0x0f0b,
+ 0x9780, 0x0f4a,
+ 0x9840, 0x0fc7,
+ 0x989f, 0x0ffa,
+ 0x9940, 0x1058,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a80, 0x1153,
+ 0x9b40, 0x11d0,
+ 0x9b80, 0x120f,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1387,
+ 0x9e40, 0x1404,
+ 0x9e80, 0x1443,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe140, 0x1638,
+ 0xe180, 0x1677,
+ 0xe240, 0x16f4,
+ 0xe280, 0x1733,
+ 0xe340, 0x17b0,
+ 0xe380, 0x17ef,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe540, 0x1928,
+ 0xe580, 0x1967,
+ 0xe640, 0x19e4,
+ 0xe680, 0x1a23,
+ 0xe740, 0x1aa0,
+ 0xe780, 0x1adf,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xea40, 0x1cd4,
+ 0xea80, 0x1d13,
+ 0xeaa3, 0x205c,
+ 0xeb40, 0x0279,
+ 0xeb41, 0x1ecf,
+ 0xeb43, 0x027c,
+ 0xeb50, 0x1ed1,
+ 0xeb52, 0x028b,
+ 0xeb5b, 0x1ed3,
+ 0xeb5e, 0x0297,
+ 0xeb60, 0x1ed6,
+ 0xeb65, 0x029e,
+ 0xeb69, 0x1edb,
+ 0xeb7b, 0x02b4,
+ 0xeb80, 0x02b8,
+ 0xeb81, 0x1eed,
+ 0xeb82, 0x02ba,
+ 0xebb8, 0x02e5,
+ 0xebc8, 0x02ed,
+ 0xebda, 0x02f4,
+ 0xebf0, 0x0303,
+ 0xebfc, 0x030b,
+ 0xec4f, 0x030c,
+ 0xec60, 0x0316,
+ 0xec81, 0x0330,
+ 0xec9f, 0x1eee,
+ 0xeca0, 0x034b,
+ 0xeca1, 0x1eef,
+ 0xeca2, 0x034d,
+ 0xeca3, 0x1ef0,
+ 0xeca4, 0x034f,
+ 0xeca5, 0x1ef1,
+ 0xeca6, 0x0351,
+ 0xeca7, 0x1ef2,
+ 0xeca8, 0x0353,
+ 0xecc1, 0x1ef3,
+ 0xecc2, 0x036d,
+ 0xece1, 0x1ef4,
+ 0xece2, 0x038d,
+ 0xece3, 0x1ef5,
+ 0xece4, 0x038f,
+ 0xece5, 0x1ef6,
+ 0xece6, 0x0391,
+ 0xecec, 0x1ef7,
+ 0xeced, 0x0398,
+ 0xed40, 0x1ef8,
+ 0xed41, 0x039e,
+ 0xed42, 0x1ef9,
+ 0xed43, 0x03a0,
+ 0xed44, 0x1efa,
+ 0xed45, 0x03a2,
+ 0xed46, 0x1efb,
+ 0xed47, 0x03a4,
+ 0xed48, 0x1efc,
+ 0xed49, 0x03a6,
+ 0xed62, 0x1efd,
+ 0xed63, 0x03c0,
+ 0xed80, 0x03dc,
+ 0xed83, 0x1efe,
+ 0xed84, 0x03e0,
+ 0xed85, 0x1eff,
+ 0xed86, 0x03e2,
+ 0xed87, 0x1f00,
+ 0xed88, 0x03e4,
+ 0xed8e, 0x1f01,
+ 0xed8f, 0x03eb,
+ 0xed95, 0x1f02,
+ 0xed9f, 0x03f3,
+ 0xedbf, 0x040b,
+ 0xee40, 0x1d83,
+ 0xee5f, 0x1f04,
+ 0xee6f, 0x1db1,
+ 0xee80, 0x1f14,
+ 0xee82, 0x1dba,
+ 0xee90, 0x02fa,
+ 0xee91, 0x02f9,
+ 0xee92, 0x0301,
+ 0xee93, 0x1dc8,
+ 0xee9a, 0x0300,
+ 0xee9b, 0x1dcf,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1283pvRKSJHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0061, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0098, 0x00e4, 0x007c },
+ japan1283pvRKSJHMap2, 218
+};
+
+static Gushort japan1290msRKSJHMap2[340] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x8740, 0x1d83,
+ 0x875f, 0x1da1,
+ 0x8761, 0x1f66,
+ 0x8762, 0x1da4,
+ 0x8763, 0x1f68,
+ 0x8764, 0x1da6,
+ 0x8765, 0x1f6a,
+ 0x8766, 0x1da8,
+ 0x8768, 0x1f6c,
+ 0x8769, 0x1dab,
+ 0x876b, 0x1f6b,
+ 0x876c, 0x1dae,
+ 0x876e, 0x1f6f,
+ 0x876f, 0x1db1,
+ 0x877e, 0x2083,
+ 0x8780, 0x1db8,
+ 0x8784, 0x1f77,
+ 0x8785, 0x1dbd,
+ 0x8790, 0x02fa,
+ 0x8791, 0x02f9,
+ 0x8792, 0x0301,
+ 0x8793, 0x1dc8,
+ 0x879a, 0x0300,
+ 0x879b, 0x1dcf,
+ 0x889f, 0x0465,
+ 0x8940, 0x04c3,
+ 0x8980, 0x0502,
+ 0x8a40, 0x057f,
+ 0x8a80, 0x05be,
+ 0x8b40, 0x063b,
+ 0x8b80, 0x067a,
+ 0x8c40, 0x06f7,
+ 0x8c80, 0x0736,
+ 0x8d40, 0x07b3,
+ 0x8d80, 0x07f2,
+ 0x8e40, 0x086f,
+ 0x8e80, 0x08ae,
+ 0x8f40, 0x092b,
+ 0x8f80, 0x096a,
+ 0x9040, 0x09e7,
+ 0x9080, 0x0a26,
+ 0x9140, 0x0aa3,
+ 0x9180, 0x0ae2,
+ 0x9240, 0x0b5f,
+ 0x9280, 0x0b9e,
+ 0x9340, 0x0c1b,
+ 0x9380, 0x0c5a,
+ 0x9440, 0x0cd7,
+ 0x9480, 0x0d16,
+ 0x9540, 0x0d93,
+ 0x9580, 0x0dd2,
+ 0x9640, 0x0e4f,
+ 0x9680, 0x0e8e,
+ 0x9740, 0x0f0b,
+ 0x9780, 0x0f4a,
+ 0x9840, 0x0fc7,
+ 0x989f, 0x0ffa,
+ 0x9940, 0x1058,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a80, 0x1153,
+ 0x9b40, 0x11d0,
+ 0x9b80, 0x120f,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1387,
+ 0x9e40, 0x1404,
+ 0x9e80, 0x1443,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe140, 0x1638,
+ 0xe180, 0x1677,
+ 0xe240, 0x16f4,
+ 0xe280, 0x1733,
+ 0xe340, 0x17b0,
+ 0xe380, 0x17ef,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe540, 0x1928,
+ 0xe580, 0x1967,
+ 0xe640, 0x19e4,
+ 0xe680, 0x1a23,
+ 0xe740, 0x1aa0,
+ 0xe780, 0x1adf,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xea40, 0x1cd4,
+ 0xea80, 0x1d13,
+ 0xeaa3, 0x205c,
+ 0xed40, 0x20a7,
+ 0xed80, 0x20e6,
+ 0xedb4, 0x07c9,
+ 0xedb5, 0x211a,
+ 0xee40, 0x2162,
+ 0xee80, 0x21a1,
+ 0xeeef, 0x1f9c,
+ 0xeef9, 0x02ef,
+ 0xeefa, 0x1f45,
+ 0xfa40, 0x1f9c,
+ 0xfa4a, 0x1d97,
+ 0xfa54, 0x02ef,
+ 0xfa55, 0x1f45,
+ 0xfa58, 0x1dc2,
+ 0xfa59, 0x1dba,
+ 0xfa5a, 0x1f77,
+ 0xfa5b, 0x0300,
+ 0xfa5c, 0x20a7,
+ 0xfa80, 0x20ca,
+ 0xfad0, 0x07c9,
+ 0xfad1, 0x211a,
+ 0xfb40, 0x2146,
+ 0xfb80, 0x2185,
+ 0xfc40, 0x2202,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1290msRKSJHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0277, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1290msRKSJHMap2, 170
+};
+
+static Gushort japan1290msRKSJVMap2[496] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x8740, 0x1d83,
+ 0x875f, 0x1da1,
+ 0x8761, 0x1f66,
+ 0x8762, 0x1da4,
+ 0x8763, 0x1f68,
+ 0x8764, 0x1da6,
+ 0x8765, 0x1f6a,
+ 0x8766, 0x1da8,
+ 0x8768, 0x1f6c,
+ 0x8769, 0x1dab,
+ 0x876b, 0x1f6b,
+ 0x876c, 0x1dae,
+ 0x876e, 0x1f6f,
+ 0x876f, 0x1db1,
+ 0x877e, 0x2083,
+ 0x8780, 0x1db8,
+ 0x8784, 0x1f77,
+ 0x8785, 0x1dbd,
+ 0x8790, 0x02fa,
+ 0x8791, 0x02f9,
+ 0x8792, 0x0301,
+ 0x8793, 0x1dc8,
+ 0x879a, 0x0300,
+ 0x879b, 0x1dcf,
+ 0x889f, 0x0465,
+ 0x8940, 0x04c3,
+ 0x8980, 0x0502,
+ 0x8a40, 0x057f,
+ 0x8a80, 0x05be,
+ 0x8b40, 0x063b,
+ 0x8b80, 0x067a,
+ 0x8c40, 0x06f7,
+ 0x8c80, 0x0736,
+ 0x8d40, 0x07b3,
+ 0x8d80, 0x07f2,
+ 0x8e40, 0x086f,
+ 0x8e80, 0x08ae,
+ 0x8f40, 0x092b,
+ 0x8f80, 0x096a,
+ 0x9040, 0x09e7,
+ 0x9080, 0x0a26,
+ 0x9140, 0x0aa3,
+ 0x9180, 0x0ae2,
+ 0x9240, 0x0b5f,
+ 0x9280, 0x0b9e,
+ 0x9340, 0x0c1b,
+ 0x9380, 0x0c5a,
+ 0x9440, 0x0cd7,
+ 0x9480, 0x0d16,
+ 0x9540, 0x0d93,
+ 0x9580, 0x0dd2,
+ 0x9640, 0x0e4f,
+ 0x9680, 0x0e8e,
+ 0x9740, 0x0f0b,
+ 0x9780, 0x0f4a,
+ 0x9840, 0x0fc7,
+ 0x989f, 0x0ffa,
+ 0x9940, 0x1058,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a80, 0x1153,
+ 0x9b40, 0x11d0,
+ 0x9b80, 0x120f,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1387,
+ 0x9e40, 0x1404,
+ 0x9e80, 0x1443,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe140, 0x1638,
+ 0xe180, 0x1677,
+ 0xe240, 0x16f4,
+ 0xe280, 0x1733,
+ 0xe340, 0x17b0,
+ 0xe380, 0x17ef,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe540, 0x1928,
+ 0xe580, 0x1967,
+ 0xe640, 0x19e4,
+ 0xe680, 0x1a23,
+ 0xe740, 0x1aa0,
+ 0xe780, 0x1adf,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xea40, 0x1cd4,
+ 0xea80, 0x1d13,
+ 0xeaa3, 0x205c,
+ 0xed40, 0x20a7,
+ 0xed80, 0x20e6,
+ 0xedb4, 0x07c9,
+ 0xedb5, 0x211a,
+ 0xee40, 0x2162,
+ 0xee80, 0x21a1,
+ 0xeeef, 0x1f9c,
+ 0xeef9, 0x02ef,
+ 0xeefa, 0x1f45,
+ 0xfa40, 0x1f9c,
+ 0xfa4a, 0x1d97,
+ 0xfa54, 0x02ef,
+ 0xfa55, 0x1f45,
+ 0xfa58, 0x1dc2,
+ 0xfa59, 0x1dba,
+ 0xfa5a, 0x1f77,
+ 0xfa5b, 0x0300,
+ 0xfa5c, 0x20a7,
+ 0xfa80, 0x20ca,
+ 0xfad0, 0x07c9,
+ 0xfad1, 0x211a,
+ 0xfb40, 0x2146,
+ 0xfb80, 0x2185,
+ 0xfc40, 0x2202,
+ 0x8141, 0x1ecf,
+ 0x8143, 0x204c,
+ 0x8144, 0x2052,
+ 0x8150, 0x1ed1,
+ 0x815b, 0x1ed3,
+ 0x8160, 0x1ed6,
+ 0x8169, 0x1edb,
+ 0x8181, 0x1eed,
+ 0x81a8, 0x02e3,
+ 0x81a9, 0x02e2,
+ 0x81aa, 0x02e0,
+ 0x81ac, 0x204e,
+ 0x829f, 0x1eee,
+ 0x82a1, 0x1eef,
+ 0x82a3, 0x1ef0,
+ 0x82a5, 0x1ef1,
+ 0x82a7, 0x1ef2,
+ 0x82c1, 0x1ef3,
+ 0x82e1, 0x1ef4,
+ 0x82e3, 0x1ef5,
+ 0x82e5, 0x1ef6,
+ 0x82ec, 0x1ef7,
+ 0x8340, 0x1ef8,
+ 0x8342, 0x1ef9,
+ 0x8344, 0x1efa,
+ 0x8346, 0x1efb,
+ 0x8348, 0x1efc,
+ 0x8362, 0x1efd,
+ 0x8383, 0x1efe,
+ 0x8385, 0x1eff,
+ 0x8387, 0x1f00,
+ 0x838e, 0x1f01,
+ 0x8395, 0x1f02,
+ 0x849f, 0x1d39,
+ 0x84a0, 0x1d37,
+ 0x84a1, 0x1d47,
+ 0x84a2, 0x1d4f,
+ 0x84a3, 0x1d4b,
+ 0x84a4, 0x1d43,
+ 0x84a5, 0x1d63,
+ 0x84a6, 0x1d5b,
+ 0x84a7, 0x1d6b,
+ 0x84a8, 0x1d53,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d3a,
+ 0x84ab, 0x1d38,
+ 0x84ac, 0x1d4a,
+ 0x84ad, 0x1d52,
+ 0x84ae, 0x1d4e,
+ 0x84af, 0x1d46,
+ 0x84b0, 0x1d6a,
+ 0x84b1, 0x1d62,
+ 0x84b2, 0x1d72,
+ 0x84b3, 0x1d5a,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d66,
+ 0x84b6, 0x1d5f,
+ 0x84b7, 0x1d6e,
+ 0x84b8, 0x1d57,
+ 0x84b9, 0x1d79,
+ 0x84ba, 0x1d67,
+ 0x84bb, 0x1d5c,
+ 0x84bc, 0x1d6f,
+ 0x84bd, 0x1d54,
+ 0x84be, 0x1d76,
+ 0x875f, 0x1f04,
+ 0x8761, 0x2089,
+ 0x8762, 0x1f07,
+ 0x8763, 0x2093,
+ 0x8764, 0x1f09,
+ 0x8765, 0x2092,
+ 0x8766, 0x1f0b,
+ 0x8768, 0x2098,
+ 0x8769, 0x1f0e,
+ 0x876b, 0x209c,
+ 0x876c, 0x1f11,
+ 0x876e, 0x209d,
+ 0x8780, 0x1f14,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1290msRKSJVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0277, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1290msRKSJVMap2, 248
+};
+
+static Gushort japan1290mspRKSJHMap2[340] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x8740, 0x1d83,
+ 0x875f, 0x1da1,
+ 0x8761, 0x1f66,
+ 0x8762, 0x1da4,
+ 0x8763, 0x1f68,
+ 0x8764, 0x1da6,
+ 0x8765, 0x1f6a,
+ 0x8766, 0x1da8,
+ 0x8768, 0x1f6c,
+ 0x8769, 0x1dab,
+ 0x876b, 0x1f6b,
+ 0x876c, 0x1dae,
+ 0x876e, 0x1f6f,
+ 0x876f, 0x1db1,
+ 0x877e, 0x2083,
+ 0x8780, 0x1db8,
+ 0x8784, 0x1f77,
+ 0x8785, 0x1dbd,
+ 0x8790, 0x02fa,
+ 0x8791, 0x02f9,
+ 0x8792, 0x0301,
+ 0x8793, 0x1dc8,
+ 0x879a, 0x0300,
+ 0x879b, 0x1dcf,
+ 0x889f, 0x0465,
+ 0x8940, 0x04c3,
+ 0x8980, 0x0502,
+ 0x8a40, 0x057f,
+ 0x8a80, 0x05be,
+ 0x8b40, 0x063b,
+ 0x8b80, 0x067a,
+ 0x8c40, 0x06f7,
+ 0x8c80, 0x0736,
+ 0x8d40, 0x07b3,
+ 0x8d80, 0x07f2,
+ 0x8e40, 0x086f,
+ 0x8e80, 0x08ae,
+ 0x8f40, 0x092b,
+ 0x8f80, 0x096a,
+ 0x9040, 0x09e7,
+ 0x9080, 0x0a26,
+ 0x9140, 0x0aa3,
+ 0x9180, 0x0ae2,
+ 0x9240, 0x0b5f,
+ 0x9280, 0x0b9e,
+ 0x9340, 0x0c1b,
+ 0x9380, 0x0c5a,
+ 0x9440, 0x0cd7,
+ 0x9480, 0x0d16,
+ 0x9540, 0x0d93,
+ 0x9580, 0x0dd2,
+ 0x9640, 0x0e4f,
+ 0x9680, 0x0e8e,
+ 0x9740, 0x0f0b,
+ 0x9780, 0x0f4a,
+ 0x9840, 0x0fc7,
+ 0x989f, 0x0ffa,
+ 0x9940, 0x1058,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a80, 0x1153,
+ 0x9b40, 0x11d0,
+ 0x9b80, 0x120f,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1387,
+ 0x9e40, 0x1404,
+ 0x9e80, 0x1443,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe140, 0x1638,
+ 0xe180, 0x1677,
+ 0xe240, 0x16f4,
+ 0xe280, 0x1733,
+ 0xe340, 0x17b0,
+ 0xe380, 0x17ef,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe540, 0x1928,
+ 0xe580, 0x1967,
+ 0xe640, 0x19e4,
+ 0xe680, 0x1a23,
+ 0xe740, 0x1aa0,
+ 0xe780, 0x1adf,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xea40, 0x1cd4,
+ 0xea80, 0x1d13,
+ 0xeaa3, 0x205c,
+ 0xed40, 0x20a7,
+ 0xed80, 0x20e6,
+ 0xedb4, 0x07c9,
+ 0xedb5, 0x211a,
+ 0xee40, 0x2162,
+ 0xee80, 0x21a1,
+ 0xeeef, 0x1f9c,
+ 0xeef9, 0x02ef,
+ 0xeefa, 0x1f45,
+ 0xfa40, 0x1f9c,
+ 0xfa4a, 0x1d97,
+ 0xfa54, 0x02ef,
+ 0xfa55, 0x1f45,
+ 0xfa58, 0x1dc2,
+ 0xfa59, 0x1dba,
+ 0xfa5a, 0x1f77,
+ 0xfa5b, 0x0300,
+ 0xfa5c, 0x20a7,
+ 0xfa80, 0x20ca,
+ 0xfad0, 0x07c9,
+ 0xfad1, 0x211a,
+ 0xfb40, 0x2146,
+ 0xfb80, 0x2185,
+ 0xfc40, 0x2202,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1290mspRKSJHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1290mspRKSJHMap2, 170
+};
+
+static Gushort japan1290mspRKSJVMap2[496] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x8740, 0x1d83,
+ 0x875f, 0x1da1,
+ 0x8761, 0x1f66,
+ 0x8762, 0x1da4,
+ 0x8763, 0x1f68,
+ 0x8764, 0x1da6,
+ 0x8765, 0x1f6a,
+ 0x8766, 0x1da8,
+ 0x8768, 0x1f6c,
+ 0x8769, 0x1dab,
+ 0x876b, 0x1f6b,
+ 0x876c, 0x1dae,
+ 0x876e, 0x1f6f,
+ 0x876f, 0x1db1,
+ 0x877e, 0x2083,
+ 0x8780, 0x1db8,
+ 0x8784, 0x1f77,
+ 0x8785, 0x1dbd,
+ 0x8790, 0x02fa,
+ 0x8791, 0x02f9,
+ 0x8792, 0x0301,
+ 0x8793, 0x1dc8,
+ 0x879a, 0x0300,
+ 0x879b, 0x1dcf,
+ 0x889f, 0x0465,
+ 0x8940, 0x04c3,
+ 0x8980, 0x0502,
+ 0x8a40, 0x057f,
+ 0x8a80, 0x05be,
+ 0x8b40, 0x063b,
+ 0x8b80, 0x067a,
+ 0x8c40, 0x06f7,
+ 0x8c80, 0x0736,
+ 0x8d40, 0x07b3,
+ 0x8d80, 0x07f2,
+ 0x8e40, 0x086f,
+ 0x8e80, 0x08ae,
+ 0x8f40, 0x092b,
+ 0x8f80, 0x096a,
+ 0x9040, 0x09e7,
+ 0x9080, 0x0a26,
+ 0x9140, 0x0aa3,
+ 0x9180, 0x0ae2,
+ 0x9240, 0x0b5f,
+ 0x9280, 0x0b9e,
+ 0x9340, 0x0c1b,
+ 0x9380, 0x0c5a,
+ 0x9440, 0x0cd7,
+ 0x9480, 0x0d16,
+ 0x9540, 0x0d93,
+ 0x9580, 0x0dd2,
+ 0x9640, 0x0e4f,
+ 0x9680, 0x0e8e,
+ 0x9740, 0x0f0b,
+ 0x9780, 0x0f4a,
+ 0x9840, 0x0fc7,
+ 0x989f, 0x0ffa,
+ 0x9940, 0x1058,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a80, 0x1153,
+ 0x9b40, 0x11d0,
+ 0x9b80, 0x120f,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1387,
+ 0x9e40, 0x1404,
+ 0x9e80, 0x1443,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe140, 0x1638,
+ 0xe180, 0x1677,
+ 0xe240, 0x16f4,
+ 0xe280, 0x1733,
+ 0xe340, 0x17b0,
+ 0xe380, 0x17ef,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe540, 0x1928,
+ 0xe580, 0x1967,
+ 0xe640, 0x19e4,
+ 0xe680, 0x1a23,
+ 0xe740, 0x1aa0,
+ 0xe780, 0x1adf,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xea40, 0x1cd4,
+ 0xea80, 0x1d13,
+ 0xeaa3, 0x205c,
+ 0xed40, 0x20a7,
+ 0xed80, 0x20e6,
+ 0xedb4, 0x07c9,
+ 0xedb5, 0x211a,
+ 0xee40, 0x2162,
+ 0xee80, 0x21a1,
+ 0xeeef, 0x1f9c,
+ 0xeef9, 0x02ef,
+ 0xeefa, 0x1f45,
+ 0xfa40, 0x1f9c,
+ 0xfa4a, 0x1d97,
+ 0xfa54, 0x02ef,
+ 0xfa55, 0x1f45,
+ 0xfa58, 0x1dc2,
+ 0xfa59, 0x1dba,
+ 0xfa5a, 0x1f77,
+ 0xfa5b, 0x0300,
+ 0xfa5c, 0x20a7,
+ 0xfa80, 0x20ca,
+ 0xfad0, 0x07c9,
+ 0xfad1, 0x211a,
+ 0xfb40, 0x2146,
+ 0xfb80, 0x2185,
+ 0xfc40, 0x2202,
+ 0x8141, 0x1ecf,
+ 0x8143, 0x204c,
+ 0x8144, 0x2052,
+ 0x8150, 0x1ed1,
+ 0x815b, 0x1ed3,
+ 0x8160, 0x1ed6,
+ 0x8169, 0x1edb,
+ 0x8181, 0x1eed,
+ 0x81a8, 0x02e3,
+ 0x81a9, 0x02e2,
+ 0x81aa, 0x02e0,
+ 0x81ac, 0x204e,
+ 0x829f, 0x1eee,
+ 0x82a1, 0x1eef,
+ 0x82a3, 0x1ef0,
+ 0x82a5, 0x1ef1,
+ 0x82a7, 0x1ef2,
+ 0x82c1, 0x1ef3,
+ 0x82e1, 0x1ef4,
+ 0x82e3, 0x1ef5,
+ 0x82e5, 0x1ef6,
+ 0x82ec, 0x1ef7,
+ 0x8340, 0x1ef8,
+ 0x8342, 0x1ef9,
+ 0x8344, 0x1efa,
+ 0x8346, 0x1efb,
+ 0x8348, 0x1efc,
+ 0x8362, 0x1efd,
+ 0x8383, 0x1efe,
+ 0x8385, 0x1eff,
+ 0x8387, 0x1f00,
+ 0x838e, 0x1f01,
+ 0x8395, 0x1f02,
+ 0x849f, 0x1d39,
+ 0x84a0, 0x1d37,
+ 0x84a1, 0x1d47,
+ 0x84a2, 0x1d4f,
+ 0x84a3, 0x1d4b,
+ 0x84a4, 0x1d43,
+ 0x84a5, 0x1d63,
+ 0x84a6, 0x1d5b,
+ 0x84a7, 0x1d6b,
+ 0x84a8, 0x1d53,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d3a,
+ 0x84ab, 0x1d38,
+ 0x84ac, 0x1d4a,
+ 0x84ad, 0x1d52,
+ 0x84ae, 0x1d4e,
+ 0x84af, 0x1d46,
+ 0x84b0, 0x1d6a,
+ 0x84b1, 0x1d62,
+ 0x84b2, 0x1d72,
+ 0x84b3, 0x1d5a,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d66,
+ 0x84b6, 0x1d5f,
+ 0x84b7, 0x1d6e,
+ 0x84b8, 0x1d57,
+ 0x84b9, 0x1d79,
+ 0x84ba, 0x1d67,
+ 0x84bb, 0x1d5c,
+ 0x84bc, 0x1d6f,
+ 0x84bd, 0x1d54,
+ 0x84be, 0x1d76,
+ 0x875f, 0x1f04,
+ 0x8761, 0x2089,
+ 0x8762, 0x1f07,
+ 0x8763, 0x2093,
+ 0x8764, 0x1f09,
+ 0x8765, 0x2092,
+ 0x8766, 0x1f0b,
+ 0x8768, 0x2098,
+ 0x8769, 0x1f0e,
+ 0x876b, 0x209c,
+ 0x876c, 0x1f11,
+ 0x876e, 0x209d,
+ 0x8780, 0x1f14,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1290mspRKSJVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan1290mspRKSJVMap2, 248
+};
+
+static Gushort japan1290pvRKSJHMap2[518] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x8540, 0x1d83,
+ 0x855e, 0x1f87,
+ 0x857c, 0x205e,
+ 0x8580, 0x2061,
+ 0x8591, 0x1f7d,
+ 0x859f, 0x1d97,
+ 0x85a9, 0x2021,
+ 0x85ab, 0x2067,
+ 0x85b3, 0x1f9c,
+ 0x85bd, 0x206a,
+ 0x85db, 0x1fb0,
+ 0x8640, 0x1db1,
+ 0x8641, 0x1ffa,
+ 0x8642, 0x1db2,
+ 0x8643, 0x1f54,
+ 0x8644, 0x1f56,
+ 0x8645, 0x206f,
+ 0x8646, 0x1db7,
+ 0x8647, 0x1f57,
+ 0x8648, 0x1db3,
+ 0x8649, 0x1f55,
+ 0x864a, 0x1db4,
+ 0x864b, 0x2070,
+ 0x864c, 0x1db5,
+ 0x864e, 0x1f65,
+ 0x864f, 0x1f58,
+ 0x8656, 0x2071,
+ 0x8657, 0x1f64,
+ 0x8658, 0x1f62,
+ 0x865a, 0x1f5f,
+ 0x865d, 0x2072,
+ 0x869b, 0x1dba,
+ 0x869e, 0x2073,
+ 0x869f, 0x1f52,
+ 0x86a0, 0x1f50,
+ 0x86a2, 0x1f53,
+ 0x86a3, 0x2013,
+ 0x86a4, 0x2015,
+ 0x86a5, 0x2014,
+ 0x86a6, 0x2016,
+ 0x86b3, 0x1f7a,
+ 0x86b4, 0x1f78,
+ 0x86b5, 0x2074,
+ 0x86c7, 0x201b,
+ 0x86cb, 0x2075,
+ 0x86cf, 0x1f4e,
+ 0x86d0, 0x1f4d,
+ 0x86d1, 0x1f4c,
+ 0x86d2, 0x1f4b,
+ 0x86d3, 0x200e,
+ 0x8740, 0x2005,
+ 0x8747, 0x1fd6,
+ 0x8748, 0x200c,
+ 0x8749, 0x1fd1,
+ 0x874a, 0x1fca,
+ 0x874b, 0x1dc4,
+ 0x874c, 0x1fd7,
+ 0x874d, 0x1dc2,
+ 0x874e, 0x1fd2,
+ 0x874f, 0x1fcd,
+ 0x8750, 0x1dc3,
+ 0x8751, 0x1fd5,
+ 0x8752, 0x1fd3,
+ 0x8753, 0x1fcf,
+ 0x8754, 0x1fd4,
+ 0x8755, 0x1fd0,
+ 0x8756, 0x1fcb,
+ 0x8758, 0x1fce,
+ 0x8791, 0x207d,
+ 0x8793, 0x1dbd,
+ 0x8798, 0x1fda,
+ 0x8799, 0x1fe5,
+ 0x879a, 0x207f,
+ 0x879b, 0x1fde,
+ 0x879c, 0x1fff,
+ 0x879d, 0x2080,
+ 0x879e, 0x201f,
+ 0x879f, 0x1da1,
+ 0x87a0, 0x1f66,
+ 0x87a1, 0x1da4,
+ 0x87a2, 0x1da2,
+ 0x87a3, 0x1f67,
+ 0x87a4, 0x1ff7,
+ 0x87a5, 0x2087,
+ 0x87a7, 0x1f6a,
+ 0x87a8, 0x1da8,
+ 0x87a9, 0x1f68,
+ 0x87ab, 0x1da6,
+ 0x87ac, 0x1da9,
+ 0x87ad, 0x1daf,
+ 0x87ae, 0x1f6e,
+ 0x87af, 0x1f6c,
+ 0x87b0, 0x1dab,
+ 0x87b1, 0x1f6d,
+ 0x87b2, 0x1f6b,
+ 0x87b3, 0x1dac,
+ 0x87b4, 0x1f6f,
+ 0x87b5, 0x1dae,
+ 0x87bd, 0x1f70,
+ 0x87be, 0x1f73,
+ 0x87c0, 0x1f71,
+ 0x87e5, 0x1dc5,
+ 0x87e8, 0x2083,
+ 0x87fa, 0x1f76,
+ 0x87fb, 0x2081,
+ 0x8840, 0x1dc8,
+ 0x8841, 0x1dcd,
+ 0x8854, 0x1db8,
+ 0x8868, 0x1f16,
+ 0x886a, 0x2079,
+ 0x889f, 0x0465,
+ 0x8940, 0x04c3,
+ 0x8980, 0x0502,
+ 0x8a40, 0x057f,
+ 0x8a80, 0x05be,
+ 0x8b40, 0x063b,
+ 0x8b80, 0x067a,
+ 0x8c40, 0x06f7,
+ 0x8c80, 0x0736,
+ 0x8d40, 0x07b3,
+ 0x8d80, 0x07f2,
+ 0x8e40, 0x086f,
+ 0x8e80, 0x08ae,
+ 0x8f40, 0x092b,
+ 0x8f80, 0x096a,
+ 0x9040, 0x09e7,
+ 0x9080, 0x0a26,
+ 0x9140, 0x0aa3,
+ 0x9180, 0x0ae2,
+ 0x9240, 0x0b5f,
+ 0x9280, 0x0b9e,
+ 0x9340, 0x0c1b,
+ 0x9380, 0x0c5a,
+ 0x9440, 0x0cd7,
+ 0x9480, 0x0d16,
+ 0x9540, 0x0d93,
+ 0x9580, 0x0dd2,
+ 0x9640, 0x0e4f,
+ 0x9680, 0x0e8e,
+ 0x9740, 0x0f0b,
+ 0x9780, 0x0f4a,
+ 0x9840, 0x0fc7,
+ 0x989f, 0x0ffa,
+ 0x9940, 0x1058,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a80, 0x1153,
+ 0x9b40, 0x11d0,
+ 0x9b80, 0x120f,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1387,
+ 0x9e40, 0x1404,
+ 0x9e80, 0x1443,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe140, 0x1638,
+ 0xe180, 0x1677,
+ 0xe240, 0x16f4,
+ 0xe280, 0x1733,
+ 0xe340, 0x17b0,
+ 0xe380, 0x17ef,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe540, 0x1928,
+ 0xe580, 0x1967,
+ 0xe640, 0x19e4,
+ 0xe680, 0x1a23,
+ 0xe740, 0x1aa0,
+ 0xe780, 0x1adf,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xea40, 0x1cd4,
+ 0xea80, 0x1d13,
+ 0xeaa3, 0x205c,
+ 0xeb41, 0x1ecf,
+ 0xeb50, 0x1ed1,
+ 0xeb5b, 0x1ed3,
+ 0xeb60, 0x1ed6,
+ 0xeb69, 0x1edb,
+ 0xeb81, 0x1eed,
+ 0xec9f, 0x1eee,
+ 0xeca1, 0x1eef,
+ 0xeca3, 0x1ef0,
+ 0xeca5, 0x1ef1,
+ 0xeca7, 0x1ef2,
+ 0xecc1, 0x1ef3,
+ 0xece1, 0x1ef4,
+ 0xece3, 0x1ef5,
+ 0xece5, 0x1ef6,
+ 0xecec, 0x1ef7,
+ 0xed40, 0x1ef8,
+ 0xed42, 0x1ef9,
+ 0xed44, 0x1efa,
+ 0xed46, 0x1efb,
+ 0xed48, 0x1efc,
+ 0xed62, 0x1efd,
+ 0xed83, 0x1efe,
+ 0xed85, 0x1eff,
+ 0xed87, 0x1f00,
+ 0xed8e, 0x1f01,
+ 0xed95, 0x1f02,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1290pvRKSJHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0061, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0098, 0x00e4, 0x007c },
+ japan1290pvRKSJHMap2, 259
+};
+
+static Gushort japan1290pvRKSJVMap2[620] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x8540, 0x1d83,
+ 0x855e, 0x1f87,
+ 0x857c, 0x205e,
+ 0x8580, 0x2061,
+ 0x8591, 0x1f7d,
+ 0x859f, 0x1d97,
+ 0x85a9, 0x2021,
+ 0x85ab, 0x2067,
+ 0x85b3, 0x1f9c,
+ 0x85bd, 0x206a,
+ 0x85db, 0x1fb0,
+ 0x8640, 0x1db1,
+ 0x8641, 0x1ffa,
+ 0x8642, 0x1db2,
+ 0x8643, 0x1f54,
+ 0x8644, 0x1f56,
+ 0x8645, 0x206f,
+ 0x8646, 0x1db7,
+ 0x8647, 0x1f57,
+ 0x8648, 0x1db3,
+ 0x8649, 0x1f55,
+ 0x864a, 0x1db4,
+ 0x864b, 0x2070,
+ 0x864c, 0x1db5,
+ 0x864e, 0x1f65,
+ 0x864f, 0x1f58,
+ 0x8656, 0x2071,
+ 0x8657, 0x1f64,
+ 0x8658, 0x1f62,
+ 0x865a, 0x1f5f,
+ 0x865d, 0x2072,
+ 0x869b, 0x1dba,
+ 0x869e, 0x2073,
+ 0x869f, 0x1f52,
+ 0x86a0, 0x1f50,
+ 0x86a2, 0x1f53,
+ 0x86a3, 0x2013,
+ 0x86a4, 0x2015,
+ 0x86a5, 0x2014,
+ 0x86a6, 0x2016,
+ 0x86b3, 0x1f7a,
+ 0x86b4, 0x1f78,
+ 0x86b5, 0x2074,
+ 0x86c7, 0x201b,
+ 0x86cb, 0x2075,
+ 0x86cf, 0x1f4e,
+ 0x86d0, 0x1f4d,
+ 0x86d1, 0x1f4c,
+ 0x86d2, 0x1f4b,
+ 0x86d3, 0x200e,
+ 0x8740, 0x2005,
+ 0x8747, 0x1fd6,
+ 0x8748, 0x200c,
+ 0x8749, 0x1fd1,
+ 0x874a, 0x1fca,
+ 0x874b, 0x1dc4,
+ 0x874c, 0x1fd7,
+ 0x874d, 0x1dc2,
+ 0x874e, 0x1fd2,
+ 0x874f, 0x1fcd,
+ 0x8750, 0x1dc3,
+ 0x8751, 0x1fd5,
+ 0x8752, 0x1fd3,
+ 0x8753, 0x1fcf,
+ 0x8754, 0x1fd4,
+ 0x8755, 0x1fd0,
+ 0x8756, 0x1fcb,
+ 0x8758, 0x1fce,
+ 0x8791, 0x207d,
+ 0x8793, 0x1dbd,
+ 0x8798, 0x1fda,
+ 0x8799, 0x1fe5,
+ 0x879a, 0x207f,
+ 0x879b, 0x1fde,
+ 0x879c, 0x1fff,
+ 0x879d, 0x2080,
+ 0x879e, 0x201f,
+ 0x879f, 0x1da1,
+ 0x87a0, 0x1f66,
+ 0x87a1, 0x1da4,
+ 0x87a2, 0x1da2,
+ 0x87a3, 0x1f67,
+ 0x87a4, 0x1ff7,
+ 0x87a5, 0x2087,
+ 0x87a7, 0x1f6a,
+ 0x87a8, 0x1da8,
+ 0x87a9, 0x1f68,
+ 0x87ab, 0x1da6,
+ 0x87ac, 0x1da9,
+ 0x87ad, 0x1daf,
+ 0x87ae, 0x1f6e,
+ 0x87af, 0x1f6c,
+ 0x87b0, 0x1dab,
+ 0x87b1, 0x1f6d,
+ 0x87b2, 0x1f6b,
+ 0x87b3, 0x1dac,
+ 0x87b4, 0x1f6f,
+ 0x87b5, 0x1dae,
+ 0x87bd, 0x1f70,
+ 0x87be, 0x1f73,
+ 0x87c0, 0x1f71,
+ 0x87e5, 0x1dc5,
+ 0x87e8, 0x2083,
+ 0x87fa, 0x1f76,
+ 0x87fb, 0x2081,
+ 0x8840, 0x1dc8,
+ 0x8841, 0x1dcd,
+ 0x8854, 0x1db8,
+ 0x8868, 0x1f16,
+ 0x886a, 0x2079,
+ 0x889f, 0x0465,
+ 0x8940, 0x04c3,
+ 0x8980, 0x0502,
+ 0x8a40, 0x057f,
+ 0x8a80, 0x05be,
+ 0x8b40, 0x063b,
+ 0x8b80, 0x067a,
+ 0x8c40, 0x06f7,
+ 0x8c80, 0x0736,
+ 0x8d40, 0x07b3,
+ 0x8d80, 0x07f2,
+ 0x8e40, 0x086f,
+ 0x8e80, 0x08ae,
+ 0x8f40, 0x092b,
+ 0x8f80, 0x096a,
+ 0x9040, 0x09e7,
+ 0x9080, 0x0a26,
+ 0x9140, 0x0aa3,
+ 0x9180, 0x0ae2,
+ 0x9240, 0x0b5f,
+ 0x9280, 0x0b9e,
+ 0x9340, 0x0c1b,
+ 0x9380, 0x0c5a,
+ 0x9440, 0x0cd7,
+ 0x9480, 0x0d16,
+ 0x9540, 0x0d93,
+ 0x9580, 0x0dd2,
+ 0x9640, 0x0e4f,
+ 0x9680, 0x0e8e,
+ 0x9740, 0x0f0b,
+ 0x9780, 0x0f4a,
+ 0x9840, 0x0fc7,
+ 0x989f, 0x0ffa,
+ 0x9940, 0x1058,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a80, 0x1153,
+ 0x9b40, 0x11d0,
+ 0x9b80, 0x120f,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1387,
+ 0x9e40, 0x1404,
+ 0x9e80, 0x1443,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe140, 0x1638,
+ 0xe180, 0x1677,
+ 0xe240, 0x16f4,
+ 0xe280, 0x1733,
+ 0xe340, 0x17b0,
+ 0xe380, 0x17ef,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe540, 0x1928,
+ 0xe580, 0x1967,
+ 0xe640, 0x19e4,
+ 0xe680, 0x1a23,
+ 0xe740, 0x1aa0,
+ 0xe780, 0x1adf,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xea40, 0x1cd4,
+ 0xea80, 0x1d13,
+ 0xeaa3, 0x205c,
+ 0xeb41, 0x1ecf,
+ 0xeb50, 0x1ed1,
+ 0xeb5b, 0x1ed3,
+ 0xeb60, 0x1ed6,
+ 0xeb69, 0x1edb,
+ 0xeb81, 0x1eed,
+ 0xec9f, 0x1eee,
+ 0xeca1, 0x1eef,
+ 0xeca3, 0x1ef0,
+ 0xeca5, 0x1ef1,
+ 0xeca7, 0x1ef2,
+ 0xecc1, 0x1ef3,
+ 0xece1, 0x1ef4,
+ 0xece3, 0x1ef5,
+ 0xece5, 0x1ef6,
+ 0xecec, 0x1ef7,
+ 0xed40, 0x1ef8,
+ 0xed42, 0x1ef9,
+ 0xed44, 0x1efa,
+ 0xed46, 0x1efb,
+ 0xed48, 0x1efc,
+ 0xed62, 0x1efd,
+ 0xed83, 0x1efe,
+ 0xed85, 0x1eff,
+ 0xed87, 0x1f00,
+ 0xed8e, 0x1f01,
+ 0xed95, 0x1f02,
+ 0x8141, 0x1ecf,
+ 0x8150, 0x1ed1,
+ 0x815b, 0x1ed3,
+ 0x8160, 0x1ed6,
+ 0x8169, 0x1edb,
+ 0x8181, 0x1eed,
+ 0x829f, 0x1eee,
+ 0x82a1, 0x1eef,
+ 0x82a3, 0x1ef0,
+ 0x82a5, 0x1ef1,
+ 0x82a7, 0x1ef2,
+ 0x82c1, 0x1ef3,
+ 0x82e1, 0x1ef4,
+ 0x82e3, 0x1ef5,
+ 0x82e5, 0x1ef6,
+ 0x82ec, 0x1ef7,
+ 0x8340, 0x1ef8,
+ 0x8342, 0x1ef9,
+ 0x8344, 0x1efa,
+ 0x8346, 0x1efb,
+ 0x8348, 0x1efc,
+ 0x8362, 0x1efd,
+ 0x8383, 0x1efe,
+ 0x8385, 0x1eff,
+ 0x8387, 0x1f00,
+ 0x838e, 0x1f01,
+ 0x8395, 0x1f02,
+ 0x879f, 0x1f04,
+ 0x87a0, 0x2089,
+ 0x87a1, 0x1f07,
+ 0x87a2, 0x1f05,
+ 0x87a3, 0x208a,
+ 0x87a4, 0x208d,
+ 0x87a6, 0x2091,
+ 0x87a8, 0x1f0b,
+ 0x87a9, 0x2093,
+ 0x87ab, 0x1f09,
+ 0x87ac, 0x1f0c,
+ 0x87ad, 0x1f12,
+ 0x87ae, 0x2097,
+ 0x87b0, 0x1f0e,
+ 0x87b1, 0x209b,
+ 0x87b3, 0x1f0f,
+ 0x87b4, 0x209d,
+ 0x87b5, 0x1f11,
+ 0x87bd, 0x209e,
+ 0x87be, 0x20a1,
+ 0x87bf, 0x20a4,
+ 0x87c0, 0x20a6,
+ 0x87c1, 0x20a5,
+ 0x87fa, 0x2084,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan1290pvRKSJVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010,
+ 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018,
+ 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000,
+ 0x0061, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0098, 0x00e4, 0x007c },
+ japan1290pvRKSJVMap2, 310
+};
+
+static Gushort japan12AddHMap2[1266] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0279,
+ 0x2221, 0x02d7,
+ 0x223a, 0x02e5,
+ 0x224a, 0x02ed,
+ 0x225c, 0x02f4,
+ 0x2272, 0x0303,
+ 0x227e, 0x030b,
+ 0x2330, 0x030c,
+ 0x2341, 0x0316,
+ 0x2361, 0x0330,
+ 0x2421, 0x034a,
+ 0x2474, 0x1f16,
+ 0x2521, 0x039d,
+ 0x2621, 0x03f3,
+ 0x2641, 0x040b,
+ 0x2721, 0x0423,
+ 0x2751, 0x0444,
+ 0x2821, 0x1d37,
+ 0x2822, 0x1d39,
+ 0x2823, 0x1d43,
+ 0x2824, 0x1d47,
+ 0x2825, 0x1d4f,
+ 0x2826, 0x1d4b,
+ 0x2827, 0x1d53,
+ 0x2828, 0x1d63,
+ 0x2829, 0x1d5b,
+ 0x282a, 0x1d6b,
+ 0x282b, 0x1d73,
+ 0x282c, 0x1d38,
+ 0x282d, 0x1d3a,
+ 0x282e, 0x1d46,
+ 0x282f, 0x1d4a,
+ 0x2830, 0x1d52,
+ 0x2831, 0x1d4e,
+ 0x2832, 0x1d5a,
+ 0x2833, 0x1d6a,
+ 0x2834, 0x1d62,
+ 0x2835, 0x1d72,
+ 0x2836, 0x1d82,
+ 0x2837, 0x1d57,
+ 0x2838, 0x1d66,
+ 0x2839, 0x1d5f,
+ 0x283a, 0x1d6e,
+ 0x283b, 0x1d76,
+ 0x283c, 0x1d54,
+ 0x283d, 0x1d67,
+ 0x283e, 0x1d5c,
+ 0x283f, 0x1d6f,
+ 0x2840, 0x1d79,
+ 0x3021, 0x0465,
+ 0x3022, 0x1dd1,
+ 0x3023, 0x0467,
+ 0x3032, 0x1f19,
+ 0x3033, 0x0477,
+ 0x303b, 0x1dd2,
+ 0x303c, 0x0480,
+ 0x306e, 0x1dd3,
+ 0x306f, 0x04b3,
+ 0x3071, 0x1f1a,
+ 0x3072, 0x04b6,
+ 0x3073, 0x1dd4,
+ 0x3074, 0x04b8,
+ 0x307c, 0x1dd5,
+ 0x307d, 0x04c1,
+ 0x3121, 0x04c3,
+ 0x312a, 0x1dd6,
+ 0x312b, 0x04cd,
+ 0x3133, 0x1f1b,
+ 0x3134, 0x04d6,
+ 0x3135, 0x1dd7,
+ 0x3136, 0x04d8,
+ 0x3139, 0x1f1c,
+ 0x313a, 0x04dc,
+ 0x313d, 0x1dda,
+ 0x313e, 0x04e0,
+ 0x3142, 0x1ddb,
+ 0x3143, 0x04e5,
+ 0x316b, 0x1ddc,
+ 0x316c, 0x050e,
+ 0x3221, 0x0521,
+ 0x3228, 0x1ddd,
+ 0x3229, 0x0529,
+ 0x322a, 0x1dde,
+ 0x322b, 0x052b,
+ 0x3260, 0x1ddf,
+ 0x3261, 0x0561,
+ 0x3267, 0x1f1d,
+ 0x3268, 0x0568,
+ 0x327a, 0x1de0,
+ 0x327b, 0x057b,
+ 0x3321, 0x057f,
+ 0x3322, 0x1de2,
+ 0x3323, 0x0581,
+ 0x336b, 0x1de4,
+ 0x336c, 0x05ca,
+ 0x3373, 0x1de5,
+ 0x3374, 0x05d2,
+ 0x337a, 0x1de6,
+ 0x337b, 0x05d9,
+ 0x3421, 0x05dd,
+ 0x3442, 0x1de7,
+ 0x3443, 0x05ff,
+ 0x344d, 0x1de8,
+ 0x344e, 0x060a,
+ 0x3465, 0x1de9,
+ 0x3466, 0x0622,
+ 0x3521, 0x063b,
+ 0x352b, 0x1dea,
+ 0x352c, 0x0646,
+ 0x3540, 0x1deb,
+ 0x3541, 0x065b,
+ 0x3562, 0x1f1e,
+ 0x3563, 0x067d,
+ 0x3568, 0x1f1f,
+ 0x3569, 0x0683,
+ 0x3621, 0x0699,
+ 0x3622, 0x1dec,
+ 0x3623, 0x069b,
+ 0x362a, 0x1ded,
+ 0x362b, 0x06a3,
+ 0x3642, 0x1f20,
+ 0x3643, 0x06bb,
+ 0x364f, 0x1dee,
+ 0x3650, 0x06c8,
+ 0x366d, 0x1def,
+ 0x366e, 0x06e6,
+ 0x3674, 0x1df0,
+ 0x3675, 0x06ed,
+ 0x367b, 0x1df1,
+ 0x367c, 0x06f4,
+ 0x367d, 0x1df2,
+ 0x367e, 0x06f6,
+ 0x3721, 0x06f7,
+ 0x3737, 0x1df4,
+ 0x3738, 0x070e,
+ 0x3752, 0x1df7,
+ 0x3753, 0x0729,
+ 0x3771, 0x1dfa,
+ 0x3772, 0x0748,
+ 0x377d, 0x1f21,
+ 0x377e, 0x1dfc,
+ 0x3821, 0x0755,
+ 0x3834, 0x1dfd,
+ 0x3835, 0x0769,
+ 0x3841, 0x1dfe,
+ 0x3842, 0x0776,
+ 0x3921, 0x07b3,
+ 0x392b, 0x1dff,
+ 0x392c, 0x07be,
+ 0x396d, 0x1e02,
+ 0x396e, 0x0800,
+ 0x3974, 0x1e03,
+ 0x3975, 0x0807,
+ 0x3979, 0x1e04,
+ 0x397a, 0x080c,
+ 0x3a21, 0x0811,
+ 0x3a53, 0x1e05,
+ 0x3a54, 0x0844,
+ 0x3a67, 0x1e06,
+ 0x3a68, 0x0858,
+ 0x3a74, 0x1e07,
+ 0x3a75, 0x0865,
+ 0x3b21, 0x086f,
+ 0x3b27, 0x1e08,
+ 0x3b28, 0x0876,
+ 0x3b2a, 0x1e09,
+ 0x3b2b, 0x0879,
+ 0x3b2c, 0x1e0a,
+ 0x3b2d, 0x087b,
+ 0x3b39, 0x1e0b,
+ 0x3b3a, 0x0888,
+ 0x3b41, 0x1f22,
+ 0x3b42, 0x0890,
+ 0x3c21, 0x08cd,
+ 0x3c48, 0x1e0d,
+ 0x3c49, 0x08f5,
+ 0x3c5d, 0x1e0f,
+ 0x3c5f, 0x090b,
+ 0x3d21, 0x092b,
+ 0x3d2b, 0x1e11,
+ 0x3d2c, 0x0936,
+ 0x3d36, 0x1e12,
+ 0x3d37, 0x0941,
+ 0x3d6c, 0x1e13,
+ 0x3d6d, 0x0977,
+ 0x3d72, 0x1e15,
+ 0x3d74, 0x097e,
+ 0x3e21, 0x0989,
+ 0x3e25, 0x1e17,
+ 0x3e26, 0x098e,
+ 0x3e33, 0x1e18,
+ 0x3e34, 0x099c,
+ 0x3e55, 0x1e1a,
+ 0x3e56, 0x09be,
+ 0x3e5f, 0x1e1b,
+ 0x3e60, 0x09c8,
+ 0x3e64, 0x1e1c,
+ 0x3e65, 0x09cd,
+ 0x3f21, 0x09e7,
+ 0x3f2a, 0x1e1d,
+ 0x3f2b, 0x09f1,
+ 0x3f59, 0x1f23,
+ 0x3f5a, 0x0a20,
+ 0x3f60, 0x1e1f,
+ 0x3f61, 0x0a27,
+ 0x4021, 0x0a45,
+ 0x4022, 0x1e21,
+ 0x4023, 0x0a47,
+ 0x4066, 0x1e23,
+ 0x4067, 0x0a8b,
+ 0x4071, 0x1e24,
+ 0x4072, 0x0a96,
+ 0x4079, 0x1e26,
+ 0x407a, 0x1f24,
+ 0x407b, 0x0a9f,
+ 0x407c, 0x1f25,
+ 0x407e, 0x0aa2,
+ 0x4121, 0x0aa3,
+ 0x4127, 0x1e28,
+ 0x4128, 0x0aaa,
+ 0x4139, 0x1e29,
+ 0x413a, 0x0abc,
+ 0x414c, 0x1e2a,
+ 0x414d, 0x0acf,
+ 0x414f, 0x1e2b,
+ 0x4150, 0x0ad2,
+ 0x415f, 0x1e2c,
+ 0x4160, 0x0ae2,
+ 0x4169, 0x1e2d,
+ 0x416a, 0x0aec,
+ 0x4221, 0x0b01,
+ 0x4237, 0x1f27,
+ 0x4238, 0x0b18,
+ 0x423d, 0x1e2e,
+ 0x423e, 0x0b1e,
+ 0x424d, 0x1e2f,
+ 0x424e, 0x0b2e,
+ 0x425c, 0x1e30,
+ 0x425d, 0x0b3d,
+ 0x4263, 0x1e31,
+ 0x4264, 0x0b44,
+ 0x426f, 0x1e32,
+ 0x4270, 0x0b50,
+ 0x427d, 0x1e35,
+ 0x427e, 0x0b5e,
+ 0x4321, 0x0b5f,
+ 0x4327, 0x1e36,
+ 0x4328, 0x0b66,
+ 0x4329, 0x1e37,
+ 0x432a, 0x0b68,
+ 0x432d, 0x1e39,
+ 0x432f, 0x0b6d,
+ 0x433d, 0x1e3b,
+ 0x433e, 0x0b7c,
+ 0x4370, 0x1e3c,
+ 0x4371, 0x0baf,
+ 0x4375, 0x1e3d,
+ 0x4376, 0x0bb4,
+ 0x437c, 0x1e3e,
+ 0x437d, 0x0bbb,
+ 0x4421, 0x0bbd,
+ 0x443d, 0x1e3f,
+ 0x443e, 0x0bda,
+ 0x4448, 0x1e40,
+ 0x4449, 0x0be5,
+ 0x444a, 0x1e41,
+ 0x444b, 0x0be7,
+ 0x444f, 0x1e43,
+ 0x4450, 0x0bec,
+ 0x4521, 0x0c1b,
+ 0x4522, 0x1e44,
+ 0x4523, 0x0c1d,
+ 0x4527, 0x1e45,
+ 0x4528, 0x0c22,
+ 0x452e, 0x1e46,
+ 0x452f, 0x0c29,
+ 0x4536, 0x1e47,
+ 0x4537, 0x0c31,
+ 0x453f, 0x1e48,
+ 0x4540, 0x0c3a,
+ 0x4548, 0x1e49,
+ 0x4549, 0x0c43,
+ 0x454b, 0x1e4a,
+ 0x454c, 0x0c46,
+ 0x4551, 0x1f28,
+ 0x4552, 0x1e4c,
+ 0x4553, 0x0c4d,
+ 0x4564, 0x1e4d,
+ 0x4565, 0x0c5f,
+ 0x4578, 0x1e4e,
+ 0x4579, 0x0c73,
+ 0x4621, 0x0c79,
+ 0x4642, 0x1e50,
+ 0x4643, 0x0c9b,
+ 0x4654, 0x1e51,
+ 0x4655, 0x0cad,
+ 0x465b, 0x1e53,
+ 0x465c, 0x0cb4,
+ 0x4666, 0x1e56,
+ 0x4668, 0x0cc0,
+ 0x466a, 0x1e58,
+ 0x466b, 0x0cc3,
+ 0x4676, 0x1ec0,
+ 0x4677, 0x0ccf,
+ 0x4721, 0x0cd7,
+ 0x4729, 0x1e59,
+ 0x472a, 0x1f29,
+ 0x472b, 0x0ce1,
+ 0x4739, 0x1e5a,
+ 0x473a, 0x0cf0,
+ 0x4757, 0x1e5b,
+ 0x4758, 0x0d0e,
+ 0x4767, 0x1e5c,
+ 0x4768, 0x0d1e,
+ 0x4769, 0x1e5d,
+ 0x476a, 0x0d20,
+ 0x476d, 0x1e5e,
+ 0x476e, 0x0d24,
+ 0x4821, 0x0d35,
+ 0x4824, 0x1e5f,
+ 0x4825, 0x0d39,
+ 0x482e, 0x1e60,
+ 0x482f, 0x0d43,
+ 0x4830, 0x1e61,
+ 0x4831, 0x0d45,
+ 0x4840, 0x1f2a,
+ 0x4841, 0x0d55,
+ 0x4854, 0x1e62,
+ 0x4855, 0x0d69,
+ 0x4875, 0x1e64,
+ 0x4876, 0x0d8a,
+ 0x4921, 0x0d93,
+ 0x4922, 0x1e65,
+ 0x4924, 0x0d96,
+ 0x492f, 0x1e67,
+ 0x4930, 0x0da2,
+ 0x4932, 0x1e68,
+ 0x4933, 0x0da5,
+ 0x4935, 0x1e69,
+ 0x4936, 0x0da8,
+ 0x4940, 0x1e6a,
+ 0x4941, 0x0db3,
+ 0x494e, 0x1e6b,
+ 0x494f, 0x0dc1,
+ 0x4a21, 0x0df1,
+ 0x4a43, 0x1e6d,
+ 0x4a44, 0x0e14,
+ 0x4a4d, 0x1e6e,
+ 0x4a4e, 0x0e1e,
+ 0x4a53, 0x1f2b,
+ 0x4a54, 0x0e24,
+ 0x4a5a, 0x1e6f,
+ 0x4a5b, 0x0e2b,
+ 0x4a79, 0x1e70,
+ 0x4a7a, 0x0e4a,
+ 0x4b21, 0x0e4f,
+ 0x4b29, 0x1e72,
+ 0x4b2a, 0x0e58,
+ 0x4b4b, 0x1e73,
+ 0x4b4c, 0x0e7a,
+ 0x4b70, 0x1e74,
+ 0x4b71, 0x0e9f,
+ 0x4b78, 0x1f2c,
+ 0x4b79, 0x0ea7,
+ 0x4c21, 0x0ead,
+ 0x4c4d, 0x1e75,
+ 0x4c4e, 0x0eda,
+ 0x4c59, 0x1e76,
+ 0x4c5a, 0x0ee6,
+ 0x4c5f, 0x1e77,
+ 0x4c60, 0x0eec,
+ 0x4c62, 0x1e78,
+ 0x4c63, 0x0eef,
+ 0x4c7a, 0x1e79,
+ 0x4c7b, 0x0f07,
+ 0x4c7c, 0x1e7a,
+ 0x4c7d, 0x0f09,
+ 0x4d21, 0x0f0b,
+ 0x4d32, 0x1e7c,
+ 0x4d33, 0x0f1d,
+ 0x4d50, 0x1e7d,
+ 0x4d51, 0x0f3b,
+ 0x4d54, 0x1e7e,
+ 0x4d55, 0x0f3f,
+ 0x4d69, 0x1e7f,
+ 0x4d6a, 0x0f54,
+ 0x4e21, 0x0f69,
+ 0x4e7a, 0x1e81,
+ 0x4e7c, 0x1f2d,
+ 0x4e7d, 0x0fc5,
+ 0x4f21, 0x1e83,
+ 0x4f22, 0x0fc8,
+ 0x4f31, 0x1e84,
+ 0x4f32, 0x0fd8,
+ 0x4f39, 0x1e85,
+ 0x4f3a, 0x0fe0,
+ 0x5021, 0x0ffa,
+ 0x5121, 0x1058,
+ 0x5122, 0x1f2e,
+ 0x5123, 0x105a,
+ 0x513d, 0x1e86,
+ 0x513e, 0x1075,
+ 0x514d, 0x1e89,
+ 0x514e, 0x1085,
+ 0x5221, 0x10b6,
+ 0x5238, 0x1f2f,
+ 0x5239, 0x10ce,
+ 0x5321, 0x1114,
+ 0x5330, 0x1e8a,
+ 0x5331, 0x1124,
+ 0x533a, 0x1e8b,
+ 0x533b, 0x112e,
+ 0x5348, 0x1f30,
+ 0x5349, 0x113c,
+ 0x535e, 0x1e8d,
+ 0x535f, 0x1152,
+ 0x536b, 0x1e8e,
+ 0x536c, 0x1f31,
+ 0x536d, 0x1160,
+ 0x5421, 0x1172,
+ 0x5444, 0x1e8f,
+ 0x5445, 0x1f32,
+ 0x5446, 0x1197,
+ 0x546c, 0x1f33,
+ 0x546d, 0x11be,
+ 0x5521, 0x11d0,
+ 0x553d, 0x1e90,
+ 0x553e, 0x11ed,
+ 0x5563, 0x1e91,
+ 0x5564, 0x1213,
+ 0x5578, 0x1f34,
+ 0x5579, 0x1228,
+ 0x5621, 0x122e,
+ 0x5622, 0x1e92,
+ 0x5623, 0x1230,
+ 0x567d, 0x1f35,
+ 0x5721, 0x128c,
+ 0x5821, 0x12ea,
+ 0x5824, 0x1e94,
+ 0x5825, 0x12ee,
+ 0x5921, 0x1348,
+ 0x5928, 0x1f37,
+ 0x5929, 0x1350,
+ 0x5960, 0x1e95,
+ 0x5961, 0x1388,
+ 0x596c, 0x1e96,
+ 0x596d, 0x1394,
+ 0x5a21, 0x13a6,
+ 0x5a39, 0x1e97,
+ 0x5a3a, 0x13bf,
+ 0x5a7a, 0x1f38,
+ 0x5a7b, 0x1400,
+ 0x5b21, 0x1404,
+ 0x5b45, 0x1e99,
+ 0x5b46, 0x1429,
+ 0x5b6b, 0x1e9b,
+ 0x5b6c, 0x144f,
+ 0x5c21, 0x1462,
+ 0x5d21, 0x14c0,
+ 0x5d61, 0x1f39,
+ 0x5d62, 0x1501,
+ 0x5e21, 0x151e,
+ 0x5e50, 0x1e9d,
+ 0x5e51, 0x154e,
+ 0x5e56, 0x1f3a,
+ 0x5e57, 0x1554,
+ 0x5e76, 0x1f3b,
+ 0x5e77, 0x1574,
+ 0x5f21, 0x157c,
+ 0x5f73, 0x1e9e,
+ 0x5f74, 0x15cf,
+ 0x6021, 0x15da,
+ 0x6026, 0x1e9f,
+ 0x6027, 0x15e0,
+ 0x605f, 0x1ea0,
+ 0x6060, 0x1619,
+ 0x6121, 0x1638,
+ 0x612b, 0x1ea1,
+ 0x612c, 0x1643,
+ 0x6221, 0x1696,
+ 0x626f, 0x1ea5,
+ 0x6270, 0x16e5,
+ 0x6321, 0x16f4,
+ 0x634a, 0x1ea6,
+ 0x634b, 0x171e,
+ 0x6354, 0x1ea7,
+ 0x6355, 0x1728,
+ 0x6359, 0x1f3c,
+ 0x635a, 0x172d,
+ 0x6421, 0x1752,
+ 0x6439, 0x1ea8,
+ 0x643a, 0x176b,
+ 0x6440, 0x1f3d,
+ 0x6441, 0x1772,
+ 0x6464, 0x1ea9,
+ 0x6465, 0x1796,
+ 0x646e, 0x1eaa,
+ 0x646f, 0x17a0,
+ 0x6521, 0x17b0,
+ 0x6539, 0x1eab,
+ 0x653a, 0x17c9,
+ 0x653b, 0x1eac,
+ 0x653c, 0x17cb,
+ 0x6546, 0x1ead,
+ 0x6547, 0x17d6,
+ 0x6621, 0x180e,
+ 0x6649, 0x1f3e,
+ 0x664a, 0x1837,
+ 0x6721, 0x186c,
+ 0x6764, 0x1eaf,
+ 0x6765, 0x18b0,
+ 0x6769, 0x1eb0,
+ 0x676a, 0x18b5,
+ 0x6772, 0x1eb1,
+ 0x6773, 0x18be,
+ 0x6821, 0x18ca,
+ 0x683b, 0x1eb3,
+ 0x683c, 0x18e5,
+ 0x684d, 0x1f3f,
+ 0x684e, 0x18f7,
+ 0x6921, 0x1928,
+ 0x697e, 0x1f40,
+ 0x6a21, 0x1986,
+ 0x6a3c, 0x1f41,
+ 0x6a3e, 0x19a3,
+ 0x6a6f, 0x1eb8,
+ 0x6a70, 0x19d5,
+ 0x6b21, 0x19e4,
+ 0x6b32, 0x1eb9,
+ 0x6b33, 0x19f6,
+ 0x6b66, 0x1eba,
+ 0x6b67, 0x1a2a,
+ 0x6c21, 0x1a42,
+ 0x6c69, 0x1ebc,
+ 0x6c6a, 0x1a8b,
+ 0x6d21, 0x1aa0,
+ 0x6d4e, 0x1ebe,
+ 0x6d4f, 0x1ace,
+ 0x6e21, 0x1afe,
+ 0x6e29, 0x1ec1,
+ 0x6e2a, 0x1b07,
+ 0x6e3d, 0x1ec2,
+ 0x6e3e, 0x1b1b,
+ 0x6f21, 0x1b5c,
+ 0x7021, 0x1bba,
+ 0x7051, 0x1ec7,
+ 0x7052, 0x1beb,
+ 0x7121, 0x1c18,
+ 0x7159, 0x1f43,
+ 0x715a, 0x1c51,
+ 0x7221, 0x1c76,
+ 0x722d, 0x1eca,
+ 0x722e, 0x1c83,
+ 0x723c, 0x1ecb,
+ 0x723d, 0x1c92,
+ 0x724e, 0x1ecc,
+ 0x724f, 0x1ca4,
+ 0x7321, 0x1cd4,
+ 0x7351, 0x1ecd,
+ 0x7352, 0x1f44,
+ 0x7353, 0x1d06,
+ 0x737d, 0x1ece,
+ 0x737e, 0x1d31,
+ 0x7421, 0x1d32,
+ 0x7425, 0x205c,
+ 0x7721, 0x1f45,
+ 0x7727, 0x1f48,
+ 0x7728, 0x0300,
+ 0x7729, 0x02fa,
+ 0x772a, 0x02f9,
+ 0x772e, 0x1f49,
+ 0x773c, 0x1db1,
+ 0x773f, 0x1f54,
+ 0x7740, 0x1db7,
+ 0x7741, 0x1f55,
+ 0x7744, 0x1db4,
+ 0x7747, 0x1f58,
+ 0x7751, 0x0303,
+ 0x7752, 0x1f62,
+ 0x7753, 0x0304,
+ 0x7754, 0x1f63,
+ 0x7757, 0x1f65,
+ 0x7759, 0x1da4,
+ 0x775a, 0x1da1,
+ 0x775b, 0x1f66,
+ 0x775c, 0x1da2,
+ 0x775d, 0x1f67,
+ 0x7760, 0x1da6,
+ 0x7761, 0x1f6a,
+ 0x7762, 0x1da8,
+ 0x7763, 0x1dac,
+ 0x7764, 0x1f6b,
+ 0x7765, 0x1dae,
+ 0x7766, 0x1dab,
+ 0x7767, 0x1f6c,
+ 0x7769, 0x1daf,
+ 0x776a, 0x1f6e,
+ 0x7774, 0x1f75,
+ 0x777a, 0x1dba,
+ 0x777b, 0x1f7b,
+ 0x777e, 0x1f7c,
+ 0x7829, 0x1f7d,
+ 0x7834, 0x1f87,
+ 0x7849, 0x1d83,
+ 0x785d, 0x1f9b,
+ 0x785e, 0x1d97,
+ 0x786b, 0x1f9c,
+ 0x7921, 0x1fb0,
+ 0x7945, 0x1f16,
+ 0x7949, 0x1fca,
+ 0x794b, 0x1dc4,
+ 0x794c, 0x1fcc,
+ 0x794f, 0x1dc3,
+ 0x7950, 0x1fcf,
+ 0x7955, 0x1dc2,
+ 0x7956, 0x1fd4,
+ 0x795d, 0x1fd8,
+ 0x796f, 0x1fe6,
+ 0x7d21, 0x1ecf,
+ 0x7d23, 0x204c,
+ 0x7d24, 0x2052,
+ 0x7d25, 0x1ed1,
+ 0x7d2f, 0x205a,
+ 0x7d30, 0x2053,
+ 0x7d31, 0x2058,
+ 0x7d32, 0x2055,
+ 0x7d33, 0x1edb,
+ 0x7d45, 0x1eee,
+ 0x7d5b, 0x2048,
+ 0x7d6d, 0x02e0,
+ 0x7d71, 0x1ff6,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12AddHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12AddHMap2, 633
+};
+
+static Gushort japan12AddRKSJHMap2[1270] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x82f2, 0x1f16,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x889f, 0x0465,
+ 0x88a0, 0x1dd1,
+ 0x88a1, 0x0467,
+ 0x88b0, 0x1f19,
+ 0x88b1, 0x0477,
+ 0x88b9, 0x1dd2,
+ 0x88ba, 0x0480,
+ 0x88ec, 0x1dd3,
+ 0x88ed, 0x04b3,
+ 0x88ef, 0x1f1a,
+ 0x88f0, 0x04b6,
+ 0x88f1, 0x1dd4,
+ 0x88f2, 0x04b8,
+ 0x88fa, 0x1dd5,
+ 0x88fb, 0x04c1,
+ 0x8940, 0x04c3,
+ 0x8949, 0x1dd6,
+ 0x894a, 0x04cd,
+ 0x8952, 0x1f1b,
+ 0x8953, 0x04d6,
+ 0x8954, 0x1dd7,
+ 0x8955, 0x04d8,
+ 0x8958, 0x1f1c,
+ 0x8959, 0x04dc,
+ 0x895c, 0x1dda,
+ 0x895d, 0x04e0,
+ 0x8961, 0x1ddb,
+ 0x8962, 0x04e5,
+ 0x8980, 0x0502,
+ 0x898b, 0x1ddc,
+ 0x898c, 0x050e,
+ 0x89a6, 0x1ddd,
+ 0x89a7, 0x0529,
+ 0x89a8, 0x1dde,
+ 0x89a9, 0x052b,
+ 0x89de, 0x1ddf,
+ 0x89df, 0x0561,
+ 0x89e5, 0x1f1d,
+ 0x89e6, 0x0568,
+ 0x89f8, 0x1de0,
+ 0x89f9, 0x057b,
+ 0x8a40, 0x057f,
+ 0x8a41, 0x1de2,
+ 0x8a42, 0x0581,
+ 0x8a80, 0x05be,
+ 0x8a8b, 0x1de4,
+ 0x8a8c, 0x05ca,
+ 0x8a93, 0x1de5,
+ 0x8a94, 0x05d2,
+ 0x8a9a, 0x1de6,
+ 0x8a9b, 0x05d9,
+ 0x8ac0, 0x1de7,
+ 0x8ac1, 0x05ff,
+ 0x8acb, 0x1de8,
+ 0x8acc, 0x060a,
+ 0x8ae3, 0x1de9,
+ 0x8ae4, 0x0622,
+ 0x8b40, 0x063b,
+ 0x8b4a, 0x1dea,
+ 0x8b4b, 0x0646,
+ 0x8b5f, 0x1deb,
+ 0x8b60, 0x065b,
+ 0x8b80, 0x067a,
+ 0x8b82, 0x1f1e,
+ 0x8b83, 0x067d,
+ 0x8b88, 0x1f1f,
+ 0x8b89, 0x0683,
+ 0x8ba0, 0x1dec,
+ 0x8ba1, 0x069b,
+ 0x8ba8, 0x1ded,
+ 0x8ba9, 0x06a3,
+ 0x8bc0, 0x1f20,
+ 0x8bc1, 0x06bb,
+ 0x8bcd, 0x1dee,
+ 0x8bce, 0x06c8,
+ 0x8beb, 0x1def,
+ 0x8bec, 0x06e6,
+ 0x8bf2, 0x1df0,
+ 0x8bf3, 0x06ed,
+ 0x8bf9, 0x1df1,
+ 0x8bfa, 0x06f4,
+ 0x8bfb, 0x1df2,
+ 0x8bfc, 0x06f6,
+ 0x8c40, 0x06f7,
+ 0x8c56, 0x1df4,
+ 0x8c57, 0x070e,
+ 0x8c71, 0x1df7,
+ 0x8c72, 0x0729,
+ 0x8c80, 0x0736,
+ 0x8c91, 0x1dfa,
+ 0x8c92, 0x0748,
+ 0x8c9d, 0x1f21,
+ 0x8c9e, 0x1dfc,
+ 0x8c9f, 0x0755,
+ 0x8cb2, 0x1dfd,
+ 0x8cb3, 0x0769,
+ 0x8cbf, 0x1dfe,
+ 0x8cc0, 0x0776,
+ 0x8d40, 0x07b3,
+ 0x8d4a, 0x1dff,
+ 0x8d4b, 0x07be,
+ 0x8d80, 0x07f2,
+ 0x8d8d, 0x1e02,
+ 0x8d8e, 0x0800,
+ 0x8d94, 0x1e03,
+ 0x8d95, 0x0807,
+ 0x8d99, 0x1e04,
+ 0x8d9a, 0x080c,
+ 0x8dd1, 0x1e05,
+ 0x8dd2, 0x0844,
+ 0x8de5, 0x1e06,
+ 0x8de6, 0x0858,
+ 0x8df2, 0x1e07,
+ 0x8df3, 0x0865,
+ 0x8e40, 0x086f,
+ 0x8e46, 0x1e08,
+ 0x8e47, 0x0876,
+ 0x8e49, 0x1e09,
+ 0x8e4a, 0x0879,
+ 0x8e4b, 0x1e0a,
+ 0x8e4c, 0x087b,
+ 0x8e58, 0x1e0b,
+ 0x8e59, 0x0888,
+ 0x8e60, 0x1f22,
+ 0x8e61, 0x0890,
+ 0x8e80, 0x08ae,
+ 0x8ec6, 0x1e0d,
+ 0x8ec7, 0x08f5,
+ 0x8edb, 0x1e0f,
+ 0x8edd, 0x090b,
+ 0x8f40, 0x092b,
+ 0x8f4a, 0x1e11,
+ 0x8f4b, 0x0936,
+ 0x8f55, 0x1e12,
+ 0x8f56, 0x0941,
+ 0x8f80, 0x096a,
+ 0x8f8c, 0x1e13,
+ 0x8f8d, 0x0977,
+ 0x8f92, 0x1e15,
+ 0x8f94, 0x097e,
+ 0x8fa3, 0x1e17,
+ 0x8fa4, 0x098e,
+ 0x8fb1, 0x1e18,
+ 0x8fb2, 0x099c,
+ 0x8fd3, 0x1e1a,
+ 0x8fd4, 0x09be,
+ 0x8fdd, 0x1e1b,
+ 0x8fde, 0x09c8,
+ 0x8fe2, 0x1e1c,
+ 0x8fe3, 0x09cd,
+ 0x9040, 0x09e7,
+ 0x9049, 0x1e1d,
+ 0x904a, 0x09f1,
+ 0x9078, 0x1f23,
+ 0x9079, 0x0a20,
+ 0x9080, 0x1e1f,
+ 0x9081, 0x0a27,
+ 0x90a0, 0x1e21,
+ 0x90a1, 0x0a47,
+ 0x90e4, 0x1e23,
+ 0x90e5, 0x0a8b,
+ 0x90ef, 0x1e24,
+ 0x90f0, 0x0a96,
+ 0x90f7, 0x1e26,
+ 0x90f8, 0x1f24,
+ 0x90f9, 0x0a9f,
+ 0x90fa, 0x1f25,
+ 0x90fc, 0x0aa2,
+ 0x9140, 0x0aa3,
+ 0x9146, 0x1e28,
+ 0x9147, 0x0aaa,
+ 0x9158, 0x1e29,
+ 0x9159, 0x0abc,
+ 0x916b, 0x1e2a,
+ 0x916c, 0x0acf,
+ 0x916e, 0x1e2b,
+ 0x916f, 0x0ad2,
+ 0x917e, 0x1e2c,
+ 0x9180, 0x0ae2,
+ 0x9189, 0x1e2d,
+ 0x918a, 0x0aec,
+ 0x91b5, 0x1f27,
+ 0x91b6, 0x0b18,
+ 0x91bb, 0x1e2e,
+ 0x91bc, 0x0b1e,
+ 0x91cb, 0x1e2f,
+ 0x91cc, 0x0b2e,
+ 0x91da, 0x1e30,
+ 0x91db, 0x0b3d,
+ 0x91e1, 0x1e31,
+ 0x91e2, 0x0b44,
+ 0x91ed, 0x1e32,
+ 0x91ee, 0x0b50,
+ 0x91fb, 0x1e35,
+ 0x91fc, 0x0b5e,
+ 0x9240, 0x0b5f,
+ 0x9246, 0x1e36,
+ 0x9247, 0x0b66,
+ 0x9248, 0x1e37,
+ 0x9249, 0x0b68,
+ 0x924c, 0x1e39,
+ 0x924e, 0x0b6d,
+ 0x925c, 0x1e3b,
+ 0x925d, 0x0b7c,
+ 0x9280, 0x0b9e,
+ 0x9290, 0x1e3c,
+ 0x9291, 0x0baf,
+ 0x9295, 0x1e3d,
+ 0x9296, 0x0bb4,
+ 0x929c, 0x1e3e,
+ 0x929d, 0x0bbb,
+ 0x92bb, 0x1e3f,
+ 0x92bc, 0x0bda,
+ 0x92c6, 0x1e40,
+ 0x92c7, 0x0be5,
+ 0x92c8, 0x1e41,
+ 0x92c9, 0x0be7,
+ 0x92cd, 0x1e43,
+ 0x92ce, 0x0bec,
+ 0x9340, 0x0c1b,
+ 0x9341, 0x1e44,
+ 0x9342, 0x0c1d,
+ 0x9346, 0x1e45,
+ 0x9347, 0x0c22,
+ 0x934d, 0x1e46,
+ 0x934e, 0x0c29,
+ 0x9355, 0x1e47,
+ 0x9356, 0x0c31,
+ 0x935e, 0x1e48,
+ 0x935f, 0x0c3a,
+ 0x9367, 0x1e49,
+ 0x9368, 0x0c43,
+ 0x936a, 0x1e4a,
+ 0x936b, 0x0c46,
+ 0x9370, 0x1f28,
+ 0x9371, 0x1e4c,
+ 0x9372, 0x0c4d,
+ 0x9380, 0x0c5a,
+ 0x9384, 0x1e4d,
+ 0x9385, 0x0c5f,
+ 0x9398, 0x1e4e,
+ 0x9399, 0x0c73,
+ 0x93c0, 0x1e50,
+ 0x93c1, 0x0c9b,
+ 0x93d2, 0x1e51,
+ 0x93d3, 0x0cad,
+ 0x93d9, 0x1e53,
+ 0x93da, 0x0cb4,
+ 0x93e4, 0x1e56,
+ 0x93e6, 0x0cc0,
+ 0x93e8, 0x1e58,
+ 0x93e9, 0x0cc3,
+ 0x93f4, 0x1ec0,
+ 0x93f5, 0x0ccf,
+ 0x9440, 0x0cd7,
+ 0x9448, 0x1e59,
+ 0x9449, 0x1f29,
+ 0x944a, 0x0ce1,
+ 0x9458, 0x1e5a,
+ 0x9459, 0x0cf0,
+ 0x9476, 0x1e5b,
+ 0x9477, 0x0d0e,
+ 0x9480, 0x0d16,
+ 0x9487, 0x1e5c,
+ 0x9488, 0x0d1e,
+ 0x9489, 0x1e5d,
+ 0x948a, 0x0d20,
+ 0x948d, 0x1e5e,
+ 0x948e, 0x0d24,
+ 0x94a2, 0x1e5f,
+ 0x94a3, 0x0d39,
+ 0x94ac, 0x1e60,
+ 0x94ad, 0x0d43,
+ 0x94ae, 0x1e61,
+ 0x94af, 0x0d45,
+ 0x94be, 0x1f2a,
+ 0x94bf, 0x0d55,
+ 0x94d2, 0x1e62,
+ 0x94d3, 0x0d69,
+ 0x94f3, 0x1e64,
+ 0x94f4, 0x0d8a,
+ 0x9540, 0x0d93,
+ 0x9541, 0x1e65,
+ 0x9543, 0x0d96,
+ 0x954e, 0x1e67,
+ 0x954f, 0x0da2,
+ 0x9551, 0x1e68,
+ 0x9552, 0x0da5,
+ 0x9554, 0x1e69,
+ 0x9555, 0x0da8,
+ 0x955f, 0x1e6a,
+ 0x9560, 0x0db3,
+ 0x956d, 0x1e6b,
+ 0x956e, 0x0dc1,
+ 0x9580, 0x0dd2,
+ 0x95c1, 0x1e6d,
+ 0x95c2, 0x0e14,
+ 0x95cb, 0x1e6e,
+ 0x95cc, 0x0e1e,
+ 0x95d1, 0x1f2b,
+ 0x95d2, 0x0e24,
+ 0x95d8, 0x1e6f,
+ 0x95d9, 0x0e2b,
+ 0x95f7, 0x1e70,
+ 0x95f8, 0x0e4a,
+ 0x9640, 0x0e4f,
+ 0x9648, 0x1e72,
+ 0x9649, 0x0e58,
+ 0x966a, 0x1e73,
+ 0x966b, 0x0e7a,
+ 0x9680, 0x0e8e,
+ 0x9690, 0x1e74,
+ 0x9691, 0x0e9f,
+ 0x9698, 0x1f2c,
+ 0x9699, 0x0ea7,
+ 0x96cb, 0x1e75,
+ 0x96cc, 0x0eda,
+ 0x96d7, 0x1e76,
+ 0x96d8, 0x0ee6,
+ 0x96dd, 0x1e77,
+ 0x96de, 0x0eec,
+ 0x96e0, 0x1e78,
+ 0x96e1, 0x0eef,
+ 0x96f8, 0x1e79,
+ 0x96f9, 0x0f07,
+ 0x96fa, 0x1e7a,
+ 0x96fb, 0x0f09,
+ 0x9740, 0x0f0b,
+ 0x9751, 0x1e7c,
+ 0x9752, 0x0f1d,
+ 0x976f, 0x1e7d,
+ 0x9770, 0x0f3b,
+ 0x9773, 0x1e7e,
+ 0x9774, 0x0f3f,
+ 0x9780, 0x0f4a,
+ 0x9789, 0x1e7f,
+ 0x978a, 0x0f54,
+ 0x97f8, 0x1e81,
+ 0x97fa, 0x1f2d,
+ 0x97fb, 0x0fc5,
+ 0x9840, 0x1e83,
+ 0x9841, 0x0fc8,
+ 0x9850, 0x1e84,
+ 0x9851, 0x0fd8,
+ 0x9858, 0x1e85,
+ 0x9859, 0x0fe0,
+ 0x989f, 0x0ffa,
+ 0x9940, 0x1058,
+ 0x9941, 0x1f2e,
+ 0x9942, 0x105a,
+ 0x995c, 0x1e86,
+ 0x995d, 0x1075,
+ 0x996c, 0x1e89,
+ 0x996d, 0x1085,
+ 0x9980, 0x1097,
+ 0x99b6, 0x1f2f,
+ 0x99b7, 0x10ce,
+ 0x9a40, 0x1114,
+ 0x9a4f, 0x1e8a,
+ 0x9a50, 0x1124,
+ 0x9a59, 0x1e8b,
+ 0x9a5a, 0x112e,
+ 0x9a67, 0x1f30,
+ 0x9a68, 0x113c,
+ 0x9a7d, 0x1e8d,
+ 0x9a7e, 0x1152,
+ 0x9a80, 0x1153,
+ 0x9a8b, 0x1e8e,
+ 0x9a8c, 0x1f31,
+ 0x9a8d, 0x1160,
+ 0x9ac2, 0x1e8f,
+ 0x9ac3, 0x1f32,
+ 0x9ac4, 0x1197,
+ 0x9aea, 0x1f33,
+ 0x9aeb, 0x11be,
+ 0x9b40, 0x11d0,
+ 0x9b5c, 0x1e90,
+ 0x9b5d, 0x11ed,
+ 0x9b80, 0x120f,
+ 0x9b83, 0x1e91,
+ 0x9b84, 0x1213,
+ 0x9b98, 0x1f34,
+ 0x9b99, 0x1228,
+ 0x9ba0, 0x1e92,
+ 0x9ba1, 0x1230,
+ 0x9bfb, 0x1f35,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9ca2, 0x1e94,
+ 0x9ca3, 0x12ee,
+ 0x9d40, 0x1348,
+ 0x9d47, 0x1f37,
+ 0x9d48, 0x1350,
+ 0x9d80, 0x1e95,
+ 0x9d81, 0x1388,
+ 0x9d8c, 0x1e96,
+ 0x9d8d, 0x1394,
+ 0x9db7, 0x1e97,
+ 0x9db8, 0x13bf,
+ 0x9df8, 0x1f38,
+ 0x9df9, 0x1400,
+ 0x9e40, 0x1404,
+ 0x9e64, 0x1e99,
+ 0x9e65, 0x1429,
+ 0x9e80, 0x1443,
+ 0x9e8b, 0x1e9b,
+ 0x9e8c, 0x144f,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0x9f81, 0x1f39,
+ 0x9f82, 0x1501,
+ 0x9fce, 0x1e9d,
+ 0x9fcf, 0x154e,
+ 0x9fd4, 0x1f3a,
+ 0x9fd5, 0x1554,
+ 0x9ff4, 0x1f3b,
+ 0x9ff5, 0x1574,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe093, 0x1e9e,
+ 0xe094, 0x15cf,
+ 0xe0a4, 0x1e9f,
+ 0xe0a5, 0x15e0,
+ 0xe0dd, 0x1ea0,
+ 0xe0de, 0x1619,
+ 0xe140, 0x1638,
+ 0xe14a, 0x1ea1,
+ 0xe14b, 0x1643,
+ 0xe180, 0x1677,
+ 0xe1ed, 0x1ea5,
+ 0xe1ee, 0x16e5,
+ 0xe240, 0x16f4,
+ 0xe269, 0x1ea6,
+ 0xe26a, 0x171e,
+ 0xe273, 0x1ea7,
+ 0xe274, 0x1728,
+ 0xe278, 0x1f3c,
+ 0xe279, 0x172d,
+ 0xe280, 0x1733,
+ 0xe2b7, 0x1ea8,
+ 0xe2b8, 0x176b,
+ 0xe2be, 0x1f3d,
+ 0xe2bf, 0x1772,
+ 0xe2e2, 0x1ea9,
+ 0xe2e3, 0x1796,
+ 0xe2ec, 0x1eaa,
+ 0xe2ed, 0x17a0,
+ 0xe340, 0x17b0,
+ 0xe358, 0x1eab,
+ 0xe359, 0x17c9,
+ 0xe35a, 0x1eac,
+ 0xe35b, 0x17cb,
+ 0xe365, 0x1ead,
+ 0xe366, 0x17d6,
+ 0xe380, 0x17ef,
+ 0xe3c7, 0x1f3e,
+ 0xe3c8, 0x1837,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe484, 0x1eaf,
+ 0xe485, 0x18b0,
+ 0xe489, 0x1eb0,
+ 0xe48a, 0x18b5,
+ 0xe492, 0x1eb1,
+ 0xe493, 0x18be,
+ 0xe4b9, 0x1eb3,
+ 0xe4ba, 0x18e5,
+ 0xe4cb, 0x1f3f,
+ 0xe4cc, 0x18f7,
+ 0xe540, 0x1928,
+ 0xe580, 0x1967,
+ 0xe59e, 0x1f40,
+ 0xe59f, 0x1986,
+ 0xe5ba, 0x1f41,
+ 0xe5bc, 0x19a3,
+ 0xe5ed, 0x1eb8,
+ 0xe5ee, 0x19d5,
+ 0xe640, 0x19e4,
+ 0xe651, 0x1eb9,
+ 0xe652, 0x19f6,
+ 0xe680, 0x1a23,
+ 0xe686, 0x1eba,
+ 0xe687, 0x1a2a,
+ 0xe6e7, 0x1ebc,
+ 0xe6e8, 0x1a8b,
+ 0xe740, 0x1aa0,
+ 0xe76d, 0x1ebe,
+ 0xe76e, 0x1ace,
+ 0xe780, 0x1adf,
+ 0xe7a7, 0x1ec1,
+ 0xe7a8, 0x1b07,
+ 0xe7bb, 0x1ec2,
+ 0xe7bc, 0x1b1b,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe8cf, 0x1ec7,
+ 0xe8d0, 0x1beb,
+ 0xe940, 0x1c18,
+ 0xe978, 0x1f43,
+ 0xe979, 0x1c51,
+ 0xe980, 0x1c57,
+ 0xe9ab, 0x1eca,
+ 0xe9ac, 0x1c83,
+ 0xe9ba, 0x1ecb,
+ 0xe9bb, 0x1c92,
+ 0xe9cc, 0x1ecc,
+ 0xe9cd, 0x1ca4,
+ 0xea40, 0x1cd4,
+ 0xea70, 0x1ecd,
+ 0xea71, 0x1f44,
+ 0xea72, 0x1d06,
+ 0xea80, 0x1d13,
+ 0xea9d, 0x1ece,
+ 0xea9e, 0x1d31,
+ 0xeaa3, 0x205c,
+ 0xec40, 0x1f45,
+ 0xec46, 0x1f48,
+ 0xec47, 0x0300,
+ 0xec48, 0x02fa,
+ 0xec49, 0x02f9,
+ 0xec4d, 0x1f49,
+ 0xec5b, 0x1db1,
+ 0xec5e, 0x1f54,
+ 0xec5f, 0x1db7,
+ 0xec60, 0x1f55,
+ 0xec63, 0x1db4,
+ 0xec66, 0x1f58,
+ 0xec70, 0x0303,
+ 0xec71, 0x1f62,
+ 0xec72, 0x0304,
+ 0xec73, 0x1f63,
+ 0xec76, 0x1f65,
+ 0xec78, 0x1da4,
+ 0xec79, 0x1da1,
+ 0xec7a, 0x1f66,
+ 0xec7b, 0x1da2,
+ 0xec7c, 0x1f67,
+ 0xec80, 0x1da6,
+ 0xec81, 0x1f6a,
+ 0xec82, 0x1da8,
+ 0xec83, 0x1dac,
+ 0xec84, 0x1f6b,
+ 0xec85, 0x1dae,
+ 0xec86, 0x1dab,
+ 0xec87, 0x1f6c,
+ 0xec89, 0x1daf,
+ 0xec8a, 0x1f6e,
+ 0xec94, 0x1f75,
+ 0xec9a, 0x1dba,
+ 0xec9b, 0x1f7b,
+ 0xec9e, 0x1f7c,
+ 0xeca7, 0x1f7d,
+ 0xecb2, 0x1f87,
+ 0xecc7, 0x1d83,
+ 0xecdb, 0x1f9b,
+ 0xecdc, 0x1d97,
+ 0xece9, 0x1f9c,
+ 0xed40, 0x1fb0,
+ 0xed64, 0x1f16,
+ 0xed68, 0x1fca,
+ 0xed6a, 0x1dc4,
+ 0xed6b, 0x1fcc,
+ 0xed6e, 0x1dc3,
+ 0xed6f, 0x1fcf,
+ 0xed74, 0x1dc2,
+ 0xed75, 0x1fd4,
+ 0xed7c, 0x1fd8,
+ 0xed80, 0x1fdb,
+ 0xed8f, 0x1fe6,
+ 0xef40, 0x1ecf,
+ 0xef42, 0x204c,
+ 0xef43, 0x2052,
+ 0xef44, 0x1ed1,
+ 0xef4e, 0x205a,
+ 0xef4f, 0x2053,
+ 0xef50, 0x2058,
+ 0xef51, 0x2055,
+ 0xef52, 0x1edb,
+ 0xef64, 0x1eee,
+ 0xef7a, 0x2048,
+ 0xef8d, 0x02e0,
+ 0xef91, 0x1ff6,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12AddRKSJHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12AddRKSJHMap2, 635
+};
+
+static Gushort japan12AddRKSJVMap2[1384] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x82f2, 0x1f16,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x889f, 0x0465,
+ 0x88a0, 0x1dd1,
+ 0x88a1, 0x0467,
+ 0x88b0, 0x1f19,
+ 0x88b1, 0x0477,
+ 0x88b9, 0x1dd2,
+ 0x88ba, 0x0480,
+ 0x88ec, 0x1dd3,
+ 0x88ed, 0x04b3,
+ 0x88ef, 0x1f1a,
+ 0x88f0, 0x04b6,
+ 0x88f1, 0x1dd4,
+ 0x88f2, 0x04b8,
+ 0x88fa, 0x1dd5,
+ 0x88fb, 0x04c1,
+ 0x8940, 0x04c3,
+ 0x8949, 0x1dd6,
+ 0x894a, 0x04cd,
+ 0x8952, 0x1f1b,
+ 0x8953, 0x04d6,
+ 0x8954, 0x1dd7,
+ 0x8955, 0x04d8,
+ 0x8958, 0x1f1c,
+ 0x8959, 0x04dc,
+ 0x895c, 0x1dda,
+ 0x895d, 0x04e0,
+ 0x8961, 0x1ddb,
+ 0x8962, 0x04e5,
+ 0x8980, 0x0502,
+ 0x898b, 0x1ddc,
+ 0x898c, 0x050e,
+ 0x89a6, 0x1ddd,
+ 0x89a7, 0x0529,
+ 0x89a8, 0x1dde,
+ 0x89a9, 0x052b,
+ 0x89de, 0x1ddf,
+ 0x89df, 0x0561,
+ 0x89e5, 0x1f1d,
+ 0x89e6, 0x0568,
+ 0x89f8, 0x1de0,
+ 0x89f9, 0x057b,
+ 0x8a40, 0x057f,
+ 0x8a41, 0x1de2,
+ 0x8a42, 0x0581,
+ 0x8a80, 0x05be,
+ 0x8a8b, 0x1de4,
+ 0x8a8c, 0x05ca,
+ 0x8a93, 0x1de5,
+ 0x8a94, 0x05d2,
+ 0x8a9a, 0x1de6,
+ 0x8a9b, 0x05d9,
+ 0x8ac0, 0x1de7,
+ 0x8ac1, 0x05ff,
+ 0x8acb, 0x1de8,
+ 0x8acc, 0x060a,
+ 0x8ae3, 0x1de9,
+ 0x8ae4, 0x0622,
+ 0x8b40, 0x063b,
+ 0x8b4a, 0x1dea,
+ 0x8b4b, 0x0646,
+ 0x8b5f, 0x1deb,
+ 0x8b60, 0x065b,
+ 0x8b80, 0x067a,
+ 0x8b82, 0x1f1e,
+ 0x8b83, 0x067d,
+ 0x8b88, 0x1f1f,
+ 0x8b89, 0x0683,
+ 0x8ba0, 0x1dec,
+ 0x8ba1, 0x069b,
+ 0x8ba8, 0x1ded,
+ 0x8ba9, 0x06a3,
+ 0x8bc0, 0x1f20,
+ 0x8bc1, 0x06bb,
+ 0x8bcd, 0x1dee,
+ 0x8bce, 0x06c8,
+ 0x8beb, 0x1def,
+ 0x8bec, 0x06e6,
+ 0x8bf2, 0x1df0,
+ 0x8bf3, 0x06ed,
+ 0x8bf9, 0x1df1,
+ 0x8bfa, 0x06f4,
+ 0x8bfb, 0x1df2,
+ 0x8bfc, 0x06f6,
+ 0x8c40, 0x06f7,
+ 0x8c56, 0x1df4,
+ 0x8c57, 0x070e,
+ 0x8c71, 0x1df7,
+ 0x8c72, 0x0729,
+ 0x8c80, 0x0736,
+ 0x8c91, 0x1dfa,
+ 0x8c92, 0x0748,
+ 0x8c9d, 0x1f21,
+ 0x8c9e, 0x1dfc,
+ 0x8c9f, 0x0755,
+ 0x8cb2, 0x1dfd,
+ 0x8cb3, 0x0769,
+ 0x8cbf, 0x1dfe,
+ 0x8cc0, 0x0776,
+ 0x8d40, 0x07b3,
+ 0x8d4a, 0x1dff,
+ 0x8d4b, 0x07be,
+ 0x8d80, 0x07f2,
+ 0x8d8d, 0x1e02,
+ 0x8d8e, 0x0800,
+ 0x8d94, 0x1e03,
+ 0x8d95, 0x0807,
+ 0x8d99, 0x1e04,
+ 0x8d9a, 0x080c,
+ 0x8dd1, 0x1e05,
+ 0x8dd2, 0x0844,
+ 0x8de5, 0x1e06,
+ 0x8de6, 0x0858,
+ 0x8df2, 0x1e07,
+ 0x8df3, 0x0865,
+ 0x8e40, 0x086f,
+ 0x8e46, 0x1e08,
+ 0x8e47, 0x0876,
+ 0x8e49, 0x1e09,
+ 0x8e4a, 0x0879,
+ 0x8e4b, 0x1e0a,
+ 0x8e4c, 0x087b,
+ 0x8e58, 0x1e0b,
+ 0x8e59, 0x0888,
+ 0x8e60, 0x1f22,
+ 0x8e61, 0x0890,
+ 0x8e80, 0x08ae,
+ 0x8ec6, 0x1e0d,
+ 0x8ec7, 0x08f5,
+ 0x8edb, 0x1e0f,
+ 0x8edd, 0x090b,
+ 0x8f40, 0x092b,
+ 0x8f4a, 0x1e11,
+ 0x8f4b, 0x0936,
+ 0x8f55, 0x1e12,
+ 0x8f56, 0x0941,
+ 0x8f80, 0x096a,
+ 0x8f8c, 0x1e13,
+ 0x8f8d, 0x0977,
+ 0x8f92, 0x1e15,
+ 0x8f94, 0x097e,
+ 0x8fa3, 0x1e17,
+ 0x8fa4, 0x098e,
+ 0x8fb1, 0x1e18,
+ 0x8fb2, 0x099c,
+ 0x8fd3, 0x1e1a,
+ 0x8fd4, 0x09be,
+ 0x8fdd, 0x1e1b,
+ 0x8fde, 0x09c8,
+ 0x8fe2, 0x1e1c,
+ 0x8fe3, 0x09cd,
+ 0x9040, 0x09e7,
+ 0x9049, 0x1e1d,
+ 0x904a, 0x09f1,
+ 0x9078, 0x1f23,
+ 0x9079, 0x0a20,
+ 0x9080, 0x1e1f,
+ 0x9081, 0x0a27,
+ 0x90a0, 0x1e21,
+ 0x90a1, 0x0a47,
+ 0x90e4, 0x1e23,
+ 0x90e5, 0x0a8b,
+ 0x90ef, 0x1e24,
+ 0x90f0, 0x0a96,
+ 0x90f7, 0x1e26,
+ 0x90f8, 0x1f24,
+ 0x90f9, 0x0a9f,
+ 0x90fa, 0x1f25,
+ 0x90fc, 0x0aa2,
+ 0x9140, 0x0aa3,
+ 0x9146, 0x1e28,
+ 0x9147, 0x0aaa,
+ 0x9158, 0x1e29,
+ 0x9159, 0x0abc,
+ 0x916b, 0x1e2a,
+ 0x916c, 0x0acf,
+ 0x916e, 0x1e2b,
+ 0x916f, 0x0ad2,
+ 0x917e, 0x1e2c,
+ 0x9180, 0x0ae2,
+ 0x9189, 0x1e2d,
+ 0x918a, 0x0aec,
+ 0x91b5, 0x1f27,
+ 0x91b6, 0x0b18,
+ 0x91bb, 0x1e2e,
+ 0x91bc, 0x0b1e,
+ 0x91cb, 0x1e2f,
+ 0x91cc, 0x0b2e,
+ 0x91da, 0x1e30,
+ 0x91db, 0x0b3d,
+ 0x91e1, 0x1e31,
+ 0x91e2, 0x0b44,
+ 0x91ed, 0x1e32,
+ 0x91ee, 0x0b50,
+ 0x91fb, 0x1e35,
+ 0x91fc, 0x0b5e,
+ 0x9240, 0x0b5f,
+ 0x9246, 0x1e36,
+ 0x9247, 0x0b66,
+ 0x9248, 0x1e37,
+ 0x9249, 0x0b68,
+ 0x924c, 0x1e39,
+ 0x924e, 0x0b6d,
+ 0x925c, 0x1e3b,
+ 0x925d, 0x0b7c,
+ 0x9280, 0x0b9e,
+ 0x9290, 0x1e3c,
+ 0x9291, 0x0baf,
+ 0x9295, 0x1e3d,
+ 0x9296, 0x0bb4,
+ 0x929c, 0x1e3e,
+ 0x929d, 0x0bbb,
+ 0x92bb, 0x1e3f,
+ 0x92bc, 0x0bda,
+ 0x92c6, 0x1e40,
+ 0x92c7, 0x0be5,
+ 0x92c8, 0x1e41,
+ 0x92c9, 0x0be7,
+ 0x92cd, 0x1e43,
+ 0x92ce, 0x0bec,
+ 0x9340, 0x0c1b,
+ 0x9341, 0x1e44,
+ 0x9342, 0x0c1d,
+ 0x9346, 0x1e45,
+ 0x9347, 0x0c22,
+ 0x934d, 0x1e46,
+ 0x934e, 0x0c29,
+ 0x9355, 0x1e47,
+ 0x9356, 0x0c31,
+ 0x935e, 0x1e48,
+ 0x935f, 0x0c3a,
+ 0x9367, 0x1e49,
+ 0x9368, 0x0c43,
+ 0x936a, 0x1e4a,
+ 0x936b, 0x0c46,
+ 0x9370, 0x1f28,
+ 0x9371, 0x1e4c,
+ 0x9372, 0x0c4d,
+ 0x9380, 0x0c5a,
+ 0x9384, 0x1e4d,
+ 0x9385, 0x0c5f,
+ 0x9398, 0x1e4e,
+ 0x9399, 0x0c73,
+ 0x93c0, 0x1e50,
+ 0x93c1, 0x0c9b,
+ 0x93d2, 0x1e51,
+ 0x93d3, 0x0cad,
+ 0x93d9, 0x1e53,
+ 0x93da, 0x0cb4,
+ 0x93e4, 0x1e56,
+ 0x93e6, 0x0cc0,
+ 0x93e8, 0x1e58,
+ 0x93e9, 0x0cc3,
+ 0x93f4, 0x1ec0,
+ 0x93f5, 0x0ccf,
+ 0x9440, 0x0cd7,
+ 0x9448, 0x1e59,
+ 0x9449, 0x1f29,
+ 0x944a, 0x0ce1,
+ 0x9458, 0x1e5a,
+ 0x9459, 0x0cf0,
+ 0x9476, 0x1e5b,
+ 0x9477, 0x0d0e,
+ 0x9480, 0x0d16,
+ 0x9487, 0x1e5c,
+ 0x9488, 0x0d1e,
+ 0x9489, 0x1e5d,
+ 0x948a, 0x0d20,
+ 0x948d, 0x1e5e,
+ 0x948e, 0x0d24,
+ 0x94a2, 0x1e5f,
+ 0x94a3, 0x0d39,
+ 0x94ac, 0x1e60,
+ 0x94ad, 0x0d43,
+ 0x94ae, 0x1e61,
+ 0x94af, 0x0d45,
+ 0x94be, 0x1f2a,
+ 0x94bf, 0x0d55,
+ 0x94d2, 0x1e62,
+ 0x94d3, 0x0d69,
+ 0x94f3, 0x1e64,
+ 0x94f4, 0x0d8a,
+ 0x9540, 0x0d93,
+ 0x9541, 0x1e65,
+ 0x9543, 0x0d96,
+ 0x954e, 0x1e67,
+ 0x954f, 0x0da2,
+ 0x9551, 0x1e68,
+ 0x9552, 0x0da5,
+ 0x9554, 0x1e69,
+ 0x9555, 0x0da8,
+ 0x955f, 0x1e6a,
+ 0x9560, 0x0db3,
+ 0x956d, 0x1e6b,
+ 0x956e, 0x0dc1,
+ 0x9580, 0x0dd2,
+ 0x95c1, 0x1e6d,
+ 0x95c2, 0x0e14,
+ 0x95cb, 0x1e6e,
+ 0x95cc, 0x0e1e,
+ 0x95d1, 0x1f2b,
+ 0x95d2, 0x0e24,
+ 0x95d8, 0x1e6f,
+ 0x95d9, 0x0e2b,
+ 0x95f7, 0x1e70,
+ 0x95f8, 0x0e4a,
+ 0x9640, 0x0e4f,
+ 0x9648, 0x1e72,
+ 0x9649, 0x0e58,
+ 0x966a, 0x1e73,
+ 0x966b, 0x0e7a,
+ 0x9680, 0x0e8e,
+ 0x9690, 0x1e74,
+ 0x9691, 0x0e9f,
+ 0x9698, 0x1f2c,
+ 0x9699, 0x0ea7,
+ 0x96cb, 0x1e75,
+ 0x96cc, 0x0eda,
+ 0x96d7, 0x1e76,
+ 0x96d8, 0x0ee6,
+ 0x96dd, 0x1e77,
+ 0x96de, 0x0eec,
+ 0x96e0, 0x1e78,
+ 0x96e1, 0x0eef,
+ 0x96f8, 0x1e79,
+ 0x96f9, 0x0f07,
+ 0x96fa, 0x1e7a,
+ 0x96fb, 0x0f09,
+ 0x9740, 0x0f0b,
+ 0x9751, 0x1e7c,
+ 0x9752, 0x0f1d,
+ 0x976f, 0x1e7d,
+ 0x9770, 0x0f3b,
+ 0x9773, 0x1e7e,
+ 0x9774, 0x0f3f,
+ 0x9780, 0x0f4a,
+ 0x9789, 0x1e7f,
+ 0x978a, 0x0f54,
+ 0x97f8, 0x1e81,
+ 0x97fa, 0x1f2d,
+ 0x97fb, 0x0fc5,
+ 0x9840, 0x1e83,
+ 0x9841, 0x0fc8,
+ 0x9850, 0x1e84,
+ 0x9851, 0x0fd8,
+ 0x9858, 0x1e85,
+ 0x9859, 0x0fe0,
+ 0x989f, 0x0ffa,
+ 0x9940, 0x1058,
+ 0x9941, 0x1f2e,
+ 0x9942, 0x105a,
+ 0x995c, 0x1e86,
+ 0x995d, 0x1075,
+ 0x996c, 0x1e89,
+ 0x996d, 0x1085,
+ 0x9980, 0x1097,
+ 0x99b6, 0x1f2f,
+ 0x99b7, 0x10ce,
+ 0x9a40, 0x1114,
+ 0x9a4f, 0x1e8a,
+ 0x9a50, 0x1124,
+ 0x9a59, 0x1e8b,
+ 0x9a5a, 0x112e,
+ 0x9a67, 0x1f30,
+ 0x9a68, 0x113c,
+ 0x9a7d, 0x1e8d,
+ 0x9a7e, 0x1152,
+ 0x9a80, 0x1153,
+ 0x9a8b, 0x1e8e,
+ 0x9a8c, 0x1f31,
+ 0x9a8d, 0x1160,
+ 0x9ac2, 0x1e8f,
+ 0x9ac3, 0x1f32,
+ 0x9ac4, 0x1197,
+ 0x9aea, 0x1f33,
+ 0x9aeb, 0x11be,
+ 0x9b40, 0x11d0,
+ 0x9b5c, 0x1e90,
+ 0x9b5d, 0x11ed,
+ 0x9b80, 0x120f,
+ 0x9b83, 0x1e91,
+ 0x9b84, 0x1213,
+ 0x9b98, 0x1f34,
+ 0x9b99, 0x1228,
+ 0x9ba0, 0x1e92,
+ 0x9ba1, 0x1230,
+ 0x9bfb, 0x1f35,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9ca2, 0x1e94,
+ 0x9ca3, 0x12ee,
+ 0x9d40, 0x1348,
+ 0x9d47, 0x1f37,
+ 0x9d48, 0x1350,
+ 0x9d80, 0x1e95,
+ 0x9d81, 0x1388,
+ 0x9d8c, 0x1e96,
+ 0x9d8d, 0x1394,
+ 0x9db7, 0x1e97,
+ 0x9db8, 0x13bf,
+ 0x9df8, 0x1f38,
+ 0x9df9, 0x1400,
+ 0x9e40, 0x1404,
+ 0x9e64, 0x1e99,
+ 0x9e65, 0x1429,
+ 0x9e80, 0x1443,
+ 0x9e8b, 0x1e9b,
+ 0x9e8c, 0x144f,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0x9f81, 0x1f39,
+ 0x9f82, 0x1501,
+ 0x9fce, 0x1e9d,
+ 0x9fcf, 0x154e,
+ 0x9fd4, 0x1f3a,
+ 0x9fd5, 0x1554,
+ 0x9ff4, 0x1f3b,
+ 0x9ff5, 0x1574,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe093, 0x1e9e,
+ 0xe094, 0x15cf,
+ 0xe0a4, 0x1e9f,
+ 0xe0a5, 0x15e0,
+ 0xe0dd, 0x1ea0,
+ 0xe0de, 0x1619,
+ 0xe140, 0x1638,
+ 0xe14a, 0x1ea1,
+ 0xe14b, 0x1643,
+ 0xe180, 0x1677,
+ 0xe1ed, 0x1ea5,
+ 0xe1ee, 0x16e5,
+ 0xe240, 0x16f4,
+ 0xe269, 0x1ea6,
+ 0xe26a, 0x171e,
+ 0xe273, 0x1ea7,
+ 0xe274, 0x1728,
+ 0xe278, 0x1f3c,
+ 0xe279, 0x172d,
+ 0xe280, 0x1733,
+ 0xe2b7, 0x1ea8,
+ 0xe2b8, 0x176b,
+ 0xe2be, 0x1f3d,
+ 0xe2bf, 0x1772,
+ 0xe2e2, 0x1ea9,
+ 0xe2e3, 0x1796,
+ 0xe2ec, 0x1eaa,
+ 0xe2ed, 0x17a0,
+ 0xe340, 0x17b0,
+ 0xe358, 0x1eab,
+ 0xe359, 0x17c9,
+ 0xe35a, 0x1eac,
+ 0xe35b, 0x17cb,
+ 0xe365, 0x1ead,
+ 0xe366, 0x17d6,
+ 0xe380, 0x17ef,
+ 0xe3c7, 0x1f3e,
+ 0xe3c8, 0x1837,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe484, 0x1eaf,
+ 0xe485, 0x18b0,
+ 0xe489, 0x1eb0,
+ 0xe48a, 0x18b5,
+ 0xe492, 0x1eb1,
+ 0xe493, 0x18be,
+ 0xe4b9, 0x1eb3,
+ 0xe4ba, 0x18e5,
+ 0xe4cb, 0x1f3f,
+ 0xe4cc, 0x18f7,
+ 0xe540, 0x1928,
+ 0xe580, 0x1967,
+ 0xe59e, 0x1f40,
+ 0xe59f, 0x1986,
+ 0xe5ba, 0x1f41,
+ 0xe5bc, 0x19a3,
+ 0xe5ed, 0x1eb8,
+ 0xe5ee, 0x19d5,
+ 0xe640, 0x19e4,
+ 0xe651, 0x1eb9,
+ 0xe652, 0x19f6,
+ 0xe680, 0x1a23,
+ 0xe686, 0x1eba,
+ 0xe687, 0x1a2a,
+ 0xe6e7, 0x1ebc,
+ 0xe6e8, 0x1a8b,
+ 0xe740, 0x1aa0,
+ 0xe76d, 0x1ebe,
+ 0xe76e, 0x1ace,
+ 0xe780, 0x1adf,
+ 0xe7a7, 0x1ec1,
+ 0xe7a8, 0x1b07,
+ 0xe7bb, 0x1ec2,
+ 0xe7bc, 0x1b1b,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe8cf, 0x1ec7,
+ 0xe8d0, 0x1beb,
+ 0xe940, 0x1c18,
+ 0xe978, 0x1f43,
+ 0xe979, 0x1c51,
+ 0xe980, 0x1c57,
+ 0xe9ab, 0x1eca,
+ 0xe9ac, 0x1c83,
+ 0xe9ba, 0x1ecb,
+ 0xe9bb, 0x1c92,
+ 0xe9cc, 0x1ecc,
+ 0xe9cd, 0x1ca4,
+ 0xea40, 0x1cd4,
+ 0xea70, 0x1ecd,
+ 0xea71, 0x1f44,
+ 0xea72, 0x1d06,
+ 0xea80, 0x1d13,
+ 0xea9d, 0x1ece,
+ 0xea9e, 0x1d31,
+ 0xeaa3, 0x205c,
+ 0xec40, 0x1f45,
+ 0xec46, 0x1f48,
+ 0xec47, 0x0300,
+ 0xec48, 0x02fa,
+ 0xec49, 0x02f9,
+ 0xec4d, 0x1f49,
+ 0xec5b, 0x1db1,
+ 0xec5e, 0x1f54,
+ 0xec5f, 0x1db7,
+ 0xec60, 0x1f55,
+ 0xec63, 0x1db4,
+ 0xec66, 0x1f58,
+ 0xec70, 0x0303,
+ 0xec71, 0x1f62,
+ 0xec72, 0x0304,
+ 0xec73, 0x1f63,
+ 0xec76, 0x1f65,
+ 0xec78, 0x1da4,
+ 0xec79, 0x1da1,
+ 0xec7a, 0x1f66,
+ 0xec7b, 0x1da2,
+ 0xec7c, 0x1f67,
+ 0xec80, 0x1da6,
+ 0xec81, 0x1f6a,
+ 0xec82, 0x1da8,
+ 0xec83, 0x1dac,
+ 0xec84, 0x1f6b,
+ 0xec85, 0x1dae,
+ 0xec86, 0x1dab,
+ 0xec87, 0x1f6c,
+ 0xec89, 0x1daf,
+ 0xec8a, 0x1f6e,
+ 0xec94, 0x1f75,
+ 0xec9a, 0x1dba,
+ 0xec9b, 0x1f7b,
+ 0xec9e, 0x1f7c,
+ 0xeca7, 0x1f7d,
+ 0xecb2, 0x1f87,
+ 0xecc7, 0x1d83,
+ 0xecdb, 0x1f9b,
+ 0xecdc, 0x1d97,
+ 0xece9, 0x1f9c,
+ 0xed40, 0x1fb0,
+ 0xed64, 0x1f16,
+ 0xed68, 0x1fca,
+ 0xed6a, 0x1dc4,
+ 0xed6b, 0x1fcc,
+ 0xed6e, 0x1dc3,
+ 0xed6f, 0x1fcf,
+ 0xed74, 0x1dc2,
+ 0xed75, 0x1fd4,
+ 0xed7c, 0x1fd8,
+ 0xed80, 0x1fdb,
+ 0xed8f, 0x1fe6,
+ 0xef40, 0x1ecf,
+ 0xef42, 0x204c,
+ 0xef43, 0x2052,
+ 0xef44, 0x1ed1,
+ 0xef4e, 0x205a,
+ 0xef4f, 0x2053,
+ 0xef50, 0x2058,
+ 0xef51, 0x2055,
+ 0xef52, 0x1edb,
+ 0xef64, 0x1eee,
+ 0xef7a, 0x2048,
+ 0xef8d, 0x02e0,
+ 0xef91, 0x1ff6,
+ 0x8141, 0x1ecf,
+ 0x8143, 0x204c,
+ 0x8144, 0x2052,
+ 0x8150, 0x1ed1,
+ 0x815b, 0x1ed3,
+ 0x8160, 0x1ed6,
+ 0x8165, 0x205a,
+ 0x8166, 0x2053,
+ 0x8167, 0x2058,
+ 0x8168, 0x2055,
+ 0x8169, 0x1edb,
+ 0x829f, 0x1eee,
+ 0x82a1, 0x1eef,
+ 0x82a3, 0x1ef0,
+ 0x82a5, 0x1ef1,
+ 0x82a7, 0x1ef2,
+ 0x82c1, 0x1ef3,
+ 0x82e1, 0x1ef4,
+ 0x82e3, 0x1ef5,
+ 0x82e5, 0x1ef6,
+ 0x82ec, 0x1ef7,
+ 0x82f3, 0x2048,
+ 0x8340, 0x1ef8,
+ 0x8342, 0x1ef9,
+ 0x8344, 0x1efa,
+ 0x8346, 0x1efb,
+ 0x8348, 0x1efc,
+ 0x8362, 0x1efd,
+ 0x8383, 0x1efe,
+ 0x8385, 0x1eff,
+ 0x8387, 0x1f00,
+ 0x838e, 0x1f01,
+ 0x8395, 0x1f02,
+ 0xec78, 0x1f07,
+ 0xec79, 0x1f04,
+ 0xec7a, 0x2089,
+ 0xec7b, 0x1f05,
+ 0xec7c, 0x208a,
+ 0xec7d, 0x2093,
+ 0xec80, 0x1f09,
+ 0xec81, 0x2092,
+ 0xec82, 0x1f0b,
+ 0xec83, 0x1f0f,
+ 0xec84, 0x209c,
+ 0xec85, 0x1f11,
+ 0xec86, 0x1f0e,
+ 0xec87, 0x2098,
+ 0xec88, 0x209b,
+ 0xec89, 0x1f12,
+ 0xec8a, 0x2097,
+ 0xec8b, 0x209d,
+ 0xec8d, 0x20a6,
+ 0xec8e, 0x20a5,
+ 0xec8f, 0x20a1,
+ 0xec90, 0x20a4,
+ 0xec95, 0x2084,
+ 0xef92, 0x208d,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12AddRKSJVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12AddRKSJVMap2, 692
+};
+
+static Gushort japan12AddVMap2[1380] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0279,
+ 0x2221, 0x02d7,
+ 0x223a, 0x02e5,
+ 0x224a, 0x02ed,
+ 0x225c, 0x02f4,
+ 0x2272, 0x0303,
+ 0x227e, 0x030b,
+ 0x2330, 0x030c,
+ 0x2341, 0x0316,
+ 0x2361, 0x0330,
+ 0x2421, 0x034a,
+ 0x2474, 0x1f16,
+ 0x2521, 0x039d,
+ 0x2621, 0x03f3,
+ 0x2641, 0x040b,
+ 0x2721, 0x0423,
+ 0x2751, 0x0444,
+ 0x2821, 0x1d37,
+ 0x2822, 0x1d39,
+ 0x2823, 0x1d43,
+ 0x2824, 0x1d47,
+ 0x2825, 0x1d4f,
+ 0x2826, 0x1d4b,
+ 0x2827, 0x1d53,
+ 0x2828, 0x1d63,
+ 0x2829, 0x1d5b,
+ 0x282a, 0x1d6b,
+ 0x282b, 0x1d73,
+ 0x282c, 0x1d38,
+ 0x282d, 0x1d3a,
+ 0x282e, 0x1d46,
+ 0x282f, 0x1d4a,
+ 0x2830, 0x1d52,
+ 0x2831, 0x1d4e,
+ 0x2832, 0x1d5a,
+ 0x2833, 0x1d6a,
+ 0x2834, 0x1d62,
+ 0x2835, 0x1d72,
+ 0x2836, 0x1d82,
+ 0x2837, 0x1d57,
+ 0x2838, 0x1d66,
+ 0x2839, 0x1d5f,
+ 0x283a, 0x1d6e,
+ 0x283b, 0x1d76,
+ 0x283c, 0x1d54,
+ 0x283d, 0x1d67,
+ 0x283e, 0x1d5c,
+ 0x283f, 0x1d6f,
+ 0x2840, 0x1d79,
+ 0x3021, 0x0465,
+ 0x3022, 0x1dd1,
+ 0x3023, 0x0467,
+ 0x3032, 0x1f19,
+ 0x3033, 0x0477,
+ 0x303b, 0x1dd2,
+ 0x303c, 0x0480,
+ 0x306e, 0x1dd3,
+ 0x306f, 0x04b3,
+ 0x3071, 0x1f1a,
+ 0x3072, 0x04b6,
+ 0x3073, 0x1dd4,
+ 0x3074, 0x04b8,
+ 0x307c, 0x1dd5,
+ 0x307d, 0x04c1,
+ 0x3121, 0x04c3,
+ 0x312a, 0x1dd6,
+ 0x312b, 0x04cd,
+ 0x3133, 0x1f1b,
+ 0x3134, 0x04d6,
+ 0x3135, 0x1dd7,
+ 0x3136, 0x04d8,
+ 0x3139, 0x1f1c,
+ 0x313a, 0x04dc,
+ 0x313d, 0x1dda,
+ 0x313e, 0x04e0,
+ 0x3142, 0x1ddb,
+ 0x3143, 0x04e5,
+ 0x316b, 0x1ddc,
+ 0x316c, 0x050e,
+ 0x3221, 0x0521,
+ 0x3228, 0x1ddd,
+ 0x3229, 0x0529,
+ 0x322a, 0x1dde,
+ 0x322b, 0x052b,
+ 0x3260, 0x1ddf,
+ 0x3261, 0x0561,
+ 0x3267, 0x1f1d,
+ 0x3268, 0x0568,
+ 0x327a, 0x1de0,
+ 0x327b, 0x057b,
+ 0x3321, 0x057f,
+ 0x3322, 0x1de2,
+ 0x3323, 0x0581,
+ 0x336b, 0x1de4,
+ 0x336c, 0x05ca,
+ 0x3373, 0x1de5,
+ 0x3374, 0x05d2,
+ 0x337a, 0x1de6,
+ 0x337b, 0x05d9,
+ 0x3421, 0x05dd,
+ 0x3442, 0x1de7,
+ 0x3443, 0x05ff,
+ 0x344d, 0x1de8,
+ 0x344e, 0x060a,
+ 0x3465, 0x1de9,
+ 0x3466, 0x0622,
+ 0x3521, 0x063b,
+ 0x352b, 0x1dea,
+ 0x352c, 0x0646,
+ 0x3540, 0x1deb,
+ 0x3541, 0x065b,
+ 0x3562, 0x1f1e,
+ 0x3563, 0x067d,
+ 0x3568, 0x1f1f,
+ 0x3569, 0x0683,
+ 0x3621, 0x0699,
+ 0x3622, 0x1dec,
+ 0x3623, 0x069b,
+ 0x362a, 0x1ded,
+ 0x362b, 0x06a3,
+ 0x3642, 0x1f20,
+ 0x3643, 0x06bb,
+ 0x364f, 0x1dee,
+ 0x3650, 0x06c8,
+ 0x366d, 0x1def,
+ 0x366e, 0x06e6,
+ 0x3674, 0x1df0,
+ 0x3675, 0x06ed,
+ 0x367b, 0x1df1,
+ 0x367c, 0x06f4,
+ 0x367d, 0x1df2,
+ 0x367e, 0x06f6,
+ 0x3721, 0x06f7,
+ 0x3737, 0x1df4,
+ 0x3738, 0x070e,
+ 0x3752, 0x1df7,
+ 0x3753, 0x0729,
+ 0x3771, 0x1dfa,
+ 0x3772, 0x0748,
+ 0x377d, 0x1f21,
+ 0x377e, 0x1dfc,
+ 0x3821, 0x0755,
+ 0x3834, 0x1dfd,
+ 0x3835, 0x0769,
+ 0x3841, 0x1dfe,
+ 0x3842, 0x0776,
+ 0x3921, 0x07b3,
+ 0x392b, 0x1dff,
+ 0x392c, 0x07be,
+ 0x396d, 0x1e02,
+ 0x396e, 0x0800,
+ 0x3974, 0x1e03,
+ 0x3975, 0x0807,
+ 0x3979, 0x1e04,
+ 0x397a, 0x080c,
+ 0x3a21, 0x0811,
+ 0x3a53, 0x1e05,
+ 0x3a54, 0x0844,
+ 0x3a67, 0x1e06,
+ 0x3a68, 0x0858,
+ 0x3a74, 0x1e07,
+ 0x3a75, 0x0865,
+ 0x3b21, 0x086f,
+ 0x3b27, 0x1e08,
+ 0x3b28, 0x0876,
+ 0x3b2a, 0x1e09,
+ 0x3b2b, 0x0879,
+ 0x3b2c, 0x1e0a,
+ 0x3b2d, 0x087b,
+ 0x3b39, 0x1e0b,
+ 0x3b3a, 0x0888,
+ 0x3b41, 0x1f22,
+ 0x3b42, 0x0890,
+ 0x3c21, 0x08cd,
+ 0x3c48, 0x1e0d,
+ 0x3c49, 0x08f5,
+ 0x3c5d, 0x1e0f,
+ 0x3c5f, 0x090b,
+ 0x3d21, 0x092b,
+ 0x3d2b, 0x1e11,
+ 0x3d2c, 0x0936,
+ 0x3d36, 0x1e12,
+ 0x3d37, 0x0941,
+ 0x3d6c, 0x1e13,
+ 0x3d6d, 0x0977,
+ 0x3d72, 0x1e15,
+ 0x3d74, 0x097e,
+ 0x3e21, 0x0989,
+ 0x3e25, 0x1e17,
+ 0x3e26, 0x098e,
+ 0x3e33, 0x1e18,
+ 0x3e34, 0x099c,
+ 0x3e55, 0x1e1a,
+ 0x3e56, 0x09be,
+ 0x3e5f, 0x1e1b,
+ 0x3e60, 0x09c8,
+ 0x3e64, 0x1e1c,
+ 0x3e65, 0x09cd,
+ 0x3f21, 0x09e7,
+ 0x3f2a, 0x1e1d,
+ 0x3f2b, 0x09f1,
+ 0x3f59, 0x1f23,
+ 0x3f5a, 0x0a20,
+ 0x3f60, 0x1e1f,
+ 0x3f61, 0x0a27,
+ 0x4021, 0x0a45,
+ 0x4022, 0x1e21,
+ 0x4023, 0x0a47,
+ 0x4066, 0x1e23,
+ 0x4067, 0x0a8b,
+ 0x4071, 0x1e24,
+ 0x4072, 0x0a96,
+ 0x4079, 0x1e26,
+ 0x407a, 0x1f24,
+ 0x407b, 0x0a9f,
+ 0x407c, 0x1f25,
+ 0x407e, 0x0aa2,
+ 0x4121, 0x0aa3,
+ 0x4127, 0x1e28,
+ 0x4128, 0x0aaa,
+ 0x4139, 0x1e29,
+ 0x413a, 0x0abc,
+ 0x414c, 0x1e2a,
+ 0x414d, 0x0acf,
+ 0x414f, 0x1e2b,
+ 0x4150, 0x0ad2,
+ 0x415f, 0x1e2c,
+ 0x4160, 0x0ae2,
+ 0x4169, 0x1e2d,
+ 0x416a, 0x0aec,
+ 0x4221, 0x0b01,
+ 0x4237, 0x1f27,
+ 0x4238, 0x0b18,
+ 0x423d, 0x1e2e,
+ 0x423e, 0x0b1e,
+ 0x424d, 0x1e2f,
+ 0x424e, 0x0b2e,
+ 0x425c, 0x1e30,
+ 0x425d, 0x0b3d,
+ 0x4263, 0x1e31,
+ 0x4264, 0x0b44,
+ 0x426f, 0x1e32,
+ 0x4270, 0x0b50,
+ 0x427d, 0x1e35,
+ 0x427e, 0x0b5e,
+ 0x4321, 0x0b5f,
+ 0x4327, 0x1e36,
+ 0x4328, 0x0b66,
+ 0x4329, 0x1e37,
+ 0x432a, 0x0b68,
+ 0x432d, 0x1e39,
+ 0x432f, 0x0b6d,
+ 0x433d, 0x1e3b,
+ 0x433e, 0x0b7c,
+ 0x4370, 0x1e3c,
+ 0x4371, 0x0baf,
+ 0x4375, 0x1e3d,
+ 0x4376, 0x0bb4,
+ 0x437c, 0x1e3e,
+ 0x437d, 0x0bbb,
+ 0x4421, 0x0bbd,
+ 0x443d, 0x1e3f,
+ 0x443e, 0x0bda,
+ 0x4448, 0x1e40,
+ 0x4449, 0x0be5,
+ 0x444a, 0x1e41,
+ 0x444b, 0x0be7,
+ 0x444f, 0x1e43,
+ 0x4450, 0x0bec,
+ 0x4521, 0x0c1b,
+ 0x4522, 0x1e44,
+ 0x4523, 0x0c1d,
+ 0x4527, 0x1e45,
+ 0x4528, 0x0c22,
+ 0x452e, 0x1e46,
+ 0x452f, 0x0c29,
+ 0x4536, 0x1e47,
+ 0x4537, 0x0c31,
+ 0x453f, 0x1e48,
+ 0x4540, 0x0c3a,
+ 0x4548, 0x1e49,
+ 0x4549, 0x0c43,
+ 0x454b, 0x1e4a,
+ 0x454c, 0x0c46,
+ 0x4551, 0x1f28,
+ 0x4552, 0x1e4c,
+ 0x4553, 0x0c4d,
+ 0x4564, 0x1e4d,
+ 0x4565, 0x0c5f,
+ 0x4578, 0x1e4e,
+ 0x4579, 0x0c73,
+ 0x4621, 0x0c79,
+ 0x4642, 0x1e50,
+ 0x4643, 0x0c9b,
+ 0x4654, 0x1e51,
+ 0x4655, 0x0cad,
+ 0x465b, 0x1e53,
+ 0x465c, 0x0cb4,
+ 0x4666, 0x1e56,
+ 0x4668, 0x0cc0,
+ 0x466a, 0x1e58,
+ 0x466b, 0x0cc3,
+ 0x4676, 0x1ec0,
+ 0x4677, 0x0ccf,
+ 0x4721, 0x0cd7,
+ 0x4729, 0x1e59,
+ 0x472a, 0x1f29,
+ 0x472b, 0x0ce1,
+ 0x4739, 0x1e5a,
+ 0x473a, 0x0cf0,
+ 0x4757, 0x1e5b,
+ 0x4758, 0x0d0e,
+ 0x4767, 0x1e5c,
+ 0x4768, 0x0d1e,
+ 0x4769, 0x1e5d,
+ 0x476a, 0x0d20,
+ 0x476d, 0x1e5e,
+ 0x476e, 0x0d24,
+ 0x4821, 0x0d35,
+ 0x4824, 0x1e5f,
+ 0x4825, 0x0d39,
+ 0x482e, 0x1e60,
+ 0x482f, 0x0d43,
+ 0x4830, 0x1e61,
+ 0x4831, 0x0d45,
+ 0x4840, 0x1f2a,
+ 0x4841, 0x0d55,
+ 0x4854, 0x1e62,
+ 0x4855, 0x0d69,
+ 0x4875, 0x1e64,
+ 0x4876, 0x0d8a,
+ 0x4921, 0x0d93,
+ 0x4922, 0x1e65,
+ 0x4924, 0x0d96,
+ 0x492f, 0x1e67,
+ 0x4930, 0x0da2,
+ 0x4932, 0x1e68,
+ 0x4933, 0x0da5,
+ 0x4935, 0x1e69,
+ 0x4936, 0x0da8,
+ 0x4940, 0x1e6a,
+ 0x4941, 0x0db3,
+ 0x494e, 0x1e6b,
+ 0x494f, 0x0dc1,
+ 0x4a21, 0x0df1,
+ 0x4a43, 0x1e6d,
+ 0x4a44, 0x0e14,
+ 0x4a4d, 0x1e6e,
+ 0x4a4e, 0x0e1e,
+ 0x4a53, 0x1f2b,
+ 0x4a54, 0x0e24,
+ 0x4a5a, 0x1e6f,
+ 0x4a5b, 0x0e2b,
+ 0x4a79, 0x1e70,
+ 0x4a7a, 0x0e4a,
+ 0x4b21, 0x0e4f,
+ 0x4b29, 0x1e72,
+ 0x4b2a, 0x0e58,
+ 0x4b4b, 0x1e73,
+ 0x4b4c, 0x0e7a,
+ 0x4b70, 0x1e74,
+ 0x4b71, 0x0e9f,
+ 0x4b78, 0x1f2c,
+ 0x4b79, 0x0ea7,
+ 0x4c21, 0x0ead,
+ 0x4c4d, 0x1e75,
+ 0x4c4e, 0x0eda,
+ 0x4c59, 0x1e76,
+ 0x4c5a, 0x0ee6,
+ 0x4c5f, 0x1e77,
+ 0x4c60, 0x0eec,
+ 0x4c62, 0x1e78,
+ 0x4c63, 0x0eef,
+ 0x4c7a, 0x1e79,
+ 0x4c7b, 0x0f07,
+ 0x4c7c, 0x1e7a,
+ 0x4c7d, 0x0f09,
+ 0x4d21, 0x0f0b,
+ 0x4d32, 0x1e7c,
+ 0x4d33, 0x0f1d,
+ 0x4d50, 0x1e7d,
+ 0x4d51, 0x0f3b,
+ 0x4d54, 0x1e7e,
+ 0x4d55, 0x0f3f,
+ 0x4d69, 0x1e7f,
+ 0x4d6a, 0x0f54,
+ 0x4e21, 0x0f69,
+ 0x4e7a, 0x1e81,
+ 0x4e7c, 0x1f2d,
+ 0x4e7d, 0x0fc5,
+ 0x4f21, 0x1e83,
+ 0x4f22, 0x0fc8,
+ 0x4f31, 0x1e84,
+ 0x4f32, 0x0fd8,
+ 0x4f39, 0x1e85,
+ 0x4f3a, 0x0fe0,
+ 0x5021, 0x0ffa,
+ 0x5121, 0x1058,
+ 0x5122, 0x1f2e,
+ 0x5123, 0x105a,
+ 0x513d, 0x1e86,
+ 0x513e, 0x1075,
+ 0x514d, 0x1e89,
+ 0x514e, 0x1085,
+ 0x5221, 0x10b6,
+ 0x5238, 0x1f2f,
+ 0x5239, 0x10ce,
+ 0x5321, 0x1114,
+ 0x5330, 0x1e8a,
+ 0x5331, 0x1124,
+ 0x533a, 0x1e8b,
+ 0x533b, 0x112e,
+ 0x5348, 0x1f30,
+ 0x5349, 0x113c,
+ 0x535e, 0x1e8d,
+ 0x535f, 0x1152,
+ 0x536b, 0x1e8e,
+ 0x536c, 0x1f31,
+ 0x536d, 0x1160,
+ 0x5421, 0x1172,
+ 0x5444, 0x1e8f,
+ 0x5445, 0x1f32,
+ 0x5446, 0x1197,
+ 0x546c, 0x1f33,
+ 0x546d, 0x11be,
+ 0x5521, 0x11d0,
+ 0x553d, 0x1e90,
+ 0x553e, 0x11ed,
+ 0x5563, 0x1e91,
+ 0x5564, 0x1213,
+ 0x5578, 0x1f34,
+ 0x5579, 0x1228,
+ 0x5621, 0x122e,
+ 0x5622, 0x1e92,
+ 0x5623, 0x1230,
+ 0x567d, 0x1f35,
+ 0x5721, 0x128c,
+ 0x5821, 0x12ea,
+ 0x5824, 0x1e94,
+ 0x5825, 0x12ee,
+ 0x5921, 0x1348,
+ 0x5928, 0x1f37,
+ 0x5929, 0x1350,
+ 0x5960, 0x1e95,
+ 0x5961, 0x1388,
+ 0x596c, 0x1e96,
+ 0x596d, 0x1394,
+ 0x5a21, 0x13a6,
+ 0x5a39, 0x1e97,
+ 0x5a3a, 0x13bf,
+ 0x5a7a, 0x1f38,
+ 0x5a7b, 0x1400,
+ 0x5b21, 0x1404,
+ 0x5b45, 0x1e99,
+ 0x5b46, 0x1429,
+ 0x5b6b, 0x1e9b,
+ 0x5b6c, 0x144f,
+ 0x5c21, 0x1462,
+ 0x5d21, 0x14c0,
+ 0x5d61, 0x1f39,
+ 0x5d62, 0x1501,
+ 0x5e21, 0x151e,
+ 0x5e50, 0x1e9d,
+ 0x5e51, 0x154e,
+ 0x5e56, 0x1f3a,
+ 0x5e57, 0x1554,
+ 0x5e76, 0x1f3b,
+ 0x5e77, 0x1574,
+ 0x5f21, 0x157c,
+ 0x5f73, 0x1e9e,
+ 0x5f74, 0x15cf,
+ 0x6021, 0x15da,
+ 0x6026, 0x1e9f,
+ 0x6027, 0x15e0,
+ 0x605f, 0x1ea0,
+ 0x6060, 0x1619,
+ 0x6121, 0x1638,
+ 0x612b, 0x1ea1,
+ 0x612c, 0x1643,
+ 0x6221, 0x1696,
+ 0x626f, 0x1ea5,
+ 0x6270, 0x16e5,
+ 0x6321, 0x16f4,
+ 0x634a, 0x1ea6,
+ 0x634b, 0x171e,
+ 0x6354, 0x1ea7,
+ 0x6355, 0x1728,
+ 0x6359, 0x1f3c,
+ 0x635a, 0x172d,
+ 0x6421, 0x1752,
+ 0x6439, 0x1ea8,
+ 0x643a, 0x176b,
+ 0x6440, 0x1f3d,
+ 0x6441, 0x1772,
+ 0x6464, 0x1ea9,
+ 0x6465, 0x1796,
+ 0x646e, 0x1eaa,
+ 0x646f, 0x17a0,
+ 0x6521, 0x17b0,
+ 0x6539, 0x1eab,
+ 0x653a, 0x17c9,
+ 0x653b, 0x1eac,
+ 0x653c, 0x17cb,
+ 0x6546, 0x1ead,
+ 0x6547, 0x17d6,
+ 0x6621, 0x180e,
+ 0x6649, 0x1f3e,
+ 0x664a, 0x1837,
+ 0x6721, 0x186c,
+ 0x6764, 0x1eaf,
+ 0x6765, 0x18b0,
+ 0x6769, 0x1eb0,
+ 0x676a, 0x18b5,
+ 0x6772, 0x1eb1,
+ 0x6773, 0x18be,
+ 0x6821, 0x18ca,
+ 0x683b, 0x1eb3,
+ 0x683c, 0x18e5,
+ 0x684d, 0x1f3f,
+ 0x684e, 0x18f7,
+ 0x6921, 0x1928,
+ 0x697e, 0x1f40,
+ 0x6a21, 0x1986,
+ 0x6a3c, 0x1f41,
+ 0x6a3e, 0x19a3,
+ 0x6a6f, 0x1eb8,
+ 0x6a70, 0x19d5,
+ 0x6b21, 0x19e4,
+ 0x6b32, 0x1eb9,
+ 0x6b33, 0x19f6,
+ 0x6b66, 0x1eba,
+ 0x6b67, 0x1a2a,
+ 0x6c21, 0x1a42,
+ 0x6c69, 0x1ebc,
+ 0x6c6a, 0x1a8b,
+ 0x6d21, 0x1aa0,
+ 0x6d4e, 0x1ebe,
+ 0x6d4f, 0x1ace,
+ 0x6e21, 0x1afe,
+ 0x6e29, 0x1ec1,
+ 0x6e2a, 0x1b07,
+ 0x6e3d, 0x1ec2,
+ 0x6e3e, 0x1b1b,
+ 0x6f21, 0x1b5c,
+ 0x7021, 0x1bba,
+ 0x7051, 0x1ec7,
+ 0x7052, 0x1beb,
+ 0x7121, 0x1c18,
+ 0x7159, 0x1f43,
+ 0x715a, 0x1c51,
+ 0x7221, 0x1c76,
+ 0x722d, 0x1eca,
+ 0x722e, 0x1c83,
+ 0x723c, 0x1ecb,
+ 0x723d, 0x1c92,
+ 0x724e, 0x1ecc,
+ 0x724f, 0x1ca4,
+ 0x7321, 0x1cd4,
+ 0x7351, 0x1ecd,
+ 0x7352, 0x1f44,
+ 0x7353, 0x1d06,
+ 0x737d, 0x1ece,
+ 0x737e, 0x1d31,
+ 0x7421, 0x1d32,
+ 0x7425, 0x205c,
+ 0x7721, 0x1f45,
+ 0x7727, 0x1f48,
+ 0x7728, 0x0300,
+ 0x7729, 0x02fa,
+ 0x772a, 0x02f9,
+ 0x772e, 0x1f49,
+ 0x773c, 0x1db1,
+ 0x773f, 0x1f54,
+ 0x7740, 0x1db7,
+ 0x7741, 0x1f55,
+ 0x7744, 0x1db4,
+ 0x7747, 0x1f58,
+ 0x7751, 0x0303,
+ 0x7752, 0x1f62,
+ 0x7753, 0x0304,
+ 0x7754, 0x1f63,
+ 0x7757, 0x1f65,
+ 0x7759, 0x1da4,
+ 0x775a, 0x1da1,
+ 0x775b, 0x1f66,
+ 0x775c, 0x1da2,
+ 0x775d, 0x1f67,
+ 0x7760, 0x1da6,
+ 0x7761, 0x1f6a,
+ 0x7762, 0x1da8,
+ 0x7763, 0x1dac,
+ 0x7764, 0x1f6b,
+ 0x7765, 0x1dae,
+ 0x7766, 0x1dab,
+ 0x7767, 0x1f6c,
+ 0x7769, 0x1daf,
+ 0x776a, 0x1f6e,
+ 0x7774, 0x1f75,
+ 0x777a, 0x1dba,
+ 0x777b, 0x1f7b,
+ 0x777e, 0x1f7c,
+ 0x7829, 0x1f7d,
+ 0x7834, 0x1f87,
+ 0x7849, 0x1d83,
+ 0x785d, 0x1f9b,
+ 0x785e, 0x1d97,
+ 0x786b, 0x1f9c,
+ 0x7921, 0x1fb0,
+ 0x7945, 0x1f16,
+ 0x7949, 0x1fca,
+ 0x794b, 0x1dc4,
+ 0x794c, 0x1fcc,
+ 0x794f, 0x1dc3,
+ 0x7950, 0x1fcf,
+ 0x7955, 0x1dc2,
+ 0x7956, 0x1fd4,
+ 0x795d, 0x1fd8,
+ 0x796f, 0x1fe6,
+ 0x7d21, 0x1ecf,
+ 0x7d23, 0x204c,
+ 0x7d24, 0x2052,
+ 0x7d25, 0x1ed1,
+ 0x7d2f, 0x205a,
+ 0x7d30, 0x2053,
+ 0x7d31, 0x2058,
+ 0x7d32, 0x2055,
+ 0x7d33, 0x1edb,
+ 0x7d45, 0x1eee,
+ 0x7d5b, 0x2048,
+ 0x7d6d, 0x02e0,
+ 0x7d71, 0x1ff6,
+ 0x2122, 0x1ecf,
+ 0x2124, 0x204c,
+ 0x2125, 0x2052,
+ 0x2131, 0x1ed1,
+ 0x213c, 0x1ed3,
+ 0x2141, 0x1ed6,
+ 0x2146, 0x205a,
+ 0x2147, 0x2053,
+ 0x2148, 0x2058,
+ 0x2149, 0x2055,
+ 0x214a, 0x1edb,
+ 0x2421, 0x1eee,
+ 0x2423, 0x1eef,
+ 0x2425, 0x1ef0,
+ 0x2427, 0x1ef1,
+ 0x2429, 0x1ef2,
+ 0x2443, 0x1ef3,
+ 0x2463, 0x1ef4,
+ 0x2465, 0x1ef5,
+ 0x2467, 0x1ef6,
+ 0x246e, 0x1ef7,
+ 0x2475, 0x2048,
+ 0x2521, 0x1ef8,
+ 0x2523, 0x1ef9,
+ 0x2525, 0x1efa,
+ 0x2527, 0x1efb,
+ 0x2529, 0x1efc,
+ 0x2543, 0x1efd,
+ 0x2563, 0x1efe,
+ 0x2565, 0x1eff,
+ 0x2567, 0x1f00,
+ 0x256e, 0x1f01,
+ 0x2575, 0x1f02,
+ 0x7759, 0x1f07,
+ 0x775a, 0x1f04,
+ 0x775b, 0x2089,
+ 0x775c, 0x1f05,
+ 0x775d, 0x208a,
+ 0x775e, 0x2093,
+ 0x7760, 0x1f09,
+ 0x7761, 0x2092,
+ 0x7762, 0x1f0b,
+ 0x7763, 0x1f0f,
+ 0x7764, 0x209c,
+ 0x7765, 0x1f11,
+ 0x7766, 0x1f0e,
+ 0x7767, 0x2098,
+ 0x7768, 0x209b,
+ 0x7769, 0x1f12,
+ 0x776a, 0x2097,
+ 0x776b, 0x209d,
+ 0x776d, 0x20a6,
+ 0x776e, 0x20a5,
+ 0x776f, 0x20a1,
+ 0x7770, 0x20a4,
+ 0x7775, 0x2084,
+ 0x7d72, 0x208d,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12AddVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12AddVMap2, 690
+};
+
+static Gushort japan12AdobeJapan10Map2[70] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12AdobeJapan10Enc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12AdobeJapan10Map2, 35
+};
+
+static Gushort japan12AdobeJapan11Map2[70] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12AdobeJapan11Enc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12AdobeJapan11Map2, 35
+};
+
+static Gushort japan12AdobeJapan12Map2[74] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0x2100, 0x2100,
+ 0x2200, 0x2200,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12AdobeJapan12Enc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12AdobeJapan12Map2, 37
+};
+
+static Gushort japan12EUCHMap2[242] = {
+ 0x0000, 0x0000,
+ 0x8ea0, 0x0146,
+ 0xa1a1, 0x0279,
+ 0xa2a1, 0x02d7,
+ 0xa2ba, 0x02e5,
+ 0xa2ca, 0x02ed,
+ 0xa2dc, 0x02f4,
+ 0xa2f2, 0x0303,
+ 0xa2fe, 0x030b,
+ 0xa3b0, 0x030c,
+ 0xa3c1, 0x0316,
+ 0xa3e1, 0x0330,
+ 0xa4a1, 0x034a,
+ 0xa5a1, 0x039d,
+ 0xa6a1, 0x03f3,
+ 0xa6c1, 0x040b,
+ 0xa7a1, 0x0423,
+ 0xa7d1, 0x0444,
+ 0xa8a1, 0x1d37,
+ 0xa8a2, 0x1d39,
+ 0xa8a3, 0x1d43,
+ 0xa8a4, 0x1d47,
+ 0xa8a5, 0x1d4f,
+ 0xa8a6, 0x1d4b,
+ 0xa8a7, 0x1d53,
+ 0xa8a8, 0x1d63,
+ 0xa8a9, 0x1d5b,
+ 0xa8aa, 0x1d6b,
+ 0xa8ab, 0x1d73,
+ 0xa8ac, 0x1d38,
+ 0xa8ad, 0x1d3a,
+ 0xa8ae, 0x1d46,
+ 0xa8af, 0x1d4a,
+ 0xa8b0, 0x1d52,
+ 0xa8b1, 0x1d4e,
+ 0xa8b2, 0x1d5a,
+ 0xa8b3, 0x1d6a,
+ 0xa8b4, 0x1d62,
+ 0xa8b5, 0x1d72,
+ 0xa8b6, 0x1d82,
+ 0xa8b7, 0x1d57,
+ 0xa8b8, 0x1d66,
+ 0xa8b9, 0x1d5f,
+ 0xa8ba, 0x1d6e,
+ 0xa8bb, 0x1d76,
+ 0xa8bc, 0x1d54,
+ 0xa8bd, 0x1d67,
+ 0xa8be, 0x1d5c,
+ 0xa8bf, 0x1d6f,
+ 0xa8c0, 0x1d79,
+ 0xb0a1, 0x0465,
+ 0xb1a1, 0x04c3,
+ 0xb2a1, 0x0521,
+ 0xb3a1, 0x057f,
+ 0xb4a1, 0x05dd,
+ 0xb5a1, 0x063b,
+ 0xb6a1, 0x0699,
+ 0xb7a1, 0x06f7,
+ 0xb8a1, 0x0755,
+ 0xb9a1, 0x07b3,
+ 0xbaa1, 0x0811,
+ 0xbba1, 0x086f,
+ 0xbca1, 0x08cd,
+ 0xbda1, 0x092b,
+ 0xbea1, 0x0989,
+ 0xbfa1, 0x09e7,
+ 0xc0a1, 0x0a45,
+ 0xc1a1, 0x0aa3,
+ 0xc2a1, 0x0b01,
+ 0xc3a1, 0x0b5f,
+ 0xc4a1, 0x0bbd,
+ 0xc5a1, 0x0c1b,
+ 0xc6a1, 0x0c79,
+ 0xc7a1, 0x0cd7,
+ 0xc8a1, 0x0d35,
+ 0xc9a1, 0x0d93,
+ 0xcaa1, 0x0df1,
+ 0xcba1, 0x0e4f,
+ 0xcca1, 0x0ead,
+ 0xcda1, 0x0f0b,
+ 0xcea1, 0x0f69,
+ 0xcfa1, 0x0fc7,
+ 0xd0a1, 0x0ffa,
+ 0xd1a1, 0x1058,
+ 0xd2a1, 0x10b6,
+ 0xd3a1, 0x1114,
+ 0xd4a1, 0x1172,
+ 0xd5a1, 0x11d0,
+ 0xd6a1, 0x122e,
+ 0xd7a1, 0x128c,
+ 0xd8a1, 0x12ea,
+ 0xd9a1, 0x1348,
+ 0xdaa1, 0x13a6,
+ 0xdba1, 0x1404,
+ 0xdca1, 0x1462,
+ 0xdda1, 0x14c0,
+ 0xdea1, 0x151e,
+ 0xdfa1, 0x157c,
+ 0xe0a1, 0x15da,
+ 0xe1a1, 0x1638,
+ 0xe2a1, 0x1696,
+ 0xe3a1, 0x16f4,
+ 0xe4a1, 0x1752,
+ 0xe5a1, 0x17b0,
+ 0xe6a1, 0x180e,
+ 0xe7a1, 0x186c,
+ 0xe8a1, 0x18ca,
+ 0xe9a1, 0x1928,
+ 0xeaa1, 0x1986,
+ 0xeba1, 0x19e4,
+ 0xeca1, 0x1a42,
+ 0xeda1, 0x1aa0,
+ 0xeea1, 0x1afe,
+ 0xefa1, 0x1b5c,
+ 0xf0a1, 0x1bba,
+ 0xf1a1, 0x1c18,
+ 0xf2a1, 0x1c76,
+ 0xf3a1, 0x1cd4,
+ 0xf4a1, 0x1d32,
+ 0xf4a5, 0x205c,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12EUCHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12EUCHMap2, 121
+};
+
+static Gushort japan12EUCVMap2[296] = {
+ 0x0000, 0x0000,
+ 0x8ea0, 0x0146,
+ 0xa1a1, 0x0279,
+ 0xa2a1, 0x02d7,
+ 0xa2ba, 0x02e5,
+ 0xa2ca, 0x02ed,
+ 0xa2dc, 0x02f4,
+ 0xa2f2, 0x0303,
+ 0xa2fe, 0x030b,
+ 0xa3b0, 0x030c,
+ 0xa3c1, 0x0316,
+ 0xa3e1, 0x0330,
+ 0xa4a1, 0x034a,
+ 0xa5a1, 0x039d,
+ 0xa6a1, 0x03f3,
+ 0xa6c1, 0x040b,
+ 0xa7a1, 0x0423,
+ 0xa7d1, 0x0444,
+ 0xa8a1, 0x1d37,
+ 0xa8a2, 0x1d39,
+ 0xa8a3, 0x1d43,
+ 0xa8a4, 0x1d47,
+ 0xa8a5, 0x1d4f,
+ 0xa8a6, 0x1d4b,
+ 0xa8a7, 0x1d53,
+ 0xa8a8, 0x1d63,
+ 0xa8a9, 0x1d5b,
+ 0xa8aa, 0x1d6b,
+ 0xa8ab, 0x1d73,
+ 0xa8ac, 0x1d38,
+ 0xa8ad, 0x1d3a,
+ 0xa8ae, 0x1d46,
+ 0xa8af, 0x1d4a,
+ 0xa8b0, 0x1d52,
+ 0xa8b1, 0x1d4e,
+ 0xa8b2, 0x1d5a,
+ 0xa8b3, 0x1d6a,
+ 0xa8b4, 0x1d62,
+ 0xa8b5, 0x1d72,
+ 0xa8b6, 0x1d82,
+ 0xa8b7, 0x1d57,
+ 0xa8b8, 0x1d66,
+ 0xa8b9, 0x1d5f,
+ 0xa8ba, 0x1d6e,
+ 0xa8bb, 0x1d76,
+ 0xa8bc, 0x1d54,
+ 0xa8bd, 0x1d67,
+ 0xa8be, 0x1d5c,
+ 0xa8bf, 0x1d6f,
+ 0xa8c0, 0x1d79,
+ 0xb0a1, 0x0465,
+ 0xb1a1, 0x04c3,
+ 0xb2a1, 0x0521,
+ 0xb3a1, 0x057f,
+ 0xb4a1, 0x05dd,
+ 0xb5a1, 0x063b,
+ 0xb6a1, 0x0699,
+ 0xb7a1, 0x06f7,
+ 0xb8a1, 0x0755,
+ 0xb9a1, 0x07b3,
+ 0xbaa1, 0x0811,
+ 0xbba1, 0x086f,
+ 0xbca1, 0x08cd,
+ 0xbda1, 0x092b,
+ 0xbea1, 0x0989,
+ 0xbfa1, 0x09e7,
+ 0xc0a1, 0x0a45,
+ 0xc1a1, 0x0aa3,
+ 0xc2a1, 0x0b01,
+ 0xc3a1, 0x0b5f,
+ 0xc4a1, 0x0bbd,
+ 0xc5a1, 0x0c1b,
+ 0xc6a1, 0x0c79,
+ 0xc7a1, 0x0cd7,
+ 0xc8a1, 0x0d35,
+ 0xc9a1, 0x0d93,
+ 0xcaa1, 0x0df1,
+ 0xcba1, 0x0e4f,
+ 0xcca1, 0x0ead,
+ 0xcda1, 0x0f0b,
+ 0xcea1, 0x0f69,
+ 0xcfa1, 0x0fc7,
+ 0xd0a1, 0x0ffa,
+ 0xd1a1, 0x1058,
+ 0xd2a1, 0x10b6,
+ 0xd3a1, 0x1114,
+ 0xd4a1, 0x1172,
+ 0xd5a1, 0x11d0,
+ 0xd6a1, 0x122e,
+ 0xd7a1, 0x128c,
+ 0xd8a1, 0x12ea,
+ 0xd9a1, 0x1348,
+ 0xdaa1, 0x13a6,
+ 0xdba1, 0x1404,
+ 0xdca1, 0x1462,
+ 0xdda1, 0x14c0,
+ 0xdea1, 0x151e,
+ 0xdfa1, 0x157c,
+ 0xe0a1, 0x15da,
+ 0xe1a1, 0x1638,
+ 0xe2a1, 0x1696,
+ 0xe3a1, 0x16f4,
+ 0xe4a1, 0x1752,
+ 0xe5a1, 0x17b0,
+ 0xe6a1, 0x180e,
+ 0xe7a1, 0x186c,
+ 0xe8a1, 0x18ca,
+ 0xe9a1, 0x1928,
+ 0xeaa1, 0x1986,
+ 0xeba1, 0x19e4,
+ 0xeca1, 0x1a42,
+ 0xeda1, 0x1aa0,
+ 0xeea1, 0x1afe,
+ 0xefa1, 0x1b5c,
+ 0xf0a1, 0x1bba,
+ 0xf1a1, 0x1c18,
+ 0xf2a1, 0x1c76,
+ 0xf3a1, 0x1cd4,
+ 0xf4a1, 0x1d32,
+ 0xf4a5, 0x205c,
+ 0xa1a2, 0x1ecf,
+ 0xa1b1, 0x1ed1,
+ 0xa1bc, 0x1ed3,
+ 0xa1c1, 0x1ed6,
+ 0xa1ca, 0x1edb,
+ 0xa1e1, 0x1eed,
+ 0xa4a1, 0x1eee,
+ 0xa4a3, 0x1eef,
+ 0xa4a5, 0x1ef0,
+ 0xa4a7, 0x1ef1,
+ 0xa4a9, 0x1ef2,
+ 0xa4c3, 0x1ef3,
+ 0xa4e3, 0x1ef4,
+ 0xa4e5, 0x1ef5,
+ 0xa4e7, 0x1ef6,
+ 0xa4ee, 0x1ef7,
+ 0xa5a1, 0x1ef8,
+ 0xa5a3, 0x1ef9,
+ 0xa5a5, 0x1efa,
+ 0xa5a7, 0x1efb,
+ 0xa5a9, 0x1efc,
+ 0xa5c3, 0x1efd,
+ 0xa5e3, 0x1efe,
+ 0xa5e5, 0x1eff,
+ 0xa5e7, 0x1f00,
+ 0xa5ee, 0x1f01,
+ 0xa5f5, 0x1f02,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12EUCVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12EUCVMap2, 148
+};
+
+static Gushort japan12ExtHMap2[1326] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0279,
+ 0x2169, 0x1d36,
+ 0x216a, 0x02c2,
+ 0x2221, 0x02d7,
+ 0x2330, 0x030c,
+ 0x2341, 0x0316,
+ 0x2361, 0x0330,
+ 0x2421, 0x034a,
+ 0x2521, 0x039d,
+ 0x2621, 0x03f3,
+ 0x2641, 0x040b,
+ 0x2721, 0x0423,
+ 0x2751, 0x0444,
+ 0x2921, 0x00e8,
+ 0x2960, 0x0186,
+ 0x2961, 0x0128,
+ 0x2a21, 0x0147,
+ 0x2a60, 0x0187,
+ 0x2b21, 0x01a6,
+ 0x2b72, 0x0127,
+ 0x2b73, 0x01f7,
+ 0x2c24, 0x1d37,
+ 0x2d21, 0x1d83,
+ 0x2d40, 0x1da1,
+ 0x2d5f, 0x2083,
+ 0x2d60, 0x1db8,
+ 0x2d70, 0x02fa,
+ 0x2d71, 0x02f9,
+ 0x2d72, 0x0301,
+ 0x2d73, 0x1dc8,
+ 0x2d7a, 0x0300,
+ 0x2d7b, 0x1dcf,
+ 0x3021, 0x0465,
+ 0x3022, 0x1dd1,
+ 0x3023, 0x0467,
+ 0x3033, 0x1ca2,
+ 0x3034, 0x0478,
+ 0x303b, 0x1dd2,
+ 0x303c, 0x0480,
+ 0x306e, 0x1dd3,
+ 0x306f, 0x04b3,
+ 0x3073, 0x1dd4,
+ 0x3074, 0x04b8,
+ 0x307c, 0x1dd5,
+ 0x307d, 0x04c1,
+ 0x3121, 0x04c3,
+ 0x312a, 0x1dd6,
+ 0x312b, 0x04cd,
+ 0x3135, 0x1dd7,
+ 0x3136, 0x04d8,
+ 0x3139, 0x1dd8,
+ 0x313a, 0x04dc,
+ 0x313c, 0x1dd9,
+ 0x313e, 0x04e0,
+ 0x3142, 0x1ddb,
+ 0x3143, 0x04e5,
+ 0x316b, 0x1ddc,
+ 0x316c, 0x050e,
+ 0x3221, 0x0521,
+ 0x3228, 0x1ddd,
+ 0x3229, 0x1cc9,
+ 0x322a, 0x1dde,
+ 0x322b, 0x052b,
+ 0x3260, 0x1ddf,
+ 0x3261, 0x0561,
+ 0x327a, 0x1de0,
+ 0x327b, 0x057b,
+ 0x327d, 0x1de1,
+ 0x327e, 0x057e,
+ 0x3321, 0x057f,
+ 0x3322, 0x1de2,
+ 0x3323, 0x0581,
+ 0x3342, 0x1961,
+ 0x3343, 0x05a1,
+ 0x3349, 0x139f,
+ 0x334a, 0x05a8,
+ 0x3365, 0x1de3,
+ 0x3366, 0x05c4,
+ 0x336b, 0x1de4,
+ 0x336c, 0x05ca,
+ 0x3373, 0x1de5,
+ 0x3374, 0x05d2,
+ 0x3376, 0x1731,
+ 0x3377, 0x05d5,
+ 0x337a, 0x1de6,
+ 0x337b, 0x05d9,
+ 0x3421, 0x05dd,
+ 0x3442, 0x1de7,
+ 0x3443, 0x1572,
+ 0x3444, 0x0600,
+ 0x344d, 0x1de8,
+ 0x344e, 0x060a,
+ 0x3452, 0x1a20,
+ 0x3453, 0x060f,
+ 0x3465, 0x1de9,
+ 0x3466, 0x0622,
+ 0x3521, 0x063b,
+ 0x352b, 0x1dea,
+ 0x352c, 0x0646,
+ 0x3540, 0x1deb,
+ 0x3541, 0x065b,
+ 0x3621, 0x0699,
+ 0x3622, 0x1dec,
+ 0x3623, 0x069b,
+ 0x362a, 0x1ded,
+ 0x362b, 0x06a3,
+ 0x3646, 0x1d32,
+ 0x3647, 0x06bf,
+ 0x364f, 0x1dee,
+ 0x3650, 0x06c8,
+ 0x366d, 0x1def,
+ 0x366e, 0x06e6,
+ 0x3674, 0x1df0,
+ 0x3675, 0x06ed,
+ 0x367b, 0x1df1,
+ 0x367c, 0x06f4,
+ 0x367d, 0x1df2,
+ 0x367e, 0x06f6,
+ 0x3721, 0x06f7,
+ 0x3724, 0x1df3,
+ 0x3725, 0x06fb,
+ 0x3737, 0x1df4,
+ 0x3738, 0x070e,
+ 0x3745, 0x1df5,
+ 0x3746, 0x071c,
+ 0x374e, 0x1df6,
+ 0x374f, 0x0725,
+ 0x3752, 0x1df7,
+ 0x3753, 0x0729,
+ 0x3755, 0x1df8,
+ 0x3756, 0x072c,
+ 0x375b, 0x1c0d,
+ 0x375c, 0x0732,
+ 0x3764, 0x1df9,
+ 0x3765, 0x073b,
+ 0x3771, 0x1dfa,
+ 0x3772, 0x0748,
+ 0x3779, 0x1dfb,
+ 0x377a, 0x0750,
+ 0x377e, 0x1dfc,
+ 0x3821, 0x0755,
+ 0x3834, 0x1dfd,
+ 0x3835, 0x0769,
+ 0x3841, 0x1dfe,
+ 0x3842, 0x0776,
+ 0x3921, 0x07b3,
+ 0x392b, 0x1dff,
+ 0x392c, 0x07be,
+ 0x3937, 0x1e00,
+ 0x3938, 0x07ca,
+ 0x3942, 0x1e01,
+ 0x3943, 0x07d5,
+ 0x395c, 0x16dd,
+ 0x395d, 0x07ef,
+ 0x396d, 0x1e02,
+ 0x396e, 0x0800,
+ 0x3974, 0x1e03,
+ 0x3975, 0x0807,
+ 0x3979, 0x1e04,
+ 0x397a, 0x080c,
+ 0x3a21, 0x0811,
+ 0x3a53, 0x1e05,
+ 0x3a54, 0x0844,
+ 0x3a67, 0x1e06,
+ 0x3a68, 0x0858,
+ 0x3a74, 0x1e07,
+ 0x3a75, 0x0865,
+ 0x3b21, 0x086f,
+ 0x3b27, 0x1e08,
+ 0x3b28, 0x0876,
+ 0x3b2a, 0x1e09,
+ 0x3b2b, 0x0879,
+ 0x3b2c, 0x1e0a,
+ 0x3b2d, 0x087b,
+ 0x3b39, 0x1e0b,
+ 0x3b3a, 0x0888,
+ 0x3c21, 0x08cd,
+ 0x3c38, 0x1e0c,
+ 0x3c39, 0x08e5,
+ 0x3c48, 0x1e0d,
+ 0x3c49, 0x1929,
+ 0x3c4a, 0x08f6,
+ 0x3c57, 0x1e0e,
+ 0x3c58, 0x0904,
+ 0x3c5d, 0x1e0f,
+ 0x3c5f, 0x090b,
+ 0x3d21, 0x092b,
+ 0x3d2b, 0x1e11,
+ 0x3d2c, 0x0936,
+ 0x3d36, 0x1e12,
+ 0x3d37, 0x0941,
+ 0x3d6c, 0x1e13,
+ 0x3d6e, 0x0978,
+ 0x3d72, 0x1e15,
+ 0x3d74, 0x097e,
+ 0x3e21, 0x0989,
+ 0x3e25, 0x1e17,
+ 0x3e26, 0x098e,
+ 0x3e33, 0x1e18,
+ 0x3e34, 0x099c,
+ 0x3e3f, 0x1e19,
+ 0x3e40, 0x09a8,
+ 0x3e55, 0x1e1a,
+ 0x3e56, 0x09be,
+ 0x3e5f, 0x1e1b,
+ 0x3e60, 0x09c8,
+ 0x3e64, 0x1e1c,
+ 0x3e65, 0x09cd,
+ 0x3f21, 0x09e7,
+ 0x3f2a, 0x1e1d,
+ 0x3f2b, 0x09f1,
+ 0x3f59, 0x1e1e,
+ 0x3f5a, 0x0a20,
+ 0x3f60, 0x1e1f,
+ 0x3f61, 0x0a27,
+ 0x3f69, 0x1e20,
+ 0x3f6a, 0x0a30,
+ 0x4021, 0x0a45,
+ 0x4022, 0x1e21,
+ 0x4023, 0x0a47,
+ 0x4042, 0x1e22,
+ 0x4043, 0x0a67,
+ 0x4066, 0x1e23,
+ 0x4067, 0x0a8b,
+ 0x4071, 0x1e24,
+ 0x4073, 0x0a97,
+ 0x4079, 0x1e26,
+ 0x407b, 0x0a9f,
+ 0x4121, 0x0aa3,
+ 0x4127, 0x1e28,
+ 0x4128, 0x1a6e,
+ 0x4129, 0x0aab,
+ 0x4139, 0x1e29,
+ 0x413a, 0x0abc,
+ 0x414c, 0x1e2a,
+ 0x414d, 0x0acf,
+ 0x414f, 0x1e2b,
+ 0x4150, 0x0ad2,
+ 0x415f, 0x1e2c,
+ 0x4160, 0x0ae2,
+ 0x4169, 0x1e2d,
+ 0x416a, 0x0aec,
+ 0x4221, 0x0b01,
+ 0x423d, 0x1e2e,
+ 0x423e, 0x0b1e,
+ 0x424d, 0x1e2f,
+ 0x424e, 0x0b2e,
+ 0x425c, 0x1e30,
+ 0x425d, 0x0b3d,
+ 0x4263, 0x1e31,
+ 0x4264, 0x0b44,
+ 0x426f, 0x1e32,
+ 0x4270, 0x0b50,
+ 0x4275, 0x1e33,
+ 0x4277, 0x0b57,
+ 0x427d, 0x1e35,
+ 0x427e, 0x0b5e,
+ 0x4321, 0x0b5f,
+ 0x4327, 0x1e36,
+ 0x4328, 0x0b66,
+ 0x4329, 0x1e37,
+ 0x432b, 0x0b69,
+ 0x432d, 0x1e39,
+ 0x432f, 0x0b6d,
+ 0x433d, 0x1e3b,
+ 0x433e, 0x0b7c,
+ 0x4370, 0x1e3c,
+ 0x4371, 0x0baf,
+ 0x4375, 0x1e3d,
+ 0x4376, 0x0bb4,
+ 0x437c, 0x1e3e,
+ 0x437d, 0x0bbb,
+ 0x4421, 0x0bbd,
+ 0x443d, 0x1e3f,
+ 0x443e, 0x0bda,
+ 0x4448, 0x1e40,
+ 0x4449, 0x0be5,
+ 0x444a, 0x1e41,
+ 0x444b, 0x0be7,
+ 0x444d, 0x1e42,
+ 0x444e, 0x0bea,
+ 0x444f, 0x1e43,
+ 0x4450, 0x0bec,
+ 0x445b, 0x11b5,
+ 0x445c, 0x0bf8,
+ 0x4521, 0x0c1b,
+ 0x4522, 0x1e44,
+ 0x4523, 0x0c1d,
+ 0x4527, 0x1e45,
+ 0x4528, 0x0c22,
+ 0x452e, 0x1e46,
+ 0x452f, 0x0c29,
+ 0x4536, 0x1e47,
+ 0x4537, 0x0c31,
+ 0x453f, 0x1e48,
+ 0x4540, 0x0c3a,
+ 0x4548, 0x1e49,
+ 0x4549, 0x0c43,
+ 0x454b, 0x1e4a,
+ 0x454c, 0x0c46,
+ 0x4551, 0x1e4b,
+ 0x4553, 0x0c4d,
+ 0x4557, 0x16df,
+ 0x4558, 0x0c52,
+ 0x4564, 0x1e4d,
+ 0x4565, 0x0c5f,
+ 0x456e, 0x1450,
+ 0x456f, 0x0c69,
+ 0x4573, 0x1536,
+ 0x4574, 0x0c6e,
+ 0x4578, 0x1e4e,
+ 0x4579, 0x0c73,
+ 0x4621, 0x0c79,
+ 0x463e, 0x1e4f,
+ 0x463f, 0x0c97,
+ 0x4642, 0x1e50,
+ 0x4643, 0x0c9b,
+ 0x4654, 0x1e51,
+ 0x4656, 0x0cae,
+ 0x465b, 0x1e53,
+ 0x465d, 0x0cb5,
+ 0x4661, 0x1e55,
+ 0x4662, 0x0cba,
+ 0x4666, 0x1e56,
+ 0x4668, 0x0cc0,
+ 0x466a, 0x1e58,
+ 0x466b, 0x0cc3,
+ 0x4676, 0x1aed,
+ 0x4677, 0x0ccf,
+ 0x4721, 0x0cd7,
+ 0x4729, 0x1e59,
+ 0x472a, 0x0ce0,
+ 0x4739, 0x1e5a,
+ 0x473a, 0x0cf0,
+ 0x4757, 0x1e5b,
+ 0x4758, 0x0d0e,
+ 0x4767, 0x1e5c,
+ 0x4768, 0x1989,
+ 0x4769, 0x1e5d,
+ 0x476a, 0x0d20,
+ 0x476d, 0x1e5e,
+ 0x476e, 0x0d24,
+ 0x4821, 0x0d35,
+ 0x4824, 0x1e5f,
+ 0x4825, 0x0d39,
+ 0x482e, 0x1e60,
+ 0x482f, 0x0d43,
+ 0x4830, 0x1e61,
+ 0x4831, 0x0d45,
+ 0x4854, 0x1e62,
+ 0x4855, 0x0d69,
+ 0x4862, 0x1e63,
+ 0x4863, 0x0d77,
+ 0x4875, 0x1e64,
+ 0x4876, 0x0d8a,
+ 0x4921, 0x0d93,
+ 0x4922, 0x1e65,
+ 0x4924, 0x0d96,
+ 0x492f, 0x1e67,
+ 0x4930, 0x143b,
+ 0x4931, 0x0da3,
+ 0x4932, 0x1e68,
+ 0x4933, 0x0da5,
+ 0x4935, 0x1e69,
+ 0x4936, 0x0da8,
+ 0x4940, 0x1e6a,
+ 0x4941, 0x0db3,
+ 0x494e, 0x1e6b,
+ 0x494f, 0x0dc1,
+ 0x4951, 0x1e6c,
+ 0x4952, 0x0dc4,
+ 0x4a21, 0x0df1,
+ 0x4a43, 0x1e6d,
+ 0x4a44, 0x0e14,
+ 0x4a4d, 0x1e6e,
+ 0x4a4e, 0x0e1e,
+ 0x4a5a, 0x1e6f,
+ 0x4a5b, 0x0e2b,
+ 0x4a79, 0x1e70,
+ 0x4a7a, 0x0e4a,
+ 0x4b21, 0x0e4f,
+ 0x4b22, 0x1e71,
+ 0x4b23, 0x0e51,
+ 0x4b29, 0x1e72,
+ 0x4b2a, 0x0e58,
+ 0x4b4b, 0x1e73,
+ 0x4b4c, 0x0e7a,
+ 0x4b6a, 0x1d33,
+ 0x4b6b, 0x0e99,
+ 0x4b70, 0x1e74,
+ 0x4b71, 0x0e9f,
+ 0x4b79, 0x102f,
+ 0x4b7a, 0x0ea8,
+ 0x4c21, 0x0ead,
+ 0x4c4d, 0x1e75,
+ 0x4c4e, 0x0eda,
+ 0x4c59, 0x1e76,
+ 0x4c5a, 0x0ee6,
+ 0x4c5f, 0x1e77,
+ 0x4c60, 0x0eec,
+ 0x4c62, 0x1e78,
+ 0x4c63, 0x0eef,
+ 0x4c79, 0x1935,
+ 0x4c7a, 0x1e79,
+ 0x4c7b, 0x0f07,
+ 0x4c7c, 0x1e7a,
+ 0x4c7d, 0x0f09,
+ 0x4c7e, 0x1e7b,
+ 0x4d21, 0x0f0b,
+ 0x4d32, 0x1e7c,
+ 0x4d33, 0x0f1d,
+ 0x4d50, 0x1e7d,
+ 0x4d51, 0x0f3b,
+ 0x4d54, 0x1e7e,
+ 0x4d55, 0x0f3f,
+ 0x4d5a, 0x1d34,
+ 0x4d5b, 0x0f45,
+ 0x4d69, 0x1e7f,
+ 0x4d6a, 0x0f54,
+ 0x4e21, 0x0f69,
+ 0x4e4b, 0x1e80,
+ 0x4e4c, 0x0f94,
+ 0x4e7a, 0x1e81,
+ 0x4e7c, 0x0fc4,
+ 0x4f21, 0x1e83,
+ 0x4f22, 0x0fc8,
+ 0x4f31, 0x1e84,
+ 0x4f32, 0x0fd8,
+ 0x4f36, 0x1777,
+ 0x4f37, 0x0fdd,
+ 0x4f39, 0x1e85,
+ 0x4f3a, 0x0fe0,
+ 0x5021, 0x0ffa,
+ 0x5056, 0x0ea7,
+ 0x5057, 0x1030,
+ 0x5121, 0x1058,
+ 0x513d, 0x1e86,
+ 0x513e, 0x1075,
+ 0x5147, 0x1e87,
+ 0x5148, 0x107f,
+ 0x514b, 0x1e88,
+ 0x514c, 0x1083,
+ 0x514d, 0x1e89,
+ 0x514e, 0x1085,
+ 0x5221, 0x10b6,
+ 0x5321, 0x1114,
+ 0x5330, 0x1e8a,
+ 0x5331, 0x1124,
+ 0x533a, 0x1e8b,
+ 0x533b, 0x112e,
+ 0x5350, 0x1e8c,
+ 0x5351, 0x1144,
+ 0x535e, 0x1e8d,
+ 0x535f, 0x1152,
+ 0x536b, 0x1e8e,
+ 0x536c, 0x115f,
+ 0x5421, 0x1172,
+ 0x5444, 0x1e8f,
+ 0x5445, 0x1196,
+ 0x5464, 0x0bf7,
+ 0x5465, 0x11b6,
+ 0x5521, 0x11d0,
+ 0x553d, 0x1e90,
+ 0x553e, 0x11ed,
+ 0x5563, 0x1e91,
+ 0x5564, 0x1213,
+ 0x5621, 0x122e,
+ 0x5622, 0x1e92,
+ 0x5623, 0x1230,
+ 0x5672, 0x1e93,
+ 0x5673, 0x1280,
+ 0x5721, 0x128c,
+ 0x5821, 0x12ea,
+ 0x5824, 0x1e94,
+ 0x5825, 0x12ee,
+ 0x5921, 0x1348,
+ 0x5960, 0x1e95,
+ 0x5961, 0x1388,
+ 0x596c, 0x1e96,
+ 0x596d, 0x1394,
+ 0x5978, 0x05a7,
+ 0x5979, 0x13a0,
+ 0x5a21, 0x13a6,
+ 0x5a39, 0x1e97,
+ 0x5a3a, 0x13bf,
+ 0x5a4d, 0x1e98,
+ 0x5a4e, 0x13d3,
+ 0x5b21, 0x1404,
+ 0x5b45, 0x1e99,
+ 0x5b46, 0x1429,
+ 0x5b4a, 0x1e9a,
+ 0x5b4b, 0x142e,
+ 0x5b58, 0x0da2,
+ 0x5b59, 0x143c,
+ 0x5b6b, 0x1e9b,
+ 0x5b6c, 0x144f,
+ 0x5b6d, 0x0c68,
+ 0x5b6e, 0x1451,
+ 0x5b74, 0x1e9c,
+ 0x5b75, 0x1458,
+ 0x5c21, 0x1462,
+ 0x5d21, 0x14c0,
+ 0x5e21, 0x151e,
+ 0x5e39, 0x0c6d,
+ 0x5e3a, 0x1537,
+ 0x5e50, 0x1e9d,
+ 0x5e51, 0x154e,
+ 0x5e75, 0x05ff,
+ 0x5e76, 0x1573,
+ 0x5f21, 0x157c,
+ 0x5f73, 0x1e9e,
+ 0x5f74, 0x15cf,
+ 0x6021, 0x15da,
+ 0x6026, 0x1e9f,
+ 0x6027, 0x15e0,
+ 0x605f, 0x1ea0,
+ 0x6060, 0x1619,
+ 0x6076, 0x1d35,
+ 0x6077, 0x1630,
+ 0x6121, 0x1638,
+ 0x612b, 0x1ea1,
+ 0x612c, 0x1643,
+ 0x6130, 0x1ea2,
+ 0x6132, 0x1649,
+ 0x6221, 0x1696,
+ 0x622b, 0x1ea4,
+ 0x622c, 0x16a1,
+ 0x6268, 0x07ee,
+ 0x6269, 0x16de,
+ 0x626a, 0x0c51,
+ 0x626b, 0x16e0,
+ 0x626f, 0x1ea5,
+ 0x6270, 0x16e5,
+ 0x6321, 0x16f4,
+ 0x634a, 0x1ea6,
+ 0x634b, 0x171e,
+ 0x6354, 0x1ea7,
+ 0x6355, 0x1728,
+ 0x635e, 0x05d4,
+ 0x635f, 0x1732,
+ 0x6421, 0x1752,
+ 0x6439, 0x1ea8,
+ 0x643a, 0x176b,
+ 0x6446, 0x0fdc,
+ 0x6447, 0x1778,
+ 0x6464, 0x1ea9,
+ 0x6465, 0x1796,
+ 0x646e, 0x1eaa,
+ 0x646f, 0x17a0,
+ 0x6521, 0x17b0,
+ 0x6539, 0x1eab,
+ 0x653a, 0x17c9,
+ 0x653b, 0x1eac,
+ 0x653c, 0x17cb,
+ 0x6546, 0x1ead,
+ 0x6547, 0x17d6,
+ 0x6621, 0x180e,
+ 0x6646, 0x1eae,
+ 0x6647, 0x1834,
+ 0x6721, 0x186c,
+ 0x6764, 0x1eaf,
+ 0x6765, 0x18b0,
+ 0x6769, 0x1eb0,
+ 0x676a, 0x18b5,
+ 0x6772, 0x1eb1,
+ 0x6773, 0x18be,
+ 0x6821, 0x18ca,
+ 0x6834, 0x1eb2,
+ 0x6835, 0x18de,
+ 0x683b, 0x1eb3,
+ 0x683c, 0x18e5,
+ 0x6874, 0x1eb4,
+ 0x6875, 0x191e,
+ 0x6921, 0x1928,
+ 0x6922, 0x08f5,
+ 0x6923, 0x192a,
+ 0x692e, 0x0f05,
+ 0x692f, 0x1936,
+ 0x693c, 0x1eb5,
+ 0x693d, 0x1944,
+ 0x695a, 0x05a0,
+ 0x695b, 0x1962,
+ 0x6a21, 0x1986,
+ 0x6a24, 0x0d1e,
+ 0x6a25, 0x198a,
+ 0x6a27, 0x1eb6,
+ 0x6a28, 0x198d,
+ 0x6a3d, 0x1eb7,
+ 0x6a3e, 0x19a3,
+ 0x6a6f, 0x1eb8,
+ 0x6a70, 0x19d5,
+ 0x6b21, 0x19e4,
+ 0x6b32, 0x1eb9,
+ 0x6b33, 0x19f6,
+ 0x6b5d, 0x060e,
+ 0x6b5e, 0x1a21,
+ 0x6b66, 0x1eba,
+ 0x6b67, 0x1a2a,
+ 0x6b76, 0x1ebb,
+ 0x6b77, 0x1a3a,
+ 0x6c21, 0x1a42,
+ 0x6c4d, 0x0aaa,
+ 0x6c4e, 0x1a6f,
+ 0x6c69, 0x1ebc,
+ 0x6c6a, 0x1a8b,
+ 0x6c74, 0x1ebd,
+ 0x6c75, 0x1a96,
+ 0x6d21, 0x1aa0,
+ 0x6d4e, 0x1ebe,
+ 0x6d4f, 0x1ace,
+ 0x6d6c, 0x1ebf,
+ 0x6d6d, 0x1aec,
+ 0x6d6e, 0x1ec0,
+ 0x6d6f, 0x1aee,
+ 0x6e21, 0x1afe,
+ 0x6e29, 0x1ec1,
+ 0x6e2a, 0x1b07,
+ 0x6e3d, 0x1ec2,
+ 0x6e3e, 0x1b1b,
+ 0x6e57, 0x1ec3,
+ 0x6e58, 0x1b35,
+ 0x6f21, 0x1b5c,
+ 0x6f65, 0x1ec4,
+ 0x6f66, 0x1ba1,
+ 0x7021, 0x1bba,
+ 0x7033, 0x1ec5,
+ 0x7034, 0x1bcd,
+ 0x7045, 0x1ec6,
+ 0x7046, 0x1bdf,
+ 0x7051, 0x1ec7,
+ 0x7052, 0x1beb,
+ 0x7057, 0x1ec8,
+ 0x7058, 0x1bf1,
+ 0x7074, 0x0731,
+ 0x7075, 0x1ec9,
+ 0x7076, 0x1c0f,
+ 0x7121, 0x1c18,
+ 0x7221, 0x1c76,
+ 0x722d, 0x1eca,
+ 0x722e, 0x1c83,
+ 0x723c, 0x1ecb,
+ 0x723d, 0x1c92,
+ 0x724d, 0x0477,
+ 0x724e, 0x1ecc,
+ 0x724f, 0x1ca4,
+ 0x7274, 0x0529,
+ 0x7275, 0x1cca,
+ 0x7321, 0x1cd4,
+ 0x7351, 0x1ecd,
+ 0x7352, 0x1d05,
+ 0x737d, 0x1ece,
+ 0x737e, 0x1d31,
+ 0x7921, 0x20a7,
+ 0x7a21, 0x2105,
+ 0x7a36, 0x07c9,
+ 0x7a37, 0x211a,
+ 0x7b21, 0x2162,
+ 0x7c21, 0x21c0,
+ 0x7c71, 0x1f9c,
+ 0x7c7b, 0x02ef,
+ 0x7c7c, 0x1f45,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12ExtHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12ExtHMap2, 663
+};
+
+static Gushort japan12ExtRKSJHMap2[1330] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x8189, 0x1d36,
+ 0x818a, 0x02c2,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x8540, 0x00e8,
+ 0x8580, 0x0186,
+ 0x8581, 0x0128,
+ 0x859f, 0x0147,
+ 0x85de, 0x0187,
+ 0x8640, 0x01a6,
+ 0x8680, 0x01e5,
+ 0x8692, 0x0127,
+ 0x8693, 0x01f7,
+ 0x86a2, 0x1d37,
+ 0x8740, 0x1d83,
+ 0x875f, 0x1da1,
+ 0x877e, 0x2083,
+ 0x8780, 0x1db8,
+ 0x8790, 0x02fa,
+ 0x8791, 0x02f9,
+ 0x8792, 0x0301,
+ 0x8793, 0x1dc8,
+ 0x879a, 0x0300,
+ 0x879b, 0x1dcf,
+ 0x889f, 0x0465,
+ 0x88a0, 0x1dd1,
+ 0x88a1, 0x0467,
+ 0x88b1, 0x1ca2,
+ 0x88b2, 0x0478,
+ 0x88b9, 0x1dd2,
+ 0x88ba, 0x0480,
+ 0x88ec, 0x1dd3,
+ 0x88ed, 0x04b3,
+ 0x88f1, 0x1dd4,
+ 0x88f2, 0x04b8,
+ 0x88fa, 0x1dd5,
+ 0x88fb, 0x04c1,
+ 0x8940, 0x04c3,
+ 0x8949, 0x1dd6,
+ 0x894a, 0x04cd,
+ 0x8954, 0x1dd7,
+ 0x8955, 0x04d8,
+ 0x8958, 0x1dd8,
+ 0x8959, 0x04dc,
+ 0x895b, 0x1dd9,
+ 0x895d, 0x04e0,
+ 0x8961, 0x1ddb,
+ 0x8962, 0x04e5,
+ 0x8980, 0x0502,
+ 0x898b, 0x1ddc,
+ 0x898c, 0x050e,
+ 0x89a6, 0x1ddd,
+ 0x89a7, 0x1cc9,
+ 0x89a8, 0x1dde,
+ 0x89a9, 0x052b,
+ 0x89de, 0x1ddf,
+ 0x89df, 0x0561,
+ 0x89f8, 0x1de0,
+ 0x89f9, 0x057b,
+ 0x89fb, 0x1de1,
+ 0x89fc, 0x057e,
+ 0x8a40, 0x057f,
+ 0x8a41, 0x1de2,
+ 0x8a42, 0x0581,
+ 0x8a61, 0x1961,
+ 0x8a62, 0x05a1,
+ 0x8a68, 0x139f,
+ 0x8a69, 0x05a8,
+ 0x8a80, 0x05be,
+ 0x8a85, 0x1de3,
+ 0x8a86, 0x05c4,
+ 0x8a8b, 0x1de4,
+ 0x8a8c, 0x05ca,
+ 0x8a93, 0x1de5,
+ 0x8a94, 0x05d2,
+ 0x8a96, 0x1731,
+ 0x8a97, 0x05d5,
+ 0x8a9a, 0x1de6,
+ 0x8a9b, 0x05d9,
+ 0x8ac0, 0x1de7,
+ 0x8ac1, 0x1572,
+ 0x8ac2, 0x0600,
+ 0x8acb, 0x1de8,
+ 0x8acc, 0x060a,
+ 0x8ad0, 0x1a20,
+ 0x8ad1, 0x060f,
+ 0x8ae3, 0x1de9,
+ 0x8ae4, 0x0622,
+ 0x8b40, 0x063b,
+ 0x8b4a, 0x1dea,
+ 0x8b4b, 0x0646,
+ 0x8b5f, 0x1deb,
+ 0x8b60, 0x065b,
+ 0x8b80, 0x067a,
+ 0x8ba0, 0x1dec,
+ 0x8ba1, 0x069b,
+ 0x8ba8, 0x1ded,
+ 0x8ba9, 0x06a3,
+ 0x8bc4, 0x1d32,
+ 0x8bc5, 0x06bf,
+ 0x8bcd, 0x1dee,
+ 0x8bce, 0x06c8,
+ 0x8beb, 0x1def,
+ 0x8bec, 0x06e6,
+ 0x8bf2, 0x1df0,
+ 0x8bf3, 0x06ed,
+ 0x8bf9, 0x1df1,
+ 0x8bfa, 0x06f4,
+ 0x8bfb, 0x1df2,
+ 0x8bfc, 0x06f6,
+ 0x8c40, 0x06f7,
+ 0x8c43, 0x1df3,
+ 0x8c44, 0x06fb,
+ 0x8c56, 0x1df4,
+ 0x8c57, 0x070e,
+ 0x8c64, 0x1df5,
+ 0x8c65, 0x071c,
+ 0x8c6d, 0x1df6,
+ 0x8c6e, 0x0725,
+ 0x8c71, 0x1df7,
+ 0x8c72, 0x0729,
+ 0x8c74, 0x1df8,
+ 0x8c75, 0x072c,
+ 0x8c7a, 0x1c0d,
+ 0x8c7b, 0x0732,
+ 0x8c80, 0x0736,
+ 0x8c84, 0x1df9,
+ 0x8c85, 0x073b,
+ 0x8c91, 0x1dfa,
+ 0x8c92, 0x0748,
+ 0x8c99, 0x1dfb,
+ 0x8c9a, 0x0750,
+ 0x8c9e, 0x1dfc,
+ 0x8c9f, 0x0755,
+ 0x8cb2, 0x1dfd,
+ 0x8cb3, 0x0769,
+ 0x8cbf, 0x1dfe,
+ 0x8cc0, 0x0776,
+ 0x8d40, 0x07b3,
+ 0x8d4a, 0x1dff,
+ 0x8d4b, 0x07be,
+ 0x8d56, 0x1e00,
+ 0x8d57, 0x07ca,
+ 0x8d61, 0x1e01,
+ 0x8d62, 0x07d5,
+ 0x8d7b, 0x16dd,
+ 0x8d7c, 0x07ef,
+ 0x8d80, 0x07f2,
+ 0x8d8d, 0x1e02,
+ 0x8d8e, 0x0800,
+ 0x8d94, 0x1e03,
+ 0x8d95, 0x0807,
+ 0x8d99, 0x1e04,
+ 0x8d9a, 0x080c,
+ 0x8dd1, 0x1e05,
+ 0x8dd2, 0x0844,
+ 0x8de5, 0x1e06,
+ 0x8de6, 0x0858,
+ 0x8df2, 0x1e07,
+ 0x8df3, 0x0865,
+ 0x8e40, 0x086f,
+ 0x8e46, 0x1e08,
+ 0x8e47, 0x0876,
+ 0x8e49, 0x1e09,
+ 0x8e4a, 0x0879,
+ 0x8e4b, 0x1e0a,
+ 0x8e4c, 0x087b,
+ 0x8e58, 0x1e0b,
+ 0x8e59, 0x0888,
+ 0x8e80, 0x08ae,
+ 0x8eb6, 0x1e0c,
+ 0x8eb7, 0x08e5,
+ 0x8ec6, 0x1e0d,
+ 0x8ec7, 0x1929,
+ 0x8ec8, 0x08f6,
+ 0x8ed5, 0x1e0e,
+ 0x8ed6, 0x0904,
+ 0x8edb, 0x1e0f,
+ 0x8edd, 0x090b,
+ 0x8f40, 0x092b,
+ 0x8f4a, 0x1e11,
+ 0x8f4b, 0x0936,
+ 0x8f55, 0x1e12,
+ 0x8f56, 0x0941,
+ 0x8f80, 0x096a,
+ 0x8f8c, 0x1e13,
+ 0x8f8e, 0x0978,
+ 0x8f92, 0x1e15,
+ 0x8f94, 0x097e,
+ 0x8fa3, 0x1e17,
+ 0x8fa4, 0x098e,
+ 0x8fb1, 0x1e18,
+ 0x8fb2, 0x099c,
+ 0x8fbd, 0x1e19,
+ 0x8fbe, 0x09a8,
+ 0x8fd3, 0x1e1a,
+ 0x8fd4, 0x09be,
+ 0x8fdd, 0x1e1b,
+ 0x8fde, 0x09c8,
+ 0x8fe2, 0x1e1c,
+ 0x8fe3, 0x09cd,
+ 0x9040, 0x09e7,
+ 0x9049, 0x1e1d,
+ 0x904a, 0x09f1,
+ 0x9078, 0x1e1e,
+ 0x9079, 0x0a20,
+ 0x9080, 0x1e1f,
+ 0x9081, 0x0a27,
+ 0x9089, 0x1e20,
+ 0x908a, 0x0a30,
+ 0x90a0, 0x1e21,
+ 0x90a1, 0x0a47,
+ 0x90c0, 0x1e22,
+ 0x90c1, 0x0a67,
+ 0x90e4, 0x1e23,
+ 0x90e5, 0x0a8b,
+ 0x90ef, 0x1e24,
+ 0x90f1, 0x0a97,
+ 0x90f7, 0x1e26,
+ 0x90f9, 0x0a9f,
+ 0x9140, 0x0aa3,
+ 0x9146, 0x1e28,
+ 0x9147, 0x1a6e,
+ 0x9148, 0x0aab,
+ 0x9158, 0x1e29,
+ 0x9159, 0x0abc,
+ 0x916b, 0x1e2a,
+ 0x916c, 0x0acf,
+ 0x916e, 0x1e2b,
+ 0x916f, 0x0ad2,
+ 0x917e, 0x1e2c,
+ 0x9180, 0x0ae2,
+ 0x9189, 0x1e2d,
+ 0x918a, 0x0aec,
+ 0x91bb, 0x1e2e,
+ 0x91bc, 0x0b1e,
+ 0x91cb, 0x1e2f,
+ 0x91cc, 0x0b2e,
+ 0x91da, 0x1e30,
+ 0x91db, 0x0b3d,
+ 0x91e1, 0x1e31,
+ 0x91e2, 0x0b44,
+ 0x91ed, 0x1e32,
+ 0x91ee, 0x0b50,
+ 0x91f3, 0x1e33,
+ 0x91f5, 0x0b57,
+ 0x91fb, 0x1e35,
+ 0x91fc, 0x0b5e,
+ 0x9240, 0x0b5f,
+ 0x9246, 0x1e36,
+ 0x9247, 0x0b66,
+ 0x9248, 0x1e37,
+ 0x924a, 0x0b69,
+ 0x924c, 0x1e39,
+ 0x924e, 0x0b6d,
+ 0x925c, 0x1e3b,
+ 0x925d, 0x0b7c,
+ 0x9280, 0x0b9e,
+ 0x9290, 0x1e3c,
+ 0x9291, 0x0baf,
+ 0x9295, 0x1e3d,
+ 0x9296, 0x0bb4,
+ 0x929c, 0x1e3e,
+ 0x929d, 0x0bbb,
+ 0x92bb, 0x1e3f,
+ 0x92bc, 0x0bda,
+ 0x92c6, 0x1e40,
+ 0x92c7, 0x0be5,
+ 0x92c8, 0x1e41,
+ 0x92c9, 0x0be7,
+ 0x92cb, 0x1e42,
+ 0x92cc, 0x0bea,
+ 0x92cd, 0x1e43,
+ 0x92ce, 0x0bec,
+ 0x92d9, 0x11b5,
+ 0x92da, 0x0bf8,
+ 0x9340, 0x0c1b,
+ 0x9341, 0x1e44,
+ 0x9342, 0x0c1d,
+ 0x9346, 0x1e45,
+ 0x9347, 0x0c22,
+ 0x934d, 0x1e46,
+ 0x934e, 0x0c29,
+ 0x9355, 0x1e47,
+ 0x9356, 0x0c31,
+ 0x935e, 0x1e48,
+ 0x935f, 0x0c3a,
+ 0x9367, 0x1e49,
+ 0x9368, 0x0c43,
+ 0x936a, 0x1e4a,
+ 0x936b, 0x0c46,
+ 0x9370, 0x1e4b,
+ 0x9372, 0x0c4d,
+ 0x9376, 0x16df,
+ 0x9377, 0x0c52,
+ 0x9380, 0x0c5a,
+ 0x9384, 0x1e4d,
+ 0x9385, 0x0c5f,
+ 0x938e, 0x1450,
+ 0x938f, 0x0c69,
+ 0x9393, 0x1536,
+ 0x9394, 0x0c6e,
+ 0x9398, 0x1e4e,
+ 0x9399, 0x0c73,
+ 0x93bc, 0x1e4f,
+ 0x93bd, 0x0c97,
+ 0x93c0, 0x1e50,
+ 0x93c1, 0x0c9b,
+ 0x93d2, 0x1e51,
+ 0x93d4, 0x0cae,
+ 0x93d9, 0x1e53,
+ 0x93db, 0x0cb5,
+ 0x93df, 0x1e55,
+ 0x93e0, 0x0cba,
+ 0x93e4, 0x1e56,
+ 0x93e6, 0x0cc0,
+ 0x93e8, 0x1e58,
+ 0x93e9, 0x0cc3,
+ 0x93f4, 0x1aed,
+ 0x93f5, 0x0ccf,
+ 0x9440, 0x0cd7,
+ 0x9448, 0x1e59,
+ 0x9449, 0x0ce0,
+ 0x9458, 0x1e5a,
+ 0x9459, 0x0cf0,
+ 0x9476, 0x1e5b,
+ 0x9477, 0x0d0e,
+ 0x9480, 0x0d16,
+ 0x9487, 0x1e5c,
+ 0x9488, 0x1989,
+ 0x9489, 0x1e5d,
+ 0x948a, 0x0d20,
+ 0x948d, 0x1e5e,
+ 0x948e, 0x0d24,
+ 0x94a2, 0x1e5f,
+ 0x94a3, 0x0d39,
+ 0x94ac, 0x1e60,
+ 0x94ad, 0x0d43,
+ 0x94ae, 0x1e61,
+ 0x94af, 0x0d45,
+ 0x94d2, 0x1e62,
+ 0x94d3, 0x0d69,
+ 0x94e0, 0x1e63,
+ 0x94e1, 0x0d77,
+ 0x94f3, 0x1e64,
+ 0x94f4, 0x0d8a,
+ 0x9540, 0x0d93,
+ 0x9541, 0x1e65,
+ 0x9543, 0x0d96,
+ 0x954e, 0x1e67,
+ 0x954f, 0x143b,
+ 0x9550, 0x0da3,
+ 0x9551, 0x1e68,
+ 0x9552, 0x0da5,
+ 0x9554, 0x1e69,
+ 0x9555, 0x0da8,
+ 0x955f, 0x1e6a,
+ 0x9560, 0x0db3,
+ 0x956d, 0x1e6b,
+ 0x956e, 0x0dc1,
+ 0x9570, 0x1e6c,
+ 0x9571, 0x0dc4,
+ 0x9580, 0x0dd2,
+ 0x95c1, 0x1e6d,
+ 0x95c2, 0x0e14,
+ 0x95cb, 0x1e6e,
+ 0x95cc, 0x0e1e,
+ 0x95d8, 0x1e6f,
+ 0x95d9, 0x0e2b,
+ 0x95f7, 0x1e70,
+ 0x95f8, 0x0e4a,
+ 0x9640, 0x0e4f,
+ 0x9641, 0x1e71,
+ 0x9642, 0x0e51,
+ 0x9648, 0x1e72,
+ 0x9649, 0x0e58,
+ 0x966a, 0x1e73,
+ 0x966b, 0x0e7a,
+ 0x9680, 0x0e8e,
+ 0x968a, 0x1d33,
+ 0x968b, 0x0e99,
+ 0x9690, 0x1e74,
+ 0x9691, 0x0e9f,
+ 0x9699, 0x102f,
+ 0x969a, 0x0ea8,
+ 0x96cb, 0x1e75,
+ 0x96cc, 0x0eda,
+ 0x96d7, 0x1e76,
+ 0x96d8, 0x0ee6,
+ 0x96dd, 0x1e77,
+ 0x96de, 0x0eec,
+ 0x96e0, 0x1e78,
+ 0x96e1, 0x0eef,
+ 0x96f7, 0x1935,
+ 0x96f8, 0x1e79,
+ 0x96f9, 0x0f07,
+ 0x96fa, 0x1e7a,
+ 0x96fb, 0x0f09,
+ 0x96fc, 0x1e7b,
+ 0x9740, 0x0f0b,
+ 0x9751, 0x1e7c,
+ 0x9752, 0x0f1d,
+ 0x976f, 0x1e7d,
+ 0x9770, 0x0f3b,
+ 0x9773, 0x1e7e,
+ 0x9774, 0x0f3f,
+ 0x9779, 0x1d34,
+ 0x977a, 0x0f45,
+ 0x9780, 0x0f4a,
+ 0x9789, 0x1e7f,
+ 0x978a, 0x0f54,
+ 0x97c9, 0x1e80,
+ 0x97ca, 0x0f94,
+ 0x97f8, 0x1e81,
+ 0x97fa, 0x0fc4,
+ 0x9840, 0x1e83,
+ 0x9841, 0x0fc8,
+ 0x9850, 0x1e84,
+ 0x9851, 0x0fd8,
+ 0x9855, 0x1777,
+ 0x9856, 0x0fdd,
+ 0x9858, 0x1e85,
+ 0x9859, 0x0fe0,
+ 0x989f, 0x0ffa,
+ 0x98d4, 0x0ea7,
+ 0x98d5, 0x1030,
+ 0x9940, 0x1058,
+ 0x995c, 0x1e86,
+ 0x995d, 0x1075,
+ 0x9966, 0x1e87,
+ 0x9967, 0x107f,
+ 0x996a, 0x1e88,
+ 0x996b, 0x1083,
+ 0x996c, 0x1e89,
+ 0x996d, 0x1085,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a4f, 0x1e8a,
+ 0x9a50, 0x1124,
+ 0x9a59, 0x1e8b,
+ 0x9a5a, 0x112e,
+ 0x9a6f, 0x1e8c,
+ 0x9a70, 0x1144,
+ 0x9a7d, 0x1e8d,
+ 0x9a7e, 0x1152,
+ 0x9a80, 0x1153,
+ 0x9a8b, 0x1e8e,
+ 0x9a8c, 0x115f,
+ 0x9ac2, 0x1e8f,
+ 0x9ac3, 0x1196,
+ 0x9ae2, 0x0bf7,
+ 0x9ae3, 0x11b6,
+ 0x9b40, 0x11d0,
+ 0x9b5c, 0x1e90,
+ 0x9b5d, 0x11ed,
+ 0x9b80, 0x120f,
+ 0x9b83, 0x1e91,
+ 0x9b84, 0x1213,
+ 0x9ba0, 0x1e92,
+ 0x9ba1, 0x1230,
+ 0x9bf0, 0x1e93,
+ 0x9bf1, 0x1280,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9ca2, 0x1e94,
+ 0x9ca3, 0x12ee,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1e95,
+ 0x9d81, 0x1388,
+ 0x9d8c, 0x1e96,
+ 0x9d8d, 0x1394,
+ 0x9d98, 0x05a7,
+ 0x9d99, 0x13a0,
+ 0x9db7, 0x1e97,
+ 0x9db8, 0x13bf,
+ 0x9dcb, 0x1e98,
+ 0x9dcc, 0x13d3,
+ 0x9e40, 0x1404,
+ 0x9e64, 0x1e99,
+ 0x9e65, 0x1429,
+ 0x9e69, 0x1e9a,
+ 0x9e6a, 0x142e,
+ 0x9e77, 0x0da2,
+ 0x9e78, 0x143c,
+ 0x9e80, 0x1443,
+ 0x9e8b, 0x1e9b,
+ 0x9e8c, 0x144f,
+ 0x9e8d, 0x0c68,
+ 0x9e8e, 0x1451,
+ 0x9e94, 0x1e9c,
+ 0x9e95, 0x1458,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0x9fb7, 0x0c6d,
+ 0x9fb8, 0x1537,
+ 0x9fce, 0x1e9d,
+ 0x9fcf, 0x154e,
+ 0x9ff3, 0x05ff,
+ 0x9ff4, 0x1573,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe093, 0x1e9e,
+ 0xe094, 0x15cf,
+ 0xe0a4, 0x1e9f,
+ 0xe0a5, 0x15e0,
+ 0xe0dd, 0x1ea0,
+ 0xe0de, 0x1619,
+ 0xe0f4, 0x1d35,
+ 0xe0f5, 0x1630,
+ 0xe140, 0x1638,
+ 0xe14a, 0x1ea1,
+ 0xe14b, 0x1643,
+ 0xe14f, 0x1ea2,
+ 0xe151, 0x1649,
+ 0xe180, 0x1677,
+ 0xe1a9, 0x1ea4,
+ 0xe1aa, 0x16a1,
+ 0xe1e6, 0x07ee,
+ 0xe1e7, 0x16de,
+ 0xe1e8, 0x0c51,
+ 0xe1e9, 0x16e0,
+ 0xe1ed, 0x1ea5,
+ 0xe1ee, 0x16e5,
+ 0xe240, 0x16f4,
+ 0xe269, 0x1ea6,
+ 0xe26a, 0x171e,
+ 0xe273, 0x1ea7,
+ 0xe274, 0x1728,
+ 0xe27d, 0x05d4,
+ 0xe27e, 0x1732,
+ 0xe280, 0x1733,
+ 0xe2b7, 0x1ea8,
+ 0xe2b8, 0x176b,
+ 0xe2c4, 0x0fdc,
+ 0xe2c5, 0x1778,
+ 0xe2e2, 0x1ea9,
+ 0xe2e3, 0x1796,
+ 0xe2ec, 0x1eaa,
+ 0xe2ed, 0x17a0,
+ 0xe340, 0x17b0,
+ 0xe358, 0x1eab,
+ 0xe359, 0x17c9,
+ 0xe35a, 0x1eac,
+ 0xe35b, 0x17cb,
+ 0xe365, 0x1ead,
+ 0xe366, 0x17d6,
+ 0xe380, 0x17ef,
+ 0xe3c4, 0x1eae,
+ 0xe3c5, 0x1834,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe484, 0x1eaf,
+ 0xe485, 0x18b0,
+ 0xe489, 0x1eb0,
+ 0xe48a, 0x18b5,
+ 0xe492, 0x1eb1,
+ 0xe493, 0x18be,
+ 0xe4b2, 0x1eb2,
+ 0xe4b3, 0x18de,
+ 0xe4b9, 0x1eb3,
+ 0xe4ba, 0x18e5,
+ 0xe4f2, 0x1eb4,
+ 0xe4f3, 0x191e,
+ 0xe540, 0x1928,
+ 0xe541, 0x08f5,
+ 0xe542, 0x192a,
+ 0xe54d, 0x0f05,
+ 0xe54e, 0x1936,
+ 0xe55b, 0x1eb5,
+ 0xe55c, 0x1944,
+ 0xe579, 0x05a0,
+ 0xe57a, 0x1962,
+ 0xe580, 0x1967,
+ 0xe5a2, 0x0d1e,
+ 0xe5a3, 0x198a,
+ 0xe5a5, 0x1eb6,
+ 0xe5a6, 0x198d,
+ 0xe5bb, 0x1eb7,
+ 0xe5bc, 0x19a3,
+ 0xe5ed, 0x1eb8,
+ 0xe5ee, 0x19d5,
+ 0xe640, 0x19e4,
+ 0xe651, 0x1eb9,
+ 0xe652, 0x19f6,
+ 0xe67c, 0x060e,
+ 0xe67d, 0x1a21,
+ 0xe680, 0x1a23,
+ 0xe686, 0x1eba,
+ 0xe687, 0x1a2a,
+ 0xe696, 0x1ebb,
+ 0xe697, 0x1a3a,
+ 0xe6cb, 0x0aaa,
+ 0xe6cc, 0x1a6f,
+ 0xe6e7, 0x1ebc,
+ 0xe6e8, 0x1a8b,
+ 0xe6f2, 0x1ebd,
+ 0xe6f3, 0x1a96,
+ 0xe740, 0x1aa0,
+ 0xe76d, 0x1ebe,
+ 0xe76e, 0x1ace,
+ 0xe780, 0x1adf,
+ 0xe78c, 0x1ebf,
+ 0xe78d, 0x1aec,
+ 0xe78e, 0x1ec0,
+ 0xe78f, 0x1aee,
+ 0xe7a7, 0x1ec1,
+ 0xe7a8, 0x1b07,
+ 0xe7bb, 0x1ec2,
+ 0xe7bc, 0x1b1b,
+ 0xe7d5, 0x1ec3,
+ 0xe7d6, 0x1b35,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe885, 0x1ec4,
+ 0xe886, 0x1ba1,
+ 0xe8b1, 0x1ec5,
+ 0xe8b2, 0x1bcd,
+ 0xe8c3, 0x1ec6,
+ 0xe8c4, 0x1bdf,
+ 0xe8cf, 0x1ec7,
+ 0xe8d0, 0x1beb,
+ 0xe8d5, 0x1ec8,
+ 0xe8d6, 0x1bf1,
+ 0xe8f2, 0x0731,
+ 0xe8f3, 0x1ec9,
+ 0xe8f4, 0x1c0f,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xe9ab, 0x1eca,
+ 0xe9ac, 0x1c83,
+ 0xe9ba, 0x1ecb,
+ 0xe9bb, 0x1c92,
+ 0xe9cb, 0x0477,
+ 0xe9cc, 0x1ecc,
+ 0xe9cd, 0x1ca4,
+ 0xe9f2, 0x0529,
+ 0xe9f3, 0x1cca,
+ 0xea40, 0x1cd4,
+ 0xea70, 0x1ecd,
+ 0xea71, 0x1d05,
+ 0xea80, 0x1d13,
+ 0xea9d, 0x1ece,
+ 0xea9e, 0x1d31,
+ 0xed40, 0x20a7,
+ 0xed80, 0x20e6,
+ 0xedb4, 0x07c9,
+ 0xedb5, 0x211a,
+ 0xee40, 0x2162,
+ 0xee80, 0x21a1,
+ 0xeeef, 0x1f9c,
+ 0xeef9, 0x02ef,
+ 0xeefa, 0x1f45,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12ExtRKSJHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12ExtRKSJHMap2, 665
+};
+
+static Gushort japan12ExtRKSJVMap2[1408] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x8189, 0x1d36,
+ 0x818a, 0x02c2,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x8540, 0x00e8,
+ 0x8580, 0x0186,
+ 0x8581, 0x0128,
+ 0x859f, 0x0147,
+ 0x85de, 0x0187,
+ 0x8640, 0x01a6,
+ 0x8680, 0x01e5,
+ 0x8692, 0x0127,
+ 0x8693, 0x01f7,
+ 0x86a2, 0x1d37,
+ 0x8740, 0x1d83,
+ 0x875f, 0x1da1,
+ 0x877e, 0x2083,
+ 0x8780, 0x1db8,
+ 0x8790, 0x02fa,
+ 0x8791, 0x02f9,
+ 0x8792, 0x0301,
+ 0x8793, 0x1dc8,
+ 0x879a, 0x0300,
+ 0x879b, 0x1dcf,
+ 0x889f, 0x0465,
+ 0x88a0, 0x1dd1,
+ 0x88a1, 0x0467,
+ 0x88b1, 0x1ca2,
+ 0x88b2, 0x0478,
+ 0x88b9, 0x1dd2,
+ 0x88ba, 0x0480,
+ 0x88ec, 0x1dd3,
+ 0x88ed, 0x04b3,
+ 0x88f1, 0x1dd4,
+ 0x88f2, 0x04b8,
+ 0x88fa, 0x1dd5,
+ 0x88fb, 0x04c1,
+ 0x8940, 0x04c3,
+ 0x8949, 0x1dd6,
+ 0x894a, 0x04cd,
+ 0x8954, 0x1dd7,
+ 0x8955, 0x04d8,
+ 0x8958, 0x1dd8,
+ 0x8959, 0x04dc,
+ 0x895b, 0x1dd9,
+ 0x895d, 0x04e0,
+ 0x8961, 0x1ddb,
+ 0x8962, 0x04e5,
+ 0x8980, 0x0502,
+ 0x898b, 0x1ddc,
+ 0x898c, 0x050e,
+ 0x89a6, 0x1ddd,
+ 0x89a7, 0x1cc9,
+ 0x89a8, 0x1dde,
+ 0x89a9, 0x052b,
+ 0x89de, 0x1ddf,
+ 0x89df, 0x0561,
+ 0x89f8, 0x1de0,
+ 0x89f9, 0x057b,
+ 0x89fb, 0x1de1,
+ 0x89fc, 0x057e,
+ 0x8a40, 0x057f,
+ 0x8a41, 0x1de2,
+ 0x8a42, 0x0581,
+ 0x8a61, 0x1961,
+ 0x8a62, 0x05a1,
+ 0x8a68, 0x139f,
+ 0x8a69, 0x05a8,
+ 0x8a80, 0x05be,
+ 0x8a85, 0x1de3,
+ 0x8a86, 0x05c4,
+ 0x8a8b, 0x1de4,
+ 0x8a8c, 0x05ca,
+ 0x8a93, 0x1de5,
+ 0x8a94, 0x05d2,
+ 0x8a96, 0x1731,
+ 0x8a97, 0x05d5,
+ 0x8a9a, 0x1de6,
+ 0x8a9b, 0x05d9,
+ 0x8ac0, 0x1de7,
+ 0x8ac1, 0x1572,
+ 0x8ac2, 0x0600,
+ 0x8acb, 0x1de8,
+ 0x8acc, 0x060a,
+ 0x8ad0, 0x1a20,
+ 0x8ad1, 0x060f,
+ 0x8ae3, 0x1de9,
+ 0x8ae4, 0x0622,
+ 0x8b40, 0x063b,
+ 0x8b4a, 0x1dea,
+ 0x8b4b, 0x0646,
+ 0x8b5f, 0x1deb,
+ 0x8b60, 0x065b,
+ 0x8b80, 0x067a,
+ 0x8ba0, 0x1dec,
+ 0x8ba1, 0x069b,
+ 0x8ba8, 0x1ded,
+ 0x8ba9, 0x06a3,
+ 0x8bc4, 0x1d32,
+ 0x8bc5, 0x06bf,
+ 0x8bcd, 0x1dee,
+ 0x8bce, 0x06c8,
+ 0x8beb, 0x1def,
+ 0x8bec, 0x06e6,
+ 0x8bf2, 0x1df0,
+ 0x8bf3, 0x06ed,
+ 0x8bf9, 0x1df1,
+ 0x8bfa, 0x06f4,
+ 0x8bfb, 0x1df2,
+ 0x8bfc, 0x06f6,
+ 0x8c40, 0x06f7,
+ 0x8c43, 0x1df3,
+ 0x8c44, 0x06fb,
+ 0x8c56, 0x1df4,
+ 0x8c57, 0x070e,
+ 0x8c64, 0x1df5,
+ 0x8c65, 0x071c,
+ 0x8c6d, 0x1df6,
+ 0x8c6e, 0x0725,
+ 0x8c71, 0x1df7,
+ 0x8c72, 0x0729,
+ 0x8c74, 0x1df8,
+ 0x8c75, 0x072c,
+ 0x8c7a, 0x1c0d,
+ 0x8c7b, 0x0732,
+ 0x8c80, 0x0736,
+ 0x8c84, 0x1df9,
+ 0x8c85, 0x073b,
+ 0x8c91, 0x1dfa,
+ 0x8c92, 0x0748,
+ 0x8c99, 0x1dfb,
+ 0x8c9a, 0x0750,
+ 0x8c9e, 0x1dfc,
+ 0x8c9f, 0x0755,
+ 0x8cb2, 0x1dfd,
+ 0x8cb3, 0x0769,
+ 0x8cbf, 0x1dfe,
+ 0x8cc0, 0x0776,
+ 0x8d40, 0x07b3,
+ 0x8d4a, 0x1dff,
+ 0x8d4b, 0x07be,
+ 0x8d56, 0x1e00,
+ 0x8d57, 0x07ca,
+ 0x8d61, 0x1e01,
+ 0x8d62, 0x07d5,
+ 0x8d7b, 0x16dd,
+ 0x8d7c, 0x07ef,
+ 0x8d80, 0x07f2,
+ 0x8d8d, 0x1e02,
+ 0x8d8e, 0x0800,
+ 0x8d94, 0x1e03,
+ 0x8d95, 0x0807,
+ 0x8d99, 0x1e04,
+ 0x8d9a, 0x080c,
+ 0x8dd1, 0x1e05,
+ 0x8dd2, 0x0844,
+ 0x8de5, 0x1e06,
+ 0x8de6, 0x0858,
+ 0x8df2, 0x1e07,
+ 0x8df3, 0x0865,
+ 0x8e40, 0x086f,
+ 0x8e46, 0x1e08,
+ 0x8e47, 0x0876,
+ 0x8e49, 0x1e09,
+ 0x8e4a, 0x0879,
+ 0x8e4b, 0x1e0a,
+ 0x8e4c, 0x087b,
+ 0x8e58, 0x1e0b,
+ 0x8e59, 0x0888,
+ 0x8e80, 0x08ae,
+ 0x8eb6, 0x1e0c,
+ 0x8eb7, 0x08e5,
+ 0x8ec6, 0x1e0d,
+ 0x8ec7, 0x1929,
+ 0x8ec8, 0x08f6,
+ 0x8ed5, 0x1e0e,
+ 0x8ed6, 0x0904,
+ 0x8edb, 0x1e0f,
+ 0x8edd, 0x090b,
+ 0x8f40, 0x092b,
+ 0x8f4a, 0x1e11,
+ 0x8f4b, 0x0936,
+ 0x8f55, 0x1e12,
+ 0x8f56, 0x0941,
+ 0x8f80, 0x096a,
+ 0x8f8c, 0x1e13,
+ 0x8f8e, 0x0978,
+ 0x8f92, 0x1e15,
+ 0x8f94, 0x097e,
+ 0x8fa3, 0x1e17,
+ 0x8fa4, 0x098e,
+ 0x8fb1, 0x1e18,
+ 0x8fb2, 0x099c,
+ 0x8fbd, 0x1e19,
+ 0x8fbe, 0x09a8,
+ 0x8fd3, 0x1e1a,
+ 0x8fd4, 0x09be,
+ 0x8fdd, 0x1e1b,
+ 0x8fde, 0x09c8,
+ 0x8fe2, 0x1e1c,
+ 0x8fe3, 0x09cd,
+ 0x9040, 0x09e7,
+ 0x9049, 0x1e1d,
+ 0x904a, 0x09f1,
+ 0x9078, 0x1e1e,
+ 0x9079, 0x0a20,
+ 0x9080, 0x1e1f,
+ 0x9081, 0x0a27,
+ 0x9089, 0x1e20,
+ 0x908a, 0x0a30,
+ 0x90a0, 0x1e21,
+ 0x90a1, 0x0a47,
+ 0x90c0, 0x1e22,
+ 0x90c1, 0x0a67,
+ 0x90e4, 0x1e23,
+ 0x90e5, 0x0a8b,
+ 0x90ef, 0x1e24,
+ 0x90f1, 0x0a97,
+ 0x90f7, 0x1e26,
+ 0x90f9, 0x0a9f,
+ 0x9140, 0x0aa3,
+ 0x9146, 0x1e28,
+ 0x9147, 0x1a6e,
+ 0x9148, 0x0aab,
+ 0x9158, 0x1e29,
+ 0x9159, 0x0abc,
+ 0x916b, 0x1e2a,
+ 0x916c, 0x0acf,
+ 0x916e, 0x1e2b,
+ 0x916f, 0x0ad2,
+ 0x917e, 0x1e2c,
+ 0x9180, 0x0ae2,
+ 0x9189, 0x1e2d,
+ 0x918a, 0x0aec,
+ 0x91bb, 0x1e2e,
+ 0x91bc, 0x0b1e,
+ 0x91cb, 0x1e2f,
+ 0x91cc, 0x0b2e,
+ 0x91da, 0x1e30,
+ 0x91db, 0x0b3d,
+ 0x91e1, 0x1e31,
+ 0x91e2, 0x0b44,
+ 0x91ed, 0x1e32,
+ 0x91ee, 0x0b50,
+ 0x91f3, 0x1e33,
+ 0x91f5, 0x0b57,
+ 0x91fb, 0x1e35,
+ 0x91fc, 0x0b5e,
+ 0x9240, 0x0b5f,
+ 0x9246, 0x1e36,
+ 0x9247, 0x0b66,
+ 0x9248, 0x1e37,
+ 0x924a, 0x0b69,
+ 0x924c, 0x1e39,
+ 0x924e, 0x0b6d,
+ 0x925c, 0x1e3b,
+ 0x925d, 0x0b7c,
+ 0x9280, 0x0b9e,
+ 0x9290, 0x1e3c,
+ 0x9291, 0x0baf,
+ 0x9295, 0x1e3d,
+ 0x9296, 0x0bb4,
+ 0x929c, 0x1e3e,
+ 0x929d, 0x0bbb,
+ 0x92bb, 0x1e3f,
+ 0x92bc, 0x0bda,
+ 0x92c6, 0x1e40,
+ 0x92c7, 0x0be5,
+ 0x92c8, 0x1e41,
+ 0x92c9, 0x0be7,
+ 0x92cb, 0x1e42,
+ 0x92cc, 0x0bea,
+ 0x92cd, 0x1e43,
+ 0x92ce, 0x0bec,
+ 0x92d9, 0x11b5,
+ 0x92da, 0x0bf8,
+ 0x9340, 0x0c1b,
+ 0x9341, 0x1e44,
+ 0x9342, 0x0c1d,
+ 0x9346, 0x1e45,
+ 0x9347, 0x0c22,
+ 0x934d, 0x1e46,
+ 0x934e, 0x0c29,
+ 0x9355, 0x1e47,
+ 0x9356, 0x0c31,
+ 0x935e, 0x1e48,
+ 0x935f, 0x0c3a,
+ 0x9367, 0x1e49,
+ 0x9368, 0x0c43,
+ 0x936a, 0x1e4a,
+ 0x936b, 0x0c46,
+ 0x9370, 0x1e4b,
+ 0x9372, 0x0c4d,
+ 0x9376, 0x16df,
+ 0x9377, 0x0c52,
+ 0x9380, 0x0c5a,
+ 0x9384, 0x1e4d,
+ 0x9385, 0x0c5f,
+ 0x938e, 0x1450,
+ 0x938f, 0x0c69,
+ 0x9393, 0x1536,
+ 0x9394, 0x0c6e,
+ 0x9398, 0x1e4e,
+ 0x9399, 0x0c73,
+ 0x93bc, 0x1e4f,
+ 0x93bd, 0x0c97,
+ 0x93c0, 0x1e50,
+ 0x93c1, 0x0c9b,
+ 0x93d2, 0x1e51,
+ 0x93d4, 0x0cae,
+ 0x93d9, 0x1e53,
+ 0x93db, 0x0cb5,
+ 0x93df, 0x1e55,
+ 0x93e0, 0x0cba,
+ 0x93e4, 0x1e56,
+ 0x93e6, 0x0cc0,
+ 0x93e8, 0x1e58,
+ 0x93e9, 0x0cc3,
+ 0x93f4, 0x1aed,
+ 0x93f5, 0x0ccf,
+ 0x9440, 0x0cd7,
+ 0x9448, 0x1e59,
+ 0x9449, 0x0ce0,
+ 0x9458, 0x1e5a,
+ 0x9459, 0x0cf0,
+ 0x9476, 0x1e5b,
+ 0x9477, 0x0d0e,
+ 0x9480, 0x0d16,
+ 0x9487, 0x1e5c,
+ 0x9488, 0x1989,
+ 0x9489, 0x1e5d,
+ 0x948a, 0x0d20,
+ 0x948d, 0x1e5e,
+ 0x948e, 0x0d24,
+ 0x94a2, 0x1e5f,
+ 0x94a3, 0x0d39,
+ 0x94ac, 0x1e60,
+ 0x94ad, 0x0d43,
+ 0x94ae, 0x1e61,
+ 0x94af, 0x0d45,
+ 0x94d2, 0x1e62,
+ 0x94d3, 0x0d69,
+ 0x94e0, 0x1e63,
+ 0x94e1, 0x0d77,
+ 0x94f3, 0x1e64,
+ 0x94f4, 0x0d8a,
+ 0x9540, 0x0d93,
+ 0x9541, 0x1e65,
+ 0x9543, 0x0d96,
+ 0x954e, 0x1e67,
+ 0x954f, 0x143b,
+ 0x9550, 0x0da3,
+ 0x9551, 0x1e68,
+ 0x9552, 0x0da5,
+ 0x9554, 0x1e69,
+ 0x9555, 0x0da8,
+ 0x955f, 0x1e6a,
+ 0x9560, 0x0db3,
+ 0x956d, 0x1e6b,
+ 0x956e, 0x0dc1,
+ 0x9570, 0x1e6c,
+ 0x9571, 0x0dc4,
+ 0x9580, 0x0dd2,
+ 0x95c1, 0x1e6d,
+ 0x95c2, 0x0e14,
+ 0x95cb, 0x1e6e,
+ 0x95cc, 0x0e1e,
+ 0x95d8, 0x1e6f,
+ 0x95d9, 0x0e2b,
+ 0x95f7, 0x1e70,
+ 0x95f8, 0x0e4a,
+ 0x9640, 0x0e4f,
+ 0x9641, 0x1e71,
+ 0x9642, 0x0e51,
+ 0x9648, 0x1e72,
+ 0x9649, 0x0e58,
+ 0x966a, 0x1e73,
+ 0x966b, 0x0e7a,
+ 0x9680, 0x0e8e,
+ 0x968a, 0x1d33,
+ 0x968b, 0x0e99,
+ 0x9690, 0x1e74,
+ 0x9691, 0x0e9f,
+ 0x9699, 0x102f,
+ 0x969a, 0x0ea8,
+ 0x96cb, 0x1e75,
+ 0x96cc, 0x0eda,
+ 0x96d7, 0x1e76,
+ 0x96d8, 0x0ee6,
+ 0x96dd, 0x1e77,
+ 0x96de, 0x0eec,
+ 0x96e0, 0x1e78,
+ 0x96e1, 0x0eef,
+ 0x96f7, 0x1935,
+ 0x96f8, 0x1e79,
+ 0x96f9, 0x0f07,
+ 0x96fa, 0x1e7a,
+ 0x96fb, 0x0f09,
+ 0x96fc, 0x1e7b,
+ 0x9740, 0x0f0b,
+ 0x9751, 0x1e7c,
+ 0x9752, 0x0f1d,
+ 0x976f, 0x1e7d,
+ 0x9770, 0x0f3b,
+ 0x9773, 0x1e7e,
+ 0x9774, 0x0f3f,
+ 0x9779, 0x1d34,
+ 0x977a, 0x0f45,
+ 0x9780, 0x0f4a,
+ 0x9789, 0x1e7f,
+ 0x978a, 0x0f54,
+ 0x97c9, 0x1e80,
+ 0x97ca, 0x0f94,
+ 0x97f8, 0x1e81,
+ 0x97fa, 0x0fc4,
+ 0x9840, 0x1e83,
+ 0x9841, 0x0fc8,
+ 0x9850, 0x1e84,
+ 0x9851, 0x0fd8,
+ 0x9855, 0x1777,
+ 0x9856, 0x0fdd,
+ 0x9858, 0x1e85,
+ 0x9859, 0x0fe0,
+ 0x989f, 0x0ffa,
+ 0x98d4, 0x0ea7,
+ 0x98d5, 0x1030,
+ 0x9940, 0x1058,
+ 0x995c, 0x1e86,
+ 0x995d, 0x1075,
+ 0x9966, 0x1e87,
+ 0x9967, 0x107f,
+ 0x996a, 0x1e88,
+ 0x996b, 0x1083,
+ 0x996c, 0x1e89,
+ 0x996d, 0x1085,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a4f, 0x1e8a,
+ 0x9a50, 0x1124,
+ 0x9a59, 0x1e8b,
+ 0x9a5a, 0x112e,
+ 0x9a6f, 0x1e8c,
+ 0x9a70, 0x1144,
+ 0x9a7d, 0x1e8d,
+ 0x9a7e, 0x1152,
+ 0x9a80, 0x1153,
+ 0x9a8b, 0x1e8e,
+ 0x9a8c, 0x115f,
+ 0x9ac2, 0x1e8f,
+ 0x9ac3, 0x1196,
+ 0x9ae2, 0x0bf7,
+ 0x9ae3, 0x11b6,
+ 0x9b40, 0x11d0,
+ 0x9b5c, 0x1e90,
+ 0x9b5d, 0x11ed,
+ 0x9b80, 0x120f,
+ 0x9b83, 0x1e91,
+ 0x9b84, 0x1213,
+ 0x9ba0, 0x1e92,
+ 0x9ba1, 0x1230,
+ 0x9bf0, 0x1e93,
+ 0x9bf1, 0x1280,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9ca2, 0x1e94,
+ 0x9ca3, 0x12ee,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1e95,
+ 0x9d81, 0x1388,
+ 0x9d8c, 0x1e96,
+ 0x9d8d, 0x1394,
+ 0x9d98, 0x05a7,
+ 0x9d99, 0x13a0,
+ 0x9db7, 0x1e97,
+ 0x9db8, 0x13bf,
+ 0x9dcb, 0x1e98,
+ 0x9dcc, 0x13d3,
+ 0x9e40, 0x1404,
+ 0x9e64, 0x1e99,
+ 0x9e65, 0x1429,
+ 0x9e69, 0x1e9a,
+ 0x9e6a, 0x142e,
+ 0x9e77, 0x0da2,
+ 0x9e78, 0x143c,
+ 0x9e80, 0x1443,
+ 0x9e8b, 0x1e9b,
+ 0x9e8c, 0x144f,
+ 0x9e8d, 0x0c68,
+ 0x9e8e, 0x1451,
+ 0x9e94, 0x1e9c,
+ 0x9e95, 0x1458,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0x9fb7, 0x0c6d,
+ 0x9fb8, 0x1537,
+ 0x9fce, 0x1e9d,
+ 0x9fcf, 0x154e,
+ 0x9ff3, 0x05ff,
+ 0x9ff4, 0x1573,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe093, 0x1e9e,
+ 0xe094, 0x15cf,
+ 0xe0a4, 0x1e9f,
+ 0xe0a5, 0x15e0,
+ 0xe0dd, 0x1ea0,
+ 0xe0de, 0x1619,
+ 0xe0f4, 0x1d35,
+ 0xe0f5, 0x1630,
+ 0xe140, 0x1638,
+ 0xe14a, 0x1ea1,
+ 0xe14b, 0x1643,
+ 0xe14f, 0x1ea2,
+ 0xe151, 0x1649,
+ 0xe180, 0x1677,
+ 0xe1a9, 0x1ea4,
+ 0xe1aa, 0x16a1,
+ 0xe1e6, 0x07ee,
+ 0xe1e7, 0x16de,
+ 0xe1e8, 0x0c51,
+ 0xe1e9, 0x16e0,
+ 0xe1ed, 0x1ea5,
+ 0xe1ee, 0x16e5,
+ 0xe240, 0x16f4,
+ 0xe269, 0x1ea6,
+ 0xe26a, 0x171e,
+ 0xe273, 0x1ea7,
+ 0xe274, 0x1728,
+ 0xe27d, 0x05d4,
+ 0xe27e, 0x1732,
+ 0xe280, 0x1733,
+ 0xe2b7, 0x1ea8,
+ 0xe2b8, 0x176b,
+ 0xe2c4, 0x0fdc,
+ 0xe2c5, 0x1778,
+ 0xe2e2, 0x1ea9,
+ 0xe2e3, 0x1796,
+ 0xe2ec, 0x1eaa,
+ 0xe2ed, 0x17a0,
+ 0xe340, 0x17b0,
+ 0xe358, 0x1eab,
+ 0xe359, 0x17c9,
+ 0xe35a, 0x1eac,
+ 0xe35b, 0x17cb,
+ 0xe365, 0x1ead,
+ 0xe366, 0x17d6,
+ 0xe380, 0x17ef,
+ 0xe3c4, 0x1eae,
+ 0xe3c5, 0x1834,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe484, 0x1eaf,
+ 0xe485, 0x18b0,
+ 0xe489, 0x1eb0,
+ 0xe48a, 0x18b5,
+ 0xe492, 0x1eb1,
+ 0xe493, 0x18be,
+ 0xe4b2, 0x1eb2,
+ 0xe4b3, 0x18de,
+ 0xe4b9, 0x1eb3,
+ 0xe4ba, 0x18e5,
+ 0xe4f2, 0x1eb4,
+ 0xe4f3, 0x191e,
+ 0xe540, 0x1928,
+ 0xe541, 0x08f5,
+ 0xe542, 0x192a,
+ 0xe54d, 0x0f05,
+ 0xe54e, 0x1936,
+ 0xe55b, 0x1eb5,
+ 0xe55c, 0x1944,
+ 0xe579, 0x05a0,
+ 0xe57a, 0x1962,
+ 0xe580, 0x1967,
+ 0xe5a2, 0x0d1e,
+ 0xe5a3, 0x198a,
+ 0xe5a5, 0x1eb6,
+ 0xe5a6, 0x198d,
+ 0xe5bb, 0x1eb7,
+ 0xe5bc, 0x19a3,
+ 0xe5ed, 0x1eb8,
+ 0xe5ee, 0x19d5,
+ 0xe640, 0x19e4,
+ 0xe651, 0x1eb9,
+ 0xe652, 0x19f6,
+ 0xe67c, 0x060e,
+ 0xe67d, 0x1a21,
+ 0xe680, 0x1a23,
+ 0xe686, 0x1eba,
+ 0xe687, 0x1a2a,
+ 0xe696, 0x1ebb,
+ 0xe697, 0x1a3a,
+ 0xe6cb, 0x0aaa,
+ 0xe6cc, 0x1a6f,
+ 0xe6e7, 0x1ebc,
+ 0xe6e8, 0x1a8b,
+ 0xe6f2, 0x1ebd,
+ 0xe6f3, 0x1a96,
+ 0xe740, 0x1aa0,
+ 0xe76d, 0x1ebe,
+ 0xe76e, 0x1ace,
+ 0xe780, 0x1adf,
+ 0xe78c, 0x1ebf,
+ 0xe78d, 0x1aec,
+ 0xe78e, 0x1ec0,
+ 0xe78f, 0x1aee,
+ 0xe7a7, 0x1ec1,
+ 0xe7a8, 0x1b07,
+ 0xe7bb, 0x1ec2,
+ 0xe7bc, 0x1b1b,
+ 0xe7d5, 0x1ec3,
+ 0xe7d6, 0x1b35,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe885, 0x1ec4,
+ 0xe886, 0x1ba1,
+ 0xe8b1, 0x1ec5,
+ 0xe8b2, 0x1bcd,
+ 0xe8c3, 0x1ec6,
+ 0xe8c4, 0x1bdf,
+ 0xe8cf, 0x1ec7,
+ 0xe8d0, 0x1beb,
+ 0xe8d5, 0x1ec8,
+ 0xe8d6, 0x1bf1,
+ 0xe8f2, 0x0731,
+ 0xe8f3, 0x1ec9,
+ 0xe8f4, 0x1c0f,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xe9ab, 0x1eca,
+ 0xe9ac, 0x1c83,
+ 0xe9ba, 0x1ecb,
+ 0xe9bb, 0x1c92,
+ 0xe9cb, 0x0477,
+ 0xe9cc, 0x1ecc,
+ 0xe9cd, 0x1ca4,
+ 0xe9f2, 0x0529,
+ 0xe9f3, 0x1cca,
+ 0xea40, 0x1cd4,
+ 0xea70, 0x1ecd,
+ 0xea71, 0x1d05,
+ 0xea80, 0x1d13,
+ 0xea9d, 0x1ece,
+ 0xea9e, 0x1d31,
+ 0xed40, 0x20a7,
+ 0xed80, 0x20e6,
+ 0xedb4, 0x07c9,
+ 0xedb5, 0x211a,
+ 0xee40, 0x2162,
+ 0xee80, 0x21a1,
+ 0xeeef, 0x1f9c,
+ 0xeef9, 0x02ef,
+ 0xeefa, 0x1f45,
+ 0x8141, 0x1ecf,
+ 0x8143, 0x204c,
+ 0x8144, 0x2052,
+ 0x814a, 0x2050,
+ 0x814b, 0x204f,
+ 0x815b, 0x1ed3,
+ 0x8160, 0x1ed6,
+ 0x8165, 0x2059,
+ 0x8166, 0x2054,
+ 0x8167, 0x2057,
+ 0x8168, 0x2056,
+ 0x8169, 0x1edb,
+ 0x818b, 0x204d,
+ 0x818c, 0x2051,
+ 0x818d, 0x205b,
+ 0x81ac, 0x204e,
+ 0x829f, 0x1eee,
+ 0x82a1, 0x1eef,
+ 0x82a3, 0x1ef0,
+ 0x82a5, 0x1ef1,
+ 0x82a7, 0x1ef2,
+ 0x82c1, 0x1ef3,
+ 0x82e1, 0x1ef4,
+ 0x82e3, 0x1ef5,
+ 0x82e5, 0x1ef6,
+ 0x82ec, 0x1ef7,
+ 0x8340, 0x1ef8,
+ 0x8342, 0x1ef9,
+ 0x8344, 0x1efa,
+ 0x8346, 0x1efb,
+ 0x8348, 0x1efc,
+ 0x8362, 0x1efd,
+ 0x8383, 0x1efe,
+ 0x8385, 0x1eff,
+ 0x8387, 0x1f00,
+ 0x838e, 0x1f01,
+ 0x8395, 0x1f02,
+ 0x875f, 0x1f04,
+ 0x8780, 0x1f14,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12ExtRKSJVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12ExtRKSJVMap2, 704
+};
+
+static Gushort japan12ExtVMap2[1404] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0279,
+ 0x2169, 0x1d36,
+ 0x216a, 0x02c2,
+ 0x2221, 0x02d7,
+ 0x2330, 0x030c,
+ 0x2341, 0x0316,
+ 0x2361, 0x0330,
+ 0x2421, 0x034a,
+ 0x2521, 0x039d,
+ 0x2621, 0x03f3,
+ 0x2641, 0x040b,
+ 0x2721, 0x0423,
+ 0x2751, 0x0444,
+ 0x2921, 0x00e8,
+ 0x2960, 0x0186,
+ 0x2961, 0x0128,
+ 0x2a21, 0x0147,
+ 0x2a60, 0x0187,
+ 0x2b21, 0x01a6,
+ 0x2b72, 0x0127,
+ 0x2b73, 0x01f7,
+ 0x2c24, 0x1d37,
+ 0x2d21, 0x1d83,
+ 0x2d40, 0x1da1,
+ 0x2d5f, 0x2083,
+ 0x2d60, 0x1db8,
+ 0x2d70, 0x02fa,
+ 0x2d71, 0x02f9,
+ 0x2d72, 0x0301,
+ 0x2d73, 0x1dc8,
+ 0x2d7a, 0x0300,
+ 0x2d7b, 0x1dcf,
+ 0x3021, 0x0465,
+ 0x3022, 0x1dd1,
+ 0x3023, 0x0467,
+ 0x3033, 0x1ca2,
+ 0x3034, 0x0478,
+ 0x303b, 0x1dd2,
+ 0x303c, 0x0480,
+ 0x306e, 0x1dd3,
+ 0x306f, 0x04b3,
+ 0x3073, 0x1dd4,
+ 0x3074, 0x04b8,
+ 0x307c, 0x1dd5,
+ 0x307d, 0x04c1,
+ 0x3121, 0x04c3,
+ 0x312a, 0x1dd6,
+ 0x312b, 0x04cd,
+ 0x3135, 0x1dd7,
+ 0x3136, 0x04d8,
+ 0x3139, 0x1dd8,
+ 0x313a, 0x04dc,
+ 0x313c, 0x1dd9,
+ 0x313e, 0x04e0,
+ 0x3142, 0x1ddb,
+ 0x3143, 0x04e5,
+ 0x316b, 0x1ddc,
+ 0x316c, 0x050e,
+ 0x3221, 0x0521,
+ 0x3228, 0x1ddd,
+ 0x3229, 0x1cc9,
+ 0x322a, 0x1dde,
+ 0x322b, 0x052b,
+ 0x3260, 0x1ddf,
+ 0x3261, 0x0561,
+ 0x327a, 0x1de0,
+ 0x327b, 0x057b,
+ 0x327d, 0x1de1,
+ 0x327e, 0x057e,
+ 0x3321, 0x057f,
+ 0x3322, 0x1de2,
+ 0x3323, 0x0581,
+ 0x3342, 0x1961,
+ 0x3343, 0x05a1,
+ 0x3349, 0x139f,
+ 0x334a, 0x05a8,
+ 0x3365, 0x1de3,
+ 0x3366, 0x05c4,
+ 0x336b, 0x1de4,
+ 0x336c, 0x05ca,
+ 0x3373, 0x1de5,
+ 0x3374, 0x05d2,
+ 0x3376, 0x1731,
+ 0x3377, 0x05d5,
+ 0x337a, 0x1de6,
+ 0x337b, 0x05d9,
+ 0x3421, 0x05dd,
+ 0x3442, 0x1de7,
+ 0x3443, 0x1572,
+ 0x3444, 0x0600,
+ 0x344d, 0x1de8,
+ 0x344e, 0x060a,
+ 0x3452, 0x1a20,
+ 0x3453, 0x060f,
+ 0x3465, 0x1de9,
+ 0x3466, 0x0622,
+ 0x3521, 0x063b,
+ 0x352b, 0x1dea,
+ 0x352c, 0x0646,
+ 0x3540, 0x1deb,
+ 0x3541, 0x065b,
+ 0x3621, 0x0699,
+ 0x3622, 0x1dec,
+ 0x3623, 0x069b,
+ 0x362a, 0x1ded,
+ 0x362b, 0x06a3,
+ 0x3646, 0x1d32,
+ 0x3647, 0x06bf,
+ 0x364f, 0x1dee,
+ 0x3650, 0x06c8,
+ 0x366d, 0x1def,
+ 0x366e, 0x06e6,
+ 0x3674, 0x1df0,
+ 0x3675, 0x06ed,
+ 0x367b, 0x1df1,
+ 0x367c, 0x06f4,
+ 0x367d, 0x1df2,
+ 0x367e, 0x06f6,
+ 0x3721, 0x06f7,
+ 0x3724, 0x1df3,
+ 0x3725, 0x06fb,
+ 0x3737, 0x1df4,
+ 0x3738, 0x070e,
+ 0x3745, 0x1df5,
+ 0x3746, 0x071c,
+ 0x374e, 0x1df6,
+ 0x374f, 0x0725,
+ 0x3752, 0x1df7,
+ 0x3753, 0x0729,
+ 0x3755, 0x1df8,
+ 0x3756, 0x072c,
+ 0x375b, 0x1c0d,
+ 0x375c, 0x0732,
+ 0x3764, 0x1df9,
+ 0x3765, 0x073b,
+ 0x3771, 0x1dfa,
+ 0x3772, 0x0748,
+ 0x3779, 0x1dfb,
+ 0x377a, 0x0750,
+ 0x377e, 0x1dfc,
+ 0x3821, 0x0755,
+ 0x3834, 0x1dfd,
+ 0x3835, 0x0769,
+ 0x3841, 0x1dfe,
+ 0x3842, 0x0776,
+ 0x3921, 0x07b3,
+ 0x392b, 0x1dff,
+ 0x392c, 0x07be,
+ 0x3937, 0x1e00,
+ 0x3938, 0x07ca,
+ 0x3942, 0x1e01,
+ 0x3943, 0x07d5,
+ 0x395c, 0x16dd,
+ 0x395d, 0x07ef,
+ 0x396d, 0x1e02,
+ 0x396e, 0x0800,
+ 0x3974, 0x1e03,
+ 0x3975, 0x0807,
+ 0x3979, 0x1e04,
+ 0x397a, 0x080c,
+ 0x3a21, 0x0811,
+ 0x3a53, 0x1e05,
+ 0x3a54, 0x0844,
+ 0x3a67, 0x1e06,
+ 0x3a68, 0x0858,
+ 0x3a74, 0x1e07,
+ 0x3a75, 0x0865,
+ 0x3b21, 0x086f,
+ 0x3b27, 0x1e08,
+ 0x3b28, 0x0876,
+ 0x3b2a, 0x1e09,
+ 0x3b2b, 0x0879,
+ 0x3b2c, 0x1e0a,
+ 0x3b2d, 0x087b,
+ 0x3b39, 0x1e0b,
+ 0x3b3a, 0x0888,
+ 0x3c21, 0x08cd,
+ 0x3c38, 0x1e0c,
+ 0x3c39, 0x08e5,
+ 0x3c48, 0x1e0d,
+ 0x3c49, 0x1929,
+ 0x3c4a, 0x08f6,
+ 0x3c57, 0x1e0e,
+ 0x3c58, 0x0904,
+ 0x3c5d, 0x1e0f,
+ 0x3c5f, 0x090b,
+ 0x3d21, 0x092b,
+ 0x3d2b, 0x1e11,
+ 0x3d2c, 0x0936,
+ 0x3d36, 0x1e12,
+ 0x3d37, 0x0941,
+ 0x3d6c, 0x1e13,
+ 0x3d6e, 0x0978,
+ 0x3d72, 0x1e15,
+ 0x3d74, 0x097e,
+ 0x3e21, 0x0989,
+ 0x3e25, 0x1e17,
+ 0x3e26, 0x098e,
+ 0x3e33, 0x1e18,
+ 0x3e34, 0x099c,
+ 0x3e3f, 0x1e19,
+ 0x3e40, 0x09a8,
+ 0x3e55, 0x1e1a,
+ 0x3e56, 0x09be,
+ 0x3e5f, 0x1e1b,
+ 0x3e60, 0x09c8,
+ 0x3e64, 0x1e1c,
+ 0x3e65, 0x09cd,
+ 0x3f21, 0x09e7,
+ 0x3f2a, 0x1e1d,
+ 0x3f2b, 0x09f1,
+ 0x3f59, 0x1e1e,
+ 0x3f5a, 0x0a20,
+ 0x3f60, 0x1e1f,
+ 0x3f61, 0x0a27,
+ 0x3f69, 0x1e20,
+ 0x3f6a, 0x0a30,
+ 0x4021, 0x0a45,
+ 0x4022, 0x1e21,
+ 0x4023, 0x0a47,
+ 0x4042, 0x1e22,
+ 0x4043, 0x0a67,
+ 0x4066, 0x1e23,
+ 0x4067, 0x0a8b,
+ 0x4071, 0x1e24,
+ 0x4073, 0x0a97,
+ 0x4079, 0x1e26,
+ 0x407b, 0x0a9f,
+ 0x4121, 0x0aa3,
+ 0x4127, 0x1e28,
+ 0x4128, 0x1a6e,
+ 0x4129, 0x0aab,
+ 0x4139, 0x1e29,
+ 0x413a, 0x0abc,
+ 0x414c, 0x1e2a,
+ 0x414d, 0x0acf,
+ 0x414f, 0x1e2b,
+ 0x4150, 0x0ad2,
+ 0x415f, 0x1e2c,
+ 0x4160, 0x0ae2,
+ 0x4169, 0x1e2d,
+ 0x416a, 0x0aec,
+ 0x4221, 0x0b01,
+ 0x423d, 0x1e2e,
+ 0x423e, 0x0b1e,
+ 0x424d, 0x1e2f,
+ 0x424e, 0x0b2e,
+ 0x425c, 0x1e30,
+ 0x425d, 0x0b3d,
+ 0x4263, 0x1e31,
+ 0x4264, 0x0b44,
+ 0x426f, 0x1e32,
+ 0x4270, 0x0b50,
+ 0x4275, 0x1e33,
+ 0x4277, 0x0b57,
+ 0x427d, 0x1e35,
+ 0x427e, 0x0b5e,
+ 0x4321, 0x0b5f,
+ 0x4327, 0x1e36,
+ 0x4328, 0x0b66,
+ 0x4329, 0x1e37,
+ 0x432b, 0x0b69,
+ 0x432d, 0x1e39,
+ 0x432f, 0x0b6d,
+ 0x433d, 0x1e3b,
+ 0x433e, 0x0b7c,
+ 0x4370, 0x1e3c,
+ 0x4371, 0x0baf,
+ 0x4375, 0x1e3d,
+ 0x4376, 0x0bb4,
+ 0x437c, 0x1e3e,
+ 0x437d, 0x0bbb,
+ 0x4421, 0x0bbd,
+ 0x443d, 0x1e3f,
+ 0x443e, 0x0bda,
+ 0x4448, 0x1e40,
+ 0x4449, 0x0be5,
+ 0x444a, 0x1e41,
+ 0x444b, 0x0be7,
+ 0x444d, 0x1e42,
+ 0x444e, 0x0bea,
+ 0x444f, 0x1e43,
+ 0x4450, 0x0bec,
+ 0x445b, 0x11b5,
+ 0x445c, 0x0bf8,
+ 0x4521, 0x0c1b,
+ 0x4522, 0x1e44,
+ 0x4523, 0x0c1d,
+ 0x4527, 0x1e45,
+ 0x4528, 0x0c22,
+ 0x452e, 0x1e46,
+ 0x452f, 0x0c29,
+ 0x4536, 0x1e47,
+ 0x4537, 0x0c31,
+ 0x453f, 0x1e48,
+ 0x4540, 0x0c3a,
+ 0x4548, 0x1e49,
+ 0x4549, 0x0c43,
+ 0x454b, 0x1e4a,
+ 0x454c, 0x0c46,
+ 0x4551, 0x1e4b,
+ 0x4553, 0x0c4d,
+ 0x4557, 0x16df,
+ 0x4558, 0x0c52,
+ 0x4564, 0x1e4d,
+ 0x4565, 0x0c5f,
+ 0x456e, 0x1450,
+ 0x456f, 0x0c69,
+ 0x4573, 0x1536,
+ 0x4574, 0x0c6e,
+ 0x4578, 0x1e4e,
+ 0x4579, 0x0c73,
+ 0x4621, 0x0c79,
+ 0x463e, 0x1e4f,
+ 0x463f, 0x0c97,
+ 0x4642, 0x1e50,
+ 0x4643, 0x0c9b,
+ 0x4654, 0x1e51,
+ 0x4656, 0x0cae,
+ 0x465b, 0x1e53,
+ 0x465d, 0x0cb5,
+ 0x4661, 0x1e55,
+ 0x4662, 0x0cba,
+ 0x4666, 0x1e56,
+ 0x4668, 0x0cc0,
+ 0x466a, 0x1e58,
+ 0x466b, 0x0cc3,
+ 0x4676, 0x1aed,
+ 0x4677, 0x0ccf,
+ 0x4721, 0x0cd7,
+ 0x4729, 0x1e59,
+ 0x472a, 0x0ce0,
+ 0x4739, 0x1e5a,
+ 0x473a, 0x0cf0,
+ 0x4757, 0x1e5b,
+ 0x4758, 0x0d0e,
+ 0x4767, 0x1e5c,
+ 0x4768, 0x1989,
+ 0x4769, 0x1e5d,
+ 0x476a, 0x0d20,
+ 0x476d, 0x1e5e,
+ 0x476e, 0x0d24,
+ 0x4821, 0x0d35,
+ 0x4824, 0x1e5f,
+ 0x4825, 0x0d39,
+ 0x482e, 0x1e60,
+ 0x482f, 0x0d43,
+ 0x4830, 0x1e61,
+ 0x4831, 0x0d45,
+ 0x4854, 0x1e62,
+ 0x4855, 0x0d69,
+ 0x4862, 0x1e63,
+ 0x4863, 0x0d77,
+ 0x4875, 0x1e64,
+ 0x4876, 0x0d8a,
+ 0x4921, 0x0d93,
+ 0x4922, 0x1e65,
+ 0x4924, 0x0d96,
+ 0x492f, 0x1e67,
+ 0x4930, 0x143b,
+ 0x4931, 0x0da3,
+ 0x4932, 0x1e68,
+ 0x4933, 0x0da5,
+ 0x4935, 0x1e69,
+ 0x4936, 0x0da8,
+ 0x4940, 0x1e6a,
+ 0x4941, 0x0db3,
+ 0x494e, 0x1e6b,
+ 0x494f, 0x0dc1,
+ 0x4951, 0x1e6c,
+ 0x4952, 0x0dc4,
+ 0x4a21, 0x0df1,
+ 0x4a43, 0x1e6d,
+ 0x4a44, 0x0e14,
+ 0x4a4d, 0x1e6e,
+ 0x4a4e, 0x0e1e,
+ 0x4a5a, 0x1e6f,
+ 0x4a5b, 0x0e2b,
+ 0x4a79, 0x1e70,
+ 0x4a7a, 0x0e4a,
+ 0x4b21, 0x0e4f,
+ 0x4b22, 0x1e71,
+ 0x4b23, 0x0e51,
+ 0x4b29, 0x1e72,
+ 0x4b2a, 0x0e58,
+ 0x4b4b, 0x1e73,
+ 0x4b4c, 0x0e7a,
+ 0x4b6a, 0x1d33,
+ 0x4b6b, 0x0e99,
+ 0x4b70, 0x1e74,
+ 0x4b71, 0x0e9f,
+ 0x4b79, 0x102f,
+ 0x4b7a, 0x0ea8,
+ 0x4c21, 0x0ead,
+ 0x4c4d, 0x1e75,
+ 0x4c4e, 0x0eda,
+ 0x4c59, 0x1e76,
+ 0x4c5a, 0x0ee6,
+ 0x4c5f, 0x1e77,
+ 0x4c60, 0x0eec,
+ 0x4c62, 0x1e78,
+ 0x4c63, 0x0eef,
+ 0x4c79, 0x1935,
+ 0x4c7a, 0x1e79,
+ 0x4c7b, 0x0f07,
+ 0x4c7c, 0x1e7a,
+ 0x4c7d, 0x0f09,
+ 0x4c7e, 0x1e7b,
+ 0x4d21, 0x0f0b,
+ 0x4d32, 0x1e7c,
+ 0x4d33, 0x0f1d,
+ 0x4d50, 0x1e7d,
+ 0x4d51, 0x0f3b,
+ 0x4d54, 0x1e7e,
+ 0x4d55, 0x0f3f,
+ 0x4d5a, 0x1d34,
+ 0x4d5b, 0x0f45,
+ 0x4d69, 0x1e7f,
+ 0x4d6a, 0x0f54,
+ 0x4e21, 0x0f69,
+ 0x4e4b, 0x1e80,
+ 0x4e4c, 0x0f94,
+ 0x4e7a, 0x1e81,
+ 0x4e7c, 0x0fc4,
+ 0x4f21, 0x1e83,
+ 0x4f22, 0x0fc8,
+ 0x4f31, 0x1e84,
+ 0x4f32, 0x0fd8,
+ 0x4f36, 0x1777,
+ 0x4f37, 0x0fdd,
+ 0x4f39, 0x1e85,
+ 0x4f3a, 0x0fe0,
+ 0x5021, 0x0ffa,
+ 0x5056, 0x0ea7,
+ 0x5057, 0x1030,
+ 0x5121, 0x1058,
+ 0x513d, 0x1e86,
+ 0x513e, 0x1075,
+ 0x5147, 0x1e87,
+ 0x5148, 0x107f,
+ 0x514b, 0x1e88,
+ 0x514c, 0x1083,
+ 0x514d, 0x1e89,
+ 0x514e, 0x1085,
+ 0x5221, 0x10b6,
+ 0x5321, 0x1114,
+ 0x5330, 0x1e8a,
+ 0x5331, 0x1124,
+ 0x533a, 0x1e8b,
+ 0x533b, 0x112e,
+ 0x5350, 0x1e8c,
+ 0x5351, 0x1144,
+ 0x535e, 0x1e8d,
+ 0x535f, 0x1152,
+ 0x536b, 0x1e8e,
+ 0x536c, 0x115f,
+ 0x5421, 0x1172,
+ 0x5444, 0x1e8f,
+ 0x5445, 0x1196,
+ 0x5464, 0x0bf7,
+ 0x5465, 0x11b6,
+ 0x5521, 0x11d0,
+ 0x553d, 0x1e90,
+ 0x553e, 0x11ed,
+ 0x5563, 0x1e91,
+ 0x5564, 0x1213,
+ 0x5621, 0x122e,
+ 0x5622, 0x1e92,
+ 0x5623, 0x1230,
+ 0x5672, 0x1e93,
+ 0x5673, 0x1280,
+ 0x5721, 0x128c,
+ 0x5821, 0x12ea,
+ 0x5824, 0x1e94,
+ 0x5825, 0x12ee,
+ 0x5921, 0x1348,
+ 0x5960, 0x1e95,
+ 0x5961, 0x1388,
+ 0x596c, 0x1e96,
+ 0x596d, 0x1394,
+ 0x5978, 0x05a7,
+ 0x5979, 0x13a0,
+ 0x5a21, 0x13a6,
+ 0x5a39, 0x1e97,
+ 0x5a3a, 0x13bf,
+ 0x5a4d, 0x1e98,
+ 0x5a4e, 0x13d3,
+ 0x5b21, 0x1404,
+ 0x5b45, 0x1e99,
+ 0x5b46, 0x1429,
+ 0x5b4a, 0x1e9a,
+ 0x5b4b, 0x142e,
+ 0x5b58, 0x0da2,
+ 0x5b59, 0x143c,
+ 0x5b6b, 0x1e9b,
+ 0x5b6c, 0x144f,
+ 0x5b6d, 0x0c68,
+ 0x5b6e, 0x1451,
+ 0x5b74, 0x1e9c,
+ 0x5b75, 0x1458,
+ 0x5c21, 0x1462,
+ 0x5d21, 0x14c0,
+ 0x5e21, 0x151e,
+ 0x5e39, 0x0c6d,
+ 0x5e3a, 0x1537,
+ 0x5e50, 0x1e9d,
+ 0x5e51, 0x154e,
+ 0x5e75, 0x05ff,
+ 0x5e76, 0x1573,
+ 0x5f21, 0x157c,
+ 0x5f73, 0x1e9e,
+ 0x5f74, 0x15cf,
+ 0x6021, 0x15da,
+ 0x6026, 0x1e9f,
+ 0x6027, 0x15e0,
+ 0x605f, 0x1ea0,
+ 0x6060, 0x1619,
+ 0x6076, 0x1d35,
+ 0x6077, 0x1630,
+ 0x6121, 0x1638,
+ 0x612b, 0x1ea1,
+ 0x612c, 0x1643,
+ 0x6130, 0x1ea2,
+ 0x6132, 0x1649,
+ 0x6221, 0x1696,
+ 0x622b, 0x1ea4,
+ 0x622c, 0x16a1,
+ 0x6268, 0x07ee,
+ 0x6269, 0x16de,
+ 0x626a, 0x0c51,
+ 0x626b, 0x16e0,
+ 0x626f, 0x1ea5,
+ 0x6270, 0x16e5,
+ 0x6321, 0x16f4,
+ 0x634a, 0x1ea6,
+ 0x634b, 0x171e,
+ 0x6354, 0x1ea7,
+ 0x6355, 0x1728,
+ 0x635e, 0x05d4,
+ 0x635f, 0x1732,
+ 0x6421, 0x1752,
+ 0x6439, 0x1ea8,
+ 0x643a, 0x176b,
+ 0x6446, 0x0fdc,
+ 0x6447, 0x1778,
+ 0x6464, 0x1ea9,
+ 0x6465, 0x1796,
+ 0x646e, 0x1eaa,
+ 0x646f, 0x17a0,
+ 0x6521, 0x17b0,
+ 0x6539, 0x1eab,
+ 0x653a, 0x17c9,
+ 0x653b, 0x1eac,
+ 0x653c, 0x17cb,
+ 0x6546, 0x1ead,
+ 0x6547, 0x17d6,
+ 0x6621, 0x180e,
+ 0x6646, 0x1eae,
+ 0x6647, 0x1834,
+ 0x6721, 0x186c,
+ 0x6764, 0x1eaf,
+ 0x6765, 0x18b0,
+ 0x6769, 0x1eb0,
+ 0x676a, 0x18b5,
+ 0x6772, 0x1eb1,
+ 0x6773, 0x18be,
+ 0x6821, 0x18ca,
+ 0x6834, 0x1eb2,
+ 0x6835, 0x18de,
+ 0x683b, 0x1eb3,
+ 0x683c, 0x18e5,
+ 0x6874, 0x1eb4,
+ 0x6875, 0x191e,
+ 0x6921, 0x1928,
+ 0x6922, 0x08f5,
+ 0x6923, 0x192a,
+ 0x692e, 0x0f05,
+ 0x692f, 0x1936,
+ 0x693c, 0x1eb5,
+ 0x693d, 0x1944,
+ 0x695a, 0x05a0,
+ 0x695b, 0x1962,
+ 0x6a21, 0x1986,
+ 0x6a24, 0x0d1e,
+ 0x6a25, 0x198a,
+ 0x6a27, 0x1eb6,
+ 0x6a28, 0x198d,
+ 0x6a3d, 0x1eb7,
+ 0x6a3e, 0x19a3,
+ 0x6a6f, 0x1eb8,
+ 0x6a70, 0x19d5,
+ 0x6b21, 0x19e4,
+ 0x6b32, 0x1eb9,
+ 0x6b33, 0x19f6,
+ 0x6b5d, 0x060e,
+ 0x6b5e, 0x1a21,
+ 0x6b66, 0x1eba,
+ 0x6b67, 0x1a2a,
+ 0x6b76, 0x1ebb,
+ 0x6b77, 0x1a3a,
+ 0x6c21, 0x1a42,
+ 0x6c4d, 0x0aaa,
+ 0x6c4e, 0x1a6f,
+ 0x6c69, 0x1ebc,
+ 0x6c6a, 0x1a8b,
+ 0x6c74, 0x1ebd,
+ 0x6c75, 0x1a96,
+ 0x6d21, 0x1aa0,
+ 0x6d4e, 0x1ebe,
+ 0x6d4f, 0x1ace,
+ 0x6d6c, 0x1ebf,
+ 0x6d6d, 0x1aec,
+ 0x6d6e, 0x1ec0,
+ 0x6d6f, 0x1aee,
+ 0x6e21, 0x1afe,
+ 0x6e29, 0x1ec1,
+ 0x6e2a, 0x1b07,
+ 0x6e3d, 0x1ec2,
+ 0x6e3e, 0x1b1b,
+ 0x6e57, 0x1ec3,
+ 0x6e58, 0x1b35,
+ 0x6f21, 0x1b5c,
+ 0x6f65, 0x1ec4,
+ 0x6f66, 0x1ba1,
+ 0x7021, 0x1bba,
+ 0x7033, 0x1ec5,
+ 0x7034, 0x1bcd,
+ 0x7045, 0x1ec6,
+ 0x7046, 0x1bdf,
+ 0x7051, 0x1ec7,
+ 0x7052, 0x1beb,
+ 0x7057, 0x1ec8,
+ 0x7058, 0x1bf1,
+ 0x7074, 0x0731,
+ 0x7075, 0x1ec9,
+ 0x7076, 0x1c0f,
+ 0x7121, 0x1c18,
+ 0x7221, 0x1c76,
+ 0x722d, 0x1eca,
+ 0x722e, 0x1c83,
+ 0x723c, 0x1ecb,
+ 0x723d, 0x1c92,
+ 0x724d, 0x0477,
+ 0x724e, 0x1ecc,
+ 0x724f, 0x1ca4,
+ 0x7274, 0x0529,
+ 0x7275, 0x1cca,
+ 0x7321, 0x1cd4,
+ 0x7351, 0x1ecd,
+ 0x7352, 0x1d05,
+ 0x737d, 0x1ece,
+ 0x737e, 0x1d31,
+ 0x7921, 0x20a7,
+ 0x7a21, 0x2105,
+ 0x7a36, 0x07c9,
+ 0x7a37, 0x211a,
+ 0x7b21, 0x2162,
+ 0x7c21, 0x21c0,
+ 0x7c71, 0x1f9c,
+ 0x7c7b, 0x02ef,
+ 0x7c7c, 0x1f45,
+ 0x2122, 0x1ecf,
+ 0x2124, 0x204c,
+ 0x2125, 0x2052,
+ 0x212b, 0x2050,
+ 0x212c, 0x204f,
+ 0x213c, 0x1ed3,
+ 0x2141, 0x1ed6,
+ 0x2146, 0x2059,
+ 0x2147, 0x2054,
+ 0x2148, 0x2057,
+ 0x2149, 0x2056,
+ 0x214a, 0x1edb,
+ 0x216b, 0x204d,
+ 0x216c, 0x2051,
+ 0x216d, 0x205b,
+ 0x222e, 0x204e,
+ 0x2421, 0x1eee,
+ 0x2423, 0x1eef,
+ 0x2425, 0x1ef0,
+ 0x2427, 0x1ef1,
+ 0x2429, 0x1ef2,
+ 0x2443, 0x1ef3,
+ 0x2463, 0x1ef4,
+ 0x2465, 0x1ef5,
+ 0x2467, 0x1ef6,
+ 0x246e, 0x1ef7,
+ 0x2521, 0x1ef8,
+ 0x2523, 0x1ef9,
+ 0x2525, 0x1efa,
+ 0x2527, 0x1efb,
+ 0x2529, 0x1efc,
+ 0x2543, 0x1efd,
+ 0x2563, 0x1efe,
+ 0x2565, 0x1eff,
+ 0x2567, 0x1f00,
+ 0x256e, 0x1f01,
+ 0x2575, 0x1f02,
+ 0x2d40, 0x1f04,
+ 0x2d60, 0x1f14,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12ExtVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12ExtVMap2, 702
+};
+
+static Gushort japan12HMap2[240] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0279,
+ 0x2221, 0x02d7,
+ 0x223a, 0x02e5,
+ 0x224a, 0x02ed,
+ 0x225c, 0x02f4,
+ 0x2272, 0x0303,
+ 0x227e, 0x030b,
+ 0x2330, 0x030c,
+ 0x2341, 0x0316,
+ 0x2361, 0x0330,
+ 0x2421, 0x034a,
+ 0x2521, 0x039d,
+ 0x2621, 0x03f3,
+ 0x2641, 0x040b,
+ 0x2721, 0x0423,
+ 0x2751, 0x0444,
+ 0x2821, 0x1d37,
+ 0x2822, 0x1d39,
+ 0x2823, 0x1d43,
+ 0x2824, 0x1d47,
+ 0x2825, 0x1d4f,
+ 0x2826, 0x1d4b,
+ 0x2827, 0x1d53,
+ 0x2828, 0x1d63,
+ 0x2829, 0x1d5b,
+ 0x282a, 0x1d6b,
+ 0x282b, 0x1d73,
+ 0x282c, 0x1d38,
+ 0x282d, 0x1d3a,
+ 0x282e, 0x1d46,
+ 0x282f, 0x1d4a,
+ 0x2830, 0x1d52,
+ 0x2831, 0x1d4e,
+ 0x2832, 0x1d5a,
+ 0x2833, 0x1d6a,
+ 0x2834, 0x1d62,
+ 0x2835, 0x1d72,
+ 0x2836, 0x1d82,
+ 0x2837, 0x1d57,
+ 0x2838, 0x1d66,
+ 0x2839, 0x1d5f,
+ 0x283a, 0x1d6e,
+ 0x283b, 0x1d76,
+ 0x283c, 0x1d54,
+ 0x283d, 0x1d67,
+ 0x283e, 0x1d5c,
+ 0x283f, 0x1d6f,
+ 0x2840, 0x1d79,
+ 0x3021, 0x0465,
+ 0x3121, 0x04c3,
+ 0x3221, 0x0521,
+ 0x3321, 0x057f,
+ 0x3421, 0x05dd,
+ 0x3521, 0x063b,
+ 0x3621, 0x0699,
+ 0x3721, 0x06f7,
+ 0x3821, 0x0755,
+ 0x3921, 0x07b3,
+ 0x3a21, 0x0811,
+ 0x3b21, 0x086f,
+ 0x3c21, 0x08cd,
+ 0x3d21, 0x092b,
+ 0x3e21, 0x0989,
+ 0x3f21, 0x09e7,
+ 0x4021, 0x0a45,
+ 0x4121, 0x0aa3,
+ 0x4221, 0x0b01,
+ 0x4321, 0x0b5f,
+ 0x4421, 0x0bbd,
+ 0x4521, 0x0c1b,
+ 0x4621, 0x0c79,
+ 0x4721, 0x0cd7,
+ 0x4821, 0x0d35,
+ 0x4921, 0x0d93,
+ 0x4a21, 0x0df1,
+ 0x4b21, 0x0e4f,
+ 0x4c21, 0x0ead,
+ 0x4d21, 0x0f0b,
+ 0x4e21, 0x0f69,
+ 0x4f21, 0x0fc7,
+ 0x5021, 0x0ffa,
+ 0x5121, 0x1058,
+ 0x5221, 0x10b6,
+ 0x5321, 0x1114,
+ 0x5421, 0x1172,
+ 0x5521, 0x11d0,
+ 0x5621, 0x122e,
+ 0x5721, 0x128c,
+ 0x5821, 0x12ea,
+ 0x5921, 0x1348,
+ 0x5a21, 0x13a6,
+ 0x5b21, 0x1404,
+ 0x5c21, 0x1462,
+ 0x5d21, 0x14c0,
+ 0x5e21, 0x151e,
+ 0x5f21, 0x157c,
+ 0x6021, 0x15da,
+ 0x6121, 0x1638,
+ 0x6221, 0x1696,
+ 0x6321, 0x16f4,
+ 0x6421, 0x1752,
+ 0x6521, 0x17b0,
+ 0x6621, 0x180e,
+ 0x6721, 0x186c,
+ 0x6821, 0x18ca,
+ 0x6921, 0x1928,
+ 0x6a21, 0x1986,
+ 0x6b21, 0x19e4,
+ 0x6c21, 0x1a42,
+ 0x6d21, 0x1aa0,
+ 0x6e21, 0x1afe,
+ 0x6f21, 0x1b5c,
+ 0x7021, 0x1bba,
+ 0x7121, 0x1c18,
+ 0x7221, 0x1c76,
+ 0x7321, 0x1cd4,
+ 0x7421, 0x1d32,
+ 0x7425, 0x205c,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12HEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12HMap2, 120
+};
+
+static Gushort japan12HankakuMap2[4] = {
+ 0x0000, 0x0000,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12HankakuEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x00e7, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x0204, 0x0205,
+ 0x0206, 0x0207, 0x0208, 0x0209, 0x020a, 0x020b, 0x020c, 0x020d,
+ 0x0156, 0x020e, 0x020f, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214,
+ 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021a, 0x021b, 0x021c,
+ 0x0000, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x021d, 0x021e, 0x021f, 0x0220, 0x0221, 0x0222, 0x0223, 0x0224,
+ 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022a, 0x022b, 0x022c,
+ 0x022d, 0x022e, 0x022f, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234,
+ 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, 0x023a, 0x0184, 0x0185 },
+ japan12HankakuMap2, 2
+};
+
+static Gushort japan12HiraganaMap2[4] = {
+ 0x0000, 0x0000,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12HiraganaEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0203, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x0204, 0x0205,
+ 0x0206, 0x0207, 0x0208, 0x0209, 0x020a, 0x020b, 0x020c, 0x020d,
+ 0x0156, 0x020e, 0x020f, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214,
+ 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021a, 0x021b, 0x021c,
+ 0x021d, 0x021e, 0x021f, 0x0220, 0x0221, 0x0222, 0x0223, 0x0224,
+ 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022a, 0x022b, 0x022c,
+ 0x022d, 0x022e, 0x022f, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234,
+ 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, 0x023a, 0x0184, 0x0185,
+ 0x023b, 0x023c, 0x023d, 0x0000, 0x0000, 0x0000, 0x023e, 0x023f,
+ 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247,
+ 0x0248, 0x0249, 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f,
+ 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12HiraganaMap2, 2
+};
+
+static Gushort japan12KatakanaMap2[4] = {
+ 0x0000, 0x0000,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12KatakanaEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0187, 0x0188, 0x0189, 0x018a, 0x018b, 0x018c, 0x018d, 0x018e,
+ 0x018f, 0x0190, 0x0191, 0x0192, 0x0193, 0x0194, 0x0195, 0x0196,
+ 0x0197, 0x0198, 0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e,
+ 0x019f, 0x01a0, 0x01a1, 0x01a2, 0x01a3, 0x01a4, 0x01a5, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12KatakanaMap2, 2
+};
+
+static Gushort japan12NWPHMap2[1522] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0279,
+ 0x2169, 0x1d36,
+ 0x216a, 0x02c2,
+ 0x2221, 0x02d7,
+ 0x223a, 0x02e5,
+ 0x224a, 0x02ed,
+ 0x225c, 0x02f4,
+ 0x2272, 0x0303,
+ 0x227e, 0x030b,
+ 0x2330, 0x030c,
+ 0x2341, 0x0316,
+ 0x2361, 0x0330,
+ 0x2421, 0x034a,
+ 0x2521, 0x039d,
+ 0x2621, 0x03f3,
+ 0x2641, 0x040b,
+ 0x2721, 0x0423,
+ 0x2751, 0x0444,
+ 0x2921, 0x00e8,
+ 0x2960, 0x0186,
+ 0x2961, 0x0128,
+ 0x2a21, 0x0147,
+ 0x2a60, 0x0187,
+ 0x2b21, 0x01a6,
+ 0x2b72, 0x0127,
+ 0x2b73, 0x01f7,
+ 0x2c24, 0x1d37,
+ 0x2d21, 0x1d83,
+ 0x2d40, 0x1da1,
+ 0x2d60, 0x1db8,
+ 0x2d70, 0x02fa,
+ 0x2d71, 0x02f9,
+ 0x2d72, 0x0301,
+ 0x2d73, 0x1dc8,
+ 0x2d7a, 0x0300,
+ 0x2d7b, 0x1dcf,
+ 0x2e21, 0x0282,
+ 0x2e22, 0x02a1,
+ 0x2e23, 0x0305,
+ 0x2e24, 0x02c8,
+ 0x2e25, 0x02cb,
+ 0x2e26, 0x02cd,
+ 0x2e27, 0x029f,
+ 0x2e28, 0x02a2,
+ 0x2e2a, 0x02ce,
+ 0x2e2b, 0x02b4,
+ 0x2e2c, 0x027c,
+ 0x2e2d, 0x02b5,
+ 0x2e2e, 0x027d,
+ 0x2e2f, 0x0297,
+ 0x2e30, 0x030c,
+ 0x2e3a, 0x027f,
+ 0x2e3c, 0x02bb,
+ 0x2e3d, 0x02b9,
+ 0x2e3e, 0x02bc,
+ 0x2e3f, 0x0281,
+ 0x2e40, 0x02cf,
+ 0x2e41, 0x0316,
+ 0x2e5b, 0x02a6,
+ 0x2e5c, 0x02c7,
+ 0x2e5d, 0x02a7,
+ 0x2e5e, 0x0288,
+ 0x2e5f, 0x028a,
+ 0x2e60, 0x0286,
+ 0x2e61, 0x0330,
+ 0x2e7b, 0x02a8,
+ 0x2e7c, 0x029b,
+ 0x2e7d, 0x02a9,
+ 0x2e7e, 0x0289,
+ 0x2f21, 0x027b,
+ 0x2f22, 0x02ae,
+ 0x2f24, 0x027a,
+ 0x2f25, 0x027e,
+ 0x2f26, 0x03ee,
+ 0x2f27, 0x039d,
+ 0x2f28, 0x039f,
+ 0x2f29, 0x03a1,
+ 0x2f2a, 0x03a3,
+ 0x2f2b, 0x03a5,
+ 0x2f2c, 0x03df,
+ 0x2f2d, 0x03e1,
+ 0x2f2e, 0x03e3,
+ 0x2f2f, 0x03bf,
+ 0x2f30, 0x0294,
+ 0x2f31, 0x039e,
+ 0x2f32, 0x03a0,
+ 0x2f33, 0x03a2,
+ 0x2f34, 0x03a4,
+ 0x2f35, 0x03a6,
+ 0x2f37, 0x03a9,
+ 0x2f38, 0x03ab,
+ 0x2f39, 0x03ad,
+ 0x2f3a, 0x03af,
+ 0x2f3b, 0x03b1,
+ 0x2f3c, 0x03b3,
+ 0x2f3d, 0x03b5,
+ 0x2f3e, 0x03b7,
+ 0x2f3f, 0x03b9,
+ 0x2f40, 0x03bb,
+ 0x2f41, 0x03bd,
+ 0x2f42, 0x03c0,
+ 0x2f43, 0x03c2,
+ 0x2f44, 0x03c4,
+ 0x2f45, 0x03c6,
+ 0x2f4b, 0x03ce,
+ 0x2f4c, 0x03d1,
+ 0x2f4d, 0x03d4,
+ 0x2f4e, 0x03d7,
+ 0x2f4f, 0x03da,
+ 0x2f54, 0x03e0,
+ 0x2f55, 0x03e2,
+ 0x2f56, 0x03e4,
+ 0x2f5c, 0x03eb,
+ 0x2f5d, 0x03ef,
+ 0x2f5e, 0x0283,
+ 0x2f60, 0x03ec,
+ 0x2f62, 0x03ea,
+ 0x2f63, 0x03f1,
+ 0x2f65, 0x03f0,
+ 0x2f66, 0x03a8,
+ 0x2f67, 0x03aa,
+ 0x2f68, 0x03ac,
+ 0x2f69, 0x03ae,
+ 0x2f6a, 0x03b0,
+ 0x2f6b, 0x03b2,
+ 0x2f6c, 0x03b4,
+ 0x2f6d, 0x03b6,
+ 0x2f6e, 0x03b8,
+ 0x2f6f, 0x03ba,
+ 0x2f70, 0x03bc,
+ 0x2f71, 0x03be,
+ 0x2f72, 0x03c1,
+ 0x2f73, 0x03c3,
+ 0x2f74, 0x03c5,
+ 0x2f75, 0x03cc,
+ 0x2f77, 0x03cf,
+ 0x2f79, 0x03d2,
+ 0x2f7b, 0x03d5,
+ 0x2f7d, 0x03d8,
+ 0x3021, 0x0465,
+ 0x3022, 0x1dd1,
+ 0x3023, 0x0467,
+ 0x3033, 0x1ca2,
+ 0x3034, 0x0478,
+ 0x303b, 0x1dd2,
+ 0x303c, 0x0480,
+ 0x306e, 0x1dd3,
+ 0x306f, 0x04b3,
+ 0x3073, 0x1dd4,
+ 0x3074, 0x04b8,
+ 0x307c, 0x1dd5,
+ 0x307d, 0x04c1,
+ 0x3121, 0x04c3,
+ 0x312a, 0x1dd6,
+ 0x312b, 0x04cd,
+ 0x3135, 0x1dd7,
+ 0x3136, 0x04d8,
+ 0x3139, 0x1dd8,
+ 0x313a, 0x04dc,
+ 0x313c, 0x1dd9,
+ 0x313e, 0x04e0,
+ 0x3142, 0x1ddb,
+ 0x3143, 0x04e5,
+ 0x316b, 0x1ddc,
+ 0x316c, 0x050e,
+ 0x3221, 0x0521,
+ 0x3228, 0x1ddd,
+ 0x3229, 0x1cc9,
+ 0x322a, 0x1dde,
+ 0x322b, 0x052b,
+ 0x3260, 0x1ddf,
+ 0x3261, 0x0561,
+ 0x327a, 0x1de0,
+ 0x327b, 0x057b,
+ 0x327d, 0x1de1,
+ 0x327e, 0x057e,
+ 0x3321, 0x057f,
+ 0x3322, 0x1de2,
+ 0x3323, 0x0581,
+ 0x3342, 0x1961,
+ 0x3343, 0x05a1,
+ 0x3349, 0x139f,
+ 0x334a, 0x05a8,
+ 0x3365, 0x1de3,
+ 0x3366, 0x05c4,
+ 0x336b, 0x1de4,
+ 0x336c, 0x05ca,
+ 0x3373, 0x1de5,
+ 0x3374, 0x05d2,
+ 0x3376, 0x1731,
+ 0x3377, 0x05d5,
+ 0x337a, 0x1de6,
+ 0x337b, 0x05d9,
+ 0x3421, 0x05dd,
+ 0x3442, 0x1de7,
+ 0x3443, 0x1572,
+ 0x3444, 0x0600,
+ 0x344d, 0x1de8,
+ 0x344e, 0x060a,
+ 0x3452, 0x1a20,
+ 0x3453, 0x060f,
+ 0x3465, 0x1de9,
+ 0x3466, 0x0622,
+ 0x3521, 0x063b,
+ 0x352b, 0x1dea,
+ 0x352c, 0x0646,
+ 0x3540, 0x1deb,
+ 0x3541, 0x065b,
+ 0x3621, 0x0699,
+ 0x3622, 0x1dec,
+ 0x3623, 0x069b,
+ 0x362a, 0x1ded,
+ 0x362b, 0x06a3,
+ 0x3646, 0x1d32,
+ 0x3647, 0x06bf,
+ 0x364f, 0x1dee,
+ 0x3650, 0x06c8,
+ 0x366d, 0x1def,
+ 0x366e, 0x06e6,
+ 0x3674, 0x1df0,
+ 0x3675, 0x06ed,
+ 0x367b, 0x1df1,
+ 0x367c, 0x06f4,
+ 0x367d, 0x1df2,
+ 0x367e, 0x06f6,
+ 0x3721, 0x06f7,
+ 0x3724, 0x1df3,
+ 0x3725, 0x06fb,
+ 0x3737, 0x1df4,
+ 0x3738, 0x070e,
+ 0x3745, 0x1df5,
+ 0x3746, 0x071c,
+ 0x374e, 0x1df6,
+ 0x374f, 0x0725,
+ 0x3752, 0x1df7,
+ 0x3753, 0x0729,
+ 0x3755, 0x1df8,
+ 0x3756, 0x072c,
+ 0x375b, 0x1c0d,
+ 0x375c, 0x0732,
+ 0x3764, 0x1df9,
+ 0x3765, 0x073b,
+ 0x3771, 0x1dfa,
+ 0x3772, 0x0748,
+ 0x3779, 0x1dfb,
+ 0x377a, 0x0750,
+ 0x377e, 0x1dfc,
+ 0x3821, 0x0755,
+ 0x3834, 0x1dfd,
+ 0x3835, 0x0769,
+ 0x3841, 0x1dfe,
+ 0x3842, 0x0776,
+ 0x3921, 0x07b3,
+ 0x392b, 0x1dff,
+ 0x392c, 0x07be,
+ 0x3937, 0x1e00,
+ 0x3938, 0x07ca,
+ 0x3942, 0x1e01,
+ 0x3943, 0x07d5,
+ 0x395c, 0x16dd,
+ 0x395d, 0x07ef,
+ 0x396d, 0x1e02,
+ 0x396e, 0x0800,
+ 0x3974, 0x1e03,
+ 0x3975, 0x0807,
+ 0x3979, 0x1e04,
+ 0x397a, 0x080c,
+ 0x3a21, 0x0811,
+ 0x3a53, 0x1e05,
+ 0x3a54, 0x0844,
+ 0x3a67, 0x1e06,
+ 0x3a68, 0x0858,
+ 0x3a74, 0x1e07,
+ 0x3a75, 0x0865,
+ 0x3b21, 0x086f,
+ 0x3b27, 0x1e08,
+ 0x3b28, 0x0876,
+ 0x3b2a, 0x1e09,
+ 0x3b2b, 0x0879,
+ 0x3b2c, 0x1e0a,
+ 0x3b2d, 0x087b,
+ 0x3b39, 0x1e0b,
+ 0x3b3a, 0x0888,
+ 0x3c21, 0x08cd,
+ 0x3c38, 0x1e0c,
+ 0x3c39, 0x08e5,
+ 0x3c48, 0x1e0d,
+ 0x3c49, 0x1929,
+ 0x3c4a, 0x08f6,
+ 0x3c57, 0x1e0e,
+ 0x3c58, 0x0904,
+ 0x3c5d, 0x1e0f,
+ 0x3c5f, 0x090b,
+ 0x3d21, 0x092b,
+ 0x3d2b, 0x1e11,
+ 0x3d2c, 0x0936,
+ 0x3d36, 0x1e12,
+ 0x3d37, 0x0941,
+ 0x3d6c, 0x1e13,
+ 0x3d6e, 0x0978,
+ 0x3d72, 0x1e15,
+ 0x3d74, 0x097e,
+ 0x3e21, 0x0989,
+ 0x3e25, 0x1e17,
+ 0x3e26, 0x098e,
+ 0x3e33, 0x1e18,
+ 0x3e34, 0x099c,
+ 0x3e3f, 0x1e19,
+ 0x3e40, 0x09a8,
+ 0x3e55, 0x1e1a,
+ 0x3e56, 0x09be,
+ 0x3e5f, 0x1e1b,
+ 0x3e60, 0x09c8,
+ 0x3e64, 0x1e1c,
+ 0x3e65, 0x09cd,
+ 0x3f21, 0x09e7,
+ 0x3f2a, 0x1e1d,
+ 0x3f2b, 0x09f1,
+ 0x3f59, 0x1e1e,
+ 0x3f5a, 0x0a20,
+ 0x3f60, 0x1e1f,
+ 0x3f61, 0x0a27,
+ 0x3f69, 0x1e20,
+ 0x3f6a, 0x0a30,
+ 0x4021, 0x0a45,
+ 0x4022, 0x1e21,
+ 0x4023, 0x0a47,
+ 0x4042, 0x1e22,
+ 0x4043, 0x0a67,
+ 0x4066, 0x1e23,
+ 0x4067, 0x0a8b,
+ 0x4071, 0x1e24,
+ 0x4073, 0x0a97,
+ 0x4079, 0x1e26,
+ 0x407b, 0x0a9f,
+ 0x4121, 0x0aa3,
+ 0x4127, 0x1e28,
+ 0x4128, 0x1a6e,
+ 0x4129, 0x0aab,
+ 0x4139, 0x1e29,
+ 0x413a, 0x0abc,
+ 0x414c, 0x1e2a,
+ 0x414d, 0x0acf,
+ 0x414f, 0x1e2b,
+ 0x4150, 0x0ad2,
+ 0x415f, 0x1e2c,
+ 0x4160, 0x0ae2,
+ 0x4169, 0x1e2d,
+ 0x416a, 0x0aec,
+ 0x4221, 0x0b01,
+ 0x423d, 0x1e2e,
+ 0x423e, 0x0b1e,
+ 0x424d, 0x1e2f,
+ 0x424e, 0x0b2e,
+ 0x425c, 0x1e30,
+ 0x425d, 0x0b3d,
+ 0x4263, 0x1e31,
+ 0x4264, 0x0b44,
+ 0x426f, 0x1e32,
+ 0x4270, 0x0b50,
+ 0x4275, 0x1e33,
+ 0x4277, 0x0b57,
+ 0x427d, 0x1e35,
+ 0x427e, 0x0b5e,
+ 0x4321, 0x0b5f,
+ 0x4327, 0x1e36,
+ 0x4328, 0x0b66,
+ 0x4329, 0x1e37,
+ 0x432b, 0x0b69,
+ 0x432d, 0x1e39,
+ 0x432f, 0x0b6d,
+ 0x433d, 0x1e3b,
+ 0x433e, 0x0b7c,
+ 0x4370, 0x1e3c,
+ 0x4371, 0x0baf,
+ 0x4375, 0x1e3d,
+ 0x4376, 0x0bb4,
+ 0x437c, 0x1e3e,
+ 0x437d, 0x0bbb,
+ 0x4421, 0x0bbd,
+ 0x443d, 0x1e3f,
+ 0x443e, 0x0bda,
+ 0x4448, 0x1e40,
+ 0x4449, 0x0be5,
+ 0x444a, 0x1e41,
+ 0x444b, 0x0be7,
+ 0x444d, 0x1e42,
+ 0x444e, 0x0bea,
+ 0x444f, 0x1e43,
+ 0x4450, 0x0bec,
+ 0x445b, 0x11b5,
+ 0x445c, 0x0bf8,
+ 0x4521, 0x0c1b,
+ 0x4522, 0x1e44,
+ 0x4523, 0x0c1d,
+ 0x4527, 0x1e45,
+ 0x4528, 0x0c22,
+ 0x452e, 0x1e46,
+ 0x452f, 0x0c29,
+ 0x4536, 0x1e47,
+ 0x4537, 0x0c31,
+ 0x453f, 0x1e48,
+ 0x4540, 0x0c3a,
+ 0x4548, 0x1e49,
+ 0x4549, 0x0c43,
+ 0x454b, 0x1e4a,
+ 0x454c, 0x0c46,
+ 0x4551, 0x1e4b,
+ 0x4553, 0x0c4d,
+ 0x4557, 0x16df,
+ 0x4558, 0x0c52,
+ 0x4564, 0x1e4d,
+ 0x4565, 0x0c5f,
+ 0x456e, 0x1450,
+ 0x456f, 0x0c69,
+ 0x4573, 0x1536,
+ 0x4574, 0x0c6e,
+ 0x4578, 0x1e4e,
+ 0x4579, 0x0c73,
+ 0x4621, 0x0c79,
+ 0x463e, 0x1e4f,
+ 0x463f, 0x0c97,
+ 0x4642, 0x1e50,
+ 0x4643, 0x0c9b,
+ 0x4654, 0x1e51,
+ 0x4656, 0x0cae,
+ 0x465b, 0x1e53,
+ 0x465d, 0x0cb5,
+ 0x4661, 0x1e55,
+ 0x4662, 0x0cba,
+ 0x4666, 0x1e56,
+ 0x4668, 0x0cc0,
+ 0x466a, 0x1e58,
+ 0x466b, 0x0cc3,
+ 0x4676, 0x1aed,
+ 0x4677, 0x0ccf,
+ 0x4721, 0x0cd7,
+ 0x4729, 0x1e59,
+ 0x472a, 0x0ce0,
+ 0x4739, 0x1e5a,
+ 0x473a, 0x0cf0,
+ 0x4757, 0x1e5b,
+ 0x4758, 0x0d0e,
+ 0x4767, 0x1e5c,
+ 0x4768, 0x1989,
+ 0x4769, 0x1e5d,
+ 0x476a, 0x0d20,
+ 0x476d, 0x1e5e,
+ 0x476e, 0x0d24,
+ 0x4821, 0x0d35,
+ 0x4824, 0x1e5f,
+ 0x4825, 0x0d39,
+ 0x482e, 0x1e60,
+ 0x482f, 0x0d43,
+ 0x4830, 0x1e61,
+ 0x4831, 0x0d45,
+ 0x4854, 0x1e62,
+ 0x4855, 0x0d69,
+ 0x4862, 0x1e63,
+ 0x4863, 0x0d77,
+ 0x4875, 0x1e64,
+ 0x4876, 0x0d8a,
+ 0x4921, 0x0d93,
+ 0x4922, 0x1e65,
+ 0x4924, 0x0d96,
+ 0x492f, 0x1e67,
+ 0x4930, 0x143b,
+ 0x4931, 0x0da3,
+ 0x4932, 0x1e68,
+ 0x4933, 0x0da5,
+ 0x4935, 0x1e69,
+ 0x4936, 0x0da8,
+ 0x4940, 0x1e6a,
+ 0x4941, 0x0db3,
+ 0x494e, 0x1e6b,
+ 0x494f, 0x0dc1,
+ 0x4951, 0x1e6c,
+ 0x4952, 0x0dc4,
+ 0x4a21, 0x0df1,
+ 0x4a43, 0x1e6d,
+ 0x4a44, 0x0e14,
+ 0x4a4d, 0x1e6e,
+ 0x4a4e, 0x0e1e,
+ 0x4a5a, 0x1e6f,
+ 0x4a5b, 0x0e2b,
+ 0x4a79, 0x1e70,
+ 0x4a7a, 0x0e4a,
+ 0x4b21, 0x0e4f,
+ 0x4b22, 0x1e71,
+ 0x4b23, 0x0e51,
+ 0x4b29, 0x1e72,
+ 0x4b2a, 0x0e58,
+ 0x4b4b, 0x1e73,
+ 0x4b4c, 0x0e7a,
+ 0x4b6a, 0x1d33,
+ 0x4b6b, 0x0e99,
+ 0x4b70, 0x1e74,
+ 0x4b71, 0x0e9f,
+ 0x4b79, 0x102f,
+ 0x4b7a, 0x0ea8,
+ 0x4c21, 0x0ead,
+ 0x4c4d, 0x1e75,
+ 0x4c4e, 0x0eda,
+ 0x4c59, 0x1e76,
+ 0x4c5a, 0x0ee6,
+ 0x4c5f, 0x1e77,
+ 0x4c60, 0x0eec,
+ 0x4c62, 0x1e78,
+ 0x4c63, 0x0eef,
+ 0x4c79, 0x1935,
+ 0x4c7a, 0x1e79,
+ 0x4c7b, 0x0f07,
+ 0x4c7c, 0x1e7a,
+ 0x4c7d, 0x0f09,
+ 0x4c7e, 0x1e7b,
+ 0x4d21, 0x0f0b,
+ 0x4d32, 0x1e7c,
+ 0x4d33, 0x0f1d,
+ 0x4d50, 0x1e7d,
+ 0x4d51, 0x0f3b,
+ 0x4d54, 0x1e7e,
+ 0x4d55, 0x0f3f,
+ 0x4d5a, 0x1d34,
+ 0x4d5b, 0x0f45,
+ 0x4d69, 0x1e7f,
+ 0x4d6a, 0x0f54,
+ 0x4e21, 0x0f69,
+ 0x4e4b, 0x1e80,
+ 0x4e4c, 0x0f94,
+ 0x4e7a, 0x1e81,
+ 0x4e7c, 0x0fc4,
+ 0x4f21, 0x1e83,
+ 0x4f22, 0x0fc8,
+ 0x4f31, 0x1e84,
+ 0x4f32, 0x0fd8,
+ 0x4f36, 0x1777,
+ 0x4f37, 0x0fdd,
+ 0x4f39, 0x1e85,
+ 0x4f3a, 0x0fe0,
+ 0x5021, 0x0ffa,
+ 0x5056, 0x0ea7,
+ 0x5057, 0x1030,
+ 0x5121, 0x1058,
+ 0x513d, 0x1e86,
+ 0x513e, 0x1075,
+ 0x5147, 0x1e87,
+ 0x5148, 0x107f,
+ 0x514b, 0x1e88,
+ 0x514c, 0x1083,
+ 0x514d, 0x1e89,
+ 0x514e, 0x1085,
+ 0x5221, 0x10b6,
+ 0x5321, 0x1114,
+ 0x5330, 0x1e8a,
+ 0x5331, 0x1124,
+ 0x533a, 0x1e8b,
+ 0x533b, 0x112e,
+ 0x5350, 0x1e8c,
+ 0x5351, 0x1144,
+ 0x535e, 0x1e8d,
+ 0x535f, 0x1152,
+ 0x536b, 0x1e8e,
+ 0x536c, 0x115f,
+ 0x5421, 0x1172,
+ 0x5444, 0x1e8f,
+ 0x5445, 0x1196,
+ 0x5464, 0x0bf7,
+ 0x5465, 0x11b6,
+ 0x5521, 0x11d0,
+ 0x553d, 0x1e90,
+ 0x553e, 0x11ed,
+ 0x5563, 0x1e91,
+ 0x5564, 0x1213,
+ 0x5621, 0x122e,
+ 0x5622, 0x1e92,
+ 0x5623, 0x1230,
+ 0x5672, 0x1e93,
+ 0x5673, 0x1280,
+ 0x5721, 0x128c,
+ 0x5821, 0x12ea,
+ 0x5824, 0x1e94,
+ 0x5825, 0x12ee,
+ 0x5921, 0x1348,
+ 0x5960, 0x1e95,
+ 0x5961, 0x1388,
+ 0x596c, 0x1e96,
+ 0x596d, 0x1394,
+ 0x5978, 0x05a7,
+ 0x5979, 0x13a0,
+ 0x5a21, 0x13a6,
+ 0x5a39, 0x1e97,
+ 0x5a3a, 0x13bf,
+ 0x5a4d, 0x1e98,
+ 0x5a4e, 0x13d3,
+ 0x5b21, 0x1404,
+ 0x5b45, 0x1e99,
+ 0x5b46, 0x1429,
+ 0x5b4a, 0x1e9a,
+ 0x5b4b, 0x142e,
+ 0x5b58, 0x0da2,
+ 0x5b59, 0x143c,
+ 0x5b6b, 0x1e9b,
+ 0x5b6c, 0x144f,
+ 0x5b6d, 0x0c68,
+ 0x5b6e, 0x1451,
+ 0x5b74, 0x1e9c,
+ 0x5b75, 0x1458,
+ 0x5c21, 0x1462,
+ 0x5d21, 0x14c0,
+ 0x5e21, 0x151e,
+ 0x5e39, 0x0c6d,
+ 0x5e3a, 0x1537,
+ 0x5e50, 0x1e9d,
+ 0x5e51, 0x154e,
+ 0x5e75, 0x05ff,
+ 0x5e76, 0x1573,
+ 0x5f21, 0x157c,
+ 0x5f73, 0x1e9e,
+ 0x5f74, 0x15cf,
+ 0x6021, 0x15da,
+ 0x6026, 0x1e9f,
+ 0x6027, 0x15e0,
+ 0x605f, 0x1ea0,
+ 0x6060, 0x1619,
+ 0x6076, 0x1d35,
+ 0x6077, 0x1630,
+ 0x6121, 0x1638,
+ 0x612b, 0x1ea1,
+ 0x612c, 0x1643,
+ 0x6130, 0x1ea2,
+ 0x6132, 0x1649,
+ 0x6221, 0x1696,
+ 0x622b, 0x1ea4,
+ 0x622c, 0x16a1,
+ 0x6268, 0x07ee,
+ 0x6269, 0x16de,
+ 0x626a, 0x0c51,
+ 0x626b, 0x16e0,
+ 0x626f, 0x1ea5,
+ 0x6270, 0x16e5,
+ 0x6321, 0x16f4,
+ 0x634a, 0x1ea6,
+ 0x634b, 0x171e,
+ 0x6354, 0x1ea7,
+ 0x6355, 0x1728,
+ 0x635e, 0x05d4,
+ 0x635f, 0x1732,
+ 0x6421, 0x1752,
+ 0x6439, 0x1ea8,
+ 0x643a, 0x176b,
+ 0x6446, 0x0fdc,
+ 0x6447, 0x1778,
+ 0x6464, 0x1ea9,
+ 0x6465, 0x1796,
+ 0x646e, 0x1eaa,
+ 0x646f, 0x17a0,
+ 0x6521, 0x17b0,
+ 0x6539, 0x1eab,
+ 0x653a, 0x17c9,
+ 0x653b, 0x1eac,
+ 0x653c, 0x17cb,
+ 0x6546, 0x1ead,
+ 0x6547, 0x17d6,
+ 0x6621, 0x180e,
+ 0x6646, 0x1eae,
+ 0x6647, 0x1834,
+ 0x6721, 0x186c,
+ 0x6764, 0x1eaf,
+ 0x6765, 0x18b0,
+ 0x6769, 0x1eb0,
+ 0x676a, 0x18b5,
+ 0x6772, 0x1eb1,
+ 0x6773, 0x18be,
+ 0x6821, 0x18ca,
+ 0x6834, 0x1eb2,
+ 0x6835, 0x18de,
+ 0x683b, 0x1eb3,
+ 0x683c, 0x18e5,
+ 0x6874, 0x1eb4,
+ 0x6875, 0x191e,
+ 0x6921, 0x1928,
+ 0x6922, 0x08f5,
+ 0x6923, 0x192a,
+ 0x692e, 0x0f05,
+ 0x692f, 0x1936,
+ 0x693c, 0x1eb5,
+ 0x693d, 0x1944,
+ 0x695a, 0x05a0,
+ 0x695b, 0x1962,
+ 0x6a21, 0x1986,
+ 0x6a24, 0x0d1e,
+ 0x6a25, 0x198a,
+ 0x6a27, 0x1eb6,
+ 0x6a28, 0x198d,
+ 0x6a3d, 0x1eb7,
+ 0x6a3e, 0x19a3,
+ 0x6a6f, 0x1eb8,
+ 0x6a70, 0x19d5,
+ 0x6b21, 0x19e4,
+ 0x6b32, 0x1eb9,
+ 0x6b33, 0x19f6,
+ 0x6b5d, 0x060e,
+ 0x6b5e, 0x1a21,
+ 0x6b66, 0x1eba,
+ 0x6b67, 0x1a2a,
+ 0x6b76, 0x1ebb,
+ 0x6b77, 0x1a3a,
+ 0x6c21, 0x1a42,
+ 0x6c4d, 0x0aaa,
+ 0x6c4e, 0x1a6f,
+ 0x6c69, 0x1ebc,
+ 0x6c6a, 0x1a8b,
+ 0x6c74, 0x1ebd,
+ 0x6c75, 0x1a96,
+ 0x6d21, 0x1aa0,
+ 0x6d4e, 0x1ebe,
+ 0x6d4f, 0x1ace,
+ 0x6d6c, 0x1ebf,
+ 0x6d6d, 0x1aec,
+ 0x6d6e, 0x1ec0,
+ 0x6d6f, 0x1aee,
+ 0x6e21, 0x1afe,
+ 0x6e29, 0x1ec1,
+ 0x6e2a, 0x1b07,
+ 0x6e3d, 0x1ec2,
+ 0x6e3e, 0x1b1b,
+ 0x6e57, 0x1ec3,
+ 0x6e58, 0x1b35,
+ 0x6f21, 0x1b5c,
+ 0x6f65, 0x1ec4,
+ 0x6f66, 0x1ba1,
+ 0x7021, 0x1bba,
+ 0x7033, 0x1ec5,
+ 0x7034, 0x1bcd,
+ 0x7045, 0x1ec6,
+ 0x7046, 0x1bdf,
+ 0x7051, 0x1ec7,
+ 0x7052, 0x1beb,
+ 0x7057, 0x1ec8,
+ 0x7058, 0x1bf1,
+ 0x7074, 0x0731,
+ 0x7075, 0x1ec9,
+ 0x7076, 0x1c0f,
+ 0x7121, 0x1c18,
+ 0x7221, 0x1c76,
+ 0x722d, 0x1eca,
+ 0x722e, 0x1c83,
+ 0x723c, 0x1ecb,
+ 0x723d, 0x1c92,
+ 0x724d, 0x0477,
+ 0x724e, 0x1ecc,
+ 0x724f, 0x1ca4,
+ 0x7274, 0x0529,
+ 0x7275, 0x1cca,
+ 0x7321, 0x1cd4,
+ 0x7351, 0x1ecd,
+ 0x7352, 0x1d05,
+ 0x737d, 0x1ece,
+ 0x737e, 0x1d31,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12NWPHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12NWPHMap2, 761
+};
+
+static Gushort japan12NWPVMap2[1618] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0279,
+ 0x2169, 0x1d36,
+ 0x216a, 0x02c2,
+ 0x2221, 0x02d7,
+ 0x223a, 0x02e5,
+ 0x224a, 0x02ed,
+ 0x225c, 0x02f4,
+ 0x2272, 0x0303,
+ 0x227e, 0x030b,
+ 0x2330, 0x030c,
+ 0x2341, 0x0316,
+ 0x2361, 0x0330,
+ 0x2421, 0x034a,
+ 0x2521, 0x039d,
+ 0x2621, 0x03f3,
+ 0x2641, 0x040b,
+ 0x2721, 0x0423,
+ 0x2751, 0x0444,
+ 0x2921, 0x00e8,
+ 0x2960, 0x0186,
+ 0x2961, 0x0128,
+ 0x2a21, 0x0147,
+ 0x2a60, 0x0187,
+ 0x2b21, 0x01a6,
+ 0x2b72, 0x0127,
+ 0x2b73, 0x01f7,
+ 0x2c24, 0x1d37,
+ 0x2d21, 0x1d83,
+ 0x2d40, 0x1da1,
+ 0x2d60, 0x1db8,
+ 0x2d70, 0x02fa,
+ 0x2d71, 0x02f9,
+ 0x2d72, 0x0301,
+ 0x2d73, 0x1dc8,
+ 0x2d7a, 0x0300,
+ 0x2d7b, 0x1dcf,
+ 0x2e21, 0x0282,
+ 0x2e22, 0x02a1,
+ 0x2e23, 0x0305,
+ 0x2e24, 0x02c8,
+ 0x2e25, 0x02cb,
+ 0x2e26, 0x02cd,
+ 0x2e27, 0x029f,
+ 0x2e28, 0x02a2,
+ 0x2e2a, 0x02ce,
+ 0x2e2b, 0x02b4,
+ 0x2e2c, 0x027c,
+ 0x2e2d, 0x02b5,
+ 0x2e2e, 0x027d,
+ 0x2e2f, 0x0297,
+ 0x2e30, 0x030c,
+ 0x2e3a, 0x027f,
+ 0x2e3c, 0x02bb,
+ 0x2e3d, 0x02b9,
+ 0x2e3e, 0x02bc,
+ 0x2e3f, 0x0281,
+ 0x2e40, 0x02cf,
+ 0x2e41, 0x0316,
+ 0x2e5b, 0x02a6,
+ 0x2e5c, 0x02c7,
+ 0x2e5d, 0x02a7,
+ 0x2e5e, 0x0288,
+ 0x2e5f, 0x028a,
+ 0x2e60, 0x0286,
+ 0x2e61, 0x0330,
+ 0x2e7b, 0x02a8,
+ 0x2e7c, 0x029b,
+ 0x2e7d, 0x02a9,
+ 0x2e7e, 0x0289,
+ 0x2f21, 0x027b,
+ 0x2f22, 0x02ae,
+ 0x2f24, 0x027a,
+ 0x2f25, 0x027e,
+ 0x2f26, 0x03ee,
+ 0x2f27, 0x039d,
+ 0x2f28, 0x039f,
+ 0x2f29, 0x03a1,
+ 0x2f2a, 0x03a3,
+ 0x2f2b, 0x03a5,
+ 0x2f2c, 0x03df,
+ 0x2f2d, 0x03e1,
+ 0x2f2e, 0x03e3,
+ 0x2f2f, 0x03bf,
+ 0x2f30, 0x0294,
+ 0x2f31, 0x039e,
+ 0x2f32, 0x03a0,
+ 0x2f33, 0x03a2,
+ 0x2f34, 0x03a4,
+ 0x2f35, 0x03a6,
+ 0x2f37, 0x03a9,
+ 0x2f38, 0x03ab,
+ 0x2f39, 0x03ad,
+ 0x2f3a, 0x03af,
+ 0x2f3b, 0x03b1,
+ 0x2f3c, 0x03b3,
+ 0x2f3d, 0x03b5,
+ 0x2f3e, 0x03b7,
+ 0x2f3f, 0x03b9,
+ 0x2f40, 0x03bb,
+ 0x2f41, 0x03bd,
+ 0x2f42, 0x03c0,
+ 0x2f43, 0x03c2,
+ 0x2f44, 0x03c4,
+ 0x2f45, 0x03c6,
+ 0x2f4b, 0x03ce,
+ 0x2f4c, 0x03d1,
+ 0x2f4d, 0x03d4,
+ 0x2f4e, 0x03d7,
+ 0x2f4f, 0x03da,
+ 0x2f54, 0x03e0,
+ 0x2f55, 0x03e2,
+ 0x2f56, 0x03e4,
+ 0x2f5c, 0x03eb,
+ 0x2f5d, 0x03ef,
+ 0x2f5e, 0x0283,
+ 0x2f60, 0x03ec,
+ 0x2f62, 0x03ea,
+ 0x2f63, 0x03f1,
+ 0x2f65, 0x03f0,
+ 0x2f66, 0x03a8,
+ 0x2f67, 0x03aa,
+ 0x2f68, 0x03ac,
+ 0x2f69, 0x03ae,
+ 0x2f6a, 0x03b0,
+ 0x2f6b, 0x03b2,
+ 0x2f6c, 0x03b4,
+ 0x2f6d, 0x03b6,
+ 0x2f6e, 0x03b8,
+ 0x2f6f, 0x03ba,
+ 0x2f70, 0x03bc,
+ 0x2f71, 0x03be,
+ 0x2f72, 0x03c1,
+ 0x2f73, 0x03c3,
+ 0x2f74, 0x03c5,
+ 0x2f75, 0x03cc,
+ 0x2f77, 0x03cf,
+ 0x2f79, 0x03d2,
+ 0x2f7b, 0x03d5,
+ 0x2f7d, 0x03d8,
+ 0x3021, 0x0465,
+ 0x3022, 0x1dd1,
+ 0x3023, 0x0467,
+ 0x3033, 0x1ca2,
+ 0x3034, 0x0478,
+ 0x303b, 0x1dd2,
+ 0x303c, 0x0480,
+ 0x306e, 0x1dd3,
+ 0x306f, 0x04b3,
+ 0x3073, 0x1dd4,
+ 0x3074, 0x04b8,
+ 0x307c, 0x1dd5,
+ 0x307d, 0x04c1,
+ 0x3121, 0x04c3,
+ 0x312a, 0x1dd6,
+ 0x312b, 0x04cd,
+ 0x3135, 0x1dd7,
+ 0x3136, 0x04d8,
+ 0x3139, 0x1dd8,
+ 0x313a, 0x04dc,
+ 0x313c, 0x1dd9,
+ 0x313e, 0x04e0,
+ 0x3142, 0x1ddb,
+ 0x3143, 0x04e5,
+ 0x316b, 0x1ddc,
+ 0x316c, 0x050e,
+ 0x3221, 0x0521,
+ 0x3228, 0x1ddd,
+ 0x3229, 0x1cc9,
+ 0x322a, 0x1dde,
+ 0x322b, 0x052b,
+ 0x3260, 0x1ddf,
+ 0x3261, 0x0561,
+ 0x327a, 0x1de0,
+ 0x327b, 0x057b,
+ 0x327d, 0x1de1,
+ 0x327e, 0x057e,
+ 0x3321, 0x057f,
+ 0x3322, 0x1de2,
+ 0x3323, 0x0581,
+ 0x3342, 0x1961,
+ 0x3343, 0x05a1,
+ 0x3349, 0x139f,
+ 0x334a, 0x05a8,
+ 0x3365, 0x1de3,
+ 0x3366, 0x05c4,
+ 0x336b, 0x1de4,
+ 0x336c, 0x05ca,
+ 0x3373, 0x1de5,
+ 0x3374, 0x05d2,
+ 0x3376, 0x1731,
+ 0x3377, 0x05d5,
+ 0x337a, 0x1de6,
+ 0x337b, 0x05d9,
+ 0x3421, 0x05dd,
+ 0x3442, 0x1de7,
+ 0x3443, 0x1572,
+ 0x3444, 0x0600,
+ 0x344d, 0x1de8,
+ 0x344e, 0x060a,
+ 0x3452, 0x1a20,
+ 0x3453, 0x060f,
+ 0x3465, 0x1de9,
+ 0x3466, 0x0622,
+ 0x3521, 0x063b,
+ 0x352b, 0x1dea,
+ 0x352c, 0x0646,
+ 0x3540, 0x1deb,
+ 0x3541, 0x065b,
+ 0x3621, 0x0699,
+ 0x3622, 0x1dec,
+ 0x3623, 0x069b,
+ 0x362a, 0x1ded,
+ 0x362b, 0x06a3,
+ 0x3646, 0x1d32,
+ 0x3647, 0x06bf,
+ 0x364f, 0x1dee,
+ 0x3650, 0x06c8,
+ 0x366d, 0x1def,
+ 0x366e, 0x06e6,
+ 0x3674, 0x1df0,
+ 0x3675, 0x06ed,
+ 0x367b, 0x1df1,
+ 0x367c, 0x06f4,
+ 0x367d, 0x1df2,
+ 0x367e, 0x06f6,
+ 0x3721, 0x06f7,
+ 0x3724, 0x1df3,
+ 0x3725, 0x06fb,
+ 0x3737, 0x1df4,
+ 0x3738, 0x070e,
+ 0x3745, 0x1df5,
+ 0x3746, 0x071c,
+ 0x374e, 0x1df6,
+ 0x374f, 0x0725,
+ 0x3752, 0x1df7,
+ 0x3753, 0x0729,
+ 0x3755, 0x1df8,
+ 0x3756, 0x072c,
+ 0x375b, 0x1c0d,
+ 0x375c, 0x0732,
+ 0x3764, 0x1df9,
+ 0x3765, 0x073b,
+ 0x3771, 0x1dfa,
+ 0x3772, 0x0748,
+ 0x3779, 0x1dfb,
+ 0x377a, 0x0750,
+ 0x377e, 0x1dfc,
+ 0x3821, 0x0755,
+ 0x3834, 0x1dfd,
+ 0x3835, 0x0769,
+ 0x3841, 0x1dfe,
+ 0x3842, 0x0776,
+ 0x3921, 0x07b3,
+ 0x392b, 0x1dff,
+ 0x392c, 0x07be,
+ 0x3937, 0x1e00,
+ 0x3938, 0x07ca,
+ 0x3942, 0x1e01,
+ 0x3943, 0x07d5,
+ 0x395c, 0x16dd,
+ 0x395d, 0x07ef,
+ 0x396d, 0x1e02,
+ 0x396e, 0x0800,
+ 0x3974, 0x1e03,
+ 0x3975, 0x0807,
+ 0x3979, 0x1e04,
+ 0x397a, 0x080c,
+ 0x3a21, 0x0811,
+ 0x3a53, 0x1e05,
+ 0x3a54, 0x0844,
+ 0x3a67, 0x1e06,
+ 0x3a68, 0x0858,
+ 0x3a74, 0x1e07,
+ 0x3a75, 0x0865,
+ 0x3b21, 0x086f,
+ 0x3b27, 0x1e08,
+ 0x3b28, 0x0876,
+ 0x3b2a, 0x1e09,
+ 0x3b2b, 0x0879,
+ 0x3b2c, 0x1e0a,
+ 0x3b2d, 0x087b,
+ 0x3b39, 0x1e0b,
+ 0x3b3a, 0x0888,
+ 0x3c21, 0x08cd,
+ 0x3c38, 0x1e0c,
+ 0x3c39, 0x08e5,
+ 0x3c48, 0x1e0d,
+ 0x3c49, 0x1929,
+ 0x3c4a, 0x08f6,
+ 0x3c57, 0x1e0e,
+ 0x3c58, 0x0904,
+ 0x3c5d, 0x1e0f,
+ 0x3c5f, 0x090b,
+ 0x3d21, 0x092b,
+ 0x3d2b, 0x1e11,
+ 0x3d2c, 0x0936,
+ 0x3d36, 0x1e12,
+ 0x3d37, 0x0941,
+ 0x3d6c, 0x1e13,
+ 0x3d6e, 0x0978,
+ 0x3d72, 0x1e15,
+ 0x3d74, 0x097e,
+ 0x3e21, 0x0989,
+ 0x3e25, 0x1e17,
+ 0x3e26, 0x098e,
+ 0x3e33, 0x1e18,
+ 0x3e34, 0x099c,
+ 0x3e3f, 0x1e19,
+ 0x3e40, 0x09a8,
+ 0x3e55, 0x1e1a,
+ 0x3e56, 0x09be,
+ 0x3e5f, 0x1e1b,
+ 0x3e60, 0x09c8,
+ 0x3e64, 0x1e1c,
+ 0x3e65, 0x09cd,
+ 0x3f21, 0x09e7,
+ 0x3f2a, 0x1e1d,
+ 0x3f2b, 0x09f1,
+ 0x3f59, 0x1e1e,
+ 0x3f5a, 0x0a20,
+ 0x3f60, 0x1e1f,
+ 0x3f61, 0x0a27,
+ 0x3f69, 0x1e20,
+ 0x3f6a, 0x0a30,
+ 0x4021, 0x0a45,
+ 0x4022, 0x1e21,
+ 0x4023, 0x0a47,
+ 0x4042, 0x1e22,
+ 0x4043, 0x0a67,
+ 0x4066, 0x1e23,
+ 0x4067, 0x0a8b,
+ 0x4071, 0x1e24,
+ 0x4073, 0x0a97,
+ 0x4079, 0x1e26,
+ 0x407b, 0x0a9f,
+ 0x4121, 0x0aa3,
+ 0x4127, 0x1e28,
+ 0x4128, 0x1a6e,
+ 0x4129, 0x0aab,
+ 0x4139, 0x1e29,
+ 0x413a, 0x0abc,
+ 0x414c, 0x1e2a,
+ 0x414d, 0x0acf,
+ 0x414f, 0x1e2b,
+ 0x4150, 0x0ad2,
+ 0x415f, 0x1e2c,
+ 0x4160, 0x0ae2,
+ 0x4169, 0x1e2d,
+ 0x416a, 0x0aec,
+ 0x4221, 0x0b01,
+ 0x423d, 0x1e2e,
+ 0x423e, 0x0b1e,
+ 0x424d, 0x1e2f,
+ 0x424e, 0x0b2e,
+ 0x425c, 0x1e30,
+ 0x425d, 0x0b3d,
+ 0x4263, 0x1e31,
+ 0x4264, 0x0b44,
+ 0x426f, 0x1e32,
+ 0x4270, 0x0b50,
+ 0x4275, 0x1e33,
+ 0x4277, 0x0b57,
+ 0x427d, 0x1e35,
+ 0x427e, 0x0b5e,
+ 0x4321, 0x0b5f,
+ 0x4327, 0x1e36,
+ 0x4328, 0x0b66,
+ 0x4329, 0x1e37,
+ 0x432b, 0x0b69,
+ 0x432d, 0x1e39,
+ 0x432f, 0x0b6d,
+ 0x433d, 0x1e3b,
+ 0x433e, 0x0b7c,
+ 0x4370, 0x1e3c,
+ 0x4371, 0x0baf,
+ 0x4375, 0x1e3d,
+ 0x4376, 0x0bb4,
+ 0x437c, 0x1e3e,
+ 0x437d, 0x0bbb,
+ 0x4421, 0x0bbd,
+ 0x443d, 0x1e3f,
+ 0x443e, 0x0bda,
+ 0x4448, 0x1e40,
+ 0x4449, 0x0be5,
+ 0x444a, 0x1e41,
+ 0x444b, 0x0be7,
+ 0x444d, 0x1e42,
+ 0x444e, 0x0bea,
+ 0x444f, 0x1e43,
+ 0x4450, 0x0bec,
+ 0x445b, 0x11b5,
+ 0x445c, 0x0bf8,
+ 0x4521, 0x0c1b,
+ 0x4522, 0x1e44,
+ 0x4523, 0x0c1d,
+ 0x4527, 0x1e45,
+ 0x4528, 0x0c22,
+ 0x452e, 0x1e46,
+ 0x452f, 0x0c29,
+ 0x4536, 0x1e47,
+ 0x4537, 0x0c31,
+ 0x453f, 0x1e48,
+ 0x4540, 0x0c3a,
+ 0x4548, 0x1e49,
+ 0x4549, 0x0c43,
+ 0x454b, 0x1e4a,
+ 0x454c, 0x0c46,
+ 0x4551, 0x1e4b,
+ 0x4553, 0x0c4d,
+ 0x4557, 0x16df,
+ 0x4558, 0x0c52,
+ 0x4564, 0x1e4d,
+ 0x4565, 0x0c5f,
+ 0x456e, 0x1450,
+ 0x456f, 0x0c69,
+ 0x4573, 0x1536,
+ 0x4574, 0x0c6e,
+ 0x4578, 0x1e4e,
+ 0x4579, 0x0c73,
+ 0x4621, 0x0c79,
+ 0x463e, 0x1e4f,
+ 0x463f, 0x0c97,
+ 0x4642, 0x1e50,
+ 0x4643, 0x0c9b,
+ 0x4654, 0x1e51,
+ 0x4656, 0x0cae,
+ 0x465b, 0x1e53,
+ 0x465d, 0x0cb5,
+ 0x4661, 0x1e55,
+ 0x4662, 0x0cba,
+ 0x4666, 0x1e56,
+ 0x4668, 0x0cc0,
+ 0x466a, 0x1e58,
+ 0x466b, 0x0cc3,
+ 0x4676, 0x1aed,
+ 0x4677, 0x0ccf,
+ 0x4721, 0x0cd7,
+ 0x4729, 0x1e59,
+ 0x472a, 0x0ce0,
+ 0x4739, 0x1e5a,
+ 0x473a, 0x0cf0,
+ 0x4757, 0x1e5b,
+ 0x4758, 0x0d0e,
+ 0x4767, 0x1e5c,
+ 0x4768, 0x1989,
+ 0x4769, 0x1e5d,
+ 0x476a, 0x0d20,
+ 0x476d, 0x1e5e,
+ 0x476e, 0x0d24,
+ 0x4821, 0x0d35,
+ 0x4824, 0x1e5f,
+ 0x4825, 0x0d39,
+ 0x482e, 0x1e60,
+ 0x482f, 0x0d43,
+ 0x4830, 0x1e61,
+ 0x4831, 0x0d45,
+ 0x4854, 0x1e62,
+ 0x4855, 0x0d69,
+ 0x4862, 0x1e63,
+ 0x4863, 0x0d77,
+ 0x4875, 0x1e64,
+ 0x4876, 0x0d8a,
+ 0x4921, 0x0d93,
+ 0x4922, 0x1e65,
+ 0x4924, 0x0d96,
+ 0x492f, 0x1e67,
+ 0x4930, 0x143b,
+ 0x4931, 0x0da3,
+ 0x4932, 0x1e68,
+ 0x4933, 0x0da5,
+ 0x4935, 0x1e69,
+ 0x4936, 0x0da8,
+ 0x4940, 0x1e6a,
+ 0x4941, 0x0db3,
+ 0x494e, 0x1e6b,
+ 0x494f, 0x0dc1,
+ 0x4951, 0x1e6c,
+ 0x4952, 0x0dc4,
+ 0x4a21, 0x0df1,
+ 0x4a43, 0x1e6d,
+ 0x4a44, 0x0e14,
+ 0x4a4d, 0x1e6e,
+ 0x4a4e, 0x0e1e,
+ 0x4a5a, 0x1e6f,
+ 0x4a5b, 0x0e2b,
+ 0x4a79, 0x1e70,
+ 0x4a7a, 0x0e4a,
+ 0x4b21, 0x0e4f,
+ 0x4b22, 0x1e71,
+ 0x4b23, 0x0e51,
+ 0x4b29, 0x1e72,
+ 0x4b2a, 0x0e58,
+ 0x4b4b, 0x1e73,
+ 0x4b4c, 0x0e7a,
+ 0x4b6a, 0x1d33,
+ 0x4b6b, 0x0e99,
+ 0x4b70, 0x1e74,
+ 0x4b71, 0x0e9f,
+ 0x4b79, 0x102f,
+ 0x4b7a, 0x0ea8,
+ 0x4c21, 0x0ead,
+ 0x4c4d, 0x1e75,
+ 0x4c4e, 0x0eda,
+ 0x4c59, 0x1e76,
+ 0x4c5a, 0x0ee6,
+ 0x4c5f, 0x1e77,
+ 0x4c60, 0x0eec,
+ 0x4c62, 0x1e78,
+ 0x4c63, 0x0eef,
+ 0x4c79, 0x1935,
+ 0x4c7a, 0x1e79,
+ 0x4c7b, 0x0f07,
+ 0x4c7c, 0x1e7a,
+ 0x4c7d, 0x0f09,
+ 0x4c7e, 0x1e7b,
+ 0x4d21, 0x0f0b,
+ 0x4d32, 0x1e7c,
+ 0x4d33, 0x0f1d,
+ 0x4d50, 0x1e7d,
+ 0x4d51, 0x0f3b,
+ 0x4d54, 0x1e7e,
+ 0x4d55, 0x0f3f,
+ 0x4d5a, 0x1d34,
+ 0x4d5b, 0x0f45,
+ 0x4d69, 0x1e7f,
+ 0x4d6a, 0x0f54,
+ 0x4e21, 0x0f69,
+ 0x4e4b, 0x1e80,
+ 0x4e4c, 0x0f94,
+ 0x4e7a, 0x1e81,
+ 0x4e7c, 0x0fc4,
+ 0x4f21, 0x1e83,
+ 0x4f22, 0x0fc8,
+ 0x4f31, 0x1e84,
+ 0x4f32, 0x0fd8,
+ 0x4f36, 0x1777,
+ 0x4f37, 0x0fdd,
+ 0x4f39, 0x1e85,
+ 0x4f3a, 0x0fe0,
+ 0x5021, 0x0ffa,
+ 0x5056, 0x0ea7,
+ 0x5057, 0x1030,
+ 0x5121, 0x1058,
+ 0x513d, 0x1e86,
+ 0x513e, 0x1075,
+ 0x5147, 0x1e87,
+ 0x5148, 0x107f,
+ 0x514b, 0x1e88,
+ 0x514c, 0x1083,
+ 0x514d, 0x1e89,
+ 0x514e, 0x1085,
+ 0x5221, 0x10b6,
+ 0x5321, 0x1114,
+ 0x5330, 0x1e8a,
+ 0x5331, 0x1124,
+ 0x533a, 0x1e8b,
+ 0x533b, 0x112e,
+ 0x5350, 0x1e8c,
+ 0x5351, 0x1144,
+ 0x535e, 0x1e8d,
+ 0x535f, 0x1152,
+ 0x536b, 0x1e8e,
+ 0x536c, 0x115f,
+ 0x5421, 0x1172,
+ 0x5444, 0x1e8f,
+ 0x5445, 0x1196,
+ 0x5464, 0x0bf7,
+ 0x5465, 0x11b6,
+ 0x5521, 0x11d0,
+ 0x553d, 0x1e90,
+ 0x553e, 0x11ed,
+ 0x5563, 0x1e91,
+ 0x5564, 0x1213,
+ 0x5621, 0x122e,
+ 0x5622, 0x1e92,
+ 0x5623, 0x1230,
+ 0x5672, 0x1e93,
+ 0x5673, 0x1280,
+ 0x5721, 0x128c,
+ 0x5821, 0x12ea,
+ 0x5824, 0x1e94,
+ 0x5825, 0x12ee,
+ 0x5921, 0x1348,
+ 0x5960, 0x1e95,
+ 0x5961, 0x1388,
+ 0x596c, 0x1e96,
+ 0x596d, 0x1394,
+ 0x5978, 0x05a7,
+ 0x5979, 0x13a0,
+ 0x5a21, 0x13a6,
+ 0x5a39, 0x1e97,
+ 0x5a3a, 0x13bf,
+ 0x5a4d, 0x1e98,
+ 0x5a4e, 0x13d3,
+ 0x5b21, 0x1404,
+ 0x5b45, 0x1e99,
+ 0x5b46, 0x1429,
+ 0x5b4a, 0x1e9a,
+ 0x5b4b, 0x142e,
+ 0x5b58, 0x0da2,
+ 0x5b59, 0x143c,
+ 0x5b6b, 0x1e9b,
+ 0x5b6c, 0x144f,
+ 0x5b6d, 0x0c68,
+ 0x5b6e, 0x1451,
+ 0x5b74, 0x1e9c,
+ 0x5b75, 0x1458,
+ 0x5c21, 0x1462,
+ 0x5d21, 0x14c0,
+ 0x5e21, 0x151e,
+ 0x5e39, 0x0c6d,
+ 0x5e3a, 0x1537,
+ 0x5e50, 0x1e9d,
+ 0x5e51, 0x154e,
+ 0x5e75, 0x05ff,
+ 0x5e76, 0x1573,
+ 0x5f21, 0x157c,
+ 0x5f73, 0x1e9e,
+ 0x5f74, 0x15cf,
+ 0x6021, 0x15da,
+ 0x6026, 0x1e9f,
+ 0x6027, 0x15e0,
+ 0x605f, 0x1ea0,
+ 0x6060, 0x1619,
+ 0x6076, 0x1d35,
+ 0x6077, 0x1630,
+ 0x6121, 0x1638,
+ 0x612b, 0x1ea1,
+ 0x612c, 0x1643,
+ 0x6130, 0x1ea2,
+ 0x6132, 0x1649,
+ 0x6221, 0x1696,
+ 0x622b, 0x1ea4,
+ 0x622c, 0x16a1,
+ 0x6268, 0x07ee,
+ 0x6269, 0x16de,
+ 0x626a, 0x0c51,
+ 0x626b, 0x16e0,
+ 0x626f, 0x1ea5,
+ 0x6270, 0x16e5,
+ 0x6321, 0x16f4,
+ 0x634a, 0x1ea6,
+ 0x634b, 0x171e,
+ 0x6354, 0x1ea7,
+ 0x6355, 0x1728,
+ 0x635e, 0x05d4,
+ 0x635f, 0x1732,
+ 0x6421, 0x1752,
+ 0x6439, 0x1ea8,
+ 0x643a, 0x176b,
+ 0x6446, 0x0fdc,
+ 0x6447, 0x1778,
+ 0x6464, 0x1ea9,
+ 0x6465, 0x1796,
+ 0x646e, 0x1eaa,
+ 0x646f, 0x17a0,
+ 0x6521, 0x17b0,
+ 0x6539, 0x1eab,
+ 0x653a, 0x17c9,
+ 0x653b, 0x1eac,
+ 0x653c, 0x17cb,
+ 0x6546, 0x1ead,
+ 0x6547, 0x17d6,
+ 0x6621, 0x180e,
+ 0x6646, 0x1eae,
+ 0x6647, 0x1834,
+ 0x6721, 0x186c,
+ 0x6764, 0x1eaf,
+ 0x6765, 0x18b0,
+ 0x6769, 0x1eb0,
+ 0x676a, 0x18b5,
+ 0x6772, 0x1eb1,
+ 0x6773, 0x18be,
+ 0x6821, 0x18ca,
+ 0x6834, 0x1eb2,
+ 0x6835, 0x18de,
+ 0x683b, 0x1eb3,
+ 0x683c, 0x18e5,
+ 0x6874, 0x1eb4,
+ 0x6875, 0x191e,
+ 0x6921, 0x1928,
+ 0x6922, 0x08f5,
+ 0x6923, 0x192a,
+ 0x692e, 0x0f05,
+ 0x692f, 0x1936,
+ 0x693c, 0x1eb5,
+ 0x693d, 0x1944,
+ 0x695a, 0x05a0,
+ 0x695b, 0x1962,
+ 0x6a21, 0x1986,
+ 0x6a24, 0x0d1e,
+ 0x6a25, 0x198a,
+ 0x6a27, 0x1eb6,
+ 0x6a28, 0x198d,
+ 0x6a3d, 0x1eb7,
+ 0x6a3e, 0x19a3,
+ 0x6a6f, 0x1eb8,
+ 0x6a70, 0x19d5,
+ 0x6b21, 0x19e4,
+ 0x6b32, 0x1eb9,
+ 0x6b33, 0x19f6,
+ 0x6b5d, 0x060e,
+ 0x6b5e, 0x1a21,
+ 0x6b66, 0x1eba,
+ 0x6b67, 0x1a2a,
+ 0x6b76, 0x1ebb,
+ 0x6b77, 0x1a3a,
+ 0x6c21, 0x1a42,
+ 0x6c4d, 0x0aaa,
+ 0x6c4e, 0x1a6f,
+ 0x6c69, 0x1ebc,
+ 0x6c6a, 0x1a8b,
+ 0x6c74, 0x1ebd,
+ 0x6c75, 0x1a96,
+ 0x6d21, 0x1aa0,
+ 0x6d4e, 0x1ebe,
+ 0x6d4f, 0x1ace,
+ 0x6d6c, 0x1ebf,
+ 0x6d6d, 0x1aec,
+ 0x6d6e, 0x1ec0,
+ 0x6d6f, 0x1aee,
+ 0x6e21, 0x1afe,
+ 0x6e29, 0x1ec1,
+ 0x6e2a, 0x1b07,
+ 0x6e3d, 0x1ec2,
+ 0x6e3e, 0x1b1b,
+ 0x6e57, 0x1ec3,
+ 0x6e58, 0x1b35,
+ 0x6f21, 0x1b5c,
+ 0x6f65, 0x1ec4,
+ 0x6f66, 0x1ba1,
+ 0x7021, 0x1bba,
+ 0x7033, 0x1ec5,
+ 0x7034, 0x1bcd,
+ 0x7045, 0x1ec6,
+ 0x7046, 0x1bdf,
+ 0x7051, 0x1ec7,
+ 0x7052, 0x1beb,
+ 0x7057, 0x1ec8,
+ 0x7058, 0x1bf1,
+ 0x7074, 0x0731,
+ 0x7075, 0x1ec9,
+ 0x7076, 0x1c0f,
+ 0x7121, 0x1c18,
+ 0x7221, 0x1c76,
+ 0x722d, 0x1eca,
+ 0x722e, 0x1c83,
+ 0x723c, 0x1ecb,
+ 0x723d, 0x1c92,
+ 0x724d, 0x0477,
+ 0x724e, 0x1ecc,
+ 0x724f, 0x1ca4,
+ 0x7274, 0x0529,
+ 0x7275, 0x1cca,
+ 0x7321, 0x1cd4,
+ 0x7351, 0x1ecd,
+ 0x7352, 0x1d05,
+ 0x737d, 0x1ece,
+ 0x737e, 0x1d31,
+ 0x2122, 0x1ecf,
+ 0x2124, 0x204c,
+ 0x2125, 0x2052,
+ 0x212b, 0x2050,
+ 0x212c, 0x204f,
+ 0x213c, 0x1ed3,
+ 0x2141, 0x1ed6,
+ 0x2146, 0x2059,
+ 0x2147, 0x2054,
+ 0x2148, 0x2057,
+ 0x2149, 0x2056,
+ 0x214a, 0x1edb,
+ 0x216b, 0x204d,
+ 0x216c, 0x2051,
+ 0x216d, 0x205b,
+ 0x222e, 0x204e,
+ 0x2421, 0x1eee,
+ 0x2423, 0x1eef,
+ 0x2425, 0x1ef0,
+ 0x2427, 0x1ef1,
+ 0x2429, 0x1ef2,
+ 0x2443, 0x1ef3,
+ 0x2463, 0x1ef4,
+ 0x2465, 0x1ef5,
+ 0x2467, 0x1ef6,
+ 0x246e, 0x1ef7,
+ 0x2521, 0x1ef8,
+ 0x2523, 0x1ef9,
+ 0x2525, 0x1efa,
+ 0x2527, 0x1efb,
+ 0x2529, 0x1efc,
+ 0x2543, 0x1efd,
+ 0x2563, 0x1efe,
+ 0x2565, 0x1eff,
+ 0x2567, 0x1f00,
+ 0x256e, 0x1f01,
+ 0x2575, 0x1f02,
+ 0x2d40, 0x1f04,
+ 0x2d60, 0x1f14,
+ 0x2f21, 0x1ed0,
+ 0x2f22, 0x1ee7,
+ 0x2f24, 0x1ecf,
+ 0x2f27, 0x1ef8,
+ 0x2f2c, 0x1efe,
+ 0x2f2f, 0x1efd,
+ 0x2f30, 0x1ed3,
+ 0x2f5e, 0x2050,
+ 0x2f5f, 0x204f,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12NWPVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12NWPVMap2, 809
+};
+
+static Gushort japan12RKSJHMap2[244] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x889f, 0x0465,
+ 0x8940, 0x04c3,
+ 0x8980, 0x0502,
+ 0x8a40, 0x057f,
+ 0x8a80, 0x05be,
+ 0x8b40, 0x063b,
+ 0x8b80, 0x067a,
+ 0x8c40, 0x06f7,
+ 0x8c80, 0x0736,
+ 0x8d40, 0x07b3,
+ 0x8d80, 0x07f2,
+ 0x8e40, 0x086f,
+ 0x8e80, 0x08ae,
+ 0x8f40, 0x092b,
+ 0x8f80, 0x096a,
+ 0x9040, 0x09e7,
+ 0x9080, 0x0a26,
+ 0x9140, 0x0aa3,
+ 0x9180, 0x0ae2,
+ 0x9240, 0x0b5f,
+ 0x9280, 0x0b9e,
+ 0x9340, 0x0c1b,
+ 0x9380, 0x0c5a,
+ 0x9440, 0x0cd7,
+ 0x9480, 0x0d16,
+ 0x9540, 0x0d93,
+ 0x9580, 0x0dd2,
+ 0x9640, 0x0e4f,
+ 0x9680, 0x0e8e,
+ 0x9740, 0x0f0b,
+ 0x9780, 0x0f4a,
+ 0x9840, 0x0fc7,
+ 0x989f, 0x0ffa,
+ 0x9940, 0x1058,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a80, 0x1153,
+ 0x9b40, 0x11d0,
+ 0x9b80, 0x120f,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1387,
+ 0x9e40, 0x1404,
+ 0x9e80, 0x1443,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe140, 0x1638,
+ 0xe180, 0x1677,
+ 0xe240, 0x16f4,
+ 0xe280, 0x1733,
+ 0xe340, 0x17b0,
+ 0xe380, 0x17ef,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe540, 0x1928,
+ 0xe580, 0x1967,
+ 0xe640, 0x19e4,
+ 0xe680, 0x1a23,
+ 0xe740, 0x1aa0,
+ 0xe780, 0x1adf,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xea40, 0x1cd4,
+ 0xea80, 0x1d13,
+ 0xeaa3, 0x205c,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12RKSJHEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12RKSJHMap2, 122
+};
+
+static Gushort japan12RKSJVMap2[298] = {
+ 0x0000, 0x0000,
+ 0x8140, 0x0279,
+ 0x8180, 0x02b8,
+ 0x81b8, 0x02e5,
+ 0x81c8, 0x02ed,
+ 0x81da, 0x02f4,
+ 0x81f0, 0x0303,
+ 0x81fc, 0x030b,
+ 0x824f, 0x030c,
+ 0x8260, 0x0316,
+ 0x8281, 0x0330,
+ 0x829f, 0x034a,
+ 0x8340, 0x039d,
+ 0x8380, 0x03dc,
+ 0x839f, 0x03f3,
+ 0x83bf, 0x040b,
+ 0x8440, 0x0423,
+ 0x8470, 0x0444,
+ 0x8480, 0x0453,
+ 0x849f, 0x1d37,
+ 0x84a0, 0x1d39,
+ 0x84a1, 0x1d43,
+ 0x84a2, 0x1d47,
+ 0x84a3, 0x1d4f,
+ 0x84a4, 0x1d4b,
+ 0x84a5, 0x1d53,
+ 0x84a6, 0x1d63,
+ 0x84a7, 0x1d5b,
+ 0x84a8, 0x1d6b,
+ 0x84a9, 0x1d73,
+ 0x84aa, 0x1d38,
+ 0x84ab, 0x1d3a,
+ 0x84ac, 0x1d46,
+ 0x84ad, 0x1d4a,
+ 0x84ae, 0x1d52,
+ 0x84af, 0x1d4e,
+ 0x84b0, 0x1d5a,
+ 0x84b1, 0x1d6a,
+ 0x84b2, 0x1d62,
+ 0x84b3, 0x1d72,
+ 0x84b4, 0x1d82,
+ 0x84b5, 0x1d57,
+ 0x84b6, 0x1d66,
+ 0x84b7, 0x1d5f,
+ 0x84b8, 0x1d6e,
+ 0x84b9, 0x1d76,
+ 0x84ba, 0x1d54,
+ 0x84bb, 0x1d67,
+ 0x84bc, 0x1d5c,
+ 0x84bd, 0x1d6f,
+ 0x84be, 0x1d79,
+ 0x889f, 0x0465,
+ 0x8940, 0x04c3,
+ 0x8980, 0x0502,
+ 0x8a40, 0x057f,
+ 0x8a80, 0x05be,
+ 0x8b40, 0x063b,
+ 0x8b80, 0x067a,
+ 0x8c40, 0x06f7,
+ 0x8c80, 0x0736,
+ 0x8d40, 0x07b3,
+ 0x8d80, 0x07f2,
+ 0x8e40, 0x086f,
+ 0x8e80, 0x08ae,
+ 0x8f40, 0x092b,
+ 0x8f80, 0x096a,
+ 0x9040, 0x09e7,
+ 0x9080, 0x0a26,
+ 0x9140, 0x0aa3,
+ 0x9180, 0x0ae2,
+ 0x9240, 0x0b5f,
+ 0x9280, 0x0b9e,
+ 0x9340, 0x0c1b,
+ 0x9380, 0x0c5a,
+ 0x9440, 0x0cd7,
+ 0x9480, 0x0d16,
+ 0x9540, 0x0d93,
+ 0x9580, 0x0dd2,
+ 0x9640, 0x0e4f,
+ 0x9680, 0x0e8e,
+ 0x9740, 0x0f0b,
+ 0x9780, 0x0f4a,
+ 0x9840, 0x0fc7,
+ 0x989f, 0x0ffa,
+ 0x9940, 0x1058,
+ 0x9980, 0x1097,
+ 0x9a40, 0x1114,
+ 0x9a80, 0x1153,
+ 0x9b40, 0x11d0,
+ 0x9b80, 0x120f,
+ 0x9c40, 0x128c,
+ 0x9c80, 0x12cb,
+ 0x9d40, 0x1348,
+ 0x9d80, 0x1387,
+ 0x9e40, 0x1404,
+ 0x9e80, 0x1443,
+ 0x9f40, 0x14c0,
+ 0x9f80, 0x14ff,
+ 0xe040, 0x157c,
+ 0xe080, 0x15bb,
+ 0xe140, 0x1638,
+ 0xe180, 0x1677,
+ 0xe240, 0x16f4,
+ 0xe280, 0x1733,
+ 0xe340, 0x17b0,
+ 0xe380, 0x17ef,
+ 0xe440, 0x186c,
+ 0xe480, 0x18ab,
+ 0xe540, 0x1928,
+ 0xe580, 0x1967,
+ 0xe640, 0x19e4,
+ 0xe680, 0x1a23,
+ 0xe740, 0x1aa0,
+ 0xe780, 0x1adf,
+ 0xe840, 0x1b5c,
+ 0xe880, 0x1b9b,
+ 0xe940, 0x1c18,
+ 0xe980, 0x1c57,
+ 0xea40, 0x1cd4,
+ 0xea80, 0x1d13,
+ 0xeaa3, 0x205c,
+ 0x8141, 0x1ecf,
+ 0x8150, 0x1ed1,
+ 0x815b, 0x1ed3,
+ 0x8160, 0x1ed6,
+ 0x8169, 0x1edb,
+ 0x8181, 0x1eed,
+ 0x829f, 0x1eee,
+ 0x82a1, 0x1eef,
+ 0x82a3, 0x1ef0,
+ 0x82a5, 0x1ef1,
+ 0x82a7, 0x1ef2,
+ 0x82c1, 0x1ef3,
+ 0x82e1, 0x1ef4,
+ 0x82e3, 0x1ef5,
+ 0x82e5, 0x1ef6,
+ 0x82ec, 0x1ef7,
+ 0x8340, 0x1ef8,
+ 0x8342, 0x1ef9,
+ 0x8344, 0x1efa,
+ 0x8346, 0x1efb,
+ 0x8348, 0x1efc,
+ 0x8362, 0x1efd,
+ 0x8383, 0x1efe,
+ 0x8385, 0x1eff,
+ 0x8387, 0x1f00,
+ 0x838e, 0x1f01,
+ 0x8395, 0x1f02,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12RKSJVEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d,
+ 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155,
+ 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d,
+ 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165,
+ 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d,
+ 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d,
+ 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12RKSJVMap2, 149
+};
+
+static Gushort japan12RomanMap2[4] = {
+ 0x0000, 0x0000,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12RomanEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee,
+ 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6,
+ 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe,
+ 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106,
+ 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e,
+ 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116,
+ 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e,
+ 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126,
+ 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e,
+ 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e,
+ 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12RomanMap2, 2
+};
+
+static Gushort japan12UniJISUCS2HMap2[13926] = {
+ 0x0000, 0x0000,
+ 0x0020, 0x0001,
+ 0x005c, 0x0061,
+ 0x005d, 0x003e,
+ 0x00a1, 0x0065,
+ 0x00a4, 0x006b,
+ 0x00a5, 0x003d,
+ 0x00a6, 0x0063,
+ 0x00a7, 0x02d0,
+ 0x00a8, 0x0287,
+ 0x00a9, 0x0098,
+ 0x00aa, 0x008c,
+ 0x00ab, 0x006d,
+ 0x00ac, 0x0099,
+ 0x00ad, 0x0097,
+ 0x00ae, 0x009a,
+ 0x00af, 0x0081,
+ 0x00b0, 0x02c3,
+ 0x00b1, 0x02b6,
+ 0x00b2, 0x009d,
+ 0x00b4, 0x0285,
+ 0x00b5, 0x009f,
+ 0x00b6, 0x030a,
+ 0x00b7, 0x0075,
+ 0x00b8, 0x0086,
+ 0x00b9, 0x00a0,
+ 0x00ba, 0x0090,
+ 0x00bb, 0x007b,
+ 0x00bc, 0x00a1,
+ 0x00bf, 0x007e,
+ 0x00c0, 0x00a4,
+ 0x00c6, 0x008b,
+ 0x00c7, 0x00aa,
+ 0x00d7, 0x02b7,
+ 0x00d8, 0x008e,
+ 0x00d9, 0x00bb,
+ 0x00df, 0x0096,
+ 0x00e0, 0x00c1,
+ 0x00e6, 0x0091,
+ 0x00e7, 0x00c7,
+ 0x00f7, 0x02b8,
+ 0x00f8, 0x0094,
+ 0x00f9, 0x00d8,
+ 0x0131, 0x0092,
+ 0x0141, 0x008d,
+ 0x0142, 0x0093,
+ 0x0152, 0x008f,
+ 0x0153, 0x0095,
+ 0x0160, 0x00df,
+ 0x0161, 0x00e3,
+ 0x0178, 0x00e0,
+ 0x017d, 0x00e1,
+ 0x017e, 0x00e5,
+ 0x01c0, 0x0063,
+ 0x0300, 0x0041,
+ 0x0301, 0x007f,
+ 0x0303, 0x005f,
+ 0x0304, 0x0081,
+ 0x0305, 0x00e2,
+ 0x0306, 0x0082,
+ 0x030a, 0x0085,
+ 0x030b, 0x0087,
+ 0x030c, 0x0089,
+ 0x0327, 0x0086,
+ 0x0328, 0x0088,
+ 0x0332, 0x0040,
+ 0x0336, 0x008a,
+ 0x0361, 0x02f6,
+ 0x0391, 0x03f3,
+ 0x03a3, 0x0404,
+ 0x03b1, 0x040b,
+ 0x03c3, 0x041c,
+ 0x0401, 0x0429,
+ 0x0410, 0x0423,
+ 0x0416, 0x042a,
+ 0x0436, 0x044b,
+ 0x0451, 0x044a,
+ 0x2002, 0x00e7,
+ 0x2003, 0x0279,
+ 0x2010, 0x000e,
+ 0x2011, 0x000e,
+ 0x2012, 0x0072,
+ 0x2013, 0x0072,
+ 0x2014, 0x008a,
+ 0x2015, 0x0295,
+ 0x2016, 0x029a,
+ 0x2018, 0x029e,
+ 0x201a, 0x0078,
+ 0x201c, 0x02a0,
+ 0x201e, 0x0079,
+ 0x2020, 0x0308,
+ 0x2022, 0x0077,
+ 0x2025, 0x029d,
+ 0x2026, 0x029c,
+ 0x2030, 0x0304,
+ 0x2032, 0x02c4,
+ 0x2039, 0x006e,
+ 0x203b, 0x02de,
+ 0x203e, 0x0145,
+ 0x2044, 0x0068,
+ 0x20dd, 0x030b,
+ 0x2103, 0x02c6,
+ 0x2109, 0x2071,
+ 0x2113, 0x1f59,
+ 0x2116, 0x1dba,
+ 0x2121, 0x1f77,
+ 0x2122, 0x00e4,
+ 0x212b, 0x0303,
+ 0x2160, 0x1d97,
+ 0x216a, 0x2021,
+ 0x2170, 0x1f9c,
+ 0x217a, 0x206a,
+ 0x217f, 0x206f,
+ 0x2190, 0x02e1,
+ 0x2192, 0x02e0,
+ 0x2193, 0x02e3,
+ 0x21c4, 0x2076,
+ 0x21c6, 0x2075,
+ 0x21d2, 0x02f0,
+ 0x21d4, 0x02f1,
+ 0x21e6, 0x1f4d,
+ 0x21e7, 0x1f4c,
+ 0x21e8, 0x1f4e,
+ 0x21e9, 0x1f4b,
+ 0x2200, 0x02f2,
+ 0x2202, 0x02f7,
+ 0x2203, 0x02f3,
+ 0x2207, 0x02f8,
+ 0x2208, 0x02e5,
+ 0x220b, 0x02e6,
+ 0x2211, 0x1dc9,
+ 0x2212, 0x02b5,
+ 0x221a, 0x02fd,
+ 0x221d, 0x02ff,
+ 0x221e, 0x02bf,
+ 0x221f, 0x1dcd,
+ 0x2220, 0x02f4,
+ 0x2225, 0x029a,
+ 0x2227, 0x02ed,
+ 0x2229, 0x02ec,
+ 0x222a, 0x02eb,
+ 0x222b, 0x0301,
+ 0x222d, 0x2003,
+ 0x222e, 0x1dc8,
+ 0x2234, 0x02c0,
+ 0x2235, 0x0300,
+ 0x223c, 0x0299,
+ 0x223d, 0x02fe,
+ 0x2252, 0x02fa,
+ 0x2260, 0x02ba,
+ 0x2261, 0x02f9,
+ 0x2266, 0x02bd,
+ 0x226a, 0x02fb,
+ 0x2282, 0x02e9,
+ 0x2286, 0x02e7,
+ 0x22a5, 0x02f5,
+ 0x22bf, 0x1dce,
+ 0x22ee, 0x1ed9,
+ 0x22ef, 0x029c,
+ 0x2312, 0x02f6,
+ 0x2460, 0x1d83,
+ 0x2474, 0x1f87,
+ 0x2488, 0x1f7e,
+ 0x249c, 0x1fb0,
+ 0x24ea, 0x2020,
+ 0x2500, 0x1d37,
+ 0x2550, 0x203b,
+ 0x255e, 0x203c,
+ 0x2561, 0x203e,
+ 0x256a, 0x203d,
+ 0x256d, 0x2037,
+ 0x256f, 0x203a,
+ 0x2570, 0x2039,
+ 0x2571, 0x2045,
+ 0x2581, 0x2026,
+ 0x2589, 0x2034,
+ 0x258a, 0x2033,
+ 0x258b, 0x2032,
+ 0x258c, 0x2031,
+ 0x258d, 0x2030,
+ 0x258e, 0x202f,
+ 0x258f, 0x202e,
+ 0x2594, 0x2035,
+ 0x25a0, 0x02d9,
+ 0x25a1, 0x02d8,
+ 0x25a2, 0x1f4f,
+ 0x25b2, 0x02db,
+ 0x25b3, 0x02da,
+ 0x25b7, 0x1f4a,
+ 0x25bc, 0x02dd,
+ 0x25bd, 0x02dc,
+ 0x25c1, 0x1f49,
+ 0x25c6, 0x02d7,
+ 0x25c7, 0x02d6,
+ 0x25c9, 0x2012,
+ 0x25cb, 0x02d3,
+ 0x25ce, 0x02d5,
+ 0x25cf, 0x02d4,
+ 0x25e2, 0x203f,
+ 0x25e4, 0x2042,
+ 0x25e5, 0x2041,
+ 0x25ef, 0x030b,
+ 0x2600, 0x2017,
+ 0x2605, 0x02d2,
+ 0x2606, 0x02d1,
+ 0x260e, 0x1f78,
+ 0x261c, 0x201c,
+ 0x261e, 0x201b,
+ 0x261f, 0x201e,
+ 0x2640, 0x02c2,
+ 0x2642, 0x02c1,
+ 0x2660, 0x2013,
+ 0x2661, 0x1f51,
+ 0x2662, 0x1f53,
+ 0x2663, 0x2015,
+ 0x2664, 0x1f52,
+ 0x2665, 0x2014,
+ 0x2666, 0x2016,
+ 0x2667, 0x1f50,
+ 0x266a, 0x0307,
+ 0x266d, 0x0306,
+ 0x266f, 0x0305,
+ 0x2776, 0x205e,
+ 0x27a1, 0x200e,
+ 0x3000, 0x0279,
+ 0x3003, 0x028f,
+ 0x3004, 0x2074,
+ 0x3005, 0x0291,
+ 0x3008, 0x02aa,
+ 0x3012, 0x02df,
+ 0x3013, 0x02e4,
+ 0x3014, 0x02a4,
+ 0x301c, 0x0299,
+ 0x301d, 0x1db8,
+ 0x301f, 0x1db9,
+ 0x3020, 0x1f7a,
+ 0x3036, 0x1f79,
+ 0x3041, 0x034a,
+ 0x3094, 0x1f16,
+ 0x309b, 0x0283,
+ 0x309d, 0x028d,
+ 0x30a1, 0x039d,
+ 0x30f7, 0x2079,
+ 0x30fb, 0x027e,
+ 0x30fc, 0x0294,
+ 0x30fd, 0x028b,
+ 0x322a, 0x2006,
+ 0x3230, 0x2005,
+ 0x3231, 0x1dc2,
+ 0x3233, 0x1fcf,
+ 0x3234, 0x1fcd,
+ 0x3235, 0x1fd4,
+ 0x3236, 0x1fd3,
+ 0x3237, 0x200c,
+ 0x3238, 0x1fce,
+ 0x3239, 0x1dc4,
+ 0x323a, 0x1fd7,
+ 0x323b, 0x1fd5,
+ 0x323c, 0x1fd0,
+ 0x323d, 0x1fcb,
+ 0x323e, 0x1fd2,
+ 0x323f, 0x1fcc,
+ 0x3240, 0x1fd6,
+ 0x3241, 0x200d,
+ 0x3242, 0x1fd1,
+ 0x3243, 0x1fca,
+ 0x3291, 0x1fe1,
+ 0x3292, 0x1fe0,
+ 0x3293, 0x1fe2,
+ 0x3294, 0x1fdc,
+ 0x3296, 0x1fe5,
+ 0x3298, 0x1fde,
+ 0x3299, 0x201f,
+ 0x329d, 0x207f,
+ 0x329e, 0x1fff,
+ 0x32a4, 0x1dbd,
+ 0x32a9, 0x1fda,
+ 0x32aa, 0x1fdd,
+ 0x32ab, 0x1fdf,
+ 0x32ac, 0x1fe3,
+ 0x32ad, 0x1fd9,
+ 0x32ae, 0x1fe4,
+ 0x32af, 0x1fdb,
+ 0x32b0, 0x1fd8,
+ 0x3300, 0x1f70,
+ 0x3303, 0x1f6a,
+ 0x3305, 0x1ff7,
+ 0x330d, 0x1dab,
+ 0x3314, 0x1da2,
+ 0x3315, 0x1f69,
+ 0x3316, 0x1f67,
+ 0x3318, 0x1f68,
+ 0x331e, 0x1f73,
+ 0x3322, 0x1f66,
+ 0x3323, 0x1f6b,
+ 0x3326, 0x1dac,
+ 0x3327, 0x1da6,
+ 0x332a, 0x1f74,
+ 0x332b, 0x1dae,
+ 0x3331, 0x1f71,
+ 0x3333, 0x2087,
+ 0x3336, 0x1da8,
+ 0x3339, 0x1f6e,
+ 0x333b, 0x1f6f,
+ 0x3342, 0x1f6d,
+ 0x3347, 0x1f72,
+ 0x3349, 0x1da1,
+ 0x334a, 0x1daf,
+ 0x334d, 0x1da4,
+ 0x334e, 0x2088,
+ 0x3351, 0x1da9,
+ 0x3357, 0x1f6c,
+ 0x337b, 0x2083,
+ 0x337c, 0x1dc7,
+ 0x337d, 0x1dc6,
+ 0x337e, 0x1dc5,
+ 0x337f, 0x1f76,
+ 0x3385, 0x1f5f,
+ 0x3388, 0x2000,
+ 0x338e, 0x1db4,
+ 0x3390, 0x1f63,
+ 0x3396, 0x1f65,
+ 0x3397, 0x1f58,
+ 0x3398, 0x1f5a,
+ 0x339c, 0x1db1,
+ 0x339f, 0x1ffa,
+ 0x33a0, 0x1f54,
+ 0x33a1, 0x1db7,
+ 0x33a2, 0x1f55,
+ 0x33a3, 0x1ffb,
+ 0x33a4, 0x1f56,
+ 0x33a6, 0x1ffc,
+ 0x33b0, 0x1f5e,
+ 0x33b1, 0x1f5d,
+ 0x33b2, 0x1f5c,
+ 0x33b3, 0x1f5b,
+ 0x33c4, 0x1db6,
+ 0x33c8, 0x2002,
+ 0x33cb, 0x1f62,
+ 0x33cc, 0x1ff6,
+ 0x33cd, 0x1dbb,
+ 0x33d4, 0x1f64,
+ 0x4e00, 0x04b0,
+ 0x4e01, 0x0bb8,
+ 0x4e03, 0x08e3,
+ 0x4e07, 0x0eaa,
+ 0x4e08, 0x09ce,
+ 0x4e09, 0x087e,
+ 0x4e0a, 0x09cd,
+ 0x4e0b, 0x053c,
+ 0x4e0d, 0x0dc6,
+ 0x4e0e, 0x0f29,
+ 0x4e10, 0x0ffb,
+ 0x4e11, 0x04d1,
+ 0x4e14, 0x05cc,
+ 0x4e15, 0x0ffc,
+ 0x4e16, 0x0a48,
+ 0x4e17, 0x10d7,
+ 0x4e18, 0x0670,
+ 0x4e19, 0x0e0a,
+ 0x4e1e, 0x09cf,
+ 0x4e21, 0x0f86,
+ 0x4e26, 0x0e12,
+ 0x4e28, 0x20b3,
+ 0x4e2a, 0x0ffd,
+ 0x4e2d, 0x0ba4,
+ 0x4e31, 0x0ffe,
+ 0x4e32, 0x06f2,
+ 0x4e36, 0x0fff,
+ 0x4e38, 0x0619,
+ 0x4e39, 0x0b6e,
+ 0x4e3b, 0x0913,
+ 0x4e3c, 0x1000,
+ 0x4e3f, 0x1001,
+ 0x4e42, 0x1002,
+ 0x4e43, 0x0ceb,
+ 0x4e45, 0x0671,
+ 0x4e4b, 0x0ced,
+ 0x4e4d, 0x0cbb,
+ 0x4e4e, 0x0777,
+ 0x4e4f, 0x0e61,
+ 0x4e55, 0x1950,
+ 0x4e56, 0x1003,
+ 0x4e57, 0x09d0,
+ 0x4e58, 0x1004,
+ 0x4e59, 0x0535,
+ 0x4e5d, 0x06dd,
+ 0x4e5e, 0x07a4,
+ 0x4e5f, 0x0ef5,
+ 0x4e62, 0x1233,
+ 0x4e71, 0x0f5a,
+ 0x4e73, 0x0cd5,
+ 0x4e7e, 0x05e1,
+ 0x4e80, 0x064f,
+ 0x4e82, 0x1005,
+ 0x4e85, 0x1006,
+ 0x4e86, 0x0f83,
+ 0x4e88, 0x0f27,
+ 0x4e89, 0x0aea,
+ 0x4e8a, 0x1008,
+ 0x4e8b, 0x08c4,
+ 0x4e8c, 0x0ccb,
+ 0x4e8e, 0x100b,
+ 0x4e91, 0x04e0,
+ 0x4e92, 0x0793,
+ 0x4e94, 0x0792,
+ 0x4e95, 0x04aa,
+ 0x4e98, 0x0ff1,
+ 0x4e99, 0x0ff0,
+ 0x4e9b, 0x0823,
+ 0x4e9c, 0x0465,
+ 0x4e9e, 0x100c,
+ 0x4ea1, 0x0e62,
+ 0x4ea2, 0x100f,
+ 0x4ea4, 0x07a6,
+ 0x4ea5, 0x04ab,
+ 0x4ea6, 0x0ea0,
+ 0x4ea8, 0x0696,
+ 0x4eab, 0x0697,
+ 0x4ead, 0x0bfe,
+ 0x4eae, 0x0f84,
+ 0x4eb0, 0x1010,
+ 0x4eb3, 0x1011,
+ 0x4eb6, 0x1012,
+ 0x4eba, 0x0a13,
+ 0x4ec0, 0x0944,
+ 0x4ec1, 0x0a14,
+ 0x4ec2, 0x1017,
+ 0x4ec4, 0x1015,
+ 0x4ec6, 0x1016,
+ 0x4ec7, 0x0672,
+ 0x4eca, 0x0813,
+ 0x4ecb, 0x0570,
+ 0x4ecd, 0x1014,
+ 0x4ece, 0x1013,
+ 0x4ecf, 0x0df9,
+ 0x4ed4, 0x0894,
+ 0x4ed5, 0x0893,
+ 0x4ed6, 0x0b1e,
+ 0x4ed7, 0x1018,
+ 0x4ed8, 0x0dc7,
+ 0x4ed9, 0x0a8b,
+ 0x4edd, 0x0290,
+ 0x4ede, 0x1019,
+ 0x4edf, 0x101b,
+ 0x4ee1, 0x20b4,
+ 0x4ee3, 0x0b45,
+ 0x4ee4, 0x0fa9,
+ 0x4ee5, 0x048e,
+ 0x4eed, 0x101a,
+ 0x4eee, 0x053e,
+ 0x4ef0, 0x06bc,
+ 0x4ef2, 0x0ba5,
+ 0x4ef6, 0x0745,
+ 0x4ef7, 0x101c,
+ 0x4efb, 0x0cda,
+ 0x4efc, 0x20b5,
+ 0x4f00, 0x20b6,
+ 0x4f01, 0x0627,
+ 0x4f03, 0x20b7,
+ 0x4f09, 0x101d,
+ 0x4f0a, 0x048f,
+ 0x4f0d, 0x0794,
+ 0x4f0e, 0x0628,
+ 0x4f0f, 0x0dec,
+ 0x4f10, 0x0d46,
+ 0x4f11, 0x0673,
+ 0x4f1a, 0x0571,
+ 0x4f1c, 0x1040,
+ 0x4f1d, 0x0c3b,
+ 0x4f2f, 0x0d22,
+ 0x4f30, 0x101f,
+ 0x4f34, 0x0d50,
+ 0x4f36, 0x0faa,
+ 0x4f38, 0x09f3,
+ 0x4f39, 0x20b8,
+ 0x4f3a, 0x0895,
+ 0x4f3c, 0x08c5,
+ 0x4f3d, 0x0540,
+ 0x4f43, 0x0bed,
+ 0x4f46, 0x0b60,
+ 0x4f47, 0x1023,
+ 0x4f4d, 0x0490,
+ 0x4f4e, 0x0bff,
+ 0x4f4f, 0x0945,
+ 0x4f50, 0x0824,
+ 0x4f51, 0x0f0e,
+ 0x4f53, 0x0b2e,
+ 0x4f55, 0x053f,
+ 0x4f56, 0x20b9,
+ 0x4f57, 0x1022,
+ 0x4f59, 0x0f28,
+ 0x4f5a, 0x101e,
+ 0x4f5b, 0x1020,
+ 0x4f5c, 0x085e,
+ 0x4f5d, 0x1021,
+ 0x4f5e, 0x11d3,
+ 0x4f69, 0x1029,
+ 0x4f6f, 0x102c,
+ 0x4f70, 0x102a,
+ 0x4f73, 0x0542,
+ 0x4f75, 0x0e0b,
+ 0x4f76, 0x1024,
+ 0x4f7b, 0x1028,
+ 0x4f7c, 0x07a7,
+ 0x4f7f, 0x0896,
+ 0x4f83, 0x05e2,
+ 0x4f86, 0x102d,
+ 0x4f88, 0x1025,
+ 0x4f8a, 0x20bb,
+ 0x4f8b, 0x0fab,
+ 0x4f8d, 0x08c6,
+ 0x4f8f, 0x1026,
+ 0x4f91, 0x102b,
+ 0x4f92, 0x20ba,
+ 0x4f94, 0x20bd,
+ 0x4f96, 0x102e,
+ 0x4f98, 0x1027,
+ 0x4f9a, 0x20bc,
+ 0x4f9b, 0x0699,
+ 0x4f9d, 0x0491,
+ 0x4fa0, 0x069a,
+ 0x4fa1, 0x0541,
+ 0x4fab, 0x11d4,
+ 0x4fad, 0x0ea7,
+ 0x4fae, 0x0de0,
+ 0x4faf, 0x07a8,
+ 0x4fb5, 0x09f5,
+ 0x4fb6, 0x0f7f,
+ 0x4fbf, 0x0e28,
+ 0x4fc2, 0x070e,
+ 0x4fc3, 0x0b05,
+ 0x4fc4, 0x0564,
+ 0x4fc9, 0x20ac,
+ 0x4fca, 0x095d,
+ 0x4fcd, 0x20be,
+ 0x4fce, 0x1032,
+ 0x4fd0, 0x1037,
+ 0x4fd1, 0x1035,
+ 0x4fd4, 0x1030,
+ 0x4fd7, 0x0b0f,
+ 0x4fd8, 0x1033,
+ 0x4fda, 0x1036,
+ 0x4fdb, 0x1034,
+ 0x4fdd, 0x0e2d,
+ 0x4fdf, 0x1031,
+ 0x4fe0, 0x1dec,
+ 0x4fe1, 0x09f4,
+ 0x4fe3, 0x0ea1,
+ 0x4fe4, 0x1038,
+ 0x4fee, 0x092e,
+ 0x4fef, 0x1046,
+ 0x4ff3, 0x0d06,
+ 0x4ff5, 0x0da8,
+ 0x4ff6, 0x1041,
+ 0x4ff8, 0x0e40,
+ 0x4ffa, 0x0536,
+ 0x4ffe, 0x1045,
+ 0x4fff, 0x20c1,
+ 0x5005, 0x103f,
+ 0x5006, 0x1048,
+ 0x5009, 0x0ad4,
+ 0x500b, 0x0778,
+ 0x500d, 0x0d12,
+ 0x500f, 0x1600,
+ 0x5011, 0x1047,
+ 0x5012, 0x0c57,
+ 0x5014, 0x103c,
+ 0x5016, 0x07aa,
+ 0x5019, 0x07a9,
+ 0x501a, 0x103a,
+ 0x501e, 0x20c2,
+ 0x501f, 0x0906,
+ 0x5021, 0x1042,
+ 0x5022, 0x20c0,
+ 0x5023, 0x0e3f,
+ 0x5024, 0x0b8b,
+ 0x5025, 0x103e,
+ 0x5026, 0x0747,
+ 0x5028, 0x103b,
+ 0x5029, 0x1043,
+ 0x502a, 0x103d,
+ 0x502b, 0x0f99,
+ 0x502c, 0x1044,
+ 0x502d, 0x0fe7,
+ 0x5036, 0x06de,
+ 0x5039, 0x0746,
+ 0x5040, 0x20bf,
+ 0x5042, 0x20c5,
+ 0x5043, 0x1049,
+ 0x5046, 0x20c3,
+ 0x5047, 0x104a,
+ 0x5048, 0x104e,
+ 0x5049, 0x0492,
+ 0x504f, 0x0e20,
+ 0x5050, 0x104d,
+ 0x5055, 0x104c,
+ 0x5056, 0x1050,
+ 0x505a, 0x104f,
+ 0x505c, 0x0c00,
+ 0x5065, 0x0748,
+ 0x506c, 0x1051,
+ 0x5070, 0x20c4,
+ 0x5072, 0x08f1,
+ 0x5074, 0x0b06,
+ 0x5075, 0x0c01,
+ 0x5076, 0x06ee,
+ 0x5078, 0x1052,
+ 0x507d, 0x0650,
+ 0x5080, 0x1053,
+ 0x5085, 0x1055,
+ 0x508d, 0x0e63,
+ 0x5091, 0x073c,
+ 0x5094, 0x20c6,
+ 0x5098, 0x087f,
+ 0x5099, 0x0d8b,
+ 0x509a, 0x1054,
+ 0x50ac, 0x0835,
+ 0x50ad, 0x0f2d,
+ 0x50b2, 0x1057,
+ 0x50b3, 0x105a,
+ 0x50b4, 0x1056,
+ 0x50b5, 0x0834,
+ 0x50b7, 0x0987,
+ 0x50be, 0x070f,
+ 0x50c2, 0x105b,
+ 0x50c5, 0x06c7,
+ 0x50c9, 0x1058,
+ 0x50cd, 0x0c87,
+ 0x50cf, 0x0afe,
+ 0x50d1, 0x069b,
+ 0x50d5, 0x0e7b,
+ 0x50d6, 0x105c,
+ 0x50d8, 0x20c8,
+ 0x50da, 0x0f85,
+ 0x50de, 0x105d,
+ 0x50e3, 0x1060,
+ 0x50e5, 0x105e,
+ 0x50e7, 0x0ad0,
+ 0x50ed, 0x105f,
+ 0x50ee, 0x1061,
+ 0x50f4, 0x20c7,
+ 0x50f5, 0x1063,
+ 0x50f9, 0x1062,
+ 0x50fb, 0x0e18,
+ 0x5100, 0x0651,
+ 0x5101, 0x1065,
+ 0x5104, 0x052f,
+ 0x5109, 0x1064,
+ 0x5112, 0x0920,
+ 0x5114, 0x1069,
+ 0x5115, 0x1068,
+ 0x5116, 0x1067,
+ 0x5118, 0x102f,
+ 0x511a, 0x106a,
+ 0x511f, 0x0988,
+ 0x5121, 0x106b,
+ 0x512a, 0x0f0f,
+ 0x5132, 0x0ee5,
+ 0x5137, 0x106d,
+ 0x513a, 0x106c,
+ 0x513b, 0x106f,
+ 0x513c, 0x106e,
+ 0x513f, 0x1070,
+ 0x5141, 0x04b8,
+ 0x5143, 0x0769,
+ 0x5144, 0x0711,
+ 0x5145, 0x0946,
+ 0x5146, 0x0bb9,
+ 0x5147, 0x069c,
+ 0x5148, 0x0a8c,
+ 0x5149, 0x07ab,
+ 0x514a, 0x20c9,
+ 0x514b, 0x0800,
+ 0x514c, 0x1073,
+ 0x514d, 0x0ed4,
+ 0x514e, 0x0c40,
+ 0x5150, 0x08c7,
+ 0x5152, 0x1072,
+ 0x5154, 0x1074,
+ 0x515a, 0x0c58,
+ 0x515c, 0x05d3,
+ 0x5162, 0x1075,
+ 0x5164, 0x20ca,
+ 0x5165, 0x0cd6,
+ 0x5168, 0x0ab6,
+ 0x5169, 0x1077,
+ 0x516b, 0x0d40,
+ 0x516c, 0x07ac,
+ 0x516d, 0x0fe1,
+ 0x516e, 0x1079,
+ 0x5171, 0x069e,
+ 0x5175, 0x0e0c,
+ 0x5176, 0x0b16,
+ 0x5177, 0x06e9,
+ 0x5178, 0x0c2f,
+ 0x517c, 0x0749,
+ 0x5180, 0x107a,
+ 0x5182, 0x107b,
+ 0x5185, 0x0cba,
+ 0x5186, 0x0501,
+ 0x5189, 0x107e,
+ 0x518a, 0x086d,
+ 0x518c, 0x107d,
+ 0x518d, 0x0836,
+ 0x518f, 0x107f,
+ 0x5190, 0x185b,
+ 0x5191, 0x1080,
+ 0x5192, 0x0e6f,
+ 0x5193, 0x1081,
+ 0x5195, 0x1082,
+ 0x5197, 0x09d1,
+ 0x5199, 0x08f8,
+ 0x519d, 0x20cb,
+ 0x51a0, 0x05e3,
+ 0x51a2, 0x1086,
+ 0x51a4, 0x1084,
+ 0x51a5, 0x0ec9,
+ 0x51a6, 0x1085,
+ 0x51a8, 0x0dcc,
+ 0x51a9, 0x1087,
+ 0x51ac, 0x0c59,
+ 0x51b0, 0x108d,
+ 0x51b1, 0x108b,
+ 0x51b3, 0x108a,
+ 0x51b4, 0x0853,
+ 0x51b5, 0x108e,
+ 0x51b6, 0x0ef6,
+ 0x51b7, 0x0fac,
+ 0x51bd, 0x108f,
+ 0x51be, 0x20cc,
+ 0x51c4, 0x0a4c,
+ 0x51c5, 0x1090,
+ 0x51c6, 0x0964,
+ 0x51c9, 0x1091,
+ 0x51cb, 0x0bba,
+ 0x51cc, 0x0f87,
+ 0x51cd, 0x0c5a,
+ 0x51d6, 0x10da,
+ 0x51db, 0x1092,
+ 0x51dc, 0x205c,
+ 0x51dd, 0x06bd,
+ 0x51e0, 0x1093,
+ 0x51e1, 0x0e8c,
+ 0x51e6, 0x0972,
+ 0x51e7, 0x0b5c,
+ 0x51e9, 0x1095,
+ 0x51ea, 0x0cbc,
+ 0x51ec, 0x20cd,
+ 0x51ed, 0x1096,
+ 0x51f0, 0x1097,
+ 0x51f1, 0x058c,
+ 0x51f5, 0x1098,
+ 0x51f6, 0x069f,
+ 0x51f8, 0x0ca4,
+ 0x51f9, 0x051c,
+ 0x51fa, 0x095a,
+ 0x51fd, 0x0d35,
+ 0x51fe, 0x1099,
+ 0x5200, 0x0c5b,
+ 0x5203, 0x0a15,
+ 0x5204, 0x109a,
+ 0x5206, 0x0dfc,
+ 0x5207, 0x0a7e,
+ 0x5208, 0x05de,
+ 0x520a, 0x05e5,
+ 0x520b, 0x109b,
+ 0x520e, 0x109d,
+ 0x5211, 0x0710,
+ 0x5214, 0x109c,
+ 0x5215, 0x20ce,
+ 0x5217, 0x0fbb,
+ 0x521d, 0x0973,
+ 0x5224, 0x0d51,
+ 0x5225, 0x0e1c,
+ 0x5227, 0x109e,
+ 0x5229, 0x0f62,
+ 0x522a, 0x109f,
+ 0x522e, 0x10a0,
+ 0x5230, 0x0c78,
+ 0x5233, 0x10a1,
+ 0x5236, 0x0a4d,
+ 0x5237, 0x086e,
+ 0x5238, 0x074a,
+ 0x5239, 0x10a2,
+ 0x523a, 0x0897,
+ 0x523b, 0x0801,
+ 0x5243, 0x0c02,
+ 0x5244, 0x10a4,
+ 0x5247, 0x0b07,
+ 0x524a, 0x085f,
+ 0x524b, 0x10a5,
+ 0x524d, 0x0ab2,
+ 0x524f, 0x10a3,
+ 0x5254, 0x10a8,
+ 0x5256, 0x0e64,
+ 0x525b, 0x07f6,
+ 0x525d, 0x1e5e,
+ 0x525e, 0x10a7,
+ 0x5263, 0x074b,
+ 0x5264, 0x084e,
+ 0x5265, 0x0d23,
+ 0x5269, 0x10ab,
+ 0x526a, 0x10a9,
+ 0x526f, 0x0ded,
+ 0x5270, 0x09d2,
+ 0x5271, 0x10b2,
+ 0x5272, 0x05c2,
+ 0x5273, 0x10ac,
+ 0x5274, 0x10aa,
+ 0x5275, 0x0ad1,
+ 0x527d, 0x10ae,
+ 0x527f, 0x10ad,
+ 0x5283, 0x05a2,
+ 0x5287, 0x0736,
+ 0x5288, 0x10b3,
+ 0x5289, 0x0f75,
+ 0x528d, 0x10af,
+ 0x5291, 0x10b4,
+ 0x5292, 0x10b1,
+ 0x5294, 0x10b0,
+ 0x529b, 0x0f97,
+ 0x529c, 0x20cf,
+ 0x529f, 0x07ad,
+ 0x52a0, 0x0543,
+ 0x52a3, 0x0fbc,
+ 0x52a6, 0x20d0,
+ 0x52a9, 0x097f,
+ 0x52aa, 0x0c52,
+ 0x52ab, 0x07f7,
+ 0x52ac, 0x10b7,
+ 0x52af, 0x217d,
+ 0x52b1, 0x0fad,
+ 0x52b4, 0x0fd1,
+ 0x52b5, 0x10ba,
+ 0x52b9, 0x07ae,
+ 0x52bc, 0x10b9,
+ 0x52be, 0x058d,
+ 0x52c0, 0x20d1,
+ 0x52c1, 0x10bb,
+ 0x52c3, 0x0e84,
+ 0x52c5, 0x0bd8,
+ 0x52c7, 0x0f10,
+ 0x52c9, 0x0e29,
+ 0x52cd, 0x10bc,
+ 0x52d2, 0x1bee,
+ 0x52d5, 0x0c88,
+ 0x52d7, 0x10bd,
+ 0x52d8, 0x05e6,
+ 0x52d9, 0x0ebf,
+ 0x52db, 0x20d2,
+ 0x52dd, 0x0989,
+ 0x52de, 0x10be,
+ 0x52df, 0x0e37,
+ 0x52e0, 0x10c2,
+ 0x52e2, 0x0a4e,
+ 0x52e3, 0x10bf,
+ 0x52e4, 0x06c8,
+ 0x52e6, 0x10c0,
+ 0x52e7, 0x05e7,
+ 0x52f2, 0x0704,
+ 0x52f3, 0x10c3,
+ 0x52f5, 0x10c4,
+ 0x52f8, 0x10c5,
+ 0x52fa, 0x0907,
+ 0x52fe, 0x07af,
+ 0x52ff, 0x0eea,
+ 0x5300, 0x20d3,
+ 0x5301, 0x0ef4,
+ 0x5302, 0x0ccf,
+ 0x5305, 0x0e41,
+ 0x5306, 0x10c7,
+ 0x5307, 0x20d4,
+ 0x5308, 0x10c8,
+ 0x530d, 0x10ca,
+ 0x530f, 0x10cc,
+ 0x5310, 0x10cb,
+ 0x5315, 0x10cd,
+ 0x5316, 0x053d,
+ 0x5317, 0x0e7a,
+ 0x5319, 0x086c,
+ 0x531a, 0x10ce,
+ 0x531d, 0x0adb,
+ 0x5320, 0x098a,
+ 0x5321, 0x06a1,
+ 0x5323, 0x10cf,
+ 0x5324, 0x20d5,
+ 0x532a, 0x0d6f,
+ 0x532f, 0x10d0,
+ 0x5331, 0x10d1,
+ 0x5333, 0x10d2,
+ 0x5338, 0x10d3,
+ 0x5339, 0x0d96,
+ 0x533a, 0x06e0,
+ 0x533b, 0x04a9,
+ 0x533f, 0x0c97,
+ 0x5340, 0x10d4,
+ 0x5341, 0x0947,
+ 0x5343, 0x0a8d,
+ 0x5345, 0x10d6,
+ 0x5346, 0x10d5,
+ 0x5347, 0x098b,
+ 0x5348, 0x0795,
+ 0x5349, 0x10d8,
+ 0x534a, 0x0d52,
+ 0x534d, 0x10d9,
+ 0x5351, 0x0d70,
+ 0x5352, 0x0b14,
+ 0x5353, 0x0b4e,
+ 0x5354, 0x06a0,
+ 0x5357, 0x0cc6,
+ 0x5358, 0x0b6f,
+ 0x535a, 0x0d24,
+ 0x535c, 0x0e7c,
+ 0x535e, 0x10db,
+ 0x5360, 0x0a8e,
+ 0x5366, 0x070b,
+ 0x5369, 0x10dc,
+ 0x536e, 0x10dd,
+ 0x536f, 0x04ce,
+ 0x5370, 0x04b9,
+ 0x5371, 0x0629,
+ 0x5372, 0x20d6,
+ 0x5373, 0x0b08,
+ 0x5374, 0x066b,
+ 0x5375, 0x0f5b,
+ 0x5377, 0x10e0,
+ 0x5378, 0x0537,
+ 0x537b, 0x10df,
+ 0x537f, 0x06a2,
+ 0x5382, 0x10e1,
+ 0x5384, 0x0efd,
+ 0x5393, 0x20d7,
+ 0x5396, 0x10e2,
+ 0x5398, 0x0f9a,
+ 0x539a, 0x07b0,
+ 0x539f, 0x076a,
+ 0x53a0, 0x10e3,
+ 0x53a5, 0x10e5,
+ 0x53a6, 0x10e4,
+ 0x53a8, 0x0a25,
+ 0x53a9, 0x04db,
+ 0x53ad, 0x0500,
+ 0x53ae, 0x10e6,
+ 0x53b0, 0x10e7,
+ 0x53b2, 0x20d8,
+ 0x53b3, 0x076b,
+ 0x53b6, 0x10e8,
+ 0x53bb, 0x0688,
+ 0x53c2, 0x0880,
+ 0x53c3, 0x10e9,
+ 0x53c8, 0x0ea2,
+ 0x53c9, 0x0825,
+ 0x53ca, 0x0674,
+ 0x53cb, 0x0f11,
+ 0x53cc, 0x0ad2,
+ 0x53cd, 0x0d53,
+ 0x53ce, 0x0929,
+ 0x53d4, 0x0951,
+ 0x53d6, 0x0914,
+ 0x53d7, 0x0921,
+ 0x53d9, 0x0980,
+ 0x53db, 0x0d54,
+ 0x53dd, 0x20d9,
+ 0x53df, 0x10ec,
+ 0x53e1, 0x04e5,
+ 0x53e2, 0x0ad3,
+ 0x53e3, 0x07b1,
+ 0x53e4, 0x0779,
+ 0x53e5, 0x06df,
+ 0x53e8, 0x10f0,
+ 0x53e9, 0x0b5f,
+ 0x53ea, 0x0b5e,
+ 0x53eb, 0x06a3,
+ 0x53ec, 0x098c,
+ 0x53ed, 0x10f1,
+ 0x53ee, 0x10ef,
+ 0x53ef, 0x0544,
+ 0x53f0, 0x0b46,
+ 0x53f1, 0x08e4,
+ 0x53f2, 0x0899,
+ 0x53f3, 0x04c8,
+ 0x53f6, 0x05ce,
+ 0x53f7, 0x07f8,
+ 0x53f8, 0x0898,
+ 0x53fa, 0x10f2,
+ 0x5401, 0x10f3,
+ 0x5403, 0x0663,
+ 0x5404, 0x05a4,
+ 0x5408, 0x07f9,
+ 0x5409, 0x0662,
+ 0x540a, 0x0bfb,
+ 0x540b, 0x04c7,
+ 0x540c, 0x0c89,
+ 0x540d, 0x0eca,
+ 0x540e, 0x07b3,
+ 0x540f, 0x0f63,
+ 0x5410, 0x0c41,
+ 0x5411, 0x07b2,
+ 0x541b, 0x0705,
+ 0x541d, 0x10fc,
+ 0x541f, 0x06db,
+ 0x5420, 0x0e78,
+ 0x5426, 0x0d71,
+ 0x5429, 0x10fb,
+ 0x542b, 0x061a,
+ 0x542c, 0x10f6,
+ 0x542e, 0x10f9,
+ 0x5436, 0x10fa,
+ 0x5438, 0x0675,
+ 0x5439, 0x0a27,
+ 0x543b, 0x0dfd,
+ 0x543c, 0x10f8,
+ 0x543d, 0x10f4,
+ 0x543e, 0x0797,
+ 0x5440, 0x10f5,
+ 0x5442, 0x0fca,
+ 0x5446, 0x0e42,
+ 0x5448, 0x0c04,
+ 0x5449, 0x0796,
+ 0x544a, 0x0802,
+ 0x544e, 0x10fd,
+ 0x5451, 0x0cb5,
+ 0x545f, 0x1101,
+ 0x5468, 0x092a,
+ 0x546a, 0x0922,
+ 0x5470, 0x1104,
+ 0x5471, 0x1102,
+ 0x5473, 0x0eaf,
+ 0x5475, 0x10ff,
+ 0x5476, 0x1108,
+ 0x5477, 0x1103,
+ 0x547b, 0x1106,
+ 0x547c, 0x077a,
+ 0x547d, 0x0ecb,
+ 0x5480, 0x1107,
+ 0x5484, 0x1109,
+ 0x5486, 0x110b,
+ 0x548a, 0x20dc,
+ 0x548b, 0x0860,
+ 0x548c, 0x0fe8,
+ 0x548e, 0x1100,
+ 0x548f, 0x10fe,
+ 0x5490, 0x110a,
+ 0x5492, 0x1105,
+ 0x549c, 0x20db,
+ 0x54a2, 0x110d,
+ 0x54a4, 0x1116,
+ 0x54a5, 0x110f,
+ 0x54a8, 0x1113,
+ 0x54a9, 0x20dd,
+ 0x54ab, 0x1114,
+ 0x54ac, 0x1110,
+ 0x54af, 0x1131,
+ 0x54b2, 0x0859,
+ 0x54b3, 0x058f,
+ 0x54b8, 0x110e,
+ 0x54bc, 0x1118,
+ 0x54bd, 0x04ba,
+ 0x54be, 0x1117,
+ 0x54c0, 0x0469,
+ 0x54c1, 0x0dbc,
+ 0x54c2, 0x1115,
+ 0x54c4, 0x1111,
+ 0x54c7, 0x110c,
+ 0x54c8, 0x1112,
+ 0x54c9, 0x0838,
+ 0x54d8, 0x1119,
+ 0x54e1, 0x04bb,
+ 0x54e2, 0x1122,
+ 0x54e5, 0x111a,
+ 0x54e8, 0x098d,
+ 0x54e9, 0x0e97,
+ 0x54ed, 0x1120,
+ 0x54ee, 0x111f,
+ 0x54f2, 0x0c29,
+ 0x54fa, 0x1121,
+ 0x54fd, 0x111e,
+ 0x54ff, 0x20de,
+ 0x5504, 0x04d6,
+ 0x5506, 0x0826,
+ 0x5507, 0x09f6,
+ 0x550f, 0x111c,
+ 0x5510, 0x0c5c,
+ 0x5514, 0x111d,
+ 0x5516, 0x0466,
+ 0x552e, 0x1127,
+ 0x552f, 0x0f0d,
+ 0x5531, 0x098f,
+ 0x5533, 0x112d,
+ 0x5538, 0x112c,
+ 0x5539, 0x1123,
+ 0x553e, 0x0b23,
+ 0x5540, 0x1124,
+ 0x5544, 0x0b4f,
+ 0x5545, 0x1129,
+ 0x5546, 0x098e,
+ 0x554c, 0x1126,
+ 0x554f, 0x0ef0,
+ 0x5553, 0x0712,
+ 0x5556, 0x112a,
+ 0x555c, 0x1128,
+ 0x555d, 0x112e,
+ 0x555e, 0x1dd1,
+ 0x5563, 0x1125,
+ 0x557b, 0x1134,
+ 0x557c, 0x1139,
+ 0x557e, 0x1135,
+ 0x5580, 0x1130,
+ 0x5583, 0x113a,
+ 0x5584, 0x0ab3,
+ 0x5586, 0x20df,
+ 0x5587, 0x113c,
+ 0x5589, 0x07b4,
+ 0x558a, 0x1132,
+ 0x558b, 0x0bbb,
+ 0x5598, 0x1136,
+ 0x5599, 0x112f,
+ 0x559a, 0x05e9,
+ 0x559c, 0x062a,
+ 0x559d, 0x05c3,
+ 0x559e, 0x1137,
+ 0x559f, 0x1133,
+ 0x55a7, 0x074c,
+ 0x55a8, 0x113d,
+ 0x55a9, 0x113b,
+ 0x55aa, 0x0ad5,
+ 0x55ab, 0x0664,
+ 0x55ac, 0x06a4,
+ 0x55ae, 0x1138,
+ 0x55b0, 0x06ec,
+ 0x55b6, 0x04e6,
+ 0x55c4, 0x1141,
+ 0x55c5, 0x113f,
+ 0x55c7, 0x1178,
+ 0x55d4, 0x1144,
+ 0x55da, 0x113e,
+ 0x55dc, 0x1142,
+ 0x55df, 0x1140,
+ 0x55e3, 0x089a,
+ 0x55e4, 0x1143,
+ 0x55f7, 0x1146,
+ 0x55f9, 0x114b,
+ 0x55fd, 0x1149,
+ 0x55fe, 0x1148,
+ 0x5606, 0x0b70,
+ 0x5609, 0x0545,
+ 0x5614, 0x1145,
+ 0x5616, 0x1147,
+ 0x5617, 0x0990,
+ 0x5618, 0x04d5,
+ 0x561b, 0x114a,
+ 0x5629, 0x055e,
+ 0x562f, 0x1155,
+ 0x5631, 0x09e4,
+ 0x5632, 0x1151,
+ 0x5634, 0x114f,
+ 0x5636, 0x1150,
+ 0x5638, 0x1152,
+ 0x5642, 0x04df,
+ 0x564c, 0x0abb,
+ 0x564e, 0x114c,
+ 0x5650, 0x114d,
+ 0x5653, 0x1f1b,
+ 0x565b, 0x05d8,
+ 0x5664, 0x1154,
+ 0x5668, 0x062b,
+ 0x566a, 0x1157,
+ 0x566b, 0x1153,
+ 0x566c, 0x1156,
+ 0x5674, 0x0dfe,
+ 0x5678, 0x0cad,
+ 0x567a, 0x0d4c,
+ 0x5680, 0x1159,
+ 0x5686, 0x1158,
+ 0x5687, 0x05a3,
+ 0x568a, 0x115a,
+ 0x568f, 0x115d,
+ 0x5694, 0x115c,
+ 0x5699, 0x1de6,
+ 0x56a0, 0x115b,
+ 0x56a2, 0x0cef,
+ 0x56a5, 0x115e,
+ 0x56ae, 0x115f,
+ 0x56b4, 0x1161,
+ 0x56b6, 0x1160,
+ 0x56bc, 0x1163,
+ 0x56c0, 0x1166,
+ 0x56c1, 0x1164,
+ 0x56c2, 0x1162,
+ 0x56c3, 0x1165,
+ 0x56c8, 0x1167,
+ 0x56ca, 0x1e5a,
+ 0x56ce, 0x1168,
+ 0x56d1, 0x1169,
+ 0x56d3, 0x116a,
+ 0x56d7, 0x116b,
+ 0x56d8, 0x107c,
+ 0x56da, 0x0928,
+ 0x56db, 0x089b,
+ 0x56de, 0x0573,
+ 0x56e0, 0x04bc,
+ 0x56e3, 0x0b82,
+ 0x56ee, 0x116c,
+ 0x56f0, 0x0814,
+ 0x56f2, 0x0493,
+ 0x56f3, 0x0a24,
+ 0x56f9, 0x116d,
+ 0x56fa, 0x077b,
+ 0x56fd, 0x0803,
+ 0x56ff, 0x116f,
+ 0x5700, 0x116e,
+ 0x5703, 0x0e30,
+ 0x5704, 0x1170,
+ 0x5708, 0x1172,
+ 0x5709, 0x1171,
+ 0x570b, 0x1173,
+ 0x570d, 0x1174,
+ 0x570f, 0x074d,
+ 0x5712, 0x0502,
+ 0x5713, 0x1175,
+ 0x5716, 0x1177,
+ 0x5718, 0x1176,
+ 0x571c, 0x1179,
+ 0x571f, 0x0c54,
+ 0x5726, 0x117a,
+ 0x5727, 0x0479,
+ 0x5728, 0x084f,
+ 0x572d, 0x0713,
+ 0x5730, 0x0b8d,
+ 0x5737, 0x117b,
+ 0x573b, 0x117e,
+ 0x5740, 0x117f,
+ 0x5742, 0x0854,
+ 0x5747, 0x06c9,
+ 0x574a, 0x0e65,
+ 0x574e, 0x117d,
+ 0x574f, 0x1180,
+ 0x5750, 0x0831,
+ 0x5751, 0x07b5,
+ 0x5759, 0x20e0,
+ 0x5761, 0x1184,
+ 0x5764, 0x0815,
+ 0x5765, 0x20e1,
+ 0x5766, 0x0b71,
+ 0x5769, 0x1181,
+ 0x576a, 0x0bf6,
+ 0x577f, 0x1185,
+ 0x5782, 0x0a28,
+ 0x5788, 0x1183,
+ 0x5789, 0x1186,
+ 0x578b, 0x0715,
+ 0x5793, 0x1187,
+ 0x57a0, 0x1188,
+ 0x57a2, 0x07b6,
+ 0x57a3, 0x059e,
+ 0x57a4, 0x118a,
+ 0x57aa, 0x118b,
+ 0x57ac, 0x20e2,
+ 0x57b0, 0x118c,
+ 0x57b3, 0x1189,
+ 0x57c0, 0x1182,
+ 0x57c3, 0x118d,
+ 0x57c6, 0x118e,
+ 0x57c7, 0x20e4,
+ 0x57c8, 0x20e3,
+ 0x57cb, 0x0e92,
+ 0x57ce, 0x09d3,
+ 0x57d2, 0x1190,
+ 0x57d4, 0x118f,
+ 0x57d6, 0x1193,
+ 0x57dc, 0x0cee,
+ 0x57df, 0x04ac,
+ 0x57e0, 0x0dc8,
+ 0x57e3, 0x1194,
+ 0x57f4, 0x09e5,
+ 0x57f7, 0x08e5,
+ 0x57f9, 0x0d13,
+ 0x57fa, 0x062c,
+ 0x57fc, 0x085b,
+ 0x5800, 0x0e87,
+ 0x5802, 0x0c8a,
+ 0x5805, 0x074e,
+ 0x5806, 0x0b2f,
+ 0x580a, 0x1192,
+ 0x580b, 0x1195,
+ 0x5815, 0x0b24,
+ 0x5819, 0x1196,
+ 0x581d, 0x1197,
+ 0x5821, 0x1199,
+ 0x5824, 0x0c05,
+ 0x582a, 0x05ea,
+ 0x582f, 0x1d32,
+ 0x5830, 0x0503,
+ 0x5831, 0x0e43,
+ 0x5834, 0x09d4,
+ 0x5835, 0x0c42,
+ 0x583a, 0x0856,
+ 0x583d, 0x119f,
+ 0x5840, 0x0e0d,
+ 0x5841, 0x0fa5,
+ 0x584a, 0x0574,
+ 0x584b, 0x119b,
+ 0x5851, 0x0abc,
+ 0x5852, 0x119e,
+ 0x5854, 0x0c5d,
+ 0x5857, 0x0c43,
+ 0x5858, 0x0c5e,
+ 0x5859, 0x0d4d,
+ 0x585a, 0x0be9,
+ 0x585e, 0x0839,
+ 0x5861, 0x1e47,
+ 0x5862, 0x119a,
+ 0x5869, 0x0518,
+ 0x586b, 0x0c30,
+ 0x5870, 0x119c,
+ 0x5872, 0x1198,
+ 0x5875, 0x0a16,
+ 0x5879, 0x11a0,
+ 0x587e, 0x0958,
+ 0x5883, 0x06a5,
+ 0x5885, 0x11a1,
+ 0x5893, 0x0e38,
+ 0x5897, 0x0aff,
+ 0x589c, 0x0be2,
+ 0x589e, 0x20e7,
+ 0x589f, 0x11a3,
+ 0x58a8, 0x0e7d,
+ 0x58ab, 0x11a4,
+ 0x58ae, 0x11a9,
+ 0x58b2, 0x20e8,
+ 0x58b3, 0x0dff,
+ 0x58b8, 0x11a8,
+ 0x58b9, 0x11a2,
+ 0x58ba, 0x11a5,
+ 0x58bb, 0x11a7,
+ 0x58be, 0x0816,
+ 0x58c1, 0x0e19,
+ 0x58c5, 0x11aa,
+ 0x58c7, 0x0b83,
+ 0x58ca, 0x0575,
+ 0x58cc, 0x09d5,
+ 0x58d1, 0x11ac,
+ 0x58d3, 0x11ab,
+ 0x58d5, 0x07fa,
+ 0x58d7, 0x11ad,
+ 0x58d8, 0x11af,
+ 0x58d9, 0x11ae,
+ 0x58dc, 0x11b1,
+ 0x58de, 0x11a6,
+ 0x58df, 0x11b3,
+ 0x58e4, 0x11b2,
+ 0x58e5, 0x11b0,
+ 0x58eb, 0x089c,
+ 0x58ec, 0x0a17,
+ 0x58ee, 0x0ad6,
+ 0x58ef, 0x11b4,
+ 0x58f0, 0x0a60,
+ 0x58f1, 0x04b1,
+ 0x58f2, 0x0d1a,
+ 0x58f7, 0x0bf7,
+ 0x58f9, 0x11b6,
+ 0x58fa, 0x11b5,
+ 0x58fb, 0x11b7,
+ 0x5902, 0x11ba,
+ 0x5909, 0x0e21,
+ 0x590a, 0x11bb,
+ 0x590b, 0x20e9,
+ 0x590f, 0x0546,
+ 0x5910, 0x11bc,
+ 0x5915, 0x0f26,
+ 0x5916, 0x058e,
+ 0x5918, 0x10de,
+ 0x5919, 0x0952,
+ 0x591a, 0x0b1f,
+ 0x591b, 0x11bd,
+ 0x591c, 0x0ef7,
+ 0x5922, 0x0ec0,
+ 0x5925, 0x11bf,
+ 0x5927, 0x0b47,
+ 0x5929, 0x0c31,
+ 0x592a, 0x0b20,
+ 0x592b, 0x0dc9,
+ 0x592c, 0x11c0,
+ 0x592e, 0x051d,
+ 0x5931, 0x08e6,
+ 0x5932, 0x11c2,
+ 0x5937, 0x0494,
+ 0x5938, 0x11c3,
+ 0x593e, 0x11c4,
+ 0x5944, 0x0504,
+ 0x5947, 0x062d,
+ 0x5948, 0x0cb8,
+ 0x5949, 0x0e44,
+ 0x594e, 0x11c8,
+ 0x594f, 0x0ad7,
+ 0x5950, 0x11c7,
+ 0x5951, 0x0716,
+ 0x5953, 0x20ea,
+ 0x5954, 0x0e89,
+ 0x5955, 0x11c6,
+ 0x5957, 0x0c5f,
+ 0x5958, 0x11ca,
+ 0x595a, 0x11c9,
+ 0x595b, 0x20eb,
+ 0x595d, 0x20ec,
+ 0x5960, 0x11cc,
+ 0x5962, 0x11cb,
+ 0x5963, 0x20ed,
+ 0x5965, 0x051e,
+ 0x5967, 0x11cd,
+ 0x5968, 0x0991,
+ 0x5969, 0x11cf,
+ 0x596a, 0x0b63,
+ 0x596c, 0x11ce,
+ 0x596e, 0x0e03,
+ 0x5973, 0x0981,
+ 0x5974, 0x0c55,
+ 0x5978, 0x11d0,
+ 0x597d, 0x07b7,
+ 0x5981, 0x11d1,
+ 0x5982, 0x0cd7,
+ 0x5983, 0x0d72,
+ 0x5984, 0x0edd,
+ 0x598a, 0x0cdb,
+ 0x598d, 0x11da,
+ 0x5993, 0x0652,
+ 0x5996, 0x0f2f,
+ 0x5999, 0x0ebb,
+ 0x599b, 0x1239,
+ 0x599d, 0x11d2,
+ 0x59a3, 0x11d5,
+ 0x59a4, 0x20ee,
+ 0x59a5, 0x0b25,
+ 0x59a8, 0x0e66,
+ 0x59ac, 0x0c44,
+ 0x59b2, 0x11d6,
+ 0x59b9, 0x0e93,
+ 0x59ba, 0x20ef,
+ 0x59bb, 0x083a,
+ 0x59be, 0x0992,
+ 0x59c6, 0x11d7,
+ 0x59c9, 0x089e,
+ 0x59cb, 0x089d,
+ 0x59d0, 0x047d,
+ 0x59d1, 0x077c,
+ 0x59d3, 0x0a4f,
+ 0x59d4, 0x0495,
+ 0x59d9, 0x11db,
+ 0x59dc, 0x11d9,
+ 0x59e5, 0x04da,
+ 0x59e6, 0x05eb,
+ 0x59e8, 0x11d8,
+ 0x59ea, 0x0ed1,
+ 0x59eb, 0x0da3,
+ 0x59f6, 0x046c,
+ 0x59fb, 0x04bd,
+ 0x59ff, 0x089f,
+ 0x5a01, 0x0496,
+ 0x5a03, 0x0467,
+ 0x5a09, 0x11e1,
+ 0x5a11, 0x11df,
+ 0x5a18, 0x0ec8,
+ 0x5a1a, 0x11e2,
+ 0x5a1c, 0x11e0,
+ 0x5a1f, 0x11de,
+ 0x5a20, 0x09f7,
+ 0x5a25, 0x11dd,
+ 0x5a29, 0x0e2a,
+ 0x5a2f, 0x0798,
+ 0x5a35, 0x11e6,
+ 0x5a3c, 0x0993,
+ 0x5a40, 0x11e3,
+ 0x5a41, 0x0fd2,
+ 0x5a46, 0x0d02,
+ 0x5a49, 0x11e5,
+ 0x5a5a, 0x0817,
+ 0x5a62, 0x11e8,
+ 0x5a66, 0x0dca,
+ 0x5a6a, 0x11e9,
+ 0x5a6c, 0x11e4,
+ 0x5a7f, 0x0ec7,
+ 0x5a92, 0x0d14,
+ 0x5a9a, 0x11ea,
+ 0x5a9b, 0x0da4,
+ 0x5abc, 0x11eb,
+ 0x5abd, 0x11ef,
+ 0x5abe, 0x11ec,
+ 0x5ac1, 0x0547,
+ 0x5ac2, 0x11ee,
+ 0x5ac9, 0x08e7,
+ 0x5acb, 0x11ed,
+ 0x5acc, 0x074f,
+ 0x5ad0, 0x11fb,
+ 0x5ad6, 0x11f4,
+ 0x5ad7, 0x11f1,
+ 0x5ae1, 0x0ba2,
+ 0x5ae3, 0x11f0,
+ 0x5ae6, 0x11f2,
+ 0x5ae9, 0x11f3,
+ 0x5afa, 0x11f5,
+ 0x5b09, 0x062e,
+ 0x5b0b, 0x11f8,
+ 0x5b0c, 0x11f7,
+ 0x5b16, 0x11f9,
+ 0x5b22, 0x09d6,
+ 0x5b2a, 0x11fc,
+ 0x5b2c, 0x0bf8,
+ 0x5b30, 0x04e7,
+ 0x5b32, 0x11fa,
+ 0x5b36, 0x11fd,
+ 0x5b3e, 0x11fe,
+ 0x5b40, 0x1201,
+ 0x5b43, 0x11ff,
+ 0x5b45, 0x1200,
+ 0x5b50, 0x08a0,
+ 0x5b51, 0x1202,
+ 0x5b54, 0x07b8,
+ 0x5b55, 0x1203,
+ 0x5b56, 0x20f0,
+ 0x5b57, 0x08c8,
+ 0x5b58, 0x0b18,
+ 0x5b5a, 0x1204,
+ 0x5b5c, 0x08a8,
+ 0x5b5d, 0x07b9,
+ 0x5b5f, 0x0ede,
+ 0x5b63, 0x0642,
+ 0x5b64, 0x077d,
+ 0x5b65, 0x1206,
+ 0x5b66, 0x05b6,
+ 0x5b69, 0x1207,
+ 0x5b6b, 0x0b19,
+ 0x5b70, 0x1208,
+ 0x5b71, 0x1230,
+ 0x5b73, 0x1209,
+ 0x5b75, 0x120a,
+ 0x5b78, 0x120b,
+ 0x5b7a, 0x120d,
+ 0x5b80, 0x120e,
+ 0x5b83, 0x120f,
+ 0x5b85, 0x0b50,
+ 0x5b87, 0x04c9,
+ 0x5b88, 0x0915,
+ 0x5b89, 0x0486,
+ 0x5b8b, 0x0ad9,
+ 0x5b8c, 0x05ec,
+ 0x5b8d, 0x08e1,
+ 0x5b8f, 0x07ba,
+ 0x5b95, 0x0c60,
+ 0x5b97, 0x092b,
+ 0x5b98, 0x05ed,
+ 0x5b99, 0x0ba6,
+ 0x5b9a, 0x0c06,
+ 0x5b9b, 0x047c,
+ 0x5b9c, 0x0653,
+ 0x5b9d, 0x0e45,
+ 0x5b9f, 0x08ee,
+ 0x5ba2, 0x066c,
+ 0x5ba3, 0x0a8f,
+ 0x5ba4, 0x08e8,
+ 0x5ba5, 0x0f12,
+ 0x5ba6, 0x1210,
+ 0x5bae, 0x0676,
+ 0x5bb0, 0x083b,
+ 0x5bb3, 0x0590,
+ 0x5bb4, 0x0505,
+ 0x5bb5, 0x0994,
+ 0x5bb6, 0x0548,
+ 0x5bb8, 0x1211,
+ 0x5bb9, 0x0f30,
+ 0x5bbf, 0x0953,
+ 0x5bc0, 0x20f1,
+ 0x5bc2, 0x0910,
+ 0x5bc3, 0x1212,
+ 0x5bc4, 0x062f,
+ 0x5bc5, 0x0caa,
+ 0x5bc6, 0x0eb5,
+ 0x5bc7, 0x1213,
+ 0x5bc9, 0x1214,
+ 0x5bcc, 0x0dcb,
+ 0x5bd0, 0x1216,
+ 0x5bd2, 0x05e4,
+ 0x5bd3, 0x06ef,
+ 0x5bd4, 0x1215,
+ 0x5bd8, 0x20f3,
+ 0x5bdb, 0x05ee,
+ 0x5bdd, 0x09f8,
+ 0x5bde, 0x121a,
+ 0x5bdf, 0x086f,
+ 0x5be1, 0x0549,
+ 0x5be2, 0x1219,
+ 0x5be4, 0x1217,
+ 0x5be5, 0x121b,
+ 0x5be6, 0x1218,
+ 0x5be7, 0x0ce1,
+ 0x5be8, 0x148e,
+ 0x5be9, 0x09f9,
+ 0x5beb, 0x121c,
+ 0x5bec, 0x20f4,
+ 0x5bee, 0x0f88,
+ 0x5bf0, 0x121d,
+ 0x5bf3, 0x121f,
+ 0x5bf5, 0x0bbc,
+ 0x5bf6, 0x121e,
+ 0x5bf8, 0x0a47,
+ 0x5bfa, 0x08c9,
+ 0x5bfe, 0x0b30,
+ 0x5bff, 0x0923,
+ 0x5c01, 0x0de7,
+ 0x5c02, 0x0a90,
+ 0x5c04, 0x08f9,
+ 0x5c05, 0x1220,
+ 0x5c06, 0x0995,
+ 0x5c07, 0x1221,
+ 0x5c09, 0x0497,
+ 0x5c0a, 0x0b1a,
+ 0x5c0b, 0x0a18,
+ 0x5c0d, 0x1223,
+ 0x5c0e, 0x0c8b,
+ 0x5c0f, 0x0996,
+ 0x5c11, 0x0997,
+ 0x5c13, 0x1224,
+ 0x5c16, 0x0a91,
+ 0x5c1a, 0x0998,
+ 0x5c1e, 0x20f5,
+ 0x5c20, 0x1225,
+ 0x5c22, 0x1226,
+ 0x5c24, 0x0eec,
+ 0x5c28, 0x1227,
+ 0x5c2d, 0x06be,
+ 0x5c31, 0x092c,
+ 0x5c38, 0x1228,
+ 0x5c3a, 0x0908,
+ 0x5c3b, 0x09f2,
+ 0x5c3c, 0x0ccc,
+ 0x5c3d, 0x0a1a,
+ 0x5c3e, 0x0d8c,
+ 0x5c3f, 0x0cd8,
+ 0x5c40, 0x06c1,
+ 0x5c41, 0x122a,
+ 0x5c45, 0x0689,
+ 0x5c46, 0x122b,
+ 0x5c48, 0x06f6,
+ 0x5c4a, 0x0ca7,
+ 0x5c4b, 0x0530,
+ 0x5c4d, 0x08a1,
+ 0x5c4e, 0x122c,
+ 0x5c4f, 0x122f,
+ 0x5c50, 0x122e,
+ 0x5c51, 0x06f5,
+ 0x5c53, 0x122d,
+ 0x5c55, 0x0c32,
+ 0x5c5b, 0x1e92,
+ 0x5c5e, 0x0b10,
+ 0x5c60, 0x0c45,
+ 0x5c61, 0x08f4,
+ 0x5c62, 0x1e0d,
+ 0x5c64, 0x0ada,
+ 0x5c65, 0x0f64,
+ 0x5c6c, 0x1231,
+ 0x5c6e, 0x1232,
+ 0x5c6f, 0x0cae,
+ 0x5c71, 0x0881,
+ 0x5c76, 0x1234,
+ 0x5c79, 0x1235,
+ 0x5c8c, 0x1236,
+ 0x5c90, 0x0630,
+ 0x5c91, 0x1237,
+ 0x5c94, 0x1238,
+ 0x5ca1, 0x052c,
+ 0x5ca6, 0x20f6,
+ 0x5ca8, 0x0abd,
+ 0x5ca9, 0x0620,
+ 0x5cab, 0x123a,
+ 0x5cac, 0x0eb4,
+ 0x5cb1, 0x0b32,
+ 0x5cb3, 0x05b7,
+ 0x5cb6, 0x123c,
+ 0x5cb7, 0x123e,
+ 0x5cb8, 0x061b,
+ 0x5cba, 0x20f7,
+ 0x5cbb, 0x123b,
+ 0x5cbc, 0x123d,
+ 0x5cbe, 0x1240,
+ 0x5cc5, 0x123f,
+ 0x5cc7, 0x1241,
+ 0x5cd9, 0x1242,
+ 0x5ce0, 0x0c95,
+ 0x5ce1, 0x06a6,
+ 0x5ce8, 0x0565,
+ 0x5ce9, 0x1243,
+ 0x5cea, 0x1248,
+ 0x5ced, 0x1246,
+ 0x5cef, 0x0e47,
+ 0x5cf0, 0x0e46,
+ 0x5cf5, 0x20f8,
+ 0x5cf6, 0x0c61,
+ 0x5cfa, 0x1245,
+ 0x5cfb, 0x095e,
+ 0x5cfd, 0x1244,
+ 0x5d07, 0x0a38,
+ 0x5d0b, 0x1249,
+ 0x5d0e, 0x085a,
+ 0x5d11, 0x124f,
+ 0x5d14, 0x1250,
+ 0x5d15, 0x124a,
+ 0x5d16, 0x0591,
+ 0x5d17, 0x124b,
+ 0x5d18, 0x1254,
+ 0x5d19, 0x1253,
+ 0x5d1a, 0x1252,
+ 0x5d1b, 0x124e,
+ 0x5d1f, 0x124d,
+ 0x5d22, 0x1251,
+ 0x5d27, 0x20f9,
+ 0x5d29, 0x0e48,
+ 0x5d42, 0x20fc,
+ 0x5d4b, 0x1258,
+ 0x5d4c, 0x1255,
+ 0x5d4e, 0x1257,
+ 0x5d50, 0x0f5c,
+ 0x5d52, 0x1256,
+ 0x5d53, 0x20fa,
+ 0x5d5c, 0x124c,
+ 0x5d69, 0x0a39,
+ 0x5d6c, 0x1259,
+ 0x5d6d, 0x20fd,
+ 0x5d6f, 0x0827,
+ 0x5d73, 0x125a,
+ 0x5d76, 0x125b,
+ 0x5d82, 0x125e,
+ 0x5d84, 0x125d,
+ 0x5d87, 0x125c,
+ 0x5d8b, 0x0c62,
+ 0x5d8c, 0x1247,
+ 0x5d90, 0x1264,
+ 0x5d9d, 0x1260,
+ 0x5da2, 0x125f,
+ 0x5dac, 0x1261,
+ 0x5dae, 0x1262,
+ 0x5db7, 0x1265,
+ 0x5db8, 0x20fe,
+ 0x5dba, 0x0fae,
+ 0x5dbc, 0x1266,
+ 0x5dbd, 0x1263,
+ 0x5dc9, 0x1267,
+ 0x5dcc, 0x061c,
+ 0x5dcd, 0x1268,
+ 0x5dd0, 0x2100,
+ 0x5dd2, 0x126a,
+ 0x5dd3, 0x1269,
+ 0x5dd6, 0x126b,
+ 0x5ddb, 0x126c,
+ 0x5ddd, 0x0a92,
+ 0x5dde, 0x092d,
+ 0x5de1, 0x096e,
+ 0x5de3, 0x0ae5,
+ 0x5de5, 0x07bb,
+ 0x5de6, 0x0828,
+ 0x5de7, 0x07bc,
+ 0x5de8, 0x068a,
+ 0x5deb, 0x126d,
+ 0x5dee, 0x0829,
+ 0x5df1, 0x077e,
+ 0x5df2, 0x126e,
+ 0x5df3, 0x0eb2,
+ 0x5df4, 0x0cf9,
+ 0x5df5, 0x126f,
+ 0x5df7, 0x07bd,
+ 0x5dfb, 0x05e8,
+ 0x5dfd, 0x0b65,
+ 0x5dfe, 0x06ca,
+ 0x5e02, 0x08a2,
+ 0x5e03, 0x0dcd,
+ 0x5e06, 0x0d55,
+ 0x5e0b, 0x1270,
+ 0x5e0c, 0x0631,
+ 0x5e11, 0x1273,
+ 0x5e16, 0x0bbd,
+ 0x5e19, 0x1272,
+ 0x5e1a, 0x1271,
+ 0x5e1b, 0x1274,
+ 0x5e1d, 0x0c07,
+ 0x5e25, 0x0a29,
+ 0x5e2b, 0x08a3,
+ 0x5e2d, 0x0a6e,
+ 0x5e2f, 0x0b33,
+ 0x5e30, 0x063c,
+ 0x5e33, 0x0bbe,
+ 0x5e36, 0x1275,
+ 0x5e38, 0x09d7,
+ 0x5e3d, 0x0e67,
+ 0x5e40, 0x1279,
+ 0x5e43, 0x1278,
+ 0x5e44, 0x1277,
+ 0x5e45, 0x0def,
+ 0x5e47, 0x1280,
+ 0x5e4c, 0x0e88,
+ 0x5e4e, 0x127a,
+ 0x5e54, 0x127c,
+ 0x5e55, 0x0e99,
+ 0x5e57, 0x127b,
+ 0x5e5f, 0x127d,
+ 0x5e61, 0x0d3c,
+ 0x5e62, 0x127e,
+ 0x5e63, 0x0e0e,
+ 0x5e64, 0x127f,
+ 0x5e72, 0x05ef,
+ 0x5e73, 0x0e0f,
+ 0x5e74, 0x0ce5,
+ 0x5e75, 0x1281,
+ 0x5e78, 0x07be,
+ 0x5e79, 0x05f0,
+ 0x5e7a, 0x1283,
+ 0x5e7b, 0x076c,
+ 0x5e7c, 0x0f2e,
+ 0x5e7d, 0x0f13,
+ 0x5e7e, 0x0632,
+ 0x5e7f, 0x1285,
+ 0x5e81, 0x0bbf,
+ 0x5e83, 0x07bf,
+ 0x5e84, 0x0999,
+ 0x5e87, 0x0d73,
+ 0x5e8a, 0x099a,
+ 0x5e8f, 0x0982,
+ 0x5e95, 0x0c08,
+ 0x5e96, 0x0e49,
+ 0x5e97, 0x0c33,
+ 0x5e9a, 0x07c0,
+ 0x5e9c, 0x0dce,
+ 0x5ea0, 0x1286,
+ 0x5ea6, 0x0c53,
+ 0x5ea7, 0x0832,
+ 0x5eab, 0x077f,
+ 0x5ead, 0x0c09,
+ 0x5eb5, 0x0487,
+ 0x5eb6, 0x0978,
+ 0x5eb7, 0x07c1,
+ 0x5eb8, 0x0f31,
+ 0x5ec1, 0x1287,
+ 0x5ec3, 0x0d07,
+ 0x5ec8, 0x1289,
+ 0x5ec9, 0x0fbf,
+ 0x5eca, 0x0fd3,
+ 0x5ecf, 0x128b,
+ 0x5ed0, 0x128a,
+ 0x5ed3, 0x05a5,
+ 0x5ed6, 0x128c,
+ 0x5eda, 0x128f,
+ 0x5edd, 0x128e,
+ 0x5edf, 0x0db2,
+ 0x5ee0, 0x099b,
+ 0x5ee1, 0x1292,
+ 0x5ee2, 0x1291,
+ 0x5ee3, 0x128d,
+ 0x5ee8, 0x1293,
+ 0x5eec, 0x1295,
+ 0x5ef0, 0x1298,
+ 0x5ef1, 0x1296,
+ 0x5ef3, 0x1297,
+ 0x5ef4, 0x1299,
+ 0x5ef6, 0x0506,
+ 0x5ef7, 0x0c0a,
+ 0x5ef8, 0x129a,
+ 0x5efa, 0x0750,
+ 0x5efb, 0x0576,
+ 0x5efc, 0x0cec,
+ 0x5efe, 0x129b,
+ 0x5eff, 0x0cd3,
+ 0x5f01, 0x0e2b,
+ 0x5f03, 0x129c,
+ 0x5f04, 0x0fd4,
+ 0x5f09, 0x129d,
+ 0x5f0a, 0x0e10,
+ 0x5f0b, 0x12a0,
+ 0x5f0c, 0x0ffa,
+ 0x5f0d, 0x100a,
+ 0x5f0f, 0x08dc,
+ 0x5f10, 0x0ccd,
+ 0x5f11, 0x12a1,
+ 0x5f13, 0x0677,
+ 0x5f14, 0x0bc0,
+ 0x5f15, 0x04be,
+ 0x5f16, 0x12a2,
+ 0x5f17, 0x0df6,
+ 0x5f18, 0x07c2,
+ 0x5f1b, 0x0b8e,
+ 0x5f1f, 0x0c0b,
+ 0x5f21, 0x2101,
+ 0x5f25, 0x0efb,
+ 0x5f26, 0x076d,
+ 0x5f27, 0x0780,
+ 0x5f29, 0x12a3,
+ 0x5f2d, 0x12a4,
+ 0x5f2f, 0x12aa,
+ 0x5f31, 0x0911,
+ 0x5f34, 0x2102,
+ 0x5f35, 0x0bc1,
+ 0x5f37, 0x06a7,
+ 0x5f38, 0x12a5,
+ 0x5f3c, 0x0d9d,
+ 0x5f3e, 0x0b84,
+ 0x5f41, 0x12a6,
+ 0x5f45, 0x20b2,
+ 0x5f48, 0x12a7,
+ 0x5f4a, 0x06a8,
+ 0x5f4c, 0x12a8,
+ 0x5f4e, 0x12a9,
+ 0x5f51, 0x12ab,
+ 0x5f53, 0x0c70,
+ 0x5f56, 0x12ac,
+ 0x5f59, 0x12ae,
+ 0x5f5c, 0x129f,
+ 0x5f5d, 0x129e,
+ 0x5f61, 0x12af,
+ 0x5f62, 0x0717,
+ 0x5f66, 0x0d99,
+ 0x5f67, 0x2103,
+ 0x5f69, 0x083c,
+ 0x5f6a, 0x0da9,
+ 0x5f6b, 0x0bc2,
+ 0x5f6c, 0x0dbd,
+ 0x5f6d, 0x12b0,
+ 0x5f70, 0x099c,
+ 0x5f71, 0x04e8,
+ 0x5f73, 0x12b1,
+ 0x5f77, 0x12b2,
+ 0x5f79, 0x0efe,
+ 0x5f7c, 0x0d74,
+ 0x5f7f, 0x12b5,
+ 0x5f80, 0x051f,
+ 0x5f81, 0x0a50,
+ 0x5f82, 0x12b4,
+ 0x5f83, 0x12b3,
+ 0x5f84, 0x0718,
+ 0x5f85, 0x0b34,
+ 0x5f87, 0x12b9,
+ 0x5f88, 0x12b7,
+ 0x5f8a, 0x12b6,
+ 0x5f8b, 0x0f6f,
+ 0x5f8c, 0x0799,
+ 0x5f90, 0x0983,
+ 0x5f91, 0x12b8,
+ 0x5f92, 0x0c46,
+ 0x5f93, 0x0948,
+ 0x5f97, 0x0c98,
+ 0x5f98, 0x12bc,
+ 0x5f99, 0x12bb,
+ 0x5f9e, 0x12ba,
+ 0x5fa0, 0x12bd,
+ 0x5fa1, 0x079a,
+ 0x5fa8, 0x12be,
+ 0x5fa9, 0x0dee,
+ 0x5faa, 0x0965,
+ 0x5fad, 0x12bf,
+ 0x5fae, 0x0d8d,
+ 0x5fb3, 0x0c99,
+ 0x5fb4, 0x0bc3,
+ 0x5fb7, 0x2104,
+ 0x5fb9, 0x0c2a,
+ 0x5fbc, 0x12c0,
+ 0x5fbd, 0x0645,
+ 0x5fc3, 0x09fa,
+ 0x5fc5, 0x0d9e,
+ 0x5fcc, 0x0633,
+ 0x5fcd, 0x0cdc,
+ 0x5fd6, 0x12c1,
+ 0x5fd7, 0x08a4,
+ 0x5fd8, 0x0e68,
+ 0x5fdc, 0x0520,
+ 0x5fdd, 0x12c6,
+ 0x5fde, 0x2105,
+ 0x5fe0, 0x0ba7,
+ 0x5fe4, 0x12c3,
+ 0x5feb, 0x0577,
+ 0x5ff0, 0x12f6,
+ 0x5ff1, 0x12c5,
+ 0x5ff5, 0x0ce6,
+ 0x5ff8, 0x12c4,
+ 0x5ffb, 0x12c2,
+ 0x5ffd, 0x080c,
+ 0x5fff, 0x12c8,
+ 0x600e, 0x12ce,
+ 0x600f, 0x12d4,
+ 0x6010, 0x12cc,
+ 0x6012, 0x0c56,
+ 0x6015, 0x12d1,
+ 0x6016, 0x0dcf,
+ 0x6019, 0x12cb,
+ 0x601b, 0x12d0,
+ 0x601c, 0x0faf,
+ 0x601d, 0x08a5,
+ 0x6020, 0x0b35,
+ 0x6021, 0x12c9,
+ 0x6025, 0x0678,
+ 0x6026, 0x12d3,
+ 0x6027, 0x0a51,
+ 0x6028, 0x0507,
+ 0x6029, 0x12cd,
+ 0x602a, 0x0578,
+ 0x602b, 0x12d2,
+ 0x602f, 0x06a9,
+ 0x6031, 0x12cf,
+ 0x603a, 0x12d5,
+ 0x6041, 0x12d7,
+ 0x6042, 0x12e1,
+ 0x6043, 0x12df,
+ 0x6046, 0x12dc,
+ 0x604a, 0x12db,
+ 0x604b, 0x0fc0,
+ 0x604d, 0x12dd,
+ 0x6050, 0x06aa,
+ 0x6052, 0x07c3,
+ 0x6055, 0x0984,
+ 0x6059, 0x12e4,
+ 0x605a, 0x12d6,
+ 0x605d, 0x2106,
+ 0x605f, 0x12da,
+ 0x6060, 0x12ca,
+ 0x6062, 0x057a,
+ 0x6063, 0x12de,
+ 0x6064, 0x12e0,
+ 0x6065, 0x0b8f,
+ 0x6068, 0x0818,
+ 0x6069, 0x0538,
+ 0x606a, 0x12d8,
+ 0x606b, 0x12e3,
+ 0x606c, 0x12e2,
+ 0x606d, 0x06ab,
+ 0x606f, 0x0b09,
+ 0x6070, 0x05c4,
+ 0x6075, 0x0719,
+ 0x6077, 0x12d9,
+ 0x6081, 0x12e5,
+ 0x6083, 0x12e8,
+ 0x6084, 0x12ea,
+ 0x6085, 0x2107,
+ 0x6089, 0x08e9,
+ 0x608a, 0x2108,
+ 0x608b, 0x12f0,
+ 0x608c, 0x0c0c,
+ 0x608d, 0x12e6,
+ 0x6092, 0x12ee,
+ 0x6094, 0x0579,
+ 0x6096, 0x12ec,
+ 0x609a, 0x12e9,
+ 0x609b, 0x12eb,
+ 0x609f, 0x079b,
+ 0x60a0, 0x0f14,
+ 0x60a3, 0x05f1,
+ 0x60a6, 0x04fb,
+ 0x60a7, 0x12ef,
+ 0x60a9, 0x0cf0,
+ 0x60aa, 0x0471,
+ 0x60b2, 0x0d75,
+ 0x60b3, 0x12c7,
+ 0x60b4, 0x12f5,
+ 0x60b5, 0x12f9,
+ 0x60b6, 0x0ef1,
+ 0x60b8, 0x12f2,
+ 0x60bc, 0x0c63,
+ 0x60bd, 0x12f7,
+ 0x60c5, 0x09d8,
+ 0x60c6, 0x12f8,
+ 0x60c7, 0x0caf,
+ 0x60d1, 0x0fed,
+ 0x60d3, 0x12f4,
+ 0x60d5, 0x210a,
+ 0x60d8, 0x12fa,
+ 0x60da, 0x080d,
+ 0x60dc, 0x0a6f,
+ 0x60de, 0x2109,
+ 0x60df, 0x0498,
+ 0x60e0, 0x12f3,
+ 0x60e1, 0x12f1,
+ 0x60e3, 0x0adc,
+ 0x60e7, 0x12e7,
+ 0x60e8, 0x0882,
+ 0x60f0, 0x0b26,
+ 0x60f1, 0x1306,
+ 0x60f2, 0x210c,
+ 0x60f3, 0x0add,
+ 0x60f4, 0x1301,
+ 0x60f6, 0x12fe,
+ 0x60f9, 0x0912,
+ 0x60fa, 0x1302,
+ 0x60fb, 0x1305,
+ 0x6100, 0x1300,
+ 0x6101, 0x092f,
+ 0x6103, 0x1303,
+ 0x6106, 0x12fd,
+ 0x6108, 0x0f08,
+ 0x6109, 0x0f07,
+ 0x610d, 0x1307,
+ 0x610f, 0x0499,
+ 0x6111, 0x210d,
+ 0x6115, 0x12fc,
+ 0x611a, 0x06ea,
+ 0x611b, 0x046a,
+ 0x611f, 0x05f2,
+ 0x6120, 0x210b,
+ 0x6121, 0x1304,
+ 0x6127, 0x130c,
+ 0x6128, 0x130b,
+ 0x612c, 0x1310,
+ 0x6130, 0x210f,
+ 0x6134, 0x1311,
+ 0x6137, 0x210e,
+ 0x613c, 0x130f,
+ 0x613d, 0x1312,
+ 0x613e, 0x130a,
+ 0x613f, 0x130e,
+ 0x6142, 0x1313,
+ 0x6144, 0x1314,
+ 0x6147, 0x1309,
+ 0x6148, 0x08ca,
+ 0x614a, 0x130d,
+ 0x614b, 0x0b36,
+ 0x614c, 0x07c4,
+ 0x614d, 0x12fb,
+ 0x614e, 0x09fb,
+ 0x6153, 0x1321,
+ 0x6155, 0x0e39,
+ 0x6158, 0x1317,
+ 0x615d, 0x1320,
+ 0x615f, 0x131f,
+ 0x6162, 0x0eab,
+ 0x6163, 0x05f3,
+ 0x6165, 0x131d,
+ 0x6167, 0x071b,
+ 0x6168, 0x0592,
+ 0x616b, 0x131a,
+ 0x616e, 0x0f80,
+ 0x616f, 0x131c,
+ 0x6170, 0x049a,
+ 0x6171, 0x131e,
+ 0x6173, 0x1315,
+ 0x6174, 0x131b,
+ 0x6175, 0x1322,
+ 0x6176, 0x071a,
+ 0x6177, 0x1316,
+ 0x617e, 0x0f47,
+ 0x6182, 0x0f15,
+ 0x6187, 0x1325,
+ 0x618a, 0x1329,
+ 0x618e, 0x0b00,
+ 0x6190, 0x0fc1,
+ 0x6191, 0x132a,
+ 0x6194, 0x1327,
+ 0x6196, 0x1324,
+ 0x6198, 0x2110,
+ 0x6199, 0x1323,
+ 0x619a, 0x1328,
+ 0x61a4, 0x0e00,
+ 0x61a7, 0x0c8c,
+ 0x61a9, 0x071c,
+ 0x61ab, 0x132b,
+ 0x61ac, 0x1326,
+ 0x61ae, 0x132c,
+ 0x61b2, 0x0751,
+ 0x61b6, 0x0531,
+ 0x61ba, 0x1334,
+ 0x61be, 0x05f4,
+ 0x61c3, 0x1332,
+ 0x61c6, 0x1333,
+ 0x61c7, 0x0819,
+ 0x61c8, 0x1331,
+ 0x61c9, 0x132f,
+ 0x61ca, 0x132e,
+ 0x61cb, 0x1335,
+ 0x61cc, 0x132d,
+ 0x61cd, 0x1337,
+ 0x61d0, 0x057b,
+ 0x61e3, 0x1339,
+ 0x61e6, 0x1338,
+ 0x61f2, 0x0bc4,
+ 0x61f4, 0x133c,
+ 0x61f6, 0x133a,
+ 0x61f7, 0x1330,
+ 0x61f8, 0x0752,
+ 0x61fa, 0x133b,
+ 0x61fc, 0x133f,
+ 0x61fd, 0x133e,
+ 0x61fe, 0x1340,
+ 0x61ff, 0x133d,
+ 0x6200, 0x1341,
+ 0x6208, 0x1342,
+ 0x620a, 0x0e3a,
+ 0x620c, 0x1345,
+ 0x620d, 0x1344,
+ 0x620e, 0x0949,
+ 0x6210, 0x0a52,
+ 0x6211, 0x0566,
+ 0x6212, 0x057c,
+ 0x6213, 0x2111,
+ 0x6214, 0x1346,
+ 0x6216, 0x0483,
+ 0x621a, 0x0a70,
+ 0x621b, 0x1347,
+ 0x621d, 0x1a64,
+ 0x621e, 0x1348,
+ 0x621f, 0x0737,
+ 0x6221, 0x1349,
+ 0x6226, 0x0a93,
+ 0x622a, 0x134a,
+ 0x622e, 0x134b,
+ 0x622f, 0x0654,
+ 0x6230, 0x134c,
+ 0x6232, 0x134d,
+ 0x6234, 0x0b37,
+ 0x6238, 0x0781,
+ 0x623b, 0x0eed,
+ 0x623f, 0x0e6a,
+ 0x6240, 0x0974,
+ 0x6241, 0x134f,
+ 0x6247, 0x0a94,
+ 0x6248, 0x1b1a,
+ 0x6249, 0x0d76,
+ 0x624b, 0x0916,
+ 0x624d, 0x083d,
+ 0x624e, 0x1350,
+ 0x6253, 0x0b27,
+ 0x6255, 0x0df7,
+ 0x6258, 0x0b51,
+ 0x625b, 0x1353,
+ 0x625e, 0x1351,
+ 0x6260, 0x1354,
+ 0x6263, 0x1352,
+ 0x6268, 0x1355,
+ 0x626e, 0x0e01,
+ 0x6271, 0x047b,
+ 0x6276, 0x0dd0,
+ 0x6279, 0x0d77,
+ 0x627c, 0x1356,
+ 0x627e, 0x1359,
+ 0x627f, 0x099d,
+ 0x6280, 0x0655,
+ 0x6282, 0x1357,
+ 0x6283, 0x135e,
+ 0x6284, 0x099e,
+ 0x6289, 0x1358,
+ 0x628a, 0x0cfa,
+ 0x6291, 0x0f48,
+ 0x6292, 0x135a,
+ 0x6294, 0x135f,
+ 0x6295, 0x0c64,
+ 0x6296, 0x135c,
+ 0x6297, 0x07c5,
+ 0x6298, 0x0a82,
+ 0x629b, 0x136d,
+ 0x629c, 0x0d48,
+ 0x629e, 0x0b52,
+ 0x62a6, 0x2112,
+ 0x62ab, 0x0d78,
+ 0x62ac, 0x13b2,
+ 0x62b1, 0x0e4a,
+ 0x62b5, 0x0c0d,
+ 0x62b9, 0x0ea3,
+ 0x62bb, 0x1362,
+ 0x62bc, 0x0521,
+ 0x62bd, 0x0ba8,
+ 0x62c2, 0x136b,
+ 0x62c5, 0x0b72,
+ 0x62c6, 0x1365,
+ 0x62c7, 0x136c,
+ 0x62c8, 0x1367,
+ 0x62c9, 0x136e,
+ 0x62ca, 0x136a,
+ 0x62cc, 0x1369,
+ 0x62cd, 0x0d25,
+ 0x62cf, 0x1363,
+ 0x62d0, 0x057d,
+ 0x62d1, 0x1361,
+ 0x62d2, 0x068b,
+ 0x62d3, 0x0b53,
+ 0x62d4, 0x135d,
+ 0x62d7, 0x1360,
+ 0x62d8, 0x07c6,
+ 0x62d9, 0x0a7f,
+ 0x62db, 0x099f,
+ 0x62dc, 0x1368,
+ 0x62dd, 0x0d08,
+ 0x62e0, 0x068c,
+ 0x62e1, 0x05a6,
+ 0x62ec, 0x05c5,
+ 0x62ed, 0x09e7,
+ 0x62ee, 0x1370,
+ 0x62ef, 0x1375,
+ 0x62f1, 0x1371,
+ 0x62f3, 0x0753,
+ 0x62f5, 0x1376,
+ 0x62f6, 0x0870,
+ 0x62f7, 0x07fb,
+ 0x62fe, 0x0930,
+ 0x62ff, 0x1364,
+ 0x6301, 0x08cb,
+ 0x6302, 0x1373,
+ 0x6307, 0x08a6,
+ 0x6308, 0x1374,
+ 0x6309, 0x0488,
+ 0x630c, 0x136f,
+ 0x6311, 0x0bc5,
+ 0x6319, 0x068d,
+ 0x631f, 0x06ac,
+ 0x6327, 0x1372,
+ 0x6328, 0x046b,
+ 0x632b, 0x0833,
+ 0x632f, 0x09fc,
+ 0x633a, 0x0c0e,
+ 0x633d, 0x0d68,
+ 0x633e, 0x1378,
+ 0x633f, 0x0ae0,
+ 0x6349, 0x0b0a,
+ 0x634c, 0x0879,
+ 0x634d, 0x1379,
+ 0x634f, 0x137b,
+ 0x6350, 0x1377,
+ 0x6355, 0x0e31,
+ 0x6357, 0x0bd9,
+ 0x635c, 0x0ade,
+ 0x6367, 0x0e4b,
+ 0x6368, 0x08fa,
+ 0x6369, 0x1387,
+ 0x636b, 0x1386,
+ 0x636e, 0x0a3e,
+ 0x6372, 0x0754,
+ 0x6376, 0x1380,
+ 0x6377, 0x09a1,
+ 0x637a, 0x0cc0,
+ 0x637b, 0x0ce7,
+ 0x6380, 0x137e,
+ 0x6383, 0x0adf,
+ 0x6388, 0x0924,
+ 0x6389, 0x1383,
+ 0x638c, 0x09a0,
+ 0x638e, 0x137d,
+ 0x638f, 0x1382,
+ 0x6392, 0x0d09,
+ 0x6396, 0x137c,
+ 0x6398, 0x06f7,
+ 0x639b, 0x05bb,
+ 0x639f, 0x1384,
+ 0x63a0, 0x0f73,
+ 0x63a1, 0x083e,
+ 0x63a2, 0x0b73,
+ 0x63a3, 0x1381,
+ 0x63a5, 0x0a80,
+ 0x63a7, 0x07c7,
+ 0x63a8, 0x0a2a,
+ 0x63a9, 0x0508,
+ 0x63aa, 0x0abe,
+ 0x63ab, 0x137f,
+ 0x63ac, 0x065f,
+ 0x63b2, 0x071d,
+ 0x63b4, 0x0beb,
+ 0x63b5, 0x1385,
+ 0x63bb, 0x0ae1,
+ 0x63be, 0x1388,
+ 0x63c0, 0x138a,
+ 0x63c3, 0x0b17,
+ 0x63c4, 0x1390,
+ 0x63c6, 0x138b,
+ 0x63c9, 0x138d,
+ 0x63cf, 0x0db3,
+ 0x63d0, 0x0c0f,
+ 0x63d2, 0x138e,
+ 0x63d6, 0x0f16,
+ 0x63da, 0x0f32,
+ 0x63db, 0x05f5,
+ 0x63e1, 0x0472,
+ 0x63e3, 0x138c,
+ 0x63e9, 0x1389,
+ 0x63ee, 0x0634,
+ 0x63f4, 0x0509,
+ 0x63f5, 0x2113,
+ 0x63f6, 0x138f,
+ 0x63fa, 0x0f33,
+ 0x6406, 0x1393,
+ 0x640d, 0x0b1b,
+ 0x640f, 0x139a,
+ 0x6413, 0x1394,
+ 0x6414, 0x1e2c,
+ 0x6416, 0x1391,
+ 0x6417, 0x1398,
+ 0x641c, 0x137a,
+ 0x6426, 0x1395,
+ 0x6428, 0x1399,
+ 0x642c, 0x0d56,
+ 0x642d, 0x0c65,
+ 0x6434, 0x1392,
+ 0x6436, 0x1396,
+ 0x643a, 0x071e,
+ 0x643e, 0x0861,
+ 0x6442, 0x0a81,
+ 0x644e, 0x139e,
+ 0x6451, 0x1e43,
+ 0x6458, 0x0c20,
+ 0x6460, 0x2114,
+ 0x6467, 0x139b,
+ 0x6469, 0x0e8e,
+ 0x646f, 0x139c,
+ 0x6476, 0x139d,
+ 0x6478, 0x0eda,
+ 0x647a, 0x0a46,
+ 0x6483, 0x0738,
+ 0x6488, 0x13a4,
+ 0x6492, 0x0883,
+ 0x6493, 0x13a1,
+ 0x6495, 0x13a0,
+ 0x649a, 0x0ce8,
+ 0x649d, 0x2115,
+ 0x649e, 0x0c8d,
+ 0x64a4, 0x0c2b,
+ 0x64a5, 0x13a2,
+ 0x64a9, 0x13a3,
+ 0x64ab, 0x0de1,
+ 0x64ad, 0x0cfb,
+ 0x64ae, 0x0871,
+ 0x64b0, 0x0a95,
+ 0x64b2, 0x0e7e,
+ 0x64b9, 0x05a7,
+ 0x64bb, 0x13aa,
+ 0x64bc, 0x13a5,
+ 0x64c1, 0x0f34,
+ 0x64c2, 0x13ac,
+ 0x64c5, 0x13a8,
+ 0x64c7, 0x13a9,
+ 0x64cd, 0x0ae2,
+ 0x64ce, 0x2116,
+ 0x64d2, 0x13a7,
+ 0x64d4, 0x1366,
+ 0x64d8, 0x13ab,
+ 0x64da, 0x13a6,
+ 0x64e0, 0x13b0,
+ 0x64e2, 0x0c21,
+ 0x64e3, 0x13b3,
+ 0x64e6, 0x0872,
+ 0x64e7, 0x13ae,
+ 0x64ec, 0x0656,
+ 0x64ef, 0x13b4,
+ 0x64f1, 0x13ad,
+ 0x64f2, 0x13b8,
+ 0x64f4, 0x13b7,
+ 0x64f6, 0x13b6,
+ 0x64fa, 0x13b9,
+ 0x64fd, 0x13bb,
+ 0x64fe, 0x09d9,
+ 0x6500, 0x13ba,
+ 0x6505, 0x13be,
+ 0x6518, 0x13bc,
+ 0x651c, 0x13bd,
+ 0x651d, 0x1397,
+ 0x6522, 0x1e97,
+ 0x6523, 0x13c0,
+ 0x6524, 0x13bf,
+ 0x652a, 0x139f,
+ 0x652b, 0x13c1,
+ 0x652c, 0x13b5,
+ 0x652f, 0x08a7,
+ 0x6534, 0x13c2,
+ 0x6536, 0x13c5,
+ 0x6537, 0x13c4,
+ 0x6538, 0x13c6,
+ 0x6539, 0x057e,
+ 0x653b, 0x07c8,
+ 0x653e, 0x0e4c,
+ 0x653f, 0x0a53,
+ 0x6545, 0x0782,
+ 0x6548, 0x13c8,
+ 0x654d, 0x13cb,
+ 0x654e, 0x2117,
+ 0x654f, 0x0dc4,
+ 0x6551, 0x0679,
+ 0x6555, 0x13ca,
+ 0x6556, 0x13c9,
+ 0x6557, 0x0d0a,
+ 0x6558, 0x13cc,
+ 0x6559, 0x06ad,
+ 0x655d, 0x13ce,
+ 0x655e, 0x13cd,
+ 0x6562, 0x05f6,
+ 0x6563, 0x0884,
+ 0x6566, 0x0cb0,
+ 0x656c, 0x071f,
+ 0x6570, 0x0a3a,
+ 0x6572, 0x13cf,
+ 0x6574, 0x0a54,
+ 0x6575, 0x0c22,
+ 0x6577, 0x0dd1,
+ 0x6578, 0x13d0,
+ 0x6582, 0x13d1,
+ 0x6587, 0x0e08,
+ 0x6588, 0x120c,
+ 0x6589, 0x0a6a,
+ 0x658c, 0x0dbe,
+ 0x658e, 0x0848,
+ 0x6590, 0x0d79,
+ 0x6591, 0x0d57,
+ 0x6597, 0x0c47,
+ 0x6599, 0x0f89,
+ 0x659b, 0x13d4,
+ 0x659c, 0x08fc,
+ 0x659f, 0x13d5,
+ 0x65a1, 0x047a,
+ 0x65a4, 0x06cc,
+ 0x65a5, 0x0a71,
+ 0x65a7, 0x0dd2,
+ 0x65ab, 0x13d6,
+ 0x65ac, 0x0890,
+ 0x65ad, 0x0b85,
+ 0x65af, 0x08a9,
+ 0x65b0, 0x09fd,
+ 0x65b7, 0x13d7,
+ 0x65b9, 0x0e4d,
+ 0x65bc, 0x0519,
+ 0x65bd, 0x08aa,
+ 0x65c1, 0x13da,
+ 0x65c3, 0x13d8,
+ 0x65c4, 0x13db,
+ 0x65c5, 0x0f81,
+ 0x65c6, 0x13d9,
+ 0x65cb, 0x0a9f,
+ 0x65cc, 0x13dc,
+ 0x65cf, 0x0b12,
+ 0x65d2, 0x13dd,
+ 0x65d7, 0x0636,
+ 0x65d9, 0x13df,
+ 0x65db, 0x13de,
+ 0x65e0, 0x13e0,
+ 0x65e2, 0x0637,
+ 0x65e5, 0x0cd4,
+ 0x65e6, 0x0b74,
+ 0x65e7, 0x0686,
+ 0x65e8, 0x08ab,
+ 0x65e9, 0x0ae3,
+ 0x65ec, 0x0966,
+ 0x65ed, 0x0474,
+ 0x65f1, 0x13e2,
+ 0x65fa, 0x0522,
+ 0x65fb, 0x13e6,
+ 0x6600, 0x2118,
+ 0x6602, 0x07c9,
+ 0x6603, 0x13e5,
+ 0x6606, 0x081b,
+ 0x6607, 0x09a2,
+ 0x6609, 0x211a,
+ 0x660a, 0x13e4,
+ 0x660c, 0x09a3,
+ 0x660e, 0x0ecc,
+ 0x660f, 0x081a,
+ 0x6613, 0x049b,
+ 0x6614, 0x0a72,
+ 0x6615, 0x2119,
+ 0x661c, 0x13eb,
+ 0x661e, 0x211c,
+ 0x661f, 0x0a55,
+ 0x6620, 0x04e9,
+ 0x6624, 0x211d,
+ 0x6625, 0x095f,
+ 0x6627, 0x0e94,
+ 0x6628, 0x0862,
+ 0x662d, 0x09a4,
+ 0x662e, 0x211b,
+ 0x662f, 0x0a4b,
+ 0x6631, 0x20ae,
+ 0x6634, 0x13ea,
+ 0x6635, 0x13e8,
+ 0x663b, 0x1e00,
+ 0x663c, 0x0ba9,
+ 0x663f, 0x1409,
+ 0x6641, 0x13ef,
+ 0x6642, 0x08cc,
+ 0x6643, 0x07ca,
+ 0x6644, 0x13ed,
+ 0x6649, 0x13ee,
+ 0x664b, 0x09fe,
+ 0x664f, 0x13ec,
+ 0x6652, 0x087d,
+ 0x6657, 0x211f,
+ 0x6659, 0x2120,
+ 0x665d, 0x13f1,
+ 0x665e, 0x13f0,
+ 0x665f, 0x13f5,
+ 0x6662, 0x13f6,
+ 0x6664, 0x13f2,
+ 0x6665, 0x211e,
+ 0x6666, 0x0580,
+ 0x6667, 0x13f3,
+ 0x6669, 0x0d69,
+ 0x666e, 0x0dd3,
+ 0x666f, 0x0720,
+ 0x6670, 0x13f7,
+ 0x6673, 0x2122,
+ 0x6674, 0x0a56,
+ 0x6676, 0x09a5,
+ 0x667a, 0x0b90,
+ 0x6681, 0x06bf,
+ 0x6683, 0x13f8,
+ 0x6684, 0x13fc,
+ 0x6687, 0x054b,
+ 0x6688, 0x13f9,
+ 0x6689, 0x13fb,
+ 0x668e, 0x13fa,
+ 0x6691, 0x0975,
+ 0x6696, 0x0b86,
+ 0x6697, 0x0489,
+ 0x6698, 0x13fd,
+ 0x6699, 0x2123,
+ 0x669d, 0x13fe,
+ 0x66a0, 0x2124,
+ 0x66a2, 0x0bc6,
+ 0x66a6, 0x0fb9,
+ 0x66ab, 0x0891,
+ 0x66ae, 0x0e3b,
+ 0x66b2, 0x2125,
+ 0x66b4, 0x0e6b,
+ 0x66b8, 0x1405,
+ 0x66b9, 0x1400,
+ 0x66bc, 0x1403,
+ 0x66be, 0x1402,
+ 0x66bf, 0x2126,
+ 0x66c1, 0x13ff,
+ 0x66c4, 0x1404,
+ 0x66c7, 0x0cb6,
+ 0x66c9, 0x1401,
+ 0x66d6, 0x1406,
+ 0x66d9, 0x0976,
+ 0x66da, 0x1407,
+ 0x66dc, 0x0f35,
+ 0x66dd, 0x0d2e,
+ 0x66e0, 0x1408,
+ 0x66e6, 0x140a,
+ 0x66e9, 0x140b,
+ 0x66f0, 0x140c,
+ 0x66f2, 0x06c2,
+ 0x66f3, 0x04ea,
+ 0x66f4, 0x07cb,
+ 0x66f5, 0x140d,
+ 0x66f7, 0x140e,
+ 0x66f8, 0x097b,
+ 0x66f9, 0x0ae4,
+ 0x66fa, 0x2127,
+ 0x66fb, 0x20b1,
+ 0x66fc, 0x10ed,
+ 0x66fd, 0x0ac0,
+ 0x66fe, 0x0abf,
+ 0x66ff, 0x0b38,
+ 0x6700, 0x0837,
+ 0x6703, 0x104b,
+ 0x6708, 0x0744,
+ 0x6709, 0x0f17,
+ 0x670b, 0x0e4e,
+ 0x670d, 0x0df0,
+ 0x670e, 0x2128,
+ 0x670f, 0x140f,
+ 0x6714, 0x0863,
+ 0x6715, 0x0bdb,
+ 0x6716, 0x1410,
+ 0x6717, 0x0fd5,
+ 0x671b, 0x0e6c,
+ 0x671d, 0x0bc7,
+ 0x671e, 0x1411,
+ 0x671f, 0x0638,
+ 0x6726, 0x1412,
+ 0x6728, 0x0ee6,
+ 0x672a, 0x0eb0,
+ 0x672b, 0x0ea4,
+ 0x672c, 0x0e8a,
+ 0x672d, 0x0873,
+ 0x672e, 0x1415,
+ 0x6731, 0x0917,
+ 0x6734, 0x0e7f,
+ 0x6736, 0x1417,
+ 0x6737, 0x141a,
+ 0x6738, 0x1419,
+ 0x673a, 0x0635,
+ 0x673d, 0x067a,
+ 0x673f, 0x1416,
+ 0x6741, 0x1418,
+ 0x6746, 0x141b,
+ 0x6749, 0x0a3f,
+ 0x674e, 0x0f65,
+ 0x674f, 0x048d,
+ 0x6750, 0x0850,
+ 0x6751, 0x0b1c,
+ 0x6753, 0x0909,
+ 0x6756, 0x09db,
+ 0x6759, 0x141e,
+ 0x675c, 0x0c48,
+ 0x675e, 0x141c,
+ 0x675f, 0x0b0b,
+ 0x6760, 0x141d,
+ 0x6761, 0x09da,
+ 0x6762, 0x0ee9,
+ 0x6763, 0x141f,
+ 0x6765, 0x0f52,
+ 0x6766, 0x212a,
+ 0x676a, 0x1425,
+ 0x676d, 0x07cc,
+ 0x676f, 0x0d0b,
+ 0x6770, 0x1422,
+ 0x6771, 0x0c66,
+ 0x6772, 0x13e3,
+ 0x6773, 0x13e7,
+ 0x6775, 0x0669,
+ 0x6777, 0x0cfd,
+ 0x677c, 0x1424,
+ 0x677e, 0x09a6,
+ 0x677f, 0x0d58,
+ 0x6785, 0x142a,
+ 0x6787, 0x0d8e,
+ 0x6789, 0x1421,
+ 0x678b, 0x1427,
+ 0x678c, 0x1426,
+ 0x6790, 0x0a73,
+ 0x6795, 0x0e9b,
+ 0x6797, 0x0f9b,
+ 0x679a, 0x0e95,
+ 0x679c, 0x054c,
+ 0x679d, 0x08ac,
+ 0x67a0, 0x0fee,
+ 0x67a1, 0x1429,
+ 0x67a2, 0x0a3b,
+ 0x67a6, 0x1428,
+ 0x67a9, 0x1423,
+ 0x67af, 0x0783,
+ 0x67b3, 0x142f,
+ 0x67b4, 0x142d,
+ 0x67b6, 0x054d,
+ 0x67b7, 0x142b,
+ 0x67b8, 0x1431,
+ 0x67b9, 0x1437,
+ 0x67bb, 0x212b,
+ 0x67c0, 0x212d,
+ 0x67c1, 0x0b28,
+ 0x67c4, 0x0e11,
+ 0x67c6, 0x1439,
+ 0x67ca, 0x0d94,
+ 0x67ce, 0x1438,
+ 0x67cf, 0x0d26,
+ 0x67d0, 0x0e6d,
+ 0x67d1, 0x05f7,
+ 0x67d3, 0x0a9b,
+ 0x67d4, 0x094a,
+ 0x67d8, 0x0bef,
+ 0x67da, 0x0f18,
+ 0x67dd, 0x1434,
+ 0x67de, 0x1433,
+ 0x67e2, 0x1435,
+ 0x67e4, 0x1432,
+ 0x67e7, 0x143a,
+ 0x67e9, 0x1430,
+ 0x67ec, 0x142e,
+ 0x67ee, 0x1436,
+ 0x67ef, 0x142c,
+ 0x67f1, 0x0baa,
+ 0x67f3, 0x0f04,
+ 0x67f4, 0x08f2,
+ 0x67f5, 0x0864,
+ 0x67fb, 0x082a,
+ 0x67fe, 0x0e9d,
+ 0x67ff, 0x059f,
+ 0x6801, 0x212e,
+ 0x6802, 0x0bea,
+ 0x6803, 0x0ca2,
+ 0x6804, 0x04eb,
+ 0x6805, 0x1e07,
+ 0x6813, 0x0a96,
+ 0x6816, 0x0a58,
+ 0x6817, 0x0700,
+ 0x681e, 0x143c,
+ 0x6821, 0x07cd,
+ 0x6822, 0x05da,
+ 0x6829, 0x143e,
+ 0x682a, 0x05d2,
+ 0x682b, 0x1444,
+ 0x6832, 0x1441,
+ 0x6834, 0x0a97,
+ 0x6838, 0x05a9,
+ 0x6839, 0x081c,
+ 0x683c, 0x05a8,
+ 0x683d, 0x083f,
+ 0x6840, 0x143f,
+ 0x6841, 0x073b,
+ 0x6842, 0x0721,
+ 0x6843, 0x0c67,
+ 0x6844, 0x212f,
+ 0x6846, 0x143d,
+ 0x6848, 0x048a,
+ 0x684d, 0x1440,
+ 0x684e, 0x1442,
+ 0x6850, 0x06c5,
+ 0x6851, 0x0702,
+ 0x6852, 0x212c,
+ 0x6853, 0x05f8,
+ 0x6854, 0x0665,
+ 0x6859, 0x1445,
+ 0x685c, 0x0869,
+ 0x685d, 0x0e9f,
+ 0x685f, 0x0885,
+ 0x6863, 0x1446,
+ 0x6867, 0x0da2,
+ 0x6874, 0x1452,
+ 0x6876, 0x0533,
+ 0x6877, 0x1447,
+ 0x687e, 0x1458,
+ 0x687f, 0x1448,
+ 0x6881, 0x0f8a,
+ 0x6883, 0x144f,
+ 0x6885, 0x0d15,
+ 0x688d, 0x1457,
+ 0x688e, 0x1e9c,
+ 0x688f, 0x144a,
+ 0x6893, 0x0478,
+ 0x6894, 0x144c,
+ 0x6897, 0x07ce,
+ 0x689b, 0x144e,
+ 0x689d, 0x144d,
+ 0x689f, 0x1449,
+ 0x68a0, 0x1454,
+ 0x68a2, 0x09a7,
+ 0x68a6, 0x11be,
+ 0x68a7, 0x079c,
+ 0x68a8, 0x0f66,
+ 0x68ad, 0x144b,
+ 0x68af, 0x0c10,
+ 0x68b0, 0x0581,
+ 0x68b1, 0x081d,
+ 0x68b3, 0x1443,
+ 0x68b5, 0x1453,
+ 0x68b6, 0x05bf,
+ 0x68b9, 0x1451,
+ 0x68ba, 0x1455,
+ 0x68bc, 0x0c68,
+ 0x68c4, 0x063a,
+ 0x68c6, 0x1473,
+ 0x68c8, 0x20af,
+ 0x68c9, 0x0ed5,
+ 0x68ca, 0x145a,
+ 0x68cb, 0x0639,
+ 0x68cd, 0x1461,
+ 0x68cf, 0x2130,
+ 0x68d2, 0x0e6e,
+ 0x68d4, 0x1462,
+ 0x68d5, 0x1464,
+ 0x68d7, 0x1468,
+ 0x68d8, 0x145c,
+ 0x68da, 0x0b68,
+ 0x68df, 0x0c69,
+ 0x68e0, 0x146c,
+ 0x68e1, 0x145f,
+ 0x68e3, 0x1469,
+ 0x68e7, 0x1463,
+ 0x68ee, 0x09ff,
+ 0x68ef, 0x146d,
+ 0x68f2, 0x0a57,
+ 0x68f9, 0x146b,
+ 0x68fa, 0x05f9,
+ 0x6900, 0x0ff6,
+ 0x6901, 0x1459,
+ 0x6904, 0x1467,
+ 0x6905, 0x049c,
+ 0x6908, 0x145b,
+ 0x690b, 0x0ec6,
+ 0x690c, 0x1460,
+ 0x690d, 0x09e8,
+ 0x690e, 0x0be3,
+ 0x690f, 0x1456,
+ 0x6912, 0x1466,
+ 0x6919, 0x0a40,
+ 0x691a, 0x1470,
+ 0x691b, 0x05cf,
+ 0x691c, 0x0755,
+ 0x6921, 0x1472,
+ 0x6922, 0x145d,
+ 0x6923, 0x1471,
+ 0x6925, 0x146a,
+ 0x6926, 0x145e,
+ 0x6928, 0x146e,
+ 0x692a, 0x146f,
+ 0x6930, 0x1480,
+ 0x6934, 0x0ca6,
+ 0x6936, 0x1465,
+ 0x6939, 0x147c,
+ 0x693d, 0x147e,
+ 0x693f, 0x0bf4,
+ 0x694a, 0x0f36,
+ 0x6953, 0x0de8,
+ 0x6954, 0x1479,
+ 0x6955, 0x0b2a,
+ 0x6959, 0x147f,
+ 0x695a, 0x0ac1,
+ 0x695c, 0x1476,
+ 0x695d, 0x1483,
+ 0x695e, 0x1482,
+ 0x6960, 0x0cc7,
+ 0x6961, 0x1481,
+ 0x6962, 0x0cc2,
+ 0x6968, 0x2132,
+ 0x696a, 0x1485,
+ 0x696b, 0x1478,
+ 0x696d, 0x06c0,
+ 0x696e, 0x147b,
+ 0x696f, 0x0967,
+ 0x6973, 0x0d16,
+ 0x6974, 0x147d,
+ 0x6975, 0x06c3,
+ 0x6977, 0x1475,
+ 0x6978, 0x1477,
+ 0x6979, 0x1474,
+ 0x697c, 0x0fd6,
+ 0x697d, 0x05b8,
+ 0x697e, 0x147a,
+ 0x6981, 0x1484,
+ 0x6982, 0x0593,
+ 0x698a, 0x0857,
+ 0x698e, 0x04ff,
+ 0x6991, 0x1495,
+ 0x6994, 0x0fd7,
+ 0x6995, 0x1498,
+ 0x6998, 0x2134,
+ 0x699b, 0x0a00,
+ 0x699c, 0x1497,
+ 0x69a0, 0x1496,
+ 0x69a7, 0x1493,
+ 0x69ae, 0x1487,
+ 0x69b1, 0x14a4,
+ 0x69b2, 0x1486,
+ 0x69b4, 0x1499,
+ 0x69bb, 0x1491,
+ 0x69be, 0x148c,
+ 0x69bf, 0x1489,
+ 0x69c1, 0x148a,
+ 0x69c3, 0x1492,
+ 0x69c7, 0x1d33,
+ 0x69ca, 0x148f,
+ 0x69cb, 0x07cf,
+ 0x69cc, 0x0be4,
+ 0x69cd, 0x0ae6,
+ 0x69ce, 0x148d,
+ 0x69d0, 0x1488,
+ 0x69d3, 0x148b,
+ 0x69d8, 0x0f37,
+ 0x69d9, 0x0e98,
+ 0x69dd, 0x1490,
+ 0x69de, 0x149a,
+ 0x69e2, 0x2135,
+ 0x69e7, 0x14a2,
+ 0x69e8, 0x149b,
+ 0x69eb, 0x14a8,
+ 0x69ed, 0x14a6,
+ 0x69f2, 0x14a1,
+ 0x69f9, 0x14a0,
+ 0x69fb, 0x0bec,
+ 0x69fd, 0x0ae7,
+ 0x69ff, 0x149e,
+ 0x6a02, 0x149c,
+ 0x6a05, 0x14a3,
+ 0x6a0a, 0x14a9,
+ 0x6a0b, 0x0d89,
+ 0x6a0c, 0x14af,
+ 0x6a12, 0x14aa,
+ 0x6a13, 0x14ad,
+ 0x6a14, 0x14a7,
+ 0x6a17, 0x0bb2,
+ 0x6a19, 0x0daa,
+ 0x6a1b, 0x149d,
+ 0x6a1e, 0x14a5,
+ 0x6a1f, 0x09a8,
+ 0x6a21, 0x0edb,
+ 0x6a22, 0x14b9,
+ 0x6a23, 0x14ac,
+ 0x6a29, 0x0756,
+ 0x6a2a, 0x0523,
+ 0x6a2b, 0x05bd,
+ 0x6a2e, 0x1494,
+ 0x6a30, 0x2136,
+ 0x6a35, 0x09a9,
+ 0x6a36, 0x14b1,
+ 0x6a38, 0x14b8,
+ 0x6a39, 0x0925,
+ 0x6a3a, 0x05d0,
+ 0x6a3d, 0x0b6c,
+ 0x6a44, 0x14ae,
+ 0x6a46, 0x2138,
+ 0x6a47, 0x14b3,
+ 0x6a48, 0x14b7,
+ 0x6a4b, 0x06ae,
+ 0x6a58, 0x0666,
+ 0x6a59, 0x14b5,
+ 0x6a5f, 0x063b,
+ 0x6a61, 0x0ca3,
+ 0x6a62, 0x14b4,
+ 0x6a66, 0x14b6,
+ 0x6a6b, 0x2137,
+ 0x6a72, 0x14b0,
+ 0x6a73, 0x2139,
+ 0x6a78, 0x14b2,
+ 0x6a7e, 0x213a,
+ 0x6a7f, 0x05be,
+ 0x6a80, 0x0b87,
+ 0x6a84, 0x14bd,
+ 0x6a8d, 0x14bb,
+ 0x6a8e, 0x079d,
+ 0x6a90, 0x14ba,
+ 0x6a97, 0x14c0,
+ 0x6a9c, 0x143b,
+ 0x6aa0, 0x14bc,
+ 0x6aa2, 0x14be,
+ 0x6aaa, 0x14cb,
+ 0x6aac, 0x14c7,
+ 0x6aae, 0x1450,
+ 0x6ab3, 0x14c6,
+ 0x6ab8, 0x14c5,
+ 0x6abb, 0x14c2,
+ 0x6ac1, 0x14ab,
+ 0x6ac2, 0x14c4,
+ 0x6ac3, 0x14c3,
+ 0x6ad1, 0x14c9,
+ 0x6ad3, 0x0fcc,
+ 0x6ada, 0x14cc,
+ 0x6adb, 0x06f3,
+ 0x6ade, 0x14c8,
+ 0x6adf, 0x14ca,
+ 0x6ae2, 0x213b,
+ 0x6ae4, 0x213c,
+ 0x6ae8, 0x0d3b,
+ 0x6aea, 0x14cd,
+ 0x6afa, 0x14d1,
+ 0x6afb, 0x14ce,
+ 0x6b04, 0x0f5d,
+ 0x6b05, 0x14cf,
+ 0x6b0a, 0x149f,
+ 0x6b12, 0x14d2,
+ 0x6b16, 0x14d3,
+ 0x6b1d, 0x04d7,
+ 0x6b1f, 0x14d5,
+ 0x6b20, 0x073d,
+ 0x6b21, 0x08cd,
+ 0x6b23, 0x06cd,
+ 0x6b27, 0x0524,
+ 0x6b32, 0x0f49,
+ 0x6b37, 0x14d7,
+ 0x6b38, 0x14d6,
+ 0x6b39, 0x14d9,
+ 0x6b3a, 0x0657,
+ 0x6b3d, 0x06ce,
+ 0x6b3e, 0x05fa,
+ 0x6b43, 0x14dc,
+ 0x6b47, 0x14db,
+ 0x6b49, 0x14dd,
+ 0x6b4c, 0x054e,
+ 0x6b4e, 0x0b75,
+ 0x6b50, 0x14de,
+ 0x6b53, 0x05fb,
+ 0x6b54, 0x14e0,
+ 0x6b59, 0x14df,
+ 0x6b5b, 0x14e1,
+ 0x6b5f, 0x14e2,
+ 0x6b61, 0x14e3,
+ 0x6b62, 0x08ad,
+ 0x6b63, 0x0a59,
+ 0x6b64, 0x0811,
+ 0x6b66, 0x0de2,
+ 0x6b69, 0x0e32,
+ 0x6b6a, 0x0fea,
+ 0x6b6f, 0x08c3,
+ 0x6b73, 0x0840,
+ 0x6b74, 0x0fba,
+ 0x6b78, 0x14e4,
+ 0x6b7b, 0x08ae,
+ 0x6b7f, 0x14e6,
+ 0x6b83, 0x14e9,
+ 0x6b84, 0x14e8,
+ 0x6b86, 0x0e86,
+ 0x6b89, 0x0968,
+ 0x6b8a, 0x0918,
+ 0x6b8b, 0x0892,
+ 0x6b8d, 0x14ea,
+ 0x6b95, 0x14ec,
+ 0x6b96, 0x09e9,
+ 0x6b98, 0x14eb,
+ 0x6b9e, 0x14ed,
+ 0x6ba4, 0x14ee,
+ 0x6baa, 0x14ef,
+ 0x6baf, 0x14f1,
+ 0x6bb1, 0x14f3,
+ 0x6bb2, 0x14f2,
+ 0x6bb3, 0x14f4,
+ 0x6bb4, 0x0525,
+ 0x6bb5, 0x0b88,
+ 0x6bb7, 0x14f5,
+ 0x6bba, 0x0874,
+ 0x6bbb, 0x05aa,
+ 0x6bbc, 0x14f6,
+ 0x6bbf, 0x0c3c,
+ 0x6bc0, 0x119d,
+ 0x6bc5, 0x063d,
+ 0x6bc6, 0x14f7,
+ 0x6bcb, 0x14f8,
+ 0x6bcd, 0x0e3c,
+ 0x6bce, 0x0e96,
+ 0x6bd2, 0x0c9f,
+ 0x6bd3, 0x14f9,
+ 0x6bd4, 0x0d7a,
+ 0x6bd6, 0x213d,
+ 0x6bd8, 0x0d8f,
+ 0x6bdb, 0x0edf,
+ 0x6bdf, 0x14fa,
+ 0x6beb, 0x14fc,
+ 0x6bec, 0x14fb,
+ 0x6bef, 0x14fe,
+ 0x6bf3, 0x14fd,
+ 0x6c08, 0x1500,
+ 0x6c0f, 0x08af,
+ 0x6c11, 0x0ebd,
+ 0x6c13, 0x1501,
+ 0x6c17, 0x063e,
+ 0x6c1b, 0x1503,
+ 0x6c23, 0x1505,
+ 0x6c24, 0x1504,
+ 0x6c34, 0x0a2b,
+ 0x6c37, 0x0dab,
+ 0x6c38, 0x04ec,
+ 0x6c3e, 0x0d59,
+ 0x6c3f, 0x213e,
+ 0x6c40, 0x0c11,
+ 0x6c41, 0x094b,
+ 0x6c42, 0x067b,
+ 0x6c4e, 0x0d5a,
+ 0x6c50, 0x08da,
+ 0x6c55, 0x1507,
+ 0x6c57, 0x05fc,
+ 0x6c5a, 0x051a,
+ 0x6c5c, 0x213f,
+ 0x6c5d, 0x0cca,
+ 0x6c5e, 0x1506,
+ 0x6c5f, 0x07d0,
+ 0x6c60, 0x0b91,
+ 0x6c62, 0x1508,
+ 0x6c68, 0x1510,
+ 0x6c6a, 0x1509,
+ 0x6c6f, 0x2141,
+ 0x6c70, 0x0b21,
+ 0x6c72, 0x067c,
+ 0x6c73, 0x1511,
+ 0x6c7a, 0x073e,
+ 0x6c7d, 0x063f,
+ 0x6c7e, 0x150f,
+ 0x6c81, 0x150d,
+ 0x6c82, 0x150a,
+ 0x6c83, 0x0f4a,
+ 0x6c86, 0x2140,
+ 0x6c88, 0x0bdc,
+ 0x6c8c, 0x0cb1,
+ 0x6c8d, 0x150b,
+ 0x6c90, 0x1513,
+ 0x6c92, 0x1512,
+ 0x6c93, 0x06f9,
+ 0x6c96, 0x052d,
+ 0x6c99, 0x082b,
+ 0x6c9a, 0x150c,
+ 0x6c9b, 0x150e,
+ 0x6ca1, 0x0e85,
+ 0x6ca2, 0x0b54,
+ 0x6cab, 0x0ea5,
+ 0x6cae, 0x151b,
+ 0x6cb1, 0x151c,
+ 0x6cb3, 0x054f,
+ 0x6cb8, 0x0df8,
+ 0x6cb9, 0x0f09,
+ 0x6cba, 0x151e,
+ 0x6cbb, 0x08cf,
+ 0x6cbc, 0x09aa,
+ 0x6cbd, 0x1517,
+ 0x6cbe, 0x151d,
+ 0x6cbf, 0x050a,
+ 0x6cc1, 0x06af,
+ 0x6cc4, 0x1514,
+ 0x6cc5, 0x1519,
+ 0x6cc9, 0x0a98,
+ 0x6cca, 0x0d27,
+ 0x6ccc, 0x0d7b,
+ 0x6cd3, 0x1516,
+ 0x6cd5, 0x0e4f,
+ 0x6cd7, 0x1518,
+ 0x6cd9, 0x1521,
+ 0x6cda, 0x2142,
+ 0x6cdb, 0x151f,
+ 0x6cdd, 0x151a,
+ 0x6ce1, 0x0e50,
+ 0x6ce2, 0x0cfe,
+ 0x6ce3, 0x067d,
+ 0x6ce5, 0x0c1f,
+ 0x6ce8, 0x0bab,
+ 0x6cea, 0x1522,
+ 0x6cef, 0x1520,
+ 0x6cf0, 0x0b39,
+ 0x6cf1, 0x1515,
+ 0x6cf3, 0x04ed,
+ 0x6d04, 0x2143,
+ 0x6d0b, 0x0f38,
+ 0x6d0c, 0x152d,
+ 0x6d12, 0x152c,
+ 0x6d17, 0x0a9a,
+ 0x6d19, 0x1529,
+ 0x6d1b, 0x0f56,
+ 0x6d1e, 0x0c8e,
+ 0x6d1f, 0x1523,
+ 0x6d25, 0x0be1,
+ 0x6d29, 0x04ee,
+ 0x6d2a, 0x07d1,
+ 0x6d2b, 0x1526,
+ 0x6d32, 0x0931,
+ 0x6d33, 0x152b,
+ 0x6d35, 0x152a,
+ 0x6d36, 0x1525,
+ 0x6d38, 0x1528,
+ 0x6d3b, 0x05c6,
+ 0x6d3d, 0x1527,
+ 0x6d3e, 0x0cff,
+ 0x6d41, 0x0f76,
+ 0x6d44, 0x09dc,
+ 0x6d45, 0x0a99,
+ 0x6d59, 0x1533,
+ 0x6d5a, 0x1531,
+ 0x6d5c, 0x0dbf,
+ 0x6d63, 0x152e,
+ 0x6d64, 0x1530,
+ 0x6d66, 0x04dc,
+ 0x6d69, 0x07d2,
+ 0x6d6a, 0x0fd8,
+ 0x6d6c, 0x059b,
+ 0x6d6e, 0x0dd4,
+ 0x6d6f, 0x2145,
+ 0x6d74, 0x0f4b,
+ 0x6d77, 0x0582,
+ 0x6d78, 0x0a01,
+ 0x6d79, 0x1532,
+ 0x6d85, 0x1537,
+ 0x6d87, 0x2144,
+ 0x6d88, 0x09ab,
+ 0x6d8c, 0x0f1a,
+ 0x6d8e, 0x1534,
+ 0x6d93, 0x152f,
+ 0x6d95, 0x1535,
+ 0x6d96, 0x2146,
+ 0x6d99, 0x0fa6,
+ 0x6d9b, 0x0c6d,
+ 0x6d9c, 0x0c9a,
+ 0x6dac, 0x2147,
+ 0x6daf, 0x0594,
+ 0x6db2, 0x04f7,
+ 0x6db5, 0x153b,
+ 0x6db8, 0x153e,
+ 0x6dbc, 0x0f8b,
+ 0x6dc0, 0x0f4e,
+ 0x6dc5, 0x1545,
+ 0x6dc6, 0x153f,
+ 0x6dc7, 0x153c,
+ 0x6dcb, 0x0f9c,
+ 0x6dcc, 0x1542,
+ 0x6dcf, 0x2148,
+ 0x6dd1, 0x0954,
+ 0x6dd2, 0x1544,
+ 0x6dd5, 0x1549,
+ 0x6dd8, 0x0c6b,
+ 0x6dd9, 0x1547,
+ 0x6dde, 0x1541,
+ 0x6de1, 0x0b76,
+ 0x6de4, 0x1548,
+ 0x6de6, 0x153d,
+ 0x6de8, 0x1543,
+ 0x6dea, 0x154a,
+ 0x6deb, 0x04c0,
+ 0x6dec, 0x1540,
+ 0x6dee, 0x154b,
+ 0x6df1, 0x0a02,
+ 0x6df2, 0x214a,
+ 0x6df3, 0x0969,
+ 0x6df5, 0x0df5,
+ 0x6df7, 0x081e,
+ 0x6df8, 0x2149,
+ 0x6df9, 0x1538,
+ 0x6dfa, 0x1546,
+ 0x6dfb, 0x0c34,
+ 0x6dfc, 0x214b,
+ 0x6e05, 0x0a5a,
+ 0x6e07, 0x05c7,
+ 0x6e08, 0x0841,
+ 0x6e09, 0x09ac,
+ 0x6e0a, 0x153a,
+ 0x6e0b, 0x094c,
+ 0x6e13, 0x0722,
+ 0x6e15, 0x1539,
+ 0x6e19, 0x154f,
+ 0x6e1a, 0x0977,
+ 0x6e1b, 0x076e,
+ 0x6e1d, 0x155e,
+ 0x6e1f, 0x1558,
+ 0x6e20, 0x068e,
+ 0x6e21, 0x0c49,
+ 0x6e23, 0x1553,
+ 0x6e24, 0x155c,
+ 0x6e25, 0x0473,
+ 0x6e26, 0x04d4,
+ 0x6e27, 0x214e,
+ 0x6e29, 0x0539,
+ 0x6e2b, 0x1555,
+ 0x6e2c, 0x0b0c,
+ 0x6e2d, 0x154c,
+ 0x6e2e, 0x154e,
+ 0x6e2f, 0x07d3,
+ 0x6e38, 0x155f,
+ 0x6e39, 0x214c,
+ 0x6e3a, 0x155a,
+ 0x6e3c, 0x214f,
+ 0x6e3e, 0x1552,
+ 0x6e43, 0x1559,
+ 0x6e4a, 0x0eb7,
+ 0x6e4d, 0x1557,
+ 0x6e4e, 0x155b,
+ 0x6e56, 0x0784,
+ 0x6e58, 0x09ad,
+ 0x6e5b, 0x0b77,
+ 0x6e5c, 0x214d,
+ 0x6e5f, 0x1551,
+ 0x6e67, 0x0f19,
+ 0x6e6b, 0x1554,
+ 0x6e6e, 0x154d,
+ 0x6e6f, 0x0c6c,
+ 0x6e72, 0x1550,
+ 0x6e76, 0x1556,
+ 0x6e7e, 0x0ff7,
+ 0x6e7f, 0x08ea,
+ 0x6e80, 0x0eac,
+ 0x6e82, 0x1560,
+ 0x6e8c, 0x0d42,
+ 0x6e8f, 0x156c,
+ 0x6e90, 0x076f,
+ 0x6e96, 0x096a,
+ 0x6e98, 0x1562,
+ 0x6e9c, 0x0f77,
+ 0x6e9d, 0x07d4,
+ 0x6e9f, 0x156f,
+ 0x6ea2, 0x04b2,
+ 0x6ea5, 0x156d,
+ 0x6eaa, 0x1561,
+ 0x6eaf, 0x1567,
+ 0x6eb2, 0x1569,
+ 0x6eb6, 0x0f39,
+ 0x6eb7, 0x1564,
+ 0x6eba, 0x0c28,
+ 0x6ebd, 0x1566,
+ 0x6ebf, 0x2150,
+ 0x6ec2, 0x156e,
+ 0x6ec4, 0x1568,
+ 0x6ec5, 0x0ed3,
+ 0x6ec9, 0x1563,
+ 0x6ecb, 0x08ce,
+ 0x6ecc, 0x157b,
+ 0x6ed1, 0x05c8,
+ 0x6ed3, 0x1565,
+ 0x6ed4, 0x156a,
+ 0x6edd, 0x0b4c,
+ 0x6ede, 0x0b3a,
+ 0x6eec, 0x1573,
+ 0x6eef, 0x1579,
+ 0x6ef2, 0x1577,
+ 0x6ef4, 0x0c23,
+ 0x6ef7, 0x157e,
+ 0x6ef8, 0x1574,
+ 0x6efe, 0x1575,
+ 0x6eff, 0x155d,
+ 0x6f01, 0x0693,
+ 0x6f02, 0x0dac,
+ 0x6f06, 0x08eb,
+ 0x6f09, 0x0809,
+ 0x6f0f, 0x0fd9,
+ 0x6f11, 0x1571,
+ 0x6f13, 0x157d,
+ 0x6f14, 0x050b,
+ 0x6f15, 0x0ae8,
+ 0x6f20, 0x0d2f,
+ 0x6f22, 0x05fd,
+ 0x6f23, 0x0fc2,
+ 0x6f2b, 0x0ead,
+ 0x6f2c, 0x0bee,
+ 0x6f31, 0x1578,
+ 0x6f32, 0x157a,
+ 0x6f38, 0x0ab4,
+ 0x6f3e, 0x157c,
+ 0x6f3f, 0x1576,
+ 0x6f41, 0x1570,
+ 0x6f45, 0x05ff,
+ 0x6f51, 0x1e60,
+ 0x6f54, 0x073f,
+ 0x6f58, 0x158a,
+ 0x6f5b, 0x1585,
+ 0x6f5c, 0x0a9c,
+ 0x6f5f, 0x05c1,
+ 0x6f64, 0x096b,
+ 0x6f66, 0x158e,
+ 0x6f6d, 0x1587,
+ 0x6f6e, 0x0bc8,
+ 0x6f6f, 0x1584,
+ 0x6f70, 0x0bf5,
+ 0x6f74, 0x15a7,
+ 0x6f78, 0x1581,
+ 0x6f7a, 0x1580,
+ 0x6f7c, 0x1589,
+ 0x6f80, 0x1583,
+ 0x6f81, 0x1582,
+ 0x6f82, 0x1588,
+ 0x6f84, 0x0a45,
+ 0x6f86, 0x157f,
+ 0x6f88, 0x2151,
+ 0x6f8e, 0x158b,
+ 0x6f91, 0x158c,
+ 0x6f97, 0x05fe,
+ 0x6fa1, 0x1591,
+ 0x6fa3, 0x1590,
+ 0x6fa4, 0x1592,
+ 0x6faa, 0x1595,
+ 0x6fb1, 0x0c3d,
+ 0x6fb3, 0x158f,
+ 0x6fb5, 0x2152,
+ 0x6fb9, 0x1593,
+ 0x6fc0, 0x0739,
+ 0x6fc1, 0x0b59,
+ 0x6fc2, 0x158d,
+ 0x6fc3, 0x0cf1,
+ 0x6fc6, 0x1594,
+ 0x6fd4, 0x1599,
+ 0x6fd5, 0x1597,
+ 0x6fd8, 0x159a,
+ 0x6fdb, 0x159d,
+ 0x6fdf, 0x1596,
+ 0x6fe0, 0x07fc,
+ 0x6fe1, 0x0cde,
+ 0x6fe4, 0x1536,
+ 0x6feb, 0x0f5e,
+ 0x6fec, 0x1598,
+ 0x6fee, 0x159c,
+ 0x6fef, 0x0b55,
+ 0x6ff1, 0x159b,
+ 0x6ff3, 0x1586,
+ 0x6ff5, 0x2153,
+ 0x6ff6, 0x1ba4,
+ 0x6ffa, 0x15a0,
+ 0x6ffe, 0x15a4,
+ 0x7001, 0x15a2,
+ 0x7005, 0x2154,
+ 0x7006, 0x1e50,
+ 0x7007, 0x2155,
+ 0x7009, 0x159e,
+ 0x700b, 0x159f,
+ 0x700f, 0x15a3,
+ 0x7011, 0x15a1,
+ 0x7015, 0x0dc0,
+ 0x7018, 0x15a9,
+ 0x701a, 0x15a6,
+ 0x701b, 0x15a5,
+ 0x701d, 0x15a8,
+ 0x701e, 0x0cac,
+ 0x701f, 0x15aa,
+ 0x7026, 0x0bb3,
+ 0x7027, 0x0b4d,
+ 0x7028, 0x2156,
+ 0x702c, 0x0a49,
+ 0x7030, 0x15ab,
+ 0x7032, 0x15ad,
+ 0x703e, 0x15ac,
+ 0x704c, 0x1572,
+ 0x7051, 0x15ae,
+ 0x7058, 0x0cbf,
+ 0x7063, 0x15af,
+ 0x706b, 0x0550,
+ 0x706f, 0x0c6e,
+ 0x7070, 0x0583,
+ 0x7078, 0x067e,
+ 0x707c, 0x090a,
+ 0x707d, 0x0842,
+ 0x7085, 0x2157,
+ 0x7089, 0x0fcd,
+ 0x708a, 0x0a2c,
+ 0x708e, 0x050c,
+ 0x7092, 0x15b1,
+ 0x7099, 0x15b0,
+ 0x70ab, 0x2158,
+ 0x70ac, 0x15b4,
+ 0x70ad, 0x0b78,
+ 0x70ae, 0x15b7,
+ 0x70af, 0x15b2,
+ 0x70b3, 0x15b6,
+ 0x70b8, 0x15b5,
+ 0x70b9, 0x0c3a,
+ 0x70ba, 0x049d,
+ 0x70bb, 0x20ad,
+ 0x70c8, 0x0fbd,
+ 0x70cb, 0x15b9,
+ 0x70cf, 0x04ca,
+ 0x70d9, 0x15bb,
+ 0x70dd, 0x15ba,
+ 0x70df, 0x15b8,
+ 0x70f1, 0x15b3,
+ 0x70f9, 0x0e51,
+ 0x70fd, 0x15bd,
+ 0x7104, 0x215a,
+ 0x7109, 0x15bc,
+ 0x710f, 0x2159,
+ 0x7114, 0x050d,
+ 0x7119, 0x15bf,
+ 0x711a, 0x0e02,
+ 0x711c, 0x15be,
+ 0x7121, 0x0ec1,
+ 0x7126, 0x09af,
+ 0x7130, 0x1ddc,
+ 0x7136, 0x0ab5,
+ 0x713c, 0x09ae,
+ 0x7146, 0x215c,
+ 0x7149, 0x0fc3,
+ 0x714c, 0x15c5,
+ 0x714e, 0x0a9d,
+ 0x7155, 0x15c1,
+ 0x7156, 0x15c6,
+ 0x7159, 0x050e,
+ 0x715c, 0x215b,
+ 0x7162, 0x15c4,
+ 0x7164, 0x0d17,
+ 0x7165, 0x15c0,
+ 0x7166, 0x15c3,
+ 0x7167, 0x09b0,
+ 0x7169, 0x0d65,
+ 0x716c, 0x15c7,
+ 0x716e, 0x08fd,
+ 0x717d, 0x0a9e,
+ 0x7184, 0x15ca,
+ 0x7188, 0x15c2,
+ 0x718a, 0x06fd,
+ 0x718f, 0x15c8,
+ 0x7194, 0x0f3a,
+ 0x7195, 0x15cb,
+ 0x7199, 0x205d,
+ 0x719f, 0x0959,
+ 0x71a8, 0x15cc,
+ 0x71ac, 0x15cd,
+ 0x71b1, 0x0ce4,
+ 0x71b9, 0x15cf,
+ 0x71be, 0x15d0,
+ 0x71c1, 0x215f,
+ 0x71c3, 0x0ce9,
+ 0x71c8, 0x0c6f,
+ 0x71c9, 0x15d2,
+ 0x71ce, 0x15d4,
+ 0x71d0, 0x0f9d,
+ 0x71d2, 0x15d1,
+ 0x71d4, 0x15d3,
+ 0x71d5, 0x050f,
+ 0x71d7, 0x15ce,
+ 0x71df, 0x114e,
+ 0x71e0, 0x15d5,
+ 0x71e5, 0x0ae9,
+ 0x71e6, 0x0886,
+ 0x71e7, 0x15d7,
+ 0x71ec, 0x15d6,
+ 0x71ed, 0x09ea,
+ 0x71ee, 0x10ee,
+ 0x71f5, 0x15d8,
+ 0x71f9, 0x15da,
+ 0x71fb, 0x15c9,
+ 0x71fc, 0x15d9,
+ 0x71fe, 0x2160,
+ 0x71ff, 0x15db,
+ 0x7206, 0x0d30,
+ 0x720d, 0x15dc,
+ 0x7210, 0x15dd,
+ 0x721b, 0x15de,
+ 0x7228, 0x15df,
+ 0x722a, 0x0bfa,
+ 0x722c, 0x15e1,
+ 0x722d, 0x15e0,
+ 0x7230, 0x15e2,
+ 0x7232, 0x15e3,
+ 0x7235, 0x090b,
+ 0x7236, 0x0dd5,
+ 0x723a, 0x0ef8,
+ 0x723b, 0x15e4,
+ 0x723d, 0x0ad8,
+ 0x723e, 0x08d0,
+ 0x723f, 0x15e6,
+ 0x7246, 0x15e8,
+ 0x7247, 0x0e22,
+ 0x7248, 0x0d5b,
+ 0x724b, 0x15e9,
+ 0x724c, 0x0d0d,
+ 0x7252, 0x0bc9,
+ 0x7258, 0x15ea,
+ 0x7259, 0x0567,
+ 0x725b, 0x0687,
+ 0x725d, 0x0ed2,
+ 0x725f, 0x0ec2,
+ 0x7261, 0x0534,
+ 0x7262, 0x0fda,
+ 0x7267, 0x0e80,
+ 0x7269, 0x0dfa,
+ 0x7272, 0x0a5b,
+ 0x7274, 0x15eb,
+ 0x7279, 0x0c9b,
+ 0x727d, 0x0757,
+ 0x727e, 0x15ec,
+ 0x7280, 0x0844,
+ 0x7281, 0x15ee,
+ 0x7282, 0x15ed,
+ 0x7287, 0x15ef,
+ 0x7292, 0x15f0,
+ 0x7296, 0x15f1,
+ 0x72a0, 0x0658,
+ 0x72a2, 0x15f2,
+ 0x72a7, 0x15f3,
+ 0x72ac, 0x0758,
+ 0x72af, 0x0d5c,
+ 0x72b1, 0x2161,
+ 0x72b2, 0x15f5,
+ 0x72b6, 0x09dd,
+ 0x72b9, 0x15f4,
+ 0x72be, 0x2162,
+ 0x72c2, 0x06b0,
+ 0x72c3, 0x15f6,
+ 0x72c4, 0x15f8,
+ 0x72c6, 0x15f7,
+ 0x72ce, 0x15f9,
+ 0x72d0, 0x0785,
+ 0x72d2, 0x15fa,
+ 0x72d7, 0x06e1,
+ 0x72d9, 0x0ac2,
+ 0x72db, 0x080f,
+ 0x72e0, 0x15fc,
+ 0x72e2, 0x15fb,
+ 0x72e9, 0x0919,
+ 0x72ec, 0x0ca0,
+ 0x72ed, 0x06b1,
+ 0x72f7, 0x15ff,
+ 0x72f8, 0x0b6a,
+ 0x72f9, 0x15fe,
+ 0x72fc, 0x0fdb,
+ 0x72fd, 0x0d18,
+ 0x730a, 0x1602,
+ 0x7316, 0x1604,
+ 0x7317, 0x1601,
+ 0x731b, 0x0ee0,
+ 0x731c, 0x1603,
+ 0x731d, 0x1605,
+ 0x731f, 0x0f8c,
+ 0x7324, 0x2163,
+ 0x7325, 0x1609,
+ 0x7329, 0x1608,
+ 0x732a, 0x0bb4,
+ 0x732b, 0x0ce3,
+ 0x732e, 0x0759,
+ 0x732f, 0x1607,
+ 0x7334, 0x1606,
+ 0x7336, 0x0f1b,
+ 0x733e, 0x160a,
+ 0x733f, 0x0510,
+ 0x7344, 0x0808,
+ 0x7345, 0x08b0,
+ 0x734e, 0x160b,
+ 0x7357, 0x160e,
+ 0x7363, 0x094d,
+ 0x7368, 0x1610,
+ 0x736a, 0x160f,
+ 0x7370, 0x1611,
+ 0x7372, 0x05ab,
+ 0x7375, 0x1613,
+ 0x7377, 0x2165,
+ 0x7378, 0x1612,
+ 0x737a, 0x1615,
+ 0x737b, 0x1614,
+ 0x7384, 0x0770,
+ 0x7387, 0x0f70,
+ 0x7389, 0x06c4,
+ 0x738b, 0x0526,
+ 0x7396, 0x06e2,
+ 0x73a9, 0x061d,
+ 0x73b2, 0x0fb0,
+ 0x73b3, 0x1617,
+ 0x73bb, 0x1619,
+ 0x73bd, 0x2166,
+ 0x73c0, 0x161a,
+ 0x73c2, 0x0551,
+ 0x73c8, 0x1616,
+ 0x73c9, 0x2167,
+ 0x73ca, 0x0887,
+ 0x73cd, 0x0bdd,
+ 0x73ce, 0x1618,
+ 0x73d2, 0x216a,
+ 0x73d6, 0x2168,
+ 0x73de, 0x161d,
+ 0x73e0, 0x091a,
+ 0x73e3, 0x2169,
+ 0x73e5, 0x161b,
+ 0x73ea, 0x0714,
+ 0x73ed, 0x0d5d,
+ 0x73ee, 0x161c,
+ 0x73f1, 0x1637,
+ 0x73f5, 0x216c,
+ 0x73f8, 0x1622,
+ 0x73fe, 0x0771,
+ 0x7403, 0x067f,
+ 0x7405, 0x161f,
+ 0x7406, 0x0f67,
+ 0x7407, 0x216b,
+ 0x7409, 0x0f78,
+ 0x7422, 0x0b56,
+ 0x7425, 0x1621,
+ 0x7426, 0x216d,
+ 0x7429, 0x216f,
+ 0x742a, 0x216e,
+ 0x742e, 0x2170,
+ 0x7432, 0x1623,
+ 0x7433, 0x0f9e,
+ 0x7434, 0x06cf,
+ 0x7435, 0x0d90,
+ 0x7436, 0x0d00,
+ 0x743a, 0x1624,
+ 0x743f, 0x1626,
+ 0x7441, 0x1629,
+ 0x7455, 0x1625,
+ 0x7459, 0x1628,
+ 0x745a, 0x079e,
+ 0x745b, 0x04ef,
+ 0x745c, 0x162a,
+ 0x745e, 0x0a36,
+ 0x745f, 0x1627,
+ 0x7460, 0x0fa4,
+ 0x7462, 0x2171,
+ 0x7463, 0x162d,
+ 0x7464, 0x1d35,
+ 0x7469, 0x162b,
+ 0x746a, 0x162e,
+ 0x746f, 0x1620,
+ 0x7470, 0x162c,
+ 0x7473, 0x082c,
+ 0x7476, 0x162f,
+ 0x747e, 0x1630,
+ 0x7483, 0x0f68,
+ 0x7489, 0x2172,
+ 0x748b, 0x1631,
+ 0x749e, 0x1632,
+ 0x749f, 0x2173,
+ 0x74a2, 0x161e,
+ 0x74a7, 0x1633,
+ 0x74b0, 0x0600,
+ 0x74bd, 0x08d1,
+ 0x74ca, 0x1634,
+ 0x74cf, 0x1635,
+ 0x74d4, 0x1636,
+ 0x74dc, 0x04dd,
+ 0x74e0, 0x1638,
+ 0x74e2, 0x0dad,
+ 0x74e3, 0x1639,
+ 0x74e6, 0x05e0,
+ 0x74e7, 0x163a,
+ 0x74e9, 0x163b,
+ 0x74ee, 0x163c,
+ 0x74f0, 0x163e,
+ 0x74f2, 0x163d,
+ 0x74f6, 0x0dc5,
+ 0x74f7, 0x1641,
+ 0x74f8, 0x1640,
+ 0x7501, 0x2174,
+ 0x7503, 0x1643,
+ 0x7504, 0x1642,
+ 0x7505, 0x1644,
+ 0x750c, 0x1645,
+ 0x750d, 0x1647,
+ 0x750e, 0x1646,
+ 0x7511, 0x080b,
+ 0x7513, 0x1649,
+ 0x7515, 0x1648,
+ 0x7518, 0x0601,
+ 0x751a, 0x0a19,
+ 0x751c, 0x0c36,
+ 0x751e, 0x164a,
+ 0x751f, 0x0a5c,
+ 0x7523, 0x0888,
+ 0x7525, 0x051b,
+ 0x7526, 0x164b,
+ 0x7528, 0x0f3b,
+ 0x752b, 0x0e33,
+ 0x752c, 0x164c,
+ 0x752f, 0x20f2,
+ 0x7530, 0x0c3e,
+ 0x7531, 0x0f1d,
+ 0x7532, 0x07d5,
+ 0x7533, 0x0a03,
+ 0x7537, 0x0b89,
+ 0x7538, 0x10c9,
+ 0x753a, 0x0bca,
+ 0x753b, 0x0568,
+ 0x753c, 0x164d,
+ 0x7544, 0x164e,
+ 0x7546, 0x1653,
+ 0x7549, 0x1651,
+ 0x754a, 0x1650,
+ 0x754b, 0x13c7,
+ 0x754c, 0x0584,
+ 0x754d, 0x164f,
+ 0x754f, 0x049e,
+ 0x7551, 0x0d3e,
+ 0x7554, 0x0d5e,
+ 0x7559, 0x0f79,
+ 0x755a, 0x1654,
+ 0x755b, 0x1652,
+ 0x755c, 0x0b9a,
+ 0x755d, 0x0a4a,
+ 0x7560, 0x0d3f,
+ 0x7562, 0x0d9f,
+ 0x7564, 0x1656,
+ 0x7565, 0x0f74,
+ 0x7566, 0x0723,
+ 0x7567, 0x1657,
+ 0x7569, 0x1655,
+ 0x756a, 0x0d6a,
+ 0x756b, 0x1658,
+ 0x756d, 0x1659,
+ 0x756f, 0x2175,
+ 0x7570, 0x049f,
+ 0x7573, 0x09de,
+ 0x7574, 0x165e,
+ 0x7576, 0x165b,
+ 0x7577, 0x0cc5,
+ 0x7578, 0x165a,
+ 0x757f, 0x0640,
+ 0x7582, 0x1661,
+ 0x7586, 0x165c,
+ 0x7589, 0x1660,
+ 0x758a, 0x165f,
+ 0x758b, 0x0d97,
+ 0x758e, 0x0ac4,
+ 0x758f, 0x0ac3,
+ 0x7591, 0x0659,
+ 0x7594, 0x1662,
+ 0x759a, 0x1663,
+ 0x759d, 0x1664,
+ 0x75a3, 0x1666,
+ 0x75a5, 0x1665,
+ 0x75ab, 0x04f8,
+ 0x75b1, 0x166e,
+ 0x75b2, 0x0d7c,
+ 0x75b3, 0x1668,
+ 0x75b5, 0x166a,
+ 0x75b8, 0x166c,
+ 0x75b9, 0x0a04,
+ 0x75bc, 0x166d,
+ 0x75bd, 0x166b,
+ 0x75be, 0x08ec,
+ 0x75c2, 0x1667,
+ 0x75c3, 0x1669,
+ 0x75c5, 0x0db4,
+ 0x75c7, 0x09b1,
+ 0x75ca, 0x1670,
+ 0x75cd, 0x166f,
+ 0x75d2, 0x1671,
+ 0x75d4, 0x08d2,
+ 0x75d5, 0x081f,
+ 0x75d8, 0x0c71,
+ 0x75d9, 0x1672,
+ 0x75db, 0x0be7,
+ 0x75de, 0x1674,
+ 0x75e2, 0x0f69,
+ 0x75e3, 0x1673,
+ 0x75e9, 0x0aeb,
+ 0x75f0, 0x1679,
+ 0x75f2, 0x167b,
+ 0x75f4, 0x0b92,
+ 0x75fa, 0x167a,
+ 0x75fc, 0x1677,
+ 0x75fe, 0x1675,
+ 0x7601, 0x1678,
+ 0x7609, 0x167f,
+ 0x760b, 0x167d,
+ 0x760d, 0x167e,
+ 0x761f, 0x1680,
+ 0x7620, 0x1682,
+ 0x7624, 0x1685,
+ 0x7626, 0x1e2d,
+ 0x7627, 0x1681,
+ 0x7630, 0x1687,
+ 0x7634, 0x1686,
+ 0x763b, 0x1688,
+ 0x7642, 0x0f8d,
+ 0x7646, 0x168b,
+ 0x7647, 0x1689,
+ 0x764c, 0x061e,
+ 0x7652, 0x0f0a,
+ 0x7656, 0x0e1a,
+ 0x7658, 0x168d,
+ 0x765c, 0x168c,
+ 0x7661, 0x168e,
+ 0x7667, 0x1693,
+ 0x7668, 0x1690,
+ 0x766c, 0x1694,
+ 0x7670, 0x1695,
+ 0x7672, 0x1696,
+ 0x7676, 0x1697,
+ 0x7678, 0x1698,
+ 0x767a, 0x0d43,
+ 0x767b, 0x0c4a,
+ 0x767c, 0x1699,
+ 0x767d, 0x0d28,
+ 0x767e, 0x0da6,
+ 0x7680, 0x169a,
+ 0x7682, 0x2176,
+ 0x7683, 0x169b,
+ 0x7684, 0x0c24,
+ 0x7686, 0x0585,
+ 0x7687, 0x07d6,
+ 0x7688, 0x169c,
+ 0x768b, 0x169d,
+ 0x768e, 0x169e,
+ 0x7690, 0x0877,
+ 0x7693, 0x16a0,
+ 0x7696, 0x169f,
+ 0x7699, 0x16a1,
+ 0x769b, 0x2179,
+ 0x769c, 0x2177,
+ 0x769e, 0x2178,
+ 0x76a6, 0x217a,
+ 0x76ae, 0x0d7d,
+ 0x76b0, 0x16a3,
+ 0x76b4, 0x16a4,
+ 0x76b7, 0x1d1c,
+ 0x76b8, 0x16a5,
+ 0x76bf, 0x087c,
+ 0x76c2, 0x16a8,
+ 0x76c3, 0x0d0c,
+ 0x76c6, 0x0e8d,
+ 0x76c8, 0x04f0,
+ 0x76ca, 0x04f9,
+ 0x76cd, 0x16a9,
+ 0x76d2, 0x16ab,
+ 0x76d6, 0x16aa,
+ 0x76d7, 0x0c6a,
+ 0x76db, 0x0a5d,
+ 0x76dc, 0x14d8,
+ 0x76de, 0x16ac,
+ 0x76df, 0x0ecd,
+ 0x76e1, 0x16ad,
+ 0x76e3, 0x0602,
+ 0x76e4, 0x0d6b,
+ 0x76e5, 0x16ae,
+ 0x76e7, 0x16af,
+ 0x76ea, 0x16b0,
+ 0x76ee, 0x0ee8,
+ 0x76f2, 0x0ee1,
+ 0x76f4, 0x0bda,
+ 0x76f8, 0x0aec,
+ 0x76fb, 0x16b2,
+ 0x76fe, 0x096c,
+ 0x7701, 0x09b2,
+ 0x7704, 0x16b5,
+ 0x7707, 0x16b4,
+ 0x7708, 0x16b3,
+ 0x7709, 0x0d91,
+ 0x770b, 0x0603,
+ 0x770c, 0x075d,
+ 0x771b, 0x16bb,
+ 0x771e, 0x16b8,
+ 0x771f, 0x0a05,
+ 0x7720, 0x0ebe,
+ 0x7724, 0x16b7,
+ 0x7725, 0x16b9,
+ 0x7729, 0x16b6,
+ 0x7737, 0x16bc,
+ 0x773a, 0x0bcb,
+ 0x773c, 0x061f,
+ 0x7740, 0x0ba3,
+ 0x7746, 0x217c,
+ 0x7747, 0x16be,
+ 0x775a, 0x16bf,
+ 0x775b, 0x16c2,
+ 0x7761, 0x0a2d,
+ 0x7762, 0x1ec5,
+ 0x7763, 0x0c9c,
+ 0x7765, 0x16c3,
+ 0x7766, 0x0e81,
+ 0x7768, 0x16c0,
+ 0x776b, 0x16c1,
+ 0x7779, 0x16c6,
+ 0x777e, 0x16c5,
+ 0x777f, 0x16c4,
+ 0x778b, 0x16c8,
+ 0x778e, 0x16c7,
+ 0x7791, 0x16c9,
+ 0x779e, 0x16cb,
+ 0x77a0, 0x16ca,
+ 0x77a5, 0x0e1d,
+ 0x77ac, 0x0960,
+ 0x77ad, 0x0f8e,
+ 0x77b0, 0x16cc,
+ 0x77b3, 0x0c8f,
+ 0x77b6, 0x16cd,
+ 0x77b9, 0x16ce,
+ 0x77bb, 0x16d2,
+ 0x77bc, 0x16d0,
+ 0x77bf, 0x16cf,
+ 0x77c7, 0x16d3,
+ 0x77cd, 0x16d4,
+ 0x77d7, 0x16d5,
+ 0x77da, 0x16d6,
+ 0x77db, 0x0ec3,
+ 0x77dc, 0x16d7,
+ 0x77e2, 0x0efc,
+ 0x77e3, 0x16d8,
+ 0x77e5, 0x0b8c,
+ 0x77e7, 0x0d20,
+ 0x77e9, 0x06e3,
+ 0x77ed, 0x0b79,
+ 0x77ee, 0x16d9,
+ 0x77ef, 0x06b2,
+ 0x77f3, 0x0a74,
+ 0x77fc, 0x16da,
+ 0x7802, 0x082d,
+ 0x780c, 0x16db,
+ 0x7812, 0x16dc,
+ 0x7814, 0x075a,
+ 0x7815, 0x0845,
+ 0x7820, 0x16de,
+ 0x7821, 0x217e,
+ 0x7825, 0x0c50,
+ 0x7826, 0x0846,
+ 0x7827, 0x0668,
+ 0x7832, 0x0e52,
+ 0x7834, 0x0d01,
+ 0x783a, 0x0c51,
+ 0x783f, 0x07ee,
+ 0x7845, 0x16e0,
+ 0x784e, 0x217f,
+ 0x785d, 0x09b3,
+ 0x7864, 0x2180,
+ 0x786b, 0x0f7a,
+ 0x786c, 0x07d7,
+ 0x786f, 0x075b,
+ 0x7872, 0x0d37,
+ 0x7874, 0x16e2,
+ 0x787a, 0x2181,
+ 0x787c, 0x16e4,
+ 0x7881, 0x079f,
+ 0x7886, 0x16e3,
+ 0x7887, 0x0c12,
+ 0x788c, 0x16e6,
+ 0x788d, 0x0595,
+ 0x788e, 0x16e1,
+ 0x7891, 0x0d7e,
+ 0x7893, 0x04d2,
+ 0x7895, 0x085c,
+ 0x7897, 0x0ff8,
+ 0x789a, 0x16e5,
+ 0x78a3, 0x16e7,
+ 0x78a7, 0x0e1b,
+ 0x78a9, 0x0a7d,
+ 0x78aa, 0x16e9,
+ 0x78af, 0x16ea,
+ 0x78b5, 0x16e8,
+ 0x78ba, 0x05ac,
+ 0x78bc, 0x16f0,
+ 0x78be, 0x16ef,
+ 0x78c1, 0x08d3,
+ 0x78c5, 0x16f1,
+ 0x78c6, 0x16ec,
+ 0x78ca, 0x16f2,
+ 0x78cb, 0x16ed,
+ 0x78d0, 0x0d6c,
+ 0x78d1, 0x16eb,
+ 0x78d4, 0x16ee,
+ 0x78da, 0x16f5,
+ 0x78e7, 0x16f4,
+ 0x78e8, 0x0e8f,
+ 0x78ec, 0x16f3,
+ 0x78ef, 0x04af,
+ 0x78f4, 0x16f7,
+ 0x78fd, 0x16f6,
+ 0x7901, 0x09b4,
+ 0x7907, 0x16f8,
+ 0x790e, 0x0ac5,
+ 0x7911, 0x16fa,
+ 0x7912, 0x16f9,
+ 0x7919, 0x16fb,
+ 0x7926, 0x16dd,
+ 0x792a, 0x16df,
+ 0x792b, 0x16fd,
+ 0x792c, 0x16fc,
+ 0x7930, 0x2182,
+ 0x793a, 0x08d4,
+ 0x793c, 0x0fb1,
+ 0x793e, 0x08fe,
+ 0x7940, 0x16fe,
+ 0x7941, 0x070d,
+ 0x7947, 0x065a,
+ 0x7948, 0x0641,
+ 0x7949, 0x08b1,
+ 0x7950, 0x0f1e,
+ 0x7953, 0x1704,
+ 0x7955, 0x1703,
+ 0x7956, 0x0ac6,
+ 0x7957, 0x1700,
+ 0x795a, 0x1702,
+ 0x795d, 0x0955,
+ 0x795e, 0x0a06,
+ 0x795f, 0x1701,
+ 0x7960, 0x16ff,
+ 0x7962, 0x0ce0,
+ 0x7965, 0x09b5,
+ 0x7968, 0x0dae,
+ 0x796d, 0x0847,
+ 0x7977, 0x0c72,
+ 0x797a, 0x1705,
+ 0x797f, 0x1706,
+ 0x7980, 0x171c,
+ 0x7981, 0x06d0,
+ 0x7984, 0x0fe3,
+ 0x7985, 0x0ab7,
+ 0x798a, 0x1707,
+ 0x798d, 0x0552,
+ 0x798e, 0x0c13,
+ 0x798f, 0x0df1,
+ 0x7994, 0x2186,
+ 0x799b, 0x2188,
+ 0x799d, 0x1708,
+ 0x79a6, 0x0694,
+ 0x79a7, 0x1709,
+ 0x79aa, 0x170b,
+ 0x79ae, 0x170c,
+ 0x79b0, 0x0cdf,
+ 0x79b1, 0x1e4e,
+ 0x79b3, 0x170d,
+ 0x79b9, 0x170e,
+ 0x79bd, 0x06d1,
+ 0x79be, 0x0553,
+ 0x79bf, 0x0c9d,
+ 0x79c0, 0x0932,
+ 0x79c1, 0x08b2,
+ 0x79c9, 0x1710,
+ 0x79cb, 0x0933,
+ 0x79d1, 0x054a,
+ 0x79d2, 0x0db5,
+ 0x79d5, 0x1711,
+ 0x79d8, 0x0d7f,
+ 0x79df, 0x0ac7,
+ 0x79e1, 0x1714,
+ 0x79e3, 0x1715,
+ 0x79e4, 0x0d1f,
+ 0x79e6, 0x0a07,
+ 0x79e7, 0x1712,
+ 0x79e9, 0x0b9f,
+ 0x79ec, 0x1713,
+ 0x79f0, 0x09b6,
+ 0x79fb, 0x04a0,
+ 0x7a00, 0x0643,
+ 0x7a08, 0x1716,
+ 0x7a0b, 0x0c14,
+ 0x7a0d, 0x1717,
+ 0x7a0e, 0x0a6b,
+ 0x7a14, 0x0eb9,
+ 0x7a17, 0x0d95,
+ 0x7a18, 0x1718,
+ 0x7a1a, 0x0b93,
+ 0x7a1c, 0x0f8f,
+ 0x7a1f, 0x171b,
+ 0x7a20, 0x171a,
+ 0x7a2e, 0x091b,
+ 0x7a31, 0x171d,
+ 0x7a32, 0x04b4,
+ 0x7a37, 0x1720,
+ 0x7a3b, 0x171e,
+ 0x7a3c, 0x0554,
+ 0x7a3d, 0x0724,
+ 0x7a3e, 0x171f,
+ 0x7a3f, 0x07d8,
+ 0x7a40, 0x0804,
+ 0x7a42, 0x0e36,
+ 0x7a43, 0x1721,
+ 0x7a46, 0x0e82,
+ 0x7a49, 0x1723,
+ 0x7a4d, 0x0a75,
+ 0x7a4e, 0x04f1,
+ 0x7a4f, 0x053a,
+ 0x7a50, 0x0470,
+ 0x7a57, 0x1722,
+ 0x7a61, 0x1724,
+ 0x7a63, 0x09df,
+ 0x7a69, 0x1726,
+ 0x7a6b, 0x05ad,
+ 0x7a70, 0x1728,
+ 0x7a74, 0x0740,
+ 0x7a76, 0x0680,
+ 0x7a79, 0x1729,
+ 0x7a7a, 0x06ed,
+ 0x7a7d, 0x172a,
+ 0x7a7f, 0x0aa0,
+ 0x7a81, 0x0ca5,
+ 0x7a83, 0x0a84,
+ 0x7a84, 0x0865,
+ 0x7a88, 0x172b,
+ 0x7a92, 0x0ba0,
+ 0x7a93, 0x0aed,
+ 0x7a95, 0x172d,
+ 0x7a96, 0x172f,
+ 0x7a97, 0x172c,
+ 0x7a98, 0x172e,
+ 0x7a9f, 0x06f8,
+ 0x7aa9, 0x1730,
+ 0x7aaa, 0x06fc,
+ 0x7aae, 0x0681,
+ 0x7aaf, 0x0f3c,
+ 0x7ab0, 0x1732,
+ 0x7ab6, 0x1733,
+ 0x7aba, 0x04d0,
+ 0x7abf, 0x1736,
+ 0x7ac3, 0x05d4,
+ 0x7ac4, 0x1735,
+ 0x7ac5, 0x1734,
+ 0x7ac7, 0x1738,
+ 0x7ac8, 0x1731,
+ 0x7aca, 0x1739,
+ 0x7acb, 0x0f71,
+ 0x7acd, 0x173a,
+ 0x7acf, 0x173b,
+ 0x7ad1, 0x2189,
+ 0x7ad2, 0x11c5,
+ 0x7ad3, 0x173d,
+ 0x7ad5, 0x173c,
+ 0x7ad9, 0x173e,
+ 0x7adc, 0x0f7d,
+ 0x7add, 0x1740,
+ 0x7adf, 0x1c08,
+ 0x7ae0, 0x09b7,
+ 0x7ae1, 0x1741,
+ 0x7ae3, 0x0961,
+ 0x7ae5, 0x0c90,
+ 0x7ae6, 0x1743,
+ 0x7ae7, 0x218a,
+ 0x7aea, 0x0b66,
+ 0x7aeb, 0x218c,
+ 0x7aed, 0x1744,
+ 0x7aef, 0x0b7a,
+ 0x7af0, 0x1745,
+ 0x7af6, 0x069d,
+ 0x7af8, 0x1076,
+ 0x7af9, 0x0b9b,
+ 0x7afa, 0x08df,
+ 0x7aff, 0x0604,
+ 0x7b02, 0x1746,
+ 0x7b04, 0x1753,
+ 0x7b06, 0x1749,
+ 0x7b08, 0x0682,
+ 0x7b0a, 0x1748,
+ 0x7b0b, 0x1755,
+ 0x7b0f, 0x1747,
+ 0x7b11, 0x09b8,
+ 0x7b18, 0x174b,
+ 0x7b1b, 0x0c25,
+ 0x7b1e, 0x174d,
+ 0x7b20, 0x05bc,
+ 0x7b25, 0x0a20,
+ 0x7b26, 0x0dd6,
+ 0x7b28, 0x174f,
+ 0x7b2c, 0x0b48,
+ 0x7b33, 0x174a,
+ 0x7b35, 0x174e,
+ 0x7b36, 0x1750,
+ 0x7b39, 0x086b,
+ 0x7b45, 0x1757,
+ 0x7b46, 0x0da0,
+ 0x7b48, 0x0d3a,
+ 0x7b49, 0x0c73,
+ 0x7b4b, 0x06d2,
+ 0x7b4c, 0x1756,
+ 0x7b4d, 0x1754,
+ 0x7b4f, 0x0d49,
+ 0x7b50, 0x1751,
+ 0x7b51, 0x0b9c,
+ 0x7b52, 0x0c75,
+ 0x7b54, 0x0c74,
+ 0x7b56, 0x0866,
+ 0x7b5d, 0x1769,
+ 0x7b65, 0x1759,
+ 0x7b67, 0x175b,
+ 0x7b6c, 0x175e,
+ 0x7b6e, 0x175f,
+ 0x7b70, 0x175c,
+ 0x7b74, 0x175a,
+ 0x7b75, 0x1758,
+ 0x7b7a, 0x1752,
+ 0x7b86, 0x0e1f,
+ 0x7b87, 0x0555,
+ 0x7b8b, 0x1766,
+ 0x7b8d, 0x1763,
+ 0x7b8f, 0x1768,
+ 0x7b92, 0x1767,
+ 0x7b94, 0x0d29,
+ 0x7b95, 0x0eb3,
+ 0x7b97, 0x0889,
+ 0x7b98, 0x1761,
+ 0x7b99, 0x176a,
+ 0x7b9a, 0x1765,
+ 0x7b9c, 0x1764,
+ 0x7b9d, 0x1760,
+ 0x7b9e, 0x218d,
+ 0x7b9f, 0x1762,
+ 0x7ba1, 0x0605,
+ 0x7baa, 0x0b7b,
+ 0x7bad, 0x0aa1,
+ 0x7bb1, 0x0d36,
+ 0x7bb4, 0x176f,
+ 0x7bb8, 0x0d38,
+ 0x7bc0, 0x0a85,
+ 0x7bc1, 0x176c,
+ 0x7bc4, 0x0d63,
+ 0x7bc6, 0x1770,
+ 0x7bc7, 0x0e23,
+ 0x7bc9, 0x0b99,
+ 0x7bcb, 0x176b,
+ 0x7bcc, 0x176d,
+ 0x7bcf, 0x176e,
+ 0x7bdd, 0x1771,
+ 0x7be0, 0x08f0,
+ 0x7be4, 0x0c9e,
+ 0x7be5, 0x1776,
+ 0x7be6, 0x1775,
+ 0x7be9, 0x1772,
+ 0x7bed, 0x0fdc,
+ 0x7bf3, 0x177b,
+ 0x7bf6, 0x177f,
+ 0x7bf7, 0x177c,
+ 0x7c00, 0x1778,
+ 0x7c07, 0x1779,
+ 0x7c0d, 0x177e,
+ 0x7c11, 0x1773,
+ 0x7c12, 0x10ea,
+ 0x7c13, 0x177a,
+ 0x7c14, 0x1774,
+ 0x7c17, 0x177d,
+ 0x7c1e, 0x1e3b,
+ 0x7c1f, 0x1783,
+ 0x7c21, 0x0606,
+ 0x7c23, 0x1780,
+ 0x7c27, 0x1781,
+ 0x7c2a, 0x1782,
+ 0x7c2b, 0x1785,
+ 0x7c37, 0x1784,
+ 0x7c38, 0x0d8a,
+ 0x7c3d, 0x1786,
+ 0x7c3e, 0x0fc4,
+ 0x7c3f, 0x0e3d,
+ 0x7c40, 0x178b,
+ 0x7c43, 0x1788,
+ 0x7c4c, 0x1787,
+ 0x7c4d, 0x0a76,
+ 0x7c4f, 0x178a,
+ 0x7c50, 0x178c,
+ 0x7c54, 0x1789,
+ 0x7c56, 0x1790,
+ 0x7c58, 0x178d,
+ 0x7c5f, 0x178e,
+ 0x7c60, 0x1777,
+ 0x7c64, 0x178f,
+ 0x7c65, 0x1791,
+ 0x7c6c, 0x1792,
+ 0x7c73, 0x0e16,
+ 0x7c75, 0x1793,
+ 0x7c7e, 0x0eee,
+ 0x7c81, 0x06c6,
+ 0x7c82, 0x06ff,
+ 0x7c83, 0x1794,
+ 0x7c89, 0x0e04,
+ 0x7c8b, 0x0a2e,
+ 0x7c8d, 0x0ebc,
+ 0x7c90, 0x1795,
+ 0x7c92, 0x0f7b,
+ 0x7c95, 0x0d2a,
+ 0x7c97, 0x0ac8,
+ 0x7c98, 0x0cea,
+ 0x7c9b, 0x0957,
+ 0x7c9f, 0x0484,
+ 0x7ca1, 0x179a,
+ 0x7ca2, 0x1798,
+ 0x7ca4, 0x1796,
+ 0x7ca5, 0x05dd,
+ 0x7ca7, 0x09b9,
+ 0x7ca8, 0x179b,
+ 0x7cab, 0x1799,
+ 0x7cad, 0x1797,
+ 0x7cae, 0x179f,
+ 0x7cb1, 0x179e,
+ 0x7cb2, 0x179d,
+ 0x7cb3, 0x179c,
+ 0x7cb9, 0x17a0,
+ 0x7cbd, 0x17a1,
+ 0x7cbe, 0x0a5e,
+ 0x7cc0, 0x17a2,
+ 0x7cc2, 0x17a4,
+ 0x7cc5, 0x17a3,
+ 0x7cca, 0x0786,
+ 0x7cce, 0x0aba,
+ 0x7cd2, 0x17a6,
+ 0x7cd6, 0x0c76,
+ 0x7cd8, 0x17a5,
+ 0x7cdc, 0x17a7,
+ 0x7cde, 0x0e05,
+ 0x7cdf, 0x0aee,
+ 0x7ce0, 0x07d9,
+ 0x7ce2, 0x17a8,
+ 0x7ce7, 0x0f90,
+ 0x7cef, 0x17aa,
+ 0x7cf2, 0x17ab,
+ 0x7cf4, 0x17ac,
+ 0x7cf6, 0x17ad,
+ 0x7cf8, 0x08b3,
+ 0x7cfa, 0x17ae,
+ 0x7cfb, 0x0725,
+ 0x7cfe, 0x0684,
+ 0x7d00, 0x0644,
+ 0x7d02, 0x17b0,
+ 0x7d04, 0x0eff,
+ 0x7d05, 0x07da,
+ 0x7d06, 0x17af,
+ 0x7d0a, 0x17b3,
+ 0x7d0b, 0x0ef2,
+ 0x7d0d, 0x0cf2,
+ 0x7d10, 0x0da5,
+ 0x7d14, 0x096d,
+ 0x7d15, 0x17b2,
+ 0x7d17, 0x08ff,
+ 0x7d18, 0x07db,
+ 0x7d19, 0x08b4,
+ 0x7d1a, 0x0683,
+ 0x7d1b, 0x0e06,
+ 0x7d1c, 0x17b1,
+ 0x7d20, 0x0ac9,
+ 0x7d21, 0x0e70,
+ 0x7d22, 0x0867,
+ 0x7d2b, 0x08b5,
+ 0x7d2c, 0x0bf9,
+ 0x7d2e, 0x17b6,
+ 0x7d2f, 0x0fa7,
+ 0x7d30, 0x0849,
+ 0x7d32, 0x17b7,
+ 0x7d33, 0x0a08,
+ 0x7d35, 0x17b9,
+ 0x7d39, 0x09ba,
+ 0x7d3a, 0x0820,
+ 0x7d3f, 0x17b8,
+ 0x7d42, 0x0934,
+ 0x7d43, 0x0772,
+ 0x7d44, 0x0aca,
+ 0x7d45, 0x17b4,
+ 0x7d46, 0x17ba,
+ 0x7d48, 0x218f,
+ 0x7d4b, 0x17b5,
+ 0x7d4c, 0x0726,
+ 0x7d4e, 0x17bd,
+ 0x7d4f, 0x17c1,
+ 0x7d50, 0x0741,
+ 0x7d56, 0x17bc,
+ 0x7d5b, 0x17c5,
+ 0x7d5c, 0x2190,
+ 0x7d5e, 0x07dc,
+ 0x7d61, 0x0f57,
+ 0x7d62, 0x0480,
+ 0x7d63, 0x17c2,
+ 0x7d66, 0x0685,
+ 0x7d68, 0x17bf,
+ 0x7d6e, 0x17c0,
+ 0x7d71, 0x0c77,
+ 0x7d72, 0x17be,
+ 0x7d73, 0x17bb,
+ 0x7d75, 0x0586,
+ 0x7d76, 0x0a88,
+ 0x7d79, 0x075c,
+ 0x7d7d, 0x17c7,
+ 0x7d89, 0x17c4,
+ 0x7d8f, 0x17c6,
+ 0x7d93, 0x17c3,
+ 0x7d99, 0x0727,
+ 0x7d9a, 0x0b13,
+ 0x7d9b, 0x17c8,
+ 0x7d9c, 0x0af0,
+ 0x7d9f, 0x17d5,
+ 0x7da0, 0x2192,
+ 0x7da2, 0x17d1,
+ 0x7da3, 0x17cb,
+ 0x7dab, 0x17cf,
+ 0x7dac, 0x0926,
+ 0x7dad, 0x04a1,
+ 0x7dae, 0x17ca,
+ 0x7daf, 0x17d2,
+ 0x7db0, 0x17d6,
+ 0x7db1, 0x07dd,
+ 0x7db2, 0x0ee2,
+ 0x7db4, 0x0bf2,
+ 0x7db5, 0x17cc,
+ 0x7db7, 0x2191,
+ 0x7db8, 0x17d4,
+ 0x7dba, 0x17c9,
+ 0x7dbb, 0x0b7c,
+ 0x7dbd, 0x17ce,
+ 0x7dbe, 0x0481,
+ 0x7dbf, 0x0ed6,
+ 0x7dc7, 0x17cd,
+ 0x7dca, 0x06d3,
+ 0x7dcb, 0x0d80,
+ 0x7dcf, 0x0aef,
+ 0x7dd1, 0x0f98,
+ 0x7dd2, 0x0979,
+ 0x7dd5, 0x17fd,
+ 0x7dd6, 0x2193,
+ 0x7dd8, 0x17d7,
+ 0x7dda, 0x0aa2,
+ 0x7ddc, 0x17d3,
+ 0x7ddd, 0x17d8,
+ 0x7dde, 0x17da,
+ 0x7de0, 0x0c15,
+ 0x7de1, 0x17dd,
+ 0x7de4, 0x17d9,
+ 0x7de8, 0x0e24,
+ 0x7de9, 0x0607,
+ 0x7dec, 0x0ed7,
+ 0x7def, 0x04a2,
+ 0x7df2, 0x17dc,
+ 0x7df4, 0x0fc5,
+ 0x7dfb, 0x17db,
+ 0x7e01, 0x0511,
+ 0x7e04, 0x0cc4,
+ 0x7e05, 0x17de,
+ 0x7e09, 0x17e5,
+ 0x7e0a, 0x17df,
+ 0x7e0b, 0x17e6,
+ 0x7e12, 0x17e2,
+ 0x7e1b, 0x0d31,
+ 0x7e1e, 0x08f6,
+ 0x7e1f, 0x17e4,
+ 0x7e21, 0x17e1,
+ 0x7e22, 0x17e7,
+ 0x7e23, 0x17e0,
+ 0x7e26, 0x094e,
+ 0x7e2b, 0x0e53,
+ 0x7e2e, 0x0956,
+ 0x7e31, 0x17e3,
+ 0x7e32, 0x17ef,
+ 0x7e35, 0x17eb,
+ 0x7e37, 0x17ee,
+ 0x7e39, 0x17ec,
+ 0x7e3a, 0x17f0,
+ 0x7e3b, 0x17ea,
+ 0x7e3d, 0x17d0,
+ 0x7e3e, 0x0a77,
+ 0x7e41, 0x0d5f,
+ 0x7e43, 0x17ed,
+ 0x7e46, 0x17e8,
+ 0x7e4a, 0x0aa3,
+ 0x7e4b, 0x0728,
+ 0x7e4d, 0x0935,
+ 0x7e52, 0x2194,
+ 0x7e54, 0x09eb,
+ 0x7e55, 0x0ab8,
+ 0x7e56, 0x17f3,
+ 0x7e59, 0x17f5,
+ 0x7e5d, 0x17f2,
+ 0x7e5e, 0x17f4,
+ 0x7e61, 0x1e11,
+ 0x7e66, 0x17e9,
+ 0x7e67, 0x17f1,
+ 0x7e69, 0x17f9,
+ 0x7e6a, 0x17f8,
+ 0x7e6b, 0x1df7,
+ 0x7e6d, 0x0ea8,
+ 0x7e70, 0x0701,
+ 0x7e79, 0x17f7,
+ 0x7e7b, 0x17fb,
+ 0x7e7c, 0x17fa,
+ 0x7e7d, 0x17fe,
+ 0x7e7f, 0x1800,
+ 0x7e82, 0x088a,
+ 0x7e83, 0x17fc,
+ 0x7e88, 0x1801,
+ 0x7e8a, 0x20a7,
+ 0x7e8c, 0x1803,
+ 0x7e8e, 0x1809,
+ 0x7e8f, 0x0c35,
+ 0x7e90, 0x1805,
+ 0x7e92, 0x1804,
+ 0x7e93, 0x1806,
+ 0x7e96, 0x1808,
+ 0x7e9b, 0x180a,
+ 0x7f36, 0x0608,
+ 0x7f38, 0x180c,
+ 0x7f3a, 0x180d,
+ 0x7f45, 0x180e,
+ 0x7f47, 0x2195,
+ 0x7f4c, 0x180f,
+ 0x7f50, 0x1812,
+ 0x7f54, 0x1815,
+ 0x7f55, 0x1814,
+ 0x7f58, 0x1816,
+ 0x7f5f, 0x1817,
+ 0x7f67, 0x181b,
+ 0x7f68, 0x1819,
+ 0x7f6a, 0x0851,
+ 0x7f6b, 0x0729,
+ 0x7f6e, 0x0b94,
+ 0x7f70, 0x0d47,
+ 0x7f72, 0x097a,
+ 0x7f75, 0x0d03,
+ 0x7f77, 0x0d81,
+ 0x7f78, 0x181c,
+ 0x7f79, 0x1336,
+ 0x7f82, 0x181d,
+ 0x7f83, 0x181f,
+ 0x7f85, 0x0f4f,
+ 0x7f86, 0x181e,
+ 0x7f87, 0x1821,
+ 0x7f88, 0x1820,
+ 0x7f8a, 0x0f3d,
+ 0x7f8c, 0x1822,
+ 0x7f8e, 0x0d92,
+ 0x7f94, 0x1823,
+ 0x7f9a, 0x1826,
+ 0x7f9d, 0x1825,
+ 0x7f9e, 0x1824,
+ 0x7fa1, 0x2196,
+ 0x7fa3, 0x1827,
+ 0x7fa4, 0x0708,
+ 0x7fa8, 0x0aa4,
+ 0x7fa9, 0x065b,
+ 0x7fae, 0x182b,
+ 0x7faf, 0x1828,
+ 0x7fb2, 0x1829,
+ 0x7fb6, 0x182c,
+ 0x7fb8, 0x182d,
+ 0x7fb9, 0x182a,
+ 0x7fbd, 0x04cb,
+ 0x7fc1, 0x0527,
+ 0x7fc5, 0x182f,
+ 0x7fca, 0x1831,
+ 0x7fcc, 0x0f4c,
+ 0x7fd2, 0x0936,
+ 0x7fd4, 0x1833,
+ 0x7fd5, 0x1832,
+ 0x7fe0, 0x0a2f,
+ 0x7fe1, 0x1834,
+ 0x7fe6, 0x1835,
+ 0x7fe9, 0x1836,
+ 0x7feb, 0x0621,
+ 0x7ff0, 0x0609,
+ 0x7ff3, 0x1837,
+ 0x7ff9, 0x1838,
+ 0x7ffb, 0x0e8b,
+ 0x7ffc, 0x0f4d,
+ 0x8000, 0x0f3e,
+ 0x8001, 0x0fdd,
+ 0x8003, 0x07df,
+ 0x8004, 0x183b,
+ 0x8005, 0x0900,
+ 0x8006, 0x183a,
+ 0x800b, 0x183c,
+ 0x800c, 0x08d5,
+ 0x8010, 0x0b31,
+ 0x8012, 0x183d,
+ 0x8015, 0x07de,
+ 0x8017, 0x0ee3,
+ 0x8018, 0x183e,
+ 0x801c, 0x1840,
+ 0x8021, 0x1841,
+ 0x8028, 0x1842,
+ 0x8033, 0x08d6,
+ 0x8036, 0x0ef9,
+ 0x803b, 0x1844,
+ 0x803d, 0x0b7d,
+ 0x803f, 0x1843,
+ 0x8046, 0x1846,
+ 0x804a, 0x1845,
+ 0x8052, 0x1847,
+ 0x8056, 0x0a5f,
+ 0x8058, 0x1848,
+ 0x805a, 0x1849,
+ 0x805e, 0x0e09,
+ 0x805f, 0x184a,
+ 0x8061, 0x0af1,
+ 0x8062, 0x184b,
+ 0x8068, 0x184c,
+ 0x806f, 0x0fc6,
+ 0x8070, 0x184f,
+ 0x8072, 0x184e,
+ 0x8073, 0x184d,
+ 0x8074, 0x0bcc,
+ 0x8076, 0x1850,
+ 0x8077, 0x09ec,
+ 0x8079, 0x1851,
+ 0x807d, 0x1852,
+ 0x807e, 0x0fde,
+ 0x807f, 0x1853,
+ 0x8084, 0x1854,
+ 0x8085, 0x1856,
+ 0x8086, 0x1855,
+ 0x8087, 0x0d39,
+ 0x8089, 0x0cd1,
+ 0x808b, 0x0fe4,
+ 0x808c, 0x0d3d,
+ 0x8093, 0x1858,
+ 0x8096, 0x09bb,
+ 0x8098, 0x0d9c,
+ 0x809a, 0x1859,
+ 0x809b, 0x1857,
+ 0x809d, 0x060a,
+ 0x80a1, 0x0788,
+ 0x80a2, 0x08b6,
+ 0x80a5, 0x0d82,
+ 0x80a9, 0x075e,
+ 0x80aa, 0x0e71,
+ 0x80ac, 0x185c,
+ 0x80ad, 0x185a,
+ 0x80af, 0x07e0,
+ 0x80b1, 0x07e1,
+ 0x80b2, 0x04ad,
+ 0x80b4, 0x0858,
+ 0x80ba, 0x0d0f,
+ 0x80c3, 0x04a3,
+ 0x80c4, 0x1861,
+ 0x80c6, 0x0b7e,
+ 0x80cc, 0x0d0e,
+ 0x80ce, 0x0b3b,
+ 0x80d6, 0x1863,
+ 0x80d9, 0x185f,
+ 0x80da, 0x1862,
+ 0x80db, 0x185d,
+ 0x80dd, 0x1860,
+ 0x80de, 0x0e54,
+ 0x80e1, 0x0789,
+ 0x80e4, 0x04c1,
+ 0x80e5, 0x185e,
+ 0x80ef, 0x1865,
+ 0x80f1, 0x1866,
+ 0x80f4, 0x0c91,
+ 0x80f8, 0x06b3,
+ 0x80fc, 0x1871,
+ 0x80fd, 0x0cf3,
+ 0x8102, 0x08b7,
+ 0x8105, 0x06b4,
+ 0x8106, 0x0a6c,
+ 0x8107, 0x0fec,
+ 0x8108, 0x0eba,
+ 0x8109, 0x1864,
+ 0x810a, 0x0a78,
+ 0x811a, 0x066d,
+ 0x811b, 0x1867,
+ 0x8123, 0x1869,
+ 0x8129, 0x1868,
+ 0x812f, 0x186a,
+ 0x8131, 0x0b64,
+ 0x8133, 0x0cf4,
+ 0x8139, 0x0bcd,
+ 0x813e, 0x186e,
+ 0x8146, 0x186d,
+ 0x814b, 0x186b,
+ 0x814e, 0x0a1b,
+ 0x8150, 0x0dd7,
+ 0x8151, 0x1870,
+ 0x8153, 0x186f,
+ 0x8154, 0x07e2,
+ 0x8155, 0x0ff9,
+ 0x815f, 0x1880,
+ 0x8165, 0x1874,
+ 0x816b, 0x091c,
+ 0x816e, 0x1873,
+ 0x8170, 0x080a,
+ 0x8171, 0x1872,
+ 0x8174, 0x1876,
+ 0x8178, 0x0bce,
+ 0x8179, 0x0df2,
+ 0x817a, 0x0aa5,
+ 0x817f, 0x0b3c,
+ 0x8180, 0x187a,
+ 0x8182, 0x187b,
+ 0x8183, 0x1877,
+ 0x8188, 0x1878,
+ 0x818a, 0x1879,
+ 0x818f, 0x07e3,
+ 0x8193, 0x1881,
+ 0x8195, 0x187d,
+ 0x819a, 0x0dd8,
+ 0x819c, 0x0e9a,
+ 0x819d, 0x0d9a,
+ 0x81a0, 0x187c,
+ 0x81a3, 0x187f,
+ 0x81a4, 0x187e,
+ 0x81a8, 0x0e72,
+ 0x81a9, 0x1882,
+ 0x81b0, 0x1883,
+ 0x81b3, 0x0ab9,
+ 0x81b5, 0x1884,
+ 0x81b8, 0x1886,
+ 0x81ba, 0x188a,
+ 0x81bd, 0x1887,
+ 0x81be, 0x1885,
+ 0x81bf, 0x0cf5,
+ 0x81c0, 0x1888,
+ 0x81c2, 0x1889,
+ 0x81c6, 0x0532,
+ 0x81c8, 0x1890,
+ 0x81c9, 0x188b,
+ 0x81cd, 0x188c,
+ 0x81d1, 0x188d,
+ 0x81d3, 0x0b01,
+ 0x81d8, 0x188f,
+ 0x81d9, 0x188e,
+ 0x81da, 0x1891,
+ 0x81df, 0x1892,
+ 0x81e3, 0x0a09,
+ 0x81e5, 0x0569,
+ 0x81e7, 0x1894,
+ 0x81e8, 0x0f9f,
+ 0x81ea, 0x08d7,
+ 0x81ed, 0x0937,
+ 0x81f3, 0x08b8,
+ 0x81f4, 0x0b95,
+ 0x81fa, 0x1895,
+ 0x81fc, 0x04d3,
+ 0x81fe, 0x1897,
+ 0x8201, 0x1898,
+ 0x8205, 0x189a,
+ 0x8207, 0x189b,
+ 0x8208, 0x06b5,
+ 0x8209, 0x13af,
+ 0x820a, 0x189c,
+ 0x820c, 0x0a89,
+ 0x820d, 0x189d,
+ 0x820e, 0x08f7,
+ 0x8210, 0x189e,
+ 0x8212, 0x1009,
+ 0x8216, 0x189f,
+ 0x8217, 0x0e2e,
+ 0x8218, 0x0618,
+ 0x821b, 0x0aa6,
+ 0x821c, 0x0962,
+ 0x821e, 0x0de3,
+ 0x821f, 0x0938,
+ 0x8229, 0x18a0,
+ 0x822a, 0x07e4,
+ 0x822b, 0x18a1,
+ 0x822c, 0x0d60,
+ 0x822e, 0x18af,
+ 0x8233, 0x18a3,
+ 0x8235, 0x0b29,
+ 0x8236, 0x0d2b,
+ 0x8237, 0x0773,
+ 0x8238, 0x18a2,
+ 0x8239, 0x0aa7,
+ 0x8240, 0x18a4,
+ 0x8247, 0x0c16,
+ 0x8258, 0x18a6,
+ 0x8259, 0x18a5,
+ 0x825a, 0x18a8,
+ 0x825d, 0x18a7,
+ 0x825f, 0x18a9,
+ 0x8262, 0x18ab,
+ 0x8264, 0x18aa,
+ 0x8266, 0x060b,
+ 0x8268, 0x18ac,
+ 0x826a, 0x18ad,
+ 0x826e, 0x0821,
+ 0x826f, 0x0f91,
+ 0x8271, 0x18b0,
+ 0x8272, 0x09ed,
+ 0x8276, 0x0512,
+ 0x8277, 0x18b1,
+ 0x827e, 0x18b3,
+ 0x828b, 0x04b6,
+ 0x828d, 0x18b4,
+ 0x8292, 0x18b5,
+ 0x8299, 0x0dd9,
+ 0x829d, 0x08f3,
+ 0x829f, 0x18b7,
+ 0x82a5, 0x0587,
+ 0x82a6, 0x0476,
+ 0x82ab, 0x18b6,
+ 0x82ac, 0x18b9,
+ 0x82ad, 0x0d04,
+ 0x82af, 0x0a0a,
+ 0x82b1, 0x0556,
+ 0x82b3, 0x0e55,
+ 0x82b8, 0x0733,
+ 0x82b9, 0x06d4,
+ 0x82bb, 0x18b8,
+ 0x82bd, 0x056a,
+ 0x82c5, 0x05df,
+ 0x82d1, 0x0513,
+ 0x82d2, 0x18bd,
+ 0x82d3, 0x0fb2,
+ 0x82d4, 0x0b3d,
+ 0x82d7, 0x0db6,
+ 0x82d9, 0x18c9,
+ 0x82db, 0x0557,
+ 0x82dc, 0x18c7,
+ 0x82de, 0x18c5,
+ 0x82df, 0x18bc,
+ 0x82e1, 0x18ba,
+ 0x82e3, 0x18bb,
+ 0x82e5, 0x090f,
+ 0x82e6, 0x06e4,
+ 0x82e7, 0x0bb5,
+ 0x82eb, 0x0ca9,
+ 0x82f1, 0x04f3,
+ 0x82f3, 0x18bf,
+ 0x82f4, 0x18be,
+ 0x82f9, 0x18c4,
+ 0x82fa, 0x18c0,
+ 0x82fb, 0x18c3,
+ 0x8301, 0x2198,
+ 0x8302, 0x0edc,
+ 0x8303, 0x18c2,
+ 0x8304, 0x0558,
+ 0x8305, 0x05db,
+ 0x8306, 0x18c6,
+ 0x8309, 0x18c8,
+ 0x830e, 0x072a,
+ 0x8316, 0x18cc,
+ 0x8317, 0x18d5,
+ 0x831c, 0x046f,
+ 0x8323, 0x18dd,
+ 0x8328, 0x04b5,
+ 0x832b, 0x18d4,
+ 0x832f, 0x18d3,
+ 0x8331, 0x18ce,
+ 0x8332, 0x18cd,
+ 0x8334, 0x18cb,
+ 0x8335, 0x18ca,
+ 0x8336, 0x0ba1,
+ 0x8338, 0x0b5b,
+ 0x8339, 0x18d0,
+ 0x8340, 0x18cf,
+ 0x8345, 0x18d2,
+ 0x8349, 0x0af2,
+ 0x834a, 0x072b,
+ 0x834f, 0x04e3,
+ 0x8350, 0x18d1,
+ 0x8352, 0x07e5,
+ 0x8358, 0x0af3,
+ 0x8362, 0x2199,
+ 0x8373, 0x18e3,
+ 0x8375, 0x18e4,
+ 0x8377, 0x0559,
+ 0x837b, 0x052e,
+ 0x837c, 0x18e1,
+ 0x837f, 0x219a,
+ 0x8385, 0x18d7,
+ 0x8387, 0x18df,
+ 0x8389, 0x18e6,
+ 0x838a, 0x18e0,
+ 0x838e, 0x18de,
+ 0x8393, 0x18c1,
+ 0x8396, 0x18dc,
+ 0x839a, 0x18d8,
+ 0x839e, 0x060c,
+ 0x839f, 0x18da,
+ 0x83a0, 0x18e5,
+ 0x83a2, 0x18db,
+ 0x83a8, 0x18e7,
+ 0x83aa, 0x18d9,
+ 0x83ab, 0x0d32,
+ 0x83b1, 0x0f53,
+ 0x83b5, 0x18e2,
+ 0x83bd, 0x18f8,
+ 0x83c1, 0x18f0,
+ 0x83c5, 0x0a41,
+ 0x83c7, 0x219b,
+ 0x83ca, 0x0660,
+ 0x83cc, 0x06d5,
+ 0x83ce, 0x18eb,
+ 0x83d3, 0x055b,
+ 0x83d6, 0x09bc,
+ 0x83d8, 0x18ee,
+ 0x83dc, 0x084a,
+ 0x83df, 0x0c4b,
+ 0x83e0, 0x18f3,
+ 0x83e9, 0x0e3e,
+ 0x83eb, 0x18ea,
+ 0x83ef, 0x055a,
+ 0x83f0, 0x078a,
+ 0x83f1, 0x0d9b,
+ 0x83f2, 0x18f4,
+ 0x83f4, 0x18e8,
+ 0x83f6, 0x219c,
+ 0x83f7, 0x18f1,
+ 0x83fb, 0x18fb,
+ 0x83fd, 0x18ec,
+ 0x8403, 0x18ed,
+ 0x8404, 0x0c92,
+ 0x8407, 0x18f2,
+ 0x840a, 0x1e7f,
+ 0x840b, 0x18ef,
+ 0x840c, 0x0e56,
+ 0x840d, 0x18f5,
+ 0x840e, 0x04a4,
+ 0x8413, 0x18e9,
+ 0x8420, 0x18f7,
+ 0x8422, 0x18f6,
+ 0x8429, 0x0d21,
+ 0x842a, 0x18fd,
+ 0x842c, 0x1908,
+ 0x8431, 0x05dc,
+ 0x8435, 0x190b,
+ 0x8438, 0x18f9,
+ 0x843c, 0x18fe,
+ 0x843d, 0x0f58,
+ 0x8446, 0x1907,
+ 0x8448, 0x219d,
+ 0x8449, 0x0f3f,
+ 0x844e, 0x0f72,
+ 0x8457, 0x0bb6,
+ 0x845b, 0x05c9,
+ 0x8461, 0x0de4,
+ 0x8462, 0x190d,
+ 0x8463, 0x0c79,
+ 0x8466, 0x0475,
+ 0x8469, 0x1906,
+ 0x846b, 0x1902,
+ 0x846c, 0x0af4,
+ 0x846d, 0x18fc,
+ 0x846e, 0x1904,
+ 0x846f, 0x1909,
+ 0x8471, 0x0ce2,
+ 0x8475, 0x046e,
+ 0x8477, 0x1901,
+ 0x8479, 0x190a,
+ 0x847a, 0x0dea,
+ 0x8482, 0x1905,
+ 0x8484, 0x1900,
+ 0x848b, 0x09bd,
+ 0x8490, 0x0939,
+ 0x8494, 0x08d8,
+ 0x8499, 0x0ee4,
+ 0x849c, 0x0db9,
+ 0x849f, 0x1910,
+ 0x84a1, 0x1919,
+ 0x84ad, 0x1903,
+ 0x84b2, 0x05d5,
+ 0x84b4, 0x219e,
+ 0x84b8, 0x09e0,
+ 0x84b9, 0x190e,
+ 0x84bb, 0x1913,
+ 0x84bc, 0x0af5,
+ 0x84bf, 0x190f,
+ 0x84c1, 0x1916,
+ 0x84c4, 0x0b9d,
+ 0x84c6, 0x1917,
+ 0x84c9, 0x0f40,
+ 0x84ca, 0x190c,
+ 0x84cb, 0x0596,
+ 0x84cd, 0x1912,
+ 0x84d0, 0x1915,
+ 0x84d1, 0x0eb8,
+ 0x84d6, 0x1918,
+ 0x84d9, 0x1911,
+ 0x84da, 0x1914,
+ 0x84dc, 0x20ab,
+ 0x84ec, 0x0e57,
+ 0x84ee, 0x0fc7,
+ 0x84f4, 0x191c,
+ 0x84fc, 0x1923,
+ 0x84ff, 0x191b,
+ 0x8500, 0x08ef,
+ 0x8506, 0x18fa,
+ 0x8511, 0x0e1e,
+ 0x8513, 0x0eae,
+ 0x8514, 0x1922,
+ 0x8515, 0x1921,
+ 0x8517, 0x191d,
+ 0x851a, 0x04d8,
+ 0x851f, 0x1920,
+ 0x8521, 0x191a,
+ 0x8523, 0x1e1a,
+ 0x8526, 0x0bf1,
+ 0x852c, 0x191f,
+ 0x852d, 0x04c2,
+ 0x8535, 0x0b02,
+ 0x853d, 0x0e13,
+ 0x853e, 0x1eb5,
+ 0x8540, 0x1924,
+ 0x8541, 0x1928,
+ 0x8543, 0x0d6d,
+ 0x8548, 0x1927,
+ 0x8549, 0x09be,
+ 0x854a, 0x08f5,
+ 0x854b, 0x192a,
+ 0x854e, 0x06b6,
+ 0x8553, 0x219f,
+ 0x8555, 0x192b,
+ 0x8557, 0x0deb,
+ 0x8558, 0x1926,
+ 0x8559, 0x21a0,
+ 0x855a, 0x18ff,
+ 0x8563, 0x1925,
+ 0x8568, 0x0ff5,
+ 0x8569, 0x0c7a,
+ 0x856a, 0x0de5,
+ 0x856b, 0x21a1,
+ 0x856d, 0x1932,
+ 0x8577, 0x1938,
+ 0x857e, 0x1939,
+ 0x8580, 0x192c,
+ 0x8584, 0x0d2c,
+ 0x8587, 0x1936,
+ 0x8588, 0x192e,
+ 0x858a, 0x1930,
+ 0x8590, 0x193a,
+ 0x8591, 0x192f,
+ 0x8594, 0x1933,
+ 0x8597, 0x0514,
+ 0x8599, 0x0cbd,
+ 0x859b, 0x1934,
+ 0x859c, 0x1937,
+ 0x85a4, 0x192d,
+ 0x85a6, 0x0aa8,
+ 0x85a8, 0x1931,
+ 0x85a9, 0x0875,
+ 0x85aa, 0x0a0b,
+ 0x85ab, 0x0706,
+ 0x85ac, 0x0f00,
+ 0x85ae, 0x0f05,
+ 0x85af, 0x097c,
+ 0x85b0, 0x21a3,
+ 0x85b9, 0x193e,
+ 0x85ba, 0x193c,
+ 0x85c1, 0x0ff4,
+ 0x85c9, 0x193b,
+ 0x85cd, 0x0f5f,
+ 0x85cf, 0x193d,
+ 0x85d0, 0x193f,
+ 0x85d5, 0x1940,
+ 0x85dc, 0x1943,
+ 0x85dd, 0x1941,
+ 0x85e4, 0x0c7b,
+ 0x85e5, 0x1942,
+ 0x85e9, 0x0d61,
+ 0x85ea, 0x1935,
+ 0x85f7, 0x097d,
+ 0x85f9, 0x1944,
+ 0x85fa, 0x1949,
+ 0x85fb, 0x0af6,
+ 0x85fe, 0x1948,
+ 0x8602, 0x1929,
+ 0x8606, 0x194a,
+ 0x8607, 0x0acb,
+ 0x860a, 0x1945,
+ 0x860b, 0x1947,
+ 0x8613, 0x1946,
+ 0x8616, 0x14d0,
+ 0x8617, 0x14c1,
+ 0x861a, 0x194c,
+ 0x8622, 0x194b,
+ 0x862d, 0x0f60,
+ 0x862f, 0x16b1,
+ 0x8630, 0x194d,
+ 0x863f, 0x194e,
+ 0x864d, 0x194f,
+ 0x864e, 0x078b,
+ 0x8650, 0x066e,
+ 0x8654, 0x1951,
+ 0x8655, 0x1094,
+ 0x865a, 0x068f,
+ 0x865c, 0x0f82,
+ 0x865e, 0x06eb,
+ 0x865f, 0x1952,
+ 0x8667, 0x1953,
+ 0x866b, 0x0bac,
+ 0x8671, 0x1954,
+ 0x8679, 0x0cd2,
+ 0x867b, 0x047e,
+ 0x868a, 0x0563,
+ 0x868b, 0x1959,
+ 0x8693, 0x1955,
+ 0x8695, 0x088b,
+ 0x86a3, 0x1956,
+ 0x86a4, 0x0cf8,
+ 0x86a9, 0x1957,
+ 0x86ab, 0x1962,
+ 0x86af, 0x195c,
+ 0x86b0, 0x195f,
+ 0x86b6, 0x195b,
+ 0x86c4, 0x195d,
+ 0x86c6, 0x195e,
+ 0x86c7, 0x0904,
+ 0x86c9, 0x1960,
+ 0x86cb, 0x0b7f,
+ 0x86cd, 0x072c,
+ 0x86ce, 0x05a0,
+ 0x86d4, 0x1963,
+ 0x86d9, 0x059d,
+ 0x86db, 0x1968,
+ 0x86de, 0x1964,
+ 0x86df, 0x1967,
+ 0x86e4, 0x0d4e,
+ 0x86e9, 0x1965,
+ 0x86ec, 0x1966,
+ 0x86ed, 0x0dba,
+ 0x86ee, 0x0d6e,
+ 0x86ef, 0x1969,
+ 0x86f8, 0x0b5d,
+ 0x86f9, 0x1973,
+ 0x86fb, 0x196f,
+ 0x86fe, 0x056b,
+ 0x8700, 0x196d,
+ 0x8702, 0x0e58,
+ 0x8703, 0x196e,
+ 0x8706, 0x196b,
+ 0x8708, 0x196c,
+ 0x8709, 0x1971,
+ 0x870a, 0x1974,
+ 0x870d, 0x1972,
+ 0x8711, 0x1970,
+ 0x8712, 0x196a,
+ 0x8718, 0x0b96,
+ 0x871a, 0x197b,
+ 0x871c, 0x0eb6,
+ 0x8725, 0x1979,
+ 0x8729, 0x197a,
+ 0x8734, 0x1975,
+ 0x8737, 0x1977,
+ 0x873b, 0x1978,
+ 0x873f, 0x1976,
+ 0x8749, 0x0a8a,
+ 0x874b, 0x0fdf,
+ 0x874c, 0x197f,
+ 0x874e, 0x1980,
+ 0x8753, 0x1986,
+ 0x8755, 0x09f0,
+ 0x8757, 0x1982,
+ 0x8759, 0x1985,
+ 0x875f, 0x197d,
+ 0x8760, 0x197c,
+ 0x8763, 0x1987,
+ 0x8766, 0x055c,
+ 0x8768, 0x1983,
+ 0x876a, 0x1988,
+ 0x876e, 0x1984,
+ 0x8774, 0x1981,
+ 0x8776, 0x0bcf,
+ 0x8778, 0x197e,
+ 0x877f, 0x0d1e,
+ 0x8782, 0x198c,
+ 0x878d, 0x0f25,
+ 0x879f, 0x198b,
+ 0x87a2, 0x198a,
+ 0x87ab, 0x1993,
+ 0x87af, 0x198d,
+ 0x87b3, 0x1995,
+ 0x87ba, 0x0f50,
+ 0x87bb, 0x1998,
+ 0x87bd, 0x198f,
+ 0x87c0, 0x1990,
+ 0x87c4, 0x1994,
+ 0x87c6, 0x1997,
+ 0x87c7, 0x1996,
+ 0x87cb, 0x198e,
+ 0x87d0, 0x1991,
+ 0x87d2, 0x19a2,
+ 0x87e0, 0x199b,
+ 0x87ec, 0x1e23,
+ 0x87ef, 0x1999,
+ 0x87f2, 0x199a,
+ 0x87f6, 0x199f,
+ 0x87f9, 0x0588,
+ 0x87fb, 0x065c,
+ 0x87fe, 0x199e,
+ 0x8805, 0x1989,
+ 0x8807, 0x21a6,
+ 0x880d, 0x199d,
+ 0x880e, 0x19a1,
+ 0x880f, 0x199c,
+ 0x8811, 0x19a3,
+ 0x8815, 0x19a5,
+ 0x8816, 0x19a4,
+ 0x881f, 0x1e85,
+ 0x8821, 0x19a7,
+ 0x8822, 0x19a6,
+ 0x8823, 0x1961,
+ 0x8827, 0x19ab,
+ 0x8831, 0x19a8,
+ 0x8836, 0x19a9,
+ 0x8839, 0x19aa,
+ 0x883b, 0x19ac,
+ 0x8840, 0x0742,
+ 0x8842, 0x19ae,
+ 0x8844, 0x19ad,
+ 0x8846, 0x093a,
+ 0x884c, 0x07e6,
+ 0x884d, 0x1524,
+ 0x8852, 0x19af,
+ 0x8853, 0x095b,
+ 0x8857, 0x0597,
+ 0x8859, 0x19b0,
+ 0x885b, 0x04f4,
+ 0x885d, 0x09bf,
+ 0x885e, 0x19b1,
+ 0x8861, 0x07e7,
+ 0x8862, 0x19b2,
+ 0x8863, 0x04a5,
+ 0x8868, 0x0daf,
+ 0x886b, 0x19b3,
+ 0x8870, 0x0a30,
+ 0x8872, 0x19ba,
+ 0x8875, 0x19b7,
+ 0x8877, 0x0bad,
+ 0x887d, 0x19b8,
+ 0x887e, 0x19b5,
+ 0x887f, 0x06d6,
+ 0x8881, 0x19b4,
+ 0x8882, 0x19bb,
+ 0x8888, 0x070c,
+ 0x888b, 0x0b3e,
+ 0x888d, 0x19c1,
+ 0x8892, 0x19bd,
+ 0x8896, 0x0b15,
+ 0x8897, 0x19bc,
+ 0x8899, 0x19bf,
+ 0x889e, 0x19b6,
+ 0x88a2, 0x19c0,
+ 0x88a4, 0x19c2,
+ 0x88ab, 0x0d83,
+ 0x88ae, 0x19be,
+ 0x88b0, 0x19c3,
+ 0x88b1, 0x19c5,
+ 0x88b4, 0x0787,
+ 0x88b5, 0x19b9,
+ 0x88b7, 0x0485,
+ 0x88bf, 0x19c4,
+ 0x88c1, 0x084b,
+ 0x88c2, 0x0fbe,
+ 0x88c3, 0x19c6,
+ 0x88c5, 0x0af7,
+ 0x88cf, 0x0f6a,
+ 0x88d4, 0x19c8,
+ 0x88d5, 0x0f1f,
+ 0x88d8, 0x19c9,
+ 0x88dc, 0x0e34,
+ 0x88dd, 0x19cb,
+ 0x88df, 0x0830,
+ 0x88e1, 0x0f6b,
+ 0x88e8, 0x19d0,
+ 0x88f2, 0x19d1,
+ 0x88f3, 0x09c0,
+ 0x88f4, 0x19cf,
+ 0x88f5, 0x21a7,
+ 0x88f8, 0x0f51,
+ 0x88f9, 0x19cc,
+ 0x88fc, 0x19ce,
+ 0x88fd, 0x0a61,
+ 0x88fe, 0x0a44,
+ 0x8902, 0x19cd,
+ 0x8904, 0x19d2,
+ 0x8907, 0x0df3,
+ 0x890a, 0x19d4,
+ 0x890c, 0x19d3,
+ 0x8910, 0x05ca,
+ 0x8912, 0x0e59,
+ 0x8913, 0x19d5,
+ 0x891c, 0x20a8,
+ 0x891d, 0x19e1,
+ 0x891e, 0x19d7,
+ 0x8925, 0x19d8,
+ 0x892a, 0x19d9,
+ 0x8936, 0x19de,
+ 0x8938, 0x19df,
+ 0x893b, 0x19dd,
+ 0x8941, 0x19db,
+ 0x8943, 0x19d6,
+ 0x8944, 0x19dc,
+ 0x894c, 0x19e0,
+ 0x894d, 0x1bd0,
+ 0x8956, 0x0528,
+ 0x895e, 0x19e3,
+ 0x895f, 0x06d7,
+ 0x8960, 0x19e2,
+ 0x8964, 0x19e5,
+ 0x8966, 0x19e4,
+ 0x896a, 0x19e7,
+ 0x896d, 0x19e6,
+ 0x896f, 0x19e8,
+ 0x8972, 0x093b,
+ 0x8974, 0x19e9,
+ 0x8977, 0x19ea,
+ 0x897e, 0x19eb,
+ 0x897f, 0x0a62,
+ 0x8981, 0x0f41,
+ 0x8983, 0x19ec,
+ 0x8986, 0x0df4,
+ 0x8987, 0x0cfc,
+ 0x8988, 0x19ed,
+ 0x898a, 0x19ee,
+ 0x898b, 0x075f,
+ 0x898f, 0x0646,
+ 0x8993, 0x19ef,
+ 0x8996, 0x08b9,
+ 0x8997, 0x0cf7,
+ 0x8998, 0x19f0,
+ 0x899a, 0x05ae,
+ 0x89a1, 0x19f1,
+ 0x89a6, 0x19f3,
+ 0x89a7, 0x0f61,
+ 0x89a9, 0x19f2,
+ 0x89aa, 0x0a0c,
+ 0x89ac, 0x19f4,
+ 0x89af, 0x19f5,
+ 0x89b2, 0x19f6,
+ 0x89b3, 0x060d,
+ 0x89ba, 0x19f7,
+ 0x89bd, 0x19f8,
+ 0x89bf, 0x19f9,
+ 0x89d2, 0x05af,
+ 0x89da, 0x19fb,
+ 0x89dc, 0x19fc,
+ 0x89e3, 0x0572,
+ 0x89e6, 0x09ee,
+ 0x89e7, 0x19fe,
+ 0x89f4, 0x19ff,
+ 0x89f8, 0x1a00,
+ 0x8a00, 0x0774,
+ 0x8a02, 0x0c17,
+ 0x8a03, 0x1a01,
+ 0x8a08, 0x072d,
+ 0x8a0a, 0x0a1c,
+ 0x8a0c, 0x1a04,
+ 0x8a0e, 0x0c7c,
+ 0x8a10, 0x1a03,
+ 0x8a12, 0x21a8,
+ 0x8a13, 0x0707,
+ 0x8a16, 0x1a02,
+ 0x8a17, 0x0b57,
+ 0x8a18, 0x0647,
+ 0x8a1b, 0x1a05,
+ 0x8a1d, 0x1a06,
+ 0x8a1f, 0x09c1,
+ 0x8a23, 0x0743,
+ 0x8a25, 0x1a07,
+ 0x8a2a, 0x0e5a,
+ 0x8a2d, 0x0a83,
+ 0x8a31, 0x0690,
+ 0x8a33, 0x0f01,
+ 0x8a34, 0x0acc,
+ 0x8a36, 0x1a08,
+ 0x8a37, 0x21a9,
+ 0x8a3a, 0x0a0d,
+ 0x8a3b, 0x0bae,
+ 0x8a3c, 0x09c2,
+ 0x8a41, 0x1a09,
+ 0x8a46, 0x1a0c,
+ 0x8a48, 0x1a0d,
+ 0x8a50, 0x082e,
+ 0x8a51, 0x0b22,
+ 0x8a52, 0x1a0b,
+ 0x8a54, 0x09c3,
+ 0x8a55, 0x0db0,
+ 0x8a5b, 0x1a0a,
+ 0x8a5e, 0x08ba,
+ 0x8a60, 0x04f5,
+ 0x8a62, 0x1a11,
+ 0x8a63, 0x072e,
+ 0x8a66, 0x08bc,
+ 0x8a69, 0x08bb,
+ 0x8a6b, 0x0ff3,
+ 0x8a6c, 0x1a10,
+ 0x8a6d, 0x1a0f,
+ 0x8a6e, 0x0aa9,
+ 0x8a70, 0x0667,
+ 0x8a71, 0x0fe9,
+ 0x8a72, 0x0598,
+ 0x8a73, 0x09c4,
+ 0x8a79, 0x21aa,
+ 0x8a7c, 0x1a0e,
+ 0x8a82, 0x1a13,
+ 0x8a84, 0x1a14,
+ 0x8a85, 0x1a12,
+ 0x8a87, 0x078c,
+ 0x8a89, 0x0f2a,
+ 0x8a8c, 0x08bd,
+ 0x8a8d, 0x0cdd,
+ 0x8a91, 0x1a17,
+ 0x8a93, 0x0a64,
+ 0x8a95, 0x0b80,
+ 0x8a98, 0x0f20,
+ 0x8a9a, 0x1a1a,
+ 0x8a9e, 0x07a0,
+ 0x8aa0, 0x0a63,
+ 0x8aa1, 0x1a16,
+ 0x8aa3, 0x1a1b,
+ 0x8aa4, 0x07a1,
+ 0x8aa5, 0x1a18,
+ 0x8aa7, 0x21ab,
+ 0x8aa8, 0x1a15,
+ 0x8aac, 0x0a86,
+ 0x8aad, 0x0ca1,
+ 0x8ab0, 0x0b6d,
+ 0x8ab2, 0x055d,
+ 0x8ab9, 0x0d84,
+ 0x8abc, 0x065d,
+ 0x8abe, 0x21ac,
+ 0x8abf, 0x0bd0,
+ 0x8ac2, 0x1a1e,
+ 0x8ac4, 0x1a1c,
+ 0x8ac7, 0x0b8a,
+ 0x8acb, 0x0a65,
+ 0x8acc, 0x060e,
+ 0x8acd, 0x1a1d,
+ 0x8acf, 0x0a21,
+ 0x8ad2, 0x0f92,
+ 0x8ad6, 0x0fe6,
+ 0x8ada, 0x1a1f,
+ 0x8adb, 0x1a2a,
+ 0x8adc, 0x0bd1,
+ 0x8ade, 0x1a29,
+ 0x8adf, 0x21ad,
+ 0x8ae0, 0x1a26,
+ 0x8ae1, 0x1a2e,
+ 0x8ae2, 0x1a27,
+ 0x8ae4, 0x1a23,
+ 0x8ae6, 0x0c18,
+ 0x8ae7, 0x1a22,
+ 0x8aeb, 0x1a20,
+ 0x8aed, 0x0f0b,
+ 0x8aee, 0x08be,
+ 0x8af1, 0x1a24,
+ 0x8af3, 0x1a21,
+ 0x8af6, 0x21af,
+ 0x8af7, 0x1a28,
+ 0x8af8, 0x097e,
+ 0x8afa, 0x0775,
+ 0x8afe, 0x0b5a,
+ 0x8b00, 0x0e73,
+ 0x8b01, 0x04fc,
+ 0x8b02, 0x04a6,
+ 0x8b04, 0x0c7d,
+ 0x8b07, 0x1a2c,
+ 0x8b0c, 0x1a2b,
+ 0x8b0e, 0x0cbe,
+ 0x8b10, 0x1a30,
+ 0x8b14, 0x1a25,
+ 0x8b16, 0x1a2f,
+ 0x8b17, 0x1a31,
+ 0x8b19, 0x0760,
+ 0x8b1a, 0x1a2d,
+ 0x8b1b, 0x07e8,
+ 0x8b1d, 0x0901,
+ 0x8b20, 0x1a32,
+ 0x8b21, 0x0f42,
+ 0x8b26, 0x1a35,
+ 0x8b28, 0x1a38,
+ 0x8b2b, 0x1a36,
+ 0x8b2c, 0x0da7,
+ 0x8b33, 0x1a33,
+ 0x8b39, 0x06d8,
+ 0x8b3e, 0x1a37,
+ 0x8b41, 0x1a39,
+ 0x8b49, 0x1a3d,
+ 0x8b4c, 0x1a3a,
+ 0x8b4e, 0x1a3c,
+ 0x8b4f, 0x1a3b,
+ 0x8b53, 0x21b0,
+ 0x8b56, 0x1a3e,
+ 0x8b58, 0x08dd,
+ 0x8b5a, 0x1a40,
+ 0x8b5b, 0x1a3f,
+ 0x8b5c, 0x0dda,
+ 0x8b5f, 0x1a42,
+ 0x8b66, 0x072f,
+ 0x8b6b, 0x1a41,
+ 0x8b6c, 0x1a43,
+ 0x8b6f, 0x1a44,
+ 0x8b70, 0x065e,
+ 0x8b71, 0x182e,
+ 0x8b72, 0x09e1,
+ 0x8b74, 0x1a45,
+ 0x8b77, 0x07a2,
+ 0x8b7d, 0x1a46,
+ 0x8b7f, 0x21b1,
+ 0x8b80, 0x1a47,
+ 0x8b83, 0x088c,
+ 0x8b8a, 0x13d3,
+ 0x8b8c, 0x1a48,
+ 0x8b8e, 0x1a49,
+ 0x8b90, 0x093c,
+ 0x8b92, 0x1a4a,
+ 0x8b96, 0x1a4c,
+ 0x8b99, 0x1a4d,
+ 0x8c37, 0x0b69,
+ 0x8c3a, 0x1a4f,
+ 0x8c3f, 0x1a51,
+ 0x8c41, 0x1a50,
+ 0x8c46, 0x0c7e,
+ 0x8c48, 0x1a52,
+ 0x8c4a, 0x0e5b,
+ 0x8c4c, 0x1a53,
+ 0x8c4e, 0x1a54,
+ 0x8c50, 0x1a55,
+ 0x8c55, 0x1a56,
+ 0x8c5a, 0x0cb2,
+ 0x8c61, 0x09c5,
+ 0x8c62, 0x1a57,
+ 0x8c6a, 0x07fd,
+ 0x8c6b, 0x1007,
+ 0x8c6c, 0x1a58,
+ 0x8c78, 0x1a59,
+ 0x8c79, 0x0db1,
+ 0x8c7a, 0x1a5a,
+ 0x8c7c, 0x1a62,
+ 0x8c82, 0x1a5b,
+ 0x8c85, 0x1a5d,
+ 0x8c89, 0x1a5c,
+ 0x8c8a, 0x1a5e,
+ 0x8c8c, 0x0e74,
+ 0x8c8d, 0x1a5f,
+ 0x8c94, 0x1a61,
+ 0x8c98, 0x1a63,
+ 0x8c9d, 0x058b,
+ 0x8c9e, 0x0c03,
+ 0x8ca0, 0x0ddb,
+ 0x8ca1, 0x0852,
+ 0x8ca2, 0x07e9,
+ 0x8ca7, 0x0dc1,
+ 0x8ca8, 0x055f,
+ 0x8ca9, 0x0d62,
+ 0x8caa, 0x1a66,
+ 0x8cab, 0x060f,
+ 0x8cac, 0x0a79,
+ 0x8cad, 0x1a65,
+ 0x8cae, 0x1a6a,
+ 0x8caf, 0x0bb7,
+ 0x8cb0, 0x0eef,
+ 0x8cb2, 0x1a68,
+ 0x8cb4, 0x0648,
+ 0x8cb6, 0x1a6b,
+ 0x8cb7, 0x0d19,
+ 0x8cb8, 0x0b3f,
+ 0x8cbb, 0x0d85,
+ 0x8cbc, 0x0c37,
+ 0x8cbd, 0x1a67,
+ 0x8cbf, 0x0e75,
+ 0x8cc0, 0x056c,
+ 0x8cc1, 0x1a6d,
+ 0x8cc2, 0x0fce,
+ 0x8cc3, 0x0bde,
+ 0x8cc4, 0x0feb,
+ 0x8cc7, 0x08bf,
+ 0x8cc8, 0x1a6c,
+ 0x8cca, 0x0b11,
+ 0x8ccd, 0x1a7d,
+ 0x8cce, 0x0aaa,
+ 0x8cd1, 0x0cd0,
+ 0x8cd3, 0x0dc2,
+ 0x8cda, 0x1a70,
+ 0x8cdb, 0x088d,
+ 0x8cdc, 0x08c0,
+ 0x8cde, 0x09c6,
+ 0x8ce0, 0x0d1b,
+ 0x8ce2, 0x0761,
+ 0x8ce3, 0x1a6f,
+ 0x8ce4, 0x1a6e,
+ 0x8ce6, 0x0ddc,
+ 0x8cea, 0x08ed,
+ 0x8ced, 0x0c4c,
+ 0x8cf0, 0x21b2,
+ 0x8cf4, 0x21b3,
+ 0x8cfa, 0x1a72,
+ 0x8cfc, 0x07ea,
+ 0x8cfd, 0x1a71,
+ 0x8d04, 0x1a74,
+ 0x8d07, 0x1a77,
+ 0x8d08, 0x0b03,
+ 0x8d0a, 0x1a76,
+ 0x8d0b, 0x0622,
+ 0x8d0d, 0x1a79,
+ 0x8d0f, 0x1a78,
+ 0x8d10, 0x1a7a,
+ 0x8d12, 0x21b4,
+ 0x8d13, 0x1a7c,
+ 0x8d14, 0x1a7e,
+ 0x8d16, 0x1a7f,
+ 0x8d64, 0x0a7a,
+ 0x8d66, 0x08fb,
+ 0x8d67, 0x1a80,
+ 0x8d6b, 0x05b0,
+ 0x8d6d, 0x1a81,
+ 0x8d70, 0x0af8,
+ 0x8d71, 0x1a82,
+ 0x8d73, 0x1a83,
+ 0x8d74, 0x0ddd,
+ 0x8d76, 0x21b5,
+ 0x8d77, 0x0649,
+ 0x8d81, 0x1a84,
+ 0x8d85, 0x0bd2,
+ 0x8d8a, 0x04fd,
+ 0x8d99, 0x1a85,
+ 0x8da3, 0x091d,
+ 0x8da8, 0x0a3c,
+ 0x8db3, 0x0b0d,
+ 0x8dba, 0x1a88,
+ 0x8dbe, 0x1a87,
+ 0x8dc2, 0x1a86,
+ 0x8dcb, 0x1a8e,
+ 0x8dcc, 0x1a8c,
+ 0x8dcf, 0x1a89,
+ 0x8dd6, 0x1a8b,
+ 0x8dda, 0x1a8a,
+ 0x8ddb, 0x1a8d,
+ 0x8ddd, 0x0691,
+ 0x8ddf, 0x1a91,
+ 0x8de1, 0x0a7b,
+ 0x8de3, 0x1a92,
+ 0x8de8, 0x078d,
+ 0x8dea, 0x1a8f,
+ 0x8def, 0x0fcf,
+ 0x8df3, 0x0bd3,
+ 0x8df5, 0x0aab,
+ 0x8dfc, 0x1a93,
+ 0x8dff, 0x1a96,
+ 0x8e08, 0x1a94,
+ 0x8e0a, 0x0f43,
+ 0x8e0f, 0x0c7f,
+ 0x8e10, 0x1a99,
+ 0x8e1d, 0x1a97,
+ 0x8e1f, 0x1a9a,
+ 0x8e2a, 0x1aa8,
+ 0x8e30, 0x1a9d,
+ 0x8e34, 0x1a9e,
+ 0x8e35, 0x1a9c,
+ 0x8e42, 0x1a9b,
+ 0x8e44, 0x0c19,
+ 0x8e47, 0x1aa0,
+ 0x8e48, 0x1aa4,
+ 0x8e49, 0x1aa1,
+ 0x8e4a, 0x1a9f,
+ 0x8e4c, 0x1aa2,
+ 0x8e50, 0x1aa3,
+ 0x8e55, 0x1aaa,
+ 0x8e59, 0x1aa5,
+ 0x8e5f, 0x0a7c,
+ 0x8e60, 0x1aa7,
+ 0x8e63, 0x1aa9,
+ 0x8e64, 0x1aa6,
+ 0x8e72, 0x1aac,
+ 0x8e74, 0x093d,
+ 0x8e76, 0x1aab,
+ 0x8e7c, 0x1aad,
+ 0x8e81, 0x1aae,
+ 0x8e84, 0x1ab1,
+ 0x8e85, 0x1ab0,
+ 0x8e87, 0x1aaf,
+ 0x8e8a, 0x1ab3,
+ 0x8e8b, 0x1ab2,
+ 0x8e8d, 0x0f02,
+ 0x8e91, 0x1ab5,
+ 0x8e93, 0x1ab4,
+ 0x8e94, 0x1ab6,
+ 0x8e99, 0x1ab7,
+ 0x8ea1, 0x1ab9,
+ 0x8eaa, 0x1ab8,
+ 0x8eab, 0x0a0e,
+ 0x8eac, 0x1aba,
+ 0x8eaf, 0x06e5,
+ 0x8eb0, 0x1abb,
+ 0x8eb1, 0x1abd,
+ 0x8ebe, 0x1abe,
+ 0x8ec0, 0x1def,
+ 0x8ec5, 0x1abf,
+ 0x8ec6, 0x1abc,
+ 0x8ec8, 0x1ac0,
+ 0x8eca, 0x0902,
+ 0x8ecb, 0x1ac1,
+ 0x8ecc, 0x064a,
+ 0x8ecd, 0x0709,
+ 0x8ecf, 0x21b7,
+ 0x8ed2, 0x0762,
+ 0x8edb, 0x1ac2,
+ 0x8edf, 0x0cc8,
+ 0x8ee2, 0x0c38,
+ 0x8ee3, 0x1ac3,
+ 0x8eeb, 0x1ac6,
+ 0x8ef8, 0x08e0,
+ 0x8efb, 0x1ac5,
+ 0x8efc, 0x1ac4,
+ 0x8efd, 0x0730,
+ 0x8efe, 0x1ac7,
+ 0x8f03, 0x05b1,
+ 0x8f05, 0x1ac9,
+ 0x8f09, 0x084c,
+ 0x8f0a, 0x1ac8,
+ 0x8f0c, 0x1ad1,
+ 0x8f12, 0x1acb,
+ 0x8f13, 0x1acd,
+ 0x8f14, 0x0e35,
+ 0x8f15, 0x1aca,
+ 0x8f19, 0x1acc,
+ 0x8f1b, 0x1ad0,
+ 0x8f1c, 0x1ace,
+ 0x8f1d, 0x064b,
+ 0x8f1f, 0x1acf,
+ 0x8f26, 0x1ad2,
+ 0x8f29, 0x0d10,
+ 0x8f2a, 0x0fa0,
+ 0x8f2f, 0x093e,
+ 0x8f33, 0x1ad3,
+ 0x8f38, 0x0f0c,
+ 0x8f39, 0x1ad5,
+ 0x8f3b, 0x1ad4,
+ 0x8f3e, 0x1ad8,
+ 0x8f3f, 0x0f2b,
+ 0x8f42, 0x1ad7,
+ 0x8f44, 0x05cb,
+ 0x8f45, 0x1ad6,
+ 0x8f46, 0x1adb,
+ 0x8f49, 0x1ada,
+ 0x8f4c, 0x1ad9,
+ 0x8f4d, 0x0c2c,
+ 0x8f4e, 0x1adc,
+ 0x8f57, 0x1add,
+ 0x8f5c, 0x1ade,
+ 0x8f5f, 0x07fe,
+ 0x8f61, 0x06fb,
+ 0x8f62, 0x1adf,
+ 0x8f9b, 0x0a0f,
+ 0x8f9c, 0x1ae2,
+ 0x8f9e, 0x08d9,
+ 0x8f9f, 0x1ae3,
+ 0x8fa3, 0x1ae4,
+ 0x8fa7, 0x10b6,
+ 0x8fa8, 0x10b5,
+ 0x8fad, 0x1ae5,
+ 0x8fae, 0x17ff,
+ 0x8faf, 0x1ae6,
+ 0x8fb0, 0x0b62,
+ 0x8fb1, 0x09f1,
+ 0x8fb2, 0x0cf6,
+ 0x8fb7, 0x1ae7,
+ 0x8fba, 0x0e25,
+ 0x8fbb, 0x0bf0,
+ 0x8fbc, 0x0810,
+ 0x8fbf, 0x0b67,
+ 0x8fc2, 0x04cc,
+ 0x8fc4, 0x0ea6,
+ 0x8fc5, 0x0a1d,
+ 0x8fce, 0x0734,
+ 0x8fd1, 0x06d9,
+ 0x8fd4, 0x0e26,
+ 0x8fda, 0x1ae8,
+ 0x8fe2, 0x1aea,
+ 0x8fe5, 0x1ae9,
+ 0x8fe6, 0x0560,
+ 0x8fe9, 0x0cce,
+ 0x8fea, 0x1aeb,
+ 0x8feb, 0x0d2d,
+ 0x8fed, 0x0c2d,
+ 0x8fef, 0x1aec,
+ 0x8ff0, 0x095c,
+ 0x8ff4, 0x1aee,
+ 0x8ff7, 0x0ece,
+ 0x8ff8, 0x1afd,
+ 0x8ff9, 0x1af0,
+ 0x8ffd, 0x0be5,
+ 0x9000, 0x0b40,
+ 0x9001, 0x0af9,
+ 0x9003, 0x0c80,
+ 0x9005, 0x1aef,
+ 0x9006, 0x066f,
+ 0x900b, 0x1af8,
+ 0x900d, 0x1af5,
+ 0x900e, 0x1b02,
+ 0x900f, 0x0c81,
+ 0x9010, 0x0b9e,
+ 0x9011, 0x1af2,
+ 0x9013, 0x0c1a,
+ 0x9014, 0x0c4d,
+ 0x9015, 0x1af3,
+ 0x9016, 0x1af7,
+ 0x9017, 0x0a26,
+ 0x9019, 0x0d1d,
+ 0x901a, 0x0be8,
+ 0x901d, 0x0a66,
+ 0x901e, 0x1af6,
+ 0x901f, 0x0b0e,
+ 0x9020, 0x0b04,
+ 0x9021, 0x1af4,
+ 0x9022, 0x046d,
+ 0x9023, 0x0fc8,
+ 0x9027, 0x1af9,
+ 0x902e, 0x0b41,
+ 0x9031, 0x093f,
+ 0x9032, 0x0a10,
+ 0x9035, 0x1afb,
+ 0x9036, 0x1afa,
+ 0x9038, 0x04b3,
+ 0x9039, 0x1afc,
+ 0x903c, 0x0da1,
+ 0x903e, 0x1b04,
+ 0x9041, 0x0cb3,
+ 0x9042, 0x0a31,
+ 0x9045, 0x0b97,
+ 0x9047, 0x06f0,
+ 0x9049, 0x1b03,
+ 0x904a, 0x0f21,
+ 0x904b, 0x04e1,
+ 0x904d, 0x0e27,
+ 0x904e, 0x0561,
+ 0x904f, 0x1afe,
+ 0x9053, 0x0c93,
+ 0x9054, 0x0b61,
+ 0x9055, 0x04a7,
+ 0x9056, 0x1b05,
+ 0x9058, 0x1b06,
+ 0x9059, 0x1d34,
+ 0x905c, 0x0b1d,
+ 0x905e, 0x1b07,
+ 0x9060, 0x0515,
+ 0x9061, 0x0ace,
+ 0x9063, 0x0763,
+ 0x9065, 0x0f44,
+ 0x9067, 0x21ba,
+ 0x9068, 0x1b08,
+ 0x9069, 0x0c26,
+ 0x906d, 0x0afa,
+ 0x906e, 0x0903,
+ 0x906f, 0x1b09,
+ 0x9072, 0x1b0c,
+ 0x9075, 0x096f,
+ 0x9076, 0x1b0a,
+ 0x9077, 0x0aad,
+ 0x9078, 0x0aac,
+ 0x907a, 0x04a8,
+ 0x907c, 0x0f93,
+ 0x907d, 0x1b0e,
+ 0x907f, 0x0d86,
+ 0x9080, 0x1b10,
+ 0x9081, 0x1b0f,
+ 0x9082, 0x1b0d,
+ 0x9083, 0x1737,
+ 0x9084, 0x0610,
+ 0x9087, 0x1aed,
+ 0x9089, 0x1b12,
+ 0x908a, 0x1b11,
+ 0x908f, 0x1b13,
+ 0x9091, 0x0f22,
+ 0x90a3, 0x0cb9,
+ 0x90a6, 0x0e5c,
+ 0x90a8, 0x1b14,
+ 0x90aa, 0x0905,
+ 0x90af, 0x1b15,
+ 0x90b1, 0x1b16,
+ 0x90b5, 0x1b17,
+ 0x90b8, 0x0c1b,
+ 0x90c1, 0x04ae,
+ 0x90ca, 0x07eb,
+ 0x90ce, 0x0fe0,
+ 0x90db, 0x1b1b,
+ 0x90de, 0x21bb,
+ 0x90e1, 0x070a,
+ 0x90e2, 0x1b18,
+ 0x90e4, 0x1b19,
+ 0x90e8, 0x0de6,
+ 0x90ed, 0x05b2,
+ 0x90f5, 0x0f23,
+ 0x90f7, 0x06b7,
+ 0x90fd, 0x0c4e,
+ 0x9102, 0x1b1c,
+ 0x9112, 0x1b1d,
+ 0x9115, 0x21bd,
+ 0x9119, 0x1b1e,
+ 0x9127, 0x21be,
+ 0x912d, 0x0c1c,
+ 0x9130, 0x1b20,
+ 0x9132, 0x1b1f,
+ 0x9149, 0x0cab,
+ 0x914a, 0x1b21,
+ 0x914b, 0x0940,
+ 0x914c, 0x090c,
+ 0x914d, 0x0d11,
+ 0x914e, 0x0baf,
+ 0x9152, 0x091e,
+ 0x9154, 0x0a32,
+ 0x9156, 0x1b22,
+ 0x9158, 0x1b23,
+ 0x9162, 0x0a23,
+ 0x9163, 0x1b24,
+ 0x9165, 0x1b25,
+ 0x9169, 0x1b26,
+ 0x916a, 0x0f59,
+ 0x916c, 0x0941,
+ 0x9172, 0x1b28,
+ 0x9173, 0x1b27,
+ 0x9175, 0x07ec,
+ 0x9177, 0x0805,
+ 0x9178, 0x088e,
+ 0x9182, 0x1b2b,
+ 0x9187, 0x0970,
+ 0x9189, 0x1b2a,
+ 0x918b, 0x1b29,
+ 0x918d, 0x0b49,
+ 0x9190, 0x07a3,
+ 0x9192, 0x0a67,
+ 0x9197, 0x0d44,
+ 0x919c, 0x0943,
+ 0x91a2, 0x1b2c,
+ 0x91a4, 0x09c7,
+ 0x91aa, 0x1b2f,
+ 0x91ab, 0x1b2d,
+ 0x91ac, 0x1e1b,
+ 0x91af, 0x1b2e,
+ 0x91b1, 0x1e61,
+ 0x91b4, 0x1b31,
+ 0x91b5, 0x1b30,
+ 0x91b8, 0x09e2,
+ 0x91ba, 0x1b32,
+ 0x91c0, 0x1b33,
+ 0x91c6, 0x0d64,
+ 0x91c7, 0x0843,
+ 0x91c8, 0x090d,
+ 0x91c9, 0x1b35,
+ 0x91cb, 0x1b36,
+ 0x91cc, 0x0f6c,
+ 0x91cd, 0x094f,
+ 0x91ce, 0x0efa,
+ 0x91cf, 0x0f94,
+ 0x91d0, 0x1b37,
+ 0x91d1, 0x06da,
+ 0x91d6, 0x1b38,
+ 0x91d7, 0x21c0,
+ 0x91d8, 0x0c1d,
+ 0x91da, 0x21bf,
+ 0x91db, 0x1b3b,
+ 0x91dc, 0x05d6,
+ 0x91dd, 0x0a11,
+ 0x91de, 0x21c1,
+ 0x91df, 0x1b39,
+ 0x91e1, 0x1b3a,
+ 0x91e3, 0x0bfc,
+ 0x91e4, 0x21c4,
+ 0x91e6, 0x0e83,
+ 0x91e7, 0x06f4,
+ 0x91ed, 0x21c2,
+ 0x91f5, 0x1b3d,
+ 0x91fc, 0x1b3c,
+ 0x91ff, 0x1b40,
+ 0x9206, 0x21c6,
+ 0x920a, 0x21c8,
+ 0x920d, 0x0cb7,
+ 0x920e, 0x05a1,
+ 0x9210, 0x21c7,
+ 0x9211, 0x1b44,
+ 0x9214, 0x1b41,
+ 0x9215, 0x1b43,
+ 0x921e, 0x1b3f,
+ 0x9229, 0x1b8a,
+ 0x922c, 0x1b42,
+ 0x9234, 0x0fb3,
+ 0x9237, 0x078e,
+ 0x9239, 0x21cf,
+ 0x923a, 0x21c9,
+ 0x923c, 0x21cb,
+ 0x923f, 0x1b4c,
+ 0x9240, 0x21ca,
+ 0x9244, 0x0c2e,
+ 0x9245, 0x1b47,
+ 0x9248, 0x1b4a,
+ 0x9249, 0x1b48,
+ 0x924b, 0x1b4d,
+ 0x924e, 0x21cc,
+ 0x9250, 0x1b4e,
+ 0x9251, 0x21ce,
+ 0x9257, 0x1b46,
+ 0x9259, 0x21cd,
+ 0x925a, 0x1b53,
+ 0x925b, 0x0516,
+ 0x925e, 0x1b45,
+ 0x9262, 0x0d41,
+ 0x9264, 0x1b49,
+ 0x9266, 0x09c8,
+ 0x9267, 0x21d0,
+ 0x9271, 0x07ed,
+ 0x9277, 0x21d2,
+ 0x927e, 0x0e76,
+ 0x9280, 0x06dc,
+ 0x9283, 0x0950,
+ 0x9285, 0x0c94,
+ 0x9288, 0x20aa,
+ 0x9291, 0x0aaf,
+ 0x9293, 0x1b51,
+ 0x9295, 0x1b4b,
+ 0x9296, 0x1b50,
+ 0x9298, 0x0ecf,
+ 0x929a, 0x0bd4,
+ 0x929b, 0x1b52,
+ 0x929c, 0x1b4f,
+ 0x92a7, 0x21d1,
+ 0x92ad, 0x0aae,
+ 0x92b7, 0x1b56,
+ 0x92b9, 0x1b55,
+ 0x92cf, 0x1b54,
+ 0x92d0, 0x21d7,
+ 0x92d2, 0x0e5d,
+ 0x92d3, 0x21db,
+ 0x92d5, 0x21d9,
+ 0x92d7, 0x21d5,
+ 0x92d9, 0x21d6,
+ 0x92e0, 0x21da,
+ 0x92e4, 0x0985,
+ 0x92e7, 0x21d4,
+ 0x92e9, 0x1b57,
+ 0x92ea, 0x0e2f,
+ 0x92ed, 0x04f6,
+ 0x92f2, 0x0db8,
+ 0x92f3, 0x0bb0,
+ 0x92f8, 0x0692,
+ 0x92f9, 0x20b0,
+ 0x92fa, 0x1b59,
+ 0x92fb, 0x21de,
+ 0x92fc, 0x07ef,
+ 0x92ff, 0x21e1,
+ 0x9302, 0x21e3,
+ 0x9306, 0x087a,
+ 0x930f, 0x1b58,
+ 0x9310, 0x0a33,
+ 0x9318, 0x0a34,
+ 0x9319, 0x1b5c,
+ 0x931a, 0x1b5e,
+ 0x931d, 0x21e2,
+ 0x931e, 0x21e0,
+ 0x9320, 0x09e3,
+ 0x9321, 0x21dd,
+ 0x9322, 0x1b5d,
+ 0x9323, 0x1b5f,
+ 0x9325, 0x21dc,
+ 0x9326, 0x06cb,
+ 0x9328, 0x0db7,
+ 0x932b, 0x090e,
+ 0x932c, 0x0fc9,
+ 0x932e, 0x1b5b,
+ 0x932f, 0x0868,
+ 0x9332, 0x0fe5,
+ 0x9335, 0x1b61,
+ 0x933a, 0x1b60,
+ 0x933b, 0x1b62,
+ 0x9344, 0x1b5a,
+ 0x9348, 0x20a9,
+ 0x934b, 0x0cc1,
+ 0x934d, 0x0c4f,
+ 0x9354, 0x0bf3,
+ 0x9356, 0x1b67,
+ 0x9357, 0x21e5,
+ 0x935b, 0x0b81,
+ 0x935c, 0x1b63,
+ 0x9360, 0x1b64,
+ 0x936c, 0x0703,
+ 0x936e, 0x1b66,
+ 0x9370, 0x21e4,
+ 0x9375, 0x0764,
+ 0x937c, 0x1b65,
+ 0x937e, 0x09c9,
+ 0x938c, 0x05d7,
+ 0x9394, 0x1b6b,
+ 0x9396, 0x082f,
+ 0x9397, 0x0afb,
+ 0x939a, 0x0be6,
+ 0x93a4, 0x21e6,
+ 0x93a7, 0x0599,
+ 0x93ac, 0x1b69,
+ 0x93ae, 0x0bdf,
+ 0x93b0, 0x1b68,
+ 0x93b9, 0x1b6c,
+ 0x93c3, 0x1b72,
+ 0x93c6, 0x21e7,
+ 0x93c8, 0x1b75,
+ 0x93d0, 0x1b74,
+ 0x93d1, 0x0c27,
+ 0x93d6, 0x1b6d,
+ 0x93d8, 0x1b71,
+ 0x93dd, 0x1b73,
+ 0x93de, 0x21e8,
+ 0x93e1, 0x06b8,
+ 0x93e4, 0x1b76,
+ 0x93e5, 0x1b70,
+ 0x93e8, 0x1b6f,
+ 0x93f8, 0x21e9,
+ 0x9403, 0x1b7a,
+ 0x9407, 0x1b7b,
+ 0x9410, 0x1b7c,
+ 0x9413, 0x1b79,
+ 0x9414, 0x1b78,
+ 0x9418, 0x09ca,
+ 0x9419, 0x0c82,
+ 0x941a, 0x1b77,
+ 0x9421, 0x1b80,
+ 0x942b, 0x1b7e,
+ 0x9431, 0x21ea,
+ 0x9435, 0x1b7f,
+ 0x9436, 0x1b7d,
+ 0x9438, 0x0b58,
+ 0x943a, 0x1b81,
+ 0x9441, 0x1b82,
+ 0x9444, 0x1b84,
+ 0x9445, 0x21eb,
+ 0x9448, 0x21ec,
+ 0x9451, 0x0611,
+ 0x9452, 0x1b83,
+ 0x9453, 0x0f06,
+ 0x945a, 0x1b8f,
+ 0x945b, 0x1b85,
+ 0x945e, 0x1b88,
+ 0x9460, 0x1b86,
+ 0x9462, 0x1b87,
+ 0x946a, 0x1b89,
+ 0x9470, 0x1b8b,
+ 0x9475, 0x1b8c,
+ 0x9477, 0x1b8d,
+ 0x947c, 0x1b90,
+ 0x947d, 0x1b8e,
+ 0x947e, 0x1b91,
+ 0x947f, 0x1b93,
+ 0x9481, 0x1b92,
+ 0x9577, 0x0bd5,
+ 0x9580, 0x0ef3,
+ 0x9582, 0x1b94,
+ 0x9583, 0x0ab0,
+ 0x9587, 0x1b95,
+ 0x9589, 0x0e14,
+ 0x958a, 0x1b96,
+ 0x958b, 0x0589,
+ 0x958f, 0x04de,
+ 0x9591, 0x0613,
+ 0x9592, 0x21ed,
+ 0x9593, 0x0612,
+ 0x9594, 0x1b97,
+ 0x9596, 0x1b98,
+ 0x9598, 0x1b99,
+ 0x95a0, 0x1b9b,
+ 0x95a2, 0x0614,
+ 0x95a3, 0x05b3,
+ 0x95a4, 0x07f0,
+ 0x95a5, 0x0d4a,
+ 0x95a7, 0x1b9d,
+ 0x95a8, 0x1b9c,
+ 0x95ad, 0x1b9e,
+ 0x95b2, 0x04fe,
+ 0x95b9, 0x1ba1,
+ 0x95bb, 0x1ba0,
+ 0x95bc, 0x1b9f,
+ 0x95be, 0x1ba2,
+ 0x95c3, 0x1ba5,
+ 0x95c7, 0x048b,
+ 0x95ca, 0x1ba3,
+ 0x95cc, 0x1ba7,
+ 0x95cd, 0x1ba6,
+ 0x95d4, 0x1ba9,
+ 0x95d5, 0x1ba8,
+ 0x95d6, 0x1baa,
+ 0x95d8, 0x0c86,
+ 0x95dc, 0x1bab,
+ 0x95e1, 0x1bac,
+ 0x95e2, 0x1bae,
+ 0x95e5, 0x1bad,
+ 0x961c, 0x0dde,
+ 0x9621, 0x1baf,
+ 0x9628, 0x1bb0,
+ 0x962a, 0x0855,
+ 0x962e, 0x1bb1,
+ 0x9632, 0x0e77,
+ 0x963b, 0x0acd,
+ 0x963f, 0x0468,
+ 0x9640, 0x0b2b,
+ 0x9642, 0x1bb3,
+ 0x9644, 0x0ddf,
+ 0x964b, 0x1bb6,
+ 0x964c, 0x1bb4,
+ 0x964d, 0x07f1,
+ 0x964f, 0x1bb5,
+ 0x9650, 0x0776,
+ 0x965b, 0x0e15,
+ 0x965c, 0x1bb8,
+ 0x965d, 0x1bba,
+ 0x965e, 0x1bb9,
+ 0x965f, 0x1bbb,
+ 0x9662, 0x04c3,
+ 0x9663, 0x0a1e,
+ 0x9664, 0x0986,
+ 0x9665, 0x0615,
+ 0x9666, 0x1bbc,
+ 0x966a, 0x0d1c,
+ 0x966c, 0x1bbe,
+ 0x9670, 0x04c4,
+ 0x9672, 0x1bbd,
+ 0x9673, 0x0be0,
+ 0x9675, 0x0f95,
+ 0x9676, 0x0c83,
+ 0x9677, 0x1bb7,
+ 0x9678, 0x0f6e,
+ 0x967a, 0x0765,
+ 0x967d, 0x0f45,
+ 0x9685, 0x06f1,
+ 0x9686, 0x0f7c,
+ 0x9688, 0x06fe,
+ 0x968a, 0x0b42,
+ 0x968b, 0x186c,
+ 0x968d, 0x1bbf,
+ 0x968e, 0x058a,
+ 0x968f, 0x0a35,
+ 0x9694, 0x05b4,
+ 0x9695, 0x1bc1,
+ 0x9697, 0x1bc2,
+ 0x9698, 0x1bc0,
+ 0x9699, 0x073a,
+ 0x969b, 0x084d,
+ 0x969c, 0x09cb,
+ 0x969d, 0x21f0,
+ 0x96a0, 0x04c5,
+ 0x96a3, 0x0fa1,
+ 0x96a7, 0x1bc4,
+ 0x96a8, 0x1b0b,
+ 0x96aa, 0x1bc3,
+ 0x96af, 0x21f1,
+ 0x96b0, 0x1bc7,
+ 0x96b1, 0x1bc5,
+ 0x96b4, 0x1bc8,
+ 0x96b6, 0x1bc9,
+ 0x96b7, 0x0fb4,
+ 0x96b8, 0x1bca,
+ 0x96bb, 0x0a6d,
+ 0x96bc, 0x0d4f,
+ 0x96c0, 0x0a43,
+ 0x96c1, 0x0623,
+ 0x96c4, 0x0f24,
+ 0x96c5, 0x056d,
+ 0x96c6, 0x0942,
+ 0x96c7, 0x078f,
+ 0x96c9, 0x1bce,
+ 0x96cb, 0x1bcd,
+ 0x96cc, 0x08c1,
+ 0x96cd, 0x1bcf,
+ 0x96ce, 0x1bcc,
+ 0x96d1, 0x0876,
+ 0x96d5, 0x1bd3,
+ 0x96d6, 0x1992,
+ 0x96d9, 0x10eb,
+ 0x96db, 0x0a3d,
+ 0x96dc, 0x1bd1,
+ 0x96e2, 0x0f6d,
+ 0x96e3, 0x0cc9,
+ 0x96e8, 0x04cd,
+ 0x96ea, 0x0a87,
+ 0x96eb, 0x08e2,
+ 0x96f0, 0x0e07,
+ 0x96f2, 0x04e2,
+ 0x96f6, 0x0fb5,
+ 0x96f7, 0x0f55,
+ 0x96f9, 0x1bd4,
+ 0x96fb, 0x0c3f,
+ 0x9700, 0x0927,
+ 0x9704, 0x1bd5,
+ 0x9706, 0x1bd6,
+ 0x9707, 0x0a12,
+ 0x9708, 0x1bd7,
+ 0x970a, 0x0fb6,
+ 0x970d, 0x1bd2,
+ 0x970e, 0x1bd9,
+ 0x970f, 0x1bdb,
+ 0x9711, 0x1bda,
+ 0x9713, 0x1bd8,
+ 0x9716, 0x1bdc,
+ 0x9719, 0x1bdd,
+ 0x971c, 0x0afc,
+ 0x971e, 0x0562,
+ 0x9724, 0x1bde,
+ 0x9727, 0x0ec4,
+ 0x972a, 0x1bdf,
+ 0x9730, 0x1be0,
+ 0x9732, 0x0fd0,
+ 0x9733, 0x21f2,
+ 0x9738, 0x1414,
+ 0x9739, 0x1be1,
+ 0x973b, 0x21f3,
+ 0x973d, 0x1be2,
+ 0x9742, 0x1be7,
+ 0x9743, 0x21f4,
+ 0x9744, 0x1be4,
+ 0x9746, 0x1be5,
+ 0x9748, 0x1be6,
+ 0x9749, 0x1be8,
+ 0x974d, 0x21f5,
+ 0x974f, 0x21f6,
+ 0x9751, 0x21f7,
+ 0x9752, 0x0a68,
+ 0x9755, 0x21f8,
+ 0x9756, 0x0f03,
+ 0x9759, 0x0a69,
+ 0x975c, 0x1be9,
+ 0x975e, 0x0d87,
+ 0x9760, 0x1bea,
+ 0x9761, 0x1d06,
+ 0x9762, 0x0ed8,
+ 0x9764, 0x1beb,
+ 0x9766, 0x1bec,
+ 0x9768, 0x1bed,
+ 0x9769, 0x05b5,
+ 0x976b, 0x1bef,
+ 0x976d, 0x0a1f,
+ 0x9771, 0x1bf0,
+ 0x9774, 0x06fa,
+ 0x9779, 0x1bf1,
+ 0x977a, 0x1bf5,
+ 0x977c, 0x1bf3,
+ 0x9781, 0x1bf4,
+ 0x9784, 0x05d1,
+ 0x9785, 0x1bf2,
+ 0x9786, 0x1bf6,
+ 0x978b, 0x1bf7,
+ 0x978d, 0x048c,
+ 0x978f, 0x1bf8,
+ 0x9798, 0x09cc,
+ 0x979c, 0x1bfa,
+ 0x97a0, 0x0661,
+ 0x97a3, 0x1bfd,
+ 0x97a6, 0x1bfc,
+ 0x97a8, 0x1bfb,
+ 0x97ab, 0x1a34,
+ 0x97ad, 0x0e2c,
+ 0x97b3, 0x1bfe,
+ 0x97c3, 0x1c00,
+ 0x97c6, 0x1c01,
+ 0x97c8, 0x1c02,
+ 0x97cb, 0x1c03,
+ 0x97d3, 0x0616,
+ 0x97dc, 0x1c04,
+ 0x97ed, 0x1c05,
+ 0x97ee, 0x0cd9,
+ 0x97f2, 0x1c07,
+ 0x97f3, 0x053b,
+ 0x97f5, 0x1c0a,
+ 0x97f6, 0x1c09,
+ 0x97fb, 0x04c6,
+ 0x97ff, 0x06b9,
+ 0x9801, 0x0e17,
+ 0x9802, 0x0bd6,
+ 0x9803, 0x0812,
+ 0x9805, 0x07f2,
+ 0x9806, 0x0971,
+ 0x9808, 0x0a22,
+ 0x980c, 0x1c0c,
+ 0x980f, 0x1c0b,
+ 0x9810, 0x0f2c,
+ 0x9811, 0x0624,
+ 0x9812, 0x0d66,
+ 0x9813, 0x0cb4,
+ 0x9817, 0x0a42,
+ 0x9818, 0x0f96,
+ 0x981a, 0x0731,
+ 0x9821, 0x1c0f,
+ 0x9824, 0x1c0e,
+ 0x982c, 0x0e79,
+ 0x982d, 0x0c84,
+ 0x9830, 0x1e73,
+ 0x9834, 0x04f2,
+ 0x9837, 0x1c10,
+ 0x9838, 0x1c0d,
+ 0x983b, 0x0dc3,
+ 0x983c, 0x0f54,
+ 0x983d, 0x1c11,
+ 0x9846, 0x1c12,
+ 0x984b, 0x1c14,
+ 0x984c, 0x0b4a,
+ 0x984d, 0x05b9,
+ 0x984f, 0x1c13,
+ 0x9854, 0x0625,
+ 0x9855, 0x0766,
+ 0x9857, 0x21f9,
+ 0x9858, 0x0626,
+ 0x985a, 0x1e48,
+ 0x985b, 0x0c39,
+ 0x985e, 0x0fa8,
+ 0x9865, 0x21fa,
+ 0x9867, 0x0790,
+ 0x986b, 0x1c15,
+ 0x986f, 0x1c16,
+ 0x9873, 0x1c1a,
+ 0x9874, 0x1c19,
+ 0x98a8, 0x0de9,
+ 0x98aa, 0x1c1b,
+ 0x98af, 0x1c1c,
+ 0x98b1, 0x1c1d,
+ 0x98b6, 0x1c1e,
+ 0x98c3, 0x1c20,
+ 0x98c4, 0x1c1f,
+ 0x98c6, 0x1c21,
+ 0x98db, 0x0d88,
+ 0x98dc, 0x1839,
+ 0x98df, 0x09ef,
+ 0x98e2, 0x064c,
+ 0x98e9, 0x1c22,
+ 0x98eb, 0x1c23,
+ 0x98ed, 0x10c1,
+ 0x98ee, 0x14da,
+ 0x98ef, 0x0d67,
+ 0x98f2, 0x04bf,
+ 0x98f4, 0x047f,
+ 0x98fc, 0x08c2,
+ 0x98fd, 0x0e5e,
+ 0x98fe, 0x09e6,
+ 0x9903, 0x1c24,
+ 0x9905, 0x0eeb,
+ 0x9909, 0x1c25,
+ 0x990a, 0x0f46,
+ 0x990c, 0x04e4,
+ 0x9910, 0x088f,
+ 0x9912, 0x1c26,
+ 0x9913, 0x056e,
+ 0x9914, 0x1c27,
+ 0x9918, 0x1c28,
+ 0x991d, 0x1c2a,
+ 0x9920, 0x1c2d,
+ 0x9921, 0x1c29,
+ 0x9924, 0x1c2c,
+ 0x9927, 0x21fd,
+ 0x9928, 0x0617,
+ 0x992c, 0x1c2e,
+ 0x992e, 0x1c2f,
+ 0x993d, 0x1c30,
+ 0x9942, 0x1c32,
+ 0x9945, 0x1c34,
+ 0x9949, 0x1c33,
+ 0x994b, 0x1c36,
+ 0x994c, 0x1c39,
+ 0x9950, 0x1c35,
+ 0x9951, 0x1c37,
+ 0x9955, 0x1c3a,
+ 0x9957, 0x06ba,
+ 0x9996, 0x091f,
+ 0x9997, 0x1c3b,
+ 0x9999, 0x07f3,
+ 0x999e, 0x21ff,
+ 0x99a5, 0x1c3d,
+ 0x99a8, 0x059c,
+ 0x99ac, 0x0d05,
+ 0x99ad, 0x1c3e,
+ 0x99b3, 0x0b98,
+ 0x99b4, 0x0cc3,
+ 0x99bc, 0x1c40,
+ 0x99c1, 0x0d33,
+ 0x99c4, 0x0b2c,
+ 0x99c5, 0x04fa,
+ 0x99c6, 0x06e6,
+ 0x99c8, 0x06e7,
+ 0x99d0, 0x0bb1,
+ 0x99d1, 0x1c45,
+ 0x99d2, 0x06e8,
+ 0x99d5, 0x056f,
+ 0x99d8, 0x1c44,
+ 0x99db, 0x1c42,
+ 0x99dd, 0x1c43,
+ 0x99df, 0x1c41,
+ 0x99e2, 0x1c4f,
+ 0x99ed, 0x1c46,
+ 0x99f1, 0x1c48,
+ 0x99f8, 0x1c4b,
+ 0x99fb, 0x1c4a,
+ 0x99ff, 0x0963,
+ 0x9a01, 0x1c4c,
+ 0x9a05, 0x1c4e,
+ 0x9a0e, 0x064d,
+ 0x9a0f, 0x1c4d,
+ 0x9a12, 0x0afd,
+ 0x9a13, 0x0767,
+ 0x9a19, 0x1c50,
+ 0x9a28, 0x0b2d,
+ 0x9a2b, 0x1c51,
+ 0x9a30, 0x0c85,
+ 0x9a37, 0x1c52,
+ 0x9a3e, 0x1c57,
+ 0x9a40, 0x1c55,
+ 0x9a42, 0x1c54,
+ 0x9a43, 0x1c56,
+ 0x9a45, 0x1c53,
+ 0x9a4d, 0x1c59,
+ 0x9a4e, 0x2200,
+ 0x9a52, 0x1e2f,
+ 0x9a55, 0x1c58,
+ 0x9a57, 0x1c5b,
+ 0x9a5a, 0x06bb,
+ 0x9a5b, 0x1c5a,
+ 0x9a5f, 0x1c5c,
+ 0x9a62, 0x1c5d,
+ 0x9a64, 0x1c5f,
+ 0x9a65, 0x1c5e,
+ 0x9a69, 0x1c60,
+ 0x9a6a, 0x1c62,
+ 0x9a6b, 0x1c61,
+ 0x9aa8, 0x080e,
+ 0x9aad, 0x1c63,
+ 0x9ab0, 0x1c64,
+ 0x9ab8, 0x059a,
+ 0x9abc, 0x1c65,
+ 0x9ac0, 0x1c66,
+ 0x9ac4, 0x0a37,
+ 0x9acf, 0x1c67,
+ 0x9ad1, 0x1c68,
+ 0x9ad3, 0x1c69,
+ 0x9ad8, 0x07f4,
+ 0x9ad9, 0x2201,
+ 0x9adc, 0x2202,
+ 0x9ade, 0x1c6b,
+ 0x9ae2, 0x1c6d,
+ 0x9ae6, 0x1c6f,
+ 0x9aea, 0x0d45,
+ 0x9aeb, 0x1c71,
+ 0x9aed, 0x0d98,
+ 0x9aee, 0x1c72,
+ 0x9aef, 0x1c70,
+ 0x9af1, 0x1c74,
+ 0x9af4, 0x1c73,
+ 0x9af7, 0x1c75,
+ 0x9afb, 0x1c76,
+ 0x9b06, 0x1c77,
+ 0x9b18, 0x1c78,
+ 0x9b1a, 0x1c79,
+ 0x9b1f, 0x1c7a,
+ 0x9b22, 0x1c7b,
+ 0x9b25, 0x1c7d,
+ 0x9b27, 0x1c7e,
+ 0x9b2e, 0x1c82,
+ 0x9b31, 0x14d4,
+ 0x9b32, 0x1c84,
+ 0x9b3b, 0x17a9,
+ 0x9b3c, 0x064e,
+ 0x9b41, 0x057f,
+ 0x9b42, 0x0822,
+ 0x9b43, 0x1c86,
+ 0x9b44, 0x1c85,
+ 0x9b45, 0x0eb1,
+ 0x9b4d, 0x1c88,
+ 0x9b4f, 0x1c87,
+ 0x9b51, 0x1c8a,
+ 0x9b54, 0x0e90,
+ 0x9b58, 0x1c8b,
+ 0x9b5a, 0x0695,
+ 0x9b6f, 0x0fcb,
+ 0x9b72, 0x2204,
+ 0x9b74, 0x1c8c,
+ 0x9b75, 0x2203,
+ 0x9b83, 0x1c8e,
+ 0x9b8e, 0x0482,
+ 0x9b8f, 0x2205,
+ 0x9b91, 0x1c8f,
+ 0x9b92, 0x0dfb,
+ 0x9b93, 0x1c8d,
+ 0x9b96, 0x1c90,
+ 0x9b9f, 0x1c92,
+ 0x9ba8, 0x1c94,
+ 0x9baa, 0x0e9c,
+ 0x9bab, 0x087b,
+ 0x9bad, 0x086a,
+ 0x9bae, 0x0ab1,
+ 0x9bb1, 0x2206,
+ 0x9bb4, 0x1c95,
+ 0x9bb9, 0x1c98,
+ 0x9bbb, 0x2207,
+ 0x9bc0, 0x1c96,
+ 0x9bc6, 0x1c99,
+ 0x9bc9, 0x07a5,
+ 0x9bca, 0x1c97,
+ 0x9bcf, 0x1c9a,
+ 0x9bd1, 0x1c9b,
+ 0x9bd4, 0x1ca0,
+ 0x9bd6, 0x0878,
+ 0x9bdb, 0x0b44,
+ 0x9be1, 0x1ca1,
+ 0x9be2, 0x1c9e,
+ 0x9be3, 0x1c9d,
+ 0x9be4, 0x1c9f,
+ 0x9be8, 0x0735,
+ 0x9bf0, 0x1ca5,
+ 0x9bf1, 0x1ca4,
+ 0x9bf2, 0x1ca3,
+ 0x9bf5, 0x0477,
+ 0x9c00, 0x2208,
+ 0x9c04, 0x1caf,
+ 0x9c06, 0x1cab,
+ 0x9c08, 0x1cac,
+ 0x9c09, 0x1ca8,
+ 0x9c0a, 0x1cae,
+ 0x9c0c, 0x1caa,
+ 0x9c0d, 0x05c0,
+ 0x9c10, 0x0ff2,
+ 0x9c12, 0x1cad,
+ 0x9c13, 0x1ca9,
+ 0x9c14, 0x1ca7,
+ 0x9c15, 0x1ca6,
+ 0x9c1b, 0x1cb1,
+ 0x9c21, 0x1cb4,
+ 0x9c24, 0x1cb3,
+ 0x9c25, 0x1cb2,
+ 0x9c2d, 0x0dbb,
+ 0x9c2e, 0x1cb0,
+ 0x9c2f, 0x04b7,
+ 0x9c30, 0x1cb5,
+ 0x9c32, 0x1cb7,
+ 0x9c39, 0x05cd,
+ 0x9c3a, 0x1ca2,
+ 0x9c3b, 0x04d9,
+ 0x9c3e, 0x1cb9,
+ 0x9c46, 0x1cb8,
+ 0x9c47, 0x1cb6,
+ 0x9c48, 0x0b6b,
+ 0x9c52, 0x0e9e,
+ 0x9c57, 0x0fa2,
+ 0x9c5a, 0x1cba,
+ 0x9c60, 0x1cbb,
+ 0x9c67, 0x1cbc,
+ 0x9c76, 0x1cbd,
+ 0x9c78, 0x1cbe,
+ 0x9ce5, 0x0bd7,
+ 0x9ce7, 0x1cbf,
+ 0x9ce9, 0x0d4b,
+ 0x9ceb, 0x1cc4,
+ 0x9cec, 0x1cc0,
+ 0x9cf0, 0x1cc1,
+ 0x9cf3, 0x0e5f,
+ 0x9cf4, 0x0ed0,
+ 0x9cf6, 0x0ca8,
+ 0x9d03, 0x1cc5,
+ 0x9d06, 0x1cc6,
+ 0x9d07, 0x0c96,
+ 0x9d08, 0x1cc3,
+ 0x9d09, 0x1cc2,
+ 0x9d0e, 0x052a,
+ 0x9d12, 0x1cce,
+ 0x9d15, 0x1ccd,
+ 0x9d1b, 0x0517,
+ 0x9d1f, 0x1ccb,
+ 0x9d23, 0x1cca,
+ 0x9d26, 0x1cc8,
+ 0x9d28, 0x05d9,
+ 0x9d2a, 0x1cc7,
+ 0x9d2b, 0x08de,
+ 0x9d2c, 0x0529,
+ 0x9d3b, 0x07f5,
+ 0x9d3e, 0x1cd1,
+ 0x9d3f, 0x1cd0,
+ 0x9d41, 0x1ccf,
+ 0x9d44, 0x1ccc,
+ 0x9d46, 0x1cd2,
+ 0x9d48, 0x1cd3,
+ 0x9d50, 0x1cd8,
+ 0x9d51, 0x1cd7,
+ 0x9d59, 0x1cd9,
+ 0x9d5c, 0x04cf,
+ 0x9d5d, 0x1cd4,
+ 0x9d60, 0x0806,
+ 0x9d61, 0x0ec5,
+ 0x9d64, 0x1cd6,
+ 0x9d6b, 0x220a,
+ 0x9d6c, 0x0e60,
+ 0x9d6f, 0x1cde,
+ 0x9d70, 0x2209,
+ 0x9d72, 0x1cda,
+ 0x9d7a, 0x1cdf,
+ 0x9d87, 0x1cdc,
+ 0x9d89, 0x1cdb,
+ 0x9d8f, 0x0732,
+ 0x9d9a, 0x1ce0,
+ 0x9da4, 0x1ce1,
+ 0x9da9, 0x1ce2,
+ 0x9dab, 0x1cdd,
+ 0x9daf, 0x1cc9,
+ 0x9db2, 0x1ce3,
+ 0x9db4, 0x0bfd,
+ 0x9db8, 0x1ce7,
+ 0x9dba, 0x1ce8,
+ 0x9dbb, 0x1ce6,
+ 0x9dc1, 0x1ce5,
+ 0x9dc2, 0x1ceb,
+ 0x9dc4, 0x1ce4,
+ 0x9dc6, 0x1ce9,
+ 0x9dcf, 0x1cea,
+ 0x9dd3, 0x1ced,
+ 0x9dd7, 0x1dde,
+ 0x9dd9, 0x1cec,
+ 0x9de6, 0x1cef,
+ 0x9ded, 0x1cf0,
+ 0x9def, 0x1cf1,
+ 0x9df2, 0x0fef,
+ 0x9df8, 0x1cee,
+ 0x9df9, 0x0b4b,
+ 0x9dfa, 0x085d,
+ 0x9dfd, 0x1cf2,
+ 0x9e19, 0x220c,
+ 0x9e1a, 0x1cf3,
+ 0x9e1e, 0x1cf5,
+ 0x9e75, 0x1cf6,
+ 0x9e78, 0x0768,
+ 0x9e79, 0x1cf7,
+ 0x9e7c, 0x1dfd,
+ 0x9e7d, 0x1cf8,
+ 0x9e7f, 0x08db,
+ 0x9e81, 0x1cf9,
+ 0x9e88, 0x1cfa,
+ 0x9e8b, 0x1cfb,
+ 0x9e91, 0x1cff,
+ 0x9e92, 0x1cfd,
+ 0x9e93, 0x0fe2,
+ 0x9e95, 0x1cfe,
+ 0x9e97, 0x0fb7,
+ 0x9e9d, 0x1d00,
+ 0x9e9f, 0x0fa3,
+ 0x9ea5, 0x1d01,
+ 0x9ea6, 0x0d34,
+ 0x9ea9, 0x1d02,
+ 0x9eaa, 0x1d04,
+ 0x9ead, 0x1d05,
+ 0x9eb4, 0x1e02,
+ 0x9eb5, 0x1e75,
+ 0x9eb8, 0x1d03,
+ 0x9eb9, 0x07ff,
+ 0x9eba, 0x0ed9,
+ 0x9ebb, 0x0e91,
+ 0x9ebc, 0x1284,
+ 0x9ebe, 0x14ff,
+ 0x9ebf, 0x0ea9,
+ 0x9ec4, 0x052b,
+ 0x9ecc, 0x1d07,
+ 0x9ecd, 0x066a,
+ 0x9ece, 0x1d08,
+ 0x9ed1, 0x220d,
+ 0x9ed2, 0x0807,
+ 0x9ed4, 0x1d0b,
+ 0x9ed8, 0x160d,
+ 0x9ed9, 0x0ee7,
+ 0x9edb, 0x0b43,
+ 0x9edc, 0x1d0c,
+ 0x9edd, 0x1d0e,
+ 0x9ede, 0x1d0d,
+ 0x9ee0, 0x1d0f,
+ 0x9ee5, 0x1d10,
+ 0x9ee8, 0x1d11,
+ 0x9eef, 0x1d12,
+ 0x9ef4, 0x1d13,
+ 0x9ef6, 0x1d14,
+ 0x9ef9, 0x1d16,
+ 0x9efb, 0x1d17,
+ 0x9f07, 0x1d1a,
+ 0x9f0e, 0x0c1e,
+ 0x9f13, 0x0791,
+ 0x9f15, 0x1d1d,
+ 0x9f20, 0x0acf,
+ 0x9f21, 0x1d1e,
+ 0x9f2c, 0x1d1f,
+ 0x9f3b, 0x0d93,
+ 0x9f3e, 0x1d20,
+ 0x9f4a, 0x1d21,
+ 0x9f4b, 0x170a,
+ 0x9f4e, 0x1a7b,
+ 0x9f4f, 0x1c06,
+ 0x9f52, 0x1d22,
+ 0x9f54, 0x1d23,
+ 0x9f5f, 0x1d25,
+ 0x9f62, 0x0fb8,
+ 0x9f63, 0x1d24,
+ 0x9f66, 0x1d28,
+ 0x9f6a, 0x1d2b,
+ 0x9f6c, 0x1d2a,
+ 0x9f72, 0x1d2d,
+ 0x9f76, 0x1d2e,
+ 0x9f77, 0x1d2c,
+ 0x9f8d, 0x0f7e,
+ 0x9f95, 0x1d2f,
+ 0x9f9c, 0x1d30,
+ 0x9f9d, 0x1727,
+ 0x9fa0, 0x1d31,
+ 0xf929, 0x2129,
+ 0xf9dc, 0x21ee,
+ 0xfa0e, 0x20da,
+ 0xfa0f, 0x20e5,
+ 0xfa11, 0x20fb,
+ 0xfa12, 0x2121,
+ 0xfa13, 0x2131,
+ 0xfa14, 0x2133,
+ 0xfa15, 0x215e,
+ 0xfa16, 0x2164,
+ 0xfa17, 0x217b,
+ 0xfa18, 0x2183,
+ 0xfa1b, 0x2187,
+ 0xfa1c, 0x218b,
+ 0xfa1d, 0x218e,
+ 0xfa1e, 0x2197,
+ 0xfa1f, 0x21a2,
+ 0xfa20, 0x21a4,
+ 0xfa22, 0x21ae,
+ 0xfa23, 0x21b6,
+ 0xfa24, 0x21b8,
+ 0xfa26, 0x21bc,
+ 0xfa27, 0x21d8,
+ 0xfa28, 0x21df,
+ 0xfa29, 0x21ef,
+ 0xfa2a, 0x21fb,
+ 0xfa2c, 0x21fe,
+ 0xfa2d, 0x220b,
+ 0xfb01, 0x0070,
+ 0xfe30, 0x1eda,
+ 0xfe31, 0x1ed4,
+ 0xfe33, 0x1ed2,
+ 0xfe35, 0x1edb,
+ 0xfe37, 0x1ee1,
+ 0xfe39, 0x1edd,
+ 0xfe3b, 0x1eeb,
+ 0xfe3d, 0x1ee5,
+ 0xfe3f, 0x1ee3,
+ 0xfe41, 0x1ee7,
+ 0xff01, 0x0282,
+ 0xff02, 0x1f47,
+ 0xff03, 0x02cc,
+ 0xff04, 0x02c8,
+ 0xff05, 0x02cb,
+ 0xff06, 0x02cd,
+ 0xff07, 0x1f46,
+ 0xff08, 0x02a2,
+ 0xff0a, 0x02ce,
+ 0xff0b, 0x02b4,
+ 0xff0c, 0x027c,
+ 0xff0d, 0x0296,
+ 0xff0e, 0x027d,
+ 0xff0f, 0x0297,
+ 0xff10, 0x030c,
+ 0xff1a, 0x027f,
+ 0xff1c, 0x02bb,
+ 0xff1d, 0x02b9,
+ 0xff1e, 0x02bc,
+ 0xff1f, 0x0281,
+ 0xff20, 0x02cf,
+ 0xff21, 0x0316,
+ 0xff3b, 0x02a6,
+ 0xff3c, 0x0298,
+ 0xff3d, 0x02a7,
+ 0xff3e, 0x0288,
+ 0xff3f, 0x028a,
+ 0xff40, 0x0286,
+ 0xff41, 0x0330,
+ 0xff5b, 0x02a8,
+ 0xff5c, 0x029b,
+ 0xff5d, 0x02a9,
+ 0xff5e, 0x0299,
+ 0xff61, 0x0147,
+ 0xffe0, 0x02c9,
+ 0xffe2, 0x02ef,
+ 0xffe3, 0x0289,
+ 0xffe4, 0x1f45,
+ 0xffe5, 0x02c7,
+ 0xffe8, 0x0143,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12UniJISUCS2HEnc16 = {
+ 0,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12UniJISUCS2HMap2, 6963
+};
+
+static Gushort japan12UniJISUCS2VMap2[14216] = {
+ 0x0000, 0x0000,
+ 0x0020, 0x0001,
+ 0x005c, 0x0061,
+ 0x005d, 0x003e,
+ 0x00a1, 0x0065,
+ 0x00a4, 0x006b,
+ 0x00a5, 0x003d,
+ 0x00a6, 0x0063,
+ 0x00a7, 0x02d0,
+ 0x00a8, 0x0287,
+ 0x00a9, 0x0098,
+ 0x00aa, 0x008c,
+ 0x00ab, 0x006d,
+ 0x00ac, 0x0099,
+ 0x00ad, 0x0097,
+ 0x00ae, 0x009a,
+ 0x00af, 0x0081,
+ 0x00b0, 0x02c3,
+ 0x00b1, 0x02b6,
+ 0x00b2, 0x009d,
+ 0x00b4, 0x0285,
+ 0x00b5, 0x009f,
+ 0x00b6, 0x030a,
+ 0x00b7, 0x0075,
+ 0x00b8, 0x0086,
+ 0x00b9, 0x00a0,
+ 0x00ba, 0x0090,
+ 0x00bb, 0x007b,
+ 0x00bc, 0x00a1,
+ 0x00bf, 0x007e,
+ 0x00c0, 0x00a4,
+ 0x00c6, 0x008b,
+ 0x00c7, 0x00aa,
+ 0x00d7, 0x02b7,
+ 0x00d8, 0x008e,
+ 0x00d9, 0x00bb,
+ 0x00df, 0x0096,
+ 0x00e0, 0x00c1,
+ 0x00e6, 0x0091,
+ 0x00e7, 0x00c7,
+ 0x00f7, 0x02b8,
+ 0x00f8, 0x0094,
+ 0x00f9, 0x00d8,
+ 0x0131, 0x0092,
+ 0x0141, 0x008d,
+ 0x0142, 0x0093,
+ 0x0152, 0x008f,
+ 0x0153, 0x0095,
+ 0x0160, 0x00df,
+ 0x0161, 0x00e3,
+ 0x0178, 0x00e0,
+ 0x017d, 0x00e1,
+ 0x017e, 0x00e5,
+ 0x01c0, 0x0063,
+ 0x0300, 0x0041,
+ 0x0301, 0x007f,
+ 0x0303, 0x005f,
+ 0x0304, 0x0081,
+ 0x0305, 0x00e2,
+ 0x0306, 0x0082,
+ 0x030a, 0x0085,
+ 0x030b, 0x0087,
+ 0x030c, 0x0089,
+ 0x0327, 0x0086,
+ 0x0328, 0x0088,
+ 0x0332, 0x0040,
+ 0x0336, 0x008a,
+ 0x0361, 0x02f6,
+ 0x0391, 0x03f3,
+ 0x03a3, 0x0404,
+ 0x03b1, 0x040b,
+ 0x03c3, 0x041c,
+ 0x0401, 0x0429,
+ 0x0410, 0x0423,
+ 0x0416, 0x042a,
+ 0x0436, 0x044b,
+ 0x0451, 0x044a,
+ 0x2002, 0x00e7,
+ 0x2003, 0x0279,
+ 0x2010, 0x000e,
+ 0x2011, 0x000e,
+ 0x2012, 0x0072,
+ 0x2013, 0x0072,
+ 0x2014, 0x008a,
+ 0x2015, 0x0295,
+ 0x2016, 0x029a,
+ 0x2018, 0x029e,
+ 0x201a, 0x0078,
+ 0x201c, 0x02a0,
+ 0x201e, 0x0079,
+ 0x2020, 0x0308,
+ 0x2022, 0x0077,
+ 0x2025, 0x029d,
+ 0x2026, 0x029c,
+ 0x2030, 0x0304,
+ 0x2032, 0x02c4,
+ 0x2039, 0x006e,
+ 0x203b, 0x02de,
+ 0x203e, 0x0145,
+ 0x2044, 0x0068,
+ 0x20dd, 0x030b,
+ 0x2103, 0x02c6,
+ 0x2109, 0x2071,
+ 0x2113, 0x1f59,
+ 0x2116, 0x1dba,
+ 0x2121, 0x1f77,
+ 0x2122, 0x00e4,
+ 0x212b, 0x0303,
+ 0x2160, 0x1d97,
+ 0x216a, 0x2021,
+ 0x2170, 0x1f9c,
+ 0x217a, 0x206a,
+ 0x217f, 0x206f,
+ 0x2190, 0x02e1,
+ 0x2192, 0x02e0,
+ 0x2193, 0x02e3,
+ 0x21c4, 0x2076,
+ 0x21c6, 0x2075,
+ 0x21d2, 0x02f0,
+ 0x21d4, 0x02f1,
+ 0x21e6, 0x1f4d,
+ 0x21e7, 0x1f4c,
+ 0x21e8, 0x1f4e,
+ 0x21e9, 0x1f4b,
+ 0x2200, 0x02f2,
+ 0x2202, 0x02f7,
+ 0x2203, 0x02f3,
+ 0x2207, 0x02f8,
+ 0x2208, 0x02e5,
+ 0x220b, 0x02e6,
+ 0x2211, 0x1dc9,
+ 0x2212, 0x02b5,
+ 0x221a, 0x02fd,
+ 0x221d, 0x02ff,
+ 0x221e, 0x02bf,
+ 0x221f, 0x1dcd,
+ 0x2220, 0x02f4,
+ 0x2225, 0x029a,
+ 0x2227, 0x02ed,
+ 0x2229, 0x02ec,
+ 0x222a, 0x02eb,
+ 0x222b, 0x0301,
+ 0x222d, 0x2003,
+ 0x222e, 0x1dc8,
+ 0x2234, 0x02c0,
+ 0x2235, 0x0300,
+ 0x223c, 0x0299,
+ 0x223d, 0x02fe,
+ 0x2252, 0x02fa,
+ 0x2260, 0x02ba,
+ 0x2261, 0x02f9,
+ 0x2266, 0x02bd,
+ 0x226a, 0x02fb,
+ 0x2282, 0x02e9,
+ 0x2286, 0x02e7,
+ 0x22a5, 0x02f5,
+ 0x22bf, 0x1dce,
+ 0x22ee, 0x1ed9,
+ 0x22ef, 0x029c,
+ 0x2312, 0x02f6,
+ 0x2460, 0x1d83,
+ 0x2474, 0x1f87,
+ 0x2488, 0x1f7e,
+ 0x249c, 0x1fb0,
+ 0x24ea, 0x2020,
+ 0x2500, 0x1d37,
+ 0x2550, 0x203b,
+ 0x255e, 0x203c,
+ 0x2561, 0x203e,
+ 0x256a, 0x203d,
+ 0x256d, 0x2037,
+ 0x256f, 0x203a,
+ 0x2570, 0x2039,
+ 0x2571, 0x2045,
+ 0x2581, 0x2026,
+ 0x2589, 0x2034,
+ 0x258a, 0x2033,
+ 0x258b, 0x2032,
+ 0x258c, 0x2031,
+ 0x258d, 0x2030,
+ 0x258e, 0x202f,
+ 0x258f, 0x202e,
+ 0x2594, 0x2035,
+ 0x25a0, 0x02d9,
+ 0x25a1, 0x02d8,
+ 0x25a2, 0x1f4f,
+ 0x25b2, 0x02db,
+ 0x25b3, 0x02da,
+ 0x25b7, 0x1f4a,
+ 0x25bc, 0x02dd,
+ 0x25bd, 0x02dc,
+ 0x25c1, 0x1f49,
+ 0x25c6, 0x02d7,
+ 0x25c7, 0x02d6,
+ 0x25c9, 0x2012,
+ 0x25cb, 0x02d3,
+ 0x25ce, 0x02d5,
+ 0x25cf, 0x02d4,
+ 0x25e2, 0x203f,
+ 0x25e4, 0x2042,
+ 0x25e5, 0x2041,
+ 0x25ef, 0x030b,
+ 0x2600, 0x2017,
+ 0x2605, 0x02d2,
+ 0x2606, 0x02d1,
+ 0x260e, 0x1f78,
+ 0x261c, 0x201c,
+ 0x261e, 0x201b,
+ 0x261f, 0x201e,
+ 0x2640, 0x02c2,
+ 0x2642, 0x02c1,
+ 0x2660, 0x2013,
+ 0x2661, 0x1f51,
+ 0x2662, 0x1f53,
+ 0x2663, 0x2015,
+ 0x2664, 0x1f52,
+ 0x2665, 0x2014,
+ 0x2666, 0x2016,
+ 0x2667, 0x1f50,
+ 0x266a, 0x0307,
+ 0x266d, 0x0306,
+ 0x266f, 0x0305,
+ 0x2776, 0x205e,
+ 0x27a1, 0x200e,
+ 0x3000, 0x0279,
+ 0x3003, 0x028f,
+ 0x3004, 0x2074,
+ 0x3005, 0x0291,
+ 0x3008, 0x02aa,
+ 0x3012, 0x02df,
+ 0x3013, 0x02e4,
+ 0x3014, 0x02a4,
+ 0x301c, 0x0299,
+ 0x301d, 0x1db8,
+ 0x301f, 0x1db9,
+ 0x3020, 0x1f7a,
+ 0x3036, 0x1f79,
+ 0x3041, 0x034a,
+ 0x3094, 0x1f16,
+ 0x309b, 0x0283,
+ 0x309d, 0x028d,
+ 0x30a1, 0x039d,
+ 0x30f7, 0x2079,
+ 0x30fb, 0x027e,
+ 0x30fc, 0x0294,
+ 0x30fd, 0x028b,
+ 0x322a, 0x2006,
+ 0x3230, 0x2005,
+ 0x3231, 0x1dc2,
+ 0x3233, 0x1fcf,
+ 0x3234, 0x1fcd,
+ 0x3235, 0x1fd4,
+ 0x3236, 0x1fd3,
+ 0x3237, 0x200c,
+ 0x3238, 0x1fce,
+ 0x3239, 0x1dc4,
+ 0x323a, 0x1fd7,
+ 0x323b, 0x1fd5,
+ 0x323c, 0x1fd0,
+ 0x323d, 0x1fcb,
+ 0x323e, 0x1fd2,
+ 0x323f, 0x1fcc,
+ 0x3240, 0x1fd6,
+ 0x3241, 0x200d,
+ 0x3242, 0x1fd1,
+ 0x3243, 0x1fca,
+ 0x3291, 0x1fe1,
+ 0x3292, 0x1fe0,
+ 0x3293, 0x1fe2,
+ 0x3294, 0x1fdc,
+ 0x3296, 0x1fe5,
+ 0x3298, 0x1fde,
+ 0x3299, 0x201f,
+ 0x329d, 0x207f,
+ 0x329e, 0x1fff,
+ 0x32a4, 0x1dbd,
+ 0x32a9, 0x1fda,
+ 0x32aa, 0x1fdd,
+ 0x32ab, 0x1fdf,
+ 0x32ac, 0x1fe3,
+ 0x32ad, 0x1fd9,
+ 0x32ae, 0x1fe4,
+ 0x32af, 0x1fdb,
+ 0x32b0, 0x1fd8,
+ 0x3300, 0x1f70,
+ 0x3303, 0x1f6a,
+ 0x3305, 0x1ff7,
+ 0x330d, 0x1dab,
+ 0x3314, 0x1da2,
+ 0x3315, 0x1f69,
+ 0x3316, 0x1f67,
+ 0x3318, 0x1f68,
+ 0x331e, 0x1f73,
+ 0x3322, 0x1f66,
+ 0x3323, 0x1f6b,
+ 0x3326, 0x1dac,
+ 0x3327, 0x1da6,
+ 0x332a, 0x1f74,
+ 0x332b, 0x1dae,
+ 0x3331, 0x1f71,
+ 0x3333, 0x2087,
+ 0x3336, 0x1da8,
+ 0x3339, 0x1f6e,
+ 0x333b, 0x1f6f,
+ 0x3342, 0x1f6d,
+ 0x3347, 0x1f72,
+ 0x3349, 0x1da1,
+ 0x334a, 0x1daf,
+ 0x334d, 0x1da4,
+ 0x334e, 0x2088,
+ 0x3351, 0x1da9,
+ 0x3357, 0x1f6c,
+ 0x337b, 0x2083,
+ 0x337c, 0x1dc7,
+ 0x337d, 0x1dc6,
+ 0x337e, 0x1dc5,
+ 0x337f, 0x1f76,
+ 0x3385, 0x1f5f,
+ 0x3388, 0x2000,
+ 0x338e, 0x1db4,
+ 0x3390, 0x1f63,
+ 0x3396, 0x1f65,
+ 0x3397, 0x1f58,
+ 0x3398, 0x1f5a,
+ 0x339c, 0x1db1,
+ 0x339f, 0x1ffa,
+ 0x33a0, 0x1f54,
+ 0x33a1, 0x1db7,
+ 0x33a2, 0x1f55,
+ 0x33a3, 0x1ffb,
+ 0x33a4, 0x1f56,
+ 0x33a6, 0x1ffc,
+ 0x33b0, 0x1f5e,
+ 0x33b1, 0x1f5d,
+ 0x33b2, 0x1f5c,
+ 0x33b3, 0x1f5b,
+ 0x33c4, 0x1db6,
+ 0x33c8, 0x2002,
+ 0x33cb, 0x1f62,
+ 0x33cc, 0x1ff6,
+ 0x33cd, 0x1dbb,
+ 0x33d4, 0x1f64,
+ 0x4e00, 0x04b0,
+ 0x4e01, 0x0bb8,
+ 0x4e03, 0x08e3,
+ 0x4e07, 0x0eaa,
+ 0x4e08, 0x09ce,
+ 0x4e09, 0x087e,
+ 0x4e0a, 0x09cd,
+ 0x4e0b, 0x053c,
+ 0x4e0d, 0x0dc6,
+ 0x4e0e, 0x0f29,
+ 0x4e10, 0x0ffb,
+ 0x4e11, 0x04d1,
+ 0x4e14, 0x05cc,
+ 0x4e15, 0x0ffc,
+ 0x4e16, 0x0a48,
+ 0x4e17, 0x10d7,
+ 0x4e18, 0x0670,
+ 0x4e19, 0x0e0a,
+ 0x4e1e, 0x09cf,
+ 0x4e21, 0x0f86,
+ 0x4e26, 0x0e12,
+ 0x4e28, 0x20b3,
+ 0x4e2a, 0x0ffd,
+ 0x4e2d, 0x0ba4,
+ 0x4e31, 0x0ffe,
+ 0x4e32, 0x06f2,
+ 0x4e36, 0x0fff,
+ 0x4e38, 0x0619,
+ 0x4e39, 0x0b6e,
+ 0x4e3b, 0x0913,
+ 0x4e3c, 0x1000,
+ 0x4e3f, 0x1001,
+ 0x4e42, 0x1002,
+ 0x4e43, 0x0ceb,
+ 0x4e45, 0x0671,
+ 0x4e4b, 0x0ced,
+ 0x4e4d, 0x0cbb,
+ 0x4e4e, 0x0777,
+ 0x4e4f, 0x0e61,
+ 0x4e55, 0x1950,
+ 0x4e56, 0x1003,
+ 0x4e57, 0x09d0,
+ 0x4e58, 0x1004,
+ 0x4e59, 0x0535,
+ 0x4e5d, 0x06dd,
+ 0x4e5e, 0x07a4,
+ 0x4e5f, 0x0ef5,
+ 0x4e62, 0x1233,
+ 0x4e71, 0x0f5a,
+ 0x4e73, 0x0cd5,
+ 0x4e7e, 0x05e1,
+ 0x4e80, 0x064f,
+ 0x4e82, 0x1005,
+ 0x4e85, 0x1006,
+ 0x4e86, 0x0f83,
+ 0x4e88, 0x0f27,
+ 0x4e89, 0x0aea,
+ 0x4e8a, 0x1008,
+ 0x4e8b, 0x08c4,
+ 0x4e8c, 0x0ccb,
+ 0x4e8e, 0x100b,
+ 0x4e91, 0x04e0,
+ 0x4e92, 0x0793,
+ 0x4e94, 0x0792,
+ 0x4e95, 0x04aa,
+ 0x4e98, 0x0ff1,
+ 0x4e99, 0x0ff0,
+ 0x4e9b, 0x0823,
+ 0x4e9c, 0x0465,
+ 0x4e9e, 0x100c,
+ 0x4ea1, 0x0e62,
+ 0x4ea2, 0x100f,
+ 0x4ea4, 0x07a6,
+ 0x4ea5, 0x04ab,
+ 0x4ea6, 0x0ea0,
+ 0x4ea8, 0x0696,
+ 0x4eab, 0x0697,
+ 0x4ead, 0x0bfe,
+ 0x4eae, 0x0f84,
+ 0x4eb0, 0x1010,
+ 0x4eb3, 0x1011,
+ 0x4eb6, 0x1012,
+ 0x4eba, 0x0a13,
+ 0x4ec0, 0x0944,
+ 0x4ec1, 0x0a14,
+ 0x4ec2, 0x1017,
+ 0x4ec4, 0x1015,
+ 0x4ec6, 0x1016,
+ 0x4ec7, 0x0672,
+ 0x4eca, 0x0813,
+ 0x4ecb, 0x0570,
+ 0x4ecd, 0x1014,
+ 0x4ece, 0x1013,
+ 0x4ecf, 0x0df9,
+ 0x4ed4, 0x0894,
+ 0x4ed5, 0x0893,
+ 0x4ed6, 0x0b1e,
+ 0x4ed7, 0x1018,
+ 0x4ed8, 0x0dc7,
+ 0x4ed9, 0x0a8b,
+ 0x4edd, 0x0290,
+ 0x4ede, 0x1019,
+ 0x4edf, 0x101b,
+ 0x4ee1, 0x20b4,
+ 0x4ee3, 0x0b45,
+ 0x4ee4, 0x0fa9,
+ 0x4ee5, 0x048e,
+ 0x4eed, 0x101a,
+ 0x4eee, 0x053e,
+ 0x4ef0, 0x06bc,
+ 0x4ef2, 0x0ba5,
+ 0x4ef6, 0x0745,
+ 0x4ef7, 0x101c,
+ 0x4efb, 0x0cda,
+ 0x4efc, 0x20b5,
+ 0x4f00, 0x20b6,
+ 0x4f01, 0x0627,
+ 0x4f03, 0x20b7,
+ 0x4f09, 0x101d,
+ 0x4f0a, 0x048f,
+ 0x4f0d, 0x0794,
+ 0x4f0e, 0x0628,
+ 0x4f0f, 0x0dec,
+ 0x4f10, 0x0d46,
+ 0x4f11, 0x0673,
+ 0x4f1a, 0x0571,
+ 0x4f1c, 0x1040,
+ 0x4f1d, 0x0c3b,
+ 0x4f2f, 0x0d22,
+ 0x4f30, 0x101f,
+ 0x4f34, 0x0d50,
+ 0x4f36, 0x0faa,
+ 0x4f38, 0x09f3,
+ 0x4f39, 0x20b8,
+ 0x4f3a, 0x0895,
+ 0x4f3c, 0x08c5,
+ 0x4f3d, 0x0540,
+ 0x4f43, 0x0bed,
+ 0x4f46, 0x0b60,
+ 0x4f47, 0x1023,
+ 0x4f4d, 0x0490,
+ 0x4f4e, 0x0bff,
+ 0x4f4f, 0x0945,
+ 0x4f50, 0x0824,
+ 0x4f51, 0x0f0e,
+ 0x4f53, 0x0b2e,
+ 0x4f55, 0x053f,
+ 0x4f56, 0x20b9,
+ 0x4f57, 0x1022,
+ 0x4f59, 0x0f28,
+ 0x4f5a, 0x101e,
+ 0x4f5b, 0x1020,
+ 0x4f5c, 0x085e,
+ 0x4f5d, 0x1021,
+ 0x4f5e, 0x11d3,
+ 0x4f69, 0x1029,
+ 0x4f6f, 0x102c,
+ 0x4f70, 0x102a,
+ 0x4f73, 0x0542,
+ 0x4f75, 0x0e0b,
+ 0x4f76, 0x1024,
+ 0x4f7b, 0x1028,
+ 0x4f7c, 0x07a7,
+ 0x4f7f, 0x0896,
+ 0x4f83, 0x05e2,
+ 0x4f86, 0x102d,
+ 0x4f88, 0x1025,
+ 0x4f8a, 0x20bb,
+ 0x4f8b, 0x0fab,
+ 0x4f8d, 0x08c6,
+ 0x4f8f, 0x1026,
+ 0x4f91, 0x102b,
+ 0x4f92, 0x20ba,
+ 0x4f94, 0x20bd,
+ 0x4f96, 0x102e,
+ 0x4f98, 0x1027,
+ 0x4f9a, 0x20bc,
+ 0x4f9b, 0x0699,
+ 0x4f9d, 0x0491,
+ 0x4fa0, 0x069a,
+ 0x4fa1, 0x0541,
+ 0x4fab, 0x11d4,
+ 0x4fad, 0x0ea7,
+ 0x4fae, 0x0de0,
+ 0x4faf, 0x07a8,
+ 0x4fb5, 0x09f5,
+ 0x4fb6, 0x0f7f,
+ 0x4fbf, 0x0e28,
+ 0x4fc2, 0x070e,
+ 0x4fc3, 0x0b05,
+ 0x4fc4, 0x0564,
+ 0x4fc9, 0x20ac,
+ 0x4fca, 0x095d,
+ 0x4fcd, 0x20be,
+ 0x4fce, 0x1032,
+ 0x4fd0, 0x1037,
+ 0x4fd1, 0x1035,
+ 0x4fd4, 0x1030,
+ 0x4fd7, 0x0b0f,
+ 0x4fd8, 0x1033,
+ 0x4fda, 0x1036,
+ 0x4fdb, 0x1034,
+ 0x4fdd, 0x0e2d,
+ 0x4fdf, 0x1031,
+ 0x4fe0, 0x1dec,
+ 0x4fe1, 0x09f4,
+ 0x4fe3, 0x0ea1,
+ 0x4fe4, 0x1038,
+ 0x4fee, 0x092e,
+ 0x4fef, 0x1046,
+ 0x4ff3, 0x0d06,
+ 0x4ff5, 0x0da8,
+ 0x4ff6, 0x1041,
+ 0x4ff8, 0x0e40,
+ 0x4ffa, 0x0536,
+ 0x4ffe, 0x1045,
+ 0x4fff, 0x20c1,
+ 0x5005, 0x103f,
+ 0x5006, 0x1048,
+ 0x5009, 0x0ad4,
+ 0x500b, 0x0778,
+ 0x500d, 0x0d12,
+ 0x500f, 0x1600,
+ 0x5011, 0x1047,
+ 0x5012, 0x0c57,
+ 0x5014, 0x103c,
+ 0x5016, 0x07aa,
+ 0x5019, 0x07a9,
+ 0x501a, 0x103a,
+ 0x501e, 0x20c2,
+ 0x501f, 0x0906,
+ 0x5021, 0x1042,
+ 0x5022, 0x20c0,
+ 0x5023, 0x0e3f,
+ 0x5024, 0x0b8b,
+ 0x5025, 0x103e,
+ 0x5026, 0x0747,
+ 0x5028, 0x103b,
+ 0x5029, 0x1043,
+ 0x502a, 0x103d,
+ 0x502b, 0x0f99,
+ 0x502c, 0x1044,
+ 0x502d, 0x0fe7,
+ 0x5036, 0x06de,
+ 0x5039, 0x0746,
+ 0x5040, 0x20bf,
+ 0x5042, 0x20c5,
+ 0x5043, 0x1049,
+ 0x5046, 0x20c3,
+ 0x5047, 0x104a,
+ 0x5048, 0x104e,
+ 0x5049, 0x0492,
+ 0x504f, 0x0e20,
+ 0x5050, 0x104d,
+ 0x5055, 0x104c,
+ 0x5056, 0x1050,
+ 0x505a, 0x104f,
+ 0x505c, 0x0c00,
+ 0x5065, 0x0748,
+ 0x506c, 0x1051,
+ 0x5070, 0x20c4,
+ 0x5072, 0x08f1,
+ 0x5074, 0x0b06,
+ 0x5075, 0x0c01,
+ 0x5076, 0x06ee,
+ 0x5078, 0x1052,
+ 0x507d, 0x0650,
+ 0x5080, 0x1053,
+ 0x5085, 0x1055,
+ 0x508d, 0x0e63,
+ 0x5091, 0x073c,
+ 0x5094, 0x20c6,
+ 0x5098, 0x087f,
+ 0x5099, 0x0d8b,
+ 0x509a, 0x1054,
+ 0x50ac, 0x0835,
+ 0x50ad, 0x0f2d,
+ 0x50b2, 0x1057,
+ 0x50b3, 0x105a,
+ 0x50b4, 0x1056,
+ 0x50b5, 0x0834,
+ 0x50b7, 0x0987,
+ 0x50be, 0x070f,
+ 0x50c2, 0x105b,
+ 0x50c5, 0x06c7,
+ 0x50c9, 0x1058,
+ 0x50cd, 0x0c87,
+ 0x50cf, 0x0afe,
+ 0x50d1, 0x069b,
+ 0x50d5, 0x0e7b,
+ 0x50d6, 0x105c,
+ 0x50d8, 0x20c8,
+ 0x50da, 0x0f85,
+ 0x50de, 0x105d,
+ 0x50e3, 0x1060,
+ 0x50e5, 0x105e,
+ 0x50e7, 0x0ad0,
+ 0x50ed, 0x105f,
+ 0x50ee, 0x1061,
+ 0x50f4, 0x20c7,
+ 0x50f5, 0x1063,
+ 0x50f9, 0x1062,
+ 0x50fb, 0x0e18,
+ 0x5100, 0x0651,
+ 0x5101, 0x1065,
+ 0x5104, 0x052f,
+ 0x5109, 0x1064,
+ 0x5112, 0x0920,
+ 0x5114, 0x1069,
+ 0x5115, 0x1068,
+ 0x5116, 0x1067,
+ 0x5118, 0x102f,
+ 0x511a, 0x106a,
+ 0x511f, 0x0988,
+ 0x5121, 0x106b,
+ 0x512a, 0x0f0f,
+ 0x5132, 0x0ee5,
+ 0x5137, 0x106d,
+ 0x513a, 0x106c,
+ 0x513b, 0x106f,
+ 0x513c, 0x106e,
+ 0x513f, 0x1070,
+ 0x5141, 0x04b8,
+ 0x5143, 0x0769,
+ 0x5144, 0x0711,
+ 0x5145, 0x0946,
+ 0x5146, 0x0bb9,
+ 0x5147, 0x069c,
+ 0x5148, 0x0a8c,
+ 0x5149, 0x07ab,
+ 0x514a, 0x20c9,
+ 0x514b, 0x0800,
+ 0x514c, 0x1073,
+ 0x514d, 0x0ed4,
+ 0x514e, 0x0c40,
+ 0x5150, 0x08c7,
+ 0x5152, 0x1072,
+ 0x5154, 0x1074,
+ 0x515a, 0x0c58,
+ 0x515c, 0x05d3,
+ 0x5162, 0x1075,
+ 0x5164, 0x20ca,
+ 0x5165, 0x0cd6,
+ 0x5168, 0x0ab6,
+ 0x5169, 0x1077,
+ 0x516b, 0x0d40,
+ 0x516c, 0x07ac,
+ 0x516d, 0x0fe1,
+ 0x516e, 0x1079,
+ 0x5171, 0x069e,
+ 0x5175, 0x0e0c,
+ 0x5176, 0x0b16,
+ 0x5177, 0x06e9,
+ 0x5178, 0x0c2f,
+ 0x517c, 0x0749,
+ 0x5180, 0x107a,
+ 0x5182, 0x107b,
+ 0x5185, 0x0cba,
+ 0x5186, 0x0501,
+ 0x5189, 0x107e,
+ 0x518a, 0x086d,
+ 0x518c, 0x107d,
+ 0x518d, 0x0836,
+ 0x518f, 0x107f,
+ 0x5190, 0x185b,
+ 0x5191, 0x1080,
+ 0x5192, 0x0e6f,
+ 0x5193, 0x1081,
+ 0x5195, 0x1082,
+ 0x5197, 0x09d1,
+ 0x5199, 0x08f8,
+ 0x519d, 0x20cb,
+ 0x51a0, 0x05e3,
+ 0x51a2, 0x1086,
+ 0x51a4, 0x1084,
+ 0x51a5, 0x0ec9,
+ 0x51a6, 0x1085,
+ 0x51a8, 0x0dcc,
+ 0x51a9, 0x1087,
+ 0x51ac, 0x0c59,
+ 0x51b0, 0x108d,
+ 0x51b1, 0x108b,
+ 0x51b3, 0x108a,
+ 0x51b4, 0x0853,
+ 0x51b5, 0x108e,
+ 0x51b6, 0x0ef6,
+ 0x51b7, 0x0fac,
+ 0x51bd, 0x108f,
+ 0x51be, 0x20cc,
+ 0x51c4, 0x0a4c,
+ 0x51c5, 0x1090,
+ 0x51c6, 0x0964,
+ 0x51c9, 0x1091,
+ 0x51cb, 0x0bba,
+ 0x51cc, 0x0f87,
+ 0x51cd, 0x0c5a,
+ 0x51d6, 0x10da,
+ 0x51db, 0x1092,
+ 0x51dc, 0x205c,
+ 0x51dd, 0x06bd,
+ 0x51e0, 0x1093,
+ 0x51e1, 0x0e8c,
+ 0x51e6, 0x0972,
+ 0x51e7, 0x0b5c,
+ 0x51e9, 0x1095,
+ 0x51ea, 0x0cbc,
+ 0x51ec, 0x20cd,
+ 0x51ed, 0x1096,
+ 0x51f0, 0x1097,
+ 0x51f1, 0x058c,
+ 0x51f5, 0x1098,
+ 0x51f6, 0x069f,
+ 0x51f8, 0x0ca4,
+ 0x51f9, 0x051c,
+ 0x51fa, 0x095a,
+ 0x51fd, 0x0d35,
+ 0x51fe, 0x1099,
+ 0x5200, 0x0c5b,
+ 0x5203, 0x0a15,
+ 0x5204, 0x109a,
+ 0x5206, 0x0dfc,
+ 0x5207, 0x0a7e,
+ 0x5208, 0x05de,
+ 0x520a, 0x05e5,
+ 0x520b, 0x109b,
+ 0x520e, 0x109d,
+ 0x5211, 0x0710,
+ 0x5214, 0x109c,
+ 0x5215, 0x20ce,
+ 0x5217, 0x0fbb,
+ 0x521d, 0x0973,
+ 0x5224, 0x0d51,
+ 0x5225, 0x0e1c,
+ 0x5227, 0x109e,
+ 0x5229, 0x0f62,
+ 0x522a, 0x109f,
+ 0x522e, 0x10a0,
+ 0x5230, 0x0c78,
+ 0x5233, 0x10a1,
+ 0x5236, 0x0a4d,
+ 0x5237, 0x086e,
+ 0x5238, 0x074a,
+ 0x5239, 0x10a2,
+ 0x523a, 0x0897,
+ 0x523b, 0x0801,
+ 0x5243, 0x0c02,
+ 0x5244, 0x10a4,
+ 0x5247, 0x0b07,
+ 0x524a, 0x085f,
+ 0x524b, 0x10a5,
+ 0x524d, 0x0ab2,
+ 0x524f, 0x10a3,
+ 0x5254, 0x10a8,
+ 0x5256, 0x0e64,
+ 0x525b, 0x07f6,
+ 0x525d, 0x1e5e,
+ 0x525e, 0x10a7,
+ 0x5263, 0x074b,
+ 0x5264, 0x084e,
+ 0x5265, 0x0d23,
+ 0x5269, 0x10ab,
+ 0x526a, 0x10a9,
+ 0x526f, 0x0ded,
+ 0x5270, 0x09d2,
+ 0x5271, 0x10b2,
+ 0x5272, 0x05c2,
+ 0x5273, 0x10ac,
+ 0x5274, 0x10aa,
+ 0x5275, 0x0ad1,
+ 0x527d, 0x10ae,
+ 0x527f, 0x10ad,
+ 0x5283, 0x05a2,
+ 0x5287, 0x0736,
+ 0x5288, 0x10b3,
+ 0x5289, 0x0f75,
+ 0x528d, 0x10af,
+ 0x5291, 0x10b4,
+ 0x5292, 0x10b1,
+ 0x5294, 0x10b0,
+ 0x529b, 0x0f97,
+ 0x529c, 0x20cf,
+ 0x529f, 0x07ad,
+ 0x52a0, 0x0543,
+ 0x52a3, 0x0fbc,
+ 0x52a6, 0x20d0,
+ 0x52a9, 0x097f,
+ 0x52aa, 0x0c52,
+ 0x52ab, 0x07f7,
+ 0x52ac, 0x10b7,
+ 0x52af, 0x217d,
+ 0x52b1, 0x0fad,
+ 0x52b4, 0x0fd1,
+ 0x52b5, 0x10ba,
+ 0x52b9, 0x07ae,
+ 0x52bc, 0x10b9,
+ 0x52be, 0x058d,
+ 0x52c0, 0x20d1,
+ 0x52c1, 0x10bb,
+ 0x52c3, 0x0e84,
+ 0x52c5, 0x0bd8,
+ 0x52c7, 0x0f10,
+ 0x52c9, 0x0e29,
+ 0x52cd, 0x10bc,
+ 0x52d2, 0x1bee,
+ 0x52d5, 0x0c88,
+ 0x52d7, 0x10bd,
+ 0x52d8, 0x05e6,
+ 0x52d9, 0x0ebf,
+ 0x52db, 0x20d2,
+ 0x52dd, 0x0989,
+ 0x52de, 0x10be,
+ 0x52df, 0x0e37,
+ 0x52e0, 0x10c2,
+ 0x52e2, 0x0a4e,
+ 0x52e3, 0x10bf,
+ 0x52e4, 0x06c8,
+ 0x52e6, 0x10c0,
+ 0x52e7, 0x05e7,
+ 0x52f2, 0x0704,
+ 0x52f3, 0x10c3,
+ 0x52f5, 0x10c4,
+ 0x52f8, 0x10c5,
+ 0x52fa, 0x0907,
+ 0x52fe, 0x07af,
+ 0x52ff, 0x0eea,
+ 0x5300, 0x20d3,
+ 0x5301, 0x0ef4,
+ 0x5302, 0x0ccf,
+ 0x5305, 0x0e41,
+ 0x5306, 0x10c7,
+ 0x5307, 0x20d4,
+ 0x5308, 0x10c8,
+ 0x530d, 0x10ca,
+ 0x530f, 0x10cc,
+ 0x5310, 0x10cb,
+ 0x5315, 0x10cd,
+ 0x5316, 0x053d,
+ 0x5317, 0x0e7a,
+ 0x5319, 0x086c,
+ 0x531a, 0x10ce,
+ 0x531d, 0x0adb,
+ 0x5320, 0x098a,
+ 0x5321, 0x06a1,
+ 0x5323, 0x10cf,
+ 0x5324, 0x20d5,
+ 0x532a, 0x0d6f,
+ 0x532f, 0x10d0,
+ 0x5331, 0x10d1,
+ 0x5333, 0x10d2,
+ 0x5338, 0x10d3,
+ 0x5339, 0x0d96,
+ 0x533a, 0x06e0,
+ 0x533b, 0x04a9,
+ 0x533f, 0x0c97,
+ 0x5340, 0x10d4,
+ 0x5341, 0x0947,
+ 0x5343, 0x0a8d,
+ 0x5345, 0x10d6,
+ 0x5346, 0x10d5,
+ 0x5347, 0x098b,
+ 0x5348, 0x0795,
+ 0x5349, 0x10d8,
+ 0x534a, 0x0d52,
+ 0x534d, 0x10d9,
+ 0x5351, 0x0d70,
+ 0x5352, 0x0b14,
+ 0x5353, 0x0b4e,
+ 0x5354, 0x06a0,
+ 0x5357, 0x0cc6,
+ 0x5358, 0x0b6f,
+ 0x535a, 0x0d24,
+ 0x535c, 0x0e7c,
+ 0x535e, 0x10db,
+ 0x5360, 0x0a8e,
+ 0x5366, 0x070b,
+ 0x5369, 0x10dc,
+ 0x536e, 0x10dd,
+ 0x536f, 0x04ce,
+ 0x5370, 0x04b9,
+ 0x5371, 0x0629,
+ 0x5372, 0x20d6,
+ 0x5373, 0x0b08,
+ 0x5374, 0x066b,
+ 0x5375, 0x0f5b,
+ 0x5377, 0x10e0,
+ 0x5378, 0x0537,
+ 0x537b, 0x10df,
+ 0x537f, 0x06a2,
+ 0x5382, 0x10e1,
+ 0x5384, 0x0efd,
+ 0x5393, 0x20d7,
+ 0x5396, 0x10e2,
+ 0x5398, 0x0f9a,
+ 0x539a, 0x07b0,
+ 0x539f, 0x076a,
+ 0x53a0, 0x10e3,
+ 0x53a5, 0x10e5,
+ 0x53a6, 0x10e4,
+ 0x53a8, 0x0a25,
+ 0x53a9, 0x04db,
+ 0x53ad, 0x0500,
+ 0x53ae, 0x10e6,
+ 0x53b0, 0x10e7,
+ 0x53b2, 0x20d8,
+ 0x53b3, 0x076b,
+ 0x53b6, 0x10e8,
+ 0x53bb, 0x0688,
+ 0x53c2, 0x0880,
+ 0x53c3, 0x10e9,
+ 0x53c8, 0x0ea2,
+ 0x53c9, 0x0825,
+ 0x53ca, 0x0674,
+ 0x53cb, 0x0f11,
+ 0x53cc, 0x0ad2,
+ 0x53cd, 0x0d53,
+ 0x53ce, 0x0929,
+ 0x53d4, 0x0951,
+ 0x53d6, 0x0914,
+ 0x53d7, 0x0921,
+ 0x53d9, 0x0980,
+ 0x53db, 0x0d54,
+ 0x53dd, 0x20d9,
+ 0x53df, 0x10ec,
+ 0x53e1, 0x04e5,
+ 0x53e2, 0x0ad3,
+ 0x53e3, 0x07b1,
+ 0x53e4, 0x0779,
+ 0x53e5, 0x06df,
+ 0x53e8, 0x10f0,
+ 0x53e9, 0x0b5f,
+ 0x53ea, 0x0b5e,
+ 0x53eb, 0x06a3,
+ 0x53ec, 0x098c,
+ 0x53ed, 0x10f1,
+ 0x53ee, 0x10ef,
+ 0x53ef, 0x0544,
+ 0x53f0, 0x0b46,
+ 0x53f1, 0x08e4,
+ 0x53f2, 0x0899,
+ 0x53f3, 0x04c8,
+ 0x53f6, 0x05ce,
+ 0x53f7, 0x07f8,
+ 0x53f8, 0x0898,
+ 0x53fa, 0x10f2,
+ 0x5401, 0x10f3,
+ 0x5403, 0x0663,
+ 0x5404, 0x05a4,
+ 0x5408, 0x07f9,
+ 0x5409, 0x0662,
+ 0x540a, 0x0bfb,
+ 0x540b, 0x04c7,
+ 0x540c, 0x0c89,
+ 0x540d, 0x0eca,
+ 0x540e, 0x07b3,
+ 0x540f, 0x0f63,
+ 0x5410, 0x0c41,
+ 0x5411, 0x07b2,
+ 0x541b, 0x0705,
+ 0x541d, 0x10fc,
+ 0x541f, 0x06db,
+ 0x5420, 0x0e78,
+ 0x5426, 0x0d71,
+ 0x5429, 0x10fb,
+ 0x542b, 0x061a,
+ 0x542c, 0x10f6,
+ 0x542e, 0x10f9,
+ 0x5436, 0x10fa,
+ 0x5438, 0x0675,
+ 0x5439, 0x0a27,
+ 0x543b, 0x0dfd,
+ 0x543c, 0x10f8,
+ 0x543d, 0x10f4,
+ 0x543e, 0x0797,
+ 0x5440, 0x10f5,
+ 0x5442, 0x0fca,
+ 0x5446, 0x0e42,
+ 0x5448, 0x0c04,
+ 0x5449, 0x0796,
+ 0x544a, 0x0802,
+ 0x544e, 0x10fd,
+ 0x5451, 0x0cb5,
+ 0x545f, 0x1101,
+ 0x5468, 0x092a,
+ 0x546a, 0x0922,
+ 0x5470, 0x1104,
+ 0x5471, 0x1102,
+ 0x5473, 0x0eaf,
+ 0x5475, 0x10ff,
+ 0x5476, 0x1108,
+ 0x5477, 0x1103,
+ 0x547b, 0x1106,
+ 0x547c, 0x077a,
+ 0x547d, 0x0ecb,
+ 0x5480, 0x1107,
+ 0x5484, 0x1109,
+ 0x5486, 0x110b,
+ 0x548a, 0x20dc,
+ 0x548b, 0x0860,
+ 0x548c, 0x0fe8,
+ 0x548e, 0x1100,
+ 0x548f, 0x10fe,
+ 0x5490, 0x110a,
+ 0x5492, 0x1105,
+ 0x549c, 0x20db,
+ 0x54a2, 0x110d,
+ 0x54a4, 0x1116,
+ 0x54a5, 0x110f,
+ 0x54a8, 0x1113,
+ 0x54a9, 0x20dd,
+ 0x54ab, 0x1114,
+ 0x54ac, 0x1110,
+ 0x54af, 0x1131,
+ 0x54b2, 0x0859,
+ 0x54b3, 0x058f,
+ 0x54b8, 0x110e,
+ 0x54bc, 0x1118,
+ 0x54bd, 0x04ba,
+ 0x54be, 0x1117,
+ 0x54c0, 0x0469,
+ 0x54c1, 0x0dbc,
+ 0x54c2, 0x1115,
+ 0x54c4, 0x1111,
+ 0x54c7, 0x110c,
+ 0x54c8, 0x1112,
+ 0x54c9, 0x0838,
+ 0x54d8, 0x1119,
+ 0x54e1, 0x04bb,
+ 0x54e2, 0x1122,
+ 0x54e5, 0x111a,
+ 0x54e8, 0x098d,
+ 0x54e9, 0x0e97,
+ 0x54ed, 0x1120,
+ 0x54ee, 0x111f,
+ 0x54f2, 0x0c29,
+ 0x54fa, 0x1121,
+ 0x54fd, 0x111e,
+ 0x54ff, 0x20de,
+ 0x5504, 0x04d6,
+ 0x5506, 0x0826,
+ 0x5507, 0x09f6,
+ 0x550f, 0x111c,
+ 0x5510, 0x0c5c,
+ 0x5514, 0x111d,
+ 0x5516, 0x0466,
+ 0x552e, 0x1127,
+ 0x552f, 0x0f0d,
+ 0x5531, 0x098f,
+ 0x5533, 0x112d,
+ 0x5538, 0x112c,
+ 0x5539, 0x1123,
+ 0x553e, 0x0b23,
+ 0x5540, 0x1124,
+ 0x5544, 0x0b4f,
+ 0x5545, 0x1129,
+ 0x5546, 0x098e,
+ 0x554c, 0x1126,
+ 0x554f, 0x0ef0,
+ 0x5553, 0x0712,
+ 0x5556, 0x112a,
+ 0x555c, 0x1128,
+ 0x555d, 0x112e,
+ 0x555e, 0x1dd1,
+ 0x5563, 0x1125,
+ 0x557b, 0x1134,
+ 0x557c, 0x1139,
+ 0x557e, 0x1135,
+ 0x5580, 0x1130,
+ 0x5583, 0x113a,
+ 0x5584, 0x0ab3,
+ 0x5586, 0x20df,
+ 0x5587, 0x113c,
+ 0x5589, 0x07b4,
+ 0x558a, 0x1132,
+ 0x558b, 0x0bbb,
+ 0x5598, 0x1136,
+ 0x5599, 0x112f,
+ 0x559a, 0x05e9,
+ 0x559c, 0x062a,
+ 0x559d, 0x05c3,
+ 0x559e, 0x1137,
+ 0x559f, 0x1133,
+ 0x55a7, 0x074c,
+ 0x55a8, 0x113d,
+ 0x55a9, 0x113b,
+ 0x55aa, 0x0ad5,
+ 0x55ab, 0x0664,
+ 0x55ac, 0x06a4,
+ 0x55ae, 0x1138,
+ 0x55b0, 0x06ec,
+ 0x55b6, 0x04e6,
+ 0x55c4, 0x1141,
+ 0x55c5, 0x113f,
+ 0x55c7, 0x1178,
+ 0x55d4, 0x1144,
+ 0x55da, 0x113e,
+ 0x55dc, 0x1142,
+ 0x55df, 0x1140,
+ 0x55e3, 0x089a,
+ 0x55e4, 0x1143,
+ 0x55f7, 0x1146,
+ 0x55f9, 0x114b,
+ 0x55fd, 0x1149,
+ 0x55fe, 0x1148,
+ 0x5606, 0x0b70,
+ 0x5609, 0x0545,
+ 0x5614, 0x1145,
+ 0x5616, 0x1147,
+ 0x5617, 0x0990,
+ 0x5618, 0x04d5,
+ 0x561b, 0x114a,
+ 0x5629, 0x055e,
+ 0x562f, 0x1155,
+ 0x5631, 0x09e4,
+ 0x5632, 0x1151,
+ 0x5634, 0x114f,
+ 0x5636, 0x1150,
+ 0x5638, 0x1152,
+ 0x5642, 0x04df,
+ 0x564c, 0x0abb,
+ 0x564e, 0x114c,
+ 0x5650, 0x114d,
+ 0x5653, 0x1f1b,
+ 0x565b, 0x05d8,
+ 0x5664, 0x1154,
+ 0x5668, 0x062b,
+ 0x566a, 0x1157,
+ 0x566b, 0x1153,
+ 0x566c, 0x1156,
+ 0x5674, 0x0dfe,
+ 0x5678, 0x0cad,
+ 0x567a, 0x0d4c,
+ 0x5680, 0x1159,
+ 0x5686, 0x1158,
+ 0x5687, 0x05a3,
+ 0x568a, 0x115a,
+ 0x568f, 0x115d,
+ 0x5694, 0x115c,
+ 0x5699, 0x1de6,
+ 0x56a0, 0x115b,
+ 0x56a2, 0x0cef,
+ 0x56a5, 0x115e,
+ 0x56ae, 0x115f,
+ 0x56b4, 0x1161,
+ 0x56b6, 0x1160,
+ 0x56bc, 0x1163,
+ 0x56c0, 0x1166,
+ 0x56c1, 0x1164,
+ 0x56c2, 0x1162,
+ 0x56c3, 0x1165,
+ 0x56c8, 0x1167,
+ 0x56ca, 0x1e5a,
+ 0x56ce, 0x1168,
+ 0x56d1, 0x1169,
+ 0x56d3, 0x116a,
+ 0x56d7, 0x116b,
+ 0x56d8, 0x107c,
+ 0x56da, 0x0928,
+ 0x56db, 0x089b,
+ 0x56de, 0x0573,
+ 0x56e0, 0x04bc,
+ 0x56e3, 0x0b82,
+ 0x56ee, 0x116c,
+ 0x56f0, 0x0814,
+ 0x56f2, 0x0493,
+ 0x56f3, 0x0a24,
+ 0x56f9, 0x116d,
+ 0x56fa, 0x077b,
+ 0x56fd, 0x0803,
+ 0x56ff, 0x116f,
+ 0x5700, 0x116e,
+ 0x5703, 0x0e30,
+ 0x5704, 0x1170,
+ 0x5708, 0x1172,
+ 0x5709, 0x1171,
+ 0x570b, 0x1173,
+ 0x570d, 0x1174,
+ 0x570f, 0x074d,
+ 0x5712, 0x0502,
+ 0x5713, 0x1175,
+ 0x5716, 0x1177,
+ 0x5718, 0x1176,
+ 0x571c, 0x1179,
+ 0x571f, 0x0c54,
+ 0x5726, 0x117a,
+ 0x5727, 0x0479,
+ 0x5728, 0x084f,
+ 0x572d, 0x0713,
+ 0x5730, 0x0b8d,
+ 0x5737, 0x117b,
+ 0x573b, 0x117e,
+ 0x5740, 0x117f,
+ 0x5742, 0x0854,
+ 0x5747, 0x06c9,
+ 0x574a, 0x0e65,
+ 0x574e, 0x117d,
+ 0x574f, 0x1180,
+ 0x5750, 0x0831,
+ 0x5751, 0x07b5,
+ 0x5759, 0x20e0,
+ 0x5761, 0x1184,
+ 0x5764, 0x0815,
+ 0x5765, 0x20e1,
+ 0x5766, 0x0b71,
+ 0x5769, 0x1181,
+ 0x576a, 0x0bf6,
+ 0x577f, 0x1185,
+ 0x5782, 0x0a28,
+ 0x5788, 0x1183,
+ 0x5789, 0x1186,
+ 0x578b, 0x0715,
+ 0x5793, 0x1187,
+ 0x57a0, 0x1188,
+ 0x57a2, 0x07b6,
+ 0x57a3, 0x059e,
+ 0x57a4, 0x118a,
+ 0x57aa, 0x118b,
+ 0x57ac, 0x20e2,
+ 0x57b0, 0x118c,
+ 0x57b3, 0x1189,
+ 0x57c0, 0x1182,
+ 0x57c3, 0x118d,
+ 0x57c6, 0x118e,
+ 0x57c7, 0x20e4,
+ 0x57c8, 0x20e3,
+ 0x57cb, 0x0e92,
+ 0x57ce, 0x09d3,
+ 0x57d2, 0x1190,
+ 0x57d4, 0x118f,
+ 0x57d6, 0x1193,
+ 0x57dc, 0x0cee,
+ 0x57df, 0x04ac,
+ 0x57e0, 0x0dc8,
+ 0x57e3, 0x1194,
+ 0x57f4, 0x09e5,
+ 0x57f7, 0x08e5,
+ 0x57f9, 0x0d13,
+ 0x57fa, 0x062c,
+ 0x57fc, 0x085b,
+ 0x5800, 0x0e87,
+ 0x5802, 0x0c8a,
+ 0x5805, 0x074e,
+ 0x5806, 0x0b2f,
+ 0x580a, 0x1192,
+ 0x580b, 0x1195,
+ 0x5815, 0x0b24,
+ 0x5819, 0x1196,
+ 0x581d, 0x1197,
+ 0x5821, 0x1199,
+ 0x5824, 0x0c05,
+ 0x582a, 0x05ea,
+ 0x582f, 0x1d32,
+ 0x5830, 0x0503,
+ 0x5831, 0x0e43,
+ 0x5834, 0x09d4,
+ 0x5835, 0x0c42,
+ 0x583a, 0x0856,
+ 0x583d, 0x119f,
+ 0x5840, 0x0e0d,
+ 0x5841, 0x0fa5,
+ 0x584a, 0x0574,
+ 0x584b, 0x119b,
+ 0x5851, 0x0abc,
+ 0x5852, 0x119e,
+ 0x5854, 0x0c5d,
+ 0x5857, 0x0c43,
+ 0x5858, 0x0c5e,
+ 0x5859, 0x0d4d,
+ 0x585a, 0x0be9,
+ 0x585e, 0x0839,
+ 0x5861, 0x1e47,
+ 0x5862, 0x119a,
+ 0x5869, 0x0518,
+ 0x586b, 0x0c30,
+ 0x5870, 0x119c,
+ 0x5872, 0x1198,
+ 0x5875, 0x0a16,
+ 0x5879, 0x11a0,
+ 0x587e, 0x0958,
+ 0x5883, 0x06a5,
+ 0x5885, 0x11a1,
+ 0x5893, 0x0e38,
+ 0x5897, 0x0aff,
+ 0x589c, 0x0be2,
+ 0x589e, 0x20e7,
+ 0x589f, 0x11a3,
+ 0x58a8, 0x0e7d,
+ 0x58ab, 0x11a4,
+ 0x58ae, 0x11a9,
+ 0x58b2, 0x20e8,
+ 0x58b3, 0x0dff,
+ 0x58b8, 0x11a8,
+ 0x58b9, 0x11a2,
+ 0x58ba, 0x11a5,
+ 0x58bb, 0x11a7,
+ 0x58be, 0x0816,
+ 0x58c1, 0x0e19,
+ 0x58c5, 0x11aa,
+ 0x58c7, 0x0b83,
+ 0x58ca, 0x0575,
+ 0x58cc, 0x09d5,
+ 0x58d1, 0x11ac,
+ 0x58d3, 0x11ab,
+ 0x58d5, 0x07fa,
+ 0x58d7, 0x11ad,
+ 0x58d8, 0x11af,
+ 0x58d9, 0x11ae,
+ 0x58dc, 0x11b1,
+ 0x58de, 0x11a6,
+ 0x58df, 0x11b3,
+ 0x58e4, 0x11b2,
+ 0x58e5, 0x11b0,
+ 0x58eb, 0x089c,
+ 0x58ec, 0x0a17,
+ 0x58ee, 0x0ad6,
+ 0x58ef, 0x11b4,
+ 0x58f0, 0x0a60,
+ 0x58f1, 0x04b1,
+ 0x58f2, 0x0d1a,
+ 0x58f7, 0x0bf7,
+ 0x58f9, 0x11b6,
+ 0x58fa, 0x11b5,
+ 0x58fb, 0x11b7,
+ 0x5902, 0x11ba,
+ 0x5909, 0x0e21,
+ 0x590a, 0x11bb,
+ 0x590b, 0x20e9,
+ 0x590f, 0x0546,
+ 0x5910, 0x11bc,
+ 0x5915, 0x0f26,
+ 0x5916, 0x058e,
+ 0x5918, 0x10de,
+ 0x5919, 0x0952,
+ 0x591a, 0x0b1f,
+ 0x591b, 0x11bd,
+ 0x591c, 0x0ef7,
+ 0x5922, 0x0ec0,
+ 0x5925, 0x11bf,
+ 0x5927, 0x0b47,
+ 0x5929, 0x0c31,
+ 0x592a, 0x0b20,
+ 0x592b, 0x0dc9,
+ 0x592c, 0x11c0,
+ 0x592e, 0x051d,
+ 0x5931, 0x08e6,
+ 0x5932, 0x11c2,
+ 0x5937, 0x0494,
+ 0x5938, 0x11c3,
+ 0x593e, 0x11c4,
+ 0x5944, 0x0504,
+ 0x5947, 0x062d,
+ 0x5948, 0x0cb8,
+ 0x5949, 0x0e44,
+ 0x594e, 0x11c8,
+ 0x594f, 0x0ad7,
+ 0x5950, 0x11c7,
+ 0x5951, 0x0716,
+ 0x5953, 0x20ea,
+ 0x5954, 0x0e89,
+ 0x5955, 0x11c6,
+ 0x5957, 0x0c5f,
+ 0x5958, 0x11ca,
+ 0x595a, 0x11c9,
+ 0x595b, 0x20eb,
+ 0x595d, 0x20ec,
+ 0x5960, 0x11cc,
+ 0x5962, 0x11cb,
+ 0x5963, 0x20ed,
+ 0x5965, 0x051e,
+ 0x5967, 0x11cd,
+ 0x5968, 0x0991,
+ 0x5969, 0x11cf,
+ 0x596a, 0x0b63,
+ 0x596c, 0x11ce,
+ 0x596e, 0x0e03,
+ 0x5973, 0x0981,
+ 0x5974, 0x0c55,
+ 0x5978, 0x11d0,
+ 0x597d, 0x07b7,
+ 0x5981, 0x11d1,
+ 0x5982, 0x0cd7,
+ 0x5983, 0x0d72,
+ 0x5984, 0x0edd,
+ 0x598a, 0x0cdb,
+ 0x598d, 0x11da,
+ 0x5993, 0x0652,
+ 0x5996, 0x0f2f,
+ 0x5999, 0x0ebb,
+ 0x599b, 0x1239,
+ 0x599d, 0x11d2,
+ 0x59a3, 0x11d5,
+ 0x59a4, 0x20ee,
+ 0x59a5, 0x0b25,
+ 0x59a8, 0x0e66,
+ 0x59ac, 0x0c44,
+ 0x59b2, 0x11d6,
+ 0x59b9, 0x0e93,
+ 0x59ba, 0x20ef,
+ 0x59bb, 0x083a,
+ 0x59be, 0x0992,
+ 0x59c6, 0x11d7,
+ 0x59c9, 0x089e,
+ 0x59cb, 0x089d,
+ 0x59d0, 0x047d,
+ 0x59d1, 0x077c,
+ 0x59d3, 0x0a4f,
+ 0x59d4, 0x0495,
+ 0x59d9, 0x11db,
+ 0x59dc, 0x11d9,
+ 0x59e5, 0x04da,
+ 0x59e6, 0x05eb,
+ 0x59e8, 0x11d8,
+ 0x59ea, 0x0ed1,
+ 0x59eb, 0x0da3,
+ 0x59f6, 0x046c,
+ 0x59fb, 0x04bd,
+ 0x59ff, 0x089f,
+ 0x5a01, 0x0496,
+ 0x5a03, 0x0467,
+ 0x5a09, 0x11e1,
+ 0x5a11, 0x11df,
+ 0x5a18, 0x0ec8,
+ 0x5a1a, 0x11e2,
+ 0x5a1c, 0x11e0,
+ 0x5a1f, 0x11de,
+ 0x5a20, 0x09f7,
+ 0x5a25, 0x11dd,
+ 0x5a29, 0x0e2a,
+ 0x5a2f, 0x0798,
+ 0x5a35, 0x11e6,
+ 0x5a3c, 0x0993,
+ 0x5a40, 0x11e3,
+ 0x5a41, 0x0fd2,
+ 0x5a46, 0x0d02,
+ 0x5a49, 0x11e5,
+ 0x5a5a, 0x0817,
+ 0x5a62, 0x11e8,
+ 0x5a66, 0x0dca,
+ 0x5a6a, 0x11e9,
+ 0x5a6c, 0x11e4,
+ 0x5a7f, 0x0ec7,
+ 0x5a92, 0x0d14,
+ 0x5a9a, 0x11ea,
+ 0x5a9b, 0x0da4,
+ 0x5abc, 0x11eb,
+ 0x5abd, 0x11ef,
+ 0x5abe, 0x11ec,
+ 0x5ac1, 0x0547,
+ 0x5ac2, 0x11ee,
+ 0x5ac9, 0x08e7,
+ 0x5acb, 0x11ed,
+ 0x5acc, 0x074f,
+ 0x5ad0, 0x11fb,
+ 0x5ad6, 0x11f4,
+ 0x5ad7, 0x11f1,
+ 0x5ae1, 0x0ba2,
+ 0x5ae3, 0x11f0,
+ 0x5ae6, 0x11f2,
+ 0x5ae9, 0x11f3,
+ 0x5afa, 0x11f5,
+ 0x5b09, 0x062e,
+ 0x5b0b, 0x11f8,
+ 0x5b0c, 0x11f7,
+ 0x5b16, 0x11f9,
+ 0x5b22, 0x09d6,
+ 0x5b2a, 0x11fc,
+ 0x5b2c, 0x0bf8,
+ 0x5b30, 0x04e7,
+ 0x5b32, 0x11fa,
+ 0x5b36, 0x11fd,
+ 0x5b3e, 0x11fe,
+ 0x5b40, 0x1201,
+ 0x5b43, 0x11ff,
+ 0x5b45, 0x1200,
+ 0x5b50, 0x08a0,
+ 0x5b51, 0x1202,
+ 0x5b54, 0x07b8,
+ 0x5b55, 0x1203,
+ 0x5b56, 0x20f0,
+ 0x5b57, 0x08c8,
+ 0x5b58, 0x0b18,
+ 0x5b5a, 0x1204,
+ 0x5b5c, 0x08a8,
+ 0x5b5d, 0x07b9,
+ 0x5b5f, 0x0ede,
+ 0x5b63, 0x0642,
+ 0x5b64, 0x077d,
+ 0x5b65, 0x1206,
+ 0x5b66, 0x05b6,
+ 0x5b69, 0x1207,
+ 0x5b6b, 0x0b19,
+ 0x5b70, 0x1208,
+ 0x5b71, 0x1230,
+ 0x5b73, 0x1209,
+ 0x5b75, 0x120a,
+ 0x5b78, 0x120b,
+ 0x5b7a, 0x120d,
+ 0x5b80, 0x120e,
+ 0x5b83, 0x120f,
+ 0x5b85, 0x0b50,
+ 0x5b87, 0x04c9,
+ 0x5b88, 0x0915,
+ 0x5b89, 0x0486,
+ 0x5b8b, 0x0ad9,
+ 0x5b8c, 0x05ec,
+ 0x5b8d, 0x08e1,
+ 0x5b8f, 0x07ba,
+ 0x5b95, 0x0c60,
+ 0x5b97, 0x092b,
+ 0x5b98, 0x05ed,
+ 0x5b99, 0x0ba6,
+ 0x5b9a, 0x0c06,
+ 0x5b9b, 0x047c,
+ 0x5b9c, 0x0653,
+ 0x5b9d, 0x0e45,
+ 0x5b9f, 0x08ee,
+ 0x5ba2, 0x066c,
+ 0x5ba3, 0x0a8f,
+ 0x5ba4, 0x08e8,
+ 0x5ba5, 0x0f12,
+ 0x5ba6, 0x1210,
+ 0x5bae, 0x0676,
+ 0x5bb0, 0x083b,
+ 0x5bb3, 0x0590,
+ 0x5bb4, 0x0505,
+ 0x5bb5, 0x0994,
+ 0x5bb6, 0x0548,
+ 0x5bb8, 0x1211,
+ 0x5bb9, 0x0f30,
+ 0x5bbf, 0x0953,
+ 0x5bc0, 0x20f1,
+ 0x5bc2, 0x0910,
+ 0x5bc3, 0x1212,
+ 0x5bc4, 0x062f,
+ 0x5bc5, 0x0caa,
+ 0x5bc6, 0x0eb5,
+ 0x5bc7, 0x1213,
+ 0x5bc9, 0x1214,
+ 0x5bcc, 0x0dcb,
+ 0x5bd0, 0x1216,
+ 0x5bd2, 0x05e4,
+ 0x5bd3, 0x06ef,
+ 0x5bd4, 0x1215,
+ 0x5bd8, 0x20f3,
+ 0x5bdb, 0x05ee,
+ 0x5bdd, 0x09f8,
+ 0x5bde, 0x121a,
+ 0x5bdf, 0x086f,
+ 0x5be1, 0x0549,
+ 0x5be2, 0x1219,
+ 0x5be4, 0x1217,
+ 0x5be5, 0x121b,
+ 0x5be6, 0x1218,
+ 0x5be7, 0x0ce1,
+ 0x5be8, 0x148e,
+ 0x5be9, 0x09f9,
+ 0x5beb, 0x121c,
+ 0x5bec, 0x20f4,
+ 0x5bee, 0x0f88,
+ 0x5bf0, 0x121d,
+ 0x5bf3, 0x121f,
+ 0x5bf5, 0x0bbc,
+ 0x5bf6, 0x121e,
+ 0x5bf8, 0x0a47,
+ 0x5bfa, 0x08c9,
+ 0x5bfe, 0x0b30,
+ 0x5bff, 0x0923,
+ 0x5c01, 0x0de7,
+ 0x5c02, 0x0a90,
+ 0x5c04, 0x08f9,
+ 0x5c05, 0x1220,
+ 0x5c06, 0x0995,
+ 0x5c07, 0x1221,
+ 0x5c09, 0x0497,
+ 0x5c0a, 0x0b1a,
+ 0x5c0b, 0x0a18,
+ 0x5c0d, 0x1223,
+ 0x5c0e, 0x0c8b,
+ 0x5c0f, 0x0996,
+ 0x5c11, 0x0997,
+ 0x5c13, 0x1224,
+ 0x5c16, 0x0a91,
+ 0x5c1a, 0x0998,
+ 0x5c1e, 0x20f5,
+ 0x5c20, 0x1225,
+ 0x5c22, 0x1226,
+ 0x5c24, 0x0eec,
+ 0x5c28, 0x1227,
+ 0x5c2d, 0x06be,
+ 0x5c31, 0x092c,
+ 0x5c38, 0x1228,
+ 0x5c3a, 0x0908,
+ 0x5c3b, 0x09f2,
+ 0x5c3c, 0x0ccc,
+ 0x5c3d, 0x0a1a,
+ 0x5c3e, 0x0d8c,
+ 0x5c3f, 0x0cd8,
+ 0x5c40, 0x06c1,
+ 0x5c41, 0x122a,
+ 0x5c45, 0x0689,
+ 0x5c46, 0x122b,
+ 0x5c48, 0x06f6,
+ 0x5c4a, 0x0ca7,
+ 0x5c4b, 0x0530,
+ 0x5c4d, 0x08a1,
+ 0x5c4e, 0x122c,
+ 0x5c4f, 0x122f,
+ 0x5c50, 0x122e,
+ 0x5c51, 0x06f5,
+ 0x5c53, 0x122d,
+ 0x5c55, 0x0c32,
+ 0x5c5b, 0x1e92,
+ 0x5c5e, 0x0b10,
+ 0x5c60, 0x0c45,
+ 0x5c61, 0x08f4,
+ 0x5c62, 0x1e0d,
+ 0x5c64, 0x0ada,
+ 0x5c65, 0x0f64,
+ 0x5c6c, 0x1231,
+ 0x5c6e, 0x1232,
+ 0x5c6f, 0x0cae,
+ 0x5c71, 0x0881,
+ 0x5c76, 0x1234,
+ 0x5c79, 0x1235,
+ 0x5c8c, 0x1236,
+ 0x5c90, 0x0630,
+ 0x5c91, 0x1237,
+ 0x5c94, 0x1238,
+ 0x5ca1, 0x052c,
+ 0x5ca6, 0x20f6,
+ 0x5ca8, 0x0abd,
+ 0x5ca9, 0x0620,
+ 0x5cab, 0x123a,
+ 0x5cac, 0x0eb4,
+ 0x5cb1, 0x0b32,
+ 0x5cb3, 0x05b7,
+ 0x5cb6, 0x123c,
+ 0x5cb7, 0x123e,
+ 0x5cb8, 0x061b,
+ 0x5cba, 0x20f7,
+ 0x5cbb, 0x123b,
+ 0x5cbc, 0x123d,
+ 0x5cbe, 0x1240,
+ 0x5cc5, 0x123f,
+ 0x5cc7, 0x1241,
+ 0x5cd9, 0x1242,
+ 0x5ce0, 0x0c95,
+ 0x5ce1, 0x06a6,
+ 0x5ce8, 0x0565,
+ 0x5ce9, 0x1243,
+ 0x5cea, 0x1248,
+ 0x5ced, 0x1246,
+ 0x5cef, 0x0e47,
+ 0x5cf0, 0x0e46,
+ 0x5cf5, 0x20f8,
+ 0x5cf6, 0x0c61,
+ 0x5cfa, 0x1245,
+ 0x5cfb, 0x095e,
+ 0x5cfd, 0x1244,
+ 0x5d07, 0x0a38,
+ 0x5d0b, 0x1249,
+ 0x5d0e, 0x085a,
+ 0x5d11, 0x124f,
+ 0x5d14, 0x1250,
+ 0x5d15, 0x124a,
+ 0x5d16, 0x0591,
+ 0x5d17, 0x124b,
+ 0x5d18, 0x1254,
+ 0x5d19, 0x1253,
+ 0x5d1a, 0x1252,
+ 0x5d1b, 0x124e,
+ 0x5d1f, 0x124d,
+ 0x5d22, 0x1251,
+ 0x5d27, 0x20f9,
+ 0x5d29, 0x0e48,
+ 0x5d42, 0x20fc,
+ 0x5d4b, 0x1258,
+ 0x5d4c, 0x1255,
+ 0x5d4e, 0x1257,
+ 0x5d50, 0x0f5c,
+ 0x5d52, 0x1256,
+ 0x5d53, 0x20fa,
+ 0x5d5c, 0x124c,
+ 0x5d69, 0x0a39,
+ 0x5d6c, 0x1259,
+ 0x5d6d, 0x20fd,
+ 0x5d6f, 0x0827,
+ 0x5d73, 0x125a,
+ 0x5d76, 0x125b,
+ 0x5d82, 0x125e,
+ 0x5d84, 0x125d,
+ 0x5d87, 0x125c,
+ 0x5d8b, 0x0c62,
+ 0x5d8c, 0x1247,
+ 0x5d90, 0x1264,
+ 0x5d9d, 0x1260,
+ 0x5da2, 0x125f,
+ 0x5dac, 0x1261,
+ 0x5dae, 0x1262,
+ 0x5db7, 0x1265,
+ 0x5db8, 0x20fe,
+ 0x5dba, 0x0fae,
+ 0x5dbc, 0x1266,
+ 0x5dbd, 0x1263,
+ 0x5dc9, 0x1267,
+ 0x5dcc, 0x061c,
+ 0x5dcd, 0x1268,
+ 0x5dd0, 0x2100,
+ 0x5dd2, 0x126a,
+ 0x5dd3, 0x1269,
+ 0x5dd6, 0x126b,
+ 0x5ddb, 0x126c,
+ 0x5ddd, 0x0a92,
+ 0x5dde, 0x092d,
+ 0x5de1, 0x096e,
+ 0x5de3, 0x0ae5,
+ 0x5de5, 0x07bb,
+ 0x5de6, 0x0828,
+ 0x5de7, 0x07bc,
+ 0x5de8, 0x068a,
+ 0x5deb, 0x126d,
+ 0x5dee, 0x0829,
+ 0x5df1, 0x077e,
+ 0x5df2, 0x126e,
+ 0x5df3, 0x0eb2,
+ 0x5df4, 0x0cf9,
+ 0x5df5, 0x126f,
+ 0x5df7, 0x07bd,
+ 0x5dfb, 0x05e8,
+ 0x5dfd, 0x0b65,
+ 0x5dfe, 0x06ca,
+ 0x5e02, 0x08a2,
+ 0x5e03, 0x0dcd,
+ 0x5e06, 0x0d55,
+ 0x5e0b, 0x1270,
+ 0x5e0c, 0x0631,
+ 0x5e11, 0x1273,
+ 0x5e16, 0x0bbd,
+ 0x5e19, 0x1272,
+ 0x5e1a, 0x1271,
+ 0x5e1b, 0x1274,
+ 0x5e1d, 0x0c07,
+ 0x5e25, 0x0a29,
+ 0x5e2b, 0x08a3,
+ 0x5e2d, 0x0a6e,
+ 0x5e2f, 0x0b33,
+ 0x5e30, 0x063c,
+ 0x5e33, 0x0bbe,
+ 0x5e36, 0x1275,
+ 0x5e38, 0x09d7,
+ 0x5e3d, 0x0e67,
+ 0x5e40, 0x1279,
+ 0x5e43, 0x1278,
+ 0x5e44, 0x1277,
+ 0x5e45, 0x0def,
+ 0x5e47, 0x1280,
+ 0x5e4c, 0x0e88,
+ 0x5e4e, 0x127a,
+ 0x5e54, 0x127c,
+ 0x5e55, 0x0e99,
+ 0x5e57, 0x127b,
+ 0x5e5f, 0x127d,
+ 0x5e61, 0x0d3c,
+ 0x5e62, 0x127e,
+ 0x5e63, 0x0e0e,
+ 0x5e64, 0x127f,
+ 0x5e72, 0x05ef,
+ 0x5e73, 0x0e0f,
+ 0x5e74, 0x0ce5,
+ 0x5e75, 0x1281,
+ 0x5e78, 0x07be,
+ 0x5e79, 0x05f0,
+ 0x5e7a, 0x1283,
+ 0x5e7b, 0x076c,
+ 0x5e7c, 0x0f2e,
+ 0x5e7d, 0x0f13,
+ 0x5e7e, 0x0632,
+ 0x5e7f, 0x1285,
+ 0x5e81, 0x0bbf,
+ 0x5e83, 0x07bf,
+ 0x5e84, 0x0999,
+ 0x5e87, 0x0d73,
+ 0x5e8a, 0x099a,
+ 0x5e8f, 0x0982,
+ 0x5e95, 0x0c08,
+ 0x5e96, 0x0e49,
+ 0x5e97, 0x0c33,
+ 0x5e9a, 0x07c0,
+ 0x5e9c, 0x0dce,
+ 0x5ea0, 0x1286,
+ 0x5ea6, 0x0c53,
+ 0x5ea7, 0x0832,
+ 0x5eab, 0x077f,
+ 0x5ead, 0x0c09,
+ 0x5eb5, 0x0487,
+ 0x5eb6, 0x0978,
+ 0x5eb7, 0x07c1,
+ 0x5eb8, 0x0f31,
+ 0x5ec1, 0x1287,
+ 0x5ec3, 0x0d07,
+ 0x5ec8, 0x1289,
+ 0x5ec9, 0x0fbf,
+ 0x5eca, 0x0fd3,
+ 0x5ecf, 0x128b,
+ 0x5ed0, 0x128a,
+ 0x5ed3, 0x05a5,
+ 0x5ed6, 0x128c,
+ 0x5eda, 0x128f,
+ 0x5edd, 0x128e,
+ 0x5edf, 0x0db2,
+ 0x5ee0, 0x099b,
+ 0x5ee1, 0x1292,
+ 0x5ee2, 0x1291,
+ 0x5ee3, 0x128d,
+ 0x5ee8, 0x1293,
+ 0x5eec, 0x1295,
+ 0x5ef0, 0x1298,
+ 0x5ef1, 0x1296,
+ 0x5ef3, 0x1297,
+ 0x5ef4, 0x1299,
+ 0x5ef6, 0x0506,
+ 0x5ef7, 0x0c0a,
+ 0x5ef8, 0x129a,
+ 0x5efa, 0x0750,
+ 0x5efb, 0x0576,
+ 0x5efc, 0x0cec,
+ 0x5efe, 0x129b,
+ 0x5eff, 0x0cd3,
+ 0x5f01, 0x0e2b,
+ 0x5f03, 0x129c,
+ 0x5f04, 0x0fd4,
+ 0x5f09, 0x129d,
+ 0x5f0a, 0x0e10,
+ 0x5f0b, 0x12a0,
+ 0x5f0c, 0x0ffa,
+ 0x5f0d, 0x100a,
+ 0x5f0f, 0x08dc,
+ 0x5f10, 0x0ccd,
+ 0x5f11, 0x12a1,
+ 0x5f13, 0x0677,
+ 0x5f14, 0x0bc0,
+ 0x5f15, 0x04be,
+ 0x5f16, 0x12a2,
+ 0x5f17, 0x0df6,
+ 0x5f18, 0x07c2,
+ 0x5f1b, 0x0b8e,
+ 0x5f1f, 0x0c0b,
+ 0x5f21, 0x2101,
+ 0x5f25, 0x0efb,
+ 0x5f26, 0x076d,
+ 0x5f27, 0x0780,
+ 0x5f29, 0x12a3,
+ 0x5f2d, 0x12a4,
+ 0x5f2f, 0x12aa,
+ 0x5f31, 0x0911,
+ 0x5f34, 0x2102,
+ 0x5f35, 0x0bc1,
+ 0x5f37, 0x06a7,
+ 0x5f38, 0x12a5,
+ 0x5f3c, 0x0d9d,
+ 0x5f3e, 0x0b84,
+ 0x5f41, 0x12a6,
+ 0x5f45, 0x20b2,
+ 0x5f48, 0x12a7,
+ 0x5f4a, 0x06a8,
+ 0x5f4c, 0x12a8,
+ 0x5f4e, 0x12a9,
+ 0x5f51, 0x12ab,
+ 0x5f53, 0x0c70,
+ 0x5f56, 0x12ac,
+ 0x5f59, 0x12ae,
+ 0x5f5c, 0x129f,
+ 0x5f5d, 0x129e,
+ 0x5f61, 0x12af,
+ 0x5f62, 0x0717,
+ 0x5f66, 0x0d99,
+ 0x5f67, 0x2103,
+ 0x5f69, 0x083c,
+ 0x5f6a, 0x0da9,
+ 0x5f6b, 0x0bc2,
+ 0x5f6c, 0x0dbd,
+ 0x5f6d, 0x12b0,
+ 0x5f70, 0x099c,
+ 0x5f71, 0x04e8,
+ 0x5f73, 0x12b1,
+ 0x5f77, 0x12b2,
+ 0x5f79, 0x0efe,
+ 0x5f7c, 0x0d74,
+ 0x5f7f, 0x12b5,
+ 0x5f80, 0x051f,
+ 0x5f81, 0x0a50,
+ 0x5f82, 0x12b4,
+ 0x5f83, 0x12b3,
+ 0x5f84, 0x0718,
+ 0x5f85, 0x0b34,
+ 0x5f87, 0x12b9,
+ 0x5f88, 0x12b7,
+ 0x5f8a, 0x12b6,
+ 0x5f8b, 0x0f6f,
+ 0x5f8c, 0x0799,
+ 0x5f90, 0x0983,
+ 0x5f91, 0x12b8,
+ 0x5f92, 0x0c46,
+ 0x5f93, 0x0948,
+ 0x5f97, 0x0c98,
+ 0x5f98, 0x12bc,
+ 0x5f99, 0x12bb,
+ 0x5f9e, 0x12ba,
+ 0x5fa0, 0x12bd,
+ 0x5fa1, 0x079a,
+ 0x5fa8, 0x12be,
+ 0x5fa9, 0x0dee,
+ 0x5faa, 0x0965,
+ 0x5fad, 0x12bf,
+ 0x5fae, 0x0d8d,
+ 0x5fb3, 0x0c99,
+ 0x5fb4, 0x0bc3,
+ 0x5fb7, 0x2104,
+ 0x5fb9, 0x0c2a,
+ 0x5fbc, 0x12c0,
+ 0x5fbd, 0x0645,
+ 0x5fc3, 0x09fa,
+ 0x5fc5, 0x0d9e,
+ 0x5fcc, 0x0633,
+ 0x5fcd, 0x0cdc,
+ 0x5fd6, 0x12c1,
+ 0x5fd7, 0x08a4,
+ 0x5fd8, 0x0e68,
+ 0x5fdc, 0x0520,
+ 0x5fdd, 0x12c6,
+ 0x5fde, 0x2105,
+ 0x5fe0, 0x0ba7,
+ 0x5fe4, 0x12c3,
+ 0x5feb, 0x0577,
+ 0x5ff0, 0x12f6,
+ 0x5ff1, 0x12c5,
+ 0x5ff5, 0x0ce6,
+ 0x5ff8, 0x12c4,
+ 0x5ffb, 0x12c2,
+ 0x5ffd, 0x080c,
+ 0x5fff, 0x12c8,
+ 0x600e, 0x12ce,
+ 0x600f, 0x12d4,
+ 0x6010, 0x12cc,
+ 0x6012, 0x0c56,
+ 0x6015, 0x12d1,
+ 0x6016, 0x0dcf,
+ 0x6019, 0x12cb,
+ 0x601b, 0x12d0,
+ 0x601c, 0x0faf,
+ 0x601d, 0x08a5,
+ 0x6020, 0x0b35,
+ 0x6021, 0x12c9,
+ 0x6025, 0x0678,
+ 0x6026, 0x12d3,
+ 0x6027, 0x0a51,
+ 0x6028, 0x0507,
+ 0x6029, 0x12cd,
+ 0x602a, 0x0578,
+ 0x602b, 0x12d2,
+ 0x602f, 0x06a9,
+ 0x6031, 0x12cf,
+ 0x603a, 0x12d5,
+ 0x6041, 0x12d7,
+ 0x6042, 0x12e1,
+ 0x6043, 0x12df,
+ 0x6046, 0x12dc,
+ 0x604a, 0x12db,
+ 0x604b, 0x0fc0,
+ 0x604d, 0x12dd,
+ 0x6050, 0x06aa,
+ 0x6052, 0x07c3,
+ 0x6055, 0x0984,
+ 0x6059, 0x12e4,
+ 0x605a, 0x12d6,
+ 0x605d, 0x2106,
+ 0x605f, 0x12da,
+ 0x6060, 0x12ca,
+ 0x6062, 0x057a,
+ 0x6063, 0x12de,
+ 0x6064, 0x12e0,
+ 0x6065, 0x0b8f,
+ 0x6068, 0x0818,
+ 0x6069, 0x0538,
+ 0x606a, 0x12d8,
+ 0x606b, 0x12e3,
+ 0x606c, 0x12e2,
+ 0x606d, 0x06ab,
+ 0x606f, 0x0b09,
+ 0x6070, 0x05c4,
+ 0x6075, 0x0719,
+ 0x6077, 0x12d9,
+ 0x6081, 0x12e5,
+ 0x6083, 0x12e8,
+ 0x6084, 0x12ea,
+ 0x6085, 0x2107,
+ 0x6089, 0x08e9,
+ 0x608a, 0x2108,
+ 0x608b, 0x12f0,
+ 0x608c, 0x0c0c,
+ 0x608d, 0x12e6,
+ 0x6092, 0x12ee,
+ 0x6094, 0x0579,
+ 0x6096, 0x12ec,
+ 0x609a, 0x12e9,
+ 0x609b, 0x12eb,
+ 0x609f, 0x079b,
+ 0x60a0, 0x0f14,
+ 0x60a3, 0x05f1,
+ 0x60a6, 0x04fb,
+ 0x60a7, 0x12ef,
+ 0x60a9, 0x0cf0,
+ 0x60aa, 0x0471,
+ 0x60b2, 0x0d75,
+ 0x60b3, 0x12c7,
+ 0x60b4, 0x12f5,
+ 0x60b5, 0x12f9,
+ 0x60b6, 0x0ef1,
+ 0x60b8, 0x12f2,
+ 0x60bc, 0x0c63,
+ 0x60bd, 0x12f7,
+ 0x60c5, 0x09d8,
+ 0x60c6, 0x12f8,
+ 0x60c7, 0x0caf,
+ 0x60d1, 0x0fed,
+ 0x60d3, 0x12f4,
+ 0x60d5, 0x210a,
+ 0x60d8, 0x12fa,
+ 0x60da, 0x080d,
+ 0x60dc, 0x0a6f,
+ 0x60de, 0x2109,
+ 0x60df, 0x0498,
+ 0x60e0, 0x12f3,
+ 0x60e1, 0x12f1,
+ 0x60e3, 0x0adc,
+ 0x60e7, 0x12e7,
+ 0x60e8, 0x0882,
+ 0x60f0, 0x0b26,
+ 0x60f1, 0x1306,
+ 0x60f2, 0x210c,
+ 0x60f3, 0x0add,
+ 0x60f4, 0x1301,
+ 0x60f6, 0x12fe,
+ 0x60f9, 0x0912,
+ 0x60fa, 0x1302,
+ 0x60fb, 0x1305,
+ 0x6100, 0x1300,
+ 0x6101, 0x092f,
+ 0x6103, 0x1303,
+ 0x6106, 0x12fd,
+ 0x6108, 0x0f08,
+ 0x6109, 0x0f07,
+ 0x610d, 0x1307,
+ 0x610f, 0x0499,
+ 0x6111, 0x210d,
+ 0x6115, 0x12fc,
+ 0x611a, 0x06ea,
+ 0x611b, 0x046a,
+ 0x611f, 0x05f2,
+ 0x6120, 0x210b,
+ 0x6121, 0x1304,
+ 0x6127, 0x130c,
+ 0x6128, 0x130b,
+ 0x612c, 0x1310,
+ 0x6130, 0x210f,
+ 0x6134, 0x1311,
+ 0x6137, 0x210e,
+ 0x613c, 0x130f,
+ 0x613d, 0x1312,
+ 0x613e, 0x130a,
+ 0x613f, 0x130e,
+ 0x6142, 0x1313,
+ 0x6144, 0x1314,
+ 0x6147, 0x1309,
+ 0x6148, 0x08ca,
+ 0x614a, 0x130d,
+ 0x614b, 0x0b36,
+ 0x614c, 0x07c4,
+ 0x614d, 0x12fb,
+ 0x614e, 0x09fb,
+ 0x6153, 0x1321,
+ 0x6155, 0x0e39,
+ 0x6158, 0x1317,
+ 0x615d, 0x1320,
+ 0x615f, 0x131f,
+ 0x6162, 0x0eab,
+ 0x6163, 0x05f3,
+ 0x6165, 0x131d,
+ 0x6167, 0x071b,
+ 0x6168, 0x0592,
+ 0x616b, 0x131a,
+ 0x616e, 0x0f80,
+ 0x616f, 0x131c,
+ 0x6170, 0x049a,
+ 0x6171, 0x131e,
+ 0x6173, 0x1315,
+ 0x6174, 0x131b,
+ 0x6175, 0x1322,
+ 0x6176, 0x071a,
+ 0x6177, 0x1316,
+ 0x617e, 0x0f47,
+ 0x6182, 0x0f15,
+ 0x6187, 0x1325,
+ 0x618a, 0x1329,
+ 0x618e, 0x0b00,
+ 0x6190, 0x0fc1,
+ 0x6191, 0x132a,
+ 0x6194, 0x1327,
+ 0x6196, 0x1324,
+ 0x6198, 0x2110,
+ 0x6199, 0x1323,
+ 0x619a, 0x1328,
+ 0x61a4, 0x0e00,
+ 0x61a7, 0x0c8c,
+ 0x61a9, 0x071c,
+ 0x61ab, 0x132b,
+ 0x61ac, 0x1326,
+ 0x61ae, 0x132c,
+ 0x61b2, 0x0751,
+ 0x61b6, 0x0531,
+ 0x61ba, 0x1334,
+ 0x61be, 0x05f4,
+ 0x61c3, 0x1332,
+ 0x61c6, 0x1333,
+ 0x61c7, 0x0819,
+ 0x61c8, 0x1331,
+ 0x61c9, 0x132f,
+ 0x61ca, 0x132e,
+ 0x61cb, 0x1335,
+ 0x61cc, 0x132d,
+ 0x61cd, 0x1337,
+ 0x61d0, 0x057b,
+ 0x61e3, 0x1339,
+ 0x61e6, 0x1338,
+ 0x61f2, 0x0bc4,
+ 0x61f4, 0x133c,
+ 0x61f6, 0x133a,
+ 0x61f7, 0x1330,
+ 0x61f8, 0x0752,
+ 0x61fa, 0x133b,
+ 0x61fc, 0x133f,
+ 0x61fd, 0x133e,
+ 0x61fe, 0x1340,
+ 0x61ff, 0x133d,
+ 0x6200, 0x1341,
+ 0x6208, 0x1342,
+ 0x620a, 0x0e3a,
+ 0x620c, 0x1345,
+ 0x620d, 0x1344,
+ 0x620e, 0x0949,
+ 0x6210, 0x0a52,
+ 0x6211, 0x0566,
+ 0x6212, 0x057c,
+ 0x6213, 0x2111,
+ 0x6214, 0x1346,
+ 0x6216, 0x0483,
+ 0x621a, 0x0a70,
+ 0x621b, 0x1347,
+ 0x621d, 0x1a64,
+ 0x621e, 0x1348,
+ 0x621f, 0x0737,
+ 0x6221, 0x1349,
+ 0x6226, 0x0a93,
+ 0x622a, 0x134a,
+ 0x622e, 0x134b,
+ 0x622f, 0x0654,
+ 0x6230, 0x134c,
+ 0x6232, 0x134d,
+ 0x6234, 0x0b37,
+ 0x6238, 0x0781,
+ 0x623b, 0x0eed,
+ 0x623f, 0x0e6a,
+ 0x6240, 0x0974,
+ 0x6241, 0x134f,
+ 0x6247, 0x0a94,
+ 0x6248, 0x1b1a,
+ 0x6249, 0x0d76,
+ 0x624b, 0x0916,
+ 0x624d, 0x083d,
+ 0x624e, 0x1350,
+ 0x6253, 0x0b27,
+ 0x6255, 0x0df7,
+ 0x6258, 0x0b51,
+ 0x625b, 0x1353,
+ 0x625e, 0x1351,
+ 0x6260, 0x1354,
+ 0x6263, 0x1352,
+ 0x6268, 0x1355,
+ 0x626e, 0x0e01,
+ 0x6271, 0x047b,
+ 0x6276, 0x0dd0,
+ 0x6279, 0x0d77,
+ 0x627c, 0x1356,
+ 0x627e, 0x1359,
+ 0x627f, 0x099d,
+ 0x6280, 0x0655,
+ 0x6282, 0x1357,
+ 0x6283, 0x135e,
+ 0x6284, 0x099e,
+ 0x6289, 0x1358,
+ 0x628a, 0x0cfa,
+ 0x6291, 0x0f48,
+ 0x6292, 0x135a,
+ 0x6294, 0x135f,
+ 0x6295, 0x0c64,
+ 0x6296, 0x135c,
+ 0x6297, 0x07c5,
+ 0x6298, 0x0a82,
+ 0x629b, 0x136d,
+ 0x629c, 0x0d48,
+ 0x629e, 0x0b52,
+ 0x62a6, 0x2112,
+ 0x62ab, 0x0d78,
+ 0x62ac, 0x13b2,
+ 0x62b1, 0x0e4a,
+ 0x62b5, 0x0c0d,
+ 0x62b9, 0x0ea3,
+ 0x62bb, 0x1362,
+ 0x62bc, 0x0521,
+ 0x62bd, 0x0ba8,
+ 0x62c2, 0x136b,
+ 0x62c5, 0x0b72,
+ 0x62c6, 0x1365,
+ 0x62c7, 0x136c,
+ 0x62c8, 0x1367,
+ 0x62c9, 0x136e,
+ 0x62ca, 0x136a,
+ 0x62cc, 0x1369,
+ 0x62cd, 0x0d25,
+ 0x62cf, 0x1363,
+ 0x62d0, 0x057d,
+ 0x62d1, 0x1361,
+ 0x62d2, 0x068b,
+ 0x62d3, 0x0b53,
+ 0x62d4, 0x135d,
+ 0x62d7, 0x1360,
+ 0x62d8, 0x07c6,
+ 0x62d9, 0x0a7f,
+ 0x62db, 0x099f,
+ 0x62dc, 0x1368,
+ 0x62dd, 0x0d08,
+ 0x62e0, 0x068c,
+ 0x62e1, 0x05a6,
+ 0x62ec, 0x05c5,
+ 0x62ed, 0x09e7,
+ 0x62ee, 0x1370,
+ 0x62ef, 0x1375,
+ 0x62f1, 0x1371,
+ 0x62f3, 0x0753,
+ 0x62f5, 0x1376,
+ 0x62f6, 0x0870,
+ 0x62f7, 0x07fb,
+ 0x62fe, 0x0930,
+ 0x62ff, 0x1364,
+ 0x6301, 0x08cb,
+ 0x6302, 0x1373,
+ 0x6307, 0x08a6,
+ 0x6308, 0x1374,
+ 0x6309, 0x0488,
+ 0x630c, 0x136f,
+ 0x6311, 0x0bc5,
+ 0x6319, 0x068d,
+ 0x631f, 0x06ac,
+ 0x6327, 0x1372,
+ 0x6328, 0x046b,
+ 0x632b, 0x0833,
+ 0x632f, 0x09fc,
+ 0x633a, 0x0c0e,
+ 0x633d, 0x0d68,
+ 0x633e, 0x1378,
+ 0x633f, 0x0ae0,
+ 0x6349, 0x0b0a,
+ 0x634c, 0x0879,
+ 0x634d, 0x1379,
+ 0x634f, 0x137b,
+ 0x6350, 0x1377,
+ 0x6355, 0x0e31,
+ 0x6357, 0x0bd9,
+ 0x635c, 0x0ade,
+ 0x6367, 0x0e4b,
+ 0x6368, 0x08fa,
+ 0x6369, 0x1387,
+ 0x636b, 0x1386,
+ 0x636e, 0x0a3e,
+ 0x6372, 0x0754,
+ 0x6376, 0x1380,
+ 0x6377, 0x09a1,
+ 0x637a, 0x0cc0,
+ 0x637b, 0x0ce7,
+ 0x6380, 0x137e,
+ 0x6383, 0x0adf,
+ 0x6388, 0x0924,
+ 0x6389, 0x1383,
+ 0x638c, 0x09a0,
+ 0x638e, 0x137d,
+ 0x638f, 0x1382,
+ 0x6392, 0x0d09,
+ 0x6396, 0x137c,
+ 0x6398, 0x06f7,
+ 0x639b, 0x05bb,
+ 0x639f, 0x1384,
+ 0x63a0, 0x0f73,
+ 0x63a1, 0x083e,
+ 0x63a2, 0x0b73,
+ 0x63a3, 0x1381,
+ 0x63a5, 0x0a80,
+ 0x63a7, 0x07c7,
+ 0x63a8, 0x0a2a,
+ 0x63a9, 0x0508,
+ 0x63aa, 0x0abe,
+ 0x63ab, 0x137f,
+ 0x63ac, 0x065f,
+ 0x63b2, 0x071d,
+ 0x63b4, 0x0beb,
+ 0x63b5, 0x1385,
+ 0x63bb, 0x0ae1,
+ 0x63be, 0x1388,
+ 0x63c0, 0x138a,
+ 0x63c3, 0x0b17,
+ 0x63c4, 0x1390,
+ 0x63c6, 0x138b,
+ 0x63c9, 0x138d,
+ 0x63cf, 0x0db3,
+ 0x63d0, 0x0c0f,
+ 0x63d2, 0x138e,
+ 0x63d6, 0x0f16,
+ 0x63da, 0x0f32,
+ 0x63db, 0x05f5,
+ 0x63e1, 0x0472,
+ 0x63e3, 0x138c,
+ 0x63e9, 0x1389,
+ 0x63ee, 0x0634,
+ 0x63f4, 0x0509,
+ 0x63f5, 0x2113,
+ 0x63f6, 0x138f,
+ 0x63fa, 0x0f33,
+ 0x6406, 0x1393,
+ 0x640d, 0x0b1b,
+ 0x640f, 0x139a,
+ 0x6413, 0x1394,
+ 0x6414, 0x1e2c,
+ 0x6416, 0x1391,
+ 0x6417, 0x1398,
+ 0x641c, 0x137a,
+ 0x6426, 0x1395,
+ 0x6428, 0x1399,
+ 0x642c, 0x0d56,
+ 0x642d, 0x0c65,
+ 0x6434, 0x1392,
+ 0x6436, 0x1396,
+ 0x643a, 0x071e,
+ 0x643e, 0x0861,
+ 0x6442, 0x0a81,
+ 0x644e, 0x139e,
+ 0x6451, 0x1e43,
+ 0x6458, 0x0c20,
+ 0x6460, 0x2114,
+ 0x6467, 0x139b,
+ 0x6469, 0x0e8e,
+ 0x646f, 0x139c,
+ 0x6476, 0x139d,
+ 0x6478, 0x0eda,
+ 0x647a, 0x0a46,
+ 0x6483, 0x0738,
+ 0x6488, 0x13a4,
+ 0x6492, 0x0883,
+ 0x6493, 0x13a1,
+ 0x6495, 0x13a0,
+ 0x649a, 0x0ce8,
+ 0x649d, 0x2115,
+ 0x649e, 0x0c8d,
+ 0x64a4, 0x0c2b,
+ 0x64a5, 0x13a2,
+ 0x64a9, 0x13a3,
+ 0x64ab, 0x0de1,
+ 0x64ad, 0x0cfb,
+ 0x64ae, 0x0871,
+ 0x64b0, 0x0a95,
+ 0x64b2, 0x0e7e,
+ 0x64b9, 0x05a7,
+ 0x64bb, 0x13aa,
+ 0x64bc, 0x13a5,
+ 0x64c1, 0x0f34,
+ 0x64c2, 0x13ac,
+ 0x64c5, 0x13a8,
+ 0x64c7, 0x13a9,
+ 0x64cd, 0x0ae2,
+ 0x64ce, 0x2116,
+ 0x64d2, 0x13a7,
+ 0x64d4, 0x1366,
+ 0x64d8, 0x13ab,
+ 0x64da, 0x13a6,
+ 0x64e0, 0x13b0,
+ 0x64e2, 0x0c21,
+ 0x64e3, 0x13b3,
+ 0x64e6, 0x0872,
+ 0x64e7, 0x13ae,
+ 0x64ec, 0x0656,
+ 0x64ef, 0x13b4,
+ 0x64f1, 0x13ad,
+ 0x64f2, 0x13b8,
+ 0x64f4, 0x13b7,
+ 0x64f6, 0x13b6,
+ 0x64fa, 0x13b9,
+ 0x64fd, 0x13bb,
+ 0x64fe, 0x09d9,
+ 0x6500, 0x13ba,
+ 0x6505, 0x13be,
+ 0x6518, 0x13bc,
+ 0x651c, 0x13bd,
+ 0x651d, 0x1397,
+ 0x6522, 0x1e97,
+ 0x6523, 0x13c0,
+ 0x6524, 0x13bf,
+ 0x652a, 0x139f,
+ 0x652b, 0x13c1,
+ 0x652c, 0x13b5,
+ 0x652f, 0x08a7,
+ 0x6534, 0x13c2,
+ 0x6536, 0x13c5,
+ 0x6537, 0x13c4,
+ 0x6538, 0x13c6,
+ 0x6539, 0x057e,
+ 0x653b, 0x07c8,
+ 0x653e, 0x0e4c,
+ 0x653f, 0x0a53,
+ 0x6545, 0x0782,
+ 0x6548, 0x13c8,
+ 0x654d, 0x13cb,
+ 0x654e, 0x2117,
+ 0x654f, 0x0dc4,
+ 0x6551, 0x0679,
+ 0x6555, 0x13ca,
+ 0x6556, 0x13c9,
+ 0x6557, 0x0d0a,
+ 0x6558, 0x13cc,
+ 0x6559, 0x06ad,
+ 0x655d, 0x13ce,
+ 0x655e, 0x13cd,
+ 0x6562, 0x05f6,
+ 0x6563, 0x0884,
+ 0x6566, 0x0cb0,
+ 0x656c, 0x071f,
+ 0x6570, 0x0a3a,
+ 0x6572, 0x13cf,
+ 0x6574, 0x0a54,
+ 0x6575, 0x0c22,
+ 0x6577, 0x0dd1,
+ 0x6578, 0x13d0,
+ 0x6582, 0x13d1,
+ 0x6587, 0x0e08,
+ 0x6588, 0x120c,
+ 0x6589, 0x0a6a,
+ 0x658c, 0x0dbe,
+ 0x658e, 0x0848,
+ 0x6590, 0x0d79,
+ 0x6591, 0x0d57,
+ 0x6597, 0x0c47,
+ 0x6599, 0x0f89,
+ 0x659b, 0x13d4,
+ 0x659c, 0x08fc,
+ 0x659f, 0x13d5,
+ 0x65a1, 0x047a,
+ 0x65a4, 0x06cc,
+ 0x65a5, 0x0a71,
+ 0x65a7, 0x0dd2,
+ 0x65ab, 0x13d6,
+ 0x65ac, 0x0890,
+ 0x65ad, 0x0b85,
+ 0x65af, 0x08a9,
+ 0x65b0, 0x09fd,
+ 0x65b7, 0x13d7,
+ 0x65b9, 0x0e4d,
+ 0x65bc, 0x0519,
+ 0x65bd, 0x08aa,
+ 0x65c1, 0x13da,
+ 0x65c3, 0x13d8,
+ 0x65c4, 0x13db,
+ 0x65c5, 0x0f81,
+ 0x65c6, 0x13d9,
+ 0x65cb, 0x0a9f,
+ 0x65cc, 0x13dc,
+ 0x65cf, 0x0b12,
+ 0x65d2, 0x13dd,
+ 0x65d7, 0x0636,
+ 0x65d9, 0x13df,
+ 0x65db, 0x13de,
+ 0x65e0, 0x13e0,
+ 0x65e2, 0x0637,
+ 0x65e5, 0x0cd4,
+ 0x65e6, 0x0b74,
+ 0x65e7, 0x0686,
+ 0x65e8, 0x08ab,
+ 0x65e9, 0x0ae3,
+ 0x65ec, 0x0966,
+ 0x65ed, 0x0474,
+ 0x65f1, 0x13e2,
+ 0x65fa, 0x0522,
+ 0x65fb, 0x13e6,
+ 0x6600, 0x2118,
+ 0x6602, 0x07c9,
+ 0x6603, 0x13e5,
+ 0x6606, 0x081b,
+ 0x6607, 0x09a2,
+ 0x6609, 0x211a,
+ 0x660a, 0x13e4,
+ 0x660c, 0x09a3,
+ 0x660e, 0x0ecc,
+ 0x660f, 0x081a,
+ 0x6613, 0x049b,
+ 0x6614, 0x0a72,
+ 0x6615, 0x2119,
+ 0x661c, 0x13eb,
+ 0x661e, 0x211c,
+ 0x661f, 0x0a55,
+ 0x6620, 0x04e9,
+ 0x6624, 0x211d,
+ 0x6625, 0x095f,
+ 0x6627, 0x0e94,
+ 0x6628, 0x0862,
+ 0x662d, 0x09a4,
+ 0x662e, 0x211b,
+ 0x662f, 0x0a4b,
+ 0x6631, 0x20ae,
+ 0x6634, 0x13ea,
+ 0x6635, 0x13e8,
+ 0x663b, 0x1e00,
+ 0x663c, 0x0ba9,
+ 0x663f, 0x1409,
+ 0x6641, 0x13ef,
+ 0x6642, 0x08cc,
+ 0x6643, 0x07ca,
+ 0x6644, 0x13ed,
+ 0x6649, 0x13ee,
+ 0x664b, 0x09fe,
+ 0x664f, 0x13ec,
+ 0x6652, 0x087d,
+ 0x6657, 0x211f,
+ 0x6659, 0x2120,
+ 0x665d, 0x13f1,
+ 0x665e, 0x13f0,
+ 0x665f, 0x13f5,
+ 0x6662, 0x13f6,
+ 0x6664, 0x13f2,
+ 0x6665, 0x211e,
+ 0x6666, 0x0580,
+ 0x6667, 0x13f3,
+ 0x6669, 0x0d69,
+ 0x666e, 0x0dd3,
+ 0x666f, 0x0720,
+ 0x6670, 0x13f7,
+ 0x6673, 0x2122,
+ 0x6674, 0x0a56,
+ 0x6676, 0x09a5,
+ 0x667a, 0x0b90,
+ 0x6681, 0x06bf,
+ 0x6683, 0x13f8,
+ 0x6684, 0x13fc,
+ 0x6687, 0x054b,
+ 0x6688, 0x13f9,
+ 0x6689, 0x13fb,
+ 0x668e, 0x13fa,
+ 0x6691, 0x0975,
+ 0x6696, 0x0b86,
+ 0x6697, 0x0489,
+ 0x6698, 0x13fd,
+ 0x6699, 0x2123,
+ 0x669d, 0x13fe,
+ 0x66a0, 0x2124,
+ 0x66a2, 0x0bc6,
+ 0x66a6, 0x0fb9,
+ 0x66ab, 0x0891,
+ 0x66ae, 0x0e3b,
+ 0x66b2, 0x2125,
+ 0x66b4, 0x0e6b,
+ 0x66b8, 0x1405,
+ 0x66b9, 0x1400,
+ 0x66bc, 0x1403,
+ 0x66be, 0x1402,
+ 0x66bf, 0x2126,
+ 0x66c1, 0x13ff,
+ 0x66c4, 0x1404,
+ 0x66c7, 0x0cb6,
+ 0x66c9, 0x1401,
+ 0x66d6, 0x1406,
+ 0x66d9, 0x0976,
+ 0x66da, 0x1407,
+ 0x66dc, 0x0f35,
+ 0x66dd, 0x0d2e,
+ 0x66e0, 0x1408,
+ 0x66e6, 0x140a,
+ 0x66e9, 0x140b,
+ 0x66f0, 0x140c,
+ 0x66f2, 0x06c2,
+ 0x66f3, 0x04ea,
+ 0x66f4, 0x07cb,
+ 0x66f5, 0x140d,
+ 0x66f7, 0x140e,
+ 0x66f8, 0x097b,
+ 0x66f9, 0x0ae4,
+ 0x66fa, 0x2127,
+ 0x66fb, 0x20b1,
+ 0x66fc, 0x10ed,
+ 0x66fd, 0x0ac0,
+ 0x66fe, 0x0abf,
+ 0x66ff, 0x0b38,
+ 0x6700, 0x0837,
+ 0x6703, 0x104b,
+ 0x6708, 0x0744,
+ 0x6709, 0x0f17,
+ 0x670b, 0x0e4e,
+ 0x670d, 0x0df0,
+ 0x670e, 0x2128,
+ 0x670f, 0x140f,
+ 0x6714, 0x0863,
+ 0x6715, 0x0bdb,
+ 0x6716, 0x1410,
+ 0x6717, 0x0fd5,
+ 0x671b, 0x0e6c,
+ 0x671d, 0x0bc7,
+ 0x671e, 0x1411,
+ 0x671f, 0x0638,
+ 0x6726, 0x1412,
+ 0x6728, 0x0ee6,
+ 0x672a, 0x0eb0,
+ 0x672b, 0x0ea4,
+ 0x672c, 0x0e8a,
+ 0x672d, 0x0873,
+ 0x672e, 0x1415,
+ 0x6731, 0x0917,
+ 0x6734, 0x0e7f,
+ 0x6736, 0x1417,
+ 0x6737, 0x141a,
+ 0x6738, 0x1419,
+ 0x673a, 0x0635,
+ 0x673d, 0x067a,
+ 0x673f, 0x1416,
+ 0x6741, 0x1418,
+ 0x6746, 0x141b,
+ 0x6749, 0x0a3f,
+ 0x674e, 0x0f65,
+ 0x674f, 0x048d,
+ 0x6750, 0x0850,
+ 0x6751, 0x0b1c,
+ 0x6753, 0x0909,
+ 0x6756, 0x09db,
+ 0x6759, 0x141e,
+ 0x675c, 0x0c48,
+ 0x675e, 0x141c,
+ 0x675f, 0x0b0b,
+ 0x6760, 0x141d,
+ 0x6761, 0x09da,
+ 0x6762, 0x0ee9,
+ 0x6763, 0x141f,
+ 0x6765, 0x0f52,
+ 0x6766, 0x212a,
+ 0x676a, 0x1425,
+ 0x676d, 0x07cc,
+ 0x676f, 0x0d0b,
+ 0x6770, 0x1422,
+ 0x6771, 0x0c66,
+ 0x6772, 0x13e3,
+ 0x6773, 0x13e7,
+ 0x6775, 0x0669,
+ 0x6777, 0x0cfd,
+ 0x677c, 0x1424,
+ 0x677e, 0x09a6,
+ 0x677f, 0x0d58,
+ 0x6785, 0x142a,
+ 0x6787, 0x0d8e,
+ 0x6789, 0x1421,
+ 0x678b, 0x1427,
+ 0x678c, 0x1426,
+ 0x6790, 0x0a73,
+ 0x6795, 0x0e9b,
+ 0x6797, 0x0f9b,
+ 0x679a, 0x0e95,
+ 0x679c, 0x054c,
+ 0x679d, 0x08ac,
+ 0x67a0, 0x0fee,
+ 0x67a1, 0x1429,
+ 0x67a2, 0x0a3b,
+ 0x67a6, 0x1428,
+ 0x67a9, 0x1423,
+ 0x67af, 0x0783,
+ 0x67b3, 0x142f,
+ 0x67b4, 0x142d,
+ 0x67b6, 0x054d,
+ 0x67b7, 0x142b,
+ 0x67b8, 0x1431,
+ 0x67b9, 0x1437,
+ 0x67bb, 0x212b,
+ 0x67c0, 0x212d,
+ 0x67c1, 0x0b28,
+ 0x67c4, 0x0e11,
+ 0x67c6, 0x1439,
+ 0x67ca, 0x0d94,
+ 0x67ce, 0x1438,
+ 0x67cf, 0x0d26,
+ 0x67d0, 0x0e6d,
+ 0x67d1, 0x05f7,
+ 0x67d3, 0x0a9b,
+ 0x67d4, 0x094a,
+ 0x67d8, 0x0bef,
+ 0x67da, 0x0f18,
+ 0x67dd, 0x1434,
+ 0x67de, 0x1433,
+ 0x67e2, 0x1435,
+ 0x67e4, 0x1432,
+ 0x67e7, 0x143a,
+ 0x67e9, 0x1430,
+ 0x67ec, 0x142e,
+ 0x67ee, 0x1436,
+ 0x67ef, 0x142c,
+ 0x67f1, 0x0baa,
+ 0x67f3, 0x0f04,
+ 0x67f4, 0x08f2,
+ 0x67f5, 0x0864,
+ 0x67fb, 0x082a,
+ 0x67fe, 0x0e9d,
+ 0x67ff, 0x059f,
+ 0x6801, 0x212e,
+ 0x6802, 0x0bea,
+ 0x6803, 0x0ca2,
+ 0x6804, 0x04eb,
+ 0x6805, 0x1e07,
+ 0x6813, 0x0a96,
+ 0x6816, 0x0a58,
+ 0x6817, 0x0700,
+ 0x681e, 0x143c,
+ 0x6821, 0x07cd,
+ 0x6822, 0x05da,
+ 0x6829, 0x143e,
+ 0x682a, 0x05d2,
+ 0x682b, 0x1444,
+ 0x6832, 0x1441,
+ 0x6834, 0x0a97,
+ 0x6838, 0x05a9,
+ 0x6839, 0x081c,
+ 0x683c, 0x05a8,
+ 0x683d, 0x083f,
+ 0x6840, 0x143f,
+ 0x6841, 0x073b,
+ 0x6842, 0x0721,
+ 0x6843, 0x0c67,
+ 0x6844, 0x212f,
+ 0x6846, 0x143d,
+ 0x6848, 0x048a,
+ 0x684d, 0x1440,
+ 0x684e, 0x1442,
+ 0x6850, 0x06c5,
+ 0x6851, 0x0702,
+ 0x6852, 0x212c,
+ 0x6853, 0x05f8,
+ 0x6854, 0x0665,
+ 0x6859, 0x1445,
+ 0x685c, 0x0869,
+ 0x685d, 0x0e9f,
+ 0x685f, 0x0885,
+ 0x6863, 0x1446,
+ 0x6867, 0x0da2,
+ 0x6874, 0x1452,
+ 0x6876, 0x0533,
+ 0x6877, 0x1447,
+ 0x687e, 0x1458,
+ 0x687f, 0x1448,
+ 0x6881, 0x0f8a,
+ 0x6883, 0x144f,
+ 0x6885, 0x0d15,
+ 0x688d, 0x1457,
+ 0x688e, 0x1e9c,
+ 0x688f, 0x144a,
+ 0x6893, 0x0478,
+ 0x6894, 0x144c,
+ 0x6897, 0x07ce,
+ 0x689b, 0x144e,
+ 0x689d, 0x144d,
+ 0x689f, 0x1449,
+ 0x68a0, 0x1454,
+ 0x68a2, 0x09a7,
+ 0x68a6, 0x11be,
+ 0x68a7, 0x079c,
+ 0x68a8, 0x0f66,
+ 0x68ad, 0x144b,
+ 0x68af, 0x0c10,
+ 0x68b0, 0x0581,
+ 0x68b1, 0x081d,
+ 0x68b3, 0x1443,
+ 0x68b5, 0x1453,
+ 0x68b6, 0x05bf,
+ 0x68b9, 0x1451,
+ 0x68ba, 0x1455,
+ 0x68bc, 0x0c68,
+ 0x68c4, 0x063a,
+ 0x68c6, 0x1473,
+ 0x68c8, 0x20af,
+ 0x68c9, 0x0ed5,
+ 0x68ca, 0x145a,
+ 0x68cb, 0x0639,
+ 0x68cd, 0x1461,
+ 0x68cf, 0x2130,
+ 0x68d2, 0x0e6e,
+ 0x68d4, 0x1462,
+ 0x68d5, 0x1464,
+ 0x68d7, 0x1468,
+ 0x68d8, 0x145c,
+ 0x68da, 0x0b68,
+ 0x68df, 0x0c69,
+ 0x68e0, 0x146c,
+ 0x68e1, 0x145f,
+ 0x68e3, 0x1469,
+ 0x68e7, 0x1463,
+ 0x68ee, 0x09ff,
+ 0x68ef, 0x146d,
+ 0x68f2, 0x0a57,
+ 0x68f9, 0x146b,
+ 0x68fa, 0x05f9,
+ 0x6900, 0x0ff6,
+ 0x6901, 0x1459,
+ 0x6904, 0x1467,
+ 0x6905, 0x049c,
+ 0x6908, 0x145b,
+ 0x690b, 0x0ec6,
+ 0x690c, 0x1460,
+ 0x690d, 0x09e8,
+ 0x690e, 0x0be3,
+ 0x690f, 0x1456,
+ 0x6912, 0x1466,
+ 0x6919, 0x0a40,
+ 0x691a, 0x1470,
+ 0x691b, 0x05cf,
+ 0x691c, 0x0755,
+ 0x6921, 0x1472,
+ 0x6922, 0x145d,
+ 0x6923, 0x1471,
+ 0x6925, 0x146a,
+ 0x6926, 0x145e,
+ 0x6928, 0x146e,
+ 0x692a, 0x146f,
+ 0x6930, 0x1480,
+ 0x6934, 0x0ca6,
+ 0x6936, 0x1465,
+ 0x6939, 0x147c,
+ 0x693d, 0x147e,
+ 0x693f, 0x0bf4,
+ 0x694a, 0x0f36,
+ 0x6953, 0x0de8,
+ 0x6954, 0x1479,
+ 0x6955, 0x0b2a,
+ 0x6959, 0x147f,
+ 0x695a, 0x0ac1,
+ 0x695c, 0x1476,
+ 0x695d, 0x1483,
+ 0x695e, 0x1482,
+ 0x6960, 0x0cc7,
+ 0x6961, 0x1481,
+ 0x6962, 0x0cc2,
+ 0x6968, 0x2132,
+ 0x696a, 0x1485,
+ 0x696b, 0x1478,
+ 0x696d, 0x06c0,
+ 0x696e, 0x147b,
+ 0x696f, 0x0967,
+ 0x6973, 0x0d16,
+ 0x6974, 0x147d,
+ 0x6975, 0x06c3,
+ 0x6977, 0x1475,
+ 0x6978, 0x1477,
+ 0x6979, 0x1474,
+ 0x697c, 0x0fd6,
+ 0x697d, 0x05b8,
+ 0x697e, 0x147a,
+ 0x6981, 0x1484,
+ 0x6982, 0x0593,
+ 0x698a, 0x0857,
+ 0x698e, 0x04ff,
+ 0x6991, 0x1495,
+ 0x6994, 0x0fd7,
+ 0x6995, 0x1498,
+ 0x6998, 0x2134,
+ 0x699b, 0x0a00,
+ 0x699c, 0x1497,
+ 0x69a0, 0x1496,
+ 0x69a7, 0x1493,
+ 0x69ae, 0x1487,
+ 0x69b1, 0x14a4,
+ 0x69b2, 0x1486,
+ 0x69b4, 0x1499,
+ 0x69bb, 0x1491,
+ 0x69be, 0x148c,
+ 0x69bf, 0x1489,
+ 0x69c1, 0x148a,
+ 0x69c3, 0x1492,
+ 0x69c7, 0x1d33,
+ 0x69ca, 0x148f,
+ 0x69cb, 0x07cf,
+ 0x69cc, 0x0be4,
+ 0x69cd, 0x0ae6,
+ 0x69ce, 0x148d,
+ 0x69d0, 0x1488,
+ 0x69d3, 0x148b,
+ 0x69d8, 0x0f37,
+ 0x69d9, 0x0e98,
+ 0x69dd, 0x1490,
+ 0x69de, 0x149a,
+ 0x69e2, 0x2135,
+ 0x69e7, 0x14a2,
+ 0x69e8, 0x149b,
+ 0x69eb, 0x14a8,
+ 0x69ed, 0x14a6,
+ 0x69f2, 0x14a1,
+ 0x69f9, 0x14a0,
+ 0x69fb, 0x0bec,
+ 0x69fd, 0x0ae7,
+ 0x69ff, 0x149e,
+ 0x6a02, 0x149c,
+ 0x6a05, 0x14a3,
+ 0x6a0a, 0x14a9,
+ 0x6a0b, 0x0d89,
+ 0x6a0c, 0x14af,
+ 0x6a12, 0x14aa,
+ 0x6a13, 0x14ad,
+ 0x6a14, 0x14a7,
+ 0x6a17, 0x0bb2,
+ 0x6a19, 0x0daa,
+ 0x6a1b, 0x149d,
+ 0x6a1e, 0x14a5,
+ 0x6a1f, 0x09a8,
+ 0x6a21, 0x0edb,
+ 0x6a22, 0x14b9,
+ 0x6a23, 0x14ac,
+ 0x6a29, 0x0756,
+ 0x6a2a, 0x0523,
+ 0x6a2b, 0x05bd,
+ 0x6a2e, 0x1494,
+ 0x6a30, 0x2136,
+ 0x6a35, 0x09a9,
+ 0x6a36, 0x14b1,
+ 0x6a38, 0x14b8,
+ 0x6a39, 0x0925,
+ 0x6a3a, 0x05d0,
+ 0x6a3d, 0x0b6c,
+ 0x6a44, 0x14ae,
+ 0x6a46, 0x2138,
+ 0x6a47, 0x14b3,
+ 0x6a48, 0x14b7,
+ 0x6a4b, 0x06ae,
+ 0x6a58, 0x0666,
+ 0x6a59, 0x14b5,
+ 0x6a5f, 0x063b,
+ 0x6a61, 0x0ca3,
+ 0x6a62, 0x14b4,
+ 0x6a66, 0x14b6,
+ 0x6a6b, 0x2137,
+ 0x6a72, 0x14b0,
+ 0x6a73, 0x2139,
+ 0x6a78, 0x14b2,
+ 0x6a7e, 0x213a,
+ 0x6a7f, 0x05be,
+ 0x6a80, 0x0b87,
+ 0x6a84, 0x14bd,
+ 0x6a8d, 0x14bb,
+ 0x6a8e, 0x079d,
+ 0x6a90, 0x14ba,
+ 0x6a97, 0x14c0,
+ 0x6a9c, 0x143b,
+ 0x6aa0, 0x14bc,
+ 0x6aa2, 0x14be,
+ 0x6aaa, 0x14cb,
+ 0x6aac, 0x14c7,
+ 0x6aae, 0x1450,
+ 0x6ab3, 0x14c6,
+ 0x6ab8, 0x14c5,
+ 0x6abb, 0x14c2,
+ 0x6ac1, 0x14ab,
+ 0x6ac2, 0x14c4,
+ 0x6ac3, 0x14c3,
+ 0x6ad1, 0x14c9,
+ 0x6ad3, 0x0fcc,
+ 0x6ada, 0x14cc,
+ 0x6adb, 0x06f3,
+ 0x6ade, 0x14c8,
+ 0x6adf, 0x14ca,
+ 0x6ae2, 0x213b,
+ 0x6ae4, 0x213c,
+ 0x6ae8, 0x0d3b,
+ 0x6aea, 0x14cd,
+ 0x6afa, 0x14d1,
+ 0x6afb, 0x14ce,
+ 0x6b04, 0x0f5d,
+ 0x6b05, 0x14cf,
+ 0x6b0a, 0x149f,
+ 0x6b12, 0x14d2,
+ 0x6b16, 0x14d3,
+ 0x6b1d, 0x04d7,
+ 0x6b1f, 0x14d5,
+ 0x6b20, 0x073d,
+ 0x6b21, 0x08cd,
+ 0x6b23, 0x06cd,
+ 0x6b27, 0x0524,
+ 0x6b32, 0x0f49,
+ 0x6b37, 0x14d7,
+ 0x6b38, 0x14d6,
+ 0x6b39, 0x14d9,
+ 0x6b3a, 0x0657,
+ 0x6b3d, 0x06ce,
+ 0x6b3e, 0x05fa,
+ 0x6b43, 0x14dc,
+ 0x6b47, 0x14db,
+ 0x6b49, 0x14dd,
+ 0x6b4c, 0x054e,
+ 0x6b4e, 0x0b75,
+ 0x6b50, 0x14de,
+ 0x6b53, 0x05fb,
+ 0x6b54, 0x14e0,
+ 0x6b59, 0x14df,
+ 0x6b5b, 0x14e1,
+ 0x6b5f, 0x14e2,
+ 0x6b61, 0x14e3,
+ 0x6b62, 0x08ad,
+ 0x6b63, 0x0a59,
+ 0x6b64, 0x0811,
+ 0x6b66, 0x0de2,
+ 0x6b69, 0x0e32,
+ 0x6b6a, 0x0fea,
+ 0x6b6f, 0x08c3,
+ 0x6b73, 0x0840,
+ 0x6b74, 0x0fba,
+ 0x6b78, 0x14e4,
+ 0x6b7b, 0x08ae,
+ 0x6b7f, 0x14e6,
+ 0x6b83, 0x14e9,
+ 0x6b84, 0x14e8,
+ 0x6b86, 0x0e86,
+ 0x6b89, 0x0968,
+ 0x6b8a, 0x0918,
+ 0x6b8b, 0x0892,
+ 0x6b8d, 0x14ea,
+ 0x6b95, 0x14ec,
+ 0x6b96, 0x09e9,
+ 0x6b98, 0x14eb,
+ 0x6b9e, 0x14ed,
+ 0x6ba4, 0x14ee,
+ 0x6baa, 0x14ef,
+ 0x6baf, 0x14f1,
+ 0x6bb1, 0x14f3,
+ 0x6bb2, 0x14f2,
+ 0x6bb3, 0x14f4,
+ 0x6bb4, 0x0525,
+ 0x6bb5, 0x0b88,
+ 0x6bb7, 0x14f5,
+ 0x6bba, 0x0874,
+ 0x6bbb, 0x05aa,
+ 0x6bbc, 0x14f6,
+ 0x6bbf, 0x0c3c,
+ 0x6bc0, 0x119d,
+ 0x6bc5, 0x063d,
+ 0x6bc6, 0x14f7,
+ 0x6bcb, 0x14f8,
+ 0x6bcd, 0x0e3c,
+ 0x6bce, 0x0e96,
+ 0x6bd2, 0x0c9f,
+ 0x6bd3, 0x14f9,
+ 0x6bd4, 0x0d7a,
+ 0x6bd6, 0x213d,
+ 0x6bd8, 0x0d8f,
+ 0x6bdb, 0x0edf,
+ 0x6bdf, 0x14fa,
+ 0x6beb, 0x14fc,
+ 0x6bec, 0x14fb,
+ 0x6bef, 0x14fe,
+ 0x6bf3, 0x14fd,
+ 0x6c08, 0x1500,
+ 0x6c0f, 0x08af,
+ 0x6c11, 0x0ebd,
+ 0x6c13, 0x1501,
+ 0x6c17, 0x063e,
+ 0x6c1b, 0x1503,
+ 0x6c23, 0x1505,
+ 0x6c24, 0x1504,
+ 0x6c34, 0x0a2b,
+ 0x6c37, 0x0dab,
+ 0x6c38, 0x04ec,
+ 0x6c3e, 0x0d59,
+ 0x6c3f, 0x213e,
+ 0x6c40, 0x0c11,
+ 0x6c41, 0x094b,
+ 0x6c42, 0x067b,
+ 0x6c4e, 0x0d5a,
+ 0x6c50, 0x08da,
+ 0x6c55, 0x1507,
+ 0x6c57, 0x05fc,
+ 0x6c5a, 0x051a,
+ 0x6c5c, 0x213f,
+ 0x6c5d, 0x0cca,
+ 0x6c5e, 0x1506,
+ 0x6c5f, 0x07d0,
+ 0x6c60, 0x0b91,
+ 0x6c62, 0x1508,
+ 0x6c68, 0x1510,
+ 0x6c6a, 0x1509,
+ 0x6c6f, 0x2141,
+ 0x6c70, 0x0b21,
+ 0x6c72, 0x067c,
+ 0x6c73, 0x1511,
+ 0x6c7a, 0x073e,
+ 0x6c7d, 0x063f,
+ 0x6c7e, 0x150f,
+ 0x6c81, 0x150d,
+ 0x6c82, 0x150a,
+ 0x6c83, 0x0f4a,
+ 0x6c86, 0x2140,
+ 0x6c88, 0x0bdc,
+ 0x6c8c, 0x0cb1,
+ 0x6c8d, 0x150b,
+ 0x6c90, 0x1513,
+ 0x6c92, 0x1512,
+ 0x6c93, 0x06f9,
+ 0x6c96, 0x052d,
+ 0x6c99, 0x082b,
+ 0x6c9a, 0x150c,
+ 0x6c9b, 0x150e,
+ 0x6ca1, 0x0e85,
+ 0x6ca2, 0x0b54,
+ 0x6cab, 0x0ea5,
+ 0x6cae, 0x151b,
+ 0x6cb1, 0x151c,
+ 0x6cb3, 0x054f,
+ 0x6cb8, 0x0df8,
+ 0x6cb9, 0x0f09,
+ 0x6cba, 0x151e,
+ 0x6cbb, 0x08cf,
+ 0x6cbc, 0x09aa,
+ 0x6cbd, 0x1517,
+ 0x6cbe, 0x151d,
+ 0x6cbf, 0x050a,
+ 0x6cc1, 0x06af,
+ 0x6cc4, 0x1514,
+ 0x6cc5, 0x1519,
+ 0x6cc9, 0x0a98,
+ 0x6cca, 0x0d27,
+ 0x6ccc, 0x0d7b,
+ 0x6cd3, 0x1516,
+ 0x6cd5, 0x0e4f,
+ 0x6cd7, 0x1518,
+ 0x6cd9, 0x1521,
+ 0x6cda, 0x2142,
+ 0x6cdb, 0x151f,
+ 0x6cdd, 0x151a,
+ 0x6ce1, 0x0e50,
+ 0x6ce2, 0x0cfe,
+ 0x6ce3, 0x067d,
+ 0x6ce5, 0x0c1f,
+ 0x6ce8, 0x0bab,
+ 0x6cea, 0x1522,
+ 0x6cef, 0x1520,
+ 0x6cf0, 0x0b39,
+ 0x6cf1, 0x1515,
+ 0x6cf3, 0x04ed,
+ 0x6d04, 0x2143,
+ 0x6d0b, 0x0f38,
+ 0x6d0c, 0x152d,
+ 0x6d12, 0x152c,
+ 0x6d17, 0x0a9a,
+ 0x6d19, 0x1529,
+ 0x6d1b, 0x0f56,
+ 0x6d1e, 0x0c8e,
+ 0x6d1f, 0x1523,
+ 0x6d25, 0x0be1,
+ 0x6d29, 0x04ee,
+ 0x6d2a, 0x07d1,
+ 0x6d2b, 0x1526,
+ 0x6d32, 0x0931,
+ 0x6d33, 0x152b,
+ 0x6d35, 0x152a,
+ 0x6d36, 0x1525,
+ 0x6d38, 0x1528,
+ 0x6d3b, 0x05c6,
+ 0x6d3d, 0x1527,
+ 0x6d3e, 0x0cff,
+ 0x6d41, 0x0f76,
+ 0x6d44, 0x09dc,
+ 0x6d45, 0x0a99,
+ 0x6d59, 0x1533,
+ 0x6d5a, 0x1531,
+ 0x6d5c, 0x0dbf,
+ 0x6d63, 0x152e,
+ 0x6d64, 0x1530,
+ 0x6d66, 0x04dc,
+ 0x6d69, 0x07d2,
+ 0x6d6a, 0x0fd8,
+ 0x6d6c, 0x059b,
+ 0x6d6e, 0x0dd4,
+ 0x6d6f, 0x2145,
+ 0x6d74, 0x0f4b,
+ 0x6d77, 0x0582,
+ 0x6d78, 0x0a01,
+ 0x6d79, 0x1532,
+ 0x6d85, 0x1537,
+ 0x6d87, 0x2144,
+ 0x6d88, 0x09ab,
+ 0x6d8c, 0x0f1a,
+ 0x6d8e, 0x1534,
+ 0x6d93, 0x152f,
+ 0x6d95, 0x1535,
+ 0x6d96, 0x2146,
+ 0x6d99, 0x0fa6,
+ 0x6d9b, 0x0c6d,
+ 0x6d9c, 0x0c9a,
+ 0x6dac, 0x2147,
+ 0x6daf, 0x0594,
+ 0x6db2, 0x04f7,
+ 0x6db5, 0x153b,
+ 0x6db8, 0x153e,
+ 0x6dbc, 0x0f8b,
+ 0x6dc0, 0x0f4e,
+ 0x6dc5, 0x1545,
+ 0x6dc6, 0x153f,
+ 0x6dc7, 0x153c,
+ 0x6dcb, 0x0f9c,
+ 0x6dcc, 0x1542,
+ 0x6dcf, 0x2148,
+ 0x6dd1, 0x0954,
+ 0x6dd2, 0x1544,
+ 0x6dd5, 0x1549,
+ 0x6dd8, 0x0c6b,
+ 0x6dd9, 0x1547,
+ 0x6dde, 0x1541,
+ 0x6de1, 0x0b76,
+ 0x6de4, 0x1548,
+ 0x6de6, 0x153d,
+ 0x6de8, 0x1543,
+ 0x6dea, 0x154a,
+ 0x6deb, 0x04c0,
+ 0x6dec, 0x1540,
+ 0x6dee, 0x154b,
+ 0x6df1, 0x0a02,
+ 0x6df2, 0x214a,
+ 0x6df3, 0x0969,
+ 0x6df5, 0x0df5,
+ 0x6df7, 0x081e,
+ 0x6df8, 0x2149,
+ 0x6df9, 0x1538,
+ 0x6dfa, 0x1546,
+ 0x6dfb, 0x0c34,
+ 0x6dfc, 0x214b,
+ 0x6e05, 0x0a5a,
+ 0x6e07, 0x05c7,
+ 0x6e08, 0x0841,
+ 0x6e09, 0x09ac,
+ 0x6e0a, 0x153a,
+ 0x6e0b, 0x094c,
+ 0x6e13, 0x0722,
+ 0x6e15, 0x1539,
+ 0x6e19, 0x154f,
+ 0x6e1a, 0x0977,
+ 0x6e1b, 0x076e,
+ 0x6e1d, 0x155e,
+ 0x6e1f, 0x1558,
+ 0x6e20, 0x068e,
+ 0x6e21, 0x0c49,
+ 0x6e23, 0x1553,
+ 0x6e24, 0x155c,
+ 0x6e25, 0x0473,
+ 0x6e26, 0x04d4,
+ 0x6e27, 0x214e,
+ 0x6e29, 0x0539,
+ 0x6e2b, 0x1555,
+ 0x6e2c, 0x0b0c,
+ 0x6e2d, 0x154c,
+ 0x6e2e, 0x154e,
+ 0x6e2f, 0x07d3,
+ 0x6e38, 0x155f,
+ 0x6e39, 0x214c,
+ 0x6e3a, 0x155a,
+ 0x6e3c, 0x214f,
+ 0x6e3e, 0x1552,
+ 0x6e43, 0x1559,
+ 0x6e4a, 0x0eb7,
+ 0x6e4d, 0x1557,
+ 0x6e4e, 0x155b,
+ 0x6e56, 0x0784,
+ 0x6e58, 0x09ad,
+ 0x6e5b, 0x0b77,
+ 0x6e5c, 0x214d,
+ 0x6e5f, 0x1551,
+ 0x6e67, 0x0f19,
+ 0x6e6b, 0x1554,
+ 0x6e6e, 0x154d,
+ 0x6e6f, 0x0c6c,
+ 0x6e72, 0x1550,
+ 0x6e76, 0x1556,
+ 0x6e7e, 0x0ff7,
+ 0x6e7f, 0x08ea,
+ 0x6e80, 0x0eac,
+ 0x6e82, 0x1560,
+ 0x6e8c, 0x0d42,
+ 0x6e8f, 0x156c,
+ 0x6e90, 0x076f,
+ 0x6e96, 0x096a,
+ 0x6e98, 0x1562,
+ 0x6e9c, 0x0f77,
+ 0x6e9d, 0x07d4,
+ 0x6e9f, 0x156f,
+ 0x6ea2, 0x04b2,
+ 0x6ea5, 0x156d,
+ 0x6eaa, 0x1561,
+ 0x6eaf, 0x1567,
+ 0x6eb2, 0x1569,
+ 0x6eb6, 0x0f39,
+ 0x6eb7, 0x1564,
+ 0x6eba, 0x0c28,
+ 0x6ebd, 0x1566,
+ 0x6ebf, 0x2150,
+ 0x6ec2, 0x156e,
+ 0x6ec4, 0x1568,
+ 0x6ec5, 0x0ed3,
+ 0x6ec9, 0x1563,
+ 0x6ecb, 0x08ce,
+ 0x6ecc, 0x157b,
+ 0x6ed1, 0x05c8,
+ 0x6ed3, 0x1565,
+ 0x6ed4, 0x156a,
+ 0x6edd, 0x0b4c,
+ 0x6ede, 0x0b3a,
+ 0x6eec, 0x1573,
+ 0x6eef, 0x1579,
+ 0x6ef2, 0x1577,
+ 0x6ef4, 0x0c23,
+ 0x6ef7, 0x157e,
+ 0x6ef8, 0x1574,
+ 0x6efe, 0x1575,
+ 0x6eff, 0x155d,
+ 0x6f01, 0x0693,
+ 0x6f02, 0x0dac,
+ 0x6f06, 0x08eb,
+ 0x6f09, 0x0809,
+ 0x6f0f, 0x0fd9,
+ 0x6f11, 0x1571,
+ 0x6f13, 0x157d,
+ 0x6f14, 0x050b,
+ 0x6f15, 0x0ae8,
+ 0x6f20, 0x0d2f,
+ 0x6f22, 0x05fd,
+ 0x6f23, 0x0fc2,
+ 0x6f2b, 0x0ead,
+ 0x6f2c, 0x0bee,
+ 0x6f31, 0x1578,
+ 0x6f32, 0x157a,
+ 0x6f38, 0x0ab4,
+ 0x6f3e, 0x157c,
+ 0x6f3f, 0x1576,
+ 0x6f41, 0x1570,
+ 0x6f45, 0x05ff,
+ 0x6f51, 0x1e60,
+ 0x6f54, 0x073f,
+ 0x6f58, 0x158a,
+ 0x6f5b, 0x1585,
+ 0x6f5c, 0x0a9c,
+ 0x6f5f, 0x05c1,
+ 0x6f64, 0x096b,
+ 0x6f66, 0x158e,
+ 0x6f6d, 0x1587,
+ 0x6f6e, 0x0bc8,
+ 0x6f6f, 0x1584,
+ 0x6f70, 0x0bf5,
+ 0x6f74, 0x15a7,
+ 0x6f78, 0x1581,
+ 0x6f7a, 0x1580,
+ 0x6f7c, 0x1589,
+ 0x6f80, 0x1583,
+ 0x6f81, 0x1582,
+ 0x6f82, 0x1588,
+ 0x6f84, 0x0a45,
+ 0x6f86, 0x157f,
+ 0x6f88, 0x2151,
+ 0x6f8e, 0x158b,
+ 0x6f91, 0x158c,
+ 0x6f97, 0x05fe,
+ 0x6fa1, 0x1591,
+ 0x6fa3, 0x1590,
+ 0x6fa4, 0x1592,
+ 0x6faa, 0x1595,
+ 0x6fb1, 0x0c3d,
+ 0x6fb3, 0x158f,
+ 0x6fb5, 0x2152,
+ 0x6fb9, 0x1593,
+ 0x6fc0, 0x0739,
+ 0x6fc1, 0x0b59,
+ 0x6fc2, 0x158d,
+ 0x6fc3, 0x0cf1,
+ 0x6fc6, 0x1594,
+ 0x6fd4, 0x1599,
+ 0x6fd5, 0x1597,
+ 0x6fd8, 0x159a,
+ 0x6fdb, 0x159d,
+ 0x6fdf, 0x1596,
+ 0x6fe0, 0x07fc,
+ 0x6fe1, 0x0cde,
+ 0x6fe4, 0x1536,
+ 0x6feb, 0x0f5e,
+ 0x6fec, 0x1598,
+ 0x6fee, 0x159c,
+ 0x6fef, 0x0b55,
+ 0x6ff1, 0x159b,
+ 0x6ff3, 0x1586,
+ 0x6ff5, 0x2153,
+ 0x6ff6, 0x1ba4,
+ 0x6ffa, 0x15a0,
+ 0x6ffe, 0x15a4,
+ 0x7001, 0x15a2,
+ 0x7005, 0x2154,
+ 0x7006, 0x1e50,
+ 0x7007, 0x2155,
+ 0x7009, 0x159e,
+ 0x700b, 0x159f,
+ 0x700f, 0x15a3,
+ 0x7011, 0x15a1,
+ 0x7015, 0x0dc0,
+ 0x7018, 0x15a9,
+ 0x701a, 0x15a6,
+ 0x701b, 0x15a5,
+ 0x701d, 0x15a8,
+ 0x701e, 0x0cac,
+ 0x701f, 0x15aa,
+ 0x7026, 0x0bb3,
+ 0x7027, 0x0b4d,
+ 0x7028, 0x2156,
+ 0x702c, 0x0a49,
+ 0x7030, 0x15ab,
+ 0x7032, 0x15ad,
+ 0x703e, 0x15ac,
+ 0x704c, 0x1572,
+ 0x7051, 0x15ae,
+ 0x7058, 0x0cbf,
+ 0x7063, 0x15af,
+ 0x706b, 0x0550,
+ 0x706f, 0x0c6e,
+ 0x7070, 0x0583,
+ 0x7078, 0x067e,
+ 0x707c, 0x090a,
+ 0x707d, 0x0842,
+ 0x7085, 0x2157,
+ 0x7089, 0x0fcd,
+ 0x708a, 0x0a2c,
+ 0x708e, 0x050c,
+ 0x7092, 0x15b1,
+ 0x7099, 0x15b0,
+ 0x70ab, 0x2158,
+ 0x70ac, 0x15b4,
+ 0x70ad, 0x0b78,
+ 0x70ae, 0x15b7,
+ 0x70af, 0x15b2,
+ 0x70b3, 0x15b6,
+ 0x70b8, 0x15b5,
+ 0x70b9, 0x0c3a,
+ 0x70ba, 0x049d,
+ 0x70bb, 0x20ad,
+ 0x70c8, 0x0fbd,
+ 0x70cb, 0x15b9,
+ 0x70cf, 0x04ca,
+ 0x70d9, 0x15bb,
+ 0x70dd, 0x15ba,
+ 0x70df, 0x15b8,
+ 0x70f1, 0x15b3,
+ 0x70f9, 0x0e51,
+ 0x70fd, 0x15bd,
+ 0x7104, 0x215a,
+ 0x7109, 0x15bc,
+ 0x710f, 0x2159,
+ 0x7114, 0x050d,
+ 0x7119, 0x15bf,
+ 0x711a, 0x0e02,
+ 0x711c, 0x15be,
+ 0x7121, 0x0ec1,
+ 0x7126, 0x09af,
+ 0x7130, 0x1ddc,
+ 0x7136, 0x0ab5,
+ 0x713c, 0x09ae,
+ 0x7146, 0x215c,
+ 0x7149, 0x0fc3,
+ 0x714c, 0x15c5,
+ 0x714e, 0x0a9d,
+ 0x7155, 0x15c1,
+ 0x7156, 0x15c6,
+ 0x7159, 0x050e,
+ 0x715c, 0x215b,
+ 0x7162, 0x15c4,
+ 0x7164, 0x0d17,
+ 0x7165, 0x15c0,
+ 0x7166, 0x15c3,
+ 0x7167, 0x09b0,
+ 0x7169, 0x0d65,
+ 0x716c, 0x15c7,
+ 0x716e, 0x08fd,
+ 0x717d, 0x0a9e,
+ 0x7184, 0x15ca,
+ 0x7188, 0x15c2,
+ 0x718a, 0x06fd,
+ 0x718f, 0x15c8,
+ 0x7194, 0x0f3a,
+ 0x7195, 0x15cb,
+ 0x7199, 0x205d,
+ 0x719f, 0x0959,
+ 0x71a8, 0x15cc,
+ 0x71ac, 0x15cd,
+ 0x71b1, 0x0ce4,
+ 0x71b9, 0x15cf,
+ 0x71be, 0x15d0,
+ 0x71c1, 0x215f,
+ 0x71c3, 0x0ce9,
+ 0x71c8, 0x0c6f,
+ 0x71c9, 0x15d2,
+ 0x71ce, 0x15d4,
+ 0x71d0, 0x0f9d,
+ 0x71d2, 0x15d1,
+ 0x71d4, 0x15d3,
+ 0x71d5, 0x050f,
+ 0x71d7, 0x15ce,
+ 0x71df, 0x114e,
+ 0x71e0, 0x15d5,
+ 0x71e5, 0x0ae9,
+ 0x71e6, 0x0886,
+ 0x71e7, 0x15d7,
+ 0x71ec, 0x15d6,
+ 0x71ed, 0x09ea,
+ 0x71ee, 0x10ee,
+ 0x71f5, 0x15d8,
+ 0x71f9, 0x15da,
+ 0x71fb, 0x15c9,
+ 0x71fc, 0x15d9,
+ 0x71fe, 0x2160,
+ 0x71ff, 0x15db,
+ 0x7206, 0x0d30,
+ 0x720d, 0x15dc,
+ 0x7210, 0x15dd,
+ 0x721b, 0x15de,
+ 0x7228, 0x15df,
+ 0x722a, 0x0bfa,
+ 0x722c, 0x15e1,
+ 0x722d, 0x15e0,
+ 0x7230, 0x15e2,
+ 0x7232, 0x15e3,
+ 0x7235, 0x090b,
+ 0x7236, 0x0dd5,
+ 0x723a, 0x0ef8,
+ 0x723b, 0x15e4,
+ 0x723d, 0x0ad8,
+ 0x723e, 0x08d0,
+ 0x723f, 0x15e6,
+ 0x7246, 0x15e8,
+ 0x7247, 0x0e22,
+ 0x7248, 0x0d5b,
+ 0x724b, 0x15e9,
+ 0x724c, 0x0d0d,
+ 0x7252, 0x0bc9,
+ 0x7258, 0x15ea,
+ 0x7259, 0x0567,
+ 0x725b, 0x0687,
+ 0x725d, 0x0ed2,
+ 0x725f, 0x0ec2,
+ 0x7261, 0x0534,
+ 0x7262, 0x0fda,
+ 0x7267, 0x0e80,
+ 0x7269, 0x0dfa,
+ 0x7272, 0x0a5b,
+ 0x7274, 0x15eb,
+ 0x7279, 0x0c9b,
+ 0x727d, 0x0757,
+ 0x727e, 0x15ec,
+ 0x7280, 0x0844,
+ 0x7281, 0x15ee,
+ 0x7282, 0x15ed,
+ 0x7287, 0x15ef,
+ 0x7292, 0x15f0,
+ 0x7296, 0x15f1,
+ 0x72a0, 0x0658,
+ 0x72a2, 0x15f2,
+ 0x72a7, 0x15f3,
+ 0x72ac, 0x0758,
+ 0x72af, 0x0d5c,
+ 0x72b1, 0x2161,
+ 0x72b2, 0x15f5,
+ 0x72b6, 0x09dd,
+ 0x72b9, 0x15f4,
+ 0x72be, 0x2162,
+ 0x72c2, 0x06b0,
+ 0x72c3, 0x15f6,
+ 0x72c4, 0x15f8,
+ 0x72c6, 0x15f7,
+ 0x72ce, 0x15f9,
+ 0x72d0, 0x0785,
+ 0x72d2, 0x15fa,
+ 0x72d7, 0x06e1,
+ 0x72d9, 0x0ac2,
+ 0x72db, 0x080f,
+ 0x72e0, 0x15fc,
+ 0x72e2, 0x15fb,
+ 0x72e9, 0x0919,
+ 0x72ec, 0x0ca0,
+ 0x72ed, 0x06b1,
+ 0x72f7, 0x15ff,
+ 0x72f8, 0x0b6a,
+ 0x72f9, 0x15fe,
+ 0x72fc, 0x0fdb,
+ 0x72fd, 0x0d18,
+ 0x730a, 0x1602,
+ 0x7316, 0x1604,
+ 0x7317, 0x1601,
+ 0x731b, 0x0ee0,
+ 0x731c, 0x1603,
+ 0x731d, 0x1605,
+ 0x731f, 0x0f8c,
+ 0x7324, 0x2163,
+ 0x7325, 0x1609,
+ 0x7329, 0x1608,
+ 0x732a, 0x0bb4,
+ 0x732b, 0x0ce3,
+ 0x732e, 0x0759,
+ 0x732f, 0x1607,
+ 0x7334, 0x1606,
+ 0x7336, 0x0f1b,
+ 0x733e, 0x160a,
+ 0x733f, 0x0510,
+ 0x7344, 0x0808,
+ 0x7345, 0x08b0,
+ 0x734e, 0x160b,
+ 0x7357, 0x160e,
+ 0x7363, 0x094d,
+ 0x7368, 0x1610,
+ 0x736a, 0x160f,
+ 0x7370, 0x1611,
+ 0x7372, 0x05ab,
+ 0x7375, 0x1613,
+ 0x7377, 0x2165,
+ 0x7378, 0x1612,
+ 0x737a, 0x1615,
+ 0x737b, 0x1614,
+ 0x7384, 0x0770,
+ 0x7387, 0x0f70,
+ 0x7389, 0x06c4,
+ 0x738b, 0x0526,
+ 0x7396, 0x06e2,
+ 0x73a9, 0x061d,
+ 0x73b2, 0x0fb0,
+ 0x73b3, 0x1617,
+ 0x73bb, 0x1619,
+ 0x73bd, 0x2166,
+ 0x73c0, 0x161a,
+ 0x73c2, 0x0551,
+ 0x73c8, 0x1616,
+ 0x73c9, 0x2167,
+ 0x73ca, 0x0887,
+ 0x73cd, 0x0bdd,
+ 0x73ce, 0x1618,
+ 0x73d2, 0x216a,
+ 0x73d6, 0x2168,
+ 0x73de, 0x161d,
+ 0x73e0, 0x091a,
+ 0x73e3, 0x2169,
+ 0x73e5, 0x161b,
+ 0x73ea, 0x0714,
+ 0x73ed, 0x0d5d,
+ 0x73ee, 0x161c,
+ 0x73f1, 0x1637,
+ 0x73f5, 0x216c,
+ 0x73f8, 0x1622,
+ 0x73fe, 0x0771,
+ 0x7403, 0x067f,
+ 0x7405, 0x161f,
+ 0x7406, 0x0f67,
+ 0x7407, 0x216b,
+ 0x7409, 0x0f78,
+ 0x7422, 0x0b56,
+ 0x7425, 0x1621,
+ 0x7426, 0x216d,
+ 0x7429, 0x216f,
+ 0x742a, 0x216e,
+ 0x742e, 0x2170,
+ 0x7432, 0x1623,
+ 0x7433, 0x0f9e,
+ 0x7434, 0x06cf,
+ 0x7435, 0x0d90,
+ 0x7436, 0x0d00,
+ 0x743a, 0x1624,
+ 0x743f, 0x1626,
+ 0x7441, 0x1629,
+ 0x7455, 0x1625,
+ 0x7459, 0x1628,
+ 0x745a, 0x079e,
+ 0x745b, 0x04ef,
+ 0x745c, 0x162a,
+ 0x745e, 0x0a36,
+ 0x745f, 0x1627,
+ 0x7460, 0x0fa4,
+ 0x7462, 0x2171,
+ 0x7463, 0x162d,
+ 0x7464, 0x1d35,
+ 0x7469, 0x162b,
+ 0x746a, 0x162e,
+ 0x746f, 0x1620,
+ 0x7470, 0x162c,
+ 0x7473, 0x082c,
+ 0x7476, 0x162f,
+ 0x747e, 0x1630,
+ 0x7483, 0x0f68,
+ 0x7489, 0x2172,
+ 0x748b, 0x1631,
+ 0x749e, 0x1632,
+ 0x749f, 0x2173,
+ 0x74a2, 0x161e,
+ 0x74a7, 0x1633,
+ 0x74b0, 0x0600,
+ 0x74bd, 0x08d1,
+ 0x74ca, 0x1634,
+ 0x74cf, 0x1635,
+ 0x74d4, 0x1636,
+ 0x74dc, 0x04dd,
+ 0x74e0, 0x1638,
+ 0x74e2, 0x0dad,
+ 0x74e3, 0x1639,
+ 0x74e6, 0x05e0,
+ 0x74e7, 0x163a,
+ 0x74e9, 0x163b,
+ 0x74ee, 0x163c,
+ 0x74f0, 0x163e,
+ 0x74f2, 0x163d,
+ 0x74f6, 0x0dc5,
+ 0x74f7, 0x1641,
+ 0x74f8, 0x1640,
+ 0x7501, 0x2174,
+ 0x7503, 0x1643,
+ 0x7504, 0x1642,
+ 0x7505, 0x1644,
+ 0x750c, 0x1645,
+ 0x750d, 0x1647,
+ 0x750e, 0x1646,
+ 0x7511, 0x080b,
+ 0x7513, 0x1649,
+ 0x7515, 0x1648,
+ 0x7518, 0x0601,
+ 0x751a, 0x0a19,
+ 0x751c, 0x0c36,
+ 0x751e, 0x164a,
+ 0x751f, 0x0a5c,
+ 0x7523, 0x0888,
+ 0x7525, 0x051b,
+ 0x7526, 0x164b,
+ 0x7528, 0x0f3b,
+ 0x752b, 0x0e33,
+ 0x752c, 0x164c,
+ 0x752f, 0x20f2,
+ 0x7530, 0x0c3e,
+ 0x7531, 0x0f1d,
+ 0x7532, 0x07d5,
+ 0x7533, 0x0a03,
+ 0x7537, 0x0b89,
+ 0x7538, 0x10c9,
+ 0x753a, 0x0bca,
+ 0x753b, 0x0568,
+ 0x753c, 0x164d,
+ 0x7544, 0x164e,
+ 0x7546, 0x1653,
+ 0x7549, 0x1651,
+ 0x754a, 0x1650,
+ 0x754b, 0x13c7,
+ 0x754c, 0x0584,
+ 0x754d, 0x164f,
+ 0x754f, 0x049e,
+ 0x7551, 0x0d3e,
+ 0x7554, 0x0d5e,
+ 0x7559, 0x0f79,
+ 0x755a, 0x1654,
+ 0x755b, 0x1652,
+ 0x755c, 0x0b9a,
+ 0x755d, 0x0a4a,
+ 0x7560, 0x0d3f,
+ 0x7562, 0x0d9f,
+ 0x7564, 0x1656,
+ 0x7565, 0x0f74,
+ 0x7566, 0x0723,
+ 0x7567, 0x1657,
+ 0x7569, 0x1655,
+ 0x756a, 0x0d6a,
+ 0x756b, 0x1658,
+ 0x756d, 0x1659,
+ 0x756f, 0x2175,
+ 0x7570, 0x049f,
+ 0x7573, 0x09de,
+ 0x7574, 0x165e,
+ 0x7576, 0x165b,
+ 0x7577, 0x0cc5,
+ 0x7578, 0x165a,
+ 0x757f, 0x0640,
+ 0x7582, 0x1661,
+ 0x7586, 0x165c,
+ 0x7589, 0x1660,
+ 0x758a, 0x165f,
+ 0x758b, 0x0d97,
+ 0x758e, 0x0ac4,
+ 0x758f, 0x0ac3,
+ 0x7591, 0x0659,
+ 0x7594, 0x1662,
+ 0x759a, 0x1663,
+ 0x759d, 0x1664,
+ 0x75a3, 0x1666,
+ 0x75a5, 0x1665,
+ 0x75ab, 0x04f8,
+ 0x75b1, 0x166e,
+ 0x75b2, 0x0d7c,
+ 0x75b3, 0x1668,
+ 0x75b5, 0x166a,
+ 0x75b8, 0x166c,
+ 0x75b9, 0x0a04,
+ 0x75bc, 0x166d,
+ 0x75bd, 0x166b,
+ 0x75be, 0x08ec,
+ 0x75c2, 0x1667,
+ 0x75c3, 0x1669,
+ 0x75c5, 0x0db4,
+ 0x75c7, 0x09b1,
+ 0x75ca, 0x1670,
+ 0x75cd, 0x166f,
+ 0x75d2, 0x1671,
+ 0x75d4, 0x08d2,
+ 0x75d5, 0x081f,
+ 0x75d8, 0x0c71,
+ 0x75d9, 0x1672,
+ 0x75db, 0x0be7,
+ 0x75de, 0x1674,
+ 0x75e2, 0x0f69,
+ 0x75e3, 0x1673,
+ 0x75e9, 0x0aeb,
+ 0x75f0, 0x1679,
+ 0x75f2, 0x167b,
+ 0x75f4, 0x0b92,
+ 0x75fa, 0x167a,
+ 0x75fc, 0x1677,
+ 0x75fe, 0x1675,
+ 0x7601, 0x1678,
+ 0x7609, 0x167f,
+ 0x760b, 0x167d,
+ 0x760d, 0x167e,
+ 0x761f, 0x1680,
+ 0x7620, 0x1682,
+ 0x7624, 0x1685,
+ 0x7626, 0x1e2d,
+ 0x7627, 0x1681,
+ 0x7630, 0x1687,
+ 0x7634, 0x1686,
+ 0x763b, 0x1688,
+ 0x7642, 0x0f8d,
+ 0x7646, 0x168b,
+ 0x7647, 0x1689,
+ 0x764c, 0x061e,
+ 0x7652, 0x0f0a,
+ 0x7656, 0x0e1a,
+ 0x7658, 0x168d,
+ 0x765c, 0x168c,
+ 0x7661, 0x168e,
+ 0x7667, 0x1693,
+ 0x7668, 0x1690,
+ 0x766c, 0x1694,
+ 0x7670, 0x1695,
+ 0x7672, 0x1696,
+ 0x7676, 0x1697,
+ 0x7678, 0x1698,
+ 0x767a, 0x0d43,
+ 0x767b, 0x0c4a,
+ 0x767c, 0x1699,
+ 0x767d, 0x0d28,
+ 0x767e, 0x0da6,
+ 0x7680, 0x169a,
+ 0x7682, 0x2176,
+ 0x7683, 0x169b,
+ 0x7684, 0x0c24,
+ 0x7686, 0x0585,
+ 0x7687, 0x07d6,
+ 0x7688, 0x169c,
+ 0x768b, 0x169d,
+ 0x768e, 0x169e,
+ 0x7690, 0x0877,
+ 0x7693, 0x16a0,
+ 0x7696, 0x169f,
+ 0x7699, 0x16a1,
+ 0x769b, 0x2179,
+ 0x769c, 0x2177,
+ 0x769e, 0x2178,
+ 0x76a6, 0x217a,
+ 0x76ae, 0x0d7d,
+ 0x76b0, 0x16a3,
+ 0x76b4, 0x16a4,
+ 0x76b7, 0x1d1c,
+ 0x76b8, 0x16a5,
+ 0x76bf, 0x087c,
+ 0x76c2, 0x16a8,
+ 0x76c3, 0x0d0c,
+ 0x76c6, 0x0e8d,
+ 0x76c8, 0x04f0,
+ 0x76ca, 0x04f9,
+ 0x76cd, 0x16a9,
+ 0x76d2, 0x16ab,
+ 0x76d6, 0x16aa,
+ 0x76d7, 0x0c6a,
+ 0x76db, 0x0a5d,
+ 0x76dc, 0x14d8,
+ 0x76de, 0x16ac,
+ 0x76df, 0x0ecd,
+ 0x76e1, 0x16ad,
+ 0x76e3, 0x0602,
+ 0x76e4, 0x0d6b,
+ 0x76e5, 0x16ae,
+ 0x76e7, 0x16af,
+ 0x76ea, 0x16b0,
+ 0x76ee, 0x0ee8,
+ 0x76f2, 0x0ee1,
+ 0x76f4, 0x0bda,
+ 0x76f8, 0x0aec,
+ 0x76fb, 0x16b2,
+ 0x76fe, 0x096c,
+ 0x7701, 0x09b2,
+ 0x7704, 0x16b5,
+ 0x7707, 0x16b4,
+ 0x7708, 0x16b3,
+ 0x7709, 0x0d91,
+ 0x770b, 0x0603,
+ 0x770c, 0x075d,
+ 0x771b, 0x16bb,
+ 0x771e, 0x16b8,
+ 0x771f, 0x0a05,
+ 0x7720, 0x0ebe,
+ 0x7724, 0x16b7,
+ 0x7725, 0x16b9,
+ 0x7729, 0x16b6,
+ 0x7737, 0x16bc,
+ 0x773a, 0x0bcb,
+ 0x773c, 0x061f,
+ 0x7740, 0x0ba3,
+ 0x7746, 0x217c,
+ 0x7747, 0x16be,
+ 0x775a, 0x16bf,
+ 0x775b, 0x16c2,
+ 0x7761, 0x0a2d,
+ 0x7762, 0x1ec5,
+ 0x7763, 0x0c9c,
+ 0x7765, 0x16c3,
+ 0x7766, 0x0e81,
+ 0x7768, 0x16c0,
+ 0x776b, 0x16c1,
+ 0x7779, 0x16c6,
+ 0x777e, 0x16c5,
+ 0x777f, 0x16c4,
+ 0x778b, 0x16c8,
+ 0x778e, 0x16c7,
+ 0x7791, 0x16c9,
+ 0x779e, 0x16cb,
+ 0x77a0, 0x16ca,
+ 0x77a5, 0x0e1d,
+ 0x77ac, 0x0960,
+ 0x77ad, 0x0f8e,
+ 0x77b0, 0x16cc,
+ 0x77b3, 0x0c8f,
+ 0x77b6, 0x16cd,
+ 0x77b9, 0x16ce,
+ 0x77bb, 0x16d2,
+ 0x77bc, 0x16d0,
+ 0x77bf, 0x16cf,
+ 0x77c7, 0x16d3,
+ 0x77cd, 0x16d4,
+ 0x77d7, 0x16d5,
+ 0x77da, 0x16d6,
+ 0x77db, 0x0ec3,
+ 0x77dc, 0x16d7,
+ 0x77e2, 0x0efc,
+ 0x77e3, 0x16d8,
+ 0x77e5, 0x0b8c,
+ 0x77e7, 0x0d20,
+ 0x77e9, 0x06e3,
+ 0x77ed, 0x0b79,
+ 0x77ee, 0x16d9,
+ 0x77ef, 0x06b2,
+ 0x77f3, 0x0a74,
+ 0x77fc, 0x16da,
+ 0x7802, 0x082d,
+ 0x780c, 0x16db,
+ 0x7812, 0x16dc,
+ 0x7814, 0x075a,
+ 0x7815, 0x0845,
+ 0x7820, 0x16de,
+ 0x7821, 0x217e,
+ 0x7825, 0x0c50,
+ 0x7826, 0x0846,
+ 0x7827, 0x0668,
+ 0x7832, 0x0e52,
+ 0x7834, 0x0d01,
+ 0x783a, 0x0c51,
+ 0x783f, 0x07ee,
+ 0x7845, 0x16e0,
+ 0x784e, 0x217f,
+ 0x785d, 0x09b3,
+ 0x7864, 0x2180,
+ 0x786b, 0x0f7a,
+ 0x786c, 0x07d7,
+ 0x786f, 0x075b,
+ 0x7872, 0x0d37,
+ 0x7874, 0x16e2,
+ 0x787a, 0x2181,
+ 0x787c, 0x16e4,
+ 0x7881, 0x079f,
+ 0x7886, 0x16e3,
+ 0x7887, 0x0c12,
+ 0x788c, 0x16e6,
+ 0x788d, 0x0595,
+ 0x788e, 0x16e1,
+ 0x7891, 0x0d7e,
+ 0x7893, 0x04d2,
+ 0x7895, 0x085c,
+ 0x7897, 0x0ff8,
+ 0x789a, 0x16e5,
+ 0x78a3, 0x16e7,
+ 0x78a7, 0x0e1b,
+ 0x78a9, 0x0a7d,
+ 0x78aa, 0x16e9,
+ 0x78af, 0x16ea,
+ 0x78b5, 0x16e8,
+ 0x78ba, 0x05ac,
+ 0x78bc, 0x16f0,
+ 0x78be, 0x16ef,
+ 0x78c1, 0x08d3,
+ 0x78c5, 0x16f1,
+ 0x78c6, 0x16ec,
+ 0x78ca, 0x16f2,
+ 0x78cb, 0x16ed,
+ 0x78d0, 0x0d6c,
+ 0x78d1, 0x16eb,
+ 0x78d4, 0x16ee,
+ 0x78da, 0x16f5,
+ 0x78e7, 0x16f4,
+ 0x78e8, 0x0e8f,
+ 0x78ec, 0x16f3,
+ 0x78ef, 0x04af,
+ 0x78f4, 0x16f7,
+ 0x78fd, 0x16f6,
+ 0x7901, 0x09b4,
+ 0x7907, 0x16f8,
+ 0x790e, 0x0ac5,
+ 0x7911, 0x16fa,
+ 0x7912, 0x16f9,
+ 0x7919, 0x16fb,
+ 0x7926, 0x16dd,
+ 0x792a, 0x16df,
+ 0x792b, 0x16fd,
+ 0x792c, 0x16fc,
+ 0x7930, 0x2182,
+ 0x793a, 0x08d4,
+ 0x793c, 0x0fb1,
+ 0x793e, 0x08fe,
+ 0x7940, 0x16fe,
+ 0x7941, 0x070d,
+ 0x7947, 0x065a,
+ 0x7948, 0x0641,
+ 0x7949, 0x08b1,
+ 0x7950, 0x0f1e,
+ 0x7953, 0x1704,
+ 0x7955, 0x1703,
+ 0x7956, 0x0ac6,
+ 0x7957, 0x1700,
+ 0x795a, 0x1702,
+ 0x795d, 0x0955,
+ 0x795e, 0x0a06,
+ 0x795f, 0x1701,
+ 0x7960, 0x16ff,
+ 0x7962, 0x0ce0,
+ 0x7965, 0x09b5,
+ 0x7968, 0x0dae,
+ 0x796d, 0x0847,
+ 0x7977, 0x0c72,
+ 0x797a, 0x1705,
+ 0x797f, 0x1706,
+ 0x7980, 0x171c,
+ 0x7981, 0x06d0,
+ 0x7984, 0x0fe3,
+ 0x7985, 0x0ab7,
+ 0x798a, 0x1707,
+ 0x798d, 0x0552,
+ 0x798e, 0x0c13,
+ 0x798f, 0x0df1,
+ 0x7994, 0x2186,
+ 0x799b, 0x2188,
+ 0x799d, 0x1708,
+ 0x79a6, 0x0694,
+ 0x79a7, 0x1709,
+ 0x79aa, 0x170b,
+ 0x79ae, 0x170c,
+ 0x79b0, 0x0cdf,
+ 0x79b1, 0x1e4e,
+ 0x79b3, 0x170d,
+ 0x79b9, 0x170e,
+ 0x79bd, 0x06d1,
+ 0x79be, 0x0553,
+ 0x79bf, 0x0c9d,
+ 0x79c0, 0x0932,
+ 0x79c1, 0x08b2,
+ 0x79c9, 0x1710,
+ 0x79cb, 0x0933,
+ 0x79d1, 0x054a,
+ 0x79d2, 0x0db5,
+ 0x79d5, 0x1711,
+ 0x79d8, 0x0d7f,
+ 0x79df, 0x0ac7,
+ 0x79e1, 0x1714,
+ 0x79e3, 0x1715,
+ 0x79e4, 0x0d1f,
+ 0x79e6, 0x0a07,
+ 0x79e7, 0x1712,
+ 0x79e9, 0x0b9f,
+ 0x79ec, 0x1713,
+ 0x79f0, 0x09b6,
+ 0x79fb, 0x04a0,
+ 0x7a00, 0x0643,
+ 0x7a08, 0x1716,
+ 0x7a0b, 0x0c14,
+ 0x7a0d, 0x1717,
+ 0x7a0e, 0x0a6b,
+ 0x7a14, 0x0eb9,
+ 0x7a17, 0x0d95,
+ 0x7a18, 0x1718,
+ 0x7a1a, 0x0b93,
+ 0x7a1c, 0x0f8f,
+ 0x7a1f, 0x171b,
+ 0x7a20, 0x171a,
+ 0x7a2e, 0x091b,
+ 0x7a31, 0x171d,
+ 0x7a32, 0x04b4,
+ 0x7a37, 0x1720,
+ 0x7a3b, 0x171e,
+ 0x7a3c, 0x0554,
+ 0x7a3d, 0x0724,
+ 0x7a3e, 0x171f,
+ 0x7a3f, 0x07d8,
+ 0x7a40, 0x0804,
+ 0x7a42, 0x0e36,
+ 0x7a43, 0x1721,
+ 0x7a46, 0x0e82,
+ 0x7a49, 0x1723,
+ 0x7a4d, 0x0a75,
+ 0x7a4e, 0x04f1,
+ 0x7a4f, 0x053a,
+ 0x7a50, 0x0470,
+ 0x7a57, 0x1722,
+ 0x7a61, 0x1724,
+ 0x7a63, 0x09df,
+ 0x7a69, 0x1726,
+ 0x7a6b, 0x05ad,
+ 0x7a70, 0x1728,
+ 0x7a74, 0x0740,
+ 0x7a76, 0x0680,
+ 0x7a79, 0x1729,
+ 0x7a7a, 0x06ed,
+ 0x7a7d, 0x172a,
+ 0x7a7f, 0x0aa0,
+ 0x7a81, 0x0ca5,
+ 0x7a83, 0x0a84,
+ 0x7a84, 0x0865,
+ 0x7a88, 0x172b,
+ 0x7a92, 0x0ba0,
+ 0x7a93, 0x0aed,
+ 0x7a95, 0x172d,
+ 0x7a96, 0x172f,
+ 0x7a97, 0x172c,
+ 0x7a98, 0x172e,
+ 0x7a9f, 0x06f8,
+ 0x7aa9, 0x1730,
+ 0x7aaa, 0x06fc,
+ 0x7aae, 0x0681,
+ 0x7aaf, 0x0f3c,
+ 0x7ab0, 0x1732,
+ 0x7ab6, 0x1733,
+ 0x7aba, 0x04d0,
+ 0x7abf, 0x1736,
+ 0x7ac3, 0x05d4,
+ 0x7ac4, 0x1735,
+ 0x7ac5, 0x1734,
+ 0x7ac7, 0x1738,
+ 0x7ac8, 0x1731,
+ 0x7aca, 0x1739,
+ 0x7acb, 0x0f71,
+ 0x7acd, 0x173a,
+ 0x7acf, 0x173b,
+ 0x7ad1, 0x2189,
+ 0x7ad2, 0x11c5,
+ 0x7ad3, 0x173d,
+ 0x7ad5, 0x173c,
+ 0x7ad9, 0x173e,
+ 0x7adc, 0x0f7d,
+ 0x7add, 0x1740,
+ 0x7adf, 0x1c08,
+ 0x7ae0, 0x09b7,
+ 0x7ae1, 0x1741,
+ 0x7ae3, 0x0961,
+ 0x7ae5, 0x0c90,
+ 0x7ae6, 0x1743,
+ 0x7ae7, 0x218a,
+ 0x7aea, 0x0b66,
+ 0x7aeb, 0x218c,
+ 0x7aed, 0x1744,
+ 0x7aef, 0x0b7a,
+ 0x7af0, 0x1745,
+ 0x7af6, 0x069d,
+ 0x7af8, 0x1076,
+ 0x7af9, 0x0b9b,
+ 0x7afa, 0x08df,
+ 0x7aff, 0x0604,
+ 0x7b02, 0x1746,
+ 0x7b04, 0x1753,
+ 0x7b06, 0x1749,
+ 0x7b08, 0x0682,
+ 0x7b0a, 0x1748,
+ 0x7b0b, 0x1755,
+ 0x7b0f, 0x1747,
+ 0x7b11, 0x09b8,
+ 0x7b18, 0x174b,
+ 0x7b1b, 0x0c25,
+ 0x7b1e, 0x174d,
+ 0x7b20, 0x05bc,
+ 0x7b25, 0x0a20,
+ 0x7b26, 0x0dd6,
+ 0x7b28, 0x174f,
+ 0x7b2c, 0x0b48,
+ 0x7b33, 0x174a,
+ 0x7b35, 0x174e,
+ 0x7b36, 0x1750,
+ 0x7b39, 0x086b,
+ 0x7b45, 0x1757,
+ 0x7b46, 0x0da0,
+ 0x7b48, 0x0d3a,
+ 0x7b49, 0x0c73,
+ 0x7b4b, 0x06d2,
+ 0x7b4c, 0x1756,
+ 0x7b4d, 0x1754,
+ 0x7b4f, 0x0d49,
+ 0x7b50, 0x1751,
+ 0x7b51, 0x0b9c,
+ 0x7b52, 0x0c75,
+ 0x7b54, 0x0c74,
+ 0x7b56, 0x0866,
+ 0x7b5d, 0x1769,
+ 0x7b65, 0x1759,
+ 0x7b67, 0x175b,
+ 0x7b6c, 0x175e,
+ 0x7b6e, 0x175f,
+ 0x7b70, 0x175c,
+ 0x7b74, 0x175a,
+ 0x7b75, 0x1758,
+ 0x7b7a, 0x1752,
+ 0x7b86, 0x0e1f,
+ 0x7b87, 0x0555,
+ 0x7b8b, 0x1766,
+ 0x7b8d, 0x1763,
+ 0x7b8f, 0x1768,
+ 0x7b92, 0x1767,
+ 0x7b94, 0x0d29,
+ 0x7b95, 0x0eb3,
+ 0x7b97, 0x0889,
+ 0x7b98, 0x1761,
+ 0x7b99, 0x176a,
+ 0x7b9a, 0x1765,
+ 0x7b9c, 0x1764,
+ 0x7b9d, 0x1760,
+ 0x7b9e, 0x218d,
+ 0x7b9f, 0x1762,
+ 0x7ba1, 0x0605,
+ 0x7baa, 0x0b7b,
+ 0x7bad, 0x0aa1,
+ 0x7bb1, 0x0d36,
+ 0x7bb4, 0x176f,
+ 0x7bb8, 0x0d38,
+ 0x7bc0, 0x0a85,
+ 0x7bc1, 0x176c,
+ 0x7bc4, 0x0d63,
+ 0x7bc6, 0x1770,
+ 0x7bc7, 0x0e23,
+ 0x7bc9, 0x0b99,
+ 0x7bcb, 0x176b,
+ 0x7bcc, 0x176d,
+ 0x7bcf, 0x176e,
+ 0x7bdd, 0x1771,
+ 0x7be0, 0x08f0,
+ 0x7be4, 0x0c9e,
+ 0x7be5, 0x1776,
+ 0x7be6, 0x1775,
+ 0x7be9, 0x1772,
+ 0x7bed, 0x0fdc,
+ 0x7bf3, 0x177b,
+ 0x7bf6, 0x177f,
+ 0x7bf7, 0x177c,
+ 0x7c00, 0x1778,
+ 0x7c07, 0x1779,
+ 0x7c0d, 0x177e,
+ 0x7c11, 0x1773,
+ 0x7c12, 0x10ea,
+ 0x7c13, 0x177a,
+ 0x7c14, 0x1774,
+ 0x7c17, 0x177d,
+ 0x7c1e, 0x1e3b,
+ 0x7c1f, 0x1783,
+ 0x7c21, 0x0606,
+ 0x7c23, 0x1780,
+ 0x7c27, 0x1781,
+ 0x7c2a, 0x1782,
+ 0x7c2b, 0x1785,
+ 0x7c37, 0x1784,
+ 0x7c38, 0x0d8a,
+ 0x7c3d, 0x1786,
+ 0x7c3e, 0x0fc4,
+ 0x7c3f, 0x0e3d,
+ 0x7c40, 0x178b,
+ 0x7c43, 0x1788,
+ 0x7c4c, 0x1787,
+ 0x7c4d, 0x0a76,
+ 0x7c4f, 0x178a,
+ 0x7c50, 0x178c,
+ 0x7c54, 0x1789,
+ 0x7c56, 0x1790,
+ 0x7c58, 0x178d,
+ 0x7c5f, 0x178e,
+ 0x7c60, 0x1777,
+ 0x7c64, 0x178f,
+ 0x7c65, 0x1791,
+ 0x7c6c, 0x1792,
+ 0x7c73, 0x0e16,
+ 0x7c75, 0x1793,
+ 0x7c7e, 0x0eee,
+ 0x7c81, 0x06c6,
+ 0x7c82, 0x06ff,
+ 0x7c83, 0x1794,
+ 0x7c89, 0x0e04,
+ 0x7c8b, 0x0a2e,
+ 0x7c8d, 0x0ebc,
+ 0x7c90, 0x1795,
+ 0x7c92, 0x0f7b,
+ 0x7c95, 0x0d2a,
+ 0x7c97, 0x0ac8,
+ 0x7c98, 0x0cea,
+ 0x7c9b, 0x0957,
+ 0x7c9f, 0x0484,
+ 0x7ca1, 0x179a,
+ 0x7ca2, 0x1798,
+ 0x7ca4, 0x1796,
+ 0x7ca5, 0x05dd,
+ 0x7ca7, 0x09b9,
+ 0x7ca8, 0x179b,
+ 0x7cab, 0x1799,
+ 0x7cad, 0x1797,
+ 0x7cae, 0x179f,
+ 0x7cb1, 0x179e,
+ 0x7cb2, 0x179d,
+ 0x7cb3, 0x179c,
+ 0x7cb9, 0x17a0,
+ 0x7cbd, 0x17a1,
+ 0x7cbe, 0x0a5e,
+ 0x7cc0, 0x17a2,
+ 0x7cc2, 0x17a4,
+ 0x7cc5, 0x17a3,
+ 0x7cca, 0x0786,
+ 0x7cce, 0x0aba,
+ 0x7cd2, 0x17a6,
+ 0x7cd6, 0x0c76,
+ 0x7cd8, 0x17a5,
+ 0x7cdc, 0x17a7,
+ 0x7cde, 0x0e05,
+ 0x7cdf, 0x0aee,
+ 0x7ce0, 0x07d9,
+ 0x7ce2, 0x17a8,
+ 0x7ce7, 0x0f90,
+ 0x7cef, 0x17aa,
+ 0x7cf2, 0x17ab,
+ 0x7cf4, 0x17ac,
+ 0x7cf6, 0x17ad,
+ 0x7cf8, 0x08b3,
+ 0x7cfa, 0x17ae,
+ 0x7cfb, 0x0725,
+ 0x7cfe, 0x0684,
+ 0x7d00, 0x0644,
+ 0x7d02, 0x17b0,
+ 0x7d04, 0x0eff,
+ 0x7d05, 0x07da,
+ 0x7d06, 0x17af,
+ 0x7d0a, 0x17b3,
+ 0x7d0b, 0x0ef2,
+ 0x7d0d, 0x0cf2,
+ 0x7d10, 0x0da5,
+ 0x7d14, 0x096d,
+ 0x7d15, 0x17b2,
+ 0x7d17, 0x08ff,
+ 0x7d18, 0x07db,
+ 0x7d19, 0x08b4,
+ 0x7d1a, 0x0683,
+ 0x7d1b, 0x0e06,
+ 0x7d1c, 0x17b1,
+ 0x7d20, 0x0ac9,
+ 0x7d21, 0x0e70,
+ 0x7d22, 0x0867,
+ 0x7d2b, 0x08b5,
+ 0x7d2c, 0x0bf9,
+ 0x7d2e, 0x17b6,
+ 0x7d2f, 0x0fa7,
+ 0x7d30, 0x0849,
+ 0x7d32, 0x17b7,
+ 0x7d33, 0x0a08,
+ 0x7d35, 0x17b9,
+ 0x7d39, 0x09ba,
+ 0x7d3a, 0x0820,
+ 0x7d3f, 0x17b8,
+ 0x7d42, 0x0934,
+ 0x7d43, 0x0772,
+ 0x7d44, 0x0aca,
+ 0x7d45, 0x17b4,
+ 0x7d46, 0x17ba,
+ 0x7d48, 0x218f,
+ 0x7d4b, 0x17b5,
+ 0x7d4c, 0x0726,
+ 0x7d4e, 0x17bd,
+ 0x7d4f, 0x17c1,
+ 0x7d50, 0x0741,
+ 0x7d56, 0x17bc,
+ 0x7d5b, 0x17c5,
+ 0x7d5c, 0x2190,
+ 0x7d5e, 0x07dc,
+ 0x7d61, 0x0f57,
+ 0x7d62, 0x0480,
+ 0x7d63, 0x17c2,
+ 0x7d66, 0x0685,
+ 0x7d68, 0x17bf,
+ 0x7d6e, 0x17c0,
+ 0x7d71, 0x0c77,
+ 0x7d72, 0x17be,
+ 0x7d73, 0x17bb,
+ 0x7d75, 0x0586,
+ 0x7d76, 0x0a88,
+ 0x7d79, 0x075c,
+ 0x7d7d, 0x17c7,
+ 0x7d89, 0x17c4,
+ 0x7d8f, 0x17c6,
+ 0x7d93, 0x17c3,
+ 0x7d99, 0x0727,
+ 0x7d9a, 0x0b13,
+ 0x7d9b, 0x17c8,
+ 0x7d9c, 0x0af0,
+ 0x7d9f, 0x17d5,
+ 0x7da0, 0x2192,
+ 0x7da2, 0x17d1,
+ 0x7da3, 0x17cb,
+ 0x7dab, 0x17cf,
+ 0x7dac, 0x0926,
+ 0x7dad, 0x04a1,
+ 0x7dae, 0x17ca,
+ 0x7daf, 0x17d2,
+ 0x7db0, 0x17d6,
+ 0x7db1, 0x07dd,
+ 0x7db2, 0x0ee2,
+ 0x7db4, 0x0bf2,
+ 0x7db5, 0x17cc,
+ 0x7db7, 0x2191,
+ 0x7db8, 0x17d4,
+ 0x7dba, 0x17c9,
+ 0x7dbb, 0x0b7c,
+ 0x7dbd, 0x17ce,
+ 0x7dbe, 0x0481,
+ 0x7dbf, 0x0ed6,
+ 0x7dc7, 0x17cd,
+ 0x7dca, 0x06d3,
+ 0x7dcb, 0x0d80,
+ 0x7dcf, 0x0aef,
+ 0x7dd1, 0x0f98,
+ 0x7dd2, 0x0979,
+ 0x7dd5, 0x17fd,
+ 0x7dd6, 0x2193,
+ 0x7dd8, 0x17d7,
+ 0x7dda, 0x0aa2,
+ 0x7ddc, 0x17d3,
+ 0x7ddd, 0x17d8,
+ 0x7dde, 0x17da,
+ 0x7de0, 0x0c15,
+ 0x7de1, 0x17dd,
+ 0x7de4, 0x17d9,
+ 0x7de8, 0x0e24,
+ 0x7de9, 0x0607,
+ 0x7dec, 0x0ed7,
+ 0x7def, 0x04a2,
+ 0x7df2, 0x17dc,
+ 0x7df4, 0x0fc5,
+ 0x7dfb, 0x17db,
+ 0x7e01, 0x0511,
+ 0x7e04, 0x0cc4,
+ 0x7e05, 0x17de,
+ 0x7e09, 0x17e5,
+ 0x7e0a, 0x17df,
+ 0x7e0b, 0x17e6,
+ 0x7e12, 0x17e2,
+ 0x7e1b, 0x0d31,
+ 0x7e1e, 0x08f6,
+ 0x7e1f, 0x17e4,
+ 0x7e21, 0x17e1,
+ 0x7e22, 0x17e7,
+ 0x7e23, 0x17e0,
+ 0x7e26, 0x094e,
+ 0x7e2b, 0x0e53,
+ 0x7e2e, 0x0956,
+ 0x7e31, 0x17e3,
+ 0x7e32, 0x17ef,
+ 0x7e35, 0x17eb,
+ 0x7e37, 0x17ee,
+ 0x7e39, 0x17ec,
+ 0x7e3a, 0x17f0,
+ 0x7e3b, 0x17ea,
+ 0x7e3d, 0x17d0,
+ 0x7e3e, 0x0a77,
+ 0x7e41, 0x0d5f,
+ 0x7e43, 0x17ed,
+ 0x7e46, 0x17e8,
+ 0x7e4a, 0x0aa3,
+ 0x7e4b, 0x0728,
+ 0x7e4d, 0x0935,
+ 0x7e52, 0x2194,
+ 0x7e54, 0x09eb,
+ 0x7e55, 0x0ab8,
+ 0x7e56, 0x17f3,
+ 0x7e59, 0x17f5,
+ 0x7e5d, 0x17f2,
+ 0x7e5e, 0x17f4,
+ 0x7e61, 0x1e11,
+ 0x7e66, 0x17e9,
+ 0x7e67, 0x17f1,
+ 0x7e69, 0x17f9,
+ 0x7e6a, 0x17f8,
+ 0x7e6b, 0x1df7,
+ 0x7e6d, 0x0ea8,
+ 0x7e70, 0x0701,
+ 0x7e79, 0x17f7,
+ 0x7e7b, 0x17fb,
+ 0x7e7c, 0x17fa,
+ 0x7e7d, 0x17fe,
+ 0x7e7f, 0x1800,
+ 0x7e82, 0x088a,
+ 0x7e83, 0x17fc,
+ 0x7e88, 0x1801,
+ 0x7e8a, 0x20a7,
+ 0x7e8c, 0x1803,
+ 0x7e8e, 0x1809,
+ 0x7e8f, 0x0c35,
+ 0x7e90, 0x1805,
+ 0x7e92, 0x1804,
+ 0x7e93, 0x1806,
+ 0x7e96, 0x1808,
+ 0x7e9b, 0x180a,
+ 0x7f36, 0x0608,
+ 0x7f38, 0x180c,
+ 0x7f3a, 0x180d,
+ 0x7f45, 0x180e,
+ 0x7f47, 0x2195,
+ 0x7f4c, 0x180f,
+ 0x7f50, 0x1812,
+ 0x7f54, 0x1815,
+ 0x7f55, 0x1814,
+ 0x7f58, 0x1816,
+ 0x7f5f, 0x1817,
+ 0x7f67, 0x181b,
+ 0x7f68, 0x1819,
+ 0x7f6a, 0x0851,
+ 0x7f6b, 0x0729,
+ 0x7f6e, 0x0b94,
+ 0x7f70, 0x0d47,
+ 0x7f72, 0x097a,
+ 0x7f75, 0x0d03,
+ 0x7f77, 0x0d81,
+ 0x7f78, 0x181c,
+ 0x7f79, 0x1336,
+ 0x7f82, 0x181d,
+ 0x7f83, 0x181f,
+ 0x7f85, 0x0f4f,
+ 0x7f86, 0x181e,
+ 0x7f87, 0x1821,
+ 0x7f88, 0x1820,
+ 0x7f8a, 0x0f3d,
+ 0x7f8c, 0x1822,
+ 0x7f8e, 0x0d92,
+ 0x7f94, 0x1823,
+ 0x7f9a, 0x1826,
+ 0x7f9d, 0x1825,
+ 0x7f9e, 0x1824,
+ 0x7fa1, 0x2196,
+ 0x7fa3, 0x1827,
+ 0x7fa4, 0x0708,
+ 0x7fa8, 0x0aa4,
+ 0x7fa9, 0x065b,
+ 0x7fae, 0x182b,
+ 0x7faf, 0x1828,
+ 0x7fb2, 0x1829,
+ 0x7fb6, 0x182c,
+ 0x7fb8, 0x182d,
+ 0x7fb9, 0x182a,
+ 0x7fbd, 0x04cb,
+ 0x7fc1, 0x0527,
+ 0x7fc5, 0x182f,
+ 0x7fca, 0x1831,
+ 0x7fcc, 0x0f4c,
+ 0x7fd2, 0x0936,
+ 0x7fd4, 0x1833,
+ 0x7fd5, 0x1832,
+ 0x7fe0, 0x0a2f,
+ 0x7fe1, 0x1834,
+ 0x7fe6, 0x1835,
+ 0x7fe9, 0x1836,
+ 0x7feb, 0x0621,
+ 0x7ff0, 0x0609,
+ 0x7ff3, 0x1837,
+ 0x7ff9, 0x1838,
+ 0x7ffb, 0x0e8b,
+ 0x7ffc, 0x0f4d,
+ 0x8000, 0x0f3e,
+ 0x8001, 0x0fdd,
+ 0x8003, 0x07df,
+ 0x8004, 0x183b,
+ 0x8005, 0x0900,
+ 0x8006, 0x183a,
+ 0x800b, 0x183c,
+ 0x800c, 0x08d5,
+ 0x8010, 0x0b31,
+ 0x8012, 0x183d,
+ 0x8015, 0x07de,
+ 0x8017, 0x0ee3,
+ 0x8018, 0x183e,
+ 0x801c, 0x1840,
+ 0x8021, 0x1841,
+ 0x8028, 0x1842,
+ 0x8033, 0x08d6,
+ 0x8036, 0x0ef9,
+ 0x803b, 0x1844,
+ 0x803d, 0x0b7d,
+ 0x803f, 0x1843,
+ 0x8046, 0x1846,
+ 0x804a, 0x1845,
+ 0x8052, 0x1847,
+ 0x8056, 0x0a5f,
+ 0x8058, 0x1848,
+ 0x805a, 0x1849,
+ 0x805e, 0x0e09,
+ 0x805f, 0x184a,
+ 0x8061, 0x0af1,
+ 0x8062, 0x184b,
+ 0x8068, 0x184c,
+ 0x806f, 0x0fc6,
+ 0x8070, 0x184f,
+ 0x8072, 0x184e,
+ 0x8073, 0x184d,
+ 0x8074, 0x0bcc,
+ 0x8076, 0x1850,
+ 0x8077, 0x09ec,
+ 0x8079, 0x1851,
+ 0x807d, 0x1852,
+ 0x807e, 0x0fde,
+ 0x807f, 0x1853,
+ 0x8084, 0x1854,
+ 0x8085, 0x1856,
+ 0x8086, 0x1855,
+ 0x8087, 0x0d39,
+ 0x8089, 0x0cd1,
+ 0x808b, 0x0fe4,
+ 0x808c, 0x0d3d,
+ 0x8093, 0x1858,
+ 0x8096, 0x09bb,
+ 0x8098, 0x0d9c,
+ 0x809a, 0x1859,
+ 0x809b, 0x1857,
+ 0x809d, 0x060a,
+ 0x80a1, 0x0788,
+ 0x80a2, 0x08b6,
+ 0x80a5, 0x0d82,
+ 0x80a9, 0x075e,
+ 0x80aa, 0x0e71,
+ 0x80ac, 0x185c,
+ 0x80ad, 0x185a,
+ 0x80af, 0x07e0,
+ 0x80b1, 0x07e1,
+ 0x80b2, 0x04ad,
+ 0x80b4, 0x0858,
+ 0x80ba, 0x0d0f,
+ 0x80c3, 0x04a3,
+ 0x80c4, 0x1861,
+ 0x80c6, 0x0b7e,
+ 0x80cc, 0x0d0e,
+ 0x80ce, 0x0b3b,
+ 0x80d6, 0x1863,
+ 0x80d9, 0x185f,
+ 0x80da, 0x1862,
+ 0x80db, 0x185d,
+ 0x80dd, 0x1860,
+ 0x80de, 0x0e54,
+ 0x80e1, 0x0789,
+ 0x80e4, 0x04c1,
+ 0x80e5, 0x185e,
+ 0x80ef, 0x1865,
+ 0x80f1, 0x1866,
+ 0x80f4, 0x0c91,
+ 0x80f8, 0x06b3,
+ 0x80fc, 0x1871,
+ 0x80fd, 0x0cf3,
+ 0x8102, 0x08b7,
+ 0x8105, 0x06b4,
+ 0x8106, 0x0a6c,
+ 0x8107, 0x0fec,
+ 0x8108, 0x0eba,
+ 0x8109, 0x1864,
+ 0x810a, 0x0a78,
+ 0x811a, 0x066d,
+ 0x811b, 0x1867,
+ 0x8123, 0x1869,
+ 0x8129, 0x1868,
+ 0x812f, 0x186a,
+ 0x8131, 0x0b64,
+ 0x8133, 0x0cf4,
+ 0x8139, 0x0bcd,
+ 0x813e, 0x186e,
+ 0x8146, 0x186d,
+ 0x814b, 0x186b,
+ 0x814e, 0x0a1b,
+ 0x8150, 0x0dd7,
+ 0x8151, 0x1870,
+ 0x8153, 0x186f,
+ 0x8154, 0x07e2,
+ 0x8155, 0x0ff9,
+ 0x815f, 0x1880,
+ 0x8165, 0x1874,
+ 0x816b, 0x091c,
+ 0x816e, 0x1873,
+ 0x8170, 0x080a,
+ 0x8171, 0x1872,
+ 0x8174, 0x1876,
+ 0x8178, 0x0bce,
+ 0x8179, 0x0df2,
+ 0x817a, 0x0aa5,
+ 0x817f, 0x0b3c,
+ 0x8180, 0x187a,
+ 0x8182, 0x187b,
+ 0x8183, 0x1877,
+ 0x8188, 0x1878,
+ 0x818a, 0x1879,
+ 0x818f, 0x07e3,
+ 0x8193, 0x1881,
+ 0x8195, 0x187d,
+ 0x819a, 0x0dd8,
+ 0x819c, 0x0e9a,
+ 0x819d, 0x0d9a,
+ 0x81a0, 0x187c,
+ 0x81a3, 0x187f,
+ 0x81a4, 0x187e,
+ 0x81a8, 0x0e72,
+ 0x81a9, 0x1882,
+ 0x81b0, 0x1883,
+ 0x81b3, 0x0ab9,
+ 0x81b5, 0x1884,
+ 0x81b8, 0x1886,
+ 0x81ba, 0x188a,
+ 0x81bd, 0x1887,
+ 0x81be, 0x1885,
+ 0x81bf, 0x0cf5,
+ 0x81c0, 0x1888,
+ 0x81c2, 0x1889,
+ 0x81c6, 0x0532,
+ 0x81c8, 0x1890,
+ 0x81c9, 0x188b,
+ 0x81cd, 0x188c,
+ 0x81d1, 0x188d,
+ 0x81d3, 0x0b01,
+ 0x81d8, 0x188f,
+ 0x81d9, 0x188e,
+ 0x81da, 0x1891,
+ 0x81df, 0x1892,
+ 0x81e3, 0x0a09,
+ 0x81e5, 0x0569,
+ 0x81e7, 0x1894,
+ 0x81e8, 0x0f9f,
+ 0x81ea, 0x08d7,
+ 0x81ed, 0x0937,
+ 0x81f3, 0x08b8,
+ 0x81f4, 0x0b95,
+ 0x81fa, 0x1895,
+ 0x81fc, 0x04d3,
+ 0x81fe, 0x1897,
+ 0x8201, 0x1898,
+ 0x8205, 0x189a,
+ 0x8207, 0x189b,
+ 0x8208, 0x06b5,
+ 0x8209, 0x13af,
+ 0x820a, 0x189c,
+ 0x820c, 0x0a89,
+ 0x820d, 0x189d,
+ 0x820e, 0x08f7,
+ 0x8210, 0x189e,
+ 0x8212, 0x1009,
+ 0x8216, 0x189f,
+ 0x8217, 0x0e2e,
+ 0x8218, 0x0618,
+ 0x821b, 0x0aa6,
+ 0x821c, 0x0962,
+ 0x821e, 0x0de3,
+ 0x821f, 0x0938,
+ 0x8229, 0x18a0,
+ 0x822a, 0x07e4,
+ 0x822b, 0x18a1,
+ 0x822c, 0x0d60,
+ 0x822e, 0x18af,
+ 0x8233, 0x18a3,
+ 0x8235, 0x0b29,
+ 0x8236, 0x0d2b,
+ 0x8237, 0x0773,
+ 0x8238, 0x18a2,
+ 0x8239, 0x0aa7,
+ 0x8240, 0x18a4,
+ 0x8247, 0x0c16,
+ 0x8258, 0x18a6,
+ 0x8259, 0x18a5,
+ 0x825a, 0x18a8,
+ 0x825d, 0x18a7,
+ 0x825f, 0x18a9,
+ 0x8262, 0x18ab,
+ 0x8264, 0x18aa,
+ 0x8266, 0x060b,
+ 0x8268, 0x18ac,
+ 0x826a, 0x18ad,
+ 0x826e, 0x0821,
+ 0x826f, 0x0f91,
+ 0x8271, 0x18b0,
+ 0x8272, 0x09ed,
+ 0x8276, 0x0512,
+ 0x8277, 0x18b1,
+ 0x827e, 0x18b3,
+ 0x828b, 0x04b6,
+ 0x828d, 0x18b4,
+ 0x8292, 0x18b5,
+ 0x8299, 0x0dd9,
+ 0x829d, 0x08f3,
+ 0x829f, 0x18b7,
+ 0x82a5, 0x0587,
+ 0x82a6, 0x0476,
+ 0x82ab, 0x18b6,
+ 0x82ac, 0x18b9,
+ 0x82ad, 0x0d04,
+ 0x82af, 0x0a0a,
+ 0x82b1, 0x0556,
+ 0x82b3, 0x0e55,
+ 0x82b8, 0x0733,
+ 0x82b9, 0x06d4,
+ 0x82bb, 0x18b8,
+ 0x82bd, 0x056a,
+ 0x82c5, 0x05df,
+ 0x82d1, 0x0513,
+ 0x82d2, 0x18bd,
+ 0x82d3, 0x0fb2,
+ 0x82d4, 0x0b3d,
+ 0x82d7, 0x0db6,
+ 0x82d9, 0x18c9,
+ 0x82db, 0x0557,
+ 0x82dc, 0x18c7,
+ 0x82de, 0x18c5,
+ 0x82df, 0x18bc,
+ 0x82e1, 0x18ba,
+ 0x82e3, 0x18bb,
+ 0x82e5, 0x090f,
+ 0x82e6, 0x06e4,
+ 0x82e7, 0x0bb5,
+ 0x82eb, 0x0ca9,
+ 0x82f1, 0x04f3,
+ 0x82f3, 0x18bf,
+ 0x82f4, 0x18be,
+ 0x82f9, 0x18c4,
+ 0x82fa, 0x18c0,
+ 0x82fb, 0x18c3,
+ 0x8301, 0x2198,
+ 0x8302, 0x0edc,
+ 0x8303, 0x18c2,
+ 0x8304, 0x0558,
+ 0x8305, 0x05db,
+ 0x8306, 0x18c6,
+ 0x8309, 0x18c8,
+ 0x830e, 0x072a,
+ 0x8316, 0x18cc,
+ 0x8317, 0x18d5,
+ 0x831c, 0x046f,
+ 0x8323, 0x18dd,
+ 0x8328, 0x04b5,
+ 0x832b, 0x18d4,
+ 0x832f, 0x18d3,
+ 0x8331, 0x18ce,
+ 0x8332, 0x18cd,
+ 0x8334, 0x18cb,
+ 0x8335, 0x18ca,
+ 0x8336, 0x0ba1,
+ 0x8338, 0x0b5b,
+ 0x8339, 0x18d0,
+ 0x8340, 0x18cf,
+ 0x8345, 0x18d2,
+ 0x8349, 0x0af2,
+ 0x834a, 0x072b,
+ 0x834f, 0x04e3,
+ 0x8350, 0x18d1,
+ 0x8352, 0x07e5,
+ 0x8358, 0x0af3,
+ 0x8362, 0x2199,
+ 0x8373, 0x18e3,
+ 0x8375, 0x18e4,
+ 0x8377, 0x0559,
+ 0x837b, 0x052e,
+ 0x837c, 0x18e1,
+ 0x837f, 0x219a,
+ 0x8385, 0x18d7,
+ 0x8387, 0x18df,
+ 0x8389, 0x18e6,
+ 0x838a, 0x18e0,
+ 0x838e, 0x18de,
+ 0x8393, 0x18c1,
+ 0x8396, 0x18dc,
+ 0x839a, 0x18d8,
+ 0x839e, 0x060c,
+ 0x839f, 0x18da,
+ 0x83a0, 0x18e5,
+ 0x83a2, 0x18db,
+ 0x83a8, 0x18e7,
+ 0x83aa, 0x18d9,
+ 0x83ab, 0x0d32,
+ 0x83b1, 0x0f53,
+ 0x83b5, 0x18e2,
+ 0x83bd, 0x18f8,
+ 0x83c1, 0x18f0,
+ 0x83c5, 0x0a41,
+ 0x83c7, 0x219b,
+ 0x83ca, 0x0660,
+ 0x83cc, 0x06d5,
+ 0x83ce, 0x18eb,
+ 0x83d3, 0x055b,
+ 0x83d6, 0x09bc,
+ 0x83d8, 0x18ee,
+ 0x83dc, 0x084a,
+ 0x83df, 0x0c4b,
+ 0x83e0, 0x18f3,
+ 0x83e9, 0x0e3e,
+ 0x83eb, 0x18ea,
+ 0x83ef, 0x055a,
+ 0x83f0, 0x078a,
+ 0x83f1, 0x0d9b,
+ 0x83f2, 0x18f4,
+ 0x83f4, 0x18e8,
+ 0x83f6, 0x219c,
+ 0x83f7, 0x18f1,
+ 0x83fb, 0x18fb,
+ 0x83fd, 0x18ec,
+ 0x8403, 0x18ed,
+ 0x8404, 0x0c92,
+ 0x8407, 0x18f2,
+ 0x840a, 0x1e7f,
+ 0x840b, 0x18ef,
+ 0x840c, 0x0e56,
+ 0x840d, 0x18f5,
+ 0x840e, 0x04a4,
+ 0x8413, 0x18e9,
+ 0x8420, 0x18f7,
+ 0x8422, 0x18f6,
+ 0x8429, 0x0d21,
+ 0x842a, 0x18fd,
+ 0x842c, 0x1908,
+ 0x8431, 0x05dc,
+ 0x8435, 0x190b,
+ 0x8438, 0x18f9,
+ 0x843c, 0x18fe,
+ 0x843d, 0x0f58,
+ 0x8446, 0x1907,
+ 0x8448, 0x219d,
+ 0x8449, 0x0f3f,
+ 0x844e, 0x0f72,
+ 0x8457, 0x0bb6,
+ 0x845b, 0x05c9,
+ 0x8461, 0x0de4,
+ 0x8462, 0x190d,
+ 0x8463, 0x0c79,
+ 0x8466, 0x0475,
+ 0x8469, 0x1906,
+ 0x846b, 0x1902,
+ 0x846c, 0x0af4,
+ 0x846d, 0x18fc,
+ 0x846e, 0x1904,
+ 0x846f, 0x1909,
+ 0x8471, 0x0ce2,
+ 0x8475, 0x046e,
+ 0x8477, 0x1901,
+ 0x8479, 0x190a,
+ 0x847a, 0x0dea,
+ 0x8482, 0x1905,
+ 0x8484, 0x1900,
+ 0x848b, 0x09bd,
+ 0x8490, 0x0939,
+ 0x8494, 0x08d8,
+ 0x8499, 0x0ee4,
+ 0x849c, 0x0db9,
+ 0x849f, 0x1910,
+ 0x84a1, 0x1919,
+ 0x84ad, 0x1903,
+ 0x84b2, 0x05d5,
+ 0x84b4, 0x219e,
+ 0x84b8, 0x09e0,
+ 0x84b9, 0x190e,
+ 0x84bb, 0x1913,
+ 0x84bc, 0x0af5,
+ 0x84bf, 0x190f,
+ 0x84c1, 0x1916,
+ 0x84c4, 0x0b9d,
+ 0x84c6, 0x1917,
+ 0x84c9, 0x0f40,
+ 0x84ca, 0x190c,
+ 0x84cb, 0x0596,
+ 0x84cd, 0x1912,
+ 0x84d0, 0x1915,
+ 0x84d1, 0x0eb8,
+ 0x84d6, 0x1918,
+ 0x84d9, 0x1911,
+ 0x84da, 0x1914,
+ 0x84dc, 0x20ab,
+ 0x84ec, 0x0e57,
+ 0x84ee, 0x0fc7,
+ 0x84f4, 0x191c,
+ 0x84fc, 0x1923,
+ 0x84ff, 0x191b,
+ 0x8500, 0x08ef,
+ 0x8506, 0x18fa,
+ 0x8511, 0x0e1e,
+ 0x8513, 0x0eae,
+ 0x8514, 0x1922,
+ 0x8515, 0x1921,
+ 0x8517, 0x191d,
+ 0x851a, 0x04d8,
+ 0x851f, 0x1920,
+ 0x8521, 0x191a,
+ 0x8523, 0x1e1a,
+ 0x8526, 0x0bf1,
+ 0x852c, 0x191f,
+ 0x852d, 0x04c2,
+ 0x8535, 0x0b02,
+ 0x853d, 0x0e13,
+ 0x853e, 0x1eb5,
+ 0x8540, 0x1924,
+ 0x8541, 0x1928,
+ 0x8543, 0x0d6d,
+ 0x8548, 0x1927,
+ 0x8549, 0x09be,
+ 0x854a, 0x08f5,
+ 0x854b, 0x192a,
+ 0x854e, 0x06b6,
+ 0x8553, 0x219f,
+ 0x8555, 0x192b,
+ 0x8557, 0x0deb,
+ 0x8558, 0x1926,
+ 0x8559, 0x21a0,
+ 0x855a, 0x18ff,
+ 0x8563, 0x1925,
+ 0x8568, 0x0ff5,
+ 0x8569, 0x0c7a,
+ 0x856a, 0x0de5,
+ 0x856b, 0x21a1,
+ 0x856d, 0x1932,
+ 0x8577, 0x1938,
+ 0x857e, 0x1939,
+ 0x8580, 0x192c,
+ 0x8584, 0x0d2c,
+ 0x8587, 0x1936,
+ 0x8588, 0x192e,
+ 0x858a, 0x1930,
+ 0x8590, 0x193a,
+ 0x8591, 0x192f,
+ 0x8594, 0x1933,
+ 0x8597, 0x0514,
+ 0x8599, 0x0cbd,
+ 0x859b, 0x1934,
+ 0x859c, 0x1937,
+ 0x85a4, 0x192d,
+ 0x85a6, 0x0aa8,
+ 0x85a8, 0x1931,
+ 0x85a9, 0x0875,
+ 0x85aa, 0x0a0b,
+ 0x85ab, 0x0706,
+ 0x85ac, 0x0f00,
+ 0x85ae, 0x0f05,
+ 0x85af, 0x097c,
+ 0x85b0, 0x21a3,
+ 0x85b9, 0x193e,
+ 0x85ba, 0x193c,
+ 0x85c1, 0x0ff4,
+ 0x85c9, 0x193b,
+ 0x85cd, 0x0f5f,
+ 0x85cf, 0x193d,
+ 0x85d0, 0x193f,
+ 0x85d5, 0x1940,
+ 0x85dc, 0x1943,
+ 0x85dd, 0x1941,
+ 0x85e4, 0x0c7b,
+ 0x85e5, 0x1942,
+ 0x85e9, 0x0d61,
+ 0x85ea, 0x1935,
+ 0x85f7, 0x097d,
+ 0x85f9, 0x1944,
+ 0x85fa, 0x1949,
+ 0x85fb, 0x0af6,
+ 0x85fe, 0x1948,
+ 0x8602, 0x1929,
+ 0x8606, 0x194a,
+ 0x8607, 0x0acb,
+ 0x860a, 0x1945,
+ 0x860b, 0x1947,
+ 0x8613, 0x1946,
+ 0x8616, 0x14d0,
+ 0x8617, 0x14c1,
+ 0x861a, 0x194c,
+ 0x8622, 0x194b,
+ 0x862d, 0x0f60,
+ 0x862f, 0x16b1,
+ 0x8630, 0x194d,
+ 0x863f, 0x194e,
+ 0x864d, 0x194f,
+ 0x864e, 0x078b,
+ 0x8650, 0x066e,
+ 0x8654, 0x1951,
+ 0x8655, 0x1094,
+ 0x865a, 0x068f,
+ 0x865c, 0x0f82,
+ 0x865e, 0x06eb,
+ 0x865f, 0x1952,
+ 0x8667, 0x1953,
+ 0x866b, 0x0bac,
+ 0x8671, 0x1954,
+ 0x8679, 0x0cd2,
+ 0x867b, 0x047e,
+ 0x868a, 0x0563,
+ 0x868b, 0x1959,
+ 0x8693, 0x1955,
+ 0x8695, 0x088b,
+ 0x86a3, 0x1956,
+ 0x86a4, 0x0cf8,
+ 0x86a9, 0x1957,
+ 0x86ab, 0x1962,
+ 0x86af, 0x195c,
+ 0x86b0, 0x195f,
+ 0x86b6, 0x195b,
+ 0x86c4, 0x195d,
+ 0x86c6, 0x195e,
+ 0x86c7, 0x0904,
+ 0x86c9, 0x1960,
+ 0x86cb, 0x0b7f,
+ 0x86cd, 0x072c,
+ 0x86ce, 0x05a0,
+ 0x86d4, 0x1963,
+ 0x86d9, 0x059d,
+ 0x86db, 0x1968,
+ 0x86de, 0x1964,
+ 0x86df, 0x1967,
+ 0x86e4, 0x0d4e,
+ 0x86e9, 0x1965,
+ 0x86ec, 0x1966,
+ 0x86ed, 0x0dba,
+ 0x86ee, 0x0d6e,
+ 0x86ef, 0x1969,
+ 0x86f8, 0x0b5d,
+ 0x86f9, 0x1973,
+ 0x86fb, 0x196f,
+ 0x86fe, 0x056b,
+ 0x8700, 0x196d,
+ 0x8702, 0x0e58,
+ 0x8703, 0x196e,
+ 0x8706, 0x196b,
+ 0x8708, 0x196c,
+ 0x8709, 0x1971,
+ 0x870a, 0x1974,
+ 0x870d, 0x1972,
+ 0x8711, 0x1970,
+ 0x8712, 0x196a,
+ 0x8718, 0x0b96,
+ 0x871a, 0x197b,
+ 0x871c, 0x0eb6,
+ 0x8725, 0x1979,
+ 0x8729, 0x197a,
+ 0x8734, 0x1975,
+ 0x8737, 0x1977,
+ 0x873b, 0x1978,
+ 0x873f, 0x1976,
+ 0x8749, 0x0a8a,
+ 0x874b, 0x0fdf,
+ 0x874c, 0x197f,
+ 0x874e, 0x1980,
+ 0x8753, 0x1986,
+ 0x8755, 0x09f0,
+ 0x8757, 0x1982,
+ 0x8759, 0x1985,
+ 0x875f, 0x197d,
+ 0x8760, 0x197c,
+ 0x8763, 0x1987,
+ 0x8766, 0x055c,
+ 0x8768, 0x1983,
+ 0x876a, 0x1988,
+ 0x876e, 0x1984,
+ 0x8774, 0x1981,
+ 0x8776, 0x0bcf,
+ 0x8778, 0x197e,
+ 0x877f, 0x0d1e,
+ 0x8782, 0x198c,
+ 0x878d, 0x0f25,
+ 0x879f, 0x198b,
+ 0x87a2, 0x198a,
+ 0x87ab, 0x1993,
+ 0x87af, 0x198d,
+ 0x87b3, 0x1995,
+ 0x87ba, 0x0f50,
+ 0x87bb, 0x1998,
+ 0x87bd, 0x198f,
+ 0x87c0, 0x1990,
+ 0x87c4, 0x1994,
+ 0x87c6, 0x1997,
+ 0x87c7, 0x1996,
+ 0x87cb, 0x198e,
+ 0x87d0, 0x1991,
+ 0x87d2, 0x19a2,
+ 0x87e0, 0x199b,
+ 0x87ec, 0x1e23,
+ 0x87ef, 0x1999,
+ 0x87f2, 0x199a,
+ 0x87f6, 0x199f,
+ 0x87f9, 0x0588,
+ 0x87fb, 0x065c,
+ 0x87fe, 0x199e,
+ 0x8805, 0x1989,
+ 0x8807, 0x21a6,
+ 0x880d, 0x199d,
+ 0x880e, 0x19a1,
+ 0x880f, 0x199c,
+ 0x8811, 0x19a3,
+ 0x8815, 0x19a5,
+ 0x8816, 0x19a4,
+ 0x881f, 0x1e85,
+ 0x8821, 0x19a7,
+ 0x8822, 0x19a6,
+ 0x8823, 0x1961,
+ 0x8827, 0x19ab,
+ 0x8831, 0x19a8,
+ 0x8836, 0x19a9,
+ 0x8839, 0x19aa,
+ 0x883b, 0x19ac,
+ 0x8840, 0x0742,
+ 0x8842, 0x19ae,
+ 0x8844, 0x19ad,
+ 0x8846, 0x093a,
+ 0x884c, 0x07e6,
+ 0x884d, 0x1524,
+ 0x8852, 0x19af,
+ 0x8853, 0x095b,
+ 0x8857, 0x0597,
+ 0x8859, 0x19b0,
+ 0x885b, 0x04f4,
+ 0x885d, 0x09bf,
+ 0x885e, 0x19b1,
+ 0x8861, 0x07e7,
+ 0x8862, 0x19b2,
+ 0x8863, 0x04a5,
+ 0x8868, 0x0daf,
+ 0x886b, 0x19b3,
+ 0x8870, 0x0a30,
+ 0x8872, 0x19ba,
+ 0x8875, 0x19b7,
+ 0x8877, 0x0bad,
+ 0x887d, 0x19b8,
+ 0x887e, 0x19b5,
+ 0x887f, 0x06d6,
+ 0x8881, 0x19b4,
+ 0x8882, 0x19bb,
+ 0x8888, 0x070c,
+ 0x888b, 0x0b3e,
+ 0x888d, 0x19c1,
+ 0x8892, 0x19bd,
+ 0x8896, 0x0b15,
+ 0x8897, 0x19bc,
+ 0x8899, 0x19bf,
+ 0x889e, 0x19b6,
+ 0x88a2, 0x19c0,
+ 0x88a4, 0x19c2,
+ 0x88ab, 0x0d83,
+ 0x88ae, 0x19be,
+ 0x88b0, 0x19c3,
+ 0x88b1, 0x19c5,
+ 0x88b4, 0x0787,
+ 0x88b5, 0x19b9,
+ 0x88b7, 0x0485,
+ 0x88bf, 0x19c4,
+ 0x88c1, 0x084b,
+ 0x88c2, 0x0fbe,
+ 0x88c3, 0x19c6,
+ 0x88c5, 0x0af7,
+ 0x88cf, 0x0f6a,
+ 0x88d4, 0x19c8,
+ 0x88d5, 0x0f1f,
+ 0x88d8, 0x19c9,
+ 0x88dc, 0x0e34,
+ 0x88dd, 0x19cb,
+ 0x88df, 0x0830,
+ 0x88e1, 0x0f6b,
+ 0x88e8, 0x19d0,
+ 0x88f2, 0x19d1,
+ 0x88f3, 0x09c0,
+ 0x88f4, 0x19cf,
+ 0x88f5, 0x21a7,
+ 0x88f8, 0x0f51,
+ 0x88f9, 0x19cc,
+ 0x88fc, 0x19ce,
+ 0x88fd, 0x0a61,
+ 0x88fe, 0x0a44,
+ 0x8902, 0x19cd,
+ 0x8904, 0x19d2,
+ 0x8907, 0x0df3,
+ 0x890a, 0x19d4,
+ 0x890c, 0x19d3,
+ 0x8910, 0x05ca,
+ 0x8912, 0x0e59,
+ 0x8913, 0x19d5,
+ 0x891c, 0x20a8,
+ 0x891d, 0x19e1,
+ 0x891e, 0x19d7,
+ 0x8925, 0x19d8,
+ 0x892a, 0x19d9,
+ 0x8936, 0x19de,
+ 0x8938, 0x19df,
+ 0x893b, 0x19dd,
+ 0x8941, 0x19db,
+ 0x8943, 0x19d6,
+ 0x8944, 0x19dc,
+ 0x894c, 0x19e0,
+ 0x894d, 0x1bd0,
+ 0x8956, 0x0528,
+ 0x895e, 0x19e3,
+ 0x895f, 0x06d7,
+ 0x8960, 0x19e2,
+ 0x8964, 0x19e5,
+ 0x8966, 0x19e4,
+ 0x896a, 0x19e7,
+ 0x896d, 0x19e6,
+ 0x896f, 0x19e8,
+ 0x8972, 0x093b,
+ 0x8974, 0x19e9,
+ 0x8977, 0x19ea,
+ 0x897e, 0x19eb,
+ 0x897f, 0x0a62,
+ 0x8981, 0x0f41,
+ 0x8983, 0x19ec,
+ 0x8986, 0x0df4,
+ 0x8987, 0x0cfc,
+ 0x8988, 0x19ed,
+ 0x898a, 0x19ee,
+ 0x898b, 0x075f,
+ 0x898f, 0x0646,
+ 0x8993, 0x19ef,
+ 0x8996, 0x08b9,
+ 0x8997, 0x0cf7,
+ 0x8998, 0x19f0,
+ 0x899a, 0x05ae,
+ 0x89a1, 0x19f1,
+ 0x89a6, 0x19f3,
+ 0x89a7, 0x0f61,
+ 0x89a9, 0x19f2,
+ 0x89aa, 0x0a0c,
+ 0x89ac, 0x19f4,
+ 0x89af, 0x19f5,
+ 0x89b2, 0x19f6,
+ 0x89b3, 0x060d,
+ 0x89ba, 0x19f7,
+ 0x89bd, 0x19f8,
+ 0x89bf, 0x19f9,
+ 0x89d2, 0x05af,
+ 0x89da, 0x19fb,
+ 0x89dc, 0x19fc,
+ 0x89e3, 0x0572,
+ 0x89e6, 0x09ee,
+ 0x89e7, 0x19fe,
+ 0x89f4, 0x19ff,
+ 0x89f8, 0x1a00,
+ 0x8a00, 0x0774,
+ 0x8a02, 0x0c17,
+ 0x8a03, 0x1a01,
+ 0x8a08, 0x072d,
+ 0x8a0a, 0x0a1c,
+ 0x8a0c, 0x1a04,
+ 0x8a0e, 0x0c7c,
+ 0x8a10, 0x1a03,
+ 0x8a12, 0x21a8,
+ 0x8a13, 0x0707,
+ 0x8a16, 0x1a02,
+ 0x8a17, 0x0b57,
+ 0x8a18, 0x0647,
+ 0x8a1b, 0x1a05,
+ 0x8a1d, 0x1a06,
+ 0x8a1f, 0x09c1,
+ 0x8a23, 0x0743,
+ 0x8a25, 0x1a07,
+ 0x8a2a, 0x0e5a,
+ 0x8a2d, 0x0a83,
+ 0x8a31, 0x0690,
+ 0x8a33, 0x0f01,
+ 0x8a34, 0x0acc,
+ 0x8a36, 0x1a08,
+ 0x8a37, 0x21a9,
+ 0x8a3a, 0x0a0d,
+ 0x8a3b, 0x0bae,
+ 0x8a3c, 0x09c2,
+ 0x8a41, 0x1a09,
+ 0x8a46, 0x1a0c,
+ 0x8a48, 0x1a0d,
+ 0x8a50, 0x082e,
+ 0x8a51, 0x0b22,
+ 0x8a52, 0x1a0b,
+ 0x8a54, 0x09c3,
+ 0x8a55, 0x0db0,
+ 0x8a5b, 0x1a0a,
+ 0x8a5e, 0x08ba,
+ 0x8a60, 0x04f5,
+ 0x8a62, 0x1a11,
+ 0x8a63, 0x072e,
+ 0x8a66, 0x08bc,
+ 0x8a69, 0x08bb,
+ 0x8a6b, 0x0ff3,
+ 0x8a6c, 0x1a10,
+ 0x8a6d, 0x1a0f,
+ 0x8a6e, 0x0aa9,
+ 0x8a70, 0x0667,
+ 0x8a71, 0x0fe9,
+ 0x8a72, 0x0598,
+ 0x8a73, 0x09c4,
+ 0x8a79, 0x21aa,
+ 0x8a7c, 0x1a0e,
+ 0x8a82, 0x1a13,
+ 0x8a84, 0x1a14,
+ 0x8a85, 0x1a12,
+ 0x8a87, 0x078c,
+ 0x8a89, 0x0f2a,
+ 0x8a8c, 0x08bd,
+ 0x8a8d, 0x0cdd,
+ 0x8a91, 0x1a17,
+ 0x8a93, 0x0a64,
+ 0x8a95, 0x0b80,
+ 0x8a98, 0x0f20,
+ 0x8a9a, 0x1a1a,
+ 0x8a9e, 0x07a0,
+ 0x8aa0, 0x0a63,
+ 0x8aa1, 0x1a16,
+ 0x8aa3, 0x1a1b,
+ 0x8aa4, 0x07a1,
+ 0x8aa5, 0x1a18,
+ 0x8aa7, 0x21ab,
+ 0x8aa8, 0x1a15,
+ 0x8aac, 0x0a86,
+ 0x8aad, 0x0ca1,
+ 0x8ab0, 0x0b6d,
+ 0x8ab2, 0x055d,
+ 0x8ab9, 0x0d84,
+ 0x8abc, 0x065d,
+ 0x8abe, 0x21ac,
+ 0x8abf, 0x0bd0,
+ 0x8ac2, 0x1a1e,
+ 0x8ac4, 0x1a1c,
+ 0x8ac7, 0x0b8a,
+ 0x8acb, 0x0a65,
+ 0x8acc, 0x060e,
+ 0x8acd, 0x1a1d,
+ 0x8acf, 0x0a21,
+ 0x8ad2, 0x0f92,
+ 0x8ad6, 0x0fe6,
+ 0x8ada, 0x1a1f,
+ 0x8adb, 0x1a2a,
+ 0x8adc, 0x0bd1,
+ 0x8ade, 0x1a29,
+ 0x8adf, 0x21ad,
+ 0x8ae0, 0x1a26,
+ 0x8ae1, 0x1a2e,
+ 0x8ae2, 0x1a27,
+ 0x8ae4, 0x1a23,
+ 0x8ae6, 0x0c18,
+ 0x8ae7, 0x1a22,
+ 0x8aeb, 0x1a20,
+ 0x8aed, 0x0f0b,
+ 0x8aee, 0x08be,
+ 0x8af1, 0x1a24,
+ 0x8af3, 0x1a21,
+ 0x8af6, 0x21af,
+ 0x8af7, 0x1a28,
+ 0x8af8, 0x097e,
+ 0x8afa, 0x0775,
+ 0x8afe, 0x0b5a,
+ 0x8b00, 0x0e73,
+ 0x8b01, 0x04fc,
+ 0x8b02, 0x04a6,
+ 0x8b04, 0x0c7d,
+ 0x8b07, 0x1a2c,
+ 0x8b0c, 0x1a2b,
+ 0x8b0e, 0x0cbe,
+ 0x8b10, 0x1a30,
+ 0x8b14, 0x1a25,
+ 0x8b16, 0x1a2f,
+ 0x8b17, 0x1a31,
+ 0x8b19, 0x0760,
+ 0x8b1a, 0x1a2d,
+ 0x8b1b, 0x07e8,
+ 0x8b1d, 0x0901,
+ 0x8b20, 0x1a32,
+ 0x8b21, 0x0f42,
+ 0x8b26, 0x1a35,
+ 0x8b28, 0x1a38,
+ 0x8b2b, 0x1a36,
+ 0x8b2c, 0x0da7,
+ 0x8b33, 0x1a33,
+ 0x8b39, 0x06d8,
+ 0x8b3e, 0x1a37,
+ 0x8b41, 0x1a39,
+ 0x8b49, 0x1a3d,
+ 0x8b4c, 0x1a3a,
+ 0x8b4e, 0x1a3c,
+ 0x8b4f, 0x1a3b,
+ 0x8b53, 0x21b0,
+ 0x8b56, 0x1a3e,
+ 0x8b58, 0x08dd,
+ 0x8b5a, 0x1a40,
+ 0x8b5b, 0x1a3f,
+ 0x8b5c, 0x0dda,
+ 0x8b5f, 0x1a42,
+ 0x8b66, 0x072f,
+ 0x8b6b, 0x1a41,
+ 0x8b6c, 0x1a43,
+ 0x8b6f, 0x1a44,
+ 0x8b70, 0x065e,
+ 0x8b71, 0x182e,
+ 0x8b72, 0x09e1,
+ 0x8b74, 0x1a45,
+ 0x8b77, 0x07a2,
+ 0x8b7d, 0x1a46,
+ 0x8b7f, 0x21b1,
+ 0x8b80, 0x1a47,
+ 0x8b83, 0x088c,
+ 0x8b8a, 0x13d3,
+ 0x8b8c, 0x1a48,
+ 0x8b8e, 0x1a49,
+ 0x8b90, 0x093c,
+ 0x8b92, 0x1a4a,
+ 0x8b96, 0x1a4c,
+ 0x8b99, 0x1a4d,
+ 0x8c37, 0x0b69,
+ 0x8c3a, 0x1a4f,
+ 0x8c3f, 0x1a51,
+ 0x8c41, 0x1a50,
+ 0x8c46, 0x0c7e,
+ 0x8c48, 0x1a52,
+ 0x8c4a, 0x0e5b,
+ 0x8c4c, 0x1a53,
+ 0x8c4e, 0x1a54,
+ 0x8c50, 0x1a55,
+ 0x8c55, 0x1a56,
+ 0x8c5a, 0x0cb2,
+ 0x8c61, 0x09c5,
+ 0x8c62, 0x1a57,
+ 0x8c6a, 0x07fd,
+ 0x8c6b, 0x1007,
+ 0x8c6c, 0x1a58,
+ 0x8c78, 0x1a59,
+ 0x8c79, 0x0db1,
+ 0x8c7a, 0x1a5a,
+ 0x8c7c, 0x1a62,
+ 0x8c82, 0x1a5b,
+ 0x8c85, 0x1a5d,
+ 0x8c89, 0x1a5c,
+ 0x8c8a, 0x1a5e,
+ 0x8c8c, 0x0e74,
+ 0x8c8d, 0x1a5f,
+ 0x8c94, 0x1a61,
+ 0x8c98, 0x1a63,
+ 0x8c9d, 0x058b,
+ 0x8c9e, 0x0c03,
+ 0x8ca0, 0x0ddb,
+ 0x8ca1, 0x0852,
+ 0x8ca2, 0x07e9,
+ 0x8ca7, 0x0dc1,
+ 0x8ca8, 0x055f,
+ 0x8ca9, 0x0d62,
+ 0x8caa, 0x1a66,
+ 0x8cab, 0x060f,
+ 0x8cac, 0x0a79,
+ 0x8cad, 0x1a65,
+ 0x8cae, 0x1a6a,
+ 0x8caf, 0x0bb7,
+ 0x8cb0, 0x0eef,
+ 0x8cb2, 0x1a68,
+ 0x8cb4, 0x0648,
+ 0x8cb6, 0x1a6b,
+ 0x8cb7, 0x0d19,
+ 0x8cb8, 0x0b3f,
+ 0x8cbb, 0x0d85,
+ 0x8cbc, 0x0c37,
+ 0x8cbd, 0x1a67,
+ 0x8cbf, 0x0e75,
+ 0x8cc0, 0x056c,
+ 0x8cc1, 0x1a6d,
+ 0x8cc2, 0x0fce,
+ 0x8cc3, 0x0bde,
+ 0x8cc4, 0x0feb,
+ 0x8cc7, 0x08bf,
+ 0x8cc8, 0x1a6c,
+ 0x8cca, 0x0b11,
+ 0x8ccd, 0x1a7d,
+ 0x8cce, 0x0aaa,
+ 0x8cd1, 0x0cd0,
+ 0x8cd3, 0x0dc2,
+ 0x8cda, 0x1a70,
+ 0x8cdb, 0x088d,
+ 0x8cdc, 0x08c0,
+ 0x8cde, 0x09c6,
+ 0x8ce0, 0x0d1b,
+ 0x8ce2, 0x0761,
+ 0x8ce3, 0x1a6f,
+ 0x8ce4, 0x1a6e,
+ 0x8ce6, 0x0ddc,
+ 0x8cea, 0x08ed,
+ 0x8ced, 0x0c4c,
+ 0x8cf0, 0x21b2,
+ 0x8cf4, 0x21b3,
+ 0x8cfa, 0x1a72,
+ 0x8cfc, 0x07ea,
+ 0x8cfd, 0x1a71,
+ 0x8d04, 0x1a74,
+ 0x8d07, 0x1a77,
+ 0x8d08, 0x0b03,
+ 0x8d0a, 0x1a76,
+ 0x8d0b, 0x0622,
+ 0x8d0d, 0x1a79,
+ 0x8d0f, 0x1a78,
+ 0x8d10, 0x1a7a,
+ 0x8d12, 0x21b4,
+ 0x8d13, 0x1a7c,
+ 0x8d14, 0x1a7e,
+ 0x8d16, 0x1a7f,
+ 0x8d64, 0x0a7a,
+ 0x8d66, 0x08fb,
+ 0x8d67, 0x1a80,
+ 0x8d6b, 0x05b0,
+ 0x8d6d, 0x1a81,
+ 0x8d70, 0x0af8,
+ 0x8d71, 0x1a82,
+ 0x8d73, 0x1a83,
+ 0x8d74, 0x0ddd,
+ 0x8d76, 0x21b5,
+ 0x8d77, 0x0649,
+ 0x8d81, 0x1a84,
+ 0x8d85, 0x0bd2,
+ 0x8d8a, 0x04fd,
+ 0x8d99, 0x1a85,
+ 0x8da3, 0x091d,
+ 0x8da8, 0x0a3c,
+ 0x8db3, 0x0b0d,
+ 0x8dba, 0x1a88,
+ 0x8dbe, 0x1a87,
+ 0x8dc2, 0x1a86,
+ 0x8dcb, 0x1a8e,
+ 0x8dcc, 0x1a8c,
+ 0x8dcf, 0x1a89,
+ 0x8dd6, 0x1a8b,
+ 0x8dda, 0x1a8a,
+ 0x8ddb, 0x1a8d,
+ 0x8ddd, 0x0691,
+ 0x8ddf, 0x1a91,
+ 0x8de1, 0x0a7b,
+ 0x8de3, 0x1a92,
+ 0x8de8, 0x078d,
+ 0x8dea, 0x1a8f,
+ 0x8def, 0x0fcf,
+ 0x8df3, 0x0bd3,
+ 0x8df5, 0x0aab,
+ 0x8dfc, 0x1a93,
+ 0x8dff, 0x1a96,
+ 0x8e08, 0x1a94,
+ 0x8e0a, 0x0f43,
+ 0x8e0f, 0x0c7f,
+ 0x8e10, 0x1a99,
+ 0x8e1d, 0x1a97,
+ 0x8e1f, 0x1a9a,
+ 0x8e2a, 0x1aa8,
+ 0x8e30, 0x1a9d,
+ 0x8e34, 0x1a9e,
+ 0x8e35, 0x1a9c,
+ 0x8e42, 0x1a9b,
+ 0x8e44, 0x0c19,
+ 0x8e47, 0x1aa0,
+ 0x8e48, 0x1aa4,
+ 0x8e49, 0x1aa1,
+ 0x8e4a, 0x1a9f,
+ 0x8e4c, 0x1aa2,
+ 0x8e50, 0x1aa3,
+ 0x8e55, 0x1aaa,
+ 0x8e59, 0x1aa5,
+ 0x8e5f, 0x0a7c,
+ 0x8e60, 0x1aa7,
+ 0x8e63, 0x1aa9,
+ 0x8e64, 0x1aa6,
+ 0x8e72, 0x1aac,
+ 0x8e74, 0x093d,
+ 0x8e76, 0x1aab,
+ 0x8e7c, 0x1aad,
+ 0x8e81, 0x1aae,
+ 0x8e84, 0x1ab1,
+ 0x8e85, 0x1ab0,
+ 0x8e87, 0x1aaf,
+ 0x8e8a, 0x1ab3,
+ 0x8e8b, 0x1ab2,
+ 0x8e8d, 0x0f02,
+ 0x8e91, 0x1ab5,
+ 0x8e93, 0x1ab4,
+ 0x8e94, 0x1ab6,
+ 0x8e99, 0x1ab7,
+ 0x8ea1, 0x1ab9,
+ 0x8eaa, 0x1ab8,
+ 0x8eab, 0x0a0e,
+ 0x8eac, 0x1aba,
+ 0x8eaf, 0x06e5,
+ 0x8eb0, 0x1abb,
+ 0x8eb1, 0x1abd,
+ 0x8ebe, 0x1abe,
+ 0x8ec0, 0x1def,
+ 0x8ec5, 0x1abf,
+ 0x8ec6, 0x1abc,
+ 0x8ec8, 0x1ac0,
+ 0x8eca, 0x0902,
+ 0x8ecb, 0x1ac1,
+ 0x8ecc, 0x064a,
+ 0x8ecd, 0x0709,
+ 0x8ecf, 0x21b7,
+ 0x8ed2, 0x0762,
+ 0x8edb, 0x1ac2,
+ 0x8edf, 0x0cc8,
+ 0x8ee2, 0x0c38,
+ 0x8ee3, 0x1ac3,
+ 0x8eeb, 0x1ac6,
+ 0x8ef8, 0x08e0,
+ 0x8efb, 0x1ac5,
+ 0x8efc, 0x1ac4,
+ 0x8efd, 0x0730,
+ 0x8efe, 0x1ac7,
+ 0x8f03, 0x05b1,
+ 0x8f05, 0x1ac9,
+ 0x8f09, 0x084c,
+ 0x8f0a, 0x1ac8,
+ 0x8f0c, 0x1ad1,
+ 0x8f12, 0x1acb,
+ 0x8f13, 0x1acd,
+ 0x8f14, 0x0e35,
+ 0x8f15, 0x1aca,
+ 0x8f19, 0x1acc,
+ 0x8f1b, 0x1ad0,
+ 0x8f1c, 0x1ace,
+ 0x8f1d, 0x064b,
+ 0x8f1f, 0x1acf,
+ 0x8f26, 0x1ad2,
+ 0x8f29, 0x0d10,
+ 0x8f2a, 0x0fa0,
+ 0x8f2f, 0x093e,
+ 0x8f33, 0x1ad3,
+ 0x8f38, 0x0f0c,
+ 0x8f39, 0x1ad5,
+ 0x8f3b, 0x1ad4,
+ 0x8f3e, 0x1ad8,
+ 0x8f3f, 0x0f2b,
+ 0x8f42, 0x1ad7,
+ 0x8f44, 0x05cb,
+ 0x8f45, 0x1ad6,
+ 0x8f46, 0x1adb,
+ 0x8f49, 0x1ada,
+ 0x8f4c, 0x1ad9,
+ 0x8f4d, 0x0c2c,
+ 0x8f4e, 0x1adc,
+ 0x8f57, 0x1add,
+ 0x8f5c, 0x1ade,
+ 0x8f5f, 0x07fe,
+ 0x8f61, 0x06fb,
+ 0x8f62, 0x1adf,
+ 0x8f9b, 0x0a0f,
+ 0x8f9c, 0x1ae2,
+ 0x8f9e, 0x08d9,
+ 0x8f9f, 0x1ae3,
+ 0x8fa3, 0x1ae4,
+ 0x8fa7, 0x10b6,
+ 0x8fa8, 0x10b5,
+ 0x8fad, 0x1ae5,
+ 0x8fae, 0x17ff,
+ 0x8faf, 0x1ae6,
+ 0x8fb0, 0x0b62,
+ 0x8fb1, 0x09f1,
+ 0x8fb2, 0x0cf6,
+ 0x8fb7, 0x1ae7,
+ 0x8fba, 0x0e25,
+ 0x8fbb, 0x0bf0,
+ 0x8fbc, 0x0810,
+ 0x8fbf, 0x0b67,
+ 0x8fc2, 0x04cc,
+ 0x8fc4, 0x0ea6,
+ 0x8fc5, 0x0a1d,
+ 0x8fce, 0x0734,
+ 0x8fd1, 0x06d9,
+ 0x8fd4, 0x0e26,
+ 0x8fda, 0x1ae8,
+ 0x8fe2, 0x1aea,
+ 0x8fe5, 0x1ae9,
+ 0x8fe6, 0x0560,
+ 0x8fe9, 0x0cce,
+ 0x8fea, 0x1aeb,
+ 0x8feb, 0x0d2d,
+ 0x8fed, 0x0c2d,
+ 0x8fef, 0x1aec,
+ 0x8ff0, 0x095c,
+ 0x8ff4, 0x1aee,
+ 0x8ff7, 0x0ece,
+ 0x8ff8, 0x1afd,
+ 0x8ff9, 0x1af0,
+ 0x8ffd, 0x0be5,
+ 0x9000, 0x0b40,
+ 0x9001, 0x0af9,
+ 0x9003, 0x0c80,
+ 0x9005, 0x1aef,
+ 0x9006, 0x066f,
+ 0x900b, 0x1af8,
+ 0x900d, 0x1af5,
+ 0x900e, 0x1b02,
+ 0x900f, 0x0c81,
+ 0x9010, 0x0b9e,
+ 0x9011, 0x1af2,
+ 0x9013, 0x0c1a,
+ 0x9014, 0x0c4d,
+ 0x9015, 0x1af3,
+ 0x9016, 0x1af7,
+ 0x9017, 0x0a26,
+ 0x9019, 0x0d1d,
+ 0x901a, 0x0be8,
+ 0x901d, 0x0a66,
+ 0x901e, 0x1af6,
+ 0x901f, 0x0b0e,
+ 0x9020, 0x0b04,
+ 0x9021, 0x1af4,
+ 0x9022, 0x046d,
+ 0x9023, 0x0fc8,
+ 0x9027, 0x1af9,
+ 0x902e, 0x0b41,
+ 0x9031, 0x093f,
+ 0x9032, 0x0a10,
+ 0x9035, 0x1afb,
+ 0x9036, 0x1afa,
+ 0x9038, 0x04b3,
+ 0x9039, 0x1afc,
+ 0x903c, 0x0da1,
+ 0x903e, 0x1b04,
+ 0x9041, 0x0cb3,
+ 0x9042, 0x0a31,
+ 0x9045, 0x0b97,
+ 0x9047, 0x06f0,
+ 0x9049, 0x1b03,
+ 0x904a, 0x0f21,
+ 0x904b, 0x04e1,
+ 0x904d, 0x0e27,
+ 0x904e, 0x0561,
+ 0x904f, 0x1afe,
+ 0x9053, 0x0c93,
+ 0x9054, 0x0b61,
+ 0x9055, 0x04a7,
+ 0x9056, 0x1b05,
+ 0x9058, 0x1b06,
+ 0x9059, 0x1d34,
+ 0x905c, 0x0b1d,
+ 0x905e, 0x1b07,
+ 0x9060, 0x0515,
+ 0x9061, 0x0ace,
+ 0x9063, 0x0763,
+ 0x9065, 0x0f44,
+ 0x9067, 0x21ba,
+ 0x9068, 0x1b08,
+ 0x9069, 0x0c26,
+ 0x906d, 0x0afa,
+ 0x906e, 0x0903,
+ 0x906f, 0x1b09,
+ 0x9072, 0x1b0c,
+ 0x9075, 0x096f,
+ 0x9076, 0x1b0a,
+ 0x9077, 0x0aad,
+ 0x9078, 0x0aac,
+ 0x907a, 0x04a8,
+ 0x907c, 0x0f93,
+ 0x907d, 0x1b0e,
+ 0x907f, 0x0d86,
+ 0x9080, 0x1b10,
+ 0x9081, 0x1b0f,
+ 0x9082, 0x1b0d,
+ 0x9083, 0x1737,
+ 0x9084, 0x0610,
+ 0x9087, 0x1aed,
+ 0x9089, 0x1b12,
+ 0x908a, 0x1b11,
+ 0x908f, 0x1b13,
+ 0x9091, 0x0f22,
+ 0x90a3, 0x0cb9,
+ 0x90a6, 0x0e5c,
+ 0x90a8, 0x1b14,
+ 0x90aa, 0x0905,
+ 0x90af, 0x1b15,
+ 0x90b1, 0x1b16,
+ 0x90b5, 0x1b17,
+ 0x90b8, 0x0c1b,
+ 0x90c1, 0x04ae,
+ 0x90ca, 0x07eb,
+ 0x90ce, 0x0fe0,
+ 0x90db, 0x1b1b,
+ 0x90de, 0x21bb,
+ 0x90e1, 0x070a,
+ 0x90e2, 0x1b18,
+ 0x90e4, 0x1b19,
+ 0x90e8, 0x0de6,
+ 0x90ed, 0x05b2,
+ 0x90f5, 0x0f23,
+ 0x90f7, 0x06b7,
+ 0x90fd, 0x0c4e,
+ 0x9102, 0x1b1c,
+ 0x9112, 0x1b1d,
+ 0x9115, 0x21bd,
+ 0x9119, 0x1b1e,
+ 0x9127, 0x21be,
+ 0x912d, 0x0c1c,
+ 0x9130, 0x1b20,
+ 0x9132, 0x1b1f,
+ 0x9149, 0x0cab,
+ 0x914a, 0x1b21,
+ 0x914b, 0x0940,
+ 0x914c, 0x090c,
+ 0x914d, 0x0d11,
+ 0x914e, 0x0baf,
+ 0x9152, 0x091e,
+ 0x9154, 0x0a32,
+ 0x9156, 0x1b22,
+ 0x9158, 0x1b23,
+ 0x9162, 0x0a23,
+ 0x9163, 0x1b24,
+ 0x9165, 0x1b25,
+ 0x9169, 0x1b26,
+ 0x916a, 0x0f59,
+ 0x916c, 0x0941,
+ 0x9172, 0x1b28,
+ 0x9173, 0x1b27,
+ 0x9175, 0x07ec,
+ 0x9177, 0x0805,
+ 0x9178, 0x088e,
+ 0x9182, 0x1b2b,
+ 0x9187, 0x0970,
+ 0x9189, 0x1b2a,
+ 0x918b, 0x1b29,
+ 0x918d, 0x0b49,
+ 0x9190, 0x07a3,
+ 0x9192, 0x0a67,
+ 0x9197, 0x0d44,
+ 0x919c, 0x0943,
+ 0x91a2, 0x1b2c,
+ 0x91a4, 0x09c7,
+ 0x91aa, 0x1b2f,
+ 0x91ab, 0x1b2d,
+ 0x91ac, 0x1e1b,
+ 0x91af, 0x1b2e,
+ 0x91b1, 0x1e61,
+ 0x91b4, 0x1b31,
+ 0x91b5, 0x1b30,
+ 0x91b8, 0x09e2,
+ 0x91ba, 0x1b32,
+ 0x91c0, 0x1b33,
+ 0x91c6, 0x0d64,
+ 0x91c7, 0x0843,
+ 0x91c8, 0x090d,
+ 0x91c9, 0x1b35,
+ 0x91cb, 0x1b36,
+ 0x91cc, 0x0f6c,
+ 0x91cd, 0x094f,
+ 0x91ce, 0x0efa,
+ 0x91cf, 0x0f94,
+ 0x91d0, 0x1b37,
+ 0x91d1, 0x06da,
+ 0x91d6, 0x1b38,
+ 0x91d7, 0x21c0,
+ 0x91d8, 0x0c1d,
+ 0x91da, 0x21bf,
+ 0x91db, 0x1b3b,
+ 0x91dc, 0x05d6,
+ 0x91dd, 0x0a11,
+ 0x91de, 0x21c1,
+ 0x91df, 0x1b39,
+ 0x91e1, 0x1b3a,
+ 0x91e3, 0x0bfc,
+ 0x91e4, 0x21c4,
+ 0x91e6, 0x0e83,
+ 0x91e7, 0x06f4,
+ 0x91ed, 0x21c2,
+ 0x91f5, 0x1b3d,
+ 0x91fc, 0x1b3c,
+ 0x91ff, 0x1b40,
+ 0x9206, 0x21c6,
+ 0x920a, 0x21c8,
+ 0x920d, 0x0cb7,
+ 0x920e, 0x05a1,
+ 0x9210, 0x21c7,
+ 0x9211, 0x1b44,
+ 0x9214, 0x1b41,
+ 0x9215, 0x1b43,
+ 0x921e, 0x1b3f,
+ 0x9229, 0x1b8a,
+ 0x922c, 0x1b42,
+ 0x9234, 0x0fb3,
+ 0x9237, 0x078e,
+ 0x9239, 0x21cf,
+ 0x923a, 0x21c9,
+ 0x923c, 0x21cb,
+ 0x923f, 0x1b4c,
+ 0x9240, 0x21ca,
+ 0x9244, 0x0c2e,
+ 0x9245, 0x1b47,
+ 0x9248, 0x1b4a,
+ 0x9249, 0x1b48,
+ 0x924b, 0x1b4d,
+ 0x924e, 0x21cc,
+ 0x9250, 0x1b4e,
+ 0x9251, 0x21ce,
+ 0x9257, 0x1b46,
+ 0x9259, 0x21cd,
+ 0x925a, 0x1b53,
+ 0x925b, 0x0516,
+ 0x925e, 0x1b45,
+ 0x9262, 0x0d41,
+ 0x9264, 0x1b49,
+ 0x9266, 0x09c8,
+ 0x9267, 0x21d0,
+ 0x9271, 0x07ed,
+ 0x9277, 0x21d2,
+ 0x927e, 0x0e76,
+ 0x9280, 0x06dc,
+ 0x9283, 0x0950,
+ 0x9285, 0x0c94,
+ 0x9288, 0x20aa,
+ 0x9291, 0x0aaf,
+ 0x9293, 0x1b51,
+ 0x9295, 0x1b4b,
+ 0x9296, 0x1b50,
+ 0x9298, 0x0ecf,
+ 0x929a, 0x0bd4,
+ 0x929b, 0x1b52,
+ 0x929c, 0x1b4f,
+ 0x92a7, 0x21d1,
+ 0x92ad, 0x0aae,
+ 0x92b7, 0x1b56,
+ 0x92b9, 0x1b55,
+ 0x92cf, 0x1b54,
+ 0x92d0, 0x21d7,
+ 0x92d2, 0x0e5d,
+ 0x92d3, 0x21db,
+ 0x92d5, 0x21d9,
+ 0x92d7, 0x21d5,
+ 0x92d9, 0x21d6,
+ 0x92e0, 0x21da,
+ 0x92e4, 0x0985,
+ 0x92e7, 0x21d4,
+ 0x92e9, 0x1b57,
+ 0x92ea, 0x0e2f,
+ 0x92ed, 0x04f6,
+ 0x92f2, 0x0db8,
+ 0x92f3, 0x0bb0,
+ 0x92f8, 0x0692,
+ 0x92f9, 0x20b0,
+ 0x92fa, 0x1b59,
+ 0x92fb, 0x21de,
+ 0x92fc, 0x07ef,
+ 0x92ff, 0x21e1,
+ 0x9302, 0x21e3,
+ 0x9306, 0x087a,
+ 0x930f, 0x1b58,
+ 0x9310, 0x0a33,
+ 0x9318, 0x0a34,
+ 0x9319, 0x1b5c,
+ 0x931a, 0x1b5e,
+ 0x931d, 0x21e2,
+ 0x931e, 0x21e0,
+ 0x9320, 0x09e3,
+ 0x9321, 0x21dd,
+ 0x9322, 0x1b5d,
+ 0x9323, 0x1b5f,
+ 0x9325, 0x21dc,
+ 0x9326, 0x06cb,
+ 0x9328, 0x0db7,
+ 0x932b, 0x090e,
+ 0x932c, 0x0fc9,
+ 0x932e, 0x1b5b,
+ 0x932f, 0x0868,
+ 0x9332, 0x0fe5,
+ 0x9335, 0x1b61,
+ 0x933a, 0x1b60,
+ 0x933b, 0x1b62,
+ 0x9344, 0x1b5a,
+ 0x9348, 0x20a9,
+ 0x934b, 0x0cc1,
+ 0x934d, 0x0c4f,
+ 0x9354, 0x0bf3,
+ 0x9356, 0x1b67,
+ 0x9357, 0x21e5,
+ 0x935b, 0x0b81,
+ 0x935c, 0x1b63,
+ 0x9360, 0x1b64,
+ 0x936c, 0x0703,
+ 0x936e, 0x1b66,
+ 0x9370, 0x21e4,
+ 0x9375, 0x0764,
+ 0x937c, 0x1b65,
+ 0x937e, 0x09c9,
+ 0x938c, 0x05d7,
+ 0x9394, 0x1b6b,
+ 0x9396, 0x082f,
+ 0x9397, 0x0afb,
+ 0x939a, 0x0be6,
+ 0x93a4, 0x21e6,
+ 0x93a7, 0x0599,
+ 0x93ac, 0x1b69,
+ 0x93ae, 0x0bdf,
+ 0x93b0, 0x1b68,
+ 0x93b9, 0x1b6c,
+ 0x93c3, 0x1b72,
+ 0x93c6, 0x21e7,
+ 0x93c8, 0x1b75,
+ 0x93d0, 0x1b74,
+ 0x93d1, 0x0c27,
+ 0x93d6, 0x1b6d,
+ 0x93d8, 0x1b71,
+ 0x93dd, 0x1b73,
+ 0x93de, 0x21e8,
+ 0x93e1, 0x06b8,
+ 0x93e4, 0x1b76,
+ 0x93e5, 0x1b70,
+ 0x93e8, 0x1b6f,
+ 0x93f8, 0x21e9,
+ 0x9403, 0x1b7a,
+ 0x9407, 0x1b7b,
+ 0x9410, 0x1b7c,
+ 0x9413, 0x1b79,
+ 0x9414, 0x1b78,
+ 0x9418, 0x09ca,
+ 0x9419, 0x0c82,
+ 0x941a, 0x1b77,
+ 0x9421, 0x1b80,
+ 0x942b, 0x1b7e,
+ 0x9431, 0x21ea,
+ 0x9435, 0x1b7f,
+ 0x9436, 0x1b7d,
+ 0x9438, 0x0b58,
+ 0x943a, 0x1b81,
+ 0x9441, 0x1b82,
+ 0x9444, 0x1b84,
+ 0x9445, 0x21eb,
+ 0x9448, 0x21ec,
+ 0x9451, 0x0611,
+ 0x9452, 0x1b83,
+ 0x9453, 0x0f06,
+ 0x945a, 0x1b8f,
+ 0x945b, 0x1b85,
+ 0x945e, 0x1b88,
+ 0x9460, 0x1b86,
+ 0x9462, 0x1b87,
+ 0x946a, 0x1b89,
+ 0x9470, 0x1b8b,
+ 0x9475, 0x1b8c,
+ 0x9477, 0x1b8d,
+ 0x947c, 0x1b90,
+ 0x947d, 0x1b8e,
+ 0x947e, 0x1b91,
+ 0x947f, 0x1b93,
+ 0x9481, 0x1b92,
+ 0x9577, 0x0bd5,
+ 0x9580, 0x0ef3,
+ 0x9582, 0x1b94,
+ 0x9583, 0x0ab0,
+ 0x9587, 0x1b95,
+ 0x9589, 0x0e14,
+ 0x958a, 0x1b96,
+ 0x958b, 0x0589,
+ 0x958f, 0x04de,
+ 0x9591, 0x0613,
+ 0x9592, 0x21ed,
+ 0x9593, 0x0612,
+ 0x9594, 0x1b97,
+ 0x9596, 0x1b98,
+ 0x9598, 0x1b99,
+ 0x95a0, 0x1b9b,
+ 0x95a2, 0x0614,
+ 0x95a3, 0x05b3,
+ 0x95a4, 0x07f0,
+ 0x95a5, 0x0d4a,
+ 0x95a7, 0x1b9d,
+ 0x95a8, 0x1b9c,
+ 0x95ad, 0x1b9e,
+ 0x95b2, 0x04fe,
+ 0x95b9, 0x1ba1,
+ 0x95bb, 0x1ba0,
+ 0x95bc, 0x1b9f,
+ 0x95be, 0x1ba2,
+ 0x95c3, 0x1ba5,
+ 0x95c7, 0x048b,
+ 0x95ca, 0x1ba3,
+ 0x95cc, 0x1ba7,
+ 0x95cd, 0x1ba6,
+ 0x95d4, 0x1ba9,
+ 0x95d5, 0x1ba8,
+ 0x95d6, 0x1baa,
+ 0x95d8, 0x0c86,
+ 0x95dc, 0x1bab,
+ 0x95e1, 0x1bac,
+ 0x95e2, 0x1bae,
+ 0x95e5, 0x1bad,
+ 0x961c, 0x0dde,
+ 0x9621, 0x1baf,
+ 0x9628, 0x1bb0,
+ 0x962a, 0x0855,
+ 0x962e, 0x1bb1,
+ 0x9632, 0x0e77,
+ 0x963b, 0x0acd,
+ 0x963f, 0x0468,
+ 0x9640, 0x0b2b,
+ 0x9642, 0x1bb3,
+ 0x9644, 0x0ddf,
+ 0x964b, 0x1bb6,
+ 0x964c, 0x1bb4,
+ 0x964d, 0x07f1,
+ 0x964f, 0x1bb5,
+ 0x9650, 0x0776,
+ 0x965b, 0x0e15,
+ 0x965c, 0x1bb8,
+ 0x965d, 0x1bba,
+ 0x965e, 0x1bb9,
+ 0x965f, 0x1bbb,
+ 0x9662, 0x04c3,
+ 0x9663, 0x0a1e,
+ 0x9664, 0x0986,
+ 0x9665, 0x0615,
+ 0x9666, 0x1bbc,
+ 0x966a, 0x0d1c,
+ 0x966c, 0x1bbe,
+ 0x9670, 0x04c4,
+ 0x9672, 0x1bbd,
+ 0x9673, 0x0be0,
+ 0x9675, 0x0f95,
+ 0x9676, 0x0c83,
+ 0x9677, 0x1bb7,
+ 0x9678, 0x0f6e,
+ 0x967a, 0x0765,
+ 0x967d, 0x0f45,
+ 0x9685, 0x06f1,
+ 0x9686, 0x0f7c,
+ 0x9688, 0x06fe,
+ 0x968a, 0x0b42,
+ 0x968b, 0x186c,
+ 0x968d, 0x1bbf,
+ 0x968e, 0x058a,
+ 0x968f, 0x0a35,
+ 0x9694, 0x05b4,
+ 0x9695, 0x1bc1,
+ 0x9697, 0x1bc2,
+ 0x9698, 0x1bc0,
+ 0x9699, 0x073a,
+ 0x969b, 0x084d,
+ 0x969c, 0x09cb,
+ 0x969d, 0x21f0,
+ 0x96a0, 0x04c5,
+ 0x96a3, 0x0fa1,
+ 0x96a7, 0x1bc4,
+ 0x96a8, 0x1b0b,
+ 0x96aa, 0x1bc3,
+ 0x96af, 0x21f1,
+ 0x96b0, 0x1bc7,
+ 0x96b1, 0x1bc5,
+ 0x96b4, 0x1bc8,
+ 0x96b6, 0x1bc9,
+ 0x96b7, 0x0fb4,
+ 0x96b8, 0x1bca,
+ 0x96bb, 0x0a6d,
+ 0x96bc, 0x0d4f,
+ 0x96c0, 0x0a43,
+ 0x96c1, 0x0623,
+ 0x96c4, 0x0f24,
+ 0x96c5, 0x056d,
+ 0x96c6, 0x0942,
+ 0x96c7, 0x078f,
+ 0x96c9, 0x1bce,
+ 0x96cb, 0x1bcd,
+ 0x96cc, 0x08c1,
+ 0x96cd, 0x1bcf,
+ 0x96ce, 0x1bcc,
+ 0x96d1, 0x0876,
+ 0x96d5, 0x1bd3,
+ 0x96d6, 0x1992,
+ 0x96d9, 0x10eb,
+ 0x96db, 0x0a3d,
+ 0x96dc, 0x1bd1,
+ 0x96e2, 0x0f6d,
+ 0x96e3, 0x0cc9,
+ 0x96e8, 0x04cd,
+ 0x96ea, 0x0a87,
+ 0x96eb, 0x08e2,
+ 0x96f0, 0x0e07,
+ 0x96f2, 0x04e2,
+ 0x96f6, 0x0fb5,
+ 0x96f7, 0x0f55,
+ 0x96f9, 0x1bd4,
+ 0x96fb, 0x0c3f,
+ 0x9700, 0x0927,
+ 0x9704, 0x1bd5,
+ 0x9706, 0x1bd6,
+ 0x9707, 0x0a12,
+ 0x9708, 0x1bd7,
+ 0x970a, 0x0fb6,
+ 0x970d, 0x1bd2,
+ 0x970e, 0x1bd9,
+ 0x970f, 0x1bdb,
+ 0x9711, 0x1bda,
+ 0x9713, 0x1bd8,
+ 0x9716, 0x1bdc,
+ 0x9719, 0x1bdd,
+ 0x971c, 0x0afc,
+ 0x971e, 0x0562,
+ 0x9724, 0x1bde,
+ 0x9727, 0x0ec4,
+ 0x972a, 0x1bdf,
+ 0x9730, 0x1be0,
+ 0x9732, 0x0fd0,
+ 0x9733, 0x21f2,
+ 0x9738, 0x1414,
+ 0x9739, 0x1be1,
+ 0x973b, 0x21f3,
+ 0x973d, 0x1be2,
+ 0x9742, 0x1be7,
+ 0x9743, 0x21f4,
+ 0x9744, 0x1be4,
+ 0x9746, 0x1be5,
+ 0x9748, 0x1be6,
+ 0x9749, 0x1be8,
+ 0x974d, 0x21f5,
+ 0x974f, 0x21f6,
+ 0x9751, 0x21f7,
+ 0x9752, 0x0a68,
+ 0x9755, 0x21f8,
+ 0x9756, 0x0f03,
+ 0x9759, 0x0a69,
+ 0x975c, 0x1be9,
+ 0x975e, 0x0d87,
+ 0x9760, 0x1bea,
+ 0x9761, 0x1d06,
+ 0x9762, 0x0ed8,
+ 0x9764, 0x1beb,
+ 0x9766, 0x1bec,
+ 0x9768, 0x1bed,
+ 0x9769, 0x05b5,
+ 0x976b, 0x1bef,
+ 0x976d, 0x0a1f,
+ 0x9771, 0x1bf0,
+ 0x9774, 0x06fa,
+ 0x9779, 0x1bf1,
+ 0x977a, 0x1bf5,
+ 0x977c, 0x1bf3,
+ 0x9781, 0x1bf4,
+ 0x9784, 0x05d1,
+ 0x9785, 0x1bf2,
+ 0x9786, 0x1bf6,
+ 0x978b, 0x1bf7,
+ 0x978d, 0x048c,
+ 0x978f, 0x1bf8,
+ 0x9798, 0x09cc,
+ 0x979c, 0x1bfa,
+ 0x97a0, 0x0661,
+ 0x97a3, 0x1bfd,
+ 0x97a6, 0x1bfc,
+ 0x97a8, 0x1bfb,
+ 0x97ab, 0x1a34,
+ 0x97ad, 0x0e2c,
+ 0x97b3, 0x1bfe,
+ 0x97c3, 0x1c00,
+ 0x97c6, 0x1c01,
+ 0x97c8, 0x1c02,
+ 0x97cb, 0x1c03,
+ 0x97d3, 0x0616,
+ 0x97dc, 0x1c04,
+ 0x97ed, 0x1c05,
+ 0x97ee, 0x0cd9,
+ 0x97f2, 0x1c07,
+ 0x97f3, 0x053b,
+ 0x97f5, 0x1c0a,
+ 0x97f6, 0x1c09,
+ 0x97fb, 0x04c6,
+ 0x97ff, 0x06b9,
+ 0x9801, 0x0e17,
+ 0x9802, 0x0bd6,
+ 0x9803, 0x0812,
+ 0x9805, 0x07f2,
+ 0x9806, 0x0971,
+ 0x9808, 0x0a22,
+ 0x980c, 0x1c0c,
+ 0x980f, 0x1c0b,
+ 0x9810, 0x0f2c,
+ 0x9811, 0x0624,
+ 0x9812, 0x0d66,
+ 0x9813, 0x0cb4,
+ 0x9817, 0x0a42,
+ 0x9818, 0x0f96,
+ 0x981a, 0x0731,
+ 0x9821, 0x1c0f,
+ 0x9824, 0x1c0e,
+ 0x982c, 0x0e79,
+ 0x982d, 0x0c84,
+ 0x9830, 0x1e73,
+ 0x9834, 0x04f2,
+ 0x9837, 0x1c10,
+ 0x9838, 0x1c0d,
+ 0x983b, 0x0dc3,
+ 0x983c, 0x0f54,
+ 0x983d, 0x1c11,
+ 0x9846, 0x1c12,
+ 0x984b, 0x1c14,
+ 0x984c, 0x0b4a,
+ 0x984d, 0x05b9,
+ 0x984f, 0x1c13,
+ 0x9854, 0x0625,
+ 0x9855, 0x0766,
+ 0x9857, 0x21f9,
+ 0x9858, 0x0626,
+ 0x985a, 0x1e48,
+ 0x985b, 0x0c39,
+ 0x985e, 0x0fa8,
+ 0x9865, 0x21fa,
+ 0x9867, 0x0790,
+ 0x986b, 0x1c15,
+ 0x986f, 0x1c16,
+ 0x9873, 0x1c1a,
+ 0x9874, 0x1c19,
+ 0x98a8, 0x0de9,
+ 0x98aa, 0x1c1b,
+ 0x98af, 0x1c1c,
+ 0x98b1, 0x1c1d,
+ 0x98b6, 0x1c1e,
+ 0x98c3, 0x1c20,
+ 0x98c4, 0x1c1f,
+ 0x98c6, 0x1c21,
+ 0x98db, 0x0d88,
+ 0x98dc, 0x1839,
+ 0x98df, 0x09ef,
+ 0x98e2, 0x064c,
+ 0x98e9, 0x1c22,
+ 0x98eb, 0x1c23,
+ 0x98ed, 0x10c1,
+ 0x98ee, 0x14da,
+ 0x98ef, 0x0d67,
+ 0x98f2, 0x04bf,
+ 0x98f4, 0x047f,
+ 0x98fc, 0x08c2,
+ 0x98fd, 0x0e5e,
+ 0x98fe, 0x09e6,
+ 0x9903, 0x1c24,
+ 0x9905, 0x0eeb,
+ 0x9909, 0x1c25,
+ 0x990a, 0x0f46,
+ 0x990c, 0x04e4,
+ 0x9910, 0x088f,
+ 0x9912, 0x1c26,
+ 0x9913, 0x056e,
+ 0x9914, 0x1c27,
+ 0x9918, 0x1c28,
+ 0x991d, 0x1c2a,
+ 0x9920, 0x1c2d,
+ 0x9921, 0x1c29,
+ 0x9924, 0x1c2c,
+ 0x9927, 0x21fd,
+ 0x9928, 0x0617,
+ 0x992c, 0x1c2e,
+ 0x992e, 0x1c2f,
+ 0x993d, 0x1c30,
+ 0x9942, 0x1c32,
+ 0x9945, 0x1c34,
+ 0x9949, 0x1c33,
+ 0x994b, 0x1c36,
+ 0x994c, 0x1c39,
+ 0x9950, 0x1c35,
+ 0x9951, 0x1c37,
+ 0x9955, 0x1c3a,
+ 0x9957, 0x06ba,
+ 0x9996, 0x091f,
+ 0x9997, 0x1c3b,
+ 0x9999, 0x07f3,
+ 0x999e, 0x21ff,
+ 0x99a5, 0x1c3d,
+ 0x99a8, 0x059c,
+ 0x99ac, 0x0d05,
+ 0x99ad, 0x1c3e,
+ 0x99b3, 0x0b98,
+ 0x99b4, 0x0cc3,
+ 0x99bc, 0x1c40,
+ 0x99c1, 0x0d33,
+ 0x99c4, 0x0b2c,
+ 0x99c5, 0x04fa,
+ 0x99c6, 0x06e6,
+ 0x99c8, 0x06e7,
+ 0x99d0, 0x0bb1,
+ 0x99d1, 0x1c45,
+ 0x99d2, 0x06e8,
+ 0x99d5, 0x056f,
+ 0x99d8, 0x1c44,
+ 0x99db, 0x1c42,
+ 0x99dd, 0x1c43,
+ 0x99df, 0x1c41,
+ 0x99e2, 0x1c4f,
+ 0x99ed, 0x1c46,
+ 0x99f1, 0x1c48,
+ 0x99f8, 0x1c4b,
+ 0x99fb, 0x1c4a,
+ 0x99ff, 0x0963,
+ 0x9a01, 0x1c4c,
+ 0x9a05, 0x1c4e,
+ 0x9a0e, 0x064d,
+ 0x9a0f, 0x1c4d,
+ 0x9a12, 0x0afd,
+ 0x9a13, 0x0767,
+ 0x9a19, 0x1c50,
+ 0x9a28, 0x0b2d,
+ 0x9a2b, 0x1c51,
+ 0x9a30, 0x0c85,
+ 0x9a37, 0x1c52,
+ 0x9a3e, 0x1c57,
+ 0x9a40, 0x1c55,
+ 0x9a42, 0x1c54,
+ 0x9a43, 0x1c56,
+ 0x9a45, 0x1c53,
+ 0x9a4d, 0x1c59,
+ 0x9a4e, 0x2200,
+ 0x9a52, 0x1e2f,
+ 0x9a55, 0x1c58,
+ 0x9a57, 0x1c5b,
+ 0x9a5a, 0x06bb,
+ 0x9a5b, 0x1c5a,
+ 0x9a5f, 0x1c5c,
+ 0x9a62, 0x1c5d,
+ 0x9a64, 0x1c5f,
+ 0x9a65, 0x1c5e,
+ 0x9a69, 0x1c60,
+ 0x9a6a, 0x1c62,
+ 0x9a6b, 0x1c61,
+ 0x9aa8, 0x080e,
+ 0x9aad, 0x1c63,
+ 0x9ab0, 0x1c64,
+ 0x9ab8, 0x059a,
+ 0x9abc, 0x1c65,
+ 0x9ac0, 0x1c66,
+ 0x9ac4, 0x0a37,
+ 0x9acf, 0x1c67,
+ 0x9ad1, 0x1c68,
+ 0x9ad3, 0x1c69,
+ 0x9ad8, 0x07f4,
+ 0x9ad9, 0x2201,
+ 0x9adc, 0x2202,
+ 0x9ade, 0x1c6b,
+ 0x9ae2, 0x1c6d,
+ 0x9ae6, 0x1c6f,
+ 0x9aea, 0x0d45,
+ 0x9aeb, 0x1c71,
+ 0x9aed, 0x0d98,
+ 0x9aee, 0x1c72,
+ 0x9aef, 0x1c70,
+ 0x9af1, 0x1c74,
+ 0x9af4, 0x1c73,
+ 0x9af7, 0x1c75,
+ 0x9afb, 0x1c76,
+ 0x9b06, 0x1c77,
+ 0x9b18, 0x1c78,
+ 0x9b1a, 0x1c79,
+ 0x9b1f, 0x1c7a,
+ 0x9b22, 0x1c7b,
+ 0x9b25, 0x1c7d,
+ 0x9b27, 0x1c7e,
+ 0x9b2e, 0x1c82,
+ 0x9b31, 0x14d4,
+ 0x9b32, 0x1c84,
+ 0x9b3b, 0x17a9,
+ 0x9b3c, 0x064e,
+ 0x9b41, 0x057f,
+ 0x9b42, 0x0822,
+ 0x9b43, 0x1c86,
+ 0x9b44, 0x1c85,
+ 0x9b45, 0x0eb1,
+ 0x9b4d, 0x1c88,
+ 0x9b4f, 0x1c87,
+ 0x9b51, 0x1c8a,
+ 0x9b54, 0x0e90,
+ 0x9b58, 0x1c8b,
+ 0x9b5a, 0x0695,
+ 0x9b6f, 0x0fcb,
+ 0x9b72, 0x2204,
+ 0x9b74, 0x1c8c,
+ 0x9b75, 0x2203,
+ 0x9b83, 0x1c8e,
+ 0x9b8e, 0x0482,
+ 0x9b8f, 0x2205,
+ 0x9b91, 0x1c8f,
+ 0x9b92, 0x0dfb,
+ 0x9b93, 0x1c8d,
+ 0x9b96, 0x1c90,
+ 0x9b9f, 0x1c92,
+ 0x9ba8, 0x1c94,
+ 0x9baa, 0x0e9c,
+ 0x9bab, 0x087b,
+ 0x9bad, 0x086a,
+ 0x9bae, 0x0ab1,
+ 0x9bb1, 0x2206,
+ 0x9bb4, 0x1c95,
+ 0x9bb9, 0x1c98,
+ 0x9bbb, 0x2207,
+ 0x9bc0, 0x1c96,
+ 0x9bc6, 0x1c99,
+ 0x9bc9, 0x07a5,
+ 0x9bca, 0x1c97,
+ 0x9bcf, 0x1c9a,
+ 0x9bd1, 0x1c9b,
+ 0x9bd4, 0x1ca0,
+ 0x9bd6, 0x0878,
+ 0x9bdb, 0x0b44,
+ 0x9be1, 0x1ca1,
+ 0x9be2, 0x1c9e,
+ 0x9be3, 0x1c9d,
+ 0x9be4, 0x1c9f,
+ 0x9be8, 0x0735,
+ 0x9bf0, 0x1ca5,
+ 0x9bf1, 0x1ca4,
+ 0x9bf2, 0x1ca3,
+ 0x9bf5, 0x0477,
+ 0x9c00, 0x2208,
+ 0x9c04, 0x1caf,
+ 0x9c06, 0x1cab,
+ 0x9c08, 0x1cac,
+ 0x9c09, 0x1ca8,
+ 0x9c0a, 0x1cae,
+ 0x9c0c, 0x1caa,
+ 0x9c0d, 0x05c0,
+ 0x9c10, 0x0ff2,
+ 0x9c12, 0x1cad,
+ 0x9c13, 0x1ca9,
+ 0x9c14, 0x1ca7,
+ 0x9c15, 0x1ca6,
+ 0x9c1b, 0x1cb1,
+ 0x9c21, 0x1cb4,
+ 0x9c24, 0x1cb3,
+ 0x9c25, 0x1cb2,
+ 0x9c2d, 0x0dbb,
+ 0x9c2e, 0x1cb0,
+ 0x9c2f, 0x04b7,
+ 0x9c30, 0x1cb5,
+ 0x9c32, 0x1cb7,
+ 0x9c39, 0x05cd,
+ 0x9c3a, 0x1ca2,
+ 0x9c3b, 0x04d9,
+ 0x9c3e, 0x1cb9,
+ 0x9c46, 0x1cb8,
+ 0x9c47, 0x1cb6,
+ 0x9c48, 0x0b6b,
+ 0x9c52, 0x0e9e,
+ 0x9c57, 0x0fa2,
+ 0x9c5a, 0x1cba,
+ 0x9c60, 0x1cbb,
+ 0x9c67, 0x1cbc,
+ 0x9c76, 0x1cbd,
+ 0x9c78, 0x1cbe,
+ 0x9ce5, 0x0bd7,
+ 0x9ce7, 0x1cbf,
+ 0x9ce9, 0x0d4b,
+ 0x9ceb, 0x1cc4,
+ 0x9cec, 0x1cc0,
+ 0x9cf0, 0x1cc1,
+ 0x9cf3, 0x0e5f,
+ 0x9cf4, 0x0ed0,
+ 0x9cf6, 0x0ca8,
+ 0x9d03, 0x1cc5,
+ 0x9d06, 0x1cc6,
+ 0x9d07, 0x0c96,
+ 0x9d08, 0x1cc3,
+ 0x9d09, 0x1cc2,
+ 0x9d0e, 0x052a,
+ 0x9d12, 0x1cce,
+ 0x9d15, 0x1ccd,
+ 0x9d1b, 0x0517,
+ 0x9d1f, 0x1ccb,
+ 0x9d23, 0x1cca,
+ 0x9d26, 0x1cc8,
+ 0x9d28, 0x05d9,
+ 0x9d2a, 0x1cc7,
+ 0x9d2b, 0x08de,
+ 0x9d2c, 0x0529,
+ 0x9d3b, 0x07f5,
+ 0x9d3e, 0x1cd1,
+ 0x9d3f, 0x1cd0,
+ 0x9d41, 0x1ccf,
+ 0x9d44, 0x1ccc,
+ 0x9d46, 0x1cd2,
+ 0x9d48, 0x1cd3,
+ 0x9d50, 0x1cd8,
+ 0x9d51, 0x1cd7,
+ 0x9d59, 0x1cd9,
+ 0x9d5c, 0x04cf,
+ 0x9d5d, 0x1cd4,
+ 0x9d60, 0x0806,
+ 0x9d61, 0x0ec5,
+ 0x9d64, 0x1cd6,
+ 0x9d6b, 0x220a,
+ 0x9d6c, 0x0e60,
+ 0x9d6f, 0x1cde,
+ 0x9d70, 0x2209,
+ 0x9d72, 0x1cda,
+ 0x9d7a, 0x1cdf,
+ 0x9d87, 0x1cdc,
+ 0x9d89, 0x1cdb,
+ 0x9d8f, 0x0732,
+ 0x9d9a, 0x1ce0,
+ 0x9da4, 0x1ce1,
+ 0x9da9, 0x1ce2,
+ 0x9dab, 0x1cdd,
+ 0x9daf, 0x1cc9,
+ 0x9db2, 0x1ce3,
+ 0x9db4, 0x0bfd,
+ 0x9db8, 0x1ce7,
+ 0x9dba, 0x1ce8,
+ 0x9dbb, 0x1ce6,
+ 0x9dc1, 0x1ce5,
+ 0x9dc2, 0x1ceb,
+ 0x9dc4, 0x1ce4,
+ 0x9dc6, 0x1ce9,
+ 0x9dcf, 0x1cea,
+ 0x9dd3, 0x1ced,
+ 0x9dd7, 0x1dde,
+ 0x9dd9, 0x1cec,
+ 0x9de6, 0x1cef,
+ 0x9ded, 0x1cf0,
+ 0x9def, 0x1cf1,
+ 0x9df2, 0x0fef,
+ 0x9df8, 0x1cee,
+ 0x9df9, 0x0b4b,
+ 0x9dfa, 0x085d,
+ 0x9dfd, 0x1cf2,
+ 0x9e19, 0x220c,
+ 0x9e1a, 0x1cf3,
+ 0x9e1e, 0x1cf5,
+ 0x9e75, 0x1cf6,
+ 0x9e78, 0x0768,
+ 0x9e79, 0x1cf7,
+ 0x9e7c, 0x1dfd,
+ 0x9e7d, 0x1cf8,
+ 0x9e7f, 0x08db,
+ 0x9e81, 0x1cf9,
+ 0x9e88, 0x1cfa,
+ 0x9e8b, 0x1cfb,
+ 0x9e91, 0x1cff,
+ 0x9e92, 0x1cfd,
+ 0x9e93, 0x0fe2,
+ 0x9e95, 0x1cfe,
+ 0x9e97, 0x0fb7,
+ 0x9e9d, 0x1d00,
+ 0x9e9f, 0x0fa3,
+ 0x9ea5, 0x1d01,
+ 0x9ea6, 0x0d34,
+ 0x9ea9, 0x1d02,
+ 0x9eaa, 0x1d04,
+ 0x9ead, 0x1d05,
+ 0x9eb4, 0x1e02,
+ 0x9eb5, 0x1e75,
+ 0x9eb8, 0x1d03,
+ 0x9eb9, 0x07ff,
+ 0x9eba, 0x0ed9,
+ 0x9ebb, 0x0e91,
+ 0x9ebc, 0x1284,
+ 0x9ebe, 0x14ff,
+ 0x9ebf, 0x0ea9,
+ 0x9ec4, 0x052b,
+ 0x9ecc, 0x1d07,
+ 0x9ecd, 0x066a,
+ 0x9ece, 0x1d08,
+ 0x9ed1, 0x220d,
+ 0x9ed2, 0x0807,
+ 0x9ed4, 0x1d0b,
+ 0x9ed8, 0x160d,
+ 0x9ed9, 0x0ee7,
+ 0x9edb, 0x0b43,
+ 0x9edc, 0x1d0c,
+ 0x9edd, 0x1d0e,
+ 0x9ede, 0x1d0d,
+ 0x9ee0, 0x1d0f,
+ 0x9ee5, 0x1d10,
+ 0x9ee8, 0x1d11,
+ 0x9eef, 0x1d12,
+ 0x9ef4, 0x1d13,
+ 0x9ef6, 0x1d14,
+ 0x9ef9, 0x1d16,
+ 0x9efb, 0x1d17,
+ 0x9f07, 0x1d1a,
+ 0x9f0e, 0x0c1e,
+ 0x9f13, 0x0791,
+ 0x9f15, 0x1d1d,
+ 0x9f20, 0x0acf,
+ 0x9f21, 0x1d1e,
+ 0x9f2c, 0x1d1f,
+ 0x9f3b, 0x0d93,
+ 0x9f3e, 0x1d20,
+ 0x9f4a, 0x1d21,
+ 0x9f4b, 0x170a,
+ 0x9f4e, 0x1a7b,
+ 0x9f4f, 0x1c06,
+ 0x9f52, 0x1d22,
+ 0x9f54, 0x1d23,
+ 0x9f5f, 0x1d25,
+ 0x9f62, 0x0fb8,
+ 0x9f63, 0x1d24,
+ 0x9f66, 0x1d28,
+ 0x9f6a, 0x1d2b,
+ 0x9f6c, 0x1d2a,
+ 0x9f72, 0x1d2d,
+ 0x9f76, 0x1d2e,
+ 0x9f77, 0x1d2c,
+ 0x9f8d, 0x0f7e,
+ 0x9f95, 0x1d2f,
+ 0x9f9c, 0x1d30,
+ 0x9f9d, 0x1727,
+ 0x9fa0, 0x1d31,
+ 0xf929, 0x2129,
+ 0xf9dc, 0x21ee,
+ 0xfa0e, 0x20da,
+ 0xfa0f, 0x20e5,
+ 0xfa11, 0x20fb,
+ 0xfa12, 0x2121,
+ 0xfa13, 0x2131,
+ 0xfa14, 0x2133,
+ 0xfa15, 0x215e,
+ 0xfa16, 0x2164,
+ 0xfa17, 0x217b,
+ 0xfa18, 0x2183,
+ 0xfa1b, 0x2187,
+ 0xfa1c, 0x218b,
+ 0xfa1d, 0x218e,
+ 0xfa1e, 0x2197,
+ 0xfa1f, 0x21a2,
+ 0xfa20, 0x21a4,
+ 0xfa22, 0x21ae,
+ 0xfa23, 0x21b6,
+ 0xfa24, 0x21b8,
+ 0xfa26, 0x21bc,
+ 0xfa27, 0x21d8,
+ 0xfa28, 0x21df,
+ 0xfa29, 0x21ef,
+ 0xfa2a, 0x21fb,
+ 0xfa2c, 0x21fe,
+ 0xfa2d, 0x220b,
+ 0xfb01, 0x0070,
+ 0xfe30, 0x1eda,
+ 0xfe31, 0x1ed4,
+ 0xfe33, 0x1ed2,
+ 0xfe35, 0x1edb,
+ 0xfe37, 0x1ee1,
+ 0xfe39, 0x1edd,
+ 0xfe3b, 0x1eeb,
+ 0xfe3d, 0x1ee5,
+ 0xfe3f, 0x1ee3,
+ 0xfe41, 0x1ee7,
+ 0xff01, 0x0282,
+ 0xff02, 0x1f47,
+ 0xff03, 0x02cc,
+ 0xff04, 0x02c8,
+ 0xff05, 0x02cb,
+ 0xff06, 0x02cd,
+ 0xff07, 0x1f46,
+ 0xff08, 0x02a2,
+ 0xff0a, 0x02ce,
+ 0xff0b, 0x02b4,
+ 0xff0c, 0x027c,
+ 0xff0d, 0x0296,
+ 0xff0e, 0x027d,
+ 0xff0f, 0x0297,
+ 0xff10, 0x030c,
+ 0xff1a, 0x027f,
+ 0xff1c, 0x02bb,
+ 0xff1d, 0x02b9,
+ 0xff1e, 0x02bc,
+ 0xff1f, 0x0281,
+ 0xff20, 0x02cf,
+ 0xff21, 0x0316,
+ 0xff3b, 0x02a6,
+ 0xff3c, 0x0298,
+ 0xff3d, 0x02a7,
+ 0xff3e, 0x0288,
+ 0xff3f, 0x028a,
+ 0xff40, 0x0286,
+ 0xff41, 0x0330,
+ 0xff5b, 0x02a8,
+ 0xff5c, 0x029b,
+ 0xff5d, 0x02a9,
+ 0xff5e, 0x0299,
+ 0xff61, 0x0147,
+ 0xffe0, 0x02c9,
+ 0xffe2, 0x02ef,
+ 0xffe3, 0x0289,
+ 0xffe4, 0x1f45,
+ 0xffe5, 0x02c7,
+ 0xffe8, 0x0143,
+ 0x00b0, 0x204d,
+ 0x2015, 0x1ed4,
+ 0x2016, 0x1ed7,
+ 0x2018, 0x2059,
+ 0x201c, 0x2057,
+ 0x2025, 0x1eda,
+ 0x2026, 0x1ed9,
+ 0x2032, 0x2051,
+ 0x2033, 0x205b,
+ 0x2190, 0x02e2,
+ 0x2191, 0x02e0,
+ 0x2192, 0x02e3,
+ 0x2193, 0x02e1,
+ 0x2225, 0x1ed7,
+ 0x223c, 0x1ed6,
+ 0x22ef, 0x1ed9,
+ 0x2500, 0x1d39,
+ 0x2502, 0x1d37,
+ 0x2504, 0x1d3d,
+ 0x2506, 0x1d3b,
+ 0x2508, 0x1d41,
+ 0x250a, 0x1d3f,
+ 0x250c, 0x1d47,
+ 0x250d, 0x1d49,
+ 0x250e, 0x1d48,
+ 0x250f, 0x1d4a,
+ 0x2510, 0x1d4f,
+ 0x2511, 0x1d51,
+ 0x2512, 0x1d50,
+ 0x2513, 0x1d52,
+ 0x2514, 0x1d43,
+ 0x2515, 0x1d45,
+ 0x2516, 0x1d44,
+ 0x2517, 0x1d46,
+ 0x2518, 0x1d4b,
+ 0x2519, 0x1d4d,
+ 0x251a, 0x1d4c,
+ 0x251b, 0x1d4e,
+ 0x251c, 0x1d63,
+ 0x251d, 0x1d67,
+ 0x251e, 0x1d65,
+ 0x251f, 0x1d64,
+ 0x2520, 0x1d66,
+ 0x2521, 0x1d69,
+ 0x2522, 0x1d68,
+ 0x2523, 0x1d6a,
+ 0x2525, 0x1d6f,
+ 0x2526, 0x1d6d,
+ 0x2527, 0x1d6c,
+ 0x2528, 0x1d6e,
+ 0x2529, 0x1d71,
+ 0x252a, 0x1d70,
+ 0x252b, 0x1d72,
+ 0x252c, 0x1d5b,
+ 0x252d, 0x1d5d,
+ 0x2530, 0x1d5c,
+ 0x2531, 0x1d60,
+ 0x2534, 0x1d53,
+ 0x2535, 0x1d55,
+ 0x2538, 0x1d54,
+ 0x2539, 0x1d58,
+ 0x253d, 0x1d77,
+ 0x2540, 0x1d75,
+ 0x2541, 0x1d74,
+ 0x2542, 0x1d76,
+ 0x2543, 0x1d7b,
+ 0x2544, 0x1d7d,
+ 0x2545, 0x1d7a,
+ 0x2546, 0x1d7c,
+ 0x2547, 0x1d81,
+ 0x2548, 0x1d80,
+ 0x2549, 0x1d7e,
+ 0x3001, 0x1ecf,
+ 0x3008, 0x1ee3,
+ 0x3013, 0x204e,
+ 0x3014, 0x1edd,
+ 0x301c, 0x1ed6,
+ 0x301d, 0x1f14,
+ 0x301f, 0x1f15,
+ 0x3041, 0x1eee,
+ 0x3043, 0x1eef,
+ 0x3045, 0x1ef0,
+ 0x3047, 0x1ef1,
+ 0x3049, 0x1ef2,
+ 0x3063, 0x1ef3,
+ 0x3083, 0x1ef4,
+ 0x3085, 0x1ef5,
+ 0x3087, 0x1ef6,
+ 0x308e, 0x1ef7,
+ 0x309b, 0x2050,
+ 0x309c, 0x204f,
+ 0x30a1, 0x1ef8,
+ 0x30a3, 0x1ef9,
+ 0x30a5, 0x1efa,
+ 0x30a7, 0x1efb,
+ 0x30a9, 0x1efc,
+ 0x30c3, 0x1efd,
+ 0x30e3, 0x1efe,
+ 0x30e5, 0x1eff,
+ 0x30e7, 0x1f00,
+ 0x30ee, 0x1f01,
+ 0x30f5, 0x1f02,
+ 0x30fc, 0x1ed3,
+ 0x3300, 0x209e,
+ 0x3303, 0x2092,
+ 0x3305, 0x208d,
+ 0x330d, 0x1f0e,
+ 0x3314, 0x1f05,
+ 0x3315, 0x2094,
+ 0x3316, 0x208a,
+ 0x3318, 0x2093,
+ 0x331e, 0x20a1,
+ 0x3322, 0x2089,
+ 0x3323, 0x209c,
+ 0x3326, 0x1f0f,
+ 0x3327, 0x1f09,
+ 0x332a, 0x20a4,
+ 0x332b, 0x1f11,
+ 0x3331, 0x20a6,
+ 0x3333, 0x208e,
+ 0x3336, 0x1f0b,
+ 0x3339, 0x2097,
+ 0x333b, 0x209d,
+ 0x3342, 0x209b,
+ 0x3347, 0x20a5,
+ 0x3349, 0x1f04,
+ 0x334a, 0x1f12,
+ 0x334d, 0x1f07,
+ 0x334e, 0x2091,
+ 0x3351, 0x1f0c,
+ 0x3357, 0x2098,
+ 0x337f, 0x2084,
+ 0xff08, 0x1edb,
+ 0xff0c, 0x204c,
+ 0xff0d, 0x1ed5,
+ 0xff0e, 0x2052,
+ 0xff1d, 0x1eed,
+ 0xff3b, 0x1edf,
+ 0xff3d, 0x1ee0,
+ 0xff3f, 0x1ed2,
+ 0xff5b, 0x1ee1,
+ 0xff5c, 0x1ed8,
+ 0xff5d, 0x1ee2,
+ 0xff5e, 0x1ed6,
+ 0xffe3, 0x1ed1,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12UniJISUCS2VEnc16 = {
+ 1,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12UniJISUCS2VMap2, 7108
+};
+
+static Gushort japan12VMap2[294] = {
+ 0x0000, 0x0000,
+ 0x2121, 0x0279,
+ 0x2221, 0x02d7,
+ 0x223a, 0x02e5,
+ 0x224a, 0x02ed,
+ 0x225c, 0x02f4,
+ 0x2272, 0x0303,
+ 0x227e, 0x030b,
+ 0x2330, 0x030c,
+ 0x2341, 0x0316,
+ 0x2361, 0x0330,
+ 0x2421, 0x034a,
+ 0x2521, 0x039d,
+ 0x2621, 0x03f3,
+ 0x2641, 0x040b,
+ 0x2721, 0x0423,
+ 0x2751, 0x0444,
+ 0x2821, 0x1d37,
+ 0x2822, 0x1d39,
+ 0x2823, 0x1d43,
+ 0x2824, 0x1d47,
+ 0x2825, 0x1d4f,
+ 0x2826, 0x1d4b,
+ 0x2827, 0x1d53,
+ 0x2828, 0x1d63,
+ 0x2829, 0x1d5b,
+ 0x282a, 0x1d6b,
+ 0x282b, 0x1d73,
+ 0x282c, 0x1d38,
+ 0x282d, 0x1d3a,
+ 0x282e, 0x1d46,
+ 0x282f, 0x1d4a,
+ 0x2830, 0x1d52,
+ 0x2831, 0x1d4e,
+ 0x2832, 0x1d5a,
+ 0x2833, 0x1d6a,
+ 0x2834, 0x1d62,
+ 0x2835, 0x1d72,
+ 0x2836, 0x1d82,
+ 0x2837, 0x1d57,
+ 0x2838, 0x1d66,
+ 0x2839, 0x1d5f,
+ 0x283a, 0x1d6e,
+ 0x283b, 0x1d76,
+ 0x283c, 0x1d54,
+ 0x283d, 0x1d67,
+ 0x283e, 0x1d5c,
+ 0x283f, 0x1d6f,
+ 0x2840, 0x1d79,
+ 0x3021, 0x0465,
+ 0x3121, 0x04c3,
+ 0x3221, 0x0521,
+ 0x3321, 0x057f,
+ 0x3421, 0x05dd,
+ 0x3521, 0x063b,
+ 0x3621, 0x0699,
+ 0x3721, 0x06f7,
+ 0x3821, 0x0755,
+ 0x3921, 0x07b3,
+ 0x3a21, 0x0811,
+ 0x3b21, 0x086f,
+ 0x3c21, 0x08cd,
+ 0x3d21, 0x092b,
+ 0x3e21, 0x0989,
+ 0x3f21, 0x09e7,
+ 0x4021, 0x0a45,
+ 0x4121, 0x0aa3,
+ 0x4221, 0x0b01,
+ 0x4321, 0x0b5f,
+ 0x4421, 0x0bbd,
+ 0x4521, 0x0c1b,
+ 0x4621, 0x0c79,
+ 0x4721, 0x0cd7,
+ 0x4821, 0x0d35,
+ 0x4921, 0x0d93,
+ 0x4a21, 0x0df1,
+ 0x4b21, 0x0e4f,
+ 0x4c21, 0x0ead,
+ 0x4d21, 0x0f0b,
+ 0x4e21, 0x0f69,
+ 0x4f21, 0x0fc7,
+ 0x5021, 0x0ffa,
+ 0x5121, 0x1058,
+ 0x5221, 0x10b6,
+ 0x5321, 0x1114,
+ 0x5421, 0x1172,
+ 0x5521, 0x11d0,
+ 0x5621, 0x122e,
+ 0x5721, 0x128c,
+ 0x5821, 0x12ea,
+ 0x5921, 0x1348,
+ 0x5a21, 0x13a6,
+ 0x5b21, 0x1404,
+ 0x5c21, 0x1462,
+ 0x5d21, 0x14c0,
+ 0x5e21, 0x151e,
+ 0x5f21, 0x157c,
+ 0x6021, 0x15da,
+ 0x6121, 0x1638,
+ 0x6221, 0x1696,
+ 0x6321, 0x16f4,
+ 0x6421, 0x1752,
+ 0x6521, 0x17b0,
+ 0x6621, 0x180e,
+ 0x6721, 0x186c,
+ 0x6821, 0x18ca,
+ 0x6921, 0x1928,
+ 0x6a21, 0x1986,
+ 0x6b21, 0x19e4,
+ 0x6c21, 0x1a42,
+ 0x6d21, 0x1aa0,
+ 0x6e21, 0x1afe,
+ 0x6f21, 0x1b5c,
+ 0x7021, 0x1bba,
+ 0x7121, 0x1c18,
+ 0x7221, 0x1c76,
+ 0x7321, 0x1cd4,
+ 0x7421, 0x1d32,
+ 0x7425, 0x205c,
+ 0x2122, 0x1ecf,
+ 0x2131, 0x1ed1,
+ 0x213c, 0x1ed3,
+ 0x2141, 0x1ed6,
+ 0x214a, 0x1edb,
+ 0x2161, 0x1eed,
+ 0x2421, 0x1eee,
+ 0x2423, 0x1eef,
+ 0x2425, 0x1ef0,
+ 0x2427, 0x1ef1,
+ 0x2429, 0x1ef2,
+ 0x2443, 0x1ef3,
+ 0x2463, 0x1ef4,
+ 0x2465, 0x1ef5,
+ 0x2467, 0x1ef6,
+ 0x246e, 0x1ef7,
+ 0x2521, 0x1ef8,
+ 0x2523, 0x1ef9,
+ 0x2525, 0x1efa,
+ 0x2527, 0x1efb,
+ 0x2529, 0x1efc,
+ 0x2543, 0x1efd,
+ 0x2563, 0x1efe,
+ 0x2565, 0x1eff,
+ 0x2567, 0x1f00,
+ 0x256e, 0x1f01,
+ 0x2575, 0x1f02,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12VEnc16 = {
+ 1,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12VMap2, 147
+};
+
+static Gushort japan12WPSymbolMap2[4] = {
+ 0x0000, 0x0000,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12WPSymbolEnc16 = {
+ 0,
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x1f78, 0x1f7a, 0x1fff, 0x2004, 0x1f7d, 0x1f7e, 0x1f7f,
+ 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87,
+ 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f,
+ 0x1f90, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa0, 0x1fa1, 0x1fa2,
+ 0x1fa3, 0x1fa4, 0x1fa5, 0x1ffa, 0x1f54, 0x1f55, 0x1ffb, 0x1f56,
+ 0x1f57, 0x1ffc, 0x1f65, 0x1f58, 0x1f59, 0x1f5a, 0x1ffd, 0x1ffe,
+ 0x2000, 0x2001, 0x1edb, 0x1edc, 0x1ed6, 0x2002, 0x1f63, 0x1f5b,
+ 0x1f5c, 0x1f5d, 0x2003, 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4,
+ 0x1fb5, 0x1fb6, 0x1fb7, 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc,
+ 0x1fbd, 0x1fbe, 0x1fbf, 0x1fc0, 0x1fc1, 0x1fc2, 0x1fc3, 0x1fc4,
+ 0x1fc5, 0x1fc6, 0x1fc7, 0x1fc8, 0x1fc9, 0x2005, 0x2006, 0x2007,
+ 0x2008, 0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x1fd7, 0x0000,
+ 0x0000, 0x200e, 0x200f, 0x2010, 0x2011, 0x2012, 0x2013, 0x2014,
+ 0x2015, 0x2016, 0x2017, 0x2018, 0x2019, 0x201a, 0x201b, 0x201c,
+ 0x201d, 0x201e, 0x1f79, 0x201f, 0x2020, 0x2021, 0x2022, 0x2023,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12WPSymbolMap2, 2
+};
+
+static Gushort japan12AdobeJapan12VMap2[74] = {
+ 0x0000, 0x0000,
+ 0x0000, 0x0000,
+ 0x0100, 0x0100,
+ 0x0200, 0x0200,
+ 0x0300, 0x0300,
+ 0x0400, 0x0400,
+ 0x0500, 0x0500,
+ 0x0600, 0x0600,
+ 0x0700, 0x0700,
+ 0x0800, 0x0800,
+ 0x0900, 0x0900,
+ 0x0a00, 0x0a00,
+ 0x0b00, 0x0b00,
+ 0x0c00, 0x0c00,
+ 0x0d00, 0x0d00,
+ 0x0e00, 0x0e00,
+ 0x0f00, 0x0f00,
+ 0x1000, 0x1000,
+ 0x1100, 0x1100,
+ 0x1200, 0x1200,
+ 0x1300, 0x1300,
+ 0x1400, 0x1400,
+ 0x1500, 0x1500,
+ 0x1600, 0x1600,
+ 0x1700, 0x1700,
+ 0x1800, 0x1800,
+ 0x1900, 0x1900,
+ 0x1a00, 0x1a00,
+ 0x1b00, 0x1b00,
+ 0x1c00, 0x1c00,
+ 0x1d00, 0x1d00,
+ 0x1e00, 0x1e00,
+ 0x1f00, 0x1f00,
+ 0x2000, 0x2000,
+ 0x2100, 0x2100,
+ 0x2200, 0x2200,
+ 0xffff, 0x0000
+};
+
+static GfxFontEncoding16 japan12AdobeJapan12VEnc16 = {
+ 1,
+ { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+ japan12AdobeJapan12VMap2, 37
+};
+
+static struct {
+ char *name;
+ GfxFontEncoding16 *enc;
+} gfxJapan12Tab[] = {
+ { "78-EUC-H", &japan1278EUCHEnc16 },
+ { "78-EUC-V", &japan1278EUCVEnc16 },
+ { "78-H", &japan1278HEnc16 },
+ { "78-RKSJ-H", &japan1278RKSJHEnc16 },
+ { "78-RKSJ-V", &japan1278RKSJVEnc16 },
+ { "78-V", &japan1278VEnc16 },
+ { "78ms-RKSJ-H", &japan1278msRKSJHEnc16 },
+ { "78ms-RKSJ-V", &japan1278msRKSJVEnc16 },
+ { "83pv-RKSJ-H", &japan1283pvRKSJHEnc16 },
+ { "90ms-RKSJ-H", &japan1290msRKSJHEnc16 },
+ { "90ms-RKSJ-V", &japan1290msRKSJVEnc16 },
+ { "90msp-RKSJ-H", &japan1290mspRKSJHEnc16 },
+ { "90msp-RKSJ-V", &japan1290mspRKSJVEnc16 },
+ { "90pv-RKSJ-H", &japan1290pvRKSJHEnc16 },
+ { "90pv-RKSJ-V", &japan1290pvRKSJVEnc16 },
+ { "Add-H", &japan12AddHEnc16 },
+ { "Add-RKSJ-H", &japan12AddRKSJHEnc16 },
+ { "Add-RKSJ-V", &japan12AddRKSJVEnc16 },
+ { "Add-V", &japan12AddVEnc16 },
+ { "Adobe-Japan1-0", &japan12AdobeJapan10Enc16 },
+ { "Adobe-Japan1-1", &japan12AdobeJapan11Enc16 },
+ { "Adobe-Japan1-2", &japan12AdobeJapan12Enc16 },
+ { "EUC-H", &japan12EUCHEnc16 },
+ { "EUC-V", &japan12EUCVEnc16 },
+ { "Ext-H", &japan12ExtHEnc16 },
+ { "Ext-RKSJ-H", &japan12ExtRKSJHEnc16 },
+ { "Ext-RKSJ-V", &japan12ExtRKSJVEnc16 },
+ { "Ext-V", &japan12ExtVEnc16 },
+ { "H", &japan12HEnc16 },
+ { "Hankaku", &japan12HankakuEnc16 },
+ { "Hiragana", &japan12HiraganaEnc16 },
+ { "Katakana", &japan12KatakanaEnc16 },
+ { "NWP-H", &japan12NWPHEnc16 },
+ { "NWP-V", &japan12NWPVEnc16 },
+ { "RKSJ-H", &japan12RKSJHEnc16 },
+ { "RKSJ-V", &japan12RKSJVEnc16 },
+ { "Roman", &japan12RomanEnc16 },
+ { "UniJIS-UCS2-H", &japan12UniJISUCS2HEnc16 },
+ { "UniJIS-UCS2-V", &japan12UniJISUCS2VEnc16 },
+ { "V", &japan12VEnc16 },
+ { "WP-Symbol", &japan12WPSymbolEnc16 },
+ { "Identity-H", &japan12AdobeJapan12Enc16 },
+ { "Identity-V", &japan12AdobeJapan12VEnc16 },
+ { NULL, NULL }
+};
+
+#endif
diff --git a/pdftops/Japan12ToRKSJ.h b/pdftops/Japan12ToRKSJ.h
new file mode 100644
index 000000000..5ca62c30c
--- /dev/null
+++ b/pdftops/Japan12ToRKSJ.h
@@ -0,0 +1,1038 @@
+static Gushort japan12ToRKSJ[8286] = {
+ 0x0020, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026,
+ 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e,
+ 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036,
+ 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
+ 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046,
+ 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e,
+ 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056,
+ 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e,
+ 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066,
+ 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e,
+ 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076,
+ 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028,
+ 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030,
+ 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038,
+ 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060,
+ 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068,
+ 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070,
+ 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
+ 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x00a0, 0x00a1,
+ 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9,
+ 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1,
+ 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9,
+ 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1,
+ 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9,
+ 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1,
+ 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9,
+ 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x8140, 0x8141, 0x8142, 0x8143, 0x8144, 0x8145, 0x8146,
+ 0x8147, 0x8148, 0x8149, 0x814a, 0x814b, 0x814c, 0x814d, 0x814e,
+ 0x814f, 0x8150, 0x8151, 0x8152, 0x8153, 0x8154, 0x8155, 0x8156,
+ 0x8157, 0x8158, 0x8159, 0x815a, 0x815b, 0x815c, 0x815d, 0x815e,
+ 0x815f, 0x8160, 0x8161, 0x8162, 0x8163, 0x8164, 0x8165, 0x8166,
+ 0x8167, 0x8168, 0x8169, 0x816a, 0x816b, 0x816c, 0x816d, 0x816e,
+ 0x816f, 0x8170, 0x8171, 0x8172, 0x8173, 0x8174, 0x8175, 0x8176,
+ 0x8177, 0x8178, 0x8179, 0x817a, 0x817b, 0x817c, 0x817d, 0x817e,
+ 0x8180, 0x8181, 0x8182, 0x8183, 0x8184, 0x8185, 0x8186, 0x8187,
+ 0x8188, 0x8189, 0x818a, 0x818b, 0x818c, 0x818d, 0x818e, 0x818f,
+ 0x8190, 0x8191, 0x8192, 0x8193, 0x8194, 0x8195, 0x8196, 0x8197,
+ 0x8198, 0x8199, 0x819a, 0x819b, 0x819c, 0x819d, 0x819e, 0x819f,
+ 0x81a0, 0x81a1, 0x81a2, 0x81a3, 0x81a4, 0x81a5, 0x81a6, 0x81a7,
+ 0x81a8, 0x81a9, 0x81aa, 0x81ab, 0x81ac, 0x81b8, 0x81b9, 0x81ba,
+ 0x81bb, 0x81bc, 0x81bd, 0x81be, 0x81bf, 0x81c8, 0x81c9, 0x81ca,
+ 0x81cb, 0x81cc, 0x81cd, 0x81ce, 0x81da, 0x81db, 0x81dc, 0x81dd,
+ 0x81de, 0x81df, 0x81e0, 0x81e1, 0x81e2, 0x81e3, 0x81e4, 0x81e5,
+ 0x81e6, 0x81e7, 0x81e8, 0x81f0, 0x81f1, 0x81f2, 0x81f3, 0x81f4,
+ 0x81f5, 0x81f6, 0x81f7, 0x81fc, 0x824f, 0x8250, 0x8251, 0x8252,
+ 0x8253, 0x8254, 0x8255, 0x8256, 0x8257, 0x8258, 0x8260, 0x8261,
+ 0x8262, 0x8263, 0x8264, 0x8265, 0x8266, 0x8267, 0x8268, 0x8269,
+ 0x826a, 0x826b, 0x826c, 0x826d, 0x826e, 0x826f, 0x8270, 0x8271,
+ 0x8272, 0x8273, 0x8274, 0x8275, 0x8276, 0x8277, 0x8278, 0x8279,
+ 0x8281, 0x8282, 0x8283, 0x8284, 0x8285, 0x8286, 0x8287, 0x8288,
+ 0x8289, 0x828a, 0x828b, 0x828c, 0x828d, 0x828e, 0x828f, 0x8290,
+ 0x8291, 0x8292, 0x8293, 0x8294, 0x8295, 0x8296, 0x8297, 0x8298,
+ 0x8299, 0x829a, 0x829f, 0x82a0, 0x82a1, 0x82a2, 0x82a3, 0x82a4,
+ 0x82a5, 0x82a6, 0x82a7, 0x82a8, 0x82a9, 0x82aa, 0x82ab, 0x82ac,
+ 0x82ad, 0x82ae, 0x82af, 0x82b0, 0x82b1, 0x82b2, 0x82b3, 0x82b4,
+ 0x82b5, 0x82b6, 0x82b7, 0x82b8, 0x82b9, 0x82ba, 0x82bb, 0x82bc,
+ 0x82bd, 0x82be, 0x82bf, 0x82c0, 0x82c1, 0x82c2, 0x82c3, 0x82c4,
+ 0x82c5, 0x82c6, 0x82c7, 0x82c8, 0x82c9, 0x82ca, 0x82cb, 0x82cc,
+ 0x82cd, 0x82ce, 0x82cf, 0x82d0, 0x82d1, 0x82d2, 0x82d3, 0x82d4,
+ 0x82d5, 0x82d6, 0x82d7, 0x82d8, 0x82d9, 0x82da, 0x82db, 0x82dc,
+ 0x82dd, 0x82de, 0x82df, 0x82e0, 0x82e1, 0x82e2, 0x82e3, 0x82e4,
+ 0x82e5, 0x82e6, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82eb, 0x82ec,
+ 0x82ed, 0x82ee, 0x82ef, 0x82f0, 0x82f1, 0x8340, 0x8341, 0x8342,
+ 0x8343, 0x8344, 0x8345, 0x8346, 0x8347, 0x8348, 0x8349, 0x834a,
+ 0x834b, 0x834c, 0x834d, 0x834e, 0x834f, 0x8350, 0x8351, 0x8352,
+ 0x8353, 0x8354, 0x8355, 0x8356, 0x8357, 0x8358, 0x8359, 0x835a,
+ 0x835b, 0x835c, 0x835d, 0x835e, 0x835f, 0x8360, 0x8361, 0x8362,
+ 0x8363, 0x8364, 0x8365, 0x8366, 0x8367, 0x8368, 0x8369, 0x836a,
+ 0x836b, 0x836c, 0x836d, 0x836e, 0x836f, 0x8370, 0x8371, 0x8372,
+ 0x8373, 0x8374, 0x8375, 0x8376, 0x8377, 0x8378, 0x8379, 0x837a,
+ 0x837b, 0x837c, 0x837d, 0x837e, 0x8380, 0x8381, 0x8382, 0x8383,
+ 0x8384, 0x8385, 0x8386, 0x8387, 0x8388, 0x8389, 0x838a, 0x838b,
+ 0x838c, 0x838d, 0x838e, 0x838f, 0x8390, 0x8391, 0x8392, 0x8393,
+ 0x8394, 0x8395, 0x8396, 0x839f, 0x83a0, 0x83a1, 0x83a2, 0x83a3,
+ 0x83a4, 0x83a5, 0x83a6, 0x83a7, 0x83a8, 0x83a9, 0x83aa, 0x83ab,
+ 0x83ac, 0x83ad, 0x83ae, 0x83af, 0x83b0, 0x83b1, 0x83b2, 0x83b3,
+ 0x83b4, 0x83b5, 0x83b6, 0x83bf, 0x83c0, 0x83c1, 0x83c2, 0x83c3,
+ 0x83c4, 0x83c5, 0x83c6, 0x83c7, 0x83c8, 0x83c9, 0x83ca, 0x83cb,
+ 0x83cc, 0x83cd, 0x83ce, 0x83cf, 0x83d0, 0x83d1, 0x83d2, 0x83d3,
+ 0x83d4, 0x83d5, 0x83d6, 0x8440, 0x8441, 0x8442, 0x8443, 0x8444,
+ 0x8445, 0x8446, 0x8447, 0x8448, 0x8449, 0x844a, 0x844b, 0x844c,
+ 0x844d, 0x844e, 0x844f, 0x8450, 0x8451, 0x8452, 0x8453, 0x8454,
+ 0x8455, 0x8456, 0x8457, 0x8458, 0x8459, 0x845a, 0x845b, 0x845c,
+ 0x845d, 0x845e, 0x845f, 0x8460, 0x8470, 0x8471, 0x8472, 0x8473,
+ 0x8474, 0x8475, 0x8476, 0x8477, 0x8478, 0x8479, 0x847a, 0x847b,
+ 0x847c, 0x847d, 0x847e, 0x8480, 0x8481, 0x8482, 0x8483, 0x8484,
+ 0x8485, 0x8486, 0x8487, 0x8488, 0x8489, 0x848a, 0x848b, 0x848c,
+ 0x848d, 0x848e, 0x848f, 0x8490, 0x8491, 0x889f, 0x88a0, 0x88a1,
+ 0x88a2, 0x88a3, 0x88a4, 0x88a5, 0x88a6, 0x88a7, 0x88a8, 0x88a9,
+ 0x88aa, 0x88ab, 0x88ac, 0x88ad, 0x88ae, 0x88af, 0x88b0, 0x88b1,
+ 0x88b2, 0x88b3, 0x88b4, 0x88b5, 0x88b6, 0x88b7, 0x88b8, 0x88b9,
+ 0x88ba, 0x88bb, 0x88bc, 0x88bd, 0x88be, 0x88bf, 0x88c0, 0x88c1,
+ 0x88c2, 0x88c3, 0x88c4, 0x88c5, 0x88c6, 0x88c7, 0x88c8, 0x88c9,
+ 0x88ca, 0x88cb, 0x88cc, 0x88cd, 0x88ce, 0x88cf, 0x88d0, 0x88d1,
+ 0x88d2, 0x88d3, 0x88d4, 0x88d5, 0x88d6, 0x88d7, 0x88d8, 0x88d9,
+ 0x88da, 0x88db, 0x88dc, 0x88dd, 0x88de, 0x88df, 0x88e0, 0x88e1,
+ 0x88e2, 0x88e3, 0x88e4, 0x88e5, 0x88e6, 0x88e7, 0x88e8, 0x88e9,
+ 0x88ea, 0x88eb, 0x88ec, 0x88ed, 0x88ee, 0x88ef, 0x88f0, 0x88f1,
+ 0x88f2, 0x88f3, 0x88f4, 0x88f5, 0x88f6, 0x88f7, 0x88f8, 0x88f9,
+ 0x88fa, 0x88fb, 0x88fc, 0x8940, 0x8941, 0x8942, 0x8943, 0x8944,
+ 0x8945, 0x8946, 0x8947, 0x8948, 0x8949, 0x894a, 0x894b, 0x894c,
+ 0x894d, 0x894e, 0x894f, 0x8950, 0x8951, 0x8952, 0x8953, 0x8954,
+ 0x8955, 0x8956, 0x8957, 0x8958, 0x8959, 0x895a, 0x895b, 0x895c,
+ 0x895d, 0x895e, 0x895f, 0x8960, 0x8961, 0x8962, 0x8963, 0x8964,
+ 0x8965, 0x8966, 0x8967, 0x8968, 0x8969, 0x896a, 0x896b, 0x896c,
+ 0x896d, 0x896e, 0x896f, 0x8970, 0x8971, 0x8972, 0x8973, 0x8974,
+ 0x8975, 0x8976, 0x8977, 0x8978, 0x8979, 0x897a, 0x897b, 0x897c,
+ 0x897d, 0x897e, 0x8980, 0x8981, 0x8982, 0x8983, 0x8984, 0x8985,
+ 0x8986, 0x8987, 0x8988, 0x8989, 0x898a, 0x898b, 0x898c, 0x898d,
+ 0x898e, 0x898f, 0x8990, 0x8991, 0x8992, 0x8993, 0x8994, 0x8995,
+ 0x8996, 0x8997, 0x8998, 0x8999, 0x899a, 0x899b, 0x899c, 0x899d,
+ 0x899e, 0x899f, 0x89a0, 0x89a1, 0x89a2, 0x89a3, 0x89a4, 0x89a5,
+ 0x89a6, 0x89a7, 0x89a8, 0x89a9, 0x89aa, 0x89ab, 0x89ac, 0x89ad,
+ 0x89ae, 0x89af, 0x89b0, 0x89b1, 0x89b2, 0x89b3, 0x89b4, 0x89b5,
+ 0x89b6, 0x89b7, 0x89b8, 0x89b9, 0x89ba, 0x89bb, 0x89bc, 0x89bd,
+ 0x89be, 0x89bf, 0x89c0, 0x89c1, 0x89c2, 0x89c3, 0x89c4, 0x89c5,
+ 0x89c6, 0x89c7, 0x89c8, 0x89c9, 0x89ca, 0x89cb, 0x89cc, 0x89cd,
+ 0x89ce, 0x89cf, 0x89d0, 0x89d1, 0x89d2, 0x89d3, 0x89d4, 0x89d5,
+ 0x89d6, 0x89d7, 0x89d8, 0x89d9, 0x89da, 0x89db, 0x89dc, 0x89dd,
+ 0x89de, 0x89df, 0x89e0, 0x89e1, 0x89e2, 0x89e3, 0x89e4, 0x89e5,
+ 0x89e6, 0x89e7, 0x89e8, 0x89e9, 0x89ea, 0x89eb, 0x89ec, 0x89ed,
+ 0x89ee, 0x89ef, 0x89f0, 0x89f1, 0x89f2, 0x89f3, 0x89f4, 0x89f5,
+ 0x89f6, 0x89f7, 0x89f8, 0x89f9, 0x89fa, 0x89fb, 0x89fc, 0x8a40,
+ 0x8a41, 0x8a42, 0x8a43, 0x8a44, 0x8a45, 0x8a46, 0x8a47, 0x8a48,
+ 0x8a49, 0x8a4a, 0x8a4b, 0x8a4c, 0x8a4d, 0x8a4e, 0x8a4f, 0x8a50,
+ 0x8a51, 0x8a52, 0x8a53, 0x8a54, 0x8a55, 0x8a56, 0x8a57, 0x8a58,
+ 0x8a59, 0x8a5a, 0x8a5b, 0x8a5c, 0x8a5d, 0x8a5e, 0x8a5f, 0x8a60,
+ 0x8a61, 0x8a62, 0x8a63, 0x8a64, 0x8a65, 0x8a66, 0x8a67, 0x8a68,
+ 0x8a69, 0x8a6a, 0x8a6b, 0x8a6c, 0x8a6d, 0x8a6e, 0x8a6f, 0x8a70,
+ 0x8a71, 0x8a72, 0x8a73, 0x8a74, 0x8a75, 0x8a76, 0x8a77, 0x8a78,
+ 0x8a79, 0x8a7a, 0x8a7b, 0x8a7c, 0x8a7d, 0x8a7e, 0x8a80, 0x8a81,
+ 0x8a82, 0x8a83, 0x8a84, 0x8a85, 0x8a86, 0x8a87, 0x8a88, 0x8a89,
+ 0x8a8a, 0x8a8b, 0x8a8c, 0x8a8d, 0x8a8e, 0x8a8f, 0x8a90, 0x8a91,
+ 0x8a92, 0x8a93, 0x8a94, 0x8a95, 0x8a96, 0x8a97, 0x8a98, 0x8a99,
+ 0x8a9a, 0x8a9b, 0x8a9c, 0x8a9d, 0x8a9e, 0x8a9f, 0x8aa0, 0x8aa1,
+ 0x8aa2, 0x8aa3, 0x8aa4, 0x8aa5, 0x8aa6, 0x8aa7, 0x8aa8, 0x8aa9,
+ 0x8aaa, 0x8aab, 0x8aac, 0x8aad, 0x8aae, 0x8aaf, 0x8ab0, 0x8ab1,
+ 0x8ab2, 0x8ab3, 0x8ab4, 0x8ab5, 0x8ab6, 0x8ab7, 0x8ab8, 0x8ab9,
+ 0x8aba, 0x8abb, 0x8abc, 0x8abd, 0x8abe, 0x8abf, 0x8ac0, 0x8ac1,
+ 0x8ac2, 0x8ac3, 0x8ac4, 0x8ac5, 0x8ac6, 0x8ac7, 0x8ac8, 0x8ac9,
+ 0x8aca, 0x8acb, 0x8acc, 0x8acd, 0x8ace, 0x8acf, 0x8ad0, 0x8ad1,
+ 0x8ad2, 0x8ad3, 0x8ad4, 0x8ad5, 0x8ad6, 0x8ad7, 0x8ad8, 0x8ad9,
+ 0x8ada, 0x8adb, 0x8adc, 0x8add, 0x8ade, 0x8adf, 0x8ae0, 0x8ae1,
+ 0x8ae2, 0x8ae3, 0x8ae4, 0x8ae5, 0x8ae6, 0x8ae7, 0x8ae8, 0x8ae9,
+ 0x8aea, 0x8aeb, 0x8aec, 0x8aed, 0x8aee, 0x8aef, 0x8af0, 0x8af1,
+ 0x8af2, 0x8af3, 0x8af4, 0x8af5, 0x8af6, 0x8af7, 0x8af8, 0x8af9,
+ 0x8afa, 0x8afb, 0x8afc, 0x8b40, 0x8b41, 0x8b42, 0x8b43, 0x8b44,
+ 0x8b45, 0x8b46, 0x8b47, 0x8b48, 0x8b49, 0x8b4a, 0x8b4b, 0x8b4c,
+ 0x8b4d, 0x8b4e, 0x8b4f, 0x8b50, 0x8b51, 0x8b52, 0x8b53, 0x8b54,
+ 0x8b55, 0x8b56, 0x8b57, 0x8b58, 0x8b59, 0x8b5a, 0x8b5b, 0x8b5c,
+ 0x8b5d, 0x8b5e, 0x8b5f, 0x8b60, 0x8b61, 0x8b62, 0x8b63, 0x8b64,
+ 0x8b65, 0x8b66, 0x8b67, 0x8b68, 0x8b69, 0x8b6a, 0x8b6b, 0x8b6c,
+ 0x8b6d, 0x8b6e, 0x8b6f, 0x8b70, 0x8b71, 0x8b72, 0x8b73, 0x8b74,
+ 0x8b75, 0x8b76, 0x8b77, 0x8b78, 0x8b79, 0x8b7a, 0x8b7b, 0x8b7c,
+ 0x8b7d, 0x8b7e, 0x8b80, 0x8b81, 0x8b82, 0x8b83, 0x8b84, 0x8b85,
+ 0x8b86, 0x8b87, 0x8b88, 0x8b89, 0x8b8a, 0x8b8b, 0x8b8c, 0x8b8d,
+ 0x8b8e, 0x8b8f, 0x8b90, 0x8b91, 0x8b92, 0x8b93, 0x8b94, 0x8b95,
+ 0x8b96, 0x8b97, 0x8b98, 0x8b99, 0x8b9a, 0x8b9b, 0x8b9c, 0x8b9d,
+ 0x8b9e, 0x8b9f, 0x8ba0, 0x8ba1, 0x8ba2, 0x8ba3, 0x8ba4, 0x8ba5,
+ 0x8ba6, 0x8ba7, 0x8ba8, 0x8ba9, 0x8baa, 0x8bab, 0x8bac, 0x8bad,
+ 0x8bae, 0x8baf, 0x8bb0, 0x8bb1, 0x8bb2, 0x8bb3, 0x8bb4, 0x8bb5,
+ 0x8bb6, 0x8bb7, 0x8bb8, 0x8bb9, 0x8bba, 0x8bbb, 0x8bbc, 0x8bbd,
+ 0x8bbe, 0x8bbf, 0x8bc0, 0x8bc1, 0x8bc2, 0x8bc3, 0x8bc4, 0x8bc5,
+ 0x8bc6, 0x8bc7, 0x8bc8, 0x8bc9, 0x8bca, 0x8bcb, 0x8bcc, 0x8bcd,
+ 0x8bce, 0x8bcf, 0x8bd0, 0x8bd1, 0x8bd2, 0x8bd3, 0x8bd4, 0x8bd5,
+ 0x8bd6, 0x8bd7, 0x8bd8, 0x8bd9, 0x8bda, 0x8bdb, 0x8bdc, 0x8bdd,
+ 0x8bde, 0x8bdf, 0x8be0, 0x8be1, 0x8be2, 0x8be3, 0x8be4, 0x8be5,
+ 0x8be6, 0x8be7, 0x8be8, 0x8be9, 0x8bea, 0x8beb, 0x8bec, 0x8bed,
+ 0x8bee, 0x8bef, 0x8bf0, 0x8bf1, 0x8bf2, 0x8bf3, 0x8bf4, 0x8bf5,
+ 0x8bf6, 0x8bf7, 0x8bf8, 0x8bf9, 0x8bfa, 0x8bfb, 0x8bfc, 0x8c40,
+ 0x8c41, 0x8c42, 0x8c43, 0x8c44, 0x8c45, 0x8c46, 0x8c47, 0x8c48,
+ 0x8c49, 0x8c4a, 0x8c4b, 0x8c4c, 0x8c4d, 0x8c4e, 0x8c4f, 0x8c50,
+ 0x8c51, 0x8c52, 0x8c53, 0x8c54, 0x8c55, 0x8c56, 0x8c57, 0x8c58,
+ 0x8c59, 0x8c5a, 0x8c5b, 0x8c5c, 0x8c5d, 0x8c5e, 0x8c5f, 0x8c60,
+ 0x8c61, 0x8c62, 0x8c63, 0x8c64, 0x8c65, 0x8c66, 0x8c67, 0x8c68,
+ 0x8c69, 0x8c6a, 0x8c6b, 0x8c6c, 0x8c6d, 0x8c6e, 0x8c6f, 0x8c70,
+ 0x8c71, 0x8c72, 0x8c73, 0x8c74, 0x8c75, 0x8c76, 0x8c77, 0x8c78,
+ 0x8c79, 0x8c7a, 0x8c7b, 0x8c7c, 0x8c7d, 0x8c7e, 0x8c80, 0x8c81,
+ 0x8c82, 0x8c83, 0x8c84, 0x8c85, 0x8c86, 0x8c87, 0x8c88, 0x8c89,
+ 0x8c8a, 0x8c8b, 0x8c8c, 0x8c8d, 0x8c8e, 0x8c8f, 0x8c90, 0x8c91,
+ 0x8c92, 0x8c93, 0x8c94, 0x8c95, 0x8c96, 0x8c97, 0x8c98, 0x8c99,
+ 0x8c9a, 0x8c9b, 0x8c9c, 0x8c9d, 0x8c9e, 0x8c9f, 0x8ca0, 0x8ca1,
+ 0x8ca2, 0x8ca3, 0x8ca4, 0x8ca5, 0x8ca6, 0x8ca7, 0x8ca8, 0x8ca9,
+ 0x8caa, 0x8cab, 0x8cac, 0x8cad, 0x8cae, 0x8caf, 0x8cb0, 0x8cb1,
+ 0x8cb2, 0x8cb3, 0x8cb4, 0x8cb5, 0x8cb6, 0x8cb7, 0x8cb8, 0x8cb9,
+ 0x8cba, 0x8cbb, 0x8cbc, 0x8cbd, 0x8cbe, 0x8cbf, 0x8cc0, 0x8cc1,
+ 0x8cc2, 0x8cc3, 0x8cc4, 0x8cc5, 0x8cc6, 0x8cc7, 0x8cc8, 0x8cc9,
+ 0x8cca, 0x8ccb, 0x8ccc, 0x8ccd, 0x8cce, 0x8ccf, 0x8cd0, 0x8cd1,
+ 0x8cd2, 0x8cd3, 0x8cd4, 0x8cd5, 0x8cd6, 0x8cd7, 0x8cd8, 0x8cd9,
+ 0x8cda, 0x8cdb, 0x8cdc, 0x8cdd, 0x8cde, 0x8cdf, 0x8ce0, 0x8ce1,
+ 0x8ce2, 0x8ce3, 0x8ce4, 0x8ce5, 0x8ce6, 0x8ce7, 0x8ce8, 0x8ce9,
+ 0x8cea, 0x8ceb, 0x8cec, 0x8ced, 0x8cee, 0x8cef, 0x8cf0, 0x8cf1,
+ 0x8cf2, 0x8cf3, 0x8cf4, 0x8cf5, 0x8cf6, 0x8cf7, 0x8cf8, 0x8cf9,
+ 0x8cfa, 0x8cfb, 0x8cfc, 0x8d40, 0x8d41, 0x8d42, 0x8d43, 0x8d44,
+ 0x8d45, 0x8d46, 0x8d47, 0x8d48, 0x8d49, 0x8d4a, 0x8d4b, 0x8d4c,
+ 0x8d4d, 0x8d4e, 0x8d4f, 0x8d50, 0x8d51, 0x8d52, 0x8d53, 0x8d54,
+ 0x8d55, 0x8d56, 0x8d57, 0x8d58, 0x8d59, 0x8d5a, 0x8d5b, 0x8d5c,
+ 0x8d5d, 0x8d5e, 0x8d5f, 0x8d60, 0x8d61, 0x8d62, 0x8d63, 0x8d64,
+ 0x8d65, 0x8d66, 0x8d67, 0x8d68, 0x8d69, 0x8d6a, 0x8d6b, 0x8d6c,
+ 0x8d6d, 0x8d6e, 0x8d6f, 0x8d70, 0x8d71, 0x8d72, 0x8d73, 0x8d74,
+ 0x8d75, 0x8d76, 0x8d77, 0x8d78, 0x8d79, 0x8d7a, 0x8d7b, 0x8d7c,
+ 0x8d7d, 0x8d7e, 0x8d80, 0x8d81, 0x8d82, 0x8d83, 0x8d84, 0x8d85,
+ 0x8d86, 0x8d87, 0x8d88, 0x8d89, 0x8d8a, 0x8d8b, 0x8d8c, 0x8d8d,
+ 0x8d8e, 0x8d8f, 0x8d90, 0x8d91, 0x8d92, 0x8d93, 0x8d94, 0x8d95,
+ 0x8d96, 0x8d97, 0x8d98, 0x8d99, 0x8d9a, 0x8d9b, 0x8d9c, 0x8d9d,
+ 0x8d9e, 0x8d9f, 0x8da0, 0x8da1, 0x8da2, 0x8da3, 0x8da4, 0x8da5,
+ 0x8da6, 0x8da7, 0x8da8, 0x8da9, 0x8daa, 0x8dab, 0x8dac, 0x8dad,
+ 0x8dae, 0x8daf, 0x8db0, 0x8db1, 0x8db2, 0x8db3, 0x8db4, 0x8db5,
+ 0x8db6, 0x8db7, 0x8db8, 0x8db9, 0x8dba, 0x8dbb, 0x8dbc, 0x8dbd,
+ 0x8dbe, 0x8dbf, 0x8dc0, 0x8dc1, 0x8dc2, 0x8dc3, 0x8dc4, 0x8dc5,
+ 0x8dc6, 0x8dc7, 0x8dc8, 0x8dc9, 0x8dca, 0x8dcb, 0x8dcc, 0x8dcd,
+ 0x8dce, 0x8dcf, 0x8dd0, 0x8dd1, 0x8dd2, 0x8dd3, 0x8dd4, 0x8dd5,
+ 0x8dd6, 0x8dd7, 0x8dd8, 0x8dd9, 0x8dda, 0x8ddb, 0x8ddc, 0x8ddd,
+ 0x8dde, 0x8ddf, 0x8de0, 0x8de1, 0x8de2, 0x8de3, 0x8de4, 0x8de5,
+ 0x8de6, 0x8de7, 0x8de8, 0x8de9, 0x8dea, 0x8deb, 0x8dec, 0x8ded,
+ 0x8dee, 0x8def, 0x8df0, 0x8df1, 0x8df2, 0x8df3, 0x8df4, 0x8df5,
+ 0x8df6, 0x8df7, 0x8df8, 0x8df9, 0x8dfa, 0x8dfb, 0x8dfc, 0x8e40,
+ 0x8e41, 0x8e42, 0x8e43, 0x8e44, 0x8e45, 0x8e46, 0x8e47, 0x8e48,
+ 0x8e49, 0x8e4a, 0x8e4b, 0x8e4c, 0x8e4d, 0x8e4e, 0x8e4f, 0x8e50,
+ 0x8e51, 0x8e52, 0x8e53, 0x8e54, 0x8e55, 0x8e56, 0x8e57, 0x8e58,
+ 0x8e59, 0x8e5a, 0x8e5b, 0x8e5c, 0x8e5d, 0x8e5e, 0x8e5f, 0x8e60,
+ 0x8e61, 0x8e62, 0x8e63, 0x8e64, 0x8e65, 0x8e66, 0x8e67, 0x8e68,
+ 0x8e69, 0x8e6a, 0x8e6b, 0x8e6c, 0x8e6d, 0x8e6e, 0x8e6f, 0x8e70,
+ 0x8e71, 0x8e72, 0x8e73, 0x8e74, 0x8e75, 0x8e76, 0x8e77, 0x8e78,
+ 0x8e79, 0x8e7a, 0x8e7b, 0x8e7c, 0x8e7d, 0x8e7e, 0x8e80, 0x8e81,
+ 0x8e82, 0x8e83, 0x8e84, 0x8e85, 0x8e86, 0x8e87, 0x8e88, 0x8e89,
+ 0x8e8a, 0x8e8b, 0x8e8c, 0x8e8d, 0x8e8e, 0x8e8f, 0x8e90, 0x8e91,
+ 0x8e92, 0x8e93, 0x8e94, 0x8e95, 0x8e96, 0x8e97, 0x8e98, 0x8e99,
+ 0x8e9a, 0x8e9b, 0x8e9c, 0x8e9d, 0x8e9e, 0x8e9f, 0x8ea0, 0x8ea1,
+ 0x8ea2, 0x8ea3, 0x8ea4, 0x8ea5, 0x8ea6, 0x8ea7, 0x8ea8, 0x8ea9,
+ 0x8eaa, 0x8eab, 0x8eac, 0x8ead, 0x8eae, 0x8eaf, 0x8eb0, 0x8eb1,
+ 0x8eb2, 0x8eb3, 0x8eb4, 0x8eb5, 0x8eb6, 0x8eb7, 0x8eb8, 0x8eb9,
+ 0x8eba, 0x8ebb, 0x8ebc, 0x8ebd, 0x8ebe, 0x8ebf, 0x8ec0, 0x8ec1,
+ 0x8ec2, 0x8ec3, 0x8ec4, 0x8ec5, 0x8ec6, 0x8ec7, 0x8ec8, 0x8ec9,
+ 0x8eca, 0x8ecb, 0x8ecc, 0x8ecd, 0x8ece, 0x8ecf, 0x8ed0, 0x8ed1,
+ 0x8ed2, 0x8ed3, 0x8ed4, 0x8ed5, 0x8ed6, 0x8ed7, 0x8ed8, 0x8ed9,
+ 0x8eda, 0x8edb, 0x8edc, 0x8edd, 0x8ede, 0x8edf, 0x8ee0, 0x8ee1,
+ 0x8ee2, 0x8ee3, 0x8ee4, 0x8ee5, 0x8ee6, 0x8ee7, 0x8ee8, 0x8ee9,
+ 0x8eea, 0x8eeb, 0x8eec, 0x8eed, 0x8eee, 0x8eef, 0x8ef0, 0x8ef1,
+ 0x8ef2, 0x8ef3, 0x8ef4, 0x8ef5, 0x8ef6, 0x8ef7, 0x8ef8, 0x8ef9,
+ 0x8efa, 0x8efb, 0x8efc, 0x8f40, 0x8f41, 0x8f42, 0x8f43, 0x8f44,
+ 0x8f45, 0x8f46, 0x8f47, 0x8f48, 0x8f49, 0x8f4a, 0x8f4b, 0x8f4c,
+ 0x8f4d, 0x8f4e, 0x8f4f, 0x8f50, 0x8f51, 0x8f52, 0x8f53, 0x8f54,
+ 0x8f55, 0x8f56, 0x8f57, 0x8f58, 0x8f59, 0x8f5a, 0x8f5b, 0x8f5c,
+ 0x8f5d, 0x8f5e, 0x8f5f, 0x8f60, 0x8f61, 0x8f62, 0x8f63, 0x8f64,
+ 0x8f65, 0x8f66, 0x8f67, 0x8f68, 0x8f69, 0x8f6a, 0x8f6b, 0x8f6c,
+ 0x8f6d, 0x8f6e, 0x8f6f, 0x8f70, 0x8f71, 0x8f72, 0x8f73, 0x8f74,
+ 0x8f75, 0x8f76, 0x8f77, 0x8f78, 0x8f79, 0x8f7a, 0x8f7b, 0x8f7c,
+ 0x8f7d, 0x8f7e, 0x8f80, 0x8f81, 0x8f82, 0x8f83, 0x8f84, 0x8f85,
+ 0x8f86, 0x8f87, 0x8f88, 0x8f89, 0x8f8a, 0x8f8b, 0x8f8c, 0x8f8d,
+ 0x8f8e, 0x8f8f, 0x8f90, 0x8f91, 0x8f92, 0x8f93, 0x8f94, 0x8f95,
+ 0x8f96, 0x8f97, 0x8f98, 0x8f99, 0x8f9a, 0x8f9b, 0x8f9c, 0x8f9d,
+ 0x8f9e, 0x8f9f, 0x8fa0, 0x8fa1, 0x8fa2, 0x8fa3, 0x8fa4, 0x8fa5,
+ 0x8fa6, 0x8fa7, 0x8fa8, 0x8fa9, 0x8faa, 0x8fab, 0x8fac, 0x8fad,
+ 0x8fae, 0x8faf, 0x8fb0, 0x8fb1, 0x8fb2, 0x8fb3, 0x8fb4, 0x8fb5,
+ 0x8fb6, 0x8fb7, 0x8fb8, 0x8fb9, 0x8fba, 0x8fbb, 0x8fbc, 0x8fbd,
+ 0x8fbe, 0x8fbf, 0x8fc0, 0x8fc1, 0x8fc2, 0x8fc3, 0x8fc4, 0x8fc5,
+ 0x8fc6, 0x8fc7, 0x8fc8, 0x8fc9, 0x8fca, 0x8fcb, 0x8fcc, 0x8fcd,
+ 0x8fce, 0x8fcf, 0x8fd0, 0x8fd1, 0x8fd2, 0x8fd3, 0x8fd4, 0x8fd5,
+ 0x8fd6, 0x8fd7, 0x8fd8, 0x8fd9, 0x8fda, 0x8fdb, 0x8fdc, 0x8fdd,
+ 0x8fde, 0x8fdf, 0x8fe0, 0x8fe1, 0x8fe2, 0x8fe3, 0x8fe4, 0x8fe5,
+ 0x8fe6, 0x8fe7, 0x8fe8, 0x8fe9, 0x8fea, 0x8feb, 0x8fec, 0x8fed,
+ 0x8fee, 0x8fef, 0x8ff0, 0x8ff1, 0x8ff2, 0x8ff3, 0x8ff4, 0x8ff5,
+ 0x8ff6, 0x8ff7, 0x8ff8, 0x8ff9, 0x8ffa, 0x8ffb, 0x8ffc, 0x9040,
+ 0x9041, 0x9042, 0x9043, 0x9044, 0x9045, 0x9046, 0x9047, 0x9048,
+ 0x9049, 0x904a, 0x904b, 0x904c, 0x904d, 0x904e, 0x904f, 0x9050,
+ 0x9051, 0x9052, 0x9053, 0x9054, 0x9055, 0x9056, 0x9057, 0x9058,
+ 0x9059, 0x905a, 0x905b, 0x905c, 0x905d, 0x905e, 0x905f, 0x9060,
+ 0x9061, 0x9062, 0x9063, 0x9064, 0x9065, 0x9066, 0x9067, 0x9068,
+ 0x9069, 0x906a, 0x906b, 0x906c, 0x906d, 0x906e, 0x906f, 0x9070,
+ 0x9071, 0x9072, 0x9073, 0x9074, 0x9075, 0x9076, 0x9077, 0x9078,
+ 0x9079, 0x907a, 0x907b, 0x907c, 0x907d, 0x907e, 0x9080, 0x9081,
+ 0x9082, 0x9083, 0x9084, 0x9085, 0x9086, 0x9087, 0x9088, 0x9089,
+ 0x908a, 0x908b, 0x908c, 0x908d, 0x908e, 0x908f, 0x9090, 0x9091,
+ 0x9092, 0x9093, 0x9094, 0x9095, 0x9096, 0x9097, 0x9098, 0x9099,
+ 0x909a, 0x909b, 0x909c, 0x909d, 0x909e, 0x909f, 0x90a0, 0x90a1,
+ 0x90a2, 0x90a3, 0x90a4, 0x90a5, 0x90a6, 0x90a7, 0x90a8, 0x90a9,
+ 0x90aa, 0x90ab, 0x90ac, 0x90ad, 0x90ae, 0x90af, 0x90b0, 0x90b1,
+ 0x90b2, 0x90b3, 0x90b4, 0x90b5, 0x90b6, 0x90b7, 0x90b8, 0x90b9,
+ 0x90ba, 0x90bb, 0x90bc, 0x90bd, 0x90be, 0x90bf, 0x90c0, 0x90c1,
+ 0x90c2, 0x90c3, 0x90c4, 0x90c5, 0x90c6, 0x90c7, 0x90c8, 0x90c9,
+ 0x90ca, 0x90cb, 0x90cc, 0x90cd, 0x90ce, 0x90cf, 0x90d0, 0x90d1,
+ 0x90d2, 0x90d3, 0x90d4, 0x90d5, 0x90d6, 0x90d7, 0x90d8, 0x90d9,
+ 0x90da, 0x90db, 0x90dc, 0x90dd, 0x90de, 0x90df, 0x90e0, 0x90e1,
+ 0x90e2, 0x90e3, 0x90e4, 0x90e5, 0x90e6, 0x90e7, 0x90e8, 0x90e9,
+ 0x90ea, 0x90eb, 0x90ec, 0x90ed, 0x90ee, 0x90ef, 0x90f0, 0x90f1,
+ 0x90f2, 0x90f3, 0x90f4, 0x90f5, 0x90f6, 0x90f7, 0x90f8, 0x90f9,
+ 0x90fa, 0x90fb, 0x90fc, 0x9140, 0x9141, 0x9142, 0x9143, 0x9144,
+ 0x9145, 0x9146, 0x9147, 0x9148, 0x9149, 0x914a, 0x914b, 0x914c,
+ 0x914d, 0x914e, 0x914f, 0x9150, 0x9151, 0x9152, 0x9153, 0x9154,
+ 0x9155, 0x9156, 0x9157, 0x9158, 0x9159, 0x915a, 0x915b, 0x915c,
+ 0x915d, 0x915e, 0x915f, 0x9160, 0x9161, 0x9162, 0x9163, 0x9164,
+ 0x9165, 0x9166, 0x9167, 0x9168, 0x9169, 0x916a, 0x916b, 0x916c,
+ 0x916d, 0x916e, 0x916f, 0x9170, 0x9171, 0x9172, 0x9173, 0x9174,
+ 0x9175, 0x9176, 0x9177, 0x9178, 0x9179, 0x917a, 0x917b, 0x917c,
+ 0x917d, 0x917e, 0x9180, 0x9181, 0x9182, 0x9183, 0x9184, 0x9185,
+ 0x9186, 0x9187, 0x9188, 0x9189, 0x918a, 0x918b, 0x918c, 0x918d,
+ 0x918e, 0x918f, 0x9190, 0x9191, 0x9192, 0x9193, 0x9194, 0x9195,
+ 0x9196, 0x9197, 0x9198, 0x9199, 0x919a, 0x919b, 0x919c, 0x919d,
+ 0x919e, 0x919f, 0x91a0, 0x91a1, 0x91a2, 0x91a3, 0x91a4, 0x91a5,
+ 0x91a6, 0x91a7, 0x91a8, 0x91a9, 0x91aa, 0x91ab, 0x91ac, 0x91ad,
+ 0x91ae, 0x91af, 0x91b0, 0x91b1, 0x91b2, 0x91b3, 0x91b4, 0x91b5,
+ 0x91b6, 0x91b7, 0x91b8, 0x91b9, 0x91ba, 0x91bb, 0x91bc, 0x91bd,
+ 0x91be, 0x91bf, 0x91c0, 0x91c1, 0x91c2, 0x91c3, 0x91c4, 0x91c5,
+ 0x91c6, 0x91c7, 0x91c8, 0x91c9, 0x91ca, 0x91cb, 0x91cc, 0x91cd,
+ 0x91ce, 0x91cf, 0x91d0, 0x91d1, 0x91d2, 0x91d3, 0x91d4, 0x91d5,
+ 0x91d6, 0x91d7, 0x91d8, 0x91d9, 0x91da, 0x91db, 0x91dc, 0x91dd,
+ 0x91de, 0x91df, 0x91e0, 0x91e1, 0x91e2, 0x91e3, 0x91e4, 0x91e5,
+ 0x91e6, 0x91e7, 0x91e8, 0x91e9, 0x91ea, 0x91eb, 0x91ec, 0x91ed,
+ 0x91ee, 0x91ef, 0x91f0, 0x91f1, 0x91f2, 0x91f3, 0x91f4, 0x91f5,
+ 0x91f6, 0x91f7, 0x91f8, 0x91f9, 0x91fa, 0x91fb, 0x91fc, 0x9240,
+ 0x9241, 0x9242, 0x9243, 0x9244, 0x9245, 0x9246, 0x9247, 0x9248,
+ 0x9249, 0x924a, 0x924b, 0x924c, 0x924d, 0x924e, 0x924f, 0x9250,
+ 0x9251, 0x9252, 0x9253, 0x9254, 0x9255, 0x9256, 0x9257, 0x9258,
+ 0x9259, 0x925a, 0x925b, 0x925c, 0x925d, 0x925e, 0x925f, 0x9260,
+ 0x9261, 0x9262, 0x9263, 0x9264, 0x9265, 0x9266, 0x9267, 0x9268,
+ 0x9269, 0x926a, 0x926b, 0x926c, 0x926d, 0x926e, 0x926f, 0x9270,
+ 0x9271, 0x9272, 0x9273, 0x9274, 0x9275, 0x9276, 0x9277, 0x9278,
+ 0x9279, 0x927a, 0x927b, 0x927c, 0x927d, 0x927e, 0x9280, 0x9281,
+ 0x9282, 0x9283, 0x9284, 0x9285, 0x9286, 0x9287, 0x9288, 0x9289,
+ 0x928a, 0x928b, 0x928c, 0x928d, 0x928e, 0x928f, 0x9290, 0x9291,
+ 0x9292, 0x9293, 0x9294, 0x9295, 0x9296, 0x9297, 0x9298, 0x9299,
+ 0x929a, 0x929b, 0x929c, 0x929d, 0x929e, 0x929f, 0x92a0, 0x92a1,
+ 0x92a2, 0x92a3, 0x92a4, 0x92a5, 0x92a6, 0x92a7, 0x92a8, 0x92a9,
+ 0x92aa, 0x92ab, 0x92ac, 0x92ad, 0x92ae, 0x92af, 0x92b0, 0x92b1,
+ 0x92b2, 0x92b3, 0x92b4, 0x92b5, 0x92b6, 0x92b7, 0x92b8, 0x92b9,
+ 0x92ba, 0x92bb, 0x92bc, 0x92bd, 0x92be, 0x92bf, 0x92c0, 0x92c1,
+ 0x92c2, 0x92c3, 0x92c4, 0x92c5, 0x92c6, 0x92c7, 0x92c8, 0x92c9,
+ 0x92ca, 0x92cb, 0x92cc, 0x92cd, 0x92ce, 0x92cf, 0x92d0, 0x92d1,
+ 0x92d2, 0x92d3, 0x92d4, 0x92d5, 0x92d6, 0x92d7, 0x92d8, 0x92d9,
+ 0x92da, 0x92db, 0x92dc, 0x92dd, 0x92de, 0x92df, 0x92e0, 0x92e1,
+ 0x92e2, 0x92e3, 0x92e4, 0x92e5, 0x92e6, 0x92e7, 0x92e8, 0x92e9,
+ 0x92ea, 0x92eb, 0x92ec, 0x92ed, 0x92ee, 0x92ef, 0x92f0, 0x92f1,
+ 0x92f2, 0x92f3, 0x92f4, 0x92f5, 0x92f6, 0x92f7, 0x92f8, 0x92f9,
+ 0x92fa, 0x92fb, 0x92fc, 0x9340, 0x9341, 0x9342, 0x9343, 0x9344,
+ 0x9345, 0x9346, 0x9347, 0x9348, 0x9349, 0x934a, 0x934b, 0x934c,
+ 0x934d, 0x934e, 0x934f, 0x9350, 0x9351, 0x9352, 0x9353, 0x9354,
+ 0x9355, 0x9356, 0x9357, 0x9358, 0x9359, 0x935a, 0x935b, 0x935c,
+ 0x935d, 0x935e, 0x935f, 0x9360, 0x9361, 0x9362, 0x9363, 0x9364,
+ 0x9365, 0x9366, 0x9367, 0x9368, 0x9369, 0x936a, 0x936b, 0x936c,
+ 0x936d, 0x936e, 0x936f, 0x9370, 0x9371, 0x9372, 0x9373, 0x9374,
+ 0x9375, 0x9376, 0x9377, 0x9378, 0x9379, 0x937a, 0x937b, 0x937c,
+ 0x937d, 0x937e, 0x9380, 0x9381, 0x9382, 0x9383, 0x9384, 0x9385,
+ 0x9386, 0x9387, 0x9388, 0x9389, 0x938a, 0x938b, 0x938c, 0x938d,
+ 0x938e, 0x938f, 0x9390, 0x9391, 0x9392, 0x9393, 0x9394, 0x9395,
+ 0x9396, 0x9397, 0x9398, 0x9399, 0x939a, 0x939b, 0x939c, 0x939d,
+ 0x939e, 0x939f, 0x93a0, 0x93a1, 0x93a2, 0x93a3, 0x93a4, 0x93a5,
+ 0x93a6, 0x93a7, 0x93a8, 0x93a9, 0x93aa, 0x93ab, 0x93ac, 0x93ad,
+ 0x93ae, 0x93af, 0x93b0, 0x93b1, 0x93b2, 0x93b3, 0x93b4, 0x93b5,
+ 0x93b6, 0x93b7, 0x93b8, 0x93b9, 0x93ba, 0x93bb, 0x93bc, 0x93bd,
+ 0x93be, 0x93bf, 0x93c0, 0x93c1, 0x93c2, 0x93c3, 0x93c4, 0x93c5,
+ 0x93c6, 0x93c7, 0x93c8, 0x93c9, 0x93ca, 0x93cb, 0x93cc, 0x93cd,
+ 0x93ce, 0x93cf, 0x93d0, 0x93d1, 0x93d2, 0x93d3, 0x93d4, 0x93d5,
+ 0x93d6, 0x93d7, 0x93d8, 0x93d9, 0x93da, 0x93db, 0x93dc, 0x93dd,
+ 0x93de, 0x93df, 0x93e0, 0x93e1, 0x93e2, 0x93e3, 0x93e4, 0x93e5,
+ 0x93e6, 0x93e7, 0x93e8, 0x93e9, 0x93ea, 0x93eb, 0x93ec, 0x93ed,
+ 0x93ee, 0x93ef, 0x93f0, 0x93f1, 0x93f2, 0x93f3, 0x93f4, 0x93f5,
+ 0x93f6, 0x93f7, 0x93f8, 0x93f9, 0x93fa, 0x93fb, 0x93fc, 0x9440,
+ 0x9441, 0x9442, 0x9443, 0x9444, 0x9445, 0x9446, 0x9447, 0x9448,
+ 0x9449, 0x944a, 0x944b, 0x944c, 0x944d, 0x944e, 0x944f, 0x9450,
+ 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457, 0x9458,
+ 0x9459, 0x945a, 0x945b, 0x945c, 0x945d, 0x945e, 0x945f, 0x9460,
+ 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467, 0x9468,
+ 0x9469, 0x946a, 0x946b, 0x946c, 0x946d, 0x946e, 0x946f, 0x9470,
+ 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, 0x9476, 0x9477, 0x9478,
+ 0x9479, 0x947a, 0x947b, 0x947c, 0x947d, 0x947e, 0x9480, 0x9481,
+ 0x9482, 0x9483, 0x9484, 0x9485, 0x9486, 0x9487, 0x9488, 0x9489,
+ 0x948a, 0x948b, 0x948c, 0x948d, 0x948e, 0x948f, 0x9490, 0x9491,
+ 0x9492, 0x9493, 0x9494, 0x9495, 0x9496, 0x9497, 0x9498, 0x9499,
+ 0x949a, 0x949b, 0x949c, 0x949d, 0x949e, 0x949f, 0x94a0, 0x94a1,
+ 0x94a2, 0x94a3, 0x94a4, 0x94a5, 0x94a6, 0x94a7, 0x94a8, 0x94a9,
+ 0x94aa, 0x94ab, 0x94ac, 0x94ad, 0x94ae, 0x94af, 0x94b0, 0x94b1,
+ 0x94b2, 0x94b3, 0x94b4, 0x94b5, 0x94b6, 0x94b7, 0x94b8, 0x94b9,
+ 0x94ba, 0x94bb, 0x94bc, 0x94bd, 0x94be, 0x94bf, 0x94c0, 0x94c1,
+ 0x94c2, 0x94c3, 0x94c4, 0x94c5, 0x94c6, 0x94c7, 0x94c8, 0x94c9,
+ 0x94ca, 0x94cb, 0x94cc, 0x94cd, 0x94ce, 0x94cf, 0x94d0, 0x94d1,
+ 0x94d2, 0x94d3, 0x94d4, 0x94d5, 0x94d6, 0x94d7, 0x94d8, 0x94d9,
+ 0x94da, 0x94db, 0x94dc, 0x94dd, 0x94de, 0x94df, 0x94e0, 0x94e1,
+ 0x94e2, 0x94e3, 0x94e4, 0x94e5, 0x94e6, 0x94e7, 0x94e8, 0x94e9,
+ 0x94ea, 0x94eb, 0x94ec, 0x94ed, 0x94ee, 0x94ef, 0x94f0, 0x94f1,
+ 0x94f2, 0x94f3, 0x94f4, 0x94f5, 0x94f6, 0x94f7, 0x94f8, 0x94f9,
+ 0x94fa, 0x94fb, 0x94fc, 0x9540, 0x9541, 0x9542, 0x9543, 0x9544,
+ 0x9545, 0x9546, 0x9547, 0x9548, 0x9549, 0x954a, 0x954b, 0x954c,
+ 0x954d, 0x954e, 0x954f, 0x9550, 0x9551, 0x9552, 0x9553, 0x9554,
+ 0x9555, 0x9556, 0x9557, 0x9558, 0x9559, 0x955a, 0x955b, 0x955c,
+ 0x955d, 0x955e, 0x955f, 0x9560, 0x9561, 0x9562, 0x9563, 0x9564,
+ 0x9565, 0x9566, 0x9567, 0x9568, 0x9569, 0x956a, 0x956b, 0x956c,
+ 0x956d, 0x956e, 0x956f, 0x9570, 0x9571, 0x9572, 0x9573, 0x9574,
+ 0x9575, 0x9576, 0x9577, 0x9578, 0x9579, 0x957a, 0x957b, 0x957c,
+ 0x957d, 0x957e, 0x9580, 0x9581, 0x9582, 0x9583, 0x9584, 0x9585,
+ 0x9586, 0x9587, 0x9588, 0x9589, 0x958a, 0x958b, 0x958c, 0x958d,
+ 0x958e, 0x958f, 0x9590, 0x9591, 0x9592, 0x9593, 0x9594, 0x9595,
+ 0x9596, 0x9597, 0x9598, 0x9599, 0x959a, 0x959b, 0x959c, 0x959d,
+ 0x959e, 0x959f, 0x95a0, 0x95a1, 0x95a2, 0x95a3, 0x95a4, 0x95a5,
+ 0x95a6, 0x95a7, 0x95a8, 0x95a9, 0x95aa, 0x95ab, 0x95ac, 0x95ad,
+ 0x95ae, 0x95af, 0x95b0, 0x95b1, 0x95b2, 0x95b3, 0x95b4, 0x95b5,
+ 0x95b6, 0x95b7, 0x95b8, 0x95b9, 0x95ba, 0x95bb, 0x95bc, 0x95bd,
+ 0x95be, 0x95bf, 0x95c0, 0x95c1, 0x95c2, 0x95c3, 0x95c4, 0x95c5,
+ 0x95c6, 0x95c7, 0x95c8, 0x95c9, 0x95ca, 0x95cb, 0x95cc, 0x95cd,
+ 0x95ce, 0x95cf, 0x95d0, 0x95d1, 0x95d2, 0x95d3, 0x95d4, 0x95d5,
+ 0x95d6, 0x95d7, 0x95d8, 0x95d9, 0x95da, 0x95db, 0x95dc, 0x95dd,
+ 0x95de, 0x95df, 0x95e0, 0x95e1, 0x95e2, 0x95e3, 0x95e4, 0x95e5,
+ 0x95e6, 0x95e7, 0x95e8, 0x95e9, 0x95ea, 0x95eb, 0x95ec, 0x95ed,
+ 0x95ee, 0x95ef, 0x95f0, 0x95f1, 0x95f2, 0x95f3, 0x95f4, 0x95f5,
+ 0x95f6, 0x95f7, 0x95f8, 0x95f9, 0x95fa, 0x95fb, 0x95fc, 0x9640,
+ 0x9641, 0x9642, 0x9643, 0x9644, 0x9645, 0x9646, 0x9647, 0x9648,
+ 0x9649, 0x964a, 0x964b, 0x964c, 0x964d, 0x964e, 0x964f, 0x9650,
+ 0x9651, 0x9652, 0x9653, 0x9654, 0x9655, 0x9656, 0x9657, 0x9658,
+ 0x9659, 0x965a, 0x965b, 0x965c, 0x965d, 0x965e, 0x965f, 0x9660,
+ 0x9661, 0x9662, 0x9663, 0x9664, 0x9665, 0x9666, 0x9667, 0x9668,
+ 0x9669, 0x966a, 0x966b, 0x966c, 0x966d, 0x966e, 0x966f, 0x9670,
+ 0x9671, 0x9672, 0x9673, 0x9674, 0x9675, 0x9676, 0x9677, 0x9678,
+ 0x9679, 0x967a, 0x967b, 0x967c, 0x967d, 0x967e, 0x9680, 0x9681,
+ 0x9682, 0x9683, 0x9684, 0x9685, 0x9686, 0x9687, 0x9688, 0x9689,
+ 0x968a, 0x968b, 0x968c, 0x968d, 0x968e, 0x968f, 0x9690, 0x9691,
+ 0x9692, 0x9693, 0x9694, 0x9695, 0x9696, 0x9697, 0x9698, 0x9699,
+ 0x969a, 0x969b, 0x969c, 0x969d, 0x969e, 0x969f, 0x96a0, 0x96a1,
+ 0x96a2, 0x96a3, 0x96a4, 0x96a5, 0x96a6, 0x96a7, 0x96a8, 0x96a9,
+ 0x96aa, 0x96ab, 0x96ac, 0x96ad, 0x96ae, 0x96af, 0x96b0, 0x96b1,
+ 0x96b2, 0x96b3, 0x96b4, 0x96b5, 0x96b6, 0x96b7, 0x96b8, 0x96b9,
+ 0x96ba, 0x96bb, 0x96bc, 0x96bd, 0x96be, 0x96bf, 0x96c0, 0x96c1,
+ 0x96c2, 0x96c3, 0x96c4, 0x96c5, 0x96c6, 0x96c7, 0x96c8, 0x96c9,
+ 0x96ca, 0x96cb, 0x96cc, 0x96cd, 0x96ce, 0x96cf, 0x96d0, 0x96d1,
+ 0x96d2, 0x96d3, 0x96d4, 0x96d5, 0x96d6, 0x96d7, 0x96d8, 0x96d9,
+ 0x96da, 0x96db, 0x96dc, 0x96dd, 0x96de, 0x96df, 0x96e0, 0x96e1,
+ 0x96e2, 0x96e3, 0x96e4, 0x96e5, 0x96e6, 0x96e7, 0x96e8, 0x96e9,
+ 0x96ea, 0x96eb, 0x96ec, 0x96ed, 0x96ee, 0x96ef, 0x96f0, 0x96f1,
+ 0x96f2, 0x96f3, 0x96f4, 0x96f5, 0x96f6, 0x96f7, 0x96f8, 0x96f9,
+ 0x96fa, 0x96fb, 0x96fc, 0x9740, 0x9741, 0x9742, 0x9743, 0x9744,
+ 0x9745, 0x9746, 0x9747, 0x9748, 0x9749, 0x974a, 0x974b, 0x974c,
+ 0x974d, 0x974e, 0x974f, 0x9750, 0x9751, 0x9752, 0x9753, 0x9754,
+ 0x9755, 0x9756, 0x9757, 0x9758, 0x9759, 0x975a, 0x975b, 0x975c,
+ 0x975d, 0x975e, 0x975f, 0x9760, 0x9761, 0x9762, 0x9763, 0x9764,
+ 0x9765, 0x9766, 0x9767, 0x9768, 0x9769, 0x976a, 0x976b, 0x976c,
+ 0x976d, 0x976e, 0x976f, 0x9770, 0x9771, 0x9772, 0x9773, 0x9774,
+ 0x9775, 0x9776, 0x9777, 0x9778, 0x9779, 0x977a, 0x977b, 0x977c,
+ 0x977d, 0x977e, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9785,
+ 0x9786, 0x9787, 0x9788, 0x9789, 0x978a, 0x978b, 0x978c, 0x978d,
+ 0x978e, 0x978f, 0x9790, 0x9791, 0x9792, 0x9793, 0x9794, 0x9795,
+ 0x9796, 0x9797, 0x9798, 0x9799, 0x979a, 0x979b, 0x979c, 0x979d,
+ 0x979e, 0x979f, 0x97a0, 0x97a1, 0x97a2, 0x97a3, 0x97a4, 0x97a5,
+ 0x97a6, 0x97a7, 0x97a8, 0x97a9, 0x97aa, 0x97ab, 0x97ac, 0x97ad,
+ 0x97ae, 0x97af, 0x97b0, 0x97b1, 0x97b2, 0x97b3, 0x97b4, 0x97b5,
+ 0x97b6, 0x97b7, 0x97b8, 0x97b9, 0x97ba, 0x97bb, 0x97bc, 0x97bd,
+ 0x97be, 0x97bf, 0x97c0, 0x97c1, 0x97c2, 0x97c3, 0x97c4, 0x97c5,
+ 0x97c6, 0x97c7, 0x97c8, 0x97c9, 0x97ca, 0x97cb, 0x97cc, 0x97cd,
+ 0x97ce, 0x97cf, 0x97d0, 0x97d1, 0x97d2, 0x97d3, 0x97d4, 0x97d5,
+ 0x97d6, 0x97d7, 0x97d8, 0x97d9, 0x97da, 0x97db, 0x97dc, 0x97dd,
+ 0x97de, 0x97df, 0x97e0, 0x97e1, 0x97e2, 0x97e3, 0x97e4, 0x97e5,
+ 0x97e6, 0x97e7, 0x97e8, 0x97e9, 0x97ea, 0x97eb, 0x97ec, 0x97ed,
+ 0x97ee, 0x97ef, 0x97f0, 0x97f1, 0x97f2, 0x97f3, 0x97f4, 0x97f5,
+ 0x97f6, 0x97f7, 0x97f8, 0x97f9, 0x97fa, 0x97fb, 0x97fc, 0x9840,
+ 0x9841, 0x9842, 0x9843, 0x9844, 0x9845, 0x9846, 0x9847, 0x9848,
+ 0x9849, 0x984a, 0x984b, 0x984c, 0x984d, 0x984e, 0x984f, 0x9850,
+ 0x9851, 0x9852, 0x9853, 0x9854, 0x9855, 0x9856, 0x9857, 0x9858,
+ 0x9859, 0x985a, 0x985b, 0x985c, 0x985d, 0x985e, 0x985f, 0x9860,
+ 0x9861, 0x9862, 0x9863, 0x9864, 0x9865, 0x9866, 0x9867, 0x9868,
+ 0x9869, 0x986a, 0x986b, 0x986c, 0x986d, 0x986e, 0x986f, 0x9870,
+ 0x9871, 0x9872, 0x989f, 0x98a0, 0x98a1, 0x98a2, 0x98a3, 0x98a4,
+ 0x98a5, 0x98a6, 0x98a7, 0x98a8, 0x98a9, 0x98aa, 0x98ab, 0x98ac,
+ 0x98ad, 0x98ae, 0x98af, 0x98b0, 0x98b1, 0x98b2, 0x98b3, 0x98b4,
+ 0x98b5, 0x98b6, 0x98b7, 0x98b8, 0x98b9, 0x98ba, 0x98bb, 0x98bc,
+ 0x98bd, 0x98be, 0x98bf, 0x98c0, 0x98c1, 0x98c2, 0x98c3, 0x98c4,
+ 0x98c5, 0x98c6, 0x98c7, 0x98c8, 0x98c9, 0x98ca, 0x98cb, 0x98cc,
+ 0x98cd, 0x98ce, 0x98cf, 0x98d0, 0x98d1, 0x98d2, 0x98d3, 0x98d4,
+ 0x98d5, 0x98d6, 0x98d7, 0x98d8, 0x98d9, 0x98da, 0x98db, 0x98dc,
+ 0x98dd, 0x98de, 0x98df, 0x98e0, 0x98e1, 0x98e2, 0x98e3, 0x98e4,
+ 0x98e5, 0x98e6, 0x98e7, 0x98e8, 0x98e9, 0x98ea, 0x98eb, 0x98ec,
+ 0x98ed, 0x98ee, 0x98ef, 0x98f0, 0x98f1, 0x98f2, 0x98f3, 0x98f4,
+ 0x98f5, 0x98f6, 0x98f7, 0x98f8, 0x98f9, 0x98fa, 0x98fb, 0x98fc,
+ 0x9940, 0x9941, 0x9942, 0x9943, 0x9944, 0x9945, 0x9946, 0x9947,
+ 0x9948, 0x9949, 0x994a, 0x994b, 0x994c, 0x994d, 0x994e, 0x994f,
+ 0x9950, 0x9951, 0x9952, 0x9953, 0x9954, 0x9955, 0x9956, 0x9957,
+ 0x9958, 0x9959, 0x995a, 0x995b, 0x995c, 0x995d, 0x995e, 0x995f,
+ 0x9960, 0x9961, 0x9962, 0x9963, 0x9964, 0x9965, 0x9966, 0x9967,
+ 0x9968, 0x9969, 0x996a, 0x996b, 0x996c, 0x996d, 0x996e, 0x996f,
+ 0x9970, 0x9971, 0x9972, 0x9973, 0x9974, 0x9975, 0x9976, 0x9977,
+ 0x9978, 0x9979, 0x997a, 0x997b, 0x997c, 0x997d, 0x997e, 0x9980,
+ 0x9981, 0x9982, 0x9983, 0x9984, 0x9985, 0x9986, 0x9987, 0x9988,
+ 0x9989, 0x998a, 0x998b, 0x998c, 0x998d, 0x998e, 0x998f, 0x9990,
+ 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998,
+ 0x9999, 0x999a, 0x999b, 0x999c, 0x999d, 0x999e, 0x999f, 0x99a0,
+ 0x99a1, 0x99a2, 0x99a3, 0x99a4, 0x99a5, 0x99a6, 0x99a7, 0x99a8,
+ 0x99a9, 0x99aa, 0x99ab, 0x99ac, 0x99ad, 0x99ae, 0x99af, 0x99b0,
+ 0x99b1, 0x99b2, 0x99b3, 0x99b4, 0x99b5, 0x99b6, 0x99b7, 0x99b8,
+ 0x99b9, 0x99ba, 0x99bb, 0x99bc, 0x99bd, 0x99be, 0x99bf, 0x99c0,
+ 0x99c1, 0x99c2, 0x99c3, 0x99c4, 0x99c5, 0x99c6, 0x99c7, 0x99c8,
+ 0x99c9, 0x99ca, 0x99cb, 0x99cc, 0x99cd, 0x99ce, 0x99cf, 0x99d0,
+ 0x99d1, 0x99d2, 0x99d3, 0x99d4, 0x99d5, 0x99d6, 0x99d7, 0x99d8,
+ 0x99d9, 0x99da, 0x99db, 0x99dc, 0x99dd, 0x99de, 0x99df, 0x99e0,
+ 0x99e1, 0x99e2, 0x99e3, 0x99e4, 0x99e5, 0x99e6, 0x99e7, 0x99e8,
+ 0x99e9, 0x99ea, 0x99eb, 0x99ec, 0x99ed, 0x99ee, 0x99ef, 0x99f0,
+ 0x99f1, 0x99f2, 0x99f3, 0x99f4, 0x99f5, 0x99f6, 0x99f7, 0x99f8,
+ 0x99f9, 0x99fa, 0x99fb, 0x99fc, 0x9a40, 0x9a41, 0x9a42, 0x9a43,
+ 0x9a44, 0x9a45, 0x9a46, 0x9a47, 0x9a48, 0x9a49, 0x9a4a, 0x9a4b,
+ 0x9a4c, 0x9a4d, 0x9a4e, 0x9a4f, 0x9a50, 0x9a51, 0x9a52, 0x9a53,
+ 0x9a54, 0x9a55, 0x9a56, 0x9a57, 0x9a58, 0x9a59, 0x9a5a, 0x9a5b,
+ 0x9a5c, 0x9a5d, 0x9a5e, 0x9a5f, 0x9a60, 0x9a61, 0x9a62, 0x9a63,
+ 0x9a64, 0x9a65, 0x9a66, 0x9a67, 0x9a68, 0x9a69, 0x9a6a, 0x9a6b,
+ 0x9a6c, 0x9a6d, 0x9a6e, 0x9a6f, 0x9a70, 0x9a71, 0x9a72, 0x9a73,
+ 0x9a74, 0x9a75, 0x9a76, 0x9a77, 0x9a78, 0x9a79, 0x9a7a, 0x9a7b,
+ 0x9a7c, 0x9a7d, 0x9a7e, 0x9a80, 0x9a81, 0x9a82, 0x9a83, 0x9a84,
+ 0x9a85, 0x9a86, 0x9a87, 0x9a88, 0x9a89, 0x9a8a, 0x9a8b, 0x9a8c,
+ 0x9a8d, 0x9a8e, 0x9a8f, 0x9a90, 0x9a91, 0x9a92, 0x9a93, 0x9a94,
+ 0x9a95, 0x9a96, 0x9a97, 0x9a98, 0x9a99, 0x9a9a, 0x9a9b, 0x9a9c,
+ 0x9a9d, 0x9a9e, 0x9a9f, 0x9aa0, 0x9aa1, 0x9aa2, 0x9aa3, 0x9aa4,
+ 0x9aa5, 0x9aa6, 0x9aa7, 0x9aa8, 0x9aa9, 0x9aaa, 0x9aab, 0x9aac,
+ 0x9aad, 0x9aae, 0x9aaf, 0x9ab0, 0x9ab1, 0x9ab2, 0x9ab3, 0x9ab4,
+ 0x9ab5, 0x9ab6, 0x9ab7, 0x9ab8, 0x9ab9, 0x9aba, 0x9abb, 0x9abc,
+ 0x9abd, 0x9abe, 0x9abf, 0x9ac0, 0x9ac1, 0x9ac2, 0x9ac3, 0x9ac4,
+ 0x9ac5, 0x9ac6, 0x9ac7, 0x9ac8, 0x9ac9, 0x9aca, 0x9acb, 0x9acc,
+ 0x9acd, 0x9ace, 0x9acf, 0x9ad0, 0x9ad1, 0x9ad2, 0x9ad3, 0x9ad4,
+ 0x9ad5, 0x9ad6, 0x9ad7, 0x9ad8, 0x9ad9, 0x9ada, 0x9adb, 0x9adc,
+ 0x9add, 0x9ade, 0x9adf, 0x9ae0, 0x9ae1, 0x9ae2, 0x9ae3, 0x9ae4,
+ 0x9ae5, 0x9ae6, 0x9ae7, 0x9ae8, 0x9ae9, 0x9aea, 0x9aeb, 0x9aec,
+ 0x9aed, 0x9aee, 0x9aef, 0x9af0, 0x9af1, 0x9af2, 0x9af3, 0x9af4,
+ 0x9af5, 0x9af6, 0x9af7, 0x9af8, 0x9af9, 0x9afa, 0x9afb, 0x9afc,
+ 0x9b40, 0x9b41, 0x9b42, 0x9b43, 0x9b44, 0x9b45, 0x9b46, 0x9b47,
+ 0x9b48, 0x9b49, 0x9b4a, 0x9b4b, 0x9b4c, 0x9b4d, 0x9b4e, 0x9b4f,
+ 0x9b50, 0x9b51, 0x9b52, 0x9b53, 0x9b54, 0x9b55, 0x9b56, 0x9b57,
+ 0x9b58, 0x9b59, 0x9b5a, 0x9b5b, 0x9b5c, 0x9b5d, 0x9b5e, 0x9b5f,
+ 0x9b60, 0x9b61, 0x9b62, 0x9b63, 0x9b64, 0x9b65, 0x9b66, 0x9b67,
+ 0x9b68, 0x9b69, 0x9b6a, 0x9b6b, 0x9b6c, 0x9b6d, 0x9b6e, 0x9b6f,
+ 0x9b70, 0x9b71, 0x9b72, 0x9b73, 0x9b74, 0x9b75, 0x9b76, 0x9b77,
+ 0x9b78, 0x9b79, 0x9b7a, 0x9b7b, 0x9b7c, 0x9b7d, 0x9b7e, 0x9b80,
+ 0x9b81, 0x9b82, 0x9b83, 0x9b84, 0x9b85, 0x9b86, 0x9b87, 0x9b88,
+ 0x9b89, 0x9b8a, 0x9b8b, 0x9b8c, 0x9b8d, 0x9b8e, 0x9b8f, 0x9b90,
+ 0x9b91, 0x9b92, 0x9b93, 0x9b94, 0x9b95, 0x9b96, 0x9b97, 0x9b98,
+ 0x9b99, 0x9b9a, 0x9b9b, 0x9b9c, 0x9b9d, 0x9b9e, 0x9b9f, 0x9ba0,
+ 0x9ba1, 0x9ba2, 0x9ba3, 0x9ba4, 0x9ba5, 0x9ba6, 0x9ba7, 0x9ba8,
+ 0x9ba9, 0x9baa, 0x9bab, 0x9bac, 0x9bad, 0x9bae, 0x9baf, 0x9bb0,
+ 0x9bb1, 0x9bb2, 0x9bb3, 0x9bb4, 0x9bb5, 0x9bb6, 0x9bb7, 0x9bb8,
+ 0x9bb9, 0x9bba, 0x9bbb, 0x9bbc, 0x9bbd, 0x9bbe, 0x9bbf, 0x9bc0,
+ 0x9bc1, 0x9bc2, 0x9bc3, 0x9bc4, 0x9bc5, 0x9bc6, 0x9bc7, 0x9bc8,
+ 0x9bc9, 0x9bca, 0x9bcb, 0x9bcc, 0x9bcd, 0x9bce, 0x9bcf, 0x9bd0,
+ 0x9bd1, 0x9bd2, 0x9bd3, 0x9bd4, 0x9bd5, 0x9bd6, 0x9bd7, 0x9bd8,
+ 0x9bd9, 0x9bda, 0x9bdb, 0x9bdc, 0x9bdd, 0x9bde, 0x9bdf, 0x9be0,
+ 0x9be1, 0x9be2, 0x9be3, 0x9be4, 0x9be5, 0x9be6, 0x9be7, 0x9be8,
+ 0x9be9, 0x9bea, 0x9beb, 0x9bec, 0x9bed, 0x9bee, 0x9bef, 0x9bf0,
+ 0x9bf1, 0x9bf2, 0x9bf3, 0x9bf4, 0x9bf5, 0x9bf6, 0x9bf7, 0x9bf8,
+ 0x9bf9, 0x9bfa, 0x9bfb, 0x9bfc, 0x9c40, 0x9c41, 0x9c42, 0x9c43,
+ 0x9c44, 0x9c45, 0x9c46, 0x9c47, 0x9c48, 0x9c49, 0x9c4a, 0x9c4b,
+ 0x9c4c, 0x9c4d, 0x9c4e, 0x9c4f, 0x9c50, 0x9c51, 0x9c52, 0x9c53,
+ 0x9c54, 0x9c55, 0x9c56, 0x9c57, 0x9c58, 0x9c59, 0x9c5a, 0x9c5b,
+ 0x9c5c, 0x9c5d, 0x9c5e, 0x9c5f, 0x9c60, 0x9c61, 0x9c62, 0x9c63,
+ 0x9c64, 0x9c65, 0x9c66, 0x9c67, 0x9c68, 0x9c69, 0x9c6a, 0x9c6b,
+ 0x9c6c, 0x9c6d, 0x9c6e, 0x9c6f, 0x9c70, 0x9c71, 0x9c72, 0x9c73,
+ 0x9c74, 0x9c75, 0x9c76, 0x9c77, 0x9c78, 0x9c79, 0x9c7a, 0x9c7b,
+ 0x9c7c, 0x9c7d, 0x9c7e, 0x9c80, 0x9c81, 0x9c82, 0x9c83, 0x9c84,
+ 0x9c85, 0x9c86, 0x9c87, 0x9c88, 0x9c89, 0x9c8a, 0x9c8b, 0x9c8c,
+ 0x9c8d, 0x9c8e, 0x9c8f, 0x9c90, 0x9c91, 0x9c92, 0x9c93, 0x9c94,
+ 0x9c95, 0x9c96, 0x9c97, 0x9c98, 0x9c99, 0x9c9a, 0x9c9b, 0x9c9c,
+ 0x9c9d, 0x9c9e, 0x9c9f, 0x9ca0, 0x9ca1, 0x9ca2, 0x9ca3, 0x9ca4,
+ 0x9ca5, 0x9ca6, 0x9ca7, 0x9ca8, 0x9ca9, 0x9caa, 0x9cab, 0x9cac,
+ 0x9cad, 0x9cae, 0x9caf, 0x9cb0, 0x9cb1, 0x9cb2, 0x9cb3, 0x9cb4,
+ 0x9cb5, 0x9cb6, 0x9cb7, 0x9cb8, 0x9cb9, 0x9cba, 0x9cbb, 0x9cbc,
+ 0x9cbd, 0x9cbe, 0x9cbf, 0x9cc0, 0x9cc1, 0x9cc2, 0x9cc3, 0x9cc4,
+ 0x9cc5, 0x9cc6, 0x9cc7, 0x9cc8, 0x9cc9, 0x9cca, 0x9ccb, 0x9ccc,
+ 0x9ccd, 0x9cce, 0x9ccf, 0x9cd0, 0x9cd1, 0x9cd2, 0x9cd3, 0x9cd4,
+ 0x9cd5, 0x9cd6, 0x9cd7, 0x9cd8, 0x9cd9, 0x9cda, 0x9cdb, 0x9cdc,
+ 0x9cdd, 0x9cde, 0x9cdf, 0x9ce0, 0x9ce1, 0x9ce2, 0x9ce3, 0x9ce4,
+ 0x9ce5, 0x9ce6, 0x9ce7, 0x9ce8, 0x9ce9, 0x9cea, 0x9ceb, 0x9cec,
+ 0x9ced, 0x9cee, 0x9cef, 0x9cf0, 0x9cf1, 0x9cf2, 0x9cf3, 0x9cf4,
+ 0x9cf5, 0x9cf6, 0x9cf7, 0x9cf8, 0x9cf9, 0x9cfa, 0x9cfb, 0x9cfc,
+ 0x9d40, 0x9d41, 0x9d42, 0x9d43, 0x9d44, 0x9d45, 0x9d46, 0x9d47,
+ 0x9d48, 0x9d49, 0x9d4a, 0x9d4b, 0x9d4c, 0x9d4d, 0x9d4e, 0x9d4f,
+ 0x9d50, 0x9d51, 0x9d52, 0x9d53, 0x9d54, 0x9d55, 0x9d56, 0x9d57,
+ 0x9d58, 0x9d59, 0x9d5a, 0x9d5b, 0x9d5c, 0x9d5d, 0x9d5e, 0x9d5f,
+ 0x9d60, 0x9d61, 0x9d62, 0x9d63, 0x9d64, 0x9d65, 0x9d66, 0x9d67,
+ 0x9d68, 0x9d69, 0x9d6a, 0x9d6b, 0x9d6c, 0x9d6d, 0x9d6e, 0x9d6f,
+ 0x9d70, 0x9d71, 0x9d72, 0x9d73, 0x9d74, 0x9d75, 0x9d76, 0x9d77,
+ 0x9d78, 0x9d79, 0x9d7a, 0x9d7b, 0x9d7c, 0x9d7d, 0x9d7e, 0x9d80,
+ 0x9d81, 0x9d82, 0x9d83, 0x9d84, 0x9d85, 0x9d86, 0x9d87, 0x9d88,
+ 0x9d89, 0x9d8a, 0x9d8b, 0x9d8c, 0x9d8d, 0x9d8e, 0x9d8f, 0x9d90,
+ 0x9d91, 0x9d92, 0x9d93, 0x9d94, 0x9d95, 0x9d96, 0x9d97, 0x9d98,
+ 0x9d99, 0x9d9a, 0x9d9b, 0x9d9c, 0x9d9d, 0x9d9e, 0x9d9f, 0x9da0,
+ 0x9da1, 0x9da2, 0x9da3, 0x9da4, 0x9da5, 0x9da6, 0x9da7, 0x9da8,
+ 0x9da9, 0x9daa, 0x9dab, 0x9dac, 0x9dad, 0x9dae, 0x9daf, 0x9db0,
+ 0x9db1, 0x9db2, 0x9db3, 0x9db4, 0x9db5, 0x9db6, 0x9db7, 0x9db8,
+ 0x9db9, 0x9dba, 0x9dbb, 0x9dbc, 0x9dbd, 0x9dbe, 0x9dbf, 0x9dc0,
+ 0x9dc1, 0x9dc2, 0x9dc3, 0x9dc4, 0x9dc5, 0x9dc6, 0x9dc7, 0x9dc8,
+ 0x9dc9, 0x9dca, 0x9dcb, 0x9dcc, 0x9dcd, 0x9dce, 0x9dcf, 0x9dd0,
+ 0x9dd1, 0x9dd2, 0x9dd3, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7, 0x9dd8,
+ 0x9dd9, 0x9dda, 0x9ddb, 0x9ddc, 0x9ddd, 0x9dde, 0x9ddf, 0x9de0,
+ 0x9de1, 0x9de2, 0x9de3, 0x9de4, 0x9de5, 0x9de6, 0x9de7, 0x9de8,
+ 0x9de9, 0x9dea, 0x9deb, 0x9dec, 0x9ded, 0x9dee, 0x9def, 0x9df0,
+ 0x9df1, 0x9df2, 0x9df3, 0x9df4, 0x9df5, 0x9df6, 0x9df7, 0x9df8,
+ 0x9df9, 0x9dfa, 0x9dfb, 0x9dfc, 0x9e40, 0x9e41, 0x9e42, 0x9e43,
+ 0x9e44, 0x9e45, 0x9e46, 0x9e47, 0x9e48, 0x9e49, 0x9e4a, 0x9e4b,
+ 0x9e4c, 0x9e4d, 0x9e4e, 0x9e4f, 0x9e50, 0x9e51, 0x9e52, 0x9e53,
+ 0x9e54, 0x9e55, 0x9e56, 0x9e57, 0x9e58, 0x9e59, 0x9e5a, 0x9e5b,
+ 0x9e5c, 0x9e5d, 0x9e5e, 0x9e5f, 0x9e60, 0x9e61, 0x9e62, 0x9e63,
+ 0x9e64, 0x9e65, 0x9e66, 0x9e67, 0x9e68, 0x9e69, 0x9e6a, 0x9e6b,
+ 0x9e6c, 0x9e6d, 0x9e6e, 0x9e6f, 0x9e70, 0x9e71, 0x9e72, 0x9e73,
+ 0x9e74, 0x9e75, 0x9e76, 0x9e77, 0x9e78, 0x9e79, 0x9e7a, 0x9e7b,
+ 0x9e7c, 0x9e7d, 0x9e7e, 0x9e80, 0x9e81, 0x9e82, 0x9e83, 0x9e84,
+ 0x9e85, 0x9e86, 0x9e87, 0x9e88, 0x9e89, 0x9e8a, 0x9e8b, 0x9e8c,
+ 0x9e8d, 0x9e8e, 0x9e8f, 0x9e90, 0x9e91, 0x9e92, 0x9e93, 0x9e94,
+ 0x9e95, 0x9e96, 0x9e97, 0x9e98, 0x9e99, 0x9e9a, 0x9e9b, 0x9e9c,
+ 0x9e9d, 0x9e9e, 0x9e9f, 0x9ea0, 0x9ea1, 0x9ea2, 0x9ea3, 0x9ea4,
+ 0x9ea5, 0x9ea6, 0x9ea7, 0x9ea8, 0x9ea9, 0x9eaa, 0x9eab, 0x9eac,
+ 0x9ead, 0x9eae, 0x9eaf, 0x9eb0, 0x9eb1, 0x9eb2, 0x9eb3, 0x9eb4,
+ 0x9eb5, 0x9eb6, 0x9eb7, 0x9eb8, 0x9eb9, 0x9eba, 0x9ebb, 0x9ebc,
+ 0x9ebd, 0x9ebe, 0x9ebf, 0x9ec0, 0x9ec1, 0x9ec2, 0x9ec3, 0x9ec4,
+ 0x9ec5, 0x9ec6, 0x9ec7, 0x9ec8, 0x9ec9, 0x9eca, 0x9ecb, 0x9ecc,
+ 0x9ecd, 0x9ece, 0x9ecf, 0x9ed0, 0x9ed1, 0x9ed2, 0x9ed3, 0x9ed4,
+ 0x9ed5, 0x9ed6, 0x9ed7, 0x9ed8, 0x9ed9, 0x9eda, 0x9edb, 0x9edc,
+ 0x9edd, 0x9ede, 0x9edf, 0x9ee0, 0x9ee1, 0x9ee2, 0x9ee3, 0x9ee4,
+ 0x9ee5, 0x9ee6, 0x9ee7, 0x9ee8, 0x9ee9, 0x9eea, 0x9eeb, 0x9eec,
+ 0x9eed, 0x9eee, 0x9eef, 0x9ef0, 0x9ef1, 0x9ef2, 0x9ef3, 0x9ef4,
+ 0x9ef5, 0x9ef6, 0x9ef7, 0x9ef8, 0x9ef9, 0x9efa, 0x9efb, 0x9efc,
+ 0x9f40, 0x9f41, 0x9f42, 0x9f43, 0x9f44, 0x9f45, 0x9f46, 0x9f47,
+ 0x9f48, 0x9f49, 0x9f4a, 0x9f4b, 0x9f4c, 0x9f4d, 0x9f4e, 0x9f4f,
+ 0x9f50, 0x9f51, 0x9f52, 0x9f53, 0x9f54, 0x9f55, 0x9f56, 0x9f57,
+ 0x9f58, 0x9f59, 0x9f5a, 0x9f5b, 0x9f5c, 0x9f5d, 0x9f5e, 0x9f5f,
+ 0x9f60, 0x9f61, 0x9f62, 0x9f63, 0x9f64, 0x9f65, 0x9f66, 0x9f67,
+ 0x9f68, 0x9f69, 0x9f6a, 0x9f6b, 0x9f6c, 0x9f6d, 0x9f6e, 0x9f6f,
+ 0x9f70, 0x9f71, 0x9f72, 0x9f73, 0x9f74, 0x9f75, 0x9f76, 0x9f77,
+ 0x9f78, 0x9f79, 0x9f7a, 0x9f7b, 0x9f7c, 0x9f7d, 0x9f7e, 0x9f80,
+ 0x9f81, 0x9f82, 0x9f83, 0x9f84, 0x9f85, 0x9f86, 0x9f87, 0x9f88,
+ 0x9f89, 0x9f8a, 0x9f8b, 0x9f8c, 0x9f8d, 0x9f8e, 0x9f8f, 0x9f90,
+ 0x9f91, 0x9f92, 0x9f93, 0x9f94, 0x9f95, 0x9f96, 0x9f97, 0x9f98,
+ 0x9f99, 0x9f9a, 0x9f9b, 0x9f9c, 0x9f9d, 0x9f9e, 0x9f9f, 0x9fa0,
+ 0x9fa1, 0x9fa2, 0x9fa3, 0x9fa4, 0x9fa5, 0x9fa6, 0x9fa7, 0x9fa8,
+ 0x9fa9, 0x9faa, 0x9fab, 0x9fac, 0x9fad, 0x9fae, 0x9faf, 0x9fb0,
+ 0x9fb1, 0x9fb2, 0x9fb3, 0x9fb4, 0x9fb5, 0x9fb6, 0x9fb7, 0x9fb8,
+ 0x9fb9, 0x9fba, 0x9fbb, 0x9fbc, 0x9fbd, 0x9fbe, 0x9fbf, 0x9fc0,
+ 0x9fc1, 0x9fc2, 0x9fc3, 0x9fc4, 0x9fc5, 0x9fc6, 0x9fc7, 0x9fc8,
+ 0x9fc9, 0x9fca, 0x9fcb, 0x9fcc, 0x9fcd, 0x9fce, 0x9fcf, 0x9fd0,
+ 0x9fd1, 0x9fd2, 0x9fd3, 0x9fd4, 0x9fd5, 0x9fd6, 0x9fd7, 0x9fd8,
+ 0x9fd9, 0x9fda, 0x9fdb, 0x9fdc, 0x9fdd, 0x9fde, 0x9fdf, 0x9fe0,
+ 0x9fe1, 0x9fe2, 0x9fe3, 0x9fe4, 0x9fe5, 0x9fe6, 0x9fe7, 0x9fe8,
+ 0x9fe9, 0x9fea, 0x9feb, 0x9fec, 0x9fed, 0x9fee, 0x9fef, 0x9ff0,
+ 0x9ff1, 0x9ff2, 0x9ff3, 0x9ff4, 0x9ff5, 0x9ff6, 0x9ff7, 0x9ff8,
+ 0x9ff9, 0x9ffa, 0x9ffb, 0x9ffc, 0xe040, 0xe041, 0xe042, 0xe043,
+ 0xe044, 0xe045, 0xe046, 0xe047, 0xe048, 0xe049, 0xe04a, 0xe04b,
+ 0xe04c, 0xe04d, 0xe04e, 0xe04f, 0xe050, 0xe051, 0xe052, 0xe053,
+ 0xe054, 0xe055, 0xe056, 0xe057, 0xe058, 0xe059, 0xe05a, 0xe05b,
+ 0xe05c, 0xe05d, 0xe05e, 0xe05f, 0xe060, 0xe061, 0xe062, 0xe063,
+ 0xe064, 0xe065, 0xe066, 0xe067, 0xe068, 0xe069, 0xe06a, 0xe06b,
+ 0xe06c, 0xe06d, 0xe06e, 0xe06f, 0xe070, 0xe071, 0xe072, 0xe073,
+ 0xe074, 0xe075, 0xe076, 0xe077, 0xe078, 0xe079, 0xe07a, 0xe07b,
+ 0xe07c, 0xe07d, 0xe07e, 0xe080, 0xe081, 0xe082, 0xe083, 0xe084,
+ 0xe085, 0xe086, 0xe087, 0xe088, 0xe089, 0xe08a, 0xe08b, 0xe08c,
+ 0xe08d, 0xe08e, 0xe08f, 0xe090, 0xe091, 0xe092, 0xe093, 0xe094,
+ 0xe095, 0xe096, 0xe097, 0xe098, 0xe099, 0xe09a, 0xe09b, 0xe09c,
+ 0xe09d, 0xe09e, 0xe09f, 0xe0a0, 0xe0a1, 0xe0a2, 0xe0a3, 0xe0a4,
+ 0xe0a5, 0xe0a6, 0xe0a7, 0xe0a8, 0xe0a9, 0xe0aa, 0xe0ab, 0xe0ac,
+ 0xe0ad, 0xe0ae, 0xe0af, 0xe0b0, 0xe0b1, 0xe0b2, 0xe0b3, 0xe0b4,
+ 0xe0b5, 0xe0b6, 0xe0b7, 0xe0b8, 0xe0b9, 0xe0ba, 0xe0bb, 0xe0bc,
+ 0xe0bd, 0xe0be, 0xe0bf, 0xe0c0, 0xe0c1, 0xe0c2, 0xe0c3, 0xe0c4,
+ 0xe0c5, 0xe0c6, 0xe0c7, 0xe0c8, 0xe0c9, 0xe0ca, 0xe0cb, 0xe0cc,
+ 0xe0cd, 0xe0ce, 0xe0cf, 0xe0d0, 0xe0d1, 0xe0d2, 0xe0d3, 0xe0d4,
+ 0xe0d5, 0xe0d6, 0xe0d7, 0xe0d8, 0xe0d9, 0xe0da, 0xe0db, 0xe0dc,
+ 0xe0dd, 0xe0de, 0xe0df, 0xe0e0, 0xe0e1, 0xe0e2, 0xe0e3, 0xe0e4,
+ 0xe0e5, 0xe0e6, 0xe0e7, 0xe0e8, 0xe0e9, 0xe0ea, 0xe0eb, 0xe0ec,
+ 0xe0ed, 0xe0ee, 0xe0ef, 0xe0f0, 0xe0f1, 0xe0f2, 0xe0f3, 0xe0f4,
+ 0xe0f5, 0xe0f6, 0xe0f7, 0xe0f8, 0xe0f9, 0xe0fa, 0xe0fb, 0xe0fc,
+ 0xe140, 0xe141, 0xe142, 0xe143, 0xe144, 0xe145, 0xe146, 0xe147,
+ 0xe148, 0xe149, 0xe14a, 0xe14b, 0xe14c, 0xe14d, 0xe14e, 0xe14f,
+ 0xe150, 0xe151, 0xe152, 0xe153, 0xe154, 0xe155, 0xe156, 0xe157,
+ 0xe158, 0xe159, 0xe15a, 0xe15b, 0xe15c, 0xe15d, 0xe15e, 0xe15f,
+ 0xe160, 0xe161, 0xe162, 0xe163, 0xe164, 0xe165, 0xe166, 0xe167,
+ 0xe168, 0xe169, 0xe16a, 0xe16b, 0xe16c, 0xe16d, 0xe16e, 0xe16f,
+ 0xe170, 0xe171, 0xe172, 0xe173, 0xe174, 0xe175, 0xe176, 0xe177,
+ 0xe178, 0xe179, 0xe17a, 0xe17b, 0xe17c, 0xe17d, 0xe17e, 0xe180,
+ 0xe181, 0xe182, 0xe183, 0xe184, 0xe185, 0xe186, 0xe187, 0xe188,
+ 0xe189, 0xe18a, 0xe18b, 0xe18c, 0xe18d, 0xe18e, 0xe18f, 0xe190,
+ 0xe191, 0xe192, 0xe193, 0xe194, 0xe195, 0xe196, 0xe197, 0xe198,
+ 0xe199, 0xe19a, 0xe19b, 0xe19c, 0xe19d, 0xe19e, 0xe19f, 0xe1a0,
+ 0xe1a1, 0xe1a2, 0xe1a3, 0xe1a4, 0xe1a5, 0xe1a6, 0xe1a7, 0xe1a8,
+ 0xe1a9, 0xe1aa, 0xe1ab, 0xe1ac, 0xe1ad, 0xe1ae, 0xe1af, 0xe1b0,
+ 0xe1b1, 0xe1b2, 0xe1b3, 0xe1b4, 0xe1b5, 0xe1b6, 0xe1b7, 0xe1b8,
+ 0xe1b9, 0xe1ba, 0xe1bb, 0xe1bc, 0xe1bd, 0xe1be, 0xe1bf, 0xe1c0,
+ 0xe1c1, 0xe1c2, 0xe1c3, 0xe1c4, 0xe1c5, 0xe1c6, 0xe1c7, 0xe1c8,
+ 0xe1c9, 0xe1ca, 0xe1cb, 0xe1cc, 0xe1cd, 0xe1ce, 0xe1cf, 0xe1d0,
+ 0xe1d1, 0xe1d2, 0xe1d3, 0xe1d4, 0xe1d5, 0xe1d6, 0xe1d7, 0xe1d8,
+ 0xe1d9, 0xe1da, 0xe1db, 0xe1dc, 0xe1dd, 0xe1de, 0xe1df, 0xe1e0,
+ 0xe1e1, 0xe1e2, 0xe1e3, 0xe1e4, 0xe1e5, 0xe1e6, 0xe1e7, 0xe1e8,
+ 0xe1e9, 0xe1ea, 0xe1eb, 0xe1ec, 0xe1ed, 0xe1ee, 0xe1ef, 0xe1f0,
+ 0xe1f1, 0xe1f2, 0xe1f3, 0xe1f4, 0xe1f5, 0xe1f6, 0xe1f7, 0xe1f8,
+ 0xe1f9, 0xe1fa, 0xe1fb, 0xe1fc, 0xe240, 0xe241, 0xe242, 0xe243,
+ 0xe244, 0xe245, 0xe246, 0xe247, 0xe248, 0xe249, 0xe24a, 0xe24b,
+ 0xe24c, 0xe24d, 0xe24e, 0xe24f, 0xe250, 0xe251, 0xe252, 0xe253,
+ 0xe254, 0xe255, 0xe256, 0xe257, 0xe258, 0xe259, 0xe25a, 0xe25b,
+ 0xe25c, 0xe25d, 0xe25e, 0xe25f, 0xe260, 0xe261, 0xe262, 0xe263,
+ 0xe264, 0xe265, 0xe266, 0xe267, 0xe268, 0xe269, 0xe26a, 0xe26b,
+ 0xe26c, 0xe26d, 0xe26e, 0xe26f, 0xe270, 0xe271, 0xe272, 0xe273,
+ 0xe274, 0xe275, 0xe276, 0xe277, 0xe278, 0xe279, 0xe27a, 0xe27b,
+ 0xe27c, 0xe27d, 0xe27e, 0xe280, 0xe281, 0xe282, 0xe283, 0xe284,
+ 0xe285, 0xe286, 0xe287, 0xe288, 0xe289, 0xe28a, 0xe28b, 0xe28c,
+ 0xe28d, 0xe28e, 0xe28f, 0xe290, 0xe291, 0xe292, 0xe293, 0xe294,
+ 0xe295, 0xe296, 0xe297, 0xe298, 0xe299, 0xe29a, 0xe29b, 0xe29c,
+ 0xe29d, 0xe29e, 0xe29f, 0xe2a0, 0xe2a1, 0xe2a2, 0xe2a3, 0xe2a4,
+ 0xe2a5, 0xe2a6, 0xe2a7, 0xe2a8, 0xe2a9, 0xe2aa, 0xe2ab, 0xe2ac,
+ 0xe2ad, 0xe2ae, 0xe2af, 0xe2b0, 0xe2b1, 0xe2b2, 0xe2b3, 0xe2b4,
+ 0xe2b5, 0xe2b6, 0xe2b7, 0xe2b8, 0xe2b9, 0xe2ba, 0xe2bb, 0xe2bc,
+ 0xe2bd, 0xe2be, 0xe2bf, 0xe2c0, 0xe2c1, 0xe2c2, 0xe2c3, 0xe2c4,
+ 0xe2c5, 0xe2c6, 0xe2c7, 0xe2c8, 0xe2c9, 0xe2ca, 0xe2cb, 0xe2cc,
+ 0xe2cd, 0xe2ce, 0xe2cf, 0xe2d0, 0xe2d1, 0xe2d2, 0xe2d3, 0xe2d4,
+ 0xe2d5, 0xe2d6, 0xe2d7, 0xe2d8, 0xe2d9, 0xe2da, 0xe2db, 0xe2dc,
+ 0xe2dd, 0xe2de, 0xe2df, 0xe2e0, 0xe2e1, 0xe2e2, 0xe2e3, 0xe2e4,
+ 0xe2e5, 0xe2e6, 0xe2e7, 0xe2e8, 0xe2e9, 0xe2ea, 0xe2eb, 0xe2ec,
+ 0xe2ed, 0xe2ee, 0xe2ef, 0xe2f0, 0xe2f1, 0xe2f2, 0xe2f3, 0xe2f4,
+ 0xe2f5, 0xe2f6, 0xe2f7, 0xe2f8, 0xe2f9, 0xe2fa, 0xe2fb, 0xe2fc,
+ 0xe340, 0xe341, 0xe342, 0xe343, 0xe344, 0xe345, 0xe346, 0xe347,
+ 0xe348, 0xe349, 0xe34a, 0xe34b, 0xe34c, 0xe34d, 0xe34e, 0xe34f,
+ 0xe350, 0xe351, 0xe352, 0xe353, 0xe354, 0xe355, 0xe356, 0xe357,
+ 0xe358, 0xe359, 0xe35a, 0xe35b, 0xe35c, 0xe35d, 0xe35e, 0xe35f,
+ 0xe360, 0xe361, 0xe362, 0xe363, 0xe364, 0xe365, 0xe366, 0xe367,
+ 0xe368, 0xe369, 0xe36a, 0xe36b, 0xe36c, 0xe36d, 0xe36e, 0xe36f,
+ 0xe370, 0xe371, 0xe372, 0xe373, 0xe374, 0xe375, 0xe376, 0xe377,
+ 0xe378, 0xe379, 0xe37a, 0xe37b, 0xe37c, 0xe37d, 0xe37e, 0xe380,
+ 0xe381, 0xe382, 0xe383, 0xe384, 0xe385, 0xe386, 0xe387, 0xe388,
+ 0xe389, 0xe38a, 0xe38b, 0xe38c, 0xe38d, 0xe38e, 0xe38f, 0xe390,
+ 0xe391, 0xe392, 0xe393, 0xe394, 0xe395, 0xe396, 0xe397, 0xe398,
+ 0xe399, 0xe39a, 0xe39b, 0xe39c, 0xe39d, 0xe39e, 0xe39f, 0xe3a0,
+ 0xe3a1, 0xe3a2, 0xe3a3, 0xe3a4, 0xe3a5, 0xe3a6, 0xe3a7, 0xe3a8,
+ 0xe3a9, 0xe3aa, 0xe3ab, 0xe3ac, 0xe3ad, 0xe3ae, 0xe3af, 0xe3b0,
+ 0xe3b1, 0xe3b2, 0xe3b3, 0xe3b4, 0xe3b5, 0xe3b6, 0xe3b7, 0xe3b8,
+ 0xe3b9, 0xe3ba, 0xe3bb, 0xe3bc, 0xe3bd, 0xe3be, 0xe3bf, 0xe3c0,
+ 0xe3c1, 0xe3c2, 0xe3c3, 0xe3c4, 0xe3c5, 0xe3c6, 0xe3c7, 0xe3c8,
+ 0xe3c9, 0xe3ca, 0xe3cb, 0xe3cc, 0xe3cd, 0xe3ce, 0xe3cf, 0xe3d0,
+ 0xe3d1, 0xe3d2, 0xe3d3, 0xe3d4, 0xe3d5, 0xe3d6, 0xe3d7, 0xe3d8,
+ 0xe3d9, 0xe3da, 0xe3db, 0xe3dc, 0xe3dd, 0xe3de, 0xe3df, 0xe3e0,
+ 0xe3e1, 0xe3e2, 0xe3e3, 0xe3e4, 0xe3e5, 0xe3e6, 0xe3e7, 0xe3e8,
+ 0xe3e9, 0xe3ea, 0xe3eb, 0xe3ec, 0xe3ed, 0xe3ee, 0xe3ef, 0xe3f0,
+ 0xe3f1, 0xe3f2, 0xe3f3, 0xe3f4, 0xe3f5, 0xe3f6, 0xe3f7, 0xe3f8,
+ 0xe3f9, 0xe3fa, 0xe3fb, 0xe3fc, 0xe440, 0xe441, 0xe442, 0xe443,
+ 0xe444, 0xe445, 0xe446, 0xe447, 0xe448, 0xe449, 0xe44a, 0xe44b,
+ 0xe44c, 0xe44d, 0xe44e, 0xe44f, 0xe450, 0xe451, 0xe452, 0xe453,
+ 0xe454, 0xe455, 0xe456, 0xe457, 0xe458, 0xe459, 0xe45a, 0xe45b,
+ 0xe45c, 0xe45d, 0xe45e, 0xe45f, 0xe460, 0xe461, 0xe462, 0xe463,
+ 0xe464, 0xe465, 0xe466, 0xe467, 0xe468, 0xe469, 0xe46a, 0xe46b,
+ 0xe46c, 0xe46d, 0xe46e, 0xe46f, 0xe470, 0xe471, 0xe472, 0xe473,
+ 0xe474, 0xe475, 0xe476, 0xe477, 0xe478, 0xe479, 0xe47a, 0xe47b,
+ 0xe47c, 0xe47d, 0xe47e, 0xe480, 0xe481, 0xe482, 0xe483, 0xe484,
+ 0xe485, 0xe486, 0xe487, 0xe488, 0xe489, 0xe48a, 0xe48b, 0xe48c,
+ 0xe48d, 0xe48e, 0xe48f, 0xe490, 0xe491, 0xe492, 0xe493, 0xe494,
+ 0xe495, 0xe496, 0xe497, 0xe498, 0xe499, 0xe49a, 0xe49b, 0xe49c,
+ 0xe49d, 0xe49e, 0xe49f, 0xe4a0, 0xe4a1, 0xe4a2, 0xe4a3, 0xe4a4,
+ 0xe4a5, 0xe4a6, 0xe4a7, 0xe4a8, 0xe4a9, 0xe4aa, 0xe4ab, 0xe4ac,
+ 0xe4ad, 0xe4ae, 0xe4af, 0xe4b0, 0xe4b1, 0xe4b2, 0xe4b3, 0xe4b4,
+ 0xe4b5, 0xe4b6, 0xe4b7, 0xe4b8, 0xe4b9, 0xe4ba, 0xe4bb, 0xe4bc,
+ 0xe4bd, 0xe4be, 0xe4bf, 0xe4c0, 0xe4c1, 0xe4c2, 0xe4c3, 0xe4c4,
+ 0xe4c5, 0xe4c6, 0xe4c7, 0xe4c8, 0xe4c9, 0xe4ca, 0xe4cb, 0xe4cc,
+ 0xe4cd, 0xe4ce, 0xe4cf, 0xe4d0, 0xe4d1, 0xe4d2, 0xe4d3, 0xe4d4,
+ 0xe4d5, 0xe4d6, 0xe4d7, 0xe4d8, 0xe4d9, 0xe4da, 0xe4db, 0xe4dc,
+ 0xe4dd, 0xe4de, 0xe4df, 0xe4e0, 0xe4e1, 0xe4e2, 0xe4e3, 0xe4e4,
+ 0xe4e5, 0xe4e6, 0xe4e7, 0xe4e8, 0xe4e9, 0xe4ea, 0xe4eb, 0xe4ec,
+ 0xe4ed, 0xe4ee, 0xe4ef, 0xe4f0, 0xe4f1, 0xe4f2, 0xe4f3, 0xe4f4,
+ 0xe4f5, 0xe4f6, 0xe4f7, 0xe4f8, 0xe4f9, 0xe4fa, 0xe4fb, 0xe4fc,
+ 0xe540, 0xe541, 0xe542, 0xe543, 0xe544, 0xe545, 0xe546, 0xe547,
+ 0xe548, 0xe549, 0xe54a, 0xe54b, 0xe54c, 0xe54d, 0xe54e, 0xe54f,
+ 0xe550, 0xe551, 0xe552, 0xe553, 0xe554, 0xe555, 0xe556, 0xe557,
+ 0xe558, 0xe559, 0xe55a, 0xe55b, 0xe55c, 0xe55d, 0xe55e, 0xe55f,
+ 0xe560, 0xe561, 0xe562, 0xe563, 0xe564, 0xe565, 0xe566, 0xe567,
+ 0xe568, 0xe569, 0xe56a, 0xe56b, 0xe56c, 0xe56d, 0xe56e, 0xe56f,
+ 0xe570, 0xe571, 0xe572, 0xe573, 0xe574, 0xe575, 0xe576, 0xe577,
+ 0xe578, 0xe579, 0xe57a, 0xe57b, 0xe57c, 0xe57d, 0xe57e, 0xe580,
+ 0xe581, 0xe582, 0xe583, 0xe584, 0xe585, 0xe586, 0xe587, 0xe588,
+ 0xe589, 0xe58a, 0xe58b, 0xe58c, 0xe58d, 0xe58e, 0xe58f, 0xe590,
+ 0xe591, 0xe592, 0xe593, 0xe594, 0xe595, 0xe596, 0xe597, 0xe598,
+ 0xe599, 0xe59a, 0xe59b, 0xe59c, 0xe59d, 0xe59e, 0xe59f, 0xe5a0,
+ 0xe5a1, 0xe5a2, 0xe5a3, 0xe5a4, 0xe5a5, 0xe5a6, 0xe5a7, 0xe5a8,
+ 0xe5a9, 0xe5aa, 0xe5ab, 0xe5ac, 0xe5ad, 0xe5ae, 0xe5af, 0xe5b0,
+ 0xe5b1, 0xe5b2, 0xe5b3, 0xe5b4, 0xe5b5, 0xe5b6, 0xe5b7, 0xe5b8,
+ 0xe5b9, 0xe5ba, 0xe5bb, 0xe5bc, 0xe5bd, 0xe5be, 0xe5bf, 0xe5c0,
+ 0xe5c1, 0xe5c2, 0xe5c3, 0xe5c4, 0xe5c5, 0xe5c6, 0xe5c7, 0xe5c8,
+ 0xe5c9, 0xe5ca, 0xe5cb, 0xe5cc, 0xe5cd, 0xe5ce, 0xe5cf, 0xe5d0,
+ 0xe5d1, 0xe5d2, 0xe5d3, 0xe5d4, 0xe5d5, 0xe5d6, 0xe5d7, 0xe5d8,
+ 0xe5d9, 0xe5da, 0xe5db, 0xe5dc, 0xe5dd, 0xe5de, 0xe5df, 0xe5e0,
+ 0xe5e1, 0xe5e2, 0xe5e3, 0xe5e4, 0xe5e5, 0xe5e6, 0xe5e7, 0xe5e8,
+ 0xe5e9, 0xe5ea, 0xe5eb, 0xe5ec, 0xe5ed, 0xe5ee, 0xe5ef, 0xe5f0,
+ 0xe5f1, 0xe5f2, 0xe5f3, 0xe5f4, 0xe5f5, 0xe5f6, 0xe5f7, 0xe5f8,
+ 0xe5f9, 0xe5fa, 0xe5fb, 0xe5fc, 0xe640, 0xe641, 0xe642, 0xe643,
+ 0xe644, 0xe645, 0xe646, 0xe647, 0xe648, 0xe649, 0xe64a, 0xe64b,
+ 0xe64c, 0xe64d, 0xe64e, 0xe64f, 0xe650, 0xe651, 0xe652, 0xe653,
+ 0xe654, 0xe655, 0xe656, 0xe657, 0xe658, 0xe659, 0xe65a, 0xe65b,
+ 0xe65c, 0xe65d, 0xe65e, 0xe65f, 0xe660, 0xe661, 0xe662, 0xe663,
+ 0xe664, 0xe665, 0xe666, 0xe667, 0xe668, 0xe669, 0xe66a, 0xe66b,
+ 0xe66c, 0xe66d, 0xe66e, 0xe66f, 0xe670, 0xe671, 0xe672, 0xe673,
+ 0xe674, 0xe675, 0xe676, 0xe677, 0xe678, 0xe679, 0xe67a, 0xe67b,
+ 0xe67c, 0xe67d, 0xe67e, 0xe680, 0xe681, 0xe682, 0xe683, 0xe684,
+ 0xe685, 0xe686, 0xe687, 0xe688, 0xe689, 0xe68a, 0xe68b, 0xe68c,
+ 0xe68d, 0xe68e, 0xe68f, 0xe690, 0xe691, 0xe692, 0xe693, 0xe694,
+ 0xe695, 0xe696, 0xe697, 0xe698, 0xe699, 0xe69a, 0xe69b, 0xe69c,
+ 0xe69d, 0xe69e, 0xe69f, 0xe6a0, 0xe6a1, 0xe6a2, 0xe6a3, 0xe6a4,
+ 0xe6a5, 0xe6a6, 0xe6a7, 0xe6a8, 0xe6a9, 0xe6aa, 0xe6ab, 0xe6ac,
+ 0xe6ad, 0xe6ae, 0xe6af, 0xe6b0, 0xe6b1, 0xe6b2, 0xe6b3, 0xe6b4,
+ 0xe6b5, 0xe6b6, 0xe6b7, 0xe6b8, 0xe6b9, 0xe6ba, 0xe6bb, 0xe6bc,
+ 0xe6bd, 0xe6be, 0xe6bf, 0xe6c0, 0xe6c1, 0xe6c2, 0xe6c3, 0xe6c4,
+ 0xe6c5, 0xe6c6, 0xe6c7, 0xe6c8, 0xe6c9, 0xe6ca, 0xe6cb, 0xe6cc,
+ 0xe6cd, 0xe6ce, 0xe6cf, 0xe6d0, 0xe6d1, 0xe6d2, 0xe6d3, 0xe6d4,
+ 0xe6d5, 0xe6d6, 0xe6d7, 0xe6d8, 0xe6d9, 0xe6da, 0xe6db, 0xe6dc,
+ 0xe6dd, 0xe6de, 0xe6df, 0xe6e0, 0xe6e1, 0xe6e2, 0xe6e3, 0xe6e4,
+ 0xe6e5, 0xe6e6, 0xe6e7, 0xe6e8, 0xe6e9, 0xe6ea, 0xe6eb, 0xe6ec,
+ 0xe6ed, 0xe6ee, 0xe6ef, 0xe6f0, 0xe6f1, 0xe6f2, 0xe6f3, 0xe6f4,
+ 0xe6f5, 0xe6f6, 0xe6f7, 0xe6f8, 0xe6f9, 0xe6fa, 0xe6fb, 0xe6fc,
+ 0xe740, 0xe741, 0xe742, 0xe743, 0xe744, 0xe745, 0xe746, 0xe747,
+ 0xe748, 0xe749, 0xe74a, 0xe74b, 0xe74c, 0xe74d, 0xe74e, 0xe74f,
+ 0xe750, 0xe751, 0xe752, 0xe753, 0xe754, 0xe755, 0xe756, 0xe757,
+ 0xe758, 0xe759, 0xe75a, 0xe75b, 0xe75c, 0xe75d, 0xe75e, 0xe75f,
+ 0xe760, 0xe761, 0xe762, 0xe763, 0xe764, 0xe765, 0xe766, 0xe767,
+ 0xe768, 0xe769, 0xe76a, 0xe76b, 0xe76c, 0xe76d, 0xe76e, 0xe76f,
+ 0xe770, 0xe771, 0xe772, 0xe773, 0xe774, 0xe775, 0xe776, 0xe777,
+ 0xe778, 0xe779, 0xe77a, 0xe77b, 0xe77c, 0xe77d, 0xe77e, 0xe780,
+ 0xe781, 0xe782, 0xe783, 0xe784, 0xe785, 0xe786, 0xe787, 0xe788,
+ 0xe789, 0xe78a, 0xe78b, 0xe78c, 0xe78d, 0xe78e, 0xe78f, 0xe790,
+ 0xe791, 0xe792, 0xe793, 0xe794, 0xe795, 0xe796, 0xe797, 0xe798,
+ 0xe799, 0xe79a, 0xe79b, 0xe79c, 0xe79d, 0xe79e, 0xe79f, 0xe7a0,
+ 0xe7a1, 0xe7a2, 0xe7a3, 0xe7a4, 0xe7a5, 0xe7a6, 0xe7a7, 0xe7a8,
+ 0xe7a9, 0xe7aa, 0xe7ab, 0xe7ac, 0xe7ad, 0xe7ae, 0xe7af, 0xe7b0,
+ 0xe7b1, 0xe7b2, 0xe7b3, 0xe7b4, 0xe7b5, 0xe7b6, 0xe7b7, 0xe7b8,
+ 0xe7b9, 0xe7ba, 0xe7bb, 0xe7bc, 0xe7bd, 0xe7be, 0xe7bf, 0xe7c0,
+ 0xe7c1, 0xe7c2, 0xe7c3, 0xe7c4, 0xe7c5, 0xe7c6, 0xe7c7, 0xe7c8,
+ 0xe7c9, 0xe7ca, 0xe7cb, 0xe7cc, 0xe7cd, 0xe7ce, 0xe7cf, 0xe7d0,
+ 0xe7d1, 0xe7d2, 0xe7d3, 0xe7d4, 0xe7d5, 0xe7d6, 0xe7d7, 0xe7d8,
+ 0xe7d9, 0xe7da, 0xe7db, 0xe7dc, 0xe7dd, 0xe7de, 0xe7df, 0xe7e0,
+ 0xe7e1, 0xe7e2, 0xe7e3, 0xe7e4, 0xe7e5, 0xe7e6, 0xe7e7, 0xe7e8,
+ 0xe7e9, 0xe7ea, 0xe7eb, 0xe7ec, 0xe7ed, 0xe7ee, 0xe7ef, 0xe7f0,
+ 0xe7f1, 0xe7f2, 0xe7f3, 0xe7f4, 0xe7f5, 0xe7f6, 0xe7f7, 0xe7f8,
+ 0xe7f9, 0xe7fa, 0xe7fb, 0xe7fc, 0xe840, 0xe841, 0xe842, 0xe843,
+ 0xe844, 0xe845, 0xe846, 0xe847, 0xe848, 0xe849, 0xe84a, 0xe84b,
+ 0xe84c, 0xe84d, 0xe84e, 0xe84f, 0xe850, 0xe851, 0xe852, 0xe853,
+ 0xe854, 0xe855, 0xe856, 0xe857, 0xe858, 0xe859, 0xe85a, 0xe85b,
+ 0xe85c, 0xe85d, 0xe85e, 0xe85f, 0xe860, 0xe861, 0xe862, 0xe863,
+ 0xe864, 0xe865, 0xe866, 0xe867, 0xe868, 0xe869, 0xe86a, 0xe86b,
+ 0xe86c, 0xe86d, 0xe86e, 0xe86f, 0xe870, 0xe871, 0xe872, 0xe873,
+ 0xe874, 0xe875, 0xe876, 0xe877, 0xe878, 0xe879, 0xe87a, 0xe87b,
+ 0xe87c, 0xe87d, 0xe87e, 0xe880, 0xe881, 0xe882, 0xe883, 0xe884,
+ 0xe885, 0xe886, 0xe887, 0xe888, 0xe889, 0xe88a, 0xe88b, 0xe88c,
+ 0xe88d, 0xe88e, 0xe88f, 0xe890, 0xe891, 0xe892, 0xe893, 0xe894,
+ 0xe895, 0xe896, 0xe897, 0xe898, 0xe899, 0xe89a, 0xe89b, 0xe89c,
+ 0xe89d, 0xe89e, 0xe89f, 0xe8a0, 0xe8a1, 0xe8a2, 0xe8a3, 0xe8a4,
+ 0xe8a5, 0xe8a6, 0xe8a7, 0xe8a8, 0xe8a9, 0xe8aa, 0xe8ab, 0xe8ac,
+ 0xe8ad, 0xe8ae, 0xe8af, 0xe8b0, 0xe8b1, 0xe8b2, 0xe8b3, 0xe8b4,
+ 0xe8b5, 0xe8b6, 0xe8b7, 0xe8b8, 0xe8b9, 0xe8ba, 0xe8bb, 0xe8bc,
+ 0xe8bd, 0xe8be, 0xe8bf, 0xe8c0, 0xe8c1, 0xe8c2, 0xe8c3, 0xe8c4,
+ 0xe8c5, 0xe8c6, 0xe8c7, 0xe8c8, 0xe8c9, 0xe8ca, 0xe8cb, 0xe8cc,
+ 0xe8cd, 0xe8ce, 0xe8cf, 0xe8d0, 0xe8d1, 0xe8d2, 0xe8d3, 0xe8d4,
+ 0xe8d5, 0xe8d6, 0xe8d7, 0xe8d8, 0xe8d9, 0xe8da, 0xe8db, 0xe8dc,
+ 0xe8dd, 0xe8de, 0xe8df, 0xe8e0, 0xe8e1, 0xe8e2, 0xe8e3, 0xe8e4,
+ 0xe8e5, 0xe8e6, 0xe8e7, 0xe8e8, 0xe8e9, 0xe8ea, 0xe8eb, 0xe8ec,
+ 0xe8ed, 0xe8ee, 0xe8ef, 0xe8f0, 0xe8f1, 0xe8f2, 0xe8f3, 0xe8f4,
+ 0xe8f5, 0xe8f6, 0xe8f7, 0xe8f8, 0xe8f9, 0xe8fa, 0xe8fb, 0xe8fc,
+ 0xe940, 0xe941, 0xe942, 0xe943, 0xe944, 0xe945, 0xe946, 0xe947,
+ 0xe948, 0xe949, 0xe94a, 0xe94b, 0xe94c, 0xe94d, 0xe94e, 0xe94f,
+ 0xe950, 0xe951, 0xe952, 0xe953, 0xe954, 0xe955, 0xe956, 0xe957,
+ 0xe958, 0xe959, 0xe95a, 0xe95b, 0xe95c, 0xe95d, 0xe95e, 0xe95f,
+ 0xe960, 0xe961, 0xe962, 0xe963, 0xe964, 0xe965, 0xe966, 0xe967,
+ 0xe968, 0xe969, 0xe96a, 0xe96b, 0xe96c, 0xe96d, 0xe96e, 0xe96f,
+ 0xe970, 0xe971, 0xe972, 0xe973, 0xe974, 0xe975, 0xe976, 0xe977,
+ 0xe978, 0xe979, 0xe97a, 0xe97b, 0xe97c, 0xe97d, 0xe97e, 0xe980,
+ 0xe981, 0xe982, 0xe983, 0xe984, 0xe985, 0xe986, 0xe987, 0xe988,
+ 0xe989, 0xe98a, 0xe98b, 0xe98c, 0xe98d, 0xe98e, 0xe98f, 0xe990,
+ 0xe991, 0xe992, 0xe993, 0xe994, 0xe995, 0xe996, 0xe997, 0xe998,
+ 0xe999, 0xe99a, 0xe99b, 0xe99c, 0xe99d, 0xe99e, 0xe99f, 0xe9a0,
+ 0xe9a1, 0xe9a2, 0xe9a3, 0xe9a4, 0xe9a5, 0xe9a6, 0xe9a7, 0xe9a8,
+ 0xe9a9, 0xe9aa, 0xe9ab, 0xe9ac, 0xe9ad, 0xe9ae, 0xe9af, 0xe9b0,
+ 0xe9b1, 0xe9b2, 0xe9b3, 0xe9b4, 0xe9b5, 0xe9b6, 0xe9b7, 0xe9b8,
+ 0xe9b9, 0xe9ba, 0xe9bb, 0xe9bc, 0xe9bd, 0xe9be, 0xe9bf, 0xe9c0,
+ 0xe9c1, 0xe9c2, 0xe9c3, 0xe9c4, 0xe9c5, 0xe9c6, 0xe9c7, 0xe9c8,
+ 0xe9c9, 0xe9ca, 0xe9cb, 0xe9cc, 0xe9cd, 0xe9ce, 0xe9cf, 0xe9d0,
+ 0xe9d1, 0xe9d2, 0xe9d3, 0xe9d4, 0xe9d5, 0xe9d6, 0xe9d7, 0xe9d8,
+ 0xe9d9, 0xe9da, 0xe9db, 0xe9dc, 0xe9dd, 0xe9de, 0xe9df, 0xe9e0,
+ 0xe9e1, 0xe9e2, 0xe9e3, 0xe9e4, 0xe9e5, 0xe9e6, 0xe9e7, 0xe9e8,
+ 0xe9e9, 0xe9ea, 0xe9eb, 0xe9ec, 0xe9ed, 0xe9ee, 0xe9ef, 0xe9f0,
+ 0xe9f1, 0xe9f2, 0xe9f3, 0xe9f4, 0xe9f5, 0xe9f6, 0xe9f7, 0xe9f8,
+ 0xe9f9, 0xe9fa, 0xe9fb, 0xe9fc, 0xea40, 0xea41, 0xea42, 0xea43,
+ 0xea44, 0xea45, 0xea46, 0xea47, 0xea48, 0xea49, 0xea4a, 0xea4b,
+ 0xea4c, 0xea4d, 0xea4e, 0xea4f, 0xea50, 0xea51, 0xea52, 0xea53,
+ 0xea54, 0xea55, 0xea56, 0xea57, 0xea58, 0xea59, 0xea5a, 0xea5b,
+ 0xea5c, 0xea5d, 0xea5e, 0xea5f, 0xea60, 0xea61, 0xea62, 0xea63,
+ 0xea64, 0xea65, 0xea66, 0xea67, 0xea68, 0xea69, 0xea6a, 0xea6b,
+ 0xea6c, 0xea6d, 0xea6e, 0xea6f, 0xea70, 0xea71, 0xea72, 0xea73,
+ 0xea74, 0xea75, 0xea76, 0xea77, 0xea78, 0xea79, 0xea7a, 0xea7b,
+ 0xea7c, 0xea7d, 0xea7e, 0xea80, 0xea81, 0xea82, 0xea83, 0xea84,
+ 0xea85, 0xea86, 0xea87, 0xea88, 0xea89, 0xea8a, 0xea8b, 0xea8c,
+ 0xea8d, 0xea8e, 0xea8f, 0xea90, 0xea91, 0xea92, 0xea93, 0xea94,
+ 0xea95, 0xea96, 0xea97, 0xea98, 0xea99, 0xea9a, 0xea9b, 0xea9c,
+ 0xea9d, 0xea9e, 0xea9f, 0xeaa0, 0xeaa1, 0xeaa2, 0x0020, 0x849f,
+ 0x84aa, 0x84a0, 0x84ab, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x84a1, 0x0020, 0x0020, 0x84ac, 0x84a2,
+ 0x0020, 0x0020, 0x84ad, 0x84a4, 0x0020, 0x0020, 0x84af, 0x84a3,
+ 0x0020, 0x0020, 0x84ae, 0x84a5, 0x84ba, 0x0020, 0x0020, 0x84b5,
+ 0x0020, 0x0020, 0x84b0, 0x84a7, 0x84bc, 0x0020, 0x0020, 0x84b7,
+ 0x0020, 0x0020, 0x84b2, 0x84a6, 0x0020, 0x0020, 0x84b6, 0x84bb,
+ 0x0020, 0x0020, 0x84b1, 0x84a8, 0x0020, 0x0020, 0x84b8, 0x84bd,
+ 0x0020, 0x0020, 0x84b3, 0x84a9, 0x0020, 0x0020, 0x84b9, 0x0020,
+ 0x0020, 0x84be, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x84b4, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
+ 0x0020, 0x0020, 0x0020, 0x0020, 0xeaa3, 0xeaa4
+};
diff --git a/pdftops/Lexer.cxx b/pdftops/Lexer.cxx
new file mode 100644
index 000000000..442566b72
--- /dev/null
+++ b/pdftops/Lexer.cxx
@@ -0,0 +1,472 @@
+//========================================================================
+//
+// Lexer.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <ctype.h>
+#include "Lexer.h"
+#include "Error.h"
+
+//------------------------------------------------------------------------
+
+// A '1' in this array means the character is white space. A '1' or
+// '2' means the character ends a name or command.
+static char specialChars[256] = {
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
+ 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx
+};
+
+//------------------------------------------------------------------------
+// Lexer
+//------------------------------------------------------------------------
+
+Lexer::Lexer(XRef *xref, Stream *str) {
+ Object obj;
+
+ curStr.initStream(str);
+ streams = new Array(xref);
+ streams->add(curStr.copy(&obj));
+ strPtr = 0;
+ freeArray = gTrue;
+ curStr.streamReset();
+}
+
+Lexer::Lexer(XRef *xref, Object *obj) {
+ Object obj2;
+
+ if (obj->isStream()) {
+ streams = new Array(xref);
+ freeArray = gTrue;
+ streams->add(obj->copy(&obj2));
+ } else {
+ streams = obj->getArray();
+ freeArray = gFalse;
+ }
+ strPtr = 0;
+ if (streams->getLength() > 0) {
+ streams->get(strPtr, &curStr);
+ curStr.streamReset();
+ }
+}
+
+Lexer::~Lexer() {
+ if (!curStr.isNone()) {
+ curStr.streamClose();
+ curStr.free();
+ }
+ if (freeArray) {
+ delete streams;
+ }
+}
+
+int Lexer::getChar() {
+ int c;
+
+ c = EOF;
+ while (!curStr.isNone() && (c = curStr.streamGetChar()) == EOF) {
+ curStr.streamClose();
+ curStr.free();
+ ++strPtr;
+ if (strPtr < streams->getLength()) {
+ streams->get(strPtr, &curStr);
+ curStr.streamReset();
+ }
+ }
+ return c;
+}
+
+int Lexer::lookChar() {
+ if (curStr.isNone()) {
+ return EOF;
+ }
+ return curStr.streamLookChar();
+}
+
+Object *Lexer::getObj(Object *obj) {
+ char *p;
+ int c, c2;
+ GBool comment, neg, done;
+ int numParen;
+ int xi;
+ double xf, scale;
+ GString *s;
+ int n, m;
+
+ // skip whitespace and comments
+ comment = gFalse;
+ while (1) {
+ if ((c = getChar()) == EOF) {
+ return obj->initEOF();
+ }
+ if (comment) {
+ if (c == '\r' || c == '\n')
+ comment = gFalse;
+ } else if (c == '%') {
+ comment = gTrue;
+ } else if (specialChars[c] != 1) {
+ break;
+ }
+ }
+
+ // start reading token
+ switch (c) {
+
+ // number
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case '-': case '.':
+ neg = gFalse;
+ xi = 0;
+ if (c == '-') {
+ neg = gTrue;
+ } else if (c == '.') {
+ goto doReal;
+ } else {
+ xi = c - '0';
+ }
+ while (1) {
+ c = lookChar();
+ if (isdigit(c)) {
+ getChar();
+ xi = xi * 10 + (c - '0');
+ } else if (c == '.') {
+ getChar();
+ goto doReal;
+ } else {
+ break;
+ }
+ }
+ if (neg)
+ xi = -xi;
+ obj->initInt(xi);
+ break;
+ doReal:
+ xf = xi;
+ scale = 0.1;
+ while (1) {
+ c = lookChar();
+ if (!isdigit(c)) {
+ break;
+ }
+ getChar();
+ xf = xf + scale * (c - '0');
+ scale *= 0.1;
+ }
+ if (neg)
+ xf = -xf;
+ obj->initReal(xf);
+ break;
+
+ // string
+ case '(':
+ p = tokBuf;
+ n = 0;
+ numParen = 1;
+ done = gFalse;
+ s = NULL;
+ do {
+ c2 = EOF;
+ switch (c = getChar()) {
+
+ case EOF:
+#if 0
+ // This breaks some PDF files, e.g., ones from Photoshop.
+ case '\r':
+ case '\n':
+#endif
+ error(getPos(), "Unterminated string");
+ done = gTrue;
+ break;
+
+ case '(':
+ ++numParen;
+ c2 = c;
+ break;
+
+ case ')':
+ if (--numParen == 0) {
+ done = gTrue;
+ } else {
+ c2 = c;
+ }
+ break;
+
+ case '\\':
+ switch (c = getChar()) {
+ case 'n':
+ c2 = '\n';
+ break;
+ case 'r':
+ c2 = '\r';
+ break;
+ case 't':
+ c2 = '\t';
+ break;
+ case 'b':
+ c2 = '\b';
+ break;
+ case 'f':
+ c2 = '\f';
+ break;
+ case '\\':
+ case '(':
+ case ')':
+ c2 = c;
+ break;
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ c2 = c - '0';
+ c = lookChar();
+ if (c >= '0' && c <= '7') {
+ getChar();
+ c2 = (c2 << 3) + (c - '0');
+ c = lookChar();
+ if (c >= '0' && c <= '7') {
+ getChar();
+ c2 = (c2 << 3) + (c - '0');
+ }
+ }
+ break;
+ case '\r':
+ c = lookChar();
+ if (c == '\n') {
+ getChar();
+ }
+ break;
+ case '\n':
+ break;
+ case EOF:
+ error(getPos(), "Unterminated string");
+ done = gTrue;
+ break;
+ default:
+ c2 = c;
+ break;
+ }
+ break;
+
+ default:
+ c2 = c;
+ break;
+ }
+
+ if (c2 != EOF) {
+ if (n == tokBufSize) {
+ if (!s)
+ s = new GString(tokBuf, tokBufSize);
+ else
+ s->append(tokBuf, tokBufSize);
+ p = tokBuf;
+ n = 0;
+ }
+ *p++ = (char)c2;
+ ++n;
+ }
+ } while (!done);
+ if (!s)
+ s = new GString(tokBuf, n);
+ else
+ s->append(tokBuf, n);
+ obj->initString(s);
+ break;
+
+ // name
+ case '/':
+ p = tokBuf;
+ n = 0;
+ while ((c = lookChar()) != EOF && !specialChars[c]) {
+ getChar();
+ if (c == '#') {
+ c2 = lookChar();
+ if (c2 >= '0' && c2 <= '9') {
+ c = c2 - '0';
+ } else if (c2 >= 'A' && c2 <= 'F') {
+ c = c2 - 'A' + 10;
+ } else if (c2 >= 'a' && c2 <= 'f') {
+ c = c2 - 'a' + 10;
+ } else {
+ goto notEscChar;
+ }
+ getChar();
+ c <<= 4;
+ c2 = getChar();
+ if (c2 >= '0' && c2 <= '9') {
+ c += c2 - '0';
+ } else if (c2 >= 'A' && c2 <= 'F') {
+ c += c2 - 'A' + 10;
+ } else if (c2 >= 'a' && c2 <= 'f') {
+ c += c2 - 'a' + 10;
+ } else {
+ error(getPos(), "Illegal digit in hex char in name");
+ }
+ }
+ notEscChar:
+ if (++n == tokBufSize) {
+ error(getPos(), "Name token too long");
+ break;
+ }
+ *p++ = c;
+ }
+ *p = '\0';
+ obj->initName(tokBuf);
+ break;
+
+ // array punctuation
+ case '[':
+ case ']':
+ tokBuf[0] = c;
+ tokBuf[1] = '\0';
+ obj->initCmd(tokBuf);
+ break;
+
+ // hex string or dict punctuation
+ case '<':
+ c = lookChar();
+
+ // dict punctuation
+ if (c == '<') {
+ getChar();
+ tokBuf[0] = tokBuf[1] = '<';
+ tokBuf[2] = '\0';
+ obj->initCmd(tokBuf);
+
+ // hex string
+ } else {
+ p = tokBuf;
+ m = n = 0;
+ c2 = 0;
+ s = NULL;
+ while (1) {
+ c = getChar();
+ if (c == '>') {
+ break;
+ } else if (c == EOF) {
+ error(getPos(), "Unterminated hex string");
+ break;
+ } else if (specialChars[c] != 1) {
+ c2 = c2 << 4;
+ if (c >= '0' && c <= '9')
+ c2 += c - '0';
+ else if (c >= 'A' && c <= 'F')
+ c2 += c - 'A' + 10;
+ else if (c >= 'a' && c <= 'f')
+ c2 += c - 'a' + 10;
+ else
+ error(getPos(), "Illegal character <%02x> in hex string", c);
+ if (++m == 2) {
+ if (n == tokBufSize) {
+ if (!s)
+ s = new GString(tokBuf, tokBufSize);
+ else
+ s->append(tokBuf, tokBufSize);
+ p = tokBuf;
+ n = 0;
+ }
+ *p++ = (char)c2;
+ ++n;
+ c2 = 0;
+ m = 0;
+ }
+ }
+ }
+ if (!s)
+ s = new GString(tokBuf, n);
+ else
+ s->append(tokBuf, n);
+ if (m == 1)
+ s->append((char)(c2 << 4));
+ obj->initString(s);
+ }
+ break;
+
+ // dict punctuation
+ case '>':
+ c = lookChar();
+ if (c == '>') {
+ getChar();
+ tokBuf[0] = tokBuf[1] = '>';
+ tokBuf[2] = '\0';
+ obj->initCmd(tokBuf);
+ } else {
+ error(getPos(), "Illegal character '>'");
+ obj->initError();
+ }
+ break;
+
+ // error
+ case ')':
+ case '{':
+ case '}':
+ error(getPos(), "Illegal character '%c'", c);
+ obj->initError();
+ break;
+
+ // command
+ default:
+ p = tokBuf;
+ *p++ = c;
+ n = 1;
+ while ((c = lookChar()) != EOF && !specialChars[c]) {
+ getChar();
+ if (++n == tokBufSize) {
+ error(getPos(), "Command token too long");
+ break;
+ }
+ *p++ = c;
+ }
+ *p = '\0';
+ if (tokBuf[0] == 't' && !strcmp(tokBuf, "true")) {
+ obj->initBool(gTrue);
+ } else if (tokBuf[0] == 'f' && !strcmp(tokBuf, "false")) {
+ obj->initBool(gFalse);
+ } else if (tokBuf[0] == 'n' && !strcmp(tokBuf, "null")) {
+ obj->initNull();
+ } else {
+ obj->initCmd(tokBuf);
+ }
+ break;
+ }
+
+ return obj;
+}
+
+void Lexer::skipToNextLine() {
+ int c;
+
+ while (1) {
+ c = getChar();
+ if (c == EOF || c == '\n') {
+ return;
+ }
+ if (c == '\r') {
+ if ((c = lookChar()) == '\n') {
+ getChar();
+ }
+ return;
+ }
+ }
+}
diff --git a/pdftops/Lexer.h b/pdftops/Lexer.h
new file mode 100644
index 000000000..5edbeda6b
--- /dev/null
+++ b/pdftops/Lexer.h
@@ -0,0 +1,74 @@
+//========================================================================
+//
+// Lexer.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef LEXER_H
+#define LEXER_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "Object.h"
+#include "Stream.h"
+
+class XRef;
+
+#define tokBufSize 128 // size of token buffer
+
+//------------------------------------------------------------------------
+// Lexer
+//------------------------------------------------------------------------
+
+class Lexer {
+public:
+
+ // Construct a lexer for a single stream. Deletes the stream when
+ // lexer is deleted.
+ Lexer(XRef *xref, Stream *str);
+
+ // Construct a lexer for a stream or array of streams (assumes obj
+ // is either a stream or array of streams).
+ Lexer(XRef *xref, Object *obj);
+
+ // Destructor.
+ ~Lexer();
+
+ // Get the next object from the input stream.
+ Object *getObj(Object *obj);
+
+ // Skip to the beginning of the next line in the input stream.
+ void skipToNextLine();
+
+ // Skip over one character.
+ void skipChar() { getChar(); }
+
+ // Get stream.
+ Stream *getStream()
+ { return curStr.isNone() ? (Stream *)NULL : curStr.getStream(); }
+
+ // Get current position in file.
+ int getPos()
+ { return curStr.isNone() ? -1 : curStr.streamGetPos(); }
+
+ // Set position in file.
+ void setPos(int pos)
+ { if (!curStr.isNone()) curStr.streamSetPos(pos); }
+
+private:
+
+ int getChar();
+ int lookChar();
+
+ Array *streams; // array of input streams
+ int strPtr; // index of current stream
+ Object curStr; // current stream
+ GBool freeArray; // should lexer free the streams array?
+ char tokBuf[tokBufSize]; // temporary token buffer
+};
+
+#endif
diff --git a/pdftops/Link.cxx b/pdftops/Link.cxx
new file mode 100644
index 000000000..999c1f202
--- /dev/null
+++ b/pdftops/Link.cxx
@@ -0,0 +1,633 @@
+//========================================================================
+//
+// Link.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include "gmem.h"
+#include "GString.h"
+#include "Error.h"
+#include "Object.h"
+#include "Array.h"
+#include "Dict.h"
+#include "Link.h"
+
+//------------------------------------------------------------------------
+
+static GString *getFileSpecName(Object *fileSpecObj);
+
+//------------------------------------------------------------------------
+// LinkDest
+//------------------------------------------------------------------------
+
+LinkDest::LinkDest(Array *a, GBool pageIsRefA) {
+ Object obj1, obj2;
+
+ // initialize fields
+ pageIsRef = pageIsRefA;
+ left = bottom = right = top = zoom = 0;
+ ok = gFalse;
+
+ // get page
+ if (pageIsRef) {
+ if (!a->getNF(0, &obj1)->isRef()) {
+ error(-1, "Bad annotation destination");
+ goto err2;
+ }
+ pageRef.num = obj1.getRefNum();
+ pageRef.gen = obj1.getRefGen();
+ obj1.free();
+ } else {
+ if (!a->get(0, &obj1)->isInt()) {
+ error(-1, "Bad annotation destination");
+ goto err2;
+ }
+ pageNum = obj1.getInt() + 1;
+ obj1.free();
+ }
+
+ // get destination type
+ a->get(1, &obj1);
+
+ // XYZ link
+ if (obj1.isName("XYZ")) {
+ kind = destXYZ;
+ a->get(2, &obj2);
+ if (obj2.isNull()) {
+ changeLeft = gFalse;
+ } else if (obj2.isNum()) {
+ changeLeft = gTrue;
+ left = obj2.getNum();
+ } else {
+ error(-1, "Bad annotation destination position");
+ goto err1;
+ }
+ obj2.free();
+ a->get(3, &obj2);
+ if (obj2.isNull()) {
+ changeTop = gFalse;
+ } else if (obj2.isNum()) {
+ changeTop = gTrue;
+ top = obj2.getNum();
+ } else {
+ error(-1, "Bad annotation destination position");
+ goto err1;
+ }
+ obj2.free();
+ a->get(4, &obj2);
+ if (obj2.isNull()) {
+ changeZoom = gFalse;
+ } else if (obj2.isNum()) {
+ changeZoom = gTrue;
+ zoom = obj2.getNum();
+ } else {
+ error(-1, "Bad annotation destination position");
+ goto err1;
+ }
+ obj2.free();
+
+ // Fit link
+ } else if (obj1.isName("Fit")) {
+ kind = destFit;
+
+ // FitH link
+ } else if (obj1.isName("FitH")) {
+ kind = destFitH;
+ if (!a->get(2, &obj2)->isNum()) {
+ error(-1, "Bad annotation destination position");
+ goto err1;
+ }
+ top = obj2.getNum();
+ obj2.free();
+
+ // FitV link
+ } else if (obj1.isName("FitV")) {
+ kind = destFitV;
+ if (!a->get(2, &obj2)->isNum()) {
+ error(-1, "Bad annotation destination position");
+ goto err1;
+ }
+ left = obj2.getNum();
+ obj2.free();
+
+ // FitR link
+ } else if (obj1.isName("FitR")) {
+ kind = destFitR;
+ if (!a->get(2, &obj2)->isNum()) {
+ error(-1, "Bad annotation destination position");
+ goto err1;
+ }
+ left = obj2.getNum();
+ obj2.free();
+ if (!a->get(3, &obj2)->isNum()) {
+ error(-1, "Bad annotation destination position");
+ goto err1;
+ }
+ bottom = obj2.getNum();
+ obj2.free();
+ if (!a->get(4, &obj2)->isNum()) {
+ error(-1, "Bad annotation destination position");
+ goto err1;
+ }
+ right = obj2.getNum();
+ obj2.free();
+ if (!a->get(5, &obj2)->isNum()) {
+ error(-1, "Bad annotation destination position");
+ goto err1;
+ }
+ top = obj2.getNum();
+ obj2.free();
+
+ // FitB link
+ } else if (obj1.isName("FitB")) {
+ kind = destFitB;
+
+ // FitBH link
+ } else if (obj1.isName("FitBH")) {
+ kind = destFitBH;
+ if (!a->get(2, &obj2)->isNum()) {
+ error(-1, "Bad annotation destination position");
+ goto err1;
+ }
+ top = obj2.getNum();
+ obj2.free();
+
+ // FitBV link
+ } else if (obj1.isName("FitBV")) {
+ kind = destFitBV;
+ if (!a->get(2, &obj2)->isNum()) {
+ error(-1, "Bad annotation destination position");
+ goto err1;
+ }
+ left = obj2.getNum();
+ obj2.free();
+
+ // unknown link kind
+ } else {
+ error(-1, "Unknown annotation destination type");
+ goto err2;
+ }
+
+ obj1.free();
+ ok = gTrue;
+ return;
+
+ err1:
+ obj2.free();
+ err2:
+ obj1.free();
+}
+
+LinkDest::LinkDest(LinkDest *dest) {
+ kind = dest->kind;
+ pageIsRef = dest->pageIsRef;
+ if (pageIsRef)
+ pageRef = dest->pageRef;
+ else
+ pageNum = dest->pageNum;
+ left = dest->left;
+ bottom = dest->bottom;
+ right = dest->right;
+ top = dest->top;
+ zoom = dest->zoom;
+ changeLeft = dest->changeLeft;
+ changeTop = dest->changeTop;
+ changeZoom = dest->changeZoom;
+ ok = gTrue;
+}
+
+//------------------------------------------------------------------------
+// LinkGoTo
+//------------------------------------------------------------------------
+
+LinkGoTo::LinkGoTo(Object *destObj) {
+ dest = NULL;
+ namedDest = NULL;
+
+ // named destination
+ if (destObj->isName()) {
+ namedDest = new GString(destObj->getName());
+ } else if (destObj->isString()) {
+ namedDest = destObj->getString()->copy();
+
+ // destination dictionary
+ } else if (destObj->isArray()) {
+ dest = new LinkDest(destObj->getArray(), gTrue);
+ if (!dest->isOk()) {
+ delete dest;
+ dest = NULL;
+ }
+
+ // error
+ } else {
+ error(-1, "Illegal annotation destination");
+ }
+}
+
+LinkGoTo::~LinkGoTo() {
+ if (dest)
+ delete dest;
+ if (namedDest)
+ delete namedDest;
+}
+
+//------------------------------------------------------------------------
+// LinkGoToR
+//------------------------------------------------------------------------
+
+LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
+ dest = NULL;
+ namedDest = NULL;
+
+ // get file name
+ fileName = getFileSpecName(fileSpecObj);
+
+ // named destination
+ if (destObj->isName()) {
+ namedDest = new GString(destObj->getName());
+ } else if (destObj->isString()) {
+ namedDest = destObj->getString()->copy();
+
+ // destination dictionary
+ } else if (destObj->isArray()) {
+ dest = new LinkDest(destObj->getArray(), gFalse);
+ if (!dest->isOk()) {
+ delete dest;
+ dest = NULL;
+ }
+
+ // error
+ } else {
+ error(-1, "Illegal annotation destination");
+ }
+}
+
+LinkGoToR::~LinkGoToR() {
+ if (fileName)
+ delete fileName;
+ if (dest)
+ delete dest;
+ if (namedDest)
+ delete namedDest;
+}
+
+
+//------------------------------------------------------------------------
+// LinkLaunch
+//------------------------------------------------------------------------
+
+LinkLaunch::LinkLaunch(Object *actionObj) {
+ Object obj1, obj2;
+
+ fileName = NULL;
+ params = NULL;
+
+ if (actionObj->isDict()) {
+ if (!actionObj->dictLookup("F", &obj1)->isNull()) {
+ fileName = getFileSpecName(&obj1);
+ } else {
+ obj1.free();
+ //~ This hasn't been defined by Adobe yet, so assume it looks
+ //~ just like the Win dictionary until they say otherwise.
+ if (actionObj->dictLookup("Unix", &obj1)->isDict()) {
+ obj1.dictLookup("F", &obj2);
+ fileName = getFileSpecName(&obj2);
+ obj2.free();
+ if (obj1.dictLookup("P", &obj2)->isString())
+ params = obj2.getString()->copy();
+ obj2.free();
+ } else {
+ error(-1, "Bad launch-type link action");
+ }
+ }
+ obj1.free();
+ }
+}
+
+LinkLaunch::~LinkLaunch() {
+ if (fileName)
+ delete fileName;
+ if (params)
+ delete params;
+}
+
+//------------------------------------------------------------------------
+// LinkURI
+//------------------------------------------------------------------------
+
+LinkURI::LinkURI(Object *uriObj, GString *baseURI) {
+ GString *uri2;
+ int n;
+ char c;
+
+ uri = NULL;
+ if (uriObj->isString()) {
+ uri2 = uriObj->getString()->copy();
+ if (baseURI) {
+ n = strcspn(uri2->getCString(), "/:");
+ if (n == uri2->getLength() || uri2->getChar(n) == '/') {
+ uri = baseURI->copy();
+ c = uri->getChar(uri->getLength() - 1);
+ if (c == '/' || c == '?') {
+ if (uri2->getChar(0) == '/') {
+ uri2->del(0);
+ }
+ } else {
+ if (uri2->getChar(0) != '/') {
+ uri->append('/');
+ }
+ }
+ uri->append(uri2);
+ delete uri2;
+ } else {
+ uri = uri2;
+ }
+ } else {
+ uri = uri2;
+ }
+ } else {
+ error(-1, "Illegal URI-type link");
+ }
+}
+
+LinkURI::~LinkURI() {
+ if (uri)
+ delete uri;
+}
+
+//------------------------------------------------------------------------
+// LinkNamed
+//------------------------------------------------------------------------
+
+LinkNamed::LinkNamed(Object *nameObj) {
+ name = NULL;
+ if (nameObj->isName()) {
+ name = new GString(nameObj->getName());
+ }
+}
+
+LinkNamed::~LinkNamed() {
+ if (name) {
+ delete name;
+ }
+}
+
+//------------------------------------------------------------------------
+// LinkUnknown
+//------------------------------------------------------------------------
+
+LinkUnknown::LinkUnknown(char *actionA) {
+ action = new GString(actionA);
+}
+
+LinkUnknown::~LinkUnknown() {
+ delete action;
+}
+
+//------------------------------------------------------------------------
+// Link
+//------------------------------------------------------------------------
+
+Link::Link(Dict *dict, GString *baseURI) {
+ Object obj1, obj2, obj3, obj4;
+ double t;
+
+ action = NULL;
+ ok = gFalse;
+
+ // get rectangle
+ if (!dict->lookup("Rect", &obj1)->isArray()) {
+ error(-1, "Annotation rectangle is wrong type");
+ goto err2;
+ }
+ if (!obj1.arrayGet(0, &obj2)->isNum()) {
+ error(-1, "Bad annotation rectangle");
+ goto err1;
+ }
+ x1 = obj2.getNum();
+ obj2.free();
+ if (!obj1.arrayGet(1, &obj2)->isNum()) {
+ error(-1, "Bad annotation rectangle");
+ goto err1;
+ }
+ y1 = obj2.getNum();
+ obj2.free();
+ if (!obj1.arrayGet(2, &obj2)->isNum()) {
+ error(-1, "Bad annotation rectangle");
+ goto err1;
+ }
+ x2 = obj2.getNum();
+ obj2.free();
+ if (!obj1.arrayGet(3, &obj2)->isNum()) {
+ error(-1, "Bad annotation rectangle");
+ goto err1;
+ }
+ y2 = obj2.getNum();
+ obj2.free();
+ obj1.free();
+ if (x1 > x2) {
+ t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+ if (y1 > y2) {
+ t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+
+ // get border
+ borderW = 0;
+ if (!dict->lookup("Border", &obj1)->isNull()) {
+ if (obj1.isArray() && obj1.arrayGetLength() >= 3) {
+ if (obj1.arrayGet(2, &obj2)->isNum()) {
+ borderW = obj2.getNum();
+ } else {
+ error(-1, "Bad annotation border");
+ }
+ obj2.free();
+ }
+ }
+ obj1.free();
+
+ // look for destination
+ if (!dict->lookup("Dest", &obj1)->isNull()) {
+ action = new LinkGoTo(&obj1);
+
+ // look for action
+ } else {
+ obj1.free();
+ if (dict->lookup("A", &obj1)->isDict()) {
+ obj1.dictLookup("S", &obj2);
+
+ // GoTo action
+ if (obj2.isName("GoTo")) {
+ obj1.dictLookup("D", &obj3);
+ action = new LinkGoTo(&obj3);
+ obj3.free();
+
+ // GoToR action
+ } else if (obj2.isName("GoToR")) {
+ obj1.dictLookup("F", &obj3);
+ obj1.dictLookup("D", &obj4);
+ action = new LinkGoToR(&obj3, &obj4);
+ obj3.free();
+ obj4.free();
+
+ // Launch action
+ } else if (obj2.isName("Launch")) {
+ action = new LinkLaunch(&obj1);
+
+ // URI action
+ } else if (obj2.isName("URI")) {
+ obj1.dictLookup("URI", &obj3);
+ action = new LinkURI(&obj3, baseURI);
+ obj3.free();
+
+ // Named action
+ } else if (obj2.isName("Named")) {
+ obj1.dictLookup("N", &obj3);
+ action = new LinkNamed(&obj3);
+ obj3.free();
+
+ // unknown action
+ } else if (obj2.isName()) {
+ action = new LinkUnknown(obj2.getName());
+
+ // action is missing or wrong type
+ } else {
+ error(-1, "Bad annotation action");
+ action = NULL;
+ }
+
+ obj2.free();
+
+ } else {
+ error(-1, "Missing annotation destination/action");
+ action = NULL;
+ }
+ }
+ obj1.free();
+
+ // check for bad action
+ if (action && action->isOk())
+ ok = gTrue;
+
+ return;
+
+ err1:
+ obj2.free();
+ err2:
+ obj1.free();
+}
+
+Link::~Link() {
+ if (action)
+ delete action;
+}
+
+//------------------------------------------------------------------------
+// Links
+//------------------------------------------------------------------------
+
+Links::Links(Object *annots, GString *baseURI) {
+ Link *link;
+ Object obj1, obj2;
+ int size;
+ int i;
+
+ links = NULL;
+ size = 0;
+ numLinks = 0;
+
+ if (annots->isArray()) {
+ for (i = 0; i < annots->arrayGetLength(); ++i) {
+ if (annots->arrayGet(i, &obj1)->isDict()) {
+ if (obj1.dictLookup("Subtype", &obj2)->isName("Link")) {
+ link = new Link(obj1.getDict(), baseURI);
+ if (link->isOk()) {
+ if (numLinks >= size) {
+ size += 16;
+ links = (Link **)grealloc(links, size * sizeof(Link *));
+ }
+ links[numLinks++] = link;
+ } else {
+ delete link;
+ }
+ }
+ obj2.free();
+ }
+ obj1.free();
+ }
+ }
+}
+
+Links::~Links() {
+ int i;
+
+ for (i = 0; i < numLinks; ++i)
+ delete links[i];
+ gfree(links);
+}
+
+LinkAction *Links::find(double x, double y) {
+ int i;
+
+ for (i = 0; i < numLinks; ++i) {
+ if (links[i]->inRect(x, y)) {
+ return links[i]->getAction();
+ }
+ }
+ return NULL;
+}
+
+GBool Links::onLink(double x, double y) {
+ int i;
+
+ for (i = 0; i < numLinks; ++i) {
+ if (links[i]->inRect(x, y))
+ return gTrue;
+ }
+ return gFalse;
+}
+
+//------------------------------------------------------------------------
+
+// Extract a file name from a file specification (string or dictionary).
+static GString *getFileSpecName(Object *fileSpecObj) {
+ GString *name;
+ Object obj1;
+
+ name = NULL;
+
+ // string
+ if (fileSpecObj->isString()) {
+ name = fileSpecObj->getString()->copy();
+
+ // dictionary
+ } else if (fileSpecObj->isDict()) {
+ if (!fileSpecObj->dictLookup("Unix", &obj1)->isString()) {
+ obj1.free();
+ fileSpecObj->dictLookup("F", &obj1);
+ }
+ if (obj1.isString())
+ name = obj1.getString()->copy();
+ else
+ error(-1, "Illegal file spec in link");
+ obj1.free();
+
+ // error
+ } else {
+ error(-1, "Illegal file spec in link");
+ }
+
+ return name;
+}
diff --git a/pdftops/Link.h b/pdftops/Link.h
new file mode 100644
index 000000000..4d1672478
--- /dev/null
+++ b/pdftops/Link.h
@@ -0,0 +1,336 @@
+//========================================================================
+//
+// Link.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef LINK_H
+#define LINK_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "Object.h"
+
+class GString;
+class Array;
+class Dict;
+
+//------------------------------------------------------------------------
+// LinkAction
+//------------------------------------------------------------------------
+
+enum LinkActionKind {
+ actionGoTo, // go to destination
+ actionGoToR, // go to destination in new file
+ actionLaunch, // launch app (or open document)
+ actionURI, // URI
+ actionNamed, // named action
+ actionUnknown // anything else
+};
+
+class LinkAction {
+public:
+
+ // Destructor.
+ virtual ~LinkAction() {}
+
+ // Was the LinkAction created successfully?
+ virtual GBool isOk() = 0;
+
+ // Check link action type.
+ virtual LinkActionKind getKind() = 0;
+};
+
+//------------------------------------------------------------------------
+// LinkDest
+//------------------------------------------------------------------------
+
+enum LinkDestKind {
+ destXYZ,
+ destFit,
+ destFitH,
+ destFitV,
+ destFitR,
+ destFitB,
+ destFitBH,
+ destFitBV
+};
+
+class LinkDest {
+public:
+
+ // Build a LinkDest from the array. If <pageIsRef> is true, the
+ // page is specified by an object reference; otherwise the page is
+ // specified by a (zero-relative) page number.
+ LinkDest(Array *a, GBool pageIsRef1);
+
+ // Copy a LinkDest.
+ LinkDest *copy() { return new LinkDest(this); }
+
+ // Was the LinkDest created successfully?
+ GBool isOk() { return ok; }
+
+ // Accessors.
+ LinkDestKind getKind() { return kind; }
+ GBool isPageRef() { return pageIsRef; }
+ int getPageNum() { return pageNum; }
+ Ref getPageRef() { return pageRef; }
+ double getLeft() { return left; }
+ double getBottom() { return bottom; }
+ double getRight() { return right; }
+ double getTop() { return top; }
+ double getZoom() { return zoom; }
+ GBool getChangeLeft() { return changeLeft; }
+ GBool getChangeTop() { return changeTop; }
+ GBool getChangeZoom() { return changeZoom; }
+
+private:
+
+ LinkDestKind kind; // destination type
+ GBool pageIsRef; // is the page a reference or number?
+ union {
+ Ref pageRef; // reference to page
+ int pageNum; // one-relative page number
+ };
+ double left, bottom; // position
+ double right, top;
+ double zoom; // zoom factor
+ GBool changeLeft, changeTop; // for destXYZ links, which position
+ GBool changeZoom; // components to change
+ GBool ok; // set if created successfully
+
+ LinkDest(LinkDest *dest);
+};
+
+//------------------------------------------------------------------------
+// LinkGoTo
+//------------------------------------------------------------------------
+
+class LinkGoTo: public LinkAction {
+public:
+
+ // Build a LinkGoTo from a destination (dictionary, name, or string).
+ LinkGoTo(Object *destObj);
+
+ // Destructor.
+ virtual ~LinkGoTo();
+
+ // Was the LinkGoTo created successfully?
+ virtual GBool isOk() { return dest || namedDest; }
+
+ // Accessors.
+ virtual LinkActionKind getKind() { return actionGoTo; }
+ LinkDest *getDest() { return dest; }
+ GString *getNamedDest() { return namedDest; }
+
+private:
+
+ LinkDest *dest; // regular destination (NULL for remote
+ // link with bad destination)
+ GString *namedDest; // named destination (only one of dest and
+ // and namedDest may be non-NULL)
+};
+
+//------------------------------------------------------------------------
+// LinkGoToR
+//------------------------------------------------------------------------
+
+class LinkGoToR: public LinkAction {
+public:
+
+ // Build a LinkGoToR from a file spec (dictionary) and destination
+ // (dictionary, name, or string).
+ LinkGoToR(Object *fileSpecObj, Object *destObj);
+
+ // Destructor.
+ virtual ~LinkGoToR();
+
+ // Was the LinkGoToR created successfully?
+ virtual GBool isOk() { return fileName && (dest || namedDest); }
+
+ // Accessors.
+ virtual LinkActionKind getKind() { return actionGoToR; }
+ GString *getFileName() { return fileName; }
+ LinkDest *getDest() { return dest; }
+ GString *getNamedDest() { return namedDest; }
+
+private:
+
+ GString *fileName; // file name
+ LinkDest *dest; // regular destination (NULL for remote
+ // link with bad destination)
+ GString *namedDest; // named destination (only one of dest and
+ // and namedDest may be non-NULL)
+};
+
+//------------------------------------------------------------------------
+// LinkLaunch
+//------------------------------------------------------------------------
+
+class LinkLaunch: public LinkAction {
+public:
+
+ // Build a LinkLaunch from an action dictionary.
+ LinkLaunch(Object *actionObj);
+
+ // Destructor.
+ virtual ~LinkLaunch();
+
+ // Was the LinkLaunch created successfully?
+ virtual GBool isOk() { return fileName != NULL; }
+
+ // Accessors.
+ virtual LinkActionKind getKind() { return actionLaunch; }
+ GString *getFileName() { return fileName; }
+ GString *getParams() { return params; }
+
+private:
+
+ GString *fileName; // file name
+ GString *params; // parameters
+};
+
+//------------------------------------------------------------------------
+// LinkURI
+//------------------------------------------------------------------------
+
+class LinkURI: public LinkAction {
+public:
+
+ // Build a LinkURI given the URI (string) and base URI.
+ LinkURI(Object *uriObj, GString *baseURI);
+
+ // Destructor.
+ virtual ~LinkURI();
+
+ // Was the LinkURI created successfully?
+ virtual GBool isOk() { return uri != NULL; }
+
+ // Accessors.
+ virtual LinkActionKind getKind() { return actionURI; }
+ GString *getURI() { return uri; }
+
+private:
+
+ GString *uri; // the URI
+};
+
+//------------------------------------------------------------------------
+// LinkNamed
+//------------------------------------------------------------------------
+
+class LinkNamed: public LinkAction {
+public:
+
+ // Build a LinkNamed given the action name.
+ LinkNamed(Object *nameObj);
+
+ virtual ~LinkNamed();
+
+ virtual GBool isOk() { return name != NULL; }
+
+ virtual LinkActionKind getKind() { return actionNamed; }
+ GString *getName() { return name; }
+
+private:
+
+ GString *name;
+};
+
+//------------------------------------------------------------------------
+// LinkUnknown
+//------------------------------------------------------------------------
+
+class LinkUnknown: public LinkAction {
+public:
+
+ // Build a LinkUnknown with the specified action type.
+ LinkUnknown(char *actionA);
+
+ // Destructor.
+ virtual ~LinkUnknown();
+
+ // Was the LinkUnknown create successfully?
+ virtual GBool isOk() { return action != NULL; }
+
+ // Accessors.
+ virtual LinkActionKind getKind() { return actionUnknown; }
+ GString *getAction() { return action; }
+
+private:
+
+ GString *action; // action subtype
+};
+
+//------------------------------------------------------------------------
+// Link
+//------------------------------------------------------------------------
+
+class Link {
+public:
+
+ // Construct a link, given its dictionary.
+ Link(Dict *dict, GString *baseURI);
+
+ // Destructor.
+ ~Link();
+
+ // Was the link created successfully?
+ GBool isOk() { return ok; }
+
+ // Check if point is inside the link rectangle.
+ GBool inRect(double x, double y)
+ { return x1 <= x && x <= x2 && y1 <= y && y <= y2; }
+
+ // Get action.
+ LinkAction *getAction() { return action; }
+
+ // Get border corners and width.
+ void getBorder(double *xa1, double *ya1, double *xa2, double *ya2,
+ double *wa)
+ { *xa1 = x1; *ya1 = y1; *xa2 = x2; *ya2 = y2; *wa = borderW; }
+
+private:
+
+ double x1, y1; // lower left corner
+ double x2, y2; // upper right corner
+ double borderW; // border width
+ LinkAction *action; // action
+ GBool ok; // is link valid?
+};
+
+//------------------------------------------------------------------------
+// Links
+//------------------------------------------------------------------------
+
+class Links {
+public:
+
+ // Extract links from array of annotations.
+ Links(Object *annots, GString *baseURI);
+
+ // Destructor.
+ ~Links();
+
+ // Iterate through list of links.
+ int getNumLinks() { return numLinks; }
+ Link *getLink(int i) { return links[i]; }
+
+ // If point <x>,<y> is in a link, return the associated action;
+ // else return NULL.
+ LinkAction *find(double x, double y);
+
+ // Return true if <x>,<y> is in a link.
+ GBool onLink(double x, double y);
+
+private:
+
+ Link **links;
+ int numLinks;
+};
+
+#endif
diff --git a/pdftops/Makefile b/pdftops/Makefile
new file mode 100644
index 000000000..6d9892832
--- /dev/null
+++ b/pdftops/Makefile
@@ -0,0 +1,87 @@
+#
+# "$Id$"
+#
+# pdftops filter Makefile for the Common UNIX Printing System (CUPS).
+#
+# CUPS filter changes Copyright 1997-2002 by Easy Software Products.
+# Xpdf code Copyright 1996-1999 by Derek B. Noonburg
+#
+
+
+include ../Makedefs
+
+#
+# Object files...
+#
+
+LIBOBJS = Decrypt.o GString.o gfile.o gmempp.o gmem.o parseargs.o \
+ Array.o Catalog.o Dict.o Error.o FontEncoding.o \
+ FontFile.o FormWidget.o Function.o Gfx.o GfxFont.o GfxState.o \
+ Lexer.o Link.o Object.o OutputDev.o Page.o Params.o \
+ Parser.o PDFDoc.o PSOutputDev.o Stream.o XRef.o
+OBJS = pdftops.o $(LIBOBJS)
+
+#
+# Make everything...
+#
+
+all: pdftops
+
+
+#
+# Clean all object files...
+#
+
+clean:
+ $(RM) $(OBJS)
+ $(RM) libxpdf.a
+ $(RM) pdftops
+
+
+#
+# Update dependencies (without system header dependencies...)
+#
+
+depend:
+ makedepend -Y -I.. -fDependencies $(OBJS:.o=.cxx) gmem.c parseargs.c >/dev/null 2>&1
+
+
+#
+# Install the filter...
+#
+
+install: all
+ $(INSTALL_DIR) $(SERVERBIN)/filter
+ $(INSTALL_BIN) pdftops $(SERVERBIN)/filter
+
+
+#
+# pdftops
+#
+
+pdftops: libxpdf.a pdftops.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CXX) $(LDFLAGS) -o $@ pdftops.o libxpdf.a $(LIBS) $(CXXLIBS) -lm
+
+
+#
+# libxpdf.a
+#
+
+libxpdf.a: $(LIBOBJS)
+ echo Archiving $@...
+ $(RM) $@
+ $(AR) $(ARFLAGS) $@ $(LIBOBJS)
+ $(RANLIB) $@
+
+
+#
+# Dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id$".
+#
diff --git a/pdftops/Object.cxx b/pdftops/Object.cxx
new file mode 100644
index 000000000..ca671ea2c
--- /dev/null
+++ b/pdftops/Object.cxx
@@ -0,0 +1,220 @@
+//========================================================================
+//
+// Object.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stddef.h>
+#include "Object.h"
+#include "Array.h"
+#include "Dict.h"
+#include "Error.h"
+#include "Stream.h"
+#include "XRef.h"
+
+//------------------------------------------------------------------------
+// Object
+//------------------------------------------------------------------------
+
+char *objTypeNames[numObjTypes] = {
+ "boolean",
+ "integer",
+ "real",
+ "string",
+ "name",
+ "null",
+ "array",
+ "dictionary",
+ "stream",
+ "ref",
+ "cmd",
+ "error",
+ "eof",
+ "none"
+};
+
+#ifdef DEBUG_MEM
+int Object::numAlloc[numObjTypes] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+#endif
+
+Object *Object::initArray(XRef *xref) {
+ initObj(objArray);
+ array = new Array(xref);
+ return this;
+}
+
+Object *Object::initDict(XRef *xref) {
+ initObj(objDict);
+ dict = new Dict(xref);
+ return this;
+}
+
+Object *Object::initStream(Stream *streamA) {
+ initObj(objStream);
+ stream = streamA;
+ return this;
+}
+
+Object *Object::copy(Object *obj) {
+ *obj = *this;
+ switch (type) {
+ case objString:
+ obj->string = string->copy();
+ break;
+ case objName:
+ obj->name = copyString(name);
+ break;
+ case objArray:
+ array->incRef();
+ break;
+ case objDict:
+ dict->incRef();
+ break;
+ case objStream:
+ stream->incRef();
+ break;
+ case objCmd:
+ obj->cmd = copyString(cmd);
+ break;
+ default:
+ break;
+ }
+#ifdef DEBUG_MEM
+ ++numAlloc[type];
+#endif
+ return obj;
+}
+
+Object *Object::fetch(XRef *xref, Object *obj) {
+ return (type == objRef && xref) ?
+ xref->fetch(ref.num, ref.gen, obj) : copy(obj);
+}
+
+void Object::free() {
+ switch (type) {
+ case objString:
+ delete string;
+ break;
+ case objName:
+ gfree(name);
+ break;
+ case objArray:
+ if (!array->decRef()) {
+ delete array;
+ }
+ break;
+ case objDict:
+ if (!dict->decRef()) {
+ delete dict;
+ }
+ break;
+ case objStream:
+ if (!stream->decRef()) {
+ delete stream;
+ }
+ break;
+ case objCmd:
+ gfree(cmd);
+ break;
+ default:
+ break;
+ }
+#ifdef DEBUG_MEM
+ --numAlloc[type];
+#endif
+ type = objNone;
+}
+
+char *Object::getTypeName() {
+ return objTypeNames[type];
+}
+
+void Object::print(FILE *f) {
+ Object obj;
+ int i;
+
+ switch (type) {
+ case objBool:
+ fprintf(f, "%s", booln ? "true" : "false");
+ break;
+ case objInt:
+ fprintf(f, "%d", intg);
+ break;
+ case objReal:
+ fprintf(f, "%g", real);
+ break;
+ case objString:
+ fprintf(f, "(%s)", string->getCString());
+ break;
+ case objName:
+ fprintf(f, "/%s", name);
+ break;
+ case objNull:
+ fprintf(f, "null");
+ break;
+ case objArray:
+ fprintf(f, "[");
+ for (i = 0; i < arrayGetLength(); ++i) {
+ if (i > 0)
+ fprintf(f, " ");
+ arrayGetNF(i, &obj);
+ obj.print(f);
+ obj.free();
+ }
+ fprintf(f, "]");
+ break;
+ case objDict:
+ fprintf(f, "<<");
+ for (i = 0; i < dictGetLength(); ++i) {
+ fprintf(f, " /%s ", dictGetKey(i));
+ dictGetValNF(i, &obj);
+ obj.print(f);
+ obj.free();
+ }
+ fprintf(f, " >>");
+ break;
+ case objStream:
+ fprintf(f, "<stream>");
+ break;
+ case objRef:
+ fprintf(f, "%d %d R", ref.num, ref.gen);
+ break;
+ case objCmd:
+ fprintf(f, "%s", cmd);
+ break;
+ case objError:
+ fprintf(f, "<error>");
+ break;
+ case objEOF:
+ fprintf(f, "<EOF>");
+ break;
+ case objNone:
+ fprintf(f, "<none>");
+ break;
+ }
+}
+
+void Object::memCheck(FILE *f) {
+#ifdef DEBUG_MEM
+ int i;
+ int t;
+
+ t = 0;
+ for (i = 0; i < numObjTypes; ++i)
+ t += numAlloc[i];
+ if (t > 0) {
+ fprintf(f, "Allocated objects:\n");
+ for (i = 0; i < numObjTypes; ++i) {
+ if (numAlloc[i] > 0)
+ fprintf(f, " %-20s: %6d\n", objTypeNames[i], numAlloc[i]);
+ }
+ }
+#endif
+}
diff --git a/pdftops/Object.h b/pdftops/Object.h
new file mode 100644
index 000000000..49af58613
--- /dev/null
+++ b/pdftops/Object.h
@@ -0,0 +1,299 @@
+//========================================================================
+//
+// Object.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef OBJECT_H
+#define OBJECT_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include "gtypes.h"
+#include "gmem.h"
+#include "GString.h"
+
+class XRef;
+class Array;
+class Dict;
+class Stream;
+
+//------------------------------------------------------------------------
+// Ref
+//------------------------------------------------------------------------
+
+struct Ref {
+ int num; // object number
+ int gen; // generation number
+};
+
+//------------------------------------------------------------------------
+// object types
+//------------------------------------------------------------------------
+
+enum ObjType {
+ // simple objects
+ objBool, // boolean
+ objInt, // integer
+ objReal, // real
+ objString, // string
+ objName, // name
+ objNull, // null
+
+ // complex objects
+ objArray, // array
+ objDict, // dictionary
+ objStream, // stream
+ objRef, // indirect reference
+
+ // special objects
+ objCmd, // command name
+ objError, // error return from Lexer
+ objEOF, // end of file return from Lexer
+ objNone // uninitialized object
+};
+
+#define numObjTypes 14 // total number of object types
+
+//------------------------------------------------------------------------
+// Object
+//------------------------------------------------------------------------
+
+#ifdef DEBUG_MEM
+#define initObj(t) ++numAlloc[type = t]
+#else
+#define initObj(t) type = t
+#endif
+
+class Object {
+public:
+
+ // Default constructor.
+ Object():
+ type(objNone) {}
+
+ // Initialize an object.
+ Object *initBool(GBool boolnA)
+ { initObj(objBool); booln = boolnA; return this; }
+ Object *initInt(int intgA)
+ { initObj(objInt); intg = intgA; return this; }
+ Object *initReal(double realA)
+ { initObj(objReal); real = realA; return this; }
+ Object *initString(GString *stringA)
+ { initObj(objString); string = stringA; return this; }
+ Object *initName(char *nameA)
+ { initObj(objName); name = copyString(nameA); return this; }
+ Object *initNull()
+ { initObj(objNull); return this; }
+ Object *initArray(XRef *xref);
+ Object *initDict(XRef *xref);
+ Object *initStream(Stream *streamA);
+ Object *initRef(int numA, int genA)
+ { initObj(objRef); ref.num = numA; ref.gen = genA; return this; }
+ Object *initCmd(char *cmdA)
+ { initObj(objCmd); cmd = copyString(cmdA); return this; }
+ Object *initError()
+ { initObj(objError); return this; }
+ Object *initEOF()
+ { initObj(objEOF); return this; }
+
+ // Copy an object.
+ Object *copy(Object *obj);
+
+ // If object is a Ref, fetch and return the referenced object.
+ // Otherwise, return a copy of the object.
+ Object *fetch(XRef *xref, Object *obj);
+
+ // Free object contents.
+ void free();
+
+ // Type checking.
+ ObjType getType() { return type; }
+ GBool isBool() { return type == objBool; }
+ GBool isInt() { return type == objInt; }
+ GBool isReal() { return type == objReal; }
+ GBool isNum() { return type == objInt || type == objReal; }
+ GBool isString() { return type == objString; }
+ GBool isName() { return type == objName; }
+ GBool isNull() { return type == objNull; }
+ GBool isArray() { return type == objArray; }
+ GBool isDict() { return type == objDict; }
+ GBool isStream() { return type == objStream; }
+ GBool isRef() { return type == objRef; }
+ GBool isCmd() { return type == objCmd; }
+ GBool isError() { return type == objError; }
+ GBool isEOF() { return type == objEOF; }
+ GBool isNone() { return type == objNone; }
+
+ // Special type checking.
+ GBool isName(char *nameA)
+ { return type == objName && !strcmp(name, nameA); }
+ GBool isDict(char *dictType);
+ GBool isStream(char *dictType);
+ GBool isCmd(char *cmdA)
+ { return type == objCmd && !strcmp(cmd, cmdA); }
+
+ // Accessors. NB: these assume object is of correct type.
+ GBool getBool() { return booln; }
+ int getInt() { return intg; }
+ double getReal() { return real; }
+ double getNum() { return type == objInt ? (double)intg : real; }
+ GString *getString() { return string; }
+ char *getName() { return name; }
+ Array *getArray() { return array; }
+ Dict *getDict() { return dict; }
+ Stream *getStream() { return stream; }
+ Ref getRef() { return ref; }
+ int getRefNum() { return ref.num; }
+ int getRefGen() { return ref.gen; }
+
+ // Array accessors.
+ int arrayGetLength();
+ void arrayAdd(Object *elem);
+ Object *arrayGet(int i, Object *obj);
+ Object *arrayGetNF(int i, Object *obj);
+
+ // Dict accessors.
+ int dictGetLength();
+ void dictAdd(char *key, Object *val);
+ GBool dictIs(char *dictType);
+ Object *dictLookup(char *key, Object *obj);
+ Object *dictLookupNF(char *key, Object *obj);
+ char *dictGetKey(int i);
+ Object *dictGetVal(int i, Object *obj);
+ Object *dictGetValNF(int i, Object *obj);
+
+ // Stream accessors.
+ GBool streamIs(char *dictType);
+ void streamReset();
+ void streamClose();
+ int streamGetChar();
+ int streamLookChar();
+ char *streamGetLine(char *buf, int size);
+ int streamGetPos();
+ void streamSetPos(int pos);
+ Dict *streamGetDict();
+
+ // Output.
+ char *getTypeName();
+ void print(FILE *f = stdout);
+
+ // Memory testing.
+ static void memCheck(FILE *f);
+
+private:
+
+ ObjType type; // object type
+ union { // value for each type:
+ GBool booln; // boolean
+ int intg; // integer
+ double real; // real
+ GString *string; // string
+ char *name; // name
+ Array *array; // array
+ Dict *dict; // dictionary
+ Stream *stream; // stream
+ Ref ref; // indirect reference
+ char *cmd; // command
+ };
+
+#ifdef DEBUG_MEM
+ static int // number of each type of object
+ numAlloc[numObjTypes]; // currently allocated
+#endif
+};
+
+//------------------------------------------------------------------------
+// Array accessors.
+//------------------------------------------------------------------------
+
+#include "Array.h"
+
+inline int Object::arrayGetLength()
+ { return array->getLength(); }
+
+inline void Object::arrayAdd(Object *elem)
+ { array->add(elem); }
+
+inline Object *Object::arrayGet(int i, Object *obj)
+ { return array->get(i, obj); }
+
+inline Object *Object::arrayGetNF(int i, Object *obj)
+ { return array->getNF(i, obj); }
+
+//------------------------------------------------------------------------
+// Dict accessors.
+//------------------------------------------------------------------------
+
+#include "Dict.h"
+
+inline int Object::dictGetLength()
+ { return dict->getLength(); }
+
+inline void Object::dictAdd(char *key, Object *val)
+ { dict->add(key, val); }
+
+inline GBool Object::dictIs(char *dictType)
+ { return dict->is(dictType); }
+
+inline GBool Object::isDict(char *dictType)
+ { return type == objDict && dictIs(dictType); }
+
+inline Object *Object::dictLookup(char *key, Object *obj)
+ { return dict->lookup(key, obj); }
+
+inline Object *Object::dictLookupNF(char *key, Object *obj)
+ { return dict->lookupNF(key, obj); }
+
+inline char *Object::dictGetKey(int i)
+ { return dict->getKey(i); }
+
+inline Object *Object::dictGetVal(int i, Object *obj)
+ { return dict->getVal(i, obj); }
+
+inline Object *Object::dictGetValNF(int i, Object *obj)
+ { return dict->getValNF(i, obj); }
+
+//------------------------------------------------------------------------
+// Stream accessors.
+//------------------------------------------------------------------------
+
+#include "Stream.h"
+
+inline GBool Object::streamIs(char *dictType)
+ { return stream->getDict()->is(dictType); }
+
+inline GBool Object::isStream(char *dictType)
+ { return type == objStream && streamIs(dictType); }
+
+inline void Object::streamReset()
+ { stream->reset(); }
+
+inline void Object::streamClose()
+ { stream->close(); }
+
+inline int Object::streamGetChar()
+ { return stream->getChar(); }
+
+inline int Object::streamLookChar()
+ { return stream->lookChar(); }
+
+inline char *Object::streamGetLine(char *buf, int size)
+ { return stream->getLine(buf, size); }
+
+inline int Object::streamGetPos()
+ { return stream->getPos(); }
+
+inline void Object::streamSetPos(int pos)
+ { stream->setPos(pos); }
+
+inline Dict *Object::streamGetDict()
+ { return stream->getDict(); }
+
+#endif
diff --git a/pdftops/OutputDev.cxx b/pdftops/OutputDev.cxx
new file mode 100644
index 000000000..014b2aef6
--- /dev/null
+++ b/pdftops/OutputDev.cxx
@@ -0,0 +1,94 @@
+//========================================================================
+//
+// OutputDev.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stddef.h>
+#include "Object.h"
+#include "Stream.h"
+#include "GfxState.h"
+#include "OutputDev.h"
+
+//------------------------------------------------------------------------
+// OutputDev
+//------------------------------------------------------------------------
+
+void OutputDev::setDefaultCTM(double *ctm) {
+ int i;
+ double det;
+
+ for (i = 0; i < 6; ++i) {
+ defCTM[i] = ctm[i];
+ }
+ det = 1 / (defCTM[0] * defCTM[3] - defCTM[1] * defCTM[2]);
+ defICTM[0] = defCTM[3] * det;
+ defICTM[1] = -defCTM[1] * det;
+ defICTM[2] = -defCTM[2] * det;
+ defICTM[3] = defCTM[0] * det;
+ defICTM[4] = (defCTM[2] * defCTM[5] - defCTM[3] * defCTM[4]) * det;
+ defICTM[5] = (defCTM[1] * defCTM[4] - defCTM[0] * defCTM[5]) * det;
+}
+
+void OutputDev::cvtDevToUser(int dx, int dy, double *ux, double *uy) {
+ *ux = defICTM[0] * dx + defICTM[2] * dy + defICTM[4];
+ *uy = defICTM[1] * dx + defICTM[3] * dy + defICTM[5];
+}
+
+void OutputDev::cvtUserToDev(double ux, double uy, int *dx, int *dy) {
+ *dx = (int)(defCTM[0] * ux + defCTM[2] * uy + defCTM[4] + 0.5);
+ *dy = (int)(defCTM[1] * ux + defCTM[3] * uy + defCTM[5] + 0.5);
+}
+
+void OutputDev::updateAll(GfxState *state) {
+ updateLineDash(state);
+ updateFlatness(state);
+ updateLineJoin(state);
+ updateLineCap(state);
+ updateMiterLimit(state);
+ updateLineWidth(state);
+ updateFillColor(state);
+ updateStrokeColor(state);
+ updateFont(state);
+}
+
+void OutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GBool invert,
+ GBool inlineImg) {
+ int i, j;
+
+ if (inlineImg) {
+ str->reset();
+ j = height * ((width + 7) / 8);
+ for (i = 0; i < j; ++i)
+ str->getChar();
+ }
+}
+
+void OutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GfxImageColorMap *colorMap,
+ int *maskColors, GBool inlineImg) {
+ int i, j;
+
+ if (inlineImg) {
+ str->reset();
+ j = height * ((width * colorMap->getNumPixelComps() *
+ colorMap->getBits() + 7) / 8);
+ for (i = 0; i < j; ++i)
+ str->getChar();
+ }
+}
+
+#if OPI_SUPPORT
+void OutputDev::opiBegin(GfxState *state, Dict *opiDict) {
+}
+
+void OutputDev::opiEnd(GfxState *state, Dict *opiDict) {
+}
+#endif
diff --git a/pdftops/OutputDev.h b/pdftops/OutputDev.h
new file mode 100644
index 000000000..c332fa933
--- /dev/null
+++ b/pdftops/OutputDev.h
@@ -0,0 +1,140 @@
+//========================================================================
+//
+// OutputDev.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef OUTPUTDEV_H
+#define OUTPUTDEV_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "gtypes.h"
+
+class GString;
+class GfxState;
+class GfxColorSpace;
+class GfxImageColorMap;
+class Stream;
+class Link;
+class Catalog;
+
+//------------------------------------------------------------------------
+// OutputDev
+//------------------------------------------------------------------------
+
+class OutputDev {
+public:
+
+ // Constructor.
+ OutputDev() {}
+
+ // Destructor.
+ virtual ~OutputDev() {}
+
+ //----- get info about output device
+
+ // Does this device use upside-down coordinates?
+ // (Upside-down means (0,0) is the top left corner of the page.)
+ virtual GBool upsideDown() = 0;
+
+ // Does this device use drawChar() or drawString()?
+ virtual GBool useDrawChar() = 0;
+
+ //----- initialization and control
+
+ // Set default transform matrix.
+ virtual void setDefaultCTM(double *ctm);
+
+ // Start a page.
+ virtual void startPage(int pageNum, GfxState *state) {}
+
+ // End a page.
+ virtual void endPage() {}
+
+ // Dump page contents to display.
+ virtual void dump() {}
+
+ //----- coordinate conversion
+
+ // Convert between device and user coordinates.
+ virtual void cvtDevToUser(int dx, int dy, double *ux, double *uy);
+ virtual void cvtUserToDev(double ux, double uy, int *dx, int *dy);
+
+ //----- link borders
+ virtual void drawLink(Link *link, Catalog *catalog) {}
+
+ //----- save/restore graphics state
+ virtual void saveState(GfxState *state) {}
+ virtual void restoreState(GfxState *state) {}
+
+ //----- update graphics state
+ virtual void updateAll(GfxState *state);
+ virtual void updateCTM(GfxState *state, double m11, double m12,
+ double m21, double m22, double m31, double m32) {}
+ virtual void updateLineDash(GfxState *state) {}
+ virtual void updateFlatness(GfxState *state) {}
+ virtual void updateLineJoin(GfxState *state) {}
+ virtual void updateLineCap(GfxState *state) {}
+ virtual void updateMiterLimit(GfxState *state) {}
+ virtual void updateLineWidth(GfxState *state) {}
+ virtual void updateFillColor(GfxState *state) {}
+ virtual void updateStrokeColor(GfxState *state) {}
+ virtual void updateFillOpacity(GfxState *state) {}
+ virtual void updateStrokeOpacity(GfxState *state) {}
+
+ //----- update text state
+ virtual void updateFont(GfxState *state) {}
+ virtual void updateTextMat(GfxState *state) {}
+ virtual void updateCharSpace(GfxState *state) {}
+ virtual void updateRender(GfxState *state) {}
+ virtual void updateRise(GfxState *state) {}
+ virtual void updateWordSpace(GfxState *state) {}
+ virtual void updateHorizScaling(GfxState *state) {}
+ virtual void updateTextPos(GfxState *state) {}
+ virtual void updateTextShift(GfxState *state, double shift) {}
+
+ //----- path painting
+ virtual void stroke(GfxState *state) {}
+ virtual void fill(GfxState *state) {}
+ virtual void eoFill(GfxState *state) {}
+
+ //----- path clipping
+ virtual void clip(GfxState *state) {}
+ virtual void eoClip(GfxState *state) {}
+
+ //----- text drawing
+ virtual void beginString(GfxState *state, GString *s) {}
+ virtual void endString(GfxState *state) {}
+ virtual void drawChar(GfxState *state, double x, double y,
+ double dx, double dy, Guchar c) {}
+ virtual void drawChar16(GfxState *state, double x, double y,
+ double dx, double dy, int c) {}
+ virtual void drawString(GfxState *state, GString *s) {}
+ virtual void drawString16(GfxState *state, GString *s) {}
+
+ //----- image drawing
+ virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GBool invert,
+ GBool inlineImg);
+ virtual void drawImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GfxImageColorMap *colorMap,
+ int *maskColors, GBool inlineImg);
+
+#if OPI_SUPPORT
+ //----- OPI functions
+ virtual void opiBegin(GfxState *state, Dict *opiDict);
+ virtual void opiEnd(GfxState *state, Dict *opiDict);
+#endif
+
+private:
+
+ double defCTM[6]; // default coordinate transform matrix
+ double defICTM[6]; // inverse of default CTM
+};
+
+#endif
diff --git a/pdftops/PDFDoc.cxx b/pdftops/PDFDoc.cxx
new file mode 100644
index 000000000..ae0428054
--- /dev/null
+++ b/pdftops/PDFDoc.cxx
@@ -0,0 +1,251 @@
+//========================================================================
+//
+// PDFDoc.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include "GString.h"
+#include "config.h"
+#include "Page.h"
+#include "Catalog.h"
+#include "Stream.h"
+#include "XRef.h"
+#include "Link.h"
+#include "OutputDev.h"
+#include "Params.h"
+#include "Error.h"
+#include "Lexer.h"
+#include "Parser.h"
+#include "PDFDoc.h"
+
+//------------------------------------------------------------------------
+
+#define headerSearchSize 1024 // read this many bytes at beginning of
+ // file to look for '%PDF'
+
+//------------------------------------------------------------------------
+// PDFDoc
+//------------------------------------------------------------------------
+
+PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
+ GString *userPassword, GBool printCommandsA) {
+ Object obj;
+ GString *fileName2;
+
+ ok = gFalse;
+
+ file = NULL;
+ str = NULL;
+ xref = NULL;
+ catalog = NULL;
+ links = NULL;
+ printCommands = printCommandsA;
+
+ // try to open file
+ fileName = fileNameA;
+ fileName2 = NULL;
+#ifdef VMS
+ if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) {
+ error(-1, "Couldn't open file '%s'", fileName->getCString());
+ return;
+ }
+#else
+ if (!(file = fopen(fileName->getCString(), "rb"))) {
+ fileName2 = fileName->copy();
+ fileName2->lowerCase();
+ if (!(file = fopen(fileName2->getCString(), "rb"))) {
+ fileName2->upperCase();
+ if (!(file = fopen(fileName2->getCString(), "rb"))) {
+ error(-1, "Couldn't open file '%s'", fileName->getCString());
+ delete fileName2;
+ return;
+ }
+ }
+ delete fileName2;
+ }
+#endif
+
+ // create stream
+ obj.initNull();
+ str = new FileStream(file, 0, -1, &obj);
+
+ ok = setup(ownerPassword, userPassword);
+}
+
+PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword,
+ GString *userPassword, GBool printCommandsA) {
+ ok = gFalse;
+ fileName = NULL;
+ file = NULL;
+ str = strA;
+ xref = NULL;
+ catalog = NULL;
+ links = NULL;
+ printCommands = printCommandsA;
+ ok = setup(ownerPassword, userPassword);
+}
+
+GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
+ // check header
+ checkHeader();
+
+ // read xref table
+ xref = new XRef(str, ownerPassword, userPassword);
+ if (!xref->isOk()) {
+ error(-1, "Couldn't read xref table");
+ return gFalse;
+ }
+
+ // read catalog
+ catalog = new Catalog(xref, printCommands);
+ if (!catalog->isOk()) {
+ error(-1, "Couldn't read page catalog");
+ return gFalse;
+ }
+
+ // done
+ return gTrue;
+}
+
+PDFDoc::~PDFDoc() {
+ if (catalog) {
+ delete catalog;
+ }
+ if (xref) {
+ delete xref;
+ }
+ if (str) {
+ delete str;
+ }
+ if (file) {
+ fclose(file);
+ }
+ if (fileName) {
+ delete fileName;
+ }
+ if (links) {
+ delete links;
+ }
+}
+
+// Check for a PDF header on this stream. Skip past some garbage
+// if necessary.
+void PDFDoc::checkHeader() {
+ char hdrBuf[headerSearchSize+1];
+ char *p;
+ int i;
+
+ pdfVersion = 0;
+ for (i = 0; i < headerSearchSize; ++i) {
+ hdrBuf[i] = str->getChar();
+ }
+ hdrBuf[headerSearchSize] = '\0';
+ for (i = 0; i < headerSearchSize - 5; ++i) {
+ if (!strncmp(&hdrBuf[i], "%PDF-", 5)) {
+ break;
+ }
+ }
+ if (i >= headerSearchSize - 5) {
+ error(-1, "May not be a PDF file (continuing anyway)");
+ return;
+ }
+ str->moveStart(i);
+ p = strtok(&hdrBuf[i+5], " \t\n\r");
+ pdfVersion = atof(p);
+ if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') ||
+ pdfVersion > supportedPDFVersionNum + 0.0001) {
+ error(-1, "PDF version %s -- xpdf supports version %s"
+ " (continuing anyway)", p, supportedPDFVersionStr);
+ }
+}
+
+void PDFDoc::displayPage(OutputDev *out, int page, double zoom,
+ int rotate, GBool doLinks) {
+ Page *p;
+
+ if (printCommands) {
+ printf("***** page %d *****\n", page);
+ }
+ p = catalog->getPage(page);
+ if (doLinks) {
+ if (links) {
+ delete links;
+ }
+ getLinks(p);
+ p->display(out, zoom, rotate, links, catalog);
+ } else {
+ p->display(out, zoom, rotate, NULL, catalog);
+ }
+}
+
+void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
+ int zoom, int rotate, GBool doLinks) {
+ int page;
+
+ for (page = firstPage; page <= lastPage; ++page) {
+ displayPage(out, page, zoom, rotate, doLinks);
+ }
+}
+
+GBool PDFDoc::isLinearized() {
+ Parser *parser;
+ Object obj1, obj2, obj3, obj4, obj5;
+ GBool lin;
+
+ lin = gFalse;
+ obj1.initNull();
+ parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(),
+ -1, &obj1)));
+ parser->getObj(&obj1);
+ parser->getObj(&obj2);
+ parser->getObj(&obj3);
+ parser->getObj(&obj4);
+ if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") &&
+ obj4.isDict()) {
+ obj4.dictLookup("Linearized", &obj5);
+ if (obj5.isNum() && obj5.getNum() > 0) {
+ lin = gTrue;
+ }
+ obj5.free();
+ }
+ obj4.free();
+ obj3.free();
+ obj2.free();
+ obj1.free();
+ delete parser;
+ return lin;
+}
+
+GBool PDFDoc::saveAs(GString *name) {
+ FILE *f;
+ int c;
+
+ if (!(f = fopen(name->getCString(), "wb"))) {
+ error(-1, "Couldn't open file '%s'", name->getCString());
+ return gFalse;
+ }
+ str->reset();
+ while ((c = str->getChar()) != EOF) {
+ fputc(c, f);
+ }
+ str->close();
+ fclose(f);
+ return gTrue;
+}
+
+void PDFDoc::getLinks(Page *page) {
+ Object obj;
+
+ links = new Links(page->getAnnots(&obj), catalog->getBaseURI());
+ obj.free();
+}
diff --git a/pdftops/PDFDoc.h b/pdftops/PDFDoc.h
new file mode 100644
index 000000000..c693e991a
--- /dev/null
+++ b/pdftops/PDFDoc.h
@@ -0,0 +1,135 @@
+//========================================================================
+//
+// PDFDoc.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef PDFDOC_H
+#define PDFDOC_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <stdio.h>
+#include "XRef.h"
+#include "Link.h"
+#include "Catalog.h"
+#include "Page.h"
+
+class GString;
+class BaseStream;
+class OutputDev;
+class Links;
+class LinkAction;
+class LinkDest;
+
+//------------------------------------------------------------------------
+// PDFDoc
+//------------------------------------------------------------------------
+
+class PDFDoc {
+public:
+
+ PDFDoc(GString *fileNameA, GString *ownerPassword = NULL,
+ GString *userPassword = NULL, GBool printCommandsA = gFalse);
+ PDFDoc(BaseStream *strA, GString *ownerPassword = NULL,
+ GString *userPassword = NULL, GBool printCommandsA = gFalse);
+ ~PDFDoc();
+
+ // Was PDF document successfully opened?
+ GBool isOk() { return ok; }
+
+ // Get file name.
+ GString *getFileName() { return fileName; }
+
+ // Get the xref table.
+ XRef *getXRef() { return xref; }
+
+ // Get catalog.
+ Catalog *getCatalog() { return catalog; }
+
+ // Get base stream.
+ BaseStream *getBaseStream() { return str; }
+
+ // Get page parameters.
+ double getPageWidth(int page)
+ { return catalog->getPage(page)->getWidth(); }
+ double getPageHeight(int page)
+ { return catalog->getPage(page)->getHeight(); }
+ int getPageRotate(int page)
+ { return catalog->getPage(page)->getRotate(); }
+
+ // Get number of pages.
+ int getNumPages() { return catalog->getNumPages(); }
+
+ // Display a page.
+ void displayPage(OutputDev *out, int page, double zoom,
+ int rotate, GBool doLinks);
+
+ // Display a range of pages.
+ void displayPages(OutputDev *out, int firstPage, int lastPage,
+ int zoom, int rotate, GBool doLinks);
+
+ // Find a page, given its object ID. Returns page number, or 0 if
+ // not found.
+ int findPage(int num, int gen) { return catalog->findPage(num, gen); }
+
+ // If point <x>,<y> is in a link, return the associated action;
+ // else return NULL.
+ LinkAction *findLink(double x, double y) { return links->find(x, y); }
+
+ // Return true if <x>,<y> is in a link.
+ GBool onLink(double x, double y) { return links->onLink(x, y); }
+
+ // Find a named destination. Returns the link destination, or
+ // NULL if <name> is not a destination.
+ LinkDest *findDest(GString *name)
+ { return catalog->findDest(name); }
+
+ // Is the file encrypted?
+ GBool isEncrypted() { return xref->isEncrypted(); }
+
+ // Check various permissions.
+ GBool okToPrint(GBool ignoreOwnerPW = gFalse)
+ { return xref->okToPrint(ignoreOwnerPW); }
+ GBool okToChange(GBool ignoreOwnerPW = gFalse)
+ { return xref->okToChange(ignoreOwnerPW); }
+ GBool okToCopy(GBool ignoreOwnerPW = gFalse)
+ { return xref->okToCopy(ignoreOwnerPW); }
+ GBool okToAddNotes(GBool ignoreOwnerPW = gFalse)
+ { return xref->okToAddNotes(ignoreOwnerPW); }
+
+ // Is this document linearized?
+ GBool isLinearized();
+
+ // Return the document's Info dictionary (if any).
+ Object *getDocInfo(Object *obj) { return xref->getDocInfo(obj); }
+
+ // Return the PDF version specified by the file.
+ double getPDFVersion() { return pdfVersion; }
+
+ // Save this file with another name.
+ GBool saveAs(GString *name);
+
+private:
+
+ GBool setup(GString *ownerPassword, GString *userPassword);
+ void checkHeader();
+ void getLinks(Page *page);
+
+ GString *fileName;
+ FILE *file;
+ BaseStream *str;
+ double pdfVersion;
+ XRef *xref;
+ Catalog *catalog;
+ Links *links;
+ GBool printCommands;
+
+ GBool ok;
+};
+
+#endif
diff --git a/pdftops/PSOutputDev.cxx b/pdftops/PSOutputDev.cxx
new file mode 100644
index 000000000..b62a23d24
--- /dev/null
+++ b/pdftops/PSOutputDev.cxx
@@ -0,0 +1,2562 @@
+//========================================================================
+//
+// PSOutputDev.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <math.h>
+#include "GString.h"
+#include "config.h"
+#include "Object.h"
+#include "Error.h"
+#include "Function.h"
+#include "GfxState.h"
+#include "GfxFont.h"
+#include "FontFile.h"
+#include "Catalog.h"
+#include "Page.h"
+#include "Stream.h"
+#include "FormWidget.h"
+#include "PSOutputDev.h"
+
+#if JAPANESE_SUPPORT
+#include "Japan12ToRKSJ.h"
+#endif
+
+#ifdef MACOS
+// needed for setting type/creator of MacOS files
+#include "ICSupport.h"
+#endif
+
+//------------------------------------------------------------------------
+// PostScript prolog and setup
+//------------------------------------------------------------------------
+
+static char *prolog[] = {
+ "/xpdf 75 dict def xpdf begin",
+ "% PDF special state",
+ "/pdfDictSize 14 def",
+ "/pdfSetup {",
+ " 2 array astore",
+ " /setpagedevice where {",
+ " pop 3 dict dup begin",
+ " exch /PageSize exch def",
+ " /ImagingBBox null def",
+ " /Policies 1 dict dup begin /PageSize 3 def end def",
+ " end setpagedevice",
+ " } {",
+ " pop",
+ " } ifelse",
+ "} def",
+ "/pdfStartPage {",
+ " pdfDictSize dict begin",
+ " /pdfFill [0] def",
+ " /pdfStroke [0] def",
+ " /pdfLastFill false def",
+ " /pdfLastStroke false def",
+ " /pdfTextMat [1 0 0 1 0 0] def",
+ " /pdfFontSize 0 def",
+ " /pdfCharSpacing 0 def",
+ " /pdfTextRender 0 def",
+ " /pdfTextRise 0 def",
+ " /pdfWordSpacing 0 def",
+ " /pdfHorizScaling 1 def",
+ "} def",
+ "/pdfEndPage { end } def",
+ "% separation convention operators",
+ "/findcmykcustomcolor where {",
+ " pop",
+ "}{",
+ " /findcmykcustomcolor { 5 array astore } def",
+ "} ifelse",
+ "/setcustomcolor where {",
+ " pop",
+ "}{",
+ " /setcustomcolor {",
+ " exch",
+ " [ exch /Separation exch dup 4 get exch /DeviceCMYK exch",
+ " 0 4 getinterval cvx",
+ " [ exch /dup load exch { mul exch dup } /forall load",
+ " /pop load dup ] cvx",
+ " ] setcolorspace setcolor",
+ " } def",
+ "} ifelse",
+ "/customcolorimage where {",
+ " pop",
+ "}{",
+ " /customcolorimage {",
+ " gsave",
+ " [ exch /Separation exch dup 4 get exch /DeviceCMYK exch",
+ " 0 4 getinterval cvx",
+ " [ exch /dup load exch { mul exch dup } /forall load",
+ " /pop load dup ] cvx",
+ " ] setcolorspace",
+ " 10 dict begin",
+ " /ImageType 1 def",
+ " /DataSource exch def",
+ " /ImageMatrix exch def",
+ " /BitsPerComponent exch def",
+ " /Height exch def",
+ " /Width exch def",
+ " /Decode [1 0] def",
+ " currentdict end",
+ " image",
+ " grestore",
+ " } def",
+ "} ifelse",
+ "% PDF color state",
+ "/sCol {",
+ " pdfLastStroke not {",
+ " pdfStroke aload length",
+ " dup 1 eq {",
+ " pop setgray",
+ " }{",
+ " dup 3 eq {",
+ " pop setrgbcolor",
+ " }{",
+ " 4 eq {",
+ " setcmykcolor",
+ " }{",
+ " findcmykcustomcolor exch setcustomcolor",
+ " } ifelse",
+ " } ifelse",
+ " } ifelse",
+ " /pdfLastStroke true def /pdfLastFill false def",
+ " } if",
+ "} def",
+ "/fCol {",
+ " pdfLastFill not {",
+ " pdfFill aload length",
+ " dup 1 eq {",
+ " pop setgray",
+ " }{",
+ " dup 3 eq {",
+ " pop setrgbcolor",
+ " }{",
+ " 4 eq {",
+ " setcmykcolor",
+ " }{",
+ " findcmykcustomcolor exch setcustomcolor",
+ " } ifelse",
+ " } ifelse",
+ " } ifelse",
+ " /pdfLastFill true def /pdfLastStroke false def",
+ " } if",
+ "} def",
+ "% build a font",
+ "/pdfMakeFont {",
+ " 4 3 roll findfont",
+ " 4 2 roll matrix scale makefont",
+ " dup length dict begin",
+ " { 1 index /FID ne { def } { pop pop } ifelse } forall",
+ " /Encoding exch def",
+ " currentdict",
+ " end",
+ " definefont pop",
+ "} def",
+ "/pdfMakeFont16 { findfont definefont pop } def",
+ "% graphics state operators",
+ "/q { gsave pdfDictSize dict begin } def",
+ "/Q { end grestore } def",
+ "/cm { concat } def",
+ "/d { setdash } def",
+ "/i { setflat } def",
+ "/j { setlinejoin } def",
+ "/J { setlinecap } def",
+ "/M { setmiterlimit } def",
+ "/w { setlinewidth } def",
+ "% color operators",
+ "/g { dup 1 array astore /pdfFill exch def setgray",
+ " /pdfLastFill true def /pdfLastStroke false def } def",
+ "/G { dup 1 array astore /pdfStroke exch def setgray",
+ " /pdfLastStroke true def /pdfLastFill false def } def",
+ "/rg { 3 copy 3 array astore /pdfFill exch def setrgbcolor",
+ " /pdfLastFill true def /pdfLastStroke false def } def",
+ "/RG { 3 copy 3 array astore /pdfStroke exch def setrgbcolor",
+ " /pdfLastStroke true def /pdfLastFill false def } def",
+ "/k { 4 copy 4 array astore /pdfFill exch def setcmykcolor",
+ " /pdfLastFill true def /pdfLastStroke false def } def",
+ "/K { 4 copy 4 array astore /pdfStroke exch def setcmykcolor",
+ " /pdfLastStroke true def /pdfLastFill false def } def",
+ "/ck { 6 copy 6 array astore /pdfFill exch def",
+ " findcmykcustomcolor exch setcustomcolor",
+ " /pdfLastFill true def /pdfLastStroke false def } def",
+ "/CK { 6 copy 6 array astore /pdfStroke exch def",
+ " findcmykcustomcolor exch setcustomcolor",
+ " /pdfLastStroke true def /pdfLastFill false def } def",
+ "% path segment operators",
+ "/m { moveto } def",
+ "/l { lineto } def",
+ "/c { curveto } def",
+ "/re { 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto",
+ " neg 0 rlineto closepath } def",
+ "/h { closepath } def",
+ "% path painting operators",
+ "/S { sCol stroke } def",
+ "/f { fCol fill } def",
+ "/f* { fCol eofill } def",
+ "% clipping operators",
+ "/W { clip newpath } def",
+ "/W* { eoclip newpath } def",
+ "% text state operators",
+ "/Tc { /pdfCharSpacing exch def } def",
+ "/Tf { dup /pdfFontSize exch def",
+ " dup pdfHorizScaling mul exch matrix scale",
+ " pdfTextMat matrix concatmatrix dup 4 0 put dup 5 0 put",
+ " exch findfont exch makefont setfont } def",
+ "/Tr { /pdfTextRender exch def } def",
+ "/Ts { /pdfTextRise exch def } def",
+ "/Tw { /pdfWordSpacing exch def } def",
+ "/Tz { /pdfHorizScaling exch def } def",
+ "% text positioning operators",
+ "/Td { pdfTextMat transform moveto } def",
+ "/Tm { /pdfTextMat exch def } def",
+ "% text string operators",
+ "/Tj { pdfTextRender 1 and 0 eq { fCol } { sCol } ifelse",
+ " 0 pdfTextRise pdfTextMat dtransform rmoveto",
+ " pdfFontSize mul pdfHorizScaling mul",
+ " 1 index stringwidth pdfTextMat idtransform pop",
+ " sub 1 index length dup 0 ne { div } { pop pop 0 } ifelse",
+ " pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32",
+ " 4 3 roll pdfCharSpacing pdfHorizScaling mul add 0",
+ " pdfTextMat dtransform",
+ " 6 5 roll awidthshow",
+ " 0 pdfTextRise neg pdfTextMat dtransform rmoveto } def",
+ "/TJm { pdfFontSize 0.001 mul mul neg 0",
+ " pdfTextMat dtransform rmoveto } def",
+ "% Level 1 image operators",
+ "/pdfIm1 {",
+ " /pdfImBuf1 4 index string def",
+ " { currentfile pdfImBuf1 readhexstring pop } image",
+ "} def",
+ "/pdfIm1Sep {",
+ " /pdfImBuf1 4 index string def",
+ " /pdfImBuf2 4 index string def",
+ " /pdfImBuf3 4 index string def",
+ " /pdfImBuf4 4 index string def",
+ " { currentfile pdfImBuf1 readhexstring pop }",
+ " { currentfile pdfImBuf2 readhexstring pop }",
+ " { currentfile pdfImBuf3 readhexstring pop }",
+ " { currentfile pdfImBuf4 readhexstring pop }",
+ " true 4 colorimage",
+ "} def",
+ "/pdfImM1 {",
+ " /pdfImBuf1 4 index 7 add 8 idiv string def",
+ " { currentfile pdfImBuf1 readhexstring pop } imagemask",
+ "} def",
+ "% Level 2 image operators",
+ "/pdfImBuf 100 string def",
+ "/pdfIm {",
+ " image",
+ " { currentfile pdfImBuf readline",
+ " not { pop exit } if",
+ " (%-EOD-) eq { exit } if } loop",
+ "} def",
+ "/pdfImSep {",
+ " findcmykcustomcolor exch",
+ " dup /Width get /pdfImBuf1 exch string def",
+ " begin Width Height BitsPerComponent ImageMatrix DataSource end",
+ " /pdfImData exch def",
+ " { pdfImData pdfImBuf1 readstring pop",
+ " 0 1 2 index length 1 sub {",
+ " 1 index exch 2 copy get 255 exch sub put",
+ " } for }",
+ " 6 5 roll customcolorimage",
+ " { currentfile pdfImBuf readline",
+ " not { pop exit } if",
+ " (%-EOD-) eq { exit } if } loop",
+ "} def",
+ "/pdfImM {",
+ " fCol imagemask",
+ " { currentfile pdfImBuf readline",
+ " not { pop exit } if",
+ " (%-EOD-) eq { exit } if } loop",
+ "} def",
+ "end",
+ NULL
+};
+
+//------------------------------------------------------------------------
+// Fonts
+//------------------------------------------------------------------------
+
+struct PSFont {
+ char *name; // PDF name
+ char *psName; // PostScript name
+};
+
+struct PSSubstFont {
+ char *psName; // PostScript name
+ double mWidth; // width of 'm' character
+};
+
+static PSFont psFonts[] = {
+ {"Courier", "Courier"},
+ {"Courier-Bold", "Courier-Bold"},
+ {"Courier-Oblique", "Courier-Oblique"},
+ {"Courier-BoldOblique", "Courier-BoldOblique"},
+ {"Helvetica", "Helvetica"},
+ {"Helvetica-Bold", "Helvetica-Bold"},
+ {"Helvetica-Oblique", "Helvetica-Oblique"},
+ {"Helvetica-BoldOblique", "Helvetica-BoldOblique"},
+ {"Symbol", "Symbol"},
+ {"Times-Roman", "Times-Roman"},
+ {"Times-Bold", "Times-Bold"},
+ {"Times-Italic", "Times-Italic"},
+ {"Times-BoldItalic", "Times-BoldItalic"},
+ {"ZapfDingbats", "ZapfDingbats"},
+ {NULL}
+};
+
+static PSSubstFont psSubstFonts[] = {
+ {"Helvetica", 0.833},
+ {"Helvetica-Oblique", 0.833},
+ {"Helvetica-Bold", 0.889},
+ {"Helvetica-BoldOblique", 0.889},
+ {"Times-Roman", 0.788},
+ {"Times-Italic", 0.722},
+ {"Times-Bold", 0.833},
+ {"Times-BoldItalic", 0.778},
+ {"Courier", 0.600},
+ {"Courier-Oblique", 0.600},
+ {"Courier-Bold", 0.600},
+ {"Courier-BoldOblique", 0.600}
+};
+
+//------------------------------------------------------------------------
+// process colors
+//------------------------------------------------------------------------
+
+#define psProcessCyan 1
+#define psProcessMagenta 2
+#define psProcessYellow 4
+#define psProcessBlack 8
+#define psProcessCMYK 15
+
+//------------------------------------------------------------------------
+// PSOutCustomColor
+//------------------------------------------------------------------------
+
+class PSOutCustomColor {
+public:
+
+ PSOutCustomColor(double cA, double mA,
+ double yA, double kA, GString *nameA);
+ ~PSOutCustomColor();
+
+ double c, m, y, k;
+ GString *name;
+ PSOutCustomColor *next;
+};
+
+PSOutCustomColor::PSOutCustomColor(double cA, double mA,
+ double yA, double kA, GString *nameA) {
+ c = cA;
+ m = mA;
+ y = yA;
+ k = kA;
+ name = nameA;
+ next = NULL;
+}
+
+PSOutCustomColor::~PSOutCustomColor() {
+ delete name;
+}
+
+//------------------------------------------------------------------------
+// PSOutputDev
+//------------------------------------------------------------------------
+
+extern "C" {
+typedef void (*SignalFunc)(int);
+}
+
+PSOutputDev::PSOutputDev(char *fileName, XRef *xrefA, Catalog *catalog,
+ int firstPage, int lastPage,
+ PSOutLevel levelA, PSOutMode modeA, GBool doOPIA,
+ GBool embedType1A, GBool embedTrueTypeA,
+ int paperWidthA, int paperHeightA) {
+ Page *page;
+ PDFRectangle *box;
+ Dict *resDict;
+ FormWidgets *formWidgets;
+ char **p;
+ int pg;
+ Object obj1, obj2;
+ int i;
+
+ // initialize
+ xref = xrefA;
+ level = levelA;
+ mode = modeA;
+ doOPI = doOPIA;
+ embedType1 = embedType1A;
+ embedTrueType = embedTrueTypeA;
+ paperWidth = paperWidthA;
+ paperHeight = paperHeightA;
+ fontIDs = NULL;
+ fontFileIDs = NULL;
+ fontFileNames = NULL;
+ embFontList = NULL;
+ f = NULL;
+ if (mode == psModeForm) {
+ lastPage = firstPage;
+ }
+ processColors = 0;
+ customColors = NULL;
+
+ // open file or pipe
+ ok = gTrue;
+ if (!strcmp(fileName, "-")) {
+ fileType = psStdout;
+ f = stdout;
+ } else if (fileName[0] == '|') {
+ fileType = psPipe;
+#ifdef HAVE_POPEN
+#ifndef WIN32
+ signal(SIGPIPE, (SignalFunc)SIG_IGN);
+#endif
+ if (!(f = popen(fileName + 1, "w"))) {
+ error(-1, "Couldn't run print command '%s'", fileName);
+ ok = gFalse;
+ return;
+ }
+#else
+ error(-1, "Print commands are not supported ('%s')", fileName);
+ ok = gFalse;
+ return;
+#endif
+ } else {
+ fileType = psFile;
+ if (!(f = fopen(fileName, "w"))) {
+ error(-1, "Couldn't open PostScript file '%s'", fileName);
+ ok = gFalse;
+ return;
+ }
+ }
+
+ // initialize fontIDs, fontFileIDs, and fontFileNames lists
+ fontIDSize = 64;
+ fontIDLen = 0;
+ fontIDs = (Ref *)gmalloc(fontIDSize * sizeof(Ref));
+ fontFileIDSize = 64;
+ fontFileIDLen = 0;
+ fontFileIDs = (Ref *)gmalloc(fontFileIDSize * sizeof(Ref));
+ fontFileNameSize = 64;
+ fontFileNameLen = 0;
+ fontFileNames = (GString **)gmalloc(fontFileNameSize * sizeof(GString *));
+
+ // initialize embedded font resource comment list
+ embFontList = new GString();
+
+ // write header
+ switch (mode) {
+ case psModePS:
+ writePS("%%!PS-Adobe-3.0\n");
+ writePS("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion);
+ writePS("%%%%LanguageLevel: %d\n",
+ (level == psLevel1 || level == psLevel1Sep) ? 1 : 2);
+ if (level == psLevel1Sep || level == psLevel2Sep) {
+ writePS("%%%%DocumentProcessColors: (atend)\n");
+ writePS("%%%%DocumentCustomColors: (atend)\n");
+ }
+ writePS("%%%%DocumentMedia: plain %d %d 0 () ()\n",
+ paperWidth, paperHeight);
+ writePS("%%%%Pages: %d\n", lastPage - firstPage + 1);
+ writePS("%%%%EndComments\n");
+ writePS("%%%%BeginDefaults\n");
+ writePS("%%%%PageMedia: plain\n");
+ writePS("%%%%EndDefaults\n");
+ break;
+ case psModeEPS:
+ writePS("%%!PS-Adobe-3.0 EPSF-3.0\n");
+ writePS("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion);
+ writePS("%%%%LanguageLevel: %d\n",
+ (level == psLevel1 || level == psLevel1Sep) ? 1 : 2);
+ if (level == psLevel1Sep || level == psLevel2Sep) {
+ writePS("%%%%DocumentProcessColors: (atend)\n");
+ writePS("%%%%DocumentCustomColors: (atend)\n");
+ }
+ page = catalog->getPage(firstPage);
+ box = page->getBox();
+ writePS("%%%%BoundingBox: %d %d %d %d\n",
+ (int)floor(box->x1), (int)floor(box->y1),
+ (int)ceil(box->x2), (int)ceil(box->y2));
+ if (floor(box->x1) != ceil(box->x1) ||
+ floor(box->y1) != ceil(box->y1) ||
+ floor(box->x2) != ceil(box->x2) ||
+ floor(box->y2) != ceil(box->y2)) {
+ writePS("%%%%HiResBoundingBox: %g %g %g %g\n",
+ box->x1, box->y1, box->x2, box->y2);
+ }
+ writePS("%%%%DocumentSuppliedResources: (atend)\n");
+ writePS("%%%%EndComments\n");
+ break;
+ case psModeForm:
+ writePS("%%!PS-Adobe-3.0 Resource-Form\n");
+ writePS("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion);
+ writePS("%%%%LanguageLevel: %d\n",
+ (level == psLevel1 || level == psLevel1Sep) ? 1 : 2);
+ if (level == psLevel1Sep || level == psLevel2Sep) {
+ writePS("%%%%DocumentProcessColors: (atend)\n");
+ writePS("%%%%DocumentCustomColors: (atend)\n");
+ }
+ writePS("%%%%EndComments\n");
+ page = catalog->getPage(firstPage);
+ box = page->getBox();
+ writePS("32 dict dup begin\n");
+ writePS("/BBox [%d %d %d %d] def\n",
+ (int)box->x1, (int)box->y1, (int)box->x2, (int)box->y2);
+ writePS("/FormType 1 def\n");
+ writePS("/Matrix [1 0 0 1 0 0] def\n");
+ break;
+ }
+
+ // write prolog
+ if (mode != psModeForm) {
+ writePS("%%%%BeginProlog\n");
+ }
+ writePS("%%%%BeginResource: procset xpdf %s 0\n", xpdfVersion);
+ for (p = prolog; *p; ++p) {
+ writePS("%s\n", *p);
+ }
+ writePS("%%%%EndResource\n");
+ if (mode != psModeForm) {
+ writePS("%%%%EndProlog\n");
+ }
+
+ // set up fonts and images
+ type3Warning = gFalse;
+ if (mode == psModeForm) {
+ // swap the form and xpdf dicts
+ writePS("xpdf end begin dup begin\n");
+ } else {
+ writePS("%%%%BeginSetup\n");
+ writePS("xpdf begin\n");
+ }
+ for (pg = firstPage; pg <= lastPage; ++pg) {
+ page = catalog->getPage(pg);
+ if ((resDict = page->getResourceDict())) {
+ setupResources(resDict);
+ }
+ formWidgets = new FormWidgets(xref, page->getAnnots(&obj1));
+ obj1.free();
+ for (i = 0; i < formWidgets->getNumWidgets(); ++i) {
+ if (formWidgets->getWidget(i)->getAppearance(&obj1)->isStream()) {
+ obj1.streamGetDict()->lookup("Resources", &obj2);
+ if (obj2.isDict()) {
+ setupResources(obj2.getDict());
+ }
+ obj2.free();
+ }
+ obj1.free();
+ }
+ delete formWidgets;
+ }
+ if (mode != psModeForm) {
+#if OPI_SUPPORT
+ if (doOPI) {
+ writePS("/opiMatrix matrix currentmatrix def\n");
+ }
+#endif
+ if (mode != psModeEPS) {
+ writePS("%d %d pdfSetup\n", paperWidth, paperHeight);
+ }
+ writePS("%%%%EndSetup\n");
+ }
+
+ // initialize sequential page number
+ seqPage = 1;
+
+#if OPI_SUPPORT
+ // initialize OPI nesting levels
+ opi13Nest = 0;
+ opi20Nest = 0;
+#endif
+}
+
+PSOutputDev::~PSOutputDev() {
+ PSOutCustomColor *cc;
+ int i;
+
+ if (f) {
+ if (mode == psModeForm) {
+ writePS("/Foo exch /Form defineresource pop\n");
+ } else {
+ writePS("%%%%Trailer\n");
+ writePS("end\n");
+ writePS("%%%%DocumentSuppliedResources:\n");
+ writePS("%s", embFontList->getCString());
+ if (level == psLevel1Sep || level == psLevel2Sep) {
+ writePS("%%%%DocumentProcessColors:");
+ if (processColors & psProcessCyan) {
+ writePS(" Cyan");
+ }
+ if (processColors & psProcessMagenta) {
+ writePS(" Magenta");
+ }
+ if (processColors & psProcessYellow) {
+ writePS(" Yellow");
+ }
+ if (processColors & psProcessBlack) {
+ writePS(" Black");
+ }
+ writePS("\n");
+ writePS("%%%%DocumentCustomColors:");
+ for (cc = customColors; cc; cc = cc->next) {
+ writePS(" (%s)", cc->name->getCString());
+ }
+ writePS("\n");
+ writePS("%%%%CMYKCustomColor:\n");
+ for (cc = customColors; cc; cc = cc->next) {
+ writePS("%%%%+ %g %g %g %g (%s)\n",
+ cc->c, cc->m, cc->y, cc->k, cc->name->getCString());
+ }
+ }
+ writePS("%%%%EOF\n");
+ }
+ if (fileType == psFile) {
+#ifdef MACOS
+ ICS_MapRefNumAndAssign((short)f->handle);
+#endif
+ fclose(f);
+ }
+#ifdef HAVE_POPEN
+ else if (fileType == psPipe) {
+ pclose(f);
+#ifndef WIN32
+ signal(SIGPIPE, (SignalFunc)SIG_DFL);
+#endif
+ }
+#endif
+ }
+ if (embFontList) {
+ delete embFontList;
+ }
+ if (fontIDs) {
+ gfree(fontIDs);
+ }
+ if (fontFileIDs) {
+ gfree(fontFileIDs);
+ }
+ if (fontFileNames) {
+ for (i = 0; i < fontFileNameLen; ++i) {
+ delete fontFileNames[i];
+ }
+ gfree(fontFileNames);
+ }
+ while (customColors) {
+ cc = customColors;
+ customColors = cc->next;
+ delete cc;
+ }
+}
+
+void PSOutputDev::setupResources(Dict *resDict) {
+ Object xObjDict, xObj, resObj;
+ int i;
+
+ setupFonts(resDict);
+ setupImages(resDict);
+
+ resDict->lookup("XObject", &xObjDict);
+ if (xObjDict.isDict()) {
+ for (i = 0; i < xObjDict.dictGetLength(); ++i) {
+ xObjDict.dictGetVal(i, &xObj);
+ if (xObj.isStream()) {
+ xObj.streamGetDict()->lookup("Resources", &resObj);
+ if (resObj.isDict()) {
+ setupResources(resObj.getDict());
+ }
+ resObj.free();
+ }
+ xObj.free();
+ }
+ }
+ xObjDict.free();
+}
+
+void PSOutputDev::setupFonts(Dict *resDict) {
+ Object fontDict;
+ GfxFontDict *gfxFontDict;
+ GfxFont *font;
+ int i;
+
+ resDict->lookup("Font", &fontDict);
+ if (fontDict.isDict()) {
+ gfxFontDict = new GfxFontDict(xref, fontDict.getDict());
+ for (i = 0; i < gfxFontDict->getNumFonts(); ++i) {
+ font = gfxFontDict->getFont(i);
+ setupFont(font);
+ }
+ delete gfxFontDict;
+ }
+ fontDict.free();
+}
+
+void PSOutputDev::setupFont(GfxFont *font) {
+ Ref fontFileID;
+ GString *name;
+ char *psName;
+ char *charName;
+ double xs, ys;
+ GBool do16Bit;
+ int code;
+ double w1, w2;
+ double *fm;
+ int i, j;
+
+ // check if font is already set up
+ for (i = 0; i < fontIDLen; ++i) {
+ if (fontIDs[i].num == font->getID().num &&
+ fontIDs[i].gen == font->getID().gen)
+ return;
+ }
+
+ // add entry to fontIDs list
+ if (fontIDLen >= fontIDSize) {
+ fontIDSize += 64;
+ fontIDs = (Ref *)grealloc(fontIDs, fontIDSize * sizeof(Ref));
+ }
+ fontIDs[fontIDLen++] = font->getID();
+
+ xs = ys = 1;
+ do16Bit = gFalse;
+
+ // check for embedded Type 1 font
+ if (embedType1 && font->getType() == fontType1 &&
+ font->getEmbeddedFontID(&fontFileID)) {
+ psName = font->getEmbeddedFontName();
+ setupEmbeddedType1Font(&fontFileID, psName);
+
+ // check for external Type 1 font file
+ } else if (embedType1 && font->getType() == fontType1 &&
+ font->getExtFontFile()) {
+ // this assumes that the PS font name matches the PDF font name
+ psName = font->getName()->getCString();
+ setupEmbeddedType1Font(font->getExtFontFile(), psName);
+
+ // check for embedded Type 1C font
+ } else if (embedType1 && font->getType() == fontType1C &&
+ font->getEmbeddedFontID(&fontFileID)) {
+ psName = font->getEmbeddedFontName();
+ setupEmbeddedType1CFont(font, &fontFileID, psName);
+
+ // check for embedded TrueType font
+ } else if (embedTrueType && font->getType() == fontTrueType &&
+ font->getEmbeddedFontID(&fontFileID)) {
+ psName = font->getEmbeddedFontName();
+ setupEmbeddedTrueTypeFont(font, &fontFileID, psName);
+
+ // check for Japanese font
+ } else if (font->is16Bit() && font->getCharSet16() == font16AdobeJapan12) {
+ psName = "Ryumin-Light-RKSJ";
+ do16Bit = gTrue;
+
+ // do font substitution
+ } else {
+ if (!type3Warning && font->getType() == fontType3) {
+ error(-1, "This document uses Type 3 fonts - some text may not be correctly printed");
+ type3Warning = gTrue;
+ }
+ name = font->getName();
+ psName = NULL;
+ if (name) {
+ for (i = 0; psFonts[i].name; ++i) {
+ if (name->cmp(psFonts[i].name) == 0) {
+ psName = psFonts[i].psName;
+ break;
+ }
+ }
+ }
+ if (!psName) {
+ if (font->isFixedWidth())
+ i = 8;
+ else if (font->isSerif())
+ i = 4;
+ else
+ i = 0;
+ if (font->isBold())
+ i += 2;
+ if (font->isItalic())
+ i += 1;
+ psName = psSubstFonts[i].psName;
+ if ((code = font->getCharCode("m")) >= 0) {
+ w1 = font->getWidth(code);
+ } else {
+ w1 = 0;
+ }
+ w2 = psSubstFonts[i].mWidth;
+ xs = w1 / w2;
+ if (xs < 0.1) {
+ xs = 1;
+ }
+ if (font->getType() == fontType3) {
+ // This is a hack which makes it possible to substitute for some
+ // Type 3 fonts. The problem is that it's impossible to know what
+ // the base coordinate system used in the font is without actually
+ // rendering the font.
+ ys = xs;
+ fm = font->getFontMatrix();
+ if (fm[0] != 0) {
+ ys *= fm[3] / fm[0];
+ }
+ } else {
+ ys = 1;
+ }
+ }
+ }
+
+ // generate PostScript code to set up the font
+ if (do16Bit) {
+ writePS("/F%d_%d /%s pdfMakeFont16\n",
+ font->getID().num, font->getID().gen, psName);
+ } else {
+ writePS("/F%d_%d /%s %g %g\n",
+ font->getID().num, font->getID().gen, psName, xs, ys);
+ for (i = 0; i < 256; i += 8) {
+ writePS((i == 0) ? "[ " : " ");
+ for (j = 0; j < 8; ++j) {
+ charName = font->getCharName(i+j);
+ // this is a kludge for broken PDF files that encode char 32
+ // as .notdef
+ if (i+j == 32 && charName && !strcmp(charName, ".notdef")) {
+ charName = "space";
+ }
+ writePS("/%s", charName ? charName : ".notdef");
+ }
+ writePS((i == 256-8) ? "]\n" : "\n");
+ }
+ writePS("pdfMakeFont\n");
+ }
+}
+
+void PSOutputDev::setupEmbeddedType1Font(Ref *id, char *psName) {
+ static char hexChar[17] = "0123456789abcdef";
+ Object refObj, strObj, obj1, obj2;
+ Dict *dict;
+ int length1, length2;
+ int c;
+ int start[4];
+ GBool binMode;
+ int i;
+
+ // check if font is already embedded
+ for (i = 0; i < fontFileIDLen; ++i) {
+ if (fontFileIDs[i].num == id->num &&
+ fontFileIDs[i].gen == id->gen)
+ return;
+ }
+
+ // add entry to fontFileIDs list
+ if (fontFileIDLen >= fontFileIDSize) {
+ fontFileIDSize += 64;
+ fontFileIDs = (Ref *)grealloc(fontFileIDs, fontFileIDSize * sizeof(Ref));
+ }
+ fontFileIDs[fontFileIDLen++] = *id;
+
+ // get the font stream and info
+ refObj.initRef(id->num, id->gen);
+ refObj.fetch(xref, &strObj);
+ refObj.free();
+ if (!strObj.isStream()) {
+ error(-1, "Embedded font file object is not a stream");
+ goto err1;
+ }
+ if (!(dict = strObj.streamGetDict())) {
+ error(-1, "Embedded font stream is missing its dictionary");
+ goto err1;
+ }
+ dict->lookup("Length1", &obj1);
+ dict->lookup("Length2", &obj2);
+ if (!obj1.isInt() || !obj2.isInt()) {
+ error(-1, "Missing length fields in embedded font stream dictionary");
+ obj1.free();
+ obj2.free();
+ goto err1;
+ }
+ length1 = obj1.getInt();
+ length2 = obj2.getInt();
+ obj1.free();
+ obj2.free();
+
+ // beginning comment
+ writePS("%%%%BeginResource: font %s\n", psName);
+ embFontList->append("%%+ font ");
+ embFontList->append(psName);
+ embFontList->append("\n");
+
+ // copy ASCII portion of font
+ strObj.streamReset();
+ for (i = 0; i < length1 && (c = strObj.streamGetChar()) != EOF; ++i)
+ fputc(c, f);
+
+ // figure out if encrypted portion is binary or ASCII
+ binMode = gFalse;
+ for (i = 0; i < 4; ++i) {
+ start[i] = strObj.streamGetChar();
+ if (start[i] == EOF) {
+ error(-1, "Unexpected end of file in embedded font stream");
+ goto err1;
+ }
+ if (!((start[i] >= '0' && start[i] <= '9') ||
+ (start[i] >= 'A' && start[i] <= 'F') ||
+ (start[i] >= 'a' && start[i] <= 'f')))
+ binMode = gTrue;
+ }
+
+ // convert binary data to ASCII
+ if (binMode) {
+ for (i = 0; i < 4; ++i) {
+ fputc(hexChar[(start[i] >> 4) & 0x0f], f);
+ fputc(hexChar[start[i] & 0x0f], f);
+ }
+ while (i < length2) {
+ if ((c = strObj.streamGetChar()) == EOF)
+ break;
+ fputc(hexChar[(c >> 4) & 0x0f], f);
+ fputc(hexChar[c & 0x0f], f);
+ if (++i % 32 == 0)
+ fputc('\n', f);
+ }
+ if (i % 32 > 0)
+ fputc('\n', f);
+
+ // already in ASCII format -- just copy it
+ } else {
+ for (i = 0; i < 4; ++i)
+ fputc(start[i], f);
+ for (i = 4; i < length2; ++i) {
+ if ((c = strObj.streamGetChar()) == EOF)
+ break;
+ fputc(c, f);
+ }
+ }
+
+ // write padding and "cleartomark"
+ for (i = 0; i < 8; ++i)
+ writePS("00000000000000000000000000000000"
+ "00000000000000000000000000000000\n");
+ writePS("cleartomark\n");
+
+ // ending comment
+ writePS("%%%%EndResource\n");
+
+ err1:
+ strObj.streamClose();
+ strObj.free();
+}
+
+//~ This doesn't handle .pfb files or binary eexec data (which only
+//~ happens in pfb files?).
+void PSOutputDev::setupEmbeddedType1Font(GString *fileName, char *psName) {
+ FILE *fontFile;
+ int c;
+ int i;
+
+ // check if font is already embedded
+ for (i = 0; i < fontFileNameLen; ++i) {
+ if (!fontFileNames[i]->cmp(fileName)) {
+ return;
+ }
+ }
+
+ // add entry to fontFileNames list
+ if (fontFileNameLen >= fontFileNameSize) {
+ fontFileNameSize += 64;
+ fontFileNames = (GString **)grealloc(fontFileNames,
+ fontFileNameSize * sizeof(GString *));
+ }
+ fontFileNames[fontFileNameLen++] = fileName->copy();
+
+ // beginning comment
+ writePS("%%%%BeginResource: font %s\n", psName);
+ embFontList->append("%%+ font ");
+ embFontList->append(psName);
+ embFontList->append("\n");
+
+ // copy the font file
+ if (!(fontFile = fopen(fileName->getCString(), "rb"))) {
+ error(-1, "Couldn't open external font file");
+ return;
+ }
+ while ((c = fgetc(fontFile)) != EOF)
+ fputc(c, f);
+ fclose(fontFile);
+
+ // ending comment
+ writePS("%%%%EndResource\n");
+}
+
+void PSOutputDev::setupEmbeddedType1CFont(GfxFont *font, Ref *id,
+ char *psName) {
+ char *fontBuf;
+ int fontLen;
+ Type1CFontConverter *cvt;
+ int i;
+
+ // check if font is already embedded
+ for (i = 0; i < fontFileIDLen; ++i) {
+ if (fontFileIDs[i].num == id->num &&
+ fontFileIDs[i].gen == id->gen)
+ return;
+ }
+
+ // add entry to fontFileIDs list
+ if (fontFileIDLen >= fontFileIDSize) {
+ fontFileIDSize += 64;
+ fontFileIDs = (Ref *)grealloc(fontFileIDs, fontFileIDSize * sizeof(Ref));
+ }
+ fontFileIDs[fontFileIDLen++] = *id;
+
+ // beginning comment
+ writePS("%%%%BeginResource: font %s\n", psName);
+ embFontList->append("%%+ font ");
+ embFontList->append(psName);
+ embFontList->append("\n");
+
+ // convert it to a Type 1 font
+ fontBuf = font->readEmbFontFile(xref, &fontLen);
+ cvt = new Type1CFontConverter(fontBuf, fontLen, f);
+ cvt->convert();
+ delete cvt;
+ gfree(fontBuf);
+
+ // ending comment
+ writePS("%%%%EndResource\n");
+}
+
+void PSOutputDev::setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id,
+ char *psName) {
+ char *fontBuf;
+ int fontLen;
+ TrueTypeFontFile *ttFile;
+ int i;
+
+ // check if font is already embedded
+ for (i = 0; i < fontFileIDLen; ++i) {
+ if (fontFileIDs[i].num == id->num &&
+ fontFileIDs[i].gen == id->gen)
+ return;
+ }
+
+ // add entry to fontFileIDs list
+ if (fontFileIDLen >= fontFileIDSize) {
+ fontFileIDSize += 64;
+ fontFileIDs = (Ref *)grealloc(fontFileIDs, fontFileIDSize * sizeof(Ref));
+ }
+ fontFileIDs[fontFileIDLen++] = *id;
+
+ // beginning comment
+ writePS("%%%%BeginResource: font %s\n", psName);
+ embFontList->append("%%+ font ");
+ embFontList->append(psName);
+ embFontList->append("\n");
+
+ // convert it to a Type 42 font
+ fontBuf = font->readEmbFontFile(xref, &fontLen);
+ ttFile = new TrueTypeFontFile(fontBuf, fontLen);
+ ttFile->convertToType42(psName, font->getEncoding(), f);
+ delete ttFile;
+ gfree(fontBuf);
+
+ // ending comment
+ writePS("%%%%EndResource\n");
+}
+
+void PSOutputDev::setupImages(Dict *resDict) {
+ Object xObjDict, xObj, xObjRef, subtypeObj;
+ int i;
+
+ if (mode != psModeForm) {
+ return;
+ }
+
+ resDict->lookup("XObject", &xObjDict);
+ if (xObjDict.isDict()) {
+ for (i = 0; i < xObjDict.dictGetLength(); ++i) {
+ xObjDict.dictGetValNF(i, &xObjRef);
+ xObjDict.dictGetVal(i, &xObj);
+ if (xObj.isStream()) {
+ xObj.streamGetDict()->lookup("Subtype", &subtypeObj);
+ if (subtypeObj.isName("Image")) {
+ if (xObjRef.isRef()) {
+ setupImage(xObjRef.getRef(), xObj.getStream());
+ } else {
+ error(-1, "Image in resource dict is not an indirect reference");
+ }
+ }
+ subtypeObj.free();
+ }
+ xObj.free();
+ xObjRef.free();
+ }
+ }
+ xObjDict.free();
+}
+
+void PSOutputDev::setupImage(Ref id, Stream *str) {
+ int c;
+ int size, line, col, i;
+
+ // construct an encoder stream
+ str = new ASCII85Encoder(str);
+
+ // compute image data size
+ str->reset();
+ col = size = 0;
+ do {
+ do {
+ c = str->getChar();
+ } while (c == '\n' || c == '\r');
+ if (c == '~' || c == EOF) {
+ break;
+ }
+ if (c == 'z') {
+ ++col;
+ } else {
+ ++col;
+ for (i = 1; i <= 4; ++i) {
+ do {
+ c = str->getChar();
+ } while (c == '\n' || c == '\r');
+ if (c == '~' || c == EOF) {
+ break;
+ }
+ ++col;
+ }
+ }
+ if (col > 225) {
+ ++size;
+ col = 0;
+ }
+ } while (c != '~' && c != EOF);
+ ++size;
+ writePS("%d array dup /ImData_%d_%d exch def\n", size, id.num, id.gen);
+
+ // write the data into the array
+ str->reset();
+ line = col = 0;
+ writePS("dup 0 <~");
+ do {
+ do {
+ c = str->getChar();
+ } while (c == '\n' || c == '\r');
+ if (c == '~' || c == EOF) {
+ break;
+ }
+ if (c == 'z') {
+ fputc(c, f);
+ ++col;
+ } else {
+ fputc(c, f);
+ ++col;
+ for (i = 1; i <= 4; ++i) {
+ do {
+ c = str->getChar();
+ } while (c == '\n' || c == '\r');
+ if (c == '~' || c == EOF) {
+ break;
+ }
+ fputc(c, f);
+ ++col;
+ }
+ }
+ // each line is: "dup nnnnn <~...data...~> put<eol>"
+ // so max data length = 255 - 20 = 235
+ // chunks are 1 or 4 bytes each, so we have to stop at 232
+ // but make it 225 just to be safe
+ if (col > 225) {
+ writePS("~> put\n");
+ ++line;
+ writePS("dup %d <~", line);
+ col = 0;
+ }
+ } while (c != '~' && c != EOF);
+ writePS("~> put\n");
+ writePS("pop\n");
+
+ delete str;
+}
+
+void PSOutputDev::startPage(int pageNum, GfxState *state) {
+ int x1, y1, x2, y2, width, height, t;
+
+ switch (mode) {
+
+ case psModePS:
+ writePS("%%%%Page: %d %d\n", pageNum, seqPage);
+ writePS("%%%%BeginPageSetup\n");
+
+ // rotate, translate, and scale page
+ x1 = (int)(state->getX1() + 0.5);
+ y1 = (int)(state->getY1() + 0.5);
+ x2 = (int)(state->getX2() + 0.5);
+ y2 = (int)(state->getY2() + 0.5);
+ width = x2 - x1;
+ height = y2 - y1;
+ if (width > height && width > paperWidth) {
+ landscape = gTrue;
+ writePS("%%%%PageOrientation: Landscape\n");
+ writePS("pdfStartPage\n");
+ writePS("90 rotate\n");
+ tx = -x1;
+ ty = -(y1 + paperWidth);
+ t = width;
+ width = height;
+ height = t;
+ } else {
+ landscape = gFalse;
+ writePS("%%%%PageOrientation: Portrait\n");
+ writePS("pdfStartPage\n");
+ tx = -x1;
+ ty = -y1;
+ }
+ if (width < paperWidth) {
+ tx += (paperWidth - width) / 2;
+ }
+ if (height < paperHeight) {
+ ty += (paperHeight - height) / 2;
+ }
+ if (tx != 0 || ty != 0) {
+ writePS("%g %g translate\n", tx, ty);
+ }
+ if (width > paperWidth || height > paperHeight) {
+ xScale = (double)paperWidth / (double)width;
+ yScale = (double)paperHeight / (double)height;
+ if (yScale < xScale) {
+ xScale = yScale;
+ }
+ writePS("%0.4f %0.4f scale\n", xScale, xScale);
+ } else {
+ xScale = yScale = 1;
+ }
+
+ writePS("%%%%EndPageSetup\n");
+ ++seqPage;
+ break;
+
+ case psModeEPS:
+ writePS("pdfStartPage\n");
+ tx = ty = 0;
+ xScale = yScale = 1;
+ landscape = gFalse;
+ break;
+
+ case psModeForm:
+ writePS("/PaintProc {\n");
+ writePS("begin xpdf begin\n");
+ writePS("pdfStartPage\n");
+ tx = ty = 0;
+ xScale = yScale = 1;
+ landscape = gFalse;
+ break;
+ }
+}
+
+void PSOutputDev::endPage() {
+ if (mode == psModeForm) {
+ writePS("pdfEndPage\n");
+ writePS("end end\n");
+ writePS("} def\n");
+ writePS("end end\n");
+ } else {
+ writePS("showpage\n");
+ writePS("%%%%PageTrailer\n");
+ writePS("pdfEndPage\n");
+ }
+}
+
+void PSOutputDev::saveState(GfxState *state) {
+ writePS("q\n");
+}
+
+void PSOutputDev::restoreState(GfxState *state) {
+ writePS("Q\n");
+}
+
+void PSOutputDev::updateCTM(GfxState *state, double m11, double m12,
+ double m21, double m22, double m31, double m32) {
+ writePS("[%g %g %g %g %g %g] cm\n", m11, m12, m21, m22, m31, m32);
+}
+
+void PSOutputDev::updateLineDash(GfxState *state) {
+ double *dash;
+ double start;
+ int length, i;
+
+ state->getLineDash(&dash, &length, &start);
+ writePS("[");
+ for (i = 0; i < length; ++i)
+ writePS("%g%s", dash[i], (i == length-1) ? "" : " ");
+ writePS("] %g d\n", start);
+}
+
+void PSOutputDev::updateFlatness(GfxState *state) {
+ writePS("%d i\n", state->getFlatness());
+}
+
+void PSOutputDev::updateLineJoin(GfxState *state) {
+ writePS("%d j\n", state->getLineJoin());
+}
+
+void PSOutputDev::updateLineCap(GfxState *state) {
+ writePS("%d J\n", state->getLineCap());
+}
+
+void PSOutputDev::updateMiterLimit(GfxState *state) {
+ writePS("%g M\n", state->getMiterLimit());
+}
+
+void PSOutputDev::updateLineWidth(GfxState *state) {
+ writePS("%g w\n", state->getLineWidth());
+}
+
+void PSOutputDev::updateFillColor(GfxState *state) {
+ GfxColor color;
+ double gray;
+ GfxRGB rgb;
+ GfxCMYK cmyk;
+ GfxSeparationColorSpace *sepCS;
+
+ switch (level) {
+ case psLevel1:
+ state->getFillGray(&gray);
+ writePS("%g g\n", gray);
+ break;
+ case psLevel1Sep:
+ state->getFillCMYK(&cmyk);
+ writePS("%g %g %g %g k\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k);
+ break;
+ case psLevel2:
+ if (state->getFillColorSpace()->getMode() == csDeviceCMYK) {
+ state->getFillCMYK(&cmyk);
+ writePS("%g %g %g %g k\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k);
+ } else {
+ state->getFillRGB(&rgb);
+ if (rgb.r == rgb.g && rgb.g == rgb.b) {
+ writePS("%g g\n", rgb.r);
+ } else {
+ writePS("%g %g %g rg\n", rgb.r, rgb.g, rgb.b);
+ }
+ }
+ break;
+ case psLevel2Sep:
+ if (state->getFillColorSpace()->getMode() == csSeparation) {
+ sepCS = (GfxSeparationColorSpace *)state->getFillColorSpace();
+ color.c[0] = 1;
+ sepCS->getCMYK(&color, &cmyk);
+ writePS("%g %g %g %g %g (%s) ck\n",
+ state->getFillColor()->c[0],
+ cmyk.c, cmyk.m, cmyk.y, cmyk.k,
+ sepCS->getName()->getCString());
+ addCustomColor(sepCS);
+ } else {
+ state->getFillCMYK(&cmyk);
+ writePS("%g %g %g %g k\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k);
+ addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k);
+ }
+ break;
+ }
+}
+
+void PSOutputDev::updateStrokeColor(GfxState *state) {
+ GfxColor color;
+ double gray;
+ GfxRGB rgb;
+ GfxCMYK cmyk;
+ GfxSeparationColorSpace *sepCS;
+
+ switch (level) {
+ case psLevel1:
+ state->getStrokeGray(&gray);
+ writePS("%g G\n", gray);
+ break;
+ case psLevel1Sep:
+ state->getStrokeCMYK(&cmyk);
+ writePS("%g %g %g %g K\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k);
+ break;
+ case psLevel2:
+ if (state->getStrokeColorSpace()->getMode() == csDeviceCMYK) {
+ state->getStrokeCMYK(&cmyk);
+ writePS("%g %g %g %g K\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k);
+ } else {
+ state->getStrokeRGB(&rgb);
+ if (rgb.r == rgb.g && rgb.g == rgb.b) {
+ writePS("%g G\n", rgb.r);
+ } else {
+ writePS("%g %g %g RG\n", rgb.r, rgb.g, rgb.b);
+ }
+ }
+ break;
+ case psLevel2Sep:
+ if (state->getStrokeColorSpace()->getMode() == csSeparation) {
+ sepCS = (GfxSeparationColorSpace *)state->getStrokeColorSpace();
+ color.c[0] = 1;
+ sepCS->getCMYK(&color, &cmyk);
+ writePS("%g %g %g %g %g (%s) CK\n",
+ state->getStrokeColor()->c[0],
+ cmyk.c, cmyk.m, cmyk.y, cmyk.k,
+ sepCS->getName()->getCString());
+ addCustomColor(sepCS);
+ } else {
+ state->getStrokeCMYK(&cmyk);
+ writePS("%g %g %g %g K\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k);
+ addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k);
+ }
+ break;
+ }
+}
+
+void PSOutputDev::addProcessColor(double c, double m, double y, double k) {
+ if (c > 0) {
+ processColors |= psProcessCyan;
+ }
+ if (m > 0) {
+ processColors |= psProcessMagenta;
+ }
+ if (y > 0) {
+ processColors |= psProcessYellow;
+ }
+ if (k > 0) {
+ processColors |= psProcessBlack;
+ }
+}
+
+void PSOutputDev::addCustomColor(GfxSeparationColorSpace *sepCS) {
+ PSOutCustomColor *cc;
+ GfxColor color;
+ GfxCMYK cmyk;
+
+ for (cc = customColors; cc; cc = cc->next) {
+ if (!cc->name->cmp(sepCS->getName())) {
+ return;
+ }
+ }
+ color.c[0] = 1;
+ sepCS->getCMYK(&color, &cmyk);
+ cc = new PSOutCustomColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k,
+ sepCS->getName()->copy());
+ cc->next = customColors;
+ customColors = cc;
+}
+
+void PSOutputDev::updateFont(GfxState *state) {
+ if (state->getFont()) {
+ writePS("/F%d_%d %g Tf\n",
+ state->getFont()->getID().num, state->getFont()->getID().gen,
+ state->getFontSize());
+ }
+}
+
+void PSOutputDev::updateTextMat(GfxState *state) {
+ double *mat;
+
+ mat = state->getTextMat();
+ writePS("[%g %g %g %g %g %g] Tm\n",
+ mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
+}
+
+void PSOutputDev::updateCharSpace(GfxState *state) {
+ writePS("%g Tc\n", state->getCharSpace());
+}
+
+void PSOutputDev::updateRender(GfxState *state) {
+ writePS("%d Tr\n", state->getRender());
+}
+
+void PSOutputDev::updateRise(GfxState *state) {
+ writePS("%g Ts\n", state->getRise());
+}
+
+void PSOutputDev::updateWordSpace(GfxState *state) {
+ writePS("%g Tw\n", state->getWordSpace());
+}
+
+void PSOutputDev::updateHorizScaling(GfxState *state) {
+ writePS("%g Tz\n", state->getHorizScaling());
+}
+
+void PSOutputDev::updateTextPos(GfxState *state) {
+ writePS("%g %g Td\n", state->getLineX(), state->getLineY());
+}
+
+void PSOutputDev::updateTextShift(GfxState *state, double shift) {
+ writePS("%g TJm\n", shift);
+}
+
+void PSOutputDev::stroke(GfxState *state) {
+ doPath(state->getPath());
+ writePS("S\n");
+}
+
+void PSOutputDev::fill(GfxState *state) {
+ doPath(state->getPath());
+ writePS("f\n");
+}
+
+void PSOutputDev::eoFill(GfxState *state) {
+ doPath(state->getPath());
+ writePS("f*\n");
+}
+
+void PSOutputDev::clip(GfxState *state) {
+ doPath(state->getPath());
+ writePS("W\n");
+}
+
+void PSOutputDev::eoClip(GfxState *state) {
+ doPath(state->getPath());
+ writePS("W*\n");
+}
+
+void PSOutputDev::doPath(GfxPath *path) {
+ GfxSubpath *subpath;
+ double x0, y0, x1, y1, x2, y2, x3, y3, x4, y4;
+ int n, m, i, j;
+
+ n = path->getNumSubpaths();
+
+ if (n == 1 && path->getSubpath(0)->getNumPoints() == 5) {
+ subpath = path->getSubpath(0);
+ x0 = subpath->getX(0);
+ y0 = subpath->getY(0);
+ x4 = subpath->getX(4);
+ y4 = subpath->getY(4);
+ if (x4 == x0 && y4 == y0) {
+ x1 = subpath->getX(1);
+ y1 = subpath->getY(1);
+ x2 = subpath->getX(2);
+ y2 = subpath->getY(2);
+ x3 = subpath->getX(3);
+ y3 = subpath->getY(3);
+ if (x0 == x1 && x2 == x3 && y0 == y3 && y1 == y2) {
+ writePS("%g %g %g %g re\n",
+ x0 < x2 ? x0 : x2, y0 < y1 ? y0 : y1,
+ fabs(x2 - x0), fabs(y1 - y0));
+ return;
+ } else if (x0 == x3 && x1 == x2 && y0 == y1 && y2 == y3) {
+ writePS("%g %g %g %g re\n",
+ x0 < x1 ? x0 : x1, y0 < y2 ? y0 : y2,
+ fabs(x1 - x0), fabs(y2 - y0));
+ return;
+ }
+ }
+ }
+
+ for (i = 0; i < n; ++i) {
+ subpath = path->getSubpath(i);
+ m = subpath->getNumPoints();
+ writePS("%g %g m\n", subpath->getX(0), subpath->getY(0));
+ j = 1;
+ while (j < m) {
+ if (subpath->getCurve(j)) {
+ writePS("%g %g %g %g %g %g c\n", subpath->getX(j), subpath->getY(j),
+ subpath->getX(j+1), subpath->getY(j+1),
+ subpath->getX(j+2), subpath->getY(j+2));
+ j += 3;
+ } else {
+ writePS("%g %g l\n", subpath->getX(j), subpath->getY(j));
+ ++j;
+ }
+ }
+ if (subpath->isClosed()) {
+ writePS("h\n");
+ }
+ }
+}
+
+void PSOutputDev::drawString(GfxState *state, GString *s) {
+ // check for invisible text -- this is used by Acrobat Capture
+ if ((state->getRender() & 3) == 3)
+ return;
+
+ writePSString(s);
+ writePS(" %g Tj\n", state->getFont()->getWidth(s));
+}
+
+void PSOutputDev::drawString16(GfxState *state, GString *s) {
+ int c1, c2;
+ double w;
+ int i;
+
+ // check for invisible text -- this is used by Acrobat Capture
+ if ((state->getRender() & 3) == 3)
+ return;
+
+ switch (state->getFont()->getCharSet16()) {
+
+ case font16AdobeJapan12:
+#if JAPANESE_SUPPORT
+ writePS("<");
+ w = 0;
+ for (i = 0; i < s->getLength(); i += 2) {
+ c1 = ((s->getChar(i) & 0xff) << 8) + (s->getChar(i+1) & 0xff);
+ if (c1 <= 8285) {
+ c2 = japan12ToRKSJ[c1];
+ } else {
+ c2 = 0x20;
+ }
+ if (c2 <= 0xff) {
+ writePS("%02x", c2);
+ } else {
+ writePS("%02x%02x", c2 >> 8, c2 & 0xff);
+ }
+ w += state->getFont()->getWidth16(c1);
+ }
+ writePS("> %g Tj\n", w);
+#endif
+ break;
+
+ case font16AdobeGB12:
+ break;
+
+ case font16AdobeCNS13:
+ break;
+ }
+}
+
+void PSOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GBool invert,
+ GBool inlineImg) {
+ int len;
+
+ len = height * ((width + 7) / 8);
+ if (level == psLevel1 || level == psLevel1Sep) {
+ doImageL1(NULL, invert, inlineImg, str, width, height, len);
+ } else {
+ doImageL2(ref, NULL, invert, inlineImg, str, width, height, len);
+ }
+}
+
+void PSOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GfxImageColorMap *colorMap,
+ int *maskColors, GBool inlineImg) {
+ int len;
+
+ len = height * ((width * colorMap->getNumPixelComps() *
+ colorMap->getBits() + 7) / 8);
+ switch (level) {
+ case psLevel1:
+ doImageL1(colorMap, gFalse, inlineImg, str, width, height, len);
+ break;
+ case psLevel1Sep:
+ //~ handle indexed, separation, ... color spaces
+ doImageL1Sep(colorMap, gFalse, inlineImg, str, width, height, len);
+ break;
+ case psLevel2:
+ case psLevel2Sep:
+ doImageL2(ref, colorMap, gFalse, inlineImg, str, width, height, len);
+ break;
+ }
+}
+
+void PSOutputDev::doImageL1(GfxImageColorMap *colorMap,
+ GBool invert, GBool inlineImg,
+ Stream *str, int width, int height, int len) {
+ ImageStream *imgStr;
+ Guchar pixBuf[gfxColorMaxComps];
+ double gray;
+ int x, y, i;
+
+ // width, height, matrix, bits per component
+ if (colorMap) {
+ writePS("%d %d 8 [%d 0 0 %d 0 %d] pdfIm1\n",
+ width, height,
+ width, -height, height);
+ } else {
+ writePS("%d %d %s [%d 0 0 %d 0 %d] pdfImM1\n",
+ width, height, invert ? "true" : "false",
+ width, -height, height);
+ }
+
+ // image
+ if (colorMap) {
+
+ // set up to process the data stream
+ imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+
+ // process the data stream
+ i = 0;
+ for (y = 0; y < height; ++y) {
+
+ // write the line
+ for (x = 0; x < width; ++x) {
+ imgStr->getPixel(pixBuf);
+ colorMap->getGray(pixBuf, &gray);
+ fprintf(f, "%02x", (int)(gray * 255 + 0.5));
+ if (++i == 32) {
+ fputc('\n', f);
+ i = 0;
+ }
+ }
+ }
+ if (i != 0)
+ fputc('\n', f);
+ delete imgStr;
+
+ // imagemask
+ } else {
+ str->reset();
+ i = 0;
+ for (y = 0; y < height; ++y) {
+ for (x = 0; x < width; x += 8) {
+ fprintf(f, "%02x", str->getChar() & 0xff);
+ if (++i == 32) {
+ fputc('\n', f);
+ i = 0;
+ }
+ }
+ }
+ if (i != 0)
+ fputc('\n', f);
+ }
+}
+
+void PSOutputDev::doImageL1Sep(GfxImageColorMap *colorMap,
+ GBool invert, GBool inlineImg,
+ Stream *str, int width, int height, int len) {
+ ImageStream *imgStr;
+ Guchar *lineBuf;
+ Guchar pixBuf[gfxColorMaxComps];
+ GfxCMYK cmyk;
+ int x, y, i, comp;
+
+ // width, height, matrix, bits per component
+ writePS("%d %d 8 [%d 0 0 %d 0 %d] pdfIm1Sep\n",
+ width, height,
+ width, -height, height);
+
+ // allocate a line buffer
+ lineBuf = (Guchar *)gmalloc(4 * width);
+
+ // set up to process the data stream
+ imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+
+ // process the data stream
+ i = 0;
+ for (y = 0; y < height; ++y) {
+
+ // read the line
+ for (x = 0; x < width; ++x) {
+ imgStr->getPixel(pixBuf);
+ colorMap->getCMYK(pixBuf, &cmyk);
+ lineBuf[4*x+0] = (int)(255 * cmyk.c + 0.5);
+ lineBuf[4*x+1] = (int)(255 * cmyk.m + 0.5);
+ lineBuf[4*x+2] = (int)(255 * cmyk.y + 0.5);
+ lineBuf[4*x+3] = (int)(255 * cmyk.k + 0.5);
+ }
+
+ // write one line of each color component
+ for (comp = 0; comp < 4; ++comp) {
+ for (x = 0; x < width; ++x) {
+ fprintf(f, "%02x", lineBuf[4*x + comp]);
+ if (++i == 32) {
+ fputc('\n', f);
+ i = 0;
+ }
+ }
+ }
+ }
+
+ if (i != 0) {
+ fputc('\n', f);
+ }
+
+ delete imgStr;
+ gfree(lineBuf);
+}
+
+void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
+ GBool invert, GBool inlineImg,
+ Stream *str, int width, int height, int len) {
+ GString *s;
+ int n, numComps;
+ GBool useRLE, useA85;
+ GfxSeparationColorSpace *sepCS;
+ GfxColor color;
+ GfxCMYK cmyk;
+ int c;
+ int i;
+
+ // color space
+ if (colorMap) {
+ dumpColorSpaceL2(colorMap->getColorSpace());
+ writePS(" setcolorspace\n");
+ }
+
+ // set up to use the array created by setupImages()
+ if (mode == psModeForm && !inlineImg) {
+ writePS("ImData_%d_%d 0\n", ref->getRefNum(), ref->getRefGen());
+ }
+
+ // image dictionary
+ writePS("<<\n /ImageType 1\n");
+
+ // width, height, matrix, bits per component
+ writePS(" /Width %d\n", width);
+ writePS(" /Height %d\n", height);
+ writePS(" /ImageMatrix [%d 0 0 %d 0 %d]\n", width, -height, height);
+ writePS(" /BitsPerComponent %d\n",
+ colorMap ? colorMap->getBits() : 1);
+
+ // decode
+ if (colorMap) {
+ writePS(" /Decode [");
+ if (colorMap->getColorSpace()->getMode() == csSeparation) {
+ //~ this is a kludge -- see comment in dumpColorSpaceL2
+ n = (1 << colorMap->getBits()) - 1;
+ writePS("%g %g", colorMap->getDecodeLow(0) * n,
+ colorMap->getDecodeHigh(0) * n);
+ } else {
+ numComps = colorMap->getNumPixelComps();
+ for (i = 0; i < numComps; ++i) {
+ if (i > 0) {
+ writePS(" ");
+ }
+ writePS("%g %g", colorMap->getDecodeLow(i),
+ colorMap->getDecodeHigh(i));
+ }
+ }
+ writePS("]\n");
+ } else {
+ writePS(" /Decode [%d %d]\n", invert ? 1 : 0, invert ? 0 : 1);
+ }
+
+ if (mode == psModeForm) {
+
+ if (inlineImg) {
+
+ // data source
+ writePS(" /DataSource <~\n");
+
+ // write image data stream, using ASCII85 encode filter
+ str = new FixedLengthEncoder(str, len);
+ str = new ASCII85Encoder(str);
+ str->reset();
+ while ((c = str->getChar()) != EOF) {
+ fputc(c, f);
+ }
+ fputc('\n', f);
+ delete str;
+
+ } else {
+ writePS(" /DataSource { 2 copy get exch 1 add exch }\n");
+ }
+
+ // end of image dictionary
+ writePS(">>\n%s\n", colorMap ? "image" : "imagemask");
+
+ // get rid of the array and index
+ if (!inlineImg) {
+ writePS("pop pop\n");
+ }
+
+ } else {
+
+ // data source
+ writePS(" /DataSource currentfile\n");
+ s = str->getPSFilter(" ");
+ if (inlineImg || !s) {
+ useRLE = gTrue;
+ useA85 = gTrue;
+ } else {
+ useRLE = gFalse;
+ useA85 = str->isBinary();
+ }
+ if (useA85) {
+ writePS(" /ASCII85Decode filter\n");
+ }
+ if (useRLE) {
+ writePS(" /RunLengthDecode filter\n");
+ } else {
+ writePS("%s", s->getCString());
+ }
+ if (s) {
+ delete s;
+ }
+
+ // cut off inline image streams at appropriate length
+ if (inlineImg) {
+ str = new FixedLengthEncoder(str, len);
+ } else if (!useRLE) {
+ str = str->getBaseStream();
+ }
+
+ // add RunLengthEncode and ASCII85 encode filters
+ if (useRLE) {
+ str = new RunLengthEncoder(str);
+ }
+ if (useA85) {
+ str = new ASCII85Encoder(str);
+ }
+
+ // end of image dictionary
+ writePS(">>\n");
+#if OPI_SUPPORT
+ if (opi13Nest) {
+ if (inlineImg) {
+ // this can't happen -- OPI dictionaries are in XObjects
+ error(-1, "Internal: OPI in inline image");
+ n = 0;
+ } else {
+ // need to read the stream to count characters -- the length
+ // is data-dependent (because of A85 and RLE filters)
+ str->reset();
+ n = 0;
+ while ((c = str->getChar()) != EOF) {
+ ++n;
+ }
+ }
+ // +6/7 for "pdfIm\n" / "pdfImM\n"
+ // +8 for newline + trailer
+ n += colorMap ? 14 : 15;
+ writePS("%%%%BeginData: %d Hex Bytes\n", n);
+ }
+#endif
+ if (level == psLevel2Sep && colorMap &&
+ colorMap->getColorSpace()->getMode() == csSeparation) {
+ color.c[0] = 1;
+ sepCS = (GfxSeparationColorSpace *)colorMap->getColorSpace();
+ sepCS->getCMYK(&color, &cmyk);
+ writePS("%g %g %g %g (%s) pdfImSep\n",
+ cmyk.c, cmyk.m, cmyk.y, cmyk.k, sepCS->getName()->getCString());
+ } else {
+ writePS("%s\n", colorMap ? "pdfIm" : "pdfImM");
+ }
+
+ // copy the stream data
+ str->reset();
+ while ((c = str->getChar()) != EOF) {
+ fputc(c, f);
+ }
+
+ // add newline and trailer to the end
+ fputc('\n', f);
+ fputs("%-EOD-\n", f);
+#if OPI_SUPPORT
+ if (opi13Nest) {
+ writePS("%%%%EndData\n");
+ }
+#endif
+
+ // delete encoders
+ if (useRLE || useA85) {
+ delete str;
+ }
+ }
+}
+
+void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace) {
+ GfxCalGrayColorSpace *calGrayCS;
+ GfxCalRGBColorSpace *calRGBCS;
+ GfxLabColorSpace *labCS;
+ GfxIndexedColorSpace *indexedCS;
+ GfxSeparationColorSpace *separationCS;
+ Guchar *lookup;
+ double x[gfxColorMaxComps], y[gfxColorMaxComps];
+ GfxColor color;
+ GfxCMYK cmyk;
+ int n, numComps;
+ int i, j, k;
+
+ switch (colorSpace->getMode()) {
+
+ case csDeviceGray:
+ writePS("/DeviceGray");
+ processColors |= psProcessBlack;
+ break;
+
+ case csCalGray:
+ calGrayCS = (GfxCalGrayColorSpace *)colorSpace;
+ writePS("[/CIEBasedA <<\n");
+ writePS(" /DecodeA {%g exp} bind\n", calGrayCS->getGamma());
+ writePS(" /MatrixA [%g %g %g]\n",
+ calGrayCS->getWhiteX(), calGrayCS->getWhiteY(),
+ calGrayCS->getWhiteZ());
+ writePS(" /WhitePoint [%g %g %g]\n",
+ calGrayCS->getWhiteX(), calGrayCS->getWhiteY(),
+ calGrayCS->getWhiteZ());
+ writePS(" /BlackPoint [%g %g %g]\n",
+ calGrayCS->getBlackX(), calGrayCS->getBlackY(),
+ calGrayCS->getBlackZ());
+ writePS(">>]");
+ processColors |= psProcessBlack;
+ break;
+
+ case csDeviceRGB:
+ writePS("/DeviceRGB");
+ processColors |= psProcessCMYK;
+ break;
+
+ case csCalRGB:
+ calRGBCS = (GfxCalRGBColorSpace *)colorSpace;
+ writePS("[/CIEBasedABC <<\n");
+ writePS(" /DecodeABC [{%g exp} bind {%g exp} bind {%g exp} bind]\n",
+ calRGBCS->getGammaR(), calRGBCS->getGammaG(),
+ calRGBCS->getGammaB());
+ writePS(" /MatrixABC [%g %g %g %g %g %g %g %g %g]\n",
+ calRGBCS->getMatrix()[0], calRGBCS->getMatrix()[1],
+ calRGBCS->getMatrix()[2], calRGBCS->getMatrix()[3],
+ calRGBCS->getMatrix()[4], calRGBCS->getMatrix()[5],
+ calRGBCS->getMatrix()[6], calRGBCS->getMatrix()[7],
+ calRGBCS->getMatrix()[8]);
+ writePS(" /WhitePoint [%g %g %g]\n",
+ calRGBCS->getWhiteX(), calRGBCS->getWhiteY(),
+ calRGBCS->getWhiteZ());
+ writePS(" /BlackPoint [%g %g %g]\n",
+ calRGBCS->getBlackX(), calRGBCS->getBlackY(),
+ calRGBCS->getBlackZ());
+ writePS(">>]");
+ processColors |= psProcessCMYK;
+ break;
+
+ case csDeviceCMYK:
+ writePS("/DeviceCMYK");
+ processColors |= psProcessCMYK;
+ break;
+
+ case csLab:
+ labCS = (GfxLabColorSpace *)colorSpace;
+ writePS("[/CIEBasedABC <<\n");
+ writePS(" /RangeABC [0 100 %g %g %g %g]\n",
+ labCS->getAMin(), labCS->getAMax(),
+ labCS->getBMin(), labCS->getBMax());
+ writePS(" /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind]\n");
+ writePS(" /MatrixABC [1 1 1 1 0 0 0 0 -1]\n");
+ writePS(" /DecodeLMN\n");
+ writePS(" [{dup 6 29 div ge {dup dup mul mul}\n");
+ writePS(" {4 29 div sub 108 841 div mul } ifelse %g mul} bind\n",
+ labCS->getWhiteX());
+ writePS(" {dup 6 29 div ge {dup dup mul mul}\n");
+ writePS(" {4 29 div sub 108 841 div mul } ifelse %g mul} bind\n",
+ labCS->getWhiteY());
+ writePS(" {dup 6 29 div ge {dup dup mul mul}\n");
+ writePS(" {4 29 div sub 108 841 div mul } ifelse %g mul} bind]\n",
+ labCS->getWhiteZ());
+ writePS(" /WhitePoint [%g %g %g]\n",
+ labCS->getWhiteX(), labCS->getWhiteY(), labCS->getWhiteZ());
+ writePS(" /BlackPoint [%g %g %g]\n",
+ labCS->getBlackX(), labCS->getBlackY(), labCS->getBlackZ());
+ writePS(">>]");
+ processColors |= psProcessCMYK;
+ break;
+
+ case csICCBased:
+ dumpColorSpaceL2(((GfxICCBasedColorSpace *)colorSpace)->getAlt());
+ break;
+
+ case csIndexed:
+ indexedCS = (GfxIndexedColorSpace *)colorSpace;
+ writePS("[/Indexed ");
+ dumpColorSpaceL2(indexedCS->getBase());
+ n = indexedCS->getIndexHigh();
+ numComps = indexedCS->getBase()->getNComps();
+ lookup = indexedCS->getLookup();
+ writePS(" %d <\n", n);
+ for (i = 0; i <= n; i += 8) {
+ writePS(" ");
+ for (j = i; j < i+8 && j <= n; ++j) {
+ for (k = 0; k < numComps; ++k) {
+ writePS("%02x", lookup[j * numComps + k]);
+ }
+ color.c[0] = j;
+ indexedCS->getCMYK(&color, &cmyk);
+ addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k);
+ }
+ writePS("\n");
+ }
+ writePS(">]");
+ break;
+
+ case csSeparation:
+ //~ this is a kludge -- the correct thing would to ouput a
+ //~ separation color space, with the specified alternate color
+ //~ space and tint transform
+ separationCS = (GfxSeparationColorSpace *)colorSpace;
+ writePS("[/Indexed ");
+ dumpColorSpaceL2(separationCS->getAlt());
+ writePS(" 255 <\n");
+ numComps = separationCS->getAlt()->getNComps();
+ for (i = 0; i <= 255; i += 8) {
+ writePS(" ");
+ for (j = i; j < i+8 && j <= 255; ++j) {
+ x[0] = (double)j / 255.0;
+ separationCS->getFunc()->transform(x, y);
+ for (k = 0; k < numComps; ++k) {
+ writePS("%02x", (int)(255 * y[k] + 0.5));
+ }
+ }
+ writePS("\n");
+ }
+ writePS(">]");
+ addCustomColor(separationCS);
+ break;
+
+ case csDeviceN:
+ // DeviceN color spaces are a Level 3 PostScript feature.
+ dumpColorSpaceL2(((GfxDeviceNColorSpace *)colorSpace)->getAlt());
+ break;
+
+ case csPattern:
+ //~ unimplemented
+ break;
+
+ }
+}
+
+#if OPI_SUPPORT
+void PSOutputDev::opiBegin(GfxState *state, Dict *opiDict) {
+ Object dict;
+
+ if (doOPI) {
+ opiDict->lookup("2.0", &dict);
+ if (dict.isDict()) {
+ opiBegin20(state, dict.getDict());
+ dict.free();
+ } else {
+ dict.free();
+ opiDict->lookup("1.3", &dict);
+ if (dict.isDict()) {
+ opiBegin13(state, dict.getDict());
+ }
+ dict.free();
+ }
+ }
+}
+
+void PSOutputDev::opiBegin20(GfxState *state, Dict *dict) {
+ Object obj1, obj2, obj3, obj4;
+ double width, height, left, right, top, bottom;
+ int w, h;
+ int i;
+
+ writePS("%%%%BeginOPI: 2.0\n");
+ writePS("%%%%Distilled\n");
+
+ dict->lookup("F", &obj1);
+ if (getFileSpec(&obj1, &obj2)) {
+ writePS("%%%%ImageFileName: %s\n",
+ obj2.getString()->getCString());
+ obj2.free();
+ }
+ obj1.free();
+
+ dict->lookup("MainImage", &obj1);
+ if (obj1.isString()) {
+ writePS("%%%%MainImage: %s\n", obj1.getString()->getCString());
+ }
+ obj1.free();
+
+ //~ ignoring 'Tags' entry
+ //~ need to use writePSString() and deal with >255-char lines
+
+ dict->lookup("Size", &obj1);
+ if (obj1.isArray() && obj1.arrayGetLength() == 2) {
+ obj1.arrayGet(0, &obj2);
+ width = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ height = obj2.getNum();
+ obj2.free();
+ writePS("%%%%ImageDimensions: %g %g\n", width, height);
+ }
+ obj1.free();
+
+ dict->lookup("CropRect", &obj1);
+ if (obj1.isArray() && obj1.arrayGetLength() == 4) {
+ obj1.arrayGet(0, &obj2);
+ left = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ top = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(2, &obj2);
+ right = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(3, &obj2);
+ bottom = obj2.getNum();
+ obj2.free();
+ writePS("%%%%ImageCropRect: %g %g %g %g\n", left, top, right, bottom);
+ }
+ obj1.free();
+
+ dict->lookup("Overprint", &obj1);
+ if (obj1.isBool()) {
+ writePS("%%%%ImageOverprint: %s\n", obj1.getBool() ? "true" : "false");
+ }
+ obj1.free();
+
+ dict->lookup("Inks", &obj1);
+ if (obj1.isName()) {
+ writePS("%%%%ImageInks: %s\n", obj1.getName());
+ } else if (obj1.isArray() && obj1.arrayGetLength() >= 1) {
+ obj1.arrayGet(0, &obj2);
+ if (obj2.isName()) {
+ writePS("%%%%ImageInks: %s %d",
+ obj2.getName(), (obj1.arrayGetLength() - 1) / 2);
+ for (i = 1; i+1 < obj1.arrayGetLength(); i += 2) {
+ obj1.arrayGet(i, &obj3);
+ obj1.arrayGet(i+1, &obj4);
+ if (obj3.isString() && obj4.isNum()) {
+ writePS(" ");
+ writePSString(obj3.getString());
+ writePS(" %g", obj4.getNum());
+ }
+ obj3.free();
+ obj4.free();
+ }
+ writePS("\n");
+ }
+ obj2.free();
+ }
+ obj1.free();
+
+ writePS("gsave\n");
+
+ writePS("%%%%BeginIncludedImage\n");
+
+ dict->lookup("IncludedImageDimensions", &obj1);
+ if (obj1.isArray() && obj1.arrayGetLength() == 2) {
+ obj1.arrayGet(0, &obj2);
+ w = obj2.getInt();
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ h = obj2.getInt();
+ obj2.free();
+ writePS("%%%%IncludedImageDimensions: %d %d\n", w, h);
+ }
+ obj1.free();
+
+ dict->lookup("IncludedImageQuality", &obj1);
+ if (obj1.isNum()) {
+ writePS("%%%%IncludedImageQuality: %g\n", obj1.getNum());
+ }
+ obj1.free();
+
+ ++opi20Nest;
+}
+
+void PSOutputDev::opiBegin13(GfxState *state, Dict *dict) {
+ Object obj1, obj2;
+ int left, right, top, bottom, samples, bits, width, height;
+ double c, m, y, k;
+ double llx, lly, ulx, uly, urx, ury, lrx, lry;
+ double tllx, tlly, tulx, tuly, turx, tury, tlrx, tlry;
+ double horiz, vert;
+ int i, j;
+
+ writePS("save\n");
+ writePS("/opiMatrix2 matrix currentmatrix def\n");
+ writePS("opiMatrix setmatrix\n");
+
+ dict->lookup("F", &obj1);
+ if (getFileSpec(&obj1, &obj2)) {
+ writePS("%%ALDImageFileName: %s\n",
+ obj2.getString()->getCString());
+ obj2.free();
+ }
+ obj1.free();
+
+ dict->lookup("CropRect", &obj1);
+ if (obj1.isArray() && obj1.arrayGetLength() == 4) {
+ obj1.arrayGet(0, &obj2);
+ left = obj2.getInt();
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ top = obj2.getInt();
+ obj2.free();
+ obj1.arrayGet(2, &obj2);
+ right = obj2.getInt();
+ obj2.free();
+ obj1.arrayGet(3, &obj2);
+ bottom = obj2.getInt();
+ obj2.free();
+ writePS("%%ALDImageCropRect: %d %d %d %d\n", left, top, right, bottom);
+ }
+ obj1.free();
+
+ dict->lookup("Color", &obj1);
+ if (obj1.isArray() && obj1.arrayGetLength() == 5) {
+ obj1.arrayGet(0, &obj2);
+ c = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ m = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(2, &obj2);
+ y = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(3, &obj2);
+ k = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(4, &obj2);
+ if (obj2.isString()) {
+ writePS("%%ALDImageColor: %g %g %g %g ", c, m, y, k);
+ writePSString(obj2.getString());
+ writePS("\n");
+ }
+ obj2.free();
+ }
+ obj1.free();
+
+ dict->lookup("ColorType", &obj1);
+ if (obj1.isName()) {
+ writePS("%%ALDImageColorType: %s\n", obj1.getName());
+ }
+ obj1.free();
+
+ //~ ignores 'Comments' entry
+ //~ need to handle multiple lines
+
+ dict->lookup("CropFixed", &obj1);
+ if (obj1.isArray()) {
+ obj1.arrayGet(0, &obj2);
+ ulx = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ uly = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(2, &obj2);
+ lrx = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(3, &obj2);
+ lry = obj2.getNum();
+ obj2.free();
+ writePS("%%ALDImageCropFixed: %g %g %g %g\n", ulx, uly, lrx, lry);
+ }
+ obj1.free();
+
+ dict->lookup("GrayMap", &obj1);
+ if (obj1.isArray()) {
+ writePS("%%ALDImageGrayMap:");
+ for (i = 0; i < obj1.arrayGetLength(); i += 16) {
+ if (i > 0) {
+ writePS("\n%%%%+");
+ }
+ for (j = 0; j < 16 && i+j < obj1.arrayGetLength(); ++j) {
+ obj1.arrayGet(i+j, &obj2);
+ writePS(" %d", obj2.getInt());
+ obj2.free();
+ }
+ }
+ writePS("\n");
+ }
+ obj1.free();
+
+ dict->lookup("ID", &obj1);
+ if (obj1.isString()) {
+ writePS("%%ALDImageID: %s\n", obj1.getString()->getCString());
+ }
+ obj1.free();
+
+ dict->lookup("ImageType", &obj1);
+ if (obj1.isArray() && obj1.arrayGetLength() == 2) {
+ obj1.arrayGet(0, &obj2);
+ samples = obj2.getInt();
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ bits = obj2.getInt();
+ obj2.free();
+ writePS("%%ALDImageType: %d %d\n", samples, bits);
+ }
+ obj1.free();
+
+ dict->lookup("Overprint", &obj1);
+ if (obj1.isBool()) {
+ writePS("%%ALDImageOverprint: %s\n", obj1.getBool() ? "true" : "false");
+ }
+ obj1.free();
+
+ dict->lookup("Position", &obj1);
+ if (obj1.isArray() && obj1.arrayGetLength() == 8) {
+ obj1.arrayGet(0, &obj2);
+ llx = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ lly = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(2, &obj2);
+ ulx = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(3, &obj2);
+ uly = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(4, &obj2);
+ urx = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(5, &obj2);
+ ury = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(6, &obj2);
+ lrx = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(7, &obj2);
+ lry = obj2.getNum();
+ obj2.free();
+ opiTransform(state, llx, lly, &tllx, &tlly);
+ opiTransform(state, ulx, uly, &tulx, &tuly);
+ opiTransform(state, urx, ury, &turx, &tury);
+ opiTransform(state, lrx, lry, &tlrx, &tlry);
+ writePS("%%ALDImagePosition: %g %g %g %g %g %g %g %g\n",
+ tllx, tlly, tulx, tuly, turx, tury, tlrx, tlry);
+ obj2.free();
+ }
+ obj1.free();
+
+ dict->lookup("Resolution", &obj1);
+ if (obj1.isArray() && obj1.arrayGetLength() == 2) {
+ obj1.arrayGet(0, &obj2);
+ horiz = obj2.getNum();
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ vert = obj2.getNum();
+ obj2.free();
+ writePS("%%ALDImageResoution: %g %g\n", horiz, vert);
+ obj2.free();
+ }
+ obj1.free();
+
+ dict->lookup("Size", &obj1);
+ if (obj1.isArray() && obj1.arrayGetLength() == 2) {
+ obj1.arrayGet(0, &obj2);
+ width = obj2.getInt();
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ height = obj2.getInt();
+ obj2.free();
+ writePS("%%ALDImageDimensions: %d %d\n", width, height);
+ }
+ obj1.free();
+
+ //~ ignoring 'Tags' entry
+ //~ need to use writePSString() and deal with >255-char lines
+
+ dict->lookup("Tint", &obj1);
+ if (obj1.isNum()) {
+ writePS("%%ALDImageTint: %g\n", obj1.getNum());
+ }
+ obj1.free();
+
+ dict->lookup("Transparency", &obj1);
+ if (obj1.isBool()) {
+ writePS("%%ALDImageTransparency: %s\n", obj1.getBool() ? "true" : "false");
+ }
+ obj1.free();
+
+ writePS("%%%%BeginObject: image\n");
+ writePS("opiMatrix2 setmatrix\n");
+ ++opi13Nest;
+}
+
+// Convert PDF user space coordinates to PostScript default user space
+// coordinates. This has to account for both the PDF CTM and the
+// PSOutputDev page-fitting transform.
+void PSOutputDev::opiTransform(GfxState *state, double x0, double y0,
+ double *x1, double *y1) {
+ double t;
+
+ state->transform(x0, y0, x1, y1);
+ *x1 += tx;
+ *y1 += ty;
+ if (landscape) {
+ t = *x1;
+ *x1 = -*y1;
+ *y1 = t;
+ }
+ *x1 *= xScale;
+ *y1 *= yScale;
+}
+
+void PSOutputDev::opiEnd(GfxState *state, Dict *opiDict) {
+ Object dict;
+
+ if (doOPI) {
+ opiDict->lookup("2.0", &dict);
+ if (dict.isDict()) {
+ writePS("%%%%EndIncludedImage\n");
+ writePS("%%%%EndOPI\n");
+ writePS("grestore\n");
+ --opi20Nest;
+ dict.free();
+ } else {
+ dict.free();
+ opiDict->lookup("1.3", &dict);
+ if (dict.isDict()) {
+ writePS("%%%%EndObject\n");
+ writePS("restore\n");
+ --opi13Nest;
+ }
+ dict.free();
+ }
+ }
+}
+
+GBool PSOutputDev::getFileSpec(Object *fileSpec, Object *fileName) {
+ if (fileSpec->isString()) {
+ fileSpec->copy(fileName);
+ return gTrue;
+ }
+ if (fileSpec->isDict()) {
+ fileSpec->dictLookup("DOS", fileName);
+ if (fileName->isString()) {
+ return gTrue;
+ }
+ fileName->free();
+ fileSpec->dictLookup("Mac", fileName);
+ if (fileName->isString()) {
+ return gTrue;
+ }
+ fileName->free();
+ fileSpec->dictLookup("Unix", fileName);
+ if (fileName->isString()) {
+ return gTrue;
+ }
+ fileName->free();
+ fileSpec->dictLookup("F", fileName);
+ if (fileName->isString()) {
+ return gTrue;
+ }
+ fileName->free();
+ }
+ return gFalse;
+}
+#endif // OPI_SUPPORT
+
+void PSOutputDev::writePS(const char *fmt, ...) {
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(f, fmt, args);
+ va_end(args);
+}
+
+void PSOutputDev::writePSString(GString *s) {
+ Guchar *p;
+ int n;
+
+ fputc('(', f);
+ for (p = (Guchar *)s->getCString(), n = s->getLength(); n; ++p, --n) {
+ if (*p == '(' || *p == ')' || *p == '\\')
+ fprintf(f, "\\%c", *p);
+ else if (*p < 0x20 || *p >= 0x80)
+ fprintf(f, "\\%03o", *p);
+ else
+ fputc(*p, f);
+ }
+ fputc(')', f);
+}
diff --git a/pdftops/PSOutputDev.h b/pdftops/PSOutputDev.h
new file mode 100644
index 000000000..81279be4a
--- /dev/null
+++ b/pdftops/PSOutputDev.h
@@ -0,0 +1,215 @@
+//========================================================================
+//
+// PSOutputDev.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef PSOUTPUTDEV_H
+#define PSOUTPUTDEV_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <stddef.h>
+#include "config.h"
+#include "Object.h"
+#include "OutputDev.h"
+
+class GfxPath;
+class GfxFont;
+class GfxColorSpace;
+class GfxSeparationColorSpace;
+class PSOutCustomColor;
+
+//------------------------------------------------------------------------
+// PSOutputDev
+//------------------------------------------------------------------------
+
+enum PSOutLevel {
+ psLevel1,
+ psLevel1Sep,
+ psLevel2,
+ psLevel2Sep
+};
+
+enum PSOutMode {
+ psModePS,
+ psModeEPS,
+ psModeForm
+};
+
+enum PSFileType {
+ psFile, // write to file
+ psPipe, // write to pipe
+ psStdout // write to stdout
+};
+
+class PSOutputDev: public OutputDev {
+public:
+
+ // Open a PostScript output file, and write the prolog.
+ PSOutputDev(char *fileName, XRef *xrefA, Catalog *catalog,
+ int firstPage, int lastPage,
+ PSOutLevel levelA, PSOutMode modeA, GBool doOPIA,
+ GBool embedType1A, GBool embedTrueTypeA,
+ int paperWidthA, int paperHeightA);
+
+ // Destructor -- writes the trailer and closes the file.
+ virtual ~PSOutputDev();
+
+ // Check if file was successfully created.
+ virtual GBool isOk() { return ok; }
+
+ //---- get info about output device
+
+ // Does this device use upside-down coordinates?
+ // (Upside-down means (0,0) is the top left corner of the page.)
+ virtual GBool upsideDown() { return gFalse; }
+
+ // Does this device use drawChar() or drawString()?
+ virtual GBool useDrawChar() { return gFalse; }
+
+ //----- initialization and control
+
+ // Start a page.
+ virtual void startPage(int pageNum, GfxState *state);
+
+ // End a page.
+ virtual void endPage();
+
+ //----- save/restore graphics state
+ virtual void saveState(GfxState *state);
+ virtual void restoreState(GfxState *state);
+
+ //----- update graphics state
+ virtual void updateCTM(GfxState *state, double m11, double m12,
+ double m21, double m22, double m31, double m32);
+ virtual void updateLineDash(GfxState *state);
+ virtual void updateFlatness(GfxState *state);
+ virtual void updateLineJoin(GfxState *state);
+ virtual void updateLineCap(GfxState *state);
+ virtual void updateMiterLimit(GfxState *state);
+ virtual void updateLineWidth(GfxState *state);
+ virtual void updateFillColor(GfxState *state);
+ virtual void updateStrokeColor(GfxState *state);
+
+ //----- update text state
+ virtual void updateFont(GfxState *state);
+ virtual void updateTextMat(GfxState *state);
+ virtual void updateCharSpace(GfxState *state);
+ virtual void updateRender(GfxState *state);
+ virtual void updateRise(GfxState *state);
+ virtual void updateWordSpace(GfxState *state);
+ virtual void updateHorizScaling(GfxState *state);
+ virtual void updateTextPos(GfxState *state);
+ virtual void updateTextShift(GfxState *state, double shift);
+
+ //----- path painting
+ virtual void stroke(GfxState *state);
+ virtual void fill(GfxState *state);
+ virtual void eoFill(GfxState *state);
+
+ //----- path clipping
+ virtual void clip(GfxState *state);
+ virtual void eoClip(GfxState *state);
+
+ //----- text drawing
+ virtual void drawString(GfxState *state, GString *s);
+ virtual void drawString16(GfxState *state, GString *s);
+
+ //----- image drawing
+ virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GBool invert,
+ GBool inlineImg);
+ virtual void drawImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GfxImageColorMap *colorMap,
+ int *maskColors, GBool inlineImg);
+
+#if OPI_SUPPORT
+ //----- OPI functions
+ virtual void opiBegin(GfxState *state, Dict *opiDict);
+ virtual void opiEnd(GfxState *state, Dict *opiDict);
+#endif
+
+private:
+
+ void setupResources(Dict *resDict);
+ void setupFonts(Dict *resDict);
+ void setupFont(GfxFont *font);
+ void setupEmbeddedType1Font(Ref *id, char *psName);
+ void setupEmbeddedType1Font(GString *fileName, char *psName);
+ void setupEmbeddedType1CFont(GfxFont *font, Ref *id, char *psName);
+ void setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id, char *psName);
+ void setupImages(Dict *resDict);
+ void setupImage(Ref id, Stream *str);
+ void addProcessColor(double c, double m, double y, double k);
+ void addCustomColor(GfxSeparationColorSpace *sepCS);
+ void doPath(GfxPath *path);
+ void doImageL1(GfxImageColorMap *colorMap,
+ GBool invert, GBool inlineImg,
+ Stream *str, int width, int height, int len);
+ void doImageL1Sep(GfxImageColorMap *colorMap,
+ GBool invert, GBool inlineImg,
+ Stream *str, int width, int height, int len);
+ void doImageL2(Object *ref, GfxImageColorMap *colorMap,
+ GBool invert, GBool inlineImg,
+ Stream *str, int width, int height, int len);
+ void dumpColorSpaceL2(GfxColorSpace *colorSpace);
+#if OPI_SUPPORT
+ void opiBegin20(GfxState *state, Dict *dict);
+ void opiBegin13(GfxState *state, Dict *dict);
+ void opiTransform(GfxState *state, double x0, double y0,
+ double *x1, double *y1);
+ GBool getFileSpec(Object *fileSpec, Object *fileName);
+#endif
+ void writePS(const char *fmt, ...);
+ void writePSString(GString *s);
+
+ PSOutLevel level; // PostScript level (1, 2, separation)
+ PSOutMode mode; // PostScript mode (PS, EPS, form)
+ GBool doOPI; // generate OPI comments?
+ GBool embedType1; // embed Type 1 fonts?
+ GBool embedTrueType; // embed TrueType fonts?
+ int paperWidth; // width of paper, in pts
+ int paperHeight; // height of paper, in pts
+
+ FILE *f; // PostScript file
+ PSFileType fileType; // file / pipe / stdout
+ int seqPage; // current sequential page number
+
+ XRef *xref; // the xref table for this PDF file
+
+ Ref *fontIDs; // list of object IDs of all used fonts
+ int fontIDLen; // number of entries in fontIDs array
+ int fontIDSize; // size of fontIDs array
+ Ref *fontFileIDs; // list of object IDs of all embedded fonts
+ int fontFileIDLen; // number of entries in fontFileIDs array
+ int fontFileIDSize; // size of fontFileIDs array
+ GString **fontFileNames; // list of names of all embedded external fonts
+ int fontFileNameLen; // number of entries in fontFileNames array
+ int fontFileNameSize; // size of fontFileNames array
+
+ double tx, ty; // global translation
+ double xScale, yScale; // global scaling
+ GBool landscape; // true for landscape, false for portrait
+
+ GString *embFontList; // resource comments for embedded fonts
+
+ int processColors; // used process colors
+ PSOutCustomColor // used custom colors
+ *customColors;
+
+#if OPI_SUPPORT
+ int opi13Nest; // nesting level of OPI 1.3 objects
+ int opi20Nest; // nesting level of OPI 2.0 objects
+#endif
+
+ GBool type3Warning; // only show the Type 3 font warning once
+
+ GBool ok; // set up ok?
+};
+
+#endif
diff --git a/pdftops/Page.cxx b/pdftops/Page.cxx
new file mode 100644
index 000000000..975fcf1b6
--- /dev/null
+++ b/pdftops/Page.cxx
@@ -0,0 +1,268 @@
+//========================================================================
+//
+// Page.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stddef.h>
+#include "Object.h"
+#include "Array.h"
+#include "Dict.h"
+#include "XRef.h"
+#include "Link.h"
+#include "OutputDev.h"
+#ifndef PDF_PARSER_ONLY
+#include "Gfx.h"
+#include "FormWidget.h"
+#endif
+#include "Error.h"
+
+#include "Params.h"
+#include "Page.h"
+
+//------------------------------------------------------------------------
+// PageAttrs
+//------------------------------------------------------------------------
+
+PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
+ Object obj1;
+ double w, h;
+
+ // get old/default values
+ if (attrs) {
+ mediaBox = attrs->mediaBox;
+ cropBox = attrs->cropBox;
+ haveCropBox = attrs->haveCropBox;
+ rotate = attrs->rotate;
+ attrs->resources.copy(&resources);
+ } else {
+ // set default MediaBox to 8.5" x 11" -- this shouldn't be necessary
+ // but some (non-compliant) PDF files don't specify a MediaBox
+ mediaBox.x1 = 0;
+ mediaBox.y1 = 0;
+ mediaBox.x2 = 612;
+ mediaBox.y2 = 792;
+ cropBox.x1 = cropBox.y1 = cropBox.x2 = cropBox.y2 = 0;
+ haveCropBox = gFalse;
+ rotate = 0;
+ resources.initNull();
+ }
+
+ // media box
+ readBox(dict, "MediaBox", &mediaBox);
+
+ // crop box
+ cropBox = mediaBox;
+ haveCropBox = readBox(dict, "CropBox", &cropBox);
+
+ // if the MediaBox is excessively larger than the CropBox,
+ // just use the CropBox
+ limitToCropBox = gFalse;
+ if (haveCropBox) {
+ w = 0.25 * (cropBox.x2 - cropBox.x1);
+ h = 0.25 * (cropBox.y2 - cropBox.y1);
+ if ((cropBox.x1 - mediaBox.x1) + (mediaBox.x2 - cropBox.x2) > w ||
+ (cropBox.y1 - mediaBox.y1) + (mediaBox.y2 - cropBox.y2) > h) {
+ limitToCropBox = gTrue;
+ }
+ }
+
+ // other boxes
+ bleedBox = cropBox;
+ readBox(dict, "BleedBox", &bleedBox);
+ trimBox = cropBox;
+ readBox(dict, "TrimBox", &trimBox);
+ artBox = cropBox;
+ readBox(dict, "ArtBox", &artBox);
+
+ // rotate
+ dict->lookup("Rotate", &obj1);
+ if (obj1.isInt()) {
+ rotate = obj1.getInt();
+ }
+ obj1.free();
+ while (rotate < 0) {
+ rotate += 360;
+ }
+ while (rotate >= 360) {
+ rotate -= 360;
+ }
+
+ // resource dictionary
+ dict->lookup("Resources", &obj1);
+ if (obj1.isDict()) {
+ resources.free();
+ obj1.copy(&resources);
+ }
+ obj1.free();
+}
+
+PageAttrs::~PageAttrs() {
+ resources.free();
+}
+
+GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) {
+ PDFRectangle tmp;
+ Object obj1, obj2;
+ GBool ok;
+
+ dict->lookup(key, &obj1);
+ if (obj1.isArray() && obj1.arrayGetLength() == 4) {
+ ok = gTrue;
+ obj1.arrayGet(0, &obj2);
+ if (obj2.isNum()) {
+ tmp.x1 = obj2.getNum();
+ } else {
+ ok = gFalse;
+ }
+ obj2.free();
+ obj1.arrayGet(1, &obj2);
+ if (obj2.isNum()) {
+ tmp.y1 = obj2.getNum();
+ } else {
+ ok = gFalse;
+ }
+ obj2.free();
+ obj1.arrayGet(2, &obj2);
+ if (obj2.isNum()) {
+ tmp.x2 = obj2.getNum();
+ } else {
+ ok = gFalse;
+ }
+ obj2.free();
+ obj1.arrayGet(3, &obj2);
+ if (obj2.isNum()) {
+ tmp.y2 = obj2.getNum();
+ } else {
+ ok = gFalse;
+ }
+ obj2.free();
+ if (ok) {
+ *box = tmp;
+ }
+ } else {
+ ok = gFalse;
+ }
+ obj1.free();
+ return ok;
+}
+
+//------------------------------------------------------------------------
+// Page
+//------------------------------------------------------------------------
+
+Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA,
+ GBool printCommandsA) {
+
+ ok = gTrue;
+ xref = xrefA;
+ num = numA;
+ printCommands = printCommandsA;
+
+ // get attributes
+ attrs = attrsA;
+
+ // annotations
+ pageDict->lookupNF("Annots", &annots);
+ if (!(annots.isRef() || annots.isArray() || annots.isNull())) {
+ error(-1, "Page annotations object (page %d) is wrong type (%s)",
+ num, annots.getTypeName());
+ annots.free();
+ goto err2;
+ }
+
+ // contents
+ pageDict->lookupNF("Contents", &contents);
+ if (!(contents.isRef() || contents.isArray() ||
+ contents.isNull())) {
+ error(-1, "Page contents object (page %d) is wrong type (%s)",
+ num, contents.getTypeName());
+ contents.free();
+ goto err1;
+ }
+
+ return;
+
+ err2:
+ annots.initNull();
+ err1:
+ contents.initNull();
+ ok = gFalse;
+}
+
+Page::~Page() {
+ delete attrs;
+ annots.free();
+ contents.free();
+}
+
+void Page::display(OutputDev *out, double dpi, int rotate,
+ Links *links, Catalog *catalog) {
+#ifndef PDF_PARSER_ONLY
+ PDFRectangle *box, *cropBox;
+ Gfx *gfx;
+ Object obj;
+ Link *link;
+ int i;
+ FormWidgets *formWidgets;
+
+ box = getBox();
+ cropBox = getCropBox();
+
+ if (printCommands) {
+ printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
+ box->x1, box->y1, box->x2, box->y2);
+ if (isCropped()) {
+ printf("***** CropBox = ll:%g,%g ur:%g,%g\n",
+ cropBox->x1, cropBox->y1, cropBox->x2, cropBox->y2);
+ }
+ printf("***** Rotate = %d\n", attrs->getRotate());
+ }
+
+ rotate += getRotate();
+ if (rotate >= 360) {
+ rotate -= 360;
+ } else if (rotate < 0) {
+ rotate += 360;
+ }
+ gfx = new Gfx(xref, out, num, attrs->getResourceDict(),
+ dpi, box, isCropped(), cropBox, rotate, printCommands);
+ contents.fetch(xref, &obj);
+ if (!obj.isNull()) {
+ gfx->display(&obj);
+ }
+ obj.free();
+
+ // draw links
+ if (links) {
+ for (i = 0; i < links->getNumLinks(); ++i) {
+ link = links->getLink(i);
+ out->drawLink(link, catalog);
+ }
+ out->dump();
+ }
+
+ // draw AcroForm widgets
+ //~ need to reset CTM ???
+ formWidgets = new FormWidgets(xref, annots.fetch(xref, &obj));
+ obj.free();
+ if (printCommands && formWidgets->getNumWidgets() > 0) {
+ printf("***** AcroForm widgets\n");
+ }
+ for (i = 0; i < formWidgets->getNumWidgets(); ++i) {
+ formWidgets->getWidget(i)->draw(gfx);
+ }
+ if (formWidgets->getNumWidgets() > 0) {
+ out->dump();
+ }
+ delete formWidgets;
+
+ delete gfx;
+#endif
+}
diff --git a/pdftops/Page.h b/pdftops/Page.h
new file mode 100644
index 000000000..a40974cfc
--- /dev/null
+++ b/pdftops/Page.h
@@ -0,0 +1,125 @@
+//========================================================================
+//
+// Page.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef PAGE_H
+#define PAGE_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "Object.h"
+
+class Dict;
+class XRef;
+class OutputDev;
+class Links;
+class Catalog;
+
+//------------------------------------------------------------------------
+
+struct PDFRectangle {
+ double x1, y1, x2, y2;
+};
+
+//------------------------------------------------------------------------
+// PageAttrs
+//------------------------------------------------------------------------
+
+class PageAttrs {
+public:
+
+ // Construct a new PageAttrs object by merging a dictionary
+ // (of type Pages or Page) into another PageAttrs object. If
+ // <attrs> is NULL, uses defaults.
+ PageAttrs(PageAttrs *attrs, Dict *dict);
+
+ // Destructor.
+ ~PageAttrs();
+
+ // Accessors.
+ PDFRectangle *getBox() { return limitToCropBox ? &cropBox : &mediaBox; }
+ PDFRectangle *getMediaBox() { return &mediaBox; }
+ PDFRectangle *getCropBox() { return &cropBox; }
+ GBool isCropped() { return haveCropBox; }
+ PDFRectangle *getBleedBox() { return &bleedBox; }
+ PDFRectangle *getTrimBox() { return &trimBox; }
+ PDFRectangle *getArtBox() { return &artBox; }
+ int getRotate() { return rotate; }
+ Dict *getResourceDict()
+ { return resources.isDict() ? resources.getDict() : (Dict *)NULL; }
+
+private:
+
+ GBool readBox(Dict *dict, char *key, PDFRectangle *box);
+
+ PDFRectangle mediaBox;
+ PDFRectangle cropBox;
+ GBool haveCropBox;
+ GBool limitToCropBox;
+ PDFRectangle bleedBox;
+ PDFRectangle trimBox;
+ PDFRectangle artBox;
+ int rotate;
+ Object resources;
+};
+
+//------------------------------------------------------------------------
+// Page
+//------------------------------------------------------------------------
+
+class Page {
+public:
+
+ // Constructor.
+ Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA,
+ GBool printCommandsA);
+
+ // Destructor.
+ ~Page();
+
+ // Is page valid?
+ GBool isOk() { return ok; }
+
+ // Get page parameters.
+ PDFRectangle *getBox() { return attrs->getBox(); }
+ PDFRectangle *getMediaBox() { return attrs->getMediaBox(); }
+ PDFRectangle *getCropBox() { return attrs->getCropBox(); }
+ GBool isCropped() { return attrs->isCropped(); }
+ double getWidth() { return attrs->getBox()->x2 - attrs->getBox()->x1; }
+ double getHeight() { return attrs->getBox()->y2 - attrs->getBox()->y1; }
+ PDFRectangle *getBleedBox() { return attrs->getBleedBox(); }
+ PDFRectangle *getTrimBox() { return attrs->getTrimBox(); }
+ PDFRectangle *getArtBox() { return attrs->getArtBox(); }
+ int getRotate() { return attrs->getRotate(); }
+
+ // Get resource dictionary.
+ Dict *getResourceDict() { return attrs->getResourceDict(); }
+
+ // Get annotations array.
+ Object *getAnnots(Object *obj) { return annots.fetch(xref, obj); }
+
+ // Get contents.
+ Object *getContents(Object *obj) { return contents.fetch(xref, obj); }
+
+ // Display a page.
+ void display(OutputDev *out, double dpi, int rotate,
+ Links *links, Catalog *catalog);
+
+private:
+
+ XRef *xref; // the xref table for this PDF file
+ int num; // page number
+ PageAttrs *attrs; // page attributes
+ Object annots; // annotations array
+ Object contents; // page contents
+ GBool printCommands; // print the drawing commands (for debugging)
+ GBool ok; // true if page is valid
+};
+
+#endif
diff --git a/pdftops/Params.cxx b/pdftops/Params.cxx
new file mode 100644
index 000000000..8536da20d
--- /dev/null
+++ b/pdftops/Params.cxx
@@ -0,0 +1,90 @@
+//========================================================================
+//
+// Params.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include "gtypes.h"
+#include "gmem.h"
+#include "GString.h"
+#include "gfile.h"
+#include "Params.h"
+
+char **fontPath = NULL;
+static int fontPathLen, fontPathSize;
+
+DevFontMapEntry *devFontMap = NULL;
+static int devFontMapLen, devFontMapSize;
+
+void initParams(char *userConfigFile, char *sysConfigFile) {
+ GString *fileName;
+ FILE *f;
+ char buf[256];
+ char *p, *q;
+
+ // initialize font path and font map
+ fontPath = (char **)gmalloc((fontPathSize = 8) * sizeof(char *));
+ fontPath[fontPathLen = 0] = NULL;
+ devFontMap = (DevFontMapEntry *)gmalloc((devFontMapSize = 8) *
+ sizeof(DevFontMapEntry));
+ devFontMap[devFontMapLen = 0].pdfFont = NULL;
+
+ // read config file
+ fileName = appendToPath(getHomeDir(), userConfigFile);
+ if (!(f = fopen(fileName->getCString(), "r"))) {
+ f = fopen(sysConfigFile, "r");
+ }
+ if (f) {
+ while (fgets(buf, sizeof(buf)-1, f)) {
+ buf[sizeof(buf)-1] = '\0';
+ p = strtok(buf, " \t\n\r");
+ if (p && !strcmp(p, "fontpath")) {
+ if (fontPathLen+1 >= fontPathSize)
+ fontPath = (char **)
+ grealloc(fontPath, (fontPathSize += 8) * sizeof(char *));
+ p = strtok(NULL, " \t\n\r");
+ fontPath[fontPathLen++] = copyString(p);
+ } else if (p && !strcmp(p, "fontmap")) {
+ if (devFontMapLen+1 >= devFontMapSize)
+ devFontMap = (DevFontMapEntry *)
+ grealloc(devFontMap,
+ (devFontMapSize += 8) * sizeof(DevFontMapEntry));
+ p = strtok(NULL, " \t\n\r");
+ devFontMap[devFontMapLen].pdfFont = copyString(p);
+ p = strtok(NULL, "\t\n\r");
+ while (*p == ' ')
+ ++p;
+ for (q = p + strlen(p) - 1; q >= p && *q == ' '; --q) ;
+ q[1] = '\0';
+ devFontMap[devFontMapLen++].devFont = copyString(p);
+ }
+ }
+ fclose(f);
+ fontPath[fontPathLen] = NULL;
+ devFontMap[devFontMapLen].pdfFont = NULL;
+ }
+ delete fileName;
+}
+
+void freeParams() {
+ int i;
+
+ if (fontPath) {
+ for (i = 0; i < fontPathLen; ++i)
+ gfree(fontPath[i]);
+ gfree(fontPath);
+ }
+ if (devFontMap) {
+ for (i = 0; i < devFontMapLen; ++i) {
+ gfree(devFontMap[i].pdfFont);
+ gfree(devFontMap[i].devFont);
+ }
+ gfree(devFontMap);
+ }
+}
diff --git a/pdftops/Params.h b/pdftops/Params.h
new file mode 100644
index 000000000..1d8ce3828
--- /dev/null
+++ b/pdftops/Params.h
@@ -0,0 +1,38 @@
+//========================================================================
+//
+// Params.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef PARAMS_H
+#define PARAMS_H
+
+#include "gtypes.h"
+
+// If this is set, error messages will be silently discarded.
+extern GBool errQuiet;
+
+// Font search path.
+extern char **fontPath;
+
+// Mapping from PDF font name to device font name.
+struct DevFontMapEntry {
+ char *pdfFont;
+ char *devFont;
+};
+extern DevFontMapEntry *devFontMap;
+
+//------------------------------------------------------------------------
+
+// Initialize font path and font map, and read configuration file. If
+// <userConfigFile> exists, read it; else if <sysConfigFile> exists,
+// read it. <userConfigFile> is relative to the user's home
+// directory; <sysConfigFile> should be an absolute path.
+extern void initParams(char *userConfigFile, char *sysConfigFile);
+
+// Free memory used for font path and font map.
+extern void freeParams();
+
+#endif
diff --git a/pdftops/Parser.cxx b/pdftops/Parser.cxx
new file mode 100644
index 000000000..57ba05061
--- /dev/null
+++ b/pdftops/Parser.cxx
@@ -0,0 +1,212 @@
+//========================================================================
+//
+// Parser.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stddef.h>
+#include "Object.h"
+#include "Array.h"
+#include "Dict.h"
+#include "Parser.h"
+#include "XRef.h"
+#include "Error.h"
+#ifndef NO_DECRYPTION
+#include "Decrypt.h"
+#endif
+
+Parser::Parser(XRef *xrefA, Lexer *lexerA) {
+ xref = xrefA;
+ lexer = lexerA;
+ inlineImg = 0;
+ lexer->getObj(&buf1);
+ lexer->getObj(&buf2);
+}
+
+Parser::~Parser() {
+ buf1.free();
+ buf2.free();
+ delete lexer;
+}
+
+#ifndef NO_DECRYPTION
+Object *Parser::getObj(Object *obj,
+ Guchar *fileKey, int keyLength,
+ int objNum, int objGen) {
+#else
+Object *Parser::getObj(Object *obj) {
+#endif
+ char *key;
+ Stream *str;
+ Object obj2;
+ int num;
+#ifndef NO_DECRYPTION
+ Decrypt *decrypt;
+ GString *s;
+ char *p;
+ int i;
+#endif
+
+ // refill buffer after inline image data
+ if (inlineImg == 2) {
+ buf1.free();
+ buf2.free();
+ lexer->getObj(&buf1);
+ lexer->getObj(&buf2);
+ inlineImg = 0;
+ }
+
+ // array
+ if (buf1.isCmd("[")) {
+ shift();
+ obj->initArray(xref);
+ while (!buf1.isCmd("]") && !buf1.isEOF())
+#ifndef NO_DECRYPTION
+ obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen));
+#else
+ obj->arrayAdd(getObj(&obj2));
+#endif
+ if (buf1.isEOF())
+ error(getPos(), "End of file inside array");
+ shift();
+
+ // dictionary or stream
+ } else if (buf1.isCmd("<<")) {
+ shift();
+ obj->initDict(xref);
+ while (!buf1.isCmd(">>") && !buf1.isEOF()) {
+ if (!buf1.isName()) {
+ error(getPos(), "Dictionary key must be a name object");
+ shift();
+ } else {
+ key = copyString(buf1.getName());
+ shift();
+ if (buf1.isEOF() || buf1.isError())
+ break;
+#ifndef NO_DECRYPTION
+ obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen));
+#else
+ obj->dictAdd(key, getObj(&obj2));
+#endif
+ }
+ }
+ if (buf1.isEOF())
+ error(getPos(), "End of file inside dictionary");
+ if (buf2.isCmd("stream")) {
+ if ((str = makeStream(obj))) {
+ obj->initStream(str);
+#ifndef NO_DECRYPTION
+ if (fileKey) {
+ str->getBaseStream()->doDecryption(fileKey, keyLength,
+ objNum, objGen);
+ }
+#endif
+ } else {
+ obj->free();
+ obj->initError();
+ }
+ } else {
+ shift();
+ }
+
+ // indirect reference or integer
+ } else if (buf1.isInt()) {
+ num = buf1.getInt();
+ shift();
+ if (buf1.isInt() && buf2.isCmd("R")) {
+ obj->initRef(num, buf1.getInt());
+ shift();
+ shift();
+ } else {
+ obj->initInt(num);
+ }
+
+#ifndef NO_DECRYPTION
+ // string
+ } else if (buf1.isString() && fileKey) {
+ buf1.copy(obj);
+ s = obj->getString();
+ decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
+ for (i = 0, p = obj->getString()->getCString();
+ i < s->getLength();
+ ++i, ++p) {
+ *p = decrypt->decryptByte(*p);
+ }
+ delete decrypt;
+ shift();
+#endif
+
+ // simple object
+ } else {
+ buf1.copy(obj);
+ shift();
+ }
+
+ return obj;
+}
+
+Stream *Parser::makeStream(Object *dict) {
+ Object obj;
+ Stream *str;
+ int pos, endPos, length;
+
+ // get stream start position
+ lexer->skipToNextLine();
+ pos = lexer->getPos();
+
+ // get length
+ dict->dictLookup("Length", &obj);
+ if (obj.isInt()) {
+ length = obj.getInt();
+ obj.free();
+ } else {
+ error(getPos(), "Bad 'Length' attribute in stream");
+ obj.free();
+ return NULL;
+ }
+
+ // check for length in damaged file
+ if ((endPos = xref->getStreamEnd(pos)) >= 0) {
+ length = endPos - pos;
+ }
+
+ // make base stream
+ str = lexer->getStream()->getBaseStream()->makeSubStream(pos, length, dict);
+
+ // get filters
+ str = str->addFilters(dict);
+
+ // skip over stream data
+ lexer->setPos(pos + length);
+
+ // refill token buffers and check for 'endstream'
+ shift(); // kill '>>'
+ shift(); // kill 'stream'
+ if (buf1.isCmd("endstream"))
+ shift();
+ else
+ error(getPos(), "Missing 'endstream'");
+
+ return str;
+}
+
+void Parser::shift() {
+ if (inlineImg > 0) {
+ ++inlineImg;
+ } else if (buf2.isCmd("ID")) {
+ lexer->skipChar(); // skip char after 'ID' command
+ inlineImg = 1;
+ }
+ buf1.free();
+ buf1 = buf2;
+ if (inlineImg > 0) // don't buffer inline image data
+ buf2.initNull();
+ else
+ lexer->getObj(&buf2);
+}
diff --git a/pdftops/Parser.h b/pdftops/Parser.h
new file mode 100644
index 000000000..463d99827
--- /dev/null
+++ b/pdftops/Parser.h
@@ -0,0 +1,58 @@
+//========================================================================
+//
+// Parser.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef PARSER_H
+#define PARSER_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "Lexer.h"
+
+//------------------------------------------------------------------------
+// Parser
+//------------------------------------------------------------------------
+
+class Parser {
+public:
+
+ // Constructor.
+ Parser(XRef *xrefA, Lexer *lexerA);
+
+ // Destructor.
+ ~Parser();
+
+ // Get the next object from the input stream.
+#ifndef NO_DECRYPTION
+ Object *getObj(Object *obj,
+ Guchar *fileKey = NULL, int keyLength = 0,
+ int objNum = 0, int objGen = 0);
+#else
+ Object *getObj(Object *obj);
+#endif
+
+ // Get stream.
+ Stream *getStream() { return lexer->getStream(); }
+
+ // Get current position in file.
+ int getPos() { return lexer->getPos(); }
+
+private:
+
+ XRef *xref; // the xref table for this PDF file
+ Lexer *lexer; // input stream
+ Object buf1, buf2; // next two tokens
+ int inlineImg; // set when inline image data is encountered
+
+ Stream *makeStream(Object *dict);
+ void shift();
+};
+
+#endif
+
diff --git a/pdftops/README b/pdftops/README
new file mode 100644
index 000000000..4835a82f8
--- /dev/null
+++ b/pdftops/README
@@ -0,0 +1,426 @@
+Xpdf
+====
+
+version 0.93
+2001-oct-25
+
+The Xpdf software and documentation are
+copyright 1996-2001 Derek B. Noonburg.
+
+Email: derekn@foolabs.com
+WWW: http://www.foolabs.com/xpdf/
+
+The PDF data structures, operators, and specification are
+copyright 1995 Adobe Systems Inc.
+
+
+What is Xpdf?
+-------------
+
+Xpdf is a viewer for Portable Document Format (PDF) files. (These are
+also sometimes also called 'Acrobat' files, from the name of Adobe's
+PDF software.) Xpdf runs under the X Window System on UNIX, VMS, and
+OS/2. The non-X components of the package (pdftops, pdftotext, etc.)
+also run on Win32 systems and should run on pretty much any system
+with a decent C++ compiler.
+
+Xpdf is designed to be small and efficient. It can use Type 1,
+TrueType, or standard X fonts.
+
+
+Distribution
+------------
+
+Xpdf is licensed under the GNU General Public License (GPL), version
+2. In my opinion, the GPL is a convoluted, confusing, ambiguous mess.
+But it's also pervasive, and I'm sick of arguing. And even if it is
+confusing, the basic idea is good.
+
+In order to cut down on the confusion a little bit, here are some
+informal clarifications:
+
+- I don't mind if you redistribute Xpdf in source and/or binary form,
+ as long as you include all of the documentation: README, man pages
+ (or help files), and COPYING. (Note that the README file contains a
+ pointer to a web page with the source code.)
+
+- Selling a CD-ROM that contains Xpdf is fine with me, as long as it
+ includes the documentation. I wouldn't mind receiving a sample
+ copy, but it's not necessary.
+
+- If you make useful changes to Xpdf, please make the source code
+ available -- post it on a web site, email it to me, whatever.
+
+If you're interested in commercial licensing, please contact me by
+email: derekn@foolabs.com .
+
+
+Compatibility
+-------------
+
+Xpdf is developed and tested on a Linux 2.2 x86 system.
+
+In addition, it has been compiled by others on Solaris, AIX, HP-UX,
+SCO UnixWare, Digital Unix, Irix, and numerous other Unix
+implementations, as well as VMS and OS/2. It should work on pretty
+much any system which runs X11 and has Unix-like libraries. You'll
+need ANSI C++ and C compilers to compile it.
+
+The non-X components of Xpdf (pdftops, pdftotext, pdfinfo, pdfimages)
+can also be compiled on Win32 systems. See the Xpdf web page for
+details.
+
+If you compile Xpdf for a system not listed on the web page, please
+let me know. If you're willing to make your binary available by ftp
+or on the web, I'll be happy to add a link from the Xpdf web page. I
+have decided not to host any binaries I didn't compile myself (for
+disk space and support reasons).
+
+If you can't get Xpdf to compile on your system, send me email and
+I'll try to help.
+
+Xpdf has been ported to the Acorn, Amiga, BeOS, and EPOC. See the
+Xpdf web page for links.
+
+
+Getting Xpdf
+------------
+
+The latest version is available from:
+
+ http://www.foolabs.com/xpdf/
+
+or:
+
+ ftp://ftp.foolabs.com/pub/xpdf/
+
+Source code and several precompiled executables are available.
+
+Announcements of new versions are posted to several newsgroups
+(comp.text.pdf, comp.os.linux.announce, and others) and emailed to a
+list of people. If you'd like to receive email notification of new
+versions, just let me know.
+
+
+Running Xpdf
+------------
+
+To run xpdf, simply type:
+
+ xpdf file.pdf
+
+To generate a PostScript file, hit the "print" button in xpdf, or run
+pdftops:
+
+ pdftops file.pdf
+
+To generate a plain text file, run pdftotext:
+
+ pdftotext file.pdf
+
+There are three additional utilities (which are fully described in
+their man pages):
+
+ pdfinfo -- dumps a PDF file's Info dictionary (plus some other
+ useful information)
+ pdftopbm -- converts a PDF file to a series of PBM-format bitmaps
+ pdfimages -- extracts the images from a PDF file
+
+Command line options and many other details are described in the man
+pages (xpdf.1, etc.) and the VMS help files (xpdf.hlp, etc.).
+
+
+Fonts
+-----
+
+Xpdf uses X server fonts. It requires the following fonts:
+
+* Courier: medium-r, bold-r, medium-o, and bold-o
+* Helvetica: medium-r, bold-r, medium-o, and bold-o
+* Times: medium-r, bold-r, medium-i, and bold-i
+* Symbol: medium-r
+* Zapf Dingbats: medium-r
+
+Most X installations should already have all of these fonts, except
+Zapf Dingbats. You can install a Type 1 Zapf Dingbats font -- see the
+mkfontdir(1) man page for details. Use this font descriptor in your
+fonts.scale file:
+
+ -itc-zapfdingbats-medium-r-normal--0-0-0-0-p-0-adobe-fontspecific
+
+You can get a Type 1 font file from the ghostscript 4.x distribution
+(look for d050000l.pfb).
+
+X servers, starting at R5, support font scaling. Xpdf will
+automatically take advantage of this. There are two types of scaling.
+The first type uses standard bitmap fonts: if a font doesn't exist in
+the requested size, the server will scale the bitmapped characters.
+This is reasonably fast, and the results are readable but not very
+pretty. X servers can also handle true scalable, e.g., Type 1, fonts.
+(See the mkfontdir(1) man page for details on setting these up.)
+Scalable fonts are slower, especially since PDF documents tend to use
+lots of fonts, but they look much nicer.
+
+Some X servers also support font rotation. Xpdf will use this feature
+if available.
+
+For Japanese support, you will need a Japanese font of the form:
+
+ -*-fixed-medium-r-normal-*-NN-*-*-*-*-*-jisx0208.1983-0
+
+and an X server that can handle 16-bit fonts. You can also set this
+font using the xpdf.japaneseFont resource.
+
+For Chinese GB (simplified Chinese) support, you will need a font of
+the form:
+
+ -*-fangsong ti-medium-r-normal-*-%s-*-*-*-*-*-gb2312.1980-0
+
+You can replace this font using the xpdf.chineseGBFont resource.
+
+For Chinese CNS (traditional Chinese) support, you will need a font of
+the form:
+
+ -*-fixed-medium-r-normal--*-%s-*-*-*-*-big5-0
+
+You can replace this font using the xpdf.chineseCNSFont resource.
+
+If compiled with t1lib support, xpdf will use t1lib to render embedded
+Type 1 and Type 1C fonts. In addition, xpdf can be configured to use
+t1lib for the base 14 fonts and for substituted fonts. To enable this
+feature, you must set an X resource for each Type 1 font file. For
+example:
+
+ xpdf.t1TimesRoman: /usr/local/fonts/Times-Roman.pfa
+ xpdf.t1TimesItalic: /usr/local/fonts/Times-Italic.pfa
+ xpdf.t1TimesBold: /usr/local/fonts/Times-Bold.pfa
+ xpdf.t1TimesBoldItalic: /usr/local/fonts/Times-BoldItalic.pfa
+ xpdf.t1Helvetica: /usr/local/fonts/Helvetica.pfa
+ xpdf.t1HelveticaOblique: /usr/local/fonts/Helvetica-Oblique.pfa
+ xpdf.t1HelveticaBold: /usr/local/fonts/Helvetica-Bold.pfa
+ xpdf.t1HelveticaBoldOblique: /usr/local/fonts/Helvetica-BoldOblique.pfa
+ xpdf.t1Courier: /usr/local/fonts/Courier.pfa
+ xpdf.t1CourierOblique: /usr/local/fonts/Courier-Oblique.pfa
+ xpdf.t1CourierBold: /usr/local/fonts/Courier-Bold.pfa
+ xpdf.t1CourierBoldOblique: /usr/local/fonts/Courier-BoldOblique.pfa
+ xpdf.t1Symbol: /usr/local/fonts/Symbol.pfa
+ xpdf.t1ZapfDingbats: /usr/local/fonts/ZapfDingbats.pfa
+
+Ghostscript comes with a set of free, high-quality Type 1 fonts,
+donated by URW++ Design and Development Incorporated. The xpdf X
+resources needed for these fonts are:
+
+ xpdf.t1TimesRoman: /usr/ghostscript/fonts/n021003l.pfb
+ xpdf.t1TimesItalic: /usr/ghostscript/fonts/n021023l.pfb
+ xpdf.t1TimesBold: /usr/ghostscript/fonts/n021004l.pfb
+ xpdf.t1TimesBoldItalic: /usr/ghostscript/fonts/n021024l.pfb
+ xpdf.t1Helvetica: /usr/ghostscript/fonts/n019003l.pfb
+ xpdf.t1HelveticaOblique: /usr/ghostscript/fonts/n019023l.pfb
+ xpdf.t1HelveticaBold: /usr/ghostscript/fonts/n019004l.pfb
+ xpdf.t1HelveticaBoldOblique: /usr/ghostscript/fonts/n019024l.pfb
+ xpdf.t1Courier: /usr/ghostscript/fonts/n022003l.pfb
+ xpdf.t1CourierOblique: /usr/ghostscript/fonts/n022023l.pfb
+ xpdf.t1CourierBold: /usr/ghostscript/fonts/n022004l.pfb
+ xpdf.t1CourierBoldOblique: /usr/ghostscript/fonts/n022024l.pfb
+ xpdf.t1Symbol: /usr/ghostscript/fonts/s050000l.pfb
+ xpdf.t1ZapfDingbats: /usr/ghostscript/fonts/d050000l.pfb
+
+You will obviously need to replace '/usr/ghostscript/fonts' with the
+appropriate path on your system.
+
+
+The Unisys LZW Patent
+---------------------
+
+Nearly all PDF files include data which has been compressed with the
+LZW compression algorithm. Unfortunately, LZW is covered by a
+software patent which is owned by Unisys Corporation. Unisys refuses
+to license this patent for PDF-related use in software such as Xpdf
+which is released for free and which may be freely redistributed.
+(This is same algorithm which is used by GIF. However, Unisys is not
+doing licensing for free PDF viwers in the same way as for free GIF
+viewers.)
+
+As a workaround, Xpdf converts PDF-format LZW data to compress-format
+LZW data. (The standard UNIX compress utility also uses LZW, but with
+a slightly different file format.) This conversion does *not*
+decompress the data; it simply converts it to a different file format.
+Xpdf then calls uncompress to actually decompress the data.
+
+I have been told by several notable people that the LZW patent covers
+compression only, and does not cover decompression. This seems pretty
+fuzzy to me, so I'm going to stick with my workaround, at least for
+now.
+
+For Unisys's slant on things (mostly regarding GIF), see
+<http://www.unisys.com/LeadStory/lzwterms.html> and
+<http://www.unisys.com/LeadStory/lzwfaq.html>. These pages mention
+an email address for feedback.
+
+
+Compiling Xpdf
+--------------
+
+See the separate file, INSTALL.
+
+
+Bugs
+----
+
+Type 3 fonts are still not well supported by Xpdf.
+
+If you find a bug in Xpdf, i.e., if it prints an error message,
+crashes, or incorrectly displays a document, and you don't see that
+bug listed here, please send me email, with a pointer (URL, ftp site,
+etc.) to the PDF file.
+
+
+Acknowledgments
+---------------
+
+Thanks to:
+
+* Patrick Voigt for help with the remote server code.
+* Patrick Moreau, Martin P.J. Zinser, and David Mathog for the VMS
+ port.
+* David Boldt and Rick Rodgers for sample man pages.
+* Brendan Miller for the icon idea.
+* Olly Betts for help testing pdftotext.
+* Peter Ganten for the OS/2 port.
+* Michael Richmond for the Win32 port of pdftops and pdftotext.
+* Frank M. Siegert for improvements in the PostScript code.
+* Leo Smiers for the decryption patches.
+* Rainer Menzner for creating t1lib, and for helping me adapt it to
+ xpdf.
+* Pine Tree Systems A/S for funding the OPI and EPS support in
+ pdftops.
+* Easy Software Products for funding the "sh" operator support.
+
+
+References
+----------
+
+Adobe Systems Inc., _PDF Reference_, 2nd ed.
+Addison-Wesley, 2000, ISBN 0-201-61588-6.
+[The printed manual for PDF version 1.3.]
+
+Adobe Systems Inc., _Portable Document Format: Changes from Version
+1.3 to 1.4_, Adobe Developer Support Technical Note #5409.
+June 11, 2001.
+http://partners.adobe.com/asn/developer/acrosdk/docs/filefmtspecs/PDF14Deltas.pdf
+[Updates for PDF 1.4.]
+
+Adobe Systems Inc., _PostScript Language Reference_, 3rd ed.
+Addison-Wesley, 1999, ISBN 0-201-37922-8.
+[The official PostScript manual.]
+
+Adobe Systems, Inc., _The Type 42 Font Format Specification_,
+Adobe Developer Support Technical Specification #5012. 1998.
+http://partners.adobe.com/asn/developer/pdfs/tn/5012.Type42_Spec.pdf
+[Type 42 is the format used to embed TrueType fonts in PostScript
+files.]
+
+Adobe Systems, Inc., _Adobe CMap and CIDFont Files Specification_,
+Adobe Developer Support Technical Specification #5014. 1995.
+http://www.adobe.com/supportservice/devrelations/PDFS/TN/5014.CIDFont_Spec.pdf
+[CMap file format needed for Japanese and Chinese font support.]
+
+Adobe Systems, Inc., _Adobe-Japan1-2 Character Collection for
+CID-Keyed Fonts_, Adobe Developer Support Technical Note #5078.
+1994.
+http://partners.adobe.com/asn/developer/PDFS/TN/5078.CID_Glyph.pdf
+[The Adobe Japanese character set.]
+
+Adobe Systems, Inc., _Adobe-GB1-3 Character Collection for
+CID-Keyed Fonts_, Adobe Developer Support Technical Note #5079.
+1998.
+http://partners.adobe.com/asn/developer/PDFS/TN/5079.GB_CharColl.pdf
+[The Adobe Chinese GB character set.]
+
+Adobe Systems, Inc., _Adobe-CNS1-3 Character Collection for
+CID-Keyed Fonts_, Adobe Developer Support Technical Note #5080.
+2000.
+http://partners.adobe.com/asn/developer/PDFS/TN/5080.CNS_CharColl.pdf
+[The Adobe Chinese CNS character set.]
+
+Adobe Systems Inc., _Supporting the DCT Filters in PostScript Level
+2_, Adobe Developer Support Technical Note #5116. 1992.
+http://www.adobe.com/supportservice/devrelations/PDFS/TN/5116.PS2_DCT.PDF
+[Description of the DCTDecode filter parameters.]
+
+Adobe Systems Inc., _Open Prepress Interface (OPI) Specification -
+Version 2.0_, Adobe Developer Support Technical Note #5660. 2000.
+http://partners.adobe.com/asn/developer/PDFS/TN/5660.OPI_2.0.pdf
+
+Adobe Systems Inc., CMap files.
+ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/
+[The actual CMap files for the 16-bit CJK encodings.]
+
+Aldus Corp., _OPI: Open Prepress Interface Specification 1.3_. 1993.
+http://partners.adobe.com/asn/developer/PDFS/TN/OPI_13.pdf
+
+Anonymous, RC4 source code.
+ftp://ftp.ox.ac.uk/pub/crypto/misc/rc4.tar.gz
+ftp://idea.sec.dsi.unimi.it/pub/crypt/code/rc4.tar.gz
+[This is the algorithm used to encrypt PDF files.]
+
+CCITT, _Blue Book_, Volume VII Fascicle 3: "Terminal Equipment and
+Protocols for Telematic Services", Recommendations T.4 and T.6.
+ftp://ftp.uu.net/doc/standards/ccitt/1988/7_3_01.ps
+ftp://ftp.uu.net/doc/standards/ccitt/1988/7_3_02.ps
+[The official Group 3 and 4 fax standards. The online copies are
+unfortunately misformatted.]
+
+L. Peter Deutsch, "ZLIB Compressed Data Format Specification version
+3.3". RFC 1950.
+[Information on the general format used in FlateDecode streams.]
+
+L. Peter Deutsch, "DEFLATE Compressed Data Format Specification
+version 1.3". RFC 1951.
+[The definition of the compression algorithm used in FlateDecode
+streams.]
+
+Jim Flowers, "X Logical Font Description Conventions", Version 1.5, X
+Consortium Standard, X Version 11, Release 6.1.
+ftp://ftp.x.org/pub/R6.1/xc/doc/hardcopy/XLFD/xlfd.PS.Z
+[The official specification of X font descriptors, including font
+transformation matrices.]
+
+Foley, van Dam, Feiner, and Hughes, _Computer Graphics: Principles and
+Practice_, 2nd ed. Addison-Wesley, 1990, ISBN 0-201-12110-7.
+[Colorspace conversion functions, Bezier spline math.]
+
+Robert L. Hummel, _Programmer's Technical Reference: Data and Fax
+Communications_. Ziff-Davis Press, 1993, ISBN 1-56276-077-7.
+[CCITT Group 3 and 4 fax decoding.]
+
+Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz, "Practical
+Fast 1-D DCT Algorithms with 11 Multiplications". IEEE Intl. Conf. on
+Acoustics, Speech & Signal Processing, 1989, 988-991.
+[The fast IDCT algorithm used in the DCTDecode filter.]
+
+Microsoft, _TrueType 1.0 Font Files_, rev. 1.66. 1995.
+http://www.microsoft.com/typography/tt/tt.htm
+[The TrueType font spec (in MS Word format, naturally).]
+
+Charles Poynton, "Color FAQ".
+http://www.inforamp.net/~poynton/ColorFAQ.html
+[The mapping from the CIE 1931 (XYZ) color space to RGB.]
+
+R. Rivest, "The MD5 Message-Digest Algorithm". RFC 1321.
+[MD5 is used in PDF document encryption.]
+
+Gregory K. Wallace, "The JPEG Still Picture Compression Standard".
+ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz
+[Good description of the JPEG standard. Also published in CACM, April
+1991, and submitted to IEEE Transactions on Consumer Electronics.]
+
+W3C Recommendation, "PNG (Portable Network Graphics) Specification
+Version 1.0".
+http://www.w3.org/Graphics/PNG/
+[Defines the PNG image predictor.]
+
+"ISO 8859-2 (Latin 2) Resources".
+http://sizif.mf.uni-lj.si/linux/cee/iso8859-2.html
+[This is a web page with all sorts of useful Latin-2 character set and
+font information.]
diff --git a/pdftops/SFont.h b/pdftops/SFont.h
new file mode 100644
index 000000000..cab17961e
--- /dev/null
+++ b/pdftops/SFont.h
@@ -0,0 +1,127 @@
+//========================================================================
+//
+// SFont.h
+//
+// Base class for font rasterizers.
+//
+//========================================================================
+
+#ifndef SFONT_H
+#define SFONT_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "gtypes.h"
+
+//------------------------------------------------------------------------
+
+class SFontEngine {
+public:
+
+ SFontEngine(Display *displayA, Visual *visualA, int depthA,
+ Colormap colormapA);
+ virtual ~SFontEngine();
+
+ // Use a TrueColor visual. Pixel values are computed as:
+ //
+ // (r << rShift) + (g << gShift) + (b << bShift)
+ //
+ // where r, g, and b are scaled to the ranges [0,rMax], [0,gMax],
+ // and [0,bMax], respectively.
+ virtual void useTrueColor(int rMaxA, int rShiftA, int gMaxA, int gShiftA,
+ int bMaxA, int bShiftA);
+
+ // Use an RGB color cube. <colors> is an array containing
+ // <nRGB>*<nRGB>*<nRGB> pixel values in red,green,blue order, e.g.,
+ // for <nRGB>=2, there will be 8 entries:
+ //
+ // |--- colors[i] ---|
+ // i red green blue
+ // - ----- ----- -----
+ // 0 0000 0000 0000
+ // 1 0000 0000 ffff
+ // 2 0000 ffff 0000
+ // 3 0000 ffff ffff
+ // 4 ffff 0000 0000
+ // 5 ffff 0000 ffff
+ // 6 ffff ffff 0000
+ // 7 ffff ffff ffff
+ //
+ // The <colors> array is not copied and must remain valid for the
+ // lifetime of this SFont object.
+ virtual void useColorCube(Gulong *colorsA, int nRGBA);
+
+protected:
+
+ // Find the closest match to (<r>,<g>,<b>).
+ Gulong findColor(int r, int g, int b);
+
+ //----- X parameters
+ Display *display;
+ Visual *visual;
+ int depth;
+ Colormap colormap;
+
+ GBool trueColor; // true for TrueColor, false for RGB cube
+
+ //----- TrueColor parameters
+ int rMax, gMax, bMax;
+ int rShift, gShift, bShift;
+
+ //----- RGB color cube parameters
+ Gulong *colors;
+ int nRGB;
+};
+
+//------------------------------------------------------------------------
+
+class SFontFile {
+public:
+
+ // A typical subclass will provide a constructor along the lines of:
+ //
+ // SomeFontFile(SomeFontEngine *engine, char *fontFileName);
+ SFontFile();
+
+ virtual ~SFontFile();
+
+private:
+};
+
+//------------------------------------------------------------------------
+
+class SFont {
+public:
+
+ // A typical subclass will provide a constructor along the lines of:
+ //
+ // SomeFont(SomeFontFile *fontFile, double *m);
+ //
+ // where <m> is a transform matrix consisting of four elements,
+ // using the PostScript ordering conventions (without any
+ // translation):
+ //
+ // [x' y'] = [x y] * [m0 m1]
+ // [m2 m3]
+ //
+ // This is the level at which fonts are cached, and so the font
+ // cannot be transformed after it is created.
+ SFont();
+
+ virtual ~SFont();
+
+ // Draw a character <c> at <x>,<y> in color (<r>,<g>,<b>). The RGB
+ // values should each be in the range [0,65535]. Draws into <d>,
+ // clipped to the rectangle (0,0)-(<w>-1,<h>-1). Returns true if
+ // the character was drawn successfully.
+ virtual GBool drawChar(Drawable d, int w, int h, GC gc,
+ int x, int y, int r, int g, int b, Gushort c) = 0;
+
+protected:
+};
+
+#endif
diff --git a/pdftops/StdFontInfo.h b/pdftops/StdFontInfo.h
new file mode 100644
index 000000000..0db033f6b
--- /dev/null
+++ b/pdftops/StdFontInfo.h
@@ -0,0 +1,546 @@
+//========================================================================
+//
+// StdFontInfo.h
+//
+// This file was automatically generated by makeFontInfo.
+//
+// Copyright 1999 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef STDFONTINFO_H
+#define STDFONTINFO_H
+
+//------------------------------------------------------------------------
+// type1StdEncoding -- Adobe Type 1 StandardEncoding
+//------------------------------------------------------------------------
+
+#define type1StdEncodingSize 256
+static char *type1StdEncodingNames[type1StdEncodingSize] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "space",
+ "exclam",
+ "quotedbl",
+ "numbersign",
+ "dollar",
+ "percent",
+ "ampersand",
+ "quoteright",
+ "parenleft",
+ "parenright",
+ "asterisk",
+ "plus",
+ "comma",
+ "hyphen",
+ "period",
+ "slash",
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less",
+ "equal",
+ "greater",
+ "question",
+ "at",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "bracketleft",
+ "backslash",
+ "bracketright",
+ "asciicircum",
+ "underscore",
+ "quoteleft",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "braceleft",
+ "bar",
+ "braceright",
+ "asciitilde",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "exclamdown",
+ "cent",
+ "sterling",
+ "fraction",
+ "yen",
+ "florin",
+ "section",
+ "currency",
+ "quotesingle",
+ "quotedblleft",
+ "guillemotleft",
+ "guilsinglleft",
+ "guilsinglright",
+ "fi",
+ "fl",
+ NULL,
+ "endash",
+ "dagger",
+ "daggerdbl",
+ "periodcentered",
+ NULL,
+ "paragraph",
+ "bullet",
+ "quotesinglbase",
+ "quotedblbase",
+ "quotedblright",
+ "guillemotright",
+ "ellipsis",
+ "perthousand",
+ NULL,
+ "questiondown",
+ NULL,
+ "grave",
+ "acute",
+ "circumflex",
+ "tilde",
+ "macron",
+ "breve",
+ "dotaccent",
+ "dieresis",
+ NULL,
+ "ring",
+ "cedilla",
+ NULL,
+ "hungarumlaut",
+ "ogonek",
+ "caron",
+ "emdash",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "AE",
+ NULL,
+ "ordfeminine",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "Lslash",
+ "Oslash",
+ "OE",
+ "ordmasculine",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "ae",
+ NULL,
+ NULL,
+ NULL,
+ "dotlessi",
+ NULL,
+ NULL,
+ "lslash",
+ "oslash",
+ "oe",
+ "germandbls",
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+static FontEncoding type1StdEncoding(type1StdEncodingNames,
+ type1StdEncodingSize);
+
+//------------------------------------------------------------------------
+// type1ExpertEncoding -- Adobe Type 1 ExpertEncoding
+//------------------------------------------------------------------------
+
+#define type1ExpertEncodingSize 256
+static char *type1ExpertEncodingNames[type1ExpertEncodingSize] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "space",
+ "exclamsmall",
+ "Hungarumlautsmall",
+ NULL,
+ "dollaroldstyle",
+ "dollarsuperior",
+ "ampersandsmall",
+ "Acutesmall",
+ "parenleftsuperior",
+ "parenrightsuperior",
+ "twodotenleader",
+ "onedotenleader",
+ "comma",
+ "hyphen",
+ "period",
+ "fraction",
+ "zerooldstyle",
+ "oneoldstyle",
+ "twooldstyle",
+ "threeoldstyle",
+ "fouroldstyle",
+ "fiveoldstyle",
+ "sixoldstyle",
+ "sevenoldstyle",
+ "eightoldstyle",
+ "nineoldstyle",
+ "colon",
+ "semicolon",
+ "commasuperior",
+ "threequartersemdash",
+ "periodsuperior",
+ "questionsmall",
+ NULL,
+ "asuperior",
+ "bsuperior",
+ "centsuperior",
+ "dsuperior",
+ "esuperior",
+ NULL,
+ NULL,
+ NULL,
+ "isuperior",
+ NULL,
+ NULL,
+ "lsuperior",
+ "msuperior",
+ "nsuperior",
+ "osuperior",
+ NULL,
+ NULL,
+ "rsuperior",
+ "ssuperior",
+ "tsuperior",
+ NULL,
+ "ff",
+ "fi",
+ "fl",
+ "ffi",
+ "ffl",
+ "parenleftinferior",
+ NULL,
+ "parenrightinferior",
+ "Circumflexsmall",
+ "hyphensuperior",
+ "Gravesmall",
+ "Asmall",
+ "Bsmall",
+ "Csmall",
+ "Dsmall",
+ "Esmall",
+ "Fsmall",
+ "Gsmall",
+ "Hsmall",
+ "Ismall",
+ "Jsmall",
+ "Ksmall",
+ "Lsmall",
+ "Msmall",
+ "Nsmall",
+ "Osmall",
+ "Psmall",
+ "Qsmall",
+ "Rsmall",
+ "Ssmall",
+ "Tsmall",
+ "Usmall",
+ "Vsmall",
+ "Wsmall",
+ "Xsmall",
+ "Ysmall",
+ "Zsmall",
+ "colonmonetary",
+ "onefitted",
+ "rupiah",
+ "Tildesmall",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "exclamdownsmall",
+ "centoldstyle",
+ "Lslashsmall",
+ NULL,
+ NULL,
+ "Scaronsmall",
+ "Zcaronsmall",
+ "Dieresissmall",
+ "Brevesmall",
+ "Caronsmall",
+ NULL,
+ "Dotaccentsmall",
+ NULL,
+ NULL,
+ "Macronsmall",
+ NULL,
+ NULL,
+ "figuredash",
+ "hypheninferior",
+ NULL,
+ NULL,
+ "Ogoneksmall",
+ "Ringsmall",
+ "Cedillasmall",
+ NULL,
+ NULL,
+ NULL,
+ "onequarter",
+ "onehalf",
+ "threequarters",
+ "questiondownsmall",
+ "oneeighth",
+ "threeeighths",
+ "fiveeighths",
+ "seveneighths",
+ "onethird",
+ "twothirds",
+ NULL,
+ NULL,
+ "zerosuperior",
+ "onesuperior",
+ "twosuperior",
+ "threesuperior",
+ "foursuperior",
+ "fivesuperior",
+ "sixsuperior",
+ "sevensuperior",
+ "eightsuperior",
+ "ninesuperior",
+ "zeroinferior",
+ "oneinferior",
+ "twoinferior",
+ "threeinferior",
+ "fourinferior",
+ "fiveinferior",
+ "sixinferior",
+ "seveninferior",
+ "eightinferior",
+ "nineinferior",
+ "centinferior",
+ "dollarinferior",
+ "periodinferior",
+ "commainferior",
+ "Agravesmall",
+ "Aacutesmall",
+ "Acircumflexsmall",
+ "Atildesmall",
+ "Adieresissmall",
+ "Aringsmall",
+ "AEsmall",
+ "Ccedillasmall",
+ "Egravesmall",
+ "Eacutesmall",
+ "Ecircumflexsmall",
+ "Edieresissmall",
+ "Igravesmall",
+ "Iacutesmall",
+ "Icircumflexsmall",
+ "Idieresissmall",
+ "Ethsmall",
+ "Ntildesmall",
+ "Ogravesmall",
+ "Oacutesmall",
+ "Ocircumflexsmall",
+ "Otildesmall",
+ "Odieresissmall",
+ "OEsmall",
+ "Oslashsmall",
+ "Ugravesmall",
+ "Uacutesmall",
+ "Ucircumflexsmall",
+ "Udieresissmall",
+ "Yacutesmall",
+ "Thornsmall",
+ "Ydieresissmall"
+};
+static FontEncoding type1ExpertEncoding(type1ExpertEncodingNames,
+ type1ExpertEncodingSize);
+
+#endif
diff --git a/pdftops/Stream-CCITT.h b/pdftops/Stream-CCITT.h
new file mode 100644
index 000000000..1af874225
--- /dev/null
+++ b/pdftops/Stream-CCITT.h
@@ -0,0 +1,459 @@
+//========================================================================
+//
+// Stream-CCITT.h
+//
+// Tables for CCITT Fax decoding.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+struct CCITTCode {
+ short bits;
+ short n;
+};
+
+#define ccittEOL -2
+
+//------------------------------------------------------------------------
+// 2D codes
+//------------------------------------------------------------------------
+
+#define twoDimPass 0
+#define twoDimHoriz 1
+#define twoDimVert0 2
+#define twoDimVertR1 3
+#define twoDimVertL1 4
+#define twoDimVertR2 5
+#define twoDimVertL2 6
+#define twoDimVertR3 7
+#define twoDimVertL3 8
+
+// 1-7 bit codes
+static CCITTCode twoDimTab1[128] = {
+ {-1, -1}, {-1, -1}, // 000000x
+ {7, twoDimVertL3}, // 0000010
+ {7, twoDimVertR3}, // 0000011
+ {6, twoDimVertL2}, {6, twoDimVertL2}, // 000010x
+ {6, twoDimVertR2}, {6, twoDimVertR2}, // 000011x
+ {4, twoDimPass}, {4, twoDimPass}, // 0001xxx
+ {4, twoDimPass}, {4, twoDimPass},
+ {4, twoDimPass}, {4, twoDimPass},
+ {4, twoDimPass}, {4, twoDimPass},
+ {3, twoDimHoriz}, {3, twoDimHoriz}, // 001xxxx
+ {3, twoDimHoriz}, {3, twoDimHoriz},
+ {3, twoDimHoriz}, {3, twoDimHoriz},
+ {3, twoDimHoriz}, {3, twoDimHoriz},
+ {3, twoDimHoriz}, {3, twoDimHoriz},
+ {3, twoDimHoriz}, {3, twoDimHoriz},
+ {3, twoDimHoriz}, {3, twoDimHoriz},
+ {3, twoDimHoriz}, {3, twoDimHoriz},
+ {3, twoDimVertL1}, {3, twoDimVertL1}, // 010xxxx
+ {3, twoDimVertL1}, {3, twoDimVertL1},
+ {3, twoDimVertL1}, {3, twoDimVertL1},
+ {3, twoDimVertL1}, {3, twoDimVertL1},
+ {3, twoDimVertL1}, {3, twoDimVertL1},
+ {3, twoDimVertL1}, {3, twoDimVertL1},
+ {3, twoDimVertL1}, {3, twoDimVertL1},
+ {3, twoDimVertL1}, {3, twoDimVertL1},
+ {3, twoDimVertR1}, {3, twoDimVertR1}, // 011xxxx
+ {3, twoDimVertR1}, {3, twoDimVertR1},
+ {3, twoDimVertR1}, {3, twoDimVertR1},
+ {3, twoDimVertR1}, {3, twoDimVertR1},
+ {3, twoDimVertR1}, {3, twoDimVertR1},
+ {3, twoDimVertR1}, {3, twoDimVertR1},
+ {3, twoDimVertR1}, {3, twoDimVertR1},
+ {3, twoDimVertR1}, {3, twoDimVertR1},
+ {1, twoDimVert0}, {1, twoDimVert0}, // 1xxxxxx
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0},
+ {1, twoDimVert0}, {1, twoDimVert0}
+};
+
+//------------------------------------------------------------------------
+// white run lengths
+//------------------------------------------------------------------------
+
+// 11-12 bit codes (upper 7 bits are 0)
+static CCITTCode whiteTab1[32] = {
+ {-1, -1}, // 00000
+ {12, ccittEOL}, // 00001
+ {-1, -1}, {-1, -1}, // 0001x
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 001xx
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 010xx
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 011xx
+ {11, 1792}, {11, 1792}, // 1000x
+ {12, 1984}, // 10010
+ {12, 2048}, // 10011
+ {12, 2112}, // 10100
+ {12, 2176}, // 10101
+ {12, 2240}, // 10110
+ {12, 2304}, // 10111
+ {11, 1856}, {11, 1856}, // 1100x
+ {11, 1920}, {11, 1920}, // 1101x
+ {12, 2368}, // 11100
+ {12, 2432}, // 11101
+ {12, 2496}, // 11110
+ {12, 2560} // 11111
+};
+
+// 1-9 bit codes
+static CCITTCode whiteTab2[512] = {
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 0000000xx
+ {8, 29}, {8, 29}, // 00000010x
+ {8, 30}, {8, 30}, // 00000011x
+ {8, 45}, {8, 45}, // 00000100x
+ {8, 46}, {8, 46}, // 00000101x
+ {7, 22}, {7, 22}, {7, 22}, {7, 22}, // 0000011xx
+ {7, 23}, {7, 23}, {7, 23}, {7, 23}, // 0000100xx
+ {8, 47}, {8, 47}, // 00001010x
+ {8, 48}, {8, 48}, // 00001011x
+ {6, 13}, {6, 13}, {6, 13}, {6, 13}, // 000011xxx
+ {6, 13}, {6, 13}, {6, 13}, {6, 13},
+ {7, 20}, {7, 20}, {7, 20}, {7, 20}, // 0001000xx
+ {8, 33}, {8, 33}, // 00010010x
+ {8, 34}, {8, 34}, // 00010011x
+ {8, 35}, {8, 35}, // 00010100x
+ {8, 36}, {8, 36}, // 00010101x
+ {8, 37}, {8, 37}, // 00010110x
+ {8, 38}, {8, 38}, // 00010111x
+ {7, 19}, {7, 19}, {7, 19}, {7, 19}, // 0001100xx
+ {8, 31}, {8, 31}, // 00011010x
+ {8, 32}, {8, 32}, // 00011011x
+ {6, 1}, {6, 1}, {6, 1}, {6, 1}, // 000111xxx
+ {6, 1}, {6, 1}, {6, 1}, {6, 1},
+ {6, 12}, {6, 12}, {6, 12}, {6, 12}, // 001000xxx
+ {6, 12}, {6, 12}, {6, 12}, {6, 12},
+ {8, 53}, {8, 53}, // 00100100x
+ {8, 54}, {8, 54}, // 00100101x
+ {7, 26}, {7, 26}, {7, 26}, {7, 26}, // 0010011xx
+ {8, 39}, {8, 39}, // 00101000x
+ {8, 40}, {8, 40}, // 00101001x
+ {8, 41}, {8, 41}, // 00101010x
+ {8, 42}, {8, 42}, // 00101011x
+ {8, 43}, {8, 43}, // 00101100x
+ {8, 44}, {8, 44}, // 00101101x
+ {7, 21}, {7, 21}, {7, 21}, {7, 21}, // 0010111xx
+ {7, 28}, {7, 28}, {7, 28}, {7, 28}, // 0011000xx
+ {8, 61}, {8, 61}, // 00110010x
+ {8, 62}, {8, 62}, // 00110011x
+ {8, 63}, {8, 63}, // 00110100x
+ {8, 0}, {8, 0}, // 00110101x
+ {8, 320}, {8, 320}, // 00110110x
+ {8, 384}, {8, 384}, // 00110111x
+ {5, 10}, {5, 10}, {5, 10}, {5, 10}, // 00111xxxx
+ {5, 10}, {5, 10}, {5, 10}, {5, 10},
+ {5, 10}, {5, 10}, {5, 10}, {5, 10},
+ {5, 10}, {5, 10}, {5, 10}, {5, 10},
+ {5, 11}, {5, 11}, {5, 11}, {5, 11}, // 01000xxxx
+ {5, 11}, {5, 11}, {5, 11}, {5, 11},
+ {5, 11}, {5, 11}, {5, 11}, {5, 11},
+ {5, 11}, {5, 11}, {5, 11}, {5, 11},
+ {7, 27}, {7, 27}, {7, 27}, {7, 27}, // 0100100xx
+ {8, 59}, {8, 59}, // 01001010x
+ {8, 60}, {8, 60}, // 01001011x
+ {9, 1472}, // 010011000
+ {9, 1536}, // 010011001
+ {9, 1600}, // 010011010
+ {9, 1728}, // 010011011
+ {7, 18}, {7, 18}, {7, 18}, {7, 18}, // 0100111xx
+ {7, 24}, {7, 24}, {7, 24}, {7, 24}, // 0101000xx
+ {8, 49}, {8, 49}, // 01010010x
+ {8, 50}, {8, 50}, // 01010011x
+ {8, 51}, {8, 51}, // 01010100x
+ {8, 52}, {8, 52}, // 01010101x
+ {7, 25}, {7, 25}, {7, 25}, {7, 25}, // 0101011xx
+ {8, 55}, {8, 55}, // 01011000x
+ {8, 56}, {8, 56}, // 01011001x
+ {8, 57}, {8, 57}, // 01011010x
+ {8, 58}, {8, 58}, // 01011011x
+ {6, 192}, {6, 192}, {6, 192}, {6, 192}, // 010111xxx
+ {6, 192}, {6, 192}, {6, 192}, {6, 192},
+ {6, 1664}, {6, 1664}, {6, 1664}, {6, 1664}, // 011000xxx
+ {6, 1664}, {6, 1664}, {6, 1664}, {6, 1664},
+ {8, 448}, {8, 448}, // 01100100x
+ {8, 512}, {8, 512}, // 01100101x
+ {9, 704}, // 011001100
+ {9, 768}, // 011001101
+ {8, 640}, {8, 640}, // 01100111x
+ {8, 576}, {8, 576}, // 01101000x
+ {9, 832}, // 011010010
+ {9, 896}, // 011010011
+ {9, 960}, // 011010100
+ {9, 1024}, // 011010101
+ {9, 1088}, // 011010110
+ {9, 1152}, // 011010111
+ {9, 1216}, // 011011000
+ {9, 1280}, // 011011001
+ {9, 1344}, // 011011010
+ {9, 1408}, // 011011011
+ {7, 256}, {7, 256}, {7, 256}, {7, 256}, // 0110111xx
+ {4, 2}, {4, 2}, {4, 2}, {4, 2}, // 0111xxxxx
+ {4, 2}, {4, 2}, {4, 2}, {4, 2},
+ {4, 2}, {4, 2}, {4, 2}, {4, 2},
+ {4, 2}, {4, 2}, {4, 2}, {4, 2},
+ {4, 2}, {4, 2}, {4, 2}, {4, 2},
+ {4, 2}, {4, 2}, {4, 2}, {4, 2},
+ {4, 2}, {4, 2}, {4, 2}, {4, 2},
+ {4, 2}, {4, 2}, {4, 2}, {4, 2},
+ {4, 3}, {4, 3}, {4, 3}, {4, 3}, // 1000xxxxx
+ {4, 3}, {4, 3}, {4, 3}, {4, 3},
+ {4, 3}, {4, 3}, {4, 3}, {4, 3},
+ {4, 3}, {4, 3}, {4, 3}, {4, 3},
+ {4, 3}, {4, 3}, {4, 3}, {4, 3},
+ {4, 3}, {4, 3}, {4, 3}, {4, 3},
+ {4, 3}, {4, 3}, {4, 3}, {4, 3},
+ {4, 3}, {4, 3}, {4, 3}, {4, 3},
+ {5, 128}, {5, 128}, {5, 128}, {5, 128}, // 10010xxxx
+ {5, 128}, {5, 128}, {5, 128}, {5, 128},
+ {5, 128}, {5, 128}, {5, 128}, {5, 128},
+ {5, 128}, {5, 128}, {5, 128}, {5, 128},
+ {5, 8}, {5, 8}, {5, 8}, {5, 8}, // 10011xxxx
+ {5, 8}, {5, 8}, {5, 8}, {5, 8},
+ {5, 8}, {5, 8}, {5, 8}, {5, 8},
+ {5, 8}, {5, 8}, {5, 8}, {5, 8},
+ {5, 9}, {5, 9}, {5, 9}, {5, 9}, // 10100xxxx
+ {5, 9}, {5, 9}, {5, 9}, {5, 9},
+ {5, 9}, {5, 9}, {5, 9}, {5, 9},
+ {5, 9}, {5, 9}, {5, 9}, {5, 9},
+ {6, 16}, {6, 16}, {6, 16}, {6, 16}, // 101010xxx
+ {6, 16}, {6, 16}, {6, 16}, {6, 16},
+ {6, 17}, {6, 17}, {6, 17}, {6, 17}, // 101011xxx
+ {6, 17}, {6, 17}, {6, 17}, {6, 17},
+ {4, 4}, {4, 4}, {4, 4}, {4, 4}, // 1011xxxxx
+ {4, 4}, {4, 4}, {4, 4}, {4, 4},
+ {4, 4}, {4, 4}, {4, 4}, {4, 4},
+ {4, 4}, {4, 4}, {4, 4}, {4, 4},
+ {4, 4}, {4, 4}, {4, 4}, {4, 4},
+ {4, 4}, {4, 4}, {4, 4}, {4, 4},
+ {4, 4}, {4, 4}, {4, 4}, {4, 4},
+ {4, 4}, {4, 4}, {4, 4}, {4, 4},
+ {4, 5}, {4, 5}, {4, 5}, {4, 5}, // 1100xxxxx
+ {4, 5}, {4, 5}, {4, 5}, {4, 5},
+ {4, 5}, {4, 5}, {4, 5}, {4, 5},
+ {4, 5}, {4, 5}, {4, 5}, {4, 5},
+ {4, 5}, {4, 5}, {4, 5}, {4, 5},
+ {4, 5}, {4, 5}, {4, 5}, {4, 5},
+ {4, 5}, {4, 5}, {4, 5}, {4, 5},
+ {4, 5}, {4, 5}, {4, 5}, {4, 5},
+ {6, 14}, {6, 14}, {6, 14}, {6, 14}, // 110100xxx
+ {6, 14}, {6, 14}, {6, 14}, {6, 14},
+ {6, 15}, {6, 15}, {6, 15}, {6, 15}, // 110101xxx
+ {6, 15}, {6, 15}, {6, 15}, {6, 15},
+ {5, 64}, {5, 64}, {5, 64}, {5, 64}, // 11011xxxx
+ {5, 64}, {5, 64}, {5, 64}, {5, 64},
+ {5, 64}, {5, 64}, {5, 64}, {5, 64},
+ {5, 64}, {5, 64}, {5, 64}, {5, 64},
+ {4, 6}, {4, 6}, {4, 6}, {4, 6}, // 1110xxxxx
+ {4, 6}, {4, 6}, {4, 6}, {4, 6},
+ {4, 6}, {4, 6}, {4, 6}, {4, 6},
+ {4, 6}, {4, 6}, {4, 6}, {4, 6},
+ {4, 6}, {4, 6}, {4, 6}, {4, 6},
+ {4, 6}, {4, 6}, {4, 6}, {4, 6},
+ {4, 6}, {4, 6}, {4, 6}, {4, 6},
+ {4, 6}, {4, 6}, {4, 6}, {4, 6},
+ {4, 7}, {4, 7}, {4, 7}, {4, 7}, // 1111xxxxx
+ {4, 7}, {4, 7}, {4, 7}, {4, 7},
+ {4, 7}, {4, 7}, {4, 7}, {4, 7},
+ {4, 7}, {4, 7}, {4, 7}, {4, 7},
+ {4, 7}, {4, 7}, {4, 7}, {4, 7},
+ {4, 7}, {4, 7}, {4, 7}, {4, 7},
+ {4, 7}, {4, 7}, {4, 7}, {4, 7},
+ {4, 7}, {4, 7}, {4, 7}, {4, 7}
+};
+
+//------------------------------------------------------------------------
+// black run lengths
+//------------------------------------------------------------------------
+
+// 10-13 bit codes (upper 6 bits are 0)
+static CCITTCode blackTab1[128] = {
+ {-1, -1}, {-1, -1}, // 000000000000x
+ {12, ccittEOL}, {12, ccittEOL}, // 000000000001x
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000001xx
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000010xx
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000011xx
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000100xx
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000101xx
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000110xx
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000111xx
+ {11, 1792}, {11, 1792}, {11, 1792}, {11, 1792}, // 00000001000xx
+ {12, 1984}, {12, 1984}, // 000000010010x
+ {12, 2048}, {12, 2048}, // 000000010011x
+ {12, 2112}, {12, 2112}, // 000000010100x
+ {12, 2176}, {12, 2176}, // 000000010101x
+ {12, 2240}, {12, 2240}, // 000000010110x
+ {12, 2304}, {12, 2304}, // 000000010111x
+ {11, 1856}, {11, 1856}, {11, 1856}, {11, 1856}, // 00000001100xx
+ {11, 1920}, {11, 1920}, {11, 1920}, {11, 1920}, // 00000001101xx
+ {12, 2368}, {12, 2368}, // 000000011100x
+ {12, 2432}, {12, 2432}, // 000000011101x
+ {12, 2496}, {12, 2496}, // 000000011110x
+ {12, 2560}, {12, 2560}, // 000000011111x
+ {10, 18}, {10, 18}, {10, 18}, {10, 18}, // 0000001000xxx
+ {10, 18}, {10, 18}, {10, 18}, {10, 18},
+ {12, 52}, {12, 52}, // 000000100100x
+ {13, 640}, // 0000001001010
+ {13, 704}, // 0000001001011
+ {13, 768}, // 0000001001100
+ {13, 832}, // 0000001001101
+ {12, 55}, {12, 55}, // 000000100111x
+ {12, 56}, {12, 56}, // 000000101000x
+ {13, 1280}, // 0000001010010
+ {13, 1344}, // 0000001010011
+ {13, 1408}, // 0000001010100
+ {13, 1472}, // 0000001010101
+ {12, 59}, {12, 59}, // 000000101011x
+ {12, 60}, {12, 60}, // 000000101100x
+ {13, 1536}, // 0000001011010
+ {13, 1600}, // 0000001011011
+ {11, 24}, {11, 24}, {11, 24}, {11, 24}, // 00000010111xx
+ {11, 25}, {11, 25}, {11, 25}, {11, 25}, // 00000011000xx
+ {13, 1664}, // 0000001100100
+ {13, 1728}, // 0000001100101
+ {12, 320}, {12, 320}, // 000000110011x
+ {12, 384}, {12, 384}, // 000000110100x
+ {12, 448}, {12, 448}, // 000000110101x
+ {13, 512}, // 0000001101100
+ {13, 576}, // 0000001101101
+ {12, 53}, {12, 53}, // 000000110111x
+ {12, 54}, {12, 54}, // 000000111000x
+ {13, 896}, // 0000001110010
+ {13, 960}, // 0000001110011
+ {13, 1024}, // 0000001110100
+ {13, 1088}, // 0000001110101
+ {13, 1152}, // 0000001110110
+ {13, 1216}, // 0000001110111
+ {10, 64}, {10, 64}, {10, 64}, {10, 64}, // 0000001111xxx
+ {10, 64}, {10, 64}, {10, 64}, {10, 64}
+};
+
+// 7-12 bit codes (upper 4 bits are 0)
+static CCITTCode blackTab2[192] = {
+ {8, 13}, {8, 13}, {8, 13}, {8, 13}, // 00000100xxxx
+ {8, 13}, {8, 13}, {8, 13}, {8, 13},
+ {8, 13}, {8, 13}, {8, 13}, {8, 13},
+ {8, 13}, {8, 13}, {8, 13}, {8, 13},
+ {11, 23}, {11, 23}, // 00000101000x
+ {12, 50}, // 000001010010
+ {12, 51}, // 000001010011
+ {12, 44}, // 000001010100
+ {12, 45}, // 000001010101
+ {12, 46}, // 000001010110
+ {12, 47}, // 000001010111
+ {12, 57}, // 000001011000
+ {12, 58}, // 000001011001
+ {12, 61}, // 000001011010
+ {12, 256}, // 000001011011
+ {10, 16}, {10, 16}, {10, 16}, {10, 16}, // 0000010111xx
+ {10, 17}, {10, 17}, {10, 17}, {10, 17}, // 0000011000xx
+ {12, 48}, // 000001100100
+ {12, 49}, // 000001100101
+ {12, 62}, // 000001100110
+ {12, 63}, // 000001100111
+ {12, 30}, // 000001101000
+ {12, 31}, // 000001101001
+ {12, 32}, // 000001101010
+ {12, 33}, // 000001101011
+ {12, 40}, // 000001101100
+ {12, 41}, // 000001101101
+ {11, 22}, {11, 22}, // 00000110111x
+ {8, 14}, {8, 14}, {8, 14}, {8, 14}, // 00000111xxxx
+ {8, 14}, {8, 14}, {8, 14}, {8, 14},
+ {8, 14}, {8, 14}, {8, 14}, {8, 14},
+ {8, 14}, {8, 14}, {8, 14}, {8, 14},
+ {7, 10}, {7, 10}, {7, 10}, {7, 10}, // 0000100xxxxx
+ {7, 10}, {7, 10}, {7, 10}, {7, 10},
+ {7, 10}, {7, 10}, {7, 10}, {7, 10},
+ {7, 10}, {7, 10}, {7, 10}, {7, 10},
+ {7, 10}, {7, 10}, {7, 10}, {7, 10},
+ {7, 10}, {7, 10}, {7, 10}, {7, 10},
+ {7, 10}, {7, 10}, {7, 10}, {7, 10},
+ {7, 10}, {7, 10}, {7, 10}, {7, 10},
+ {7, 11}, {7, 11}, {7, 11}, {7, 11}, // 0000101xxxxx
+ {7, 11}, {7, 11}, {7, 11}, {7, 11},
+ {7, 11}, {7, 11}, {7, 11}, {7, 11},
+ {7, 11}, {7, 11}, {7, 11}, {7, 11},
+ {7, 11}, {7, 11}, {7, 11}, {7, 11},
+ {7, 11}, {7, 11}, {7, 11}, {7, 11},
+ {7, 11}, {7, 11}, {7, 11}, {7, 11},
+ {7, 11}, {7, 11}, {7, 11}, {7, 11},
+ {9, 15}, {9, 15}, {9, 15}, {9, 15}, // 000011000xxx
+ {9, 15}, {9, 15}, {9, 15}, {9, 15},
+ {12, 128}, // 000011001000
+ {12, 192}, // 000011001001
+ {12, 26}, // 000011001010
+ {12, 27}, // 000011001011
+ {12, 28}, // 000011001100
+ {12, 29}, // 000011001101
+ {11, 19}, {11, 19}, // 00001100111x
+ {11, 20}, {11, 20}, // 00001101000x
+ {12, 34}, // 000011010010
+ {12, 35}, // 000011010011
+ {12, 36}, // 000011010100
+ {12, 37}, // 000011010101
+ {12, 38}, // 000011010110
+ {12, 39}, // 000011010111
+ {11, 21}, {11, 21}, // 00001101100x
+ {12, 42}, // 000011011010
+ {12, 43}, // 000011011011
+ {10, 0}, {10, 0}, {10, 0}, {10, 0}, // 0000110111xx
+ {7, 12}, {7, 12}, {7, 12}, {7, 12}, // 0000111xxxxx
+ {7, 12}, {7, 12}, {7, 12}, {7, 12},
+ {7, 12}, {7, 12}, {7, 12}, {7, 12},
+ {7, 12}, {7, 12}, {7, 12}, {7, 12},
+ {7, 12}, {7, 12}, {7, 12}, {7, 12},
+ {7, 12}, {7, 12}, {7, 12}, {7, 12},
+ {7, 12}, {7, 12}, {7, 12}, {7, 12},
+ {7, 12}, {7, 12}, {7, 12}, {7, 12}
+};
+
+// 2-6 bit codes
+static CCITTCode blackTab3[64] = {
+ {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 0000xx
+ {6, 9}, // 000100
+ {6, 8}, // 000101
+ {5, 7}, {5, 7}, // 00011x
+ {4, 6}, {4, 6}, {4, 6}, {4, 6}, // 0010xx
+ {4, 5}, {4, 5}, {4, 5}, {4, 5}, // 0011xx
+ {3, 1}, {3, 1}, {3, 1}, {3, 1}, // 010xxx
+ {3, 1}, {3, 1}, {3, 1}, {3, 1},
+ {3, 4}, {3, 4}, {3, 4}, {3, 4}, // 011xxx
+ {3, 4}, {3, 4}, {3, 4}, {3, 4},
+ {2, 3}, {2, 3}, {2, 3}, {2, 3}, // 10xxxx
+ {2, 3}, {2, 3}, {2, 3}, {2, 3},
+ {2, 3}, {2, 3}, {2, 3}, {2, 3},
+ {2, 3}, {2, 3}, {2, 3}, {2, 3},
+ {2, 2}, {2, 2}, {2, 2}, {2, 2}, // 11xxxx
+ {2, 2}, {2, 2}, {2, 2}, {2, 2},
+ {2, 2}, {2, 2}, {2, 2}, {2, 2},
+ {2, 2}, {2, 2}, {2, 2}, {2, 2}
+};
diff --git a/pdftops/Stream.cxx b/pdftops/Stream.cxx
new file mode 100644
index 000000000..a8a88e623
--- /dev/null
+++ b/pdftops/Stream.cxx
@@ -0,0 +1,3466 @@
+//========================================================================
+//
+// Stream.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#ifndef WIN32
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <ctype.h>
+#include "gmem.h"
+#include "gfile.h"
+#include "config.h"
+#include "Error.h"
+#include "Object.h"
+#ifndef NO_DECRYPTION
+#include "Decrypt.h"
+#endif
+#include "Stream.h"
+#include "Stream-CCITT.h"
+
+#ifdef __DJGPP__
+static GBool setDJSYSFLAGS = gFalse;
+#endif
+
+#ifdef VMS
+#if (__VMS_VER < 70000000)
+extern "C" int unlink(char *filename);
+#endif
+#ifdef __GNUC__
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+#endif
+
+#ifdef MACOS
+#include "StuffItEngineLib.h"
+#endif
+
+//------------------------------------------------------------------------
+// Stream (base class)
+//------------------------------------------------------------------------
+
+Stream::Stream() {
+ ref = 1;
+}
+
+Stream::~Stream() {
+}
+
+void Stream::close() {
+}
+
+int Stream::getRawChar() {
+ error(-1, "Internal: called getRawChar() on non-predictor stream");
+ return EOF;
+}
+
+char *Stream::getLine(char *buf, int size) {
+ int i;
+ int c;
+
+ if (lookChar() == EOF)
+ return NULL;
+ for (i = 0; i < size - 1; ++i) {
+ c = getChar();
+ if (c == EOF || c == '\n')
+ break;
+ if (c == '\r') {
+ if ((c = lookChar()) == '\n')
+ getChar();
+ break;
+ }
+ buf[i] = c;
+ }
+ buf[i] = '\0';
+ return buf;
+}
+
+GString *Stream::getPSFilter(char *indent) {
+ return new GString();
+}
+
+Stream *Stream::addFilters(Object *dict) {
+ Object obj, obj2;
+ Object params, params2;
+ Stream *str;
+ int i;
+
+ str = this;
+ dict->dictLookup("Filter", &obj);
+ if (obj.isNull()) {
+ obj.free();
+ dict->dictLookup("F", &obj);
+ }
+ dict->dictLookup("DecodeParms", &params);
+ if (params.isNull()) {
+ params.free();
+ dict->dictLookup("DP", &params);
+ }
+ if (obj.isName()) {
+ str = makeFilter(obj.getName(), str, &params);
+ } else if (obj.isArray()) {
+ for (i = 0; i < obj.arrayGetLength(); ++i) {
+ obj.arrayGet(i, &obj2);
+ if (params.isArray())
+ params.arrayGet(i, &params2);
+ else
+ params2.initNull();
+ if (obj2.isName()) {
+ str = makeFilter(obj2.getName(), str, &params2);
+ } else {
+ error(getPos(), "Bad filter name");
+ str = new EOFStream(str);
+ }
+ obj2.free();
+ params2.free();
+ }
+ } else if (!obj.isNull()) {
+ error(getPos(), "Bad 'Filter' attribute in stream");
+ }
+ obj.free();
+ params.free();
+
+ return str;
+}
+
+Stream *Stream::makeFilter(char *name, Stream *str, Object *params) {
+ int pred; // parameters
+ int colors;
+ int bits;
+ int early;
+ int encoding;
+ GBool endOfLine, byteAlign, endOfBlock, black;
+ int columns, rows;
+ Object obj;
+
+ if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
+ str = new ASCIIHexStream(str);
+ } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
+ str = new ASCII85Stream(str);
+ } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
+ pred = 1;
+ columns = 1;
+ colors = 1;
+ bits = 8;
+ early = 1;
+ if (params->isDict()) {
+ params->dictLookup("Predictor", &obj);
+ if (obj.isInt())
+ pred = obj.getInt();
+ obj.free();
+ params->dictLookup("Columns", &obj);
+ if (obj.isInt())
+ columns = obj.getInt();
+ obj.free();
+ params->dictLookup("Colors", &obj);
+ if (obj.isInt())
+ colors = obj.getInt();
+ obj.free();
+ params->dictLookup("BitsPerComponent", &obj);
+ if (obj.isInt())
+ bits = obj.getInt();
+ obj.free();
+ params->dictLookup("EarlyChange", &obj);
+ if (obj.isInt())
+ early = obj.getInt();
+ obj.free();
+ }
+ str = new LZWStream(str, pred, columns, colors, bits, early);
+ } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
+ str = new RunLengthStream(str);
+ } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
+ encoding = 0;
+ endOfLine = gFalse;
+ byteAlign = gFalse;
+ columns = 1728;
+ rows = 0;
+ endOfBlock = gTrue;
+ black = gFalse;
+ if (params->isDict()) {
+ params->dictLookup("K", &obj);
+ if (obj.isInt()) {
+ encoding = obj.getInt();
+ }
+ obj.free();
+ params->dictLookup("EndOfLine", &obj);
+ if (obj.isBool()) {
+ endOfLine = obj.getBool();
+ }
+ obj.free();
+ params->dictLookup("EncodedByteAlign", &obj);
+ if (obj.isBool()) {
+ byteAlign = obj.getBool();
+ }
+ obj.free();
+ params->dictLookup("Columns", &obj);
+ if (obj.isInt()) {
+ columns = obj.getInt();
+ }
+ obj.free();
+ params->dictLookup("Rows", &obj);
+ if (obj.isInt()) {
+ rows = obj.getInt();
+ }
+ obj.free();
+ params->dictLookup("EndOfBlock", &obj);
+ if (obj.isBool()) {
+ endOfBlock = obj.getBool();
+ }
+ obj.free();
+ params->dictLookup("BlackIs1", &obj);
+ if (obj.isBool()) {
+ black = obj.getBool();
+ }
+ obj.free();
+ }
+ str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
+ columns, rows, endOfBlock, black);
+ } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
+ str = new DCTStream(str);
+ } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
+ pred = 1;
+ columns = 1;
+ colors = 1;
+ bits = 8;
+ if (params->isDict()) {
+ params->dictLookup("Predictor", &obj);
+ if (obj.isInt())
+ pred = obj.getInt();
+ obj.free();
+ params->dictLookup("Columns", &obj);
+ if (obj.isInt())
+ columns = obj.getInt();
+ obj.free();
+ params->dictLookup("Colors", &obj);
+ if (obj.isInt())
+ colors = obj.getInt();
+ obj.free();
+ params->dictLookup("BitsPerComponent", &obj);
+ if (obj.isInt())
+ bits = obj.getInt();
+ obj.free();
+ }
+ str = new FlateStream(str, pred, columns, colors, bits);
+ } else {
+ error(getPos(), "Unknown filter '%s'", name);
+ str = new EOFStream(str);
+ }
+ return str;
+}
+
+//------------------------------------------------------------------------
+// BaseStream
+//------------------------------------------------------------------------
+
+BaseStream::BaseStream(Object *dictA) {
+ dict = *dictA;
+#ifndef NO_DECRYPTION
+ decrypt = NULL;
+#endif
+}
+
+BaseStream::~BaseStream() {
+ dict.free();
+#ifndef NO_DECRYPTION
+ if (decrypt)
+ delete decrypt;
+#endif
+}
+
+#ifndef NO_DECRYPTION
+void BaseStream::doDecryption(Guchar *fileKey, int keyLength,
+ int objNum, int objGen) {
+ decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
+}
+#endif
+
+//------------------------------------------------------------------------
+// FilterStream
+//------------------------------------------------------------------------
+
+FilterStream::FilterStream(Stream *strA) {
+ str = strA;
+}
+
+FilterStream::~FilterStream() {
+}
+
+void FilterStream::close() {
+ str->close();
+}
+
+void FilterStream::setPos(int pos) {
+ error(-1, "Internal: called setPos() on FilterStream");
+}
+
+//------------------------------------------------------------------------
+// ImageStream
+//------------------------------------------------------------------------
+
+ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
+ int imgLineSize;
+
+ str = strA;
+ width = widthA;
+ nComps = nCompsA;
+ nBits = nBitsA;
+
+ nVals = width * nComps;
+ if (nBits == 1) {
+ imgLineSize = (nVals + 7) & ~7;
+ } else {
+ imgLineSize = nVals;
+ }
+ imgLine = (Guchar *)gmalloc(imgLineSize * sizeof(Guchar));
+ imgIdx = nVals;
+}
+
+ImageStream::~ImageStream() {
+ gfree(imgLine);
+}
+
+void ImageStream::reset() {
+ str->reset();
+}
+
+GBool ImageStream::getPixel(Guchar *pix) {
+ Gulong buf, bitMask;
+ int bits;
+ int c;
+ int i;
+
+ if (imgIdx >= nVals) {
+
+ // read one line of image pixels
+ if (nBits == 1) {
+ for (i = 0; i < nVals; i += 8) {
+ c = str->getChar();
+ imgLine[i+0] = (Guchar)((c >> 7) & 1);
+ imgLine[i+1] = (Guchar)((c >> 6) & 1);
+ imgLine[i+2] = (Guchar)((c >> 5) & 1);
+ imgLine[i+3] = (Guchar)((c >> 4) & 1);
+ imgLine[i+4] = (Guchar)((c >> 3) & 1);
+ imgLine[i+5] = (Guchar)((c >> 2) & 1);
+ imgLine[i+6] = (Guchar)((c >> 1) & 1);
+ imgLine[i+7] = (Guchar)(c & 1);
+ }
+ } else if (nBits == 8) {
+ for (i = 0; i < nVals; ++i) {
+ imgLine[i] = str->getChar();
+ }
+ } else {
+ bitMask = (1 << nBits) - 1;
+ buf = 0;
+ bits = 0;
+ for (i = 0; i < nVals; ++i) {
+ if (bits < nBits) {
+ buf = (buf << 8) | (str->getChar() & 0xff);
+ bits += 8;
+ }
+ imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
+ bits -= nBits;
+ }
+ }
+
+ // reset to start of line
+ imgIdx = 0;
+ }
+
+ for (i = 0; i < nComps; ++i)
+ pix[i] = imgLine[imgIdx++];
+ return gTrue;
+}
+
+void ImageStream::skipLine() {
+ int n, i;
+
+ n = (nVals * nBits + 7) >> 3;
+ for (i = 0; i < n; ++i) {
+ str->getChar();
+ }
+}
+
+//------------------------------------------------------------------------
+// StreamPredictor
+//------------------------------------------------------------------------
+
+StreamPredictor::StreamPredictor(Stream *strA, int predictorA,
+ int widthA, int nCompsA, int nBitsA) {
+ str = strA;
+ predictor = predictorA;
+ width = widthA;
+ nComps = nCompsA;
+ nBits = nBitsA;
+
+ nVals = width * nComps;
+ pixBytes = (nComps * nBits + 7) >> 3;
+ rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
+ predLine = (Guchar *)gmalloc(rowBytes);
+ memset(predLine, 0, rowBytes);
+ predIdx = rowBytes;
+}
+
+StreamPredictor::~StreamPredictor() {
+ gfree(predLine);
+}
+
+int StreamPredictor::lookChar() {
+ if (predIdx >= rowBytes) {
+ if (!getNextLine()) {
+ return EOF;
+ }
+ }
+ return predLine[predIdx];
+}
+
+int StreamPredictor::getChar() {
+ if (predIdx >= rowBytes) {
+ if (!getNextLine()) {
+ return EOF;
+ }
+ }
+ return predLine[predIdx++];
+}
+
+GBool StreamPredictor::getNextLine() {
+ int curPred;
+ Guchar upLeftBuf[4];
+ int left, up, upLeft, p, pa, pb, pc;
+ int c;
+ Gulong inBuf, outBuf, bitMask;
+ int inBits, outBits;
+ int i, j, k;
+
+ // get PNG optimum predictor number
+ if (predictor == 15) {
+ if ((curPred = str->getRawChar()) == EOF) {
+ return gFalse;
+ }
+ curPred += 10;
+ } else {
+ curPred = predictor;
+ }
+
+ // read the raw line, apply PNG (byte) predictor
+ upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
+ for (i = pixBytes; i < rowBytes; ++i) {
+ upLeftBuf[3] = upLeftBuf[2];
+ upLeftBuf[2] = upLeftBuf[1];
+ upLeftBuf[1] = upLeftBuf[0];
+ upLeftBuf[0] = predLine[i];
+ if ((c = str->getRawChar()) == EOF) {
+ break;
+ }
+ switch (curPred) {
+ case 11: // PNG sub
+ predLine[i] = predLine[i - pixBytes] + (Guchar)c;
+ break;
+ case 12: // PNG up
+ predLine[i] = predLine[i] + (Guchar)c;
+ break;
+ case 13: // PNG average
+ predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) +
+ (Guchar)c;
+ break;
+ case 14: // PNG Paeth
+ left = predLine[i - pixBytes];
+ up = predLine[i];
+ upLeft = upLeftBuf[pixBytes];
+ p = left + up - upLeft;
+ if ((pa = p - left) < 0)
+ pa = -pa;
+ if ((pb = p - up) < 0)
+ pb = -pb;
+ if ((pc = p - upLeft) < 0)
+ pc = -pc;
+ if (pa <= pb && pa <= pc)
+ predLine[i] = pa + (Guchar)c;
+ else if (pb <= pc)
+ predLine[i] = pb + (Guchar)c;
+ else
+ predLine[i] = pc + (Guchar)c;
+ break;
+ case 10: // PNG none
+ default: // no predictor or TIFF predictor
+ predLine[i] = (Guchar)c;
+ break;
+ }
+ }
+
+ // apply TIFF (component) predictor
+ //~ this is completely untested
+ if (predictor == 2) {
+ if (nBits == 1) {
+ inBuf = predLine[pixBytes - 1];
+ for (i = pixBytes; i < rowBytes; i += 8) {
+ // 1-bit add is just xor
+ inBuf = (inBuf << 8) | predLine[i];
+ predLine[i] ^= inBuf >> nComps;
+ }
+ } else if (nBits == 8) {
+ for (i = pixBytes; i < rowBytes; ++i) {
+ predLine[i] += predLine[i - nComps];
+ }
+ } else {
+ upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
+ bitMask = (1 << nBits) - 1;
+ inBuf = outBuf = 0;
+ inBits = outBits = 0;
+ j = k = pixBytes;
+ for (i = 0; i < nVals; ++i) {
+ if (inBits < nBits) {
+ inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
+ inBits += 8;
+ }
+ upLeftBuf[3] = upLeftBuf[2];
+ upLeftBuf[2] = upLeftBuf[1];
+ upLeftBuf[1] = upLeftBuf[0];
+ upLeftBuf[0] = (upLeftBuf[nComps] +
+ (inBuf >> (inBits - nBits))) & bitMask;
+ outBuf = (outBuf << nBits) | upLeftBuf[0];
+ inBits -= nBits;
+ outBits += nBits;
+ if (outBits > 8) {
+ predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
+ }
+ }
+ if (outBits > 0) {
+ predLine[k++] = (Guchar)(outBuf << (8 - outBits));
+ }
+ }
+ }
+
+ // reset to start of line
+ predIdx = pixBytes;
+
+ return gTrue;
+}
+
+//------------------------------------------------------------------------
+// FileStream
+//------------------------------------------------------------------------
+
+FileStream::FileStream(FILE *fA, int startA, int lengthA, Object *dictA):
+ BaseStream(dictA) {
+ f = fA;
+ start = startA;
+ length = lengthA;
+ bufPtr = bufEnd = buf;
+ bufPos = start;
+ savePos = -1;
+}
+
+FileStream::~FileStream() {
+ close();
+}
+
+Stream *FileStream::makeSubStream(int startA, int lengthA, Object *dictA) {
+ return new FileStream(f, startA, lengthA, dictA);
+}
+
+void FileStream::reset() {
+ savePos = (int)ftell(f);
+ fseek(f, start, SEEK_SET);
+ bufPtr = bufEnd = buf;
+ bufPos = start;
+#ifndef NO_DECRYPTION
+ if (decrypt)
+ decrypt->reset();
+#endif
+}
+
+void FileStream::close() {
+ if (savePos >= 0) {
+ fseek(f, savePos, SEEK_SET);
+ savePos = -1;
+ }
+}
+
+GBool FileStream::fillBuf() {
+ int n;
+#ifndef NO_DECRYPTION
+ char *p;
+#endif
+
+ bufPos += bufEnd - buf;
+ bufPtr = bufEnd = buf;
+ if (length >= 0 && bufPos >= start + length) {
+ return gFalse;
+ }
+ if (length >= 0 && bufPos + fileStreamBufSize > start + length) {
+ n = start + length - bufPos;
+ } else {
+ n = fileStreamBufSize;
+ }
+ n = fread(buf, 1, n, f);
+ bufEnd = buf + n;
+ if (bufPtr >= bufEnd) {
+ return gFalse;
+ }
+#ifndef NO_DECRYPTION
+ if (decrypt) {
+ for (p = buf; p < bufEnd; ++p) {
+ *p = (char)decrypt->decryptByte((Guchar)*p);
+ }
+ }
+#endif
+ return gTrue;
+}
+
+void FileStream::setPos(int pos) {
+ long size;
+
+ if (pos >= 0) {
+ fseek(f, pos, SEEK_SET);
+ bufPos = pos;
+ } else {
+ fseek(f, 0, SEEK_END);
+ size = ftell(f);
+ if (pos < -size)
+ pos = (int)(-size);
+#ifdef __CYGWIN32__
+ //~ work around a bug in cygwin's implementation of fseek
+ rewind(f);
+#endif
+ fseek(f, pos, SEEK_END);
+ bufPos = (int)ftell(f);
+ }
+ bufPtr = bufEnd = buf;
+}
+
+void FileStream::moveStart(int delta) {
+ start += delta;
+ bufPtr = bufEnd = buf;
+ bufPos = start;
+}
+
+//------------------------------------------------------------------------
+// EmbedStream
+//------------------------------------------------------------------------
+
+EmbedStream::EmbedStream(Stream *strA, Object *dictA):
+ BaseStream(dictA) {
+ str = strA;
+}
+
+EmbedStream::~EmbedStream() {
+}
+
+Stream *EmbedStream::makeSubStream(int start, int length, Object *dictA) {
+ error(-1, "Internal: called makeSubStream() on EmbedStream");
+ return NULL;
+}
+
+void EmbedStream::setPos(int pos) {
+ error(-1, "Internal: called setPos() on EmbedStream");
+}
+
+int EmbedStream::getStart() {
+ error(-1, "Internal: called getStart() on EmbedStream");
+ return 0;
+}
+
+void EmbedStream::moveStart(int start) {
+ error(-1, "Internal: called moveStart() on EmbedStream");
+}
+
+//------------------------------------------------------------------------
+// ASCIIHexStream
+//------------------------------------------------------------------------
+
+ASCIIHexStream::ASCIIHexStream(Stream *strA):
+ FilterStream(strA) {
+ buf = EOF;
+ eof = gFalse;
+}
+
+ASCIIHexStream::~ASCIIHexStream() {
+ delete str;
+}
+
+void ASCIIHexStream::reset() {
+ str->reset();
+ buf = EOF;
+ eof = gFalse;
+}
+
+int ASCIIHexStream::lookChar() {
+ int c1, c2, x;
+
+ if (buf != EOF)
+ return buf;
+ if (eof) {
+ buf = EOF;
+ return EOF;
+ }
+ do {
+ c1 = str->getChar();
+ } while (isspace(c1));
+ if (c1 == '>') {
+ eof = gTrue;
+ buf = EOF;
+ return buf;
+ }
+ do {
+ c2 = str->getChar();
+ } while (isspace(c2));
+ if (c2 == '>') {
+ eof = gTrue;
+ c2 = '0';
+ }
+ if (c1 >= '0' && c1 <= '9') {
+ x = (c1 - '0') << 4;
+ } else if (c1 >= 'A' && c1 <= 'F') {
+ x = (c1 - 'A' + 10) << 4;
+ } else if (c1 >= 'a' && c1 <= 'f') {
+ x = (c1 - 'a' + 10) << 4;
+ } else if (c1 == EOF) {
+ eof = gTrue;
+ x = 0;
+ } else {
+ error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
+ x = 0;
+ }
+ if (c2 >= '0' && c2 <= '9') {
+ x += c2 - '0';
+ } else if (c2 >= 'A' && c2 <= 'F') {
+ x += c2 - 'A' + 10;
+ } else if (c2 >= 'a' && c2 <= 'f') {
+ x += c2 - 'a' + 10;
+ } else if (c2 == EOF) {
+ eof = gTrue;
+ x = 0;
+ } else {
+ error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
+ }
+ buf = x & 0xff;
+ return buf;
+}
+
+GString *ASCIIHexStream::getPSFilter(char *indent) {
+ GString *s;
+
+ if (!(s = str->getPSFilter(indent))) {
+ return NULL;
+ }
+ s->append(indent)->append("/ASCIIHexDecode filter\n");
+ return s;
+}
+
+GBool ASCIIHexStream::isBinary(GBool last) {
+ return str->isBinary(gFalse);
+}
+
+//------------------------------------------------------------------------
+// ASCII85Stream
+//------------------------------------------------------------------------
+
+ASCII85Stream::ASCII85Stream(Stream *strA):
+ FilterStream(strA) {
+ index = n = 0;
+ eof = gFalse;
+}
+
+ASCII85Stream::~ASCII85Stream() {
+ delete str;
+}
+
+void ASCII85Stream::reset() {
+ str->reset();
+ index = n = 0;
+ eof = gFalse;
+}
+
+int ASCII85Stream::lookChar() {
+ int k;
+ Gulong t;
+
+ if (index >= n) {
+ if (eof)
+ return EOF;
+ index = 0;
+ do {
+ c[0] = str->getChar();
+ } while (c[0] == '\n' || c[0] == '\r');
+ if (c[0] == '~' || c[0] == EOF) {
+ eof = gTrue;
+ n = 0;
+ return EOF;
+ } else if (c[0] == 'z') {
+ b[0] = b[1] = b[2] = b[3] = 0;
+ n = 4;
+ } else {
+ for (k = 1; k < 5; ++k) {
+ do {
+ c[k] = str->getChar();
+ } while (c[k] == '\n' || c[k] == '\r');
+ if (c[k] == '~' || c[k] == EOF)
+ break;
+ }
+ n = k - 1;
+ if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
+ for (++k; k < 5; ++k)
+ c[k] = 0x21 + 84;
+ eof = gTrue;
+ }
+ t = 0;
+ for (k = 0; k < 5; ++k)
+ t = t * 85 + (c[k] - 0x21);
+ for (k = 3; k >= 0; --k) {
+ b[k] = (int)(t & 0xff);
+ t >>= 8;
+ }
+ }
+ }
+ return b[index];
+}
+
+GString *ASCII85Stream::getPSFilter(char *indent) {
+ GString *s;
+
+ if (!(s = str->getPSFilter(indent))) {
+ return NULL;
+ }
+ s->append(indent)->append("/ASCII85Decode filter\n");
+ return s;
+}
+
+GBool ASCII85Stream::isBinary(GBool last) {
+ return str->isBinary(gFalse);
+}
+
+//------------------------------------------------------------------------
+// LZWStream
+//------------------------------------------------------------------------
+
+LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors,
+ int bits, int earlyA):
+ FilterStream(strA) {
+ if (predictor != 1) {
+ pred = new StreamPredictor(this, predictor, columns, colors, bits);
+ } else {
+ pred = NULL;
+ }
+ early = earlyA;
+ zPipe = NULL;
+ bufPtr = bufEnd = buf;
+}
+
+LZWStream::~LZWStream() {
+ if (zPipe) {
+#ifdef HAVE_POPEN
+ pclose(zPipe);
+#else
+ fclose(zPipe);
+#endif
+ zPipe = NULL;
+ unlink(zName->getCString());
+ delete zName;
+ }
+ if (pred) {
+ delete pred;
+ }
+ delete str;
+}
+
+int LZWStream::getChar() {
+ if (pred) {
+ return pred->getChar();
+ }
+ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
+}
+
+int LZWStream::lookChar() {
+ if (pred) {
+ return pred->lookChar();
+ }
+ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff);
+}
+
+int LZWStream::getRawChar() {
+ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
+}
+
+void LZWStream::reset() {
+ FILE *f;
+ GString *zCmd;
+
+ //----- close old LZW stream
+ if (zPipe) {
+#ifdef HAVE_POPEN
+ pclose(zPipe);
+#else
+ fclose(zPipe);
+#endif
+ zPipe = NULL;
+ unlink(zName->getCString());
+ delete zName;
+ }
+
+ //----- tell Delorie runtime to spawn a new instance of COMMAND.COM
+ // to run gzip
+#if __DJGPP__
+ if (!setDJSYSFLAGS) {
+ setenv("DJSYSFLAGS", "0x0002", 0);
+ setDJSYSFLAGS = gTrue;
+ }
+#endif
+
+ //----- create the .Z file
+ if (!openTempFile(&zName, &f, "wb", ".Z")) {
+ error(getPos(), "Couldn't create temporary file for LZW stream");
+ return;
+ }
+ dumpFile(f);
+ fclose(f);
+
+ //----- execute uncompress / gzip
+ zCmd = new GString(uncompressCmd);
+ zCmd->append(' ');
+ zCmd->append(zName);
+#if defined(MACOS)
+ long magicCookie;
+ // first we open the engine up
+ OSErr err = OpenSITEngine(kUseExternalEngine, &magicCookie);
+ // if we found it - let's use it!
+ if (!err && magicCookie) {
+ // make sure we have the correct version of the Engine
+ if (GetSITEngineVersion(magicCookie) >= kFirstSupportedEngine) {
+ FSSpec myFSS;
+ Str255 pName;
+ strcpy((char *)pName, zName->getCString());
+ c2pstr((char *)pName);
+ FSMakeFSSpec(0, 0, pName, &myFSS);
+ short ftype = DetermineFileType(magicCookie, &myFSS);
+ OSErr expandErr = ExpandFSSpec(magicCookie, ftype, &myFSS,
+ NULL, NULL, kCreateFolderNever,
+ kDeleteOriginal, kTextConvertSmart);
+ }
+ }
+#elif defined(HAVE_POPEN)
+ if (!(zPipe = popen(zCmd->getCString(), POPEN_READ_MODE))) {
+ error(getPos(), "Couldn't popen '%s'", zCmd->getCString());
+ unlink(zName->getCString());
+ delete zName;
+ return;
+ }
+#else // HAVE_POPEN
+#ifdef VMS
+ if (!system(zCmd->getCString())) {
+#else
+ if (system(zCmd->getCString())) {
+#endif
+ error(getPos(), "Couldn't execute '%s'", zCmd->getCString());
+ unlink(zName->getCString());
+ delete zName;
+ return;
+ }
+ zName->del(zName->getLength() - 2, 2);
+ if (!(zPipe = fopen(zName->getCString(), "rb"))) {
+ error(getPos(), "Couldn't open uncompress file '%s'", zName->getCString());
+ unlink(zName->getCString());
+ delete zName;
+ return;
+ }
+#endif // HAVE_POPEN
+
+ //----- clean up
+ delete zCmd;
+
+ //----- initialize buffer
+ bufPtr = bufEnd = buf;
+}
+
+void LZWStream::dumpFile(FILE *f) {
+ int outCodeBits; // size of output code
+ int outBits; // max output code
+ int outBuf[8]; // output buffer
+ int outData; // temporary output buffer
+ int inCode, outCode; // input and output codes
+ int nextCode; // next code index
+ GBool eof; // set when EOF is reached
+ GBool clear; // set if table needs to be cleared
+ GBool first; // indicates first code word after clear
+ int i, j;
+
+ str->reset();
+
+ // magic number
+ fputc(0x1f, f);
+ fputc(0x9d, f);
+
+ // max code length, block mode flag
+ fputc(0x8c, f);
+
+ // init input side
+ inCodeBits = 9;
+ inputBuf = 0;
+ inputBits = 0;
+ eof = gFalse;
+
+ // init output side
+ outCodeBits = 9;
+
+ // clear table
+ first = gTrue;
+ nextCode = 258;
+
+ clear = gFalse;
+ do {
+ for (i = 0; i < 8; ++i) {
+ // check for table overflow
+ if (nextCode + early > 0x1001) {
+ inCode = 256;
+
+ // read input code
+ } else {
+ do {
+ inCode = getCode();
+ if (inCode == EOF) {
+ eof = gTrue;
+ inCode = 0;
+ }
+ } while (first && inCode == 256);
+ }
+
+ // compute output code
+ if (inCode < 256) {
+ outCode = inCode;
+ } else if (inCode == 256) {
+ outCode = 256;
+ clear = gTrue;
+ } else if (inCode == 257) {
+ outCode = 0;
+ eof = gTrue;
+ } else {
+ outCode = inCode - 1;
+ }
+ outBuf[i] = outCode;
+
+ // next code index
+ if (first)
+ first = gFalse;
+ else
+ ++nextCode;
+
+ // check input code size
+ if (nextCode + early == 0x200)
+ inCodeBits = 10;
+ else if (nextCode + early == 0x400) {
+ inCodeBits = 11;
+ } else if (nextCode + early == 0x800) {
+ inCodeBits = 12;
+ }
+
+ // check for eof/clear
+ if (eof)
+ break;
+ if (clear) {
+ i = 8;
+ break;
+ }
+ }
+
+ // write output block
+ outData = 0;
+ outBits = 0;
+ j = 0;
+ while (j < i || outBits > 0) {
+ if (outBits < 8 && j < i) {
+ outData = outData | (outBuf[j++] << outBits);
+ outBits += outCodeBits;
+ }
+ fputc(outData & 0xff, f);
+ outData >>= 8;
+ outBits -= 8;
+ }
+
+ // check output code size
+ if (nextCode - 1 == 512 ||
+ nextCode - 1 == 1024 ||
+ nextCode - 1 == 2048 ||
+ nextCode - 1 == 4096) {
+ outCodeBits = inCodeBits;
+ }
+
+ // clear table if necessary
+ if (clear) {
+ inCodeBits = 9;
+ outCodeBits = 9;
+ first = gTrue;
+ nextCode = 258;
+ clear = gFalse;
+ }
+ } while (!eof);
+}
+
+int LZWStream::getCode() {
+ int c;
+ int code;
+
+ while (inputBits < inCodeBits) {
+ if ((c = str->getChar()) == EOF)
+ return EOF;
+ inputBuf = (inputBuf << 8) | (c & 0xff);
+ inputBits += 8;
+ }
+ code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1);
+ inputBits -= inCodeBits;
+ return code;
+}
+
+GBool LZWStream::fillBuf() {
+ int n;
+
+ if (!zPipe)
+ return gFalse;
+ if ((n = fread(buf, 1, 256, zPipe)) < 256) {
+#ifdef HAVE_POPEN
+ pclose(zPipe);
+#else
+ fclose(zPipe);
+#endif
+ zPipe = NULL;
+ unlink(zName->getCString());
+ delete zName;
+ }
+ bufPtr = buf;
+ bufEnd = buf + n;
+ return n > 0;
+}
+
+GString *LZWStream::getPSFilter(char *indent) {
+ GString *s;
+
+ if (pred) {
+ return NULL;
+ }
+ if (!(s = str->getPSFilter(indent))) {
+ return NULL;
+ }
+ s->append(indent)->append("/LZWDecode filter\n");
+ return s;
+}
+
+GBool LZWStream::isBinary(GBool last) {
+ return str->isBinary(gTrue);
+}
+
+//------------------------------------------------------------------------
+// RunLengthStream
+//------------------------------------------------------------------------
+
+RunLengthStream::RunLengthStream(Stream *strA):
+ FilterStream(strA) {
+ bufPtr = bufEnd = buf;
+ eof = gFalse;
+}
+
+RunLengthStream::~RunLengthStream() {
+ delete str;
+}
+
+void RunLengthStream::reset() {
+ str->reset();
+ bufPtr = bufEnd = buf;
+ eof = gFalse;
+}
+
+GString *RunLengthStream::getPSFilter(char *indent) {
+ GString *s;
+
+ if (!(s = str->getPSFilter(indent))) {
+ return NULL;
+ }
+ s->append(indent)->append("/RunLengthDecode filter\n");
+ return s;
+}
+
+GBool RunLengthStream::isBinary(GBool last) {
+ return str->isBinary(gTrue);
+}
+
+GBool RunLengthStream::fillBuf() {
+ int c;
+ int n, i;
+
+ if (eof)
+ return gFalse;
+ c = str->getChar();
+ if (c == 0x80 || c == EOF) {
+ eof = gTrue;
+ return gFalse;
+ }
+ if (c < 0x80) {
+ n = c + 1;
+ for (i = 0; i < n; ++i)
+ buf[i] = (char)str->getChar();
+ } else {
+ n = 0x101 - c;
+ c = str->getChar();
+ for (i = 0; i < n; ++i)
+ buf[i] = (char)c;
+ }
+ bufPtr = buf;
+ bufEnd = buf + n;
+ return gTrue;
+}
+
+//------------------------------------------------------------------------
+// CCITTFaxStream
+//------------------------------------------------------------------------
+
+CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
+ GBool byteAlignA, int columnsA, int rowsA,
+ GBool endOfBlockA, GBool blackA):
+ FilterStream(strA) {
+ encoding = encodingA;
+ endOfLine = endOfLineA;
+ byteAlign = byteAlignA;
+ columns = columnsA;
+ rows = rowsA;
+ endOfBlock = endOfBlockA;
+ black = blackA;
+ refLine = (short *)gmalloc((columns + 3) * sizeof(short));
+ codingLine = (short *)gmalloc((columns + 2) * sizeof(short));
+
+ eof = gFalse;
+ row = 0;
+ nextLine2D = encoding < 0;
+ inputBits = 0;
+ codingLine[0] = 0;
+ codingLine[1] = refLine[2] = columns;
+ a0 = 1;
+
+ buf = EOF;
+}
+
+CCITTFaxStream::~CCITTFaxStream() {
+ delete str;
+ gfree(refLine);
+ gfree(codingLine);
+}
+
+void CCITTFaxStream::reset() {
+ int n;
+
+ str->reset();
+ eof = gFalse;
+ row = 0;
+ nextLine2D = encoding < 0;
+ inputBits = 0;
+ codingLine[0] = 0;
+ codingLine[1] = refLine[2] = columns;
+ a0 = 1;
+ buf = EOF;
+
+ // get initial end-of-line marker and 2D encoding tag
+ if (endOfBlock) {
+ if (lookBits(12) == 0x001) {
+ eatBits(12);
+ }
+ } else {
+ for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
+ if (n == 11 && lookBits(12) == 0x001) {
+ eatBits(12);
+ }
+ }
+ if (encoding > 0) {
+ nextLine2D = !lookBits(1);
+ eatBits(1);
+ }
+}
+
+int CCITTFaxStream::lookChar() {
+ short code1, code2, code3;
+ int a0New;
+#if 0 //~
+ GBool err;
+#endif
+ GBool gotEOL;
+ int ret;
+ int bits, i;
+
+ // if at eof just return EOF
+ if (eof && codingLine[a0] >= columns) {
+ return EOF;
+ }
+
+ // read the next row
+#if 0 //~
+ err = gFalse;
+#endif
+ if (codingLine[a0] >= columns) {
+
+ // 2-D encoding
+ if (nextLine2D) {
+ for (i = 0; codingLine[i] < columns; ++i)
+ refLine[i] = codingLine[i];
+ refLine[i] = refLine[i + 1] = columns;
+ b1 = 1;
+ a0New = codingLine[a0 = 0] = 0;
+ do {
+ code1 = getTwoDimCode();
+ switch (code1) {
+ case twoDimPass:
+ if (refLine[b1] < columns) {
+ a0New = refLine[b1 + 1];
+ b1 += 2;
+ }
+ break;
+ case twoDimHoriz:
+ if ((a0 & 1) == 0) {
+ code1 = code2 = 0;
+ do {
+ code1 += code3 = getWhiteCode();
+ } while (code3 >= 64);
+ do {
+ code2 += code3 = getBlackCode();
+ } while (code3 >= 64);
+ } else {
+ code1 = code2 = 0;
+ do {
+ code1 += code3 = getBlackCode();
+ } while (code3 >= 64);
+ do {
+ code2 += code3 = getWhiteCode();
+ } while (code3 >= 64);
+ }
+ codingLine[a0 + 1] = a0New + code1;
+ ++a0;
+ a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
+ ++a0;
+ while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ b1 += 2;
+ break;
+ case twoDimVert0:
+ a0New = codingLine[++a0] = refLine[b1];
+ if (refLine[b1] < columns) {
+ ++b1;
+ while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ b1 += 2;
+ }
+ break;
+ case twoDimVertR1:
+ a0New = codingLine[++a0] = refLine[b1] + 1;
+ if (refLine[b1] < columns) {
+ ++b1;
+ while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ b1 += 2;
+ }
+ break;
+ case twoDimVertL1:
+ a0New = codingLine[++a0] = refLine[b1] - 1;
+ --b1;
+ while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ b1 += 2;
+ break;
+ case twoDimVertR2:
+ a0New = codingLine[++a0] = refLine[b1] + 2;
+ if (refLine[b1] < columns) {
+ ++b1;
+ while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ b1 += 2;
+ }
+ break;
+ case twoDimVertL2:
+ a0New = codingLine[++a0] = refLine[b1] - 2;
+ --b1;
+ while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ b1 += 2;
+ break;
+ case twoDimVertR3:
+ a0New = codingLine[++a0] = refLine[b1] + 3;
+ if (refLine[b1] < columns) {
+ ++b1;
+ while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ b1 += 2;
+ }
+ break;
+ case twoDimVertL3:
+ a0New = codingLine[++a0] = refLine[b1] - 3;
+ --b1;
+ while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
+ b1 += 2;
+ break;
+ case EOF:
+ eof = gTrue;
+ codingLine[a0 = 0] = columns;
+ return EOF;
+ default:
+ error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
+#if 0 //~
+ err = gTrue;
+ break;
+#else
+ eof = gTrue;
+ return EOF;
+#endif
+ }
+ } while (codingLine[a0] < columns);
+
+ // 1-D encoding
+ } else {
+ codingLine[a0 = 0] = 0;
+ while (1) {
+ code1 = 0;
+ do {
+ code1 += code3 = getWhiteCode();
+ } while (code3 >= 64);
+ codingLine[a0+1] = codingLine[a0] + code1;
+ ++a0;
+ if (codingLine[a0] >= columns)
+ break;
+ code2 = 0;
+ do {
+ code2 += code3 = getBlackCode();
+ } while (code3 >= 64);
+ codingLine[a0+1] = codingLine[a0] + code2;
+ ++a0;
+ if (codingLine[a0] >= columns)
+ break;
+ }
+ }
+
+ if (codingLine[a0] != columns) {
+ error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
+#if 0 //~
+ err = gTrue;
+#endif
+ }
+
+ // byte-align the row
+ if (byteAlign) {
+ inputBits &= ~7;
+ }
+
+ // check for end-of-line marker, skipping over any extra zero bits
+ gotEOL = gFalse;
+ if (!endOfBlock && row == rows - 1) {
+ eof = gTrue;
+ } else {
+ code1 = lookBits(12);
+ while (code1 == 0) {
+ eatBits(1);
+ code1 = lookBits(12);
+ }
+ if (code1 == 0x001) {
+ eatBits(12);
+ gotEOL = gTrue;
+ } else if (code1 == EOF) {
+ eof = gTrue;
+ }
+ }
+
+ // get 2D encoding tag
+ if (!eof && encoding > 0) {
+ nextLine2D = !lookBits(1);
+ eatBits(1);
+ }
+
+ // check for end-of-block marker
+ if (endOfBlock && gotEOL) {
+ code1 = lookBits(12);
+ if (code1 == 0x001) {
+ eatBits(12);
+ if (encoding > 0) {
+ lookBits(1);
+ eatBits(1);
+ }
+ if (encoding >= 0) {
+ for (i = 0; i < 4; ++i) {
+ code1 = lookBits(12);
+ if (code1 != 0x001) {
+ error(getPos(), "Bad RTC code in CCITTFax stream");
+ }
+ eatBits(12);
+ if (encoding > 0) {
+ lookBits(1);
+ eatBits(1);
+ }
+ }
+ }
+ eof = gTrue;
+ }
+ }
+
+#if 0 //~
+ // This looks for an end-of-line marker after an error, however
+ // some (most?) CCITT streams in PDF files don't use end-of-line
+ // markers, and the just-plow-on technique works better in those
+ // cases.
+ else if (err) {
+ do {
+ if (code1 == EOF) {
+ eof = gTrue;
+ return EOF;
+ }
+ eatBits(1);
+ code1 = look13Bits();
+ } while ((code1 >> 1) != 0x001);
+ eatBits(12);
+ codingLine[++a0] = columns;
+ if (encoding > 0) {
+ eatBits(1);
+ nextLine2D = !(code1 & 1);
+ }
+ }
+#endif
+
+ a0 = 0;
+ outputBits = codingLine[1] - codingLine[0];
+ if (outputBits == 0) {
+ a0 = 1;
+ outputBits = codingLine[2] - codingLine[1];
+ }
+
+ ++row;
+ }
+
+ // get a byte
+ if (outputBits >= 8) {
+ ret = ((a0 & 1) == 0) ? 0xff : 0x00;
+ if ((outputBits -= 8) == 0) {
+ ++a0;
+ if (codingLine[a0] < columns) {
+ outputBits = codingLine[a0 + 1] - codingLine[a0];
+ }
+ }
+ } else {
+ bits = 8;
+ ret = 0;
+ do {
+ if (outputBits > bits) {
+ i = bits;
+ bits = 0;
+ if ((a0 & 1) == 0) {
+ ret |= 0xff >> (8 - i);
+ }
+ outputBits -= i;
+ } else {
+ i = outputBits;
+ bits -= outputBits;
+ if ((a0 & 1) == 0) {
+ ret |= (0xff >> (8 - i)) << bits;
+ }
+ outputBits = 0;
+ ++a0;
+ if (codingLine[a0] < columns) {
+ outputBits = codingLine[a0 + 1] - codingLine[a0];
+ }
+ }
+ } while (bits > 0 && codingLine[a0] < columns);
+ }
+ buf = black ? (ret ^ 0xff) : ret;
+ return buf;
+}
+
+short CCITTFaxStream::getTwoDimCode() {
+ short code;
+ CCITTCode *p;
+ int n;
+
+ code = 0; // make gcc happy
+ if (endOfBlock) {
+ code = lookBits(7);
+ p = &twoDimTab1[code];
+ if (p->bits > 0) {
+ eatBits(p->bits);
+ return p->n;
+ }
+ } else {
+ for (n = 1; n <= 7; ++n) {
+ code = lookBits(n);
+ if (n < 7) {
+ code <<= 7 - n;
+ }
+ p = &twoDimTab1[code];
+ if (p->bits == n) {
+ eatBits(n);
+ return p->n;
+ }
+ }
+ }
+ error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code);
+ return EOF;
+}
+
+short CCITTFaxStream::getWhiteCode() {
+ short code;
+ CCITTCode *p;
+ int n;
+
+ code = 0; // make gcc happy
+ if (endOfBlock) {
+ code = lookBits(12);
+ if ((code >> 5) == 0) {
+ p = &whiteTab1[code];
+ } else {
+ p = &whiteTab2[code >> 3];
+ }
+ if (p->bits > 0) {
+ eatBits(p->bits);
+ return p->n;
+ }
+ } else {
+ for (n = 1; n <= 9; ++n) {
+ code = lookBits(n);
+ if (n < 9) {
+ code <<= 9 - n;
+ }
+ p = &whiteTab2[code];
+ if (p->bits == n) {
+ eatBits(n);
+ return p->n;
+ }
+ }
+ for (n = 11; n <= 12; ++n) {
+ code = lookBits(n);
+ if (n < 12) {
+ code <<= 12 - n;
+ }
+ p = &whiteTab1[code];
+ if (p->bits == n) {
+ eatBits(n);
+ return p->n;
+ }
+ }
+ }
+ error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
+ // eat a bit and return a positive number so that the caller doesn't
+ // go into an infinite loop
+ eatBits(1);
+ return 1;
+}
+
+short CCITTFaxStream::getBlackCode() {
+ short code;
+ CCITTCode *p;
+ int n;
+
+ code = 0; // make gcc happy
+ if (endOfBlock) {
+ code = lookBits(13);
+ if ((code >> 7) == 0) {
+ p = &blackTab1[code];
+ } else if ((code >> 9) == 0) {
+ p = &blackTab2[(code >> 1) - 64];
+ } else {
+ p = &blackTab3[code >> 7];
+ }
+ if (p->bits > 0) {
+ eatBits(p->bits);
+ return p->n;
+ }
+ } else {
+ for (n = 2; n <= 6; ++n) {
+ code = lookBits(n);
+ if (n < 6) {
+ code <<= 6 - n;
+ }
+ p = &blackTab3[code];
+ if (p->bits == n) {
+ eatBits(n);
+ return p->n;
+ }
+ }
+ for (n = 7; n <= 12; ++n) {
+ code = lookBits(n);
+ if (n < 12) {
+ code <<= 12 - n;
+ }
+ if (code >= 64) {
+ p = &blackTab2[code - 64];
+ if (p->bits == n) {
+ eatBits(n);
+ return p->n;
+ }
+ }
+ }
+ for (n = 10; n <= 13; ++n) {
+ code = lookBits(n);
+ if (n < 13) {
+ code <<= 13 - n;
+ }
+ p = &blackTab1[code];
+ if (p->bits == n) {
+ eatBits(n);
+ return p->n;
+ }
+ }
+ }
+ error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
+ // eat a bit and return a positive number so that the caller doesn't
+ // go into an infinite loop
+ eatBits(1);
+ return 1;
+}
+
+short CCITTFaxStream::lookBits(int n) {
+ int c;
+
+ while (inputBits < n) {
+ if ((c = str->getChar()) == EOF) {
+ if (inputBits == 0) {
+ return EOF;
+ }
+ // near the end of the stream, the caller may ask for more bits
+ // than are available, but there may still be a valid code in
+ // however many bits are available -- we need to return correct
+ // data in this case
+ return (inputBuf << (n - inputBits)) & (0xffff >> (16 - n));
+ }
+ inputBuf = (inputBuf << 8) + c;
+ inputBits += 8;
+ }
+ return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n));
+}
+
+GString *CCITTFaxStream::getPSFilter(char *indent) {
+ GString *s;
+ char s1[50];
+
+ if (!(s = str->getPSFilter(indent))) {
+ return NULL;
+ }
+ s->append(indent)->append("<< ");
+ if (encoding != 0) {
+ sprintf(s1, "/K %d ", encoding);
+ s->append(s1);
+ }
+ if (endOfLine) {
+ s->append("/EndOfLine true ");
+ }
+ if (byteAlign) {
+ s->append("/EncodedByteAlign true ");
+ }
+ sprintf(s1, "/Columns %d ", columns);
+ s->append(s1);
+ if (rows != 0) {
+ sprintf(s1, "/Rows %d ", rows);
+ s->append(s1);
+ }
+ if (!endOfBlock) {
+ s->append("/EndOfBlock false ");
+ }
+ if (black) {
+ s->append("/BlackIs1 true ");
+ }
+ s->append(">> /CCITTFaxDecode filter\n");
+ return s;
+}
+
+GBool CCITTFaxStream::isBinary(GBool last) {
+ return str->isBinary(gTrue);
+}
+
+//------------------------------------------------------------------------
+// DCTStream
+//------------------------------------------------------------------------
+
+// IDCT constants (20.12 fixed point format)
+#ifndef FP_IDCT
+#define dctCos1 4017 // cos(pi/16)
+#define dctSin1 799 // sin(pi/16)
+#define dctCos3 3406 // cos(3*pi/16)
+#define dctSin3 2276 // sin(3*pi/16)
+#define dctCos6 1567 // cos(6*pi/16)
+#define dctSin6 3784 // sin(6*pi/16)
+#define dctSqrt2 5793 // sqrt(2)
+#define dctSqrt1d2 2896 // sqrt(2) / 2
+#endif
+
+// IDCT constants
+#ifdef FP_IDCT
+#define dctCos1 0.98078528 // cos(pi/16)
+#define dctSin1 0.19509032 // sin(pi/16)
+#define dctCos3 0.83146961 // cos(3*pi/16)
+#define dctSin3 0.55557023 // sin(3*pi/16)
+#define dctCos6 0.38268343 // cos(6*pi/16)
+#define dctSin6 0.92387953 // sin(6*pi/16)
+#define dctSqrt2 1.41421356 // sqrt(2)
+#define dctSqrt1d2 0.70710678 // sqrt(2) / 2
+#endif
+
+// color conversion parameters (16.16 fixed point format)
+#define dctCrToR 91881 // 1.4020
+#define dctCbToG -22553 // -0.3441363
+#define dctCrToG -46802 // -0.71413636
+#define dctCbToB 116130 // 1.772
+
+// clip [-256,511] --> [0,255]
+#define dctClipOffset 256
+static Guchar dctClip[768];
+static int dctClipInit = 0;
+
+// zig zag decode map
+static int dctZigZag[64] = {
+ 0,
+ 1, 8,
+ 16, 9, 2,
+ 3, 10, 17, 24,
+ 32, 25, 18, 11, 4,
+ 5, 12, 19, 26, 33, 40,
+ 48, 41, 34, 27, 20, 13, 6,
+ 7, 14, 21, 28, 35, 42, 49, 56,
+ 57, 50, 43, 36, 29, 22, 15,
+ 23, 30, 37, 44, 51, 58,
+ 59, 52, 45, 38, 31,
+ 39, 46, 53, 60,
+ 61, 54, 47,
+ 55, 62,
+ 63
+};
+
+DCTStream::DCTStream(Stream *strA):
+ FilterStream(strA) {
+ int i, j;
+
+ width = height = 0;
+ mcuWidth = mcuHeight = 0;
+ numComps = 0;
+ comp = 0;
+ x = y = dy = 0;
+ for (i = 0; i < 4; ++i)
+ for (j = 0; j < 32; ++j)
+ rowBuf[i][j] = NULL;
+
+ if (!dctClipInit) {
+ for (i = -256; i < 0; ++i)
+ dctClip[dctClipOffset + i] = 0;
+ for (i = 0; i < 256; ++i)
+ dctClip[dctClipOffset + i] = i;
+ for (i = 256; i < 512; ++i)
+ dctClip[dctClipOffset + i] = 255;
+ dctClipInit = 1;
+ }
+}
+
+DCTStream::~DCTStream() {
+ int i, j;
+
+ delete str;
+ for (i = 0; i < numComps; ++i)
+ for (j = 0; j < mcuHeight; ++j)
+ gfree(rowBuf[i][j]);
+}
+
+void DCTStream::reset() {
+ str->reset();
+ if (!readHeader()) {
+ y = height;
+ return;
+ }
+ restartMarker = 0xd0;
+ restart();
+}
+
+int DCTStream::getChar() {
+ int c;
+
+ c = lookChar();
+ if (c == EOF)
+ return EOF;
+ if (++comp == numComps) {
+ comp = 0;
+ if (++x == width) {
+ x = 0;
+ ++y;
+ ++dy;
+ }
+ }
+ if (y == height)
+ readTrailer();
+ return c;
+}
+
+int DCTStream::lookChar() {
+ if (y >= height)
+ return EOF;
+ if (dy >= mcuHeight) {
+ if (!readMCURow()) {
+ y = height;
+ return EOF;
+ }
+ comp = 0;
+ x = 0;
+ dy = 0;
+ }
+ return rowBuf[comp][dy][x];
+}
+
+void DCTStream::restart() {
+ int i;
+
+ inputBits = 0;
+ restartCtr = restartInterval;
+ for (i = 0; i < numComps; ++i)
+ compInfo[i].prevDC = 0;
+}
+
+GBool DCTStream::readMCURow() {
+ Guchar data[64];
+ Guchar *p1, *p2;
+ int pY, pCb, pCr, pR, pG, pB;
+ int h, v, horiz, vert, hSub, vSub;
+ int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
+ int c;
+
+ for (x1 = 0; x1 < width; x1 += mcuWidth) {
+
+ // deal with restart marker
+ if (restartInterval > 0 && restartCtr == 0) {
+ c = readMarker();
+ if (c != restartMarker) {
+ error(getPos(), "Bad DCT data: incorrect restart marker");
+ return gFalse;
+ }
+ if (++restartMarker == 0xd8)
+ restartMarker = 0xd0;
+ restart();
+ }
+
+ // read one MCU
+ for (cc = 0; cc < numComps; ++cc) {
+ h = compInfo[cc].hSample;
+ v = compInfo[cc].vSample;
+ horiz = mcuWidth / h;
+ vert = mcuHeight / v;
+ hSub = horiz / 8;
+ vSub = vert / 8;
+ for (y2 = 0; y2 < mcuHeight; y2 += vert) {
+ for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
+ if (!readDataUnit(&dcHuffTables[compInfo[cc].dcHuffTable],
+ &acHuffTables[compInfo[cc].acHuffTable],
+ quantTables[compInfo[cc].quantTable],
+ &compInfo[cc].prevDC,
+ data))
+ return gFalse;
+ if (hSub == 1 && vSub == 1) {
+ for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
+ p1 = &rowBuf[cc][y2+y3][x1+x2];
+ p1[0] = data[i];
+ p1[1] = data[i+1];
+ p1[2] = data[i+2];
+ p1[3] = data[i+3];
+ p1[4] = data[i+4];
+ p1[5] = data[i+5];
+ p1[6] = data[i+6];
+ p1[7] = data[i+7];
+ }
+ } else if (hSub == 2 && vSub == 2) {
+ for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
+ p1 = &rowBuf[cc][y2+y3][x1+x2];
+ p2 = &rowBuf[cc][y2+y3+1][x1+x2];
+ p1[0] = p1[1] = p2[0] = p2[1] = data[i];
+ p1[2] = p1[3] = p2[2] = p2[3] = data[i+1];
+ p1[4] = p1[5] = p2[4] = p2[5] = data[i+2];
+ p1[6] = p1[7] = p2[6] = p2[7] = data[i+3];
+ p1[8] = p1[9] = p2[8] = p2[9] = data[i+4];
+ p1[10] = p1[11] = p2[10] = p2[11] = data[i+5];
+ p1[12] = p1[13] = p2[12] = p2[13] = data[i+6];
+ p1[14] = p1[15] = p2[14] = p2[15] = data[i+7];
+ }
+ } else {
+ i = 0;
+ for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
+ for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
+ for (y5 = 0; y5 < vSub; ++y5)
+ for (x5 = 0; x5 < hSub; ++x5)
+ rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data[i];
+ ++i;
+ }
+ }
+ }
+ }
+ }
+ }
+ --restartCtr;
+
+ // color space conversion
+ if (colorXform) {
+ // convert YCbCr to RGB
+ if (numComps == 3) {
+ for (y2 = 0; y2 < mcuHeight; ++y2) {
+ for (x2 = 0; x2 < mcuWidth; ++x2) {
+ pY = rowBuf[0][y2][x1+x2];
+ pCb = rowBuf[1][y2][x1+x2] - 128;
+ pCr = rowBuf[2][y2][x1+x2] - 128;
+ pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
+ rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
+ pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
+ rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
+ pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
+ rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
+ }
+ }
+ // convert YCbCrK to CMYK (K is passed through unchanged)
+ } else if (numComps == 4) {
+ for (y2 = 0; y2 < mcuHeight; ++y2) {
+ for (x2 = 0; x2 < mcuWidth; ++x2) {
+ pY = rowBuf[0][y2][x1+x2];
+ pCb = rowBuf[1][y2][x1+x2] - 128;
+ pCr = rowBuf[2][y2][x1+x2] - 128;
+ pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
+ rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR];
+ pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32678) >> 16;
+ rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG];
+ pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
+ rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB];
+ }
+ }
+ }
+ }
+ }
+ return gTrue;
+}
+
+// This IDCT algorithm is taken from:
+// Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
+// "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
+// IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
+// 988-991.
+// The stage numbers mentioned in the comments refer to Figure 1 in this
+// paper.
+#ifndef FP_IDCT
+GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
+ DCTHuffTable *acHuffTable,
+ Guchar quantTable[64], int *prevDC,
+ Guchar data[64]) {
+ int tmp1[64];
+ int v0, v1, v2, v3, v4, v5, v6, v7, t;
+ int run, size, amp;
+ int c;
+ int i, j;
+
+ // Huffman decode and dequantize
+ size = readHuffSym(dcHuffTable);
+ if (size == 9999)
+ return gFalse;
+ if (size > 0) {
+ amp = readAmp(size);
+ if (amp == 9999)
+ return gFalse;
+ } else {
+ amp = 0;
+ }
+ tmp1[0] = (*prevDC += amp) * quantTable[0];
+ for (i = 1; i < 64; ++i)
+ tmp1[i] = 0;
+ i = 1;
+ while (i < 64) {
+ run = 0;
+ while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
+ run += 0x10;
+ if (c == 9999)
+ return gFalse;
+ if (c == 0x00) {
+ break;
+ } else {
+ run += (c >> 4) & 0x0f;
+ size = c & 0x0f;
+ amp = readAmp(size);
+ if (amp == 9999)
+ return gFalse;
+ i += run;
+ j = dctZigZag[i++];
+ tmp1[j] = amp * quantTable[j];
+ }
+ }
+
+ // inverse DCT on rows
+ for (i = 0; i < 64; i += 8) {
+
+ // stage 4
+ v0 = (dctSqrt2 * tmp1[i+0] + 128) >> 8;
+ v1 = (dctSqrt2 * tmp1[i+4] + 128) >> 8;
+ v2 = tmp1[i+2];
+ v3 = tmp1[i+6];
+ v4 = (dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]) + 128) >> 8;
+ v7 = (dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]) + 128) >> 8;
+ v5 = tmp1[i+3] << 4;
+ v6 = tmp1[i+5] << 4;
+
+ // stage 3
+ t = (v0 - v1+ 1) >> 1;
+ v0 = (v0 + v1 + 1) >> 1;
+ v1 = t;
+ t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
+ v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
+ v3 = t;
+ t = (v4 - v6 + 1) >> 1;
+ v4 = (v4 + v6 + 1) >> 1;
+ v6 = t;
+ t = (v7 + v5 + 1) >> 1;
+ v5 = (v7 - v5 + 1) >> 1;
+ v7 = t;
+
+ // stage 2
+ t = (v0 - v3 + 1) >> 1;
+ v0 = (v0 + v3 + 1) >> 1;
+ v3 = t;
+ t = (v1 - v2 + 1) >> 1;
+ v1 = (v1 + v2 + 1) >> 1;
+ v2 = t;
+ t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
+ v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
+ v7 = t;
+ t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
+ v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
+ v6 = t;
+
+ // stage 1
+ tmp1[i+0] = v0 + v7;
+ tmp1[i+7] = v0 - v7;
+ tmp1[i+1] = v1 + v6;
+ tmp1[i+6] = v1 - v6;
+ tmp1[i+2] = v2 + v5;
+ tmp1[i+5] = v2 - v5;
+ tmp1[i+3] = v3 + v4;
+ tmp1[i+4] = v3 - v4;
+ }
+
+ // inverse DCT on columns
+ for (i = 0; i < 8; ++i) {
+
+ // stage 4
+ v0 = (dctSqrt2 * tmp1[0*8+i] + 2048) >> 12;
+ v1 = (dctSqrt2 * tmp1[4*8+i] + 2048) >> 12;
+ v2 = tmp1[2*8+i];
+ v3 = tmp1[6*8+i];
+ v4 = (dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]) + 2048) >> 12;
+ v7 = (dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]) + 2048) >> 12;
+ v5 = tmp1[3*8+i];
+ v6 = tmp1[5*8+i];
+
+ // stage 3
+ t = (v0 - v1 + 1) >> 1;
+ v0 = (v0 + v1 + 1) >> 1;
+ v1 = t;
+ t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
+ v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
+ v3 = t;
+ t = (v4 - v6 + 1) >> 1;
+ v4 = (v4 + v6 + 1) >> 1;
+ v6 = t;
+ t = (v7 + v5 + 1) >> 1;
+ v5 = (v7 - v5 + 1) >> 1;
+ v7 = t;
+
+ // stage 2
+ t = (v0 - v3 + 1) >> 1;
+ v0 = (v0 + v3 + 1) >> 1;
+ v3 = t;
+ t = (v1 - v2 + 1) >> 1;
+ v1 = (v1 + v2 + 1) >> 1;
+ v2 = t;
+ t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
+ v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
+ v7 = t;
+ t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
+ v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
+ v6 = t;
+
+ // stage 1
+ tmp1[0*8+i] = v0 + v7;
+ tmp1[7*8+i] = v0 - v7;
+ tmp1[1*8+i] = v1 + v6;
+ tmp1[6*8+i] = v1 - v6;
+ tmp1[2*8+i] = v2 + v5;
+ tmp1[5*8+i] = v2 - v5;
+ tmp1[3*8+i] = v3 + v4;
+ tmp1[4*8+i] = v3 - v4;
+ }
+
+ // convert to 8-bit integers
+ for (i = 0; i < 64; ++i)
+ data[i] = dctClip[dctClipOffset + 128 + ((tmp1[i] + 8) >> 4)];
+
+ return gTrue;
+}
+#endif
+
+#ifdef FP_IDCT
+GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
+ DCTHuffTable *acHuffTable,
+ Guchar quantTable[64], int *prevDC,
+ Guchar data[64]) {
+ double tmp1[64];
+ double v0, v1, v2, v3, v4, v5, v6, v7, t;
+ int run, size, amp;
+ int c;
+ int i, j;
+
+ // Huffman decode and dequantize
+ size = readHuffSym(dcHuffTable);
+ if (size == 9999)
+ return gFalse;
+ if (size > 0) {
+ amp = readAmp(size);
+ if (amp == 9999)
+ return gFalse;
+ } else {
+ amp = 0;
+ }
+ tmp1[0] = (*prevDC += amp) * quantTable[0];
+ for (i = 1; i < 64; ++i)
+ tmp1[i] = 0;
+ i = 1;
+ while (i < 64) {
+ run = 0;
+ while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
+ run += 0x10;
+ if (c == 9999)
+ return gFalse;
+ if (c == 0x00) {
+ break;
+ } else {
+ run += (c >> 4) & 0x0f;
+ size = c & 0x0f;
+ amp = readAmp(size);
+ if (amp == 9999)
+ return gFalse;
+ i += run;
+ j = dctZigZag[i++];
+ tmp1[j] = amp * quantTable[j];
+ }
+ }
+
+ // inverse DCT on rows
+ for (i = 0; i < 64; i += 8) {
+
+ // stage 4
+ v0 = dctSqrt2 * tmp1[i+0];
+ v1 = dctSqrt2 * tmp1[i+4];
+ v2 = tmp1[i+2];
+ v3 = tmp1[i+6];
+ v4 = dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]);
+ v7 = dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]);
+ v5 = tmp1[i+3];
+ v6 = tmp1[i+5];
+
+ // stage 3
+ t = 0.5 * (v0 - v1);
+ v0 = 0.5 * (v0 + v1);
+ v1 = t;
+ t = v2 * dctSin6 + v3 * dctCos6;
+ v2 = v2 * dctCos6 - v3 * dctSin6;
+ v3 = t;
+ t = 0.5 * (v4 - v6);
+ v4 = 0.5 * (v4 + v6);
+ v6 = t;
+ t = 0.5 * (v7 + v5);
+ v5 = 0.5 * (v7 - v5);
+ v7 = t;
+
+ // stage 2
+ t = 0.5 * (v0 - v3);
+ v0 = 0.5 * (v0 + v3);
+ v3 = t;
+ t = 0.5 * (v1 - v2);
+ v1 = 0.5 * (v1 + v2);
+ v2 = t;
+ t = v4 * dctSin3 + v7 * dctCos3;
+ v4 = v4 * dctCos3 - v7 * dctSin3;
+ v7 = t;
+ t = v5 * dctSin1 + v6 * dctCos1;
+ v5 = v5 * dctCos1 - v6 * dctSin1;
+ v6 = t;
+
+ // stage 1
+ tmp1[i+0] = v0 + v7;
+ tmp1[i+7] = v0 - v7;
+ tmp1[i+1] = v1 + v6;
+ tmp1[i+6] = v1 - v6;
+ tmp1[i+2] = v2 + v5;
+ tmp1[i+5] = v2 - v5;
+ tmp1[i+3] = v3 + v4;
+ tmp1[i+4] = v3 - v4;
+ }
+
+ // inverse DCT on columns
+ for (i = 0; i < 8; ++i) {
+
+ // stage 4
+ v0 = dctSqrt2 * tmp1[0*8+i];
+ v1 = dctSqrt2 * tmp1[4*8+i];
+ v2 = tmp1[2*8+i];
+ v3 = tmp1[6*8+i];
+ v4 = dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]);
+ v7 = dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]);
+ v5 = tmp1[3*8+i];
+ v6 = tmp1[5*8+i];
+
+ // stage 3
+ t = 0.5 * (v0 - v1);
+ v0 = 0.5 * (v0 + v1);
+ v1 = t;
+ t = v2 * dctSin6 + v3 * dctCos6;
+ v2 = v2 * dctCos6 - v3 * dctSin6;
+ v3 = t;
+ t = 0.5 * (v4 - v6);
+ v4 = 0.5 * (v4 + v6);
+ v6 = t;
+ t = 0.5 * (v7 + v5);
+ v5 = 0.5 * (v7 - v5);
+ v7 = t;
+
+ // stage 2
+ t = 0.5 * (v0 - v3);
+ v0 = 0.5 * (v0 + v3);
+ v3 = t;
+ t = 0.5 * (v1 - v2);
+ v1 = 0.5 * (v1 + v2);
+ v2 = t;
+ t = v4 * dctSin3 + v7 * dctCos3;
+ v4 = v4 * dctCos3 - v7 * dctSin3;
+ v7 = t;
+ t = v5 * dctSin1 + v6 * dctCos1;
+ v5 = v5 * dctCos1 - v6 * dctSin1;
+ v6 = t;
+
+ // stage 1
+ tmp1[0*8+i] = v0 + v7;
+ tmp1[7*8+i] = v0 - v7;
+ tmp1[1*8+i] = v1 + v6;
+ tmp1[6*8+i] = v1 - v6;
+ tmp1[2*8+i] = v2 + v5;
+ tmp1[5*8+i] = v2 - v5;
+ tmp1[3*8+i] = v3 + v4;
+ tmp1[4*8+i] = v3 - v4;
+ }
+
+ // convert to 8-bit integers
+ for (i = 0; i < 64; ++i)
+ data[i] = dctClip[dctClipOffset + (int)(tmp1[i] + 128.5)];
+
+ return gTrue;
+}
+#endif
+
+int DCTStream::readHuffSym(DCTHuffTable *table) {
+ Gushort code;
+ int bit;
+ int codeBits;
+
+ code = 0;
+ codeBits = 0;
+ do {
+ // add a bit to the code
+ if ((bit = readBit()) == EOF)
+ return 9999;
+ code = (code << 1) + bit;
+ ++codeBits;
+
+ // look up code
+ if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
+ code -= table->firstCode[codeBits];
+ return table->sym[table->firstSym[codeBits] + code];
+ }
+ } while (codeBits < 16);
+
+ error(getPos(), "Bad Huffman code in DCT stream");
+ return 9999;
+}
+
+int DCTStream::readAmp(int size) {
+ int amp, bit;
+ int bits;
+
+ amp = 0;
+ for (bits = 0; bits < size; ++bits) {
+ if ((bit = readBit()) == EOF)
+ return 9999;
+ amp = (amp << 1) + bit;
+ }
+ if (amp < (1 << (size - 1)))
+ amp -= (1 << size) - 1;
+ return amp;
+}
+
+int DCTStream::readBit() {
+ int bit;
+ int c, c2;
+
+ if (inputBits == 0) {
+ if ((c = str->getChar()) == EOF)
+ return EOF;
+ if (c == 0xff) {
+ do {
+ c2 = str->getChar();
+ } while (c2 == 0xff);
+ if (c2 != 0x00) {
+ error(getPos(), "Bad DCT data: missing 00 after ff");
+ return EOF;
+ }
+ }
+ inputBuf = c;
+ inputBits = 8;
+ }
+ bit = (inputBuf >> (inputBits - 1)) & 1;
+ --inputBits;
+ return bit;
+}
+
+GBool DCTStream::readHeader() {
+ GBool doScan;
+ int minHSample, minVSample;
+ int bufWidth;
+ int n;
+ int c = 0;
+ int i, j;
+
+ width = height = 0;
+ numComps = 0;
+ numQuantTables = 0;
+ numDCHuffTables = 0;
+ numACHuffTables = 0;
+ colorXform = 0;
+ gotAdobeMarker = gFalse;
+ restartInterval = 0;
+
+ // read headers
+ doScan = gFalse;
+ while (!doScan) {
+ c = readMarker();
+ switch (c) {
+ case 0xc0: // SOF0
+ if (!readFrameInfo())
+ return gFalse;
+ break;
+ case 0xc4: // DHT
+ if (!readHuffmanTables())
+ return gFalse;
+ break;
+ case 0xd8: // SOI
+ break;
+ case 0xda: // SOS
+ if (!readScanInfo())
+ return gFalse;
+ doScan = gTrue;
+ break;
+ case 0xdb: // DQT
+ if (!readQuantTables())
+ return gFalse;
+ break;
+ case 0xdd: // DRI
+ if (!readRestartInterval())
+ return gFalse;
+ break;
+ case 0xee: // APP14
+ if (!readAdobeMarker())
+ return gFalse;
+ break;
+ case EOF:
+ error(getPos(), "Bad DCT header");
+ return gFalse;
+ default:
+ // skip APPn / COM / etc.
+ if (c >= 0xe0) {
+ n = read16() - 2;
+ for (i = 0; i < n; ++i)
+ str->getChar();
+ } else {
+ error(getPos(), "Unknown DCT marker <%02x>", c);
+ return gFalse;
+ }
+ break;
+ }
+ }
+
+ // compute MCU size
+ mcuWidth = minHSample = compInfo[0].hSample;
+ mcuHeight = minVSample = compInfo[0].vSample;
+ for (i = 1; i < numComps; ++i) {
+ if (compInfo[i].hSample < minHSample)
+ minHSample = compInfo[i].hSample;
+ if (compInfo[i].vSample < minVSample)
+ minVSample = compInfo[i].vSample;
+ if (compInfo[i].hSample > mcuWidth)
+ mcuWidth = compInfo[i].hSample;
+ if (compInfo[i].vSample > mcuHeight)
+ mcuHeight = compInfo[i].vSample;
+ }
+ for (i = 0; i < numComps; ++i) {
+ compInfo[i].hSample /= minHSample;
+ compInfo[i].vSample /= minVSample;
+ }
+ mcuWidth = (mcuWidth / minHSample) * 8;
+ mcuHeight = (mcuHeight / minVSample) * 8;
+
+ // allocate buffers
+ bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
+ for (i = 0; i < numComps; ++i)
+ for (j = 0; j < mcuHeight; ++j)
+ rowBuf[i][j] = (Guchar *)gmalloc(bufWidth * sizeof(Guchar));
+
+ // figure out color transform
+ if (!gotAdobeMarker && numComps == 3) {
+ if (compInfo[0].id == 1 && compInfo[1].id == 2 && compInfo[2].id == 3) {
+ colorXform = 1;
+ }
+ }
+
+ // initialize counters
+ comp = 0;
+ x = 0;
+ y = 0;
+ dy = mcuHeight;
+
+ return gTrue;
+}
+
+GBool DCTStream::readFrameInfo() {
+ int length;
+ int prec;
+ int i;
+ int c;
+
+ length = read16() - 2;
+ prec = str->getChar();
+ height = read16();
+ width = read16();
+ numComps = str->getChar();
+ length -= 6;
+ if (prec != 8) {
+ error(getPos(), "Bad DCT precision %d", prec);
+ return gFalse;
+ }
+ for (i = 0; i < numComps; ++i) {
+ compInfo[i].id = str->getChar();
+ compInfo[i].inScan = gFalse;
+ c = str->getChar();
+ compInfo[i].hSample = (c >> 4) & 0x0f;
+ compInfo[i].vSample = c & 0x0f;
+ compInfo[i].quantTable = str->getChar();
+ compInfo[i].dcHuffTable = 0;
+ compInfo[i].acHuffTable = 0;
+ }
+ return gTrue;
+}
+
+GBool DCTStream::readScanInfo() {
+ int length;
+ int scanComps, id, c;
+ int i, j;
+
+ length = read16() - 2;
+ scanComps = str->getChar();
+ --length;
+ if (length != 2 * scanComps + 3) {
+ error(getPos(), "Bad DCT scan info block");
+ return gFalse;
+ }
+ for (i = 0; i < scanComps; ++i) {
+ id = str->getChar();
+ for (j = 0; j < numComps; ++j) {
+ if (id == compInfo[j].id)
+ break;
+ }
+ if (j == numComps) {
+ error(getPos(), "Bad DCT component ID in scan info block");
+ return gFalse;
+ }
+ compInfo[j].inScan = gTrue;
+ c = str->getChar();
+ compInfo[j].dcHuffTable = (c >> 4) & 0x0f;
+ compInfo[j].acHuffTable = c & 0x0f;
+ }
+ str->getChar();
+ str->getChar();
+ str->getChar();
+ return gTrue;
+}
+
+GBool DCTStream::readQuantTables() {
+ int length;
+ int i;
+ int index;
+
+ length = read16() - 2;
+ while (length > 0) {
+ index = str->getChar();
+ if ((index & 0xf0) || index >= 4) {
+ error(getPos(), "Bad DCT quantization table");
+ return gFalse;
+ }
+ if (index == numQuantTables)
+ numQuantTables = index + 1;
+ for (i = 0; i < 64; ++i)
+ quantTables[index][dctZigZag[i]] = str->getChar();
+ length -= 65;
+ }
+ return gTrue;
+}
+
+GBool DCTStream::readHuffmanTables() {
+ DCTHuffTable *tbl;
+ int length;
+ int index;
+ Gushort code;
+ Guchar sym;
+ int i;
+ int c;
+
+ length = read16() - 2;
+ while (length > 0) {
+ index = str->getChar();
+ --length;
+ if ((index & 0x0f) >= 4) {
+ error(getPos(), "Bad DCT Huffman table");
+ return gFalse;
+ }
+ if (index & 0x10) {
+ index &= 0x0f;
+ if (index >= numACHuffTables)
+ numACHuffTables = index+1;
+ tbl = &acHuffTables[index];
+ } else {
+ if (index >= numDCHuffTables)
+ numDCHuffTables = index+1;
+ tbl = &dcHuffTables[index];
+ }
+ sym = 0;
+ code = 0;
+ for (i = 1; i <= 16; ++i) {
+ c = str->getChar();
+ tbl->firstSym[i] = sym;
+ tbl->firstCode[i] = code;
+ tbl->numCodes[i] = c;
+ sym += c;
+ code = (code + c) << 1;
+ }
+ length -= 16;
+ for (i = 0; i < sym; ++i)
+ tbl->sym[i] = str->getChar();
+ length -= sym;
+ }
+ return gTrue;
+}
+
+GBool DCTStream::readRestartInterval() {
+ int length;
+
+ length = read16();
+ if (length != 4) {
+ error(getPos(), "Bad DCT restart interval");
+ return gFalse;
+ }
+ restartInterval = read16();
+ return gTrue;
+}
+
+GBool DCTStream::readAdobeMarker() {
+ int length, i;
+ char buf[12];
+ int c;
+
+ length = read16();
+ if (length != 14)
+ goto err;
+ for (i = 0; i < 12; ++i) {
+ if ((c = str->getChar()) == EOF)
+ goto err;
+ buf[i] = c;
+ }
+ if (strncmp(buf, "Adobe", 5))
+ goto err;
+ colorXform = buf[11];
+ gotAdobeMarker = gTrue;
+ return gTrue;
+
+ err:
+ error(getPos(), "Bad DCT Adobe APP14 marker");
+ return gFalse;
+}
+
+GBool DCTStream::readTrailer() {
+ int c;
+
+ c = readMarker();
+ if (c != 0xd9) { // EOI
+ error(getPos(), "Bad DCT trailer");
+ return gFalse;
+ }
+ return gTrue;
+}
+
+int DCTStream::readMarker() {
+ int c;
+
+ do {
+ do {
+ c = str->getChar();
+ } while (c != 0xff);
+ do {
+ c = str->getChar();
+ } while (c == 0xff);
+ } while (c == 0x00);
+ return c;
+}
+
+int DCTStream::read16() {
+ int c1, c2;
+
+ if ((c1 = str->getChar()) == EOF)
+ return EOF;
+ if ((c2 = str->getChar()) == EOF)
+ return EOF;
+ return (c1 << 8) + c2;
+}
+
+GString *DCTStream::getPSFilter(char *indent) {
+ GString *s;
+
+ if (!(s = str->getPSFilter(indent))) {
+ return NULL;
+ }
+ s->append(indent)->append("<< >> /DCTDecode filter\n");
+ return s;
+}
+
+GBool DCTStream::isBinary(GBool last) {
+ return str->isBinary(gTrue);
+}
+
+//------------------------------------------------------------------------
+// FlateStream
+//------------------------------------------------------------------------
+
+int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+};
+
+FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
+ {0, 3},
+ {0, 4},
+ {0, 5},
+ {0, 6},
+ {0, 7},
+ {0, 8},
+ {0, 9},
+ {0, 10},
+ {1, 11},
+ {1, 13},
+ {1, 15},
+ {1, 17},
+ {2, 19},
+ {2, 23},
+ {2, 27},
+ {2, 31},
+ {3, 35},
+ {3, 43},
+ {3, 51},
+ {3, 59},
+ {4, 67},
+ {4, 83},
+ {4, 99},
+ {4, 115},
+ {5, 131},
+ {5, 163},
+ {5, 195},
+ {5, 227},
+ {0, 258}
+};
+
+FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
+ { 0, 1},
+ { 0, 2},
+ { 0, 3},
+ { 0, 4},
+ { 1, 5},
+ { 1, 7},
+ { 2, 9},
+ { 2, 13},
+ { 3, 17},
+ { 3, 25},
+ { 4, 33},
+ { 4, 49},
+ { 5, 65},
+ { 5, 97},
+ { 6, 129},
+ { 6, 193},
+ { 7, 257},
+ { 7, 385},
+ { 8, 513},
+ { 8, 769},
+ { 9, 1025},
+ { 9, 1537},
+ {10, 2049},
+ {10, 3073},
+ {11, 4097},
+ {11, 6145},
+ {12, 8193},
+ {12, 12289},
+ {13, 16385},
+ {13, 24577}
+};
+
+FlateStream::FlateStream(Stream *strA, int predictor, int columns,
+ int colors, int bits):
+ FilterStream(strA) {
+ if (predictor != 1) {
+ pred = new StreamPredictor(this, predictor, columns, colors, bits);
+ } else {
+ pred = NULL;
+ }
+}
+
+FlateStream::~FlateStream() {
+ if (pred) {
+ delete pred;
+ }
+ delete str;
+}
+
+void FlateStream::reset() {
+ int cmf, flg;
+
+ index = 0;
+ remain = 0;
+ codeBuf = 0;
+ codeSize = 0;
+ compressedBlock = gFalse;
+ endOfBlock = gTrue;
+ eof = gTrue;
+
+ str->reset();
+
+ // read header
+ //~ need to look at window size?
+ endOfBlock = eof = gTrue;
+ cmf = str->getChar();
+ flg = str->getChar();
+ if (cmf == EOF || flg == EOF)
+ return;
+ if ((cmf & 0x0f) != 0x08) {
+ error(getPos(), "Unknown compression method in flate stream");
+ return;
+ }
+ if ((((cmf << 8) + flg) % 31) != 0) {
+ error(getPos(), "Bad FCHECK in flate stream");
+ return;
+ }
+ if (flg & 0x20) {
+ error(getPos(), "FDICT bit set in flate stream");
+ return;
+ }
+
+ eof = gFalse;
+}
+
+int FlateStream::getChar() {
+ int c;
+
+ if (pred) {
+ return pred->getChar();
+ }
+ while (remain == 0) {
+ if (endOfBlock && eof)
+ return EOF;
+ readSome();
+ }
+ c = buf[index];
+ index = (index + 1) & flateMask;
+ --remain;
+ return c;
+}
+
+int FlateStream::lookChar() {
+ int c;
+
+ if (pred) {
+ return pred->lookChar();
+ }
+ while (remain == 0) {
+ if (endOfBlock && eof)
+ return EOF;
+ readSome();
+ }
+ c = buf[index];
+ return c;
+}
+
+int FlateStream::getRawChar() {
+ int c;
+
+ while (remain == 0) {
+ if (endOfBlock && eof)
+ return EOF;
+ readSome();
+ }
+ c = buf[index];
+ index = (index + 1) & flateMask;
+ --remain;
+ return c;
+}
+
+GString *FlateStream::getPSFilter(char *indent) {
+ return NULL;
+}
+
+GBool FlateStream::isBinary(GBool last) {
+ return str->isBinary(gTrue);
+}
+
+void FlateStream::readSome() {
+ int code1, code2;
+ int len, dist;
+ int i, j, k;
+ int c;
+
+ if (endOfBlock) {
+ if (!startBlock())
+ return;
+ }
+
+ if (compressedBlock) {
+ if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
+ goto err;
+ if (code1 < 256) {
+ buf[index] = code1;
+ remain = 1;
+ } else if (code1 == 256) {
+ endOfBlock = gTrue;
+ remain = 0;
+ } else {
+ code1 -= 257;
+ code2 = lengthDecode[code1].bits;
+ if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
+ goto err;
+ len = lengthDecode[code1].first + code2;
+ if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
+ goto err;
+ code2 = distDecode[code1].bits;
+ if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
+ goto err;
+ dist = distDecode[code1].first + code2;
+ i = index;
+ j = (index - dist) & flateMask;
+ for (k = 0; k < len; ++k) {
+ buf[i] = buf[j];
+ i = (i + 1) & flateMask;
+ j = (j + 1) & flateMask;
+ }
+ remain = len;
+ }
+
+ } else {
+ len = (blockLen < flateWindow) ? blockLen : flateWindow;
+ for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
+ if ((c = str->getChar()) == EOF) {
+ endOfBlock = eof = gTrue;
+ break;
+ }
+ buf[j] = c & 0xff;
+ }
+ remain = i;
+ blockLen -= len;
+ if (blockLen == 0)
+ endOfBlock = gTrue;
+ }
+
+ return;
+
+err:
+ error(getPos(), "Unexpected end of file in flate stream");
+ endOfBlock = eof = gTrue;
+ remain = 0;
+}
+
+GBool FlateStream::startBlock() {
+ int blockHdr;
+ int c;
+ int check;
+
+ // read block header
+ blockHdr = getCodeWord(3);
+ if (blockHdr & 1)
+ eof = gTrue;
+ blockHdr >>= 1;
+
+ // uncompressed block
+ if (blockHdr == 0) {
+ compressedBlock = gFalse;
+ if ((c = str->getChar()) == EOF)
+ goto err;
+ blockLen = c & 0xff;
+ if ((c = str->getChar()) == EOF)
+ goto err;
+ blockLen |= (c & 0xff) << 8;
+ if ((c = str->getChar()) == EOF)
+ goto err;
+ check = c & 0xff;
+ if ((c = str->getChar()) == EOF)
+ goto err;
+ check |= (c & 0xff) << 8;
+ if (check != (~blockLen & 0xffff))
+ error(getPos(), "Bad uncompressed block length in flate stream");
+ codeBuf = 0;
+ codeSize = 0;
+
+ // compressed block with fixed codes
+ } else if (blockHdr == 1) {
+ compressedBlock = gTrue;
+ loadFixedCodes();
+
+ // compressed block with dynamic codes
+ } else if (blockHdr == 2) {
+ compressedBlock = gTrue;
+ if (!readDynamicCodes())
+ goto err;
+
+ // unknown block type
+ } else {
+ goto err;
+ }
+
+ endOfBlock = gFalse;
+ return gTrue;
+
+err:
+ error(getPos(), "Bad block header in flate stream");
+ endOfBlock = eof = gTrue;
+ return gFalse;
+}
+
+void FlateStream::loadFixedCodes() {
+ int i;
+
+ // set up code arrays
+ litCodeTab.codes = allCodes;
+ distCodeTab.codes = allCodes + flateMaxLitCodes;
+
+ // initialize literal code table
+ for (i = 0; i <= 143; ++i)
+ litCodeTab.codes[i].len = 8;
+ for (i = 144; i <= 255; ++i)
+ litCodeTab.codes[i].len = 9;
+ for (i = 256; i <= 279; ++i)
+ litCodeTab.codes[i].len = 7;
+ for (i = 280; i <= 287; ++i)
+ litCodeTab.codes[i].len = 8;
+ compHuffmanCodes(&litCodeTab, flateMaxLitCodes);
+
+ // initialize distance code table
+ for (i = 0; i <= 5; ++i) {
+ distCodeTab.start[i] = 0;
+ }
+ for (i = 6; i <= flateMaxHuffman+1; ++i) {
+ distCodeTab.start[i] = flateMaxDistCodes;
+ }
+ for (i = 0; i < flateMaxDistCodes; ++i) {
+ distCodeTab.codes[i].len = 5;
+ distCodeTab.codes[i].code = i;
+ distCodeTab.codes[i].val = i;
+ }
+}
+
+GBool FlateStream::readDynamicCodes() {
+ int numCodeLenCodes;
+ int numLitCodes;
+ int numDistCodes;
+ FlateCode codeLenCodes[flateMaxCodeLenCodes];
+ FlateHuffmanTab codeLenCodeTab;
+ int len, repeat, code;
+ int i;
+
+ // read lengths
+ if ((numLitCodes = getCodeWord(5)) == EOF)
+ goto err;
+ numLitCodes += 257;
+ if ((numDistCodes = getCodeWord(5)) == EOF)
+ goto err;
+ numDistCodes += 1;
+ if ((numCodeLenCodes = getCodeWord(4)) == EOF)
+ goto err;
+ numCodeLenCodes += 4;
+ if (numLitCodes > flateMaxLitCodes ||
+ numDistCodes > flateMaxDistCodes ||
+ numCodeLenCodes > flateMaxCodeLenCodes)
+ goto err;
+
+ // read code length code table
+ codeLenCodeTab.codes = codeLenCodes;
+ for (i = 0; i < flateMaxCodeLenCodes; ++i)
+ codeLenCodes[i].len = 0;
+ for (i = 0; i < numCodeLenCodes; ++i) {
+ if ((codeLenCodes[codeLenCodeMap[i]].len = getCodeWord(3)) == -1)
+ goto err;
+ }
+ compHuffmanCodes(&codeLenCodeTab, flateMaxCodeLenCodes);
+
+ // set up code arrays
+ litCodeTab.codes = allCodes;
+ distCodeTab.codes = allCodes + numLitCodes;
+
+ // read literal and distance code tables
+ len = 0;
+ repeat = 0;
+ i = 0;
+ while (i < numLitCodes + numDistCodes) {
+ if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF)
+ goto err;
+ if (code == 16) {
+ if ((repeat = getCodeWord(2)) == EOF)
+ goto err;
+ for (repeat += 3; repeat > 0; --repeat)
+ allCodes[i++].len = len;
+ } else if (code == 17) {
+ if ((repeat = getCodeWord(3)) == EOF)
+ goto err;
+ len = 0;
+ for (repeat += 3; repeat > 0; --repeat)
+ allCodes[i++].len = 0;
+ } else if (code == 18) {
+ if ((repeat = getCodeWord(7)) == EOF)
+ goto err;
+ len = 0;
+ for (repeat += 11; repeat > 0; --repeat)
+ allCodes[i++].len = 0;
+ } else {
+ allCodes[i++].len = len = code;
+ }
+ }
+ compHuffmanCodes(&litCodeTab, numLitCodes);
+ compHuffmanCodes(&distCodeTab, numDistCodes);
+
+ return gTrue;
+
+err:
+ error(getPos(), "Bad dynamic code table in flate stream");
+ return gFalse;
+}
+
+// On entry, the <tab->codes> array contains the lengths of each code,
+// stored in code value order. This function computes the code words.
+// The result is sorted in order of (1) code length and (2) code word.
+// The length values are no longer valid. The <tab->start> array is
+// filled with the indexes of the first code of each length.
+void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) {
+ int numLengths[flateMaxHuffman+1];
+ int nextCode[flateMaxHuffman+1];
+ int nextIndex[flateMaxHuffman+2];
+ int code;
+ int i, j;
+
+ // count number of codes for each code length
+ for (i = 0; i <= flateMaxHuffman; ++i)
+ numLengths[i] = 0;
+ for (i = 0; i < n; ++i)
+ ++numLengths[tab->codes[i].len];
+
+ // compute first index for each length
+ tab->start[0] = nextIndex[0] = 0;
+ for (i = 1; i <= flateMaxHuffman + 1; ++i)
+ tab->start[i] = nextIndex[i] = tab->start[i-1] + numLengths[i-1];
+
+ // compute first code for each length
+ code = 0;
+ numLengths[0] = 0;
+ for (i = 1; i <= flateMaxHuffman; ++i) {
+ code = (code + numLengths[i-1]) << 1;
+ nextCode[i] = code;
+ }
+
+ // compute the codes -- this permutes the codes array from value
+ // order to length/code order
+ for (i = 0; i < n; ++i) {
+ j = nextIndex[tab->codes[i].len]++;
+ if (tab->codes[i].len == 0)
+ tab->codes[j].code = 0;
+ else
+ tab->codes[j].code = nextCode[tab->codes[i].len]++;
+ tab->codes[j].val = i;
+ }
+}
+
+int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
+ int len;
+ int code;
+ int c;
+ int i, j;
+
+ code = 0;
+ for (len = 1; len <= flateMaxHuffman; ++len) {
+
+ // add a bit to the code
+ if (codeSize == 0) {
+ if ((c = str->getChar()) == EOF)
+ return EOF;
+ codeBuf = c & 0xff;
+ codeSize = 8;
+ }
+ code = (code << 1) | (codeBuf & 1);
+ codeBuf >>= 1;
+ --codeSize;
+
+ // look for code
+ i = tab->start[len];
+ j = tab->start[len + 1];
+ if (i < j && code >= tab->codes[i].code && code <= tab->codes[j-1].code) {
+ i += code - tab->codes[i].code;
+ return tab->codes[i].val;
+ }
+ }
+
+ // not found
+ error(getPos(), "Bad code (%04x) in flate stream", code);
+ return EOF;
+}
+
+int FlateStream::getCodeWord(int bits) {
+ int c;
+
+ while (codeSize < bits) {
+ if ((c = str->getChar()) == EOF)
+ return EOF;
+ codeBuf |= (c & 0xff) << codeSize;
+ codeSize += 8;
+ }
+ c = codeBuf & ((1 << bits) - 1);
+ codeBuf >>= bits;
+ codeSize -= bits;
+ return c;
+}
+
+//------------------------------------------------------------------------
+// EOFStream
+//------------------------------------------------------------------------
+
+EOFStream::EOFStream(Stream *strA):
+ FilterStream(strA) {
+}
+
+EOFStream::~EOFStream() {
+ delete str;
+}
+
+//------------------------------------------------------------------------
+// FixedLengthEncoder
+//------------------------------------------------------------------------
+
+FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA):
+ FilterStream(strA) {
+ length = lengthA;
+ count = 0;
+}
+
+FixedLengthEncoder::~FixedLengthEncoder() {
+ if (str->isEncoder())
+ delete str;
+}
+
+void FixedLengthEncoder::reset() {
+ str->reset();
+ count = 0;
+}
+
+void FixedLengthEncoder::close() {
+}
+
+int FixedLengthEncoder::getChar() {
+ if (length >= 0 && count >= length)
+ return EOF;
+ ++count;
+ return str->getChar();
+}
+
+int FixedLengthEncoder::lookChar() {
+ if (length >= 0 && count >= length)
+ return EOF;
+ return str->getChar();
+}
+
+//------------------------------------------------------------------------
+// ASCII85Encoder
+//------------------------------------------------------------------------
+
+ASCII85Encoder::ASCII85Encoder(Stream *strA):
+ FilterStream(strA) {
+ bufPtr = bufEnd = buf;
+ lineLen = 0;
+ eof = gFalse;
+}
+
+ASCII85Encoder::~ASCII85Encoder() {
+ if (str->isEncoder())
+ delete str;
+}
+
+void ASCII85Encoder::reset() {
+ str->reset();
+ bufPtr = bufEnd = buf;
+ lineLen = 0;
+ eof = gFalse;
+}
+
+void ASCII85Encoder::close() {
+}
+
+GBool ASCII85Encoder::fillBuf() {
+ Gulong t;
+ char buf1[5];
+ int c;
+ int n, i;
+
+ if (eof)
+ return gFalse;
+ t = 0;
+ for (n = 0; n < 4; ++n) {
+ if ((c = str->getChar()) == EOF)
+ break;
+ t = (t << 8) + c;
+ }
+ bufPtr = bufEnd = buf;
+ if (n > 0) {
+ if (n == 4 && t == 0) {
+ *bufEnd++ = 'z';
+ if (++lineLen == 65) {
+ *bufEnd++ = '\n';
+ lineLen = 0;
+ }
+ } else {
+ if (n < 4)
+ t <<= 8 * (4 - n);
+ for (i = 4; i >= 0; --i) {
+ buf1[i] = (char)(t % 85 + 0x21);
+ t /= 85;
+ }
+ for (i = 0; i <= n; ++i) {
+ *bufEnd++ = buf1[i];
+ if (++lineLen == 65) {
+ *bufEnd++ = '\n';
+ lineLen = 0;
+ }
+ }
+ }
+ }
+ if (n < 4) {
+ *bufEnd++ = '~';
+ *bufEnd++ = '>';
+ eof = gTrue;
+ }
+ return bufPtr < bufEnd;
+}
+
+//------------------------------------------------------------------------
+// RunLengthEncoder
+//------------------------------------------------------------------------
+
+RunLengthEncoder::RunLengthEncoder(Stream *strA):
+ FilterStream(strA) {
+ bufPtr = bufEnd = nextEnd = buf;
+ eof = gFalse;
+}
+
+RunLengthEncoder::~RunLengthEncoder() {
+ if (str->isEncoder())
+ delete str;
+}
+
+void RunLengthEncoder::reset() {
+ str->reset();
+ bufPtr = bufEnd = nextEnd = buf;
+ eof = gFalse;
+}
+
+void RunLengthEncoder::close() {
+}
+
+//
+// When fillBuf finishes, buf[] looks like this:
+// +-----+--------------+-----------------+--
+// + tag | ... data ... | next 0, 1, or 2 |
+// +-----+--------------+-----------------+--
+// ^ ^ ^
+// bufPtr bufEnd nextEnd
+//
+GBool RunLengthEncoder::fillBuf() {
+ int c, c1, c2;
+ int n;
+
+ // already hit EOF?
+ if (eof)
+ return gFalse;
+
+ // grab two bytes
+ if (nextEnd < bufEnd + 1) {
+ if ((c1 = str->getChar()) == EOF) {
+ eof = gTrue;
+ return gFalse;
+ }
+ } else {
+ c1 = bufEnd[0] & 0xff;
+ }
+ if (nextEnd < bufEnd + 2) {
+ if ((c2 = str->getChar()) == EOF) {
+ eof = gTrue;
+ buf[0] = 0;
+ buf[1] = c1;
+ bufPtr = buf;
+ bufEnd = &buf[2];
+ return gTrue;
+ }
+ } else {
+ c2 = bufEnd[1] & 0xff;
+ }
+
+ // check for repeat
+ c = 0; // make gcc happy
+ if (c1 == c2) {
+ n = 2;
+ while (n < 128 && (c = str->getChar()) == c1)
+ ++n;
+ buf[0] = (char)(257 - n);
+ buf[1] = c1;
+ bufEnd = &buf[2];
+ if (c == EOF) {
+ eof = gTrue;
+ } else if (n < 128) {
+ buf[2] = c;
+ nextEnd = &buf[3];
+ } else {
+ nextEnd = bufEnd;
+ }
+
+ // get up to 128 chars
+ } else {
+ buf[1] = c1;
+ buf[2] = c2;
+ n = 2;
+ while (n < 128) {
+ if ((c = str->getChar()) == EOF) {
+ eof = gTrue;
+ break;
+ }
+ ++n;
+ buf[n] = c;
+ if (buf[n] == buf[n-1])
+ break;
+ }
+ if (buf[n] == buf[n-1]) {
+ buf[0] = (char)(n-2-1);
+ bufEnd = &buf[n-1];
+ nextEnd = &buf[n+1];
+ } else {
+ buf[0] = (char)(n-1);
+ bufEnd = nextEnd = &buf[n+1];
+ }
+ }
+ bufPtr = buf;
+ return gTrue;
+}
diff --git a/pdftops/Stream.h b/pdftops/Stream.h
new file mode 100644
index 000000000..1f9c561d1
--- /dev/null
+++ b/pdftops/Stream.h
@@ -0,0 +1,723 @@
+//========================================================================
+//
+// Stream.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef STREAM_H
+#define STREAM_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <stdio.h>
+#include "gtypes.h"
+#include "Object.h"
+
+#ifndef NO_DECRYPTION
+class Decrypt;
+#endif
+class BaseStream;
+
+//------------------------------------------------------------------------
+
+enum StreamKind {
+ strFile,
+ strASCIIHex,
+ strASCII85,
+ strLZW,
+ strRunLength,
+ strCCITTFax,
+ strDCT,
+ strFlate,
+ strWeird // internal-use stream types
+};
+
+//------------------------------------------------------------------------
+// Stream (base class)
+//------------------------------------------------------------------------
+
+class Stream {
+public:
+
+ // Constructor.
+ Stream();
+
+ // Destructor.
+ virtual ~Stream();
+
+ // Reference counting.
+ int incRef() { return ++ref; }
+ int decRef() { return --ref; }
+
+ // Get kind of stream.
+ virtual StreamKind getKind() = 0;
+
+ // Reset stream to beginning.
+ virtual void reset() = 0;
+
+ // Close down the stream.
+ virtual void close();
+
+ // Get next char from stream.
+ virtual int getChar() = 0;
+
+ // Peek at next char in stream.
+ virtual int lookChar() = 0;
+
+ // Get next char from stream without using the predictor.
+ // This is only used by StreamPredictor.
+ virtual int getRawChar();
+
+ // Get next line from stream.
+ virtual char *getLine(char *buf, int size);
+
+ // Get current position in file.
+ virtual int getPos() = 0;
+
+ // Go to a position in the stream.
+ virtual void setPos(int pos) = 0;
+
+ // Get PostScript command for the filter(s).
+ virtual GString *getPSFilter(char *indent);
+
+ // Does this stream type potentially contain non-printable chars?
+ virtual GBool isBinary(GBool last = gTrue) = 0;
+
+ // Get the BaseStream or EmbedStream of this stream.
+ virtual BaseStream *getBaseStream() = 0;
+
+ // Get the dictionary associated with this stream.
+ virtual Dict *getDict() = 0;
+
+ // Is this an encoding filter?
+ virtual GBool isEncoder() { return gFalse; }
+
+ // Add filters to this stream according to the parameters in <dict>.
+ // Returns the new stream.
+ Stream *addFilters(Object *dict);
+
+private:
+
+ Stream *makeFilter(char *name, Stream *str, Object *params);
+
+ int ref; // reference count
+};
+
+//------------------------------------------------------------------------
+// BaseStream
+//
+// This is the base class for all streams that read directly from a file.
+//------------------------------------------------------------------------
+
+class BaseStream: public Stream {
+public:
+
+ BaseStream(Object *dictA);
+ virtual ~BaseStream();
+ virtual Stream *makeSubStream(int start, int length, Object *dict) = 0;
+ virtual void setPos(int pos) = 0;
+ virtual BaseStream *getBaseStream() { return this; }
+ virtual Dict *getDict() { return dict.getDict(); }
+
+ // Get/set position of first byte of stream within the file.
+ virtual int getStart() = 0;
+ virtual void moveStart(int delta) = 0;
+
+#ifndef NO_DECRYPTION
+ // Set decryption for this stream.
+ void doDecryption(Guchar *fileKey, int keyLength, int objNum, int objGen);
+#endif
+
+#ifndef NO_DECRYPTION
+protected:
+
+ Decrypt *decrypt;
+#endif
+
+private:
+
+ Object dict;
+};
+
+//------------------------------------------------------------------------
+// FilterStream
+//
+// This is the base class for all streams that filter another stream.
+//------------------------------------------------------------------------
+
+class FilterStream: public Stream {
+public:
+
+ FilterStream(Stream *strA);
+ virtual ~FilterStream();
+ virtual void close();
+ virtual int getPos() { return str->getPos(); }
+ virtual void setPos(int pos);
+ virtual BaseStream *getBaseStream() { return str->getBaseStream(); }
+ virtual Dict *getDict() { return str->getDict(); }
+
+protected:
+
+ Stream *str;
+};
+
+//------------------------------------------------------------------------
+// ImageStream
+//------------------------------------------------------------------------
+
+class ImageStream {
+public:
+
+ // Create an image stream object for an image with the specified
+ // parameters. Note that these are the actual image parameters,
+ // which may be different from the predictor parameters.
+ ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA);
+
+ ~ImageStream();
+
+ // Reset the stream.
+ void reset();
+
+ // Gets the next pixel from the stream. <pix> should be able to hold
+ // at least nComps elements. Returns false at end of file.
+ GBool getPixel(Guchar *pix);
+
+ // Skip an entire line from the image.
+ void skipLine();
+
+private:
+
+ Stream *str; // base stream
+ int width; // pixels per line
+ int nComps; // components per pixel
+ int nBits; // bits per component
+ int nVals; // components per line
+ Guchar *imgLine; // line buffer
+ int imgIdx; // current index in imgLine
+};
+
+//------------------------------------------------------------------------
+// StreamPredictor
+//------------------------------------------------------------------------
+
+class StreamPredictor {
+public:
+
+ // Create a predictor object. Note that the parameters are for the
+ // predictor, and may not match the actual image parameters.
+ StreamPredictor(Stream *strA, int predictorA,
+ int widthA, int nCompsA, int nBitsA);
+
+ ~StreamPredictor();
+
+ int lookChar();
+ int getChar();
+
+private:
+
+ GBool getNextLine();
+
+ Stream *str; // base stream
+ int predictor; // predictor
+ int width; // pixels per line
+ int nComps; // components per pixel
+ int nBits; // bits per component
+ int nVals; // components per line
+ int pixBytes; // bytes per pixel
+ int rowBytes; // bytes per line
+ Guchar *predLine; // line buffer
+ int predIdx; // current index in predLine
+};
+
+//------------------------------------------------------------------------
+// FileStream
+//------------------------------------------------------------------------
+
+#define fileStreamBufSize 256
+
+class FileStream: public BaseStream {
+public:
+
+ FileStream(FILE *fA, int startA, int lengthA, Object *dictA);
+ virtual ~FileStream();
+ virtual Stream *makeSubStream(int startA, int lengthA, Object *dictA);
+ virtual StreamKind getKind() { return strFile; }
+ virtual void reset();
+ virtual void close();
+ virtual int getChar()
+ { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
+ virtual int lookChar()
+ { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
+ virtual int getPos() { return bufPos + (bufPtr - buf); }
+ virtual void setPos(int pos);
+ virtual GBool isBinary(GBool last = gTrue) { return last; }
+ virtual int getStart() { return start; }
+ virtual void moveStart(int delta);
+
+private:
+
+ GBool fillBuf();
+
+ FILE *f;
+ int start;
+ int length;
+ char buf[fileStreamBufSize];
+ char *bufPtr;
+ char *bufEnd;
+ int bufPos;
+ int savePos;
+};
+
+//------------------------------------------------------------------------
+// EmbedStream
+//
+// This is a special stream type used for embedded streams (inline
+// images). It reads directly from the base stream -- after the
+// EmbedStream is deleted, reads from the base stream will proceed where
+// the BaseStream left off. Note that this is very different behavior
+// that creating a new FileStream (using makeSubStream).
+//------------------------------------------------------------------------
+
+class EmbedStream: public BaseStream {
+public:
+
+ EmbedStream(Stream *strA, Object *dictA);
+ virtual ~EmbedStream();
+ virtual Stream *makeSubStream(int start, int length, Object *dictA);
+ virtual StreamKind getKind() { return str->getKind(); }
+ virtual void reset() {}
+ virtual int getChar() { return str->getChar(); }
+ virtual int lookChar() { return str->lookChar(); }
+ virtual int getPos() { return str->getPos(); }
+ virtual void setPos(int pos);
+ virtual GBool isBinary(GBool last = gTrue) { return last; }
+ virtual int getStart();
+ virtual void moveStart(int delta);
+
+private:
+
+ Stream *str;
+};
+
+//------------------------------------------------------------------------
+// ASCIIHexStream
+//------------------------------------------------------------------------
+
+class ASCIIHexStream: public FilterStream {
+public:
+
+ ASCIIHexStream(Stream *strA);
+ virtual ~ASCIIHexStream();
+ virtual StreamKind getKind() { return strASCIIHex; }
+ virtual void reset();
+ virtual int getChar()
+ { int c = lookChar(); buf = EOF; return c; }
+ virtual int lookChar();
+ virtual GString *getPSFilter(char *indent);
+ virtual GBool isBinary(GBool last = gTrue);
+
+private:
+
+ int buf;
+ GBool eof;
+};
+
+//------------------------------------------------------------------------
+// ASCII85Stream
+//------------------------------------------------------------------------
+
+class ASCII85Stream: public FilterStream {
+public:
+
+ ASCII85Stream(Stream *strA);
+ virtual ~ASCII85Stream();
+ virtual StreamKind getKind() { return strASCII85; }
+ virtual void reset();
+ virtual int getChar()
+ { int ch = lookChar(); ++index; return ch; }
+ virtual int lookChar();
+ virtual GString *getPSFilter(char *indent);
+ virtual GBool isBinary(GBool last = gTrue);
+
+private:
+
+ int c[5];
+ int b[4];
+ int index, n;
+ GBool eof;
+};
+
+//------------------------------------------------------------------------
+// LZWStream
+//------------------------------------------------------------------------
+
+class LZWStream: public FilterStream {
+public:
+
+ LZWStream(Stream *strA, int predictor, int columns, int colors,
+ int bits, int earlyA);
+ virtual ~LZWStream();
+ virtual StreamKind getKind() { return strLZW; }
+ virtual void reset();
+ virtual int getChar();
+ virtual int lookChar();
+ virtual int getRawChar();
+ virtual GString *getPSFilter(char *indent);
+ virtual GBool isBinary(GBool last = gTrue);
+
+private:
+
+ StreamPredictor *pred; // predictor
+ int early; // early parameter
+ FILE *zPipe; // uncompress pipe
+ GString *zName; // .Z file name
+ int inputBuf; // input buffer
+ int inputBits; // number of bits in input buffer
+ int inCodeBits; // size of input code
+ char buf[256]; // buffer
+ char *bufPtr; // next char to read
+ char *bufEnd; // end of buffer
+
+ void dumpFile(FILE *f);
+ int getCode();
+ GBool fillBuf();
+};
+
+//------------------------------------------------------------------------
+// RunLengthStream
+//------------------------------------------------------------------------
+
+class RunLengthStream: public FilterStream {
+public:
+
+ RunLengthStream(Stream *strA);
+ virtual ~RunLengthStream();
+ virtual StreamKind getKind() { return strRunLength; }
+ virtual void reset();
+ virtual int getChar()
+ { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
+ virtual int lookChar()
+ { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
+ virtual GString *getPSFilter(char *indent);
+ virtual GBool isBinary(GBool last = gTrue);
+
+private:
+
+ char buf[128]; // buffer
+ char *bufPtr; // next char to read
+ char *bufEnd; // end of buffer
+ GBool eof;
+
+ GBool fillBuf();
+};
+
+//------------------------------------------------------------------------
+// CCITTFaxStream
+//------------------------------------------------------------------------
+
+struct CCITTCodeTable;
+
+class CCITTFaxStream: public FilterStream {
+public:
+
+ CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
+ GBool byteAlignA, int columnsA, int rowsA,
+ GBool endOfBlockA, GBool blackA);
+ virtual ~CCITTFaxStream();
+ virtual StreamKind getKind() { return strCCITTFax; }
+ virtual void reset();
+ virtual int getChar()
+ { int c = lookChar(); buf = EOF; return c; }
+ virtual int lookChar();
+ virtual GString *getPSFilter(char *indent);
+ virtual GBool isBinary(GBool last = gTrue);
+
+private:
+
+ int encoding; // 'K' parameter
+ GBool endOfLine; // 'EndOfLine' parameter
+ GBool byteAlign; // 'EncodedByteAlign' parameter
+ int columns; // 'Columns' parameter
+ int rows; // 'Rows' parameter
+ GBool endOfBlock; // 'EndOfBlock' parameter
+ GBool black; // 'BlackIs1' parameter
+ GBool eof; // true if at eof
+ GBool nextLine2D; // true if next line uses 2D encoding
+ int row; // current row
+ int inputBuf; // input buffer
+ int inputBits; // number of bits in input buffer
+ short *refLine; // reference line changing elements
+ int b1; // index into refLine
+ short *codingLine; // coding line changing elements
+ int a0; // index into codingLine
+ int outputBits; // remaining ouput bits
+ int buf; // character buffer
+
+ short getTwoDimCode();
+ short getWhiteCode();
+ short getBlackCode();
+ short lookBits(int n);
+ void eatBits(int n) { inputBits -= n; }
+};
+
+//------------------------------------------------------------------------
+// DCTStream
+//------------------------------------------------------------------------
+
+// DCT component info
+struct DCTCompInfo {
+ int id; // component ID
+ GBool inScan; // is this component in the current scan?
+ int hSample, vSample; // horiz/vert sampling resolutions
+ int quantTable; // quantization table number
+ int dcHuffTable, acHuffTable; // Huffman table numbers
+ int prevDC; // DC coefficient accumulator
+};
+
+// DCT Huffman decoding table
+struct DCTHuffTable {
+ Guchar firstSym[17]; // first symbol for this bit length
+ Gushort firstCode[17]; // first code for this bit length
+ Gushort numCodes[17]; // number of codes of this bit length
+ Guchar sym[256]; // symbols
+};
+
+class DCTStream: public FilterStream {
+public:
+
+ DCTStream(Stream *strA);
+ virtual ~DCTStream();
+ virtual StreamKind getKind() { return strDCT; }
+ virtual void reset();
+ virtual int getChar();
+ virtual int lookChar();
+ virtual GString *getPSFilter(char *indent);
+ virtual GBool isBinary(GBool last = gTrue);
+ Stream *getRawStream() { return str; }
+
+private:
+
+ int width, height; // image size
+ int mcuWidth, mcuHeight; // size of min coding unit, in data units
+ DCTCompInfo compInfo[4]; // info for each component
+ int numComps; // number of components in image
+ int colorXform; // need YCbCr-to-RGB transform?
+ GBool gotAdobeMarker; // set if APP14 Adobe marker was present
+ int restartInterval; // restart interval, in MCUs
+ Guchar quantTables[4][64]; // quantization tables
+ int numQuantTables; // number of quantization tables
+ DCTHuffTable dcHuffTables[4]; // DC Huffman tables
+ DCTHuffTable acHuffTables[4]; // AC Huffman tables
+ int numDCHuffTables; // number of DC Huffman tables
+ int numACHuffTables; // number of AC Huffman tables
+ Guchar *rowBuf[4][32]; // buffer for one MCU
+ int comp, x, y, dy; // current position within image/MCU
+ int restartCtr; // MCUs left until restart
+ int restartMarker; // next restart marker
+ int inputBuf; // input buffer for variable length codes
+ int inputBits; // number of valid bits in input buffer
+
+ void restart();
+ GBool readMCURow();
+ GBool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable,
+ Guchar quantTable[64], int *prevDC, Guchar data[64]);
+ int readHuffSym(DCTHuffTable *table);
+ int readAmp(int size);
+ int readBit();
+ GBool readHeader();
+ GBool readFrameInfo();
+ GBool readScanInfo();
+ GBool readQuantTables();
+ GBool readHuffmanTables();
+ GBool readRestartInterval();
+ GBool readAdobeMarker();
+ GBool readTrailer();
+ int readMarker();
+ int read16();
+};
+
+//------------------------------------------------------------------------
+// FlateStream
+//------------------------------------------------------------------------
+
+#define flateWindow 32768 // buffer size
+#define flateMask (flateWindow-1)
+#define flateMaxHuffman 15 // max Huffman code length
+#define flateMaxCodeLenCodes 19 // max # code length codes
+#define flateMaxLitCodes 288 // max # literal codes
+#define flateMaxDistCodes 30 // max # distance codes
+
+// Huffman code table entry
+struct FlateCode {
+ int len; // code length in bits
+ int code; // code word
+ int val; // value represented by this code
+};
+
+// Huffman code table
+struct FlateHuffmanTab {
+ int start[flateMaxHuffman+2]; // indexes of first code of each length
+ FlateCode *codes; // codes, sorted by length and code word
+};
+
+// Decoding info for length and distance code words
+struct FlateDecode {
+ int bits; // # extra bits
+ int first; // first length/distance
+};
+
+class FlateStream: public FilterStream {
+public:
+
+ FlateStream(Stream *strA, int predictor, int columns,
+ int colors, int bits);
+ virtual ~FlateStream();
+ virtual StreamKind getKind() { return strFlate; }
+ virtual void reset();
+ virtual int getChar();
+ virtual int lookChar();
+ virtual int getRawChar();
+ virtual GString *getPSFilter(char *indent);
+ virtual GBool isBinary(GBool last = gTrue);
+
+private:
+
+ StreamPredictor *pred; // predictor
+ Guchar buf[flateWindow]; // output data buffer
+ int index; // current index into output buffer
+ int remain; // number valid bytes in output buffer
+ int codeBuf; // input buffer
+ int codeSize; // number of bits in input buffer
+ FlateCode // literal and distance codes
+ allCodes[flateMaxLitCodes + flateMaxDistCodes];
+ FlateHuffmanTab litCodeTab; // literal code table
+ FlateHuffmanTab distCodeTab; // distance code table
+ GBool compressedBlock; // set if reading a compressed block
+ int blockLen; // remaining length of uncompressed block
+ GBool endOfBlock; // set when end of block is reached
+ GBool eof; // set when end of stream is reached
+
+ static int // code length code reordering
+ codeLenCodeMap[flateMaxCodeLenCodes];
+ static FlateDecode // length decoding info
+ lengthDecode[flateMaxLitCodes-257];
+ static FlateDecode // distance decoding info
+ distDecode[flateMaxDistCodes];
+
+ void readSome();
+ GBool startBlock();
+ void loadFixedCodes();
+ GBool readDynamicCodes();
+ void compHuffmanCodes(FlateHuffmanTab *tab, int n);
+ int getHuffmanCodeWord(FlateHuffmanTab *tab);
+ int getCodeWord(int bits);
+};
+
+//------------------------------------------------------------------------
+// EOFStream
+//------------------------------------------------------------------------
+
+class EOFStream: public FilterStream {
+public:
+
+ EOFStream(Stream *strA);
+ virtual ~EOFStream();
+ virtual StreamKind getKind() { return strWeird; }
+ virtual void reset() {}
+ virtual int getChar() { return EOF; }
+ virtual int lookChar() { return EOF; }
+ virtual GString *getPSFilter(char *indent) { return NULL; }
+ virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
+};
+
+//------------------------------------------------------------------------
+// FixedLengthEncoder
+//------------------------------------------------------------------------
+
+class FixedLengthEncoder: public FilterStream {
+public:
+
+ FixedLengthEncoder(Stream *strA, int lengthA);
+ ~FixedLengthEncoder();
+ virtual StreamKind getKind() { return strWeird; }
+ virtual void reset();
+ virtual void close();
+ virtual int getChar();
+ virtual int lookChar();
+ virtual GString *getPSFilter(char *indent) { return NULL; }
+ virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
+ virtual GBool isEncoder() { return gTrue; }
+
+private:
+
+ int length;
+ int count;
+};
+
+//------------------------------------------------------------------------
+// ASCII85Encoder
+//------------------------------------------------------------------------
+
+class ASCII85Encoder: public FilterStream {
+public:
+
+ ASCII85Encoder(Stream *strA);
+ virtual ~ASCII85Encoder();
+ virtual StreamKind getKind() { return strWeird; }
+ virtual void reset();
+ virtual void close();
+ virtual int getChar()
+ { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
+ virtual int lookChar()
+ { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
+ virtual GString *getPSFilter(char *indent) { return NULL; }
+ virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
+ virtual GBool isEncoder() { return gTrue; }
+
+private:
+
+ char buf[8];
+ char *bufPtr;
+ char *bufEnd;
+ int lineLen;
+ GBool eof;
+
+ GBool fillBuf();
+};
+
+//------------------------------------------------------------------------
+// RunLengthEncoder
+//------------------------------------------------------------------------
+
+class RunLengthEncoder: public FilterStream {
+public:
+
+ RunLengthEncoder(Stream *strA);
+ virtual ~RunLengthEncoder();
+ virtual StreamKind getKind() { return strWeird; }
+ virtual void reset();
+ virtual void close();
+ virtual int getChar()
+ { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
+ virtual int lookChar()
+ { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
+ virtual GString *getPSFilter(char *indent) { return NULL; }
+ virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
+ virtual GBool isEncoder() { return gTrue; }
+
+private:
+
+ char buf[131];
+ char *bufPtr;
+ char *bufEnd;
+ char *nextEnd;
+ GBool eof;
+
+ GBool fillBuf();
+};
+
+#endif
diff --git a/pdftops/T1Font.h b/pdftops/T1Font.h
new file mode 100644
index 000000000..846d253e9
--- /dev/null
+++ b/pdftops/T1Font.h
@@ -0,0 +1,102 @@
+//========================================================================
+//
+// T1Font.h
+//
+// An X wrapper for the t1lib Type 1 font rasterizer.
+//
+//========================================================================
+
+#ifndef T1FONT_H
+#define T1FONT_H
+
+#if HAVE_T1LIB_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include <X11/Xlib.h>
+#include <t1lib.h>
+#include "SFont.h"
+
+class FontEncoding;
+
+//------------------------------------------------------------------------
+
+class T1FontEngine: public SFontEngine {
+public:
+
+ T1FontEngine(Display *displayA, Visual *visualA, int depthA,
+ Colormap colormapA, GBool aaA, GBool aaHighA);
+ GBool isOk() { return ok; }
+ virtual ~T1FontEngine();
+
+private:
+
+ GBool aa; // use anti-aliasing?
+ GBool aaHigh; // use high-res anti-aliasing?
+ GBool ok;
+
+ friend class T1FontFile;
+ friend class T1Font;
+};
+
+//------------------------------------------------------------------------
+
+class T1FontFile: public SFontFile {
+public:
+
+ T1FontFile(T1FontEngine *engineA, char *fontFileName,
+ FontEncoding *fontEnc, double *bboxA);
+ GBool isOk() { return ok; }
+ virtual ~T1FontFile();
+
+private:
+
+ T1FontEngine *engine;
+ int id; // t1lib font ID
+ char **enc;
+ char *encStr;
+ double bbox[4];
+ GBool ok;
+
+ friend class T1Font;
+};
+
+//------------------------------------------------------------------------
+
+struct T1FontCacheTag {
+ Gushort code;
+ Gushort mru; // valid bit (0x8000) and MRU index
+ int x, y, w, h; // offset and size of glyph
+};
+
+class T1Font: public SFont {
+public:
+
+ T1Font(T1FontFile *fontFileA, double *m);
+ GBool isOk() { return ok; }
+ virtual ~T1Font();
+ virtual GBool drawChar(Drawable d, int w, int h, GC gc,
+ int x, int y, int r, int g, int b, Gushort c);
+
+private:
+
+ Guchar *getGlyphPixmap(Gushort c, int *x, int *y, int *w, int *h);
+
+ T1FontFile *fontFile;
+ int id;
+ float size;
+ XImage *image;
+ int glyphW, glyphH; // size of glyph pixmaps
+ int glyphSize; // size of glyph pixmaps, in bytes
+ Guchar *cache; // glyph pixmap cache
+ T1FontCacheTag *cacheTags; // cache tags, i.e., char codes
+ int cacheSets; // number of sets in cache
+ int cacheAssoc; // cache associativity (glyphs per set)
+ GBool ok;
+};
+
+#endif // HAVE_T1LIB_H
+
+#endif
diff --git a/pdftops/TTFont.h b/pdftops/TTFont.h
new file mode 100644
index 000000000..998087c9c
--- /dev/null
+++ b/pdftops/TTFont.h
@@ -0,0 +1,104 @@
+//========================================================================
+//
+// TTFont.h
+//
+// An X wrapper for the FreeType TrueType font rasterizer.
+//
+//========================================================================
+
+#ifndef TTFONT_H
+#define TTFONT_H
+
+#if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#if HAVE_FREETYPE_FREETYPE_H
+#include <freetype/freetype.h>
+#include <freetype/ftxpost.h>
+#else
+#include <freetype.h>
+#include <ftxpost.h>
+#endif
+#include "SFont.h"
+
+//------------------------------------------------------------------------
+
+class TTFontEngine: public SFontEngine {
+public:
+
+ TTFontEngine(Display *displayA, Visual *visualA, int depthA,
+ Colormap colormapA, GBool aaA);
+ GBool isOk() { return ok; }
+ virtual ~TTFontEngine();
+
+private:
+
+ TT_Engine engine;
+ GBool aa;
+ Gulong palette[5];
+ GBool ok;
+
+ friend class TTFontFile;
+ friend class TTFont;
+};
+
+//------------------------------------------------------------------------
+
+class TTFontFile: public SFontFile {
+public:
+
+ TTFontFile(TTFontEngine *engineA, char *fontFileName);
+ GBool isOk() { return ok; }
+ virtual ~TTFontFile();
+
+private:
+
+ TTFontEngine *engine;
+ TT_Face face;
+ TT_CharMap charMap;
+ int charMapOffset;
+ GBool ok;
+
+ friend class TTFont;
+};
+
+//------------------------------------------------------------------------
+
+struct TTFontCacheTag {
+ Gushort code;
+ Gushort mru; // valid bit (0x8000) and MRU index
+};
+
+class TTFont: public SFont {
+public:
+
+ TTFont(TTFontFile *fontFileA, double *m);
+ GBool isOk() { return ok; }
+ virtual ~TTFont();
+ virtual GBool drawChar(Drawable d, int w, int h, GC gc,
+ int x, int y, int r, int g, int b, Gushort c);
+
+private:
+
+ GBool getGlyphPixmap(Gushort c);
+
+ TTFontFile *fontFile;
+ TT_Instance instance;
+ TT_Glyph glyph;
+ TT_Raster_Map ras;
+ XImage *image;
+ TT_Matrix matrix;
+ TT_F26Dot6 xOffset, yOffset;
+ Guchar *cache; // glyph pixmap cache
+ TTFontCacheTag *cacheTags; // cache tags, i.e., char codes
+ int cacheSets; // number of sets in cache
+ int cacheAssoc; // cache associativity (glyphs per set)
+ GBool ok;
+};
+
+#endif // !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H)
+
+#endif
diff --git a/pdftops/XRef.cxx b/pdftops/XRef.cxx
new file mode 100644
index 000000000..de2db2f23
--- /dev/null
+++ b/pdftops/XRef.cxx
@@ -0,0 +1,635 @@
+//========================================================================
+//
+// XRef.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef __GNUC__
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <ctype.h>
+#include "gmem.h"
+#include "Object.h"
+#include "Stream.h"
+#include "Lexer.h"
+#include "Parser.h"
+#include "Dict.h"
+#ifndef NO_DECRYPTION
+#include "Decrypt.h"
+#endif
+#include "Error.h"
+#include "XRef.h"
+
+//------------------------------------------------------------------------
+
+#define xrefSearchSize 1024 // read this many bytes at end of file
+ // to look for 'startxref'
+
+#ifndef NO_DECRYPTION
+//------------------------------------------------------------------------
+// Permission bits
+//------------------------------------------------------------------------
+
+#define permPrint (1<<2)
+#define permChange (1<<3)
+#define permCopy (1<<4)
+#define permNotes (1<<5)
+#define defPermFlags 0xfffc
+#endif
+
+//------------------------------------------------------------------------
+// XRef
+//------------------------------------------------------------------------
+
+XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) {
+ int pos;
+ int i;
+
+ ok = gTrue;
+ size = 0;
+ entries = NULL;
+ streamEnds = NULL;
+ streamEndsLen = 0;
+
+ // read the trailer
+ str = strA;
+ start = str->getStart();
+ pos = readTrailer();
+
+ // if there was a problem with the trailer,
+ // try to reconstruct the xref table
+ if (pos == 0) {
+ if (!(ok = constructXRef())) {
+ return;
+ }
+
+ // trailer is ok - read the xref table
+ } else {
+ entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry));
+ for (i = 0; i < size; ++i) {
+ entries[i].offset = -1;
+ entries[i].used = gFalse;
+ }
+ while (readXRef(&pos)) ;
+
+ // if there was a problem with the xref table,
+ // try to reconstruct it
+ if (!ok) {
+ gfree(entries);
+ size = 0;
+ entries = NULL;
+ if (!(ok = constructXRef())) {
+ return;
+ }
+ }
+ }
+
+ // now set the trailer dictionary's xref pointer so we can fetch
+ // indirect objects from it
+ trailerDict.getDict()->setXRef(this);
+
+ // check for encryption
+#ifndef NO_DECRYPTION
+ encrypted = gFalse;
+#endif
+ if (checkEncrypted(ownerPassword, userPassword)) {
+ ok = gFalse;
+ return;
+ }
+}
+
+XRef::~XRef() {
+ gfree(entries);
+ trailerDict.free();
+ if (streamEnds) {
+ gfree(streamEnds);
+ }
+}
+
+// Read startxref position, xref table size, and root. Returns
+// first xref position.
+int XRef::readTrailer() {
+ Parser *parser;
+ Object obj;
+ char buf[xrefSearchSize+1];
+ int n, pos, pos1;
+ char *p;
+ int c;
+ int i;
+
+ // read last xrefSearchSize bytes
+ str->setPos(-xrefSearchSize);
+ for (n = 0; n < xrefSearchSize; ++n) {
+ if ((c = str->getChar()) == EOF)
+ break;
+ buf[n] = c;
+ }
+ buf[n] = '\0';
+
+ // find startxref
+ for (i = n - 9; i >= 0; --i) {
+ if (!strncmp(&buf[i], "startxref", 9))
+ break;
+ }
+ if (i < 0)
+ return 0;
+ for (p = &buf[i+9]; isspace(*p); ++p) ;
+ pos = lastXRefPos = atoi(p);
+
+ // find trailer dict by looking after first xref table
+ // (NB: we can't just use the trailer dict at the end of the file --
+ // this won't work for linearized files.)
+ str->setPos(start + pos);
+ for (i = 0; i < 4; ++i)
+ buf[i] = str->getChar();
+ if (strncmp(buf, "xref", 4))
+ return 0;
+ pos1 = pos + 4;
+ while (1) {
+ str->setPos(start + pos1);
+ for (i = 0; i < 35; ++i) {
+ if ((c = str->getChar()) == EOF)
+ return 0;
+ buf[i] = c;
+ }
+ if (!strncmp(buf, "trailer", 7))
+ break;
+ p = buf;
+ while (isspace(*p)) ++p;
+ while ('0' <= *p && *p <= '9') ++p;
+ while (isspace(*p)) ++p;
+ n = atoi(p);
+ while ('0' <= *p && *p <= '9') ++p;
+ while (isspace(*p)) ++p;
+ if (p == buf)
+ return 0;
+ pos1 += (p - buf) + n * 20;
+ }
+ pos1 += 7;
+
+ // read trailer dict
+ obj.initNull();
+ parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(start + pos1,
+ -1, &obj)));
+ parser->getObj(&trailerDict);
+ if (trailerDict.isDict()) {
+ trailerDict.dictLookupNF("Size", &obj);
+ if (obj.isInt())
+ size = obj.getInt();
+ else
+ pos = 0;
+ obj.free();
+ trailerDict.dictLookupNF("Root", &obj);
+ if (obj.isRef()) {
+ rootNum = obj.getRefNum();
+ rootGen = obj.getRefGen();
+ } else {
+ pos = 0;
+ }
+ obj.free();
+ } else {
+ pos = 0;
+ }
+ delete parser;
+
+ // return first xref position
+ return pos;
+}
+
+// Read an xref table and the prev pointer from the trailer.
+GBool XRef::readXRef(int *pos) {
+ Parser *parser;
+ Object obj, obj2;
+ char s[20];
+ GBool more;
+ int first, newSize, n, i, j;
+ int c;
+
+ // seek to xref in stream
+ str->setPos(start + *pos);
+
+ // make sure it's an xref table
+ while ((c = str->getChar()) != EOF && isspace(c)) ;
+ s[0] = (char)c;
+ s[1] = (char)str->getChar();
+ s[2] = (char)str->getChar();
+ s[3] = (char)str->getChar();
+ if (!(s[0] == 'x' && s[1] == 'r' && s[2] == 'e' && s[3] == 'f')) {
+ goto err2;
+ }
+
+ // read xref
+ while (1) {
+ while ((c = str->lookChar()) != EOF && isspace(c)) {
+ str->getChar();
+ }
+ if (c == 't') {
+ break;
+ }
+ for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) {
+ s[i] = (char)c;
+ }
+ if (i == 0) {
+ goto err2;
+ }
+ s[i] = '\0';
+ first = atoi(s);
+ while ((c = str->lookChar()) != EOF && isspace(c)) {
+ str->getChar();
+ }
+ for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) {
+ s[i] = (char)c;
+ }
+ if (i == 0) {
+ goto err2;
+ }
+ s[i] = '\0';
+ n = atoi(s);
+ while ((c = str->lookChar()) != EOF && isspace(c)) {
+ str->getChar();
+ }
+ // check for buggy PDF files with an incorrect (too small) xref
+ // table size
+ if (first + n > size) {
+ newSize = size + 256;
+ entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
+ for (i = size; i < newSize; ++i) {
+ entries[i].offset = -1;
+ entries[i].used = gFalse;
+ }
+ size = newSize;
+ }
+ for (i = first; i < first + n; ++i) {
+ for (j = 0; j < 20; ++j) {
+ if ((c = str->getChar()) == EOF) {
+ goto err2;
+ }
+ s[j] = (char)c;
+ }
+ if (entries[i].offset < 0) {
+ s[10] = '\0';
+ entries[i].offset = atoi(s);
+ s[16] = '\0';
+ entries[i].gen = atoi(&s[11]);
+ if (s[17] == 'n') {
+ entries[i].used = gTrue;
+ } else if (s[17] == 'f') {
+ entries[i].used = gFalse;
+ } else {
+ goto err2;
+ }
+ // PDF files of patents from the IBM Intellectual Property
+ // Network have a bug: the xref table claims to start at 1
+ // instead of 0.
+ if (i == 1 && first == 1 &&
+ entries[1].offset == 0 && entries[1].gen == 65535 &&
+ !entries[1].used) {
+ i = first = 0;
+ entries[0] = entries[1];
+ entries[1].offset = -1;
+ }
+ }
+ }
+ }
+
+ // read prev pointer from trailer dictionary
+ obj.initNull();
+ parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(str->getPos(),
+ -1, &obj)));
+ parser->getObj(&obj);
+ if (!obj.isCmd("trailer")) {
+ goto err1;
+ }
+ obj.free();
+ parser->getObj(&obj);
+ if (!obj.isDict()) {
+ goto err1;
+ }
+ obj.getDict()->lookupNF("Prev", &obj2);
+ if (obj2.isInt()) {
+ *pos = obj2.getInt();
+ more = gTrue;
+ } else {
+ more = gFalse;
+ }
+ obj.free();
+ obj2.free();
+
+ delete parser;
+ return more;
+
+ err1:
+ obj.free();
+ err2:
+ ok = gFalse;
+ return gFalse;
+}
+
+// Attempt to construct an xref table for a damaged file.
+GBool XRef::constructXRef() {
+ Parser *parser;
+ Object obj;
+ char buf[256];
+ int pos;
+ int num, gen;
+ int newSize;
+ int streamEndsSize;
+ char *p;
+ int i;
+ GBool gotRoot;
+
+ error(0, "PDF file is damaged - attempting to reconstruct xref table...");
+ gotRoot = gFalse;
+ streamEndsLen = streamEndsSize = 0;
+
+ str->reset();
+ while (1) {
+ pos = str->getPos();
+ if (!str->getLine(buf, 256)) {
+ break;
+ }
+ p = buf;
+
+ // got trailer dictionary
+ if (!strncmp(p, "trailer", 7)) {
+ obj.initNull();
+ parser = new Parser(NULL, new Lexer(NULL,
+ str->makeSubStream(start + pos + 7, -1, &obj)));
+ if (!trailerDict.isNone())
+ trailerDict.free();
+ parser->getObj(&trailerDict);
+ if (trailerDict.isDict()) {
+ trailerDict.dictLookupNF("Root", &obj);
+ if (obj.isRef()) {
+ rootNum = obj.getRefNum();
+ rootGen = obj.getRefGen();
+ gotRoot = gTrue;
+ }
+ obj.free();
+ } else {
+ pos = 0;
+ }
+ delete parser;
+
+ // look for object
+ } else if (isdigit(*p)) {
+ num = atoi(p);
+ do {
+ ++p;
+ } while (*p && isdigit(*p));
+ if (isspace(*p)) {
+ do {
+ ++p;
+ } while (*p && isspace(*p));
+ if (isdigit(*p)) {
+ gen = atoi(p);
+ do {
+ ++p;
+ } while (*p && isdigit(*p));
+ if (isspace(*p)) {
+ do {
+ ++p;
+ } while (*p && isspace(*p));
+ if (!strncmp(p, "obj", 3)) {
+ if (num >= size) {
+ newSize = (num + 1 + 255) & ~255;
+ entries = (XRefEntry *)
+ grealloc(entries, newSize * sizeof(XRefEntry));
+ for (i = size; i < newSize; ++i) {
+ entries[i].offset = -1;
+ entries[i].used = gFalse;
+ }
+ size = newSize;
+ }
+ if (!entries[num].used || gen >= entries[num].gen) {
+ entries[num].offset = pos - start;
+ entries[num].gen = gen;
+ entries[num].used = gTrue;
+ }
+ }
+ }
+ }
+ }
+
+ } else if (!strncmp(p, "endstream", 9)) {
+ if (streamEndsLen == streamEndsSize) {
+ streamEndsSize += 64;
+ streamEnds = (int *)grealloc(streamEnds, streamEndsSize * sizeof(int));
+ }
+ streamEnds[streamEndsLen++] = pos;
+ }
+ }
+
+ if (gotRoot)
+ return gTrue;
+
+ error(-1, "Couldn't find trailer dictionary");
+ return gFalse;
+}
+
+#ifndef NO_DECRYPTION
+GBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) {
+ Object encrypt, filterObj, versionObj, revisionObj, lengthObj;
+ Object ownerKey, userKey, permissions, fileID, fileID1;
+ GBool encrypted1;
+ GBool ret;
+
+ ret = gFalse;
+
+ permFlags = defPermFlags;
+ trailerDict.dictLookup("Encrypt", &encrypt);
+ if ((encrypted1 = encrypt.isDict())) {
+ ret = gTrue;
+ encrypt.dictLookup("Filter", &filterObj);
+ if (filterObj.isName("Standard")) {
+ encrypt.dictLookup("V", &versionObj);
+ encrypt.dictLookup("R", &revisionObj);
+ encrypt.dictLookup("Length", &lengthObj);
+ encrypt.dictLookup("O", &ownerKey);
+ encrypt.dictLookup("U", &userKey);
+ encrypt.dictLookup("P", &permissions);
+ trailerDict.dictLookup("ID", &fileID);
+ if (versionObj.isInt() &&
+ revisionObj.isInt() &&
+ ownerKey.isString() && ownerKey.getString()->getLength() == 32 &&
+ userKey.isString() && userKey.getString()->getLength() == 32 &&
+ permissions.isInt() &&
+ fileID.isArray()) {
+ encVersion = versionObj.getInt();
+ encRevision = revisionObj.getInt();
+ if (lengthObj.isInt()) {
+ keyLength = lengthObj.getInt() / 8;
+ } else {
+ keyLength = 5;
+ }
+ permFlags = permissions.getInt();
+ if (encVersion >= 1 && encVersion <= 2 &&
+ encRevision >= 2 && encRevision <= 3) {
+ fileID.arrayGet(0, &fileID1);
+ if (fileID1.isString()) {
+ if (Decrypt::makeFileKey(encVersion, encRevision, keyLength,
+ ownerKey.getString(), userKey.getString(),
+ permFlags, fileID1.getString(),
+ ownerPassword, userPassword, fileKey,
+ &ownerPasswordOk)) {
+ if (ownerPassword && !ownerPasswordOk) {
+ error(-1, "Incorrect owner password");
+ }
+ ret = gFalse;
+ } else {
+ error(-1, "Incorrect password");
+ }
+ } else {
+ error(-1, "Weird encryption info");
+ }
+ fileID1.free();
+ } else {
+ error(-1, "Unsupported version/revision (%d/%d) of Standard security handler",
+ encVersion, encRevision);
+ }
+ } else {
+ error(-1, "Weird encryption info");
+ }
+ fileID.free();
+ permissions.free();
+ userKey.free();
+ ownerKey.free();
+ lengthObj.free();
+ revisionObj.free();
+ versionObj.free();
+ } else {
+ error(-1, "Unknown security handler '%s'",
+ filterObj.isName() ? filterObj.getName() : "???");
+ }
+ filterObj.free();
+ }
+ encrypt.free();
+
+ // this flag has to be set *after* we read the O/U/P strings
+ encrypted = encrypted1;
+
+ return ret;
+}
+#else
+GBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) {
+ Object obj;
+ GBool encrypted;
+
+ trailerDict.dictLookup("Encrypt", &obj);
+ if ((encrypted = !obj.isNull())) {
+ error(-1, "PDF file is encrypted and this version of the Xpdf tools");
+ error(-1, "was built without decryption support.");
+ }
+ obj.free();
+ return encrypted;
+}
+#endif
+
+GBool XRef::okToPrint(GBool ignoreOwnerPW) {
+#ifndef NO_DECRYPTION
+ if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permPrint)) {
+ return gFalse;
+ }
+#endif
+ return gTrue;
+}
+
+GBool XRef::okToChange(GBool ignoreOwnerPW) {
+#ifndef NO_DECRYPTION
+ if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permChange)) {
+ return gFalse;
+ }
+#endif
+ return gTrue;
+}
+
+GBool XRef::okToCopy(GBool ignoreOwnerPW) {
+#ifndef NO_DECRYPTION
+ if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permCopy)) {
+ return gFalse;
+ }
+#endif
+ return gTrue;
+}
+
+GBool XRef::okToAddNotes(GBool ignoreOwnerPW) {
+#ifndef NO_DECRYPTION
+ if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permNotes)) {
+ return gFalse;
+ }
+#endif
+ return gTrue;
+}
+
+Object *XRef::fetch(int num, int gen, Object *obj) {
+ XRefEntry *e;
+ Parser *parser;
+ Object obj1, obj2, obj3;
+
+ // check for bogus ref - this can happen in corrupted PDF files
+ if (num < 0 || num >= size) {
+ obj->initNull();
+ return obj;
+ }
+
+ e = &entries[num];
+ if (e->gen == gen && e->offset >= 0) {
+ obj1.initNull();
+ parser = new Parser(this, new Lexer(this,
+ str->makeSubStream(start + e->offset, -1, &obj1)));
+ parser->getObj(&obj1);
+ parser->getObj(&obj2);
+ parser->getObj(&obj3);
+ if (obj1.isInt() && obj1.getInt() == num &&
+ obj2.isInt() && obj2.getInt() == gen &&
+ obj3.isCmd("obj")) {
+#ifndef NO_DECRYPTION
+ parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength,
+ num, gen);
+#else
+ parser->getObj(obj);
+#endif
+ } else {
+ obj->initNull();
+ }
+ obj1.free();
+ obj2.free();
+ obj3.free();
+ delete parser;
+ } else {
+ obj->initNull();
+ }
+ return obj;
+}
+
+Object *XRef::getDocInfo(Object *obj) {
+ return trailerDict.dictLookup("Info", obj);
+}
+
+int XRef::getStreamEnd(int streamStart) {
+ int a, b, m;
+
+ if (streamEndsLen == 0 ||
+ streamStart > streamEnds[streamEndsLen - 1]) {
+ return -1;
+ }
+
+ a = -1;
+ b = streamEndsLen - 1;
+ // invariant: streamEnds[a] < streamStart <= streamEnds[b]
+ while (b - a > 1) {
+ m = (a + b) / 2;
+ if (streamStart <= streamEnds[m]) {
+ b = m;
+ } else {
+ a = m;
+ }
+ }
+ return streamEnds[b];
+}
diff --git a/pdftops/XRef.h b/pdftops/XRef.h
new file mode 100644
index 000000000..35306bba8
--- /dev/null
+++ b/pdftops/XRef.h
@@ -0,0 +1,110 @@
+//========================================================================
+//
+// XRef.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef XREF_H
+#define XREF_H
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#include "gtypes.h"
+#include "Object.h"
+
+class Dict;
+class Stream;
+
+//------------------------------------------------------------------------
+// XRef
+//------------------------------------------------------------------------
+
+struct XRefEntry {
+ int offset;
+ int gen;
+ GBool used;
+};
+
+class XRef {
+public:
+
+ // Constructor. Read xref table from stream.
+ XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword);
+
+ // Destructor.
+ ~XRef();
+
+ // Is xref table valid?
+ GBool isOk() { return ok; }
+
+ // Is the file encrypted?
+#ifndef NO_DECRYPTION
+ GBool isEncrypted() { return encrypted; }
+#else
+ GBool isEncrypted() { return gFalse; }
+#endif
+
+ // Check various permissions.
+ GBool okToPrint(GBool ignoreOwnerPW = gFalse);
+ GBool okToChange(GBool ignoreOwnerPW = gFalse);
+ GBool okToCopy(GBool ignoreOwnerPW = gFalse);
+ GBool okToAddNotes(GBool ignoreOwnerPW = gFalse);
+
+ // Get catalog object.
+ Object *getCatalog(Object *obj) { return fetch(rootNum, rootGen, obj); }
+
+ // Fetch an indirect reference.
+ Object *fetch(int num, int gen, Object *obj);
+
+ // Return the document's Info dictionary (if any).
+ Object *getDocInfo(Object *obj);
+
+ // Return the number of objects in the xref table.
+ int getNumObjects() { return size; }
+
+ // Return the offset of the last xref table.
+ int getLastXRefPos() { return lastXRefPos; }
+
+ // Return the catalog object reference.
+ int getRootNum() { return rootNum; }
+ int getRootGen() { return rootGen; }
+
+ // Get end position for a stream in a damaged file.
+ // Returns -1 if unknown or file is not damaged.
+ int getStreamEnd(int streamStart);
+
+private:
+
+ BaseStream *str; // input stream
+ int start; // offset in file (to allow for garbage
+ // at beginning of file)
+ XRefEntry *entries; // xref entries
+ int size; // size of <entries> array
+ int rootNum, rootGen; // catalog dict
+ GBool ok; // true if xref table is valid
+ Object trailerDict; // trailer dictionary
+ int lastXRefPos; // offset of last xref table
+ int *streamEnds; // 'endstream' positions - only used in
+ // damaged files
+ int streamEndsLen; // number of valid entries in streamEnds
+#ifndef NO_DECRYPTION
+ GBool encrypted; // true if file is encrypted
+ int encVersion; // encryption algorithm
+ int encRevision; // security handler revision
+ int keyLength; // length of key, in bytes
+ int permFlags; // permission bits
+ Guchar fileKey[16]; // file decryption key
+ GBool ownerPasswordOk; // true if owner password is correct
+#endif
+
+ int readTrailer();
+ GBool readXRef(int *pos);
+ GBool constructXRef();
+ GBool checkEncrypted(GString *ownerPassword, GString *userPassword);
+};
+
+#endif
diff --git a/pdftops/config.h b/pdftops/config.h
new file mode 100644
index 000000000..c88c6694c
--- /dev/null
+++ b/pdftops/config.h
@@ -0,0 +1,140 @@
+//========================================================================
+//
+// config.h
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "../config.h"
+#define HAVE_LIBCUPS
+
+//------------------------------------------------------------------------
+// general constants
+//------------------------------------------------------------------------
+
+// xpdf version
+#define xpdfVersion "0.93a"
+
+// supported PDF version
+#define supportedPDFVersionStr "1.4"
+#define supportedPDFVersionNum 1.4
+
+// copyright notice
+#define xpdfCopyright "Copyright 1996-2002 Derek B. Noonburg"
+
+// default paper size (in points) for PostScript output
+#ifdef A4_PAPER
+#define defPaperWidth 595 // ISO A4 (210x297 mm)
+#define defPaperHeight 842
+#else
+#define defPaperWidth 612 // American letter (8.5x11")
+#define defPaperHeight 792
+#endif
+
+// user config file name, relative to the user's home directory
+#if defined(VMS)
+#define xpdfUserConfigFile "xpdfrc"
+#else
+#define xpdfUserConfigFile ".xpdfrc"
+#endif
+
+#ifndef SYSTEM_XPDFRC
+# define SYSTEM_XPDFRC CUPS_SERVERROOT "/pdftops.conf"
+#endif // SYSTEM_XPDFRC
+
+// system config file name (set via the configure script)
+#define xpdfSysConfigFile SYSTEM_XPDFRC
+
+// Support Unicode/etc.
+//
+// The IBM AIX GNUPro compilers seem not to like the Asian font
+// code, causing a "virtual memory exhausted" error. Only support
+// Asian fonts on platforms that will compile it...
+
+#if !defined(_AIX) || __GNUC__ != 2 || __GNUC_MINOR__ != 9
+# define JAPANESE_SUPPORT 1
+# define CHINESE_GB_SUPPORT 1
+# define CHINESE_CNS_SUPPORT 1
+#endif // !_AIX || !GCC 2.9
+
+//------------------------------------------------------------------------
+// X-related constants
+//------------------------------------------------------------------------
+
+// default maximum size of color cube to allocate
+#define defaultRGBCube 5
+
+// number of X server fonts to cache
+#define serverFontCacheSize 16
+
+// number of Type 1 (t1lib) fonts to cache
+#define t1FontCacheSize 32
+
+// number of TrueType (FreeType) fonts to cache
+#define ttFontCacheSize 32
+
+// number of FreeType (TrueType and Type 1) fonts to cache
+#define ftFontCacheSize 32
+
+//------------------------------------------------------------------------
+// popen
+//------------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#define popen _popen
+#define pclose _pclose
+#endif
+
+#if defined(VMS) || defined(VMCMS) || defined(DOS) || defined(OS2) || defined(__EMX__) || defined(WIN32) || defined(__DJGPP__) || defined(__CYGWIN32__) || defined(MACOS)
+#define POPEN_READ_MODE "rb"
+#else
+#define POPEN_READ_MODE "r"
+#endif
+
+//------------------------------------------------------------------------
+// uncompress program
+//------------------------------------------------------------------------
+
+#ifdef HAVE_POPEN
+
+// command to uncompress to stdout
+# ifdef USE_GZIP
+# define uncompressCmd "gzip -d -c -q"
+# else
+# ifdef __EMX__
+# define uncompressCmd "compress -d -c"
+# else
+# define uncompressCmd "uncompress -c"
+# endif // __EMX__
+# endif // USE_GZIP
+
+#else // HAVE_POPEN
+
+// command to uncompress a file
+# ifdef USE_GZIP
+# define uncompressCmd "gzip -d -q"
+# else
+# define uncompressCmd "uncompress"
+# endif // USE_GZIP
+
+#endif // HAVE_POPEN
+
+//------------------------------------------------------------------------
+// Win32 stuff
+//------------------------------------------------------------------------
+
+#ifdef CDECL
+#undef CDECL
+#endif
+
+#ifdef _MSC_VER
+#define CDECL __cdecl
+#else
+#define CDECL
+#endif
+
+#endif
diff --git a/pdftops/gfile.cxx b/pdftops/gfile.cxx
new file mode 100644
index 000000000..e6428b71b
--- /dev/null
+++ b/pdftops/gfile.cxx
@@ -0,0 +1,678 @@
+//========================================================================
+//
+// gfile.cc
+//
+// Miscellaneous file and directory name manipulation.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifdef WIN32
+ extern "C" {
+# ifndef _MSC_VER
+# include <kpathsea/win32lib.h>
+# endif
+ }
+#else // !WIN32
+# if defined(MACOS)
+# include <sys/stat.h>
+# elif !defined(ACORN)
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# endif
+# include <limits.h>
+# include <string.h>
+# if !defined(VMS) && !defined(ACORN) && !defined(MACOS)
+# include <pwd.h>
+# endif
+# if defined(VMS) && (__DECCXX_VER < 50200000)
+# include <unixlib.h>
+# endif
+#endif // WIN32
+#include "GString.h"
+#include "gfile.h"
+
+#ifdef HAVE_LIBCUPS
+# include <cups/cups.h>
+#endif // HAVE_LIBCUPS
+
+#ifdef __sun
+// Solaris doesn't define mkstemp()...
+extern "C" {
+extern int mkstemp(char *);
+}
+#endif // __sun
+
+// Some systems don't define this, so just make it something reasonably
+// large.
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+//------------------------------------------------------------------------
+
+GString *getHomeDir() {
+#ifdef VMS
+ //---------- VMS ----------
+ return new GString("SYS$LOGIN:");
+
+#elif defined(__EMX__) || defined(WIN32)
+ //---------- OS/2+EMX and Win32 ----------
+ char *s;
+ GString *ret;
+
+ if ((s = getenv("HOME")))
+ ret = new GString(s);
+ else
+ ret = new GString(".");
+ return ret;
+
+#elif defined(ACORN)
+ //---------- RISCOS ----------
+ return new GString("@");
+
+#elif defined(MACOS)
+ //---------- MacOS ----------
+ return new GString(":");
+
+#else
+ //---------- Unix ----------
+ char *s;
+ struct passwd *pw;
+ GString *ret;
+
+ if ((s = getenv("HOME"))) {
+ ret = new GString(s);
+# ifdef HAVE_LIBCUPS
+ } else if ((s = getenv("CUPS_SERVERROOT"))) {
+ ret = new GString(s);
+# endif // HAVE_LIBCUPS
+ } else {
+ if ((s = getenv("USER")))
+ pw = getpwnam(s);
+ else
+ pw = getpwuid(getuid());
+ if (pw)
+ ret = new GString(pw->pw_dir);
+ else
+ ret = new GString(".");
+ }
+ return ret;
+#endif
+}
+
+GString *getCurrentDir() {
+ char buf[PATH_MAX+1];
+
+#if defined(__EMX__)
+ if (_getcwd2(buf, sizeof(buf)))
+#elif defined(WIN32)
+ if (GetCurrentDirectory(sizeof(buf), buf))
+#elif defined(ACORN)
+ if (strcpy(buf, "@"))
+#elif defined(MACOS)
+ if (strcpy(buf, ":"))
+#else
+ if (getcwd(buf, sizeof(buf)))
+#endif
+ return new GString(buf);
+ return new GString();
+}
+
+GString *appendToPath(GString *path, const char *fileName) {
+#if defined(VMS)
+ //---------- VMS ----------
+ //~ this should handle everything necessary for file
+ //~ requesters, but it's certainly not complete
+ char *p0, *p1, *p2;
+ char *q1;
+
+ p0 = path->getCString();
+ p1 = p0 + path->getLength() - 1;
+ if (!strcmp(fileName, "-")) {
+ if (*p1 == ']') {
+ for (p2 = p1; p2 > p0 && *p2 != '.' && *p2 != '['; --p2) ;
+ if (*p2 == '[')
+ ++p2;
+ path->del(p2 - p0, p1 - p2);
+ } else if (*p1 == ':') {
+ path->append("[-]");
+ } else {
+ path->clear();
+ path->append("[-]");
+ }
+ } else if ((q1 = strrchr(fileName, '.')) && !strncmp(q1, ".DIR;", 5)) {
+ if (*p1 == ']') {
+ path->insert(p1 - p0, '.');
+ path->insert(p1 - p0 + 1, fileName, q1 - fileName);
+ } else if (*p1 == ':') {
+ path->append('[');
+ path->append(']');
+ path->append(fileName, q1 - fileName);
+ } else {
+ path->clear();
+ path->append(fileName, q1 - fileName);
+ }
+ } else {
+ if (*p1 != ']' && *p1 != ':')
+ path->clear();
+ path->append(fileName);
+ }
+ return path;
+
+#elif defined(WIN32)
+ //---------- Win32 ----------
+ GString *tmp;
+ char buf[256];
+ char *fp;
+
+ tmp = new GString(path);
+ tmp->append('/');
+ tmp->append(fileName);
+ GetFullPathName(tmp->getCString(), sizeof(buf), buf, &fp);
+ delete tmp;
+ path->clear();
+ path->append(buf);
+ return path;
+
+#elif defined(ACORN)
+ //---------- RISCOS ----------
+ char *p;
+ int i;
+
+ path->append(".");
+ i = path->getLength();
+ path->append(fileName);
+ for (p = path->getCString() + i; *p; ++p) {
+ if (*p == '/') {
+ *p = '.';
+ } else if (*p == '.') {
+ *p = '/';
+ }
+ }
+ return path;
+
+#elif defined(MACOS)
+ //---------- MacOS ----------
+ char *p;
+ int i;
+
+ path->append(":");
+ i = path->getLength();
+ path->append(fileName);
+ for (p = path->getCString() + i; *p; ++p) {
+ if (*p == '/') {
+ *p = ':';
+ } else if (*p == '.') {
+ *p = ':';
+ }
+ }
+ return path;
+
+#elif defined(__EMX__)
+ //---------- OS/2+EMX ----------
+ int i;
+
+ // appending "." does nothing
+ if (!strcmp(fileName, "."))
+ return path;
+
+ // appending ".." goes up one directory
+ if (!strcmp(fileName, "..")) {
+ for (i = path->getLength() - 2; i >= 0; --i) {
+ if (path->getChar(i) == '/' || path->getChar(i) == '\\' ||
+ path->getChar(i) == ':')
+ break;
+ }
+ if (i <= 0) {
+ if (path->getChar(0) == '/' || path->getChar(0) == '\\') {
+ path->del(1, path->getLength() - 1);
+ } else if (path->getLength() >= 2 && path->getChar(1) == ':') {
+ path->del(2, path->getLength() - 2);
+ } else {
+ path->clear();
+ path->append("..");
+ }
+ } else {
+ if (path->getChar(i-1) == ':')
+ ++i;
+ path->del(i, path->getLength() - i);
+ }
+ return path;
+ }
+
+ // otherwise, append "/" and new path component
+ if (path->getLength() > 0 &&
+ path->getChar(path->getLength() - 1) != '/' &&
+ path->getChar(path->getLength() - 1) != '\\')
+ path->append('/');
+ path->append(fileName);
+ return path;
+
+#else
+ //---------- Unix ----------
+ int i;
+
+ // appending "." does nothing
+ if (!strcmp(fileName, "."))
+ return path;
+
+ // appending ".." goes up one directory
+ if (!strcmp(fileName, "..")) {
+ for (i = path->getLength() - 2; i >= 0; --i) {
+ if (path->getChar(i) == '/')
+ break;
+ }
+ if (i <= 0) {
+ if (path->getChar(0) == '/') {
+ path->del(1, path->getLength() - 1);
+ } else {
+ path->clear();
+ path->append("..");
+ }
+ } else {
+ path->del(i, path->getLength() - i);
+ }
+ return path;
+ }
+
+ // otherwise, append "/" and new path component
+ if (path->getLength() > 0 &&
+ path->getChar(path->getLength() - 1) != '/')
+ path->append('/');
+ path->append(fileName);
+ return path;
+#endif
+}
+
+GString *grabPath(const char *fileName) {
+#ifdef VMS
+ //---------- VMS ----------
+ const char *p;
+
+ if ((p = strrchr(fileName, ']')))
+ return new GString(fileName, p + 1 - fileName);
+ if ((p = strrchr(fileName, ':')))
+ return new GString(fileName, p + 1 - fileName);
+ return new GString();
+
+#elif defined(__EMX__) || defined(WIN32)
+ //---------- OS/2+EMX and Win32 ----------
+ const char *p;
+
+ if ((p = strrchr(fileName, '/')))
+ return new GString(fileName, p - fileName);
+ if ((p = strrchr(fileName, '\\')))
+ return new GString(fileName, p - fileName);
+ if ((p = strrchr(fileName, ':')))
+ return new GString(fileName, p + 1 - fileName);
+ return new GString();
+
+#elif defined(ACORN)
+ //---------- RISCOS ----------
+ const char *p;
+
+ if ((p = strrchr(fileName, '.')))
+ return new GString(fileName, p - fileName);
+ return new GString();
+
+#elif defined(MACOS)
+ //---------- MacOS ----------
+ const char *p;
+
+ if ((p = strrchr(fileName, ':')))
+ return new GString(fileName, p - fileName);
+ return new GString();
+
+#else
+ //---------- Unix ----------
+ const char *p;
+
+ if ((p = strrchr(fileName, '/')))
+ return new GString(fileName, p - fileName);
+ return new GString();
+#endif
+}
+
+GBool isAbsolutePath(const char *path) {
+#ifdef VMS
+ //---------- VMS ----------
+ return strchr(path, ':') ||
+ (path[0] == '[' && path[1] != '.' && path[1] != '-');
+
+#elif defined(__EMX__) || defined(WIN32)
+ //---------- OS/2+EMX and Win32 ----------
+ return path[0] == '/' || path[0] == '\\' || path[1] == ':';
+
+#elif defined(ACORN)
+ //---------- RISCOS ----------
+ return path[0] == '$';
+
+#elif defined(MACOS)
+ //---------- MacOS ----------
+ return path[0] != ':';
+
+#else
+ //---------- Unix ----------
+ return path[0] == '/';
+#endif
+}
+
+GString *makePathAbsolute(GString *path) {
+#ifdef VMS
+ //---------- VMS ----------
+ char buf[PATH_MAX+1];
+
+ if (!isAbsolutePath(path->getCString())) {
+ if (getcwd(buf, sizeof(buf))) {
+ path->insert(0, buf);
+ }
+ }
+ return path;
+
+#elif defined(WIN32)
+ //---------- Win32 ----------
+ char buf[_MAX_PATH];
+ char *fp;
+
+ buf[0] = '\0';
+ if (!GetFullPathName(path->getCString(), _MAX_PATH, buf, &fp)) {
+ path->clear();
+ return path;
+ }
+ path->clear();
+ path->append(buf);
+ return path;
+
+#elif defined(ACORN)
+ //---------- RISCOS ----------
+ path->insert(0, '@');
+ return path;
+
+#elif defined(MACOS)
+ //---------- MacOS ----------
+ path->del(0, 1);
+ return path;
+
+#else
+ //---------- Unix and OS/2+EMX ----------
+ struct passwd *pw;
+ char buf[PATH_MAX+1];
+ GString *s;
+ char *p1, *p2;
+ int n;
+
+ if (path->getChar(0) == '~') {
+ if (path->getChar(1) == '/' ||
+#ifdef __EMX__
+ path->getChar(1) == '\\' ||
+#endif
+ path->getLength() == 1) {
+ path->del(0, 1);
+ s = getHomeDir();
+ path->insert(0, s);
+ delete s;
+ } else {
+ p1 = path->getCString() + 1;
+#ifdef __EMX__
+ for (p2 = p1; *p2 && *p2 != '/' && *p2 != '\\'; ++p2) ;
+#else
+ for (p2 = p1; *p2 && *p2 != '/'; ++p2) ;
+#endif
+ if ((n = p2 - p1) > PATH_MAX)
+ n = PATH_MAX;
+ strncpy(buf, p1, n);
+ buf[n] = '\0';
+ if ((pw = getpwnam(buf))) {
+ path->del(0, p2 - p1 + 1);
+ path->insert(0, pw->pw_dir);
+ }
+ }
+ } else if (!isAbsolutePath(path->getCString())) {
+ if (getcwd(buf, sizeof(buf))) {
+#ifndef __EMX__
+ path->insert(0, '/');
+#endif
+ path->insert(0, buf);
+ }
+ }
+ return path;
+#endif
+}
+
+time_t getModTime(const char *fileName) {
+#ifdef WIN32
+ //~ should implement this, but it's (currently) only used in xpdf
+ return 0;
+#else
+ struct stat statBuf;
+
+ if (stat(fileName, &statBuf)) {
+ return 0;
+ }
+ return statBuf.st_mtime;
+#endif
+}
+
+GBool openTempFile(GString **name, FILE **f, const char *mode, const char *ext) {
+#if defined(VMS) || defined(__EMX__) || defined(WIN32) || defined(ACORN) || defined(MACOS)
+ //---------- non-Unix ----------
+ char *s;
+
+ // There is a security hole here: an attacker can create a symlink
+ // with this file name after the tmpnam call and before the fopen
+ // call. I will happily accept fixes to this function for non-Unix
+ // OSs.
+ if (!(s = tmpnam(NULL))) {
+ return gFalse;
+ }
+ *name = new GString(s);
+ if (ext) {
+ (*name)->append(ext);
+ }
+ if (!(*f = fopen((*name)->getCString(), mode))) {
+ delete (*name);
+ return gFalse;
+ }
+ return gTrue;
+#else
+ //---------- Unix ----------
+ char *s;
+ int fd;
+
+ // MRS: Currently there is no standard function for creating a temporary
+ // file with an extension; this is required when uncompressing
+ // LZW data using the uncompress program on some UNIX, which is
+ // looking for a ".Z" extension on the temporary filename. Sooo,
+ // when you print an *OLD* PDF file that uses LZW compression,
+ // the tmpnam() function is usually the one that is called to
+ // create the temporary file. Under *BSD, the safer mkstemps()
+ // function is used instead.
+ //
+ // That said, all CUPS filters are run with TMPDIR pointing to
+ // a private temporary directory, which by default is only
+ // accessible to the 'lp' user. Also, most files use Flate
+ // compression now and will be able to use the (safer)
+ // mkstemp() function for any temporary files...
+
+ if (ext) {
+# if HAVE_MKSTEMPS
+ if ((s = getenv("TMPDIR"))) {
+ *name = new GString(s);
+ } else {
+ *name = new GString("/tmp");
+ }
+ (*name)->append("/XXXXXX");
+ (*name)->append(ext);
+ fd = mkstemps((*name)->getCString(), strlen(ext));
+# else // HAVE_MKSTEMPS
+ char *p;
+ if (!(s = tmpnam(NULL))) {
+ return gFalse;
+ }
+ *name = new GString(s);
+ s = (*name)->getCString();
+ if ((p = strrchr(s, '.'))) {
+ (*name)->del(p - s, (*name)->getLength() - (p - s));
+ }
+ (*name)->append(ext);
+ fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600);
+# endif // HAVE_MKSTEMPS
+ } else {
+# if HAVE_MKSTEMP
+ if ((s = getenv("TMPDIR"))) {
+ *name = new GString(s);
+ } else {
+ *name = new GString("/tmp");
+ }
+ (*name)->append("/XXXXXX");
+ fd = mkstemp((*name)->getCString());
+# else // HAVE_MKSTEMP
+ if (!(s = tmpnam(NULL))) {
+ return gFalse;
+ }
+ *name = new GString(s);
+ fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600);
+# endif // HAVE_MKSTEMP
+ }
+ if (fd < 0 || !(*f = fdopen(fd, mode))) {
+ delete *name;
+ return gFalse;
+ }
+ return gTrue;
+#endif
+}
+
+//------------------------------------------------------------------------
+// GDir and GDirEntry
+//------------------------------------------------------------------------
+
+GDirEntry::GDirEntry(const char *dirPath, const char *name1, GBool doStat) {
+#ifdef VMS
+ char *p;
+#elif defined(WIN32)
+ int fa;
+ GString *s;
+#elif defined(ACORN)
+#else
+ struct stat st;
+ GString *s;
+#endif
+
+ name = new GString(name1);
+ dir = gFalse;
+ if (doStat) {
+#ifdef VMS
+ if (!strcmp(name1, "-") ||
+ ((p = strrchr(name1, '.')) && !strncmp(p, ".DIR;", 5)))
+ dir = gTrue;
+#elif defined(ACORN)
+#else
+ s = new GString(dirPath);
+ appendToPath(s, name1);
+#ifdef WIN32
+ fa = GetFileAttributes(s->getCString());
+ dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY));
+#else
+ if (stat(s->getCString(), &st) == 0)
+ dir = S_ISDIR(st.st_mode);
+#endif
+ delete s;
+#endif
+ }
+}
+
+GDirEntry::~GDirEntry() {
+ delete name;
+}
+
+GDir::GDir(const char *name, GBool doStat1) {
+ path = new GString(name);
+ doStat = doStat1;
+#if defined(WIN32)
+ GString *tmp;
+
+ tmp = path->copy();
+ tmp->append("/*.*");
+ hnd = FindFirstFile(tmp->getCString(), &ffd);
+ delete tmp;
+#elif defined(ACORN)
+#elif defined(MACOS)
+#else
+ dir = opendir(name);
+#ifdef VMS
+ needParent = strchr(name, '[') != NULL;
+#endif
+#endif
+}
+
+GDir::~GDir() {
+ delete path;
+#if defined(WIN32)
+ if (hnd) {
+ FindClose(hnd);
+ hnd = NULL;
+ }
+#elif defined(ACORN)
+#elif defined(MACOS)
+#else
+ if (dir)
+ closedir(dir);
+#endif
+}
+
+GDirEntry *GDir::getNextEntry() {
+ struct dirent *ent;
+ GDirEntry *e;
+
+ e = NULL;
+#if defined(WIN32)
+ e = new GDirEntry(path->getCString(), ffd.cFileName, doStat);
+ if (hnd && !FindNextFile(hnd, &ffd)) {
+ FindClose(hnd);
+ hnd = NULL;
+ }
+#elif defined(ACORN)
+#elif defined(MACOS)
+#else
+ if (dir) {
+#ifdef VMS
+ if (needParent) {
+ e = new GDirEntry(path->getCString(), "-", doStat);
+ needParent = gFalse;
+ return e;
+ }
+#endif
+ ent = readdir(dir);
+#ifndef VMS
+ if (ent && !strcmp(ent->d_name, "."))
+ ent = readdir(dir);
+#endif
+ if (ent)
+ e = new GDirEntry(path->getCString(), ent->d_name, doStat);
+ }
+#endif
+ return e;
+}
+
+void GDir::rewind() {
+#ifdef WIN32
+ GString *tmp;
+
+ if (hnd)
+ FindClose(hnd);
+ tmp = path->copy();
+ tmp->append("/*.*");
+ hnd = FindFirstFile(tmp->getCString(), &ffd);
+#elif defined(ACORN)
+#elif defined(MACOS)
+#else
+ if (dir)
+ rewinddir(dir);
+#ifdef VMS
+ needParent = strchr(path->getCString(), '[') != NULL;
+#endif
+#endif
+}
diff --git a/pdftops/gfile.h b/pdftops/gfile.h
new file mode 100644
index 000000000..49c6888ca
--- /dev/null
+++ b/pdftops/gfile.h
@@ -0,0 +1,132 @@
+//========================================================================
+//
+// gfile.h
+//
+// Miscellaneous file and directory name manipulation.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#ifndef GFILE_H
+#define GFILE_H
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#if defined(WIN32)
+# include <sys/stat.h>
+# ifdef FPTEX
+# include <win32lib.h>
+# else
+# include <windows.h>
+# endif
+#elif defined(ACORN)
+#elif defined(MACOS)
+# include <ctime.h>
+#else
+# include <unistd.h>
+# include <sys/types.h>
+# ifdef VMS
+# include "vms_dirent.h"
+# elif HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(d) strlen((d)->d_name)
+# else
+# define dirent direct
+# define NAMLEN(d) (d)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+# endif
+#endif
+#include "gtypes.h"
+
+class GString;
+
+//------------------------------------------------------------------------
+
+// Get home directory path.
+extern GString *getHomeDir();
+
+// Get current directory.
+extern GString *getCurrentDir();
+
+// Append a file name to a path string. <path> may be an empty
+// string, denoting the current directory). Returns <path>.
+extern GString *appendToPath(GString *path, const char *fileName);
+
+// Grab the path from the front of the file name. If there is no
+// directory component in <fileName>, returns an empty string.
+extern GString *grabPath(const char *fileName);
+
+// Is this an absolute path or file name?
+extern GBool isAbsolutePath(const char *path);
+
+// Make this path absolute by prepending current directory (if path is
+// relative) or prepending user's directory (if path starts with '~').
+GString *makePathAbsolute(GString *path);
+
+// Get the modification time for <fileName>. Returns 0 if there is an
+// error.
+time_t getModTime(const char *fileName);
+
+// Create a temporary file and open it for writing. If <ext> is not
+// NULL, it will be used as the file name extension. Returns both the
+// name and the file pointer. For security reasons, all writing
+// should be done to the returned file pointer; the file may be
+// reopened later for reading, but not for writing. The <mode> string
+// should be "w" or "wb". Returns true on success.
+GBool openTempFile(GString **name, FILE **f, const char *mode, const char *ext);
+
+//------------------------------------------------------------------------
+// GDir and GDirEntry
+//------------------------------------------------------------------------
+
+class GDirEntry {
+public:
+
+ GDirEntry(const char *dirPath, const char *name1, GBool doStat);
+ ~GDirEntry();
+ GString *getName() { return name; }
+ GBool isDir() { return dir; }
+
+private:
+
+ GString *name; // dir/file name
+ GBool dir; // is it a directory?
+};
+
+class GDir {
+public:
+
+ GDir(const char *name, GBool doStat1 = gTrue);
+ ~GDir();
+ GDirEntry *getNextEntry();
+ void rewind();
+
+private:
+
+ GString *path; // directory path
+ GBool doStat; // call stat() for each entry?
+#if defined(WIN32)
+ WIN32_FIND_DATA ffd;
+ HANDLE hnd;
+#elif defined(ACORN)
+#elif defined(MACOS)
+#else
+ DIR *dir; // the DIR structure from opendir()
+#ifdef VMS
+ GBool needParent; // need to return an entry for [-]
+#endif
+#endif
+};
+
+#endif
diff --git a/pdftops/gmem.c b/pdftops/gmem.c
new file mode 100644
index 000000000..5b3743db3
--- /dev/null
+++ b/pdftops/gmem.c
@@ -0,0 +1,203 @@
+/*
+ * gmem.c
+ *
+ * Memory routines with out-of-memory checking.
+ *
+ * Copyright 1996 Derek B. Noonburg
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include "gmem.h"
+
+#ifdef DEBUG_MEM
+
+typedef struct _GMemHdr {
+ int size;
+ int index;
+ struct _GMemHdr *next;
+} GMemHdr;
+
+#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
+#define gMemTrlSize (sizeof(long))
+
+#if gmemTrlSize==8
+#define gMemDeadVal 0xdeadbeefdeadbeef
+#else
+#define gMemDeadVal 0xdeadbeef
+#endif
+
+/* round data size so trailer will be aligned */
+#define gMemDataSize(size) \
+ ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
+
+#define gMemNLists 64
+#define gMemListShift 4
+#define gMemListMask (gMemNLists - 1)
+static GMemHdr *gMemList[gMemNLists] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+static int gMemIndex = 0;
+static int gMemAlloc = 0;
+
+#endif /* DEBUG_MEM */
+
+void *gmalloc(int size) {
+#ifdef DEBUG_MEM
+ int size1;
+ char *mem;
+ GMemHdr *hdr;
+ void *data;
+ int lst;
+ long *trl, *p;
+
+ if (size == 0)
+ return NULL;
+ size1 = gMemDataSize(size);
+ if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ hdr = (GMemHdr *)mem;
+ data = (void *)(mem + gMemHdrSize);
+ trl = (long *)(mem + gMemHdrSize + size1);
+ hdr->size = size;
+ hdr->index = gMemIndex++;
+ lst = ((int)hdr >> gMemListShift) & gMemListMask;
+ hdr->next = gMemList[lst];
+ gMemList[lst] = hdr;
+ ++gMemAlloc;
+ for (p = (long *)data; p <= trl; ++p)
+ *p = gMemDeadVal;
+ return data;
+#else
+ void *p;
+
+ if (size == 0)
+ return NULL;
+ if (!(p = malloc(size))) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ return p;
+#endif
+}
+
+void *grealloc(void *p, int size) {
+#ifdef DEBUG_MEM
+ GMemHdr *hdr;
+ void *q;
+ int oldSize;
+
+ if (size == 0) {
+ if (p)
+ gfree(p);
+ return NULL;
+ }
+ if (p) {
+ hdr = (GMemHdr *)((char *)p - gMemHdrSize);
+ oldSize = hdr->size;
+ q = gmalloc(size);
+ memcpy(q, p, size < oldSize ? size : oldSize);
+ gfree(p);
+ } else {
+ q = gmalloc(size);
+ }
+ return q;
+#else
+ void *q;
+
+ if (size == 0) {
+ if (p)
+ free(p);
+ return NULL;
+ }
+ if (p)
+ q = realloc(p, size);
+ else
+ q = malloc(size);
+ if (!q) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ return q;
+#endif
+}
+
+void gfree(void *p) {
+#ifdef DEBUG_MEM
+ int size;
+ GMemHdr *hdr;
+ GMemHdr *prevHdr, *q;
+ int lst;
+ long *trl, *clr;
+
+ if (p) {
+ hdr = (GMemHdr *)((char *)p - gMemHdrSize);
+ lst = ((int)hdr >> gMemListShift) & gMemListMask;
+ for (prevHdr = NULL, q = gMemList[lst]; q; prevHdr = q, q = q->next) {
+ if (q == hdr)
+ break;
+ }
+ if (q) {
+ if (prevHdr)
+ prevHdr->next = hdr->next;
+ else
+ gMemList[lst] = hdr->next;
+ --gMemAlloc;
+ size = gMemDataSize(hdr->size);
+ trl = (long *)((char *)hdr + gMemHdrSize + size);
+ if (*trl != gMemDeadVal) {
+ fprintf(stderr, "Overwrite past end of block %d at address %p\n",
+ hdr->index, p);
+ }
+ for (clr = (long *)hdr; clr <= trl; ++clr)
+ *clr = gMemDeadVal;
+ free(hdr);
+ } else {
+ fprintf(stderr, "Attempted to free bad address %p\n", p);
+ }
+ }
+#else
+ if (p)
+ free(p);
+#endif
+}
+
+#ifdef DEBUG_MEM
+void gMemReport(FILE *f) {
+ GMemHdr *p;
+ int lst;
+
+ fprintf(f, "%d memory allocations in all\n", gMemIndex);
+ if (gMemAlloc > 0) {
+ fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
+ fprintf(f, " index size\n");
+ fprintf(f, "-------- --------\n");
+ for (lst = 0; lst < gMemNLists; ++lst) {
+ for (p = gMemList[lst]; p; p = p->next)
+ fprintf(f, "%8d %8d\n", p->index, p->size);
+ }
+ } else {
+ fprintf(f, "No memory blocks left allocated\n");
+ }
+}
+#endif
+
+char *copyString(const char *s) {
+ char *s1;
+
+ s1 = (char *)gmalloc(strlen(s) + 1);
+ strcpy(s1, s);
+ return s1;
+}
diff --git a/pdftops/gmem.h b/pdftops/gmem.h
new file mode 100644
index 000000000..8c8ca1f4a
--- /dev/null
+++ b/pdftops/gmem.h
@@ -0,0 +1,53 @@
+/*
+ * gmem.h
+ *
+ * Memory routines with out-of-memory checking.
+ *
+ * Copyright 1996 Derek B. Noonburg
+ */
+
+#ifndef GMEM_H
+#define GMEM_H
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Same as malloc, but prints error message and exits if malloc()
+ * returns NULL.
+ */
+extern void *gmalloc(int size);
+
+/*
+ * Same as realloc, but prints error message and exits if realloc()
+ * returns NULL. If <p> is NULL, calls malloc instead of realloc().
+ */
+extern void *grealloc(void *p, int size);
+
+/*
+ * Same as free, but checks for and ignores NULL pointers.
+ */
+extern void gfree(void *p);
+
+#ifdef DEBUG_MEM
+/*
+ * Report on unfreed memory.
+ */
+extern void gMemReport(FILE *f);
+#else
+#define gMemReport(f)
+#endif
+
+/*
+ * Allocate memory and copy a string into it.
+ */
+extern char *copyString(const char *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pdftops/gmempp.cxx b/pdftops/gmempp.cxx
new file mode 100644
index 000000000..6eb64948d
--- /dev/null
+++ b/pdftops/gmempp.cxx
@@ -0,0 +1,31 @@
+//========================================================================
+//
+// gmempp.cc
+//
+// Use gmalloc/gfree for C++ new/delete operators.
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#include "gmem.h"
+
+#ifdef DEBUG_MEM
+
+void *operator new(size_t size) {
+ return gmalloc((int)size);
+}
+
+void *operator new[](size_t size) {
+ return gmalloc((int)size);
+}
+
+void operator delete(void *p) {
+ gfree(p);
+}
+
+void operator delete[](void *p) {
+ gfree(p);
+}
+
+#endif
diff --git a/pdftops/gtypes.h b/pdftops/gtypes.h
new file mode 100644
index 000000000..7a3487663
--- /dev/null
+++ b/pdftops/gtypes.h
@@ -0,0 +1,31 @@
+/*
+ * gtypes.h
+ *
+ * Some useful simple types.
+ *
+ * Copyright 1996 Derek B. Noonburg
+ */
+
+#ifndef GTYPES_H
+#define GTYPES_H
+
+#define HAVE_LIBCUPS
+
+/*
+ * These have stupid names to avoid conflicts with some (but not all)
+ * C++ compilers which define them.
+ */
+typedef int GBool;
+#define gTrue 1
+#define gFalse 0
+
+/*
+ * These have stupid names to avoid conflicts with <sys/types.h>,
+ * which on various systems defines some random subset of these.
+ */
+typedef unsigned char Guchar;
+typedef unsigned short Gushort;
+typedef unsigned int Guint;
+typedef unsigned long Gulong;
+
+#endif
diff --git a/pdftops/parseargs.c b/pdftops/parseargs.c
new file mode 100644
index 000000000..ceba88779
--- /dev/null
+++ b/pdftops/parseargs.c
@@ -0,0 +1,190 @@
+/*
+ * parseargs.h
+ *
+ * Command line argument parser.
+ *
+ * Copyright 1996 Derek B. Noonburg
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "parseargs.h"
+
+static ArgDesc *findArg(ArgDesc *args, char *arg);
+static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]);
+
+GBool parseArgs(ArgDesc *args, int *argc, char *argv[]) {
+ ArgDesc *arg;
+ int i, j;
+ GBool ok;
+
+ ok = gTrue;
+ i = 1;
+ while (i < *argc) {
+ if (!strcmp(argv[i], "--")) {
+ --*argc;
+ for (j = i; j < *argc; ++j)
+ argv[j] = argv[j+1];
+ break;
+ } else if ((arg = findArg(args, argv[i]))) {
+ if (!grabArg(arg, i, argc, argv))
+ ok = gFalse;
+ } else {
+ ++i;
+ }
+ }
+ return ok;
+}
+
+void printUsage(char *program, char *otherArgs, ArgDesc *args) {
+ ArgDesc *arg;
+ char *typ;
+ int w, w1;
+
+ w = 0;
+ for (arg = args; arg->arg; ++arg) {
+ if ((w1 = strlen(arg->arg)) > w)
+ w = w1;
+ }
+
+ fprintf(stderr, "Usage: %s [options]", program);
+ if (otherArgs)
+ fprintf(stderr, " %s", otherArgs);
+ fprintf(stderr, "\n");
+
+ for (arg = args; arg->arg; ++arg) {
+ fprintf(stderr, " %s", arg->arg);
+ w1 = 9 + w - strlen(arg->arg);
+ switch (arg->kind) {
+ case argInt:
+ case argIntDummy:
+ typ = " <int>";
+ break;
+ case argFP:
+ case argFPDummy:
+ typ = " <fp>";
+ break;
+ case argString:
+ case argStringDummy:
+ typ = " <string>";
+ break;
+ case argFlag:
+ case argFlagDummy:
+ default:
+ typ = "";
+ break;
+ }
+ fprintf(stderr, "%-*s", w1, typ);
+ if (arg->usage)
+ fprintf(stderr, ": %s", arg->usage);
+ fprintf(stderr, "\n");
+ }
+}
+
+static ArgDesc *findArg(ArgDesc *args, char *arg) {
+ ArgDesc *p;
+
+ for (p = args; p->arg; ++p) {
+ if (p->kind < argFlagDummy && !strcmp(p->arg, arg))
+ return p;
+ }
+ return NULL;
+}
+
+static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]) {
+ int n;
+ int j;
+ GBool ok;
+
+ ok = gTrue;
+ n = 0;
+ switch (arg->kind) {
+ case argFlag:
+ *(GBool *)arg->val = gTrue;
+ n = 1;
+ break;
+ case argInt:
+ if (i + 1 < *argc && isInt(argv[i+1])) {
+ *(int *)arg->val = atoi(argv[i+1]);
+ n = 2;
+ } else {
+ ok = gFalse;
+ n = 1;
+ }
+ break;
+ case argFP:
+ if (i + 1 < *argc && isFP(argv[i+1])) {
+ *(double *)arg->val = atof(argv[i+1]);
+ n = 2;
+ } else {
+ ok = gFalse;
+ n = 1;
+ }
+ break;
+ case argString:
+ if (i + 1 < *argc) {
+ strncpy((char *)arg->val, argv[i+1], arg->size - 1);
+ ((char *)arg->val)[arg->size - 1] = '\0';
+ n = 2;
+ } else {
+ ok = gFalse;
+ n = 1;
+ }
+ break;
+ default:
+ fprintf(stderr, "Internal error in arg table\n");
+ n = 1;
+ break;
+ }
+ if (n > 0) {
+ *argc -= n;
+ for (j = i; j < *argc; ++j)
+ argv[j] = argv[j+n];
+ }
+ return ok;
+}
+
+GBool isInt(char *s) {
+ if (*s == '-' || *s == '+')
+ ++s;
+ while (isdigit(*s))
+ ++s;
+ if (*s)
+ return gFalse;
+ return gTrue;
+}
+
+GBool isFP(char *s) {
+ int n;
+
+ if (*s == '-' || *s == '+')
+ ++s;
+ n = 0;
+ while (isdigit(*s)) {
+ ++s;
+ ++n;
+ }
+ if (*s == '.')
+ ++s;
+ while (isdigit(*s)) {
+ ++s;
+ ++n;
+ }
+ if (n > 0 && (*s == 'e' || *s == 'E')) {
+ ++s;
+ if (*s == '-' || *s == '+')
+ ++s;
+ n = 0;
+ if (!isdigit(*s))
+ return gFalse;
+ do {
+ ++s;
+ } while (isdigit(*s));
+ }
+ if (*s)
+ return gFalse;
+ return gTrue;
+}
diff --git a/pdftops/parseargs.h b/pdftops/parseargs.h
new file mode 100644
index 000000000..e0aa2be33
--- /dev/null
+++ b/pdftops/parseargs.h
@@ -0,0 +1,71 @@
+/*
+ * parseargs.h
+ *
+ * Command line argument parser.
+ *
+ * Copyright 1996 Derek B. Noonburg
+ */
+
+#ifndef PARSEARGS_H
+#define PARSEARGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gtypes.h"
+
+/*
+ * Argument kinds.
+ */
+typedef enum {
+ argFlag, /* flag (present / not-present) */
+ /* [val: GBool *] */
+ argInt, /* integer arg */
+ /* [val: int *] */
+ argFP, /* floating point arg */
+ /* [val: double *] */
+ argString, /* string arg */
+ /* [val: char *] */
+ /* dummy entries -- these show up in the usage listing only; */
+ /* useful for X args, for example */
+ argFlagDummy,
+ argIntDummy,
+ argFPDummy,
+ argStringDummy
+} ArgKind;
+
+/*
+ * Argument descriptor.
+ */
+typedef struct {
+ char *arg; /* the command line switch */
+ ArgKind kind; /* kind of arg */
+ void *val; /* place to store value */
+ int size; /* for argString: size of string */
+ char *usage; /* usage string */
+} ArgDesc;
+
+/*
+ * Parse command line. Removes all args which are found in the arg
+ * descriptor list <args>. Stops parsing if "--" is found (and removes
+ * it). Returns gFalse if there was an error.
+ */
+extern GBool parseArgs(ArgDesc *args, int *argc, char *argv[]);
+
+/*
+ * Print usage message, based on arg descriptor list.
+ */
+extern void printUsage(char *program, char *otherArgs, ArgDesc *args);
+
+/*
+ * Check if a string is a valid integer or floating point number.
+ */
+extern GBool isInt(char *s);
+extern GBool isFP(char *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pdftops/pdftops.cxx b/pdftops/pdftops.cxx
new file mode 100644
index 000000000..fe107f945
--- /dev/null
+++ b/pdftops/pdftops.cxx
@@ -0,0 +1,157 @@
+//========================================================================
+//
+// pdftops.cc
+//
+// Copyright 1996 Derek B. Noonburg
+//
+//========================================================================
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include "parseargs.h"
+#include "GString.h"
+#include "gmem.h"
+#include "Object.h"
+#include "Stream.h"
+#include "Array.h"
+#include "Dict.h"
+#include "XRef.h"
+#include "Catalog.h"
+#include "Page.h"
+#include "PDFDoc.h"
+#include "PSOutputDev.h"
+#include "Params.h"
+#include "Error.h"
+#include "config.h"
+
+#include <cups/cups.h>
+
+int main(int argc, char *argv[]) {
+ PDFDoc *doc;
+ GString *fileName;
+ GString *psFileName;
+ PSOutLevel level;
+ PSOutputDev *psOut;
+ int num_options;
+ cups_option_t *options;
+ ppd_file_t *ppd;
+ ppd_size_t *size;
+ FILE *fp;
+ const char *server_root;
+ char tempfile[1024];
+ char buffer[8192];
+ int bytes;
+ int width, length;
+
+
+ // Make sure status messages are not buffered...
+ setbuf(stderr, NULL);
+
+ // Send all error messages...
+ errQuiet = 0;
+
+ // Make sure we have the right number of arguments for CUPS!
+ if (argc < 6 || argc > 7) {
+ fputs("Usage: pdftops job user title copies options [filename]\n", stderr);
+ return (1);
+ }
+
+ // Copy stdin if needed...
+ if (argc == 6) {
+ if ((fp = fopen(cupsTempFile(tempfile, sizeof(tempfile)), "w")) == NULL) {
+ perror("ERROR: Unable to copy PDF file");
+ return (1);
+ }
+
+ fprintf(stderr, "DEBUG: pdftops - copying to temp print file \"%s\"\n",
+ tempfile);
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
+ fwrite(buffer, 1, bytes, fp);
+ fclose(fp);
+
+ fileName = new GString(tempfile);
+ } else {
+ fileName = new GString(argv[6]);
+ tempfile[0] = '\0';
+ }
+
+ // Default to "Universal" size - min of A4 and Letter...
+ width = 595;
+ length = 792;
+ level = psLevel2;
+
+ // Get PPD and initialize options as needed...
+ if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL)
+ {
+ fprintf(stderr, "DEBUG: pdftops - opened PPD file \"%s\"...\n", getenv("PPD"));
+
+ ppdMarkDefaults(ppd);
+ num_options = cupsParseOptions(argv[5], 0, &options);
+ cupsMarkOptions(ppd, num_options, options);
+ cupsFreeOptions(num_options, options);
+
+ if ((size = ppdPageSize(ppd, NULL)) != NULL)
+ {
+ width = (int)size->width;
+ length = (int)size->length;
+ }
+
+ level = ppd->language_level == 1 ? psLevel1 : psLevel2;
+
+ ppdClose(ppd);
+ }
+
+ fprintf(stderr, "DEBUG: pdftops - level = %d, width = %d, length = %d\n",
+ level, width, length);
+
+ // init error file
+ errorInit();
+
+ // read config file
+ if ((server_root = getenv("CUPS_SERVERROOT")) == NULL)
+ server_root = CUPS_SERVERROOT;
+
+ sprintf(tempfile, "%s/pdftops.conf", server_root);
+ initParams("", tempfile);
+
+ // open PDF file
+ doc = new PDFDoc(fileName, NULL, NULL, getenv("DEBUG") != NULL);
+
+ // check for print permission
+ if (doc->isOk() && doc->okToPrint())
+ {
+ // CUPS always writes to stdout...
+ psFileName = new GString("-");
+
+ // write PostScript file
+ psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(),
+ doc->getCatalog(), 1, doc->getNumPages(),
+ level, psModePS, 0, 1, 1, width, length);
+ if (psOut->isOk())
+ doc->displayPages(psOut, 1, doc->getNumPages(), 72, 0, gFalse);
+ delete psOut;
+
+ // clean up
+ delete psFileName;
+ }
+ else
+ {
+ error(-1, "Unable to print this document.");
+ }
+
+ delete doc;
+ freeParams();
+
+ // check for memory leaks
+ Object::memCheck(stderr);
+ gMemReport(stderr);
+
+ // Remove temp file if needed...
+ if (tempfile[0])
+ unlink(tempfile);
+
+ return 0;
+}
diff --git a/ppd/Makefile b/ppd/Makefile
new file mode 100644
index 000000000..73fa3c194
--- /dev/null
+++ b/ppd/Makefile
@@ -0,0 +1,63 @@
+#
+# "$Id$"
+#
+# PPD file makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+#
+# PPD files...
+#
+
+FILES = deskjet.ppd deskjet2.ppd dymo.ppd epson9.ppd epson24.ppd \
+ laserjet.ppd okidata9.ppd okidat24.ppd stcolor.ppd \
+ stcolor2.ppd stphoto.ppd stphoto2.ppd
+
+
+#
+# Make everything...
+#
+
+all:
+
+
+#
+# Clean all config and object files...
+#
+
+clean:
+
+
+#
+# Install files...
+#
+
+install:
+ $(INSTALL_DIR) $(DATADIR)/model
+ for file in $(FILES); do \
+ $(INSTALL_DATA) $$file $(DATADIR)/model; \
+ done
+
+
+#
+# End of "$Id$".
+#
diff --git a/ppd/deskjet.ppd b/ppd/deskjet.ppd
new file mode 100644
index 000000000..3df9a913b
--- /dev/null
+++ b/ppd/deskjet.ppd
@@ -0,0 +1,198 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Sample HP DeskJet driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "DESKJET.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: True
+*cupsFilter: "application/vnd.cups-raster 0 rastertohp"
+*cupsModelNumber: 1
+*ModelName: "HP DeskJet Series"
+*ShortNickName: "HP DeskJet Series"
+*NickName: "HP DeskJet Series CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: RGB
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*UIConstraints: *PageSize Executive *InputSlot Envelope
+*UIConstraints: *PageSize Letter *InputSlot Envelope
+*UIConstraints: *PageSize Legal *InputSlot Envelope
+*UIConstraints: *PageSize Tabloid *InputSlot Envelope
+*UIConstraints: *PageSize A3 *InputSlot Envelope
+*UIConstraints: *PageSize A4 *InputSlot Envelope
+*UIConstraints: *PageSize A5 *InputSlot Envelope
+*UIConstraints: *PageSize B5 *InputSlot Envelope
+*UIConstraints: *Resolution 600dpi *ColorModel CMYK
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageSize Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageSize A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageSize A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageSize B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageSize EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageSize Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageSize EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageSize EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageSize EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageRegion Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageRegion A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageRegion A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageRegion A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageRegion B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageRegion Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/US Letter: "18 36 594 756"
+*ImageableArea Legal/US Legal: "18 36 594 972"
+*ImageableArea Executive/US Executive: "18 36 504 684"
+*ImageableArea Tabloid/US Tabloid: "18 36 774 1188"
+*ImageableArea A3/A3: "18 36 824 1155"
+*ImageableArea A4/A4: "18 36 577 806"
+*ImageableArea A5/A5: "18 36 403 559"
+*ImageableArea B5/JIS B5: "18 36 498 693"
+*ImageableArea EnvISOB5/B5 (ISO): "18 36 463 673"
+*ImageableArea Env10/Com-10: "18 36 279 648"
+*ImageableArea EnvC5/EnvC5: "18 36 441 613"
+*ImageableArea EnvDL/EnvDL: "18 36 294 588"
+*ImageableArea EnvMonarch/Envelope Monarch: "18 36 261 504"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/US Letter: "612 792"
+*PaperDimension Legal/US Legal: "612 1008"
+*PaperDimension Executive/US Executive: "522 756"
+*PaperDimension Tabloid/US Tabloid: "792 1224"
+*PaperDimension A3/A3: "842 1191"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension A5/A5: "421 595"
+*PaperDimension B5/B5 (JIS): "516 729"
+*PaperDimension EnvISOB5/Envelope B5: "499 709"
+*PaperDimension Env10/Envelope #10: "297 684"
+*PaperDimension EnvC5/Envelope C5: "459 649"
+*PaperDimension EnvDL/Envelope DL: "312 624"
+*PaperDimension EnvMonarch/Envelope Monarch: "279 540"
+
+*OpenUI *MediaType/Media Type: PickOne
+*OrderDependency: 10 AnySetup *MediaType
+*DefaultMediaType: Plain
+*MediaType Plain/Plain Paper: "<</MediaType(Plain)/cupsMediaType 0>>setpagedevice"
+*MediaType Bond/Bond Paper: "<</MediaType(Bond)/cupsMediaType 1>>setpagedevice"
+*MediaType Special/Special Paper: "<</MediaType(Special)/cupsMediaType 2>>setpagedevice"
+*MediaType Transparency/Transparency: "<</MediaType(Transparency)/cupsMediaType 3>>setpagedevice"
+*MediaType Glossy/Glossy Paper: "<</MediaType(Glossy)/cupsMediaType 4>>setpagedevice"
+*CloseUI: *MediaType
+
+*OpenUI *InputSlot/Media Source: PickOne
+*OrderDependency: 10 AnySetup *InputSlot
+*DefaultInputSlot: Tray
+*InputSlot Tray/Tray: "<</cupsMediaPosition 1>>setpagedevice"
+*InputSlot Manual/Manual Feed: "<</cupsMediaPosition 2>>setpagedevice"
+*InputSlot Envelope/Envelope Feed: "<</cupsMediaPosition 3>>setpagedevice"
+*CloseUI: *InputSlot
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 300dpi
+*Resolution 150dpi/150 DPI: "<</HWResolution[150 150]>>setpagedevice"
+*Resolution 300dpi/300 DPI: "<</HWResolution[300 300]>>setpagedevice"
+*Resolution 600dpi/600 DPI: "<</HWResolution[600 600]/cupsColorSpace 3>>setpagedevice"
+*CloseUI: *Resolution
+
+*OpenUI *ColorModel/Output Mode: PickOne
+*OrderDependency: 10 AnySetup *ColorModel
+*DefaultColorModel: CMYK
+*ColorModel CMYK/CMYK Color: "<</cupsColorOrder 1/cupsColorSpace 8/cupsCompression 2>>setpagedevice"
+*ColorModel RGB/CMY Color: "<</cupsColorOrder 1/cupsColorSpace 4/cupsCompression 2>>setpagedevice"
+*ColorModel Gray/Grayscale: "<</cupsColorOrder 0/cupsColorSpace 3/cupsCompression 2>>setpagedevice"
+*CloseUI: *ColorModel
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/ppd/deskjet2.ppd b/ppd/deskjet2.ppd
new file mode 100644
index 000000000..fa105ef1f
--- /dev/null
+++ b/ppd/deskjet2.ppd
@@ -0,0 +1,217 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Second sample HP DeskJet driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "DESKJET2.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: True
+*cupsFilter: "application/vnd.cups-raster 0 rastertohp"
+*cupsModelNumber: 2
+*cupsFlipDuplex: True
+*cupsColorProfile -/-: "1.0 1.5 1.0 -0.25 -0.225 -0.25 1.0 -0.225 -0.25 -0.25 0.9"
+
+*ModelName: "HP New DeskJet Series"
+*ShortNickName: "HP New DeskJet Series"
+*NickName: "HP New DeskJet Series CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: RGB
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*UIConstraints: *PageSize Executive *InputSlot Envelope
+*UIConstraints: *PageSize Letter *InputSlot Envelope
+*UIConstraints: *PageSize Legal *InputSlot Envelope
+*UIConstraints: *PageSize Tabloid *InputSlot Envelope
+*UIConstraints: *PageSize A3 *InputSlot Envelope
+*UIConstraints: *PageSize A4 *InputSlot Envelope
+*UIConstraints: *PageSize A5 *InputSlot Envelope
+*UIConstraints: *PageSize B5 *InputSlot Envelope
+*UIConstraints: *Duplex *Option1 False
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageSize Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageSize A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageSize A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageSize B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageSize EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageSize Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageSize EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageSize EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageSize EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageRegion Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageRegion A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageRegion A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageRegion A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageRegion B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageRegion Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/US Letter: "18 36 594 786"
+*ImageableArea Legal/US Legal: "18 36 594 1002"
+*ImageableArea Executive/US Executive: "18 36 504 714"
+*ImageableArea Tabloid/US Tabloid: "18 36 774 1218"
+*ImageableArea A3/A3: "18 36 824 1185"
+*ImageableArea A4/A4: "18 36 577 836"
+*ImageableArea A5/A5: "18 36 403 589"
+*ImageableArea B5/JIS B5: "18 36 498 723"
+*ImageableArea EnvISOB5/B5 (ISO): "18 36 463 703"
+*ImageableArea Env10/Com-10: "18 36 279 678"
+*ImageableArea EnvC5/EnvC5: "18 36 441 643"
+*ImageableArea EnvDL/EnvDL: "18 36 294 618"
+*ImageableArea EnvMonarch/Envelope Monarch: "18 36 261 534"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/US Letter: "612 792"
+*PaperDimension Legal/US Legal: "612 1008"
+*PaperDimension Executive/US Executive: "522 756"
+*PaperDimension Tabloid/US Tabloid: "792 1224"
+*PaperDimension A3/A3: "842 1191"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension A5/A5: "421 595"
+*PaperDimension B5/B5 (JIS): "516 729"
+*PaperDimension EnvISOB5/Envelope B5: "499 709"
+*PaperDimension Env10/Envelope #10: "297 684"
+*PaperDimension EnvC5/Envelope C5: "459 649"
+*PaperDimension EnvDL/Envelope DL: "312 624"
+*PaperDimension EnvMonarch/Envelope Monarch: "279 540"
+
+*OpenUI *MediaType/Media Type: PickOne
+*OrderDependency: 10 AnySetup *MediaType
+*DefaultMediaType: Plain
+*MediaType Plain/Plain Paper: "<</MediaType(Plain)/cupsMediaType 0>>setpagedevice"
+*MediaType Bond/Bond Paper: "<</MediaType(Bond)/cupsMediaType 1>>setpagedevice"
+*MediaType Special/Special Paper: "<</MediaType(Special)/cupsMediaType 2>>setpagedevice"
+*MediaType Transparency/Transparency: "<</MediaType(Transparency)/cupsMediaType 3>>setpagedevice"
+*MediaType Glossy/Glossy Paper: "<</MediaType(Glossy)/cupsMediaType 4>>setpagedevice"
+*CloseUI: *MediaType
+
+*OpenUI *InputSlot/Media Source: PickOne
+*OrderDependency: 10 AnySetup *InputSlot
+*DefaultInputSlot: Tray
+*InputSlot Tray/Tray: "<</cupsMediaPosition 1>>setpagedevice"
+*InputSlot Manual/Manual Feed: "<</cupsMediaPosition 2>>setpagedevice"
+*InputSlot Envelope/Envelope Feed: "<</cupsMediaPosition 3>>setpagedevice"
+*CloseUI: *InputSlot
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 300dpi
+*Resolution 300dpi/300 DPI: "<</HWResolution[300 300]>>setpagedevice"
+*Resolution 600x300dpi/600x300 DPI: "<</HWResolution[600 300]>>setpagedevice"
+*Resolution 600dpi/600 DPI: "<</HWResolution[600 600]>>setpagedevice"
+*CloseUI: *Resolution
+
+*OpenUI *ColorModel/Output Mode: PickOne
+*OrderDependency: 10 AnySetup *ColorModel
+*DefaultColorModel: CMYK
+*ColorModel CMYK2/CRET Color: "<</cupsColorOrder 1/cupsColorSpace 8/cupsCompression 2/cupsBitsPerColor 2>>setpagedevice"
+*ColorModel CMYK/CMYK Color: "<</cupsColorOrder 1/cupsColorSpace 8/cupsCompression 2>>setpagedevice"
+*ColorModel Gray/Grayscale: "<</cupsColorOrder 0/cupsColorSpace 3/cupsCompression 2>>setpagedevice"
+*CloseUI: *ColorModel
+
+*OpenUI *Duplex/Double-Sided Printing: PickOne
+*OrderDependency: 20 PageSetup *Duplex
+*DefaultDuplex: None
+*Duplex None/Off: "<</Duplex false>>setpagedevice"
+*Duplex DuplexNoTumble/Long Edge (Standard): "<</Duplex true/Tumble false>>setpagedevice"
+*Duplex DuplexTumble/Short Edge (Flip): "<</Duplex true/Tumble true>>setpagedevice"
+*CloseUI: *Duplex
+
+*OpenGroup: InstallableOptions
+*OpenUI *Option1/Duplexer: Boolean
+*DefaultOption1: False
+*Option1 True/Installed: ""
+*Option1 False/Not Installed: ""
+*CloseUI: *Option1
+*CloseGroup: InstallableOptions
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/ppd/dymo.ppd b/ppd/dymo.ppd
new file mode 100644
index 000000000..43801737f
--- /dev/null
+++ b/ppd/dymo.ppd
@@ -0,0 +1,155 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Sample DYMO label printer driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 2001-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "DYMO.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: False
+*cupsFilter: "application/vnd.cups-raster 0 rastertodymo"
+*cupsModelNumber: 0
+*ModelName: "DYMO Label Printer"
+*ShortNickName: "DYMO Label Printer"
+*NickName: "DYMO Label Printer CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: False
+*DefaultColorSpace: Gray
+*FileSystem: False
+*Throughput: "8"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: w81h252
+*PageSize w81h252/Address - 1 1/8 x 3 1/2": "<</PageSize[81 252]/ImagingBBox null>>setpagedevice"
+*PageSize w101h252/Large Address - 1 4/10 x 3 1/2": "<</PageSize[101 252]/ImagingBBox null>>setpagedevice"
+*PageSize w54h144/Return Address - 3/4 x 2": "<</PageSize[54 144]/ImagingBBox null>>setpagedevice"
+*PageSize w167h288/Shipping Address - 2 5/16 x 4": "<</PageSize[167 288]/ImagingBBox null>>setpagedevice"
+*PageSize w162h540/Internet Postage 2-Part - 2 1/4 x 7 1/2": "<</PageSize[162 540]/ImagingBBox null>>setpagedevice"
+*PageSize w162h504/Internet Postage 3-Part - 2 1/4 x 7": "<</PageSize[162 504]/ImagingBBox null>>setpagedevice"
+*PageSize w41h248/File Folder - 9/16 x 3 7/16": "<</PageSize[41 248]/ImagingBBox null>>setpagedevice"
+*PageSize w41h144/Hanging Folder - 9/16 x 2": "<</PageSize[41 144]/ImagingBBox null>>setpagedevice"
+*PageSize w153h198/3.5" Disk - 2 1/8 x 2 3/4": "<</PageSize[153 198]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: w81h252
+*PageRegion w81h252/Address - 1 1/8 x 3 1/2": "<</PageSize[81 252]/ImagingBBox null>>setpagedevice"
+*PageRegion w101h252/Large Address - 1 4/10 x 3 1/2": "<</PageSize[101 252]/ImagingBBox null>>setpagedevice"
+*PageRegion w54h144/Return Address - 3/4 x 2": "<</PageSize[54 144]/ImagingBBox null>>setpagedevice"
+*PageRegion w167h288/Shipping Address - 2 5/16 x 4": "<</PageSize[167 288]/ImagingBBox null>>setpagedevice"
+*PageRegion w162h540/Internet Postage 2-Part - 2 1/4 x 7 1/2": "<</PageSize[162 540]/ImagingBBox null>>setpagedevice"
+*PageRegion w162h504/Internet Postage 3-Part - 2 1/4 x 7": "<</PageSize[162 504]/ImagingBBox null>>setpagedevice"
+*PageRegion w41h248/File Folder - 9/16 x 3 7/16": "<</PageSize[41 248]/ImagingBBox null>>setpagedevice"
+*PageRegion w41h144/Hanging Folder - 9/16 x 2": "<</PageSize[41 144]/ImagingBBox null>>setpagedevice"
+*PageRegion w153h198/3.5" Disk - 2 1/8 x 2 3/4": "<</PageSize[153 198]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: w81h252
+*ImageableArea w81h252/Address - 1 1/8 x 3 1/2": "2 14.9 79 237.1"
+*ImageableArea w101h252/Large Address - 1 4/10 x 3 1/2": "2 14.9 99 237.1"
+*ImageableArea w54h144/Return Address - 3/4 x 2": "2 14.9 52 129.1"
+*ImageableArea w167h288/Shipping Address - 2 5/16 x 4": "2 14.9 165 273.1"
+*ImageableArea w162h540/Internet Postage 2-Part - 2 1/4 x 7 1/2": "2 14.9 160 525.1"
+*ImageableArea w162h504/Internet Postage 3-Part - 2 1/4 x 7": "2 14.9 160 489.1"
+*ImageableArea w41h248/File Folder - 9/16 x 3 7/16": "2 14.9 39 233.1"
+*ImageableArea w41h144/Hanging Folder - 9/16 x 2": "2 14.9 39 129.1"
+*ImageableArea w153h198/3.5" Disk - 2 1/8 x 2 3/4": "2 14.9 151 183.1"
+
+*DefaultPaperDimension: w81h252
+*PaperDimension w81h252/Address - 1 1/8 x 3 1/2": "81 252"
+*PaperDimension w101h252/Large Address - 1 4/10 x 3 1/2": "101 252"
+*PaperDimension w54h144/Return Address - 3/4 x 2": "54 144"
+*PaperDimension w167h288/Shipping Address - 2 5/16 x 4": "167 288"
+*PaperDimension w162h540/Internet Postage 2-Part - 2 1/4 x 7 1/2": "162 540"
+*PaperDimension w162h504/Internet Postage 3-Part - 2 1/4 x 7": "162 504"
+*PaperDimension w41h248/File Folder - 9/16 x 3 7/16": "41 248"
+*PaperDimension w41h144/Hanging Folder - 9/16 x 2": "41 144"
+*PaperDimension w153h198/3.5" Disk - 2 1/8 x 2 3/4": "153 198"
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 300dpi
+*Resolution 136dpi/136 DPI: "<</HWResolution[136 136]>>setpagedevice"
+*Resolution 203dpi/203 DPI: "<</HWResolution[203 203]>>setpagedevice"
+*Resolution 300dpi/300 DPI: "<</HWResolution[300 300]>>setpagedevice"
+*CloseUI: *Resolution
+
+*OpenUI *Darkness/Output Darkness: PickOne
+*OrderDependency: 20 AnySetup *Darkness
+*DefaultDarkness: Normal
+*Darkness Light: "<</cupsCompression 0>>setpagedevice"
+*Darkness Medium: "<</cupsCompression 1>>setpagedevice"
+*Darkness Normal: "<</cupsCompression 2>>setpagedevice"
+*Darkness Dark: "<</cupsCompression 3>>setpagedevice"
+*CloseUI: *Darkness
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/ppd/epson24.ppd b/ppd/epson24.ppd
new file mode 100644
index 000000000..e60b3b56e
--- /dev/null
+++ b/ppd/epson24.ppd
@@ -0,0 +1,128 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Sample EPSON 24-Pin driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "EPSON24.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: True
+*cupsModelNumber: 1
+*cupsFilter: "application/vnd.cups-raster 0 rastertoepson"
+*ModelName: "EPSON 24-Pin Series"
+*ShortNickName: "EPSON 24-Pin Series"
+*NickName: "EPSON 24-Pin Series CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: False
+*DefaultColorSpace: Gray
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageSize FanFoldUS: "<</PageSize[1071 792]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageRegion FanFoldUS: "<</PageSize[1071 792]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter: "18.0 18.0 594.0 774.0"
+*ImageableArea Legal: "18.0 18.0 594.0 990.0"
+*ImageableArea A4: "18.0 18.0 577.0 824.0"
+*ImageableArea FanFoldUS: "18.0 18.0 1053.0 774.0"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter: "612 792"
+*PaperDimension Legal: "612 1008"
+*PaperDimension A4: "595 842"
+*PaperDimension FanFoldUS: "1071 792"
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 120dpi
+*Resolution 60dpi/60 DPI: "<</HWResolution[60 60]/cupsRowCount 8>>setpagedevice"
+*Resolution 120dpi/120x60 DPI: "<</HWResolution[120 60]/cupsRowCount 8>>setpagedevice"
+*Resolution 180dpi/180 DPI: "<</HWResolution[180 180]/cupsRowCount 24>>setpagedevice"
+*Resolution 360x180dpi/360x180 DPI: "<</HWResolution[360 180]/cupsRowCount 24>>setpagedevice"
+*Resolution 360dpi/360 DPI: "<</HWResolution[360 360]/cupsRowCount 48>>setpagedevice"
+*CloseUI: *Resolution
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/ppd/epson9.ppd b/ppd/epson9.ppd
new file mode 100644
index 000000000..a6889db81
--- /dev/null
+++ b/ppd/epson9.ppd
@@ -0,0 +1,126 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Sample EPSON 9-Pin driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "EPSON9.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: True
+*cupsModelNumber: 0
+*cupsFilter: "application/vnd.cups-raster 0 rastertoepson"
+*ModelName: "EPSON 9-Pin Series"
+*ShortNickName: "EPSON 9-Pin Series"
+*NickName: "EPSON 9-Pin Series CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: False
+*DefaultColorSpace: Gray
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageSize FanFoldUS: "<</PageSize[1071 792]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageRegion FanFoldUS: "<</PageSize[1071 792]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter: "18.0 18.0 594.0 774.0"
+*ImageableArea Legal: "18.0 18.0 594.0 990.0"
+*ImageableArea A4: "18.0 18.0 577.0 824.0"
+*ImageableArea FanFoldUS: "18.0 18.0 1053.0 774.0"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter: "612 792"
+*PaperDimension Legal: "612 1008"
+*PaperDimension A4: "595 842"
+*PaperDimension FanFoldUS: "1071 792"
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 120dpi
+*Resolution 60dpi/60x72 DPI: "<</HWResolution[60 72]/cupsRowCount 8>>setpagedevice"
+*Resolution 120dpi/120x72 DPI: "<</HWResolution[120 72]/cupsRowCount 8>>setpagedevice"
+*Resolution 240dpi/240x72 DPI: "<</HWResolution[240 72]/cupsRowCount 8>>setpagedevice"
+*CloseUI: *Resolution
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/ppd/laserjet.ppd b/ppd/laserjet.ppd
new file mode 100644
index 000000000..a37eea38a
--- /dev/null
+++ b/ppd/laserjet.ppd
@@ -0,0 +1,200 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Sample HP LaserJet driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "LASERJET.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: False
+*cupsFilter: "application/vnd.cups-raster 0 rastertohp"
+*cupsModelNumber: 0
+*ModelName: "HP LaserJet Series"
+*ShortNickName: "HP LaserJet Series"
+*NickName: "HP LaserJet Series CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: False
+*DefaultColorSpace: Gray
+*FileSystem: False
+*Throughput: "8"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*UIConstraints: *PageSize Executive *InputSlot Envelope
+*UIConstraints: *PageSize Letter *InputSlot Envelope
+*UIConstraints: *PageSize Legal *InputSlot Envelope
+*UIConstraints: *PageSize Tabloid *InputSlot Envelope
+*UIConstraints: *PageSize A3 *InputSlot Envelope
+*UIConstraints: *PageSize A4 *InputSlot Envelope
+*UIConstraints: *PageSize A5 *InputSlot Envelope
+*UIConstraints: *PageSize B5 *InputSlot Envelope
+*UIConstraints: *Duplex *Option1 False
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageSize Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageSize A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageSize A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageSize B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageSize EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageSize Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageSize EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageSize EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageSize EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageRegion Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageRegion A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageRegion A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageRegion A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageRegion B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageRegion Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/US Letter: "18 36 594 756"
+*ImageableArea Legal/US Legal: "18 36 594 972"
+*ImageableArea Executive/US Executive: "18 36 504 684"
+*ImageableArea Tabloid/US Tabloid: "18 36 774 1188"
+*ImageableArea A3/A3: "18 36 824 1155"
+*ImageableArea A4/A4: "18 36 577 806"
+*ImageableArea A5/A5: "18 36 403 559"
+*ImageableArea B5/JIS B5: "18 36 498 693"
+*ImageableArea EnvISOB5/B5 (ISO): "18 36 463 673"
+*ImageableArea Env10/Com-10: "18 36 279 648"
+*ImageableArea EnvC5/EnvC5: "18 36 441 613"
+*ImageableArea EnvDL/EnvDL: "18 36 294 588"
+*ImageableArea EnvMonarch/Envelope Monarch: "18 36 261 504"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/US Letter: "612 792"
+*PaperDimension Legal/US Legal: "612 1008"
+*PaperDimension Executive/US Executive: "522 756"
+*PaperDimension Tabloid/US Tabloid: "792 1224"
+*PaperDimension A3/A3: "842 1191"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension A5/A5: "421 595"
+*PaperDimension B5/B5 (JIS): "516 729"
+*PaperDimension EnvISOB5/Envelope B5: "499 709"
+*PaperDimension Env10/Envelope #10: "297 684"
+*PaperDimension EnvC5/Envelope C5: "459 649"
+*PaperDimension EnvDL/Envelope DL: "312 624"
+*PaperDimension EnvMonarch/Envelope Monarch: "279 540"
+
+*OpenUI *InputSlot/Media Source: PickOne
+*OrderDependency: 10 AnySetup *InputSlot
+*DefaultInputSlot: Default
+*InputSlot Default/Default: "<</cupsMediaPosition 0>>setpagedevice"
+*InputSlot Tray1/Tray 1: "<</cupsMediaPosition 8>>setpagedevice"
+*InputSlot Tray2/Tray 2: "<</cupsMediaPosition 1>>setpagedevice"
+*InputSlot Tray3/Tray 3: "<</cupsMediaPosition 4>>setpagedevice"
+*InputSlot Tray4/Tray 4: "<</cupsMediaPosition 5>>setpagedevice"
+*InputSlot Manual/Manual Feed: "<</cupsMediaPosition 2>>setpagedevice"
+*InputSlot Envelope/Envelope Feed: "<</cupsMediaPosition 3>>setpagedevice"
+*CloseUI: *InputSlot
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 300dpi
+*Resolution 150dpi/150 DPI: "<</HWResolution[150 150]/cupsColorOrder 0/cupsColorSpace 3/cupsCompression 2>>setpagedevice"
+*Resolution 300dpi/300 DPI: "<</HWResolution[300 300]/cupsColorOrder 0/cupsColorSpace 3/cupsCompression 2>>setpagedevice"
+*Resolution 600dpi/600 DPI: "<</HWResolution[600 600]/cupsColorOrder 0/cupsColorSpace 3/cupsCompression 2>>setpagedevice"
+*CloseUI: *Resolution
+
+*OpenUI *Duplex/Double-Sided Printing: PickOne
+*OrderDependency: 20 AnySetup *Duplex
+*DefaultDuplex: None
+*Duplex None/Off: "<</Duplex false>>setpagedevice"
+*Duplex DuplexNoTumble/Long Edge (Standard): "<</Duplex true/Tumble false>>setpagedevice"
+*Duplex DuplexTumble/Short Edge (Flip): "<</Duplex true/Tumble true>>setpagedevice"
+*CloseUI: *Duplex
+
+*OpenGroup: InstallableOptions
+*OpenUI *Option1/Duplexer: Boolean
+*DefaultOption1: False
+*Option1 True/Installed: ""
+*Option1 False/Not Installed: ""
+*CloseUI: *Option1
+*CloseGroup: InstallableOptions
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/ppd/okidat24.ppd b/ppd/okidat24.ppd
new file mode 100644
index 000000000..8a991c112
--- /dev/null
+++ b/ppd/okidat24.ppd
@@ -0,0 +1,128 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Sample OKIDATA 24-Pin driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "OKIDAT24.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: True
+*cupsModelNumber: 1
+*cupsFilter: "application/vnd.cups-raster 0 rastertoepson"
+*ModelName: "OKIDATA 24-Pin Series"
+*ShortNickName: "OKIDATA 24-Pin Series"
+*NickName: "OKIDATA 24-Pin Series CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: False
+*DefaultColorSpace: Gray
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageSize FanFoldUS: "<</PageSize[1071 792]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageRegion FanFoldUS: "<</PageSize[1071 792]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter: "18.0 18.0 594.0 774.0"
+*ImageableArea Legal: "18.0 18.0 594.0 990.0"
+*ImageableArea A4: "18.0 18.0 577.0 824.0"
+*ImageableArea FanFoldUS: "18.0 18.0 1053.0 774.0"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter: "612 792"
+*PaperDimension Legal: "612 1008"
+*PaperDimension A4: "595 842"
+*PaperDimension FanFoldUS: "1071 792"
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 120dpi
+*Resolution 60dpi/60 DPI: "<</HWResolution[60 60]/cupsRowCount 8>>setpagedevice"
+*Resolution 120dpi/120x60 DPI: "<</HWResolution[120 60]/cupsRowCount 8>>setpagedevice"
+*Resolution 180dpi/180 DPI: "<</HWResolution[180 180]/cupsRowCount 24>>setpagedevice"
+*Resolution 360x180dpi/360x180 DPI: "<</HWResolution[360 180]/cupsRowCount 24>>setpagedevice"
+*Resolution 360dpi/360 DPI: "<</HWResolution[360 360]/cupsRowCount 48>>setpagedevice"
+*CloseUI: *Resolution
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/ppd/okidata9.ppd b/ppd/okidata9.ppd
new file mode 100644
index 000000000..8f133582f
--- /dev/null
+++ b/ppd/okidata9.ppd
@@ -0,0 +1,126 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Sample OKIDATA 9-Pin driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "OKIDATA9.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: True
+*cupsModelNumber: 0
+*cupsFilter: "application/vnd.cups-raster 0 rastertoepson"
+*ModelName: "OKIDATA 9-Pin Series"
+*ShortNickName: "OKIDATA 9-Pin Series"
+*NickName: "OKIDATA 9-Pin Series CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: False
+*DefaultColorSpace: Gray
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageSize FanFoldUS: "<</PageSize[1071 792]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageRegion FanFoldUS: "<</PageSize[1071 792]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter: "18.0 18.0 594.0 774.0"
+*ImageableArea Legal: "18.0 18.0 594.0 990.0"
+*ImageableArea A4: "18.0 18.0 577.0 824.0"
+*ImageableArea FanFoldUS: "18.0 18.0 1053.0 774.0"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter: "612 792"
+*PaperDimension Legal: "612 1008"
+*PaperDimension A4: "595 842"
+*PaperDimension FanFoldUS: "1071 792"
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 120dpi
+*Resolution 60dpi/60x72 DPI: "<</HWResolution[60 72]/cupsRowCount 8>>setpagedevice"
+*Resolution 120dpi/120x72 DPI: "<</HWResolution[120 72]/cupsRowCount 8>>setpagedevice"
+*Resolution 240dpi/240x72 DPI: "<</HWResolution[240 72]/cupsRowCount 8>>setpagedevice"
+*CloseUI: *Resolution
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/ppd/stcolor.ppd b/ppd/stcolor.ppd
new file mode 100644
index 000000000..a6ec8c528
--- /dev/null
+++ b/ppd/stcolor.ppd
@@ -0,0 +1,132 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Sample EPSON Stylus Color driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "STCOLOR.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: True
+*cupsModelNumber: 2
+*cupsFilter: "application/vnd.cups-raster 0 rastertoepson"
+*cupsColorProfile 180dpi/-: "1.0 1.0 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
+*cupsColorProfile 360dpi/-: "1.0 1.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
+*cupsColorProfile 720dpi/-: "1.0 2.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
+*ModelName: "EPSON Stylus Color Series"
+*ShortNickName: "EPSON Stylus Color Series"
+*NickName: "EPSON Stylus Color Series CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: RGB
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter: "8.60 39.60 603.40 766.49"
+*ImageableArea Legal: "8.60 39.60 603.40 982.49"
+*ImageableArea A4: "8.60 39.60 586.40 816.49"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter: "612 792"
+*PaperDimension Legal: "612 1008"
+*PaperDimension A4: "595 842"
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 360dpi
+*Resolution 180dpi/180 DPI: "<</HWResolution[180 180]>>setpagedevice"
+*Resolution 360dpi/360 DPI: "<</HWResolution[360 360]>>setpagedevice{0.6666 exp}bind settransfer"
+*Resolution 720dpi/720 DPI: "<</HWResolution[720 720]>>setpagedevice{0.4 exp}bind settransfer"
+*CloseUI: *Resolution
+
+*OpenUI *ColorModel/Output Mode: PickOne
+*OrderDependency: 10 AnySetup *ColorModel
+*DefaultColorModel: CMYK
+*ColorModel CMYK/Color: "<</cupsColorOrder 1/cupsColorSpace 8/cupsCompression 1>>setpagedevice"
+*ColorModel Gray/Grayscale: "<</cupsColorOrder 0/cupsColorSpace 3/cupsCompression 1>>setpagedevice"
+*CloseUI: *ColorModel
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/ppd/stcolor2.ppd b/ppd/stcolor2.ppd
new file mode 100644
index 000000000..a8c470ac0
--- /dev/null
+++ b/ppd/stcolor2.ppd
@@ -0,0 +1,132 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Sample EPSON Stylus Color driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "STCOLOR2.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: True
+*cupsModelNumber: 4
+*cupsFilter: "application/vnd.cups-raster 0 rastertoepson"
+*cupsColorProfile 180dpi/-: "1.0 1.0 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
+*cupsColorProfile 360dpi/-: "1.0 1.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
+*cupsColorProfile 720dpi/-: "1.0 2.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
+*ModelName: "EPSON New Stylus Color Series"
+*ShortNickName: "EPSON New Stylus Color Series"
+*NickName: "EPSON New Stylus Color Series CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: RGB
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter: "8.60 39.60 603.40 766.49"
+*ImageableArea Legal: "8.60 39.60 603.40 982.49"
+*ImageableArea A4: "8.60 39.60 586.40 816.49"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter: "612 792"
+*PaperDimension Legal: "612 1008"
+*PaperDimension A4: "595 842"
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 360dpi
+*Resolution 180dpi/180 DPI: "<</HWResolution[180 180]>>setpagedevice"
+*Resolution 360dpi/360 DPI: "<</HWResolution[360 360]>>setpagedevice{0.6666 exp}bind settransfer"
+*Resolution 720dpi/720 DPI: "<</HWResolution[720 720]>>setpagedevice{0.4 exp}bind settransfer"
+*CloseUI: *Resolution
+
+*OpenUI *ColorModel/Output Mode: PickOne
+*OrderDependency: 10 AnySetup *ColorModel
+*DefaultColorModel: CMYK
+*ColorModel CMYK/Color: "<</cupsColorOrder 1/cupsColorSpace 8/cupsCompression 1>>setpagedevice"
+*ColorModel Gray/Grayscale: "<</cupsColorOrder 0/cupsColorSpace 3/cupsCompression 1>>setpagedevice"
+*CloseUI: *ColorModel
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/ppd/stphoto.ppd b/ppd/stphoto.ppd
new file mode 100644
index 000000000..91edf4adc
--- /dev/null
+++ b/ppd/stphoto.ppd
@@ -0,0 +1,132 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Sample EPSON Stylus Photo driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "STPHOTO.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: True
+*cupsModelNumber: 3
+*cupsFilter: "application/vnd.cups-raster 0 rastertoepson"
+*cupsColorProfile 180dpi/-: "1.0 1.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0"
+*cupsColorProfile 360dpi/-: "1.0 1.5 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0"
+*cupsColorProfile 720dpi/-: "1.0 2.5 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0"
+*ModelName: "EPSON Stylus Photo Series"
+*ShortNickName: "EPSON Stylus Photo Series"
+*NickName: "EPSON Stylus Photo Series CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: RGB
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter: "8.60 39.60 603.40 766.49"
+*ImageableArea Legal: "8.60 39.60 603.40 982.49"
+*ImageableArea A4: "8.60 39.60 586.40 816.49"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter: "612 792"
+*PaperDimension Legal: "612 1008"
+*PaperDimension A4: "595 842"
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 360dpi
+*Resolution 180dpi/180 DPI: "<</HWResolution[180 180]>>setpagedevice"
+*Resolution 360dpi/360 DPI: "<</HWResolution[360 360]>>setpagedevice{0.6666 exp}bind settransfer"
+*Resolution 720dpi/720 DPI: "<</HWResolution[720 720]>>setpagedevice{0.4 exp}bind settransfer"
+*CloseUI: *Resolution
+
+*OpenUI *ColorModel/Output Mode: PickOne
+*OrderDependency: 10 AnySetup *ColorModel
+*DefaultColorModel: CMYK
+*ColorModel CMYK/Color: "<</cupsColorOrder 1/cupsColorSpace 9/cupsCompression 1>>setpagedevice"
+*ColorModel Gray/Grayscale: "<</cupsColorOrder 0/cupsColorSpace 3/cupsCompression 1>>setpagedevice"
+*CloseUI: *ColorModel
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/ppd/stphoto2.ppd b/ppd/stphoto2.ppd
new file mode 100644
index 000000000..c944f4133
--- /dev/null
+++ b/ppd/stphoto2.ppd
@@ -0,0 +1,132 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Sample EPSON Stylus Photo driver PPD file for the Common UNIX Printing
+*% System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "STPHOTO2.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: True
+*cupsModelNumber: 5
+*cupsFilter: "application/vnd.cups-raster 0 rastertoepson"
+*cupsColorProfile 180dpi/-: "1.0 1.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0"
+*cupsColorProfile 360dpi/-: "1.0 1.5 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0"
+*cupsColorProfile 720dpi/-: "1.0 2.5 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0"
+*ModelName: "EPSON New Stylus Photo Series"
+*ShortNickName: "EPSON New Stylus Photo Series"
+*NickName: "EPSON New Stylus Photo Series CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: RGB
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter: "8.60 39.60 603.40 766.49"
+*ImageableArea Legal: "8.60 39.60 603.40 982.49"
+*ImageableArea A4: "8.60 39.60 586.40 816.49"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter: "612 792"
+*PaperDimension Legal: "612 1008"
+*PaperDimension A4: "595 842"
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 360dpi
+*Resolution 180dpi/180 DPI: "<</HWResolution[180 180]>>setpagedevice"
+*Resolution 360dpi/360 DPI: "<</HWResolution[360 360]>>setpagedevice{0.6666 exp}bind settransfer"
+*Resolution 720dpi/720 DPI: "<</HWResolution[720 720]>>setpagedevice{0.4 exp}bind settransfer"
+*CloseUI: *Resolution
+
+*OpenUI *ColorModel/Output Mode: PickOne
+*OrderDependency: 10 AnySetup *ColorModel
+*DefaultColorModel: CMYK
+*ColorModel CMYK/Color: "<</cupsColorOrder 1/cupsColorSpace 9/cupsCompression 1>>setpagedevice"
+*ColorModel Gray/Grayscale: "<</cupsColorOrder 0/cupsColorSpace 3/cupsCompression 1>>setpagedevice"
+*CloseUI: *ColorModel
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/pstoraster/.cvsignore b/pstoraster/.cvsignore
new file mode 100644
index 000000000..cf5b1a290
--- /dev/null
+++ b/pstoraster/.cvsignore
@@ -0,0 +1,3 @@
+pstoraster
+genarch
+arch.h
diff --git a/pstoraster/README.pstoraster b/pstoraster/README.pstoraster
new file mode 100644
index 000000000..56ca09039
--- /dev/null
+++ b/pstoraster/README.pstoraster
@@ -0,0 +1,63 @@
+README.pstoraster - 04/23/2002
+------------------------------
+
+INTRODUCTION
+
+ This directory contains the CUPS "driver" for GNU
+ Ghostscript, the pstoraster script that is used to run
+ Ghostscript as a CUPS filter, the pstoraster.convs file that
+ defines the PostScript to raster filter for CUPS drivers,
+ and a makefile fragment that adds the CUPS driver.
+
+ This software is included with both the CUPS and ESP
+ Ghostscript 7.05.1 distributions. While the files will also
+ compile with earlier versions of Ghostscript, there are bugs
+ in older versions of GNU Ghostscript which may cause
+ problems.
+
+
+COMPILING ESP GHOSTSCRIPT WITH THE CUPS DRIVER
+
+ Normally the CUPS driver will be automatically included when
+ you use the configure script supplied with ESP Ghostscript.
+ To use the CUPS driver with the traditional Ghostscript
+ makefiles, add the following include line to the end of the
+ makefile:
+
+ include pstoraster/cups.mak
+
+ Then add "$(DD)cups.dev" to any of the DEVICE_DEVS lines.
+
+ Once you have compiled and installed Ghostscript, restart
+ the cupsd process, either by sending the HUP signal to the
+ process or using the init script supplied with CUPS.
+
+
+COMPILING GNU GHOSTSCRIPT WITH THE CUPS DRIVER
+
+ Before configuring GNU Ghostscript, first copy this directory
+ to the GNU Ghostscript source directory, e.g.:
+
+ cp -r pstoraster /some/path/to/ghostscript-7.05
+
+ Next apply the patch:
+
+ cd /some/path/to/ghostscript-7.05
+ patch -p1 pstoraster/ghostscript-705.patch
+
+ Finally, run the configure script to use the new Ghostscript
+ with CUPS:
+
+ ./configure [any configure options you want]
+
+ To use the CUPS driver with the traditional Ghostscript
+ makefiles, add the following include line to the end of the
+ makefile:
+
+ include pstoraster/cups.mak
+
+ Then add "$(DD)cups.dev" to any of the DEVICE_DEVS lines.
+
+ Once you have compiled and installed Ghostscript, restart
+ the cupsd process, either by sending the HUP signal to the
+ process or using the init script supplied with CUPS.
diff --git a/pstoraster/cups.mak b/pstoraster/cups.mak
new file mode 100644
index 000000000..9404e5167
--- /dev/null
+++ b/pstoraster/cups.mak
@@ -0,0 +1,48 @@
+#
+# "$Id: cups.mak 2400 2002-05-13 16:21:23Z mike $"
+#
+# CUPS driver makefile for Ghostscript.
+#
+# Copyright 2001-2002 by Easy Software Products.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+### ----------------- CUPS Ghostscript Driver ---------------------- ###
+
+cups_= $(GLOBJ)gdevcups.$(OBJ)
+
+CUPSSERVER= $(install_prefix)`cups-config --serverbin`
+CUPSCONFIG= $(install_prefix)`cups-config --serverroot`
+
+$(DD)cups.dev: $(cups_) $(GLD)page.dev
+ $(ADDMOD) $(DD)cups -lib cupsimage -lib cups
+ $(SETPDEV2) $(DD)cups $(cups_)
+
+$(GLOBJ)gdevcups.$(OBJ): pstoraster/gdevcups.c $(PDEVH)
+ $(GLCC) $(GLO_)gdevcups.$(OBJ) $(C_) pstoraster/gdevcups.c
+
+install: install-cups
+
+install-cups:
+ -mkdir -p $(CUPSSERVER)/filter
+ $(INSTALL_PROGRAM) pstoraster/pstoraster $(CUPSSERVER)/filter
+ -mkdir -p $(CUPSCONFIG)
+ $(INSTALL_DATA) pstoraster/pstoraster.convs $(CUPSCONFIG)
+
+
+#
+# End of "$Id: cups.mak 2400 2002-05-13 16:21:23Z mike $".
+#
diff --git a/pstoraster/gdevcups.c b/pstoraster/gdevcups.c
new file mode 100644
index 000000000..418cbd7e2
--- /dev/null
+++ b/pstoraster/gdevcups.c
@@ -0,0 +1,3457 @@
+/*
+ * "$Id$"
+ *
+ * GNU Ghostscript raster output driver for the Common UNIX Printing
+ * System (CUPS).
+ *
+ * Copyright 1993-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This code and any derivative of it may be used and distributed
+ * freely under the terms of the GNU General Public License when
+ * used with GNU Ghostscript or its derivatives. Use of the code
+ * (or any derivative of it) with software other than GNU
+ * GhostScript (or its derivatives) is governed by the CUPS license
+ * agreement.
+ *
+ * Contents:
+ *
+ * cups_close() - Close the output file.
+ * cups_get_matrix() - Generate the default page matrix.
+ * cups_get_params() - Get pagedevice parameters.
+ * cups_get_space_params() - Get space parameters from the RIP_CACHE env var.
+ * cups_map_color_rgb() - Map a color index to an RGB color.
+ * cups_map_cielab() - Map CIE Lab transformation...
+ * cups_map_rgb_color() - Map an RGB color to a color index. We map the
+ * RGB color to the output colorspace & bits (we
+ * figure out the format when we output a page).
+ * cups_open() - Open the output file and initialize things.
+ * cups_print_pages() - Send one or more pages to the output file.
+ * cups_put_params() - Set pagedevice parameters.
+ * cups_set_color_info() - Set the color information structure based on
+ * the required output.
+ * cups_print_chunked() - Print a page of chunked pixels.
+ * cups_print_banded() - Print a page of banded pixels.
+ * cups_print_planar() - Print a page of planar pixels.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "std.h" /* to stop stdlib.h redefining types */
+#include "gdevprn.h"
+#include "gsparam.h"
+#include "gsexit.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <cups/raster.h>
+#include <cups/ppd.h>
+#include <math.h>
+
+#undef private
+#define private
+
+
+/*
+ * Globals...
+ */
+
+char *cupsProfile = NULL;
+
+
+/*
+ * Macros...
+ */
+
+#define x_dpi (pdev->HWResolution[0])
+#define y_dpi (pdev->HWResolution[1])
+#define cups ((gx_device_cups *)pdev)
+
+/*
+ * Macros from <macros.h>; we can't include <macros.h> because it also
+ * defines DEBUG, one of our flags to insert various debugging code.
+ */
+
+#ifndef max
+# define max(a,b) ((a)<(b) ? (b) : (a))
+#endif /* !max */
+
+#ifndef min
+# define min(a,b) ((a)>(b) ? (b) : (a))
+#endif /* !min */
+
+#ifndef abs
+# define abs(x) ((x)>=0 ? (x) : -(x))
+#endif /* !abs */
+
+
+/*
+ * Procedures
+ */
+
+private dev_proc_close_device(cups_close);
+private dev_proc_get_initial_matrix(cups_get_matrix);
+private int cups_get_params(gx_device *, gs_param_list *);
+private dev_proc_map_cmyk_color(cups_map_cmyk_color);
+private dev_proc_map_color_rgb(cups_map_color_rgb);
+private dev_proc_map_rgb_color(cups_map_rgb_color);
+private dev_proc_open_device(cups_open);
+private int cups_print_pages(gx_device_printer *, FILE *, int);
+private int cups_put_params(gx_device *, gs_param_list *);
+private void cups_set_color_info(gx_device *);
+private dev_proc_sync_output(cups_sync_output);
+private prn_dev_proc_get_space_params(cups_get_space_params);
+
+
+/*
+ * The device descriptors...
+ */
+
+typedef struct gx_device_cups_s
+{
+ gx_device_common; /* Standard GhostScript device stuff */
+ gx_prn_device_common; /* Standard printer device stuff */
+ int page; /* Page number */
+ cups_raster_t *stream; /* Raster stream */
+ ppd_file_t *ppd; /* PPD file for this printer */
+ cups_page_header_t header; /* PostScript page device info */
+} gx_device_cups;
+
+private gx_device_procs cups_procs =
+{
+ cups_open,
+ cups_get_matrix,
+ cups_sync_output,
+ gdev_prn_output_page,
+ cups_close,
+ cups_map_rgb_color,
+ cups_map_color_rgb,
+ NULL, /* fill_rectangle */
+ NULL, /* tile_rectangle */
+ NULL, /* copy_mono */
+ NULL, /* copy_color */
+ NULL, /* draw_line */
+ gx_default_get_bits,
+ cups_get_params,
+ cups_put_params,
+ NULL, /* map_cmyk_color */
+ NULL, /* get_xfont_procs */
+ NULL, /* get_xfont_device */
+ NULL, /* map_rgb_alpha_color */
+ gx_page_device_get_page_device,
+ NULL, /* get_alpha_bits */
+ NULL, /* copy_alpha */
+ NULL, /* get_band */
+ NULL, /* copy_rop */
+ NULL, /* fill_path */
+ NULL, /* stroke_path */
+ NULL, /* fill_mask */
+ NULL, /* fill_trapezoid */
+ NULL, /* fill_parallelogram */
+ NULL, /* fill_triangle */
+ NULL, /* draw_thin_line */
+ NULL, /* begin_image */
+ NULL, /* image_data */
+ NULL, /* end_image */
+ NULL, /* strip_tile_rectangle */
+ NULL /* strip_copy_rop */
+};
+
+#define prn_device_body_copies(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_pages)\
+ std_device_full_body_type(dtype, &procs, dname, &st_device_printer,\
+ (int)((long)(w10) * (xdpi) / 10),\
+ (int)((long)(h10) * (ydpi) / 10),\
+ xdpi, ydpi,\
+ ncomp, depth, mg, mc, dg, dc,\
+ -(lo) * (xdpi), -(to) * (ydpi),\
+ (lm) * 72.0, (bm) * 72.0,\
+ (rm) * 72.0, (tm) * 72.0\
+ ),\
+ prn_device_body_copies_rest_(print_pages)
+
+gx_device_cups gs_cups_device =
+{
+ prn_device_body_copies(gx_device_cups, /* type */
+ cups_procs, /* procedures */
+ "cups", /* device name */
+ 85, /* initial width */
+ 110, /* initial height */
+ 100, /* initial x resolution */
+ 100, /* initial y resolution */
+ 0, /* initial left offset */
+ 0, /* initial top offset */
+ 0, /* initial left margin */
+ 0, /* initial bottom margin */
+ 0, /* initial right margin */
+ 0, /* initial top margin */
+ 1, /* number of color components */
+ 1, /* number of color bits */
+ 1, /* maximum gray value */
+ 0, /* maximum color value */
+ 2, /* number of gray values */
+ 0, /* number of color values */
+ cups_print_pages), /* print procedure */
+ 0, /* page */
+ NULL, /* stream */
+ NULL, /* ppd */
+ { /* header */
+ "", /* MediaClass */
+ "", /* MediaColor */
+ "", /* MediaType */
+ "", /* OutputType */
+ 0, /* AdvanceDistance */
+ CUPS_ADVANCE_NONE, /* AdvanceMedia */
+ CUPS_FALSE, /* Collate */
+ CUPS_CUT_NONE, /* CutMedia */
+ CUPS_FALSE, /* Duplex */
+ { 100, 100 }, /* HWResolution */
+ { 0, 0, 612, 792 }, /* ImagingBoundingBox */
+ CUPS_FALSE, /* InsertSheet */
+ CUPS_JOG_NONE, /* Jog */
+ CUPS_EDGE_TOP, /* LeadingEdge */
+ { 0, 0 }, /* Margins */
+ CUPS_FALSE, /* ManualFeed */
+ 0, /* MediaPosition */
+ 0, /* MediaWeight */
+ CUPS_FALSE, /* MirrorPrint */
+ CUPS_FALSE, /* NegativePrint */
+ 1, /* NumCopies */
+ CUPS_ORIENT_0, /* Orientation */
+ CUPS_FALSE, /* OutputFaceUp */
+ { 612, 792 }, /* PageSize */
+ CUPS_FALSE, /* Separations */
+ CUPS_FALSE, /* TraySwitch */
+ CUPS_FALSE, /* Tumble */
+ 850, /* cupsWidth */
+ 1100, /* cupsHeight */
+ 0, /* cupsMediaType */
+ 1, /* cupsBitsPerColor */
+ 1, /* cupsBitsPerPixel */
+ 107, /* cupsBytesPerLine */
+ CUPS_ORDER_CHUNKED, /* cupsColorOrder */
+ CUPS_CSPACE_K, /* cupsColorSpace */
+ 0, /* cupsCompression */
+ 0, /* cupsRowCount */
+ 0, /* cupsRowFeed */
+ 0 /* cupsRowStep */
+ }
+};
+
+/*
+ * Color lookup tables...
+ */
+
+static gx_color_value lut_color_rgb[256];
+static unsigned char lut_rgb_color[gx_max_color_value + 1];
+static int cupsHaveProfile = 0;
+static int cupsMatrix[3][3][gx_max_color_value + 1];
+static int cupsDensity[gx_max_color_value + 1];
+static unsigned char rev_lower1[16] =
+ {
+ 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
+ 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
+ },
+ rev_upper1[16] =
+ {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0
+ },
+ rev_lower2[16] = /* 2-bit colors */
+ {
+ 0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d,
+ 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f
+ },
+ rev_upper2[16] = /* 2-bit colors */
+ {
+ 0x00, 0x40, 0x80, 0xc0, 0x10, 0x50, 0x90, 0xd0,
+ 0x20, 0x60, 0xa0, 0xe0, 0x30, 0x70, 0xb0, 0xf0
+ };
+
+
+/*
+ * Local functions...
+ */
+
+static double cups_map_cielab(double, double);
+static void cups_print_chunked(gx_device_printer *, unsigned char *,
+ unsigned char *, int);
+static void cups_print_banded(gx_device_printer *, unsigned char *,
+ unsigned char *, int);
+static void cups_print_planar(gx_device_printer *, unsigned char *,
+ unsigned char *, int);
+
+/*static void cups_set_margins(gx_device *);*/
+
+
+/*
+ * 'cups_close()' - Close the output file.
+ */
+
+private int
+cups_close(gx_device *pdev) /* I - Device info */
+{
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cups_close(%p)\n", pdev);
+#endif /* DEBUG */
+
+ if (cups->stream != NULL)
+ {
+ cupsRasterClose(cups->stream);
+ cups->stream = NULL;
+ }
+
+#if 0 /* Can't do this here because put_params() might close the device */
+ if (cups->ppd != NULL)
+ {
+ ppdClose(cups->ppd);
+ cups->ppd = NULL;
+ }
+
+ if (cupsProfile != NULL)
+ {
+ free(cupsProfile);
+ cupsProfile = NULL;
+ }
+#endif /* 0 */
+
+ return (gdev_prn_close(pdev));
+}
+
+
+/*
+ * 'cups_get_matrix()' - Generate the default page matrix.
+ */
+
+private void
+cups_get_matrix(gx_device *pdev, /* I - Device info */
+ gs_matrix *pmat) /* O - Physical transform matrix */
+{
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cups_get_matrix(%p, %p)\n", pdev, pmat);
+#endif /* DEBUG */
+
+ /*
+ * Set the raster width and height...
+ */
+
+ cups->header.cupsWidth = cups->width;
+ cups->header.cupsHeight = cups->height;
+
+ /*
+ * Set the transform matrix...
+ */
+
+ fprintf(stderr, "DEBUG: cups->header.Duplex = %d\n", cups->header.Duplex);
+ fprintf(stderr, "DEBUG: cups->page = %d\n", cups->page);
+ if (cups->ppd)
+ {
+ fprintf(stderr, "DEBUG: cups->ppd = %p\n", cups->ppd);
+ fprintf(stderr, "DEBUG: cups->ppd->flip_duplex = %d\n", cups->ppd->flip_duplex);
+ }
+
+ if (cups->header.Duplex && !cups->header.Tumble &&
+ cups->ppd && cups->ppd->flip_duplex && !(cups->page & 1))
+ {
+ pmat->xx = (float)cups->header.HWResolution[0] / 72.0;
+ pmat->xy = 0.0;
+ pmat->yx = 0.0;
+ pmat->yy = (float)cups->header.HWResolution[1] / 72.0;
+ pmat->tx = -(float)cups->header.HWResolution[0] * pdev->HWMargins[2] / 72.0;
+ pmat->ty = -(float)cups->header.HWResolution[1] * pdev->HWMargins[3] / 72.0;
+ }
+ else
+ {
+ pmat->xx = (float)cups->header.HWResolution[0] / 72.0;
+ pmat->xy = 0.0;
+ pmat->yx = 0.0;
+ pmat->yy = -(float)cups->header.HWResolution[1] / 72.0;
+ pmat->tx = -(float)cups->header.HWResolution[0] * pdev->HWMargins[0] / 72.0;
+ pmat->ty = (float)cups->header.HWResolution[1] *
+ ((float)cups->header.PageSize[1] - pdev->HWMargins[3]) / 72.0;
+ }
+
+ fprintf(stderr, "DEBUG: width = %d, height = %d\n", cups->width,
+ cups->height);
+ fprintf(stderr, "DEBUG: PageSize = [ %d %d ], HWResolution = [ %d %d ]\n",
+ cups->header.PageSize[0], cups->header.PageSize[1],
+ cups->header.HWResolution[0], cups->header.HWResolution[1]);
+ fprintf(stderr, "DEBUG: HWMargins = [ %.3f %.3f %.3f %.3f ]\n",
+ pdev->HWMargins[0], pdev->HWMargins[1], pdev->HWMargins[2],
+ pdev->HWMargins[3]);
+ fprintf(stderr, "DEBUG: matrix = [ %.3f %.3f %.3f %.3f %.3f %.3f ]\n",
+ pmat->xx, pmat->xy, pmat->yx, pmat->yy, pmat->tx, pmat->ty);
+}
+
+
+/*
+ * 'cups_get_params()' - Get pagedevice parameters.
+ */
+
+private int /* O - Error status */
+cups_get_params(gx_device *pdev, /* I - Device info */
+ gs_param_list *plist) /* I - Parameter list */
+{
+ int code; /* Return code */
+ gs_param_string s; /* Temporary string value */
+ bool b; /* Temporary boolean value */
+
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cups_get_params(%p, %p)\n", pdev, plist);
+#endif /* DEBUG */
+
+ /*
+ * First process the "standard" page device parameters...
+ */
+
+#ifdef DEBUG
+ fputs("DEBUG: before gdev_prn_get_params()\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = gdev_prn_get_params(pdev, plist)) < 0)
+ return (code);
+
+#ifdef DEBUG
+ fputs("DEBUG: after gdev_prn_get_params()\n", stderr);
+#endif /* DEBUG */
+
+ /*
+ * Then write the CUPS parameters...
+ */
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: MediaClass\n", stderr);
+#endif /* DEBUG */
+
+ param_string_from_string(s, cups->header.MediaClass);
+ if ((code = param_write_string(plist, "MediaClass", &s)) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: AdvanceDistance\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "AdvanceDistance",
+ (int *)&(cups->header.AdvanceDistance))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: AdvanceDistance\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "AdvanceMedia",
+ (int *)&(cups->header.AdvanceMedia))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: Collate\n", stderr);
+#endif /* DEBUG */
+
+ b = cups->header.Collate;
+ if ((code = param_write_bool(plist, "Collate", &b)) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: CutMedia\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "CutMedia",
+ (int *)&(cups->header.CutMedia))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: InsertSheet\n", stderr);
+#endif /* DEBUG */
+
+ b = cups->header.InsertSheet;
+ if ((code = param_write_bool(plist, "InsertSheet", &b)) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: Jog\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "Jog",
+ (int *)&(cups->header.Jog))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: LeadingEdge\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "LeadingEdge",
+ (int *)&(cups->header.LeadingEdge))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: ManualFeed\n", stderr);
+#endif /* DEBUG */
+
+ b = cups->header.ManualFeed;
+ if ((code = param_write_bool(plist, "ManualFeed", &b)) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: MediaPosition\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "MediaPosition",
+ (int *)&(cups->header.MediaPosition))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: MirrorPrint\n", stderr);
+#endif /* DEBUG */
+
+ b = cups->header.MirrorPrint;
+ if ((code = param_write_bool(plist, "MirrorPrint", &b)) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: NegativePrint\n", stderr);
+#endif /* DEBUG */
+
+ b = cups->header.NegativePrint;
+ if ((code = param_write_bool(plist, "NegativePrint", &b)) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: OutputFaceUp\n", stderr);
+#endif /* DEBUG */
+
+ b = cups->header.OutputFaceUp;
+ if ((code = param_write_bool(plist, "OutputFaceUp", &b)) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: Separations\n", stderr);
+#endif /* DEBUG */
+
+ b = cups->header.Separations;
+ if ((code = param_write_bool(plist, "Separations", &b)) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: TraySwitch\n", stderr);
+#endif /* DEBUG */
+
+ b = cups->header.TraySwitch;
+ if ((code = param_write_bool(plist, "TraySwitch", &b)) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: Tumble\n", stderr);
+#endif /* DEBUG */
+
+ b = cups->header.Tumble;
+ if ((code = param_write_bool(plist, "Tumble", &b)) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsWidth\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsWidth",
+ (int *)&(cups->header.cupsWidth))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsHeight\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsHeight",
+ (int *)&(cups->header.cupsHeight))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsMediaType\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsMediaType",
+ (int *)&(cups->header.cupsMediaType))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsBitsPerColor\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsBitsPerColor",
+ (int *)&(cups->header.cupsBitsPerColor))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsBitsPerPixel\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsBitsPerPixel",
+ (int *)&(cups->header.cupsBitsPerPixel))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsBytesPerLine\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsBytesPerLine",
+ (int *)&(cups->header.cupsBytesPerLine))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsColorOrder\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsColorOrder",
+ (int *)&(cups->header.cupsColorOrder))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsColorSpace\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsColorSpace",
+ (int *)&(cups->header.cupsColorSpace))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsCompression\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsCompression",
+ (int *)&(cups->header.cupsCompression))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsRowCount\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsRowCount",
+ (int *)&(cups->header.cupsRowCount))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsRowFeed\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsRowFeed",
+ (int *)&(cups->header.cupsRowFeed))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fputs("DEBUG: cupsRowStep\n", stderr);
+#endif /* DEBUG */
+
+ if ((code = param_write_int(plist, "cupsRowStep",
+ (int *)&(cups->header.cupsRowStep))) < 0)
+ return (code);
+
+#ifdef DEBUG
+ fputs("DEBUG: Leaving cups_get_params()\n", stderr);
+#endif /* DEBUG */
+
+ return (0);
+}
+
+
+/*
+ * 'cups_get_space_params()' - Get space parameters from the RIP_CACHE env var.
+ */
+
+#define TILE_SIZE 256
+
+void
+cups_get_space_params(const gx_device_printer *pdev,
+ /* I - Printer device */
+ gdev_prn_space_params *space_params)
+ /* O - Space parameters */
+{
+ float cache_size; /* Size of tile cache in bytes */
+ char *cache_env, /* Cache size environment variable */
+ cache_units[255]; /* Cache size units */
+
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cups_get_space_params(%p, %p)\n", pdev, space_params);
+#endif /* DEBUG */
+
+ if ((cache_env = getenv("RIP_MAX_CACHE")) != NULL)
+ {
+ switch (sscanf(cache_env, "%f%254s", &cache_size, cache_units))
+ {
+ case 0 :
+ cache_size = 8 * 1024 * 1024;
+ break;
+ case 1 :
+ cache_size *= 4 * TILE_SIZE * TILE_SIZE;
+ break;
+ case 2 :
+ if (tolower(cache_units[0]) == 'g')
+ cache_size *= 1024 * 1024 * 1024;
+ else if (tolower(cache_units[0]) == 'm')
+ cache_size *= 1024 * 1024;
+ else if (tolower(cache_units[0]) == 'k')
+ cache_size *= 1024;
+ else if (tolower(cache_units[0]) == 't')
+ cache_size *= 4 * TILE_SIZE * TILE_SIZE;
+ break;
+ }
+ }
+ else
+ cache_size = 8 * 1024 * 1024;
+
+ fprintf(stderr, "DEBUG: cache_size = %.0f\n", cache_size);
+
+ space_params->MaxBitmap = (int)cache_size;
+ space_params->BufferSpace = (int)cache_size / 10;
+}
+
+
+/*
+ * 'cups_map_cmyk_color()' - Map a CMYK color to a color index.
+ *
+ * This function is only called when a 4 or 6 color colorspace is
+ * selected for output. CMYK colors are *not* corrected but *are*
+ * density adjusted.
+ */
+
+private gx_color_index /* O - Color index */
+cups_map_cmyk_color(gx_device *pdev, /* I - Device info */
+ gx_color_value c, /* I - Cyan value */
+ gx_color_value m, /* I - Magenta value */
+ gx_color_value y, /* I - Yellow value */
+ gx_color_value k) /* I - Black value */
+{
+ gx_color_index i; /* Temporary index */
+ gx_color_value ic, im, iy, ik; /* Integral CMYK values */
+
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fprintf(stderr, "DEBUG: cups_map_cmyk_color(%p, %d, %d, %d, %d)\n", pdev,
+ c, m, y, k);
+#endif /* DEBUG */
+
+ /*
+ * Setup the color info data as needed...
+ */
+
+ if (pdev->color_info.num_components == 0)
+ cups_set_color_info(pdev);
+
+ /*
+ * Density correct...
+ */
+
+ if (cupsHaveProfile)
+ {
+ c = cupsDensity[c];
+ m = cupsDensity[m];
+ y = cupsDensity[y];
+ k = cupsDensity[k];
+ }
+
+ ic = lut_rgb_color[c];
+ im = lut_rgb_color[m];
+ iy = lut_rgb_color[y];
+ ik = lut_rgb_color[k];
+
+ /*
+ * Convert the CMYK color to a color index...
+ */
+
+ switch (cups->header.cupsColorSpace)
+ {
+ default :
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ i = (((((ic << 1) | im) << 1) | iy) << 1) | ik;
+ break;
+ case 2 :
+ i = (((((ic << 2) | im) << 2) | iy) << 2) | ik;
+ break;
+ case 4 :
+ i = (((((ic << 4) | im) << 4) | iy) << 4) | ik;
+ break;
+ case 8 :
+ i = (((((ic << 8) | im) << 8) | iy) << 8) | ik;
+ break;
+ }
+ break;
+
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ i = (((((iy << 1) | im) << 1) | ic) << 1) | ik;
+ break;
+ case 2 :
+ i = (((((iy << 2) | im) << 2) | ic) << 2) | ik;
+ break;
+ case 4 :
+ i = (((((iy << 4) | im) << 4) | ic) << 4) | ik;
+ break;
+ case 8 :
+ i = (((((iy << 8) | im) << 8) | ic) << 8) | ik;
+ break;
+ }
+ break;
+
+ case CUPS_CSPACE_KCMYcm :
+ if (cups->header.cupsBitsPerColor == 1)
+ {
+ if (ik)
+ i = 32;
+ else
+ i = 0;
+
+ if (ic && im)
+ i |= 17;
+ else if (ic && iy)
+ i |= 6;
+ else if (im && iy)
+ i |= 12;
+ else if (ic)
+ i |= 16;
+ else if (im)
+ i |= 8;
+ else if (iy)
+ i |= 4;
+ break;
+ }
+
+ case CUPS_CSPACE_KCMY :
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ i = (((((ik << 1) | ic) << 1) | im) << 1) | iy;
+ break;
+ case 2 :
+ i = (((((ik << 2) | ic) << 2) | im) << 2) | iy;
+ break;
+ case 4 :
+ i = (((((ik << 4) | ic) << 4) | im) << 4) | iy;
+ break;
+ case 8 :
+ i = (((((ik << 8) | ic) << 8) | im) << 8) | iy;
+ break;
+ }
+ break;
+ }
+
+ if (gs_log_errors > 1)
+ fprintf(stderr, "DEBUG: CMYK (%d,%d,%d,%d) -> CMYK %08x (%d,%d,%d,%d)\n",
+ c, m, y, k, (unsigned)i, ic, im, iy, ik);
+
+ /*
+ * Make sure we don't get a CMYK color of 255, 255, 255, 255...
+ */
+
+ if (i == gx_no_color_index)
+ i --;
+
+ return (i);
+}
+
+
+/*
+ * 'cups_map_color_rgb()' - Map a color index to an RGB color.
+ */
+
+private int
+cups_map_color_rgb(gx_device *pdev, /* I - Device info */
+ gx_color_index color, /* I - Color index */
+ gx_color_value prgb[3]) /* O - RGB values */
+{
+ unsigned char c0, c1, c2, c3; /* Color index components */
+ gx_color_value k, divk; /* Black & divisor */
+
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cups_map_color_rgb(%p, %d, %p)\n", pdev,
+ (unsigned)color, prgb);
+#endif /* DEBUG */
+
+ /*
+ * Setup the color info data as needed...
+ */
+
+ if (pdev->color_info.num_components == 0)
+ cups_set_color_info(pdev);
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fprintf(stderr, "DEBUG: COLOR %08x = ", (unsigned)color);
+#endif /* DEBUG */
+
+ /*
+ * Extract the color components from the color index...
+ */
+
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ c3 = color & 1;
+ color >>= 1;
+ c2 = color & 1;
+ color >>= 1;
+ c1 = color & 1;
+ color >>= 1;
+ c0 = color;
+ break;
+ case 2 :
+ c3 = color & 3;
+ color >>= 2;
+ c2 = color & 3;
+ color >>= 2;
+ c1 = color & 3;
+ color >>= 2;
+ c0 = color;
+ break;
+ case 4 :
+ c3 = color & 15;
+ color >>= 4;
+ c2 = color & 15;
+ color >>= 4;
+ c1 = color & 15;
+ color >>= 4;
+ c0 = color;
+ break;
+ case 8 :
+ c3 = color & 255;
+ color >>= 8;
+ c2 = color & 255;
+ color >>= 8;
+ c1 = color & 255;
+ color >>= 8;
+ c0 = color;
+ break;
+ }
+
+ /*
+ * Convert the color components to RGB...
+ */
+
+ switch (cups->header.cupsColorSpace)
+ {
+ case CUPS_CSPACE_K :
+ case CUPS_CSPACE_WHITE :
+ case CUPS_CSPACE_GOLD :
+ case CUPS_CSPACE_SILVER :
+ prgb[0] =
+ prgb[1] =
+ prgb[2] = lut_color_rgb[c3];
+ break;
+
+ case CUPS_CSPACE_W :
+ prgb[0] =
+ prgb[1] =
+ prgb[2] = lut_color_rgb[c3];
+ break;
+
+ case CUPS_CSPACE_RGB :
+ prgb[0] = lut_color_rgb[c1];
+ prgb[1] = lut_color_rgb[c2];
+ prgb[2] = lut_color_rgb[c3];
+ break;
+
+ case CUPS_CSPACE_RGBA :
+ prgb[0] = lut_color_rgb[c0];
+ prgb[1] = lut_color_rgb[c1];
+ prgb[2] = lut_color_rgb[c2];
+ break;
+
+ case CUPS_CSPACE_CMY :
+ prgb[0] = lut_color_rgb[c1];
+ prgb[1] = lut_color_rgb[c2];
+ prgb[2] = lut_color_rgb[c3];
+ break;
+
+ case CUPS_CSPACE_YMC :
+ prgb[0] = lut_color_rgb[c3];
+ prgb[1] = lut_color_rgb[c2];
+ prgb[2] = lut_color_rgb[c1];
+ break;
+
+ case CUPS_CSPACE_KCMY :
+ case CUPS_CSPACE_KCMYcm :
+ k = lut_color_rgb[c0];
+ divk = gx_max_color_value - k;
+ if (divk == 0)
+ {
+ prgb[0] = 0;
+ prgb[1] = 0;
+ prgb[2] = 0;
+ }
+ else
+ {
+ prgb[0] = gx_max_color_value + divk -
+ gx_max_color_value * c1 / divk;
+ prgb[1] = gx_max_color_value + divk -
+ gx_max_color_value * c2 / divk;
+ prgb[2] = gx_max_color_value + divk -
+ gx_max_color_value * c3 / divk;
+ }
+ break;
+
+ case CUPS_CSPACE_CMYK :
+ k = lut_color_rgb[c3];
+ divk = gx_max_color_value - k;
+ if (divk == 0)
+ {
+ prgb[0] = 0;
+ prgb[1] = 0;
+ prgb[2] = 0;
+ }
+ else
+ {
+ prgb[0] = gx_max_color_value + divk -
+ gx_max_color_value * c0 / divk;
+ prgb[1] = gx_max_color_value + divk -
+ gx_max_color_value * c1 / divk;
+ prgb[2] = gx_max_color_value + divk -
+ gx_max_color_value * c2 / divk;
+ }
+ break;
+
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ k = lut_color_rgb[c3];
+ divk = gx_max_color_value - k;
+ if (divk == 0)
+ {
+ prgb[0] = 0;
+ prgb[1] = 0;
+ prgb[2] = 0;
+ }
+ else
+ {
+ prgb[0] = gx_max_color_value + divk -
+ gx_max_color_value * c2 / divk;
+ prgb[1] = gx_max_color_value + divk -
+ gx_max_color_value * c1 / divk;
+ prgb[2] = gx_max_color_value + divk -
+ gx_max_color_value * c0 / divk;
+ }
+ break;
+
+#ifdef CUPS_RASTER_HAVE_COLORIMETRIC
+ case CUPS_CSPACE_CIEXYZ :
+ case CUPS_CSPACE_CIELab :
+ case CUPS_CSPACE_ICC1 :
+ case CUPS_CSPACE_ICC2 :
+ case CUPS_CSPACE_ICC3 :
+ case CUPS_CSPACE_ICC4 :
+ case CUPS_CSPACE_ICC5 :
+ case CUPS_CSPACE_ICC6 :
+ case CUPS_CSPACE_ICC7 :
+ case CUPS_CSPACE_ICC8 :
+ case CUPS_CSPACE_ICC9 :
+ case CUPS_CSPACE_ICCA :
+ case CUPS_CSPACE_ICCB :
+ case CUPS_CSPACE_ICCC :
+ case CUPS_CSPACE_ICCD :
+ case CUPS_CSPACE_ICCE :
+ case CUPS_CSPACE_ICCF :
+ break;
+#endif /* CUPS_RASTER_HAVE_COLORIMETRIC */
+ }
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fprintf(stderr, "%d,%d,%d\n", prgb[0], prgb[1], prgb[2]);
+#endif /* DEBUG */
+
+ return (0);
+}
+
+
+/*
+ * 'cups_map_cielab()' - Map CIE Lab transformation...
+ */
+
+static double /* O - Adjusted color value */
+cups_map_cielab(double x, /* I - Raw color value */
+ double xn) /* I - Whitepoint color value */
+{
+ double x_xn; /* Fraction of whitepoint */
+
+
+ x_xn = x / xn;
+
+ if (x_xn > 0.008856)
+ return (cbrt(x_xn));
+ else
+ return (7.787 * x_xn + 16.0 / 116.0);
+}
+
+
+/*
+ * 'cups_map_rgb_color()' - Map an RGB color to a color index. We map the
+ * RGB color to the output colorspace & bits (we
+ * figure out the format when we output a page).
+ */
+
+private gx_color_index /* O - Color index */
+cups_map_rgb_color(gx_device *pdev, /* I - Device info */
+ gx_color_value r, /* I - Red value */
+ gx_color_value g, /* I - Green value */
+ gx_color_value b) /* I - Blue value */
+{
+ gx_color_index i; /* Temporary index */
+ gx_color_value ic, im, iy, ik; /* Integral CMYK values */
+ gx_color_value mk; /* Maximum K value */
+ int tc, tm, ty; /* Temporary color values */
+ float rr, rg, rb, /* Real RGB colors */
+ ciex, ciey, ciez, /* CIE XYZ colors */
+ ciey_yn, /* Normalized luminance */
+ ciel, ciea, cieb; /* CIE Lab colors */
+
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cups_map_rgb_color(%p, %d, %d, %d)\n", pdev, r, g, b);
+#endif /* DEBUG */
+
+ /*
+ * Setup the color info data as needed...
+ */
+
+ if (pdev->color_info.num_components == 0)
+ cups_set_color_info(pdev);
+
+ /*
+ * Do color correction as needed...
+ */
+
+ if (cupsHaveProfile)
+ {
+ /*
+ * Compute CMYK values...
+ */
+
+ ic = gx_max_color_value - r;
+ im = gx_max_color_value - g;
+ iy = gx_max_color_value - b;
+ ik = min(ic, min(im, iy));
+
+ if ((mk = max(ic, max(im, iy))) > ik)
+ ik = (int)((float)ik * (float)ik * (float)ik / ((float)mk * (float)mk));
+
+ ic -= ik;
+ im -= ik;
+ iy -= ik;
+
+ /*
+ * Color correct CMY...
+ */
+
+ tc = cupsMatrix[0][0][ic] +
+ cupsMatrix[0][1][im] +
+ cupsMatrix[0][2][iy] +
+ ik;
+ tm = cupsMatrix[1][0][ic] +
+ cupsMatrix[1][1][im] +
+ cupsMatrix[1][2][iy] +
+ ik;
+ ty = cupsMatrix[2][0][ic] +
+ cupsMatrix[2][1][im] +
+ cupsMatrix[2][2][iy] +
+ ik;
+
+ /*
+ * Density correct combined CMYK...
+ */
+
+ if (tc < 0)
+ r = gx_max_color_value;
+ else if (tc > gx_max_color_value)
+ r = gx_max_color_value - cupsDensity[gx_max_color_value];
+ else
+ r = gx_max_color_value - cupsDensity[tc];
+
+ if (tm < 0)
+ g = gx_max_color_value;
+ else if (tm > gx_max_color_value)
+ g = gx_max_color_value - cupsDensity[gx_max_color_value];
+ else
+ g = gx_max_color_value - cupsDensity[tm];
+
+ if (ty < 0)
+ b = gx_max_color_value;
+ else if (ty > gx_max_color_value)
+ b = gx_max_color_value - cupsDensity[gx_max_color_value];
+ else
+ b = gx_max_color_value - cupsDensity[ty];
+ }
+
+ /*
+ * Convert the RGB color to a color index...
+ */
+
+ switch (cups->header.cupsColorSpace)
+ {
+ case CUPS_CSPACE_W :
+ i = lut_rgb_color[(r * 31 + g * 61 + b * 8) / 100];
+ break;
+
+ case CUPS_CSPACE_RGB :
+ ic = lut_rgb_color[r];
+ im = lut_rgb_color[g];
+ iy = lut_rgb_color[b];
+
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ i = (((ic << 1) | im) << 1) | iy;
+ break;
+ case 2 :
+ i = (((ic << 2) | im) << 2) | iy;
+ break;
+ case 4 :
+ i = (((ic << 4) | im) << 4) | iy;
+ break;
+ case 8 :
+ i = (((ic << 8) | im) << 8) | iy;
+ break;
+ }
+ break;
+
+ case CUPS_CSPACE_RGBA :
+ ic = lut_rgb_color[r];
+ im = lut_rgb_color[g];
+ iy = lut_rgb_color[b];
+
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ i = (((((ic << 1) | im) << 1) | iy) << 1) | 0x01;
+ break;
+ case 2 :
+ i = (((((ic << 2) | im) << 2) | iy) << 2) | 0x03;
+ break;
+ case 4 :
+ i = (((((ic << 4) | im) << 4) | iy) << 4) | 0x0f;
+ break;
+ case 8 :
+ i = (((((ic << 8) | im) << 8) | iy) << 8) | 0xff;
+ break;
+ }
+ break;
+
+ default :
+ i = lut_rgb_color[gx_max_color_value - (r * 31 + g * 61 + b * 8) / 100];
+ break;
+
+ case CUPS_CSPACE_CMY :
+ ic = lut_rgb_color[gx_max_color_value - r];
+ im = lut_rgb_color[gx_max_color_value - g];
+ iy = lut_rgb_color[gx_max_color_value - b];
+
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ i = (((ic << 1) | im) << 1) | iy;
+ break;
+ case 2 :
+ i = (((ic << 2) | im) << 2) | iy;
+ break;
+ case 4 :
+ i = (((ic << 4) | im) << 4) | iy;
+ break;
+ case 8 :
+ i = (((ic << 8) | im) << 8) | iy;
+ break;
+ }
+ break;
+
+ case CUPS_CSPACE_YMC :
+ ic = lut_rgb_color[gx_max_color_value - r];
+ im = lut_rgb_color[gx_max_color_value - g];
+ iy = lut_rgb_color[gx_max_color_value - b];
+
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ i = (((iy << 1) | im) << 1) | ic;
+ break;
+ case 2 :
+ i = (((iy << 2) | im) << 2) | ic;
+ break;
+ case 4 :
+ i = (((iy << 4) | im) << 4) | ic;
+ break;
+ case 8 :
+ i = (((iy << 8) | im) << 8) | ic;
+ break;
+ }
+ break;
+
+ case CUPS_CSPACE_CMYK :
+ ic = gx_max_color_value - r;
+ im = gx_max_color_value - g;
+ iy = gx_max_color_value - b;
+ ik = min(ic, min(im, iy));
+
+ if ((mk = max(ic, max(im, iy))) > ik)
+ ik = (int)((float)ik * (float)ik * (float)ik /
+ ((float)mk * (float)mk));
+
+ ic = lut_rgb_color[ic - ik];
+ im = lut_rgb_color[im - ik];
+ iy = lut_rgb_color[iy - ik];
+ ik = lut_rgb_color[ik];
+
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ i = (((((ic << 1) | im) << 1) | iy) << 1) | ik;
+ break;
+ case 2 :
+ i = (((((ic << 2) | im) << 2) | iy) << 2) | ik;
+ break;
+ case 4 :
+ i = (((((ic << 4) | im) << 4) | iy) << 4) | ik;
+ break;
+ case 8 :
+ i = (((((ic << 8) | im) << 8) | iy) << 8) | ik;
+ break;
+ }
+
+ if (gs_log_errors > 1)
+ fprintf(stderr, "DEBUG: CMY (%d,%d,%d) -> CMYK %08x (%d,%d,%d,%d)\n",
+ r, g, b, (unsigned)i, ic, im, iy, ik);
+ break;
+
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ ic = gx_max_color_value - r;
+ im = gx_max_color_value - g;
+ iy = gx_max_color_value - b;
+ ik = min(ic, min(im, iy));
+
+ if ((mk = max(ic, max(im, iy))) > ik)
+ ik = (int)((float)ik * (float)ik * (float)ik /
+ ((float)mk * (float)mk));
+
+ ic = lut_rgb_color[ic - ik];
+ im = lut_rgb_color[im - ik];
+ iy = lut_rgb_color[iy - ik];
+ ik = lut_rgb_color[ik];
+
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ i = (((((iy << 1) | im) << 1) | ic) << 1) | ik;
+ break;
+ case 2 :
+ i = (((((iy << 2) | im) << 2) | ic) << 2) | ik;
+ break;
+ case 4 :
+ i = (((((iy << 4) | im) << 4) | ic) << 4) | ik;
+ break;
+ case 8 :
+ i = (((((iy << 8) | im) << 8) | ic) << 8) | ik;
+ break;
+ }
+ break;
+
+ case CUPS_CSPACE_KCMYcm :
+ if (cups->header.cupsBitsPerColor == 1)
+ {
+ ic = gx_max_color_value - r;
+ im = gx_max_color_value - g;
+ iy = gx_max_color_value - b;
+ ik = min(ic, min(im, iy));
+
+ if ((mk = max(ic, max(im, iy))) > ik)
+ ik = (int)((float)ik * (float)ik * (float)ik /
+ ((float)mk * (float)mk));
+
+ ic = lut_rgb_color[ic - ik];
+ im = lut_rgb_color[im - ik];
+ iy = lut_rgb_color[iy - ik];
+ ik = lut_rgb_color[ik];
+ if (ik)
+ i = 32;
+ else if (ic && im)
+ i = 17;
+ else if (ic && iy)
+ i = 6;
+ else if (im && iy)
+ i = 12;
+ else if (ic)
+ i = 16;
+ else if (im)
+ i = 8;
+ else if (iy)
+ i = 4;
+ else
+ i = 0;
+ break;
+ }
+
+ case CUPS_CSPACE_KCMY :
+ ic = gx_max_color_value - r;
+ im = gx_max_color_value - g;
+ iy = gx_max_color_value - b;
+ ik = min(ic, min(im, iy));
+
+ if ((mk = max(ic, max(im, iy))) > ik)
+ ik = (int)((float)ik * (float)ik * (float)ik /
+ ((float)mk * (float)mk));
+
+ ic = lut_rgb_color[ic - ik];
+ im = lut_rgb_color[im - ik];
+ iy = lut_rgb_color[iy - ik];
+ ik = lut_rgb_color[ik];
+
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ i = (((((ik << 1) | ic) << 1) | im) << 1) | iy;
+ break;
+ case 2 :
+ i = (((((ik << 2) | ic) << 2) | im) << 2) | iy;
+ break;
+ case 4 :
+ i = (((((ik << 4) | ic) << 4) | im) << 4) | iy;
+ break;
+ case 8 :
+ i = (((((ik << 8) | ic) << 8) | im) << 8) | iy;
+ break;
+ }
+ break;
+
+#ifdef CUPS_RASTER_HAVE_COLORIMETRIC
+ case CUPS_CSPACE_CIEXYZ :
+ case CUPS_CSPACE_CIELab :
+ case CUPS_CSPACE_ICC1 :
+ case CUPS_CSPACE_ICC2 :
+ case CUPS_CSPACE_ICC3 :
+ case CUPS_CSPACE_ICC4 :
+ case CUPS_CSPACE_ICC5 :
+ case CUPS_CSPACE_ICC6 :
+ case CUPS_CSPACE_ICC7 :
+ case CUPS_CSPACE_ICC8 :
+ case CUPS_CSPACE_ICC9 :
+ case CUPS_CSPACE_ICCA :
+ case CUPS_CSPACE_ICCB :
+ case CUPS_CSPACE_ICCC :
+ case CUPS_CSPACE_ICCD :
+ case CUPS_CSPACE_ICCE :
+ case CUPS_CSPACE_ICCF :
+ /*
+ * Convert sRGB to linear RGB...
+ */
+
+ rr = pow((double)r / (double)gx_max_color_value, 0.58823529412);
+ rg = pow((double)g / (double)gx_max_color_value, 0.58823529412);
+ rb = pow((double)b / (double)gx_max_color_value, 0.58823529412);
+
+ /*
+ * Convert to CIE XYZ...
+ */
+
+# define D65_X (0.412453 + 0.357580 + 0.180423)
+# define D65_Y (0.212671 + 0.715160 + 0.072169)
+# define D65_Z (0.019334 + 0.119193 + 0.950227)
+
+ ciex = 0.412453 * rr + 0.357580 * rg + 0.180423 * rb;
+ ciey = 0.212671 * rr + 0.715160 * rg + 0.072169 * rb;
+ ciez = 0.019334 * rr + 0.119193 * rg + 0.950227 * rb;
+
+ if (cups->header.cupsColorSpace != CUPS_CSPACE_CIELab)
+ {
+ /*
+ * Convert to an integer XYZ color value...
+ */
+
+ if (ciex > 1.0)
+ ic = 255;
+ else if (ciex > 0.0)
+ ic = (int)(ciex * 255.0 + 0.5);
+ else
+ ic = 0;
+
+ if (ciey > 1.0)
+ im = 255;
+ else if (ciey > 0.0)
+ im = (int)(ciey * 255.0 + 0.5);
+ else
+ im = 0;
+
+ if (ciez > 1.0)
+ iy = 255;
+ else if (ciez > 0.0)
+ iy = (int)(ciez * 255.0 + 0.5);
+ else
+ iy = 0;
+ }
+ else
+ {
+ /*
+ * Convert CIE XYZ to Lab...
+ */
+
+ ciey_yn = ciey / D65_Y;
+
+ if (ciey_yn > 0.008856)
+ ciel = 116 * cbrt(ciey_yn) - 16;
+ else
+ ciel = 903.3 * ciey_yn;
+
+ if (ciel < 0.0)
+ ic = 0;
+ else if (ciel < 255.0)
+ ic = (int)(ciel + 0.5);
+ else
+ ic = 255;
+
+ ciea = 500 * (cups_map_cielab(ciex, D65_X) -
+ cups_map_cielab(ciey, D65_Y));
+ cieb = 200 * (cups_map_cielab(ciey, D65_Y) -
+ cups_map_cielab(ciez, D65_Z));
+
+ if (ciea < -127.0)
+ im = 128;
+ else if (ciea < 0.0)
+ im = (int)(ciea + 256.5);
+ else if (ciea > 127.0)
+ im = 127;
+ else
+ im = (int)(ciea + 0.5);
+
+ if (cieb < -127.0)
+ iy = 128;
+ else if (cieb < 0.0)
+ iy = (int)(cieb + 256.5);
+ else if (cieb > 127.0)
+ iy = 127;
+ else
+ iy = (int)(cieb + 0.5);
+ }
+
+ /*
+ * Put the final color value together...
+ */
+
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ i = (((ic << 1) | im) << 1) | iy;
+ break;
+ case 2 :
+ i = (((ic << 2) | im) << 2) | iy;
+ break;
+ case 4 :
+ i = (((ic << 4) | im) << 4) | iy;
+ break;
+ case 8 :
+ i = (((ic << 8) | im) << 8) | iy;
+ break;
+ }
+ break;
+#endif /* CUPS_RASTER_HAVE_COLORIMETRIC */
+ }
+
+#ifdef DEBUG
+ if (gs_log_errors > 1)
+ fprintf(stderr, "DEBUG: RGB %d,%d,%d = %08x\n", r, g, b, (unsigned)i);
+#endif /* DEBUG */
+
+ return (i);
+}
+
+
+/*
+ * 'cups_open()' - Open the output file and initialize things.
+ */
+
+private int /* O - Error status */
+cups_open(gx_device *pdev) /* I - Device info */
+{
+ int code; /* Return status */
+
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cups_open(%p)\n", pdev);
+#endif /* DEBUG */
+
+ cups->printer_procs.get_space_params = cups_get_space_params;
+
+ if (cups->page == 0)
+ {
+ fputs("INFO: Processing page 1...\n", stderr);
+ cups->page = 1;
+ }
+
+ if (pdev->color_info.num_components == 0)
+ cups_set_color_info(pdev);
+
+ if ((code = gdev_prn_open(pdev)) != 0)
+ return (code);
+
+ if (cups->ppd == NULL)
+ cups->ppd = ppdOpenFile(getenv("PPD"));
+
+ return (0);
+}
+
+
+/*
+ * 'cups_print_pages()' - Send one or more pages to the output file.
+ */
+
+private int /* O - 0 if everything is OK */
+cups_print_pages(gx_device_printer *pdev, /* I - Device info */
+ FILE *fp, /* I - Output file */
+ int num_copies) /* I - Number of copies */
+{
+ int copy; /* Copy number */
+ int srcbytes; /* Byte width of scanline */
+ unsigned char *src, /* Scanline data */
+ *dst; /* Bitmap data */
+
+
+ (void)fp; /* reference unused file pointer to prevent compiler warning */
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cups_print_pages(%p, %p, %d)\n", pdev, fp,
+ num_copies);
+#endif /* DEBUG */
+
+ /*
+ * Figure out the number of bytes per line...
+ */
+
+ switch (cups->header.cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerPixel *
+ cups->header.cupsWidth + 7) / 8;
+ break;
+
+ case CUPS_ORDER_BANDED :
+ if (cups->header.cupsColorSpace == CUPS_CSPACE_KCMYcm &&
+ cups->header.cupsBitsPerColor == 1)
+ cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerColor *
+ cups->header.cupsWidth + 7) / 8 * 6;
+ else
+ cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerColor *
+ cups->header.cupsWidth + 7) / 8 *
+ cups->color_info.num_components;
+ break;
+
+ case CUPS_ORDER_PLANAR :
+ cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerColor *
+ cups->header.cupsWidth + 7) / 8;
+ break;
+ }
+
+ /*
+ * Compute the width of a scanline and allocate input/output buffers...
+ */
+
+ srcbytes = gdev_prn_raster(pdev);
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d, cupsWidth = %d, cupsBytesPerLine = %d, srcbytes = %d\n",
+ cups->header.cupsBitsPerPixel, cups->header.cupsWidth,
+ cups->header.cupsBytesPerLine, srcbytes);
+#endif /* DEBUG */
+
+ src = (unsigned char *)gs_malloc(srcbytes, 1, "cups_print_pages");
+
+ if (src == NULL) /* can't allocate input buffer */
+ return_error(gs_error_VMerror);
+
+ /*
+ * Need an output buffer, too...
+ */
+
+ dst = (unsigned char *)gs_malloc(cups->header.cupsBytesPerLine, 2,
+ "cups_print_pages");
+
+ if (dst == NULL) /* can't allocate working area */
+ return_error(gs_error_VMerror);
+
+ /*
+ * See if the stream has been initialized yet...
+ */
+
+ if (cups->stream == NULL)
+ {
+ if ((cups->stream = cupsRasterOpen(fileno(cups->file),
+ CUPS_RASTER_WRITE)) == NULL)
+ {
+ perror("ERROR: Unable to open raster stream - ");
+ gs_exit(0);
+ }
+ }
+
+ /*
+ * Output a page of graphics...
+ */
+
+ if (num_copies < 1)
+ num_copies = 1;
+
+ if (cups->ppd != NULL && !cups->ppd->manual_copies)
+ {
+ cups->header.NumCopies = num_copies;
+ num_copies = 1;
+ }
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cupsWidth = %d, cupsHeight = %d, cupsBytesPerLine = %d\n",
+ cups->header.cupsWidth, cups->header.cupsHeight,
+ cups->header.cupsBytesPerLine);
+#endif /* DEBUG */
+
+ for (copy = num_copies; copy > 0; copy --)
+ {
+ cupsRasterWriteHeader(cups->stream, &(cups->header));
+
+ if (pdev->color_info.num_components == 1)
+ cups_print_chunked(pdev, src, dst, srcbytes);
+ else
+ switch (cups->header.cupsColorOrder)
+ {
+ case CUPS_ORDER_CHUNKED :
+ cups_print_chunked(pdev, src, dst, srcbytes);
+ break;
+ case CUPS_ORDER_BANDED :
+ cups_print_banded(pdev, src, dst, srcbytes);
+ break;
+ case CUPS_ORDER_PLANAR :
+ cups_print_planar(pdev, src, dst, srcbytes);
+ break;
+ }
+ }
+
+ /*
+ * Free temporary storage and return...
+ */
+
+ gs_free((char *)src, srcbytes, 1, "cups_print_pages");
+ gs_free((char *)dst, cups->header.cupsBytesPerLine, 1, "cups_print_pages");
+
+ cups->page ++;
+ fprintf(stderr, "INFO: Processing page %d...\n", cups->page);
+
+ return (0);
+}
+
+
+/*
+ * 'cups_put_params()' - Set pagedevice parameters.
+ */
+
+private int /* O - Error status */
+cups_put_params(gx_device *pdev, /* I - Device info */
+ gs_param_list *plist) /* I - Parameter list */
+{
+ int i; /* Looping var */
+ float margins[4]; /* Physical margins of print */
+ ppd_size_t *size; /* Page size */
+ int code; /* Error code */
+ int intval; /* Integer value */
+ bool boolval; /* Boolean value */
+ float floatval; /* Floating point value */
+ gs_param_string stringval; /* String value */
+ gs_param_float_array arrayval; /* Float array value */
+ int old_depth; /* Old color depth */
+ int size_set; /* Was the size set? */
+ gdev_prn_space_params sp; /* Space parameter data */
+
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cups_put_params(%p, %p)\n", pdev, plist);
+#endif /* DEBUG */
+
+ /*
+ * Process other options for CUPS...
+ */
+
+#define stringoption(name, sname) \
+ if ((code = param_read_string(plist, sname, &stringval)) < 0) \
+ { \
+ param_signal_error(plist, sname, code); \
+ return (code); \
+ } \
+ else if (code == 0) \
+ { \
+ strncpy(cups->header.name, (const char *)stringval.data, \
+ stringval.size); \
+ cups->header.name[stringval.size] = '\0'; \
+ }
+
+#define intoption(name, sname, type) \
+ if ((code = param_read_int(plist, sname, &intval)) < 0) \
+ { \
+ param_signal_error(plist, sname, code); \
+ return (code); \
+ } \
+ else if (code == 0) \
+ { \
+ fprintf(stderr, "DEBUG: Setting %s to %d...\n", sname, intval); \
+ cups->header.name = (type)intval; \
+ }
+
+#define floatoption(name, sname) \
+ if ((code = param_read_float(plist, sname, &floatval)) < 0) \
+ { \
+ param_signal_error(plist, sname, code); \
+ return (code); \
+ } \
+ else if (code == 0) \
+ cups->header.name = (unsigned)floatval;
+
+#define booloption(name, sname) \
+ if ((code = param_read_bool(plist, sname, &boolval)) < 0) \
+ { \
+ if ((code = param_read_null(plist, sname)) < 0) \
+ { \
+ param_signal_error(plist, sname, code); \
+ return (code); \
+ } \
+ if (code == 0) \
+ cups->header.name = CUPS_FALSE; \
+ } \
+ else if (code == 0) \
+ cups->header.name = (cups_bool_t)boolval;
+
+#define arrayoption(name, sname, count) \
+ if ((code = param_read_float_array(plist, sname, &arrayval)) < 0) \
+ { \
+ if ((code = param_read_null(plist, sname)) < 0) \
+ { \
+ param_signal_error(plist, sname, code); \
+ return (code); \
+ } \
+ if (code == 0) \
+ for (i = 0; i < count; i ++) \
+ cups->header.name[i] = 0; \
+ } \
+ else if (code == 0) \
+ { \
+ for (i = 0; i < count; i ++) \
+ cups->header.name[i] = (unsigned)arrayval.data[i]; \
+ }
+
+ old_depth = pdev->color_info.depth;
+ size_set = param_read_float_array(plist, ".MediaSize", &arrayval) == 0 ||
+ param_read_float_array(plist, "PageSize", &arrayval) == 0;
+
+ stringoption(MediaClass, "MediaClass")
+ stringoption(MediaColor, "MediaColor")
+ stringoption(MediaType, "MediaType")
+ stringoption(OutputType, "OutputType")
+ floatoption(AdvanceDistance, "AdvanceDistance")
+ intoption(AdvanceMedia, "AdvanceMedia", cups_adv_t)
+ booloption(Collate, "Collate")
+ intoption(CutMedia, "CutMedia", cups_cut_t)
+ booloption(Duplex, "Duplex")
+ arrayoption(ImagingBoundingBox, "ImagingBoundingBox", 4)
+ booloption(InsertSheet, "InsertSheet")
+ intoption(Jog, "Jog", cups_jog_t)
+ intoption(LeadingEdge, "LeadingEdge", cups_edge_t)
+ arrayoption(Margins, "Margins", 2)
+ booloption(ManualFeed, "ManualFeed")
+ intoption(MediaPosition, "cupsMediaPosition", unsigned) /* Compatibility */
+ intoption(MediaPosition, "MediaPosition", unsigned)
+ floatoption(MediaWeight, "MediaWeight")
+ booloption(MirrorPrint, "MirrorPrint")
+ booloption(NegativePrint, "NegativePrint")
+ intoption(Orientation, "Orientation", cups_orient_t)
+ booloption(OutputFaceUp, "OutputFaceUp")
+ booloption(Separations, "Separations")
+ booloption(TraySwitch, "TraySwitch")
+ booloption(Tumble, "Tumble")
+ intoption(cupsMediaType, "cupsMediaType", unsigned)
+ intoption(cupsBitsPerColor, "cupsBitsPerColor", unsigned)
+ intoption(cupsColorOrder, "cupsColorOrder", cups_order_t)
+ intoption(cupsColorSpace, "cupsColorSpace", cups_cspace_t)
+ intoption(cupsCompression, "cupsCompression", unsigned)
+ intoption(cupsRowCount, "cupsRowCount", unsigned)
+ intoption(cupsRowFeed, "cupsRowFeed", unsigned)
+ intoption(cupsRowStep, "cupsRowStep", unsigned)
+
+ if ((code = param_read_string(plist, "cupsProfile", &stringval)) < 0)
+ {
+ param_signal_error(plist, "cupsProfile", code);
+ return (code);
+ }
+ else if (code == 0)
+ {
+ if (cupsProfile != NULL)
+ free(cupsProfile);
+
+ cupsProfile = strdup(stringval.data);
+ }
+
+ cups_set_color_info(pdev);
+
+ /*
+ * Compute the page margins...
+ */
+
+ if (cups->ppd != NULL)
+ {
+ /*
+ * Pull the margins from the first size entry; since the margins are not
+ * like the bounding box we have to adjust the top and right values
+ * accordingly.
+ */
+
+ for (i = cups->ppd->num_sizes, size = cups->ppd->sizes;
+ i > 0;
+ i --, size ++)
+ if ((fabs(cups->MediaSize[1] - size->length) < 18.0 &&
+ fabs(cups->MediaSize[0] - size->width) < 18.0) ||
+ (fabs(cups->MediaSize[0] - size->length) < 18.0 &&
+ fabs(cups->MediaSize[1] - size->width) < 18.0))
+ break;
+
+ if (i == 0 && !cups->ppd->variable_sizes)
+ {
+ i = 1;
+ size = cups->ppd->sizes;
+ }
+
+ if (i > 0)
+ {
+ /*
+ * Standard size...
+ */
+
+ fprintf(stderr, "DEBUG: size = %s\n", size->name);
+
+ margins[0] = size->left / 72.0;
+ margins[1] = size->bottom / 72.0;
+ margins[2] = (size->width - size->right) / 72.0;
+ margins[3] = (size->length - size->top) / 72.0;
+ }
+ else
+ {
+ /*
+ * Custom size...
+ */
+
+ fputs("DEBUG: size = Custom\n", stderr);
+
+ for (i = 0; i < 4; i ++)
+ margins[i] = cups->ppd->custom_margins[i] / 72.0;
+ }
+
+ fprintf(stderr, "DEBUG: margins[] = [ %f %f %f %f ]\n",
+ margins[0], margins[1], margins[2], margins[3]);
+ }
+ else
+ {
+ /*
+ * Set default margins of 0.0...
+ */
+
+ memset(margins, 0, sizeof(margins));
+ }
+
+ /*
+ * Set the margins to update the bitmap size...
+ */
+
+ gx_device_set_margins(pdev, margins, false);
+
+ /*
+ * Then process standard page device options...
+ */
+
+ if ((code = gdev_prn_put_params(pdev, plist)) < 0)
+ return (code);
+
+ cups->header.HWResolution[0] = pdev->HWResolution[0];
+ cups->header.HWResolution[1] = pdev->HWResolution[1];
+
+ cups->header.Margins[0] = 72.0 * margins[0];
+ cups->header.Margins[1] = 72.0 * margins[1];
+
+ cups->header.PageSize[0] = pdev->MediaSize[0];
+ cups->header.PageSize[1] = pdev->MediaSize[1];
+
+ cups->header.ImagingBoundingBox[0] = 72.0 * margins[0];
+ cups->header.ImagingBoundingBox[1] = 72.0 * margins[1];
+ cups->header.ImagingBoundingBox[2] = pdev->MediaSize[0] - 72.0 * margins[2];
+ cups->header.ImagingBoundingBox[3] = pdev->MediaSize[1] - 72.0 * margins[3];
+
+ /*
+ * Reallocate memory if the size or color depth was changed...
+ */
+
+ fprintf(stderr, "DEBUG: old_depth = %d, depth = %d, size_set = %d\n",
+ old_depth, pdev->color_info.depth, size_set);
+
+ if (old_depth != pdev->color_info.depth || size_set)
+ {
+ /*
+ * Make sure the page image is the correct size - current Ghostscript
+ * does not keep track of the margins in the bitmap size...
+ */
+
+ pdev->width = (pdev->MediaSize[0] / 72.0f - margins[0] - margins[2]) *
+ pdev->HWResolution[0] + 0.499f;
+ pdev->height = (pdev->MediaSize[1] / 72.0f - margins[1] - margins[3]) *
+ pdev->HWResolution[1] + 0.499f;
+
+ fputs("DEBUG: Reallocating memory...\n", stderr);
+ sp = ((gx_device_printer *)pdev)->space_params;
+
+ if ((code = gdev_prn_reallocate_memory(pdev, &sp, pdev->width,
+ pdev->height)) < 0)
+ return (code);
+ }
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: ppd = %p\n", cups->ppd);
+ fprintf(stderr, "DEBUG: PageSize = [ %.3f %.3f ]\n",
+ pdev->MediaSize[0], pdev->MediaSize[1]);
+ fprintf(stderr, "DEBUG: margins = [ %.3f %.3f %.3f %.3f ]\n",
+ margins[0], margins[1], margins[2], margins[3]);
+ fprintf(stderr, "DEBUG: HWResolution = [ %.3f %.3f ]\n",
+ pdev->HWResolution[0], pdev->HWResolution[1]);
+ fprintf(stderr, "DEBUG: width = %d, height = %d\n",
+ pdev->width, pdev->height);
+ fprintf(stderr, "DEBUG: HWMargins = [ %.3f %.3f %.3f %.3f ]\n",
+ pdev->HWMargins[0], pdev->HWMargins[1],
+ pdev->HWMargins[2], pdev->HWMargins[3]);
+#endif /* DEBUG */
+
+ return (0);
+}
+
+
+/*
+ * 'cups_set_color_info()' - Set the color information structure based on
+ * the required output.
+ */
+
+private void
+cups_set_color_info(gx_device *pdev) /* I - Device info */
+{
+ int i, j, k; /* Looping vars */
+ float d, g; /* Density and gamma correction */
+ float m[3][3]; /* Color correction matrix */
+ char resolution[41]; /* Resolution string */
+ ppd_profile_t *profile; /* Color profile information */
+
+
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG: cups_set_color_info(%p)\n", pdev);
+#endif /* DEBUG */
+
+ switch (cups->header.cupsColorSpace)
+ {
+ default :
+ case CUPS_CSPACE_W :
+ case CUPS_CSPACE_K :
+ case CUPS_CSPACE_WHITE :
+ case CUPS_CSPACE_GOLD :
+ case CUPS_CSPACE_SILVER :
+ cups->header.cupsBitsPerPixel = cups->header.cupsBitsPerColor;
+ cups->color_info.depth = cups->header.cupsBitsPerPixel;
+ cups->color_info.num_components = 1;
+ break;
+
+ case CUPS_CSPACE_CMY :
+ case CUPS_CSPACE_YMC :
+ case CUPS_CSPACE_RGB :
+ if (cups->header.cupsColorOrder != CUPS_ORDER_CHUNKED)
+ cups->header.cupsBitsPerPixel = cups->header.cupsBitsPerColor;
+ else if (cups->header.cupsBitsPerColor < 8)
+ cups->header.cupsBitsPerPixel = 4 * cups->header.cupsBitsPerColor;
+ else
+ cups->header.cupsBitsPerPixel = 3 * cups->header.cupsBitsPerColor;
+
+ if (cups->header.cupsBitsPerColor < 8)
+ cups->color_info.depth = 4 * cups->header.cupsBitsPerColor;
+ else
+ cups->color_info.depth = 3 * cups->header.cupsBitsPerColor;
+
+ cups->color_info.num_components = 3;
+ break;
+
+ case CUPS_CSPACE_KCMYcm :
+ if (cups->header.cupsBitsPerColor == 1)
+ {
+ cups->header.cupsBitsPerPixel = 8;
+ cups->color_info.depth = 8;
+ cups->color_info.num_components = 4;
+ break;
+ }
+
+ case CUPS_CSPACE_CMYK :
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_KCMY :
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ if (cups->header.cupsColorOrder != CUPS_ORDER_CHUNKED)
+ cups->header.cupsBitsPerPixel = cups->header.cupsBitsPerColor;
+ else
+ cups->header.cupsBitsPerPixel = 4 * cups->header.cupsBitsPerColor;
+
+ cups->color_info.depth = 4 * cups->header.cupsBitsPerColor;
+ cups->color_info.num_components = 4;
+ break;
+
+#ifdef CUPS_RASTER_HAVE_COLORIMETRIC
+ case CUPS_CSPACE_CIEXYZ :
+ case CUPS_CSPACE_CIELab :
+ case CUPS_CSPACE_ICC1 :
+ case CUPS_CSPACE_ICC2 :
+ case CUPS_CSPACE_ICC3 :
+ case CUPS_CSPACE_ICC4 :
+ case CUPS_CSPACE_ICC5 :
+ case CUPS_CSPACE_ICC6 :
+ case CUPS_CSPACE_ICC7 :
+ case CUPS_CSPACE_ICC8 :
+ case CUPS_CSPACE_ICC9 :
+ case CUPS_CSPACE_ICCA :
+ case CUPS_CSPACE_ICCB :
+ case CUPS_CSPACE_ICCC :
+ case CUPS_CSPACE_ICCD :
+ case CUPS_CSPACE_ICCE :
+ case CUPS_CSPACE_ICCF :
+ /*
+ * Colorimetric color spaces currently are implemented as 24-bit
+ * mapping to XYZ or Lab, which are then converted as needed to
+ * the final representation...
+ *
+ * This code enforces a minimum output depth of 8 bits per
+ * component...
+ */
+
+ if (cups->header.cupsBitsPerColor < 8)
+ cups->header.cupsBitsPerColor = 8;
+
+ if (cups->header.cupsColorOrder != CUPS_ORDER_CHUNKED)
+ cups->header.cupsBitsPerPixel = cups->header.cupsBitsPerColor;
+ else
+ {
+ if (cups->header.cupsColorSpace < CUPS_CSPACE_ICC1)
+ cups->header.cupsBitsPerPixel = 3 * cups->header.cupsBitsPerColor;
+ else
+ cups->header.cupsBitsPerPixel =
+ (cups->header.cupsColorSpace - CUPS_CSPACE_ICC1 + 1) *
+ cups->header.cupsBitsPerColor;
+ }
+
+ cups->color_info.depth = 24;
+ cups->color_info.num_components = 3;
+ break;
+#endif /* CUPS_RASTER_HAVE_COLORIMETRIC */
+ }
+
+ if ((i = cups->header.cupsBitsPerColor) > 8)
+ i = 8;
+
+ if (cups->color_info.num_components > 1)
+ {
+ cups->color_info.max_gray = (1 << i) - 1;
+ cups->color_info.max_color = (1 << i) - 1;
+ cups->color_info.dither_grays = (1 << i);
+ cups->color_info.dither_colors = (1 << i);
+ }
+ else
+ {
+ cups->color_info.max_gray = (1 << i) - 1;
+ cups->color_info.max_color = 0;
+ cups->color_info.dither_grays = (1 << i);
+ cups->color_info.dither_colors = 0;
+ }
+
+ /*
+ * Enable/disable CMYK color support...
+ */
+
+ if (cups->color_info.num_components == 4)
+ cups->procs.map_cmyk_color = cups_map_cmyk_color;
+ else
+ cups->procs.map_cmyk_color = NULL;
+
+ /*
+ * Tell Ghostscript to forget any colors it has cached...
+ */
+
+ gx_device_decache_colors(pdev);
+
+ /*
+ * Compute the lookup tables...
+ */
+
+ for (i = 0; i <= gx_max_color_value; i ++)
+ lut_rgb_color[i] = cups->color_info.max_gray * i / gx_max_color_value;
+
+ for (i = 0; i < cups->color_info.dither_grays; i ++)
+ lut_color_rgb[i] = gx_max_color_value * i / cups->color_info.max_gray;
+
+ fprintf(stderr, "DEBUG: num_components = %d, depth = %d\n",
+ cups->color_info.num_components, cups->color_info.depth);
+ fprintf(stderr, "DEBUG: cupsColorSpace = %d, cupsColorOrder = %d\n",
+ cups->header.cupsColorSpace, cups->header.cupsColorOrder);
+ fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d, cupsBitsPerColor = %d\n",
+ cups->header.cupsBitsPerPixel, cups->header.cupsBitsPerColor);
+ fprintf(stderr, "DEBUG: max_gray = %d, dither_grays = %d\n",
+ cups->color_info.max_gray, cups->color_info.dither_grays);
+ fprintf(stderr, "DEBUG: max_color = %d, dither_colors = %d\n",
+ cups->color_info.max_color, cups->color_info.dither_colors);
+
+ /*
+ * Set the color profile as needed...
+ */
+
+ cupsHaveProfile = 0;
+
+ if (cupsProfile && cups->header.cupsBitsPerColor == 8)
+ {
+ fprintf(stderr, "DEBUG: Using user-defined profile \"%s\"...\n", cupsProfile);
+
+ if (sscanf(cupsProfile, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &d, &g,
+ m[0] + 0, m[0] + 1, m[0] + 2,
+ m[1] + 0, m[1] + 1, m[1] + 2,
+ m[2] + 0, m[2] + 1, m[2] + 2) != 11)
+ fputs("DEBUG: User-defined profile does not contain 11 integers!\n", stderr);
+ else
+ {
+ cupsHaveProfile = 1;
+
+ d *= 0.001f;
+ g *= 0.001f;
+ m[0][0] *= 0.001f;
+ m[0][1] *= 0.001f;
+ m[0][2] *= 0.001f;
+ m[1][0] *= 0.001f;
+ m[1][1] *= 0.001f;
+ m[1][2] *= 0.001f;
+ m[2][0] *= 0.001f;
+ m[2][1] *= 0.001f;
+ m[2][2] *= 0.001f;
+ }
+ }
+ else if (cups->ppd != NULL && cups->header.cupsBitsPerColor == 8)
+ {
+ /*
+ * Find the appropriate color profile...
+ */
+
+ if (pdev->HWResolution[0] != pdev->HWResolution[1])
+ sprintf(resolution, "%.0fx%.0fdpi", pdev->HWResolution[0],
+ pdev->HWResolution[1]);
+ else
+ sprintf(resolution, "%.0fdpi", pdev->HWResolution[0]);
+
+ for (i = 0, profile = cups->ppd->profiles;
+ i < cups->ppd->num_profiles;
+ i ++, profile ++)
+ if ((strcmp(profile->resolution, resolution) == 0 ||
+ profile->resolution[0] == '-') &&
+ (strcmp(profile->media_type, cups->header.MediaType) == 0 ||
+ profile->media_type[0] == '-'))
+ break;
+
+ /*
+ * If we found a color profile, use it!
+ */
+
+ if (i < cups->ppd->num_profiles)
+ {
+ fputs("DEBUG: Using color profile in PPD file!\n", stderr);
+
+ cupsHaveProfile = 1;
+
+ d = profile->density;
+ g = profile->gamma;
+
+ memcpy(m, profile->matrix, sizeof(m));
+ }
+ }
+
+ if (cupsHaveProfile)
+ {
+ for (i = 0; i < 3; i ++)
+ for (j = 0; j < 3; j ++)
+ for (k = 0; k <= gx_max_color_value; k ++)
+ {
+ cupsMatrix[i][j][k] = (int)((float)k * m[i][j] + 0.5);
+
+#ifdef DEBUG
+ if ((k & 4095) == 0)
+ fprintf(stderr, "DEBUG: cupsMatrix[%d][%d][%d] = %d\n",
+ i, j, k, cupsMatrix[i][j][k]);
+#endif /* DEBUG */
+ }
+
+
+ for (k = 0; k <= gx_max_color_value; k ++)
+ {
+ cupsDensity[k] = (int)((float)gx_max_color_value * d *
+ pow((float)k / (float)gx_max_color_value, g) +
+ 0.5);
+
+#ifdef DEBUG
+ if ((k & 4095) == 0)
+ fprintf(stderr, "DEBUG: cupsDensity[%d] = %d\n", k, cupsDensity[k]);
+#endif /* DEBUG */
+ }
+ }
+}
+
+
+/*
+ * 'cups_sync_output()' - Keep the user informed of our status...
+ */
+
+private int /* O - Error status */
+cups_sync_output(gx_device *pdev) /* I - Device info */
+{
+ fprintf(stderr, "INFO: Processing page %d...\n", cups->page);
+
+ return (0);
+}
+
+
+/*
+ * 'cups_print_chunked()' - Print a page of chunked pixels.
+ */
+
+static void
+cups_print_chunked(gx_device_printer *pdev, /* I - Printer device */
+ unsigned char *src, /* I - Scanline buffer */
+ unsigned char *dst, /* I - Bitmap buffer */
+ int srcbytes) /* I - Number of bytes in src */
+{
+ int y; /* Looping var */
+ unsigned char *srcptr, /* Pointer to data */
+ *dstptr; /* Pointer to bits */
+ int count; /* Count for loop */
+ int flip; /* Flip scanline? */
+
+
+ if (cups->header.Duplex && !cups->header.Tumble &&
+ cups->ppd && cups->ppd->flip_duplex && !(cups->page & 1))
+ flip = 1;
+ else
+ flip = 0;
+
+ fprintf(stderr, "DEBUG: cups_print_chunked - flip = %d\n", flip);
+
+ /*
+ * Loop through the page bitmap and write chunked pixels, reversing as
+ * needed...
+ */
+
+ for (y = 0; y < cups->height; y ++)
+ {
+ /*
+ * Grab the scanline data...
+ */
+
+ if (gdev_prn_get_bits((gx_device_printer *)pdev, y, src, &srcptr) < 0)
+ {
+ fprintf(stderr, "ERROR: Unable to get scanline %d!\n", y);
+ gs_exit(1);
+ }
+
+ if (flip)
+ {
+ /*
+ * Flip the raster data before writing it...
+ */
+
+ if (srcptr[0] == 0 && memcmp(srcptr, srcptr + 1, srcbytes - 1) == 0)
+ memset(dst, 0, cups->header.cupsBytesPerLine);
+ else
+ {
+ dstptr = dst;
+ count = srcbytes;
+
+ switch (cups->color_info.depth)
+ {
+ case 1 : /* B&W bitmap */
+ for (srcptr += srcbytes - 1;
+ count > 0;
+ count --, srcptr --, dstptr ++)
+ {
+ *dstptr = rev_upper1[*srcptr & 15] |
+ rev_lower1[*srcptr >> 4];
+ }
+ break;
+
+ case 2 : /* 2-bit grayscale */
+ for (srcptr += srcbytes - 1;
+ count > 0;
+ count --, srcptr --, dstptr ++)
+ {
+ *dstptr = rev_upper2[*srcptr & 15] |
+ rev_lower2[*srcptr >> 4];
+ }
+ break;
+
+ case 4 : /* 4-bit grayscale, or RGB, CMY, or CMYK bitmap */
+ for (srcptr += srcbytes - 1;
+ count > 0;
+ count --, srcptr --, dstptr ++)
+ *dstptr = (*srcptr >> 4) | (*srcptr << 4);
+ break;
+
+ case 8 : /* 8-bit grayscale, or 2-bit RGB, CMY, or CMYK image */
+ for (srcptr += srcbytes - 1;
+ count > 0;
+ count --, srcptr --, dstptr ++)
+ *dstptr = *srcptr;
+ break;
+
+ case 16 : /* 4-bit RGB, CMY or CMYK image */
+ for (srcptr += srcbytes - 2;
+ count > 0;
+ count -= 2, srcptr -= 2, dstptr += 2)
+ {
+ dstptr[0] = srcptr[0];
+ dstptr[1] = srcptr[1];
+ }
+ break;
+
+ case 24 : /* 8-bit RGB or CMY image */
+ for (srcptr += srcbytes - 3;
+ count > 0;
+ count -= 3, srcptr -= 3, dstptr += 3)
+ {
+ dstptr[0] = srcptr[0];
+ dstptr[1] = srcptr[1];
+ dstptr[2] = srcptr[2];
+ }
+ break;
+
+ case 32 : /* 4-bit RGB, CMY or CMYK bitmap */
+ for (srcptr += srcbytes - 4;
+ count > 0;
+ count -= 4, srcptr -= 4, dstptr += 4)
+ {
+ dstptr[0] = srcptr[0];
+ dstptr[1] = srcptr[1];
+ dstptr[2] = srcptr[2];
+ dstptr[3] = srcptr[3];
+ }
+ break;
+ }
+ }
+
+ /*
+ * Write the bitmap data to the raster stream...
+ */
+
+ cupsRasterWritePixels(cups->stream, dst, cups->header.cupsBytesPerLine);
+ }
+ else
+ {
+ /*
+ * Write the scanline data to the raster stream...
+ */
+
+ cupsRasterWritePixels(cups->stream, srcptr, cups->header.cupsBytesPerLine);
+ }
+ }
+}
+
+
+/*
+ * 'cups_print_banded()' - Print a page of banded pixels.
+ */
+
+static void
+cups_print_banded(gx_device_printer *pdev, /* I - Printer device */
+ unsigned char *src, /* I - Scanline buffer */
+ unsigned char *dst, /* I - Bitmap buffer */
+ int srcbytes) /* I - Number of bytes in src */
+{
+ int x; /* Looping var */
+ int y; /* Looping var */
+ int bandbytes; /* Bytes per band */
+ unsigned char bit; /* Current bit */
+ unsigned char temp; /* Temporary variable */
+ unsigned char *srcptr; /* Pointer to data */
+ unsigned char *cptr, *mptr, *yptr, *kptr; /* Pointer to components */
+ unsigned char *lcptr, *lmptr; /* ... */
+ int flip; /* Flip scanline? */
+
+
+ if (cups->header.Duplex && !cups->header.Tumble &&
+ cups->ppd && cups->ppd->flip_duplex && !(cups->page & 1))
+ flip = 1;
+ else
+ flip = 0;
+
+ fprintf(stderr, "DEBUG: cups_print_banded - flip = %d\n", flip);
+
+ /*
+ * Loop through the page bitmap and write banded pixels... We have
+ * to separate each chunked color as needed...
+ */
+
+ bandbytes = (cups->header.cupsWidth * cups->header.cupsBitsPerColor + 7) / 8;
+
+ for (y = 0; y < cups->height; y ++)
+ {
+ /*
+ * Grab the scanline data...
+ */
+
+ if (gdev_prn_get_bits((gx_device_printer *)pdev, y, src, &srcptr) < 0)
+ {
+ fprintf(stderr, "ERROR: Unable to get scanline %d!\n", y);
+ gs_exit(1);
+ }
+
+ /*
+ * Separate the chunked colors into their components...
+ */
+
+ if (srcptr[0] == 0 && memcmp(srcptr, srcptr + 1, srcbytes - 1) == 0)
+ memset(dst, 0, cups->header.cupsBytesPerLine);
+ else
+ {
+ if (flip)
+ cptr = dst + bandbytes - 1;
+ else
+ cptr = dst;
+
+ mptr = cptr + bandbytes;
+ yptr = mptr + bandbytes;
+ kptr = yptr + bandbytes;
+ lcptr = yptr + bandbytes;
+ lmptr = lcptr + bandbytes;
+
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ memset(dst, 0, cups->header.cupsBytesPerLine);
+
+ switch (cups->header.cupsColorSpace)
+ {
+ default :
+ for (x = cups->width, bit = flip ? 1 << (x & 7) : 128;
+ x > 0;
+ x --, srcptr ++)
+ {
+ if (*srcptr & 0x40)
+ *cptr |= bit;
+ if (*srcptr & 0x20)
+ *mptr |= bit;
+ if (*srcptr & 0x10)
+ *yptr |= bit;
+
+ if (flip)
+ {
+ if (bit < 128)
+ bit <<= 1;
+ else
+ {
+ cptr --;
+ mptr --;
+ yptr --;
+ bit = 1;
+ }
+ }
+ else
+ bit >>= 1;
+
+ x --;
+ if (x == 0)
+ break;
+
+ if (*srcptr & 0x4)
+ *cptr |= bit;
+ if (*srcptr & 0x2)
+ *mptr |= bit;
+ if (*srcptr & 0x1)
+ *yptr |= bit;
+
+ if (flip)
+ {
+ if (bit < 128)
+ bit <<= 1;
+ else
+ {
+ cptr --;
+ mptr --;
+ yptr --;
+ bit = 1;
+ }
+ }
+ else if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ bit = 128;
+ }
+ }
+ break;
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ case CUPS_CSPACE_RGBA :
+ case CUPS_CSPACE_CMYK :
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_KCMY :
+ for (x = cups->width, bit = flip ? 1 << (x & 7) : 128;
+ x > 0;
+ x --, srcptr ++)
+ {
+ if (*srcptr & 0x80)
+ *cptr |= bit;
+ if (*srcptr & 0x40)
+ *mptr |= bit;
+ if (*srcptr & 0x20)
+ *yptr |= bit;
+ if (*srcptr & 0x10)
+ *kptr |= bit;
+
+ if (flip)
+ {
+ if (bit < 128)
+ bit <<= 1;
+ else
+ {
+ cptr --;
+ mptr --;
+ yptr --;
+ kptr --;
+ bit = 1;
+ }
+ }
+ else
+ bit >>= 1;
+
+ x --;
+ if (x == 0)
+ break;
+
+ if (*srcptr & 0x8)
+ *cptr |= bit;
+ if (*srcptr & 0x4)
+ *mptr |= bit;
+ if (*srcptr & 0x2)
+ *yptr |= bit;
+ if (*srcptr & 0x1)
+ *kptr |= bit;
+
+ if (flip)
+ {
+ if (bit < 128)
+ bit <<= 1;
+ else
+ {
+ cptr --;
+ mptr --;
+ yptr --;
+ kptr --;
+ bit = 1;
+ }
+ }
+ else if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ bit = 128;
+ }
+ }
+ break;
+ case CUPS_CSPACE_KCMYcm :
+ for (x = cups->width, bit = flip ? 1 << (x & 7) : 128;
+ x > 0;
+ x --, srcptr ++)
+ {
+ /*
+ * Note: Because of the way the pointers are setup,
+ * the following code is correct even though
+ * the names don't match...
+ */
+
+ if (*srcptr & 0x20)
+ *cptr |= bit;
+ if (*srcptr & 0x10)
+ *mptr |= bit;
+ if (*srcptr & 0x08)
+ *yptr |= bit;
+ if (*srcptr & 0x04)
+ *kptr |= bit;
+ if (*srcptr & 0x02)
+ *lcptr |= bit;
+ if (*srcptr & 0x01)
+ *lmptr |= bit;
+
+ if (flip)
+ {
+ if (bit < 128)
+ bit <<= 1;
+ else
+ {
+ cptr --;
+ mptr --;
+ yptr --;
+ kptr --;
+ lcptr --;
+ lmptr --;
+ bit = 1;
+ }
+ }
+ else if (bit > 1)
+ bit >>= 1;
+ else
+ {
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ lcptr ++;
+ lmptr ++;
+ bit = 128;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 2 :
+ memset(dst, 0, cups->header.cupsBytesPerLine);
+
+ switch (cups->header.cupsColorSpace)
+ {
+ default :
+ for (x = cups->width, bit = flip ? 3 << (2 * (x & 3)) : 0xc0;
+ x > 0;
+ x --, srcptr ++)
+ switch (bit)
+ {
+ case 0xc0 :
+ if ((temp = *srcptr & 0x30) != 0)
+ *cptr |= temp << 2;
+ if ((temp = *srcptr & 0x0c) != 0)
+ *mptr |= temp << 4;
+ if ((temp = *srcptr & 0x03) != 0)
+ *yptr |= temp << 6;
+
+ if (flip)
+ {
+ bit = 0x03;
+ cptr --;
+ mptr --;
+ yptr --;
+ }
+ else
+ bit = 0x30;
+ break;
+ case 0x30 :
+ if ((temp = *srcptr & 0x30) != 0)
+ *cptr |= temp;
+ if ((temp = *srcptr & 0x0c) != 0)
+ *mptr |= temp << 2;
+ if ((temp = *srcptr & 0x03) != 0)
+ *yptr |= temp << 4;
+
+ if (flip)
+ bit = 0xc0;
+ else
+ bit = 0x0c;
+ break;
+ case 0x0c :
+ if ((temp = *srcptr & 0x30) != 0)
+ *cptr |= temp >> 2;
+ if ((temp = *srcptr & 0x0c) != 0)
+ *mptr |= temp;
+ if ((temp = *srcptr & 0x03) != 0)
+ *yptr |= temp << 2;
+
+ if (flip)
+ bit = 0x30;
+ else
+ bit = 0x03;
+ break;
+ case 0x03 :
+ if ((temp = *srcptr & 0x30) != 0)
+ *cptr |= temp >> 4;
+ if ((temp = *srcptr & 0x0c) != 0)
+ *mptr |= temp >> 2;
+ if ((temp = *srcptr & 0x03) != 0)
+ *yptr |= temp;
+
+ if (flip)
+ bit = 0x0c;
+ else
+ {
+ bit = 0xc0;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ break;
+ }
+ break;
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ case CUPS_CSPACE_RGBA :
+ case CUPS_CSPACE_CMYK :
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_KCMY :
+ case CUPS_CSPACE_KCMYcm :
+ for (x = cups->width, bit = flip ? 3 << (2 * (x & 3)) : 0xc0;
+ x > 0;
+ x --, srcptr ++)
+ switch (bit)
+ {
+ case 0xc0 :
+ if ((temp = *srcptr & 0xc0) != 0)
+ *cptr |= temp;
+ if ((temp = *srcptr & 0x30) != 0)
+ *mptr |= temp << 2;
+ if ((temp = *srcptr & 0x0c) != 0)
+ *yptr |= temp << 4;
+ if ((temp = *srcptr & 0x03) != 0)
+ *kptr |= temp << 6;
+
+ if (flip)
+ {
+ bit = 0x03;
+ cptr --;
+ mptr --;
+ yptr --;
+ kptr --;
+ }
+ else
+ bit = 0x30;
+ break;
+ case 0x30 :
+ if ((temp = *srcptr & 0xc0) != 0)
+ *cptr |= temp >> 2;
+ if ((temp = *srcptr & 0x30) != 0)
+ *mptr |= temp;
+ if ((temp = *srcptr & 0x0c) != 0)
+ *yptr |= temp << 2;
+ if ((temp = *srcptr & 0x03) != 0)
+ *kptr |= temp << 4;
+
+ if (flip)
+ bit = 0xc0;
+ else
+ bit = 0x0c;
+ break;
+ case 0x0c :
+ if ((temp = *srcptr & 0xc0) != 0)
+ *cptr |= temp >> 4;
+ if ((temp = *srcptr & 0x30) != 0)
+ *mptr |= temp >> 2;
+ if ((temp = *srcptr & 0x0c) != 0)
+ *yptr |= temp;
+ if ((temp = *srcptr & 0x03) != 0)
+ *kptr |= temp << 2;
+
+ if (flip)
+ bit = 0x30;
+ else
+ bit = 0x03;
+ break;
+ case 0x03 :
+ if ((temp = *srcptr & 0xc0) != 0)
+ *cptr |= temp >> 6;
+ if ((temp = *srcptr & 0x30) != 0)
+ *mptr |= temp >> 4;
+ if ((temp = *srcptr & 0x0c) != 0)
+ *yptr |= temp >> 2;
+ if ((temp = *srcptr & 0x03) != 0)
+ *kptr |= temp;
+
+ if (flip)
+ bit = 0x0c;
+ else
+ {
+ bit = 0xc0;
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ break;
+ }
+ break;
+ }
+ break;
+
+ case 4 :
+ memset(dst, 0, cups->header.cupsBytesPerLine);
+
+ switch (cups->header.cupsColorSpace)
+ {
+ default :
+ for (x = cups->width, bit = flip && (x & 1) ? 0xf0 : 0x0f;
+ x > 0;
+ x --, srcptr += 2)
+ switch (bit)
+ {
+ case 0xf0 :
+ if ((temp = srcptr[0] & 0x0f) != 0)
+ *cptr |= temp << 4;
+ if ((temp = srcptr[1] & 0xf0) != 0)
+ *mptr |= temp;
+ if ((temp = srcptr[1] & 0x0f) != 0)
+ *yptr |= temp << 4;
+
+ bit = 0x0f;
+
+ if (flip)
+ {
+ cptr --;
+ mptr --;
+ yptr --;
+ }
+ break;
+ case 0x0f :
+ if ((temp = srcptr[0] & 0x0f) != 0)
+ *cptr |= temp;
+ if ((temp = srcptr[1] & 0xf0) != 0)
+ *mptr |= temp >> 4;
+ if ((temp = srcptr[1] & 0x0f) != 0)
+ *yptr |= temp;
+
+ bit = 0xf0;
+
+ if (!flip)
+ {
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ }
+ break;
+ }
+ break;
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ case CUPS_CSPACE_RGBA :
+ case CUPS_CSPACE_CMYK :
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_KCMY :
+ case CUPS_CSPACE_KCMYcm :
+ for (x = cups->width, bit = flip && (x & 1) ? 0xf0 : 0x0f;
+ x > 0;
+ x --, srcptr += 2)
+ switch (bit)
+ {
+ case 0xf0 :
+ if ((temp = srcptr[0] & 0xf0) != 0)
+ *cptr |= temp;
+ if ((temp = srcptr[0] & 0x0f) != 0)
+ *mptr |= temp << 4;
+ if ((temp = srcptr[1] & 0xf0) != 0)
+ *yptr |= temp;
+ if ((temp = srcptr[1] & 0x0f) != 0)
+ *kptr |= temp << 4;
+
+ bit = 0x0f;
+
+ if (flip)
+ {
+ cptr --;
+ mptr --;
+ yptr --;
+ kptr --;
+ }
+ break;
+ case 0x0f :
+ if ((temp = srcptr[0] & 0xf0) != 0)
+ *cptr |= temp >> 4;
+ if ((temp = srcptr[0] & 0x0f) != 0)
+ *mptr |= temp;
+ if ((temp = srcptr[1] & 0xf0) != 0)
+ *yptr |= temp >> 4;
+ if ((temp = srcptr[1] & 0x0f) != 0)
+ *kptr |= temp;
+
+ bit = 0xf0;
+
+ if (!flip)
+ {
+ cptr ++;
+ mptr ++;
+ yptr ++;
+ kptr ++;
+ }
+ break;
+ }
+ break;
+ }
+ break;
+
+ case 8 :
+ switch (cups->header.cupsColorSpace)
+ {
+ default :
+ if (flip)
+ for (x = cups->width; x > 0; x --)
+ {
+ *cptr-- = *srcptr++;
+ *mptr-- = *srcptr++;
+ *yptr-- = *srcptr++;
+ }
+ else
+ for (x = cups->width; x > 0; x --)
+ {
+ *cptr++ = *srcptr++;
+ *mptr++ = *srcptr++;
+ *yptr++ = *srcptr++;
+ }
+ break;
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ case CUPS_CSPACE_RGBA :
+ case CUPS_CSPACE_CMYK :
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_KCMY :
+ case CUPS_CSPACE_KCMYcm :
+ if (flip)
+ for (x = cups->width; x > 0; x --)
+ {
+ *cptr-- = *srcptr++;
+ *mptr-- = *srcptr++;
+ *yptr-- = *srcptr++;
+ *kptr-- = *srcptr++;
+ }
+ else
+ for (x = cups->width; x > 0; x --)
+ {
+ *cptr++ = *srcptr++;
+ *mptr++ = *srcptr++;
+ *yptr++ = *srcptr++;
+ *kptr++ = *srcptr++;
+ }
+ break;
+ }
+ break;
+ }
+ }
+
+ /*
+ * Write the bitmap data to the raster stream...
+ */
+
+ cupsRasterWritePixels(cups->stream, dst, cups->header.cupsBytesPerLine);
+ }
+}
+
+
+/*
+ * 'cups_print_planar()' - Print a page of planar pixels.
+ */
+
+static void
+cups_print_planar(gx_device_printer *pdev, /* I - Printer device */
+ unsigned char *src, /* I - Scanline buffer */
+ unsigned char *dst, /* I - Bitmap buffer */
+ int srcbytes) /* I - Number of bytes in src */
+{
+ int x; /* Looping var */
+ int y; /* Looping var */
+ int z; /* Looping var */
+ unsigned char srcbit; /* Current source bit */
+ unsigned char dstbit; /* Current destination bit */
+ unsigned char temp; /* Temporary variable */
+ unsigned char *srcptr; /* Pointer to data */
+ unsigned char *dstptr; /* Pointer to bitmap */
+
+
+ /**** NOTE: Currently planar output doesn't support flipped duplex!!! ****/
+
+ /*
+ * Loop through the page bitmap and write planar pixels... We have
+ * to separate each chunked color as needed...
+ */
+
+ for (z = 0; z < pdev->color_info.num_components; z ++)
+ for (y = 0; y < cups->height; y ++)
+ {
+ /*
+ * Grab the scanline data...
+ */
+
+ if (gdev_prn_get_bits((gx_device_printer *)pdev, y, src, &srcptr) < 0)
+ {
+ fprintf(stderr, "ERROR: Unable to get scanline %d!\n", y);
+ gs_exit(1);
+ }
+
+ /*
+ * Pull the individual color planes out of the pixels...
+ */
+
+ if (srcptr[0] == 0 && memcmp(srcptr, srcptr + 1, srcbytes - 1) == 0)
+ memset(dst, 0, cups->header.cupsBytesPerLine);
+ else
+ switch (cups->header.cupsBitsPerColor)
+ {
+ default :
+ memset(dst, 0, cups->header.cupsBytesPerLine);
+
+ switch (cups->header.cupsColorSpace)
+ {
+ default :
+ for (dstptr = dst, x = cups->width, srcbit = 64 >> z,
+ dstbit = 128;
+ x > 0;
+ x --)
+ {
+ if (*srcptr & srcbit)
+ *dstptr |= dstbit;
+
+ if (srcbit >= 16)
+ srcbit >>= 4;
+ else
+ {
+ srcbit = 64 >> z;
+ srcptr ++;
+ }
+
+ if (dstbit > 1)
+ dstbit >>= 1;
+ else
+ {
+ dstbit = 128;
+ dstptr ++;
+ }
+ }
+ break;
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ case CUPS_CSPACE_RGBA :
+ case CUPS_CSPACE_CMYK :
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_KCMY :
+ for (dstptr = dst, x = cups->width, srcbit = 128 >> z,
+ dstbit = 128;
+ x > 0;
+ x --)
+ {
+ if (*srcptr & srcbit)
+ *dstptr |= dstbit;
+
+ if (srcbit >= 16)
+ srcbit >>= 4;
+ else
+ {
+ srcbit = 128 >> z;
+ srcptr ++;
+ }
+
+ if (dstbit > 1)
+ dstbit >>= 1;
+ else
+ {
+ dstbit = 128;
+ dstptr ++;
+ }
+ }
+ break;
+ case CUPS_CSPACE_KCMYcm :
+ for (dstptr = dst, x = cups->width, srcbit = 32 >> z,
+ dstbit = 128;
+ x > 0;
+ x --, srcptr ++)
+ {
+ if (*srcptr & srcbit)
+ *dstptr |= dstbit;
+
+ if (dstbit > 1)
+ dstbit >>= 1;
+ else
+ {
+ dstbit = 128;
+ dstptr ++;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 2 :
+ memset(dst, 0, cups->header.cupsBytesPerLine);
+
+ switch (cups->header.cupsColorSpace)
+ {
+ default :
+ for (dstptr = dst, x = cups->width, srcbit = 48 >> (z * 2),
+ dstbit = 0xc0;
+ x > 0;
+ x --, srcptr ++)
+ {
+ if ((temp = *srcptr & srcbit) != 0)
+ {
+ if (srcbit == dstbit)
+ *dstptr |= temp;
+ else
+ {
+ switch (srcbit)
+ {
+ case 0x30 :
+ temp >>= 4;
+ break;
+ case 0x0c :
+ temp >>= 2;
+ break;
+ }
+
+ switch (dstbit)
+ {
+ case 0xc0 :
+ *dstptr |= temp << 6;
+ break;
+ case 0x30 :
+ *dstptr |= temp << 4;
+ break;
+ case 0x0c :
+ *dstptr |= temp << 2;
+ break;
+ case 0x03 :
+ *dstptr |= temp;
+ break;
+ }
+ }
+ }
+
+ if (dstbit > 0x03)
+ dstbit >>= 2;
+ else
+ {
+ dstbit = 0xc0;
+ dstptr ++;
+ }
+ }
+ break;
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ case CUPS_CSPACE_RGBA :
+ case CUPS_CSPACE_CMYK :
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_KCMY :
+ case CUPS_CSPACE_KCMYcm :
+ for (dstptr = dst, x = cups->width, srcbit = 192 >> (z * 2),
+ dstbit = 0xc0;
+ x > 0;
+ x --, srcptr ++)
+ {
+ if ((temp = *srcptr & srcbit) != 0)
+ {
+ if (srcbit == dstbit)
+ *dstptr |= temp;
+ else
+ {
+ switch (srcbit)
+ {
+ case 0xc0 :
+ temp >>= 6;
+ break;
+ case 0x30 :
+ temp >>= 4;
+ break;
+ case 0x0c :
+ temp >>= 2;
+ break;
+ }
+
+ switch (dstbit)
+ {
+ case 0xc0 :
+ *dstptr |= temp << 6;
+ break;
+ case 0x30 :
+ *dstptr |= temp << 4;
+ break;
+ case 0x0c :
+ *dstptr |= temp << 2;
+ break;
+ case 0x03 :
+ *dstptr |= temp;
+ break;
+ }
+ }
+ }
+
+ if (dstbit > 0x03)
+ dstbit >>= 2;
+ else
+ {
+ dstbit = 0xc0;
+ dstptr ++;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 4 :
+ memset(dst, 0, cups->header.cupsBytesPerLine);
+
+ switch (cups->header.cupsColorSpace)
+ {
+ default :
+ if (z > 0)
+ srcptr ++;
+
+ if (z == 1)
+ srcbit = 0xf0;
+ else
+ srcbit = 0x0f;
+
+ for (dstptr = dst, x = cups->width, dstbit = 0xf0;
+ x > 0;
+ x --, srcptr += 2)
+ {
+ if ((temp = *srcptr & srcbit) != 0)
+ {
+ if (srcbit == dstbit)
+ *dstptr |= temp;
+ else
+ {
+ if (srcbit == 0xf0)
+ temp >>= 4;
+
+ if (dstbit == 0xf0)
+ *dstptr |= temp << 4;
+ else
+ *dstptr |= temp;
+ }
+ }
+
+ if (dstbit == 0xf0)
+ dstbit = 0x0f;
+ else
+ {
+ dstbit = 0xf0;
+ dstptr ++;
+ }
+ }
+ break;
+ case CUPS_CSPACE_GMCK :
+ case CUPS_CSPACE_GMCS :
+ case CUPS_CSPACE_RGBA :
+ case CUPS_CSPACE_CMYK :
+ case CUPS_CSPACE_YMCK :
+ case CUPS_CSPACE_KCMY :
+ case CUPS_CSPACE_KCMYcm :
+ if (z > 1)
+ srcptr ++;
+
+ if (z & 1)
+ srcbit = 0x0f;
+ else
+ srcbit = 0xf0;
+
+ for (dstptr = dst, x = cups->width, dstbit = 0xf0;
+ x > 0;
+ x --, srcptr += 2)
+ {
+ if ((temp = *srcptr & srcbit) != 0)
+ {
+ if (srcbit == dstbit)
+ *dstptr |= temp;
+ else
+ {
+ if (srcbit == 0xf0)
+ temp >>= 4;
+
+ if (dstbit == 0xf0)
+ *dstptr |= temp << 4;
+ else
+ *dstptr |= temp;
+ }
+ }
+
+ if (dstbit == 0xf0)
+ dstbit = 0x0f;
+ else
+ {
+ dstbit = 0xf0;
+ dstptr ++;
+ }
+ }
+ break;
+ }
+ break;
+
+ case 8 :
+ for (srcptr += z, dstptr = dst, x = cups->header.cupsBytesPerLine;
+ x > 0;
+ srcptr += pdev->color_info.num_components, x --)
+ *dstptr++ = *srcptr;
+ break;
+ }
+
+ /*
+ * Write the bitmap data to the raster stream...
+ */
+
+ cupsRasterWritePixels(cups->stream, dst, cups->header.cupsBytesPerLine);
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/pstoraster/ghostscript-705.patch b/pstoraster/ghostscript-705.patch
new file mode 100644
index 000000000..125c67900
--- /dev/null
+++ b/pstoraster/ghostscript-705.patch
@@ -0,0 +1,4563 @@
+diff -ur ghostscript-7.05/lib/gs_setpd.ps espgs/lib/gs_setpd.ps
+--- ghostscript-7.05/lib/gs_setpd.ps Fri Feb 22 14:45:55 2002
++++ espgs/lib/gs_setpd.ps Tue Apr 23 08:37:55 2002
+@@ -321,21 +321,42 @@
+ } bind
+ .dicttomark readonly def
+
+-% Define the keys used in input attribute matching.
+-/.inputattrkeys [
+- /PageSize /MediaColor /MediaWeight /MediaType /InsertSheet
+- % The following are documented in Adobe's supplement for v2017.
+- /LeadingEdge /MediaClass
+-] readonly def
+-% Define other keys used in media selection.
+-/.inputselectionkeys [
+- /MediaPosition /Orientation
+-] readonly def
+-
+-% Define the keys used in output attribute matching.
+-/.outputattrkeys [
+- /OutputType
+-] readonly def
++% M. Sweet, Easy Software Products:
++%
++% Define NOMEDIAATTRS to turn the default (but unimplementable) media
++% selection policies for setpagedevice. This is used by CUPS to
++% support the standard Adobe media attributes.
++currentdict /NOMEDIAATTRS known {
++ % Define the keys used in input attribute matching.
++ /.inputattrkeys [
++ /PageSize /MediaColor /MediaWeight /MediaType /InsertSheet
++ % The following are documented in Adobe's supplement for v2017.
++ /LeadingEdge /MediaClass
++ ] readonly def
++ % Define other keys used in media selection.
++ /.inputselectionkeys [
++ /MediaPosition /Orientation
++ ] readonly def
++
++ % Define the keys used in output attribute matching.
++ /.outputattrkeys [
++ /OutputType
++ ] readonly def
++} {
++ % Define only PageSize for input attribute matching.
++ /.inputattrkeys [
++ /PageSize
++ ] readonly def
++ % Define no other keys used in media selection.
++ /.inputselectionkeys [
++ /noInputSelectionsKeys
++ ] readonly def
++
++ % Define no keys used in output attribute matching.
++ /.outputattrkeys [
++ /noOutputAttrKeys
++ ] readonly def
++} ifelse
+
+ % Define all the parameters that should always be copied to the merged
+ % dictionary.
+diff -ur ghostscript-7.05/src/Makefile.in espgs/src/Makefile.in
+--- ghostscript-7.05/src/Makefile.in Fri Apr 19 18:23:09 2002
++++ espgs/src/Makefile.in Tue Apr 23 11:18:45 2002
+@@ -70,7 +70,7 @@
+ # Define the default directory/ies for the runtime
+ # initialization and font files. Separate multiple directories with a :.
+
+-GS_LIB_DEFAULT=$(gsdatadir)/lib:$(gsdir)/fonts
++GS_LIB_DEFAULT=$(gsdatadir)/lib:$(gsdir)/fonts:@fontpath@
+
+ # Define whether or not searching for initialization files should always
+ # look in the current directory first. This leads to well-known security
+@@ -110,7 +110,7 @@
+
+ # Define the name of the executable file.
+
+-GS=gs
++GS=@GS@
+
+ # Define the name of a pre-built executable that can be invoked at build
+ # time. Currently, this is only needed for compiled fonts. The usual
+@@ -222,7 +222,7 @@
+ # defines from autoconf; note that we don't use these at present.
+ ACDEFS=@DEFS@
+
+-CFLAGS=$(CFLAGS_STANDARD) $(GCFLAGS) $(XCFLAGS)
++CFLAGS=@CFLAGS@ $(GCFLAGS) $(XCFLAGS)
+
+ # Define platform flags for ld.
+ # SunOS 4.n may need -Bstatic.
+@@ -231,9 +231,9 @@
+ # -R /usr/local/xxx/lib:/usr/local/lib
+ # giving the full path names of the shared library directories.
+ # XLDFLAGS can be set from the command line.
+-XLDFLAGS=
++XLDFLAGS=@XLDFLAGS@
+
+-LDFLAGS=$(XLDFLAGS)
++LDFLAGS=@LDFLAGS@ $(XLDFLAGS)
+
+ # Define any extra libraries to link into the executable.
+ # ISC Unix 2.2 wants -linet.
+@@ -242,7 +242,7 @@
+ # Solaris may need -lnsl -lsocket -lposix4.
+ # (Libraries required by individual drivers are handled automatically.)
+
+-EXTRALIBS=
++EXTRALIBS=@LIBS@
+
+ # Define the standard libraries to search at the end of linking.
+ # Most platforms require -lpthread for the POSIX threads library;
+@@ -317,7 +317,7 @@
+ # Choose whether to compile the .ps initialization files into the executable.
+ # See gs.mak for details.
+
+-COMPILE_INITS=0
++COMPILE_INITS=@COMPILE_INITS@
+
+ # Choose whether to store band lists on files or in memory.
+ # The choices are 'file' or 'memory'.
+@@ -353,30 +353,27 @@
+ # devs.mak and contrib.mak for the list of available devices.
+
+ #DEVICE_DEVS=$(DISPLAY_DEV) $(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev
+-DEVICE_DEVS=$(DISPLAY_DEV) @X11DEVS@
+-
+-DEVICE_DEVS1=$(DD)bmpmono.dev $(DD)bmpgray.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16.dev $(DD)bmp256.dev $(DD)bmp16m.dev $(DD)bmp32b.dev
+-DEVICE_DEVS2=
+-DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev $(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev $(DD)lj5mono.dev $(DD)lj5gray.dev
+-DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev $(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev
+-DEVICE_DEVS5=$(DD)uniprint.dev @IJSDEVS@ @STPDEVS@
+-DEVICE_DEVS6=$(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev
+-DEVICE_DEVS7=$(DD)faxg3.dev $(DD)faxg32d.dev $(DD)faxg4.dev
+-DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev
+-DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev
+-DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev
+-DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev
+-DEVICE_DEVS12=$(DD)psmono.dev $(DD)psgray.dev $(DD)psrgb.dev $(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev
+-#DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev
+-DEVICE_DEVS13=@PNGDEVS@
+-DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev
+-DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)pswrite.dev $(DD)epswrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev
+-
++DEVICE_DEVS=$(DISPLAY_DEV) @X_DEVS@
++DEVICE_DEVS1=@CUPSDEV@
++DEVICE_DEVS2=@STPDEVS@
++DEVICE_DEVS3=@FILES@
++DEVICE_DEVS4=@PRINTERS@
++DEVICE_DEVS5=
++DEVICE_DEVS6=
++DEVICE_DEVS7=
++DEVICE_DEVS8=
++DEVICE_DEVS9=
++DEVICE_DEVS10=
++DEVICE_DEVS11=
++DEVICE_DEVS12=
++DEVICE_DEVS13=
++DEVICE_DEVS14=
++DEVICE_DEVS15=
+ DEVICE_DEVS16=
+ DEVICE_DEVS17=
+ DEVICE_DEVS18=
+ DEVICE_DEVS19=
+-DEVICE_DEVS20=$(DD)cljet5.dev $(DD)cljet5c.dev
++DEVICE_DEVS20=
+
+ # ---------------------------- End of options --------------------------- #
+
+@@ -422,3 +419,4 @@
+ include $(GLSRCDIR)/unix-dll.mak
+ include $(GLSRCDIR)/unix-end.mak
+ include $(GLSRCDIR)/unixinst.mak
++@CUPSINCLUDE@
+diff -ur ghostscript-7.05/src/configure.ac espgs/src/configure.ac
+--- ghostscript-7.05/src/configure.ac Fri Apr 19 18:23:09 2002
++++ espgs/src/configure.ac Tue Apr 23 11:08:36 2002
+@@ -167,6 +167,234 @@
+ AC_SUBST(LIBPNGDIR)
+ AC_SUBST(PNGDEVS)
+
++dnl check to see if we want a different name for the executable...
++AC_ARG_WITH(gs,
++ [ --with-gs=NAME Name of the Ghostscript exectuable, default=gs ],
++ GS="$withval", GS="gs")
++
++AC_SUBST(GS)
++
++dnl do we compile the Ghostscript initialization files into Ghostscript?
++COMPILE_INITS="0"
++AC_ARG_ENABLE(compiled-inits,
++ [ --enable-compiled-inits compile initialization files into Ghostscript, default=no],
++ COMPILE_INITS="1")
++
++AC_SUBST(COMPILE_INITS)
++
++dnl look for drivers to compile...
++AC_ARG_WITH(drivers,
++[ --with-drivers=LIST Drivers to support, separated by commas.
++ Either list the drivers or use aliases:
++ ALL = all drivers
++ FILES = all file format drivers
++ PRINTERS = all printer drivers
++ Printers:
++ APPLE = all Apple printers
++ CANON = all Canon printers
++ EPSON = all Epson printers
++ HP = all HP printers
++ IBM = all IBM printers
++ IJS = all printers using IJS
++ LEXMARK = all Lexmark printers
++ OKI = all OKI printers
++ File formats:
++ BMP = Output to bmp files
++ FAX = Output to fax files
++ JPEG = Output to JPEG files
++ PBM = Output to PBM/PNM
++ PCX = Output to PCX
++ PS = Output to PostScript/PDF
++ TIFF = Output to TIFF
++ You can mix both variants, e.g.
++ --with-drivers=HP,stcolor would build HP drivers and
++ the Epson stcolor driver.
++ Aliases must be uppercase (a 3rd party driver might
++ have the same name).
++ Default: ALL],drivers="$withval",drivers="ALL")
++
++AC_ARG_WITH(driversfile,
++[ --with-driversfile=FILE Drivers to support from file, separated by newlines.],
++driversfile="$withval",driversfile="")
++
++if test "x$driversfile" != x; then
++ # Add drivers from file...
++ drivers="`tr '\n' ',' <$driversfile`"
++fi
++
++dnl Check which drivers we'd like to support.
++P_DEVS=""
++F_DEVS=""
++
++dnl Known printers
++HP_DEVS="cdj500 djet500c dnj650c cljet5pr deskjet laserjet ljetplus ljet2p ljet3 ljet3d ljet4 ljet4d lj5mono lj5gray cdeskjet cdjcolor cdjmono cdj550 pj pjxl pjxl300 lp2563 paintjet pjetxl cljet5 cljet5c pxlmono pxlcolor"
++IJS_DEVS="ijs"
++EPSON_DEVS="eps9high eps9mid epson epsonc escp lp8000 lq850 photoex st800 stcolor"
++CANON_DEVS="bj10e bj200 bjc600 bjc800 lbp8"
++LEXMARK_DEVS="lxm5700m"
++APPLE_DEVS="appledmp iwhi iwlo iwlq"
++IBM_DEVS="ibmpro jetp3852"
++OKI_DEVS="oki182 okiibm"
++MISC_PDEVS="uniprint ap3250 atx23 atx24 atx38 coslw2p coslwxl cp50 declj250 fs600 imagen lj250 m8510 necp6 oce9050 r4081 sj48 tek4696"
++
++dnl Known file formats
++BMP_DEVS="bmpmono bmpgray bmpsep1 bmpsep8 bmp16 bmp256 bmp16m bmp32b bmpa16 bmpa16m bmpa256 bmpa32b bmpamono bmpasep1 bmpasep8"
++FAX_DEVS="cfax dfaxlow dfaxhigh fax tfax tiffg3 tiffg32d tiffg4 faxg3 faxg32d faxg4"
++JPEG_DEVS="jpeg jpeggray"
++TIFF_DEVS="tiffs tiff12nc tiff24nc tiffcrle tifflzw tiffpack"
++PCX_DEVS="pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk"
++PBM_DEVS="pbm pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm pksmraw"
++PS_DEVS="psdf pdfwrite pswrite epswrite psgray psmono psrgb"
++MISC_FDEVS="ccr cgm24 cgm8 cgmmono inferno mgr4 mgr8 mgrgray2 mgrgray4 mgrgray8 mgrmono miff24 plan9bm sgirgb sunhmono bit bitrgb bitcmyk"
++
++while test -n "$drivers"; do
++ if echo $drivers |grep -q ","; then
++ THIS="`echo $drivers |sed -e 's/,.*//'`"
++ drivers="`echo $drivers |sed -e \"s/$THIS,//\"`"
++ else
++ THIS=$drivers
++ drivers=""
++ fi
++ case "$THIS" in
++ ALL)
++ # ALL = PRINTERS + FILES...
++ if test -z "$drivers"; then
++ drivers="PRINTERS,FILES"
++ else
++ drivers="$drivers,PRINTERS,FILES"
++ fi
++ ;;
++ PRINTERS)
++ P_DEVS="$P_DEVS $CANON_DEVS $EPSON_DEVS $HP_DEVS $IJS_DEVS $LEXMARK_DEVS $APPLE_DEVS $IBM_DEVS $OKI_DEVS $MISC_PDEVS"
++ ;;
++ FILES)
++ F_DEVS="$F_DEVS $BMP_DEVS $FAX_DEVS $JPEG_DEVS $PNG_DEVS $TIFF_DEVS $PCX_DEVS $PBM_DEVS $PS_DEVS $MISC_FDEVS"
++ ;;
++ APPLE)
++ # All Apple printers
++ P_DEVS="$P_DEVS $APPLE_DEVS"
++ ;;
++ BMP)
++ # BMP file format
++ F_DEVS="$F_DEVS $BMP_DEVS"
++ ;;
++ CANON)
++ # All Canon printers
++ P_DEVS="$P_DEVS $CANON_DEVS"
++ ;;
++ EPSON)
++ # All Epson printers
++ P_DEVS="$P_DEVS $EPSON_DEVS"
++ ;;
++ FAX)
++ # Fax file formats
++ F_DEVS="$F_DEVS $FAX_DEVS"
++ ;;
++ JPEG)
++ # Jpeg file formats
++ F_DEVS="$F_DEVS $JPEG_DEVS"
++ ;;
++ PNG)
++ # PNG file formats
++ F_DEVS="$F_DEVS $PNG_DEVS"
++ ;;
++ TIFF)
++ # TIFF file formats
++ F_DEVS="$F_DEVS $TIFF_DEVS"
++ ;;
++ PCX)
++ # PCX file formats
++ F_DEVS="$F_DEVS $PCX_DEVS"
++ ;;
++ PBM)
++ # PBM file formats
++ F_DEVS="$F_DEVS $PBM_DEVS"
++ ;;
++ HP)
++ # All HP printers
++ P_DEVS="$P_DEVS $HP_DEVS $IJS_DEVS"
++ ;;
++ LEXMARK)
++ # All Lexmark printers
++ P_DEVS="$P_DEVS $LEXMARK_DEVS"
++ ;;
++ OKI)
++ # All OKI printers
++ P_DEVS="$P_DEVS $OKI_DEVS"
++ ;;
++ IBM)
++ # All IBM printers
++ P_DEVS="$P_DEVS $IBM_DEVS"
++ ;;
++ IJS)
++ # All printers using IJS
++ P_DEVS="$P_DEVS $IJS_DEVS"
++ ;;
++ PS)
++ # PostScript/PDF writing
++ F_DEVS="$F_DEVS $PS_DEVS"
++ ;;
++ *)
++ # It's a driver name (or a user messup)
++ P_DEVS="$P_DEVS `echo $THIS |sed -e 's,\.dev$,,'`"
++ ;;
++ esac
++done
++# Make sure we don't have any duplicates in there, add $(DD)foo.dev constructs
++if test -n "$P_DEVS"; then
++ PRINTERS=`(for i in $P_DEVS; do echo '$('DD')'${i}.dev; done) | sort | uniq |xargs echo`
++fi
++if test -n "$F_DEVS"; then
++ FILES=`(for i in $F_DEVS; do echo '$('DD')'${i}.dev; done) | sort | uniq |xargs echo`
++fi
++echo "PRINTERS: $PRINTERS" >>FOO
++echo "FILES: $FILES" >>FOO
++AC_SUBST(PRINTERS)
++AC_SUBST(FILES)
++
++dnl look for default font path...
++AC_ARG_WITH(fontpath, [ --with-fontpath set font path for gs],fontpath="$withval",fontpath="")
++
++dnl Fix "fontpath" variable...
++if test "x$fontpath" = "x"; then
++ # These font directories are used by various Linux distributions...
++ fontpath="$datadir/fonts/default/ghostscript"
++ fontpath="${fontpath}:$datadir/fonts/default/Type1"
++ fontpath="${fontpath}:$datadir/fonts/default/TrueType"
++fi
++
++AC_SUBST(fontpath)
++
++dnl look for CUPS...
++AC_ARG_ENABLE(cups, [ --enable-cups turn on CUPS support, default=yes])
++
++CUPSDEV=""
++CUPSINCLUDE=""
++CUPSCONFIG=":"
++cups_serverroot="/etc/cups"
++cups_serverbin="/usr/lib/cups"
++
++if test -d pstoraster; then
++ if test x$enable_cups != xno; then
++ AC_PATH_PROG(CUPSCONFIG,cups-config)
++ if test "x$CUPSCONFIG" != x; then
++ dnl Use values from CUPS config...
++ LIBS="`$CUPSCONFIG --ldflags` `$CUPSCONFIG --image --libs` $LIBS"
++ CFLAGS="`$CUPSCONFIG --cflags` $CFLAGS"
++ cups_serverroot="`$CUPSCONFIG --serverroot`"
++ cups_serverbin="`$CUPSCONFIG --serverbin`"
++ CUPSINCLUDE="include pstoraster/cups.mak"
++ CUPSDEV="\$(DD)cups.dev"
++ fi
++ fi
++fi
++
++AC_SUBST(CUPSDEV)
++AC_SUBST(CUPSCONFIG)
++AC_SUBST(CUPSINCLUDE)
++AC_SUBST(cups_serverroot)
++AC_SUBST(cups_serverbin)
++
+ dnl look for IJS implementation
+ AC_ARG_WITH(ijs, AC_HELP_STRING([--with-ijs],[include IJS driver support]))
+ dnl set safe defaults
+@@ -202,15 +430,52 @@
+ AC_SUBST(STPDEVS)
+
+ dnl optional X11 for display devices
+-AC_PATH_XTRA
+-if test x"$no_x" = x"yes"; then
+- AC_MSG_NOTICE([disabling X11 output devices])
+- X11DEVS=''
+-else
+- X11DEVS='$(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev'
++AC_PATH_X
++
++XLDFLAGS=""
++X_CFLAGS=""
++X_DEVS=""
++X_LIBS=""
++
++if test x$no_x != xyes; then
++ if test "$x_libraries" = "/usr/lib"; then
++ echo "Ignoring X library directory \"$x_libraries\" requested by configure."
++ x_libraries="NONE"
++ fi
++ if test ! "$x_libraries" = "NONE" -a ! "$x_libraries" = ""; then
++ LDFLAGS="-L$x_libraries $LDFLAGS"
++ XLDFLAGS="-L$x_libraries"
++ if test "$uname" = "SunOS"; then
++ XLDFLAGS="$XLDFLAGS -R$x_libraries"
++ fi
++ fi
++
++ if test "$x_includes" = "/usr/include"; then
++ echo "Ignoring X include directory \"$x_includes\" requested by configure."
++ x_includes="NONE"
++ fi
++ if test ! "$x_includes" = "NONE" -a ! "$x_includes" = ""; then
++ X_CFLAGS="-I$x_includes"
++ fi
++
++ SAVELIBS="$LIBS"
++
++ AC_CHECK_LIB(X11,XOpenDisplay)
++ AC_CHECK_LIB(Xext,XdbeQueryExtension)
++ AC_CHECK_LIB(Xt,XtAppCreateShell)
++
++ LIBS="$SAVELIBS"
++
++ if test "$ac_cv_lib_Xt_XtAppCreateShell" = yes; then
++ X_DEVS="\$(DD)x11.dev \$(DD)x11alpha.dev \$(DD)x11cmyk.dev \$(DD)x11mono.dev \$(DD)x11_.dev \$(DD)x11alt_.dev \$(DD)x11cmyk2.dev \$(DD)x11cmyk4.dev \$(DD)x11cmyk8.dev \$(DD)x11rg16x.dev \$(DD)x11rg32x.dev"
++ X_LIBS="-lXt -lXext -lX11"
++ fi
+ fi
+-AC_SUBST(X11DEVS)
+
++AC_SUBST(XLDFLAGS)
++AC_SUBST(X_CFLAGS)
++AC_SUBST(X_LIBS)
++AC_SUBST(X_DEVS)
+
+ dnl --------------------------------------------------
+ dnl Check for library functions
+@@ -233,4 +498,9 @@
+ dnl --------------------------------------------------
+
+ AC_SUBST(GCFLAGS)
+-AC_OUTPUT(Makefile)
++
++if test -d pstoraster; then
++ AC_OUTPUT(Makefile pstoraster/pstoraster)
++else
++ AC_OUTPUT(Makefile)
++fi
+--- ghostscript-7.05/configure Mon Apr 22 22:29:10 2002
++++ espgs/configure Tue Apr 23 11:08:52 2002
+@@ -823,9 +823,46 @@
+
+ cat <<\_ACEOF
+
++Optional Features:
++ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
++ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
++ --enable-compiled-inits compile initialization files into Ghostscript, default=no
++ --enable-cups turn on CUPS support, default=yes
++
+ Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
++ --with-gs=NAME Name of the Ghostscript exectuable, default=gs
++ --with-drivers=LIST Drivers to support, separated by commas.
++ Either list the drivers or use aliases:
++ ALL = all drivers
++ FILES = all file format drivers
++ PRINTERS = all printer drivers
++ Printers:
++ APPLE = all Apple printers
++ CANON = all Canon printers
++ EPSON = all Epson printers
++ HP = all HP printers
++ IBM = all IBM printers
++ IJS = all printers using IJS
++ LEXMARK = all Lexmark printers
++ OKI = all OKI printers
++ File formats:
++ BMP = Output to bmp files
++ FAX = Output to fax files
++ JPEG = Output to JPEG files
++ PBM = Output to PBM/PNM
++ PCX = Output to PCX
++ PS = Output to PostScript/PDF
++ TIFF = Output to TIFF
++ You can mix both variants, e.g.
++ --with-drivers=HP,stcolor would build HP drivers and
++ the Epson stcolor driver.
++ Aliases must be uppercase (a 3rd party driver might
++ have the same name).
++ Default: ALL
++ --with-driversfile=FILE Drivers to support from file, separated by newlines.
++ --with-fontpath set font path for gs
+ --with-ijs include IJS driver support
+ --with-gimp-print build the gimp-print (stp) driver
+ --with-x use the X Window System
+@@ -3962,6 +3999,264 @@
+
+
+
++# Check whether --with-gs or --without-gs was given.
++if test "${with_gs+set}" = set; then
++ withval="$with_gs"
++ GS="$withval"
++else
++ GS="gs"
++fi;
++
++
++
++COMPILE_INITS="0"
++# Check whether --enable-compiled-inits or --disable-compiled-inits was given.
++if test "${enable_compiled_inits+set}" = set; then
++ enableval="$enable_compiled_inits"
++ COMPILE_INITS="1"
++fi;
++
++
++
++
++# Check whether --with-drivers or --without-drivers was given.
++if test "${with_drivers+set}" = set; then
++ withval="$with_drivers"
++ drivers="$withval"
++else
++ drivers="ALL"
++fi;
++
++
++# Check whether --with-driversfile or --without-driversfile was given.
++if test "${with_driversfile+set}" = set; then
++ withval="$with_driversfile"
++ driversfile="$withval"
++else
++ driversfile=""
++fi;
++
++if test "x$driversfile" != x; then
++ # Add drivers from file...
++ drivers="`tr '\n' ',' <$driversfile`"
++fi
++
++P_DEVS=""
++F_DEVS=""
++
++HP_DEVS="cdj500 djet500c dnj650c cljet5pr deskjet laserjet ljetplus ljet2p ljet3 ljet3d ljet4 ljet4d lj5mono lj5gray cdeskjet cdjcolor cdjmono cdj550 pj pjxl pjxl300 lp2563 paintjet pjetxl cljet5 cljet5c pxlmono pxlcolor"
++IJS_DEVS="ijs"
++EPSON_DEVS="eps9high eps9mid epson epsonc escp lp8000 lq850 photoex st800 stcolor"
++CANON_DEVS="bj10e bj200 bjc600 bjc800 lbp8"
++LEXMARK_DEVS="lxm5700m"
++APPLE_DEVS="appledmp iwhi iwlo iwlq"
++IBM_DEVS="ibmpro jetp3852"
++OKI_DEVS="oki182 okiibm"
++MISC_PDEVS="uniprint ap3250 atx23 atx24 atx38 coslw2p coslwxl cp50 declj250 fs600 imagen lj250 m8510 necp6 oce9050 r4081 sj48 tek4696"
++
++BMP_DEVS="bmpmono bmpgray bmpsep1 bmpsep8 bmp16 bmp256 bmp16m bmp32b bmpa16 bmpa16m bmpa256 bmpa32b bmpamono bmpasep1 bmpasep8"
++FAX_DEVS="cfax dfaxlow dfaxhigh fax tfax tiffg3 tiffg32d tiffg4 faxg3 faxg32d faxg4"
++JPEG_DEVS="jpeg jpeggray"
++TIFF_DEVS="tiffs tiff12nc tiff24nc tiffcrle tifflzw tiffpack"
++PCX_DEVS="pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk"
++PBM_DEVS="pbm pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm pksmraw"
++PS_DEVS="psdf pdfwrite pswrite epswrite psgray psmono psrgb"
++MISC_FDEVS="ccr cgm24 cgm8 cgmmono inferno mgr4 mgr8 mgrgray2 mgrgray4 mgrgray8 mgrmono miff24 plan9bm sgirgb sunhmono bit bitrgb bitcmyk"
++
++while test -n "$drivers"; do
++ if echo $drivers |grep -q ","; then
++ THIS="`echo $drivers |sed -e 's/,.*//'`"
++ drivers="`echo $drivers |sed -e \"s/$THIS,//\"`"
++ else
++ THIS=$drivers
++ drivers=""
++ fi
++ case "$THIS" in
++ ALL)
++ # ALL = PRINTERS + FILES...
++ if test -z "$drivers"; then
++ drivers="PRINTERS,FILES"
++ else
++ drivers="$drivers,PRINTERS,FILES"
++ fi
++ ;;
++ PRINTERS)
++ P_DEVS="$P_DEVS $CANON_DEVS $EPSON_DEVS $HP_DEVS $IJS_DEVS $LEXMARK_DEVS $APPLE_DEVS $IBM_DEVS $OKI_DEVS $MISC_PDEVS"
++ ;;
++ FILES)
++ F_DEVS="$F_DEVS $BMP_DEVS $FAX_DEVS $JPEG_DEVS $PNG_DEVS $TIFF_DEVS $PCX_DEVS $PBM_DEVS $PS_DEVS $MISC_FDEVS"
++ ;;
++ APPLE)
++ # All Apple printers
++ P_DEVS="$P_DEVS $APPLE_DEVS"
++ ;;
++ BMP)
++ # BMP file format
++ F_DEVS="$F_DEVS $BMP_DEVS"
++ ;;
++ CANON)
++ # All Canon printers
++ P_DEVS="$P_DEVS $CANON_DEVS"
++ ;;
++ EPSON)
++ # All Epson printers
++ P_DEVS="$P_DEVS $EPSON_DEVS"
++ ;;
++ FAX)
++ # Fax file formats
++ F_DEVS="$F_DEVS $FAX_DEVS"
++ ;;
++ JPEG)
++ # Jpeg file formats
++ F_DEVS="$F_DEVS $JPEG_DEVS"
++ ;;
++ PNG)
++ # PNG file formats
++ F_DEVS="$F_DEVS $PNG_DEVS"
++ ;;
++ TIFF)
++ # TIFF file formats
++ F_DEVS="$F_DEVS $TIFF_DEVS"
++ ;;
++ PCX)
++ # PCX file formats
++ F_DEVS="$F_DEVS $PCX_DEVS"
++ ;;
++ PBM)
++ # PBM file formats
++ F_DEVS="$F_DEVS $PBM_DEVS"
++ ;;
++ HP)
++ # All HP printers
++ P_DEVS="$P_DEVS $HP_DEVS $IJS_DEVS"
++ ;;
++ LEXMARK)
++ # All Lexmark printers
++ P_DEVS="$P_DEVS $LEXMARK_DEVS"
++ ;;
++ OKI)
++ # All OKI printers
++ P_DEVS="$P_DEVS $OKI_DEVS"
++ ;;
++ IBM)
++ # All IBM printers
++ P_DEVS="$P_DEVS $IBM_DEVS"
++ ;;
++ IJS)
++ # All printers using IJS
++ P_DEVS="$P_DEVS $IJS_DEVS"
++ ;;
++ PS)
++ # PostScript/PDF writing
++ F_DEVS="$F_DEVS $PS_DEVS"
++ ;;
++ *)
++ # It's a driver name (or a user messup)
++ P_DEVS="$P_DEVS `echo $THIS |sed -e 's,\.dev$,,'`"
++ ;;
++ esac
++done
++# Make sure we don't have any duplicates in there, add $(DD)foo.dev constructs
++if test -n "$P_DEVS"; then
++ PRINTERS=`(for i in $P_DEVS; do echo '$('DD')'${i}.dev; done) | sort | uniq |xargs echo`
++fi
++if test -n "$F_DEVS"; then
++ FILES=`(for i in $F_DEVS; do echo '$('DD')'${i}.dev; done) | sort | uniq |xargs echo`
++fi
++echo "PRINTERS: $PRINTERS" >>FOO
++echo "FILES: $FILES" >>FOO
++
++
++
++
++# Check whether --with-fontpath or --without-fontpath was given.
++if test "${with_fontpath+set}" = set; then
++ withval="$with_fontpath"
++ fontpath="$withval"
++else
++ fontpath=""
++fi;
++
++if test "x$fontpath" = "x"; then
++ # These font directories are used by various Linux distributions...
++ fontpath="$datadir/fonts/default/ghostscript"
++ fontpath="${fontpath}:$datadir/fonts/default/Type1"
++ fontpath="${fontpath}:$datadir/fonts/default/TrueType"
++fi
++
++
++
++# Check whether --enable-cups or --disable-cups was given.
++if test "${enable_cups+set}" = set; then
++ enableval="$enable_cups"
++
++fi;
++
++CUPSDEV=""
++CUPSINCLUDE=""
++CUPSCONFIG=":"
++cups_serverroot="/etc/cups"
++cups_serverbin="/usr/lib/cups"
++
++if test -d pstoraster; then
++ if test x$enable_cups != xno; then
++ # Extract the first word of "cups-config", so it can be a program name with args.
++set dummy cups-config; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_path_CUPSCONFIG+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ case $CUPSCONFIG in
++ [\\/]* | ?:[\\/]*)
++ ac_cv_path_CUPSCONFIG="$CUPSCONFIG" # Let the user override the test with a path.
++ ;;
++ *)
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_path_CUPSCONFIG="$as_dir/$ac_word$ac_exec_ext"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++ ;;
++esac
++fi
++CUPSCONFIG=$ac_cv_path_CUPSCONFIG
++
++if test -n "$CUPSCONFIG"; then
++ echo "$as_me:$LINENO: result: $CUPSCONFIG" >&5
++echo "${ECHO_T}$CUPSCONFIG" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ if test "x$CUPSCONFIG" != x; then
++ LIBS="`$CUPSCONFIG --ldflags` `$CUPSCONFIG --image --libs` $LIBS"
++ CFLAGS="`$CUPSCONFIG --cflags` $CFLAGS"
++ cups_serverroot="`$CUPSCONFIG --serverroot`"
++ cups_serverbin="`$CUPSCONFIG --serverbin`"
++ CUPSINCLUDE="include pstoraster/cups.mak"
++ CUPSDEV="\$(DD)cups.dev"
++ fi
++ fi
++fi
++
++
++
++
++
++
++
++
+ # Check whether --with-ijs or --without-ijs was given.
+ if test "${with_ijs+set}" = set; then
+ withval="$with_ijs"
+@@ -4387,134 +4682,44 @@
+ echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6
+ fi
+
+-if test "$no_x" = yes; then
+- # Not all programs may use this symbol, but it does not hurt to define it.
+-
+-cat >>confdefs.h <<\_ACEOF
+-#define X_DISPLAY_MISSING 1
+-_ACEOF
+-
+- X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+-else
+- if test -n "$x_includes"; then
+- X_CFLAGS="$X_CFLAGS -I$x_includes"
+- fi
+
+- # It would also be nice to do this for all -L options, not just this one.
+- if test -n "$x_libraries"; then
+- X_LIBS="$X_LIBS -L$x_libraries"
+- # For Solaris; some versions of Sun CC require a space after -R and
+- # others require no space. Words are not sufficient . . . .
+- case `(uname -sr) 2>/dev/null` in
+- "SunOS 5"*)
+- echo "$as_me:$LINENO: checking whether -R must be followed by a space" >&5
+-echo $ECHO_N "checking whether -R must be followed by a space... $ECHO_C" >&6
+- ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries"
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
++XLDFLAGS=""
++X_CFLAGS=""
++X_DEVS=""
++X_LIBS=""
++
++if test x$no_x != xyes; then
++ if test "$x_libraries" = "/usr/lib"; then
++ echo "Ignoring X library directory \"$x_libraries\" requested by configure."
++ x_libraries="NONE"
++ fi
++ if test ! "$x_libraries" = "NONE" -a ! "$x_libraries" = ""; then
++ LDFLAGS="-L$x_libraries $LDFLAGS"
++ XLDFLAGS="-L$x_libraries"
++ if test "$uname" = "SunOS"; then
++ XLDFLAGS="$XLDFLAGS -R$x_libraries"
++ fi
++ fi
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
++ if test "$x_includes" = "/usr/include"; then
++ echo "Ignoring X include directory \"$x_includes\" requested by configure."
++ x_includes="NONE"
++ fi
++ if test ! "$x_includes" = "NONE" -a ! "$x_includes" = ""; then
++ X_CFLAGS="-I$x_includes"
++ fi
+
+- ;
+- return 0;
+-}
+-_ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- ac_R_nospace=yes
+-else
+- echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-ac_R_nospace=no
+-fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+- if test $ac_R_nospace = yes; then
+- echo "$as_me:$LINENO: result: no" >&5
+-echo "${ECHO_T}no" >&6
+- X_LIBS="$X_LIBS -R$x_libraries"
+- else
+- LIBS="$ac_xsave_LIBS -R $x_libraries"
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
++ SAVELIBS="$LIBS"
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+
+- ;
+- return 0;
+-}
+-_ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- ac_R_space=yes
++echo "$as_me:$LINENO: checking for XOpenDisplay in -lX11" >&5
++echo $ECHO_N "checking for XOpenDisplay in -lX11... $ECHO_C" >&6
++if test "${ac_cv_lib_X11_XOpenDisplay+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+- echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-ac_R_space=no
+-fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+- if test $ac_R_space = yes; then
+- echo "$as_me:$LINENO: result: yes" >&5
+-echo "${ECHO_T}yes" >&6
+- X_LIBS="$X_LIBS -R $x_libraries"
+- else
+- echo "$as_me:$LINENO: result: neither works" >&5
+-echo "${ECHO_T}neither works" >&6
+- fi
+- fi
+- LIBS=$ac_xsave_LIBS
+- esac
+- fi
+-
+- # Check for system-dependent libraries X programs must link with.
+- # Do this before checking for the system-independent R6 libraries
+- # (-lICE), since we may need -lsocket or whatever for X linking.
+-
+- if test "$ISC" = yes; then
+- X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+- else
+- # Martyn Johnson says this is needed for Ultrix, if the X
+- # libraries were built with DECnet support. And Karl Berry says
+- # the Alpha needs dnet_stub (dnet does not exist).
+- ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11"
+- cat >conftest.$ac_ext <<_ACEOF
++ ac_check_lib_save_LIBS=$LIBS
++LIBS="-lX11 $LIBS"
++cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+
+@@ -4551,17 +4756,34 @@
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- :
++ ac_cv_lib_X11_XOpenDisplay=yes
+ else
+ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet" >&5
+-echo $ECHO_N "checking for dnet_ntoa in -ldnet... $ECHO_C" >&6
+-if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then
++ac_cv_lib_X11_XOpenDisplay=no
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++echo "$as_me:$LINENO: result: $ac_cv_lib_X11_XOpenDisplay" >&5
++echo "${ECHO_T}$ac_cv_lib_X11_XOpenDisplay" >&6
++if test $ac_cv_lib_X11_XOpenDisplay = yes; then
++ cat >>confdefs.h <<_ACEOF
++#define HAVE_LIBX11 1
++_ACEOF
++
++ LIBS="-lX11 $LIBS"
++
++fi
++
++
++echo "$as_me:$LINENO: checking for XdbeQueryExtension in -lXext" >&5
++echo $ECHO_N "checking for XdbeQueryExtension in -lXext... $ECHO_C" >&6
++if test "${ac_cv_lib_Xext_XdbeQueryExtension+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+ ac_check_lib_save_LIBS=$LIBS
+-LIBS="-ldnet $LIBS"
++LIBS="-lXext $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+@@ -4572,7 +4794,7 @@
+ #endif
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+-char dnet_ntoa ();
++char XdbeQueryExtension ();
+ #ifdef F77_DUMMY_MAIN
+ # ifdef __cplusplus
+ extern "C"
+@@ -4582,7 +4804,7 @@
+ int
+ main ()
+ {
+-dnet_ntoa ();
++XdbeQueryExtension ();
+ ;
+ return 0;
+ }
+@@ -4599,29 +4821,34 @@
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_lib_dnet_dnet_ntoa=yes
++ ac_cv_lib_Xext_XdbeQueryExtension=yes
+ else
+ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_lib_dnet_dnet_ntoa=no
++ac_cv_lib_Xext_XdbeQueryExtension=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ LIBS=$ac_check_lib_save_LIBS
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_dnet_ntoa" >&5
+-echo "${ECHO_T}$ac_cv_lib_dnet_dnet_ntoa" >&6
+-if test $ac_cv_lib_dnet_dnet_ntoa = yes; then
+- X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
++echo "$as_me:$LINENO: result: $ac_cv_lib_Xext_XdbeQueryExtension" >&5
++echo "${ECHO_T}$ac_cv_lib_Xext_XdbeQueryExtension" >&6
++if test $ac_cv_lib_Xext_XdbeQueryExtension = yes; then
++ cat >>confdefs.h <<_ACEOF
++#define HAVE_LIBXEXT 1
++_ACEOF
++
++ LIBS="-lXext $LIBS"
++
+ fi
+
+- if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+- echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet_stub" >&5
+-echo $ECHO_N "checking for dnet_ntoa in -ldnet_stub... $ECHO_C" >&6
+-if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then
++
++echo "$as_me:$LINENO: checking for XtAppCreateShell in -lXt" >&5
++echo $ECHO_N "checking for XtAppCreateShell in -lXt... $ECHO_C" >&6
++if test "${ac_cv_lib_Xt_XtAppCreateShell+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+ ac_check_lib_save_LIBS=$LIBS
+-LIBS="-ldnet_stub $LIBS"
++LIBS="-lXt $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+@@ -4632,7 +4859,7 @@
+ #endif
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+-char dnet_ntoa ();
++char XtAppCreateShell ();
+ #ifdef F77_DUMMY_MAIN
+ # ifdef __cplusplus
+ extern "C"
+@@ -4642,7 +4869,7 @@
+ int
+ main ()
+ {
+-dnet_ntoa ();
++XtAppCreateShell ();
+ ;
+ return 0;
+ }
+@@ -4659,44 +4886,55 @@
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_lib_dnet_stub_dnet_ntoa=yes
++ ac_cv_lib_Xt_XtAppCreateShell=yes
+ else
+ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_lib_dnet_stub_dnet_ntoa=no
++ac_cv_lib_Xt_XtAppCreateShell=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ LIBS=$ac_check_lib_save_LIBS
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5
+-echo "${ECHO_T}$ac_cv_lib_dnet_stub_dnet_ntoa" >&6
+-if test $ac_cv_lib_dnet_stub_dnet_ntoa = yes; then
+- X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
++echo "$as_me:$LINENO: result: $ac_cv_lib_Xt_XtAppCreateShell" >&5
++echo "${ECHO_T}$ac_cv_lib_Xt_XtAppCreateShell" >&6
++if test $ac_cv_lib_Xt_XtAppCreateShell = yes; then
++ cat >>confdefs.h <<_ACEOF
++#define HAVE_LIBXT 1
++_ACEOF
++
++ LIBS="-lXt $LIBS"
++
+ fi
+
+- fi
++
++ LIBS="$SAVELIBS"
++
++ if test "$ac_cv_lib_Xt_XtAppCreateShell" = yes; then
++ X_DEVS="\$(DD)x11.dev \$(DD)x11alpha.dev \$(DD)x11cmyk.dev \$(DD)x11mono.dev \$(DD)x11_.dev \$(DD)x11alt_.dev \$(DD)x11cmyk2.dev \$(DD)x11cmyk4.dev \$(DD)x11cmyk8.dev \$(DD)x11rg16x.dev \$(DD)x11rg32x.dev"
++ X_LIBS="-lXt -lXext -lX11"
++ fi
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+- LIBS="$ac_xsave_LIBS"
+
+- # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+- # to get the SysV transport functions.
+- # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4)
+- # needs -lnsl.
+- # The nsl library prevents programs from opening the X display
+- # on Irix 5.2, according to T.E. Dickey.
+- # The functions gethostbyname, getservbyname, and inet_addr are
+- # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking.
+- echo "$as_me:$LINENO: checking for gethostbyname" >&5
+-echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6
+-if test "${ac_cv_func_gethostbyname+set}" = set; then
++
++
++
++
++
++
++
++for ac_func in mkstemp
++do
++as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
++echo "$as_me:$LINENO: checking for $ac_func" >&5
++echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
++if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+ /* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char gethostbyname (); below. */
++ which can conflict with char $ac_func (); below. */
+ #include <assert.h>
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -4704,7 +4942,7 @@
+ #endif
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+-char gethostbyname ();
++char $ac_func ();
+ char (*f) ();
+
+ #ifdef F77_DUMMY_MAIN
+@@ -4719,10 +4957,10 @@
+ /* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+-#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
++#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+ choke me
+ #else
+-f = gethostbyname;
++f = $ac_func;
+ #endif
+
+ ;
+@@ -4741,36 +4979,35 @@
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_func_gethostbyname=yes
++ eval "$as_ac_var=yes"
+ else
+ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_func_gethostbyname=no
++eval "$as_ac_var=no"
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5
+-echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
++if test `eval echo '${'$as_ac_var'}'` = yes; then
++ cat >>confdefs.h <<_ACEOF
++#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
++_ACEOF
++ HAVE_MKSTEMP=-DHAVE_MKSTEMP
++fi
++done
++
++
+
+- if test $ac_cv_func_gethostbyname = no; then
+- echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+-echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
+-if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
++echo "$as_me:$LINENO: checking for pid_t" >&5
++echo $ECHO_N "checking for pid_t... $ECHO_C" >&6
++if test "${ac_cv_type_pid_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+- ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lnsl $LIBS"
+-cat >conftest.$ac_ext <<_ACEOF
++ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+-
+-/* Override any gcc2 internal prototype to avoid an error. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char gethostbyname ();
++$ac_includes_default
+ #ifdef F77_DUMMY_MAIN
+ # ifdef __cplusplus
+ extern "C"
+@@ -4780,118 +5017,176 @@
+ int
+ main ()
+ {
+-gethostbyname ();
++if ((pid_t *) 0)
++ return 0;
++if (sizeof (pid_t))
++ return 0;
+ ;
+ return 0;
+ }
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
++ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_lib_nsl_gethostbyname=yes
++ ac_cv_type_pid_t=yes
+ else
+ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_lib_nsl_gethostbyname=no
+-fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+-LIBS=$ac_check_lib_save_LIBS
++ac_cv_type_pid_t=no
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+-echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
+-if test $ac_cv_lib_nsl_gethostbyname = yes; then
+- X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
++rm -f conftest.$ac_objext conftest.$ac_ext
+ fi
+-
+- if test $ac_cv_lib_nsl_gethostbyname = no; then
+- echo "$as_me:$LINENO: checking for gethostbyname in -lbsd" >&5
+-echo $ECHO_N "checking for gethostbyname in -lbsd... $ECHO_C" >&6
+-if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
++echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
++echo "${ECHO_T}$ac_cv_type_pid_t" >&6
++if test $ac_cv_type_pid_t = yes; then
++ :
+ else
+- ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lbsd $LIBS"
+-cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+
+-/* Override any gcc2 internal prototype to avoid an error. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char gethostbyname ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+-gethostbyname ();
+- ;
+- return 0;
+-}
++cat >>confdefs.h <<_ACEOF
++#define pid_t int
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
++
++fi
++
++
++
++for ac_header in unistd.h vfork.h
++do
++as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
++ echo "$as_me:$LINENO: checking for $ac_header" >&5
++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++fi
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
++else
++ # Is the header compilable?
++echo "$as_me:$LINENO: checking $ac_header usability" >&5
++echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++$ac_includes_default
++#include <$ac_header>
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
++ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_lib_bsd_gethostbyname=yes
++ ac_header_compiler=yes
+ else
+ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_lib_bsd_gethostbyname=no
++ac_header_compiler=no
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+-LIBS=$ac_check_lib_save_LIBS
++rm -f conftest.$ac_objext conftest.$ac_ext
++echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
++echo "${ECHO_T}$ac_header_compiler" >&6
++
++# Is the header present?
++echo "$as_me:$LINENO: checking $ac_header presence" >&5
++echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++#include <$ac_header>
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++ ac_status=$?
++ egrep -v '^ *\+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_c_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gethostbyname" >&5
+-echo "${ECHO_T}$ac_cv_lib_bsd_gethostbyname" >&6
+-if test $ac_cv_lib_bsd_gethostbyname = yes; then
+- X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd"
++if test -z "$ac_cpp_err"; then
++ ac_header_preproc=yes
++else
++ echo "$as_me: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ ac_header_preproc=no
+ fi
++rm -f conftest.err conftest.$ac_ext
++echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
++echo "${ECHO_T}$ac_header_preproc" >&6
+
+- fi
+- fi
++# So? What about this header?
++case $ac_header_compiler:$ac_header_preproc in
++ yes:no )
++ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
++echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
++ no:yes )
++ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
++echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
++ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
++echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
++esac
++echo "$as_me:$LINENO: checking for $ac_header" >&5
++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ eval "$as_ac_Header=$ac_header_preproc"
++fi
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
++
++fi
++if test `eval echo '${'$as_ac_Header'}'` = yes; then
++ cat >>confdefs.h <<_ACEOF
++#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
++_ACEOF
++
++fi
++
++done
+
+- # lieder@skyler.mavd.honeywell.com says without -lsocket,
+- # socket/setsockopt and other routines are undefined under SCO ODT
+- # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary
+- # on later versions), says Simon Leinen: it contains gethostby*
+- # variants that don't use the nameserver (or something). -lsocket
+- # must be given before -lnsl if both are needed. We assume that
+- # if connect needs -lnsl, so does gethostbyname.
+- echo "$as_me:$LINENO: checking for connect" >&5
+-echo $ECHO_N "checking for connect... $ECHO_C" >&6
+-if test "${ac_cv_func_connect+set}" = set; then
++
++
++for ac_func in fork vfork
++do
++as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
++echo "$as_me:$LINENO: checking for $ac_func" >&5
++echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
++if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+ /* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char connect (); below. */
++ which can conflict with char $ac_func (); below. */
+ #include <assert.h>
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -4899,7 +5194,7 @@
+ #endif
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+-char connect ();
++char $ac_func ();
+ char (*f) ();
+
+ #ifdef F77_DUMMY_MAIN
+@@ -4914,10 +5209,10 @@
+ /* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+-#if defined (__stub_connect) || defined (__stub___connect)
++#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+ choke me
+ #else
+-f = connect;
++f = $ac_func;
+ #endif
+
+ ;
+@@ -4936,292 +5231,422 @@
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_func_connect=yes
++ eval "$as_ac_var=yes"
+ else
+ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_func_connect=no
++eval "$as_ac_var=no"
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+-echo "${ECHO_T}$ac_cv_func_connect" >&6
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
++if test `eval echo '${'$as_ac_var'}'` = yes; then
++ cat >>confdefs.h <<_ACEOF
++#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
++_ACEOF
++
++fi
++done
+
+- if test $ac_cv_func_connect = no; then
+- echo "$as_me:$LINENO: checking for connect in -lsocket" >&5
+-echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6
+-if test "${ac_cv_lib_socket_connect+set}" = set; then
++ac_cv_func_fork_works=$ac_cv_func_fork
++if test "x$ac_cv_func_fork" = xyes; then
++ echo "$as_me:$LINENO: checking for working fork" >&5
++echo $ECHO_N "checking for working fork... $ECHO_C" >&6
++if test "${ac_cv_func_fork_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+- ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+-cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-
+-/* Override any gcc2 internal prototype to avoid an error. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char connect ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+-connect ();
+- ;
+- return 0;
+-}
++ if test "$cross_compiling" = yes; then
++ ac_cv_func_fork_works=cross
++else
++ cat >conftest.$ac_ext <<_ACEOF
++/* By Ruediger Kuhlmann. */
++ #include <sys/types.h>
++ #if HAVE_UNISTD_H
++ # include <unistd.h>
++ #endif
++ /* Some systems only have a dummy stub for fork() */
++ int main ()
++ {
++ if (fork() < 0)
++ exit (1);
++ exit (0);
++ }
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
++rm -f conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_lib_socket_connect=yes
++ ac_cv_func_fork_works=yes
+ else
+- echo "$as_me: failed program was:" >&5
++ echo "$as_me: program exited with status $ac_status" >&5
++echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_lib_socket_connect=no
++( exit $ac_status )
++ac_cv_func_fork_works=no
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+-LIBS=$ac_check_lib_save_LIBS
++rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5
+-echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6
+-if test $ac_cv_lib_socket_connect = yes; then
+- X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+ fi
++echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5
++echo "${ECHO_T}$ac_cv_func_fork_works" >&6
+
+- fi
+-
+- # Guillermo Gomez says -lposix is necessary on A/UX.
+- echo "$as_me:$LINENO: checking for remove" >&5
+-echo $ECHO_N "checking for remove... $ECHO_C" >&6
+-if test "${ac_cv_func_remove+set}" = set; then
++fi
++if test "x$ac_cv_func_fork_works" = xcross; then
++ case $host in
++ *-*-amigaos* | *-*-msdosdjgpp*)
++ # Override, as these systems have only a dummy fork() stub
++ ac_cv_func_fork_works=no
++ ;;
++ *)
++ ac_cv_func_fork_works=yes
++ ;;
++ esac
++ { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
++echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
++fi
++ac_cv_func_vfork_works=$ac_cv_func_vfork
++if test "x$ac_cv_func_vfork" = xyes; then
++ echo "$as_me:$LINENO: checking for working vfork" >&5
++echo $ECHO_N "checking for working vfork... $ECHO_C" >&6
++if test "${ac_cv_func_vfork_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
++ if test "$cross_compiling" = yes; then
++ ac_cv_func_vfork_works=cross
++else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+-/* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char remove (); below. */
+-#include <assert.h>
+-/* Override any gcc2 internal prototype to avoid an error. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char remove ();
+-char (*f) ();
+-
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
++/* Thanks to Paul Eggert for this test. */
++#include <stdio.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#if HAVE_UNISTD_H
++# include <unistd.h>
+ #endif
++#if HAVE_VFORK_H
++# include <vfork.h>
++#endif
++/* On some sparc systems, changes by the child to local and incoming
++ argument registers are propagated back to the parent. The compiler
++ is told about this with #include <vfork.h>, but some compilers
++ (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a
++ static variable whose address is put into a register that is
++ clobbered by the vfork. */
++static
++#ifdef __cplusplus
++sparc_address_test (int arg)
++# else
++sparc_address_test (arg) int arg;
++#endif
++{
++ static pid_t child;
++ if (!child) {
++ child = vfork ();
++ if (child < 0) {
++ perror ("vfork");
++ _exit(2);
++ }
++ if (!child) {
++ arg = getpid();
++ write(-1, "", 0);
++ _exit (arg);
++ }
++ }
++}
++
+ int
+ main ()
+ {
+-/* The GNU C library defines this for functions which it implements
+- to always fail with ENOSYS. Some functions are actually named
+- something starting with __ and the normal name is an alias. */
+-#if defined (__stub_remove) || defined (__stub___remove)
+-choke me
+-#else
+-f = remove;
+-#endif
++ pid_t parent = getpid ();
++ pid_t child;
+
+- ;
+- return 0;
++ sparc_address_test ();
++
++ child = vfork ();
++
++ if (child == 0) {
++ /* Here is another test for sparc vfork register problems. This
++ test uses lots of local variables, at least as many local
++ variables as main has allocated so far including compiler
++ temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
++ 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
++ reuse the register of parent for one of the local variables,
++ since it will think that parent can't possibly be used any more
++ in this routine. Assigning to the local variable will thus
++ munge parent in the parent process. */
++ pid_t
++ p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
++ p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
++ /* Convince the compiler that p..p7 are live; otherwise, it might
++ use the same hardware register for all 8 local variables. */
++ if (p != p1 || p != p2 || p != p3 || p != p4
++ || p != p5 || p != p6 || p != p7)
++ _exit(1);
++
++ /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
++ from child file descriptors. If the child closes a descriptor
++ before it execs or exits, this munges the parent's descriptor
++ as well. Test for this by closing stdout in the child. */
++ _exit(close(fileno(stdout)) != 0);
++ } else {
++ int status;
++ struct stat st;
++
++ while (wait(&status) != child)
++ ;
++ exit(
++ /* Was there some problem with vforking? */
++ child < 0
++
++ /* Did the child fail? (This shouldn't happen.) */
++ || status
++
++ /* Did the vfork/compiler bug occur? */
++ || parent != getpid()
++
++ /* Did the file descriptor bug occur? */
++ || fstat(fileno(stdout), &st) != 0
++ );
++ }
+ }
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
++rm -f conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_func_remove=yes
++ ac_cv_func_vfork_works=yes
+ else
+- echo "$as_me: failed program was:" >&5
++ echo "$as_me: program exited with status $ac_status" >&5
++echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_func_remove=no
++( exit $ac_status )
++ac_cv_func_vfork_works=no
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++fi
++fi
++echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5
++echo "${ECHO_T}$ac_cv_func_vfork_works" >&6
++
++fi;
++if test "x$ac_cv_func_fork_works" = xcross; then
++ ac_cv_func_vfork_works=ac_cv_func_vfork
++ { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
++echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
++fi
++
++if test "x$ac_cv_func_vfork_works" = xyes; then
++
++cat >>confdefs.h <<\_ACEOF
++#define HAVE_WORKING_VFORK 1
++_ACEOF
++
++else
++
++cat >>confdefs.h <<\_ACEOF
++#define vfork fork
++_ACEOF
++
++fi
++if test "x$ac_cv_func_fork_works" = xyes; then
++
++cat >>confdefs.h <<\_ACEOF
++#define HAVE_WORKING_FORK 1
++_ACEOF
++
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_func_remove" >&5
+-echo "${ECHO_T}$ac_cv_func_remove" >&6
+
+- if test $ac_cv_func_remove = no; then
+- echo "$as_me:$LINENO: checking for remove in -lposix" >&5
+-echo $ECHO_N "checking for remove in -lposix... $ECHO_C" >&6
+-if test "${ac_cv_lib_posix_remove+set}" = set; then
++if test $ac_cv_c_compiler_gnu = yes; then
++ echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
++echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
++if test "${ac_cv_prog_gcc_traditional+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+- ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lposix $LIBS"
+-cat >conftest.$ac_ext <<_ACEOF
++ ac_pattern="Autoconf.*'x'"
++ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
++#include <sgtty.h>
++Autoconf TIOCGETP
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++ egrep "$ac_pattern" >/dev/null 2>&1; then
++ ac_cv_prog_gcc_traditional=yes
++else
++ ac_cv_prog_gcc_traditional=no
++fi
++rm -f conftest*
+
+-/* Override any gcc2 internal prototype to avoid an error. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char remove ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+-remove ();
+- ;
+- return 0;
+-}
++
++ if test $ac_cv_prog_gcc_traditional = no; then
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++#include <termio.h>
++Autoconf TCGETA
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++ egrep "$ac_pattern" >/dev/null 2>&1; then
++ ac_cv_prog_gcc_traditional=yes
++fi
++rm -f conftest*
++
++ fi
++fi
++echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
++echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
++ if test $ac_cv_prog_gcc_traditional = yes; then
++ CC="$CC -traditional"
++ fi
++fi
++
++
++for ac_header in stdlib.h
++do
++as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
++ echo "$as_me:$LINENO: checking for $ac_header" >&5
++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++fi
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
++else
++ # Is the header compilable?
++echo "$as_me:$LINENO: checking $ac_header usability" >&5
++echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++$ac_includes_default
++#include <$ac_header>
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
++ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_lib_posix_remove=yes
++ ac_header_compiler=yes
+ else
+ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_lib_posix_remove=no
+-fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+-LIBS=$ac_check_lib_save_LIBS
+-fi
+-echo "$as_me:$LINENO: result: $ac_cv_lib_posix_remove" >&5
+-echo "${ECHO_T}$ac_cv_lib_posix_remove" >&6
+-if test $ac_cv_lib_posix_remove = yes; then
+- X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
++ac_header_compiler=no
+ fi
++rm -f conftest.$ac_objext conftest.$ac_ext
++echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
++echo "${ECHO_T}$ac_header_compiler" >&6
+
+- fi
+-
+- # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+- echo "$as_me:$LINENO: checking for shmat" >&5
+-echo $ECHO_N "checking for shmat... $ECHO_C" >&6
+-if test "${ac_cv_func_shmat+set}" = set; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- cat >conftest.$ac_ext <<_ACEOF
++# Is the header present?
++echo "$as_me:$LINENO: checking $ac_header presence" >&5
++echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
++cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+-/* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char shmat (); below. */
+-#include <assert.h>
+-/* Override any gcc2 internal prototype to avoid an error. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char shmat ();
+-char (*f) ();
+-
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+-/* The GNU C library defines this for functions which it implements
+- to always fail with ENOSYS. Some functions are actually named
+- something starting with __ and the normal name is an alias. */
+-#if defined (__stub_shmat) || defined (__stub___shmat)
+-choke me
+-#else
+-f = shmat;
+-#endif
+-
+- ;
+- return 0;
+-}
++#include <$ac_header>
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
++ egrep -v '^ *\+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- ac_cv_func_shmat=yes
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_c_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++ ac_header_preproc=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-ac_cv_func_shmat=no
++ cat conftest.$ac_ext >&5
++ ac_header_preproc=no
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++rm -f conftest.err conftest.$ac_ext
++echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
++echo "${ECHO_T}$ac_header_preproc" >&6
++
++# So? What about this header?
++case $ac_header_compiler:$ac_header_preproc in
++ yes:no )
++ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
++echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
++ no:yes )
++ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
++echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
++ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
++echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
++esac
++echo "$as_me:$LINENO: checking for $ac_header" >&5
++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ eval "$as_ac_Header=$ac_header_preproc"
++fi
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
++
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_func_shmat" >&5
+-echo "${ECHO_T}$ac_cv_func_shmat" >&6
++if test `eval echo '${'$as_ac_Header'}'` = yes; then
++ cat >>confdefs.h <<_ACEOF
++#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
++_ACEOF
++
++fi
++
++done
+
+- if test $ac_cv_func_shmat = no; then
+- echo "$as_me:$LINENO: checking for shmat in -lipc" >&5
+-echo $ECHO_N "checking for shmat in -lipc... $ECHO_C" >&6
+-if test "${ac_cv_lib_ipc_shmat+set}" = set; then
++echo "$as_me:$LINENO: checking for working malloc" >&5
++echo $ECHO_N "checking for working malloc... $ECHO_C" >&6
++if test "${ac_cv_func_malloc_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+- ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lipc $LIBS"
+-cat >conftest.$ac_ext <<_ACEOF
++ if test "$cross_compiling" = yes; then
++ ac_cv_func_malloc_works=no
++else
++ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+-
+-/* Override any gcc2 internal prototype to avoid an error. */
+-#ifdef __cplusplus
+-extern "C"
++#if STDC_HEADERS || HAVE_STDLIB_H
++# include <stdlib.h>
++#else
++char *malloc ();
+ #endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char shmat ();
++
+ #ifdef F77_DUMMY_MAIN
+ # ifdef __cplusplus
+ extern "C"
+@@ -5231,68 +5656,55 @@
+ int
+ main ()
+ {
+-shmat ();
++exit (malloc (0) ? 0 : 1);
+ ;
+ return 0;
+ }
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
++rm -f conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_lib_ipc_shmat=yes
++ ac_cv_func_malloc_works=yes
+ else
+- echo "$as_me: failed program was:" >&5
++ echo "$as_me: program exited with status $ac_status" >&5
++echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_lib_ipc_shmat=no
++( exit $ac_status )
++ac_cv_func_malloc_works=no
+ fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+-LIBS=$ac_check_lib_save_LIBS
++rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_shmat" >&5
+-echo "${ECHO_T}$ac_cv_lib_ipc_shmat" >&6
+-if test $ac_cv_lib_ipc_shmat = yes; then
+- X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+ fi
++echo "$as_me:$LINENO: result: $ac_cv_func_malloc_works" >&5
++echo "${ECHO_T}$ac_cv_func_malloc_works" >&6
++if test $ac_cv_func_malloc_works = yes; then
+
+- fi
+- fi
++cat >>confdefs.h <<\_ACEOF
++#define HAVE_MALLOC 1
++_ACEOF
++
++fi
+
+- # Check for libraries that X11R6 Xt/Xaw programs need.
+- ac_save_LDFLAGS=$LDFLAGS
+- test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+- # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+- # check for ICE first), but we must link in the order -lSM -lICE or
+- # we get undefined symbols. So assume we have SM if we have ICE.
+- # These have to be linked with before -lX11, unlike the other
+- # libraries we check for below, so use a different variable.
+- # John Interrante, Karl Berry
+- echo "$as_me:$LINENO: checking for IceConnectionNumber in -lICE" >&5
+-echo $ECHO_N "checking for IceConnectionNumber in -lICE... $ECHO_C" >&6
+-if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then
++echo "$as_me:$LINENO: checking for working memcmp" >&5
++echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6
++if test "${ac_cv_func_memcmp_working+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+- ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lICE $X_EXTRA_LIBS $LIBS"
+-cat >conftest.$ac_ext <<_ACEOF
++ if test "$cross_compiling" = yes; then
++ ac_cv_func_memcmp_working=no
++else
++ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+
+-/* Override any gcc2 internal prototype to avoid an error. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char IceConnectionNumber ();
+ #ifdef F77_DUMMY_MAIN
+ # ifdef __cplusplus
+ extern "C"
+@@ -5302,76 +5714,79 @@
+ int
+ main ()
+ {
+-IceConnectionNumber ();
++
++ /* Some versions of memcmp are not 8-bit clean. */
++ char c0 = 0x40, c1 = 0x80, c2 = 0x81;
++ if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0)
++ exit (1);
++
++ /* The Next x86 OpenStep bug shows up only when comparing 16 bytes
++ or more and with at least one buffer not starting on a 4-byte boundary.
++ William Lewis provided this test program. */
++ {
++ char foo[21];
++ char bar[21];
++ int i;
++ for (i = 0; i < 4; i++)
++ {
++ char *a = foo + i;
++ char *b = bar + i;
++ strcpy (a, "--------01111111");
++ strcpy (b, "--------10000000");
++ if (memcmp (a, b, 16) >= 0)
++ exit (1);
++ }
++ exit (0);
++ }
++
+ ;
+ return 0;
+ }
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
++rm -f conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_lib_ICE_IceConnectionNumber=yes
++ ac_cv_func_memcmp_working=yes
+ else
+- echo "$as_me: failed program was:" >&5
++ echo "$as_me: program exited with status $ac_status" >&5
++echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_lib_ICE_IceConnectionNumber=no
+-fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+-LIBS=$ac_check_lib_save_LIBS
+-fi
+-echo "$as_me:$LINENO: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5
+-echo "${ECHO_T}$ac_cv_lib_ICE_IceConnectionNumber" >&6
+-if test $ac_cv_lib_ICE_IceConnectionNumber = yes; then
+- X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
++( exit $ac_status )
++ac_cv_func_memcmp_working=no
+ fi
+-
+- LDFLAGS=$ac_save_LDFLAGS
+-
++rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+-
+-if test x"$no_x" = x"yes"; then
+- { echo "$as_me:$LINENO: disabling X11 output devices" >&5
+-echo "$as_me: disabling X11 output devices" >&6;}
+- X11DEVS=''
+-else
+- X11DEVS='$(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev'
+ fi
++echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5
++echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6
++test $ac_cv_func_memcmp_working = no && LIBOBJS="$LIBOBJS memcmp.$ac_objext"
+
+-
+-
+-
+-
+-for ac_func in mkstemp
+-do
+-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+-echo "$as_me:$LINENO: checking for $ac_func" >&5
+-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+-if eval "test \"\${$as_ac_var+set}\" = set"; then
++echo "$as_me:$LINENO: checking return type of signal handlers" >&5
++echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
++if test "${ac_cv_type_signal+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+-/* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char $ac_func (); below. */
+-#include <assert.h>
+-/* Override any gcc2 internal prototype to avoid an error. */
++#include <sys/types.h>
++#include <signal.h>
++#ifdef signal
++# undef signal
++#endif
+ #ifdef __cplusplus
+-extern "C"
++extern "C" void (*signal (int, void (*)(int)))(int);
++#else
++void (*signal ()) ();
+ #endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char $ac_func ();
+-char (*f) ();
+
+ #ifdef F77_DUMMY_MAIN
+ # ifdef __cplusplus
+@@ -5382,56 +5797,50 @@
+ int
+ main ()
+ {
+-/* The GNU C library defines this for functions which it implements
+- to always fail with ENOSYS. Some functions are actually named
+- something starting with __ and the normal name is an alias. */
+-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+-choke me
+-#else
+-f = $ac_func;
+-#endif
+-
++int i;
+ ;
+ return 0;
+ }
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
++ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- eval "$as_ac_var=yes"
++ ac_cv_type_signal=void
+ else
+ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-eval "$as_ac_var=no"
+-fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++ac_cv_type_signal=int
+ fi
+-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+-if test `eval echo '${'$as_ac_var'}'` = yes; then
+- cat >>confdefs.h <<_ACEOF
+-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+-_ACEOF
+- HAVE_MKSTEMP=-DHAVE_MKSTEMP
++rm -f conftest.$ac_objext conftest.$ac_ext
+ fi
+-done
++echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
++echo "${ECHO_T}$ac_cv_type_signal" >&6
+
++cat >>confdefs.h <<_ACEOF
++#define RETSIGTYPE $ac_cv_type_signal
++_ACEOF
+
+
+-echo "$as_me:$LINENO: checking for pid_t" >&5
+-echo $ECHO_N "checking for pid_t... $ECHO_C" >&6
+-if test "${ac_cv_type_pid_t+set}" = set; then
++echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5
++echo $ECHO_N "checking whether lstat dereferences a symlink specified with a trailing slash... $ECHO_C" >&6
++if test "${ac_cv_func_lstat_dereferences_slashed_symlink+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
++ rm -f conftest.sym conftest.file
++echo >conftest.file
++if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then
++ if test "$cross_compiling" = yes; then
++ ac_cv_func_lstat_dereferences_slashed_symlink=no
++else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+@@ -5445,164 +5854,120 @@
+ int
+ main ()
+ {
+-if ((pid_t *) 0)
+- return 0;
+-if (sizeof (pid_t))
+- return 0;
++struct stat sbuf;
++ /* Linux will dereference the symlink and fail.
++ That is better in the sense that it means we will not
++ have to compile and use the lstat wrapper. */
++ exit (lstat ("conftest.sym/", &sbuf) ? 0 : 1);
+ ;
+ return 0;
+ }
+ _ACEOF
+-rm -f conftest.$ac_objext
+-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+- (eval $ac_compile) 2>&5
++rm -f conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest.$ac_objext'
++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_type_pid_t=yes
++ ac_cv_func_lstat_dereferences_slashed_symlink=yes
+ else
+- echo "$as_me: failed program was:" >&5
++ echo "$as_me: program exited with status $ac_status" >&5
++echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_cv_type_pid_t=no
++( exit $ac_status )
++ac_cv_func_lstat_dereferences_slashed_symlink=no
+ fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
+-echo "${ECHO_T}$ac_cv_type_pid_t" >&6
+-if test $ac_cv_type_pid_t = yes; then
+- :
+ else
++ # If the `ln -s' command failed, then we probably don't even
++ # have an lstat function.
++ ac_cv_func_lstat_dereferences_slashed_symlink=no
++fi
++rm -f conftest.sym conftest.file
++
++fi
++echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5
++echo "${ECHO_T}$ac_cv_func_lstat_dereferences_slashed_symlink" >&6
++
++test $ac_cv_func_lstat_dereferences_slashed_symlink = yes &&
+
+ cat >>confdefs.h <<_ACEOF
+-#define pid_t int
++#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
+ _ACEOF
+
+-fi
+-
+
++if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then
++ LIBOBJS="$LIBOBJS lstat.$ac_objext"
++fi
+
+-for ac_header in unistd.h vfork.h
+-do
+-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+-if eval "test \"\${$as_ac_Header+set}\" = set"; then
+- echo "$as_me:$LINENO: checking for $ac_header" >&5
+-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+-if eval "test \"\${$as_ac_Header+set}\" = set"; then
++echo "$as_me:$LINENO: checking whether stat accepts an empty string" >&5
++echo $ECHO_N "checking whether stat accepts an empty string... $ECHO_C" >&6
++if test "${ac_cv_func_stat_empty_string_bug+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+-fi
+-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+ else
+- # Is the header compilable?
+-echo "$as_me:$LINENO: checking $ac_header usability" >&5
+-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+-cat >conftest.$ac_ext <<_ACEOF
++ if test "$cross_compiling" = yes; then
++ ac_cv_func_stat_empty_string_bug=yes
++else
++ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+ $ac_includes_default
+-#include <$ac_header>
++#ifdef F77_DUMMY_MAIN
++# ifdef __cplusplus
++ extern "C"
++# endif
++ int F77_DUMMY_MAIN() { return 1; }
++#endif
++int
++main ()
++{
++struct stat sbuf;
++ exit (stat ("", &sbuf) ? 1 : 0);
++ ;
++ return 0;
++}
+ _ACEOF
+-rm -f conftest.$ac_objext
+-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+- (eval $ac_compile) 2>&5
++rm -f conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest.$ac_objext'
++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_header_compiler=yes
++ ac_cv_func_stat_empty_string_bug=yes
+ else
+- echo "$as_me: failed program was:" >&5
++ echo "$as_me: program exited with status $ac_status" >&5
++echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-ac_header_compiler=no
+-fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
+-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+-echo "${ECHO_T}$ac_header_compiler" >&6
+-
+-# Is the header present?
+-echo "$as_me:$LINENO: checking $ac_header presence" >&5
+-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+-cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-#include <$ac_header>
+-_ACEOF
+-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+- ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
+- rm -f conftest.er1
+- cat conftest.err >&5
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } >/dev/null; then
+- if test -s conftest.err; then
+- ac_cpp_err=$ac_c_preproc_warn_flag
+- else
+- ac_cpp_err=
+- fi
+-else
+- ac_cpp_err=yes
++( exit $ac_status )
++ac_cv_func_stat_empty_string_bug=no
+ fi
+-if test -z "$ac_cpp_err"; then
+- ac_header_preproc=yes
+-else
+- echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
+- ac_header_preproc=no
++rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+-rm -f conftest.err conftest.$ac_ext
+-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+-echo "${ECHO_T}$ac_header_preproc" >&6
+-
+-# So? What about this header?
+-case $ac_header_compiler:$ac_header_preproc in
+- yes:no )
+- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+- no:yes )
+- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+-esac
+-echo "$as_me:$LINENO: checking for $ac_header" >&5
+-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+-if eval "test \"\${$as_ac_Header+set}\" = set"; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- eval "$as_ac_Header=$ac_header_preproc"
+ fi
+-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
++echo "$as_me:$LINENO: result: $ac_cv_func_stat_empty_string_bug" >&5
++echo "${ECHO_T}$ac_cv_func_stat_empty_string_bug" >&6
++if test $ac_cv_func_stat_empty_string_bug = yes; then
++ LIBOBJS="$LIBOBJS stat.$ac_objext"
+
+-fi
+-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+- cat >>confdefs.h <<_ACEOF
+-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
++cat >>confdefs.h <<_ACEOF
++#define HAVE_STAT_EMPTY_STRING_BUG 1
+ _ACEOF
+
+ fi
+
+-done
+-
+-
+
+-for ac_func in fork vfork
++for ac_func in vprintf
+ do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ echo "$as_me:$LINENO: checking for $ac_func" >&5
+@@ -5674,974 +6039,1023 @@
+ #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+ _ACEOF
+
+-fi
+-done
+-
+-ac_cv_func_fork_works=$ac_cv_func_fork
+-if test "x$ac_cv_func_fork" = xyes; then
+- echo "$as_me:$LINENO: checking for working fork" >&5
+-echo $ECHO_N "checking for working fork... $ECHO_C" >&6
+-if test "${ac_cv_func_fork_works+set}" = set; then
++echo "$as_me:$LINENO: checking for _doprnt" >&5
++echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6
++if test "${ac_cv_func__doprnt+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+- if test "$cross_compiling" = yes; then
+- ac_cv_func_fork_works=cross
+-else
+ cat >conftest.$ac_ext <<_ACEOF
+-/* By Ruediger Kuhlmann. */
+- #include <sys/types.h>
+- #if HAVE_UNISTD_H
+- # include <unistd.h>
+- #endif
+- /* Some systems only have a dummy stub for fork() */
+- int main ()
+- {
+- if (fork() < 0)
+- exit (1);
+- exit (0);
+- }
++#line $LINENO "configure"
++#include "confdefs.h"
++/* System header to define __stub macros and hopefully few prototypes,
++ which can conflict with char _doprnt (); below. */
++#include <assert.h>
++/* Override any gcc2 internal prototype to avoid an error. */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char _doprnt ();
++char (*f) ();
++
++#ifdef F77_DUMMY_MAIN
++# ifdef __cplusplus
++ extern "C"
++# endif
++ int F77_DUMMY_MAIN() { return 1; }
++#endif
++int
++main ()
++{
++/* The GNU C library defines this for functions which it implements
++ to always fail with ENOSYS. Some functions are actually named
++ something starting with __ and the normal name is an alias. */
++#if defined (__stub__doprnt) || defined (__stub____doprnt)
++choke me
++#else
++f = _doprnt;
++#endif
++
++ ;
++ return 0;
++}
+ _ACEOF
+-rm -f conftest$ac_exeext
++rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_func_fork_works=yes
++ ac_cv_func__doprnt=yes
+ else
+- echo "$as_me: program exited with status $ac_status" >&5
+-echo "$as_me: failed program was:" >&5
++ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-( exit $ac_status )
+-ac_cv_func_fork_works=no
+-fi
+-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++ac_cv_func__doprnt=no
+ fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5
+-echo "${ECHO_T}$ac_cv_func_fork_works" >&6
++echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
++echo "${ECHO_T}$ac_cv_func__doprnt" >&6
++if test $ac_cv_func__doprnt = yes; then
++
++cat >>confdefs.h <<\_ACEOF
++#define HAVE_DOPRNT 1
++_ACEOF
+
+ fi
+-if test "x$ac_cv_func_fork_works" = xcross; then
+- case $host in
+- *-*-amigaos* | *-*-msdosdjgpp*)
+- # Override, as these systems have only a dummy fork() stub
+- ac_cv_func_fork_works=no
+- ;;
+- *)
+- ac_cv_func_fork_works=yes
+- ;;
+- esac
+- { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+-echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
++
+ fi
+-ac_cv_func_vfork_works=$ac_cv_func_vfork
+-if test "x$ac_cv_func_vfork" = xyes; then
+- echo "$as_me:$LINENO: checking for working vfork" >&5
+-echo $ECHO_N "checking for working vfork... $ECHO_C" >&6
+-if test "${ac_cv_func_vfork_works+set}" = set; then
++done
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++for ac_func in bzero dup2 floor gettimeofday memchr memmove memset mkdir mkfifo modf pow putenv rint setenv sqrt strchr strerror strrchr strspn strstr
++do
++as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
++echo "$as_me:$LINENO: checking for $ac_func" >&5
++echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
++if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+- if test "$cross_compiling" = yes; then
+- ac_cv_func_vfork_works=cross
+-else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+-/* Thanks to Paul Eggert for this test. */
+-#include <stdio.h>
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#if HAVE_UNISTD_H
+-# include <unistd.h>
+-#endif
+-#if HAVE_VFORK_H
+-# include <vfork.h>
+-#endif
+-/* On some sparc systems, changes by the child to local and incoming
+- argument registers are propagated back to the parent. The compiler
+- is told about this with #include <vfork.h>, but some compilers
+- (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a
+- static variable whose address is put into a register that is
+- clobbered by the vfork. */
+-static
++/* System header to define __stub macros and hopefully few prototypes,
++ which can conflict with char $ac_func (); below. */
++#include <assert.h>
++/* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+-sparc_address_test (int arg)
+-# else
+-sparc_address_test (arg) int arg;
++extern "C"
+ #endif
+-{
+- static pid_t child;
+- if (!child) {
+- child = vfork ();
+- if (child < 0) {
+- perror ("vfork");
+- _exit(2);
+- }
+- if (!child) {
+- arg = getpid();
+- write(-1, "", 0);
+- _exit (arg);
+- }
+- }
+-}
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char $ac_func ();
++char (*f) ();
+
++#ifdef F77_DUMMY_MAIN
++# ifdef __cplusplus
++ extern "C"
++# endif
++ int F77_DUMMY_MAIN() { return 1; }
++#endif
+ int
+ main ()
+ {
+- pid_t parent = getpid ();
+- pid_t child;
+-
+- sparc_address_test ();
+-
+- child = vfork ();
+-
+- if (child == 0) {
+- /* Here is another test for sparc vfork register problems. This
+- test uses lots of local variables, at least as many local
+- variables as main has allocated so far including compiler
+- temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
+- 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
+- reuse the register of parent for one of the local variables,
+- since it will think that parent can't possibly be used any more
+- in this routine. Assigning to the local variable will thus
+- munge parent in the parent process. */
+- pid_t
+- p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+- p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+- /* Convince the compiler that p..p7 are live; otherwise, it might
+- use the same hardware register for all 8 local variables. */
+- if (p != p1 || p != p2 || p != p3 || p != p4
+- || p != p5 || p != p6 || p != p7)
+- _exit(1);
+-
+- /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+- from child file descriptors. If the child closes a descriptor
+- before it execs or exits, this munges the parent's descriptor
+- as well. Test for this by closing stdout in the child. */
+- _exit(close(fileno(stdout)) != 0);
+- } else {
+- int status;
+- struct stat st;
+-
+- while (wait(&status) != child)
+- ;
+- exit(
+- /* Was there some problem with vforking? */
+- child < 0
+-
+- /* Did the child fail? (This shouldn't happen.) */
+- || status
+-
+- /* Did the vfork/compiler bug occur? */
+- || parent != getpid()
++/* The GNU C library defines this for functions which it implements
++ to always fail with ENOSYS. Some functions are actually named
++ something starting with __ and the normal name is an alias. */
++#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
++choke me
++#else
++f = $ac_func;
++#endif
+
+- /* Did the file descriptor bug occur? */
+- || fstat(fileno(stdout), &st) != 0
+- );
+- }
++ ;
++ return 0;
+ }
+ _ACEOF
+-rm -f conftest$ac_exeext
++rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+- ac_cv_func_vfork_works=yes
++ eval "$as_ac_var=yes"
+ else
+- echo "$as_me: program exited with status $ac_status" >&5
+-echo "$as_me: failed program was:" >&5
++ echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+-( exit $ac_status )
+-ac_cv_func_vfork_works=no
+-fi
+-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++eval "$as_ac_var=no"
+ fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5
+-echo "${ECHO_T}$ac_cv_func_vfork_works" >&6
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
++if test `eval echo '${'$as_ac_var'}'` = yes; then
++ cat >>confdefs.h <<_ACEOF
++#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
++_ACEOF
+
+-fi;
+-if test "x$ac_cv_func_fork_works" = xcross; then
+- ac_cv_func_vfork_works=ac_cv_func_vfork
+- { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+-echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
+ fi
++done
+
+-if test "x$ac_cv_func_vfork_works" = xyes; then
+
+-cat >>confdefs.h <<\_ACEOF
+-#define HAVE_WORKING_VFORK 1
+-_ACEOF
+
+-else
+
+-cat >>confdefs.h <<\_ACEOF
+-#define vfork fork
+-_ACEOF
+
+-fi
+-if test "x$ac_cv_func_fork_works" = xyes; then
++if test -d pstoraster; then
++ ac_config_files="$ac_config_files Makefile pstoraster/pstoraster"
++cat >confcache <<\_ACEOF
++# This file is a shell script that caches the results of configure
++# tests run on this system so they can be shared between configure
++# scripts and configure runs, see configure's option --config-cache.
++# It is not useful on other systems. If it contains results you don't
++# want to keep, you may remove or edit it.
++#
++# config.status only pays attention to the cache file if you give it
++# the --recheck option to rerun configure.
++#
++# `ac_cv_env_foo' variables (set or unset) will be overriden when
++# loading this file, other *unset* `ac_cv_foo' will be assigned the
++# following values.
+
+-cat >>confdefs.h <<\_ACEOF
+-#define HAVE_WORKING_FORK 1
+ _ACEOF
+
++# The following way of writing the cache mishandles newlines in values,
++# but we know of no workaround that is simple, portable, and efficient.
++# So, don't put newlines in cache variables' values.
++# Ultrix sh set writes to stderr and can't be redirected directly,
++# and sets the high bit in the cache file unless we assign to the vars.
++{
++ (set) 2>&1 |
++ case `(ac_space=' '; set | grep ac_space) 2>&1` in
++ *ac_space=\ *)
++ # `set' does not quote correctly, so add quotes (double-quote
++ # substitution turns \\\\ into \\, and sed turns \\ into \).
++ sed -n \
++ "s/'/'\\\\''/g;
++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
++ ;;
++ *)
++ # `set' quotes correctly as required by POSIX, so do not add quotes.
++ sed -n \
++ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
++ ;;
++ esac;
++} |
++ sed '
++ t clear
++ : clear
++ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
++ t end
++ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
++ : end' >>confcache
++if cmp -s $cache_file confcache; then :; else
++ if test -w $cache_file; then
++ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
++ cat confcache >$cache_file
++ else
++ echo "not updating unwritable cache $cache_file"
++ fi
+ fi
++rm -f confcache
+
+-if test $ac_cv_c_compiler_gnu = yes; then
+- echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
+-echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
+-if test "${ac_cv_prog_gcc_traditional+set}" = set; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- ac_pattern="Autoconf.*'x'"
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-#include <sgtty.h>
+-Autoconf TIOCGETP
+-_ACEOF
+-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+- egrep "$ac_pattern" >/dev/null 2>&1; then
+- ac_cv_prog_gcc_traditional=yes
+-else
+- ac_cv_prog_gcc_traditional=no
+-fi
+-rm -f conftest*
+-
++test "x$prefix" = xNONE && prefix=$ac_default_prefix
++# Let make expand exec_prefix.
++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+- if test $ac_cv_prog_gcc_traditional = no; then
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-#include <termio.h>
+-Autoconf TCGETA
+-_ACEOF
+-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+- egrep "$ac_pattern" >/dev/null 2>&1; then
+- ac_cv_prog_gcc_traditional=yes
++# VPATH may cause trouble with some makes, so we remove $(srcdir),
++# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
++# trailing colons and then remove the whole line if VPATH becomes empty
++# (actually we leave an empty line to preserve line numbers).
++if test "x$srcdir" = x.; then
++ ac_vpsub='/^[ ]*VPATH[ ]*=/{
++s/:*\$(srcdir):*/:/;
++s/:*\${srcdir}:*/:/;
++s/:*@srcdir@:*/:/;
++s/^\([^=]*=[ ]*\):*/\1/;
++s/:*$//;
++s/^[^=]*=[ ]*$//;
++}'
+ fi
+-rm -f conftest*
+
+- fi
+-fi
+-echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
+-echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
+- if test $ac_cv_prog_gcc_traditional = yes; then
+- CC="$CC -traditional"
+- fi
+-fi
++# Transform confdefs.h into DEFS.
++# Protect against shell expansion while executing Makefile rules.
++# Protect against Makefile macro expansion.
++#
++# If the first sed substitution is executed (which looks for macros that
++# take arguments), then we branch to the quote section. Otherwise,
++# look for a macro that doesn't take arguments.
++cat >confdef2opt.sed <<\_ACEOF
++t clear
++: clear
++s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
++t quote
++s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
++t quote
++d
++: quote
++s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
++s,\[,\\&,g
++s,\],\\&,g
++s,\$,$$,g
++p
++_ACEOF
++# We use echo to avoid assuming a particular line-breaking character.
++# The extra dot is to prevent the shell from consuming trailing
++# line-breaks from the sub-command output. A line-break within
++# single-quotes doesn't work because, if this script is created in a
++# platform that uses two characters for line-breaks (e.g., DOS), tr
++# would break.
++ac_LF_and_DOT=`echo; echo .`
++DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
++rm -f confdef2opt.sed
+
+
+-for ac_header in stdlib.h
+-do
+-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+-if eval "test \"\${$as_ac_Header+set}\" = set"; then
+- echo "$as_me:$LINENO: checking for $ac_header" >&5
+-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+-if eval "test \"\${$as_ac_Header+set}\" = set"; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-fi
+-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+-else
+- # Is the header compilable?
+-echo "$as_me:$LINENO: checking $ac_header usability" >&5
+-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+-cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-$ac_includes_default
+-#include <$ac_header>
+-_ACEOF
+-rm -f conftest.$ac_objext
+-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+- (eval $ac_compile) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest.$ac_objext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- ac_header_compiler=yes
+-else
+- echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-ac_header_compiler=no
+-fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
+-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+-echo "${ECHO_T}$ac_header_compiler" >&6
+
+-# Is the header present?
+-echo "$as_me:$LINENO: checking $ac_header presence" >&5
+-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+-cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-#include <$ac_header>
++: ${CONFIG_STATUS=./config.status}
++ac_clean_files_save=$ac_clean_files
++ac_clean_files="$ac_clean_files $CONFIG_STATUS"
++{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
++echo "$as_me: creating $CONFIG_STATUS" >&6;}
++cat >$CONFIG_STATUS <<_ACEOF
++#! $SHELL
++# Generated by $as_me.
++# Run this file to recreate the current configuration.
++# Compiler output produced by configure, useful for debugging
++# configure, is in config.log if it exists.
++
++debug=false
++SHELL=\${CONFIG_SHELL-$SHELL}
+ _ACEOF
+-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+- ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
+- rm -f conftest.er1
+- cat conftest.err >&5
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } >/dev/null; then
+- if test -s conftest.err; then
+- ac_cpp_err=$ac_c_preproc_warn_flag
+- else
+- ac_cpp_err=
+- fi
+-else
+- ac_cpp_err=yes
+-fi
+-if test -z "$ac_cpp_err"; then
+- ac_header_preproc=yes
+-else
+- echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
+- ac_header_preproc=no
+-fi
+-rm -f conftest.err conftest.$ac_ext
+-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+-echo "${ECHO_T}$ac_header_preproc" >&6
+
+-# So? What about this header?
+-case $ac_header_compiler:$ac_header_preproc in
+- yes:no )
+- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+- no:yes )
+- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+-esac
+-echo "$as_me:$LINENO: checking for $ac_header" >&5
+-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+-if eval "test \"\${$as_ac_Header+set}\" = set"; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- eval "$as_ac_Header=$ac_header_preproc"
+-fi
+-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
++cat >>$CONFIG_STATUS <<\_ACEOF
+
+-fi
+-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+- cat >>confdefs.h <<_ACEOF
+-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+-_ACEOF
++## --------------------- ##
++## M4sh Initialization. ##
++## --------------------- ##
+
++# Be Bourne compatible
++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
++ emulate sh
++ NULLCMD=:
++elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
++ set -o posix
+ fi
+
+-done
+-
+-echo "$as_me:$LINENO: checking for working malloc" >&5
+-echo $ECHO_N "checking for working malloc... $ECHO_C" >&6
+-if test "${ac_cv_func_malloc_works+set}" = set; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- if test "$cross_compiling" = yes; then
+- ac_cv_func_malloc_works=no
++# NLS nuisances.
++# Support unset when possible.
++if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
++ as_unset=unset
+ else
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-#if STDC_HEADERS || HAVE_STDLIB_H
+-# include <stdlib.h>
+-#else
+-char *malloc ();
+-#endif
++ as_unset=false
++fi
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+-exit (malloc (0) ? 0 : 1);
+- ;
+- return 0;
+-}
+-_ACEOF
+-rm -f conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- ac_cv_func_malloc_works=yes
+-else
+- echo "$as_me: program exited with status $ac_status" >&5
+-echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-( exit $ac_status )
+-ac_cv_func_malloc_works=no
+-fi
+-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+-fi
+-fi
+-echo "$as_me:$LINENO: result: $ac_cv_func_malloc_works" >&5
+-echo "${ECHO_T}$ac_cv_func_malloc_works" >&6
+-if test $ac_cv_func_malloc_works = yes; then
++(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
++ { $as_unset LANG || test "${LANG+set}" != set; } ||
++ { LANG=C; export LANG; }
++(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
++ { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
++ { LC_ALL=C; export LC_ALL; }
++(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
++ { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
++ { LC_TIME=C; export LC_TIME; }
++(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
++ { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
++ { LC_CTYPE=C; export LC_CTYPE; }
++(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
++ { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
++ { LANGUAGE=C; export LANGUAGE; }
++(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
++ { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
++ { LC_COLLATE=C; export LC_COLLATE; }
++(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
++ { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
++ { LC_NUMERIC=C; export LC_NUMERIC; }
++(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
++ { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
++ { LC_MESSAGES=C; export LC_MESSAGES; }
+
+-cat >>confdefs.h <<\_ACEOF
+-#define HAVE_MALLOC 1
+-_ACEOF
+
++# Name of the executable.
++as_me=`(basename "$0") 2>/dev/null ||
++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
++ X"$0" : 'X\(//\)$' \| \
++ X"$0" : 'X\(/\)$' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X/"$0" |
++ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
++ /^X\/\(\/\/\)$/{ s//\1/; q; }
++ /^X\/\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++
++# PATH needs CR, and LINENO needs CR and PATH.
++# Avoid depending upon Character Ranges.
++as_cr_letters='abcdefghijklmnopqrstuvwxyz'
++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
++as_cr_Letters=$as_cr_letters$as_cr_LETTERS
++as_cr_digits='0123456789'
++as_cr_alnum=$as_cr_Letters$as_cr_digits
++
++# The user is always right.
++if test "${PATH_SEPARATOR+set}" != set; then
++ echo "#! /bin/sh" >conftest.sh
++ echo "exit 0" >>conftest.sh
++ chmod +x conftest.sh
++ if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
++ PATH_SEPARATOR=';'
++ else
++ PATH_SEPARATOR=:
++ fi
++ rm -f conftest.sh
+ fi
+
+-echo "$as_me:$LINENO: checking for working memcmp" >&5
+-echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6
+-if test "${ac_cv_func_memcmp_working+set}" = set; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- if test "$cross_compiling" = yes; then
+- ac_cv_func_memcmp_working=no
+-else
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
++ as_lineno_1=$LINENO
++ as_lineno_2=$LINENO
++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
++ test "x$as_lineno_1" != "x$as_lineno_2" &&
++ test "x$as_lineno_3" = "x$as_lineno_2" || {
++ # Find who we are. Look in the path if we contain no path at all
++ # relative or not.
++ case $0 in
++ *[\\/]* ) as_myself=$0 ;;
++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
++done
+
+- /* Some versions of memcmp are not 8-bit clean. */
+- char c0 = 0x40, c1 = 0x80, c2 = 0x81;
+- if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0)
+- exit (1);
++ ;;
++ esac
++ # We did not find ourselves, most probably we were run as `sh COMMAND'
++ # in which case we are not to be found in the path.
++ if test "x$as_myself" = x; then
++ as_myself=$0
++ fi
++ if test ! -f "$as_myself"; then
++ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
++echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
++ { (exit 1); exit 1; }; }
++ fi
++ case $CONFIG_SHELL in
++ '')
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for as_base in sh bash ksh sh5; do
++ case $as_dir in
++ /*)
++ if ("$as_dir/$as_base" -c '
++ as_lineno_1=$LINENO
++ as_lineno_2=$LINENO
++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
++ test "x$as_lineno_1" != "x$as_lineno_2" &&
++ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
++ CONFIG_SHELL=$as_dir/$as_base
++ export CONFIG_SHELL
++ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
++ fi;;
++ esac
++ done
++done
++;;
++ esac
+
+- /* The Next x86 OpenStep bug shows up only when comparing 16 bytes
+- or more and with at least one buffer not starting on a 4-byte boundary.
+- William Lewis provided this test program. */
+- {
+- char foo[21];
+- char bar[21];
+- int i;
+- for (i = 0; i < 4; i++)
+- {
+- char *a = foo + i;
+- char *b = bar + i;
+- strcpy (a, "--------01111111");
+- strcpy (b, "--------10000000");
+- if (memcmp (a, b, 16) >= 0)
+- exit (1);
+- }
+- exit (0);
+- }
++ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
++ # uniformly replaced by the line number. The first 'sed' inserts a
++ # line-number line before each line; the second 'sed' does the real
++ # work. The second script uses 'N' to pair each line-number line
++ # with the numbered line, and appends trailing '-' during
++ # substitution so that $LINENO is not a special case at line end.
++ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
++ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
++ sed '=' <$as_myself |
++ sed '
++ N
++ s,$,-,
++ : loop
++ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
++ t loop
++ s,-$,,
++ s,^['$as_cr_digits']*\n,,
++ ' >$as_me.lineno &&
++ chmod +x $as_me.lineno ||
++ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
++echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
++ { (exit 1); exit 1; }; }
+
+- ;
+- return 0;
++ # Don't try to exec as it changes $[0], causing all sort of problems
++ # (the dirname of $[0] is not the place where we might find the
++ # original and so on. Autoconf is especially sensible to this).
++ . ./$as_me.lineno
++ # Exit status is that of the last command.
++ exit
+ }
+-_ACEOF
+-rm -f conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- ac_cv_func_memcmp_working=yes
++
++
++case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
++ *c*,-n*) ECHO_N= ECHO_C='
++' ECHO_T=' ' ;;
++ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
++ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
++esac
++
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
+ else
+- echo "$as_me: program exited with status $ac_status" >&5
+-echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-( exit $ac_status )
+-ac_cv_func_memcmp_working=no
+-fi
+-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+-fi
++ as_expr=false
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5
+-echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6
+-test $ac_cv_func_memcmp_working = no && LIBOBJS="$LIBOBJS memcmp.$ac_objext"
+-
+-echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+-echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+-if test "${ac_cv_type_signal+set}" = set; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-#include <sys/types.h>
+-#include <signal.h>
+-#ifdef signal
+-# undef signal
+-#endif
+-#ifdef __cplusplus
+-extern "C" void (*signal (int, void (*)(int)))(int);
+-#else
+-void (*signal ()) ();
+-#endif
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+-int i;
+- ;
+- return 0;
+-}
+-_ACEOF
+-rm -f conftest.$ac_objext
+-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+- (eval $ac_compile) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest.$ac_objext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- ac_cv_type_signal=void
++rm -f conf$$ conf$$.exe conf$$.file
++echo >conf$$.file
++if ln -s conf$$.file conf$$ 2>/dev/null; then
++ # We could just check for DJGPP; but this test a) works b) is more generic
++ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
++ if test -f conf$$.exe; then
++ # Don't use ln at all; we don't have any links
++ as_ln_s='cp -p'
++ else
++ as_ln_s='ln -s'
++ fi
++elif ln conf$$.file conf$$ 2>/dev/null; then
++ as_ln_s=ln
+ else
+- echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-ac_cv_type_signal=int
+-fi
+-rm -f conftest.$ac_objext conftest.$ac_ext
++ as_ln_s='cp -p'
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+-echo "${ECHO_T}$ac_cv_type_signal" >&6
++rm -f conf$$ conf$$.exe conf$$.file
+
+-cat >>confdefs.h <<_ACEOF
+-#define RETSIGTYPE $ac_cv_type_signal
+-_ACEOF
++as_executable_p="test -f"
+
++# Sed expression to map a string onto a valid CPP name.
++as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+-echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5
+-echo $ECHO_N "checking whether lstat dereferences a symlink specified with a trailing slash... $ECHO_C" >&6
+-if test "${ac_cv_func_lstat_dereferences_slashed_symlink+set}" = set; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- rm -f conftest.sym conftest.file
+-echo >conftest.file
+-if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then
+- if test "$cross_compiling" = yes; then
+- ac_cv_func_lstat_dereferences_slashed_symlink=no
+-else
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-$ac_includes_default
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
++# Sed expression to map a string onto a valid variable name.
++as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
++
++
++# IFS
++# We need space, tab and new line, in precisely that order.
++as_nl='
++'
++IFS=" $as_nl"
++
++# CDPATH.
++$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
++
++exec 6>&1
++
++# Open the log real soon, to keep \$[0] and so on meaningful, and to
++# report actual input values of CONFIG_FILES etc. instead of their
++# values after options handling. Logging --version etc. is OK.
++exec 5>>config.log
+ {
+-struct stat sbuf;
+- /* Linux will dereference the symlink and fail.
+- That is better in the sense that it means we will not
+- have to compile and use the lstat wrapper. */
+- exit (lstat ("conftest.sym/", &sbuf) ? 0 : 1);
+- ;
+- return 0;
+-}
+-_ACEOF
+-rm -f conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- ac_cv_func_lstat_dereferences_slashed_symlink=yes
+-else
+- echo "$as_me: program exited with status $ac_status" >&5
+-echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-( exit $ac_status )
+-ac_cv_func_lstat_dereferences_slashed_symlink=no
+-fi
+-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+-fi
+-else
+- # If the `ln -s' command failed, then we probably don't even
+- # have an lstat function.
+- ac_cv_func_lstat_dereferences_slashed_symlink=no
+-fi
+-rm -f conftest.sym conftest.file
++ echo
++ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
++## Running $as_me. ##
++_ASBOX
++} >&5
++cat >&5 <<_CSEOF
+
+-fi
+-echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5
+-echo "${ECHO_T}$ac_cv_func_lstat_dereferences_slashed_symlink" >&6
++This file was extended by $as_me, which was
++generated by GNU Autoconf 2.53. Invocation command line was
+
+-test $ac_cv_func_lstat_dereferences_slashed_symlink = yes &&
++ CONFIG_FILES = $CONFIG_FILES
++ CONFIG_HEADERS = $CONFIG_HEADERS
++ CONFIG_LINKS = $CONFIG_LINKS
++ CONFIG_COMMANDS = $CONFIG_COMMANDS
++ $ $0 $@
+
+-cat >>confdefs.h <<_ACEOF
+-#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
++_CSEOF
++echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
++echo >&5
+ _ACEOF
+
+-
+-if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then
+- LIBOBJS="$LIBOBJS lstat.$ac_objext"
++# Files that config.status was made for.
++if test -n "$ac_config_files"; then
++ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+ fi
+
+-echo "$as_me:$LINENO: checking whether stat accepts an empty string" >&5
+-echo $ECHO_N "checking whether stat accepts an empty string... $ECHO_C" >&6
+-if test "${ac_cv_func_stat_empty_string_bug+set}" = set; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- if test "$cross_compiling" = yes; then
+- ac_cv_func_stat_empty_string_bug=yes
+-else
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-$ac_includes_default
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+-struct stat sbuf;
+- exit (stat ("", &sbuf) ? 1 : 0);
+- ;
+- return 0;
+-}
+-_ACEOF
+-rm -f conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- ac_cv_func_stat_empty_string_bug=yes
+-else
+- echo "$as_me: program exited with status $ac_status" >&5
+-echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-( exit $ac_status )
+-ac_cv_func_stat_empty_string_bug=no
++if test -n "$ac_config_headers"; then
++ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+ fi
+-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++
++if test -n "$ac_config_links"; then
++ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+ fi
++
++if test -n "$ac_config_commands"; then
++ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+ fi
+-echo "$as_me:$LINENO: result: $ac_cv_func_stat_empty_string_bug" >&5
+-echo "${ECHO_T}$ac_cv_func_stat_empty_string_bug" >&6
+-if test $ac_cv_func_stat_empty_string_bug = yes; then
+- LIBOBJS="$LIBOBJS stat.$ac_objext"
+
+-cat >>confdefs.h <<_ACEOF
+-#define HAVE_STAT_EMPTY_STRING_BUG 1
+-_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
+
+-fi
++ac_cs_usage="\
++\`$as_me' instantiates files from templates according to the
++current configuration.
+
++Usage: $0 [OPTIONS] [FILE]...
+
+-for ac_func in vprintf
+-do
+-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+-echo "$as_me:$LINENO: checking for $ac_func" >&5
+-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+-if eval "test \"\${$as_ac_var+set}\" = set"; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-/* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char $ac_func (); below. */
+-#include <assert.h>
+-/* Override any gcc2 internal prototype to avoid an error. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char $ac_func ();
+-char (*f) ();
++ -h, --help print this help, then exit
++ -V, --version print version number, then exit
++ -d, --debug don't remove temporary files
++ --recheck update $as_me by reconfiguring in the same conditions
++ --file=FILE[:TEMPLATE]
++ instantiate the configuration file FILE
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+-/* The GNU C library defines this for functions which it implements
+- to always fail with ENOSYS. Some functions are actually named
+- something starting with __ and the normal name is an alias. */
+-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+-choke me
+-#else
+-f = $ac_func;
+-#endif
++Configuration files:
++$config_files
+
+- ;
+- return 0;
+-}
++Report bugs to <bug-autoconf@gnu.org>."
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- eval "$as_ac_var=yes"
+-else
+- echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-eval "$as_ac_var=no"
+-fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+-fi
+-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+-if test `eval echo '${'$as_ac_var'}'` = yes; then
+- cat >>confdefs.h <<_ACEOF
+-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
++
++cat >>$CONFIG_STATUS <<_ACEOF
++ac_cs_version="\\
++config.status
++configured by $0, generated by GNU Autoconf 2.53,
++ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
++
++Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
++Free Software Foundation, Inc.
++This config.status script is free software; the Free Software Foundation
++gives unlimited permission to copy, distribute and modify it."
++srcdir=$srcdir
+ _ACEOF
+
+-echo "$as_me:$LINENO: checking for _doprnt" >&5
+-echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6
+-if test "${ac_cv_func__doprnt+set}" = set; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-/* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char _doprnt (); below. */
+-#include <assert.h>
+-/* Override any gcc2 internal prototype to avoid an error. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char _doprnt ();
+-char (*f) ();
++cat >>$CONFIG_STATUS <<\_ACEOF
++# If no file are specified by the user, then we need to provide default
++# value. By we need to know if files were specified by the user.
++ac_need_defaults=:
++while test $# != 0
++do
++ case $1 in
++ --*=*)
++ ac_option=`expr "x$1" : 'x\([^=]*\)='`
++ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
++ shift
++ set dummy "$ac_option" "$ac_optarg" ${1+"$@"}
++ shift
++ ;;
++ -*);;
++ *) # This is not an option, so the user has probably given explicit
++ # arguments.
++ ac_need_defaults=false;;
++ esac
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
++ case $1 in
++ # Handling of the options.
++_ACEOF
++cat >>$CONFIG_STATUS <<_ACEOF
++ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
++ echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion"
++ exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;;
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
++ --version | --vers* | -V )
++ echo "$ac_cs_version"; exit 0 ;;
++ --he | --h)
++ # Conflict between --help and --header
++ { { echo "$as_me:$LINENO: error: ambiguous option: $1
++Try \`$0 --help' for more information." >&5
++echo "$as_me: error: ambiguous option: $1
++Try \`$0 --help' for more information." >&2;}
++ { (exit 1); exit 1; }; };;
++ --help | --hel | -h )
++ echo "$ac_cs_usage"; exit 0 ;;
++ --debug | --d* | -d )
++ debug=: ;;
++ --file | --fil | --fi | --f )
++ shift
++ CONFIG_FILES="$CONFIG_FILES $1"
++ ac_need_defaults=false;;
++ --header | --heade | --head | --hea )
++ shift
++ CONFIG_HEADERS="$CONFIG_HEADERS $1"
++ ac_need_defaults=false;;
++
++ # This is an error.
++ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
++Try \`$0 --help' for more information." >&5
++echo "$as_me: error: unrecognized option: $1
++Try \`$0 --help' for more information." >&2;}
++ { (exit 1); exit 1; }; } ;;
++
++ *) ac_config_targets="$ac_config_targets $1" ;;
++
++ esac
++ shift
++done
++
++_ACEOF
++
++
++
++
++
++cat >>$CONFIG_STATUS <<\_ACEOF
++for ac_config_target in $ac_config_targets
++do
++ case "$ac_config_target" in
++ # Handling of arguments.
++ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
++ "pstoraster/pstoraster" ) CONFIG_FILES="$CONFIG_FILES pstoraster/pstoraster" ;;
++ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
++echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
++ { (exit 1); exit 1; }; };;
++ esac
++done
++
++# If the user did not use the arguments to specify the items to instantiate,
++# then the envvar interface is used. Set only those that are not.
++# We use the long form for the default assignment because of an extremely
++# bizarre bug on SunOS 4.1.3.
++if $ac_need_defaults; then
++ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
++fi
++
++# Create a temporary directory, and hook for its removal unless debugging.
++$debug ||
+ {
+-/* The GNU C library defines this for functions which it implements
+- to always fail with ENOSYS. Some functions are actually named
+- something starting with __ and the normal name is an alias. */
+-#if defined (__stub__doprnt) || defined (__stub____doprnt)
+-choke me
+-#else
+-f = _doprnt;
+-#endif
++ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
++ trap '{ (exit 1); exit 1; }' 1 2 13 15
++}
+
+- ;
+- return 0;
++# Create a (secure) tmp directory for tmp files.
++: ${TMPDIR=/tmp}
++{
++ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
++ test -n "$tmp" && test -d "$tmp"
++} ||
++{
++ tmp=$TMPDIR/cs$$-$RANDOM
++ (umask 077 && mkdir $tmp)
++} ||
++{
++ echo "$me: cannot create a temporary directory in $TMPDIR" >&2
++ { (exit 1); exit 1; }
+ }
++
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- ac_cv_func__doprnt=yes
+-else
+- echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-ac_cv_func__doprnt=no
+-fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+-fi
+-echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
+-echo "${ECHO_T}$ac_cv_func__doprnt" >&6
+-if test $ac_cv_func__doprnt = yes; then
+
+-cat >>confdefs.h <<\_ACEOF
+-#define HAVE_DOPRNT 1
++cat >>$CONFIG_STATUS <<_ACEOF
++
++#
++# CONFIG_FILES section.
++#
++
++# No need to generate the scripts if there are no CONFIG_FILES.
++# This happens for instance when ./config.status config.h
++if test -n "\$CONFIG_FILES"; then
++ # Protect against being on the right side of a sed subst in config.status.
++ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
++ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
++s,@SHELL@,$SHELL,;t t
++s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
++s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
++s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
++s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
++s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
++s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
++s,@exec_prefix@,$exec_prefix,;t t
++s,@prefix@,$prefix,;t t
++s,@program_transform_name@,$program_transform_name,;t t
++s,@bindir@,$bindir,;t t
++s,@sbindir@,$sbindir,;t t
++s,@libexecdir@,$libexecdir,;t t
++s,@datadir@,$datadir,;t t
++s,@sysconfdir@,$sysconfdir,;t t
++s,@sharedstatedir@,$sharedstatedir,;t t
++s,@localstatedir@,$localstatedir,;t t
++s,@libdir@,$libdir,;t t
++s,@includedir@,$includedir,;t t
++s,@oldincludedir@,$oldincludedir,;t t
++s,@infodir@,$infodir,;t t
++s,@mandir@,$mandir,;t t
++s,@build_alias@,$build_alias,;t t
++s,@host_alias@,$host_alias,;t t
++s,@target_alias@,$target_alias,;t t
++s,@DEFS@,$DEFS,;t t
++s,@ECHO_C@,$ECHO_C,;t t
++s,@ECHO_N@,$ECHO_N,;t t
++s,@ECHO_T@,$ECHO_T,;t t
++s,@LIBS@,$LIBS,;t t
++s,@CC@,$CC,;t t
++s,@CFLAGS@,$CFLAGS,;t t
++s,@LDFLAGS@,$LDFLAGS,;t t
++s,@CPPFLAGS@,$CPPFLAGS,;t t
++s,@ac_ct_CC@,$ac_ct_CC,;t t
++s,@EXEEXT@,$EXEEXT,;t t
++s,@OBJEXT@,$OBJEXT,;t t
++s,@CPP@,$CPP,;t t
++s,@RANLIB@,$RANLIB,;t t
++s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
++s,@LIBOBJS@,$LIBOBJS,;t t
++s,@SHARE_LIBJPEG@,$SHARE_LIBJPEG,;t t
++s,@LIBJPEGDIR@,$LIBJPEGDIR,;t t
++s,@SHARE_ZLIB@,$SHARE_ZLIB,;t t
++s,@ZLIBDIR@,$ZLIBDIR,;t t
++s,@SHARE_LIBPNG@,$SHARE_LIBPNG,;t t
++s,@LIBPNGDIR@,$LIBPNGDIR,;t t
++s,@PNGDEVS@,$PNGDEVS,;t t
++s,@GS@,$GS,;t t
++s,@COMPILE_INITS@,$COMPILE_INITS,;t t
++s,@PRINTERS@,$PRINTERS,;t t
++s,@FILES@,$FILES,;t t
++s,@fontpath@,$fontpath,;t t
++s,@CUPSCONFIG@,$CUPSCONFIG,;t t
++s,@CUPSDEV@,$CUPSDEV,;t t
++s,@CUPSINCLUDE@,$CUPSINCLUDE,;t t
++s,@cups_serverroot@,$cups_serverroot,;t t
++s,@cups_serverbin@,$cups_serverbin,;t t
++s,@IJSDIR@,$IJSDIR,;t t
++s,@IJSDEVS@,$IJSDEVS,;t t
++s,@STPLIB@,$STPLIB,;t t
++s,@STPDEVS@,$STPDEVS,;t t
++s,@XLDFLAGS@,$XLDFLAGS,;t t
++s,@X_CFLAGS@,$X_CFLAGS,;t t
++s,@X_LIBS@,$X_LIBS,;t t
++s,@X_DEVS@,$X_DEVS,;t t
++s,@HAVE_MKSTEMP@,$HAVE_MKSTEMP,;t t
++s,@GCFLAGS@,$GCFLAGS,;t t
++CEOF
++
++_ACEOF
++
++ cat >>$CONFIG_STATUS <<\_ACEOF
++ # Split the substitutions into bite-sized pieces for seds with
++ # small command number limits, like on Digital OSF/1 and HP-UX.
++ ac_max_sed_lines=48
++ ac_sed_frag=1 # Number of current file.
++ ac_beg=1 # First line for current file.
++ ac_end=$ac_max_sed_lines # Line after last line for current file.
++ ac_more_lines=:
++ ac_sed_cmds=
++ while $ac_more_lines; do
++ if test $ac_beg -gt 1; then
++ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
++ else
++ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
++ fi
++ if test ! -s $tmp/subs.frag; then
++ ac_more_lines=false
++ else
++ # The purpose of the label and of the branching condition is to
++ # speed up the sed processing (if there are no `@' at all, there
++ # is no need to browse any of the substitutions).
++ # These are the two extra sed commands mentioned above.
++ (echo ':t
++ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
++ if test -z "$ac_sed_cmds"; then
++ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
++ else
++ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
++ fi
++ ac_sed_frag=`expr $ac_sed_frag + 1`
++ ac_beg=$ac_end
++ ac_end=`expr $ac_end + $ac_max_sed_lines`
++ fi
++ done
++ if test -z "$ac_sed_cmds"; then
++ ac_sed_cmds=cat
++ fi
++fi # test -n "$CONFIG_FILES"
++
+ _ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
++for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
++ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
++ case $ac_file in
++ - | *:- | *:-:* ) # input from stdin
++ cat >$tmp/stdin
++ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
++ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
++ * ) ac_file_in=$ac_file.in ;;
++ esac
+
+-fi
+-
+-fi
+-done
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
++ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
++ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
++$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$ac_file" : 'X\(//\)[^/]' \| \
++ X"$ac_file" : 'X\(//\)$' \| \
++ X"$ac_file" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$ac_file" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ { case "$ac_dir" in
++ [\\/]* | ?:[\\/]* ) as_incr_dir=;;
++ *) as_incr_dir=.;;
++esac
++as_dummy="$ac_dir"
++for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
++ case $as_mkdir_dir in
++ # Skip DOS drivespec
++ ?:) as_incr_dir=$as_mkdir_dir ;;
++ *)
++ as_incr_dir=$as_incr_dir/$as_mkdir_dir
++ test -d "$as_incr_dir" ||
++ mkdir "$as_incr_dir" ||
++ { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
++echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
++ { (exit 1); exit 1; }; }
++ ;;
++ esac
++done; }
+
++ ac_builddir=.
+
++if test "$ac_dir" != .; then
++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
++ # A "../" for each directory in $ac_dir_suffix.
++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
++else
++ ac_dir_suffix= ac_top_builddir=
++fi
+
++case $srcdir in
++ .) # No --srcdir option. We are building in place.
++ ac_srcdir=.
++ if test -z "$ac_top_builddir"; then
++ ac_top_srcdir=.
++ else
++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
++ fi ;;
++ [\\/]* | ?:[\\/]* ) # Absolute path.
++ ac_srcdir=$srcdir$ac_dir_suffix;
++ ac_top_srcdir=$srcdir ;;
++ *) # Relative path.
++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
++ ac_top_srcdir=$ac_top_builddir$srcdir ;;
++esac
++# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
++# absolute.
++ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
++ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
++ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+-for ac_func in bzero dup2 floor gettimeofday memchr memmove memset mkdir mkfifo modf pow putenv rint setenv sqrt strchr strerror strrchr strspn strstr
+-do
+-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+-echo "$as_me:$LINENO: checking for $ac_func" >&5
+-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+-if eval "test \"\${$as_ac_var+set}\" = set"; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- cat >conftest.$ac_ext <<_ACEOF
+-#line $LINENO "configure"
+-#include "confdefs.h"
+-/* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char $ac_func (); below. */
+-#include <assert.h>
+-/* Override any gcc2 internal prototype to avoid an error. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-/* We use char because int might match the return type of a gcc2
+- builtin and then its argument prototype would still apply. */
+-char $ac_func ();
+-char (*f) ();
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+-/* The GNU C library defines this for functions which it implements
+- to always fail with ENOSYS. Some functions are actually named
+- something starting with __ and the normal name is an alias. */
+-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+-choke me
+-#else
+-f = $ac_func;
+-#endif
++ if test x"$ac_file" != x-; then
++ { echo "$as_me:$LINENO: creating $ac_file" >&5
++echo "$as_me: creating $ac_file" >&6;}
++ rm -f "$ac_file"
++ fi
++ # Let's still pretend it is `configure' which instantiates (i.e., don't
++ # use $as_me), people would be surprised to read:
++ # /* config.h. Generated by config.status. */
++ if test x"$ac_file" = x-; then
++ configure_input=
++ else
++ configure_input="$ac_file. "
++ fi
++ configure_input=$configure_input"Generated from `echo $ac_file_in |
++ sed 's,.*/,,'` by configure."
+
+- ;
+- return 0;
+-}
++ # First look for the input files in the build tree, otherwise in the
++ # src tree.
++ ac_file_inputs=`IFS=:
++ for f in $ac_file_in; do
++ case $f in
++ -) echo $tmp/stdin ;;
++ [\\/$]*)
++ # Absolute (can't be DOS-style, as IFS=:)
++ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
++echo "$as_me: error: cannot find input file: $f" >&2;}
++ { (exit 1); exit 1; }; }
++ echo $f;;
++ *) # Relative
++ if test -f "$f"; then
++ # Build tree
++ echo $f
++ elif test -f "$srcdir/$f"; then
++ # Source tree
++ echo $srcdir/$f
++ else
++ # /dev/null tree
++ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
++echo "$as_me: error: cannot find input file: $f" >&2;}
++ { (exit 1); exit 1; }; }
++ fi;;
++ esac
++ done` || { (exit 1); exit 1; }
+ _ACEOF
+-rm -f conftest.$ac_objext conftest$ac_exeext
+-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+- (eval $ac_link) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } &&
+- { ac_try='test -s conftest$ac_exeext'
+- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+- (eval $ac_try) 2>&5
+- ac_status=$?
+- echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); }; }; then
+- eval "$as_ac_var=yes"
+-else
+- echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-eval "$as_ac_var=no"
+-fi
+-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+-fi
+-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+-if test `eval echo '${'$as_ac_var'}'` = yes; then
+- cat >>confdefs.h <<_ACEOF
+-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
++cat >>$CONFIG_STATUS <<_ACEOF
++ sed "$ac_vpsub
++$extrasub
+ _ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
++:t
++/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
++s,@configure_input@,$configure_input,;t t
++s,@srcdir@,$ac_srcdir,;t t
++s,@abs_srcdir@,$ac_abs_srcdir,;t t
++s,@top_srcdir@,$ac_top_srcdir,;t t
++s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
++s,@builddir@,$ac_builddir,;t t
++s,@abs_builddir@,$ac_abs_builddir,;t t
++s,@top_builddir@,$ac_top_builddir,;t t
++s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
++" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
++ rm -f $tmp/stdin
++ if test x"$ac_file" != x-; then
++ mv $tmp/out $ac_file
++ else
++ cat $tmp/out
++ rm -f $tmp/out
++ fi
+
+-fi
+ done
++_ACEOF
++
++cat >>$CONFIG_STATUS <<\_ACEOF
+
++{ (exit 0); exit 0; }
++_ACEOF
++chmod +x $CONFIG_STATUS
++ac_clean_files=$ac_clean_files_save
+
+
++# configure is writing to config.log, and then calls config.status.
++# config.status does its own redirection, appending to config.log.
++# Unfortunately, on DOS this fails, as config.log is still kept open
++# by configure, so config.status won't be able to write to it; its
++# output is simply discarded. So we exec the FD to /dev/null,
++# effectively closing config.log, so it can be properly (re)opened and
++# appended to by config.status. When coming back to configure, we
++# need to make the FD available again.
++if test "$no_create" != yes; then
++ ac_cs_success=:
++ exec 5>/dev/null
++ $SHELL $CONFIG_STATUS || ac_cs_success=false
++ exec 5>>config.log
++ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
++ # would make configure fail if this is the last instruction.
++ $ac_cs_success || { (exit 1); exit 1; }
++fi
+
+-ac_config_files="$ac_config_files Makefile"
++else
++ ac_config_files="$ac_config_files Makefile"
+ cat >confcache <<\_ACEOF
+ # This file is a shell script that caches the results of configure
+ # tests run on this system so they can be shared between configure
+@@ -7139,6 +7553,8 @@
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
++ "pstoraster/pstoraster" ) CONFIG_FILES="$CONFIG_FILES pstoraster/pstoraster" ;;
++ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+ echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+@@ -7237,15 +7653,24 @@
+ s,@SHARE_LIBPNG@,$SHARE_LIBPNG,;t t
+ s,@LIBPNGDIR@,$LIBPNGDIR,;t t
+ s,@PNGDEVS@,$PNGDEVS,;t t
++s,@GS@,$GS,;t t
++s,@COMPILE_INITS@,$COMPILE_INITS,;t t
++s,@PRINTERS@,$PRINTERS,;t t
++s,@FILES@,$FILES,;t t
++s,@fontpath@,$fontpath,;t t
++s,@CUPSCONFIG@,$CUPSCONFIG,;t t
++s,@CUPSDEV@,$CUPSDEV,;t t
++s,@CUPSINCLUDE@,$CUPSINCLUDE,;t t
++s,@cups_serverroot@,$cups_serverroot,;t t
++s,@cups_serverbin@,$cups_serverbin,;t t
+ s,@IJSDIR@,$IJSDIR,;t t
+ s,@IJSDEVS@,$IJSDEVS,;t t
+ s,@STPLIB@,$STPLIB,;t t
+ s,@STPDEVS@,$STPDEVS,;t t
++s,@XLDFLAGS@,$XLDFLAGS,;t t
+ s,@X_CFLAGS@,$X_CFLAGS,;t t
+-s,@X_PRE_LIBS@,$X_PRE_LIBS,;t t
+ s,@X_LIBS@,$X_LIBS,;t t
+-s,@X_EXTRA_LIBS@,$X_EXTRA_LIBS,;t t
+-s,@X11DEVS@,$X11DEVS,;t t
++s,@X_DEVS@,$X_DEVS,;t t
+ s,@HAVE_MKSTEMP@,$HAVE_MKSTEMP,;t t
+ s,@GCFLAGS@,$GCFLAGS,;t t
+ CEOF
+@@ -7470,3 +7895,4 @@
+ $ac_cs_success || { (exit 1); exit 1; }
+ fi
+
++fi
diff --git a/pstoraster/pstoraster b/pstoraster/pstoraster
new file mode 100755
index 000000000..0ea8c8c04
--- /dev/null
+++ b/pstoraster/pstoraster
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# "$Id: pstoraster 2352 2002-04-23 17:29:00Z mike $"
+#
+# CUPS filter script for Ghostscript.
+#
+# Copyright 2001-2002 by Easy Software Products.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+# Installation directories...
+prefix=/usr/local
+exec_prefix=${prefix}
+bindir=${exec_prefix}/bin
+
+# Set the library/font path...
+GS_FONTPATH="$CUPS_FONTPATH"
+export GS_FONTPATH
+
+# Options we use with Ghostscript...
+gsopts="-dQUIET -dDEBUG -dPARANOIDSAFER -dNOPAUSE -dBATCH "
+gsopts="$gsopts -dNOMEDIAATTRS -sDEVICE=cups -sstdout=%stderr"
+
+# See if we have a profile=n,n,n,n,n,n,n,n,n,n,n option...
+profile=""
+for option in $5; do
+ case $option in
+ profile=*)
+ profile="-scupsProfile=`echo $option | awk -F= '{print $2}'`"
+ ;;
+ esac
+done
+
+# Now run Ghostscript...
+$bindir/gs $gsopts -sOUTPUTFILE="%stdout" $profile $6
+
+#
+# End of "$Id: pstoraster 2352 2002-04-23 17:29:00Z mike $".
+#
diff --git a/pstoraster/pstoraster.convs b/pstoraster/pstoraster.convs
new file mode 100644
index 000000000..c1a416bc1
--- /dev/null
+++ b/pstoraster/pstoraster.convs
@@ -0,0 +1,29 @@
+#
+# "$Id: pstoraster.convs 2352 2002-04-23 17:29:00Z mike $"
+#
+# MIME converts file for Ghostscript.
+#
+# Copyright 1997-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+application/vnd.cups-postscript application/vnd.cups-raster 100 pstoraster
+
+#
+# End of "$Id: pstoraster.convs 2352 2002-04-23 17:29:00Z mike $".
+#
diff --git a/pstoraster/pstoraster.in b/pstoraster/pstoraster.in
new file mode 100755
index 000000000..a6390b814
--- /dev/null
+++ b/pstoraster/pstoraster.in
@@ -0,0 +1,59 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# CUPS filter script for Ghostscript.
+#
+# Copyright 2001-2002 by Easy Software Products.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+# Installation directories...
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+
+# Set the library/font path...
+GS_FONTPATH="$CUPS_FONTPATH"
+export GS_FONTPATH
+
+# Options we use with Ghostscript...
+gsopts="-dQUIET -dDEBUG -dPARANOIDSAFER -dNOPAUSE -dBATCH "
+gsopts="$gsopts -dNOMEDIAATTRS -sDEVICE=cups -sstdout=%stderr"
+
+# See if we have a profile=n,n,n,n,n,n,n,n,n,n,n option...
+profile=""
+for option in $5; do
+ case $option in
+ profile=*)
+ profile="-scupsProfile=`echo $option | awk -F= '{print $2}'`"
+ ;;
+ esac
+done
+
+# See if we have a filename on the command-line...
+if test -z "$6"; then
+ ifile="-"
+else
+ ifile="$6"
+fi
+
+# Now run Ghostscript...
+$bindir/@GS@ $gsopts -sOUTPUTFILE="%stdout" $profile $ifile
+
+#
+# End of "$Id$".
+#
diff --git a/scheduler/.cvsignore b/scheduler/.cvsignore
new file mode 100644
index 000000000..22f1097b7
--- /dev/null
+++ b/scheduler/.cvsignore
@@ -0,0 +1,5 @@
+cupsd
+cups-polld
+cups-lpd
+testmime
+testspeed
diff --git a/scheduler/Dependencies b/scheduler/Dependencies
new file mode 100644
index 000000000..7e688d60f
--- /dev/null
+++ b/scheduler/Dependencies
@@ -0,0 +1,95 @@
+# DO NOT DELETE
+
+auth.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+auth.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+auth.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+auth.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h network.h
+auth.o: ../cups/md5.h
+banners.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+banners.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+banners.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+banners.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h
+banners.o: network.h
+cert.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+cert.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+cert.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+cert.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h network.h
+classes.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+classes.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+classes.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+classes.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h
+classes.o: network.h
+client.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+client.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+client.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+client.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h
+client.o: network.h
+conf.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+conf.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+conf.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+conf.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h network.h
+devices.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+devices.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+devices.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+devices.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h
+devices.o: network.h
+dirsvc.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+dirsvc.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+dirsvc.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+dirsvc.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h
+dirsvc.o: network.h
+main.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+main.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+main.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+main.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h network.h
+ipp.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+ipp.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+ipp.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+ipp.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h network.h
+listen.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+listen.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+listen.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+listen.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h
+listen.o: network.h
+job.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+job.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+job.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+job.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h network.h
+log.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+log.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+log.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+log.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h network.h
+network.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+network.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+network.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+network.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h
+network.o: network.h
+ppds.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+ppds.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+ppds.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+ppds.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h network.h
+printers.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+printers.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+printers.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+printers.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h
+printers.o: network.h
+quotas.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+quotas.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+quotas.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+quotas.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h
+quotas.o: network.h
+server.o: cupsd.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+server.o: ../cups/ppd.h ../cups/string.h ../config.h mime.h ../cups/ipp.h
+server.o: ../cups/http.h ../cups/language.h ../cups/debug.h cert.h client.h
+server.o: auth.h printers.h classes.h job.h conf.h banners.h dirsvc.h
+server.o: network.h
+filter.o: ../cups/string.h ../config.h mime.h ../cups/ipp.h
+mime.o: ../cups/string.h ../config.h mime.h ../cups/ipp.h
+type.o: ../cups/string.h ../config.h mime.h ../cups/ipp.h ../cups/debug.h
+cups-lpd.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+cups-lpd.o: ../cups/ppd.h ../cups/string.h ../config.h ../cups/language.h
+cups-polld.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+cups-polld.o: ../cups/ppd.h ../cups/language.h ../cups/string.h ../config.h
+testmime.o: ../cups/string.h ../config.h mime.h ../cups/ipp.h
+testspeed.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+testspeed.o: ../cups/ppd.h ../cups/language.h ../cups/debug.h
diff --git a/scheduler/Makefile b/scheduler/Makefile
new file mode 100644
index 000000000..63a1ce8e8
--- /dev/null
+++ b/scheduler/Makefile
@@ -0,0 +1,142 @@
+#
+# "$Id$"
+#
+# Scheduler Makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+CUPSDOBJS = auth.o banners.o cert.o classes.o client.o conf.o devices.o \
+ dirsvc.o main.o ipp.o listen.o job.o log.o network.o \
+ ppds.o printers.o quotas.o server.o
+MIMEOBJS = filter.o mime.o type.o
+OBJS = $(CUPSDOBJS) $(MIMEOBJS) cups-lpd.o cups-polld.o testmime.o \
+ testspeed.o
+
+
+#
+# Make everything...
+#
+
+all: cupsd cups-lpd cups-polld libmime.a
+
+
+#
+# Clean all object files...
+#
+
+clean:
+ $(RM) $(OBJS) cupsd cups-lpd cups-polld libmime.a testmime testspeed
+
+
+#
+# Update dependencies (without system header dependencies...)
+#
+
+depend:
+ makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1
+
+
+#
+# Install the scheduler...
+#
+
+install: all
+ $(INSTALL_DIR) $(SBINDIR)
+ $(INSTALL_BIN) cupsd $(SBINDIR)
+ $(INSTALL_DIR) $(SERVERBIN)/daemon
+ $(INSTALL_BIN) cups-lpd $(SERVERBIN)/daemon
+ $(INSTALL_BIN) cups-polld $(SERVERBIN)/daemon
+ $(INSTALL_DIR) -m 711 $(SERVERROOT)/certs
+ $(INSTALL_DIR) $(SERVERROOT)/interfaces
+ $(INSTALL_DIR) $(SERVERROOT)/ppd
+ $(INSTALL_DIR) $(LOGDIR)
+ $(INSTALL_DIR) -m 700 $(REQUESTS)
+ $(INSTALL_DIR) -m 1700 $(REQUESTS)/tmp
+
+
+#
+# Make the scheduler executable, "cupsd".
+#
+
+cupsd: $(CUPSDOBJS) libmime.a ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) libmime.a \
+ $(LIBZ) $(SSLLIBS) $(LIBSLP) $(PAMLIBS) $(LIBS) $(LIBMALLOC)
+
+
+#
+# Make the line printer daemon, "cups-lpd".
+#
+
+cups-lpd: cups-lpd.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o cups-lpd cups-lpd.o $(LIBS)
+
+
+#
+# Make the polling daemon, "cups-polld".
+#
+
+cups-polld: cups-polld.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o cups-polld cups-polld.o $(LIBS)
+
+
+#
+# libmime.a
+#
+
+libmime.a: $(MIMEOBJS)
+ echo Archiving $@...
+ $(RM) $@
+ $(AR) $(ARFLAGS) $@ $(MIMEOBJS)
+ $(RANLIB) $@
+
+
+#
+# testmime
+#
+
+testmime: testmime.o libmime.a
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o $@ testmime.o libmime.a ../cups/libcups.a
+
+
+#
+# Make the test program, "testspeed".
+#
+
+testspeed: testspeed.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o testspeed testspeed.o $(LIBS)
+
+
+#
+# Dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id$".
+#
diff --git a/scheduler/auth.c b/scheduler/auth.c
new file mode 100644
index 000000000..011be6d20
--- /dev/null
+++ b/scheduler/auth.c
@@ -0,0 +1,1627 @@
+/*
+ * "$Id$"
+ *
+ * Authorization routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * AddLocation() - Add a location for authorization.
+ * AddName() - Add a name to a location...
+ * AllowHost() - Add a host name that is allowed to access the
+ * location.
+ * AllowIP() - Add an IP address or network that is allowed to
+ * access the location.
+ * CheckAuth() - Check authorization masks.
+ * CopyLocation() - Make a copy of a location...
+ * DeleteAllLocations() - Free all memory used for location authorization.
+ * DenyHost() - Add a host name that is not allowed to access the
+ * location.
+ * DenyIP() - Add an IP address or network that is not allowed
+ * to access the location.
+ * FindBest() - Find the location entry that best matches the
+ * resource.
+ * FindLocation() - Find the named location.
+ * GetMD5Passwd() - Get an MD5 password.
+ * IsAuthorized() - Check to see if the user is authorized...
+ * add_allow() - Add an allow mask to the location.
+ * add_deny() - Add a deny mask to the location.
+ * cups_crypt() - Encrypt the password using the DES or MD5
+ * algorithms, as needed.
+ * pam_func() - PAM conversation function.
+ * to64() - Base64-encode an integer value...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+#include <pwd.h>
+#include <grp.h>
+#include <cups/md5.h>
+#ifdef HAVE_SHADOW_H
+# include <shadow.h>
+#endif /* HAVE_SHADOW_H */
+#ifdef HAVE_CRYPT_H
+# include <crypt.h>
+#endif /* HAVE_CRYPT_H */
+#if HAVE_LIBPAM
+# ifdef HAVE_PAM_PAM_APPL_H
+# include <pam/pam_appl.h>
+# else
+# include <security/pam_appl.h>
+# endif /* HAVE_PAM_PAM_APPL_H */
+#endif /* HAVE_LIBPAM */
+#ifdef HAVE_USERSEC_H
+# include <usersec.h>
+#endif /* HAVE_USERSEC_H */
+
+
+/*
+ * Local functions...
+ */
+
+static authmask_t *add_allow(location_t *loc);
+static authmask_t *add_deny(location_t *loc);
+#if !HAVE_LIBPAM
+static char *cups_crypt(const char *pw, const char *salt);
+#endif /* !HAVE_LIBPAM */
+#if HAVE_LIBPAM
+static int pam_func(int, const struct pam_message **,
+ struct pam_response **, void *);
+#else
+static void to64(char *s, unsigned long v, int n);
+#endif /* HAVE_LIBPAM */
+
+
+/*
+ * Local globals...
+ */
+
+#ifdef __hpux
+static client_t *auth_client; /* Current client being authenticated */
+#endif /* __hpux */
+
+
+/*
+ * 'AddLocation()' - Add a location for authorization.
+ */
+
+location_t * /* O - Pointer to new location record */
+AddLocation(const char *location) /* I - Location path */
+{
+ location_t *temp; /* New location */
+
+
+ /*
+ * Try to allocate memory for the new location.
+ */
+
+ if (NumLocations == 0)
+ temp = malloc(sizeof(location_t));
+ else
+ temp = realloc(Locations, sizeof(location_t) * (NumLocations + 1));
+
+ if (temp == NULL)
+ return (NULL);
+
+ Locations = temp;
+ temp += NumLocations;
+ NumLocations ++;
+
+ /*
+ * Initialize the record and copy the name over...
+ */
+
+ memset(temp, 0, sizeof(location_t));
+ strlcpy(temp->location, location, sizeof(temp->location));
+ temp->length = strlen(temp->location);
+
+ LogMessage(L_DEBUG, "AddLocation: added location \'%s\'", location);
+
+ /*
+ * Return the new record...
+ */
+
+ return (temp);
+}
+
+
+/*
+ * 'AddName()' - Add a name to a location...
+ */
+
+void
+AddName(location_t *loc, /* I - Location to add to */
+ char *name) /* I - Name to add */
+{
+ char **temp; /* Pointer to names array */
+
+
+ if (loc->num_names == 0)
+ temp = malloc(sizeof(char *));
+ else
+ temp = realloc(loc->names, (loc->num_names + 1) * sizeof(char *));
+
+ if (temp == NULL)
+ {
+ LogMessage(L_ERROR, "Unable to add name to location %s: %s", loc->location,
+ strerror(errno));
+ return;
+ }
+
+ loc->names = temp;
+
+ if ((temp[loc->num_names] = strdup(name)) == NULL)
+ {
+ LogMessage(L_ERROR, "Unable to duplicate name for location %s: %s",
+ loc->location, strerror(errno));
+ return;
+ }
+
+ loc->num_names ++;
+}
+
+
+/*
+ * 'AllowHost()' - Add a host name that is allowed to access the location.
+ */
+
+void
+AllowHost(location_t *loc, /* I - Location to add to */
+ char *name) /* I - Name of host or domain to add */
+{
+ authmask_t *temp; /* New host/domain mask */
+ char ifname[32], /* Interface name */
+ *ifptr; /* Pointer to end of name */
+
+
+ if ((temp = add_allow(loc)) == NULL)
+ return;
+
+ if (strcasecmp(name, "@LOCAL") == 0)
+ {
+ /*
+ * Allow *interface*...
+ */
+
+ temp->type = AUTH_INTERFACE;
+ temp->mask.name.name = strdup("*");
+ temp->mask.name.length = 1;
+ }
+ else if (strncasecmp(name, "@IF(", 4) == 0)
+ {
+ /*
+ * Allow *interface*...
+ */
+
+ strlcpy(ifname, name + 4, sizeof(ifname));
+
+ ifptr = ifname + strlen(ifname);
+
+ if (ifptr[-1] == ')')
+ {
+ ifptr --;
+ *ifptr = '\0';
+ }
+
+ temp->type = AUTH_INTERFACE;
+ temp->mask.name.name = strdup(ifname);
+ temp->mask.name.length = ifptr - ifname;
+ }
+ else
+ {
+ /*
+ * Allow name...
+ */
+
+ temp->type = AUTH_NAME;
+ temp->mask.name.name = strdup(name);
+ temp->mask.name.length = strlen(name);
+ }
+
+ LogMessage(L_DEBUG, "AllowHost: %s allow %s", loc->location, name);
+}
+
+
+/*
+ * 'AllowIP()' - Add an IP address or network that is allowed to access the
+ * location.
+ */
+
+void
+AllowIP(location_t *loc, /* I - Location to add to */
+ unsigned address, /* I - IP address to add */
+ unsigned netmask) /* I - Netmask of address */
+{
+ authmask_t *temp; /* New host/domain mask */
+
+
+ if ((temp = add_allow(loc)) == NULL)
+ return;
+
+ temp->type = AUTH_IP;
+ temp->mask.ip.address = address;
+ temp->mask.ip.netmask = netmask;
+
+ LogMessage(L_DEBUG, "AllowIP: %s allow %08x/%08x", loc->location,
+ address, netmask);
+}
+
+
+/*
+ * 'CheckAuth()' - Check authorization masks.
+ */
+
+int /* O - 1 if mask matches, 0 otherwise */
+CheckAuth(unsigned ip, /* I - Client address */
+ char *name, /* I - Client hostname */
+ int name_len, /* I - Length of hostname */
+ int num_masks, /* I - Number of masks */
+ authmask_t *masks) /* I - Masks */
+{
+ cups_netif_t *iface; /* Network interface */
+ unsigned netip; /* Network address */
+
+
+ while (num_masks > 0)
+ {
+ switch (masks->type)
+ {
+ case AUTH_INTERFACE :
+ /*
+ * Check for a match with a network interface...
+ */
+
+ netip = htonl(ip);
+
+ if (strcmp(masks->mask.name.name, "*") == 0)
+ {
+ /*
+ * Check against all local interfaces...
+ */
+
+ NetIFUpdate();
+
+ for (iface = NetIFList; iface != NULL; iface = iface->next)
+ {
+ /*
+ * Only check local interfaces...
+ */
+
+ if (!iface->is_local)
+ continue;
+
+ if ((netip & iface->mask.sin_addr.s_addr) ==
+ (iface->address.sin_addr.s_addr &
+ iface->mask.sin_addr.s_addr))
+ return (1);
+ }
+ }
+ else
+ {
+ /*
+ * Check the named interface...
+ */
+
+ if ((iface = NetIFFind(masks->mask.name.name)) != NULL)
+ {
+ if ((netip & iface->mask.sin_addr.s_addr) ==
+ (iface->address.sin_addr.s_addr &
+ iface->mask.sin_addr.s_addr))
+ return (1);
+ }
+ }
+ break;
+
+ case AUTH_NAME :
+ /*
+ * Check for exact name match...
+ */
+
+ if (strcasecmp(name, masks->mask.name.name) == 0)
+ return (1);
+
+ /*
+ * Check for domain match...
+ */
+
+ if (name_len >= masks->mask.name.length &&
+ masks->mask.name.name[0] == '.' &&
+ strcasecmp(name + name_len - masks->mask.name.length,
+ masks->mask.name.name) == 0)
+ return (1);
+ break;
+
+ case AUTH_IP :
+ /*
+ * Check for IP/network address match...
+ */
+
+ if ((ip & masks->mask.ip.netmask) == masks->mask.ip.address)
+ return (1);
+ break;
+ }
+
+ masks ++;
+ num_masks --;
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'CopyLocation()' - Make a copy of a location...
+ */
+
+location_t * /* O - New location */
+CopyLocation(location_t **loc) /* IO - Original location */
+{
+ int i; /* Looping var */
+ int locindex; /* Index into Locations array */
+ location_t *temp; /* New location */
+
+
+ /*
+ * Add the new location, updating the original location
+ * pointer as needed...
+ */
+
+ locindex = *loc - Locations;
+
+ if ((temp = AddLocation((*loc)->location)) == NULL)
+ return (NULL);
+
+ *loc = Locations + locindex;
+
+ /*
+ * Copy the information from the original location to the new one.
+ */
+
+ temp->limit = (*loc)->limit;
+ temp->order_type = (*loc)->order_type;
+ temp->type = (*loc)->type;
+ temp->level = (*loc)->level;
+ temp->satisfy = (*loc)->satisfy;
+ temp->encryption = (*loc)->encryption;
+
+ if ((temp->num_names = (*loc)->num_names) > 0)
+ {
+ /*
+ * Copy the names array...
+ */
+
+ if ((temp->names = calloc(temp->num_names, sizeof(char *))) == NULL)
+ {
+ LogMessage(L_ERROR, "CopyLocation: Unable to allocate memory for %d names: %s",
+ temp->num_names, strerror(errno));
+ NumLocations --;
+ return (NULL);
+ }
+
+ for (i = 0; i < temp->num_names; i ++)
+ if ((temp->names[i] = strdup((*loc)->names[i])) == NULL)
+ {
+ LogMessage(L_ERROR, "CopyLocation: Unable to copy name \"%s\": %s",
+ (*loc)->names[i], strerror(errno));
+
+ NumLocations --;
+ return (NULL);
+ }
+ }
+
+ if ((temp->num_allow = (*loc)->num_allow) > 0)
+ {
+ /*
+ * Copy allow rules...
+ */
+
+ if ((temp->allow = calloc(temp->num_allow, sizeof(authmask_t))) == NULL)
+ {
+ LogMessage(L_ERROR, "CopyLocation: Unable to allocate memory for %d allow rules: %s",
+ temp->num_allow, strerror(errno));
+ NumLocations --;
+ return (NULL);
+ }
+
+ for (i = 0; i < temp->num_allow; i ++)
+ switch (temp->allow[i].type = (*loc)->allow[i].type)
+ {
+ case AUTH_NAME :
+ temp->allow[i].mask.name.length = (*loc)->allow[i].mask.name.length;
+ temp->allow[i].mask.name.name = strdup((*loc)->allow[i].mask.name.name);
+
+ if (temp->allow[i].mask.name.name == NULL)
+ {
+ LogMessage(L_ERROR, "CopyLocation: Unable to copy allow name \"%s\": %s",
+ (*loc)->allow[i].mask.name.name, strerror(errno));
+ NumLocations --;
+ return (NULL);
+ }
+ break;
+ case AUTH_IP :
+ memcpy(&(temp->allow[i].mask.ip), &((*loc)->allow[i].mask.ip),
+ sizeof(ipmask_t));
+ break;
+ }
+ }
+
+ if ((temp->num_deny = (*loc)->num_deny) > 0)
+ {
+ /*
+ * Copy deny rules...
+ */
+
+ if ((temp->deny = calloc(temp->num_deny, sizeof(authmask_t))) == NULL)
+ {
+ LogMessage(L_ERROR, "CopyLocation: Unable to allocate memory for %d deny rules: %s",
+ temp->num_deny, strerror(errno));
+ NumLocations --;
+ return (NULL);
+ }
+
+ for (i = 0; i < temp->num_deny; i ++)
+ switch (temp->deny[i].type = (*loc)->deny[i].type)
+ {
+ case AUTH_NAME :
+ temp->deny[i].mask.name.length = (*loc)->deny[i].mask.name.length;
+ temp->deny[i].mask.name.name = strdup((*loc)->deny[i].mask.name.name);
+
+ if (temp->deny[i].mask.name.name == NULL)
+ {
+ LogMessage(L_ERROR, "CopyLocation: Unable to copy deny name \"%s\": %s",
+ (*loc)->deny[i].mask.name.name, strerror(errno));
+ NumLocations --;
+ return (NULL);
+ }
+ break;
+ case AUTH_IP :
+ memcpy(&(temp->deny[i].mask.ip), &((*loc)->deny[i].mask.ip),
+ sizeof(ipmask_t));
+ break;
+ }
+ }
+
+ return (temp);
+}
+
+
+/*
+ * 'DeleteAllLocations()' - Free all memory used for location authorization.
+ */
+
+void
+DeleteAllLocations(void)
+{
+ int i, j; /* Looping vars */
+ location_t *loc; /* Current location */
+ authmask_t *mask; /* Current mask */
+
+
+ /*
+ * Free all of the allow/deny records first...
+ */
+
+ for (i = NumLocations, loc = Locations; i > 0; i --, loc ++)
+ {
+ for (j = loc->num_names - 1; j >= 0; j --)
+ free(loc->names[j]);
+
+ if (loc->num_names > 0)
+ free(loc->names);
+
+ for (j = loc->num_allow, mask = loc->allow; j > 0; j --, mask ++)
+ if (mask->type == AUTH_NAME)
+ free(mask->mask.name.name);
+
+ if (loc->num_allow > 0)
+ free(loc->allow);
+
+ for (j = loc->num_deny, mask = loc->deny; j > 0; j --, mask ++)
+ if (mask->type == AUTH_NAME)
+ free(mask->mask.name.name);
+
+ if (loc->num_deny > 0)
+ free(loc->deny);
+ }
+
+ /*
+ * Then free the location array...
+ */
+
+ if (NumLocations > 0)
+ free(Locations);
+
+ Locations = NULL;
+ NumLocations = 0;
+}
+
+
+/*
+ * 'DenyHost()' - Add a host name that is not allowed to access the location.
+ */
+
+void
+DenyHost(location_t *loc, /* I - Location to add to */
+ char *name) /* I - Name of host or domain to add */
+{
+ authmask_t *temp; /* New host/domain mask */
+ char ifname[32], /* Interface name */
+ *ifptr; /* Pointer to end of name */
+
+
+ if ((temp = add_deny(loc)) == NULL)
+ return;
+
+ if (strcasecmp(name, "@LOCAL") == 0)
+ {
+ /*
+ * Deny *interface*...
+ */
+
+ temp->type = AUTH_INTERFACE;
+ temp->mask.name.name = strdup("*");
+ temp->mask.name.length = 1;
+ }
+ else if (strncasecmp(name, "@IF(", 4) == 0)
+ {
+ /*
+ * Deny *interface*...
+ */
+
+ strlcpy(ifname, name + 4, sizeof(ifname));
+
+ ifptr = ifname + strlen(ifname);
+
+ if (ifptr[-1] == ')')
+ {
+ ifptr --;
+ *ifptr = '\0';
+ }
+
+ temp->type = AUTH_INTERFACE;
+ temp->mask.name.name = strdup(ifname);
+ temp->mask.name.length = ifptr - ifname;
+ }
+ else
+ {
+ /*
+ * Deny name...
+ */
+
+ temp->type = AUTH_NAME;
+ temp->mask.name.name = strdup(name);
+ temp->mask.name.length = strlen(name);
+ }
+
+ LogMessage(L_DEBUG, "DenyHost: %s deny %s", loc->location, name);
+}
+
+
+/*
+ * 'DenyIP()' - Add an IP address or network that is not allowed to access
+ * the location.
+ */
+
+void
+DenyIP(location_t *loc, /* I - Location to add to */
+ unsigned address, /* I - IP address to add */
+ unsigned netmask) /* I - Netmask of address */
+{
+ authmask_t *temp; /* New host/domain mask */
+
+
+ if ((temp = add_deny(loc)) == NULL)
+ return;
+
+ temp->type = AUTH_IP;
+ temp->mask.ip.address = address;
+ temp->mask.ip.netmask = netmask;
+
+ LogMessage(L_DEBUG, "DenyIP: %s deny %08x/%08x\n", loc->location,
+ address, netmask);
+}
+
+
+/*
+ * 'FindBest()' - Find the location entry that best matches the resource.
+ */
+
+location_t * /* O - Location that matches */
+FindBest(const char *path, /* I - Resource path */
+ http_state_t state) /* I - HTTP state/request */
+{
+ int i; /* Looping var */
+ char uri[HTTP_MAX_URI],
+ /* URI in request... */
+ *uriptr; /* Pointer into URI */
+ location_t *loc, /* Current location */
+ *best; /* Best match for location so far */
+ int bestlen; /* Length of best match */
+ int limit; /* Limit field */
+ static int limits[] = /* Map http_status_t to AUTH_LIMIT_xyz */
+ {
+ AUTH_LIMIT_ALL,
+ AUTH_LIMIT_OPTIONS,
+ AUTH_LIMIT_GET,
+ AUTH_LIMIT_GET,
+ AUTH_LIMIT_HEAD,
+ AUTH_LIMIT_POST,
+ AUTH_LIMIT_POST,
+ AUTH_LIMIT_POST,
+ AUTH_LIMIT_PUT,
+ AUTH_LIMIT_PUT,
+ AUTH_LIMIT_DELETE,
+ AUTH_LIMIT_TRACE,
+ AUTH_LIMIT_ALL,
+ AUTH_LIMIT_ALL
+ };
+
+
+ /*
+ * First copy the connection URI to a local string so we have drop
+ * any .ppd extension from the pathname in /printers or /classes
+ * URIs...
+ */
+
+ strlcpy(uri, path, sizeof(uri));
+
+ if (strncmp(uri, "/printers/", 10) == 0 ||
+ strncmp(uri, "/classes/", 9) == 0)
+ {
+ /*
+ * Check if the URI has .ppd on the end...
+ */
+
+ uriptr = uri + strlen(uri) - 4; /* len > 4 if we get here... */
+
+ if (strcmp(uriptr, ".ppd") == 0)
+ *uriptr = '\0';
+ }
+
+ LogMessage(L_DEBUG2, "FindBest: uri = \"%s\"...", uri);
+
+ /*
+ * Loop through the list of locations to find a match...
+ */
+
+ limit = limits[state];
+ best = NULL;
+ bestlen = 0;
+
+ for (i = NumLocations, loc = Locations; i > 0; i --, loc ++)
+ {
+ LogMessage(L_DEBUG2, "FindBest: Location %s Limit %x",
+ loc->location, loc->limit);
+
+ if (loc->length > bestlen &&
+ strncmp(uri, loc->location, loc->length) == 0 &&
+ loc->location[0] == '/' &&
+ (limit & loc->limit) != 0)
+ {
+ best = loc;
+ bestlen = loc->length;
+ }
+ }
+
+ /*
+ * Return the match, if any...
+ */
+
+ LogMessage(L_DEBUG2, "FindBest: best = \"%s\"",
+ best ? best->location : "NONE");
+
+ return (best);
+}
+
+
+/*
+ * 'FindLocation()' - Find the named location.
+ */
+
+location_t * /* O - Location that matches */
+FindLocation(const char *location) /* I - Connection */
+{
+ int i; /* Looping var */
+
+
+ /*
+ * Loop through the list of locations to find a match...
+ */
+
+ for (i = 0; i < NumLocations; i ++)
+ if (strcasecmp(Locations[i].location, location) == 0)
+ return (Locations + i);
+
+ return (NULL);
+}
+
+
+/*
+ * 'GetMD5Passwd()' - Get an MD5 password.
+ */
+
+char * /* O - MD5 password string */
+GetMD5Passwd(const char *username, /* I - Username */
+ const char *group, /* I - Group */
+ char passwd[33]) /* O - MD5 password string */
+{
+ FILE *fp; /* passwd.md5 file */
+ char filename[1024], /* passwd.md5 filename */
+ line[256], /* Line from file */
+ tempuser[33], /* User from file */
+ tempgroup[33]; /* Group from file */
+
+
+ snprintf(filename, sizeof(filename), "%s/passwd.md5", ServerRoot);
+ if ((fp = fopen(filename, "r")) == NULL)
+ return (NULL);
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ if (sscanf(line, "%32[^:]:%32[^:]:%32s", tempuser, tempgroup, passwd) != 3)
+ continue;
+
+ if (strcmp(username, tempuser) == 0 &&
+ (group == NULL || strcmp(group, tempgroup) == 0))
+ {
+ /*
+ * Found the password entry!
+ */
+
+ fclose(fp);
+ return (passwd);
+ }
+ }
+
+ /*
+ * Didn't find a password entry - return NULL!
+ */
+
+ fclose(fp);
+ return (NULL);
+}
+
+
+/*
+ * 'IsAuthorized()' - Check to see if the user is authorized...
+ */
+
+http_status_t /* O - HTTP_OK if authorized or error code */
+IsAuthorized(client_t *con) /* I - Connection */
+{
+ int i, j, /* Looping vars */
+ auth; /* Authorization status */
+ unsigned address; /* Authorization address */
+ location_t *best; /* Best match for location so far */
+ int hostlen; /* Length of hostname */
+ struct passwd *pw; /* User password data */
+ struct group *grp; /* Group data */
+ char nonce[HTTP_MAX_VALUE],
+ /* Nonce value from client */
+ md5[33], /* MD5 password */
+ basicmd5[33]; /* MD5 of Basic password */
+#if HAVE_LIBPAM
+ pam_handle_t *pamh; /* PAM authentication handle */
+ int pamerr; /* PAM error code */
+ struct pam_conv pamdata; /* PAM conversation data */
+#elif defined(HAVE_USERSEC_H)
+ char *authmsg; /* Authentication message */
+ char *loginmsg; /* Login message */
+ int reenter; /* ??? */
+#else
+ char *pass; /* Encrypted password */
+# ifdef HAVE_SHADOW_H
+ struct spwd *spw; /* Shadow password data */
+# endif /* HAVE_SHADOW_H */
+#endif /* HAVE_LIBPAM */
+ static const char *states[] = /* HTTP client states... */
+ {
+ "WAITING",
+ "OPTIONS",
+ "GET",
+ "GET",
+ "HEAD",
+ "POST",
+ "POST",
+ "POST",
+ "PUT",
+ "PUT",
+ "DELETE",
+ "TRACE",
+ "CLOSE",
+ "STATUS"
+ };
+
+
+ LogMessage(L_DEBUG2, "IsAuthorized: con->uri = \"%s\"", con->uri);
+
+ /*
+ * Find a matching location; if there is no match then access is
+ * not authorized...
+ */
+
+ if ((best = FindBest(con->uri, con->http.state)) == NULL)
+ return (HTTP_FORBIDDEN);
+
+ /*
+ * Check host/ip-based accesses...
+ */
+
+ address = ntohl(con->http.hostaddr.sin_addr.s_addr);
+ hostlen = strlen(con->http.hostname);
+
+ if (address == 0x7f000001 || strcasecmp(con->http.hostname, "localhost") == 0)
+ {
+ /*
+ * Access from localhost (127.0.0.1) is always allowed...
+ */
+
+ auth = AUTH_ALLOW;
+ }
+ else if (best->num_allow == 0 && best->num_deny == 0)
+ {
+ /*
+ * No allow/deny lines - allow access...
+ */
+
+ auth = AUTH_ALLOW;
+ }
+ else
+ {
+ /*
+ * Do authorization checks on the domain/address...
+ */
+
+ switch (best->order_type)
+ {
+ default :
+ auth = AUTH_DENY; /* anti-compiler-warning-code */
+ break;
+
+ case AUTH_ALLOW : /* Order Deny,Allow */
+ auth = AUTH_ALLOW;
+
+ if (CheckAuth(address, con->http.hostname, hostlen,
+ best->num_deny, best->deny))
+ auth = AUTH_DENY;
+
+ if (CheckAuth(address, con->http.hostname, hostlen,
+ best->num_allow, best->allow))
+ auth = AUTH_ALLOW;
+ break;
+
+ case AUTH_DENY : /* Order Allow,Deny */
+ auth = AUTH_DENY;
+
+ if (CheckAuth(address, con->http.hostname, hostlen,
+ best->num_allow, best->allow))
+ auth = AUTH_ALLOW;
+
+ if (CheckAuth(address, con->http.hostname, hostlen,
+ best->num_deny, best->deny))
+ auth = AUTH_DENY;
+ break;
+ }
+ }
+
+ LogMessage(L_DEBUG2, "IsAuthorized: auth = %d, satisfy=%d...",
+ auth, best->satisfy);
+
+ if (auth == AUTH_DENY && best->satisfy == AUTH_SATISFY_ALL)
+ return (HTTP_FORBIDDEN);
+
+#ifdef HAVE_LIBSSL
+ /*
+ * See if encryption is required...
+ */
+
+ if (best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http.tls)
+ {
+ LogMessage(L_DEBUG2, "IsAuthorized: Need upgrade to TLS...");
+ return (HTTP_UPGRADE_REQUIRED);
+ }
+#endif /* HAVE_LIBSSL */
+
+ /*
+ * Now see what access level is required...
+ */
+
+ if (best->level == AUTH_ANON) /* Anonymous access - allow it */
+ return (HTTP_OK);
+
+ LogMessage(L_DEBUG2, "IsAuthorized: username = \"%s\" password = %d chars",
+ con->username, strlen(con->password));
+ DEBUG_printf(("IsAuthorized: username = \"%s\", password = \"%s\"\n",
+ con->username, con->password));
+
+ if (con->username[0] == '\0')
+ {
+ if (best->satisfy == AUTH_SATISFY_ALL || auth == AUTH_DENY)
+ return (HTTP_UNAUTHORIZED); /* Non-anonymous needs user/pass */
+ else
+ return (HTTP_OK); /* unless overridden with Satisfy */
+ }
+
+ /*
+ * Check the user's password...
+ */
+
+ LogMessage(L_DEBUG2, "IsAuthorized: Checking \"%s\", address = %08x, hostname = \"%s\"",
+ con->username, address, con->http.hostname);
+
+ pw = NULL;
+
+ if ((address != 0x7f000001 &&
+ strcasecmp(con->http.hostname, "localhost") != 0) ||
+ strncmp(con->http.fields[HTTP_FIELD_AUTHORIZATION], "Local", 5) != 0)
+ {
+ /*
+ * Not doing local certificate-based authentication; check the password...
+ */
+
+ if (!con->password[0])
+ return (HTTP_UNAUTHORIZED);
+
+ /*
+ * See what kind of authentication we are doing...
+ */
+
+ switch (best->type)
+ {
+ case AUTH_BASIC :
+ /*
+ * Get the user info...
+ */
+
+ pw = getpwnam(con->username); /* Get the current password */
+ endpwent(); /* Close the password file */
+
+ if (pw == NULL) /* No such user... */
+ {
+ LogMessage(L_WARN, "IsAuthorized: Unknown username \"%s\"; access denied.",
+ con->username);
+ return (HTTP_UNAUTHORIZED);
+ }
+
+#if HAVE_LIBPAM
+ /*
+ * Only use PAM to do authentication. This allows MD5 passwords, among
+ * other things...
+ */
+
+ pamdata.conv = pam_func;
+ pamdata.appdata_ptr = con;
+
+# ifdef __hpux
+ /*
+ * Workaround for HP-UX bug in pam_unix; see pam_conv() below for
+ * more info...
+ */
+
+ auth_client = con;
+# endif /* __hpux */
+
+ DEBUG_printf(("IsAuthorized: Setting appdata_ptr = %p\n", con));
+
+ pamerr = pam_start("cups", con->username, &pamdata, &pamh);
+ if (pamerr != PAM_SUCCESS)
+ {
+ LogMessage(L_ERROR, "IsAuthorized: pam_start() returned %d (%s)!\n",
+ pamerr, pam_strerror(pamh, pamerr));
+ pam_end(pamh, 0);
+ return (HTTP_UNAUTHORIZED);
+ }
+
+ pamerr = pam_authenticate(pamh, PAM_SILENT);
+ if (pamerr != PAM_SUCCESS)
+ {
+ LogMessage(L_ERROR, "IsAuthorized: pam_authenticate() returned %d (%s)!\n",
+ pamerr, pam_strerror(pamh, pamerr));
+ pam_end(pamh, 0);
+ return (HTTP_UNAUTHORIZED);
+ }
+
+ pamerr = pam_acct_mgmt(pamh, PAM_SILENT);
+ if (pamerr != PAM_SUCCESS)
+ {
+ LogMessage(L_ERROR, "IsAuthorized: pam_acct_mgmt() returned %d (%s)!\n",
+ pamerr, pam_strerror(pamh, pamerr));
+ pam_end(pamh, 0);
+ return (HTTP_UNAUTHORIZED);
+ }
+
+ pam_end(pamh, PAM_SUCCESS);
+#elif defined(HAVE_USERSEC_H)
+ /*
+ * Use AIX authentication interface...
+ */
+
+ LogMessage(L_DEBUG, "IsAuthorized: AIX authenticate of username \"%s\"",
+ con->username);
+
+ reenter = 1;
+ if (authenticate(con->username, con->password, &reenter, &authmsg) != 0)
+ {
+ LogMessage(L_DEBUG, "IsAuthorized: Unable to authenticate username \"%s\": %s",
+ con->username, strerror(errno));
+ return (HTTP_UNAUTHORIZED);
+ }
+#else
+# ifdef HAVE_SHADOW_H
+ spw = getspnam(con->username);
+ endspent();
+
+ if (spw == NULL && strcmp(pw->pw_passwd, "x") == 0)
+ { /* Don't allow blank passwords! */
+ LogMessage(L_WARN, "IsAuthorized: Username \"%s\" has no shadow password; access denied.",
+ con->username);
+ return (HTTP_UNAUTHORIZED); /* No such user or bad shadow file */
+ }
+
+# ifdef DEBUG
+ if (spw != NULL)
+ printf("spw->sp_pwdp = \"%s\"\n", spw->sp_pwdp);
+ else
+ puts("spw = NULL");
+# endif /* DEBUG */
+
+ if (spw != NULL && spw->sp_pwdp[0] == '\0' && pw->pw_passwd[0] == '\0')
+# else
+ if (pw->pw_passwd[0] == '\0')
+# endif /* HAVE_SHADOW_H */
+ { /* Don't allow blank passwords! */
+ LogMessage(L_WARN, "IsAuthorized: Username \"%s\" has no password; access denied.",
+ con->username);
+ return (HTTP_UNAUTHORIZED);
+ }
+
+ /*
+ * OK, the password isn't blank, so compare with what came from the client...
+ */
+
+ pass = cups_crypt(con->password, pw->pw_passwd);
+
+ LogMessage(L_DEBUG2, "IsAuthorized: pw_passwd = %s, crypt = %s",
+ pw->pw_passwd, pass);
+
+ if (pass == NULL || strcmp(pw->pw_passwd, pass) != 0)
+ {
+# ifdef HAVE_SHADOW_H
+ if (spw != NULL)
+ {
+ pass = cups_crypt(con->password, spw->sp_pwdp);
+
+ LogMessage(L_DEBUG2, "IsAuthorized: sp_pwdp = %s, crypt = %s",
+ spw->sp_pwdp, pass);
+
+ if (pass == NULL || strcmp(spw->sp_pwdp, pass) != 0)
+ return (HTTP_UNAUTHORIZED);
+ }
+ else
+# endif /* HAVE_SHADOW_H */
+ return (HTTP_UNAUTHORIZED);
+ }
+#endif /* HAVE_LIBPAM */
+ break;
+
+ case AUTH_DIGEST :
+ /*
+ * Do Digest authentication...
+ */
+
+ if (!httpGetSubField(&(con->http), HTTP_FIELD_AUTHORIZATION, "nonce",
+ nonce))
+ {
+ LogMessage(L_ERROR, "IsAuthorized: No nonce value for Digest authentication!");
+ return (HTTP_UNAUTHORIZED);
+ }
+
+ if (strcmp(con->http.hostname, nonce) != 0)
+ {
+ LogMessage(L_ERROR, "IsAuthorized: Nonce value error!");
+ LogMessage(L_ERROR, "IsAuthorized: Expected \"%s\",",
+ con->http.hostname);
+ LogMessage(L_ERROR, "IsAuthorized: Got \"%s\"!", nonce);
+ return (HTTP_UNAUTHORIZED);
+ }
+
+ LogMessage(L_DEBUG2, "IsAuthorized: nonce = \"%s\"", nonce);
+
+ if (best->num_names && best->level == AUTH_GROUP)
+ {
+ for (i = 0; i < best->num_names; i ++)
+ if (GetMD5Passwd(con->username, best->names[i], md5))
+ break;
+
+ if (i >= best->num_names)
+ md5[0] = '\0';
+ }
+ else if (!GetMD5Passwd(con->username, NULL, md5))
+ md5[0] = '\0';
+
+
+ if (!md5[0])
+ {
+ LogMessage(L_ERROR, "IsAuthorized: No matching user:group for \"%s\" in passwd.md5!",
+ con->username);
+ return (HTTP_UNAUTHORIZED);
+ }
+
+ httpMD5Final(nonce, states[con->http.state], con->uri, md5);
+
+ if (strcmp(md5, con->password) != 0)
+ {
+ LogMessage(L_ERROR, "IsAuthorized: MD5s \"%s\" and \"%s\" don't match!",
+ md5, con->password);
+ return (HTTP_UNAUTHORIZED);
+ }
+ break;
+
+ case AUTH_BASICDIGEST :
+ /*
+ * Do Basic authentication with the Digest password file...
+ */
+
+ if (best->num_names && best->level == AUTH_GROUP)
+ {
+ for (i = 0; i < best->num_names; i ++)
+ if (GetMD5Passwd(con->username, best->names[i], md5))
+ break;
+
+ if (i >= best->num_names)
+ md5[0] = '\0';
+ }
+ else if (!GetMD5Passwd(con->username, NULL, md5))
+ md5[0] = '\0';
+
+ if (!md5[0])
+ {
+ LogMessage(L_ERROR, "IsAuthorized: No matching user:group for \"%s\" in passwd.md5!",
+ con->username);
+ return (HTTP_UNAUTHORIZED);
+ }
+
+ httpMD5(con->username, "CUPS", con->password, basicmd5);
+
+ if (strcmp(md5, basicmd5) != 0)
+ {
+ LogMessage(L_ERROR, "IsAuthorized: MD5s \"%s\" and \"%s\" don't match!",
+ md5, basicmd5);
+ return (HTTP_UNAUTHORIZED);
+ }
+ break;
+ }
+ }
+ else
+ {
+ /*
+ * Get password entry for certificate-based auth...
+ */
+
+ pw = getpwnam(con->username); /* Get the current password */
+ endpwent(); /* Close the password file */
+ }
+
+ /*
+ * OK, the password is good. See if we need normal user access, or group
+ * access... (root always matches)
+ */
+
+ if (strcmp(con->username, "root") == 0)
+ return (HTTP_OK);
+
+ if (best->level == AUTH_USER)
+ {
+ /*
+ * If there are no names associated with this location, then
+ * any valid user is OK...
+ */
+
+ LogMessage(L_DEBUG2, "IsAuthorized: Checking user membership...");
+
+ if (best->num_names == 0)
+ return (HTTP_OK);
+
+ /*
+ * Otherwise check the user list and return OK if this user is
+ * allowed...
+ */
+
+ for (i = 0; i < best->num_names; i ++)
+ if (strcmp(con->username, best->names[i]) == 0)
+ return (HTTP_OK);
+
+ return (HTTP_UNAUTHORIZED);
+ }
+
+ if (best->type == AUTH_BASIC)
+ {
+ /*
+ * Check to see if this user is in any of the named groups...
+ */
+
+ LogMessage(L_DEBUG2, "IsAuthorized: Checking group membership...");
+
+ for (i = 0; i < best->num_names; i ++)
+ {
+ grp = getgrnam(best->names[i]);
+ endgrent();
+
+ if (grp == NULL) /* No group by that name??? */
+ {
+ LogMessage(L_WARN, "IsAuthorized: group name \"%s\" does not exist!",
+ best->names[i]);
+ return (HTTP_FORBIDDEN);
+ }
+
+ for (j = 0; grp->gr_mem[j] != NULL; j ++)
+ if (strcmp(con->username, grp->gr_mem[j]) == 0)
+ return (HTTP_OK);
+
+ /*
+ * Check to see if the default group ID matches for the user...
+ */
+
+ if (grp->gr_gid == pw->pw_gid)
+ return (HTTP_OK);
+ }
+
+ /*
+ * The user isn't part of the specified group, so deny access...
+ */
+
+ LogMessage(L_DEBUG2, "IsAuthorized: user not in group!");
+
+ return (HTTP_UNAUTHORIZED);
+ }
+
+ /*
+ * All checks passed...
+ */
+
+ return (HTTP_OK);
+}
+
+
+/*
+ * 'add_allow()' - Add an allow mask to the location.
+ */
+
+static authmask_t * /* O - New mask record */
+add_allow(location_t *loc) /* I - Location to add to */
+{
+ authmask_t *temp; /* New mask record */
+
+
+ /*
+ * Range-check...
+ */
+
+ if (loc == NULL)
+ return (NULL);
+
+ /*
+ * Try to allocate memory for the record...
+ */
+
+ if (loc->num_allow == 0)
+ temp = malloc(sizeof(authmask_t));
+ else
+ temp = realloc(loc->allow, sizeof(authmask_t) * (loc->num_allow + 1));
+
+ if (temp == NULL)
+ return (NULL);
+
+ loc->allow = temp;
+ temp += loc->num_allow;
+ loc->num_allow ++;
+
+ /*
+ * Clear the mask record and return...
+ */
+
+ memset(temp, 0, sizeof(authmask_t));
+ return (temp);
+}
+
+
+/*
+ * 'add_deny()' - Add a deny mask to the location.
+ */
+
+static authmask_t * /* O - New mask record */
+add_deny(location_t *loc) /* I - Location to add to */
+{
+ authmask_t *temp; /* New mask record */
+
+
+ /*
+ * Range-check...
+ */
+
+ if (loc == NULL)
+ return (NULL);
+
+ /*
+ * Try to allocate memory for the record...
+ */
+
+ if (loc->num_deny == 0)
+ temp = malloc(sizeof(authmask_t));
+ else
+ temp = realloc(loc->deny, sizeof(authmask_t) * (loc->num_deny + 1));
+
+ if (temp == NULL)
+ return (NULL);
+
+ loc->deny = temp;
+ temp += loc->num_deny;
+ loc->num_deny ++;
+
+ /*
+ * Clear the mask record and return...
+ */
+
+ memset(temp, 0, sizeof(authmask_t));
+ return (temp);
+}
+
+
+#if !HAVE_LIBPAM
+/*
+ * 'cups_crypt()' - Encrypt the password using the DES or MD5 algorithms,
+ * as needed.
+ */
+
+static char * /* O - Encrypted password */
+cups_crypt(const char *pw, /* I - Password string */
+ const char *salt) /* I - Salt (key) string */
+{
+ if (strncmp(salt, "$1$", 3) == 0)
+ {
+ /*
+ * Use MD5 passwords without the benefit of PAM; this is for
+ * Slackware Linux, and the algorithm was taken from the
+ * old shadow-19990827/lib/md5crypt.c source code... :(
+ */
+
+ int i; /* Looping var */
+ unsigned long n; /* Output number */
+ int pwlen; /* Length of password string */
+ const char *salt_end; /* End of "salt" data for MD5 */
+ char *ptr; /* Pointer into result string */
+ md5_state_t state; /* Primary MD5 state info */
+ md5_state_t state2; /* Secondary MD5 state info */
+ md5_byte_t digest[16]; /* MD5 digest result */
+ static char result[120]; /* Final password string */
+
+
+ /*
+ * Get the salt data between dollar signs, e.g. $1$saltdata$md5.
+ * Get a maximum of 8 characters of salt data after $1$...
+ */
+
+ for (salt_end = salt + 3; *salt_end && (salt_end - salt) < 11; salt_end ++)
+ if (*salt_end == '$')
+ break;
+
+ /*
+ * Compute the MD5 sum we need...
+ */
+
+ pwlen = strlen(pw);
+
+ md5_init(&state);
+ md5_append(&state, pw, pwlen);
+ md5_append(&state, salt, salt_end - salt);
+
+ md5_init(&state2);
+ md5_append(&state2, pw, pwlen);
+ md5_append(&state2, salt + 3, salt_end - salt - 3);
+ md5_append(&state2, pw, pwlen);
+ md5_finish(&state2, digest);
+
+ for (i = pwlen; i > 0; i -= 16)
+ md5_append(&state, digest, i > 16 ? 16 : i);
+
+ for (i = pwlen; i > 0; i >>= 1)
+ md5_append(&state, (i & 1) ? "" : pw, 1);
+
+ md5_finish(&state, digest);
+
+ for (i = 0; i < 1000; i ++)
+ {
+ md5_init(&state);
+
+ if (i & 1)
+ md5_append(&state, pw, pwlen);
+ else
+ md5_append(&state, digest, 16);
+
+ if (i % 3)
+ md5_append(&state, salt + 3, salt_end - salt - 3);
+
+ if (i % 7)
+ md5_append(&state, pw, pwlen);
+
+ if (i & 1)
+ md5_append(&state, digest, 16);
+ else
+ md5_append(&state, pw, pwlen);
+
+ md5_finish(&state, digest);
+ }
+
+ /*
+ * Copy the final sum to the result string and return...
+ */
+
+ memcpy(result, salt, salt_end - salt);
+ ptr = result + (salt_end - salt);
+ *ptr++ = '$';
+
+ for (i = 0; i < 5; i ++, ptr += 4)
+ {
+ n = (((digest[i] << 8) | digest[i + 6]) << 8);
+
+ if (i < 4)
+ n |= digest[i + 12];
+ else
+ n |= digest[5];
+
+ to64(ptr, n, 4);
+ }
+
+ to64(ptr, digest[11], 2);
+ ptr += 2;
+ *ptr = '\0';
+
+ return (result);
+ }
+ else
+ {
+ /*
+ * Use the standard crypt() function...
+ */
+
+ return (crypt(pw, salt));
+ }
+}
+#endif /* !HAVE_LIBPAM */
+
+
+#if HAVE_LIBPAM
+/*
+ * 'pam_func()' - PAM conversation function.
+ */
+
+static int /* O - Success or failure */
+pam_func(int num_msg, /* I - Number of messages */
+ const struct pam_message **msg, /* I - Messages */
+ struct pam_response **resp, /* O - Responses */
+ void *appdata_ptr) /* I - Pointer to connection */
+{
+ int i; /* Looping var */
+ struct pam_response *replies; /* Replies */
+ client_t *client; /* Pointer client connection */
+
+
+ /*
+ * Allocate memory for the responses...
+ */
+
+ if ((replies = malloc(sizeof(struct pam_response) * num_msg)) == NULL)
+ return (PAM_CONV_ERR);
+
+ /*
+ * Answer all of the messages...
+ */
+
+ DEBUG_printf(("pam_func: appdata_ptr = %p\n", appdata_ptr));
+
+#ifdef __hpux
+ /*
+ * Apparently some versions of HP-UX 11 have a broken pam_unix security
+ * module. This is a workaround...
+ */
+
+ client = auth_client;
+ (void)appdata_ptr;
+#else
+ client = (client_t *)appdata_ptr;
+#endif /* __hpux */
+
+ for (i = 0; i < num_msg; i ++)
+ {
+ DEBUG_printf(("pam_func: Message = \"%s\"\n", msg[i]->msg));
+
+ switch (msg[i]->msg_style)
+ {
+ case PAM_PROMPT_ECHO_ON:
+ DEBUG_printf(("pam_func: PAM_PROMPT_ECHO_ON, returning \"%s\"...\n",
+ client->username));
+ replies[i].resp_retcode = PAM_SUCCESS;
+ replies[i].resp = strdup(client->username);
+ break;
+
+ case PAM_PROMPT_ECHO_OFF:
+ DEBUG_printf(("pam_func: PAM_PROMPT_ECHO_OFF, returning \"%s\"...\n",
+ client->password));
+ replies[i].resp_retcode = PAM_SUCCESS;
+ replies[i].resp = strdup(client->password);
+ break;
+
+ case PAM_TEXT_INFO:
+ DEBUG_puts("pam_func: PAM_TEXT_INFO...");
+ replies[i].resp_retcode = PAM_SUCCESS;
+ replies[i].resp = NULL;
+ break;
+
+ case PAM_ERROR_MSG:
+ DEBUG_puts("pam_func: PAM_ERROR_MSG...");
+ replies[i].resp_retcode = PAM_SUCCESS;
+ replies[i].resp = NULL;
+ break;
+
+ default:
+ DEBUG_printf(("pam_func: Unknown PAM message %d...\n",
+ msg[i]->msg_style));
+ free(replies);
+ return (PAM_CONV_ERR);
+ }
+ }
+
+ /*
+ * Return the responses back to PAM...
+ */
+
+ *resp = replies;
+
+ return (PAM_SUCCESS);
+}
+#else
+
+
+/*
+ * 'to64()' - Base64-encode an integer value...
+ */
+
+static void
+to64(char *s, /* O - Output string */
+ unsigned long v, /* I - Value to encode */
+ int n) /* I - Number of digits */
+{
+ const char *itoa64 = "./0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+
+
+ for (; n > 0; n --, v >>= 6)
+ *s++ = itoa64[v & 0x3f];
+}
+#endif /* HAVE_LIBPAM */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/auth.h b/scheduler/auth.h
new file mode 100644
index 000000000..0e3468099
--- /dev/null
+++ b/scheduler/auth.h
@@ -0,0 +1,139 @@
+/*
+ * "$Id$"
+ *
+ * Authorization definitions for the Common UNIX Printing System (CUPS)
+ * scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * HTTP authorization types and levels...
+ */
+
+#define AUTH_NONE 0 /* No authentication */
+#define AUTH_BASIC 1 /* Basic authentication */
+#define AUTH_DIGEST 2 /* Digest authentication */
+#define AUTH_BASICDIGEST 3 /* Basic authentication w/passwd.md5 */
+
+#define AUTH_ANON 0 /* Anonymous access */
+#define AUTH_USER 1 /* Must have a valid username/password */
+#define AUTH_GROUP 2 /* Must also be in a named group */
+
+#define AUTH_ALLOW 0 /* Allow access */
+#define AUTH_DENY 1 /* Deny access */
+
+#define AUTH_NAME 0 /* Authorize host by name */
+#define AUTH_IP 1 /* Authorize host by IP */
+#define AUTH_INTERFACE 2 /* Authorize host by interface */
+
+#define AUTH_SATISFY_ALL 0 /* Satisfy both address and auth */
+#define AUTH_SATISFY_ANY 1 /* Satisfy either address or auth */
+
+#define AUTH_LIMIT_DELETE 1 /* Limit DELETE requests */
+#define AUTH_LIMIT_GET 2 /* Limit GET requests */
+#define AUTH_LIMIT_HEAD 4 /* Limit HEAD requests */
+#define AUTH_LIMIT_OPTIONS 8 /* Limit OPTIONS requests */
+#define AUTH_LIMIT_POST 16 /* Limit POST requests */
+#define AUTH_LIMIT_PUT 32 /* Limit PUT requests */
+#define AUTH_LIMIT_TRACE 64 /* Limit TRACE requests */
+#define AUTH_LIMIT_ALL 127 /* Limit all requests */
+
+
+/*
+ * HTTP access control structures...
+ */
+
+typedef struct
+{
+ unsigned address, /* IP address */
+ netmask; /* IP netmask */
+} ipmask_t;
+
+typedef struct
+{
+ int length; /* Length of name */
+ char *name; /* Name string */
+} namemask_t;
+
+typedef struct
+{
+ int type; /* Mask type */
+ union
+ {
+ namemask_t name; /* Host/Domain name */
+ ipmask_t ip; /* IP address/network */
+ } mask; /* Mask data */
+} authmask_t;
+
+typedef struct
+{
+ char location[HTTP_MAX_URI]; /* Location of resource */
+ int limit, /* Limit for these types of requests */
+ length, /* Length of location string */
+ order_type, /* Allow or Deny */
+ type, /* Type of authentication */
+ level, /* Access level required */
+ satisfy; /* Satisfy any or all limits? */
+ int num_names; /* Number of names */
+ char **names; /* User or group names */
+ int num_allow; /* Number of Allow lines */
+ authmask_t *allow; /* Allow lines */
+ int num_deny; /* Number of Deny lines */
+ authmask_t *deny; /* Deny lines */
+ http_encryption_t encryption; /* To encrypt or not to encrypt... */
+} location_t;
+
+
+/*
+ * Globals...
+ */
+
+VAR int NumLocations VALUE(0);
+ /* Number of authorization locations */
+VAR location_t *Locations VALUE(NULL);
+ /* Authorization locations */
+
+
+/*
+ * Prototypes...
+ */
+
+extern location_t *AddLocation(const char *location);
+extern void AddName(location_t *loc, char *name);
+extern void AllowHost(location_t *loc, char *name);
+extern void AllowIP(location_t *loc, unsigned address,
+ unsigned netmask);
+extern int CheckAuth(unsigned ip, char *name, int namelen,
+ int num_masks, authmask_t *masks);
+extern location_t *CopyLocation(location_t **loc);
+extern void DeleteAllLocations(void);
+extern void DenyHost(location_t *loc, char *name);
+extern void DenyIP(location_t *loc, unsigned address,
+ unsigned netmask);
+extern location_t *FindBest(const char *path, http_state_t state);
+extern location_t *FindLocation(const char *location);
+extern char *GetMD5Passwd(const char *username, const char *group,
+ char passwd[33]);
+extern http_status_t IsAuthorized(client_t *con);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/banners.c b/scheduler/banners.c
new file mode 100644
index 000000000..228c6991d
--- /dev/null
+++ b/scheduler/banners.c
@@ -0,0 +1,215 @@
+/*
+ * "$Id$"
+ *
+ * Banner routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * AddBanner() - Add a banner to the array.
+ * FindBanner() - Find a named banner.
+ * LoadBanners() - Load all available banner files...
+ * compare() - Compare two banners.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+
+
+/*
+ * Local functions...
+ */
+
+static int compare(const banner_t *b0, const banner_t *b1);
+
+
+/*
+ * 'AddBanner()' - Add a banner to the array.
+ */
+
+void
+AddBanner(const char *name, /* I - Name of banner */
+ const char *filename) /* I - Filename for banner */
+{
+ mime_type_t *filetype; /* Filetype */
+ banner_t *temp; /* New banner data */
+
+
+ /*
+ * See what the filetype is...
+ */
+
+ if ((filetype = mimeFileType(MimeDatabase, filename)) == NULL)
+ {
+ LogMessage(L_WARN, "AddBanner: Banner \"%s\" is of an unknown file type - skipping!",
+ name);
+ return;
+ }
+
+ /*
+ * Allocate memory...
+ */
+
+ if (NumBanners == 0)
+ temp = malloc(sizeof(banner_t));
+ else
+ temp = realloc(Banners, sizeof(banner_t) * (NumBanners + 1));
+
+ if (temp == NULL)
+ {
+ LogMessage(L_ERROR, "AddBanner: Ran out of memory adding a banner!");
+ return;
+ }
+
+ /*
+ * Copy the new banner data over...
+ */
+
+ Banners = temp;
+ temp += NumBanners;
+ NumBanners ++;
+
+ memset(temp, 0, sizeof(banner_t));
+ strlcpy(temp->name, name, sizeof(temp->name));
+ temp->filetype = filetype;
+}
+
+
+/*
+ * 'FindBanner()' - Find a named banner.
+ */
+
+banner_t * /* O - Pointer to banner or NULL */
+FindBanner(const char *name) /* I - Name of banner */
+{
+ banner_t key; /* Search key */
+
+
+ strlcpy(key.name, name, sizeof(key.name));
+
+ return ((banner_t *)bsearch(&key, Banners, NumBanners, sizeof(banner_t),
+ (int (*)(const void *, const void *))compare));
+}
+
+
+/*
+ * 'LoadBanners()' - Load all available banner files...
+ */
+
+void
+LoadBanners(const char *d) /* I - Directory to search */
+{
+ DIR *dir; /* Directory pointer */
+ DIRENT *dent; /* Directory entry */
+ char filename[1024], /* Name of banner */
+ *ext; /* Pointer to extension */
+ struct stat fileinfo; /* File information */
+
+
+ /*
+ * Free old banner info...
+ */
+
+ if (NumBanners)
+ {
+ free(Banners);
+ NumBanners = 0;
+ }
+
+ /*
+ * Try opening the banner directory...
+ */
+
+ if ((dir = opendir(d)) == NULL)
+ {
+ LogMessage(L_ERROR, "LoadBanners: Unable to open banner directory \"%s\": %s",
+ d, strerror(errno));
+ return;
+ }
+
+ /*
+ * Read entries, skipping directories and backup files.
+ */
+
+ while ((dent = readdir(dir)) != NULL)
+ {
+ /*
+ * Check the file to make sure it isn't a directory or a backup
+ * file of some sort...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/%s", d, dent->d_name);
+
+ if (stat(filename, &fileinfo))
+ {
+ LogMessage(L_WARN, "LoadBanners: Unable to state \"%s\" banner: %s",
+ dent->d_name, strerror(errno));
+ continue;
+ }
+
+ if (S_ISDIR(fileinfo.st_mode))
+ continue;
+
+ if (dent->d_name[0] == '~')
+ continue;
+
+ if ((ext = strrchr(dent->d_name, '.')) != NULL)
+ if (strcmp(ext, ".bck") == 0 ||
+ strcmp(ext, ".bak") == 0 ||
+ strcmp(ext, ".sav") == 0)
+ continue;
+
+ /*
+ * Must be a valid file; add it!
+ */
+
+ AddBanner(dent->d_name, filename);
+ }
+
+ /*
+ * Close the directory and sort as needed...
+ */
+
+ closedir(dir);
+
+ if (NumBanners > 1)
+ qsort(Banners, NumBanners, sizeof(banner_t),
+ (int (*)(const void *, const void *))compare);
+}
+
+
+/*
+ * 'compare()' - Compare two banners.
+ */
+
+static int /* O - -1 if name0 < name1, etc. */
+compare(const banner_t *b0, /* I - First banner */
+ const banner_t *b1) /* I - Second banner */
+{
+ return (strcasecmp(b0->name, b1->name));
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/banners.h b/scheduler/banners.h
new file mode 100644
index 000000000..ababc82c5
--- /dev/null
+++ b/scheduler/banners.h
@@ -0,0 +1,57 @@
+/*
+ * "$Id$"
+ *
+ * Banner definitions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Banner information structure...
+ */
+
+typedef struct
+{
+ char name[256]; /* Name of banner */
+ mime_type_t *filetype; /* Filetype for banner */
+} banner_t;
+
+
+/*
+ * Globals...
+ */
+
+VAR int NumBanners VALUE(0);
+ /* Number of banner files available */
+VAR banner_t *Banners VALUE(NULL);
+ /* Available banner files */
+
+
+/*
+ * Prototypes...
+ */
+
+extern void AddBanner(const char *name, const char *filename);
+extern banner_t *FindBanner(const char *name);
+extern void LoadBanners(const char *d);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/cert.c b/scheduler/cert.c
new file mode 100644
index 000000000..836f3e0cc
--- /dev/null
+++ b/scheduler/cert.c
@@ -0,0 +1,276 @@
+/*
+ * "$Id$"
+ *
+ * Authentication certificate routines for the Common UNIX
+ * Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * AddCert() - Add a certificate.
+ * DeleteCert() - Delete a single certificate.
+ * DeleteAllCerts() - Delete all certificates...
+ * FindCert() - Find a certificate.
+ * InitCerts() - Initialize the certificate "system" and root
+ * certificate.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+#include <grp.h>
+
+
+/*
+ * 'AddCert()' - Add a certificate.
+ */
+
+void
+AddCert(int pid, /* I - Process ID */
+ const char *username) /* I - Username */
+{
+ int i; /* Looping var */
+ cert_t *cert; /* Current certificate */
+ FILE *fp; /* Certificate file */
+ char filename[1024]; /* Certificate filename */
+ struct group *grp; /* System group */
+ static const char *hex = "0123456789ABCDEF";
+ /* Hex constants... */
+
+
+ /*
+ * Allocate memory for the certificate...
+ */
+
+ if ((cert = calloc(sizeof(cert_t), 1)) == NULL)
+ return;
+
+ /*
+ * Fill in the certificate information...
+ */
+
+ cert->pid = pid;
+ strlcpy(cert->username, username, sizeof(cert->username));
+
+ for (i = 0; i < 32; i ++)
+ cert->certificate[i] = hex[random() & 15];
+
+ /*
+ * Save the certificate to a file readable only by the User and Group
+ * (or root and SystemGroup for PID == 0)...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, pid);
+
+ if ((fp = fopen(filename, "w")) == NULL)
+ {
+ free(cert);
+ return;
+ }
+
+ if (pid == 0)
+ {
+ /*
+ * Root certificate...
+ */
+
+ fchmod(fileno(fp), 0440);
+
+ if ((grp = getgrnam(SystemGroups[0])) == NULL)
+ fchown(fileno(fp), getuid(), 0);
+ else
+ fchown(fileno(fp), getuid(), grp->gr_gid);
+
+ endgrent();
+
+ RootCertTime = time(NULL);
+ }
+ else
+ {
+ /*
+ * CGI certificate...
+ */
+
+ fchmod(fileno(fp), 0400);
+ fchown(fileno(fp), User, Group);
+ }
+
+ fputs(cert->certificate, fp);
+ fclose(fp);
+
+ /*
+ * Insert the certificate at the front of the list...
+ */
+
+ cert->next = Certs;
+ Certs = cert;
+}
+
+
+/*
+ * 'DeleteCert()' - Delete a single certificate.
+ */
+
+void
+DeleteCert(int pid) /* I - Process ID */
+{
+ cert_t *cert, /* Current certificate */
+ *prev; /* Previous certificate */
+ char filename[1024]; /* Certificate file */
+
+
+ for (prev = NULL, cert = Certs; cert != NULL; prev = cert, cert = cert->next)
+ if (cert->pid == pid)
+ {
+ /*
+ * Remove this certificate from the list...
+ */
+
+ if (prev == NULL)
+ Certs = cert->next;
+ else
+ prev->next = cert->next;
+
+ free(cert);
+
+ /*
+ * Delete the file and return...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, pid);
+ unlink(filename);
+
+ return;
+ }
+}
+
+
+/*
+ * 'DeleteAllCerts()' - Delete all certificates...
+ */
+
+void
+DeleteAllCerts(void)
+{
+ cert_t *cert, /* Current certificate */
+ *next; /* Next certificate */
+ char filename[1024]; /* Certificate file */
+
+
+ /*
+ * Loop through each certificate, deleting them...
+ */
+
+ for (cert = Certs; cert != NULL; cert = next)
+ {
+ /*
+ * Delete the file...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, cert->pid);
+ unlink(filename);
+
+ /*
+ * Free memory...
+ */
+
+ next = cert->next;
+ free(cert);
+ }
+
+ Certs = NULL;
+}
+
+
+/*
+ * 'FindCert()' - Find a certificate.
+ */
+
+const char * /* O - Matching username or NULL */
+FindCert(const char *certificate) /* I - Certificate */
+{
+ cert_t *cert; /* Current certificate */
+
+
+ for (cert = Certs; cert != NULL; cert = cert->next)
+ if (strcasecmp(certificate, cert->certificate) == 0)
+ return (cert->username);
+
+ return (NULL);
+}
+
+
+/*
+ * 'InitCerts()' - Initialize the certificate "system" and root certificate.
+ */
+
+void
+InitCerts(void)
+{
+ FILE *fp; /* /dev/random file */
+ unsigned seed; /* Seed for random number generator */
+ struct timeval tod; /* Time of day */
+
+
+ /*
+ * Initialize the random number generator using the random device or
+ * the current time, as available...
+ */
+
+ if ((fp = fopen("/dev/urandom", "rb")) == NULL)
+ {
+ /*
+ * Get the time in usecs and use it as the initial seed...
+ */
+
+ gettimeofday(&tod, NULL);
+
+ seed = (unsigned)(tod.tv_sec + tod.tv_usec);
+ }
+ else
+ {
+ /*
+ * Read 4 random characters from the random device and use
+ * them as the seed...
+ */
+
+ seed = getc(fp);
+ seed = (seed << 8) | getc(fp);
+ seed = (seed << 8) | getc(fp);
+ seed = (seed << 8) | getc(fp);
+
+ fclose(fp);
+ }
+
+ srandom(seed);
+
+ /*
+ * Create a root certificate and return...
+ */
+
+ AddCert(0, "root");
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/cert.h b/scheduler/cert.h
new file mode 100644
index 000000000..d078d53cc
--- /dev/null
+++ b/scheduler/cert.h
@@ -0,0 +1,60 @@
+/*
+ * "$Id$"
+ *
+ * Authentication certificate definitions for the Common UNIX
+ * Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Certificate structure...
+ */
+
+typedef struct cert_str
+{
+ struct cert_str *next; /* Next certificate in list */
+ int pid; /* Process ID (0 for root certificate) */
+ char certificate[33];/* 32 hex characters, or 128 bits */
+ char username[33]; /* Authenticated username */
+} cert_t;
+
+
+/*
+ * Globals...
+ */
+
+VAR cert_t *Certs; /* List of certificates */
+VAR time_t RootCertTime; /* Root certificate update time */
+
+
+/*
+ * Prototypes...
+ */
+
+extern void AddCert(int pid, const char *username);
+extern void DeleteCert(int pid);
+extern void DeleteAllCerts(void);
+extern const char *FindCert(const char *certificate);
+extern void InitCerts(void);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/classes.c b/scheduler/classes.c
new file mode 100644
index 000000000..aa2b08fc1
--- /dev/null
+++ b/scheduler/classes.c
@@ -0,0 +1,695 @@
+/*
+ * "$Id$"
+ *
+ * Printer class routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * AddClass() - Add a class to the system.
+ * AddPrinterToClass() - Add a printer to a class...
+ * DeletePrinterFromClass() - Delete a printer from a class.
+ * DeletePrinterFromClasses() - Delete a printer from all classes.
+ * DeleteAllClasses() - Remove all classes from the system.
+ * FindAvailablePrinter() - Find an available printer in a class.
+ * FindClass() - Find the named class.
+ * LoadAllClasses() - Load classes from the classes.conf file.
+ * SaveAllClasses() - Save classes to the classes.conf file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+
+
+/*
+ * 'AddClass()' - Add a class to the system.
+ */
+
+printer_t * /* O - New class */
+AddClass(const char *name) /* I - Name of class */
+{
+ printer_t *c; /* New class */
+
+
+ /*
+ * Add the printer and set the type to "class"...
+ */
+
+ if ((c = AddPrinter(name)) != NULL)
+ {
+ /*
+ * Change from a printer to a class...
+ */
+
+ c->type = CUPS_PRINTER_CLASS;
+ snprintf(c->uri, sizeof(c->uri), "ipp://%s:%d/classes/%s", ServerName,
+ ntohs(Listeners[0].address.sin_port), name);
+
+ /*
+ * Set the printer attributes to make this a class.
+ */
+
+ SetPrinterAttrs(c);
+ }
+
+ return (c);
+}
+
+
+/*
+ * 'AddPrinterToClass()' - Add a printer to a class...
+ */
+
+void
+AddPrinterToClass(printer_t *c, /* I - Class to add to */
+ printer_t *p) /* I - Printer to add */
+{
+ int i; /* Looping var */
+ printer_t **temp; /* Pointer to printer array */
+
+
+ /*
+ * See if this printer is already a member of the class...
+ */
+
+ for (i = 0; i < c->num_printers; i ++)
+ if (c->printers[i] == p)
+ return;
+
+ /*
+ * Allocate memory as needed...
+ */
+
+ if (c->num_printers == 0)
+ temp = malloc(sizeof(printer_t *));
+ else
+ temp = realloc(c->printers, sizeof(printer_t *) * (c->num_printers + 1));
+
+ if (temp == NULL)
+ {
+ LogMessage(L_ERROR, "Unable to add printer %s to class %s!",
+ p->name, c->name);
+ return;
+ }
+
+ /*
+ * Add the printer to the end of the array and update the number of printers.
+ */
+
+ c->printers = temp;
+ temp += c->num_printers;
+ c->num_printers ++;
+
+ *temp = p;
+
+ /*
+ * Update the IPP attributes...
+ */
+
+ SetPrinterAttrs(c);
+}
+
+
+/*
+ * 'DeletePrinterFromClass()' - Delete a printer from a class.
+ */
+
+void
+DeletePrinterFromClass(printer_t *c, /* I - Class to delete from */
+ printer_t *p) /* I - Printer to delete */
+{
+ int i; /* Looping var */
+ cups_ptype_t type; /* Class type */
+
+
+ /*
+ * See if the printer is in the class...
+ */
+
+ for (i = 0; i < c->num_printers; i ++)
+ if (p == c->printers[i])
+ break;
+
+ /*
+ * If it is, remove it from the list...
+ */
+
+ if (i < c->num_printers)
+ {
+ /*
+ * Yes, remove the printer...
+ */
+
+ c->num_printers --;
+ if (i < c->num_printers)
+ memcpy(c->printers + i, c->printers + i + 1,
+ (c->num_printers - i) * sizeof(printer_t *));
+ }
+
+ /*
+ * Recompute the printer type mask as needed...
+ */
+
+ if (c->num_printers > 0)
+ {
+ type = c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT);
+ c->type = ~CUPS_PRINTER_REMOTE;
+
+ for (i = 0; i < c->num_printers; i ++)
+ c->type &= c->printers[i]->type;
+
+ c->type |= type;
+
+ /*
+ * Update the IPP attributes...
+ */
+
+ SetPrinterAttrs(c);
+ }
+}
+
+
+/*
+ * 'DeletePrinterFromClasses()' - Delete a printer from all classes.
+ */
+
+void
+DeletePrinterFromClasses(printer_t *p) /* I - Printer to delete */
+{
+ printer_t *c, /* Pointer to current class */
+ *next; /* Pointer to next class */
+
+
+ /*
+ * Loop through the printer/class list and remove the printer
+ * from each class listed...
+ */
+
+ for (c = Printers; c != NULL; c = next)
+ {
+ next = c->next;
+
+ if (c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+ DeletePrinterFromClass(c, p);
+ }
+
+ /*
+ * Then clean out any empty classes...
+ */
+
+ for (c = Printers; c != NULL; c = next)
+ {
+ next = c->next;
+
+ if ((c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) &&
+ c->num_printers == 0)
+ DeletePrinter(c);
+ }
+}
+
+
+/*
+ * 'DeleteAllClasses()' - Remove all classes from the system.
+ */
+
+void
+DeleteAllClasses(void)
+{
+ printer_t *c, /* Pointer to current printer/class */
+ *next; /* Pointer to next printer in list */
+
+
+ for (c = Printers; c != NULL; c = next)
+ {
+ next = c->next;
+
+ if (c->type & CUPS_PRINTER_CLASS)
+ DeletePrinter(c);
+ }
+}
+
+
+/*
+ * 'FindAvailablePrinter()' - Find an available printer in a class.
+ */
+
+printer_t * /* O - Available printer or NULL */
+FindAvailablePrinter(const char *name) /* I - Class to check */
+{
+ int i; /* Looping var */
+ printer_t *c; /* Printer class */
+
+
+ /*
+ * Find the class...
+ */
+
+ if ((c = FindClass(name)) == NULL)
+ {
+ LogMessage(L_ERROR, "Unable to find class \"%s\"!", name);
+ return (NULL);
+ }
+
+ /*
+ * Loop through the printers in the class and return the first idle
+ * printer... We keep track of the last printer that we used so that
+ * a "round robin" type of scheduling is realized (otherwise the first
+ * server might be saturated with print jobs...)
+ *
+ * Thanks to Joel Fredrikson for helping us get this right!
+ */
+
+ for (i = c->last_printer + 1; ; i ++)
+ {
+ if (i >= c->num_printers)
+ i = 0;
+
+ if (c->printers[i]->state == IPP_PRINTER_IDLE ||
+ ((c->printers[i]->type & CUPS_PRINTER_REMOTE) && !c->printers[i]->job))
+ {
+ c->last_printer = i;
+ return (c->printers[i]);
+ }
+
+ if (i == c->last_printer)
+ break;
+ }
+
+ return (NULL);
+}
+
+
+/*
+ * 'FindClass()' - Find the named class.
+ */
+
+printer_t * /* O - Matching class or NULL */
+FindClass(const char *name) /* I - Name of class */
+{
+ printer_t *c; /* Current class/printer */
+
+
+ for (c = Printers; c != NULL; c = c->next)
+ switch (strcasecmp(name, c->name))
+ {
+ case 0 : /* name == c->name */
+ if (c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+ return (c);
+ case 1 : /* name > c->name */
+ break;
+ case -1 : /* name < c->name */
+ return (NULL);
+ }
+
+ return (NULL);
+}
+
+
+/*
+ * 'LoadAllClasses()' - Load classes from the classes.conf file.
+ */
+
+void
+LoadAllClasses(void)
+{
+ FILE *fp; /* classes.conf file */
+ int linenum; /* Current line number */
+ int len; /* Length of line */
+ char line[1024], /* Line from file */
+ name[256], /* Parameter name */
+ *nameptr, /* Pointer into name */
+ *value, /* Pointer to value */
+ *valueptr; /* Pointer into value */
+ printer_t *p, /* Current printer class */
+ *temp; /* Temporary pointer to printer */
+
+
+ /*
+ * Open the classes.conf file...
+ */
+
+ snprintf(line, sizeof(line), "%s/classes.conf", ServerRoot);
+ if ((fp = fopen(line, "r")) == NULL)
+ return;
+
+ /*
+ * Read class configurations until we hit EOF...
+ */
+
+ linenum = 0;
+ p = NULL;
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ linenum ++;
+
+ /*
+ * Skip comment lines...
+ */
+
+ if (line[0] == '#')
+ continue;
+
+ /*
+ * Strip trailing whitespace, if any...
+ */
+
+ len = strlen(line);
+
+ while (len > 0 && isspace(line[len - 1]))
+ {
+ len --;
+ line[len] = '\0';
+ }
+
+ /*
+ * Extract the name from the beginning of the line...
+ */
+
+ for (value = line; isspace(*value); value ++);
+
+ for (nameptr = name; *value != '\0' && !isspace(*value) &&
+ nameptr < (name + sizeof(name) - 1);)
+ *nameptr++ = *value++;
+ *nameptr = '\0';
+
+ while (isspace(*value))
+ value ++;
+
+ if (name[0] == '\0')
+ continue;
+
+ /*
+ * Decode the directive...
+ */
+
+ if (strcmp(name, "<Class") == 0 ||
+ strcmp(name, "<DefaultClass") == 0)
+ {
+ /*
+ * <Class name> or <DefaultClass name>
+ */
+
+ if (line[len - 1] == '>' && p == NULL)
+ {
+ line[len - 1] = '\0';
+
+ p = AddClass(value);
+ p->accepting = 1;
+ p->state = IPP_PRINTER_IDLE;
+
+ if (strcmp(name, "<DefaultClass") == 0)
+ DefaultPrinter = p;
+ }
+ else
+ {
+ LogMessage(L_ERROR, "Syntax error on line %d of classes.conf.",
+ linenum);
+ return;
+ }
+ }
+ else if (strcmp(name, "</Class>") == 0)
+ {
+ if (p != NULL)
+ {
+ SetPrinterAttrs(p);
+ p = NULL;
+ }
+ else
+ {
+ LogMessage(L_ERROR, "Syntax error on line %d of classes.conf.",
+ linenum);
+ return;
+ }
+ }
+ else if (p == NULL)
+ {
+ LogMessage(L_ERROR, "Syntax error on line %d of classes.conf.",
+ linenum);
+ return;
+ }
+
+ else if (strcmp(name, "Info") == 0)
+ strlcpy(p->info, value, sizeof(p->info));
+ else if (strcmp(name, "Location") == 0)
+ strlcpy(p->location, value, sizeof(p->location));
+ else if (strcmp(name, "Printer") == 0)
+ {
+ if ((temp = FindPrinter(value)) == NULL)
+ {
+ LogMessage(L_WARN, "Unknown printer %s on line %d of classes.conf.",
+ value, linenum);
+
+ /*
+ * Add the missing remote printer...
+ */
+
+ temp = AddPrinter(value);
+ strcpy(temp->make_model, "Remote Printer on unknown");
+
+ temp->state = IPP_PRINTER_STOPPED;
+ temp->type |= CUPS_PRINTER_REMOTE;
+ temp->browse_time = 2147483647;
+
+ strcpy(temp->location, "Location Unknown");
+ strcpy(temp->info, "No Information Available");
+ temp->hostname[0] = '\0';
+
+ SetPrinterAttrs(temp);
+ }
+
+ if (temp)
+ AddPrinterToClass(p, temp);
+ }
+ else if (strcmp(name, "State") == 0)
+ {
+ /*
+ * Set the initial queue state...
+ */
+
+ if (strcasecmp(value, "idle") == 0)
+ p->state = IPP_PRINTER_IDLE;
+ else if (strcasecmp(value, "stopped") == 0)
+ p->state = IPP_PRINTER_STOPPED;
+ }
+ else if (strcmp(name, "StateMessage") == 0)
+ {
+ /*
+ * Set the initial queue state message...
+ */
+
+ while (isspace(*value))
+ value ++;
+
+ strlcpy(p->state_message, value, sizeof(p->state_message));
+ }
+ else if (strcmp(name, "Accepting") == 0)
+ {
+ /*
+ * Set the initial accepting state...
+ */
+
+ if (strcasecmp(value, "yes") == 0)
+ p->accepting = 1;
+ else
+ p->accepting = 0;
+ }
+ else if (strcmp(name, "JobSheets") == 0)
+ {
+ /*
+ * Set the initial job sheets...
+ */
+
+ for (valueptr = value; *valueptr && !isspace(*valueptr); valueptr ++);
+
+ if (*valueptr)
+ *valueptr++ = '\0';
+
+ strlcpy(p->job_sheets[0], value, sizeof(p->job_sheets[0]));
+
+ while (isspace(*valueptr))
+ valueptr ++;
+
+ if (*valueptr)
+ {
+ for (value = valueptr; *valueptr && !isspace(*valueptr); valueptr ++);
+
+ if (*valueptr)
+ *valueptr++ = '\0';
+
+ strlcpy(p->job_sheets[1], value, sizeof(p->job_sheets[1]));
+ }
+ }
+ else if (strcmp(name, "AllowUser") == 0)
+ {
+ p->deny_users = 0;
+ AddPrinterUser(p, value);
+ }
+ else if (strcmp(name, "DenyUser") == 0)
+ {
+ p->deny_users = 1;
+ AddPrinterUser(p, value);
+ }
+ else if (strcmp(name, "QuotaPeriod") == 0)
+ p->quota_period = atoi(value);
+ else if (strcmp(name, "PageLimit") == 0)
+ p->page_limit = atoi(value);
+ else if (strcmp(name, "KLimit") == 0)
+ p->k_limit = atoi(value);
+ else
+ {
+ /*
+ * Something else we don't understand...
+ */
+
+ LogMessage(L_ERROR, "Unknown configuration directive %s on line %d of classes.conf.",
+ name, linenum);
+ }
+ }
+
+ fclose(fp);
+}
+
+
+/*
+ * 'SaveAllClasses()' - Save classes to the classes.conf file.
+ */
+
+void
+SaveAllClasses(void)
+{
+ FILE *fp; /* classes.conf file */
+ char temp[1024]; /* Temporary string */
+ char backup[1024]; /* classes.conf.O file */
+ printer_t *pclass; /* Current printer class */
+ int i; /* Looping var */
+ time_t curtime; /* Current time */
+ struct tm *curdate; /* Current date */
+
+
+ /*
+ * Create the classes.conf file...
+ */
+
+ snprintf(temp, sizeof(temp), "%s/classes.conf", ServerRoot);
+ snprintf(backup, sizeof(backup), "%s/classes.conf.O", ServerRoot);
+
+ if (rename(temp, backup))
+ LogMessage(L_ERROR, "Unable to backup classes.conf - %s", strerror(errno));
+
+ if ((fp = fopen(temp, "w")) == NULL)
+ {
+ LogMessage(L_ERROR, "Unable to save classes.conf - %s", strerror(errno));
+
+ if (rename(backup, temp))
+ LogMessage(L_ERROR, "Unable to restore classes.conf - %s", strerror(errno));
+ return;
+ }
+ else
+ LogMessage(L_INFO, "Saving classes.conf...");
+
+ /*
+ * Restrict access to the file...
+ */
+
+ fchown(fileno(fp), User, Group);
+ fchmod(fileno(fp), 0600);
+
+ /*
+ * Write a small header to the file...
+ */
+
+ curtime = time(NULL);
+ curdate = gmtime(&curtime);
+ strftime(temp, sizeof(temp) - 1, CUPS_STRFTIME_FORMAT, curdate);
+
+ fputs("# Class configuration file for " CUPS_SVERSION "\n", fp);
+ fprintf(fp, "# Written by cupsd on %s\n", temp);
+
+ /*
+ * Write each local class known to the system...
+ */
+
+ for (pclass = Printers; pclass != NULL; pclass = pclass->next)
+ {
+ /*
+ * Skip remote destinations and regular printers...
+ */
+
+ if ((pclass->type & CUPS_PRINTER_REMOTE) ||
+ (pclass->type & CUPS_PRINTER_IMPLICIT) ||
+ !(pclass->type & CUPS_PRINTER_CLASS))
+ continue;
+
+ /*
+ * Write printers as needed...
+ */
+
+ if (pclass == DefaultPrinter)
+ fprintf(fp, "<DefaultClass %s>\n", pclass->name);
+ else
+ fprintf(fp, "<Class %s>\n", pclass->name);
+
+ if (pclass->info[0])
+ fprintf(fp, "Info %s\n", pclass->info);
+
+ if (pclass->location[0])
+ fprintf(fp, "Location %s\n", pclass->location);
+
+ if (pclass->state == IPP_PRINTER_STOPPED)
+ {
+ fputs("State Stopped\n", fp);
+ fprintf(fp, "StateMessage %s\n", pclass->state_message);
+ }
+ else
+ fputs("State Idle\n", fp);
+
+ if (pclass->accepting)
+ fputs("Accepting Yes\n", fp);
+ else
+ fputs("Accepting No\n", fp);
+
+ fprintf(fp, "JobSheets %s %s\n", pclass->job_sheets[0],
+ pclass->job_sheets[1]);
+
+ for (i = 0; i < pclass->num_printers; i ++)
+ fprintf(fp, "Printer %s\n", pclass->printers[i]->name);
+
+ fprintf(fp, "QuotaPeriod %d\n", pclass->quota_period);
+ fprintf(fp, "PageLimit %d\n", pclass->page_limit);
+ fprintf(fp, "KLimit %d\n", pclass->k_limit);
+
+ for (i = 0; i < pclass->num_users; i ++)
+ fprintf(fp, "%sUser %s\n", pclass->deny_users ? "Deny" : "Allow",
+ pclass->users[i]);
+
+ fputs("</Class>\n", fp);
+ }
+
+ fclose(fp);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/classes.h b/scheduler/classes.h
new file mode 100644
index 000000000..385314d28
--- /dev/null
+++ b/scheduler/classes.h
@@ -0,0 +1,43 @@
+/*
+ * "$Id$"
+ *
+ * Printer class definitions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+
+/*
+ * Prototypes...
+ */
+
+extern printer_t *AddClass(const char *name);
+extern void AddPrinterToClass(printer_t *c, printer_t *p);
+extern void DeletePrinterFromClass(printer_t *c, printer_t *p);
+extern void DeletePrinterFromClasses(printer_t *p);
+extern void DeleteAllClasses(void);
+extern printer_t *FindAvailablePrinter(const char *name);
+extern printer_t *FindClass(const char *name);
+extern void LoadAllClasses(void);
+extern void SaveAllClasses(void);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/client.c b/scheduler/client.c
new file mode 100644
index 000000000..9d8e75162
--- /dev/null
+++ b/scheduler/client.c
@@ -0,0 +1,2584 @@
+/*
+ * "$Id$"
+ *
+ * Client routines for the Common UNIX Printing System (CUPS) scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * AcceptClient() - Accept a new client.
+ * CloseAllClients() - Close all remote clients immediately.
+ * CloseClient() - Close a remote client.
+ * EncryptClient() - Enable encryption for the client...
+ * ReadClient() - Read data from a client.
+ * SendCommand() - Send output from a command via HTTP.
+ * SendError() - Send an error message via HTTP.
+ * SendFile() - Send a file via HTTP.
+ * SendHeader() - Send an HTTP request.
+ * ShutdownClient() - Shutdown the receiving end of a connection.
+ * WriteClient() - Write data to a client as needed.
+ * check_if_modified() - Decode an "If-Modified-Since" line.
+ * decode_auth() - Decode an authorization string.
+ * get_file() - Get a filename and state info.
+ * install_conf_file() - Install a configuration file.
+ * pipe_command() - Pipe the output of a command to the remote client.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+
+#include <grp.h>
+
+#ifdef HAVE_LIBSSL
+# include <openssl/err.h>
+# include <openssl/ssl.h>
+# include <openssl/rand.h>
+#endif /* HAVE_LIBSSL */
+
+
+/*
+ * Local functions...
+ */
+
+static int check_if_modified(client_t *con,
+ struct stat *filestats);
+static void decode_auth(client_t *con);
+static char *get_file(client_t *con, struct stat *filestats);
+static http_status_t install_conf_file(client_t *con);
+static int pipe_command(client_t *con, int infile, int *outfile,
+ char *command, char *options);
+
+
+/*
+ * 'AcceptClient()' - Accept a new client.
+ */
+
+void
+AcceptClient(listener_t *lis) /* I - Listener socket */
+{
+ int i; /* Looping var */
+ int val; /* Parameter value */
+ client_t *con; /* New client pointer */
+ unsigned address;/* Address of client */
+ struct hostent *host; /* Host entry for address */
+
+
+ LogMessage(L_DEBUG2, "AcceptClient(%p) %d NumClients = %d",
+ lis, lis->fd, NumClients);
+
+ /*
+ * Make sure we don't have a full set of clients already...
+ */
+
+ if (NumClients == MaxClients)
+ return;
+
+ /*
+ * Get a pointer to the next available client...
+ */
+
+ con = Clients + NumClients;
+
+ memset(con, 0, sizeof(client_t));
+ con->http.activity = time(NULL);
+
+ /*
+ * Accept the client and get the remote address...
+ */
+
+ val = sizeof(struct sockaddr_in);
+
+ if ((con->http.fd = accept(lis->fd, (struct sockaddr *)&(con->http.hostaddr),
+ &val)) < 0)
+ {
+ LogMessage(L_ERROR, "Unable to accept client connection - %s.",
+ strerror(errno));
+ return;
+ }
+
+ con->http.hostaddr.sin_port = lis->address.sin_port;
+
+ /*
+ * Get the hostname or format the IP address as needed...
+ */
+
+ address = ntohl(con->http.hostaddr.sin_addr.s_addr);
+
+ if (HostNameLookups)
+#ifndef __sgi
+ host = gethostbyaddr((char *)&(con->http.hostaddr.sin_addr),
+ sizeof(struct in_addr), AF_INET);
+#else
+ host = gethostbyaddr(&(con->http.hostaddr.sin_addr),
+ sizeof(struct in_addr), AF_INET);
+#endif /* !__sgi */
+ else
+ host = NULL;
+
+ if (address == 0x7f000001)
+ {
+ /*
+ * Map accesses from the loopback interface to "localhost"...
+ */
+
+ strlcpy(con->http.hostname, "localhost", sizeof(con->http.hostname));
+ }
+ else if (con->http.hostaddr.sin_addr.s_addr == ServerAddr.sin_addr.s_addr)
+ {
+ /*
+ * Map accesses from the same host to the server name.
+ */
+
+ strlcpy(con->http.hostname, ServerName, sizeof(con->http.hostname));
+ }
+ else if (host == NULL)
+ {
+ sprintf(con->http.hostname, "%d.%d.%d.%d", (address >> 24) & 255,
+ (address >> 16) & 255, (address >> 8) & 255, address & 255);
+
+ if (HostNameLookups == 2)
+ {
+ /*
+ * Can't have an unresolved IP address with double-lookups enabled...
+ */
+
+#ifdef WIN32
+ closesocket(con->http.fd);
+#else
+ close(con->http.fd);
+#endif /* WIN32 */
+
+ LogMessage(L_WARN, "Name lookup failed - connection from %s closed!",
+ con->http.hostname);
+ return;
+ }
+ }
+ else
+ strlcpy(con->http.hostname, host->h_name, sizeof(con->http.hostname));
+
+ if (HostNameLookups == 2)
+ {
+ /*
+ * Do double lookups as needed...
+ */
+
+ if ((host = httpGetHostByName(con->http.hostname)) != NULL)
+ {
+ /*
+ * See if the hostname maps to the IP address...
+ */
+
+ if (host->h_length != 4 || host->h_addrtype != AF_INET)
+ {
+ /*
+ * Not an IPv4 address...
+ */
+
+ host = NULL;
+ }
+ else
+ {
+ /*
+ * Compare all of the addresses against this one...
+ */
+
+ for (i = 0; host->h_addr_list[i]; i ++)
+ if (memcmp(&(con->http.hostaddr.sin_addr), host->h_addr_list[i], 4) == 0)
+ break;
+
+ if (!host->h_addr_list[i])
+ host = NULL;
+ }
+ }
+
+ if (host == NULL)
+ {
+ /*
+ * Can't have a hostname that doesn't resolve to the same IP address
+ * with double-lookups enabled...
+ */
+
+#ifdef WIN32
+ closesocket(con->http.fd);
+#else
+ close(con->http.fd);
+#endif /* WIN32 */
+
+ LogMessage(L_WARN, "IP lookup failed - connection from %s closed!",
+ con->http.hostname);
+ return;
+ }
+ }
+
+ LogMessage(L_DEBUG, "AcceptClient() %d from %s:%d.", con->http.fd,
+ con->http.hostname, ntohs(con->http.hostaddr.sin_port));
+
+ /*
+ * Using TCP_NODELAY improves responsiveness, especially on systems
+ * with a slow loopback interface... Since we write large buffers
+ * when sending print files and requests, there shouldn't be any
+ * performance penalty for this...
+ */
+
+ val = 1;
+ setsockopt(con->http.fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
+
+ /*
+ * Add the socket to the select() input mask.
+ */
+
+ fcntl(con->http.fd, F_SETFD, fcntl(con->http.fd, F_GETFD) | FD_CLOEXEC);
+
+ LogMessage(L_DEBUG2, "AcceptClient: Adding fd %d to InputSet...",
+ con->http.fd);
+ FD_SET(con->http.fd, &InputSet);
+
+ NumClients ++;
+
+ /*
+ * Temporarily suspend accept()'s until we lose a client...
+ */
+
+ if (NumClients == MaxClients)
+ PauseListening();
+
+#ifdef HAVE_LIBSSL
+ /*
+ * See if we are connecting on a secure port...
+ */
+
+ if (lis->encryption == HTTP_ENCRYPT_ALWAYS)
+ {
+ /*
+ * https connection; go secure...
+ */
+
+ con->http.encryption = HTTP_ENCRYPT_ALWAYS;
+
+ EncryptClient(con);
+ }
+#endif /* HAVE_LIBSSL */
+}
+
+
+/*
+ * 'CloseAllClients()' - Close all remote clients immediately.
+ */
+
+void
+CloseAllClients(void)
+{
+ while (NumClients > 0)
+ CloseClient(Clients);
+}
+
+
+/*
+ * 'CloseClient()' - Close a remote client.
+ */
+
+void
+CloseClient(client_t *con) /* I - Client to close */
+{
+ int status; /* Exit status of pipe command */
+#ifdef HAVE_LIBSSL
+ SSL_CTX *context; /* Context for encryption */
+ SSL *conn; /* Connection for encryption */
+ unsigned long error; /* Error code */
+#endif /* HAVE_LIBSSL */
+
+
+ LogMessage(L_DEBUG, "CloseClient() %d", con->http.fd);
+
+#ifdef HAVE_LIBSSL
+ /*
+ * Shutdown encryption as needed...
+ */
+
+ if (con->http.tls)
+ {
+ conn = (SSL *)(con->http.tls);
+ context = SSL_get_SSL_CTX(conn);
+
+ switch (SSL_shutdown(conn))
+ {
+ case 1 :
+ LogMessage(L_INFO, "CloseClient: SSL shutdown successful!");
+ break;
+ case -1 :
+ LogMessage(L_ERROR, "CloseClient: Fatal error during SSL shutdown!");
+ default :
+ while ((error = ERR_get_error()) != 0)
+ LogMessage(L_ERROR, "CloseClient: %s", ERR_error_string(error, NULL));
+ break;
+ }
+
+ SSL_CTX_free(context);
+ SSL_free(conn);
+
+ con->http.tls = NULL;
+ }
+#endif /* HAVE_LIBSSL */
+
+ /*
+ * Close the socket and clear the file from the input set for select()...
+ */
+
+ if (con->http.fd > 0)
+ {
+ LogMessage(L_DEBUG2, "CloseClient: Removing fd %d from InputSet and OutputSet...",
+ con->http.fd);
+ close(con->http.fd);
+ FD_CLR(con->http.fd, &InputSet);
+ FD_CLR(con->http.fd, &OutputSet);
+ con->http.fd = 0;
+ }
+
+ if (con->pipe_pid != 0)
+ {
+ LogMessage(L_DEBUG2, "CloseClient: Removing fd %d from InputSet...",
+ con->file);
+ FD_CLR(con->file, &InputSet);
+ }
+
+ if (con->file)
+ {
+ /*
+ * Close the open data file...
+ */
+
+ if (con->pipe_pid)
+ {
+ kill(con->pipe_pid, SIGKILL);
+ waitpid(con->pipe_pid, &status, WNOHANG);
+ }
+
+ LogMessage(L_DEBUG2, "CloseClient: %d Closing data file %d.",
+ con->http.fd, con->file);
+ LogMessage(L_DEBUG2, "CloseClient: %d Removing fd %d from InputSet.",
+ con->http.fd, con->file);
+
+ FD_CLR(con->file, &InputSet);
+ close(con->file);
+ con->file = 0;
+ }
+
+ if (con->request)
+ {
+ ippDelete(con->request);
+ con->request = NULL;
+ }
+
+ if (con->response)
+ {
+ ippDelete(con->response);
+ con->response = NULL;
+ }
+
+ if (con->language)
+ {
+ cupsLangFree(con->language);
+ con->language = NULL;
+ }
+
+ /*
+ * Re-enable new client connections if we are going back under the
+ * limit...
+ */
+
+ if (NumClients == MaxClients)
+ ResumeListening();
+
+ /*
+ * Compact the list of clients as necessary...
+ */
+
+ NumClients --;
+
+ if (con < (Clients + NumClients))
+ memcpy(con, con + 1, (Clients + NumClients - con) * sizeof(client_t));
+}
+
+
+/*
+ * 'EncryptClient()' - Enable encryption for the client...
+ */
+
+int /* O - 1 on success, 0 on error */
+EncryptClient(client_t *con) /* I - Client to encrypt */
+{
+#ifdef HAVE_LIBSSL
+ SSL_CTX *context; /* Context for encryption */
+ SSL *conn; /* Connection for encryption */
+ unsigned long error; /* Error code */
+
+
+ /*
+ * Create the SSL context and accept the connection...
+ */
+
+ context = SSL_CTX_new(SSLv23_method());
+ conn = SSL_new(context);
+
+ SSL_use_PrivateKey_file(conn, ServerKey, SSL_FILETYPE_PEM);
+ SSL_use_certificate_file(conn, ServerCertificate, SSL_FILETYPE_PEM);
+
+ SSL_set_fd(conn, con->http.fd);
+ if (SSL_accept(conn) != 1)
+ {
+ while ((error = ERR_get_error()) != 0)
+ LogMessage(L_ERROR, "EncryptClient: %s", ERR_error_string(error, NULL));
+
+ SSL_CTX_free(context);
+ SSL_free(conn);
+ return (0);
+ }
+
+ LogMessage(L_DEBUG, "EncryptClient() %d Connection now encrypted.",
+ con->http.fd);
+
+ con->http.tls = conn;
+ return (1);
+#else
+ return (0);
+#endif /* HAVE_LIBSSL */
+}
+
+
+/*
+ * 'ReadClient()' - Read data from a client.
+ */
+
+int /* O - 1 on success, 0 on error */
+ReadClient(client_t *con) /* I - Client to read from */
+{
+ char line[32768], /* Line from client... */
+ operation[64], /* Operation code from socket */
+ version[64]; /* HTTP version number string */
+ int major, minor; /* HTTP version numbers */
+ http_status_t status; /* Transfer status */
+ ipp_state_t ipp_state; /* State of IPP transfer */
+ int bytes; /* Number of bytes to POST */
+ char *filename; /* Name of file for GET/HEAD */
+ struct stat filestats; /* File information */
+ mime_type_t *type; /* MIME type of file */
+ printer_t *p; /* Printer */
+ location_t *best; /* Best match for authentication */
+ static unsigned request_id = 0;/* Request ID for temp files */
+
+
+ status = HTTP_CONTINUE;
+
+ switch (con->http.state)
+ {
+ case HTTP_WAITING :
+ /*
+ * See if we've received a request line...
+ */
+
+ if (httpGets(line, sizeof(line) - 1, HTTP(con)) == NULL)
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ /*
+ * Ignore blank request lines...
+ */
+
+ if (line[0] == '\0')
+ break;
+
+ /*
+ * Clear other state variables...
+ */
+
+ httpClearFields(HTTP(con));
+
+ con->http.activity = time(NULL);
+ con->http.version = HTTP_1_0;
+ con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+ con->http.data_encoding = HTTP_ENCODE_LENGTH;
+ con->http.data_remaining = 0;
+ con->operation = HTTP_WAITING;
+ con->bytes = 0;
+ con->file = 0;
+ con->pipe_pid = 0;
+ con->command[0] = '\0';
+ con->username[0] = '\0';
+ con->password[0] = '\0';
+ con->uri[0] = '\0';
+
+ if (con->language != NULL)
+ {
+ cupsLangFree(con->language);
+ con->language = NULL;
+ }
+
+ /*
+ * Grab the request line...
+ */
+
+ switch (sscanf(line, "%63s%1023s%63s", operation, con->uri, version))
+ {
+ case 1 :
+ SendError(con, HTTP_BAD_REQUEST);
+ ShutdownClient(con);
+ return (0);
+ case 2 :
+ con->http.version = HTTP_0_9;
+ break;
+ case 3 :
+ if (sscanf(version, "HTTP/%d.%d", &major, &minor) != 2)
+ {
+ SendError(con, HTTP_BAD_REQUEST);
+ ShutdownClient(con);
+ return (0);
+ }
+
+ if (major < 2)
+ {
+ con->http.version = (http_version_t)(major * 100 + minor);
+ if (con->http.version == HTTP_1_1 && KeepAlive)
+ con->http.keep_alive = HTTP_KEEPALIVE_ON;
+ else
+ con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+ }
+ else
+ {
+ SendError(con, HTTP_NOT_SUPPORTED);
+ ShutdownClient(con);
+ return (0);
+ }
+ break;
+ }
+
+ /*
+ * Process the request...
+ */
+
+ if (strcmp(operation, "GET") == 0)
+ con->http.state = HTTP_GET;
+ else if (strcmp(operation, "PUT") == 0)
+ con->http.state = HTTP_PUT;
+ else if (strcmp(operation, "POST") == 0)
+ con->http.state = HTTP_POST;
+ else if (strcmp(operation, "DELETE") == 0)
+ con->http.state = HTTP_DELETE;
+ else if (strcmp(operation, "TRACE") == 0)
+ con->http.state = HTTP_TRACE;
+ else if (strcmp(operation, "OPTIONS") == 0)
+ con->http.state = HTTP_OPTIONS;
+ else if (strcmp(operation, "HEAD") == 0)
+ con->http.state = HTTP_HEAD;
+ else
+ {
+ SendError(con, HTTP_BAD_REQUEST);
+ ShutdownClient(con);
+ return (0);
+ }
+
+ con->start = time(NULL);
+ con->operation = con->http.state;
+
+ LogMessage(L_DEBUG, "ReadClient() %d %s %s HTTP/%d.%d", con->http.fd,
+ operation, con->uri,
+ con->http.version / 100, con->http.version % 100);
+
+ con->http.status = HTTP_OK;
+
+ case HTTP_OPTIONS :
+ case HTTP_DELETE :
+ case HTTP_GET :
+ case HTTP_HEAD :
+ case HTTP_POST :
+ case HTTP_PUT :
+ case HTTP_TRACE :
+ /*
+ * Parse incoming parameters until the status changes...
+ */
+
+ status = httpUpdate(HTTP(con));
+
+ if (status != HTTP_OK && status != HTTP_CONTINUE)
+ {
+ SendError(con, HTTP_BAD_REQUEST);
+ ShutdownClient(con);
+ return (0);
+ }
+ break;
+
+ default :
+ break; /* Anti-compiler-warning-code */
+ }
+
+ /*
+ * Handle new transfers...
+ */
+
+ if (status == HTTP_OK)
+ {
+ con->language = cupsLangGet(con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE]);
+
+ decode_auth(con);
+
+ if (strncmp(con->http.fields[HTTP_FIELD_CONNECTION], "Keep-Alive", 10) == 0 &&
+ KeepAlive)
+ con->http.keep_alive = HTTP_KEEPALIVE_ON;
+
+ if (con->http.fields[HTTP_FIELD_HOST][0] == '\0' &&
+ con->http.version >= HTTP_1_1)
+ {
+ /*
+ * HTTP/1.1 and higher require the "Host:" field...
+ */
+
+ if (!SendError(con, HTTP_BAD_REQUEST))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ else if (con->operation == HTTP_OPTIONS)
+ {
+ /*
+ * Do OPTIONS command...
+ */
+
+ if ((best = FindBest(con->uri, con->http.state)) != NULL &&
+ best->type != AUTH_NONE)
+ {
+ if (!SendHeader(con, HTTP_UNAUTHORIZED, NULL))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+
+ if (strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Upgrade") == 0 &&
+ con->http.tls == NULL)
+ {
+#ifdef HAVE_LIBSSL
+ /*
+ * Do encryption stuff...
+ */
+
+ if (!SendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ httpPrintf(HTTP(con), "Connection: Upgrade\r\n");
+ httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n");
+ httpPrintf(HTTP(con), "Content-Length: 0\r\n");
+ httpPrintf(HTTP(con), "\r\n");
+
+ EncryptClient(con);
+#else
+ if (!SendError(con, HTTP_NOT_IMPLEMENTED))
+ {
+ CloseClient(con);
+ return (0);
+ }
+#endif /* HAVE_LIBSSL */
+ }
+
+ if (!SendHeader(con, HTTP_OK, NULL))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ httpPrintf(HTTP(con), "Allow: GET, HEAD, OPTIONS, POST, PUT\r\n");
+ httpPrintf(HTTP(con), "Content-Length: 0\r\n");
+ httpPrintf(HTTP(con), "\r\n");
+ }
+ else if (strstr(con->uri, "..") != NULL)
+ {
+ /*
+ * Protect against malicious users!
+ */
+
+ if (!SendError(con, HTTP_FORBIDDEN))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ else if (con->uri[0] != '/')
+ {
+ /*
+ * Don't allow proxying (yet)...
+ */
+
+ if (!SendError(con, HTTP_METHOD_NOT_ALLOWED))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ else
+ {
+ if (strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Upgrade") == 0 &&
+ con->http.tls == NULL)
+ {
+#ifdef HAVE_LIBSSL
+ /*
+ * Do encryption stuff...
+ */
+
+ if (!SendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ httpPrintf(HTTP(con), "Connection: Upgrade\r\n");
+ httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n");
+ httpPrintf(HTTP(con), "Content-Length: 0\r\n");
+ httpPrintf(HTTP(con), "\r\n");
+
+ EncryptClient(con);
+#else
+ if (!SendError(con, HTTP_NOT_IMPLEMENTED))
+ {
+ CloseClient(con);
+ return (0);
+ }
+#endif /* HAVE_LIBSSL */
+ }
+
+ if ((status = IsAuthorized(con)) != HTTP_OK)
+ {
+ SendError(con, status);
+ ShutdownClient(con);
+ return (0);
+ }
+
+ switch (con->http.state)
+ {
+ case HTTP_GET_SEND :
+ if (strncmp(con->uri, "/printers/", 10) == 0 &&
+ strcmp(con->uri + strlen(con->uri) - 4, ".ppd") == 0)
+ {
+ /*
+ * Send PPD file - get the real printer name since printer
+ * names are not case sensitive but filenames can be...
+ */
+
+ con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".ppd" */
+
+ if ((p = FindPrinter(con->uri + 10)) != NULL)
+ snprintf(con->uri, sizeof(con->uri), "/ppd/%s.ppd", p->name);
+ else
+ {
+ if (!SendError(con, HTTP_NOT_FOUND))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ break;
+ }
+ }
+
+ if ((strncmp(con->uri, "/admin", 6) == 0 &&
+ strncmp(con->uri, "/admin/conf/", 12) != 0) ||
+ strncmp(con->uri, "/printers", 9) == 0 ||
+ strncmp(con->uri, "/classes", 8) == 0 ||
+ strncmp(con->uri, "/jobs", 5) == 0)
+ {
+ /*
+ * Send CGI output...
+ */
+
+ if (strncmp(con->uri, "/admin", 6) == 0)
+ {
+ snprintf(con->command, sizeof(con->command),
+ "%s/cgi-bin/admin.cgi", ServerBin);
+ con->options = con->uri + 6;
+ }
+ else if (strncmp(con->uri, "/printers", 9) == 0)
+ {
+ snprintf(con->command, sizeof(con->command),
+ "%s/cgi-bin/printers.cgi", ServerBin);
+ con->options = con->uri + 9;
+ }
+ else if (strncmp(con->uri, "/classes", 8) == 0)
+ {
+ snprintf(con->command, sizeof(con->command),
+ "%s/cgi-bin/classes.cgi", ServerBin);
+ con->options = con->uri + 8;
+ }
+ else
+ {
+ snprintf(con->command, sizeof(con->command),
+ "%s/cgi-bin/jobs.cgi", ServerBin);
+ con->options = con->uri + 5;
+ }
+
+ if (con->options[0] == '/')
+ con->options ++;
+
+ if (!SendCommand(con, con->command, con->options))
+ {
+ if (!SendError(con, HTTP_NOT_FOUND))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ else
+ LogRequest(con, HTTP_OK);
+
+ if (con->http.version <= HTTP_1_0)
+ con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+ }
+ else if (strncmp(con->uri, "/admin/conf/", 12) == 0 &&
+ (strchr(con->uri + 12, '/') != NULL ||
+ strlen(con->uri) == 12))
+ {
+ /*
+ * GET can only be done to configuration files under
+ * /admin/conf...
+ */
+
+ if (!SendError(con, HTTP_FORBIDDEN))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ break;
+ }
+ else
+ {
+ /*
+ * Serve a file...
+ */
+
+ if ((filename = get_file(con, &filestats)) == NULL)
+ {
+ if (!SendError(con, HTTP_NOT_FOUND))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ else if (!check_if_modified(con, &filestats))
+ {
+ if (!SendError(con, HTTP_NOT_MODIFIED))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ else
+ {
+ type = mimeFileType(MimeDatabase, filename);
+ if (type == NULL)
+ strcpy(line, "text/plain");
+ else
+ snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
+
+ if (!SendFile(con, HTTP_OK, filename, line, &filestats))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ }
+ break;
+
+ case HTTP_POST_RECV :
+ /*
+ * See if the POST request includes a Content-Length field, and if
+ * so check the length against any limits that are set...
+ */
+
+ LogMessage(L_DEBUG2, "POST %s", con->uri);
+ LogMessage(L_DEBUG2, "CONTENT_TYPE = %s", con->http.fields[HTTP_FIELD_CONTENT_TYPE]);
+
+ if (con->http.fields[HTTP_FIELD_CONTENT_LENGTH][0] &&
+ atoi(con->http.fields[HTTP_FIELD_CONTENT_LENGTH]) > MaxRequestSize &&
+ MaxRequestSize > 0)
+ {
+ /*
+ * Request too large...
+ */
+
+ if (!SendError(con, HTTP_REQUEST_TOO_LARGE))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ break;
+ }
+
+ /*
+ * See what kind of POST request this is; for IPP requests the
+ * content-type field will be "application/ipp"...
+ */
+
+ if (strcmp(con->http.fields[HTTP_FIELD_CONTENT_TYPE], "application/ipp") == 0)
+ con->request = ippNew();
+ else if ((strncmp(con->uri, "/admin", 6) == 0 &&
+ strncmp(con->uri, "/admin/conf/", 12) != 0) ||
+ strncmp(con->uri, "/printers", 9) == 0 ||
+ strncmp(con->uri, "/classes", 8) == 0 ||
+ strncmp(con->uri, "/jobs", 5) == 0)
+ {
+ /*
+ * CGI request...
+ */
+
+ if (strncmp(con->uri, "/admin", 6) == 0)
+ {
+ snprintf(con->command, sizeof(con->command),
+ "%s/cgi-bin/admin.cgi", ServerBin);
+ con->options = con->uri + 6;
+ }
+ else if (strncmp(con->uri, "/printers", 9) == 0)
+ {
+ snprintf(con->command, sizeof(con->command),
+ "%s/cgi-bin/printers.cgi", ServerBin);
+ con->options = con->uri + 9;
+ }
+ else if (strncmp(con->uri, "/classes", 8) == 0)
+ {
+ snprintf(con->command, sizeof(con->command),
+ "%s/cgi-bin/classes.cgi", ServerBin);
+ con->options = con->uri + 8;
+ }
+ else
+ {
+ snprintf(con->command, sizeof(con->command),
+ "%s/cgi-bin/jobs.cgi", ServerBin);
+ con->options = con->uri + 5;
+ }
+
+ if (con->options[0] == '/')
+ con->options ++;
+
+ LogMessage(L_DEBUG2, "ReadClient() %d command=\"%s\", options = \"%s\"",
+ con->http.fd, con->command, con->options);
+
+ if (con->http.version <= HTTP_1_0)
+ con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+ }
+ else if (!SendError(con, HTTP_UNAUTHORIZED))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ break;
+
+ case HTTP_PUT_RECV :
+ /*
+ * Validate the resource name...
+ */
+
+ if (strncmp(con->uri, "/admin/conf/", 12) != 0 ||
+ strchr(con->uri + 12, '/') != NULL ||
+ strlen(con->uri) == 12)
+ {
+ /*
+ * PUT can only be done to configuration files under
+ * /admin/conf...
+ */
+
+ if (!SendError(con, HTTP_FORBIDDEN))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ break;
+ }
+
+ /*
+ * See if the PUT request includes a Content-Length field, and if
+ * so check the length against any limits that are set...
+ */
+
+ LogMessage(L_DEBUG2, "PUT %s", con->uri);
+ LogMessage(L_DEBUG2, "CONTENT_TYPE = %s", con->http.fields[HTTP_FIELD_CONTENT_TYPE]);
+
+ if (con->http.fields[HTTP_FIELD_CONTENT_LENGTH][0] &&
+ atoi(con->http.fields[HTTP_FIELD_CONTENT_LENGTH]) > MaxRequestSize &&
+ MaxRequestSize > 0)
+ {
+ /*
+ * Request too large...
+ */
+
+ if (!SendError(con, HTTP_REQUEST_TOO_LARGE))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ break;
+ }
+
+ /*
+ * Open a temporary file to hold the request...
+ */
+
+ snprintf(con->filename, sizeof(con->filename), "%s/%08x",
+ RequestRoot, request_id ++);
+ con->file = open(con->filename, O_WRONLY | O_CREAT | O_TRUNC, 0640);
+ fchmod(con->file, 0640);
+ fchown(con->file, User, Group);
+
+ LogMessage(L_DEBUG2, "ReadClient() %d REQUEST %s=%d", con->http.fd,
+ con->filename, con->file);
+
+ if (con->file < 0)
+ {
+ if (!SendError(con, HTTP_REQUEST_TOO_LARGE))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ break;
+
+ case HTTP_DELETE :
+ case HTTP_TRACE :
+ SendError(con, HTTP_NOT_IMPLEMENTED);
+ ShutdownClient(con);
+ return (0);
+
+ case HTTP_HEAD :
+ if (strncmp(con->uri, "/printers/", 10) == 0 &&
+ strcmp(con->uri + strlen(con->uri) - 4, ".ppd") == 0)
+ {
+ /*
+ * Send PPD file - get the real printer name since printer
+ * names are not case sensitive but filenames can be...
+ */
+
+ con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".ppd" */
+
+ if ((p = FindPrinter(con->uri + 10)) != NULL)
+ snprintf(con->uri, sizeof(con->uri), "/ppd/%s.ppd", p->name);
+ else
+ {
+ if (!SendError(con, HTTP_NOT_FOUND))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ break;
+ }
+ }
+
+ if ((strncmp(con->uri, "/admin/", 7) == 0 &&
+ strncmp(con->uri, "/admin/conf/", 12) != 0) ||
+ strncmp(con->uri, "/printers/", 10) == 0 ||
+ strncmp(con->uri, "/classes/", 9) == 0 ||
+ strncmp(con->uri, "/jobs/", 6) == 0)
+ {
+ /*
+ * CGI output...
+ */
+
+ if (!SendHeader(con, HTTP_OK, "text/html"))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ if (httpPrintf(HTTP(con), "\r\n") < 0)
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ LogRequest(con, HTTP_OK);
+ }
+ else if (strncmp(con->uri, "/admin/conf/", 12) == 0 &&
+ (strchr(con->uri + 12, '/') != NULL ||
+ strlen(con->uri) == 12))
+ {
+ /*
+ * HEAD can only be done to configuration files under
+ * /admin/conf...
+ */
+
+ if (!SendError(con, HTTP_FORBIDDEN))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ break;
+ }
+ else if ((filename = get_file(con, &filestats)) == NULL)
+ {
+ if (!SendHeader(con, HTTP_NOT_FOUND, "text/html"))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ LogRequest(con, HTTP_NOT_FOUND);
+ }
+ else if (!check_if_modified(con, &filestats))
+ {
+ if (!SendError(con, HTTP_NOT_MODIFIED))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ LogRequest(con, HTTP_NOT_MODIFIED);
+ }
+ else
+ {
+ /*
+ * Serve a file...
+ */
+
+ type = mimeFileType(MimeDatabase, filename);
+ if (type == NULL)
+ strcpy(line, "text/plain");
+ else
+ snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
+
+ if (!SendHeader(con, HTTP_OK, line))
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ if (httpPrintf(HTTP(con), "Last-Modified: %s\r\n",
+ httpGetDateString(filestats.st_mtime)) < 0)
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ if (httpPrintf(HTTP(con), "Content-Length: %lu\r\n",
+ (unsigned long)filestats.st_size) < 0)
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ LogRequest(con, HTTP_OK);
+ }
+
+ if (httpPrintf(HTTP(con), "\r\n") < 0)
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ con->http.state = HTTP_WAITING;
+ break;
+
+ default :
+ break; /* Anti-compiler-warning-code */
+ }
+ }
+ }
+
+ /*
+ * Handle any incoming data...
+ */
+
+ switch (con->http.state)
+ {
+ case HTTP_PUT_RECV :
+ LogMessage(L_DEBUG2, "ReadClient() %d con->data_encoding = %s, con->data_remaining = %d, con->file = %d",
+ con->http.fd,
+ con->http.data_encoding == HTTP_ENCODE_CHUNKED ? "chunked" : "length",
+ con->http.data_remaining, con->file);
+
+ if ((bytes = httpRead(HTTP(con), line, sizeof(line))) < 0)
+ {
+ CloseClient(con);
+ return (0);
+ }
+ else if (bytes > 0)
+ {
+ con->bytes += bytes;
+
+ LogMessage(L_DEBUG2, "ReadClient() %d writing %d bytes to %d",
+ con->http.fd, bytes, con->file);
+
+ if (write(con->file, line, bytes) < bytes)
+ {
+ LogMessage(L_ERROR, "ReadClient: Unable to write %d bytes to %s: %s",
+ bytes, con->filename, strerror(errno));
+
+ close(con->file);
+ con->file = 0;
+ unlink(con->filename);
+ con->filename[0] = '\0';
+
+ if (!SendError(con, HTTP_REQUEST_TOO_LARGE))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ }
+
+ if (con->http.state == HTTP_WAITING)
+ {
+ /*
+ * End of file, see how big it is...
+ */
+
+ fstat(con->file, &filestats);
+
+ LogMessage(L_DEBUG2, "ReadClient() %d Closing data file %d, size = %d.",
+ con->http.fd, con->file, (int)filestats.st_size);
+
+ close(con->file);
+ con->file = 0;
+
+ if (filestats.st_size > MaxRequestSize &&
+ MaxRequestSize > 0)
+ {
+ /*
+ * Request is too big; remove it and send an error...
+ */
+
+ LogMessage(L_DEBUG2, "ReadClient() %d Removing temp file %s",
+ con->http.fd, con->filename);
+ unlink(con->filename);
+ con->filename[0] = '\0';
+
+ if (!SendError(con, HTTP_REQUEST_TOO_LARGE))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+
+ /*
+ * Install the configuration file...
+ */
+
+ status = install_conf_file(con);
+
+ /*
+ * Return the status to the client...
+ */
+
+ if (!SendError(con, status))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ break;
+
+ case HTTP_POST_RECV :
+ LogMessage(L_DEBUG2, "ReadClient() %d con->data_encoding = %s, con->data_remaining = %d, con->file = %d",
+ con->http.fd,
+ con->http.data_encoding == HTTP_ENCODE_CHUNKED ? "chunked" : "length",
+ con->http.data_remaining, con->file);
+
+ if (con->request != NULL)
+ {
+ /*
+ * Grab any request data from the connection...
+ */
+
+ if ((ipp_state = ippRead(&(con->http), con->request)) == IPP_ERROR)
+ {
+ LogMessage(L_ERROR, "ReadClient() %d IPP Read Error!",
+ con->http.fd);
+ CloseClient(con);
+ return (0);
+ }
+ else if (ipp_state != IPP_DATA)
+ break;
+ else
+ con->bytes += ippLength(con->request);
+ }
+
+ if (con->file == 0 && con->http.state != HTTP_POST_SEND)
+ {
+ /*
+ * Create a file as needed for the request data...
+ */
+
+ snprintf(con->filename, sizeof(con->filename), "%s/%08x",
+ RequestRoot, request_id ++);
+ con->file = open(con->filename, O_WRONLY | O_CREAT | O_TRUNC, 0640);
+ fchmod(con->file, 0640);
+ fchown(con->file, User, Group);
+
+ LogMessage(L_DEBUG2, "ReadClient() %d REQUEST %s=%d", con->http.fd,
+ con->filename, con->file);
+
+ if (con->file < 0)
+ {
+ if (!SendError(con, HTTP_REQUEST_TOO_LARGE))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ }
+
+ if (con->http.state != HTTP_POST_SEND)
+ {
+ if ((bytes = httpRead(HTTP(con), line, sizeof(line))) < 0)
+ {
+ CloseClient(con);
+ return (0);
+ }
+ else if (bytes > 0)
+ {
+ con->bytes += bytes;
+
+ LogMessage(L_DEBUG2, "ReadClient() %d writing %d bytes to %d",
+ con->http.fd, bytes, con->file);
+
+ if (write(con->file, line, bytes) < bytes)
+ {
+ LogMessage(L_ERROR, "ReadClient: Unable to write %d bytes to %s: %s",
+ bytes, con->filename, strerror(errno));
+
+ close(con->file);
+ con->file = 0;
+ unlink(con->filename);
+ con->filename[0] = '\0';
+
+ if (!SendError(con, HTTP_REQUEST_TOO_LARGE))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ }
+ else if (con->http.state != HTTP_POST_SEND)
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+
+ if (con->http.state == HTTP_POST_SEND)
+ {
+ if (con->file)
+ {
+ fstat(con->file, &filestats);
+
+ LogMessage(L_DEBUG2, "ReadClient() %d Closing data file %d, size = %d.",
+ con->http.fd, con->file, (int)filestats.st_size);
+
+ close(con->file);
+ con->file = 0;
+
+ if (filestats.st_size > MaxRequestSize &&
+ MaxRequestSize > 0)
+ {
+ /*
+ * Request is too big; remove it and send an error...
+ */
+
+ LogMessage(L_DEBUG2, "ReadClient() %d Removing temp file %s",
+ con->http.fd, con->filename);
+ unlink(con->filename);
+ con->filename[0] = '\0';
+
+ if (con->request)
+ {
+ /*
+ * Delete any IPP request data...
+ */
+
+ ippDelete(con->request);
+ con->request = NULL;
+ }
+
+ if (!SendError(con, HTTP_REQUEST_TOO_LARGE))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+
+ if (con->command[0])
+ {
+ if (!SendCommand(con, con->command, con->options))
+ {
+ if (!SendError(con, HTTP_NOT_FOUND))
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+ else
+ LogRequest(con, HTTP_OK);
+ }
+ }
+
+ if (con->request)
+ ProcessIPPRequest(con);
+ }
+ break;
+
+ default :
+ break; /* Anti-compiler-warning-code */
+ }
+
+ if (!con->http.keep_alive && con->http.state == HTTP_WAITING)
+ {
+ CloseClient(con);
+ return (0);
+ }
+ else
+ return (1);
+}
+
+
+/*
+ * 'SendCommand()' - Send output from a command via HTTP.
+ */
+
+int
+SendCommand(client_t *con,
+ char *command,
+ char *options)
+{
+ int fd;
+
+
+ if (con->filename[0])
+ fd = open(con->filename, O_RDONLY);
+ else
+ fd = open("/dev/null", O_RDONLY);
+
+ con->pipe_pid = pipe_command(con, fd, &(con->file), command, options);
+
+ close(fd);
+
+ LogMessage(L_INFO, "Started \"%s\" (pid=%d)", command, con->pipe_pid);
+
+ LogMessage(L_DEBUG, "SendCommand() %d file=%d", con->http.fd, con->file);
+
+ if (con->pipe_pid == 0)
+ return (0);
+
+ fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
+
+ LogMessage(L_DEBUG2, "SendCommand: Adding fd %d to InputSet...", con->file);
+ LogMessage(L_DEBUG2, "SendCommand: Adding fd %d to OutputSet...",
+ con->http.fd);
+
+ FD_SET(con->file, &InputSet);
+ FD_SET(con->http.fd, &OutputSet);
+
+ if (!SendHeader(con, HTTP_OK, NULL))
+ return (0);
+
+ if (con->http.version == HTTP_1_1)
+ {
+ con->http.data_encoding = HTTP_ENCODE_CHUNKED;
+
+ if (httpPrintf(HTTP(con), "Transfer-Encoding: chunked\r\n") < 0)
+ return (0);
+ }
+
+ con->got_fields = 0;
+ con->field_col = 0;
+
+ return (1);
+}
+
+
+/*
+ * 'SendError()' - Send an error message via HTTP.
+ */
+
+int /* O - 1 if successful, 0 otherwise */
+SendError(client_t *con, /* I - Connection */
+ http_status_t code) /* I - Error code */
+{
+ char message[1024]; /* Message for user */
+
+
+ /*
+ * Put the request in the access_log file...
+ */
+
+ if (con->operation > HTTP_WAITING)
+ LogRequest(con, code);
+
+ LogMessage(L_DEBUG, "SendError() %d code=%d", con->http.fd, code);
+
+ /*
+ * To work around bugs in some proxies, don't use Keep-Alive for some
+ * error messages...
+ */
+
+ if (code >= HTTP_BAD_REQUEST)
+ con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+
+ /*
+ * Send an error message back to the client. If the error code is a
+ * 400 or 500 series, make sure the message contains some text, too!
+ */
+
+ if (!SendHeader(con, code, NULL))
+ return (0);
+
+#ifdef HAVE_LIBSSL
+ if (code == HTTP_UPGRADE_REQUIRED)
+ if (httpPrintf(HTTP(con), "Connection: Upgrade\r\n") < 0)
+ return (0);
+
+ if (httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n") < 0)
+ return (0);
+#endif /* HAVE_LIBSSL */
+
+ if (con->http.version >= HTTP_1_1 && !con->http.keep_alive)
+ {
+ if (httpPrintf(HTTP(con), "Connection: close\r\n") < 0)
+ return (0);
+ }
+
+ if (code >= HTTP_BAD_REQUEST)
+ {
+ /*
+ * Send a human-readable error message.
+ */
+
+ snprintf(message, sizeof(message),
+ "<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>"
+ "<BODY><H1>%s</H1>%s</BODY></HTML>\n",
+ code, httpStatus(code), httpStatus(code),
+ con->language ? con->language->messages[code] :
+ httpStatus(code));
+
+ if (httpPrintf(HTTP(con), "Content-Type: text/html\r\n") < 0)
+ return (0);
+ if (httpPrintf(HTTP(con), "Content-Length: %d\r\n", strlen(message)) < 0)
+ return (0);
+ if (httpPrintf(HTTP(con), "\r\n") < 0)
+ return (0);
+ if (httpPrintf(HTTP(con), "%s", message) < 0)
+ return (0);
+ }
+ else if (httpPrintf(HTTP(con), "\r\n") < 0)
+ return (0);
+
+ con->http.state = HTTP_WAITING;
+
+ return (1);
+}
+
+
+/*
+ * 'SendFile()' - Send a file via HTTP.
+ */
+
+int
+SendFile(client_t *con,
+ http_status_t code,
+ char *filename,
+ char *type,
+ struct stat *filestats)
+{
+ con->file = open(filename, O_RDONLY);
+
+ LogMessage(L_DEBUG, "SendFile() %d file=%d", con->http.fd, con->file);
+
+ if (con->file < 0)
+ return (0);
+
+ fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
+
+ con->pipe_pid = 0;
+
+ if (!SendHeader(con, code, type))
+ return (0);
+
+ if (httpPrintf(HTTP(con), "Last-Modified: %s\r\n", httpGetDateString(filestats->st_mtime)) < 0)
+ return (0);
+ if (httpPrintf(HTTP(con), "Content-Length: %lu\r\n",
+ (unsigned long)filestats->st_size) < 0)
+ return (0);
+ if (httpPrintf(HTTP(con), "\r\n") < 0)
+ return (0);
+
+ LogMessage(L_DEBUG2, "SendFile: Adding fd %d to OutputSet...", con->http.fd);
+
+ FD_SET(con->http.fd, &OutputSet);
+
+ return (1);
+}
+
+
+/*
+ * 'SendHeader()' - Send an HTTP request.
+ */
+
+int /* O - 1 on success, 0 on failure */
+SendHeader(client_t *con, /* I - Client to send to */
+ http_status_t code, /* I - HTTP status code */
+ char *type) /* I - MIME type of document */
+{
+ location_t *loc; /* Authentication location */
+
+
+ if (httpPrintf(HTTP(con), "HTTP/%d.%d %d %s\r\n", con->http.version / 100,
+ con->http.version % 100, code, httpStatus(code)) < 0)
+ return (0);
+ if (httpPrintf(HTTP(con), "Date: %s\r\n", httpGetDateString(time(NULL))) < 0)
+ return (0);
+ if (httpPrintf(HTTP(con), "Server: CUPS/1.1\r\n") < 0)
+ return (0);
+ if (con->http.keep_alive && con->http.version >= HTTP_1_0)
+ {
+ if (httpPrintf(HTTP(con), "Connection: Keep-Alive\r\n") < 0)
+ return (0);
+ if (httpPrintf(HTTP(con), "Keep-Alive: timeout=%d\r\n", KeepAliveTimeout) < 0)
+ return (0);
+ }
+ if (code == HTTP_METHOD_NOT_ALLOWED)
+ if (httpPrintf(HTTP(con), "Allow: GET, HEAD, OPTIONS, POST\r\n") < 0)
+ return (0);
+
+ if (code == HTTP_UNAUTHORIZED)
+ {
+ /*
+ * This already succeeded in IsAuthorized...
+ */
+
+ loc = FindBest(con->uri, con->http.state);
+
+ if (loc->type != AUTH_DIGEST)
+ {
+ if (httpPrintf(HTTP(con), "WWW-Authenticate: Basic realm=\"CUPS\"\r\n") < 0)
+ return (0);
+ }
+ else
+ {
+ if (httpPrintf(HTTP(con), "WWW-Authenticate: Digest realm=\"CUPS\" "
+ "nonce=\"%s\"\r\n", con->http.hostname) < 0)
+ return (0);
+ }
+ }
+ if (con->language != NULL)
+ {
+ if (httpPrintf(HTTP(con), "Content-Language: %s\r\n",
+ con->language->language) < 0)
+ return (0);
+
+ if (type != NULL)
+ if (httpPrintf(HTTP(con), "Content-Type: %s; charset=%s\r\n", type,
+ cupsLangEncoding(con->language)) < 0)
+ return (0);
+ }
+ else if (type != NULL)
+ if (httpPrintf(HTTP(con), "Content-Type: %s\r\n", type) < 0)
+ return (0);
+
+ return (1);
+}
+
+
+/*
+ * 'ShutdownClient()' - Shutdown the receiving end of a connection.
+ */
+
+void
+ShutdownClient(client_t *con) /* I - Client connection */
+{
+ /*
+ * Shutdown the receiving end of the socket, since the client
+ * still needs to read the error message...
+ */
+
+ shutdown(con->http.fd, 0);
+
+ LogMessage(L_DEBUG2, "ShutdownClient: Removing fd %d from InputSet...",
+ con->http.fd);
+
+ FD_CLR(con->http.fd, &InputSet);
+}
+
+
+/*
+ * 'WriteClient()' - Write data to a client as needed.
+ */
+
+int /* O - 1 if success, 0 if fail */
+WriteClient(client_t *con) /* I - Client connection */
+{
+ int bytes; /* Number of bytes written */
+ char buf[HTTP_MAX_BUFFER + 1];/* Data buffer */
+ char *bufptr; /* Pointer into buffer */
+ ipp_state_t ipp_state; /* IPP state value */
+
+
+ if (con->http.state != HTTP_GET_SEND &&
+ con->http.state != HTTP_POST_SEND)
+ return (1);
+
+ if (con->response != NULL)
+ {
+ ipp_state = ippWrite(&(con->http), con->response);
+ bytes = ipp_state != IPP_ERROR && ipp_state != IPP_DATA;
+ }
+ else if ((bytes = read(con->file, buf, HTTP_MAX_BUFFER)) > 0)
+ {
+ if (con->pipe_pid && !con->got_fields)
+ {
+ /*
+ * Inspect the data for Content-Type and other fields.
+ */
+
+ buf[bytes] = '\0';
+
+ for (bufptr = buf; !con->got_fields && *bufptr; bufptr ++)
+ if (*bufptr == '\n')
+ {
+ /*
+ * Send line to client...
+ */
+
+ if (bufptr > buf && bufptr[-1] == '\r')
+ bufptr[-1] = '\0';
+ *bufptr++ = '\0';
+
+ httpPrintf(HTTP(con), "%s\r\n", buf);
+ LogMessage(L_DEBUG2, "WriteClient() %d %s", con->http.fd, buf);
+
+ /*
+ * Update buffer...
+ */
+
+ bytes -= (bufptr - buf);
+ memcpy(buf, bufptr, bytes + 1);
+ bufptr = buf - 1;
+
+ /*
+ * See if the line was empty...
+ */
+
+ if (con->field_col == 0)
+ con->got_fields = 1;
+ else
+ con->field_col = 0;
+ }
+ else if (*bufptr != '\r')
+ con->field_col ++;
+
+ if (bytes > 0 && !con->got_fields)
+ {
+ /*
+ * Remaining text needs to go out...
+ */
+
+ httpPrintf(HTTP(con), "%s", buf);
+
+ con->http.activity = time(NULL);
+ return (1);
+ }
+ else if (bytes == 0)
+ {
+ con->http.activity = time(NULL);
+ return (1);
+ }
+ }
+
+ if (httpWrite(HTTP(con), buf, bytes) < 0)
+ {
+ CloseClient(con);
+ return (0);
+ }
+
+ con->bytes += bytes;
+ }
+
+ if (bytes <= 0)
+ {
+ LogRequest(con, HTTP_OK);
+
+ if (con->http.data_encoding == HTTP_ENCODE_CHUNKED)
+ {
+ if (httpPrintf(HTTP(con), "0\r\n\r\n") < 0)
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+
+ con->http.state = HTTP_WAITING;
+
+ LogMessage(L_DEBUG2, "WriteClient: Removing fd %d from OutputSet...",
+ con->http.fd);
+
+ FD_CLR(con->http.fd, &OutputSet);
+
+ if (con->file)
+ {
+ LogMessage(L_DEBUG2, "WriteClient: Removing fd %d from InputSet...",
+ con->file);
+ FD_CLR(con->file, &InputSet);
+
+ if (con->pipe_pid)
+ kill(con->pipe_pid, SIGTERM);
+
+ LogMessage(L_DEBUG2, "WriteClient: %d Closing data file %d.",
+ con->http.fd, con->file);
+
+ close(con->file);
+ con->file = 0;
+ con->pipe_pid = 0;
+ }
+
+ if (con->filename[0])
+ {
+ LogMessage(L_DEBUG2, "WriteClient: %d Removing temp file %s",
+ con->http.fd, con->filename);
+ unlink(con->filename);
+ con->filename[0] = '\0';
+ }
+
+ if (con->request != NULL)
+ {
+ ippDelete(con->request);
+ con->request = NULL;
+ }
+
+ if (con->response != NULL)
+ {
+ ippDelete(con->response);
+ con->response = NULL;
+ }
+
+ if (!con->http.keep_alive)
+ {
+ CloseClient(con);
+ return (0);
+ }
+ }
+
+ if (bytes >= 1024)
+ LogMessage(L_DEBUG2, "WriteClient() %d %d bytes", con->http.fd, bytes);
+
+ con->http.activity = time(NULL);
+
+ return (1);
+}
+
+
+/*
+ * 'check_if_modified()' - Decode an "If-Modified-Since" line.
+ */
+
+static int /* O - 1 if modified since */
+check_if_modified(client_t *con, /* I - Client connection */
+ struct stat *filestats) /* I - File information */
+{
+ char *ptr; /* Pointer into field */
+ time_t date; /* Time/date value */
+ int size; /* Size/length value */
+
+
+ size = 0;
+ date = 0;
+ ptr = con->http.fields[HTTP_FIELD_IF_MODIFIED_SINCE];
+
+ if (*ptr == '\0')
+ return (1);
+
+ LogMessage(L_DEBUG2, "check_if_modified() %d If-Modified-Since=\"%s\"",
+ con->http.fd, ptr);
+
+ while (*ptr != '\0')
+ {
+ while (isspace(*ptr) || *ptr == ';')
+ ptr ++;
+
+ if (strncasecmp(ptr, "length=", 7) == 0)
+ {
+ ptr += 7;
+ size = atoi(ptr);
+
+ while (isdigit(*ptr))
+ ptr ++;
+ }
+ else if (isalpha(*ptr))
+ {
+ date = httpGetDateTime(ptr);
+ while (*ptr != '\0' && *ptr != ';')
+ ptr ++;
+ }
+ }
+
+ LogMessage(L_DEBUG2, "check_if_modified() %d sizes=%d,%d dates=%d,%d",
+ con->http.fd, size, (int)filestats->st_size, (int)date,
+ (int)filestats->st_mtime);
+
+ return ((size != filestats->st_size && size != 0) ||
+ (date < filestats->st_mtime && date != 0) ||
+ (size == 0 && date == 0));
+}
+
+
+/*
+ * 'decode_auth()' - Decode an authorization string.
+ */
+
+static void
+decode_auth(client_t *con) /* I - Client to decode to */
+{
+ char *s, /* Authorization string */
+ value[1024]; /* Value string */
+ const char *username; /* Certificate username */
+
+
+ /*
+ * Decode the string...
+ */
+
+ s = con->http.fields[HTTP_FIELD_AUTHORIZATION];
+
+ LogMessage(L_DEBUG2, "decode_auth(%p): Authorization string = \"%s\"",
+ con, s);
+ LogMessage(L_INFO, "decode_auth(%p): Authorization string = \"%s\"",
+ con, s);
+
+ if (strncmp(s, "Basic", 5) == 0)
+ {
+ s += 5;
+ while (isspace(*s))
+ s ++;
+
+ httpDecode64(value, s);
+
+ /*
+ * Pull the username and password out...
+ */
+
+ if ((s = strchr(value, ':')) == NULL)
+ {
+ LogMessage(L_DEBUG, "decode_auth() %d no colon in auth string \"%s\"",
+ con->http.fd, value);
+ return;
+ }
+
+ *s++ = '\0';
+
+ strlcpy(con->username, value, sizeof(con->username));
+ strlcpy(con->password, s, sizeof(con->password));
+ }
+ else if (strncmp(s, "Local", 5) == 0)
+ {
+ s += 5;
+ while (isspace(*s))
+ s ++;
+
+ if ((username = FindCert(s)) != NULL)
+ strlcpy(con->username, username, sizeof(con->username));
+ }
+ else if (strncmp(s, "Digest", 5) == 0)
+ {
+ /*
+ * Get the username and password from the Digest attributes...
+ */
+
+ if (httpGetSubField(&(con->http), HTTP_FIELD_AUTHORIZATION, "username",
+ value))
+ strlcpy(con->username, value, sizeof(con->username));
+
+ if (httpGetSubField(&(con->http), HTTP_FIELD_AUTHORIZATION, "response",
+ value))
+ strlcpy(con->password, value, sizeof(con->password));
+ }
+
+ LogMessage(L_DEBUG2, "decode_auth() %d username=\"%s\"",
+ con->http.fd, con->username);
+}
+
+
+/*
+ * 'get_file()' - Get a filename and state info.
+ */
+
+static char * /* O - Real filename */
+get_file(client_t *con, /* I - Client connection */
+ struct stat *filestats)/* O - File information */
+{
+ int status; /* Status of filesystem calls */
+ char *params; /* Pointer to parameters in URI */
+ static char filename[1024]; /* Filename buffer */
+
+
+ /*
+ * Need to add DocumentRoot global...
+ */
+
+ if (strncmp(con->uri, "/ppd/", 5) == 0)
+ snprintf(filename, sizeof(filename), "%s%s", ServerRoot, con->uri);
+ else if (strncmp(con->uri, "/admin/conf/", 12) == 0)
+ snprintf(filename, sizeof(filename), "%s%s", ServerRoot, con->uri + 11);
+ else if (con->language != NULL)
+ snprintf(filename, sizeof(filename), "%s/%s%s", DocumentRoot, con->language->language,
+ con->uri);
+ else
+ snprintf(filename, sizeof(filename), "%s%s", DocumentRoot, con->uri);
+
+ if ((params = strchr(filename, '?')) != NULL)
+ *params = '\0';
+
+ /*
+ * Grab the status for this language; if there isn't a language-specific file
+ * then fallback to the default one...
+ */
+
+ if ((status = stat(filename, filestats)) != 0 && con->language != NULL)
+ {
+ /*
+ * Drop the language prefix and try the current directory...
+ */
+
+ if (strncmp(con->uri, "/ppd/", 5) != 0 &&
+ strncmp(con->uri, "/admin/conf/", 12) != 0)
+ {
+ snprintf(filename, sizeof(filename), "%s%s", DocumentRoot, con->uri);
+
+ status = stat(filename, filestats);
+ }
+ }
+
+ /*
+ * If we're found a directory, get the index.html file instead...
+ */
+
+ if (!status && S_ISDIR(filestats->st_mode))
+ {
+ if (filename[strlen(filename) - 1] == '/')
+ strlcat(filename, "index.html", sizeof(filename));
+ else
+ strlcat(filename, "/index.html", sizeof(filename));
+
+ status = stat(filename, filestats);
+ }
+
+ LogMessage(L_DEBUG2, "get_file() %d filename=%s size=%d",
+ con->http.fd, filename, status ? -1 : (int)filestats->st_size);
+
+ if (status)
+ return (NULL);
+ else
+ return (filename);
+}
+
+
+/*
+ * 'install_conf_file()' - Install a configuration file.
+ */
+
+static http_status_t /* O - Status */
+install_conf_file(client_t *con) /* I - Connection */
+{
+ FILE *in, /* Input file */
+ *out; /* Output file */
+ char buffer[1024]; /* Copy buffer */
+ int bytes; /* Number of bytes */
+ char conffile[1024], /* Configuration filename */
+ newfile[1024], /* New config filename */
+ oldfile[1024]; /* Old config filename */
+ struct stat confinfo; /* Config file info */
+
+
+ /*
+ * First construct the filenames...
+ */
+
+ snprintf(conffile, sizeof(conffile), "%s%s", ServerRoot, con->uri + 11);
+ snprintf(newfile, sizeof(newfile), "%s%s.N", ServerRoot, con->uri + 11);
+ snprintf(oldfile, sizeof(oldfile), "%s%s.O", ServerRoot, con->uri + 11);
+
+ LogMessage(L_INFO, "Installing config file \"%s\"...", conffile);
+
+ /*
+ * Get the owner, group, and permissions of the configuration file.
+ * If it doesn't exist, assign it to the User and Group in the
+ * cupsd.conf file with mode 0640 permissions.
+ */
+
+ if (stat(conffile, &confinfo))
+ {
+ confinfo.st_uid = User;
+ confinfo.st_gid = Group;
+ confinfo.st_mode = 0640;
+ }
+
+ /*
+ * Open the request file and new config file...
+ */
+
+ if ((in = fopen(con->filename, "rb")) == NULL)
+ {
+ LogMessage(L_ERROR, "Unable to open request file \"%s\" - %s",
+ con->filename, strerror(errno));
+ return (HTTP_SERVER_ERROR);
+ }
+
+ if ((out = fopen(newfile, "wb")) == NULL)
+ {
+ fclose(in);
+ LogMessage(L_ERROR, "Unable to open config file \"%s\" - %s",
+ newfile, strerror(errno));
+ return (HTTP_SERVER_ERROR);
+ }
+
+ fchmod(fileno(out), confinfo.st_mode);
+ fchown(fileno(out), confinfo.st_uid, confinfo.st_gid);
+
+ /*
+ * Copy from the request to the new config file...
+ */
+
+ while ((bytes = fread(buffer, 1, sizeof(buffer), in)) > 0)
+ if (fwrite(buffer, 1, bytes, out) < bytes)
+ {
+ LogMessage(L_ERROR, "Unable to copy to config file \"%s\" - %s",
+ newfile, strerror(errno));
+
+ fclose(in);
+ fclose(out);
+ unlink(newfile);
+
+ return (HTTP_SERVER_ERROR);
+ }
+
+ /*
+ * Close the files...
+ */
+
+ fclose(in);
+ if (fclose(out))
+ {
+ LogMessage(L_ERROR, "Error file closing config file \"%s\" - %s",
+ newfile, strerror(errno));
+
+ unlink(newfile);
+
+ return (HTTP_SERVER_ERROR);
+ }
+
+ /*
+ * Remove the request file...
+ */
+
+ unlink(con->filename);
+ con->filename[0] = '\0';
+
+ /*
+ * Unlink the old backup, rename the current config file to the backup
+ * filename, and rename the new config file to the config file name...
+ */
+
+ if (unlink(oldfile))
+ if (errno != ENOENT)
+ {
+ LogMessage(L_ERROR, "Unable to remove backup config file \"%s\" - %s",
+ oldfile, strerror(errno));
+
+ unlink(newfile);
+
+ return (HTTP_SERVER_ERROR);
+ }
+
+ if (rename(conffile, oldfile))
+ if (errno != ENOENT)
+ {
+ LogMessage(L_ERROR, "Unable to rename old config file \"%s\" - %s",
+ conffile, strerror(errno));
+
+ unlink(newfile);
+
+ return (HTTP_SERVER_ERROR);
+ }
+
+ if (rename(newfile, conffile))
+ {
+ LogMessage(L_ERROR, "Unable to rename new config file \"%s\" - %s",
+ newfile, strerror(errno));
+
+ rename(oldfile, conffile);
+ unlink(newfile);
+
+ return (HTTP_SERVER_ERROR);
+ }
+
+ /*
+ * If the cupsd.conf file was updated, set the NeedReload flag...
+ */
+
+ if (strcmp(con->uri, "/admin/conf/cupsd.conf") == 0)
+ NeedReload = TRUE;
+
+ /*
+ * Return that the file was created successfully...
+ */
+
+ return (HTTP_CREATED);
+}
+
+
+/*
+ * 'pipe_command()' - Pipe the output of a command to the remote client.
+ */
+
+static int /* O - Process ID */
+pipe_command(client_t *con, /* I - Client connection */
+ int infile, /* I - Standard input for command */
+ int *outfile, /* O - Standard output for command */
+ char *command, /* I - Command to run */
+ char *options) /* I - Options for command */
+{
+ int i; /* Looping var */
+ int pid; /* Process ID */
+ char *commptr; /* Command string pointer */
+ int fd; /* Looping var */
+ int fds[2]; /* Pipe FDs */
+ int argc; /* Number of arguments */
+ int envc; /* Number of environment variables */
+ char argbuf[10240], /* Argument buffer */
+ *argv[100], /* Argument strings */
+ *envp[100]; /* Environment variables */
+ char lang[1024], /* LANG env variable */
+ content_length[1024], /* CONTENT_LENGTH env variable */
+ content_type[1024], /* CONTENT_TYPE env variable */
+ ipp_port[1024], /* Default listen port */
+ server_port[1024], /* Default server port */
+ server_name[1024], /* Default listen hostname */
+ remote_host[1024], /* REMOTE_HOST env variable */
+ remote_user[1024], /* REMOTE_USER env variable */
+ tmpdir[1024], /* TMPDIR environment variable */
+ ldpath[1024], /* LD_LIBRARY_PATH environment variable */
+ nlspath[1024], /* NLSPATH environment variable */
+ datadir[1024], /* CUPS_DATADIR environment variable */
+ root[1024], /* CUPS_SERVERROOT environment variable */
+ query_string[10240]; /* QUERY_STRING env variable */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ sigset_t oldmask, /* POSIX signal masks */
+ newmask;
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Copy the command string...
+ */
+
+ strlcpy(argbuf, options, sizeof(argbuf));
+
+ /*
+ * Parse the string; arguments can be separated by + and are terminated
+ * by ?...
+ */
+
+ argv[0] = argbuf;
+
+ for (commptr = argbuf, argc = 1; *commptr != '\0' && argc < 99; commptr ++)
+ if (*commptr == ' ' || *commptr == '+')
+ {
+ *commptr++ = '\0';
+
+ while (*commptr == ' ')
+ commptr ++;
+
+ if (*commptr != '\0')
+ {
+ argv[argc] = commptr;
+ argc ++;
+ }
+
+ commptr --;
+ }
+ else if (*commptr == '%')
+ {
+ if (commptr[1] >= '0' && commptr[1] <= '9')
+ *commptr = (commptr[1] - '0') << 4;
+ else
+ *commptr = (tolower(commptr[1]) - 'a' + 10) << 4;
+
+ if (commptr[2] >= '0' && commptr[2] <= '9')
+ *commptr |= commptr[2] - '0';
+ else
+ *commptr |= tolower(commptr[2]) - 'a' + 10;
+
+ strcpy(commptr + 1, commptr + 3);
+ }
+ else if (*commptr == '?')
+ break;
+
+ argv[argc] = NULL;
+
+ if (argv[0][0] == '\0')
+ argv[0] = strrchr(command, '/') + 1;
+
+ /*
+ * Setup the environment variables as needed...
+ */
+
+ snprintf(lang, sizeof(lang), "LANG=%s",
+ con->language ? con->language->language : "C");
+ sprintf(ipp_port, "IPP_PORT=%d", ntohs(con->http.hostaddr.sin_port));
+ sprintf(server_port, "SERVER_PORT=%d", ntohs(con->http.hostaddr.sin_port));
+ snprintf(server_name, sizeof(server_name), "SERVER_NAME=%s", ServerName);
+ snprintf(remote_host, sizeof(remote_host), "REMOTE_HOST=%s", con->http.hostname);
+ snprintf(remote_user, sizeof(remote_user), "REMOTE_USER=%s", con->username);
+ snprintf(tmpdir, sizeof(tmpdir), "TMPDIR=%s", TempDir);
+ snprintf(datadir, sizeof(datadir), "CUPS_DATADIR=%s", DataDir);
+ snprintf(root, sizeof(root), "CUPS_SERVERROOT=%s", ServerRoot);
+
+ if (getenv("LD_LIBRARY_PATH") != NULL)
+ snprintf(ldpath, sizeof(ldpath), "LD_LIBRARY_PATH=%s",
+ getenv("LD_LIBRARY_PATH"));
+ else if (getenv("DYLD_LIBRARY_PATH") != NULL)
+ snprintf(ldpath, sizeof(ldpath), "DYLD_LIBRARY_PATH=%s",
+ getenv("DYLD_LIBRARY_PATH"));
+ else if (getenv("SHLIB_PATH") != NULL)
+ snprintf(ldpath, sizeof(ldpath), "SHLIB_PATH=%s",
+ getenv("SHLIB_PATH"));
+ else
+ ldpath[0] = '\0';
+
+ if (getenv("NLSPATH") != NULL)
+ snprintf(nlspath, sizeof(nlspath), "NLSPATH=%s", getenv("NLSPATH"));
+ else
+ nlspath[0] = '\0';
+
+ envp[0] = "PATH=/bin:/usr/bin";
+ envp[1] = "SERVER_SOFTWARE=CUPS/1.1";
+ envp[2] = "GATEWAY_INTERFACE=CGI/1.1";
+ envp[3] = "SERVER_PROTOCOL=HTTP/1.1";
+ envp[4] = ipp_port;
+ envp[5] = server_name;
+ envp[6] = server_port;
+ envp[7] = remote_host;
+ envp[8] = remote_user;
+ envp[9] = lang;
+ envp[10] = TZ;
+ envp[11] = tmpdir;
+ envp[12] = datadir;
+ envp[13] = root;
+
+ envc = 14;
+
+ if (ldpath[0])
+ envp[envc ++] = ldpath;
+
+ if (nlspath[0])
+ envp[envc ++] = nlspath;
+
+ if (con->operation == HTTP_GET)
+ {
+ envp[envc ++] = "REQUEST_METHOD=GET";
+
+ if (*commptr)
+ {
+ /*
+ * Add GET form variables after ?...
+ */
+
+ *commptr++ = '\0';
+
+ snprintf(query_string, sizeof(query_string), "QUERY_STRING=%s", commptr);
+ envp[envc ++] = query_string;
+ }
+ }
+ else
+ {
+ sprintf(content_length, "CONTENT_LENGTH=%d", con->bytes);
+ snprintf(content_type, sizeof(content_type), "CONTENT_TYPE=%s",
+ con->http.fields[HTTP_FIELD_CONTENT_TYPE]);
+
+ envp[envc ++] = "REQUEST_METHOD=POST";
+ envp[envc ++] = content_length;
+ envp[envc ++] = content_type;
+ }
+
+ /*
+ * Tell the CGI if we are using encryption...
+ */
+
+ if (con->http.encryption == HTTP_ENCRYPT_ALWAYS)
+ {
+ envp[envc ++] = "HTTPS=ON";
+ envp[envc ++] = "CUPS_ENCRYPTION=Always";
+ }
+
+ envp[envc] = NULL;
+
+ if (LogLevel == L_DEBUG2)
+ {
+ for (i = 0; i < envc; i ++)
+ LogMessage(L_DEBUG2, "envp[%d] = \"%s\"", i, envp[i]);
+ }
+
+ /*
+ * Create a pipe for the output...
+ */
+
+ if (pipe(fds))
+ {
+ LogMessage(L_ERROR, "Unable to create pipes for CGI %s - %s",
+ argv[0], strerror(errno));
+ return (0);
+ }
+
+ /*
+ * Block signals before forking...
+ */
+
+#ifdef HAVE_SIGSET
+ sighold(SIGTERM);
+ sighold(SIGCHLD);
+#elif defined(HAVE_SIGACTION)
+ sigemptyset(&newmask);
+ sigaddset(&newmask, SIGTERM);
+ sigaddset(&newmask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &newmask, &oldmask);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Then execute the command...
+ */
+
+ if ((pid = fork()) == 0)
+ {
+ /*
+ * Child comes here... Close stdin if necessary and dup the pipe to stdout.
+ */
+
+ if (getuid() == 0)
+ {
+ /*
+ * Running as root, so change to a non-priviledged user...
+ */
+
+ if (setgid(Group))
+ exit(errno);
+
+ if (setuid(User))
+ exit(errno);
+ }
+
+ /*
+ * Reset group membership to just the main one we belong to.
+ */
+
+ setgroups(0, NULL);
+
+ /*
+ * Update stdin/stdout/stderr...
+ */
+
+ if (infile)
+ {
+ close(0);
+ if (dup(infile) < 0)
+ exit(errno);
+ }
+
+ close(1);
+ if (dup(fds[1]) < 0)
+ exit(errno);
+
+ close(2);
+ open("/dev/null", O_WRONLY);
+
+ /*
+ * Close extra file descriptors...
+ */
+
+ for (fd = 3; fd < MaxFDs; fd ++)
+ close(fd);
+
+ /*
+ * Change umask to restrict permissions on created files...
+ */
+
+ umask(077);
+
+ /*
+ * Execute the pipe program; if an error occurs, exit with status 1...
+ */
+
+ execve(command, argv, envp);
+ exit(errno);
+ return (0);
+ }
+ else if (pid < 0)
+ {
+ /*
+ * Error - can't fork!
+ */
+
+ LogMessage(L_ERROR, "Unable to fork for CGI %s - %s", argv[0],
+ strerror(errno));
+
+ close(fds[0]);
+ close(fds[1]);
+ pid = 0;
+ }
+ else
+ {
+ /*
+ * Fork successful - return the PID...
+ */
+
+ AddCert(pid, con->username);
+
+ LogMessage(L_DEBUG, "CGI %s started - PID = %d", command, pid);
+
+ *outfile = fds[0];
+ close(fds[1]);
+ }
+
+#ifdef HAVE_SIGSET
+ sigrelse(SIGTERM);
+ sigrelse(SIGCHLD);
+#elif defined(HAVE_SIGACTION)
+ sigprocmask(SIG_SETMASK, &oldmask, NULL);
+#endif /* HAVE_SIGSET */
+
+ return (pid);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/client.h b/scheduler/client.h
new file mode 100644
index 000000000..1d6917306
--- /dev/null
+++ b/scheduler/client.h
@@ -0,0 +1,105 @@
+/*
+ * "$Id$"
+ *
+ * Client definitions for the Common UNIX Printing System (CUPS) scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * HTTP client structure...
+ */
+
+typedef struct
+{
+ http_t http; /* HTTP client connection */
+ ipp_t *request, /* IPP request information */
+ *response; /* IPP response information */
+ time_t start; /* Request start time */
+ http_state_t operation; /* Request operation */
+ int bytes; /* Bytes transferred for this request */
+ char username[33], /* Username from Authorization: line */
+ password[33], /* Password from Authorization: line */
+ uri[HTTP_MAX_URI], /* Localized URL/URI for GET/PUT */
+ filename[HTTP_MAX_URI], /* Filename of output file */
+ command[HTTP_MAX_URI], /* Command to run */
+ *options; /* Options for command */
+ int file; /* Input/output file */
+ int pipe_pid; /* Pipe process ID (or 0 if not a pipe) */
+ int got_fields, /* Non-zero if all fields seen */
+ field_col; /* Column within line */
+ cups_lang_t *language; /* Language to use */
+} client_t;
+
+#define HTTP(con) &((con)->http)
+
+
+/*
+ * HTTP listener structure...
+ */
+
+typedef struct
+{
+ int fd; /* File descriptor for this server */
+ struct sockaddr_in address; /* Bind address of socket */
+ http_encryption_t encryption; /* To encrypt or not to encrypt... */
+} listener_t;
+
+
+/*
+ * Globals...
+ */
+
+VAR int ListenBackLog VALUE(SOMAXCONN);
+VAR int NumListeners VALUE(0);
+ /* Number of listening sockets */
+VAR listener_t Listeners[MAX_LISTENERS];
+ /* Listening sockets */
+VAR int NumClients VALUE(0);
+ /* Number of HTTP clients */
+VAR client_t *Clients VALUE(NULL);
+ /* HTTP clients */
+VAR struct sockaddr_in ServerAddr; /* Server IP address */
+
+
+/*
+ * Prototypes...
+ */
+
+extern void AcceptClient(listener_t *lis);
+extern void CloseAllClients(void);
+extern void CloseClient(client_t *con);
+extern int EncryptClient(client_t *con);
+extern void PauseListening(void);
+extern void ProcessIPPRequest(client_t *con);
+extern int ReadClient(client_t *con);
+extern void ResumeListening(void);
+extern int SendCommand(client_t *con, char *command, char *options);
+extern int SendError(client_t *con, http_status_t code);
+extern int SendFile(client_t *con, http_status_t code, char *filename,
+ char *type, struct stat *filestats);
+extern int SendHeader(client_t *con, http_status_t code, char *type);
+extern void ShutdownClient(client_t *con);
+extern void StartListening(void);
+extern void StopListening(void);
+extern int WriteClient(client_t *con);
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/conf.c b/scheduler/conf.c
new file mode 100644
index 000000000..5324a821e
--- /dev/null
+++ b/scheduler/conf.c
@@ -0,0 +1,1894 @@
+/*
+ * "$Id$"
+ *
+ * Configuration routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * ReadConfiguration() - Read the cupsd.conf file.
+ * read_configuration() - Read a configuration file.
+ * read_location() - Read a <Location path> definition.
+ * get_address() - Get an address + port number from a line.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+#include <stdarg.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/resource.h>
+
+#ifdef HAVE_VSYSLOG
+# include <syslog.h>
+#endif /* HAVE_VSYSLOG */
+
+
+/*
+ * Possibly missing network definitions...
+ */
+
+#ifndef INADDR_NONE
+# define INADDR_NONE 0xffffffff
+#endif /* !INADDR_NONE */
+
+
+/*
+ * Configuration variable structure...
+ */
+
+typedef struct
+{
+ char *name; /* Name of variable */
+ void *ptr; /* Pointer to variable */
+ int type, /* Type (int, string, address) */
+ size; /* Size of string */
+} var_t;
+
+#define VAR_INTEGER 0
+#define VAR_STRING 1
+#define VAR_BOOLEAN 2
+
+
+/*
+ * Local globals...
+ */
+
+static var_t variables[] =
+{
+ { "AccessLog", AccessLog, VAR_STRING, sizeof(AccessLog) },
+ { "AutoPurgeJobs", &JobAutoPurge, VAR_BOOLEAN, 0 },
+ { "BrowseInterval", &BrowseInterval, VAR_INTEGER, 0 },
+ { "BrowsePort", &BrowsePort, VAR_INTEGER, 0 },
+ { "BrowseShortNames", &BrowseShortNames, VAR_BOOLEAN, 0 },
+ { "BrowseTimeout", &BrowseTimeout, VAR_INTEGER, 0 },
+ { "Browsing", &Browsing, VAR_BOOLEAN, 0 },
+ { "Classification", Classification, VAR_STRING, sizeof(Classification) },
+ { "ClassifyOverride", &ClassifyOverride, VAR_BOOLEAN, 0 },
+ { "ConfigFilePerm", &ConfigFilePerm, VAR_INTEGER, 0 },
+ { "DataDir", DataDir, VAR_STRING, sizeof(DataDir) },
+ { "DefaultCharset", DefaultCharset, VAR_STRING, sizeof(DefaultCharset) },
+ { "DefaultLanguage", DefaultLanguage, VAR_STRING, sizeof(DefaultLanguage) },
+ { "DocumentRoot", DocumentRoot, VAR_STRING, sizeof(DocumentRoot) },
+ { "ErrorLog", ErrorLog, VAR_STRING, sizeof(ErrorLog) },
+ { "FilterLimit", &FilterLimit, VAR_INTEGER, 0 },
+ { "FilterNice", &FilterNice, VAR_INTEGER, 0 },
+ { "FontPath", FontPath, VAR_STRING, sizeof(FontPath) },
+ { "HideImplicitMembers", &HideImplicitMembers, VAR_BOOLEAN, 0 },
+ { "ImplicitClasses", &ImplicitClasses, VAR_BOOLEAN, 0 },
+ { "ImplicitAnyClasses", &ImplicitAnyClasses, VAR_BOOLEAN, 0 },
+ { "KeepAliveTimeout", &KeepAliveTimeout, VAR_INTEGER, 0 },
+ { "KeepAlive", &KeepAlive, VAR_BOOLEAN, 0 },
+ { "LimitRequestBody", &MaxRequestSize, VAR_INTEGER, 0 },
+ { "ListenBackLog", &ListenBackLog, VAR_INTEGER, 0 },
+ { "LogFilePerm", &LogFilePerm, VAR_INTEGER, 0 },
+ { "MaxClients", &MaxClients, VAR_INTEGER, 0 },
+ { "MaxCopies", &MaxCopies, VAR_INTEGER, 0 },
+ { "MaxJobs", &MaxJobs, VAR_INTEGER, 0 },
+ { "MaxJobsPerPrinter",&MaxJobsPerPrinter, VAR_INTEGER, 0 },
+ { "MaxJobsPerUser", &MaxJobsPerUser, VAR_INTEGER, 0 },
+ { "MaxLogSize", &MaxLogSize, VAR_INTEGER, 0 },
+ { "MaxRequestSize", &MaxRequestSize, VAR_INTEGER, 0 },
+ { "PageLog", PageLog, VAR_STRING, sizeof(PageLog) },
+ { "PreserveJobFiles", &JobFiles, VAR_BOOLEAN, 0 },
+ { "PreserveJobHistory", &JobHistory, VAR_BOOLEAN, 0 },
+ { "Printcap", Printcap, VAR_STRING, sizeof(Printcap) },
+ { "PrintcapGUI", PrintcapGUI, VAR_STRING, sizeof(PrintcapGUI) },
+ { "RemoteRoot", RemoteRoot, VAR_STRING, sizeof(RemoteRoot) },
+ { "RequestRoot", RequestRoot, VAR_STRING, sizeof(RequestRoot) },
+ { "RIPCache", RIPCache, VAR_STRING, sizeof(RIPCache) },
+ { "RunAsUser", &RunAsUser, VAR_BOOLEAN, 0 },
+ { "RootCertDuration", &RootCertDuration, VAR_INTEGER, 0 },
+ { "ServerAdmin", ServerAdmin, VAR_STRING, sizeof(ServerAdmin) },
+ { "ServerBin", ServerBin, VAR_STRING, sizeof(ServerBin) },
+#ifdef HAVE_LIBSSL
+ { "ServerCertificate",ServerCertificate, VAR_STRING, sizeof(ServerCertificate) },
+ { "ServerKey", ServerKey, VAR_STRING, sizeof(ServerKey) },
+#endif /* HAVE_LIBSSL */
+ { "ServerName", ServerName, VAR_STRING, sizeof(ServerName) },
+ { "ServerRoot", ServerRoot, VAR_STRING, sizeof(ServerRoot) },
+ { "TempDir", TempDir, VAR_STRING, sizeof(TempDir) },
+ { "Timeout", &Timeout, VAR_INTEGER, 0 }
+};
+#define NUM_VARS (sizeof(variables) / sizeof(variables[0]))
+
+
+/*
+ * Local functions...
+ */
+
+static int read_configuration(FILE *fp);
+static int read_location(FILE *fp, char *name, int linenum);
+static int get_address(char *value, unsigned defaddress, int defport,
+ struct sockaddr_in *address);
+
+
+/*
+ * 'ReadConfiguration()' - Read the cupsd.conf file.
+ */
+
+int /* O - 1 if file read successfully, 0 otherwise */
+ReadConfiguration(void)
+{
+ int i; /* Looping var */
+ FILE *fp; /* Configuration file */
+ int status; /* Return status */
+ char directory[1024],/* Configuration directory */
+ *slash; /* Directory separator */
+ char type[MIME_MAX_SUPER + MIME_MAX_TYPE];
+ /* MIME type name */
+ struct rlimit limit; /* Runtime limit */
+ char *language; /* Language string */
+ struct passwd *user; /* Default user */
+ struct group *group; /* Default group */
+
+
+ /*
+ * Shutdown the server...
+ */
+
+ StopServer();
+
+ /*
+ * Free all memory...
+ */
+
+ FreeAllJobs();
+ DeleteAllClasses();
+ DeleteAllLocations();
+ DeleteAllPrinters();
+
+ DefaultPrinter = NULL;
+
+ if (Devices)
+ {
+ ippDelete(Devices);
+ Devices = NULL;
+ }
+
+ if (PPDs)
+ {
+ ippDelete(PPDs);
+ PPDs = NULL;
+ }
+
+ if (MimeDatabase != NULL)
+ mimeDelete(MimeDatabase);
+
+ if (NumMimeTypes)
+ {
+ for (i = 0; i < NumMimeTypes; i ++)
+ free((void *)MimeTypes[i]);
+
+ free(MimeTypes);
+ }
+
+ for (i = 0; i < NumRelays; i ++)
+ if (Relays[i].from.type == AUTH_NAME)
+ free(Relays[i].from.mask.name.name);
+
+ NumRelays = 0;
+
+ /*
+ * Reset the current configuration to the defaults...
+ */
+
+ NeedReload = FALSE;
+
+ /*
+ * String options...
+ */
+
+ gethostname(ServerName, sizeof(ServerName));
+ snprintf(ServerAdmin, sizeof(ServerAdmin), "root@%s", ServerName);
+ strcpy(ServerBin, CUPS_SERVERBIN);
+ strcpy(RequestRoot, CUPS_REQUESTS);
+ strcpy(DocumentRoot, CUPS_DOCROOT);
+ strcpy(DataDir, CUPS_DATADIR);
+ strcpy(AccessLog, CUPS_LOGDIR "/access_log");
+ strcpy(ErrorLog, CUPS_LOGDIR "/error_log");
+ strcpy(PageLog, CUPS_LOGDIR "/page_log");
+ strcpy(Printcap, "/etc/printcap");
+ strcpy(PrintcapGUI, "/usr/bin/glpoptions");
+ strcpy(FontPath, CUPS_FONTPATH);
+ strcpy(RemoteRoot, "remroot");
+
+ strcpy(ServerRoot, ConfigurationFile);
+ if ((slash = strrchr(ServerRoot, '/')) != NULL)
+ *slash = '\0';
+
+ Classification[0] = '\0';
+ ClassifyOverride = 0;
+
+#ifdef HAVE_LIBSSL
+ strcpy(ServerCertificate, "ssl/server.crt");
+ strcpy(ServerKey, "ssl/server.key");
+#endif /* HAVE_LIBSSL */
+
+ if ((language = DEFAULT_LANGUAGE) == NULL)
+ language = "en";
+ else if (strcmp(language, "C") == 0 || strcmp(language, "POSIX") == 0)
+ language = "en";
+
+ strlcpy(DefaultLanguage, language, sizeof(DefaultLanguage));
+
+ strcpy(DefaultCharset, DEFAULT_CHARSET);
+
+ strcpy(RIPCache, "8m");
+
+ if (getenv("TMPDIR") == NULL)
+ strcpy(TempDir, CUPS_REQUESTS "/tmp");
+ else
+ strlcpy(TempDir, getenv("TMPDIR"), sizeof(TempDir));
+
+ /*
+ * Find the default system group: "sys", "system", or "root"...
+ */
+
+ group = getgrnam(CUPS_DEFAULT_GROUP);
+ endgrent();
+
+ NumSystemGroups = 0;
+
+ if (group != NULL)
+ {
+ strcpy(SystemGroups[0], CUPS_DEFAULT_GROUP);
+ Group = group->gr_gid;
+ }
+ else
+ {
+ group = getgrgid(0);
+ endgrent();
+
+ if (group != NULL)
+ {
+ strcpy(SystemGroups[0], group->gr_name);
+ Group = 0;
+ }
+ else
+ {
+ strcpy(SystemGroups[0], "unknown");
+ Group = 0;
+ }
+ }
+
+ /*
+ * Find the default user...
+ */
+
+ if ((user = getpwnam(CUPS_DEFAULT_USER)) == NULL)
+ User = 1; /* Force to a non-priviledged account */
+ else
+ User = user->pw_uid;
+
+ endpwent();
+
+ /*
+ * Numeric options...
+ */
+
+ ConfigFilePerm = 0600;
+ LogFilePerm = 0644;
+
+ FilterLevel = 0;
+ FilterLimit = 0;
+ FilterNice = 0;
+ HostNameLookups = FALSE;
+ ImplicitClasses = TRUE;
+ ImplicitAnyClasses = FALSE;
+ HideImplicitMembers = TRUE;
+ KeepAlive = TRUE;
+ KeepAliveTimeout = DEFAULT_KEEPALIVE;
+ ListenBackLog = SOMAXCONN;
+ LogLevel = L_ERROR;
+ MaxClients = 100;
+ MaxLogSize = 1024 * 1024;
+ MaxRequestSize = 0;
+ RootCertDuration = 300;
+ RunAsUser = FALSE;
+ Timeout = DEFAULT_TIMEOUT;
+
+ BrowseInterval = DEFAULT_INTERVAL;
+ BrowsePort = ippPort();
+ BrowseProtocols = BROWSE_CUPS;
+ BrowseShortNames = TRUE;
+ BrowseTimeout = DEFAULT_TIMEOUT;
+ Browsing = TRUE;
+ NumBrowsers = 0;
+ NumPolled = 0;
+
+ NumListeners = 0;
+
+ JobHistory = DEFAULT_HISTORY;
+ JobFiles = DEFAULT_FILES;
+ JobAutoPurge = 0;
+ MaxJobs = 500;
+ MaxJobsPerUser = 0;
+ MaxJobsPerPrinter = 0;
+ MaxCopies = 100;
+
+ /*
+ * Read the configuration file...
+ */
+
+ if ((fp = fopen(ConfigurationFile, "r")) == NULL)
+ return (0);
+
+ status = read_configuration(fp);
+
+ fclose(fp);
+
+ if (!status)
+ return (0);
+
+ /*
+ * Use the default system group if none was supplied in cupsd.conf...
+ */
+
+ if (NumSystemGroups == 0)
+ NumSystemGroups ++;
+
+ /*
+ * Get the access control list for browsing...
+ */
+
+ BrowseACL = FindLocation("CUPS_INTERNAL_BROWSE_ACL");
+
+ /*
+ * Open the system log for cupsd if necessary...
+ */
+
+#ifdef HAVE_VSYSLOG
+ if (strcmp(AccessLog, "syslog") == 0 ||
+ strcmp(ErrorLog, "syslog") == 0 ||
+ strcmp(PageLog, "syslog") == 0)
+ openlog("cupsd", LOG_PID | LOG_NOWAIT | LOG_NDELAY, LOG_LPR);
+#endif /* HAVE_VSYSLOG */
+
+ /*
+ * Log the configuration file that was used...
+ */
+
+ LogMessage(L_DEBUG, "ReadConfiguration() ConfigurationFile=\"%s\"",
+ ConfigurationFile);
+
+ /*
+ * Update all relative filenames to include the full path from ServerRoot...
+ */
+
+ if (DocumentRoot[0] != '/')
+ {
+ snprintf(directory, sizeof(directory), "%s/%s", ServerRoot, DocumentRoot);
+ strlcpy(DocumentRoot, directory, sizeof(DocumentRoot));
+ }
+
+ if (RequestRoot[0] != '/')
+ {
+ snprintf(directory, sizeof(directory), "%s/%s", ServerRoot, RequestRoot);
+ strlcpy(RequestRoot, directory, sizeof(RequestRoot));
+ }
+
+ if (ServerBin[0] != '/')
+ {
+ snprintf(directory, sizeof(directory), "%s/%s", ServerRoot, ServerBin);
+ strlcpy(ServerBin, directory, sizeof(ServerBin));
+ }
+
+#ifdef HAVE_LIBSSL
+ if (ServerCertificate[0] != '/')
+ {
+ snprintf(directory, sizeof(directory), "%s/%s", ServerRoot, ServerCertificate);
+ strlcpy(ServerCertificate, directory, sizeof(ServerCertificate));
+ }
+
+ chown(ServerCertificate, User, Group);
+ chmod(ServerCertificate, ConfigFilePerm);
+
+ if (ServerKey[0] != '/')
+ {
+ snprintf(directory, sizeof(directory), "%s/%s", ServerRoot, ServerKey);
+ strlcpy(ServerKey, directory, sizeof(ServerKey));
+ }
+
+ chown(ServerKey, User, Group);
+ chmod(ServerKey, ConfigFilePerm);
+#endif /* HAVE_LIBSSL */
+
+ /*
+ * Make sure that ServerRoot and the config files are owned and
+ * writable by the user and group in the cupsd.conf file...
+ */
+
+ chown(ServerRoot, User, Group);
+ chmod(ServerRoot, 0755);
+
+ snprintf(directory, sizeof(directory), "%s/certs", ServerRoot);
+ chown(directory, User, Group);
+ chmod(directory, 0711);
+
+ snprintf(directory, sizeof(directory), "%s/ppd", ServerRoot);
+ chown(directory, User, Group);
+ chmod(directory, 0755);
+
+ snprintf(directory, sizeof(directory), "%s/ssl", ServerRoot);
+ chown(directory, User, Group);
+ chmod(directory, 0700);
+
+ snprintf(directory, sizeof(directory), "%s/cupsd.conf", ServerRoot);
+ chown(directory, User, Group);
+ chmod(directory, ConfigFilePerm);
+
+ snprintf(directory, sizeof(directory), "%s/classes.conf", ServerRoot);
+ chown(directory, User, Group);
+ chmod(directory, ConfigFilePerm);
+
+ snprintf(directory, sizeof(directory), "%s/printers.conf", ServerRoot);
+ chown(directory, User, Group);
+ chmod(directory, ConfigFilePerm);
+
+ snprintf(directory, sizeof(directory), "%s/passwd.md5", ServerRoot);
+ chown(directory, User, Group);
+ chmod(directory, 0600);
+
+ /*
+ * Make sure the request and temporary directories have the right
+ * permissions...
+ */
+
+ chown(RequestRoot, User, Group);
+ chmod(RequestRoot, 0700);
+
+ if (strncmp(TempDir, RequestRoot, strlen(RequestRoot)) == 0)
+ {
+ /*
+ * Only update ownership and permissions if the CUPS temp directory
+ * is under the spool directory...
+ */
+
+ chown(TempDir, User, Group);
+ chmod(TempDir, 01700);
+ }
+
+ /*
+ * Check the MaxClients setting, and then allocate memory for it...
+ */
+
+ getrlimit(RLIMIT_NOFILE, &limit);
+
+ if (MaxClients > (limit.rlim_max / 3) || MaxClients <= 0)
+ MaxClients = limit.rlim_max / 3;
+
+ if ((Clients = calloc(sizeof(client_t), MaxClients)) == NULL)
+ {
+ LogMessage(L_ERROR, "ReadConfiguration: Unable to allocate memory for %d clients: %s",
+ MaxClients, strerror(errno));
+ exit(1);
+ }
+ else
+ LogMessage(L_INFO, "Configured for up to %d clients.", MaxClients);
+
+ if (strcasecmp(Classification, "none") == 0)
+ Classification[0] = '\0';
+
+ if (Classification[0])
+ LogMessage(L_INFO, "Security set to \"%s\"", Classification);
+
+ /*
+ * Read the MIME type and conversion database...
+ */
+
+ snprintf(directory, sizeof(directory), "%s/filter", ServerBin);
+
+ MimeDatabase = mimeNew();
+ mimeMerge(MimeDatabase, ServerRoot, directory);
+
+ /*
+ * Create a list of MIME types for the document-format-supported
+ * attribute...
+ */
+
+ NumMimeTypes = MimeDatabase->num_types;
+ if (!mimeType(MimeDatabase, "application", "octet-stream"))
+ NumMimeTypes ++;
+
+ MimeTypes = calloc(NumMimeTypes, sizeof(const char *));
+
+ for (i = 0; i < MimeDatabase->num_types; i ++)
+ {
+ snprintf(type, sizeof(type), "%s/%s", MimeDatabase->types[i]->super,
+ MimeDatabase->types[i]->type);
+
+ MimeTypes[i] = strdup(type);
+ }
+
+ if (i < NumMimeTypes)
+ MimeTypes[i] = strdup("application/octet-stream");
+
+ /*
+ * Load banners...
+ */
+
+ snprintf(directory, sizeof(directory), "%s/banners", DataDir);
+ LoadBanners(directory);
+
+ /*
+ * Load printers and classes...
+ */
+
+ LoadAllPrinters();
+ LoadAllClasses();
+
+ /*
+ * Load devices and PPDs...
+ */
+
+ snprintf(directory, sizeof(directory), "%s/model", DataDir);
+ LoadPPDs(directory);
+
+ snprintf(directory, sizeof(directory), "%s/backend", ServerBin);
+ LoadDevices(directory);
+
+ /*
+ * Startup the server...
+ */
+
+ StartServer();
+
+ /*
+ * Check for queued jobs...
+ */
+
+ LoadAllJobs();
+ CheckJobs();
+
+ return (1);
+}
+
+
+/*
+ * 'read_configuration()' - Read a configuration file.
+ */
+
+static int /* O - 1 on success, 0 on failure */
+read_configuration(FILE *fp) /* I - File to read from */
+{
+ int i; /* Looping var */
+ int linenum; /* Current line number */
+ int len; /* Length of line */
+ char line[HTTP_MAX_BUFFER], /* Line from file */
+ name[256], /* Parameter name */
+ *nameptr, /* Pointer into name */
+ *value; /* Pointer to value */
+ int valuelen; /* Length of value */
+ var_t *var; /* Current variable */
+ unsigned address, /* Address value */
+ netmask; /* Netmask value */
+ int ip[4], /* IP address components */
+ ipcount, /* Number of components provided */
+ mask[4]; /* IP netmask components */
+ dirsvc_relay_t *relay; /* Relay data */
+ dirsvc_poll_t *poll; /* Polling data */
+ struct sockaddr_in polladdr; /* Polling address */
+ location_t *location; /* Browse location */
+ FILE *incfile; /* Include file */
+ char incname[1024]; /* Include filename */
+ static unsigned netmasks[4] = /* Standard netmasks... */
+ {
+ 0xff000000,
+ 0xffff0000,
+ 0xffffff00,
+ 0xffffffff
+ };
+
+
+ /*
+ * Loop through each line in the file...
+ */
+
+ linenum = 0;
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ linenum ++;
+
+ /*
+ * Skip comment lines...
+ */
+
+ if (line[0] == '#')
+ continue;
+
+ /*
+ * Strip trailing whitespace, if any...
+ */
+
+ len = strlen(line);
+
+ while (len > 0 && isspace(line[len - 1]))
+ {
+ len --;
+ line[len] = '\0';
+ }
+
+ /*
+ * Extract the name from the beginning of the line...
+ */
+
+ for (value = line; isspace(*value); value ++);
+
+ for (nameptr = name; *value != '\0' && !isspace(*value) &&
+ nameptr < (name + sizeof(name) - 1);)
+ *nameptr++ = *value++;
+ *nameptr = '\0';
+
+ while (isspace(*value))
+ value ++;
+
+ if (name[0] == '\0')
+ continue;
+
+ /*
+ * Decode the directive...
+ */
+
+ if (strcasecmp(name, "Include") == 0)
+ {
+ /*
+ * Include filename
+ */
+
+ if (value[0] == '/')
+ strlcpy(incname, value, sizeof(incname));
+ else
+ snprintf(incname, sizeof(incname), "%s/%s", ServerRoot, value);
+
+ if ((incfile = fopen(incname, "rb")) == NULL)
+ LogMessage(L_ERROR, "Unable to include config file \"%s\" - %s",
+ incname, strerror(errno));
+ else
+ {
+ read_configuration(incfile);
+ fclose(incfile);
+ }
+ }
+ else if (strcasecmp(name, "<Location") == 0)
+ {
+ /*
+ * <Location path>
+ */
+
+ if (line[len - 1] == '>')
+ {
+ line[len - 1] = '\0';
+
+ linenum = read_location(fp, value, linenum);
+ if (linenum == 0)
+ return (0);
+ }
+ else
+ {
+ LogMessage(L_ERROR, "ReadConfiguration() Syntax error on line %d.",
+ linenum);
+ return (0);
+ }
+ }
+ else if (strcasecmp(name, "Port") == 0 ||
+ strcasecmp(name, "Listen") == 0)
+ {
+ /*
+ * Add a listening address to the list...
+ */
+
+ if (NumListeners < MAX_LISTENERS)
+ {
+ if (get_address(value, INADDR_ANY, IPP_PORT,
+ &(Listeners[NumListeners].address)))
+ {
+ LogMessage(L_INFO, "Listening to %x:%d",
+ ntohl(Listeners[NumListeners].address.sin_addr.s_addr),
+ ntohs(Listeners[NumListeners].address.sin_port));
+ NumListeners ++;
+ }
+ else
+ LogMessage(L_ERROR, "Bad %s address %s at line %d.", name,
+ value, linenum);
+ }
+ else
+ LogMessage(L_WARN, "Too many %s directives at line %d.", name,
+ linenum);
+ }
+#ifdef HAVE_LIBSSL
+ else if (strcasecmp(name, "SSLPort") == 0 ||
+ strcasecmp(name, "SSLListen") == 0)
+ {
+ /*
+ * Add a listening address to the list...
+ */
+
+ if (NumListeners < MAX_LISTENERS)
+ {
+ if (get_address(value, INADDR_ANY, IPP_PORT,
+ &(Listeners[NumListeners].address)))
+ {
+ LogMessage(L_INFO, "Listening to %x:%d (SSL)",
+ ntohl(Listeners[NumListeners].address.sin_addr.s_addr),
+ ntohs(Listeners[NumListeners].address.sin_port));
+ Listeners[NumListeners].encryption = HTTP_ENCRYPT_ALWAYS;
+ NumListeners ++;
+ }
+ else
+ LogMessage(L_ERROR, "Bad %s address %s at line %d.", name,
+ value, linenum);
+ }
+ else
+ LogMessage(L_WARN, "Too many %s directives at line %d.", name,
+ linenum);
+ }
+#endif /* HAVE_LIBSSL */
+ else if (strcasecmp(name, "BrowseAddress") == 0)
+ {
+ /*
+ * Add a browse address to the list...
+ */
+
+ if (NumBrowsers < MAX_BROWSERS)
+ {
+ memset(Browsers + NumBrowsers, 0, sizeof(dirsvc_addr_t));
+
+ if (strcasecmp(value, "@LOCAL") == 0)
+ {
+ /*
+ * Send browse data to all local interfaces...
+ */
+
+ strcpy(Browsers[NumBrowsers].iface, "*");
+ NumBrowsers ++;
+ }
+ else if (strncasecmp(value, "@IF(", 4) == 0)
+ {
+ /*
+ * Send browse data to the named interface...
+ */
+
+ strlcpy(Browsers[NumBrowsers].iface, value + 4,
+ sizeof(Browsers[0].iface));
+
+ nameptr = Browsers[NumBrowsers].iface +
+ strlen(Browsers[NumBrowsers].iface) - 1;
+ if (*nameptr == ')')
+ *nameptr = '\0';
+
+ NumBrowsers ++;
+ }
+ else if (get_address(value, INADDR_NONE, BrowsePort,
+ &(Browsers[NumBrowsers].to)))
+ {
+ LogMessage(L_INFO, "Sending browsing info to %x:%d",
+ ntohl(Browsers[NumBrowsers].to.sin_addr.s_addr),
+ ntohs(Browsers[NumBrowsers].to.sin_port));
+
+ NumBrowsers ++;
+ }
+ else
+ LogMessage(L_ERROR, "Bad BrowseAddress %s at line %d.", value,
+ linenum);
+ }
+ else
+ LogMessage(L_WARN, "Too many BrowseAddress directives at line %d.",
+ linenum);
+ }
+ else if (strcasecmp(name, "BrowseOrder") == 0)
+ {
+ /*
+ * "BrowseOrder Deny,Allow" or "BrowseOrder Allow,Deny"...
+ */
+
+ if ((location = FindLocation("CUPS_INTERNAL_BROWSE_ACL")) == NULL)
+ location = AddLocation("CUPS_INTERNAL_BROWSE_ACL");
+
+ if (location == NULL)
+ LogMessage(L_ERROR, "Unable to initialize browse access control list!");
+ else if (strncasecmp(value, "deny", 4) == 0)
+ location->order_type = AUTH_ALLOW;
+ else if (strncasecmp(value, "allow", 5) == 0)
+ location->order_type = AUTH_DENY;
+ else
+ LogMessage(L_ERROR, "Unknown BrowseOrder value %s on line %d.",
+ value, linenum);
+ }
+ else if (strcasecmp(name, "BrowseProtocols") == 0)
+ {
+ /*
+ * "BrowseProtocol name [... name]"
+ */
+
+ BrowseProtocols = 0;
+
+ for (; *value;)
+ {
+ for (valuelen = 0; value[valuelen]; valuelen ++)
+ if (isspace(value[valuelen]) || value[valuelen] == ',')
+ break;
+
+ if (value[valuelen])
+ {
+ value[valuelen] = '\0';
+ valuelen ++;
+ }
+
+ if (strcasecmp(value, "cups") == 0)
+ BrowseProtocols |= BROWSE_CUPS;
+ else if (strcasecmp(value, "slp") == 0)
+ BrowseProtocols |= BROWSE_SLP;
+ else if (strcasecmp(value, "ldap") == 0)
+ BrowseProtocols |= BROWSE_LDAP;
+ else if (strcasecmp(value, "all") == 0)
+ BrowseProtocols |= BROWSE_ALL;
+ else
+ {
+ LogMessage(L_ERROR, "Unknown browse protocol \"%s\" on line %d.",
+ value, linenum);
+ break;
+ }
+
+ for (value += valuelen; *value; value ++)
+ if (!isspace(*value) || *value != ',')
+ break;
+ }
+ }
+ else if (strcasecmp(name, "BrowseAllow") == 0 ||
+ strcasecmp(name, "BrowseDeny") == 0)
+ {
+ /*
+ * BrowseAllow [From] host/ip...
+ * BrowseDeny [From] host/ip...
+ */
+
+ if ((location = FindLocation("CUPS_INTERNAL_BROWSE_ACL")) == NULL)
+ location = AddLocation("CUPS_INTERNAL_BROWSE_ACL");
+
+ if (location == NULL)
+ LogMessage(L_ERROR, "Unable to initialize browse access control list!");
+ else
+ {
+ if (strncasecmp(value, "from ", 5) == 0)
+ {
+ /*
+ * Strip leading "from"...
+ */
+
+ value += 5;
+
+ while (isspace(*value))
+ value ++;
+ }
+
+ /*
+ * Figure out what form the allow/deny address takes:
+ *
+ * All
+ * None
+ * *.domain.com
+ * .domain.com
+ * host.domain.com
+ * nnn.*
+ * nnn.nnn.*
+ * nnn.nnn.nnn.*
+ * nnn.nnn.nnn.nnn
+ * nnn.nnn.nnn.nnn/mm
+ * nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+ */
+
+ if (strcasecmp(value, "all") == 0)
+ {
+ /*
+ * All hosts...
+ */
+
+ if (strcasecmp(name, "BrowseAllow") == 0)
+ AllowIP(location, 0, 0);
+ else
+ DenyIP(location, 0, 0);
+ }
+ else if (strcasecmp(value, "none") == 0)
+ {
+ /*
+ * No hosts...
+ */
+
+ if (strcasecmp(name, "BrowseAllow") == 0)
+ AllowIP(location, ~0, 0);
+ else
+ DenyIP(location, ~0, 0);
+ }
+ else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0]))
+ {
+ /*
+ * Host or domain name...
+ */
+
+ if (value[0] == '*')
+ value ++;
+
+ if (strcasecmp(name, "BrowseAllow") == 0)
+ AllowHost(location, value);
+ else
+ DenyHost(location, value);
+ }
+ else
+ {
+ /*
+ * One of many IP address forms...
+ */
+
+ memset(ip, 0, sizeof(ip));
+ ipcount = sscanf(value, "%d.%d.%d.%d", ip + 0, ip + 1, ip + 2, ip + 3);
+ address = (((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | ip[3];
+
+ if ((value = strchr(value, '/')) != NULL)
+ {
+ value ++;
+ memset(mask, 0, sizeof(mask));
+ switch (sscanf(value, "%d.%d.%d.%d", mask + 0, mask + 1,
+ mask + 2, mask + 3))
+ {
+ case 1 :
+ netmask = (0xffffffff << (32 - mask[0])) & 0xffffffff;
+ break;
+ case 4 :
+ netmask = (((((mask[0] << 8) | mask[1]) << 8) |
+ mask[2]) << 8) | mask[3];
+ break;
+ default :
+ LogMessage(L_ERROR, "Bad netmask value %s on line %d.",
+ value, linenum);
+ netmask = 0xffffffff;
+ break;
+ }
+ }
+ else
+ netmask = netmasks[ipcount - 1];
+
+ if (strcasecmp(name, "BrowseAllow") == 0)
+ AllowIP(location, address, netmask);
+ else
+ DenyIP(location, address, netmask);
+ }
+ }
+ }
+ else if (strcasecmp(name, "BrowseRelay") == 0)
+ {
+ /*
+ * BrowseRelay [from] source [to] destination
+ */
+
+ if (NumRelays >= MAX_BROWSERS)
+ {
+ LogMessage(L_WARN, "Too many BrowseRelay directives at line %d.",
+ linenum);
+ continue;
+ }
+
+ relay = Relays + NumRelays;
+
+ memset(relay, 0, sizeof(dirsvc_relay_t));
+
+ if (strncasecmp(value, "from ", 5) == 0)
+ {
+ /*
+ * Strip leading "from"...
+ */
+
+ value += 5;
+
+ while (isspace(*value))
+ value ++;
+ }
+
+ /*
+ * Figure out what form the from address takes:
+ *
+ * *.domain.com
+ * .domain.com
+ * host.domain.com
+ * nnn.*
+ * nnn.nnn.*
+ * nnn.nnn.nnn.*
+ * nnn.nnn.nnn.nnn
+ * nnn.nnn.nnn.nnn/mm
+ * nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+ */
+
+ if (value[0] == '*' || value[0] == '.' || !isdigit(value[0]))
+ {
+ /*
+ * Host or domain name...
+ */
+
+ if (value[0] == '*')
+ value ++;
+
+ relay->from.type = AUTH_NAME;
+ relay->from.mask.name.name = strdup(value);
+ relay->from.mask.name.length = strlen(value);
+ }
+ else
+ {
+ /*
+ * One of many IP address forms...
+ */
+
+ memset(ip, 0, sizeof(ip));
+ ipcount = sscanf(value, "%d.%d.%d.%d", ip + 0, ip + 1, ip + 2, ip + 3);
+ address = (((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | ip[3];
+
+ for (; *value; value ++)
+ if (*value == '/' || isspace(*value))
+ break;
+
+ if (*value == '/')
+ {
+ value ++;
+ memset(mask, 0, sizeof(mask));
+ switch (sscanf(value, "%d.%d.%d.%d", mask + 0, mask + 1,
+ mask + 2, mask + 3))
+ {
+ case 1 :
+ netmask = (0xffffffff << (32 - mask[0])) & 0xffffffff;
+ break;
+ case 4 :
+ netmask = (((((mask[0] << 8) | mask[1]) << 8) |
+ mask[2]) << 8) | mask[3];
+ break;
+ default :
+ LogMessage(L_ERROR, "Bad netmask value %s on line %d.",
+ value, linenum);
+ netmask = 0xffffffff;
+ break;
+ }
+ }
+ else
+ netmask = netmasks[ipcount - 1];
+
+ relay->from.type = AUTH_IP;
+ relay->from.mask.ip.address = address;
+ relay->from.mask.ip.netmask = netmask;
+ }
+
+ /*
+ * Skip value and trailing whitespace...
+ */
+
+ for (; *value; value ++)
+ if (isspace(*value))
+ break;
+
+ while (isspace(*value))
+ value ++;
+
+ if (strncasecmp(value, "to ", 3) == 0)
+ {
+ /*
+ * Strip leading "to"...
+ */
+
+ value += 3;
+
+ while (isspace(*value))
+ value ++;
+ }
+
+ /*
+ * Get "to" address and port...
+ */
+
+ if (get_address(value, INADDR_BROADCAST, BrowsePort, &(relay->to)))
+ {
+ if (relay->from.type == AUTH_NAME)
+ LogMessage(L_INFO, "Relaying from %s to %x:%d",
+ relay->from.mask.name.name,
+ ntohl(relay->to.sin_addr.s_addr),
+ ntohs(relay->to.sin_port));
+ else
+ LogMessage(L_INFO, "Relaying from %x/%x to %x:%d",
+ relay->from.mask.ip.address, relay->from.mask.ip.netmask,
+ ntohl(relay->to.sin_addr.s_addr),
+ ntohs(relay->to.sin_port));
+
+ NumRelays ++;
+ }
+ else
+ {
+ if (relay->from.type == AUTH_NAME)
+ free(relay->from.mask.name.name);
+
+ LogMessage(L_ERROR, "Bad relay address %s at line %d.", value, linenum);
+ }
+ }
+ else if (strcasecmp(name, "BrowsePoll") == 0)
+ {
+ /*
+ * BrowsePoll address[:port]
+ */
+
+ if (NumPolled >= MAX_BROWSERS)
+ {
+ LogMessage(L_WARN, "Too many BrowsePoll directives at line %d.",
+ linenum);
+ continue;
+ }
+
+ /*
+ * Get poll address and port...
+ */
+
+ if (get_address(value, INADDR_NONE, ippPort(), &polladdr))
+ {
+ LogMessage(L_INFO, "Polling %x:%d", ntohl(polladdr.sin_addr.s_addr),
+ ntohs(polladdr.sin_port));
+
+ poll = Polled + NumPolled;
+ NumPolled ++;
+ memset(poll, 0, sizeof(dirsvc_poll_t));
+
+ address = ntohl(polladdr.sin_addr.s_addr);
+
+ sprintf(poll->hostname, "%d.%d.%d.%d", address >> 24,
+ (address >> 16) & 255, (address >> 8) & 255, address & 255);
+ poll->port = ntohs(polladdr.sin_port);
+ }
+ else
+ LogMessage(L_ERROR, "Bad poll address %s at line %d.", value, linenum);
+ }
+ else if (strcasecmp(name, "User") == 0)
+ {
+ /*
+ * User ID to run as...
+ */
+
+ if (isdigit(value[0]))
+ User = atoi(value);
+ else
+ {
+ struct passwd *p; /* Password information */
+
+ endpwent();
+ p = getpwnam(value);
+
+ if (p != NULL)
+ User = p->pw_uid;
+ else
+ LogMessage(L_WARN, "ReadConfiguration() Unknown username \"%s\"",
+ value);
+ }
+ }
+ else if (strcasecmp(name, "Group") == 0)
+ {
+ /*
+ * Group ID to run as...
+ */
+
+ if (isdigit(value[0]))
+ Group = atoi(value);
+ else
+ {
+ struct group *g; /* Group information */
+
+ endgrent();
+ g = getgrnam(value);
+
+ if (g != NULL)
+ Group = g->gr_gid;
+ else
+ LogMessage(L_WARN, "ReadConfiguration() Unknown groupname \"%s\"",
+ value);
+ }
+ }
+ else if (strcasecmp(name, "SystemGroup") == 0)
+ {
+ /*
+ * System (admin) group(s)...
+ */
+
+ char *valueptr; /* Pointer into value */
+
+
+ for (i = 0; i < MAX_SYSTEM_GROUPS; i ++)
+ {
+ for (valueptr = value; *valueptr; valueptr ++)
+ if (isspace(*valueptr) || *valueptr == ',')
+ break;
+
+ if (*valueptr)
+ *valueptr++ = '\0';
+
+ strlcpy(SystemGroups[i], value, sizeof(SystemGroups[0]));
+
+ while (*value == ',' || isspace(*value))
+ value ++;
+ }
+
+ if (i)
+ NumSystemGroups = i;
+ }
+ else if (strcasecmp(name, "HostNameLookups") == 0)
+ {
+ /*
+ * Do hostname lookups?
+ */
+
+ if (strcasecmp(value, "off") == 0)
+ HostNameLookups = 0;
+ else if (strcasecmp(value, "on") == 0)
+ HostNameLookups = 1;
+ else if (strcasecmp(value, "double") == 0)
+ HostNameLookups = 2;
+ else
+ LogMessage(L_WARN, "ReadConfiguration() Unknown HostNameLookups %s on line %d.",
+ value, linenum);
+ }
+ else if (strcasecmp(name, "LogLevel") == 0)
+ {
+ /*
+ * Amount of logging to do...
+ */
+
+ if (strcasecmp(value, "debug2") == 0)
+ LogLevel = L_DEBUG2;
+ else if (strcasecmp(value, "debug") == 0)
+ LogLevel = L_DEBUG;
+ else if (strcasecmp(value, "info") == 0)
+ LogLevel = L_INFO;
+ else if (strcasecmp(value, "notice") == 0)
+ LogLevel = L_NOTICE;
+ else if (strcasecmp(value, "warn") == 0)
+ LogLevel = L_WARN;
+ else if (strcasecmp(value, "error") == 0)
+ LogLevel = L_ERROR;
+ else if (strcasecmp(value, "crit") == 0)
+ LogLevel = L_CRIT;
+ else if (strcasecmp(value, "alert") == 0)
+ LogLevel = L_ALERT;
+ else if (strcasecmp(value, "emerg") == 0)
+ LogLevel = L_EMERG;
+ else if (strcasecmp(value, "none") == 0)
+ LogLevel = L_NONE;
+ else
+ LogMessage(L_WARN, "Unknown LogLevel %s on line %d.", value, linenum);
+ }
+ else if (strcasecmp(name, "PrintcapFormat") == 0)
+ {
+ /*
+ * Format of printcap file?
+ */
+
+ if (strcasecmp(value, "bsd") == 0)
+ PrintcapFormat = PRINTCAP_BSD;
+ else if (strcasecmp(value, "solaris") == 0)
+ PrintcapFormat = PRINTCAP_SOLARIS;
+ else
+ LogMessage(L_WARN, "ReadConfiguration() Unknown PrintcapFormat %s on line %d.",
+ value, linenum);
+ }
+ else
+ {
+ /*
+ * Find a simple variable in the list...
+ */
+
+ for (i = NUM_VARS, var = variables; i > 0; i --, var ++)
+ if (strcasecmp(name, var->name) == 0)
+ break;
+
+ if (i == 0)
+ {
+ /*
+ * Unknown directive! Output an error message and continue...
+ */
+
+ LogMessage(L_ERROR, "Unknown directive %s on line %d.", name,
+ linenum);
+ continue;
+ }
+
+ switch (var->type)
+ {
+ case VAR_INTEGER :
+ {
+ int n; /* Number */
+ char *units; /* Units */
+
+
+ n = strtol(value, &units, 0);
+
+ if (units && *units)
+ {
+ if (tolower(units[0]) == 'g')
+ n *= 1024 * 1024 * 1024;
+ else if (tolower(units[0]) == 'm')
+ n *= 1024 * 1024;
+ else if (tolower(units[0]) == 'k')
+ n *= 1024;
+ else if (tolower(units[0]) == 't')
+ n *= 262144;
+ }
+
+ *((int *)var->ptr) = n;
+ }
+ break;
+
+ case VAR_BOOLEAN :
+ if (strcasecmp(value, "true") == 0 ||
+ strcasecmp(value, "on") == 0 ||
+ strcasecmp(value, "enabled") == 0 ||
+ strcasecmp(value, "yes") == 0 ||
+ atoi(value) != 0)
+ *((int *)var->ptr) = TRUE;
+ else if (strcasecmp(value, "false") == 0 ||
+ strcasecmp(value, "off") == 0 ||
+ strcasecmp(value, "disabled") == 0 ||
+ strcasecmp(value, "no") == 0 ||
+ strcasecmp(value, "0") == 0)
+ *((int *)var->ptr) = FALSE;
+ else
+ LogMessage(L_ERROR, "Unknown boolean value %s on line %d.",
+ value, linenum);
+ break;
+
+ case VAR_STRING :
+ strlcpy((char *)var->ptr, value, var->size);
+ break;
+ }
+ }
+ }
+
+ return (1);
+}
+
+
+/*
+ * 'read_location()' - Read a <Location path> definition.
+ */
+
+static int /* O - New line number or 0 on error */
+read_location(FILE *fp, /* I - Configuration file */
+ char *location, /* I - Location name/path */
+ int linenum) /* I - Current line number */
+{
+ int i; /* Looping var */
+ location_t *loc, /* New location */
+ *parent; /* Parent location */
+ int len; /* Length of line */
+ char line[HTTP_MAX_BUFFER], /* Line buffer */
+ name[256], /* Configuration directive */
+ *nameptr, /* Pointer into name */
+ *value, /* Value for directive */
+ *valptr; /* Pointer into value */
+ unsigned address, /* Address value */
+ netmask; /* Netmask value */
+ int ip[4], /* IP address components */
+ ipcount, /* Number of components provided */
+ mask[4]; /* IP netmask components */
+ static unsigned netmasks[4] = /* Standard netmasks... */
+ {
+ 0xff000000,
+ 0xffff0000,
+ 0xffffff00,
+ 0xffffffff
+ };
+
+
+ if ((parent = AddLocation(location)) == NULL)
+ return (0);
+
+ parent->limit = AUTH_LIMIT_ALL;
+ loc = parent;
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ linenum ++;
+
+ /*
+ * Skip comment lines...
+ */
+
+ if (line[0] == '#')
+ continue;
+
+ /*
+ * Strip trailing whitespace, if any...
+ */
+
+ len = strlen(line);
+
+ while (len > 0 && isspace(line[len - 1]))
+ {
+ len --;
+ line[len] = '\0';
+ }
+
+ /*
+ * Extract the name from the beginning of the line...
+ */
+
+ for (value = line; isspace(*value); value ++);
+
+ for (nameptr = name; *value != '\0' && !isspace(*value) &&
+ nameptr < (name + sizeof(name) - 1);)
+ *nameptr++ = *value++;
+ *nameptr = '\0';
+
+ while (isspace(*value))
+ value ++;
+
+ if (name[0] == '\0')
+ continue;
+
+ /*
+ * Decode the directive...
+ */
+
+ if (strcasecmp(name, "</Location>") == 0)
+ return (linenum);
+ else if (strcasecmp(name, "<Limit") == 0 ||
+ strcasecmp(name, "<LimitExcept") == 0)
+ {
+ if ((loc = CopyLocation(&parent)) == NULL)
+ return (0);
+
+ loc->limit = 0;
+ while (*value)
+ {
+ for (valptr = value;
+ !isspace(*valptr) && *valptr != '>' && *valptr;
+ valptr ++);
+
+ if (*valptr)
+ *valptr++ = '\0';
+
+ if (strcmp(value, "ALL") == 0)
+ loc->limit = AUTH_LIMIT_ALL;
+ else if (strcmp(value, "GET") == 0)
+ loc->limit |= AUTH_LIMIT_GET;
+ else if (strcmp(value, "HEAD") == 0)
+ loc->limit |= AUTH_LIMIT_HEAD;
+ else if (strcmp(value, "OPTIONS") == 0)
+ loc->limit |= AUTH_LIMIT_OPTIONS;
+ else if (strcmp(value, "POST") == 0)
+ loc->limit |= AUTH_LIMIT_POST;
+ else if (strcmp(value, "PUT") == 0)
+ loc->limit |= AUTH_LIMIT_PUT;
+ else if (strcmp(value, "TRACE") == 0)
+ loc->limit |= AUTH_LIMIT_TRACE;
+ else
+ LogMessage(L_WARN, "Unknown request type %s on line %d!", value,
+ linenum);
+
+ for (value = valptr; isspace(*value) || *value == '>'; value ++);
+ }
+
+ if (strcasecmp(name, "<LimitExcept") == 0)
+ loc->limit = AUTH_LIMIT_ALL ^ loc->limit;
+
+ parent->limit &= ~loc->limit;
+ }
+ else if (strcasecmp(name, "</Limit>") == 0)
+ loc = parent;
+ else if (strcasecmp(name, "Encryption") == 0)
+ {
+ /*
+ * "Encryption xxx" - set required encryption level...
+ */
+
+ if (strcasecmp(value, "never") == 0)
+ loc->encryption = HTTP_ENCRYPT_NEVER;
+ else if (strcasecmp(value, "always") == 0)
+ {
+ LogMessage(L_ERROR, "Encryption value \"%s\" on line %d is invalid in this context. "
+ "Using \"required\" instead.", value, linenum);
+
+ loc->encryption = HTTP_ENCRYPT_REQUIRED;
+ }
+ else if (strcasecmp(value, "required") == 0)
+ loc->encryption = HTTP_ENCRYPT_REQUIRED;
+ else if (strcasecmp(value, "ifrequested") == 0)
+ loc->encryption = HTTP_ENCRYPT_IF_REQUESTED;
+ else
+ LogMessage(L_ERROR, "Unknown Encryption value %s on line %d.",
+ value, linenum);
+ }
+ else if (strcasecmp(name, "Order") == 0)
+ {
+ /*
+ * "Order Deny,Allow" or "Order Allow,Deny"...
+ */
+
+ if (strncasecmp(value, "deny", 4) == 0)
+ loc->order_type = AUTH_ALLOW;
+ else if (strncasecmp(value, "allow", 5) == 0)
+ loc->order_type = AUTH_DENY;
+ else
+ LogMessage(L_ERROR, "Unknown Order value %s on line %d.",
+ value, linenum);
+ }
+ else if (strcasecmp(name, "Allow") == 0 ||
+ strcasecmp(name, "Deny") == 0)
+ {
+ /*
+ * Allow [From] host/ip...
+ * Deny [From] host/ip...
+ */
+
+ if (strncasecmp(value, "from", 4) == 0)
+ {
+ /*
+ * Strip leading "from"...
+ */
+
+ value += 4;
+
+ while (isspace(*value))
+ value ++;
+ }
+
+ /*
+ * Figure out what form the allow/deny address takes:
+ *
+ * All
+ * None
+ * *.domain.com
+ * .domain.com
+ * host.domain.com
+ * nnn.*
+ * nnn.nnn.*
+ * nnn.nnn.nnn.*
+ * nnn.nnn.nnn.nnn
+ * nnn.nnn.nnn.nnn/mm
+ * nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
+ */
+
+ if (strcasecmp(value, "all") == 0)
+ {
+ /*
+ * All hosts...
+ */
+
+ if (strcasecmp(name, "Allow") == 0)
+ AllowIP(loc, 0, 0);
+ else
+ DenyIP(loc, 0, 0);
+ }
+ else if (strcasecmp(value, "none") == 0)
+ {
+ /*
+ * No hosts...
+ */
+
+ if (strcasecmp(name, "Allow") == 0)
+ AllowIP(loc, ~0, 0);
+ else
+ DenyIP(loc, ~0, 0);
+ }
+ else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0]))
+ {
+ /*
+ * Host or domain name...
+ */
+
+ if (value[0] == '*')
+ value ++;
+
+ if (strcasecmp(name, "Allow") == 0)
+ AllowHost(loc, value);
+ else
+ DenyHost(loc, value);
+ }
+ else
+ {
+ /*
+ * One of many IP address forms...
+ */
+
+ memset(ip, 0, sizeof(ip));
+ ipcount = sscanf(value, "%d.%d.%d.%d", ip + 0, ip + 1, ip + 2, ip + 3);
+ address = (((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | ip[3];
+
+ if ((value = strchr(value, '/')) != NULL)
+ {
+ value ++;
+ memset(mask, 0, sizeof(mask));
+ switch (sscanf(value, "%d.%d.%d.%d", mask + 0, mask + 1,
+ mask + 2, mask + 3))
+ {
+ case 1 :
+ netmask = (0xffffffff << (32 - mask[0])) & 0xffffffff;
+ break;
+ case 4 :
+ netmask = (((((mask[0] << 8) | mask[1]) << 8) |
+ mask[2]) << 8) | mask[3];
+ break;
+ default :
+ LogMessage(L_ERROR, "Bad netmask value %s on line %d.",
+ value, linenum);
+ netmask = 0xffffffff;
+ break;
+ }
+ }
+ else
+ netmask = netmasks[ipcount - 1];
+
+ if (strcasecmp(name, "Allow") == 0)
+ AllowIP(loc, address, netmask);
+ else
+ DenyIP(loc, address, netmask);
+ }
+ }
+ else if (strcasecmp(name, "AuthType") == 0)
+ {
+ /*
+ * AuthType {none,basic,digest,basicdigest}
+ */
+
+ if (strcasecmp(value, "none") == 0)
+ {
+ loc->type = AUTH_NONE;
+ loc->level = AUTH_ANON;
+ }
+ else if (strcasecmp(value, "basic") == 0)
+ {
+ loc->type = AUTH_BASIC;
+
+ if (loc->level == AUTH_ANON)
+ loc->level = AUTH_USER;
+ }
+ else if (strcasecmp(value, "digest") == 0)
+ {
+ loc->type = AUTH_DIGEST;
+
+ if (loc->level == AUTH_ANON)
+ loc->level = AUTH_USER;
+ }
+ else if (strcasecmp(value, "basicdigest") == 0)
+ {
+ loc->type = AUTH_BASICDIGEST;
+
+ if (loc->level == AUTH_ANON)
+ loc->level = AUTH_USER;
+ }
+ else
+ LogMessage(L_WARN, "Unknown authorization type %s on line %d.",
+ value, linenum);
+ }
+ else if (strcasecmp(name, "AuthClass") == 0)
+ {
+ /*
+ * AuthClass anonymous, user, system, group
+ */
+
+ if (strcasecmp(value, "anonymous") == 0)
+ {
+ loc->type = AUTH_NONE;
+ loc->level = AUTH_ANON;
+ }
+ else if (strcasecmp(value, "user") == 0)
+ loc->level = AUTH_USER;
+ else if (strcasecmp(value, "group") == 0)
+ loc->level = AUTH_GROUP;
+ else if (strcasecmp(value, "system") == 0)
+ {
+ loc->level = AUTH_GROUP;
+
+ /*
+ * Use the default system group if none is defined so far...
+ */
+
+ if (NumSystemGroups == 0)
+ NumSystemGroups = 1;
+
+ for (i = 0; i < NumSystemGroups; i ++)
+ AddName(loc, SystemGroups[i]);
+ }
+ else
+ LogMessage(L_WARN, "Unknown authorization class %s on line %d.",
+ value, linenum);
+ }
+ else if (strcasecmp(name, "AuthGroupName") == 0)
+ AddName(loc, value);
+ else if (strcasecmp(name, "Require") == 0)
+ {
+ /*
+ * Apache synonym for AuthClass and AuthGroupName...
+ *
+ * Get initial word:
+ *
+ * Require valid-user
+ * Require group names
+ * Require user names
+ */
+
+ for (valptr = value;
+ !isspace(*valptr) && *valptr != '>' && *valptr;
+ valptr ++);
+
+ if (*valptr)
+ *valptr++ = '\0';
+
+ if (strcasecmp(value, "valid-user") == 0 ||
+ strcasecmp(value, "user") == 0)
+ loc->level = AUTH_USER;
+ else if (strcasecmp(value, "group") == 0)
+ loc->level = AUTH_GROUP;
+ else
+ {
+ LogMessage(L_WARN, "Unknown Require type %s on line %d.",
+ value, linenum);
+ continue;
+ }
+
+ /*
+ * Get the list of names from the line...
+ */
+
+ for (value = valptr; *value;)
+ {
+ for (valptr = value; !isspace(*valptr) && *valptr; valptr ++);
+
+ if (*valptr)
+ *valptr++ = '\0';
+
+ AddName(loc, value);
+
+ for (value = valptr; isspace(*value); value ++);
+ }
+ }
+ else if (strcasecmp(name, "Satisfy") == 0)
+ {
+ if (strcasecmp(value, "all") == 0)
+ loc->satisfy = AUTH_SATISFY_ALL;
+ else if (strcasecmp(value, "any") == 0)
+ loc->satisfy = AUTH_SATISFY_ANY;
+ else
+ LogMessage(L_WARN, "Unknown Satisfy value %s on line %d.", value,
+ linenum);
+ }
+ else
+ LogMessage(L_ERROR, "Unknown Location directive %s on line %d.",
+ name, linenum);
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'get_address()' - Get an address + port number from a line.
+ */
+
+static int /* O - 1 if address good, 0 if bad */
+get_address(char *value, /* I - Value string */
+ unsigned defaddress, /* I - Default address */
+ int defport, /* I - Default port */
+ struct sockaddr_in *address) /* O - Socket address */
+{
+ char hostname[256], /* Hostname or IP */
+ portname[256]; /* Port number or name */
+ struct hostent *host; /* Host address */
+ struct servent *port; /* Port number */
+
+
+ /*
+ * Initialize the socket address to the defaults...
+ */
+
+ memset(address, 0, sizeof(struct sockaddr_in));
+ address->sin_family = AF_INET;
+ address->sin_addr.s_addr = htonl(defaddress);
+ address->sin_port = htons(defport);
+
+ /*
+ * Try to grab a hostname and port number...
+ */
+
+ switch (sscanf(value, "%255[^:]:%255s", hostname, portname))
+ {
+ case 1 :
+ if (strchr(hostname, '.') == NULL && defaddress == INADDR_ANY)
+ {
+ /*
+ * Hostname is a port number...
+ */
+
+ strlcpy(portname, hostname, sizeof(portname));
+ hostname[0] = '\0';
+ }
+ else
+ portname[0] = '\0';
+ break;
+ case 2 :
+ break;
+ default :
+ LogMessage(L_ERROR, "Unable to decode address \"%s\"!", value);
+ return (0);
+ }
+
+ /*
+ * Decode the hostname and port number as needed...
+ */
+
+ if (hostname[0] && strcmp(hostname, "*") != 0)
+ {
+ if ((host = httpGetHostByName(hostname)) == NULL)
+ {
+ LogMessage(L_ERROR, "httpGetHostByName(\"%s\") failed - %s!", hostname,
+ strerror(errno));
+ return (0);
+ }
+
+ memcpy(&(address->sin_addr), host->h_addr, host->h_length);
+ address->sin_port = htons(defport);
+ }
+
+ if (portname[0] != '\0')
+ {
+ if (isdigit(portname[0]))
+ address->sin_port = htons(atoi(portname));
+ else
+ {
+ if ((port = getservbyname(portname, NULL)) == NULL)
+ {
+ LogMessage(L_ERROR, "getservbyname(\"%s\") failed - %s!", portname,
+ strerror(errno));
+ return (0);
+ }
+ else
+ address->sin_port = htons(port->s_port);
+ }
+ }
+
+ return (1);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/conf.h b/scheduler/conf.h
new file mode 100644
index 000000000..d29deb26e
--- /dev/null
+++ b/scheduler/conf.h
@@ -0,0 +1,183 @@
+/*
+ * "$Id$"
+ *
+ * Configuration file definitions for the Common UNIX Printing System (CUPS)
+ * scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Log levels...
+ */
+
+#define L_PAGE -1 /* Used internally for page logging */
+#define L_NONE 0
+#define L_EMERG 1 /* Emergency issues */
+#define L_ALERT 2 /* Something bad happened that needs attention */
+#define L_CRIT 3 /* Critical error but server continues */
+#define L_ERROR 4 /* Error condition */
+#define L_WARN 5 /* Warning */
+#define L_NOTICE 6 /* Normal condition that needs logging */
+#define L_INFO 7 /* General information */
+#define L_DEBUG 8 /* General debugging */
+#define L_DEBUG2 9 /* Detailed debugging */
+
+
+/*
+ * Printcap formats...
+ */
+
+#define PRINTCAP_BSD 0 /* Berkeley LPD format */
+#define PRINTCAP_SOLARIS 1 /* Solaris lpsched format */
+
+
+/*
+ * Globals...
+ */
+
+VAR char ConfigurationFile[256] VALUE(CUPS_SERVERROOT "/cupsd.conf"),
+ /* Configuration file to use */
+ ServerName[256] VALUE(""),
+ /* FQDN for server */
+ ServerAdmin[256] VALUE(""),
+ /* Administrator's email */
+ ServerRoot[1024] VALUE(CUPS_SERVERROOT),
+ /* Root directory for scheduler */
+ ServerBin[1024] VALUE(CUPS_SERVERBIN),
+ /* Root directory for binaries */
+ RequestRoot[1024] VALUE(CUPS_REQUESTS),
+ /* Directory for request files */
+ DocumentRoot[1024] VALUE(CUPS_DOCROOT);
+ /* Root directory for documents */
+VAR int NumSystemGroups VALUE(0);
+ /* Number of system group names */
+VAR char SystemGroups[MAX_SYSTEM_GROUPS][32],
+ /* System group names */
+ AccessLog[1024] VALUE(CUPS_LOGDIR "/access_log"),
+ /* Access log filename */
+ ErrorLog[1024] VALUE(CUPS_LOGDIR "/error_log"),
+ /* Error log filename */
+ PageLog[1024] VALUE(CUPS_LOGDIR "/page_log"),
+ /* Page log filename */
+ DataDir[1024] VALUE(CUPS_DATADIR),
+ /* Data file directory */
+ DefaultLanguage[32] VALUE("C"),
+ /* Default language encoding */
+ DefaultCharset[32] VALUE(DEFAULT_CHARSET),
+ /* Default charset */
+ RIPCache[32] VALUE("8m"),
+ /* Amount of memory for RIPs */
+ TempDir[1024] VALUE(CUPS_REQUESTS "/tmp"),
+ /* Temporary directory */
+ Printcap[1024] VALUE(""),
+ /* Printcap file */
+ PrintcapGUI[1024] VALUE("/usr/bin/glpoptions"),
+ /* GUI program to use for IRIX */
+ FontPath[1024] VALUE(CUPS_FONTPATH),
+ /* Font search path */
+ RemoteRoot[32] VALUE("remroot"),
+ /* Remote root user */
+ Classification[IPP_MAX_NAME] VALUE("");
+ /* Classification of system */
+VAR int ClassifyOverride VALUE(0),
+ /* Allow overrides? */
+ ConfigFilePerm VALUE(0600),
+ /* Permissions for config files */
+ LogFilePerm VALUE(0644),
+ /* Permissions for log files */
+ User VALUE(1),
+ /* User ID for server */
+ Group VALUE(0),
+ /* Group ID for server */
+ LogLevel VALUE(L_ERROR),
+ /* Log level */
+ MaxClients VALUE(0),
+ /* Maximum number of clients */
+ MaxCopies VALUE(100),
+ /* Maximum number of copies per job */
+ MaxLogSize VALUE(1024 * 1024),
+ /* Maximum size of log files */
+ MaxRequestSize VALUE(0),
+ /* Maximum size of IPP requests */
+ HostNameLookups VALUE(FALSE),
+ /* Do we do reverse lookups? */
+ Timeout VALUE(DEFAULT_TIMEOUT),
+ /* Timeout during requests */
+ KeepAlive VALUE(TRUE),
+ /* Support the Keep-Alive option? */
+ KeepAliveTimeout VALUE(DEFAULT_KEEPALIVE),
+ /* Timeout between requests */
+ ImplicitClasses VALUE(TRUE),
+ /* Are classes implicitly created? */
+ ImplicitAnyClasses VALUE(FALSE),
+ /* Create AnyPrinter classes? */
+ HideImplicitMembers VALUE(TRUE),
+ /* Hide implicit class members? */
+ FilterLimit VALUE(0),
+ /* Max filter cost at any time */
+ FilterLevel VALUE(0),
+ /* Current filter level */
+ FilterNice VALUE(0),
+ /* Nice value for filters */
+ RootCertDuration VALUE(300),
+ /* Root certificate update interval */
+ RunAsUser VALUE(FALSE),
+ /* Run as unpriviledged user? */
+ PrintcapFormat VALUE(PRINTCAP_BSD);
+ /* Format of printcap file? */
+VAR FILE *AccessFile VALUE(NULL),
+ /* Access log file */
+ *ErrorFile VALUE(NULL),
+ /* Error log file */
+ *PageFile VALUE(NULL);
+ /* Page log file */
+VAR mime_t *MimeDatabase VALUE(NULL);
+ /* MIME type database */
+VAR int NumMimeTypes VALUE(0);
+ /* Number of MIME types */
+VAR const char **MimeTypes VALUE(NULL);
+ /* Array of MIME types */
+
+#ifdef HAVE_LIBSSL
+VAR char ServerCertificate[1024] VALUE("ssl/server.crt"),
+ /* Server certificate file */
+ ServerKey[1024] VALUE("ssl/server.key");
+ /* Server key file */
+#endif /* HAVE_LIBSSL */
+
+
+/*
+ * Prototypes...
+ */
+
+extern char *GetDateTime(time_t t);
+extern int ReadConfiguration(void);
+extern int LogRequest(client_t *con, http_status_t code);
+extern int LogMessage(int level, const char *message, ...)
+#ifdef __GNUC__
+__attribute__ ((__format__ (__printf__, 2, 3)))
+#endif /* __GNUC__ */
+;
+extern int LogPage(job_t *job, const char *page);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/cups-lpd.c b/scheduler/cups-lpd.c
new file mode 100644
index 000000000..1c59ac33c
--- /dev/null
+++ b/scheduler/cups-lpd.c
@@ -0,0 +1,1293 @@
+/*
+ * "$Id$"
+ *
+ * Line Printer Daemon interface for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Process an incoming LPD request...
+ * print_file() - Print a file to a printer or class.
+ * recv_print_job() - Receive a print job from the client.
+ * remove_jobs() - Cancel one or more jobs.
+ * send_state() - Send the queue state.
+ * smart_gets() - Get a line of text, removing the trailing CR
+ * and/or LF.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/cups.h>
+#include <cups/string.h>
+#include <cups/language.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+
+/*
+ * LPD "mini-daemon" for CUPS. This program must be used in conjunction
+ * with inetd or another similar program that monitors ports and starts
+ * daemons for each client connection. A typical configuration is:
+ *
+ * printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd
+ *
+ * This daemon implements most of RFC 1179 (the unofficial LPD specification)
+ * except for:
+ *
+ * - This daemon does not check to make sure that the source port is
+ * between 721 and 731, since it isn't necessary for proper
+ * functioning and port-based security is no security at all!
+ *
+ * - The "Print any waiting jobs" command is a no-op.
+ *
+ * The LPD-to-IPP mapping is as defined in RFC 2569. The report formats
+ * currently match the Solaris LPD mini-daemon.
+ */
+
+/*
+ * Prototypes...
+ */
+
+int print_file(const char *name, const char *file,
+ const char *title, const char *docname,
+ const char *user, int num_options,
+ cups_option_t *options);
+int recv_print_job(const char *dest, int num_defaults, cups_option_t *defaults);
+int remove_jobs(const char *dest, const char *agent, const char *list);
+int send_state(const char *dest, const char *list, int longstatus);
+char *smart_gets(char *s, int len, FILE *fp);
+
+
+/*
+ * 'main()' - Process an incoming LPD request...
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ int num_defaults; /* Number of default options */
+ cups_option_t *defaults; /* Default options */
+ char line[256], /* Command string */
+ command, /* Command code */
+ *dest, /* Pointer to destination */
+ *list, /* Pointer to list */
+ *agent, /* Pointer to user */
+ status; /* Status for client */
+ int hostlen; /* Size of client address */
+ unsigned hostip; /* (32-bit) IP address */
+ struct sockaddr_in hostaddr; /* Address of client */
+ struct hostent *hostent; /* Host entry of client */
+ char hostname[256]; /* Hostname of client */
+
+
+ /*
+ * Don't buffer the output...
+ */
+
+ setbuf(stdout, NULL);
+
+ /*
+ * Log things using the "cups-lpd" name...
+ */
+
+ openlog("cups-lpd", LOG_PID, LOG_LPR);
+
+ /*
+ * Get the address of the client...
+ */
+
+ hostlen = sizeof(hostaddr);
+
+ if (getpeername(0, (struct sockaddr *)&hostaddr, &hostlen))
+ {
+ syslog(LOG_WARNING, "Unable to get client address - %s", strerror(errno));
+ strcpy(hostname, "unknown");
+ }
+ else
+ {
+ hostip = ntohl(hostaddr.sin_addr.s_addr);
+ hostent = gethostbyaddr((void *)&(hostaddr.sin_addr), hostlen, AF_INET);
+
+ if (hostent)
+ strlcpy(hostname, hostent->h_name, sizeof(hostname));
+ else
+ {
+ snprintf(hostname, sizeof(hostname), "%d.%d.%d.%d",
+ (hostip >> 24) & 255, (hostip >> 16) & 255,
+ (hostip >> 8) & 255, hostip & 255);
+ }
+
+ syslog(LOG_INFO, "Connection from %s (%d.%d.%d.%d)",
+ hostname, (hostip >> 24) & 255, (hostip >> 16) & 255,
+ (hostip >> 8) & 255, hostip & 255);
+ }
+
+ /*
+ * Scan the command-line for options...
+ */
+
+ num_defaults = 0;
+ defaults = NULL;
+
+ num_defaults = cupsAddOption("job-originating-host-name", hostname,
+ num_defaults, &defaults);
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'o' : /* Option */
+ if (argv[i][2])
+ num_defaults = cupsParseOptions(argv[i] + 2, num_defaults,
+ &defaults);
+ else
+ {
+ i ++;
+ if (i < argc)
+ num_defaults = cupsParseOptions(argv[i], num_defaults, &defaults);
+ else
+ syslog(LOG_WARNING, "Expected option string after -o option!");
+ }
+ break;
+ default :
+ syslog(LOG_WARNING, "Unknown option \"%c\" ignored!", argv[i][1]);
+ break;
+ }
+ }
+ else
+ syslog(LOG_WARNING, "Unknown command-line option \"%s\" ignored!", argv[i]);
+
+ /*
+ * RFC1179 specifies that only 1 daemon command can be received for
+ * every connection.
+ */
+
+ if (smart_gets(line, sizeof(line), stdin) == NULL)
+ {
+ /*
+ * Unable to get command from client! Send an error status and return.
+ */
+
+ syslog(LOG_ERR, "Unable to get command line from client!");
+ putchar(1);
+ return (1);
+ }
+
+ /*
+ * The first byte is the command byte. After that will be the queue name,
+ * resource list, and/or user name.
+ */
+
+ command = line[0];
+ dest = line + 1;
+
+ for (list = dest + 1; *list && !isspace(*list); list ++);
+
+ while (isspace(*list))
+ *list++ = '\0';
+
+ /*
+ * Do the command...
+ */
+
+ switch (command)
+ {
+ default : /* Unknown command */
+ syslog(LOG_ERR, "Unknown LPD command 0x%02X!", command);
+ syslog(LOG_ERR, "Command line = %s", line + 1);
+ putchar(1);
+
+ status = 1;
+ break;
+
+ case 0x01 : /* Print any waiting jobs */
+ syslog(LOG_INFO, "Print waiting jobs (no-op)");
+ putchar(0);
+
+ status = 0;
+ break;
+
+ case 0x02 : /* Receive a printer job */
+ syslog(LOG_INFO, "Receive print job for %s", dest);
+ /* recv_print_job() sends initial status byte */
+
+ status = recv_print_job(dest, num_defaults, defaults);
+ break;
+
+ case 0x03 : /* Send queue state (short) */
+ syslog(LOG_INFO, "Send queue state (short) for %s %s", dest, list);
+ /* no status byte for this command */
+
+ status = send_state(dest, list, 0);
+ break;
+
+ case 0x04 : /* Send queue state (long) */
+ syslog(LOG_INFO, "Send queue state (long) for %s %s", dest, list);
+ /* no status byte for this command */
+
+ status = send_state(dest, list, 1);
+ break;
+
+ case 0x05 : /* Remove jobs */
+ /*
+ * Grab the agent and skip to the list of users and/or jobs.
+ */
+
+ agent = list;
+
+ for (; *list && !isspace(*list); list ++);
+ while (isspace(*list))
+ *list++ = '\0';
+
+ syslog(LOG_INFO, "Remove jobs %s on %s by %s", list, dest, agent);
+
+ status = remove_jobs(dest, agent, list);
+
+ putchar(status);
+ break;
+ }
+
+ syslog(LOG_INFO, "Closing connection");
+ closelog();
+
+ return (status);
+}
+
+
+/*
+ * 'print_file()' - Print a file to a printer or class.
+ */
+
+int /* O - Job ID */
+print_file(const char *name, /* I - Printer or class name */
+ const char *file, /* I - File to print */
+ const char *title, /* I - Title of job */
+ const char *docname, /* I - Name of job file */
+ const char *user, /* I - Owner of job */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ http_t *http; /* Connection to server */
+ ipp_t *request; /* IPP request */
+ ipp_t *response; /* IPP response */
+ ipp_attribute_t *attr; /* IPP job-id attribute */
+ char uri[HTTP_MAX_URI]; /* Printer URI */
+ cups_lang_t *language; /* Language to use */
+ int jobid; /* New job ID */
+
+
+ /*
+ * Setup a connection and request data...
+ */
+
+ if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption())) == NULL)
+ {
+ syslog(LOG_ERR, "Unable to connect to server: %s", strerror(errno));
+ return (0);
+ }
+
+ language = cupsLangDefault();
+
+ /*
+ * Build a standard CUPS URI for the printer and fill the standard IPP
+ * attributes...
+ */
+
+ if ((request = ippNew()) == NULL)
+ {
+ syslog(LOG_ERR, "Unable to create request: %s", strerror(errno));
+ return (0);
+ }
+
+ request->request.op.operation_id = IPP_PRINT_JOB;
+ request->request.op.request_id = 1;
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", name);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language != NULL ? language->language : "C");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, user);
+
+ if (title)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, title);
+ if (docname)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name", NULL, docname);
+
+ /*
+ * Then add all options on the command-line...
+ */
+
+ cupsEncodeOptions(request, num_options, options);
+
+ /*
+ * Do the request...
+ */
+
+ snprintf(uri, sizeof(uri), "/printers/%s", name);
+
+ response = cupsDoFileRequest(http, request, uri, file);
+
+ if (response == NULL)
+ jobid = 0;
+ else if (response->request.status.status_code > IPP_OK_CONFLICT)
+ jobid = 0;
+ else if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL)
+ jobid = 0;
+ else
+ jobid = attr->values[0].integer;
+
+ if (jobid)
+ syslog(LOG_INFO, "Print file - job ID = %d", jobid);
+ else if (response)
+ syslog(LOG_ERR, "Unable to print file - %s",
+ ippErrorString(response->request.status.status_code));
+ else
+ syslog(LOG_ERR, "Unable to print file - %s",
+ ippErrorString(cupsLastError()));
+
+ if (response != NULL)
+ ippDelete(response);
+
+ httpClose(http);
+ cupsLangFree(language);
+
+ return (jobid);
+}
+
+
+/*
+ * 'recv_print_job()' - Receive a print job from the client.
+ */
+
+int /* O - Command status */
+recv_print_job(const char *dest, /* I - Destination */
+ int num_defaults,/* I - Number of default options */
+ cups_option_t *defaults) /* I - Default options */
+{
+ int i; /* Looping var */
+ int status; /* Command status */
+ int fd; /* Temporary file */
+ FILE *fp; /* File pointer */
+ char filename[1024]; /* Temporary filename */
+ int bytes; /* Bytes received */
+ char line[256], /* Line from file/stdin */
+ command, /* Command from line */
+ *count, /* Number of bytes */
+ *name; /* Name of file */
+ int num_data; /* Number of data files */
+ char control[1024], /* Control filename */
+ data[32][256], /* Data files */
+ temp[32][1024]; /* Temporary files */
+ char user[1024], /* User name */
+ title[1024], /* Job title */
+ docname[1024], /* Document name */
+ queue[256], /* Printer/class queue */
+ *instance; /* Printer/class instance */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dests, /* Destinations */
+ *destptr; /* Current destination */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ int banner; /* Print banner? */
+
+
+ status = 0;
+ num_data = 0;
+ fd = -1;
+
+ control[0] = '\0';
+
+ strlcpy(queue, dest, sizeof(queue));
+
+ if ((instance = strrchr(queue, '/')) != NULL)
+ *instance++ = '\0';
+
+ num_dests = cupsGetDests(&dests);
+ if ((destptr = cupsGetDest(queue, instance, num_dests, dests)) == NULL)
+ {
+ if (instance)
+ syslog(LOG_ERR, "Unknown destination %s/%s!", queue, instance);
+ else
+ syslog(LOG_ERR, "Unknown destination %s!", queue);
+
+ cupsFreeDests(num_dests, dests);
+
+ putchar(1);
+
+ return (1);
+ }
+ else
+ putchar(0);
+
+ while (smart_gets(line, sizeof(line), stdin) != NULL)
+ {
+ if (strlen(line) < 2)
+ {
+ status = 1;
+ break;
+ }
+
+ command = line[0];
+ count = line + 1;
+
+ for (name = count + 1; *name && !isspace(*name); name ++);
+ while (isspace(*name))
+ *name++ = '\0';
+
+ switch (command)
+ {
+ default :
+ case 0x01 : /* Abort */
+ status = 1;
+ break;
+ case 0x02 : /* Receive control file */
+ if (strlen(name) < 2)
+ {
+ syslog(LOG_ERR, "Bad control file name \"%s\"", name);
+ putchar(1);
+ status = 1;
+ break;
+ }
+
+ if (control[0])
+ {
+ /*
+ * Append to the existing control file - the LPD spec is
+ * not entirely clear, but at least the OS/2 LPD code sends
+ * multiple control files per connection...
+ */
+
+ if ((fd = open(control, O_WRONLY)) < 0)
+ {
+ syslog(LOG_ERR, "Unable to append to temporary control file - %s",
+ strerror(errno));
+ putchar(1);
+ status = 1;
+ break;
+ }
+
+ lseek(fd, 0, SEEK_END);
+ }
+ else
+ {
+ if ((fd = cupsTempFd(control, sizeof(control))) < 0)
+ {
+ syslog(LOG_ERR, "Unable to open temporary control file - %s",
+ strerror(errno));
+ putchar(1);
+ status = 1;
+ break;
+ }
+
+ strcpy(filename, control);
+ }
+ break;
+ case 0x03 : /* Receive data file */
+ if (strlen(name) < 2)
+ {
+ syslog(LOG_ERR, "Bad data file name \"%s\"", name);
+ putchar(1);
+ status = 1;
+ break;
+ }
+
+ if (num_data >= (sizeof(data) / sizeof(data[0])))
+ {
+ /*
+ * Too many data files...
+ */
+
+ syslog(LOG_ERR, "Too many data files (%d)", num_data);
+ putchar(1);
+ status = 1;
+ break;
+ }
+
+ strlcpy(data[num_data], name, sizeof(data[0]));
+
+ if ((fd = cupsTempFd(temp[num_data], sizeof(temp[0]))) < 0)
+ {
+ syslog(LOG_ERR, "Unable to open temporary data file - %s",
+ strerror(errno));
+ putchar(1);
+ status = 1;
+ break;
+ }
+
+ strcpy(filename, temp[num_data]);
+
+ num_data ++;
+ break;
+ }
+
+ putchar(status);
+
+ if (status)
+ break;
+
+ /*
+ * Copy the data or control file from the client...
+ */
+
+ for (i = atoi(count); i > 0; i -= bytes)
+ {
+ if (i > sizeof(line))
+ bytes = sizeof(line);
+ else
+ bytes = i;
+
+ if ((bytes = fread(line, 1, bytes, stdin)) > 0)
+ bytes = write(fd, line, bytes);
+
+ if (bytes < 1)
+ {
+ syslog(LOG_ERR, "Error while reading file - %s",
+ strerror(errno));
+ status = 1;
+ break;
+ }
+ }
+
+ /*
+ * Read trailing nul...
+ */
+
+ if (!status)
+ {
+ if (fread(line, 1, 1, stdin) < 1)
+ {
+ status = 1;
+ syslog(LOG_ERR, "Error while reading trailing nul - %s",
+ strerror(errno));
+ }
+ else if (line[0])
+ {
+ status = 1;
+ syslog(LOG_ERR, "Trailing character after file is not nul (%02X)!",
+ line[0]);
+ }
+ }
+
+ /*
+ * Close the file and send an acknowledgement...
+ */
+
+ close(fd);
+
+ putchar(status);
+
+ if (status)
+ break;
+ }
+
+ if (!status)
+ {
+ /*
+ * Process the control file and print stuff...
+ */
+
+ if ((fp = fopen(control, "rb")) == NULL)
+ status = 1;
+ else
+ {
+ /*
+ * Grab the job information first...
+ */
+
+ title[0] = '\0';
+ user[0] = '\0';
+ docname[0] = '\0';
+ banner = 0;
+
+ while (smart_gets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Process control lines...
+ */
+
+ switch (line[0])
+ {
+ case 'J' : /* Job name */
+ strlcpy(title, line + 1, sizeof(title));
+ break;
+ case 'N' : /* Document name */
+ strlcpy(docname, line + 1, sizeof(docname));
+ break;
+ case 'P' : /* User identification */
+ strlcpy(user, line + 1, sizeof(user));
+ break;
+ case 'L' : /* Print banner page */
+ banner = 1;
+ break;
+ }
+
+ if (status)
+ break;
+ }
+
+ /*
+ * Then print the jobs...
+ */
+
+ rewind(fp);
+
+ while (smart_gets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Process control lines...
+ */
+
+ switch (line[0])
+ {
+ case 'c' : /* Plot CIF file */
+ case 'd' : /* Print DVI file */
+ case 'f' : /* Print formatted file */
+ case 'g' : /* Plot file */
+ case 'l' : /* Print file leaving control characters (raw) */
+ case 'n' : /* Print ditroff output file */
+ case 'o' : /* Print PostScript output file */
+ case 'p' : /* Print file with 'pr' format (prettyprint) */
+ case 'r' : /* File to print with FORTRAN carriage control */
+ case 't' : /* Print troff output file */
+ case 'v' : /* Print raster file */
+ /*
+ * Check that we have a username...
+ */
+
+ if (!user[0])
+ {
+ syslog(LOG_WARNING, "No username specified by client! "
+ "Using \"anonymous\"...");
+ strcpy(user, "anonymous");
+ }
+
+ /*
+ * Copy the default options...
+ */
+
+ num_options = 0;
+ options = NULL;
+
+ for (i = 0; i < num_defaults; i ++)
+ num_options = cupsAddOption(defaults[i].name,
+ defaults[i].value,
+ num_options, &options);
+ for (i = 0; i < destptr->num_options; i ++)
+ num_options = cupsAddOption(destptr->options[i].name,
+ destptr->options[i].value,
+ num_options, &options);
+
+ /*
+ * Add additional options as needed...
+ */
+
+ if (!banner)
+ num_options = cupsAddOption("job-sheets", "none",
+ num_options, &options);
+
+ if (line[0] == 'l')
+ num_options = cupsAddOption("raw", "", num_options, &options);
+
+ if (line[0] == 'p')
+ num_options = cupsAddOption("prettyprint", "", num_options,
+ &options);
+
+ /*
+ * Figure out which file we are printing...
+ */
+
+ for (i = 0; i < num_data; i ++)
+ if (strcmp(data[i], line + 1) == 0)
+ break;
+
+ if (i >= num_data)
+ {
+ status = 1;
+ break;
+ }
+
+ /*
+ * Send the print request...
+ */
+
+ if (print_file(queue, temp[i], title, docname, user, num_options,
+ options) == 0)
+ status = 1;
+ else
+ status = 0;
+
+ cupsFreeOptions(num_options, options);
+ break;
+ }
+
+ if (status)
+ break;
+ }
+
+ fclose(fp);
+ }
+ }
+
+ /*
+ * Clean up all temporary files and return...
+ */
+
+ unlink(control);
+
+ for (i = 0; i < num_data; i ++)
+ unlink(temp[i]);
+
+ cupsFreeDests(num_dests, dests);
+
+ return (status);
+}
+
+
+/*
+ * 'remove_jobs()' - Cancel one or more jobs.
+ */
+
+int /* O - Command status */
+remove_jobs(const char *dest, /* I - Destination */
+ const char *agent, /* I - User agent */
+ const char *list) /* I - List of jobs or users */
+{
+ int id; /* Job ID */
+ http_t *http; /* HTTP server connection */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ cups_lang_t *language; /* Default language */
+ char uri[HTTP_MAX_URI]; /* Job URI */
+
+
+ (void)dest; /* Suppress compiler warnings... */
+
+ /*
+ * Try connecting to the local server...
+ */
+
+ if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption())) == NULL)
+ {
+ syslog(LOG_ERR, "Unable to connect to server: %s", strerror(errno));
+ return (1);
+ }
+
+ language = cupsLangDefault();
+
+ /*
+ * Loop for each job...
+ */
+
+ while ((id = atoi(list)) > 0)
+ {
+ /*
+ * Skip job ID in list...
+ */
+
+ while (isdigit(*list))
+ list ++;
+ while (isspace(*list))
+ list ++;
+
+ /*
+ * Build an IPP_CANCEL_JOB request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * job-uri
+ * requesting-user-name
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_CANCEL_JOB;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ sprintf(uri, "ipp://localhost/jobs/%d", id);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, agent);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ syslog(LOG_WARNING, "Cancel of job ID %d failed: %s\n", id,
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ cupsLangFree(language);
+ httpClose(http);
+ return (1);
+ }
+ else
+ syslog(LOG_INFO, "Job ID %d cancelled", id);
+
+ ippDelete(response);
+ }
+ else
+ {
+ syslog(LOG_WARNING, "Cancel of job ID %d failed: %s\n", id,
+ ippErrorString(cupsLastError()));
+ cupsLangFree(language);
+ httpClose(http);
+ return (1);
+ }
+ }
+
+ cupsLangFree(language);
+ httpClose(http);
+
+ return (0);
+}
+
+
+/*
+ * 'send_state()' - Send the queue state.
+ */
+
+int /* O - Command status */
+send_state(const char *dest, /* I - Destination */
+ const char *list, /* I - Job or user */
+ int longstatus) /* I - List of jobs or users */
+{
+ int id; /* Job ID from list */
+ http_t *http; /* HTTP server connection */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ ipp_pstate_t state; /* Printer state */
+ const char *jobdest, /* Pointer into job-printer-uri */
+ *jobuser, /* Pointer to job-originating-user-name */
+ *jobname; /* Pointer to job-name */
+ ipp_jstate_t jobstate; /* job-state */
+ int jobid, /* job-id */
+ jobsize, /* job-k-octets */
+ jobcount, /* Number of jobs */
+ jobcopies, /* Number of copies */
+ rank; /* Rank of job */
+ char rankstr[255]; /* Rank string */
+ char namestr[1024]; /* Job name string */
+ char uri[HTTP_MAX_URI]; /* Printer URI */
+ char queue[256], /* Printer/class queue */
+ *instance; /* Printer/class instance */
+ static const char *ranks[10] = /* Ranking strings */
+ {
+ "th",
+ "st",
+ "nd",
+ "rd",
+ "th",
+ "th",
+ "th",
+ "th",
+ "th",
+ "th"
+ };
+ static const char *requested[] = /* Requested attributes */
+ {
+ "job-id",
+ "job-k-octets",
+ "job-state",
+ "job-printer-uri",
+ "job-originating-user-name",
+ "job-name",
+ "copies"
+ };
+
+
+ /*
+ * Remove instance from destination, if any...
+ */
+
+ strlcpy(queue, dest, sizeof(queue));
+
+ if ((instance = strrchr(queue, '/')) != NULL)
+ *instance++ = '\0';
+
+ /*
+ * Try connecting to the local server...
+ */
+
+ if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption())) == NULL)
+ {
+ syslog(LOG_ERR, "Unable to connect to server: %s", strerror(errno));
+ printf("Unable to connect to server: %s", strerror(errno));
+ return (1);
+ }
+
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", queue);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", NULL, "printer-state");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ syslog(LOG_WARNING, "Unable to get printer list: %s\n",
+ ippErrorString(response->request.status.status_code));
+ printf("Unable to get printer list: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return (1);
+ }
+
+ if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
+ state = (ipp_pstate_t)attr->values[0].integer;
+ else
+ state = IPP_PRINTER_STOPPED;
+
+ switch (state)
+ {
+ case IPP_PRINTER_IDLE :
+ printf("%s is ready\n", dest);
+ break;
+ case IPP_PRINTER_PROCESSING :
+ printf("%s is ready and printing\n", dest);
+ break;
+ case IPP_PRINTER_STOPPED :
+ printf("%s is not ready\n", dest);
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ syslog(LOG_WARNING, "Unable to get printer list: %s\n",
+ ippErrorString(cupsLastError()));
+ printf("Unable to get printer list: %s\n",
+ ippErrorString(cupsLastError()));
+ return (1);
+ }
+
+ /*
+ * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires
+ * the following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * job-uri or printer-uri
+ */
+
+ id = atoi(list);
+
+ request = ippNew();
+
+ request->request.op.operation_id = id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", queue);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ if (id)
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", id);
+ else
+ {
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, list);
+ ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
+ }
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(requested) / sizeof(requested[0]),
+ NULL, requested);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ jobcount = 0;
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ printf("get-jobs failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return (1);
+ }
+
+ rank = 1;
+
+ /*
+ * Loop through the job list and display them...
+ */
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a job...
+ */
+
+ while (attr != NULL &&
+ (attr->group_tag != IPP_TAG_JOB || attr->name == NULL))
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this job...
+ */
+
+ jobid = 0;
+ jobsize = 0;
+ jobstate = IPP_JOB_PENDING;
+ jobname = "untitled";
+ jobuser = NULL;
+ jobdest = NULL;
+ jobcopies = 1;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
+ {
+ if (strcmp(attr->name, "job-id") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobid = attr->values[0].integer;
+
+ if (strcmp(attr->name, "job-k-octets") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobsize = attr->values[0].integer * 1024;
+
+ if (strcmp(attr->name, "job-state") == 0 &&
+ attr->value_tag == IPP_TAG_ENUM)
+ jobstate = (ipp_jstate_t)attr->values[0].integer;
+
+ if (strcmp(attr->name, "job-printer-uri") == 0 &&
+ attr->value_tag == IPP_TAG_URI)
+ if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL)
+ jobdest ++;
+
+ if (strcmp(attr->name, "job-originating-user-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ jobuser = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "job-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ jobname = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "copies") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobcopies = attr->values[0].integer;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (jobdest == NULL || jobid == 0)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ if (!longstatus && jobcount == 0)
+ puts("Rank Owner Job File(s) Total Size");
+
+ jobcount ++;
+
+ /*
+ * Display the job...
+ */
+
+ if (jobstate == IPP_JOB_PROCESSING)
+ strcpy(rankstr, "active");
+ else
+ {
+ snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]);
+ rank ++;
+ }
+
+ if (longstatus)
+ {
+ puts("");
+
+ if (jobcopies > 1)
+ snprintf(namestr, sizeof(namestr), "%d copies of %s", jobcopies,
+ jobname);
+ else
+ strlcpy(namestr, jobname, sizeof(namestr));
+
+ printf("%s: %-34.34s[job %d localhost]\n", jobuser, rankstr, jobid);
+ printf(" %-40.40s%d bytes\n", namestr, jobsize);
+ }
+ else
+ printf("%-7s %-8.8s%-8d%-32.32s%d bytes\n", rankstr, jobuser,
+ jobid, jobname, jobsize);
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ printf("get-jobs failed: %s\n", ippErrorString(cupsLastError()));
+ return (1);
+ }
+
+ if (jobcount == 0)
+ puts("no entries");
+
+ cupsLangFree(language);
+ httpClose(http);
+
+ return (0);
+}
+
+
+/*
+ * 'smart_gets()' - Get a line of text, removing the trailing CR and/or LF.
+ */
+
+char * /* O - Line read or NULL */
+smart_gets(char *s, /* I - Pointer to line buffer */
+ int len, /* I - Size of line buffer */
+ FILE *fp) /* I - File to read from */
+{
+ char *ptr, /* Pointer into line */
+ *end; /* End of line */
+ int ch; /* Character from file */
+
+
+ /*
+ * Read the line; unlike fgets(), we read the entire line but dump
+ * characters that go past the end of the buffer. Also, we accept
+ * CR, LF, or CR LF for the line endings to be "safe", although
+ * RFC 1179 specifically says "just use LF".
+ */
+
+ ptr = s;
+ end = s + len - 1;
+
+ while ((ch = getc(fp)) != EOF)
+ {
+ if (ch == '\n')
+ break;
+ else if (ch == '\r')
+ {
+ /*
+ * See if a LF follows...
+ */
+
+ ch = getc(fp);
+
+ if (ch != '\n')
+ ungetc(ch, fp);
+
+ break;
+ }
+ else if (ptr < end)
+ *ptr++ = ch;
+ }
+
+ *ptr = '\0';
+
+ if (ch == EOF && ptr == s)
+ return (NULL);
+ else
+ return (s);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/cups-polld.c b/scheduler/cups-polld.c
new file mode 100644
index 000000000..7d832864f
--- /dev/null
+++ b/scheduler/cups-polld.c
@@ -0,0 +1,383 @@
+/*
+ * "$Id$"
+ *
+ * Polling daemon for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Open socks and poll until we are killed...
+ * poll_server() - Poll the server for the given set of printers or classes.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/cups.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <cups/language.h>
+#include <cups/string.h>
+
+
+/*
+ * Local functions...
+ */
+
+int poll_server(http_t *http, cups_lang_t *language, ipp_op_t op,
+ int sock, int port, int interval);
+
+
+/*
+ * 'main()' - Open socks and poll until we are killed...
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ http_t *http; /* HTTP connection */
+ cups_lang_t *language; /* Language info */
+ int interval; /* Polling interval */
+ int sock; /* Browser sock */
+ int port; /* Browser port */
+ int val; /* Socket option value */
+
+
+ /*
+ * Don't buffer errors...
+ */
+
+ setbuf(stderr, NULL);
+
+ /*
+ * The command-line must contain the following:
+ *
+ * cups-polld server server-port interval port
+ */
+
+ if (argc != 5)
+ {
+ fputs("Usage: cups-polld server server-port interval port\n", stderr);
+ return (1);
+ }
+
+ interval = atoi(argv[3]);
+ port = atoi(argv[4]);
+
+ /*
+ * Open a broadcast socket...
+ */
+
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ fprintf(stderr, "cups-polld: Unable to open broadcast socket: %s\n",
+ strerror(errno));
+ return (1);
+ }
+
+ /*
+ * Set the "broadcast" flag...
+ */
+
+ val = 1;
+ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)))
+ {
+ fprintf(stderr, "cups-polld: Unable to put socket in broadcast mode: %s\n",
+ strerror(errno));
+
+ close(sock);
+ return (1);
+ }
+
+ /*
+ * Open a connection to the server...
+ */
+
+ while ((http = httpConnectEncrypt(argv[1], atoi(argv[2]),
+ cupsEncryption())) == NULL)
+ {
+ fprintf(stderr, "cups-polld: Unable to connect to %s on port %s: %s\n",
+ argv[1], argv[2], strerror(errno));
+ sleep (interval);
+ }
+
+ /*
+ * Loop forever, asking for available printers and classes...
+ */
+
+ language = cupsLangDefault();
+
+ for (;;)
+ {
+ if (!poll_server(http, language, CUPS_GET_PRINTERS, sock, port,
+ interval / 2))
+ {
+ /*
+ * We got the printers, now get the classes...
+ */
+
+ poll_server(http, language, CUPS_GET_CLASSES, sock, port, interval / 2);
+ }
+ else
+ {
+ /*
+ * If successful, poll_server() will sleep for us; otherwise sleep
+ * here...
+ */
+
+ sleep(interval);
+ }
+ }
+}
+
+
+/*
+ * 'poll_server()' - Poll the server for the given set of printers or classes.
+ */
+
+int /* O - 0 for success, -1 on error */
+poll_server(http_t *http, /* I - HTTP connection */
+ cups_lang_t *language, /* I - Language */
+ ipp_op_t op, /* I - Operation code */
+ int sock, /* I - Broadcast sock */
+ int port, /* I - Broadcast port */
+ int interval) /* I - Polling interval */
+{
+ int count, /* Current number of printers/classes */
+ max_count; /* Maximum printers/classes per second */
+ ipp_t *request, /* Request data */
+ *response; /* Response data */
+ ipp_attribute_t *attr; /* Current attribute */
+ const char *uri, /* printer-uri */
+ *info, /* printer-info */
+ *location, /* printer-location */
+ *make_model; /* printer-make-and-model */
+ cups_ptype_t type; /* printer-type */
+ ipp_pstate_t state; /* printer-state */
+ struct sockaddr_in addr; /* Broadcast address */
+ char packet[1540]; /* Data packet */
+ static const char *attrs[] = /* Requested attributes */
+ {
+ "printer-info",
+ "printer-location",
+ "printer-make-and-model",
+ "printer-state",
+ "printer-type",
+ "printer-uri-supported"
+ };
+
+
+ /*
+ * Broadcast to 127.0.0.1 (localhost)
+ */
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_addr.s_addr = htonl(0x7f000001);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+
+ /*
+ * Build a CUPS_GET_PRINTERS or CUPS_GET_CLASSES request, which requires
+ * only the attributes-charset and attributes-natural-language attributes.
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = op;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(attrs) / sizeof(attrs[0]),
+ NULL, attrs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "cups-polld: get-%s failed: %s\n",
+ op == CUPS_GET_PRINTERS ? "printers" : "classes",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return (-1);
+ }
+
+ /*
+ * Figure out how many printers/classes we have...
+ */
+
+ for (attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME),
+ max_count = 0;
+ attr != NULL;
+ attr = ippFindNextAttribute(response, "printer-name", IPP_TAG_NAME),
+ max_count ++);
+
+ count = 0;
+ max_count = max_count / interval + 1;
+
+ /*
+ * Loop through the printers or classes returned in the list...
+ */
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a printer...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this printer...
+ */
+
+ uri = NULL;
+ info = "";
+ location = "";
+ make_model = "";
+ type = CUPS_PRINTER_REMOTE;
+ state = IPP_PRINTER_IDLE;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
+ {
+ if (strcmp(attr->name, "printer-uri-supported") == 0 &&
+ attr->value_tag == IPP_TAG_URI)
+ uri = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-info") == 0 &&
+ attr->value_tag == IPP_TAG_TEXT)
+ info = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-location") == 0 &&
+ attr->value_tag == IPP_TAG_TEXT)
+ location = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-make-and-model") == 0 &&
+ attr->value_tag == IPP_TAG_TEXT)
+ make_model = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-state") == 0 &&
+ attr->value_tag == IPP_TAG_ENUM)
+ state = (ipp_pstate_t)attr->values[0].integer;
+
+ if (strcmp(attr->name, "printer-type") == 0 &&
+ attr->value_tag == IPP_TAG_ENUM)
+ type = (cups_ptype_t)attr->values[0].integer;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (uri == NULL)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ /*
+ * See if this is a local printer or class...
+ */
+
+ if (!(type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+ {
+ /*
+ * Send the printer information...
+ */
+
+ snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"\n",
+ type | CUPS_PRINTER_REMOTE, state, uri,
+ location, info, make_model);
+ puts(packet);
+
+ if (sendto(sock, packet, strlen(packet), 0,
+ (struct sockaddr *)&addr, sizeof(addr)) <= 0)
+ {
+ perror("cups-polld");
+ return (-1);
+ }
+
+ /*
+ * Throttle the local broadcasts as needed so that we don't
+ * overwhelm the local server...
+ */
+
+ count ++;
+ if (count >= max_count)
+ {
+ /*
+ * Sleep for a second...
+ */
+
+ count = 0;
+ sleep(1);
+ interval --;
+ }
+ }
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ fprintf(stderr, "cups-polld: get-%s failed: %s\n",
+ op == CUPS_GET_PRINTERS ? "printers" : "classes",
+ ippErrorString(cupsLastError()));
+ return (-1);
+ }
+
+ /*
+ * OK, sleep for the remaining time interval...
+ */
+
+ if (interval)
+ sleep(interval);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/cups.pam b/scheduler/cups.pam
new file mode 100644
index 000000000..f38e70184
--- /dev/null
+++ b/scheduler/cups.pam
@@ -0,0 +1,2 @@
+auth required /lib/security/pam_pwdb.so nullok shadow
+account required /lib/security/pam_pwdb.so
diff --git a/scheduler/cupsd.dsp b/scheduler/cupsd.dsp
new file mode 100644
index 000000000..60b2cb927
--- /dev/null
+++ b/scheduler/cupsd.dsp
@@ -0,0 +1,173 @@
+# Microsoft Developer Studio Project File - Name="cupsd" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=cupsd - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "cupsd.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "cupsd.mak" CFG="cupsd - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "cupsd - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "cupsd - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "cupsd - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+
+!ELSEIF "$(CFG)" == "cupsd - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "../visualc" /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "cupsd - Win32 Release"
+# Name "cupsd - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\auth.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\classes.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\client.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\conf.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dirsvc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ipp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\job.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\listen.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\log.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\printers.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\auth.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\classes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\client.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\conf.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\cupsd.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\dirsvc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\job.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\printers.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h
new file mode 100644
index 000000000..ec63bb0ca
--- /dev/null
+++ b/scheduler/cupsd.h
@@ -0,0 +1,177 @@
+/*
+ * "$Id$"
+ *
+ * Main header file for the Common UNIX Printing System (CUPS) scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <time.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#ifdef WIN32
+# include <direct.h>
+#else
+# include <unistd.h>
+#endif /* WIN32 */
+
+#include <cups/cups.h>
+#include <cups/string.h>
+#include "mime.h"
+#include <cups/http.h>
+#include <cups/ipp.h>
+#include <cups/language.h>
+#include <cups/debug.h>
+
+
+/*
+ * Common constants.
+ */
+
+#ifndef FALSE
+# define FALSE 0
+# define TRUE (!FALSE)
+#endif /* !FALSE */
+
+
+/*
+ * Implementation limits...
+ */
+
+#define MAX_BROWSERS 10 /* Maximum number of browse addresses */
+#define MAX_LISTENERS 10 /* Maximum number of listener sockets */
+#define MAX_USERPASS 33 /* Maximum size of username/password */
+#define MAX_FILTERS 20 /* Maximum number of filters */
+#define MAX_SYSTEM_GROUPS 32 /* Maximum number of system groups */
+
+
+/*
+ * Defaults...
+ */
+
+#define DEFAULT_HISTORY 1 /* Preserve job history? */
+#define DEFAULT_FILES 0 /* Preserve job files? */
+#define DEFAULT_TIMEOUT 300 /* Timeout during requests/updates */
+#define DEFAULT_KEEPALIVE 60 /* Timeout between requests */
+#define DEFAULT_INTERVAL 30 /* Interval between browse updates */
+#define DEFAULT_LANGUAGE setlocale(LC_ALL,"")
+ /* Default language encoding */
+#define DEFAULT_CHARSET "utf-8" /* Default charset */
+
+
+/*
+ * Global variable macros...
+ */
+
+#ifdef _MAIN_C_
+# define VAR
+# define VALUE(x) =x
+#else
+# define VAR extern
+# define VALUE(x)
+#endif /* _MAIN_C */
+
+
+/*
+ * Other stuff for the scheduler...
+ */
+
+#include "cert.h"
+#include "client.h"
+#include "auth.h"
+#include "printers.h"
+#include "classes.h"
+#include "job.h"
+#include "conf.h"
+#include "banners.h"
+#include "dirsvc.h"
+#include "network.h"
+
+
+/*
+ * Directory handling functions...
+ */
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+typedef struct dirent DIRENT;
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+typedef struct direct DIRENT;
+# define NAMLEN(dirent) (dirent)->d_namlen
+#endif
+
+
+/*
+ * Globals...
+ */
+
+VAR int MaxFDs; /* Maximum number of files */
+VAR fd_set InputSet, /* Input files for select() */
+ OutputSet; /* Output files for select() */
+
+VAR int NeedReload VALUE(TRUE);
+ /* Need to load configuration? */
+VAR char TZ[1024] VALUE("TZ=GMT");
+ /* Timezone configuration */
+
+VAR ipp_t *Devices VALUE(NULL),
+ /* Available devices */
+ *PPDs VALUE(NULL);
+ /* Available PPDs */
+
+
+/*
+ * Prototypes...
+ */
+
+extern void CatchChildSignals(void);
+extern void IgnoreChildSignals(void);
+extern void LoadDevices(const char *d);
+extern void LoadPPDs(const char *d);
+extern void StartServer(void);
+extern void StopServer(void);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/devices.c b/scheduler/devices.c
new file mode 100644
index 000000000..faf2c3b91
--- /dev/null
+++ b/scheduler/devices.c
@@ -0,0 +1,482 @@
+/*
+ * "$Id$"
+ *
+ * Device scanning routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * LoadDevices() - Load all available devices.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+
+
+/*
+ * Device information structure...
+ */
+
+typedef struct
+{
+ char device_class[128], /* Device class */
+ device_make_and_model[128], /* Make and model, if known */
+ device_info[128], /* Device info/description */
+ device_uri[1024]; /* Device URI */
+} dev_info_t;
+
+
+/*
+ * Local globals...
+ */
+
+static int num_devs, /* Number of devices */
+ alloc_devs; /* Number of allocated entries */
+static dev_info_t *devs; /* Device info */
+
+
+/*
+ * Local functions...
+ */
+
+static int compare_devs(const dev_info_t *p0, const dev_info_t *p1);
+static void sigalrm_handler(int sig);
+
+
+/*
+ * 'LoadDevices()' - Load all available devices.
+ */
+
+void
+LoadDevices(const char *d) /* I - Directory to scan */
+{
+ int i; /* Looping var */
+ int count; /* Number of devices from backend */
+ int compat; /* Compatibility device? */
+ FILE *fp; /* Pipe to device backend */
+ DIR *dir; /* Directory pointer */
+ DIRENT *dent; /* Directory entry */
+ char filename[1024], /* Name of backend */
+ line[2048], /* Line from backend */
+ dclass[64], /* Device class */
+ uri[1024], /* Device URI */
+ info[128], /* Device info */
+ make_model[256];/* Make and model */
+ dev_info_t *dev; /* Current device */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ /*
+ * Initialize the device list.
+ */
+
+ Devices = ippNew();
+
+ /*
+ * Try opening the backend directory...
+ */
+
+ if ((dir = opendir(d)) == NULL)
+ {
+ LogMessage(L_ERROR, "LoadDevices: Unable to open backend directory \"%s\": %s",
+ d, strerror(errno));
+ return;
+ }
+
+ /*
+ * Setup the devices array...
+ */
+
+ alloc_devs = 0;
+ num_devs = 0;
+ devs = (dev_info_t *)0;
+
+ /*
+ * Ignore child signals...
+ */
+
+ IgnoreChildSignals();
+
+ /*
+ * Loop through all of the device backends...
+ */
+
+ while ((dent = readdir(dir)) != NULL)
+ {
+ /*
+ * Skip "." and ".."...
+ */
+
+ if (dent->d_name[0] == '.')
+ continue;
+
+ /*
+ * Run the backend with no arguments and collect the output...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/%s", d, dent->d_name);
+ if ((fp = popen(filename, "r")) != NULL)
+ {
+ /*
+ * Set an alarm for the first read from the backend; this avoids
+ * problems when a backend is hung getting device information.
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGALRM, sigalrm_handler);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGALRM);
+ action.sa_handler = sigalrm_handler;
+ sigaction(SIGALRM, &action, NULL);
+#else
+ signal(SIGALRM, sigalrm_handler);
+#endif /* HAVE_SIGSET */
+
+ alarm(30);
+ count = 0;
+ compat = strcmp(dent->d_name, "smb") == 0;
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Reset the alarm clock...
+ */
+
+ alarm(30);
+
+ /*
+ * Each line is of the form:
+ *
+ * class URI "make model" "name"
+ */
+
+ if (strncasecmp(line, "Usage", 5) == 0)
+ compat = 1;
+ else if (sscanf(line, "%63s%1023s%*[ \t]\"%127[^\"]\"%*[ \t]\"%255[^\"]",
+ dclass, uri, make_model, info) != 4)
+ {
+ /*
+ * Bad format; strip trailing newline and write an error message.
+ */
+
+ if (line[strlen(line) - 1] == '\n')
+ line[strlen(line) - 1] = '\0';
+
+ LogMessage(L_ERROR, "LoadDevices: Bad line from \"%s\": %s",
+ dent->d_name, line);
+ compat = 1;
+ break;
+ }
+ else
+ {
+ /*
+ * Add the device to the array of available devices...
+ */
+
+ if (num_devs >= alloc_devs)
+ {
+ /*
+ * Allocate (more) memory for the devices...
+ */
+
+ if (alloc_devs == 0)
+ dev = malloc(sizeof(dev_info_t) * 16);
+ else
+ dev = realloc(devs, sizeof(dev_info_t) * (alloc_devs + 16));
+
+ if (dev == NULL)
+ {
+ LogMessage(L_ERROR, "LoadDevices: Ran out of memory for %d devices!",
+ alloc_devs + 16);
+ closedir(dir);
+ return;
+ }
+
+ devs = dev;
+ alloc_devs += 16;
+ }
+
+ dev = devs + num_devs;
+ num_devs ++;
+
+ memset(dev, 0, sizeof(dev_info_t));
+ strlcpy(dev->device_class, dclass, sizeof(dev->device_class));
+ strlcpy(dev->device_info, info, sizeof(dev->device_info));
+ strlcpy(dev->device_make_and_model, make_model,
+ sizeof(dev->device_make_and_model));
+ strlcpy(dev->device_uri, uri, sizeof(dev->device_uri));
+
+ LogMessage(L_DEBUG, "LoadDevices: Added device \"%s\"...", uri);
+ count ++;
+ }
+ }
+
+ /*
+ * Turn the alarm clock off and close the pipe to the command...
+ */
+
+ alarm(0);
+
+ pclose(fp);
+
+ /*
+ * Hack for backends that don't support the CUPS 1.1 calling convention:
+ * add a network device with the method == backend name.
+ */
+
+ if (count == 0 && compat)
+ {
+ if (num_devs >= alloc_devs)
+ {
+ /*
+ * Allocate (more) memory for the devices...
+ */
+
+ if (alloc_devs == 0)
+ dev = malloc(sizeof(dev_info_t) * 16);
+ else
+ dev = realloc(devs, sizeof(dev_info_t) * (alloc_devs + 16));
+
+ if (dev == NULL)
+ {
+ LogMessage(L_ERROR, "LoadDevices: Ran out of memory for %d devices!",
+ alloc_devs + 16);
+ closedir(dir);
+ return;
+ }
+
+ devs = dev;
+ alloc_devs += 16;
+ }
+
+ dev = devs + num_devs;
+ num_devs ++;
+
+ memset(dev, 0, sizeof(dev_info_t));
+ strcpy(dev->device_class, "network");
+ snprintf(dev->device_info, sizeof(dev->device_info),
+ "Unknown Network Device (%s)", dent->d_name);
+ strcpy(dev->device_make_and_model, "Unknown");
+ strlcpy(dev->device_uri, dent->d_name, sizeof(dev->device_uri));
+
+ LogMessage(L_DEBUG, "LoadDevices: Compatibility device \"%s\"...",
+ dent->d_name);
+ }
+ }
+ else
+ LogMessage(L_WARN, "LoadDevices: Unable to execute \"%s\" backend: %s",
+ dent->d_name, strerror(errno));
+ }
+
+ closedir(dir);
+
+ /*
+ * Catch child signals...
+ */
+
+ CatchChildSignals();
+
+ /*
+ * Sort the available devices...
+ */
+
+ if (num_devs > 1)
+ qsort(devs, num_devs, sizeof(dev_info_t),
+ (int (*)(const void *, const void *))compare_devs);
+
+ /*
+ * Create the list of devices...
+ */
+
+ for (i = num_devs, dev = devs; i > 0; i --, dev ++)
+ {
+ /*
+ * Add strings to attributes...
+ */
+
+ if (i < num_devs)
+ ippAddSeparator(Devices);
+
+ ippAddString(Devices, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "device-class", NULL, dev->device_class);
+ ippAddString(Devices, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "device-info", NULL, dev->device_info);
+ ippAddString(Devices, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "device-make-and-model", NULL, dev->device_make_and_model);
+ ippAddString(Devices, IPP_TAG_PRINTER, IPP_TAG_URI,
+ "device-uri", NULL, dev->device_uri);
+ }
+
+ /*
+ * Free the devices array...
+ */
+
+ if (alloc_devs)
+ free(devs);
+}
+
+
+/*
+ * 'compare_devs()' - Compare PPD file make and model names for sorting.
+ */
+
+static int /* O - Result of comparison */
+compare_devs(const dev_info_t *d0, /* I - First PPD file */
+ const dev_info_t *d1) /* I - Second PPD file */
+{
+ const char *s, /* First name */
+ *t; /* Second name */
+ int diff, /* Difference between digits */
+ digits; /* Number of digits */
+
+
+ /*
+ * First compare names...
+ */
+
+ s = d0->device_info;
+ t = d1->device_info;
+
+ /*
+ * Loop through both nicknames, returning only when a difference is
+ * seen. Also, compare whole numbers rather than just characters, too!
+ */
+
+ while (*s && *t)
+ {
+ if (isdigit(*s) && isdigit(*t))
+ {
+ /*
+ * Got a number; start by skipping leading 0's...
+ */
+
+ while (*s == '0')
+ s ++;
+ while (*t == '0')
+ t ++;
+
+ /*
+ * Skip equal digits...
+ */
+
+ while (isdigit(*s) && *s == *t)
+ {
+ s ++;
+ t ++;
+ }
+
+ /*
+ * Bounce out if *s and *t aren't both digits...
+ */
+
+ if (isdigit(*s) && !isdigit(*t))
+ return (1);
+ else if (!isdigit(*s) && isdigit(*t))
+ return (-1);
+ else if (!isdigit(*s) || !isdigit(*t))
+ continue;
+
+ if (*s < *t)
+ diff = -1;
+ else
+ diff = 1;
+
+ /*
+ * Figure out how many more digits there are...
+ */
+
+ digits = 0;
+ s ++;
+ t ++;
+
+ while (isdigit(*s))
+ {
+ digits ++;
+ s ++;
+ }
+
+ while (isdigit(*t))
+ {
+ digits --;
+ t ++;
+ }
+
+ /*
+ * Return if the number or value of the digits is different...
+ */
+
+ if (digits < 0)
+ return (-1);
+ else if (digits > 0)
+ return (1);
+ else if (diff)
+ return (diff);
+ }
+ else if (tolower(*s) < tolower(*t))
+ return (-1);
+ else if (tolower(*s) > tolower(*t))
+ return (1);
+ else
+ {
+ s ++;
+ t ++;
+ }
+ }
+
+ /*
+ * Return the results of the final comparison...
+ */
+
+ if (*s)
+ return (1);
+ else if (*t)
+ return (-1);
+ else if ((diff = strcasecmp(d0->device_class, d1->device_class)) != 0)
+ return (diff);
+ else
+ return (strcasecmp(d0->device_uri, d1->device_uri));
+}
+
+
+/*
+ * 'sigalrm_handler()' - Handle alarm signals for backends that get hung
+ * trying to list the available devices...
+ */
+
+static void
+sigalrm_handler(int sig) /* I - Signal number */
+{
+ (void)sig; /* remove compiler warnings... */
+
+ LogMessage(L_WARN, "LoadDevices: Backend did not respond within 30 seconds!");
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c
new file mode 100644
index 000000000..cf1a3a153
--- /dev/null
+++ b/scheduler/dirsvc.c
@@ -0,0 +1,1828 @@
+/*
+ * "$Id$"
+ *
+ * Directory services routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * ProcessBrowseData() - Process new browse data.
+ * SendBrowseList() - Send new browsing information as necessary.
+ * SendCUPSBrowse() - Send new browsing information using the CUPS protocol.
+ * StartBrowsing() - Start sending and receiving broadcast information.
+ * StartPolling() - Start polling servers as needed.
+ * StopBrowsing() - Stop sending and receiving broadcast information.
+ * StopPolling() - Stop polling servers as needed.
+ * UpdateCUPSBrowse() - Update the browse lists using the CUPS protocol.
+ * UpdatePolling() - Read status messages from the poll daemons.
+ * RegReportCallback() - Empty SLPRegReport.
+ * SendSLPBrowse() - Register the specified printer with SLP.
+ * SLPDeregPrinter() - SLPDereg() the specified printer
+ * GetSlpAttrVal() - Get an attribute from an SLP registration.
+ * AttrCallback() - SLP attribute callback
+ * SrvUrlCallback() - SLP service url callback
+ * UpdateSLPBrowse() - Get browsing information via SLP.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+#include <grp.h>
+
+
+/*
+ * 'ProcessBrowseData()' - Process new browse data.
+ */
+
+void
+ProcessBrowseData(const char *uri, /* I - URI of printer/class */
+ cups_ptype_t type, /* I - Printer type */
+ ipp_pstate_t state, /* I - Printer state */
+ const char *location,/* I - Printer location */
+ const char *info, /* I - Printer information */
+ const char *make_model) /* I - Printer make and model */
+{
+ int i; /* Looping var */
+ int update; /* Update printer attributes? */
+ char method[HTTP_MAX_URI], /* Method portion of URI */
+ username[HTTP_MAX_URI], /* Username portion of URI */
+ host[HTTP_MAX_URI], /* Host portion of URI */
+ resource[HTTP_MAX_URI]; /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ char name[IPP_MAX_NAME], /* Name of printer */
+ *hptr, /* Pointer into hostname */
+ *sptr; /* Pointer into ServerName */
+ char local_make_model[IPP_MAX_NAME];
+ /* Local make and model */
+ printer_t *p, /* Printer information */
+ *pclass, /* Printer class */
+ *first, /* First printer in class */
+ *next; /* Next printer in list */
+ int offset, /* Offset of name */
+ len; /* Length of name */
+
+
+ /*
+ * Pull the URI apart to see if this is a local or remote printer...
+ */
+
+ httpSeparate(uri, method, username, host, &port, resource);
+
+ /*
+ * OK, this isn't a local printer; see if we already have it listed in
+ * the Printers list, and add it if not...
+ */
+
+ update = 0;
+ hptr = strchr(host, '.');
+ sptr = strchr(ServerName, '.');
+
+ if (sptr != NULL && hptr != NULL)
+ {
+ /*
+ * Strip the common domain name components...
+ */
+
+ while (hptr != NULL)
+ {
+ if (strcasecmp(hptr, sptr) == 0)
+ {
+ *hptr = '\0';
+ break;
+ }
+ else
+ hptr = strchr(hptr + 1, '.');
+ }
+ }
+
+ if (type & CUPS_PRINTER_CLASS)
+ {
+ /*
+ * Remote destination is a class...
+ */
+
+ if (strncmp(resource, "/classes/", 9) == 0)
+ snprintf(name, sizeof(name), "%s@%s", resource + 9, host);
+ else
+ return;
+
+ if ((p = FindClass(name)) == NULL && BrowseShortNames)
+ {
+ if ((p = FindClass(resource + 9)) != NULL)
+ {
+ if (strcasecmp(p->hostname, host) != 0 && p->hostname[0])
+ {
+ /*
+ * Nope, this isn't the same host; if the hostname isn't the local host,
+ * add it to the other class and then find a class using the full host
+ * name...
+ */
+
+ if (p->type & CUPS_PRINTER_REMOTE)
+ {
+ strlcat(p->name, "@", sizeof(p->name));
+ strlcat(p->name, p->hostname, sizeof(p->name));
+ SetPrinterAttrs(p);
+ SortPrinters();
+ }
+
+ p = NULL;
+ }
+ else if (!p->hostname[0])
+ {
+ strlcpy(p->hostname, host, sizeof(p->hostname));
+ strlcpy(p->uri, uri, sizeof(p->uri));
+ strlcpy(p->device_uri, uri, sizeof(p->device_uri));
+ update = 1;
+ }
+ }
+ else
+ strlcpy(name, resource + 9, sizeof(name));
+ }
+ else if (p != NULL && !p->hostname[0])
+ {
+ strlcpy(p->hostname, host, sizeof(p->hostname));
+ strlcpy(p->uri, uri, sizeof(p->uri));
+ strlcpy(p->device_uri, uri, sizeof(p->device_uri));
+ update = 1;
+ }
+
+ if (p == NULL)
+ {
+ /*
+ * Class doesn't exist; add it...
+ */
+
+ p = AddClass(name);
+
+ LogMessage(L_INFO, "Added remote class \"%s\"...", name);
+
+ /*
+ * Force the URI to point to the real server...
+ */
+
+ p->type = type;
+ strlcpy(p->uri, uri, sizeof(p->uri));
+ strlcpy(p->device_uri, uri, sizeof(p->device_uri));
+ strlcpy(p->hostname, host, sizeof(p->hostname));
+
+ update = 1;
+ }
+ }
+ else
+ {
+ /*
+ * Remote destination is a printer...
+ */
+
+ if (strncmp(resource, "/printers/", 10) == 0)
+ snprintf(name, sizeof(name), "%s@%s", resource + 10, host);
+ else
+ return;
+
+ if ((p = FindPrinter(name)) == NULL && BrowseShortNames)
+ {
+ if ((p = FindPrinter(resource + 10)) != NULL)
+ {
+ if (strcasecmp(p->hostname, host) != 0 && p->hostname[0])
+ {
+ /*
+ * Nope, this isn't the same host; if the hostname isn't the local host,
+ * add it to the other printer and then find a printer using the full host
+ * name...
+ */
+
+ if (p->type & CUPS_PRINTER_REMOTE)
+ {
+ strlcat(p->name, "@", sizeof(p->name));
+ strlcat(p->name, p->hostname, sizeof(p->name));
+ SetPrinterAttrs(p);
+ SortPrinters();
+ }
+
+ p = NULL;
+ }
+ else if (!p->hostname[0])
+ {
+ strlcpy(p->hostname, host, sizeof(p->hostname));
+ strlcpy(p->uri, uri, sizeof(p->uri));
+ strlcpy(p->device_uri, uri, sizeof(p->device_uri));
+ update = 1;
+ }
+ }
+ else
+ strlcpy(name, resource + 10, sizeof(name));
+ }
+ else if (p != NULL && !p->hostname[0])
+ {
+ strlcpy(p->hostname, host, sizeof(p->hostname));
+ strlcpy(p->uri, uri, sizeof(p->uri));
+ strlcpy(p->device_uri, uri, sizeof(p->device_uri));
+ update = 1;
+ }
+
+ if (p == NULL)
+ {
+ /*
+ * Printer doesn't exist; add it...
+ */
+
+ p = AddPrinter(name);
+
+ LogMessage(L_INFO, "Added remote printer \"%s\"...", name);
+
+ /*
+ * Force the URI to point to the real server...
+ */
+
+ p->type = type;
+ strlcpy(p->hostname, host, sizeof(p->hostname));
+ strlcpy(p->uri, uri, sizeof(p->uri));
+ strlcpy(p->device_uri, uri, sizeof(p->device_uri));
+
+ update = 1;
+ }
+ }
+
+ /*
+ * Update the state...
+ */
+
+ p->state = state;
+ p->accepting = state != IPP_PRINTER_STOPPED;
+ p->browse_time = time(NULL);
+
+ if (p->type != type)
+ {
+ p->type = type;
+ update = 1;
+ }
+
+ if (strcmp(p->location, location))
+ {
+ strlcpy(p->location, location, sizeof(p->location));
+ update = 1;
+ }
+
+ if (strcmp(p->info, info))
+ {
+ strlcpy(p->info, info, sizeof(p->info));
+ update = 1;
+ }
+
+ if (!make_model[0])
+ {
+ if (type & CUPS_PRINTER_CLASS)
+ snprintf(local_make_model, sizeof(local_make_model),
+ "Remote Class on %s", host);
+ else
+ snprintf(local_make_model, sizeof(local_make_model),
+ "Remote Printer on %s", host);
+ }
+ else
+ snprintf(local_make_model, sizeof(local_make_model),
+ "%s on %s", make_model, host);
+
+ if (strcmp(p->make_model, local_make_model))
+ {
+ strlcpy(p->make_model, local_make_model, sizeof(p->make_model));
+ update = 1;
+ }
+
+ if (update)
+ SetPrinterAttrs(p);
+
+ /*
+ * See if we have a default printer... If not, make the first printer the
+ * default.
+ */
+
+ if (DefaultPrinter == NULL && Printers != NULL)
+ {
+ DefaultPrinter = Printers;
+
+ WritePrintcap();
+ }
+
+ /*
+ * Do auto-classing if needed...
+ */
+
+ if (ImplicitClasses)
+ {
+ /*
+ * Loop through all available printers and create classes as needed...
+ */
+
+ for (p = Printers, len = 0, offset = 0, first = NULL;
+ p != NULL;
+ p = next)
+ {
+ /*
+ * Get next printer in list...
+ */
+
+ next = p->next;
+
+ /*
+ * Skip classes...
+ */
+
+ if (p->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_CLASS))
+ {
+ len = 0;
+ continue;
+ }
+
+ /*
+ * If len == 0, get the length of this printer name up to the "@"
+ * sign (if any).
+ */
+
+ if (len > 0 &&
+ strncasecmp(p->name, name + offset, len) == 0 &&
+ (p->name[len] == '\0' || p->name[len] == '@'))
+ {
+ /*
+ * We have more than one printer with the same name; see if
+ * we have a class, and if this printer is a member...
+ */
+
+ if ((pclass = FindPrinter(name)) == NULL)
+ {
+ /*
+ * Need to add the class...
+ */
+
+ pclass = AddPrinter(name);
+ pclass->type |= CUPS_PRINTER_IMPLICIT;
+ pclass->accepting = 1;
+ pclass->state = IPP_PRINTER_IDLE;
+
+ strcpy(pclass->location, p->location);
+ strcpy(pclass->info, p->info);
+
+ SetPrinterAttrs(pclass);
+
+ LogMessage(L_INFO, "Added implicit class \"%s\"...", name);
+ }
+
+ if (first != NULL)
+ {
+ for (i = 0; i < pclass->num_printers; i ++)
+ if (pclass->printers[i] == first)
+ break;
+
+ if (i >= pclass->num_printers)
+ AddPrinterToClass(pclass, first);
+
+ first = NULL;
+ }
+
+ for (i = 0; i < pclass->num_printers; i ++)
+ if (pclass->printers[i] == p)
+ break;
+
+ if (i >= pclass->num_printers)
+ AddPrinterToClass(pclass, p);
+ }
+ else
+ {
+ /*
+ * First time around; just get name length and mark it as first
+ * in the list...
+ */
+
+ if ((hptr = strchr(p->name, '@')) != NULL)
+ len = hptr - p->name;
+ else
+ len = strlen(p->name);
+
+ strncpy(name, p->name, len);
+ name[len] = '\0';
+ offset = 0;
+
+ if ((pclass = FindPrinter(name)) != NULL &&
+ !(pclass->type & CUPS_PRINTER_IMPLICIT))
+ {
+ /*
+ * Can't use same name as a local printer; add "Any" to the
+ * front of the name, unless we have explicitly disabled
+ * the "ImplicitAnyClasses"...
+ */
+
+ if (ImplicitAnyClasses)
+ {
+ /*
+ * Add "Any" to the class name...
+ */
+
+ strcpy(name, "Any");
+ strncpy(name + 3, p->name, len);
+ name[len + 3] = '\0';
+ offset = 3;
+ }
+ else
+ {
+ /*
+ * Don't create an implicit class if we have a local printer
+ * with the same name...
+ */
+
+ len = 0;
+ continue;
+ }
+ }
+
+ first = p;
+ }
+ }
+ }
+}
+
+
+/*
+ * 'SendBrowseList()' - Send new browsing information as necessary.
+ */
+
+void
+SendBrowseList(void)
+{
+ int count; /* Number of dests to update */
+ printer_t *p, /* Current printer */
+ *np; /* Next printer */
+ time_t ut, /* Minimum update time */
+ to; /* Timeout time */
+
+
+ if (!Browsing || !(BrowseProtocols & BROWSE_CUPS))
+ return;
+
+ /*
+ * Compute the update and timeout times...
+ */
+
+ ut = time(NULL) - BrowseInterval;
+ to = time(NULL) - BrowseTimeout;
+
+ /*
+ * Figure out how many printers need an update...
+ */
+
+ if (BrowseInterval > 0)
+ {
+ for (count = 0, p = Printers; p != NULL; p = p->next)
+ if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) &&
+ p->browse_time < ut)
+ count ++;
+
+ /*
+ * Throttle the number of printers we'll be updating this time
+ * around...
+ */
+
+ count = 2 * count / BrowseInterval + 1;
+ }
+ else
+ count = 0;
+
+ /*
+ * Loop through all of the printers and send local updates as needed...
+ */
+
+ for (p = Printers; p != NULL; p = np)
+ {
+ np = p->next;
+
+ if (p->type & CUPS_PRINTER_REMOTE)
+ {
+ /*
+ * See if this printer needs to be timed out...
+ */
+
+ if (p->browse_time < to)
+ {
+ LogMessage(L_INFO, "Remote destination \"%s\" has timed out; deleting it...",
+ p->name);
+ DeletePrinter(p);
+ }
+ }
+ else if (p->browse_time < ut && count > 0 &&
+ !(p->type & CUPS_PRINTER_IMPLICIT))
+ {
+ /*
+ * Need to send an update...
+ */
+
+ count --;
+
+ p->browse_time = time(NULL);
+
+ if (BrowseProtocols & BROWSE_CUPS)
+ SendCUPSBrowse(p);
+
+#ifdef HAVE_LIBSLP
+ if (BrowseProtocols & BROWSE_SLP)
+ SendSLPBrowse(p);
+#endif /* HAVE_LIBSLP */
+ }
+ }
+}
+
+
+/*
+ * 'SendCUPSBrowse()' - Send new browsing information using the CUPS protocol.
+ */
+
+void
+SendCUPSBrowse(printer_t *p) /* I - Printer to send */
+{
+ int i; /* Looping var */
+ dirsvc_addr_t *b; /* Browse address */
+ int bytes; /* Length of packet */
+ char packet[1453]; /* Browse data packet */
+ cups_netif_t *iface; /* Network interface */
+
+
+ /*
+ * Send a packet to each browse address...
+ */
+
+ for (i = NumBrowsers, b = Browsers; i > 0; i --, b ++)
+ if (b->iface[0])
+ {
+ /*
+ * Send the browse packet to one or more interfaces...
+ */
+
+ if (strcmp(b->iface, "*") == 0)
+ {
+ /*
+ * Send to all local interfaces...
+ */
+
+ NetIFUpdate();
+
+ for (iface = NetIFList; iface != NULL; iface = iface->next)
+ {
+ /*
+ * Only send to local interfaces...
+ */
+
+ if (!iface->is_local)
+ continue;
+
+ snprintf(packet, sizeof(packet), "%x %x ipp://%s/%s/%s \"%s\" \"%s\" \"%s\"\n",
+ p->type | CUPS_PRINTER_REMOTE, p->state, iface->hostname,
+ (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
+ p->name, p->location, p->info, p->make_model);
+
+ bytes = strlen(packet);
+
+ LogMessage(L_DEBUG2, "SendBrowseList: (%d bytes to \"%s\") %s", bytes,
+ iface->name, packet);
+
+ iface->broadcast.sin_port = htons(BrowsePort);
+
+ sendto(BrowseSocket, packet, bytes, 0,
+ (struct sockaddr *)&(iface->broadcast),
+ sizeof(struct sockaddr_in));
+ }
+ }
+ else if ((iface = NetIFFind(b->iface)) != NULL)
+ {
+ /*
+ * Send to the named interface...
+ */
+
+ snprintf(packet, sizeof(packet), "%x %x ipp://%s/%s/%s \"%s\" \"%s\" \"%s\"\n",
+ p->type | CUPS_PRINTER_REMOTE, p->state, iface->hostname,
+ (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
+ p->name, p->location, p->info, p->make_model);
+
+ bytes = strlen(packet);
+
+ LogMessage(L_DEBUG2, "SendBrowseList: (%d bytes to \"%s\") %s", bytes,
+ iface->name, packet);
+
+ iface->broadcast.sin_port = htons(BrowsePort);
+
+ sendto(BrowseSocket, packet, bytes, 0,
+ (struct sockaddr *)&(iface->broadcast),
+ sizeof(struct sockaddr_in));
+ }
+ }
+ else
+ {
+ /*
+ * Send the browse packet to the indicated address using
+ * the default server name...
+ */
+
+ snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"\n",
+ p->type | CUPS_PRINTER_REMOTE, p->state, p->uri,
+ p->location, p->info, p->make_model);
+
+ bytes = strlen(packet);
+ LogMessage(L_DEBUG2, "SendBrowseList: (%d bytes to %x) %s", bytes,
+ ntohl(b->to.sin_addr.s_addr), packet);
+
+ if (sendto(BrowseSocket, packet, bytes, 0,
+ (struct sockaddr *)&(b->to), sizeof(struct sockaddr_in)) <= 0)
+ {
+ /*
+ * Unable to send browse packet, so remove this address from the
+ * list...
+ */
+
+ LogMessage(L_ERROR, "SendBrowseList: sendto failed for browser %d - %s.",
+ b - Browsers + 1, strerror(errno));
+
+ if (i > 1)
+ memcpy(b, b + 1, (i - 1) * sizeof(dirsvc_addr_t));
+
+ b --;
+ NumBrowsers --;
+ }
+ }
+}
+
+
+/*
+ * 'StartBrowsing()' - Start sending and receiving broadcast information.
+ */
+
+void
+StartBrowsing(void)
+{
+ int val; /* Socket option value */
+ struct sockaddr_in addr; /* Broadcast address */
+
+
+ if (!Browsing)
+ return;
+
+ if (BrowseProtocols & BROWSE_CUPS)
+ {
+ /*
+ * Create the broadcast socket...
+ */
+
+ if ((BrowseSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ LogMessage(L_ERROR, "StartBrowsing: Unable to create broadcast socket - %s.",
+ strerror(errno));
+ Browsing = 0;
+ return;
+ }
+
+ /*
+ * Set the "broadcast" flag...
+ */
+
+ val = 1;
+ if (setsockopt(BrowseSocket, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)))
+ {
+ LogMessage(L_ERROR, "StartBrowsing: Unable to set broadcast mode - %s.",
+ strerror(errno));
+
+#ifdef WIN32
+ closesocket(BrowseSocket);
+#else
+ close(BrowseSocket);
+#endif /* WIN32 */
+
+ BrowseSocket = -1;
+ Browsing = 0;
+ return;
+ }
+
+ /*
+ * Bind the socket to browse port...
+ */
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(BrowsePort);
+
+ if (bind(BrowseSocket, (struct sockaddr *)&addr, sizeof(addr)))
+ {
+ LogMessage(L_ERROR, "StartBrowsing: Unable to bind broadcast socket - %s.",
+ strerror(errno));
+
+#ifdef WIN32
+ closesocket(BrowseSocket);
+#else
+ close(BrowseSocket);
+#endif /* WIN32 */
+
+ BrowseSocket = -1;
+ Browsing = 0;
+ return;
+ }
+
+ /*
+ * Finally, add the socket to the input selection set...
+ */
+
+ LogMessage(L_DEBUG2, "StartBrowsing: Adding fd %d to InputSet...",
+ BrowseSocket);
+
+ FD_SET(BrowseSocket, &InputSet);
+ }
+
+#ifdef HAVE_LIBSLP
+ if (BrowseProtocols & BROWSE_SLP)
+ {
+ /*
+ * Open SLP handle...
+ */
+
+ if (SLPOpen("en", SLP_FALSE, &BrowseSLPHandle) != SLP_OK)
+ {
+ LogMessage(L_ERROR, "Unable to open an SLP handle; disabling SLP browsing!");
+ BrowseProtocols &= ~BROWSE_SLP;
+ }
+
+ BrowseSLPRefresh = 0;
+ }
+#endif /* HAVE_LIBSLP */
+}
+
+
+/*
+ * 'StartPolling()' - Start polling servers as needed.
+ */
+
+void
+StartPolling(void)
+{
+ int i; /* Looping var */
+ dirsvc_poll_t *poll; /* Current polling server */
+ int pid; /* New process ID */
+ char sport[10]; /* Server port */
+ char bport[10]; /* Browser port */
+ char interval[10]; /* Poll interval */
+ int statusfds[2]; /* Status pipe */
+ int fd; /* Current file descriptor */
+
+
+ /*
+ * Don't do anything if we aren't polling...
+ */
+
+ if (NumPolled == 0)
+ {
+ PollPipe = -1;
+ return;
+ }
+
+ /*
+ * Setup string arguments for port and interval options.
+ */
+
+ sprintf(bport, "%d", BrowsePort);
+
+ if (BrowseInterval)
+ sprintf(interval, "%d", BrowseInterval);
+ else
+ strcpy(interval, "30");
+
+ /*
+ * Create a pipe that receives the status messages from each
+ * polling daemon...
+ */
+
+ if (pipe(statusfds))
+ {
+ LogMessage(L_ERROR, "Unable to create polling status pipes - %s.",
+ strerror(errno));
+ PollPipe = -1;
+ return;
+ }
+
+ PollPipe = statusfds[0];
+
+ /*
+ * Run each polling daemon, redirecting stderr to the polling pipe...
+ */
+
+ for (i = 0, poll = Polled; i < NumPolled; i ++, poll ++)
+ {
+ sprintf(sport, "%d", poll->port);
+
+ if ((pid = fork()) == 0)
+ {
+ /*
+ * Child...
+ */
+
+ if (getuid() == 0)
+ {
+ /*
+ * Running as root, so change to non-priviledged user...
+ */
+
+ if (setgid(Group))
+ exit(errno);
+
+ if (setuid(User))
+ exit(errno);
+ }
+
+ /*
+ * Reset group membership to just the main one we belong to.
+ */
+
+ setgroups(0, NULL);
+
+ /*
+ * Redirect stdin and stdout to /dev/null, and stderr to the
+ * status pipe. Close all other files.
+ */
+
+ close(0);
+ open("/dev/null", O_RDONLY);
+
+ close(1);
+ open("/dev/null", O_WRONLY);
+
+ close(2);
+ dup(statusfds[1]);
+
+ for (fd = 3; fd < MaxFDs; fd ++)
+ close(fd);
+
+ /*
+ * Execute the polling daemon...
+ */
+
+ execl(CUPS_SERVERBIN "/daemon/cups-polld", "cups-polld", poll->hostname,
+ sport, interval, bport, NULL);
+ exit(errno);
+ }
+ else if (pid < 0)
+ {
+ LogMessage(L_ERROR, "StartPolling: Unable to fork polling daemon - %s",
+ strerror(errno));
+ poll->pid = 0;
+ break;
+ }
+ else
+ {
+ poll->pid = pid;
+ LogMessage(L_DEBUG, "StartPolling: Started polling daemon for %s:%d, pid = %d",
+ poll->hostname, poll->port, pid);
+ }
+ }
+
+ close(statusfds[1]);
+
+ /*
+ * Finally, add the pipe to the input selection set...
+ */
+
+ LogMessage(L_DEBUG2, "StartPolling: Adding fd %d to InputSet...",
+ PollPipe);
+
+ FD_SET(PollPipe, &InputSet);
+}
+
+
+/*
+ * 'StopBrowsing()' - Stop sending and receiving broadcast information.
+ */
+
+void
+StopBrowsing(void)
+{
+ if (!Browsing)
+ return;
+
+ if (BrowseProtocols & BROWSE_CUPS)
+ {
+ /*
+ * Close the socket and remove it from the input selection set.
+ */
+
+ if (BrowseSocket >= 0)
+ {
+#ifdef WIN32
+ closesocket(BrowseSocket);
+#else
+ close(BrowseSocket);
+#endif /* WIN32 */
+
+ LogMessage(L_DEBUG2, "StopBrowsing: Removing fd %d from InputSet...",
+ BrowseSocket);
+
+ FD_CLR(BrowseSocket, &InputSet);
+ BrowseSocket = 0;
+ }
+ }
+
+#ifdef HAVE_LIBSLP
+ if (BrowseProtocols & BROWSE_SLP)
+ {
+ /*
+ * Close SLP handle...
+ */
+
+ SLPClose(BrowseSLPHandle);
+ }
+#endif /* HAVE_LIBSLP */
+}
+
+
+/*
+ * 'StopPolling()' - Stop polling servers as needed.
+ */
+
+void
+StopPolling(void)
+{
+ int i; /* Looping var */
+ dirsvc_poll_t *poll; /* Current polling server */
+
+
+ if (PollPipe >= 0)
+ {
+ close(PollPipe);
+
+ LogMessage(L_DEBUG2, "StopPolling: removing fd %d from InputSet.",
+ PollPipe);
+ FD_CLR(PollPipe, &InputSet);
+
+ PollPipe = -1;
+ }
+
+ for (i = 0, poll = Polled; i < NumPolled; i ++, poll ++)
+ if (poll->pid)
+ kill(poll->pid, SIGTERM);
+}
+
+
+/*
+ * 'UpdateCUPSBrowse()' - Update the browse lists using the CUPS protocol.
+ */
+
+void
+UpdateCUPSBrowse(void)
+{
+ int i; /* Looping var */
+ int auth; /* Authorization status */
+ int len; /* Length of name string */
+ int bytes; /* Number of bytes left */
+ char packet[1540], /* Broadcast packet */
+ *pptr; /* Pointer into packet */
+ struct sockaddr_in srcaddr; /* Source address */
+ char srcname[1024]; /* Source hostname */
+ unsigned address; /* Source address (host order) */
+ struct hostent *srchost; /* Host entry for source address */
+ cups_ptype_t type; /* Printer type */
+ ipp_pstate_t state; /* Printer state */
+ char uri[HTTP_MAX_URI], /* Printer URI */
+ method[HTTP_MAX_URI], /* Method portion of URI */
+ username[HTTP_MAX_URI], /* Username portion of URI */
+ host[HTTP_MAX_URI], /* Host portion of URI */
+ resource[HTTP_MAX_URI], /* Resource portion of URI */
+ info[IPP_MAX_NAME], /* Information string */
+ location[IPP_MAX_NAME], /* Location string */
+ make_model[IPP_MAX_NAME];/* Make and model string */
+ int port; /* Port portion of URI */
+ cups_netif_t *iface; /* Network interface */
+
+
+ /*
+ * Read a packet from the browse socket...
+ */
+
+ len = sizeof(srcaddr);
+ if ((bytes = recvfrom(BrowseSocket, packet, sizeof(packet), 0,
+ (struct sockaddr *)&srcaddr, &len)) <= 0)
+ {
+ /*
+ * "Connection refused" is returned under Linux if the destination port
+ * or address is unreachable from a previous sendto(); check for the
+ * error here and ignore it for now...
+ */
+
+ if (errno != ECONNREFUSED)
+ {
+ LogMessage(L_ERROR, "Browse recv failed - %s.", strerror(errno));
+ LogMessage(L_ERROR, "Browsing turned off.");
+
+ StopBrowsing();
+ Browsing = 0;
+ }
+
+ return;
+ }
+
+ packet[bytes] = '\0';
+
+ /*
+ * Figure out where it came from...
+ */
+
+ address = ntohl(srcaddr.sin_addr.s_addr);
+
+ if (HostNameLookups)
+#ifndef __sgi
+ srchost = gethostbyaddr((char *)&(srcaddr.sin_addr), sizeof(struct in_addr),
+ AF_INET);
+#else
+ srchost = gethostbyaddr(&(srcaddr.sin_addr), sizeof(struct in_addr),
+ AF_INET);
+#endif /* !__sgi */
+ else
+ srchost = NULL;
+
+ if (srchost == NULL)
+ sprintf(srcname, "%d.%d.%d.%d", address >> 24, (address >> 16) & 255,
+ (address >> 8) & 255, address & 255);
+ else
+ strlcpy(srcname, srchost->h_name, sizeof(srcname));
+
+ len = strlen(srcname);
+
+ /*
+ * Do ACL stuff...
+ */
+
+ if (BrowseACL && (BrowseACL->num_allow || BrowseACL->num_deny))
+ {
+ if (address == 0x7f000001 || strcasecmp(srcname, "localhost") == 0)
+ {
+ /*
+ * Access from localhost (127.0.0.1) is always allowed...
+ */
+
+ auth = AUTH_ALLOW;
+ }
+ else
+ {
+ /*
+ * Do authorization checks on the domain/address...
+ */
+
+ switch (BrowseACL->order_type)
+ {
+ default :
+ auth = AUTH_DENY; /* anti-compiler-warning-code */
+ break;
+
+ case AUTH_ALLOW : /* Order Deny,Allow */
+ auth = AUTH_ALLOW;
+
+ if (CheckAuth(address, srcname, len,
+ BrowseACL->num_deny, BrowseACL->deny))
+ auth = AUTH_DENY;
+
+ if (CheckAuth(address, srcname, len,
+ BrowseACL->num_allow, BrowseACL->allow))
+ auth = AUTH_ALLOW;
+ break;
+
+ case AUTH_DENY : /* Order Allow,Deny */
+ auth = AUTH_DENY;
+
+ if (CheckAuth(address, srcname, len,
+ BrowseACL->num_allow, BrowseACL->allow))
+ auth = AUTH_ALLOW;
+
+ if (CheckAuth(address, srcname, len,
+ BrowseACL->num_deny, BrowseACL->deny))
+ auth = AUTH_DENY;
+ break;
+ }
+ }
+ }
+ else
+ auth = AUTH_ALLOW;
+
+ if (auth == AUTH_DENY)
+ {
+ LogMessage(L_DEBUG, "UpdateCUPSBrowse: Refused %d bytes from %s", bytes,
+ srcname);
+ return;
+ }
+
+ LogMessage(L_DEBUG2, "UpdateCUPSBrowse: (%d bytes from %s) %s", bytes, srcname,
+ packet);
+
+ /*
+ * Parse packet...
+ */
+
+ if (sscanf(packet, "%x%x%1023s", (unsigned *)&type, (unsigned *)&state,
+ uri) < 3)
+ {
+ LogMessage(L_WARN, "UpdateCUPSBrowse: Garbled browse packet - %s",
+ packet);
+ return;
+ }
+
+ strcpy(location, "Location Unknown");
+ strcpy(info, "No Information Available");
+ make_model[0] = '\0';
+
+ if ((pptr = strchr(packet, '\"')) != NULL)
+ {
+ /*
+ * Have extended information; can't use sscanf for it because not all
+ * sscanf's allow empty strings with %[^\"]...
+ */
+
+ for (i = 0, pptr ++;
+ i < (sizeof(location) - 1) && *pptr && *pptr != '\"';
+ i ++, pptr ++)
+ location[i] = *pptr;
+
+ if (i)
+ location[i] = '\0';
+
+ if (*pptr == '\"')
+ pptr ++;
+
+ while (*pptr && isspace(*pptr))
+ pptr ++;
+
+ if (*pptr == '\"')
+ {
+ for (i = 0, pptr ++;
+ i < (sizeof(info) - 1) && *pptr && *pptr != '\"';
+ i ++, pptr ++)
+ info[i] = *pptr;
+
+ if (i)
+ info[i] = '\0';
+
+ if (*pptr == '\"')
+ pptr ++;
+
+ while (*pptr && isspace(*pptr))
+ pptr ++;
+
+ if (*pptr == '\"')
+ {
+ for (i = 0, pptr ++;
+ i < (sizeof(make_model) - 1) && *pptr && *pptr != '\"';
+ i ++, pptr ++)
+ make_model[i] = *pptr;
+
+ if (i)
+ make_model[i] = '\0';
+ }
+ }
+ }
+
+ DEBUG_puts(packet);
+ DEBUG_printf(("type=%x, state=%x, uri=\"%s\"\n"
+ "location=\"%s\", info=\"%s\", make_model=\"%s\"\n",
+ type, state, uri, location, info, make_model));
+
+ /*
+ * Pull the URI apart to see if this is a local or remote printer...
+ */
+
+ httpSeparate(uri, method, username, host, &port, resource);
+
+ DEBUG_printf(("host=\"%s\", ServerName=\"%s\"\n", host, ServerName));
+
+ /*
+ * Check for packets from the local server...
+ */
+
+ if (strcasecmp(host, ServerName) == 0)
+ return;
+
+ NetIFUpdate();
+
+ for (iface = NetIFList; iface != NULL; iface = iface->next)
+ if (strcasecmp(host, iface->hostname) == 0)
+ return;
+
+ /*
+ * Do relaying...
+ */
+
+ for (i = 0; i < NumRelays; i ++)
+ if (CheckAuth(address, srcname, len, 1, &(Relays[i].from)))
+ if (sendto(BrowseSocket, packet, bytes, 0,
+ (struct sockaddr *)&(Relays[i].to),
+ sizeof(struct sockaddr_in)) <= 0)
+ {
+ LogMessage(L_ERROR, "UpdateCUPSBrowse: sendto failed for relay %d - %s.",
+ i + 1, strerror(errno));
+ return;
+ }
+
+ /*
+ * Process the browse data...
+ */
+
+ ProcessBrowseData(uri, type, state, location, info, make_model);
+}
+
+
+/*
+ * 'UpdatePolling()' - Read status messages from the poll daemons.
+ */
+
+void
+UpdatePolling(void)
+{
+ int bytes; /* Number of bytes read */
+ char *lineptr; /* Pointer to end of line in buffer */
+ static int bufused = 0; /* Number of bytes used in buffer */
+ static char buffer[1024]; /* Status buffer */
+
+
+ if ((bytes = read(PollPipe, buffer + bufused,
+ sizeof(buffer) - bufused - 1)) > 0)
+ {
+ bufused += bytes;
+ buffer[bufused] = '\0';
+ lineptr = strchr(buffer, '\n');
+ }
+ else if (bytes < 0 && errno == EINTR)
+ return;
+ else
+ {
+ lineptr = buffer + bufused;
+ lineptr[1] = 0;
+ }
+
+ if (bytes == 0 && bufused == 0)
+ lineptr = NULL;
+
+ while (lineptr != NULL)
+ {
+ /*
+ * Terminate each line and process it...
+ */
+
+ *lineptr++ = '\0';
+
+ LogMessage(L_ERROR, "%s", buffer);
+
+ /*
+ * Copy over the buffer data we've used up...
+ */
+
+ strcpy(buffer, lineptr);
+ bufused -= lineptr - buffer;
+
+ if (bufused < 0)
+ bufused = 0;
+
+ lineptr = strchr(buffer, '\n');
+ }
+
+ if (bytes <= 0)
+ {
+ /*
+ * All polling processes have died; stop polling...
+ */
+
+ LogMessage(L_ERROR, "UpdatePolling: all polling processes have exited!");
+ StopPolling();
+ }
+}
+
+
+/***********************************************************************
+ **** SLP Support Code *************************************************
+ ***********************************************************************/
+
+#ifdef HAVE_LIBSLP
+/*
+ * SLP service name for CUPS...
+ */
+
+# define SLP_CUPS_SRVTYPE "service:printer"
+# define SLP_CUPS_SRVLEN 15
+
+
+/*
+ * Printer service URL structure
+ */
+
+typedef struct _slpsrvurl
+{
+ struct _slpsrvurl *next;
+ char url[HTTP_MAX_URI];
+} slpsrvurl_t;
+
+
+/*
+ * 'RegReportCallback()' - Empty SLPRegReport.
+ */
+
+void
+RegReportCallback(SLPHandle hslp,
+ SLPError errcode,
+ void *cookie)
+{
+ (void)hslp;
+ (void)errcode;
+ (void)cookie;
+
+ return;
+}
+
+
+/*
+ * 'SendSLPBrowse()' - Register the specified printer with SLP.
+ */
+
+void
+SendSLPBrowse(printer_t *p) /* I - Printer to register */
+{
+ char srvurl[HTTP_MAX_URI], /* Printer service URI */
+ attrs[8192], /* Printer attributes */
+ finishings[1024], /* Finishings to support */
+ make_model[IPP_MAX_NAME * 2],
+ /* Make and model, quoted */
+ location[IPP_MAX_NAME * 2],
+ /* Location, quoted */
+ info[IPP_MAX_NAME * 2],
+ /* Info, quoted */
+ *src, /* Pointer to original string */
+ *dst; /* Pointer to destination string */
+ ipp_attribute_t *authentication; /* uri-authentication-supported value */
+ SLPError error; /* SLP error, if any */
+
+
+ LogMessage(L_DEBUG, "SendSLPBrowse(%p = \"%s\")", p, p->name);
+
+ /*
+ * Make the SLP service URL that conforms to the IANA
+ * 'printer:' template.
+ */
+
+ snprintf(srvurl, sizeof(srvurl), SLP_CUPS_SRVTYPE ":%s", p->uri);
+
+ LogMessage(L_DEBUG2, "Service URL = \"%s\"", srvurl);
+
+ /*
+ * Figure out the finishings string...
+ */
+
+ if (p->type & CUPS_PRINTER_STAPLE)
+ strcpy(finishings, "staple");
+ else
+ finishings[0] = '\0';
+
+ if (p->type & CUPS_PRINTER_BIND)
+ {
+ if (finishings[0])
+ strlcat(finishings, ",bind", sizeof(finishings));
+ else
+ strcpy(finishings, "bind");
+ }
+
+ if (p->type & CUPS_PRINTER_PUNCH)
+ {
+ if (finishings[0])
+ strlcat(finishings, ",punch", sizeof(finishings));
+ else
+ strcpy(finishings, "punch");
+ }
+
+ if (p->type & CUPS_PRINTER_COVER)
+ {
+ if (finishings[0])
+ strlcat(finishings, ",cover", sizeof(finishings));
+ else
+ strcpy(finishings, "cover");
+ }
+
+ if (p->type & CUPS_PRINTER_SORT)
+ {
+ if (finishings[0])
+ strlcat(finishings, ",sort", sizeof(finishings));
+ else
+ strcpy(finishings, "sort");
+ }
+
+ if (!finishings[0])
+ strcpy(finishings, "none");
+
+ /*
+ * Quote any commas in the make and model, location, and info strings
+ * (local strings are twice the size of the ones in the printer_t
+ * structure, so no buffer overflow is possible...)
+ */
+
+ for (src = p->make_model, dst = make_model; *src;)
+ {
+ if (*src == ',' || *src == '\\' || *src == ')')
+ *dst++ = '\\';
+
+ *dst++ = *src++;
+ }
+
+ *dst = '\0';
+
+ if (!make_model[0])
+ strcpy(make_model, "Unknown");
+
+ for (src = p->location, dst = location; *src;)
+ {
+ if (*src == ',' || *src == '\\' || *src == ')')
+ *dst++ = '\\';
+
+ *dst++ = *src++;
+ }
+
+ *dst = '\0';
+
+ if (!location[0])
+ strcpy(location, "Unknown");
+
+ for (src = p->info, dst = info; *src;)
+ {
+ if (*src == ',' || *src == '\\' || *src == ')')
+ *dst++ = '\\';
+
+ *dst++ = *src++;
+ }
+
+ *dst = '\0';
+
+ if (!info[0])
+ strcpy(info, "Unknown");
+
+ /*
+ * Get the authentication value...
+ */
+
+ authentication = ippFindAttribute(p->attrs, "uri-authentication-supported",
+ IPP_TAG_KEYWORD);
+
+ /*
+ * Make the SLP attribute string list that conforms to
+ * the IANA 'printer:' template.
+ */
+
+ snprintf(attrs, sizeof(attrs),
+ "(printer-uri-supported=%s),"
+ "(uri-authentication-supported=%s>),"
+#ifdef HAVE_LIBSSL
+ "(uri-security-supported=tls>),"
+#else
+ "(uri-security-supported=none>),"
+#endif /* HAVE_LIBSSL */
+ "(printer-name=%s),"
+ "(printer-location=%s),"
+ "(printer-info=%s),"
+ "(printer-more-info=%s),"
+ "(printer-make-and-model=%s),"
+ "(charset-supported=utf-8),"
+ "(natural-language-configured=%s),"
+ "(natural-language-supported=de,en,es,fr,it),"
+ "(color-supported=%s),"
+ "(finishings-supported=%s),"
+ "(sides-supported=one-sided%s),"
+ "(multiple-document-jobs-supported=true)"
+ "(ipp-versions-supported=1.0,1.1)",
+ p->uri, authentication->values[0].string.text, p->name, location,
+ info, p->uri, make_model, DefaultLanguage,
+ p->type & CUPS_PRINTER_COLOR ? "true" : "false",
+ finishings,
+ p->type & CUPS_PRINTER_DUPLEX ?
+ ",two-sided-long-edge,two-sided-short-edge" : "");
+
+ LogMessage(L_DEBUG2, "Attributes = \"%s\"", attrs);
+
+ /*
+ * Register the printer with the SLP server...
+ */
+
+ error = SLPReg(BrowseSLPHandle, srvurl, BrowseTimeout,
+ SLP_CUPS_SRVTYPE, attrs, SLP_TRUE, RegReportCallback, 0);
+
+ if (error != SLP_OK)
+ LogMessage(L_ERROR, "SLPReg of \"%s\" failed with status %d!", p->name,
+ error);
+}
+
+
+/*
+ * 'SLPDeregPrinter()' - SLPDereg() the specified printer
+ */
+
+void
+SLPDeregPrinter(printer_t *p)
+{
+ char srvurl[HTTP_MAX_URI]; /* Printer service URI */
+
+
+ if((p->type & CUPS_PRINTER_REMOTE) == 0)
+ {
+ /*
+ * Make the SLP service URL that conforms to the IANA
+ * 'printer:' template.
+ */
+
+ snprintf(srvurl, sizeof(srvurl), SLP_CUPS_SRVTYPE ":%s", p->uri);
+
+ /*
+ * Deregister the printer...
+ */
+
+ SLPDereg(BrowseSLPHandle, srvurl, RegReportCallback, 0);
+ }
+}
+
+
+/*
+ * 'GetSlpAttrVal()' - Get an attribute from an SLP registration.
+ */
+
+int /* O - 0 on success */
+GetSlpAttrVal(const char *attrlist, /* I - Attribute list string */
+ const char *tag, /* I - Name of attribute */
+ char *valbuf, /* O - Value */
+ int valbuflen) /* I - Max length of value */
+{
+ char *ptr1, /* Pointer into string */
+ *ptr2; /* ... */
+
+
+ valbuf[0] = '\0';
+
+ if ((ptr1 = strstr(attrlist, tag)) != NULL)
+ {
+ ptr1 += strlen(tag);
+
+ if ((ptr2 = strchr(ptr1,')')) != NULL)
+ {
+ if (valbuflen > (ptr2 - ptr1))
+ {
+ /*
+ * Copy the value...
+ */
+
+ strncpy(valbuf, ptr1, ptr2 - ptr1);
+ valbuf[ptr2 - ptr1] = '\0';
+
+ /*
+ * Dequote the value...
+ */
+
+ for (ptr1 = valbuf; *ptr1; ptr1 ++)
+ if (*ptr1 == '\\' && ptr1[1])
+ strcpy(ptr1, ptr1 + 1);
+
+ return (0);
+ }
+ }
+ }
+
+ return (-1);
+}
+
+
+/*
+ * 'AttrCallback()' - SLP attribute callback
+ */
+
+SLPBoolean
+AttrCallback(SLPHandle hslp,
+ const char *attrlist,
+ SLPError errcode,
+ void *cookie)
+{
+ char tmp[IPP_MAX_NAME];
+ printer_t *p = (printer_t*)cookie;
+
+
+ /*
+ * Let the compiler know we won't be using these...
+ */
+
+ (void)hslp;
+
+ /*
+ * Bail if there was an error
+ */
+
+ if (errcode != SLP_OK)
+ return (SLP_TRUE);
+
+ /*
+ * Parse the attrlist to obtain things needed to build CUPS browse packet
+ */
+
+ memset(p, 0, sizeof(printer_t));
+
+ p->type = CUPS_PRINTER_REMOTE;
+
+ if (GetSlpAttrVal(attrlist, "(printer-location=", p->location,
+ sizeof(p->location)))
+ return (SLP_FALSE);
+ if (GetSlpAttrVal(attrlist, "(printer-make-and-model=", p->make_model,
+ sizeof(p->make_model)))
+ return (SLP_FALSE);
+
+ if (GetSlpAttrVal(attrlist, "(color-supported=", tmp, sizeof(tmp)))
+ return (SLP_FALSE);
+ if (strcasecmp(tmp, "true") == 0)
+ p->type |= CUPS_PRINTER_COLOR;
+
+ if (GetSlpAttrVal(attrlist, "(finishings-supported=", tmp, sizeof(tmp)))
+ return (SLP_FALSE);
+ if (strstr(tmp, "staple"))
+ p->type |= CUPS_PRINTER_STAPLE;
+ if (strstr(tmp, "bind"))
+ p->type |= CUPS_PRINTER_BIND;
+ if (strstr(tmp, "punch"))
+ p->type |= CUPS_PRINTER_PUNCH;
+
+ if (GetSlpAttrVal(attrlist, "(sides-supported=", tmp, sizeof(tmp)))
+ return (SLP_FALSE);
+ if (strstr(tmp,"two-sided"))
+ p->type |= CUPS_PRINTER_DUPLEX;
+
+ return (SLP_TRUE);
+}
+
+
+/*
+ * 'SrvUrlCallback()' - SLP service url callback
+ */
+
+SLPBoolean /* O - TRUE = OK, FALSE = error */
+SrvUrlCallback(SLPHandle hslp, /* I - SLP handle */
+ const char *srvurl, /* I - URL of service */
+ unsigned short lifetime, /* I - Life of service */
+ SLPError errcode, /* I - Existing error code */
+ void *cookie) /* I - Pointer to service list */
+{
+ slpsrvurl_t *s, /* New service entry */
+ **head; /* Pointer to head of entry */
+
+
+ /*
+ * Let the compiler know we won't be using these vars...
+ */
+
+ (void)hslp;
+ (void)lifetime;
+
+ /*
+ * Bail if there was an error
+ */
+
+ if (errcode != SLP_OK)
+ return (SLP_TRUE);
+
+ /*
+ * Grab the head of the list...
+ */
+
+ head = (slpsrvurl_t**)cookie;
+
+ /*
+ * Allocate a *temporary* slpsrvurl_t to hold this entry.
+ */
+
+ if ((s = (slpsrvurl_t *)calloc(1, sizeof(slpsrvurl_t))) == NULL)
+ return (SLP_FALSE);
+
+ /*
+ * Copy the SLP service URL...
+ */
+
+ strlcpy(s->url, srvurl, sizeof(s->url));
+
+ /*
+ * Link the SLP service URL into the head of the list
+ */
+
+ if (*head)
+ s->next = *head;
+
+ *head = s;
+
+ return (SLP_TRUE);
+}
+
+
+/*
+ * 'UpdateSLPBrowse()' - Get browsing information via SLP.
+ */
+
+void
+UpdateSLPBrowse(void)
+{
+ slpsrvurl_t *s, /* Temporary list of service URLs */
+ *next; /* Next service in list */
+ printer_t p; /* Printer information */
+ const char *uri; /* Pointer to printer URI */
+ char method[HTTP_MAX_URI], /* Method portion of URI */
+ username[HTTP_MAX_URI], /* Username portion of URI */
+ host[HTTP_MAX_URI], /* Host portion of URI */
+ resource[HTTP_MAX_URI]; /* Resource portion of URI */
+ int port; /* Port portion of URI */
+
+
+ LogMessage(L_DEBUG, "UpdateSLPBrowse() Start...");
+
+ /*
+ * Reset the refresh time...
+ */
+
+ BrowseSLPRefresh = time(NULL) + BrowseTimeout - BrowseInterval;
+
+ /*
+ * Poll for remote printers using SLP...
+ */
+
+ s = NULL;
+
+ SLPFindSrvs(BrowseSLPHandle, SLP_CUPS_SRVTYPE, "", "",
+ SrvUrlCallback, &s);
+
+ /*
+ * Loop through the list of available printers...
+ */
+
+ for (; s; s = next)
+ {
+ /*
+ * Load a printer_t structure with the SLP service attributes...
+ */
+
+ SLPFindAttrs(BrowseSLPHandle, s->url, "", "", AttrCallback, &p);
+
+ /*
+ * Process this printer entry...
+ */
+
+ uri = s->url + SLP_CUPS_SRVLEN + 1;
+
+ if (strncmp(uri, "http://", 7) == 0 ||
+ strncmp(uri, "ipp://", 6) == 0)
+ {
+ /*
+ * Pull the URI apart to see if this is a local or remote printer...
+ */
+
+ httpSeparate(uri, method, username, host, &port, resource);
+
+ if (strcasecmp(host, ServerName) == 0)
+ continue;
+
+ /*
+ * OK, at least an IPP printer, see if it is a CUPS printer or
+ * class...
+ */
+
+ if (strstr(uri, "/printers/") != NULL)
+ ProcessBrowseData(uri, p.type, IPP_PRINTER_IDLE, p.location,
+ p.info, p.make_model);
+ else if (strstr(uri, "/classes/") != NULL)
+ ProcessBrowseData(uri, p.type | CUPS_PRINTER_CLASS, IPP_PRINTER_IDLE,
+ p.location, p.info, p.make_model);
+ }
+
+ /*
+ * Save the "next" pointer and free this listing...
+ */
+
+ next = s->next;
+ free(s);
+ }
+
+ LogMessage(L_DEBUG, "UpdateSLPBrowse() End...");
+}
+#endif /* HAVE_LIBSLP */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/dirsvc.h b/scheduler/dirsvc.h
new file mode 100644
index 000000000..1434dbe4e
--- /dev/null
+++ b/scheduler/dirsvc.h
@@ -0,0 +1,143 @@
+/*
+ * "$Id$"
+ *
+ * Directory services definitions for the Common UNIX Printing System
+ * (CUPS) scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#ifdef HAVE_LIBSLP
+# include <slp.h>
+#endif /* HAVE_LIBSLP */
+
+
+/*
+ * Browse protocols...
+ */
+
+#define BROWSE_CUPS 1 /* CUPS */
+#define BROWSE_SLP 2 /* SLPv2 */
+#define BROWSE_LDAP 4 /* LDAP (not supported yet) */
+#define BROWSE_ALL 7 /* All protocols */
+
+
+/*
+ * Browse address...
+ */
+
+typedef struct
+{
+ char iface[32]; /* Destination interface */
+ struct sockaddr_in to; /* Destination address */
+} dirsvc_addr_t;
+
+
+/*
+ * Relay structure...
+ */
+
+typedef struct
+{
+ authmask_t from; /* Source address/name mask */
+ struct sockaddr_in to; /* Destination address */
+} dirsvc_relay_t;
+
+
+/*
+ * Polling structure...
+ */
+
+typedef struct
+{
+ char hostname[16]; /* Hostname (actually, IP address) */
+ int port; /* Port number */
+ int pid; /* Current poll server PID */
+} dirsvc_poll_t;
+
+
+/*
+ * Globals...
+ */
+
+VAR int Browsing VALUE(TRUE),
+ /* Whether or not browsing is enabled */
+ BrowseProtocols VALUE(BROWSE_ALL),
+ /* Protocols to support */
+ BrowseShortNames VALUE(TRUE),
+ /* Short names for remote printers? */
+ BrowseSocket VALUE(-1),
+ /* Socket for browsing */
+ BrowsePort VALUE(IPP_PORT),
+ /* Port number for broadcasts */
+ BrowseInterval VALUE(DEFAULT_INTERVAL),
+ /* Broadcast interval in seconds */
+ BrowseTimeout VALUE(DEFAULT_TIMEOUT),
+ /* Time out for printers in seconds */
+ NumBrowsers VALUE(0);
+ /* Number of broadcast addresses */
+VAR dirsvc_addr_t Browsers[MAX_BROWSERS];
+ /* Broadcast addresses */
+VAR location_t *BrowseACL VALUE(NULL);
+ /* Browser access control list */
+VAR int NumRelays VALUE(0);
+ /* Number of broadcast relays */
+VAR dirsvc_relay_t Relays[MAX_BROWSERS];
+ /* Broadcast relays */
+VAR int NumPolled VALUE(0);
+ /* Number of polled servers */
+VAR dirsvc_poll_t Polled[MAX_BROWSERS];
+ /* Polled servers */
+VAR int PollPipe VALUE(0);
+ /* Status pipe for pollers */
+
+#ifdef HAVE_LIBSLP
+VAR SLPHandle BrowseSLPHandle VALUE(NULL);
+ /* SLP API handle */
+VAR time_t BrowseSLPRefresh VALUE(0);
+ /* Next SLP refresh time */
+#endif /* HAVE_LIBSLP */
+
+
+/*
+ * Prototypes...
+ */
+
+extern void ProcessBrowseData(const char *uri, cups_ptype_t type,
+ ipp_pstate_t state, const char *location,
+ const char *info, const char *make_model);
+extern void SendBrowseList(void);
+extern void SendCUPSBrowse(printer_t *p);
+extern void SendSLPBrowse(printer_t *p);
+extern void StartBrowsing(void);
+extern void StartPolling(void);
+extern void StopBrowsing(void);
+extern void StopPolling(void);
+extern void UpdateCUPSBrowse(void);
+extern void UpdatePolling(void);
+extern void UpdateSLPBrowse(void);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/filter.c b/scheduler/filter.c
new file mode 100644
index 000000000..7c674a308
--- /dev/null
+++ b/scheduler/filter.c
@@ -0,0 +1,320 @@
+/*
+ * "$Id$"
+ *
+ * File type conversion routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * mimeAddFilter() - Add a filter to the current MIME database.
+ * mimeFilter() - Find the fastest way to convert from one type to another.
+ * compare() - Compare two filter types...
+ * lookup() - Lookup a filter...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <cups/debug.h>
+#include <cups/string.h>
+#include "mime.h"
+
+
+/*
+ * Local functions...
+ */
+
+static int compare(mime_filter_t *, mime_filter_t *);
+static mime_filter_t *lookup(mime_t *, mime_type_t *, mime_type_t *);
+
+
+/*
+ * 'mimeAddFilter()' - Add a filter to the current MIME database.
+ */
+
+mime_filter_t * /* O - New filter */
+mimeAddFilter(mime_t *mime, /* I - MIME database */
+ mime_type_t *src, /* I - Source type */
+ mime_type_t *dst, /* I - Destination type */
+ int cost, /* I - Relative time/resource cost */
+ const char *filter) /* I - Filter program to run */
+{
+ mime_filter_t *temp; /* New filter */
+
+
+ /*
+ * Range-check the input...
+ */
+
+ if (mime == NULL || src == NULL || dst == NULL || filter == NULL)
+ return (NULL);
+
+ if (strlen(filter) > (MIME_MAX_FILTER - 1))
+ return (NULL);
+
+ /*
+ * See if we already have an existing filter for the given source and
+ * destination...
+ */
+
+ if ((temp = lookup(mime, src, dst)) != NULL)
+ {
+ /*
+ * Yup, does the existing filter have a higher cost? If so, copy the
+ * filter and cost to the existing filter entry and return it...
+ */
+
+ if (temp->cost > cost)
+ {
+ temp->cost = cost;
+ strlcpy(temp->filter, filter, sizeof(temp->filter));
+ }
+ }
+ else
+ {
+ /*
+ * Nope, add a new one...
+ */
+
+ if (mime->num_filters == 0)
+ temp = malloc(sizeof(mime_filter_t));
+ else
+ temp = realloc(mime->filters, sizeof(mime_filter_t) * (mime->num_filters + 1));
+
+ if (temp == NULL)
+ return (NULL);
+
+ mime->filters = temp;
+ temp += mime->num_filters;
+ mime->num_filters ++;
+
+ /*
+ * Copy the information over and sort if necessary...
+ */
+
+ temp->src = src;
+ temp->dst = dst;
+ temp->cost = cost;
+ strlcpy(temp->filter, filter, sizeof(temp->filter));
+
+ if (mime->num_filters > 1)
+ qsort(mime->filters, mime->num_filters, sizeof(mime_filter_t),
+ (int (*)(const void *, const void *))compare);
+ }
+
+ /*
+ * Return the new/updated filter...
+ */
+
+ return (temp);
+}
+
+
+/*
+ * 'mimeFilter()' - Find the fastest way to convert from one type to another.
+ */
+
+mime_filter_t * /* O - Array of filters to run */
+mimeFilter(mime_t *mime, /* I - MIME database */
+ mime_type_t *src, /* I - Source file type */
+ mime_type_t *dst, /* I - Destination file type */
+ int *num_filters, /* O - Number of filters to run */
+ int max_depth) /* I - Maximum depth of search */
+{
+ int i, j, /* Looping vars */
+ num_temp, /* Number of temporary filters */
+ num_mintemp, /* Number of filters in the minimum */
+ cost, /* Current cost */
+ mincost; /* Current minimum */
+ mime_filter_t *temp, /* Temporary filter */
+ *mintemp, /* Current minimum */
+ *mincurrent, /* Current filter for minimum */
+ *current, /* Current filter */
+ *filters; /* Filters to use */
+
+
+ /*
+ * Range-check the input...
+ */
+
+ DEBUG_printf(("mimeFilter(mime=%p, src=%p(%s/%s), dst=%p(%s/%s), num_filters=%p(%d))\n",
+ mime, src, src ? src->super : "?", src ? src->type : "?",
+ dst, dst ? dst->super : "?", dst ? dst->type : "?",
+ num_filters, num_filters ? *num_filters : 0));
+
+ if (mime == NULL || src == NULL || dst == NULL || num_filters == NULL ||
+ max_depth <= 0)
+ return (NULL);
+
+ *num_filters = 0;
+
+ /*
+ * See if there is a filter that can convert the files directly...
+ */
+
+ if ((temp = lookup(mime, src, dst)) != NULL)
+ {
+ /*
+ * Got a direct filter!
+ */
+
+ if ((filters = (mime_filter_t *)malloc(sizeof(mime_filter_t))) == NULL)
+ return (NULL);
+
+ memcpy(filters, temp, sizeof(mime_filter_t));
+ *num_filters = 1;
+
+ DEBUG_puts(" Returning 1 filter:");
+ DEBUG_printf((" %s\n", filters->filter));
+
+ return (filters);
+ }
+
+ /*
+ * OK, now look for filters from the source type to any other type...
+ */
+
+ mincost = 9999999;
+ mintemp = NULL;
+ num_mintemp = 0;
+ mincurrent = NULL;
+
+ for (i = mime->num_filters, current = mime->filters; i > 0; i --, current ++)
+ if (current->src == src)
+ {
+ /*
+ * See if we have any filters that can convert from the destination type
+ * of this filter to the final type...
+ */
+
+ if ((temp = mimeFilter(mime, current->dst, dst, &num_temp,
+ max_depth - 1)) == NULL)
+ continue;
+
+ /*
+ * Found a match; see if this one is less costly than the last (if
+ * any...)
+ */
+
+ for (j = 0, cost = 0; j < num_temp; j ++)
+ cost += temp->cost;
+
+ if (cost < mincost)
+ {
+ if (mintemp != NULL)
+ free(mintemp);
+
+ mincost = cost;
+ mintemp = temp;
+ num_mintemp = num_temp;
+ mincurrent = current;
+ }
+ else
+ free(temp);
+ }
+
+ if (mintemp != NULL)
+ {
+ /*
+ * Hey, we got a match! Add the current filter to the beginning of the
+ * filter list...
+ */
+
+ filters = (mime_filter_t *)realloc(mintemp, sizeof(mime_filter_t) *
+ (num_mintemp + 1));
+
+ if (filters == NULL)
+ {
+ *num_filters = 0;
+ return (NULL);
+ }
+
+ memmove(filters + 1, filters, num_mintemp * sizeof(mime_filter_t));
+ memcpy(filters, mincurrent, sizeof(mime_filter_t));
+
+ *num_filters = num_mintemp + 1;
+
+#ifdef DEBUG
+ printf(" Returning %d filters:\n", *num_filters);
+ for (i = 0; i <= num_mintemp; i ++)
+ printf(" %s\n", filters[i].filter);
+#endif /* DEBUG */
+
+ return (filters);
+ }
+
+ DEBUG_puts(" Returning zippo...");
+
+ return (NULL);
+}
+
+
+/*
+ * 'compare()' - Compare two filter types...
+ */
+
+static int /* O - Comparison result */
+compare(mime_filter_t *f0, /* I - First filter */
+ mime_filter_t *f1) /* I - Second filter */
+{
+ int i; /* Result of comparison */
+
+
+ if ((i = strcmp(f0->src->super, f1->src->super)) == 0)
+ if ((i = strcmp(f0->src->type, f1->src->type)) == 0)
+ if ((i = strcmp(f0->dst->super, f1->dst->super)) == 0)
+ i = strcmp(f0->dst->type, f1->dst->type);
+
+ return (i);
+}
+
+
+/*
+ * 'lookup()' - Lookup a filter...
+ */
+
+static mime_filter_t * /* O - Filter for src->dst */
+lookup(mime_t *mime, /* I - MIME database */
+ mime_type_t *src, /* I - Source type */
+ mime_type_t *dst) /* I - Destination type */
+{
+ mime_filter_t key; /* Key record for filter search */
+
+
+ if (mime->num_filters == 0)
+ return (NULL);
+
+ key.src = src;
+ key.dst = dst;
+
+ return ((mime_filter_t *)bsearch(&key, mime->filters, mime->num_filters,
+ sizeof(mime_filter_t),
+ (int (*)(const void *, const void *))compare));
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
new file mode 100644
index 000000000..c1ca8b161
--- /dev/null
+++ b/scheduler/ipp.c
@@ -0,0 +1,5983 @@
+/*
+ * "$Id$"
+ *
+ * IPP routines for the Common UNIX Printing System (CUPS) scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * ProcessIPPRequest() - Process an incoming IPP request...
+ * accept_jobs() - Accept print jobs to a printer.
+ * add_class() - Add a class to the system.
+ * add_file() - Add a file to a job.
+ * add_job_state_reasons() - Add the "job-state-reasons" attribute based
+ * upon the job and printer state...
+ * add_printer() - Add a printer to the system.
+ * add_printer_state_reasons() - Add the "printer-state-reasons" attribute
+ * based upon the printer state...
+ * add_queued_job_count() - Add the "queued-job-count" attribute for
+ * cancel_all_jobs() - Cancel all print jobs.
+ * cancel_job() - Cancel a print job.
+ * check_quotas() - Check quotas for a printer and user.
+ * copy_attribute() - Copy a single attribute.
+ * copy_attrs() - Copy attributes from one request to another.
+ * create_job() - Print a file to a printer or class.
+ * copy_banner() - Copy a banner file to the requests directory
+ * for the specified job.
+ * copy_file() - Copy a PPD file or interface script...
+ * delete_printer() - Remove a printer or class from the system.
+ * get_default() - Get the default destination.
+ * get_devices() - Get the list of available devices on the
+ * local system.
+ * get_jobs() - Get a list of jobs for the specified printer.
+ * get_job_attrs() - Get job attributes.
+ * get_ppds() - Get the list of PPD files on the local
+ * system.
+ * get_printer_attrs() - Get printer attributes.
+ * get_printers() - Get a list of printers.
+ * hold_job() - Hold a print job.
+ * move_job() - Move a job to a new destination.
+ * print_job() - Print a file to a printer or class.
+ * read_ps_job_ticket() - Reads a job ticket embedded in a PS file.
+ * reject_jobs() - Reject print jobs to a printer.
+ * release_job() - Release a held print job.
+ * restart_job() - Restart an old print job.
+ * send_document() - Send a file to a printer or class.
+ * send_ipp_error() - Send an error status back to the IPP client.
+ * set_default() - Set the default destination...
+ * set_job_attrs() - Set job attributes.
+ * start_printer() - Start a printer.
+ * stop_printer() - Stop a printer.
+ * validate_job() - Validate printer options and destination.
+ * validate_user() - Validate the user for the request.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+#include <pwd.h>
+#include <grp.h>
+#ifdef HAVE_LIBZ
+# include <zlib.h>
+#endif /* HAVE_LIBZ */
+
+
+/*
+ * Local functions...
+ */
+
+static void accept_jobs(client_t *con, ipp_attribute_t *uri);
+static void add_class(client_t *con, ipp_attribute_t *uri);
+static int add_file(client_t *con, job_t *job, mime_type_t *filetype);
+static void add_job_state_reasons(client_t *con, job_t *job);
+static void add_printer(client_t *con, ipp_attribute_t *uri);
+static void add_printer_state_reasons(client_t *con, printer_t *p);
+static void add_queued_job_count(client_t *con, printer_t *p);
+static void cancel_all_jobs(client_t *con, ipp_attribute_t *uri);
+static void cancel_job(client_t *con, ipp_attribute_t *uri);
+static int check_quotas(client_t *con, printer_t *p);
+static void copy_attribute(ipp_t *to, ipp_attribute_t *attr,
+ int quickcopy);
+static void copy_attrs(ipp_t *to, ipp_t *from, ipp_attribute_t *req,
+ ipp_tag_t group);
+static int copy_banner(client_t *con, job_t *job, const char *name);
+static int copy_file(const char *from, const char *to);
+static void create_job(client_t *con, ipp_attribute_t *uri);
+static void delete_printer(client_t *con, ipp_attribute_t *uri);
+static void get_default(client_t *con);
+static void get_devices(client_t *con);
+static void get_jobs(client_t *con, ipp_attribute_t *uri);
+static void get_job_attrs(client_t *con, ipp_attribute_t *uri);
+static void get_ppds(client_t *con);
+static void get_printers(client_t *con, int type);
+static void get_printer_attrs(client_t *con, ipp_attribute_t *uri);
+static void hold_job(client_t *con, ipp_attribute_t *uri);
+static void move_job(client_t *con, ipp_attribute_t *uri);
+static void print_job(client_t *con, ipp_attribute_t *uri);
+static void read_ps_job_ticket(client_t *con);
+static void reject_jobs(client_t *con, ipp_attribute_t *uri);
+static void release_job(client_t *con, ipp_attribute_t *uri);
+static void restart_job(client_t *con, ipp_attribute_t *uri);
+static void send_document(client_t *con, ipp_attribute_t *uri);
+static void send_ipp_error(client_t *con, ipp_status_t status);
+static void set_default(client_t *con, ipp_attribute_t *uri);
+static void set_job_attrs(client_t *con, ipp_attribute_t *uri);
+static void start_printer(client_t *con, ipp_attribute_t *uri);
+static void stop_printer(client_t *con, ipp_attribute_t *uri);
+static void validate_job(client_t *con, ipp_attribute_t *uri);
+static int validate_user(client_t *con, const char *owner, char *username,
+ int userlen);
+
+
+/*
+ * 'ProcessIPPRequest()' - Process an incoming IPP request...
+ */
+
+void
+ProcessIPPRequest(client_t *con) /* I - Client connection */
+{
+ ipp_tag_t group; /* Current group tag */
+ ipp_attribute_t *attr; /* Current attribute */
+ ipp_attribute_t *charset; /* Character set attribute */
+ ipp_attribute_t *language; /* Language attribute */
+ ipp_attribute_t *uri; /* Printer URI attribute */
+ ipp_attribute_t *username; /* requesting-user-name attr */
+
+
+ LogMessage(L_DEBUG2, "ProcessIPPRequest(%p[%d]): operation_id = %04x",
+ con, con->http.fd, con->request->request.op.operation_id);
+
+ /*
+ * First build an empty response message for this request...
+ */
+
+ con->response = ippNew();
+
+ con->response->request.status.version[0] = con->request->request.op.version[0];
+ con->response->request.status.version[1] = con->request->request.op.version[1];
+ con->response->request.status.request_id = con->request->request.op.request_id;
+
+ /*
+ * Then validate the request header and required attributes...
+ */
+
+ if (con->request->request.any.version[0] != 1)
+ {
+ /*
+ * Return an error, since we only support IPP 1.x.
+ */
+
+ LogMessage(L_ERROR, "ProcessIPPRequest: bad request version (%d.%d)!",
+ con->request->request.any.version[0],
+ con->request->request.any.version[1]);
+
+ send_ipp_error(con, IPP_VERSION_NOT_SUPPORTED);
+ }
+ else if (con->request->attrs == NULL)
+ {
+ LogMessage(L_ERROR, "ProcessIPPRequest: no attributes in request!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ }
+ else
+ {
+ /*
+ * Make sure that the attributes are provided in the correct order and
+ * don't repeat groups...
+ */
+
+ for (attr = con->request->attrs, group = attr->group_tag;
+ attr != NULL;
+ attr = attr->next)
+ if (attr->group_tag < group)
+ {
+ /*
+ * Out of order; return an error...
+ */
+
+ LogMessage(L_ERROR, "ProcessIPPRequest: attribute groups are out of order!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ break;
+ }
+ else
+ group = attr->group_tag;
+
+ if (attr == NULL)
+ {
+ /*
+ * Then make sure that the first three attributes are:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri/job-uri
+ */
+
+ attr = con->request->attrs;
+ if (attr != NULL && strcmp(attr->name, "attributes-charset") == 0 &&
+ attr->value_tag == IPP_TAG_CHARSET)
+ charset = attr;
+ else
+ charset = NULL;
+
+ if (attr)
+ attr = attr->next;
+ if (attr != NULL && strcmp(attr->name, "attributes-natural-language") == 0 &&
+ attr->value_tag == IPP_TAG_LANGUAGE)
+ language = attr;
+ else
+ language = NULL;
+
+ if ((attr = ippFindAttribute(con->request, "printer-uri", IPP_TAG_URI)) != NULL)
+ uri = attr;
+ else if ((attr = ippFindAttribute(con->request, "job-uri", IPP_TAG_URI)) != NULL)
+ uri = attr;
+ else
+ uri = NULL;
+
+ if (charset)
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, charset->values[0].string.text);
+ else
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, DefaultCharset);
+
+ if (language)
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language->values[0].string.text);
+ else
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, DefaultLanguage);
+
+ if (charset == NULL || language == NULL ||
+ (uri == NULL &&
+ con->request->request.op.operation_id != CUPS_GET_DEFAULT &&
+ con->request->request.op.operation_id != CUPS_GET_PRINTERS &&
+ con->request->request.op.operation_id != CUPS_GET_CLASSES &&
+ con->request->request.op.operation_id != CUPS_GET_DEVICES &&
+ con->request->request.op.operation_id != CUPS_GET_PPDS))
+ {
+ /*
+ * Return an error, since attributes-charset,
+ * attributes-natural-language, and printer-uri/job-uri are required
+ * for all operations.
+ */
+
+ if (charset == NULL)
+ LogMessage(L_ERROR, "ProcessIPPRequest: missing attributes-charset attribute!");
+
+ if (language == NULL)
+ LogMessage(L_ERROR, "ProcessIPPRequest: missing attributes-natural-language attribute!");
+
+ if (uri == NULL)
+ LogMessage(L_ERROR, "ProcessIPPRequest: missing printer-uri or job-uri attribute!");
+
+ LogMessage(L_DEBUG, "Request attributes follow...");
+
+ for (attr = con->request->attrs; attr != NULL; attr = attr->next)
+ LogMessage(L_DEBUG, "attr \"%s\": group_tag = %x, value_tag = %x",
+ attr->name ? attr->name : "(null)", attr->group_tag,
+ attr->value_tag);
+
+ LogMessage(L_DEBUG, "End of attributes...");
+
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ }
+ else
+ {
+ /*
+ * OK, all the checks pass so far; make sure requesting-user-name is
+ * not "root" from a remote host...
+ */
+
+ if ((username = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME)) != NULL)
+ {
+ /*
+ * Check for root user...
+ */
+
+ if (strcmp(username->values[0].string.text, "root") == 0 &&
+ ntohl(con->http.hostaddr.sin_addr.s_addr) != 0x7f000001 &&
+ strcmp(con->username, "root") != 0)
+ {
+ /*
+ * Remote unauthenticated user masquerading as local root...
+ */
+
+ free(username->values[0].string.text);
+ username->values[0].string.text = strdup(RemoteRoot);
+ }
+ }
+
+ /*
+ * Then try processing the operation...
+ */
+
+ switch (con->request->request.op.operation_id)
+ {
+ case IPP_PRINT_JOB :
+ print_job(con, uri);
+ break;
+
+ case IPP_VALIDATE_JOB :
+ validate_job(con, uri);
+ break;
+
+ case IPP_CREATE_JOB :
+ create_job(con, uri);
+ break;
+
+ case IPP_SEND_DOCUMENT :
+ send_document(con, uri);
+ break;
+
+ case IPP_CANCEL_JOB :
+ cancel_job(con, uri);
+ break;
+
+ case IPP_GET_JOB_ATTRIBUTES :
+ get_job_attrs(con, uri);
+ break;
+
+ case IPP_GET_JOBS :
+ get_jobs(con, uri);
+ break;
+
+ case IPP_GET_PRINTER_ATTRIBUTES :
+ get_printer_attrs(con, uri);
+ break;
+
+ case IPP_HOLD_JOB :
+ hold_job(con, uri);
+ break;
+
+ case IPP_RELEASE_JOB :
+ release_job(con, uri);
+ break;
+
+ case IPP_RESTART_JOB :
+ restart_job(con, uri);
+ break;
+
+ case IPP_PAUSE_PRINTER :
+ stop_printer(con, uri);
+ break;
+
+ case IPP_RESUME_PRINTER :
+ start_printer(con, uri);
+ break;
+
+ case IPP_PURGE_JOBS :
+ cancel_all_jobs(con, uri);
+ break;
+
+ case IPP_SET_JOB_ATTRIBUTES :
+ set_job_attrs(con, uri);
+ break;
+
+ case CUPS_GET_DEFAULT :
+ get_default(con);
+ break;
+
+ case CUPS_GET_PRINTERS :
+ get_printers(con, 0);
+ break;
+
+ case CUPS_GET_CLASSES :
+ get_printers(con, CUPS_PRINTER_CLASS);
+ break;
+
+ case CUPS_ADD_PRINTER :
+ add_printer(con, uri);
+ break;
+
+ case CUPS_DELETE_PRINTER :
+ delete_printer(con, uri);
+ break;
+
+ case CUPS_ADD_CLASS :
+ add_class(con, uri);
+ break;
+
+ case CUPS_DELETE_CLASS :
+ delete_printer(con, uri);
+ break;
+
+ case CUPS_ACCEPT_JOBS :
+ case IPP_ENABLE_PRINTER :
+ accept_jobs(con, uri);
+ break;
+
+ case CUPS_REJECT_JOBS :
+ case IPP_DISABLE_PRINTER :
+ reject_jobs(con, uri);
+ break;
+
+ case CUPS_SET_DEFAULT :
+ set_default(con, uri);
+ break;
+
+ case CUPS_GET_DEVICES :
+ get_devices(con);
+ break;
+
+ case CUPS_GET_PPDS :
+ get_ppds(con);
+ break;
+
+ case CUPS_MOVE_JOB :
+ move_job(con, uri);
+ break;
+
+ default :
+ send_ipp_error(con, IPP_OPERATION_NOT_SUPPORTED);
+ }
+ }
+ }
+ }
+
+ SendHeader(con, HTTP_OK, "application/ipp");
+
+ con->http.data_encoding = HTTP_ENCODE_LENGTH;
+ con->http.data_remaining = ippLength(con->response);
+
+ httpPrintf(HTTP(con), "Content-Length: %d\r\n\r\n",
+ con->http.data_remaining);
+
+ FD_SET(con->http.fd, &OutputSet);
+}
+
+
+/*
+ * 'accept_jobs()' - Accept print jobs to a printer.
+ */
+
+static void
+accept_jobs(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer or class URI */
+{
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ const char *name; /* Printer name */
+ printer_t *printer; /* Printer data */
+
+
+ LogMessage(L_DEBUG2, "accept_jobs(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ LogMessage(L_ERROR, "accept_jobs: admin request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((name = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "accept_jobs: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Accept jobs sent to the printer...
+ */
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ printer = FindClass(name);
+ else
+ printer = FindPrinter(name);
+
+ printer->accepting = 1;
+ printer->state_message[0] = '\0';
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ SaveAllClasses();
+ else
+ SaveAllPrinters();
+
+ LogMessage(L_INFO, "Printer \'%s\' now accepting jobs (\'%s\').", name,
+ con->username);
+
+ /*
+ * Everything was ok, so return OK status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'add_class()' - Add a class to the system.
+ */
+
+static void
+add_class(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - URI of class */
+{
+ int i; /* Looping var */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ printer_t *pclass; /* Class */
+ cups_ptype_t dtype; /* Destination type */
+ const char *dest; /* Printer or class name */
+ ipp_attribute_t *attr; /* Printer attribute */
+ int modify; /* Non-zero if we just modified */
+
+
+ LogMessage(L_DEBUG2, "add_class(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ LogMessage(L_ERROR, "add_class: admin request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Do we have a valid URI?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (strncmp(resource, "/classes/", 9) != 0 || strlen(resource) == 9)
+ {
+ /*
+ * No, return an error...
+ */
+
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ /*
+ * See if the class already exists; if not, create a new class...
+ */
+
+ if ((pclass = FindClass(resource + 9)) == NULL)
+ {
+ /*
+ * Class doesn't exist; see if we have a printer of the same name...
+ */
+
+ if ((pclass = FindPrinter(resource + 9)) != NULL &&
+ !(pclass->type & CUPS_PRINTER_REMOTE))
+ {
+ /*
+ * Yes, return an error...
+ */
+
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ /*
+ * No, add the pclass...
+ */
+
+ pclass = AddClass(resource + 9);
+ modify = 0;
+ }
+ else if (pclass->type & CUPS_PRINTER_IMPLICIT)
+ {
+ /*
+ * Rename the implicit class to "AnyClass" or remove it...
+ */
+
+ if (ImplicitAnyClasses)
+ {
+ snprintf(pclass->name, sizeof(pclass->name), "Any%s", resource + 9);
+ SortPrinters();
+ }
+ else
+ DeletePrinter(pclass);
+
+ /*
+ * Add the class as a new local class...
+ */
+
+ pclass = AddClass(resource + 9);
+ modify = 0;
+ }
+ else if (pclass->type & CUPS_PRINTER_REMOTE)
+ {
+ /*
+ * Rename the remote class to "Class"...
+ */
+
+ DeletePrinterFilters(pclass);
+ snprintf(pclass->name, sizeof(pclass->name), "%s@%s", resource + 9,
+ pclass->hostname);
+ SetPrinterAttrs(pclass);
+ SortPrinters();
+
+ /*
+ * Add the class as a new local class...
+ */
+
+ pclass = AddClass(resource + 9);
+ modify = 0;
+ }
+ else
+ modify = 1;
+
+ /*
+ * Look for attributes and copy them over as needed...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "printer-location", IPP_TAG_TEXT)) != NULL)
+ strlcpy(pclass->location, attr->values[0].string.text, sizeof(pclass->location));
+
+ if ((attr = ippFindAttribute(con->request, "printer-info", IPP_TAG_TEXT)) != NULL)
+ strlcpy(pclass->info, attr->values[0].string.text, sizeof(pclass->info));
+
+ if ((attr = ippFindAttribute(con->request, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN)) != NULL)
+ {
+ LogMessage(L_INFO, "Setting %s printer-is-accepting-jobs to %d (was %d.)",
+ pclass->name, attr->values[0].boolean, pclass->accepting);
+
+ pclass->accepting = attr->values[0].boolean;
+ }
+ if ((attr = ippFindAttribute(con->request, "printer-state", IPP_TAG_ENUM)) != NULL)
+ {
+ LogMessage(L_INFO, "Setting %s printer-state to %d (was %d.)", pclass->name,
+ attr->values[0].integer, pclass->state);
+
+ if (pclass->state == IPP_PRINTER_STOPPED &&
+ attr->values[0].integer != IPP_PRINTER_STOPPED)
+ pclass->state = IPP_PRINTER_IDLE;
+ else if (pclass->state != IPP_PRINTER_STOPPED &&
+ attr->values[0].integer == IPP_PRINTER_STOPPED)
+ {
+ if (pclass->state == IPP_PRINTER_PROCESSING)
+ StopJob(((job_t *)pclass->job)->id, 0);
+
+ pclass->state = IPP_PRINTER_STOPPED;
+ }
+
+ pclass->browse_time = 0;
+ }
+ if ((attr = ippFindAttribute(con->request, "printer-state-message", IPP_TAG_TEXT)) != NULL)
+ strlcpy(pclass->state_message, attr->values[0].string.text,
+ sizeof(pclass->state_message));
+ if ((attr = ippFindAttribute(con->request, "job-sheets-default", IPP_TAG_ZERO)) != NULL &&
+ !Classification[0])
+ {
+ strlcpy(pclass->job_sheets[0], attr->values[0].string.text,
+ sizeof(pclass->job_sheets[0]));
+ if (attr->num_values > 1)
+ strlcpy(pclass->job_sheets[1], attr->values[1].string.text,
+ sizeof(pclass->job_sheets[1]));
+ else
+ strcpy(pclass->job_sheets[1], "none");
+ }
+ if ((attr = ippFindAttribute(con->request, "requesting-user-name-allowed",
+ IPP_TAG_ZERO)) != NULL)
+ {
+ FreePrinterUsers(pclass);
+
+ pclass->deny_users = 0;
+ if (attr->value_tag == IPP_TAG_NAME &&
+ (attr->num_values > 1 ||
+ strcmp(attr->values[0].string.text, "all") != 0))
+ for (i = 0; i < attr->num_values; i ++)
+ AddPrinterUser(pclass, attr->values[i].string.text);
+ }
+ else if ((attr = ippFindAttribute(con->request, "requesting-user-name-denied",
+ IPP_TAG_ZERO)) != NULL)
+ {
+ FreePrinterUsers(pclass);
+
+ pclass->deny_users = 1;
+ if (attr->value_tag == IPP_TAG_NAME &&
+ (attr->num_values > 1 ||
+ strcmp(attr->values[0].string.text, "none") != 0))
+ for (i = 0; i < attr->num_values; i ++)
+ AddPrinterUser(pclass, attr->values[i].string.text);
+ }
+ if ((attr = ippFindAttribute(con->request, "job-quota-period",
+ IPP_TAG_INTEGER)) != NULL)
+ {
+ FreeQuotas(pclass);
+ pclass->quota_period = attr->values[0].integer;
+ }
+ if ((attr = ippFindAttribute(con->request, "job-k-limit",
+ IPP_TAG_INTEGER)) != NULL)
+ {
+ FreeQuotas(pclass);
+ pclass->k_limit = attr->values[0].integer;
+ }
+ if ((attr = ippFindAttribute(con->request, "job-page-limit",
+ IPP_TAG_INTEGER)) != NULL)
+ {
+ FreeQuotas(pclass);
+ pclass->page_limit = attr->values[0].integer;
+ }
+
+ if ((attr = ippFindAttribute(con->request, "member-uris", IPP_TAG_URI)) != NULL)
+ {
+ /*
+ * Clear the printer array as needed...
+ */
+
+ if (pclass->num_printers > 0)
+ {
+ free(pclass->printers);
+ pclass->num_printers = 0;
+ }
+
+ /*
+ * Add each printer or class that is listed...
+ */
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ /*
+ * Search for the printer or class URI...
+ */
+
+ httpSeparate(attr->values[i].string.text, method, username, host,
+ &port, resource);
+
+ if ((dest = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "add_class: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Add it to the class...
+ */
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ {
+ AddPrinterToClass(pclass, FindClass(dest));
+
+ LogMessage(L_DEBUG, "add_class: Added class \"%s\" to class \"%s\"...",
+ dest, pclass->name);
+ }
+ else
+ {
+ AddPrinterToClass(pclass, FindPrinter(dest));
+
+ LogMessage(L_DEBUG, "add_class: Added printer \"%s\" to class \"%s\"...",
+ dest, pclass->name);
+ }
+ }
+ }
+
+ /*
+ * Update the printer class attributes and return...
+ */
+
+ SetPrinterAttrs(pclass);
+ SaveAllClasses();
+ CheckJobs();
+
+ WritePrintcap();
+
+ if (modify)
+ LogMessage(L_INFO, "Class \'%s\' modified by \'%s\'.", pclass->name,
+ con->username);
+ else
+ LogMessage(L_INFO, "New class \'%s\' added by \'%s\'.", pclass->name,
+ con->username);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'add_file()' - Add a file to a job.
+ */
+
+static int /* O - 0 on success, -1 on error */
+add_file(client_t *con, /* I - Connection to client */
+ job_t *job, /* I - Job to add to */
+ mime_type_t *filetype) /* I - Type of file */
+{
+ mime_type_t **filetypes; /* New filetypes array... */
+
+
+ LogMessage(L_DEBUG2, "add_file(%p[%d], %d, %s/%s)\n", con, con->http.fd,
+ job->id, filetype->super, filetype->type);
+
+ /*
+ * Add the file to the job...
+ */
+
+ if (job->num_files == 0)
+ filetypes = (mime_type_t **)malloc(sizeof(mime_type_t *));
+ else
+ filetypes = (mime_type_t **)realloc(job->filetypes,
+ (job->num_files + 1) *
+ sizeof(mime_type_t));
+
+ if (filetypes == NULL)
+ {
+ CancelJob(job->id, 1);
+ LogMessage(L_ERROR, "add_file: unable to allocate memory for file types!");
+ send_ipp_error(con, IPP_INTERNAL_ERROR);
+ return (-1);
+ }
+
+ job->filetypes = filetypes;
+ job->filetypes[job->num_files] = filetype;
+
+ job->num_files ++;
+
+ return (0);
+}
+
+
+/*
+ * 'add_job_state_reasons()' - Add the "job-state-reasons" attribute based
+ * upon the job and printer state...
+ */
+
+static void
+add_job_state_reasons(client_t *con, /* I - Client connection */
+ job_t *job) /* I - Job info */
+{
+ printer_t *dest; /* Destination printer */
+
+
+ LogMessage(L_DEBUG2, "add_job_state_reasons(%p[%d], %d)\n", con, con->http.fd,
+ job->id);
+
+ switch (job->state->values[0].integer)
+ {
+ case IPP_JOB_PENDING :
+ if (job->dtype & CUPS_PRINTER_CLASS)
+ dest = FindClass(job->dest);
+ else
+ dest = FindPrinter(job->dest);
+
+ if (dest != NULL && dest->state == IPP_PRINTER_STOPPED)
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-state-reasons", NULL, "printer-stopped");
+ else
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-state-reasons", NULL, "none");
+ break;
+
+ case IPP_JOB_HELD :
+ if (ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD) != NULL ||
+ ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME) != NULL)
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-state-reasons", NULL, "job-hold-until-specified");
+ else
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-state-reasons", NULL, "job-incoming");
+ break;
+
+ case IPP_JOB_PROCESSING :
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-state-reasons", NULL, "job-printing");
+ break;
+
+ case IPP_JOB_STOPPED :
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-state-reasons", NULL, "job-stopped");
+ break;
+
+ case IPP_JOB_CANCELLED :
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-state-reasons", NULL, "job-canceled-by-user");
+ break;
+
+ case IPP_JOB_ABORTED :
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-state-reasons", NULL, "aborted-by-system");
+ break;
+
+ case IPP_JOB_COMPLETED :
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-state-reasons", NULL, "job-completed-successfully");
+ break;
+ }
+}
+
+
+/*
+ * 'add_printer()' - Add a printer to the system.
+ */
+
+static void
+add_printer(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - URI of printer */
+{
+ int i; /* Looping var */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ printer_t *printer; /* Printer/class */
+ ipp_attribute_t *attr; /* Printer attribute */
+#ifdef HAVE_LIBZ
+ gzFile fp; /* Script/PPD file */
+#else
+ FILE *fp; /* Script/PPD file */
+#endif /* HAVE_LIBZ */
+ char line[1024]; /* Line from file... */
+ char srcfile[1024], /* Source Script/PPD file */
+ dstfile[1024]; /* Destination Script/PPD file */
+ int modify; /* Non-zero if we are modifying */
+
+
+ LogMessage(L_DEBUG2, "add_printer(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ LogMessage(L_ERROR, "add_printer: admin request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Do we have a valid URI?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (strncmp(resource, "/printers/", 10) != 0 || strlen(resource) == 10)
+ {
+ /*
+ * No, return an error...
+ */
+
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ /*
+ * See if the printer already exists; if not, create a new printer...
+ */
+
+ if ((printer = FindPrinter(resource + 10)) == NULL)
+ {
+ /*
+ * Printer doesn't exist; see if we have a class of the same name...
+ */
+
+ if ((printer = FindClass(resource + 10)) != NULL &&
+ !(printer->type & CUPS_PRINTER_REMOTE))
+ {
+ /*
+ * Yes, return an error...
+ */
+
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ /*
+ * No, add the printer...
+ */
+
+ printer = AddPrinter(resource + 10);
+ modify = 0;
+ }
+ else if (printer->type & CUPS_PRINTER_IMPLICIT)
+ {
+ /*
+ * Rename the implicit printer to "AnyPrinter" or delete it...
+ */
+
+ if (ImplicitAnyClasses)
+ {
+ snprintf(printer->name, sizeof(printer->name), "Any%s", resource + 10);
+ SortPrinters();
+ }
+ else
+ DeletePrinter(printer);
+
+ /*
+ * Add the printer as a new local printer...
+ */
+
+ printer = AddPrinter(resource + 10);
+ modify = 0;
+ }
+ else if (printer->type & CUPS_PRINTER_REMOTE)
+ {
+ /*
+ * Rename the remote printer to "Printer@server"...
+ */
+
+ DeletePrinterFilters(printer);
+ snprintf(printer->name, sizeof(printer->name), "%s@%s", resource + 10,
+ printer->hostname);
+ SetPrinterAttrs(printer);
+ SortPrinters();
+
+ /*
+ * Add the printer as a new local printer...
+ */
+
+ printer = AddPrinter(resource + 10);
+ modify = 0;
+ }
+ else
+ modify = 1;
+
+ /*
+ * Look for attributes and copy them over as needed...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "printer-location", IPP_TAG_TEXT)) != NULL)
+ strlcpy(printer->location, attr->values[0].string.text,
+ sizeof(printer->location));
+
+ if ((attr = ippFindAttribute(con->request, "printer-info", IPP_TAG_TEXT)) != NULL)
+ strlcpy(printer->info, attr->values[0].string.text,
+ sizeof(printer->info));
+
+ if ((attr = ippFindAttribute(con->request, "device-uri", IPP_TAG_URI)) != NULL)
+ {
+ ipp_attribute_t *device; /* Current device */
+ int methodlen; /* Length of method string */
+
+
+ /*
+ * Do we have a valid device URI?
+ */
+
+ httpSeparate(attr->values[0].string.text, method, username, host,
+ &port, resource);
+ methodlen = strlen(method);
+
+ if (strcmp(method, "file") != 0)
+ {
+ /*
+ * See if the backend is listed as a device...
+ */
+
+ for (device = ippFindAttribute(Devices, "device-uri", IPP_TAG_URI);
+ device != NULL;
+ device = ippFindNextAttribute(Devices, "device-uri", IPP_TAG_URI))
+ if (strncmp(method, device->values[0].string.text, methodlen) == 0 &&
+ (device->values[0].string.text[methodlen] == ':' ||
+ device->values[0].string.text[methodlen] == '\0'))
+ break;
+
+ if (device == NULL)
+ {
+ /*
+ * Could not find device in list!
+ */
+
+ LogMessage(L_ERROR, "add_printer: bad device-uri attribute \'%s\'!",
+ attr->values[0].string.text);
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+ }
+
+ LogMessage(L_INFO, "Setting %s device-uri to \"%s\" (was \"%s\".)",
+ printer->name, attr->values[0].string.text, printer->device_uri);
+
+ strlcpy(printer->device_uri, attr->values[0].string.text,
+ sizeof(printer->device_uri));
+ }
+
+ if ((attr = ippFindAttribute(con->request, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN)) != NULL)
+ {
+ LogMessage(L_INFO, "Setting %s printer-is-accepting-jobs to %d (was %d.)",
+ printer->name, attr->values[0].boolean, printer->accepting);
+
+ printer->accepting = attr->values[0].boolean;
+ }
+ if ((attr = ippFindAttribute(con->request, "printer-state", IPP_TAG_ENUM)) != NULL)
+ {
+ LogMessage(L_INFO, "Setting %s printer-state to %d (was %d.)", printer->name,
+ attr->values[0].integer, printer->state);
+
+ if (printer->state == IPP_PRINTER_STOPPED &&
+ attr->values[0].integer != IPP_PRINTER_STOPPED)
+ printer->state = IPP_PRINTER_IDLE;
+ else if (printer->state != IPP_PRINTER_STOPPED &&
+ attr->values[0].integer == IPP_PRINTER_STOPPED)
+ {
+ if (printer->state == IPP_PRINTER_PROCESSING)
+ StopJob(((job_t *)printer->job)->id, 0);
+
+ printer->state = IPP_PRINTER_STOPPED;
+ }
+
+ printer->browse_time = 0;
+ }
+ if ((attr = ippFindAttribute(con->request, "printer-state-message", IPP_TAG_TEXT)) != NULL)
+ strlcpy(printer->state_message, attr->values[0].string.text,
+ sizeof(printer->state_message));
+ if ((attr = ippFindAttribute(con->request, "job-sheets-default", IPP_TAG_ZERO)) != NULL &&
+ !Classification[0])
+ {
+ strlcpy(printer->job_sheets[0], attr->values[0].string.text,
+ sizeof(printer->job_sheets[0]));
+ if (attr->num_values > 1)
+ strlcpy(printer->job_sheets[1], attr->values[1].string.text,
+ sizeof(printer->job_sheets[1]));
+ else
+ strcpy(printer->job_sheets[1], "none");
+ }
+ if ((attr = ippFindAttribute(con->request, "requesting-user-name-allowed",
+ IPP_TAG_ZERO)) != NULL)
+ {
+ FreePrinterUsers(printer);
+
+ printer->deny_users = 0;
+ if (attr->value_tag == IPP_TAG_NAME &&
+ (attr->num_values > 1 ||
+ strcmp(attr->values[0].string.text, "all") != 0))
+ for (i = 0; i < attr->num_values; i ++)
+ AddPrinterUser(printer, attr->values[i].string.text);
+ }
+ else if ((attr = ippFindAttribute(con->request, "requesting-user-name-denied",
+ IPP_TAG_ZERO)) != NULL)
+ {
+ FreePrinterUsers(printer);
+
+ printer->deny_users = 1;
+ if (attr->value_tag == IPP_TAG_NAME &&
+ (attr->num_values > 1 ||
+ strcmp(attr->values[0].string.text, "none") != 0))
+ for (i = 0; i < attr->num_values; i ++)
+ AddPrinterUser(printer, attr->values[i].string.text);
+ }
+ if ((attr = ippFindAttribute(con->request, "job-quota-period",
+ IPP_TAG_INTEGER)) != NULL)
+ {
+ FreeQuotas(printer);
+ printer->quota_period = attr->values[0].integer;
+ }
+ if ((attr = ippFindAttribute(con->request, "job-k-limit",
+ IPP_TAG_INTEGER)) != NULL)
+ {
+ FreeQuotas(printer);
+ printer->k_limit = attr->values[0].integer;
+ }
+ if ((attr = ippFindAttribute(con->request, "job-page-limit",
+ IPP_TAG_INTEGER)) != NULL)
+ {
+ FreeQuotas(printer);
+ printer->page_limit = attr->values[0].integer;
+ }
+
+ /*
+ * See if we have all required attributes...
+ */
+
+ if (printer->device_uri[0] == '\0')
+ strcpy(printer->device_uri, "file:/dev/null");
+
+ /*
+ * See if we have an interface script or PPD file attached to the request...
+ */
+
+ if (con->filename[0])
+ strlcpy(srcfile, con->filename, sizeof(srcfile));
+ else if ((attr = ippFindAttribute(con->request, "ppd-name", IPP_TAG_NAME)) != NULL)
+ {
+ if (strcmp(attr->values[0].string.text, "raw") == 0)
+ strcpy(srcfile, "raw");
+ else
+ snprintf(srcfile, sizeof(srcfile), "%s/model/%s", DataDir,
+ attr->values[0].string.text);
+ }
+ else
+ srcfile[0] = '\0';
+
+ LogMessage(L_DEBUG, "add_printer: srcfile = \"%s\"", srcfile);
+
+ if (strcmp(srcfile, "raw") == 0)
+ {
+ /*
+ * Raw driver, remove any existing PPD or interface script files.
+ */
+
+ snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot,
+ printer->name);
+ unlink(dstfile);
+
+ snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
+ printer->name);
+ unlink(dstfile);
+ }
+#ifdef HAVE_LIBZ
+ else if (srcfile[0] && (fp = gzopen(srcfile, "rb")) != NULL)
+#else
+ else if (srcfile[0] && (fp = fopen(srcfile, "rb")) != NULL)
+#endif /* HAVE_LIBZ */
+ {
+ /*
+ * Yes; get the first line from it...
+ */
+
+ line[0] = '\0';
+#ifdef HAVE_LIBZ
+ gzgets(fp, line, sizeof(line));
+ gzclose(fp);
+#else
+ fgets(line, sizeof(line), fp);
+ fclose(fp);
+#endif /* HAVE_LIBZ */
+
+ /*
+ * Then see what kind of file it is...
+ */
+
+ snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot,
+ printer->name);
+
+ if (strncmp(line, "*PPD-Adobe", 10) == 0)
+ {
+ /*
+ * The new file is a PPD file, so remove any old interface script
+ * that might be lying around...
+ */
+
+ unlink(dstfile);
+ }
+ else
+ {
+ /*
+ * This must be an interface script, so move the file over to the
+ * interfaces directory and make it executable...
+ */
+
+ if (copy_file(srcfile, dstfile))
+ {
+ LogMessage(L_ERROR, "add_printer: Unable to copy interface script from %s to %s - %s!",
+ srcfile, dstfile, strerror(errno));
+ send_ipp_error(con, IPP_INTERNAL_ERROR);
+ return;
+ }
+ else
+ {
+ LogMessage(L_DEBUG, "add_printer: Copied interface script successfully!");
+ chmod(dstfile, 0755);
+ }
+ }
+
+ snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
+ printer->name);
+
+ if (strncmp(line, "*PPD-Adobe", 10) == 0)
+ {
+ /*
+ * The new file is a PPD file, so move the file over to the
+ * ppd directory and make it readable by all...
+ */
+
+ if (copy_file(srcfile, dstfile))
+ {
+ LogMessage(L_ERROR, "add_printer: Unable to copy PPD file from %s to %s - %s!",
+ srcfile, dstfile, strerror(errno));
+ send_ipp_error(con, IPP_INTERNAL_ERROR);
+ return;
+ }
+ else
+ {
+ LogMessage(L_DEBUG, "add_printer: Copied PPD file successfully!");
+ chmod(dstfile, 0644);
+ }
+ }
+ else
+ {
+ /*
+ * This must be an interface script, so remove any old PPD file that
+ * may be lying around...
+ */
+
+ unlink(dstfile);
+ }
+ }
+
+ /*
+ * Make this printer the default if there is none...
+ */
+
+ if (DefaultPrinter == NULL)
+ DefaultPrinter = printer;
+
+ /*
+ * Update the printer attributes and return...
+ */
+
+ SetPrinterAttrs(printer);
+ SaveAllPrinters();
+
+ if (printer->job != NULL)
+ {
+ job_t *job;
+
+ /*
+ * Stop the current job and then restart it below...
+ */
+
+ job = (job_t *)printer->job;
+
+ StopJob(job->id, 1);
+ job->state->values[0].integer = IPP_JOB_PENDING;
+ }
+
+ CheckJobs();
+
+ WritePrintcap();
+
+ if (modify)
+ LogMessage(L_INFO, "Printer \'%s\' modified by \'%s\'.", printer->name,
+ con->username);
+ else
+ LogMessage(L_INFO, "New printer \'%s\' added by \'%s\'.", printer->name,
+ con->username);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'add_printer_state_reasons()' - Add the "printer-state-reasons" attribute
+ * based upon the printer state...
+ */
+
+static void
+add_printer_state_reasons(client_t *con, /* I - Client connection */
+ printer_t *p) /* I - Printer info */
+{
+ LogMessage(L_DEBUG2, "add_printer_state_reasons(%p[%d], %p[%s])\n",
+ con, con->http.fd, p, p->name);
+
+ switch (p->state)
+ {
+ case IPP_PRINTER_STOPPED :
+ ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-state-reasons", NULL, "paused");
+ break;
+
+ default :
+ ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-state-reasons", NULL, "none");
+ break;
+ }
+}
+
+
+/*
+ * 'add_queued_job_count()' - Add the "queued-job-count" attribute for
+ * the specified printer or class.
+ */
+
+static void
+add_queued_job_count(client_t *con, /* I - Client connection */
+ printer_t *p) /* I - Printer or class */
+{
+ int count; /* Number of jobs on destination */
+
+
+ LogMessage(L_DEBUG2, "add_queued_job_count(%p[%d], %p[%s])\n",
+ con, con->http.fd, p, p->name);
+
+ count = GetPrinterJobCount(p->name);
+
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "queued-job-count", count);
+}
+
+
+/*
+ * 'cancel_all_jobs()' - Cancel all print jobs.
+ */
+
+static void
+cancel_all_jobs(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Job or Printer URI */
+{
+ const char *dest; /* Destination */
+ cups_ptype_t dtype; /* Destination type */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ printer_t *printer; /* Current printer */
+
+
+ LogMessage(L_DEBUG2, "cancel_all_jobs(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ LogMessage(L_ERROR, "cancel_all_jobs: admin request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * See if we have a printer URI...
+ */
+
+ if (strcmp(uri->name, "printer-uri") != 0)
+ {
+ LogMessage(L_ERROR, "cancel_all_jobs: bad %s attribute \'%s\'!",
+ uri->name, uri->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ /*
+ * And if the destination is valid...
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port,
+ resource);
+
+ if ((dest = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI?
+ */
+
+ if (strcmp(resource, "/printers/") != 0)
+ {
+ LogMessage(L_ERROR, "cancel_all_jobs: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Cancel all jobs on all printers...
+ */
+
+ for (printer = Printers; printer; printer = printer->next)
+ {
+ CancelJobs(printer->name);
+ LogMessage(L_INFO, "All jobs on \'%s\' were cancelled by \'%s\'.",
+ printer->name, con->username);
+ }
+ }
+ else
+ {
+ /*
+ * Cancel all of the jobs on the named printer...
+ */
+
+ CancelJobs(dest);
+ LogMessage(L_INFO, "All jobs on \'%s\' were cancelled by \'%s\'.", dest,
+ con->username);
+ }
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'cancel_job()' - Cancel a print job.
+ */
+
+static void
+cancel_job(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Job or Printer URI */
+{
+ ipp_attribute_t *attr; /* Current attribute */
+ int jobid; /* Job ID */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ job_t *job; /* Job information */
+ const char *dest; /* Destination */
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ printer_t *printer; /* Printer data */
+
+
+ LogMessage(L_DEBUG2, "cancel_job(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Verify that the POST operation was done to a valid URI.
+ */
+
+ if (strncmp(con->uri, "/classes/", 9) != 0 &&
+ strncmp(con->uri, "/jobs/", 5) != 0 &&
+ strncmp(con->uri, "/printers/", 10) != 0)
+ {
+ LogMessage(L_ERROR, "cancel_job: cancel request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * See if we have a job URI or a printer URI...
+ */
+
+ if (strcmp(uri->name, "printer-uri") == 0)
+ {
+ /*
+ * Got a printer URI; see if we also have a job-id attribute...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "job-id", IPP_TAG_INTEGER)) == NULL)
+ {
+ LogMessage(L_ERROR, "cancel_job: got a printer-uri attribute but no job-id!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ if ((jobid = attr->values[0].integer) == 0)
+ {
+ /*
+ * Find the current job on the specified printer...
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((dest = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "cancel_job: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ printer = FindClass(dest);
+ else
+ printer = FindPrinter(dest);
+
+ /*
+ * See if the printer is currently printing a job...
+ */
+
+ if (printer->job)
+ jobid = ((job_t *)printer->job)->id;
+ else
+ {
+ /*
+ * No, see if there are any pending jobs...
+ */
+
+ for (job = Jobs; job != NULL; job = job->next)
+ if (job->state->values[0].integer <= IPP_JOB_PROCESSING &&
+ strcasecmp(job->dest, dest) == 0)
+ break;
+
+ if (job != NULL)
+ jobid = job->id;
+ else
+ {
+ LogMessage(L_ERROR, "cancel_job: No active jobs on %s!", dest);
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Got a job URI; parse it to get the job ID...
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (strncmp(resource, "/jobs/", 6) != 0)
+ {
+ /*
+ * Not a valid URI!
+ */
+
+ LogMessage(L_ERROR, "cancel_job: bad job-uri attribute \'%s\'!",
+ uri->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = atoi(resource + 6);
+ }
+
+ /*
+ * See if the job exists...
+ */
+
+ if ((job = FindJob(jobid)) == NULL)
+ {
+ /*
+ * Nope - return a "not found" error...
+ */
+
+ LogMessage(L_ERROR, "cancel_job: job #%d doesn't exist!", jobid);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * See if the job is owned by the requesting user...
+ */
+
+ if (!validate_user(con, job->username, username, sizeof(username)))
+ {
+ LogMessage(L_ERROR, "cancel_job: \"%s\" not authorized to delete job id %d owned by \"%s\"!",
+ username, jobid, job->username);
+ send_ipp_error(con, IPP_FORBIDDEN);
+ return;
+ }
+
+ /*
+ * See if the job is already completed, cancelled, or aborted; if so,
+ * we can't cancel...
+ */
+
+ if (job->state->values[0].integer >= IPP_JOB_CANCELLED)
+ {
+ LogMessage(L_ERROR, "cancel_job: job id %d is %s - can't cancel!",
+ jobid,
+ job->state->values[0].integer == IPP_JOB_CANCELLED ? "cancelled" :
+ job->state->values[0].integer == IPP_JOB_ABORTED ? "aborted" :
+ "completed");
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ /*
+ * Cancel the job and return...
+ */
+
+ CancelJob(jobid, 0);
+ CheckJobs();
+
+ LogMessage(L_INFO, "Job %d was cancelled by \'%s\'.", jobid, username);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'check_quotas()' - Check quotas for a printer and user.
+ */
+
+static int /* O - 1 if OK, 0 if not */
+check_quotas(client_t *con, /* I - Client connection */
+ printer_t *p) /* I - Printer or class */
+{
+ int i; /* Looping var */
+ ipp_attribute_t *attr; /* Current attribute */
+ char username[33]; /* Username */
+ quota_t *q; /* Quota data */
+
+
+ LogMessage(L_DEBUG2, "check_quotas(%p[%d], %p[%s])\n",
+ con, con->http.fd, p, p->name);
+
+ /*
+ * Check input...
+ */
+
+ if (con == NULL || p == NULL)
+ return (0);
+
+ /*
+ * Figure out who is printing...
+ */
+
+ attr = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME);
+
+ if (con->username[0])
+ strlcpy(username, con->username, sizeof(username));
+ else if (attr != NULL)
+ {
+ LogMessage(L_DEBUG, "check_quotas: requesting-user-name = \'%s\'",
+ attr->values[0].string.text);
+
+ strlcpy(username, attr->values[0].string.text, sizeof(username));
+ }
+ else
+ strcpy(username, "anonymous");
+
+ /*
+ * Check global active job limits for printers and users...
+ */
+
+ if (MaxJobsPerPrinter)
+ {
+ /*
+ * Check if there are too many pending jobs on this printer...
+ */
+
+ if (GetPrinterJobCount(p->name) >= MaxJobsPerPrinter)
+ {
+ LogMessage(L_INFO, "Too many jobs for printer \"%s\"...", p->name);
+ return (0);
+ }
+ }
+
+ if (MaxJobsPerUser)
+ {
+ /*
+ * Check if there are too many pending jobs for this user...
+ */
+
+ if (GetUserJobCount(username) >= MaxJobsPerUser)
+ {
+ LogMessage(L_INFO, "Too many jobs for user \"%s\"...", username);
+ return (0);
+ }
+ }
+
+ /*
+ * Check against users...
+ */
+
+ if (p->num_users == 0 && p->k_limit == 0 && p->page_limit == 0)
+ return (1);
+
+ if (p->num_users)
+ {
+ for (i = 0; i < p->num_users; i ++)
+ if (strcasecmp(username, p->users[i]) == 0)
+ break;
+
+ if ((i < p->num_users) == p->deny_users)
+ {
+ LogMessage(L_INFO, "Denying user \"%s\" access to printer \"%s\"...",
+ username, p->name);
+ return (0);
+ }
+ }
+
+ /*
+ * Check quotas...
+ */
+
+ if (p->k_limit || p->page_limit)
+ {
+ if ((q = UpdateQuota(p, username, 0, 0)) == NULL)
+ {
+ LogMessage(L_ERROR, "Unable to allocate quota data for user \"%s\"!",
+ username);
+ return (0);
+ }
+
+ if ((q->k_count >= p->k_limit && p->k_limit) ||
+ (q->page_count >= p->page_limit && p->page_limit))
+ {
+ LogMessage(L_INFO, "User \"%s\" is over the quota limit...",
+ username);
+ return (0);
+ }
+ }
+
+ /*
+ * If we have gotten this far, we're done!
+ */
+
+ return (1);
+}
+
+
+/*
+ * 'copy_attribute()' - Copy a single attribute.
+ */
+
+static void
+copy_attribute(ipp_t *to, /* O - Destination request/response */
+ ipp_attribute_t *attr, /* I - Attribute to copy */
+ int quickcopy)/* I - Do a quick copy? */
+{
+ int i; /* Looping var */
+ ipp_attribute_t *toattr; /* Destination attribute */
+
+
+ LogMessage(L_DEBUG2, "copy_attribute(%p, %p[%s,%x,%x])\n", to, attr,
+ attr->name ? attr->name : "(null)", attr->group_tag,
+ attr->value_tag);
+
+ switch (attr->value_tag & ~IPP_TAG_COPY)
+ {
+ case IPP_TAG_ZERO :
+ ippAddSeparator(to);
+ break;
+
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag,
+ attr->name, attr->num_values, NULL);
+
+ for (i = 0; i < attr->num_values; i ++)
+ toattr->values[i].integer = attr->values[i].integer;
+ break;
+
+ case IPP_TAG_BOOLEAN :
+ toattr = ippAddBooleans(to, attr->group_tag, attr->name,
+ attr->num_values, NULL);
+
+ for (i = 0; i < attr->num_values; i ++)
+ toattr->values[i].boolean = attr->values[i].boolean;
+ break;
+
+ case IPP_TAG_STRING :
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ toattr = ippAddStrings(to, attr->group_tag,
+ (ipp_tag_t)(attr->value_tag | quickcopy),
+ attr->name, attr->num_values, NULL, NULL);
+
+ if (quickcopy)
+ {
+ for (i = 0; i < attr->num_values; i ++)
+ toattr->values[i].string.text = attr->values[i].string.text;
+ }
+ else
+ {
+ for (i = 0; i < attr->num_values; i ++)
+ toattr->values[i].string.text = strdup(attr->values[i].string.text);
+ }
+ break;
+
+ case IPP_TAG_DATE :
+ toattr = ippAddDate(to, attr->group_tag, attr->name,
+ attr->values[0].date);
+ break;
+
+ case IPP_TAG_RESOLUTION :
+ toattr = ippAddResolutions(to, attr->group_tag, attr->name,
+ attr->num_values, IPP_RES_PER_INCH,
+ NULL, NULL);
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ toattr->values[i].resolution.xres = attr->values[i].resolution.xres;
+ toattr->values[i].resolution.yres = attr->values[i].resolution.yres;
+ toattr->values[i].resolution.units = attr->values[i].resolution.units;
+ }
+ break;
+
+ case IPP_TAG_RANGE :
+ toattr = ippAddRanges(to, attr->group_tag, attr->name,
+ attr->num_values, NULL, NULL);
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ toattr->values[i].range.lower = attr->values[i].range.lower;
+ toattr->values[i].range.upper = attr->values[i].range.upper;
+ }
+ break;
+
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ toattr = ippAddStrings(to, attr->group_tag,
+ (ipp_tag_t)(attr->value_tag | quickcopy),
+ attr->name, attr->num_values, NULL, NULL);
+
+ if (quickcopy)
+ {
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ toattr->values[i].string.charset = attr->values[i].string.charset;
+ toattr->values[i].string.text = attr->values[i].string.text;
+ }
+ }
+ else
+ {
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if (!i)
+ toattr->values[i].string.charset =
+ strdup(attr->values[i].string.charset);
+ else
+ toattr->values[i].string.charset =
+ toattr->values[0].string.charset;
+
+ toattr->values[i].string.text = strdup(attr->values[i].string.text);
+ }
+ }
+ break;
+
+ default :
+ toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag,
+ attr->name, attr->num_values, NULL);
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ toattr->values[i].unknown.length = attr->values[i].unknown.length;
+
+ if (toattr->values[i].unknown.length > 0)
+ {
+ if ((toattr->values[i].unknown.data = malloc(toattr->values[i].unknown.length)) == NULL)
+ toattr->values[i].unknown.length = 0;
+ else
+ memcpy(toattr->values[i].unknown.data,
+ attr->values[i].unknown.data,
+ toattr->values[i].unknown.length);
+ }
+ }
+ break; /* anti-compiler-warning-code */
+ }
+}
+
+
+/*
+ * 'copy_attrs()' - Copy attributes from one request to another.
+ */
+
+static void
+copy_attrs(ipp_t *to, /* I - Destination request */
+ ipp_t *from, /* I - Source request */
+ ipp_attribute_t *req, /* I - Requested attributes */
+ ipp_tag_t group) /* I - Group to copy */
+{
+ int i; /* Looping var */
+ ipp_attribute_t *fromattr; /* Source attribute */
+
+
+ LogMessage(L_DEBUG2, "copy_attrs(%p, %p, %p, %x)\n", to, from, req, group);
+
+ if (to == NULL || from == NULL)
+ return;
+
+ if (req != NULL && strcmp(req->values[0].string.text, "all") == 0)
+ req = NULL; /* "all" means no filter... */
+
+ for (fromattr = from->attrs; fromattr != NULL; fromattr = fromattr->next)
+ {
+ /*
+ * Filter attributes as needed...
+ */
+
+ if (group != IPP_TAG_ZERO && fromattr->group_tag != group &&
+ fromattr->group_tag != IPP_TAG_ZERO)
+ continue;
+
+ if (req != NULL && fromattr->name != NULL)
+ {
+ for (i = 0; i < req->num_values; i ++)
+ if (strcmp(fromattr->name, req->values[i].string.text) == 0)
+ break;
+
+ if (i == req->num_values)
+ continue;
+ }
+
+ copy_attribute(to, fromattr, IPP_TAG_COPY);
+ }
+}
+
+
+/*
+ * 'create_job()' - Print a file to a printer or class.
+ */
+
+static void
+create_job(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ ipp_attribute_t *attr; /* Current attribute */
+ const char *dest; /* Destination */
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ int priority; /* Job priority */
+ char *title; /* Job name/title */
+ job_t *job; /* Current job */
+ char job_uri[HTTP_MAX_URI],
+ /* Job URI */
+ printer_uri[HTTP_MAX_URI],
+ /* Printer URI */
+ method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ printer_t *printer; /* Printer data */
+ int kbytes; /* Size of print file */
+
+
+ LogMessage(L_DEBUG2, "create_job(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Verify that the POST operation was done to a valid URI.
+ */
+
+ if (strncmp(con->uri, "/classes/", 9) != 0 &&
+ strncmp(con->uri, "/printers/", 10) != 0)
+ {
+ LogMessage(L_ERROR, "create_job: cancel request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((dest = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "create_job: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * See if the printer is accepting jobs...
+ */
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ {
+ printer = FindClass(dest);
+ snprintf(printer_uri, sizeof(printer_uri), "http://%s:%d/classes/%s",
+ ServerName, ntohs(con->http.hostaddr.sin_port), dest);
+ }
+ else
+ {
+ printer = FindPrinter(dest);
+
+ snprintf(printer_uri, sizeof(printer_uri), "http://%s:%d/printers/%s",
+ ServerName, ntohs(con->http.hostaddr.sin_port), dest);
+ }
+
+ if (!printer->accepting)
+ {
+ LogMessage(L_INFO, "create_job: destination \'%s\' is not accepting jobs.",
+ dest);
+ send_ipp_error(con, IPP_NOT_ACCEPTING);
+ return;
+ }
+
+ /*
+ * Validate job template attributes; for now just copies...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "copies", IPP_TAG_INTEGER)) != NULL)
+ {
+ if (attr->values[0].integer < 1 || attr->values[0].integer > MaxCopies)
+ {
+ LogMessage(L_INFO, "create_job: bad copies value %d.",
+ attr->values[0].integer);
+ send_ipp_error(con, IPP_ATTRIBUTES);
+ return;
+ }
+ }
+
+ /*
+ * Make sure we aren't over our limit...
+ */
+
+ if (NumJobs >= MaxJobs && MaxJobs)
+ CleanJobs();
+
+ if (NumJobs >= MaxJobs && MaxJobs)
+ {
+ LogMessage(L_INFO, "create_job: too many jobs.");
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ if (!check_quotas(con, printer))
+ {
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ /*
+ * Create the job and set things up...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "job-priority", IPP_TAG_INTEGER)) != NULL)
+ priority = attr->values[0].integer;
+ else
+ ippAddInteger(con->request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority",
+ priority = 50);
+
+ if ((attr = ippFindAttribute(con->request, "job-name", IPP_TAG_NAME)) != NULL)
+ title = attr->values[0].string.text;
+ else
+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
+ title = "Untitled");
+
+ if ((job = AddJob(priority, printer->name)) == NULL)
+ {
+ LogMessage(L_ERROR, "create_job: unable to add job for destination \'%s\'!",
+ dest);
+ send_ipp_error(con, IPP_INTERNAL_ERROR);
+ return;
+ }
+
+ job->dtype = dtype;
+ job->attrs = con->request;
+ con->request = NULL;
+
+ strlcpy(job->title, title, sizeof(job->title));
+
+ attr = ippFindAttribute(job->attrs, "requesting-user-name", IPP_TAG_NAME);
+
+ if (con->username[0])
+ strlcpy(job->username, con->username, sizeof(job->username));
+ else if (attr != NULL)
+ {
+ LogMessage(L_DEBUG, "create_job: requesting-user-name = \'%s\'",
+ attr->values[0].string.text);
+
+ strlcpy(job->username, attr->values[0].string.text,
+ sizeof(job->username));
+ }
+ else
+ strcpy(job->username, "anonymous");
+
+ if (attr == NULL)
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-originating-user-name",
+ NULL, job->username);
+ else
+ {
+ attr->group_tag = IPP_TAG_JOB;
+ free(attr->name);
+ attr->name = strdup("job-originating-user-name");
+ }
+
+ if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name",
+ IPP_TAG_ZERO)) != NULL)
+ {
+ /*
+ * Request contains a job-originating-host-name attribute; validate it...
+ */
+
+ if (attr->value_tag != IPP_TAG_NAME ||
+ attr->num_values != 1 ||
+ strcmp(con->http.hostname, "localhost") != 0)
+ {
+ /*
+ * Can't override the value if we aren't connected via localhost.
+ * Also, we can only have 1 value and it must be a name value.
+ */
+
+ int i; /* Looping var */
+
+ switch (attr->value_tag)
+ {
+ case IPP_TAG_STRING :
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ /*
+ * Free old strings...
+ */
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ free(attr->values[i].string.text);
+ attr->values[i].string.text = NULL;
+ if (attr->values[i].string.charset)
+ {
+ free(attr->values[i].string.charset);
+ attr->values[i].string.charset = NULL;
+ }
+ }
+
+ default :
+ break;
+ }
+
+ /*
+ * Use the default connection hostname instead...
+ */
+
+ attr->value_tag = IPP_TAG_NAME;
+ attr->num_values = 1;
+ attr->values[0].string.text = strdup(con->http.hostname);
+ }
+ }
+ else
+ {
+ /*
+ * No job-originating-host-name attribute, so use the hostname from
+ * the connection...
+ */
+
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME,
+ "job-originating-host-name", NULL, con->http.hostname);
+ }
+
+ ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation",
+ time(NULL));
+ attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+ "time-at-processing", 0);
+ attr->value_tag = IPP_TAG_NOVALUE;
+ attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+ "time-at-completed", 0);
+ attr->value_tag = IPP_TAG_NOVALUE;
+
+ /*
+ * Add remaining job attributes...
+ */
+
+ ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
+ job->state = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_ENUM,
+ "job-state", IPP_JOB_STOPPED);
+ job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+ "job-media-sheets-completed", 0);
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL,
+ printer_uri);
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
+ title);
+
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
+ attr->values[0].integer = 0;
+ else
+ attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+ "job-k-octets", 0);
+
+ if ((attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+ if (attr == NULL)
+ attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-hold-until", NULL, "no-hold");
+ if (attr != NULL && strcmp(attr->values[0].string.text, "no-hold") != 0 &&
+ !(printer->type & CUPS_PRINTER_REMOTE))
+ {
+ /*
+ * Hold job until specified time...
+ */
+
+ SetJobHoldUntil(job->id, attr->values[0].string.text);
+ }
+ else
+ job->hold_until = time(NULL) + 60;
+
+ job->state->values[0].integer = IPP_JOB_HELD;
+
+ if (!(printer->type & CUPS_PRINTER_REMOTE) || Classification[0])
+ {
+ /*
+ * Add job sheets options...
+ */
+
+ if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) == NULL)
+ {
+ LogMessage(L_DEBUG, "Adding default job-sheets values \"%s,%s\"...",
+ printer->job_sheets[0], printer->job_sheets[1]);
+
+ attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets",
+ 2, NULL, NULL);
+ attr->values[0].string.text = strdup(printer->job_sheets[0]);
+ attr->values[1].string.text = strdup(printer->job_sheets[1]);
+ }
+
+ job->job_sheets = attr;
+
+ /*
+ * Enforce classification level if set...
+ */
+
+ if (Classification[0])
+ {
+ if (ClassifyOverride)
+ {
+ if (strcmp(attr->values[0].string.text, "none") == 0 &&
+ (attr->num_values == 1 ||
+ strcmp(attr->values[1].string.text, "none") == 0))
+ {
+ /*
+ * Force the leading banner to have the classification on it...
+ */
+
+ free(attr->values[0].string.text);
+ attr->values[0].string.text = strdup(Classification);
+ }
+ else if (attr->num_values == 2 &&
+ strcmp(attr->values[0].string.text, attr->values[1].string.text) != 0 &&
+ strcmp(attr->values[0].string.text, "none") != 0 &&
+ strcmp(attr->values[1].string.text, "none") != 0)
+ {
+ /*
+ * Can't put two different security markings on the same document!
+ */
+
+ free(attr->values[1].string.text);
+ attr->values[1].string.text = strdup(attr->values[0].string.text);
+ }
+ }
+ else if (strcmp(attr->values[0].string.text, Classification) != 0 &&
+ (attr->num_values == 1 ||
+ strcmp(attr->values[1].string.text, Classification) != 0))
+ {
+ /*
+ * Force the leading banner to have the classification on it...
+ */
+
+ free(attr->values[0].string.text);
+ attr->values[0].string.text = strdup(Classification);
+ }
+ }
+
+ /*
+ * See if we need to add the starting sheet...
+ */
+
+ if (!(printer->type & CUPS_PRINTER_REMOTE))
+ {
+ kbytes = copy_banner(con, job, attr->values[0].string.text);
+
+ UpdateQuota(printer, job->username, 0, kbytes);
+ }
+ }
+ else if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL)
+ job->sheets = attr;
+
+ /*
+ * Save and log the job...
+ */
+
+ SaveJob(job->id);
+
+ LogMessage(L_INFO, "Job %d created on \'%s\' by \'%s\'.", job->id,
+ job->dest, job->username);
+
+ /*
+ * Fill in the response info...
+ */
+
+ snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName,
+ ntohs(con->http.hostaddr.sin_port), job->id);
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL, job_uri);
+
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
+
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
+ job->state->values[0].integer);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'copy_banner()' - Copy a banner file to the requests directory for the
+ * specified job.
+ */
+
+static int /* O - Size of banner file in kbytes */
+copy_banner(client_t *con, /* I - Client connection */
+ job_t *job, /* I - Job information */
+ const char *name) /* I - Name of banner */
+{
+ int i; /* Looping var */
+ int kbytes; /* Size of banner file in kbytes */
+ char filename[1024]; /* Job filename */
+ banner_t *banner; /* Pointer to banner */
+ FILE *in; /* Input file */
+ FILE *out; /* Output file */
+ int ch; /* Character from file */
+ char attrname[255], /* Name of attribute */
+ *s; /* Pointer into name */
+ ipp_attribute_t *attr; /* Attribute */
+
+
+ LogMessage(L_DEBUG2, "copy_banner(%p[%d], %p[%d], %s)",
+ con, con->http.fd, job, job->id, name ? name : "(null)");
+
+ /*
+ * Find the banner; return if not found or "none"...
+ */
+
+ if (name == NULL ||
+ strcmp(name, "none") == 0 ||
+ (banner = FindBanner(name)) == NULL)
+ return (0);
+
+ /*
+ * Open the banner and job files...
+ */
+
+ if (add_file(con, job, banner->filetype))
+ return (0);
+
+ snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id,
+ job->num_files);
+ if ((out = fopen(filename, "w")) == NULL)
+ {
+ LogMessage(L_ERROR, "copy_banner: Unable to create banner job file %s - %s",
+ filename, strerror(errno));
+ job->num_files --;
+ return (0);
+ }
+
+ fchmod(fileno(out), 0640);
+ fchown(fileno(out), User, Group);
+
+ if (con->language)
+ {
+ /*
+ * Try the localized banner file under the subdirectory...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir,
+ con->language->language, name);
+
+ if (access(filename, 0) && con->language->language[2])
+ {
+ /*
+ * Wasn't able to find "ll_CC" locale file; try the non-national
+ * localization banner directory.
+ */
+
+ attrname[0] = con->language->language[0];
+ attrname[1] = con->language->language[1];
+ attrname[2] = '\0';
+
+ snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir,
+ attrname, name);
+ }
+
+ if (access(filename, 0))
+ {
+ /*
+ * Use the non-localized banner file.
+ */
+
+ snprintf(filename, sizeof(filename), "%s/banners/%s", DataDir, name);
+ }
+ }
+ else
+ {
+ /*
+ * Use the non-localized banner file.
+ */
+
+ snprintf(filename, sizeof(filename), "%s/banners/%s", DataDir, name);
+ }
+
+ if ((in = fopen(filename, "r")) == NULL)
+ {
+ fclose(out);
+ unlink(filename);
+ LogMessage(L_ERROR, "copy_banner: Unable to open banner template file %s - %s",
+ filename, strerror(errno));
+ job->num_files --;
+ return (0);
+ }
+
+ /*
+ * Parse the file to the end...
+ */
+
+ while ((ch = getc(in)) != EOF)
+ if (ch == '{')
+ {
+ /*
+ * Get an attribute name...
+ */
+
+ for (s = attrname; (ch = getc(in)) != EOF;)
+ if (!isalpha(ch) && ch != '-' && ch != '?')
+ break;
+ else if (s < (attrname + sizeof(attrname) - 1))
+ *s++ = ch;
+ else
+ break;
+
+ *s = '\0';
+
+ if (ch != '}')
+ {
+ /*
+ * Ignore { followed by stuff that is not an attribute name...
+ */
+
+ putc('{', out);
+ fputs(attrname, out);
+ putc(ch, out);
+ continue;
+ }
+
+ /*
+ * See if it is defined...
+ */
+
+ if (attrname[0] == '?')
+ s = attrname + 1;
+ else
+ s = attrname;
+
+ if (strcmp(s, "printer-name") == 0)
+ {
+ fputs(job->dest, out);
+ continue;
+ }
+ else if ((attr = ippFindAttribute(job->attrs, s, IPP_TAG_ZERO)) == NULL)
+ {
+ /*
+ * See if we have a leading question mark...
+ */
+
+ if (attrname[0] != '?')
+ {
+ /*
+ * Nope, write to file as-is; probably a PostScript procedure...
+ */
+
+ putc('{', out);
+ fputs(attrname, out);
+ putc('}', out);
+ }
+
+ continue;
+ }
+
+ /*
+ * Output value(s)...
+ */
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if (i)
+ putc(',', out);
+
+ switch (attr->value_tag)
+ {
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ if (strncmp(attrname, "time-at-", 8) == 0)
+ fputs(GetDateTime(attr->values[i].integer), out);
+ else
+ fprintf(out, "%d", attr->values[i].integer);
+ break;
+
+ case IPP_TAG_BOOLEAN :
+ fprintf(out, "%d", attr->values[i].boolean);
+ break;
+
+ case IPP_TAG_NOVALUE :
+ fputs("novalue", out);
+ break;
+
+ case IPP_TAG_RANGE :
+ fprintf(out, "%d-%d", attr->values[i].range.lower,
+ attr->values[i].range.upper);
+ break;
+
+ case IPP_TAG_RESOLUTION :
+ fprintf(out, "%dx%d%s", attr->values[i].resolution.xres,
+ attr->values[i].resolution.yres,
+ attr->values[i].resolution.units == IPP_RES_PER_INCH ?
+ "dpi" : "dpc");
+ break;
+
+ case IPP_TAG_URI :
+ case IPP_TAG_STRING :
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ if (strcasecmp(banner->filetype->type, "postscript") == 0)
+ {
+ /*
+ * Need to quote strings for PS banners...
+ */
+
+ const char *p;
+
+ for (p = attr->values[i].string.text; *p; p ++)
+ {
+ if (*p == '(' || *p == ')' || *p == '\\')
+ {
+ putc('\\', out);
+ putc(*p, out);
+ }
+ else if (*p < 32 || *p > 126)
+ fprintf(out, "\\%03o", *p);
+ else
+ putc(*p, out);
+ }
+ }
+ else
+ fputs(attr->values[i].string.text, out);
+ break;
+
+ default :
+ break; /* anti-compiler-warning-code */
+ }
+ }
+ }
+ else if (ch == '\\') /* Quoted char */
+ {
+ ch = getc(in);
+
+ if (ch != '{') /* Only do special handling for \{ */
+ putc('\\', out);
+
+ putc(ch, out);
+ }
+ else
+ putc(ch, out);
+
+ fclose(in);
+
+ kbytes = (ftell(out) + 1023) / 1024;
+
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
+ attr->values[0].integer += kbytes;
+
+ fclose(out);
+
+ return (kbytes);
+}
+
+
+/*
+ * 'copy_file()' - Copy a PPD file or interface script...
+ */
+
+static int /* O - 0 = success, -1 = error */
+copy_file(const char *from, /* I - Source file */
+ const char *to) /* I - Destination file */
+{
+#ifdef HAVE_LIBZ
+ gzFile src; /* Source file */
+#else
+ int src; /* Source file */
+#endif /* HAVE_LIBZ */
+ int dst, /* Destination file */
+ bytes; /* Bytes to read/write */
+ char buffer[8192]; /* Copy buffer */
+
+
+ LogMessage(L_DEBUG2, "copy_file(\"%s\", \"%s\")\n", from, to);
+
+#ifdef HAVE_LIBZ
+ if ((src = gzopen(from, "rb")) == NULL)
+ return (-1);
+#else
+ if ((src = open(from, O_RDONLY)) < 0)
+ return (-1);
+#endif /* HAVE_LIBZ */
+
+ if ((dst = open(to, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0)
+ {
+#ifdef HAVE_LIBZ
+ gzclose(src);
+#else
+ close(src);
+#endif /* HAVE_LIBZ */
+ return (-1);
+ }
+
+#ifdef HAVE_LIBZ
+ while ((bytes = gzread(src, buffer, sizeof(buffer))) > 0)
+#else
+ while ((bytes = read(src, buffer, sizeof(buffer))) > 0)
+#endif /* HAVE_LIBZ */
+ if (write(dst, buffer, bytes) < bytes)
+ {
+#ifdef HAVE_LIBZ
+ gzclose(src);
+#else
+ close(src);
+#endif /* HAVE_LIBZ */
+ close(dst);
+ return (-1);
+ }
+
+#ifdef HAVE_LIBZ
+ gzclose(src);
+#else
+ close(src);
+#endif /* HAVE_LIBZ */
+ close(dst);
+
+ return (0);
+}
+
+
+/*
+ * 'delete_printer()' - Remove a printer or class from the system.
+ */
+
+static void
+delete_printer(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - URI of printer or class */
+{
+ const char *dest; /* Destination */
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ printer_t *printer; /* Printer/class */
+ char filename[1024]; /* Script/PPD filename */
+
+
+ LogMessage(L_DEBUG2, "delete_printer(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ LogMessage(L_ERROR, "delete_printer: admin request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Do we have a valid URI?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((dest = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "delete_printer: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Find the printer or class and delete it...
+ */
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ printer = FindClass(dest);
+ else
+ printer = FindPrinter(dest);
+
+ /*
+ * Remove old jobs...
+ */
+
+ CancelJobs(dest);
+
+ /*
+ * Remove any old PPD or script files...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot, dest);
+ unlink(filename);
+
+ snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot, dest);
+ unlink(filename);
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ {
+ LogMessage(L_INFO, "Class \'%s\' deleted by \'%s\'.", dest,
+ con->username);
+
+ DeletePrinter(printer);
+ SaveAllClasses();
+ }
+ else
+ {
+ LogMessage(L_INFO, "Printer \'%s\' deleted by \'%s\'.", dest,
+ con->username);
+
+ DeletePrinter(printer);
+ SaveAllPrinters();
+ }
+
+ /*
+ * Return with no errors...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'get_default()' - Get the default destination.
+ */
+
+static void
+get_default(client_t *con) /* I - Client connection */
+{
+ LogMessage(L_DEBUG2, "get_default(%p[%d])\n", con, con->http.fd);
+
+ if (DefaultPrinter != NULL)
+ {
+ copy_attrs(con->response, DefaultPrinter->attrs,
+ ippFindAttribute(con->request, "requested-attributes",
+ IPP_TAG_KEYWORD), IPP_TAG_ZERO);
+
+ con->response->request.status.status_code = IPP_OK;
+ }
+ else
+ con->response->request.status.status_code = IPP_NOT_FOUND;
+}
+
+
+/*
+ * 'get_devices()' - Get the list of available devices on the local system.
+ */
+
+static void
+get_devices(client_t *con) /* I - Client connection */
+{
+ LogMessage(L_DEBUG2, "get_devices(%p[%d])\n", con, con->http.fd);
+
+ /*
+ * Copy the device attributes to the response using the requested-attributes
+ * attribute that may be provided by the client.
+ */
+
+ copy_attrs(con->response, Devices,
+ ippFindAttribute(con->request, "requested-attributes",
+ IPP_TAG_KEYWORD), IPP_TAG_ZERO);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'get_jobs()' - Get a list of jobs for the specified printer.
+ */
+
+static void
+get_jobs(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ ipp_attribute_t *attr, /* Current attribute */
+ *requested; /* Requested attributes */
+ const char *dest; /* Destination */
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ cups_ptype_t dmask; /* Destination type mask */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ int completed; /* Completed jobs? */
+ int limit; /* Maximum number of jobs to return */
+ int count; /* Number of jobs that match */
+ job_t *job; /* Current job pointer */
+ char job_uri[HTTP_MAX_URI];
+ /* Job URI... */
+
+
+ LogMessage(L_DEBUG2, "get_jobs(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (strcmp(resource, "/") == 0 ||
+ (strncmp(resource, "/jobs", 5) == 0 && strlen(resource) <= 6))
+ {
+ dest = NULL;
+ dtype = (cups_ptype_t)0;
+ dmask = (cups_ptype_t)0;
+ }
+ else if (strncmp(resource, "/printers", 9) == 0 && strlen(resource) <= 10)
+ {
+ dest = NULL;
+ dtype = (cups_ptype_t)0;
+ dmask = CUPS_PRINTER_CLASS;
+ }
+ else if (strncmp(resource, "/classes", 8) == 0 && strlen(resource) <= 9)
+ {
+ dest = NULL;
+ dtype = CUPS_PRINTER_CLASS;
+ dmask = CUPS_PRINTER_CLASS;
+ }
+ else if ((dest = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "get_jobs: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+ else
+ dmask = CUPS_PRINTER_CLASS;
+
+ /*
+ * See if the "which-jobs" attribute have been specified; if so, return
+ * right away if they specify "completed" - we don't keep old job records...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "which-jobs", IPP_TAG_KEYWORD)) != NULL &&
+ strcmp(attr->values[0].string.text, "completed") == 0)
+ completed = 1;
+ else
+ completed = 0;
+
+ /*
+ * See if they want to limit the number of jobs reported...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER)) != NULL)
+ limit = attr->values[0].integer;
+ else
+ limit = 1000000;
+
+ /*
+ * See if we only want to see jobs for a specific user...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "my-jobs", IPP_TAG_BOOLEAN)) != NULL &&
+ attr->values[0].boolean)
+ {
+ if (con->username[0])
+ strlcpy(username, con->username, sizeof(username));
+ else if ((attr = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME)) != NULL)
+ strlcpy(username, attr->values[0].string.text, sizeof(username));
+ else
+ strcpy(username, "anonymous");
+ }
+ else
+ username[0] = '\0';
+
+ requested = ippFindAttribute(con->request, "requested-attributes",
+ IPP_TAG_KEYWORD);
+
+ /*
+ * OK, build a list of jobs for this printer...
+ */
+
+ for (count = 0, job = Jobs; count < limit && job != NULL; job = job->next)
+ {
+ /*
+ * Filter out jobs that don't match...
+ */
+
+ LogMessage(L_DEBUG2, "get_jobs: job->id = %d", job->id);
+
+ if ((dest != NULL && strcmp(job->dest, dest) != 0) &&
+ (job->printer == NULL || dest == NULL ||
+ strcmp(job->printer->name, dest) != 0))
+ continue;
+ if ((job->dtype & dmask) != dtype &&
+ (job->printer == NULL || (job->printer->type & dmask) != dtype))
+ continue;
+ if (username[0] != '\0' && strcmp(username, job->username) != 0)
+ continue;
+
+ if (completed && job->state->values[0].integer <= IPP_JOB_STOPPED)
+ continue;
+ if (!completed && job->state->values[0].integer > IPP_JOB_STOPPED)
+ continue;
+
+ count ++;
+
+ LogMessage(L_DEBUG2, "get_jobs: count = %d", count);
+
+ /*
+ * Send the requested attributes for each job...
+ */
+
+ snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName,
+ ntohs(con->http.hostaddr.sin_port), job->id);
+
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
+ "job-more-info", NULL, job_uri);
+
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
+ "job-uri", NULL, job_uri);
+
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER,
+ "job-printer-up-time", time(NULL));
+
+ /*
+ * Copy the job attributes to the response using the requested-attributes
+ * attribute that may be provided by the client.
+ */
+
+ copy_attrs(con->response, job->attrs, requested, IPP_TAG_JOB);
+
+ add_job_state_reasons(con, job);
+
+ ippAddSeparator(con->response);
+ }
+
+ if (requested != NULL)
+ con->response->request.status.status_code = IPP_OK_SUBST;
+ else
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'get_job_attrs()' - Get job attributes.
+ */
+
+static void
+get_job_attrs(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Job URI */
+{
+ ipp_attribute_t *attr, /* Current attribute */
+ *requested; /* Requested attributes */
+ int jobid; /* Job ID */
+ job_t *job; /* Current job */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ char job_uri[HTTP_MAX_URI];
+ /* Job URI... */
+
+
+ LogMessage(L_DEBUG2, "get_job_attrs(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * See if we have a job URI or a printer URI...
+ */
+
+ if (strcmp(uri->name, "printer-uri") == 0)
+ {
+ /*
+ * Got a printer URI; see if we also have a job-id attribute...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "job-id", IPP_TAG_INTEGER)) == NULL)
+ {
+ LogMessage(L_ERROR, "get_job_attrs: got a printer-uri attribute but no job-id!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = attr->values[0].integer;
+ }
+ else
+ {
+ /*
+ * Got a job URI; parse it to get the job ID...
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (strncmp(resource, "/jobs/", 6) != 0)
+ {
+ /*
+ * Not a valid URI!
+ */
+
+ LogMessage(L_ERROR, "get_job_attrs: bad job-uri attribute \'%s\'!\n",
+ uri->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = atoi(resource + 6);
+ }
+
+ /*
+ * See if the job exists...
+ */
+
+ if ((job = FindJob(jobid)) == NULL)
+ {
+ /*
+ * Nope - return a "not found" error...
+ */
+
+ LogMessage(L_ERROR, "get_job_attrs: job #%d doesn't exist!", jobid);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Put out the standard attributes...
+ */
+
+ snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d",
+ ServerName, ntohs(con->http.hostaddr.sin_port),
+ job->id);
+
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
+
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
+ "job-more-info", NULL, job_uri);
+
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
+ "job-uri", NULL, job_uri);
+
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER,
+ "job-printer-up-time", time(NULL));
+
+ /*
+ * Copy the job attributes to the response using the requested-attributes
+ * attribute that may be provided by the client.
+ */
+
+ requested = ippFindAttribute(con->request, "requested-attributes",
+ IPP_TAG_KEYWORD);
+
+ copy_attrs(con->response, job->attrs, requested, IPP_TAG_JOB);
+
+ add_job_state_reasons(con, job);
+
+ if (requested != NULL)
+ con->response->request.status.status_code = IPP_OK_SUBST;
+ else
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'get_ppds()' - Get the list of PPD files on the local system.
+ */
+
+static void
+get_ppds(client_t *con) /* I - Client connection */
+{
+ LogMessage(L_DEBUG2, "get_ppds(%p[%d])\n", con, con->http.fd);
+
+ /*
+ * Copy the PPD attributes to the response using the requested-attributes
+ * attribute that may be provided by the client.
+ */
+
+ copy_attrs(con->response, PPDs,
+ ippFindAttribute(con->request, "requested-attributes",
+ IPP_TAG_KEYWORD), IPP_TAG_ZERO);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'get_printer_attrs()' - Get printer attributes.
+ */
+
+static void
+get_printer_attrs(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ const char *dest; /* Destination */
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ printer_t *printer; /* Printer/class */
+ time_t curtime; /* Current time */
+
+
+ LogMessage(L_DEBUG2, "get_printer_attrs(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((dest = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "get_printer_attrs: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ printer = FindClass(dest);
+ else
+ printer = FindPrinter(dest);
+
+ curtime = time(NULL);
+
+ /*
+ * Copy the printer attributes to the response using requested-attributes
+ * and document-format attributes that may be provided by the client.
+ */
+
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
+ printer->state);
+
+ add_printer_state_reasons(con, printer);
+
+ ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-state-message", NULL, printer->state_message);
+
+ ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs",
+ printer->accepting);
+
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "printer-up-time", curtime);
+ ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
+ ippTimeToDate(curtime));
+
+ add_queued_job_count(con, printer);
+
+ copy_attrs(con->response, printer->attrs,
+ ippFindAttribute(con->request, "requested-attributes",
+ IPP_TAG_KEYWORD), IPP_TAG_ZERO);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'get_printers()' - Get a list of printers or classes.
+ */
+
+static void
+get_printers(client_t *con, /* I - Client connection */
+ int type) /* I - 0 or CUPS_PRINTER_CLASS */
+{
+ ipp_attribute_t *attr, /* Current attribute */
+ *requested; /* Requested attributes */
+ int limit; /* Maximum number of printers to return */
+ int count; /* Number of printers that match */
+ printer_t *printer; /* Current printer pointer */
+ time_t curtime; /* Current time */
+ int printer_type, /* printer-type attribute */
+ printer_mask; /* printer-type-mask attribute */
+ char *location; /* Location string */
+ char name[IPP_MAX_NAME],
+ /* Printer name */
+ *nameptr; /* Pointer into name */
+ printer_t *iclass; /* Implicit class */
+
+
+ LogMessage(L_DEBUG2, "get_printers(%p[%d], %x)\n", con, con->http.fd, type);
+
+ /*
+ * See if they want to limit the number of printers reported...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER)) != NULL)
+ limit = attr->values[0].integer;
+ else
+ limit = 10000000;
+
+ /*
+ * Support filtering...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "printer-type", IPP_TAG_ENUM)) != NULL)
+ printer_type = attr->values[0].integer;
+ else
+ printer_type = 0;
+
+ if ((attr = ippFindAttribute(con->request, "printer-type-mask", IPP_TAG_ENUM)) != NULL)
+ printer_mask = attr->values[0].integer;
+ else
+ printer_mask = 0;
+
+ if ((attr = ippFindAttribute(con->request, "location", IPP_TAG_TEXT)) != NULL)
+ location = attr->values[0].string.text;
+ else
+ location = NULL;
+
+ requested = ippFindAttribute(con->request, "requested-attributes",
+ IPP_TAG_KEYWORD);
+
+ /*
+ * OK, build a list of printers for this printer...
+ */
+
+ curtime = time(NULL);
+
+ for (count = 0, printer = Printers;
+ count < limit && printer != NULL;
+ printer = printer->next)
+ if ((printer->type & CUPS_PRINTER_CLASS) == type &&
+ (printer->type & printer_mask) == printer_type &&
+ (location == NULL || strcasecmp(printer->location, location) == 0))
+ {
+ /*
+ * If HideImplicitMembers is enabled, see if this printer or class
+ * is a member of an implicit class...
+ */
+
+ if (ImplicitClasses && HideImplicitMembers &&
+ (printer->type & CUPS_PRINTER_REMOTE))
+ {
+ /*
+ * Make a copy of the printer name...
+ *
+ * Note: name and printer->name are both IPP_MAX_NAME characters
+ * in size, so strcpy() is safe...
+ */
+
+ strcpy(name, printer->name);
+
+ if ((nameptr = strchr(name, '@')) != NULL)
+ {
+ /*
+ * Strip trailing @server...
+ */
+
+ *nameptr = '\0';
+
+ /*
+ * Find the core printer, if any...
+ */
+
+ if ((iclass = FindPrinter(name)) != NULL &&
+ (iclass->type & CUPS_PRINTER_IMPLICIT))
+ continue;
+ }
+ }
+
+ /*
+ * Add the group separator as needed...
+ */
+
+ if (count > 0)
+ ippAddSeparator(con->response);
+
+ count ++;
+
+ /*
+ * Send the following attributes for each printer:
+ *
+ * printer-state
+ * printer-state-message
+ * printer-is-accepting-jobs
+ * + all printer attributes
+ */
+
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM,
+ "printer-state", printer->state);
+
+ add_printer_state_reasons(con, printer);
+
+ ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-state-message", NULL, printer->state_message);
+
+ ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs",
+ printer->accepting);
+
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "printer-up-time", curtime);
+ ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
+ ippTimeToDate(curtime));
+
+ add_queued_job_count(con, printer);
+
+ copy_attrs(con->response, printer->attrs, requested, IPP_TAG_ZERO);
+ }
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'hold_job()' - Hold a print job.
+ */
+
+static void
+hold_job(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Job or Printer URI */
+{
+ ipp_attribute_t *attr, /* Current job-hold-until */
+ *newattr; /* New job-hold-until */
+ int jobid; /* Job ID */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ job_t *job; /* Job information */
+
+
+ LogMessage(L_DEBUG2, "hold_job(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Verify that the POST operation was done to a valid URI.
+ */
+
+ if (strncmp(con->uri, "/classes/", 9) != 0 &&
+ strncmp(con->uri, "/jobs/", 5) != 0 &&
+ strncmp(con->uri, "/printers/", 10) != 0)
+ {
+ LogMessage(L_ERROR, "hold_job: hold request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * See if we have a job URI or a printer URI...
+ */
+
+ if (strcmp(uri->name, "printer-uri") == 0)
+ {
+ /*
+ * Got a printer URI; see if we also have a job-id attribute...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "job-id", IPP_TAG_INTEGER)) == NULL)
+ {
+ LogMessage(L_ERROR, "hold_job: got a printer-uri attribute but no job-id!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = attr->values[0].integer;
+ }
+ else
+ {
+ /*
+ * Got a job URI; parse it to get the job ID...
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (strncmp(resource, "/jobs/", 6) != 0)
+ {
+ /*
+ * Not a valid URI!
+ */
+
+ LogMessage(L_ERROR, "hold_job: bad job-uri attribute \'%s\'!",
+ uri->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = atoi(resource + 6);
+ }
+
+ /*
+ * See if the job exists...
+ */
+
+ if ((job = FindJob(jobid)) == NULL)
+ {
+ /*
+ * Nope - return a "not found" error...
+ */
+
+ LogMessage(L_ERROR, "hold_job: job #%d doesn't exist!", jobid);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * See if the job is owned by the requesting user...
+ */
+
+ if (!validate_user(con, job->username, username, sizeof(username)))
+ {
+ LogMessage(L_ERROR, "hold_job: \"%s\" not authorized to hold job id %d owned by \"%s\"!",
+ username, jobid, job->username);
+ send_ipp_error(con, IPP_FORBIDDEN);
+ return;
+ }
+
+ /*
+ * Hold the job and return...
+ */
+
+ HoldJob(jobid);
+
+ if ((newattr = ippFindAttribute(con->request, "job-hold-until", IPP_TAG_KEYWORD)) == NULL)
+ newattr = ippFindAttribute(con->request, "job-hold-until", IPP_TAG_NAME);
+
+ if ((attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+
+ if (attr != NULL)
+ {
+ /*
+ * Free the old hold value and copy the new one over...
+ */
+
+ free(attr->values[0].string.text);
+
+ if (newattr != NULL)
+ {
+ attr->value_tag = newattr->value_tag;
+ attr->values[0].string.text = strdup(newattr->values[0].string.text);
+ }
+ else
+ {
+ attr->value_tag = IPP_TAG_KEYWORD;
+ attr->values[0].string.text = strdup("indefinite");
+ }
+
+ /*
+ * Hold job until specified time...
+ */
+
+ SetJobHoldUntil(job->id, attr->values[0].string.text);
+ }
+
+ LogMessage(L_INFO, "Job %d was held by \'%s\'.", jobid, username);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'move_job()' - Move a job to a new destination.
+ */
+
+static void
+move_job(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Job URI */
+{
+ ipp_attribute_t *attr; /* Current attribute */
+ int jobid; /* Job ID */
+ job_t *job; /* Current job */
+ const char *dest; /* Destination */
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+
+
+ LogMessage(L_DEBUG2, "move_job(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * See if we have a job URI or a printer URI...
+ */
+
+ if (strcmp(uri->name, "printer-uri") == 0)
+ {
+ /*
+ * Got a printer URI; see if we also have a job-id attribute...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "job-id", IPP_TAG_INTEGER)) == NULL)
+ {
+ LogMessage(L_ERROR, "move_job: got a printer-uri attribute but no job-id!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = attr->values[0].integer;
+ }
+ else
+ {
+ /*
+ * Got a job URI; parse it to get the job ID...
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (strncmp(resource, "/jobs/", 6) != 0)
+ {
+ /*
+ * Not a valid URI!
+ */
+
+ LogMessage(L_ERROR, "move_job: bad job-uri attribute \'%s\'!\n",
+ uri->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = atoi(resource + 6);
+ }
+
+ /*
+ * See if the job exists...
+ */
+
+ if ((job = FindJob(jobid)) == NULL)
+ {
+ /*
+ * Nope - return a "not found" error...
+ */
+
+ LogMessage(L_ERROR, "move_job: job #%d doesn't exist!", jobid);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * See if the job has been completed...
+ */
+
+ if (job->state->values[0].integer > IPP_JOB_STOPPED)
+ {
+ /*
+ * Return a "not-possible" error...
+ */
+
+ LogMessage(L_ERROR, "move_job: job #%d is finished and cannot be altered!", jobid);
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ /*
+ * See if the job is owned by the requesting user...
+ */
+
+ if (!validate_user(con, job->username, username, sizeof(username)))
+ {
+ LogMessage(L_ERROR, "move_job: \"%s\" not authorized to move job id %d owned by \"%s\"!",
+ username, jobid, job->username);
+ send_ipp_error(con, IPP_FORBIDDEN);
+ return;
+ }
+
+ if ((attr = ippFindAttribute(con->request, "job-printer-uri", IPP_TAG_URI)) == NULL)
+ {
+ /*
+ * Need job-printer-uri...
+ */
+
+ LogMessage(L_ERROR, "move_job: job-printer-uri attribute missing!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ /*
+ * Move the job to a different printer or class...
+ */
+
+ httpSeparate(attr->values[0].string.text, method, username, host, &port,
+ resource);
+ if ((dest = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "move_job: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ MoveJob(jobid, dest);
+
+ /*
+ * Start jobs if possible...
+ */
+
+ CheckJobs();
+
+ /*
+ * Return with "everything is OK" status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'print_job()' - Print a file to a printer or class.
+ */
+
+static void
+print_job(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ ipp_attribute_t *attr; /* Current attribute */
+ ipp_attribute_t *format; /* Document-format attribute */
+ const char *dest; /* Destination */
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ int priority; /* Job priority */
+ char *title; /* Job name/title */
+ job_t *job; /* Current job */
+ char job_uri[HTTP_MAX_URI],
+ /* Job URI */
+ printer_uri[HTTP_MAX_URI],
+ /* Printer URI */
+ method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI],
+ /* Resource portion of URI */
+ filename[1024]; /* Job filename */
+ int port; /* Port portion of URI */
+ mime_type_t *filetype; /* Type of file */
+ char super[MIME_MAX_SUPER],
+ /* Supertype of file */
+ type[MIME_MAX_TYPE],
+ /* Subtype of file */
+ mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE + 2];
+ /* Textual name of mime type */
+ printer_t *printer; /* Printer data */
+ struct stat fileinfo; /* File information */
+ int kbytes; /* Size of file */
+
+
+ LogMessage(L_DEBUG2, "print_job(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Verify that the POST operation was done to a valid URI.
+ */
+
+ if (strncmp(con->uri, "/classes/", 9) != 0 &&
+ strncmp(con->uri, "/printers/", 10) != 0)
+ {
+ LogMessage(L_ERROR, "print_job: cancel request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Validate job template attributes; for now just copies...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "copies", IPP_TAG_INTEGER)) != NULL)
+ {
+ if (attr->values[0].integer < 1 || attr->values[0].integer > MaxCopies)
+ {
+ LogMessage(L_INFO, "print_job: bad copies value %d.",
+ attr->values[0].integer);
+ send_ipp_error(con, IPP_ATTRIBUTES);
+ return;
+ }
+ }
+
+ /*
+ * OK, see if the client is sending the document compressed - CUPS
+ * doesn't support compression yet...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "compression", IPP_TAG_KEYWORD)) != NULL &&
+ strcmp(attr->values[0].string.text, "none") == 0)
+ {
+ LogMessage(L_ERROR, "print_job: Unsupported compression attribute %s!",
+ attr->values[0].string.text);
+ send_ipp_error(con, IPP_ATTRIBUTES);
+ ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
+ "compression", NULL, attr->values[0].string.text);
+ return;
+ }
+
+ /*
+ * Do we have a file to print?
+ */
+
+ if (con->filename[0] == '\0')
+ {
+ LogMessage(L_ERROR, "print_job: No file!?!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ /*
+ * Is it a format we support?
+ */
+
+ if ((format = ippFindAttribute(con->request, "document-format", IPP_TAG_MIMETYPE)) != NULL)
+ {
+ /*
+ * Grab format from client...
+ */
+
+ if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, type) != 2)
+ {
+ LogMessage(L_ERROR, "print_job: could not scan type \'%s\'!",
+ format->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+ }
+ else
+ {
+ /*
+ * No document format attribute? Auto-type it!
+ */
+
+ strcpy(super, "application");
+ strcpy(type, "octet-stream");
+ }
+
+ if (strcmp(super, "application") == 0 &&
+ strcmp(type, "octet-stream") == 0)
+ {
+ /*
+ * Auto-type the file...
+ */
+
+ LogMessage(L_DEBUG, "print_job: auto-typing file...");
+
+ filetype = mimeFileType(MimeDatabase, con->filename);
+
+ if (filetype != NULL)
+ {
+ /*
+ * Replace the document-format attribute value with the auto-typed one.
+ */
+
+ snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super,
+ filetype->type);
+
+ if (format != NULL)
+ {
+ free(format->values[0].string.text);
+ format->values[0].string.text = strdup(mimetype);
+ }
+ else
+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
+ "document-format", NULL, mimetype);
+ }
+ else
+ filetype = mimeType(MimeDatabase, super, type);
+ }
+ else
+ filetype = mimeType(MimeDatabase, super, type);
+
+ if (filetype == NULL)
+ {
+ LogMessage(L_ERROR, "print_job: Unsupported format \'%s/%s\'!",
+ super, type);
+ LogMessage(L_INFO, "Hint: Do you have the raw file printing rules enabled?");
+ send_ipp_error(con, IPP_DOCUMENT_FORMAT);
+
+ if (format)
+ ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
+ "document-format", NULL, format->values[0].string.text);
+
+ return;
+ }
+
+ LogMessage(L_DEBUG, "print_job: request file type is %s/%s.",
+ filetype->super, filetype->type);
+
+ /*
+ * Read any embedded job ticket info from PS files...
+ */
+
+ if (strcasecmp(filetype->super, "application") == 0 &&
+ strcasecmp(filetype->type, "postscript") == 0)
+ read_ps_job_ticket(con);
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((dest = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "print_job: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * See if the printer is accepting jobs...
+ */
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ {
+ printer = FindClass(dest);
+ snprintf(printer_uri, sizeof(printer_uri), "http://%s:%d/classes/%s",
+ ServerName, ntohs(con->http.hostaddr.sin_port), dest);
+ }
+ else
+ {
+ printer = FindPrinter(dest);
+
+ snprintf(printer_uri, sizeof(printer_uri), "http://%s:%d/printers/%s",
+ ServerName, ntohs(con->http.hostaddr.sin_port), dest);
+ }
+
+ if (!printer->accepting)
+ {
+ LogMessage(L_INFO, "print_job: destination \'%s\' is not accepting jobs.",
+ dest);
+ send_ipp_error(con, IPP_NOT_ACCEPTING);
+ return;
+ }
+
+ /*
+ * Make sure we aren't over our limit...
+ */
+
+ if (NumJobs >= MaxJobs && MaxJobs)
+ CleanJobs();
+
+ if (NumJobs >= MaxJobs && MaxJobs)
+ {
+ LogMessage(L_INFO, "print_job: too many jobs.");
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ if (!check_quotas(con, printer))
+ {
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ /*
+ * Create the job and set things up...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "job-priority", IPP_TAG_INTEGER)) != NULL)
+ priority = attr->values[0].integer;
+ else
+ ippAddInteger(con->request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority",
+ priority = 50);
+
+ if ((attr = ippFindAttribute(con->request, "job-name", IPP_TAG_NAME)) != NULL)
+ title = attr->values[0].string.text;
+ else
+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
+ title = "Untitled");
+
+ if ((job = AddJob(priority, printer->name)) == NULL)
+ {
+ LogMessage(L_ERROR, "print_job: unable to add job for destination \'%s\'!",
+ dest);
+ send_ipp_error(con, IPP_INTERNAL_ERROR);
+ return;
+ }
+
+ job->dtype = dtype;
+ job->attrs = con->request;
+ con->request = NULL;
+
+ /*
+ * Copy the rest of the job info...
+ */
+
+ strlcpy(job->title, title, sizeof(job->title));
+
+ attr = ippFindAttribute(job->attrs, "requesting-user-name", IPP_TAG_NAME);
+
+ if (con->username[0])
+ strlcpy(job->username, con->username, sizeof(job->username));
+ else if (attr != NULL)
+ {
+ LogMessage(L_DEBUG, "print_job: requesting-user-name = \'%s\'",
+ attr->values[0].string.text);
+
+ strlcpy(job->username, attr->values[0].string.text, sizeof(job->username));
+ }
+ else
+ strcpy(job->username, "anonymous");
+
+ if (attr == NULL)
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-originating-user-name",
+ NULL, job->username);
+ else
+ {
+ attr->group_tag = IPP_TAG_JOB;
+ free(attr->name);
+ attr->name = strdup("job-originating-user-name");
+ }
+
+ /*
+ * Add remaining job attributes...
+ */
+
+ if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name",
+ IPP_TAG_ZERO)) != NULL)
+ {
+ /*
+ * Request contains a job-originating-host-name attribute; validate it...
+ */
+
+ if (attr->value_tag != IPP_TAG_NAME ||
+ attr->num_values != 1 ||
+ strcmp(con->http.hostname, "localhost") != 0)
+ {
+ /*
+ * Can't override the value if we aren't connected via localhost.
+ * Also, we can only have 1 value and it must be a name value.
+ */
+
+ int i; /* Looping var */
+
+ switch (attr->value_tag)
+ {
+ case IPP_TAG_STRING :
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ /*
+ * Free old strings...
+ */
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ free(attr->values[i].string.text);
+ attr->values[i].string.text = NULL;
+ if (attr->values[i].string.charset)
+ {
+ free(attr->values[i].string.charset);
+ attr->values[i].string.charset = NULL;
+ }
+ }
+
+ default :
+ break;
+ }
+
+ /*
+ * Use the default connection hostname instead...
+ */
+
+ attr->value_tag = IPP_TAG_NAME;
+ attr->num_values = 1;
+ attr->values[0].string.text = strdup(con->http.hostname);
+ }
+ }
+ else
+ {
+ /*
+ * No job-originating-host-name attribute, so use the hostname from
+ * the connection...
+ */
+
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME,
+ "job-originating-host-name", NULL, con->http.hostname);
+ }
+
+ ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
+ job->state = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_ENUM,
+ "job-state", IPP_JOB_PENDING);
+ job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+ "job-media-sheets-completed", 0);
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL,
+ printer_uri);
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
+ title);
+
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) == NULL)
+ attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+ "job-k-octets", 0);
+
+ if (stat(con->filename, &fileinfo))
+ kbytes = 0;
+ else
+ kbytes = (fileinfo.st_size + 1023) / 1024;
+
+ UpdateQuota(printer, job->username, 0, kbytes);
+ attr->values[0].integer += kbytes;
+
+ ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation",
+ time(NULL));
+ attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+ "time-at-processing", 0);
+ attr->value_tag = IPP_TAG_NOVALUE;
+ attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
+ "time-at-completed", 0);
+ attr->value_tag = IPP_TAG_NOVALUE;
+
+ if ((attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+ if (attr == NULL)
+ attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-hold-until", NULL, "no-hold");
+
+ if (attr != NULL && strcmp(attr->values[0].string.text, "no-hold") != 0 &&
+ !(printer->type & CUPS_PRINTER_REMOTE))
+ {
+ /*
+ * Hold job until specified time...
+ */
+
+ job->state->values[0].integer = IPP_JOB_HELD;
+ SetJobHoldUntil(job->id, attr->values[0].string.text);
+ }
+
+ if (!(printer->type & CUPS_PRINTER_REMOTE) || Classification[0])
+ {
+ /*
+ * Add job sheets options...
+ */
+
+ if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) == NULL)
+ {
+ LogMessage(L_DEBUG, "Adding default job-sheets values \"%s,%s\"...",
+ printer->job_sheets[0], printer->job_sheets[1]);
+
+ attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets",
+ 2, NULL, NULL);
+ attr->values[0].string.text = strdup(printer->job_sheets[0]);
+ attr->values[1].string.text = strdup(printer->job_sheets[1]);
+ }
+
+ job->job_sheets = attr;
+
+ /*
+ * Enforce classification level if set...
+ */
+
+ if (Classification[0])
+ {
+ if (ClassifyOverride)
+ {
+ if (strcmp(attr->values[0].string.text, "none") == 0 &&
+ (attr->num_values == 1 ||
+ strcmp(attr->values[1].string.text, "none") == 0))
+ {
+ /*
+ * Force the leading banner to have the classification on it...
+ */
+
+ free(attr->values[0].string.text);
+ attr->values[0].string.text = strdup(Classification);
+ }
+ else if (attr->num_values == 2 &&
+ strcmp(attr->values[0].string.text, attr->values[1].string.text) != 0 &&
+ strcmp(attr->values[0].string.text, "none") != 0 &&
+ strcmp(attr->values[1].string.text, "none") != 0)
+ {
+ /*
+ * Can't put two different security markings on the same document!
+ */
+
+ free(attr->values[1].string.text);
+ attr->values[1].string.text = strdup(attr->values[0].string.text);
+ }
+ }
+ else if (strcmp(attr->values[0].string.text, Classification) != 0 &&
+ (attr->num_values == 1 ||
+ strcmp(attr->values[1].string.text, Classification) != 0))
+ {
+ /*
+ * Force the leading banner to have the classification on it...
+ */
+
+ free(attr->values[0].string.text);
+ attr->values[0].string.text = strdup(Classification);
+ }
+ }
+
+ /*
+ * Add the starting sheet...
+ */
+
+ if (!(printer->type & CUPS_PRINTER_REMOTE))
+ {
+ kbytes = copy_banner(con, job, attr->values[0].string.text);
+
+ UpdateQuota(printer, job->username, 0, kbytes);
+ }
+ }
+ else if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL)
+ job->sheets = attr;
+
+ /*
+ * Add the job file...
+ */
+
+ if (add_file(con, job, filetype))
+ return;
+
+ snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id,
+ job->num_files);
+ rename(con->filename, filename);
+ con->filename[0] = '\0';
+
+ /*
+ * See if we need to add the ending sheet...
+ */
+
+ if (!(printer->type & CUPS_PRINTER_REMOTE) && attr->num_values > 1)
+ {
+ /*
+ * Yes...
+ */
+
+ kbytes = copy_banner(con, job, attr->values[1].string.text);
+ UpdateQuota(printer, job->username, 0, kbytes);
+ }
+
+ /*
+ * Log and save the job...
+ */
+
+ LogMessage(L_INFO, "Job %d queued on \'%s\' by \'%s\'.", job->id,
+ job->dest, job->username);
+ LogMessage(L_DEBUG, "Job %d hold_until = %d", job->id, (int)job->hold_until);
+
+ SaveJob(job->id);
+
+ /*
+ * Start the job if possible...
+ */
+
+ CheckJobs();
+
+ /*
+ * Fill in the response info...
+ */
+
+ snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName,
+ ntohs(con->http.hostaddr.sin_port), job->id);
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL, job_uri);
+
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
+
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
+ job->state->values[0].integer);
+ add_job_state_reasons(con, job);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'read_ps_job_ticket()' - Reads a job ticket embedded in a PS file.
+ *
+ * This function only gets called when printing a single PostScript
+ * file using the Print-Job operation. It doesn't work for Create-Job +
+ * Send-File, since the job attributes need to be set at job creation
+ * time for banners to work. The embedded PS job ticket stuff is here
+ * only to allow the Windows printer driver for CUPS to pass in JCL
+ * options and IPP attributes which otherwise would be lost.
+ *
+ * The format of a PS job ticket is simple:
+ *
+ * %cupsJobTicket: attr1=value1 attr2=value2 ... attrN=valueN
+ *
+ * %cupsJobTicket: attr1=value1
+ * %cupsJobTicket: attr2=value2
+ * ...
+ * %cupsJobTicket: attrN=valueN
+ *
+ * Job ticket lines must appear immediately after the first line that
+ * specifies PostScript format (%!PS-Adobe-3.0), and CUPS will stop
+ * looking for job ticket info when it finds a line that does not begin
+ * with "%cupsJobTicket:".
+ *
+ * The maximum length of a job ticket line, including the prefix, is
+ * 255 characters to conform with the Adobe DSC. This function assumes
+ * that job ticket lines end with CR LF or LF; CR alone is not accepted.
+ *
+ * Read-only attributes are rejected with a notice to the error log in
+ * case a malicious user tries anything. Since the job ticket is read
+ * prior to attribute validation in print_job(), job ticket attributes
+ * will go through the same validation as IPP attributes...
+ */
+
+static void
+read_ps_job_ticket(client_t *con) /* I - Client connection */
+{
+ FILE *fp; /* File to read from */
+ char line[256]; /* Line in file */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ ipp_t *ticket; /* New attributes */
+ ipp_attribute_t *attr, /* Current attribute */
+ *attr2, /* Job attribute */
+ *prev2; /* Previous job attribute */
+
+
+ /*
+ * First open the print file...
+ */
+
+ if ((fp = fopen(con->filename, "r")) == NULL)
+ {
+ LogMessage(L_ERROR, "read_ps_job_ticket: Unable to open PostScript print file - %s",
+ strerror(errno));
+ return;
+ }
+
+ /*
+ * Skip the first line...
+ */
+
+ if (!fgets(line, sizeof(line), fp))
+ {
+ LogMessage(L_ERROR, "read_ps_job_ticket: Unable to read from PostScript print file - %s",
+ strerror(ferror(fp)));
+ fclose(fp);
+ return;
+ }
+
+ if (strncmp(line, "%!PS-Adobe-", 11) != 0)
+ {
+ /*
+ * Not a DSC-compliant file, so no job ticket info will be available...
+ */
+
+ fclose(fp);
+ return;
+ }
+
+ /*
+ * Read job ticket info from the file...
+ */
+
+ num_options = 0;
+ options = NULL;
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Stop at the first non-ticket line...
+ */
+
+ if (strncmp(line, "%cupsJobTicket:", 15) != 0)
+ break;
+
+ /*
+ * Add the options to the option array...
+ */
+
+ num_options = cupsParseOptions(line + 15, num_options, &options);
+ }
+
+ /*
+ * Done with the file; see if we have any options...
+ */
+
+ fclose(fp);
+
+ if (num_options == 0)
+ return;
+
+ /*
+ * OK, convert the options to an attribute list, and apply them to
+ * the request...
+ */
+
+ ticket = ippNew();
+ cupsEncodeOptions(ticket, num_options, options);
+
+ /*
+ * See what the user wants to change.
+ */
+
+ for (attr = ticket->attrs; attr != NULL; attr = attr->next)
+ {
+ if (attr->group_tag != IPP_TAG_JOB || !attr->name)
+ continue;
+
+ if (strcmp(attr->name, "job-originating-host-name") == 0 ||
+ strcmp(attr->name, "job-originating-user-name") == 0 ||
+ strcmp(attr->name, "job-media-sheets-completed") == 0 ||
+ strcmp(attr->name, "job-k-octets") == 0 ||
+ strcmp(attr->name, "job-id") == 0 ||
+ strncmp(attr->name, "job-state", 9) == 0 ||
+ strncmp(attr->name, "time-at-", 8) == 0)
+ continue; /* Read-only attrs */
+
+ if ((attr2 = ippFindAttribute(con->request, attr->name, IPP_TAG_ZERO)) != NULL)
+ {
+ /*
+ * Some other value; first free the old value...
+ */
+
+ for (prev2 = con->request->attrs; prev2 != NULL; prev2 = prev2->next)
+ if (prev2->next == attr2)
+ break;
+
+ if (prev2)
+ prev2->next = attr2->next;
+ else
+ con->request->attrs = attr2->next;
+
+ _ipp_free_attr(attr2);
+ }
+
+ /*
+ * Add new option by copying it...
+ */
+
+ copy_attribute(con->request, attr, 0);
+ }
+
+ /*
+ * Then free the attribute list and option array...
+ */
+
+ ippDelete(ticket);
+ cupsFreeOptions(num_options, options);
+}
+
+
+/*
+ * 'reject_jobs()' - Reject print jobs to a printer.
+ */
+
+static void
+reject_jobs(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer or class URI */
+{
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ const char *name; /* Printer name */
+ printer_t *printer; /* Printer data */
+ ipp_attribute_t *attr; /* printer-state-message text */
+
+
+ LogMessage(L_DEBUG2, "reject_jobs(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ LogMessage(L_ERROR, "reject_jobs: admin request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((name = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "reject_jobs: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Reject jobs sent to the printer...
+ */
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ printer = FindClass(name);
+ else
+ printer = FindPrinter(name);
+
+ printer->accepting = 0;
+
+ if ((attr = ippFindAttribute(con->request, "printer-state-message",
+ IPP_TAG_TEXT)) == NULL)
+ strcpy(printer->state_message, "Rejecting Jobs");
+ else
+ strlcpy(printer->state_message, attr->values[0].string.text,
+ sizeof(printer->state_message));
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ {
+ SaveAllClasses();
+
+ LogMessage(L_INFO, "Class \'%s\' rejecting jobs (\'%s\').", name,
+ con->username);
+ }
+ else
+ {
+ SaveAllPrinters();
+
+ LogMessage(L_INFO, "Printer \'%s\' rejecting jobs (\'%s\').", name,
+ con->username);
+ }
+
+ /*
+ * Everything was ok, so return OK status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'release_job()' - Release a held print job.
+ */
+
+static void
+release_job(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Job or Printer URI */
+{
+ ipp_attribute_t *attr; /* Current attribute */
+ int jobid; /* Job ID */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ job_t *job; /* Job information */
+
+
+ LogMessage(L_DEBUG2, "release_job(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Verify that the POST operation was done to a valid URI.
+ */
+
+ if (strncmp(con->uri, "/classes/", 9) != 0 &&
+ strncmp(con->uri, "/jobs/", 5) != 0 &&
+ strncmp(con->uri, "/printers/", 10) != 0)
+ {
+ LogMessage(L_ERROR, "release_job: release request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * See if we have a job URI or a printer URI...
+ */
+
+ if (strcmp(uri->name, "printer-uri") == 0)
+ {
+ /*
+ * Got a printer URI; see if we also have a job-id attribute...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "job-id", IPP_TAG_INTEGER)) == NULL)
+ {
+ LogMessage(L_ERROR, "release_job: got a printer-uri attribute but no job-id!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = attr->values[0].integer;
+ }
+ else
+ {
+ /*
+ * Got a job URI; parse it to get the job ID...
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (strncmp(resource, "/jobs/", 6) != 0)
+ {
+ /*
+ * Not a valid URI!
+ */
+
+ LogMessage(L_ERROR, "release_job: bad job-uri attribute \'%s\'!",
+ uri->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = atoi(resource + 6);
+ }
+
+ /*
+ * See if the job exists...
+ */
+
+ if ((job = FindJob(jobid)) == NULL)
+ {
+ /*
+ * Nope - return a "not found" error...
+ */
+
+ LogMessage(L_ERROR, "release_job: job #%d doesn't exist!", jobid);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * See if job is "held"...
+ */
+
+ if (job->state->values[0].integer != IPP_JOB_HELD)
+ {
+ /*
+ * Nope - return a "not possible" error...
+ */
+
+ LogMessage(L_ERROR, "release_job: job #%d is not held!", jobid);
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ /*
+ * See if the job is owned by the requesting user...
+ */
+
+ if (!validate_user(con, job->username, username, sizeof(username)))
+ {
+ LogMessage(L_ERROR, "release_job: \"%s\" not authorized to release job id %d owned by \"%s\"!",
+ username, jobid, job->username);
+ send_ipp_error(con, IPP_FORBIDDEN);
+ return;
+ }
+
+ /*
+ * Reset the job-hold-until value to "no-hold"...
+ */
+
+ if ((attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+
+ if (attr != NULL)
+ {
+ free(attr->values[0].string.text);
+ attr->value_tag = IPP_TAG_KEYWORD;
+ attr->values[0].string.text = strdup("no-hold");
+ }
+
+ /*
+ * Release the job and return...
+ */
+
+ ReleaseJob(jobid);
+
+ LogMessage(L_INFO, "Job %d was released by \'%s\'.", jobid, username);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'restart_job()' - Restart an old print job.
+ */
+
+static void
+restart_job(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Job or Printer URI */
+{
+ ipp_attribute_t *attr; /* Current attribute */
+ int jobid; /* Job ID */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ job_t *job; /* Job information */
+
+
+ LogMessage(L_DEBUG2, "restart_job(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Verify that the POST operation was done to a valid URI.
+ */
+
+ if (strncmp(con->uri, "/classes/", 9) != 0 &&
+ strncmp(con->uri, "/jobs/", 5) != 0 &&
+ strncmp(con->uri, "/printers/", 10) != 0)
+ {
+ LogMessage(L_ERROR, "restart_job: restart request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * See if we have a job URI or a printer URI...
+ */
+
+ if (strcmp(uri->name, "printer-uri") == 0)
+ {
+ /*
+ * Got a printer URI; see if we also have a job-id attribute...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "job-id", IPP_TAG_INTEGER)) == NULL)
+ {
+ LogMessage(L_ERROR, "restart_job: got a printer-uri attribute but no job-id!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = attr->values[0].integer;
+ }
+ else
+ {
+ /*
+ * Got a job URI; parse it to get the job ID...
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (strncmp(resource, "/jobs/", 6) != 0)
+ {
+ /*
+ * Not a valid URI!
+ */
+
+ LogMessage(L_ERROR, "restart_job: bad job-uri attribute \'%s\'!",
+ uri->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = atoi(resource + 6);
+ }
+
+ /*
+ * See if the job exists...
+ */
+
+ if ((job = FindJob(jobid)) == NULL)
+ {
+ /*
+ * Nope - return a "not found" error...
+ */
+
+ LogMessage(L_ERROR, "restart_job: job #%d doesn't exist!", jobid);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * See if job is in any of the "completed" states...
+ */
+
+ if (job->state->values[0].integer <= IPP_JOB_PROCESSING)
+ {
+ /*
+ * Nope - return a "not possible" error...
+ */
+
+ LogMessage(L_ERROR, "restart_job: job #%d is not complete!", jobid);
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ /*
+ * See if we have retained the job files...
+ */
+
+ if (!JobFiles && job->state->values[0].integer > IPP_JOB_STOPPED)
+ {
+ /*
+ * Nope - return a "not possible" error...
+ */
+
+ LogMessage(L_ERROR, "restart_job: job #%d cannot be restarted - no files!", jobid);
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ /*
+ * See if the job is owned by the requesting user...
+ */
+
+ if (!validate_user(con, job->username, username, sizeof(username)))
+ {
+ LogMessage(L_ERROR, "restart_job: \"%s\" not authorized to restart job id %d owned by \"%s\"!",
+ username, jobid, job->username);
+ send_ipp_error(con, IPP_FORBIDDEN);
+ return;
+ }
+
+ /*
+ * Restart the job and return...
+ */
+
+ RestartJob(jobid);
+
+ LogMessage(L_INFO, "Job %d was restarted by \'%s\'.", jobid, username);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'send_document()' - Send a file to a printer or class.
+ */
+
+static void
+send_document(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ ipp_attribute_t *attr; /* Current attribute */
+ ipp_attribute_t *format; /* Document-format attribute */
+ int jobid; /* Job ID number */
+ job_t *job; /* Current job */
+ char job_uri[HTTP_MAX_URI],
+ /* Job URI */
+ method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ mime_type_t *filetype; /* Type of file */
+ char super[MIME_MAX_SUPER],
+ /* Supertype of file */
+ type[MIME_MAX_TYPE],
+ /* Subtype of file */
+ mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE + 2];
+ /* Textual name of mime type */
+ char filename[1024]; /* Job filename */
+ printer_t *printer; /* Current printer */
+ struct stat fileinfo; /* File information */
+ int kbytes; /* Size of file */
+
+
+ LogMessage(L_DEBUG2, "send_document(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Verify that the POST operation was done to a valid URI.
+ */
+
+ if (strncmp(con->uri, "/classes/", 9) != 0 &&
+ strncmp(con->uri, "/jobs/", 6) != 0 &&
+ strncmp(con->uri, "/printers/", 10) != 0)
+ {
+ LogMessage(L_ERROR, "send_document: print request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * See if we have a job URI or a printer URI...
+ */
+
+ if (strcmp(uri->name, "printer-uri") == 0)
+ {
+ /*
+ * Got a printer URI; see if we also have a job-id attribute...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "job-id", IPP_TAG_INTEGER)) == NULL)
+ {
+ LogMessage(L_ERROR, "send_document: got a printer-uri attribute but no job-id!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = attr->values[0].integer;
+ }
+ else
+ {
+ /*
+ * Got a job URI; parse it to get the job ID...
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (strncmp(resource, "/jobs/", 6) != 0)
+ {
+ /*
+ * Not a valid URI!
+ */
+
+ LogMessage(L_ERROR, "send_document: bad job-uri attribute \'%s\'!",
+ uri->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = atoi(resource + 6);
+ }
+
+ /*
+ * See if the job exists...
+ */
+
+ if ((job = FindJob(jobid)) == NULL)
+ {
+ /*
+ * Nope - return a "not found" error...
+ */
+
+ LogMessage(L_ERROR, "send_document: job #%d doesn't exist!", jobid);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * See if the job is owned by the requesting user...
+ */
+
+ if (!validate_user(con, job->username, username, sizeof(username)))
+ {
+ LogMessage(L_ERROR, "send_document: \"%s\" not authorized to send document for job id %d owned by \"%s\"!",
+ username, jobid, job->username);
+ send_ipp_error(con, IPP_FORBIDDEN);
+ return;
+ }
+
+ /*
+ * OK, see if the client is sending the document compressed - CUPS
+ * doesn't support compression yet...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "compression", IPP_TAG_KEYWORD)) != NULL &&
+ strcmp(attr->values[0].string.text, "none") == 0)
+ {
+ LogMessage(L_ERROR, "send_document: Unsupported compression attribute %s!",
+ attr->values[0].string.text);
+ send_ipp_error(con, IPP_ATTRIBUTES);
+ ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
+ "compression", NULL, attr->values[0].string.text);
+ return;
+ }
+
+ /*
+ * Do we have a file to print?
+ */
+
+ if (con->filename[0] == '\0')
+ {
+ LogMessage(L_ERROR, "send_document: No file!?!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ /*
+ * Is it a format we support?
+ */
+
+ if ((format = ippFindAttribute(con->request, "document-format", IPP_TAG_MIMETYPE)) != NULL)
+ {
+ /*
+ * Grab format from client...
+ */
+
+ if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, type) != 2)
+ {
+ LogMessage(L_ERROR, "send_document: could not scan type \'%s\'!",
+ format->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+ }
+ else
+ {
+ /*
+ * No document format attribute? Auto-type it!
+ */
+
+ strcpy(super, "application");
+ strcpy(type, "octet-stream");
+ }
+
+ if (strcmp(super, "application") == 0 &&
+ strcmp(type, "octet-stream") == 0)
+ {
+ /*
+ * Auto-type the file...
+ */
+
+ LogMessage(L_DEBUG, "send_document: auto-typing file...");
+
+ filetype = mimeFileType(MimeDatabase, con->filename);
+
+ if (filetype != NULL)
+ {
+ /*
+ * Replace the document-format attribute value with the auto-typed one.
+ */
+
+ snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super,
+ filetype->type);
+
+ if (format != NULL)
+ {
+ free(format->values[0].string.text);
+ format->values[0].string.text = strdup(mimetype);
+ }
+ else
+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
+ "document-format", NULL, mimetype);
+ }
+ else
+ filetype = mimeType(MimeDatabase, super, type);
+ }
+ else
+ filetype = mimeType(MimeDatabase, super, type);
+
+ if (filetype == NULL)
+ {
+ LogMessage(L_ERROR, "send_document: Unsupported format \'%s/%s\'!",
+ super, type);
+ LogMessage(L_INFO, "Hint: Do you have the raw file printing rules enabled?");
+ send_ipp_error(con, IPP_DOCUMENT_FORMAT);
+
+ if (format)
+ ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
+ "document-format", NULL, format->values[0].string.text);
+
+ return;
+ }
+
+ LogMessage(L_DEBUG, "send_document: request file type is %s/%s.",
+ filetype->super, filetype->type);
+
+ /*
+ * Add the file to the job...
+ */
+
+ if (add_file(con, job, filetype))
+ return;
+
+ if (job->dtype & CUPS_PRINTER_CLASS)
+ printer = FindClass(job->dest);
+ else
+ printer = FindPrinter(job->dest);
+
+ if (stat(con->filename, &fileinfo))
+ kbytes = 0;
+ else
+ kbytes = (fileinfo.st_size + 1023) / 1024;
+
+ UpdateQuota(printer, job->username, 0, kbytes);
+
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
+ attr->values[0].integer += kbytes;
+
+ snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id,
+ job->num_files);
+ rename(con->filename, filename);
+
+ con->filename[0] = '\0';
+
+ LogMessage(L_INFO, "File of type %s/%s queued in job #%d by \'%s\'.",
+ filetype->super, filetype->type, job->id, job->username);
+
+ /*
+ * Start the job if this is the last document...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "last-document", IPP_TAG_BOOLEAN)) != NULL &&
+ attr->values[0].boolean)
+ {
+ /*
+ * See if we need to add the ending sheet...
+ */
+
+ if (printer != NULL && !(printer->type & CUPS_PRINTER_REMOTE) &&
+ (attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL &&
+ attr->num_values > 1)
+ {
+ /*
+ * Yes...
+ */
+
+ kbytes = copy_banner(con, job, attr->values[1].string.text);
+ UpdateQuota(printer, job->username, 0, kbytes);
+ }
+
+ if (job->state->values[0].integer == IPP_JOB_STOPPED)
+ job->state->values[0].integer = IPP_JOB_PENDING;
+ else if (job->state->values[0].integer == IPP_JOB_HELD)
+ {
+ if ((attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+
+ if (attr == NULL || strcmp(attr->values[0].string.text, "no-hold") == 0)
+ job->state->values[0].integer = IPP_JOB_PENDING;
+ }
+
+ SaveJob(job->id);
+ CheckJobs();
+ }
+ else
+ {
+ if ((attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+
+ if (attr == NULL || strcmp(attr->values[0].string.text, "no-hold") == 0)
+ {
+ job->state->values[0].integer = IPP_JOB_HELD;
+ job->hold_until = time(NULL) + 60;
+ SaveJob(job->id);
+ }
+ }
+
+ /*
+ * Fill in the response info...
+ */
+
+ snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName,
+ ntohs(con->http.hostaddr.sin_port), job->id);
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL,
+ job_uri);
+
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
+
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
+ job->state->values[0].integer);
+ add_job_state_reasons(con, job);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'send_ipp_error()' - Send an error status back to the IPP client.
+ */
+
+static void
+send_ipp_error(client_t *con, /* I - Client connection */
+ ipp_status_t status) /* I - IPP status code */
+{
+ LogMessage(L_DEBUG2, "send_ipp_error(%p[%d], %x)\n", con, con->http.fd,
+ status);
+
+ LogMessage(L_DEBUG, "Sending error: %s", ippErrorString(status));
+
+ con->response->request.status.status_code = status;
+
+ if (ippFindAttribute(con->response, "attributes-charset", IPP_TAG_ZERO) == NULL)
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, DefaultCharset);
+
+ if (ippFindAttribute(con->response, "attributes-natural-language",
+ IPP_TAG_ZERO) == NULL)
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, DefaultLanguage);
+}
+
+
+/*
+ * 'set_default()' - Set the default destination...
+ */
+
+static void
+set_default(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ const char *name; /* Printer name */
+
+
+ LogMessage(L_DEBUG2, "set_default(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ LogMessage(L_ERROR, "set_default: admin request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((name = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "set_default: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Set it as the default...
+ */
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ DefaultPrinter = FindClass(name);
+ else
+ DefaultPrinter = FindPrinter(name);
+
+ SaveAllPrinters();
+ SaveAllClasses();
+
+ LogMessage(L_INFO, "Default destination set to \'%s\' by \'%s\'.", name,
+ con->username);
+
+ /*
+ * Everything was ok, so return OK status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'set_job_attrs()' - Set job attributes.
+ */
+
+static void
+set_job_attrs(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Job URI */
+{
+ ipp_attribute_t *attr, /* Current attribute */
+ *attr2, /* Job attribute */
+ *prev2; /* Previous job attribute */
+ int jobid; /* Job ID */
+ job_t *job; /* Current job */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+
+
+ LogMessage(L_DEBUG2, "set_job_attrs(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * See if we have a job URI or a printer URI...
+ */
+
+ if (strcmp(uri->name, "printer-uri") == 0)
+ {
+ /*
+ * Got a printer URI; see if we also have a job-id attribute...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "job-id", IPP_TAG_INTEGER)) == NULL)
+ {
+ LogMessage(L_ERROR, "set_job_attrs: got a printer-uri attribute but no job-id!");
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = attr->values[0].integer;
+ }
+ else
+ {
+ /*
+ * Got a job URI; parse it to get the job ID...
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (strncmp(resource, "/jobs/", 6) != 0)
+ {
+ /*
+ * Not a valid URI!
+ */
+
+ LogMessage(L_ERROR, "set_job_attrs: bad job-uri attribute \'%s\'!\n",
+ uri->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ jobid = atoi(resource + 6);
+ }
+
+ /*
+ * See if the job exists...
+ */
+
+ if ((job = FindJob(jobid)) == NULL)
+ {
+ /*
+ * Nope - return a "not found" error...
+ */
+
+ LogMessage(L_ERROR, "set_job_attrs: job #%d doesn't exist!", jobid);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * See if the job has been completed...
+ */
+
+ if (job->state->values[0].integer > IPP_JOB_STOPPED)
+ {
+ /*
+ * Return a "not-possible" error...
+ */
+
+ LogMessage(L_ERROR, "set_job_attrs: job #%d is finished and cannot be altered!", jobid);
+ send_ipp_error(con, IPP_NOT_POSSIBLE);
+ return;
+ }
+
+ /*
+ * See if the job is owned by the requesting user...
+ */
+
+ if (!validate_user(con, job->username, username, sizeof(username)))
+ {
+ LogMessage(L_ERROR, "set_job_attrs: \"%s\" not authorized to alter job id %d owned by \"%s\"!",
+ username, jobid, job->username);
+ send_ipp_error(con, IPP_FORBIDDEN);
+ return;
+ }
+
+ /*
+ * See what the user wants to change.
+ */
+
+ for (attr = con->request->attrs; attr != NULL; attr = attr->next)
+ {
+ if (attr->group_tag != IPP_TAG_JOB || !attr->name)
+ continue;
+
+ if (strcmp(attr->name, "job-originating-host-name") == 0 ||
+ strcmp(attr->name, "job-originating-user-name") == 0 ||
+ strcmp(attr->name, "job-media-sheets-completed") == 0 ||
+ strcmp(attr->name, "job-k-octets") == 0 ||
+ strcmp(attr->name, "job-id") == 0 ||
+ strcmp(attr->name, "job-sheets") == 0 ||
+ strncmp(attr->name, "time-at-", 8) == 0)
+ continue; /* Read-only attrs */
+
+ if (strcmp(attr->name, "job-priority") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER &&
+ job->state->values[0].integer != IPP_JOB_PROCESSING)
+ {
+ /*
+ * Change the job priority
+ */
+
+ SetJobPriority(jobid, attr->values[0].integer);
+ }
+ else if ((attr2 = ippFindAttribute(job->attrs, attr->name, IPP_TAG_ZERO)) != NULL)
+ {
+ /*
+ * Some other value; first free the old value...
+ */
+
+ for (prev2 = job->attrs->attrs; prev2 != NULL; prev2 = prev2->next)
+ if (prev2->next == attr2)
+ break;
+
+ if (prev2)
+ prev2->next = attr2->next;
+ else
+ job->attrs->attrs = attr2->next;
+
+ _ipp_free_attr(attr2);
+
+ /*
+ * Then copy the attribute...
+ */
+
+ copy_attribute(job->attrs, attr, 0);
+
+ /*
+ * See if the job-name or job-hold-until is being changed.
+ */
+
+ if (strcmp(attr->name, "job-name") == 0)
+ strlcpy(job->title, attr->values[0].string.text, sizeof(job->title));
+ else if (strcmp(attr->name, "job-hold-until") == 0)
+ {
+ SetJobHoldUntil(job->id, attr->values[0].string.text);
+
+ if (strcmp(attr->values[0].string.text, "no-hold") == 0)
+ ReleaseJob(job->id);
+ else
+ HoldJob(job->id);
+ }
+ }
+ else if (attr->value_tag == IPP_TAG_DELETEATTR)
+ {
+ /*
+ * Delete the attribute...
+ */
+
+ for (attr2 = job->attrs->attrs, prev2 = NULL;
+ attr2 != NULL;
+ prev2 = attr2, attr2 = attr2->next)
+ if (attr2->name && strcmp(attr2->name, attr->name) == 0)
+ break;
+
+ if (attr2)
+ {
+ if (prev2)
+ prev2->next = attr2->next;
+ else
+ job->attrs->attrs = attr2->next;
+
+ _ipp_free_attr(attr2);
+ }
+ }
+ else
+ {
+ /*
+ * Add new option by copying it...
+ */
+
+ copy_attribute(job->attrs, attr, 0);
+ }
+ }
+
+ /*
+ * Save the job...
+ */
+
+ SaveJob(job->id);
+
+ /*
+ * Start jobs if possible...
+ */
+
+ CheckJobs();
+
+ /*
+ * Return with "everything is OK" status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'start_printer()' - Start a printer.
+ */
+
+static void
+start_printer(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ const char *name; /* Printer name */
+ printer_t *printer; /* Printer data */
+
+
+ LogMessage(L_DEBUG2, "start_printer(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ LogMessage(L_ERROR, "start_printer: admin request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((name = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "start_printer: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Start the printer...
+ */
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ printer = FindClass(name);
+ else
+ printer = FindPrinter(name);
+
+ StartPrinter(printer);
+
+ printer->state_message[0] = '\0';
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ {
+ SaveAllClasses();
+
+ LogMessage(L_INFO, "Class \'%s\' started by \'%s\'.", name,
+ con->username);
+ }
+ else
+ {
+ SaveAllPrinters();
+
+ LogMessage(L_INFO, "Printer \'%s\' started by \'%s\'.", name,
+ con->username);
+ }
+
+ CheckJobs();
+
+ /*
+ * Everything was ok, so return OK status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'stop_printer()' - Stop a printer.
+ */
+
+static void
+stop_printer(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ const char *name; /* Printer name */
+ printer_t *printer; /* Printer data */
+ ipp_attribute_t *attr; /* printer-state-message attribute */
+
+
+ LogMessage(L_DEBUG2, "stop_printer(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ LogMessage(L_ERROR, "stop_printer: admin request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((name = ValidateDest(host, resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "stop_printer: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Stop the printer...
+ */
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ printer = FindClass(name);
+ else
+ printer = FindPrinter(name);
+
+ StopPrinter(printer);
+
+ if ((attr = ippFindAttribute(con->request, "printer-state-message",
+ IPP_TAG_TEXT)) == NULL)
+ strcpy(printer->state_message, "Paused");
+ else
+ {
+ strlcpy(printer->state_message, attr->values[0].string.text,
+ sizeof(printer->state_message));
+ }
+
+ if (dtype & CUPS_PRINTER_CLASS)
+ {
+ SaveAllClasses();
+
+ LogMessage(L_INFO, "Class \'%s\' stopped by \'%s\'.", name,
+ con->username);
+ }
+ else
+ {
+ SaveAllPrinters();
+
+ LogMessage(L_INFO, "Printer \'%s\' stopped by \'%s\'.", name,
+ con->username);
+ }
+
+ /*
+ * Everything was ok, so return OK status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'validate_job()' - Validate printer options and destination.
+ */
+
+static void
+validate_job(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ ipp_attribute_t *attr; /* Current attribute */
+ ipp_attribute_t *format; /* Document-format attribute */
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ char super[MIME_MAX_SUPER],
+ /* Supertype of file */
+ type[MIME_MAX_TYPE];
+ /* Subtype of file */
+
+
+ LogMessage(L_DEBUG2, "validate_job(%p[%d], %s)\n", con, con->http.fd,
+ uri->values[0].string.text);
+
+ /*
+ * Verify that the POST operation was done to a valid URI.
+ */
+
+ if (strncmp(con->uri, "/classes/", 9) != 0 &&
+ strncmp(con->uri, "/printers/", 10) != 0)
+ {
+ LogMessage(L_ERROR, "validate_job: request on bad resource \'%s\'!",
+ con->uri);
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * OK, see if the client is sending the document compressed - CUPS
+ * doesn't support compression yet...
+ */
+
+ if ((attr = ippFindAttribute(con->request, "compression", IPP_TAG_KEYWORD)) != NULL &&
+ strcmp(attr->values[0].string.text, "none") == 0)
+ {
+ LogMessage(L_ERROR, "validate_job: Unsupported compression attribute %s!",
+ attr->values[0].string.text);
+ send_ipp_error(con, IPP_ATTRIBUTES);
+ ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
+ "compression", NULL, attr->values[0].string.text);
+ return;
+ }
+
+ /*
+ * Is it a format we support?
+ */
+
+ if ((format = ippFindAttribute(con->request, "document-format", IPP_TAG_MIMETYPE)) != NULL)
+ {
+ if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, type) != 2)
+ {
+ LogMessage(L_ERROR, "validate_job: could not scan type \'%s\'!\n",
+ format->values[0].string.text);
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ if ((strcmp(super, "application") != 0 ||
+ strcmp(type, "octet-stream") != 0) &&
+ mimeType(MimeDatabase, super, type) == NULL)
+ {
+ LogMessage(L_ERROR, "validate_job: Unsupported format \'%s\'!\n",
+ format->values[0].string.text);
+ LogMessage(L_INFO, "Hint: Do you have the raw file printing rules enabled?");
+ send_ipp_error(con, IPP_DOCUMENT_FORMAT);
+ ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
+ "document-format", NULL, format->values[0].string.text);
+ return;
+ }
+ }
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if (ValidateDest(host, resource, &dtype) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ LogMessage(L_ERROR, "validate_job: resource name \'%s\' no good!", resource);
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Everything was ok, so return OK status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'validate_user()' - Validate the user for the request.
+ */
+
+static int /* O - 1 if permitted, 0 otherwise */
+validate_user(client_t *con, /* I - Client connection */
+ const char *owner, /* I - Owner of job/resource */
+ char *username, /* O - Authenticated username */
+ int userlen) /* I - Length of username */
+{
+ int i, j; /* Looping vars */
+ ipp_attribute_t *attr; /* requesting-user-name attribute */
+ struct passwd *user; /* User info */
+ struct group *group; /* System group info */
+ char junk[33]; /* MD5 password (not used) */
+
+
+ LogMessage(L_DEBUG2, "validate_user(%p[%d], \"%s\", %p, %d)\n",
+ con, con->http.fd, owner, username, userlen);
+
+ /*
+ * Validate input...
+ */
+
+ if (con == NULL || owner == NULL || username == NULL || userlen <= 0)
+ return (0);
+
+ /*
+ * Get the best authenticated username that is available.
+ */
+
+ if (con->username[0])
+ strlcpy(username, con->username, userlen);
+ else if ((attr = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME)) != NULL)
+ strlcpy(username, attr->values[0].string.text, userlen);
+ else
+ strlcpy(username, "anonymous", userlen);
+
+ /*
+ * Check the username against the owner...
+ */
+
+ if (strcasecmp(username, owner) != 0 && strcasecmp(username, "root") != 0)
+ {
+ /*
+ * Not the owner or root; check to see if the user is a member of the
+ * system group...
+ */
+
+ user = getpwnam(username);
+ endpwent();
+
+ for (i = 0, j = 0, group = NULL; i < NumSystemGroups; i ++)
+ {
+ group = getgrnam(SystemGroups[i]);
+ endgrent();
+
+ if (group != NULL)
+ {
+ for (j = 0; group->gr_mem[j]; j ++)
+ if (strcasecmp(username, group->gr_mem[j]) == 0)
+ break;
+
+ if (group->gr_mem[j])
+ break;
+ }
+ else
+ j = 0;
+ }
+
+ if (user == NULL || group == NULL ||
+ (group->gr_mem[j] == NULL && group->gr_gid != user->pw_gid))
+ {
+ /*
+ * Username not found, group not found, or user is not part of the
+ * system group... Check for a user and group in the MD5 password
+ * file...
+ */
+
+ for (i = 0; i < NumSystemGroups; i ++)
+ if (GetMD5Passwd(username, SystemGroups[i], junk) != NULL)
+ return (1);
+
+ /*
+ * Nope, not an MD5 user, either. Return 0 indicating no-go...
+ */
+
+ return (0);
+ }
+ }
+
+ return (1);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/job.c b/scheduler/job.c
new file mode 100644
index 000000000..d427b74a5
--- /dev/null
+++ b/scheduler/job.c
@@ -0,0 +1,3165 @@
+/*
+ * "$Id$"
+ *
+ * Job management routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * AddJob() - Add a new job to the job queue...
+ * CancelJob() - Cancel the specified print job.
+ * CancelJobs() - Cancel all jobs on the given printer or class.
+ * CheckJobs() - Check the pending jobs and start any if the
+ * destination is available.
+ * CleanJobs() - Clean out old jobs.
+ * FreeAllJobs() - Free all jobs from memory.
+ * FindJob() - Find the specified job.
+ * GetPrinterJobCount() - Get the number of pending, processing,
+ * or held jobs in a printer or class.
+ * GetUserJobCount() - Get the number of pending, processing,
+ * or held jobs for a user.
+ * HoldJob() - Hold the specified job.
+ * LoadAllJobs() - Load all jobs from disk.
+ * LoadJob() - Load a job from disk.
+ * MoveJob() - Move the specified job to a different
+ * destination.
+ * ReleaseJob() - Release the specified job.
+ * RestartJob() - Restart the specified job.
+ * SaveJob() - Save a job to disk.
+ * SetJobHoldUntil() - Set the hold time for a job...
+ * SetJobPriority() - Set the priority of a job, moving it up/down
+ * in the list as needed.
+ * StartJob() - Start a print job.
+ * StopAllJobs() - Stop all print jobs.
+ * StopJob() - Stop a print job.
+ * UpdateJob() - Read a status update from a job's filters.
+ * ipp_read_file() - Read an IPP request from a file.
+ * ipp_write_file() - Write an IPP request to a file.
+ * start_process() - Start a background process.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+#include <grp.h>
+
+
+/*
+ * Local functions...
+ */
+
+static ipp_state_t ipp_read_file(const char *filename, ipp_t *ipp);
+static ipp_state_t ipp_write_file(const char *filename, ipp_t *ipp);
+static void set_time(job_t *job, const char *name);
+static int start_process(const char *command, char *argv[],
+ char *envp[], int in, int out, int err,
+ int root, int *pid);
+
+
+/*
+ * 'AddJob()' - Add a new job to the job queue...
+ */
+
+job_t * /* O - New job record */
+AddJob(int priority, /* I - Job priority */
+ const char *dest) /* I - Job destination */
+{
+ job_t *job, /* New job record */
+ *current, /* Current job in queue */
+ *prev; /* Previous job in queue */
+
+
+ job = calloc(sizeof(job_t), 1);
+
+ job->id = NextJobId ++;
+ job->priority = priority;
+ strlcpy(job->dest, dest, sizeof(job->dest));
+
+ NumJobs ++;
+
+ for (current = Jobs, prev = NULL;
+ current != NULL;
+ prev = current, current = current->next)
+ if (job->priority > current->priority)
+ break;
+
+ job->next = current;
+ if (prev != NULL)
+ prev->next = job;
+ else
+ Jobs = job;
+
+ return (job);
+}
+
+
+/*
+ * 'CancelJob()' - Cancel the specified print job.
+ */
+
+void
+CancelJob(int id, /* I - Job to cancel */
+ int purge) /* I - Purge jobs? */
+{
+ int i; /* Looping var */
+ job_t *current, /* Current job */
+ *prev; /* Previous job in list */
+ char filename[1024]; /* Job filename */
+
+
+ LogMessage(L_DEBUG, "CancelJob: id = %d", id);
+
+ for (current = Jobs, prev = NULL; current != NULL; prev = current, current = current->next)
+ if (current->id == id)
+ {
+ /*
+ * Stop any processes that are working on the current...
+ */
+
+ DEBUG_puts("CancelJob: found job in list.");
+
+ if (current->state->values[0].integer == IPP_JOB_PROCESSING)
+ StopJob(current->id, 0);
+
+ current->state->values[0].integer = IPP_JOB_CANCELLED;
+
+ set_time(current, "time-at-completed");
+
+ /*
+ * Remove the print file for good if we aren't preserving jobs or
+ * files...
+ */
+
+ current->current_file = 0;
+
+ if (!JobHistory || !JobFiles || purge ||
+ (current->dtype & CUPS_PRINTER_REMOTE))
+ for (i = 1; i <= current->num_files; i ++)
+ {
+ snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
+ current->id, i);
+ unlink(filename);
+ }
+
+ if (JobHistory && !purge && !(current->dtype & CUPS_PRINTER_REMOTE))
+ {
+ /*
+ * Save job state info...
+ */
+
+ SaveJob(current->id);
+ }
+ else
+ {
+ /*
+ * Remove the job info file...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot,
+ current->id);
+ unlink(filename);
+
+ /*
+ * Update pointers if we aren't preserving jobs...
+ */
+
+ if (prev == NULL)
+ Jobs = current->next;
+ else
+ prev->next = current->next;
+
+ /*
+ * Free all memory used...
+ */
+
+ if (current->attrs != NULL)
+ ippDelete(current->attrs);
+
+ free(current->filetypes);
+
+ free(current);
+
+ NumJobs --;
+ }
+
+ return;
+ }
+}
+
+
+/*
+ * 'CancelJobs()' - Cancel all jobs on the given printer or class.
+ */
+
+void
+CancelJobs(const char *dest) /* I - Destination to cancel */
+{
+ job_t *current; /* Current job */
+
+
+ for (current = Jobs; current != NULL;)
+ if (strcmp(current->dest, dest) == 0)
+ {
+ /*
+ * Cancel all jobs matching this destination...
+ */
+
+ CancelJob(current->id, 1);
+
+ current = Jobs;
+ }
+ else
+ current = current->next;
+
+ CheckJobs();
+}
+
+
+/*
+ * 'CheckJobs()' - Check the pending jobs and start any if the destination
+ * is available.
+ */
+
+void
+CheckJobs(void)
+{
+ job_t *current, /* Current job in queue */
+ *next; /* Next job in queue */
+ printer_t *printer, /* Printer destination */
+ *pclass; /* Printer class destination */
+
+
+ DEBUG_puts("CheckJobs()");
+
+ for (current = Jobs; current != NULL; current = next)
+ {
+ /*
+ * Save next pointer in case the job is cancelled en-route.
+ */
+
+ next = current->next;
+
+ /*
+ * Start held jobs if they are ready...
+ */
+
+ if (current->state->values[0].integer == IPP_JOB_HELD &&
+ current->hold_until &&
+ current->hold_until < time(NULL))
+ current->state->values[0].integer = IPP_JOB_PENDING;
+
+ /*
+ * Start pending jobs if the destination is available...
+ */
+
+ if (current->state->values[0].integer == IPP_JOB_PENDING)
+ {
+ if ((pclass = FindClass(current->dest)) != NULL)
+ {
+ /*
+ * If the class is remote, just pass it to the remote server...
+ */
+
+ if (pclass->type & CUPS_PRINTER_REMOTE)
+ printer = pclass;
+ else if (pclass->state != IPP_PRINTER_STOPPED)
+ printer = FindAvailablePrinter(current->dest);
+ else
+ printer = NULL;
+ }
+ else
+ printer = FindPrinter(current->dest);
+
+ if (printer != NULL && (printer->type & CUPS_PRINTER_IMPLICIT))
+ {
+ /*
+ * Handle implicit classes...
+ */
+
+ pclass = printer;
+
+ if (pclass->state != IPP_PRINTER_STOPPED)
+ printer = FindAvailablePrinter(current->dest);
+ else
+ printer = NULL;
+ }
+
+ if (printer == NULL && pclass == NULL)
+ {
+ /*
+ * Whoa, the printer and/or class for this destination went away;
+ * cancel the job...
+ */
+
+ LogMessage(L_WARN, "Printer/class %s has gone away; cancelling job %d!",
+ current->dest, current->id);
+ CancelJob(current->id, 1);
+ }
+ else if (printer != NULL)
+ {
+ /*
+ * See if the printer is available or remote and not printing a job;
+ * if so, start the job...
+ */
+
+ if (printer->state == IPP_PRINTER_IDLE || /* Printer is idle */
+ ((printer->type & CUPS_PRINTER_REMOTE) && /* Printer is remote */
+ !printer->job)) /* and not printing a job */
+ StartJob(current->id, printer);
+ }
+ }
+ }
+}
+
+
+/*
+ * 'CleanJobs()' - Clean out old jobs.
+ */
+
+void
+CleanJobs(void)
+{
+ job_t *job, /* Current job */
+ *next; /* Next job */
+
+
+ if (MaxJobs == 0)
+ return;
+
+ for (job = Jobs; job && NumJobs >= MaxJobs; job = next)
+ {
+ next = job->next;
+
+ if (job->state->values[0].integer >= IPP_JOB_CANCELLED)
+ CancelJob(job->id, 1);
+ }
+}
+
+
+/*
+ * 'FreeAllJobs()' - Free all jobs from memory.
+ */
+
+void
+FreeAllJobs(void)
+{
+ job_t *job, /* Current job */
+ *next; /* Next job */
+
+
+ StopAllJobs();
+
+ for (job = Jobs; job; job = next)
+ {
+ next = job->next;
+
+ ippDelete(job->attrs);
+ free(job->filetypes);
+ free(job);
+ }
+
+ Jobs = NULL;
+}
+
+
+/*
+ * 'FindJob()' - Find the specified job.
+ */
+
+job_t * /* O - Job data */
+FindJob(int id) /* I - Job ID */
+{
+ job_t *current; /* Current job */
+
+
+ for (current = Jobs; current != NULL; current = current->next)
+ if (current->id == id)
+ break;
+
+ return (current);
+}
+
+
+/*
+ * 'GetPrinterJobCount()' - Get the number of pending, processing,
+ * or held jobs in a printer or class.
+ */
+
+int /* O - Job count */
+GetPrinterJobCount(const char *dest) /* I - Printer or class name */
+{
+ int count; /* Job count */
+ job_t *job; /* Current job */
+
+
+ for (job = Jobs, count = 0; job != NULL; job = job->next)
+ if (job->state->values[0].integer <= IPP_JOB_PROCESSING &&
+ strcasecmp(job->dest, dest) == 0)
+ count ++;
+
+ return (count);
+}
+
+
+/*
+ * 'GetUserJobCount()' - Get the number of pending, processing,
+ * or held jobs for a user.
+ */
+
+int /* O - Job count */
+GetUserJobCount(const char *username) /* I - Username */
+{
+ int count; /* Job count */
+ job_t *job; /* Current job */
+
+
+ for (job = Jobs, count = 0; job != NULL; job = job->next)
+ if (job->state->values[0].integer <= IPP_JOB_PROCESSING &&
+ strcmp(job->username, username) == 0)
+ count ++;
+
+ return (count);
+}
+
+
+/*
+ * 'HoldJob()' - Hold the specified job.
+ */
+
+void
+HoldJob(int id) /* I - Job ID */
+{
+ job_t *job; /* Job data */
+
+
+ LogMessage(L_DEBUG, "HoldJob: id = %d", id);
+
+ if ((job = FindJob(id)) == NULL)
+ return;
+
+ if (job->state->values[0].integer == IPP_JOB_PROCESSING)
+ StopJob(id, 0);
+
+ DEBUG_puts("HoldJob: setting state to held...");
+
+ job->state->values[0].integer = IPP_JOB_HELD;
+
+ SaveJob(id);
+
+ CheckJobs();
+}
+
+
+/*
+ * 'LoadAllJobs()' - Load all jobs from disk.
+ */
+
+void
+LoadAllJobs(void)
+{
+ DIR *dir; /* Directory */
+ DIRENT *dent; /* Directory entry */
+ char filename[1024]; /* Full filename of job file */
+ job_t *job, /* New job */
+ *current, /* Current job */
+ *prev; /* Previous job */
+ int jobid, /* Current job ID */
+ fileid; /* Current file ID */
+ ipp_attribute_t *attr; /* Job attribute */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ printer_t *p; /* Printer or class */
+ const char *dest; /* Destination */
+ mime_type_t **filetypes; /* New filetypes array */
+
+
+ /*
+ * First open the requests directory...
+ */
+
+ LogMessage(L_DEBUG, "LoadAllJobs: Scanning %s...", RequestRoot);
+
+ if ((dir = opendir(RequestRoot)) == NULL)
+ {
+ LogMessage(L_ERROR, "LoadAllJobs: Unable to open spool directory %s: %s",
+ RequestRoot, strerror(errno));
+ return;
+ }
+
+ /*
+ * Read all the c##### files...
+ */
+
+ while ((dent = readdir(dir)) != NULL)
+ if (NAMLEN(dent) == 6 && dent->d_name[0] == 'c')
+ {
+ /*
+ * Allocate memory for the job...
+ */
+
+ if ((job = calloc(sizeof(job_t), 1)) == NULL)
+ {
+ LogMessage(L_ERROR, "LoadAllJobs: Ran out of memory for jobs!");
+ closedir(dir);
+ return;
+ }
+
+ if ((job->attrs = ippNew()) == NULL)
+ {
+ free(job);
+ LogMessage(L_ERROR, "LoadAllJobs: Ran out of memory for job attributes!");
+ closedir(dir);
+ return;
+ }
+
+ /*
+ * Assign the job ID...
+ */
+
+ job->id = atoi(dent->d_name + 1);
+
+ LogMessage(L_DEBUG, "LoadAllJobs: Loading attributes for job %d...\n",
+ job->id);
+
+ if (job->id >= NextJobId)
+ NextJobId = job->id + 1;
+
+ /*
+ * Load the job control file...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/%s", RequestRoot, dent->d_name);
+ if (ipp_read_file(filename, job->attrs) != IPP_DATA)
+ {
+ LogMessage(L_ERROR, "LoadAllJobs: Unable to read job control file \"%s\"!",
+ filename);
+ ippDelete(job->attrs);
+ free(job);
+ unlink(filename);
+ continue;
+ }
+
+ job->state = ippFindAttribute(job->attrs, "job-state", IPP_TAG_ENUM);
+
+ if ((attr = ippFindAttribute(job->attrs, "job-printer-uri", IPP_TAG_URI)) == NULL)
+ {
+ LogMessage(L_ERROR, "LoadAllJobs: No job-printer-uri attribute in control file \"%s\"!",
+ filename);
+ ippDelete(job->attrs);
+ free(job);
+ unlink(filename);
+ continue;
+ }
+
+ httpSeparate(attr->values[0].string.text, method, username, host,
+ &port, resource);
+
+ if ((dest = ValidateDest(host, resource, &(job->dtype))) == NULL &&
+ job->state != NULL &&
+ job->state->values[0].integer <= IPP_JOB_PROCESSING)
+ {
+ /*
+ * Job queued on remote printer or class, so add it...
+ */
+
+ if (strncmp(resource, "/classes/", 9) == 0)
+ {
+ p = AddClass(resource + 9);
+ strcpy(p->make_model, "Remote Class on unknown");
+ }
+ else
+ {
+ p = AddPrinter(resource + 10);
+ strcpy(p->make_model, "Remote Printer on unknown");
+ }
+
+ p->state = IPP_PRINTER_STOPPED;
+ p->type |= CUPS_PRINTER_REMOTE;
+ p->browse_time = 2147483647;
+
+ strcpy(p->location, "Location Unknown");
+ strcpy(p->info, "No Information Available");
+ p->hostname[0] = '\0';
+
+ SetPrinterAttrs(p);
+ dest = p->name;
+ }
+
+ if (dest == NULL)
+ {
+ LogMessage(L_ERROR, "LoadAllJobs: Unable to queue job for destination \"%s\"!",
+ attr->values[0].string.text);
+ ippDelete(job->attrs);
+ free(job);
+ unlink(filename);
+ continue;
+ }
+
+ strlcpy(job->dest, dest, sizeof(job->dest));
+
+ job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed",
+ IPP_TAG_INTEGER);
+ job->job_sheets = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
+
+ attr = ippFindAttribute(job->attrs, "job-priority", IPP_TAG_INTEGER);
+ job->priority = attr->values[0].integer;
+
+ attr = ippFindAttribute(job->attrs, "job-name", IPP_TAG_NAME);
+ strlcpy(job->title, attr->values[0].string.text,
+ sizeof(job->title));
+
+ attr = ippFindAttribute(job->attrs, "job-originating-user-name", IPP_TAG_NAME);
+ strlcpy(job->username, attr->values[0].string.text,
+ sizeof(job->username));
+
+ /*
+ * Insert the job into the array, sorting by job priority and ID...
+ */
+
+ for (current = Jobs, prev = NULL;
+ current != NULL;
+ prev = current, current = current->next)
+ if (job->priority > current->priority)
+ break;
+ else if (job->priority == current->priority && job->id < current->id)
+ break;
+
+ job->next = current;
+ if (prev != NULL)
+ prev->next = job;
+ else
+ Jobs = job;
+
+ NumJobs ++;
+
+ /*
+ * Set the job hold-until time and state...
+ */
+
+ if (job->state->values[0].integer == IPP_JOB_HELD)
+ {
+ if ((attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD)) == NULL)
+ attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
+
+ if (attr == NULL)
+ job->state->values[0].integer = IPP_JOB_PENDING;
+ else
+ SetJobHoldUntil(job->id, attr->values[0].string.text);
+ }
+ else if (job->state->values[0].integer == IPP_JOB_PROCESSING)
+ job->state->values[0].integer = IPP_JOB_PENDING;
+ }
+
+ /*
+ * Read all the d##### files...
+ */
+
+ rewinddir(dir);
+
+ while ((dent = readdir(dir)) != NULL)
+ if (NAMLEN(dent) > 7 && dent->d_name[0] == 'd')
+ {
+ /*
+ * Find the job...
+ */
+
+ jobid = atoi(dent->d_name + 1);
+ fileid = atoi(dent->d_name + 7);
+
+ LogMessage(L_DEBUG, "LoadAllJobs: Auto-typing document file %s...",
+ dent->d_name);
+
+ snprintf(filename, sizeof(filename), "%s/%s", RequestRoot, dent->d_name);
+
+ if ((job = FindJob(jobid)) == NULL)
+ {
+ LogMessage(L_ERROR, "LoadAllJobs: Orphaned print file \"%s\"!",
+ filename);
+ unlink(filename);
+ continue;
+ }
+
+ if (fileid > job->num_files)
+ {
+ if (job->num_files == 0)
+ filetypes = (mime_type_t **)calloc(sizeof(mime_type_t *), fileid);
+ else
+ filetypes = (mime_type_t **)realloc(job->filetypes,
+ sizeof(mime_type_t *) * fileid);
+
+ if (filetypes == NULL)
+ {
+ LogMessage(L_ERROR, "LoadAllJobs: Ran out of memory for job file types!");
+ continue;
+ }
+
+ job->filetypes = filetypes;
+ job->num_files = fileid;
+ }
+
+ job->filetypes[fileid - 1] = mimeFileType(MimeDatabase, filename);
+
+ if (job->filetypes[fileid - 1] == NULL)
+ job->filetypes[fileid - 1] = mimeType(MimeDatabase, "application",
+ "vnd.cups-raw");
+ }
+
+ closedir(dir);
+
+ /*
+ * Clean out old jobs as needed...
+ */
+
+ CleanJobs();
+
+ /*
+ * Check to see if we need to start any jobs...
+ */
+
+ CheckJobs();
+}
+
+
+/*
+ * 'MoveJob()' - Move the specified job to a different destination.
+ */
+
+void
+MoveJob(int id, /* I - Job ID */
+ const char *dest) /* I - Destination */
+{
+ job_t *current;/* Current job */
+ ipp_attribute_t *attr; /* job-printer-uri attribute */
+ printer_t *p; /* Destination printer or class */
+
+
+ if ((p = FindPrinter(dest)) == NULL)
+ p = FindClass(dest);
+
+ if (p == NULL)
+ return;
+
+ for (current = Jobs; current != NULL; current = current->next)
+ if (current->id == id)
+ {
+ if (current->state->values[0].integer >= IPP_JOB_PROCESSING)
+ break;
+
+ strlcpy(current->dest, dest, sizeof(current->dest));
+ current->dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE |
+ CUPS_PRINTER_IMPLICIT);
+
+ if ((attr = ippFindAttribute(current->attrs, "job-printer-uri", IPP_TAG_URI)) != NULL)
+ {
+ free(attr->values[0].string.text);
+ attr->values[0].string.text = strdup(p->uri);
+ }
+
+ SaveJob(current->id);
+
+ return;
+ }
+}
+
+
+/*
+ * 'ReleaseJob()' - Release the specified job.
+ */
+
+void
+ReleaseJob(int id) /* I - Job ID */
+{
+ job_t *job; /* Job data */
+
+
+ LogMessage(L_DEBUG, "ReleaseJob: id = %d", id);
+
+ if ((job = FindJob(id)) == NULL)
+ return;
+
+ if (job->state->values[0].integer == IPP_JOB_HELD)
+ {
+ DEBUG_puts("ReleaseJob: setting state to pending...");
+
+ job->state->values[0].integer = IPP_JOB_PENDING;
+ SaveJob(id);
+ CheckJobs();
+ }
+}
+
+
+/*
+ * 'RestartJob()' - Restart the specified job.
+ */
+
+void
+RestartJob(int id) /* I - Job ID */
+{
+ job_t *job; /* Job data */
+
+
+ if ((job = FindJob(id)) == NULL)
+ return;
+
+ if (job->state->values[0].integer == IPP_JOB_STOPPED || JobFiles)
+ {
+ job->state->values[0].integer = IPP_JOB_PENDING;
+ SaveJob(id);
+ CheckJobs();
+ }
+}
+
+
+/*
+ * 'SaveJob()' - Save a job to disk.
+ */
+
+void
+SaveJob(int id) /* I - Job ID */
+{
+ job_t *job; /* Pointer to job */
+ char filename[1024]; /* Job control filename */
+
+
+ if ((job = FindJob(id)) == NULL)
+ return;
+
+ snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, id);
+ ipp_write_file(filename, job->attrs);
+}
+
+
+/*
+ * 'SetJobHoldUntil()' - Set the hold time for a job...
+ */
+
+void
+SetJobHoldUntil(int id, /* I - Job ID */
+ const char *when) /* I - When to resume */
+{
+ job_t *job; /* Pointer to job */
+ time_t curtime; /* Current time */
+ struct tm *curdate; /* Current date */
+ int hour; /* Hold hour */
+ int minute; /* Hold minute */
+ int second; /* Hold second */
+
+
+ LogMessage(L_DEBUG, "SetJobHoldUntil(%d, \"%s\")", id, when);
+
+ if ((job = FindJob(id)) == NULL)
+ return;
+
+ second = 0;
+
+ if (strcmp(when, "indefinite") == 0)
+ {
+ /*
+ * Hold indefinitely...
+ */
+
+ job->hold_until = 0;
+ }
+ else if (strcmp(when, "day-time") == 0)
+ {
+ /*
+ * Hold to 6am the next morning unless local time is < 6pm.
+ */
+
+ curtime = time(NULL);
+ curdate = localtime(&curtime);
+
+ if (curdate->tm_hour < 18)
+ job->hold_until = curtime;
+ else
+ job->hold_until = curtime +
+ ((29 - curdate->tm_hour) * 60 + 59 -
+ curdate->tm_min) * 60 + 60 - curdate->tm_sec;
+ }
+ else if (strcmp(when, "evening") == 0 || strcmp(when, "night") == 0)
+ {
+ /*
+ * Hold to 6pm unless local time is > 6pm or < 6am.
+ */
+
+ curtime = time(NULL);
+ curdate = localtime(&curtime);
+
+ if (curdate->tm_hour < 6 || curdate->tm_hour >= 18)
+ job->hold_until = curtime;
+ else
+ job->hold_until = curtime +
+ ((17 - curdate->tm_hour) * 60 + 59 -
+ curdate->tm_min) * 60 + 60 - curdate->tm_sec;
+ }
+ else if (strcmp(when, "second-shift") == 0)
+ {
+ /*
+ * Hold to 4pm unless local time is > 4pm.
+ */
+
+ curtime = time(NULL);
+ curdate = localtime(&curtime);
+
+ if (curdate->tm_hour >= 16)
+ job->hold_until = curtime;
+ else
+ job->hold_until = curtime +
+ ((15 - curdate->tm_hour) * 60 + 59 -
+ curdate->tm_min) * 60 + 60 - curdate->tm_sec;
+ }
+ else if (strcmp(when, "third-shift") == 0)
+ {
+ /*
+ * Hold to 12am unless local time is < 8am.
+ */
+
+ curtime = time(NULL);
+ curdate = localtime(&curtime);
+
+ if (curdate->tm_hour < 8)
+ job->hold_until = curtime;
+ else
+ job->hold_until = curtime +
+ ((23 - curdate->tm_hour) * 60 + 59 -
+ curdate->tm_min) * 60 + 60 - curdate->tm_sec;
+ }
+ else if (strcmp(when, "weekend") == 0)
+ {
+ /*
+ * Hold to weekend unless we are in the weekend.
+ */
+
+ curtime = time(NULL);
+ curdate = localtime(&curtime);
+
+ if (curdate->tm_wday == 0 || curdate->tm_wday == 6)
+ job->hold_until = curtime;
+ else
+ job->hold_until = curtime +
+ (((5 - curdate->tm_wday) * 24 +
+ (17 - curdate->tm_hour)) * 60 + 59 -
+ curdate->tm_min) * 60 + 60 - curdate->tm_sec;
+ }
+ else if (sscanf(when, "%d:%d:%d", &hour, &minute, &second) >= 2)
+ {
+ /*
+ * Hold to specified GMT time (HH:MM or HH:MM:SS)...
+ */
+
+ curtime = time(NULL);
+ curdate = gmtime(&curtime);
+
+ job->hold_until = curtime +
+ ((hour - curdate->tm_hour) * 60 + minute -
+ curdate->tm_min) * 60 + second - curdate->tm_sec;
+
+ /*
+ * Hold until next day as needed...
+ */
+
+ if (job->hold_until < curtime)
+ job->hold_until += 24 * 60 * 60 * 60;
+ }
+
+ LogMessage(L_DEBUG, "SetJobHoldUntil: hold_until = %d", (int)job->hold_until);
+}
+
+
+/*
+ * 'SetJobPriority()' - Set the priority of a job, moving it up/down in the
+ * list as needed.
+ */
+
+void
+SetJobPriority(int id, /* I - Job ID */
+ int priority) /* I - New priority (0 to 100) */
+{
+ job_t *job, /* Job to change */
+ *current, /* Current job */
+ *prev; /* Previous job */
+ ipp_attribute_t *attr; /* Job attribute */
+
+
+ /*
+ * Find the job...
+ */
+
+ for (current = Jobs, prev = NULL;
+ current != NULL;
+ prev = current, current = current->next)
+ if (current->id == id)
+ break;
+
+ if (current == NULL)
+ return;
+
+ /*
+ * Set the new priority...
+ */
+
+ job = current;
+ job->priority = priority;
+
+ if ((attr = ippFindAttribute(job->attrs, "job-priority", IPP_TAG_INTEGER)) != NULL)
+ attr->values[0].integer = priority;
+ else
+ ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority",
+ priority);
+
+ SaveJob(job->id);
+
+ /*
+ * See if we need to do any sorting...
+ */
+
+ if ((prev == NULL || job->priority < prev->priority) &&
+ (job->next == NULL || job->next->priority < job->priority))
+ return;
+
+ /*
+ * Remove the job from the list, and then insert it where it belongs...
+ */
+
+ if (prev == NULL)
+ Jobs = job->next;
+ else
+ prev->next = job->next;
+
+ for (current = Jobs, prev = NULL;
+ current != NULL;
+ prev = current, current = current->next)
+ if (job->priority > current->priority)
+ break;
+
+ job->next = current;
+ if (prev != NULL)
+ prev->next = job;
+ else
+ Jobs = job;
+}
+
+
+/*
+ * 'StartJob()' - Start a print job.
+ */
+
+void
+StartJob(int id, /* I - Job ID */
+ printer_t *printer) /* I - Printer to print job */
+{
+ job_t *current; /* Current job */
+ int i; /* Looping var */
+ int slot; /* Pipe slot */
+ int num_filters; /* Number of filters for job */
+ mime_filter_t *filters; /* Filters for job */
+ char method[255], /* Method for output */
+ *optptr; /* Pointer to options */
+ ipp_attribute_t *attr; /* Current attribute */
+ int pid; /* Process ID of new filter process */
+ int banner_page; /* 1 if banner page, 0 otherwise */
+ int statusfds[2], /* Pipes used between the filters and scheduler */
+ filterfds[2][2];/* Pipes used between the filters */
+ char *argv[8], /* Filter command-line arguments */
+ filename[1024], /* Job filename */
+ command[1024], /* Full path to filter/backend command */
+ jobid[255], /* Job ID string */
+ title[IPP_MAX_NAME],
+ /* Job title string */
+ copies[255], /* # copies string */
+ options[16384], /* Full list of options */
+ *envp[20], /* Environment variables */
+ path[1024], /* PATH environment variable */
+ language[255], /* LANG environment variable */
+ charset[255], /* CHARSET environment variable */
+ classification[1024],
+ /* CLASSIFICATION environment variable */
+ content_type[1024],
+ /* CONTENT_TYPE environment variable */
+ device_uri[1024],
+ /* DEVICE_URI environment variable */
+ ppd[1024], /* PPD environment variable */
+ class_name[255],
+ /* CLASS environment variable */
+ printer_name[255],
+ /* PRINTER environment variable */
+ root[1024], /* CUPS_SERVERROOT environment variable */
+ cache[255], /* RIP_MAX_CACHE environment variable */
+ tmpdir[1024], /* TMPDIR environment variable */
+ ldpath[1024], /* LD_LIBRARY_PATH environment variable */
+ nlspath[1024], /* NLSPATH environment variable */
+ datadir[1024], /* CUPS_DATADIR environment variable */
+ fontpath[1050]; /* CUPS_FONTPATH environment variable */
+
+
+ LogMessage(L_DEBUG, "StartJob(%d, %p)", id, printer);
+
+ for (current = Jobs; current != NULL; current = current->next)
+ if (current->id == id)
+ break;
+
+ if (current == NULL)
+ return;
+
+ LogMessage(L_DEBUG, "StartJob() id = %d, file = %d/%d", id,
+ current->current_file, current->num_files);
+
+ if (current->num_files == 0)
+ {
+ LogMessage(L_ERROR, "Job ID %d has no files! Cancelling it!", id);
+ CancelJob(id, 0);
+ return;
+ }
+
+ /*
+ * Figure out what filters are required to convert from
+ * the source to the destination type...
+ */
+
+ num_filters = 0;
+ current->cost = 0;
+
+ if (printer->type & CUPS_PRINTER_REMOTE)
+ {
+ /*
+ * Remote jobs go directly to the remote job...
+ */
+
+ filters = NULL;
+ }
+ else
+ {
+ /*
+ * Local jobs get filtered...
+ */
+
+ filters = mimeFilter(MimeDatabase, current->filetypes[current->current_file],
+ printer->filetype, &num_filters, MAX_FILTERS - 1);
+
+ if (num_filters == 0)
+ {
+ LogMessage(L_ERROR, "Unable to convert file %d to printable format for job %d!",
+ current->current_file, current->id);
+ LogMessage(L_INFO, "Hint: Do you have ESP Ghostscript installed?");
+
+ if (LogLevel < L_DEBUG)
+ LogMessage(L_INFO, "Hint: Try setting the LogLevel to \"debug\".");
+
+ current->current_file ++;
+
+ if (current->current_file == current->num_files)
+ CancelJob(current->id, 0);
+
+ return;
+ }
+
+ /*
+ * Remove NULL ("-") filters...
+ */
+
+ for (i = 0; i < num_filters;)
+ if (strcmp(filters[i].filter, "-") == 0)
+ {
+ num_filters --;
+ if (i < num_filters)
+ memcpy(filters + i, filters + i + 1,
+ (num_filters - i) * sizeof(mime_filter_t));
+ }
+ else
+ i ++;
+
+ if (num_filters == 0)
+ {
+ free(filters);
+ filters = NULL;
+ }
+ else
+ {
+ /*
+ * Compute filter cost...
+ */
+
+ for (i = 0; i < num_filters; i ++)
+ current->cost += filters[i].cost;
+ }
+ }
+
+ /*
+ * See if the filter cost is too high...
+ */
+
+ if ((FilterLevel + current->cost) > FilterLimit && FilterLevel > 0 &&
+ FilterLimit > 0)
+ {
+ /*
+ * Don't print this job quite yet...
+ */
+
+ if (filters != NULL)
+ free(filters);
+
+ LogMessage(L_INFO, "Holding job %d because filter limit has been reached.",
+ id);
+ LogMessage(L_DEBUG, "StartJob: id = %d, file = %d, "
+ "cost = %d, level = %d, limit = %d",
+ id, current->current_file, current->cost, FilterLevel,
+ FilterLimit);
+ return;
+ }
+
+ FilterLevel += current->cost;
+
+ /*
+ * Update the printer and job state to "processing"...
+ */
+
+ current->state->values[0].integer = IPP_JOB_PROCESSING;
+ current->status = 0;
+ current->printer = printer;
+ printer->job = current;
+ SetPrinterState(printer, IPP_PRINTER_PROCESSING);
+
+ if (current->current_file == 0)
+ set_time(current, "time-at-processing");
+
+ /*
+ * Determine if we are printing a banner page or not...
+ */
+
+ if (current->job_sheets == NULL)
+ {
+ LogMessage(L_DEBUG, "No job-sheets attribute.");
+ if ((current->job_sheets =
+ ippFindAttribute(current->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL)
+ LogMessage(L_DEBUG, "... but someone added one without setting job_sheets!");
+ }
+ else if (current->job_sheets->num_values == 1)
+ LogMessage(L_DEBUG, "job-sheets=%s",
+ current->job_sheets->values[0].string.text);
+ else
+ LogMessage(L_DEBUG, "job-sheets=%s,%s",
+ current->job_sheets->values[0].string.text,
+ current->job_sheets->values[1].string.text);
+
+ if (printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))
+ banner_page = 0;
+ else if (current->job_sheets == NULL)
+ banner_page = 0;
+ else if (strcasecmp(current->job_sheets->values[0].string.text, "none") != 0 &&
+ current->current_file == 0)
+ banner_page = 1;
+ else if (current->job_sheets->num_values > 1 &&
+ strcasecmp(current->job_sheets->values[1].string.text, "none") != 0 &&
+ current->current_file == (current->num_files - 1))
+ banner_page = 1;
+ else
+ banner_page = 0;
+
+ LogMessage(L_DEBUG, "banner_page = %d", banner_page);
+
+ /*
+ * Building the options string is harder than it needs to be, but
+ * for the moment we need to pass strings for command-line args and
+ * not IPP attribute pointers... :)
+ */
+
+ optptr = options;
+ *optptr = '\0';
+
+ snprintf(title, sizeof(title), "%s-%d", printer->name, current->id);
+ strcpy(copies, "1");
+
+ for (attr = current->attrs->attrs; attr != NULL; attr = attr->next)
+ {
+ if (strcmp(attr->name, "copies") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ {
+ /*
+ * Don't use the # copies attribute if we are printing the job sheets...
+ */
+
+ if (!banner_page)
+ sprintf(copies, "%d", attr->values[0].integer);
+ }
+ else if (strcmp(attr->name, "job-name") == 0 &&
+ (attr->value_tag == IPP_TAG_NAME ||
+ attr->value_tag == IPP_TAG_NAMELANG))
+ strlcpy(title, attr->values[0].string.text, sizeof(title));
+ else if (attr->group_tag == IPP_TAG_JOB)
+ {
+ /*
+ * Filter out other unwanted attributes...
+ */
+
+ if (attr->value_tag == IPP_TAG_MIMETYPE ||
+ attr->value_tag == IPP_TAG_NAMELANG ||
+ attr->value_tag == IPP_TAG_TEXTLANG ||
+ attr->value_tag == IPP_TAG_URI ||
+ attr->value_tag == IPP_TAG_URISCHEME)
+ continue;
+
+ if (strncmp(attr->name, "time-", 5) == 0)
+ continue;
+
+ if (strncmp(attr->name, "job-", 4) == 0 &&
+ !(printer->type & CUPS_PRINTER_REMOTE))
+ continue;
+
+ if (strncmp(attr->name, "job-", 4) == 0 &&
+ strcmp(attr->name, "job-billing") != 0 &&
+ strcmp(attr->name, "job-sheets") != 0 &&
+ strcmp(attr->name, "job-hold-until") != 0 &&
+ strcmp(attr->name, "job-priority") != 0)
+ continue;
+
+ if ((strcmp(attr->name, "page-label") == 0 ||
+ strcmp(attr->name, "page-border") == 0 ||
+ strncmp(attr->name, "number-up", 9) == 0) &&
+ banner_page)
+ continue;
+
+ /*
+ * Otherwise add them to the list...
+ */
+
+ if (optptr > options)
+ strlcat(optptr, " ", sizeof(options) - (optptr - options));
+
+ if (attr->value_tag != IPP_TAG_BOOLEAN)
+ {
+ strlcat(optptr, attr->name, sizeof(options) - (optptr - options));
+ strlcat(optptr, "=", sizeof(options) - (optptr - options));
+ }
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if (i)
+ strlcat(optptr, ",", sizeof(options) - (optptr - options));
+
+ optptr += strlen(optptr);
+
+ switch (attr->value_tag)
+ {
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ snprintf(optptr, sizeof(options) - (optptr - options),
+ "%d", attr->values[i].integer);
+ break;
+
+ case IPP_TAG_BOOLEAN :
+ if (!attr->values[i].boolean)
+ strlcat(optptr, "no", sizeof(options) - (optptr - options));
+
+ case IPP_TAG_NOVALUE :
+ strlcat(optptr, attr->name,
+ sizeof(options) - (optptr - options));
+ break;
+
+ case IPP_TAG_RANGE :
+ if (attr->values[i].range.lower == attr->values[i].range.upper)
+ snprintf(optptr, sizeof(options) - (optptr - options) - 1,
+ "%d", attr->values[i].range.lower);
+ else
+ snprintf(optptr, sizeof(options) - (optptr - options) - 1,
+ "%d-%d", attr->values[i].range.lower,
+ attr->values[i].range.upper);
+ break;
+
+ case IPP_TAG_RESOLUTION :
+ snprintf(optptr, sizeof(options) - (optptr - options) - 1,
+ "%dx%d%s", attr->values[i].resolution.xres,
+ attr->values[i].resolution.yres,
+ attr->values[i].resolution.units == IPP_RES_PER_INCH ?
+ "dpi" : "dpc");
+ break;
+
+ case IPP_TAG_STRING :
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ if (strchr(attr->values[i].string.text, ' ') != NULL ||
+ strchr(attr->values[i].string.text, '\t') != NULL ||
+ strchr(attr->values[i].string.text, '\n') != NULL)
+ {
+ strlcat(optptr, "\'", sizeof(options) - (optptr - options));
+ strlcat(optptr, attr->values[i].string.text,
+ sizeof(options) - (optptr - options));
+ strlcat(optptr, "\'", sizeof(options) - (optptr - options));
+ }
+ else
+ strlcat(optptr, attr->values[i].string.text,
+ sizeof(options) - (optptr - options));
+ break;
+
+ default :
+ break; /* anti-compiler-warning-code */
+ }
+ }
+
+ optptr += strlen(optptr);
+ }
+ }
+
+ /*
+ * Build the command-line arguments for the filters. Each filter
+ * has 6 or 7 arguments:
+ *
+ * argv[0] = printer
+ * argv[1] = job ID
+ * argv[2] = username
+ * argv[3] = title
+ * argv[4] = # copies
+ * argv[5] = options
+ * argv[6] = filename (optional; normally stdin)
+ *
+ * This allows legacy printer drivers that use the old System V
+ * printing interface to be used by CUPS.
+ */
+
+ sprintf(jobid, "%d", current->id);
+ snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
+ current->id, current->current_file + 1);
+
+ argv[0] = printer->name;
+ argv[1] = jobid;
+ argv[2] = current->username;
+ argv[3] = title;
+ argv[4] = copies;
+ argv[5] = options;
+ argv[6] = filename;
+ argv[7] = NULL;
+
+ LogMessage(L_DEBUG, "StartJob: argv = \"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"",
+ argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
+
+ /*
+ * Create environment variable strings for the filters...
+ */
+
+ attr = ippFindAttribute(current->attrs, "attributes-natural-language",
+ IPP_TAG_LANGUAGE);
+
+ switch (strlen(attr->values[0].string.text))
+ {
+ default :
+ /*
+ * This is an unknown or badly formatted language code; use
+ * the POSIX locale...
+ */
+
+ strcpy(language, "LANG=C");
+ break;
+
+ case 2 :
+ /*
+ * Just the language code (ll)...
+ */
+
+ snprintf(language, sizeof(language), "LANG=%s",
+ attr->values[0].string.text);
+ break;
+
+ case 5 :
+ /*
+ * Language and country code (ll-cc)...
+ */
+
+ snprintf(language, sizeof(language), "LANG=%c%c_%c%c",
+ attr->values[0].string.text[0],
+ attr->values[0].string.text[1],
+ toupper(attr->values[0].string.text[3]),
+ toupper(attr->values[0].string.text[4]));
+ break;
+ }
+
+ attr = ippFindAttribute(current->attrs, "document-format",
+ IPP_TAG_MIMETYPE);
+ if (attr != NULL &&
+ (optptr = strstr(attr->values[0].string.text, "charset=")) != NULL)
+ snprintf(charset, sizeof(charset), "CHARSET=%s", optptr + 8);
+ else
+ {
+ attr = ippFindAttribute(current->attrs, "attributes-charset",
+ IPP_TAG_CHARSET);
+ snprintf(charset, sizeof(charset), "CHARSET=%s",
+ attr->values[0].string.text);
+ }
+
+ snprintf(path, sizeof(path), "PATH=%s/filter:/bin:/usr/bin", ServerBin);
+ snprintf(content_type, sizeof(content_type), "CONTENT_TYPE=%s/%s",
+ current->filetypes[current->current_file]->super,
+ current->filetypes[current->current_file]->type);
+ snprintf(device_uri, sizeof(device_uri), "DEVICE_URI=%s", printer->device_uri);
+ snprintf(ppd, sizeof(ppd), "PPD=%s/ppd/%s.ppd", ServerRoot, printer->name);
+ snprintf(printer_name, sizeof(printer_name), "PRINTER=%s", printer->name);
+ snprintf(cache, sizeof(cache), "RIP_MAX_CACHE=%s", RIPCache);
+ snprintf(root, sizeof(root), "CUPS_SERVERROOT=%s", ServerRoot);
+ snprintf(tmpdir, sizeof(tmpdir), "TMPDIR=%s", TempDir);
+ snprintf(datadir, sizeof(datadir), "CUPS_DATADIR=%s", DataDir);
+ snprintf(fontpath, sizeof(fontpath), "CUPS_FONTPATH=%s", FontPath);
+
+ if (current->dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+ snprintf(class_name, sizeof(class_name), "CLASS=%s", current->dest);
+ else
+ class_name[0] = '\0';
+
+ if (Classification[0] && !banner_page)
+ {
+ if ((attr = ippFindAttribute(current->attrs, "job-sheets",
+ IPP_TAG_NAME)) == NULL)
+ snprintf(classification, sizeof(classification), "CLASSIFICATION=%s",
+ Classification);
+ else if (attr->num_values > 1 &&
+ strcmp(attr->values[1].string.text, "none") != 0)
+ snprintf(classification, sizeof(classification), "CLASSIFICATION=%s",
+ attr->values[1].string.text);
+ else
+ snprintf(classification, sizeof(classification), "CLASSIFICATION=%s",
+ attr->values[0].string.text);
+ }
+ else
+ classification[0] = '\0';
+
+ if (getenv("LD_LIBRARY_PATH") != NULL)
+ snprintf(ldpath, sizeof(ldpath), "LD_LIBRARY_PATH=%s",
+ getenv("LD_LIBRARY_PATH"));
+ else if (getenv("DYLD_LIBRARY_PATH") != NULL)
+ snprintf(ldpath, sizeof(ldpath), "DYLD_LIBRARY_PATH=%s",
+ getenv("DYLD_LIBRARY_PATH"));
+ else if (getenv("SHLIB_PATH") != NULL)
+ snprintf(ldpath, sizeof(ldpath), "SHLIB_PATH=%s",
+ getenv("SHLIB_PATH"));
+ else
+ ldpath[0] = '\0';
+
+ if (getenv("NLSPATH") != NULL)
+ snprintf(nlspath, sizeof(nlspath), "NLSPATH=%s", getenv("NLSPATH"));
+ else
+ nlspath[0] = '\0';
+
+ envp[0] = path;
+ envp[1] = "SOFTWARE=CUPS/1.1";
+ envp[2] = "USER=root";
+ envp[3] = charset;
+ envp[4] = language;
+ envp[5] = TZ;
+ envp[6] = ppd;
+ envp[7] = root;
+ envp[8] = cache;
+ envp[9] = tmpdir;
+ envp[10] = content_type;
+ envp[11] = device_uri;
+ envp[12] = printer_name;
+ envp[13] = datadir;
+ envp[14] = fontpath;
+ envp[15] = ldpath;
+ envp[16] = nlspath;
+ envp[17] = classification;
+ envp[18] = class_name;
+ envp[19] = NULL;
+
+ LogMessage(L_DEBUG, "StartJob: envp = \"%s\",\"%s\",\"%s\",\"%s\","
+ "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\","
+ "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"",
+ envp[0], envp[1], envp[2], envp[3], envp[4],
+ envp[5], envp[6], envp[7], envp[8], envp[9],
+ envp[10], envp[11], envp[12], envp[13], envp[14],
+ envp[15], envp[16], envp[17]);
+
+ current->current_file ++;
+
+ /*
+ * Make sure we have a buffer to read status info into...
+ */
+
+ if (current->buffer == NULL)
+ {
+ LogMessage(L_DEBUG2, "UpdateJob: Allocating status buffer...");
+
+ if ((current->buffer = malloc(JOB_BUFFER_SIZE)) == NULL)
+ {
+ LogMessage(L_EMERG, "Unable to allocate memory for job status buffer - %s",
+ strerror(errno));
+ CancelJob(current->id, 0);
+ return;
+ }
+
+ current->bufused = 0;
+ }
+
+ /*
+ * Now create processes for all of the filters...
+ */
+
+ if (pipe(statusfds))
+ {
+ LogMessage(L_ERROR, "Unable to create job status pipes - %s.",
+ strerror(errno));
+ snprintf(printer->state_message, sizeof(printer->state_message),
+ "Unable to create status pipes - %s.", strerror(errno));
+ return;
+ }
+
+ LogMessage(L_DEBUG, "StartJob: statusfds = %d, %d",
+ statusfds[0], statusfds[1]);
+
+ current->pipe = statusfds[0];
+ current->status = 0;
+ memset(current->procs, 0, sizeof(current->procs));
+
+ filterfds[1][0] = open("/dev/null", O_RDONLY);
+ filterfds[1][1] = -1;
+
+ LogMessage(L_DEBUG, "StartJob: filterfds[%d] = %d, %d", 1, filterfds[1][0],
+ filterfds[1][1]);
+
+ for (i = 0, slot = 0; i < num_filters; i ++)
+ {
+ if (filters[i].filter[0] != '/')
+ snprintf(command, sizeof(command), "%s/filter/%s", ServerBin,
+ filters[i].filter);
+ else
+ strlcpy(command, filters[i].filter, sizeof(command));
+
+ if (i < (num_filters - 1) ||
+ strncmp(printer->device_uri, "file:", 5) != 0)
+ pipe(filterfds[slot]);
+ else
+ {
+ filterfds[slot][0] = -1;
+ if (strncmp(printer->device_uri, "file:/dev/", 10) == 0)
+ filterfds[slot][1] = open(printer->device_uri + 5,
+ O_WRONLY | O_EXCL);
+ else
+ filterfds[slot][1] = open(printer->device_uri + 5,
+ O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ }
+
+ LogMessage(L_DEBUG, "StartJob: filter = \"%s\"", command);
+ LogMessage(L_DEBUG, "StartJob: filterfds[%d] = %d, %d",
+ slot, filterfds[slot][0], filterfds[slot][1]);
+
+ pid = start_process(command, argv, envp, filterfds[!slot][0],
+ filterfds[slot][1], statusfds[1], 0,
+ current->procs + i);
+
+ close(filterfds[!slot][0]);
+ close(filterfds[!slot][1]);
+
+ if (pid == 0)
+ {
+ LogMessage(L_ERROR, "Unable to start filter \"%s\" - %s.",
+ filters[i].filter, strerror(errno));
+ snprintf(printer->state_message, sizeof(printer->state_message),
+ "Unable to start filter \"%s\" - %s.",
+ filters[i].filter, strerror(errno));
+ return;
+ }
+
+ LogMessage(L_INFO, "Started filter %s (PID %d) for job %d.",
+ command, pid, current->id);
+
+ argv[6] = NULL;
+ slot = !slot;
+ }
+
+ if (filters != NULL)
+ free(filters);
+
+ /*
+ * Finally, pipe the final output into a backend process if needed...
+ */
+
+ if (strncmp(printer->device_uri, "file:", 5) != 0)
+ {
+ sscanf(printer->device_uri, "%254[^:]", method);
+ snprintf(command, sizeof(command), "%s/backend/%s", ServerBin, method);
+
+ argv[0] = printer->device_uri;
+
+ filterfds[slot][0] = -1;
+ filterfds[slot][1] = open("/dev/null", O_WRONLY);
+
+ LogMessage(L_DEBUG, "StartJob: backend = \"%s\"", command);
+ LogMessage(L_DEBUG, "StartJob: filterfds[%d] = %d, %d",
+ slot, filterfds[slot][0], filterfds[slot][1]);
+
+ pid = start_process(command, argv, envp, filterfds[!slot][0],
+ filterfds[slot][1], statusfds[1], 1,
+ current->procs + i);
+
+ close(filterfds[!slot][0]);
+ close(filterfds[!slot][1]);
+
+ if (pid == 0)
+ {
+ LogMessage(L_ERROR, "Unable to start backend \"%s\" - %s.",
+ method, strerror(errno));
+ snprintf(printer->state_message, sizeof(printer->state_message),
+ "Unable to start backend \"%s\" - %s.", method, strerror(errno));
+ return;
+ }
+ else
+ {
+ LogMessage(L_INFO, "Started backend %s (PID %d) for job %d.", command, pid,
+ current->id);
+ }
+ }
+ else
+ {
+ filterfds[slot][0] = -1;
+ filterfds[slot][1] = -1;
+
+ close(filterfds[!slot][0]);
+ close(filterfds[!slot][1]);
+ }
+
+ close(filterfds[slot][0]);
+ close(filterfds[slot][1]);
+
+ close(statusfds[1]);
+
+ LogMessage(L_DEBUG2, "StartJob: Adding fd %d to InputSet...", current->pipe);
+
+ FD_SET(current->pipe, &InputSet);
+}
+
+
+/*
+ * 'StopAllJobs()' - Stop all print jobs.
+ */
+
+void
+StopAllJobs(void)
+{
+ job_t *current; /* Current job */
+
+
+ DEBUG_puts("StopAllJobs()");
+
+ for (current = Jobs; current != NULL; current = current->next)
+ if (current->state->values[0].integer == IPP_JOB_PROCESSING)
+ {
+ StopJob(current->id, 1);
+ current->state->values[0].integer = IPP_JOB_PENDING;
+ }
+}
+
+
+/*
+ * 'StopJob()' - Stop a print job.
+ */
+
+void
+StopJob(int id, /* I - Job ID */
+ int force) /* I - 1 = Force all filters to stop */
+{
+ int i; /* Looping var */
+ job_t *current; /* Current job */
+
+
+ LogMessage(L_DEBUG, "StopJob: id = %d, force = %d", id, force);
+
+ for (current = Jobs; current != NULL; current = current->next)
+ if (current->id == id)
+ {
+ DEBUG_puts("StopJob: found job in list.");
+
+ if (current->state->values[0].integer == IPP_JOB_PROCESSING)
+ {
+ DEBUG_puts("StopJob: job state is \'processing\'.");
+
+ FilterLevel -= current->cost;
+
+ if (current->status < 0 &&
+ (current->dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) != 0)
+ SetPrinterState(current->printer, IPP_PRINTER_STOPPED);
+ else if (current->printer->state != IPP_PRINTER_STOPPED)
+ SetPrinterState(current->printer, IPP_PRINTER_IDLE);
+
+ LogMessage(L_DEBUG, "StopJob: printer state is %d", current->printer->state);
+
+ current->state->values[0].integer = IPP_JOB_STOPPED;
+ current->printer->job = NULL;
+ current->printer = NULL;
+
+ current->current_file --;
+
+ for (i = 0; current->procs[i]; i ++)
+ if (current->procs[i] > 0)
+ {
+ kill(current->procs[i], force ? SIGKILL : SIGTERM);
+ current->procs[i] = 0;
+ }
+
+ if (current->pipe)
+ {
+ /*
+ * Close the pipe and clear the input bit.
+ */
+
+ LogMessage(L_DEBUG2, "StopJob: Removing fd %d from InputSet...",
+ current->pipe);
+
+ close(current->pipe);
+ FD_CLR(current->pipe, &InputSet);
+ current->pipe = 0;
+ }
+
+ if (current->buffer)
+ {
+ /*
+ * Free the status buffer...
+ */
+
+ LogMessage(L_DEBUG2, "StopJob: Freeing status buffer...");
+
+ free(current->buffer);
+ current->buffer = NULL;
+ current->bufused = 0;
+ }
+ }
+ return;
+ }
+}
+
+
+/*
+ * 'UpdateJob()' - Read a status update from a job's filters.
+ */
+
+void
+UpdateJob(job_t *job) /* I - Job to check */
+{
+ int bytes; /* Number of bytes read */
+ int copies; /* Number of copies printed */
+ char *lineptr, /* Pointer to end of line in buffer */
+ *message; /* Pointer to message text */
+ int loglevel; /* Log level for message */
+
+
+ if ((bytes = read(job->pipe, job->buffer + job->bufused,
+ JOB_BUFFER_SIZE - job->bufused - 1)) > 0)
+ {
+ job->bufused += bytes;
+ job->buffer[job->bufused] = '\0';
+
+ if (job->bufused == (JOB_BUFFER_SIZE - 1))
+ lineptr = job->buffer + JOB_BUFFER_SIZE - 1;
+ else
+ lineptr = strchr(job->buffer, '\n');
+ }
+ else if (bytes < 0 && errno == EINTR)
+ return;
+ else
+ {
+ lineptr = job->buffer + job->bufused;
+ *lineptr = '\0';
+ }
+
+ if (job->bufused == 0 && bytes == 0)
+ lineptr = NULL;
+
+ while (lineptr != NULL)
+ {
+ /*
+ * Terminate each line and process it...
+ */
+
+ *lineptr++ = '\0';
+
+ /*
+ * Figure out the logging level...
+ */
+
+ if (strncmp(job->buffer, "EMERG:", 6) == 0)
+ {
+ loglevel = L_EMERG;
+ message = job->buffer + 6;
+ }
+ else if (strncmp(job->buffer, "ALERT:", 6) == 0)
+ {
+ loglevel = L_ALERT;
+ message = job->buffer + 6;
+ }
+ else if (strncmp(job->buffer, "CRIT:", 5) == 0)
+ {
+ loglevel = L_CRIT;
+ message = job->buffer + 5;
+ }
+ else if (strncmp(job->buffer, "ERROR:", 6) == 0)
+ {
+ loglevel = L_ERROR;
+ message = job->buffer + 6;
+ }
+ else if (strncmp(job->buffer, "WARNING:", 8) == 0)
+ {
+ loglevel = L_WARN;
+ message = job->buffer + 8;
+ }
+ else if (strncmp(job->buffer, "NOTICE:", 6) == 0)
+ {
+ loglevel = L_NOTICE;
+ message = job->buffer + 6;
+ }
+ else if (strncmp(job->buffer, "INFO:", 5) == 0)
+ {
+ loglevel = L_INFO;
+ message = job->buffer + 5;
+ }
+ else if (strncmp(job->buffer, "DEBUG:", 6) == 0)
+ {
+ loglevel = L_DEBUG;
+ message = job->buffer + 6;
+ }
+ else if (strncmp(job->buffer, "DEBUG2:", 7) == 0)
+ {
+ loglevel = L_DEBUG2;
+ message = job->buffer + 7;
+ }
+ else if (strncmp(job->buffer, "PAGE:", 5) == 0)
+ {
+ loglevel = L_PAGE;
+ message = job->buffer + 5;
+ }
+ else
+ {
+ loglevel = L_DEBUG;
+ message = job->buffer;
+ }
+
+ /*
+ * Skip leading whitespace in the message...
+ */
+
+ while (isspace(*message))
+ message ++;
+
+ /*
+ * Send it to the log file and printer state message as needed...
+ */
+
+ if (loglevel == L_PAGE)
+ {
+ /*
+ * Page message; send the message to the page_log file and update the
+ * job sheet count...
+ */
+
+ if (job->sheets != NULL)
+ {
+ if (!sscanf(message, "%*d%d", &copies))
+ {
+ job->sheets->values[0].integer ++;
+
+ if (job->printer->page_limit)
+ UpdateQuota(job->printer, job->username, 1, 0);
+ }
+ else
+ {
+ job->sheets->values[0].integer += copies;
+
+ if (job->printer->page_limit)
+ UpdateQuota(job->printer, job->username, copies, 0);
+ }
+ }
+
+ LogPage(job, message);
+ }
+ else
+ {
+ /*
+ * Other status message; send it to the error_log file...
+ */
+
+ if (loglevel != L_INFO || LogLevel == L_DEBUG2)
+ LogMessage(loglevel, "%s", message);
+
+ if ((loglevel == L_INFO && !job->status) ||
+ loglevel < L_INFO)
+ strlcpy(job->printer->state_message, message,
+ sizeof(job->printer->state_message));
+ }
+
+ /*
+ * Copy over the buffer data we've used up...
+ */
+
+ strcpy(job->buffer, lineptr);
+ job->bufused -= lineptr - job->buffer;
+
+ if (job->bufused < 0)
+ job->bufused = 0;
+
+ lineptr = strchr(job->buffer, '\n');
+ }
+
+ if (bytes <= 0)
+ {
+ LogMessage(L_DEBUG, "UpdateJob: job %d, file %d is complete.",
+ job->id, job->current_file - 1);
+
+ if (job->pipe)
+ {
+ /*
+ * Close the pipe and clear the input bit.
+ */
+
+ LogMessage(L_DEBUG2, "UpdateJob: Removing fd %d from InputSet...",
+ job->pipe);
+
+ close(job->pipe);
+ FD_CLR(job->pipe, &InputSet);
+ job->pipe = 0;
+ }
+
+ if (job->status < 0)
+ {
+ /*
+ * Backend had errors; stop it...
+ */
+
+ StopJob(job->id, 0);
+ job->state->values[0].integer = IPP_JOB_PENDING;
+ SaveJob(job->id);
+
+ /*
+ * If the job was queued to a class, try requeuing it...
+ */
+
+ if (job->dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+ CheckJobs();
+ }
+ else if (job->status > 0)
+ {
+ /*
+ * Filter had errors; cancel it...
+ */
+
+ if (job->current_file < job->num_files)
+ StartJob(job->id, job->printer);
+ else
+ {
+ CancelJob(job->id, 0);
+
+ if (JobHistory)
+ {
+ job->state->values[0].integer = IPP_JOB_ABORTED;
+ SaveJob(job->id);
+ }
+
+ CheckJobs();
+ }
+ }
+ else
+ {
+ /*
+ * Job printed successfully; cancel it...
+ */
+
+ if (job->current_file < job->num_files)
+ {
+ FilterLevel -= job->cost;
+ StartJob(job->id, job->printer);
+ }
+ else
+ {
+ CancelJob(job->id, 0);
+
+ if (JobHistory)
+ {
+ job->state->values[0].integer = IPP_JOB_COMPLETED;
+ SaveJob(job->id);
+ }
+
+ CheckJobs();
+ }
+ }
+ }
+}
+
+
+/*
+ * 'ipp_read_file()' - Read an IPP request from a file.
+ */
+
+static ipp_state_t /* O - State */
+ipp_read_file(const char *filename, /* I - File to read from */
+ ipp_t *ipp) /* I - Request to read into */
+{
+ int fd; /* File descriptor for file */
+ int n; /* Length of data */
+ unsigned char buffer[8192], /* Data buffer */
+ *bufptr; /* Pointer into buffer */
+ ipp_attribute_t *attr; /* Current attribute */
+ ipp_tag_t tag; /* Current tag */
+
+
+ /*
+ * Open the file if possible...
+ */
+
+ if (filename == NULL || ipp == NULL)
+ return (IPP_ERROR);
+
+ if ((fd = open(filename, O_RDONLY)) == -1)
+ return (IPP_ERROR);
+
+ /*
+ * Read the IPP request...
+ */
+
+ ipp->state = IPP_IDLE;
+
+ switch (ipp->state)
+ {
+ default :
+ break; /* anti-compiler-warning-code */
+
+ case IPP_IDLE :
+ ipp->state ++; /* Avoid common problem... */
+
+ case IPP_HEADER :
+ /*
+ * Get the request header...
+ */
+
+ if ((n = read(fd, buffer, 8)) < 8)
+ {
+ DEBUG_printf(("ipp_read_file: Unable to read header (%d bytes read)!\n", n));
+ close(fd);
+ return (n == 0 ? IPP_IDLE : IPP_ERROR);
+ }
+
+ /*
+ * Verify the major version number...
+ */
+
+ if (buffer[0] != 1)
+ {
+ DEBUG_printf(("ipp_read_file: version number (%d.%d) is bad.\n", buffer[0],
+ buffer[1]));
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ /*
+ * Then copy the request header over...
+ */
+
+ ipp->request.any.version[0] = buffer[0];
+ ipp->request.any.version[1] = buffer[1];
+ ipp->request.any.op_status = (buffer[2] << 8) | buffer[3];
+ ipp->request.any.request_id = (((((buffer[4] << 8) | buffer[5]) << 8) |
+ buffer[6]) << 8) | buffer[7];
+
+ ipp->state = IPP_ATTRIBUTE;
+ ipp->current = NULL;
+ ipp->curtag = IPP_TAG_ZERO;
+
+ case IPP_ATTRIBUTE :
+ while (read(fd, buffer, 1) > 0)
+ {
+ /*
+ * Read this attribute...
+ */
+
+ tag = (ipp_tag_t)buffer[0];
+
+ if (tag == IPP_TAG_END)
+ {
+ /*
+ * No more attributes left...
+ */
+
+ DEBUG_puts("ipp_read_file: IPP_TAG_END!");
+
+ ipp->state = IPP_DATA;
+ break;
+ }
+ else if (tag < IPP_TAG_UNSUPPORTED_VALUE)
+ {
+ /*
+ * Group tag... Set the current group and continue...
+ */
+
+ if (ipp->curtag == tag)
+ ippAddSeparator(ipp);
+
+ ipp->curtag = tag;
+ ipp->current = NULL;
+ DEBUG_printf(("ipp_read_file: group tag = %x\n", tag));
+ continue;
+ }
+
+ DEBUG_printf(("ipp_read_file: value tag = %x\n", tag));
+
+ /*
+ * Get the name...
+ */
+
+ if (read(fd, buffer, 2) < 2)
+ {
+ DEBUG_puts("ipp_read_file: unable to read name length!");
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ n = (buffer[0] << 8) | buffer[1];
+
+ if (n > (sizeof(buffer) - 1))
+ {
+ DEBUG_printf(("ipp_read_file: bad name length %d!\n", n));
+ return (IPP_ERROR);
+ }
+
+ DEBUG_printf(("ipp_read_file: name length = %d\n", n));
+
+ if (n == 0)
+ {
+ /*
+ * More values for current attribute...
+ */
+
+ if (ipp->current == NULL)
+ {
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ attr = ipp->current;
+
+ /*
+ * Finally, reallocate the attribute array as needed...
+ */
+
+ if ((attr->num_values % IPP_MAX_VALUES) == 0)
+ {
+ ipp_attribute_t *temp, /* Pointer to new buffer */
+ *ptr; /* Pointer in attribute list */
+
+
+ /*
+ * Reallocate memory...
+ */
+
+ if ((temp = realloc(attr, sizeof(ipp_attribute_t) +
+ (attr->num_values + IPP_MAX_VALUES - 1) *
+ sizeof(ipp_value_t))) == NULL)
+ {
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ /*
+ * Reset pointers in the list...
+ */
+
+ for (ptr = ipp->attrs; ptr && ptr->next != attr; ptr = ptr->next);
+
+ if (ptr)
+ ptr->next = temp;
+ else
+ ipp->attrs = temp;
+
+ attr = ipp->current = ipp->last = temp;
+ }
+ }
+ else
+ {
+ /*
+ * New attribute; read the name and add it...
+ */
+
+ if (read(fd, buffer, n) < n)
+ {
+ DEBUG_puts("ipp_read_file: unable to read name!");
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ buffer[n] = '\0';
+ DEBUG_printf(("ipp_read_file: name = \'%s\'\n", buffer));
+
+ attr = ipp->current = _ipp_add_attr(ipp, IPP_MAX_VALUES);
+
+ attr->group_tag = ipp->curtag;
+ attr->value_tag = tag;
+ attr->name = strdup((char *)buffer);
+ attr->num_values = 0;
+ }
+
+ if (read(fd, buffer, 2) < 2)
+ {
+ DEBUG_puts("ipp_read_file: unable to read value length!");
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ n = (buffer[0] << 8) | buffer[1];
+ DEBUG_printf(("ipp_read_file: value length = %d\n", n));
+
+ switch (tag)
+ {
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ if (read(fd, buffer, 4) < 4)
+ {
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ n = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) |
+ buffer[3];
+
+ attr->values[attr->num_values].integer = n;
+ break;
+ case IPP_TAG_BOOLEAN :
+ if (read(fd, buffer, 1) < 1)
+ {
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ attr->values[attr->num_values].boolean = buffer[0];
+ break;
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_STRING :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ if (read(fd, buffer, n) < n)
+ {
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ buffer[n] = '\0';
+ DEBUG_printf(("ipp_read_file: value = \'%s\'\n", buffer));
+
+ attr->values[attr->num_values].string.text = strdup((char *)buffer);
+ break;
+ case IPP_TAG_DATE :
+ if (read(fd, buffer, 11) < 11)
+ {
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ memcpy(attr->values[attr->num_values].date, buffer, 11);
+ break;
+ case IPP_TAG_RESOLUTION :
+ if (read(fd, buffer, 9) < 9)
+ {
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ attr->values[attr->num_values].resolution.xres =
+ (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) |
+ buffer[3];
+ attr->values[attr->num_values].resolution.yres =
+ (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) |
+ buffer[7];
+ attr->values[attr->num_values].resolution.units =
+ (ipp_res_t)buffer[8];
+ break;
+ case IPP_TAG_RANGE :
+ if (read(fd, buffer, 8) < 8)
+ {
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ attr->values[attr->num_values].range.lower =
+ (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) |
+ buffer[3];
+ attr->values[attr->num_values].range.upper =
+ (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) |
+ buffer[7];
+ break;
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ if (n > sizeof(buffer))
+ {
+ DEBUG_printf(("ipp_read_file: bad value length %d!\n", n));
+ return (IPP_ERROR);
+ }
+
+ if (read(fd, buffer, n) < n)
+ return (IPP_ERROR);
+
+ bufptr = buffer;
+
+ /*
+ * text-with-language and name-with-language are composite
+ * values:
+ *
+ * charset-length
+ * charset
+ * text-length
+ * text
+ */
+
+ n = (bufptr[0] << 8) | bufptr[1];
+
+ attr->values[attr->num_values].string.charset = calloc(n + 1, 1);
+
+ memcpy(attr->values[attr->num_values].string.charset,
+ bufptr + 2, n);
+
+ bufptr += 2 + n;
+ n = (bufptr[0] << 8) | bufptr[1];
+
+ attr->values[attr->num_values].string.text = calloc(n + 1, 1);
+
+ memcpy(attr->values[attr->num_values].string.text,
+ bufptr + 2, n);
+
+ break;
+
+ default : /* Other unsupported values */
+ attr->values[attr->num_values].unknown.length = n;
+ if (n > 0)
+ {
+ attr->values[attr->num_values].unknown.data = malloc(n);
+ if (read(fd, attr->values[attr->num_values].unknown.data, n) < n)
+ return (IPP_ERROR);
+ }
+ else
+ attr->values[attr->num_values].unknown.data = NULL;
+ break;
+ }
+
+ attr->num_values ++;
+ }
+ break;
+
+ case IPP_DATA :
+ break;
+ }
+
+ /*
+ * Close the file and return...
+ */
+
+ close(fd);
+
+ return (ipp->state);
+}
+
+
+/*
+ * 'ipp_write_file()' - Write an IPP request to a file.
+ */
+
+static ipp_state_t /* O - State */
+ipp_write_file(const char *filename, /* I - File to write to */
+ ipp_t *ipp) /* I - Request to write */
+{
+ int fd; /* File descriptor */
+ int i; /* Looping var */
+ int n; /* Length of data */
+ unsigned char buffer[32768], /* Data buffer */
+ *bufptr; /* Pointer into buffer */
+ ipp_attribute_t *attr; /* Current attribute */
+
+
+ /*
+ * Open the file if possible...
+ */
+
+ if (filename == NULL || ipp == NULL)
+ return (IPP_ERROR);
+
+ if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) == -1)
+ return (IPP_ERROR);
+
+ fchmod(fd, 0600);
+ fchown(fd, User, Group);
+
+ /*
+ * Write the IPP request...
+ */
+
+ ipp->state = IPP_IDLE;
+
+ switch (ipp->state)
+ {
+ default :
+ break; /* anti-compiler-warning-code */
+
+ case IPP_IDLE :
+ ipp->state ++; /* Avoid common problem... */
+
+ case IPP_HEADER :
+ /*
+ * Send the request header...
+ */
+
+ bufptr = buffer;
+
+ *bufptr++ = ipp->request.any.version[0];
+ *bufptr++ = ipp->request.any.version[1];
+ *bufptr++ = ipp->request.any.op_status >> 8;
+ *bufptr++ = ipp->request.any.op_status;
+ *bufptr++ = ipp->request.any.request_id >> 24;
+ *bufptr++ = ipp->request.any.request_id >> 16;
+ *bufptr++ = ipp->request.any.request_id >> 8;
+ *bufptr++ = ipp->request.any.request_id;
+
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ipp_write_file: Could not write IPP header...");
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ ipp->state = IPP_ATTRIBUTE;
+ ipp->current = ipp->attrs;
+ ipp->curtag = IPP_TAG_ZERO;
+
+ case IPP_ATTRIBUTE :
+ while (ipp->current != NULL)
+ {
+ /*
+ * Write this attribute...
+ */
+
+ bufptr = buffer;
+ attr = ipp->current;
+
+ ipp->current = ipp->current->next;
+
+ if (ipp->curtag != attr->group_tag)
+ {
+ /*
+ * Send a group operation tag...
+ */
+
+ ipp->curtag = attr->group_tag;
+
+ if (attr->group_tag == IPP_TAG_ZERO)
+ continue;
+
+ DEBUG_printf(("ipp_write_file: wrote group tag = %x\n", attr->group_tag));
+ *bufptr++ = attr->group_tag;
+ }
+
+ if ((n = strlen(attr->name)) > (sizeof(buffer) - 3))
+ return (IPP_ERROR);
+
+ DEBUG_printf(("ipp_write_file: writing value tag = %x\n", attr->value_tag));
+ DEBUG_printf(("ipp_write_file: writing name = %d, \'%s\'\n", n, attr->name));
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+ memcpy(bufptr, attr->name, n);
+ bufptr += n;
+
+ switch (attr->value_tag)
+ {
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if ((sizeof(buffer) - (bufptr - buffer)) < 9)
+ {
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ *bufptr++ = 0;
+ *bufptr++ = 4;
+ *bufptr++ = attr->values[i].integer >> 24;
+ *bufptr++ = attr->values[i].integer >> 16;
+ *bufptr++ = attr->values[i].integer >> 8;
+ *bufptr++ = attr->values[i].integer;
+ }
+ break;
+
+ case IPP_TAG_BOOLEAN :
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if ((sizeof(buffer) - (bufptr - buffer)) < 6)
+ {
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ *bufptr++ = 0;
+ *bufptr++ = 1;
+ *bufptr++ = attr->values[i].boolean;
+ }
+ break;
+
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_STRING :
+ case IPP_TAG_URI :
+ case IPP_TAG_URISCHEME :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_LANGUAGE :
+ case IPP_TAG_MIMETYPE :
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ DEBUG_printf(("ipp_write_file: writing value tag = %x\n",
+ attr->value_tag));
+ DEBUG_printf(("ipp_write_file: writing name = 0, \'\'\n"));
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < 3)
+ {
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ n = strlen(attr->values[i].string.text);
+
+ if (n > (sizeof(buffer) - 2))
+ return (IPP_ERROR);
+
+ DEBUG_printf(("ipp_write_file: writing string = %d, \'%s\'\n", n,
+ attr->values[i].string.text));
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2))
+ {
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ipp_write_file: Could not write IPP attribute...");
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+ memcpy(bufptr, attr->values[i].string.text, n);
+ bufptr += n;
+ }
+ break;
+
+ case IPP_TAG_DATE :
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if ((sizeof(buffer) - (bufptr - buffer)) < 16)
+ {
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ *bufptr++ = 0;
+ *bufptr++ = 11;
+ memcpy(bufptr, attr->values[i].date, 11);
+ bufptr += 11;
+ }
+ break;
+
+ case IPP_TAG_RESOLUTION :
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if ((sizeof(buffer) - (bufptr - buffer)) < 14)
+ {
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ *bufptr++ = 0;
+ *bufptr++ = 9;
+ *bufptr++ = attr->values[i].resolution.xres >> 24;
+ *bufptr++ = attr->values[i].resolution.xres >> 16;
+ *bufptr++ = attr->values[i].resolution.xres >> 8;
+ *bufptr++ = attr->values[i].resolution.xres;
+ *bufptr++ = attr->values[i].resolution.yres >> 24;
+ *bufptr++ = attr->values[i].resolution.yres >> 16;
+ *bufptr++ = attr->values[i].resolution.yres >> 8;
+ *bufptr++ = attr->values[i].resolution.yres;
+ *bufptr++ = attr->values[i].resolution.units;
+ }
+ break;
+
+ case IPP_TAG_RANGE :
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if ((sizeof(buffer) - (bufptr - buffer)) < 13)
+ {
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ *bufptr++ = 0;
+ *bufptr++ = 8;
+ *bufptr++ = attr->values[i].range.lower >> 24;
+ *bufptr++ = attr->values[i].range.lower >> 16;
+ *bufptr++ = attr->values[i].range.lower >> 8;
+ *bufptr++ = attr->values[i].range.lower;
+ *bufptr++ = attr->values[i].range.upper >> 24;
+ *bufptr++ = attr->values[i].range.upper >> 16;
+ *bufptr++ = attr->values[i].range.upper >> 8;
+ *bufptr++ = attr->values[i].range.upper;
+ }
+ break;
+
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < 3)
+ {
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ n = strlen(attr->values[i].string.charset) +
+ strlen(attr->values[i].string.text) +
+ 4;
+
+ if (n > (sizeof(buffer) - 2))
+ return (IPP_ERROR);
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2))
+ {
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ipp_write_file: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ /* Length of entire value */
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+
+ /* Length of charset */
+ n = strlen(attr->values[i].string.charset);
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+
+ /* Charset */
+ memcpy(bufptr, attr->values[i].string.charset, n);
+ bufptr += n;
+
+ /* Length of text */
+ n = strlen(attr->values[i].string.text);
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+
+ /* Text */
+ memcpy(bufptr, attr->values[i].string.text, n);
+ bufptr += n;
+ }
+ break;
+
+ default :
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ if (i)
+ {
+ /*
+ * Arrays and sets are done by sending additional
+ * values with a zero-length name...
+ */
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < 3)
+ {
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ippWrite: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ *bufptr++ = attr->value_tag;
+ *bufptr++ = 0;
+ *bufptr++ = 0;
+ }
+
+ n = attr->values[i].unknown.length;
+
+ if (n > (sizeof(buffer) - 2))
+ return (IPP_ERROR);
+
+ if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2))
+ {
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ipp_write_file: Could not write IPP attribute...");
+ return (IPP_ERROR);
+ }
+
+ bufptr = buffer;
+ }
+
+ /* Length of unknown value */
+ *bufptr++ = n >> 8;
+ *bufptr++ = n;
+
+ /* Value */
+ if (n > 0)
+ {
+ memcpy(bufptr, attr->values[i].unknown.data, n);
+ bufptr += n;
+ }
+ }
+ break;
+ }
+
+ /*
+ * Write the data out...
+ */
+
+ if (write(fd, (char *)buffer, bufptr - buffer) < 0)
+ {
+ DEBUG_puts("ipp_write_file: Could not write IPP attribute...");
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ DEBUG_printf(("ipp_write_file: wrote %d bytes\n", bufptr - buffer));
+ }
+
+ if (ipp->current == NULL)
+ {
+ /*
+ * Done with all of the attributes; add the end-of-attributes tag...
+ */
+
+ buffer[0] = IPP_TAG_END;
+ if (write(fd, (char *)buffer, 1) < 0)
+ {
+ DEBUG_puts("ipp_write_file: Could not write IPP end-tag...");
+ close(fd);
+ return (IPP_ERROR);
+ }
+
+ ipp->state = IPP_DATA;
+ }
+ break;
+
+ case IPP_DATA :
+ break;
+ }
+
+ /*
+ * Close the file and return...
+ */
+
+ close(fd);
+
+ return (ipp->state);
+}
+
+
+/*
+ * 'set_time()' - Set one of the "time-at-xyz" attributes...
+ */
+
+static void
+set_time(job_t *job, /* I - Job to update */
+ const char *name) /* I - Name of attribute */
+{
+ ipp_attribute_t *attr; /* Time attribute */
+
+
+ if ((attr = ippFindAttribute(job->attrs, name, IPP_TAG_ZERO)) != NULL)
+ {
+ attr->value_tag = IPP_TAG_INTEGER;
+ attr->values[0].integer = time(NULL);
+ }
+}
+
+
+/*
+ * 'start_process()' - Start a background process.
+ */
+
+static int /* O - Process ID or 0 */
+start_process(const char *command, /* I - Full path to command */
+ char *argv[], /* I - Command-line arguments */
+ char *envp[], /* I - Environment */
+ int infd, /* I - Standard input file descriptor */
+ int outfd, /* I - Standard output file descriptor */
+ int errfd, /* I - Standard error file descriptor */
+ int root, /* I - Run as root? */
+ int *pid) /* O - Process ID */
+{
+ int fd; /* Looping var */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ sigset_t oldmask, /* POSIX signal masks */
+ newmask;
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ LogMessage(L_DEBUG, "start_process(\"%s\", %p, %p, %d, %d, %d)",
+ command, argv, envp, infd, outfd, errfd);
+
+ /*
+ * Block signals before forking...
+ */
+
+#ifdef HAVE_SIGSET
+ sighold(SIGTERM);
+ sighold(SIGCHLD);
+#elif defined(HAVE_SIGACTION)
+ sigemptyset(&newmask);
+ sigaddset(&newmask, SIGTERM);
+ sigaddset(&newmask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &newmask, &oldmask);
+#endif /* HAVE_SIGSET */
+
+ if ((*pid = fork()) == 0)
+ {
+ /*
+ * Child process goes here...
+ *
+ * Update stdin/stdout/stderr as needed...
+ */
+
+ close(0);
+ dup(infd);
+ close(1);
+ dup(outfd);
+ if (errfd > 2)
+ {
+ close(2);
+ dup(errfd);
+ }
+
+ /*
+ * Close extra file descriptors...
+ */
+
+ for (fd = 3; fd < MaxFDs; fd ++)
+ close(fd);
+
+ /*
+ * Change the priority of the process based on the FilterNice setting.
+ * (this is not done for backends...)
+ */
+
+ if (!root)
+ nice(FilterNice);
+
+ /*
+ * Change user to something "safe"...
+ */
+
+ if (!root && getuid() == 0)
+ {
+ /*
+ * Running as root, so change to non-priviledged user...
+ */
+
+ if (setgid(Group))
+ exit(errno);
+
+ if (setuid(User))
+ exit(errno);
+ }
+
+ /*
+ * Reset group membership to just the main one we belong to.
+ */
+
+ setgroups(0, NULL);
+
+ /*
+ * Change umask to restrict permissions on created files...
+ */
+
+ umask(077);
+
+ /*
+ * Execute the command; if for some reason this doesn't work,
+ * return the error code...
+ */
+
+ execve(command, argv, envp);
+
+ perror(command);
+
+ exit(errno);
+ }
+ else if (*pid < 0)
+ {
+ /*
+ * Error - couldn't fork a new process!
+ */
+
+ LogMessage(L_ERROR, "Unable to fork %s - %s.", command, strerror(errno));
+
+ *pid = 0;
+ }
+
+#ifdef HAVE_SIGSET
+ sigrelse(SIGTERM);
+ sigrelse(SIGCHLD);
+#elif defined(HAVE_SIGACTION)
+ sigprocmask(SIG_SETMASK, &oldmask, NULL);
+#endif /* HAVE_SIGSET */
+
+ return (*pid);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/job.h b/scheduler/job.h
new file mode 100644
index 000000000..1d2e23d9d
--- /dev/null
+++ b/scheduler/job.h
@@ -0,0 +1,108 @@
+/*
+ * "$Id$"
+ *
+ * Print job definitions for the Common UNIX Printing System (CUPS) scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Constants...
+ */
+
+#define JOB_BUFFER_SIZE 1024 /* Bytes for job status buffer */
+
+
+/*
+ * Job request structure...
+ */
+
+typedef struct job_str
+{
+ struct job_str *next; /* Next job in queue */
+ int id, /* Job ID */
+ priority; /* Job priority */
+ ipp_attribute_t *state; /* Job state */
+ ipp_attribute_t *sheets; /* job-media-sheets-completed */
+ time_t hold_until; /* Hold expiration date/time */
+ char username[33]; /* Printing user */
+ char dest[IPP_MAX_NAME]; /* Destination printer or class */
+ cups_ptype_t dtype; /* Destination type (class/remote bits) */
+ char title[IPP_MAX_NAME]; /* Job name/title */
+ ipp_attribute_t *job_sheets; /* Job sheets (NULL if none) */
+ int num_files; /* Number of files in job */
+ int current_file; /* Current file in job */
+ mime_type_t **filetypes; /* File types */
+ ipp_t *attrs; /* Job attributes */
+ int pipe; /* Status pipe for this job */
+ int cost; /* Filtering cost */
+ int procs[MAX_FILTERS + 2]; /* Process IDs, 0 terminated */
+ int status; /* Status code from filters */
+ printer_t *printer; /* Printer this job is assigned to */
+ char *buffer; /* Status buffer */
+ int bufused; /* Amount of buffer in use */
+} job_t;
+
+
+/*
+ * Globals...
+ */
+
+VAR int JobHistory VALUE(1); /* Preserve job history? */
+VAR int JobFiles VALUE(0); /* Preserve job files? */
+VAR int MaxJobs VALUE(0), /* Max number of jobs */
+ MaxJobsPerUser VALUE(0), /* Max jobs per user */
+ MaxJobsPerPrinter VALUE(0); /* Max jobs per printer */
+VAR int JobAutoPurge VALUE(0); /* Automatically purge jobs */
+VAR int NumJobs VALUE(0); /* Number of jobs in queue */
+VAR job_t *Jobs VALUE(NULL); /* List of current jobs */
+VAR int NextJobId VALUE(1); /* Next job ID to use */
+
+
+/*
+ * Prototypes...
+ */
+
+extern job_t *AddJob(int priority, const char *dest);
+extern void CancelJob(int id, int purge);
+extern void CancelJobs(const char *dest);
+extern void CheckJobs(void);
+extern void CleanJobs(void);
+extern void DeleteJob(int id);
+extern job_t *FindJob(int id);
+extern void FreeAllJobs(void);
+extern int GetPrinterJobCount(const char *dest);
+extern int GetUserJobCount(const char *username);
+extern void HoldJob(int id);
+extern void LoadAllJobs(void);
+extern void MoveJob(int id, const char *dest);
+extern void ReleaseJob(int id);
+extern void RestartJob(int id);
+extern void SaveJob(int id);
+extern void SetJobHoldUntil(int id, const char *when);
+extern void SetJobPriority(int id, int priority);
+extern void StartJob(int id, printer_t *printer);
+extern void StopAllJobs(void);
+extern void StopJob(int id, int force);
+extern void UpdateJob(job_t *job);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/listen.c b/scheduler/listen.c
new file mode 100644
index 000000000..a9787c244
--- /dev/null
+++ b/scheduler/listen.c
@@ -0,0 +1,222 @@
+/*
+ * "$Id$"
+ *
+ * Server listening routines for the Common UNIX Printing System (CUPS)
+ * scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * PauseListening() - Clear input polling on all listening sockets...
+ * ResumeListening() - Set input polling on all listening sockets...
+ * StartListening() - Create all listening sockets...
+ * StopListening() - Close all listening sockets...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+
+
+/*
+ * 'PauseListening()' - Clear input polling on all listening sockets...
+ */
+
+void
+PauseListening(void)
+{
+ int i; /* Looping var */
+ listener_t *lis; /* Current listening socket */
+
+
+ if (!FD_ISSET(Listeners[0].fd, &InputSet))
+ return;
+
+ if (NumClients == MaxClients)
+ LogMessage(L_WARN, "Max clients reached, holding new connections...");
+
+ LogMessage(L_DEBUG, "PauseListening: clearing input bits...");
+
+ for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
+ {
+ LogMessage(L_DEBUG2, "PauseListening: Removing fd %d from InputSet...",
+ lis->fd);
+
+ FD_CLR(lis->fd, &InputSet);
+ }
+}
+
+
+/*
+ * 'ResumeListening()' - Set input polling on all listening sockets...
+ */
+
+void
+ResumeListening(void)
+{
+ int i; /* Looping var */
+ listener_t *lis; /* Current listening socket */
+
+
+ if (FD_ISSET(Listeners[0].fd, &InputSet))
+ return;
+
+ if (NumClients >= (MaxClients - 1))
+ LogMessage(L_WARN, "Resuming new connection processing...");
+
+ LogMessage(L_DEBUG, "ResumeListening: setting input bits...");
+
+ for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
+ {
+ LogMessage(L_DEBUG2, "ResumeListening: Adding fd %d to InputSet...",
+ lis->fd);
+
+ FD_SET(lis->fd, &InputSet);
+ }
+}
+
+
+/*
+ * 'StartListening()' - Create all listening sockets...
+ */
+
+void
+StartListening(void)
+{
+ int i, /* Looping var */
+ val; /* Parameter value */
+ listener_t *lis; /* Current listening socket */
+ struct hostent *host; /* Host entry for server address */
+
+
+ LogMessage(L_DEBUG, "StartListening: NumListeners=%d", NumListeners);
+
+ /*
+ * Get the server's IP address...
+ */
+
+ memset(&ServerAddr, 0, sizeof(ServerAddr));
+
+ if ((host = httpGetHostByName(ServerName)) != NULL)
+ {
+ /*
+ * Found the server's address!
+ */
+
+ memcpy((char *)&(ServerAddr.sin_addr), host->h_addr, host->h_length);
+ ServerAddr.sin_family = host->h_addrtype;
+ }
+ else
+ {
+ /*
+ * Didn't find it! Use an address of 0...
+ */
+
+ LogMessage(L_ERROR, "StartListening: Unable to find IP address for server name \"%s\"!\n",
+ ServerName);
+
+ ServerAddr.sin_family = AF_INET;
+ }
+
+ /*
+ * Setup socket listeners...
+ */
+
+ for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
+ {
+ LogMessage(L_DEBUG, "StartListening: address=%08x port=%d",
+ ntohl(lis->address.sin_addr.s_addr),
+ ntohs(lis->address.sin_port));
+
+ if ((lis->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+ {
+ LogMessage(L_ERROR, "StartListening: Unable to open listen socket - %s.",
+ strerror(errno));
+ exit(errno);
+ }
+
+ fcntl(lis->fd, F_SETFD, fcntl(lis->fd, F_GETFD) | FD_CLOEXEC);
+
+ /*
+ * Set things up to reuse the local address for this port.
+ */
+
+ val = 1;
+#ifdef __sun
+ setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
+#else
+ setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
+#endif /* __sun */
+
+ /*
+ * Bind to the port we found...
+ */
+
+ if (bind(lis->fd, (struct sockaddr *)&(lis->address), sizeof(lis->address)) < 0)
+ {
+ LogMessage(L_ERROR, "StartListening: Unable to bind socket - %s.", strerror(errno));
+ exit(errno);
+ }
+
+ /*
+ * Listen for new clients.
+ */
+
+ if (listen(lis->fd, ListenBackLog) < 0)
+ {
+ LogMessage(L_ERROR, "StartListening: Unable to listen for clients - %s.",
+ strerror(errno));
+ exit(errno);
+ }
+ }
+
+ ResumeListening();
+}
+
+
+/*
+ * 'StopListening()' - Close all listening sockets...
+ */
+
+void
+StopListening(void)
+{
+ int i; /* Looping var */
+ listener_t *lis; /* Current listening socket */
+
+
+ LogMessage(L_DEBUG, "StopListening: closing all listen sockets.");
+
+ PauseListening();
+
+ for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
+#ifdef WIN32
+ closesocket(lis->fd);
+#else
+ close(lis->fd);
+#endif /* WIN32 */
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/log.c b/scheduler/log.c
new file mode 100644
index 000000000..5e8b256eb
--- /dev/null
+++ b/scheduler/log.c
@@ -0,0 +1,445 @@
+/*
+ * "$Id$"
+ *
+ * Log file routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * GetDateTime() - Returns a pointer to a date/time string.
+ * LogMessage() - Log a message to the error log file.
+ * LogPage() - Log a page to the page log file.
+ * LogRequest() - Log an HTTP request in Common Log Format.
+ * check_log_file() - Open/rotate a log file if it needs it.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+#include <stdarg.h>
+
+#ifdef HAVE_VSYSLOG
+# include <syslog.h>
+#endif /* HAVE_VSYSLOG */
+
+
+/*
+ * Local functions...
+ */
+
+static int check_log_file(FILE **, const char *);
+
+
+/*
+ * 'GetDateTime()' - Returns a pointer to a date/time string.
+ */
+
+char * /* O - Date/time string */
+GetDateTime(time_t t) /* I - Time value */
+{
+ struct tm *date; /* Date/time value */
+ static char s[1024]; /* Date/time string */
+ static const char *months[12] =/* Months */
+ {
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ };
+
+
+ /*
+ * Get the date and time from the UNIX time value, and then format it
+ * into a string. Note that we *can't* use the strftime() function since
+ * it is localized and will seriously confuse automatic programs if the
+ * month names are in the wrong language!
+ *
+ * Also, we use the "timezone" variable that contains the current timezone
+ * offset from GMT in seconds so that we are reporting local time in the
+ * log files. If you want GMT, set the TZ environment variable accordingly
+ * before starting the scheduler.
+ *
+ * (*BSD and Darwin store the timezone offset in the tm structure)
+ */
+
+ date = localtime(&t);
+
+ snprintf(s, sizeof(s), "[%02d/%s/%04d:%02d:%02d:%02d %+03ld%02ld]",
+ date->tm_mday, months[date->tm_mon], 1900 + date->tm_year,
+ date->tm_hour, date->tm_min, date->tm_sec,
+#ifdef HAVE_TM_GMTOFF
+ date->tm_gmtoff / 3600, (date->tm_gmtoff / 60) % 60);
+#else
+ timezone / 3600, (timezone / 60) % 60);
+#endif /* HAVE_TM_GMTOFF */
+
+ return (s);
+}
+
+
+/*
+ * 'LogMessage()' - Log a message to the error log file.
+ */
+
+int /* O - 1 on success, 0 on error */
+LogMessage(int level, /* I - Log level */
+ const char *message, /* I - printf-style message string */
+ ...) /* I - Additional args as needed */
+{
+ int len; /* Length of message */
+ char line[1024]; /* Line for output file */
+ va_list ap; /* Argument pointer */
+ static char levels[] = /* Log levels... */
+ {
+ ' ',
+ 'X',
+ 'A',
+ 'C',
+ 'E',
+ 'W',
+ 'N',
+ 'I',
+ 'D',
+ 'd'
+ };
+#ifdef HAVE_VSYSLOG
+ static int syslevels[] = /* SYSLOG levels... */
+ {
+ 0,
+ LOG_EMERG,
+ LOG_ALERT,
+ LOG_CRIT,
+ LOG_ERR,
+ LOG_WARNING,
+ LOG_NOTICE,
+ LOG_INFO,
+ LOG_DEBUG,
+ LOG_DEBUG
+ };
+#endif /* HAVE_VSYSLOG */
+
+
+ /*
+ * See if we want to log this message...
+ */
+
+ if (level > LogLevel)
+ return (1);
+
+#ifdef HAVE_VSYSLOG
+ /*
+ * See if we are logging errors via syslog...
+ */
+
+ if (strcmp(ErrorLog, "syslog") == 0)
+ {
+ va_start(ap, message);
+ vsyslog(syslevels[level], message, ap);
+ va_end(ap);
+
+ return (1);
+ }
+#endif /* HAVE_VSYSLOG */
+
+ /*
+ * Not using syslog; check the log file...
+ */
+
+ if (!check_log_file(&ErrorFile, ErrorLog))
+ return (0);
+
+ /*
+ * Print the log level and date/time...
+ */
+
+ fprintf(ErrorFile, "%c %s ", levels[level], GetDateTime(time(NULL)));
+
+ /*
+ * Then the log message...
+ */
+
+ va_start(ap, message);
+ len = vsnprintf(line, sizeof(line), message, ap);
+ va_end(ap);
+
+ /*
+ * Then a newline...
+ */
+
+ fputs(line, ErrorFile);
+ if (len > 0 && line[len - 1] != '\n')
+ putc('\n', ErrorFile);
+
+ fflush(ErrorFile);
+
+ return (1);
+}
+
+
+/*
+ * 'LogPage()' - Log a page to the page log file.
+ */
+
+int /* O - 1 on success, 0 on error */
+LogPage(job_t *job, /* I - Job being printed */
+ const char *page) /* I - Page being printed */
+{
+ ipp_attribute_t *billing; /* job-billing attribute */
+
+
+
+ billing = ippFindAttribute(job->attrs, "job-billing", IPP_TAG_ZERO);
+
+#ifdef HAVE_VSYSLOG
+ /*
+ * See if we are logging pages via syslog...
+ */
+
+ if (strcmp(PageLog, "syslog") == 0)
+ {
+ syslog(LOG_INFO, "PAGE %s %s %d %s %s", job->printer->name, job->username,
+ job->id, page, billing ? billing->values[0].string.text : "");
+
+ return (1);
+ }
+#endif /* HAVE_VSYSLOG */
+
+ /*
+ * Not using syslog; check the log file...
+ */
+
+ if (!check_log_file(&PageFile, PageLog))
+ return (0);
+
+ /*
+ * Print a page log entry of the form:
+ *
+ * printer job-id user [DD/MON/YYYY:HH:MM:SS +TTTT] page num-copies billing
+ */
+
+ fprintf(PageFile, "%s %s %d %s %s %s\n", job->printer->name, job->username,
+ job->id, GetDateTime(time(NULL)), page,
+ billing ? billing->values[0].string.text : "");
+ fflush(PageFile);
+
+ return (1);
+}
+
+
+/*
+ * 'LogRequest()' - Log an HTTP request in Common Log Format.
+ */
+
+int /* O - 1 on success, 0 on error */
+LogRequest(client_t *con, /* I - Request to log */
+ http_status_t code) /* I - Response code */
+{
+ static const char *states[] = /* HTTP client states... */
+ {
+ "WAITING",
+ "OPTIONS",
+ "GET",
+ "GET",
+ "HEAD",
+ "POST",
+ "POST",
+ "POST",
+ "PUT",
+ "PUT",
+ "DELETE",
+ "TRACE",
+ "CLOSE",
+ "STATUS"
+ };
+
+
+#ifdef HAVE_VSYSLOG
+ /*
+ * See if we are logging accesses via syslog...
+ */
+
+ if (strcmp(AccessLog, "syslog") == 0)
+ {
+ syslog(LOG_INFO, "REQUEST %s - %s \"%s %s HTTP/%d.%d\" %d %d\n",
+ con->http.hostname, con->username[0] != '\0' ? con->username : "-",
+ states[con->operation], con->uri,
+ con->http.version / 100, con->http.version % 100,
+ code, con->bytes);
+
+ return (1);
+ }
+#endif /* HAVE_VSYSLOG */
+
+ /*
+ * Not using syslog; check the log file...
+ */
+
+ if (!check_log_file(&AccessFile, AccessLog))
+ return (0);
+
+ /*
+ * Write a log of the request in "common log format"...
+ */
+
+ fprintf(AccessFile, "%s - %s %s \"%s %s HTTP/%d.%d\" %d %d\n",
+ con->http.hostname, con->username[0] != '\0' ? con->username : "-",
+ GetDateTime(con->start), states[con->operation], con->uri,
+ con->http.version / 100, con->http.version % 100,
+ code, con->bytes);
+ fflush(AccessFile);
+
+ return (1);
+}
+
+
+/*
+ * 'check_log_file()' - Open/rotate a log file if it needs it.
+ */
+
+static int /* O - 1 if log file open */
+check_log_file(FILE **log, /* IO - Log file */
+ const char *logname) /* I - Log filename */
+{
+ char backname[1024], /* Backup log filename */
+ filename[1024], /* Formatted log filename */
+ *ptr; /* Pointer into filename */
+
+
+ /*
+ * See if we have a log file to check...
+ */
+
+ if (log == NULL || logname == NULL || !logname[0])
+ return (1);
+
+ /*
+ * Format the filename as needed...
+ */
+
+ if (*log == NULL ||
+ (ftell(*log) > MaxLogSize && MaxLogSize > 0))
+ {
+ /*
+ * Handle format strings...
+ */
+
+ filename[sizeof(filename) - 1] = '\0';
+
+ if (logname[0] != '/')
+ {
+ strlcpy(filename, ServerRoot, sizeof(filename));
+ strlcat(filename, "/", sizeof(filename));
+ }
+ else
+ filename[0] = '\0';
+
+ for (ptr = filename + strlen(filename);
+ *logname && ptr < (filename + sizeof(filename) - 1);
+ logname ++)
+ if (*logname == '%')
+ {
+ /*
+ * Format spec...
+ */
+
+ logname ++;
+ if (*logname == 's')
+ {
+ /*
+ * Insert the server name...
+ */
+
+ strlcpy(ptr, ServerName, sizeof(filename) - (ptr - filename));
+ ptr += strlen(ptr);
+ }
+ else
+ {
+ /*
+ * Otherwise just insert the character...
+ */
+
+ *ptr++ = *logname;
+ }
+ }
+ else
+ *ptr++ = *logname;
+
+ *ptr = '\0';
+ }
+
+ /*
+ * See if the log file is open...
+ */
+
+ if (*log == NULL)
+ {
+ /*
+ * Nope, open the log file...
+ */
+
+ if ((*log = fopen(filename, "a")) == NULL)
+ return (0);
+
+ fchown(fileno(*log), User, Group);
+ fchmod(fileno(*log), LogFilePerm);
+ }
+
+ /*
+ * Do we need to rotate the log?
+ */
+
+ if (ftell(*log) > MaxLogSize && MaxLogSize > 0)
+ {
+ /*
+ * Rotate log file...
+ */
+
+ fclose(*log);
+
+ strcpy(backname, filename);
+ strlcat(backname, ".O", sizeof(backname));
+
+ unlink(backname);
+ rename(filename, backname);
+
+ if ((*log = fopen(filename, "a")) == NULL)
+ return (0);
+
+ fchown(fileno(*log), User, Group);
+ fchmod(fileno(*log), LogFilePerm);
+ }
+
+ return (1);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/main.c b/scheduler/main.c
new file mode 100644
index 000000000..13eb653e2
--- /dev/null
+++ b/scheduler/main.c
@@ -0,0 +1,885 @@
+/*
+ * "$Id$"
+ *
+ * Scheduler main loop for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Main entry for the CUPS scheduler.
+ * CatchChildSignals() - Catch SIGCHLD signals...
+ * IgnoreChildSignals() - Ignore SIGCHLD signals...
+ * sigchld_handler() - Handle 'child' signals from old processes.
+ * sighup_handler() - Handle 'hangup' signals to reconfigure the scheduler.
+ * sigterm_handler() - Handle 'terminate' signals that stop the scheduler.
+ * usage() - Show scheduler usage.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#define _MAIN_C_
+#include "cupsd.h"
+#include <sys/resource.h>
+#include <syslog.h>
+
+#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
+# include <malloc.h>
+#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
+
+#ifndef FD_SETSIZE
+# define FD_SETSIZE 1024
+#endif /* !FD_SETSIZE */
+
+
+/*
+ * Local functions...
+ */
+
+static void sigchld_handler(int sig);
+static void sighup_handler(int sig);
+static void sigterm_handler(int sig);
+static void sigusr1_handler(int sig);
+static void usage(void);
+
+
+/*
+ * 'main()' - Main entry for the CUPS scheduler.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ char *opt; /* Option character */
+ int fg; /* Run in the foreground */
+ fd_set input, /* Input set for select() */
+ output; /* Output set for select() */
+ client_t *con; /* Current client */
+ job_t *job, /* Current job */
+ *next; /* Next job */
+ listener_t *lis; /* Current listener */
+ time_t activity; /* Activity timer */
+ time_t senddoc_time; /* Send-Document time */
+#ifdef HAVE_MALLINFO
+ time_t mallinfo_time; /* Malloc information time */
+#endif /* HAVE_MALLINFO */
+ struct timeval timeout; /* select() timeout */
+ struct rlimit limit; /* Runtime limit */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+#ifdef __sgi
+ FILE *fp; /* Fake lpsched lock file */
+#endif /* __sgi */
+
+
+ /*
+ * Check for command-line arguments...
+ */
+
+ fg = 0;
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ for (opt = argv[i] + 1; *opt != '\0'; opt ++)
+ switch (*opt)
+ {
+ case 'c' : /* Configuration file */
+ i ++;
+ if (i >= argc)
+ usage();
+
+ if (argv[i][0] == '/')
+ {
+ /*
+ * Absolute directory...
+ */
+
+ strlcpy(ConfigurationFile, argv[i], sizeof(ConfigurationFile));
+ }
+ else
+ {
+ /*
+ * Relative directory...
+ */
+
+ getcwd(ConfigurationFile, sizeof(ConfigurationFile));
+ strlcat(ConfigurationFile, "/", sizeof(ConfigurationFile));
+ strlcat(ConfigurationFile, argv[i], sizeof(ConfigurationFile));
+ }
+ break;
+
+ case 'f' : /* Run in foreground... */
+ fg = 1;
+ break;
+
+ case 'F' : /* Run in foreground, but still disconnect from terminal... */
+ fg = -1;
+ break;
+
+ default : /* Unknown option */
+ fprintf(stderr, "cupsd: Unknown option \'%c\' - aborting!\n", *opt);
+ usage();
+ break;
+ }
+ else
+ {
+ fprintf(stderr, "cupsd: Unknown argument \'%s\' - aborting!\n", argv[i]);
+ usage();
+ }
+
+ /*
+ * If the user hasn't specified "-f", run in the background...
+ */
+
+ if (!fg)
+ {
+ if (fork() > 0)
+ {
+ /*
+ * OK, wait for the child to startup and send us SIGUSR1... We
+ * also need to ignore SIGHUP which might be sent by the init
+ * script to restart the scheduler...
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGUSR1, sigusr1_handler);
+
+ sigset(SIGHUP, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGUSR1);
+ action.sa_handler = sigusr1_handler;
+ sigaction(SIGUSR1, &action, NULL);
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGHUP, &action, NULL);
+#else
+ signal(SIGUSR1, sigusr1_handler);
+
+ signal(SIGHUP, SIG_IGN);
+#endif /* HAVE_SIGSET */
+
+ if (wait(&i) < 0)
+ i = 0;
+
+ if (i == 0)
+ return (0);
+
+ if (i >= 256)
+ fprintf(stderr, "cupsd: Child exited with status %d!\n", i / 256);
+ else
+ fprintf(stderr, "cupsd: Child exited on signal %d!\n", i);
+
+ return (i);
+ }
+ }
+
+ if (fg < 1)
+ {
+ /*
+ * Make sure we aren't tying up any filesystems...
+ */
+
+ chdir("/");
+
+#ifndef DEBUG
+ /*
+ * Disable core dumps...
+ */
+
+ getrlimit(RLIMIT_CORE, &limit);
+ limit.rlim_cur = 0;
+ setrlimit(RLIMIT_CORE, &limit);
+
+ /*
+ * Disconnect from the controlling terminal...
+ */
+
+ close(0);
+ close(1);
+ close(2);
+
+ setsid();
+#endif /* DEBUG */
+ }
+
+ /*
+ * Set the timezone info...
+ */
+
+ if (getenv("TZ") != NULL)
+ snprintf(TZ, sizeof(TZ), "TZ=%s", getenv("TZ"));
+ else
+ TZ[0] = '\0';
+
+ tzset();
+
+ /*
+ * Set the maximum number of files...
+ */
+
+ getrlimit(RLIMIT_NOFILE, &limit);
+ if (limit.rlim_max > FD_SETSIZE) /* Can't exceed size of FD set! */
+ MaxFDs = FD_SETSIZE;
+ else
+ MaxFDs = limit.rlim_max;
+
+ limit.rlim_cur = MaxFDs;
+ setrlimit(RLIMIT_NOFILE, &limit);
+
+ /*
+ * Catch hangup and child signals and ignore broken pipes...
+ */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ if (RunAsUser)
+ sigset(SIGHUP, sigterm_handler);
+ else
+ sigset(SIGHUP, sighup_handler);
+ sigset(SIGPIPE, SIG_IGN);
+ sigset(SIGTERM, sigterm_handler);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGHUP);
+
+ if (RunAsUser)
+ action.sa_handler = sigterm_handler;
+ else
+ action.sa_handler = sighup_handler;
+
+ sigaction(SIGHUP, &action, NULL);
+
+ sigemptyset(&action.sa_mask);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &action, NULL);
+
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGTERM);
+ sigaddset(&action.sa_mask, SIGCHLD);
+ action.sa_handler = sigterm_handler;
+ sigaction(SIGTERM, &action, NULL);
+#else
+ if (RunAsUser)
+ signal(SIGHUP, sigterm_handler);
+ else
+ signal(SIGHUP, sighup_handler);
+
+ signal(SIGPIPE, SIG_IGN);
+ signal(SIGTERM, sigterm_handler);
+#endif /* HAVE_SIGSET */
+
+ /*
+ * Read configuration...
+ */
+
+ if (!ReadConfiguration())
+ {
+ syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
+ ConfigurationFile);
+ return (1);
+ }
+
+#ifdef __sgi
+ /*
+ * Try to create a fake lpsched lock file if one is not already there.
+ * Some Adobe applications need it under IRIX in order to enable
+ * printing...
+ */
+
+ if ((fp = fopen("/var/spool/lp/SCHEDLOCK", "a")) == NULL)
+ {
+ syslog(LOG_LPR, "Unable to create fake lpsched lock file "
+ "\"/var/spool/lp/SCHEDLOCK\"\' - %s!",
+ strerror(errno));
+ }
+ else
+ {
+ fclose(fp);
+
+ chmod("/var/spool/lp/SCHEDLOCK", 0644);
+ chown("/var/spool/lp/SCHEDLOCK", User, Group);
+ }
+#endif /* __sgi */
+
+ /*
+ * Initialize authentication certificates...
+ */
+
+ InitCerts();
+
+ /*
+ * If we are running in the background, signal the parent process that
+ * we are up and running...
+ */
+
+ if (!fg)
+ kill(getppid(), SIGUSR1);
+
+ /*
+ * Loop forever...
+ */
+
+ senddoc_time = time(NULL);
+
+#ifdef HAVE_MALLINFO
+ mallinfo_time = 0;
+#endif /* HAVE_MALLINFO */
+
+ for (;;)
+ {
+ /*
+ * Check if we need to load the server configuration file...
+ */
+
+ if (NeedReload)
+ {
+ if (NumClients > 0)
+ {
+ for (i = NumClients, con = Clients; i > 0; i --, con ++)
+ if (con->http.state == HTTP_WAITING)
+ {
+ CloseClient(con);
+ con --;
+ }
+ else
+ con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+
+ PauseListening();
+ }
+ else if (!ReadConfiguration())
+ {
+ syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
+ ConfigurationFile);
+ break;
+ }
+ }
+
+ /*
+ * Check for available input or ready output. If select() returns
+ * 0 or -1, something bad happened and we should exit immediately.
+ *
+ * Note that we at least have one listening socket open at all
+ * times.
+ */
+
+ input = InputSet;
+ output = OutputSet;
+
+ for (i = NumClients, con = Clients; i > 0; i --, con ++)
+ if (con->http.used > 0)
+ break;
+
+ if (i)
+ {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ }
+ else
+ {
+ /*
+ * If we have no pending data from a client, see when we really
+ * need to wake up...
+ */
+
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+ }
+
+ if ((i = select(MaxFDs, &input, &output, NULL, &timeout)) < 0)
+ {
+ char s[16384], /* String buffer */
+ *sptr; /* Pointer into buffer */
+ int slen; /* Length of string buffer */
+
+
+ /*
+ * Got an error from select!
+ */
+
+ if (errno == EINTR) /* Just interrupted by a signal */
+ continue;
+
+ /*
+ * Log all sorts of debug info to help track down the problem.
+ */
+
+ LogMessage(L_EMERG, "select() failed - %s!", strerror(errno));
+
+ strcpy(s, "InputSet =");
+ slen = 10;
+ sptr = s + 10;
+
+ for (i = 0; i < MaxFDs; i ++)
+ if (FD_ISSET(i, &InputSet))
+ {
+ snprintf(sptr, sizeof(s) - slen, " %d", i);
+ slen += strlen(sptr);
+ sptr += strlen(sptr);
+ }
+
+ LogMessage(L_EMERG, s);
+
+ strcpy(s, "OutputSet =");
+ slen = 11;
+ sptr = s + 11;
+
+ for (i = 0; i < MaxFDs; i ++)
+ if (FD_ISSET(i, &OutputSet))
+ {
+ snprintf(sptr, sizeof(s) - slen, " %d", i);
+ slen += strlen(sptr);
+ sptr += strlen(sptr);
+ }
+
+ LogMessage(L_EMERG, s);
+
+ for (i = 0, con = Clients; i < NumClients; i ++, con ++)
+ LogMessage(L_EMERG, "Clients[%d] = %d, file = %d, state = %d",
+ i, con->http.fd, con->file, con->http.state);
+
+ for (i = 0, lis = Listeners; i < NumListeners; i ++, lis ++)
+ LogMessage(L_EMERG, "Listeners[%d] = %d", i, lis->fd);
+
+ LogMessage(L_EMERG, "BrowseSocket = %d", BrowseSocket);
+
+ for (job = Jobs; job != NULL; job = job->next)
+ LogMessage(L_EMERG, "Jobs[%d] = %d", job->id, job->pipe);
+
+ break;
+ }
+
+ for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
+ if (FD_ISSET(lis->fd, &input))
+ AcceptClient(lis);
+
+ for (i = NumClients, con = Clients; i > 0; i --, con ++)
+ {
+ /*
+ * Process the input buffer...
+ */
+
+ if (FD_ISSET(con->http.fd, &input) || con->http.used)
+ if (!ReadClient(con))
+ {
+ con --;
+ continue;
+ }
+
+ /*
+ * Write data as needed...
+ */
+
+ if (FD_ISSET(con->http.fd, &output) &&
+ (!con->pipe_pid || FD_ISSET(con->file, &input)))
+ if (!WriteClient(con))
+ {
+ con --;
+ continue;
+ }
+
+ /*
+ * Check the activity and close old clients...
+ */
+
+ activity = time(NULL) - Timeout;
+ if (con->http.activity < activity && !con->pipe_pid)
+ {
+ CloseClient(con);
+ con --;
+ continue;
+ }
+ }
+
+ /*
+ * Check for status info from job filters...
+ */
+
+ for (job = Jobs; job != NULL; job = next)
+ {
+ next = job->next;
+
+ if (job->pipe && FD_ISSET(job->pipe, &input))
+ {
+ /*
+ * Clear the input bit to avoid updating the next job
+ * using the same status pipe file descriptor...
+ */
+
+ FD_CLR(job->pipe, &input);
+
+ /*
+ * Read any status messages from the filters...
+ */
+
+ UpdateJob(job);
+ }
+ }
+
+ /*
+ * Update the browse list as needed...
+ */
+
+ if (Browsing && BrowseProtocols)
+ {
+ if (BrowseSocket >= 0 && FD_ISSET(BrowseSocket, &input))
+ UpdateCUPSBrowse();
+
+ if (PollPipe >= 0 && FD_ISSET(PollPipe, &input))
+ UpdatePolling();
+
+#ifdef HAVE_LIBSLP
+ if ((BrowseProtocols & BROWSE_SLP) && BrowseSLPRefresh <= time(NULL))
+ UpdateSLPBrowse();
+#endif /* HAVE_LIBSLP */
+
+ SendBrowseList();
+ }
+
+ /*
+ * Update any pending multi-file documents...
+ */
+
+ if ((time(NULL) - senddoc_time) >= 10)
+ {
+ CheckJobs();
+ senddoc_time = time(NULL);
+ }
+
+#ifdef HAVE_MALLINFO
+ /*
+ * Log memory usage every minute...
+ */
+
+ if ((time(NULL) - mallinfo_time) >= 60 && LogLevel >= L_DEBUG)
+ {
+ struct mallinfo mem; /* Malloc information */
+
+
+ mem = mallinfo();
+ LogMessage(L_DEBUG, "mallinfo: arena = %d, used = %d, free = %d\n",
+ mem.arena, mem.usmblks + mem.uordblks,
+ mem.fsmblks + mem.fordblks);
+ mallinfo_time = time(NULL);
+ }
+#endif /* HAVE_MALLINFO */
+
+ /*
+ * Update the root certificate once every 5 minutes...
+ */
+
+ if ((time(NULL) - RootCertTime) >= RootCertDuration && RootCertDuration)
+ {
+ /*
+ * Update the root certificate...
+ */
+
+ DeleteCert(0);
+ AddCert(0, "root");
+ }
+ }
+
+ /*
+ * If we get here something very bad happened and we need to exit
+ * immediately.
+ */
+
+ DeleteAllCerts();
+ CloseAllClients();
+ StopListening();
+
+ return (1);
+}
+
+
+/*
+ * 'CatchChildSignals()' - Catch SIGCHLD signals...
+ */
+
+void
+CatchChildSignals(void)
+{
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGCHLD, sigchld_handler);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGTERM);
+ sigaddset(&action.sa_mask, SIGCHLD);
+ action.sa_handler = sigchld_handler;
+ sigaction(SIGCHLD, &action, NULL);
+#else
+ signal(SIGCLD, sigchld_handler); /* No, SIGCLD isn't a typo... */
+#endif /* HAVE_SIGSET */
+}
+
+
+/*
+ * 'IgnoreChildSignals()' - Ignore SIGCHLD signals...
+ */
+
+void
+IgnoreChildSignals(void)
+{
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Actions for POSIX signals */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+ sigset(SIGCHLD, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGCHLD);
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGCHLD, &action, NULL);
+#else
+ signal(SIGCLD, SIG_IGN); /* No, SIGCLD isn't a typo... */
+#endif /* HAVE_SIGSET */
+}
+
+
+/*
+ * 'sigchld_handler()' - Handle 'child' signals from old processes.
+ */
+
+static void
+sigchld_handler(int sig) /* I - Signal number */
+{
+ int status; /* Exit status of child */
+ int pid; /* Process ID of child */
+ job_t *job; /* Current job */
+ int i; /* Looping var */
+
+
+ (void)sig;
+
+#ifdef HAVE_WAITPID
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
+#elif defined(HAVE_WAIT3)
+ while ((pid = wait3(&status, WNOHANG, NULL)) > 0)
+#else
+ if ((pid = wait(&status)) > 0)
+#endif /* HAVE_WAITPID */
+ {
+ DEBUG_printf(("sigchld_handler: pid = %d, status = %d\n", pid, status));
+
+ /*
+ * Delete certificates for CGI processes...
+ */
+
+ if (pid)
+ DeleteCert(pid);
+
+ /*
+ * Ignore SIGTERM errors - that comes when a job is cancelled...
+ */
+
+ if (status == SIGTERM)
+ status = 0;
+
+ if (status)
+ {
+ if (status < 256)
+ LogMessage(L_ERROR, "PID %d crashed on signal %d!", pid, status);
+ else
+ LogMessage(L_ERROR, "PID %d stopped with status %d!", pid,
+ status / 256);
+
+ if (LogLevel < L_DEBUG)
+ LogMessage(L_INFO, "Hint: Try setting the LogLevel to \"debug\" to find out more.");
+ }
+
+ for (job = Jobs; job != NULL; job = job->next)
+ if (job->state != NULL &&
+ job->state->values[0].integer == IPP_JOB_PROCESSING)
+ {
+ for (i = 0; job->procs[i]; i ++)
+ if (job->procs[i] == pid)
+ break;
+
+ if (job->procs[i])
+ {
+ /*
+ * OK, this process has gone away; what's left?
+ */
+
+ job->procs[i] = -pid;
+
+ if (status && job->status >= 0)
+ {
+ /*
+ * An error occurred; save the exit status so we know to stop
+ * the printer or cancel the job when all of the filters finish...
+ *
+ * A negative status indicates that the backend failed and the
+ * printer needs to be stopped.
+ */
+
+ if (!job->procs[i + 1])
+ job->status = -status; /* Backend failed */
+ else
+ job->status = status; /* Filter failed */
+ }
+ break;
+ }
+ }
+ }
+
+#ifdef HAVE_SIGSET
+ sigset(SIGCHLD, sigchld_handler);
+#elif !defined(HAVE_SIGACTION)
+ signal(SIGCLD, sigchld_handler);
+#endif /* HAVE_SIGSET */
+}
+
+
+/*
+ * 'sighup_handler()' - Handle 'hangup' signals to reconfigure the scheduler.
+ */
+
+static void
+sighup_handler(int sig) /* I - Signal number */
+{
+ (void)sig;
+
+ NeedReload = TRUE;
+
+#ifdef HAVE_SIGSET
+ sigset(SIGHUP, sighup_handler);
+#elif !defined(HAVE_SIGACTION)
+ signal(SIGHUP, sighup_handler);
+#endif /* HAVE_SIGSET */
+}
+
+
+/*
+ * 'sigterm_handler()' - Handle 'terminate' signals that stop the scheduler.
+ */
+
+static void
+sigterm_handler(int sig) /* I - Signal */
+{
+#ifdef __sgi
+ struct stat statbuf; /* Needed for checking lpsched FIFO */
+#endif /* __sgi */
+
+
+ (void)sig; /* remove compiler warnings... */
+
+ /*
+ * Log an error...
+ */
+
+ LogMessage(L_ERROR, "Scheduler shutting down due to SIGTERM.");
+
+ /*
+ * Close all network clients and stop all jobs...
+ */
+
+ CloseAllClients();
+ StopListening();
+ StopPolling();
+ StopBrowsing();
+
+ if (Clients != NULL)
+ free(Clients);
+
+ FreeAllJobs();
+
+ if (AccessFile != NULL)
+ fclose(AccessFile);
+
+ if (ErrorFile != NULL)
+ fclose(ErrorFile);
+
+ if (PageFile != NULL)
+ fclose(PageFile);
+
+ DeleteAllLocations();
+
+ DeleteAllClasses();
+
+ if (Devices)
+ ippDelete(Devices);
+
+ if (PPDs)
+ ippDelete(PPDs);
+
+ DeleteAllPrinters();
+
+ if (MimeDatabase != NULL)
+ mimeDelete(MimeDatabase);
+
+#ifdef __sgi
+ /*
+ * Remove the fake IRIX lpsched lock file, but only if the existing
+ * file is not a FIFO which indicates that the real IRIX lpsched is
+ * running...
+ */
+
+ if (!stat("/var/spool/lp/FIFO", &statbuf))
+ if (!S_ISFIFO(statbuf.st_mode))
+ unlink("/var/spool/lp/SCHEDLOCK");
+#endif /* __sgi */
+
+ exit(1);
+}
+
+
+/*
+ * 'sigusr1_handler()' - Catch USR1 signals...
+ */
+
+static void
+sigusr1_handler(int sig) /* I - Signal */
+{
+ (void)sig; /* remove compiler warnings... */
+}
+
+
+/*
+ * 'usage()' - Show scheduler usage.
+ */
+
+static void
+usage(void)
+{
+ fputs("Usage: cupsd [-c config-file] [-f]\n", stderr);
+ exit(1);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/mime.c b/scheduler/mime.c
new file mode 100644
index 000000000..3fddf95f6
--- /dev/null
+++ b/scheduler/mime.c
@@ -0,0 +1,600 @@
+/*
+ * "$Id$"
+ *
+ * MIME database file routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * mimeDelete() - Delete (free) a MIME database.
+ * mimeMerge() - Merge a MIME database from disk with the current one.
+ * mimeNew() - Create a new, empty MIME database.
+ * load_types() - Load a xyz.types file...
+ * delete_rules() - Free all memory for the given rule tree.
+ * load_convs() - Load a xyz.convs file...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <cups/string.h>
+#include "mime.h"
+
+#ifdef WIN32
+# include <windows.h>
+#elif HAVE_DIRENT_H
+# include <dirent.h>
+typedef struct dirent DIRENT;
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+typedef struct direct DIRENT;
+# define NAMLEN(dirent) (dirent)->d_namlen
+#endif
+
+
+/*
+ * Local functions...
+ */
+
+static void load_types(mime_t *mime, const char *filename);
+static void load_convs(mime_t *mime, const char *filename,
+ const char *filterpath);
+static void delete_rules(mime_magic_t *rules);
+
+
+/*
+ * 'mimeDelete()' - Delete (free) a MIME database.
+ */
+
+void
+mimeDelete(mime_t *mime) /* I - MIME database */
+{
+ int i; /* Looping var */
+
+
+ if (mime == NULL)
+ return;
+
+ /*
+ * Loop through the file types and delete any rules...
+ */
+
+ for (i = 0; i < mime->num_types; i ++)
+ {
+ delete_rules(mime->types[i]->rules);
+ free(mime->types[i]->type);
+ free(mime->types[i]);
+ }
+
+ /*
+ * Free the types and filters arrays, and then the MIME database structure.
+ */
+
+ free(mime->types);
+ free(mime->filters);
+ free(mime);
+}
+
+
+/*
+ * 'mimeMerge()' - Merge a MIME database from disk with the current one.
+ */
+
+mime_t * /* O - Updated MIME database */
+mimeMerge(mime_t *mime, /* I - MIME database to add to */
+ const char *pathname, /* I - Directory to load */
+ const char *filterpath)/* I - Directory to load */
+{
+#ifdef WIN32
+ HANDLE dir; /* Directory handle */
+ WIN32_FIND_DATA dent; /* Directory entry */
+ char filename[1024], /* Full filename of types/converts file */
+ *pathsep; /* Last character in path */
+
+
+ /*
+ * First open the directory specified by pathname... Return NULL if nothing
+ * was read or if the pathname is NULL...
+ */
+
+ if (pathname == NULL)
+ return (NULL);
+
+ strlcpy(filename, pathname, sizeof(filename));
+
+ pathsep = filename + strlen(filename);
+ if ((pathsep - filename + 9) > sizeof(filename))
+ return (NULL);
+
+ if (pathsep == filename ||
+ (pathsep[-1] != '/' && pathsep[-1] != '\\'))
+ {
+ strcpy(pathsep, "/");
+ pathsep ++;
+ }
+
+ strcpy(pathsep, "*.types");
+
+ if ((dir = FindFirstFile(filename, &dent)) == 0)
+ return (NULL);
+
+ /*
+ * If "mime" is NULL, make a new, blank database...
+ */
+
+ if (mime == NULL)
+ if ((mime = mimeNew()) == NULL)
+ return (NULL);
+
+ /*
+ * Read all the .types files...
+ */
+
+ do
+ {
+ /*
+ * Load a mime.types file...
+ */
+
+ if ((pathsep - filename + strlen(dent.cFileName)) >= sizeof(filename))
+ continue;
+
+ strcpy(pathsep, dent.cFileName);
+ load_types(mime, filename);
+ }
+ while (FindNextFile(dir, &dent));
+
+ FindClose(dir);
+
+ /*
+ * Read all the .convs files...
+ */
+
+ strcpy(pathsep, "*.convs");
+
+ if ((dir = FindFirstFile(filename, &dent)) == 0)
+ return (mime);
+
+ do
+ {
+ /*
+ * Load a mime.convs file...
+ */
+
+ if ((pathsep - filename + strlen(dent.cFileName)) >= sizeof(filename))
+ continue;
+
+ strcpy(pathsep, dent.cFileName);
+ load_convs(mime, filename);
+ }
+ while (FindNextFile(dir, &dent));
+
+ FindClose(dir);
+
+ return (mime);
+#else
+ DIR *dir; /* Directory */
+ DIRENT *dent; /* Directory entry */
+ char filename[1024]; /* Full filename of types/converts file */
+
+
+ /*
+ * First open the directory specified by pathname... Return NULL if nothing
+ * was read or if the pathname is NULL...
+ */
+
+ if (pathname == NULL)
+ return (NULL);
+
+ if ((dir = opendir(pathname)) == NULL)
+ return (NULL);
+
+ /*
+ * If "mime" is NULL, make a new, blank database...
+ */
+
+ if (mime == NULL)
+ if ((mime = mimeNew()) == NULL)
+ return (NULL);
+
+ /*
+ * Read all the .types files...
+ */
+
+ while ((dent = readdir(dir)) != NULL)
+ {
+ if (NAMLEN(dent) > 6 &&
+ strcmp(dent->d_name + NAMLEN(dent) - 6, ".types") == 0)
+ {
+ /*
+ * Load a mime.types file...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->d_name);
+ load_types(mime, filename);
+ }
+ }
+
+ rewinddir(dir);
+
+ /*
+ * Read all the .convs files...
+ */
+
+ while ((dent = readdir(dir)) != NULL)
+ {
+ if (NAMLEN(dent) > 6 &&
+ strcmp(dent->d_name + NAMLEN(dent) - 6, ".convs") == 0)
+ {
+ /*
+ * Load a mime.convs file...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->d_name);
+ load_convs(mime, filename, filterpath);
+ }
+ }
+
+ closedir(dir);
+
+ return (mime);
+#endif /* WIN32 */
+}
+
+
+/*
+ * 'mimeNew()' - Create a new, empty MIME database.
+ */
+
+mime_t * /* O - MIME database */
+mimeNew(void)
+{
+ return ((mime_t *)calloc(1, sizeof(mime_t)));
+}
+
+
+/*
+ * 'load_types()' - Load a xyz.types file...
+ */
+
+static void
+load_types(mime_t *mime, /* I - MIME database */
+ const char *filename) /* I - Types file to load */
+{
+ FILE *fp; /* Types file */
+ int linelen; /* Length of line */
+ char line[65536], /* Input line from file */
+ *lineptr, /* Current position in line */
+ super[MIME_MAX_SUPER], /* Super-type name */
+ type[MIME_MAX_TYPE], /* Type name */
+ *temp; /* Temporary pointer */
+ mime_type_t *typeptr; /* New MIME type */
+
+
+ /*
+ * First try to open the file...
+ */
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ return;
+
+ /*
+ * Then read each line from the file, skipping any comments in the file...
+ */
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ linelen = strlen(line);
+
+ /*
+ * While the last character in the line is a backslash, continue on to the
+ * next line (and the next, etc.)
+ */
+
+ if (line[linelen - 1] == '\n')
+ {
+ line[linelen - 1] = '\0';
+ linelen --;
+ }
+
+ while (line[linelen - 1] == '\\')
+ {
+ linelen --;
+
+ if (fgets(line + linelen, sizeof(line) - linelen, fp) == NULL)
+ line[linelen] = '\0';
+ else
+ {
+ linelen += strlen(line + linelen);
+ if (line[linelen - 1] == '\n')
+ {
+ line[linelen - 1] = '\0';
+ linelen --;
+ }
+ }
+ }
+
+ /*
+ * Skip blank lines and lines starting with a #...
+ */
+
+ if (line[0] == '\n' || line[0] == '#')
+ continue;
+
+ /*
+ * Extract the super-type and type names from the beginning of the line.
+ */
+
+ lineptr = line;
+ temp = super;
+
+ while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' &&
+ (temp - super + 1) < MIME_MAX_SUPER)
+ *temp++ = tolower(*lineptr++);
+
+ *temp = '\0';
+
+ if (*lineptr != '/')
+ continue;
+
+ lineptr ++;
+ temp = type;
+
+ while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' &&
+ *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE)
+ *temp++ = tolower(*lineptr++);
+
+ *temp = '\0';
+
+ /*
+ * Add the type and rules to the MIME database...
+ */
+
+ typeptr = mimeAddType(mime, super, type);
+ mimeAddTypeRule(typeptr, lineptr);
+ }
+
+ fclose(fp);
+}
+
+
+/*
+ * 'load_convs()' - Load a xyz.convs file...
+ */
+
+static void
+load_convs(mime_t *mime, /* I - MIME database */
+ const char *filename, /* I - Convs file to load */
+ const char *filterpath) /* I - Directory to load */
+{
+ int i; /* Looping var */
+ FILE *fp; /* Convs file */
+ char line[1024], /* Input line from file */
+ *lineptr, /* Current position in line */
+ super[MIME_MAX_SUPER], /* Super-type name */
+ type[MIME_MAX_TYPE], /* Type name */
+ *temp, /* Temporary pointer */
+ *filter; /* Filter program */
+ mime_type_t **temptype, /* MIME type looping var */
+ *dsttype; /* Destination MIME type */
+ int cost; /* Cost of filter */
+ char filterprog[1024]; /* Full path of filter... */
+
+
+ /*
+ * First try to open the file...
+ */
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ return;
+
+ /*
+ * Then read each line from the file, skipping any comments in the file...
+ */
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Skip blank lines and lines starting with a #...
+ */
+
+ if (line[0] == '\n' || line[0] == '#')
+ continue;
+
+ /*
+ * Strip trailing whitespace...
+ */
+
+ for (lineptr = line + strlen(line) - 1;
+ lineptr >= line && isspace(*lineptr);
+ lineptr --)
+ *lineptr = '\0';
+
+ /*
+ * Extract the destination super-type and type names from the middle of
+ * the line.
+ */
+
+ lineptr = line;
+ while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\0')
+ lineptr ++;
+
+ while (*lineptr == ' ' || *lineptr == '\t')
+ lineptr ++;
+
+ temp = super;
+
+ while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' &&
+ (temp - super + 1) < MIME_MAX_SUPER)
+ *temp++ = tolower(*lineptr++);
+
+ *temp = '\0';
+
+ if (*lineptr != '/')
+ continue;
+
+ lineptr ++;
+ temp = type;
+
+ while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' &&
+ *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE)
+ *temp++ = tolower(*lineptr++);
+
+ *temp = '\0';
+
+ if (*lineptr == '\0' || *lineptr == '\n')
+ continue;
+
+ if ((dsttype = mimeType(mime, super, type)) == NULL)
+ continue;
+
+ /*
+ * Then get the cost and filter program...
+ */
+
+ while (*lineptr == ' ' || *lineptr == '\t')
+ lineptr ++;
+
+ if (*lineptr < '0' || *lineptr > '9')
+ continue;
+
+ cost = atoi(lineptr);
+
+ while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\0')
+ lineptr ++;
+ while (*lineptr == ' ' || *lineptr == '\t')
+ lineptr ++;
+
+ if (*lineptr == '\0' || *lineptr == '\n')
+ continue;
+
+ filter = lineptr;
+
+#ifndef WIN32
+ if (strcmp(filter, "-") != 0)
+ {
+ /*
+ * Verify that the filter exists and is executable...
+ */
+
+ if (filter[0] == '/')
+ strlcpy(filterprog, filter, sizeof(filterprog));
+ else
+ snprintf(filterprog, sizeof(filterprog), "%s/%s", filterpath, filter);
+
+ if (access(filterprog, X_OK))
+ continue;
+ }
+#endif /* !WIN32 */
+
+ /*
+ * Finally, get the source super-type and type names from the beginning of
+ * the line. We do it here so we can support wildcards...
+ */
+
+ lineptr = line;
+ temp = super;
+
+ while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' &&
+ (temp - super + 1) < MIME_MAX_SUPER)
+ *temp++ = tolower(*lineptr++);
+
+ *temp = '\0';
+
+ if (*lineptr != '/')
+ continue;
+
+ lineptr ++;
+ temp = type;
+
+ while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' &&
+ *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE)
+ *temp++ = tolower(*lineptr++);
+
+ *temp = '\0';
+
+ if (strcmp(super, "*") == 0 && strcmp(type, "*") == 0)
+ {
+ /*
+ * Force * / * to be "application/octet-stream"...
+ */
+
+ strcpy(super, "application");
+ strcpy(type, "octet-stream");
+ }
+
+ /*
+ * Add the filter to the MIME database, supporting wildcards as needed...
+ */
+
+ for (temptype = mime->types, i = 0; i < mime->num_types; i ++, temptype ++)
+ if ((super[0] == '*' || strcmp((*temptype)->super, super) == 0) &&
+ (type[0] == '*' || strcmp((*temptype)->type, type) == 0))
+ mimeAddFilter(mime, *temptype, dsttype, cost, filter);
+ }
+
+ fclose(fp);
+}
+
+
+/*
+ * 'delete_rules()' - Free all memory for the given rule tree.
+ */
+
+static void
+delete_rules(mime_magic_t *rules) /* I - Rules to free */
+{
+ mime_magic_t *next; /* Next rule to free */
+
+
+ /*
+ * Free the rules list, descending recursively to free any child rules.
+ */
+
+ while (rules != NULL)
+ {
+ next = rules->next;
+
+ if (rules->child != NULL)
+ delete_rules(rules->child);
+
+ free(rules);
+ rules = next;
+ }
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/mime.h b/scheduler/mime.h
new file mode 100644
index 000000000..35dc4d7aa
--- /dev/null
+++ b/scheduler/mime.h
@@ -0,0 +1,143 @@
+/*
+ * "$Id$"
+ *
+ * MIME type/conversion database definitions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+#ifndef _MIME_H_
+# define _MIME_H_
+
+# include <cups/ipp.h>
+
+
+/*
+ * C++ magic...
+ */
+
+# ifdef _cplusplus
+extern "C" {
+# endif /* _cplusplus */
+
+
+/*
+ * Constants...
+ */
+
+# define MIME_MAX_SUPER 16 /* Maximum size of supertype name */
+# define MIME_MAX_TYPE IPP_MAX_NAME /* Maximum size of type name */
+# define MIME_MAX_FILTER 256 /* Maximum size of filter pathname */
+# define MIME_MAX_BUFFER 8192 /* Maximum size of file buffer */
+
+
+/*
+ * Types/structures...
+ */
+
+typedef enum
+{
+ MIME_MAGIC_NOP, /* No operation */
+ MIME_MAGIC_AND, /* Logical AND of all children */
+ MIME_MAGIC_OR, /* Logical OR of all children */
+ MIME_MAGIC_MATCH, /* Filename match */
+ MIME_MAGIC_ASCII, /* ASCII characters in range */
+ MIME_MAGIC_PRINTABLE, /* Printable characters (32-255) in range */
+ MIME_MAGIC_STRING, /* String matches */
+ MIME_MAGIC_CHAR, /* Character/byte matches */
+ MIME_MAGIC_SHORT, /* Short/16-bit word matches */
+ MIME_MAGIC_INT, /* Integer/32-bit word matches */
+ MIME_MAGIC_LOCALE, /* Current locale matches string */
+ MIME_MAGIC_CONTAINS /* File contains a string */
+} mime_op_t;
+
+typedef struct mime_magic_str /**** MIME Magic Data ****/
+{
+ struct mime_magic_str *prev, /* Previous rule */
+ *next, /* Next rule */
+ *parent, /* Parent rules */
+ *child; /* Child rules */
+ short op, /* Operation code (see above) */
+ invert; /* Invert the result */
+ int offset, /* Offset in file */
+ region, /* Region length */
+ length; /* Length of data */
+ union
+ {
+ char matchv[64]; /* Match value */
+ char localev[64]; /* Locale value */
+ char stringv[64]; /* String value */
+ char charv; /* Byte value */
+ short shortv; /* Short value */
+ int intv; /* Integer value */
+ } value;
+} mime_magic_t;
+
+typedef struct /**** MIME Type Data ****/
+{
+ char super[MIME_MAX_SUPER], /* Super-type name ("image", "application", etc.) */
+ *type; /* Type name ("png", "postscript", etc.) */
+ mime_magic_t *rules; /* Rules used to detect this type */
+} mime_type_t;
+
+typedef struct /**** MIME Conversion Filter Data ****/
+{
+ mime_type_t *src, /* Source type */
+ *dst; /* Destination type */
+ int cost; /* Relative cost */
+ char filter[MIME_MAX_FILTER];/* Filter program to use */
+} mime_filter_t;
+
+typedef struct /**** MIME Database ****/
+{
+ int num_types; /* Number of file types */
+ mime_type_t **types; /* File types */
+ int num_filters; /* Number of type conversion filters */
+ mime_filter_t *filters; /* Type conversion filters */
+} mime_t;
+
+
+/*
+ * Functions...
+ */
+
+extern void mimeDelete(mime_t *mime);
+#define mimeLoad(pathname) mimeMerge((mime_t *)0, (pathname));
+extern mime_t *mimeMerge(mime_t *mime, const char *pathname,
+ const char *filterpath);
+extern mime_t *mimeNew(void);
+
+extern mime_type_t *mimeAddType(mime_t *mime, const char *super, const char *type);
+extern int mimeAddTypeRule(mime_type_t *mt, const char *rule);
+extern mime_type_t *mimeFileType(mime_t *mime, const char *pathname);
+extern mime_type_t *mimeType(mime_t *mime, const char *super, const char *type);
+
+extern mime_filter_t *mimeAddFilter(mime_t *mime, mime_type_t *src, mime_type_t *dst,
+ int cost, const char *filter);
+extern mime_filter_t *mimeFilter(mime_t *mime, mime_type_t *src, mime_type_t *dst,
+ int *num_filters, int max_depth);
+
+# ifdef _cplusplus
+}
+# endif /* _cplusplus */
+#endif /* !_MIME_H_ */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/network.c b/scheduler/network.c
new file mode 100644
index 000000000..cfea9ebff
--- /dev/null
+++ b/scheduler/network.c
@@ -0,0 +1,476 @@
+/*
+ * "$Id$"
+ *
+ * Network interface functions for the Common UNIX Printing System
+ * (CUPS) scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+#include "cupsd.h"
+
+#include <net/if.h>
+
+#ifdef HAVE_GETIFADDRS
+/*
+ * Use native getifaddrs() function...
+ */
+# include <ifaddrs.h>
+#else
+/*
+ * Use getifaddrs() emulation...
+ */
+
+# include <sys/ioctl.h>
+# ifdef HAVE_SYS_SOCKIO_H
+# include <sys/sockio.h>
+# endif
+
+# ifdef ifa_dstaddr
+# undef ifa_dstaddr
+# endif /* ifa_dstaddr */
+# ifndef ifr_netmask
+# define ifr_netmask ifr_addr
+# endif /* !ifr_netmask */
+
+struct ifaddrs /**** Interface Structure ****/
+{
+ struct ifaddrs *ifa_next; /* Next interface in list */
+ char *ifa_name; /* Name of interface */
+ unsigned int ifa_flags; /* Flags (up, point-to-point, etc.) */
+ struct sockaddr *ifa_addr, /* Network address */
+ *ifa_netmask, /* Address mask */
+ *ifa_dstaddr; /* Broadcast or destination address */
+ void *ifa_data; /* Interface statistics */
+};
+
+int getifaddrs(struct ifaddrs **addrs);
+void freeifaddrs(struct ifaddrs *addrs);
+#endif /* HAVE_GETIFADDRS */
+
+
+/*
+ * 'NetIFFind()' - Find a network interface.
+ */
+
+cups_netif_t * /* O - Network interface data */
+NetIFFind(const char *name) /* I - Name of interface */
+{
+ cups_netif_t *temp; /* Current network interface */
+
+
+ /*
+ * Update the interface list as needed...
+ */
+
+ NetIFUpdate();
+
+ /*
+ * Search for the named interface...
+ */
+
+ for (temp = NetIFList; temp != NULL; temp = temp->next)
+ if (strcasecmp(name, temp->name) == 0)
+ return (temp);
+
+ return (NULL);
+}
+
+
+/*
+ * 'NetIFFree()' - Free the current network interface list.
+ */
+
+void
+NetIFFree(void)
+{
+ cups_netif_t *next; /* Next interface in list */
+
+
+ /*
+ * Loop through the interface list and free all the records...
+ */
+
+ while (NetIFList != NULL)
+ {
+ next = NetIFList->next;
+
+ free(NetIFList);
+
+ NetIFList = next;
+ }
+}
+
+
+/*
+ * 'NetIFUpdate()' - Update the network interface list as needed...
+ */
+
+void
+NetIFUpdate(void)
+{
+ cups_netif_t *temp; /* Current interface */
+ struct ifaddrs *addrs, /* Interface address list */
+ *addr; /* Current interface address */
+ struct hostent *host; /* Host lookup info */
+
+
+ /*
+ * Update the network interface list no more often than once a
+ * minute...
+ */
+
+ if ((time(NULL) - NetIFTime) < 60)
+ return;
+
+ NetIFTime = time(NULL);
+
+ /*
+ * Free the old interfaces...
+ */
+
+ NetIFFree();
+
+ /*
+ * Grab a new list of interfaces...
+ */
+
+ if (getifaddrs(&addrs) < 0)
+ return;
+
+ for (addr = addrs; addr != NULL; addr = addr->ifa_next)
+ {
+ /*
+ * See if this interface address is IPv4...
+ */
+
+ if (addr->ifa_addr == NULL || addr->ifa_addr->sa_family != AF_INET ||
+ addr->ifa_netmask == NULL || addr->ifa_name == NULL)
+ continue;
+
+ /*
+ * OK, we have an IPv4 address, so create a new list node...
+ */
+
+ if ((temp = calloc(1, sizeof(cups_netif_t))) == NULL)
+ break;
+
+ temp->next = NetIFList;
+ NetIFList = temp;
+
+ /*
+ * Then copy all of the information...
+ */
+
+ strlcpy(temp->name, addr->ifa_name, sizeof(temp->name));
+ memcpy(&(temp->address), addr->ifa_addr, sizeof(temp->address));
+ memcpy(&(temp->mask), addr->ifa_netmask, sizeof(temp->mask));
+
+ if (addr->ifa_dstaddr)
+ memcpy(&(temp->broadcast), addr->ifa_dstaddr, sizeof(temp->broadcast));
+
+ if (!(addr->ifa_flags & IFF_POINTOPOINT) &&
+ ntohl(temp->address.sin_addr.s_addr) != 0x7f000001)
+ temp->is_local = 1;
+
+ /*
+ * Finally, try looking up the hostname for the address as needed...
+ */
+
+ if (HostNameLookups)
+ {
+#ifndef __sgi
+ host = gethostbyaddr((char *)&(temp->address.sin_addr),
+ sizeof(struct in_addr), AF_INET);
+#else
+ host = gethostbyaddr(&(temp->address.sin_addr),
+ sizeof(struct in_addr), AF_INET);
+#endif /* !__sgi */
+ }
+ else
+ host = NULL;
+
+ /*
+ * Map the default server address and localhost to the server name
+ * and localhost, respectively; for all other addresses, use the
+ * dotted notation...
+ */
+
+ if (host != NULL)
+ strlcpy(temp->hostname, host->h_name, sizeof(temp->hostname));
+ else if (ntohl(temp->address.sin_addr.s_addr) == 0x7f000001)
+ strcpy(temp->hostname, "localhost");
+ else if (temp->address.sin_addr.s_addr == ServerAddr.sin_addr.s_addr)
+ strlcpy(temp->hostname, ServerName, sizeof(temp->hostname));
+ else
+ {
+ unsigned ip = ntohl(temp->address.sin_addr.s_addr);
+
+ snprintf(temp->hostname, sizeof(temp->hostname), "%d.%d.%d.%d",
+ (ip >> 24) & 255, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255);
+ }
+ }
+
+ freeifaddrs(addrs);
+}
+
+
+#ifndef HAVE_GETIFADDRS
+/*
+ * 'getifaddrs()' - Get a list of network interfaces on the system.
+ */
+
+int /* O - 0 on success, -1 on error */
+getifaddrs(struct ifaddrs **addrs) /* O - List of interfaces */
+{
+ int sock; /* Socket */
+ char buffer[65536], /* Buffer for address info */
+ *bufptr, /* Pointer into buffer */
+ *bufend; /* End of buffer */
+ struct ifconf conf; /* Interface configurations */
+ struct sockaddr addr; /* Address data */
+ struct ifreq *ifp; /* Interface data */
+ int ifpsize; /* Size of interface data */
+ struct ifaddrs *temp; /* Pointer to current interface */
+ struct ifreq request; /* Interface request */
+
+
+ /*
+ * Start with an empty list...
+ */
+
+ if (addrs == NULL)
+ return (-1);
+
+ *addrs = NULL;
+
+ /*
+ * Create a UDP socket to get the interface data...
+ */
+
+ memset (&addr, 0, sizeof(addr));
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ return (-1);
+
+ /*
+ * Try to get the list of interfaces...
+ */
+
+ conf.ifc_len = sizeof(buffer);
+ conf.ifc_buf = buffer;
+
+ if (ioctl(sock, SIOCGIFCONF, &conf) < 0)
+ {
+ /*
+ * Couldn't get the list of interfaces...
+ */
+
+ close(sock);
+ return (-1);
+ }
+
+ /*
+ * OK, got the list of interfaces, now lets step through the
+ * buffer to pull them out...
+ */
+
+# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+# define sockaddr_len(a) ((a)->sa_len)
+# else
+# define sockaddr_len(a) (sizeof(struct sockaddr))
+# endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
+
+ for (bufptr = buffer, bufend = buffer + conf.ifc_len;
+ bufptr < bufend;
+ bufptr += ifpsize)
+ {
+ /*
+ * Get the current interface information...
+ */
+
+ ifp = (struct ifreq *)bufptr;
+ ifpsize = sizeof(ifp->ifr_name) + sockaddr_len(&(ifp->ifr_addr));
+
+ if (ifpsize < sizeof(struct ifreq))
+ ifpsize = sizeof(struct ifreq);
+
+ memset(&request, 0, sizeof(request));
+ memcpy(request.ifr_name, ifp->ifr_name, sizeof(ifp->ifr_name));
+
+ /*
+ * Check the status of the interface...
+ */
+
+ if (ioctl(sock, SIOCGIFFLAGS, &request) < 0)
+ continue;
+
+ /*
+ * Allocate memory for a single interface record...
+ */
+
+ if ((temp = calloc(1, sizeof(struct ifaddrs))) == NULL)
+ {
+ /*
+ * Unable to allocate memory...
+ */
+
+ close(sock);
+ return (-1);
+ }
+
+ /*
+ * Add this record to the front of the list and copy the name, flags,
+ * and network address...
+ */
+
+ temp->ifa_next = *addrs;
+ *addrs = temp;
+ temp->ifa_name = strdup(ifp->ifr_name);
+ temp->ifa_flags = request.ifr_flags;
+ if ((temp->ifa_addr = calloc(1, sockaddr_len(&(ifp->ifr_addr)))) != NULL)
+ memcpy(temp->ifa_addr, &(ifp->ifr_addr), sockaddr_len(&(ifp->ifr_addr)));
+
+ /*
+ * Try to get the netmask for the interface...
+ */
+
+ if (!ioctl(sock, SIOCGIFNETMASK, &request))
+ {
+ /*
+ * Got it, make a copy...
+ */
+
+ if ((temp->ifa_netmask = calloc(1, sizeof(request.ifr_netmask))) != NULL)
+ memcpy(temp->ifa_netmask, &(request.ifr_netmask),
+ sizeof(request.ifr_netmask));
+ }
+
+ /*
+ * Then get the broadcast or point-to-point (destination) address,
+ * if applicable...
+ */
+
+ if (temp->ifa_flags & IFF_BROADCAST)
+ {
+ /*
+ * Have a broadcast address, so get it!
+ */
+
+ if (!ioctl(sock, SIOCGIFBRDADDR, &request))
+ {
+ /*
+ * Got it, make a copy...
+ */
+
+ if ((temp->ifa_dstaddr = calloc(1, sizeof(request.ifr_broadaddr))) != NULL)
+ memcpy(temp->ifa_dstaddr, &(request.ifr_broadaddr),
+ sizeof(request.ifr_broadaddr));
+ }
+ }
+ else if (temp->ifa_flags & IFF_POINTOPOINT)
+ {
+ /*
+ * Point-to-point interface; grab the remote address...
+ */
+
+ if (!ioctl(sock, SIOCGIFDSTADDR, &request))
+ {
+ temp->ifa_dstaddr = malloc(sizeof(request.ifr_dstaddr));
+ memcpy(temp->ifa_dstaddr, &(request.ifr_dstaddr),
+ sizeof(request.ifr_dstaddr));
+ }
+ }
+ }
+
+ /*
+ * OK, we're done with the socket, close it and return 0...
+ */
+
+ close(sock);
+
+ return (0);
+}
+
+
+/*
+ * 'freeifaddrs()' - Free an interface list...
+ */
+
+void
+freeifaddrs(struct ifaddrs *addrs) /* I - Interface list to free */
+{
+ struct ifaddrs *next; /* Next interface in list */
+
+
+ while (addrs != NULL)
+ {
+ /*
+ * Make a copy of the next interface pointer...
+ */
+
+ next = addrs->ifa_next;
+
+ /*
+ * Free data values as needed...
+ */
+
+ if (addrs->ifa_name)
+ {
+ free(addrs->ifa_name);
+ addrs->ifa_name = NULL;
+ }
+
+ if (addrs->ifa_addr)
+ {
+ free(addrs->ifa_addr);
+ addrs->ifa_addr = NULL;
+ }
+
+ if (addrs->ifa_netmask)
+ {
+ free(addrs->ifa_netmask);
+ addrs->ifa_netmask = NULL;
+ }
+
+ if (addrs->ifa_dstaddr)
+ {
+ free(addrs->ifa_dstaddr);
+ addrs->ifa_dstaddr = NULL;
+ }
+
+ /*
+ * Free this node and continue to the next...
+ */
+
+ free(addrs);
+
+ addrs = next;
+ }
+}
+
+#endif /* !HAVE_GETIFADDRS */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/network.h b/scheduler/network.h
new file mode 100644
index 000000000..a9406edcf
--- /dev/null
+++ b/scheduler/network.h
@@ -0,0 +1,63 @@
+/*
+ * "$Id$"
+ *
+ * Network interface definitions for the Common UNIX Printing System
+ * (CUPS) scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Structures...
+ */
+
+typedef struct cups_netif_str /**** Network interface data ****/
+{
+ struct cups_netif_str *next; /* Next interface in list */
+ char name[32], /* Network interface name */
+ hostname[HTTP_MAX_HOST];
+ /* Hostname associated with interface */
+ int is_local; /* Local (not point-to-point) interface? */
+ struct sockaddr_in address, /* Network address */
+ mask, /* Network mask */
+ broadcast; /* Broadcast address */
+} cups_netif_t;
+
+
+/*
+ * Globals...
+ */
+
+VAR time_t NetIFTime VALUE(0);
+ /* Network interface list time */
+VAR cups_netif_t *NetIFList VALUE(NULL);
+ /* List of network interfaces */
+
+/*
+ * Prototypes...
+ */
+
+extern cups_netif_t *NetIFFind(const char *name);
+extern void NetIFFree(void);
+extern void NetIFUpdate(void);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/ppds.c b/scheduler/ppds.c
new file mode 100644
index 000000000..0a79b70e4
--- /dev/null
+++ b/scheduler/ppds.c
@@ -0,0 +1,896 @@
+/*
+ * "$Id$"
+ *
+ * PPD scanning routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * LoadPPDs() - Load PPD files from the specified directory...
+ * buf_read() - Read a buffer of data into memory...
+ * check_ppds() - Check to see if we need to regenerate the PPD file
+ * list...
+ * compare_names() - Compare PPD filenames for sorting.
+ * compare_ppds() - Compare PPD file make and model names for sorting.
+ * load_ppds() - Load PPD files recursively.
+ * ppd_gets() - Read a line from a PPD file.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+#include <ctype.h>
+
+#ifdef HAVE_LIBZ
+# include <zlib.h>
+#else
+# define gzFile FILE *
+# define gzclose fclose
+# define gzread(f,b,l) fread((b), 1, (l), (f))
+# define gzopen fopen
+#endif /* HAVE_LIBZ */
+
+
+/*
+ * PPD information structures...
+ */
+
+typedef struct
+{
+ char ppd_make[128], /* Manufacturer */
+ ppd_make_and_model[248]; /* Make and model */
+ int ppd_size, /* Size in bytes */
+ ppd_mtime; /* Modification time */
+ char ppd_name[256], /* PPD filename */
+ ppd_natural_language[16]; /* Natural language */
+} ppd_rec_t;
+
+typedef struct
+{
+ int found; /* 1 if PPD is found */
+ ppd_rec_t record; /* ppds.dat record */
+} ppd_info_t;
+
+
+/*
+ * Buffered file structure...
+ */
+
+typedef struct
+{
+ gzFile fp; /* Pointer to file */
+ char *ptr, /* Pointer in buffer */
+ *end, /* End of buffer */
+ buf[1024]; /* Buffer */
+} buf_t;
+
+
+/*
+ * Local globals...
+ */
+
+static int num_ppds, /* Number of PPD files */
+ alloc_ppds; /* Number of allocated entries */
+static ppd_info_t *ppds; /* PPD file info */
+static int changed_ppd; /* Did we change the PPD database? */
+
+
+/*
+ * Local functions...
+ */
+
+static int buf_read(buf_t *fp);
+static int compare_names(const ppd_info_t *p0, const ppd_info_t *p1);
+static int compare_ppds(const ppd_info_t *p0, const ppd_info_t *p1);
+static void load_ppds(const char *d, const char *p);
+static char *ppd_gets(buf_t *fp, char *buf, int buflen);
+
+
+/*
+ * 'LoadPPDs()' - Load PPD files from the specified directory...
+ */
+
+void
+LoadPPDs(const char *d) /* I - Directory to scan... */
+{
+ int i; /* Looping var */
+ ppd_info_t *ppd; /* Current PPD file */
+ FILE *fp; /* ppds.dat file */
+ struct stat fileinfo; /* ppds.dat information */
+ char filename[1024]; /* ppds.dat filename */
+
+
+ /*
+ * See if we a PPD database file...
+ */
+
+ num_ppds = 0;
+ alloc_ppds = 0;
+ ppds = (ppd_info_t *)0;
+ changed_ppd = 0;
+
+ snprintf(filename, sizeof(filename), "%s/ppds.dat", ServerRoot);
+ if (!stat(filename, &fileinfo) &&
+ (num_ppds = fileinfo.st_size / sizeof(ppd_rec_t)) > 0)
+ {
+ /*
+ * We have a ppds.dat file, so read it!
+ */
+
+ alloc_ppds = num_ppds;
+
+ if ((ppds = malloc(sizeof(ppd_info_t) * num_ppds)) == NULL)
+ {
+ LogMessage(L_ERROR, "LoadPPDs: Unable to allocate memory for %d PPD files!",
+ num_ppds);
+ num_ppds = 0;
+ alloc_ppds = 0;
+ }
+ else if ((fp = fopen(filename, "rb")) != NULL)
+ {
+ for (i = num_ppds, ppd = ppds; i > 0; i --, ppd ++)
+ {
+ fread(&(ppd->record), 1, sizeof(ppd_rec_t), fp);
+ ppd->found = 0;
+ }
+
+ fclose(fp);
+
+ LogMessage(L_INFO, "LoadPPDs: Read \"%s\", %d PPDs...", filename,
+ num_ppds);
+
+ /*
+ * Sort the PPDs by name...
+ */
+
+ if (num_ppds > 1)
+ qsort(ppds, num_ppds, sizeof(ppd_info_t),
+ (int (*)(const void *, const void *))compare_names);
+ }
+ else
+ {
+ LogMessage(L_ERROR, "LoadPPDs: Unable to read \"%s\" - %s", filename,
+ strerror(errno));
+ num_ppds = 0;
+ }
+ }
+
+ /*
+ * Load all PPDs in the specified directory and below...
+ */
+
+ load_ppds(d, "");
+
+ /*
+ * Cull PPD files that are no longer present...
+ */
+
+ for (i = num_ppds, ppd = ppds; i > 0; i --, ppd ++)
+ if (!ppd->found)
+ {
+ /*
+ * Remove this PPD file from the list...
+ */
+
+ if (i > 1)
+ memcpy(ppd, ppd + 1, (i - 1) * sizeof(ppd_info_t));
+
+ num_ppds --;
+ ppd --;
+ }
+
+ /*
+ * Sort the PPDs by make and model...
+ */
+
+ if (num_ppds > 1)
+ qsort(ppds, num_ppds, sizeof(ppd_info_t),
+ (int (*)(const void *, const void *))compare_ppds);
+
+ /*
+ * Write the new ppds.dat file...
+ */
+
+ if (changed_ppd)
+ {
+ if ((fp = fopen(filename, "wb")) != NULL)
+ {
+ for (i = num_ppds, ppd = ppds; i > 0; i --, ppd ++)
+ fwrite(&(ppd->record), 1, sizeof(ppd_rec_t), fp);
+
+ fclose(fp);
+
+ LogMessage(L_INFO, "LoadPPDs: Wrote \"%s\", %d PPDs...", filename,
+ num_ppds);
+ }
+ else
+ LogMessage(L_ERROR, "LoadPPDs: Unable to write \"%s\" - %s", filename,
+ strerror(errno));
+ }
+ else
+ LogMessage(L_INFO, "LoadPPDs: No new or changed PPDs...");
+
+ /*
+ * Create the list of PPDs...
+ */
+
+ PPDs = ippNew();
+
+ /*
+ * First the raw driver...
+ */
+
+ ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "ppd-name", NULL, "raw");
+ ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "ppd-make", NULL, "Raw");
+ ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "ppd-make-and-model", NULL, "Raw Queue");
+ ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
+ "ppd-natural-language", NULL, "en");
+
+ /*
+ * Then the PPD files...
+ */
+
+ for (i = num_ppds, ppd = ppds; i > 0; i --, ppd ++)
+ {
+ ippAddSeparator(PPDs);
+
+ ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "ppd-name", NULL, ppd->record.ppd_name);
+ ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "ppd-make", NULL, ppd->record.ppd_make);
+ ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "ppd-make-and-model", NULL, ppd->record.ppd_make_and_model);
+ ippAddString(PPDs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
+ "ppd-natural-language", NULL, ppd->record.ppd_natural_language);
+ }
+
+ /*
+ * Free the memory used...
+ */
+
+ if (alloc_ppds)
+ {
+ free(ppds);
+ alloc_ppds = 0;
+ }
+}
+
+
+/*
+ * 'buf_read()' - Read a buffer of data into memory...
+ */
+
+static int /* O - Number of bytes read */
+buf_read(buf_t *fp) /* I - File to read from */
+{
+ int count; /* Number of bytes read */
+
+
+ if ((count = gzread(fp->fp, fp->buf, sizeof(fp->buf))) > 0)
+ {
+ fp->ptr = fp->buf;
+ fp->end = fp->buf + count;
+ }
+ else
+ {
+ fp->ptr = NULL;
+ fp->end = NULL;
+ }
+
+ return (count);
+}
+
+
+/*
+ * 'compare_names()' - Compare PPD filenames for sorting.
+ */
+
+static int /* O - Result of comparison */
+compare_names(const ppd_info_t *p0, /* I - First PPD file */
+ const ppd_info_t *p1) /* I - Second PPD file */
+{
+ return (strcasecmp(p0->record.ppd_name, p1->record.ppd_name));
+}
+
+
+/*
+ * 'compare_ppds()' - Compare PPD file make and model names for sorting.
+ */
+
+static int /* O - Result of comparison */
+compare_ppds(const ppd_info_t *p0, /* I - First PPD file */
+ const ppd_info_t *p1) /* I - Second PPD file */
+{
+ const char *s, /* First name */
+ *t; /* Second name */
+ int diff, /* Difference between digits */
+ digits; /* Number of digits */
+
+
+ /*
+ * First compare manufacturers...
+ */
+
+ if ((diff = strcasecmp(p0->record.ppd_make, p1->record.ppd_make)) != 0)
+ return (diff);
+
+ /*
+ * Then compare names...
+ */
+
+ s = p0->record.ppd_make_and_model;
+ t = p1->record.ppd_make_and_model;
+
+ /*
+ * Loop through both nicknames, returning only when a difference is
+ * seen. Also, compare whole numbers rather than just characters, too!
+ */
+
+ while (*s && *t)
+ {
+ if (isdigit(*s) && isdigit(*t))
+ {
+ /*
+ * Got a number; start by skipping leading 0's...
+ */
+
+ while (*s == '0')
+ s ++;
+ while (*t == '0')
+ t ++;
+
+ /*
+ * Skip equal digits...
+ */
+
+ while (isdigit(*s) && *s == *t)
+ {
+ s ++;
+ t ++;
+ }
+
+ /*
+ * Bounce out if *s and *t aren't both digits...
+ */
+
+ if (isdigit(*s) && !isdigit(*t))
+ return (1);
+ else if (!isdigit(*s) && isdigit(*t))
+ return (-1);
+ else if (!isdigit(*s) || !isdigit(*t))
+ continue;
+
+ if (*s < *t)
+ diff = -1;
+ else
+ diff = 1;
+
+ /*
+ * Figure out how many more digits there are...
+ */
+
+ digits = 0;
+ s ++;
+ t ++;
+
+ while (isdigit(*s))
+ {
+ digits ++;
+ s ++;
+ }
+
+ while (isdigit(*t))
+ {
+ digits --;
+ t ++;
+ }
+
+ /*
+ * Return if the number or value of the digits is different...
+ */
+
+ if (digits < 0)
+ return (-1);
+ else if (digits > 0)
+ return (1);
+ else if (diff)
+ return (diff);
+ }
+ else if (tolower(*s) < tolower(*t))
+ return (-1);
+ else if (tolower(*s) > tolower(*t))
+ return (1);
+ else
+ {
+ s ++;
+ t ++;
+ }
+ }
+
+ /*
+ * Return the results of the final comparison...
+ */
+
+ if (*s)
+ return (1);
+ else if (*t)
+ return (-1);
+ else
+ return (strcasecmp(p0->record.ppd_natural_language,
+ p1->record.ppd_natural_language));
+}
+
+
+/*
+ * 'load_ppds()' - Load PPD files recursively.
+ */
+
+static void
+load_ppds(const char *d, /* I - Actual directory */
+ const char *p) /* I - Virtual path in name */
+{
+ int i; /* Looping var */
+ buf_t fp; /* Pointer to file */
+ DIR *dir; /* Directory pointer */
+ DIRENT *dent; /* Directory entry */
+ struct stat fileinfo; /* File information */
+ char filename[1024], /* Name of PPD or directory */
+ line[256], /* Line from backend */
+ *ptr, /* Pointer into name */
+ name[128], /* Name of PPD file */
+ language[64], /* PPD language version */
+ country[64], /* Country code */
+ manufacturer[256], /* Manufacturer */
+ make_model[256], /* Make and Model */
+ model_name[256], /* ModelName */
+ nick_name[256]; /* NickName */
+ ppd_info_t *ppd, /* New PPD file */
+ key; /* Search key */
+ int new_ppd; /* Is this a new PPD? */
+ struct /* LanguageVersion translation table */
+ {
+ const char *version, /* LanguageVersion string */
+ *language; /* Language code */
+ } languages[] =
+ {
+ { "chinese", "cn" },
+ { "danish", "da" },
+ { "dutch", "nl" },
+ { "english", "en" },
+ { "finnish", "fi" },
+ { "french", "fr" },
+ { "german", "de" },
+ { "greek", "el" },
+ { "italian", "it" },
+ { "japanese", "jp" },
+ { "norwegian", "no" },
+ { "polish", "pl" },
+ { "portuguese", "pt" },
+ { "russian", "ru" },
+ { "slovak", "sk" },
+ { "swedish", "sv" },
+ { "turkish", "tr" }
+ };
+
+
+ if ((dir = opendir(d)) == NULL)
+ {
+ LogMessage(L_ERROR, "LoadPPDs: Unable to open PPD directory \"%s\": %s",
+ d, strerror(errno));
+ return;
+ }
+
+ while ((dent = readdir(dir)) != NULL)
+ {
+ /*
+ * Skip "." and ".."...
+ */
+
+ if (dent->d_name[0] == '.')
+ continue;
+
+ /*
+ * See if this is a file...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/%s", d, dent->d_name);
+
+ if (p[0])
+ snprintf(name, sizeof(name), "%s/%s", p, dent->d_name);
+ else
+ strlcpy(name, dent->d_name, sizeof(name));
+
+ if (stat(filename, &fileinfo))
+ continue;
+
+ if (S_ISDIR(fileinfo.st_mode))
+ {
+ /*
+ * Do subdirectory...
+ */
+
+ load_ppds(filename, name);
+ continue;
+ }
+
+ /*
+ * See if this file has been scanned before...
+ */
+
+ if (num_ppds > 0)
+ {
+ strcpy(key.record.ppd_name, name);
+
+ ppd = bsearch(&key, ppds, num_ppds, sizeof(ppd_info_t),
+ (int (*)(const void *, const void *))compare_names);
+
+ if (ppd &&
+ ppd->record.ppd_size == fileinfo.st_size &&
+ ppd->record.ppd_mtime == fileinfo.st_mtime)
+ {
+ ppd->found = 1;
+ continue;
+ }
+ }
+ else
+ ppd = NULL;
+
+ /*
+ * No, file is new/changed, so re-scan it...
+ */
+
+ if ((fp.fp = gzopen(filename, "rb")) == NULL)
+ continue;
+
+ fp.ptr = fp.end = NULL;
+
+ /*
+ * Now see if this is a PPD file...
+ */
+
+ line[0] = '\0';
+ ppd_gets(&fp, line, sizeof(line));
+
+ if (strncmp(line, "*PPD-Adobe:", 11) != 0)
+ {
+ /*
+ * Nope, close the file and continue...
+ */
+
+ gzclose(fp.fp);
+
+ continue;
+ }
+
+ /*
+ * Now read until we get the NickName field...
+ */
+
+ model_name[0] = '\0';
+ nick_name[0] = '\0';
+ manufacturer[0] = '\0';
+ strcpy(language, "en");
+
+ while (ppd_gets(&fp, line, sizeof(line)) != NULL)
+ {
+ if (strncmp(line, "*Manufacturer:", 14) == 0)
+ sscanf(line, "%*[^\"]\"%255[^\"]", manufacturer);
+ else if (strncmp(line, "*ModelName:", 11) == 0)
+ sscanf(line, "%*[^\"]\"%127[^\"]", model_name);
+ else if (strncmp(line, "*LanguageVersion:", 17) == 0)
+ sscanf(line, "%*[^:]:%63s", language);
+ else if (strncmp(line, "*NickName:", 10) == 0)
+ sscanf(line, "%*[^\"]\"%255[^\"]", nick_name);
+ else if (strncmp(line, "*OpenUI", 7) == 0)
+ {
+ /*
+ * Stop early if we have a NickName or ModelName attributes
+ * before the first OpenUI...
+ */
+
+ if (model_name[0] || nick_name[0])
+ break;
+ }
+
+ /*
+ * Stop early if we have both the Manufacturer and NickName
+ * attributes...
+ */
+
+ if (manufacturer[0] && nick_name[0])
+ break;
+ }
+
+ /*
+ * Close the file...
+ */
+
+ gzclose(fp.fp);
+
+ /*
+ * See if we got all of the required info...
+ */
+
+ if (nick_name[0])
+ strcpy(make_model, nick_name);
+ else
+ strcpy(make_model, model_name);
+
+ while (isspace(make_model[0]))
+ strcpy(make_model, make_model + 1);
+
+ if (!make_model[0])
+ continue; /* Nope... */
+
+ /*
+ * See if we got a manufacturer...
+ */
+
+ while (isspace(manufacturer[0]))
+ strcpy(manufacturer, manufacturer + 1);
+
+ if (!manufacturer[0] || strcmp(manufacturer, "ESP") == 0)
+ {
+ /*
+ * Nope, copy the first part of the make and model then...
+ */
+
+ strlcpy(manufacturer, make_model, sizeof(manufacturer));
+
+ /*
+ * Truncate at the first space, dash, or slash, or make the
+ * manufacturer "Other"...
+ */
+
+ for (ptr = manufacturer; *ptr; ptr ++)
+ if (*ptr == ' ' || *ptr == '-' || *ptr == '/')
+ break;
+
+ if (*ptr && ptr > manufacturer)
+ *ptr = '\0';
+ else if (strncasecmp(manufacturer, "agfa", 4) == 0)
+ strcpy(manufacturer, "AGFA");
+ else if (strncasecmp(manufacturer, "herk", 4) == 0 ||
+ strncasecmp(manufacturer, "linotype", 8) == 0)
+ strcpy(manufacturer, "LHAG");
+ else
+ strcpy(manufacturer, "Other");
+
+ /*
+ * Hack for various vendors...
+ */
+
+ if (strcasecmp(manufacturer, "XPrint") == 0)
+ strcpy(manufacturer, "Xerox");
+ else if (strcasecmp(manufacturer, "Eastman") == 0)
+ strcpy(manufacturer, "Kodak");
+ else if (strcasecmp(manufacturer, "laserwriter") == 0)
+ strcpy(manufacturer, "Apple");
+ else if (strcasecmp(manufacturer, "colorpoint") == 0)
+ strcpy(manufacturer, "Seiko");
+ else if (strcasecmp(manufacturer, "fiery") == 0)
+ strcpy(manufacturer, "EFI");
+ else if (strcasecmp(manufacturer, "ps") == 0 ||
+ strcasecmp(manufacturer, "colorpass") == 0)
+ strcpy(manufacturer, "Canon");
+ else if (strncasecmp(manufacturer, "primera", 7) == 0)
+ strcpy(manufacturer, "Fargo");
+ else if (strcasecmp(manufacturer, "designjet") == 0)
+ strcpy(manufacturer, "HP");
+ }
+ else if (strncasecmp(manufacturer, "LHAG", 4) == 0 ||
+ strncasecmp(manufacturer, "linotype", 8) == 0)
+ strcpy(manufacturer, "LHAG");
+
+ /*
+ * Fix the language as needed...
+ */
+
+ if ((ptr = strchr(language, '-')) != NULL)
+ *ptr++ = '\0';
+ else if ((ptr = strchr(language, '_')) != NULL)
+ *ptr++ = '\0';
+
+ if (ptr)
+ {
+ /*
+ * Setup the country suffix...
+ */
+
+ country[0] = '_';
+ strcpy(country + 1, ptr);
+ }
+ else
+ {
+ /*
+ * No country suffix...
+ */
+
+ country[0] = '\0';
+ }
+
+ for (i = 0; i < (int)(sizeof(languages) / sizeof(languages[0])); i ++)
+ if (strcasecmp(languages[i].version, language) == 0)
+ break;
+
+ if (i < (int)(sizeof(languages) / sizeof(languages[0])))
+ {
+ /*
+ * Found a known language...
+ */
+
+ snprintf(language, sizeof(language), "%s%s", languages[i].language,
+ country);
+ }
+ else
+ {
+ /*
+ * Unknown language; use "xx"...
+ */
+
+ strcpy(language, "xx");
+ }
+
+ /*
+ * Add the PPD file...
+ */
+
+ new_ppd = !ppd;
+
+ if (new_ppd)
+ {
+ /*
+ * Allocate memory for the new PPD file...
+ */
+
+ LogMessage(L_DEBUG, "LoadPPDs: Adding ppd \"%s\"...", name);
+
+ if (num_ppds >= alloc_ppds)
+ {
+ /*
+ * Allocate (more) memory for the PPD files...
+ */
+
+ if (alloc_ppds == 0)
+ ppd = malloc(sizeof(ppd_info_t) * 32);
+ else
+ ppd = realloc(ppds, sizeof(ppd_info_t) * (alloc_ppds + 32));
+
+ if (ppd == NULL)
+ {
+ LogMessage(L_ERROR, "load_ppds: Ran out of memory for %d PPD files!",
+ alloc_ppds + 32);
+ closedir(dir);
+ return;
+ }
+
+ ppds = ppd;
+ alloc_ppds += 32;
+ }
+
+ ppd = ppds + num_ppds;
+ num_ppds ++;
+ }
+ else
+ LogMessage(L_DEBUG, "LoadPPDs: Updating ppd \"%s\"...", name);
+
+ /*
+ * Zero the PPD record and copy the info over...
+ */
+
+ memset(ppd, 0, sizeof(ppd_info_t));
+
+ ppd->found = 1;
+ ppd->record.ppd_mtime = fileinfo.st_mtime;
+ ppd->record.ppd_size = fileinfo.st_size;
+
+ strlcpy(ppd->record.ppd_name, name,
+ sizeof(ppd->record.ppd_name));
+ strlcpy(ppd->record.ppd_make, manufacturer,
+ sizeof(ppd->record.ppd_make));
+ strlcpy(ppd->record.ppd_make_and_model, make_model,
+ sizeof(ppd->record.ppd_make_and_model));
+ strlcpy(ppd->record.ppd_natural_language, language,
+ sizeof(ppd->record.ppd_natural_language));
+
+ changed_ppd = 1;
+
+ /*
+ * Re-sort the PPD array...
+ */
+
+ if (num_ppds > 1 && new_ppd)
+ qsort(ppds, num_ppds, sizeof(ppd_info_t),
+ (int (*)(const void *, const void *))compare_names);
+ }
+
+ closedir(dir);
+}
+
+
+/*
+ * 'ppd_gets()' - Read a line from a PPD file.
+ */
+
+static char * /* O - Line from file or NULL on EOF */
+ppd_gets(buf_t *fp, /* I - File to read from */
+ char *buf, /* I - Line buffer */
+ int buflen) /* I - Length of buffer */
+{
+ int ch; /* Character from file */
+ char *ptr, /* Current position in line buffer */
+ *end; /* End of line buffer */
+
+ /*
+ * Range check everything...
+ */
+
+ if (fp == NULL || buf == NULL || buflen < 2)
+ return (NULL);
+
+ /*
+ * Now loop until we have a valid line...
+ */
+
+ ptr = buf;
+ end = buf + buflen - 1;
+
+ for (;;)
+ {
+ if (fp->ptr >= fp->end)
+ if (buf_read(fp) <= 0)
+ break;
+
+ ch = *(fp->ptr)++;
+
+ if (ch == '\r' || ch == '\n')
+ {
+ /*
+ * Line feed or carriage return...
+ */
+
+ if (ptr == buf) /* Skip blank lines */
+ continue;
+
+ break;
+ }
+ else if (ptr < end)
+ *ptr++ = ch;
+ }
+
+ if (ptr > buf)
+ {
+ *ptr = '\0';
+
+ return (buf);
+ }
+ else
+ return (NULL);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/printers.c b/scheduler/printers.c
new file mode 100644
index 000000000..4c0f8b7ce
--- /dev/null
+++ b/scheduler/printers.c
@@ -0,0 +1,2081 @@
+/*
+ * "$Id$"
+ *
+ * Printer routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * AddPrinter() - Add a printer to the system.
+ * AddPrinterFilter() - Add a MIME filter for a printer.
+ * AddPrinterUser() - Add a user to the ACL.
+ * DeleteAllPrinters() - Delete all printers from the system.
+ * DeletePrinter() - Delete a printer from the system.
+ * DeletePrinterFilters() - Delete all MIME filters for a printer.
+ * FindPrinter() - Find a printer in the list.
+ * FreePrinterUsers() - Free allow/deny users.
+ * LoadAllPrinters() - Load printers from the printers.conf file.
+ * SaveAllPrinters() - Save all printer definitions to the printers.conf
+ * SetPrinterAttrs() - Set printer attributes based upon the PPD file.
+ * SetPrinterState() - Update the current state of a printer.
+ * SortPrinters() - Sort the printer list when a printer name is
+ * changed.
+ * StopPrinter() - Stop a printer from printing any jobs...
+ * ValidateDest() - Validate a printer/class destination.
+ * WritePrintcap() - Write a pseudo-printcap file for older
+ * applications that need it...
+ * write_irix_config() - Update the config files used by the IRIX
+ * desktop tools.
+ * write_irix_state() - Update the status files used by IRIX printing
+ * desktop tools.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+
+
+/*
+ * Local functions...
+ */
+
+#ifdef __sgi
+static void write_irix_config(printer_t *p);
+static void write_irix_state(printer_t *p);
+#endif /* __sgi */
+
+
+/*
+ * 'AddPrinter()' - Add a printer to the system.
+ */
+
+printer_t * /* O - New printer */
+AddPrinter(const char *name) /* I - Name of printer */
+{
+ printer_t *p, /* New printer */
+ *current, /* Current printer in list */
+ *prev; /* Previous printer in list */
+
+
+ DEBUG_printf(("AddPrinter(\"%s\")\n", name));
+
+ /*
+ * Range check input...
+ */
+
+ if (name == NULL)
+ return (NULL);
+
+ /*
+ * Create a new printer entity...
+ */
+
+ if ((p = calloc(1, sizeof(printer_t))) == NULL)
+ return (NULL);
+
+ strlcpy(p->name, name, sizeof(p->name));
+ strlcpy(p->info, name, sizeof(p->info));
+ strlcpy(p->hostname, ServerName, sizeof(p->hostname));
+ snprintf(p->uri, sizeof(p->uri), "ipp://%s:%d/printers/%s", ServerName,
+ ntohs(Listeners[0].address.sin_port), name);
+
+ p->state = IPP_PRINTER_STOPPED;
+ p->accepting = 0;
+ p->filetype = mimeAddType(MimeDatabase, "printer", name);
+
+ strcpy(p->job_sheets[0], "none");
+ strcpy(p->job_sheets[1], "none");
+
+ /*
+ * Setup required filters and IPP attributes...
+ */
+
+ SetPrinterAttrs(p);
+
+ /*
+ * Insert the printer in the printer list alphabetically...
+ */
+
+ for (prev = NULL, current = Printers;
+ current != NULL;
+ prev = current, current = current->next)
+ if (strcasecmp(p->name, current->name) < 0)
+ break;
+
+ /*
+ * Insert this printer before the current one...
+ */
+
+ if (prev == NULL)
+ Printers = p;
+ else
+ prev->next = p;
+
+ p->next = current;
+
+ /*
+ * Write a new /etc/printcap or /var/spool/lp/pstatus file.
+ */
+
+ WritePrintcap();
+
+ return (p);
+}
+
+
+/*
+ * 'AddPrinterFilter()' - Add a MIME filter for a printer.
+ */
+
+void
+AddPrinterFilter(printer_t *p, /* I - Printer to add to */
+ const char *filter) /* I - Filter to add */
+{
+ int i; /* Looping var */
+ char super[MIME_MAX_SUPER], /* Super-type for filter */
+ type[MIME_MAX_TYPE], /* Type for filter */
+ program[1024]; /* Program/filter name */
+ int cost; /* Cost of filter */
+ mime_type_t **temptype; /* MIME type looping var */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (p == NULL || filter == NULL)
+ return;
+
+ /*
+ * Parse the filter string; it should be in the following format:
+ *
+ * super/type cost program
+ */
+
+ if (sscanf(filter, "%15[^/]/%31s%d%1023s", super, type, &cost, program) != 4)
+ {
+ LogMessage(L_ERROR, "AddPrinterFilter: Invalid filter string \"%s\"!",
+ filter);
+ return;
+ }
+
+ /*
+ * Add the filter to the MIME database, supporting wildcards as needed...
+ */
+
+ for (temptype = MimeDatabase->types, i = MimeDatabase->num_types;
+ i > 0;
+ i --, temptype ++)
+ if (((super[0] == '*' && strcmp((*temptype)->super, "printer") != 0) ||
+ strcmp((*temptype)->super, super) == 0) &&
+ (type[0] == '*' || strcmp((*temptype)->type, type) == 0))
+ {
+ LogMessage(L_DEBUG2, "Adding filter %s/%s %s/%s %d %s",
+ (*temptype)->super, (*temptype)->type,
+ p->filetype->super, p->filetype->type,
+ cost, program);
+ mimeAddFilter(MimeDatabase, *temptype, p->filetype, cost, program);
+ }
+}
+
+
+/*
+ * 'AddPrinterUser()' - Add a user to the ACL.
+ */
+
+void
+AddPrinterUser(printer_t *p, /* I - Printer */
+ const char *username) /* I - User */
+{
+ const char **temp; /* Temporary array pointer */
+
+
+ if (!p || !username)
+ return;
+
+ if (p->num_users == 0)
+ temp = malloc(sizeof(char **));
+ else
+ temp = realloc(p->users, sizeof(char **) * (p->num_users + 1));
+
+ if (!temp)
+ return;
+
+ p->users = temp;
+ temp += p->num_users;
+
+ if ((*temp = strdup(username)) != NULL)
+ p->num_users ++;
+}
+
+
+/*
+ * 'DeleteAllPrinters()' - Delete all printers from the system.
+ */
+
+void
+DeleteAllPrinters(void)
+{
+ printer_t *p, /* Pointer to current printer/class */
+ *next; /* Pointer to next printer in list */
+
+
+ for (p = Printers; p != NULL; p = next)
+ {
+ next = p->next;
+
+ if (!(p->type & CUPS_PRINTER_CLASS))
+ DeletePrinter(p);
+ }
+}
+
+
+/*
+ * 'DeletePrinter()' - Delete a printer from the system.
+ */
+
+void
+DeletePrinter(printer_t *p) /* I - Printer to delete */
+{
+ printer_t *current, /* Current printer in list */
+ *prev; /* Previous printer in list */
+#ifdef __sgi
+ char filename[1024]; /* Interface script filename */
+#endif /* __sgi */
+
+
+ DEBUG_printf(("DeletePrinter(%08x): p->name = \"%s\"...\n", p, p->name));
+
+ /*
+ * Range check input...
+ */
+
+ if (p == NULL)
+ return;
+
+ /*
+ * Remove the printer from the list...
+ */
+
+ for (prev = NULL, current = Printers;
+ current != NULL;
+ prev = current, current = current->next)
+ if (p == current)
+ break;
+
+ if (current == NULL)
+ {
+ LogMessage(L_ERROR, "Tried to delete a non-existent printer %s!\n",
+ p->name);
+ return;
+ }
+
+ if (prev == NULL)
+ Printers = p->next;
+ else
+ prev->next = p->next;
+
+ /*
+ * Stop printing on this printer...
+ */
+
+ StopPrinter(p);
+
+ /*
+ * Remove the dummy interface/icon/option files under IRIX...
+ */
+
+#ifdef __sgi
+ snprintf(filename, sizeof(filename), "/var/spool/lp/interface/%s", p->name);
+ unlink(filename);
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/gui_interface/ELF/%s.gui",
+ p->name);
+ unlink(filename);
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/activeicons/%s", p->name);
+ unlink(filename);
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.config", p->name);
+ unlink(filename);
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.status", p->name);
+ unlink(filename);
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/member/%s", p->name);
+ unlink(filename);
+#endif /* __sgi */
+
+ /*
+ * If p is the default printer, assign the next one...
+ */
+
+ if (p == DefaultPrinter)
+ {
+ DefaultPrinter = Printers;
+
+ WritePrintcap();
+ }
+
+ /*
+ * Remove this printer from any classes...
+ */
+
+ if (!(p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)))
+ DeletePrinterFromClasses(p);
+
+ /*
+ * Free all memory used by the printer...
+ */
+
+ if (p->printers != NULL)
+ free(p->printers);
+
+ ippDelete(p->attrs);
+
+ DeletePrinterFilters(p);
+
+ FreePrinterUsers(p);
+ FreeQuotas(p);
+
+ free(p);
+
+ /*
+ * Write a new /etc/printcap file...
+ */
+
+ WritePrintcap();
+}
+
+
+/*
+ * 'DeletePrinterFilters()' - Delete all MIME filters for a printer.
+ */
+
+void
+DeletePrinterFilters(printer_t *p) /* I - Printer to remove from */
+{
+ int i; /* Looping var */
+ mime_filter_t *filter; /* MIME filter looping var */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (p == NULL)
+ return;
+
+ /*
+ * Remove all filters from the MIME database that have a destination
+ * type == printer...
+ */
+
+ for (filter = MimeDatabase->filters, i = MimeDatabase->num_filters;
+ i > 0;
+ i --, filter ++)
+ if (filter->dst == p->filetype)
+ {
+ /*
+ * Delete the current filter...
+ */
+
+ MimeDatabase->num_filters --;
+
+ if (i > 1)
+ memcpy(filter, filter + 1, sizeof(mime_filter_t) * (i - 1));
+
+ filter --;
+ }
+}
+
+
+/*
+ * 'FindPrinter()' - Find a printer in the list.
+ */
+
+printer_t * /* O - Printer in list */
+FindPrinter(const char *name) /* I - Name of printer to find */
+{
+ printer_t *p; /* Current printer */
+
+
+ for (p = Printers; p != NULL; p = p->next)
+ switch (strcasecmp(name, p->name))
+ {
+ case 0 : /* name == p->name */
+ if (!(p->type & CUPS_PRINTER_CLASS))
+ return (p);
+ case 1 : /* name > p->name */
+ break;
+ case -1 : /* name < p->name */
+ return (NULL);
+ }
+
+ return (NULL);
+}
+
+
+/*
+ * 'FreePrinterUsers()' - Free allow/deny users.
+ */
+
+void
+FreePrinterUsers(printer_t *p) /* I - Printer */
+{
+ int i; /* Looping var */
+
+
+ if (!p || !p->num_users)
+ return;
+
+ for (i = 0; i < p->num_users; i ++)
+ free((void *)p->users[i]);
+
+ free(p->users);
+
+ p->num_users = 0;
+ p->users = NULL;
+}
+
+
+/*
+ * 'LoadAllPrinters()' - Load printers from the printers.conf file.
+ */
+
+void
+LoadAllPrinters(void)
+{
+ FILE *fp; /* printers.conf file */
+ int linenum; /* Current line number */
+ int len; /* Length of line */
+ char line[1024], /* Line from file */
+ name[256], /* Parameter name */
+ *nameptr, /* Pointer into name */
+ *value, /* Pointer to value */
+ *valueptr; /* Pointer into value */
+ printer_t *p; /* Current printer */
+
+
+ /*
+ * Open the printers.conf file...
+ */
+
+ snprintf(line, sizeof(line), "%s/printers.conf", ServerRoot);
+ if ((fp = fopen(line, "r")) == NULL)
+ return;
+
+ /*
+ * Read printer configurations until we hit EOF...
+ */
+
+ linenum = 0;
+ p = NULL;
+
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ linenum ++;
+
+ /*
+ * Skip comment lines...
+ */
+
+ if (line[0] == '#')
+ continue;
+
+ /*
+ * Strip trailing whitespace, if any...
+ */
+
+ len = strlen(line);
+
+ while (len > 0 && isspace(line[len - 1]))
+ {
+ len --;
+ line[len] = '\0';
+ }
+
+ /*
+ * Extract the name from the beginning of the line...
+ */
+
+ for (value = line; isspace(*value); value ++);
+
+ for (nameptr = name; *value != '\0' && !isspace(*value) &&
+ nameptr < (name + sizeof(name) - 1);)
+ *nameptr++ = *value++;
+ *nameptr = '\0';
+
+ while (isspace(*value))
+ value ++;
+
+ if (name[0] == '\0')
+ continue;
+
+ /*
+ * Decode the directive...
+ */
+
+ if (strcmp(name, "<Printer") == 0 ||
+ strcmp(name, "<DefaultPrinter") == 0)
+ {
+ /*
+ * <Printer name> or <DefaultPrinter name>
+ */
+
+ if (line[len - 1] == '>' && p == NULL)
+ {
+ /*
+ * Add the printer and a base file type...
+ */
+
+ line[len - 1] = '\0';
+
+ p = AddPrinter(value);
+ p->accepting = 1;
+ p->state = IPP_PRINTER_IDLE;
+
+ /*
+ * Set the default printer as needed...
+ */
+
+ if (strcmp(name, "<DefaultPrinter") == 0)
+ DefaultPrinter = p;
+ }
+ else
+ {
+ LogMessage(L_ERROR, "Syntax error on line %d of printers.conf.",
+ linenum);
+ return;
+ }
+ }
+ else if (strcmp(name, "</Printer>") == 0)
+ {
+ if (p != NULL)
+ {
+ SetPrinterAttrs(p);
+ p = NULL;
+ }
+ else
+ {
+ LogMessage(L_ERROR, "Syntax error on line %d of printers.conf.",
+ linenum);
+ return;
+ }
+ }
+ else if (p == NULL)
+ {
+ LogMessage(L_ERROR, "Syntax error on line %d of printers.conf.",
+ linenum);
+ return;
+ }
+ else if (strcmp(name, "Info") == 0)
+ strlcpy(p->info, value, sizeof(p->info));
+ else if (strcmp(name, "Location") == 0)
+ strlcpy(p->location, value, sizeof(p->location));
+ else if (strcmp(name, "DeviceURI") == 0)
+ strlcpy(p->device_uri, value, sizeof(p->device_uri));
+ else if (strcmp(name, "State") == 0)
+ {
+ /*
+ * Set the initial queue state...
+ */
+
+ if (strcasecmp(value, "idle") == 0)
+ p->state = IPP_PRINTER_IDLE;
+ else if (strcasecmp(value, "stopped") == 0)
+ p->state = IPP_PRINTER_STOPPED;
+ }
+ else if (strcmp(name, "StateMessage") == 0)
+ {
+ /*
+ * Set the initial queue state message...
+ */
+
+ while (isspace(*value))
+ value ++;
+
+ strlcpy(p->state_message, value, sizeof(p->state_message));
+ }
+ else if (strcmp(name, "Accepting") == 0)
+ {
+ /*
+ * Set the initial accepting state...
+ */
+
+ if (strcasecmp(value, "yes") == 0)
+ p->accepting = 1;
+ else
+ p->accepting = 0;
+ }
+ else if (strcmp(name, "JobSheets") == 0)
+ {
+ /*
+ * Set the initial job sheets...
+ */
+
+ for (valueptr = value; *valueptr && !isspace(*valueptr); valueptr ++);
+
+ if (*valueptr)
+ *valueptr++ = '\0';
+
+ strlcpy(p->job_sheets[0], value, sizeof(p->job_sheets[0]));
+
+ while (isspace(*valueptr))
+ valueptr ++;
+
+ if (*valueptr)
+ {
+ for (value = valueptr; *valueptr && !isspace(*valueptr); valueptr ++);
+
+ if (*valueptr)
+ *valueptr++ = '\0';
+
+ strlcpy(p->job_sheets[1], value, sizeof(p->job_sheets[1]));
+ }
+ }
+ else if (strcmp(name, "AllowUser") == 0)
+ {
+ p->deny_users = 0;
+ AddPrinterUser(p, value);
+ }
+ else if (strcmp(name, "DenyUser") == 0)
+ {
+ p->deny_users = 1;
+ AddPrinterUser(p, value);
+ }
+ else if (strcmp(name, "QuotaPeriod") == 0)
+ p->quota_period = atoi(value);
+ else if (strcmp(name, "PageLimit") == 0)
+ p->page_limit = atoi(value);
+ else if (strcmp(name, "KLimit") == 0)
+ p->k_limit = atoi(value);
+ else
+ {
+ /*
+ * Something else we don't understand...
+ */
+
+ LogMessage(L_ERROR, "Unknown configuration directive %s on line %d of printers.conf.",
+ name, linenum);
+ }
+ }
+
+ fclose(fp);
+}
+
+
+/*
+ * 'SaveAllPrinters()' - Save all printer definitions to the printers.conf
+ * file.
+ */
+
+void
+SaveAllPrinters(void)
+{
+ int i; /* Looping var */
+ FILE *fp; /* printers.conf file */
+ char temp[1024]; /* Temporary string */
+ char backup[1024]; /* printers.conf.O file */
+ printer_t *printer; /* Current printer class */
+ time_t curtime; /* Current time */
+ struct tm *curdate; /* Current date */
+
+
+ /*
+ * Create the printers.conf file...
+ */
+
+ snprintf(temp, sizeof(temp), "%s/printers.conf", ServerRoot);
+ snprintf(backup, sizeof(backup), "%s/printers.conf.O", ServerRoot);
+
+ if (rename(temp, backup))
+ LogMessage(L_ERROR, "Unable to backup printers.conf - %s", strerror(errno));
+
+ if ((fp = fopen(temp, "w")) == NULL)
+ {
+ LogMessage(L_ERROR, "Unable to save printers.conf - %s", strerror(errno));
+
+ if (rename(backup, temp))
+ LogMessage(L_ERROR, "Unable to restore printers.conf - %s", strerror(errno));
+ return;
+ }
+ else
+ LogMessage(L_INFO, "Saving printers.conf...");
+
+ /*
+ * Restrict access to the file...
+ */
+
+ fchown(fileno(fp), User, Group);
+ fchmod(fileno(fp), 0600);
+
+ /*
+ * Write a small header to the file...
+ */
+
+ curtime = time(NULL);
+ curdate = gmtime(&curtime);
+ strftime(temp, sizeof(temp) - 1, CUPS_STRFTIME_FORMAT, curdate);
+
+ fputs("# Printer configuration file for " CUPS_SVERSION "\n", fp);
+ fprintf(fp, "# Written by cupsd on %s\n", temp);
+
+ /*
+ * Write each local printer known to the system...
+ */
+
+ for (printer = Printers; printer != NULL; printer = printer->next)
+ {
+ /*
+ * Skip remote destinations and printer classes...
+ */
+
+ if ((printer->type & CUPS_PRINTER_REMOTE) ||
+ (printer->type & CUPS_PRINTER_CLASS) ||
+ (printer->type & CUPS_PRINTER_IMPLICIT))
+ continue;
+
+ /*
+ * Write printers as needed...
+ */
+
+ if (printer == DefaultPrinter)
+ fprintf(fp, "<DefaultPrinter %s>\n", printer->name);
+ else
+ fprintf(fp, "<Printer %s>\n", printer->name);
+
+ if (printer->info[0])
+ fprintf(fp, "Info %s\n", printer->info);
+
+ if (printer->location[0])
+ fprintf(fp, "Location %s\n", printer->location);
+
+ if (printer->device_uri[0])
+ fprintf(fp, "DeviceURI %s\n", printer->device_uri);
+
+ if (printer->state == IPP_PRINTER_STOPPED)
+ {
+ fputs("State Stopped\n", fp);
+ fprintf(fp, "StateMessage %s\n", printer->state_message);
+ }
+ else
+ fputs("State Idle\n", fp);
+
+ if (printer->accepting)
+ fputs("Accepting Yes\n", fp);
+ else
+ fputs("Accepting No\n", fp);
+
+ fprintf(fp, "JobSheets %s %s\n", printer->job_sheets[0],
+ printer->job_sheets[1]);
+
+ fprintf(fp, "QuotaPeriod %d\n", printer->quota_period);
+ fprintf(fp, "PageLimit %d\n", printer->page_limit);
+ fprintf(fp, "KLimit %d\n", printer->k_limit);
+
+ for (i = 0; i < printer->num_users; i ++)
+ fprintf(fp, "%sUser %s\n", printer->deny_users ? "Deny" : "Allow",
+ printer->users[i]);
+
+ fputs("</Printer>\n", fp);
+
+#ifdef __sgi
+ /*
+ * Make IRIX desktop & printer status happy
+ */
+
+ write_irix_state(printer);
+#endif /* __sgi */
+ }
+
+ fclose(fp);
+}
+
+
+/*
+ * 'SetPrinterAttrs()' - Set printer attributes based upon the PPD file.
+ */
+
+void
+SetPrinterAttrs(printer_t *p) /* I - Printer to setup */
+{
+ char uri[HTTP_MAX_URI]; /* URI for printer */
+ char method[HTTP_MAX_URI], /* Method portion of URI */
+ username[HTTP_MAX_URI], /* Username portion of URI */
+ host[HTTP_MAX_URI], /* Host portion of URI */
+ resource[HTTP_MAX_URI]; /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ int i; /* Looping var */
+ char filename[1024]; /* Name of PPD file */
+ int num_media; /* Number of media options */
+ location_t *auth; /* Pointer to authentication element */
+ const char *auth_supported; /* Authentication supported */
+ cups_ptype_t printer_type; /* Printer type data */
+ ppd_file_t *ppd; /* PPD file data */
+ ppd_option_t *input_slot, /* InputSlot options */
+ *media_type, /* MediaType options */
+ *page_size, /* PageSize options */
+ *output_bin; /* OutputBin options */
+ ipp_attribute_t *attr; /* Attribute data */
+ ipp_value_t *val; /* Attribute value */
+ int nups[] = /* number-up-supported values */
+ { 1, 2, 4, 6, 9, 16 };
+ ipp_orient_t orients[4] = /* orientation-requested-supported values */
+ {
+ IPP_PORTRAIT,
+ IPP_LANDSCAPE,
+ IPP_REVERSE_LANDSCAPE,
+ IPP_REVERSE_PORTRAIT
+ };
+ const char *sides[3] = /* sides-supported values */
+ {
+ "one",
+ "two-long-edge",
+ "two-short-edge"
+ };
+ const char *versions[] = /* ipp-versions-supported values */
+ {
+ "1.0",
+ "1.1"
+ };
+ ipp_op_t ops[] = /* operations-supported values */
+ {
+ IPP_PRINT_JOB,
+ IPP_VALIDATE_JOB,
+ IPP_CREATE_JOB,
+ IPP_SEND_DOCUMENT,
+ IPP_CANCEL_JOB,
+ IPP_GET_JOB_ATTRIBUTES,
+ IPP_GET_JOBS,
+ IPP_GET_PRINTER_ATTRIBUTES,
+ IPP_HOLD_JOB,
+ IPP_RELEASE_JOB,
+ IPP_PAUSE_PRINTER,
+ IPP_RESUME_PRINTER,
+ IPP_PURGE_JOBS,
+ IPP_SET_JOB_ATTRIBUTES,
+ IPP_ENABLE_PRINTER,
+ IPP_DISABLE_PRINTER,
+ CUPS_GET_DEFAULT,
+ CUPS_GET_PRINTERS,
+ CUPS_ADD_PRINTER,
+ CUPS_DELETE_PRINTER,
+ CUPS_GET_CLASSES,
+ CUPS_ADD_CLASS,
+ CUPS_DELETE_CLASS,
+ CUPS_ACCEPT_JOBS,
+ CUPS_REJECT_JOBS,
+ CUPS_GET_DEVICES,
+ CUPS_GET_PPDS,
+ IPP_RESTART_JOB
+ };
+ const char *charsets[] = /* charset-supported values */
+ {
+ "us-ascii",
+ "iso-8859-1",
+ "iso-8859-2",
+ "iso-8859-3",
+ "iso-8859-4",
+ "iso-8859-5",
+ "iso-8859-6",
+ "iso-8859-7",
+ "iso-8859-8",
+ "iso-8859-9",
+ "iso-8859-10",
+ "iso-8859-13",
+ "iso-8859-14",
+ "iso-8859-15",
+ "utf-8",
+ "windows-874",
+ "windows-1250",
+ "windows-1251",
+ "windows-1252",
+ "windows-1253",
+ "windows-1254",
+ "windows-1255",
+ "windows-1256",
+ "windows-1257",
+ "windows-1258",
+ "koi8-r",
+ "koi8-u",
+ };
+ int num_finishings;
+ ipp_finish_t finishings[5];
+ const char *multiple_document_handling[] =
+ {
+ "separate-documents-uncollated-copies",
+ "separate-documents-collated-copies"
+ };
+
+
+ DEBUG_printf(("SetPrinterAttrs: entering name = %s, type = %x\n", p->name,
+ p->type));
+
+ /*
+ * Clear out old filters and add a filter from application/vnd.cups-raw to
+ * printer/name to handle "raw" printing by users.
+ */
+
+ DeletePrinterFilters(p);
+ AddPrinterFilter(p, "application/vnd.cups-raw 0 -");
+
+ /*
+ * Figure out the authentication that is required for the printer.
+ */
+
+ auth_supported = "requesting-user-name";
+ if (!(p->type & CUPS_PRINTER_REMOTE))
+ {
+ if (p->type & CUPS_PRINTER_CLASS)
+ snprintf(resource, sizeof(resource), "/classes/%s", p->name);
+ else
+ snprintf(resource, sizeof(resource), "/printers/%s", p->name);
+
+ if ((auth = FindBest(resource, HTTP_POST)) != NULL)
+ {
+ if (auth->type == AUTH_BASIC || auth->type == AUTH_BASICDIGEST)
+ auth_supported = "basic";
+ else if (auth->type == AUTH_DIGEST)
+ auth_supported = "digest";
+ }
+ }
+
+ /*
+ * Create the required IPP attributes for a printer...
+ */
+
+ if (p->attrs)
+ ippDelete(p->attrs);
+
+ p->attrs = ippNew();
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-uri-supported",
+ NULL, p->uri);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "uri-authentication-supported", NULL, auth_supported);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "uri-security-supported", NULL, "none");
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-name", NULL,
+ p->name);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
+ NULL, p->location);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
+ NULL, p->info);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-more-info",
+ NULL, p->uri);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "pdl-override-supported", NULL, "not-attempted");
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "ipp-versions-supported", sizeof(versions) / sizeof(versions[0]),
+ NULL, versions);
+ ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "operations-supported",
+ sizeof(ops) / sizeof(ops[0]) + JobFiles - 1, (int *)ops);
+ ippAddBoolean(p->attrs, IPP_TAG_PRINTER, "multiple-document-jobs-supported", 1);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "multiple-operation-time-out", 60);
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "multiple-document-handling-supported",
+ sizeof(multiple_document_handling) /
+ sizeof(multiple_document_handling[0]), NULL,
+ multiple_document_handling);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_CHARSET, "charset-configured",
+ NULL, DefaultCharset);
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_CHARSET, "charset-supported",
+ sizeof(charsets) / sizeof(charsets[0]), NULL, charsets);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
+ "natural-language-configured", NULL, DefaultLanguage);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
+ "generated-natural-language-supported", NULL, DefaultLanguage);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
+ "document-format-default", NULL, "application/octet-stream");
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER,
+ (ipp_tag_t)(IPP_TAG_MIMETYPE | IPP_TAG_COPY),
+ "document-format-supported", NumMimeTypes, NULL, MimeTypes);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "compression-supported", NULL, "none");
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-priority-supported", 100);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-priority-default", 50);
+ ippAddRange(p->attrs, IPP_TAG_PRINTER, "copies-supported", 1, MaxCopies);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "copies-default", 1);
+ ippAddBoolean(p->attrs, IPP_TAG_PRINTER, "page-ranges-supported", 1);
+ ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "number-up-supported", sizeof(nups) / sizeof(nups[0]), nups);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "number-up-default", 1);
+ ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
+ "orientation-requested-supported", 4, (int *)orients);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
+ "orientation-requested-default", IPP_PORTRAIT);
+
+ if (p->num_users)
+ {
+ if (p->deny_users)
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "requesting-user-name-denied", p->num_users, NULL,
+ p->users);
+ else
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "requesting-user-name-allowed", p->num_users, NULL,
+ p->users);
+ }
+
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-quota-period", p->quota_period);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-k-limit", p->k_limit);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-page-limit", p->page_limit);
+
+ if (NumBanners > 0)
+ {
+ /*
+ * Setup the job-sheets-supported and job-sheets-default attributes...
+ */
+
+ if (Classification[0] && !ClassifyOverride)
+ attr = ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "job-sheets-supported", NULL, Classification);
+ else
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "job-sheets-supported", NumBanners + 1, NULL, NULL);
+
+ if (attr == NULL)
+ LogMessage(L_EMERG, "SetPrinterAttrs: Unable to allocate memory for "
+ "job-sheets-supported attribute: %s!",
+ strerror(errno));
+ else if (!Classification[0] || ClassifyOverride)
+ {
+ attr->values[0].string.text = strdup("none");
+
+ for (i = 0; i < NumBanners; i ++)
+ attr->values[i + 1].string.text = strdup(Banners[i].name);
+ }
+
+ if (!(p->type & CUPS_PRINTER_REMOTE))
+ {
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "job-sheets-default", 2, NULL, NULL);
+
+ if (attr != NULL)
+ {
+ attr->values[0].string.text = strdup(Classification[0] ?
+ Classification : p->job_sheets[0]);
+ attr->values[1].string.text = strdup(Classification[0] ?
+ Classification : p->job_sheets[1]);
+ }
+ }
+ }
+
+ printer_type = p->type;
+
+ if (p->type & CUPS_PRINTER_REMOTE)
+ {
+ /*
+ * Tell the client this is a remote printer of some type...
+ */
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-make-and-model", NULL, p->make_model);
+ }
+ else
+ {
+ /*
+ * Assign additional attributes depending on whether this is a printer
+ * or class...
+ */
+
+ p->type &= ~CUPS_PRINTER_OPTIONS;
+
+ if (p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+ {
+ /*
+ * Add class-specific attributes...
+ */
+
+ if ((p->type & CUPS_PRINTER_IMPLICIT) && p->num_printers > 0)
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-make-and-model", NULL, p->printers[0]->make_model);
+ else
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-make-and-model", NULL, "Local Printer Class");
+
+ if (p->num_printers > 0)
+ {
+ /*
+ * Add a list of member URIs and names...
+ */
+
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI,
+ "member-uris", p->num_printers, NULL, NULL);
+ p->type |= CUPS_PRINTER_OPTIONS;
+
+ for (i = 0; i < p->num_printers; i ++)
+ {
+ if (attr != NULL)
+ attr->values[i].string.text = strdup(p->printers[i]->uri);
+
+ p->type &= ~CUPS_PRINTER_OPTIONS | p->printers[i]->type;
+ }
+
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "member-names", p->num_printers, NULL, NULL);
+
+ if (attr != NULL)
+ {
+ for (i = 0; i < p->num_printers; i ++)
+ attr->values[i].string.text = strdup(p->printers[i]->name);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Add printer-specific attributes... Start by sanitizing the device
+ * URI so it doesn't have a username or password in it...
+ */
+
+ if (strstr(p->device_uri, "://") != NULL)
+ {
+ /*
+ * http://..., ipp://..., etc.
+ */
+
+ httpSeparate(p->device_uri, method, username, host, &port, resource);
+ if (port)
+ snprintf(uri, sizeof(uri), "%s://%s:%d%s", method, host, port,
+ resource);
+ else
+ snprintf(uri, sizeof(uri), "%s://%s%s", method, host, resource);
+ }
+ else
+ {
+ /*
+ * file:..., serial:..., etc.
+ */
+
+ strcpy(uri, p->device_uri);
+ }
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
+ uri);
+
+ /*
+ * Assign additional attributes from the PPD file (if any)...
+ */
+
+ p->type |= CUPS_PRINTER_BW;
+ finishings[0] = IPP_FINISHINGS_NONE;
+ num_finishings = 1;
+
+ snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot,
+ p->name);
+
+ if ((ppd = ppdOpenFile(filename)) != NULL)
+ {
+ /*
+ * Add make/model and other various attributes...
+ */
+
+ if (ppd->color_device)
+ p->type |= CUPS_PRINTER_COLOR;
+ if (ppd->variable_sizes)
+ p->type |= CUPS_PRINTER_VARIABLE;
+ if (!ppd->manual_copies)
+ p->type |= CUPS_PRINTER_COPIES;
+
+ ippAddBoolean(p->attrs, IPP_TAG_PRINTER, "color-supported",
+ ppd->color_device);
+ if (ppd->throughput)
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "pages-per-minute", ppd->throughput);
+
+ if (ppd->nickname)
+ strlcpy(p->make_model, ppd->nickname, sizeof(p->make_model));
+ else if (ppd->modelname)
+ strlcpy(p->make_model, ppd->modelname, sizeof(p->make_model));
+ else
+ strcpy(p->make_model, "Bad PPD File");
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-make-and-model", NULL, p->make_model);
+
+ /*
+ * Add media options from the PPD file...
+ */
+
+ if ((input_slot = ppdFindOption(ppd, "InputSlot")) != NULL)
+ num_media = input_slot->num_choices;
+ else
+ num_media = 0;
+
+ if ((media_type = ppdFindOption(ppd, "MediaType")) != NULL)
+ num_media += media_type->num_choices;
+
+ if ((page_size = ppdFindOption(ppd, "PageSize")) != NULL)
+ num_media += page_size->num_choices;
+
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "media-supported", num_media, NULL, NULL);
+ if (attr != NULL)
+ {
+ val = attr->values;
+
+ if (input_slot != NULL)
+ for (i = 0; i < input_slot->num_choices; i ++, val ++)
+ val->string.text = strdup(input_slot->choices[i].choice);
+
+ if (media_type != NULL)
+ for (i = 0; i < media_type->num_choices; i ++, val ++)
+ val->string.text = strdup(media_type->choices[i].choice);
+
+ if (page_size != NULL)
+ {
+ for (i = 0; i < page_size->num_choices; i ++, val ++)
+ val->string.text = strdup(page_size->choices[i].choice);
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
+ NULL, page_size->defchoice);
+ }
+ else if (input_slot != NULL)
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
+ NULL, input_slot->defchoice);
+ else if (media_type != NULL)
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
+ NULL, media_type->defchoice);
+ else
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
+ NULL, "none");
+ }
+
+ /*
+ * Output bin...
+ */
+
+ if ((output_bin = ppdFindOption(ppd, "OutputBin")) != NULL)
+ {
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "output-bin-supported", output_bin->num_choices,
+ NULL, NULL);
+
+ if (attr != NULL)
+ {
+ for (i = 0, val = attr->values;
+ i < output_bin->num_choices;
+ i ++, val ++)
+ val->string.text = strdup(output_bin->choices[i].choice);
+ }
+ }
+
+ /*
+ * Duplexing, etc...
+ */
+
+ if (ppdFindOption(ppd, "Duplex") != NULL)
+ {
+ p->type |= CUPS_PRINTER_DUPLEX;
+
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "sides-supported",
+ 3, NULL, sides);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "sides-default",
+ NULL, "one");
+ }
+
+ if (ppdFindOption(ppd, "Collate") != NULL)
+ p->type |= CUPS_PRINTER_COLLATE;
+
+ if (ppdFindOption(ppd, "StapleLocation") != NULL)
+ {
+ p->type |= CUPS_PRINTER_STAPLE;
+ finishings[num_finishings++] = IPP_FINISHINGS_STAPLE;
+ }
+
+ if (ppdFindOption(ppd, "BindEdge") != NULL)
+ {
+ p->type |= CUPS_PRINTER_BIND;
+ finishings[num_finishings++] = IPP_FINISHINGS_BIND;
+ }
+
+ for (i = 0; i < ppd->num_sizes; i ++)
+ if (ppd->sizes[i].length > 1728)
+ p->type |= CUPS_PRINTER_LARGE;
+ else if (ppd->sizes[i].length > 1008)
+ p->type |= CUPS_PRINTER_MEDIUM;
+ else
+ p->type |= CUPS_PRINTER_SMALL;
+
+ /*
+ * Add any filters in the PPD file...
+ */
+
+ DEBUG_printf(("ppd->num_filters = %d\n", ppd->num_filters));
+ for (i = 0; i < ppd->num_filters; i ++)
+ {
+ DEBUG_printf(("ppd->filters[%d] = \"%s\"\n", i, ppd->filters[i]));
+ AddPrinterFilter(p, ppd->filters[i]);
+ }
+
+ if (ppd->num_filters == 0)
+ AddPrinterFilter(p, "application/vnd.cups-postscript 0 -");
+
+ ppdClose(ppd);
+
+ printer_type = p->type;
+ }
+ else if (access(filename, 0) == 0)
+ {
+ LogMessage(L_ERROR, "PPD file for %s cannot be loaded!", p->name);
+
+ AddPrinterFilter(p, "application/vnd.cups-postscript 0 -");
+ }
+ else
+ {
+ /*
+ * If we have an interface script, add a filter entry for it...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot,
+ p->name);
+ if (access(filename, X_OK) == 0)
+ {
+ /*
+ * Yes, we have a System V style interface script; use it!
+ */
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-make-and-model", NULL, "Local System V Printer");
+
+ snprintf(filename, sizeof(filename), "*/* 0 %s/interfaces/%s",
+ ServerRoot, p->name);
+ AddPrinterFilter(p, filename);
+ }
+ else if (strncmp(p->device_uri, "ipp://", 6) == 0 &&
+ (strstr(p->device_uri, "/printers/") != NULL ||
+ strstr(p->device_uri, "/classes/") != NULL))
+ {
+ /*
+ * Tell the client this is really a hard-wired remote printer.
+ */
+
+ printer_type |= CUPS_PRINTER_REMOTE;
+
+ /*
+ * Reset the printer-uri-supported attribute to point at the
+ * remote printer...
+ */
+
+ attr = ippFindAttribute(p->attrs, "printer-uri-supported", IPP_TAG_URI);
+ free(attr->values[0].string.text);
+ attr->values[0].string.text = strdup(p->device_uri);
+
+ /*
+ * Then set the make-and-model accordingly...
+ */
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-make-and-model", NULL, "Remote Printer");
+
+ /*
+ * Print all files directly...
+ */
+
+ AddPrinterFilter(p, "*/* 0 -");
+ }
+ else
+ {
+ /*
+ * Otherwise we have neither - treat this as a "dumb" printer
+ * with no PPD file...
+ */
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-make-and-model", NULL, "Local Raw Printer");
+
+ AddPrinterFilter(p, "*/* 0 -");
+ }
+ }
+
+ ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
+ "finishings-supported", num_finishings, (int *)finishings);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
+ "finishings-default", IPP_FINISHINGS_NONE);
+ }
+ }
+
+ /*
+ * Add the CUPS-specific printer-type attribute...
+ */
+
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type",
+ printer_type);
+
+ DEBUG_printf(("SetPrinterAttrs: leaving name = %s, type = %x\n", p->name,
+ p->type));
+
+#ifdef __sgi
+ /*
+ * Write the IRIX printer config and status files...
+ */
+
+ write_irix_config(p);
+ write_irix_state(p);
+#endif /* __sgi */
+}
+
+
+/*
+ * 'SetPrinterState()' - Update the current state of a printer.
+ */
+
+void
+SetPrinterState(printer_t *p, /* I - Printer to change */
+ ipp_pstate_t s) /* I - New state */
+{
+ ipp_pstate_t old_state; /* Old printer state */
+
+
+ /*
+ * Can't set status of remote printers...
+ */
+
+ if (p->type & CUPS_PRINTER_REMOTE)
+ return;
+
+ /*
+ * Set the new state...
+ */
+
+ old_state = p->state;
+ p->state = s;
+ p->state_time = time(NULL);
+
+ if (old_state != s)
+ {
+ p->browse_time = 0;
+
+#ifdef __sgi
+ write_irix_state(p);
+#endif /* __sgi */
+ }
+
+ /*
+ * Save the printer configuration if a printer goes from idle or processing
+ * to stopped (or visa-versa)...
+ */
+
+ if ((old_state == IPP_PRINTER_STOPPED) != (s == IPP_PRINTER_STOPPED))
+ SaveAllPrinters();
+}
+
+
+/*
+ * 'SortPrinters()' - Sort the printer list when a printer name is changed.
+ */
+
+void
+SortPrinters(void)
+{
+ printer_t *current, /* Current printer */
+ *prev, /* Previous printer */
+ *next; /* Next printer */
+ int did_swap; /* Non-zero if we did a swap */
+
+
+ do
+ {
+ for (did_swap = 0, current = Printers, prev = NULL; current != NULL;)
+ if (current->next == NULL)
+ break;
+ else if (strcasecmp(current->name, current->next->name) > 0)
+ {
+ DEBUG_printf(("Swapping %s and %s...\n", current->name,
+ current->next->name));
+
+ /*
+ * Need to swap these two printers...
+ */
+
+ did_swap = 1;
+
+ if (prev == NULL)
+ Printers = current->next;
+ else
+ prev->next = current->next;
+
+ /*
+ * Yes, we can all get a headache from the next bunch of pointer
+ * swapping...
+ */
+
+ next = current->next;
+ current->next = next->next;
+ next->next = current;
+ prev = next;
+ }
+ else
+ {
+ prev = current;
+ current = current->next;
+ }
+ }
+ while (did_swap);
+}
+
+
+/*
+ * 'StopPrinter()' - Stop a printer from printing any jobs...
+ */
+
+void
+StopPrinter(printer_t *p) /* I - Printer to stop */
+{
+ job_t *job; /* Active print job */
+
+
+ /*
+ * Set the printer state...
+ */
+
+ p->state = IPP_PRINTER_STOPPED;
+
+ /*
+ * See if we have a job printing on this printer...
+ */
+
+ if (p->job)
+ {
+ /*
+ * Get pointer to job...
+ */
+
+ job = (job_t *)p->job;
+
+ /*
+ * Stop it...
+ */
+
+ StopJob(job->id, 0);
+
+ /*
+ * Reset the state to pending...
+ */
+
+ job->state->values[0].integer = IPP_JOB_PENDING;
+
+ SaveJob(job->id);
+ }
+}
+
+
+/*
+ * 'ValidateDest()' - Validate a printer/class destination.
+ */
+
+const char * /* O - Printer or class name */
+ValidateDest(const char *hostname, /* I - Host name */
+ const char *resource, /* I - Resource name */
+ cups_ptype_t *dtype) /* O - Type (printer or class) */
+{
+ printer_t *p; /* Current printer */
+ char localname[1024], /* Localized hostname */
+ *lptr, /* Pointer into localized hostname */
+ *sptr; /* Pointer into server name */
+
+
+ DEBUG_printf(("ValidateDest(\"%s\", \"%s\", %p)\n", hostname, resource, dtype));
+
+ /*
+ * See if the resource is a class or printer...
+ */
+
+ if (strncmp(resource, "/classes/", 9) == 0)
+ {
+ /*
+ * Class...
+ */
+
+ resource += 9;
+ }
+ else if (strncmp(resource, "/printers/", 10) == 0)
+ {
+ /*
+ * Printer...
+ */
+
+ resource += 10;
+ }
+ else
+ {
+ /*
+ * Bad resource name...
+ */
+
+ return (NULL);
+ }
+
+ /*
+ * See if the printer or class name exists...
+ */
+
+ if ((p = FindPrinter(resource)) == NULL)
+ p = FindClass(resource);
+
+ if (p == NULL && strchr(resource, '@') == NULL)
+ return (NULL);
+ else if (p != NULL)
+ {
+ *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_REMOTE);
+ return (p->name);
+ }
+
+ /*
+ * Change localhost to the server name...
+ */
+
+ if (strcasecmp(hostname, "localhost") == 0)
+ hostname = ServerName;
+
+ strlcpy(localname, hostname, sizeof(localname));
+
+ if (strcasecmp(hostname, ServerName) != 0)
+ {
+ /*
+ * Localize the hostname...
+ */
+
+ lptr = strchr(localname, '.');
+ sptr = strchr(ServerName, '.');
+
+ if (sptr != NULL && lptr != NULL)
+ {
+ /*
+ * Strip the common domain name components...
+ */
+
+ while (lptr != NULL)
+ {
+ if (strcasecmp(lptr, sptr) == 0)
+ {
+ *lptr = '\0';
+ break;
+ }
+ else
+ lptr = strchr(lptr + 1, '.');
+ }
+ }
+ }
+
+ DEBUG_printf(("localized hostname is \"%s\"...\n", localname));
+
+ /*
+ * Find a matching printer or class...
+ */
+
+ for (p = Printers; p != NULL; p = p->next)
+ if (strcasecmp(p->hostname, localname) == 0 &&
+ strcasecmp(p->name, resource) == 0)
+ {
+ *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_REMOTE);
+ return (p->name);
+ }
+
+ return (NULL);
+}
+
+
+/*
+ * 'WritePrintcap()' - Write a pseudo-printcap file for older applications
+ * that need it...
+ */
+
+void
+WritePrintcap(void)
+{
+ FILE *fp; /* printcap file */
+ printer_t *p; /* Current printer */
+
+
+#ifdef __sgi
+ /*
+ * Update the IRIX printer state for the default printer; if
+ * no printers remain, then the default printer file will be
+ * removed...
+ */
+
+ write_irix_state(DefaultPrinter);
+#endif /* __sgi */
+
+ /*
+ * See if we have a printcap file; if not, don't bother writing it.
+ */
+
+ if (!Printcap[0])
+ return;
+
+ /*
+ * Open the printcap file...
+ */
+
+ if ((fp = fopen(Printcap, "w")) == NULL)
+ return;
+
+ /*
+ * Put a comment header at the top so that users will know where the
+ * data has come from...
+ */
+
+ fputs("# This file was automatically generated by cupsd(8) from the\n", fp);
+ fprintf(fp, "# %s/printers.conf file. All changes to this file\n",
+ ServerRoot);
+ fputs("# will be lost.\n", fp);
+
+ /*
+ * Write a new printcap with the current list of printers.
+ */
+
+ switch (PrintcapFormat)
+ {
+ case PRINTCAP_BSD:
+ /*
+ * Each printer is put in the file as:
+ *
+ * Printer1:
+ * Printer2:
+ * Printer3:
+ * ...
+ * PrinterN:
+ */
+
+ if (DefaultPrinter)
+ fprintf(fp, "%s:\n", DefaultPrinter->name);
+
+ for (p = Printers; p != NULL; p = p->next)
+ if (p != DefaultPrinter)
+ fprintf(fp, "%s:\n", p->name);
+ break;
+
+ case PRINTCAP_SOLARIS:
+ /*
+ * Each printer is put in the file as:
+ *
+ * _all:all=Printer1,Printer2,Printer3,...,PrinterN
+ * _default:use=DefaultPrinter
+ * Printer1:\
+ * :bsdaddr=ServerName,Printer1:\
+ * :description=Description:
+ * Printer2:
+ * :bsdaddr=ServerName,Printer2:\
+ * :description=Description:
+ * Printer3:
+ * :bsdaddr=ServerName,Printer3:\
+ * :description=Description:
+ * ...
+ * PrinterN:
+ * :bsdaddr=ServerName,PrinterN:\
+ * :description=Description:
+ */
+
+ fputs("_all:all=", fp);
+ for (p = Printers; p != NULL; p = p->next)
+ fprintf(fp, "%s%c", p->name, p->next ? ',' : '\n');
+
+ if (DefaultPrinter)
+ fprintf(fp, "_default:use=%s\n", DefaultPrinter->name);
+
+ for (p = Printers; p != NULL; p = p->next)
+ fprintf(fp, "%s:\\\n"
+ "\t:bsdaddr=%s,%s:\\\n"
+ "\t:description=%s:\n",
+ p->name, ServerName, p->name, p->info);
+ break;
+ }
+
+ /*
+ * Close the file...
+ */
+
+ fclose(fp);
+}
+
+
+#ifdef __sgi
+/*
+ * 'write_irix_config()' - Update the config files used by the IRIX
+ * desktop tools.
+ */
+
+static void
+write_irix_config(printer_t *p) /* I - Printer to update */
+{
+ char filename[1024]; /* Interface script filename */
+ FILE *fp; /* Interface script file */
+ ipp_attribute_t *attr; /* Attribute value */
+
+
+ /*
+ * Add dummy interface and GUI scripts to fool SGI's "challenged" printing
+ * tools. First the interface script that tells the tools what kind of
+ * printer we have...
+ */
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/interface/%s", p->name);
+
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = fopen(filename, "w")) != NULL)
+ {
+ fputs("#!/bin/sh\n", fp);
+
+ if ((attr = ippFindAttribute(p->attrs, "printer-make-and-model",
+ IPP_TAG_TEXT)) != NULL)
+ fprintf(fp, "NAME=\"%s\"\n", attr->values[0].string.text);
+ else if (p->type & CUPS_PRINTER_CLASS)
+ fputs("NAME=\"Printer Class\"\n", fp);
+ else
+ fputs("NAME=\"Remote Destination\"\n", fp);
+
+ if (p->type & CUPS_PRINTER_COLOR)
+ fputs("TYPE=ColorPostScript\n", fp);
+ else
+ fputs("TYPE=MonoPostScript\n", fp);
+
+ fprintf(fp, "HOSTNAME=%s\n", ServerName);
+ fprintf(fp, "HOSTPRINTER=%s\n", p->name);
+
+ fclose(fp);
+
+ chmod(filename, 0755);
+ chown(filename, User, Group);
+ }
+
+ /*
+ * Then the member file that tells which device file the queue is connected
+ * to... Networked printers use "/dev/null" in this file, so that's what
+ * we use (the actual device URI can confuse some apps...)
+ */
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/member/%s", p->name);
+
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = fopen(filename, "w")) != NULL)
+ {
+ fputs("/dev/null\n", fp);
+
+ fclose(fp);
+
+ chmod(filename, 0644);
+ chown(filename, User, Group);
+ }
+
+ /*
+ * The gui_interface file is a script or program that launches a GUI
+ * option panel for the printer, using options specified on the
+ * command-line in the third argument. The option panel must send
+ * any printing options to stdout on a single line when the user
+ * accepts them, or nothing if the user cancels the dialog.
+ *
+ * The default options panel program is /usr/bin/glpoptions, from
+ * the ESP Print Pro software. You can select another using the
+ * PrintcapGUI option.
+ */
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/gui_interface/ELF/%s.gui", p->name);
+
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = fopen(filename, "w")) != NULL)
+ {
+ fputs("#!/bin/sh\n", fp);
+ fprintf(fp, "%s -d %s -o \"$3\"\n", PrintcapGUI, p->name);
+
+ fclose(fp);
+
+ chmod(filename, 0755);
+ chown(filename, User, Group);
+ }
+
+ /*
+ * The POD config file is needed by the printstatus command to show
+ * the printer location and device.
+ */
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.config", p->name);
+
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = fopen(filename, "w")) != NULL)
+ {
+ fprintf(fp, "Printer Class | %s\n",
+ (p->type & CUPS_PRINTER_COLOR) ? "ColorPostScript" : "MonoPostScript");
+ fprintf(fp, "Printer Model | %s\n", p->make_model);
+ fprintf(fp, "Location Code | %s\n", p->location);
+ fprintf(fp, "Physical Location | %s\n", p->info);
+ fprintf(fp, "Port Path | %s\n", p->device_uri);
+ fprintf(fp, "Config Path | /var/spool/lp/pod/%s.config\n", p->name);
+ fprintf(fp, "Active Status Path | /var/spool/lp/pod/%s.status\n", p->name);
+ fputs("Status Update Wait | 10 seconds\n", fp);
+
+ fclose(fp);
+
+ chmod(filename, 0664);
+ chown(filename, User, Group);
+ }
+}
+
+
+/*
+ * 'write_irix_state()' - Update the status files used by IRIX printing
+ * desktop tools.
+ */
+
+static void
+write_irix_state(printer_t *p) /* I - Printer to update */
+{
+ char filename[1024]; /* Interface script filename */
+ FILE *fp; /* Interface script file */
+ int tag; /* Status tag value */
+
+
+ if (p)
+ {
+ /*
+ * The POD status file is needed for the printstatus window to
+ * provide the current status of the printer.
+ */
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.status", p->name);
+
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = fopen(filename, "w")) != NULL)
+ {
+ fprintf(fp, "Operational Status | %s\n",
+ (p->state == IPP_PRINTER_IDLE) ? "Idle" :
+ (p->state == IPP_PRINTER_PROCESSING) ? "Busy" :
+ "Faulted");
+ fprintf(fp, "Information | 01 00 00 | %s\n", CUPS_SVERSION);
+ fprintf(fp, "Information | 02 00 00 | Device URI: %s\n", p->device_uri);
+ fprintf(fp, "Information | 03 00 00 | %s jobs\n",
+ p->accepting ? "Accepting" : "Not accepting");
+ fprintf(fp, "Information | 04 00 00 | %s\n", p->state_message);
+
+ fclose(fp);
+
+ chmod(filename, 0664);
+ chown(filename, User, Group);
+ }
+
+ /*
+ * The activeicons file is needed to provide desktop icons for printers:
+ *
+ * [ quoted from /usr/lib/print/tagit ]
+ *
+ * --- Type of printer tags (base values)
+ *
+ * Dumb=66048 # 0x10200
+ * DumbColor=66080 # 0x10220
+ * Raster=66112 # 0x10240
+ * ColorRaster=66144 # 0x10260
+ * Plotter=66176 # 0x10280
+ * PostScript=66208 # 0x102A0
+ * ColorPostScript=66240 # 0x102C0
+ * MonoPostScript=66272 # 0x102E0
+ *
+ * --- Printer state modifiers for local printers
+ *
+ * Idle=0 # 0x0
+ * Busy=1 # 0x1
+ * Faulted=2 # 0x2
+ * Unknown=3 # 0x3 (Faulted due to unknown reason)
+ *
+ * --- Printer state modifiers for network printers
+ *
+ * NetIdle=8 # 0x8
+ * NetBusy=9 # 0x9
+ * NetFaulted=10 # 0xA
+ * NetUnknown=11 # 0xB (Faulted due to unknown reason)
+ */
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/activeicons/%s", p->name);
+
+ if (p->type & CUPS_PRINTER_CLASS)
+ unlink(filename);
+ else if ((fp = fopen(filename, "w")) != NULL)
+ {
+ if (p->type & CUPS_PRINTER_COLOR)
+ tag = 66240;
+ else
+ tag = 66272;
+
+ if (p->type & CUPS_PRINTER_REMOTE)
+ tag |= 8;
+
+ if (p->state == IPP_PRINTER_PROCESSING)
+ tag |= 1;
+
+ else if (p->state == IPP_PRINTER_STOPPED)
+ tag |= 2;
+
+ fputs("#!/bin/sh\n", fp);
+ fprintf(fp, "#Tag %d\n", tag);
+
+ fclose(fp);
+
+ chmod(filename, 0755);
+ chown(filename, User, Group);
+ }
+ }
+
+ /*
+ * The default file is needed by the printers window to show
+ * the default printer.
+ */
+
+ snprintf(filename, sizeof(filename), "/var/spool/lp/default");
+
+ if (DefaultPrinter != NULL)
+ {
+ if ((fp = fopen(filename, "w")) != NULL)
+ {
+ fprintf(fp, "%s\n", DefaultPrinter->name);
+
+ fclose(fp);
+
+ chmod(filename, 0644);
+ chown(filename, User, Group);
+ }
+ }
+ else
+ unlink(filename);
+}
+#endif /* __sgi */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/printers.h b/scheduler/printers.h
new file mode 100644
index 000000000..d44f4e26b
--- /dev/null
+++ b/scheduler/printers.h
@@ -0,0 +1,118 @@
+/*
+ * "$Id$"
+ *
+ * Printer definitions for the Common UNIX Printing System (CUPS) scheduler.
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Quota data...
+ */
+
+typedef struct
+{
+ char username[33]; /* User data */
+ time_t next_update; /* Next update time */
+ int page_count, /* Count of pages */
+ k_count; /* Count of kilobytes */
+} quota_t;
+
+
+/*
+ * Printer/class information structure...
+ */
+
+typedef struct printer_str
+{
+ struct printer_str *next; /* Next printer in list */
+ char uri[HTTP_MAX_URI], /* Printer URI */
+ hostname[HTTP_MAX_HOST],/* Host printer resides on */
+ name[IPP_MAX_NAME], /* Printer name */
+ location[IPP_MAX_NAME], /* Location code */
+ make_model[IPP_MAX_NAME],/* Make and model */
+ info[IPP_MAX_NAME]; /* Description */
+ int accepting; /* Accepting jobs? */
+ ipp_pstate_t state; /* Printer state */
+ char state_message[1024]; /* Printer state message */
+ time_t state_time; /* Time at this state */
+ char job_sheets[2][IPP_MAX_NAME];
+ /* Banners/job sheets */
+ cups_ptype_t type; /* Printer type (color, small, etc.) */
+ time_t browse_time; /* Last time update was sent/received */
+ char device_uri[HTTP_MAX_URI],/* Device URI */
+ backend[1024]; /* Backend to use */
+ mime_type_t *filetype; /* Pseudo-filetype for printer */
+ void *job; /* Current job in queue */
+ ipp_t *attrs; /* Attributes supported by this printer */
+ int num_printers, /* Number of printers in class */
+ last_printer; /* Last printer job was sent to */
+ struct printer_str **printers; /* Printers in class */
+ int quota_period, /* Period for quotas */
+ page_limit, /* Maximum number of pages */
+ k_limit, /* Maximum number of kilobytes */
+ num_quotas; /* Number of quota records */
+ quota_t *quotas; /* Quota records */
+ int deny_users, /* 1 = deny, 0 = allow */
+ num_users; /* Number of allowed/denied users */
+ const char **users; /* Allowed/denied users */
+} printer_t;
+
+
+/*
+ * Globals...
+ */
+
+VAR printer_t *Printers VALUE(NULL); /* Printer list */
+VAR printer_t *DefaultPrinter VALUE(NULL);
+ /* Default printer */
+
+/*
+ * Prototypes...
+ */
+
+extern printer_t *AddPrinter(const char *name);
+extern void AddPrinterFilter(printer_t *p, const char *filter);
+extern void AddPrinterUser(printer_t *p, const char *username);
+extern quota_t *AddQuota(printer_t *p, const char *username);
+extern void DeleteAllPrinters(void);
+extern void DeletePrinter(printer_t *p);
+extern void DeletePrinterFilters(printer_t *p);
+extern printer_t *FindPrinter(const char *name);
+extern quota_t *FindQuota(printer_t *p, const char *username);
+extern void FreePrinterUsers(printer_t *p);
+extern void FreeQuotas(printer_t *p);
+extern void LoadAllPrinters(void);
+extern void SaveAllPrinters(void);
+extern void SetPrinterAttrs(printer_t *p);
+extern void SetPrinterState(printer_t *p, ipp_pstate_t s);
+extern void SortPrinters(void);
+#define StartPrinter(p) SetPrinterState((p), IPP_PRINTER_IDLE)
+extern void StopPrinter(printer_t *p);
+extern quota_t *UpdateQuota(printer_t *p, const char *username,
+ int pages, int k);
+extern const char *ValidateDest(const char *hostname,
+ const char *resource,
+ cups_ptype_t *dtype);
+extern void WritePrintcap(void);
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/quotas.c b/scheduler/quotas.c
new file mode 100644
index 000000000..0b39ab4df
--- /dev/null
+++ b/scheduler/quotas.c
@@ -0,0 +1,235 @@
+/*
+ * "$Id$"
+ *
+ * Quota routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * AddQuota() - Add a quota record for this printer and user.
+ * FindQuota() - Find a quota record.
+ * FreeQuotas() - Free quotas for a printer.
+ * UpdateQuota() - Update quota data for the specified printer and user.
+ * compare() - Compare two quota records...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+
+
+/*
+ * Local functions...
+ */
+
+static int compare(const quota_t *q1, const quota_t *q2);
+
+
+/*
+ * 'AddQuota()' - Add a quota record for this printer and user.
+ */
+
+quota_t * /* O - Quota data */
+AddQuota(printer_t *p, /* I - Printer */
+ const char *username) /* I - User */
+{
+ quota_t *q; /* New quota data */
+
+
+ if (!p || !username)
+ return (NULL);
+
+ if (p->num_quotas == 0)
+ q = malloc(sizeof(quota_t));
+ else
+ q = realloc(p->quotas, sizeof(quota_t) * (p->num_quotas + 1));
+
+ if (!q)
+ return (NULL);
+
+ p->quotas = q;
+ q += p->num_quotas;
+ p->num_quotas ++;
+
+ memset(q, 0, sizeof(quota_t));
+ strlcpy(q->username, username, sizeof(q->username));
+
+ if (p->num_quotas > 1)
+ qsort(p->quotas, p->num_quotas, sizeof(quota_t),
+ (int (*)(const void *, const void *))compare);
+
+ return (FindQuota(p, username));
+}
+
+
+/*
+ * 'FindQuota()' - Find a quota record.
+ */
+
+quota_t * /* O - Quota data */
+FindQuota(printer_t *p, /* I - Printer */
+ const char *username) /* I - User */
+{
+ quota_t *q, /* Quota data pointer */
+ match; /* Search data */
+
+
+ if (!p || !username)
+ return (NULL);
+
+ if (p->num_quotas == 0)
+ q = NULL;
+ else
+ {
+ strlcpy(match.username, username, sizeof(match.username));
+
+ q = bsearch(&match, p->quotas, p->num_quotas, sizeof(quota_t),
+ (int(*)(const void *, const void *))compare);
+ }
+
+ if (q)
+ return (q);
+ else
+ return (AddQuota(p, username));
+}
+
+
+/*
+ * 'FreeQuotas()' - Free quotas for a printer.
+ */
+
+void
+FreeQuotas(printer_t *p) /* I - Printer */
+{
+ if (!p)
+ return;
+
+ if (p->num_quotas)
+ free(p->quotas);
+
+ p->num_quotas = 0;
+ p->quotas = NULL;
+}
+
+
+/*
+ * 'UpdateQuota()' - Update quota data for the specified printer and user.
+ */
+
+quota_t * /* O - Quota data */
+UpdateQuota(printer_t *p, /* I - Printer */
+ const char *username, /* I - User */
+ int pages, /* I - Number of pages */
+ int k) /* I - Number of kilobytes */
+{
+ quota_t *q; /* Quota data */
+ job_t *job, /* Current job */
+ *next; /* Next job */
+ time_t curtime; /* Current time */
+ ipp_attribute_t *attr; /* Job attribute */
+
+
+ if (!p || !username)
+ return (NULL);
+
+ if (!p->k_limit && !p->page_limit)
+ return (NULL);
+
+ if ((q = FindQuota(p, username)) == NULL)
+ return (NULL);
+
+ curtime = time(NULL);
+
+ if (curtime < q->next_update)
+ {
+ q->page_count += pages;
+ q->k_count += k;
+
+ return (q);
+ }
+
+ if (p->quota_period)
+ curtime -= p->quota_period;
+ else
+ curtime = 0;
+
+ q->next_update = 0;
+ q->page_count = 0;
+ q->k_count = 0;
+
+ for (job = Jobs; job; job = next)
+ {
+ next = job->next;
+
+ if (strcasecmp(job->dest, p->name) != 0 ||
+ strcasecmp(job->username, q->username) != 0)
+ continue;
+
+ if ((attr = ippFindAttribute(job->attrs, "time-at-completion",
+ IPP_TAG_INTEGER)) == NULL)
+ if ((attr = ippFindAttribute(job->attrs, "time-at-processing",
+ IPP_TAG_INTEGER)) == NULL)
+ attr = ippFindAttribute(job->attrs, "time-at-creation",
+ IPP_TAG_INTEGER);
+
+ if (attr == NULL)
+ break;
+
+ if (attr->values[0].integer < curtime)
+ {
+ if (JobAutoPurge)
+ CancelJob(job->id, 1);
+
+ continue;
+ }
+
+ if (q->next_update == 0)
+ q->next_update = attr->values[0].integer + p->quota_period;
+
+ if ((attr = ippFindAttribute(job->attrs, "job-media-sheets-completed",
+ IPP_TAG_INTEGER)) != NULL)
+ q->page_count += attr->values[0].integer;
+
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
+ IPP_TAG_INTEGER)) != NULL)
+ q->k_count += attr->values[0].integer;
+ }
+
+ return (q);
+}
+
+
+/*
+ * 'compare()' - Compare two quota records...
+ */
+
+static int /* O - Result of comparison */
+compare(const quota_t *q1, /* I - First quota record */
+ const quota_t *q2) /* I - Second quota record */
+{
+ return (strcasecmp(q1->username, q2->username));
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/server.c b/scheduler/server.c
new file mode 100644
index 000000000..524e807b7
--- /dev/null
+++ b/scheduler/server.c
@@ -0,0 +1,162 @@
+/*
+ * "$Id$"
+ *
+ * Server start/stop routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * StartServer() - Start the server.
+ * StopServer() - Stop the server.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+
+#include <grp.h>
+
+#ifdef HAVE_LIBSSL
+# include <openssl/ssl.h>
+# include <openssl/rand.h>
+#endif /* HAVE_LIBSSL */
+
+
+/*
+ * 'StartServer()' - Start the server.
+ */
+
+void
+StartServer(void)
+{
+#ifdef HAVE_LIBSSL
+ int i; /* Looping var */
+ struct timeval curtime; /* Current time in microseconds */
+ unsigned char data[1024]; /* Seed data */
+#endif /* HAVE_LIBSSL */
+
+
+#ifdef HAVE_LIBSSL
+ /*
+ * Initialize the encryption libraries...
+ */
+
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ /*
+ * Using the current time is a dubious random seed, but on some systems
+ * it is the best we can do (on others, this seed isn't even used...)
+ */
+
+ gettimeofday(&curtime, NULL);
+ srand(curtime.tv_sec + curtime.tv_usec);
+
+ for (i = 0; i < sizeof(data); i ++)
+ data[i] = rand(); /* Yes, this is a poor source of random data... */
+
+ RAND_seed(&data, sizeof(data));
+#endif /* HAVE_LIBSSL */
+
+ /*
+ * Startup all the networking stuff...
+ */
+
+ StartListening();
+ StartBrowsing();
+ StartPolling();
+
+ /*
+ * If the administrator has configured the server to run as an unpriviledged
+ * user, change to that user now...
+ */
+
+ if (RunAsUser)
+ {
+ setgid(Group);
+ setgroups(0, NULL);
+ setuid(User);
+ }
+}
+
+
+/*
+ * 'StopServer()' - Stop the server.
+ */
+
+void
+StopServer(void)
+{
+ /*
+ * Close all network clients and stop all jobs...
+ */
+
+ CloseAllClients();
+ StopListening();
+ StopPolling();
+ StopBrowsing();
+
+ if (Clients != NULL)
+ {
+ free(Clients);
+ Clients = NULL;
+ }
+
+ StopAllJobs();
+
+ /*
+ * Close all log files...
+ */
+
+ if (AccessFile != NULL)
+ {
+ fclose(AccessFile);
+
+ AccessFile = NULL;
+ }
+
+ if (ErrorFile != NULL)
+ {
+ fclose(ErrorFile);
+
+ ErrorFile = NULL;
+ }
+
+ if (PageFile != NULL)
+ {
+ fclose(PageFile);
+
+ PageFile = NULL;
+ }
+
+ /*
+ * Clear the input and output sets...
+ */
+
+ FD_ZERO(&InputSet);
+ FD_ZERO(&OutputSet);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/testmime.c b/scheduler/testmime.c
new file mode 100644
index 000000000..20015d11e
--- /dev/null
+++ b/scheduler/testmime.c
@@ -0,0 +1,241 @@
+/*
+ * "$Id$"
+ *
+ * MIME test program for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Main entry for the test program.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cups/string.h>
+#include "mime.h"
+
+
+/*
+ * Local functions...
+ */
+
+static void print_rules(mime_magic_t *rules);
+
+
+/*
+ * 'main()' - Main entry for the test program.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line args */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ char super[MIME_MAX_SUPER], /* Super-type name */
+ type[MIME_MAX_TYPE]; /* Type name */
+ mime_t *mime; /* MIME database */
+ mime_type_t *src, /* Source type */
+ *dst, /* Destination type */
+ **types; /* File type array pointer */
+ mime_filter_t *filters; /* Filters for the file */
+ int num_filters; /* Number of filters for the file */
+
+
+ mime = NULL;
+ src = NULL;
+ dst = NULL;
+
+ for (i = 1; i < argc; i ++)
+ if (strcmp(argv[i], "-d") == 0)
+ {
+ i ++;
+
+ if (i < argc)
+ mime = mimeLoad(argv[i]);
+ }
+ else if (src == NULL)
+ {
+ if (!mime)
+ mime = mimeLoad("../conf");
+
+ src = mimeFileType(mime, argv[i]);
+
+ if (src != NULL)
+ {
+ printf("%s: %s/%s\n", argv[i], src->super, src->type);
+ if (mime)
+ mimeDelete(mime);
+ return (0);
+ }
+ else
+ {
+ printf("%s: unknown\n", argv[i]);
+ if (mime)
+ mimeDelete(mime);
+ return (1);
+ }
+ }
+ else
+ {
+ sscanf(argv[i], "%15[^/]/%31s", super, type);
+ dst = mimeType(mime, super, type);
+
+ filters = mimeFilter(mime, src, dst, &num_filters);
+
+ if (filters == NULL)
+ {
+ printf("No filters to convert from %s/%s to %s.\n", src->super,
+ src->type, argv[i]);
+ }
+ else
+ {
+ for (i = 0; i < num_filters; i ++)
+ if (i < (num_filters - 1))
+ printf("%s | ", filters[i].filter);
+ else
+ puts(filters[i].filter);
+
+ free(filters);
+ }
+ }
+
+ if (!mime)
+ mime = mimeLoad("../conf");
+
+ if (src == NULL)
+ {
+ puts("MIME database types:");
+ for (i = 0, types = mime->types; i < mime->num_types; i ++, types ++)
+ {
+ printf("\t%s/%s:\n", (*types)->super, (*types)->type);
+ print_rules((*types)->rules);
+ puts("");
+ }
+
+ puts("");
+
+ puts("MIME database filters:");
+ for (i = 0, filters = mime->filters; i < mime->num_filters; i ++, filters ++)
+ printf("\t%s/%s to %s/%s: %s (%d)\n",
+ filters->src->super, filters->src->type,
+ filters->dst->super, filters->dst->type,
+ filters->filter, filters->cost);
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'print_rules()' - Print the rules for a file type...
+ */
+
+static void
+print_rules(mime_magic_t *rules) /* I - Rules to print */
+{
+ int i; /* Looping var */
+ static char indent[255] = "\t"; /* Indentation for rules */
+
+
+ if (rules == NULL)
+ return;
+
+ while (rules != NULL)
+ {
+ printf("%s[%p] ", indent, rules);
+
+ if (rules->invert)
+ printf("NOT ");
+
+ switch (rules->op)
+ {
+ case MIME_MAGIC_MATCH :
+ printf("match(%s)", rules->value.matchv);
+ break;
+ case MIME_MAGIC_LOCALE :
+ printf("locale(%s)", rules->value.localev);
+ break;
+ case MIME_MAGIC_ASCII :
+ printf("ascii(%d,%d)", rules->offset, rules->length);
+ break;
+ case MIME_MAGIC_PRINTABLE :
+ printf("printable(%d,%d)", rules->offset, rules->length);
+ break;
+ case MIME_MAGIC_STRING :
+ printf("string(%d,", rules->offset);
+ for (i = 0; i < rules->length; i ++)
+ if (rules->value.stringv[i] < ' ' ||
+ rules->value.stringv[i] > 126)
+ printf("<%02X>", rules->value.stringv[i]);
+ else
+ putchar(rules->value.stringv[i]);
+ putchar(')');
+ break;
+ case MIME_MAGIC_CHAR :
+ printf("char(%d,%d)", rules->offset, rules->value.charv);
+ break;
+ case MIME_MAGIC_SHORT :
+ printf("short(%d,%d)", rules->offset, rules->value.shortv);
+ break;
+ case MIME_MAGIC_INT :
+ printf("int(%d,%d)", rules->offset, rules->value.intv);
+ break;
+ case MIME_MAGIC_CONTAINS :
+ printf("contains(%d,%d,", rules->offset, rules->region);
+ for (i = 0; i < rules->length; i ++)
+ if (rules->value.stringv[i] < ' ' ||
+ rules->value.stringv[i] > 126)
+ printf("<%02X>", rules->value.stringv[i]);
+ else
+ putchar(rules->value.stringv[i]);
+ putchar(')');
+ break;
+ default :
+ break;
+ }
+
+ if (rules->child != NULL)
+ {
+ if (rules->op == MIME_MAGIC_OR)
+ puts("OR (");
+ else
+ puts("AND (");
+
+ strcat(indent, "\t");
+ print_rules(rules->child);
+ indent[strlen(indent) - 1] = '\0';
+ printf("%s)\n", indent);
+ }
+ else
+ putchar('\n');
+
+ rules = rules->next;
+ }
+}
+
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/testspeed.c b/scheduler/testspeed.c
new file mode 100644
index 000000000..671f18148
--- /dev/null
+++ b/scheduler/testspeed.c
@@ -0,0 +1,126 @@
+/*
+ * "$Id$"
+ *
+ * Scheduler speed test for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <cups/debug.h>
+
+
+/*
+ * 'main()' - Send multiple IPP requests and report on the average response
+ * time.
+ */
+
+int
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ http_t *http; /* Connection to server */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ cups_lang_t *language; /* Default language */
+ struct timeval start, /* Start time */
+ end; /* End time */
+ double elapsed; /* Elapsed time */
+
+
+ if (argc > 1)
+ http = httpConnect(argv[1], ippPort());
+ else
+ http = httpConnect("localhost", ippPort());
+
+ if (http == NULL)
+ {
+ perror("testspeed: unable to connect to server");
+ return (1);
+ }
+
+ language = cupsLangDefault();
+
+ /*
+ * Do requests 100 times...
+ */
+
+ printf("Testing: ");
+
+ for (elapsed = 0.0, i = 0; i < 100; i ++)
+ {
+ putchar('>');
+ fflush(stdout);
+
+ /*
+ * Build a CUPS_GET_PRINTERS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_PRINTERS;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ gettimeofday(&start, NULL);
+ response = cupsDoRequest(http, request, "/printers/");
+ gettimeofday(&end, NULL);
+
+ putchar('<');
+
+ if (response != NULL)
+ ippDelete(response);
+
+ elapsed += (end.tv_sec - start.tv_sec) +
+ 0.000001 * (end.tv_usec - start.tv_usec);
+ }
+
+ puts("");
+ printf("Total elapsed time for %d requests was %.1fs (%.3fs/r)\n",
+ i, elapsed, elapsed / i);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/type.c b/scheduler/type.c
new file mode 100644
index 000000000..7459ea482
--- /dev/null
+++ b/scheduler/type.c
@@ -0,0 +1,1096 @@
+/*
+ * "$Id$"
+ *
+ * MIME typing routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * mimeAddType() - Add a MIME type to a database.
+ * mimeAddTypeRule() - Add a detection rule for a file type.
+ * mimeFileType() - Determine the type of a file.
+ * mimeType() - Lookup a file type.
+ * compare() - Compare two MIME super/type names.
+ * checkrules() - Check each rule in a list.
+ * patmatch() - Pattern matching...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <locale.h>
+
+#include <cups/string.h>
+#include "mime.h"
+#include <cups/debug.h>
+
+
+/*
+ * Local functions...
+ */
+
+static int compare(mime_type_t **, mime_type_t **);
+static int checkrules(const char *, FILE *, mime_magic_t *);
+static int patmatch(const char *, const char *);
+
+
+/*
+ * 'mimeAddType()' - Add a MIME type to a database.
+ */
+
+mime_type_t * /* O - New (or existing) MIME type */
+mimeAddType(mime_t *mime, /* I - MIME database */
+ const char *super, /* I - Super-type name */
+ const char *type) /* I - Type name */
+{
+ mime_type_t *temp, /* New MIME type */
+ **types; /* New MIME types array */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (mime == NULL || super == NULL || type == NULL)
+ return (NULL);
+
+ if (strlen(super) > (MIME_MAX_SUPER - 1) ||
+ strlen(type) > (MIME_MAX_TYPE - 1))
+ return (NULL);
+
+ /*
+ * See if the type already exists; if so, return the existing type...
+ */
+
+ if ((temp = mimeType(mime, super, type)) != NULL)
+ return (temp);
+
+ /*
+ * The type doesn't exist; add it...
+ */
+
+ if ((temp = calloc(1, sizeof(mime_type_t))) == NULL)
+ return (NULL);
+
+ if (mime->num_types == 0)
+ types = (mime_type_t **)malloc(sizeof(mime_type_t *));
+ else
+ types = (mime_type_t **)realloc(mime->types, sizeof(mime_type_t *) * (mime->num_types + 1));
+
+ if (types == NULL)
+ {
+ free(temp);
+ return (NULL);
+ }
+
+ mime->types = types;
+ types += mime->num_types;
+ mime->num_types ++;
+
+ *types = temp;
+ strlcpy(temp->super, super, sizeof(temp->super));
+ if ((temp->type = strdup(type)) == NULL)
+ {
+ mime->num_types --;
+ return (NULL);
+ }
+
+ if (mime->num_types > 1)
+ qsort(mime->types, mime->num_types, sizeof(mime_type_t *),
+ (int (*)(const void *, const void *))compare);
+
+ return (temp);
+}
+
+
+/*
+ * 'mimeAddTypeRule()' - Add a detection rule for a file type.
+ */
+
+int /* O - 0 on success, -1 on failure */
+mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */
+ const char *rule) /* I - Rule to add */
+{
+ int num_values, /* Number of values seen */
+ op, /* Operation code */
+ logic, /* Logic for next rule */
+ invert; /* Invert following rule? */
+ char name[255], /* Name in rule string */
+ value[3][255], /* Value in rule string */
+ *ptr, /* Position in name or value */
+ quote; /* Quote character */
+ int length[3]; /* Length of each parameter */
+ mime_magic_t *temp, /* New rule */
+ *current; /* Current rule */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (mt == NULL || rule == NULL)
+ return (-1);
+
+ /*
+ * Find the last rule in the top-level of the rules tree.
+ */
+
+ for (current = mt->rules; current != NULL; current = current->next)
+ if (current->next == NULL)
+ break;
+
+ /*
+ * Parse the rules string. Most rules are either a file extension or a
+ * comparison function:
+ *
+ * extension
+ * function(parameters)
+ */
+
+ logic = MIME_MAGIC_NOP;
+ invert = 0;
+
+ DEBUG_printf(("%s/%s: %s\n", mt->super, mt->type, rule));
+
+ while (*rule != '\0')
+ {
+ while (isspace(*rule))
+ rule ++;
+
+ if (*rule == '(')
+ {
+ DEBUG_puts("new parenthesis group");
+ logic = MIME_MAGIC_NOP;
+ rule ++;
+ }
+ else if (*rule == ')')
+ {
+ DEBUG_puts("close paren...");
+ if (current == NULL || current->parent == NULL)
+ return (-1);
+
+ current = current->parent;
+
+ if (current->parent == NULL)
+ logic = MIME_MAGIC_OR;
+ else
+ logic = current->parent->op;
+
+ rule ++;
+ }
+ else if (*rule == '+' && current != NULL)
+ {
+ if (logic != MIME_MAGIC_AND &&
+ current != NULL && current->prev != NULL && current->prev->prev != NULL)
+ {
+ /*
+ * OK, we have more than 1 rule in the current tree level... Make a
+ * new group tree and move the previous rule to it...
+ */
+
+ if ((temp = calloc(1, sizeof(mime_magic_t))) == NULL)
+ return (-1);
+
+ temp->op = MIME_MAGIC_AND;
+ temp->child = current;
+ temp->parent = current->parent;
+ current->prev->next = temp;
+ temp->prev = current->prev;
+
+ current->prev = NULL;
+ current->parent = temp;
+
+ DEBUG_printf(("creating new AND group %p...\n", temp));
+ }
+ else
+ {
+ DEBUG_printf(("setting group %p op to AND...\n", current->parent));
+ current->parent->op = MIME_MAGIC_AND;
+ }
+
+ logic = MIME_MAGIC_AND;
+ rule ++;
+ }
+ else if (*rule == ',')
+ {
+ if (logic != MIME_MAGIC_OR && current != NULL)
+ {
+ /*
+ * OK, we have two possibilities; either this is the top-level rule or
+ * we have a bunch of AND rules at this level.
+ */
+
+ if (current->parent == NULL)
+ {
+ /*
+ * This is the top-level rule; we have to move *all* of the AND rules
+ * down a level, as AND has precedence over OR.
+ */
+
+ if ((temp = calloc(1, sizeof(mime_magic_t))) == NULL)
+ return (-1);
+
+ DEBUG_printf(("creating new AND group %p inside OR group\n", temp));
+
+ while (current->prev != NULL)
+ {
+ current->parent = temp;
+ current = current->prev;
+ }
+
+ current->parent = temp;
+ temp->op = MIME_MAGIC_AND;
+ temp->child = current;
+
+ mt->rules = current = temp;
+ }
+ else
+ {
+ /*
+ * This isn't the top rule, so go up one level...
+ */
+
+ DEBUG_puts("going up one level");
+ current = current->parent;
+ }
+ }
+
+ logic = MIME_MAGIC_OR;
+ rule ++;
+ }
+ else if (*rule == '!')
+ {
+ DEBUG_puts("NOT");
+ invert = 1;
+ rule ++;
+ }
+ else if (isalnum(*rule))
+ {
+ /*
+ * Read an extension name or a function...
+ */
+
+ for (ptr = name; isalnum(*rule) && (ptr - name) < (sizeof(name) - 1);)
+ *ptr++ = *rule++;
+
+ *ptr = '\0';
+ num_values = 0;
+
+ if (*rule == '(')
+ {
+ /*
+ * Read function parameters...
+ */
+
+ rule ++;
+ for (num_values = 0;
+ num_values < (sizeof(value) / sizeof(value[0]));
+ num_values ++)
+ {
+ ptr = value[num_values];
+
+ while ((ptr - value[num_values]) < (sizeof(value[0]) - 1) &&
+ *rule != '\0' && *rule != ',' && *rule != ')')
+ {
+ if (isspace(*rule))
+ {
+ /*
+ * Ignore whitespace...
+ */
+
+ rule ++;
+ continue;
+ }
+ else if (*rule == '\"' || *rule == '\'')
+ {
+ /*
+ * Copy quoted strings literally...
+ */
+
+ quote = *rule++;
+
+ while (*rule != '\0' && *rule != quote &&
+ (ptr - value[num_values]) < (sizeof(value[0]) - 1))
+ *ptr++ = *rule++;
+
+ if (*rule == quote)
+ rule ++;
+ else
+ return (-1);
+ }
+ else if (*rule == '<')
+ {
+ rule ++;
+
+ while (*rule != '>' && *rule != '\0' &&
+ (ptr - value[num_values]) < (sizeof(value[0]) - 1))
+ {
+ if (isxdigit(rule[0]) && isxdigit(rule[1]))
+ {
+ if (isdigit(*rule))
+ *ptr = (*rule++ - '0') << 4;
+ else
+ *ptr = (tolower(*rule++) - 'a' + 10) << 4;
+
+ if (isdigit(*rule))
+ *ptr++ |= *rule++ - '0';
+ else
+ *ptr++ |= tolower(*rule++) - 'a' + 10;
+ }
+ else
+ return (-1);
+ }
+
+ if (*rule == '>')
+ rule ++;
+ else
+ return (-1);
+ }
+ else
+ *ptr++ = *rule++;
+ }
+
+ *ptr = '\0';
+ length[num_values] = ptr - value[num_values];
+
+ if (*rule != ',')
+ break;
+
+ rule ++;
+ }
+
+ if (*rule != ')')
+ return (-1);
+
+ rule ++;
+
+ /*
+ * Figure out the function...
+ */
+
+ if (strcmp(name, "match") == 0)
+ op = MIME_MAGIC_MATCH;
+ else if (strcmp(name, "ascii") == 0)
+ op = MIME_MAGIC_ASCII;
+ else if (strcmp(name, "printable") == 0)
+ op = MIME_MAGIC_PRINTABLE;
+ else if (strcmp(name, "string") == 0)
+ op = MIME_MAGIC_STRING;
+ else if (strcmp(name, "char") == 0)
+ op = MIME_MAGIC_CHAR;
+ else if (strcmp(name, "short") == 0)
+ op = MIME_MAGIC_SHORT;
+ else if (strcmp(name, "int") == 0)
+ op = MIME_MAGIC_INT;
+ else if (strcmp(name, "locale") == 0)
+ op = MIME_MAGIC_LOCALE;
+ else if (strcmp(name, "contains") == 0)
+ op = MIME_MAGIC_CONTAINS;
+ else
+ return (-1);
+ }
+ else
+ {
+ /*
+ * This is just a filename match on the extension...
+ */
+
+ snprintf(value[0], sizeof(value[0]), "*.%s", name);
+ length[0] = strlen(value[0]);
+ num_values = 1;
+ op = MIME_MAGIC_MATCH;
+ }
+
+ /*
+ * Add a rule for this operation.
+ */
+
+ if ((temp = calloc(1, sizeof(mime_magic_t))) == NULL)
+ return (-1);
+
+ temp->invert = invert;
+ if (current != NULL)
+ {
+ temp->parent = current->parent;
+ current->next = temp;
+ }
+ else
+ mt->rules = temp;
+
+ temp->prev = current;
+
+ if (logic == MIME_MAGIC_NOP)
+ {
+ /*
+ * Add parenthetical grouping...
+ */
+
+ DEBUG_printf(("making new OR group %p for parenthesis...\n", temp));
+
+ temp->op = MIME_MAGIC_OR;
+
+ if ((temp->child = calloc(1, sizeof(mime_magic_t))) == NULL)
+ return (-1);
+
+ temp->child->parent = temp;
+
+ temp = temp->child;
+ logic = MIME_MAGIC_OR;
+ }
+
+ DEBUG_printf(("adding %p: %s, op = %d, logic = %d, invert = %d\n",
+ temp, name, op, logic, invert));
+
+ /*
+ * Fill in data for the rule...
+ */
+
+ current = temp;
+ temp->op = op;
+ invert = 0;
+
+ switch (op)
+ {
+ case MIME_MAGIC_MATCH :
+ if (length[0] > (sizeof(temp->value.matchv) - 1))
+ return (-1);
+ strcpy(temp->value.matchv, value[0]);
+ break;
+ case MIME_MAGIC_ASCII :
+ case MIME_MAGIC_PRINTABLE :
+ temp->offset = strtol(value[0], NULL, 0);
+ temp->length = strtol(value[1], NULL, 0);
+ if (temp->length > MIME_MAX_BUFFER)
+ temp->length = MIME_MAX_BUFFER;
+ break;
+ case MIME_MAGIC_STRING :
+ temp->offset = strtol(value[0], NULL, 0);
+ if (length[1] > sizeof(temp->value.stringv))
+ return (-1);
+ temp->length = length[1];
+ memcpy(temp->value.stringv, value[1], length[1]);
+ break;
+ case MIME_MAGIC_CHAR :
+ temp->offset = strtol(value[0], NULL, 0);
+ if (length[1] == 1)
+ temp->value.charv = value[1][0];
+ else
+ temp->value.charv = strtol(value[1], NULL, 0);
+ break;
+ case MIME_MAGIC_SHORT :
+ temp->offset = strtol(value[0], NULL, 0);
+ temp->value.shortv = strtol(value[1], NULL, 0);
+ break;
+ case MIME_MAGIC_INT :
+ temp->offset = strtol(value[0], NULL, 0);
+ temp->value.intv = strtol(value[1], NULL, 0);
+ break;
+ case MIME_MAGIC_LOCALE :
+ if (length[0] > (sizeof(temp->value.localev) - 1))
+ return (-1);
+
+ strcpy(temp->value.localev, value[0]);
+ break;
+ case MIME_MAGIC_CONTAINS :
+ temp->offset = strtol(value[0], NULL, 0);
+ temp->region = strtol(value[1], NULL, 0);
+ if (length[2] > sizeof(temp->value.stringv))
+ return (-1);
+ temp->length = length[2];
+ memcpy(temp->value.stringv, value[2], length[2]);
+ break;
+ }
+ }
+ else
+ break;
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'mimeFileType()' - Determine the type of a file.
+ */
+
+mime_type_t * /* O - Type of file */
+mimeFileType(mime_t *mime, /* I - MIME database */
+ const char *pathname) /* I - Name of file to check */
+{
+ int i; /* Looping var */
+ FILE *fp; /* File pointer */
+ mime_type_t **types; /* File types */
+ const char *filename; /* Base filename of file */
+
+
+ /*
+ * Range check input parameters...
+ */
+
+ if (mime == NULL || pathname == NULL)
+ return (NULL);
+
+ /*
+ * Try to open the file...
+ */
+
+ if ((fp = fopen(pathname, "r")) == NULL)
+ return (NULL);
+
+ /*
+ * Figure out the filename (without directory portion)...
+ */
+
+ if ((filename = strrchr(pathname, '/')) != NULL)
+ filename ++;
+ else
+ filename = pathname;
+
+ /*
+ * Then check it against all known types...
+ */
+
+ for (i = mime->num_types, types = mime->types; i > 0; i --, types ++)
+ if (checkrules(filename, fp, (*types)->rules))
+ break;
+
+ /*
+ * Finally, close the file and return a match (if any)...
+ */
+
+ fclose(fp);
+
+ if (i > 0)
+ return (*types);
+ else
+ return (NULL);
+}
+
+
+/*
+ * 'mimeType()' - Lookup a file type.
+ */
+
+mime_type_t * /* O - Matching file type definition */
+mimeType(mime_t *mime, /* I - MIME database */
+ const char *super, /* I - Super-type name */
+ const char *type) /* I - Type name */
+{
+ mime_type_t key, /* MIME type search key*/
+ *keyptr, /* Key pointer... */
+ **match; /* Matching pointer */
+
+ /*
+ * Range check input...
+ */
+
+ if (mime == NULL || super == NULL || type == NULL)
+ return (NULL);
+
+ if (strlen(super) > (MIME_MAX_SUPER - 1) ||
+ strlen(type) > (MIME_MAX_TYPE - 1))
+ return (NULL);
+
+ if (mime->num_types == 0)
+ return (NULL);
+
+ /*
+ * Lookup the type in the array...
+ */
+
+ strlcpy(key.super, super, sizeof(key.super));
+ key.type = (char *)type;
+
+ keyptr = &key;
+
+ match = (mime_type_t **)bsearch(&keyptr, mime->types, mime->num_types,
+ sizeof(mime_type_t *),
+ (int (*)(const void *, const void *))compare);
+
+ if (match == NULL)
+ return (NULL);
+ else
+ return (*match);
+}
+
+
+/*
+ * 'compare()' - Compare two MIME super/type names.
+ */
+
+static int /* O - Result of comparison */
+compare(mime_type_t **t0, /* I - First type */
+ mime_type_t **t1) /* I - Second type */
+{
+ int i; /* Result of comparison */
+
+
+ if ((i = strcasecmp((*t0)->super, (*t1)->super)) == 0)
+ i = strcasecmp((*t0)->type, (*t1)->type);
+
+ return (i);
+}
+
+
+/*
+ * 'checkrules()' - Check each rule in a list.
+ */
+
+static int /* O - 1 if match, 0 if no match */
+checkrules(const char *filename, /* I - Filename */
+ FILE *fp, /* I - File to check */
+ mime_magic_t *rules) /* I - Rules to check */
+{
+ int n; /* Looping var */
+ int region; /* Region to look at */
+ int logic, /* Logic to apply */
+ result, /* Result of test */
+ intv; /* Integer value */
+ short shortv; /* Short value */
+ unsigned char buffer[MIME_MAX_BUFFER],/* Input buffer */
+ *bufptr; /* Current buffer position */
+ int bufoffset, /* Offset in file for buffer */
+ buflength; /* Length of data in buffer */
+
+
+ if (rules == NULL)
+ return (0);
+
+ if (rules->parent == NULL)
+ logic = MIME_MAGIC_OR;
+ else
+ logic = rules->parent->op;
+
+ bufoffset = -1;
+ buflength = 0;
+ result = 0;
+
+ while (rules != NULL)
+ {
+ /*
+ * Compute the result of this rule...
+ */
+
+ switch (rules->op)
+ {
+ case MIME_MAGIC_MATCH :
+ result = patmatch(filename, rules->value.matchv);
+ break;
+
+ case MIME_MAGIC_ASCII :
+ /*
+ * Load the buffer if necessary...
+ */
+
+ if (bufoffset < 0 || rules->offset < bufoffset ||
+ (rules->offset + rules->length) > (bufoffset + buflength))
+ {
+ /*
+ * Reload file buffer...
+ */
+
+ fseek(fp, rules->offset, SEEK_SET);
+ buflength = fread(buffer, 1, sizeof(buffer), fp);
+ bufoffset = rules->offset;
+ }
+
+ /*
+ * Test for ASCII printable characters plus standard control chars.
+ */
+
+ if ((rules->offset + rules->length) > (bufoffset + buflength))
+ n = bufoffset + buflength - rules->offset;
+ else
+ n = rules->length;
+
+ bufptr = buffer + rules->offset - bufoffset;
+ while (n > 0)
+ if ((*bufptr >= 32 && *bufptr <= 126) ||
+ (*bufptr >= 8 && *bufptr <= 13) ||
+ *bufptr == 26 || *bufptr == 27)
+ {
+ n --;
+ bufptr ++;
+ }
+ else
+ break;
+
+ result = (n == 0);
+ break;
+
+ case MIME_MAGIC_PRINTABLE :
+ /*
+ * Load the buffer if necessary...
+ */
+
+ if (bufoffset < 0 || rules->offset < bufoffset ||
+ (rules->offset + rules->length) > (bufoffset + buflength))
+ {
+ /*
+ * Reload file buffer...
+ */
+
+ fseek(fp, rules->offset, SEEK_SET);
+ buflength = fread(buffer, 1, sizeof(buffer), fp);
+ bufoffset = rules->offset;
+ }
+
+ /*
+ * Test for 8-bit printable characters plus standard control chars.
+ */
+
+ if ((rules->offset + rules->length) > (bufoffset + buflength))
+ n = bufoffset + buflength - rules->offset;
+ else
+ n = rules->length;
+
+ bufptr = buffer + rules->offset - bufoffset;
+
+ while (n > 0)
+ if (*bufptr >= 128 ||
+ (*bufptr >= 32 && *bufptr <= 126) ||
+ (*bufptr >= 8 && *bufptr <= 13) ||
+ *bufptr == 26 || *bufptr == 27)
+ {
+ n --;
+ bufptr ++;
+ }
+ else
+ break;
+
+ result = (n == 0);
+ break;
+
+ case MIME_MAGIC_STRING :
+ /*
+ * Load the buffer if necessary...
+ */
+
+ if (bufoffset < 0 || rules->offset < bufoffset ||
+ (rules->offset + rules->length) > (bufoffset + buflength))
+ {
+ /*
+ * Reload file buffer...
+ */
+
+ fseek(fp, rules->offset, SEEK_SET);
+ buflength = fread(buffer, 1, sizeof(buffer), fp);
+ bufoffset = rules->offset;
+ }
+
+ /*
+ * Compare the buffer against the string. If the file is too
+ * short then don't compare - it can't match...
+ */
+
+ if ((rules->offset + rules->length) > (bufoffset + buflength))
+ result = 0;
+ else
+ result = (memcmp(buffer + rules->offset - bufoffset,
+ rules->value.stringv, rules->length) == 0);
+ break;
+
+ case MIME_MAGIC_CHAR :
+ /*
+ * Load the buffer if necessary...
+ */
+
+ if (bufoffset < 0 || rules->offset < bufoffset)
+ {
+ /*
+ * Reload file buffer...
+ */
+
+ fseek(fp, rules->offset, SEEK_SET);
+ buflength = fread(buffer, 1, sizeof(buffer), fp);
+ bufoffset = rules->offset;
+ }
+
+ /*
+ * Compare the character values; if the file is too short, it
+ * can't match...
+ */
+
+ if (buflength < 1)
+ result = 0;
+ else
+ result = (buffer[rules->offset - bufoffset] == rules->value.charv);
+ break;
+
+ case MIME_MAGIC_SHORT :
+ /*
+ * Load the buffer if necessary...
+ */
+
+ if (bufoffset < 0 || rules->offset < bufoffset ||
+ (rules->offset + 2) > (bufoffset + buflength))
+ {
+ /*
+ * Reload file buffer...
+ */
+
+ fseek(fp, rules->offset, SEEK_SET);
+ buflength = fread(buffer, 1, sizeof(buffer), fp);
+ bufoffset = rules->offset;
+ }
+
+ /*
+ * Compare the short values; if the file is too short, it
+ * can't match...
+ */
+
+ if (buflength < 2)
+ result = 0;
+ else
+ {
+ bufptr = buffer + rules->offset - bufoffset;
+ shortv = (bufptr[0] << 8) | bufptr[1];
+ result = (shortv == rules->value.shortv);
+ }
+ break;
+
+ case MIME_MAGIC_INT :
+ /*
+ * Load the buffer if necessary...
+ */
+
+ if (bufoffset < 0 || rules->offset < bufoffset ||
+ (rules->offset + 4) > (bufoffset + buflength))
+ {
+ /*
+ * Reload file buffer...
+ */
+
+ fseek(fp, rules->offset, SEEK_SET);
+ buflength = fread(buffer, 1, sizeof(buffer), fp);
+ bufoffset = rules->offset;
+ }
+
+ /*
+ * Compare the int values; if the file is too short, it
+ * can't match...
+ */
+
+ if (buflength < 4)
+ result = 0;
+ else
+ {
+ bufptr = buffer + rules->offset - bufoffset;
+ intv = (((((bufptr[0] << 8) | bufptr[1]) << 8) | bufptr[2]) << 8) |
+ bufptr[3];;
+ result = (intv == rules->value.intv);
+ }
+ break;
+
+ case MIME_MAGIC_LOCALE :
+#ifdef __APPLE__
+ result = (strcmp(rules->value.localev, setlocale(LC_ALL, NULL)) == 0);
+#else
+ result = (strcmp(rules->value.localev, setlocale(LC_MESSAGES, NULL)) == 0);
+#endif /* __APPLE__ */
+ break;
+
+ case MIME_MAGIC_CONTAINS :
+ /*
+ * Load the buffer if necessary...
+ */
+
+ if (bufoffset < 0 || rules->offset < bufoffset ||
+ (rules->offset + rules->region) > (bufoffset + buflength))
+ {
+ /*
+ * Reload file buffer...
+ */
+
+ fseek(fp, rules->offset, SEEK_SET);
+ buflength = fread(buffer, 1, sizeof(buffer), fp);
+ bufoffset = rules->offset;
+ }
+
+ /*
+ * Compare the buffer against the string. If the file is too
+ * short then don't compare - it can't match...
+ */
+
+ if ((rules->offset + rules->length) > (bufoffset + buflength))
+ result = 0;
+ else
+ {
+ if (buflength > rules->region)
+ region = rules->region - rules->length;
+ else
+ region = buflength - rules->length;
+
+ for (n = 0; n < region; n ++)
+ if ((result = (memcmp(buffer + rules->offset - bufoffset + n,
+ rules->value.stringv, rules->length) == 0)) != 0)
+ break;
+ }
+ break;
+
+ default :
+ if (rules->child != NULL)
+ result = checkrules(filename, fp, rules->child);
+ else
+ result = 0;
+ break;
+ }
+
+ /*
+ * If the logic is inverted, invert the result...
+ */
+
+ if (rules->invert)
+ result = !result;
+
+ /*
+ * OK, now if the current logic is OR and this result is true, the this
+ * rule set is true. If the current logic is AND and this result is false,
+ * the the rule set is false...
+ */
+
+ DEBUG_printf(("result of test %p is %d\n", rules, result));
+
+ if ((result && logic == MIME_MAGIC_OR) ||
+ (!result && logic == MIME_MAGIC_AND))
+ return (result);
+
+ /*
+ * Otherwise the jury is still out on this one, so move to the next rule.
+ */
+
+ rules = rules->next;
+ }
+
+ return (result);
+}
+
+
+/*
+ * 'patmatch()' - Pattern matching...
+ */
+
+static int /* O - 1 if match, 0 if no match */
+patmatch(const char *s, /* I - String to match against */
+ const char *pat) /* I - Pattern to match against */
+{
+ /*
+ * Range check the input...
+ */
+
+ if (s == NULL || pat == NULL)
+ return (0);
+
+ /*
+ * Loop through the pattern and match strings, and stop if we come to a
+ * point where the strings don't match or we find a complete match.
+ */
+
+ while (*s != '\0' && *pat != '\0')
+ {
+ if (*pat == '*')
+ {
+ /*
+ * Wildcard - 0 or more characters...
+ */
+
+ pat ++;
+ if (*pat == '\0')
+ return (1); /* Last pattern char is *, so everything matches now... */
+
+ /*
+ * Test all remaining combinations until we get to the end of the string.
+ */
+
+ while (*s != '\0')
+ {
+ if (patmatch(s, pat))
+ return (1);
+
+ s ++;
+ }
+ }
+ else if (*pat == '?')
+ {
+ /*
+ * Wildcard - 1 character...
+ */
+
+ pat ++;
+ s ++;
+ continue;
+ }
+ else if (*pat == '[')
+ {
+ /*
+ * Match a character from the input set [chars]...
+ */
+
+ pat ++;
+ while (*pat != ']' && *pat != '\0')
+ if (*s == *pat)
+ break;
+ else
+ pat ++;
+
+ if (*pat == ']' || *pat == '\0')
+ return (0);
+
+ while (*pat != ']' && *pat != '\0')
+ pat ++;
+
+ if (*pat == ']')
+ pat ++;
+
+ continue;
+ }
+ else if (*pat == '\\')
+ {
+ /*
+ * Handle quoted characters...
+ */
+
+ pat ++;
+ }
+
+ /*
+ * Stop if the pattern and string don't match...
+ */
+
+ if (*pat++ != *s++)
+ return (0);
+ }
+
+ /*
+ * Done parsing the pattern and string; return 1 if the last character matches
+ * and 0 otherwise...
+ */
+
+ return (*s == *pat);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/standards/draft-ietf-ipp-collection-04.txt b/standards/draft-ietf-ipp-collection-04.txt
new file mode 100644
index 000000000..1a5905eab
--- /dev/null
+++ b/standards/draft-ietf-ipp-collection-04.txt
@@ -0,0 +1,2262 @@
+
+
+
+
+
+
+INTERNET-DRAFT Roger deBry
+<draft-ietf-ipp-collection-04.txt> Utah Valley State College
+ T. Hastings
+ Xerox Corporation
+ R. Herriot
+ Xerox Corporation
+ K. Ocke
+ Xerox Corporation
+ P. Zehler
+ Xerox Corporation
+ January 24, 2001
+
+
+ Internet Printing Protocol (IPP):
+ The 'collection' attribute syntax
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+
+
+Status of this Memo:
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of [RFC2026]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress".
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed as
+ http://www.ietf.org/shadow.html.
+
+Abstract
+ This document specifies an OPTIONAL attribute syntax called
+ 'collection' for use with the Internet Printing Protocol/1.0
+ (IPP) [RFC2565, RFC2566], IPP/1.1 [RFC2911, RFC2910], and
+ subsequent versions. A 'collection' is a container holding one or
+ more named values, which are called "member" attributes. A
+ collection allows data to be grouped like a PostScript dictionary
+ or a Java Map. This document also specifies the conformance
+ requirements for a definition document that defines a collection
+ attribute. Finally, this document gives some illustrative
+ example collection attribute definitions that are not intended as
+ actual attribute specifications.
+
+
+deBry, et al. Expires: July 24, 2001 [page 1]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics [RFC2911]
+ Internet Printing Protocol/1.1: Encoding and Transport [RFC2910]
+ Internet Printing Protocol/1.1: Implementer's Guide [IPP-IIG]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ The "Design Goals for an Internet Printing Protocol" document takes a
+ broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. A few OPTIONAL operator operations have
+ been added to IPP/1.1.
+
+ The "Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol" document describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specification documents, and gives background and rationale
+ for the IETF working group's major decisions.
+
+ The "Internet Printing Protocol/1.1: Encoding and Transport" document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1 [RFC2616]. It defines the
+ encoding rules for a new Internet MIME media type called
+ "application/ipp". This document also defines the rules for
+ transporting over HTTP a message body whose Content-Type is
+ "application/ipp". This document defines a new scheme named 'ipp'
+ for identifying IPP printers and jobs.
+
+ The "Internet Printing Protocol/1.1: Implementer's Guide" document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.1 and some of
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+ The "Mapping between LPD and IPP Protocols" document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 2]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+Table of Contents
+
+
+
+ 1 Introduction....................................................5
+ 1.1 Problem Statement ............................................5
+ 1.2 Solution .....................................................5
+
+ 2 Terminology.....................................................6
+ 2.1 Conformance Terminology ......................................6
+ 2.2 Other terminology ............................................7
+
+ 3 Definition of a Collection Attribute............................7
+ 3.1 Information to Include .......................................7
+ 3.2 Nested Collections ..........................................11
+
+ 4 Collection Attributes as Attributes in Operations..............11
+ 4.1 General Rules ...............................................11
+ 4.2 Unsupported Values ..........................................11
+
+ 5 Example definition of a collection attribute...................12
+ 5.1 media-col (collection) ......................................12
+ 5.1.1media-color (type3 keyword | name(MAX) ......................13
+ 5.1.2media-size (collection) .....................................13
+ 5.2 media-col-default (collection) ..............................14
+ 5.3 media-col-ready (1setOf collection) .........................14
+ 5.4 media-col-supported (1setOf type2 keyword) ..................14
+
+ 6 A Second Example Definition Of A Collection Attribute..........15
+
+ 7 Encoding.......................................................15
+ 7.1 Additional tags defined for representing a collection attribute
+ value16
+ 7.2 Example encoding: "media-col" (collection) ..................17
+
+ 8 Legacy issues..................................................23
+
+ 9 IANA Considerations............................................23
+ 9.1 Attribute Syntax Registration ...............................23
+
+ 10 Internationalization Considerations............................23
+
+ 11 Security Considerations........................................24
+
+ 12 References.....................................................24
+
+ 13 Author's Addresses.............................................25
+
+ 14 Appendix A: Encoding Example of a Simple Collection............26
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 3]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ 15 Appendix B: Encoding Example of 1setOf Collection..............29
+
+ 16 Appendix C: Encoding Example of Collection containing 1setOf XXX
+ attribute.........................................................34
+
+ 17 Appendix D: Full Copyright Statement...........................38
+
+
+Table of Tables
+
+ Table 1 - "media-col" member attributes...........................13
+ Table 2 - "media-size" collection member attributes...............13
+ Table 3 - Tags defined for encoding the 'collection' attribute syntax
+ ..............................................................16
+ Table 4 - Overview Encoding of "media-col" collection.............18
+ Table 5 - Example Encoding of "media-col" collection..............18
+ Table 6 - Overview Encoding of simple collection..................26
+ Table 7 - Example Encoding of simple collection...................26
+ Table 8 - Overview Encoding of 1setOf collection..................29
+ Table 9 - Example Encoding of 1setOf collection...................30
+ Table 10 - Overview Encoding of collection with 1setOf value......34
+ Table 11 - Example Encoding of collection with 1setOf value.......35
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 4]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+
+
+1 Introduction
+
+
+1.1 Problem Statement
+
+ The IPP Model and Semantics [RFC2911] supports most of the common
+ data structures that are available in programming languages. It lacks
+ a mechanism for grouping several attributes of different types. The
+ Java language uses the Map to solve this problem and PostScript has a
+ dictionary. The new mechanism for grouping attributes together
+ (called 'collection' mechanism) must allow for optional members and
+ subsequent addition of new members.
+
+ The 'collection' mechanism must be encoded in a manner consistent
+ with existing 1.0 and 1.1 parsing rules (see [RFC2910]). Current 1.0
+ and 1.1 parsers that don't support the 'collection' mechanism must
+ not confuse collections or parts of collection they receive with
+ other attributes.
+
+
+1.2 Solution
+
+ The new mechanism is a new IPP attribute syntax called a
+ 'collection'. As such, each collection value is a value of an
+ attribute whose attribute syntax type is defined to be a
+ 'collection'. Such an attribute is called a collection attribute.
+ The name of the collection attribute serves to identify the
+ collection value in an operation request or response, as with any
+ attribute value.
+
+ The 'collection' attribute syntax is a container holding one or more
+ named values (i.e., attributes), which are called member attributes.
+ Each collection attribute definition document lists the mandatory and
+ optional member attributes of each collection value. A collection
+ value is similar to an IPP attribute group in a request or a
+ response, such as the operation attributes group. They both consist
+ of a set of attributes.
+
+ As with any attribute syntax, the document that defines a collection
+ attribute specifies whether the attribute is single-value
+ (collection) or multi-valued (1setOf collection). If the attribute is
+ multi-valued (1setOf collection) each collection value MUST be a
+ separate instance of a single definition of a collection, i.e. it
+ MUST have the same member attributes except for OPTIONAL member
+ attributes. If we view each collection definition as a separate
+ syntax type, this rule continues the IPP/1.1 notion that each
+
+
+deBry, et al. Expires: July 24, 2001 [page 5]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ attribute has a single type or pattern (e.g. "keyword | name" is a
+ pattern). Without this rule, the supported values would be more
+ difficult to describe and the mechanism defined in item 4 of section
+ 3.1 would not be sufficient.
+
+ The name of each member attribute MUST be unique for a collection
+ attribute, but MAY be the same as the name of a member attribute in
+ another collection attribute and/or MAY be the same as the name of an
+ attribute that is not a member of a collection. The rules for naming
+ member attributes are given in section 3.1.
+
+ Each member attribute can have any attribute syntax type, including
+ 'collection', and can be either single-valued or multi-valued. The
+ length of a collection value is not limited. However, the length of
+ each member attribute MUST NOT exceed the limit of its attribute
+ syntax.
+
+ The member attributes in a collection MAY be in any order in a
+ request or response. When a client sends a collection attribute to
+ the Printer, the order that the Printer stores the member attributes
+ of the collection value and the order returned in a response MAY be
+ different from the order sent by the client.
+
+ A collection value MUST NOT contains two or more member attributes
+ with the same attribute name. Such a collection is mal-formed.
+ Clients MUST NOT submit such malformed requests and Printers MUST NOT
+ return such malformed responses. If such a malformed request is
+ submitted to a Printer, the Printer MUST (depending on
+ implementation) either (1) reject the request with the 'client-error-
+ bad-request' status code (see section 13.1.4.1), or (2) accept the
+ request and use only one of each duplicate member attribute.
+
+
+
+2 Terminology
+
+ This section defines terminology used throughout this document.
+
+
+2.1 Conformance Terminology
+
+ Capitalized terms, such as MUST, MUST NOT, REQUIRED, SHOULD, SHOULD
+ NOT, MAY, NEED NOT, and OPTIONAL, have special meaning relating to
+ conformance. These terms are defined in [RFC2911] section 12.1 on
+ conformance terminology, most of which is taken from RFC 2119
+ [RFC2119].
+
+ The following specialization of these terms apply to this document:
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 6]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ REQUIRED: if an implementation supports the extensions described in
+ this document, it MUST support a REQUIRED feature.
+
+ OPTIONAL: if an implementation supports the extensions described in
+ this document, it MAY support an OPTIONAL feature.
+
+
+2.2 Other terminology
+
+ This document uses terms such as Job object (or Job), IPP Printer
+ object (or Printer), "operation", "request", response", "attributes",
+ "keywords", and "support". These terms have special meaning and are
+ defined in the model terminology [RFC2911] section 12.2. The
+ following additional terms are introduced in this document:
+
+ collection: an attribute syntax in which each attribute value is a
+ set of attributes, called member attributes.
+
+ member attribute: an attribute that is defined to be used as one
+ of the attributes in a collection.
+
+ collection attribute: an attribute whose definition specifies the
+ 'collection' attribute syntax and each of the member attributes
+ that MAY occur in a collection attribute value.
+
+
+
+3 Definition of a Collection Attribute
+
+ This section describes the requirements for any collection attribute
+ definition.
+
+
+3.1 Information to Include
+
+ When a specification document defines an "xxx" collection attribute,
+ i.e., an attribute whose attribute syntax type is 'collection' or
+ '1setOf collection'; the definition document MUST include the
+ following aspects of the attribute semantics. Suppose the "xxx"
+ collection attribute contains N member attributes named "aaa1",
+ "aaa2", _, "aaaN" ("aaaI" represents any one of these N member
+ attributes).
+
+ 1. The name of the collection attribute MUST be specified (e.g.
+ "xxx"). The selection of the name "xxx" MUST follow the same rules
+ for uniqueness as for attributes of any other syntax type (as
+ defined by IPP/1.1) unless "xxx" is a member attribute of another
+ collection. Then the selection of the name "xxx" MUST follow the
+ rules for uniqueness defined in item 5a) of this list.
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 7]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ 2. The collection attribute syntax MUST be of type 'collection' or
+ '1setOf collection'.
+
+ 3. The context of the collection attribute MUST be specified, i.e.,
+ whether the attribute is an operation attribute, a Job Template
+ attribute, a Job Description attribute, a Printer Description
+ attribute, a member attribute of a particular collection attribute,
+ etc.
+
+ 4. An "xxx-supported" attribute MUST be specified and it has one of
+ the following two forms:
+
+ a)"xxx-supported" is a "1setOf collection" which enumerates all of
+ the supported collection values of "xxx". If a collection of
+ this form contains a nested collection, it MUST be of the same
+ form.
+
+ For example, "media-size-supported" might have the values {{x-
+ dimension:210, y-dimension:297},{x-dimension:297, y-
+ dimension:420}} to show that it supports two values of "media
+ size": A4 (210x297) and A3 (297x420). It does not support other
+ combinations of "x-dimension" and "y-dimension" member
+ attributes, such as 210x420 or 297x297 and it does not supported
+ non-enumerated values, such as 420x595.
+
+ b)"xxx-supported" is a "1setOf type2 keyword" which enumerates
+ the names of all of the member attributes of "xxx": "aaa1",
+ "aaa2", _, "aaaN". If a collection of this form contains a
+ nested collection, it MAY be of either form. See item 5f) below
+ for details on supported values of member attributes.
+
+ For example, "media-col-supported" might have the keyword
+ values: "media-size" and "media-color".
+
+ 5. The member attributes MUST be defined. For each member attribute
+ the definition document MUST provide the following information:
+
+
+ a)The member attribute's name (e.g., "aaa") MUST be unique within
+ the collection being defined and MUST either
+
+
+ i) reuse the attribute name of another attribute (that is unique
+ across the entire IPP attribute name space) and have the same
+ syntax and semantics as the reused attribute (if the condition
+ of item 4b) above is met). For example, a member attribute
+ definition could reuse the IPP/1.1 "media" attribute.
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 8]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ ii) potentially occur elsewhere in the entire IPP attribute
+ name space. (if the condition of item 4a) above is met). For
+ example, a member attribute could be "x-dimension" which could
+ potentially occur in another collection or as an attribute
+ outside of a collection.
+
+
+ iii) be unique across the entire IPP attribute name space (if
+ the condition of item 4b) above is met). For example, a member
+ attribute could be "media-color" which must unique be across
+ the entire IPP attribute name space.
+
+
+ b)Whether the member attribute is REQUIRED or OPTIONAL for the
+ Printer to support
+
+
+ c)Whether the member attribute is REQUIRED or OPTIONAL for the
+ client to supply in a request
+
+
+ d)The member attribute's syntax type, which can be any attribute
+ syntax, including '1setOf X', 'collection', and '1setOf
+ collection'. If this attribute name reuses the name of another
+ attribute (case of item a1 above), it MUST have the same
+ attribute syntax, including cardinality (whether or not 1setOf).
+
+
+ e)The semantics of the "aaa" member attribute. The semantic
+ definition MUST include a description of any constraint or
+ boundary conditions the member attribute places on the
+ associated attribute, especially if the attribute reuses the
+ name of another attribute (case of item a1 above)
+
+ f)The supported values for the each "aaaI" member attribute (of
+ the member attributes "aaa1", "aaa2", _, "aaaN") is specified
+ by one of two mechanisms.
+
+ i) If "xxx-supported" is a "1setOf collection" (see item 4a)
+ above), the value for each "aaaI" is specified in each
+ collection value of "xxx-supported" in the context of other
+ member attributes. That is, "xxx-supported" enumerates all
+ supported values of "xxx".
+
+
+ ii) If the value of "xxx-supported" is a "1setOf type2
+ keyword" (see item 4b) above), the supported values of "aaaI"
+ are the values specified by either i) the "aaaI-supported"
+ attribute or ii) the definition of the member attribute "aaaI"
+ within the document defining the "xxx" attribute. The values
+
+
+deBry, et al. Expires: July 24, 2001 [page 9]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ of each member attribute "aaaI" are specified independently of
+ other member attributes though a Printer is not required to
+ support all combinations of supported values.
+
+ For example, "media-col-supported" might have the keyword
+ values: "media-size" and "media-color". Using the first method
+ for defining supported values (an "aaaI-supported" attribute),
+ the collection values of "media-col" are combinations of
+ values of "media-size-supported" and "media-color-
+ supported".If "media-size-supported" has the values of
+ '210x297' and '297x420' and "media-color-supported" has the
+ values of 'white' and 'pink', the Printer might support only
+ the combinations 'white-210x297', 'pink-210x297'and 'white-
+ 297x420', and not 'pink-297x420'.
+
+ If a collection contains a member "aaaI" whose syntax type is
+ "text", the supported values would probably be defined by the
+ definition of "xxx" rather than by the attribute "aaaI-
+ supported".
+
+ g)the default value of each "aaaI" member attribute if it is
+ OPTIONAL for a client to supply the "aaa" member attribute in a
+ request. The default value is specified by in the attribute's
+ definition within a document and MUST be one of the following:
+
+ i) a fixed default
+
+ ii) a mechanism by which the Printer determines default
+
+ iii) an indefinite default that is left to the implementation.
+
+ iv) an attribute that the Printer uses to determine the default
+
+ 6. The default value of "xxx" if a client does not supply it. The
+ default value is specified by in the attribute's definition within
+ a document and MUST be one of the following:
+
+
+ a)a fixed default
+
+
+ b)a mechanism by which the Printer determines default
+
+
+ c)an indefinite default that is left to the implementation
+
+ d)a Printer attribute "xxx-default" which is a collection with the
+ same member attributes as "xxx". Though optional member
+ attributes may be absent in which case the Printer uses the
+ defaulting rules of item 5g) above.
+
+
+deBry, et al. Expires: July 24, 2001 [page 10]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ 7. The "xxx-ready (1setOf collection)" attribute if human intervention
+ is required to make many of the supported values available. For
+ example, "media-col" is an attribute which has a "ready" attribute.
+ Most attributes do not have a "ready" attribute.
+
+
+3.2 Nested Collections
+
+ A member attribute may have a syntax type of 'collection' or '1setOf
+ collection', in which case it is called a nested collection
+ attribute. The rules for a nested collection attribute are the same
+ as for a collection attribute as specified in section 3.1.
+
+
+
+4 Collection Attributes as Attributes in Operations
+
+
+4.1 General Rules
+
+ A collection value is like any other IPP/1.1 value, except that it is
+ structured. The rules for attributes with collection values are the
+ same as for attributes of any other syntax type (see IPP/1.1), be
+ they in any group of a request of a response.
+
+
+4.2 Unsupported Values
+
+ The rules for returning an unsupported collection attribute are an
+ extension to the current rules:
+
+ 1. If the entire collection attribute is unsupported, then the
+ Printer returns just the collection attribute name with the
+ 'unsupported' out-of-band value (see the beginning of [RFC2911]
+ section 4.1) in the Unsupported Attributes Group.
+
+ 2. If a collection contains unrecognized, unsupported member
+ attributes and/or conflicting values, the attribute returned in
+ the Unsupported Group is a collection containing the
+ unrecognized, unsupported member attributes, and/or conflicting
+ values. The unrecognized member attributes have an out-of-band
+ value of 'unsupported' (see the beginning of [RFC2911] section
+ 4.1). The unsupported member attributes and conflicting values
+ have their unsupported or conflicting values.
+
+
+
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 11]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+5 Example definition of a collection attribute
+
+ In some printing environments, it is desirable to allow the client to
+ select the media by its properties, e.g., weight, color, size, etc.,
+ instead of by name. In IPP/1.1 (see [RFC2911]), the "media (type3
+ keyword | name) Job Template attribute allows selection by name. It
+ is tempting to extend the "media" attribute syntax to include
+ "collection", but then existing clients could not understand default
+ or supported media values that use the collection value. To preserve
+ interoperability, a new attribute MUST BE added, e.g., "media-col
+ (collection)". The following subsections contain a sample definition
+ of a simplified "media-col" attribute. The definition follows the
+ rules in section 3.
+
+ All of the example attribute definitions in this document are
+ illustrative examples, rather than actual definitions. These
+ examples are intended to illustrate how to define collection
+ attributes. Other documents MUST define collection attributes for
+ use in actual interchange. Such definitions may be very similar to
+ the examples in this document, since we attempted to pick useful
+ examples.
+
+ Note: we picked the name "media-col" because the name "media" is
+ already in use. Ordinarily the collection attribute would have a name
+ like any other attribute and would not end in "col".
+
+ The member attributes of "media-col" attribute ("media-color (type 3
+ keyword)" and "media-size (collection)") both follow the naming rules
+ of item 4a3 of section 3, i.e. the names are unique across the entire
+ IPP attribute name space. The member attributes of the "media-size
+ (collection)" member attribute ("x-dimension (integer(0,MAX))" and
+ "y-dimension (integer(0,MAX))") both follow the naming rules of item
+ 4a2 of section 3, i.e. they potentially occur elsewhere in the IPP
+ attribute name space.
+
+
+5.1 media-col (collection)
+
+ The "media-col" (collection) attribute augments the IPP/1.1 [RFC2911]
+ "media" attribute. This collection attribute enables a client end
+ user to submit a list of media characteristics to the Printer. When
+ the client specifies media using the "media-col" collection
+ attribute, the Printer object MUST match the requested media exactly.
+ The 'collection' consists of the following member attributes:
+
+
+
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 12]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ Table 1 - "media-col" member attributes
+
+
+
+ Attribute name attribute syntax reque Printer
+ st Support
+
+
+ media-color type3 keyword | name (MAX) MAY MUST
+
+ media-size collection MUST MUST
+
+
+ The definitions for the member attributes is given in the following
+ sub-sections:
+
+
+ 5.1.1 media-color (type3 keyword | name(MAX)
+
+ This member attribute identifies the color of the media. Valid
+ values are 'red', 'white' and 'blue'
+
+ The "media-color-supported" (1setOf (type3 keyword | name(MAX)))
+ Printer attribute identifies the values of this "media-color"
+ member attribute that the Printer supports, i.e., the colors
+ supported.
+
+ If the client omits this member attribute, the Printer determines
+ the value in an implementation dependent manner.
+
+
+ 5.1.2 media-size (collection)
+
+ This member attribute identifies the size of the media. The
+ 'collection' consists of the member attributes shown in Table 2:
+
+
+ Table 2 - "media-size" collection member attributes
+
+
+
+ Attribute attribute syntax request Printer
+ name Support
+
+
+ x-dimension integer (0:MAX) MUST MUST
+
+ y-dimension integer (0:MAX) MUST MUST
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 13]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ The definitions for the member attributes is given in the
+ following sub-sections:
+
+
+ 5.1.2.1 x-dimension (integer(0:MAX))
+ This attribute identifies the width of the media in inch units
+ along the X axis.
+
+
+ 5.1.2.2 y-dimension (integer(0:MAX))
+ This attribute identifies the height of the media in inch
+ units along the Y axis.
+
+ The "media-size-supported" (1setOf collection) Printer
+ attribute identifies the values of this "media-size" member
+ attribute that the Printer supports, i.e., the size
+ combinations supported. The names of the member attributes
+ are the same as the member attributes of the "media-size"
+ collection attribute, namely "x-dimension", and "y-dimension",
+ since they have the same attribute syntax and the same
+ semantics.
+
+
+5.2 media-col-default (collection)
+
+ The "media-col-default" Printer attribute specifies the media that
+ the Printer uses, if any, if the client omits the "media-col" and
+ "media". Job Template attribute in the Job Creation operation (and
+ the PDL doesn't include a media specification). The member
+ attributes are defined in Table 1. A Printer MUST support the same
+ member attributes for this default collection attribute as it
+ supports for the corresponding "media-col" Job Template attribute.
+
+
+5.3 media-col-ready (1setOf collection)
+
+ The "media-col-ready" Printer attribute identifies the media that are
+ available for use without human intervention, i.e., the media that
+ are ready to be used without human intervention. The collection
+ value MUST have all of the member attributes that are supported in
+ Table 1.
+
+
+5.4 media-col-supported (1setOf type2 keyword)
+
+ The "media-col-supported" Printer attribute identifies the keyword
+ names of the member attributes supported in the "media-col"
+ collection Job Template attribute, i.e., the keyword names of the
+ member attributes in Table 1 that the Printer supports.
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 14]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+6 A Second Example Definition Of A Collection Attribute
+
+ All of the example attribute definitions in this document are
+ illustrative examples, rather than actual definitions. These
+ examples are intended to illustrate how to define collection
+ attributes. Other documents MUST define collection attributes for
+ use in actual interchange. Such definitions may be very similar to
+ the examples in this document, since we attempted to pick useful
+ examples.
+
+ In some printing environments, it is desirable to allow the client to
+ select the media for the job start sheet. The reason for not adding
+ the 'collection' attribute syntax to the existing "job-sheets" Job
+ Template attribute is the same as for "media". Instead, a new Job
+ Template attribute is introduced, e.g. "job-sheet-col (collection)".
+
+ The member attributes of "job-sheet-col" attribute ("job-sheets
+ (type 3 keyword)" and "media (type3 keyword | name)") both follow
+ the naming rules of item 4a1 of section 3, i.e they reuse existing
+ IPP attributes. According to the rules, their supported values come
+ from the existing IPP attributes: "job-sheets-supported" and "media-
+ supported". However, their default values do not come from "job-
+ sheets-default" and "media-default", respectively. Rather the
+ definition of "job-sheet-col" says that "job-sheets (type 3 keyword)"
+ is required and if "media (type3 keyword | name)" is absent, the
+ Printer uses the same media as the rest of the job uses.
+
+ If "job-sheet-col" attribute were defined to contain the member
+ attribute "job-sheet-media (type3 keyword | name)" instead of "media
+ (type3 keyword | name)", then the definition would also have to
+ specify a "job-sheet-media-supported (1setOf (type3 keyword |
+ name))" whose values would be independent of "media-supported
+ (1setOf (type3 keyword | name))" and would be set separately by a
+ System Administrator.
+
+ The actual text for the definition of the attribute is left as an
+ exercise for the reader.
+
+
+
+7 Encoding
+
+ This section defines the additional encoding tags used according to
+ [RFC2910] and gives an example of their use. The encoding tags
+ define in this document MUST be used by all collection attributes
+ defined in other documents. However, the example of their use is
+ illustrative only.
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 15]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+7.1 Additional tags defined for representing a collection attribute
+ value
+
+ The 'collection' attribute syntax uses the tags defined in Table 3.
+
+
+ Table 3 - Tags defined for encoding the 'collection' attribute syntax
+
+
+
+ Tag name Tag Meaning
+ value
+
+
+ begCollection 0x34 Begin the collection attribute value.
+
+ endCollection 0x37 End the collection attribute value.
+
+ memberAttrName 0x4A The value is the name of the
+ collection member attribute
+
+
+ When encoding a collection attribute "xxx" that contains an attribute
+ "aaa" and is not inside another collection, the encoding follows
+ these rules:
+
+ 1. The beginning of the collection is indicated with a value tag
+ that MUST be syntax type 'begCollection' (0x34) with a name
+ length and Name field that represent the name of the collection
+ attribute ("xxx") as with any attribute, followed by a value. The
+ Printer MAY ignore the value and its length of MAY be 0. In the
+ future, however, this field MAY contain useful information, such
+ as the collection name (cf. the name of a C struct).
+
+ 2. Each member attribute is encoded as a sequence of two or more
+ values that appear to be part of a single multi-valued attribute,
+ i.e. 1setOf. The first value after the 'begCollection' value has
+ the attribute syntax 'memberAttrName' (0x4A) and its value holds
+ the name of the first member attribute (e.g. "aaa"). The second
+ value holds the first member's attribute value, which can be of
+ any attribute syntax, except 'memberAttrName' or 'endCollection'.
+ If the first member's attribute value is multi-valued, the third
+ value holds the second value of the first member's value.
+ Otherwise, the third value holds the name of second member
+ attribute (e.g. "bbb") and its attribute syntax is
+ 'memberAttrName'. In this case, the fourth member's value is the
+ value of "bbb".
+
+ Note that the technique of encoding a 'collection' as a '1setOf'
+ makes it easy for a Printer that doesn't support a particular
+
+
+deBry, et al. Expires: July 24, 2001 [page 16]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ collection attribute (or the collection attribute syntax at all)
+ to simply skip over the entire collection value.
+
+ 3. The end of the collection is indicated with a value tag that MUST
+ be syntax type 'endCollection' (e.g. 0x37) and MAY have a zero
+ name length and a zero value length. In the future, this field
+ MAY contain useful information,such as the collection name that
+ matches the one in the 'begCollection' .
+
+ 4. It is valid to have a member attribute that is, itself, a
+ collection attribute, i.e., collections can be nested within
+ collections. This is represented by the occurrence of a member
+ attribute that is of attribute syntax type 'begCollection'. Such
+ a collection is terminated by a matching 'endCollection'. The
+ name of such a member attribute is in the immediately preceding
+ value whose syntax type is 'memberAttrName'.
+
+ 5. It is valid for a collection attribute to be multi-valued, i.e.,
+ have more than one collection value. If the next attribute
+ immediately following the 'endCollection' has a zero name length
+ and a tag of 'begCollection', then the collection attribute is a
+ multi-valued collection, as with any attribute. This statement
+ applies to collections within collections and collections that
+ are not in collections.
+
+
+7.2 Example encoding: "media-col" (collection)
+
+ The collection specified in section 5 is used for the encoding
+ example shown in Table 5. The example also shows nested collections,
+ since the "media-size" member attribute is a 'collection. The
+ encoding example represents a blue 4x6-index cards and takes 216
+ octets. The Appendices contains more complex examples.
+
+ Additional examples have been included in the appendices.
+
+ The overall structure of the two collection values can be pictorially
+ represented as:
+
+ "media-col" =
+ { "media-color" = 'blue';
+ "media-size" =
+ { "x-dimension" = 6;
+ "y-dimension" = 4
+ }
+ },
+
+ The full encoding is in table 4. A simplified view of the encoding
+ looks like this:
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 17]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ Table 4 - Overview Encoding of "media-col" collection
+
+
+
+ Tag Value Name Value
+
+
+ begCollection media-col ""
+
+ memberAttrName "" media-color
+
+ keyword "" blue
+
+ memberAttrName "" media-size
+
+ begCollection "" ""
+
+ memberAttrName "" x-dimension
+
+ integer "" 6
+
+ memberAttrName "" y-dimension
+
+ integer "" 4
+
+ endCollection "" ""
+
+ endCollection "" ""
+
+
+
+
+
+
+ Table 5 - Example Encoding of "media-col" collection
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x34 begCollection value-tag beginning of the "media-
+ col" collection attribute
+
+ 0x0009 name- length of (collection)
+ length attribute name
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 18]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ media-col media-col name name of (collection)
+ attribute
+
+ 0x0000 value- defined to be 0 for this
+ length type
+
+ no value (since value-
+ length was 0)
+
+ 0x4A memberAttrName value-tag starts a new member
+ attribute: "media-color"
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x000B value- length of "media-color"
+ length keyword
+
+ media-color media-color value value is name of 1st
+ member attribute
+
+
+ 0x44 keyword type value-tag keyword type
+
+ 0x0000 name- 0 indicates 1setOf
+ length
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value-
+ length
+
+ blue blue value value of 1st member
+ attribute
+
+
+ 0x4A memberAttrName value-tag starts a new member
+ attribute: "media-size"
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 19]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x000A value- length of "media-size"
+ length keyword
+
+ media-size media-size value Name of 2nd member
+ attribute
+
+
+ 0x34 begCollection value-tag Beginning of the "media-
+ size" collection attribute
+ which is a sub-collection
+
+ 0x0000 name- 0 indicates 1setOf
+ length
+
+ no name (since name-length
+ was 0)
+
+ 0x0000 value- collection attribute names
+ length have no value
+
+ no value (since value-
+ length was 0)
+
+ 0x4A memberAttrName value-tag starts a new member
+ attribute: "x-dimension"
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x000B value- length of "x-dimension"
+ length keyword
+
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 20]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ x-dimension x-dimension value name of 1st sub-
+ collection member
+ attribute
+
+
+ 0x21 integer type value-tag attribute type
+
+ 0x0000 name- 0 indicates 1setOf
+ length
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value- length of an integer = 4
+ length
+
+ 0x0006 value value of 1st sub-
+ collection member
+ attribute
+
+
+ 0x4A memberAttrName value-tag starts a new member
+ attribute: "y-dimension"
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x000B value- length of the "y-
+ length dimension" keyword
+
+ y-dimension y-dimension value name of 2nd sub-
+ collection member
+ attribute
+
+
+ 0x21 integer type value-tag attribute type
+
+ 0x0000 name- 0 indicates 1setOf
+ length
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 21]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value- length of an integer = 4
+ length
+
+ 0x0004 value value of 2nd sub-
+ collection member
+ attribute
+
+
+ 0x37 endCollection value-tag end of the sub-collection
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x0000 value- defined to be 0 for this
+ length type
+
+ no value (since value-
+ length was 0)
+
+ 0x37 endCollection value-tag end of the 1st collection
+ value in 1setOf
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x0000 value- defined to be 0 for this
+ length type
+
+ no value (since value-
+ length was 0)
+
+
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 22]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+8 Legacy issues
+
+ IPP 1.x Printers and Clients will gracefully ignore collections and
+ its member attributes if it does not understand the collection. The
+ begCollection and endCollection elements each look like an attribute
+ with an attribute syntax that the recipient doesn't support and so
+ should ignore the entire attribute. The individual member attributes
+ and their values will look like a 1setOf values of the collection
+ attribute, so that the Printer simply ignores the entire attribute
+ and all of its values. Returning unsupported attributes is also
+ simple, since only the name of the collection attribute is returned
+ with the 'unsupported' out-of-band value (see section 4.2).
+
+
+
+9 IANA Considerations
+
+ This section contains the exact information for IANA to add to the
+ IPP Registries according to the procedures defined in "IPP/1.1 Model
+ and Semantics" document [RFC2911] section 6.
+
+ Note to RFC Editors: Replace RFC NNNN below with the RFC number for
+ this document, so that it accurately reflects the content of the
+ information for the IANA Registry.
+
+
+9.1 Attribute Syntax Registration
+
+ The attribute syntax defined in this document will be published by
+ IANA according to the procedures in RFC 2911 [RFC2911] section 6.3
+ with the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-syntaxes/
+
+ The registry entry will contain the following information:
+
+ Reference:
+ RFC NNNN [this document]
+
+ Attribute Syntaxes: Ref. Section:
+ collection RFC NNNN 3
+
+
+
+
+10 Internationalization Considerations
+
+ This attribute syntax by itself has no impact on
+ internationalization. However, the member attributes that are
+ subsequently defined for use in a collection may have
+
+
+deBry, et al. Expires: July 24, 2001 [page 23]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ internationalization considerations, as may any attribute, according
+ to [RFC2911].
+
+
+
+11 Security Considerations
+
+ This attribute syntax causes no more security concerns than any other
+ attribute syntax. It is only the attributes that are subsequently
+ defined to use this or any other attribute syntax that may have
+ security concerns, depending on the semantics of the attribute,
+ according to [RFC2911].
+
+
+
+12 References
+
+ [ipp-ntfy]
+ Isaacson, S., Martin, J., deBry, R., Hastings, T., Shepherd, M.,
+ Bergman, R. " Internet Printing Protocol/1.0 & 1.1: IPP Event
+ Notification Specification" draft-ietf-ipp-not-spec-02.txt, work in
+ progress, February 2, 2000.
+
+ [RFC2565]
+ Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet Printing
+ Protocol/1.0: Encoding and Transport", RFC 2565, April 1999.
+
+ [RFC2566]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell,
+ "Internet Printing Protocol/1.0: Model and Semantics", RFC 2566,
+ April 1999.
+
+ [RFC2567]
+ Wright, D., "Design Goals for an Internet Printing Protocol", RFC
+ 2567, April 1999.
+
+ [RFC2568]
+ Zilles, S., "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", RFC 2568, April 1999.
+
+ [RFC2569]
+ Herriot, R., Hastings, T., Jacobs, N., Martin, J., "Mapping between
+ LPD and IPP Protocols", RFC 2569, April 1999.
+
+ [RFC2616]
+ R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P.
+ Leach, T. Berners-Lee, "Hypertext Transfer Protocol - HTTP/1.1",
+ RFC 2616, June 1999.
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 24]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ [RFC2910]
+ Herriot, R., Butler, S., Moore, P., Turner, R., "Internet Printing
+ Protocol/1.1: Encoding and Transport", draft-ietf-ipp-protocol-v11-
+ 05.txt, March 1, 2000.
+
+ [RFC2911]
+ Isaacson, S., deBry, R., Hastings, T., Herriot, R., Powell, P.,
+ "Internet Printing Protocol/1.1: Model and Semantics", RFC 2911,
+ September 2000.
+
+
+
+13 Author's Addresses
+
+ Roger deBry
+ Utah Valley State College
+ Orem, UT 84058
+ Phone: (801) 222-8000
+ EMail: debryro@uvsc.edu
+
+ Tom Hastings
+ Xerox Corporation
+ 737 Hawaii St. ESAE 231
+ El Segundo, CA 90245
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ e-mail: hastings@cp10.es.xerox.com
+
+ Robert Herriot
+ Xerox Corp.
+ 3400 Hill View Ave, Building 1
+ Palo Alto, CA 94304
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ e-mail: robert.herriot@pahv.xerox.com
+
+ Kirk Ocke
+ Xerox Corp.
+ 800 Phillips Rd
+ M/S 139-05A
+ Webster, NY 14580
+ Phone: (716) 442-4832
+ EMail: kirk.ocke@usa.xerox.com
+
+ Peter Zehler
+ Xerox Corp.
+ 800 Phillips Rd
+ M/S 139-05A
+ Webster, NY 14580
+ Phone: (716) 265-8755
+
+
+deBry, et al. Expires: July 24, 2001 [page 25]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ EMail: peter.zehler@usa.xerox.com
+
+
+14 Appendix A: Encoding Example of a Simple Collection
+
+ The overall structure of the collection value can be pictorially
+ represented as:
+
+ " media-size " =
+ { "x-dimension" = 6;
+ "y-dimension" = 4
+ }
+
+ A simplified view of the encoding would look like this:
+
+
+ Table 6 - Overview Encoding of simple collection
+
+
+
+ Tag Value Name Value
+
+
+ begCollection media-size ""
+
+ memberAttrName "" x-dimension
+
+ integer "" 6
+
+ memberAttrName "" y-dimension
+
+ integer "" 4
+
+ endCollection "" ""
+
+
+ Note: "" represents a name or value whose length is 0.
+
+
+ Table 7 - Example Encoding of simple collection
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x34 begCollection value-tag beginning of the "media-
+ size" collection attribute
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 26]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x000A name- length of (collection)
+ length attribute name
+
+ media-size media-size name name of (collection)
+ attribute
+
+ 0x0000 value- defined to be 0 for this
+ length type
+
+ no value (since value-
+ length was 0)
+
+ 0x4A memberAttrName value-tag starts member attribute:
+ "x-dimension"
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x000B value- length of "x-dimension"
+ length keyword
+
+ x-dimension x-dimension value name of 1st collection
+ member attribute
+
+
+ 0x21 integer type value-tag attribute type
+
+ 0x0000 name- 0 indicates 1setOf
+ length
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value- length of an integer = 4
+ length
+
+ 0x0006 value value of 1st collection
+ member attribute
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 27]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x4A memberAttrName value-tag starts a new member
+ attribute: "y-dimension"
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x000B value- length of the "y-
+ length dimension" keyword
+
+ y-dimension y-dimension value name of 2nd collection
+ member attribute
+
+
+ 0x21 integer type value-tag attribute type
+
+ 0x0000 name- 0 indicates 1setOf for
+ length media-size
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value- length of an integer = 4
+ length
+
+ 0x0004 value value of 2nd collection
+ member attribute
+
+
+ 0x37 endCollection value-tag end of the collection
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x0000 value- defined to be 0 for this
+ length type
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 28]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ no value (since value-
+ length was 0)
+
+
+
+
+
+15 Appendix B: Encoding Example of 1setOf Collection
+
+ The overall structure of the collection value can be pictorially
+ represented as:
+
+ "media-size-supported" =
+ { "x-dimension" = 6;
+ "y-dimension" = 4
+ },
+ { "x-dimension" = 3;
+ "y-dimension" = 5
+ };
+
+ A simplified view of the encoding would look like this:
+
+
+ Table 8 - Overview Encoding of 1setOf collection
+
+
+
+ Tag Value Name Value
+
+
+ begCollection media-size- ""
+ supported
+
+ memberAttrName "" x-dimension
+
+ integer "" 6
+
+ memberAttrName "" y-dimension
+
+ integer "" 4
+
+ endCollection "" ""
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 29]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+ begCollection "" ""
+
+ memberAttrName "" x-dimension
+
+ integer "" 3
+
+ memberAttrName "" y-dimension
+
+ integer "" 5
+
+ endCollection "" ""
+
+
+
+
+ Table 9 - Example Encoding of 1setOf collection
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x34 begCollection value-tag beginning of the "media-
+ size-supported (1setOf
+ collection" attribute
+
+ 0x00014 name- length of (collection)
+ length attribute name
+
+ media-size- media-size- name name of (collection)
+ supported supported attribute
+
+ 0x0000 value- defined to be 0 for this
+ length type
+
+ no value (since value-
+ length was 0)
+
+ 0x4A memberAttrName value-tag starts member attribute:
+ "x-dimension"
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 30]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x000B value- length of "x-dimension"
+ length keyword
+
+ x-dimension x-dimension value name of 1st collection
+ member attribute
+
+
+ 0x21 integer type value-tag attribute type
+
+ 0x0000 name- 0 indicates 1setOf
+ length
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value- length of an integer = 4
+ length
+
+ 0x0006 value value of 1st collection
+ member attribute
+
+ 0x4A memberAttrName value-tag starts member attribute:
+ "y-dimension"
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x000B value- length of the "y-
+ length dimension" keyword
+
+ y-dimension y-dimension value name of 2nd collection
+ member attribute
+
+ 0x21 integer type value-tag attribute type
+
+ 0x0000 name- 0 indicates 1setOf
+ length
+
+ no name (since name-length
+ was 0)
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 31]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x0004 value- length of an integer = 4
+ length
+
+ 0x0004 value value of 2nd collection
+ member attribute
+
+ 0x37 endCollection value-tag end of the collection
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x0000 value- defined to be 0 for this
+ length type
+
+ no value (since value-
+ length was 0)
+
+ 0x34 begCollection value-tag beginning of the 2nd
+ member of the 1SetOf
+ "sizes-avail " collection
+ attribute
+
+ 0x0000 name- Zero length name indicates
+ length this is member of previous
+ attribute
+
+ name no name (since name-length
+ was 0)
+
+ 0x0000 value- defined to be 0 for this
+ length type
+
+ no value (since value-
+ length was 0)
+
+ 0x4A memberAttrName value-tag starts member attribute:
+ "x-dimension"
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 32]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ no name (since name-length
+ was 0)
+
+ 0x000B value- length of "x-dimension"
+ length keyword
+
+ x-dimension x-dimension value name of 1st collection
+ member attribute
+
+ 0x21 integer type value-tag attribute type
+
+ 0x0000 name- 0 indicates 1setOf
+ length
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value- length of an integer = 4
+ length
+
+ 0x0003 value value of 1st collection
+ member attribute
+
+ 0x4A memberAttrName value-tag starts member attribute:
+ "y-dimension"
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x000B value- length of the "y-
+ length dimension" keyword
+
+ y-dimension y-dimension value name of 2nd collection
+ member attribute
+
+ 0x21 integer type value-tag attribute type
+
+ 0x0000 name- 0 indicates 1setOf
+ length
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 33]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value- length of an integer = 4
+ length
+
+ 0x0005 value value of 2nd collection
+ member attribute
+
+ 0x37 endCollection value-tag end of the 1setOf
+ collection value
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x0000 value- defined to be 0 for this
+ length type
+
+ no value (since value-
+ length was 0)
+
+
+
+
+
+16 Appendix C: Encoding Example of Collection containing 1setOf XXX
+ attribute
+
+ The overall structure of the collection value can be pictorially
+ represented as:
+
+ "wagons" =
+ { "colors" = red, blue;
+ "sizes" = 4, 6, 8
+ }
+
+ A simplified view of the encoding would look like this:
+
+ Table 10 - Overview Encoding of collection with 1setOf value
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 34]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Tag Value Name Value
+
+
+ begCollection wagons ""
+
+ memberAttrName "" colors
+
+ keyword "" red
+
+ keyword "" blue
+
+ memberAttrName "" sizes
+
+ integer "" 4
+
+ integer "" 6
+
+ integer "" 8
+
+ endCollection "" ""
+
+
+
+
+ Table 11 - Example Encoding of collection with 1setOf value
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x34 begCollection value-tag beginning of the "wagons"
+ collection attribute
+
+ 0x0005 name- length of (collection)
+ length attribute name
+
+ wagons wagons name name of (collection)
+ attribute
+
+ 0x0000 value- defined to be 0 for this
+ length type
+
+ no value (since value-
+ length was 0)
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 35]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x4A memberAttrName value-tag starts a new member
+ attribute: "colors"
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x0006 value- length of "colors" keyword
+ length
+
+ colors colosr value value is name of 1st
+ member attribute
+
+ 0x44 keyword type value-tag keyword type
+
+ 0x0000 name- 0 indicates 1setOf wagons
+ length
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value-
+ length
+
+ blue blue value value of 1st member
+ attribute
+
+ 0x44 keyword type value-tag keyword type
+
+ 0x0000 name- 0 indicates 1setOf wagons
+ length
+
+ no name (since name-length
+ was 0)
+
+ 0x0003 value-
+ length
+
+ red red value value of 1st member
+ attribute
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 36]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x4A memberAttrName value-tag starts a new member
+ attribute: "sizes"
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x0005 value- length of "length-avail"
+ length keyword
+
+ sizes sizes value Name of 2nd member
+ attribute
+
+ 0x21 integer type value-tag attribute type
+
+ 0x0000 name- 0 indicates 1setOf wagons
+ length
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value- length of an integer = 4
+ length
+
+ 0x0004 value 1st value for 1SetOf
+ integer attribute
+
+ 0x21 integer type value-tag attribute type
+
+ 0x0000 name- 0 indicates 1setOf
+ length
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value- length of an integer = 4
+ length
+
+ 0x0006 value 2nd value for 1SetOf
+ integer attribute
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 37]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+
+
+ Octets Symbolic Value Protocol comments
+ field
+
+
+ 0x21 integer type value-tag attribute type
+
+ 0x0000 name- 0 indicates 1setOf
+ length
+
+ no name (since name-length
+ was 0)
+
+ 0x0004 value- length of an integer = 4
+ length
+
+ 0x0008 value 3rd value for 1SetOf
+ integer attribute
+
+ 0x37 endCollection value-tag end of the collection
+
+ 0x0000 name- defined to be 0 for this
+ length type, so part of 1setOf
+
+ no name (since name-length
+ was 0)
+
+ 0x0000 value- defined to be 0 for this
+ length type
+
+ no value (since value-
+ length was 0)
+
+
+
+
+
+17 Appendix D: Full Copyright Statement
+
+ Copyright (C) The Internet Society (1998,1999,2000,2001). All Rights
+ Reserved
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+
+
+deBry, et al. Expires: July 24, 2001 [page 38]
+
+
+INTERNET-DRAFT IPP: The 'collection' attribute syntax Jan 24, 2001
+
+
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Expires: July 24, 2001 [page 39]
diff --git a/standards/draft-ietf-ipp-finishings-fold-trim-bale-00.txt b/standards/draft-ietf-ipp-finishings-fold-trim-bale-00.txt
new file mode 100644
index 000000000..dd4ac3403
--- /dev/null
+++ b/standards/draft-ietf-ipp-finishings-fold-trim-bale-00.txt
@@ -0,0 +1,585 @@
+INTERNET-DRAFT
+<draft-ietf-ipp-finishings-fold-trim-bale-00.txt>
+ T. Hastings
+ Xerox Corporation
+ D. Fullman
+ Xerox Corporation
+ October 20, 1999
+
+
+Internet Printing Protocol/1.1: "finishings" 'fold', 'trim', and 'bale'
+ attribute values extension
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+
+
+
+Status of this Memo
+
+
+This document is an Internet-Draft and is in full conformance with all
+provisions of Section 10 of [RFC2026]. Internet-Drafts are working
+documents of the Internet Engineering Task Force (IETF), its areas, and
+its working groups. Note that other groups may also distribute working
+documents as Internet-Drafts.
+
+
+Internet-Drafts are draft documents valid for a maximum of six months
+and may be updated, replaced, or obsoleted by other documents at any
+time. It is inappropriate to use Internet-Drafts as reference material
+or to cite them other than as "work in progress".
+
+
+The list of current Internet-Drafts can be accessed at
+http://www.ietf.org/ietf/1id-abstracts.txt
+
+
+The list of Internet-Draft Shadow Directories can be accessed as
+http://www.ietf.org/shadow.html.
+
+
+Abstract
+
+
+This document specifies the additional enum values 'fold', 'trim', and
+'bale' for the IPP/1.1 "finishings" Job Template attribute for use with
+the Internet Printing Protocol/1.1 (IPP) [ipp-mod, ipp-pro]. This
+attribute permits the client to specify additional finishing options,
+including values that include a specification of a coordinate system for
+the placement of finishings operation with respect to the corners and
+edges of portrait and landscape documents.
+
+
+
+
+
+
+
+
+
+T. Hastings, D. Fullman [page 1]
+ Expires April 20, 2000
+
+
+
+INTERNET-DRAFT IPP/1.0: "finishings" extension October 20, 1999
+
+
+The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics [ipp-mod]
+ Internet Printing Protocol/1.1: Encoding and Transport [ipp-pro]
+ Internet Printing Protocol/1.1: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+
+The "Design Goals for an Internet Printing Protocol" document takes a
+broad look at distributed printing functionality, and it enumerates
+real-life scenarios that help to clarify the features that need to be
+included in a printing protocol for the Internet. It identifies
+requirements for three types of users: end users, operators, and
+administrators. It calls out a subset of end user requirements that are
+satisfied in IPP/1.0. A few OPTIONAL operator operations have been
+added to IPP/1.1.
+
+
+The "Rationale for the Structure and Model and Protocol for the Internet
+Printing Protocol" document describes IPP from a high level view,
+defines a roadmap for the various documents that form the suite of IPP
+specification documents, and gives background and rationale for the IETF
+working group's major decisions.
+
+
+The "Internet Printing Protocol/1.1: Encoding and Transport" document is
+a formal mapping of the abstract operations and attributes defined in
+the model document onto HTTP/1.1 [RFC2616]. It defines the encoding
+rules for a new Internet MIME media type called "application/ipp". This
+document also defines the rules for transporting over HTTP a message
+body whose Content-Type is "application/ipp". This document defines a
+new scheme named 'ipp' for identifying IPP printers and jobs.
+
+
+The "Internet Printing Protocol/1.1: Implementer's Guide" document gives
+insight and advice to implementers of IPP clients and IPP objects. It
+is intended to help them understand IPP/1.1 and some of the
+considerations that may assist them in the design of their client and/or
+IPP object implementations. For example, a typical order of processing
+requests is given, including error checking. Motivation for some of the
+specification decisions is also included.
+
+
+The "Mapping between LPD and IPP Protocols" document gives some advice
+to implementers of gateways between IPP and LPD (Line Printer Daemon)
+implementations.
+
+
+
+
+
+
+
+
+
+T. Hastings, D. Fullman [page 2]
+ Expires April 20, 2000
+
+
+
+INTERNET-DRAFT IPP/1.0: "finishings" extension October 20, 1999
+
+
+
+
+ TABLE OF CONTENTS
+
+1 Additional values for the "finishings" Job Template attribute......4
+
+ 1.1 Problem.........................................................4
+
+ 1.2 Suggested solution..............................................4
+
+ 1.3 Proposed Text...................................................5
+
+ 1.3.1Coordinate system for enum values............................6
+
+2 IANA Considerations................................................7
+
+3 Security Considerations............................................7
+
+4 References.........................................................7
+
+5 Author's Addresses.................................................8
+
+6 Full Copyright Statement...........................................9
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+T. Hastings, D. Fullman [page 3]
+ Expires April 20, 2000
+
+
+
+INTERNET-DRAFT IPP/1.0: "finishings" extension October 20, 1999
+
+
+
+
+1 Additional values for the "finishings" Job Template attribute
+
+
+1.1 Problem
+
+
+Need additional enum values for finishing to specify which of four
+corners to put a single staple, which of four edges to put two staples,
+and generic values for the following: fold, trim, bale, saddle stitch
+and edge stitch.
+
+1.2 Suggested solution
+
+
+This solution has been proposed at two previous meetings with comments
+returned and incorporated. The suggestion is to add additional enum
+values to the "finishings" Job Template attributes (also applies to
+"finishings-default" and "finishings-supported" attributes).
+
+Coordination with the Finisher MIB has been done. There appears to be
+no direct way to use the same enum values, since the Finisher MIB
+divides up finishing into separate enum values by type. So all the
+stapling is done as a separate enum. Also all the punching is done as a
+separate enum.
+
+The coordinate system scheme has been selected to agree with the
+Finisher MIB which in turn follows the ISO DPA approach of using a
+coordinate system as if the document were portrait. The approach for
+coordinate system being relative to the intended reading direction
+depends on the device being able to understand the orientation embedded
+in the PDL, which is too problematic for many PDLs. The approach for
+the coordinate system of being relative to the media feed direction is
+to dependent on the way the device is currently set up, i.e., pulling
+short edge first vs. long edge first, and can vary between different
+output-bins in the same device.
+
+Additional (new) keyword symbolic names of these enum values are:
+ fold
+ trim
+ bale
+
+
+Although not a part of this specification, more specific values for
+saddle-stitch and fold could be considered once adequate definitions
+have been developed. Some examples are:
+
+ saddle-stitch-single-long
+ saddle-stitch-single-short
+ saddle-stitch-dual-long
+ saddle-stitch-dual-short
+ fold-in-half-long
+ fold-in-half-short
+ fold-in-thirds-long
+ fold-in-thirds-short
+
+T. Hastings, D. Fullman [page 4]
+ Expires April 20, 2000
+
+
+
+INTERNET-DRAFT IPP/1.0: "finishings" extension October 20, 1999
+
+
+ fold-z-long
+ fold-z-short
+
+
+1.3 Proposed Text
+
+
+Add the following paragraphs indicated with revision marks to the
+description of the "finishings" Job Template attribute, section 4.2.6,
+so that the entire section would be:
+
+4.2.6 finishings (1setOf type2 enum)
+
+This attribute identifies the finishing operations that the Printer uses
+for each copy of each printed document in the Job. For Jobs with
+multiple documents, the "multiple-document-handling" attribute
+determines what constitutes a "copy" for purposes of finishing.
+
+
+Standard enum values are:
+
+ Value Symbolic Name and Description
+
+ '3' 'none': Perform no finishing
+ '4' 'staple': Bind the document(s) with one or more staples. The
+ exact number and placement of the staples is site-
+ defined.
+ '5' 'punch': This value indicates that holes are required in the
+ finished document. The exact number and placement of the
+ holes is site-defined The punch specification MAY be
+ satisfied (in a site- and implementation-specific manner)
+ either by drilling/punching, or by substituting pre-
+ drilled media.
+ '6' 'cover': This value is specified when it is desired to select
+ a non-printed (or pre-printed) cover for the document.
+ This does not supplant the specification of a printed
+ cover (on cover stock medium) by the document itself.
+ '7' 'bind': This value indicates that a binding is to be applied
+ to the document; the type and placement of the binding is
+ site-defined.
+ '8' 'saddle-stitch': Bind the document(s) with one or more
+ staples (wire stitches) along the middle fold. The exact
+ number and placement of the staples and the middle fold
+ is implementation and/or site-defined.
+ '9' 'edge-stitch': Bind the document(s) with one or more staples
+ (wire stitches) along one edge. The exact number and
+ placement of the staples is implementation and/or site-
+ defined.
+ '10' 'fold': Fold the document(s) with one or more folds. The
+ exact number and orientations of the folds is
+ implementation and/or site-defined.
+ '11' 'trim': Trim the document(s) on one or more edges. The exact
+ number of edges and the amount to be trimmed is
+ implementation and/or site-defined.
+
+
+
+T. Hastings, D. Fullman [page 5]
+ Expires April 20, 2000
+
+
+
+INTERNET-DRAFT IPP/1.0: "finishings" extension October 20, 1999
+
+
+ '12' 'bale': Bale the document(s). The type of baling is
+ implementation and/or site-defined.
+ '13'-'19' reserved for future generic finishing enum values.
+
+The following values are more specific stapling and stitching values;
+they indicate a corner or an edge as if the document were a portrait
+document (see section 1.3.1):
+
+ '20' 'staple-top-left': Bind the document(s) with one or more
+ staples in the top left corner.
+ '21' 'staple-bottom-left': Bind the document(s) with one or more
+ staples in the bottom left corner.
+ '22' 'staple-top-right': Bind the document(s) with one or more
+ staples in the top right corner.
+ '23' 'staple-bottom-right': Bind the document(s) with one or more
+ staples in the bottom right corner.
+ '24' 'edge-stitch-left': Bind the document(s) with one or more
+ staples (wire stitches) along the left edge. The exact
+ number and placement of the staples is implementation
+ and/or site-defined.
+ '25' 'edge-stitch-top': Bind the document(s) with one or more
+ staples (wire stitches) along the top edge. The exact
+ number and placement of the staples is implementation
+ and/or site-defined.
+ '26' 'edge-stitch-right': Bind the document(s) with one or more
+ staples (wire stitches) along the right edge. The exact
+ number and placement of the staples is implementation
+ and/or site-defined.
+ '27' 'edge-stitch-bottom': Bind the document(s) with one or more
+ staples (wire stitches) along the bottom edge. The exact
+ number and placement of the staples is implementation
+ and/or site-defined.
+ '28' 'staple-dual-left': Bind the document(s) with two staples
+ (wire stitches) along the left edge.
+ '29' 'staple-dual-top': Bind the document(s) with two staples
+ (wire stitches) along the top edge.
+ '30' 'staple-dual-right': Bind the document(s) with two staples
+ (wire stitches) along the right edge.
+ '31' 'staple-dual-bottom': Bind the document(s) with two staples
+ (wire stitches) along the bottom edge.
+ '32'-'79' reserved for future specific stapling, stitching and
+ folding enum values.
+
+1.1.11.3.1Coordinate system for enum values
+
+The values, for which the symbolic name contains "top", "bottom", "left"
+and "right", are specified with respect to the document as if the
+document were a portrait document. If the document is actually a
+landscape or a reverse-landscape document, the client supplies the
+appropriate transformed value. This applies to values such as 'staple-
+xxx' and 'edge-stitch-xxx'. For example, to position a staple in the
+upper left hand corner of a landscape document when held for reading,
+the client supplies the 'staple-bottom-left' value (since landscape is
+defined as a +90 degree rotation from portrait, i.e., anti-clockwise).
+On the other hand, to position a staple in the upper left hand corner of
+
+T. Hastings, D. Fullman [page 6]
+ Expires April 20, 2000
+
+
+
+INTERNET-DRAFT IPP/1.0: "finishings" extension October 20, 1999
+
+
+a reverse-landscape document when held for reading, the client supplies
+the 'staple-top-right' value (since reverse-landscape is defined as a -
+90 degree rotation from portrait, i.e., clockwise).
+
+
+The angle (vertical, horizontal, angled) of each staple with respect to
+the document depends on the implementation which may in turn depend on
+the value of the attribute.
+
+
+Note: The effect of this attribute on jobs with multiple documents is
+controlled by the "multiple-document-handling" job attribute (section
+4.2.4) and the relationship of this attribute and the other attributes
+that control document processing is described in section 16.3.
+
+
+If the client supplies a value of 'none' along with any other
+combination of values, it is the same as if only that other combination
+of values had been supplied (that is the 'none' value has no effect).
+
+
+2 IANA Considerations
+
+
+These "finishings" type2 enum attribute values will be published by IANA
+according to the procedures in RFC 2566 [rfc2566] section 6.1 with the
+following URL:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-values/finishings/fold-
+ trim-bale.txt
+
+
+3 Internationalization Considerations
+
+
+Normally a client will provide localization of the enum values of this
+attribute to the language of the user.
+
+
+4 Security Considerations
+
+
+This extension poses no additional security threats or burdens than
+those in IPP/1.0 [RFC2566, RFC2565] and IPP/1.1 [ipp-mod, ipp-pro].
+However, implementations MAY support different access control to various
+finishing features, depending on the identity of the job submitting
+user.
+
+
+5 References
+
+
+[ipp-iig]
+ Hastings, T., Manros, C., "Internet Printing Protocol/1.1: <draft-
+ ietf-ipp-implementers-guide-v11-00.txt>, work in progress,
+ September 27, 1999.
+
+
+
+
+T. Hastings, D. Fullman [page 7]
+ Expires April 20, 2000
+
+
+
+INTERNET-DRAFT IPP/1.0: "finishings" extension October 20, 1999
+
+
+[ipp-mod]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell,
+ "Internet Printing Protocol/1.1: Model and Semantics", <draft-ietf-
+ ipp-model-v11-03.txt>, work in progress, June 1999.
+
+
+[ipp-pro]
+ Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet Printing
+ Protocol/1.1: Encoding and Transport", <draft-ietf-ipp-protocol-
+ v11-03.txt>, work in progress, June 1999.
+
+
+[RFC2565]
+ Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet Printing
+ Protocol/1.0: Encoding and Transport", RFC 2565, April 1999.
+
+
+[RFC2566]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell,
+ "Internet Printing Protocol/1.0: Model and Semantics", RFC 2566,
+ April 1999.
+
+
+[RFC2567]
+ Wright, D., "Design Goals for an Internet Printing Protocol", RFC
+ 2567, April 1999.
+
+
+[RFC2568]
+ Zilles, S., "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", RFC 2568, April 1999.
+
+
+[RFC2569]
+ Herriot, R., Hastings, T., Jacobs, N., Martin, J., "Mapping between
+ LPD and IPP Protocols", RFC 2569, April 1999.
+
+
+[RFC2639]
+ Hastings, T., Manros, C., "Internet Printing Protocol/1.0:
+ Implementer's Guide", RFC 2639, July 1999.
+
+
+6 Author's Addresses
+
+ Tom Hastings
+ Xerox Corporation
+ 737 Hawaii St. ESAE 231
+ El Segundo, CA 90245
+
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ e-mail: hastings@cp10.es.xerox.com
+
+ Don Fullman
+ Xerox Corporation
+ 737 Hawaii St. ESAE 231
+
+
+T. Hastings, D. Fullman [page 8]
+ Expires April 20, 2000
+
+
+
+INTERNET-DRAFT IPP/1.0: "finishings" extension October 20, 1999
+
+
+ El Segundo, CA 90245
+
+ Phone: 310-333-8342
+ Fax: 310-333-5514
+ e-mail: dfullman@cp10.es.xerox.com
+
+7 Full Copyright Statement
+
+
+Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+
+This document and translations of it may be copied and furnished to
+others, and derivative works that comment on or otherwise explain it or
+assist in its implementation may be prepared, copied, published and
+distributed, in whole or in part, without restriction of any kind,
+provided that the above copyright notice and this paragraph are included
+on all such copies and derivative works. However, this document itself
+may not be modified in any way, such as by removing the copyright notice
+or references to the Internet Society or other Internet organizations,
+except as needed for the purpose of developing Internet standards in
+which case the procedures for copyrights defined in the Internet
+Standards process must be followed, or as required to translate it into
+languages other than English.
+
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+
+This document and the information contained herein is provided on an "AS
+IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
+FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
+INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR
+FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+T. Hastings, D. Fullman [page 9]
+ Expires April 20, 2000
diff --git a/standards/draft-ietf-ipp-implementers-guide-v11-02.txt b/standards/draft-ietf-ipp-implementers-guide-v11-02.txt
new file mode 100644
index 000000000..5cf1db457
--- /dev/null
+++ b/standards/draft-ietf-ipp-implementers-guide-v11-02.txt
@@ -0,0 +1,5046 @@
+
+
+
+
+
+
+INTERNET-DRAFT
+draft-ietf-ipp-implementers-guide-v11-02.txt
+[Obsoletes RFC 2639] T. Hastings
+ Xerox Corporation
+ C. Manros
+ Xerox Corporation
+ C. Kugler
+ IBM Printing Systems Co
+ H. Holst
+ i-data Printing Systems
+ P. Zehler
+ Xerox Corporation
+ January 25, 2001
+
+ Internet Printing Protocol/1.1: Implementer's Guide
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of [RFC2026]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress".
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed as
+ http://www.ietf.org/shadow.html.
+
+Abstract
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 1]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ This document is one of a set of documents, which together describe
+ all aspects of a new Internet Printing Protocol (IPP). IPP is an
+ application level protocol that can be used for distributed printing
+ using Internet tools and technologies. This document contains
+ information that supplements the IPP Model and Semantics [RFC2911]
+ and the IPP Transport and Encoding [RFC2910] documents. It is
+ intended to help implementers understand IPP/1.1, as well as IPP/1.0,
+ and some of the considerations that may assist them in the design of
+ their client and/or IPP object implementations. For example, a
+ typical order of processing requests is given, including error
+ checking. Motivation for some of the specification decisions is also
+ included.
+
+ This document obsoletes RFC 2639 which was the Implementer's Guide
+ for IPP/1.0.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 2]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ The full set of IPP documents includes:
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics [RFC2911]
+ Internet Printing Protocol/1.1: Encoding and Transport [RFC2910]
+ Mapping between LPD and IPP Protocols [RFC2569]
+ The document, "Design Goals for an Internet Printing Protocol", takes
+ a broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. The design goal document calls out a subset of end
+ user requirements that are satisfied in IPP/1.1. Operator and
+ administrator requirements are out of scope for version 1.1.
+
+ The document, "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specifications, and gives background and rationale for the
+ IETF working group's major decisions.
+
+ The document, "Internet Printing Protocol/1.1: Model and Semantics",
+ describes a simplified model with abstract objects, their attributes,
+ and their operations. The model introduces a Printer and a Job. The
+ Job supports multiple documents per Job. The model document also
+ addresses how security, internationalization, and directory issues
+ are addressed.
+
+ The document, "Internet Printing Protocol/1.1: Encoding and
+ Transport", is a formal mapping of the abstract operations and
+ attributes defined in the model document onto HTTP/1.1. It also
+ defines the encoding rules for a new Internet media type called
+ "application/ipp".
+
+ The document, "Mapping between LPD and IPP Protocols", gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 3]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+TABLE OF CONTENTS
+
+ 1 Introduction....................................................7
+ 1.1 Conformance language.........................................7
+ 1.2 Other terminology............................................8
+ 1.3 Issues Raised from Interoperability Testing Events...........8
+
+ 2 IPP Objects.....................................................8
+
+ 3 IPP Operations.................................................10
+ 3.1 Common Semantics............................................10
+ 3.1.1 Summary of Operation Attributes............................10
+ 3.1.2 Suggested Operation Processing Steps for IPP Objects.......16
+ 3.1.2.1 Suggested Operation Processing Steps for all Operations ..17
+ 3.1.2.1.1 Validate version number...............................18
+ 3.1.2.1.2 Validate operation identifier.........................19
+ 3.1.2.1.3 Validate the request identifier.......................19
+ 3.1.2.1.4 Validate attribute group and attribute presence and order
+ 19
+ 3.1.2.1.4.1 Validate the presence and order of attribute groups .19
+ 3.1.2.1.4.2 Ignore unknown attribute groups in the expected
+ position 20
+ 3.1.2.1.4.3 Validate the presence of a single occurrence of
+ required Operation attributes.....................................21
+ 3.1.2.1.5 Validate the values of the REQUIRED Operation attributes
+ 28
+ 3.1.2.1.6 Validate the values of the OPTIONAL Operation attributes
+ 32
+ 3.1.2.2 Suggested Additional Processing Steps for Operations that
+ Create/Validate Jobs and Add Documents............................35
+ 3.1.2.2.1 Default "ipp-attribute-fidelity" if not supplied......35
+ 3.1.2.2.2 Check that the Printer object is accepting jobs.......36
+ 3.1.2.2.3 Validate the values of the Job Template attributes....36
+ 3.1.2.3 Algorithm for job validation .............................37
+ 3.1.2.3.1 Check for conflicting Job Template attributes values..43
+ 3.1.2.3.2 Decide whether to REJECT the request..................43
+ 3.1.2.3.3 For the Validate-Job operation, RETURN one of the success
+ status codes......................................................45
+ 3.1.2.3.4 Create the Job object with attributes to support......45
+ 3.1.2.3.5 Return one of the success status codes................47
+ 3.1.2.3.6 Accept appended Document Content......................48
+ 3.1.2.3.7 Scheduling and Starting to Process the Job............48
+ 3.1.2.3.8 Completing the Job....................................48
+ 3.1.2.3.9 Destroying the Job after completion...................48
+ 3.1.2.3.10 Interaction with "ipp-attribute-fidelity".............49
+ 3.1.2.3.11 Character set code conversion support.................49
+ 3.1.2.3.12 What charset to return when an unsupported charset is
+ requested (Issue 1.19)?...........................................50
+ 3.1.2.3.13 Natural Language Override (NLO).......................51
+ 3.1.3 Status codes returned by operation.........................53
+
+
+Hastings, et al. Expires July 25, 2001 [page 4]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ 3.1.3.1 Printer Operations .......................................53
+ 3.1.3.1.1 Print-Job.............................................53
+ 3.1.3.1.2 Print-URI.............................................55
+ 3.1.3.1.3 Validate-Job..........................................56
+ 3.1.3.1.4 Create-Job............................................56
+ 3.1.3.1.5 Get-Printer-Attributes................................56
+ 3.1.3.1.6 Get-Jobs..............................................57
+ 3.1.3.1.7 Pause-Printer.........................................58
+ 3.1.3.1.8 Resume-Printer........................................59
+ 3.1.3.1.8.1 What about Printers unable to change state due to an
+ error condition?..................................................59
+ 3.1.3.1.8.2 How is "printer-state" handled on Resume-Printer? ...59
+ 3.1.3.1.9 Purge-Printer.........................................60
+ 3.1.3.2 Job Operations ...........................................60
+ 3.1.3.2.1 Send-Document.........................................60
+ 3.1.3.2.2 Send-URI..............................................61
+ 3.1.3.2.3 Cancel-Job............................................62
+ 3.1.3.2.4 Get-Job-Attributes....................................62
+ 3.1.3.2.5 Hold-Job..............................................63
+ 3.1.3.2.6 Release-Job...........................................64
+ 3.1.3.2.7 Restart-Job...........................................64
+ 3.1.3.2.7.1 Can documents be added to a restarted job? ..........65
+ 3.1.4 Returning unsupported attributes in Get-Xxxx responses (Issue
+ 1.18) 65
+ 3.1.5 Sending empty attribute groups.............................65
+ 3.2 Printer Operations..........................................66
+ 3.2.1 Print-Job operation........................................66
+ 3.2.1.1 Flow controlling the data portion of a Print-Job request
+ (Issue 1.22)......................................................66
+ 3.2.1.2 Returning job-state in Print-Job response (Issue 1.30) ...66
+ 3.2.2 Get-Printer-Attributes operation...........................67
+ 3.2.3 Get-Jobs operation.........................................67
+ 3.2.3.1 Get-Jobs, my-jobs='true', and 'requesting-user-name' (Issue
+ 1.39)? 67
+ 3.2.3.2 Why is there a "limit" attribute in the Get-Jobs operation?
+ 68
+ 3.2.4 Create-Job operation.......................................68
+ 3.3 Job Operations..............................................69
+ 3.3.1 Validate-Job...............................................69
+ 3.3.2 Restart-Job................................................69
+
+ 4 Object Attributes..............................................70
+ 4.1 Attribute Syntax's..........................................70
+ 4.1.1 The 'none' value for empty sets (Issue 1.37)...............70
+ 4.1.2 Multi-valued attributes (Issue 1.31).......................70
+ 4.1.3 Case Sensitivity in URIs (issue 1.6).......................70
+ 4.1.4 Maximum length for xxxWithLanguage and xxxWithoutLanguage..71
+ 4.2 Job Template Attributes.....................................72
+ 4.2.1 multiple-document-handling(type2 keyword)..................72
+ 4.2.1.1 Support of multiple document jobs ........................72
+
+
+Hastings, et al. Expires July 25, 2001 [page 5]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ 4.3 Job Description Attributes..................................72
+ 4.3.1 Getting the date and time of day...........................72
+ 4.4 Printer Description Attributes..............................73
+ 4.4.1 queued-job-count (integer(0:MAX))..........................73
+ 4.4.1.1 Why is "queued-job-count" RECOMMENDED (Issue 1.14)? ......73
+ 4.4.1.2 Is "queued-job-count" a good measure of how busy a printer
+ is (Issue 1.15)?..................................................73
+ 4.4.2 printer-current-time (dateTime)............................73
+ 4.4.3 Printer-uri................................................74
+ 4.5 Empty Jobs..................................................74
+
+ 5 Directory Considerations.......................................75
+ 5.1 General Directory Schema Considerations.....................75
+ 5.2 IPP Printer with a DNS name.................................75
+
+ 6 Security Considerations........................................75
+ 6.1 Querying jobs with IPP that were submitted using other job
+ submission protocols (Issue 1.32).................................75
+
+ 7 Encoding and Transport.........................................76
+ 7.1 General Headers.............................................78
+ 7.2 Request Headers............................................79
+ 7.3 Response Headers............................................81
+ 7.4 Entity Headers.............................................81
+ 7.5 Optional support for HTTP/1.0...............................82
+ 7.6 HTTP/1.1 Chunking...........................................83
+ 7.6.1 Disabling IPP Server Response Chunking.....................83
+ 7.6.2 Warning About the Support of Chunked Requests..............83
+
+ 8 References.....................................................84
+
+ 9 Authors' Address...............................................85
+
+ 10 Full Copyright Statement.......................................86
+
+TABLES
+
+ Table 1 - Summary of Printer operation attributes that sender MUST
+ supply ........................................................11
+ Table 2 - Summary of Printer operation attributes that sender MAY
+ supply ........................................................12
+ Table 3 - Summary of Job operation attributes that sender MUST supply
+ ..............................................................13
+ Table 4 - Summary of Job operation attributes that sender MAY supply
+ ..............................................................14
+ Table 5 - Printer operation response attributes...................15
+ Table 6 - Examples of validating IPP version......................18
+ Table 7 - Rules for validating single values X against Z..........38
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 6]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+
+
+
+
+1 Introduction
+
+ The IPP Implementer's Guide (IIG) (this document) contains
+ information that supplements the IPP Model and Semantics [RFC2911]
+ and the IPP Transport and Encoding [RFC2910] documents. As such this
+ information is not part of the formal specifications. Instead
+ information is presented to help implementers understand the
+ specification, including some of the motivation for decisions taken
+ by the committee in developing the specification. Some of the
+ implementation considerations are intended to help implementers
+ design their client and/or IPP object implementations. If there are
+ any contradictions between this document and [RFC2911] or [RFC2910],
+ those documents take precedence over this document.
+
+ Platform-specific implementation considerations will be included in
+ this guide as they become known.
+
+ In order to help the reader of the IIG and the IPP Model and
+ Semantics document, the sections in this document parallel the
+ corresponding sections in the Model document and are numbered the
+ same for ease of cross reference. The sections that correspond to
+ the IPP Transport and Encoding are correspondingly offset.
+
+
+1.1 Conformance language
+
+ Usually, this document does not contain the terminology MUST, MUST
+ NOT, MAY, NEED NOT, SHOULD, SHOULD NOT, REQUIRED, and OPTIONAL.
+ However, when those terms do appear in this document, their intent is
+ to repeat what the [RFC2911] and [RFC2910] documents require and
+ allow, rather than specifying additional conformance requirements.
+ These terms are defined in section 12 on conformance terminology in
+ [RFC2911], most of which is taken from RFC 2119 [RFC2119].
+
+ Implementers should read section 12 (APPENDIX A) in [RFC2911] in
+ order to understand these capitalized words. The words MUST, MUST
+ NOT, and REQUIRED indicate what implementations are required to
+ support in a client or IPP object in order to be conformant to
+ [RFC2911] and [RFC2910]. MAY, NEED NOT, and OPTIONAL indicate was is
+ merely allowed as an implementer option. The verbs SHOULD and SHOULD
+ NOT indicate suggested behavior, but which is not required or
+ disallowed, respectively, in order to conform to the specification.
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 7]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+1.2 Other terminology
+
+ This document uses other terms, such as "attributes", "operation",
+ and "Printer" as defined in [RFC2911] section 12. In addition, the
+ term "sender" refers to the client that sends a request or an IPP
+ object that returns a response. The term "receiver" refers to the
+ IPP object that receives a request and to a client that receives a
+ response.
+
+
+1.3 Issues Raised from Interoperability Testing Events
+
+ The IPP WG has conducted three open Interoperability Testing Events.
+ The first one was held in September 1998, the second one was held in
+ March 1999, and the third one was held in October 2000. See the
+ summary reports in:
+
+ ftp://ftp.pwg.org/pub/pwg/ipp/new_TES/
+
+ The issues raised from the first Interoperability Testing Event are
+ numbered 1.n in this document and have been incorporated into
+ "IPP/1.0 Model and Semantics" [RFC2566] and the "IPP/1.0 Encoding and
+ Transport" [RFC2565] documents. However, some of the discussion is
+ left here in the Implementer's Guide to help understanding.
+
+ The issues raised from the second Interoperability Testing Event are
+ numbered 2.n in this document have been incorporated into "IPP/1.1
+ Model and Semantics" [RFC2911] and the "IPP/1.1 Encoding and
+ Transport" [RFC2910] documents. However, some of the discussion is
+ left here in the Implementer's Guide to help understanding.
+
+ The issues raised from the third Interoperability Testing Event are
+ numbered 3.n in this document and are described in:
+
+ ftp://ftp.pwg.org/pub/pwg/ipp/Issues/Issues-raised-at-Bake-Off3.pdf
+ ftp://ftp.pwg.org/pub/pwg/ipp/Issues/Issues-raised-at-Bake-Off3.doc
+ ftp://ftp.pwg.org/pub/pwg/ipp/Issues/Issues-raised-at-Bake-Off3.txt
+
+
+2 IPP Objects
+
+ The term "client" in IPP is intended to mean any client that issues
+ IPP operation requests and accepts IPP operation responses, whether
+ it be a desktop or a server. In other words, the term "client" does
+ not just mean end-user clients, such as those associated with
+ desktops.
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 8]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ The term "IPP Printer" in IPP is intended to mean an object that
+ accepts IPP operation requests and returns IPP operation responses,
+ whether implemented in a server or a device. An IPP Printer object
+ MAY, if implemented in a server, turn around and forward received
+ jobs (and other requests) to other devices and print
+ servers/services, either using IPP or some other protocol.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 9]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3 IPP Operations
+
+ This section corresponds to Section 3 "IPP Operations" in the
+ IPP/1.1 Model and Semantics document [RFC2911].
+
+
+3.1 Common Semantics
+
+ This section discusses semantics common to all operations.
+
+
+3.1.1 Summary of Operation Attributes
+
+ Legend for the following table:
+
+ R indicates a REQUIRED operation that MUST be supported by the IPP
+ object (Printer or Job). For attributes, R indicates that the
+ attribute MUST be supported by the IPP object supports the
+ associated operation.
+
+ O indicates an OPTIONAL operation or attribute that MAY be
+ supported by the IPP object (Printer or Job).
+
+ + indicates that this is not an IPP/1.0 feature, but is only a part
+ of IPP/1.1 and future versions of IPP.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 10]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ Table 1 - Summary of Printer operation attributes that sender MUST
+ supply
+
+ Printer Operations
+ Requests Response
+ s
+
+ Operation Print- Pri Crea Get- Get Pause- All
+ Attributes Job, te- Printer- - Printer Operatio
+ Validate URI Job Attribut Job , ns
+ -Job (R) (O) (O) es (R) s Resume-
+ (R) Printer
+ ,
+ Purge-
+ nt- Printer
+ (O+)
+
+ Operation parameters--REQUIRED to be supplied by the sender:
+ operation-id R R R R R R
+ status-code R
+ request-id R R R R R R R
+ version- R R R R R R R
+ number
+ Operation attributes--REQUIRED to be supplied by the sender:
+ attributes- R R R R R R R
+ charset
+ attributes- R R R R R R R
+ natural-
+ language
+ document-uri R
+ job-id*
+ job-uri*
+ last-
+ document
+ printer-uri R R R R R R
+ Operation attributes--RECOMMENDED to be supplied by the sender:
+ job-name R R R
+ requesting- R R R R R R
+ user-name
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 11]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ Table 2 - Summary of Printer operation attributes that sender MAY
+ supply
+
+ Printer Operations
+ Requests Respo
+ nses
+
+ Operation Print- Prin Crea Get- Get Pause- All
+ Attributes Job, t- te- Printer - Printer Opera
+ Valida URI Job - Job , tions
+ te-Job (O) (O) Attribu s Resume-
+ (R) tes (R) (R) Printer
+ ,
+ Purge-
+ Printer
+ (O+)
+
+ Operation attributes--OPTIONAL to be supplied by the sender:
+ status-message O
+ detailed-status- O
+ message
+ document-access- O**
+ error
+ compression O O
+ document-format R R R
+ document-name O O
+ document-natural- O O
+ language
+ ipp-attribute- R R R
+ fidelity
+ job-impressions O O O
+ job-k-octets O O O
+ job-media-sheets O O O
+ limit R
+ message
+ my-jobs R
+ requested- R R
+ attributes
+ which-jobs R
+ * "job-id" is REQUIRED only if used together with "printer-uri"
+ to identify the target job; otherwise, "job-uri" is REQUIRED.
+ ** "document-access-error" applies to the Print-URI response
+ only.
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 12]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+
+
+ Table 3 - Summary of Job operation attributes that sender MUST supply
+
+ Job Operations
+ Requests Respons
+ es
+
+ Operation Send- Send Cance Get- All
+ Attributes Docume -URI l-Job Job- Job, Operatio
+ nt (O) (R) Attrib Release ns
+ (O) utes -Job,
+ (R) Restart
+ -Job
+ (O+)
+
+ Operation parameters--REQUIRED to be supplied by the sender:
+ operation-id R R R R R
+ status-code R
+ request-id R R R R R R
+ version-number R R R R R R
+ Operation attributes--REQUIRED to be supplied by the sender:
+ attributes-charset R R R R R R
+ attributes-natural- R R R R R R
+ language
+ document-uri R
+ job-id* R R R R R
+ job-uri* R R R R R
+ last-document R R
+ printer-uri R R R R R
+ Operation attributes--RECOMMENDED to be supplied by the sender:
+ job-name
+ requesting-user- R R R R R
+ name
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 13]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+
+ Table 4 - Summary of Job operation attributes that sender MAY supply
+
+ Job Operations
+ Requests Respo
+ nses
+
+ Operation Send- Sen Cance Hold- Relea All
+ Attributes Documen d- l-Job Get- Job, se- Opera
+ t URI (R) Attrib Restar Job tions
+ (O) (O) utes t-Job (O+)
+ (R) (O+)
+
+ Operation attributes--OPTIONAL to be supplied by the sender:
+ status-message O
+ detailed-status- O
+ message
+ document-access- O**
+ error
+ compression O O
+ document-format R R
+ document-name O O
+ document-natural- O O
+ language
+ ipp-attribute-
+ fidelity
+ job-impressions
+ job-k-octets
+ job-media-sheets
+ limit
+ message O O O
+ job-hold-until R
+ my-jobs
+ requested- R
+ attributes
+ which-jobs
+ * "job-id" is REQUIRED only if used together with "printer-uri" to
+ identify the target job; otherwise, "job-uri" is REQUIRED.
+ ** "document-access-error" applies to the Send-URI operation only.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 14]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+
+
+ Table 5 - Printer operation response attributes
+
+ Printer Operations
+ Response
+
+ Operation Print- Validat Prin Create Get- Get- Pause-
+ Attributes Job e-Job t- -Job Printe Jobs Printer
+ (R),Send (R) URI (O) r- (R) ,
+ - (O), Attrib Resume-
+ Document Send utes Printer
+ (O) -URI (R) ,
+ (O) Purge-
+ Printer
+ (O+)
+
+ job-uri R R R
+ job-id R R R
+ job-state R R R
+ job-state- R+ R+ R+
+ reasons
+ number-of- O O O
+ intervening-
+ jobs
+ document- O
+ access-error+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 15]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+
+
+
+3.1.2 Suggested Operation Processing Steps for IPP Objects
+
+ This section suggests the steps and error checks that an IPP object
+ MAY perform when processing requests and returning responses. An IPP
+ object MAY perform some or all of the error checks. However, some
+ implementations MAY choose to be more forgiving than the error checks
+ shown here, in order to be able to accept requests from non-
+ conforming clients. Not performing all of these error checks is a
+ so-called "forgiving" implementation. On the other hand, clients
+ that successfully submit requests to IPP objects that do perform all
+ the error checks will be more likely to be able to interoperate with
+ other IPP object implementations. Thus an implementer of an IPP
+ object needs to decide whether to be a "forgiving" or a "strict"
+ implementation. Therefore, the error status codes returned may
+ differ between implementations. Consequentially, client SHOULD NOT
+ expect exactly the error code processing described in this section.
+
+ When an IPP object receives a request, the IPP object either accepts
+ or rejects the request. In order to determine whether or not to
+ accept or reject the request, the IPP object SHOULD execute the
+ following steps. The order of the steps may be rearranged and/or
+ combined, including making one or multiple passes over the request.
+
+ A client MUST supply requests that would pass all of the error checks
+ indicated here in order to be a conforming client. Therefore, a
+ client SHOULD supply requests that are conforming, in order to avoid
+ being rejected by some IPP object implementations and/or risking
+ different semantics by different implementations of forgiving
+ implementations. For example, a forgiving implementation that
+ accepts multiple occurrences of the same attribute, rather than
+ rejecting the request might use the first occurrences, while another
+ might use the last occurrence. Thus such a non-conforming client
+ would get different results from the two forgiving implementations.
+
+ In the following, processing continues step by step until a "RETURNS
+ the xxx status code ..." statement is encountered. Error returns are
+ indicated by the verb: "REJECTS". Since clients have difficulty
+ getting the status code before sending all of the document data in a
+ Print-Job request, clients SHOULD use the Validate-Job operation
+ before sending large documents to be printed, in order to validate
+ whether the IPP Printer will accept the job or not.
+
+ It is assumed that security authentication and authorization has
+ already taken place at a lower layer.
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 16]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3.1.2.1 Suggested Operation Processing Steps for all Operations
+
+ This section is intended to apply to all operations. The next
+ section contains the additional steps for the Print-Job, Validate-
+ Job, Print-URI, Create-Job, Send-Document, and Send-URI operations
+ that create jobs, adds documents, and validates jobs.
+
+ IIG Sect # Flow IPP error status codes
+ ---------- ---- ----------------------
+ |
+ v err
+ 3.1.2.1.1 <Validate version> --> server-error-version-not-
+ supported
+ ok|
+ v err
+ 3.1.2.1.2 <Validate operation> --> server-error-operation-not-
+ supported
+ ok|
+ v err
+ 3.1.2.1.4.1- <Validate presence> --> client-error-bad-request
+ 3.1.2.1.4.2 <of attributes>
+ ok|
+ v err
+ 3.1.2.1.4.3 <Validate presence> --> client-error-bad-request
+ <of operation attr>
+ ok|
+ v err
+ 3.1.2.1.5 <Valied values of> --> client-error-bad-request
+ <operation attrs> client-error-request-value-
+ too-long
+ <(length, tag, range,>
+ <multi-value)>
+ ok|
+ v err
+ 3.1.2.1.5 <Validate values> --> client-error-bad-request
+ <with supported values> client-error-charset-not-
+ supported
+ ok| client-error-attributes-or-
+ values-
+ | not-supported
+ v err
+ 3.1.2.1.6 <Validate optionally> --> client-error-bad-request
+ <operation attr> client-error-natural-language-
+ not-supported
+ | client-error-request-value-
+ too-long
+ | client-error-attributes-or-
+ values-not-supported
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 17]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3.1.2.1.1 Validate version number
+
+ Every request and every response contains the "version-number"
+ attribute. The value of this attribute is the major and minor
+ version number of the syntax and semantics that the client and IPP
+ object is using, respectively. The "version-number" attribute
+ remains in a fixed position across all future versions so that all
+ clients and IPP object that support future versions can determine
+ which version is being used. The IPP object checks to see if the
+ major version number supplied in the request is supported. If not,
+ the Printer object REJECTS the request and RETURNS the 'server-error-
+ version-not-supported' status code in the response. The IPP object
+ returns in the "version-number" response attribute the major and
+ minor version for the error response. Thus the client can learn at
+ least one major and minor version that the IPP object supports. The
+ IPP object is encouraged to return the closest version number to the
+ one supplied by the client.
+
+ The checking of the minor version number is implementation dependent,
+ however if the client supplied minor version is explicitly supported,
+ the IPP object MUST respond using that identical minor version
+ number. If the major version number matches, but the minor version
+ number does not, the Printer SHOULD accept and attempt to process
+ the request, or MAY reject the request and return the 'server-error-
+ version-not-supported' status code. In all cases, the Printer MUST
+ return the nearest version number that it supports. For example,
+ suppose that an IPP/1.2 Printer supports versions '1.1' and '1.2'.
+ The following responses are conforming:
+
+ Table 6 - Examples of validating IPP version
+
+
+
+ Client supplies Printer Accept Request? Printer returns
+
+
+ 1.0 yes (SHOULD) 1.1
+
+ 1.0 no (SHOULD NOT) 1.1
+
+ 1.1 yes (MUST) 1.1
+
+ 1.2 yes (MUST) 1.2
+
+ 1.3 yes (SHOULD) 1.2
+
+ 1.3 no (SHOULD NOT) 1.2
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 18]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ It is advantageous for Printers to support both IPP/1.1 and IPP/1.0,
+ so that they can interoperate with either client implementations.
+ Some implementations may allow an Administrator to explicitly disable
+ support for one or the other by setting the "ipp-versions-supported"
+ Printer description attribute.
+
+ Likewise, it is advantageous for clients to support both versions to
+ allow interoperability with new and legacy Printers.
+
+
+3.1.2.1.2 Validate operation identifier
+
+ The Printer object checks to see if the "operation-id" attribute
+ supplied by the client is supported as indicated in the Printer
+ object's "operations-supported" attribute. If not, the Printer
+ REJECTS the request and returns the 'server-error-operation-not-
+ supported' status code in the response.
+
+
+3.1.2.1.3 Validate the request identifier
+
+ The Printer object SHOULD NOT check to see if the "request-id"
+ attribute supplied by the client is in range: between 1 and 2**31 - 1
+ (inclusive), but copies all 32 bits.
+
+ Note: The "version-number", "operation-id", and the "request-id"
+ parameters are in fixed octet positions in the IPP/1.1 encoding. The
+ "version-number" parameter will be the same fixed octet position in
+ all versions of the protocol. These fields are validated before
+ proceeding with the rest of the validation.
+
+
+3.1.2.1.4 Validate attribute group and attribute presence and order
+
+ The order of the following validation steps depends on
+ implementation.
+
+
+3.1.2.1.4.1 Validate the presence and order of attribute groups
+ Client requests and IPP object responses contain attribute groups
+ that Section 3 requires to be present and in a specified order. An
+ IPP object verifies that the attribute groups are present and in the
+ correct order in requests supplied by clients (attribute groups
+ without an * in the following tables).
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 19]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ If an IPP object receives a request with (1) required attribute
+ groups missing, or (2) the attributes groups are out of order, or (3)
+ the groups are repeated, the IPP object REJECTS the request and
+ RETURNS the 'client-error-bad-request' status code. For example, it
+ is an error for the Job Template Attributes group to occur before the
+ Operation Attributes group, for the Operation Attributes group to be
+ omitted, or for an attribute group to occur more than once, except in
+ the Get-Jobs response.
+
+ Since this kind of attribute group error is most likely to be an
+ error detected by a client developer rather than by a customer, the
+ IPP object NEED NOT return an indication of which attribute group was
+ in error in either the Unsupported Attributes group or the Status
+ Message. Also, the IPP object NEED NOT find all attribute group
+ errors before returning this error.
+
+
+3.1.2.1.4.2 Ignore unknown attribute groups in the expected position
+ Future attribute groups may be added to the specification at the end
+ of requests just before the Document Content and at the end of
+ response, except for the Get-Jobs response, where it maybe there or
+ before the first job attributes returned. If an IPP object receives
+ an unknown attribute group in these positions, it ignores the entire
+ group, rather than returning an error, since that group may be a new
+ group in a later minor version of the protocol that can be ignored.
+ (If the new attribute group cannot be ignored without confusing the
+ client, the major version number would have been increased in the
+ protocol document and in the request). If the unknown group occurs
+ in a different position, the IPP object REJECTS the request and
+ RETURNS the 'client-error-bad-request' status code.
+
+ Clients also ignore unknown attribute groups returned in a response.
+
+ Note: By validating that requests are in the proper form, IPP
+ objects force clients to use the proper form which, in turn,
+ increases the chances that customers will be able to use such clients
+ from multiple vendors with IPP objects from other vendors.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 20]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3.1.2.1.4.3 Validate the presence of a single occurrence of required
+ Operation attributes
+ Client requests and IPP object responses contain Operation attributes
+ that [RFC2911] Section 3 requires to be present. Attributes within a
+ group may be in any order, except for the ordering of target,
+ charset, and natural languages attributes. These attributes MUST be
+ first, and MUST be supplied in the following order: charset, natural
+ language, and then target. An IPP object verifies that the attributes
+ that Section 4 requires to be supplied by the client have been
+ supplied in the request (attributes without an * in the following
+ tables). An asterisk (*) indicates groups and Operation attributes
+ that the client may omit in a request or an IPP object may omit in a
+ response.
+
+ If an IPP object receives a request with required attributes missing
+ or repeated from a group or in the wrong position, the behavior of
+ the IPP object is IMPLEMENTATION DEPENDENT. Some of the possible
+ implementations are:
+
+ REJECTS the request and RETURNS the 'client-error-bad-request'
+ status code
+
+ accepts the request and uses the first occurrence of the
+ attribute no matter where it is
+
+ accepts the request and uses the last occurrence of the
+ attribute no matter where it is
+
+ accept the request and assume some default value for the
+ missing attribute
+
+ Therefore, client MUST send conforming requests, if they want to
+ receive the same behavior from all IPP object implementations. For
+ example, it is an error for the "attributes-charset" or "attributes-
+ natural-language" attribute to be omitted in any operation request,
+ or for an Operation attribute to be supplied in a Job Template group
+ or a Job Template attribute to be supplied in an Operation Attribute
+ group in a create request. It is also an error to supply the
+ "attributes-charset" attribute twice.
+
+ Since these kinds of attribute errors are most likely to be detected
+ by a client developer rather than by a customer, the IPP object NEED
+ NOT return an indication of which attribute was in error in either
+ the Unsupported Attributes group or the Status Message. Also, the
+ IPP object NEED NOT find all attribute errors before returning this
+ error.
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 21]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ The following tables list all the attributes for all the operations
+ by attribute group in each request and each response. The order of
+ the groups is the order that the client supplies the groups as
+ specified in [RFC2911] Section 3. The order of the attributes within
+ a group is arbitrary, except as noted for some of the special
+ operation attributes (charset, natural language, and target). The
+ tables below use the following notation:
+
+ R indicates a REQUIRED attribute or operation that an IPP object
+ MUST support
+ O indicates an OPTIONAL attribute or operation that an IPP
+ object NEED NOT support
+ * indicates that a client MAY omit the attribute in a request
+ and that an IPP object MAY omit the attribute in a
+ response. The absence of an * means that a client MUST
+ supply the attribute in a request and an IPP object
+ MUST supply the attribute in a response.
+ + indicates that this is not a IPP/1.0 operation, but is only a
+ part of IPP/1.1 and future versions of IPP.
+
+ Operation Requests
+
+ The tables below show the attributes in their proper attribute groups
+ for operation requests:
+
+ Note: All operation requests contain "version-number", "operation-
+ id", and "request-id" parameters.
+
+
+
+ Print-Job Request (R):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ requesting-user-name (R*)
+ job-name (R*)
+ ipp-attribute-fidelity (R*)
+ document-name (R*)
+ document-format (R*)
+ document-natural-language (O*)
+ compression (O*)
+ job-k-octets (O*)
+ job-impressions (O*)
+ job-media-sheets (O*)
+ Group 2: Job Template Attributes (R*)
+ <Job Template attributes> (O*)
+ (see [RFC2911] Section 4.2)
+ Group 3: Document Content (R)
+ <document content>
+
+
+Hastings, et al. Expires July 25, 2001 [page 22]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+
+ Validate-Job Request (R):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ requesting-user-name (R*)
+ job-name (R*)
+ ipp-attribute-fidelity (R*)
+ document-name (R*)
+ document-format (R*)
+ document-natural-language (O*)
+ compression (O*)
+ job-k-octets (O*)
+ job-impressions (O*)
+ job-media-sheets (O*)
+ Group 2: Job Template Attributes (R*)
+ <Job Template attributes> (O*)
+ (see [RFC2911] Section 4.2)
+
+ Print-URI Request (O):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ document-uri (R)
+ requesting-user-name (R*)
+ job-name (R*)
+ ipp-attribute-fidelity (R*)
+ document-name (R*)
+ document-format (R*)
+ document-natural-language (O*)
+ compression (O*)
+ job-k-octets (O*)
+ job-impressions (O*)
+ job-media-sheets (O*)
+ Group 2: Job Template Attributes (R*)
+ <Job Template attributes> (O*) (see
+ (see [RFC2911] Section 4.2)
+
+ Create-Job Request (O):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ requesting-user-name (R*)
+ job-name (R*)
+ ipp-attribute-fidelity (R*)
+ job-k-octets (O*)
+ job-impressions (O*)
+
+
+Hastings, et al. Expires July 25, 2001 [page 23]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ job-media-sheets (O*)
+ Group 2: Job Template Attributes (R*)
+ <Job Template attributes> (O*) (see
+ (see [RFC2911] Section 4.2)
+
+ Get-Printer-Attributes Request (R):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ requesting-user-name (R*)
+ requested-attributes (R*)
+ document-format (R*)
+
+ Get-Jobs Request (R):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ requesting-user-name (R*)
+ limit (R*)
+ requested-attributes (R*)
+ which-jobs (R*)
+ my-jobs (R*)
+
+ Send-Document Request (O):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ (printer-uri & job-id) | job-uri (R)
+ last-document (R)
+ requesting-user-name (R*)
+ document-name (R*)
+ document-format (R*)
+ document-natural-language (O*)
+ compression (O*)
+ Group 2: Document Content (R*)
+ <document content>
+
+ Send-URI Request (O):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ (printer-uri & job-id) | job-uri (R)
+ last-document (R)
+ document-uri (R)
+ requesting-user-name (R*)
+ document-name (R*)
+ document-format (R*)
+ document-natural-language (O*)
+
+
+Hastings, et al. Expires July 25, 2001 [page 24]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ compression (O*)
+
+ Cancel-Job Request (R):
+ Release-Job Request (O+):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ (printer-uri & job-id) | job-uri (R)
+ requesting-user-name (R*)
+ message (O*)
+
+ Get-Job-Attributes Request (R):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ (printer-uri & job-id) | job-uri (R)
+ requesting-user-name (R*)
+ requested-attributes (R*)
+
+ Pause-Printer Request (O+):
+ Resume-Printer Request (O+):
+ Purge-Printer Request (O+):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ requesting-user-name (R*)
+
+ Hold-Job Request (O+):
+ Restart-Job Request (O+):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ (printer-uri & job-id) | job-uri (R)
+ requesting-user-name (R*)
+ job-hold-until (R*)
+ message (O*)
+
+ Operation Responses
+
+ The tables below show the response attributes in their proper
+ attribute groups for responses.
+
+ Note: All operation responses contain "version-number", "status-
+ code", and "request-id" parameters.
+
+
+ Print-Job Response (R):
+ Create-Job Response (O):
+ Send-Document Response (O):
+
+
+Hastings, et al. Expires July 25, 2001 [page 25]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ status-message (O*)
+ detailed-status-message (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 3)
+ <unsupported attributes> (R*)
+ Group 3: Job Object Attributes(R*) (see Note 2)
+ job-uri (R)
+ job-id (R)
+ job-state (R)
+ job-state-reasons (O* | R+)
+ job-state-message (O*)
+ number-of-intervening-jobs (O*)
+
+ Validate-Job Response (R):
+ Cancel-Job Response (R):
+ Hold-Job Response (O+):
+ Release-Job Response (O+):
+ Restart-Job Response (O+):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ status-message (O*)
+ detailed-status-message (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 3)
+ <unsupported attributes> (R*)
+
+ Print-URI Response (O):
+ Send-URI Response (O):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ status-message (O*)
+ detailed-status-message (O*)
+ document-access-error (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 3)
+ <unsupported attributes> (R*)
+ Group 3: Job Object Attributes(R*) (see Note 2)
+ job-uri (R)
+ job-id (R)
+ job-state (R)
+ job-state-reasons (O* | R+)
+ job-state-message (O*)
+ number-of-intervening-jobs (O*)
+
+ Get-Printer-Attributes Response (R):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+
+
+Hastings, et al. Expires July 25, 2001 [page 26]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ status-message (O*)
+ detailed-status-message (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 4)
+ <unsupported attributes> (R*)
+ Group 3: Printer Object Attributes(R*) (see Note 2)
+ <requested attributes> (R*)
+
+ Get-Jobs Response (R):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ status-message (O*)
+ detailed-status-message (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 4)
+ <unsupported attributes> (R*)
+ Group 3: Job Object Attributes(R*) (see Note 2, 5)
+ <requested attributes> (R*)
+
+ Get-Job-Attributes Response (R):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ status-message (O*)
+ detailed-status-message (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 4)
+ <unsupported attributes> (R*)
+ Group 3: Job Object Attributes(R*) (see Note 2)
+ <requested attributes> (R*)
+
+ Pause-Printer Response (O+):
+ Resume-Printer Response (O+):
+ Purge-Printer Response (O+):
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ status-message (O*)
+ detailed-status-message (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 4)
+ <unsupported attributes> (R*)
+
+ Note 2 - the Job Object Attributes and Printer Object Attributes are
+ returned only if the IPP object returns one of the success status
+ codes.
+
+ Note 3 - the Unsupported Attributes Group is present only if the
+ client included some Operation and/or Job Template attributes or
+ values that the Printer doesn't support whether a success or an error
+ return.
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 27]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ Note 4 - the Unsupported Attributes Group is present only if the
+ client included some Operation attributes that the Printer doesn't
+ support whether a success or an error return.
+
+ Note 5: for the Get-Jobs operation the response contains a separate
+ Job Object Attributes group 3 to N containing requested-attributes
+ for each job object in the response.
+
+
+3.1.2.1.5 Validate the values of the REQUIRED Operation attributes
+
+ An IPP object validates the values supplied by the client of the
+ REQUIRED Operation attribute that the IPP object MUST support. The
+ next section specifies the validation of the values of the OPTIONAL
+ Operation attributes that IPP objects MAY support.
+
+ The IPP object performs the following syntactic validation checks of
+ each Operation attribute value:
+
+ a) that the length of each Operation attribute value is
+ correct for the attribute syntax tag supplied by the client
+ according to [RFC2911] Section 4.1,
+
+ b) that the attribute syntax tag is correct for that Operation
+ attribute according to [RFC2911] Section 3,
+
+ c) that the value is in the range specified for that Operation
+ attribute according to [RFC2911] Section 3,
+
+ d) that multiple values are supplied by the client only for
+ operation attributes that are multi-valued, i.e., that are 1setOf
+ X according to [RFC2911] Section 3.
+
+
+
+ If any of these checks fail, the IPP object REJECTS the request and
+ RETURNS the 'client-error-bad-request' or the 'client-error-request-
+ value-too-long' status code. Since such an error is most likely to
+ be an error detected by a client developer, rather than by an end-
+ user, the IPP object NEED NOT return an indication of which attribute
+ had the error in either the Unsupported Attributes Group or the
+ Status Message. The description for each of these syntactic checks
+ is explicitly expressed in the first IF statement in the following
+ table.
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 28]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ In addition, the IPP object checks each Operation attribute value
+ against some Printer object attribute or some hard-coded value if
+ there is no "xxx-supported" Printer object attribute defined. If its
+ value is not among those supported or is not in the range supported,
+ then the IPP object REJECTS the request and RETURNS the error status
+ code indicated in the table by the second IF statement. If the value
+ of the Printer object's "xxx-supported" attribute is 'no-value'
+ (because the system administrator hasn't configured a value), the
+ check always fails.
+
+ -----------------------------------------------
+
+ attributes-charset (charset)
+
+ IF NOT a single non-empty 'charset' value, REJECT/RETURN
+ 'client-error-bad-request'.
+ IF the value length is greater than 63 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "charset-supported" attribute,
+ REJECT/RETURN "client-error-charset-not-supported".
+
+ attributes-natural-language(naturalLanguage)
+
+ IF NOT a single non-empty 'naturalLanguage' value, REJECT/RETURN
+ 'client-error-bad-request'.
+ IF the value length is greater than 63 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ ACCEPT the request even if not a member of the set in the
+ Printer object's "generated-natural-language-supported"
+ attribute. If the supplied value is not a member of the
+ Printer object's "generated-natural-language-supported"
+ attribute, use the Printer object's "natural-language-
+ configured" value.
+
+ requesting-user-name
+
+ IF NOT a single 'name' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF the IPP object can obtain a better-authenticated name, use it
+ instead.
+
+ job-name(name)
+
+ IF NOT a single 'name' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 29]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ IF NOT supplied by the client, the Printer object creates a name
+ from the document-name or document-uri.
+
+ document-name (name)
+
+ IF NOT a single 'name' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+
+ ipp-attribute-fidelity (boolean)
+
+ IF NEITHER a single 'true' NOR a single 'false' 'boolean' value,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF the value length is NOT equal to 1 octet, REJECT/RETURN
+ 'client-error-request-value-too-long'
+ IF NOT supplied by the client, the IPP object assumes the value
+ 'false'.
+
+ document-format (mimeMediaType)
+
+ IF NOT a single non-empty 'mimeMediaType' value, REJECT/RETURN
+ 'client-error-bad-request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "document-format-supported"
+ attribute, REJECT/RETURN 'client-error-document-format-not-
+ supported'
+ IF NOT supplied by the client, the IPP object assumes the value
+ of the Printer object's "document-format-default"
+ attribute.
+
+ document-uri (uri)
+
+ IF NOT a single non-empty 'uri' value, REJECT/RETURN 'client-
+ error-bad-request'.
+ IF the value length is greater than 1023 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF the URI syntax is not valid, REJECT/RETURN 'client-error-bad-
+ request'.
+ If the client-supplied URI scheme is not supported, i.e. the
+ value is not in the Printer object's referenced-uri-scheme-
+ supported" attribute, the Printer object MUST reject the
+ request and return the 'client-error-uri-scheme-not-
+ supported' status code. The Printer object MAY check to see
+ if the document exists and is accessible. If the document
+ is not found or is not accessible, REJECT/RETURN 'client-
+ error-not found'.
+ last-document (boolean)
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 30]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ IF NEITHER a single 'true' NOR a single 'false' 'boolean' value,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF the value length is NOT equal to 1 octet, REJECT/RETURN
+ 'client-error-request-value-too-long'
+
+ job-id (integer(1:MAX))
+
+ IF NOT an single 'integer' value equal to 4 octets AND in the
+ range 1 to MAX, REJECT/RETURN 'client-error-bad-request'.
+ IF NOT a job-id of an existing Job object, REJECT/RETURN
+ 'client-error-not-found' or 'client-error-gone' status
+ code, if keep track of recently deleted jobs.
+
+ requested-attributes (1setOf keyword)
+
+ IF NOT one or more 'keyword' values, REJECT/RETURN 'client-
+ error-bad-request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ Ignore unsupported values, which are the keyword names of
+ unsupported attributes. Don't bother to copy such
+ requested (unsupported) attributes to the Unsupported
+ Attribute response group since the response will not return
+ them.
+
+ which-jobs (type2 keyword)
+
+ IF NOT a single 'keyword' value, REJECT/RETURN 'client-error-
+ bad-request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NEITHER 'completed' NOR 'not-completed', copy the attribute
+ and the unsupported value to the Unsupported Attributes
+ response group and REJECT/RETURN 'client-error-attributes-
+ or-values-not-supported'.
+ Note: a Printer still supports the 'completed' value even if it
+ keeps no completed/canceled/aborted jobs: by returning no
+ jobs when so queried.
+ IF NOT supplied by the client, the IPP object assumes the 'not-
+ completed' value.
+
+ my-jobs (boolean)
+
+ IF NEITHER a single 'true' NOR a single 'false' 'boolean' value,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF the value length is NOT equal to 1 octet, REJECT/RETURN
+ 'client-error-request-value-too-long'
+ IF NOT supplied by the client, the IPP object assumes the
+ 'false' value.
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 31]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ limit (integer(1:MAX))
+
+ IF NOT a single 'integer' value equal to 4 octets AND in the
+ range 1 to MAX, REJECT/RETURN 'client-error-bad-request'.
+ IF NOT supplied by the client, the IPP object returns all jobs,
+ no matter how many.
+
+ -----------------------------------------------
+
+
+
+3.1.2.1.6 Validate the values of the OPTIONAL Operation attributes
+
+ OPTIONAL Operation attributes are those that an IPP object MAY
+ support. An IPP object validates the values of the OPTIONAL
+ attributes supplied by the client. The IPP object performs the same
+ syntactic validation checks for each OPTIONAL attribute value as in
+ Section 3.1.2.1.5. As in Section 3.1.2.1.5, if any fail, the IPP
+ object REJECTS the request and RETURNS the 'client-error-bad-request'
+ or the 'client-error-request-value-too-long' status code.
+
+ In addition, the IPP object checks each Operation attribute value
+ against some Printer attribute or some hard-coded value if there is
+ no "xxx-supported" Printer attribute defined. If its value is not
+ among those supported or is not in the range supported, then the IPP
+ object REJECTS the request and RETURNS the error status code
+ indicated in the table. If the value of the Printer object's "xxx-
+ supported" attribute is 'no-value' (because the system administrator
+ hasn't configured a value), the check always fails.
+
+ If the IPP object doesn't recognize/support an attribute, the IPP
+ object treats the attribute as an unknown or unsupported attribute
+ (see the last row in the table below).
+
+ -----------------------------------------------
+
+ document-natural-language (naturalLanguage)
+
+ IF NOT a single non-empty 'naturalLanguage' value, REJECT/RETURN
+ 'client-error-bad-request'.
+ IF the value length is greater than 63 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT a value that the Printer object supports in document
+ formats, (no corresponding "xxx-supported" Printer attribute),
+ REJECT/RETURN 'client-error-natural-language-not-supported'.
+
+ compression (type3 keyword)
+
+ IF NOT a single 'keyword' value, REJECT/RETURN 'client-error-bad-
+ request'.
+
+
+Hastings, et al. Expires July 25, 2001 [page 32]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "compression-supported" attribute,
+ copy the attribute and the unsupported value to the
+ Unsupported Attributes response group and REJECT/RETURN
+ 'client-error-attributes-or-values-not-supported'.
+ Note to IPP/1.0 implementers: Support for the "compression"
+ attribute was optional in IPP/1.0 and was changed to REQUIRED
+ in IPP/1.1. However, an IPP/1.0 object SHOULD at least check
+ for the "compression" attribute being present and reject the
+ create request, if they don't support "compression". Not
+ checking is a bug, since the data will be unintelligible.
+
+ job-k-octets (integer(0:MAX))
+
+ IF NOT a single 'integer' value equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the range of the Printer object's "job-k-octets-
+ supported" attribute, copy the attribute and the unsupported
+ value to the Unsupported Attributes response group and
+ REJECT/RETURN 'client-error-attributes-or-values-not-
+ supported'.
+
+ job-impressions (integer(0:MAX))
+
+ IF NOT a single 'integer' value equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the range of the Printer object's "job-impressions-
+ supported" attribute, copy the attribute and the unsupported
+ value to the Unsupported Attributes response group and
+ REJECT/RETURN 'client-error-attributes-or-values-not-
+ supported'.
+
+ job-media-sheets (integer(0:MAX))
+
+ IF NOT a single 'integer' value equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the range of the Printer object's "job-media-sheets-
+ supported" attribute, copy the attribute and the unsupported
+ value to the Unsupported Attributes response group and
+ REJECT/RETURN 'client-error-attributes-or-values-not-
+ supported'.
+
+ message (text(127))
+
+ IF NOT a single 'text' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 127 octets,
+ REJECT/RETURN 'client-error-request-value-too-long'.
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 33]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ unknown or unsupported attribute
+
+ IF the attribute syntax supplied by the client is supported but the
+ length is not legal for that attribute syntax, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ ELSE copy the attribute and value to the Unsupported Attributes
+ response group and change the attribute value to the "out-of-
+ band" 'unsupported' value, but otherwise ignore the attribute.
+
+ Note: Future Operation attributes may be added to the protocol
+ specification that may occur anywhere in the specified group. When
+ the operation is otherwise successful, the IPP object returns the
+ 'successful-ok-ignored-or-substituted-attributes' status code.
+ Ignoring unsupported Operation attributes in all operations is
+ analogous to the handling of unsupported Job Template attributes in
+ the create and Validate-Job operations when the client supplies the
+ "ipp-attribute-fidelity" Operation attribute with the 'false' value.
+ This last rule is so that we can add OPTIONAL Operation attributes to
+ future versions of IPP so that older clients can inter-work with new
+ IPP objects and newer clients can inter-work with older IPP objects.
+ (If the new attribute cannot be ignored without performing
+ unexpectedly, the major version number would have been increased in
+ the protocol document and in the request). This rule for Operation
+ attributes is independent of the value of the "ipp-attribute-
+ fidelity" attribute. For example, if an IPP object doesn't support
+ the OPTIONAL "job-k-octets" attribute', the IPP object treats "job-k-
+ octets" as an unknown attribute and only checks the length for the
+ 'integer' attribute syntax supplied by the client. If it is not four
+ octets, the IPP object REJECTS the request and RETURNS the 'client-
+ error-bad-request' status code, else the IPP object copies the
+ attribute to the Unsupported Attribute response group, setting the
+ value to the "out-of-band" 'unsupported' value, but otherwise ignores
+ the attribute.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 34]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3.1.2.2 Suggested Additional Processing Steps for Operations that
+ Create/Validate Jobs and Add Documents
+
+ This section in combination with the previous section recommends the
+ processing steps for the Print-Job, Validate-Job, Print-URI, Create-
+ Job, Send-Document, and Send-URI operations that IPP objects SHOULD
+ use. These are the operations that create jobs, validate a Print-Job
+ request, and add documents to a job.
+
+ IIG Sect # Flow IPP error status codes
+ ---------- ---- ----------------------
+ |
+ v No
+ 3.1.2.2.1 <ipp-attribute-fidelity> ------------------+
+ <supplied?> |
+ Yes| |
+ | ipp-attribute-fidelity = no |
+ |<------------------------------+
+ v No
+ 3.1.2.2.2 <Printer is> --> server-error-not-accepting-jobs
+ <accepting jobs?>
+ Yes|
+ v err
+ 3.1.2.3 <Validate values of> --> client-error-bad-request
+ <Job template attributes> client-error-request-value-too-
+ long
+ <(length, tag, range,>
+ <multi-value)>
+ ok|
+ v err
+ 3.1.2.3 <Validate values with> --> client-error-bad-request
+ <supported values> client-error-attributes-or-
+ | values-not-supported
+ v err
+ 3.1.2.3.1 <Any conflicting> --> client-error-conflicting-
+ attributes
+ <Job Template attr values> client-error-attributes-or-
+ values-not-supported
+ v
+
+3.1.2.2.1 Default "ipp-attribute-fidelity" if not supplied
+
+ The Printer object checks to see if the client supplied an "ipp-
+ attribute-fidelity" Operation attribute. If the attribute is not
+ supplied by the client, the IPP object assumes that the value is
+ 'false'.
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 35]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3.1.2.2.2 Check that the Printer object is accepting jobs
+
+ If the value of the Printer objects "printer-is-accepting-jobs" is
+ 'false', the Printer object REJECTS the request and RETURNS the
+ 'server-error-not-accepting-jobs' status code.
+
+
+3.1.2.2.3 Validate the values of the Job Template attributes
+
+ An IPP object validates the values of all Job Template attribute
+ supplied by the client. The IPP object performs the analogous
+ syntactic validation checks of each Job Template attribute value that
+ it performs for Operation attributes (see Section 3.1.2.1.5.):
+
+ a) that the length of each value is correct for the attribute
+ syntax tag supplied by the client according to [RFC2911] Section
+ 4.1.
+
+ b) that the attribute syntax tag is correct for that attribute
+ according to [RFC2911] Sections 4.2 to 4.4.
+
+ c) that multiple values are supplied only for multi-valued
+ attributes, i.e., that are 1setOf X according to [RFC2911]
+ Sections 4.2 to 4.4.
+
+ As in Section 3.1.2.1.5, if any of these syntactic checks fail, the
+ IPP object REJECTS the request and RETURNS the 'client-error-bad-
+ request' or 'client-error-request-value-too-long' status code as
+ appropriate, independent of the value of the "ipp-attribute-
+ fidelity". Since such an error is most likely to be an error
+ detected by a client developer, rather than by an end-user, the IPP
+ object NEED NOT return an indication of which attribute had the error
+ in either the Unsupported Attributes Group or the Status Message.
+ The description for each of these syntactic checks is explicitly
+ expressed in the first IF statement in the following table.
+
+ Each Job Template attribute MUST occur no more than once. If an IPP
+ Printer receives a create request with multiple occurrences of a Job
+ Template attribute, it MAY:
+
+ 1. reject the operation and return the 'client-error-bad-request'
+ error status code
+
+ 2. accept the operation and use the first occurrence of the
+ attribute
+
+ 3. accept the operation and use the last occurrence of the
+ attribute
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 36]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ depending on implementation. Therefore, clients MUST NOT supply
+ multiple occurrences of the same Job Template attribute in the Job
+ Attributes group in the request.
+
+
+3.1.2.3 Algorithm for job validation
+
+ The process of validating a Job-Template attribute "xxx" against a
+ Printer attribute "xxx-supported" can use the following validation
+ algorithm (see section 3.2.1.2 in [RFC2911]).
+
+ To validate the value U of Job-Template attribute "xxx" against the
+ value V of Printer "xxx-supported", perform the following
+ algorithm:
+
+ 1.If U is multi-valued, validate each value X of U by performing
+ the algorithm in Table 7 with each value X. Each validation is
+ separate from the standpoint of returning unsupported values.
+ Example: If U is "finishings" that the client supplies with
+ 'staple', 'bind' values, then X takes on the successive values:
+ 'staple', then 'bind'
+
+ 2.If V is multi-valued, validate X against each Z of V by
+ performing the algorithm in Table 7 with each value Z. If a
+ value Z validates, the validation for the attribute value X
+ succeeds. If it fails, the algorithm is applied to the next
+ value Z of V. If there are no more values Z of V, validation
+ fails. Example" If V is "sides-supported" with values: 'one-
+ sided', 'two-sided-long', and 'two-sided-short', then Z takes on
+ the successive values: 'one-sided', 'two-sided-long', and 'two-
+ sided-short'. If the client supplies "sides" with 'two-sided-
+ long', the first comparison fails ('one-sided' is not equal to
+ 'two-sided-long'), the second comparison succeeds ('two-sided-
+ long' is equal to 'two-sided-long"), and the third comparison
+ ('two-sided-short' with 'two-sided-long') is not even performed.
+
+ 3.If both U and V are single-valued, let X be U and Z be V and use
+ the validation rules in Table 7.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 37]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ Table 7 - Rules for validating single values X against Z
+
+
+
+ Attribute syntax attribute syntax validated if:
+ of X of Z
+
+
+ integer rangeOfInteger X is within the range of Z
+
+ uri uriScheme the uri scheme in X is equal to
+ Z
+
+ any boolean the value of Z is TRUE
+
+ any any X and Z are of the same type
+ and are equal.
+
+
+
+ If the value of the Printer object's "xxx-supported" attribute is
+ 'no-value' (because the system administrator hasn't configured a
+ value), the check always fails. If the check fails, the IPP object
+ copies the attribute to the Unsupported Attributes response group
+ with its unsupported value. If the attribute contains more than one
+ value, each value is checked and each unsupported value is separately
+ copied, while supported values are not copied. If an IPP object
+ doesn't recognize/support a Job Template attribute, i.e., there is no
+ corresponding Printer object "xxx-supported" attribute, the IPP
+ object treats the attribute as an unknown or unsupported attribute
+ (see the last row in the table below).
+
+ If some Job Template attributes are supported for some document
+ formats and not for others or the values are different for different
+ document formats, the IPP object SHOULD take that into account in
+ this validation using the value of the "document-format" supplied by
+ the client (or defaulted to the value of the Printer's "document-
+ format-default" attribute, if not supplied by the client). For
+ example, if "number-up" is supported for the 'text/plain' document
+ format, but not for the 'application/postscript' document format, the
+ check SHOULD (though it NEED NOT) depend on the value of the
+ "document-format" operation attribute. See "document-format" in
+ [RFC2911] section 3.2.1.1 and 3.2.5.1.
+
+ Note: whether the request is accepted or rejected is determined by
+ the value of the "ipp-attribute-fidelity" attribute in a subsequent
+ step, so that all Job Template attribute supplied are examined and
+ all unsupported attributes and/or values are copied to the
+ Unsupported Attributes response group.
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 38]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ -----------------------------------------------
+
+ job-priority (integer(1:100))
+
+ IF NOT a single 'integer' value with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT supplied by the client, use the value of the Printer
+ object's "job-priority-default" attribute at job submission
+ time.
+ IF NOT in the range 1 to 100, inclusive, copy the attribute and the
+ unsupported value to the Unsupported Attributes response
+ group.
+ Map the value to the nearest supported value in the range 1:100 as
+ specified by the number of discrete values indicated by the
+ value of the Printer's "job-priority-supported" attribute.
+ See the formula in [RFC2911] Section 4.2.1.
+
+ job-hold-until (type3 keyword | name)
+
+ IF NOT a single 'keyword' or 'name' value, REJECT/RETURN 'client-
+ error-bad-request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT supplied by the client, use the value of the Printer
+ object's "job-hold-until" attribute at job submission time.
+ IF NOT in the Printer object's "job-hold-until-supported"
+ attribute, copy the attribute and the unsupported value to the
+ Unsupported Attributes response group.
+
+ job-sheets (type3 keyword | name)
+
+ IF NOT a single 'keyword' or 'name' value, REJECT/RETURN 'client-
+ error-bad-request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "job-sheets-supported" attribute,
+ copy the attribute and the unsupported value to the
+ Unsupported Attributes response group.
+
+ multiple-document-handling (type2 keyword)
+
+ IF NOT a single 'keyword' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "multiple-document-handling-
+ supported" attribute, copy the attribute and the unsupported
+ value to the Unsupported Attributes response group.
+
+ copies (integer(1:MAX))
+
+
+Hastings, et al. Expires July 25, 2001 [page 39]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ IF NOT a single 'integer' value with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in range of the Printer object's "copies-supported"
+ attribute
+ copy the attribute and the unsupported value to the Unsupported
+ Attributes response group.
+
+ finishings (1setOf type2 enum)
+
+ IF NOT an 'enum' value(s) each with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the Printer object's "finishings-supported" attribute,
+ copy the attribute and the unsupported value(s), but not any
+ supported values, to the Unsupported Attributes response
+ group.
+
+ page-ranges (1setOf rangeOfInteger(1:MAX))
+
+ IF NOT a 'rangeOfInteger' value(s) each with a length equal to 8
+ octets, REJECT/RETURN 'client-error-bad-request'.
+ IF first value is greater than second value in any range, the
+ ranges are not in ascending order, or ranges overlap,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF the value of the Printer object's "page-ranges-supported"
+ attribute is 'false', copy the attribute to the Unsupported
+ Attributes response group and set the value to the "out-of-
+ band" 'unsupported' value.
+
+ sides (type2 keyword)
+
+ IF NOT a single 'keyword' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "sides-supported" attribute, copy
+ the attribute and the unsupported value to the Unsupported
+ Attributes response group.
+
+ number-up (integer(1:MAX))
+
+ IF NOT a single 'integer' value with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT a value or in the range of one of the values of the Printer
+ object's "number-up-supported" attribute, copy the attribute
+ and value to the Unsupported Attribute response group.
+
+ orientation-requested (type2 enum)
+
+ IF NOT a single 'enum' value with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+
+
+Hastings, et al. Expires July 25, 2001 [page 40]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ IF NOT in the Printer object's "orientation-requested-supported"
+ attribute, copy the attribute and the unsupported value to the
+ Unsupported Attributes response group.
+
+ media (type3 keyword | name)
+
+ IF NOT a single 'keyword' or 'name' value, REJECT/RETURN 'client-
+ error-bad-request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "media-supported" attribute, copy
+ the attribute and the unsupported value to the Unsupported
+ Attributes response group.
+
+ printer-resolution (resolution)
+
+ IF NOT a single 'resolution' value with a length equal to 9 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the Printer object's "printer-resolution-supported"
+ attribute, copy the attribute and the unsupported value to the
+ Unsupported Attributes response group.
+
+ print-quality (type2 enum)
+
+ IF NOT a single 'enum' value with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the Printer object's "print-quality-supported" attribute,
+ copy the attribute and the unsupported value to the
+ Unsupported Attributes response group.
+
+ unknown or unsupported attribute (i.e., there is no corresponding
+ Printer object "xxx-supported" attribute)
+
+ IF the attribute syntax supplied by the client is supported but the
+ length is not legal for that attribute syntax,
+ REJECT/RETURN 'client-error-bad-request' if the length of the
+ attribute syntax is fixed or 'client-error-request-value-too-
+ long' if the length of the attribute syntax is variable.
+ ELSE copy the attribute and value to the Unsupported Attributes
+ response group and change the attribute value to the "out-of-
+ band" 'unsupported' value. Any remaining Job Template
+ Attributes are either unknown or unsupported Job Template
+ attributes and are validated algorithmically according to
+ their attribute syntax for proper length (see below).
+ -----------------------------------------------
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 41]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ If the attribute syntax is supported AND the length check fails, the
+ IPP object REJECTS the request and RETURNS the 'client-error-bad-
+ request' if the length of the attribute syntax is fixed or the
+ 'client-error-request-value-too-long' status code if the length of
+ the attribute syntax is variable. Otherwise, the IPP object copies
+ the unsupported Job Template attribute to the Unsupported Attributes
+ response group and changes the attribute value to the "out-of-band"
+ 'unsupported' value. The following table shows the length checks for
+ all attribute syntaxes. In the following table: "<=" means less
+ than or equal, "=" means equal to:
+
+ Name Octet length check for read-write attributes
+ ----------- --------------------------------------------
+ 'textWithLanguage <= 1023 AND 'naturalLanguage' <= 63
+ 'textWithoutLanguage' <= 1023
+ 'nameWithLanguage' <= 255 AND 'naturalLanguage' <= 63
+ 'nameWithoutLanguage' <= 255
+ 'keyword' <= 255
+ 'enum' = 4
+ 'uri' <= 1023
+ 'uriScheme' <= 63
+ 'charset' <= 63
+ 'naturalLanguage' <= 63
+ 'mimeMediaType' <= 255
+ 'octetString' <= 1023
+ 'boolean' = 1
+ 'integer' = 4
+ 'rangeOfInteger' = 8
+ 'dateTime' = 11
+ 'resolution' = 9
+ '1setOf X'
+
+ Note: It's possible for a Printer to receive a zero length keyword
+ in a request. Since this is a keyword, its value needs to be
+ compared with the supported values. Assuming that the printer
+ doesn't have any values in its corresponding "xxx-supported"
+ attribute that are keywords of zero length, the comparison will fail.
+ Then the request will be accepted or rejected depending on the value
+ of "ipp-attributes-fidelity" being 'false' or 'true', respectively.
+ No special handling is required for
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 42]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3.1.2.3.1 Check for conflicting Job Template attributes values
+
+ Once all the Operation and Job Template attributes have been checked
+ individually, the Printer object SHOULD check for any conflicting
+ values among all the supported values supplied by the client. For
+ example, a Printer object might be able to staple and to print on
+ transparencies, however due to physical stapling constraints, the
+ Printer object might not be able to staple transparencies. The IPP
+ object copies the supported attributes and their conflicting
+ attribute values to the Unsupported Attributes response group. The
+ Printer object only copies over those attributes that the Printer
+ object either ignores or substitutes in order to resolve the
+ conflict, and it returns the original values which were supplied by
+ the client. For example suppose the client supplies "finishings"
+ equals 'staple' and "media" equals 'transparency', but the Printer
+ object does not support stapling transparencies. If the Printer
+ chooses to ignore the stapling request in order to resolve the
+ conflict, the Printer objects returns "finishings" equal to 'staple'
+ in the Unsupported Attributes response group. If any attributes are
+ multi-valued, only the conflicting values of the attributes are
+ copied.
+
+ Note: The decisions made to resolve the conflict (if there is a
+ choice) is implementation dependent.
+
+
+3.1.2.3.2 Decide whether to REJECT the request
+
+ If there were any unsupported Job Template attributes or
+ unsupported/conflicting Job Template attribute values and the client
+ supplied the "ipp-attribute-fidelity" attribute with the 'true'
+ value, the Printer object REJECTS the request and return the status
+ code:
+
+ 1. 'client-error-conflicting-attributes' status code, if there were
+ any conflicts between attributes supplied by the client.
+ 2. 'client-error-attributes-or-values-not-supported' status code,
+ otherwise.
+
+ Note: Unsupported Operation attributes or values that are returned
+ do not affect the status returned in this step. If the unsupported
+ Operation attribute was a serious error, the above already rejected
+ the request in a previous step. If control gets to this step with
+ unsupported Operation attributes being returned, they are not serious
+ errors.
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 43]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ In general, the final results of Job processing are unknown at Job
+ submission time. The client has to rely on notifications or polling
+ to find out what happens at Job processing time. However, there are
+ cases in which some Printers can determine at Job submission time
+ that Job processing is going to fail. As an optimization, we'd like
+ to have the Printer reject the Job in these cases.
+
+ There are three types of "processing" errors that might be detectable
+ at Job submission time:
+
+ 1. 'client-error-document-format-not-supported' : For the Print-
+ Job, Send-Document, Print-URI, and Send-URI operations, if all these
+ conditions are true:
+
+ - the Printer supports auto-sensing,
+ - the request "document-format" operation attribute is
+ 'application/octet-stream',
+ - the Printer receives document data before responding,
+ - the Printer auto-senses the document format before responding,
+ - the sensed document format is not supported by the Printer
+ then the Printer should respond with 'client-error-document-format-
+ not-supported' status.
+
+ 2. 'client-error-compression-error': For the Print-Job, Send-
+ Document, Print-URI, and Send-URI operations, if all these
+ conditions are true:
+
+ - the client supplies a supported value for the "compression"
+ operation attribute in the request
+ - the Printer receives document data before responding,
+ - the Printer attempts to decompress the document data before
+ responding,
+ - the document data cannot be decompressed using the algorithm
+ specified by the "compression" operation attribute
+ then the Printer should respond with 'client-error-compression-error'
+ status.
+
+ 3. 'client-error-document-access-error': For the Print-URI, and
+ Send-URI operations, if the Printer attempts and fails to pull the
+ referenced document data before responding, it should respond with
+ 'client-error-document-access-error' status.
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 44]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ Some Printers are not able to detect these errors until Job
+ processing time. In that case, the errors are recorded in the
+ corresponding job-state and job-state reason attributes. (There is
+ no standard way for a client to determine whether a Printer can
+ detect these errors at Job submission time.) For example, if auto-
+ sensing happens AFTER the job is accepted (as opposed to auto-sensing
+ at submit time before returning the response), the implementation
+ aborts the job, puts the job in the 'aborted' state and sets the
+ 'unsupported-document-format' value in the job's "job-state-reasons".
+
+ A client should always provide a valid "document-format" operation
+ attribute whenever practical. In the absence of other information, a
+ client itself may sniff the document data to determine document
+ format.
+
+ Auto sensing at Job submission time may be more difficult for the
+ Printer when combined with compression. For auto-sensed Jobs, a
+ client may be better off deferring compression to the transfer
+ protocol layer, e.g.; by using the HTTP Content-Encoding header.
+
+
+3.1.2.3.3 For the Validate-Job operation, RETURN one of the success
+ status codes
+
+ If the requested operation is the Validate-Job operation, the Printer
+ object returns:
+
+ 1. the "successful-ok" status code, if there are no unsupported or
+ conflicting Job Template attributes or values.
+ 2. the "successful-ok-conflicting-attributes, if there are any
+ conflicting Job Template attribute or values.
+ 3. the "successful-ok-ignored-or-substituted-attributes, if there
+ are only unsupported Job Template attributes or values.
+
+
+ Note: Unsupported Operation attributes or values that are returned
+ do not affect the status returned in this step. If the unsupported
+ Operation attribute was a serious error, the above already rejected
+ the request in a previous step. If control gets to this step with
+ unsupported Operation attributes being returned, they are not serious
+ errors.
+
+
+3.1.2.3.4 Create the Job object with attributes to support
+
+ If "ipp-attribute-fidelity" is set to 'false' (or it was not supplied
+ by the client), the Printer object:
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 45]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ 1. creates a Job object, assigns a unique value to the job's "job-
+ uri" and "job-id" attributes, and initializes all of the job's
+ other supported Job Description attributes.
+ 2. removes all unsupported attributes from the Job object.
+ 3. for each unsupported value, removes either the unsupported value
+ or substitutes the unsupported attribute value with some
+ supported value. If an attribute has no values after removing
+ unsupported values from it, the attribute is removed from the
+ Job object (so that the normal default behavior at job
+ processing time will take place for that attribute).
+ 4. for each conflicting value, removes either the conflicting value
+ or substitutes the conflicting attribute value with some other
+ supported value. If an attribute has no values after removing
+ conflicting values from it, the attribute is removed from the
+ Job object (so that the normal default behavior at job
+ processing time will take place for that attribute).
+
+ If there were no attributes or values flagged as unsupported, or the
+ value of 'ipp-attribute-fidelity" was 'false', the Printer object is
+ able to accept the create request and create a new Job object. If
+ the "ipp-attribute-fidelity" attribute is set to 'true', the Job
+ Template attributes that populate the new Job object are necessarily
+ all the Job Template attributes supplied in the create request. If
+ the "ipp-attribute-fidelity" attribute is set to 'false', the Job
+ Template attributes that populate the new Job object are all the
+ client supplied Job Template attributes that are supported or that
+ have value substitution. Thus, some of the requested Job Template
+ attributes will not appear in the Job object because the Printer
+ object did not support those attributes. The attributes that
+ populate the Job object are persistently stored with the Job object
+ for that Job. A Get-Job-Attributes operation on that Job object will
+ return only those attributes that are persistently stored with the
+ Job object.
+
+ Note: All Job Template attributes that are persistently stored with
+ the Job object are intended to be "override values"; that is, they
+ that take precedence over whatever other embedded instructions might
+ be in the document data itself. However, it is not possible for all
+ Printer objects to realize the semantics of "override". End users
+ may query the Printer's "pdl-override-supported" attribute to
+ determine if the Printer either attempts or does not attempt to
+ override document data instructions with IPP attributes.
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 46]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ There are some cases, where a Printer supports a Job Template
+ attribute and has an associated default value set for that attribute.
+ In the case where a client does not supply the corresponding
+ attribute, the Printer does not use its default values to populate
+ Job attributes when creating the new Job object; only Job Template
+ attributes actually in the create request are used to populate the
+ Job object. The Printer's default values are only used later at Job
+ processing time if no other IPP attribute or instruction embedded in
+ the document data is present.
+
+ Note: If the default values associated with Job Template attributes
+ that the client did not supply were to be used to populate the Job
+ object, then these values would become "override values" rather than
+ defaults. If the Printer supports the 'attempted' value of the "pdl-
+ override-supported" attribute, then these override values could
+ replace values specified within the document data. This is not the
+ intent of the default value mechanism. A default value for an
+ attribute is used only if the create request did not specify that
+ attribute (or it was ignored when allowed by "ipp-attribute-fidelity"
+ being 'false') and no value was provided within the content of the
+ document data.
+
+ If the client does not supply a value for some Job Template
+ attribute, and the Printer does not support that attribute, as far as
+ IPP is concerned, the result of processing that Job (with respect to
+ the missing attribute) is undefined.
+
+
+3.1.2.3.5 Return one of the success status codes
+
+ Once the Job object has been created, the Printer object accepts the
+ request and returns to the client:
+
+ 1. the 'successful-ok' status code, if there are no unsupported or
+ conflicting Job Template attributes or values.
+ 2. the 'successful-ok-conflicting-attributes' status code, if there
+ are any conflicting Job Template attribute or values.
+ 3. the 'successful-ok-ignored-or-substituted-attributes' status
+ code, if there are only unsupported Job Template attributes or
+ values.
+
+ Note: Unsupported Operation attributes or values that are returned
+ do not affect the status returned in this step. If the unsupported
+ Operation attribute was a serious error, the above already rejected
+ the request in a previous step. If control gets to this step with
+ unsupported Operation attributes being returned, they are not serious
+ errors.
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 47]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ The Printer object also returns Job status attributes that indicate
+ the initial state of the Job ('pending', 'pending-held',
+ 'processing', etc.), etc. See Print-Job Response, [RFC2911] section
+ 3.2.1.2.
+
+
+3.1.2.3.6 Accept appended Document Content
+
+ The Printer object accepts the appended Document Content data and
+ either starts it printing, or spools it for later processing.
+
+
+3.1.2.3.7 Scheduling and Starting to Process the Job
+
+ The Printer object uses its own configuration and implementation
+ specific algorithms for scheduling the Job in the correct processing
+ order. Once the Printer object begins processing the Job, the
+ Printer changes the Job's state to 'processing'. If the Printer
+ object supports PDL override (the "pdl-override-supported" attribute
+ set to 'attempted'), the implementation does its best to see that IPP
+ attributes take precedence over embedded instructions in the document
+ data.
+
+
+3.1.2.3.8 Completing the Job
+
+ The Printer object continues to process the Job until it can move the
+ Job into the 'completed' state. If an Cancel-Job operation is
+ received, the implementation eventually moves the Job into the
+ 'canceled' state. If the system encounters errors during processing
+ that do not allow it to progress the Job into a completed state, the
+ implementation halts all processing, cleans up any resources, and
+ moves the Job into the 'aborted' state.
+
+
+3.1.2.3.9 Destroying the Job after completion
+
+ Once the Job moves to the 'completed', 'aborted', or 'canceled'
+ state, it is an implementation decision as to when to destroy the Job
+ object and release all associated resources. Once the Job has been
+ destroyed, the Printer would return either the "client-error-not-
+ found" or "client-error-gone" status codes for operations directed at
+ that Job.
+
+ Note: the Printer object SHOULD NOT re-use a "job-uri" or "job-id"
+ value for a sufficiently long time after a job has been destroyed, so
+ that stale references kept by clients are less likely to access the
+ wrong (newer) job.
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 48]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3.1.2.3.10 Interaction with "ipp-attribute-fidelity"
+
+ Some Printer object implementations may support "ipp-attribute-
+ fidelity" set to 'true' and "pdl-override-supported" set to
+ 'attempted' and yet still not be able to realize exactly what the
+ client specifies in the create request. This is due to legacy
+ decisions and assumptions that have been made about the role of job
+ instructions embedded within the document data and external job
+ instructions that accompany the document data and how to handle
+ conflicts between such instructions. The inability to be 100%
+ precise about how a given implementation will behave is also
+ compounded by the fact that the two special attributes, "ipp-
+ attribute-fidelity" and "pdl-"override-supported", apply to the whole
+ job rather than specific values for each attribute. For example, some
+ implementations may be able to override almost all Job Template
+ attributes except for "number-up". Character Sets, natural languages,
+ and internationalization
+
+ This section discusses character set support, natural language
+ support and internationalization.
+
+
+3.1.2.3.11 Character set code conversion support
+
+ IPP clients and IPP objects are REQUIRED to support UTF-8. They MAY
+ support additional charsets. It is RECOMMENDED that an IPP object
+ also support US-ASCII, since many clients support US-ASCII, and
+ indicate that UTF-8 and US-ASCII are supported by populating the
+ Printer's "charset-supported" with 'utf-8' and 'us-ascii' values. An
+ IPP object is required to code covert with as little loss as possible
+ between the charsets that it supports, as indicated in the Printer's
+ "charsets-supported" attribute.
+
+ How should the server handle the situation where the "attributes-
+ charset" of the response itself is "us-ascii", but one or more
+ attributes in that response is in the "utf-8" format?
+
+ Example: Consider a case where a client sends a Print-Job request
+ with "utf-8" as the value of "attributes-charset" and with the "job-
+ name" attribute supplied. Later another client submits a Get-Job-
+ Attribute or Get-Jobs request. This second request contains the
+ "attributes-charset" with value "us-ascii" and "requested-attributes"
+ attribute with exactly one value "job-name".
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 49]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ According to the RFC2911 document (section 3.1.4.2), the value of the
+ "attributes-charset" for the response of the second request must be
+ "us-ascii" since that is the charset specified in the request. The
+ "job-name" value, however, is in "utf-8" format. Should the request
+ be rejected even though both "utf-8" and "us-ascii" charsets are
+ supported by the server? or should the "job-name" value be converted
+ to "us-ascii" and return "successful-ok-conflicting-attributes"
+ (0x0002) as the status code?
+
+ Answer: An IPP object that supports both utf-8 (REQUIRED) and us-
+ ascii, the second paragraph of section 3.1.4.2 applies so that the
+ IPP object MUST accept the request, perform code set conversion
+ between these two charsets with "the highest fidelity possible" and
+ return 'successful-ok', rather than a warning 'successful-ok-
+ conflicting-attributes, or an error. The printer will do the best it
+ can to convert between each of the character sets that it supports--
+ even if that means providing a string of question marks because none
+ of the characters are representable in US ASCII. If it can't perform
+ such conversion, it MUST NOT advertise us-ascii as a value of its
+ "attributes-charset-supported" and MUST reject any request that
+ requests 'us-ascii'.
+
+ One IPP object implementation strategy is to convert all request text
+ and name values to a Unicode internal representation. This is 16-bit
+ and virtually universal. Then convert to the specified operation
+ attributes-charset on output.
+
+ Also it would be smarter for a client to ask for 'utf-8', rather than
+ 'us-ascii' and throw away characters that it doesn't understand,
+ rather than depending on the code conversion of the IPP object.
+
+
+3.1.2.3.12 What charset to return when an unsupported charset is
+ requested (Issue 1.19)?
+
+ Section 3.1.4.1 Request Operation attributes was clarified in
+ November 1998 as follows:
+
+ All clients and IPP objects MUST support the 'utf-8' charset
+ [RFC2044] and MAY support additional charsets provided that they are
+ registered with IANA [IANA-CS]. If the Printer object does not
+ support the client supplied charset value, the Printer object MUST
+ reject the request, set the "attributes-charset" to 'utf-8' in the
+ response, and return the 'client-error-charset-not-supported' status
+ code and any 'text' or 'name' attributes using the 'utf-8' charset.
+
+ Since the client and IPP object MUST support UTF-8, returning any
+ text or name attributes in UTF-8 when the client requests a charset
+ that is not supported should allow the client to display the text or
+ name.
+
+
+Hastings, et al. Expires July 25, 2001 [page 50]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ Since such an error is a client error, rather than a user error, the
+ client should check the status code first so that it can avoid
+ displaying any other returned 'text' and 'name' attributes that are
+ not in the charset requested.
+
+ Furthermore, [RFC2911] section 14.1.4.14 client-error-charset-not-
+ supported (0x040D) was clarified in November 1998 as follows:
+
+ For any operation, if the IPP Printer does not support the charset
+ supplied by the client in the "attributes-charset" operation
+ attribute, the Printer MUST reject the operation and return this
+ status and any 'text' or 'name' attributes using the 'utf-8' charset
+ (see Section 3.1.4.1).
+
+
+3.1.2.3.13 Natural Language Override (NLO)
+
+ The 'text' and 'name' attributes each have two forms. One has an
+ implicit natural language, and the other has an explicit natural
+ language. The 'textWithoutLanguage' and 'textWithLanguage' are the
+ two 'text' forms. The 'nameWithoutLanguage" and 'nameWithLanguage
+ are the two 'name' forms. If a receiver (IPP object or IPP client)
+ supports an attribute with attribute syntax 'text', it MUST support
+ both forms in a request and a response. A sender (IPP client or IPP
+ object) MAY send either form for any such attribute. When a sender
+ sends a WithoutLanguage form, the implicit natural language is
+ specified in the "attributes-natural-language" operation attribute,
+ which all senders MUST include in every request and response.
+
+ When a sender sends a WithLanguage form, it MAY be different from the
+ implicit natural language supplied by the sender or it MAY be the
+ same. The receiver MUST treat either form equivalently.
+
+ There is an implementation decision for senders, whether to always
+ send the WithLanguage forms or use the WithoutLanguage form when the
+ attribute's natural language is the same as the request or response.
+ The former approach makes the sender implementation simpler. The
+ latter approach is more efficient on the wire and allows inter-
+ working with non-conforming receivers that fail to support the
+ WithLanguage forms. As each approach have advantages, the choice is
+ completely up to the implementer of the sender.
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 51]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ Furthermore, when a client receives a 'text' or 'name' job attribute
+ that it had previously supplied, that client MUST NOT expect to see
+ the attribute in the same form, i.e., in the same WithoutLanguage or
+ WithLanguage form as the client supplied when it created the job.
+ The IPP object is free to transform the attribute from the
+ WithLanguage form to the WithoutLanguage form and vice versa, as long
+ as the natural language is preserved. However, in order to meet this
+ latter requirement, it is usually simpler for the IPP object
+ implementation to store the natural language explicitly with the
+ attribute value, i.e., to store using an internal representation that
+ resembles the WithLanguage form.
+
+ The IPP Printer MUST copy the natural language of a job, i.e., the
+ value of the "attributes-natural-language" operation attribute
+ supplied by the client in the create operation, to the Job object as
+ a Job Description attribute, so that a client is able to query it.
+ In returning a Get-Job-Attributes response, the IPP object MAY return
+ one of three natural language values in the response's "attributes-
+ natural-language" operation attribute: (1) that requested by the
+ requester, (2) the natural language of the job, or (3) the configured
+ natural language of the IPP Printer, if the requested language is not
+ supported by the IPP Printer.
+
+ This "attributes-natural-language" Job Description attribute is
+ useful for an IPP object implementation that prints start sheets in
+ the language of the user who submitted the job. This same Job
+ Description attribute is useful to a multi-lingual operator who has
+ to communicate with different job submitters in different natural
+ languages. This same Job Description attribute is expected to be
+ used in the future to generate notification messages in the natural
+ language of the job submitter.
+
+ Early drafts of [RFC2911] contained a job-level natural language
+ override (NLO) for the Get-Jobs response. A job-level (NLO) is an
+ (unrequested) Job Attribute which then specified the implicit natural
+ language for any other WithoutLanguage job attributes returned in the
+ response for that job. Interoperability testing of early
+ implementations showed that no one was implementing the job-level NLO
+ in Get-Job responses. So the job-level NLO was eliminated from the
+ Get-Jobs response. This simplification makes all requests and
+ responses consistent in that the implicit natural language for any
+ WithoutLanguage 'text' or 'name' form is always supplied in the
+ request's or response's "attributes-natural-language" operation
+ attribute.
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 52]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3.1.3 Status codes returned by operation
+
+ This section corresponds to [RFC2911] section 3.1.6 "Operation
+ Response Status Codes and Status Messages". This section lists all
+ status codes once in the first operation (Print-Job). Then it lists
+ the status codes that are different or specialized for subsequent
+ operations under each operation.
+
+
+3.1.3.1 Printer Operations
+
+
+3.1.3.1.1 Print-Job
+
+ The Printer object MUST return one of the following "status-code"
+ values for the indicated reason. Whether all of the document data
+ has been accepted or not before returning the success or error
+ response depends on implementation. See Section 13 in [RFC2911] for
+ a more complete description of each status code.
+
+ For the following success status codes, the Job object has been
+ created and the "job-id", and "job-uri" assigned and returned in the
+ response:
+
+ successful-ok: no request attributes were substituted or ignored.
+ successful-ok-ignored-or-substituted-attributes: some supplied (1)
+ attributes were ignored or (2) unsupported attribute syntaxes or
+ values were substituted with supported values or were ignored.
+ Unsupported attributes, attribute syntax's, or values MUST be
+ returned in the Unsupported Attributes group of the response.
+ successful-ok-conflicting-attributes: some supplied attribute
+ values conflicted with the values of other supplied attributes
+ and were either substituted or ignored. Attributes or values
+ which conflict with other attributes and have been substituted
+ or ignored MUST be returned in the Unsupported Attributes group
+ of the response as supplied by the client.
+
+ [RFC2911] section 3.1.6 Operation Status Codes and Messages states:
+
+ If the Printer object supports the "status-message" operation
+ attribute, it SHOULD use the REQUIRED 'utf-8' charset to return a
+ status message for the following error status codes (see section 13
+ in [RFC2911]): 'client-error-bad-request', 'client-error-charset-
+ not-supported', 'server-error-internal-error', 'server-error-
+ operation-not-supported', and 'server-error-version-not-supported'.
+ In this case, it MUST set the value of the "attributes-charset"
+ operation attribute to 'utf-8' in the error response.
+
+ For the following error status codes, no job is created and no
+ "job-id" or "job-uri" is returned:
+
+
+Hastings, et al. Expires July 25, 2001 [page 53]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ client-error-bad-request: The request syntax does not conform
+ to the specification.
+ client-error-forbidden: The request is being refused for
+ authorization or authentication reasons. The implementation
+ security policy is to not reveal whether the failure is one of
+ authentication or authorization.
+ client-error-not-authenticated: Either the request requires
+ authentication information to be supplied or the
+ authentication information is not sufficient for
+ authorization.
+ client-error-not-authorized: The requester is not authorized to
+ perform the request on the target object.
+ client-error-not-possible: The request cannot be carried out
+ because of the state of the system. See also 'server-error-
+ not-accepting-jobs' status code, which MUST take precedence if
+ the Printer object's "printer-accepting-jobs" attribute is
+ 'false'.
+ client-error-timeout: not applicable.
+ client-error-not-found: the target object does not exist.
+ client-error-gone: the target object no longer exists and no
+ forwarding address is known.
+ client-error-request-entity-too-large: the size of the request
+ and/or print data exceeds the capacity of the IPP Printer to
+ process it.
+ client-error-request-value-too-long: the size of request
+ variable length attribute values, such as 'text' and 'name'
+ attribute syntax's, exceed the maximum length specified in
+ [RFC2911] for the attribute and MUST be returned in the
+ Unsupported Attributes Group.
+ client-error-document-format-not-supported: the document format
+ supplied is not supported. The "document-format" attribute
+ with the unsupported value MUST be returned in the Unsupported
+ Attributes Group. This error SHOULD take precedence over any
+ other 'xxx-not-supported' error, except 'client-error-charset-
+ not-supported'.
+ client-error-attributes-or-values-not-supported: one or more
+ supplied attributes, attribute syntax's, or values are not
+ supported and the client supplied the "ipp-attributes-
+ fidelity" operation attribute with a 'true' value. They MUST
+ be returned in the Unsupported Attributes Group as explained
+ below.
+ client-error-uri-scheme-not-supported: not applicable.
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 54]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ client-error-charset-not-supported: the charset supplied in the
+ "attributes-charset" operation attribute is not supported.
+ The Printer's "configured-charset" MUST be returned in the
+ response as the value of the "attributes-charset" operation
+ attribute and used for any 'text' and 'name' attributes
+ returned in the error response. This error SHOULD take
+ precedence over any other error, unless the request syntax is
+ so bad that the client's supplied "attributes-charset" cannot
+ be determined.
+ client-error-conflicting-attributes: one or more supplied
+ attribute values conflicted with each other and the client
+ supplied the "ipp-attributes-fidelity" operation attribute
+ with a 'true' value. They MUST be returned in the Unsupported
+ Attributes Group as explained below.
+ server-error-internal-error: an unexpected condition prevents
+ the request from being fulfilled.
+ server-error-operation-not-supported: not applicable (since
+ Print-Job is REQUIRED).
+ server-error-service-unavailable: the service is temporarily
+ overloaded.
+ server-error-version-not-supported: the version in the request
+ is not supported. The "closest" version number supported MUST
+ be returned in the response.
+ server-error-device-error: a device error occurred while
+ receiving or spooling the request or document data or the IPP
+ Printer object can only accept one job at a time.
+ server-error-temporary-error: a temporary error such as a
+ buffer full write error, a memory overflow, or a disk full
+ condition occurred while receiving the request and/or the
+ document data.
+ server-error-not-accepting-jobs: the Printer object's "printer-
+ is-not-accepting-jobs" attribute is 'false'.
+ server-error-busy: the Printer is too busy processing jobs to
+ accept another job at this time.
+ server-error-job-canceled: the job has been canceled by an
+ operator or the system while the client was transmitting the
+ document data.
+
+3.1.3.1.2 Print-URI
+
+ All of the Print-Job status codes described in Section 3.1.3.1.1
+ Print-Job Response are applicable to Print-URI with the following
+ specializations and differences. See Section 14 for a more complete
+ description of each status code.
+
+ client-error-uri-scheme-not-supported: the URI scheme supplied in
+ the "document-uri" operation attribute is not supported and is
+ returned in the Unsupported Attributes group.
+ server-error-operation-not-supported: the Print-URI operation is
+ not supported.
+
+
+Hastings, et al. Expires July 25, 2001 [page 55]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+
+
+3.1.3.1.3 Validate-Job
+
+ All of the Print-Job status codes described in Section 3.1.3.1.1
+ Print-Job Response are applicable to Validate-Job. See Section 13 in
+ [RFC2911] for a more complete description of each status code.
+
+
+3.1.3.1.4 Create-Job
+
+ All of the Print-Job status codes described in Section 3.1.3.1.1
+ Print-Job Response are applicable to Create-Job with the following
+ specializations and differences. See Section 13 in [RFC2911] for a
+ more complete description of each status code.
+
+ server-error-operation-not-supported: the Create-Job operation is
+ not supported.
+ client-error-multiple-document-jobs-not-supported: while the
+ Create-Job and Send-Document operations are supported, this
+ implementation doesn't support more than one document with data.
+
+3.1.3.1.5 Get-Printer-Attributes
+
+ All of the Print-Job status codes described in Section 3.1.3.1.1
+ Print-Job Response are applicable to the Get-Printer-Attributes
+ operation with the following specialization's and differences. See
+ Section 13 in [RFC2911] for a more complete description of each
+ status code.
+
+ For the following success status codes, the requested attributes are
+ returned in Group 3 in the response:
+
+ successful-ok: no operation attributes or values were substituted
+ or ignored (same as Print-Job) and no requested attributes were
+ unsupported.
+ successful-ok-ignored-or-substituted-attributes: The "requested-
+ attributes" operation attribute MAY, but NEED NOT, be returned
+ with the unsupported values.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+ For the error status codes, Group 3 is returned containing no
+ attributes or is not returned at all:
+
+ client-error-not-possible: Same as Print-Job, in addition the
+ Printer object is not accepting any requests.
+ client-error-request-entity-too-large: same as Print-job, except
+ that no print data is involved.
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 56]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ client-error-attributes-or-values-not-supported: not applicable,
+ since unsupported operation attributes and/or values MUST be
+ ignored and an appropriate success code returned (see above).
+ client-error-conflicting-attributes: same as Print-Job, except
+ that "ipp-attribute-fidelity" is not involved.
+ server-error-operation-not-supported: not applicable (since Get-
+ Printer-Attributes is REQUIRED).
+ server-error-device-error: same as Print-Job, except that no
+ document data is involved.
+ server-error-temporary-error: same as Print-Job, except that no
+ document data is involved.
+ server-error-not-accepting-jobs: not applicable.
+ server-error-busy: same as Print-Job, except the IPP object is too
+ busy to accept even query requests.
+ server-error-job-canceled: not applicable.
+
+3.1.3.1.6 Get-Jobs
+
+ All of the Print-Job status codes described in Section 3.1.3.1.1
+ Print-Job Response are applicable to the Get-Jobs operation with the
+ following specialization's and differences. See Section 13 in
+ [RFC2911] for a more complete description of each status code.
+
+ For the following success status codes, the requested attributes are
+ returned in Group 3 in the response:
+
+ successful-ok: same as Get-Printer-Attributes (see section
+ 3.1.3.1.5).
+ successful-ok-ignored-or-substituted-attributes: same as Get-
+ Printer-Attributes (see section 3.1.3.1.5).
+ successful-ok-conflicting-attributes: same as Get-Printer-
+ Attributes (see section 3.1.3.1.5).
+
+ For any error status codes, Group 3 is returned containing no
+ attributes or is not returned at all. The following brief error
+ status code descriptions contain unique information for use with Get-
+ Jobs operation. See section 14 for the other error status codes that
+ apply uniformly to all operations:
+
+ client-error-not-possible: Same as Print-Job, in addition the
+ Printer object is not accepting any requests.
+ client-error-request-entity-too-large: same as Print-job,
+ except that no print data is involved.
+ client-error-document-format-not-supported: not applicable.
+ client-error-attributes-or-values-not-supported: not
+ applicable, since unsupported operation attributes and/or
+ values MUST be ignored and an appropriate success code
+ returned (see above).
+ client-error-conflicting-attributes: same as Print-Job, except
+ that "ipp-attribute-fidelity" is not involved.
+
+
+Hastings, et al. Expires July 25, 2001 [page 57]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ server-error-operation-not-supported: not applicable (since
+ Get-Jobs is REQUIRED).
+ server-error-device-error: same as Print-Job, except that no
+ document data is involved.
+ server-error-temporary-error: same as Print-Job, except that no
+ document data is involved.
+ server-error-not-accepting-jobs: not applicable.
+ server-error-job-canceled: not applicable.
+
+3.1.3.1.7 Pause-Printer
+
+ All of the Print-Job status codes described in Section 3.1.3.1.1
+ Print-Job Response are applicable to Pause-Printer with the following
+ specializations and differences. See Section 13 in [RFC2911] for a
+ more complete description of each status code.
+
+ For the following success status codes, the Printer object is being
+ stopped from scheduling jobs on all its devices.
+
+ successful-ok: no request attributes were substituted or
+ ignored (same as Print-Job).
+ successful-ok-ignored-or-substituted-attributes: same as
+ Print-Job.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+ For any of the error status codes, the Printer object has not been
+ stopped from scheduling jobs on all its devices.
+
+ client-error-not-possible: not applicable.
+ client-error-not-found: the target Printer object does not
+ exist.
+ client-error-gone: the target Printer object no longer exists
+ and no forwarding address is known.
+ client-error-request-entity-too-large: same as Print-Job,
+ except no document data is involved.
+ client-error-document-format-not-supported: not applicable.
+ client-error-conflicting-attributes: same as Print-Job, except
+ that the Printer's "printer-is-accepting-jobs" attribute is
+ not involved.
+ server-error-operation-not-supported: the Pause-Printer
+ operation is not supported.
+ server-error-device-error: not applicable.
+ server-error-temporary-error: same as Print-Job, except no
+ document data is involved.
+ server-error-not-accepting-jobs: not applicable.
+ server-error-job-canceled: not applicable.
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 58]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3.1.3.1.8 Resume-Printer
+
+ All of the Print-Job status code descriptions in Section 3.1.3.1.1
+ Print-Job Response with the specialization's described for Pause-
+ Printer are applicable to Resume-Printer. See Section 13 in
+ [RFC2911] for a more complete description of each status code.
+
+ For the following success status codes, the Printer object resumes
+ scheduling jobs on all its devices.
+
+ successful-ok: no request attributes were substituted or
+ ignored (same as Print-Job).
+ successful-ok-ignored-or-substituted-attributes: same as
+ Print-Job.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+ For any of the error status codes, the Printer object does not resume
+ scheduling jobs.
+
+ server-error-operation-not-supported: the Resume-Printer
+ operation is not supported.
+
+
+3.1.3.1.8.1 What about Printers unable to change state due to an error
+ condition?
+ If, in case, the IPP printer is unable to change its state due to
+ some problem with the actual printer device (say, it is shut down or
+ there is a media-jam as indicated in [RFC2911]), what should be the
+ result of the "Resume-Printer" operation? Should it still change the
+ 'printer-state-reasons' and return success or should it fail ?
+
+ The Resume-Printer operation must clear the 'paused' or 'moving-to-
+ paused' 'printer-state-message'. The operation must return a
+ 'successful-ok' status code.
+
+
+3.1.3.1.8.2 How is "printer-state" handled on Resume-Printer?
+
+
+ If the Resume-Printer operation succeeds, what should be the value of
+ "printer-state" and who should take care of the "printer-state"
+ attribute value later on ?
+
+ The Resume-Printer operation may change the "printer-state-reasons"
+ value.
+
+ The "printer-state" will change to one of three states:
+
+ 1. 'idle' - no additional jobs and no error conditions present
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 59]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ 2. 'processing' - job available and no error conditions present
+
+ 3. current state (i.e. no change) an error condition is present
+ (e.g. media jam)
+
+ In the third case the "printer-state-reason" will be cleared by
+ automata when it detects the error condition no longer exists. The
+ "printer-state" will move to 'idle' or 'processing' when conditions
+ permit. (i.e. no more error conditions)
+
+
+3.1.3.1.9 Purge-Printer
+
+ All of the Print-Job status code descriptions in Section 3.1.3.1.1
+ Print-Job Response with the specialization's described for Pause-
+ Printer are applicable to Purge-Printer. See Section 13 in [RFC2911]
+ for a more complete description of each status code.
+
+ For the following success status codes, the Printer object purges all
+ it's jobs.
+
+ successful-ok: no request attributes were substituted or
+ ignored (same as Print-Job).
+ successful-ok-ignored-or-substituted-attributes: same as
+ Print-Job.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+ For any of the error status codes, the Printer object does not purge
+ any jobs.
+
+ server-error-operation-not-supported: the Purge-Printer
+ operation is not supported.
+
+3.1.3.2 Job Operations
+
+
+3.1.3.2.1 Send-Document
+
+ All of the Print-Job status codes described in Section 3.1.3.1.1
+ Print-Job Response are applicable to the Get-Printer-Attributes
+ operation with the following specialization's and differences. See
+ Section 13 in [RFC2911] for a more complete description of each
+ status code.
+
+ For the following success status codes, the document has been added
+ to the specified Job object and the job's "number-of-documents"
+ attribute has been incremented:
+
+ successful-ok: no request attributes were substituted or
+ ignored (same as Print-Job).
+
+
+Hastings, et al. Expires July 25, 2001 [page 60]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ successful-ok-ignored-or-substituted-attributes: same as Print-
+ Job.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+ For the error status codes, no document has been added to the Job
+ object and the job's "number-of-documents" attribute has not been
+ incremented:
+
+ client-error-not-possible: Same as Print-Job, except that the
+ Printer's "printer-is-accepting-jobs" attribute is not
+ involved, so that the client is able to finish submitting a
+ job that was created with a Create-Job operation after this
+ attribute has been set to 'true'. Another condition is that
+ the state of the job precludes Send-Document, i.e., the job
+ has already been closed out by the client. However, if the
+ IPP Printer closed out the job due to timeout, the 'client-
+ error-timeout' error status SHOULD be returned instead.
+ client-error-timeout: This request was sent after the Printer
+ closed the job, because it has not received a Send-Document or
+ Send-URI operation within the Printer's "multiple-operation-
+ time-out" period .
+ client-error-request-entity-too-large: same as Print-Job.
+ client-error-conflicting-attributes: same as Print-Job, except
+ that "ipp-attributes-fidelity" operation attribute is not
+ involved..
+ server-error-operation-not-supported: the Send-Document request
+ is not supported.
+ server-error-not-accepting-jobs: not applicable.
+ server-error-job-canceled: the job has been canceled by an
+ operator or the system while the client was transmitting the
+ data.
+
+3.1.3.2.2 Send-URI
+
+ All of the Print-Job status code descriptions in Section 3.1.3.1.1
+ Print-Job Response with the specialization's described for Send-
+ Document are applicable to Send-URI. See Section 13 in [RFC2911] for
+ a more complete description of each status code.
+
+ client-error-uri-scheme-not-supported: the URI scheme supplied
+ in the "document-uri" operation attribute is not supported and
+ the "document-uri" attribute MUST be returned in the
+ Unsupported Attributes group.
+ server-error-operation-not-supported: the Send-URI operation is
+ not supported.
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 61]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3.1.3.2.3 Cancel-Job
+
+ All of the Print-Job status codes described in Section 3.1.3.1.1
+ Print-Job Response are applicable to Cancel-Job with the following
+ specializations and differences. See Section 13 in [RFC2911] for a
+ more complete description of each status code.
+
+ For the following success status codes, the Job object is being
+ canceled or has been canceled:
+
+ successful-ok: no request attributes were substituted or
+ ignored (same as Print-Job).
+ successful-ok-ignored-or-substituted-attributes: same as
+ Print-Job.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+ For any of the error status codes, the Job object has not been
+ canceled or was previously canceled.
+
+ client-error-not-possible: The request cannot be carried out
+ because of the state of the Job object ('completed',
+ 'canceled', or 'aborted') or the state of the system.
+ client-error-not-found: the target Printer and/or Job object
+ does not exist.
+ client-error-gone: the target Printer and/or Job object no
+ longer exists and no forwarding address is known.
+ client-error-request-entity-too-large: same as Print-Job,
+ except no document data is involved.
+ client-error-document-format-not-supported: not applicable.
+ client-error-attributes-or-values-not-supported: not
+ applicable, since unsupported operation attributes and values
+ MUST be ignored.
+ client-error-conflicting-attributes: same as Print-Job, except
+ that the Printer's "printer-is-accepting-jobs" attribute is
+ not involved.
+ server-error-operation-not-supported: not applicable (Cancel-
+ Job is REQUIRED).
+ server-error-device-error: same as Print-Job, except no
+ document data is involved.
+ server-error-temporary-error: same as Print-Job, except no
+ document data is involved.
+ server-error-not-accepting-jobs: not applicable..
+ server-error-job-canceled: not applicable.
+
+3.1.3.2.4 Get-Job-Attributes
+
+ All of the Print-Job status codes described in Section 3.1.3.1.1
+ Print-Job Response are applicable to Get-Job-Attributes with the
+ following specializations and differences. See Section 13 in
+ [RFC2911] for a more complete description of each status code.
+
+
+Hastings, et al. Expires July 25, 2001 [page 62]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ For the following success status codes, the requested attributes are
+ returned in Group 3 in the response:
+
+ successful-ok: same as Get-Printer-Attributes (see section
+ 3.1.3.1.5).
+ successful-ok-ignored-or-substituted-attributes: same as Get-
+ Printer-Attributes (see section 3.1.3.1.5).
+ successful-ok-conflicting-attributes: same as Get-Printer-
+ Attributes (see section 3.1.3.1.5).
+
+ For the error status codes, Group 3 is returned containing no
+ attributes or is not returned at all.
+
+ client-error-not-possible: Same as Print-Job, in addition the
+ Printer object is not accepting any requests.
+ client-error-document-format-not-supported: not applicable.
+ client-error-attributes-or-values-not-supported: not
+ applicable.
+ client-error-uri-scheme-not-supported: not applicable.
+ client-error-attributes-or-values-not-supported: not
+ applicable, since unsupported operation attributes and/or
+ values MUST be ignored and an appropriate success code
+ returned (see above).
+ client-error-conflicting-attributes: not applicable
+ server-error-operation-not-supported: not applicable (since
+ Get-Job-Attributes is REQUIRED).
+ server-error-device-error: same as Print-Job, except no
+ document data is involved.
+ server-error-temporary-error: sane as Print-Job, except no
+ document data is involved..
+ server-error-not-accepting-jobs: not applicable.
+ server-error-job-canceled: not applicable.
+
+3.1.3.2.5 Hold-Job
+
+ All of the Print-Job status codes described in Section 3.1.3.1.1
+ Print-Job Response are applicable to Hold-Job with the following
+ specializations and differences. See Section 13 in [RFC2911] for a
+ more complete description of each status code.
+
+ For the following success status codes, the Job object is being held
+ or has been held:
+
+ successful-ok: no request attributes were substituted or
+ ignored (same as Print-Job).
+ successful-ok-ignored-or-substituted-attributes: same as
+ Print-Job.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 63]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ For any of the error status codes, the Job object has not been held
+ or was previously held.
+
+ client-error-not-possible: The request cannot be carried out
+ because of the state of the Job object ('completed',
+ 'canceled', or 'aborted') or the state of the system.
+ client-error-not-found: the target Printer and/or Job object
+ does not exist.
+ client-error-gone: the target Printer and/or Job object no
+ longer exists and no forwarding address is known.
+ client-error-request-entity-too-large: same as Print-Job,
+ except no document data is involved.
+ client-error-document-format-not-supported: not applicable.
+ client-error-conflicting-attributes: same as Print-Job, except
+ that the Printer's "printer-is-accepting-jobs" attribute is
+ not involved.
+ server-error-operation-not-supported: the Hold-Job operation is
+ not supported.
+ server-error-device-error: not applicable.
+ server-error-temporary-error: same as Print-Job, except no
+ document data is involved.
+ server-error-not-accepting-jobs: not applicable.
+ server-error-job-canceled: not applicable.
+
+3.1.3.2.6 Release-Job
+
+ All of the Print-Job status code descriptions in Section 3.1.3.1.1
+ Print-Job Response with the specialization's described for Hold-Job
+ are applicable to Release-Job. See Section 13 in [RFC2911] for a
+ more complete description of each status code.
+
+ server-error-operation-not-supported: the Release-Job operation
+ is not supported.
+
+3.1.3.2.7 Restart-Job
+
+ All of the Print-Job status code descriptions in Section 3.1.3.1.1
+ Print-Job Response with the specialization's described for Hold-Job
+ are applicable to Restart-Job. See Section 13 in [RFC2911] for a
+ more complete description of each status code.
+
+ server-error-operation-not-supported: the Restart-Job operation
+ is not supported.
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 64]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+3.1.3.2.7.1 Can documents be added to a restarted job?
+ Assume I give a Create-Job request along with a set of 5 documents .
+ All the documents get printed and the job state is moved to completed
+ . I issue a Restart-Job request on the job. Now the issue is that, if
+ I try to add new documents to the restarted job, will the IPP Server
+ permit me to do so or return "client-error-not-possible " and again
+ print those 5 jobs?
+
+ A job can not move to the 'completed' state until all the documents
+ have been processed. The 'last-document' flag indicates when the
+ last document for a job is being sent from the client. This is the
+ semantic equivalent of closing a job. No documents may be added once
+ a job is closed. Section 3.3.7 of the IPP/1.1 model states "The job
+ is moved to the 'pending' job state and restarts the beginning on the
+ same IPP Printer object with the same attribute values." 'number-of-
+ documents' is a job attribute.
+
+
+3.1.4 Returning unsupported attributes in Get-Xxxx responses (Issue
+ 1.18)
+
+ In the Get-Printer-Attributes, Get-Jobs, or Get-Job-Attributes
+ responses, the client cannot depend on getting unsupported attributes
+ returned in the Unsupported Attributes group that the client
+ requested, but are not supported by the IPP object. However, such
+ unsupported requested attributes will not be returned in the Job
+ Attributes or Printer Attributes group (since they are unsupported).
+ Furthermore, the IPP object is REQUIRED to return the 'successful-ok-
+ ignored-or-substituted-attributes' status code, so that the client
+ knows that not all that was requested has been returned.
+
+
+3.1.5 Sending empty attribute groups
+
+ The [RFC2911] and [RFC2910] specifications RECOMMEND that a sender
+ not send an empty attribute group in a request or a response.
+ However, they REQUIRE a receiver to accept an empty attribute group
+ as equivalent to the omission of that group. So a client SHOULD omit
+ the Job Template Attributes group entirely in a create operation that
+ is not supplying any Job Template attributes. Similarly, an IPP
+ object SHOULD omit an empty Unsupported Attributes group if there are
+ no unsupported attributes to be returned in a response.
+
+ The [RFC2910] specification REQUIRES a receiver to be able to receive
+ either an empty attribute group or an omitted attribute group and
+ treat them equivalently. The term "receiver" means an IPP object for
+ a request and a client for a response. The term "sender' means a
+ client for a request and an IPP object for a response.
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 65]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ There is an exception to the rule for Get-Jobs when there are no
+ attributes to be returned. [RFC2910] contains the following
+ paragraph:
+
+ The syntax allows an xxx-attributes-tag to be present when the xxx-
+ attribute-sequence that follows is empty. The syntax is defined this
+ way to allow for the response of Get-Jobs where no attributes are
+ returned for some job-objects. Although it is RECOMMENDED that the
+ sender not send an xxx-attributes-tag if there are no attributes
+ (except in the Get-Jobs response just mentioned), the receiver MUST
+ be able to decode such syntax.
+
+
+3.2 Printer Operations
+
+
+3.2.1 Print-Job operation
+
+
+3.2.1.1 Flow controlling the data portion of a Print-Job request
+ (Issue 1.22)
+
+ A paused printer, or one that is stopped due to paper out or jam or
+ spool space full or buffer space full, may flow control the data of a
+ Print-Job operation (at the TCP/IP layer), so that the client is not
+ able to send all the document data. Consequently, the Printer will
+ not return a response until the condition is changed.
+
+ The Printer should not return a Print-Job response with an error code
+ in any of these conditions, since either the printer will be resumed
+ and/or the condition will be freed either by human intervention or as
+ jobs print.
+
+ In writing test scripts to test IPP Printers, the script must also be
+ written not to expect a response, if the printer has been paused,
+ until the printer is resumed, in order to work with all possible
+ implementations.
+
+
+3.2.1.2 Returning job-state in Print-Job response (Issue 1.30)
+
+ An IPP client submits a small job via Print-Job. By the time the IPP
+ printer/print server is putting together a response to the operation,
+ the job has finished printing and been removed as an object from the
+ print system. What should the job-state be in the response?
+
+ The Model suggests that the Printer return a response before it even
+ accepts the document content. The Job Object Attributes are returned
+ only if the IPP object returns one of the success status codes. Then
+ the job-state would always be "pending" or "pending-held".
+
+
+Hastings, et al. Expires July 25, 2001 [page 66]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ This issue comes up for the implementation of an IPP Printer object
+ as a server that forwards jobs to devices that do not provide job
+ status back to the server. If the server is reasonably certain that
+ the job completed successfully, then it should return the job-state
+ as 'completed'. Also the server can keep the job in its "job
+ history" long after the job is no longer in the device. Then a user
+ could query the server and see that the job was in the 'completed'
+ state and completed as specified by the jobs "time-at-completed"
+ time, which would be the same as the server submitted the job to the
+ device.
+
+ An alternative is for the server to respond to the client before or
+ while sending the job to the device, instead of waiting until the
+ server has finished sending the job to the device. In this case, the
+ server can return the job's state as 'pending' with the 'job-
+ outgoing' value in the job's "job-state-reasons" attribute.
+
+ If the server doesn't know for sure whether the job completed
+ successfully (or at all), it could return the (out-of-band) 'unknown'
+ value.
+
+ On the other hand, if the server is able to query the device and/or
+ setup some sort of event notification that the device initiates when
+ the job makes state transitions, then the server can return the
+ current job state in the Print-Job response and in subsequent queries
+ because the server knows what the job state is in the device (or can
+ query the device).
+
+ All of these alternatives depend on implementation of the server and
+ the device.
+
+
+3.2.2 Get-Printer-Attributes operation
+
+ If a Printer supports the "printer-make-and-model" attribute and
+ returns the .INF file model name of the printer in that attribute,
+ the Microsoft client will automatically install the correct driver
+ (if available).
+
+ Clients which poll periodically for printer status or queued-job-
+ count should use the "requested-attributes" operation attribute to
+ limit the scope of the query in order to save Printer and network
+ resources.
+
+
+3.2.3 Get-Jobs operation
+
+
+3.2.3.1 Get-Jobs, my-jobs='true', and 'requesting-user-name' (Issue
+ 1.39)?
+
+
+Hastings, et al. Expires July 25, 2001 [page 67]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ In [RFC2911] section 3.2.6.1 'Get-Jobs Request', if the attribute
+ 'my-jobs' is present and set to TRUE, MUST the 'requesting-user-name'
+ attribute be there too, and if it's not present what should the IPP
+ printer do?
+
+ [RFC2911] Section 8.3 describes the various cases of "requesting-
+ user-name" being present or not for any operation. If the client
+ does not supply a value for "requesting-user-name", the printer MUST
+ assume that the client is supplying some anonymous name, such as
+ "anonymous".
+
+
+3.2.3.2 Why is there a "limit" attribute in the Get-Jobs operation?
+
+ When using the Get-Jobs operation a client implementer might choose
+ to limit the number of jobs that the client shows on the first
+ screenful. For example, if its UI can only display 50 jobs, it can
+ defend itself against a printer that would otherwise return 500 jobs,
+ perhaps taking a long time on a slow dial-up line. The client can
+ then go and ask for a larger number of jobs in the background, while
+ showing the user the first 50 jobs. Since the job history is returned
+ in reverse order, namely the most recently completed jobs are
+ returned first, the user is most likely interested in the first jobs
+ that are returned. Limiting the number of jobs may be especially
+ useful for a client that is requesting 'completed' jobs from a
+ printer that keeps a long job history. Clients that don't mind
+ sometimes getting very large responses, can omit the "limit"
+ attribute in their Get-Jobs requests.
+
+
+3.2.4 Create-Job operation
+
+ A Printer may respond to a Create-Job operation with "job-state"
+ 'pending' or 'pending-held' and " job-state-reason" 'job-data-
+ insufficient' to indicate that operation has been accepted by the
+ Printer, but the Printer is expecting additional document data before
+ it can move the job into the 'processing' state. Alternatively, it
+ may respond with "job-state" 'processing' and "job-state-reason"
+ 'job-incoming' to indicate that the Create-Job operation has been
+ accepted by the Printer, but the Printer is expecting additional
+ Send-Document and/or Send-URI operations and/or is
+ accessing/accepting document data. The second alternative is for
+ non-spooling Printers that don't implement the 'pending' state.
+
+ Should the server wait for the "last-document" operation attribute
+ set to 'true' before starting to "process" the job?
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 68]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ It depends on implementation. Some servers spool the entire job,
+ including all document data, before starting to process, so such an
+ implementation would wait for the "last-document" before starting to
+ process the job. If the time-out occurs without the "last-document",
+ then the server takes one of the indicated actions in section 3.3.1
+ in the [RFC2911] document. Other servers will start to process
+ document data as soon as they have some. These are the so-called
+ "non-spooling" printers. Currently, there isn't a way for a client to
+ determine whether the Printer will spool all the data or will start
+ to process (and print) as soon as it has some data.
+
+
+3.3 Job Operations
+
+
+3.3.1 Validate-Job
+
+ The Validate-Job operation has been designed so that its
+ implementation may be a part of the Print-Job operation. Therefore,
+ requiring Validate-Job is not a burden on implementers. Also it is
+ useful for client's to be able to count on its presence in all
+ conformance implementations, so that the client can determine before
+ sending a long document, whether the job will be accepted by the IPP
+ Printer or not.
+
+
+3.3.2 Restart-Job
+
+ The Restart-Job operation allows the reprocessing of a completed job.
+ Some jobs store the document data on the printer. Jobs created using
+ the Print-Job operation are an example. It is required that the
+ printer retains the job data after the job has moved to a 'completed
+ state' in order for the Restart-Job operation to succeed.
+
+ Some jobs contain only a reference to the job data. A job created
+ using the Print-URI is an example of such a job. When the Restart-
+ Job operation is issued the job is reprocessed. The job data MUST be
+ retrieved again to print the job.
+
+ It is possible that a job fails while attempting to access the print
+ data. When such a job is the target of a Restart-Job the Printer
+ SHALL attempt to retrieve the job data again.
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 69]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+4 Object Attributes
+
+
+4.1 Attribute Syntax's
+
+
+4.1.1 The 'none' value for empty sets (Issue 1.37)
+
+ [RFC2911] states that the 'none' value should be used as the value of
+ a 1setOf when the set is empty. In most cases, sets that are
+ potentially empty contain keywords so the keyword 'none' is used, but
+ for the 3 finishings attributes, the values are enums and thus the
+ empty set is represented by the enum 3. Currently there are no other
+ attributes with 1setOf values, which can be empty and can contain
+ values that are not keywords. This exception requires special code
+ and is a potential place for bugs. It would have been better if we
+ had chosen an out-of-band value, either "no-value" or some new value,
+ such as 'none'. Since we didn't, implementations have to deal with
+ the different representations of 'none', depending on the attribute
+ syntax.
+
+
+4.1.2 Multi-valued attributes (Issue 1.31)
+
+ What is the attribute syntax for a multi-valued attribute? Since
+ some attributes support values in more than one data type, such as
+ "media", "job-hold-until", and "job-sheets", IPP semantics associate
+ the attribute syntax with each value, not with the attribute as a
+ whole. The protocol associates the attribute syntax tag with each
+ value. Don't be fooled, just because the attribute syntax tag comes
+ before the attribute keyword. All attribute values after the first
+ have a zero length attribute keyword as the indication of a
+ subsequent value of the same attribute.
+
+
+4.1.3 Case Sensitivity in URIs (issue 1.6)
+
+ IPP client and server implementations must be aware of the diverse
+ uppercase/lowercase nature of URIs. RFC 2396 defines URL schemes and
+ Host names as case insensitive but reminds us that the rest of the
+ URL may well demonstrate case sensitivity. When creating URL's for
+ fields where the choice is completely arbitrary, it is probably best
+ to select lower case. However, this cannot be guaranteed and
+ implementations MUST NOT rely on any fields being case-sensitive or
+ case-insensitive in the URL beyond the URL scheme and host name
+ fields.
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 70]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ The reason that the IPP specification does not make any restrictions
+ on URIs, is so that implementations of IPP may use off-the-shelf
+ components that conform to the standards that define URIs, such as
+ RFC 2396 and the HTTP/1.1 specifications [RFC2616]. See these
+ specifications for rules of matching, comparison, and case-
+ sensitivity.
+
+ It is also recommended that System Administrators and implementations
+ avoid creating URLs for different printers that differ only in their
+ case. For example, don't have Printer1 and printer1 as two different
+ IPP Printers.
+
+ Example of equivalent URI's
+
+ http://abc.com:80/~smith/home.html
+
+ http://ABC.com/%7Esmith/home.html
+
+ http:/ABC.com:/%7esmith/home.html
+
+ Example of equivalent URI's using the IPP scheme
+
+ ipp://abc.com:631/~smith/home.html
+
+ ipp://ABC.com/%7Esmith/home.html
+
+ http:/ABC.com:631/%7esmith/home.html
+
+ The HTTP/1.1 specification [RFC2616] contains more details on
+ comparing URLs.
+
+
+4.1.4 Maximum length for xxxWithLanguage and xxxWithoutLanguage
+
+ The 'textWithLanguage' and 'nameWithLanguage' are compound syntaxes
+ that have two components. The first component is the 'language'
+ component that can contain up to 63 octets. The second component is
+ the 'text' or 'name' component. The maximum length of these are 1023
+ octets and 255 octets respectively. The definition of attributes
+ with either syntax may further restrict the length. (e.g. printer-
+ name (name(127)))
+
+ The length of the 'language' component has no effect on the allowable
+ length of 'text' in 'textWithLanguage' or the length of 'name' in
+ 'nameWithLanguage'
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 71]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+4.2 Job Template Attributes
+
+
+4.2.1 multiple-document-handling(type2 keyword)
+
+
+4.2.1.1 Support of multiple document jobs
+
+ IPP/1.0 is silent on which of the four effects an implementation
+ would perform if it supports Create-Job, but does not support
+ "multiple-document-handling" or multiple documents per job. IPP/1.1
+ was changed so that a Printer could support Create-Job without having
+ to support multiple document jobs. The "multiple-document-jobs-
+ supported" (boolean) Printer description attribute was added to
+ IPP/1.1 along with the 'server-error-multiple-document-jobs-not-
+ supported' status code for a Printer to indicate whether or not it
+ supports multiple document jobs, when it supports the Create-Job
+ operation. Also IPP/1.1 was clarified that the Printer MUST support
+ the "multiple-document-handling" (type2 keyword) Job Template
+ attribute with at least one value if the Printer supports multiple
+ documents per job.
+
+
+4.3 Job Description Attributes
+
+
+4.3.1 Getting the date and time of day
+
+ The "date-time-at-creation", "date-time-at-processing", and "date-
+ time-at-completed" attributes are returned as dateTime syntax.
+ These attributes are OPTIONAL for a Printer to support. However,
+ there are various ways for a Printer to get the date and time of day.
+ Some suggestions:
+
+ 1. A Printer can get time from an NTP timeserver if there's one
+ reachable on the network . See RFC 1305. Also DHCP option 32 in
+ RFC 2132 returns the IP address of the NTP server.
+
+ 2. Get the date and time at startup from a human operator
+
+ 3. Have an operator set the date and time using a web
+ administrative interface
+
+ 4. Get the date and time from incoming HTTP requests, though the
+ problems of spoofing need to be considered. Perhaps comparing
+ several HTTP requests could reduce the chances of spoofing.
+
+ 5. Internal date time clock battery driven.
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 72]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ 6. Query "http://tycho.usno.navy.mil/cgi-bin/timer.pl"
+
+
+
+4.4 Printer Description Attributes
+
+
+4.4.1 queued-job-count (integer(0:MAX))
+
+
+4.4.1.1 Why is "queued-job-count" RECOMMENDED (Issue 1.14)?
+
+ The reason that "queued-job-count" is RECOMMENDED, is that some
+ clients look at that attribute alone when summarizing the status of a
+ list of printers, instead of doing a Get-Jobs to determine the number
+ of jobs in the queue. Implementations that fail to support the
+ "queued-job-count" will cause that client to display 0 jobs when
+ there are actually queued jobs.
+
+ We would have made it a REQUIRED Printer attribute, but some
+ implementations had already been completed before the issue was
+ raised, so making it a SHOULD was a compromise.
+
+
+4.4.1.2 Is "queued-job-count" a good measure of how busy a printer is
+ (Issue 1.15)?
+
+ The "queued-job-count" is not a good measure of how busy the printer
+ is when there are held jobs. A future registration could be to add a
+ "held-job-count" (or an "active-job-count") Printer Description
+ attribute if experience shows that such an attribute (combination) is
+ needed to quickly indicate how busy a printer really is.
+
+
+4.4.2 printer-current-time (dateTime)
+
+ A Printer implementation MAY support this attribute by obtaining the
+ date and time by any number of implementation-dependent means at
+ startup or subsequently. Examples include:
+
+ 1. an internal date time clock,
+
+ 2. from the operator at startup using the console,
+
+ 3. from an operator using an administrative web page,
+
+ 4. from HTTP headers supplied in client requests,
+
+ 5. use HTTP to query "http://tycho.usno.navy.mil/cgi-bin/timer.pl"
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 73]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ 6. from the network, using NTP [RFC1305] or DHCP option 32
+ [RFC2132] that returns the IP address of the NTP server.
+
+ If an implementation supports this attribute by obtaining the current
+ time from the network (at startup or later), but the time is not
+ available, then the implementation MUST return the value of this
+ attribute using the out-of-band 'no-value' meaning not configured.
+ See the beginning of section 4.1.
+
+ Since the new "date-and-time-at-xxx" Job Description attributes refer
+ to the "printer-current-time", they will be covered also.
+
+
+4.4.3 Printer-uri
+
+ Must the operational attribute for printer-uri match one of the
+ values in "printer-uri-supported"?
+
+ A forgiving printer implementation would not reject the operation.
+ But the implementation has its rights to reject a printer or job
+ operation if the operational attribute printer-uri is not a value of
+ the printer-uri-supported. The printer might not be improperly
+ configured. The request obviously reached the printer. The printer
+ could treat the printer-uri as the logical equivalent of a value in
+ the printer-uri-supported. It would be implementation dependent for
+ which value, and associated security policy, would apply. This does
+ also apply to a job object specified with a printer-uri and job-id,
+ or with a job-uri. See section 4.1.3 for how to compare URI's.
+
+
+4.5 Empty Jobs
+
+ The IPP object model does not prohibit a job that contains no
+ documents. Such a job may be created in a number of ways including a
+ 'create-job' followed by an 'add-document' that contains no data and
+ has the 'last-document' flag set.
+
+ An empty job is processed just as any other job. The operation that
+ "closes" an empty job is not rejected because the job is empty. If
+ no other conditions exist, other than the job is empty, the response
+ to the operation will indicate success. After the job is scheduled
+ and processed, the job state SHALL be 'completed'.
+
+ There will be some variation in the value(s) of the "job-state-
+ reasons" attribute. It is required that if no conditions, other than
+ the job being empty, exist the "job-state-reasons" SHALL include the
+ 'completed-successfully'. If other conditions existed, the
+ 'completed-with-warnings' or 'completed-with-errors' values may be
+ used.
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 74]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+5 Directory Considerations
+
+
+5.1 General Directory Schema Considerations
+
+ The [RFC2911] document lists RECOMMENDED and OPTIONAL Printer object
+ attributes for directory schemas. See [RFC2911] APPENDIX E: Generic
+ Directory Schema.
+
+ The SLP printer template is defined in the "Definition of the Printer
+ Abstract Service Type v2.0" document [svrloc-printer]. The LDAP
+ printer template is defined in the "Internet Printing Protocol (IPP):
+ LDAP Schema for Printer Services" document [ldap-printer]. Both
+ documents systematically add "printer-" to any attribute that doesn't
+ already start with "printer-" in order to keep the printer directory
+ attributes distinct from other directory attributes. Also, instead
+ of using "printer-uri-supported", "uri-authentication-supported", and
+ "uri-security-supported", they use a "printer-xri-supported"
+ attribute with special syntax to contain all of the same information
+ in a single attribute.
+
+
+5.2 IPP Printer with a DNS name
+
+ If the IPP printer has a DNS name should there be at least two values
+ for the printer-uri-supported attribute. One URL with the fully
+ qualified DNS name the other with the IP address in the URL?
+
+ The printer may contain one or the other or both. It's up to the
+ administrator to configure this attribute.
+
+
+6 Security Considerations
+
+ This section corresponds to the RFC2911 Section 8 "Security
+ Considerations.
+
+
+6.1 Querying jobs with IPP that were submitted using other job
+ submission protocols (Issue 1.32)
+
+ The following clarification was added to [RFC2911] section 8.5:
+
+ 8.5 Queries on jobs submitted using non-IPP protocols
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 75]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ If the device that an IPP Printer is representing is able to accept
+ jobs using other job submission protocols in addition to IPP, it is
+ RECOMMEND that such an implementation at least allow such "foreign"
+ jobs to be queried using Get-Jobs returning "job-id" and "job-uri"
+ as 'unknown'. Such an implementation NEED NOT support all of the
+ same IPP job attributes as for IPP jobs. The IPP object returns
+ the 'unknown' out-of-band value for any requested attribute of a
+ foreign job that is supported for IPP jobs, but not for foreign
+ jobs.
+
+ It is further RECOMMENDED, that the IPP Printer generate "job-id"
+ and "job-uri" values for such "foreign jobs", if possible, so that
+ they may be targets of other IPP operations, such as Get-Job-
+ Attributes and Cancel-Job. Such an implementation also needs to
+ deal with the problem of authentication of such foreign jobs. One
+ approach would be to treat all such foreign jobs as belonging to
+ users other than the user of the IPP client. Another approach
+ would be for the foreign job to belong to 'anonymous'. Only if the
+ IPP client has been authenticated as an operator or administrator
+ of the IPP Printer object, could the foreign jobs be queried by an
+ IPP request. Alternatively, if the security policy were to allow
+ users to query other users' jobs, then the foreign jobs would also
+ be visible to an end-user IPP client using Get-Jobs and Get-Job-
+ Attributes.
+
+ Thus IPP MAY be implemented as a "universal" protocol that provides
+ access to jobs submitted with any job submission protocol. As IPP
+ becomes widely implemented, providing a more universal access makes
+ sense.
+
+
+7 Encoding and Transport
+
+ This section discusses various aspects of IPP/1.1 Encoding and
+ Transport [RFC2910].
+
+ A server is not required to send a response until after it has
+ received the client's entire request. Hence, a client must not
+ expect a response until after it has sent the entire request.
+ However, we recommend that the server return a response as soon as
+ possible if an error is detected while the client is still sending
+ the data, rather than waiting until all of the data is received.
+ Therefore, we also recommend that a client listen for an error
+ response that an IPP server MAY send before it receives all the data.
+ In this case a client, if chunking the data, can send a premature
+ zero-length chunk to end the request before sending all the data (and
+ so the client can keep the connection open for other requests, rather
+ than closing it). If the request is blocked for some reason, a client
+ MAY determine the reason by opening another connection to query the
+ server using Get-Printer-Attributes.
+
+
+Hastings, et al. Expires July 25, 2001 [page 76]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ IPP, by design, uses TCP's built-in flow control mechanisms [RFC 793]
+ to throttle clients when Printers are busy. Therefore, it is
+ perfectly normal for an IPP client transmitting a Job to be blocked
+ for a really long time. Accordingly, socket timeouts must be
+ avoided. Some socket implementations have a timeout option, which
+ specifies how long a write operation on a socket can be blocked
+ before it times out and the blocking ends. A client should set this
+ option for infinite timeout when transmitting Job submissions.
+
+ Some IPP client applications might be able to perform other useful
+ work while a Job transmission is blocked. For example, the client
+ may have other jobs that it could transmit to other Printers
+ simultaneously. A client may have a GUI, which must remain
+ responsive to the user while the Job transmission is blocked. These
+ clients should be designed to spawn a thread to handle the Job
+ transmission at its own pace, leaving the main application free to do
+ other work. Alternatively, single-threaded applications could use
+ non-blocking I/O.
+
+ Some Printer conditions, such as jam or lack of paper, could cause a
+ client to be blocked indefinitely. Clients may open additional
+ connections to the Printer to Get-Printer-Attributes, determine the
+ state of the device, alert a user if the printer is stopped, and let
+ a user decide whether to abort the job transmission or not.
+
+ In the following sections, there are tables of all HTTP headers,
+ which describe their use in an IPP client or server. The following
+ is an explanation of each column in these tables.
+
+ - the "header" column contains the name of a header
+ - the "request/client" column indicates whether a client sends the
+ header.
+ - the "request/ server" column indicates whether a server supports
+ the header when received.
+ - the "response/ server" column indicates whether a server sends
+ the header.
+ - the "response /client" column indicates whether a client
+ supports the header when received.
+ - the "values and conditions" column specifies the allowed header
+ values and the conditions for the header to be present in a
+ request/response.
+
+ The table for "request headers" does not have columns for responses,
+ and the table for "response headers" does not have columns for
+ requests.
+
+ The following is an explanation of the values in the "request/client"
+ and "response/ server" columns.
+
+ - must: the client or server MUST send the header,
+
+
+Hastings, et al. Expires July 25, 2001 [page 77]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ - must-if: the client or server MUST send the header when the
+ condition described in the "values and conditions" column is
+ met,
+ - may: the client or server MAY send the header
+ - not: the client or server SHOULD NOT send the header. It is not
+ relevant to an IPP implementation.
+
+
+ The following is an explanation of the values in the
+ "response/client" and "request/ server" columns.
+
+ - must: the client or server MUST support the header,
+ - may: the client or server MAY support the header
+ - not: the client or server SHOULD NOT support the header. It is
+ not relevant to an IPP implementation.
+
+7.1 General Headers
+
+ The following is a table for the general headers.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 78]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+
+
+ General- Request Response Values and Conditions
+ Header
+
+
+
+ Client Server Server Client
+
+
+ Cache- must not must not "no-cache" only
+ Control
+
+ Connection must- must must- must "close" only. Both
+ if if client and server SHOULD
+ keep a connection for
+ the duration of a
+ sequence of operations.
+ The client and server
+ MUST include this header
+ for the last operation
+ in such a sequence.
+
+ Date may may must may per RFC 1123 [RFC1123]
+ from RFC 2616 [RFC2616]
+
+ Pragma must not must not "no-cache" only
+
+ Transfer- must- must must- must "chunked" only . Header
+ Encoding if if MUST be present if
+ Content-Length is
+ absent.
+
+ Upgrade not not not not
+
+ Via not not not not
+
+
+7.2 Request Headers
+
+The following is a table for the request headers.
+
+
+ Request- Client Server Request Values and Conditions
+ Header
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 79]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+
+ Request- Client Server Request Values and Conditions
+ Header
+
+ Accept may must "application/ipp" only. This
+ value is the default if the client
+ omits it
+
+ Accept- not not Charset information is within the
+ Charset application/ipp entity
+
+ Accept- may must empty and per RFC 2616 [RFC2616]
+ Encoding and IANA registry for content-
+ codings
+
+ Accept- not not language information is within the
+ Language application/ipp entity
+
+ Authorization must- must per RFC 2616. A client MUST send
+ if this header when it receives a 401
+ "Unauthorized" response and does
+ not receive a "Proxy-
+ Authenticate" header.
+
+ From not not per RFC 2616. Because RFC
+ recommends sending this header
+ only with the user's approval, it
+ is not very useful
+
+ Host must must per RFC 2616
+
+ If-Match not not
+
+ If-Modified- not not
+ Since
+
+ If-None-Match not not
+
+ If-Range not not
+
+ If- not not
+ Unmodified-
+ Since
+
+ Max-Forwards not not
+
+ Proxy- must- not per RFC 2616. A client MUST send
+ Authorization if this header when it receives a 401
+ "Unauthorized" response and a
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 80]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+
+ Request- Client Server Request Values and Conditions
+ Header
+
+ "Proxy-Authenticate" header.
+
+ Range not not
+
+ Referrer not not
+
+ User-Agent not not
+
+
+7.3 Response Headers
+
+ The following is a table for the request headers.
+
+
+
+ Response- Server Client Response Values and Conditions
+ Header
+
+
+ Accept-Ranges not not
+
+ Age not not
+
+ Location must- may per RFC 2616. When URI needs
+ if redirection.
+
+ Proxy- not must per RFC 2616
+ Authenticate
+
+ Public may may per RFC 2616
+
+ Retry-After may may per RFC 2616
+
+ Server not not
+
+ Vary not not
+
+ Warning may may per RFC 2616
+
+ WWW- must- must per RFC 2616. When a server needs
+ Authenticate if to authenticate a client.
+
+
+7.4 Entity Headers
+
+The following is a table for the entity headers.
+
+
+Hastings, et al. Expires July 25, 2001 [page 81]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+
+ Entity-Header Request Response Values and
+ Conditions
+
+ Client Server Server Client
+
+ Allow not not not not
+
+ Content-Base not not not not
+
+ Content- may must must must per RFC 2616 and
+ Encoding IANA registry for
+ content codings.
+
+ Content- not not not not Application/ipp
+ Language handles language
+
+ Content- must- must must- must the length of the
+ Length if if message-body per
+ RFC 2616. Header
+ MUST be present if
+ Transfer-Encoding
+ is absent..
+
+ Content- not not not not
+ Location
+
+ Content-MD5 may may may may per RFC 2616
+
+ Content-Range not not not not
+
+ Content-Type must must must must "application/ipp"
+ only
+
+ ETag not not not not
+
+ Expires not not not not
+
+ Last-Modified not not not not
+
+
+7.5 Optional support for HTTP/1.0
+
+ IPP implementations consist of an HTTP layer and an IPP layer. In
+ the following discussion, the term "client" refers to the HTTP client
+ layer and the term "server" refers to the HTTP server layer. The
+ Encoding and Transport document [RFC2910] requires that HTTP 1.1 MUST
+ be supported by all clients and all servers. However, a client
+ and/or a server implementation may choose to also support HTTP 1.0.
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 82]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ This option means that a server may choose to communicate with a
+ (non-conforming) client that only supports HTTP 1.0. In such cases
+ the server should not use any HTTP 1.1 specific parameters or
+ features and should respond using HTTP version number 1.0.
+
+ This option also means that a client may choose to communicate with a
+ (non-conforming) server that only supports HTTP 1.0. In such cases,
+ if the server responds with an HTTP 'unsupported version number' to
+ an HTTP 1.1 request, the client should retry using HTTP version
+ number 1.0.
+
+
+7.6 HTTP/1.1 Chunking
+
+
+7.6.1 Disabling IPP Server Response Chunking
+
+ Clients MUST anticipate that the HTTP/1.1 server may chunk responses
+ and MUST accept them in responses. However, a (non-conforming) HTTP
+ client that is unable to accept chunked responses may attempt to
+ request an HTTP 1.1 server not to use chunking in its response to an
+ operation by using the following HTTP header:
+
+ TE: identity
+
+ This mechanism should not be used by a server to disable a client
+ from chunking a request, since chunking of document data is an
+ important feature for clients to send long documents.
+
+
+7.6.2 Warning About the Support of Chunked Requests
+
+ This section describes some problems with the use of chunked requests
+ and HTTP/1.1 servers.
+
+ The HTTP/1.1 standard [RFC2616] requires that conforming servers
+ support chunked requests for any method. However, in spite of this
+ requirement, some HTTP/1.1 implementations support chunked responses
+ in the GET method, but do not support chunked POST method requests.
+ Some HTTP/1.1 implementations that support CGI scripts [CGI] and/or
+ servlets [Servlet] require that the client supply a Content-Length.
+ These implementations might reject a chunked POST method and return a
+ 411 status code (Length Required), might attempt to buffer the
+ request and run out of room returning a 413 status code (Request
+ Entity Too Large), or might successfully accept the chunked request.
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 83]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ Because of this lack of conformance of HTTP servers to the HTTP/1.1
+ standard, the IPP standard [RFC2910] REQUIRES that a conforming IPP
+ Printer object implementation support chunked requests and that
+ conforming clients accept chunked responses. Therefore, IPP object
+ implementers are warned to seek HTTP server implementations that
+ support chunked POST requests in order to conform to the IPP standard
+ and/or use implementation techniques that support chunked POST
+ requests.
+
+
+8 References
+
+ [CGI]
+ CGI/1.1 (http://www.ietf.org/internet-drafts/draft-coar-cgi-v11-
+ 00.txt).
+
+ [ldap-printer]
+ Fleming, P., Jones, K., Lewis, H., McDonald, I., "Internet Printing
+ Protocol (IPP): LDAP Schema for Printer Services", <draft-ietf-ipp-
+ ldap-printer-schema-01.txt>, work in progress, April 27, 2000.
+
+ [RFC793]
+ J. Postel, "Transmission Control Protocol", RFC 793.
+
+ [RFC1123]
+ Braden, S., "Requirements for Internet Hosts - Application and
+ Support", RFC 1123, October, 1989.
+
+ [RFC2026]
+ S. Bradner, "The Internet Standards Process -- Revision 3", RFC
+ 2026, October 1996.
+
+ [RFC2119]
+ S. Bradner, "Key words for use in RFCs to Indicate Requirement
+ Levels", RFC 2119 , March 1997.
+
+ [RFC2396]
+ Berners-Lee, T., Fielding, R., Masinter, L., "Uniform Resource
+ Identifiers (URI): Generic Syntax", RFC 2396, August 1998.
+
+ [RFC2565]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell,
+ "Internet Printing Protocol/1.0: Model and Semantics", RFC 2566,
+ April 1999.
+
+ [RFC2566]
+ Herriot, R., Butler, S., Moore, P., Turner, R., "Internet Printing
+ Protocol/1.0: Encoding and Transport", RFC 2565, April 1999.
+
+ [RFC2567]
+
+
+Hastings, et al. Expires July 25, 2001 [page 84]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ Wright, D., "Design Goals for an Internet Printing Protocol",
+ draft-ietf-ipp-req-03.txt, November, 1998.
+
+ [RFC2568
+ Zilles, S., "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", RFC 2568, April 1999.
+
+ [RFC2569]
+ Herriot, R., Hastings, T., Jacobs, N., Martin, J., "Mapping between
+ LPD and IPP Protocols", RFC 2569, April 1999.
+
+ [RFC2616]
+ R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P.
+ Leach, T. Berners-Lee, "Hypertext Transfer Protocol - HTTP/1.1",
+ RFC 2616, June 1999.
+
+ [RFC2910]
+ Herriot, R., Butler, S., Moore, P., Turner, R., "Internet Printing
+ Protocol/1.0: Encoding and Transport", RFC 2910, September, 2000.
+
+ [RFC2911]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell,
+ "Internet Printing Protocol/1.0: Model and Semantics", RFC 2911,
+ September, 2000.
+
+ [Servlet]
+ Servlet Specification Version 2.1
+ (http://java.sun.com/products/servlet/2.1/index.html).
+
+
+ [svrloc-printer]
+ St. Pierre, P., Isaacson, S., McDonald, I., "Definition of the
+ Printer Abstract Service Type v2.0", <draft-ietf-svrloc-printer-
+ scheme-06.txt>, work in progress, March 8, 2000.
+
+ [SSL]
+ Netscape, The SSL Protocol, Version 3, (Text version 3.02),
+ November 1996.
+
+
+9 Authors' Address
+
+
+ Thomas N. Hastings
+ Xerox Corporation
+ 701 Aviation Blvd.
+ El Segundo, CA 90245
+ hastings@cp10.es.xerox.com
+
+ Carl-Uno Manros
+
+
+Hastings, et al. Expires July 25, 2001 [page 85]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ Xerox Corporation
+ 701 Aviation Blvd.
+ El Segundo, CA 90245
+ manros@cp10.es.xerox.com
+
+ Carl Kugler
+ Mail Stop 003G
+ IBM Printing Systems Co
+ 6300 Diagonal Hwy
+ Boulder CO 80301
+ Kugler@us.ibm.com
+
+ Henrik Holst
+ i-data Printing Systems
+ Vadstrupvej 35-43
+ 2880 Bagsvaerd, Denmark
+ hh@I-data.com
+
+
+ Peter Zehler
+ Xerox Corporation
+ 800 Philips Road
+ Webster, NY 14580
+ peter.zehler@usa.xerox.com
+
+10 Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 86]
+
+
+INTERNET-DRAFT IPP/1.1: Implementer's Guide January 25, 2001
+
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+ Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires July 25, 2001 [page 87]
diff --git a/standards/draft-ietf-ipp-indp-method-04.txt b/standards/draft-ietf-ipp-indp-method-04.txt
new file mode 100644
index 000000000..b87973fb2
--- /dev/null
+++ b/standards/draft-ietf-ipp-indp-method-04.txt
@@ -0,0 +1,1768 @@
+
+
+
+
+
+
+INTERNET-DRAFT Hugo Parra
+<draft-ietf-ipp-indp-method-04.txt> Novell, Inc.
+[Target Category: standards track] Tom Hastings
+ Xerox Corp.
+ February 28, 2001
+
+ Internet Printing Protocol (IPP):
+ The 'indp' Delivery Method for Event Notifications and Protocol/1.0
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of [RFC2026]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress".
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed as
+ http://www.ietf.org/shadow.html.
+
+Abstract
+
+ The IPP notification extension document [ipp-ntfy] defines operations
+ that a client can perform in order to create Subscription Objects in
+ a Printer and carry out other operations on them. The Subscription
+ Object specifies that when one of the specified Events occurs, the
+ Printer sends an asynchronous Event Notification to the specified
+ Notification Recipient via the specified Delivery Method (i.e.,
+ protocol).
+
+ The notification extension document [ipp-ntfy] specifies that each
+ Delivery Method is defined in another document. This document is one
+ such document, and it specifies the 'indp' Delivery Method and
+ Protocol. This Delivery Method is a simple protocol consisting of a
+ single operation: the Send-Notifications operation which uses the
+ same encoding and transport as IPP. This document defines version
+ '1.0' of the protocol.
+
+ For this Delivery Method, when an Event occurs, the Printer
+ immediately sends (pushes) an Event Notification via the Send-
+
+ Parra, Hastings Expires: August 28, 2001 [page 1]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ Notifications operation to the Notification Recipient specified in
+ the Subscription Object. The Event Notification content consists of
+ Machine Consumable attributes and a Human Consumable "notify-text"
+ attribute. The Notification Recipient returns a response to the
+ Printer.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 2]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics [RFC2911]
+ Internet Printing Protocol/1.1: Encoding and Transport [RFC2910]
+ Internet Printing Protocol/1.1: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+ Internet Printing Protocol (IPP): IPP Event Notification
+ Specification [ipp-ntfy]
+
+ The "Design Goals for an Internet Printing Protocol" document takes a
+ broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. A few OPTIONAL operator operations have
+ been added to IPP/1.1.
+
+ The "Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol" document describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specification documents, and gives background and rationale
+ for the IETF working group's major decisions.
+
+ The "Internet Printing Protocol/1.1: Model and Semantics" document
+ describes a simplified model with abstract objects, their attributes,
+ and their operations that are independent of encoding and transport.
+ It introduces a Printer and a Job object. The Job object optionally
+ supports multiple documents per Job. It also addresses security,
+ internationalization, and directory issues.
+
+ The "Internet Printing Protocol/1.1: Encoding and Transport" document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1 [RFC2616]. It defines the
+ encoding rules for a new Internet MIME media type called
+ "application/ipp". This document also defines the rules for
+ transporting a message body over HTTP whose Content-Type is
+ "application/ipp". This document defines a new scheme named 'ipp'
+ for identifying IPP printers and jobs.
+
+ The "Internet Printing Protocol/1.1: Implementer's Guide" document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.1 and some of
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+Parra, Hastings Expires: August 28, 2001 [page 3]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ The "Mapping between LPD and IPP Protocols" document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+ The "Internet Printing Protocol (IPP): IPP Event Notification
+ Specification" document defines the semantics for Subscription
+ Creation Operations and the requirements for other Delivery Method
+ documents to define a Delivery Method to carry an Event Notifications
+ to a Notification Recipient.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 4]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+
+
+Table of Contents
+
+
+ 1 Introduction....................................................7
+
+ 2 Terminology.....................................................7
+
+ 3 Model and Operation.............................................8
+
+ 4 General Information.............................................9
+
+ 5 Subscription object attributes.................................12
+ 5.1 Subscription Template Attribute Conformance.................12
+ 5.2 Additional Information about Subscription Template Attributes12
+ 5.2.1 notify-recipient-uri (uri)................................12
+ 5.3 Subscription Description Attribute Conformance..............12
+
+ 6 Printer Description Attributes.................................12
+ 6.1 Printer Description Attribute Conformance...................13
+ 6.2 New Values for Existing Printer Description Attributes......13
+ 6.2.1 notify-schemes-supported (1setOf uriScheme)...............13
+ 6.2.2 operations-supported (1setOf type2 enum)..................13
+
+ 7 Attributes Only in Event Notifications.........................13
+
+ 8 Operations for Notification....................................14
+ 8.1 Send-Notifications operation................................14
+ 8.1.1 Send-Notifications Request................................14
+ 8.1.2 Send-Notifications Response...............................18
+
+ 9 Status Codes...................................................19
+ 9.1 Additional Status Codes.....................................19
+ 9.1.1 successful-ok-ignored-notifications (0x0004)..............20
+ 9.1.2 client-error-ignored-all-notifications (0x0416)...........20
+ 9.2 Status Codes returned in Event Notification Attributes Groups20
+ 9.2.1 client-error-not-found (0x0406)...........................20
+ 9.2.2 successful-ok-but-cancel-subscription (0x0006)............20
+
+ 10 Encoding and Transport.........................................21
+ 10.1 Encoding of the Operation Layer.............................21
+ 10.2 Encoding of Transport Layer.................................21
+
+ 11 Conformance Requirements.......................................21
+ 11.1 Conformance Requirements for Printers.......................21
+ 11.2 Conformance Requirements for INDP Notification Recipients...22
+
+ 12 INDP URL Scheme................................................23
+ 12.1 INDP URL Scheme Applicability and Intended Usage............23
+
+Parra, Hastings Expires: August 28, 2001 [page 5]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ 12.2 INDP URL Scheme Associated INDP Port........................23
+ 12.3 INDP URL Scheme Associated MIME Type........................23
+ 12.4 INDP URL Scheme Character Encoding..........................23
+ 12.5 INDP URL Scheme Syntax in ABNF..............................23
+ 12.5.1 INDP URL Examples.........................................24
+ 12.5.2 INDP URL Comparisons......................................25
+
+ 13 IANA Considerations............................................26
+ 13.1 Operation Registrations.....................................26
+ 13.2 Additional values of existing attributes....................26
+ 13.2.1 Additional values for the "notify-schemes-supported" Printer
+ attribute..............................................26
+ 13.2.2 Additional values for the "operations-supported" Printer
+ attribute..............................................27
+ 13.3 Status code Registrations...................................27
+
+ 14 Internationalization Considerations............................27
+
+ 15 Security Considerations........................................28
+ 15.1 Security Conformance........................................28
+
+ 16 References.....................................................28
+
+ 17 Author's Addresses.............................................30
+
+ 18 Full Copyright Statement.......................................30
+
+
+Tables
+
+ Table 1 - Information about the Delivery Method...................10
+ Table 2 - Operation-id assignments................................13
+ Table 3 - Attributes in Event Notification Content................16
+ Table 4 - Additional Attributes in Event Notification Content for Job
+ Events ........................................................17
+ Table 5 - Combinations of Events and Subscribed Events for "job-
+ impressions-completed" ........................................17
+ Table 6 - Additional Attributes in Event Notification Content for
+ Printer Events ................................................18
+ Table 7 - The "event-notification-attributes-tag" value...........21
+
+
+
+
+
+
+
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 6]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+
+
+
+1 Introduction
+
+ The notification extension document [ipp-ntfy] defines operations
+ that a client can perform in order to create Subscription Objects in
+ a Printer and carry out other operations on them. A Subscription
+ Object represents a Subscription abstraction. The Subscription Object
+ specifies that when one of the specified Events occurs, the Printer
+ sends an asynchronous Event Notification to the specified
+ Notification Recipient via the specified Delivery Method (i.e.,
+ protocol).
+
+ The notification extension document [ipp-ntfy] specifies that each
+ Delivery Method is defined in another document. This document is one
+ such document, and it specifies the 'indp' Delivery Method. This
+ Delivery Method is a simple protocol consisting of a single
+ operation: the Send-Notifications operation which uses the same
+ encoding and transport as IPP. This document defines version '1.0'
+ of the protocol.
+
+ For the 'indp' Delivery Method, an IPP Printer sends (pushes) a Send-
+ Notifications operation request containing one or more Event
+ Notifications to the Notification Recipient specified in the
+ Subscription Object. The Event Notification content consists of
+ Machine Consumable attributes and a Human Consumable "notify-text"
+ attribute.
+
+ The Notification Recipient receives the Event Notification as a Send-
+ Notifications operation, in the same way as an IPP Printer receives
+ IPP operations. The Notification Recipient returns a response to the
+ Printer.
+
+
+2 Terminology
+
+ This section defines the following terms that are used throughout
+ this document:
+
+ Terms such as attributes, keywords, and support. These terms have
+ special meaning and are defined in the model terminology
+ [RFC2911] section 12.2.
+
+ Capitalized terms, such as MUST, MUST NOT, REQUIRED, SHOULD,
+ SHOULD NOT, MAY, NEED NOT, and OPTIONAL, have special
+ meaning relating to conformance as specified in RFC 2119
+ [RFC2119] and [RFC2911] section 12.1. These terms refer to
+ conformance to this document, if this document is
+ implemented.
+
+Parra, Hastings Expires: August 28, 2001 [page 7]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ Capitalized terms, such as Notification Recipient, Event
+ Notification, Printer, etc., that are defined in [ipp-ntfy]
+ with the same meanings and are not reproduced here.
+
+ Event Notification Attributes Group - The attributes group in a
+ request that contains Event Notification Attributes in a
+ request or response.
+
+
+3 Model and Operation
+
+ See [ipp-ntfy] for the description of the Event Notification Model
+ and Operation. This Delivery Method takes advantage of combining
+ several Event Notifications into a single Compound Event Notification
+ that is delivery by a single Send-Notification operation to a single
+ Notification Recipient.
+
+ When creating each Subscription object, the client supplies the
+ "notify-recipient" (uri) Subscription Template attribute. The
+ "notify-recipient" attribute specifies both a single Notification
+ Recipient that is to receive the Notifications when subsequent events
+ occur and the method for notification delivery that the IPP Printer
+ is to use. For the Notification Delivery Method defined in this
+ document, the notification method is 'indp' and the rest of the URI
+ is the address of the Notification Recipient to which the IPP Printer
+ will send the Send-Notifications operation.
+
+ The 'indp' Notification Delivery Method defined in this document uses
+ a client/server protocol paradigm. The "client" in this relationship
+ is the Printer described in [ipp-ntfy] while the "server" is the
+ Notification Recipient. The Printer invokes the Send-Notifications
+ operation to communicate IPP Event Notification contents to the
+ Notification Recipient. The Notification Recipient only conveys
+ information to the Printer in the form of responses to the operations
+ initiated by the Printer.
+
+ Printers that implement the 'indp' Notification Delivery Method will
+ need to include an HTTP client stack while Notification Recipients
+ that implement this Delivery Method will need to support an HTTP
+ server stack. See section 10.2 for more details.
+
+ If the client wants the Printer to send Event Notifications via the
+ 'indp' Delivery Method, the client MUST choose a value for "notify-
+ recipient-uri" attribute which conforms to the rules of section
+ 5.2.1.
+
+ When an Event occurs, the Printer MUST immediately:
+
+ 1.Find all pertinent Subscription Objects P according to the rules of
+ section 9 of [ipp-ntfy], AND
+
+Parra, Hastings Expires: August 28, 2001 [page 8]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ 2.Find the subset M of these Subscription Objects P whose "notify-
+ recipient-uri" attribute has a scheme value of 'indp', AND
+
+ 3.For each Subscription Object in M, the Printer MUST
+
+ a)generate a Send-Notifications request as specified in section
+ 8.1.1 AND
+
+ b)send the Send-Notifications request to the Notification
+ Recipient specified by the address part of the "notify-
+ recipient-uri" attribute value (see section 5.2.1).
+
+ If several events occur sufficiently close to one another for the
+ same or different Subscription objects, but with the same
+ Notification Recipient, the Printer MAY combine them into a single
+ Send-Notifications request using a separate Event Notification
+ Attributes group for each event (see section 8.1.1).
+
+
+4 General Information
+
+ If a Printer supports this Delivery Method, Table 1 lists its
+ characteristics.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 9]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ Table 1 - Information about the Delivery Method
+
+
+ Document Method conformance 'indp' realization
+ requirement
+
+
+ 1. What is the URL scheme name indp
+ for the Delivery Method?
+
+ 2. Is the Delivery Method is RECOMMENDED
+ REQUIRED, RECOMMENDED, or
+ OPTIONAL for an IPP Printer to
+ support?
+
+ 3. What transport and delivery A Printer MUST support a
+ protocol does the Printer use complete HTTP/1.1 stack
+ to deliver the Event [RFC2616]
+ Notification content, i.e.,
+ what is the entire network
+ stack?
+
+ 4. Can several Event A Printer implementation MAY
+ Notifications be combined into combine several Event
+ a Compound Event Notification? Notifications into a single
+ Event Notifications request as
+ separate Event Notification
+ Attributes Groups, see section
+ 8.1.1
+
+ 5. Is the Delivery Method This Delivery Method is a push.
+ initiated by the Notification
+ Recipient (pull), or by the
+ Printer (push)?
+
+ 6. Is the Event Notification Machine Consumable with the
+ content Machine Consumable or "notify-text" attribute being
+ Human Consumable? Human Consumable
+
+ 7. What section in this document The representation and encoding
+ answers the following is the same as IPP. See
+ question? For a Machine section 8.1.1
+ Consumable Event Notification,
+ what is the representation and
+ encoding of values defined in
+ section 9.1 of [ipp-ntfy] and
+ the conformance requirements
+ thereof? For a Human
+ Consumable Event Notification,
+
+
+Parra, Hastings Expires: August 28, 2001 [page 10]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+
+ Document Method conformance 'indp' realization
+ requirement
+
+
+ what is the representation and
+ encoding of pieces of
+ information defined in section
+ 9.2 of [ipp-ntfy] and the
+ conformance requirements
+ thereof?
+
+ 8. What are the latency and
+ reliability of the transport itselfs(see [RFC2911]).IPP/1.1
+ and delivery protocol?
+
+ 9. What are the security aspects 15
+ of the transport and delivery
+ protocol, e.g., how it is See section
+ handled in firewalls?
+
+ 10. What are the content length They are the same as for
+ restrictions? IPP/1.0 and IPP/1.1 itself (see
+ [RFC2911]).
+
+ 11. What are the additional values A new Event Notifications
+ or pieces of information that attribute group (see section
+ a Printer sends in an Event 10.1) and additional status
+ Notification and the codes for use in the response
+ conformance requirements (see section 9)
+ thereof?
+
+ 12. What are the additional None
+ Subscription Template and/or
+ Subscription Description
+ attributes and the conformance
+ requirements thereof?
+
+ 13. What are the additional None
+ Printer Description attributes
+ and the conformance
+ requirements thereof?
+
+
+ The remaining sections of this document parallel the sections of
+ [ipp-ntfy].
+
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 11]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+5 Subscription object attributes
+
+ This section defines the Subscription object conformance requirements
+ for Printers.
+
+
+5.1 Subscription Template Attribute Conformance
+
+ The 'indp' Delivery Method has the same conformance requirements for
+ Subscription Template attributes as defined in [ipp-ntfy]. The
+ 'indp' Delivery Method does not define any addition Subscription
+ Template attributes.
+
+
+5.2 Additional Information about Subscription Template Attributes
+
+ This section defines additional information about Subscription
+ Template attributes defined in [ipp-ntfy].
+
+
+5.2.1 notify-recipient-uri (uri)
+
+ This section describes the syntax of the value of this attribute for
+ the 'indp' Delivery Method. The syntax for values of this attribute
+ for other Delivery Method is defined in other Delivery Method
+ Documents.
+
+ In order to support the 'indp' Delivery Method and Protocol, the
+ Printer MUST support the following syntax:
+
+ The 'indp://' URI scheme. The remainder of the URI indicates
+ the host name or host address (and optional path) of the
+ Notification Recipient that is to receive the Send-
+ Notification operation.
+
+
+5.3 Subscription Description Attribute Conformance
+
+ The 'indp' Delivery Method has the same conformance requirements for
+ Subscription Description attributes as defined in [ipp-ntfy]. The
+ 'indp' Delivery Method does not define any addition Subscription
+ Description attributes.
+
+
+6 Printer Description Attributes
+
+ This section defines the Printer Description Attributes conformance
+ requirements for Printers.
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 12]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+6.1 Printer Description Attribute Conformance
+
+ The 'indp' Delivery Method has the same conformance requirements for
+ Printer Description attributes as defined in [ipp-ntfy]. The 'indp'
+ Delivery Method does not define any addition Printer Description
+ attributes.
+
+
+6.2 New Values for Existing Printer Description Attributes
+
+ This section defines additional values for existing Printer
+ Description attributes.
+
+
+6.2.1 notify-schemes-supported (1setOf uriScheme)
+
+ The following "notify-schemes-supported" value is added in order to
+ support the new Delivery Method defined in this document:
+
+ 'indp' - The IPP Notification Delivery Method defined in this
+ document.
+
+6.2.2 operations-supported (1setOf type2 enum)
+
+ Table 2 lists the "operation-id" value added in order to support the
+ new operation defined in this document. The operation-id is assigned
+ in the same name space as other operations that a Printer supports.
+ However, a Printer MUST NOT include this value in its "operations-
+ supported" attribute unless it can accept the Send-Notifications
+ request.
+
+ Table 2 - Operation-id assignments
+
+
+ Value Operation Name
+
+
+ 0x001D Send-Notifications
+
+
+
+
+7 Attributes Only in Event Notifications
+
+ No additional attributes are defined only for use in Event
+ Notifications besides those defined in [ipp-ntfy].
+
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 13]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+8 Operations for Notification
+
+ This section defines the operation for Event Notification using the
+ 'indp' Delivery Method.
+
+ There is only one operation defined: Send-Notifications. Section
+ 6.2.2 assigns of the "operation-id" for the Send-Notifications
+ operation and the following section defined the operation.
+
+
+8.1 Send-Notifications operation
+
+ This REQUIRED operation allows a Printer to send one or more Event
+ Notifications to a Notification Recipient using HTTP.
+
+ The Printer composes the information defined for an IPP Notification
+ [ipp-ntfy] and sends it using the Sent-Notifications operation to the
+ Notification Recipient supplied in the Subscription object.
+
+ The Send-Notifications operations uses the operations model defined
+ by IPP [RFC2566]. This includes, the use of a URI as the identifier
+ for the target of each operation, the inclusion of a version number,
+ operation-id, and request-id in each request, and the definition of
+ attribute groups. The Send-Notifications operation uses the Operation
+ Attributes group, but currently has no need for the Unsupported
+ Attributes, Printer Object Attributes, and Job-Object Attributes
+ groups. However, it uses a new attribute group, the Event
+ Notification Attributes group.
+
+ The Notification Recipient MUST accept the request in any state.
+ There is no state defined for the Notification Recipient for this
+ Delivery Method.
+
+ Access Rights: Notification Recipient MAY enforce access rights. If
+ the Printer receives a rejection with these status codes: 'client-
+ error-forbidden', 'client-error-not-authenticated', or 'client-error-
+ not-authorized' status code , the Printer SHOULD cancel the
+ subscription.
+
+
+8.1.1 Send-Notifications Request
+
+ Every operation request MUST contains the following parameters (see
+ [RFC2911] section 3.1.1):
+
+ - a "version-number" '1.0' - the version of the 'indp'
+ protocol is '1.0'.
+ - an "operation-id" - the value defined in Table 2
+ - a "request-id" - the request id (see [RFC2911] section 3.1.2).
+
+
+Parra, Hastings Expires: August 28, 2001 [page 14]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ The following groups of attributes MUST be part of the Send-
+ Notifications Request:
+
+
+ Group 1: Operation Attributes
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as defined in [RFC2911] section 3.1.4.1.
+
+ The Printer MUST use the values of "notify-charset" and
+ "notify-natural-language", respectively, from one Subscription
+ Object associated with the Event Notifications in this request.
+
+ Normally, there is only one matched Subscription Object, or the
+ value of the "notify-charset" and "notify-natural-language"
+ attributes is the same in all Subscription Objects. If not, the
+ Printer MUST pick one Subscription Object from which to obtain
+ the value of these attributes. The algorithm for picking the
+ Subscription Object is implementation dependent. The choice of
+ natural language is not critical because 'text' and 'name'
+ values can override the "attributes-natural-language" Operation
+ attribute. The Printer's choice of charset is critical because
+ a bad choice may leave it unable to send some 'text' and 'name'
+ values accurately.
+
+ Target:
+ A copy of the Subscription object's "notify-recipient-uri"
+ (uri) attribute which is the target of this operation as
+ described in [RFC2911] section 3.1.5, i.e., the URI of the
+ 'indp' Notification Recipient (see section 5.2.1).
+
+ Group 2 to N: Event Notification Attributes
+
+ In each group 2 to N, each attribute is encoded using the IPP
+ rules for encoding attributes [RFC2910] and may be encoded in
+ any order. Note: the Get-Jobs response in [RFC2911] acts as a
+ model for encoding multiple groups of attributes.
+
+ Each Event Notification Group MUST contain all of attributes
+ specified in [ipp-ntfy] section 9.1 ("Content of Machine
+ Consumable Event Notifications") with exceptions denoted by
+ asterisks in the tables below.
+
+ The tables below are copies of the tables in [ipp-ntfy] section
+ 9.1 ("Content of Machine Consumable Event Notifications")
+ except that each cell in the "Sends" column is a "MUST".
+
+ For an Event Notification for all Events, the Printer sends the
+ following attributes.
+
+
+Parra, Hastings Expires: August 28, 2001 [page 15]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ Table 3 - Attributes in Event Notification Content
+
+
+ Source Value Sends Source Object
+
+
+ notify-subscription-id (integer(1:MAX)) MUST Subscription
+
+ notify-printer-uri (uri) MUST Subscription
+
+ notify-subscribed-event (type2 keyword) MUST Event
+ Notification
+
+ printer-up-time (integer(MIN:MAX)) MUST Printer
+
+ printer-current-time (dateTime) * MUST Printer
+
+ notify-sequence-number (integer (0:MAX)) MUST Subscription
+
+ notify-charset (charset) MUST Subscription
+
+ notify-natural-language (naturalLanguage) MUST Subscription
+
+ notify-user-data (octetString(63)) ** MUST Subscription
+
+ notify-text (text (MAX)) MUST Event
+ Notification
+
+ attributes from the "notify-attributes" MUST *** Printer
+ attribute, if any ***
+
+ attributes from the "notify-attributes" MUST *** Job
+ attribute, if any ***
+
+ attributes from the "notify-attributes" MUST *** Subscription
+ attribute, if any ***
+
+
+ * The Printer MUST send "printer-current-time" if and only if
+ it supports the "printer-current-time" attribute on the Printer
+ object.
+
+ ** If the associated Subscription Object does not contain a
+ "notify-user-data" attribute, the Printer MUST send an octet-
+ string of length 0.
+
+ *** If the "notify-attributes" attribute is present on the
+ Subscription Object, the Printer MUST send all attributes
+ specified by the "notify-attributes" attribute. Note: if the
+ Printer doesn't support the "notify-attributes" attribute, it
+
+Parra, Hastings Expires: August 28, 2001 [page 16]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ is not present on the associated Subscription Object and the
+ Printer does not send any client-requested attributes.
+
+ For Event Notifications for Job Events, the Printer sends the
+ following additional attributes shown in Table 4.
+
+ Table 4 - Additional Attributes in Event Notification Content for
+ Job Events
+
+
+ Source Value Sends Source Object
+
+
+ job-id (integer(1:MAX)) MUST Job
+
+ job-state (type1 enum) MUST Job
+
+ job-state-reasons (1setOf type2 keyword) MUST Job
+
+ job-impressions-completed MUST Job
+ (integer(0:MAX)) *
+
+
+ * The Printer MUST send the "job-impressions-completed"
+ attribute in an Event Notification only for the combinations of
+ Events and Subscribed Events shown in Table 5.
+
+
+
+ Table 5 - Combinations of Events and Subscribed Events for "job-
+ impressions-completed"
+
+
+ Job Event Subscribed Job Event
+
+
+ 'job-progress' 'job-progress'
+
+ 'job-completed' 'job-completed'
+
+ 'job-completed' 'job-state-changed'
+
+
+ For Event Notification for Printer Events, the Printer sends
+ the following additional attributes shown in Table 6.
+
+
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 17]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ Table 6 - Additional Attributes in Event Notification Content for
+ Printer Events
+
+
+ Source Value Sends Source Object
+
+
+ printer-state (type1 enum) MUST Printer
+
+ printer-state-reasons (1setOf type2 keyword) MUST Printer
+
+ printer-is-accepting-jobs (boolean) MUST Printer
+
+
+
+8.1.2 Send-Notifications Response
+
+ The Notification Recipient MUST return (to the client which is the
+ Printer) the following sets of attributes as part of a Send-
+ Notifications response:
+
+ Every operation response contains the following REQUIRED parameters
+ (see [RFC2911] section 3.1.1}:
+
+ - a "version-number"
+ - a "status-code"
+ - the "request-id" that was supplied in the corresponding request
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ As defined in [RFC2911].
+
+ The Notification Recipient can return any status codes defined
+ in [RFC2911] and section 9.1 that applies to all of the Event
+ Notification Attribute groups. The following is a description
+ of the important status codes:
+
+ 'successful-ok': the Notification Recipient received all of
+ the Event Notification Attribute Groups and was expecting
+ each of them.
+
+ 'successful-ok-ignored-notifications': the Notification
+ Recipient was able to consume some, but not all of the
+ Event Notification Attributes Groups sent. The Event
+ Notification Attributes Groups with a "notify-status-
+ code" attribute are the ones that were ignored or are to
+ be canceled.
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 18]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ 'client-error-ignored-all-notifications': the Notification
+ Recipient was unable to consume any of the Event
+ Notification Attributes Groups sent. The Event
+ Notification Attributes Groups with a "notify-status-
+ code" attribute are the ones that were ignored or are to
+ be canceled.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as defined in [RFC2911] section 3.1.4.1.
+
+ Group 2 to N: Notification Attributes
+
+ These groups MUST be returned if and only if the "status-code"
+ parameter returned in Group 1 is anything but the 'successful-ok'
+ status code.
+
+ "notify-status-code" (type2 enum)
+ Indicates whether the Notification Recipient was able to
+ consume the n-th Notification Report as follows:
+
+ 'successful-ok' - this Event Notification Attribute Group
+ was consumed
+ 'client-error-not-found' - this Event Notification
+ Attribute Group was not able to be consumed. The Printer
+ MUST cancel the Subscription and MUST NOT attempt to send
+ any further Event Notifications from the associated
+ Subscription object.
+ 'successful-ok-but-cancel-subscription' - the Event
+ Notification Attribute Group was consumed, but the
+ Notification Recipient wishes to cancel the Subscription
+ object. The Printer MUST cancel the Subscription and
+ MUST NOT attempt to send any further Event Notifications
+ from the associated Subscription object.
+
+9 Status Codes
+
+ This section lists status codes whose meaning have been extended
+ and/or defined for returning in Event Notification Attribute Groups
+ as the value of the "notify-status-code" operation attribute. The
+ code values are allocated in the same space as the status codes in
+ [RFC2911].
+
+
+9.1 Additional Status Codes
+
+ The following status codes are defined as extensions for Notification
+ and are returned as the value of the "status-code" parameter in the
+ Operation Attributes Group of a response (see [RFC2911] section
+ 3.1.6.1). Operations in this document can also return the status
+
+Parra, Hastings Expires: August 28, 2001 [page 19]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ codes defined in section 13 of [RFC2911]. The 'successful-ok' status
+ code is an example of such a status code.
+
+
+9.1.1 successful-ok-ignored-notifications (0x0004)
+
+ The Notification Recipient was able to consume some, but not all, of
+ the Event Notifications Attributes Groups sent by the Printer in the
+ Send-Notifications request. See section 8.1.2 for further details.
+
+
+9.1.2 client-error-ignored-all-notifications (0x0416)
+
+ The Notification Recipient was unable to consume any of the Event
+ Notification Attributes Groups sent by the Printer. The Event
+ Notification Attributes Groups with a "notify-status-code" attribute
+ are the ones that were ignored or are to be canceled.
+
+
+9.2 Status Codes returned in Event Notification Attributes Groups
+
+ This section contains values of the "notify-status-code" attribute
+ that the Notification Recipient returns in a Event Notification
+ Attributes Group in a response when the corresponding Event
+ Notification Attributes Group in the request:
+
+ 1.was not consumed OR
+
+ 2.was consumed, but the Notification Recipient wants to cancel the
+ corresponding Subscription object
+
+ The following sections are ordered in decreasing order of importance
+ of the status-codes.
+
+
+9.2.1 client-error-not-found (0x0406)
+
+ This status code is defined in [RFC2911]. This document extends its
+ meaning and allows it to be returned in an Event Notification
+ Attributes Group of a response.
+
+ The Notification Recipient was unable to consume this Event
+ Notification Attributes Group because it was not expected. See
+ section 8.1.2 for further details.
+
+
+9.2.2 successful-ok-but-cancel-subscription (0x0006)
+
+ The Notification Recipient was able to consume this Event
+ Notification Attributes Group that the Printer sent, but wants the
+
+Parra, Hastings Expires: August 28, 2001 [page 20]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ corresponding Subscription object to be canceled none-the-less. See
+ section 8.1.2 for further details.
+
+
+10 Encoding and Transport
+
+ This section defines the encoding and transport used by the 'indp'
+ Delivery Method.
+
+
+10.1 Encoding of the Operation Layer
+
+ The 'indp' Delivery Method uses the IPP operation layer encoding
+ described in [RFC2910] and the Event Notification Attributes Group
+ tag allocated by [ipp-ntfy] as shown in Table 7:
+
+ Table 7 - The "event-notification-attributes-tag" value
+
+
+ Tag Value (Hex) Meaning
+
+
+ 0x07 "event-notification-attributes-tag"
+
+
+
+10.2 Encoding of Transport Layer
+
+ The 'indp' Notification Delivery Method uses the IPP transport layer
+ encoding described in [RFC2910].
+
+ It is REQUIRED that an 'indp' Notification Recipient implementation
+ support HTTP over the IANA assigned Well Known Port assigned to the
+ 'indp' Delivery Method as its default port by IANA (see section 13),
+ though a Notification Recipient implementation MAY support HTTP over
+ some other port as well.
+
+
+11 Conformance Requirements
+
+ This section defines conformance requirements for Printers and
+ Notification Recipients.
+
+
+11.1 Conformance Requirements for Printers
+
+ The 'indp' Delivery Method is RECOMMENDED for a Printer to support.
+
+ IPP Printers that conform to this specification:
+
+
+Parra, Hastings Expires: August 28, 2001 [page 21]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ 1.MUST meet the conformance requirements defined in [ipp-ntfy].
+
+ 2.MUST support the conformance requirements for Subscription object
+ attributes defined in section 5, including the syntax for the
+ "notify-recipient-uri" Subscription Object attribute defined in
+ section 5.2.1.
+
+ 3.MUST support the conformance requirements for Printer Description
+ object attributes defined in section 6.
+
+ 4.MUST support the 'indp' protocol by sending Event Notifications
+ using the Send-Notifications operation defined in section 8.1.
+
+ 5.MUST send INDP URLs (e.g., in the "notify-recipient-uri" attribute
+ in 'Send-Notifications') that conform to the ABNF specified in
+ section 12.5 of this document;
+
+ 6.MUST send INDP operations via the port specified in the INDP URL
+ (if present) or otherwise via IANA assigned well-known port [TBD];
+
+ 7.MUST convert INDP URLs to their corresponding HTTP URL forms by
+ the same rules used to convert IPP URLs to their corresponding
+ HTTP URL forms (see section 5 'IPP URL Scheme' in [RFC2910]).
+
+
+11.2 Conformance Requirements for INDP Notification Recipients
+
+ INDP Notification Recipients that conform to this specification:
+
+ 1.MUST accept Send-Notifications requests and return Send-
+ Notifications responses as defined in sections 8 and 9.
+
+ 2.SHOULD reject received INDP URLs in "application/ipp" request
+ bodies (e.g., in the "notify-recipient-uri" attribute in 'Send-
+ Notifications') that do not conform to the ABNF for INDP URLs
+ specified in section 12.5 of this document;
+
+ 3.MUST listen for INDP operations on IANA-assigned well-known port
+ [TBD], unless explicitly configured by system administrators or
+ site policies;
+
+ 4.SHOULD NOT listen for INDP operations on any other port, unless
+ explicitly configured by system administrators or site policies.
+
+
+
+
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 22]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+12 INDP URL Scheme
+
+
+12.1 INDP URL Scheme Applicability and Intended Usage
+
+ This section is intended for use in registering the "indp" URL scheme
+ with IANA and fully conforms to the requirements in [RFC2717]. This
+ document defines the "indp" URL (Uniform Resource Locator) scheme for
+ specifying the location of an INDP Notification Recipient object
+ which implements IPP Notification Delivery Protocol (INDP) specified
+ in this document.
+
+ The intended usage of the "indp" URL scheme is COMMON.
+
+
+12.2 INDP URL Scheme Associated INDP Port
+
+ All INDP URLs which do NOT explicitly specify a port MUST be used
+ over IANA-assigned well-known port [TBD] for the INDP protocol.
+
+ See: IANA Port Numbers Registry [IANA-PORTREG].
+
+
+12.3 INDP URL Scheme Associated MIME Type
+
+ All INDP protocol operations (requests and responses) MUST be
+ conveyed in an "application/ipp" MIME media type as registered in
+ [IANA-MIMEREG]. INDP URLs MUST refer to INDP Notification Recipient
+ objects which support this "application/ipp" MIME media type.
+
+ See: IANA MIME Media Types Registry [IANA-MIMEREG].
+
+
+12.4 INDP URL Scheme Character Encoding
+
+ The INDP URL scheme defined in this document is based on the ABNF for
+ the HTTP URL scheme defined in HTTP/1.1 [RFC2616], which is derived
+ from the URI Generic Syntax [RFC2396] and further updated by
+ [RFC2732] and [RFC2373] (for IPv6 addresses in URLs). The INDP URL
+ scheme is case-insensitive in the host name or host address part;
+ however the path part is case-sensitive, as in [RFC2396]. Code
+ points outside [US-ASCII] MUST be hex escaped by the mechanism
+ specified in [RFC2396].
+
+
+12.5 INDP URL Scheme Syntax in ABNF
+
+ This section is intended for use in registering the "indp" URL scheme
+ with IANA and fully conforms to the requirements in [RFC2717]. This
+ document defines the "indp" URL (Uniform Resource Locator) scheme for
+
+Parra, Hastings Expires: August 28, 2001 [page 23]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ specifying the location of an INDP Notification Recipient object
+ which implements IPP Notification Delivery Protocol (INDP) specified
+ in this document.
+
+ The intended usage of the "indp" URL scheme is COMMON.
+
+ The IPP protocol places a limit of 1023 octets (NOT characters) on
+ the length of a URI (see section 4.1.5 'uri' in [RFC2911]). An INDP
+ Notification Recipient MUST return 'client-error-request-value-too-
+ long' (see section 13.1.4.10 in [RFC2911]) when a URI received in a
+ request is too long.
+
+ Note: INDP Notification Recipients ought to be cautious about
+ depending on URI lengths above 255 bytes, because some older client
+ or proxy implementations might not properly support these lengths.
+
+ INDP URLs MUST be represented in absolute form. Absolute URLs always
+ begin with a scheme name followed by a colon. For definitive
+ information on URL syntax and semantics, see "Uniform Resource
+ Identifiers (URI): Generic Syntax and Semantics" [RFC2396]. This
+ specification adopts the definitions of "port", "host", "abs_path",
+ and "query" from [RFC2396], as updated by [RFC2732] and [RFC2373]
+ (for IPv6 addresses in URLs).
+
+ The INDP URL scheme syntax in ABNF is as follows:
+
+ indp_URL = "indp:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
+
+ If the port is empty or not given, IANA-assigned well-known port
+ [TBD] is assumed. The semantics are that the identified resource
+ (see section 5.1.2 of [RFC2616]) is located at the INDP Notification
+ Recipient listening for HTTP connections on that port of that host,
+ and the Request-URI for the identified resource is 'abs_path'.
+
+ Note: The use of IP addresses in URLs SHOULD be avoided whenever
+ possible (see [RFC1900]).
+
+ If the 'abs_path' is not present in the URL, it MUST be given as "/"
+ when used as a Request-URI for a resource (see section 5.1.2 of
+ [RFC2616]). If a proxy receives a host name which is not a fully
+ qualified domain name, it MAY add its domain to the host name it
+ received. If a proxy receives a fully qualified domain name, the
+ proxy MUST NOT change the host name.
+
+
+12.5.1 INDP URL Examples
+
+ The following are examples of valid INDP URLs for Notification
+ Recipient objects (using DNS host names):
+
+
+Parra, Hastings Expires: August 28, 2001 [page 24]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ indp://abc.com
+ indp://abc.com/listener
+
+ Note: The use of IP addresses in URLs SHOULD be avoided whenever
+ possible (see [RFC1900]).
+
+ The following literal IPv4 addresses:
+
+ 192.9.5.5 ; IPv4 address in IPv4 style
+ 186.7.8.9 ; IPv4 address in IPv4 style
+
+ are represented in the following example INDP URLs:
+
+ indp://192.9.5.5/listener
+ indp://186.7.8.9/listeners/tom
+
+ The following literal IPv6 addresses (conformant to [RFC2373]):
+
+ ::192.9.5.5 ; IPv4 address in IPv6 style
+ ::FFFF:129.144.52.38 ; IPv4 address in IPv6 style
+ 2010:836B:4179::836B:4179 ; IPv6 address per RFC 2373
+
+ are represented in the following example INDP URLs:
+
+ indp://[::192.9.5.5]/listener
+ indp://[::FFFF:129.144.52.38]/listener
+ indp://[2010:836B:4179::836B:4179]/listeners/tom
+
+
+12.5.2 INDP URL Comparisons
+
+ When comparing two INDP URLs to decide if they match or not, an INDP
+ Client SHOULD use a case-sensitive octet-by-octet comparison of the
+ entire URLs, with these exceptions:
+
+ . A port that is empty or not given is equivalent to the well-
+ known port for that INDP URL (port [TBD]);
+
+ . Comparisons of host names MUST be case-insensitive;
+
+ . Comparisons of scheme names MUST be case-insensitive;
+
+ . An empty 'abs_path' is equivalent to an 'abs_path' of "/".
+
+ Characters other than those in the "reserved" and "unsafe" sets (see
+ [RFC2396] and [RFC2732]) are equivalent to their ""%" HEX HEX"
+ encoding.
+
+ For example, the following three URIs are equivalent:
+
+
+Parra, Hastings Expires: August 28, 2001 [page 25]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ indp://abc.com/~smith/listener
+ indp://ABC.com/%7Esmith/listener
+ indp://ABC.com:/%7esmith/listener
+
+
+13 IANA Considerations
+
+ IANA is requested to register the indp URL scheme as defined in
+ section 12.
+
+ IANA is requested to assign a default system port (less than 1024)
+ for use with the indp URL as defined in section 12.
+
+ The rest of this section contains the exact information for IANA to
+ add to the IPP Registries according to the procedures defined in RFC
+ 2911 [RFC2911] section 6.
+
+ Note to RFC Editors: Replace RFC NNNN below with the RFC number
+ for this document, so that it accurately reflects the content of
+ the information for the IANA Registry.
+
+
+13.1 Operation Registrations
+
+ The operations defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.4 with
+ the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/operations/
+
+ The registry entry will contain the following information:
+
+ Operations: Ref. Section:
+ Send-Notifications operation RFC NNNN 8.1
+
+
+13.2 Additional values of existing attributes
+
+
+13.2.1 Additional values for the "notify-schemes-supported" Printer
+ attribute
+
+ The "notify-schemes-supported" uriScheme attribute value defined in
+ this document will be published by IANA according to the procedures
+ in RFC 2911 [RFC2911] section 6.1 with the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-values/notify-schemes-
+ supported/
+
+ The registry entry will contain the following information:
+
+Parra, Hastings Expires: August 28, 2001 [page 26]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ Ref. Section:
+ indp RFC NNNN 6.2.1
+
+
+13.2.2 Additional values for the "operations-supported" Printer
+ attribute
+
+ The "operations-supported" type2 enum attribute value defined in this
+ document will be published by IANA according to the procedures in RFC
+ 2911 [RFC2911] section 6.1 with the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-values/operations-
+ supported/
+
+ The registry entry will contain the following information:
+
+ Value Ref. Section:
+ Send-Notifications 0x001D RFC NNNN 6.2.1
+
+
+13.3 Status code Registrations
+
+ The status codes defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.6 with
+ the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/status-codes/
+
+ The registry entry will contain the following information:
+
+ Status codes: Ref. Section:
+ successful-ok-ignored-notifications (0x0004) RFC NNNN 9.1.1
+ client-error-ignored-all-notifications (0x0416) RFC NNNN 9.1.2
+
+
+
+14 Internationalization Considerations
+
+ When the client requests Human Consumable form by supplying the
+ "notify-text-format" operation attribute (see [ipp-ntfy]), the IPP
+ Printer (or any Notification Service that the IPP Printer might be
+ configured to use) supplies and localizes the text value of the
+ "human-readable-report" attribute in the Notification according to
+ the charset and natural language requested in the notification
+ subscription.
+
+
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 27]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+15 Security Considerations
+
+ The IPP Model and Semantics document [RFC2911] discusses high level
+ security requirements (Client Authentication, Server Authentication
+ and Operation Privacy). Client Authentication is the mechanism by
+ which the client proves its identity to the server in a secure
+ manner. Server Authentication is the mechanism by which the server
+ proves its identity to the client in a secure manner. Operation
+ Privacy is defined as a mechanism for protecting operations from
+ eavesdropping.
+
+ The Notification Recipient can cancel unwanted Subscriptions created
+ by other parties without having to be the owner of the subscription
+ by returning the 'successful-ok-but-cancel-subscription' status code
+ in the Send-Notifications response returned to the Printer.
+
+15.1 Security Conformance
+
+ Printers (client) MAY support Digest Authentication [RFC2617]. If
+ Digest Authentication is supported, then MD5 and MD5-sess MUST be
+ supported, but the Message Integrity feature NEED NOT be supported.
+
+ Notification Recipient (server) MAY support Digest Authentication
+ [RFC2617]. If Digest Authentication is supported, then MD5 and MD5-
+ sess MUST be supported, but the Message Integrity feature NEED NOT be
+ supported.
+
+ Notification Recipients MAY support TLS for client authentication,
+ server authentication and operation privacy. If a Notification
+ Recipient supports TLS, it MUST support the
+ TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA cipher suite as mandated by RFC
+ 2246 [RFC2246]. All other cipher suites are OPTIONAL. Notification
+ recipients MAY support Basic Authentication (described in HTTP/1.1
+ [RFC2616]) for client authentication if the channel is secure. TLS
+ with the above mandated cipher suite can provide such a secure
+ channel.
+
+
+16 References
+
+
+ [ipp-iig]
+ Hastings, T., Manros, C., Kugler, K, Holst H., Zehler, P.,
+ "Internet Printing Protocol/1.1: draft-ietf-ipp-implementers-
+ guide-v11-02.txt, work in progress, January 25, 2001
+
+
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 28]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ [ipp-ntfy]
+ Isaacson, S., Martin, J., deBry, R., Hastings, T., Shepherd, M.,
+ Bergman, R., "Internet Printing Protocol/1.1: IPP Event
+ Notification Specification", <draft-ietf-ipp-not-spec-06.txt>,
+ January 24, 2001.
+
+ [IANA-MIMEREG]
+ IANA MIME Media Types Registry. ftp://ftp.isi.edu/in-
+
+ notes/iana/assignments/media-types/
+
+
+ [IANA-PORTREG]
+ IANA Port Numbers Registry. ftp://ftp.isi.edu/in-
+
+ notes/iana/assignments/port-numbers
+
+
+ [RFC1900]
+ B. Carpenter, Y. Rekhter. Renumbering Needs Work, RFC 1900,
+ February 1996.
+
+ [RFC2026]
+ S. Bradner, "The Internet Standards Process -- Revision 3", RFC
+ 2026, October 1996.
+
+ [RFC2373]
+ R. Hinden, S. Deering. IP Version 6 Addressing Architecture, RFC
+ 2373, July 1998.
+
+ [RFC2396]
+ Berners-Lee, T. et al. Uniform Resource Identifiers (URI): Generic
+ Syntax, RFC 2396, August 1998
+
+ [RFC2616]
+ R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P.
+ Leach, T. Berners-Lee, "Hypertext Transfer Protocol - HTTP/1.1",
+ RFC 2616, June 1999.
+
+ [RFC2617]
+ J. Franks, P. Hallam-Baker, J. Hostetler, S. Lawrence, P. Leach, A.
+ Luotonen, L. Stewart, "HTTP Authentication: Basic and Digest Access
+ Authentication", RFC 2617, June 1999.
+
+ [RFC2717]
+ R. Petke and I. King, "Registration Procedures for URL Scheme
+ Names", RFC 2717, November 1999.
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 29]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ [RFC2732]
+ R. Hinden, B. Carpenter, L. Masinter. Format for Literal IPv6
+ Addresses in URL's, RFC 2732, December 1999.
+
+ [RFC2910]
+ Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet Printing
+ Protocol/1.1: Encoding and Transport", RFC 2910, September 2001.
+
+ [RFC2911]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell,
+ "Internet Printing Protocol/1.1: Model and Semantics", RFC 2911,
+ September 2001.
+
+
+17 Author's Addresses
+
+ Hugo Parra
+ Novell, Inc.
+ 1800 South Novell Place
+
+ Provo, UT 84606
+
+ Phone: 801-861-3307
+ Fax: 801-861-2517
+ e-mail: hparra@novell.com
+
+ Tom Hastings
+ Xerox Corporation
+ 737 Hawaii St. ESAE 231
+ El Segundo, CA 90245
+
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ e-mail: hastings@cp10.es.xerox.com
+
+
+18 Full Copyright Statement
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+
+Parra, Hastings Expires: August 28, 2001 [page 30]
+
+
+INTERNET-DRAFT IPP: The 'indp' Method and Protocol February 28, 2001
+
+
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Parra, Hastings Expires: August 28, 2001 [page 31]
diff --git a/standards/draft-ietf-ipp-install-02.txt b/standards/draft-ietf-ipp-install-02.txt
new file mode 100644
index 000000000..6319c431e
--- /dev/null
+++ b/standards/draft-ietf-ipp-install-02.txt
@@ -0,0 +1,1426 @@
+
+
+
+
+
+
+INTERNET-DRAFT
+<draft-ietf-ipp-install-02.txt>
+[Target category: standards track] Hugo Parra
+ Novell, Inc.
+ Ted Tronson
+ Novell, Inc.
+ Tom Hastings
+ Xerox Corp.
+ February 28, 2001
+ Internet Printing Protocol (IPP):
+ Printer Installation Extension
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of [RFC2026]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress".
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed as
+ http://www.ietf.org/shadow.html.
+
+Abstract
+
+ Various client platforms require that some setting up take place at
+ the workstation before the client can properly submit jobs to a
+ specific printer. This setup process is sometimes referred to as
+ printer installation. Most clients need some information about the
+ printer being installed as well as support files to complete the
+ printer installation. The nature of the support files varies
+ depending on the specific client platform, from simple configuration
+ files to highly sophisticated printer drivers. This document refers
+ to these support files as "Client Print Support Files".
+ Traditionally, the selection and installation of the correct Client
+ Print Support Files has been error prone. The selection and
+ installation process can be simplified and even automated if the
+ workstation can learn some key information about the printer and
+ which sets of Client Print Support Files are available. Such key
+ information includes: operating system type, CPU type, document-
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 1]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ format (PDL), natural language, compression mechanism, file type,
+ client file name, policy for automatic loading, file size, file
+ version, file date and time, file information description, and
+ digital signature. This document describes the IPP extensions that
+ enable workstations to obtain the information needed to perform a
+ proper printer driver installation using IPP, including security for
+ downloading executable code and data.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 2]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics [RFC2911]
+ Internet Printing Protocol/1.1: Encoding and Transport [RFC2910]
+ Internet Printing Protocol/1.1: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ The "Design Goals for an Internet Printing Protocol" document takes a
+ broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. A few OPTIONAL operator operations have
+ been added to IPP/1.1.
+
+ The "Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol" document describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specification documents, and gives background and rationale
+ for the IETF working group's major decisions.
+
+ The "Internet Printing Protocol/1.1: Encoding and Transport" document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1 [RFC2616]. It defines the
+ encoding rules for a new Internet MIME media type called
+ "application/ipp". This document also defines the rules for
+ transporting a message body over HTTP whose Content-Type is
+ "application/ipp". This document defines a new scheme named 'ipp'
+ for identifying IPP printers and jobs.
+
+ The "Internet Printing Protocol/1.1: Implementer's Guide" document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.1 and some of
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+ The "Mapping between LPD and IPP Protocols" document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+
+
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 3]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+
+Table of Contents
+
+ 1 Introduction....................................................6
+
+
+ 2 Terminology.....................................................6
+
+
+ 3 Model Extensions................................................7
+
+ 3.1 client-print-support-files-supported (1setOf octetString(MAX))
+
+ ..........................................................7
+ 3.1.1 Use of Keyword Values in fields.............................12
+
+ 3.1.2 Use of the Special Keyword Value: 'unknown'.................12
+
+ 3.1.3 Examples of "client-print-support-files-supported" attribute
+
+ values.................................................12
+
+ 3.2 Get-Printer-Attributes Operation Extension..................13
+
+ 3.2.1 Get-Printer-Attributes Request..............................13
+
+ 3.2.1.1 client-print-support-files-filter (octetString(MAX))
+
+ operation attribute..................................13
+
+ 3.2.1.1.1 Filter matching rules.................................15
+
+ 3.2.2 Get-Printer-Attributes Response.............................16
+
+ 3.3 Get-Client-Print-Support-Files..............................17
+
+ 3.3.1 Get-Client-Print-Support-Files Request......................17
+
+ 3.3.2 Get-Client-Print-Support-Files Response.....................18
+
+
+ 4 Conformance....................................................19
+
+
+ 5 Encoding of the Operation Layer................................20
+
+
+ 6 Encoding of Transport Layer....................................20
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 4]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ 7 IANA Considerations............................................20
+
+ 7.1 Attribute Registrations.....................................21
+
+ 7.2 Operation Registrations.....................................22
+
+
+ 8 Internationalization Considerations............................22
+
+
+ 9 Security Considerations........................................22
+
+
+ 10 References.....................................................23
+
+
+ 11 Author's Addresses.............................................24
+
+
+ 12 Full Copyright Statement.......................................25
+
+
+
+Tables
+
+ Table 1 - "client-print-support-files-supported" attribute fields..9
+
+ Table 2 - "client-print-support-files-filter" attribute fields....14
+
+ Table 3 - REQUIRED "client-print-support-files-filter" fields.....14
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 5]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+1 Introduction
+
+ A common configuration for printing from a workstation requires that
+ some Client Print Support Files (e.g., PPD, printer driver files)
+ specific to the target printer be installed on that workstation.
+ Selection and configuration of the appropriate Client Print Support
+ Files can be simplified and even automated if the workstation can
+ obtain some key information about the printer and which sets of
+ Client Print Support Files are available. Such key information
+ includes: operating system type, CPU type, document-format (PDL),
+ natural language, compression mechanism, file type, client file name,
+ policy for automatic loading, file size, file version, file date and
+ time, file information description, and digital signature. With a
+ few extensions, IPP provides a simple and reliable vehicle for
+ printers to convey this information to interested workstations. The
+ IPP extensions described in this document enable a flexible solution
+ for installing Client Print Support Files on workstations running
+ different operating systems and for printers of all makes and models.
+ It allows Client Print Support Files to be downloaded from
+ repositories of different sorts. A possible repository for the files
+ is the printer itself. The extensions necessary for getting Client
+ Print Support Files from the printer are included in this document,
+ including security for downloading executable code and data.
+
+
+2 Terminology
+
+ Client Print Support Files - a set of files, such as a printer
+ driver, font metric file, printer configuration file (PPD, GPD, etc.)
+ that support a client printing to a particular Printer. A Printer
+ MAY have multiple sets of Client Print Support Files that work for
+ different operating systems, document formats, natural languages,
+ CPUs, etc.
+
+ This document uses terms such as "attributes", "keywords", and
+ "support". These terms have special meaning and are defined in the
+ model terminology [RFC2911] section 12.2. This document also uses
+ the terms "IPP Printer", "Printer" and "Printer object"
+ interchangeably as in [RFC2911] to mean the software entity that
+ accepts IPP operation requests and returns IPP operation responses
+ (see [RFC2911] section 2).
+
+ Capitalized terms, such as MUST, MUST NOT, REQUIRED, SHOULD, SHOULD
+ NOT, MAY, NEED NOT, and OPTIONAL, have special meaning relating to
+ conformance. These terms are defined in [RFC2911] section 12.1 on
+ conformance terminology, most of which is taken from RFC 2119
+ [RFC2119].
+
+ This section defines the following additional terms that are used
+ throughout this document:
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 6]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ REQUIRED: if an implementation supports the extensions described
+ in this document, it MUST support a REQUIRED feature.
+ OPTIONAL: if an implementation supports the extensions described
+ in this document, it MAY support an OPTIONAL feature.
+
+3 Model Extensions
+
+ To assist workstations in the printer installation process, an IPP
+ printer needs to provide the workstation with information about the
+ Client Print Support Files, such as the their name and location/s.
+ This information needs to match the workstation's specific
+ environment, such as its operating system, preferred natural
+ language, and preferred document format.
+
+ The following extensions to the IPP model enable assisted or
+ automated printer installation. This section describes each
+ extension in detail.
+
+
+ - A new REQUIRED Printer Description attribute: "client-print-
+ support-files-supported" (1setOf octetString(MAX)).
+ - A new REQUIRED Get-Printer-Attributes operation attribute:
+ "client-print-support-files-filter" (octetString(MAX)).
+ - A new RECOMMENDED printer operation: Get-Client-Print-Support-
+ Files.
+
+
+3.1 client-print-support-files-supported (1setOf octetString(MAX))
+
+ An IPP Printer uses the REQUIRED Printer Description attribute
+ "client-print-support-files-supported" to represent relevant
+ information about all of the Client Print Support Files it supports.
+ Each value is a composite UTF-8 string with well-defined fields (see
+ Table 1). Each value string MUST be formatted as follows:
+
+ "uri=val1< field-name2=val21,_,val2p< _ < field-namen=valn1,_,valnq<"
+
+ The first field MUST be the "uri" field. The remaining fields MAY be
+ in any order.
+
+ The string MUST NOT include any control characters (hex 00 to 1F),
+ even the so-called white space control characters (TAB, CR, and LF)
+ anywhere. Only zero or more UTF-8 SPACE characters (hex 20) can be
+ included and they can be included only IMMEDIATELY AFTER the
+ delimiter character: "<", but NOT anywhere else, including after "="
+ and ",". However, if the UTF-8 SPACE character is needed in a
+ client-file-name value, then each occurrence is included directly,
+ without escaping (see example). On the other hand, if the UTF-8
+ SPACE character is needed in a URL value, then each occurrence is
+ escaped as: "%20" (URI conventions - see [RFC2396]).
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 7]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ Table 1 lists the REQUIRED fields that a Printer MUST support and the
+ OPTIONAL fields that a Printer MAY support in the "client-print-
+ support-files-supported" (1setOf octetString(MAX)) Printer
+ Description attribute. A Printer implementation MAY support
+ additional fields using the same syntax. Values are defined to be
+ either CASE-SENSITIVE or ALL-LOWER-CASE according to the definitions
+ for the attribute syntaxes from [RFC2911] (set off by single quotes
+ in the table). The CASE-SENSITIVE values MAY have upper and lower
+ case letters as for the corresponding attribute syntaxes in
+ [RFC2911]. The LOWER-CASE values MUST have all lower case alphabetic
+ letters. Additional characters, such as digits, hyphen-minus (-),
+ period (.), and slash (/) are according to the corresponding
+ attribute syntaxes in [RFC2911].
+
+ Clients SHOULD ignore fields they don't recognize in a given value.
+ This allows for future extensions to the format of the string without
+ breaking compatibility with earlier clients.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 8]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ Table 1 - "client-print-support-files-supported" attribute fields
+
+
+ Field Field value
+ name
+
+
+ "uri" One REQUIRED CASE-SENSITIVE 'uri' string identifying the
+ uri where to obtain the support files for each OS
+ platform, document format, and natural language the
+ printer supports. This MUST be the first field in each
+ value. Examples of uri schemes that MAY be found here
+ are 'ftp', 'http', and 'ipp'. The 'ftp' and 'http'
+ schemed URIs identify the archive file that contains all
+ the necessary client support files.
+
+ The 'ipp' schemed URIs identify the archive file that
+ clients MAY obtain from the Printer using the Get-
+ Client-Print-Support-Files operation (see section 3.3).
+ The URI MUST be a valid URI to the same Printer object,
+ i.e., one of the values of the Printer's "printer-uri-
+ supported" attribute. The 'ipp' URI is used to
+ distinguish between multiple Client Print Support Files
+ in an implementation dependent manner using the URL
+ query syntax (e.g., "?drv-id=xxx") [RFC2396]. The
+ query part MUST NOT exceed 127 octets, not counting the
+ "?" character that begins the query part. A Printer
+ SHOULD support the 'ipp' scheme.
+
+ "os-type" One or more REQUIRED comma-separated LOWER-CASE
+ 'keyword' strings identifying the operating system types
+ supported by this set of Client Print Support Files.
+ Valid values are the operating system names defined in
+ the IANA document [os-names] and the special keyword
+ value: 'unknown'. Although the IANA registry requires
+ that the names be all upper-case, the values MUST be all
+ lower case in this field (plus hyphen-minus (-), period
+ (.), and slash (/)). Examples: 'linux', 'linux-2.2',
+ 'os/2', 'sun-os-4.0', 'unix', 'unix-bsd', 'win32',
+ 'windows-95', 'windows-98', 'windows-ce', 'windows-nt',
+ 'windows-nt-4', 'windows-nt-5', 'unknown'.
+
+ "cpu- One or more REQUIRED comma-separated LOWER-CASE
+ type" 'keyword' strings identifying the CPU types supported by
+ this set of Client Print Support Files. The values
+ indicate the CPU family independent of the CPU
+ manufacturer. Valid keyword values are: 'x86-16',
+ 'x86-32', 'x86-64', 'dec-vax', 'alpha', 'power-pc', 'm-
+ 68000, 'sparc', 'itantium', 'mips', 'arm' and will be
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 9]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+
+ Field Field value
+ name
+
+
+ used as the initial value for the "cpu-type" IANA
+ registry. In addition, the special keyword value:
+ 'unknown' is valid.
+
+ "document One or more REQUIRED comma-separated CASE-SENSITIVE
+ -format" 'mimeMediaType' strings identifying the document formats
+ supported by this set of Client Print Support Files.
+ Valid values are the string representation of the IPP
+ mimeMediaType attribute syntax (see [RFC2911] section
+ 4.1.9), for example 'application/postscript'. In
+ addition, the special keyword value: 'unknown' is valid.
+
+ "natural- One or more REQUIRED comma-separated LOWER-CASE
+ language" 'naturalLanguage' strings identifying the natural
+ language used by this set of Client Print Support Files.
+ Valid values are the string representation of the IPP
+ 'naturalLanguage' attribute syntax (see [RFC2911]
+ section 4.1.8), for example 'en' and 'en-us'. In
+ addition, the special keyword value: 'unknown' is valid.
+
+ "compress One REQUIRED LOWER-CASE 'keyword' string identifying the
+ ion" mechanism used to compress this set of Client Print
+ Support Files. All files needed for the installation of
+ a printer driver MUST be compressed into a single file.
+ Valid keyword values are the keywords defined by
+ [RFC2911] or registered with IANA for use in the IPP
+ "compression" and "compression-supported" attributes.
+ See [RFC2911] section 4.4.32), for example 'gzip'. The
+ 'none' value limits the uncompressed Client Print
+ Support File to a single file. The values for the
+ "compression" field that a Printer supports NEED NOT be
+ the same values that the Printer is configured to
+ support in Job Creation operations as indicated in the
+ Printer's "compressions-supported" attribute.
+
+ "file- One or more REQUIRED comma-separated LOWER-CASE
+ type" 'keyword' strings identifying the type of the Client
+ Print Support Files. Valid keyword values are:
+ 'printer-driver', 'ppd', 'updf', 'gpd'.
+
+ "client- One REQUIRED CASE-SENSITIVE string identifying the name
+ file- by which the Client Print Support Files will be
+ name" installed on the workstation. For Client Print Support
+ Files of type 'printer-driver', this is also the name
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 10]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+
+ Field Field value
+ name
+
+
+ that identifies this printer driver in an .inf file.
+
+ "policy" One OPTIONAL LOWER-CASE 'keyword' string indicating the
+ policy for automatic loading. Valid keyword values are:
+ 'manufacturer-recommended', 'administrator-recommended',
+ 'manufacturer-experimental, 'administrator-
+ experimental'. The experimental values are for beta
+ test.
+
+ "file- One OPTIONAL file size in octets represented as ASCII
+ size" decimal digits.
+
+ "file- One OPTIONAL LOWER-CASE version number. Recommended to
+ version" be of the form "Major.minor[.revision]" where "Major" is
+ the major version number, "minor" is the minor version
+ number and "revision" is an optional revision number.
+
+ "file- One OPTIONAL File CASE-SENSITIVE creation date and time
+ date- according to ISO 8601 where all fields are fixed length
+ time" with leading zeroes (see [RFC2518] Appendix 2).
+ Examples: 2000-01-01T23:09:05Z and 2000-01-01T02:59:59-
+ 04.00
+
+ "file- One OPTIONAL CASE-SENSITIVE human readable 'text' string
+ info" describing this set of Client Print Support Files. The
+ natural language for this value MUST be the natural
+ language indicated by the Printer's "natural-language-
+ configured" attribute. To avoid exceeding the maximum
+ limit imposed on IPP attributes and to increase
+ interoperability with other systems, the length of this
+ field value MUST not exceed 127 characters.
+
+ "digital- One REQUIRED LOWER-CASE 'keyword' string identifying the
+ signature mechanism used to ensure the integrity and authenticity
+ " of this set of Client Print Support Files. Valid values
+ are: 'smime', 'pgp', 'dss', and 'xmldsig' which are
+ defined in [RFC2634], [RFC1991], [dss], and [xmldsig],
+ respectively. In addition, the special keyword value:
+ 'none' is valid.
+
+
+ Each value MUST refer to one and only one set of Client Print Support
+ Files, even if the files are downloadable from various repositories
+ (i.e., even if they are associated with multiple URIs).
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 11]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+3.1.1 Use of Keyword Values in fields
+
+ A number of the fields in Table 1 use keyword strings as values. The
+ syntax of these keywords is the same as in [RFC2911], including the
+ use of private keywords. See [RFC2911] sections 4.1.3 and 6.1.
+ Printer implementers are strongly RECOMMENDED to submit additional
+ keyword values for registration with IANA according to the procedures
+ for registering attributes. See section 7 and [RFC2911] section 6.1.
+
+
+3.1.2 Use of the Special Keyword Value: 'unknown'
+
+ A number of REQUIRED 'keyword' value fields have a special keyword
+ value: 'unknown' defined. This value is intended for use when the
+ actual value is not known, such as by an administrator automatic
+ software configuring the IPP Printer object. However, it is strongly
+ RECOMMENDED that other more meaningful values be used, instead of the
+ 'unknown' value whenever possible.
+
+
+3.1.3 Examples of "client-print-support-files-supported" attribute
+ values
+
+ The following illustrates what two valid values of the "client-print-
+ support-files-supported" (1setOf octetString(MAX)) Printer
+ Description attribute might look like:
+
+ uri=ipp://mycompany.com/myprinter?drv-id=ModelY.gz<
+ os-type=windows-95< cpu-type=x86-32<
+ document-format=application/postscript<
+ natural-language=en< compression=gzip<
+ file-type=printer-driver<
+ client-file-name=CompanyX-ModelY-driver.gz<
+ policy=manufacturer-recommended<
+
+ uri=ftp://mycompany.com/root/drivers/win95/CompanyX/ModelY.gz<
+ os-type=windows-95< cpu-type=x86-32<
+ document-format=application/postscript,application/vnd.hp-PCL<
+ natural-language=en,fr< compression=gzip<
+ file-type=printer-driver<
+ client-file-name=Company T Model Z driver.gz<
+ policy=manufacturer-recommended<
+
+ The above examples have been broken onto separate lines for
+ readability in this document. However, there MUST NOT be any line
+ breaks in the actual values.
+
+
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 12]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ The "client-print-support-files-supported" Printer Description
+ attribute MAY be preset at manufacturing time or through
+ administrative means outside the scope of this document.
+
+
+3.2 Get-Printer-Attributes Operation Extension
+
+ The "client-print-support-files-supported" Printer Description
+ attribute defined in section 3.1 contains information, such as
+ operating system, natural language, and document format, about all of
+ the sets of Client Print Support Files. This section defines an
+ extension to the Get-Printer-Attributes operation that allows a
+ workstation to filter out all but the Client Print Support Files of
+ interest.
+
+
+3.2.1 Get-Printer-Attributes Request
+
+ A Printer MAY contain information about multiple sets of Client Print
+ Support Files to match the different operating systems, natural
+ languages and document formats it supports. A workstation MAY query
+ this information by including the 'client-print-support-files-
+ supported' keyword as a value of the "requested-attributes" operation
+ attribute of the Get-Printer-Attributes operation.
+
+
+3.2.1.1 client-print-support-files-filter (octetString(MAX)) operation
+ attribute
+
+ The client can request a subset of the values of the "client-print-
+ support-files-supported" Printer attribute by supplying the "client-
+ print-support-files-filter" (octetString(MAX)) operation attribute in
+ the request as a filter. The filter value indicates in which Client
+ Print Support Files the client is interested. The client MAY supply
+ this attribute. The Printer MUST support this attribute.
+
+ The filter value of the "client-print-support-files-filter" attribute
+ is a composite string with the same format as that of "client-print-
+ support-files-supported" (see Table 1 - "client-print-support-files-
+ supported" attribute fields in section 3.1) with the following
+ exceptions:
+
+
+
+
+
+
+
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 13]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ Table 2 - "client-print-support-files-filter" attribute fields
+
+
+ Field Field Value in the "client-print-support-files-filter"
+ Name attribute
+
+
+ uri- One or more comma-separated LOWER-CASE 'uriScheme'
+ scheme string values identifying the uri scheme to be
+ filtered on. Valid values are the string
+ representation of the IPP 'uriScheme' attribute syntax
+ (see [RFC2911] section 4.1.6). Example URI schemes
+ are: 'ftp', 'http', and 'ipp'. The Printer SHOULD
+ support the 'ipp' scheme. If supplied by the client,
+ this field NEED NOT be first. If this field is
+ omitted by the client, the Printer returns all
+ schemes.
+
+ xxx One or more comma-separated values for any of the
+ fields defined in Table 1, with the single exception
+ of the "uri" field which a client MUST NOT supply and
+ a Printer MUST NOT support.
+ The Printer MUST support any filter field having more
+ than one value separated by a COMMA (,), including the
+ fields that Table 1 indicates MUST BE single valued.
+
+
+ Printer implementations MUST support the "client-print-support-files-
+ filter" operation attribute in a Get-Printer-Attributes request with
+ the member fields listed Table 3. Printers MAY support any
+ additional filter fields listed in Table 2.
+
+ Client implementations MAY supply any filter fields listed in Table 2
+ in the "client-print-support-files-filter" operation attribute of a
+ Get-Printer-Attributes request.
+
+ Table 3 - REQUIRED "client-print-support-files-filter" fields
+
+
+ uri-scheme
+
+ os-type
+
+ cpu-type
+
+ document-format
+
+ natural-language
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 14]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+3.2.1.1.1 Filter matching rules
+
+ The Printer returns only the values of the "client-print-support-
+ files-supported" Printer Description attribute that match the filter
+ in the "client-print-support-files-filter" operation attribute. The
+ following filter matching rules are defined:
+
+ 1. A match occurs if at least one value of each field supplied by
+ the client in the filter matches a Client Print Support File
+ value. Printers MUST ignore a filter field supplied by a client
+ that the Printer does not support and return a match if all
+ supported fields do match, no matter what value the client
+ supplied for that unsupported field. Similarly, Printers MUST
+ ignore a filter field supplied by a client that the Printer does
+ support, but which the field has not been populated for a Client
+ Print Support Files and return a match if all supported and
+ populated fields do match, no matter what value the client
+ supplied for that unpopulated field.
+
+ 2. A match for a CASE-INSENSITIVE field occurs independent of the
+ case of the letters supplied by the client and those stored by
+ the Printer, while a match for a LOWER-CASE field is a strict
+ character for character match.
+
+ 3. A match for a 'keyword' Printer field that is populated with the
+ 'unknown' special keyword value occurs for any value supplied by
+ the client for that field.
+
+ 4. If the "client-print-support-files-filter" operation attribute
+ filter is not supplied by the client, the printer SHOULD behave
+ as if the attribute had been provided with all fields left empty
+ (i.e., return an unfiltered list).
+
+ The following are two examples of a "client-print-support-files-
+ filter" filter value:
+
+ os-type=windows-95< cpu-type=x86-32<
+ document-format=application-postscript< natural-language=en,de<
+
+ uri-scheme=ipp< os-type=windows-95< cpu-type=x86-32<
+ document-format=application-postscript< natural-language=en,de<
+
+ See section 3.2.2 for example matching responses.
+
+ It is RECOMMENDED that workstations first use the Get-Printer-
+ Attributes operation in combination with "client-print-support-files-
+ filter" operation attribute filter to get a list of the potential
+ Client Print Support Files that meet the workstation's requirements.
+ The workstation can then choose from the returned list which Client
+ Print Support Files to use and where to get them. If one of the URIs
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 15]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ returned is an IPP uri, the workstation can retrieve the Client Print
+ Support Files from an IPP printer via the Get-Client-Print-Support-
+ Files operation (see section 3.3).
+
+
+3.2.2 Get-Printer-Attributes Response
+
+
+ A Printer MUST return the "client-print-support-files-supported"
+ (1setOf octetString(MAX)) attribute in the Printer Object Attributes
+ group (group 3) when requested by a client. Each returned attribute
+ value MUST satisfy the criteria specified by the client in the
+ request.
+
+
+ For example, if the request contains the following "client-print-
+ support-files-filter" filter:
+
+ os-type=windows-95< cpu-type=x86-32<
+ document-format=application-postscript<
+ natural-language=en,de<
+
+ A conforming response is the following two octet String values:
+
+ uri=ipp://mycompany.com/myprinter?drv-id=ModelY.gz<
+ os-type=windows-95< cpu-type=x86-32<
+ document-format=application/postscript<
+ natural-language=en< compression=gzip<
+ file-type=printer-driver<
+ client-file-name=CompanyX-ModelY-driver.gz<
+ policy=manufacturer-recommended<
+ digital-signature=smime<
+
+ uri=ftp://mycompany.com/root/drivers/win95/CompanyX/ModelY.gz<
+ os-type=windows-95< cpu-type=x86-32<
+ document-format=application/postscript,application/vnd.hp-PCL<
+ natural-language=en,fr< compression=gzip<
+ file-type=printer-driver<
+ client-file-name=CompanyX-ModelY-driver.gz<
+ policy=manufacturer-recommended<
+ digital-signature=smime<
+
+
+ These examples have been broken onto separate lines for readability
+ in this document. However, there MUST NOT be any line breaks in the
+ actual values.
+
+
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 16]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ As another example, if the above request had also contained the "uri-
+ scheme" field in the following "client-print-support-files-filter"
+ filter:
+
+ uri-scheme=ipp< os-type=windows-95< cpu-type=x86-32<
+ document-format=application-postscript<
+ natural-language=en,de<
+
+ Then only the first value would have been returned as a single
+ octetString value:
+
+ uri=ipp://mycompany.com/myprinter?drv-id=ModelY.gz<
+ os-type=windows-95< cpu-type=x86-32<
+ document-format=application/postscript<
+ natural-language=en< compression=gzip<
+ file-type=printer-driver<
+ client-file-name=CompanyX-ModelY-driver.gz<
+ policy=manufacturer-recommended<
+ digital-signature=smime<
+
+3.3 Get-Client-Print-Support-Files
+
+ This RECOMMENDED operation allows a client to download Client Print
+ Support Files from an IPP Printer.
+
+
+3.3.1 Get-Client-Print-Support-Files Request
+
+
+ The following sets of attributes are part of the Get-Client-Print-
+ Support-Files request:
+
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911], section 3.1.4.1.
+
+ Target:
+ The "printer-uri" (uri) operation attribute which is the target
+ for this operation as described in [RFC2911], section 3.1.5.
+ The client MUST use the URI value as the target of this
+ operation that the Printer returns in the "uri" field (see Table
+ 1) in the Get-Printer-Attributes response. Furthermore, the
+ client MUST use the appropriate authorization and security
+ regime for this URI as indicated by the Printer's "printer-uri-
+ supported", "uri-authentication-supported" and "uri-security-
+ supported" attributes (see [RFC2911] sections 4.4.1, 4.4.2, and
+ 4.4.3). Only if the URI returned in the "uri" field matches the
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 17]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ URI that the client used for the Get-Printer-Attributes request
+ MAY the client use the same HTTP connection. The 'ipp' URL
+ matching rules are defined in [ipp-url] and do not include the
+ query part.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in [RFC2911], section 8.3.
+
+ "client-print-support-files-query" (text(127)):
+ The client MUST supply this attribute specifying the query part
+ [RFC2396] of the ipp uri for the desired Client Print Support
+ Files not including the "?" character that starts the query
+ part, i.e., the value of the "uri" field following the "?"
+ character returned by the Get-Printer-Attributes in one of the
+ values of the "client-print-support-files-supported" (1setOf
+ octetString(MAX)) Printer attribute (see Table 1) that had an
+ 'ipp' scheme.
+
+
+3.3.2 Get-Client-Print-Support-Files Response
+
+
+ The Printer object returns the following sets of attributes as part
+ of the Get-Client-Print-Support-Files Response:
+
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) operation attribute as described in [RFC2911],
+ sections 13 and 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911], section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+ See [RFC2911], section 3.1.7 for details on returning Unsupported
+ Attributes.
+
+
+ Group 3: Printer Object Attributes
+ "client-print-support-files-supported" (octetString(MAX)).
+ This attribute identifies the properties of the returned Client
+ Print Support Files. The Printer object MUST return this
+ attribute if the response includes Group 4 (i.e., if a set of
+ Client Print Support Files identified by the supplied "client-
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 18]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ print-support-files-query" operation attribute was found). The
+ Printer MUST return all configured fields for the selected
+ Client Print Support Files in the format shown in section 3.1.
+
+
+ Group 4: Client Print Support Files
+ The printer MUST supply the Client Print Support Files that match
+ the client's criteria following the "end-of-attributes" tag. All
+ necessary files MUST be compressed into a single transferred file.
+
+
+4 Conformance
+
+ A Printer conforming to this specification:
+
+ 1.MUST support the "client-print-support-files-supported" Printer
+ Description attribute as defined in section 3.1, including all
+ of the REQUIRED fields defined in Table 1 and MAY support the
+ OPTIONAL fields defined in Table 1.
+
+ 2.MUST support the "client-print-support-files-filter" operation
+ attribute in the Get-Printer-Attributes request as defined in
+ section 3.2, including all of the fields listed in Table 3 and
+ ignoring any fields not recognized.
+
+ 3.MUST support at least one of the following URI schemes that
+ identify the support files: 'ftp', 'http', or 'ipp', of which
+ the 'ipp' scheme is the RECOMMENDED one.
+
+ 4.SHOULD support the Get-Client-Print-Support-Files operation as
+ described in section 3.3. If this operation is supported, then
+ one of the supported schemes MUST be 'ipp'.
+
+ 5.SHOULD support TLS as described in section 9.
+
+ 6.SHOULD support the downloading of Client Print Support Files
+ that have been digitally signed as described in section 9.
+
+ A client conforming to this specification:
+
+ 1.MUST ignore any fields returned by the Printer in the "client-
+ print-support-files-supported" Printer Description attribute
+ that the client does not recognize or support.
+
+ 2.SHOULD be able to retrieve Client Print Support Files by either
+ FTP Get or HTTP Get operations.
+
+ 3.MUST be able to retrieve Client Print Support Files using the
+ Get-Client-Print-Support-Files operation, i.e., support the
+ 'ipp' scheme.
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 19]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ 4.MUST supply the proper URI value for the "printer-uri" operation
+ attribute as specified in section 3.3.1 under Target:.
+
+ 5.MUST validate that files that are supposed to be digitally
+ signed are done with the indicated mechanism as described in
+ section 9.
+
+ 6.SHOULD support TLS as described in section 9.
+
+
+5 Encoding of the Operation Layer
+
+ This extension uses the operation layer encoding described in
+ [RFC2910].
+
+
+6 Encoding of Transport Layer
+
+ This specification uses the transport layer encoding described in
+ [RFC2910] with the following extensions.
+
+ New Error codes:
+
+ 0x0417 client-error-client-print-support-file-not-found
+
+ New Operation code
+
+ 0x0021 Get-Client-Print-Support-Files
+
+
+7 IANA Considerations
+
+ The IANA-registered operating system names that IANA has registered
+ [os-names] are required by this spec for use in the "os-type" field
+ (see Table 1).
+
+ Table 1 of this document defines possible 'keyword' values for the
+ "cpu-type" field. However, the existing IANA machine registration
+ [cpu-names] is inadequate for two reasons: a) it is really a machine
+ model number, not a CPU type, and b) it doesn't express whether a
+ CPU is 16-bit, 32-bit, or 64-bit which needs to be indicated in the
+ keyword value. Therefore, the "os-type" field will be a new
+ registration with initial values assigned.
+
+ The rest of this section contains the exact information for IANA to
+ add to the IPP Registries according to the procedures defined in RFC
+ 2911 [RFC2911] section 6.
+
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 20]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ Note to RFC Editors: Replace RFC NNNN below with the RFC number
+ for this document, so that it accurately reflects the content of
+ the information for the IANA Registry.
+
+
+7.1 Attribute Registrations
+
+ The attributes and fields defined in this document will be published
+ by IANA according to the procedures in RFC 2911 [RFC2911] section 6.2
+ with the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/attributes/
+
+ The registry entry will contain the following information:
+
+ Printer Description Attributes: Ref: Section:
+ client-print-support-files-supported (1setOf octetString(MAX))
+ RFC NNNN 3.1
+
+ For purposes of IANA attribute registration, the following fields of
+ the "client-print-support-files-supported" and the "client-print-
+ support-files-filter" attributes are registered following the
+ procedures for IPP attribute registration:
+ Ref: Section:
+ uri (uri) RFC NNNN 3.1
+ os-type (type2 keyword) RFC NNNN 3.1
+ cpu-type (type2 keyword) RFC NNNN 3.1
+ document-format (mimeMediaType) RFC NNNN 3.1
+ natural-language (naturalLanguage) RFC NNNN 3.1
+ compression (type2 keyword) RFC NNNN 3.1
+ file-type (type2 keyword) RFC NNNN 3.1
+ client-file-name (name(MAX)) RFC NNNN 3.1
+ policy (type2 keyword) RFC NNNN 3.1
+ file-size (integer(0:MAX)) RFC NNNN 3.1
+ file-version (name(MAX)) RFC NNNN 3.1
+ file-date-time (text(25)) RFC NNNN 3.1
+ file-info (text(127)) RFC NNNN 3.1
+ digital-signature (type2 keyword) RFC NNNN 3.1
+
+ uri-scheme (uriScheme) RFC NNNN 3.2
+
+ Operation Attributes: Ref: Section:
+ client-print-support-files-filter (octetString(MAX))RFC NNNN 3.2
+
+
+
+
+
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 21]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+7.2 Operation Registrations
+
+ The operations defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.4 with
+ the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/operations/
+
+ The registry entry will contain the following information:
+
+ Operations: Ref. Section:
+ Get-Client-Print-Support-Files RFC NNNN 3.3
+
+
+8 Internationalization Considerations
+
+ All text representations introduced by this specification adhere to
+ the internationalization-friendly representation supported by IPP.
+ This work is also accommodates the use of Client Print Support Files
+ of different languages.
+
+
+9 Security Considerations
+
+ The IPP Model and Semantics document [RFC2911] discusses high-level
+ security requirements (Client Authentication, Server Authentication
+ and Operation Privacy). Client Authentication is the mechanism by
+ which the client proves its identity to the server in a secure
+ manner. Server Authentication is the mechanism by which the server
+ proves its identity to the client in a secure manner. Operation
+ Privacy is defined as a mechanism for protecting operations from
+ eavesdropping.
+
+ Only operators of a printer SHOULD be allowed to set the "client-
+ print-support-files-supported" attribute and only users of the
+ printer SHOULD be allowed to query that information.
+
+ The IPP extension described in this document introduces the potential
+ for a security threat previously not encountered by IPP. As Client
+ Print Support Files might exist in the form of executable objects (as
+ is the case with printer drivers, for example), additional provisions
+ are needed to prevent the distribution of malicious code through this
+ mechanism. Digital signatures provide the message level security
+ commonly used to help consumers of network resources verify the
+ authenticity and integrity of those resources. Specifically, digital
+ signatures help defend against security threats such as message
+ insertion, message deletion, and message modification, and their
+ combined use into man-in-the-middle attacks.
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 22]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ This document identifies some commonly used signing mechanisms (SMIME
+ [RFC2634], PGP [RFC1991], DSS [dss], and XML Digital Signatures
+ [xmldsig]), though any others MAY be used. Of course, it is assumed
+ that once end-users know the identity of the provider of Client Print
+ Support Files, they can make the correct determination as to whether
+ it is safe to use those files.
+
+ Printers that support the Get-Client-Print-Support-Files operation
+ SHOULD support the downloading of Client Print Support Files that
+ have been digitally signed. Clients that invoke the Get-Client-
+ Print-Support-Files operation MUST make sure that Client Print
+ Support Files that are supposed to be signed (i.e., whose client-
+ print-support-files-supported attribute value includes the "digital-
+ signature" field) are indeed signed via the specified mechanism when
+ downloaded from the printer.
+
+ Furthermore, printers that support the Get-Client-Print-Support-Files
+ operation SHOULD implement TLS to provide application level channel
+ security and enable users to reliably authenticate the source of the
+ Client Print Support Files.
+
+
+10 References
+
+
+ [cpu-names]
+ IANA Registry of CPU Names at ftp://ftp.isi.edu/in-
+ notes/iana/assignments/XXX.
+
+ [dss]
+ U.S. Department of Commerce, "Digital Signature Standard (DDS)",
+ Federal Information Processing Standards Publication 186-1 (FIPS
+ PUB 186-1), December 15, 1998.
+
+ [ipp-url]
+ Herriot, R., McDonald, I., "Internet Printing Protocol (IPP): IPP
+ URL Scheme." <draft-ietf-ipp-url-scheme-02.txt>, February 14,
+ 2001.
+
+ [os-names]
+ IANA Registry of Operating System Names at ftp://ftp.isi.edu/in-
+ notes/iana/assignments/operating-system-names.
+
+ [RFC1991]
+ D. Atkins, W. Stallings, P. Zimmermann, "PGP Message Exchange
+ Formats", RFC 1991, August, 1996.
+
+ [RFC2026]
+ S. Bradner, "The Internet Standards Process -- Revision 3", RFC
+ 2026, October 1996.
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 23]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+ [RFC2396]
+ Berners-Lee, T., Fielding, R., Masinter, L., "Uniform Resource
+ Identifiers (URI): Generic Syntax", RFC 2396, August 1998.
+
+ [RFC2518]
+ Goland, Y., et al, "HTTP Extensions for Distributed Authoring --
+ WEBDAV", RFC 2518, February 1999.
+
+ [RFC2616]
+ R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P.
+ Leach, T. Berners-Lee, "Hypertext Transfer Protocol - HTTP/1.1",
+ RFC 2616, June 1999.
+
+ [RFC2634]
+ P. Hoffman, "Enhanced Security Services for S/MIME", RFC 2634, June
+ 1999.
+
+ [RFC2910]
+ Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet Printing
+ Protocol/1.1: Encoding and Transport", RFC 2910, September 2000.
+
+ [RFC2911]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell,
+ "Internet Printing Protocol/1.0: Model and Semantics", RFC 2911,
+ September 2000.
+
+ [xmldsig]
+ D. Eastlake, J. Reagle, D. Solo "XML-Signature Syntax and
+ Processing", <draft-ietf-xmldsig-core-11.txt>, October 31, 2000.
+
+
+11 Author's Addresses
+
+ Hugo Parra
+ Novell, Inc.
+ 1800 South Novell Place
+ Provo, UT 84606
+
+ Phone: 801-861-3307
+ Fax: 801-861-4025
+ e-mail: hparra@novell.com
+
+ Ted Tronson
+ Novell, Inc.
+ 1800 South Novell Place
+ Provo, UT 84606
+
+ Phone: 801-861-3338
+ Fax: 801-861-4025
+ e-mail: ttronson@novell.com
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 24]
+
+
+INTERNET-DRAFT IPP: Printer Installation Extension February 28, 2001
+
+
+
+ Thomas N. Hastings
+ Xerox Corp.
+ 737 Hawaii St. ESAE 231
+ El Segundo, CA 90245
+
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ e-mail: hastings@cp10.es.xerox.com
+
+
+
+12 Full Copyright Statement
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+Parra, Tronson, Hastings Expires August 28, 2001 [page 25]
diff --git a/standards/draft-ietf-ipp-job-printer-set-ops-03.txt b/standards/draft-ietf-ipp-job-printer-set-ops-03.txt
new file mode 100644
index 000000000..4d628f637
--- /dev/null
+++ b/standards/draft-ietf-ipp-job-printer-set-ops-03.txt
@@ -0,0 +1,3828 @@
+
+
+
+
+
+
+INTERNET-DRAFT T. Hastings
+<draft-ietf-ipp-job-printer-set-ops-03.txt> R. Herriot
+Category: standards track Xerox Corporation
+ Carl Kugler
+ H. Lewis
+ IBM Corporation
+ January 22, 2001
+
+ Internet Printing Protocol (IPP):
+ Job and Printer Set Operations
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+
+Status of this Memo
+
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of [RFC2026]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress".
+
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+ The list of Internet-Draft Shadow Directories can be accessed as
+ http://www.ietf.org/shadow.html.
+
+
+Abstract
+
+
+ This document specifies 3 additional OPTIONAL operations for use with
+ the Internet Printing Protocol/1.0 (IPP) [RFC2565, RFC2566], IPP/1.1
+ [RFC2911, RFC2910], and future versions. The end user, operator, and
+ administrator Set-Job-Attributes and Set-Printer-Attributes
+ operations are used to modify IPP Job objects and Printer objects,
+ respectively. The third administrator Get-Printer-Supported-Values
+ operation returns values that the IPP Printer will accept for setting
+ its "xxx-supported" attributes.
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 1]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Three out-of-band values are defined for use with these operations:
+ 'delete-attribute', 'admin-define', and 'not-settable', along with a
+ 'client-error-attributes-not-settable' status code.
+
+
+ Two operation attributes: "printer-message-from-operator" (text) and
+ "job-message-from-operator" (text) are defined to set the
+ corresponding IPP/1.1 Printer and Job Description attributes with the
+ same names.
+
+ Nine Printer Description attributes are defined:
+ printer-settable-attributes-supported (1setOf type2 keyword)
+ job-settable-attributes-supported (1setOf type2 keyword)
+ document-format-varying-attributes (1setOf type2 keyword)
+ printer-message-time (integer(MIN:MAX))
+ printer-message-date-time (dateTime)
+ printer-xri-supported (1setOf collection)
+ xri-uri-scheme-supported (1setOf uriScheme)
+ xri-authentication-supported (1setOf type2 keyword)
+ xri-security-supported (1setOf type2 keyword)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 2]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics [RFC2911]
+ Internet Printing Protocol/1.1: Encoding and Transport [RFC2910]
+ Internet Printing Protocol/1.1: Implementer's Guide [IPP-IIG]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+
+ The "Design Goals for an Internet Printing Protocol" document takes a
+ broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. A few OPTIONAL operator operations have
+ been added to IPP/1.1.
+
+
+ The "Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol" document describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specification documents, and gives background and rationale
+ for the IETF working group's major decisions.
+
+
+ The "Internet Printing Protocol/1.1: Encoding and Transport" document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1 [RFC2616]. It defines the
+ encoding rules for a new Internet MIME media type called
+ "application/ipp". This document also defines the rules for
+ transporting over HTTP a message body whose Content-Type is
+ "application/ipp". This document defines a new scheme named 'ipp'
+ for identifying IPP printers and jobs.
+
+
+ The "Internet Printing Protocol/1.1: Implementer's Guide" document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.1 and some of
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+
+ The "Mapping between LPD and IPP Protocols" document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 3]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 4]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+Table of Contents
+
+
+ 1 Introduction....................................................8
+
+ 2 Terminology.....................................................8
+ 2.1 Conformance Terminology......................................9
+ 2.2 Other terminology............................................9
+
+ 3 Requirements and Use Cases......................................9
+
+ 4 Definition of the Set operations...............................10
+ 4.1 Set-Printer-Attributes Operation............................11
+ 4.1.1 Settable and READ-ONLY Printer Description attributes.....13
+ 4.1.2 Set-Printer-Attributes Request............................15
+ 4.1.3 Set-Printer-Attributes Response...........................16
+ 4.2 Set-Job-Attributes Operation................................18
+ 4.2.1 Settable and READ-ONLY Job Description attributes.........21
+ 4.2.2 Set-Job-Attributes Request................................21
+ 4.2.3 Set-Job-Attributes Response...............................22
+ 4.3 Get-Printer-Supported-Values Operation......................24
+ 4.3.1 Definition of the usage of the 'admin-define' out-of-band
+ attribute value...................................................25
+
+ 5 New Operation attributes.......................................27
+ 5.1 printer-message-from-operator (text(127))...................27
+ 5.2 job-message-from-operator (text(127)).......................28
+
+ 6 New Printer Description Attributes.............................29
+ 6.1 printer-settable-attributes-supported (1setOf type2 keyword)29
+ 6.2 job-settable-attributes-supported (1setOf type2 keyword)....30
+ 6.3 document-format-varying-attributes (1setOf type2 keyword)...30
+ 6.4 printer-message-time (integer(MIN:MAX)).....................31
+ 6.5 printer-message-date-time (dateTime)........................31
+ 6.6 printer-xri-supported (1setOf collection)...................32
+ 6.7 xri-uri-scheme-supported (1setOf uriScheme).................34
+ 6.8 xri-authentication-supported (1setOf type2 keyword).........35
+ 6.9 xri-security-supported (1setOf type2 keyword)...............35
+
+ 7 Additional status codes........................................35
+ 7.1 'client-error-attributes-not-settable' (0x0413).............35
+
+ 8 Additional out-of-band values..................................36
+ 8.1 'not-settable' out-of-band value............................36
+ 8.1.1 Encoding of the 'not-settable' out-of-band attribute value37
+ 8.2 'delete-attribute' out-of-band value........................37
+ 8.2.1 Encoding of the 'delete-attribute' out-of-band value......37
+ 8.3 'admin-define' out-of-band attribute value..................38
+ 8.3.1 Encoding of the 'admin-define' out-of-band attribute value39
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 5]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ 9 Conformance Requirements.......................................39
+
+ 10 IANA Considerations............................................41
+ 10.1 Operation Registrations.....................................41
+ 10.2 Attribute Registrations.....................................41
+ 10.3 Status code Registrations...................................42
+ 10.4 Out-of-band Attribute Value Registrations...................42
+
+ 11 Internationalization Considerations............................43
+
+ 12 Security Considerations........................................43
+
+ 13 Author's Addresses.............................................44
+
+ 14 References.....................................................45
+
+ 15 Appendix A: Allowed Values for Set-Printer-Attributes and Set-Job-
+ Attributes requests...............................................46
+
+ 16 Appendix B: Attributes returned from Get-Printer-Supported-Values
+ 60
+
+ 17 Appendix C: Full Copyright Statement...........................65
+
+
+ Table of Tables
+
+ Table 1 - Operation-Id assignments................................11
+ Table 2 - Job State Transition Table for the Set-Job-Attributes
+ operation .....................................................20
+ Table 3 - Member attributes of "printer-xri-supported" (1setOf
+ collection) ...................................................33
+ Table 4 - Validation rules for 'Any of "xxx-supported" '..........47
+ Table 5 - Validation rules for 'From Get-Printer-Supported-Values'48
+ Table 6 - Values allowed for Job Template Attributes in the Set-Job-
+ Attributes Operation ..........................................50
+ Table 7 - Values allowed for Job Description Attributes in the Set-
+ Job-Attributes Operation ......................................52
+ Table 8 - Values allowed for Printer Job Template Attributes in the
+ Set-Printer-Attributes Operation ..............................54
+ Table 9 - Values allowed for Printer Description Attributes in the
+ Set-Printer-Attributes Operation ..............................57
+ Table 10 - Printer Job Template Attributes returned from Get-Printer-
+ Supported-Values ..............................................61
+ Table 11 - Printer Job Template Attributes returned from Get-Printer-
+ Supported-Values ..............................................61
+ Table 12 - Printer Description Attributes returned from Get-Printer-
+ Supported-Values ..............................................62
+ Table 13 - Printer Job Template Attributes returned from Get-Printer-
+ Supported-Values ..............................................62
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 6]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 14 - Printer Job Template Attributes returned from Get-Printer-
+ Supported-Values ..............................................63
+ Table 15 - Printer Description Attributes returned from Get-Printer-
+ Supported-Values ..............................................64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 7]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+1 Introduction
+
+
+ The Internet Printing Protocol (IPP) is an application level protocol
+ that can be used for distributed printing using Internet tools and
+ technologies. IPP version 1.1 [RFC2911, RFC2910] focuses on end user
+ functionality with a few administrative operations included. This
+ document defines additional OPTIONAL end user, operator, and
+ administrator Set-Job-Attributes and Set-Printer-Attributes
+ operations used to modify IPP Job objects and Printer objects,
+ respectively. It also defines a third administrator Get-Printer-
+ Supported-Values operation that returns values that the IPP Printer
+ will accept for setting its "xxx-supported" attributes. The Get-
+ Printer-Supported-Values operation MUST be supported, if the
+ implementation supports setting any "xxx-supported" Printer
+ attributes using the Set-Printer-Attributes operation.
+
+
+ Three out-of-band values are defined for use with these three
+ operations: 'delete-attribute' for deleting Job attributes with the
+ Set-Job-Attributes request, 'not-settable' for use in either the Set-
+ Job-Attributes or Set-Printer-Attributes responses, and 'admin-
+ define' for use in the Get-Printer-Supported-Values response.
+
+
+ Two operation attributes: "printer-message-from-operator" (text) and
+ "job-message-from-operator" (text) are defined to set the
+ corresponding IPP/1.1 Printer and Job Description attributes with the
+ same names. These operation attributes may be used with any
+ operation that affect the Printer or Job object for which an
+ operation might want to indicate a message. For the Set-Job-
+ Attributes and Set-Printer-Attributes operations, the client MUST
+ explicitly set them, rather than using these operation attributes.
+
+
+ A Printer implementation can make the value of some attributes
+ dependent on the document-format, e.g. "resolution-supported".
+
+
+ This document is an extension to IPP/1.0 [RFC2565, RFC2566] and
+ IPP/1.1 [RFC2911, RFC2910], and future versions.
+
+
+
+2 Terminology
+
+ This section defines terminology used throughout this document.
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 8]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+2.1 Conformance Terminology
+
+
+ Capitalized terms, such as MUST, MUST NOT, REQUIRED, SHOULD, SHOULD
+ NOT, MAY, NEED NOT, and OPTIONAL, have special meaning relating to
+ conformance. These terms are defined in [RFC2911] section 12.1 on
+ conformance terminology, most of which is taken from RFC 2119
+ [RFC2119].
+
+
+ The following specialization of these terms apply to this document:
+
+ REQUIRED: if an implementation supports the extensions described in
+ this document, it MUST support a REQUIRED feature.
+ OPTIONAL: if an implementation supports the extensions described in
+ this document, it MAY support an OPTIONAL feature.
+
+2.2 Other terminology
+
+
+ This document uses terms such as Job object (or Job), IPP Printer
+ object (or Printer), "operation", "request", response", "attributes",
+ "keywords", and "support". These terms have special meaning and are
+ defined in the model terminology [RFC2911] section 12.2. The
+ following additional terms are introduced in this document:
+
+ READ-ONLY: used in an attribute definition document to indicate that
+ the attribute MUST NOT be settable using an IPP protocol Set
+ operation. In other words, the attribute is not settable by
+ definition.
+ not-settable: an implementation does not support setting an
+ attribute (whether or not the attribute's definition is READ-ONLY).
+
+
+3 Requirements and Use Cases
+
+
+ The following requirements and usage are intended to be met by the
+ specification in this document.
+
+
+ 1. The end-user and the operator need a way to modify a Job that is in
+ the 'pending' or 'pending-held' state.
+
+
+ Usage: The end-user discovers that he/she forgot to include a
+ print instruction, such as "finishings" = 'staple' after submitting
+ a job. Rather than canceling the job and resubmitting it to the
+ same IPP Printer, the end-user is able to modify the job on the IPP
+ Printer.
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 9]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ The operator needs to modify a job because it is requesting a
+ particular kind of media for which there is no more, but the policy
+ is to print the job on a comparable medium.
+
+
+ 2. The system administrator needs a way to re-configure or change the
+ policy of the IPP Printer remotely.
+
+
+ Usage: The system administrator is adding additional named media
+ to the supported media list (setting 'name' values to the "media-
+ supported" Printer attribute).
+
+
+ The system administrator is reducing the capability of the IPP
+ Printer by removing one of the operations from the supported
+ operations list, such as Cancel-Job, because the policy is to run
+ the IPP Printer like a public facsimile machine. After having
+ removed Cancel-Job from the list of supported operations, an
+ administrative client needs to be able to display to an
+ administrator that the implementation is capable of being
+ reconfigured to support Cancel-Job once again.
+
+
+ The system administrator is remotely configuring the IPP Printer
+ after installing it, and so is replacing the Printer Description
+ attributes that have the out-of-band 'no-value' value (see
+ [RFC2911] section 4.1) with the proper values.
+
+
+ The operator is changing the media loaded in the input tray and so
+ is replacing the "media-ready" Job Template Printer attribute value
+ with the proper values
+
+
+
+4 Definition of the Set operations
+
+
+ The Set-Printer-Attributes operation (as are all Printer operations)
+ are directed at Printer objects. A client MUST always supply the
+ "printer-uri" operation attribute in order to identify the correct
+ target of the operation. These descriptions assume all of the common
+ semantics of IPP/1.1 Model and Semantics document [RFC2911] section
+ 3.1.
+
+
+ The Set-Job-Attributes operation (as are all Job operations) are
+ directed at Job objects. A client MUST always supply some means of
+ identifying the Job object in order to identify the correct target of
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 10]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ the operation. That job identification MAY either be a single Job
+ URI or a combination of a Printer URI with a Job ID as defined in
+ [RFC2911]. The IPP object implementation MUST support both forms of
+ identification for every job. If possible, a client SHOULD use the
+ Printer URI with a Job ID rather than a Job URI, since the 32-bit
+ "job-id" is more readily translated to and from other print protocols
+ that MAY be serving as gateways into or out of the IPP
+ implementation.
+
+
+ The Set Printer operations are summarized in Table 1:
+
+ Table 1 - Operation-Id assignments
+
+
+
+ Operation Name Operation Brief description
+ -Id
+
+
+ Set-Printer- 0x0013 Sets attribute values of the target
+ Attributes Printer object
+
+ Set-Job-Attributes 0x0014 Sets attribute values of the target
+ Job object
+
+ Get-Printer- 0x0015 Gets values that are valid for
+ Supported-Values setting "xxx-supported" attributes
+ using the Set-Printer-Attributes
+ operation
+
+
+4.1 Set-Printer-Attributes Operation
+
+
+ This OPTIONAL operation allows a client to set the values of the
+ attributes of a Printer object. In the request, the client supplies
+ the set of Printer keyword attribute names and values that are to be
+ set. In the response, the Printer object returns success or rejects
+ the entire request with indications of which attribute or attributes
+ could not be set.
+
+
+ The Printer object validates the client-supplied attributes in the
+ Set-Printer-Attributes request. For an attribute to validate it MUST
+ meet all of the following rules:
+
+
+ 1. The number of attributes supplied by the client MUST NOT exceed the
+ maximum number that the Printer supports in a Set-Printer-
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 11]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Attributes request. A Printer MUST accept at least one attribute,
+ but SHOULD accept a reasonable number in a single Set-Printer-
+ Attributes request.
+
+
+ Note: There is no way for the client to determine the maximum
+ number of attributes that the Printer supports in a Set-Printer-
+ Attributes request, except to try a reasonable number.
+
+
+ 2. The Printer MUST support the attribute.
+
+
+ 3. The attribute MUST NOT be READ-ONLY, i.e., the definition of the
+ attribute MUST NOT indicate that the attribute is READ-ONLY (see
+ Appendix A for an indication of which IPP/1.1 attributes are READ-
+ ONLY).
+
+
+ 4. The attribute MUST be settable in this implementation.
+
+
+ 5. The Printer MUST support the value according to the rules defined
+ in Appendix A, i.e., each value of each supplied "xxx" attribute
+ MUST be validated against a value of a corresponding "xxx-
+ supported" Printer attribute. One of those rules permits an
+ administrator to set arbitrary 'name' values to those "xxx-
+ supported" Printer attributes that include the 'name' attribute
+ syntax if the implementation supports the 'admin-define' out-of-
+ band value for that "xxx-supported" attribute (see section 15 and
+ 8.3).
+
+
+ 6. The attribute's values MUST NOT conflict with the values of other
+ Printer attributes, including ones being set in this same
+ operation.
+
+
+ If any of the supplied attributes does not validate, the Printer
+ object MUST reject the entire operation; the Printer object MUST NOT
+ partially set some of the supplied attributes. In other words, after
+ the operation, all the supplied attributes MUST be set or none of
+ them MUST be set, thus making the Set-Printer-Attributes an atomic
+ operation.
+
+
+ The Printer MUST accept this operation when its READ-ONLY "printer-
+ state" attribute (see RFC2911] section 4.4.11) is 'idle' or
+ 'stopped', and SHOULD accept it when the value is 'processing'. The
+ Printer MUST accept this operation for any of the values of the
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 12]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Printer object's READ-ONLY "printer-state-reasons" and "printer-is-
+ accepting-jobs" attributes, unless explicitly defined otherwise in
+ the definition of these attributes' values.
+
+
+ This operation MUST NOT change the value of attributes not specified
+ in the operation unless the definition of the attribute explicitly
+ specifies such side-effects. For example, this document explicitly
+ specifies that when this operation sets "printer-message-from-
+ operator", the Printer also MUST set the READ-ONLY "printer-message-
+ time" and READ-ONLY "printer-message-date-time" attributes to the
+ time of the operation as a side effect . In particular, if this
+ operation changes an "xxx-default" attribute, the new value MUST be
+ in the "xxx-supported" attribute or the request MUST contain a new
+ value for "xxx-supported" which contains the new value for the "xxx-
+ default". Otherwise, the Printer MUST reject the operation. In
+ general, Printer attribute definitions that are settable will not
+ define side-effects on other attributes that are settable, only side
+ effects on READ-ONLY attributes, if any.
+
+
+4.1.1 Settable and READ-ONLY Printer Description attributes
+
+
+ If the Printer supports the Set-Printer-Attributes operation, then it
+ SHOULD support setting of:
+
+
+ all Job Template Default ("xxx-default") attributes
+
+ all Job Template Supported ("xxx-supported") attributes
+
+ all Job Template Ready ("xxx-ready") attributes
+
+ that the implementation supports (see [RFC2911] section 4.2 and
+ extensions).
+
+
+ Some Printer Description attributes (see [RFC2911] section 4.4) MUST
+ NOT be settable, i.e., they are defined to be READ-ONLY. An
+ attribute marked as "READ-ONLY" in the Printer Description attribute
+ table in Appendix A is such an attribute. The Printer attributes
+ that are not marked as "READ-ONLY" MAY be settable using the Set-
+ Printer-Attributes operation, depending on implementation.
+
+
+ Note: From now on, all extensions that define new object attributes
+ will indicate whether or not the attributes are READ-ONLY, by
+ including the "READ-ONLY" adjective in their descriptions and/or
+ explicitly stating whether they MAY be settable.
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 13]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ The current values of each "xxx-supported" Printer attribute MUST
+ reflect the current policy for support of the corresponding "xxx"
+ attribute. If an "xxx-supported" Printer attribute is settable in an
+ implementation, then its value(s) MUST affect the behavior of the
+ implementation. If an "xxx-supported" Printer attribute is defined
+ to be READ-ONLY or is not-settable in an implementation, then its
+ values MUST NOT be settable using the Set-Printer-Attributes
+ operation. Consider the following example:
+
+
+ For example, if the "operations-supported" Printer Description
+ attribute (see [RFC2911] section 4.4.15) is settable in a
+ particular implementation, then changing its value with a Set-
+ Printer-Attributes operation MUST affect the operations that the
+ implementation accepts or rejects. Such an implementation will
+ need to be able to reject values for operations that it contains no
+ code support for (see section 4.3). If the "operations-supported"
+ Printer Description attribute is not settable in a particular
+ implementation, then that implementation MUST reject an attempt to
+ set it with a Set-Printer-Attributes operation, return the 'client-
+ error-attributes-not-settable' status code (see section 7.1), and
+ return the "operations-supported" attribute with the out-of-band
+ 'not-settable' value in the Unsupported Attributes Group.
+
+
+ As another example, consider an implementation in which the "media-
+ default" and "media-supported" are settable. If a client supplies
+ a Set-Printer-Attributes request that contains the "media-default"
+ attribute with a value that is not a member of the Printer's
+ "media-supported" attribute, the Printer MUST reject the request
+ and return the "client-error-conflicting-attributes" status code
+ with the "media-default" and "media-supported" attributes and their
+ values (see [RFC2911] section 3.1.7).
+
+
+ As a third example, if a client supplies a Set-Printer-Attributes
+ request that contains both the "media-default" and the "media-
+ supported" attributes, but includes a value in the "media-default"
+ that is not a member of the supplied "media-supported" attribute,
+ the Printer MUST reject the request and return the "client-error-
+ conflicting-attributes" status code with the "media-default" and
+ "media-supported" attributes and their values (see [RFC2911]
+ section 3.1.7).
+
+
+ Access Rights: The authenticated user (see [RFC2911] section 8.3)
+ performing this operation must be an operator or administrator of the
+ Printer object (see [RFC2911] Sections 1 and 8.5). Most Printer
+ attributes will require administrator access rights to set, such as
+ "xxx-supported", while some will require operator access rights only,
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 14]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ such as "media-ready" and "printer-message-from-operator". Which
+ attributes require which access rights depends on implementation and
+ MAY depend on site policy.
+
+
+4.1.2 Set-Printer-Attributes Request
+
+
+ The following sets of attributes are part of the Set-Printer-
+ Attributes Request:
+
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.1.
+
+ Target:
+ The "printer-uri" (uri) operation attribute which is the target
+ for this operation as described in [RFC2911] section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in [RFC2911] section 8.3.
+
+ "document-format" (mimeMediaType):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. This attribute is useful
+ for a client to select the document-format to which the
+ attribute modification should be applied. A Printer
+ implementation MAY allow some attributes to have different
+ values for each document format that it supports. See [RFC2911]
+ section 3.2.5.1 "Get-Printer-Attributes Request".
+
+ If the client includes this attribute, the Printer MUST change
+ the supplied attributes for the document format specified by
+ this attribute. If a supplied attribute is a member of the
+ "document-format-varying-attributes" (i.e., the attribute
+ varies by document format, see section 6.3), the Printer MUST
+ change the supplied attribute for the document format specified
+ by this attribute, but not for other document formats. If a
+ supplied attribute isn't a member of the "document-format-
+ varying-attributes" (i.e. it doesn't vary by document format),
+ the Printer MUST change the supplied attribute for all document
+ formats.
+
+ If the client omits this attribute, the Printer MUST change the
+ supplied attributes for all document formats whether or not
+ they vary by document-format.
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 15]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+ If the client supplies a value for the "document-format"
+ Operation attribute that is either 'application/octet-stream'
+ or not supported by the Printer, i.e., is not among the values
+ of the Printer object's "document-format-supported" attribute,
+ the Printer object MUST reject the operation and return the
+ 'client-error-document-format-not-supported' status code.
+ Note: the document-format 'application/octet-stream' is the
+ union of several document-formats (see [RFC2911] section
+ 3.2.5.1, Get-Printer-Attributes) and is not a true document-
+ format.
+
+
+ Group 2: Printer Attributes
+
+ The client MUST supply a set of Printer attributes with one or
+ more values (including explicitly allowed out-of-band values)
+ as defined in [RFC2911] section 4.2 Job Template Attributes
+ ("xxx-default", "xxx-supported", and "xxx-ready" attributes),
+ section 4.4 Printer Description Attributes, and any attribute
+ extensions supported by the Printer. The value(s) of each
+ Printer attribute supplied in Group 2 replaces the value(s) of
+ the corresponding Printer attribute on the target Printer
+ object. For attributes that can have multiple values (1setOf),
+ all values supplied by the client replace all values of the
+ corresponding Printer object attribute. If a Printer object
+ attribute had not been configured yet and so had the 'no-value'
+ out-of-band value (see [RFC2911] section 4.1), the supplied
+ value(s) replace the 'no-value' value.
+
+
+4.1.3 Set-Printer-Attributes Response
+
+
+ The Printer object returns the following sets of attributes as part
+ of the Get-Printer-Attributes Response:
+
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) and/or a "detailed-status-message" (text(MAX))
+ operation attribute as described in [RFC2911] sections 13 and
+ 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.2.
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 16]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+
+ Group 2: Unsupported Attributes
+
+ See [RFC2911] section 3.1.7 for details on returning
+ Unsupported Attributes.
+
+ If some of the attributes in the operation fail to validate,
+ the Printer MUST reject the operation, MUST NOT change any
+ Printer attributes, and MUST return the indicated status code
+ below. In this group, the Printer MUST also return all
+ attributes that fail to validate. The following are the
+ reasons that an attribute fails to validate and the value
+ returned for the attribute, along with the indicated status
+ code and order of detection:
+
+ 1.The number of attributes supplied by the client exceeds the
+ maximum number that the Printer supports in a Set-Printer-
+ Attributes request: return the 'client-error-request-
+ entity-too-large' (see [RFC2911] section 13.1.4.9).
+
+
+ 2.The Printer doesn't support the attribute: return the
+ attribute with the "out-of-band" value 'unsupported' (see
+ [RFC2911] section 3.1.7 and [RFC2910]) and the 'client-
+ error-attributes-or-values-not-supported (see [RFC2911]
+ section 13.1.4.12).
+
+
+ 3.The attribute is either READ-ONLY (in its definition) or is
+ not-settable in this implementation: return the attribute
+ with the "out-of-band" value 'not-settable' (see section
+ 8.1) and the 'client-error-attributes-not-settable' status
+ code (see section 7.1).
+
+
+ 4.The Printer doesn't support the value: if the attribute in
+ the operation has a single value return it. If the
+ attribute in the operation is multi-valued, return only
+ those values in a 1setOf that are not supported. Return the
+ 'client-error-attributes-or-values-not-supported' status
+ code (see [RFC2911] section 13.1.4.12).
+
+
+ 5.The values of some of the supplied attributes conflict with
+ one another and/or other Printer attribute values not being
+ set: if the conflicting attribute in the operation has a
+ single value return the attribute and the value. If the
+ attribute in the operation is multi-valued, return only the
+ attribute and those values in a 1setOf that are conflicting
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 17]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ with other attributes. Return the 'client-error-
+ conflicting-attributes' status code (see [RFC2911] section
+ 13.1.4.15).
+
+
+4.2 Set-Job-Attributes Operation
+
+
+ This OPTIONAL operation allows a client to set the values of the
+ attributes of a Job object. In the request, the client supplies the
+ set of Job keyword attribute names and values that are to be set. In
+ the response, the IPP object returns success or rejects the entire
+ request with indications of which attribute or attributes could not
+ be set.
+
+
+ This operation is almost identical to the Set-Printer-Attributes
+ operation and follows the same rules for validation (see section
+ 4.1). The only differences are that the Set-Job-Attributes operation
+ is directed at a Job object rather than a Printer object, there is no
+ "document-format" operation attribute used when setting a Job object,
+ the operation can add an attribute to the (Job) object, the 'delete-
+ attributes' out-of-band value is permitted to remove an attribute,
+ and the validation is the same as the Job Creation operations (Print-
+ Job, Print-URI, and Create-Job), i.e., depends on the "xxx-supported"
+ Printer Description attributes (see [RFC2911] section 3.1). Using
+ the Set-Printer-Attributes operation, the administrator can set
+ arbitrary 'name' values to those "xxx-supported" Printer attributes
+ that include the 'name' attribute syntax if the implementation
+ supports the 'admin-define' out-of-band value for that "xxx-
+ supported" attribute (see section 15 and 8.3). However, the Set-Job-
+ Attributes cannot be used to add unsupported names to the Job object.
+
+
+ If a client supplies a job attribute in a Set-Job-Attributes request
+ that the Printer supports, and the job was originally submitted
+ without supplying that attribute, the Printer adds the attribute to
+ the Job object.
+
+
+ If the client supplies a job attribute with the "out-of-band" value
+ 'delete-attribute' (see section 8.2), then the Printer MUST remove
+ the attribute and all of its values from the Job object, if present.
+ The semantic effect of the client supplying the 'delete-attribute'
+ value in a Set-Job-Attributes operation MUST be the same as if the
+ attribute had not been supplied with the Job object in the Job
+ Creation operation, i.e., the Printer applies its default attribute
+ or behavior with lower precedence that the PDL (see the beginning of
+ [RFC2911] section 4.2 and [RFC2911] 3.2.1.1). Any subsequent query
+ of the Job object using Get-Job-Attributes or Get-Jobs MUST NOT
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 18]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ return any attribute that has been deleted using the 'delete-
+ attribute' out-of-band value. However, a client can re-establish
+ such a deleted Job attribute with any supported value(s) using a
+ subsequent Set-Job-Attributes operation.
+
+
+ If the client supplies an attribute in a Set-Job-Attributes request
+ with the 'delete-attribute' value and that attribute is not present
+ on the Job object, the Printer ignores that supplied attribute in the
+ request, does not return the attribute in the Unsupported Attributes
+ group, and returns the 'successful-ok' status code, if there are no
+ other problems with the request.
+
+
+ The validation of the Set-Job-Attributes request is performed by the
+ Printer as if the job had been submitted originally with the new
+ attribute values (and the deleted attributes removed) and with "ipp-
+ attribute-fidelity" set to 'true', i.e., all modified attributes Job
+ attributes and values MUST be supported in combination with the Job
+ attributes not modified. If such a Job Creation operation would have
+ been accepted, then the Set-Job-Attributes MUST be accepted. If such
+ a Job Creation operation would have been rejected, then the Set-Job-
+ Attributes MUST be rejected and the Job MUST be unchanged. In
+ addition, if any of the supplied attributes are not supported, are
+ not settable, or the values are not supported, the Printer object
+ MUST reject the entire operation; the Printer object MUST NOT
+ partially set some of the supplied attributes. In other words, after
+ the operation, all the supplied attributes MUST be set or none of
+ them MUST be set, thus making the Set-Job-Attributes an atomic
+ operation.
+
+
+ The IPP object MUST accept or reject this operations when the Job's
+ READ-ONLY "job-state" attribute has the values shown in Table 2. The
+ job's current state MUST affect whether the IPP object accepts or
+ rejects the request. For example, in the case where the operation
+ creates a request for unavailable resources, the Job transitions to a
+ new state. Table 2 shows the allowed behaviors in each job state and
+ the transitions.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 19]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 2 - Job State Transition Table for the Set-Job-Attributes
+ operation
+
+
+
+ Current "job- New "job- IPP object's response status code
+ state" state" and action:
+
+
+ 'pending' 'pending' 'successful-ok'
+
+ 'pending' 'pending-held' 'successful-ok' - needed resources
+ are not ready
+
+ 'pending-held' 'pending-held' 'successful-ok'
+
+ 'pending-held' 'pending' 'successful-ok' - needed resources
+ are ready
+
+ 'processing' 'processing' 'successful-ok' or 'client-error-
+ not-possible' depending on
+ implementation, including the
+ attributes being set, whether the
+ job has started marking media,
+ etc.
+
+ 'processing- 'processing- 'successful-ok' or 'client-error-
+ stopped' stopped' not-possible' depending on
+ implementation, including the
+ attributes being set, whether the
+ job has started marking media,
+ etc.
+
+ 'completed' 'completed' 'client-error-not-possible'
+
+ 'canceled' 'canceled' 'client-error-not-possible'
+
+ 'aborted' 'aborted' 'client-error-not-possible'
+
+
+
+
+
+ This operation MUST NOT change the value of attributes not specified
+ in the operation unless the definition of the attribute explicitly
+ specifies such side-effects. In general, Job attribute definitions
+ that are settable will not define side-effects on other attributes
+ that are settable, only side effects on READ-ONLY attributes, if any.
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 20]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+4.2.1 Settable and READ-ONLY Job Description attributes
+
+
+ If the Printer supports the "job-message-from-operator" Job
+ Description attribute (see [RFC2911] section 4.3.16) and the client
+ explicitly supplies a new value for the "job-message-from-operator"
+ in the Set-Job-Attributes request, then the Printer MUST set the
+ "job-message-from-operator" Job attribute to this new value.
+
+
+ If the Printer supports the Set-Job-Attributes operation, then it
+ SHOULD support setting of:
+
+
+ all Job Template job ("xxx") attributes
+
+ that the implementation supports (see [RFC2911] section 4.2 and
+ extensions).
+
+
+ Some Job Description attributes (see [RFC2911] section 4.3) MUST NOT
+ be settable, i.e., they are defined to be READ-ONLY. An attribute
+ marked as "READ-ONLY" in the Job Description attribute table in
+ Appendix A is such an attribute. The Job attributes not marked as
+ "READ-ONLY" MAY be settable using the Set-Job-Attributes operation,
+ depending on implementation.
+
+
+ Note: From now on, all extensions that define new object attributes
+ will indicate whether or not the attributes are READ-ONLY, by
+ including the "READ-ONLY" adjective in their descriptions and/or
+ explicitly stating whether they MAY be settable.
+
+
+ Access Rights: The authenticated user (see [RFC2911] section 8.3)
+ performing this operation must either be the job owner (as determined
+ in the Job Creation operation) or an operator or administrator of the
+ Printer object (see [RFC2911] Sections 1 and 8.5).
+
+
+4.2.2 Set-Job-Attributes Request
+
+
+ The following sets of attributes are part of the Set-Job-Attributes
+ Request:
+
+
+ Group 1: Operation Attributes
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 21]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.1.
+
+ Target:
+ Either (1) the "printer-uri" (uri) plus "job-id"
+ (integer(1:MAX)) or (2) the "job-uri" (uri) operation
+ attribute(s) which define the target for this operation as
+ described in [RFC2911] section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in [RFC2911] section 8.3.
+
+
+ Group 2: Job Attributes
+
+ The client MUST supply a set of Job attributes with one or more
+ values (including explicitly allowed out-of-band values) as
+ defined in [RFC2911] section 4.2 Job Template Attributes ("xxx"
+ attributes), section 4.3 Job Description Attributes, and any
+ attribute extensions supported by the Printer. The value(s) of
+ each Job attribute supplied in Group 2 replaces the value(s) of
+ the corresponding Job attribute on the target Job object. For
+ attributes that can have multiple values (1setOf), all values
+ supplied by the client replace all values of the corresponding
+ Job object attribute.
+
+ If the client supplies an "xxx" attribute with the 'delete-
+ attribute' out-of-band value (see section 8.2), the Printer
+ MUST remove the "xxx" attribute from the Job object, if
+ present.
+
+
+4.2.3 Set-Job-Attributes Response
+
+
+ The IPP object returns the following sets of attributes as part of
+ the Set-Job-Attributes Response:
+
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) and/or a "detailed-status-message" (text(MAX))
+ operation attribute as described in [RFC2911] sections 13 and
+ 3.1.6.
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 22]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.2.
+
+
+ Group 2: Unsupported Attributes
+
+ See [RFC2911] section 3.1.7 for details on returning
+ Unsupported Attributes.
+
+ If some of the attributes in the operation fail to validate,
+ the Printer MUST reject the operation, MUST NOT change any Job
+ attributes, and MUST return the indicated status code below.
+ In this group, the Printer MUST also return all attributes that
+ fail to validate. The following are the reasons that an
+ attribute fails to validate and the value returned for the
+ attribute, along with the indicated status code and order of
+ detection:
+
+ 1.The number of attributes supplied by the client exceeds the
+ maximum number that the Printer supports in a Set-Printer-
+ Attributes request: return the 'client-error-request-
+ entity-too-large' (see [RFC2911] section 13.1.4.9).
+
+
+ 2.The Printer doesn't support the attribute: return the
+ attribute with the 'unsupported' out-of-band attribute value
+ (see [RFC2911] section 3.1.7 and [RFC2910]) and the 'client-
+ error-attributes-or-values-not-supported (see [RFC2911]
+ section 13.1.4.12).
+
+
+ 3.The attribute is READ-ONLY (in its definition) or is not-
+ settable in this implementation: return the attribute with
+ the 'not-settable' out-of-band attribute value (see section
+ 8.1) and the 'client-error-attributes-not-settable' status
+ code (see section 7.1).
+
+
+ 4.The Printer doesn't support the value: if the attribute in
+ the operation has a single value return it. If the
+ attribute in the operation is multi-valued, return only
+ those values in a 1setOf that are not supported. Return the
+ 'client-error-attributes-or-values-not-supported' status
+ code (see [RFC2911] section 13.1.4.12).
+
+
+ 5.The values of some of the supplied attributes conflict with
+ one another and/or other Job attribute values not being set:
+ if the conflicting attribute in the operation has a single
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 23]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ value return the attribute and the value. If the attribute
+ in the operation is multi-valued, return only the attribute
+ and those values in a 1setOf that are conflicting with other
+ attributes. Return the 'client-error-conflicting-
+ attributes' status code (see [RFC2911] section 13.1.4.15).
+
+
+4.3 Get-Printer-Supported-Values Operation
+
+
+ This OPTIONAL operation allows a client to request the values that
+ the Printer allows in the Set-Printer-Attributes operation for "xxx-
+ supported" attributes. If the Printer supports the Set-Printer-
+ Attributes operation AND some of its "xxx-supported" Printer
+ attributes are settable, then the Printer MUST also support this
+ operation.
+
+
+ The Printer MUST return in the Get-Printer-Supported-Values response
+ those, and only those, "xxx-supported" Printer attributes that it
+ supports setting with the Set-Printer-Attributes operation.
+ Furthermore, if a client requests the value of an attribute that is
+ not settable or is not supported (as in the Get-Printer-Attributes
+ response), the Unsupported Attributes Group of the response NEED NOT
+ contain the "requested-attributes" operation attribute with any such
+ requested (attribute keyword) values.
+
+
+ This operation has identical request/response attributes to the Get-
+ Printer-Attributes operation in IPP/1.1 [RFC2911]. The operation
+ also behaves identically to the Get-Printer-Attributes operation in
+ IPP/1.1 [RFC2911] with the following exceptions:
+
+
+ 1.The Get-Printer-Supported-Values operation supports only "xxx-
+ supported" attributes.
+
+
+ 2.The Get-Printer-Attributes operation returns the few "xxx-
+ supported" attributes that are defined to be single valued, such
+ as "page-ranges-supported" (boolean) or "pdl-override-supported"
+ (type2 keyword), as single values, while Get-Printer-Supported-
+ Values returns the possible values that can be set as a 1setOf of
+ the same attribute syntax type (See Appendix B: Attributes
+ returned from Get-Printer-Supported-Values).
+
+
+ 3.The Get-Printer-Attributes operation returns the current values of
+ requested attributes while the Get-Printer-Supported-Values
+ operation returns the values that are inherently supported by the
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 24]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ implementation code, i.e., the values that an administrative
+ client can set in a Set-Printer-Attributes request.
+
+
+ 4.The Get-Printer-Attributes operation returns the current values of
+ requested "xxx-supported" attributes that the Printer is
+ configured to accept in Job Creation operations, including
+ additional values defined by the administrator, while the Get-
+ Printer-Supported-Values operation returns only the values of
+ "xxx-supported" attributes that are inherently supported by the
+ implementation and does not return any additional values defined
+ by the administrator where the implementation supports the 'admin-
+ define' out-of-band value.
+
+
+ 5.The Get-Printer-Attributes never returns the 'admin-define' out-
+ of-band attribute value, while the Get-Printer-Supported-
+ Attributes operation does, if the implementation allows the
+ administrator to define name values by setting that "xxx-
+ supported" attribute with any 'name' value(s).
+
+
+ 6.The Get-Printer-Attributes operation only requires end-user access
+ rights, while the Get-Printer-Supported-Values requires
+ administrator access rights.
+
+
+ Access Rights: The authenticated user (see [RFC2911] section 8.3)
+ performing this operation must be an administrator of the Printer
+ object (see [RFC2911] Sections 1 and 8.5).
+
+
+4.3.1 Definition of the usage of the 'admin-define' out-of-band
+ attribute value
+
+
+ If the Set-Printer-Attributes operation allows the System
+ Administrator to define arbitrary 'name' values for an "xxx-
+ supported" attribute, then the Get-Printer-Supported-Values operation
+ MUST return the 'admin-define' out-of-band attribute value (see
+ section 8.3) as one of the values of the "xxx-supported" attribute.
+ In other words, the 'admin-define' out-of-band attribute value
+ indicates that the Printer implementation supports clients setting
+ arbitrary 'name' attribute syntax values for that "xxx-supported"
+ attribute using the Set-Printer-Attributes operation as long as the
+ attribute is defined with the 'name' attribute syntax.
+
+
+ For example, if the Get-Printer-Supported-Values operation returns
+ several keywords as the value of the "media-supported" attribute,
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 25]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ then the Set-Printer-Attributes operation MUST accept any of these
+ keywords as values for the "media-supported" attribute. If the Get-
+ Printer-Supported-Values operation returns an 'admin-define' out-of-
+ band attribute value as one of the values of the "media-supported"
+ attribute, then the Set-Printer-Attributes operation MUST accept any
+ value whose attribute syntax is 'name' as a value for the "media-
+ supported" attribute (provided that the user is properly
+ authenticated to use the Set-Printer-Attributes operation, e.g., has
+ administrative access rights).
+
+
+ The Get-Printer-Supported-Values MAY return the 'admin-define' out-
+ of-band attribute value for any IPP/1.1 or extension Job Template
+ attribute if the implementation supports allowing the System
+ Administrator to add values to the "xxx-supported" attribute using
+ the Set-Printer-Attributes operation. In this case, the Printer MUST
+ accept any 'name' value of the correct attribute syntax in a Set-
+ Printer-Attributes operation that is setting that attribute. For
+ "xxx-supported" attributes that are defined with a choice of
+ attribute syntaxes, such as 'keyword | name', it is the 'name'
+ attribute syntax that the System Administrator can use to add new
+ values, not the 'keyword' attribute syntax. For IPP/1.1 this
+ requirement includes the following Job Template attributes:
+
+ media-supported
+ job-hold-until-supported
+ job-sheets-supported
+
+ Implementations that support additional Job Template attributes that
+ include the 'name' attribute syntax, MAY use the 'admin-define' out-
+ of-band value with them.
+
+
+ If the 'admin-define' out-of-band attribute value is not one of the
+ values of an "xxx-supported" attribute returned in a Get-Printer-
+ Supported-Values response, then the Printer MUST NOT allow the Set-
+ Printer-Attributes operation for that attribute to contain a value
+ that is not one of the explicit 'keyword' or 'name' values returned
+ in a Get-Printer-Supported-Values response.
+
+
+ See Appendix B: Attributes returned from Get-Printer-Supported-Values
+ for a full list of values returned by this operation.
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 26]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+5 New Operation attributes
+
+
+ This section defines new operation attributes for use with the
+ IPP/1.1 operations indicated. As new operations are defined they
+ will also indicate explicitly whether these operation attributes are
+ defined for use with them.
+
+
+5.1 printer-message-from-operator (text(127))
+
+
+ The Printer SHOULD support this Operation attribute in following
+ operations if it supports the corresponding "printer-message-from-
+ operator" Printer Description attribute.
+
+
+ Pause-Printer
+ Resume-Printer
+ Purge-Jobs
+
+
+ The client OPTIONALLY supplies this attribute in the above
+ operations. The value of this attribute is a message from the
+ operator about the Printer object on which the operator is performing
+ the operation. If this operation attribute is supported, the Printer
+ copies the value to its "printer-message-from-operator" Printer
+ Description attribute (see [RFC2911] section 4.4.25) even if this
+ Operation attribute is a zero-length text value or consists solely of
+ white space.
+
+
+ If the Printer supports this operation attribute, it MUST support
+ both a zero-length text value and the 'no-value' out-of-band value
+ (see [RFC2911] section 4.1) to indicate that the operator has sent no
+ message. In this case, the Printer sets the value of the "printer-
+ message-from-operator" to the zero-length value or 'no-value' out-of-
+ band value, respectively. If the client queries the "printer-
+ message-from-operator" Printer attribute, the Printer returns the
+ attribute with the zero-length value or the 'no-value' value,
+ respectively.
+
+
+ In addition, the Printer automatically copies:
+
+
+ 1.the value of its "printer-up-time" attribute (see [RFC2911]
+ section 4.4.29) to its "printer-message-time" attribute,
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 27]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ 2.the value of its printer-current-time" (dateTime) attribute (see
+ [RFC2911] section 4.4.30) to its "printer-message-date-time"
+ attribute, if supported.
+
+
+ If the client omits this operation attribute, the Printer does not
+ change the value of its "printer-message-from-operator", "printer-
+ message-time" and "printer-message-date-time" Printer Description
+ attributes.
+
+
+ The "printer-message-from-operator" operation attribute MUST NOT be
+ supported as an operation attribute for the Set-Printer-Attributes
+ operation. If the operator wants to set the Printer's "printer-
+ message-from-operator" Printer Description attribute when issuing the
+ Set-Printer-Attributes operation, the client supplies the "printer-
+ message-from-operator" explicitly with its new value as one of the
+ Printer Description attributes in Group 2 in the request. The
+ Printer also updates its "printer-message-time" and "printer-message-
+ date-time" Printer Description attributes. If the client does not
+ explicitly supply the "printer-message-from-operator" with its new
+ value in the Set-Printer-Attributes request, the Printer leaves the
+ value of the Printer's "printer-message-from-operator" Printer
+ Description attribute unchanged.
+
+
+5.2 job-message-from-operator (text(127))
+
+
+ The Printer SHOULD support this Operation attribute in following
+ operations if it supports the corresponding "job-message-from-
+ operator" Job Description attribute.
+
+
+ Cancel-Job
+ Hold-Job
+ Release-Job
+ Restart-Job
+
+
+ The client OPTIONALLY supplies this attribute in the above
+ operations. The value of this attribute is a message from the
+ operator about the Job object on which the operator has just
+ performed an operation. If supported, the Printer copies the value
+ to the Job's "job-message-from-operator" Job Description attribute
+ (see [RFC2911] section 4.3.16) (even if this Operation attribute is a
+ zero-length text value or consists solely of white space).
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 28]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ If the Printer supports this operation attribute, it MUST support
+ both a zero-length text value and the 'no-value' out-of-band value
+ (see [RFC2911] section 4.1) to indicate that the operator has sent no
+ message. In this case, the Printer sets the value of the "job-
+ message-from-operator" to the zero-length value or 'no-value' out-of-
+ band value, respectively. If the client queries the "job-message-
+ from-operator" Job attribute, the IPP object returns the attribute
+ with the zero-length value or the 'no-value' value, respectively.
+
+
+ If the client omits this attribute, the Printer does not change the
+ value of its "job-message-from-operator" Job Description attribute.
+
+
+ Note: There are no corresponding 'job-message-time" and "job-
+ message-date-time" Job Description attributes, since the usual
+ lifetime of a job is limited.
+
+
+ The "job-message-from-operator" operation attribute MUST NOT be
+ supported as an operation attribute for the Set-Job-Attributes
+ operation. If the operator wants to set the Job's "job-message-from-
+ operator" Job Description attribute when issuing the Set-Job-
+ Attributes operation, the client MUST supply the "job-message-from-
+ operator" with its new value as one of the Job Description attributes
+ in Group 2 in the request. Otherwise, the Printer leaves the value
+ of the Job's "job-message-from-operator" Job Description attribute
+ unchanged by not explicitly setting the attribute. If the client
+ does not explicitly supply the "job-message-from-operator" with its
+ new value in the Set-Job-Attributes request, the Printer leaves the
+ value of the Job's "job-message-from-operator" Job Description
+ attribute unchanged.
+
+
+
+6 New Printer Description Attributes
+
+
+ The following new Printer Description attributes are needed to
+ support the new operations defined in this document.
+
+
+6.1 printer-settable-attributes-supported (1setOf type2 keyword)
+
+
+ This REQUIRED READ-ONLY Printer attribute identifies the Printer
+ object attributes that are settable in this implementation, i.e.,
+ that are settable using the Set-Printer-Attributes operations (see
+ section 4.1). This attribute MUST be supported if the Set-Printer-
+ Attributes operations is supported. The Printer MUST reject attempts
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 29]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ to set any Printer attributes that are not one of the values of this
+ attribute, returning the 'client-error-attributes-not-settable'
+ status code (see section 7.1). The value of this attribute MAY
+ depend on the value of the "document-format" operation attribute
+ supplied in the Get-Printer-Attributes operation (see [RFC2911]
+ section 3.2.5.1).
+
+
+ Standard keyword values are:
+
+ 'none': There are no settable Printer attributes.
+ 'xxx': Where 'xxx' is any of the keyword attribute names allowed
+ by section 4.1.1
+
+6.2 job-settable-attributes-supported (1setOf type2 keyword)
+
+
+ This REQUIRED READ-ONLY Printer attribute identifies the Job object
+ attributes that are settable in this implementation, i.e., that are
+ settable using the Set-Job-Attributes operation (see section 4.2).
+ This attribute MUST be supported if the Set-Job-Attributes operations
+ is supported. The Printer MUST reject attempts to set any Job
+ attributes that are not one of the values of this attribute,
+ returning the 'client-error-attributes-not-settable' status code (see
+ section 7.1).
+
+
+ Standard keyword values are:
+
+ 'none': There are no settable Job attributes.
+ 'xxx': Where 'xxx' is any of the keyword attribute names allowed
+ by section 4.2.1.
+
+6.3 document-format-varying-attributes (1setOf type2 keyword)
+
+
+ This OPTIONAL READ-ONLY Printer Description attribute contains a set
+ of attribute name keywords. This attribute SHOULD be supported by a
+ Printer object, if the Printer object has Printer attributes whose
+ value vary depending on document format (see [RFC2911] Get-Printer-
+ Attributes operation). This attribute specifies which attribute
+ values can vary by document-format. If an attribute's name "xxx" is
+ a member of this attribute and the value of attribute "xxx" is
+ changed with the Set-Printer-Attributes operation that included the
+ "document-format" operation attribute, then the Printer MUST change
+ the value for the specified document format and no other document
+ formats (see section 4.1.2). If an attribute's name "xxx" is not a
+ member of this attribute and the value of attribute "xxx" is changed
+ with the Set-Printer-Attributes operation, then the attribute is
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 30]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ changed for all document formats (whether or not the client supplied
+ the "document-format" operation attribute).
+
+
+6.4 printer-message-time (integer(MIN:MAX))
+
+
+ This OPTIONAL READ-ONLY Printer Description attribute contains the
+ time that the Printer's "printer-message-from-operator" was changed
+ by the operator using any operation where the client supplied the
+ "printer-message-from-operator" operation attribute (see section 5.1)
+ or was explicitly set using the Set-Printer-Attributes operation (see
+ section 4.1). This attribute allows the users to know when the
+ "printer-message-from-operator" attribute was last set.
+
+
+ The Printer sets the value of this attribute by copying the value of
+ the Printer's "printer-up-time" attribute (see [RFC2911] section
+ 4.3.14). If the Printer resets its "printer-up-time" attribute to 1
+ on power-up, then it MUST change the value of the "printer-message-
+ time" to 0 or a negative number as specified in [RFC2911] section
+ 4.3.14.
+
+
+ Note: This attribute helps users better understand the context for
+ the "printer-message-from-operator" message.
+
+
+6.5 printer-message-date-time (dateTime)
+
+
+ This OPTIONAL READ-ONLY Printer Description attribute contains the
+ date and time that the Printer's "printer-message-from-operator" was
+ changed by the operator using any operation where the client supplied
+ the "printer-message-from-operator" operation attribute (see section
+ 5.1) or was explicitly set using the Set-Printer-Attributes operation
+ (see section 4.1). This attribute allows the users to know when the
+ "printer-message-from-operator" attribute was last set.
+
+
+ This attribute MUST be supported if the Printer supports both the
+ "printer-message-time" and the "printer-current-time" (dateTime)
+ attributes (see [RFC2911] section 4.4.30).
+
+
+ Note: This attribute helps users better understand the context for
+ the "printer-message-from-operator" message.
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 31]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+6.6 printer-xri-supported (1setOf collection)
+
+
+ This OPTIONAL Printer Description attribute is a multi-valued
+ attribute where each value has the 'collection' attribute syntax (see
+ [ipp-coll]) containing member attributes with the same semantics as
+ the following IPP/1.1 READ-ONLY Printer Description attributes,
+ except for cardinality:
+
+ printer-uri-supported (1setOf uri) - see [RFC2911] section
+ 4.4.1
+ uri-authentication-supported (1setOf type2 keyword) - see
+ [RFC2911] section 4.4.2
+ uri-security-supported (1setOf type2 keyword) - see [RFC2911]
+ section 4.4.3
+
+ When setting the "printer-xri-supported" attribute with a Set-
+ Printer-Attributes request, the Printer MUST also set these three
+ IPP/1.1 READ-ONLY Printer Description attributes as a defined side
+ effect. Thus, this collection attribute provides the means to set
+ these three IPP/1.1 READ-ONLY attributes atomically so that they are
+ never left in a partially inconsistent state.
+
+
+ An IPP Printer MUST NOT provide any other way using IPP to set these
+ three IPP/1.1 READ-ONLY Printer Description attributes, since they
+ are READ-ONLY and MUST have consistent values at all times. Note:
+ The "xri-printer-supported" (1setOf collection) attribute can be put
+ into a directory schema that requires a single text string value,
+ such as SLP or LDPA, by using suitable delimiting characters to
+ separate member attributes of the collection and/or terminating
+ collection values. See [svrloc-printer] and [ldap-printer].
+
+
+ The member attributes of the "printer-xri-supported" (1setOf
+ collection) are given in Table 3.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 32]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 3 - Member attributes of "printer-xri-supported" (1setOf
+ collection)
+
+
+
+ Member attribute client Printer
+ MUST MUST
+ supply support
+
+
+ xri-uri (uri) yes yes
+
+ xri-authentication (1setOf type2 keyword) yes yes
+
+ xri-security (1setOf type2 keyword) yes yes
+
+
+ Each collection value MUST contain a single unique value for the
+ "xri-uri" member attribute. However, the other two member attributes
+ are multi-valued, so that a single URI can support more than one
+ authentication scheme and/or more than one security scheme. Other
+ than the uniqueness and the cardinality requirements, the semantics
+ of these three member attributes is given in [RFC2911] sections
+ 4.4.1, 4.4.2, and 4.4.3, respectively.
+
+
+ A client can query the current values using the Get-Printer-
+ Attributes operation by supplying either:
+
+
+ 1.the three IPP/1.1 attribute names: "printer-uri-supported", "uri-
+ authentication-supported", "uri-security-supported" and getting
+ back the parallel values OR
+
+
+ 2.the single attribute name: "printer-xri-supported" and getting
+ back the 1setOf collection which contains the same information
+ semantically, but in a different form.
+
+
+ A client can query what member attribute values can be set by
+ supplying the three attribute names: "xri-uri-scheme-supported",
+ "xri-authentication-supported", and "xri-security-supported" in a
+ Get-Printer-Supported-Values request and getting back the uriScheme
+ and type2 keyword values that can be set. Since the "printer-xri-
+ supported", "uri-authentication-supported", and "uri-security-
+ supported" attributes are READ-ONLY, they are not queriable with the
+ Get-Printer-Supported-Values operation (see section 4.3). See Table
+ 15.
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 33]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ When performing a Set-Printer-Attributes operation, if there are
+ multiple values for the "xri-authentication" and/or "xri-security"
+ member attributes, the Printer MUST set the corresponding three READ-
+ ONLY attributes with all possible combinations of values. For
+ example, setting the "printer-xri-supported" with the following two
+ collection values where the first URI has both 'basic' and 'digest'
+ authentication:
+
+
+ "printer-xri-supported =
+ { "xri-uri" = ipp://abc.com/p1
+ "xri-authentication" = basic, digest
+ "xri-security" = tls
+ },
+ { "xri-uri" = http://abc.com/pq
+ "xri-authentication" = none
+ "xri-security" = none
+ }
+
+
+ would cause the Printer to set the three corresponding IPP/1.1 READ-
+ ONLY attributes, each with three parallel values as follows:
+
+
+ "printer-uri-supported" = { ipp://abc.com/p1, ipp://abc.com/p1,
+ http://abc.com/pq }
+ "uri-authentication-supported" = { basic, digest, none }
+ "uri-security-supported" = { tls, tls, none }
+
+
+ Because there were two authentication values for the ipp://abc.com/p1
+ URL, that URL value is repeated. Had the ipp URL had 2
+ authentication values and 3 security values, then there would have
+ been 7 (2*3 + 1) parallel values for each of the three attributes, 6
+ with the same ipp URI and 1 with the http URI.
+
+
+6.7 xri-uri-scheme-supported (1setOf uriScheme)
+
+
+ This OPTIONAL READ-ONLY Printer Description attribute identifies the
+ URI schemes that the implementation supports for use in the "printer-
+ uri-supported" (1setOf uri) Printer Description attribute (see
+ [RFC2911] section 4.4.1) and the "xri-uri" member attribute of the
+ "xri-printer-supported" (1setOf collection) Printer Description
+ attribute (see section 6.6).
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 34]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ A Printer MUST support this attribute if it supports setting the
+ "printer-xri-supported" (1setOf collection) with the Set-Printer-
+ Attributes operation.
+
+
+6.8 xri-authentication-supported (1setOf type2 keyword)
+
+
+ This OPTIONAL READ-ONLY Printer Description attribute identifies the
+ Client Authentication mechanisms that the implementation supports for
+ use in the "uri-authentication-supported" (1setOf type2 keyword)
+ Printer Description attribute (see [RFC2911] section 4.4.2) and the
+ "xri-authentication" member attribute of the "xri-printer-supported"
+ (1setOf collection) Printer Description attribute (see section 6.6).
+
+
+ A Printer MUST support this attribute if it supports setting the
+ "printer-xri-supported" (1setOf collection) with the Set-Printer-
+ Attributes operation.
+
+
+6.9 xri-security-supported (1setOf type2 keyword)
+
+
+ This OPTIONAL READ-ONLY Printer Description attribute identifies the
+ URI schemes that the implementation supports for use in the "uri-
+ security-supported" (1setOf type2 keyword) Printer Description
+ attribute (see [RFC2911] section 4.4.3) and the "xri-security" member
+ attribute of the "xri-printer-supported" (1setOf collection) Printer
+ Description attribute (see section 6.6).
+
+
+ A Printer MUST support this attribute if it supports setting the
+ "printer-xri-supported" (1setOf collection) with the Set-Printer-
+ Attributes operation.
+
+
+
+7 Additional status codes
+
+ This section defines new status codes used by the operations defined
+ in this document.
+
+7.1 'client-error-attributes-not-settable' (0x0413)
+
+
+ The Set-Printer-Attributes or Set-Job-Attributes operation failed
+ because one or more of the specified attributes cannot be set either
+ because the attribute is defined to be READ-ONLY or the attribute is
+ not settable in this implementation (see sections 4.1.3 and 4.2.3),
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 35]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ the Printer MUST return this error code and the attribute keyword
+ name(s) and the 'not-settable' out-of-band value (see section 8.1) in
+ the Unsupported Attributes Group(see [RFC2911] section 3.1.7) for all
+ of the attributes that could not be set. When the Printer returns
+ this status, it MUST NOT change any of the attributes supplied in the
+ operation.
+
+
+
+8 Additional out-of-band values
+
+
+ This section defines additional out-of-band values. As with all out-
+ of-band values, a client or a Printer MUST NOT use an out-of-band
+ value unless the definition of the attribute in an operation request
+ and/or response explicitly allows such usage. See the beginning of
+ [RFC2911] section 4.1.
+
+
+8.1 'not-settable' out-of-band value
+
+
+ The 'not-settable' out-of-band attribute value is returned by the IPP
+ Printer in the Unsupported Attributes group of a response to indicate
+ that the attribute supplied by the client in the request is READ-ONLY
+ by definition or is not settable in this implementation.
+
+
+ The 'not-settable' out-of-band attribute value is defined for use
+ with the Set-Job-Attributes and Set-Printer-Attributes response only.
+ If a future additional "set" operation allows the 'not-settable' out-
+ of-band value, its definition document MUST indicate such use
+ explicitly, including with which attributes.
+
+
+ An IPP object MUST support the 'not-settable' out-of-band value in a
+ Set-Job-Attributes or Set-Printer-Attributes request if it supports
+ those operations. A client MUST NOT supply the 'not-settable' out-
+ of-band value in any request. An IPP object MUST NOT support the
+ 'not-settable' out-of-band value in other operations, unless the
+ operations' definition document explicitly defines such usage. If a
+ Printer receives this out-of-band value in any operation request, the
+ Printer MUST either (1) reject the entire request and return the
+ 'client-error-bad-request' status code or (2) ignore the attribute
+ and return it with the 'unsupported' out-of-band value.
+
+
+ See sections 4.1.3 and 4.2.3 in this document for an example
+ definition of the usage of the 'not-settable' out-of-band value in
+ the Set-Printer-Attributes and Set-Job-Attributes responses.
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 36]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+8.1.1 Encoding of the 'not-settable' out-of-band attribute value
+
+
+ The encoding of the 'not-settable' out-of-band value is 0x15 (see
+ [RFC2910]). The value-length MUST be 0 and the value empty.
+
+
+8.2 'delete-attribute' out-of-band value
+
+
+ The 'delete-attribute' out-of-band attribute value is supplied by the
+ client in a request to indicate that the Printer is to remove the
+ supplied attribute and all of its values from the target object, if
+ present.
+
+
+ The 'delete-attribute' out-of-band attribute value is defined for use
+ with the Set-Job-Attributes request only. If a future additional
+ "set" operation allows the 'delete-attribute' out-of-band value, its
+ definition document MUST indicate such use explicitly, including with
+ which attributes.
+
+
+ An IPP Printer MUST support the 'delete-attribute' out-of-band value
+ if it supports the Set-Job-Attributes operation. A client MUST NOT
+ supply and an IPP object MUST NOT support the 'delete-attribute' out-
+ of-band value in other operations, unless the operations' definition
+ document explicitly defines such usage. For example, the 'delete-
+ attribute' out-of-band value MUST NOT be used in the Set-Printer-
+ Attributes operation, where the absence of an attribute from an IPP
+ object indicates that the attribute is not supported. If a Printer
+ receives this out-of-band value in other operation requests, the
+ Printer MUST either (1) reject the entire request and return the
+ 'client-error-bad-request' status code or (2) ignore the attribute
+ and return it with the 'unsupported' out-of-band value.
+
+
+ See section 4.2 in this document for the definition of the usage of
+ the 'delete-attribute' out-of-band value in the Set-Job-Attributes
+ request.
+
+
+8.2.1 Encoding of the 'delete-attribute' out-of-band value
+
+
+ The encoding of the 'delete-attribute' out-of-band value is 0x16 (see
+ [RFC2910]). The value-length MUST be 0 and the value empty.
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 37]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+8.3 'admin-define' out-of-band attribute value
+
+
+ Section 4.3 defines the Get-Printer-Supported-Values response to
+ contain the values of an "xxx-supported" attribute that are supported
+ by the implementation before any additional value are defined by the
+ administrator. The 'admin-define' out-of-band attribute value is
+ returned as an additional value of an "xxx-supported" attribute in a
+ Get-Printer-Supported-Values response to indicate that the
+ implementation supports allowing an administrator to define
+ additional arbitrary 'name' values for that "xxx-supported"
+ attribute.
+
+
+ For example, if the "media-supported" (1setOf (type3 keyword | name))
+ attribute contains this value, then the Printer MUST permit an
+ administrator to add new media names to the Printer's "media-
+ supported" attribute. In order for an administrator to add new
+ values to a Printer's "xxx-supported" attribute, the client supplies
+ the existing and new values in a Set-Printer-Attributes request for
+ that attribute. The client MUST supply any such administratively
+ defined values in the Set-Printer-Attributes request using the 'name'
+ attribute syntax.
+
+
+ The 'admin-define' out-of-band attribute value is defined for use
+ with the Get-Printer-Supported-Values response only. A Printer MUST
+ NOT return the 'admin-define' out-of-band value in a Get-Printer-
+ Attributes response, since such a response indicates what an end-user
+ client can supply in a Job Creation operation. If a future
+ additional "get" operation allows the 'admin-define' out-of-band
+ value, its definition document MUST indicate such use explicitly,
+ including with which attributes.
+
+
+ An IPP Printer MUST support the 'admin-define' out-of-band value, if
+ it supports a client setting arbitrary 'name' values of an "xxx-
+ supported" Printer attribute using the Set-Printer-Attributes
+ operation. A client MUST NOT supply the 'admin-define' out-of-band
+ value in any request. An IPP object MUST NOT support the 'admin-
+ define' out-of-band value in other operations, unless the operations'
+ definition document explicitly defines such usage. If a Printer
+ receives this out-of-band value in any operation request, the Printer
+ MUST either (1) reject the entire request and return the 'client-
+ error-bad-request' status code or (2) ignore the attribute and return
+ it with the 'unsupported' out-of-band value.
+
+
+ This document defines that the 'admin-define' out-of-band value MUST
+ be used only with "xxx-supported" attributes that are defined to
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 38]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ include the 'name' attribute syntax. This out-of-band value is not
+ intended to be used with "xxx-supported" attributes of other
+ attribute syntaxes, such as 'uri', even though the administrator
+ defines arbitrary values for such attributes. If other documents
+ extend the use of the 'admin-define' out-of-band value to other
+ attribute syntaxes, such a document MUST define such use explicitly,
+ including with which attributes.
+
+
+ See section 4.3 in this document for an example definition of the
+ usage of the 'admin-define' out-of-band attribute value in any "xxx-
+ supported" attribute returned in a Get-Printer-Supported-Values
+ response that is defined to include the 'name' attribute syntax.
+
+
+8.3.1 Encoding of the 'admin-define' out-of-band attribute value
+
+
+ The encoding of the 'admin-define' out-of-band attribute value is
+ 0x17 (see [RFC2910]). The value-length MUST be 0 and the value
+ empty.
+
+
+
+9 Conformance Requirements
+
+
+ This section specifies the conformance requirements for clients and
+ IPP objects.
+
+
+ Both the Set-Job-Attributes and the Set-Printer-Attributes operations
+ defined in the document are OPTIONAL for an IPP object to support.
+ Either one MAY be supported without the other or both MAY be
+ supported. However, if the Set-Printer-Attributes operation is
+ supported, then the Get-Printer-Supported-Values operation MUST be
+ supported if any "xxx-supported" attributes are settable. Otherwise,
+ the Get-Printer-Supported-Values operation is OPTIONAL for an IPP
+ Printer to support.
+
+
+ If the Set-Printer-Attributes operation is supported, then the
+ Printer MUST support the following additional items:
+
+
+ 1.the Get-Printer-Supported-Values operation (see section 5), if
+ any "xxx-supported" attributes are settable.
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 39]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ 2.the "printer-settable-attributes-supported" Printer Description
+ attribute (see section 6.1)
+
+
+ 3.the 'not-settable' out-of-band value in responses (see section
+ 8.1)
+
+
+ 4.the 'client-error-not-settable' status code (see section 7.1)
+
+
+ 5.If "printer-message-from-operator" Printer Description attribute
+ is supported (see [RFC2911] section 4.4.25), then it MUST be
+ settable.
+
+
+ 6.the Get-Printer-Supported-Values operation (see section 4.3), if
+ any "xxx-supported" attributes are settable.
+
+
+ 7.If a client can set a value with the 'name' attribute syntax for
+ one or more "xxx-supported" attributes, then the 'admin-define'
+ out-of-band attribute value (see section 8.3) MUST be supported
+ in the Get-Printer-Supported-Values response for each such
+ settable attribute (see section 4.3)
+
+
+ If the Set-Job-Attributes operation is supported, then the Printer
+ MUST support the following additional items:
+
+
+ 1.the "job-settable-attributes-supported " Printer Description
+ attribute (see section 6.2)
+
+
+ 2.the 'not-settable' out-of-band value in responses (see section
+ 8.1)
+
+
+ 3.the 'delete-attribute' out-of-band value in requests (see
+ section 8.2)
+
+
+ 4.the 'client-error-not-settable' status code (see section 7.1)
+
+
+ 5.If the "job-message-from-operator" Printer Description attribute
+ is supported (see [RFC2911] 4.3.16), then it MUST be settable.
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 40]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ It is OPTIONAL for the Printer object to support the "printer-
+ message-time" (integer) and "printer-message-date-time" (dateTime)
+ Printer Description attributes. If both the "printer-message-time"
+ (integer) and the "printer-current-time" (dateTime) (see [RFC2911]
+ section 4.4.30) attributes are supported, then the "printer-message-
+ date-time" (dateTime) Printer Description attribute MUST be
+ supported.
+
+
+ As with all out-of-band values, a client or a Printer MUST NOT use an
+ out-of-band value unless the definition document for the attribute in
+ an operation request and/or response explicitly allows such usage.
+
+
+
+10 IANA Considerations
+
+ This section contains the exact information for IANA to add to the
+ IPP Registries according to the procedures defined in RFC 2911
+ [RFC2911] section 6.
+
+ Note to RFC Editors: Replace RFC NNNN below with the RFC number for
+ this document, so that it accurately reflects the content of the
+ information for the IANA Registry.
+
+10.1 Operation Registrations
+
+ The operations defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.4 with
+ the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/operations/
+
+ The registry entry will contain the following information:
+
+ Operations: Ref. Section:
+ Set-Printer-Attributes RFC NNNN 4.1
+ Set-Job-Attributes RFC NNNN 4.2
+ Get-Printer-Supported-Values RFC NNNN 4.3
+
+
+10.2 Attribute Registrations
+
+ The attributes defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.2 with
+ the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/attributes/
+
+ The registry entry will contain the following information:
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 41]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+ Operation attributes: Ref. Section:
+ printer-message-from-operator (text(127)) RFC NNNN 5.1
+ job-message-from-operator (text(127)) RFC NNNN 5.2
+
+ Printer Description attributes: Ref. Section:
+ printer-settable-attributes-supported (1setOf type2 keyword)
+ RFC NNNN 6.1
+ job-settable-attributes-supported (1setOf type2 keyword)
+ RFC NNNN 6.2
+ document-format-varying-attributes (1setOf type2 keyword)
+ RFC NNNN 6.3
+ printer-message-time (integer(MIN:MAX)) RFC NNNN 6.4
+ printer-message-date-time (dateTime) RFC NNNN 6.5
+ printer-xri-supported (1setOf collection) RFC NNNN 6.6
+ xri-uri-scheme-supported (1setOf uriScheme) RFC NNNN 6.7
+ xri-authentication-supported (1setOf type2 keyword) 6.8
+ xri-security-supported (1setOf type2 keyword) RFC NNNN 6.9
+
+
+10.3 Status code Registrations
+
+ The status codes defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.6 with
+ the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/status-codes/
+
+ The registry entry will contain the following information:
+
+ Status codes: Ref. Section:
+ 'client-error-attributes-not-settable' (0x0413) RFC NNNN 7.1
+
+
+10.4 Out-of-band Attribute Value Registrations
+
+ The out-of-band attribute values defined in this document will be
+ published by IANA according to the procedures in RFC 2911 [RFC2911]
+ section 6.7 with the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/out-of-band-attribute-value-tags/
+
+ The registry entry will contain the following information:
+
+ Out-of-band Attribute Values: Ref. Section:
+ 'not-settable' out-of-band value RFC NNNN 8.1
+ 'delete-attribute' out-of-band value RFC NNNN 8.2
+ 'admin-define' out-of-band attribute value RFC NNNN 8.3
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 42]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+11 Internationalization Considerations
+
+ This document has the same localization considerations as the
+ [RFC2911].
+
+
+12 Security Considerations
+
+
+ The IPP Model and Semantics document [RFC2911 section 8] discusses
+ high level security requirements (Client Authentication, Server
+ Authentication and Operation Privacy). Client Authentication is the
+ mechanism by which the client proves its identity to the server in a
+ secure manner. Server Authentication is the mechanism by which the
+ server proves its identity to the client in a secure manner.
+ Operation Privacy is defined as a mechanism for protecting operations
+ from eavesdropping.
+
+
+ In addition, the introduction of the Set-Printer-Attributes and Set-
+ Job-Attributes operations creates another security threat, since the
+ client is able to modify the Printer and Job attributes stored in the
+ Printer. Such modifications could lead to denial of service.
+
+
+ A malicious user could alter the policy established by the system
+ administrator and stored in the Printer attributes. Such alteration
+ could either grant access to more resources or deny access to
+ resources that the system administrator has established. For
+ example, the malicious user could remove all of the document-format
+ values from the "document-format-supported" Printer attribute so that
+ the Printer would refuse to accept all jobs.
+
+
+ The general remedy for such malicious user actions against Printer
+ attributes is to have strong Client Authentication coupled with
+ Printer access control to limit the users who have System
+ Administrator or Operator privileges.
+
+
+ A malicious user could modify the Job Template attributes of another
+ user's Job, such as the "copies" attribute. For example, setting the
+ number of copies to a large number.
+
+
+ The general remedy for such malicious user actions against another
+ user's job is to have strong Client Authentication coupled with
+ Printer access control to limit the users who have System
+ Administrator or Operator privileges who can modify any job and, in
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 43]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ addition, store the Client Authentication with each Job so that only
+ the job owner End User can modify his/her own job.
+
+
+
+13 Author's Addresses
+
+ Carl Kugler
+ IBM
+ P.O. Box 1900
+ Boulder, CO 80301-9191
+
+ Phone: (303) 924-5060
+ FAX:
+ e-mail: kugler@us.ibm.com
+
+ Tom Hastings
+ Xerox Corporation
+ 737 Hawaii St. ESAE 231
+ El Segundo, CA 90245
+
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ e-mail: hastings@cp10.es.xerox.com
+
+ Robert Herriot
+ Xerox Corp.
+ 3400 Hill View Ave, Building 1
+ Palo Alto, CA 94304
+
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ e-mail: robert.herriot@pahv.xerox.com
+
+ Harry Lewis
+ IBM
+ P.O. Box 1900
+ Boulder, CO 80301-9191
+
+ Phone: (303) 924-5337
+ FAX:
+ e-mail: harryl@us.ibm.com
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 44]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+14 References
+
+ [ipp-coll]
+ deBry, R., , Hastings, T., Herriot, R., "Internet Printing Protocol
+ (IPP): The Collection Attribute Syntax", <draft-ietf-ipp-
+ collection-02.doc>, work in progress, March 9, 2000.
+
+ [ipp-set2]
+ Kugler, C, Hastings, T., Lewis, H., "Internet Printing
+ Protocol/1.1: Job and Printer Administrative Operations", <draft-
+ ietf-ipp-ops-set2-01.txt>, December 8, 1999.
+
+ [ldap-printer]
+ Fleming, P., Jones, K., Lewis, H., McDonald, I., "Internet Printing
+ Protocol (IPP): LDAP Schema for Printer Services", <draft-ietf-ipp-
+ ldap-printer-schema-00.txt>, work in progress, March 8, 2000.
+
+ [RFC2565]
+ Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet Printing
+ Protocol/1.0: Encoding and Transport", RFC 2565, April 1999.
+
+ [RFC2566]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell,
+ "Internet Printing Protocol/1.0: Model and Semantics", RFC 2566,
+ April 1999.
+
+ [RFC2910]
+ Herriot, R., Butler, S., Moore, P., Turner, R., "Internet Printing
+ Protocol/1.1: Encoding and Transport", RFC 2910, September 2000.
+
+ [RFC2911]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell,
+ "Internet Printing Protocol/1.0: Model and Semantics", RFC 2911,
+ September 2000.
+
+ [svrloc-printer]
+ St. Pierre, P., Isaacson, S., McDonald, I., "Definition of the
+ Printer Abstract Service Type v2.0", <draft-ietf-svrloc-printer-
+ scheme-06.txt>, work in progress, March 8, 2000.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 45]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+15 Appendix A: Allowed Values for Set-Printer-Attributes and Set-Job-
+ Attributes requests
+
+
+ This appendix is a normative part of this document and contains a
+ table of all IPP/1.1 attributes. Each row contains:
+
+ . an attribute and
+
+ . the values allowed in the Set-Printer-Attributes or Set-Job-
+ Attributes request for the attribute. The entry in each cell is
+ the name (first few words) of each item below 1, 2, 3, 4a-g, and
+ 5.
+
+ The allowed values include the following cases:
+
+ 1.READ-ONLY: the Set-Printer-Attributes or Set-Job-Attributes
+ operation MUST NOT change this attribute and MUST reject the
+ entire operation (see section 7.1).
+
+ 2.Any of "xxx-supported": the Set-Printer-Attributes or Set-Job-
+ Attributes operation accepts values that are allowed according to
+ the IPP/1.1 rules for validating the value(s) of an "xxx" Printer
+ or Job attribute against the value(s) of the corresponding "xxx-
+ supported" Printer attribute. Table 4 summarizes those validation
+ rules depending on each attribute syntax and value of an "xxx"
+ attribute supplied in the request and that of the corresponding
+ "xxx-supported" Printer attribute. The "xxx-supported" attribute
+ syntax type and value(s) are obtained from a Get-Printer-
+ Supported-Values response (see the tables in this Appendix).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 46]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 4 - Validation rules for 'Any of "xxx-supported" '
+
+
+
+ Type of "xxx" Type of "xxx- Validates if:
+ value to be supported" value
+ set
+
+
+ integer rangeOfInteger each value is in one of the
+ "xxx-supported" ranges
+
+ uri uriScheme each uri scheme matches one
+ of the "xxx-supported"
+ schemes
+
+ any boolean if the boolean "xxx-
+ supported" is 'true'
+
+ any same type each value matches an "xxx-
+ supported" value of the same
+ type
+
+
+
+ For additional non-normative explanatory information see section
+ 3.1.2.3 of the "Internet Printing Protocol/1.1: Implementer's
+ Guide" [ipp-iig]).
+
+ 3. From Get-Printer-Supported-Values: the Set-Printer-Attributes
+ operation accepts values that are allowed according to the IPP/1.1
+ rules for validating the value(s) of an "xxx" Printer attribute
+ against the value(s) of the corresponding "xxx-supported" Printer
+ attribute. Table 5 summarizes those validation rules depending on
+ each attribute syntax and value of an "xxx" attribute supplied in
+ the request and that of the corresponding "xxx-supported" Printer
+ attribute. The "xxx-supported" attribute syntax type and attribute
+ value(s) are obtained from a Get-Printer-Supported-Values response
+ (see Appendix B: Attributes returned from Get-Printer-Supported-
+ Values below).
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 47]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 5 - Validation rules for 'From Get-Printer-Supported-Values'
+
+
+
+ Type of Type of "xxx- Validates if:
+ "xxx" supported" value
+ value to
+ be set
+
+
+ integer rangeOfInteger each 'integer' value is in one of
+ the "xxx-supported" ranges
+
+ uri uriScheme the uri scheme of each value
+ matches one of the "xxx-supported"
+ schemes
+
+ any boolean if the boolean "xxx-supported" is
+ 'true'
+
+ name 'admin-define' any 'name' value matches
+ out-of-band
+ value
+
+ any same type each value matches an "xxx-
+ supported" value of the same type
+
+
+
+ For additional non-normative explanatory information see section
+ 3.1.2.3 of the "Internet Printing Protocol/1.1: Implementer's
+ Guide" [ipp-iig]).
+
+ 4. Any value of the proper attribute syntax: the Set-Printer-
+ Attributes or Set-Job-Attributes operation accepts any value of the
+ specified attribute syntax. The attribute syntaxes supported are
+ enumerated below.
+
+ a.Any text(127)
+ b.Any name(127)
+ c.Any uri
+ d.Any boolean
+ e.Any positive integer
+ f.Any dateTime
+ g.1setOf any uri
+
+ 5. Combination of 'Any of "xxx-supported"' or 'Any name'.
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 48]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ If a Printer implementation doesn't want to allow setting values
+ indicated in this Appendix as "any xxx", it can make the value be
+ not-settable.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 49]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 6 - Values allowed for Job Template Attributes in the Set-Job-
+ Attributes Operation
+
+
+
+ Job Template Attributes Values allowed for
+ Set
+
+
+
+
+ job-priority (integer(1:100)) Any of "xxx-
+ supported"
+
+ job-hold-until (type3 keyword | name (MAX)) Any of "xxx-
+ supported"
+
+ job-sheets (type3 keyword | name(MAX)) Any of "xxx-
+ supported"
+
+ multiple-document-handling (type2 keyword) Any of "xxx-
+ supported"
+
+ copies (integer(1:MAX)) Any of "xxx-
+ supported"
+
+ finishings (1setOf type2 enum) Any of "xxx-
+ supported"
+
+ page-ranges (1setOf rangeOfInteger (1:MAX)) Any of "xxx-
+ supported"
+
+ sides (type2 keyword) Any of "xxx-
+ supported"
+
+ number-up (integer(1:MAX)) Any of "xxx-
+ supported"
+
+ orientation-requested (type2 enum) Any of "xxx-
+ supported"
+
+ media (type3 keyword | name(MAX)) Any of "xxx-
+ supported"
+
+ printer-resolution (resolution) Any of "xxx-
+ supported"
+
+ print-quality (type2 enum) Any of "xxx-
+ supported"
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 50]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 51]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 7 - Values allowed for Job Description Attributes in the Set-
+ Job-Attributes Operation
+
+
+
+ Job Description Attributes Values allowed for
+ Set
+
+
+
+
+ job-uri (uri) READ-ONLY
+
+ job-id (integer(1:MAX)) READ-ONLY
+
+ job-printer-uri (uri) READ-ONLY
+
+ job-more-info (uri) READ-ONLY
+
+ job-name (name(MAX)) Any name(MAX)
+
+ job-originating-user-name (name(MAX)) READ-ONLY
+
+ job-state (type1 enum) READ-ONLY
+
+ job-state-reasons (1setOf type2 keyword) READ-ONLY
+
+ job-state-message (text(MAX)) READ-ONLY
+
+ job-detailed-status-messages (1setOf READ-ONLY
+ text(MAX))
+
+ job-document-access-errors (1setOf READ-ONLY
+ text(MAX))
+
+ number-of-documents (integer(0:MAX)) READ-ONLY
+
+ output-device-assigned (name(127)) READ-ONLY
+
+ time-at-creation (integer(MIN:MAX)) READ-ONLY
+
+ time-at-processing (integer(MIN:MAX)) READ-ONLY
+
+ time-at-completed (integer(MIN:MAX)) READ-ONLY
+
+ job-printer-up-time (integer(1:MAX)) READ-ONLY
+
+ date-time-at-creation (dateTime) READ-ONLY
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 52]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+
+ Job Description Attributes Values allowed for
+ Set
+
+
+
+
+ date-time-at-processing (dateTime) READ-ONLY
+
+ date-time-at-completed (dateTime) READ-ONLY
+
+ number-of-intervening-jobs (integer(0:MAX)) READ-ONLY
+
+ job-message-from-operator (text(127)) Any text(127)
+
+ job-k-octets (integer(0:MAX)) READ-ONLY
+
+ job-impressions (integer(0:MAX)) READ-ONLY
+
+ job-media-sheets (integer(0:MAX)) READ-ONLY
+
+ job-k-octets-processed (integer(0:MAX)) READ-ONLY
+
+ job-impressions-completed (integer(0:MAX)) READ-ONLY
+
+ job-media-sheets-completed (integer(0:MAX)) READ-ONLY
+
+ attributes-charset (charset) READ-ONLY
+
+ attributes-natural-language READ-ONLY
+ (naturalLanguage)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 53]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 8 - Values allowed for Printer Job Template Attributes in the
+ Set-Printer-Attributes Operation
+
+
+
+ Printer Job Template Attributes Values allowed
+ for Set
+
+
+ job-priority-default (integer(1:100)) Any of "xxx-
+ supported"
+
+ job-hold-until-default (type3 keyword | name Any of "xxx-
+ (MAX)) supported"
+
+ job-sheets-default (type3 keyword | name(MAX)) Any of "xxx-
+ supported"
+
+ multiple-document-handling-default (type2 Any of "xxx-
+ keyword) supported"
+
+ copies-default (integer(1:MAX)) Any of "xxx-
+ supported"
+
+ finishings-default (1setOf type2 enum) Any of "xxx-
+ supported"
+
+ sides-default (type2 keyword) Any of "xxx-
+ supported"
+
+ number-up-default (integer(1:MAX)) Any of "xxx-
+ supported"
+
+ orientation-requested-default (type2 enum) Any of "xxx-
+ supported"
+
+ media-default (type3 keyword | name(MAX)) Any of "xxx-
+ supported"
+
+ printer-resolution-default (resolution) Any of "xxx-
+ supported"
+
+ print-quality-default (type2 enum) Any of "xxx-
+ supported"
+
+ job-priority-supported (integer(1:100)) From Get-
+ Printer-
+ Supported-Values
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 54]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+
+ Printer Job Template Attributes Values allowed
+ for Set
+
+
+ job-hold-until-supported (1setOf(type3 keyword From Get-
+ | name (MAX))) Printer-
+ Supported-Values
+
+ job-sheets-supported (1setOf(type3 keyword | From Get-
+ name(MAX))) Printer-
+ Supported-Values
+
+ multiple-document-handling-supported (1setOf From Get-
+ type2 keyword) Printer-
+ Supported-Values
+
+ copies-supported (rangeOfInteger(1:MAX)) From Get-
+ Printer-
+ Supported-Values
+
+ finishings-supported (1setOf type2 enum) From Get-
+ Printer-
+ Supported-Values
+
+ page-ranges-supported (boolean) From Get-
+ Printer-
+ Supported-Values
+
+ sides-supported (1setOf type2 keyword) From Get-
+ Printer-
+ Supported-Values
+
+ number-up-supported (1setOf (integer(1:MAX) | From Get-
+ rangeOfInteger(1:MAX))) Printer-
+ Supported-Values
+
+ orientation-requested-supported (1setOf type2 From Get-
+ enum) Printer-
+ Supported-Values
+
+ media-supported (1setOf (type3 keyword | From Get-
+ name(MAX))) Printer-
+ Supported-Values
+
+ printer-resolution-supported (1setOf From Get-
+ resolution) Printer-
+ Supported-Values
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 55]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+
+ Printer Job Template Attributes Values allowed
+ for Set
+
+
+ print-quality-supported (1setOf type2 enum) From Get-
+ Printer-
+ Supported-Values
+
+ media-ready (type3 keyword | name(MAX)) From Get-
+ Printer-
+ Supported-Values
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 56]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 9 - Values allowed for Printer Description Attributes in the
+ Set-Printer-Attributes Operation
+
+
+
+ Printer Description Attributes Values allowed for
+ Set
+
+
+ printer-uri-supported (1setOf uri) READ-ONLY
+
+ uri-authentication-supported (1setOf type2 READ-ONLY
+ keyword)
+
+ uri-security-supported (1setOf type2 READ-ONLY
+ keyword)
+
+ printer-xri-supported (1setOf collection)
+ member attributes:
+
+ xri-uri (uri) any uriScheme of
+ "xri-uri-scheme-
+ supported" from
+ Get-Printer-
+ Attributes
+
+ xri-authentication (1setOf type2 keyword) any keyword of
+ "xri-
+ authentication-
+ supported" from
+ Get-Printer-
+ Attributes
+
+ xri-security (1setOf type2 keyword) any keyword of
+ "xri-security-
+ supported" from
+ Get-Printer-
+ Attributes
+
+ xri-uri-scheme-supported (1setOf uriScheme) READ-ONLY
+
+ xri-authentication-supported (1setOf type2 READ-ONLY
+ keyword)
+
+ xri-security-supported (1setOf type2 READ-ONLY
+ keyword)
+
+ printer-name (name(127)) Any name(127)
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 57]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+
+ Printer Description Attributes Values allowed for
+ Set
+
+
+ printer-location (text(127)) Any text(127)
+
+ printer-info (text(127)) Any text(127)
+
+ printer-more-info (uri) Any uri
+
+ printer-driver-installer (uri) Any uri
+
+ printer-make-and-model (text(127)) Any text(127)
+
+ printer-more-info-manufacturer (uri) Any uri
+
+ printer-state (type1 enum) READ-ONLY
+
+ printer-state-reasons (1setOf type2 READ-ONLY
+ keyword)
+
+ printer-state-message (text(MAX)) READ-ONLY
+
+ ipp-versions-supported (1setOf type2 From Get-Printer-
+ keyword) Supported-Values
+
+ operations-supported (1setOf type2 enum) From Get-Printer-
+ Supported-Values
+
+ multiple-document-jobs-supported (boolean) From Get-Printer-
+ Supported-Values
+
+ charset-configured (charset) Any of "xxx-
+ supported", use
+ "charset-supported"
+
+ charset-supported (1setOf charset) From Get-Printer-
+ Supported-Values
+
+ natural-language-configured Any of "xxx-
+ (naturalLanguage) supported", use
+ "generated-natural-
+ language-supported"
+
+ generated-natural-language-supported From Get-Printer-
+ (1setOf naturalLanguage) Supported-Values
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 58]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+
+ Printer Description Attributes Values allowed for
+ Set
+
+
+ document-format-default (mimeMediaType) Any of "xxx-
+ supported"
+
+ document-format-supported (1setOf From Get-Printer-
+ mimeMediaType) Supported-Values
+
+ printer-is-accepting-jobs (boolean) READ-ONLY
+
+ queued-job-count (integer(0:MAX)) READ-ONLY
+
+ printer-message-from-operator (text(127)) Any text(127)
+
+ color-supported (boolean) From Get-Printer-
+ Supported-Values
+
+ reference-uri-schemes-supported (1setOf From Get-Printer-
+ uriScheme) Supported-Values
+
+ pdl-override-supported (type2 keyword) From Get-Printer-
+ Supported-Values
+
+ printer-up-time (integer(1:MAX)) READ-ONLY
+
+ printer-current-time (dateTime) Any dateTime **
+
+ multiple-operation-time-out any positive
+ (integer(1:MAX)) integer
+
+ compression-supported (1setOf type3 From Get-Printer-
+ keyword) Supported-Values
+
+ job-k-octets-supported From Get-Printer-
+ (rangeOfInteger(0:MAX)) Supported-Values
+
+ job-impressions-supported From Get-Printer-
+ (rangeOfInteger(0:MAX)) Supported-Values
+
+ job-media-sheets-supported From Get-Printer-
+ (rangeOfInteger(0:MAX)) Supported-Values
+
+ pages-per-minute (integer(0:MAX)) READ-ONLY
+
+ pages-per-minute-color (integer(0:MAX)) READ-ONLY
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 59]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+
+ Printer Description Attributes Values allowed for
+ Set
+
+
+ printer-settable-attributes-supported From Get-Printer-
+ (1setOf type2 keyword) Supported-Values
+
+ job-settable-attributes-supported (1setOf From Get-Printer-
+ type2 keyword) Supported-Values
+
+ document-format-varying-attributes (1setOf READ-ONLY
+ type2 keyword)
+
+ printer-message-time (integer(MIN:MAX)) READ-ONLY
+
+ printer-message-date-time(dateTime) READ-ONLY
+
+
+ ** - The "printer-current-time" (dateTime) attribute is settable in
+ order to allow an administrator to correct an incorrect dateTime or
+ time zone.
+
+
+16 Appendix B: Attributes returned from Get-Printer-Supported-Values
+
+
+ This Appendix is a normative part of this document and lists all the
+ attributes that are possible for an implementation to return in a
+ Get-Printer-Supported-Values response, i.e., all the "xxx-supported"
+ attributes that can be supplied in a Set-Printer-Attributes request.
+ READ-ONLY attributes MUST NOT be returned in a Get-Printer-Supported-
+ Values response and are indicated in the tables as "READ-ONLY - MUST
+ NOT be returned."
+
+
+ For the following attributes, the value allowed by the Set-Printer-
+ Attributes operation MUST be a single integer value in the range
+ specified by the value returned by the Get-Printer-Supported-Values
+ operation.
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 60]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 10 - Printer Job Template Attributes returned from Get-Printer-
+ Supported-Values
+
+
+
+ Printer Job Template Attributes Values Returned
+
+
+ job-priority-supported (integer(1:100)) rangeOfInteger(1:100)
+
+
+
+ For the following attributes, the value allowed by the Set-Printer-
+ Attributes operation MUST be a single rangeOfInteger value whose
+ bounds do not exceed those of the range specified by the value
+ returned by the Get-Printer-Supported-Values operation.
+
+ Table 11 - Printer Job Template Attributes returned from Get-Printer-
+ Supported-Values
+
+
+
+ Printer Job Template Attributes Values Returned
+
+
+ copies-supported (rangeOfInteger(1:MAX)) rangeOfInteger(1:MAX)
+
+
+
+
+
+ The following table has the same criteria as the last, but is for
+ Printer Description attributes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 61]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 12 - Printer Description Attributes returned from Get-Printer-
+ Supported-Values
+
+
+
+ Printer Description Attributes Values allowed for Set
+
+
+ job-k-octets-supported rangeOfInteger(0:MAX)
+ (rangeOfInteger(0:MAX))
+
+ job-impressions-supported rangeOfInteger(0:MAX)
+ (rangeOfInteger(0:MAX))
+
+ job-media-sheets-supported rangeOfInteger(0:MAX)
+ (rangeOfInteger(0:MAX))
+
+
+
+ For the following attributes, the value allowed by the Set-Printer-
+ Attributes operation MUST be one or more integers and rangeOfInteger
+ values, such that the integer values described by these integers and
+ rangeOfInteger is the same as or a subset of the integers described
+ by the integers and rangeOf Integer of value returned by the Get-
+ Printer-Supported-Values operation.
+
+ Table 13 - Printer Job Template Attributes returned from Get-Printer-
+ Supported-Values
+
+
+
+ Printer Job Template Attributes Values Returned
+
+
+ number-up-supported (1setOf (integer(1:MAX) 1setOf
+ | rangeOfInteger(1:MAX))) (integer(1:MAX) |
+ rangeOfInteger(1:MA
+ X))
+
+
+
+ For the following attributes, the value allowed by the Set-Printer-
+ Attributes operation MUST be one or more values, where each such
+ value matches a value returned by the Get-Printer-Supported-Values
+ operation. A keyword, enum, boolean, charset, naturalLanguage,
+ uriScheme, mimeMediaType or resolution value matches if it is equal.
+ For Job Template attributes with the attribute syntax 'type3 keyword
+ | name', any 'name' attribute syntax value matches the 'admin-define'
+ out-of-band value, if the implementation allows the administrator to
+ set any name values for the attribute.
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 62]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 14 - Printer Job Template Attributes returned from Get-Printer-
+ Supported-Values
+
+
+
+ Printer Job Template Attributes Values Returned
+
+
+ job-hold-until-supported (1setOf(type3 1setOf (type3
+ keyword | name (MAX))) keyword | 'admin-
+ define')
+
+ job-sheets-supported (1setOf(type3 keyword 1setOf (type3
+ | name(MAX))) keyword | 'admin-
+ define')
+
+ multiple-document-handling-supported 1setOf type2
+ (1setOf type2 keyword) keyword
+
+ finishings-supported (1setOf type2 enum) 1setOf type2 enum
+
+ page-ranges-supported (boolean) 1setOf boolean **
+
+ sides-supported (1setOf type2 keyword) 1setOf type2
+ keyword
+
+ orientation-requested-supported (1setOf 1setOf type2 enum
+ type2 enum)
+
+ media-supported (1setOf (type3 keyword | 1setOf (type3
+ name(MAX))) keyword | 'admin-
+ define')
+
+ printer-resolution-supported (1setOf 1setOf resolution
+ resolution)
+
+ print-quality-supported (1setOf type2 enum) 1setOf type2 enum
+
+
+ ** Note: the Get-Printer-Supported-Values returns a '1setOf boolean'
+ so that all possible values are indicated, while Get-Printer-
+ Attributes returns only a single 'boolean' value.
+
+
+ The following table has the same criteria as the last, but is for
+ Printer Description attributes.
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 63]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ Table 15 - Printer Description Attributes returned from Get-Printer-
+ Supported-Values
+
+
+
+ Printer Description Attributes Values allowed for
+ Set
+
+
+ printer-uri-supported (1setOf uri) READ-ONLY - MUST
+ NOT be returned
+
+ uri-authentication-supported (1setOf type2 READ-ONLY - MUST
+ keyword) NOT be returned
+
+ uri-security-supported (1setOf type2 READ-ONLY - MUST
+ keyword) NOT be returned
+
+ xri-printer-supported (1setOf collection) MUST NOT be
+ returned; see next
+ three attributes
+ returned with Get-
+ Printer-Attributes:
+
+ xri-uri-scheme-supported (1setOf uriScheme) READ-ONLY - MUST
+ NOT be returned
+
+ xri-authentication-supported (1setOf type2 READ-ONLY - MUST
+ keyword) NOT be returned
+
+ xri-security-supported (1setOf type2 READ-ONLY - MUST
+ keyword) NOT be returned
+
+ ipp-versions-supported (1setOf type2 1setOf type2
+ keyword) keyword
+
+ operations-supported (1setOf type2 enum) 1setOf type2
+ keyword
+
+ multiple-document-jobs-supported (boolean) 1setOf boolean **
+
+ charset-supported (1setOf charset) 1setOf charset
+
+ generated-natural-language-supported 1setOf
+ (1setOf naturalLanguage) naturalLanguage
+
+ document-format-supported (1setOf 1setOf
+ mimeMediaType) mimeMediaType
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 64]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+
+
+ Printer Description Attributes Values allowed for
+ Set
+
+
+ color-supported (boolean) 1setOf boolean **
+
+ reference-uri-schemes-supported (1setOf 1setOf uriScheme
+ uriScheme)
+
+ pdl-override-supported (type2 keyword) 1setOf type2
+ keyword **
+
+ compression-supported (1setOf type3 1setOf type3
+ keyword) keyword
+
+ printer-settable-attributes-supported 1setOf type2
+ (1setOf type2 keyword) keyword
+
+ job-settable-attributes-supported (1setOf 1setOf type2
+ type2 keyword) keyword
+
+
+ ** Note: the Get-Printer-Supported-Values returns a '1setOf X' so
+ that all possible values are indicated, while Get-Printer-Attributes
+ returns only a single 'X' value.
+
+
+
+
+17 Appendix C: Full Copyright Statement
+
+
+ Copyright (C) The Internet Society (1998,1999,2000,2001). All Rights
+ Reserved
+
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 65]
+
+
+INTERNET-DRAFT IPP: Job and Printer Set Operations January 22, 2001
+
+
+ followed, or as required to translate it into languages other than
+ English.
+
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Expires: July 22, 2001 [Page 66]
diff --git a/standards/draft-ietf-ipp-job-prog-02.txt b/standards/draft-ietf-ipp-job-prog-02.txt
new file mode 100644
index 000000000..68ac0f577
--- /dev/null
+++ b/standards/draft-ietf-ipp-job-prog-02.txt
@@ -0,0 +1,986 @@
+
+
+
+
+
+
+INTERNET-DRAFT
+<draft-ietf-ipp-job-prog-02.txt> T. Hastings
+Category: standards track Xerox Corporation
+ H. Lewis
+ IBM Printing Company
+ R. Bergman
+ Hitachi Koki Imaging Solutions
+ January 23, 2001
+
+ Internet Printing Protocol (IPP):
+ Job Progress Attributes
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+Status of this Memo:
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of [RFC2026]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress".
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed as
+ http://www.ietf.org/shadow.html.
+
+Abstract
+ This document defines four new Job Description attributes for
+ monitoring job progress to be registered as extensions to IPP/1.0
+ [RFC2566] and IPP/1.1 [RFC2911]. These attributes are drawn from the
+ PWG Job Monitoring MIB [rfc2707]. The new Job Description attributes
+ are:
+
+ "job-collation-type" (type2 enum)
+ "sheet-completed-copy-number" (integer(0:MAX))
+ "sheet-completed-document-number" (integer(0:MAX))
+ "impressions-completed-current-copy" (integer(0:MAX))
+
+ This document also defines a new "sheet-collate" Job Template
+ attribute to control sheet collation and to help with the
+ interpretation of the job progress attributes. These new attributes
+ may also be used by themselves in combination with the IPP/1.1 "job-
+ impressions-completed" attribute as useful job progress monitoring
+ attributes and/or may be passed in an IPP Notification (see [ipp-
+ ntfy]).
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 1]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics [RFC2911]
+ Internet Printing Protocol/1.1: Encoding and Transport [RFC2910]
+ Internet Printing Protocol/1.1: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+ Internet Printing Protocol/1.0 & 1.1: Event Notification
+ Specification [ipp-ntfy]
+ The "Design Goals for an Internet Printing Protocol" document takes a
+ broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. A few OPTIONAL operator operations have
+ been added to IPP/1.1.
+
+ The "Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol" document describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specification documents, and gives background and rationale
+ for the IETF working group's major decisions.
+
+ The "Internet Printing Protocol/1.1: Model and Semantics" document
+ describes a simplified model with abstract objects, their attributes,
+ and their operations that are independent of encoding and transport.
+ It introduces a Printer and a Job object. The Job object optionally
+ supports multiple documents per Job. It also addresses security,
+ internationalization, and directory issues.
+
+ The "Internet Printing Protocol/1.1: Encoding and Transport" document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1 [RFC2616]. It defines the
+ encoding rules for a new Internet MIME media type called
+ "application/ipp". This document also defines the rules for
+ transporting over HTTP a message body whose Content-Type is
+ "application/ipp". This document defines a new scheme named 'ipp'
+ for identifying IPP printers and jobs.
+
+ The "Internet Printing Protocol/1.1: Implementer's Guide" document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.1 and some of
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 2]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+ The "Mapping between LPD and IPP Protocols" document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+ The "Event Notification Specification" document defines OPTIONAL
+ operations that allow a client to subscribe to printing related
+ events. Subscriptions include "Per-Job subscriptions" and "Per-
+ Printer subscriptions". Subscriptions are modeled as Subscription
+ objects. Four other operations are defined for subscription objects:
+ get attributes, get subscriptions, renew a subscription, and cancel a
+ subscription.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 3]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+
+TABLE OF CONTENTS
+
+ 1 New Job Template attribute......................................5
+ 1.1 sheet-collate (type2 keyword) ................................5
+
+ 2 IPP Job Description attributes for monitoring Job Progress......8
+ 2.1 job-collation-type (type2 enum) .............................11
+ 2.2 sheet-completed-copy-number (integer(0:MAX)) ................12
+ 2.3 sheet-completed-document-number (integer(0:MAX)) ............13
+ 2.4 impressions-completed-current-copy (integer(0:MAX)) .........13
+
+ 3 Conformance Requirements.......................................13
+
+ 4 IANA Considerations............................................13
+ 4.1 Attribute Registrations .....................................14
+
+ 5 Internationalization Considerations............................14
+
+ 6 Security Considerations........................................14
+
+ 7 References.....................................................15
+
+ 8 Author's Addresses.............................................16
+
+ 9 Full Copyright Statement.......................................16
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 4]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+
+
+
+
+1 New Job Template attribute
+
+
+1.1 sheet-collate (type2 keyword)
+
+ +===================+======================+=====================+
+ | Job Attribute |Printer: Default Value| Printer: Supported |
+ | | Attribute | Values Attribute |
+ +===================+======================+=====================+
+ | sheet-collate | sheet-collate-default| sheet-collate- |
+ | (type2 keyword) | (type2 keyword) | supported (1setOf |
+ | | | type2 keyword) |
+ +-------------------+----------------------+---------------------+
+ This attribute specifies whether or not the media sheets of each copy
+ of each printed document in a job are to be in sequence, when
+ multiple copies of the document are specified by the 'copies'
+ attribute.
+
+ Standard keyword values are:
+
+ 'uncollated': each print-stream sheet is printed a number of times
+ in succession equal to the value of the 'copies' attribute,
+ followed by the next print-stream sheet.
+
+ 'collated': each copy of each document is printed with the print-
+ stream sheets in sequence, followed by the next document copy.
+
+ For example, suppose a document produces two media sheets as output,
+ and "copies" is equal to '6', For the 'uncollated' case, six copies
+ of the first media sheet are printed followed by six copies of the
+ second media sheet. For the 'collated' case, one copy of each of the
+ six sheets are printed followed by another copy of each of the six
+ media sheets.
+
+ Whether the effect of sheet collation is achieved by placing copies
+ of a document in multiple output bins or in the same output bin with
+ implementation defined document separation is implementation
+ dependent. Also whether it is achieved by making multiple passes
+ over the job or by using an output sorter is implementation
+ dependent.
+
+ Note: IPP/1.0 [RFC2566] and IPP/1.1 [RFC2911] is silent on whether
+ or not sheets within documents are collated. The "sheet-collate-
+ supported" Printer attribute permits a Printer object to indicate
+ whether or not it collates sheets with each document and whether it
+ allows the client to control sheet collation. An implementation is
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 5]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+ able to indicate that it supports uncollated sheets, collated sheets,
+ or both, using the 'uncollated', 'collated', or both 'uncollated' and
+ 'collated' values, respectively.
+
+ This attribute is affected by "multiple-document-handling." The
+ "multiple-document-handling" attribute describes the collation of
+ documents, and the "sheet-collate" attribute describes the semantics
+ of collating individual pages within a document. To better explain
+ the interaction between these two attributes the term "set" is
+ introduced. A "set" is a logical boundary between the delivered
+ media sheets of a printed job. For-example, in the case of a ten
+ page single document with collated pages and a request for 50 copies,
+ each of the 50 printed copies of the document constitutes a "set."
+ In the above example if the pages were uncollated, then 50 copies of
+ each of the individual pages within the document would represent each
+ "set".
+
+ The following table describes the interaction of "sheet-collate" with
+ multiple document handling.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 6]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+
+
+ "sheet- "multiple- Semantics
+ collate" document-
+ handling"
+
+
+ 'collated' 'single- Each copy of the concatenated
+ document' documents, with their pages in
+ sequence, represents a "set."
+
+ 'collated' 'single- Each copy of the concatenated
+ document-new- documents, with their pages in
+ sheet' sequence, represents a "set."
+
+ 'collated' 'separate- Each copy of each separate
+ documents- document, with its pages in
+ collated- sequence, represents a "set."
+ copies'
+
+ 'collated' 'separate- Each copy of each separate
+ documents- document, with its pages in
+ uncollated- sequence, represents a "set."
+ copies
+
+ 'uncollated' 'single- Each media sheet of the document
+ document' is printed a number of times equal
+ to the "copies" attribute; which
+ constitutes a "set."
+
+ 'uncollated' 'single- Each media sheet of the
+ document-new- concatenated documents is printed
+ sheet' a number of times equal to the
+ "copies" attribute; which
+ constitutes a "set."
+
+ 'uncollated' 'separate- This is a degenerate case, and the
+ documents- printer object MUST reject the job
+ collated- and return the status, "client-
+ copies' error-conflicting-attributes."
+
+ 'uncollated' 'separate- This is a degenerate case, and the
+ documents- printer object MUST reject the job
+ uncollated- and return the status "client-
+ copies error-conflicting-attributes."
+
+
+
+ From the above table it is obvious that the implicit value of the
+ "sheet-collate" attribute in a printer that does not support the
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 7]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+ "sheet-collate" attribute, is 'collated.' The semantics of
+ "multiple-document-handling" are otherwise nonsensical in the case
+ of separate documents.
+
+
+
+2 IPP Job Description attributes for monitoring Job Progress
+
+ The following IPP Job Description attributes are proposed to be added
+ to IPP through the type2 registration procedures. They are useful
+ for monitoring the progress of a job. They are also used at
+ attributes in the notification content in a notification report [ipp-
+ ntfy].
+
+ There are a number of Job Description attributes for monitoring the
+ progress of a job. These objects and attributes count the number of
+ K octets, impressions, sheets, and pages requested or completed. For
+ impressions and sheets, "completed" means stacked, unless the
+ implementation is unable to detect when each sheet is stacked, in
+ which case stacked is approximated when processing of each sheet
+ completes. There are objects and attributes for the overall job and
+ for the current copy of the document currently being stacked. For
+ the latter, the rate at which the various objects and attributes
+ count depends on the sheet and document collation of the job.
+
+ Consider the following four Job Description attributes that are used
+ to monitor the progress of a job's impressions:
+
+ 1."job-impressions-completed" - counts the total number of
+ impressions stacked for the job (see [RFC2911] section 4.3.18.2)
+
+ 2."impressions-completed-current-copy" - counts the number of
+ impressions stacked for the current document copy
+
+ 3."sheet-completed-copy-number" - identifies the number of the
+ copy for the current document being stacked where the first copy
+ is 1.
+
+ 4."sheet-completed-document-number" - identifies the current
+ document within the job that is being stacked where the first
+ document in a job is 1. NOTE: this attribute SHOULD NOT be
+ implemented for implementations that only support one document
+ per job.
+
+ For each of the three types of job collation, a job with three copies
+ of two documents (1, 2), where each document consists of 3
+ impressions, the four variables have the following values as each
+ sheet is stacked for one-sided printing:
+
+
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 8]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+
+"job-collation-type" = 'uncollated-sheets(3)'
+
+
+"job- "impressions- "sheet- "sheet-
+impressions- completed- completed- completed-
+completed" current-copy" copy-number" document-
+ number"
+
+ 0 0 0 0
+ 1 1 1 1
+ 2 1 2 1
+ 3 1 3 1
+ 4 2 1 1
+ 5 2 2 1
+ 6 2 3 1
+ 7 3 1 1
+ 8 3 2 1
+ 9 3 3 1
+ 10 1 1 2
+ 11 1 2 2
+ 12 1 3 2
+ 13 2 1 2
+ 14 2 2 2
+ 15 2 3 2
+ 16 3 1 2
+ 17 3 2 2
+ 18 3 3 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 9]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+
+"job-collation-type" = 'collated-documents(4)'
+
+
+ "job- "impressions- "sheet- "sheet-
+ impressions- completed- completed- completed-
+ completed" current-copy" copy- document-
+ number" number"
+
+
+ 0 0 0 0
+ 1 1 1 1
+ 2 2 1 1
+ 3 3 1 1
+ 4 1 1 2
+ 5 2 1 2
+ 6 3 1 2
+ 7 1 2 1
+ 8 2 2 1
+ 9 3 2 1
+ 10 1 2 2
+ 11 2 2 2
+ 12 3 2 2
+ 13 1 3 1
+ 14 2 3 1
+ 15 3 3 1
+ 16 1 3 2
+ 17 2 3 2
+ 18 3 3 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 10]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+
+"job-collation-type" = 'uncollated-documents(5)'
+
+ "job- "impressions- "sheet- "sheet-
+ impressions- completed- completed- completed-
+ completed" current-copy" copy- document-
+ number" number"
+
+
+ 0 0 0 0
+ 1 1 1 1
+ 2 2 1 1
+ 3 3 1 1
+ 4 1 2 1
+ 5 2 2 1
+ 6 3 2 1
+ 7 1 3 1
+ 8 2 3 1
+ 9 3 3 1
+ 10 1 1 2
+ 11 2 1 2
+ 12 3 1 2
+ 13 1 2 2
+ 14 2 2 2
+ 15 3 2 2
+ 16 1 3 2
+ 17 2 3 2
+ 18 3 3 2
+
+
+
+2.1 job-collation-type (type2 enum)
+
+ Job Collation includes sheet collation and document collation. Sheet
+ collation is defined to be the ordering of sheets within a document
+ copy. Document collation is defined to be ordering of document
+ copies within a multi-document job. The value of the "job-collation-
+ type" is affected by the value of the "sheet-collate" Job Template
+ attribute (see section 1.1), if supplied and supported.
+
+ The Standard enum values are:
+
+ '1' 'other': not one of the defined values
+
+ '2' 'unknown': the collation type is unknown
+
+ '3' 'uncollated-sheets': No collation of the sheets within each
+ document copy, i.e., each sheet of a document that is
+ to produce multiple copies is replicated before the
+ next sheet in the document is processed and stacked.
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 11]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+ If the device has an output bin collator, the
+ 'uncollated-sheets(3)' value may actually produce
+ collated sheets as far as the user is concerned (in
+ the output bins). However, when the job collation is
+ the 'uncollated-sheets(3)' value, job progress is
+ indistinguishable to a monitoring application between
+ a device that has an output bin collator and one that
+ does not.
+
+ '4' 'collated-documents': Collation of the sheets within each
+ document copy is performed within the printing device
+ by making multiple passes over either the source or
+ an intermediate representation of the document. In
+ addition, when there are multiple documents per job,
+ the i'th copy of each document is stacked before the
+ j'th copy of each document, i.e., the documents are
+ collated within each job copy. For example, if a job
+ is submitted with documents, A and B, the job is made
+ available to the end user as: A, B, A, B, .... The
+ 'collated-documents(4)' value corresponds to the IPP
+ [RFC2911] 'separate-documents-collated-copies'
+ keyword value of the "multiple-document-handling"
+ attribute.
+
+ If the job's "copies" attribute is '1' (or not
+ supplied), then the "job-collation-type" attribute is
+ defined to be '4'.
+
+
+ '5' 'uncollated-documents': Collation of the sheets within each
+ document copy is performed within the printing device
+ by making multiple passes over either the source or
+ an intermediate representation of the document. In
+ addition, when there are multiple documents per job,
+ all copies of the first document in the job are
+ stacked before the any copied of the next document in
+ the job, i.e., the documents are uncollated within
+ the job. For example, if a job is submitted with
+ documents, A and B, the job is mad available to the
+ end user as: A, A, ..., B, B, .... The 'uncollated-
+ documents(5)' value corresponds to the IPP [RFC2911]
+ 'separate-documents-uncollated-copies' keyword value
+ of the "multiple-document-handling" attribute.
+
+2.2 sheet-completed-copy-number (integer(0:MAX))
+
+ The number of the copy being stacked for the current document. This
+ number starts at 0, is set to 1 when the first sheet of the first
+ copy for each document is being stacked and is equal to n where n is
+ the nth sheet stacked in the current document copy. If the value is
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 12]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+ unknown, the Printer MUST return the 'unknown' out-of-band value (see
+ [RFC2911] section 4.1), rather than the -2 value used in some MIBs
+ [rfc2707].
+
+
+2.3 sheet-completed-document-number (integer(0:MAX))
+
+ The ordinal number of the document in the job that is currently being
+ stacked. This number starts at 0, increments to 1 when the first
+ sheet of the first document in the job is being stacked, and is equal
+ to n where n is the nth document in the job, starting with 1. If the
+ value is unknown, the Printer MUST return the 'unknown' out-of-band
+ value (see [RFC2911] section 4.1), rather than the -2 value used in
+ some MIBs [rfc2707].
+
+ Implementations that only support one document jobs SHOULD NOT
+ implement this attribute.
+
+
+2.4 impressions-completed-current-copy (integer(0:MAX))
+
+ The number of impressions completed by the device for the current
+ copy of the current document so far. For printing, the impressions
+ completed includes interpreting, marking, and stacking the output.
+ For other types of job services, the number of impressions completed
+ includes the number of impressions processed. If the value is
+ unknown, the Printer MUST return the 'unknown' out-of-band value (see
+ [RFC2911] section 4.1), rather than the -2 value used in some MIBs
+ [rfc2707].
+
+ This value SHALL be reset to 0 for each document in the job and for
+ each document copy.
+
+
+
+3 Conformance Requirements
+
+ This section summarizes the Conformance Requirements detailed in the
+ definitions in this document. In general each of the attributes
+ defined in this document are OPTIONAL for a Printer to support, so
+ that Printer implementers MAY implement any combination of
+ attributes.
+
+
+
+4 IANA Considerations
+
+ This section contains the exact information for IANA to add to the
+ IPP Registries according to the procedures defined in RFC 2911
+ [RFC2911] section 6.
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 13]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+ Note to RFC Editors: Replace RFC NNNN below with the RFC number for
+ this document, so that it accurately reflects the content of the
+ information for the IANA Registry.
+
+
+4.1 Attribute Registrations
+
+ The attributes defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.2 with
+ the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/attributes/
+
+ The registry entry will contain the following information:
+
+ Job Template attributes: Ref. Section:
+ sheet-collate (type2 keyword) RFC NNNN 1.1
+
+ Job Description attributes: Ref. Section:
+ job-collation-type (type2 enum) RFC NNNN 2.1
+ sheet-completed-copy-number (integer(0:MAX)) RFC NNNN 2.2
+ sheet-completed-document-number (integer(0:MAX))RFC NNNN 2.3
+ impressions-completed-current-copy (integer(0:MAX))
+ RFC NNNN 2.4
+
+
+
+
+5 Internationalization Considerations
+
+ The IPP extensions defined in this document require the same
+ internationalization considerations as any of the Job Template and
+ Job Descriptions attributes defined in IPP/1.1 [RFC2911].
+
+
+
+6 Security Considerations
+
+ The IPP extensions defined in this document require the same security
+ considerations as any of the Job Template attributes and Job
+ Descriptions attributes defined in IPP/1.1 [RFC2911].
+
+
+
+
+
+
+
+
+
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 14]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+7 References
+
+ [ipp-iig]
+
+ Hastings, T., Manros, C., "Internet Printing Protocol/1.1: draft-
+ ietf-ipp-implementers-guide-v11-01.txt, work in progress, May 9,
+ 2000.
+
+ [ipp-ntfy]
+
+ Isaacson, S., Martin, J., deBry, R., Hastings, T., Shepherd, M.,
+ Bergman, R., " IPP Event Notification Specification", <draft-ietf-
+ ipp-not-spec-04.txt>, work in progress, August 30, 2000.
+
+ [RFC2565]
+
+ Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet Printing
+ Protocol/1.0: Encoding and Transport", RFC 2565, April 1999.
+
+ [RFC2566]
+
+ deBry, R., , Hastings, T., Herriot, R., Isaacson, S., Powell, P.,
+ "Internet Printing Protocol/1.0: Model and Semantics", RFC 2566,
+ April 1999.
+
+ [RFC2567]
+
+ Wright, D., "Design Goals for an Internet Printing Protocol", RFC
+ 2567, April 1999.
+
+ [RFC2568]
+
+ Zilles, S., "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", RFC 2568, April 1999.
+
+ [RFC2569]
+
+ Herriot, R., Hastings, T., Jacobs, N., Martin, J., "Mapping between
+ LPD and IPP Protocols", RFC 2569, April 1999.
+
+ [RFC2707]
+
+ Bergman, R., Hastings, T., Isaacson, S., Lewis, H. "PWG Job
+ Monitoring MIB - V1", RFC 2707, November, 1999.
+
+ [RFC2910]
+
+ Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet Printing
+ Protocol/1.1: Encoding and Transport", RFC 2910, September, 2000.
+
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 15]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+ [RFC2911]
+
+ deBry, R., , Hastings, T., Herriot, R., Isaacson, S., Powell, P.,
+ "Internet Printing Protocol/1.1: Model and Semantics", RFC 2911,
+ September, 2000.
+
+
+
+8 Author's Addresses
+
+
+ Tom Hastings
+ Xerox Corporation
+ 737 Hawaii St. ESAE 231
+ El Segundo, CA 90245
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ e-mail: hastings@cp10.es.xerox.com
+
+
+
+ Harry Lewis
+ IBM
+ P.O. Box 1900
+ Boulder, CO 80301-9191
+
+ Phone: (303) 924-5337
+ FAX:
+ e-mail: harryl@us.ibm.com
+
+
+ Ron Bergman (Editor)
+ Hitachi Koki Imaging Solutions
+ 1757 Tapo Canyon Road
+ Simi Valley, CA 93063-3394
+
+ Phone: 805-578-4421
+ Fax: 805-578-4001
+ Email: rbergma@hitachi-hkis.com
+
+
+
+9 Full Copyright Statement
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 16]
+
+
+INTERNET-DRAFT IPP: Job Progress Attributes January 23, 2001
+
+
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, Lewis, Bergman Expires July 23, 2001 [page 17]
diff --git a/standards/draft-ietf-ipp-ldap-printer-schema-04.txt b/standards/draft-ietf-ipp-ldap-printer-schema-04.txt
new file mode 100644
index 000000000..583fa1675
--- /dev/null
+++ b/standards/draft-ietf-ipp-ldap-printer-schema-04.txt
@@ -0,0 +1,1456 @@
+
+
+Internet Printing Protocol Working Group Pat Fleming
+INTERNET DRAFT IBM
+Expires 20 June 2001 Ken Jones
+ eStarCom
+[Target Category: Standards Track] Harry Lewis
+ IBM
+ Ira McDonald
+ High North Inc
+ 20 December 2000
+
+ Internet Printing Protocol (IPP):
+ LDAP Schema for Printer Services
+ <draft-ietf-ipp-ldap-printer-schema-04.txt>
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+Status of This Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of RFC 2026. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress."
+
+ To view the list of Internet-Draft Shadow Directories, see
+ http://www.ietf.org/shadow.html.
+
+Abstract
+
+ This document is a product of the Internet Printing Protocol Working
+ Group, chartered by the IETF. Comments should be sent to the
+ ipp@pwg.org mailing list and the principal editor
+ flemingp@us.ibm.com.
+
+ This document defines a common printer schema for use with directory
+ services that support the Lightweight Directory Access Protocol
+ (LDAP) [RFC 2251]. Using this common printer schema enables client
+ applications to use LDAP to search for printers using application or
+ user specified search criteria. Searches are defined based on the
+ entry's type and attributes independent of the LDAP directory being
+ used.
+
+ This document describes the LDAP schema, object classes and
+ attributes, for printers and printer services. This document uses
+ the printer attributes defined in Appendix E of [RFC 2911], the
+ 'printer:' service template defined in [SLPPRT], and the mapping
+ between SLP service advertisements and LDAP descriptions of services
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 1]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+ defined in [RFC 2926] to define an LDAP printer schema.
+
+ The goal of this document is to define a consistent schema to be used
+ by printers and print servers. The LDAP printer schema described in
+ this document MAY be used in part or whole.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 2]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+ Table of Contents
+
+1. Introduction ............................................... 5
+2. Terminology ................................................ 5
+3. Definition of Object Classes ............................... 6
+ 3.1. slpServicePrinter ...................................... 7
+ 3.2. printerAbstract ........................................ 7
+ 3.3. printerService ......................................... 8
+ 3.4. printerServiceAuxClass ................................. 8
+ 3.5. printerIPP ............................................. 9
+ 3.6. printerLPR ............................................. 9
+4. Definition of Attribute Types .............................. 10
+ 4.1. printer-uri ............................................ 11
+ 4.2. printer-xri-supported .................................. 11
+ 4.3. printer-name ........................................... 12
+ 4.4. printer-natural-language-configured .................... 13
+ 4.5. printer-location ....................................... 13
+ 4.6. printer-info ........................................... 13
+ 4.7. printer-more-info ...................................... 14
+ 4.8. printer-make-and-model ................................. 14
+ 4.9. printer-ipp-versions-supported ......................... 14
+ 4.10. printer-multiple-document-jobs-supported .............. 15
+ 4.11. printer-charset-configured ............................ 15
+ 4.12. printer-charset-supported ............................. 15
+ 4.13. printer-generated-natural-language-supported .......... 16
+ 4.14. printer-document-format-supported ..................... 16
+ 4.15. printer-color-supported ............................... 16
+ 4.16. printer-compression-supported ......................... 16
+ 4.17. printer-pages-per-minute .............................. 17
+ 4.18. printer-pages-per-minute-color ........................ 17
+ 4.19. printer-finishings-supported .......................... 17
+ 4.20. printer-number-up-supported ........................... 18
+ 4.21. printer-sides-supported ............................... 18
+ 4.22. printer-media-supported ............................... 18
+ 4.23. printer-media-local-supported ......................... 18
+ 4.24. printer-resolution-supported .......................... 19
+ 4.25. printer-print-quality-supported ....................... 19
+ 4.26. printer-job-priority-supported ........................ 19
+ 4.27. printer-copies-supported .............................. 20
+ 4.28. printer-job-k-octets-supported ........................ 20
+ 4.29. printer-current-operator .............................. 20
+ 4.30. printer-service-person ................................ 20
+ 4.31. printer-delivery-orientation-supported ................ 21
+ 4.32. printer-stacking-order-supported ...................... 21
+ 4.33. printer-output-features-supported ..................... 21
+ 4.34. printer-aliases ....................................... 22
+5. Definition of Syntaxes ..................................... 23
+6. IANA Considerations ........................................ 23
+7. Internationalization Considerations ........................ 23
+8. Security Considerations .................................... 23
+9. References ................................................. 23
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 3]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+10. Acknowledgments ........................................... 24
+11. Authors' Addresses ........................................ 25
+12. Full Copyright Statement .................................. 26
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 4]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+1. Introduction
+
+ The use of directory services based on the Lightweight Directory
+ Access Protocol [RFC 2251] is becoming increasingly popular for
+ distributed services. To ensure interoperability between vendor
+ implementations it is crucial to standardize the schemas which
+ describe these services.
+
+ Under the auspices of the IETF IPP Working Group the IPP protocol is
+ being developed to bring a standards based printing solution to the
+ Internet.
+
+ Section 16 of [RFC 2911] describes a list of attributes which should
+ be included in a general directory schema describing IPP print
+ services. The syntax for each of these attributes is described in
+ detail in [RFC 2911] and [SLPPRT]. This document will take these
+ attributes and map them to LDAP attributes and object classes.
+
+ This document defines several object classes to provide LDAP
+ applications with multiple options in defining printer information
+ using LDAP schema. Classes are provided for defining directory
+ entries with common printer information and for extending existing
+ directory entries with SLP, IPP, and LPR specific information.
+
+
+
+
+2. Terminology
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in [RFC 2119].
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 5]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+3. Definition of Object Classes
+
+ We define the following LDAP object classes for use with both generic
+ printer related information and services specific to SLP, IPP, and
+ LPR.
+
+ slpServicePrinter - auxiliary class for SLP registered printers
+ printerAbstract - abstract class for all printer classes
+ printerService - structural class for printers
+ printerServiceAuxClass - auxiliary class for printers
+ printerIPP - auxiliary class for IPP printers
+ printerLPR - auxiliary class for LPR printers
+
+ The following are some examples of how applications MAY choose to use
+ these classes when creating directory entries:
+
+ 1) Use printerService for directory entries containing common printer
+ information.
+
+ 2) Use both printerService and slpServicePrinter for directory
+ entries containing common printer information for SLP registered
+ printers.
+
+ 3) Use printerService, printerLPR and printerIPP for directory
+ entries containing common printer information for printers that
+ support both LPR and IPP.
+
+ 4) Use printerServiceAuxClass and object classes not defined by this
+ document for directory entries containing common printer information.
+ In this example, printerServiceAuxClass is used for extending other
+ structural classes defining printer information with common printer
+ information defined in this document.
+
+ Note that specifying the abstract object class printerAbstract is
+ OPTIONAL when using printerService or printerServiceAuxClass to
+ create directory entries per [RFC 2251].
+
+ Refer to section 4 for definition of attribute types referenced by
+ these object classes. We use names instead of OIDs in MUST and MAY
+ for clarity. Some attribute names described in [RFC 2911] have been
+ prefixed with 'printer-' as recommended in [SLPPRT] and [RFC 2926].
+
+ For the object classes defined in this section, schema developers MAY
+ add to the list of MAY OIDs, but MUST NOT modify the list of MUST
+ OIDs and MUST NOT remove OIDs from the list of MAY OIDs. Schema
+ developers MAY derive additional classes from the abstract and
+ structural classes defined in this section. Note, an object class
+ definition SHOULD NOT be changed without having a new name and OID
+ assigned to it.
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 6]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+
+3.1. slpServicePrinter
+
+ This auxiliary class defines Service Location Protocol (SLP) specific
+ information. It MUST be used with a structural class such as
+ printerService. It MAY be used to create new or extend existing
+ directory entries with SLP 'service:printer' abstract service type
+ information as defined in [SLPPRT]. This object class is derived
+ from 'slpService', the parent class for all SLP services, defined in
+ [RFC 2926].
+
+ ( 1.3.18.0.2.6.254
+ NAME 'slpServicePrinter'
+ DESC 'Service Location Protocol (SLP) information.'
+ AUXILIARY
+ SUP slpService
+ )
+
+
+3.2. printerAbstract
+
+ This abstract class defines printer information. It is a base class
+ for deriving other printer related classes, such as, but not limited
+ to, classes defined in this document. It defines a common set of
+ printer attributes that are not specific to any one type of service,
+ protocol or operating system.
+
+ ( 1.3.18.0.2.6.258
+ NAME 'printerAbstract'
+ DESC 'Printer related information.'
+ ABSTRACT
+ SUP top
+ MAY ( printer-name $
+ printer-natural-language-configured $
+ printer-location $ printer-info $ printer-more-info $
+ printer-make-and-model $
+ printer-multiple-document-jobs-supported $
+ printer-charset-configured $ printer-charset-supported $
+ printer-generated-natural-language-supported $
+ printer-document-format-supported $ printer-color-supported $
+ printer-compression-supported $ printer-pages-per-minute $
+ printer-pages-per-minute-color $
+ printer-finishings-supported $ printer-number-up-supported $
+ printer-sides-supported $ printer-media-supported $
+ printer-media-local-supported $
+ printer-resolution-supported $
+ printer-print-quality-supported $
+ printer-job-priority-supported $ printer-copies-supported $
+ printer-job-k-octets-supported $ printer-current-operator $
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 7]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+ printer-service-person $
+ printer-delivery-orientation-supported $
+ printer-stacking-order-supported $
+ printer-output-features-supported )
+ )
+
+
+3.3. printerService
+
+ This structural class defines printer information. It is derived
+ from class printerAbstract and thus inherits common printer
+ attributes. This class can be used with or without auxiliary classes
+ to define printer information. Auxiliary classes can be used to
+ extend the common printer information with protocol, service or
+ operating system specific information. Note that when extending
+ other structural classes with auxiliary classes, printerService MUST
+ NOT be used.
+
+ LDAP applications SHOULD use printer-uri as the naming attribute.
+ That is, when using printerService, printer-uri SHOULD be used as the
+ attribute type of the directory entry's relative distinguished name
+ (RDN). printer-uri uniquely identifies each of the printer services
+ for a given printer. Note that if the printer service changes
+ domains, printer-uri must be updated with the new domain name.
+
+ ( 1.3.18.0.2.6.255
+ NAME 'printerService'
+ DESC 'Printer information.'
+ STRUCTURAL
+ SUP printerAbstract
+ MAY ( printer-uri $ printer-xri-supported )
+ )
+
+
+3.4. printerServiceAuxClass
+
+ This auxiliary class defines printer information. It is derived from
+ class printerAbstract and thus inherits common printer attributes.
+ This class MUST be used with a structural class.
+
+ LDAP applications SHOULD use printer-uri as the naming attribute.
+ That is, when using printerServiceAuxClass, printer-uri SHOULD be
+ used as the attribute type of the directory entry's relative
+ distinguished name (RDN). printer-uri uniquely identifies each of
+ the printer services for a given printer. Note that if the printer
+ service changes domains, printer-uri must be updated with the new
+ domain name.
+
+ ( 1.3.18.0.2.6.257
+ NAME 'printerServiceAuxClass'
+ DESC 'Printer information.'
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 8]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+ AUXILIARY
+ SUP printerAbstract
+ MAY ( printer-uri $ printer-xri-supported )
+ )
+
+
+3.5. printerIPP
+
+ This auxiliary class defines Internet Printing Protocol (IPP)
+ information. It MUST be used with a structural class such as
+ printerService. It is used to extend structural classes with IPP
+ specific printer information.
+
+ ( 1.3.18.0.2.6.256
+ NAME 'printerIPP'
+ DESC 'Internet Printing Protocol (IPP) information.'
+ AUXILIARY
+ SUP top
+ MAY ( printer-ipp-versions-supported $
+ printer-multiple-document-jobs-supported )
+ )
+
+
+3.6. printerLPR
+
+ This auxiliary class defines LPR information. It MUST be used with a
+ structural class such as printerService. It is used to identify
+ directory entries that support LPR.
+
+ ( 1.3.18.0.2.6.253
+ NAME 'printerLPR'
+ DESC 'LPR information.'
+ AUXILIARY
+ SUP top
+ MUST ( printer-name )
+ MAY ( printer-aliases)
+ )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 9]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+4. Definition of Attribute Types
+
+ The following attribute types are referenced by the object classes
+ defined in section 3.
+
+ The following table is a summary of the attribute names referenced by
+ this document and their corresponding names from [RFC 2911]. Some
+ attribute names described in [RFC 2911] have been prefixed with
+ 'printer-' as recommended in [RFC 2926], to address the flat
+ namespace for LDAP identifiers.
+
+ LDAP & SLP Printer Schema IPP Model [RFC 2911]
+ ------------------------------ -------------------------------------
+ printer-uri
+ printer-xri-supported
+ [IPP printer-uri-supported]
+ [IPP uri-authentication-supported]
+ [IPP uri-security-supported]
+ printer-name printer-name
+ printer-natural-language-configured
+ natural-language-configured
+ printer-location printer-location
+ printer-info printer-info
+ printer-more-info printer-more-info
+ printer-make-and-model printer-make-and-model
+ printer-ipp-versions-supported ipp-versions-supported
+ printer-multiple-document-jobs-supported
+ multiple-document-jobs-supported
+ printer-charset-configured charset-configured
+ printer-charset-supported charset-supported
+ printer-generated-natural-language-supported
+ generated-natural-language-supported
+ printer-document-format-supported
+ document-format-supported
+ printer-color-supported color-supported
+ printer-compression-supported compression-supported
+ printer-pages-per-minute pages-per-minute
+ printer-pages-per-minute-color pages-per-minute-color
+ printer-finishings-supported finishings-supported
+ printer-number-up-supported number-up-supported
+ printer-sides-supported sides-supported
+ printer-media-supported media-supported
+ printer-media-local-supported [site names from IPP media-supported]
+ printer-resolution-supported printer-resolution-supported
+ printer-print-quality-supported print-quality-supported
+ printer-job-priority-supported job-priority-supported
+ printer-copies-supported copies-supported
+ printer-job-k-octets-supported job-k-octets-supported
+ printer-current-operator
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 10]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+ printer-service-person
+ printer-delivery-orientation-supported
+ printer-stacking-order-supported
+ printer-output-features-supported
+ printer-aliases
+
+ In the following definitions, we use matching rule names instead of
+ OIDs for clarity. Note that if the printer information is not known,
+ the attribute value is not set (for optional attributes). In the
+ following definitions, referenced matching rules are defined in
+ section 8 of [RFC 2252].
+
+ The following definitions reference syntax OIDs as defined in [RFC
+ 2252], which are summarized below:
+ Syntax OID Syntax Description
+ ----------------------------- ------------------
+ 1.3.6.1.4.1.1466.115.121.1.7 Boolean
+ 1.3.6.1.4.1.1466.115.121.1.15 Directory String (UTF-8 [RFC 2279])
+ 1.3.6.1.4.1.1466.115.121.1.27 Integer
+
+
+
+4.1. printer-uri
+
+ Note, that for SLP registered printers, the LDAP printer-uri
+ attribute should set to the value of the registered URL of the
+ printer.
+
+ ( 1.3.18.0.2.4.1140
+ NAME 'printer-uri'
+ DESC 'The URI supported by this printer.'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ )
+
+
+4.2. printer-xri-supported
+
+ A list of XRI (extended resource identifiers) supported by this
+ printer. Each value of this list consists of a URI (uniform resource
+ identifier) followed by optional authentication and security
+ metaparameters. The keywords for URI and their metaparameters are:
+ 'uri' == IPP 'printer-uri-supported' value
+ 'auth' == IPP 'uri-authentication-supported' value
+ 'sec' == IPP 'uri-security-supported' value
+ Legal values of the 'auth' metaparameter include
+ 'none' (no authentication for this URI)
+ 'requesting-user-name' (from operation request)
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 11]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+ 'basic' (HTTP/1.1 Basic [RFC 2617])
+ 'digest' (HTTP/1.1 Basic, [RFC 2617])
+ 'certificate' (from certificate)
+ per IPP Model [3] (extensions MAY also be used). A missing 'auth'
+ metaparameter SHALL mean 'none'. Legal values of the 'sec'
+ metaparameter include
+ 'none' (no security for this URI)
+ 'ssl3' (Netscape SSL3)
+ 'tls' (IETF TLS/1.0, [RFC 2246])
+ per IPP Model [3] (extensions MAY also be used). A missing 'sec'
+ metaparameter SHALL mean 'none'. Each metaparameter of a list member
+ is delimited by '<'. For example:
+ 'uri=ipp://foo.com< auth=digest< sec=tls<'
+ 'uri=lpr://bar.com< auth=none< sec=none<'
+ Registrations MAY consolidate values for metaparameters, as in the
+ following example:
+ 'uri=ipp://foo.com< auth=basic,digest< sec=tls,ssl3<'
+
+ ( 1.3.18.0.2.4.1107
+ NAME 'printer-xri-supported'
+ DESC 'The unordered list of XRI (extended resource identifiers)
+ supported by this printer. Each member of the list consists of
+ a URI (uniform resource identifier) followed by optional
+ authentication and security metaparameters.'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ )
+
+
+4.3. printer-name
+
+ The site-specific administrative name of this printer. This value of
+ this attribute SHOULD be in the language specified in
+ 'printer-natural-language-configured' (although the printer's name
+ may be in any language). This name MAY be the last part of the
+ printer's URI or it MAY be completely unrelated. This name MAY
+ contain characters that are not allowed in a conventional URI (which
+ conforms to [RFC 2396]).
+
+ ( 1.3.18.0.2.4.1135
+ NAME 'printer-name'
+ DESC 'The site-specific administrative name of this printer, more
+ end-user friendly than a URI.'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ SINGLE-VALUE
+ )
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 12]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+4.4. printer-natural-language-configured
+
+ ( 1.3.18.0.2.4.1119
+ NAME 'printer-natural-language-configured'
+ DESC 'The configured language in which error and status messages will
+ be generated (by default) by this printer. Also, a possible
+ language for printer string attributes set by operator, system
+ administrator, or manufacturer. Also, the (declared) language
+ of the "printer-name", "printer-location", "printer-info", and
+ "printer-make-and-model" attributes of this printer. For
+ example: "en-us" (US English) or "fr-fr" (French in France)
+ Legal values of language tags conform to [RFC 1766] "Tags for
+ the Identification of Languages".'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ SINGLE-VALUE
+ )
+
+
+4.5. printer-location
+
+ ( 1.3.18.0.2.4.1136
+ NAME 'printer-location'
+ DESC 'Identifies the location of the printer. This could include
+ things like: "in Room 123A", "second floor of building XYZ".'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ SINGLE-VALUE
+ )
+
+
+4.6. printer-info
+
+ ( 1.3.18.0.2.4.1139
+ NAME 'printer-info'
+ DESC 'Identifies the descriptive information about this printer.
+ This could include things like: "This printer can be used for
+ printing color transparencies for HR presentations", or "Out
+ of courtesy for others, please print only small (1-5 page) jobs
+ at this printer", or even "This printer is going away on July
+ 1, 1997, please find a new printer".'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 13]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+ SINGLE-VALUE
+ )
+
+
+4.7. printer-more-info
+
+ ( 1.3.18.0.2.4.1134
+ NAME 'printer-more-info'
+ DESC 'A URI used to obtain more information about this specific
+ printer. For example, this could be an HTTP type URI
+ referencing an HTML page accessible to a Web Browser. The
+ information obtained from this URI is intended for end user
+ consumption.'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ )
+
+
+4.8. printer-make-and-model
+
+ ( 1.3.18.0.2.4.1138
+ NAME 'printer-make-and-model'
+ DESC 'Identifies the make and model of the device. The device
+ manufacturer may initially populate this attribute.'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ SINGLE-VALUE
+ )
+
+
+4.9. printer-ipp-versions-supported
+
+ ( 1.3.18.0.2.4.1133
+ NAME 'printer-ipp-versions-supported'
+ DESC 'Identifies the IPP protocol version(s) that this printer
+ supports, including major and minor versions, i.e., the version
+ numbers for which this Printer implementation meets the
+ conformance requirements.'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ )
+
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 14]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+4.10. printer-multiple-document-jobs-supported
+
+ ( 1.3.18.0.2.4.1132
+ NAME 'printer-multiple-document-jobs-supported'
+ DESC 'Indicates whether or not the printer supports more than one
+ document per job, i.e., more than one Send-Document or
+ Send-Data operation with document data.'
+ EQUALITY booleanMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
+ SINGLE-VALUE
+ )
+
+
+4.11. printer-charset-configured
+
+ ( 1.3.18.0.2.4.1109
+ NAME 'printer-charset-configured'
+ DESC 'The configured charset in which error and status messages will
+ be generated (by default) by this printer. Also, a possible
+ charset for printer string attributes set by operator, system
+ administrator, or manufacturer. For example: "utf-8" (ISO
+ 10646/Unicode) or "iso-8859-1" (Latin1). Legal values are
+ defined by the IANA Registry of Coded Character Sets and the
+ "(preferred MIME name)" SHALL be used as the tag. For
+ coherence with IPP Model, charset tags in this attribute SHALL
+ be lowercase normalized. This attribute SHOULD be static (time
+ of registration) and SHOULD NOT be dynamically refreshed
+ (subsequently).'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63}
+ SINGLE-VALUE
+ )
+
+
+4.12. printer-charset-supported
+
+ ( 1.3.18.0.2.4.1131
+ NAME 'printer-charset-supported'
+ DESC 'Identifies the set of charsets supported for attribute type
+ values of type Directory String for this directory entry. For
+ example: "utf-8" (ISO 10646/Unicode) or "iso-8859-1" (Latin1).
+ Legal values are defined by the IANA Registry of Coded
+ Character Sets and the preferred MIME name.'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63}
+ )
+
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 15]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+4.13. printer-generated-natural-language-supported
+
+ ( 1.3.18.0.2.4.1137
+ NAME 'printer-generated-natural-language-supported'
+ DESC 'Identifies the natural language(s) supported for this directory
+ entry. For example: "en-us" (US English) or "fr-fr" (French in
+ France). Legal values conform to [RFC 1766], Tags for the
+ Identification of Languages.'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63}
+ )
+
+
+4.14. printer-document-format-supported
+
+ ( 1.3.18.0.2.4.1130
+ NAME 'printer-document-format-supported'
+ DESC 'The possible document formats in which data may be interpreted
+ and printed by this printer. Legal values are MIME types come
+ from the IANA Registry of Internet Media Types.'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ )
+
+
+4.15. printer-color-supported
+
+ ( 1.3.18.0.2.4.1129
+ NAME 'printer-color-supported'
+ DESC 'Indicates whether this printer is capable of any type of color
+ printing at all, including highlight color.'
+ EQUALITY booleanMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
+ SINGLE-VALUE
+ )
+
+
+4.16. printer-compression-supported
+
+ ( 1.3.18.0.2.4.1128
+ NAME 'printer-compression-supported'
+ DESC 'Compression algorithms supported by this printer. For example:
+ "deflate, gzip". Legal values include; "none", "deflate"
+ (public domain ZIP), "gzip" (GNU ZIP), "compress" (UNIX).'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255}
+ )
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 16]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+4.17. printer-pages-per-minute
+
+ ( 1.3.18.0.2.4.1127
+ NAME 'printer-pages-per-minute'
+ DESC 'The nominal number of pages per minute which may be output by
+ this printer (e.g., a simplex or black-and-white printer).
+ This attribute is informative, NOT a service guarantee.
+ Typically, it is the value used in marketing literature to
+ describe this printer.'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ SINGLE-VALUE
+ )
+
+
+4.18. printer-pages-per-minute-color
+
+ ( 1.3.18.0.2.4.1126
+ NAME 'printer-pages-per-minute-color'
+ DESC 'The nominal number of color pages per minute which may be
+ output by this printer (e.g., a simplex or color printer).
+ This attribute is informative, NOT a service guarantee.
+ Typically, it is the value used in marketing literature to
+ describe this printer.'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ SINGLE-VALUE
+ )
+
+
+4.19. printer-finishings-supported
+
+ ( 1.3.18.0.2.4.1125
+ NAME 'printer-finishings-supported'
+ DESC 'The possible finishing operations supported by this printer.
+ Legal values include; "none", "staple", "punch", "cover",
+ "bind", "saddle-stitch", "edge-stitch", "staple-top-left",
+ "staple-bottom-left", "staple-top-right",
+ "staple-bottom-right", "edge-stitch-left", "edge-stitch-top",
+ "edge-stitch-right", "edge-stitch-bottom", "staple-dual-left",
+ "staple-dual-top", "staple-dual-right", "staple-dual-bottom".'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255}
+ )
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 17]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+4.20. printer-number-up-supported
+
+ ( 1.3.18.0.2.4.1124
+ NAME 'printer-number-up-supported'
+ DESC 'The possible numbers of print-stream pages to impose upon a
+ single side of an instance of a selected medium. Legal values
+ include; 1, 2, and 4. Implementations may support other
+ values.'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ )
+
+
+4.21. printer-sides-supported
+
+ ( 1.3.18.0.2.4.1123
+ NAME 'printer-sides-supported'
+ DESC 'The number of impression sides (one or two) and the two-sided
+ impression rotations supported by this printer. Legal values
+ include; "one-sided", "two-sided-long-edge",
+ "two-sided-short-edge".'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ )
+
+
+4.22. printer-media-supported
+
+ ( 1.3.18.0.2.4.1122
+ NAME 'printer-media-supported'
+ DESC 'The standard names/types/sizes (and optional color suffixes) of
+ the media supported by this printer. For example: "iso-a4",
+ "envelope", or "na-letter-white". Legal values conform to ISO
+ 10175, Document Printing Application (DPA), and any IANA
+ registered extensions.'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255}
+ )
+
+
+4.23. printer-media-local-supported
+
+ ( 1.3.18.0.2.4.1117
+ NAME 'printer-media-local-supported'
+ DESC 'Site-specific names of media supported by this printer, in the
+ language in "printer-natural-language-configured".
+ For example: "purchasing-form" (site-specific name) as opposed
+ to (in "printer-media-supported"): "na-letter" (standard
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 18]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+ keyword from ISO 10175).'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255}
+ )
+
+
+4.24. printer-resolution-supported
+
+ ( 1.3.18.0.2.4.1121
+ NAME 'printer-resolution-supported'
+ DESC 'List of resolutions supported for printing documents by this
+ printer. Each resolution value is a string with 3 fields:
+ 1) Cross feed direction resolution (positive integer), 2) Feed
+ direction resolution (positive integer), 3) Resolution unit.
+ Legal values are "dpi" (dots per inch) and "dpcm" (dots per
+ centimeter). Each resolution field is delimited by ">". For
+ example: "300> 300> dpi>".'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255}
+ )
+
+
+4.25. printer-print-quality-supported
+
+ ( 1.3.18.0.2.4.1120
+ NAME 'printer-print-quality-supported'
+ DESC 'List of print qualities supported for printing documents on
+ this printer. For example: "draft, normal". Legal values
+ include; "unknown", "draft", "normal", "high".'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ )
+
+
+4.26. printer-job-priority-supported
+
+ ( 1.3.18.0.2.4.1110
+ NAME 'printer-job-priority-supported'
+ DESC 'Indicates the number of job priority levels supported. An IPP
+ conformant printer which supports job priority must always
+ support a full range of priorities from "1" to "100" (to ensure
+ consistent behavior), therefore this attribute describes the
+ "granularity". Legal values of this attribute are from "1" to
+ "100".'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ SINGLE-VALUE
+ )
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 19]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+4.27. printer-copies-supported
+
+ ( 1.3.18.0.2.4.1118
+ NAME 'printer-copies-supported'
+ DESC 'The maximum number of copies of a document that may be printed
+ as a single job. A value of "0" indicates no maximum limit. A
+ value of "-1" indicates unknown.'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ SINGLE-VALUE
+ )
+
+
+4.28. printer-job-k-octets-supported
+
+ ( 1.3.18.0.2.4.1111
+ NAME 'printer-job-k-octets-supported'
+ DESC 'The maximum size in kilobytes (1,024 octets actually) incoming
+ print job that this printer will accept. A value of "0"
+ indicates no maximum limit. A value of "-1" indicates
+ unknown.'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ SINGLE-VALUE
+ )
+
+
+4.29. printer-current-operator
+
+ ( 1.3.18.0.2.4.1112
+ NAME 'printer-current-operator'
+ DESC 'The name of the current human operator responsible for
+ operating this printer. It is suggested that this string
+ include information that would enable other humans to reach the
+ operator, such as a phone number.'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ SINGLE-VALUE
+ )
+
+
+4.30. printer-service-person
+
+ ( 1.3.18.0.2.4.1113
+ NAME 'printer-service-person'
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 20]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+ DESC 'The name of the current human service person responsible for
+ servicing this printer. It is suggested that this string
+ include information that would enable other humans to reach the
+ service person, such as a phone number.'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ SINGLE-VALUE
+ )
+
+
+4.31. printer-delivery-orientation-supported
+
+ ( 1.3.18.0.2.4.1114
+ NAME 'printer-delivery-orientation-supported'
+ DESC 'The possible delivery orientations of pages as they are printed
+ and ejected from this printer. Legal values include;
+ "unknown", "face-up", and "face-down".'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ )
+
+
+4.32. printer-stacking-order-supported
+
+ ( 1.3.18.0.2.4.1115
+ NAME 'printer-stacking-order-supported'
+ DESC 'The possible stacking order of pages as they are printed and
+ ejected from this printer. Legal values include; "unknown",
+ "first-to-last", "last-to-first".'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ )
+
+
+4.33. printer-output-features-supported
+
+ ( 1.3.18.0.2.4.1116
+ NAME 'printer-output-features-supported'
+ DESC 'The possible output features supported by this printer. Legal
+ values include; "unknown", "bursting", "decollating",
+ "page-collating", "offset-stacking".'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ )
+
+
+
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 21]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+4.34. printer-aliases
+
+ ( 1.3.18.0.2.4.1108
+ NAME 'printer-aliases'
+ DESC 'Site-specific administrative names of this printer in addition
+ the printer name specified for printer-name.'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}
+ )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 22]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+5. Definition of Syntaxes
+
+ No new syntaxes are defined by this document.
+
+
+6. IANA Considerations
+
+ There are no IANA registration considerations defined by this
+ document.
+
+
+7. Internationalization Considerations
+
+ All text string attribute values in objects of the printerService
+ class MUST be encoded in UTF-8 [RFC 2279] characters, as required by
+ the syntax 'Directory String' [RFC 2252]. Also, a language tag for
+ all of the text string attributes in objects of the printerService
+ class SHOULD be supplied in 'printer-natural-language-configured'.
+ Therefore, all objects of the printerService class conform to "IETF
+ Policy on Character Sets and Languages" [RFC 2277].
+
+
+
+8. Security Considerations
+
+ As with any LDAP schema, it is important to protect specific entries
+ and attributes with the appropriate access control. It is
+ particularly important that only administrators can modify entries
+ defined in this schema. For additional considerations of deploying
+ printers in an IPP environment the reader is referred to section 8 of
+ [RFC 2911].
+
+ By advertising the security methods for each supported printer URL
+ the printer may expose information useful to attackers. Suitable
+ security methods SHOULD be used to authenticate any service
+ advertisements.
+
+ Obtaining a reference to an object and storing it in the directory
+ may make a handle to the object available to a wider audience. This
+ may have security implications.
+
+
+
+9. References
+
+ [SLPPRT] St. Pierre, Isaacson, McDonald. Definition Printer Abstract
+ Service Type v2.0, <draft-ietf-svrloc-printer-schema-06.txt>, March
+ 2000 (appoved and archived in the IANA SLP Template Registry:
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 23]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+ ftp://isi.edu/in-notes/iana/assignments/svrloc-templates/
+ in the file 'printer.2.0.en')
+
+ [RFC 1179] McLaughlin. Line Printer Daemon Protocol, RFC 1179,
+ August 1990.
+
+ [RFC 1766] Alvestrand. Tags for the Identification of Languages, RFC
+ 1766, March 1995.
+
+ [RFC 2119] Bradner. Key words for use in RFCs to Indicate
+ Requirement Levels, RFC 2119, March 1997.
+
+ [RFC 2246] Dierks, Allen. TLS Protocol Version 1.0, RFC 2246,
+ January 1999.
+
+ [RFC 2251] Wahl, Howes, Kille. Lightweight Directory Access Protocol
+ (v3), RFC 2251, December 1997.
+
+ [RFC 2252] Wahl, Coulbeck, Howes, Kille. Lightweight Directory
+ Access Protocol (v3): Attribute Syntax Definitions, RFC 2252,
+ December 1997.
+
+ [RFC 2277] Alvestrand. IETF Policy on Character Sets and Languages,
+ RFC 2277, January 1998.
+
+ [RFC 2279] Yergeau. UTF-8, a Transformation Format of ISO 10646, RFC
+ 2279, January 1998.
+
+ [RFC 2307] Howard. An Approach for Using LDAP as a Network
+ Information Service, RFC 2307, March 1998.
+
+ [RFC 2396] Berners-Lee, Fielding, Masinter. URI Generic Syntax, RFC
+ 2396, August 1998.
+
+ [RFC 2911] deBry, Hastings, Herriot, Isaacson, Powell. Internet
+ Printing Protocol/1.1: Model and Semantics, RFC 2911, September 2000.
+
+ [RFC 2926] Kempf, Moats, St. Pierre. Conversion of LDAP Schemas to
+ and from SLP Templates, RFC 2926, September 2000.
+
+
+
+10. Acknowledgments
+
+ This document is a submission to the IPP Working group.
+
+ Thanks to Kimberly Reger (IBM), Robert Moore (IBM) and Lee Rafalow
+ (IBM) for their review comments and help in preparing this document.
+
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 24]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+11. Authors' Addresses
+
+ Principal Editor:
+ Pat Fleming
+ IBM
+ Highway 52 N.
+ Rochester, MN 55901
+ USA
+ Phone: +1 507-253-7583
+ EMail: flemingp@us.ibm.com
+
+ Ken Jones
+ eStarCom
+ 400 S McCaslin Blvd Suite 211
+ Louisville, CO 80027
+ USA
+ Phone: +1 720-890-7507
+ EMail: kenjones@estarcom.com
+
+ Harry Lewis
+ IBM
+ 6300 Diagonal Hwy
+ Boulder, CO 80301
+ USA
+ Phone: +1 303-924-5337
+ EMail: harryl@us.ibm.com
+
+ Ira McDonald
+ High North Inc
+ 221 Ridge Ave
+ Grand Marais, MI 49839
+ USA
+ Phone: +1 906-494-2434
+ Email: imcdonald@sharplabs.com
+ Email: imcdonald@crt.xerox.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 25]
+
+Internet Draft LDAP Schema for Printer Services 20 December 2000
+
+
+
+12. Full Copyright Statement
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE."
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fleming, Jones, Lewis, McDonald Expires 20 June 2001 [Page 26]
diff --git a/standards/draft-ietf-ipp-not-05.txt b/standards/draft-ietf-ipp-not-05.txt
new file mode 100644
index 000000000..c06658f1a
--- /dev/null
+++ b/standards/draft-ietf-ipp-not-05.txt
@@ -0,0 +1,928 @@
+
+
+
+
+
+
+INTERNET DRAFT Roger K deBry
+<draft-ietf-ipp-not-05.txt> Utah Valley State College
+[Target Category: Informational] Harry Lewis
+ IBM Corporation
+ Tom Hastings (editor)
+ Xerox Corporation
+ January 23, 2001
+
+ Internet Printing Protocol (IPP): Requirements for IPP Notifications
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+
+STATUS OF THIS MEMO
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of [RFC2026]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as ''work in progress.''
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed as
+ http://www.ietf.org/shadow.html.
+
+ABSTRACT
+
+ This document is one of a set of documents which together describe
+ all aspects of a new Internet Printing Protocol (IPP). IPP is an
+ application level protocol that can be used for distributed printing
+ on the Internet. There are multiple parts to IPP, but the primary
+ architectural components are the Model, the Protocol and an interface
+ to Directory Services. This document provides a statement of the
+ requirements for notifications as part of an IPP Service.
+
+
+
+
+
+
+
+
+
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 1]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+ The full set of IPP documents include:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.0: Model and Semantics [RFC2566]
+ Internet Printing Protocol/1.0: Encoding and Transport [RFC2565]
+ Internet Printing Protocol/1.0: Implementer's Guide [RFC 2639]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ The 'Design Goals for an Internet Printing Protocol' document takes a
+ broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. Operator and administrator requirements
+ are out of scope for version 1.0.
+
+ The 'Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol' document describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specifications, and gives background and rationale for the
+ IETF working group's major decisions.
+
+ The 'Internet Printing Protocol/1.0: Encoding and Transport' document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1. It defines the encoding rules
+ for a new Internet media type called 'application/ipp'.
+
+ The 'Internet Printing Protocol/1.0: Implementer's Guide' document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.0 and some of
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+ The 'Mapping between LPD and IPP Protocols' document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+ Table of Contents
+
+
+ 1 Scope ...........................................................4
+
+ 2 Terminology .....................................................4
+
+ 3 Scenarios .......................................................8
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 2]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+ 4 Requirements ...................................................11
+
+ 5 Security considerations for IPP Notifications requirements .....13
+
+ 6 Internationalization Considerations ............................14
+
+ 7 IANA Considerations ............................................14
+
+ 8 References .....................................................14
+
+ 9 Author's Address ...............................................15
+
+ 10 Appendix A: Full Copyright Statement...........................16
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 3]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+1 Scope
+
+ The scope of this requirements document covers functionality used by
+ the following kinds of IPP Users: End Users, Print Administrators and
+ Operators.
+
+2 Terminology
+
+ It is necessary to define a set of terms in order to be able to
+ clearly express the requirements for notification services in an IPP
+ System.
+
+2.1 Job Submitting End User
+
+ A human end user who submits a print job to an IPP Printer. This
+ person may or may not be within the same security domain as the
+ Printer. This person may or may not be geographically near the
+ printer.
+
+2.2 Administrator
+
+ A human user who established policy for and configures the print
+ system.
+
+2.3 Operator
+
+ A human user who carries out the policy established by the
+ Administrator and controls the day to day running of the print
+ system.
+
+2.4 Job Submitting Application
+
+ An application (for example, a batch application), acting on behalf
+ of a Job Submitting End User, which submits a print job to an IPP
+ Printer. The application may or may not be within the same security
+ domain as the Printer. This application may or may not be
+ geographically near the printer.
+
+2.5 Security Domain
+
+ For the purposes of this discussion, the set of network components
+ which can communicate without going through a proxy or firewall. A
+ security domain may be geographically very large, for example -
+ anyplace within IBM.COM.
+
+2.6 IPP Client
+
+ The software component that sends IPP requests to an IPP Printer
+ object and accepts IPP responses from an IPP Printer.
+
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 4]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+2.7 Job Recipient
+
+ A human who is the ultimate consumer of the print job. In many cases
+ this will be the same person as the Job Submitting End User, but this
+ need not always be the case. For example, if I use IPP to print a
+ document on a printer in a business partner's office, I am the Job
+ Submitting End User, while the person I intend the document for in my
+ business partner's office is the Job Recipient. Since one of the
+ goals of IPP is to be able to print near the Job Recipient of the
+ printed output, we would normally expect that person to be in the
+ same security domain as, and geographically near, the Printer.
+ However, this may not always be the case. For example, I submit a
+ print job across the Internet to a Kinko's print shop. I am both the
+ Submitting end User and the Job Recipient, but I am neither near nor
+ in the same security domain as the Printer.
+
+2.8 Job Recipient Proxy
+
+ A person acting on behalf of the Job Recipient. In particular, the
+ Job Recipient Proxy physically picks up the printed document from the
+ Printer, if the Job Recipient cannot perform that function. The Proxy
+ is by definition geographically near and in the same security domain
+ as the printer. For example, I submit a print job from home to be
+ printed on a printer at work. I'd like my secretary to pick up the
+ print job and put it on my desk. In this case, I am acting as both
+ Job Submitting End User and Job Recipient. My secretary is acting as
+ a Job Recipient Proxy.
+
+2.9 Notification Subscriber
+
+ A client that requests the IPP Printer to send Event Notifications to
+ one or more Notification Recipients. A Notification Subscriber may
+ be a Job Submitting End User or an End User, an Operator, or an
+ Administrator that is not submitting a job.
+
+2.10 Notification Source
+
+ The entity that sends Event Notifications.
+
+2.11 Notification Recipient
+
+ The entity that receives IPP Notifications about Job and/or Printer
+ events. A Notification Recipient may be a: Job Submitting End User,
+ Job Submitting Application, Job Recipient, Job Recipient Proxy,
+ Operator, or Administrator, etc., and their representatives or log
+ file or usage statistics gathering application or other active or
+ passive entities.
+
+2.12 Notification Recipient Agent
+
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 5]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+ A program which receives Event Notifications on behalf of the
+ Notification Recipient. The agent may take some action on behalf of
+ the recipient, forward the notification to the recipient via some
+ alternative means (for example, page the recipient), or queue the
+ notification for later retrieval by the recipient.
+
+2.13 Event
+
+ A Event is some occurrence (either expected or unexpected) within the
+ printing system of a change of state, condition, or configuration of
+ a Job or Printer object.
+
+2.14 Event Notification
+
+ When an event occurs, an Event Notification is generated that fully
+ describes the event (what the event was, where it occurred, when it
+ occurred, etc.). Event Notifications are delivered to all the
+ Notification Recipients that are subscribed to that Event, if any.
+ The Event Notification is delivered to the address of the
+ Notification Recipient using the notification delivery method defined
+ in the subscription. However, an Event Notification is sent ONLY if
+ there is a corresponding subscription.
+
+2.15 Notification Subscription
+
+ A Notification Subscription is a request by a Notification Subscriber
+ to the IPP Printer to send Event Notifications to specified
+ Notification Recipient(s) when the event occur.
+
+2.16 Notification Attributes
+
+ IPP Objects (for example, a print job) from which notification are
+ being sent may have attributes associated with them. A user may want
+ to have one or more of these associated attributes returned along
+ with a particular notification. In general, these may include any
+ attribute associated with the object emitting the notification.
+ Examples include:
+
+ number-of-intervening jobs
+ job-k-octets
+ job-k-octets processed
+ job impressions
+ job-impressions-interpreted
+ job-impressions-completed
+ impressionsCompletedCurrentCopy (job MIB)
+ sheetCompletedCopyNumber (job MIB)
+ sheetsCompletedDocumentNumber (job MIB)
+ Copies-requested
+ Copy-type
+ Output-destination
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 6]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+ Job-state-reasons
+ Job ID
+ Printer URI
+ Subscription ID (for job independent subscription)
+
+2.17 Notification Delivery Method (or Delivery Method for short)
+
+ Event Notifications are delivered using a method, such as email,
+ TCP/IP, etc.
+
+2.18 Immediate Notification
+
+ Notifications sent to the Notification Recipient or the Notification
+ Recipient's agent in such a way that the notification arrives
+ immediately , within the limits of common addressing, routing,
+ network congestion and quality of service.
+
+2.19 Store and Forward Notification
+
+ Notifications which are not necessarily delivered to Notification
+ Recipients immediately, but are queued for delivery by some
+ intermediate network application, for later retrieval. Email is an
+ example of a store and forward notification delivery method.
+
+2.20 Reliable Delivery of Notifications
+
+ Notifications which are delivered by a reliable delivery of packets
+ or character stream, with acknowledgment and retry, such that
+ delivery of the notification is guaranteed within some determinate
+ time limits. For example, if the Notification Recipient has logged
+ off and gone home for the day, an immediate notification cannot be
+ guaranteed to be delivered, even when sent over a reliable transport,
+ because there is nothing there to catch it. Guaranteed delivery
+ requires both store and forward notification and a reliable
+ transport.
+
+2.21 Notification over Unreliable Transport
+
+ Notifications are delivered via the fundamental transport address and
+ routing framework, but no acknowledgment or retry is required.
+ Process to process communications, if involved, are unconstrained.
+
+
+2.22 Human Consumable Notification
+
+ Notifications which are intended to be consumed by human end users
+ only. Email would be an example of a Human consumable notification,
+ though it could also contain Machine Consumable Notification.
+
+2.23 Machine Consumable Notification
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 7]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+
+ Notifications which are intended for consumption by a program only,
+ such as an IPP Client. Machine Consumable notifications may not
+ contain human readable information. Do we need both human and
+ machine? Machine readable is intended for application to application
+ only. The Notification Recipient could process the machine readable
+ Event Notification into human readable format.
+
+2.24 Mixed Notification
+
+ A mixed notification contains both Human Consumable and Machine
+ Consumable information.
+
+3 Scenarios
+
+ 1.I am sitting in my office and submit a print job to the printer
+ down the hall. I am in the same security domain as the printer and
+ of course, geographically near. I want to know immediately when
+ my print job will be completed (or if there is a problem) because
+ the document I am working on is urgent. I submit the print job
+ with the following attributes:
+
+ . Notification Recipient - me
+ . Notification Events - all
+ . Notification Attributes - job-state-reason
+ . Notification Type - immediate
+
+ 2.I am working from home and submit a print job to the same printer
+ as in the previous example. However, since I am not at work, I
+ cannot physically get the print file or do anything with it. It
+ can wait until I get to work this afternoon. However, I'd like my
+ secretary to pick up the output and put it on my desk so it
+ doesn't get lost or miss-filed. I'd also like a store and forward
+ notification sent to my email so that when I get to work I can
+ tell if there was a problem with the print job. I submit a print
+ job with the following attributes:
+
+ . Notification Recipient - my secretary
+ . Notification Events - print complete
+ . Notification Type - immediate
+
+ . Notification Recipient - me
+ . Notification Events - print complete
+ . Notification Attributes - impressions completed
+ . Notification Type - store and forward
+
+ 3.I am sitting in my office and submit a print job to a client at an
+ engineering firm we work with on a daily basis. The engineering
+ firm is in Belgium. I would like my client to know when the print
+ job is complete, so that she can pick it up from the printer in
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 8]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+ her building. It is important that she review it right away and
+ get her comments back to me. I submit the print job with the
+ following attributes:
+
+
+ . Notification Recipient - client at engineering firm
+ . Notification Events - print complete
+ . Notification Type - immediate
+ . Notification Language - French
+
+ 4.I am in a hotel room and send a print job to a Kinko's store in
+ the town I am working in, in order to get a printed report for the
+ meeting I am attending in the morning. Since I'm going out to
+ dinner after I get this job submitted, an immediate notification
+ won't do me much good. However, I'd like to check in the morning
+ before I drive to the Kinko's store to see if the file has been
+ printed. An email notification is sufficient for this purpose. I
+ submit the print job with the following attributes:
+
+ . Notification Recipient - me
+ . Notification Events - print complete
+ . Notification Type - store and forward
+
+ 5.I am printing a large, complex print file. I want to have some
+ immediate feedback on the progress of the print job as it prints.
+ I submit the print job with the following attributes:
+
+ . Notification Recipient - me
+ . Notification Type - immediate
+ . Notification Events - all state transitions
+ . Notification Attributes - impression completed
+
+ 6.I am an operator and my duties is to keep the printer running. I
+ subscribe independently from a job submission so that my
+ subscription outlasts any particular job. I subscribe with the
+ following attributes:
+
+ . Notification Recipient - me
+ . Notification Type - immediate
+ . Notification Events - all Printer state transitions
+ . Notification Attributes - Printer state, printer state reasons,
+ device powering up, device powering down.
+
+ 7.I am a usage statistics gathering application. I subscribe
+ independently from a job submission so that my subscription
+ outlasts any particular job. My subscription may persists across
+ power cycles. I subscribe with the following attributes:
+
+ . Notification Recipient - me
+ . Notification Type - immediate
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 9]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+ . Notification Events - job completion
+ . Notification Attributes - impression completed, sheets
+ completed, time submitted, time started, time completed, job
+ owner, job size in octets, etc.
+
+ 8.I am a client application program that displays a list of jobs
+ currently queued for printing on a printer. I display the "job-
+ name", "job-state", "job-state-reasons", "page-count", and
+ "intervening-jobs" either for the user's jobs or for all jobs.
+ The window displaying the job list remains open for an independent
+ amount of time, and it is desired that it represent the current
+ state of the queue. It is desired that the application only need
+ to perform a slow poll in order to recover from any missed
+ notifications. So the event delivery mechanism provides the means
+ to update the screen on all needed changes, including querying for
+ some attributes that may not be delivered in the Notification.
+
+ 9.I am a client application program that displays a list of
+ printers. For each Printer I display the current state and
+ configuration. The window displaying the printer list remains
+ open for an independent amount of time, and it is desired that it
+ represent the current state of each printer. It is desired that
+ the application only need to perform a slow poll in order to
+ recover from any missed notifications. So the event delivery
+ mechanism provides the means to update the screen on all needed
+ changes, including querying for some attributes that may not be
+ delivered in the Notification.
+
+ 10. I am an IPP Server that controls one or more devices and
+ implements an IPP Printer object to represent each device. I want
+ to support IPP Notification for each of the IPP Printer objects
+ that I implement. Many of these devices do not support
+ notification (or IPP). So I need to support the IPP Notification
+ semantics specified for each IPP Printer object myself on behalf
+ of each of the devices that each of the IPP Printer objects
+ represent. When I accept IPP job creation requests, I convert the
+ request to what the device will accept. In some cases, I must
+ poll the devices in order to be informed of their job and device
+ state and state changes in order to be able to send IPP
+ Notifications to subscribed Notification Recipients.
+
+ 11. I am an IPP Server that controls one or more devices and
+ implements an IPP Printer object to represent each device. I want
+ to support IPP Notification for each of the IPP Printer objects
+ that I implement. These devices all support IPP, including IPP
+ Notification. I would like the design choice for supporting IPP
+ Notification for these IPP Printer objects that I implement either
+ (1) by forwarding the notification to the IPP Printers that I
+ alone control and have them send the notifications to the intended
+ Notification Recipients without my involvement or (2) replace the
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 10]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+ notification submitted with the Job to indicate me as the
+ Notification Recipient and I will in turn forward Notifications to
+ the Notification Recipients requested by my clients. Most of the
+ rest of the contents of the IPP Job that I send to the IPP
+ Printers that I control will be the same as the IPP Job that I
+ receive from my IPP clients.
+
+ 12. I am an IPP Server that controls one or more devices and
+ implements an IPP Printer object to represent each device. I want
+ to support IPP Notification for each of the IPP Printer objects
+ that I implement. These devices all support IPP, including IPP
+ Notification. Because these IPP Printers MAY also be being
+ controlled by other servers (using IPP or other protocols), I only
+ want job events for the jobs that I send, but do want Printer
+ events all the time, so that I can show proper Printer state to my
+ clients. So I subscribe to these IPP Printers for Printer events
+ with a long standing subscription with myself to as the
+ Notification Recipient. When I get a Job Creation request, I
+ decide to which IPP Printer to send the job. When I do so, I also
+ add a job subscription for Job events with me as the Notification
+ Recipient to the job's job subscriptions supplied by my clients
+ (this usage is called "piggy-backing"). These IPP Printers
+ automatically remove their job subscriptions when the job
+ completes as for all job subscriptions so that I no longer get Job
+ events when my jobs are completed.
+
+4 Requirements
+
+ The following requirements are intended to be met by the IPP
+ Notification specification (not the implementation). The resulting
+ IPP Notification Specification document:
+
+ 1.must indicate which of these requirements are REQUIRED and which
+ are OPTIONAL for a conforming implementation to support. See
+ [RFC2911] section 12.1 for the definition of these important
+ conformance terms.
+
+ 2.must be designed to that an IPP Printer can transparently support
+ the IPP Notification semantics using third party notification
+ services that exist today or that may be standardized in the
+ future.
+
+ 3.must define means for a Job Submitting End User to specify zero or
+ more Notification Recipients when submitting a print job. A
+ Submitter will not be able to prevent out of band subscriptions
+ from authorized persons, such as Operators.
+
+ 4.must define means when specifying a Notification Recipient, for a
+ Notification Subscriber to be able to specify one or more
+ notification events for that Notification Recipient, subject to
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 11]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+ administrative and security policy restrictions. Any of the
+ following constitute Job or Printer Events that a Job Submitting
+ End User can specify notifications be sent for:
+ . Any standard Printer MIB alert (i.e. device alerts) (critical
+ and warning?) (state change notifications)?
+ . Job Received (transition from Unknown to Pending)
+ . Job Started (Transition from Pending to Processing)
+ . Page Complete (Page is stacked)
+ . Collated Copy Complete (last sheet of collated copy is
+ stacked)
+ . Job Complete (transition from Processing or Processing-
+ stopped to Completed)
+ . Job aborted (transition from Pending, Pending-held,
+ Processing, or Processing-stopped to Aborted)
+ . Job canceled (transition from Pending, Pending-held,
+ Processing, or Processing-held to Canceled)
+ . Other job state changes like 'paused', purged?
+ . Device problems for which the job is destined
+ . Job (interpreter) issues
+
+
+ 5.must define how an End User or Operator subscribes for:
+ . Any set of Job Events for a specific job.
+ . Any set of Printer Events while a specific job is not
+ complete.
+
+ 6.must define how an End User or Operator subscribes for the
+ following without having to submit a Job:
+ . Any set of Printer Events for a defined period.
+ . Any set of Job Events for all jobs with no control over which
+ jobs.
+
+ 7.must define how the Notification Subscriber is able to specify
+ either immediate or store and forward notification independently
+ for each Notification Recipient. The means may be explicit, or
+ implied by the method of delivery chosen by the Job Submitting End
+ User.
+
+ 8.must define common delivery methods, e.g. email, must be defined.
+
+ 9.must define how an IPP Printer validates its ability to deliver an
+ Event using the specified delivery scheme. If it does not support
+ the specified scheme, or the specified scheme is invalid for some
+ reason, then the IPP Printer accepts and performs the request
+ anyway and responds indicating the unsupported attribute values.
+ There is no requirement for the IPP Printer receiving the print
+ request to validate the identity of an Notification Recipient, nor
+ the ability of the system to deliver an event to that recipient as
+ requested (for example, if the Notification Recipient is not at
+ work today).
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 12]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+
+ 10. must define a class of IPP event notification delivery methods
+ which can flow through corporate firewalls. However, an IPP
+ printer need not test to guarantee delivery of the notification
+ through a firewall before accepting a print job.
+ 11. may define means for delivering a notification to the
+ submitting client when the delivery of an event notification to a
+ specified Notification Recipient fails. Fall back means of
+ subscribers determining if notifications have failed, i.e.
+ polling, may be provided.
+
+ 12. must define a mechanism for localizing Human Consumable
+ notifications by the Notification Source.
+
+ 13. may define a way to specify whether or not event delivery
+ requires acknowledgement back to the Notification Source.
+
+ 14. There must be a mechanism defined so that job independent
+ subscriptions do not become stale and do not require human
+ intervention to remove stale subscriptions. However, stale must
+ not be the inability to deliver an Event Notification , since
+ temporary Notification delivery problems must be tolerated.
+
+ 15. A mechanism must be defined so that an Event Subscriber is
+ able to add an Event Subscription to a Job after the Job has been
+ submitted.
+
+ 16. A mechanism must be defined so that a client is able to cancel
+ an Event Subscription on a job or printer after the job has been
+ submitted.
+
+ 17. A mechanism must be defined so that a client can obtain the
+ set of current Subscriptions.
+
+5 Security considerations for IPP Notifications requirements
+
+ By far the biggest security concern is the abuse of notification:
+ sending unwanted notifications to third parties (i.e., spam). The
+ problem is made worse by notification addresses that may be
+ redistributed to multiple parties (e.g. mailing lists). There exist
+ scenarios where third party notification is required (see Scenario #2
+ and #3). The fully secure solution would require active agreement of
+ all recipients before sending out anything. However, requirement #9
+ ("There is no requirement for IPP Printer receiving the print request
+ to validate the identity of an event recipient") argues against this.
+ Certain systems may decide to disallow third party notifications (a
+ traditional fax model).
+
+ Clients submitting notification requests to the IPP Printer has the
+ same security issues as submitting an IPP/1.1 print job request. The
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 13]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+ same mechanisms used by IPP/1.1 can therefore be used by the client
+ notification submission. Operations that require authentication can
+ use the HTTP authentication. Operations that require privacy can use
+ the HTTP/TLS privacy.
+
+ The notification access control model should be similar to the IPP
+ access control model. Creating a notification subscription is
+ associated with a user. Only the creator or an operator can cancel
+ the subscription. The system may limit the listing of items to only
+ those items owned by the user. Some subscriptions (e.g. those that
+ have a lifetime longer than a job) can be done only by privileged
+ users (operators and/or administrators), if that is the authorization
+ policy.
+
+ The standard security concerns (delivery to the right user, privacy
+ of content, tamper proof content) apply to the notification delivery.
+ IPP should use the security mechanism of the delivery method used.
+ Some delivery mechanisms are more secure than others. Therefore,
+ sensitive notifications should use the delivery method that has the
+ strongest security.
+
+6 Internationalization Considerations
+
+ The Human Consumable notification must be localized to the natural
+ language and charset that Notification Subscriber specifies within
+ the choice of natural languages and charsets that the IPP Printer
+ supports.
+
+ The Machine Consumable notification data uses the 'application/ipp'
+ MIME media type. It contains some attributes whose text values are
+ required to be in the natural language and charset that the
+ Notification Subscriber specifies within the choice of natural
+ languages and charsets that the IPP Printer supports. See [RFC2566].
+
+7 IANA Considerations
+
+ There will be some notification delivery methods registered with IANA
+ for use in URLs. These will be defined in other documents.
+
+8 References
+
+ [RFC2565]
+ Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet Printing
+ Protocol/1.0: Encoding and Transport", RFC 2565, April 1999.
+
+ [RFC2566]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell,
+ "Internet Printing Protocol/1.0: Model and Semantics", RFC 2566,
+ April 1999.
+
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 14]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+ [RFC2567]
+ Wright, D., "Design Goals for an Internet Printing Protocol",
+ draft-ietf-ipp-req-03.txt, November, 1998.
+
+ [RFC2568]
+ Zilles, S., "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", draft-ietf-ipp-rat-04.txt,
+ November, 1998.
+
+ [RFC2569]
+ Herriot, R., Hastings, T., Jacobs, N., Martin, J., "Mapping between
+ LPD and IPP Protocols", draft-ietf-ipp-lpd-ipp-map-05.txt, November
+ 1998.
+
+ [RFC2639]
+ T. Hastings, C. Manros. "Internet Printing Protocol/1.0:
+ Implementer's Guide", RFC 2639, July 1999.
+
+ [RFC2911]
+ deBry, R., , Hastings, T., Herriot, R., Isaacson, S., Powell, P.,
+ "Internet Printing Protocol/1.1: Model and Semantics", RFC 2911,
+ September 2000.
+
+9 Author's Address
+
+ Harry Lewis
+ HUC/003G
+ IBM Corporation
+ P.O. Box 1900
+ Boulder, CO 80301-9191
+
+ Phone: (303) 924-5337
+ Fax: (303) 924-9889
+ e-mail: harryl@us.ibm.com
+
+ Roger deBry
+ Utah Valley State College
+ Orem, UT 84058
+
+ Phone: (801) 222-8000
+ e-mail: debryro@uvsc.edu
+
+ Tom Hastings (editor)
+ Xerox Corporation
+ 737 Hawaii St. ESAE 231
+ El Segundo, CA 90245
+
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ e-mail: hastings@cp10.es.xerox.com
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 15]
+
+
+INTERNET DRAFT IPP/1.1: Notification Requirements January 23, 2001
+
+
+
+ IPP Mailing List: ipp@pwg.org
+ IPP Mailing List Subscription: ipp-request@pwg.org
+ IPP Web Page: http://www.pwg.org/ipp/
+
+10 Appendix A: Full Copyright Statement
+
+ Copyright (C) The Internet Society (1998,1999,2000,2001). All Rights
+ Reserved
+
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, Lewis, Hastings Expires July 23, 2001 [Page 16]
diff --git a/standards/draft-ietf-ipp-not-over-snmp-04.txt b/standards/draft-ietf-ipp-not-over-snmp-04.txt
new file mode 100644
index 000000000..f7aa32af3
--- /dev/null
+++ b/standards/draft-ietf-ipp-not-over-snmp-04.txt
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<HTML><HEAD>
+<TITLE>404 Not Found</TITLE>
+</HEAD><BODY>
+<H1>Not Found</H1>
+The requested URL /internet-drafts/draft-ietf-ipp-not-over-snmp-04.txt was not found on this server.<P>
+<HR>
+<ADDRESS>Apache/1.3.11 Server at www2.ietf.org Port 80</ADDRESS>
+</BODY></HTML>
diff --git a/standards/draft-ietf-ipp-not-spec-06.txt b/standards/draft-ietf-ipp-not-spec-06.txt
new file mode 100644
index 000000000..fef25561f
--- /dev/null
+++ b/standards/draft-ietf-ipp-not-spec-06.txt
@@ -0,0 +1,4988 @@
+
+
+
+
+
+
+INTERNET-DRAFT R. Herriot (editor)
+<draft-ietf-ipp-not-spec-06.txt> Xerox Corporation
+[Target Category: standards track] T. Hastings
+ Xerox Corporation
+ R. deBry
+ Utah Valley State College
+ S. Isaacson
+ Novell, Inc.
+ J. Martin
+ Underscore
+ M. Shepherd
+ Xerox Corporation
+ R. Bergman
+ Hitachi Koki Imaging Solutions
+ January 24, 2000
+ Internet Printing Protocol (IPP):
+ IPP Event Notification Specification
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of [RFC2026]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress".
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed as
+ http://www.ietf.org/shadow.html.
+
+Abstract
+
+ This document describes an extension to the IPP/1.0, IPP/1.1, and
+ future versions. This extension allows a client to subscribe to
+ printing related Events. Subscriptions are modeled as Subscription
+ Objects. The Subscription Object specifies that when one of the
+ specified Event occurs, the Printer sends an asynchronous Event
+ Notification to the specified Notification Recipient via the
+ specified Delivery Method (i.e., protocol). A client associates
+ Subscription Objects with a particular Job by performing the Create-
+ Job-Subscriptions operation or by submitting a Job with subscription
+ information. A client associates Subscription Objects with the
+
+Herriot, et al. Expires July 24, 2001 [page 1]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Printer by performing a Create-Printer-Subscriptions operation. Four
+ other operations are defined for Subscription Objects: Get-
+ Subscriptions-Attributes, Get-Subscriptions, Renew-Subscription, and
+ Cancel-Subscription.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 2]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+
+
+ The basic set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics [RFC2911]
+ Internet Printing Protocol/1.1: Encoding and Transport [RFC2910]
+ Internet Printing Protocol/1.1: Implementer's Guide [IPP-IIG]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ The "Design Goals for an Internet Printing Protocol" document takes a
+ broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, Operators, and
+ Administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. Operator and Administrator requirements
+ are out of scope for version 1.0. A few OPTIONAL Operator operations
+ have been added to IPP/1.1.
+
+ The "Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol" document describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specifications, and gives background and rationale for the
+ IETF working group's major decisions.
+
+ The "Internet Printing Protocol/1.1: Model and Semantics", describes
+ a simplified model with abstract objects, their attributes, and their
+ operations that are independent of encoding and transport. It
+ introduces a Printer object and a Job object. The Job object
+ optionally supports multiple documents per Job. It also addresses
+ security, internationalization, and directory issues.
+
+ The "Internet Printing Protocol/1.1: Encoding and Transport" document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1. It defines the encoding rules
+ for a new Internet MIME media type called "application/ipp". This
+ document also defines the rules for transporting over HTTP a message
+ body whose Content-Type is "application/ipp". This document defines
+ a new scheme named 'ipp' for identifying IPP printers and jobs.
+ Finally, this document defines interoperability rules for supporting
+ IPP/1.0 clients.
+
+ The "Internet Printing Protocol/1.1: Implementer's Guide" document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.0 and some of
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+
+
+Herriot, et al. Expires July 24, 2001 [page 3]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+ The "Mapping between LPD and IPP Protocols" document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 4]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+Table of Contents
+
+
+ 1 Introduction....................................................9
+ 1.1 Notification Overview........................................9
+
+ 2 Models for Notification........................................12
+ 2.1 Model for Notification (Simple Case)........................12
+ 2.2 Model for Notification with Cascading Printers..............12
+ 2.3 Distributed Model for Notification..........................12
+ 2.4 Extended Notification Recipient.............................13
+
+ 3 Terminology....................................................13
+ 3.1 Conformance Terminology.....................................13
+ 3.2 Other Terminology...........................................14
+
+ 4 Object Relationships...........................................16
+ 4.1 Printer and Per-Printer Subscription Objects................16
+ 4.2 Printer, Job and Per-Job Subscription Objects...............16
+
+ 5 Subscription Object............................................17
+ 5.1 Rules for Support of Subscription Template Attributes.......17
+ 5.2 Rules for Processing Subscription Template Attributes.......18
+ 5.3 Subscription Template Attributes............................22
+ 5.3.1 notify-recipient-uri (uri)..................................23
+ 5.3.2 notify-events (1setOf type2 keyword)........................24
+ 5.3.2.1 Standard Values for Subscribed Events ...................24
+ 5.3.2.1.1 No Events.............................................25
+ 5.3.2.1.2 Subscribed Printer Events.............................25
+ 5.3.2.1.3 Subscribed Job Events.................................26
+ 5.3.2.2 Rules for Matching of Subscribed Events .................28
+ 5.3.2.2.1 Rules for Matching of Printer Events..................28
+ 5.3.2.2.2 Rules for Matching of Job Events......................28
+ 5.3.2.2.3 Special Cases for Matching Rules......................29
+ 5.3.3 notify-attributes (1setOf type2 keyword)....................30
+ 5.3.4 notify-user-data (octetString(63))..........................31
+ 5.3.5 notify-charset (charset)....................................31
+ 5.3.6 notify-natural-language (naturalLanguage)...................32
+ 5.3.7 notify-lease-duration (integer(0:67108863)).................32
+ 5.3.8 notify-time-interval (integer(0:MAX)).......................33
+ 5.4 Subscription Description Attributes.........................35
+ 5.4.1 notify-subscription-id (integer (1:MAX))...................35
+ 5.4.2 notify-sequence-number (integer (0:MAX))....................36
+ 5.4.3 notify-lease-expiration-time (integer(0:MAX))...............36
+ 5.4.4 notify-printer-up-time (integer(1:MAX)).....................37
+ 5.4.5 notify-printer-uri (uri)....................................37
+ 5.4.6 notify-job-id (integer(1:MAX))..............................38
+ 5.4.7 notify-subscriber-user-name (name(MAX)).....................38
+
+ 6 Printer Description Attributes Related to Notification.........38
+
+
+Herriot, et al. Expires July 24, 2001 [page 5]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ 6.1 printer-state-change-time (integer(1:MAX))..................39
+ 6.2 printer-state-change-date-time (dateTime)...................39
+
+ 7 New Values for Existing Printer Description Attributes.........40
+ 7.1 operations-supported (1setOf type2 enum)....................40
+
+ 8 Attributes Only in Event Notifications.........................40
+ 8.1 notify-subscribed-event (type2 keyword).....................40
+ 8.2 notify-text (text(MAX)).....................................41
+
+ 9 Event Notification Content.....................................41
+ 9.1 Content of Machine Consumable Event Notifications...........43
+ 9.1.1 Event Notification Content Common to All Events.............44
+ 9.1.2 Additional Event Notification Content for Job Events........45
+ 9.1.3 Additional Event Notification Content for Printer Events....46
+ 9.2 Content of Human Consumable Event Notification..............46
+ 9.2.1 Event Notification Content Common to All Events.............47
+ 9.2.2 Additional Event Notification Content for Job Events........49
+ 9.2.3 Additional Event Notification Content for Printer Events....50
+
+ 10 Delivery Methods...............................................51
+
+ 11 Operations for Notification....................................53
+ 11.1 Subscription Creation Operations............................53
+ 11.1.1 Create-Job-Subscriptions Operation .......................54
+ 11.1.1.1 Create-Job-Subscriptions Request ........................54
+ 11.1.1.2 Create-Job-Subscriptions Response .......................55
+ 11.1.2 Create-Printer-Subscriptions operation ...................56
+ 11.1.2.1 Create-Printer-Subscriptions Request ....................57
+ 11.1.2.2 Create-Printer-Subscriptions Response ...................57
+ 11.1.3 Job Creation Operation - Extensions for Notification .....57
+ 11.1.3.1 Job Creation Request ....................................58
+ 11.1.3.2 Job Creation Response ...................................58
+ 11.2 Other Operations............................................59
+ 11.2.1 Validate-Job Operation - Extensions for Notification .....59
+ 11.2.2 Get-Printer-Attributes - Extensions for Notification .....60
+ 11.2.3 Get-Subscription-Attributes operation ....................60
+ 11.2.3.1 Get-Subscription-Attributes Request .....................61
+ 11.2.3.2 Get-Subscription-Attributes Response ....................62
+ 11.2.4 Get-Subscriptions operation ..............................63
+ 11.2.4.1 Get-Subscriptions Request ...............................63
+ 11.2.4.2 Get-Subscriptions Response ..............................64
+ 11.2.5 Renew-Subscription operation .............................65
+ 11.2.5.1 Renew-Subscription Request ..............................66
+ 11.2.5.2 Renew-Subscription Response .............................66
+ 11.2.6 Cancel-Subscription operation ............................67
+ 11.2.6.1 Cancel-Subscription Request .............................68
+ 11.2.6.2 Cancel-Subscription Response ............................69
+
+ 12 Conformance Requirements.......................................69
+
+
+Herriot, et al. Expires July 24, 2001 [page 6]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ 13 IANA Considerations............................................70
+ 13.1 Attribute Registrations.....................................70
+ 13.2 Keyword Attribute Value Registrations.......................71
+ 13.3 Operation Registrations.....................................71
+ 13.4 Status code Registrations...................................72
+ 13.5 Attribute Group tag Registrations...........................72
+ 13.6 Format for Event Notification Delivery Method Registration
+ proposals.........................................................73
+ 13.7 Format and Requirements for IPP Delivery Method Registration
+ Proposals.........................................................73
+
+ 14 Internationalization Considerations............................73
+
+ 15 Security Considerations........................................74
+
+ 16 Status Codes...................................................74
+ 16.1 successful-ok-ignored-subscriptions (0x0003)................75
+ 16.2 client-error-ignored-all-subscriptions (0x0414).............75
+
+ 17 Status Codes in Subscription Attributes Groups.................75
+ 17.1 client-error-uri-scheme-not-supported (0x040C)..............75
+ 17.2 client-error-too-many-subscriptions (0x0415)................76
+ 17.3 successful-ok-too-many-events (0x0005)......................76
+ 17.4 successful-ok-ignored-or-substituted-attributes (0x0001)....76
+
+ 18 Encodings of Additional Attribute Tags.........................76
+
+ 19 References.....................................................76
+
+ 20 Author's Addresses.............................................78
+
+ A. Appendix - Model for Notification with Cascading Printers......79
+
+ B. Appendix - Distributed Model for Notification..................80
+
+ C. Appendix - Extended Notification Recipient.....................81
+
+ D. Appendix - Details about Conformance Terminology...............82
+
+ E. Appendix - Object Model for Notification.......................83
+ E.1 Appendix - Object relationships.............................84
+ E.2 Printer Object and Per-Printer Subscription Objects.........85
+ E.3 Job Object and Per-Job Subscription Objects.................85
+
+ F. Appendix - Per-Job versus Per-Printer Subscription Objects.....85
+
+ G. Appendix: Full Copyright Statement.............................86
+
+Tables
+ Table 1 - Subscription Template Attributes........................23
+
+
+Herriot, et al. Expires July 24, 2001 [page 7]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Table 2 - Subscription Description Attributes.....................35
+ Table 3 - Printer Description Attributes Associated with Notification
+ ..............................................................39
+ Table 4 - Operation-id assignments................................40
+ Table 5 - Attributes in Event Notification Content................44
+ Table 6 - Additional Event Notification Content for Job Events....45
+ Table 7 - Combinations of Events and Subscribed Events for "job-
+ impressions-completed" ........................................46
+ Table 8 - Additional Event Notification Content for Printer Events46
+ Table 9 - Printer Name in Event Notification Content..............48
+ Table 10 - Event Name in Event Notification Content...............48
+ Table 11 - Event Time in Event Notification Content...............49
+ Table 12 - Job Name in Event Notification Content.................49
+ Table 13 - Job State in Event Notification Content................50
+ Table 14 - Printer State in Event Notification Content............51
+ Table 15 - Information about the Delivery Method..................52
+ Table 16 - Conformance Requirements for Operations................70
+Figures
+ Figure 1 - Model for Notification.................................12
+ Figure 2 - Model for Notification with Cascading Printers.........80
+ Figure 3 - Opaque Use of a Notification Service Transparent to the
+ Client ........................................................81
+ Figure 4 - Use of an Extended Notification Recipient transparent to
+ the Printer ...................................................82
+ Figure 5 - Object Model for Notification..........................84
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 8]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+1 Introduction
+
+ This IPP notification specification is an extension to IPP/1.0
+ [RFC2568, RFC2569] and IPP/1.1 [RFC2911, RFC2910]. This document in
+ combination with the following documents is intended to meet the
+ notification requirements described in [ipp-not-req]:
+
+ Internet Printing Protocol (IPP): "Job Progress Attributes"
+ [ipp-prog]
+ One or more Delivery Method Documents registered with IANA (see
+ section 13).
+
+ Note: this document does not define any Delivery Methods, but it does
+ define the rules for conformance for Delivery Method Documents.
+
+ Refer to the Table of Contents for the layout of this document.
+
+1.1 Notification Overview
+
+ This document defines operations that a client can perform in order
+ to create Subscription Objects in a Printer and carry out other
+ operations on them. A Subscription Object represents a Subscription
+ abstraction. The Subscription Object specifies that when one of the
+ specified Events occurs, the Printer sends an asynchronous Event
+ Notification to the specified Notification Recipient via the
+ specified Delivery Method (i.e., protocol).
+
+ When a client (called a Subscribing Client) performs an operation
+ that creates a Subscription Object, the operation contains one or
+ more Subscription Template Attributes Groups. Each such group holds
+ information used by the Printer to initialize a newly created
+ Subscription Object. The Printer creates one Subscription Object for
+ each Subscription Template Attributes Group in the operation. This
+ group is like the Job Template Attributes group defined in [RFC2911].
+ The following is an example of the information included in a
+ Subscription Template Attributes Group (see section 5 for details on
+ the Subscription Object attributes):
+
+ 1.The names of Subscribed Events that are of interest to the
+ Notification Recipient.
+ 2.The address (URL) of one Notification Recipient.
+ 3.The Delivery Method (i.e., the protocol) which the Printer uses
+ to send the Event Notification.
+ 4.Some opaque data that the Printer sends to the Notification
+ Recipient in the Event Notification. The Notification Recipient
+ might use this opaque data as a forwarding address for the Event
+ Notification.
+ 5.The charset to use in text fields within an Event Notification
+ 6.The natural language to use in the text fields of the Event
+ Notification
+
+
+Herriot, et al. Expires July 24, 2001 [page 9]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ 7.The requested lease time in seconds for the Subscription Object
+ An operation that creates a Subscription Object is called a
+ Subscription Creation Operation. These operations include the
+ following operations (see section 11.1 for further details):
+
+ . Job Creation operation: When a client performs such an operation
+ (Print-Job, Print-URI, and Create-Job), a client can include
+ zero or more Subscription Template Attributes Groups in the
+ request. The Printer creates one Subscription Object for each
+ Subscription Template Attributes Group in the request, and the
+ Printer associates each such Subscription Object with the newly
+ created Job. This document extends these operations' definitions
+ in [RFC2911] by adding Subscription Template Attributes Groups
+ in the request and Subscription Attributes Groups in the
+ response.
+
+ . Create-Job-Subscriptions operation: A client can include one or
+ more Subscription Template Attributes Groups in the request.
+ The Printer creates one Subscription Object for each
+ Subscription Template Attributes Group and associates each with
+ the job that is the target of this operation.
+
+ . Create-Printer-Subscriptions operation: A client can include one
+ or more Subscription Template Attributes Groups in the request.
+ The Printer creates one Subscription Object for each
+ Subscription Template Attributes Group and associates each with
+ the Printer that is the target of this operation.
+
+ For each of the above operations:
+
+ . the Printer associates a Subscription Object with the Printer or
+ a specific Job. When a Subscription Object is associated with a
+ Job Object, it is called a Per-Job Subscription Object. When a
+ Subscription Object is associated with a Printer Object, it is
+ called a Per-Printer Subscription Object.
+
+ . the response contains one Subscription Attributes Group for each
+ Subscription Template Attributes Group in the request and in the
+ same order. When the Printer successfully creates a Subscription
+ Object, its corresponding Subscription Attributes Group contains
+ the "notify-subscription-id" attribute. This attribute uniquely
+ identifies the Subscription Object and is analogous to a "job-
+ id" for a Job object. Some operations described below use the
+ "notify-subscription-id" to identify the target Subscription
+ Object.
+
+ This document defines the following additional operations (see
+ section 11.2 for further details):
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 10]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ . Validate-Job operation: When a client performs this operation, a
+ client can include zero or more Subscription Template Attributes
+ Groups in the request. The Printer determines if it could
+ create one Subscription Object for each Subscription Template
+ Attributes Group in the request. This document extends this
+ operation's definition in [RFC2911] by adding Subscription
+ Template Attributes Groups in the request and Subscription
+ Attributes Groups in the response.
+
+ . Get-Subscription-Attributes operation: This operation allows a
+ client to obtain the specified attributes of a target
+ Subscription Object.
+
+ . Get-Subscriptions operation: This operation allows a client to
+ obtain the specified attributes of all Subscription Objects
+ associated with the Printer or a specified Job.
+
+ . Renew-Subscription operation: This operation renews the lease on
+ the target Per-Printer Subscription Object before it expires. A
+ newly created Per-Printer Subscription Object receives an
+ initial lease. It is the duty of the client to use this
+ operation frequently enough to preserve a Per-Printer
+ Subscription Object. The Printer deletes a Per-Printer
+ Subscription Object when its lease expires. A Per-Job
+ Subscription Object last exactly as long as its associated Job
+ Object and thus doesn't have a lease.
+
+ . Cancel-Subscription operation: This operation cancels the lease
+ on the specified Per-Printer Subscription Object and thereby
+ deletes the Subscription Object.
+
+ When an Event occurs, the Printer finds all Subscription Objects
+ listening for the Event (see section 9 for details on finding such
+ Subscription Objects). For each such Subscription Object, the
+ Printer:
+
+ a)generates an Event Notification with information specified in
+ section 9, AND
+
+ b)either:
+
+ i) delivers the Event Notification using the Delivery Method
+ and target address identified in the Subscription Object's
+ "notify-recipient-uri" attribute if the Delivery Method is a
+ "push", OR
+
+ ii) saves Event Notification for a time period defined by the
+ Delivery Method if the Delivery Method is a "pull", i.e., the
+ Notification Recipient is expected to fetch the Event
+ Notifications.
+
+
+Herriot, et al. Expires July 24, 2001 [page 11]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+2 Models for Notification
+
+2.1 Model for Notification (Simple Case)
+
+ As part of a Subscription Creation Operation, an IPP Printer (i.e.,
+ located in an output device or a server) creates one or more
+ Subscription Objects. In a Subscription Creation Operation, the
+ client specifies the Notification Recipient to which the Printer is
+ to deliver Event Notifications. A Notification Recipient can be the
+ Subscribing Client or a third party.
+
+ Figure 1 shows the Notification model for a simple Client-Printer
+ relationship.
+
+
+ embedded printer:
+ output device or server
+ PDA, desktop, or server +---------------+
+ +--------+ | ########### |
+ | client |-----Subscription ---------># Printer # |
+ +--------+ Creation Operation | # Object # |
+ +------------+ | #####|##### |
+ |Notification| +-------|-------+
+ |Recipient |<----IPP Event Notifications----+
+ +------------+ (Job and/or Printer Events)
+
+ Figure 1 - Model for Notification
+
+2.2 Model for Notification with Cascading Printers
+
+ With this model, there is an intervening Print server between the
+ human user and the Printer in the output device. If the Printer in
+ the output device generates an Event, the system can be configured to
+ send Event Notification either
+
+ . directly to the Notification Recipient specified by the
+ Subscribing Client or
+
+ . via the Print Server to the Notification Recipient specified by
+ the Subscribing Client.
+
+ See Appendix A for more details.
+
+2.3 Distributed Model for Notification
+
+ The preceding sections (2.1 and 2.2) assume that the Notification
+ software resides in the same device or Server box as the rest of the
+ Printer software. In many implementations, the assumption is correct.
+ However, the Notification model also permits a distributed
+ implementation.
+
+
+Herriot, et al. Expires July 24, 2001 [page 12]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ For example, the software that supports both Subscription Creation
+ Operations and sending of Event Notifications could be on hardware
+ that is separate from the output device. To make this work, there
+ must be a symbiotic relationship between the output device software
+ and the remote Notification software. Without the remote Notification
+ software, the output device software is not a complete Printer.
+
+ The term "Printer" in this document includes the software on the
+ output device or server box as well as Notification software that is
+ local to or remote from the output device.
+
+ Appendix B describes this example in detail.
+
+2.4 Extended Notification Recipient
+
+ The model allows for an extended Notification Recipient that is
+ itself a Notification service that forwards each Event Notification
+ to another recipient. The client contacts this Notification Recipient
+ to arrange for forwarding by means outside the scope of this
+ document. The Printer need not be aware that the Notification
+ Recipient forwards Event Notifications.
+
+ Appendix C describes this example in detail.
+
+
+3 Terminology
+
+ This section defines terminology used throughout this document. Other
+ terminology is defined in [RFC2911].
+
+3.1 Conformance Terminology
+
+ Capitalized terms, such as MUST, MUST NOT, REQUIRED, SHOULD, SHOULD
+ NOT, MAY, NEED NOT, and OPTIONAL, have special meaning relating to
+ conformance to this specification. These terms are defined in
+ [RFC2911 section 13.1 on conformance terminology, most of which is
+ taken from RFC 2119 [RFC2119]. See Appendix D for complete details.
+
+ Note: a feature that is OPTIONAL in this document becomes REQUIRED if
+ the Printer implements a Delivery Method that REQUIRES the feature
+
+ READ-ONLY - an adjective used in an attribute definition to indicate
+ that an IPP Printer MUST NOT allow the attribute's value to be
+ modified with the Set-Job-Attributes or Set-Printer-Attributes
+ operations (see [ipp-set]). Note: there is no Set-Subscription
+ operation so this term is not used for Subscription object
+ attributes.
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 13]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+3.2 Other Terminology
+
+ Administrator - A human user who establishes policy for and
+ configures the print system.
+
+ Operator - A human user who carries out the policy established by the
+ Administrator and controls the day to day running of the print
+ system.
+
+ IPP Client (or client) - The software component (PDA, desktop, or
+ server) that performs an IPP operation directed at an IPP Printer
+ (located in a server or output device).
+
+ Job Creation operation - One of the operations that creates a Job
+ object: Print-Job, Print-URI and Create-Job. The Validate-Job
+ operation is not a Job Creation operation because no Job object is
+ created. Therefore, when a statement also applies to the
+ Validate-Job operation, it is mentioned explicitly.
+
+ Event - some occurrence (either expected or unexpected) within the
+ printing system of a change of state, condition, or configuration
+ of a Job or Printer object. An Event occurs only at one instant in
+ time and does not span the time the physical Event takes place.
+ For example, jam-occurred and jam-cleared are two distinct,
+ instantaneous Events, even though the jam may last for a while.
+
+ Job Event - an Event caused by some change in a particular job on the
+ Printer, e.g., job-completed.
+
+ Printer Event - an Event caused by some change in the Printer that is
+ not specific to a job, e.g., printer-state-changed.
+
+ Subscribed Event - an Event that the Subscribing Client expresses
+ interest in by making it a value of the "notify-events" attribute
+ on a Subscription Object.
+
+ Subscribed Job Event - a Subscribed Event that is a Job Event.
+
+ Subscribed Printer Event - a Subscribed Event that is a Printer
+ Event.
+
+ Event Notification - the information about an Event that the Printer
+ sends when an Event occurs.
+
+ Notification Recipient - the entity to which the Printer sends an
+ Event Notification.
+
+ Delivery Method - the mechanism by which the Printer delivers the
+ Event Notification, e.g., via email or via SNMP.
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 14]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Delivery Method Document - a document, separate from this document,
+ that defines a Delivery Method.
+
+ Compound Event Notification - two or more Event Notifications that a
+ Printer sends together as a single entity. The Delivery Method
+ Document specifies whether the Delivery Method supports Compound
+ Event Notifications.
+
+ Subscription Object - An object containing a set of attributes that
+ indicate: the Notification Recipient, the Delivery Method, the
+ Subscribed Events that cause the Printer to send an Event
+ Notification, and the information to send in an Event
+ Notification.
+
+ Per-Job Subscription Object - A Subscription Object that is
+ associated with a single Job. The Create-Job-Subscriptions
+ operation and Job Creation operations create such an object.
+
+ Per-Printer Subscription Object - A Subscription Object that is
+ associated with the Printer as a whole. The Create-Printer-
+ Subscriptions operation creates such an object.
+
+ Subscribing Client - The client that creates the Subscription Object.
+
+ Subscription Creation Operation - An operation that creates a
+ Subscription Object: Job Creation operations, Create-Job-
+ Subscriptions operation, and Create-Printer-Subscriptions
+ operation. In the context of a Job Creation operation, a
+ Subscription Creation Operation is the part of the Job Creation
+ operation that creates a Subscription object.
+
+ Subscription Creation Request - The request portion of a
+ Subscription Creation Operation.
+
+ Subscription Template Attributes - Subscription Object attributes
+ that a client can supply in a Subscription Creation Operation and
+ associated Printer Object attributes that specify supported and
+ default values for the Subscription Object attributes.
+
+ Subscription Description Attributes - Subscription Object attributes
+ that a Printer supplies during a Subscription Creation Operation.
+
+ Subscription Template Attributes Group - The attributes group in a
+ request that contains Subscription Object attributes that are
+ Subscription Template Attributes.
+
+ Subscription Attributes Group - The attributes group in a response
+ that contains Subscription Object attributes.
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 15]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Human Consumable Event Notification - localized text for human
+ consumption only. There is no standardized format and thus
+ programs should not try to parse this text.
+
+ Machine Consumable Event Notification - bytes for program
+ consumption. The bytes are formatted according to the Delivery
+ Method document.
+
+ Printer - the software that supports an output device or print server
+ (see IPP/1.1 [RFC2911] which uses the terms Printer and Printer
+ object interchangeably). This document extends the IPP/1.1 Printer
+ definition to include the software that implements Subscription
+ Creation Operations and the sending of Event Notifications, even
+ if the software for such a Printer would be distributed across a
+ network (see section 2.3).
+
+ Notification - when not in the phrases 'Event Notification' and
+ 'Notification Recipient' - the concepts of this specification,
+ i.e., Events, Subscription Objects, and Event Notifications.
+
+
+4 Object Relationships
+
+ This section defines the object relationships between the Printer,
+ Job, and Subscription Objects. It does not define the
+ implementation. For an illustration of these relationships, see
+ Appendix E.
+
+4.1 Printer and Per-Printer Subscription Objects
+
+ 1.A Printer object can be associated with zero or more Per-Printer
+ Subscription Objects.
+
+ 2.Each Per-Printer Subscription Object is associated with exactly
+ one Printer object.
+
+4.2 Printer, Job and Per-Job Subscription Objects
+
+ 1.A Printer object is associated with zero or more Job objects.
+
+ 2.Each Job object is associated with exactly one Printer object.
+
+ 3.A Job object is associated with zero or more Per-Job Subscription
+ Objects.
+
+ 4.Each Per-Job Subscription Object is associated with exactly one
+ Job object.
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 16]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+5 Subscription Object
+
+ A Subscribing Client creates a Subscription Object with a
+ Subscription Creation Operation in order to indicate its interest in
+ certain Events. See section 11 for a description of these operations.
+ When an Event occurs, the Subscription Object specifies to the
+ Printer where to send Event Notifications, how to send them and what
+ to put in them. See section 9 for details on the contents of an Event
+ Notification.
+
+ Using the IPP Job Template attributes as a model (see [RFC2911]
+ section 4.2), the attributes of a Subscription Object are divided
+ into two categories: Subscription Template Attributes and
+ Subscription Description Attributes.
+
+ Subscription Template attributes are, in turn, like the Job Template
+ attributes, divided into
+
+ 1.Subscription Object attributes that a client can supply in a
+ Subscription Creation Request and
+
+ 2.their associated Printer Object attributes that specify
+ supported and default values for the Subscription Object
+ attributes
+
+ The remainder of this section specifies general rules for
+ Subscription Template Attributes and describes each attribute in a
+ Subscription Object.
+
+5.1 Rules for Support of Subscription Template Attributes
+
+ Subscription Template Attributes are fundamental to the Notification
+ model described in this specification. The client supplies these
+ attributes in Subscription Creation Operations and the Printer uses
+ these attributes to populate a newly created Subscription Object.
+
+ Subscription Objects attributes that are Subscription Template
+ Attributes conform to the following rules:
+
+ 1.Each attribute's name starts with the prefix string "notify-"
+ and this document calls such attributes "notify-xxx".
+
+ 2.For each "notify-xxx" Subscription Object attribute defined in
+ column 1 of Table 1 in section 5.3, Table 1 specifies
+ corresponding Printer attributes: "notify-xxx-default", "notify-
+ xxx-supported", "yyy-supported" and "notify-max-xxx-supported"
+ defined in column 2 of Table 1. Note "xxx" stands for the same
+ string in each case and "yyy" stands for some other string.
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 17]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ 3.If a Printer supports "notify-xxx" in column 1 of Table 1, then
+ the Printer MUST support all associated attributes specified in
+ column 2 of Table 1. For example, Table 1 shows that if the
+ Printer supports "notify-events", it MUST support "notify-
+ events-default", "notify-events-supported" and "notify-max-
+ events-supported".
+
+ 4.If a Printer does not support "notify-xxx" in column 1 of Table
+ 1, then the Printer MUST NOT support any associated "notify-yyy"
+ attributes specified in column 2 of Table 1. For example, Table
+ 1 shows that if the Printer doesn't support "notify-events", it
+ MUST NOT support "notify-events-default", "notify-events-
+ supported" and "notify-max-events-supported". Note this rule
+ does not apply to attributes whose names do not start with the
+ string "notify-" and are thus defined in another object and used
+ by other attributes.
+
+ 5.Most "notify-xxx" attributes have a corresponding "yyy-
+ supported" attribute that specifies the supported values for
+ "notify-xxx". Column 2 of Table 1 specifies the name of each
+ "yyy-supported" attribute. The naming rules of IPP/1.1 (see
+ [RFC2911]) are used when "yyy-supported" is "notify-xxx-
+ supported".
+
+ 6.Some "notify-xxx" attributes have a corresponding "notify-xxx-
+ default" attribute that specifies the value for "notify-xxx" if
+ the client does not supply it. Column 2 of Table 1 specifies the
+ name of each "notify-xxx-default" attribute. The naming rules of
+ IPP/1.1 (see [RFC2911]) are used.
+
+ If a client wishes to present an end user with a list of supported
+ values from which to choose, the client SHOULD query the Printer for
+ its supported value attributes. The client SHOULD also query the
+ default value attributes. If the client then limits selectable
+ values to only those values that are supported, the client can
+ guarantee that the values supplied by the client in the create
+ request all fall within the set of supported values at the Printer.
+ When querying the Printer, the client MAY enumerate each attribute by
+ name in the Get-Printer-Attributes Request, or the client MAY just
+ supply the 'subscription-template' group name in order to get the
+ complete set of supported attributes (both supported and default
+ attributes).
+
+5.2 Rules for Processing Subscription Template Attributes
+
+ This section defines a detailed set of rules that a Printer follows
+ when it processes Subscription Template Attributes in a Subscription
+ Creation Request. These rules for are similar to the rules for
+ processing Operation attributes in [RFC2911]. That is, the Printer
+ may or may not support an attribute and a client may or may not
+
+
+Herriot, et al. Expires July 24, 2001 [page 18]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ supply the attribute. Some combinations of these cases are OK. Others
+ return warnings or errors, and perhaps a list of unsupported
+ attributes.
+
+ A Printer MUST implement the following behavior for processing
+ Subscription Template Attributes in a Subscription Creation Request:
+
+ 1.If a client supplies a "notify-xxx" attribute from column 1 of
+ Table 1 and the Printer supports it and its value, the Printer
+ MUST populate the attribute on the created Subscription Object.
+
+ 2.If a client supplies a "notify-xxx" attribute from column 1 of
+ Table 1 and the Printer doesn't support it or its value, the
+ Printer MUST NOT populate the attribute on the created
+ Subscription Object with it. The Printer MUST do one of the
+ following:
+
+ a) If the value of the "notify-xxx" attribute is unsupported, the
+ Printer MUST return the attribute with its value in the
+ Subscription Attributes Group of the response.
+
+ b) If "notify-xxx" is an unsupported attribute, the Printer MUST
+ return the attribute in the Subscription Attributes Group of the
+ response with the 'unsupported' out-of-band value.
+
+ Note: The rules of this step are the same as for Unsupported
+ Attributes [RFC2911] section 3.1.7. except that the unsupported
+ attributes are returned in the Subscription Attributes Group
+ rather than the Unsupported Attributes Group because Subscription
+ Creation Operations can create more than one Subscription Object).
+
+ 3.If a client is REQUIRED to supply a "notify-xxx" attribute from
+ column 1 of Table 1 and the Printer doesn't support the supplied
+ value, the Printer MUST NOT create a Subscription Object. The
+ rules for Unsupported Attributes in step #2 still apply.
+
+ 4.If a client does not supply a "notify-xxx" attribute from column 1
+ of Table 1 and the attribute is REQUIRED for the client to supply,
+ the Printer MUST reject the Subscription Creation Operation
+ (including Job Creation operations) without creating a
+ Subscription Object, and MUST return in the response:
+
+ c) the status code 'client-error-bad-request' AND
+
+ d) no Subscription Attribute Groups.
+
+ 5.If a client does not supply a "notify-xxx" attribute from column 1
+ of Table 1 that is OPTIONAL for the client to supply, and column 2
+ of Table 1 either:
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 19]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ a) specifies a "notify-xxx-default" attribute, the Printer MUST
+ behave as if the client had supplied the "notify-xxx-default"
+ attribute (see step #1) and populate the Subscription object
+ with the value of the "notify-xxx-default" attribute as part of
+ the Subscription Creation operation (unlike Job Template
+ attributes where the Printer does not populate the Job object
+ with defaults - see [RFC2911]) OR
+
+ b) does not specify a "notify-xxx-default" attribute, the Printer
+ MUST populate the "notify-xxx" attribute on the Subscription
+ Object according to the definition of the "notify-xxx" attribute
+ in a section 5.3. For some attributes, the "notify-xxx" is
+ populated with the value of some other attribute, and for
+ others, the "notify-xxx" is NOT populated on the Subscription
+ object at all.
+
+ 6.A Printer MUST create a Subscription Object for each Subscription
+ Template Attributes group in a request unless the Printer:
+
+ a) encounters some attributes in a Subscription Template Attributes
+ Group that require the Printer not to create the Subscription
+ Object OR
+
+ b) would create a Per-Job Subscription Object when it doesn't have
+ space for another Per-Job Subscription Object OR
+
+ c) would create a Per-Printer Subscription Object when it doesn't
+ have space for another Per-Printer Subscription Object.
+
+ 7.A response MUST contain one Subscription Attributes Group for each
+ Subscription Template Attributes Group in the request (and in the
+ same order) whether the Printer creates a Subscription Object from
+ the Subscription Template Attributes Group or not. However, the
+ attributes in each Subscription Attributes Group can be in any
+ order.
+
+ 8.The Printer MUST populate each Subscription Attributes Group of
+ the response such that each contains:
+
+ a) the "notify-subscription-id" attribute (see section 0), if and
+ only if the Printer creates a Subscription Object.
+
+ b) the "notify-lease-duration" attribute (see section 5.3.7), if
+ and only if the Printer creates a Per-Printer Subscription
+ Object. The value of this attribute is the value of the
+ Subscription Object's "notify-lease-duration" attribute. This
+ value MAY be different from the client-supplied value (see
+ section 5.3.7). If a client supplies this attribute in the
+ creation of a Per-Job Subscription Object, it MUST appear in
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 20]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ this group with the out-of-band value 'unsupported' to indicate
+ that the Printer doesn't support it in this context.
+
+ c) all of the unsupported Subscription Template Attributes from
+ step #2. Note, they are not returned in the Unsupported
+ Attributes Group in order to separate the unsupported attributes
+ for each Subscription Object.
+
+ d) the "notify-status-code" attribute if the Printer does not
+ create the Subscription Object or if there are unsupported
+ attributes from step #2. The possible values of the "notify-
+ status-code" attribute are shown below (see section 17 for more
+ details). The Printer returns the first value in the list below
+ that describes the status.
+
+ 'client-error-uri-scheme-not-supported': the Subscription
+ Object was not created because the scheme of the "notify-
+ recipient-uri" attribute is not supported. See section 17.1
+ for more details about this status code. See step #3 in
+ this section for the case that causes this error, and the
+ resulting step #6a) that causes the Printer not to create
+ the Subscription Object.
+
+ 'client-error-too-many-subscriptions': the Subscription
+ Object was not created because the Printer has no space for
+ additional Subscription Objects. The client SHOULD try
+ again later. See section 17.2 for more details about this
+ status code. See steps #6b) and #6c) in this section for
+ the cases that causes this error.
+
+ 'successful-ok-too-many-events': the Subscription Object
+ was created without the "notify-events" values included in
+ this Subscription Attributes Group because the "notify-
+ events" attribute contains too many values. See section
+ 17.3 for more details about this status code. See step #2
+ in this section and section 5.3.2 for the cases that cause
+ this status code.
+
+ 'successful-ok-ignored-or-substituted-attributes' : the
+ Subscription Object was created but some supplied
+ Subscription Template Attributes are unsupported. These
+ unsupported attributes are also in the Subscription
+ Attributes Group. See section 17.4 for more details about
+ this status code. See step #2 in this section for the cases
+ that cause this status code.
+
+ 9.The Printer MUST validate all Subscription Template Attributes and
+ MUST return all unsupported attributes and values in the
+ corresponding Subscription Attributes Group of the response (see
+ step #2) unless it determines that it could not create additional
+
+
+Herriot, et al. Expires July 24, 2001 [page 21]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Subscription Objects because of condition #6b) or condition #6c).
+ Then, the Printer NEED NOT validate these additional Subscription
+ Template Attributes and the client MUST NOT expect to find
+ unsupported attributes from step #2 in such additional
+ Subscription Attribute Groups.
+
+5.3 Subscription Template Attributes
+
+ This section contains the Subscription Template Attributes defined
+ for the Subscription and Printer objects.
+
+ Table 1 below shows the Subscription Template Attributes and has two
+ columns:
+
+ . Attribute in Subscription Object: the name and attribute syntax
+ of each Subscription Object Attribute that is a Subscription
+ Template Attribute
+
+ . Default and Supported Printer Attributes: the default attribute
+ and supported Printer attributes that are associated with the
+ attribute in column 1.
+
+ A Printer MUST support all attributes in Table 1 below except for
+ "notify-attributes" (and "notify-attributes-supported"). A client
+ MUST supply "notify-recipient-uri" and MAY omit any of the rest of
+ the attributes in column 1 of Table 1 in a Subscription Creation
+ Request.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 22]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Table 1 - Subscription Template Attributes
+
+
+
+ Attribute in Subscription Default and Supported Printer
+ Object Attributes
+
+
+ notify-recipient-uri (uri) notify-schemes-supported (1setOf
+ uriScheme)
+
+ notify-events (1setOf type2 notify-events-default (1setOf type2
+ keyword) keyword)
+ notify-events-supported (1setOf type2
+ keyword)
+ notify-max-events-supported
+ (integer(2:MAX))
+
+ notify-attributes (1setOf notify-attributes-supported (1setOf
+ type2 keyword) type2 keyword)
+
+ notify-user-data
+ (octetString(63))
+
+ notify-charset (charset) charset-supported (1setOf charset)
+
+ notify-natural-languages generated-natural-language-supported
+ (naturalLanguage) (1setOf naturalLanguage)
+
+ notify-lease-duration notify-lease-duration-default
+ (integer(0:MAX)) (integer(0:67108863))
+ notify-lease-duration-supported
+ (1setOf (integer(0: 67108863) |
+ rangeOfInteger(0:67108863)))
+
+ notify-time-interval
+ (integer(0:MAX))
+
+
+
+5.3.1 notify-recipient-uri (uri)
+
+ This attribute's value is a URL, which is a special case of a URI.
+ Its value consists of a scheme and an address. The address specifies
+ the Notification Recipient and the scheme specifies the Delivery
+ Method for each Event Notification associated with this Subscription
+ Object.
+
+ A Printer MUST support this attribute.
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 23]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ A client MUST supply this attribute in Subscription Creation
+ Operation. Thus there is no need for a default attribute.
+
+ The "notify-schemes-supported (1setOf uriScheme)" attribute MUST
+ specify the schemes supported for this attribute. Note: According to
+ [RFC1738] the ":" terminates the scheme and so is not part of the
+ scheme. Therefore, values of this attribute do not include the ":".
+
+ If the client supplies an unsupported scheme in the value of this
+ attribute, then the Printer MUST not create the Subscription Object
+ and MUST return the "notify-status-code" attribute with the 'client-
+ error-uri-scheme-not-supported' value in the Subscription Attributes
+ Group in the response.
+
+ The Printer MUST treat the address part of this attribute as opaque.
+
+5.3.2 notify-events (1setOf type2 keyword)
+
+ This attribute contains a set of Subscribed Events. When an Event
+ occurs and it "matches" a value of this attribute, the Printer sends
+ an Event Notification using information in the Subscription Object.
+ The details of "matching" are described subsection 5.3.2.2.
+
+ A Printer MUST support this attribute.
+
+ A client MAY supply this attribute in a Subscription Creation
+ Operation. If the client does not supply this attribute in
+ Subscription Creation Operation, the Printer MUST populate this
+ attribute on the Subscription Object with its "notify-events-default"
+ attribute value.
+
+ Each value of this attribute on a Subscription Object MUST be one of
+ the values of the "notify-events-supported (1setOf type2 keyword)"
+ attribute.
+
+ The number of values of this attribute MUST NOT exceed the value of
+ the "notify-max-events-supported" attribute. A Printer MUST support
+ at least 2 values per Subscription Object. If the number of values
+ supplied by a client in a Subscription Creation Operation exceeds the
+ value of this attribute, the Printer MUST treat extra values as
+ unsupported values and MUST use the value of 'successful-ok-too-many-
+ events' for the "notify-status-code" attribute in the Subscription
+ Attributes Group of the response.
+
+5.3.2.1 Standard Values for Subscribed Events
+
+ Each value of this attribute is a keyword and it specifies a
+ Subscribed Event that represents certain changes. Some keywords
+ represent a subset of changes of another keyword, e.g., 'job-
+ completed' is an Event value which is a sub-value of 'job-state-
+
+
+Herriot, et al. Expires July 24, 2001 [page 24]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ change'. See section 5.3.2.2 for the case where this attribute
+ contains both a value and a sub-value.
+
+ The values in this section are divided into three categories: No
+ Events, Job Events and Printer Events.
+
+ A Printer MUST support the Events indicated as "REQUIRED" and MAY
+ support the Events indicated as "OPTIONAL".
+
+5.3.2.1.1 No Events
+
+ The standard and only keyword value for No Events is:
+
+ 'none': REQUIRED - no Event Notifications for any Events. As the
+ sole value of "notify-events-supported", this value means that the
+ Printer does not support the sending of Event Notifications. As
+ the sole value of "notify-events-default", this value means that a
+ client MUST specify the "notify-events" attribute in order for a
+ Subscription Creation Operation to succeed. If the Printer
+ receives this value as the sole value of a Subscription Creation
+ Operation, it does not create a Subscription Object. If a Printer
+ receives this value with other values of a Subscription Creation
+ Operation, the Printer MUST treat this value as an unsupported
+ value.
+
+5.3.2.1.2 Subscribed Printer Events
+
+ The standard keyword values for Subscribed Printer Events are:
+
+ 'printer-state-changed': REQUIRED - the Printer changed state from
+ any state to any other state. Specifically, the value of the
+ Printer's "printer-state", "printer-state-reasons" or "printer-is-
+ accepting-jobs" attributes changed.
+
+ This Subscribed Event value has the following sub-values:
+ 'printer-restarted' and 'printer-shutdown'. A client can listen
+ for any of these sub-values if it doesn't want to listen to all
+ printer-state changes:
+
+ 'printer-restarted': OPTIONAL - when the printer is powered
+ up .
+
+ 'printer-shutdown': OPTIONAL - when the device is being
+ powered down .
+
+ 'printer-stopped: REQUIRED - when the printer stops printing,
+ i.e. the value of the "printer-state" Printer attribute
+ becomes 'stopped'.
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 25]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ 'printer-config-changed': OPTIONAL - when the configuration of a
+ Printer has changed, i.e., the value of the "printer-message-from-
+ operator" or any "configuration" Printer attribute has changed. A
+ "configuration" Printer attribute is an attribute which can change
+ value because of some human interaction either direct or indirect,
+ and which is not covered by one of the other Events in this
+ section. Examples of "configuration" Printer attributes are any of
+ the Job Template attributes, such as "xxx-supported", "xxx-ready"
+ and "xxx-default". Often, such a change is the result of a client
+ performing a Set-Printer-Attributes operation (see [ipp-set]) on
+ the Printer. The client has to perform a Get-Printer-Attributes to
+ find out the new values of these changed attributes. This Event
+ is useful for GUI clients and drivers to update the available
+ printer capabilities to the user.
+
+ This Event value has the following sub-values: 'printer-media-
+ changed' and 'printer-finishings-changed'. A client can listen for
+ any of these sub-values if it doesn't want to listen to all
+ printer-configuration changes:
+
+ 'printer-media-changed': OPTIONAL - when the media loaded on
+ a printer has been changed, i.e., the "media-ready"
+ attribute has changed. This Event includes two cases: an
+ input tray that goes empty and an input tray that receives
+ additional media of the same type or of a different type.
+ The client must check the "media-ready" Printer attribute
+ (see [RFC2911] section 4.2.11) separately to find out what
+ changed.
+
+ 'printer-finishings-changed': OPTIONAL - when the finisher on
+ a printer has been changed, i.e., the "finishings-ready"
+ attribute has changed. This Event includes two cases: a
+ finisher that goes empty and a finisher that is refilled
+ (even if it is not full). The client must check the
+ "finishings-ready" Printer attribute separately to find out
+ what changed.
+
+ 'printer-queue-order-changed': OPTIONAL - the order of jobs in the
+ Printer's queue has changed, so that an application that is
+ monitoring the queue can perform a Get-Jobs operation to determine
+ the new order. This Event does not include when a job enters the
+ queue (the 'job-created' Event covers that) and does not include
+ when a job leaves the queue (the 'job-completed' Event covers
+ that).
+
+5.3.2.1.3 Subscribed Job Events
+
+ The standard keyword values for Subscribed Job Events are:
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 26]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ 'job-state-changed': REQUIRED - the job has changed from any state
+ to any other state. Specifically, the Printer sends this Event
+ whenever the value of the "job-state" attribute or "job-state-
+ reasons" attribute changes. When a Job is removed from the Job
+ History (see [RFC2911] 4.3.7.1), no Event is generated.
+
+ This Event value has the following sub-values: 'job-created',
+ 'job-completed' and 'job-stopped'. A client can listen for any of
+ these sub-values if it doesn't want to listen to all 'job-state
+ changes'.
+
+ 'job-created': REQUIRED - the Printer has accepted a Job
+ Creation operation and the job's "time-at-creation"
+ attribute value is set (see [RFC2911] section 4.3.14.1).
+ The Printer puts the job in the 'pending', 'pending-held'
+ or 'processing' states..
+
+ 'job-completed': REQUIRED - the job has reached one of the
+ completed states, i.e., the value of the job's "job-state"
+ attribute has changed to: 'completed', 'aborted', or
+ 'canceled'. The Job's "time-at-completed" and "date-time-
+ at-completed" (if supported) attributes are set (see
+ [RFC2911] section 4.3.14).. The Printer also sends this
+ Event when a Job is removed with the Purge-Job operation.
+ In this case, the Event Notification MUST report the 'job-
+ state' as 'canceled'.
+
+ 'job-stopped: OPTIONAL - when the job stops printing, i.e.
+ the value of the "job-state" Job attribute becomes
+ 'processing-stopped'.
+
+ 'job-config-changed': OPTIONAL - when the configuration of a job has
+ changed, i.e., the value of the "job-message-from-operator" or any
+ of the "configuration" Job attributes have changed. A
+ "configuration" Job attribute is an attribute that can change
+ value because of some human interaction either direct or indirect.
+ Examples of "configuration" Job attributes are any of the job
+ template attributes and the "job-name" attribute. Often, such a
+ change is the result of the user or the Operator performing a Set-
+ Job-Attributes operation (see [ipp-set]) on the Job object. The
+ client performs a Get-Job-Attributes to find out the new values of
+ the changed attributes. This Event is useful for GUI clients and
+ drivers to update the job information to the user.
+
+ 'job-progress': OPTIONAL - when the Printer has completed Printing a
+ sheet. See the separate [ipp-prog] specification for additional
+ attributes that a Printer MAY send in an Event Notification caused
+ by this Event. The "notify-time-interval" attribute affects this
+ Event by causing the Printer NOT to send an Event Notification
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 27]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ every time a 'job-progress' Events occurs. See section 5.3.8 for
+ full details.
+
+5.3.2.2 Rules for Matching of Subscribed Events
+
+ When an Event occurs, the Printer MUST find each Subscription object
+ whose "notify-events" attribute "matches" the Event. The rules for
+ "matching" of Subscribed Events are described separately for Printer
+ Events and for Job Events. This section also describes some special
+ cases.
+
+5.3.2.2.1 Rules for Matching of Printer Events
+
+ Suppose that the Printer causes Printer Event E to occur. For each
+ Per-Job or Per-Printer Subscription S in the Printer, if E equals a
+ value of this attribute in S or E is a sub-value of a value of this
+ attribute in S, the Printer MUST generate an Event Notification.
+
+ Consider the example. There are three Subscription Objects each with
+ the Subscribed Printer Event 'printer-state-changed'. Subscription
+ Object A is a Per-Printer Subscription Object. Subscription Object B
+ is a Per-Job Subscription Object for Job 1, and Subscription Object C
+ is a Per-Job Subscription Object for Job 2. When the Printer enters
+ the 'stopped' state, the Printer sends an Event Notification to the
+ Notification Recipients of Subscription Objects A, B, and C because
+ this is a Printer Event. Note if Job 1 has already completed, the
+ Printer would not send an Event Notification for its Subscription
+ Object.
+
+5.3.2.2.2 Rules for Matching of Job Events
+
+ Suppose that Job J causes Job Event E to occur.
+
+ 1.For each Per-Printer Subscription S in the Printer, if E equals
+ a value of this attribute in S or E is a sub-value of a value of
+ this attribute in S, the Printer MUST generate an Event
+ Notification.
+
+ 2.For each Per-Job Subscription S associated with Job J, if E
+ equals a value of this attribute in S or E is a sub-value of a
+ value of this attribute in S, the Printer MUST generate an Event
+ Notification.
+
+ 3.For each Per-Job Subscription S that is NOT associated Job J, if
+ E equals a value of this attribute in S or E is a sub-value of a
+ value of this attribute in, the Printer MUST NOT generate an
+ Event Notification from S.
+
+ Consider the example: There are three Subscription Objects listening
+ for the Job Event 'job-completed'. Subscription Object A is a Per-
+
+
+Herriot, et al. Expires July 24, 2001 [page 28]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Printer Subscription Object. Subscription Object B is a Per-Job
+ Subscription Object for Job 1, and Subscription Object C is a Per-Job
+ Subscription Object for Job 2. In addition, Per-Printer Subscription
+ Object D is listening for the Job Event 'job-state-changed'. When Job
+ 1 completes, the Printer sends an Event Notification to the
+ Notification Recipient of Subscription Object A (because it is Per-
+ Printer) and Subscription Object B because it is a Per-Job
+ Subscription Object associated with the Job generating the Event.
+ The Printer also sends an Event Notification to the Notification
+ Recipient of Subscription Object D because 'job-completed' is a sub-
+ value of 'job-state-changed' - the value that Subscription Object D
+ is listening for. The Printer does not send an Event Notification to
+ the Notification Recipients of Subscription Object C because it is a
+ Per-Job Subscription Object associated with some Job other than the
+ Job generating the Event.
+
+5.3.2.2.3 Special Cases for Matching Rules
+
+ This section contains rule for special cases.
+
+ If an Event matches Subscribed Events in two different Subscription
+ Objects and the Printer would send two identical Event Notifications
+ (except for the "notify-subscription-id" attribute) to the same
+ Notification Recipient using the same Delivery Method, the Printer
+ MUST send both Event Notifications. That is, the Printer MUST NOT try
+ to consolidate seemingly identical Event Notifications that occur in
+ separate Subscription objects. Incidentally, the Printer MUST NOT
+ reject Subscription Creation Operations that would create this
+ scenario.
+
+ If an Event matches two values of this "notify-events" attribute in a
+ single Subscription object (e.g., a value and its sub-value), a
+ Printer MAY send one Event Notification for each matched value in the
+ Subscription Object or it MAY send only one Event Notification per
+ Subscription Object. The rules in sections 5.3.2.2.1 and 5.3.2.2.2
+ are purposefully ambiguous about the number of Event Notification
+ sent when Event E matches two or more values in a Subscription
+ Object.
+
+ Consider the example: There are two Per-Printer Subscription Objects
+ when a Job completes. Subscription Object A has the Subscribed Job
+ Event 'job-state-changed'. Subscription Object B has the Subscribed
+ Job Events 'job-state-changed' and 'job-completed'. The Printer sends
+ an Event Notification to the Notification Recipient of Subscription
+ Object A with the value of 'job-state-changed' for the "notify-
+ subscribing-event" attribute. The Printer sends either one or two
+ Event Notifications to the Notification Recipient of Subscription
+ Object B, depending on implementation. If it sends two Event
+ Notifications, one has the value of 'job-state-changed' for the
+ "notify-subscribing-event" attribute, and the other has the value of
+
+
+Herriot, et al. Expires July 24, 2001 [page 29]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ 'job-completed' for the "notify-subscribing-event" attribute. If it
+ sends one Event Notification, it has the value of either 'job-state-
+ changed' or 'job-completed' for the "notify-subscribing-event"
+ attribute, depending on implementation. The algorithm for choosing
+ such a value is implementation dependent.
+
+5.3.3 notify-attributes (1setOf type2 keyword)
+
+ This attribute contains a set of attribute names. When a Printer
+ sends a Machine Consumable Event Notification, it includes a fixed
+ set of attributes (see section 9.1). If this attribute is present and
+ the Event Notification is Machine Consumable, the Printer also
+ includes the attributes specified by this attribute.
+
+ A Printer MAY support this attribute.
+
+ A client MAY supply this attribute in a Subscription Creation
+ Operation. If the client does not supply this attribute in
+ Subscription Creation Operation or the Printer does not support this
+ attribute, the Subscription Object MUST NOT contain the "notify-
+ attributes" attribute. There is no "notify-attributes-default"
+ attribute.
+
+ Each keyword value of this attribute on a Subscription Object MUST be
+ a value of the "notify-attributes-supported (1setOf type2 keyword)"
+ attribute. The "notify-attributes-supported" MAY contain any Printer
+ attribute, Job attribute or Subscription Object attribute that the
+ Printer supports in an Event Notification. It MUST NOT contain any
+ of the attributes in Section 9.1 that a Printer automatically puts in
+ an Event Notification; it would be redundant. If a client supplies an
+ attribute in Section 9.1, the Printer MUST treat it as an unsupported
+ attribute value of the "notify-attributes" attribute.
+
+ The following rules apply to each keyword value N of the "notify-
+ attributes" attribute: If the value N names:
+
+ a)a Subscription attribute, the Printer MUST use the attribute N in
+ the Subscription Object that is being used to generate the Event
+ Notification.
+
+ b)a Job attribute and the Printer is generating an Event
+ Notification from a Per-Job Subscription Object S, the Printer
+ MUST use the attribute N in the Job object associated with S.
+
+ c)a Job attribute and the Printer is generating an Event
+ Notification from a Per-Printer Subscription Object and the Event
+ is:
+
+ . a Job Event, the Printer MUST use the attribute N in the Job
+ object that caused the Event.
+
+
+Herriot, et al. Expires July 24, 2001 [page 30]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ . a Printer Event, the Printer MUST use the attribute N in the
+ active Job.
+
+ If a Printer supports this attribute and a Subscription Object
+ contains this attribute and the Delivery Method generates a Machine
+ Consumable Event Notification, the Printer MUST include in each Event
+ Notification:
+
+ a)the attributes specified in section 9.1 and
+
+ b)each attribute named by this attribute.
+
+ The Printer MUST NOT use this attribute to generate a Human
+ Consumable Event Notification.
+
+5.3.4 notify-user-data (octetString(63))
+
+ This attribute contains opaque data that some Delivery Methods
+ include in each Machine Consumable Event Notification. The opaque
+ data might contain, for example:
+
+ . the identity of the Subscriber
+
+ . a path or index to some Subscriber information
+
+ . a key that identifies to the Notification Recipient the ultimate
+ recipient of the Event Notification
+
+ . the id for a Notification Recipient that had previously
+ registered with an Instant Messaging Service
+
+ A Printer MUST support this attribute.
+
+ A client MAY supply this attribute in a Subscription Creation
+ Operation. If the client does not supply this attribute in
+ Subscription Creation Operation, the Subscription Object MUST NOT
+ contain the "notify-user-data" attribute. There is no "notify-user-
+ data-default" attribute.
+
+ There is no "user-data-supported" attribute. Rather, any octetString
+ whose length does not exceed 63 octets is a supported value. If the
+ length exceeds 63 octets, the Printer MUST treat it as an unsupported
+ value.
+
+5.3.5 notify-charset (charset)
+
+ This attribute specifies the charset to be used in the Event
+ Notification content sent to the Notification Recipient, whether the
+ Event Notification content is Machine Consumable or Human Consumable.
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 31]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ A Printer MUST support this attribute.
+
+ A client MAY supply this attribute in a Subscription Creation
+ Operation. If the client does not supply this attribute in
+ Subscription Creation Operation or supplies an unsupported value, the
+ Printer MUST populate this attribute in the Subscription Object with
+ the value of the "attributes-charset" operation attribute, which is a
+ REQUIRED attribute in all IPP requests (see [RFC2911]). If the value
+ of the "attributes-charset" attribute is unsupported, the Printer
+ MUST populate this attribute in the Subscription Object with the
+ value of the Printer's "charset-configured" attribute. There is no
+ "notify-charset-default" attribute.
+
+ The value of this attribute on a Subscription Object MUST be a value
+ of the "charset-supported (1setOf charset)" attribute.
+
+5.3.6 notify-natural-language (naturalLanguage)
+
+ This attribute specifies the natural language to be used in any human
+ consumable text in the Event Notification content sent to the
+ Notification Recipient, whether the Event Notification content is
+ Machine Consumable or Human Consumable.
+
+ A Printer MUST support this attribute.
+
+ A client MAY supply this attribute in a Subscription Creation
+ Operation. If the client does not supply this attribute in
+ Subscription Creation Operation or supplies an unsupported value, the
+ Printer MUST populate this attribute in the Subscription Object with
+ the value of the "attributes-natural-language" operation attribute,
+ which is a REQUIRED attribute in all IPP requests (see [RFC2911]). If
+ the value of the "attributes-natural-language" attribute is
+ unsupported, the Printer MUST populate this attribute in the
+ Subscription Object with the value of the Printer's "natural-
+ language-configured" attribute. There is no "notify-natural-language-
+ default" attribute.
+
+ The value of this attribute on a Subscription Object MUST be a value
+ of the "generated-natural-language-supported (1setOf type2
+ naturalLanguage)" attribute.
+
+5.3.7 notify-lease-duration (integer(0:67108863))
+
+ This attribute specifies the duration of the lease (in seconds)
+ associated with the Per-Printer Subscription Object at the time the
+ Subscription Object was created or the lease was renewed. The
+ duration of the lease is infinite if the value is 0, i.e., the lease
+ never expires.
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 32]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ This attribute is not present on a Per-Job Subscription Object
+ because the Subscription Object lasts exactly as long as the
+ associated Job object. See section 5.4.3 on "notify-lease-expiration-
+ time (integer(0:MAX))" for more details.
+
+ A Printer MUST support this attribute.
+
+ For a Subscription Object Creation operation of a Per-Job
+ Subscription Object, the client MUST NOT supply this attribute. If
+ the client does supply this attribute, the Printer MUST treat it as
+ an unsupported attribute.
+
+ For a Subscription Creation Operation of a Per-Printer Subscription
+ Object or a Renew-Subscription operation, a client MAY supply this
+ attribute. If the client does not supply this attribute, the Printer
+ MUST populate this attribute with its "notify-lease-duration-default"
+ (0:67108863) attribute value. If the client supplies this attribute
+ with an unsupported value, the Printer MUST populate this attribute
+ with a supported value, and this value SHOULD be as close as possible
+ to the value requested by the client. Note: this rule implies that a
+ Printer doesn't assign the value of 0 (infinite) unless the client
+ requests it.
+
+ After the Printer has populated this attribute with a supported
+ value, the value represents the "granted duration" of the lease in
+ seconds and the Printer sets the value of the Subscription Object's
+ "notify-lease-expiration-time" attribute as specified in section
+ 5.4.3.
+
+ The value of this attribute on a Subscription Object MUST be a value
+ of the "notify-lease-duration-supported" (1setOf (integer(0:67108863)
+ | rangeOfInteger(0:67108863))) attribute.
+
+ A Printer MAY require authentication in order to return the value of
+ 0 (the lease never expires) as one of the values of "notify-lease-
+ duration-supported", and to allow 0 as a value of the "notify-lease-
+ duration" attribute.
+
+ Note: The maximum value 67,108,863 is 2 raised to the 26 power minus
+ 1 and is about 2 years in seconds. The value is considerably less
+ than MAX so that there is virtually no chance of an overflow when it
+ is added to "printer-up-time" to produce "notify-lease-expiration-
+ time".
+
+5.3.8 notify-time-interval (integer(0:MAX))
+
+ The 'job-progress' Event occurs each time that a Printer completes a
+ sheet. Some Notification Recipients do not want to receive an Event
+ Notification every time this Event occurs. This attribute allows a
+ Subscribing Client to request how often it wants to receive Event
+
+
+Herriot, et al. Expires July 24, 2001 [page 33]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Notifications for 'job-progress' Events. The value of this attribute
+ MAY be any nonnegative integer (0,MAX) indicating the minimum number
+ of seconds between 'job-progress' Event Notifications.
+
+ The Printer MUST support this attribute if and only if the Printer
+ supports the 'job-progress' Event.
+
+ A client MAY supply this attribute in a Subscription Creation
+ Operation. If the client does not supply this attribute, the Printer
+ MUST not populate this attribute on the Subscription Object. There is
+ no "notify-time-interval-default" attribute.
+
+ There is no "notify-time-interval-supported" attribute.
+
+ If the 'job-progress' Event occurs and a Subscription Object contains
+ the 'job-progress' Event as a value of the 'notify-events' attribute,
+ there are two cases to consider:
+
+ 1.This attribute is not present on the Subscription Object or has
+ the value of 0. The Printer MUST generate and send an Event
+ Notification (as is the case with other Events).
+
+ 2.This attribute is present with a nonzero value of N:
+
+ a)If the Printer has not sent an Event Notification for the 'job-
+ progress' Event for the associated Subscription Object within
+ the past N seconds, the Printer MUST send an Event Notification
+ for the Event that just occurred. Note when the Printer
+ completes the first page of a Job, this rule implies that the
+ Printer sends an Event Notification for a Per-Job Subscription
+ Objects.
+
+ b)Otherwise, the Printer MUST NOT generate or send an Event
+ Notification for the associated Subscription Object. The Printer
+ MUST NOT increase the value of the "notify-sequence-number"
+ Subscription Object attribute (i.e., the sequence of values of
+ the "notify-sequence-number" attribute counts the Event
+ Notifications that the Printer sent and not the Events that do
+ not cause an Event Notification to be sent).
+
+ It is RECOMMENDED that a Subscribing Client use this attribute when
+ it subscribes to the 'job-progress' Event, and that the value be
+ sufficiently large to limit the frequency with which the Printer
+ sends Event Notifications requests.
+
+ This attribute MUST NOT effect any Events other than 'job-progress'.
+
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 34]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+5.4 Subscription Description Attributes
+
+ Subscription Description Attributes are those attributes that a
+ Printer adds to a Subscription Object at the time of its creation.
+
+ A Printer MUST support all attributes in this Table 2.
+
+ A client MUST NOT supply the attributes in Table 2 in a Subscription
+ Template Attributes Group of a Subscription Creation Operation. If
+ the client supplies them, the Printer MUST NOT set them and MUST
+ treat them as unsupported attributes. There are no corresponding
+ default or supported attributes.
+
+
+ Table 2 - Subscription Description Attributes
+
+
+
+ Subscription Object attributes:
+
+
+ notify-subscription-id (integer(1:MAX))
+
+ notify-sequence-number (integer(0:MAX))
+
+ notify-lease-expiration-time (integer(0:MAX))
+
+ notify-printer-up-time (integer(1:MAX))
+
+ notify-printer-uri (uri)
+
+ notify-job-id (integer(1:MAX))
+
+ notify-subscriber-user-name (name(MAX))
+
+
+
+5.4.1 notify-subscription-id (integer (1:MAX))
+
+ This attribute identifies a Subscription Object instance with a
+ number that is unique within the context of the Printer. The Printer
+ generates this value at the time it creates the Subscription Object.
+
+ A Printer MUST support this attribute.
+
+ The Printer SHOULD NOT assign the value of this attribute
+ sequentially as it creates Subscription Objects. Sequential
+ assignment makes it easy for rogue clients to guess the value of this
+ attribute on other Subscription Objects.
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 35]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ The Printer SHOULD avoid re-using recent values of this attribute
+ during continuous operation of the Printer as well as across power
+ cycles. Then a Subscribing Client is unlikely to find that a stale
+ reference accesses a new Subscription Object.
+
+ The 0 value is not permitted in order to allow for compatibility with
+ "job-id" and with SNMP index values, which also cannot be 0.
+
+5.4.2 notify-sequence-number (integer (0:MAX))
+
+ The value of this attribute indicates the number of times that the
+ Printer has generated and attempted to send an Event Notification.
+ When an Event Notification contains this attribute, the Notification
+ Recipient can determine whether it missed some Event Notifications
+ (i.e., numbers skipped) or received duplicates (i.e., same number
+ twice).
+
+ A Printer MUST support this attribute.
+
+ When the Printer creates a Subscription Object, it MUST set the value
+ of this attribute to 0. This value indicates that the Printer has not
+ sent any Event Notifications for this Subscription Object.
+
+ Each time the Printer sends a newly generated Event Notification, it
+ MUST increase the value of this attribute by 1. For some Delivery
+ Methods, the Printer MUST include this attribute in each Event
+ Notification, and the value MUST be the value after it is increased
+ by 1. That is, the value of this attribute in the first Event
+ Notification after Subscription object creation MUST be 1, the second
+ MUST be 2, etc. If a Delivery Method is defined such that the
+ Notification Recipient returns a response, the Printer can re-try
+ sending an Event Notification a certain number of times with the same
+ sequence number when the Notification Recipient fails to return a
+ response.
+
+ If a Subscription Object lasts long enough to reach the value of MAX,
+ its next value MUST be 0, i.e., it wraps.
+
+5.4.3 notify-lease-expiration-time (integer(0:MAX))
+
+ This attribute specifies the time in the future when the lease on the
+ Per-Printer Subscription Object will expire, i.e. the "printer-up-
+ time" value at which the lease will expire. If the value is 0, the
+ lease never expires.
+
+ A Printer MUST support this attribute.
+
+ When the Printer creates a Per-Job Subscription Object, this
+ attribute MUST NOT be present - the Subscription Object lasts exactly
+ as long as the associated Job object.
+
+
+Herriot, et al. Expires July 24, 2001 [page 36]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ When the Printer creates a Per-Printer Subscription Object, it
+ populates this attribute with a value that is the sum of the values
+ of the Printer's "printer-up-time" attribute and the Subscription
+ Object's "notify-lease-duration" attribute with the following
+ exception. If the value of the Subscription Object's "notify-lease-
+ duration" attribute is 0 (i.e., no expiration time), then the value
+ of this attribute MUST be set to 0 (i.e., no expiration time).
+
+ When the Printer powers up, it MUST set the value of this attribute
+ in each persistent Subscription Object using the algorithm in the
+ previous paragraph.
+
+ When the "printer-up-time" equals the value of this attribute, the
+ Printer MUST delete the Subscription Object. A client can extend a
+ lease of a Per-Printer Subscription Object with the Renew-
+ Subscription operation (see section 11.2.5).
+
+ Note: In order to compute the number of seconds remaining in a lease
+ for a Per-Printer Subscription Object, a client can subtract the
+ Subscription's "notify-printer-up-time" attribute (see section 5.4.4)
+ from the Subscription's "notify-lease-expiration-time" attribute.
+
+5.4.4 notify-printer-up-time (integer(1:MAX))
+
+ This attribute is an alias for the Printer's "printer-up-time"
+ attribute " (see [RFC2911] section 4.4.29).
+
+ A Printer MUST support this attribute.
+
+ When the Printer creates a Per-Job Subscription Object, this
+ attribute MUST NOT be present. When the Printer creates a Per-Printer
+ Subscription Object, this attribute MUST be present.
+
+ Note: this attribute exists in a Per-Printer Subscription Object so
+ that a client using the Get-Subscription-Attributes or Get-
+ Subscription operations can convert the Per-Printer Subscription's
+ "notify-lease-expiration-time" attribute to wall clock time with one
+ request. If the value of the "notify-lease-expiration-time" attribute
+ is not 0 (i.e., no expiration time), then the difference between the
+ "notify-lease-expiration-time" attribute and the "notify-printer-up-
+ time" is the remaining number of seconds on the lease from the
+ current time.
+
+5.4.5 notify-printer-uri (uri)
+
+ This attribute identifies the Printer object that created this
+ Subscription Object.
+
+ A Printer MUST support this attribute.
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 37]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ During a Subscription Creation Operation, the Printer MUST populate
+ this attribute with the value of the "printer-uri" operation
+ attribute in the request. From the Printer URI, the client can, for
+ example, determine what security scheme was used.
+
+5.4.6 notify-job-id (integer(1:MAX))
+
+ This attribute specifies whether the containing Subscription Object
+ is a Per-Job or Per-Printer Subscription Object, and for Per-Job
+ Subscription Objects, it specifies the associated Job.
+
+ A Printer MUST support this attribute.
+
+ If this attribute is not present, the Subscription Object MUST be a
+ Per-Printer Subscription. If this attribute is present, the
+ Subscription Object MUST be a Per-Job Subscription Object and this
+ attribute MUST identify the Job with which the Subscription Object is
+ associated.
+
+ Note: This attribute could be useful to a Notification Recipient that
+ receives an Event Notification generated from a Per-Job Subscription
+ Object and caused by a Printer Event. The Event Notification gives
+ access to the Printer and the Subscription Object. The Event
+ Notification gives access to the associated Job only via this
+ attribute.
+
+5.4.7 notify-subscriber-user-name (name(MAX))
+
+ This attribute contains the name of the user who performed the
+ Subscription Creation Operation.
+
+ A Printer MUST support this attribute.
+
+ The Printer sets this attribute to the most authenticated printable
+ name that it can obtain from the authentication service over which
+ the Subscription Creation Operation was received. The Printer uses
+ the same mechanism for determining the value of this attribute as it
+ does for a Job's "job-originating-user-name" (see [RFC2911] section
+ 4.3.6).
+
+ Note: To help with authentication, a Subscription Object may have
+ additional private attributes about the user, e.g., a credential of a
+ principal. Such private attributes are implementation-dependent and
+ not defined in this document.
+
+
+6 Printer Description Attributes Related to Notification
+
+ This section defines the Printer Description attributes that are
+ related to Notification. Table 3 lists the Printer Description
+
+
+Herriot, et al. Expires July 24, 2001 [page 38]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ attributes, indicates the Printer support required for conformance,
+ and whether or not the attribute is READ-ONLY (see section 3.1):
+
+
+ Table 3 - Printer Description Attributes Associated with Notification
+
+
+
+ Printer object attributes: REQUIRED READ-ONLY
+
+
+ printer-state-change-time (integer(1:MAX)) No Yes
+
+ printer-state-change-date-time (dateTime) No Yes
+
+
+
+6.1 printer-state-change-time (integer(1:MAX))
+
+ This attribute records the most recent time at which the 'printer-
+ state-changed' Printer Event occurred whether or not any Subscription
+ objects were listening for this event. This attribute helps a client
+ or operator to determine how long the Printer has been in its current
+ state.
+
+ A Printer MAY support this attribute and if so, the attribute MUST be
+ READ-ONLY.
+
+ On power-up, the Printer MUST set the value of this attribute to be
+ the value of its "printer-up-time" attribute, so that it always has a
+ value. Whenever the 'printer-state-changed' Printer Event occurs, the
+ Printer MUST set this attribute to the value of the Printer's
+ "printer-up-time" attribute.
+
+6.2 printer-state-change-date-time (dateTime)
+
+ This attribute records the most recent time at which the 'printer-
+ state-changed' Printer Event occurred whether or not there were any
+ Subscription Objects listening for this event. This attribute helps
+ a client or operator to determine how long the Printer has been in
+ its current state.
+
+ A Printer MAY support this attribute and if so, the attribute MUST be
+ READ-ONLY.
+
+ On power-up, the Printer MUST set the value of this attribute to be
+ the value of its "printer-current-time" attribute, so that it always
+ has a value (see [RFC2911] section 4.4.30 on "printer-current-time").
+ Whenever the 'printer-state-changed' Printer Event occurs, the
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 39]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Printer MUST set this attribute to the value of the Printer's
+ "printer-current-time" attribute.
+
+
+7 New Values for Existing Printer Description Attributes
+
+ This section contains those attributes for which additional values
+ are added.
+
+7.1 operations-supported (1setOf type2 enum)
+
+ The following "operation-id" values are added in order to support the
+ new operations defined in this document:
+
+
+ Table 4 - Operation-id assignments
+
+
+
+ Value Operation Name
+
+
+ 0x0016 Create-Printer-Subscriptions
+
+ 0x0017 Create-Job-Subscriptions
+
+ 0x0018 Get-Subscription-Attributes
+
+ 0x0019 Get-Subscriptions
+
+ 0x001A Renew-Subscription
+
+ 0x001B Cancel-Subscription
+
+
+8 Attributes Only in Event Notifications
+
+ This section contains those attributes that exist only in Event
+ Notifications and do not exist in any objects.
+
+8.1 notify-subscribed-event (type2 keyword)
+
+ This attribute indicates the Subscribed Event that caused the Printer
+ to send this Event Notification. This attribute exists only in Event
+ Notifications.
+
+ This attribute MUST contain one of the values of the "notify-events"
+ attribute in the Subscription Object, i.e., one of the Subscribed
+ Event values. Its value is the Subscribed Event that "matches" the
+ Event that caused the Printer to send this Event Notification. This
+
+
+Herriot, et al. Expires July 24, 2001 [page 40]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Subscribed Event value may be identical to the Event or the Event may
+ be a sub-value of the Subscribed Event. For example, the 'job-
+ completed' Event (which is a sub-event of the 'job-state-changed'
+ event) would cause the Printer to send an Event Notification for
+ either the 'job-completed' or 'job-state-changed' Subscribed Events
+ and to send the 'job-completed' or 'job-state-changed' value for this
+ attribute, respectively,. See section 5.3.2.2 for the "matching"
+ rules of Subscribed Events and for additional examples.
+
+ The Delivery Method Document specifies whether the Printer includes
+ the value of this attribute in an Event Notification.
+
+8.2 notify-text (text(MAX))
+
+ This attribute contains a Human Consumable text message (see section
+ 0). This message describes the Event and is encoded as plain text,
+ i.e., 'text/plain' with the charset specified by Subscription
+ Object's "notify-charset" attribute.
+
+ The Delivery Method Document specifies whether the Printer includes
+ this attribute in an Event Notification.
+
+
+9 Event Notification Content
+
+ This section defines the Event Notification content that the Printer
+ sends when an Event occurs.
+
+ When an Event occurs, the Printer MUST find each Subscription object
+ whose "notify-events" attribute "matches" the Event. See section
+ 5.3.2.2 for details on "matching". For each matched Subscription
+ Object, the Printer MUST create an Event Notification with the
+ content and format that the Delivery Method Document specifies. The
+ content contains the value of attributes specified by the Delivery
+ Method Document. The Printer obtains the values immediately after the
+ Event occurs. For example, if the "printer-state" attribute changes
+ from 'idle' to 'processing', the Event 'printer-state-changed' occurs
+ and the Printer puts various attributes into the Event Notification,
+ including "printer-up-time" and "printer-state" with the values that
+ they have immediately after the Event occurs, i.e., the value of
+ "printer-state" is 'processing'.
+
+ If two different Events occur simultaneously, or nearly so (e.g.,
+ "printer-up-time" has the same value for both), the Printer MUST
+ create a separate Event Notification for each Event, even if the
+ associated Subscription Object is the same for both Events. However,
+ the Printer MAY combine these distinct Event Notifications into a
+ single Compound Event Notification if the Delivery Method supports
+ Compound Event Notifications For example, suppose that two nearly-
+ simultaneously Events represent two successive 'printer-state-
+
+
+Herriot, et al. Expires July 24, 2001 [page 41]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ changed' Events, one from 'idle' to 'processing' and another from
+ 'processing' to 'stopped'. These two Events have the same name but
+ are different instances of the Event. Then the Printer MUST create a
+ separate Event Notification for each Event and SHOULD accurately
+ report the "printer-state" of the first Event as 'processing' and the
+ second Event as 'stopped'.
+
+ If a Subscription Object contains more than one Subscribed Event, and
+ several Events occur in quick succession each matching a different
+ Subscribed Event in the Subscription Object, the Printer MUST NOT
+ generate a single Event Notification from several of these Events,
+ but MAY combine distinct Event Notifications into a single Compound
+ Event Notification if the Delivery Method supports Compound Event
+ Notifications.
+
+ After the Printer has created the Event Notification, the Printer
+ delivers it via either a:
+
+ Push Delivery Method: The Printer sends the Event Notification
+ shortly after an Event occurs. For some Push Delivery Methods,
+ the Notification Recipient MUST send a response; for others it
+ MUST NOT send a response.
+
+ Pull Delivery Method: The Printer saves Event Notifications for
+ some event-lease time and expects the Notification Recipient to
+ request Event Notifications. The Printer returns the Event
+ Notifications in a response to such a request.
+
+ If an error that meets the following conditions occurs, the Printer
+ MUST cancel the Subscription Object.
+
+ a)the error occurs during the sending of an Event Notification
+ generated from Subscription Object S AND
+
+ b)the error would continue to occur every time the Printer sends an
+ Event Notification generated from Subscription Object S in the
+ future.
+
+ From example, if the address of the "notify-recipient-uri" of
+ Subscription Object A references a non-existent target and the
+ Printer determines that this fact, it MUST delete Subscription Object
+ A.
+
+ The next two sections describe the values that a Printer sends in the
+ content of Machine Consumable and Human Consumable Event
+ Notifications, respectively.
+
+ The tables in the sub-sections of this section contain the following
+ columns:
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 42]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ a)Source Value: the name of the attribute that supplies the value
+ for the Event Notification. Asterisks in this field refer to a
+ note below the table.
+
+ b)Sends: if the Printer supports the value (column 1) on the
+ Source Object (column 3) the Delivery Method MUST specify:
+
+ MUST: that the Printer MUST send the value.
+
+ SHOULD: either that the Printer MUST send the value or that
+ the value is incompatible with the Delivery Method.
+
+ MAY: that the Printer MUST, SHOULD, MAY, MUST NOT, SHOULD NOT,
+ or NEED NOT send the value. The Delivery Method specifies the
+ level of conformance for the Printer.
+
+ c)Source Object: the object from which the source value comes. If
+ the object is "Event Notification", the Printer fabricates the
+ value when it sends the Event Notification. See section 8.
+
+9.1 Content of Machine Consumable Event Notifications
+
+ This section defines the attributes that a Delivery Method MUST
+ mention in a Delivery Method Document when specifying the Machine
+ Consumable Event Notification's contents.
+
+ This document does not define the order of attributes in Event
+ Notifications. However, Delivery Method Documents MAY define the
+ order of some or all of the attributes.
+
+ A Delivery Method Document MUST specify additional attributes (if
+ any) that a Printer implementation sends in a Machine Consumable
+ Event Notification.
+
+ Notification Recipients MUST be able to accept Event Notifications
+ containing attributes they do not recognize. What a Notification
+ Recipient does with an unrecognized attribute is implementation-
+ dependent. Notification Recipients MAY attempt to display
+ unrecognized attributes anyway or MAY ignore them.
+
+ The next three sections define the attributes in Event Notification
+ Contents that are:
+
+ 1.for all Events
+
+ 2.for Job Events only
+
+ 3.for Printer Events only
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 43]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+9.1.1 Event Notification Content Common to All Events
+
+ This section lists the attributes that a Delivery Method Document
+ MUST specify for all Events.
+
+ Table 5 lists potential values in each Event Notification.
+
+
+ Table 5 - Attributes in Event Notification Content
+
+
+
+ Source Value Sends Source Object
+
+
+ notify-subscription-id (integer(1:MAX)) MUST Subscription
+
+ notify-printer-uri (uri) MUST Subscription
+
+ notify-subscribed-event (type2 keyword) MUST Event
+ Notification
+
+ printer-up-time (integer(MIN:MAX)) MUST Printer
+
+ printer-current-time (dateTime) * MUST Printer
+
+ notify-sequence-number (integer (0:MAX)) SHOULD Subscription
+
+ notify-charset (charset) SHOULD Subscription
+
+ notify-natural-language (naturalLanguage) SHOULD Subscription
+
+ notify-user-data (octetString(63)) ** SHOULD Subscription
+
+ notify-text (text) SHOULD Event
+ Notification
+
+ attributes from the "notify-attributes" MAY Printer
+ attribute ***
+
+ attributes from the "notify-attributes" MAY Job
+ attribute ***
+
+ attributes from the "notify-attributes" MAY Subscription
+ attribute ***
+
+
+ *A Printer MUST send this value only if and only if it supports the
+ Printer's "printer-current-time" attribute.
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 44]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ ** If the Subscription Object does not contain a "notify-user-data"
+ attribute and the Delivery Method document REQUIRES the Printer to
+ send the "notify-user-data" source value in the Event Notification,
+ the Printer MUST send an octet-string of length 0.
+
+ *** The last three rows represent additional attributes that a client
+ MAY request via the "notify-attributes" attribute. A Printer MAY
+ support the "notify-attributes" attribute. The Delivery Method MUST
+ say that the Printer MUST, SHOULD, MAY, MUST NOT, SHOULD NOT, or NEED
+ NOT support the "notify-attributes" attribute and specific values of
+ this attribute. The Delivery Method MAY say that support for the
+ "notify-attributes" is conditioned on support of the attribute by the
+ Printer or it MAY say that Printer MUST support the "notify-
+ attributes" attribute if the Printer supports the Delivery Method.
+
+9.1.2 Additional Event Notification Content for Job Events
+
+ This section lists the additional attributes that a Delivery Method
+ Document MUST specify for Job Events. See Table 6.
+
+
+ Table 6 - Additional Event Notification Content for Job Events
+
+
+
+ Source Value Sends Source Object
+
+
+ job-id (integer(1:MAX)) MUST Job
+
+ job-state (type1 enum) MUST Job
+
+ job-state-reasons (1setOf type2 keyword) MUST Job
+
+ job-impressions-completed (integer(0:MAX)) * MUST Job
+
+
+ * The Printer MUST send the "job-impressions-completed" attribute in
+ an Event Notification only for the combinations of Events and
+ Subscribed Events shown in Table 7.
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 45]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Table 7 - Combinations of Events and Subscribed Events for "job-
+ impressions-completed"
+
+
+
+ Job Event Subscribed Job Event
+
+
+ 'job-progress' 'job-progress'
+
+ 'job-completed' 'job-completed'
+
+ 'job-completed' 'job-state-changed'
+
+
+
+9.1.3 Additional Event Notification Content for Printer Events
+
+ This section lists the additional attributes that a Delivery Method
+ Document MUST specify for Printer Events. See Table 8.
+
+
+ Table 8 - Additional Event Notification Content for Printer Events
+
+
+
+ Source Value Sends Source Object
+
+
+ printer-state (type1 enum) MUST Printer
+
+ printer-state-reasons (1setOf type2 keyword) MUST Printer
+
+ printer-is-accepting-jobs (boolean) MUST Printer
+
+
+9.2 Content of Human Consumable Event Notification
+
+ This section defines the information that a Delivery Method MUST
+ mention in a Delivery Method Document when specifying the Human
+ Consumable Event Notifications contents or the value of the "notify-
+ text" attribute.
+
+ Such a Delivery Method MUST specify the following information and a
+ Printer SHOULD send it:
+
+ a)the Printer name (see Table 9)
+ b)the time of the Event (see Table 11)
+ c)for Printer Events only:
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 46]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ i) the Event (see Table 10) and/or Printer state information
+ (see Table 14)
+ d)for Job Events only:
+ i) the job identity (see Table 12)
+ ii) the Event (see Table 10) and/or Job state information (see
+ Table 13)
+
+ The subsections of this section specify the attributes that a Printer
+ MUST use to obtain this information.
+
+ A Delivery Method Document MUST specify additional information (if
+ any) that a Printer implementation sends in a Human Consumable Event
+ Notification or in the "notify-text" attribute.
+
+ A client MUST NOT request additional attributes via the "notify-
+ attributes" attribute because this attribute works only for Machine
+ Consumable Event Notifications.
+
+ Notification Recipients MUST NOT expect to be able to parse the Human
+ Consumable Event Notification contents or the value of the "notify-
+ text" attribute.
+
+ The next three sections define the attributes in Event Notification
+ Contents that are:
+
+ a) for all Events
+ b) for Job Events only
+ c) for Printer Events only
+
+9.2.1 Event Notification Content Common to All Events
+
+ This section lists the source of the information that a Delivery
+ Method MUST specify for all Events.
+
+ There is a separate table for each piece of information. Each row in
+ the table represents a source value for the information and the
+ values are listed in order of preference, with the first one being
+ the preferred one. An implementation SHOULD use the source value from
+ the earliest row in each table. It MAY use the source value from
+ another row instead, or it MAY combine the source values from several
+ rows. An implementation is free to determine the best way to present
+ this information.
+
+ In all tables of this section, all rows contain a "MAY" in order to
+ state that the Delivery Method specifies the conformance.
+
+ Table 9 lists the source of the information for the Printer Name. The
+ "printer-name" is more user-friendly unless the Notification
+ Recipient is in a place where the Printer name is not meaningful. For
+ example, an implementation could have the intelligence to send the
+
+
+Herriot, et al. Expires July 24, 2001 [page 47]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ value of the "printer-name" attribute to a Notification Recipient
+ that can access the Printer via value of the "printer-name" attribute
+ and otherwise send the value of the "notify-printer-uri" attribute.
+
+
+ Table 9 - Printer Name in Event Notification Content
+
+
+
+ Source Value Sends Source Object
+
+
+ printer-name (name(127)) MAY Printer
+
+ notify-printer-uri (uri) MAY Subscription
+
+
+
+
+ Table 10 lists the source of the information for the Event name. A
+ Printer MAY combine this information with state information described
+ for Jobs in Table 13 or for Printers in Table 14.
+
+
+ Table 10 - Event Name in Event Notification Content
+
+
+
+ Source Value Sends Source Object
+
+
+ notify-subscribed-event (type2 keyword) MAY Subscription
+
+
+
+ Table 11 lists the source of the information for the time that the
+ Event occurred. A Printer can send this value only if it supports the
+ Printer's "printer-current-time" attribute. If a Printer does not
+ support the "printer-current-time" attribute, it MUST NOT send the
+ "printer-up-time" value instead, since it is not an allowed option
+ for human consumable information.
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 48]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Table 11 - Event Time in Event Notification Content
+
+
+
+ Source Value Sends Source Object
+
+
+ printer-current-time (dateTime) MAY Printer
+
+
+
+9.2.2 Additional Event Notification Content for Job Events
+
+ This section lists the source of the additional information that a
+ Delivery Method MUST specify for Job Events.
+
+ Table 12 lists the source of the information for the job name. The
+ "job-name" is likely more meaningful to a user than "job-id".
+
+
+ Table 12 - Job Name in Event Notification Content
+
+
+
+ Source Value Sends Source Object
+
+
+ job-name (name(MAX)) MAY Job
+
+ job-id (integer(1:MAX)) MAY Job
+
+
+
+ Table 13 lists the source of the information for the job state. If a
+ Printer supports the "job-state-message" and "job-detailed-state-
+ message" attributes, it SHOULD use those attributes for the job state
+ information, otherwise, it should fabricate such information from the
+ "job-state" and "job-state-reasons". For some Events, a Printer MAY
+ combine this information with Event information.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 49]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Table 13 - Job State in Event Notification Content
+
+
+
+ Source Value Sends Source
+ Object
+
+
+ job-state-message (text(MAX)) MAY Job
+
+ job-detailed-status-messages (1setOf text(MAX)) MAY Job
+
+ job-state (type1 enum) MAY Job
+
+ job-state-reasons (1setOf type2 keyword) MAY Job
+
+
+9.2.3 Additional Event Notification Content for Printer Events
+
+ This section lists the source of the additional information that a
+ Delivery Method MUST specify for Printer Events.
+
+ Table 14 lists the source of the information for the printer state.
+ If a Printer supports the "printer-state-message", it SHOULD use that
+ attribute for the job state information, otherwise it SHOULD
+ fabricate such information from the "printer-state" and "printer-
+ state-reasons". For some Events, a Printer MAY combine this
+ information with Event information.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 50]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Table 14 - Printer State in Event Notification Content
+
+
+
+ Source Value Sends Source
+ Object
+
+
+ printer-state-message (text(MAX)) MAY Printer
+
+ printer-state (type1 enum) MAY Printer
+
+ printer-state-reasons (1setOf type2 keyword) MAY Printer
+
+ printer-is-accepting-jobs (boolean) MAY Printer
+
+
+10 Delivery Methods
+
+ A Delivery Method is the mechanism, i.e., protocol, by which the
+ Printer delivers an Event Notification to a Notification Recipient.
+ There are several potential Delivery Methods for Event Notifications,
+ standardized, as well as proprietary. This document does not define
+ any of these delivery mechanisms. Each Delivery Method MUST be
+ defined in a Delivery Method Document that is separate from this
+ document. New Delivery Methods will be created as needed using an
+ extension to the registration procedures defined in [RFC2911]. Such
+ documents are registered with IANA (see section 13).
+
+ The following sorts of Delivery Methods are expected:
+
+ - The Notification Recipient polls for Event Notifications at
+ intervals directed by the Printer
+
+ - The Printer sends Event Notifications to the Notification
+ Recipient using http as the transport.
+
+ - The Printer sends an email message.
+
+ This section specifies how to define a Delivery Method Document and
+ what to put in such a document.
+
+ A Delivery Method Document MUST contain an exact copy of the
+ following paragraph, caption and table. In addition, column 2 of the
+ table in the Delivery Method Document MUST contain answers to
+ questions in column 1 for the Delivery Method. Also, the Delivery
+ Method document MUST contain a reference to this document and call
+ that reference [ipp-ntfy] because the table contains an [ipp-ntfy]
+ reference.
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 51]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ If a Printer supports this Delivery Method, the following are its
+ characteristics.
+
+
+ Table 15 - Information about the Delivery Method
+
+
+
+ Document Method Conformance Delivery Method Realization
+ Requirement
+
+
+ 1.What is the URL scheme name for the
+ Delivery Method?
+
+ 2.Is the Delivery Method REQUIRED,
+ RECOMMENDED, or OPTIONAL for an IPP
+ Printer to support?
+
+ 3.What transport and delivery
+ protocols does the Printer use to
+ deliver the Event Notification
+ Content, i.e., what is the entire
+ network stack?
+
+ 4.Can several Event Notifications be
+ combined into a Compound Event
+ Notification?
+
+ 5.Is the Delivery Method initiated by
+ the Notification Recipient (pull),
+ or by the Printer (push)?
+
+ 6.Is the Event Notification content
+ Machine Consumable or Human
+ Consumable?
+
+ 7.What section in this document
+ answers the following question? For
+ a Machine Consumable Event
+ Notification, what is the
+ representation and encoding of
+ values defined in section 9.1 of
+ [ipp-ntfy] and the conformance
+ requirements thereof? For a Human
+ Consumable Event Notification, what
+ is the representation and encoding
+ of pieces of information defined in
+ section 0 of [ipp-ntfy] and the
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 52]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+
+ conformance requirements thereof?
+
+ 8.What are the latency and
+ reliability of the transport and
+ delivery protocol?
+
+ 9.What are the security aspects of
+ the transport and delivery
+ protocol, e.g., how it is handled
+ in firewalls?
+
+ 10. What are the content length
+ restrictions?
+
+ 11. What are the additional values
+ or pieces of information that a
+ Printer sends in an Event
+ Notification content and the
+ conformance requirements thereof?
+
+ 12. What are the additional
+ Subscription Template and/or
+ Subscription Description attributes
+ and the conformance requirements
+ thereof?
+
+ 13. What are the additional Printer
+ Description attributes and the
+ conformance requirements thereof?
+
+
+
+11 Operations for Notification
+
+ This section defines all of the operations for Notification. Section
+ 7.1 assigns the "operation-id" for each operation. The following two
+ sub-sections define Subscription Creation Operations, and other
+ operations.
+
+11.1 Subscription Creation Operations
+
+ This section defines the Subscription Creation Operations. The first
+ section on Create-Job-Subscriptions gives most of the information.
+ The other Subscription Creation Operations refer to the section on
+ Create-Job-Subscriptions, even though the Create-Job-Subscriptions
+ operation is the only OPTIONAL operation in this document (see
+ section 12).
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 53]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ A Printer MUST support Create-Printer-Subscriptions and the
+ Subscription Template Attributes Group in Job Creation operations. It
+ MAY support Create-Job-Subscriptions operations.
+
+11.1.1 Create-Job-Subscriptions Operation
+
+ The operation creates one or more Per-Job Subscription Objects. The
+ client supplies one or more Subscription Template Attributes Groups
+ each containing one or more of Subscription Template Attributes
+ (defined in section 5.3).
+
+ Except for errors, the Printer MUST create exactly one Per-Job
+ Subscription Object from each Subscription Template Attributes Group
+ in the request, even if the newly created Subscription Object would
+ have identical behavior to some existing Subscription Object. The
+ Printer MUST associate each newly created Per-Job Subscription Object
+ with the target Job, which is specified by the "notify-job-id"
+ operation attribute.
+
+ The Printer MUST accept the request in any of the target job's 'not-
+ completed' states, i.e., 'pending', 'pending-held', 'processing', or
+ 'processing-stopped'. The Printer MUST NOT change the job's "job-
+ state" attribute because of this operation. If the target job is in
+ any of the 'completed' states, i.e., 'completed', 'canceled', or
+ 'aborted, then the Printer MUST reject the request and return the
+ 'client-error-not-possible' status code; the response MUST NOT
+ contain any Subscription Attribute Groups.
+
+ Access Rights: To create Per-Job Subscription Objects, the
+ authenticated user (see [RFC2911] section 8.3) performing this
+ operation MUST either be the job owner or have Operator or
+ Administrator access rights for this Printer (see [RFC2911] sections
+ 1 and 8.5). Otherwise the Printer MUST reject the operation and
+ return: the 'client-error-forbidden', 'client-error-not-
+ authenticated', or 'client-error-not-authorized' status code as
+ appropriate.
+
+11.1.1.1 Create-Job-Subscriptions Request
+
+ The following groups of attributes are part of the Create-Job-
+ Subscriptions Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.1.
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 54]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Target:
+ The "printer-uri" attribute which defines the target for this
+ operation as described in [RFC2911] section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" attribute SHOULD be supplied by the
+ client as described in [RFC2911] section 8.3.
+
+ notify-job-id (integer(1:MAX)):
+ The client MUST supply this attribute and it MUST specify the
+ Job object to associate the Per-Job Subscription with. The
+ value of "notify-job-id" MUST be the value of the "job-id" of
+ the associated Job object. If the client does not supply this
+ attribute, the Printer MUST reject this request with a 'client-
+ error-bad-request' status code.
+
+ Group 2-N: Subscription Template Attributes
+
+ For each occurrence of this group:
+
+ The client MUST supply one or more Subscription Template
+ Attributes in any order. See section 5.3 for a description of
+ each such attribute. See section 5.2 for details on processing
+ these attributes.
+
+11.1.1.2 Create-Job-Subscriptions Response
+
+ The Printer MUST return to the client the following sets of
+ attributes as part of a Create-Job-Subscriptions response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) and/or a "detailed-status-message" (text(MAX))
+ operation attribute as described in [RFC2911] sections 13 and
+ 31.6.
+
+ In this group, the Printer can return any status codes defined
+ in [RFC2911] and section 16. The following is a description of
+ the important status codes:
+
+ successful-ok: the Printer created all Subscription Objects
+ requested.
+ successful-ok-ignored-subscriptions: the Printer created some
+ Subscription Objects requested but some failed. The
+ Subscription Attributes Groups with a "notify-status-code"
+ attribute are the ones that failed.
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 55]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ client-error-ignored-all-subscriptions: the Printer created no
+ Subscription Objects requested and all failed. The
+ Subscription Attributes Groups with a "notify-status-code"
+ attribute are the ones that failed
+ client-error-not-possible: For this operation and other Per-Job
+ Subscription operations, this error can occur because the
+ specified Job has already completed.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ See [RFC2911] section 3.1.7 for details on returning
+ Unsupported Attributes. This group does not contain any
+ unsupported Subscription Template Attributes; they are returned
+ in the Subscription Attributes Group (see below).
+
+ Group 3-N: Subscription Attributes
+
+ These groups MUST be returned unless the Printer is unable to
+ interpret the entire request, e.g., the "status-code" parameter
+ returned in Group 1 has the value: 'client-error-bad-request'.
+
+ "notify-status-code" (type2 enum):
+ Indicates the status of this subscription (see section 17 for
+ the status code definitions). Section 5.2 defines when this
+ attribute MUST be present in this group.
+
+ See section 5.2 for details on the contents of each occurrence
+ of this group.
+
+11.1.2 Create-Printer-Subscriptions operation
+
+ The operation is identical to Create-Job-Subscriptions with
+ exceptions noted in this section.
+
+ The operation creates Per-Printer Subscription Objects instead of
+ Per-Job Subscription Objects, and associates each newly created Per-
+ Printer Subscription Object with the Printer specified by the
+ operation target rather than with a specific Job.
+
+ The Printer MUST accept the request in any of its states, i.e.,
+ 'idle', 'processing', or 'stopped'. The Printer MUST NOT change its
+ "printer-state" attribute because of this operation.
+
+ Access Rights: To create Per-Printer Subscription Objects, the
+ authenticated user (see [RFC2911] section 8.3) performing this
+ operation MUST have Operator or Administrator access rights for this
+
+
+Herriot, et al. Expires July 24, 2001 [page 56]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Printer (see [RFC2911] sections 1 and 8.5). Otherwise, the Printer
+ MUST reject the operation and return: the 'client-error-forbidden',
+ 'client-error-not-authenticated', or 'client-error-not-authorized'
+ status code as appropriate.
+
+11.1.2.1 Create-Printer-Subscriptions Request
+
+ The groups are identical to the Create-Job-Subscriptions (see section
+ 11.1.1.1) except that the Operation Attributes group MUST NOT contain
+ the "notify-job-id" attribute. If the client does supply the
+ "notify-job-id" attribute, then the Printer MUST treat it as any
+ other unsupported Operation attribute and MUST return it in the
+ Unsupported Attributes group.
+
+11.1.2.2 Create-Printer-Subscriptions Response
+
+ The groups are identical to the Create-Job-Subscriptions (see section
+ 11.1.1.2).
+
+
+11.1.3 Job Creation Operation - Extensions for Notification
+
+ This document extends the Job Creation operations to create
+ Subscription Objects as a part of the operation.
+
+ The operation is identical to Create-Job-Subscriptions with
+ exceptions noted in this section.
+
+ Unlike the Create-Job-Subscriptions operation, this operation
+ associates the newly created Subscription Objects with the Job object
+ created by this operation. The operation succeeds if and only if the
+ Job creation succeeds. If the Printer does not create some or all of
+ the requested Subscription Objects, the Printer MUST return a
+ 'successful-ok-ignored-subscriptions' status-code instead of a
+ 'successful-ok' status-code, but the Printer MUST NOT reject the
+ operation because of a failure to create Subscription Objects.
+
+ If the operation includes a Job Template group, the client MUST
+ supply it after the Operation Attributes group and before the first
+ Subscription Template Attributes Group.
+
+ If a Printer does not support this Notification specification, then
+ it MUST treat the Subscription Attributes Group like an unknown group
+ and ignore it (see [RFC2911] section 5.2.2). Because the Printer
+ ignores the Subscription Attributes Group, it doesn't return them in
+ the response either, thus indicating to the client that the Printer
+ doesn't support Notification.
+
+ Access Rights: To create Per-Job Subscription Objects, the
+ authenticated user (see [RFC2911] section 8.3) performing this
+
+
+Herriot, et al. Expires July 24, 2001 [page 57]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ operation MUST either have permission to create Jobs on the Printer.
+ Otherwise the Printer MUST reject the operation and return: the
+ 'client-error-forbidden', 'client-error-not-authenticated', or
+ 'client-error-not-authorized' status code as appropriate.
+
+11.1.3.1 Job Creation Request
+
+ The groups for this operation are sufficiently different from the
+ Create-Job-Subscriptions operation that they are all presented here.
+ The following groups of attributes are supplied as part of a Job
+ Creation Request:
+
+ Group 1: Operation Attributes
+
+ Same as defined in [RFC2911] for Print-Job, Print-URI, and
+ Create-Job requests.
+ Group 2: Job Template Attributes
+
+ The client OPTIONALLY supplies a set of Job Template attributes
+ as defined in [RFC2911] section 4.2.
+ Group 3 to N: Subscription Template Attributes
+
+ The same as Group 2-N in Create-Job-Subscriptions. See section
+ 11.1.1.1.
+ Group N+1: Document Content (Print-Job only)
+
+ The client MUST supply the document data to be processed.
+
+11.1.3.2 Job Creation Response
+
+ The Printer MUST return to the client the following sets of
+ attributes as part of a Print-Job, Print-URI, and Create-Job
+ Response:
+
+ Group 1: Operation Attributes
+
+
+ Status Message:
+
+ As defined in [RFC2911] for Print-Job, Print-URI, and Create-
+ Job requests.
+
+ In this group, the Printer can return any status codes defined
+ in [RFC2911] and section 16. The following is a description of
+ the important status codes:
+
+ successful-ok: the Printer created the Job and all Subscription
+ Objects requested.
+ successful-ok-ignored-subscriptions: the Printer created the Job
+ and not all of the Subscription Objects requested. This
+
+
+Herriot, et al. Expires July 24, 2001 [page 58]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ status-code hides 'successful-ok-xxx' status-codes that could
+ reveal problems in Job creation. The Printer MUST not return
+ the 'client-error-ignored-all-subscriptions' status code for
+ Job Creation operations because the Printer returns an error
+ status-code only when it fails to create a Job.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ See [RFC2911] section 3.1.7 for details on returning
+ Unsupported Attributes. This group does not contain any
+ unsupported Subscription Template Attributes; they are returned
+ in the Subscription Attributes Group (see below).
+
+ Group 3: Job Object Attributes
+
+ As defined in [RFC2911] for Print-Job, Print-URI, and Create-
+ Job requests.
+
+ Group 4 to N: Subscription Attributes
+
+ These groups MUST be returned if and only if the client
+ supplied Subscription Template Attributes and the operation was
+ accepted.
+
+ See section 5.2 for details on the contents of each occurrence
+ of this group.
+
+11.2 Other Operations
+
+ This section defines other operations on Subscription objects.
+
+11.2.1 Validate-Job Operation - Extensions for Notification
+
+ A client can test whether one or more Subscription Objects could be
+ created using the Validate-Job operation. The client supplies one or
+ more Subscription Template Attributes Groups (defined in section
+ 5.3), just as in a Job Creation request.
+
+ A Printer MUST support this extension to this operation.
+
+ The Printer MUST accept requests that are identical to the Job
+ Creation request defined in section 11.1.3.1, except that the request
+ MUST not contain document data.
+
+ The Printer MUST return the same groups and attributes as the Print-
+ Job operation (section 11.1.3.1) with the following exceptions. The
+
+
+Herriot, et al. Expires July 24, 2001 [page 59]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Printer MUST NOT return a Job Object Attributes Group because no Job
+ is created. The Printer MUST NOT return the "notify-subscription-id"
+ attribute in any Subscription Attribute Group because no Subscription
+ Object is created.
+
+ If the Printer would succeed in creating a Subscription Object, the
+ corresponding Subscription Attributes Group either has no 'status-
+ code' attribute or a 'status-code' attribute with a value of
+ 'successful-ok-too-many-events' or 'successful-ok-ignored-or-
+ substituted-attributes' (see sections 5.2 and 17). The status-codes
+ have the same meaning as in Job Creation except the results state
+ what "would happen".
+
+ The Printer MUST validate Subscription Template Attributes Groups in
+ the same manner as the Job Creation operations.
+
+11.2.2 Get-Printer-Attributes - Extensions for Notification
+
+ This operation is extended so that it returns Printer attributes
+ defined in this document.
+
+ A Printer MUST support this extension to this operation.
+
+ In addition to the requirements of [RFC2911] section 3.2.5, a Printer
+ MUST support the following additional values for the "requested-
+ attributes" Operation attribute in this operation and return such
+ attributes in the Printer Object Attributes group of its response.
+
+ 1.Subscription Template Attributes: Each supported attribute in
+ column 2 of Table 1.
+
+ 2.New Printer Description Attributes: Each supported attribute in
+ section 6.
+
+ 3.New Group Name: The 'subscription-template' group name, which
+ names all supported Subscription Template Attribute in column 2
+ of Table 1. This group name is also used in the Get-
+ Subscription-Attributes and Get-Subscriptions operation with an
+ analogous meaning.
+
+ 4.Extended Group Name: The 'all' group name, which names all
+ Printer attributes according to [RFC2911] section 3.2.5. In
+ this extension 'all' names all attributes specified in [RFC2911]
+ plus those named in items 1 and 2 of this list.
+
+11.2.3 Get-Subscription-Attributes operation
+
+ This operation allows a client to request the values of the
+ attributes of a Subscription Object.
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 60]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ A Printer MUST support this operation.
+
+ This operation is almost identical to the Get-Job-Attributes
+ operation (see [RFC2911] section 3.3.4). The only differences are
+ that the operation is directed at a Subscription Object rather than a
+ Job object, and the returned attribute group contains Subscription
+ Object attributes rather than Job object attributes.
+
+11.2.3.1 Get-Subscription-Attributes Request
+
+ The following groups of attributes are part of the Get-Subscription-
+ Attributes request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section [RFC2911] 3.1.4.1.
+
+ Target:
+ The "printer-uri" attribute which defines the target for this
+ operation as described in [RFC2911] section 3.1.5.
+
+ "notify-subscription-id" (integer (1:MAX)):
+ The client MUST supply this attribute. The Printer MUST
+ support this attribute. This attribute specifies the
+ Subscription Object from which the client is requesting
+ attributes. If the client omits this attribute, the Printer
+ MUST reject this request with the 'client-error-bad-request'
+ status code.
+
+ Requesting User Name:
+ The "requesting-user-name" attribute SHOULD be supplied by the
+ client as described in [RFC2911] section 8.3.
+
+ "requested-attributes" (1setOf keyword):
+ The client OPTIONALLY supplies this attribute. The Printer
+ MUST support this attribute. This attribute specifies the
+ attributes of the specified Subscription Object that the
+ Printer MUST return in the response. Each value of this
+ attribute is either an attribute name (defined in sections 5.3
+ and 5.4) or an attribute group name. The attribute group names
+ are:
+
+ - 'subscription-template': all attributes that are both defined
+ in section 5.3 and present on the specified Subscription
+ Object (column 1 of Table 1).
+ - 'subscription-description': all attributes that are both
+ defined in section 5.4 and present on the specified
+ Subscription Object (Table 2).
+
+
+Herriot, et al. Expires July 24, 2001 [page 61]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ - 'all': all attributes that are present on the specified
+ Subscription Object.
+ A Printer MUST support all these group names.
+
+ If the client omits this attribute, the Printer MUST respond as
+ if this attribute had been supplied with a value of 'all'.
+
+11.2.3.2 Get-Subscription-Attributes Response
+
+ The Printer returns the following sets of attributes as part of the
+ Get-Subscription-Attributes Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ Same as [RFC2911].
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.2. The
+ "attributes-natural-language" MAY be the natural language of
+ the Subscription Object, rather than the one requested.
+
+ Group 2: Unsupported Attributes
+
+ See [RFC2911] section 3.1.7 for details on returning
+ Unsupported Attributes.
+
+ The response NEED NOT contain the "requested-attributes"
+ operation attribute with any supplied values (attribute
+ keywords) that were requested by the client but are not
+ supported by the Printer. If the Printer does return
+ unsupported attributes referenced in the "requested-attributes"
+ operation attribute and that attribute included group names,
+ such as 'all', the unsupported attributes MUST NOT include
+ attributes described in the standard but not supported by the
+ implementation.
+
+ Group 3: Subscription Attributes
+
+ This group contains a set of attributes with their current
+ values. Each attribute in this group:
+
+ a)MUST be specified by the "requested-attributes" attribute
+ in the request, AND
+
+ b)MUST be present on the specified Subscription Object AND
+
+ c)MUST NOT be restricted by the security policy in force.
+ For example, a Printer MAY prohibit a client who is not the
+
+
+Herriot, et al. Expires July 24, 2001 [page 62]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ creator of a Subscription Object from seeing some or all of
+ its attributes. See [RFC2911] section 8.
+
+ The Printer can return the attributes of the Subscription
+ Object in any order. The client MUST accept the attributes in
+ any order.
+
+11.2.4 Get-Subscriptions operation
+
+ This operation allows a client to retrieve the values of attributes
+ of all Subscription Objects belonging to a Job or Printer.
+
+ A Printer MUST supported this operation.
+
+ This operation is similar to the Get-Subscription-Attributes
+ operation, except that this Get-Subscriptions operation returns
+ attributes from possibly more than one object.
+
+ This operation is similar to the Get-Jobs operation (see [RFC2911]
+ section 3.2.6), except that the operation returns Subscription
+ Objects rather than Job objects.
+
+11.2.4.1 Get-Subscriptions Request
+
+ The following groups of attributes are part of the Get-Subscriptions
+ request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.1.
+
+ Target:
+ The "printer-uri" attribute which defines the target for this
+ operation as described in [RFC2911] section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" attribute SHOULD be supplied by the
+ client as described in [RFC2911] section 8.3.
+
+ "notify-job-id" (integer(1:MAX)):
+ If the client specifies this attribute, the Printer returns the
+ specified attributes of all Per-Job Subscription Objects
+ associated with the Job whose "job-id" attribute value equals
+ the value of this attribute. If the client does not specify
+ this attribute, the Printer returns the specified attributes of
+ all Per-Printer Subscription Objects. Note: there is no way to
+ get all Per-Job Subscriptions.
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 63]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ "limit" (integer(1:MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ MUST support this attribute. It is an integer value that
+ determines the maximum number of Subscription Objects that a
+ client will receive from the Printer even if the "my-
+ subscriptions" attribute constrains which Subscription Objects
+ are returned. The limit is a "stateless limit" in that if the
+ value supplied by the client is 'N', then only the first 'N'
+ Subscription Objects are returned in the Get-Subscriptions
+ Response. There is no mechanism to allow for the next 'M'
+ Subscription Objects after the first 'N' Subscription Objects.
+ If the client does not supply this attribute, the Printer
+ responds with all applicable Subscription Objects.
+
+ "requested-attributes" (1setOf type2 keyword):
+ The client OPTIONALLY supplies this attribute. The Printer
+ MUST support this attribute. This attribute specifies the
+ attributes of the specified Subscription Objects that the
+ Printer MUST return in the response. Each value of this
+ attribute is either an attribute name (defined in sections 5.3
+ and 5.4) or an attribute group name (defined in section
+ 11.2.3.1). If the client omits this attribute, the Printer MUST
+ respond as if the client had supplied this attribute with the
+ one value: 'notify-subscription-id'.
+
+ "my-subscriptions" (boolean):
+ The client OPTIONALLY supplies this attribute. The Printer
+ MUST support this attribute. If the value is 'false', the
+ Printer MUST consider the Subscription Objects from all users
+ as candidates. If the value is 'true', the Printer MUST return
+ the Subscription Objects created by the requesting user of this
+ request. If the client does not supply this attribute, the
+ Printer MUST respond as if the client had supplied the
+ attribute with a value of 'false'. The means for
+ authenticating the requesting user and matching the
+ Subscription Objects is similar to that for Jobs which is
+ described in [RFC2911] section 8.
+
+11.2.4.2 Get-Subscriptions Response
+
+ The Printer returns the following sets of attributes as part of the
+ Get-Subscriptions Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ Same as [RFC2911].
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 64]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ Same as for Get-Subscription-Attributes.
+
+ Groups 3 to N: Subscription Attributes
+
+ The Printer responds with one Subscription Attributes Group for
+ each requested Subscription Object (see the "notify-job-id"
+ attribute in the Operation Attributes Group of this operation).
+
+ The Printer returns Subscription Objects in any order.
+
+ If the "limit" attribute is present in the Operation Attributes
+ group of the request, the number of Subscription Attributes
+ Groups in the response MUST NOT exceed the value of the "limit"
+ attribute.
+
+ It there are no Subscription Objects associated with the
+ specified Job or Printer, the Printer MUST return zero
+ Subscription Attributes Groups and it MUST NOT treat this case
+ as an error, i.e., the status-code MUST be 'successful-ok'
+ unless something else causes the status code to have some other
+ value.
+
+ See the Group 3 response (Subscription Attributes Group) of the
+ Get-Subscription-Attributes operation (section 11.2.3.2) for
+ the attributes that a Printer returns in this group.
+
+11.2.5 Renew-Subscription operation
+
+ This operation allows a client to request the Printer to extend the
+ lease on a Per-Printer Subscription Object.
+
+ The Printer MUST support this operation.
+
+ The Printer MUST accept this request for a Per-Printer Subscription
+ Object in any of the target Printer's states, i.e., 'idle',
+ 'processing', or 'stopped', but MUST NOT change the Printer's
+ "printer-state" attribute.
+
+ The Printer MUST reject this request for a Per-Job Subscription
+ Object because it has no lease (see section 5.4.3). The status code
+ returned MUST be 'client-error-not-possible'.
+
+ Access Rights: The authenticated user (see [RFC2911] section 8.3)
+ performing this operation MUST either be the owner of the Per-Printer
+
+
+Herriot, et al. Expires July 24, 2001 [page 65]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Subscription Object or have Operator or Administrator access rights
+ for the Printer (see [RFC2911] sections 1 and 8.5). Otherwise, the
+ Printer MUST reject the operation and return: the 'client-error-
+ forbidden', 'client-error-not-authenticated', or 'client-error-not-
+ authorized' status code as appropriate.
+
+11.2.5.1 Renew-Subscription Request
+
+ The following groups of attributes are part of the Renew-Subscription
+ Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.1.
+
+ Target:
+ The "printer-uri" attribute which defines the target for this
+ operation as described in [RFC2911] section 3.1.5.
+
+ "notify-subscription-id" (integer (1:MAX)):
+ The client MUST supply this attribute. The Printer MUST
+ support this attribute. This attribute specifies the Per-
+ Printer Subscription Object whose lease the Printer MUST renew.
+ If the client omits this attribute, the Printer MUST reject
+ this request with the 'client-error-bad-request' status code.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in [RFC2911] section 8.3.
+
+ Group 2: Subscription Template Attributes
+
+
+ "notify-lease-duration" (integer(0:MAX)):
+ The client MAY supply this attribute. It indicates the number
+ of seconds to renew the lease for the specified Subscription
+ Object. A value of 0 requests an infinite lease (which MAY
+ require Operator access rights). If the client omits this
+ attribute, the Printer MUST use the value of the Printer's
+ "notify-lease-duration-default" attribute. See section 5.3.7
+ for more details.
+
+11.2.5.2 Renew-Subscription Response
+
+ The Printer returns the following sets of attributes as part of the
+ Renew-Subscription Response:
+
+ Group 1: Operation Attributes
+
+
+Herriot, et al. Expires July 24, 2001 [page 66]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Status Message:
+ Same as [RFC2911].
+
+ The following are some of the status codes returned:
+
+ successful-ok: The operation successfully renewed the lease on the
+ Subscription Object for the requested duration..
+ successful-ok-ignored-or-substituted-attributes: The operation
+ successfully renewed the lease on the Subscription Object for
+ some duration other than the amount requested.
+ client-error-not-possible: The operation failed because the
+ "notify-subscription-id" Operation attribute identified a Per-
+ Job Subscription Object.
+ client-error-not-found: The operation failed because the "notify-
+ subscription-id" Operation attribute identified a non-existent
+ Subscription Object.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.2. The
+ "attributes-natural-language" MAY be the natural language of
+ the Subscription Object, rather than the one requested.
+
+ Group 2: Unsupported Attributes
+
+ See [RFC2911] section 3.1.7 for details on returning
+ Unsupported Attributes.
+
+ Group 3: Subscription Attributes
+
+ The Printer MUST return the following Subscription Attribute:
+
+ "notify-lease-duration" (integer(0:MAX)):
+ The value of this attribute MUST be the number of seconds that
+ the Printer has granted for the lease of the Subscription
+ Object (see section 5.3.7 for details, such as the value of
+ this attribute when the Printer doesn't support the requested
+ value).
+
+
+
+11.2.6 Cancel-Subscription operation
+
+ This operation allows a client to delete a Subscription Object and
+ stop the Printer from sending more Event Notifications. Once
+ performed, there is no way to reference the Subscription Object.
+
+ A Printer MUST supported this operation.
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 67]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ The Printer MUST accept this request in any of the target Printer's
+ states, i.e., 'idle', 'processing', or 'stopped', but MUST NOT change
+ the Printer's "printer-state" attribute.
+
+ If the specified Subscription Object is a Per-Job Subscription
+ Object, the Printer MUST accept this request in any of the target
+ Job's states, but MUST NOT change the Job's "job-state" attribute or
+ affect the Job.
+
+ Access Rights: The authenticated user (see [RFC2911] section 8.3)
+ performing this operation MUST either be the owner of the
+ Subscription Object or have Operator or Administrator access rights
+ for the Printer (see [RFC2911] sections 1 and 8.5). Otherwise, the
+ Printer MUST reject the operation and return: the 'client-error-
+ forbidden', 'client-error-not-authenticated', or 'client-error-not-
+ authorized' status code as appropriate.
+
+ Note: There is no way to change any attributes on a Subscription
+ Object, except the "notify-lease-duration" attribute (using the
+ Renew-Subscription operation). In order to change other attributes,
+ a client performs a Subscription Creation Operation and Cancel-
+ Subscription operation on the old Subscription Object. If the client
+ wants to avoid missing Event Notifications, it performs the
+ Subscription Creation Operation first. If this order would create too
+ many Subscription Objects on the Printer, the client reverses the
+ order.
+
+11.2.6.1 Cancel-Subscription Request
+
+ The following groups of attributes are part of the Cancel-
+ Subscription Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.1.
+
+ Target:
+ The "printer-uri" attribute which defines the target for this
+ operation as described in [RFC2911] section 3.1.5.
+
+ "notify-subscription-id" (integer (1:MAX)):
+ The client MUST supply this attribute. The Printer MUST
+ support this attribute. This attribute specifies the
+ Subscription Object that the Printer MUST cancel. If the client
+ omits this attribute, the Printer MUST reject this request with
+ the 'client-error-bad-request' status code.
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 68]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Requesting User Name:
+ The "requesting-user-name" attribute SHOULD be supplied by the
+ client as described in [RFC2911] section 8.3.
+
+11.2.6.2 Cancel-Subscription Response
+
+ The Printer returns the following sets of attributes as part of the
+ Cancel-Subscription Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ Same as [RFC2911].
+
+ The following are some of the status codes returned:
+
+ successful-ok: The operation successfully canceled (deleted) the
+ Subscription Object..
+ client-error-not-found: The operation failed because the "notify-
+ subscription-id" Operation attribute identified a non-existent
+ Subscription Object.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.2. The
+ "attributes-natural-language" MAY be the natural language of
+ the Subscription Object, rather than the one requested.
+
+ Group 2: Unsupported Attributes
+
+ See [RFC2911] section 3.1.7 for details on returning
+ Unsupported Attributes.
+
+
+12 Conformance Requirements
+
+ It is OPTIONAL to implement this Event Notification specification.
+
+ If this Event Notification specification is implemented, Printers
+ MUST:
+
+ 1.meet the Conformance Requirements detailed in section 5 of
+ [RFC2911].
+
+ 2.support the Subscription Template Attributes Group in requests
+ and the Subscription Attributes Group in responses.
+
+ 3.support all of the following attributes:
+
+ a. REQUIRED Subscription Object attributes in section 5.
+
+
+Herriot, et al. Expires July 24, 2001 [page 69]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ b. REQUIRED Printer Description object attributes in section 6.
+ c. REQUIRED attributes in Event Notification content in section
+ 8.
+
+ 4.send Event Notifications that conform to the requirements of the
+ Delivery Method Document for each supported Delivery Method (the
+ conformance requirements for Delivery Method Documents is
+ specified in section 10).
+
+ 5.support all operations as described in Table 16:
+
+
+ Table 16 - Conformance Requirements for Operations
+
+
+
+ Operation Conformance
+ requirements
+
+
+ Create-Printer-Subscriptions (section 11.1.2) REQUIRED
+
+ Create-Job-Subscriptions (section 11.1.1) OPTIONAL
+
+ Get-Subscription-Attributes (section 11.2.2) REQUIRED
+
+ Get-Subscriptions (section 11.2.4) REQUIRED
+
+ Renew-Subscription (section 11.2.5) REQUIRED
+
+ Cancel-Subscription (section 11.2.6) REQUIRED
+
+
+
+13 IANA Considerations
+
+ This section contains the exact information for IANA to add to the
+ IPP Registries according to the procedures defined in RFC 2911
+ [RFC2911] section 6.
+
+ Note to RFC Editors: Replace RFC NNNN below with the RFC number
+ for this document, so that it accurately reflects the content of
+ the information for the IANA Registry.
+
+13.1 Attribute Registrations
+
+ The attributes defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.2 with
+ the following path:
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 70]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ ftp.isi.edu/iana/assignments/ipp/attributes/
+
+ The registry entry will contain the following information:
+
+ Subscription Template attributes: Ref. Section:
+ notify-recipient-uri (uri) RFC NNNN 5.3.1
+ notify-events (1setOf type2 keyword) RFC NNNN 5.3.2
+ notify-attributes (1setOf type2 keyword) RFC NNNN 5.3.3
+ notify-user-data (octetString(63)) RFC NNNN 5.3.4
+ notify-charset (charset) RFC NNNN 5.3.5
+ notify-natural-language (naturalLanguage) RFC NNNN 5.3.6
+ notify-lease-duration (integer(0:67108863)) RFC NNNN 5.3.7
+ notify-time-interval (integer(0:MAX)) RFC NNNN 5.3.8
+
+ Subscription Description Attributes:
+ notify-subscription-id (integer (1:MAX))) RFC NNNN 5.4.1
+ notify-sequence-number (integer (0:MAX))) RFC NNNN 5.4.2
+ notify-lease-expiration-time (integer(0:MAX))) RFC NNNN 5.4.3
+ notify-printer-up-time (integer(1:MAX))) RFC NNNN 5.4.4
+ notify-printer-uri (uri)) RFC NNNN 5.4.5
+ notify-job-id (integer(1:MAX))) RFC NNNN 5.4.6
+ notify-subscriber-user-name (name(MAX))) RFC NNNN 5.4.7
+
+ Printer Description Attributes:
+ printer-state-change-time (integer(1:MAX))) RFC NNNN 6.1
+ printer-state-change-date-time (dateTime)) RFC NNNN 6.2
+
+ Attributes Only in Event Notifications
+ notify-subscribed-event (type2 keyword) RFC NNNN 8.1
+ notify-text (text(MAX)) RFC NNNN 8.2
+
+13.2 Keyword Attribute Value Registrations
+
+ The keyword attribute values defined in this document will be
+ published by IANA according to the procedures in RFC 2911 [RFC2911]
+ section 6.1 with the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-values/
+
+ The registry entry will contain the following information:
+
+ Keyword Attribute Values: Ref. Section:
+ New Values for Existing Printer Description Attributes
+ operations-supported (1setOf type2 enum) RFC NNNN 7.1
+
+13.3 Operation Registrations
+
+ The operations defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.4 with
+ the following path:
+
+
+Herriot, et al. Expires July 24, 2001 [page 71]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ ftp.isi.edu/iana/assignments/ipp/operations/
+
+ The registry entry will contain the following information:
+
+ Operations: Ref. Section:
+ Create-Job-Subscriptions Operation RFC NNNN 11.1.1
+ Create-Printer-Subscriptions operation RFC NNNN 11.1.2
+ Job Creation Operations - Extensions RFC NNNN 11.1.3
+ Validate-Job Operation - Extensions RFC NNNN 11.2.1
+ Get-Printer-Attributes - Extensions RFC NNNN 11.2.2
+ Get-Subscription-Attributes operation RFC NNNN 11.2.3
+ Get-Subscriptions operation RFC NNNN 11.2.4
+ Renew-Subscription operation RFC NNNN 11.2.5
+ Cancel-Subscription operation RFC NNNN 11.2.6
+
+13.4 Status code Registrations
+
+ The status codes defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.6 with
+ the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/status-codes/
+
+ The registry entry will contain the following information:
+
+ Status codes: Ref. Section:
+ successful-ok-ignored-subscriptions (0x0003) RFC NNNN 16.1
+ client-error-ignored-all-subscriptions (0x0414) RFC NNNN 16.2
+
+ Status Codes in Subscription Attributes Groups:
+ client-error-uri-scheme-not-supported (0x040C) RFC NNNN 17.1
+ client-error-too-many-subscriptions (0x0415) RFC NNNN 17.2
+ successful-ok-too-many-events (0x0005) RFC NNNN 17.3
+ successful-ok-ignored-or-substituted-attributes (0x0001)
+ RFC NNNN 17.4
+
+13.5 Attribute Group tag Registrations
+
+ The attribute group tags defined in this document will be published
+ by IANA according to the procedures in RFC 2911 [RFC2911] section 6.5
+ with the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-group-tags/
+
+ The registry entry will contain the following information:
+
+ Attribute Group Tags: Ref. Section:
+ subscription-attributes-tag RFC NNNN 18
+ event-notification-attributes-tag RFC NNNN 18
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 72]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+13.6 Format for Event Notification Delivery Method Registration
+ proposals
+
+ This section describes the procedures for registering Event
+ Notification Delivery Method proposals with IANA to be used with this
+ document. Such Delivery Method proposals that require a new URL
+ scheme MUST be IETF standards track documents according to RFC 2717
+ [RFC2717].
+
+13.7 Format and Requirements for IPP Delivery Method Registration
+ Proposals
+
+ This section defines the format and requirements for an IPP Event
+ Notification Delivery Method Registration Proposal. A Delivery
+ Method Registration Proposal:
+
+ 1.MUST contain the following information:
+
+ Type of registration: IPP Event Notification Delivery Method
+ Name of this delivery method:
+ Proposed URL scheme name of this delivery method:
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+ Is this delivery method REQUIRED or OPTIONAL for conformance to
+ the IPP Event Notification Specification document:
+ Is this delivery method defining Machine Consumable and/or Human
+ Consumable content:
+
+ 2.MUST meet the conformance requirements for Delivery Method
+ Documents specified in section 10.
+
+
+14 Internationalization Considerations
+
+ This IPP Notification specification continues support for the
+ internationalization of [RFC2911] of attributes containing text
+ strings and names. Allowing a Subscribing Client to specify a
+ different natural language and charset for each Subscription Object
+ increases the internationalization support.
+
+ The Printer MUST be able to localize the content of Human Consumable
+ Event Notifications and to localize the value of "notify-text"
+ attribute in Machine Consumable Event Notifications that it sends to
+ Notification Recipients. For localization, the Printer MUST use the
+ value of the "notify-charset" attribute and the "notify-natural-
+ language" attribute in the Subscription Object supplied by the
+ Subscribing Client.
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 73]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+15 Security Considerations
+
+ By far the biggest security concern is the abuse of notification:
+ sending unwanted Event Notifications to third parties (i.e., spam).
+ The problem is made worse by notification addresses that may be
+ redistributed to multiple parties (e.g., mailing lists). There exist
+ scenarios where third party notification is required (see Scenario #2
+ and #3 in [ipp-not-req]). The fully secure solution would require
+ active agreement of all recipients before sending out anything.
+ However, requirement #9 in [ipp-req] ("There is no requirement for
+ IPP Printer receiving the print request to validate the identity of
+ an Event recipient") argues against this. Certain systems may decide
+ to disallow third party Event Notifications (a traditional fax
+ model).
+
+ Clients submitting Notification requests to the IPP Printer has the
+ same security issues as submitting an IPP/1.1 print job request. The
+ same mechanisms used by IPP/1.1 can therefore be used by the client
+ Notification submission. Operations that require authentication can
+ use the HTTP authentication. Operations that require privacy can use
+ the HTTP/TLS privacy.
+
+ The Notification access control model should be similar to the IPP
+ access control model for Jobs. Creating a Per-Printer Subscription
+ Object is associated with a user. Only the creator or an Operator
+ can cancel the Subscription Object. The system may limit the listing
+ of items to only those items owned by the user. Some Subscription
+ Objects (e.g., those that have a lifetime longer than a job) can be
+ done only by privileged users (users having Operator and/or
+ Administrator access rights), if that is the authorization policy.
+
+ The standard security concerns (delivery to the right user, privacy
+ of content, tamper proof content) apply to the Delivery Method. IPP
+ should use the security mechanism of the Delivery Method used. Some
+ delivery mechanisms are more secure than others. Therefore,
+ sensitive Event Notifications should use the Delivery Method that has
+ the strongest security.
+
+
+16 Status Codes
+
+ The following status codes are defined as extensions for Notification
+ and are returned as the value of the "status-code" parameter in the
+ Operation Attributes Group of a response (see [RFC2911] section
+ 3.1.6.1). Operations in this document can also return the status
+ codes defined in section 13 of [RFC2911]. The 'successful-ok' status
+ code is an example of such a status code.
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 74]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+16.1 successful-ok-ignored-subscriptions (0x0003)
+
+ The Subscription Creation Operation was unable to create all
+ requested Subscription Objects.
+
+ For a Create-Job-Subscriptions or Create-Printer-Subscriptions
+ operation, this status code means that the Printer created one or
+ more Subscription Objects, but not all requested Subscription
+ Objects.
+
+ For a Job Creation operation, this status code means that the Printer
+ created the Job along with zero or more Subscription Objects. The
+ Printer returns this status code even if other job attributes are
+ unsupported or in conflict. That is, if an IPP Printer finds a
+ warning that would allow it to return 'successful-ok-ignored-
+ subscriptions' and either 'successful-ok-ignored-or-substituted-
+ attributes' and/or 'successful-ok-conflicting-attributes', it MUST
+ return 'successful-ok-ignored-subscriptions'.
+
+16.2 client-error-ignored-all-subscriptions (0x0414)
+
+ This status code is the same as 'successful-ok-ignored-subscriptions'
+ except that only the Create-Job-Subscriptions and Create-Printer-
+ Subscriptions operation return it. They return this status code only
+ when the Printer creates zero Subscription Objects.
+
+
+17 Status Codes in Subscription Attributes Groups
+
+ This section contains values of the "notify-status-code" (type2 enum)
+ attribute that the Printer returns in a Subscription Attributes Group
+ in a response when the corresponding Subscription Object:
+
+ 1.is not created or
+
+ 2.is created and some of the client-supplied attributes are not
+ supported.
+
+ The following sections are ordered in decreasing order of importance
+ of the status-codes.
+
+17.1 client-error-uri-scheme-not-supported (0x040C)
+
+ This status code is defined in [RFC2911]. This document extends its
+ meaning and allows it to be in a Subscription Attributes Group of a
+ response.
+
+ The scheme of the client-supplied URI in a "notify-recipient-uri"
+ Subscription Template Attribute in a Subscription Creation Operation
+ is not supported. See section 0.
+
+
+Herriot, et al. Expires July 24, 2001 [page 75]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+17.2 client-error-too-many-subscriptions (0x0415)
+
+ The number of Subscription Objects supported by the Printer would be
+ exceeded if this Subscription Object were created (see section 5.2).
+
+17.3 successful-ok-too-many-events (0x0005)
+
+ The client supplied more Events in the "notify-events" operation
+ attribute of a Subscription Creation Operation than the Printer
+ supports, as indicated in its "notify-max-events-supported" Printer
+ attribute (see section 5.3.2).
+
+17.4 successful-ok-ignored-or-substituted-attributes (0x0001)
+
+ This status code is defined in [RFC2911]. This document extends its
+ meaning to include unsupported Subscription Template Attributes and
+ it can appear in a Subscription Attributes Group.
+
+
+18 Encodings of Additional Attribute Tags
+
+ This section assigns values to two attributes tags as extensions to
+ the encoding defined in [RFC2910]).
+
+ The "subscription-attributes-tag" delimits Subscription Template
+ Attributes Groups in requests and Subscription Attributes Groups in
+ responses.
+
+ The "event-notification-attributes-tag" delimits Event Notifications
+ in Delivery Methods that use an IPP-like encoding.
+
+ The following table specifies the values for the delimiter tags:
+
+
+
+ Tag Value (Hex) Meaning
+
+
+ 0x06 "subscription-attributes-tag"
+
+ 0x07 "event-notification-attributes-tag"
+
+
+19 References
+
+ [IANA-CON]
+ Narte, T. and Alvestrand, H.T.: Guidelines for Writing an IANA
+ Considerations Section in RFCs, Work in Progress, draft-iesg-iana-
+ considerations-04.txt, May 21, 1998.
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 76]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ [ipp-not-req]
+ deBry, R., Lewis, H., Hastings, T., "Internet Printing
+ Protocol/1.1: Requirements for IPP Notifications", <draft-ietf-ipp-
+ not-05.txt>, work in progress, January 23, 2001.
+
+ [ipp-prog]
+ Hastings, T., Bergman, R., Lewis, H., "IPP: Job Progress
+ Attributes", <draft-ietf-ipp-job-prog-03.txt> work in
+ progress, January 23, 2001.
+
+ [ipp-set]
+ Kugler, C., Hastings, T., Herriot, R., Lewis, H, "Internet Printing
+ Protocol (IPP): Job and Printer Set Operations", <draft-ietf-ipp-
+ job-printer-set-ops-03.txt>, work in progress, January 22, 2001.
+
+ [RFC2026]
+ S. Bradner, "The Internet Standards Process -- Revision 3", RFC
+ 2026, October 1996.
+
+ [RFC2119]
+ S. Bradner, "Key words for use in RFCs to Indicate Requirement
+ Levels", RFC 2119 , March 1997
+
+ [RFC2566]
+ deBry, R., , Hastings, T., Herriot, R., Isaacson, S., Powell, P.,
+ "Internet Printing Protocol/1.0: Model and Semantics", RFC 2566,
+ April 1999.
+
+ [RFC2567]
+ Wright, D., "Design Goals for an Internet Printing Protocol", RFC
+ 2567, April 1999.
+
+ [RFC2568]
+ Zilles, S., "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", RFC 2568, April 1999.
+
+ [RFC2569]
+ Herriot, R., Hastings, T., Jacobs, N., Martin, J., "Mapping between
+ LPD and IPP Protocols", RFC 2569, April 1999.
+
+ [RFC2717]
+ R. Petke and I. King, "Registration Procedures for URL Scheme
+ Names", RFC 2717, November 1999.
+
+ [RFC2910]
+ Herriot, R., Butler, S., Moore, P., Turner, R., "Internet Printing
+ Protocol/1.1: Encoding and Transport", RFC 2910, September 2000.
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 77]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ [RFC2911]
+ deBry, R., , Hastings, T., Herriot, R., Isaacson, S., Powell, P.,
+ "Internet Printing Protocol/1.1: Model and Semantics", RFC 2911,
+ September 2000.
+
+
+20 Author's Addresses
+
+ Robert Herriot
+ Xerox Corporation
+ 3400 Hillview Ave., Bldg #1
+ Palo Alto, CA 94304
+
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ Email: robert.herriot@pahv.xerox.com
+
+ Tom Hastings
+ Xerox Corporation
+ 737 Hawaii St. ESAE 231
+ El Segundo, CA 90245
+
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ e-mail: hastings@cp10.es.xerox.com
+
+
+ Scott A. Isaacson
+ Novell, Inc.
+ 122 E 1700 S
+ Provo, UT 84606
+
+ Phone: 801-861-7366
+ Fax: 801-861-2517
+ e-mail: sisaacson@novell.com
+
+
+ Roger deBry
+ Utah Valley State College
+ Orem, UT 84058
+
+ Phone: (801) 222-8000
+ EMail: debryro@uvsc.edu
+
+ Jay Martin
+ Underscore Inc.
+ 9 Jacqueline St.
+ Hudson, NH 03051-5308
+ 603-889-7000
+ fax: 775-414-0245
+
+
+Herriot, et al. Expires July 24, 2001 [page 78]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ e-mail: jkm@underscore.com
+
+
+ Michael Shepherd
+ Xerox Corporation
+ 800 Phillips Road MS 128-51E
+ Webster, NY 14450
+
+ Phone: 716-422-2338
+ Fax: 716-265-8871
+ e-mail: mshepherd@crt.xerox.com
+
+
+ Ron Bergman
+ Hitachi Koki Imaging Solutions
+ 1757 Tapo Canyon Road
+ Simi Valley, CA 93063-3394
+
+ Phone: 805-578-4421
+ Fax: 805-578-4001
+ Email: rbergma@hitachi-hkis.com
+
+A. Appendix - Model for Notification with Cascading Printers
+
+ With this model (see Figure 2), there is an intervening Print server
+ between the human user and the output-device. So the system
+ effectively has two Printers. There are two cases to consider.
+
+ 1.When the Printer 1 (in the server) generates Events, the system
+ behaves like the client and Printer in Figure 1. In this case,
+ Printer 1 sends Event Notifications that are shown as Event
+ Notifications (A) of Figure 2,.
+
+ 2.When the Printer 2 (in the output-device) generates Events, there
+ are two possible system configurations:
+
+ a)Printer 1 forwards the client-supplied Subscription Creation
+ Operations to the downstream Printer 2 and lets Printer 2 send
+ the Event Notifications directly to the Notification Recipients
+ supplied by the Client (Event Notifications(C) in the diagram).
+
+ b)Printer 1 performs the client-supplied Subscription Creation
+ Operations and also forwards the Subscription Creation
+ Operations to Printer 2 with the Notification Recipient changed
+ to be the Printer 1. When an Event occurs in Printer 2, Printer
+ 2 sends the Event Notification (B) to Notification Recipient of
+ Printer 1, which relays the received Event Notification (B) to
+ the client-supplied Notification Recipient (as Event
+ Notifications(A) in the diagram). Note, when a client performs a
+ Subscription Creation Operation, Printer 1 need not forward the
+
+
+Herriot, et al. Expires July 24, 2001 [page 79]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ Subscription Creation Operation to Printer 2 if it would create
+ a duplicate Subscription Object on Printer 2.
+
+ Note: when Printer 1 is forwarding Subscription Creation Operations
+ to Printer 2, it may request Printer 2 to create additional
+ Subscription Objects (called "piggy-backing"). Piggy-backing is
+ useful when:
+
+ . Device A is configured to accept (IPP or non-IPP) requests from
+ other servers.
+
+ . Server S wants to receive Job Events that the client didn't
+ request and Server S wants these Events for jobs it submits and
+ not for other jobs.
+
+ server S device A
+ +------------+ +------------+
+ | | | |
+ +--------+ Subscription | ###########| | ###########|
+ | client |--Creation ----># Printer #| Subscription | # Printer #|
+ +--------+ Operation | # Object 1#|---Creation------|># Object 2#|
+ | ###|#######| Operation | ####|#|####|
+ +----|---^---+ +-----|-|----+
+ +--------+ Event | | | |
+ |Notific-|<-Notifications(A)-+ +-- Event Notifications(B)--+ |
+ |ation Re|<-------------Event Notifications(C)-----------------+
+ |cipient |
+ +--------+
+
+ Figure 2 - Model for Notification with Cascading Printers
+
+
+B. Appendix - Distributed Model for Notification
+
+ A Printer implementation could use some other remote notification
+ service to provide some or most of the service. For example, the
+ remote notification service could send Event Notifications using
+ Delivery Methods that are not directly supported by the output device
+ or server. Or, the remote notification service could store
+ Subscription Objects (passed to it from the output device in response
+ to Subscription Creation requests), accept Events, format the Event
+ Notification in the natural language of the Notification Recipient,
+ and send the Event Notifications to the Notification Recipient(s).
+
+ Figure 3 shows this partitioning. The interface between the output
+ device (or server) and the remote notification service is outside the
+ scope of this document and is intended to be transparent to the
+ client and this document. The combination of the output device (or
+ server) and the notification service together constitute an IPP
+ Printer conforming to this Notification document.
+
+
+Herriot, et al. Expires July 24, 2001 [page 80]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+
+
+ ***********************
+ *
+ * Printer (including
+ * the distributed
+ * Notification Service)
+ *
+ * output device or server
+ * +---------------+
+ PDA, desktop, or server * + ########### +
+ +--------+ * | # partial # |
+ | client |---IPP Subscription--------># Printer # |
+ +--------+ Creation operation * | # Object # |
+ * | #####|##### |
+ * +-------|-------+
+ * | Subscriptions
+ * | OR Event
+ +------------+ * | Notifications
+ |Notification| IPP-defined * +------v--------+
+ |Recipient |<--Event Notifications---| Notification |
+ +------------+ * | Service |
+ * +---------------+
+ *
+ *************************
+ *** = Implementation configuration opaque boundary
+
+
+ Figure 3 - Opaque Use of a Notification Service Transparent to the
+ Client
+
+
+C. Appendix - Extended Notification Recipient
+
+ The model allows for an extended Notification Recipient that is
+ itself a notification service that forwards each Event Notification
+ to another recipient (called the Ultimate Notification Recipient in
+ this section). The Delivery Method to the Ultimate Recipient is
+ probably different from the Delivery Method used by the Printer to
+ the extended Notification Recipient.
+
+ This extended Notification Recipient is transparent to the Printer
+ but not to the client.
+
+ When a client performs a Subscription Creation Operation, it
+ specifies the extended Notification Recipient as it would any
+ Notification Recipient. In addition, the client specifies the
+ Ultimate Notification Recipient in the Subscription Creation
+ Operation in a manner specified by the extended Notification
+ Recipient. Typically, it is either some bytes in the value of
+
+
+Herriot, et al. Expires July 24, 2001 [page 81]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ "notify-user-data" or some additional parameter in the value of
+ "notify-recipient-uri". The client also subscribes directly with the
+ extended Notification Recipient (by means outside this document),
+ since it is a notification service in its own right.
+
+ The IPP Printer treats the extended Notification Recipient like any
+ other Notification Recipient and the IPP Printer is not aware of the
+ forwarding. The Delivery Method that the extended Notification
+ Recipient uses for delivering the Event Notification to the Ultimate
+ Notification Recipient is beyond the scope of this document and is
+ transparent to the IPP Printer.
+
+ Examples of this extended Notification Recipient are paging,
+ immediate messaging services, general notification services, and NOS
+ vendors' infrastructure. Figure 4 shows this approach.
+
+
+ PDA, desktop, or server server or output device
+ +---------------+
+ +--------+ | ########### |
+ | client |---Subscription Creation -----------># Printer # |
+ +--------+ Operation | # Object # |
+ | #####|##### |
+ +------------+ +------------+ IPP-defined +-------|-------+
+ |Ultimate | any |Notification|<--Event Notifications----+
+ |Notification|<----|Recipient |
+ |Recipient | +------------+
+ +------------+ (Notification Service)
+
+ Figure 4 - Use of an Extended Notification Recipient transparent to
+ the Printer
+
+
+D. Appendix - Details about Conformance Terminology
+
+ The following paragraph provide more details about conformance
+ terminology.
+
+ REQUIRED - an adjective used to indicate that a conforming IPP
+ Printer implementation MUST support the indicated operation,
+ object, attribute, attribute value, status code, or out-of-band
+ value in requests and responses. See [RFC2911] "Appendix A -
+ Terminology for a definition of "support". Since support of this
+ entire Notification specification is OPTIONAL for conformance to
+ IPP/1.0 or IPP/1.1, the use of the term REQUIRED in this document
+ means "REQUIRED if this OPTIONAL Notification specification is
+ implemented".
+
+ RECOMMENDED - an adjective used to indicate that a conforming IPP
+ Printer implementation is recommended to support the indicated
+
+
+Herriot, et al. Expires July 24, 2001 [page 82]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ operation, object, attribute, attribute value, status code, or
+ out-of-band value in requests and responses. Since support of
+ this entire Notification specification is OPTIONAL for conformance
+ to IPP/1.0 or IPP/1.1, the use of the term RECOMMENDED in this
+ document means "RECOMMENDED if this OPTIONAL Notification
+ specification is implemented".
+
+ OPTIONAL - an adjective used to indicate that a conforming IPP
+ Printer implementation MAY, but is NOT REQUIRED to, support the
+ indicated operation, object, attribute, attribute value, status
+ code, or out-of-band value in requests and responses.
+
+
+E. Appendix - Object Model for Notification
+
+ This section describes the Notification object model that adds a
+ Subscription Object which together with the Job and Printer object
+ provide the complete Notification semantics.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 83]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ The object relationships can be seen pictorially as:
+
+
+ Subscription Objects (Per-Printer Subscriptions) Printer object
+ +----+ +------------+
+ | s1 |<--------------------------------------------->| |
+ +----++ | |
+ | s2 |<-------------------------------------------->| p1 |
+ +----++ | |
+ | s3 |<------------------------------------------->| |
+ +----+ +------------+
+ Job objects
+ +---------+
+ | |
+ +----+ | j1 |
+ | s4 |<------->| |
+ +----+ | |
+ | | s4 is a Per-Job Subscription Object
+ ++--------++
+ | |
+ +----+ | j2 |
+ | s5 |<------>| |
+ +----++ | |
+ | s6 |<----->| | s5 and s6 are Per-Job Subscription
+ +----+ ++--------++ Objects
+ | |
+ | j3 |
+ | |
+ | | <----> indicates association
+ +---------+
+
+ Figure 5 - Object Model for Notification
+
+ s1, s2, and s3 are Per-Printer Subscription Objects and can
+ identify Printer and/or Job Events.
+ s4, s5, and s6 are Per-Job Subscription Objects and can identify
+ Printer and/or Job Events.
+
+E.1 Appendix - Object relationships
+
+ This sub-section defines the object relationships between the
+ Printer, Job, and Subscription Objects by example. Whether Per-
+ Printer Subscription Objects are actually contained in a Printer
+ object or are just bi-directionally associated with them in some way
+ is IMPLEMENTATION DEPENDENT and is transparent to the client.
+ Similarly, whether Per-Job Subscription Objects are actually
+ contained in a Job object or are just bi-directionally associated
+ with them in some way is IMPLEMENTATION DEPENDENT and is transparent
+ to the client. The object relationships are defined as follows:
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 84]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+E.2 Printer Object and Per-Printer Subscription Objects
+
+ 1.The Printer object contains (is associated with) zero or more
+ Per-Printer Subscription Objects (p1 contains s1-s3 Per-Printer
+ Subscription Objects).
+
+ 2.Each Per-Printer Subscription Object (s1, s2, and s3) is
+ contained in (or is associated with) exactly one Printer object
+ (p1).
+
+
+E.3 Job Object and Per-Job Subscription Objects
+
+ 1.A Job object (j1, j2, j3) is associated with zero or more Per-
+ Job Subscription Objects (s4-s6). Job j1 is associated with
+ Per-Job Subscription Object s4, Job j2 is associated with Per-
+ Job Subscription Objects s5 and s6, and Job j3 is not associated
+ with any Per-Job Subscription Object.
+
+ 2.Each Per-Job Subscription Object is associated with exactly one
+ Job object.
+
+
+F. Appendix - Per-Job versus Per-Printer Subscription Objects
+
+ Per-Job and Per-Printer Subscription Objects are quite similar.
+ Either type of Subscription Object can subscribe to Job Events,
+ Printer Events, or both. Both types of Subscription Objects can be
+ queried using the Get-Subscriptions and Get-Subscription-Attributes
+ operations and canceled using the Cancel-Subscription operation.
+ Both types of Subscription Objects create Subscription Objects which
+ have the same Subscription Object attributes defined. However, there
+ are some semantic differences between Per-Job Subscription Objects
+ and Per-Printer Subscription Objects. A Per-Job Subscription Object
+ is established by the client when submitting a job and after creating
+ the job using the Create-Job-Subscriptions operation by specifying
+ the "job-id" of the Job with the "notify-job-id" attribute. A Per-
+ Printer Subscription Object is established between a client and a
+ Printer using the Create-Printer-Subscriptions operation. Some
+ specific differences are:
+
+ 1.A client usually creates one or more Per-Job Subscription
+ Objects as part of the Job Creation operations (Create-Job,
+ Print-Job, and Print-URI), rather than using the OPTIONAL
+ Create-Job-Subscriptions operation, especially since Printer
+ implementations NEED NOT support the Create-Job-Subscriptions
+ operation, since it is OPTIONAL.
+
+ 2.For Per-Job Subscription Objects, the Subscription Object is
+ only valid while the job is "not-complete" (see sections 5.4.3)
+
+
+Herriot, et al. Expires July 24, 2001 [page 85]
+
+
+INTERNET-DRAFT IPP: Event Notification January 24, 2001
+
+
+ while for the Per-Printer Subscription Objects, the Subscription
+ Object is valid until the time (in seconds) that the Printer
+ returned in the "notify-lease-expiration-time" operation
+ attribute.
+
+ 3.Job Events in a Per-Job Subscription Object apply only to "one
+ job" (the Job created by the Job Creation operation or
+ references by the Create-Job-Subscriptions operation) while Job
+ Events in a Per-Printer Subscription Object apply to ALL jobs
+ contained in the IPP Printer.
+
+
+G. Appendix: Full Copyright Statement
+
+ Copyright (C) The Internet Society (1998,1999,2000,2001). All Rights
+ Reserved
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires July 24, 2001 [page 86]
diff --git a/standards/draft-ietf-ipp-notify-get-02.txt b/standards/draft-ietf-ipp-notify-get-02.txt
new file mode 100644
index 000000000..143da3217
--- /dev/null
+++ b/standards/draft-ietf-ipp-notify-get-02.txt
@@ -0,0 +1,1711 @@
+
+
+
+
+
+
+INTERNET-DRAFT Robert Herriot (editor)
+<draft-ietf-ipp-notify-get-02.txt> Xerox Corp.
+[Target category: standards track] Carl Kugler
+ IBM, Corp.
+ Harry Lewis
+ IBM, Corp.
+ February 28, 2001
+ Internet Printing Protocol (IPP):
+ The 'ippget' Delivery Method for Event Notifications
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+Status of this Memo:
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of [rfc2026]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF), its
+ areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress".
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed as
+ http://www.ietf.org/shadow.html.
+
+Abstract
+
+ The notification extension document [ipp-ntfy] defines operations
+ that a client can perform in order to create Subscription Objects in
+ a Printer and carry out other operations on them. A Subscription
+ Object represents a Subscription abstraction. The Subscription Object
+ specifies that when one of the specified Events occurs, the Printer
+ sends an asynchronous Event Notification to the specified
+ Notification Recipient via the specified Delivery Method (i.e.,
+ protocol).
+
+ The notification extension document [ipp-ntfy] specifies that each
+ Delivery Method is defined in another document. This document is one
+ such document, and it specifies the 'ippget' delivery method.
+
+ The 'ippget' Delivery Method is a 'pull and push' Delivery Method.
+ That is, the Printer saves Event Notification for a period of time
+ and expects the Notification Recipient to fetch the Event
+ Notifications (the pull part). The Printer continues to send Event
+
+Herriot, et al. Expires: August 28, 2001 [page 1]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ Notifications to the Notification Recipient as Events occur (the push
+ part) if the client has selected the option to wait for additional
+ Event Notifications.
+
+ When a Printer supports this Delivery Method, it holds each Event
+ Notification for an amount of time, called the Event Notification
+ Lease Time.
+
+ When a Notification Recipient wants to receive Event Notifications,
+ it performs an IPP operation called 'Get-Notifications', which this
+ document defines. This operation causes the Printer to return all
+ Event Notifications held for the Notification Recipient. If the
+ Notification Recipient has selected the option to wait for additional
+ Event Notifications, the Printer continues sending Event
+ Notifications to the Notification Recipient as additional Events
+ occur.
+
+
+
+ The basic set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics [RFC2911]
+ Internet Printing Protocol/1.1: Encoding and Transport [RFC2910]
+ Internet Printing Protocol/1.1: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+ Internet Printing Protocol/1.0 & 1.1: IPP Event Notification
+ Specification [ipp-ntfy]
+
+ The "Design Goals for an Internet Printing Protocol" document takes a
+ broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. A few OPTIONAL operator operations have
+ been added to IPP/1.1.
+
+ The "Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol" document describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specification documents, and gives background and rationale
+ for the IETF working group's major decisions.
+
+ The "Internet Printing Protocol/1.1: Model and Semantics" document
+ describes a simplified model with abstract objects, their attributes,
+ and their operations that are independent of encoding and transport.
+ It introduces a Printer and a Job object. The Job object optionally
+
+Herriot, et al. Expires: August 28, 2001 [page 2]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ supports multiple documents per Job. It also addresses security,
+ internationalization, and directory issues.
+
+ The "Internet Printing Protocol/1.1: Encoding and Transport" document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1 [RFC2616]. It defines the
+ encoding rules for a new Internet MIME media type called
+ "application/ipp". This document also defines the rules for
+ transporting over HTTP a message body whose Content-Type is
+ "application/ipp". This document defines a new scheme named 'ippget'
+ for identifying IPP printers and jobs.
+
+ The "Internet Printing Protocol/1.1: Implementer's Guide" document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.1 and some of
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+ The "Mapping between LPD and IPP Protocols" document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+ The "Event Notification Specification" document describes an
+ extension to the IPP/1.0, IPP/1.1, and future versions. This
+ extension allows a client to subscribe to printing related Events.
+ Subscriptions are modeled as Subscription Objects. The Subscription
+ Object specifies that when one of the specified Event occurs, the
+ Printer sends an asynchronous Event Notification to the specified
+ Notification Recipient via the specified Delivery Method (i.e.,
+ protocol). A client associates Subscription Objects with a
+ particular Job by performing the Create-Job-Subscriptions operation
+ or by submitting a Job with subscription information. A client
+ associates Subscription Objects with the Printer by performing a
+ Create-Printer-Subscriptions operation. Four other operations are
+ defined for Subscription Objects: Get-Subscriptions-Attributes, Get-
+ Subscriptions, Renew-Subscription, and Cancel-Subscription.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 3]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+
+Table of Contents
+
+
+ 1 Introduction....................................................6
+
+ 2 Terminology.....................................................6
+
+ 3 Model and Operation.............................................7
+
+ 4 General Information.............................................8
+
+ 5 Get-Notifications operation....................................10
+ 5.1 Get-Notifications Request...................................12
+ 5.2 Get-Notifications Response..................................13
+
+ 6 Subscription Template Attributes...............................18
+ 6.1 Subscription Template Attribute Conformance.................18
+ 6.2 Additional Information about Subscription Template Attributes18
+ 6.2.1 notify-recipient-uri (uri)................................18
+ 6.3 Subscription Description Attribute Conformance..............19
+
+ 7 Additional Printer Description Attributes......................19
+ 7.1 Printer Description Attribute Conformance...................19
+ 7.2 New Values for Existing Printer Description Attributes......19
+ 7.2.1 notify-schemes-supported (1setOf uriScheme)...............19
+ 7.2.2 operations-supported (1setOf type2 enum)..................19
+ 7.3 begin-to-expire-time-interval (integer(0:MAX))..............20
+
+ 8 New Status Codes...............................................20
+ 8.1 redirection-other-site (0x300)..............................21
+
+ 9 The IPPGET URL Scheme..........................................21
+ 9.1 The IPPGET URL Scheme Applicability and Intended Usage......21
+ 9.2 The IPPGET URL Scheme Associated Port.......................21
+ 9.3 The IPPGET URL Scheme Associated MIME Type..................21
+ 9.4 The IPPGET URL Scheme Character Encoding....................22
+ 9.5 The IPPGET URL Scheme Syntax in ABNF........................22
+ 9.5.1 IPPGET URL Examples.......................................23
+ 9.5.2 IPPGET URL Comparisons....................................23
+
+ 10 Encoding.......................................................24
+
+ 11 Conformance Requirements.......................................24
+ 11.1 Conformance for IPP Printers................................24
+ 11.2 Conformance for IPP Clients.................................25
+
+ 12 IANA Considerations............................................25
+ 12.1 Operation Registrations.....................................26
+ 12.2 Additional values of existing attributes....................26
+
+Herriot, et al. Expires: August 28, 2001 [page 4]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ 12.2.1 Additional values for the "notify-schemes-supported" Printer
+ attribute..............................................26
+ 12.2.2 Additional values for the "operations-supported" Printer
+ attribute..............................................26
+ 12.3 Attribute Registrations.....................................27
+ 12.4 Status code Registrations...................................27
+
+ 13 Internationalization Considerations............................27
+
+ 14 Security Considerations........................................27
+
+ 15 References.....................................................28
+
+ 16 Authors' Addresses.............................................29
+
+ 17 Full Copyright Statement.......................................30
+
+
+Table of Tables
+
+ Table 1 - Information about the Delivery Method....................9
+
+ Table 2 - Attributes in Event Notification Content................16
+
+ Table 3 - Additional Attributes in Event Notification Content for Job
+
+ Events ........................................................17
+
+ Table 4 - Combinations of Events and Subscribed Events for "job-
+
+ impressions-completed" ........................................17
+
+ Table 5 - Additional Attributes in Event Notification Content for
+
+ Printer Events ................................................18
+
+ Table 6 - Operation-id assignments................................20
+
+ Table 7 - The "event-notification-attributes-tag" value...........24
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 5]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+1 Introduction
+
+ The notification extension document [ipp-ntfy] defines operations
+ that a client can perform in order to create Subscription Objects in
+ a Printer and carry out other operations on them. A Subscription
+ Object represents a Subscription abstraction. The Subscription Object
+ specifies that when one of the specified Events occurs, the Printer
+ sends an asynchronous Event Notification to the specified
+ Notification Recipient via the specified Delivery Method (i.e.,
+ protocol).
+
+ The notification extension document [ipp-ntfy] specifies that each
+ Delivery Method is defined in another document. This document is one
+ such document, and it specifies the 'ippget' delivery method.
+
+ The 'ippget' Delivery Method is a 'pull and push' Delivery Method.
+ That is, the Printer saves Event Notification for a period of time
+ and expects the Notification Recipient to fetch the Event
+ Notifications (the pull part). The Printer continues to send Event
+ Notifications to the Notification Recipient as Events occur (the push
+ part) if the client has selected the option to wait for additional
+ Event Notifications.
+
+ When a Printer supports this Delivery Method, it holds each Event
+ Notification for an amount of time, called the Event Notification
+ Lease Time.
+
+ When a Notification Recipient wants to receive Event Notifications,
+ it performs an IPP operation called 'Get-Notifications', which this
+ document defines. This operation causes the Printer to return all
+ Event Notifications held for the Notification Recipient. If the
+ Notification Recipient has selected the option to wait for additional
+ Event Notifications, the Printer the Printer continues to send Event
+ Notifications to the Notification Recipient as Events occur.
+
+
+2 Terminology
+
+ This section defines the following terms that are used throughout
+ this document:
+
+ Capitalized terms, such as MUST, MUST NOT, REQUIRED, SHOULD, SHOULD
+ NOT, MAY, NEED NOT, and OPTIONAL, have special meaning relating to
+ conformance to this specification. These terms are defined in
+ [RFC2911 section 13.1 on conformance terminology, most of which is
+ taken from RFC 2119 [RFC2119].
+
+ Event Notification Lease: The lease that is associated with an Event
+ Notification. When the lease expires, the Printer discards the
+ associated Event Notification.
+
+Herriot, et al. Expires: August 28, 2001 [page 6]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ Event Notification Lease Time: The expiration time assigned to a
+ lease that is associated with an Event Notification.
+
+ Event Notification Attributes Group: The attributes group in a
+ response that contains attributes that are part of an Event
+ Notification.
+
+ For other capitalized terms that appear in this document, see [ipp-
+ ntfy].
+
+
+3 Model and Operation
+
+ In a Subscription Creation Operation, when the value of the "notify-
+ recipient-uri" attribute has the scheme 'ippget', the client is
+ requesting that the Printer use the 'ippget' Delivery Method for the
+ Event Notifications associated with the new Subscription Object. The
+ client SHOULD choose a value for the address part of the "notify-
+ recipient-uri" attribute that uniquely identifies the Notification
+ Recipient.
+
+ When an Event occurs, the Printer MUST generate an Event Notification
+ and MUST assign it the Event Notification Lease Time. The Printer
+ MUST hold an Event Notification for its assigned Event Notification
+ Lease Time. The Printer MUST assign the same Event Notification
+ Lease Time to each Event Notification.
+
+ When a Notification Recipient wants to receive Event Notifications,
+ it performs the Get-Notifications operation, which causes the Printer
+ to return all un-expired Event Notifications held for the
+ Notification Recipient. If the Notification Recipient has selected
+ the option to wait for additional Event Notifications, the response
+ to the Get-Notifications request continues indefinitely as the
+ Printer continues to send Event Notifications in the response as
+ Events occur. For the Get-Notification operation, the Printer sends
+ only those Event Notifications that are generated from Subscription
+ Objects whose "notify-recipient-uri" attribute value equals the value
+ of the "notify-recipient-uri" Operation Attribute in the Get-
+ Notifications operation.
+
+ If a Notification Recipient performs the Get-Notifications operation
+ twice in quick succession, it will receive nearly the same Event
+ Notification both times because most of the Event Notifications are
+ those that the Printer saves for a few seconds after the Event
+ occurs. There are two possible differences. Some old Event
+ Notifications may not be present in the second response because their
+ Event Notification Leases have expired. Some new Event Notifications
+ may be present in the second response but not the first response.
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 7]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ When the Notification Recipient requests Event Notifications for per-
+ Job Subscription Objects, the Notification Recipient typically
+ performs the Get-Notifications operation within a second of
+ performing the Subscription Creation operation. Because the Printer
+ is likely to save Event Notifications for several seconds, the
+ Notification Recipient is unlikely to miss any Event Notifications
+ that occur between the Subscription Creation and the Get-
+ Notifications operation.
+
+
+4 General Information
+
+ If a Printer supports this Delivery Method, the following are its
+ characteristics.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 8]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ Table 1 - Information about the Delivery Method
+
+
+ Document Method Conformance Delivery Method Realization
+ Requirement
+
+
+ 1. What is the URL scheme name ippget
+ for the Delivery Method?
+
+ 2. Is the Delivery Method RECOMMENDED
+ REQUIRED, RECOMMENDED or
+ OPTIONAL for an IPP Printer
+ to support?
+
+ 3. What transport and delivery
+ protocols does the Printer
+ use to deliver the Event
+ Notification Content, i.e.,
+ what is the entire network IPP with one new operation.
+ stack?
+
+ 4. Can several Event Yes.
+ Notifications be combined
+ into a Compound Event
+ Notification?
+
+ 5. Is the Delivery Method This Delivery Method is a pull
+ initiated by the Notification and a push.
+ Recipient (pull), or by the
+ Printer (push)?
+
+ 6. Is the Event Notification Machine Consumable
+ content Machine Consumable or
+ Human Consumable?
+
+ 7. What section in this document Section 5
+ answers the following
+ question? For a Machine
+ Consumable Event
+ Notification, what is the
+ representation and encoding
+ of values defined in section
+ 9.1 of [ipp-ntfy] and the
+ conformance requirements
+ thereof? For a Human
+ Consumable Event
+ Notification, what is the
+ representation and encoding
+
+
+Herriot, et al. Expires: August 28, 2001 [page 9]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+
+ of pieces of information
+ defined in section 9.2 of
+ [ipp-ntfy] and the
+ conformance requirements
+ thereof?
+
+ 8. What are the latency and Same as IPP and the underlying
+ reliability of the transport HTTP transport
+ and delivery protocol?
+
+ 9. What are the security aspects Same as IPP and the underlying
+ of the transport and delivery HTTP transport
+ protocol, e.g., how it is
+ handled in firewalls?
+
+ 10. What are the content length None
+ restrictions?
+
+ 11. What are the additional None
+ values or pieces of
+ information that a Printer
+ sends in an Event
+ Notification content and the
+ conformance requirements
+ thereof?
+
+ 12. What are the additional None
+ Subscription Template and/or
+ Subscription Description
+ attributes and the
+ conformance requirements
+ thereof?
+
+ 13. What are the additional None
+ Printer Description
+ attributes and the
+ conformance requirements
+ thereof?
+
+
+
+
+5 Get-Notifications operation
+
+ This operation causes the Printer to return all Event Notifications
+ held for the Notification Recipient.
+
+ A Printer MUST support this operation.
+
+
+Herriot, et al. Expires: August 28, 2001 [page 10]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ When a Printer performs this operation, it MUST return all and only
+ those Event Notifications:
+
+ 1. Whose associated Subscription Object's "notify-recipient-uri"
+ attribute equals the "notify-recipient-uri" Operation attribute
+ AND
+
+ 2. Whose associated Subscription Object's "notify-recipient-uri"
+ attribute has a scheme value of 'ippget' AND
+
+ 3. Whose Event Notification Lease Time has not yet expired AND
+
+ 4. Where the Notification Recipient is the owner of or has read-
+ access rights to the associated Subscription Object.
+
+ The Printer MUST respond to this operation immediately with whatever
+ Event Notifications it currently holds. If the Notification Recipient
+ has selected the option to wait for additional Event Notifications,
+ the Printer MUST continue to send Event Notifications as they occur
+ until all of the associated Subscription Objects are cancelled. A
+ Subscription Object is cancelled either via the Cancel-Subscription
+ operation or by the Printer (e.g. the Subscription Object is
+ cancelled when the associated Job completes).
+
+ Note, the Printer terminates the operation in the same way that it
+ normally terminates IPP operations. For example, if the Printer is
+ sending chunked data, it can send a 0 length chunk to denote the end
+ of the operation or it can close the connection. If the Notification
+ Recipient wishes to terminate the Get-Notifications operation, it can
+ close the connection.
+
+ The Printer MUST accept the request in any state (see [RFC2911]
+ "printer-state" and "printer-state-reasons" attributes) and MUST
+ remain in the same state with the same "printer-state-reasons"
+ values.
+
+ Access Rights: If the policy of the Printer is to allow all users to
+ access all Event Notifications, then the Printer MUST accept this
+ operation from any user. Otherwise, the authenticated user (see
+ [RFC2911] section 8.3) performing this operation MUST either be the
+ owner of each Subscription Object identified by the "notify-
+ recipient-uri" Operation attribute (as determined during a
+ Subscription Creation Operation) or an operator or administrator of
+ the Printer (see [RFC2911] Sections 1 and 8.5). Otherwise, the IPP
+ object MUST reject the operation and return: 'client-error-
+ forbidden', 'client-error-not-authenticated', or 'client-error-not-
+ authorized' status code as appropriate.
+
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 11]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+5.1 Get-Notifications Request
+
+ The following groups of attributes are part of the Get-Notifications
+ Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.1.
+
+ Target:
+ The "printer-uri" (uri) operation attribute which is the target
+ for this operation as described in [RFC2911] section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in [RFC2911] section 8.3.
+
+ "notify-recipient-uri" (url):
+ The client MUST supply this attribute. The Printer object MUST
+ support this attribute. The Printer matches the value of this
+ attribute (byte for byte with no case conversion) against the
+ value of the "notify-recipient-uri" in each Subscription Object
+ in the Printer. If there are no matches, the IPP Printer MUST
+ return the 'client-error-not-found' status code. For each
+ matched Subscription Object, the IPP Printer MUST return all
+ unexpired Event Notifications associated with it. The Printer
+ MUST send additional Event Notifications as Events occur if and
+ only if the value of the "notify-no-wait" attribute is 'false'
+ or not supplied by the client (see the next attribute below).
+
+ Note: this attribute allows a subscribing client to pick URLs
+ that are unique, e.g. the client's own URL or a friend's URL,
+ which in both cases is likely the URL of the person's host. An
+ application could make a URL unique for each application.
+
+ "notify-no-wait" (boolean):
+ The client MAY supply this attribute. The Printer object MUST
+ support this attribute. If the value of this attribute is
+ 'false', the Printer MUST send all un-expired Event
+ Notifications (as defined in the previous attribute) and it
+ MUST continue to send responses for as long as the Subscription
+ Objects associated with the specified "notify-recipient-uri"
+ continue to exist. If the value of this attribute is 'true',
+ the Printer MUST send all un-expired Event Notifications (as
+ defined in the previous attribute) and the Printer MUST
+ conclude the operation without waiting for any additional
+ Events to occur. If the client doesn't supply this attribute,
+
+
+Herriot, et al. Expires: August 28, 2001 [page 12]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ the Printer MUST behave as if the client had supplied this
+ attribute with the value of 'false'.
+
+5.2 Get-Notifications Response
+
+ The following groups of attributes are part of the Get-Notifications
+ Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) and/or a "detailed-status-message" (text(MAX))
+ operation attribute as described in [RFC2911] sections 13 and
+ 3.1.6.
+
+ The Printer can return any status codes defined in [RFC2911].
+ If the status code is not 'successful-', the Printer MUST NOT
+ return any Event Notification Attribute groups. The following
+ is a description of the important status codes:
+
+ successful-ok: the response contains all Event Notification
+ associated with the specified "notify-recipient-uri". If
+ the specified Subscription Objects have no associated
+ Event Notification, the response MUST contain zero Event
+ Notifications.
+ client-error-not-found: The Printer has no Subscription
+ Object's whose "notify-recipient-uri" attribute equals
+ the "notify-recipient-uri" Operation attribute.
+ server-error-busy: The Printer is too busy to accept this
+ operation. If the "suggested-ask-again-time-interval"
+ operation attribute is present in the Operation
+ Attributes of the response, then the Notification
+ Recipient SHOULD wait for the number of seconds specified
+ by the "suggested-ask-again-time-interval" attribute
+ before performing this operation again. If the
+ "suggested-ask-again-time-interval" Operation Attribute
+ is not present, the Notification Recipient should use the
+ normal network back-off algorithms for determining when
+ to perform this operation again.
+ redirection-other-site: The Printer does not handle this
+ operation and requests the Notification Recipient to
+ perform the operation with the uri specified by the
+ "notify-ippget-redirect" Operation Attribute in the
+ response.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in [RFC2911] section 3.1.4.2.
+
+Herriot, et al. Expires: August 28, 2001 [page 13]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+
+ The Printer MUST use the values of "notify-charset" and
+ "notify-natural-language", respectively, from one Subscription
+ Object associated with the Event Notifications in this
+ response.
+
+ Normally, there is only one matched Subscription Object, or the
+ value of the "notify-charset" and "notify-natural-language"
+ attributes is the same in all Subscription Objects. If not, the
+ Printer MUST pick one Subscription Object from which to obtain
+ the value of these attributes. The algorithm for picking the
+ Subscription Object is implementation dependent. The choice of
+ natural language is not critical because 'text' and 'name'
+ values can override the "attributes-natural-language" Operation
+ attribute. The Printer's choice of charset is critical because
+ a bad choice may leave it unable to send some 'text' and 'name'
+ values accurately.
+
+ "printer-up-time" (integer(0:MAX)):
+ The value of this attribute is the Printer's "printer-up-time"
+ attribute at the time the Printer sends this response. Because
+ each Event Notification also contains the value of this
+ attribute when the event occurred, the value of this attribute
+ lets a Notification Recipient know when each Event Notification
+ occurred relative to the time of this response.
+
+ "suggested-ask-again-time-interval" (integer(0:MAX)):
+ The value of this attribute is the number of seconds that the
+ Notification Recipient SHOULD wait before trying this operation
+ again when
+ a) the Printer returns the 'server-error-busy' status code
+ OR
+ b) the Printer returns the 'successful-ok' status code and
+ the client supplied the "notify-no-wait" attribute with a
+ value of 'true'.
+ This value is intended to help the client be a good network
+ citizen.
+
+ "notify-ippget-redirect" (uri):
+ The value of this attribute is uri that the Notification
+ Recipient MUST use for the Get-Notifications operation. This
+ attribute is present in the Operation Attributes if and only if
+ the status code has the value 'redirection-other-site'.
+
+ Group 2: Unsupported Attributes
+
+ See [RFC2911] section 3.1.7 for details on returning
+ Unsupported Attributes.
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 14]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ If the "subscription-ids" attribute contained subscription-ids
+ that do not exist, the Printer returns them in this group as
+ value of the "subscription-ids" attribute.
+
+ Group 3 through N: Event Notification Attributes
+
+ The Printer responds with one Event Notification Attributes
+ Group per matched Event Notification. The initial matched Event
+ Notifications are all un-expired Event Notification associated
+ with the matched Subscription Objects. If the Notification
+ Recipient has selected the option to wait for additional Event
+ Notifications, the Printer the subsequent Event Notifications
+ in the response are Event Notifications associated with the
+ matched Subscription Objects as the corresponding Event occurs.
+
+ From the Notification Recipient's view, the response appears as
+ an initial burst of data, which includes the Operation
+ Attributes Group and one Event Notification Attributes Groups
+ per Event Notification that the Printer is holding. After the
+ initial burst of data, if the Notification Recipient has
+ selected the option to wait for additional Event Notifications,
+ the Notification Recipient receives occasional Event
+ Notification Attribute Groups. Proxy servers may delay some
+ Event Notifications or cause time-outs to occur. The client
+ MUST be prepared to perform the Get-Notifications operation
+ again when time-outs occur.
+
+ Each Event Notification Group MUST start with an 'event-
+ notification-attributes-tag' (see the section "Encodings of
+ Additional Attribute Tags" in [ipp-ntfy]).
+
+ Each attribute is encoded using the IPP rules for encoding
+ attributes [RFC2910] and may be encoded in any order. Note:
+ the Get-Jobs response in [RFC2911] acts as a model for encoding
+ multiple groups of attributes.
+
+ Each Event Notification Group MUST contain all of attributes
+ specified in section 9.1 ("Content of Machine Consumable Event
+ Notifications") of [ipp-ntfy] with exceptions denoted by
+ asterisks in the tables below.
+
+ The tables below are copies of the tables in section 9.1
+ ("Content of Machine Consumable Event Notifications") of [ipp-
+ ntfy] except that each cell in the "Sends" column is a "MUST".
+
+ For an Event Notification for all Events, the Printer includes
+ the attributes shown in Table 2.
+
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 15]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ Table 2 - Attributes in Event Notification Content
+
+
+ Source Value Sends Source Object
+
+
+ notify-subscription-id (integer(1:MAX)) MUST Subscription
+
+ notify-printer-uri (uri) MUST Subscription
+
+ notify-subscribed-event (type2 keyword) MUST Event
+ Notification
+
+ printer-up-time (integer(MIN:MAX)) MUST Printer
+
+ printer-current-time (dateTime) * MUST * Printer
+
+ notify-sequence-number (integer (0:MAX)) MUST Subscription
+
+ notify-charset (charset) MUST Subscription
+
+ notify-natural-language (naturalLanguage) MUST Subscription
+
+ notify-user-data (octetString(63)) ** MUST Subscription
+
+ notify-text (text) MUST Event
+ Notification
+
+ attributes from the "notify-attributes" MUST Printer
+ attribute ***
+
+ attributes from the "notify-attributes" MUST Job
+ attribute ***
+
+ attributes from the "notify-attributes" MUST Subscription
+ attribute ***
+
+
+ * The Printer MUST send the "printer-current-time" attribute if
+ and only if it supports the "printer-current-time" attribute on
+ the Printer object.
+
+ ** If the associated Subscription Object does not contain a
+ "notify-user-data" attribute, the Printer MUST send an octet-
+ string of length 0.
+
+ *** If the "notify-attributes" attribute is present on the
+ Subscription Object, the Printer MUST send all attributes
+ specified by the "notify-attributes" attribute. Note: if the
+
+
+Herriot, et al. Expires: August 28, 2001 [page 16]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ Printer doesn't support the "notify-attributes" attribute, it
+ is not present on the associated Subscription Object.
+
+ For Event Notifications for Job Events, the Printer includes
+ the additional attributes shown in Table 3.
+
+ Table 3 - Additional Attributes in Event Notification Content for
+ Job Events
+
+
+ Source Value Sends Source
+ Object
+
+
+ job-id (integer(1:MAX)) MUST Job
+
+ job-state (type1 enum) MUST Job
+
+ job-state-reasons (1setOf type2 keyword) MUST Job
+
+ job-impressions-completed (integer(0:MAX)) * MUST Job
+
+
+ * The Printer MUST send the "job-impressions-completed"
+ attribute in an Event Notification only for the combinations of
+ Events and Subscribed Events shown in Table 4.
+
+
+ Table 4 - Combinations of Events and Subscribed Events for "job-
+ impressions-completed"
+
+
+ Job Event Subscribed Job Event
+
+
+ 'job-progress' 'job-progress'
+
+ 'job-completed' 'job-completed'
+
+ 'job-completed' 'job-state-changed'
+
+
+
+ For Event Notification for Printer Events, the Printer includes
+ the additional attributes shown in Table 5.
+
+
+
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 17]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ Table 5 - Additional Attributes in Event Notification Content for
+ Printer Events
+
+
+ Source Value Sends Source
+ Object
+
+
+ printer-state (type1 enum) MUST Printer
+
+ printer-state-reasons (1setOf type2 keyword) MUST Printer
+
+ printer-is-accepting-jobs (boolean) MUST Printer
+
+
+6 Subscription Template Attributes
+
+ This section defines the Subscription object conformance requirements
+ for Printers.
+
+
+6.1 Subscription Template Attribute Conformance
+
+ The 'ippget' Delivery Method has the same conformance requirements
+ for Subscription Template attributes as defined in [ipp-ntfy]. The
+ 'ippget' Delivery Method does not define any addition Subscription
+ Template attributes.
+
+
+6.2 Additional Information about Subscription Template Attributes
+
+ This section defines additional information about Subscription
+ Template attributes defined in [ipp-ntfy].
+
+
+6.2.1 notify-recipient-uri (uri)
+
+ This section describes the syntax of the value of this attribute for
+ the 'ippget' Delivery Method. The syntax for values of this
+ attribute for other Delivery Method is defined in other Delivery
+ Method Documents.
+
+ In order to support the 'ippget' Delivery Method and Protocol, the
+ Printer MUST support the following syntax:
+
+ The 'ippget://' URI scheme. The remainder of the URI indicates
+ something unique about the Notification Recipient, such as its host
+ name or host address (and optional path) that the Printer uses to
+ match the "notify-recipient-uri" Operation attribute supplied in
+ the Get-Notifications request.
+
+Herriot, et al. Expires: August 28, 2001 [page 18]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+6.3 Subscription Description Attribute Conformance
+
+ The 'ippget' Delivery Method has the same conformance requirements
+ for Subscription Description attributes as defined in [ipp-ntfy].
+ The 'ippget' Delivery Method does not define any addition
+ Subscription Description attributes.
+
+
+7 Additional Printer Description Attributes
+
+ This section defines the Printer Description Attributes conformance
+ requirements for Printers.
+
+
+7.1 Printer Description Attribute Conformance
+
+ The 'ippget' Delivery Method has the same conformance requirements
+ for Printer Description attributes as defined in [ipp-ntfy]. The
+ 'ippget' Delivery Method does not define any addition Printer
+ Description attributes.
+
+
+7.2 New Values for Existing Printer Description Attributes
+
+ This section defines additional values for existing Printer
+ Description attributes.
+
+
+7.2.1 notify-schemes-supported (1setOf uriScheme)
+
+ The following value for the "notify-schemes-supported" attribute is
+ added in order to support the new Delivery Method defined in this
+ document:
+
+ 'ippget' - The IPP Notification Delivery Method defined in this
+ document.
+
+7.2.2 operations-supported (1setOf type2 enum)
+
+ Table 6 lists the "operation-id" value defined in order to support
+ the new Get-Notifications operation defined in this document.
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 19]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ Table 6 - Operation-id assignments
+
+
+ Value Operation Name
+
+
+ 0x001C Get-Notifications
+
+
+
+
+7.3 begin-to-expire-time-interval (integer(0:MAX))
+
+ This Printer Description attribute specifies the number of seconds
+ that a Printer keeps an Event Notification that is associated with
+ the 'ippget' Delivery Method.
+
+ The Printer MUST support this attribute if it supports the 'ippget'
+ Delivery Method.
+
+ The value of this attribute is the minimum number of seconds that
+ MUST elapse between the time the Printer creates an Event
+ Notification object for the 'ippget' Delivery Method and the time the
+ Printer discards the same Event Notification.
+
+ For example, assume the following:
+
+ 1.a client performs a Job Creation operation that creates a
+ Subscription Object associated with this Delivery Method, AND
+
+ 2.an Event associated with the new Job occurs immediately after
+ the Subscription Object is created, AND
+
+ 3.the same client or some other client performs a Get-
+ Notifications operation N seconds after the Job Creation
+ operation.
+
+ Then, if N is less than the value of this attribute, the client
+ performing the Get-Notifications operations can expect not miss any
+ Event-Notifications, barring some unforeseen lack of memory space in
+ the Printer.
+
+
+8 New Status Codes
+
+ The following status codes are defined as extensions for this
+ Delivery Method and are returned as the status code of the Get-
+ Notifications operation.
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 20]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+8.1 redirection-other-site (0x300)
+
+ This status code means that the Printer doesn't perform that Get-
+ Notifications operation and that the "notify-ippget-redirect"
+ Operation Attribute in the response contains the uri that the
+ Notification Recipient MUST use for performing the Get-Notifications
+ operation.
+
+
+9 The IPPGET URL Scheme
+
+ This section defines the 'ippget' URL and the conformance
+ requirements for using it.
+
+
+9.1 The IPPGET URL Scheme Applicability and Intended Usage
+
+ This section is intended for use in registering the 'ippget' URL
+ scheme with IANA and fully conforms to the requirements in [RFC2717].
+ This document defines the 'ippget'" URL (Uniform Resource Locator)
+ scheme for specifying a unique identifier for an IPP Client which
+ implements the IPP Get-Notifications operation specified in this
+ document (see section 5).
+
+ The intended usage of the 'ippget' URL scheme is COMMON.
+
+
+9.2 The IPPGET URL Scheme Associated Port
+
+ None.
+
+ An 'ippget' URL behaves as a unique identifier for IPP Clients and is
+ NOT used to initiate any over-the-wire protocol associations.
+
+ See: IANA Port Numbers Registry [IANA-PORTREG].
+
+
+9.3 The IPPGET URL Scheme Associated MIME Type
+
+ All IPP Get-Notifications operations (requests and responses) MUST be
+ conveyed in an 'application/ipp' MIME media type as registered in
+ [IANA-MIMEREG]. An 'ippget' URL MUST uniquely identify an IPP Client
+ that support this 'application/ipp' MIME media type.
+
+ See: IANA MIME Media Types Registry [IANA-MIMEREG].
+
+
+
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 21]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+9.4 The IPPGET URL Scheme Character Encoding
+
+ The 'ippget' URL scheme defined in this document is based on the ABNF
+ for the URI Generic Syntax [RFC2396] and further updated by [RFC2732]
+ and [RFC2373] (for IPv6 addresses in URLs). The 'ippget' URL scheme
+ is case-insensitive in the host name or host address part; however,
+ the path part is case-sensitive, as in [RFC2396]. Code points
+ outside [US-ASCII] MUST be hex escaped by the mechanism specified in
+ [RFC2396].
+
+
+9.5 The IPPGET URL Scheme Syntax in ABNF
+
+ This document is intended for use in registering the 'ippget' URL
+ scheme with IANA and fully conforms to the requirements in [RFC2717].
+ This document defines the 'ippget' URL (Uniform Resource Locator)
+ scheme for specifying a unique identifier for an IPP Client which
+ implements IPP 'Get-Notifications' operation specified in this
+ document.
+
+ The intended usage of the 'ippget' URL scheme is COMMON.
+
+ The IPP protocol places a limit of 1023 octets (NOT characters) on
+ the length of a URI (see section 4.1.5 'uri' in [RFC2911]). An IPP
+ Printer MUST return the 'client-error-request-value-too-long' status
+ code (see section 13.1.4.10 in [RFC2911]) when a URI received in a
+ request is too long.
+
+ Note: IPP Clients and IPP Printers ought to be cautious about
+ depending on URI lengths above 255 bytes, because some older client
+ or proxy implementations might not properly support these lengths.
+
+ An 'ippget' URL MUST be represented in absolute form. Absolute URLs
+ always begin with a scheme name followed by a colon. For definitive
+ information on URL syntax and semantics, see "Uniform Resource
+ Identifiers (URI): Generic Syntax and Semantics" [RFC2396]. This
+ specification adopts the definitions of "authority", "abs_path",
+ "query", "reg_name", "server", "userinfo", and "hostport" from
+ [RFC2396], as updated by [RFC2732] and [RFC2373] (for IPv6 addresses
+ in URLs).
+
+ The 'ippget' URL scheme syntax in ABNF is as follows:
+
+ ippget_URL = "ippget:" "//" authority [ abs_path [ "?" query ]]
+ authority = server | reg_name
+ reg_name = 1*( unreserved | escaped | "$" | "," |
+ ";" | ":" | "@" | "&" | "=" | "+" )
+ server = [ [ userinfo "@" ] hostport ]
+ userinfo = *( unreserved | escaped |
+ ";" | ":" | "&" | "=" | "+" | "$" | "," )
+
+Herriot, et al. Expires: August 28, 2001 [page 22]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ hostport = host [ ":" port ]
+ abs_path = "/" path_segments
+
+ If the port is empty or not given, then no port is assumed. The
+ semantics are that the 'ippget' URL is a unique identifier for an IPP
+ Client that will retrieve IPP event notifications via the IPP Get-
+ Notifications operation.
+
+ Note: The use of IP addresses in URLs SHOULD be avoided whenever
+ possible (see [RFC1900]).
+
+
+9.5.1 IPPGET URL Examples
+
+ The following are examples of valid 'ippget' URLs for IPP Clients
+ (using DNS host names):
+
+ ippget://abc.com
+ ippget://abc.com/listener
+ ippget://bob@abc.com/listener/1232
+
+ Note: The use of IP addresses in URLs SHOULD be avoided whenever
+ possible (see [RFC1900]).
+
+ The choice of 'userinfo@hostport' versus the simpler 'hostport'
+ production in an 'ippget' URL may be influenced by the intended
+ usage.
+
+ If a given IPP Client creates an IPP Subscription object for event
+ notifications intended for retrieval by the same IPP Client, then the
+ simple 'hostport' production may be most appropriate.
+
+ On the other hand, if a given IPP Client creates an IPP Subscription
+ object for event notifications intended for retrieval by a different
+ IPP Client, then the 'userinfo@hostport' production (using, for
+ example, the right-hand side of a 'mailto:' URL, see [RFC2368]) may
+ be most appropriate.
+
+
+9.5.2 IPPGET URL Comparisons
+
+ When comparing two 'ippget' URLs to decide if they match or not, an
+ IPP Client or IPP Printer SHOULD use a case-sensitive octet-by-octet
+ comparison of the entire URLs, with these exceptions:
+
+ - Comparisons of host names MUST be case-insensitive;
+
+ - Comparisons of scheme names MUST be case-insensitive;
+
+ - An empty 'abs_path' is equivalent to an 'abs_path' of "/".
+
+Herriot, et al. Expires: August 28, 2001 [page 23]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ Characters other than those in the "reserved" and "unsafe" sets (see
+ [RFC2396] and [RFC2732]) are equivalent to their ""%" HEX HEX"
+ encoding.
+
+ For example, the following three URIs are equivalent:
+
+ ippget://abc.com/~smith/listener
+
+ ippget://ABC.com/%7Esmith/listener
+
+ ippget://ABC.com:/%7esmith/listener
+
+
+10 Encoding
+
+ This notification delivery method uses the IPP transport and encoding
+ [RFC2910] for the Get-Notifications operation with one extension
+ allocated in [ipp-ntfy]:
+
+
+ Table 7 - The "event-notification-attributes-tag" value
+
+
+ Tag Value (Hex) Meaning
+
+
+ 0x07 "event-notification-attributes-tag"
+
+
+
+11 Conformance Requirements
+
+
+11.1 Conformance for IPP Printers
+
+ IPP Printers that conform to this specification:
+
+ 1. MUST meet the conformance requirements defined in [ipp-ntfy];
+
+ 2. MUST support the Get-Notifications operation defined in section
+ 5;
+
+ 3. MUST support the Subscription object attributes as defined in
+ section 6;
+
+ 4. MUST support the additional values for IPP/1.1 Printer
+ Description attributes defined in section 7.2;
+
+ 5. MUST support the "begin-to-expire-time-interval" Printer
+ Description attribute defined in section 7.3;
+
+Herriot, et al. Expires: August 28, 2001 [page 24]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ 6. MUST support the "redirection-other-site" status code defined
+ 8.1;
+
+ 7. SHOULD reject received 'ippget' URLs in 'application/ipp'
+ request bodies (e.g., in the "notify-recipient-uri" attribute in
+ a Get-Notifications request) that do not conform to the ABNF for
+ 'ippget' URLs specified in section 9.5 of this document;
+
+ 8. MUST listen for the IPP Get-Notifications operation requests on
+ IANA-assigned well-known port 631, unless explicitly configured
+ by system administrators or site policies;
+
+ 9. SHOULD NOT listen for IPP Get-Notifications operation requests
+ on any other port, unless explicitly configured by system
+ administrators or site policies.
+
+
+11.2 Conformance for IPP Clients
+
+ IPP Clients that conform to this specification:
+
+ 1.MUST create unambiguously unique 'ippget' URLs in all cases;
+
+ 2.MUST send 'ippget' URLs (e.g., in the "notify-recipient-uri"
+ attribute in a Get-Notifications request) that conform to the
+ ABNF specified in section 9.5 of this document;
+
+ 3.MUST send IPP Get-Notifications operation requests via the port
+ specified in the associated 'ipp' URL (if present) or otherwise
+ via IANA assigned well-known port 631;
+
+ 4.MUST convert the associated 'ipp' URLs to their corresponding
+ 'http' URL forms according to the rules in section 5 "IPP URL
+ Scheme" in [RFC2910].
+
+ Note: The use of ambiguous 'ippget' URLs is NOT an optional feature
+ for IPP Clients; it is a non-conformant implementation error.
+
+
+12 IANA Considerations
+
+ IANA is requested to register the 'ippget' URL scheme as defined in
+ section 9 according to the procedures of [RFC2717].
+
+ The rest of this section contains the exact information for
+ additional IPP entities for IANA to add to the IPP Registries
+ according to the procedures defined in RFC 2911 [RFC2911] section 6.
+
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 25]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ Note to RFC Editors: Replace RFC NNNN below with the RFC number
+ for this document, so that it accurately reflects the content of
+ the information for the IANA Registry.
+
+
+12.1 Operation Registrations
+
+ The operations defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.4 with
+ the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/operations/
+
+ The registry entry will contain the following information:
+
+ Operations: Ref. Section:
+ Get-Notifications operation RFC NNNN 5
+
+
+12.2 Additional values of existing attributes
+
+
+12.2.1 Additional values for the "notify-schemes-supported" Printer
+ attribute
+
+ The "notify-schemes-supported" 'uriScheme' attribute value defined in
+ this document will be published by IANA according to the procedures
+ in RFC 2911 [RFC2911] section 6.1 with the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-values/notify-schemes-
+ supported/
+
+ The registry entry will contain the following information:
+
+ Ref. Section:
+ ippget RFC NNNN 7.2.1
+
+
+12.2.2 Additional values for the "operations-supported" Printer
+ attribute
+
+ The "operations-supported" type2 enum attribute value defined in this
+ document will be published by IANA according to the procedures in RFC
+ 2911 [RFC2911] section 6.1 with the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-values/operations-
+ supported/
+
+ The registry entry will contain the following information:
+
+
+Herriot, et al. Expires: August 28, 2001 [page 26]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ Value Ref. Section:
+ Get-Notifications 0x001C RFC NNNN 7.2.2
+
+
+12.3 Attribute Registrations
+
+ The attributes defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.2 with
+ the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/attributes/
+
+ The registry entry will contain the following information:
+
+ Printer Description attributes: Ref. Section:
+ begin-to-expire-time-interval (integer(0:MAX)) RFC NNNN 7.3
+
+12.4 Status code Registrations
+
+ The status codes defined in this document will be published by IANA
+ according to the procedures in RFC 2911 [RFC2911] section 6.6 with
+ the following path:
+
+ ftp.isi.edu/iana/assignments/ipp/status-codes/
+
+ The registry entry will contain the following information:
+
+ Status codes: Ref. Section:
+ redirection-other-site (0x300) RFC NNNN 8.1
+
+
+13 Internationalization Considerations
+
+ The IPP Printer MUST localize the "notify-text" attribute as
+ specified in section 14 of [ipp-ntfy].
+
+ In addition, when the client receives the Get-Notifications response,
+ it is expected to localize the attributes that have the 'keyword'
+ attribute syntax according to the charset and natural language
+ requested in the Get-Notifications request.
+
+
+14 Security Considerations
+
+ The IPP Model and Semantics document [RFC2911] discusses high-level
+ security requirements (Client Authentication, Server Authentication
+ and Operation Privacy). Client Authentication is the mechanism by
+ which the client proves its identity to the server in a secure
+ manner. Server Authentication is the mechanism by which the server
+ proves its identity to the client in a secure manner. Operation
+
+Herriot, et al. Expires: August 28, 2001 [page 27]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ Privacy is defined as a mechanism for protecting operations from
+ eavesdropping.
+
+ Unlike other Event Notification delivery methods in which the IPP
+ Printer initiates the Event Notification, with the method defined in
+ this document, the Notification Recipient is the client who s the
+ Get-Notifications operation. Therefore, there is no chance of "spam"
+ notifications with this method. Furthermore, such a client can close
+ down the HTTP channel at any time, and so can avoid future unwanted
+ Event Notifications at any time.
+
+
+15 References
+
+ [ipp-iig]
+ Hastings, T., Manros, C., Kugler, K, Holst H., Zehler, P.,
+ "Internet Printing Protocol/1.1: draft-ietf-ipp-implementers-
+ guide-v11-02.txt, work in progress, January 25, 2001
+
+ [ipp-ntfy]
+ R. Herriot, Hastings, T., Isaacson, S., Martin, J., deBry, R.,
+ Shepherd, M., Bergman, R., "Internet Printing Protocol/1.1: IPP
+ Event Notification Specification", <draft-ietf-ipp-not-spec-
+ 06.txt>, February 24, 2001.
+
+ [RFC1900]
+ B. Carpenter, Y. Rekhter. Renumbering Needs Work, RFC 1900,
+ February 1996.
+
+ [RFC2026]
+ S. Bradner, "The Internet Standards Process -- Revision 3", RFC
+ 2026, October 1996.
+
+ [RFC2119]
+ S. Bradner, "Key words for use in RFCs to Indicate Requirement
+ Levels", RFC 2119 , March 1997
+
+ [RFC2368]
+ P. Hoffman, L. Masinter, J. Zawinski. The "mailto" URL Scheme, RFC
+ 2368, July 1998.
+
+ [RFC2373]
+ R. Hinden, S. Deering. IP Version 6 Addressing Architecture, RFC
+ 2373, July 1998.
+
+ [RFC2396]
+ Berners-Lee, T. et al. Uniform Resource Identifiers (URI): Generic
+ Syntax, RFC 2396, August 1998
+
+
+
+Herriot, et al. Expires: August 28, 2001 [page 28]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ [RFC2567]
+ Wright, D., "Design Goals for an Internet Printing Protocol", RFC
+ 2567, April 1999.
+
+ [RFC2568]
+ Zilles, S., "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", RFC 2568, April 1999.
+
+ [RFC2569]
+ Herriot, R., Hastings, T., Jacobs, N., Martin, J., "Mapping between
+ LPD and IPP Protocols", RFC 2569, April 1999.
+
+ [RFC2616]
+ R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P.
+ Leach, T. Berners-Lee, "Hypertext Transfer Protocol - HTTP/1.1",
+ RFC 2616, June 1999.
+
+ [RFC2717]
+ R. Petke and I. King, "Registration Procedures for URL Scheme
+ Names", RFC 2717, November 1999.
+
+ [RFC2732]
+ R. Hinden, B. Carpenter, L. Masinter. Format for Literal IPv6
+ Addresses in URL's, RFC 2732, December 1999.
+
+ [RFC2910]
+ Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet Printing
+ Protocol/1.1: Encoding and Transport", RFC 2910, September 2000.
+
+ [RFC2911]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell,
+ "Internet Printing Protocol/1.1: Model and Semantics", RFC 2911,
+ September 2000.
+
+
+16 Authors' Addresses
+
+
+ Robert Herriot
+ Xerox Corp.
+ 3400 Hill View Ave, Building 1
+ Palo Alto, CA 94304
+
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ e-mail: robert.herriot@pahv.xerox.com
+
+
+ Carl Kugler
+ IBM
+
+Herriot, et al. Expires: August 28, 2001 [page 29]
+
+
+INTERNET-DRAFT IPP: The 'ippget' Delivery Method February 28, 2001
+
+
+ P.O. Box 1900
+ Boulder, CO 80301-9191
+
+ Phone:
+ Fax:
+ e-mail: kugler@us.ibm.com
+
+ Harry Lewis
+ IBM
+ P.O. Box 1900
+ Boulder, CO 80301-9191
+
+ Phone: 303-924-5337
+ FAX:
+ e-mail: harryl@us.ibm.com
+
+
+17 Full Copyright Statement
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+Herriot, et al. Expires: August 28, 2001 [page 30]
diff --git a/standards/draft-ietf-ipp-notify-mailto-03.txt b/standards/draft-ietf-ipp-notify-mailto-03.txt
new file mode 100644
index 000000000..4be0dd94e
--- /dev/null
+++ b/standards/draft-ietf-ipp-notify-mailto-03.txt
@@ -0,0 +1,1740 @@
+
+
+
+
+
+
+INTERNET-DRAFT
+<draft-ietf-ipp-notify-mailto-03.txt> Robert Herriot
+Category: standards track Xerox Corp.
+ Henrik Holst
+ i-data international a/s
+ Tom Hastings
+ Xerox Corp.
+ Carl-Uno Manros
+ Xerox Corp.
+ August 30, 2000
+
+ Internet Printing Protocol (IPP):
+ The 'mailto' Delivery Method for Event Notifications
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+Status of this Memo
+
+This document is an Internet-Draft and is in full conformance with all
+provisions of Section 10 of [RFC2026]. Internet-Drafts are working
+documents of the Internet Engineering Task Force (IETF), its areas, and
+its working groups. Note that other groups may also distribute working
+documents as Internet-Drafts.
+
+Internet-Drafts are draft documents valid for a maximum of six months
+and may be updated, replaced, or obsoleted by other documents at any
+time. It is inappropriate to use Internet-Drafts as reference material
+or to cite them other than as "work in progress".
+
+The list of current Internet-Drafts can be accessed at
+http://www.ietf.org/ietf/1id-abstracts.txt
+
+The list of Internet-Draft Shadow Directories can be accessed as
+http://www.ietf.org/shadow.html.
+
+
+Abstract
+
+
+The notification extension document [ipp-ntfy] defines operations that a
+client can perform in order to create Subscription Objects in a Printer
+and carry out other operations on them. The Subscription Object
+specifies that when one of the specified Events occurs, the Printer
+sends an asynchronous Event Notification to the specified Notification
+Recipient via the specified Delivery Method (i.e., protocol).
+
+
+The notification extension document [ipp-ntfy] specifies that each
+Delivery Method is defined in another document. This document is one
+such document, and it specifies the 'mailto' delivery method.
+
+Herriot, et al. Expires: March 1, 2001 [page 1]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+For this Delivery Method, when an Event occurs, the Printer immediately
+sends an Event Notification via an email message to the Notification
+Recipient specified in the Subscription Object. The message body of the
+email consists of Human Consumable text that is not intended to be
+parsed by a machine.
+
+
+The Notification Recipient receives the Event Notification in the same
+way as it receives any other email message.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 2]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+The basic set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics [ipp-mod]
+ Internet Printing Protocol/1.1: Encoding and Transport [ipp-pro]
+ Internet Printing Protocol/1.1: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+ Internet Printing Protocol (IPP): IPP Event Notification
+ Specification [ipp-ntfy]
+
+The "Design Goals for an Internet Printing Protocol" document takes a
+broad look at distributed printing functionality, and it enumerates
+real-life scenarios that help to clarify the features that need to be
+included in a printing protocol for the Internet. It identifies
+requirements for three types of users: end users, operators, and
+administrators. It calls out a subset of end user requirements that are
+satisfied in IPP/1.0. A few OPTIONAL operator operations have been
+added to IPP/1.1.
+
+The "Rationale for the Structure and Model and Protocol for the Internet
+Printing Protocol" document describes IPP from a high level view,
+defines a roadmap for the various documents that form the suite of IPP
+specification documents, and gives background and rationale for the IETF
+working group's major decisions.
+
+The "Internet Printing Protocol/1.1: Model and Semantics" document
+describes a simplified model with abstract objects, their attributes,
+and their operations that are independent of encoding and transport. It
+introduces a Printer and a Job object. The Job object optionally
+supports multiple documents per Job. It also addresses security,
+internationalization, and directory issues.
+
+The "Internet Printing Protocol/1.1: Encoding and Transport" document is
+a formal mapping of the abstract operations and attributes defined in
+the model document onto HTTP/1.1 [RFC2616]. It defines the encoding
+rules for a new Internet MIME media type called "application/ipp". This
+document also defines the rules for transporting over HTTP a message
+body whose Content-Type is "application/ipp". This document also
+defines a new scheme named 'ipp' for identifying IPP printers and jobs.
+
+The "Internet Printing Protocol/1.1: Implementer's Guide" document gives
+insight and advice to implementers of IPP clients and IPP objects. It
+is intended to help them understand IPP/1.1 and some of the
+considerations that may assist them in the design of their client and/or
+IPP object implementations. For example, a typical order of processing
+requests is given, including error checking. Motivation for some of the
+specification decisions is also included.
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 3]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+The "Mapping between LPD and IPP Protocols" document gives some advice
+to implementers of gateways between IPP and LPD (Line Printer Daemon)
+implementations.
+
+
+The "Event Notification Specification" document describes an extension
+to the IPP/1.0, IPP/1.1, and future versions. This extension allows a
+client to subscribe to printing related Events. The Subscription Object
+specifies that when one of the specified Event occurs, the Printer sends
+an asynchronous Event Notification to the specified Notification
+Recipient via the specified Delivery Method (i.e., protocol). A client
+associates Subscription Objects with a particular Job by performing the
+Create-Job-Subscriptions operation or by submitting a Job with
+subscription information. A client associates Subscription Objects with
+the Printer by performing a Create-Printer-Subscriptions operation.
+Four other operations are defined for Subscription Objects: Get-
+Subscriptions-Attributes, Get-Subscriptions, Renew-Subscription, and
+Cancel-Subscription.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 4]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+ Table of Contents
+
+1 Introduction ......................................................7
+
+2 Terminology .......................................................7
+
+3 Model and Operation ...............................................7
+
+4 General Information ...............................................9
+
+5 Subscription Template Attributes .................................11
+ 5.1 Additional Subscription Template Attributes ...................11
+ 5.1.1 notify-mailto-text-only (boolean)..........................11
+ 5.2 Additional Information about Subscription Template Attributes .12
+ 5.2.1 notify-recipient-uri (uri).................................12
+ 5.2.2 notify-user-data (octetString(63)).........................12
+
+6 Event Notification Content .......................................13
+ 6.1 Headers .......................................................13
+ 6.1.1 'Date' header..............................................13
+ 6.1.2 'From' header..............................................14
+ 6.1.3 'Subject' header...........................................14
+ 6.1.4 'Sender' header............................................15
+ 6.1.5 'Reply-to' header..........................................15
+ 6.1.6 'To' header................................................15
+ 6.1.7 'Content-type' header......................................16
+ 6.2 Message Body ..................................................16
+ 6.3 Plain Text Content ............................................17
+ 6.3.1 Event Notification Content Common to All Events............18
+ 6.3.2 Additional Event Notification Content for Job Events.......20
+ 6.3.3 Additional Event Notification Content for Printer Events...21
+ 6.4 Examples ......................................................21
+ 6.4.1 Job Event Example..........................................22
+ 6.4.2 Printer Event Example......................................23
+ 6.4.3 Printer Event Example (localized to Danish)...............24
+
+7 Conformance Requirements .........................................25
+
+8 IANA Considerations ..............................................26
+
+9 Internationalization Considerations ..............................26
+
+10 Security Considerations ..........................................26
+
+11 References .......................................................27
+
+12 Author's Addresses ...............................................28
+
+13 Full Copyright Statement .........................................29
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 5]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+ Table of Tables
+
+Table 1 - Information about the Delivery Method.......................9
+
+
+Table 2 - Additional Subscription Template Attributes................11
+
+
+Table 3 - Printer Name in Event Notification Content.................19
+
+
+Table 4 - Event Name in Event Notification Content...................19
+
+
+Table 5 - Job Name in Event Notification Content.....................20
+
+
+Table 6 - Job State in Event Notification Content....................20
+
+
+Table 7 - Printer State in Event Notification Content................21
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 6]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+1 Introduction
+
+The notification extension document [ipp-ntfy] defines operations that a
+client can perform in order to create Subscription Objects in a Printer
+and carry out other operations on them. A Subscription Object represents
+a Subscription abstraction. The Subscription Object specifies that when
+one of the specified Events occurs, the Printer sends an asynchronous
+Event Notification to the specified Notification Recipient via the
+specified Delivery Method (i.e., protocol).
+
+
+The notification extension document [ipp-ntfy] specifies that each
+Delivery Method is defined in another document. This document is one
+such document, and it specifies the 'mailto' delivery method.
+
+
+For this Delivery Method, when an Event occurs, the Printer immediately
+sends an Event Notification via an email message to the Notification
+Recipient specified in the Subscription Object. The message body of the
+email consists of Human Consumable text that is not intended to be
+parsed by a machine. The 'mailto' Delivery Method is a 'push' Delivery
+Method as defined in [ipp-ntfy].
+
+
+The Notification Recipient receives the Event Notification in the same
+way as it receives any other email message.
+
+
+2 Terminology
+
+This section defines the following terms that are used throughout this
+document:
+
+
+Capitalized terms, such as MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT,
+MAY, NEED NOT, and OPTIONAL, have special meaning relating to
+conformance to this specification. These terms are defined in [ipp-mod
+section 13.1 on conformance terminology, most of which is taken from RFC
+2119 [RFC2119].
+
+
+For capitalized terms that appear in this document, see [ipp-ntfy].
+
+
+3 Model and Operation
+
+In a Subscription Creation Operation, when the value of the "notify-
+recipient-uri" attribute contains the scheme "mailto", the client is
+requesting that the Printer use the 'mailto' Delivery Method for Event
+Notifications generated from the new Subscription Object.
+
+
+Herriot, et al. Expires: March 1, 2001 [page 7]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+For this Delivery Method, the "notify-recipient-uri" attribute value
+MUST consist of a "mailto" scheme followed by a colon, and then followed
+by an address part (e.g. 'mailto:smith@abc.com'). See section 5.2.1 for
+the syntax of the "notify-recipient-uri" attribute value for this
+Delivery Method.
+
+
+A Printer MUST support SMTP [RFC821], and it MAY support other email
+protocols. A Printer MAY use additional services, such as SMTP delivery
+status notification [RFC1891] or S/MIME encryption [RFC2633].
+
+
+If the client wants the Printer to send Event Notifications via the
+'mailto' Delivery Method, the client MUST choose a value for "notify-
+recipient-uri" attribute which conforms to the rules of section 5.2.1.
+To avoid denial-of-service attacks, a client SHOULD NOT use distribution
+lists as the Notification Recipient.
+
+
+When an Event occurs, the Printer MUST immediately:
+
+
+ 1. Find all pertinent Subscription Objects P according to the rules of
+ section 9 of [ipp-ntfy], AND
+
+
+ 2. Find the subset M of these Subscription Objects P whose "notify-
+ recipient-uri" attribute has a scheme value of 'mailto', AND
+
+
+ 3. For each Subscription Object in M, the Printer MUST
+
+
+ a)generate an email message as specified in section 5.2.2 AND
+
+
+ b)send the email message to the Notification Recipient specified
+ by the address part of the "notify-recipient-uri" attribute
+ value (see section 5.2.1).
+
+
+If the Printer supports only SMTP, it MUST send the email message via
+SMTP. If the Printer supports additional email protocols, it MUST
+determine the protocol from the address part of the "notify-recipient-
+uri" attribute value and then send the email message via the appropriate
+email protocol.
+
+
+When a Subscribing Client is subscribing to the 'job-progress' event
+(which is a frequently occurring event), it SHOULD supply the "notify-
+
+
+Herriot, et al. Expires: March 1, 2001 [page 8]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+time-interval" attribute (see [ipp-ntfy]) in the Subscription Creation
+request with a suitable value to limit the time between 'job-progress'
+Event Notifications sent by the Printer.
+
+
+4 General Information
+If a Printer supports this Delivery Method, the following are its
+characteristics.
+
+
+ Table 1 - Information about the Delivery Method
+
+
+
+ Document Method Conformance Delivery Method Realization
+ Requirement
+
+
+ 1.What is the URL scheme name mailto
+ for the Delivery Method?
+
+ 2.Is the Delivery Method
+ REQUIRED, RECOMMENDED, or
+ OPTIONAL for an IPP Printer to RECOMMENDED
+ support?
+
+ 3.What transport and delivery A Printer MUST support SMTP. It MAY
+ protocols does the Printer use support other email protocols.
+ to deliver the Event
+ Notification Content, i.e.,
+ what is the entire network
+ stack?
+
+ 4.Can several Event A Printer implementation MAY
+ Notifications be combined into combine several Event Notifications
+ a Compound Event Notification? into a single email message.
+
+ 5.Is the Delivery Method This Delivery Method is a push.
+ initiated by the Notification
+ Recipient (pull), or by the
+ Printer (push)?
+
+ 6.Is the Event Notification Human Consumable
+ content Machine Consumable or
+ Human Consumable?
+
+ 7.What section in this document Section 6
+ answers the following
+ question? For a Machine
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 9]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+
+ Consumable Event Notification,
+ what is the representation and
+ encoding of values defined in
+ section 9.1 of [ipp-ntfy] and
+ the conformance requirements
+ thereof? For a Human
+ Consumable Event Notification,
+ what is the representation and
+ encoding of pieces of
+ information defined in section
+ 9.2 of [ipp-ntfy] and the
+ conformance requirements
+ thereof?
+
+ 8.What are the latency and Same as the underlying SMTP (or
+ reliability of the transport other optional) email transport
+ and delivery protocol?
+
+ 9.What are the security aspects Same as the underlying SMTP (or
+ of the transport and delivery other optional) email transport
+ protocol, e.g., how it is
+ handled in firewalls?
+
+ 10. What are the content length None
+ restrictions?
+
+ 11. What are the additional None
+ values or pieces of
+ information that a Printer
+ sends in an Event Notification
+ content and the conformance
+ requirements thereof?
+
+ 12. What are the additional See section 5.1.1 on "notify-
+ Subscription Template and/or mailto-text-only"
+ Subscription Description
+ attributes and the conformance
+ requirements thereof?
+
+ 13. What are the additional None
+ Printer Description attributes
+ and the conformance
+ requirements thereof?
+
+
+
+
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 10]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+5 Subscription Template Attributes
+
+5.1 Additional Subscription Template Attributes
+
+
+This Delivery Method introduces one additional Subscription Template
+Attribute (See Table 2).
+
+
+ Table 2 - Additional Subscription Template Attributes
+
+
+
+Attribute in Subscription Default and Supported Printer
+Object Attributes
+
+
+notify-mailto-text-only N/A
+(boolean)
+
+
+5.1.1notify-mailto-text-only (boolean)
+
+
+When the Printer generates an Event Notification from a Subscription
+Object, this attribute specifies whether the Printer generates the Event
+Notification with only plain text (i.e. 'text/plain') or with Content-
+Types that the Printer chooses.
+
+
+The Printer MUST support this attribute if it supports the 'mailto'
+Delivery Method.
+
+
+A client MAY supply this attribute. If a client does not supply this
+attribute, the Printer MUST populate this attribute with the value of
+'false' on the Subscription Object. There is no "notify-mailto-text-
+only-default" attribute.
+
+
+If the value of this attribute is 'true' in a Subscription Object, the
+message body of each Event Notification that the Printer generates from
+the Subscription Object MUST contain plain text only (i.e. 'text/plain'
+with the charset specified by the "notify-charset' Subscription Object
+attribute).
+
+
+If the value of this attribute is 'false' in a Subscription Object, the
+Content-Type of the message body of each Event Notification that the
+Printer generates from the Subscription Object MUST be either
+
+
+Herriot, et al. Expires: March 1, 2001 [page 11]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+'text/plain' or 'multipart', depending on implementation. If the
+Content-Type is 'multipart', one message body of the 'multipart' MUST be
+the same as the 'text/plain' message body when this attribute has the
+value of 'true'. Each of the other message bodies of the 'multipart' MAY
+be any Content-Type (e.g. 'text/html', 'image/gif', 'audio/basic',
+etc.).
+
+
+A Printer MUST support both values ('true' and 'false') of this
+attribute. There is no "notify-mailto-text-only-supported" attribute.
+
+
+5.2 Additional Information about Subscription Template Attributes
+
+
+This section describes additional values for attributes defined in [ipp-
+ntfy].
+
+
+5.2.1notify-recipient-uri (uri)
+
+This section describes the syntax of the value of this attribute for the
+'mailto' Delivery Method. The syntax for values of this attribute for
+other Delivery Method is defined in other Delivery Method Documents.
+
+
+In order to support the 'mailto' Delivery Method, the Printer MUST
+support the following syntax for the 'mailto' Delivery Method when the
+Printer uses SMTP. The line below use RFC 822 syntax rules and terms.
+
+
+ "mailto:" mailbox
+
+Note: the above syntax allows 1 occurrence of 'mailbox'. The occurrence
+of 'mailbox' represents an email address of a Notification Recipient.
+
+For SMTP, the phrase 'address part' of the "notify-recipient-uri"
+attribute value refers to the 'mailbox' part of the value.
+
+The Printer MAY support other syntax for the 'address part' if it
+supports email protocols in addition to SMTP.
+
+
+5.2.2notify-user-data (octetString(63))
+
+This attributes has a special use for the 'mailto' Delivery Method. It
+specifies the email address of the Subscribing Client. It is primarily
+useful when the Notification Recipient is some person other than the
+Subscribing Client. Then the Notification Recipient has a way to reply
+to the Subscribing Client.
+
+
+Herriot, et al. Expires: March 1, 2001 [page 12]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+If a client specifies this Delivery Method in a Subscription Creation
+Operation, and the specified Notification Recipient is not associated
+with the same person as the client, the client SHOULD supply its email
+address as the value of the "notify-user-data" attribute. If the client
+does not supply this attribute, the Printer MUST NOT populate the
+Subscription Object with this attribute.
+
+
+6 Event Notification Content
+
+This section describes the content of an Event Notification sent via the
+'mailto' Delivery Method using the SMTP protocol. This document does
+not describe the content for other email protocols, but an
+implementation should use this section as a model.
+
+
+When a Printer sends an email message via SMTP, the content MUST conform
+to RFC 822. The following sections define the content that a Printer
+MUST send. A Printer MAY send additional content as long as the
+resulting content conforms to RFC 822.
+
+
+Each subsection below specifies the syntax that pertains to the
+subsection. The syntax rules and syntactic terms (e.g. 'date-time') in
+each subsection come from RFC 822, except for the section on "Content-
+Type" which comes from RFC 1521.
+
+
+The Event Notification content has two parts, the headers and the
+message body. The headers precede the message body and are separated by
+a blank line (see [RFC 822]).
+
+
+6.1 Headers
+
+
+When a Printer sends an Event Notification via SMTP, it MUST include the
+following headers. RFC 822 RECOMMENDS that the headers be in the order
+that they appear below.
+
+
+6.1.1'Date' header
+
+Syntax: "Date" ":" date-time
+
+This header contains the date and time that the Event occurred.
+
+The Printer MUST include a "Date" header if and only if it supports the
+"printer-current-time" Printer attribute.
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 13]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+6.1.2 'From' header
+
+Syntax: "From" ":" mailbox
+
+ where
+
+ mailbox = addr-spec / phrase route-addr
+
+This header causes a typical email reader to show the email as coming
+from the Printer that is sending the Event Notification.
+
+The Printer MUST include a "From" header whose syntax is specified
+above.
+
+The Printer MUST use the second alternative of the syntax for 'mailbox'
+defined above (i.e. 'phrase route-addr'). The 'phrase' is the
+Printer's display name and it MUST be the value of the "printer-name"
+Printer attribute. The 'route-addr' MUST contain an email address
+(inside angle brackets) belonging to either an administrator or the
+output-device. This email address NEED NOT be capable of receiving mail.
+There is no Printer attribute to hold this email address, so that it
+cannot be configured using the IPP protocol without an implementation-
+defined attribute extension.
+
+
+6.1.3'Subject' header
+
+Syntax: "Subject" ":" *text
+
+This header specifies the subject of the message and contains a short
+summary of the Event Notification.
+
+The Printer MUST include a "Subject" header whose syntax is specified
+above.
+
+
+The Printer MUST localize the '*text' using the values of the "notify-
+charset" and "notify-natural-language" Subscription Object attributes.
+
+For Printer Events, the '*text' SHOULD start with the localized word
+"printer:", followed by the Printer name, and then followed by the
+localized Event name, e.g., in English: "printer: 'tiger' stopped" or in
+Danish: 'Printeren 'tiger' er standset'.
+
+For Job Events, the '*text' SHOULD start with the localized phrase
+"print job:", followed by the Job name, and then followed by the
+localized Event name, e.g., in English: "print job: 'financials'
+completed".
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 14]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+The wording is implementation dependent. A Notification Recipient MUST
+NOT expect to be able to parse this text. But an email filter might look
+for "printer" or "print job".
+
+
+6.1.4 'Sender' header
+
+Syntax: "Sender" ":" mailbox
+
+This header causes a typical email reader to show the email as coming on
+behalf of the person associated with the Subscribing Client.
+
+
+If the Subscription Object contains the "notify-user-data" attribute,
+and if its value satisfies the RFC 822 syntax rules for 'mailbox', the
+Printer MUST include a "Sender" header whose syntax is specified above.
+Otherwise, the Printer MUST NOT include a "Sender" header.
+
+For the "Sender" header, the 'mailbox' MUST be the value of the "notify-
+user-data" Subscription Object attribute. See section 5.2.2 for details
+about the "notify-user-data" attribute.
+
+
+6.1.5 'Reply-to' header
+
+Syntax: "Reply-to" ":" mailbox
+
+If the Notification Recipient replies to Event Notification email, this
+header causes a typical email reader to send email to the person acting
+as the Subscribing Client. The rules are identical to the "Sender"
+header.
+
+
+If the Subscription Object contains the "notify-user-data" attribute,
+and if its value satisfies the RFC 822 syntax rules for "mailbox", the
+Printer MUST include a "Reply-to" header whose syntax is specified
+above. Otherwise, the Printer MUST NOT include a "Reply-to" header.
+
+For the "Reply-to" header, the "mailbox" MUST be the value of the
+"notify-user-data" Subscription Object attribute. See section 5.2.2 for
+details about the "notify-user-data" attribute.
+
+
+6.1.6 'To' header
+
+
+Syntax: "To" ":" 1#mailbox
+
+See [RFC 1521] for the syntax.
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 15]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+This header specifies the Notification Recipient(s).
+
+The Printer MUST include a "To" header whose syntax is specified above.
+
+The '1#mailbox' MUST be the '1#mailbox' part of the value of the
+"notify-recipient-uri" Subscription attribute, i.e. the part after the
+"mailto:".
+
+
+6.1.7 'Content-type' header
+
+
+Syntax: "Content-Type" ":" type "/" subtype *(";"parameter)
+
+ See [RFC 1521] for the syntactic terms (e.g. 'type').
+
+This header specifies the format of the message body.
+
+The Printer MUST include the "Content-Type" header.
+
+The "notify-mailto-text-only" attribute determines the 'type' and
+'subtype' values. The possible values are "text/plain" and "multipart"
+values.
+
+
+6.2 Message Body
+
+
+The message body MUST contain Human Consumable content as plain text. It
+MAY also contain other types of implementation dependent content.
+
+
+For plain text, the Content-Type of Human Consumable content MUST be
+'text/plain'. For implementation dependent content, the Content-Type of
+Human Consumable content MUST be 'multipart'. The Content-Type of one
+body part MUST be 'text/plain' and the Content-Types of the other body
+parts are implementation dependent. See section 6.3 for a description of
+plain text content.
+
+
+The following table shows the Content-Type of the message body for the
+"notify-mailto-text-only" attribute:
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 16]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+
+
+ "notify- Content-Type Message Body
+ mailto-text- of Message
+ only" Body
+ attribute
+
+
+ false 'text/plain' Human Consumable
+
+ true 'text/plain' Human Consumable plain
+ or* text
+
+ 'multipart' Human Consumable where
+ one body part is plain
+ text
+
+
+
+ * The Content-Type depends on the implementation. A Printer MAY send
+ 'text/plain' only or it MAY send several body parts of various
+ Content-Types within a message body whose Content-Type is
+ 'multipart'.
+
+
+6.3 Plain Text Content
+
+
+When a Printer sends a plain text message, it MUST localize the text
+using the values of the "notify-charset" and "notify-natural-language"
+Subscription Object attributes.
+
+
+Section 9.2 in [ipp-ntfy] specifies the information that a Delivery
+Method MUST specify and a Printer SHOULD send.
+
+
+A Printer SHOULD send the following localized information in the message
+body. The specific wording of this information and its layout are
+implementation dependent.
+
+ a)the Printer name (see Table 3)
+ b)omitted (see below).
+ c)for Printer Events only:
+ i) the Event (see Table 4) and/or Printer state information
+ (see Table 7)
+ d)for Job Events only:
+ i) the job identity (see Table 5)
+ ii) the Event (see Table 4) and/or Job state information (see
+ Table 6)
+
+
+Herriot, et al. Expires: March 1, 2001 [page 17]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+Item b) in the above list is omitted because the Printer sends the time
+of the Event as an email header (see section 6.1.1 on the 'Date'
+header).
+
+
+The subsections of this section specify the attributes that a Printer
+MUST use to obtain this information.
+
+
+The Printer MAY send additional information, depending on
+implementation.
+
+
+Notification Recipients MUST NOT expect to be able to parse the message.
+
+
+The next three sections define the attributes in Event Notification
+Contents that are:
+
+
+ a)for all Events
+
+
+ b)for Job Events only
+
+
+ c)for Printer Events only
+
+
+6.3.1Event Notification Content Common to All Events
+
+
+The Printer MUST send the following information.
+
+
+There is a separate table for each piece of information. Each row in the
+table represents a source value for the information and the values are
+listed in order of preference, with the first one being the preferred
+one. An implementation SHOULD use the source value from the earliest row
+in each table. It MAY use the source value from another row instead, or
+it MAY combine the source values from several rows. An implementation is
+free to determine the best way to present this information.
+
+
+The tables in this section and following sections contain the following
+columns for each piece of information:
+
+
+ a)Source of Value: the name of the attribute that supplies the
+ value for the Event Notification
+
+
+Herriot, et al. Expires: March 1, 2001 [page 18]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+ b)Sends:
+
+ MAY: this is the only value used in the tables. It means that
+ the Printer OPTIONALLY sends this value. However, the Printer
+ SHOULD use at least one value from each table.
+
+
+ c)Source Object: the object from which the source value comes.
+
+
+Table 3 lists the source of the information for the Printer Name. The
+"printer-name" is more user-friendly unless the Notification Recipient
+is in a place where the Printer name is not meaningful. For example, an
+implementation could have the intelligence to send the value of the
+"printer-name" attribute to a Notification Recipient that can access the
+Printer via value of the "printer-name" attribute and otherwise send the
+value of the "notify-printer-uri" attribute.
+
+
+ Table 3 - Printer Name in Event Notification Content
+
+
+
+Source Value Sends Source Object
+
+
+printer-name (name(127)) MAY Printer
+
+notify-printer-uri (uri) MAY Subscription
+
+
+
+
+
+Table 4 lists the source of the information for the Event name. A
+Printer MAY combine this information with state information described
+for Jobs in Table 6 or for Printers in Table 7.
+
+
+ Table 4 - Event Name in Event Notification Content
+
+
+
+Source Value Sends Source Object
+
+
+notify-subscribed-event (type2 keyword) MAY Subscription
+
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 19]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+6.3.2Additional Event Notification Content for Job Events
+
+
+This section lists the source of the additional information that a
+Printer MUST send for Job Events.
+
+
+Table 5 lists the source of the information for the job name. The "job-
+name" is likely more meaningful to a user than "job-id".
+
+
+ Table 5 - Job Name in Event Notification Content
+
+
+
+Source Value Sends Source Object
+
+
+job-name (name(MAX)) MAY Job
+
+job-id (integer(1:MAX)) MAY Job
+
+
+
+
+
+Table 6 lists the source of the information for the job-state. If a
+Printer supports the "job-state-message" and "job-detailed-state-
+message" attributes, it SHOULD use those attributes for the job state
+information, otherwise, it should fabricate such information from the
+"job-state" and "job-state-reasons". For some Events, a Printer MAY
+combine this information with Event information.
+
+
+ Table 6 - Job State in Event Notification Content
+
+
+
+Source Value Sends Source
+ Object
+
+
+job-state-message (text(MAX)) MAY Job
+
+job-detailed-status-messages (1setOf MAY Job
+text(MAX))
+
+job-state (type1 enum) MAY Job
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 20]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+
+
+Source Value Sends Source
+ Object
+
+
+job-state-reasons (1setOf type2 keyword) MAY Job
+
+
+6.3.3Additional Event Notification Content for Printer Events
+
+
+This section lists the source of the additional information that a
+Printer MUST send for Printer Events.
+
+
+Table 7 lists the source of the information for the printer-state. If a
+Printer supports the "printer-state-message", it SHOULD use that
+attribute for the job state information, otherwise it SHOULD fabricate
+such information from the "printer-state" and "printer-state-reasons".
+For some Events, a Printer MAY combine this information with Event
+information.
+
+
+ Table 7 - Printer State in Event Notification Content
+
+
+
+Source Value Sends Source Object
+
+
+printer-state-message (text(MAX)) MAY Printer
+
+printer-state (type1 enum) MAY Printer
+
+printer-state-reasons (1setOf type2 MAY Printer
+keyword)
+
+printer-is-accepting-jobs (boolean) MAY Printer
+
+
+6.4 Examples
+
+
+This section contains three examples. One is a Job Event and the other
+two are Printer Events, the latter in Danish.
+
+
+A Printer implementation NEED NOT generate Event Notification content
+that is identical or even similar to these examples. In fact it would be
+
+
+Herriot, et al. Expires: March 1, 2001 [page 21]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+unfortunate if every implementation copied these example as is. These
+examples merely show some possibilities and are not necessarily the best
+way to convey information about an Event.
+
+
+6.4.1Job Event Example
+
+
+This section contains an example of an Event Notification of a Job
+Event.
+
+
+A Subscribing Client Mike Jones (who works for xyz Corp.) performs a
+Subscription Creation Operation as part of the Print-Job operation on
+Printer "ipp://tiger@abc.com". Mike Jones specifies that the "job-name"
+is "financials". Mike is printing the Job for Bill Smith at abc Corp.
+The Subscription Object then has the following attributes:
+
+
+
+ Attribute Name Attribute Value
+
+
+ notify-recipient-uri mailto:bsmith@abc.com
+
+ notify-events job-completed
+
+ notify-user-data mjones@xyz.com
+
+ notify-mailto-text-only true
+
+ notify-charset us-ascii
+
+ notify-natural-language en-us
+
+ notify-subscription-id 35692
+
+ notify-sequence-number 0
+
+ notify-printer-up-time 34593
+
+ notify-printer-uri ipp://tiger@abc.com
+
+ notify-job-id 345
+
+ notify-subscriber-user- mjones
+ name
+
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 22]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+When the Job completes, the Printer generates and sends the following
+email message:
+
+ Date: 17 Jul 00 1632 PDT
+ From: tiger <printAdmin@abc.com>
+ Subject: print job: 'financials' completed
+ Sender: mjones@xyz.com
+ Reply-to: mjones@xyz.com
+ To: bsmith@abc.com
+ Content-type: text/plain
+
+ printer: tiger
+ job: financials
+ job-state: completed
+
+The reader should note that the phrases are not identical to IPP
+keywords. They have been localized to English.
+
+
+6.4.2Printer Event Example
+
+
+This section contains an example of an Event Notification of a Printer
+Event.
+
+
+A Subscribing Client Peter Williams, a Printer admin, performs a Create-
+Printer-Subscriptions operation on Printer "ipp://tiger@abc.com". The
+Subscription Object then has the following attributes:
+
+
+
+ Attribute Name Attribute Value
+
+
+ notify-recipient-uri mailto:pwilliams@abc.com
+
+ notify-events printer-state-changed
+
+ notify-mailto-text-only true
+
+ notify-charset us-ascii
+
+ notify-natural-language en-us
+
+ notify-subscription-id 4623
+
+ notify-sequence-number 0
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 23]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+
+
+ Attribute Name Attribute Value
+
+
+ notify-printer-uptime 23002
+
+ notify-printer-uri ipp://tiger@abc.com
+
+ notify-lease-expiration- 0
+ time
+
+ notify-subscriber-user- pwilliams
+ name
+
+
+When the Printer jams, the Printer generates and sends the following
+email message:
+
+ Date: 29 Aug 00 0832 PDT
+ From: tiger <printAdmin@abc.com>
+ Subject: printer: 'tiger' has stopped
+ To: pwilliams@abc.com
+ Content-type: text/plain
+
+ Printer tiger has stopped with a paper jam.
+
+
+The reader should note that the phrases are not identical to IPP
+keywords. They have been localized to English.
+
+
+6.4.3Printer Event Example (localized to Danish)
+
+
+This section contains an example of an Event Notification of a Printer
+Event localized to Danish.
+
+
+A Subscribing Client Per Jensen, a Printer admin, performs a a Create-
+Printer-Subscriptions operation on Printer "ipp://tiger@def.dk". The
+Subscription Object then has the following attributes:
+
+
+
+ Attribute Name Attribute Value
+
+
+ notify-recipient-uri mailto:pjensen@def.dk
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 24]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+
+
+ Attribute Name Attribute Value
+
+
+ notify-events printer-state-changed
+
+ notify-mailto-text-only true
+
+ notify-charset utf-8
+
+ notify-natural-language da
+
+ notify-subscription-id 50225
+
+ notify-sequence-number 0
+
+ notify-printer-uptime 53217
+
+ notify-printer-uri ipp://tiger@def.dk
+
+ notify-lease-expiration- 0
+ time
+
+ notify-subscriber-user- pjensen
+ name
+
+
+When the Printer jams, the Printer generates and sends the following
+email message:
+
+ Date: 29 Jan 00 0832 CET
+ From: tiger <admin@def.dk>
+ Subject: Printeren 'tiger' er standset
+ To: pjensen@def.dk
+ Content-type: text/plain;charset=utf-8
+
+ Printerens navn er 'tiger'.
+ Printeren er standset.
+ Aarsagen er papir stop.
+
+7 Conformance Requirements
+
+The 'mailto' Delivery Method is RECOMMENDED for a Printer to support.
+
+
+If the Printer supports the 'mailto' Delivery Method, the Printer MUST:
+
+
+1.meet the conformance requirements defined in [ipp-ntfy].
+
+
+Herriot, et al. Expires: March 1, 2001 [page 25]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+2.support the "notify-mailto-text-only " Subscription Object attribute
+ defined in section 5.1.1.
+
+
+3.support the syntax for the "notify-recipient-uri" Subscription Object
+ attribute defined in section 5.2.1
+
+
+4.support the use for the "notify-user-data" Subscription Object
+ attribute defined in section 5.2.2
+
+
+5.support SMTP for sending Event Notifications.
+
+
+6.support the 'text/plain' Content-Type for the message body.
+
+
+7.support sending Event Notification via email with the content
+ specified in section 5.2.
+
+
+8 IANA Considerations
+
+Because the 'mailto' URL scheme is already defined in a standards track
+document [RFC 2368] and registered with IANA, this document does not
+require anything further of IANA.
+
+
+9 Internationalization Considerations
+
+This Delivery Method presents no internationalization considerations
+beyond those covered in the [ipp-ntfy] document, and sections 6.1.3 and
+6.2 of this document.
+
+
+The Notification Recipient is expected to present the email as received
+because the Printer does all necessary localization to the Event
+Notification contents.
+
+
+10 Security Considerations
+
+The biggest security concern is that a Subscribing Client will cause
+unsolicited Event Notifications to be sent to third parties, potentially
+creating denial-of-service problems (i.e., spam). The problem is even
+worse if the third parties are distribution lists.
+
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 26]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+There exist scenarios where third party notification is required (see
+Scenario #2 and #3 in [ipp-not-req]). The fully secure solution would
+require active agreement of all persons before they can become
+Notification Recipients. However, requirement #9 in [ipp-req] ("There
+is no requirement for IPP Printer receiving the print request to
+validate the identity of an event recipient") argues against this. To
+minimize the risk, a Printer could disallow third party Notification
+Recipients (a traditional facsimile model).
+
+
+The Delivery Method recommends that the Subscribing Client supply his or
+her email address as the value of the "notify-user-data" attribute in
+the Subscription Creation Operation when the Notification Recipient is a
+third party. To reduce the chance of spamming or identify the spammer, a
+Printer could disallow third party Notification Recipients if the
+Subscribing Client doesn't supply the "notify-user-data" attribute with
+a valid email address.
+
+
+Some firewall administrators prevent mail attachments from being
+accepted into their organizations because of the problem of the
+attachments containing computer viruses. The 'mailto' Delivery Method
+allows the Subscribing Client to request that the Content-Type of a
+message body be 'text/plain'.
+
+
+11 References
+ [ipp-iig]
+ Hastings, T., Manros, C., Kugler, K, Holst H., Zehler, P.,
+ "Internet Printing Protocol/1.1: draft-ietf-ipp-implementers-
+ guide-v11-01.txt, work in progress, May 9, 2000
+
+[ipp-mod]
+ R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell, "Internet
+Printing Protocol/1.0: Model and Semantics", <draft-ietf-ipp-model-v11-
+07.txt>, May 22, 2000.[ipp-ntfy]
+ Herriot, R., Hastings, T., Isaacson, S., Martin, J., deBry, R.,
+ Shepherd, M., Bergman, R., "Internet Printing Protocol/1.1: IPP
+ Event Notification Specification", <draft-ietf-ipp-not-spec-
+ 04.txt>, August 30, 2000.
+
+[ipp-pro]
+ Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet Printing
+ Protocol/1.1: Encoding and Transport", draft-ietf-ipp-protocol-v11-
+ 06.txt, May 20, 2000.
+
+[RFC821]
+ Jonathan B. Postel, "Simple Mail Transfer Protocol", RFC 821,
+ August, 1982.
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 27]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+[RFC822]
+ David H. Crocker, "Standard For The Format Of ARPA Internet Text
+ Messages", RFC 822, August 13, 1982.
+
+[RFC1341]
+ N. Borenstein, N. Freed, "MIME (Multipurpose Internet Mail
+ Extensions): Mechanisms for Specifying and Describing the Format of
+ Internet Message Bodies", RFC 1341, June, 1992.
+
+
+[RFC1521]
+
+ N. Borenstein, N. Freed, "MIME (Multipurpose Internet Mail
+ Extensions) Part One: Mechanisms for Specifying and Describing the
+ Format of Internet Message Bodies", RFC 1521, September 1993.
+
+[RFC1891]
+ K. Moore, "SMTP Service Extension for Delivery Status
+ Notifications", RFC 1891, January 1996
+
+[RFC2026]
+ S. Bradner, "The Internet Standards Process -- Revision 3", RFC
+ 2026, October 1996.
+
+[RFC2046]
+ R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P.
+ Leach, T. Berners-Lee, "Hypertext Transfer Protocol - HTTP/1.1",
+ RFC 2616, June 1999.
+
+[RFC2368]
+ P. Hoffman, L. Masinter, J. Zawinski, "The mailto URL scheme", RFC
+ 2616, July 1998.
+
+ [RFC2616]
+ R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P.
+ Leach, T. Berners-Lee, "Hypertext Transfer Protocol - HTTP/1.1",
+ RFC 2616, June 1999.
+
+ [RFC2633]
+ B. Ramsdell, "S/MIME Version 3 Message Specification", RFC 2633,
+ June 1999.
+
+
+12 Author's Addresses
+
+ Robert Herriot
+ Xerox Corporation
+ 3400 Hillview Ave., Bldg #1
+ Palo Alto, CA 94304
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 28]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ Email: robert.herriot@pahv.xerox.com
+
+ Henrik Holst
+ i-data international a/s
+ Vadstrupvej 35-43
+ 2880 Bagsvaerd, Denmark
+
+ Phone: +45 4436-6000
+ Fax: +45 4436-6111
+ e-mail: hh@i-data.com
+
+ Tom Hastings
+ Xerox Corporation
+ 737 Hawaii St. ESAE 231
+ El Segundo, CA 90245
+
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ e-mail: hastings@cp10.es.xerox.com
+
+
+ Carl-Uno Manros
+ Xerox Corporation
+ 737 Hawaii St. ESAE 231
+ El Segundo, CA 90245
+
+ Phone: 310-333-8273
+ Fax: 310-333-5514
+ e-mail: manros@cp10.es.xerox.com
+
+
+13 Full Copyright Statement
+Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to
+others, and derivative works that comment on or otherwise explain it or
+assist in its implementation may be prepared, copied, published and
+distributed, in whole or in part, without restriction of any kind,
+provided that the above copyright notice and this paragraph are included
+on all such copies and derivative works. However, this document itself
+may not be modified in any way, such as by removing the copyright notice
+or references to the Internet Society or other Internet organizations,
+except as needed for the purpose of developing Internet standards in
+which case the procedures for copyrights defined in the Internet
+Standards process must be followed, or as required to translate it into
+languages other than English.
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 29]
+
+
+PWG-DRAFT IPP: The 'mailto:' Delivery Method August 30, 2000
+
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS
+IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
+FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
+INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR
+FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Expires: March 1, 2001 [page 30]
diff --git a/standards/draft-ietf-ipp-notify-poll-02.txt b/standards/draft-ietf-ipp-notify-poll-02.txt
new file mode 100644
index 000000000..b71529e91
--- /dev/null
+++ b/standards/draft-ietf-ipp-notify-poll-02.txt
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<HTML><HEAD>
+<TITLE>404 Not Found</TITLE>
+</HEAD><BODY>
+<H1>Not Found</H1>
+The requested URL /internet-drafts/draft-ietf-ipp-notify-poll-02.txt was not found on this server.<P>
+<HR>
+<ADDRESS>Apache/1.3.11 Server at www2.ietf.org Port 80</ADDRESS>
+</BODY></HTML>
diff --git a/standards/draft-ietf-ipp-ops-admin-req-00.txt b/standards/draft-ietf-ipp-ops-admin-req-00.txt
new file mode 100644
index 000000000..c5a6ccfe4
--- /dev/null
+++ b/standards/draft-ietf-ipp-ops-admin-req-00.txt
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<HTML><HEAD>
+<TITLE>404 Not Found</TITLE>
+</HEAD><BODY>
+<H1>Not Found</H1>
+The requested URL /internet-drafts/draft-ietf-ipp-ops-admin-req-00.txt was not found on this server.<P>
+<HR>
+<ADDRESS>Apache/1.3.11 Server at www2.ietf.org Port 80</ADDRESS>
+</BODY></HTML>
diff --git a/standards/draft-ietf-ipp-ops-set2-02.txt b/standards/draft-ietf-ipp-ops-set2-02.txt
new file mode 100644
index 000000000..ad575525b
--- /dev/null
+++ b/standards/draft-ietf-ipp-ops-set2-02.txt
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<HTML><HEAD>
+<TITLE>404 Not Found</TITLE>
+</HEAD><BODY>
+<H1>Not Found</H1>
+The requested URL /internet-drafts/draft-ietf-ipp-ops-set2-02.txt was not found on this server.<P>
+<HR>
+<ADDRESS>Apache/1.3.11 Server at www2.ietf.org Port 80</ADDRESS>
+</BODY></HTML>
diff --git a/standards/draft-ietf-ipp-url-scheme-02.txt b/standards/draft-ietf-ipp-url-scheme-02.txt
new file mode 100644
index 000000000..2b5378c1f
--- /dev/null
+++ b/standards/draft-ietf-ipp-url-scheme-02.txt
@@ -0,0 +1,899 @@
+
+
+Internet Printing Protocol Working Group Bob Herriot
+INTERNET DRAFT Xerox Corporation
+Expires 13 August 2001 Ira McDonald
+ High North Inc
+[Target Category: Standards Track] 13 February 2001
+
+ Internet Printing Protocol (IPP):
+ IPP URL Scheme
+ <draft-ietf-ipp-url-scheme-02.txt>
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of RFC2026. Internet-Drafts are working
+ documents of the Internet Engineering Task Force (IETF), its areas,
+ and its working groups. Note that other groups may also distribute
+ working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference
+ material or to cite them other than as "work in progress."
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed at
+ http://www.ietf.org/shadow.html.
+
+
+Abstract
+
+ This document is a product of the Internet Printing Protocol Working
+ Group of the Internet Engineering Task Force (IETF). Comments should
+ be submitted to the ipp@pwg.org mailing list.
+
+ This document is intended for use in registering the "ipp" URL scheme
+ with IANA and fully conforms to the requirements in [RFC-2717]. This
+ document defines the "ipp" URL (Uniform Resource Locator) scheme for
+ specifying the location of an IPP Printer, IPP Job, or other IPP
+ object (defined in some future version of IPP) which implements the
+ IPP/1.1 Model [RFC-2911] and the IPP/1.1 Protocol encoding over HTTP
+ [RFC-2910] or any later version of IPP. The intended usage of the
+ "ipp" URL scheme is COMMON.
+
+ The IPP URL scheme defined in this document is based on the ABNF for
+ the HTTP URL scheme defined in HTTP/1.1 [RFC-2616], which is derived
+ from the URI Generic Syntax [RFC-2396] and further updated by
+ [RFC-2732] and [RFC-2373] (for IPv6 addresses in URLs). An IPP URL
+ is transformed into an HTTP URL according to the rules specified in
+ section 5 of the IPP/1.1 Protocol [RFC-2910].
+
+
+Herriot, McDonald Expires 13 August 2001 [Page 1]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+
+ Table of Contents
+
+1. Introduction ............................................... 3
+2. Terminology ................................................ 4
+ 2.1. Conformance Terminology ................................ 4
+ 2.2. Model Terminology ...................................... 4
+3. IPP Model for Printers and Jobs ............................ 4
+4. IPP URL Scheme ............................................. 6
+ 4.1. IPP URL Scheme Applicability and Intended Usage ........ 6
+ 4.2. IPP URL Scheme Associated IPP Port ..................... 6
+ 4.3. IPP URL Scheme Associated MIME Type .................... 6
+ 4.4. IPP URL Scheme Character Encoding ...................... 6
+ 4.5. IPP URL Scheme Syntax in ABNF .......................... 7
+ 4.5.1. IPP URL Examples ................................... 8
+ 4.5.2. IPP URL Comparisons ................................ 9
+5. Conformance Requirements ................................... 10
+ 5.1. Conformance Requirements for IPP Clients ............... 10
+ 5.2. Conformance Requirements for IPP Printers .............. 10
+6. IANA Considerations ........................................ 11
+7. Internationalization Considerations ........................ 11
+8. Security Considerations .................................... 11
+9. References ................................................. 12
+10. Acknowledgments ........................................... 13
+11. Authors' Addresses ........................................ 14
+12. Appendix X - Change History ............................... 14
+13. Full Copyright Statement .................................. 15
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, McDonald Expires 13 August 2001 [Page 2]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+
+
+1. Introduction
+
+ See section 1 'Introduction' in [RFC-2911] for a full description of
+ the IPP document set and overview information about IPP.
+
+ The open issues in this document each begin 'ISSUE_n:'.
+
+ This document is a product of the Internet Printing Protocol Working
+ Group of the Internet Engineering Task Force (IETF). Comments should
+ be submitted to the ipp@pwg.org mailing list.
+
+ This document is intended for use in registering the "ipp" URL scheme
+ with IANA and fully conforms to the requirements in [RFC-2717]. This
+ document defines the "ipp" URL (Uniform Resource Locator) scheme for
+ specifying the location of an IPP Printer, IPP Job, or other IPP
+ object (defined in some future version of IPP) which implements the
+ IPP/1.1 Model [RFC-2911] and the IPP/1.1 Protocol encoding over HTTP
+ [RFC-2910] or any later version of IPP. The intended usage of the
+ "ipp" URL scheme is COMMON.
+
+ This document defines:
+ - IPP URL scheme applicability and intended usage;
+ - IPP URL scheme associated port (i.e., well-known port 631);
+ - IPP URL scheme associated MIME type (i.e., "application/ipp");
+ - IPP URL scheme syntax in ABNF [RFC-2234];
+ - IPP URL scheme character encoding;
+ - IPP URL scheme IANA, internationalization, and security
+ considerations.
+
+ This document is laid out as follows:
+ - Section 2 is the terminology used throughout the document.
+
+ - Section 3 provides references to the IPP Printer and IPP Job object
+ model.
+
+ - Section 4 specifies IPP URL scheme.
+
+ - Section 5 specifies the conformance requirements for IPP Clients
+ and IPP Printers that claim conformance to this document.
+
+ - Section 6, 7, and 8 specify IANA, internationalization, and
+ security considerations.
+
+ - Sections 9, 10, 11, 12, and 13 list references, acknowledgements,
+ authors' addresses, change history, and full IETF copyright
+ statement.
+
+
+
+
+Herriot, McDonald Expires 13 August 2001 [Page 3]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+
+
+2. Terminology
+
+ This specification document uses the terminology defined in this
+ section.
+
+
+ 2.1. Conformance Terminology
+
+ The uppercase terms "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
+ NOT" "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in
+ this document are to be interpreted as described in [RFC-2119].
+ These terms are used to specify conformance requirements for all
+ implementations of this specification.
+
+
+ 2.2. Model Terminology
+
+ See section 12.2 'Model Terminology' in [RFC-2911].
+
+
+
+3. IPP Model for Printers and Jobs
+
+ See section 2 'IPP Objects', section 2.1 'Printer Object', and
+ section 2.2 'Job Object' in [RFC-2911] for a full description of the
+ IPP object model and terminology.
+
+ In this document, "IPP Client" means the software (on some hardware
+ platform) that submits, monitors, and/or manages print jobs via
+ IPP/1.1 [RFC-2910] [RFC-2911], or any later version of IPP to a
+ spooler, gateway, or actual printing device.
+
+ In this document, "IPP Printer object" means the software (on some
+ hardware platform) that receives print jobs and/or printer/job
+ operations via IPP/1.1 [RFC-2910] [RFC-2911], or any later version of
+ IPP from an "IPP Client".
+
+ In this document, "IPP Printer" is a synonym for "IPP Printer
+ object".
+
+ In this document, "IPP Job object" means the set of attributes and
+ documents for one print job on an "IPP Printer".
+
+ In this document, "IPP Job" is a synonym for "IPP Job object".
+
+ In this document, "IPP URL" means a URL with the "ipp" scheme.
+
+ Note: In this document, "IPP URL" is a synonym for "ipp_URL" (in
+ section 4 'IPP URL Scheme' of this document) and "ipp-URL" (in
+
+Herriot, McDonald Expires 13 August 2001 [Page 4]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+ section 5 'IPP URL Scheme' of [RFC-2910]).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, McDonald Expires 13 August 2001 [Page 5]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+
+
+4. IPP URL Scheme
+
+
+
+ 4.1. IPP URL Scheme Applicability and Intended Usage
+
+ This document is intended for use in registering the "ipp" URL scheme
+ with IANA and fully conforms to the requirements in [RFC-2717]. This
+ document defines the "ipp" URL (Uniform Resource Locator) scheme for
+ specifying the location of an IPP Printer, IPP Job, or other IPP
+ object (defined in some future version of IPP) which implements the
+ IPP/1.1 Model [RFC-2911] and the IPP/1.1 Protocol encoding over HTTP
+ [RFC-2910] or any later version of IPP. The intended usage of the
+ "ipp" URL scheme is COMMON.
+
+
+
+ 4.2. IPP URL Scheme Associated IPP Port
+
+ All IPP URLs which do NOT explicitly specify a port MUST be used over
+ IANA-assigned well-known port 631 for the IPP protocol described in
+ [RFC-2910].
+
+ See: IANA Port Numbers Registry [IANA-PORTREG]. registration with
+ IANA.
+
+
+
+ 4.3. IPP URL Scheme Associated MIME Type
+
+ All IPP protocol operations (requests and responses) MUST be conveyed
+ in an "application/ipp" MIME media type as registered in
+ [IANA-MIMEREG]. IPP URLs MUST refer to IPP Printers which support
+ this "application/ipp" MIME media type.
+
+ See: IANA MIME Media Types Registry [IANA-MIMEREG].
+
+
+
+ 4.4. IPP URL Scheme Character Encoding
+
+ The IPP URL scheme defined in this document is based on the ABNF for
+ the HTTP URL scheme defined in HTTP/1.1 [RFC-2616], which is derived
+ from the URI Generic Syntax [RFC-2396] and further updated by
+ [RFC-2732] and [RFC-2373] (for IPv6 addresses in URLs). The IPP URL
+ scheme is case-insensitive in the host name or host address part;
+ however the path part is case-sensitive, as in [RFC-2396].
+ Codepoints outside [US-ASCII] MUST be hex escaped by the mechanism
+ specified in [RFC-2396].
+
+Herriot, McDonald Expires 13 August 2001 [Page 6]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+
+
+
+ 4.5. IPP URL Scheme Syntax in ABNF
+
+ Note: In this document, "IPP URL" is a synonym for "ipp_URL" (in
+ section 4 'IPP URL Scheme' of this document) and "ipp-URL" (in
+ section 5 'IPP URL Scheme' of [RFC-2910]).
+
+ This document is intended for use in registering the "ipp" URL scheme
+ with IANA and fully conforms to the requirements in [RFC-2717]. This
+ document defines the "ipp" URL (Uniform Resource Locator) scheme for
+ specifying the location of an IPP Printer, IPP Job, or other IPP
+ object (defined in some future version of IPP) which implements the
+ IPP/1.1 Model [RFC-2911] and the IPP/1.1 Protocol encoding over HTTP
+ [RFC-2910] or any later version of IPP. The intended usage of the
+ "ipp" URL scheme is COMMON.
+
+ The IPP protocol places a limit of 1023 octets (NOT characters) on
+ the length of a URI (see section 4.1.5 'uri' in [RFC-2911]). An IPP
+ Printer MUST return 'client-error-request-value-too-long' (see
+ section 13.1.4.10 in [RFC-2911]) when a URI received in a request
+ (e.g., in the "printer-uri" attribute) is too long.
+
+ Note: IPP Printers ought to be cautious about depending on URI
+ lengths above 255 bytes, because some older client or proxy
+ implementations might not properly support these lengths.
+
+ IPP URLs MUST be represented in absolute form. Absolute URLs always
+ begin with a scheme name followed by a colon. For definitive
+ information on URL syntax and semantics, see "Uniform Resource
+ Identifiers (URI): Generic Syntax and Semantics" [RFC-2396]. This
+ specification adopts the definitions of "URI-reference",
+ "absoluteURI", "relativeURI", "port", "host","abs_path", "rel_path",
+ and "authority" from [RFC-2396], as updated by [RFC-2732] and
+ [RFC-2373] (for IPv6 addresses in URLs).
+
+ The IPP URL scheme syntax in ABNF is as follows:
+
+ ipp_URL = "ipp:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
+
+ If the port is empty or not given, port 631 is assumed. The
+ semantics are that the identified resource (see section 5.1.2 of
+ [RFC-2616]) is located at the IPP Printer or IPP Job listening for
+ HTTP connections on that port of that host, and the Request-URI for
+ the identified resource is 'abs_path'.
+
+ Note: The use of IP addresses in URLs SHOULD be avoided whenever
+ possible (see [RFC-1900]).
+
+ If the 'abs_path' is not present in the URL, it MUST be given as "/"
+
+Herriot, McDonald Expires 13 August 2001 [Page 7]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+ when used as a Request-URI for a resource (see section 5.1.2 of
+ [RFC-2616]). If a proxy receives a host name which is not a fully
+ qualified domain name, it MAY add its domain to the host name it
+ received. If a proxy receives a fully qualified domain name, the
+ proxy MUST NOT change the host name.
+
+
+
+ 4.5.1. IPP URL Examples
+
+ The following are examples of valid IPP URLs for IPP Printers:
+
+ ipp://abc.com
+ ipp://abc.com/printer
+ ipp://abc.com/tiger
+ ipp://abc.com/printers/tiger
+ ipp://abc.com/printers/fox
+ ipp://abc.com/printers/tiger/bob
+ ipp://abc.com/printers/tiger/ira
+ ipp://printer.abc.com
+ ipp://printers.abc.com/tiger
+ ipp://printers.abc.com/tiger/bob
+ ipp://printers.abc.com/tiger/ira
+
+ Each of the above URLs are legitimate URLs for IPP Printers and each
+ references a logically different IPP Printer, even though some of the
+ IPP Printers may share the same hardware. The last part of the path
+ 'bob' or 'ira' may represent two different hardware devices where
+ 'tiger' represents some grouping of IPP Printers (e.g., a
+ load-balancing spooler) or the two names may represent separate human
+ recipients ('bob' and 'ira') on the same hardware device (e.g., a
+ printer supporting two job queues). In either case both 'bob' and
+ 'ira' behave as different IPP Printers.
+
+ The following are examples of IPP URLs with (optional) ports and
+ paths:
+
+ ipp://abc.com
+ ipp://abc.com/~smith/printer
+ ipp://abc.com:631/~smith/printer
+
+ The first and second IPP URLs above MUST be resolved to port 631
+ (IANA assigned well-known port for IPP). The second and third IPP
+ URLs above are equivalent (see section 4.5.2 below).
+
+ Note: The use of IP addresses in URLs SHOULD be avoided whenever
+ possible (see [RFC-1900]).
+
+ The following literal IPv4 addresses:
+
+
+
+Herriot, McDonald Expires 13 August 2001 [Page 8]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+ 192.9.5.5 ; IPv4 address in IPv4 style
+ 186.7.8.9 ; IPv4 address in IPv4 style
+
+ are represented in the following example IPP URLs:
+
+ ipp://192.9.5.5/prt1
+ ipp://186.7.8.9/printers/tiger/bob
+
+ The following literal IPv6 addresses (conformant to [RFC-2373]):
+
+ ::192.9.5.5 ; IPv4 address in IPv6 style
+ ::FFFF:129.144.52.38 ; IPv4 address in IPv6 style
+ 2010:836B:4179::836B:4179 ; IPv6 address per RFC 2373
+
+ are represented in the following example IPP URLs:
+
+ ipp://[::192.9.5.5]/prt1
+ ipp://[::FFFF:129.144.52.38]:631/printers/tiger
+ ipp://[2010:836B:4179::836B:4179]/printers/tiger/bob
+
+
+
+ 4.5.2. IPP URL Comparisons
+
+ When comparing two IPP URLs to decide if they match or not, an IPP
+ Client SHOULD use a case-sensitive octet-by-octet comparison of the
+ entire URLs, with these exceptions:
+
+ - A port that is empty or not given is equivalent to the well-known
+ port for that IPP URL (port 631);
+
+ - Comparisons of host names MUST be case-insensitive;
+
+ - Comparisons of scheme names MUST be case-insensitive;
+
+ - An empty 'abs_path' is equivalent to an 'abs_path' of "/".
+
+ Characters other than those in the "reserved" and "unsafe" sets (see
+ [RFC-2396] and [RFC-2732]) are equivalent to their ""%" HEX HEX"
+ encoding.
+
+ For example, the following three URIs are equivalent:
+
+ ipp://abc.com:631/~smith/printer
+ ipp://ABC.com/%7Esmith/printer
+ ipp://ABC.com:/%7esmith/printer
+
+
+
+
+
+
+Herriot, McDonald Expires 13 August 2001 [Page 9]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+
+
+5. Conformance Requirements
+
+
+
+ 5.1. Conformance Requirements for IPP Clients
+
+ IPP Clients that conform to this specification:
+
+ a) MUST send IPP URLs (e.g., in the "printer-uri" operation attribute
+ in 'Print-Job') that conform to the ABNF specified in section 4.5
+ of this document;
+
+ b) MUST send IPP operations via the port specified in the IPP URL (if
+ present) or otherwise via IANA assigned well-known port 631;
+
+ c) MUST convert IPP URLs to their corresponding HTTP URL forms
+ according to the rules in section 5 'IPP URL Scheme' in
+ [RFC-2910];
+
+ d) SHOULD interoperate with IPP/1.0 Printers according to the rules
+ in section 9 'Interoperability with IPP/1.0 Implementations' and
+ section 9.2 'Security and URL Schemes' in [RFC-2910].
+
+
+
+ 5.2. Conformance Requirements for IPP Printers
+
+ IPP Printers that conform to this specification:
+
+ a) SHOULD reject received IPP URLs in "application/ipp" request
+ bodies (e.g., in the "printer-uri" attribute in a 'Print-Job'
+ request) that do not conform to the ABNF for IPP URLs specified in
+ section 4.5 of this document;
+
+ b) SHOULD return IPP URLs in "application/ipp" response bodies (e.g.,
+ in the "job-uri" attribute in a 'Print-Job' response) that do
+ conform to the ABNF for IPP URLs specified in section 4.5 of this
+ document;
+
+ c) MUST listen for IPP operations on IANA-assigned well-known port
+ 631, unless explicitly configured by system administrators or site
+ policies;
+
+ d) SHOULD NOT listen for IPP operations on any other port, unless
+ explicitly configured by system administrators or site policies;
+
+ e) SHOULD interoperate with IPP/1.0 Clients according to the rules in
+ section 9 'Interoperability with IPP/1.0 Implementations' and
+ section 9.2 'Security and URL Schemes' in [RFC-2910].
+
+Herriot, McDonald Expires 13 August 2001 [Page 10]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+
+
+6. IANA Considerations
+
+ This document is intended for use in registering the "ipp" URL scheme
+ with IANA and fully conforms to the requirements in [RFC-2717]. This
+ document defines the "ipp" URL (Uniform Resource Locator) scheme for
+ specifying the location of an IPP Printer, IPP Job, or other IPP
+ object (defined in some future version of IPP) which implements the
+ IPP/1.1 Model [RFC-2911] and the IPP/1.1 Protocol encoding over HTTP
+ [RFC-2910] or any later version of IPP. The intended usage of the
+ "ipp" URL scheme is COMMON.
+
+ This IPP URL Scheme specification does not introduce any additional
+ IANA considerations, beyond those described in [RFC-2910] and
+ [RFC-2911].
+
+ See: Section 6 'IANA Considerations' in [RFC-2910]
+ See: Section 6 'IANA Considerations' in [RFC-2911].
+
+
+
+7. Internationalization Considerations
+
+ This IPP URL Scheme specification does not introduce any additional
+ internationalization considerations, beyond those described in
+ [RFC-2910] and [RFC-2911].
+
+ See: Section 7 'Internationalization Considerations' in [RFC-2910].
+ See: Section 7 'Internationalization Considerations' in [RFC-2911].
+
+
+
+8. Security Considerations
+
+ This IPP URL Scheme specification does not introduce any additional
+ security considerations, beyond those described in [RFC-2910] and
+ [RFC-2911].
+
+ See: Section 8 'Security Considerations' in [RFC-2910].
+ See: Section 8 'Security Considerations' in [RFC-2911].
+
+
+
+
+
+
+
+
+
+
+
+Herriot, McDonald Expires 13 August 2001 [Page 11]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+
+
+9. References
+
+ See: Section 10 'References' in [RFC-2910].
+ See: Section 9 'References' in [RFC-2911].
+
+ [IANA-CHARREG] IANA Charset Registry.
+ ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets
+
+ [IANA-MIMEREG] IANA MIME Media Types Registry.
+ ftp://ftp.isi.edu/in-notes/iana/assignments/media-types/...
+
+ [IANA-PORTREG] IANA Port Numbers Registry.
+ ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers
+
+ [NET-SSL3] Netscape. The SSL Protocol, Version 3 (text version
+ 3.02), November 1996.
+
+ [RFC-1759] R. Smith, F. Wright, T. Hastings, S. Zilles,
+ J. Gyllenskog. Printer MIB, RFC 1759, March 1995.
+
+ [RFC-1900] B. Carpenter, Y. Rekhter. Renumbering Needs Work, RFC
+ 1900, February 1996.
+
+ [RFC-2046] N. Freed, N. Borenstein. MIME Part Two: Media Types, RFC
+ 2046, November 1996.
+
+ [RFC-2048] N. Freed, J. Klensin, J. Postel. MIME Part
+ Four: Registration Procedures, RFC 2048, November 1996.
+
+ [RFC-2234] D. Crocker, P. Overell. Augmented BNF for Syntax
+ Specifications: ABNF, RFC 2234, November 1997.
+
+ [RFC-2373] R. Hinden, S. Deering. IP Version 6 Addressing
+ Architecture, RFC 2373, July 1998.
+
+ [RFC-2396] T. Berners-Lee, R. Fielding, L. Masinter. Uniform
+ Resource Identifiers (URI): Generic Syntax, RFC 2396, August 1998.
+
+ [RFC-2246] T. Dierks, C. Allen. The TLS Protocol Version, RFC 2246,
+ January 1999.
+
+ [RFC-2277] H. Alvestrand. IETF Policy on Character Sets and
+ Languages, RFC 2277, January 1998.
+
+ [RFC-2279] F. Yergeau. UTF-8, a Transformation Format of ISO 10646,
+ RFC 2279, January 1998.
+
+ [RFC-2565] R. Herriot, S. Butler, P. Moore, R. Turner. IPP/1.0
+ Encoding and Transport, RFC 2565, April 1999 (Experimental).
+
+Herriot, McDonald Expires 13 August 2001 [Page 12]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+
+ [RFC-2566] R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell.
+ IPP/1.0 Model and Semantics, RFC 2566, April 1999 (Experimental).
+
+ [RFC-2579] K. McCloghrie, D. Perkins, J. Schoenwaelder. Textual
+ Conventions for SMIv2, RFC 2579, April 1999.
+
+ [RFC-2616] R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter,
+ P. Leach, T. Berners-Lee. Hypertext Transfer Protocol -- HTTP/1.1,
+ RFC 2616, June 1999.
+
+ [RFC-2617] J. Franks, P. Hallam-Baker, J. Hostetler, S. Lawrence,
+ P. Leach, A. Luotonen, L. Stewart. HTTP Authentication: Basic and
+ Digest Access Authentication, RFC 2617, June 1999.
+
+ [RFC-2717] R. Petke, I. King. Registration Procedures for URL Scheme
+ Names, RFC 2717, November 1999.
+
+ [RFC-2718] L. Masinter, H. Alvestrand, D. Zigmond, R. Petke.
+ Guidelines for new URL Scheme Names, RFC 2718, November 1999.
+
+ [RFC-2732] R. Hinden,B. Carpenter, L. Masinter. Format for Literal
+ IPv6 Addresses in URL's, RFC 2732, December 1999.
+
+ [RFC-2910] R. Herriot, S. Butler, P. Moore, R. Turner, J. Wenn.
+ IPP/1.1 Encoding and Transport, RFC 2910, September 2000.
+
+ [RFC-2911] T. Hastings, R. Herriot, R. deBry, S. Isaacson, P. Powell.
+ IPP/1.1 Model and Semantics, RFC 2911, September 2000.
+
+ [RFC-2978] N. Freed, J. Postel. IANA Charset Registration
+ Procedures, RFC 2978, October 2000.
+
+ [RFC-3066] H. Alvestrand. Tags for the Identification of Languages,
+ RFC 3066, January 2001.
+
+ [US-ASCII] Coded Character Set -- 7-bit American Standard Code for
+ Information Interchange, ANSI X3.4-1986.
+
+
+
+10. Acknowledgments
+
+ This document is a product of the Internet Printing Protocol Working
+ Group of the Internet Engineering Task Force (IETF). Comments should
+ be submitted to the ipp@pwg.org mailing list.
+
+ Thanks to Pat Fleming (IBM), Tom Hastings (Xerox), Harry Lewis (IBM),
+ and Hugo Parra (Novell).
+
+ Section 5 'IPP URL Scheme' in IPP/1.1 Encoding and Transport
+
+Herriot, McDonald Expires 13 August 2001 [Page 13]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+ [RFC-2910] was the primary input to this IPP URL Scheme
+ specification.
+
+
+
+11. Authors' Addresses
+
+ Robert Herriot
+ Xerox Corporation
+ 3400 Hill View Ave, Building 1
+ Palo Alto, CA 94304
+
+ Phone: +1 650-813-7696
+ Fax: +1 650-813-6860
+ Email: robert.herriot@pahv.xerox.com
+
+
+ Ira McDonald
+ High North Inc
+ 221 Ridge Ave
+ Grand Marais, MI 49839
+
+ Phone: +1 906-494-2434
+ Email: imcdonald@crt.xerox.com
+ Email: imcdonald@sharplabs.com
+
+
+
+12. Appendix X - Change History
+
+ [To be deleted before RFC publication]
+
+ 13 February 2001 - draft-ietf-ipp-url-scheme-02.txt
+ - revised section 3 'IPP Model for Printers and Jobs' and section 4.5
+ 'IPP URL Scheme Syntax in ABNF' to add notes stating that "IPP URL"
+ (in this document) is a synonym for "ipp-URL" in [RFC-2910], per
+ request of Bob Herriot;
+ - revised section 4.5 'IPP URL Scheme Syntax in ABNF' to correct typo
+ that showed "http:" rather than "ipp:" in the one-line ABNF, per
+ request of Tom Hastings;
+ - revised section 4.5.1 'IPP URL Examples' to add a note discouraging
+ the use of literal IP addresses in URLs, per [RFC-2616] and
+ [RFC-1900];
+
+ 5 February 2001 - draft-ietf-ipp-url-scheme-01.txt
+ - revised section 4.1 'IPP URL Applicability and Intended Usage' to
+ clarify that a given IPP URL MAY identify an IPP Printer object or
+ an IPP Job object, per request of Tom Hastings;
+ - revised section 4.5 'IPP URL Scheme Syntax in ABNF' to define IPP
+ URLs consistently with section 3.2.2 'http URL' of HTTP/1.1
+ [RFC-2616], per request of Tom Hastings;
+
+Herriot, McDonald Expires 13 August 2001 [Page 14]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+ - revised section 4.5 'IPP URL Scheme Syntax in ABNF' to clarify that
+ IPP URLs may reference IPP Printer objects, IPP Job objects, or
+ (possibly other future) IPP objects, per request of Bob Herriot;
+ - added section 4.5.1 'IPP URL Examples' to supply meaningful
+ examples of IPP URLs with host names, IPv4 addresses, and IPv6
+ addresses, per request of Tom Hastings;
+ - added section 4.5.2 'IPP URL Comparisons' to define IPP URL
+ comparisons consistently with section 3.3 'URI Comparison' of
+ HTTP/1.1 [RFC-2616], per request of Tom Hastings;
+ - revised section 5.1 'Conformance Requirements for IPP Clients' to
+ clarify that an IPP Client MUST convert IPP URLs to their
+ corresponding HTTP URL forms according to section 5 'IPP URL
+ Scheme' in [RFC-2910], per request of Tom Hastings and Bob Herriot;
+ - revised section 5.1 'Conformance Requirements for IPP Clients' and
+ section 5.2 'Conformance Requirements for IPP Printers' to clarify
+ that IPP Clients and IPP Printers SHOULD interoperate with IPP/1.0
+ systems according to section 9 'Interoperability with IPP/1.0
+ Implementations' in [RFC-2910], per request of Carl Kugler;
+ - revised section 5.2 'Conformance Requirements for IPP Printers' to
+ clarify that an IPP Printer MUST listen on (IANA assigned
+ well-known) port 631, unless explicitly configured, per request of
+ Michael Sweet;
+ - revised section 5.2 'Conformance Requirements for IPP Printers' to
+ clarify that an IPP Printer SHOULD NOT listen on ports other than
+ (IANA assigned well-known) port 631, unless explicitly configured,
+ per request of Don Wright;
+ - revised section 6 'IANA Considerations' to clarify that the sole
+ purpose of the entire document is IANA registration of the "ipp"
+ URL scheme;
+ - deleted Appendix A 'Registration of IPP Port' as unnecessary (port
+ is already registered);
+ - deleted Appendix B 'Registration of MIME "application/ipp" as
+ unnecessary (MIME registry has recently caught up to RFC 2910);
+
+ 11 January 2001 - draft-ietf-ipp-url-scheme-00.txt
+ - initial version - simple "ipp" URL scheme without parameters or
+ query part (consistent with existing and IPP/1.1 implementations);
+ - added Appendix A 'Registration of IPP Port' (placeholder) for
+ updated IANA registration of port 631 with references to IPP/1.1;
+ - added Appendix B 'Registration of MIME "application/ipp"' with
+ updated IANA registration for IPP MIME type with references to both
+ IPP/1.0 and IPP/1.1;
+
+
+
+
+13. Full Copyright Statement
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+
+Herriot, McDonald Expires 13 August 2001 [Page 15]
+
+Internet Draft IPP URL Scheme 13 February 2001
+
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, McDonald Expires 13 August 2001 [Page 16]
diff --git a/standards/pwg5100.1.pdf b/standards/pwg5100.1.pdf
new file mode 100644
index 000000000..80260170f
--- /dev/null
+++ b/standards/pwg5100.1.pdf
Binary files differ
diff --git a/standards/pwg5100.2.pdf b/standards/pwg5100.2.pdf
new file mode 100644
index 000000000..6b0ad3abc
--- /dev/null
+++ b/standards/pwg5100.2.pdf
Binary files differ
diff --git a/standards/pwg5100.3.pdf b/standards/pwg5100.3.pdf
new file mode 100644
index 000000000..0ac46446f
--- /dev/null
+++ b/standards/pwg5100.3.pdf
Binary files differ
diff --git a/standards/pwg5100.4.pdf b/standards/pwg5100.4.pdf
new file mode 100644
index 000000000..3d6c0305f
--- /dev/null
+++ b/standards/pwg5100.4.pdf
Binary files differ
diff --git a/standards/rfc1179.txt b/standards/rfc1179.txt
new file mode 100644
index 000000000..ef59411f7
--- /dev/null
+++ b/standards/rfc1179.txt
@@ -0,0 +1,787 @@
+
+
+
+
+
+
+Network Printing Working Group L. McLaughlin III, Editor
+Request for Comments: 1179 The Wollongong Group
+ August 1990
+
+
+ Line Printer Daemon Protocol
+
+Status of this Memo
+
+ This RFC describes an existing print server protocol widely used on
+ the Internet for communicating between line printer daemons (both
+ clients and servers). This memo is for informational purposes only,
+ and does not specify an Internet standard. Please refer to the
+ current edition of the "IAB Official Protocol Standards" for the
+ standardization state and status of this protocol. Distribution of
+ this memo is unlimited.
+
+1. Introduction
+
+ The Berkeley versions of the Unix(tm) operating system provide line
+ printer spooling with a collection of programs: lpr (assign to
+ queue), lpq (display the queue), lprm (remove from queue), and lpc
+ (control the queue). These programs interact with an autonomous
+ process called the line printer daemon. This RFC describes the
+ protocols with which a line printer daemon client may control
+ printing.
+
+ This memo is based almost entirely on the work of Robert Knight at
+ Princeton University. I gratefully acknowledge his efforts in
+ deciphering the UNIX lpr protocol and producing earlier versions of
+ this document.
+
+2. Model of Printing Environment
+
+ A group of hosts request services from a line printer daemon process
+ running on a host. The services provided by the process are related
+ to printing jobs. A printing job produces output from one file.
+ Each job will have a unique job number which is between 0 and 999,
+ inclusive. The jobs are requested by users which have names. These
+ user names may not start with a digit.
+
+3. Specification of the Protocol
+
+ The specification includes file formats for the control and data
+ files as well as messages used by the protocol.
+
+
+
+
+
+
+McLaughlin [Page 1]
+
+RFC 1179 LPR August 1990
+
+
+3.1 Message formats
+
+ LPR is a a TCP-based protocol. The port on which a line printer
+ daemon listens is 515. The source port must be in the range 721 to
+ 731, inclusive. A line printer daemon responds to commands send to
+ its port. All commands begin with a single octet code, which is a
+ binary number which represents the requested function. The code is
+ immediately followed by the ASCII name of the printer queue name on
+ which the function is to be performed. If there are other operands
+ to the command, they are separated from the printer queue name with
+ white space (ASCII space, horizontal tab, vertical tab, and form
+ feed). The end of the command is indicated with an ASCII line feed
+ character.
+
+4. Diagram Conventions
+
+ The diagrams in the rest of this RFC use these conventions. These
+ diagrams show the format of an octet stream sent to the server. The
+ outermost box represents this stream. Each box within the outermost
+ one shows one portion of the stream. If the contents of the box is
+ two decimal digits, this indicates that the binary 8 bit value is to
+ be used. If the contents is two uppercase letters, this indicates
+ that the corresponding ASCII control character is to be used. An
+ exception to this is that the character SP can be interpreted as
+ white space. (See the preceding section for a definition.) If the
+ contents is a single letter, the ASCII code for this letter must be
+ sent. Otherwise, the contents are intended to be mnemonic of the
+ contents of the field which is a sequence of octets.
+
+5. Daemon commands
+
+ The verbs in the command names should be interpreted as statements
+ made to the daemon. Thus, the command "Print any waiting jobs" is an
+ imperative to the line printer daemon to which it is sent. A new
+ connection must be made for each command to be given to the daemon.
+
+5.1 01 - Print any waiting jobs
+
+ +----+-------+----+
+ | 01 | Queue | LF |
+ +----+-------+----+
+ Command code - 1
+ Operand - Printer queue name
+
+ This command starts the printing process if it not already running.
+
+
+
+
+
+
+McLaughlin [Page 2]
+
+RFC 1179 LPR August 1990
+
+
+5.2 02 - Receive a printer job
+
+ +----+-------+----+
+ | 02 | Queue | LF |
+ +----+-------+----+
+ Command code - 2
+ Operand - Printer queue name
+
+ Receiving a job is controlled by a second level of commands. The
+ daemon is given commands by sending them over the same connection.
+ The commands are described in the next section (6).
+
+ After this command is sent, the client must read an acknowledgement
+ octet from the daemon. A positive acknowledgement is an octet of
+ zero bits. A negative acknowledgement is an octet of any other
+ pattern.
+
+5.3 03 - Send queue state (short)
+
+ +----+-------+----+------+----+
+ | 03 | Queue | SP | List | LF |
+ +----+-------+----+------+----+
+ Command code - 3
+ Operand 1 - Printer queue name
+ Other operands - User names or job numbers
+
+ If the user names or job numbers or both are supplied then only those
+ jobs for those users or with those numbers will be sent.
+
+ The response is an ASCII stream which describes the printer queue.
+ The stream continues until the connection closes. Ends of lines are
+ indicated with ASCII LF control characters. The lines may also
+ contain ASCII HT control characters.
+
+5.4 04 - Send queue state (long)
+
+ +----+-------+----+------+----+
+ | 04 | Queue | SP | List | LF |
+ +----+-------+----+------+----+
+ Command code - 4
+ Operand 1 - Printer queue name
+ Other operands - User names or job numbers
+
+ If the user names or job numbers or both are supplied then only those
+ jobs for those users or with those numbers will be sent.
+
+ The response is an ASCII stream which describes the printer queue.
+ The stream continues until the connection closes. Ends of lines are
+
+
+
+McLaughlin [Page 3]
+
+RFC 1179 LPR August 1990
+
+
+ indicated with ASCII LF control characters. The lines may also
+ contain ASCII HT control characters.
+
+5.5 05 - Remove jobs
+
+ +----+-------+----+-------+----+------+----+
+ | 05 | Queue | SP | Agent | SP | List | LF |
+ +----+-------+----+-------+----+------+----+
+ Command code - 5
+ Operand 1 - Printer queue name
+ Operand 2 - User name making request (the agent)
+ Other operands - User names or job numbers
+
+ This command deletes the print jobs from the specified queue which
+ are listed as the other operands. If only the agent is given, the
+ command is to delete the currently active job. Unless the agent is
+ "root", it is not possible to delete a job which is not owned by the
+ user. This is also the case for specifying user names instead of
+ numbers. That is, agent "root" can delete jobs by user name but no
+ other agents can.
+
+6. Receive job subcommands
+
+ These commands are processed when the line printer daemon has
+ been given the receive job command. The daemon will continue to
+ process commands until the connection is closed.
+
+ After a subcommand is sent, the client must wait for an
+ acknowledgement from the daemon. A positive acknowledgement is an
+ octet of zero bits. A negative acknowledgement is an octet of any
+ other pattern.
+
+ LPR clients SHOULD be able to sent the receive data file and receive
+ control file subcommands in either order. LPR servers MUST be able
+ to receive the control file subcommand first and SHOULD be able to
+ receive the data file subcommand first.
+
+6.1 01 - Abort job
+
+ Command code - 1
+ +----+----+
+ | 01 | LF |
+ +----+----+
+
+ No operands should be supplied. This subcommand will remove any
+ files which have been created during this "Receive job" command.
+
+
+
+
+
+McLaughlin [Page 4]
+
+RFC 1179 LPR August 1990
+
+
+6.2 02 - Receive control file
+
+ +----+-------+----+------+----+
+ | 02 | Count | SP | Name | LF |
+ +----+-------+----+------+----+
+ Command code - 2
+ Operand 1 - Number of bytes in control file
+ Operand 2 - Name of control file
+
+ The control file must be an ASCII stream with the ends of lines
+ indicated by ASCII LF. The total number of bytes in the stream is
+ sent as the first operand. The name of the control file is sent as
+ the second. It should start with ASCII "cfA", followed by a three
+ digit job number, followed by the host name which has constructed the
+ control file. Acknowledgement processing must occur as usual after
+ the command is sent.
+
+ The next "Operand 1" octets over the same TCP connection are the
+ intended contents of the control file. Once all of the contents have
+ been delivered, an octet of zero bits is sent as an indication that
+ the file being sent is complete. A second level of acknowledgement
+ processing must occur at this point.
+
+6.3 03 - Receive data file
+
+ +----+-------+----+------+----+
+ | 03 | Count | SP | Name | LF |
+ +----+-------+----+------+----+
+ Command code - 3
+ Operand 1 - Number of bytes in data file
+ Operand 2 - Name of data file
+
+ The data file may contain any 8 bit values at all. The total number
+ of bytes in the stream may be sent as the first operand, otherwise
+ the field should be cleared to 0. The name of the data file should
+ start with ASCII "dfA". This should be followed by a three digit job
+ number. The job number should be followed by the host name which has
+ constructed the data file. Interpretation of the contents of the
+ data file is determined by the contents of the corresponding control
+ file. If a data file length has been specified, the next "Operand 1"
+ octets over the same TCP connection are the intended contents of the
+ data file. In this case, once all of the contents have been
+ delivered, an octet of zero bits is sent as an indication that the
+ file being sent is complete. A second level of acknowledgement
+ processing must occur at this point.
+
+
+
+
+
+
+McLaughlin [Page 5]
+
+RFC 1179 LPR August 1990
+
+
+7. Control file lines
+
+ This section discusses the format of the lines in the control file
+ which is sent to the line printer daemon.
+
+ Each line of the control file consists of a single, printable ASCII
+ character which represents a function to be performed when the file
+ is printed. Interpretation of these command characters are case-
+ sensitive. The rest of the line after the command character is the
+ command's operand. No leading white space is permitted after the
+ command character. The line ends with an ASCII new line.
+
+ Those commands which have a lower case letter as a command code are
+ used to specify an actual printing request. The commands which use
+ upper case are used to describe parametric values or background
+ conditions.
+
+ Some commands must be included in every control file. These are 'H'
+ (responsible host) and 'P' (responsible user). Additionally, there
+ must be at least one lower case command to produce any output.
+
+7.1 C - Class for banner page
+
+ +---+-------+----+
+ | C | Class | LF |
+ +---+-------+----+
+ Command code - 'C'
+ Operand - Name of class for banner pages
+
+ This command sets the class name to be printed on the banner page.
+ The name must be 31 or fewer octets. The name can be omitted. If it
+ is, the name of the host on which the file is printed will be used.
+ The class is conventionally used to display the host from which the
+ printing job originated. It will be ignored unless the print banner
+ command ('L') is also used.
+
+7.2 H - Host name
+
+ +---+------+----+
+ | H | Host | LF |
+ +---+------+----+
+ Command code - 'H'
+ Operand - Name of host
+
+ This command specifies the name of the host which is to be treated as
+ the source of the print job. The command must be included in the
+ control file. The name of the host must be 31 or fewer octets.
+
+
+
+
+McLaughlin [Page 6]
+
+RFC 1179 LPR August 1990
+
+
+7.3 I - Indent Printing
+
+ +---+-------+----+
+ | I | count | LF |
+ +---+-------+----+
+ Command code - 'I'
+ Operand - Indenting count
+
+ This command specifies that, for files which are printed with the
+ 'f', of columns given. (It is ignored for other output generating
+ commands.) The identing count operand must be all decimal digits.
+
+7.4 J - Job name for banner page
+
+ +---+----------+----+
+ | J | Job name | LF |
+ +---+----------+----+
+ Command code - 'J'
+ Operand - Job name
+
+ This command sets the job name to be printed on the banner page. The
+ name of the job must be 99 or fewer octets. It can be omitted. The
+ job name is conventionally used to display the name of the file or
+ files which were "printed". It will be ignored unless the print
+ banner command ('L') is also used.
+
+7.5 L - Print banner page
+
+ +---+------+----+
+ | L | User | LF |
+ +---+------+----+
+ Command code - 'L'
+ Operand - Name of user for burst pages
+
+ This command causes the banner page to be printed. The user name can
+ be omitted. The class name for banner page and job name for banner
+ page commands must precede this command in the control file to be
+ effective.
+
+7.6 M - Mail When Printed
+
+ +---+------+----+
+ | M | user | LF |
+ +---+------+----+
+ Command code - 'M'
+ Operand - User name
+
+ This entry causes mail to be sent to the user given as the operand at
+
+
+
+McLaughlin [Page 7]
+
+RFC 1179 LPR August 1990
+
+
+ the host specified by the 'H' entry when the printing operation ends
+ (successfully or unsuccessfully).
+
+7.7 N - Name of source file
+
+ +---+------+----+
+ | N | Name | LF |
+ +---+------+----+
+ Command code - 'N'
+ Operand - File name
+
+ This command specifies the name of the file from which the data file
+ was constructed. It is returned on a query and used in printing with
+ the 'p' command when no title has been given. It must be 131 or
+ fewer octets.
+
+7.8 P - User identification
+
+ +---+------+----+
+ | P | Name | LF |
+ +---+------+----+
+ Command code - 'P'
+ Operand - User id
+
+ This command specifies the user identification of the entity
+ requesting the printing job. This command must be included in the
+ control file. The user identification must be 31 or fewer octets.
+
+7.9 S - Symbolic link data
+
+ +---+--------+----+-------+----+
+ | S | device | SP | inode | LF |
+ +---+--------+----+-------+----+
+ Command code - 'S'
+ Operand 1 - Device number
+ Operand 2 - Inode number
+
+ This command is used to record symbolic link data on a Unix system so
+ that changing a file's directory entry after a file is printed will
+ not print the new file. It is ignored if the data file is not
+ symbolically linked.
+
+
+
+
+
+
+
+
+
+
+McLaughlin [Page 8]
+
+RFC 1179 LPR August 1990
+
+
+7.10 T - Title for pr
+
+ +---+-------+----+
+ | T | title | LF |
+ +---+-------+----+
+ Command code - 'T'
+ Operand - Title text
+
+ This command provides a title for a file which is to be printed with
+ either the 'p' command. (It is ignored by all of the other printing
+ commands.) The title must be 79 or fewer octets.
+
+7.11 U - Unlink data file
+
+ +---+------+----+
+ | U | file | LF |
+ +---+------+----+
+ Command code - 'U'
+ Operand - File to unlink
+
+ This command indicates that the specified file is no longer needed.
+ This should only be used for data files.
+
+7.12 W - Width of output
+
+ +---+-------+----+
+ | W | width | LF |
+ +---+-------+----+
+ Command code - 'W'
+ Operand - Width count
+
+ This command limits the output to the specified number of columns for
+ the 'f', 'l', and 'p' commands. (It is ignored for other output
+ generating commands.) The width count operand must be all decimal
+ digits. It may be silently reduced to some lower value. The default
+ value for the width is 132.
+
+7.13 1 - troff R font
+
+ +---+------+----+
+ | 1 | file | LF |
+ +---+------+----+
+ Command code - '1'
+ Operand - File name
+
+ This command specifies the file name for the troff R font. [1] This
+ is the font which is printed using Times Roman by default.
+
+
+
+
+McLaughlin [Page 9]
+
+RFC 1179 LPR August 1990
+
+
+7.14 2 - troff I font
+
+ +---+------+----+
+ | 2 | file | LF |
+ +---+------+----+
+ Command code - '2'
+ Operand - File name
+
+ This command specifies the file name for the troff I font. [1] This
+ is the font which is printed using Times Italic by default.
+
+7.15 3 - troff B font
+
+ +---+------+----+
+ | 3 | file | LF |
+ +---+------+----+
+ Command code - '3'
+ Operand - File name
+
+ This command specifies the file name for the troff B font. [1] This
+ is the font which is printed using Times Bold by default.
+
+7.16 4 - troff S font
+
+ +---+------+----+
+ | 4 | file | LF |
+ +---+------+----+
+ Command code - '4'
+ Operand - File name
+
+ This command specifies the file name for the troff S font. [1] This
+ is the font which is printed using Special Mathematical Font by
+ default.
+
+7.17 c - Plot CIF file
+
+ +---+------+----+
+ | c | file | LF |
+ +---+------+----+
+ Command code - 'c'
+ Operand - File to plot
+
+ This command causes the data file to be plotted, treating the data as
+ CIF (CalTech Intermediate Form) graphics language. [2]
+
+
+
+
+
+
+
+McLaughlin [Page 10]
+
+RFC 1179 LPR August 1990
+
+
+7.18 d - Print DVI file
+
+ +---+------+----+
+ | d | file | LF |
+ +---+------+----+
+ Command code - 'd'
+ Operand - File to print
+
+ This command causes the data file to be printed, treating the data as
+ DVI (TeX output). [3]
+
+7.19 f - Print formatted file
+
+ +---+------+----+
+ | f | file | LF |
+ +---+------+----+
+ Command code - 'f'
+ Operand - File to print
+
+ This command cause the data file to be printed as a plain text file,
+ providing page breaks as necessary. Any ASCII control characters
+ which are not in the following list are discarded: HT, CR, FF, LF,
+ and BS.
+
+7.20 g - Plot file
+
+ +---+------+----+
+ | g | file | LF |
+ +---+------+----+
+ Command code - 'g'
+ Operand - File to plot
+
+ This command causes the data file to be plotted, treating the data as
+ output from the Berkeley Unix plot library. [1]
+
+7.21 k - Reserved for use by Kerberized LPR clients and servers.
+
+7.22 l - Print file leaving control characters
+
+ +---+------+----+
+ | l | file | LF |
+ +---+------+----+
+ Command code - 'l' (lower case L)
+ Operand - File to print
+
+ This command causes the specified data file to printed without
+ filtering the control characters (as is done with the 'f' command).
+
+
+
+
+McLaughlin [Page 11]
+
+RFC 1179 LPR August 1990
+
+
+7.23 n - Print ditroff output file
+
+ +---+------+----+
+ | n | file | LF |
+ +---+------+----+
+ Command code - 'n'
+ Operand - File to print
+
+ This command prints the data file to be printed, treating the data as
+ ditroff output. [4]
+
+7.24 o - Print Postscript output file
+
+ +---+------+----+
+ | o | file | LF |
+ +---+------+----+
+ Command code - 'o'
+ Operand - File to print
+
+ This command prints the data file to be printed, treating the data as
+ standard Postscript input.
+
+7.25 p - Print file with 'pr' format
+
+ +---+------+----+
+ | p | file | LF |
+ +---+------+----+
+ Command code - 'p'
+ Operand - File to print
+
+ This command causes the data file to be printed with a heading, page
+ numbers, and pagination. The heading should include the date and
+ time that printing was started, the title, and a page number
+ identifier followed by the page number. The title is the name of
+ file as specified by the 'N' command, unless the 'T' command (title)
+ has been given. After a page of text has been printed, a new page is
+ started with a new page number. (There is no way to specify the
+ length of the page.)
+
+7.26 r - File to print with FORTRAN carriage control
+
+ +---+------+----+
+ | r | file | LF |
+ +---+------+----+
+ Command code - 'r'
+ Operand - File to print
+
+ This command causes the data file to be printed, interpreting the
+
+
+
+McLaughlin [Page 12]
+
+RFC 1179 LPR August 1990
+
+
+ first column of each line as FORTRAN carriage control. The FORTRAN
+ standard limits this to blank, "1", "0", and "+" carriage controls.
+ Most FORTRAN programmers also expect "-" (triple space) to work as
+ well.
+
+7.27 t - Print troff output file
+
+ +---+------+----+
+ | t | file | LF |
+ +---+------+----+
+ Command code - 't'
+ Operand - File to print
+
+ This command prints the data file as Graphic Systems C/A/T
+ phototypesetter input. [5] This is the standard output of the Unix
+ "troff" command.
+
+7.28 v - Print raster file
+
+ +---+------+----+
+ | v | file | LF |
+ +---+------+----+
+ Command code - 'v'
+ Operand - File to print
+
+ This command prints a Sun raster format file. [6]
+
+7.29 z - Reserved for future use with the Palladium print system.
+
+REFERENCES and BIBLIOGRAPHY
+
+ [1] Computer Science Research Group, "UNIX Programmer's Reference
+ Manual", USENIX, 1986.
+
+ [2] Hon and Sequin, "A Guide to LSI Implementation", XEROX PARC,
+ 1980.
+
+ [3] Knuth, D., "TeX The Program".
+
+ [4] Kernighan, B., "A Typesetter-independent TROFF".
+
+ [5] "Model C/A/T Phototypesetter", Graphic Systems, Inc. Hudson, N.H.
+
+ [6] Sun Microsystems, "Pixrect Reference Manual", Sun Microsystems,
+ Mountain View, CA, 1988.
+
+
+
+
+
+
+McLaughlin [Page 13]
+
+RFC 1179 LPR August 1990
+
+
+Security Considerations
+
+ Security issues are not discussed in this memo.
+
+Author's Address
+
+ Leo J. McLaughlin III
+ The Wollongong Group
+ 1129 San Antonio Road
+ Palo Alto, CA 94303
+
+ Phone: 415-962-7100
+
+ EMail: ljm@twg.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+McLaughlin [Page 14]
+ \ No newline at end of file
diff --git a/standards/rfc1321.txt b/standards/rfc1321.txt
new file mode 100644
index 000000000..68af27d2b
--- /dev/null
+++ b/standards/rfc1321.txt
@@ -0,0 +1,1179 @@
+
+
+
+
+
+
+Network Working Group R. Rivest
+Request for Comments: 1321 MIT Laboratory for Computer Science
+ and RSA Data Security, Inc.
+ April 1992
+
+
+ The MD5 Message-Digest Algorithm
+
+Status of this Memo
+
+ This memo provides information for the Internet community. It does
+ not specify an Internet standard. Distribution of this memo is
+ unlimited.
+
+Acknowlegements
+
+ We would like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle,
+ David Chaum, and Noam Nisan for numerous helpful comments and
+ suggestions.
+
+Table of Contents
+
+ 1. Executive Summary 1
+ 2. Terminology and Notation 2
+ 3. MD5 Algorithm Description 3
+ 4. Summary 6
+ 5. Differences Between MD4 and MD5 6
+ References 7
+ APPENDIX A - Reference Implementation 7
+ Security Considerations 21
+ Author's Address 21
+
+1. Executive Summary
+
+ This document describes the MD5 message-digest algorithm. The
+ algorithm takes as input a message of arbitrary length and produces
+ as output a 128-bit "fingerprint" or "message digest" of the input.
+ It is conjectured that it is computationally infeasible to produce
+ two messages having the same message digest, or to produce any
+ message having a given prespecified target message digest. The MD5
+ algorithm is intended for digital signature applications, where a
+ large file must be "compressed" in a secure manner before being
+ encrypted with a private (secret) key under a public-key cryptosystem
+ such as RSA.
+
+
+
+
+
+
+
+Rivest [Page 1]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ The MD5 algorithm is designed to be quite fast on 32-bit machines. In
+ addition, the MD5 algorithm does not require any large substitution
+ tables; the algorithm can be coded quite compactly.
+
+ The MD5 algorithm is an extension of the MD4 message-digest algorithm
+ 1,2]. MD5 is slightly slower than MD4, but is more "conservative" in
+ design. MD5 was designed because it was felt that MD4 was perhaps
+ being adopted for use more quickly than justified by the existing
+ critical review; because MD4 was designed to be exceptionally fast,
+ it is "at the edge" in terms of risking successful cryptanalytic
+ attack. MD5 backs off a bit, giving up a little in speed for a much
+ greater likelihood of ultimate security. It incorporates some
+ suggestions made by various reviewers, and contains additional
+ optimizations. The MD5 algorithm is being placed in the public domain
+ for review and possible adoption as a standard.
+
+ For OSI-based applications, MD5's object identifier is
+
+ md5 OBJECT IDENTIFIER ::=
+ iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5}
+
+ In the X.509 type AlgorithmIdentifier [3], the parameters for MD5
+ should have type NULL.
+
+2. Terminology and Notation
+
+ In this document a "word" is a 32-bit quantity and a "byte" is an
+ eight-bit quantity. A sequence of bits can be interpreted in a
+ natural manner as a sequence of bytes, where each consecutive group
+ of eight bits is interpreted as a byte with the high-order (most
+ significant) bit of each byte listed first. Similarly, a sequence of
+ bytes can be interpreted as a sequence of 32-bit words, where each
+ consecutive group of four bytes is interpreted as a word with the
+ low-order (least significant) byte given first.
+
+ Let x_i denote "x sub i". If the subscript is an expression, we
+ surround it in braces, as in x_{i+1}. Similarly, we use ^ for
+ superscripts (exponentiation), so that x^i denotes x to the i-th
+ power.
+
+ Let the symbol "+" denote addition of words (i.e., modulo-2^32
+ addition). Let X <<< s denote the 32-bit value obtained by circularly
+ shifting (rotating) X left by s bit positions. Let not(X) denote the
+ bit-wise complement of X, and let X v Y denote the bit-wise OR of X
+ and Y. Let X xor Y denote the bit-wise XOR of X and Y, and let XY
+ denote the bit-wise AND of X and Y.
+
+
+
+
+
+Rivest [Page 2]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+3. MD5 Algorithm Description
+
+ We begin by supposing that we have a b-bit message as input, and that
+ we wish to find its message digest. Here b is an arbitrary
+ nonnegative integer; b may be zero, it need not be a multiple of
+ eight, and it may be arbitrarily large. We imagine the bits of the
+ message written down as follows:
+
+ m_0 m_1 ... m_{b-1}
+
+ The following five steps are performed to compute the message digest
+ of the message.
+
+3.1 Step 1. Append Padding Bits
+
+ The message is "padded" (extended) so that its length (in bits) is
+ congruent to 448, modulo 512. That is, the message is extended so
+ that it is just 64 bits shy of being a multiple of 512 bits long.
+ Padding is always performed, even if the length of the message is
+ already congruent to 448, modulo 512.
+
+ Padding is performed as follows: a single "1" bit is appended to the
+ message, and then "0" bits are appended so that the length in bits of
+ the padded message becomes congruent to 448, modulo 512. In all, at
+ least one bit and at most 512 bits are appended.
+
+3.2 Step 2. Append Length
+
+ A 64-bit representation of b (the length of the message before the
+ padding bits were added) is appended to the result of the previous
+ step. In the unlikely event that b is greater than 2^64, then only
+ the low-order 64 bits of b are used. (These bits are appended as two
+ 32-bit words and appended low-order word first in accordance with the
+ previous conventions.)
+
+ At this point the resulting message (after padding with bits and with
+ b) has a length that is an exact multiple of 512 bits. Equivalently,
+ this message has a length that is an exact multiple of 16 (32-bit)
+ words. Let M[0 ... N-1] denote the words of the resulting message,
+ where N is a multiple of 16.
+
+3.3 Step 3. Initialize MD Buffer
+
+ A four-word buffer (A,B,C,D) is used to compute the message digest.
+ Here each of A, B, C, D is a 32-bit register. These registers are
+ initialized to the following values in hexadecimal, low-order bytes
+ first):
+
+
+
+
+Rivest [Page 3]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ word A: 01 23 45 67
+ word B: 89 ab cd ef
+ word C: fe dc ba 98
+ word D: 76 54 32 10
+
+3.4 Step 4. Process Message in 16-Word Blocks
+
+ We first define four auxiliary functions that each take as input
+ three 32-bit words and produce as output one 32-bit word.
+
+ F(X,Y,Z) = XY v not(X) Z
+ G(X,Y,Z) = XZ v Y not(Z)
+ H(X,Y,Z) = X xor Y xor Z
+ I(X,Y,Z) = Y xor (X v not(Z))
+
+ In each bit position F acts as a conditional: if X then Y else Z.
+ The function F could have been defined using + instead of v since XY
+ and not(X)Z will never have 1's in the same bit position.) It is
+ interesting to note that if the bits of X, Y, and Z are independent
+ and unbiased, the each bit of F(X,Y,Z) will be independent and
+ unbiased.
+
+ The functions G, H, and I are similar to the function F, in that they
+ act in "bitwise parallel" to produce their output from the bits of X,
+ Y, and Z, in such a manner that if the corresponding bits of X, Y,
+ and Z are independent and unbiased, then each bit of G(X,Y,Z),
+ H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that
+ the function H is the bit-wise "xor" or "parity" function of its
+ inputs.
+
+ This step uses a 64-element table T[1 ... 64] constructed from the
+ sine function. Let T[i] denote the i-th element of the table, which
+ is equal to the integer part of 4294967296 times abs(sin(i)), where i
+ is in radians. The elements of the table are given in the appendix.
+
+ Do the following:
+
+ /* Process each 16-word block. */
+ For i = 0 to N/16-1 do
+
+ /* Copy block i into X. */
+ For j = 0 to 15 do
+ Set X[j] to M[i*16+j].
+ end /* of loop on j */
+
+ /* Save A as AA, B as BB, C as CC, and D as DD. */
+ AA = A
+ BB = B
+
+
+
+Rivest [Page 4]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ CC = C
+ DD = D
+
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
+ [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
+ [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
+ [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]
+
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
+ [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
+ [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
+ [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]
+
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
+ [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
+ [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
+ [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]
+
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+ /* Do the following 16 operations. */
+ [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]
+ [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
+ [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60]
+ [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64]
+
+ /* Then perform the following additions. (That is increment each
+ of the four registers by the value it had before this block
+ was started.) */
+ A = A + AA
+ B = B + BB
+ C = C + CC
+ D = D + DD
+
+ end /* of loop on i */
+
+
+
+Rivest [Page 5]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+3.5 Step 5. Output
+
+ The message digest produced as output is A, B, C, D. That is, we
+ begin with the low-order byte of A, and end with the high-order byte
+ of D.
+
+ This completes the description of MD5. A reference implementation in
+ C is given in the appendix.
+
+4. Summary
+
+ The MD5 message-digest algorithm is simple to implement, and provides
+ a "fingerprint" or message digest of a message of arbitrary length.
+ It is conjectured that the difficulty of coming up with two messages
+ having the same message digest is on the order of 2^64 operations,
+ and that the difficulty of coming up with any message having a given
+ message digest is on the order of 2^128 operations. The MD5 algorithm
+ has been carefully scrutinized for weaknesses. It is, however, a
+ relatively new algorithm and further security analysis is of course
+ justified, as is the case with any new proposal of this sort.
+
+5. Differences Between MD4 and MD5
+
+ The following are the differences between MD4 and MD5:
+
+ 1. A fourth round has been added.
+
+ 2. Each step now has a unique additive constant.
+
+ 3. The function g in round 2 was changed from (XY v XZ v YZ) to
+ (XZ v Y not(Z)) to make g less symmetric.
+
+ 4. Each step now adds in the result of the previous step. This
+ promotes a faster "avalanche effect".
+
+ 5. The order in which input words are accessed in rounds 2 and
+ 3 is changed, to make these patterns less like each other.
+
+ 6. The shift amounts in each round have been approximately
+ optimized, to yield a faster "avalanche effect." The shifts in
+ different rounds are distinct.
+
+
+
+
+
+
+
+
+
+
+Rivest [Page 6]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+References
+
+ [1] Rivest, R., "The MD4 Message Digest Algorithm", RFC 1320, MIT and
+ RSA Data Security, Inc., April 1992.
+
+ [2] Rivest, R., "The MD4 message digest algorithm", in A.J. Menezes
+ and S.A. Vanstone, editors, Advances in Cryptology - CRYPTO '90
+ Proceedings, pages 303-311, Springer-Verlag, 1991.
+
+ [3] CCITT Recommendation X.509 (1988), "The Directory -
+ Authentication Framework."
+
+APPENDIX A - Reference Implementation
+
+ This appendix contains the following files taken from RSAREF: A
+ Cryptographic Toolkit for Privacy-Enhanced Mail:
+
+ global.h -- global header file
+
+ md5.h -- header file for MD5
+
+ md5c.c -- source code for MD5
+
+ For more information on RSAREF, send email to <rsaref@rsa.com>.
+
+ The appendix also includes the following file:
+
+ mddriver.c -- test driver for MD2, MD4 and MD5
+
+ The driver compiles for MD5 by default but can compile for MD2 or MD4
+ if the symbol MD is defined on the C compiler command line as 2 or 4.
+
+ The implementation is portable and should work on many different
+ plaforms. However, it is not difficult to optimize the implementation
+ on particular platforms, an exercise left to the reader. For example,
+ on "little-endian" platforms where the lowest-addressed byte in a 32-
+ bit word is the least significant and there are no alignment
+ restrictions, the call to Decode in MD5Transform can be replaced with
+ a typecast.
+
+A.1 global.h
+
+/* GLOBAL.H - RSAREF types and constants
+ */
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+ function argument prototyping.
+The following makes PROTOTYPES default to 0 if it has not already
+
+
+
+Rivest [Page 7]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ been defined with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#define PROTOTYPES 0
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef unsigned short int UINT2;
+
+/* UINT4 defines a four byte word */
+typedef unsigned long int UINT4;
+
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+ returns an empty list.
+ */
+#if PROTOTYPES
+#define PROTO_LIST(list) list
+#else
+#define PROTO_LIST(list) ()
+#endif
+
+A.2 md5.h
+
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+
+
+
+Rivest [Page 8]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* MD5 context. */
+typedef struct {
+ UINT4 state[4]; /* state (ABCD) */
+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} MD5_CTX;
+
+void MD5Init PROTO_LIST ((MD5_CTX *));
+void MD5Update PROTO_LIST
+ ((MD5_CTX *, unsigned char *, unsigned int));
+void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+
+A.3 md5c.c
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#include "global.h"
+#include "md5.h"
+
+/* Constants for MD5Transform routine.
+ */
+
+
+
+Rivest [Page 9]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST
+ ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+ ((UINT4 *, unsigned char *, unsigned int));
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+
+static unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+
+
+
+Rivest [Page 10]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void MD5Init (context)
+MD5_CTX *context; /* context */
+{
+ context->count[0] = context->count[1] = 0;
+ /* Load magic initialization constants.
+*/
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+ operation, processing another message block, and updating the
+ context.
+ */
+void MD5Update (context, input, inputLen)
+MD5_CTX *context; /* context */
+unsigned char *input; /* input block */
+unsigned int inputLen; /* length of input block */
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3))
+
+
+
+Rivest [Page 11]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible.
+*/
+ if (inputLen >= partLen) {
+ MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform (context->state, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+ inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+ the message digest and zeroizing the context.
+ */
+void MD5Final (digest, context)
+unsigned char digest[16]; /* message digest */
+MD5_CTX *context; /* context */
+{
+ unsigned char bits[8];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64.
+*/
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ MD5Update (context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ MD5Update (context, bits, 8);
+
+
+
+Rivest [Page 12]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ /* Store state in digest */
+ Encode (digest, context->state, 16);
+
+ /* Zeroize sensitive information.
+*/
+ MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (state, block)
+UINT4 state[4];
+unsigned char block[64];
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode (x, block, 64);
+
+ /* Round 1 */
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+
+
+
+Rivest [Page 13]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information.
+
+
+
+Rivest [Page 14]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+*/
+ MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+ a multiple of 4.
+ */
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+ a multiple of 4.
+ */
+static void Decode (output, input, len)
+UINT4 *output;
+unsigned char *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+
+
+
+Rivest [Page 15]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ output[i] = input[i];
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ ((char *)output)[i] = (char)value;
+}
+
+A.4 mddriver.c
+
+/* MDDRIVER.C - test driver for MD2, MD4 and MD5
+ */
+
+/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+rights reserved.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* The following makes MD default to MD5 if it has not already been
+ defined with C compiler flags.
+ */
+#ifndef MD
+#define MD MD5
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include "global.h"
+#if MD == 2
+#include "md2.h"
+#endif
+#if MD == 4
+
+
+
+Rivest [Page 16]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+#include "md4.h"
+#endif
+#if MD == 5
+#include "md5.h"
+#endif
+
+/* Length of test block, number of test blocks.
+ */
+#define TEST_BLOCK_LEN 1000
+#define TEST_BLOCK_COUNT 1000
+
+static void MDString PROTO_LIST ((char *));
+static void MDTimeTrial PROTO_LIST ((void));
+static void MDTestSuite PROTO_LIST ((void));
+static void MDFile PROTO_LIST ((char *));
+static void MDFilter PROTO_LIST ((void));
+static void MDPrint PROTO_LIST ((unsigned char [16]));
+
+#if MD == 2
+#define MD_CTX MD2_CTX
+#define MDInit MD2Init
+#define MDUpdate MD2Update
+#define MDFinal MD2Final
+#endif
+#if MD == 4
+#define MD_CTX MD4_CTX
+#define MDInit MD4Init
+#define MDUpdate MD4Update
+#define MDFinal MD4Final
+#endif
+#if MD == 5
+#define MD_CTX MD5_CTX
+#define MDInit MD5Init
+#define MDUpdate MD5Update
+#define MDFinal MD5Final
+#endif
+
+/* Main driver.
+
+Arguments (may be any combination):
+ -sstring - digests string
+ -t - runs time trial
+ -x - runs test script
+ filename - digests file
+ (none) - digests standard input
+ */
+int main (argc, argv)
+int argc;
+
+
+
+Rivest [Page 17]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+char *argv[];
+{
+ int i;
+
+ if (argc > 1)
+ for (i = 1; i < argc; i++)
+ if (argv[i][0] == '-' && argv[i][1] == 's')
+ MDString (argv[i] + 2);
+ else if (strcmp (argv[i], "-t") == 0)
+ MDTimeTrial ();
+ else if (strcmp (argv[i], "-x") == 0)
+ MDTestSuite ();
+ else
+ MDFile (argv[i]);
+ else
+ MDFilter ();
+
+ return (0);
+}
+
+/* Digests a string and prints the result.
+ */
+static void MDString (string)
+char *string;
+{
+ MD_CTX context;
+ unsigned char digest[16];
+ unsigned int len = strlen (string);
+
+ MDInit (&context);
+ MDUpdate (&context, string, len);
+ MDFinal (digest, &context);
+
+ printf ("MD%d (\"%s\") = ", MD, string);
+ MDPrint (digest);
+ printf ("\n");
+}
+
+/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte
+ blocks.
+ */
+static void MDTimeTrial ()
+{
+ MD_CTX context;
+ time_t endTime, startTime;
+ unsigned char block[TEST_BLOCK_LEN], digest[16];
+ unsigned int i;
+
+
+
+
+Rivest [Page 18]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ printf
+ ("MD%d time trial. Digesting %d %d-byte blocks ...", MD,
+ TEST_BLOCK_LEN, TEST_BLOCK_COUNT);
+
+ /* Initialize block */
+ for (i = 0; i < TEST_BLOCK_LEN; i++)
+ block[i] = (unsigned char)(i & 0xff);
+
+ /* Start timer */
+ time (&startTime);
+
+ /* Digest blocks */
+ MDInit (&context);
+ for (i = 0; i < TEST_BLOCK_COUNT; i++)
+ MDUpdate (&context, block, TEST_BLOCK_LEN);
+ MDFinal (digest, &context);
+
+ /* Stop timer */
+ time (&endTime);
+
+ printf (" done\n");
+ printf ("Digest = ");
+ MDPrint (digest);
+ printf ("\nTime = %ld seconds\n", (long)(endTime-startTime));
+ printf
+ ("Speed = %ld bytes/second\n",
+ (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime));
+}
+
+/* Digests a reference suite of strings and prints the results.
+ */
+static void MDTestSuite ()
+{
+ printf ("MD%d test suite:\n", MD);
+
+ MDString ("");
+ MDString ("a");
+ MDString ("abc");
+ MDString ("message digest");
+ MDString ("abcdefghijklmnopqrstuvwxyz");
+ MDString
+ ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+ MDString
+ ("1234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890");
+}
+
+/* Digests a file and prints the result.
+
+
+
+Rivest [Page 19]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ */
+static void MDFile (filename)
+char *filename;
+{
+ FILE *file;
+ MD_CTX context;
+ int len;
+ unsigned char buffer[1024], digest[16];
+
+ if ((file = fopen (filename, "rb")) == NULL)
+ printf ("%s can't be opened\n", filename);
+
+ else {
+ MDInit (&context);
+ while (len = fread (buffer, 1, 1024, file))
+ MDUpdate (&context, buffer, len);
+ MDFinal (digest, &context);
+
+ fclose (file);
+
+ printf ("MD%d (%s) = ", MD, filename);
+ MDPrint (digest);
+ printf ("\n");
+ }
+}
+
+/* Digests the standard input and prints the result.
+ */
+static void MDFilter ()
+{
+ MD_CTX context;
+ int len;
+ unsigned char buffer[16], digest[16];
+
+ MDInit (&context);
+ while (len = fread (buffer, 1, 16, stdin))
+ MDUpdate (&context, buffer, len);
+ MDFinal (digest, &context);
+
+ MDPrint (digest);
+ printf ("\n");
+}
+
+/* Prints a message digest in hexadecimal.
+ */
+static void MDPrint (digest)
+unsigned char digest[16];
+{
+
+
+
+Rivest [Page 20]
+
+RFC 1321 MD5 Message-Digest Algorithm April 1992
+
+
+ unsigned int i;
+
+ for (i = 0; i < 16; i++)
+ printf ("%02x", digest[i]);
+}
+
+A.5 Test suite
+
+ The MD5 test suite (driver option "-x") should print the following
+ results:
+
+MD5 test suite:
+MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
+MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
+MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
+MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
+MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
+MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
+d174ab98d277d9f5a5611c2c9f419d9f
+MD5 ("123456789012345678901234567890123456789012345678901234567890123456
+78901234567890") = 57edf4a22be3c955ac49da2e2107b67a
+
+Security Considerations
+
+ The level of security discussed in this memo is considered to be
+ sufficient for implementing very high security hybrid digital-
+ signature schemes based on MD5 and a public-key cryptosystem.
+
+Author's Address
+
+ Ronald L. Rivest
+ Massachusetts Institute of Technology
+ Laboratory for Computer Science
+ NE43-324
+ 545 Technology Square
+ Cambridge, MA 02139-1986
+
+ Phone: (617) 253-5880
+ EMail: rivest@theory.lcs.mit.edu
+
+
+
+
+
+
+
+
+
+
+
+
+Rivest [Page 21]
+ \ No newline at end of file
diff --git a/standards/rfc2246.txt b/standards/rfc2246.txt
new file mode 100644
index 000000000..2e838cf5d
--- /dev/null
+++ b/standards/rfc2246.txt
@@ -0,0 +1,4483 @@
+
+
+
+
+
+
+Network Working Group T. Dierks
+Request for Comments: 2246 Certicom
+Category: Standards Track C. Allen
+ Certicom
+ January 1999
+
+
+ The TLS Protocol
+ Version 1.0
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+Abstract
+
+ This document specifies Version 1.0 of the Transport Layer Security
+ (TLS) protocol. The TLS protocol provides communications privacy over
+ the Internet. The protocol allows client/server applications to
+ communicate in a way that is designed to prevent eavesdropping,
+ tampering, or message forgery.
+
+Table of Contents
+
+ 1. Introduction 3
+ 2. Goals 4
+ 3. Goals of this document 5
+ 4. Presentation language 5
+ 4.1. Basic block size 6
+ 4.2. Miscellaneous 6
+ 4.3. Vectors 6
+ 4.4. Numbers 7
+ 4.5. Enumerateds 7
+ 4.6. Constructed types 8
+ 4.6.1. Variants 9
+ 4.7. Cryptographic attributes 10
+ 4.8. Constants 11
+ 5. HMAC and the pseudorandom function 11
+ 6. The TLS Record Protocol 13
+ 6.1. Connection states 14
+
+
+
+Dierks & Allen Standards Track [Page 1]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ 6.2. Record layer 16
+ 6.2.1. Fragmentation 16
+ 6.2.2. Record compression and decompression 17
+ 6.2.3. Record payload protection 18
+ 6.2.3.1. Null or standard stream cipher 19
+ 6.2.3.2. CBC block cipher 19
+ 6.3. Key calculation 21
+ 6.3.1. Export key generation example 22
+ 7. The TLS Handshake Protocol 23
+ 7.1. Change cipher spec protocol 24
+ 7.2. Alert protocol 24
+ 7.2.1. Closure alerts 25
+ 7.2.2. Error alerts 26
+ 7.3. Handshake Protocol overview 29
+ 7.4. Handshake protocol 32
+ 7.4.1. Hello messages 33
+ 7.4.1.1. Hello request 33
+ 7.4.1.2. Client hello 34
+ 7.4.1.3. Server hello 36
+ 7.4.2. Server certificate 37
+ 7.4.3. Server key exchange message 39
+ 7.4.4. Certificate request 41
+ 7.4.5. Server hello done 42
+ 7.4.6. Client certificate 43
+ 7.4.7. Client key exchange message 43
+ 7.4.7.1. RSA encrypted premaster secret message 44
+ 7.4.7.2. Client Diffie-Hellman public value 45
+ 7.4.8. Certificate verify 45
+ 7.4.9. Finished 46
+ 8. Cryptographic computations 47
+ 8.1. Computing the master secret 47
+ 8.1.1. RSA 48
+ 8.1.2. Diffie-Hellman 48
+ 9. Mandatory Cipher Suites 48
+ 10. Application data protocol 48
+ A. Protocol constant values 49
+ A.1. Record layer 49
+ A.2. Change cipher specs message 50
+ A.3. Alert messages 50
+ A.4. Handshake protocol 51
+ A.4.1. Hello messages 51
+ A.4.2. Server authentication and key exchange messages 52
+ A.4.3. Client authentication and key exchange messages 53
+ A.4.4. Handshake finalization message 54
+ A.5. The CipherSuite 54
+ A.6. The Security Parameters 56
+ B. Glossary 57
+ C. CipherSuite definitions 61
+
+
+
+Dierks & Allen Standards Track [Page 2]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ D. Implementation Notes 64
+ D.1. Temporary RSA keys 64
+ D.2. Random Number Generation and Seeding 64
+ D.3. Certificates and authentication 65
+ D.4. CipherSuites 65
+ E. Backward Compatibility With SSL 66
+ E.1. Version 2 client hello 67
+ E.2. Avoiding man-in-the-middle version rollback 68
+ F. Security analysis 69
+ F.1. Handshake protocol 69
+ F.1.1. Authentication and key exchange 69
+ F.1.1.1. Anonymous key exchange 69
+ F.1.1.2. RSA key exchange and authentication 70
+ F.1.1.3. Diffie-Hellman key exchange with authentication 71
+ F.1.2. Version rollback attacks 71
+ F.1.3. Detecting attacks against the handshake protocol 72
+ F.1.4. Resuming sessions 72
+ F.1.5. MD5 and SHA 72
+ F.2. Protecting application data 72
+ F.3. Final notes 73
+ G. Patent Statement 74
+ Security Considerations 75
+ References 75
+ Credits 77
+ Comments 78
+ Full Copyright Statement 80
+
+1. Introduction
+
+ The primary goal of the TLS Protocol is to provide privacy and data
+ integrity between two communicating applications. The protocol is
+ composed of two layers: the TLS Record Protocol and the TLS Handshake
+ Protocol. At the lowest level, layered on top of some reliable
+ transport protocol (e.g., TCP[TCP]), is the TLS Record Protocol. The
+ TLS Record Protocol provides connection security that has two basic
+ properties:
+
+ - The connection is private. Symmetric cryptography is used for
+ data encryption (e.g., DES [DES], RC4 [RC4], etc.) The keys for
+ this symmetric encryption are generated uniquely for each
+ connection and are based on a secret negotiated by another
+ protocol (such as the TLS Handshake Protocol). The Record
+ Protocol can also be used without encryption.
+
+ - The connection is reliable. Message transport includes a message
+ integrity check using a keyed MAC. Secure hash functions (e.g.,
+ SHA, MD5, etc.) are used for MAC computations. The Record
+ Protocol can operate without a MAC, but is generally only used in
+
+
+
+Dierks & Allen Standards Track [Page 3]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ this mode while another protocol is using the Record Protocol as
+ a transport for negotiating security parameters.
+
+ The TLS Record Protocol is used for encapsulation of various higher
+ level protocols. One such encapsulated protocol, the TLS Handshake
+ Protocol, allows the server and client to authenticate each other and
+ to negotiate an encryption algorithm and cryptographic keys before
+ the application protocol transmits or receives its first byte of
+ data. The TLS Handshake Protocol provides connection security that
+ has three basic properties:
+
+ - The peer's identity can be authenticated using asymmetric, or
+ public key, cryptography (e.g., RSA [RSA], DSS [DSS], etc.). This
+ authentication can be made optional, but is generally required
+ for at least one of the peers.
+
+ - The negotiation of a shared secret is secure: the negotiated
+ secret is unavailable to eavesdroppers, and for any authenticated
+ connection the secret cannot be obtained, even by an attacker who
+ can place himself in the middle of the connection.
+
+ - The negotiation is reliable: no attacker can modify the
+ negotiation communication without being detected by the parties
+ to the communication.
+
+ One advantage of TLS is that it is application protocol independent.
+ Higher level protocols can layer on top of the TLS Protocol
+ transparently. The TLS standard, however, does not specify how
+ protocols add security with TLS; the decisions on how to initiate TLS
+ handshaking and how to interpret the authentication certificates
+ exchanged are left up to the judgment of the designers and
+ implementors of protocols which run on top of TLS.
+
+2. Goals
+
+ The goals of TLS Protocol, in order of their priority, are:
+
+ 1. Cryptographic security: TLS should be used to establish a secure
+ connection between two parties.
+
+ 2. Interoperability: Independent programmers should be able to
+ develop applications utilizing TLS that will then be able to
+ successfully exchange cryptographic parameters without knowledge
+ of one another's code.
+
+ 3. Extensibility: TLS seeks to provide a framework into which new
+ public key and bulk encryption methods can be incorporated as
+ necessary. This will also accomplish two sub-goals: to prevent
+
+
+
+Dierks & Allen Standards Track [Page 4]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ the need to create a new protocol (and risking the introduction
+ of possible new weaknesses) and to avoid the need to implement an
+ entire new security library.
+
+ 4. Relative efficiency: Cryptographic operations tend to be highly
+ CPU intensive, particularly public key operations. For this
+ reason, the TLS protocol has incorporated an optional session
+ caching scheme to reduce the number of connections that need to
+ be established from scratch. Additionally, care has been taken to
+ reduce network activity.
+
+3. Goals of this document
+
+ This document and the TLS protocol itself are based on the SSL 3.0
+ Protocol Specification as published by Netscape. The differences
+ between this protocol and SSL 3.0 are not dramatic, but they are
+ significant enough that TLS 1.0 and SSL 3.0 do not interoperate
+ (although TLS 1.0 does incorporate a mechanism by which a TLS
+ implementation can back down to SSL 3.0). This document is intended
+ primarily for readers who will be implementing the protocol and those
+ doing cryptographic analysis of it. The specification has been
+ written with this in mind, and it is intended to reflect the needs of
+ those two groups. For that reason, many of the algorithm-dependent
+ data structures and rules are included in the body of the text (as
+ opposed to in an appendix), providing easier access to them.
+
+ This document is not intended to supply any details of service
+ definition nor interface definition, although it does cover select
+ areas of policy as they are required for the maintenance of solid
+ security.
+
+4. Presentation language
+
+ This document deals with the formatting of data in an external
+ representation. The following very basic and somewhat casually
+ defined presentation syntax will be used. The syntax draws from
+ several sources in its structure. Although it resembles the
+ programming language "C" in its syntax and XDR [XDR] in both its
+ syntax and intent, it would be risky to draw too many parallels. The
+ purpose of this presentation language is to document TLS only, not to
+ have general application beyond that particular goal.
+
+
+
+
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 5]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+4.1. Basic block size
+
+ The representation of all data items is explicitly specified. The
+ basic data block size is one byte (i.e. 8 bits). Multiple byte data
+ items are concatenations of bytes, from left to right, from top to
+ bottom. From the bytestream a multi-byte item (a numeric in the
+ example) is formed (using C notation) by:
+
+ value = (byte[0] << 8*(n-1)) | (byte[1] << 8*(n-2)) |
+ ... | byte[n-1];
+
+ This byte ordering for multi-byte values is the commonplace network
+ byte order or big endian format.
+
+4.2. Miscellaneous
+
+ Comments begin with "/*" and end with "*/".
+
+ Optional components are denoted by enclosing them in "[[ ]]" double
+ brackets.
+
+ Single byte entities containing uninterpreted data are of type
+ opaque.
+
+4.3. Vectors
+
+ A vector (single dimensioned array) is a stream of homogeneous data
+ elements. The size of the vector may be specified at documentation
+ time or left unspecified until runtime. In either case the length
+ declares the number of bytes, not the number of elements, in the
+ vector. The syntax for specifying a new type T' that is a fixed
+ length vector of type T is
+
+ T T'[n];
+
+ Here T' occupies n bytes in the data stream, where n is a multiple of
+ the size of T. The length of the vector is not included in the
+ encoded stream.
+
+ In the following example, Datum is defined to be three consecutive
+ bytes that the protocol does not interpret, while Data is three
+ consecutive Datum, consuming a total of nine bytes.
+
+ opaque Datum[3]; /* three uninterpreted bytes */
+ Datum Data[9]; /* 3 consecutive 3 byte vectors */
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 6]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Variable length vectors are defined by specifying a subrange of legal
+ lengths, inclusively, using the notation <floor..ceiling>. When
+ encoded, the actual length precedes the vector's contents in the byte
+ stream. The length will be in the form of a number consuming as many
+ bytes as required to hold the vector's specified maximum (ceiling)
+ length. A variable length vector with an actual length field of zero
+ is referred to as an empty vector.
+
+ T T'<floor..ceiling>;
+
+ In the following example, mandatory is a vector that must contain
+ between 300 and 400 bytes of type opaque. It can never be empty. The
+ actual length field consumes two bytes, a uint16, sufficient to
+ represent the value 400 (see Section 4.4). On the other hand, longer
+ can represent up to 800 bytes of data, or 400 uint16 elements, and it
+ may be empty. Its encoding will include a two byte actual length
+ field prepended to the vector. The length of an encoded vector must
+ be an even multiple of the length of a single element (for example, a
+ 17 byte vector of uint16 would be illegal).
+
+ opaque mandatory<300..400>;
+ /* length field is 2 bytes, cannot be empty */
+ uint16 longer<0..800>;
+ /* zero to 400 16-bit unsigned integers */
+
+4.4. Numbers
+
+ The basic numeric data type is an unsigned byte (uint8). All larger
+ numeric data types are formed from fixed length series of bytes
+ concatenated as described in Section 4.1 and are also unsigned. The
+ following numeric types are predefined.
+
+ uint8 uint16[2];
+ uint8 uint24[3];
+ uint8 uint32[4];
+ uint8 uint64[8];
+
+ All values, here and elsewhere in the specification, are stored in
+ "network" or "big-endian" order; the uint32 represented by the hex
+ bytes 01 02 03 04 is equivalent to the decimal value 16909060.
+
+4.5. Enumerateds
+
+ An additional sparse data type is available called enum. A field of
+ type enum can only assume the values declared in the definition.
+ Each definition is a different type. Only enumerateds of the same
+ type may be assigned or compared. Every element of an enumerated must
+
+
+
+
+Dierks & Allen Standards Track [Page 7]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ be assigned a value, as demonstrated in the following example. Since
+ the elements of the enumerated are not ordered, they can be assigned
+ any unique value, in any order.
+
+ enum { e1(v1), e2(v2), ... , en(vn) [[, (n)]] } Te;
+
+ Enumerateds occupy as much space in the byte stream as would its
+ maximal defined ordinal value. The following definition would cause
+ one byte to be used to carry fields of type Color.
+
+ enum { red(3), blue(5), white(7) } Color;
+
+ One may optionally specify a value without its associated tag to
+ force the width definition without defining a superfluous element.
+ In the following example, Taste will consume two bytes in the data
+ stream but can only assume the values 1, 2 or 4.
+
+ enum { sweet(1), sour(2), bitter(4), (32000) } Taste;
+
+ The names of the elements of an enumeration are scoped within the
+ defined type. In the first example, a fully qualified reference to
+ the second element of the enumeration would be Color.blue. Such
+ qualification is not required if the target of the assignment is well
+ specified.
+
+ Color color = Color.blue; /* overspecified, legal */
+ Color color = blue; /* correct, type implicit */
+
+ For enumerateds that are never converted to external representation,
+ the numerical information may be omitted.
+
+ enum { low, medium, high } Amount;
+
+4.6. Constructed types
+
+ Structure types may be constructed from primitive types for
+ convenience. Each specification declares a new, unique type. The
+ syntax for definition is much like that of C.
+
+ struct {
+ T1 f1;
+ T2 f2;
+ ...
+ Tn fn;
+ } [[T]];
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 8]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ The fields within a structure may be qualified using the type's name
+ using a syntax much like that available for enumerateds. For example,
+ T.f2 refers to the second field of the previous declaration.
+ Structure definitions may be embedded.
+
+4.6.1. Variants
+
+ Defined structures may have variants based on some knowledge that is
+ available within the environment. The selector must be an enumerated
+ type that defines the possible variants the structure defines. There
+ must be a case arm for every element of the enumeration declared in
+ the select. The body of the variant structure may be given a label
+ for reference. The mechanism by which the variant is selected at
+ runtime is not prescribed by the presentation language.
+
+ struct {
+ T1 f1;
+ T2 f2;
+ ....
+ Tn fn;
+ select (E) {
+ case e1: Te1;
+ case e2: Te2;
+ ....
+ case en: Ten;
+ } [[fv]];
+ } [[Tv]];
+
+ For example:
+
+ enum { apple, orange } VariantTag;
+ struct {
+ uint16 number;
+ opaque string<0..10>; /* variable length */
+ } V1;
+ struct {
+ uint32 number;
+ opaque string[10]; /* fixed length */
+ } V2;
+ struct {
+ select (VariantTag) { /* value of selector is implicit */
+ case apple: V1; /* VariantBody, tag = apple */
+ case orange: V2; /* VariantBody, tag = orange */
+ } variant_body; /* optional label on variant */
+ } VariantRecord;
+
+ Variant structures may be qualified (narrowed) by specifying a value
+ for the selector prior to the type. For example, a
+
+
+
+Dierks & Allen Standards Track [Page 9]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ orange VariantRecord
+
+ is a narrowed type of a VariantRecord containing a variant_body of
+ type V2.
+
+4.7. Cryptographic attributes
+
+ The four cryptographic operations digital signing, stream cipher
+ encryption, block cipher encryption, and public key encryption are
+ designated digitally-signed, stream-ciphered, block-ciphered, and
+ public-key-encrypted, respectively. A field's cryptographic
+ processing is specified by prepending an appropriate key word
+ designation before the field's type specification. Cryptographic keys
+ are implied by the current session state (see Section 6.1).
+
+ In digital signing, one-way hash functions are used as input for a
+ signing algorithm. A digitally-signed element is encoded as an opaque
+ vector <0..2^16-1>, where the length is specified by the signing
+ algorithm and key.
+
+ In RSA signing, a 36-byte structure of two hashes (one SHA and one
+ MD5) is signed (encrypted with the private key). It is encoded with
+ PKCS #1 block type 0 or type 1 as described in [PKCS1].
+
+ In DSS, the 20 bytes of the SHA hash are run directly through the
+ Digital Signing Algorithm with no additional hashing. This produces
+ two values, r and s. The DSS signature is an opaque vector, as above,
+ the contents of which are the DER encoding of:
+
+ Dss-Sig-Value ::= SEQUENCE {
+ r INTEGER,
+ s INTEGER
+ }
+
+ In stream cipher encryption, the plaintext is exclusive-ORed with an
+ identical amount of output generated from a cryptographically-secure
+ keyed pseudorandom number generator.
+
+ In block cipher encryption, every block of plaintext encrypts to a
+ block of ciphertext. All block cipher encryption is done in CBC
+ (Cipher Block Chaining) mode, and all items which are block-ciphered
+ will be an exact multiple of the cipher block length.
+
+ In public key encryption, a public key algorithm is used to encrypt
+ data in such a way that it can be decrypted only with the matching
+ private key. A public-key-encrypted element is encoded as an opaque
+ vector <0..2^16-1>, where the length is specified by the signing
+ algorithm and key.
+
+
+
+Dierks & Allen Standards Track [Page 10]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ An RSA encrypted value is encoded with PKCS #1 block type 2 as
+ described in [PKCS1].
+
+ In the following example:
+
+ stream-ciphered struct {
+ uint8 field1;
+ uint8 field2;
+ digitally-signed opaque hash[20];
+ } UserType;
+
+ The contents of hash are used as input for the signing algorithm,
+ then the entire structure is encrypted with a stream cipher. The
+ length of this structure, in bytes would be equal to 2 bytes for
+ field1 and field2, plus two bytes for the length of the signature,
+ plus the length of the output of the signing algorithm. This is known
+ due to the fact that the algorithm and key used for the signing are
+ known prior to encoding or decoding this structure.
+
+4.8. Constants
+
+ Typed constants can be defined for purposes of specification by
+ declaring a symbol of the desired type and assigning values to it.
+ Under-specified types (opaque, variable length vectors, and
+ structures that contain opaque) cannot be assigned values. No fields
+ of a multi-element structure or vector may be elided.
+
+ For example,
+
+ struct {
+ uint8 f1;
+ uint8 f2;
+ } Example1;
+
+ Example1 ex1 = {1, 4}; /* assigns f1 = 1, f2 = 4 */
+
+5. HMAC and the pseudorandom function
+
+ A number of operations in the TLS record and handshake layer required
+ a keyed MAC; this is a secure digest of some data protected by a
+ secret. Forging the MAC is infeasible without knowledge of the MAC
+ secret. The construction we use for this operation is known as HMAC,
+ described in [HMAC].
+
+ HMAC can be used with a variety of different hash algorithms. TLS
+ uses it in the handshake with two different algorithms: MD5 and SHA-
+ 1, denoting these as HMAC_MD5(secret, data) and HMAC_SHA(secret,
+
+
+
+
+Dierks & Allen Standards Track [Page 11]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ data). Additional hash algorithms can be defined by cipher suites and
+ used to protect record data, but MD5 and SHA-1 are hard coded into
+ the description of the handshaking for this version of the protocol.
+
+ In addition, a construction is required to do expansion of secrets
+ into blocks of data for the purposes of key generation or validation.
+ This pseudo-random function (PRF) takes as input a secret, a seed,
+ and an identifying label and produces an output of arbitrary length.
+
+ In order to make the PRF as secure as possible, it uses two hash
+ algorithms in a way which should guarantee its security if either
+ algorithm remains secure.
+
+ First, we define a data expansion function, P_hash(secret, data)
+ which uses a single hash function to expand a secret and seed into an
+ arbitrary quantity of output:
+
+ P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
+ HMAC_hash(secret, A(2) + seed) +
+ HMAC_hash(secret, A(3) + seed) + ...
+
+ Where + indicates concatenation.
+
+ A() is defined as:
+ A(0) = seed
+ A(i) = HMAC_hash(secret, A(i-1))
+
+ P_hash can be iterated as many times as is necessary to produce the
+ required quantity of data. For example, if P_SHA-1 was being used to
+ create 64 bytes of data, it would have to be iterated 4 times
+ (through A(4)), creating 80 bytes of output data; the last 16 bytes
+ of the final iteration would then be discarded, leaving 64 bytes of
+ output data.
+
+ TLS's PRF is created by splitting the secret into two halves and
+ using one half to generate data with P_MD5 and the other half to
+ generate data with P_SHA-1, then exclusive-or'ing the outputs of
+ these two expansion functions together.
+
+ S1 and S2 are the two halves of the secret and each is the same
+ length. S1 is taken from the first half of the secret, S2 from the
+ second half. Their length is created by rounding up the length of the
+ overall secret divided by two; thus, if the original secret is an odd
+ number of bytes long, the last byte of S1 will be the same as the
+ first byte of S2.
+
+ L_S = length in bytes of secret;
+ L_S1 = L_S2 = ceil(L_S / 2);
+
+
+
+Dierks & Allen Standards Track [Page 12]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ The secret is partitioned into two halves (with the possibility of
+ one shared byte) as described above, S1 taking the first L_S1 bytes
+ and S2 the last L_S2 bytes.
+
+ The PRF is then defined as the result of mixing the two pseudorandom
+ streams by exclusive-or'ing them together.
+
+ PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
+ P_SHA-1(S2, label + seed);
+
+ The label is an ASCII string. It should be included in the exact form
+ it is given without a length byte or trailing null character. For
+ example, the label "slithy toves" would be processed by hashing the
+ following bytes:
+
+ 73 6C 69 74 68 79 20 74 6F 76 65 73
+
+ Note that because MD5 produces 16 byte outputs and SHA-1 produces 20
+ byte outputs, the boundaries of their internal iterations will not be
+ aligned; to generate a 80 byte output will involve P_MD5 being
+ iterated through A(5), while P_SHA-1 will only iterate through A(4).
+
+6. The TLS Record Protocol
+
+ The TLS Record Protocol is a layered protocol. At each layer,
+ messages may include fields for length, description, and content.
+ The Record Protocol takes messages to be transmitted, fragments the
+ data into manageable blocks, optionally compresses the data, applies
+ a MAC, encrypts, and transmits the result. Received data is
+ decrypted, verified, decompressed, and reassembled, then delivered to
+ higher level clients.
+
+ Four record protocol clients are described in this document: the
+ handshake protocol, the alert protocol, the change cipher spec
+ protocol, and the application data protocol. In order to allow
+ extension of the TLS protocol, additional record types can be
+ supported by the record protocol. Any new record types should
+ allocate type values immediately beyond the ContentType values for
+ the four record types described here (see Appendix A.2). If a TLS
+ implementation receives a record type it does not understand, it
+ should just ignore it. Any protocol designed for use over TLS must be
+ carefully designed to deal with all possible attacks against it.
+ Note that because the type and length of a record are not protected
+ by encryption, care should be take to minimize the value of traffic
+ analysis of these values.
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 13]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+6.1. Connection states
+
+ A TLS connection state is the operating environment of the TLS Record
+ Protocol. It specifies a compression algorithm, encryption algorithm,
+ and MAC algorithm. In addition, the parameters for these algorithms
+ are known: the MAC secret and the bulk encryption keys and IVs for
+ the connection in both the read and the write directions. Logically,
+ there are always four connection states outstanding: the current read
+ and write states, and the pending read and write states. All records
+ are processed under the current read and write states. The security
+ parameters for the pending states can be set by the TLS Handshake
+ Protocol, and the Handshake Protocol can selectively make either of
+ the pending states current, in which case the appropriate current
+ state is disposed of and replaced with the pending state; the pending
+ state is then reinitialized to an empty state. It is illegal to make
+ a state which has not been initialized with security parameters a
+ current state. The initial current state always specifies that no
+ encryption, compression, or MAC will be used.
+
+ The security parameters for a TLS Connection read and write state are
+ set by providing the following values:
+
+ connection end
+ Whether this entity is considered the "client" or the "server" in
+ this connection.
+
+ bulk encryption algorithm
+ An algorithm to be used for bulk encryption. This specification
+ includes the key size of this algorithm, how much of that key is
+ secret, whether it is a block or stream cipher, the block size of
+ the cipher (if appropriate), and whether it is considered an
+ "export" cipher.
+
+ MAC algorithm
+ An algorithm to be used for message authentication. This
+ specification includes the size of the hash which is returned by
+ the MAC algorithm.
+
+ compression algorithm
+ An algorithm to be used for data compression. This specification
+ must include all information the algorithm requires to do
+ compression.
+
+ master secret
+ A 48 byte secret shared between the two peers in the connection.
+
+ client random
+ A 32 byte value provided by the client.
+
+
+
+Dierks & Allen Standards Track [Page 14]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ server random
+ A 32 byte value provided by the server.
+
+ These parameters are defined in the presentation language as:
+
+ enum { server, client } ConnectionEnd;
+
+ enum { null, rc4, rc2, des, 3des, des40 } BulkCipherAlgorithm;
+
+ enum { stream, block } CipherType;
+
+ enum { true, false } IsExportable;
+
+ enum { null, md5, sha } MACAlgorithm;
+
+ enum { null(0), (255) } CompressionMethod;
+
+ /* The algorithms specified in CompressionMethod,
+ BulkCipherAlgorithm, and MACAlgorithm may be added to. */
+
+ struct {
+ ConnectionEnd entity;
+ BulkCipherAlgorithm bulk_cipher_algorithm;
+ CipherType cipher_type;
+ uint8 key_size;
+ uint8 key_material_length;
+ IsExportable is_exportable;
+ MACAlgorithm mac_algorithm;
+ uint8 hash_size;
+ CompressionMethod compression_algorithm;
+ opaque master_secret[48];
+ opaque client_random[32];
+ opaque server_random[32];
+ } SecurityParameters;
+
+ The record layer will use the security parameters to generate the
+ following six items:
+
+ client write MAC secret
+ server write MAC secret
+ client write key
+ server write key
+ client write IV (for block ciphers only)
+ server write IV (for block ciphers only)
+
+ The client write parameters are used by the server when receiving and
+ processing records and vice-versa. The algorithm used for generating
+ these items from the security parameters is described in section 6.3.
+
+
+
+Dierks & Allen Standards Track [Page 15]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Once the security parameters have been set and the keys have been
+ generated, the connection states can be instantiated by making them
+ the current states. These current states must be updated for each
+ record processed. Each connection state includes the following
+ elements:
+
+ compression state
+ The current state of the compression algorithm.
+
+ cipher state
+ The current state of the encryption algorithm. This will consist
+ of the scheduled key for that connection. In addition, for block
+ ciphers running in CBC mode (the only mode specified for TLS),
+ this will initially contain the IV for that connection state and
+ be updated to contain the ciphertext of the last block encrypted
+ or decrypted as records are processed. For stream ciphers, this
+ will contain whatever the necessary state information is to allow
+ the stream to continue to encrypt or decrypt data.
+
+ MAC secret
+ The MAC secret for this connection as generated above.
+
+ sequence number
+ Each connection state contains a sequence number, which is
+ maintained separately for read and write states. The sequence
+ number must be set to zero whenever a connection state is made
+ the active state. Sequence numbers are of type uint64 and may not
+ exceed 2^64-1. A sequence number is incremented after each
+ record: specifically, the first record which is transmitted under
+ a particular connection state should use sequence number 0.
+
+6.2. Record layer
+
+ The TLS Record Layer receives uninterpreted data from higher layers
+ in non-empty blocks of arbitrary size.
+
+6.2.1. Fragmentation
+
+ The record layer fragments information blocks into TLSPlaintext
+ records carrying data in chunks of 2^14 bytes or less. Client message
+ boundaries are not preserved in the record layer (i.e., multiple
+ client messages of the same ContentType may be coalesced into a
+ single TLSPlaintext record, or a single message may be fragmented
+ across several records).
+
+ struct {
+ uint8 major, minor;
+ } ProtocolVersion;
+
+
+
+Dierks & Allen Standards Track [Page 16]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ enum {
+ change_cipher_spec(20), alert(21), handshake(22),
+ application_data(23), (255)
+ } ContentType;
+
+ struct {
+ ContentType type;
+ ProtocolVersion version;
+ uint16 length;
+ opaque fragment[TLSPlaintext.length];
+ } TLSPlaintext;
+
+ type
+ The higher level protocol used to process the enclosed fragment.
+
+ version
+ The version of the protocol being employed. This document
+ describes TLS Version 1.0, which uses the version { 3, 1 }. The
+ version value 3.1 is historical: TLS version 1.0 is a minor
+ modification to the SSL 3.0 protocol, which bears the version
+ value 3.0. (See Appendix A.1).
+
+ length
+ The length (in bytes) of the following TLSPlaintext.fragment.
+ The length should not exceed 2^14.
+
+ fragment
+ The application data. This data is transparent and treated as an
+ independent block to be dealt with by the higher level protocol
+ specified by the type field.
+
+ Note: Data of different TLS Record layer content types may be
+ interleaved. Application data is generally of lower precedence
+ for transmission than other content types.
+
+6.2.2. Record compression and decompression
+
+ All records are compressed using the compression algorithm defined in
+ the current session state. There is always an active compression
+ algorithm; however, initially it is defined as
+ CompressionMethod.null. The compression algorithm translates a
+ TLSPlaintext structure into a TLSCompressed structure. Compression
+ functions are initialized with default state information whenever a
+ connection state is made active.
+
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 17]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Compression must be lossless and may not increase the content length
+ by more than 1024 bytes. If the decompression function encounters a
+ TLSCompressed.fragment that would decompress to a length in excess of
+ 2^14 bytes, it should report a fatal decompression failure error.
+
+ struct {
+ ContentType type; /* same as TLSPlaintext.type */
+ ProtocolVersion version;/* same as TLSPlaintext.version */
+ uint16 length;
+ opaque fragment[TLSCompressed.length];
+ } TLSCompressed;
+
+ length
+ The length (in bytes) of the following TLSCompressed.fragment.
+ The length should not exceed 2^14 + 1024.
+
+ fragment
+ The compressed form of TLSPlaintext.fragment.
+
+ Note: A CompressionMethod.null operation is an identity operation; no
+ fields are altered.
+
+ Implementation note:
+ Decompression functions are responsible for ensuring that
+ messages cannot cause internal buffer overflows.
+
+6.2.3. Record payload protection
+
+ The encryption and MAC functions translate a TLSCompressed structure
+ into a TLSCiphertext. The decryption functions reverse the process.
+ The MAC of the record also includes a sequence number so that
+ missing, extra or repeated messages are detectable.
+
+ struct {
+ ContentType type;
+ ProtocolVersion version;
+ uint16 length;
+ select (CipherSpec.cipher_type) {
+ case stream: GenericStreamCipher;
+ case block: GenericBlockCipher;
+ } fragment;
+ } TLSCiphertext;
+
+ type
+ The type field is identical to TLSCompressed.type.
+
+ version
+ The version field is identical to TLSCompressed.version.
+
+
+
+Dierks & Allen Standards Track [Page 18]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ length
+ The length (in bytes) of the following TLSCiphertext.fragment.
+ The length may not exceed 2^14 + 2048.
+
+ fragment
+ The encrypted form of TLSCompressed.fragment, with the MAC.
+
+6.2.3.1. Null or standard stream cipher
+
+ Stream ciphers (including BulkCipherAlgorithm.null - see Appendix
+ A.6) convert TLSCompressed.fragment structures to and from stream
+ TLSCiphertext.fragment structures.
+
+ stream-ciphered struct {
+ opaque content[TLSCompressed.length];
+ opaque MAC[CipherSpec.hash_size];
+ } GenericStreamCipher;
+
+ The MAC is generated as:
+
+ HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
+ TLSCompressed.version + TLSCompressed.length +
+ TLSCompressed.fragment));
+
+ where "+" denotes concatenation.
+
+ seq_num
+ The sequence number for this record.
+
+ hash
+ The hashing algorithm specified by
+ SecurityParameters.mac_algorithm.
+
+ Note that the MAC is computed before encryption. The stream cipher
+ encrypts the entire block, including the MAC. For stream ciphers that
+ do not use a synchronization vector (such as RC4), the stream cipher
+ state from the end of one record is simply used on the subsequent
+ packet. If the CipherSuite is TLS_NULL_WITH_NULL_NULL, encryption
+ consists of the identity operation (i.e., the data is not encrypted
+ and the MAC size is zero implying that no MAC is used).
+ TLSCiphertext.length is TLSCompressed.length plus
+ CipherSpec.hash_size.
+
+6.2.3.2. CBC block cipher
+
+ For block ciphers (such as RC2 or DES), the encryption and MAC
+ functions convert TLSCompressed.fragment structures to and from block
+ TLSCiphertext.fragment structures.
+
+
+
+Dierks & Allen Standards Track [Page 19]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ block-ciphered struct {
+ opaque content[TLSCompressed.length];
+ opaque MAC[CipherSpec.hash_size];
+ uint8 padding[GenericBlockCipher.padding_length];
+ uint8 padding_length;
+ } GenericBlockCipher;
+
+ The MAC is generated as described in Section 6.2.3.1.
+
+ padding
+ Padding that is added to force the length of the plaintext to be
+ an integral multiple of the block cipher's block length. The
+ padding may be any length up to 255 bytes long, as long as it
+ results in the TLSCiphertext.length being an integral multiple of
+ the block length. Lengths longer than necessary might be
+ desirable to frustrate attacks on a protocol based on analysis of
+ the lengths of exchanged messages. Each uint8 in the padding data
+ vector must be filled with the padding length value.
+
+ padding_length
+ The padding length should be such that the total size of the
+ GenericBlockCipher structure is a multiple of the cipher's block
+ length. Legal values range from zero to 255, inclusive. This
+ length specifies the length of the padding field exclusive of the
+ padding_length field itself.
+
+ The encrypted data length (TLSCiphertext.length) is one more than the
+ sum of TLSCompressed.length, CipherSpec.hash_size, and
+ padding_length.
+
+ Example: If the block length is 8 bytes, the content length
+ (TLSCompressed.length) is 61 bytes, and the MAC length is 20
+ bytes, the length before padding is 82 bytes. Thus, the
+ padding length modulo 8 must be equal to 6 in order to make
+ the total length an even multiple of 8 bytes (the block
+ length). The padding length can be 6, 14, 22, and so on,
+ through 254. If the padding length were the minimum necessary,
+ 6, the padding would be 6 bytes, each containing the value 6.
+ Thus, the last 8 octets of the GenericBlockCipher before block
+ encryption would be xx 06 06 06 06 06 06 06, where xx is the
+ last octet of the MAC.
+
+ Note: With block ciphers in CBC mode (Cipher Block Chaining) the
+ initialization vector (IV) for the first record is generated with
+ the other keys and secrets when the security parameters are set.
+ The IV for subsequent records is the last ciphertext block from
+ the previous record.
+
+
+
+
+Dierks & Allen Standards Track [Page 20]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+6.3. Key calculation
+
+ The Record Protocol requires an algorithm to generate keys, IVs, and
+ MAC secrets from the security parameters provided by the handshake
+ protocol.
+
+ The master secret is hashed into a sequence of secure bytes, which
+ are assigned to the MAC secrets, keys, and non-export IVs required by
+ the current connection state (see Appendix A.6). CipherSpecs require
+ a client write MAC secret, a server write MAC secret, a client write
+ key, a server write key, a client write IV, and a server write IV,
+ which are generated from the master secret in that order. Unused
+ values are empty.
+
+ When generating keys and MAC secrets, the master secret is used as an
+ entropy source, and the random values provide unencrypted salt
+ material and IVs for exportable ciphers.
+
+ To generate the key material, compute
+
+ key_block = PRF(SecurityParameters.master_secret,
+ "key expansion",
+ SecurityParameters.server_random +
+ SecurityParameters.client_random);
+
+ until enough output has been generated. Then the key_block is
+ partitioned as follows:
+
+ client_write_MAC_secret[SecurityParameters.hash_size]
+ server_write_MAC_secret[SecurityParameters.hash_size]
+ client_write_key[SecurityParameters.key_material_length]
+ server_write_key[SecurityParameters.key_material_length]
+ client_write_IV[SecurityParameters.IV_size]
+ server_write_IV[SecurityParameters.IV_size]
+
+ The client_write_IV and server_write_IV are only generated for non-
+ export block ciphers. For exportable block ciphers, the
+ initialization vectors are generated later, as described below. Any
+ extra key_block material is discarded.
+
+ Implementation note:
+ The cipher spec which is defined in this document which requires
+ the most material is 3DES_EDE_CBC_SHA: it requires 2 x 24 byte
+ keys, 2 x 20 byte MAC secrets, and 2 x 8 byte IVs, for a total of
+ 104 bytes of key material.
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 21]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Exportable encryption algorithms (for which CipherSpec.is_exportable
+ is true) require additional processing as follows to derive their
+ final write keys:
+
+ final_client_write_key =
+ PRF(SecurityParameters.client_write_key,
+ "client write key",
+ SecurityParameters.client_random +
+ SecurityParameters.server_random);
+ final_server_write_key =
+ PRF(SecurityParameters.server_write_key,
+ "server write key",
+ SecurityParameters.client_random +
+ SecurityParameters.server_random);
+
+ Exportable encryption algorithms derive their IVs solely from the
+ random values from the hello messages:
+
+ iv_block = PRF("", "IV block", SecurityParameters.client_random +
+ SecurityParameters.server_random);
+
+ The iv_block is partitioned into two initialization vectors as the
+ key_block was above:
+
+ client_write_IV[SecurityParameters.IV_size]
+ server_write_IV[SecurityParameters.IV_size]
+
+ Note that the PRF is used without a secret in this case: this just
+ means that the secret has a length of zero bytes and contributes
+ nothing to the hashing in the PRF.
+
+6.3.1. Export key generation example
+
+ TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 requires five random bytes for
+ each of the two encryption keys and 16 bytes for each of the MAC
+ keys, for a total of 42 bytes of key material. The PRF output is
+ stored in the key_block. The key_block is partitioned, and the write
+ keys are salted because this is an exportable encryption algorithm.
+
+ key_block = PRF(master_secret,
+ "key expansion",
+ server_random +
+ client_random)[0..41]
+ client_write_MAC_secret = key_block[0..15]
+ server_write_MAC_secret = key_block[16..31]
+ client_write_key = key_block[32..36]
+ server_write_key = key_block[37..41]
+
+
+
+
+Dierks & Allen Standards Track [Page 22]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ final_client_write_key = PRF(client_write_key,
+ "client write key",
+ client_random +
+ server_random)[0..15]
+ final_server_write_key = PRF(server_write_key,
+ "server write key",
+ client_random +
+ server_random)[0..15]
+
+ iv_block = PRF("", "IV block", client_random +
+ server_random)[0..15]
+ client_write_IV = iv_block[0..7]
+ server_write_IV = iv_block[8..15]
+
+7. The TLS Handshake Protocol
+
+ The TLS Handshake Protocol consists of a suite of three sub-protocols
+ which are used to allow peers to agree upon security parameters for
+ the record layer, authenticate themselves, instantiate negotiated
+ security parameters, and report error conditions to each other.
+
+ The Handshake Protocol is responsible for negotiating a session,
+ which consists of the following items:
+
+ session identifier
+ An arbitrary byte sequence chosen by the server to identify an
+ active or resumable session state.
+
+ peer certificate
+ X509v3 [X509] certificate of the peer. This element of the state
+ may be null.
+
+ compression method
+ The algorithm used to compress data prior to encryption.
+
+ cipher spec
+ Specifies the bulk data encryption algorithm (such as null, DES,
+ etc.) and a MAC algorithm (such as MD5 or SHA). It also defines
+ cryptographic attributes such as the hash_size. (See Appendix A.6
+ for formal definition)
+
+ master secret
+ 48-byte secret shared between the client and server.
+
+ is resumable
+ A flag indicating whether the session can be used to initiate new
+ connections.
+
+
+
+
+Dierks & Allen Standards Track [Page 23]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ These items are then used to create security parameters for use by
+ the Record Layer when protecting application data. Many connections
+ can be instantiated using the same session through the resumption
+ feature of the TLS Handshake Protocol.
+
+7.1. Change cipher spec protocol
+
+ The change cipher spec protocol exists to signal transitions in
+ ciphering strategies. The protocol consists of a single message,
+ which is encrypted and compressed under the current (not the pending)
+ connection state. The message consists of a single byte of value 1.
+
+ struct {
+ enum { change_cipher_spec(1), (255) } type;
+ } ChangeCipherSpec;
+
+ The change cipher spec message is sent by both the client and server
+ to notify the receiving party that subsequent records will be
+ protected under the newly negotiated CipherSpec and keys. Reception
+ of this message causes the receiver to instruct the Record Layer to
+ immediately copy the read pending state into the read current state.
+ Immediately after sending this message, the sender should instruct
+ the record layer to make the write pending state the write active
+ state. (See section 6.1.) The change cipher spec message is sent
+ during the handshake after the security parameters have been agreed
+ upon, but before the verifying finished message is sent (see section
+ 7.4.9).
+
+7.2. Alert protocol
+
+ One of the content types supported by the TLS Record layer is the
+ alert type. Alert messages convey the severity of the message and a
+ description of the alert. Alert messages with a level of fatal result
+ in the immediate termination of the connection. In this case, other
+ connections corresponding to the session may continue, but the
+ session identifier must be invalidated, preventing the failed session
+ from being used to establish new connections. Like other messages,
+ alert messages are encrypted and compressed, as specified by the
+ current connection state.
+
+ enum { warning(1), fatal(2), (255) } AlertLevel;
+
+ enum {
+ close_notify(0),
+ unexpected_message(10),
+ bad_record_mac(20),
+ decryption_failed(21),
+ record_overflow(22),
+
+
+
+Dierks & Allen Standards Track [Page 24]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ decompression_failure(30),
+ handshake_failure(40),
+ bad_certificate(42),
+ unsupported_certificate(43),
+ certificate_revoked(44),
+ certificate_expired(45),
+ certificate_unknown(46),
+ illegal_parameter(47),
+ unknown_ca(48),
+ access_denied(49),
+ decode_error(50),
+ decrypt_error(51),
+ export_restriction(60),
+ protocol_version(70),
+ insufficient_security(71),
+ internal_error(80),
+ user_canceled(90),
+ no_renegotiation(100),
+ (255)
+ } AlertDescription;
+
+ struct {
+ AlertLevel level;
+ AlertDescription description;
+ } Alert;
+
+7.2.1. Closure alerts
+
+ The client and the server must share knowledge that the connection is
+ ending in order to avoid a truncation attack. Either party may
+ initiate the exchange of closing messages.
+
+ close_notify
+ This message notifies the recipient that the sender will not send
+ any more messages on this connection. The session becomes
+ unresumable if any connection is terminated without proper
+ close_notify messages with level equal to warning.
+
+ Either party may initiate a close by sending a close_notify alert.
+ Any data received after a closure alert is ignored.
+
+ Each party is required to send a close_notify alert before closing
+ the write side of the connection. It is required that the other party
+ respond with a close_notify alert of its own and close down the
+ connection immediately, discarding any pending writes. It is not
+ required for the initiator of the close to wait for the responding
+ close_notify alert before closing the read side of the connection.
+
+
+
+
+Dierks & Allen Standards Track [Page 25]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ If the application protocol using TLS provides that any data may be
+ carried over the underlying transport after the TLS connection is
+ closed, the TLS implementation must receive the responding
+ close_notify alert before indicating to the application layer that
+ the TLS connection has ended. If the application protocol will not
+ transfer any additional data, but will only close the underlying
+ transport connection, then the implementation may choose to close the
+ transport without waiting for the responding close_notify. No part of
+ this standard should be taken to dictate the manner in which a usage
+ profile for TLS manages its data transport, including when
+ connections are opened or closed.
+
+ NB: It is assumed that closing a connection reliably delivers
+ pending data before destroying the transport.
+
+7.2.2. Error alerts
+
+ Error handling in the TLS Handshake protocol is very simple. When an
+ error is detected, the detecting party sends a message to the other
+ party. Upon transmission or receipt of an fatal alert message, both
+ parties immediately close the connection. Servers and clients are
+ required to forget any session-identifiers, keys, and secrets
+ associated with a failed connection. The following error alerts are
+ defined:
+
+ unexpected_message
+ An inappropriate message was received. This alert is always fatal
+ and should never be observed in communication between proper
+ implementations.
+
+ bad_record_mac
+ This alert is returned if a record is received with an incorrect
+ MAC. This message is always fatal.
+
+ decryption_failed
+ A TLSCiphertext decrypted in an invalid way: either it wasn`t an
+ even multiple of the block length or its padding values, when
+ checked, weren`t correct. This message is always fatal.
+
+ record_overflow
+ A TLSCiphertext record was received which had a length more than
+ 2^14+2048 bytes, or a record decrypted to a TLSCompressed record
+ with more than 2^14+1024 bytes. This message is always fatal.
+
+ decompression_failure
+ The decompression function received improper input (e.g. data
+ that would expand to excessive length). This message is always
+ fatal.
+
+
+
+Dierks & Allen Standards Track [Page 26]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ handshake_failure
+ Reception of a handshake_failure alert message indicates that the
+ sender was unable to negotiate an acceptable set of security
+ parameters given the options available. This is a fatal error.
+
+ bad_certificate
+ A certificate was corrupt, contained signatures that did not
+ verify correctly, etc.
+
+ unsupported_certificate
+ A certificate was of an unsupported type.
+
+ certificate_revoked
+ A certificate was revoked by its signer.
+
+ certificate_expired
+ A certificate has expired or is not currently valid.
+
+ certificate_unknown
+ Some other (unspecified) issue arose in processing the
+ certificate, rendering it unacceptable.
+
+ illegal_parameter
+ A field in the handshake was out of range or inconsistent with
+ other fields. This is always fatal.
+
+ unknown_ca
+ A valid certificate chain or partial chain was received, but the
+ certificate was not accepted because the CA certificate could not
+ be located or couldn`t be matched with a known, trusted CA. This
+ message is always fatal.
+
+ access_denied
+ A valid certificate was received, but when access control was
+ applied, the sender decided not to proceed with negotiation.
+ This message is always fatal.
+
+ decode_error
+ A message could not be decoded because some field was out of the
+ specified range or the length of the message was incorrect. This
+ message is always fatal.
+
+ decrypt_error
+ A handshake cryptographic operation failed, including being
+ unable to correctly verify a signature, decrypt a key exchange,
+ or validate a finished message.
+
+
+
+
+
+Dierks & Allen Standards Track [Page 27]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ export_restriction
+ A negotiation not in compliance with export restrictions was
+ detected; for example, attempting to transfer a 1024 bit
+ ephemeral RSA key for the RSA_EXPORT handshake method. This
+ message is always fatal.
+
+ protocol_version
+ The protocol version the client has attempted to negotiate is
+ recognized, but not supported. (For example, old protocol
+ versions might be avoided for security reasons). This message is
+ always fatal.
+
+ insufficient_security
+ Returned instead of handshake_failure when a negotiation has
+ failed specifically because the server requires ciphers more
+ secure than those supported by the client. This message is always
+ fatal.
+
+ internal_error
+ An internal error unrelated to the peer or the correctness of the
+ protocol makes it impossible to continue (such as a memory
+ allocation failure). This message is always fatal.
+
+ user_canceled
+ This handshake is being canceled for some reason unrelated to a
+ protocol failure. If the user cancels an operation after the
+ handshake is complete, just closing the connection by sending a
+ close_notify is more appropriate. This alert should be followed
+ by a close_notify. This message is generally a warning.
+
+ no_renegotiation
+ Sent by the client in response to a hello request or by the
+ server in response to a client hello after initial handshaking.
+ Either of these would normally lead to renegotiation; when that
+ is not appropriate, the recipient should respond with this alert;
+ at that point, the original requester can decide whether to
+ proceed with the connection. One case where this would be
+ appropriate would be where a server has spawned a process to
+ satisfy a request; the process might receive security parameters
+ (key length, authentication, etc.) at startup and it might be
+ difficult to communicate changes to these parameters after that
+ point. This message is always a warning.
+
+ For all errors where an alert level is not explicitly specified, the
+ sending party may determine at its discretion whether this is a fatal
+ error or not; if an alert with a level of warning is received, the
+
+
+
+
+
+Dierks & Allen Standards Track [Page 28]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ receiving party may decide at its discretion whether to treat this as
+ a fatal error or not. However, all messages which are transmitted
+ with a level of fatal must be treated as fatal messages.
+
+7.3. Handshake Protocol overview
+
+ The cryptographic parameters of the session state are produced by the
+ TLS Handshake Protocol, which operates on top of the TLS Record
+ Layer. When a TLS client and server first start communicating, they
+ agree on a protocol version, select cryptographic algorithms,
+ optionally authenticate each other, and use public-key encryption
+ techniques to generate shared secrets.
+
+ The TLS Handshake Protocol involves the following steps:
+
+ - Exchange hello messages to agree on algorithms, exchange random
+ values, and check for session resumption.
+
+ - Exchange the necessary cryptographic parameters to allow the
+ client and server to agree on a premaster secret.
+
+ - Exchange certificates and cryptographic information to allow the
+ client and server to authenticate themselves.
+
+ - Generate a master secret from the premaster secret and exchanged
+ random values.
+
+ - Provide security parameters to the record layer.
+
+ - Allow the client and server to verify that their peer has
+ calculated the same security parameters and that the handshake
+ occurred without tampering by an attacker.
+
+ Note that higher layers should not be overly reliant on TLS always
+ negotiating the strongest possible connection between two peers:
+ there are a number of ways a man in the middle attacker can attempt
+ to make two entities drop down to the least secure method they
+ support. The protocol has been designed to minimize this risk, but
+ there are still attacks available: for example, an attacker could
+ block access to the port a secure service runs on, or attempt to get
+ the peers to negotiate an unauthenticated connection. The fundamental
+ rule is that higher levels must be cognizant of what their security
+ requirements are and never transmit information over a channel less
+ secure than what they require. The TLS protocol is secure, in that
+ any cipher suite offers its promised level of security: if you
+ negotiate 3DES with a 1024 bit RSA key exchange with a host whose
+ certificate you have verified, you can expect to be that secure.
+
+
+
+
+Dierks & Allen Standards Track [Page 29]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ However, you should never send data over a link encrypted with 40 bit
+ security unless you feel that data is worth no more than the effort
+ required to break that encryption.
+
+ These goals are achieved by the handshake protocol, which can be
+ summarized as follows: The client sends a client hello message to
+ which the server must respond with a server hello message, or else a
+ fatal error will occur and the connection will fail. The client hello
+ and server hello are used to establish security enhancement
+ capabilities between client and server. The client hello and server
+ hello establish the following attributes: Protocol Version, Session
+ ID, Cipher Suite, and Compression Method. Additionally, two random
+ values are generated and exchanged: ClientHello.random and
+ ServerHello.random.
+
+ The actual key exchange uses up to four messages: the server
+ certificate, the server key exchange, the client certificate, and the
+ client key exchange. New key exchange methods can be created by
+ specifying a format for these messages and defining the use of the
+ messages to allow the client and server to agree upon a shared
+ secret. This secret should be quite long; currently defined key
+ exchange methods exchange secrets which range from 48 to 128 bytes in
+ length.
+
+ Following the hello messages, the server will send its certificate,
+ if it is to be authenticated. Additionally, a server key exchange
+ message may be sent, if it is required (e.g. if their server has no
+ certificate, or if its certificate is for signing only). If the
+ server is authenticated, it may request a certificate from the
+ client, if that is appropriate to the cipher suite selected. Now the
+ server will send the server hello done message, indicating that the
+ hello-message phase of the handshake is complete. The server will
+ then wait for a client response. If the server has sent a certificate
+ request message, the client must send the certificate message. The
+ client key exchange message is now sent, and the content of that
+ message will depend on the public key algorithm selected between the
+ client hello and the server hello. If the client has sent a
+ certificate with signing ability, a digitally-signed certificate
+ verify message is sent to explicitly verify the certificate.
+
+ At this point, a change cipher spec message is sent by the client,
+ and the client copies the pending Cipher Spec into the current Cipher
+ Spec. The client then immediately sends the finished message under
+ the new algorithms, keys, and secrets. In response, the server will
+ send its own change cipher spec message, transfer the pending to the
+ current Cipher Spec, and send its finished message under the new
+
+
+
+
+
+Dierks & Allen Standards Track [Page 30]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Cipher Spec. At this point, the handshake is complete and the client
+ and server may begin to exchange application layer data. (See flow
+ chart below.)
+
+ Client Server
+
+ ClientHello -------->
+ ServerHello
+ Certificate*
+ ServerKeyExchange*
+ CertificateRequest*
+ <-------- ServerHelloDone
+ Certificate*
+ ClientKeyExchange
+ CertificateVerify*
+ [ChangeCipherSpec]
+ Finished -------->
+ [ChangeCipherSpec]
+ <-------- Finished
+ Application Data <-------> Application Data
+
+ Fig. 1 - Message flow for a full handshake
+
+ * Indicates optional or situation-dependent messages that are not
+ always sent.
+
+ Note: To help avoid pipeline stalls, ChangeCipherSpec is an
+ independent TLS Protocol content type, and is not actually a TLS
+ handshake message.
+
+ When the client and server decide to resume a previous session or
+ duplicate an existing session (instead of negotiating new security
+ parameters) the message flow is as follows:
+
+ The client sends a ClientHello using the Session ID of the session to
+ be resumed. The server then checks its session cache for a match. If
+ a match is found, and the server is willing to re-establish the
+ connection under the specified session state, it will send a
+ ServerHello with the same Session ID value. At this point, both
+ client and server must send change cipher spec messages and proceed
+ directly to finished messages. Once the re-establishment is complete,
+ the client and server may begin to exchange application layer data.
+ (See flow chart below.) If a Session ID match is not found, the
+ server generates a new session ID and the TLS client and server
+ perform a full handshake.
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 31]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Client Server
+
+ ClientHello -------->
+ ServerHello
+ [ChangeCipherSpec]
+ <-------- Finished
+ [ChangeCipherSpec]
+ Finished -------->
+ Application Data <-------> Application Data
+
+ Fig. 2 - Message flow for an abbreviated handshake
+
+ The contents and significance of each message will be presented in
+ detail in the following sections.
+
+7.4. Handshake protocol
+
+ The TLS Handshake Protocol is one of the defined higher level clients
+ of the TLS Record Protocol. This protocol is used to negotiate the
+ secure attributes of a session. Handshake messages are supplied to
+ the TLS Record Layer, where they are encapsulated within one or more
+ TLSPlaintext structures, which are processed and transmitted as
+ specified by the current active session state.
+
+ enum {
+ hello_request(0), client_hello(1), server_hello(2),
+ certificate(11), server_key_exchange (12),
+ certificate_request(13), server_hello_done(14),
+ certificate_verify(15), client_key_exchange(16),
+ finished(20), (255)
+ } HandshakeType;
+
+ struct {
+ HandshakeType msg_type; /* handshake type */
+ uint24 length; /* bytes in message */
+ select (HandshakeType) {
+ case hello_request: HelloRequest;
+ case client_hello: ClientHello;
+ case server_hello: ServerHello;
+ case certificate: Certificate;
+ case server_key_exchange: ServerKeyExchange;
+ case certificate_request: CertificateRequest;
+ case server_hello_done: ServerHelloDone;
+ case certificate_verify: CertificateVerify;
+ case client_key_exchange: ClientKeyExchange;
+ case finished: Finished;
+ } body;
+ } Handshake;
+
+
+
+Dierks & Allen Standards Track [Page 32]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ The handshake protocol messages are presented below in the order they
+ must be sent; sending handshake messages in an unexpected order
+ results in a fatal error. Unneeded handshake messages can be omitted,
+ however. Note one exception to the ordering: the Certificate message
+ is used twice in the handshake (from server to client, then from
+ client to server), but described only in its first position. The one
+ message which is not bound by these ordering rules in the Hello
+ Request message, which can be sent at any time, but which should be
+ ignored by the client if it arrives in the middle of a handshake.
+
+7.4.1. Hello messages
+
+ The hello phase messages are used to exchange security enhancement
+ capabilities between the client and server. When a new session
+ begins, the Record Layer's connection state encryption, hash, and
+ compression algorithms are initialized to null. The current
+ connection state is used for renegotiation messages.
+
+7.4.1.1. Hello request
+
+ When this message will be sent:
+ The hello request message may be sent by the server at any time.
+
+ Meaning of this message:
+ Hello request is a simple notification that the client should
+ begin the negotiation process anew by sending a client hello
+ message when convenient. This message will be ignored by the
+ client if the client is currently negotiating a session. This
+ message may be ignored by the client if it does not wish to
+ renegotiate a session, or the client may, if it wishes, respond
+ with a no_renegotiation alert. Since handshake messages are
+ intended to have transmission precedence over application data,
+ it is expected that the negotiation will begin before no more
+ than a few records are received from the client. If the server
+ sends a hello request but does not receive a client hello in
+ response, it may close the connection with a fatal alert.
+
+ After sending a hello request, servers should not repeat the request
+ until the subsequent handshake negotiation is complete.
+
+ Structure of this message:
+ struct { } HelloRequest;
+
+ Note: This message should never be included in the message hashes which
+ are maintained throughout the handshake and used in the finished
+ messages and the certificate verify message.
+
+
+
+
+
+Dierks & Allen Standards Track [Page 33]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+7.4.1.2. Client hello
+
+ When this message will be sent:
+ When a client first connects to a server it is required to send
+ the client hello as its first message. The client can also send a
+ client hello in response to a hello request or on its own
+ initiative in order to renegotiate the security parameters in an
+ existing connection.
+
+ Structure of this message:
+ The client hello message includes a random structure, which is
+ used later in the protocol.
+
+ struct {
+ uint32 gmt_unix_time;
+ opaque random_bytes[28];
+ } Random;
+
+ gmt_unix_time
+ The current time and date in standard UNIX 32-bit format (seconds
+ since the midnight starting Jan 1, 1970, GMT) according to the
+ sender's internal clock. Clocks are not required to be set
+ correctly by the basic TLS Protocol; higher level or application
+ protocols may define additional requirements.
+
+ random_bytes
+ 28 bytes generated by a secure random number generator.
+
+ The client hello message includes a variable length session
+ identifier. If not empty, the value identifies a session between the
+ same client and server whose security parameters the client wishes to
+ reuse. The session identifier may be from an earlier connection, this
+ connection, or another currently active connection. The second option
+ is useful if the client only wishes to update the random structures
+ and derived values of a connection, while the third option makes it
+ possible to establish several independent secure connections without
+ repeating the full handshake protocol. These independent connections
+ may occur sequentially or simultaneously; a SessionID becomes valid
+ when the handshake negotiating it completes with the exchange of
+ Finished messages and persists until removed due to aging or because
+ a fatal error was encountered on a connection associated with the
+ session. The actual contents of the SessionID are defined by the
+ server.
+
+ opaque SessionID<0..32>;
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 34]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Warning:
+ Because the SessionID is transmitted without encryption or
+ immediate MAC protection, servers must not place confidential
+ information in session identifiers or let the contents of fake
+ session identifiers cause any breach of security. (Note that the
+ content of the handshake as a whole, including the SessionID, is
+ protected by the Finished messages exchanged at the end of the
+ handshake.)
+
+ The CipherSuite list, passed from the client to the server in the
+ client hello message, contains the combinations of cryptographic
+ algorithms supported by the client in order of the client's
+ preference (favorite choice first). Each CipherSuite defines a key
+ exchange algorithm, a bulk encryption algorithm (including secret key
+ length) and a MAC algorithm. The server will select a cipher suite
+ or, if no acceptable choices are presented, return a handshake
+ failure alert and close the connection.
+
+ uint8 CipherSuite[2]; /* Cryptographic suite selector */
+
+ The client hello includes a list of compression algorithms supported
+ by the client, ordered according to the client's preference.
+
+ enum { null(0), (255) } CompressionMethod;
+
+ struct {
+ ProtocolVersion client_version;
+ Random random;
+ SessionID session_id;
+ CipherSuite cipher_suites<2..2^16-1>;
+ CompressionMethod compression_methods<1..2^8-1>;
+ } ClientHello;
+
+ client_version
+ The version of the TLS protocol by which the client wishes to
+ communicate during this session. This should be the latest
+ (highest valued) version supported by the client. For this
+ version of the specification, the version will be 3.1 (See
+ Appendix E for details about backward compatibility).
+
+ random
+ A client-generated random structure.
+
+ session_id
+ The ID of a session the client wishes to use for this connection.
+ This field should be empty if no session_id is available or the
+ client wishes to generate new security parameters.
+
+
+
+
+Dierks & Allen Standards Track [Page 35]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ cipher_suites
+ This is a list of the cryptographic options supported by the
+ client, with the client's first preference first. If the
+ session_id field is not empty (implying a session resumption
+ request) this vector must include at least the cipher_suite from
+ that session. Values are defined in Appendix A.5.
+
+ compression_methods
+ This is a list of the compression methods supported by the
+ client, sorted by client preference. If the session_id field is
+ not empty (implying a session resumption request) it must include
+ the compression_method from that session. This vector must
+ contain, and all implementations must support,
+ CompressionMethod.null. Thus, a client and server will always be
+ able to agree on a compression method.
+
+ After sending the client hello message, the client waits for a server
+ hello message. Any other handshake message returned by the server
+ except for a hello request is treated as a fatal error.
+
+ Forward compatibility note:
+ In the interests of forward compatibility, it is permitted for a
+ client hello message to include extra data after the compression
+ methods. This data must be included in the handshake hashes, but
+ must otherwise be ignored. This is the only handshake message for
+ which this is legal; for all other messages, the amount of data
+ in the message must match the description of the message
+ precisely.
+
+7.4.1.3. Server hello
+
+ When this message will be sent:
+ The server will send this message in response to a client hello
+ message when it was able to find an acceptable set of algorithms.
+ If it cannot find such a match, it will respond with a handshake
+ failure alert.
+
+ Structure of this message:
+ struct {
+ ProtocolVersion server_version;
+ Random random;
+ SessionID session_id;
+ CipherSuite cipher_suite;
+ CompressionMethod compression_method;
+ } ServerHello;
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 36]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ server_version
+ This field will contain the lower of that suggested by the client
+ in the client hello and the highest supported by the server. For
+ this version of the specification, the version is 3.1 (See
+ Appendix E for details about backward compatibility).
+
+ random
+ This structure is generated by the server and must be different
+ from (and independent of) ClientHello.random.
+
+ session_id
+ This is the identity of the session corresponding to this
+ connection. If the ClientHello.session_id was non-empty, the
+ server will look in its session cache for a match. If a match is
+ found and the server is willing to establish the new connection
+ using the specified session state, the server will respond with
+ the same value as was supplied by the client. This indicates a
+ resumed session and dictates that the parties must proceed
+ directly to the finished messages. Otherwise this field will
+ contain a different value identifying the new session. The server
+ may return an empty session_id to indicate that the session will
+ not be cached and therefore cannot be resumed. If a session is
+ resumed, it must be resumed using the same cipher suite it was
+ originally negotiated with.
+
+ cipher_suite
+ The single cipher suite selected by the server from the list in
+ ClientHello.cipher_suites. For resumed sessions this field is the
+ value from the state of the session being resumed.
+
+ compression_method
+ The single compression algorithm selected by the server from the
+ list in ClientHello.compression_methods. For resumed sessions
+ this field is the value from the resumed session state.
+
+7.4.2. Server certificate
+
+ When this message will be sent:
+ The server must send a certificate whenever the agreed-upon key
+ exchange method is not an anonymous one. This message will always
+ immediately follow the server hello message.
+
+ Meaning of this message:
+ The certificate type must be appropriate for the selected cipher
+ suite's key exchange algorithm, and is generally an X.509v3
+ certificate. It must contain a key which matches the key exchange
+ method, as follows. Unless otherwise specified, the signing
+
+
+
+
+Dierks & Allen Standards Track [Page 37]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ algorithm for the certificate must be the same as the algorithm
+ for the certificate key. Unless otherwise specified, the public
+ key may be of any length.
+
+ Key Exchange Algorithm Certificate Key Type
+
+ RSA RSA public key; the certificate must
+ allow the key to be used for encryption.
+
+ RSA_EXPORT RSA public key of length greater than
+ 512 bits which can be used for signing,
+ or a key of 512 bits or shorter which
+ can be used for either encryption or
+ signing.
+
+ DHE_DSS DSS public key.
+
+ DHE_DSS_EXPORT DSS public key.
+
+ DHE_RSA RSA public key which can be used for
+ signing.
+
+ DHE_RSA_EXPORT RSA public key which can be used for
+ signing.
+
+ DH_DSS Diffie-Hellman key. The algorithm used
+ to sign the certificate should be DSS.
+
+ DH_RSA Diffie-Hellman key. The algorithm used
+ to sign the certificate should be RSA.
+
+ All certificate profiles, key and cryptographic formats are defined
+ by the IETF PKIX working group [PKIX]. When a key usage extension is
+ present, the digitalSignature bit must be set for the key to be
+ eligible for signing, as described above, and the keyEncipherment bit
+ must be present to allow encryption, as described above. The
+ keyAgreement bit must be set on Diffie-Hellman certificates.
+
+ As CipherSuites which specify new key exchange methods are specified
+ for the TLS Protocol, they will imply certificate format and the
+ required encoded keying information.
+
+ Structure of this message:
+ opaque ASN.1Cert<1..2^24-1>;
+
+ struct {
+ ASN.1Cert certificate_list<0..2^24-1>;
+ } Certificate;
+
+
+
+Dierks & Allen Standards Track [Page 38]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ certificate_list
+ This is a sequence (chain) of X.509v3 certificates. The sender's
+ certificate must come first in the list. Each following
+ certificate must directly certify the one preceding it. Because
+ certificate validation requires that root keys be distributed
+ independently, the self-signed certificate which specifies the
+ root certificate authority may optionally be omitted from the
+ chain, under the assumption that the remote end must already
+ possess it in order to validate it in any case.
+
+ The same message type and structure will be used for the client's
+ response to a certificate request message. Note that a client may
+ send no certificates if it does not have an appropriate certificate
+ to send in response to the server's authentication request.
+
+ Note: PKCS #7 [PKCS7] is not used as the format for the certificate
+ vector because PKCS #6 [PKCS6] extended certificates are not
+ used. Also PKCS #7 defines a SET rather than a SEQUENCE, making
+ the task of parsing the list more difficult.
+
+7.4.3. Server key exchange message
+
+ When this message will be sent:
+ This message will be sent immediately after the server
+ certificate message (or the server hello message, if this is an
+ anonymous negotiation).
+
+ The server key exchange message is sent by the server only when
+ the server certificate message (if sent) does not contain enough
+ data to allow the client to exchange a premaster secret. This is
+ true for the following key exchange methods:
+
+ RSA_EXPORT (if the public key in the server certificate is
+ longer than 512 bits)
+ DHE_DSS
+ DHE_DSS_EXPORT
+ DHE_RSA
+ DHE_RSA_EXPORT
+ DH_anon
+
+ It is not legal to send the server key exchange message for the
+ following key exchange methods:
+
+ RSA
+ RSA_EXPORT (when the public key in the server certificate is
+ less than or equal to 512 bits in length)
+ DH_DSS
+ DH_RSA
+
+
+
+Dierks & Allen Standards Track [Page 39]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Meaning of this message:
+ This message conveys cryptographic information to allow the
+ client to communicate the premaster secret: either an RSA public
+ key to encrypt the premaster secret with, or a Diffie-Hellman
+ public key with which the client can complete a key exchange
+ (with the result being the premaster secret.)
+
+ As additional CipherSuites are defined for TLS which include new key
+ exchange algorithms, the server key exchange message will be sent if
+ and only if the certificate type associated with the key exchange
+ algorithm does not provide enough information for the client to
+ exchange a premaster secret.
+
+ Note: According to current US export law, RSA moduli larger than 512
+ bits may not be used for key exchange in software exported from
+ the US. With this message, the larger RSA keys encoded in
+ certificates may be used to sign temporary shorter RSA keys for
+ the RSA_EXPORT key exchange method.
+
+ Structure of this message:
+ enum { rsa, diffie_hellman } KeyExchangeAlgorithm;
+
+ struct {
+ opaque rsa_modulus<1..2^16-1>;
+ opaque rsa_exponent<1..2^16-1>;
+ } ServerRSAParams;
+
+ rsa_modulus
+ The modulus of the server's temporary RSA key.
+
+ rsa_exponent
+ The public exponent of the server's temporary RSA key.
+
+ struct {
+ opaque dh_p<1..2^16-1>;
+ opaque dh_g<1..2^16-1>;
+ opaque dh_Ys<1..2^16-1>;
+ } ServerDHParams; /* Ephemeral DH parameters */
+
+ dh_p
+ The prime modulus used for the Diffie-Hellman operation.
+
+ dh_g
+ The generator used for the Diffie-Hellman operation.
+
+ dh_Ys
+ The server's Diffie-Hellman public value (g^X mod p).
+
+
+
+
+Dierks & Allen Standards Track [Page 40]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ struct {
+ select (KeyExchangeAlgorithm) {
+ case diffie_hellman:
+ ServerDHParams params;
+ Signature signed_params;
+ case rsa:
+ ServerRSAParams params;
+ Signature signed_params;
+ };
+ } ServerKeyExchange;
+
+ params
+ The server's key exchange parameters.
+
+ signed_params
+ For non-anonymous key exchanges, a hash of the corresponding
+ params value, with the signature appropriate to that hash
+ applied.
+
+ md5_hash
+ MD5(ClientHello.random + ServerHello.random + ServerParams);
+
+ sha_hash
+ SHA(ClientHello.random + ServerHello.random + ServerParams);
+
+ enum { anonymous, rsa, dsa } SignatureAlgorithm;
+
+ select (SignatureAlgorithm)
+ { case anonymous: struct { };
+ case rsa:
+ digitally-signed struct {
+ opaque md5_hash[16];
+ opaque sha_hash[20];
+ };
+ case dsa:
+ digitally-signed struct {
+ opaque sha_hash[20];
+ };
+ } Signature;
+
+7.4.4. Certificate request
+
+ When this message will be sent:
+ A non-anonymous server can optionally request a certificate from
+ the client, if appropriate for the selected cipher suite. This
+ message, if sent, will immediately follow the Server Key Exchange
+ message (if it is sent; otherwise, the Server Certificate
+ message).
+
+
+
+Dierks & Allen Standards Track [Page 41]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Structure of this message:
+ enum {
+ rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
+ (255)
+ } ClientCertificateType;
+
+ opaque DistinguishedName<1..2^16-1>;
+
+ struct {
+ ClientCertificateType certificate_types<1..2^8-1>;
+ DistinguishedName certificate_authorities<3..2^16-1>;
+ } CertificateRequest;
+
+ certificate_types
+ This field is a list of the types of certificates requested,
+ sorted in order of the server's preference.
+
+ certificate_authorities
+ A list of the distinguished names of acceptable certificate
+ authorities. These distinguished names may specify a desired
+ distinguished name for a root CA or for a subordinate CA;
+ thus, this message can be used both to describe known roots
+ and a desired authorization space.
+
+ Note: DistinguishedName is derived from [X509].
+
+ Note: It is a fatal handshake_failure alert for an anonymous server to
+ request client identification.
+
+7.4.5. Server hello done
+
+ When this message will be sent:
+ The server hello done message is sent by the server to indicate
+ the end of the server hello and associated messages. After
+ sending this message the server will wait for a client response.
+
+ Meaning of this message:
+ This message means that the server is done sending messages to
+ support the key exchange, and the client can proceed with its
+ phase of the key exchange.
+
+ Upon receipt of the server hello done message the client should
+ verify that the server provided a valid certificate if required
+ and check that the server hello parameters are acceptable.
+
+ Structure of this message:
+ struct { } ServerHelloDone;
+
+
+
+
+Dierks & Allen Standards Track [Page 42]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+7.4.6. Client certificate
+
+ When this message will be sent:
+ This is the first message the client can send after receiving a
+ server hello done message. This message is only sent if the
+ server requests a certificate. If no suitable certificate is
+ available, the client should send a certificate message
+ containing no certificates. If client authentication is required
+ by the server for the handshake to continue, it may respond with
+ a fatal handshake failure alert. Client certificates are sent
+ using the Certificate structure defined in Section 7.4.2.
+
+ Note: When using a static Diffie-Hellman based key exchange method
+ (DH_DSS or DH_RSA), if client authentication is requested, the
+ Diffie-Hellman group and generator encoded in the client's
+ certificate must match the server specified Diffie-Hellman
+ parameters if the client's parameters are to be used for the key
+ exchange.
+
+7.4.7. Client key exchange message
+
+ When this message will be sent:
+ This message is always sent by the client. It will immediately
+ follow the client certificate message, if it is sent. Otherwise
+ it will be the first message sent by the client after it receives
+ the server hello done message.
+
+ Meaning of this message:
+ With this message, the premaster secret is set, either though
+ direct transmission of the RSA-encrypted secret, or by the
+ transmission of Diffie-Hellman parameters which will allow each
+ side to agree upon the same premaster secret. When the key
+ exchange method is DH_RSA or DH_DSS, client certification has
+ been requested, and the client was able to respond with a
+ certificate which contained a Diffie-Hellman public key whose
+ parameters (group and generator) matched those specified by the
+ server in its certificate, this message will not contain any
+ data.
+
+ Structure of this message:
+ The choice of messages depends on which key exchange method has
+ been selected. See Section 7.4.3 for the KeyExchangeAlgorithm
+ definition.
+
+ struct {
+ select (KeyExchangeAlgorithm) {
+ case rsa: EncryptedPreMasterSecret;
+ case diffie_hellman: ClientDiffieHellmanPublic;
+
+
+
+Dierks & Allen Standards Track [Page 43]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ } exchange_keys;
+ } ClientKeyExchange;
+
+7.4.7.1. RSA encrypted premaster secret message
+
+ Meaning of this message:
+ If RSA is being used for key agreement and authentication, the
+ client generates a 48-byte premaster secret, encrypts it using
+ the public key from the server's certificate or the temporary RSA
+ key provided in a server key exchange message, and sends the
+ result in an encrypted premaster secret message. This structure
+ is a variant of the client key exchange message, not a message in
+ itself.
+
+ Structure of this message:
+ struct {
+ ProtocolVersion client_version;
+ opaque random[46];
+ } PreMasterSecret;
+
+ client_version
+ The latest (newest) version supported by the client. This is
+ used to detect version roll-back attacks. Upon receiving the
+ premaster secret, the server should check that this value
+ matches the value transmitted by the client in the client
+ hello message.
+
+ random
+ 46 securely-generated random bytes.
+
+ struct {
+ public-key-encrypted PreMasterSecret pre_master_secret;
+ } EncryptedPreMasterSecret;
+
+ Note: An attack discovered by Daniel Bleichenbacher [BLEI] can be used
+ to attack a TLS server which is using PKCS#1 encoded RSA. The
+ attack takes advantage of the fact that by failing in different
+ ways, a TLS server can be coerced into revealing whether a
+ particular message, when decrypted, is properly PKCS#1 formatted
+ or not.
+
+ The best way to avoid vulnerability to this attack is to treat
+ incorrectly formatted messages in a manner indistinguishable from
+ correctly formatted RSA blocks. Thus, when it receives an
+ incorrectly formatted RSA block, a server should generate a
+ random 48-byte value and proceed using it as the premaster
+ secret. Thus, the server will act identically whether the
+ received RSA block is correctly encoded or not.
+
+
+
+Dierks & Allen Standards Track [Page 44]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ pre_master_secret
+ This random value is generated by the client and is used to
+ generate the master secret, as specified in Section 8.1.
+
+7.4.7.2. Client Diffie-Hellman public value
+
+ Meaning of this message:
+ This structure conveys the client's Diffie-Hellman public value
+ (Yc) if it was not already included in the client's certificate.
+ The encoding used for Yc is determined by the enumerated
+ PublicValueEncoding. This structure is a variant of the client
+ key exchange message, not a message in itself.
+
+ Structure of this message:
+ enum { implicit, explicit } PublicValueEncoding;
+
+ implicit
+ If the client certificate already contains a suitable
+ Diffie-Hellman key, then Yc is implicit and does not need to
+ be sent again. In this case, the Client Key Exchange message
+ will be sent, but will be empty.
+
+ explicit
+ Yc needs to be sent.
+
+ struct {
+ select (PublicValueEncoding) {
+ case implicit: struct { };
+ case explicit: opaque dh_Yc<1..2^16-1>;
+ } dh_public;
+ } ClientDiffieHellmanPublic;
+
+ dh_Yc
+ The client's Diffie-Hellman public value (Yc).
+
+7.4.8. Certificate verify
+
+ When this message will be sent:
+ This message is used to provide explicit verification of a client
+ certificate. This message is only sent following a client
+ certificate that has signing capability (i.e. all certificates
+ except those containing fixed Diffie-Hellman parameters). When
+ sent, it will immediately follow the client key exchange message.
+
+ Structure of this message:
+ struct {
+ Signature signature;
+ } CertificateVerify;
+
+
+
+Dierks & Allen Standards Track [Page 45]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ The Signature type is defined in 7.4.3.
+
+ CertificateVerify.signature.md5_hash
+ MD5(handshake_messages);
+
+ Certificate.signature.sha_hash
+ SHA(handshake_messages);
+
+ Here handshake_messages refers to all handshake messages sent or
+ received starting at client hello up to but not including this
+ message, including the type and length fields of the handshake
+ messages. This is the concatenation of all the Handshake structures
+ as defined in 7.4 exchanged thus far.
+
+7.4.9. Finished
+
+ When this message will be sent:
+ A finished message is always sent immediately after a change
+ cipher spec message to verify that the key exchange and
+ authentication processes were successful. It is essential that a
+ change cipher spec message be received between the other
+ handshake messages and the Finished message.
+
+ Meaning of this message:
+ The finished message is the first protected with the just-
+ negotiated algorithms, keys, and secrets. Recipients of finished
+ messages must verify that the contents are correct. Once a side
+ has sent its Finished message and received and validated the
+ Finished message from its peer, it may begin to send and receive
+ application data over the connection.
+
+ struct {
+ opaque verify_data[12];
+ } Finished;
+
+ verify_data
+ PRF(master_secret, finished_label, MD5(handshake_messages) +
+ SHA-1(handshake_messages)) [0..11];
+
+ finished_label
+ For Finished messages sent by the client, the string "client
+ finished". For Finished messages sent by the server, the
+ string "server finished".
+
+ handshake_messages
+ All of the data from all handshake messages up to but not
+ including this message. This is only data visible at the
+ handshake layer and does not include record layer headers.
+
+
+
+Dierks & Allen Standards Track [Page 46]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ This is the concatenation of all the Handshake structures as
+ defined in 7.4 exchanged thus far.
+
+ It is a fatal error if a finished message is not preceded by a change
+ cipher spec message at the appropriate point in the handshake.
+
+ The hash contained in finished messages sent by the server
+ incorporate Sender.server; those sent by the client incorporate
+ Sender.client. The value handshake_messages includes all handshake
+ messages starting at client hello up to, but not including, this
+ finished message. This may be different from handshake_messages in
+ Section 7.4.8 because it would include the certificate verify message
+ (if sent). Also, the handshake_messages for the finished message sent
+ by the client will be different from that for the finished message
+ sent by the server, because the one which is sent second will include
+ the prior one.
+
+ Note: Change cipher spec messages, alerts and any other record types
+ are not handshake messages and are not included in the hash
+ computations. Also, Hello Request messages are omitted from
+ handshake hashes.
+
+8. Cryptographic computations
+
+ In order to begin connection protection, the TLS Record Protocol
+ requires specification of a suite of algorithms, a master secret, and
+ the client and server random values. The authentication, encryption,
+ and MAC algorithms are determined by the cipher_suite selected by the
+ server and revealed in the server hello message. The compression
+ algorithm is negotiated in the hello messages, and the random values
+ are exchanged in the hello messages. All that remains is to calculate
+ the master secret.
+
+8.1. Computing the master secret
+
+ For all key exchange methods, the same algorithm is used to convert
+ the pre_master_secret into the master_secret. The pre_master_secret
+ should be deleted from memory once the master_secret has been
+ computed.
+
+ master_secret = PRF(pre_master_secret, "master secret",
+ ClientHello.random + ServerHello.random)
+ [0..47];
+
+ The master secret is always exactly 48 bytes in length. The length of
+ the premaster secret will vary depending on key exchange method.
+
+
+
+
+
+Dierks & Allen Standards Track [Page 47]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+8.1.1. RSA
+
+ When RSA is used for server authentication and key exchange, a 48-
+ byte pre_master_secret is generated by the client, encrypted under
+ the server's public key, and sent to the server. The server uses its
+ private key to decrypt the pre_master_secret. Both parties then
+ convert the pre_master_secret into the master_secret, as specified
+ above.
+
+ RSA digital signatures are performed using PKCS #1 [PKCS1] block type
+ 1. RSA public key encryption is performed using PKCS #1 block type 2.
+
+8.1.2. Diffie-Hellman
+
+ A conventional Diffie-Hellman computation is performed. The
+ negotiated key (Z) is used as the pre_master_secret, and is converted
+ into the master_secret, as specified above.
+
+ Note: Diffie-Hellman parameters are specified by the server, and may
+ be either ephemeral or contained within the server's certificate.
+
+9. Mandatory Cipher Suites
+
+ In the absence of an application profile standard specifying
+ otherwise, a TLS compliant application MUST implement the cipher
+ suite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA.
+
+10. Application data protocol
+
+ Application data messages are carried by the Record Layer and are
+ fragmented, compressed and encrypted based on the current connection
+ state. The messages are treated as transparent data to the record
+ layer.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 48]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+A. Protocol constant values
+
+ This section describes protocol types and constants.
+
+A.1. Record layer
+
+ struct {
+ uint8 major, minor;
+ } ProtocolVersion;
+
+ ProtocolVersion version = { 3, 1 }; /* TLS v1.0 */
+
+ enum {
+ change_cipher_spec(20), alert(21), handshake(22),
+ application_data(23), (255)
+ } ContentType;
+
+ struct {
+ ContentType type;
+ ProtocolVersion version;
+ uint16 length;
+ opaque fragment[TLSPlaintext.length];
+ } TLSPlaintext;
+
+ struct {
+ ContentType type;
+ ProtocolVersion version;
+ uint16 length;
+ opaque fragment[TLSCompressed.length];
+ } TLSCompressed;
+
+ struct {
+ ContentType type;
+ ProtocolVersion version;
+ uint16 length;
+ select (CipherSpec.cipher_type) {
+ case stream: GenericStreamCipher;
+ case block: GenericBlockCipher;
+ } fragment;
+ } TLSCiphertext;
+
+ stream-ciphered struct {
+ opaque content[TLSCompressed.length];
+ opaque MAC[CipherSpec.hash_size];
+ } GenericStreamCipher;
+
+ block-ciphered struct {
+ opaque content[TLSCompressed.length];
+
+
+
+Dierks & Allen Standards Track [Page 49]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ opaque MAC[CipherSpec.hash_size];
+ uint8 padding[GenericBlockCipher.padding_length];
+ uint8 padding_length;
+ } GenericBlockCipher;
+
+A.2. Change cipher specs message
+
+ struct {
+ enum { change_cipher_spec(1), (255) } type;
+ } ChangeCipherSpec;
+
+A.3. Alert messages
+
+ enum { warning(1), fatal(2), (255) } AlertLevel;
+
+ enum {
+ close_notify(0),
+ unexpected_message(10),
+ bad_record_mac(20),
+ decryption_failed(21),
+ record_overflow(22),
+ decompression_failure(30),
+ handshake_failure(40),
+ bad_certificate(42),
+ unsupported_certificate(43),
+ certificate_revoked(44),
+ certificate_expired(45),
+ certificate_unknown(46),
+ illegal_parameter(47),
+ unknown_ca(48),
+ access_denied(49),
+ decode_error(50),
+ decrypt_error(51),
+ export_restriction(60),
+ protocol_version(70),
+ insufficient_security(71),
+ internal_error(80),
+ user_canceled(90),
+ no_renegotiation(100),
+ (255)
+ } AlertDescription;
+
+ struct {
+ AlertLevel level;
+ AlertDescription description;
+ } Alert;
+
+
+
+
+
+Dierks & Allen Standards Track [Page 50]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+A.4. Handshake protocol
+
+ enum {
+ hello_request(0), client_hello(1), server_hello(2),
+ certificate(11), server_key_exchange (12),
+ certificate_request(13), server_hello_done(14),
+ certificate_verify(15), client_key_exchange(16),
+ finished(20), (255)
+ } HandshakeType;
+
+ struct {
+ HandshakeType msg_type;
+ uint24 length;
+ select (HandshakeType) {
+ case hello_request: HelloRequest;
+ case client_hello: ClientHello;
+ case server_hello: ServerHello;
+ case certificate: Certificate;
+ case server_key_exchange: ServerKeyExchange;
+ case certificate_request: CertificateRequest;
+ case server_hello_done: ServerHelloDone;
+ case certificate_verify: CertificateVerify;
+ case client_key_exchange: ClientKeyExchange;
+ case finished: Finished;
+ } body;
+ } Handshake;
+
+A.4.1. Hello messages
+
+ struct { } HelloRequest;
+
+ struct {
+ uint32 gmt_unix_time;
+ opaque random_bytes[28];
+ } Random;
+
+ opaque SessionID<0..32>;
+
+ uint8 CipherSuite[2];
+
+ enum { null(0), (255) } CompressionMethod;
+
+ struct {
+ ProtocolVersion client_version;
+ Random random;
+ SessionID session_id;
+ CipherSuite cipher_suites<2..2^16-1>;
+ CompressionMethod compression_methods<1..2^8-1>;
+
+
+
+Dierks & Allen Standards Track [Page 51]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ } ClientHello;
+
+ struct {
+ ProtocolVersion server_version;
+ Random random;
+ SessionID session_id;
+ CipherSuite cipher_suite;
+ CompressionMethod compression_method;
+ } ServerHello;
+
+A.4.2. Server authentication and key exchange messages
+
+ opaque ASN.1Cert<2^24-1>;
+
+ struct {
+ ASN.1Cert certificate_list<1..2^24-1>;
+ } Certificate;
+
+ enum { rsa, diffie_hellman } KeyExchangeAlgorithm;
+
+ struct {
+ opaque RSA_modulus<1..2^16-1>;
+ opaque RSA_exponent<1..2^16-1>;
+ } ServerRSAParams;
+
+ struct {
+ opaque DH_p<1..2^16-1>;
+ opaque DH_g<1..2^16-1>;
+ opaque DH_Ys<1..2^16-1>;
+ } ServerDHParams;
+
+ struct {
+ select (KeyExchangeAlgorithm) {
+ case diffie_hellman:
+ ServerDHParams params;
+ Signature signed_params;
+ case rsa:
+ ServerRSAParams params;
+ Signature signed_params;
+ };
+ } ServerKeyExchange;
+
+ enum { anonymous, rsa, dsa } SignatureAlgorithm;
+
+ select (SignatureAlgorithm)
+ { case anonymous: struct { };
+ case rsa:
+ digitally-signed struct {
+
+
+
+Dierks & Allen Standards Track [Page 52]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ opaque md5_hash[16];
+ opaque sha_hash[20];
+ };
+ case dsa:
+ digitally-signed struct {
+ opaque sha_hash[20];
+ };
+ } Signature;
+
+ enum {
+ rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
+ (255)
+ } ClientCertificateType;
+
+ opaque DistinguishedName<1..2^16-1>;
+
+ struct {
+ ClientCertificateType certificate_types<1..2^8-1>;
+ DistinguishedName certificate_authorities<3..2^16-1>;
+ } CertificateRequest;
+
+ struct { } ServerHelloDone;
+
+A.4.3. Client authentication and key exchange messages
+
+ struct {
+ select (KeyExchangeAlgorithm) {
+ case rsa: EncryptedPreMasterSecret;
+ case diffie_hellman: DiffieHellmanClientPublicValue;
+ } exchange_keys;
+ } ClientKeyExchange;
+
+ struct {
+ ProtocolVersion client_version;
+ opaque random[46];
+
+ } PreMasterSecret;
+
+ struct {
+ public-key-encrypted PreMasterSecret pre_master_secret;
+ } EncryptedPreMasterSecret;
+
+ enum { implicit, explicit } PublicValueEncoding;
+
+ struct {
+ select (PublicValueEncoding) {
+ case implicit: struct {};
+ case explicit: opaque DH_Yc<1..2^16-1>;
+
+
+
+Dierks & Allen Standards Track [Page 53]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ } dh_public;
+ } ClientDiffieHellmanPublic;
+
+ struct {
+ Signature signature;
+ } CertificateVerify;
+
+A.4.4. Handshake finalization message
+
+ struct {
+ opaque verify_data[12];
+ } Finished;
+
+A.5. The CipherSuite
+
+ The following values define the CipherSuite codes used in the client
+ hello and server hello messages.
+
+ A CipherSuite defines a cipher specification supported in TLS Version
+ 1.0.
+
+ TLS_NULL_WITH_NULL_NULL is specified and is the initial state of a
+ TLS connection during the first handshake on that channel, but must
+ not be negotiated, as it provides no more protection than an
+ unsecured connection.
+
+ CipherSuite TLS_NULL_WITH_NULL_NULL = { 0x00,0x00 };
+
+ The following CipherSuite definitions require that the server provide
+ an RSA certificate that can be used for key exchange. The server may
+ request either an RSA or a DSS signature-capable certificate in the
+ certificate request message.
+
+ CipherSuite TLS_RSA_WITH_NULL_MD5 = { 0x00,0x01 };
+ CipherSuite TLS_RSA_WITH_NULL_SHA = { 0x00,0x02 };
+ CipherSuite TLS_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x03 };
+ CipherSuite TLS_RSA_WITH_RC4_128_MD5 = { 0x00,0x04 };
+ CipherSuite TLS_RSA_WITH_RC4_128_SHA = { 0x00,0x05 };
+ CipherSuite TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00,0x06 };
+ CipherSuite TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00,0x07 };
+ CipherSuite TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x08 };
+ CipherSuite TLS_RSA_WITH_DES_CBC_SHA = { 0x00,0x09 };
+ CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x0A };
+
+ The following CipherSuite definitions are used for server-
+ authenticated (and optionally client-authenticated) Diffie-Hellman.
+ DH denotes cipher suites in which the server's certificate contains
+ the Diffie-Hellman parameters signed by the certificate authority
+
+
+
+Dierks & Allen Standards Track [Page 54]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ (CA). DHE denotes ephemeral Diffie-Hellman, where the Diffie-Hellman
+ parameters are signed by a DSS or RSA certificate, which has been
+ signed by the CA. The signing algorithm used is specified after the
+ DH or DHE parameter. The server can request an RSA or DSS signature-
+ capable certificate from the client for client authentication or it
+ may request a Diffie-Hellman certificate. Any Diffie-Hellman
+ certificate provided by the client must use the parameters (group and
+ generator) described by the server.
+
+ CipherSuite TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0B };
+ CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA = { 0x00,0x0C };
+ CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x0D };
+ CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0E };
+ CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA = { 0x00,0x0F };
+ CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x10 };
+ CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x11 };
+ CipherSuite TLS_DHE_DSS_WITH_DES_CBC_SHA = { 0x00,0x12 };
+ CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x13 };
+ CipherSuite TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x14 };
+ CipherSuite TLS_DHE_RSA_WITH_DES_CBC_SHA = { 0x00,0x15 };
+ CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x16 };
+
+ The following cipher suites are used for completely anonymous
+ Diffie-Hellman communications in which neither party is
+ authenticated. Note that this mode is vulnerable to man-in-the-middle
+ attacks and is therefore deprecated.
+
+ CipherSuite TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x17 };
+ CipherSuite TLS_DH_anon_WITH_RC4_128_MD5 = { 0x00,0x18 };
+ CipherSuite TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x19 };
+ CipherSuite TLS_DH_anon_WITH_DES_CBC_SHA = { 0x00,0x1A };
+ CipherSuite TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00,0x1B };
+
+ Note: All cipher suites whose first byte is 0xFF are considered
+ private and can be used for defining local/experimental
+ algorithms. Interoperability of such types is a local matter.
+
+ Note: Additional cipher suites can be registered by publishing an RFC
+ which specifies the cipher suites, including the necessary TLS
+ protocol information, including message encoding, premaster
+ secret derivation, symmetric encryption and MAC calculation and
+ appropriate reference information for the algorithms involved.
+ The RFC editor's office may, at its discretion, choose to publish
+ specifications for cipher suites which are not completely
+ described (e.g., for classified algorithms) if it finds the
+ specification to be of technical interest and completely
+ specified.
+
+
+
+
+Dierks & Allen Standards Track [Page 55]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Note: The cipher suite values { 0x00, 0x1C } and { 0x00, 0x1D } are
+ reserved to avoid collision with Fortezza-based cipher suites in
+ SSL 3.
+
+A.6. The Security Parameters
+
+ These security parameters are determined by the TLS Handshake
+ Protocol and provided as parameters to the TLS Record Layer in order
+ to initialize a connection state. SecurityParameters includes:
+
+ enum { null(0), (255) } CompressionMethod;
+
+ enum { server, client } ConnectionEnd;
+
+ enum { null, rc4, rc2, des, 3des, des40, idea }
+ BulkCipherAlgorithm;
+
+ enum { stream, block } CipherType;
+
+ enum { true, false } IsExportable;
+
+ enum { null, md5, sha } MACAlgorithm;
+
+ /* The algorithms specified in CompressionMethod,
+ BulkCipherAlgorithm, and MACAlgorithm may be added to. */
+
+ struct {
+ ConnectionEnd entity;
+ BulkCipherAlgorithm bulk_cipher_algorithm;
+ CipherType cipher_type;
+ uint8 key_size;
+ uint8 key_material_length;
+ IsExportable is_exportable;
+ MACAlgorithm mac_algorithm;
+ uint8 hash_size;
+ CompressionMethod compression_algorithm;
+ opaque master_secret[48];
+ opaque client_random[32];
+ opaque server_random[32];
+ } SecurityParameters;
+
+
+
+
+
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 56]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+B. Glossary
+
+ application protocol
+ An application protocol is a protocol that normally layers
+ directly on top of the transport layer (e.g., TCP/IP). Examples
+ include HTTP, TELNET, FTP, and SMTP.
+
+ asymmetric cipher
+ See public key cryptography.
+
+ authentication
+ Authentication is the ability of one entity to determine the
+ identity of another entity.
+
+ block cipher
+ A block cipher is an algorithm that operates on plaintext in
+ groups of bits, called blocks. 64 bits is a common block size.
+
+ bulk cipher
+ A symmetric encryption algorithm used to encrypt large quantities
+ of data.
+
+ cipher block chaining (CBC)
+ CBC is a mode in which every plaintext block encrypted with a
+ block cipher is first exclusive-ORed with the previous ciphertext
+ block (or, in the case of the first block, with the
+ initialization vector). For decryption, every block is first
+ decrypted, then exclusive-ORed with the previous ciphertext block
+ (or IV).
+
+ certificate
+ As part of the X.509 protocol (a.k.a. ISO Authentication
+ framework), certificates are assigned by a trusted Certificate
+ Authority and provide a strong binding between a party's identity
+ or some other attributes and its public key.
+
+ client
+ The application entity that initiates a TLS connection to a
+ server. This may or may not imply that the client initiated the
+ underlying transport connection. The primary operational
+ difference between the server and client is that the server is
+ generally authenticated, while the client is only optionally
+ authenticated.
+
+ client write key
+ The key used to encrypt data written by the client.
+
+
+
+
+
+Dierks & Allen Standards Track [Page 57]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ client write MAC secret
+ The secret data used to authenticate data written by the client.
+
+ connection
+ A connection is a transport (in the OSI layering model
+ definition) that provides a suitable type of service. For TLS,
+ such connections are peer to peer relationships. The connections
+ are transient. Every connection is associated with one session.
+
+ Data Encryption Standard
+ DES is a very widely used symmetric encryption algorithm. DES is
+ a block cipher with a 56 bit key and an 8 byte block size. Note
+ that in TLS, for key generation purposes, DES is treated as
+ having an 8 byte key length (64 bits), but it still only provides
+ 56 bits of protection. (The low bit of each key byte is presumed
+ to be set to produce odd parity in that key byte.) DES can also
+ be operated in a mode where three independent keys and three
+ encryptions are used for each block of data; this uses 168 bits
+ of key (24 bytes in the TLS key generation method) and provides
+ the equivalent of 112 bits of security. [DES], [3DES]
+
+ Digital Signature Standard (DSS)
+ A standard for digital signing, including the Digital Signing
+ Algorithm, approved by the National Institute of Standards and
+ Technology, defined in NIST FIPS PUB 186, "Digital Signature
+ Standard," published May, 1994 by the U.S. Dept. of Commerce.
+ [DSS]
+
+ digital signatures
+ Digital signatures utilize public key cryptography and one-way
+ hash functions to produce a signature of the data that can be
+ authenticated, and is difficult to forge or repudiate.
+
+ handshake
+ An initial negotiation between client and server that establishes
+ the parameters of their transactions.
+
+ Initialization Vector (IV)
+ When a block cipher is used in CBC mode, the initialization
+ vector is exclusive-ORed with the first plaintext block prior to
+ encryption.
+
+ IDEA
+ A 64-bit block cipher designed by Xuejia Lai and James Massey.
+ [IDEA]
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 58]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Message Authentication Code (MAC)
+ A Message Authentication Code is a one-way hash computed from a
+ message and some secret data. It is difficult to forge without
+ knowing the secret data. Its purpose is to detect if the message
+ has been altered.
+
+ master secret
+ Secure secret data used for generating encryption keys, MAC
+ secrets, and IVs.
+
+ MD5
+ MD5 is a secure hashing function that converts an arbitrarily
+ long data stream into a digest of fixed size (16 bytes). [MD5]
+
+ public key cryptography
+ A class of cryptographic techniques employing two-key ciphers.
+ Messages encrypted with the public key can only be decrypted with
+ the associated private key. Conversely, messages signed with the
+ private key can be verified with the public key.
+
+ one-way hash function
+ A one-way transformation that converts an arbitrary amount of
+ data into a fixed-length hash. It is computationally hard to
+ reverse the transformation or to find collisions. MD5 and SHA are
+ examples of one-way hash functions.
+
+ RC2
+ A block cipher developed by Ron Rivest at RSA Data Security, Inc.
+ [RSADSI] described in [RC2].
+
+ RC4
+ A stream cipher licensed by RSA Data Security [RSADSI]. A
+ compatible cipher is described in [RC4].
+
+ RSA
+ A very widely used public-key algorithm that can be used for
+ either encryption or digital signing. [RSA]
+
+ salt
+ Non-secret random data used to make export encryption keys resist
+ precomputation attacks.
+
+ server
+ The server is the application entity that responds to requests
+ for connections from clients. See also under client.
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 59]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ session
+ A TLS session is an association between a client and a server.
+ Sessions are created by the handshake protocol. Sessions define a
+ set of cryptographic security parameters, which can be shared
+ among multiple connections. Sessions are used to avoid the
+ expensive negotiation of new security parameters for each
+ connection.
+
+ session identifier
+ A session identifier is a value generated by a server that
+ identifies a particular session.
+
+ server write key
+ The key used to encrypt data written by the server.
+
+ server write MAC secret
+ The secret data used to authenticate data written by the server.
+
+ SHA
+ The Secure Hash Algorithm is defined in FIPS PUB 180-1. It
+ produces a 20-byte output. Note that all references to SHA
+ actually use the modified SHA-1 algorithm. [SHA]
+
+ SSL
+ Netscape's Secure Socket Layer protocol [SSL3]. TLS is based on
+ SSL Version 3.0
+
+ stream cipher
+ An encryption algorithm that converts a key into a
+ cryptographically-strong keystream, which is then exclusive-ORed
+ with the plaintext.
+
+ symmetric cipher
+ See bulk cipher.
+
+ Transport Layer Security (TLS)
+ This protocol; also, the Transport Layer Security working group
+ of the Internet Engineering Task Force (IETF). See "Comments" at
+ the end of this document.
+
+
+
+
+
+
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 60]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+C. CipherSuite definitions
+
+CipherSuite Is Key Cipher Hash
+ Exportable Exchange
+
+TLS_NULL_WITH_NULL_NULL * NULL NULL NULL
+TLS_RSA_WITH_NULL_MD5 * RSA NULL MD5
+TLS_RSA_WITH_NULL_SHA * RSA NULL SHA
+TLS_RSA_EXPORT_WITH_RC4_40_MD5 * RSA_EXPORT RC4_40 MD5
+TLS_RSA_WITH_RC4_128_MD5 RSA RC4_128 MD5
+TLS_RSA_WITH_RC4_128_SHA RSA RC4_128 SHA
+TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 * RSA_EXPORT RC2_CBC_40 MD5
+TLS_RSA_WITH_IDEA_CBC_SHA RSA IDEA_CBC SHA
+TLS_RSA_EXPORT_WITH_DES40_CBC_SHA * RSA_EXPORT DES40_CBC SHA
+TLS_RSA_WITH_DES_CBC_SHA RSA DES_CBC SHA
+TLS_RSA_WITH_3DES_EDE_CBC_SHA RSA 3DES_EDE_CBC SHA
+TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA * DH_DSS_EXPORT DES40_CBC SHA
+TLS_DH_DSS_WITH_DES_CBC_SHA DH_DSS DES_CBC SHA
+TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA DH_DSS 3DES_EDE_CBC SHA
+TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA * DH_RSA_EXPORT DES40_CBC SHA
+TLS_DH_RSA_WITH_DES_CBC_SHA DH_RSA DES_CBC SHA
+TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA DH_RSA 3DES_EDE_CBC SHA
+TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA * DHE_DSS_EXPORT DES40_CBC SHA
+TLS_DHE_DSS_WITH_DES_CBC_SHA DHE_DSS DES_CBC SHA
+TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA DHE_DSS 3DES_EDE_CBC SHA
+TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA * DHE_RSA_EXPORT DES40_CBC SHA
+TLS_DHE_RSA_WITH_DES_CBC_SHA DHE_RSA DES_CBC SHA
+TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA DHE_RSA 3DES_EDE_CBC SHA
+TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 * DH_anon_EXPORT RC4_40 MD5
+TLS_DH_anon_WITH_RC4_128_MD5 DH_anon RC4_128 MD5
+TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA DH_anon DES40_CBC SHA
+TLS_DH_anon_WITH_DES_CBC_SHA DH_anon DES_CBC SHA
+TLS_DH_anon_WITH_3DES_EDE_CBC_SHA DH_anon 3DES_EDE_CBC SHA
+
+
+ * Indicates IsExportable is True
+
+ Key
+ Exchange
+ Algorithm Description Key size limit
+
+ DHE_DSS Ephemeral DH with DSS signatures None
+ DHE_DSS_EXPORT Ephemeral DH with DSS signatures DH = 512 bits
+ DHE_RSA Ephemeral DH with RSA signatures None
+ DHE_RSA_EXPORT Ephemeral DH with RSA signatures DH = 512 bits,
+ RSA = none
+ DH_anon Anonymous DH, no signatures None
+ DH_anon_EXPORT Anonymous DH, no signatures DH = 512 bits
+
+
+
+Dierks & Allen Standards Track [Page 61]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ DH_DSS DH with DSS-based certificates None
+ DH_DSS_EXPORT DH with DSS-based certificates DH = 512 bits
+ DH_RSA DH with RSA-based certificates None
+ DH_RSA_EXPORT DH with RSA-based certificates DH = 512 bits,
+ RSA = none
+ NULL No key exchange N/A
+ RSA RSA key exchange None
+ RSA_EXPORT RSA key exchange RSA = 512 bits
+
+ Key size limit
+ The key size limit gives the size of the largest public key that
+ can be legally used for encryption in cipher suites that are
+ exportable.
+
+ Key Expanded Effective IV Block
+ Cipher Type Material Key Material Key Bits Size Size
+
+ NULL * Stream 0 0 0 0 N/A
+ IDEA_CBC Block 16 16 128 8 8
+ RC2_CBC_40 * Block 5 16 40 8 8
+ RC4_40 * Stream 5 16 40 0 N/A
+ RC4_128 Stream 16 16 128 0 N/A
+ DES40_CBC * Block 5 8 40 8 8
+ DES_CBC Block 8 8 56 8 8
+ 3DES_EDE_CBC Block 24 24 168 8 8
+
+ * Indicates IsExportable is true.
+
+ Type
+ Indicates whether this is a stream cipher or a block cipher
+ running in CBC mode.
+
+ Key Material
+ The number of bytes from the key_block that are used for
+ generating the write keys.
+
+ Expanded Key Material
+ The number of bytes actually fed into the encryption algorithm
+
+ Effective Key Bits
+ How much entropy material is in the key material being fed into
+ the encryption routines.
+
+ IV Size
+ How much data needs to be generated for the initialization
+ vector. Zero for stream ciphers; equal to the block size for
+ block ciphers.
+
+
+
+
+Dierks & Allen Standards Track [Page 62]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Block Size
+ The amount of data a block cipher enciphers in one chunk; a
+ block cipher running in CBC mode can only encrypt an even
+ multiple of its block size.
+
+ Hash Hash Padding
+ function Size Size
+ NULL 0 0
+ MD5 16 48
+ SHA 20 40
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 63]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+D. Implementation Notes
+
+ The TLS protocol cannot prevent many common security mistakes. This
+ section provides several recommendations to assist implementors.
+
+D.1. Temporary RSA keys
+
+ US Export restrictions limit RSA keys used for encryption to 512
+ bits, but do not place any limit on lengths of RSA keys used for
+ signing operations. Certificates often need to be larger than 512
+ bits, since 512-bit RSA keys are not secure enough for high-value
+ transactions or for applications requiring long-term security. Some
+ certificates are also designated signing-only, in which case they
+ cannot be used for key exchange.
+
+ When the public key in the certificate cannot be used for encryption,
+ the server signs a temporary RSA key, which is then exchanged. In
+ exportable applications, the temporary RSA key should be the maximum
+ allowable length (i.e., 512 bits). Because 512-bit RSA keys are
+ relatively insecure, they should be changed often. For typical
+ electronic commerce applications, it is suggested that keys be
+ changed daily or every 500 transactions, and more often if possible.
+ Note that while it is acceptable to use the same temporary key for
+ multiple transactions, it must be signed each time it is used.
+
+ RSA key generation is a time-consuming process. In many cases, a
+ low-priority process can be assigned the task of key generation.
+
+ Whenever a new key is completed, the existing temporary key can be
+ replaced with the new one.
+
+D.2. Random Number Generation and Seeding
+
+ TLS requires a cryptographically-secure pseudorandom number generator
+ (PRNG). Care must be taken in designing and seeding PRNGs. PRNGs
+ based on secure hash operations, most notably MD5 and/or SHA, are
+ acceptable, but cannot provide more security than the size of the
+ random number generator state. (For example, MD5-based PRNGs usually
+ provide 128 bits of state.)
+
+ To estimate the amount of seed material being produced, add the
+ number of bits of unpredictable information in each seed byte. For
+ example, keystroke timing values taken from a PC compatible's 18.2 Hz
+ timer provide 1 or 2 secure bits each, even though the total size of
+ the counter value is 16 bits or more. To seed a 128-bit PRNG, one
+ would thus require approximately 100 such timer values.
+
+
+
+
+
+Dierks & Allen Standards Track [Page 64]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Warning: The seeding functions in RSAREF and versions of BSAFE prior to
+ 3.0 are order-independent. For example, if 1000 seed bits are
+ supplied, one at a time, in 1000 separate calls to the seed
+ function, the PRNG will end up in a state which depends only
+ on the number of 0 or 1 seed bits in the seed data (i.e.,
+ there are 1001 possible final states). Applications using
+ BSAFE or RSAREF must take extra care to ensure proper seeding.
+ This may be accomplished by accumulating seed bits into a
+ buffer and processing them all at once or by processing an
+ incrementing counter with every seed bit; either method will
+ reintroduce order dependence into the seeding process.
+
+D.3. Certificates and authentication
+
+ Implementations are responsible for verifying the integrity of
+ certificates and should generally support certificate revocation
+ messages. Certificates should always be verified to ensure proper
+ signing by a trusted Certificate Authority (CA). The selection and
+ addition of trusted CAs should be done very carefully. Users should
+ be able to view information about the certificate and root CA.
+
+D.4. CipherSuites
+
+ TLS supports a range of key sizes and security levels, including some
+ which provide no or minimal security. A proper implementation will
+ probably not support many cipher suites. For example, 40-bit
+ encryption is easily broken, so implementations requiring strong
+ security should not allow 40-bit keys. Similarly, anonymous Diffie-
+ Hellman is strongly discouraged because it cannot prevent man-in-
+ the-middle attacks. Applications should also enforce minimum and
+ maximum key sizes. For example, certificate chains containing 512-bit
+ RSA keys or signatures are not appropriate for high-security
+ applications.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 65]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+E. Backward Compatibility With SSL
+
+ For historical reasons and in order to avoid a profligate consumption
+ of reserved port numbers, application protocols which are secured by
+ TLS 1.0, SSL 3.0, and SSL 2.0 all frequently share the same
+ connection port: for example, the https protocol (HTTP secured by SSL
+ or TLS) uses port 443 regardless of which security protocol it is
+ using. Thus, some mechanism must be determined to distinguish and
+ negotiate among the various protocols.
+
+ TLS version 1.0 and SSL 3.0 are very similar; thus, supporting both
+ is easy. TLS clients who wish to negotiate with SSL 3.0 servers
+ should send client hello messages using the SSL 3.0 record format and
+ client hello structure, sending {3, 1} for the version field to note
+ that they support TLS 1.0. If the server supports only SSL 3.0, it
+ will respond with an SSL 3.0 server hello; if it supports TLS, with a
+ TLS server hello. The negotiation then proceeds as appropriate for
+ the negotiated protocol.
+
+ Similarly, a TLS server which wishes to interoperate with SSL 3.0
+ clients should accept SSL 3.0 client hello messages and respond with
+ an SSL 3.0 server hello if an SSL 3.0 client hello is received which
+ has a version field of {3, 0}, denoting that this client does not
+ support TLS.
+
+ Whenever a client already knows the highest protocol known to a
+ server (for example, when resuming a session), it should initiate the
+ connection in that native protocol.
+
+ TLS 1.0 clients that support SSL Version 2.0 servers must send SSL
+ Version 2.0 client hello messages [SSL2]. TLS servers should accept
+ either client hello format if they wish to support SSL 2.0 clients on
+ the same connection port. The only deviations from the Version 2.0
+ specification are the ability to specify a version with a value of
+ three and the support for more ciphering types in the CipherSpec.
+
+ Warning: The ability to send Version 2.0 client hello messages will be
+ phased out with all due haste. Implementors should make every
+ effort to move forward as quickly as possible. Version 3.0
+ provides better mechanisms for moving to newer versions.
+
+ The following cipher specifications are carryovers from SSL Version
+ 2.0. These are assumed to use RSA for key exchange and
+ authentication.
+
+ V2CipherSpec TLS_RC4_128_WITH_MD5 = { 0x01,0x00,0x80 };
+ V2CipherSpec TLS_RC4_128_EXPORT40_WITH_MD5 = { 0x02,0x00,0x80 };
+ V2CipherSpec TLS_RC2_CBC_128_CBC_WITH_MD5 = { 0x03,0x00,0x80 };
+
+
+
+Dierks & Allen Standards Track [Page 66]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ V2CipherSpec TLS_RC2_CBC_128_CBC_EXPORT40_WITH_MD5
+ = { 0x04,0x00,0x80 };
+ V2CipherSpec TLS_IDEA_128_CBC_WITH_MD5 = { 0x05,0x00,0x80 };
+ V2CipherSpec TLS_DES_64_CBC_WITH_MD5 = { 0x06,0x00,0x40 };
+ V2CipherSpec TLS_DES_192_EDE3_CBC_WITH_MD5 = { 0x07,0x00,0xC0 };
+
+ Cipher specifications native to TLS can be included in Version 2.0
+ client hello messages using the syntax below. Any V2CipherSpec
+ element with its first byte equal to zero will be ignored by Version
+ 2.0 servers. Clients sending any of the above V2CipherSpecs should
+ also include the TLS equivalent (see Appendix A.5):
+
+ V2CipherSpec (see TLS name) = { 0x00, CipherSuite };
+
+E.1. Version 2 client hello
+
+ The Version 2.0 client hello message is presented below using this
+ document's presentation model. The true definition is still assumed
+ to be the SSL Version 2.0 specification.
+
+ uint8 V2CipherSpec[3];
+
+ struct {
+ uint8 msg_type;
+ Version version;
+ uint16 cipher_spec_length;
+ uint16 session_id_length;
+ uint16 challenge_length;
+ V2CipherSpec cipher_specs[V2ClientHello.cipher_spec_length];
+ opaque session_id[V2ClientHello.session_id_length];
+ Random challenge;
+ } V2ClientHello;
+
+ msg_type
+ This field, in conjunction with the version field, identifies a
+ version 2 client hello message. The value should be one (1).
+
+ version
+ The highest version of the protocol supported by the client
+ (equals ProtocolVersion.version, see Appendix A.1).
+
+ cipher_spec_length
+ This field is the total length of the field cipher_specs. It
+ cannot be zero and must be a multiple of the V2CipherSpec length
+ (3).
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 67]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ session_id_length
+ This field must have a value of either zero or 16. If zero, the
+ client is creating a new session. If 16, the session_id field
+ will contain the 16 bytes of session identification.
+
+ challenge_length
+ The length in bytes of the client's challenge to the server to
+ authenticate itself. This value must be 32.
+
+ cipher_specs
+ This is a list of all CipherSpecs the client is willing and able
+ to use. There must be at least one CipherSpec acceptable to the
+ server.
+
+ session_id
+ If this field's length is not zero, it will contain the
+ identification for a session that the client wishes to resume.
+
+ challenge
+ The client challenge to the server for the server to identify
+ itself is a (nearly) arbitrary length random. The TLS server will
+ right justify the challenge data to become the ClientHello.random
+ data (padded with leading zeroes, if necessary), as specified in
+ this protocol specification. If the length of the challenge is
+ greater than 32 bytes, only the last 32 bytes are used. It is
+ legitimate (but not necessary) for a V3 server to reject a V2
+ ClientHello that has fewer than 16 bytes of challenge data.
+
+ Note: Requests to resume a TLS session should use a TLS client hello.
+
+E.2. Avoiding man-in-the-middle version rollback
+
+ When TLS clients fall back to Version 2.0 compatibility mode, they
+ should use special PKCS #1 block formatting. This is done so that TLS
+ servers will reject Version 2.0 sessions with TLS-capable clients.
+
+ When TLS clients are in Version 2.0 compatibility mode, they set the
+ right-hand (least-significant) 8 random bytes of the PKCS padding
+ (not including the terminal null of the padding) for the RSA
+ encryption of the ENCRYPTED-KEY-DATA field of the CLIENT-MASTER-KEY
+ to 0x03 (the other padding bytes are random). After decrypting the
+ ENCRYPTED-KEY-DATA field, servers that support TLS should issue an
+ error if these eight padding bytes are 0x03. Version 2.0 servers
+ receiving blocks padded in this manner will proceed normally.
+
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 68]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+F. Security analysis
+
+ The TLS protocol is designed to establish a secure connection between
+ a client and a server communicating over an insecure channel. This
+ document makes several traditional assumptions, including that
+ attackers have substantial computational resources and cannot obtain
+ secret information from sources outside the protocol. Attackers are
+ assumed to have the ability to capture, modify, delete, replay, and
+ otherwise tamper with messages sent over the communication channel.
+ This appendix outlines how TLS has been designed to resist a variety
+ of attacks.
+
+F.1. Handshake protocol
+
+ The handshake protocol is responsible for selecting a CipherSpec and
+ generating a Master Secret, which together comprise the primary
+ cryptographic parameters associated with a secure session. The
+ handshake protocol can also optionally authenticate parties who have
+ certificates signed by a trusted certificate authority.
+
+F.1.1. Authentication and key exchange
+
+ TLS supports three authentication modes: authentication of both
+ parties, server authentication with an unauthenticated client, and
+ total anonymity. Whenever the server is authenticated, the channel is
+ secure against man-in-the-middle attacks, but completely anonymous
+ sessions are inherently vulnerable to such attacks. Anonymous
+ servers cannot authenticate clients. If the server is authenticated,
+ its certificate message must provide a valid certificate chain
+ leading to an acceptable certificate authority. Similarly,
+ authenticated clients must supply an acceptable certificate to the
+ server. Each party is responsible for verifying that the other's
+ certificate is valid and has not expired or been revoked.
+
+ The general goal of the key exchange process is to create a
+ pre_master_secret known to the communicating parties and not to
+ attackers. The pre_master_secret will be used to generate the
+ master_secret (see Section 8.1). The master_secret is required to
+ generate the certificate verify and finished messages, encryption
+ keys, and MAC secrets (see Sections 7.4.8, 7.4.9 and 6.3). By sending
+ a correct finished message, parties thus prove that they know the
+ correct pre_master_secret.
+
+F.1.1.1. Anonymous key exchange
+
+ Completely anonymous sessions can be established using RSA or
+ Diffie-Hellman for key exchange. With anonymous RSA, the client
+ encrypts a pre_master_secret with the server's uncertified public key
+
+
+
+Dierks & Allen Standards Track [Page 69]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ extracted from the server key exchange message. The result is sent in
+ a client key exchange message. Since eavesdroppers do not know the
+ server's private key, it will be infeasible for them to decode the
+ pre_master_secret. (Note that no anonymous RSA Cipher Suites are
+ defined in this document).
+
+ With Diffie-Hellman, the server's public parameters are contained in
+ the server key exchange message and the client's are sent in the
+ client key exchange message. Eavesdroppers who do not know the
+ private values should not be able to find the Diffie-Hellman result
+ (i.e. the pre_master_secret).
+
+ Warning: Completely anonymous connections only provide protection
+ against passive eavesdropping. Unless an independent tamper-
+ proof channel is used to verify that the finished messages
+ were not replaced by an attacker, server authentication is
+ required in environments where active man-in-the-middle
+ attacks are a concern.
+
+F.1.1.2. RSA key exchange and authentication
+
+ With RSA, key exchange and server authentication are combined. The
+ public key may be either contained in the server's certificate or may
+ be a temporary RSA key sent in a server key exchange message. When
+ temporary RSA keys are used, they are signed by the server's RSA or
+ DSS certificate. The signature includes the current
+ ClientHello.random, so old signatures and temporary keys cannot be
+ replayed. Servers may use a single temporary RSA key for multiple
+ negotiation sessions.
+
+ Note: The temporary RSA key option is useful if servers need large
+ certificates but must comply with government-imposed size limits
+ on keys used for key exchange.
+
+ After verifying the server's certificate, the client encrypts a
+ pre_master_secret with the server's public key. By successfully
+ decoding the pre_master_secret and producing a correct finished
+ message, the server demonstrates that it knows the private key
+ corresponding to the server certificate.
+
+ When RSA is used for key exchange, clients are authenticated using
+ the certificate verify message (see Section 7.4.8). The client signs
+ a value derived from the master_secret and all preceding handshake
+ messages. These handshake messages include the server certificate,
+ which binds the signature to the server, and ServerHello.random,
+ which binds the signature to the current handshake process.
+
+
+
+
+
+Dierks & Allen Standards Track [Page 70]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+F.1.1.3. Diffie-Hellman key exchange with authentication
+
+ When Diffie-Hellman key exchange is used, the server can either
+ supply a certificate containing fixed Diffie-Hellman parameters or
+ can use the server key exchange message to send a set of temporary
+ Diffie-Hellman parameters signed with a DSS or RSA certificate.
+ Temporary parameters are hashed with the hello.random values before
+ signing to ensure that attackers do not replay old parameters. In
+ either case, the client can verify the certificate or signature to
+ ensure that the parameters belong to the server.
+
+ If the client has a certificate containing fixed Diffie-Hellman
+ parameters, its certificate contains the information required to
+ complete the key exchange. Note that in this case the client and
+ server will generate the same Diffie-Hellman result (i.e.,
+ pre_master_secret) every time they communicate. To prevent the
+ pre_master_secret from staying in memory any longer than necessary,
+ it should be converted into the master_secret as soon as possible.
+ Client Diffie-Hellman parameters must be compatible with those
+ supplied by the server for the key exchange to work.
+
+ If the client has a standard DSS or RSA certificate or is
+ unauthenticated, it sends a set of temporary parameters to the server
+ in the client key exchange message, then optionally uses a
+ certificate verify message to authenticate itself.
+
+F.1.2. Version rollback attacks
+
+ Because TLS includes substantial improvements over SSL Version 2.0,
+ attackers may try to make TLS-capable clients and servers fall back
+ to Version 2.0. This attack can occur if (and only if) two TLS-
+ capable parties use an SSL 2.0 handshake.
+
+ Although the solution using non-random PKCS #1 block type 2 message
+ padding is inelegant, it provides a reasonably secure way for Version
+ 3.0 servers to detect the attack. This solution is not secure against
+ attackers who can brute force the key and substitute a new
+ ENCRYPTED-KEY-DATA message containing the same key (but with normal
+ padding) before the application specified wait threshold has expired.
+ Parties concerned about attacks of this scale should not be using
+ 40-bit encryption keys anyway. Altering the padding of the least-
+ significant 8 bytes of the PKCS padding does not impact security for
+ the size of the signed hashes and RSA key lengths used in the
+ protocol, since this is essentially equivalent to increasing the
+ input block size by 8 bytes.
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 71]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+F.1.3. Detecting attacks against the handshake protocol
+
+ An attacker might try to influence the handshake exchange to make the
+ parties select different encryption algorithms than they would
+ normally choose. Because many implementations will support 40-bit
+ exportable encryption and some may even support null encryption or
+ MAC algorithms, this attack is of particular concern.
+
+ For this attack, an attacker must actively change one or more
+ handshake messages. If this occurs, the client and server will
+ compute different values for the handshake message hashes. As a
+ result, the parties will not accept each others' finished messages.
+ Without the master_secret, the attacker cannot repair the finished
+ messages, so the attack will be discovered.
+
+F.1.4. Resuming sessions
+
+ When a connection is established by resuming a session, new
+ ClientHello.random and ServerHello.random values are hashed with the
+ session's master_secret. Provided that the master_secret has not been
+ compromised and that the secure hash operations used to produce the
+ encryption keys and MAC secrets are secure, the connection should be
+ secure and effectively independent from previous connections.
+ Attackers cannot use known encryption keys or MAC secrets to
+ compromise the master_secret without breaking the secure hash
+ operations (which use both SHA and MD5).
+
+ Sessions cannot be resumed unless both the client and server agree.
+ If either party suspects that the session may have been compromised,
+ or that certificates may have expired or been revoked, it should
+ force a full handshake. An upper limit of 24 hours is suggested for
+ session ID lifetimes, since an attacker who obtains a master_secret
+ may be able to impersonate the compromised party until the
+ corresponding session ID is retired. Applications that may be run in
+ relatively insecure environments should not write session IDs to
+ stable storage.
+
+F.1.5. MD5 and SHA
+
+ TLS uses hash functions very conservatively. Where possible, both MD5
+ and SHA are used in tandem to ensure that non-catastrophic flaws in
+ one algorithm will not break the overall protocol.
+
+F.2. Protecting application data
+
+ The master_secret is hashed with the ClientHello.random and
+ ServerHello.random to produce unique data encryption keys and MAC
+ secrets for each connection.
+
+
+
+Dierks & Allen Standards Track [Page 72]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Outgoing data is protected with a MAC before transmission. To prevent
+ message replay or modification attacks, the MAC is computed from the
+ MAC secret, the sequence number, the message length, the message
+ contents, and two fixed character strings. The message type field is
+ necessary to ensure that messages intended for one TLS Record Layer
+ client are not redirected to another. The sequence number ensures
+ that attempts to delete or reorder messages will be detected. Since
+ sequence numbers are 64-bits long, they should never overflow.
+ Messages from one party cannot be inserted into the other's output,
+ since they use independent MAC secrets. Similarly, the server-write
+ and client-write keys are independent so stream cipher keys are used
+ only once.
+
+ If an attacker does break an encryption key, all messages encrypted
+ with it can be read. Similarly, compromise of a MAC key can make
+ message modification attacks possible. Because MACs are also
+ encrypted, message-alteration attacks generally require breaking the
+ encryption algorithm as well as the MAC.
+
+ Note: MAC secrets may be larger than encryption keys, so messages can
+ remain tamper resistant even if encryption keys are broken.
+
+F.3. Final notes
+
+ For TLS to be able to provide a secure connection, both the client
+ and server systems, keys, and applications must be secure. In
+ addition, the implementation must be free of security errors.
+
+ The system is only as strong as the weakest key exchange and
+ authentication algorithm supported, and only trustworthy
+ cryptographic functions should be used. Short public keys, 40-bit
+ bulk encryption keys, and anonymous servers should be used with great
+ caution. Implementations and users must be careful when deciding
+ which certificates and certificate authorities are acceptable; a
+ dishonest certificate authority can do tremendous damage.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 73]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+G. Patent Statement
+
+ Some of the cryptographic algorithms proposed for use in this
+ protocol have patent claims on them. In addition Netscape
+ Communications Corporation has a patent claim on the Secure Sockets
+ Layer (SSL) work that this standard is based on. The Internet
+ Standards Process as defined in RFC 2026 requests that a statement be
+ obtained from a Patent holder indicating that a license will be made
+ available to applicants under reasonable terms and conditions.
+
+ The Massachusetts Institute of Technology has granted RSA Data
+ Security, Inc., exclusive sub-licensing rights to the following
+ patent issued in the United States:
+
+ Cryptographic Communications System and Method ("RSA"), No.
+ 4,405,829
+
+ Netscape Communications Corporation has been issued the following
+ patent in the United States:
+
+ Secure Socket Layer Application Program Apparatus And Method
+ ("SSL"), No. 5,657,390
+
+ Netscape Communications has issued the following statement:
+
+ Intellectual Property Rights
+
+ Secure Sockets Layer
+
+ The United States Patent and Trademark Office ("the PTO")
+ recently issued U.S. Patent No. 5,657,390 ("the SSL Patent") to
+ Netscape for inventions described as Secure Sockets Layers
+ ("SSL"). The IETF is currently considering adopting SSL as a
+ transport protocol with security features. Netscape encourages
+ the royalty-free adoption and use of the SSL protocol upon the
+ following terms and conditions:
+
+ * If you already have a valid SSL Ref license today which
+ includes source code from Netscape, an additional patent
+ license under the SSL patent is not required.
+
+ * If you don't have an SSL Ref license, you may have a royalty
+ free license to build implementations covered by the SSL
+ Patent Claims or the IETF TLS specification provided that you
+ do not to assert any patent rights against Netscape or other
+ companies for the implementation of SSL or the IETF TLS
+ recommendation.
+
+
+
+
+Dierks & Allen Standards Track [Page 74]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ What are "Patent Claims":
+
+ Patent claims are claims in an issued foreign or domestic patent
+ that:
+
+ 1) must be infringed in order to implement methods or build
+ products according to the IETF TLS specification; or
+
+ 2) patent claims which require the elements of the SSL patent
+ claims and/or their equivalents to be infringed.
+
+ The Internet Society, Internet Architecture Board, Internet
+ Engineering Steering Group and the Corporation for National Research
+ Initiatives take no position on the validity or scope of the patents
+ and patent applications, nor on the appropriateness of the terms of
+ the assurance. The Internet Society and other groups mentioned above
+ have not made any determination as to any other intellectual property
+ rights which may apply to the practice of this standard. Any further
+ consideration of these matters is the user's own responsibility.
+
+Security Considerations
+
+ Security issues are discussed throughout this memo.
+
+References
+
+ [3DES] W. Tuchman, "Hellman Presents No Shortcut Solutions To DES,"
+ IEEE Spectrum, v. 16, n. 7, July 1979, pp40-41.
+
+ [BLEI] Bleichenbacher D., "Chosen Ciphertext Attacks against
+ Protocols Based on RSA Encryption Standard PKCS #1" in
+ Advances in Cryptology -- CRYPTO'98, LNCS vol. 1462, pages:
+ 1--12, 1998.
+
+ [DES] ANSI X3.106, "American National Standard for Information
+ Systems-Data Link Encryption," American National Standards
+ Institute, 1983.
+
+ [DH1] W. Diffie and M. E. Hellman, "New Directions in
+ Cryptography," IEEE Transactions on Information Theory, V.
+ IT-22, n. 6, Jun 1977, pp. 74-84.
+
+ [DSS] NIST FIPS PUB 186, "Digital Signature Standard," National
+ Institute of Standards and Technology, U.S. Department of
+ Commerce, May 18, 1994.
+
+ [FTP] Postel J., and J. Reynolds, "File Transfer Protocol", STD 9,
+ RFC 959, October 1985.
+
+
+
+Dierks & Allen Standards Track [Page 75]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ [HTTP] Berners-Lee, T., Fielding, R., and H. Frystyk, "Hypertext
+ Transfer Protocol -- HTTP/1.0", RFC 1945, May 1996.
+
+ [HMAC] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication," RFC 2104, February
+ 1997.
+
+ [IDEA] X. Lai, "On the Design and Security of Block Ciphers," ETH
+ Series in Information Processing, v. 1, Konstanz: Hartung-
+ Gorre Verlag, 1992.
+
+ [MD2] Kaliski, B., "The MD2 Message Digest Algorithm", RFC 1319,
+ April 1992.
+
+ [MD5] Rivest, R., "The MD5 Message Digest Algorithm", RFC 1321,
+ April 1992.
+
+ [PKCS1] RSA Laboratories, "PKCS #1: RSA Encryption Standard,"
+ version 1.5, November 1993.
+
+ [PKCS6] RSA Laboratories, "PKCS #6: RSA Extended Certificate Syntax
+ Standard," version 1.5, November 1993.
+
+ [PKCS7] RSA Laboratories, "PKCS #7: RSA Cryptographic Message Syntax
+ Standard," version 1.5, November 1993.
+
+ [PKIX] Housley, R., Ford, W., Polk, W. and D. Solo, "Internet
+ Public Key Infrastructure: Part I: X.509 Certificate and CRL
+ Profile", RFC 2459, January 1999.
+
+ [RC2] Rivest, R., "A Description of the RC2(r) Encryption
+ Algorithm", RFC 2268, January 1998.
+
+ [RC4] Thayer, R. and K. Kaukonen, A Stream Cipher Encryption
+ Algorithm, Work in Progress.
+
+ [RSA] R. Rivest, A. Shamir, and L. M. Adleman, "A Method for
+ Obtaining Digital Signatures and Public-Key Cryptosystems,"
+ Communications of the ACM, v. 21, n. 2, Feb 1978, pp. 120-
+ 126.
+
+ [RSADSI] Contact RSA Data Security, Inc., Tel: 415-595-8782
+
+ [SCH] B. Schneier. Applied Cryptography: Protocols, Algorithms,
+ and Source Code in C, Published by John Wiley & Sons, Inc.
+ 1994.
+
+
+
+
+
+Dierks & Allen Standards Track [Page 76]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ [SHA] NIST FIPS PUB 180-1, "Secure Hash Standard," National
+ Institute of Standards and Technology, U.S. Department of
+ Commerce, Work in Progress, May 31, 1994.
+
+ [SSL2] Hickman, Kipp, "The SSL Protocol", Netscape Communications
+ Corp., Feb 9, 1995.
+
+ [SSL3] A. Frier, P. Karlton, and P. Kocher, "The SSL 3.0 Protocol",
+ Netscape Communications Corp., Nov 18, 1996.
+
+ [TCP] Postel, J., "Transmission Control Protocol," STD 7, RFC 793,
+ September 1981.
+
+ [TEL] Postel J., and J. Reynolds, "Telnet Protocol
+ Specifications", STD 8, RFC 854, May 1993.
+
+ [TEL] Postel J., and J. Reynolds, "Telnet Option Specifications",
+ STD 8, RFC 855, May 1993.
+
+ [X509] CCITT. Recommendation X.509: "The Directory - Authentication
+ Framework". 1988.
+
+ [XDR] R. Srinivansan, Sun Microsystems, RFC-1832: XDR: External
+ Data Representation Standard, August 1995.
+
+Credits
+
+ Win Treese
+ Open Market
+
+ EMail: treese@openmarket.com
+
+
+ Editors
+
+ Christopher Allen Tim Dierks
+ Certicom Certicom
+
+ EMail: callen@certicom.com EMail: tdierks@certicom.com
+
+
+ Authors' Addresses
+
+ Tim Dierks Philip L. Karlton
+ Certicom Netscape Communications
+
+ EMail: tdierks@certicom.com
+
+
+
+
+Dierks & Allen Standards Track [Page 77]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Alan O. Freier Paul C. Kocher
+ Netscape Communications Independent Consultant
+
+ EMail: freier@netscape.com EMail: pck@netcom.com
+
+
+ Other contributors
+
+ Martin Abadi Robert Relyea
+ Digital Equipment Corporation Netscape Communications
+
+ EMail: ma@pa.dec.com EMail: relyea@netscape.com
+
+ Ran Canetti Jim Roskind
+ IBM Watson Research Center Netscape Communications
+
+ EMail: canetti@watson.ibm.com EMail: jar@netscape.com
+
+
+ Taher Elgamal Micheal J. Sabin, Ph. D.
+ Securify Consulting Engineer
+
+ EMail: elgamal@securify.com EMail: msabin@netcom.com
+
+
+ Anil R. Gangolli Dan Simon
+ Structured Arts Computing Corp. Microsoft
+
+ EMail: gangolli@structuredarts.com EMail: dansimon@microsoft.com
+
+
+ Kipp E.B. Hickman Tom Weinstein
+ Netscape Communications Netscape Communications
+
+ EMail: kipp@netscape.com EMail: tomw@netscape.com
+
+
+ Hugo Krawczyk
+ IBM Watson Research Center
+
+ EMail: hugo@watson.ibm.com
+
+Comments
+
+ The discussion list for the IETF TLS working group is located at the
+ e-mail address <ietf-tls@lists.consensus.com>. Information on the
+ group and information on how to subscribe to the list is at
+ <http://lists.consensus.com/>.
+
+
+
+Dierks & Allen Standards Track [Page 78]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+ Archives of the list can be found at:
+ <http://www.imc.org/ietf-tls/mail-archive/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 79]
+
+RFC 2246 The TLS Protocol Version 1.0 January 1999
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dierks & Allen Standards Track [Page 80]
+
diff --git a/standards/rfc2396.txt b/standards/rfc2396.txt
new file mode 100644
index 000000000..5bd52110a
--- /dev/null
+++ b/standards/rfc2396.txt
@@ -0,0 +1,2243 @@
+
+
+
+
+
+
+Network Working Group T. Berners-Lee
+Request for Comments: 2396 MIT/LCS
+Updates: 1808, 1738 R. Fielding
+Category: Standards Track U.C. Irvine
+ L. Masinter
+ Xerox Corporation
+ August 1998
+
+
+ Uniform Resource Identifiers (URI): Generic Syntax
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1998). All Rights Reserved.
+
+IESG Note
+
+ This paper describes a "superset" of operations that can be applied
+ to URI. It consists of both a grammar and a description of basic
+ functionality for URI. To understand what is a valid URI, both the
+ grammar and the associated description have to be studied. Some of
+ the functionality described is not applicable to all URI schemes, and
+ some operations are only possible when certain media types are
+ retrieved using the URI, regardless of the scheme used.
+
+Abstract
+
+ A Uniform Resource Identifier (URI) is a compact string of characters
+ for identifying an abstract or physical resource. This document
+ defines the generic syntax of URI, including both absolute and
+ relative forms, and guidelines for their use; it revises and replaces
+ the generic definitions in RFC 1738 and RFC 1808.
+
+ This document defines a grammar that is a superset of all valid URI,
+ such that an implementation can parse the common components of a URI
+ reference without knowing the scheme-specific requirements of every
+ possible identifier type. This document does not define a generative
+ grammar for URI; that task will be performed by the individual
+ specifications of each URI scheme.
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 1]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+1. Introduction
+
+ Uniform Resource Identifiers (URI) provide a simple and extensible
+ means for identifying a resource. This specification of URI syntax
+ and semantics is derived from concepts introduced by the World Wide
+ Web global information initiative, whose use of such objects dates
+ from 1990 and is described in "Universal Resource Identifiers in WWW"
+ [RFC1630]. The specification of URI is designed to meet the
+ recommendations laid out in "Functional Recommendations for Internet
+ Resource Locators" [RFC1736] and "Functional Requirements for Uniform
+ Resource Names" [RFC1737].
+
+ This document updates and merges "Uniform Resource Locators"
+ [RFC1738] and "Relative Uniform Resource Locators" [RFC1808] in order
+ to define a single, generic syntax for all URI. It excludes those
+ portions of RFC 1738 that defined the specific syntax of individual
+ URL schemes; those portions will be updated as separate documents, as
+ will the process for registration of new URI schemes. This document
+ does not discuss the issues and recommendation for dealing with
+ characters outside of the US-ASCII character set [ASCII]; those
+ recommendations are discussed in a separate document.
+
+ All significant changes from the prior RFCs are noted in Appendix G.
+
+1.1 Overview of URI
+
+ URI are characterized by the following definitions:
+
+ Uniform
+ Uniformity provides several benefits: it allows different types
+ of resource identifiers to be used in the same context, even
+ when the mechanisms used to access those resources may differ;
+ it allows uniform semantic interpretation of common syntactic
+ conventions across different types of resource identifiers; it
+ allows introduction of new types of resource identifiers
+ without interfering with the way that existing identifiers are
+ used; and, it allows the identifiers to be reused in many
+ different contexts, thus permitting new applications or
+ protocols to leverage a pre-existing, large, and widely-used
+ set of resource identifiers.
+
+ Resource
+ A resource can be anything that has identity. Familiar
+ examples include an electronic document, an image, a service
+ (e.g., "today's weather report for Los Angeles"), and a
+ collection of other resources. Not all resources are network
+ "retrievable"; e.g., human beings, corporations, and bound
+ books in a library can also be considered resources.
+
+
+
+Berners-Lee, et. al. Standards Track [Page 2]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ The resource is the conceptual mapping to an entity or set of
+ entities, not necessarily the entity which corresponds to that
+ mapping at any particular instance in time. Thus, a resource
+ can remain constant even when its content---the entities to
+ which it currently corresponds---changes over time, provided
+ that the conceptual mapping is not changed in the process.
+
+ Identifier
+ An identifier is an object that can act as a reference to
+ something that has identity. In the case of URI, the object is
+ a sequence of characters with a restricted syntax.
+
+ Having identified a resource, a system may perform a variety of
+ operations on the resource, as might be characterized by such words
+ as `access', `update', `replace', or `find attributes'.
+
+1.2. URI, URL, and URN
+
+ A URI can be further classified as a locator, a name, or both. The
+ term "Uniform Resource Locator" (URL) refers to the subset of URI
+ that identify resources via a representation of their primary access
+ mechanism (e.g., their network "location"), rather than identifying
+ the resource by name or by some other attribute(s) of that resource.
+ The term "Uniform Resource Name" (URN) refers to the subset of URI
+ that are required to remain globally unique and persistent even when
+ the resource ceases to exist or becomes unavailable.
+
+ The URI scheme (Section 3.1) defines the namespace of the URI, and
+ thus may further restrict the syntax and semantics of identifiers
+ using that scheme. This specification defines those elements of the
+ URI syntax that are either required of all URI schemes or are common
+ to many URI schemes. It thus defines the syntax and semantics that
+ are needed to implement a scheme-independent parsing mechanism for
+ URI references, such that the scheme-dependent handling of a URI can
+ be postponed until the scheme-dependent semantics are needed. We use
+ the term URL below when describing syntax or semantics that only
+ apply to locators.
+
+ Although many URL schemes are named after protocols, this does not
+ imply that the only way to access the URL's resource is via the named
+ protocol. Gateways, proxies, caches, and name resolution services
+ might be used to access some resources, independent of the protocol
+ of their origin, and the resolution of some URL may require the use
+ of more than one protocol (e.g., both DNS and HTTP are typically used
+ to access an "http" URL's resource when it can't be found in a local
+ cache).
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 3]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ A URN differs from a URL in that it's primary purpose is persistent
+ labeling of a resource with an identifier. That identifier is drawn
+ from one of a set of defined namespaces, each of which has its own
+ set name structure and assignment procedures. The "urn" scheme has
+ been reserved to establish the requirements for a standardized URN
+ namespace, as defined in "URN Syntax" [RFC2141] and its related
+ specifications.
+
+ Most of the examples in this specification demonstrate URL, since
+ they allow the most varied use of the syntax and often have a
+ hierarchical namespace. A parser of the URI syntax is capable of
+ parsing both URL and URN references as a generic URI; once the scheme
+ is determined, the scheme-specific parsing can be performed on the
+ generic URI components. In other words, the URI syntax is a superset
+ of the syntax of all URI schemes.
+
+1.3. Example URI
+
+ The following examples illustrate URI that are in common use.
+
+ ftp://ftp.is.co.za/rfc/rfc1808.txt
+ -- ftp scheme for File Transfer Protocol services
+
+ gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles
+ -- gopher scheme for Gopher and Gopher+ Protocol services
+
+ http://www.math.uio.no/faq/compression-faq/part1.html
+ -- http scheme for Hypertext Transfer Protocol services
+
+ mailto:mduerst@ifi.unizh.ch
+ -- mailto scheme for electronic mail addresses
+
+ news:comp.infosystems.www.servers.unix
+ -- news scheme for USENET news groups and articles
+
+ telnet://melvyl.ucop.edu/
+ -- telnet scheme for interactive services via the TELNET Protocol
+
+1.4. Hierarchical URI and Relative Forms
+
+ An absolute identifier refers to a resource independent of the
+ context in which the identifier is used. In contrast, a relative
+ identifier refers to a resource by describing the difference within a
+ hierarchical namespace between the current context and an absolute
+ identifier of the resource.
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 4]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ Some URI schemes support a hierarchical naming system, where the
+ hierarchy of the name is denoted by a "/" delimiter separating the
+ components in the scheme. This document defines a scheme-independent
+ `relative' form of URI reference that can be used in conjunction with
+ a `base' URI (of a hierarchical scheme) to produce another URI. The
+ syntax of hierarchical URI is described in Section 3; the relative
+ URI calculation is described in Section 5.
+
+1.5. URI Transcribability
+
+ The URI syntax was designed with global transcribability as one of
+ its main concerns. A URI is a sequence of characters from a very
+ limited set, i.e. the letters of the basic Latin alphabet, digits,
+ and a few special characters. A URI may be represented in a variety
+ of ways: e.g., ink on paper, pixels on a screen, or a sequence of
+ octets in a coded character set. The interpretation of a URI depends
+ only on the characters used and not how those characters are
+ represented in a network protocol.
+
+ The goal of transcribability can be described by a simple scenario.
+ Imagine two colleagues, Sam and Kim, sitting in a pub at an
+ international conference and exchanging research ideas. Sam asks Kim
+ for a location to get more information, so Kim writes the URI for the
+ research site on a napkin. Upon returning home, Sam takes out the
+ napkin and types the URI into a computer, which then retrieves the
+ information to which Kim referred.
+
+ There are several design concerns revealed by the scenario:
+
+ o A URI is a sequence of characters, which is not always
+ represented as a sequence of octets.
+
+ o A URI may be transcribed from a non-network source, and thus
+ should consist of characters that are most likely to be able to
+ be typed into a computer, within the constraints imposed by
+ keyboards (and related input devices) across languages and
+ locales.
+
+ o A URI often needs to be remembered by people, and it is easier
+ for people to remember a URI when it consists of meaningful
+ components.
+
+ These design concerns are not always in alignment. For example, it
+ is often the case that the most meaningful name for a URI component
+ would require characters that cannot be typed into some systems. The
+ ability to transcribe the resource identifier from one medium to
+ another was considered more important than having its URI consist of
+ the most meaningful of components. In local and regional contexts
+
+
+
+Berners-Lee, et. al. Standards Track [Page 5]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ and with improving technology, users might benefit from being able to
+ use a wider range of characters; such use is not defined in this
+ document.
+
+1.6. Syntax Notation and Common Elements
+
+ This document uses two conventions to describe and define the syntax
+ for URI. The first, called the layout form, is a general description
+ of the order of components and component separators, as in
+
+ <first>/<second>;<third>?<fourth>
+
+ The component names are enclosed in angle-brackets and any characters
+ outside angle-brackets are literal separators. Whitespace should be
+ ignored. These descriptions are used informally and do not define
+ the syntax requirements.
+
+ The second convention is a BNF-like grammar, used to define the
+ formal URI syntax. The grammar is that of [RFC822], except that "|"
+ is used to designate alternatives. Briefly, rules are separated from
+ definitions by an equal "=", indentation is used to continue a rule
+ definition over more than one line, literals are quoted with "",
+ parentheses "(" and ")" are used to group elements, optional elements
+ are enclosed in "[" and "]" brackets, and elements may be preceded
+ with <n>* to designate n or more repetitions of the following
+ element; n defaults to 0.
+
+ Unlike many specifications that use a BNF-like grammar to define the
+ bytes (octets) allowed by a protocol, the URI grammar is defined in
+ terms of characters. Each literal in the grammar corresponds to the
+ character it represents, rather than to the octet encoding of that
+ character in any particular coded character set. How a URI is
+ represented in terms of bits and bytes on the wire is dependent upon
+ the character encoding of the protocol used to transport it, or the
+ charset of the document which contains it.
+
+ The following definitions are common to many elements:
+
+ alpha = lowalpha | upalpha
+
+ lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
+ "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
+ "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
+
+ upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
+ "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
+ "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 6]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
+ "8" | "9"
+
+ alphanum = alpha | digit
+
+ The complete URI syntax is collected in Appendix A.
+
+2. URI Characters and Escape Sequences
+
+ URI consist of a restricted set of characters, primarily chosen to
+ aid transcribability and usability both in computer systems and in
+ non-computer communications. Characters used conventionally as
+ delimiters around URI were excluded. The restricted set of
+ characters consists of digits, letters, and a few graphic symbols
+ were chosen from those common to most of the character encodings and
+ input facilities available to Internet users.
+
+ uric = reserved | unreserved | escaped
+
+ Within a URI, characters are either used as delimiters, or to
+ represent strings of data (octets) within the delimited portions.
+ Octets are either represented directly by a character (using the US-
+ ASCII character for that octet [ASCII]) or by an escape encoding.
+ This representation is elaborated below.
+
+2.1 URI and non-ASCII characters
+
+ The relationship between URI and characters has been a source of
+ confusion for characters that are not part of US-ASCII. To describe
+ the relationship, it is useful to distinguish between a "character"
+ (as a distinguishable semantic entity) and an "octet" (an 8-bit
+ byte). There are two mappings, one from URI characters to octets, and
+ a second from octets to original characters:
+
+ URI character sequence->octet sequence->original character sequence
+
+ A URI is represented as a sequence of characters, not as a sequence
+ of octets. That is because URI might be "transported" by means that
+ are not through a computer network, e.g., printed on paper, read over
+ the radio, etc.
+
+ A URI scheme may define a mapping from URI characters to octets;
+ whether this is done depends on the scheme. Commonly, within a
+ delimited component of a URI, a sequence of characters may be used to
+ represent a sequence of octets. For example, the character "a"
+ represents the octet 97 (decimal), while the character sequence "%",
+ "0", "a" represents the octet 10 (decimal).
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 7]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ There is a second translation for some resources: the sequence of
+ octets defined by a component of the URI is subsequently used to
+ represent a sequence of characters. A 'charset' defines this mapping.
+ There are many charsets in use in Internet protocols. For example,
+ UTF-8 [UTF-8] defines a mapping from sequences of octets to sequences
+ of characters in the repertoire of ISO 10646.
+
+ In the simplest case, the original character sequence contains only
+ characters that are defined in US-ASCII, and the two levels of
+ mapping are simple and easily invertible: each 'original character'
+ is represented as the octet for the US-ASCII code for it, which is,
+ in turn, represented as either the US-ASCII character, or else the
+ "%" escape sequence for that octet.
+
+ For original character sequences that contain non-ASCII characters,
+ however, the situation is more difficult. Internet protocols that
+ transmit octet sequences intended to represent character sequences
+ are expected to provide some way of identifying the charset used, if
+ there might be more than one [RFC2277]. However, there is currently
+ no provision within the generic URI syntax to accomplish this
+ identification. An individual URI scheme may require a single
+ charset, define a default charset, or provide a way to indicate the
+ charset used.
+
+ It is expected that a systematic treatment of character encoding
+ within URI will be developed as a future modification of this
+ specification.
+
+2.2. Reserved Characters
+
+ Many URI include components consisting of or delimited by, certain
+ special characters. These characters are called "reserved", since
+ their usage within the URI component is limited to their reserved
+ purpose. If the data for a URI component would conflict with the
+ reserved purpose, then the conflicting data must be escaped before
+ forming the URI.
+
+ reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
+ "$" | ","
+
+ The "reserved" syntax class above refers to those characters that are
+ allowed within a URI, but which may not be allowed within a
+ particular component of the generic URI syntax; they are used as
+ delimiters of the components described in Section 3.
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 8]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ Characters in the "reserved" set are not reserved in all contexts.
+ The set of characters actually reserved within any given URI
+ component is defined by that component. In general, a character is
+ reserved if the semantics of the URI changes if the character is
+ replaced with its escaped US-ASCII encoding.
+
+2.3. Unreserved Characters
+
+ Data characters that are allowed in a URI but do not have a reserved
+ purpose are called unreserved. These include upper and lower case
+ letters, decimal digits, and a limited set of punctuation marks and
+ symbols.
+
+ unreserved = alphanum | mark
+
+ mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
+
+ Unreserved characters can be escaped without changing the semantics
+ of the URI, but this should not be done unless the URI is being used
+ in a context that does not allow the unescaped character to appear.
+
+2.4. Escape Sequences
+
+ Data must be escaped if it does not have a representation using an
+ unreserved character; this includes data that does not correspond to
+ a printable character of the US-ASCII coded character set, or that
+ corresponds to any US-ASCII character that is disallowed, as
+ explained below.
+
+2.4.1. Escaped Encoding
+
+ An escaped octet is encoded as a character triplet, consisting of the
+ percent character "%" followed by the two hexadecimal digits
+ representing the octet code. For example, "%20" is the escaped
+ encoding for the US-ASCII space character.
+
+ escaped = "%" hex hex
+ hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
+ "a" | "b" | "c" | "d" | "e" | "f"
+
+2.4.2. When to Escape and Unescape
+
+ A URI is always in an "escaped" form, since escaping or unescaping a
+ completed URI might change its semantics. Normally, the only time
+ escape encodings can safely be made is when the URI is being created
+ from its component parts; each component may have its own set of
+ characters that are reserved, so only the mechanism responsible for
+ generating or interpreting that component can determine whether or
+
+
+
+Berners-Lee, et. al. Standards Track [Page 9]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ not escaping a character will change its semantics. Likewise, a URI
+ must be separated into its components before the escaped characters
+ within those components can be safely decoded.
+
+ In some cases, data that could be represented by an unreserved
+ character may appear escaped; for example, some of the unreserved
+ "mark" characters are automatically escaped by some systems. If the
+ given URI scheme defines a canonicalization algorithm, then
+ unreserved characters may be unescaped according to that algorithm.
+ For example, "%7e" is sometimes used instead of "~" in an http URL
+ path, but the two are equivalent for an http URL.
+
+ Because the percent "%" character always has the reserved purpose of
+ being the escape indicator, it must be escaped as "%25" in order to
+ be used as data within a URI. Implementers should be careful not to
+ escape or unescape the same string more than once, since unescaping
+ an already unescaped string might lead to misinterpreting a percent
+ data character as another escaped character, or vice versa in the
+ case of escaping an already escaped string.
+
+2.4.3. Excluded US-ASCII Characters
+
+ Although they are disallowed within the URI syntax, we include here a
+ description of those US-ASCII characters that have been excluded and
+ the reasons for their exclusion.
+
+ The control characters in the US-ASCII coded character set are not
+ used within a URI, both because they are non-printable and because
+ they are likely to be misinterpreted by some control mechanisms.
+
+ control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
+
+ The space character is excluded because significant spaces may
+ disappear and insignificant spaces may be introduced when URI are
+ transcribed or typeset or subjected to the treatment of word-
+ processing programs. Whitespace is also used to delimit URI in many
+ contexts.
+
+ space = <US-ASCII coded character 20 hexadecimal>
+
+ The angle-bracket "<" and ">" and double-quote (") characters are
+ excluded because they are often used as the delimiters around URI in
+ text documents and protocol fields. The character "#" is excluded
+ because it is used to delimit a URI from a fragment identifier in URI
+ references (Section 4). The percent character "%" is excluded because
+ it is used for the encoding of escaped characters.
+
+ delims = "<" | ">" | "#" | "%" | <">
+
+
+
+Berners-Lee, et. al. Standards Track [Page 10]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ Other characters are excluded because gateways and other transport
+ agents are known to sometimes modify such characters, or they are
+ used as delimiters.
+
+ unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
+
+ Data corresponding to excluded characters must be escaped in order to
+ be properly represented within a URI.
+
+3. URI Syntactic Components
+
+ The URI syntax is dependent upon the scheme. In general, absolute
+ URI are written as follows:
+
+ <scheme>:<scheme-specific-part>
+
+ An absolute URI contains the name of the scheme being used (<scheme>)
+ followed by a colon (":") and then a string (the <scheme-specific-
+ part>) whose interpretation depends on the scheme.
+
+ The URI syntax does not require that the scheme-specific-part have
+ any general structure or set of semantics which is common among all
+ URI. However, a subset of URI do share a common syntax for
+ representing hierarchical relationships within the namespace. This
+ "generic URI" syntax consists of a sequence of four main components:
+
+ <scheme>://<authority><path>?<query>
+
+ each of which, except <scheme>, may be absent from a particular URI.
+ For example, some URI schemes do not allow an <authority> component,
+ and others do not use a <query> component.
+
+ absoluteURI = scheme ":" ( hier_part | opaque_part )
+
+ URI that are hierarchical in nature use the slash "/" character for
+ separating hierarchical components. For some file systems, a "/"
+ character (used to denote the hierarchical structure of a URI) is the
+ delimiter used to construct a file name hierarchy, and thus the URI
+ path will look similar to a file pathname. This does NOT imply that
+ the resource is a file or that the URI maps to an actual filesystem
+ pathname.
+
+ hier_part = ( net_path | abs_path ) [ "?" query ]
+
+ net_path = "//" authority [ abs_path ]
+
+ abs_path = "/" path_segments
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 11]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ URI that do not make use of the slash "/" character for separating
+ hierarchical components are considered opaque by the generic URI
+ parser.
+
+ opaque_part = uric_no_slash *uric
+
+ uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
+ "&" | "=" | "+" | "$" | ","
+
+ We use the term <path> to refer to both the <abs_path> and
+ <opaque_part> constructs, since they are mutually exclusive for any
+ given URI and can be parsed as a single component.
+
+3.1. Scheme Component
+
+ Just as there are many different methods of access to resources,
+ there are a variety of schemes for identifying such resources. The
+ URI syntax consists of a sequence of components separated by reserved
+ characters, with the first component defining the semantics for the
+ remainder of the URI string.
+
+ Scheme names consist of a sequence of characters beginning with a
+ lower case letter and followed by any combination of lower case
+ letters, digits, plus ("+"), period ("."), or hyphen ("-"). For
+ resiliency, programs interpreting URI should treat upper case letters
+ as equivalent to lower case in scheme names (e.g., allow "HTTP" as
+ well as "http").
+
+ scheme = alpha *( alpha | digit | "+" | "-" | "." )
+
+ Relative URI references are distinguished from absolute URI in that
+ they do not begin with a scheme name. Instead, the scheme is
+ inherited from the base URI, as described in Section 5.2.
+
+3.2. Authority Component
+
+ Many URI schemes include a top hierarchical element for a naming
+ authority, such that the namespace defined by the remainder of the
+ URI is governed by that authority. This authority component is
+ typically defined by an Internet-based server or a scheme-specific
+ registry of naming authorities.
+
+ authority = server | reg_name
+
+ The authority component is preceded by a double slash "//" and is
+ terminated by the next slash "/", question-mark "?", or by the end of
+ the URI. Within the authority component, the characters ";", ":",
+ "@", "?", and "/" are reserved.
+
+
+
+Berners-Lee, et. al. Standards Track [Page 12]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ An authority component is not required for a URI scheme to make use
+ of relative references. A base URI without an authority component
+ implies that any relative reference will also be without an authority
+ component.
+
+3.2.1. Registry-based Naming Authority
+
+ The structure of a registry-based naming authority is specific to the
+ URI scheme, but constrained to the allowed characters for an
+ authority component.
+
+ reg_name = 1*( unreserved | escaped | "$" | "," |
+ ";" | ":" | "@" | "&" | "=" | "+" )
+
+3.2.2. Server-based Naming Authority
+
+ URL schemes that involve the direct use of an IP-based protocol to a
+ specified server on the Internet use a common syntax for the server
+ component of the URI's scheme-specific data:
+
+ <userinfo>@<host>:<port>
+
+ where <userinfo> may consist of a user name and, optionally, scheme-
+ specific information about how to gain authorization to access the
+ server. The parts "<userinfo>@" and ":<port>" may be omitted.
+
+ server = [ [ userinfo "@" ] hostport ]
+
+ The user information, if present, is followed by a commercial at-sign
+ "@".
+
+ userinfo = *( unreserved | escaped |
+ ";" | ":" | "&" | "=" | "+" | "$" | "," )
+
+ Some URL schemes use the format "user:password" in the userinfo
+ field. This practice is NOT RECOMMENDED, because the passing of
+ authentication information in clear text (such as URI) has proven to
+ be a security risk in almost every case where it has been used.
+
+ The host is a domain name of a network host, or its IPv4 address as a
+ set of four decimal digit groups separated by ".". Literal IPv6
+ addresses are not supported.
+
+ hostport = host [ ":" port ]
+ host = hostname | IPv4address
+ hostname = *( domainlabel "." ) toplabel [ "." ]
+ domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
+ toplabel = alpha | alpha *( alphanum | "-" ) alphanum
+
+
+
+Berners-Lee, et. al. Standards Track [Page 13]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit
+ port = *digit
+
+ Hostnames take the form described in Section 3 of [RFC1034] and
+ Section 2.1 of [RFC1123]: a sequence of domain labels separated by
+ ".", each domain label starting and ending with an alphanumeric
+ character and possibly also containing "-" characters. The rightmost
+ domain label of a fully qualified domain name will never start with a
+ digit, thus syntactically distinguishing domain names from IPv4
+ addresses, and may be followed by a single "." if it is necessary to
+ distinguish between the complete domain name and any local domain.
+ To actually be "Uniform" as a resource locator, a URL hostname should
+ be a fully qualified domain name. In practice, however, the host
+ component may be a local domain literal.
+
+ Note: A suitable representation for including a literal IPv6
+ address as the host part of a URL is desired, but has not yet been
+ determined or implemented in practice.
+
+ The port is the network port number for the server. Most schemes
+ designate protocols that have a default port number. Another port
+ number may optionally be supplied, in decimal, separated from the
+ host by a colon. If the port is omitted, the default port number is
+ assumed.
+
+3.3. Path Component
+
+ The path component contains data, specific to the authority (or the
+ scheme if there is no authority component), identifying the resource
+ within the scope of that scheme and authority.
+
+ path = [ abs_path | opaque_part ]
+
+ path_segments = segment *( "/" segment )
+ segment = *pchar *( ";" param )
+ param = *pchar
+
+ pchar = unreserved | escaped |
+ ":" | "@" | "&" | "=" | "+" | "$" | ","
+
+ The path may consist of a sequence of path segments separated by a
+ single slash "/" character. Within a path segment, the characters
+ "/", ";", "=", and "?" are reserved. Each path segment may include a
+ sequence of parameters, indicated by the semicolon ";" character.
+ The parameters are not significant to the parsing of relative
+ references.
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 14]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+3.4. Query Component
+
+ The query component is a string of information to be interpreted by
+ the resource.
+
+ query = *uric
+
+ Within a query component, the characters ";", "/", "?", ":", "@",
+ "&", "=", "+", ",", and "$" are reserved.
+
+4. URI References
+
+ The term "URI-reference" is used here to denote the common usage of a
+ resource identifier. A URI reference may be absolute or relative,
+ and may have additional information attached in the form of a
+ fragment identifier. However, "the URI" that results from such a
+ reference includes only the absolute URI after the fragment
+ identifier (if any) is removed and after any relative URI is resolved
+ to its absolute form. Although it is possible to limit the
+ discussion of URI syntax and semantics to that of the absolute
+ result, most usage of URI is within general URI references, and it is
+ impossible to obtain the URI from such a reference without also
+ parsing the fragment and resolving the relative form.
+
+ URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
+
+ The syntax for relative URI is a shortened form of that for absolute
+ URI, where some prefix of the URI is missing and certain path
+ components ("." and "..") have a special meaning when, and only when,
+ interpreting a relative path. The relative URI syntax is defined in
+ Section 5.
+
+4.1. Fragment Identifier
+
+ When a URI reference is used to perform a retrieval action on the
+ identified resource, the optional fragment identifier, separated from
+ the URI by a crosshatch ("#") character, consists of additional
+ reference information to be interpreted by the user agent after the
+ retrieval action has been successfully completed. As such, it is not
+ part of a URI, but is often used in conjunction with a URI.
+
+ fragment = *uric
+
+ The semantics of a fragment identifier is a property of the data
+ resulting from a retrieval action, regardless of the type of URI used
+ in the reference. Therefore, the format and interpretation of
+ fragment identifiers is dependent on the media type [RFC2046] of the
+ retrieval result. The character restrictions described in Section 2
+
+
+
+Berners-Lee, et. al. Standards Track [Page 15]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ for URI also apply to the fragment in a URI-reference. Individual
+ media types may define additional restrictions or structure within
+ the fragment for specifying different types of "partial views" that
+ can be identified within that media type.
+
+ A fragment identifier is only meaningful when a URI reference is
+ intended for retrieval and the result of that retrieval is a document
+ for which the identified fragment is consistently defined.
+
+4.2. Same-document References
+
+ A URI reference that does not contain a URI is a reference to the
+ current document. In other words, an empty URI reference within a
+ document is interpreted as a reference to the start of that document,
+ and a reference containing only a fragment identifier is a reference
+ to the identified fragment of that document. Traversal of such a
+ reference should not result in an additional retrieval action.
+ However, if the URI reference occurs in a context that is always
+ intended to result in a new request, as in the case of HTML's FORM
+ element, then an empty URI reference represents the base URI of the
+ current document and should be replaced by that URI when transformed
+ into a request.
+
+4.3. Parsing a URI Reference
+
+ A URI reference is typically parsed according to the four main
+ components and fragment identifier in order to determine what
+ components are present and whether the reference is relative or
+ absolute. The individual components are then parsed for their
+ subparts and, if not opaque, to verify their validity.
+
+ Although the BNF defines what is allowed in each component, it is
+ ambiguous in terms of differentiating between an authority component
+ and a path component that begins with two slash characters. The
+ greedy algorithm is used for disambiguation: the left-most matching
+ rule soaks up as much of the URI reference string as it is capable of
+ matching. In other words, the authority component wins.
+
+ Readers familiar with regular expressions should see Appendix B for a
+ concrete parsing example and test oracle.
+
+5. Relative URI References
+
+ It is often the case that a group or "tree" of documents has been
+ constructed to serve a common purpose; the vast majority of URI in
+ these documents point to resources within the tree rather than
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 16]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ outside of it. Similarly, documents located at a particular site are
+ much more likely to refer to other resources at that site than to
+ resources at remote sites.
+
+ Relative addressing of URI allows document trees to be partially
+ independent of their location and access scheme. For instance, it is
+ possible for a single set of hypertext documents to be simultaneously
+ accessible and traversable via each of the "file", "http", and "ftp"
+ schemes if the documents refer to each other using relative URI.
+ Furthermore, such document trees can be moved, as a whole, without
+ changing any of the relative references. Experience within the WWW
+ has demonstrated that the ability to perform relative referencing is
+ necessary for the long-term usability of embedded URI.
+
+ The syntax for relative URI takes advantage of the <hier_part> syntax
+ of <absoluteURI> (Section 3) in order to express a reference that is
+ relative to the namespace of another hierarchical URI.
+
+ relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
+
+ A relative reference beginning with two slash characters is termed a
+ network-path reference, as defined by <net_path> in Section 3. Such
+ references are rarely used.
+
+ A relative reference beginning with a single slash character is
+ termed an absolute-path reference, as defined by <abs_path> in
+ Section 3.
+
+ A relative reference that does not begin with a scheme name or a
+ slash character is termed a relative-path reference.
+
+ rel_path = rel_segment [ abs_path ]
+
+ rel_segment = 1*( unreserved | escaped |
+ ";" | "@" | "&" | "=" | "+" | "$" | "," )
+
+ Within a relative-path reference, the complete path segments "." and
+ ".." have special meanings: "the current hierarchy level" and "the
+ level above this hierarchy level", respectively. Although this is
+ very similar to their use within Unix-based filesystems to indicate
+ directory levels, these path components are only considered special
+ when resolving a relative-path reference to its absolute form
+ (Section 5.2).
+
+ Authors should be aware that a path segment which contains a colon
+ character cannot be used as the first segment of a relative URI path
+ (e.g., "this:that"), because it would be mistaken for a scheme name.
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 17]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ It is therefore necessary to precede such segments with other
+ segments (e.g., "./this:that") in order for them to be referenced as
+ a relative path.
+
+ It is not necessary for all URI within a given scheme to be
+ restricted to the <hier_part> syntax, since the hierarchical
+ properties of that syntax are only necessary when relative URI are
+ used within a particular document. Documents can only make use of
+ relative URI when their base URI fits within the <hier_part> syntax.
+ It is assumed that any document which contains a relative reference
+ will also have a base URI that obeys the syntax. In other words,
+ relative URI cannot be used within a document that has an unsuitable
+ base URI.
+
+ Some URI schemes do not allow a hierarchical syntax matching the
+ <hier_part> syntax, and thus cannot use relative references.
+
+5.1. Establishing a Base URI
+
+ The term "relative URI" implies that there exists some absolute "base
+ URI" against which the relative reference is applied. Indeed, the
+ base URI is necessary to define the semantics of any relative URI
+ reference; without it, a relative reference is meaningless. In order
+ for relative URI to be usable within a document, the base URI of that
+ document must be known to the parser.
+
+ The base URI of a document can be established in one of four ways,
+ listed below in order of precedence. The order of precedence can be
+ thought of in terms of layers, where the innermost defined base URI
+ has the highest precedence. This can be visualized graphically as:
+
+ .----------------------------------------------------------.
+ | .----------------------------------------------------. |
+ | | .----------------------------------------------. | |
+ | | | .----------------------------------------. | | |
+ | | | | .----------------------------------. | | | |
+ | | | | | <relative_reference> | | | | |
+ | | | | `----------------------------------' | | | |
+ | | | | (5.1.1) Base URI embedded in the | | | |
+ | | | | document's content | | | |
+ | | | `----------------------------------------' | | |
+ | | | (5.1.2) Base URI of the encapsulating entity | | |
+ | | | (message, document, or none). | | |
+ | | `----------------------------------------------' | |
+ | | (5.1.3) URI used to retrieve the entity | |
+ | `----------------------------------------------------' |
+ | (5.1.4) Default Base URI is application-dependent |
+ `----------------------------------------------------------'
+
+
+
+Berners-Lee, et. al. Standards Track [Page 18]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+5.1.1. Base URI within Document Content
+
+ Within certain document media types, the base URI of the document can
+ be embedded within the content itself such that it can be readily
+ obtained by a parser. This can be useful for descriptive documents,
+ such as tables of content, which may be transmitted to others through
+ protocols other than their usual retrieval context (e.g., E-Mail or
+ USENET news).
+
+ It is beyond the scope of this document to specify how, for each
+ media type, the base URI can be embedded. It is assumed that user
+ agents manipulating such media types will be able to obtain the
+ appropriate syntax from that media type's specification. An example
+ of how the base URI can be embedded in the Hypertext Markup Language
+ (HTML) [RFC1866] is provided in Appendix D.
+
+ A mechanism for embedding the base URI within MIME container types
+ (e.g., the message and multipart types) is defined by MHTML
+ [RFC2110]. Protocols that do not use the MIME message header syntax,
+ but which do allow some form of tagged metainformation to be included
+ within messages, may define their own syntax for defining the base
+ URI as part of a message.
+
+5.1.2. Base URI from the Encapsulating Entity
+
+ If no base URI is embedded, the base URI of a document is defined by
+ the document's retrieval context. For a document that is enclosed
+ within another entity (such as a message or another document), the
+ retrieval context is that entity; thus, the default base URI of the
+ document is the base URI of the entity in which the document is
+ encapsulated.
+
+5.1.3. Base URI from the Retrieval URI
+
+ If no base URI is embedded and the document is not encapsulated
+ within some other entity (e.g., the top level of a composite entity),
+ then, if a URI was used to retrieve the base document, that URI shall
+ be considered the base URI. Note that if the retrieval was the
+ result of a redirected request, the last URI used (i.e., that which
+ resulted in the actual retrieval of the document) is the base URI.
+
+5.1.4. Default Base URI
+
+ If none of the conditions described in Sections 5.1.1--5.1.3 apply,
+ then the base URI is defined by the context of the application.
+ Since this definition is necessarily application-dependent, failing
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 19]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ to define the base URI using one of the other methods may result in
+ the same content being interpreted differently by different types of
+ application.
+
+ It is the responsibility of the distributor(s) of a document
+ containing relative URI to ensure that the base URI for that document
+ can be established. It must be emphasized that relative URI cannot
+ be used reliably in situations where the document's base URI is not
+ well-defined.
+
+5.2. Resolving Relative References to Absolute Form
+
+ This section describes an example algorithm for resolving URI
+ references that might be relative to a given base URI.
+
+ The base URI is established according to the rules of Section 5.1 and
+ parsed into the four main components as described in Section 3. Note
+ that only the scheme component is required to be present in the base
+ URI; the other components may be empty or undefined. A component is
+ undefined if its preceding separator does not appear in the URI
+ reference; the path component is never undefined, though it may be
+ empty. The base URI's query component is not used by the resolution
+ algorithm and may be discarded.
+
+ For each URI reference, the following steps are performed in order:
+
+ 1) The URI reference is parsed into the potential four components and
+ fragment identifier, as described in Section 4.3.
+
+ 2) If the path component is empty and the scheme, authority, and
+ query components are undefined, then it is a reference to the
+ current document and we are done. Otherwise, the reference URI's
+ query and fragment components are defined as found (or not found)
+ within the URI reference and not inherited from the base URI.
+
+ 3) If the scheme component is defined, indicating that the reference
+ starts with a scheme name, then the reference is interpreted as an
+ absolute URI and we are done. Otherwise, the reference URI's
+ scheme is inherited from the base URI's scheme component.
+
+ Due to a loophole in prior specifications [RFC1630], some parsers
+ allow the scheme name to be present in a relative URI if it is the
+ same as the base URI scheme. Unfortunately, this can conflict
+ with the correct parsing of non-hierarchical URI. For backwards
+ compatibility, an implementation may work around such references
+ by removing the scheme if it matches that of the base URI and the
+ scheme is known to always use the <hier_part> syntax. The parser
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 20]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ can then continue with the steps below for the remainder of the
+ reference components. Validating parsers should mark such a
+ misformed relative reference as an error.
+
+ 4) If the authority component is defined, then the reference is a
+ network-path and we skip to step 7. Otherwise, the reference
+ URI's authority is inherited from the base URI's authority
+ component, which will also be undefined if the URI scheme does not
+ use an authority component.
+
+ 5) If the path component begins with a slash character ("/"), then
+ the reference is an absolute-path and we skip to step 7.
+
+ 6) If this step is reached, then we are resolving a relative-path
+ reference. The relative path needs to be merged with the base
+ URI's path. Although there are many ways to do this, we will
+ describe a simple method using a separate string buffer.
+
+ a) All but the last segment of the base URI's path component is
+ copied to the buffer. In other words, any characters after the
+ last (right-most) slash character, if any, are excluded.
+
+ b) The reference's path component is appended to the buffer
+ string.
+
+ c) All occurrences of "./", where "." is a complete path segment,
+ are removed from the buffer string.
+
+ d) If the buffer string ends with "." as a complete path segment,
+ that "." is removed.
+
+ e) All occurrences of "<segment>/../", where <segment> is a
+ complete path segment not equal to "..", are removed from the
+ buffer string. Removal of these path segments is performed
+ iteratively, removing the leftmost matching pattern on each
+ iteration, until no matching pattern remains.
+
+ f) If the buffer string ends with "<segment>/..", where <segment>
+ is a complete path segment not equal to "..", that
+ "<segment>/.." is removed.
+
+ g) If the resulting buffer string still begins with one or more
+ complete path segments of "..", then the reference is
+ considered to be in error. Implementations may handle this
+ error by retaining these components in the resolved path (i.e.,
+ treating them as part of the final URI), by removing them from
+ the resolved path (i.e., discarding relative levels above the
+ root), or by avoiding traversal of the reference.
+
+
+
+Berners-Lee, et. al. Standards Track [Page 21]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ h) The remaining buffer string is the reference URI's new path
+ component.
+
+ 7) The resulting URI components, including any inherited from the
+ base URI, are recombined to give the absolute form of the URI
+ reference. Using pseudocode, this would be
+
+ result = ""
+
+ if scheme is defined then
+ append scheme to result
+ append ":" to result
+
+ if authority is defined then
+ append "//" to result
+ append authority to result
+
+ append path to result
+
+ if query is defined then
+ append "?" to result
+ append query to result
+
+ if fragment is defined then
+ append "#" to result
+ append fragment to result
+
+ return result
+
+ Note that we must be careful to preserve the distinction between a
+ component that is undefined, meaning that its separator was not
+ present in the reference, and a component that is empty, meaning
+ that the separator was present and was immediately followed by the
+ next component separator or the end of the reference.
+
+ The above algorithm is intended to provide an example by which the
+ output of implementations can be tested -- implementation of the
+ algorithm itself is not required. For example, some systems may find
+ it more efficient to implement step 6 as a pair of segment stacks
+ being merged, rather than as a series of string pattern replacements.
+
+ Note: Some WWW client applications will fail to separate the
+ reference's query component from its path component before merging
+ the base and reference paths in step 6 above. This may result in
+ a loss of information if the query component contains the strings
+ "/../" or "/./".
+
+ Resolution examples are provided in Appendix C.
+
+
+
+Berners-Lee, et. al. Standards Track [Page 22]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+6. URI Normalization and Equivalence
+
+ In many cases, different URI strings may actually identify the
+ identical resource. For example, the host names used in URL are
+ actually case insensitive, and the URL <http://www.XEROX.com> is
+ equivalent to <http://www.xerox.com>. In general, the rules for
+ equivalence and definition of a normal form, if any, are scheme
+ dependent. When a scheme uses elements of the common syntax, it will
+ also use the common syntax equivalence rules, namely that the scheme
+ and hostname are case insensitive and a URL with an explicit ":port",
+ where the port is the default for the scheme, is equivalent to one
+ where the port is elided.
+
+7. Security Considerations
+
+ A URI does not in itself pose a security threat. Users should beware
+ that there is no general guarantee that a URL, which at one time
+ located a given resource, will continue to do so. Nor is there any
+ guarantee that a URL will not locate a different resource at some
+ later point in time, due to the lack of any constraint on how a given
+ authority apportions its namespace. Such a guarantee can only be
+ obtained from the person(s) controlling that namespace and the
+ resource in question. A specific URI scheme may include additional
+ semantics, such as name persistence, if those semantics are required
+ of all naming authorities for that scheme.
+
+ It is sometimes possible to construct a URL such that an attempt to
+ perform a seemingly harmless, idempotent operation, such as the
+ retrieval of an entity associated with the resource, will in fact
+ cause a possibly damaging remote operation to occur. The unsafe URL
+ is typically constructed by specifying a port number other than that
+ reserved for the network protocol in question. The client
+ unwittingly contacts a site that is in fact running a different
+ protocol. The content of the URL contains instructions that, when
+ interpreted according to this other protocol, cause an unexpected
+ operation. An example has been the use of a gopher URL to cause an
+ unintended or impersonating message to be sent via a SMTP server.
+
+ Caution should be used when using any URL that specifies a port
+ number other than the default for the protocol, especially when it is
+ a number within the reserved space.
+
+ Care should be taken when a URL contains escaped delimiters for a
+ given protocol (for example, CR and LF characters for telnet
+ protocols) that these are not unescaped before transmission. This
+ might violate the protocol, but avoids the potential for such
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 23]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ characters to be used to simulate an extra operation or parameter in
+ that protocol, which might lead to an unexpected and possibly harmful
+ remote operation to be performed.
+
+ It is clearly unwise to use a URL that contains a password which is
+ intended to be secret. In particular, the use of a password within
+ the 'userinfo' component of a URL is strongly disrecommended except
+ in those rare cases where the 'password' parameter is intended to be
+ public.
+
+8. Acknowledgements
+
+ This document was derived from RFC 1738 [RFC1738] and RFC 1808
+ [RFC1808]; the acknowledgements in those specifications still apply.
+ In addition, contributions by Gisle Aas, Martin Beet, Martin Duerst,
+ Jim Gettys, Martijn Koster, Dave Kristol, Daniel LaLiberte, Foteos
+ Macrides, James Marshall, Ryan Moats, Keith Moore, and Lauren Wood
+ are gratefully acknowledged.
+
+9. References
+
+ [RFC2277] Alvestrand, H., "IETF Policy on Character Sets and
+ Languages", BCP 18, RFC 2277, January 1998.
+
+ [RFC1630] Berners-Lee, T., "Universal Resource Identifiers in WWW: A
+ Unifying Syntax for the Expression of Names and Addresses
+ of Objects on the Network as used in the World-Wide Web",
+ RFC 1630, June 1994.
+
+ [RFC1738] Berners-Lee, T., Masinter, L., and M. McCahill, Editors,
+ "Uniform Resource Locators (URL)", RFC 1738, December 1994.
+
+ [RFC1866] Berners-Lee T., and D. Connolly, "HyperText Markup Language
+ Specification -- 2.0", RFC 1866, November 1995.
+
+ [RFC1123] Braden, R., Editor, "Requirements for Internet Hosts --
+ Application and Support", STD 3, RFC 1123, October 1989.
+
+ [RFC822] Crocker, D., "Standard for the Format of ARPA Internet Text
+ Messages", STD 11, RFC 822, August 1982.
+
+ [RFC1808] Fielding, R., "Relative Uniform Resource Locators", RFC
+ 1808, June 1995.
+
+ [RFC2046] Freed, N., and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part Two: Media Types", RFC 2046,
+ November 1996.
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 24]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ [RFC1736] Kunze, J., "Functional Recommendations for Internet
+ Resource Locators", RFC 1736, February 1995.
+
+ [RFC2141] Moats, R., "URN Syntax", RFC 2141, May 1997.
+
+ [RFC1034] Mockapetris, P., "Domain Names - Concepts and Facilities",
+ STD 13, RFC 1034, November 1987.
+
+ [RFC2110] Palme, J., and A. Hopmann, "MIME E-mail Encapsulation of
+ Aggregate Documents, such as HTML (MHTML)", RFC 2110, March
+ 1997.
+
+ [RFC1737] Sollins, K., and L. Masinter, "Functional Requirements for
+ Uniform Resource Names", RFC 1737, December 1994.
+
+ [ASCII] US-ASCII. "Coded Character Set -- 7-bit American Standard
+ Code for Information Interchange", ANSI X3.4-1986.
+
+ [UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO 10646",
+ RFC 2279, January 1998.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 25]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+10. Authors' Addresses
+
+ Tim Berners-Lee
+ World Wide Web Consortium
+ MIT Laboratory for Computer Science, NE43-356
+ 545 Technology Square
+ Cambridge, MA 02139
+
+ Fax: +1(617)258-8682
+ EMail: timbl@w3.org
+
+
+ Roy T. Fielding
+ Department of Information and Computer Science
+ University of California, Irvine
+ Irvine, CA 92697-3425
+
+ Fax: +1(949)824-1715
+ EMail: fielding@ics.uci.edu
+
+
+ Larry Masinter
+ Xerox PARC
+ 3333 Coyote Hill Road
+ Palo Alto, CA 94034
+
+ Fax: +1(415)812-4333
+ EMail: masinter@parc.xerox.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 26]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+A. Collected BNF for URI
+
+ URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
+ absoluteURI = scheme ":" ( hier_part | opaque_part )
+ relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
+
+ hier_part = ( net_path | abs_path ) [ "?" query ]
+ opaque_part = uric_no_slash *uric
+
+ uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
+ "&" | "=" | "+" | "$" | ","
+
+ net_path = "//" authority [ abs_path ]
+ abs_path = "/" path_segments
+ rel_path = rel_segment [ abs_path ]
+
+ rel_segment = 1*( unreserved | escaped |
+ ";" | "@" | "&" | "=" | "+" | "$" | "," )
+
+ scheme = alpha *( alpha | digit | "+" | "-" | "." )
+
+ authority = server | reg_name
+
+ reg_name = 1*( unreserved | escaped | "$" | "," |
+ ";" | ":" | "@" | "&" | "=" | "+" )
+
+ server = [ [ userinfo "@" ] hostport ]
+ userinfo = *( unreserved | escaped |
+ ";" | ":" | "&" | "=" | "+" | "$" | "," )
+
+ hostport = host [ ":" port ]
+ host = hostname | IPv4address
+ hostname = *( domainlabel "." ) toplabel [ "." ]
+ domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
+ toplabel = alpha | alpha *( alphanum | "-" ) alphanum
+ IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit
+ port = *digit
+
+ path = [ abs_path | opaque_part ]
+ path_segments = segment *( "/" segment )
+ segment = *pchar *( ";" param )
+ param = *pchar
+ pchar = unreserved | escaped |
+ ":" | "@" | "&" | "=" | "+" | "$" | ","
+
+ query = *uric
+
+ fragment = *uric
+
+
+
+Berners-Lee, et. al. Standards Track [Page 27]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ uric = reserved | unreserved | escaped
+ reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
+ "$" | ","
+ unreserved = alphanum | mark
+ mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
+ "(" | ")"
+
+ escaped = "%" hex hex
+ hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
+ "a" | "b" | "c" | "d" | "e" | "f"
+
+ alphanum = alpha | digit
+ alpha = lowalpha | upalpha
+
+ lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
+ "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
+ "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
+ upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
+ "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
+ "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
+ digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
+ "8" | "9"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 28]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+B. Parsing a URI Reference with a Regular Expression
+
+ As described in Section 4.3, the generic URI syntax is not sufficient
+ to disambiguate the components of some forms of URI. Since the
+ "greedy algorithm" described in that section is identical to the
+ disambiguation method used by POSIX regular expressions, it is
+ natural and commonplace to use a regular expression for parsing the
+ potential four components and fragment identifier of a URI reference.
+
+ The following line is the regular expression for breaking-down a URI
+ reference into its components.
+
+ ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
+ 12 3 4 5 6 7 8 9
+
+ The numbers in the second line above are only to assist readability;
+ they indicate the reference points for each subexpression (i.e., each
+ paired parenthesis). We refer to the value matched for subexpression
+ <n> as $<n>. For example, matching the above expression to
+
+ http://www.ics.uci.edu/pub/ietf/uri/#Related
+
+ results in the following subexpression matches:
+
+ $1 = http:
+ $2 = http
+ $3 = //www.ics.uci.edu
+ $4 = www.ics.uci.edu
+ $5 = /pub/ietf/uri/
+ $6 = <undefined>
+ $7 = <undefined>
+ $8 = #Related
+ $9 = Related
+
+ where <undefined> indicates that the component is not present, as is
+ the case for the query component in the above example. Therefore, we
+ can determine the value of the four components and fragment as
+
+ scheme = $2
+ authority = $4
+ path = $5
+ query = $7
+ fragment = $9
+
+ and, going in the opposite direction, we can recreate a URI reference
+ from its components using the algorithm in step 7 of Section 5.2.
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 29]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+C. Examples of Resolving Relative URI References
+
+ Within an object with a well-defined base URI of
+
+ http://a/b/c/d;p?q
+
+ the relative URI would be resolved as follows:
+
+C.1. Normal Examples
+
+ g:h = g:h
+ g = http://a/b/c/g
+ ./g = http://a/b/c/g
+ g/ = http://a/b/c/g/
+ /g = http://a/g
+ //g = http://g
+ ?y = http://a/b/c/?y
+ g?y = http://a/b/c/g?y
+ #s = (current document)#s
+ g#s = http://a/b/c/g#s
+ g?y#s = http://a/b/c/g?y#s
+ ;x = http://a/b/c/;x
+ g;x = http://a/b/c/g;x
+ g;x?y#s = http://a/b/c/g;x?y#s
+ . = http://a/b/c/
+ ./ = http://a/b/c/
+ .. = http://a/b/
+ ../ = http://a/b/
+ ../g = http://a/b/g
+ ../.. = http://a/
+ ../../ = http://a/
+ ../../g = http://a/g
+
+C.2. Abnormal Examples
+
+ Although the following abnormal examples are unlikely to occur in
+ normal practice, all URI parsers should be capable of resolving them
+ consistently. Each example uses the same base as above.
+
+ An empty reference refers to the start of the current document.
+
+ <> = (current document)
+
+ Parsers must be careful in handling the case where there are more
+ relative path ".." segments than there are hierarchical levels in the
+ base URI's path. Note that the ".." syntax cannot be used to change
+ the authority component of a URI.
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 30]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ ../../../g = http://a/../g
+ ../../../../g = http://a/../../g
+
+ In practice, some implementations strip leading relative symbolic
+ elements (".", "..") after applying a relative URI calculation, based
+ on the theory that compensating for obvious author errors is better
+ than allowing the request to fail. Thus, the above two references
+ will be interpreted as "http://a/g" by some implementations.
+
+ Similarly, parsers must avoid treating "." and ".." as special when
+ they are not complete components of a relative path.
+
+ /./g = http://a/./g
+ /../g = http://a/../g
+ g. = http://a/b/c/g.
+ .g = http://a/b/c/.g
+ g.. = http://a/b/c/g..
+ ..g = http://a/b/c/..g
+
+ Less likely are cases where the relative URI uses unnecessary or
+ nonsensical forms of the "." and ".." complete path segments.
+
+ ./../g = http://a/b/g
+ ./g/. = http://a/b/c/g/
+ g/./h = http://a/b/c/g/h
+ g/../h = http://a/b/c/h
+ g;x=1/./y = http://a/b/c/g;x=1/y
+ g;x=1/../y = http://a/b/c/y
+
+ All client applications remove the query component from the base URI
+ before resolving relative URI. However, some applications fail to
+ separate the reference's query and/or fragment components from a
+ relative path before merging it with the base path. This error is
+ rarely noticed, since typical usage of a fragment never includes the
+ hierarchy ("/") character, and the query component is not normally
+ used within relative references.
+
+ g?y/./x = http://a/b/c/g?y/./x
+ g?y/../x = http://a/b/c/g?y/../x
+ g#s/./x = http://a/b/c/g#s/./x
+ g#s/../x = http://a/b/c/g#s/../x
+
+
+
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 31]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ Some parsers allow the scheme name to be present in a relative URI if
+ it is the same as the base URI scheme. This is considered to be a
+ loophole in prior specifications of partial URI [RFC1630]. Its use
+ should be avoided.
+
+ http:g = http:g ; for validating parsers
+ | http://a/b/c/g ; for backwards compatibility
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 32]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+D. Embedding the Base URI in HTML documents
+
+ It is useful to consider an example of how the base URI of a document
+ can be embedded within the document's content. In this appendix, we
+ describe how documents written in the Hypertext Markup Language
+ (HTML) [RFC1866] can include an embedded base URI. This appendix
+ does not form a part of the URI specification and should not be
+ considered as anything more than a descriptive example.
+
+ HTML defines a special element "BASE" which, when present in the
+ "HEAD" portion of a document, signals that the parser should use the
+ BASE element's "HREF" attribute as the base URI for resolving any
+ relative URI. The "HREF" attribute must be an absolute URI. Note
+ that, in HTML, element and attribute names are case-insensitive. For
+ example:
+
+ <!doctype html public "-//IETF//DTD HTML//EN">
+ <HTML><HEAD>
+ <TITLE>An example HTML document</TITLE>
+ <BASE href="http://www.ics.uci.edu/Test/a/b/c">
+ </HEAD><BODY>
+ ... <A href="../x">a hypertext anchor</A> ...
+ </BODY></HTML>
+
+ A parser reading the example document should interpret the given
+ relative URI "../x" as representing the absolute URI
+
+ <http://www.ics.uci.edu/Test/a/x>
+
+ regardless of the context in which the example document was obtained.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 33]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+E. Recommendations for Delimiting URI in Context
+
+ URI are often transmitted through formats that do not provide a clear
+ context for their interpretation. For example, there are many
+ occasions when URI are included in plain text; examples include text
+ sent in electronic mail, USENET news messages, and, most importantly,
+ printed on paper. In such cases, it is important to be able to
+ delimit the URI from the rest of the text, and in particular from
+ punctuation marks that might be mistaken for part of the URI.
+
+ In practice, URI are delimited in a variety of ways, but usually
+ within double-quotes "http://test.com/", angle brackets
+ <http://test.com/>, or just using whitespace
+
+ http://test.com/
+
+ These wrappers do not form part of the URI.
+
+ In the case where a fragment identifier is associated with a URI
+ reference, the fragment would be placed within the brackets as well
+ (separated from the URI with a "#" character).
+
+ In some cases, extra whitespace (spaces, linebreaks, tabs, etc.) may
+ need to be added to break long URI across lines. The whitespace
+ should be ignored when extracting the URI.
+
+ No whitespace should be introduced after a hyphen ("-") character.
+ Because some typesetters and printers may (erroneously) introduce a
+ hyphen at the end of line when breaking a line, the interpreter of a
+ URI containing a line break immediately after a hyphen should ignore
+ all unescaped whitespace around the line break, and should be aware
+ that the hyphen may or may not actually be part of the URI.
+
+ Using <> angle brackets around each URI is especially recommended as
+ a delimiting style for URI that contain whitespace.
+
+ The prefix "URL:" (with or without a trailing space) was recommended
+ as a way to used to help distinguish a URL from other bracketed
+ designators, although this is not common in practice.
+
+ For robustness, software that accepts user-typed URI should attempt
+ to recognize and strip both delimiters and embedded whitespace.
+
+ For example, the text:
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 34]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ Yes, Jim, I found it under "http://www.w3.org/Addressing/",
+ but you can probably pick it up from <ftp://ds.internic.
+ net/rfc/>. Note the warning in <http://www.ics.uci.edu/pub/
+ ietf/uri/historical.html#WARNING>.
+
+ contains the URI references
+
+ http://www.w3.org/Addressing/
+ ftp://ds.internic.net/rfc/
+ http://www.ics.uci.edu/pub/ietf/uri/historical.html#WARNING
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 35]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+F. Abbreviated URLs
+
+ The URL syntax was designed for unambiguous reference to network
+ resources and extensibility via the URL scheme. However, as URL
+ identification and usage have become commonplace, traditional media
+ (television, radio, newspapers, billboards, etc.) have increasingly
+ used abbreviated URL references. That is, a reference consisting of
+ only the authority and path portions of the identified resource, such
+ as
+
+ www.w3.org/Addressing/
+
+ or simply the DNS hostname on its own. Such references are primarily
+ intended for human interpretation rather than machine, with the
+ assumption that context-based heuristics are sufficient to complete
+ the URL (e.g., most hostnames beginning with "www" are likely to have
+ a URL prefix of "http://"). Although there is no standard set of
+ heuristics for disambiguating abbreviated URL references, many client
+ implementations allow them to be entered by the user and
+ heuristically resolved. It should be noted that such heuristics may
+ change over time, particularly when new URL schemes are introduced.
+
+ Since an abbreviated URL has the same syntax as a relative URL path,
+ abbreviated URL references cannot be used in contexts where relative
+ URLs are expected. This limits the use of abbreviated URLs to places
+ where there is no defined base URL, such as dialog boxes and off-line
+ advertisements.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 36]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+G. Summary of Non-editorial Changes
+
+G.1. Additions
+
+ Section 4 (URI References) was added to stem the confusion regarding
+ "what is a URI" and how to describe fragment identifiers given that
+ they are not part of the URI, but are part of the URI syntax and
+ parsing concerns. In addition, it provides a reference definition
+ for use by other IETF specifications (HTML, HTTP, etc.) that have
+ previously attempted to redefine the URI syntax in order to account
+ for the presence of fragment identifiers in URI references.
+
+ Section 2.4 was rewritten to clarify a number of misinterpretations
+ and to leave room for fully internationalized URI.
+
+ Appendix F on abbreviated URLs was added to describe the shortened
+ references often seen on television and magazine advertisements and
+ explain why they are not used in other contexts.
+
+G.2. Modifications from both RFC 1738 and RFC 1808
+
+ Changed to URI syntax instead of just URL.
+
+ Confusion regarding the terms "character encoding", the URI
+ "character set", and the escaping of characters with %<hex><hex>
+ equivalents has (hopefully) been reduced. Many of the BNF rule names
+ regarding the character sets have been changed to more accurately
+ describe their purpose and to encompass all "characters" rather than
+ just US-ASCII octets. Unless otherwise noted here, these
+ modifications do not affect the URI syntax.
+
+ Both RFC 1738 and RFC 1808 refer to the "reserved" set of characters
+ as if URI-interpreting software were limited to a single set of
+ characters with a reserved purpose (i.e., as meaning something other
+ than the data to which the characters correspond), and that this set
+ was fixed by the URI scheme. However, this has not been true in
+ practice; any character that is interpreted differently when it is
+ escaped is, in effect, reserved. Furthermore, the interpreting
+ engine on a HTTP server is often dependent on the resource, not just
+ the URI scheme. The description of reserved characters has been
+ changed accordingly.
+
+ The plus "+", dollar "$", and comma "," characters have been added to
+ those in the "reserved" set, since they are treated as reserved
+ within the query component.
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 37]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ The tilde "~" character was added to those in the "unreserved" set,
+ since it is extensively used on the Internet in spite of the
+ difficulty to transcribe it with some keyboards.
+
+ The syntax for URI scheme has been changed to require that all
+ schemes begin with an alpha character.
+
+ The "user:password" form in the previous BNF was changed to a
+ "userinfo" token, and the possibility that it might be
+ "user:password" made scheme specific. In particular, the use of
+ passwords in the clear is not even suggested by the syntax.
+
+ The question-mark "?" character was removed from the set of allowed
+ characters for the userinfo in the authority component, since testing
+ showed that many applications treat it as reserved for separating the
+ query component from the rest of the URI.
+
+ The semicolon ";" character was added to those stated as being
+ reserved within the authority component, since several new schemes
+ are using it as a separator within userinfo to indicate the type of
+ user authentication.
+
+ RFC 1738 specified that the path was separated from the authority
+ portion of a URI by a slash. RFC 1808 followed suit, but with a
+ fudge of carrying around the separator as a "prefix" in order to
+ describe the parsing algorithm. RFC 1630 never had this problem,
+ since it considered the slash to be part of the path. In writing
+ this specification, it was found to be impossible to accurately
+ describe and retain the difference between the two URI
+ <foo:/bar> and <foo:bar>
+ without either considering the slash to be part of the path (as
+ corresponds to actual practice) or creating a separate component just
+ to hold that slash. We chose the former.
+
+G.3. Modifications from RFC 1738
+
+ The definition of specific URL schemes and their scheme-specific
+ syntax and semantics has been moved to separate documents.
+
+ The URL host was defined as a fully-qualified domain name. However,
+ many URLs are used without fully-qualified domain names (in contexts
+ for which the full qualification is not necessary), without any host
+ (as in some file URLs), or with a host of "localhost".
+
+ The URL port is now *digit instead of 1*digit, since systems are
+ expected to handle the case where the ":" separator between host and
+ port is supplied without a port.
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 38]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+ The recommendations for delimiting URI in context (Appendix E) have
+ been adjusted to reflect current practice.
+
+G.4. Modifications from RFC 1808
+
+ RFC 1808 (Section 4) defined an empty URL reference (a reference
+ containing nothing aside from the fragment identifier) as being a
+ reference to the base URL. Unfortunately, that definition could be
+ interpreted, upon selection of such a reference, as a new retrieval
+ action on that resource. Since the normal intent of such references
+ is for the user agent to change its view of the current document to
+ the beginning of the specified fragment within that document, not to
+ make an additional request of the resource, a description of how to
+ correctly interpret an empty reference has been added in Section 4.
+
+ The description of the mythical Base header field has been replaced
+ with a reference to the Content-Location header field defined by
+ MHTML [RFC2110].
+
+ RFC 1808 described various schemes as either having or not having the
+ properties of the generic URI syntax. However, the only requirement
+ is that the particular document containing the relative references
+ have a base URI that abides by the generic URI syntax, regardless of
+ the URI scheme, so the associated description has been updated to
+ reflect that.
+
+ The BNF term <net_loc> has been replaced with <authority>, since the
+ latter more accurately describes its use and purpose. Likewise, the
+ authority is no longer restricted to the IP server syntax.
+
+ Extensive testing of current client applications demonstrated that
+ the majority of deployed systems do not use the ";" character to
+ indicate trailing parameter information, and that the presence of a
+ semicolon in a path segment does not affect the relative parsing of
+ that segment. Therefore, parameters have been removed as a separate
+ component and may now appear in any path segment. Their influence
+ has been removed from the algorithm for resolving a relative URI
+ reference. The resolution examples in Appendix C have been modified
+ to reflect this change.
+
+ Implementations are now allowed to work around misformed relative
+ references that are prefixed by the same scheme as the base URI, but
+ only for schemes known to use the <hier_part> syntax.
+
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 39]
+
+RFC 2396 URI Generic Syntax August 1998
+
+
+H. Full Copyright Statement
+
+ Copyright (C) The Internet Society (1998). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Berners-Lee, et. al. Standards Track [Page 40]
+
diff --git a/standards/rfc2487.txt b/standards/rfc2487.txt
new file mode 100644
index 000000000..fb1305f00
--- /dev/null
+++ b/standards/rfc2487.txt
@@ -0,0 +1,451 @@
+
+
+
+
+
+
+Network Working Group P. Hoffman
+Request for Comments: 2487 Internet Mail Consortium
+Category: Standards Track January 1999
+
+
+ SMTP Service Extension for Secure SMTP over TLS
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+1. Abstract
+
+ This document describes an extension to the SMTP service that allows
+ an SMTP server and client to use transport-layer security to provide
+ private, authenticated communication over the Internet. This gives
+ SMTP agents the ability to protect some or all of their
+ communications from eavesdroppers and attackers.
+
+2. Introduction
+
+ SMTP [RFC-821] servers and clients normally communicate in the clear
+ over the Internet. In many cases, this communication goes through one
+ or more router that is not controlled or trusted by either entity.
+ Such an untrusted router might allow a third party to monitor or
+ alter the communications between the server and client.
+
+ Further, there is often a desire for two SMTP agents to be able to
+ authenticate each others' identities. For example, a secure SMTP
+ server might only allow communications from other SMTP agents it
+ knows, or it might act differently for messages received from an
+ agent it knows than from one it doesn't know.
+
+ TLS [TLS], more commonly known as SSL, is a popular mechanism for
+ enhancing TCP communications with privacy and authentication. TLS is
+ in wide use with the HTTP protocol, and is also being used for adding
+ security to many other common protocols that run over TCP.
+
+
+
+
+
+
+Hoffman Standards Track [Page 1]
+
+RFC 2487 SMTP Service Extension January 1999
+
+
+2.1 Terminology
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in [RFC-2119].
+
+3. STARTTLS Extension
+
+ The STARTTLS extension to SMTP is laid out as follows:
+
+ (1) the name of the SMTP service defined here is STARTTLS;
+
+ (2) the EHLO keyword value associated with the extension is STARTTLS;
+
+ (3) the STARTTLS keyword has no parameters;
+
+ (4) a new SMTP verb, "STARTTLS", is defined;
+
+ (5) no additional parameters are added to any SMTP command.
+
+4. The STARTTLS Keyword
+
+ The STARTTLS keyword is used to tell the SMTP client that the SMTP
+ server allows use of TLS. It takes no parameters.
+
+5. The STARTTLS Command
+
+ The format for the STARTTLS command is:
+
+ STARTTLS
+
+ with no parameters.
+
+ After the client gives the STARTTLS command, the server responds with
+ one of the following reply codes:
+
+ 220 Ready to start TLS
+ 501 Syntax error (no parameters allowed)
+ 454 TLS not available due to temporary reason
+
+ A publicly-referenced SMTP server MUST NOT require use of the
+ STARTTLS extension in order to deliver mail locally. This rule
+ prevents the STARTTLS extension from damaging the interoperability of
+ the Internet's SMTP infrastructure. A publicly-referenced SMTP server
+ is an SMTP server which runs on port 25 of an Internet host listed in
+ the MX record (or A record if an MX record is not present) for the
+ domain name on the right hand side of an Internet mail address.
+
+
+
+
+Hoffman Standards Track [Page 2]
+
+RFC 2487 SMTP Service Extension January 1999
+
+
+ Any SMTP server may refuse to accept messages for relay based on
+ authentication supplied during the TLS negotiation. An SMTP server
+ that is not publicly referenced may refuse to accept any messages for
+ relay or local delivery based on authentication supplied during the
+ TLS negotiation.
+
+ A SMTP server that is not publicly referenced may choose to require
+ that the client perform a TLS negotiation before accepting any
+ commands. In this case, the server SHOULD return the reply code:
+
+ 530 Must issue a STARTTLS command first
+
+ to every command other than NOOP, EHLO, STARTTLS, or QUIT. If the
+ client and server are using the ENHANCEDSTATUSCODES ESMTP extension
+ [RFC-2034], the status code to be returned SHOULD be 5.7.0.
+
+ After receiving a 220 response to a STARTTLS command, the client
+ SHOULD start the TLS negotiation before giving any other SMTP
+ commands.
+
+ If the SMTP client is using pipelining as defined in RFC 1854, the
+ STARTTLS command must be the last command in a group.
+
+5.1 Processing After the STARTTLS Command
+
+ After the TLS handshake has been completed, both parties MUST
+ immediately decide whether or not to continue based on the
+ authentication and privacy achieved. The SMTP client and server may
+ decide to move ahead even if the TLS negotiation ended with no
+ authentication and/or no privacy because most SMTP services are
+ performed with no authentication and no privacy, but some SMTP
+ clients or servers may want to continue only if a particular level of
+ authentication and/or privacy was achieved.
+
+ If the SMTP client decides that the level of authentication or
+ privacy is not high enough for it to continue, it SHOULD issue an
+ SMTP QUIT command immediately after the TLS negotiation is complete.
+ If the SMTP server decides that the level of authentication or
+ privacy is not high enough for it to continue, it SHOULD reply to
+ every SMTP command from the client (other than a QUIT command) with
+ the 554 reply code (with a possible text string such as "Command
+ refused due to lack of security").
+
+ The decision of whether or not to believe the authenticity of the
+ other party in a TLS negotiation is a local matter. However, some
+ general rules for the decisions are:
+
+
+
+
+
+Hoffman Standards Track [Page 3]
+
+RFC 2487 SMTP Service Extension January 1999
+
+
+ - A SMTP client would probably only want to authenticate an SMTP
+ server whose server certificate has a domain name that is the
+ domain name that the client thought it was connecting to.
+ - A publicly-referenced SMTP server would probably want to accept
+ any certificate from an SMTP client, and would possibly want to
+ put distinguishing information about the certificate in the
+ Received header of messages that were relayed or submitted from
+ the client.
+
+5.2 Result of the STARTTLS Command
+
+ Upon completion of the TLS handshake, the SMTP protocol is reset to
+ the initial state (the state in SMTP after a server issues a 220
+ service ready greeting). The server MUST discard any knowledge
+ obtained from the client, such as the argument to the EHLO command,
+ which was not obtained from the TLS negotiation itself. The client
+ MUST discard any knowledge obtained from the server, such as the list
+ of SMTP service extensions, which was not obtained from the TLS
+ negotiation itself. The client SHOULD send an EHLO command as the
+ first command after a successful TLS negotiation.
+
+ The list of SMTP service extensions returned in response to an EHLO
+ command received after the TLS handshake MAY be different than the
+ list returned before the TLS handshake. For example, an SMTP server
+ might not want to advertise support for a particular SASL mechanism
+ [SASL] unless a client has sent an appropriate client certificate
+ during a TLS handshake.
+
+ Both the client and the server MUST know if there is a TLS session
+ active. A client MUST NOT attempt to start a TLS session if a TLS
+ session is already active. A server MUST NOT return the TLS extension
+ in response to an EHLO command received after a TLS handshake has
+ completed.
+
+6. Usage Example
+
+ The following dialog illustrates how a client and server can start a
+ TLS session:
+
+ S: <waits for connection on TCP port 25>
+ C: <opens connection>
+ S: 220 mail.imc.org SMTP service ready
+ C: EHLO mail.ietf.org
+ S: 250-mail.imc.org offers a warm hug of welcome
+ S: 250 STARTTLS
+ C: STARTTLS
+ S: 220 Go ahead
+ C: <starts TLS negotiation>
+
+
+
+Hoffman Standards Track [Page 4]
+
+RFC 2487 SMTP Service Extension January 1999
+
+
+ C & S: <negotiate a TLS session>
+ C & S: <check result of negotiation>
+ C: <continues by sending an SMTP command>
+ . . .
+
+7. Security Considerations
+
+ It should be noted that SMTP is not an end-to-end mechanism. Thus, if
+ an SMTP client/server pair decide to add TLS privacy, they are not
+ securing the transport from the originating mail user agent to the
+ recipient. Further, because delivery of a single piece of mail may
+ go between more than two SMTP servers, adding TLS privacy to one pair
+ of servers does not mean that the entire SMTP chain has been made
+ private. Further, just because an SMTP server can authenticate an
+ SMTP client, it does not mean that the mail from the SMTP client was
+ authenticated by the SMTP client when the client received it.
+
+ Both the STMP client and server must check the result of the TLS
+ negotiation to see whether acceptable authentication or privacy was
+ achieved. Ignoring this step completely invalidates using TLS for
+ security. The decision about whether acceptable authentication or
+ privacy was achieved is made locally, is implementation-dependant,
+ and is beyond the scope of this document.
+
+ The SMTP client and server should note carefully the result of the
+ TLS negotiation. If the negotiation results in no privacy, or if it
+ results in privacy using algorithms or key lengths that are deemed
+ not strong enough, or if the authentication is not good enough for
+ either party, the client may choose to end the SMTP session with an
+ immediate QUIT command, or the server may choose to not accept any
+ more SMTP commands.
+
+ A server announcing in an EHLO response that it uses a particular TLS
+ protocol should not pose any security issues, since any use of TLS
+ will be at least as secure as no use of TLS.
+
+ A man-in-the-middle attack can be launched by deleting the "250
+ STARTTLS" response from the server. This would cause the client not
+ to try to start a TLS session. An SMTP client can protect against
+ this attack by recording the fact that a particular SMTP server
+ offers TLS during one session and generating an alarm if it does not
+ appear in the EHLO response for a later session. The lack of TLS
+ during a session SHOULD NOT result in the bouncing of email, although
+ it could result in delayed processing.
+
+
+
+
+
+
+
+Hoffman Standards Track [Page 5]
+
+RFC 2487 SMTP Service Extension January 1999
+
+
+ Before the TLS handshake has begun, any protocol interactions are
+ performed in the clear and may be modified by an active attacker. For
+ this reason, clients and servers MUST discard any knowledge obtained
+ prior to the start of the TLS handshake upon completion of the TLS
+ handshake.
+
+ The STARTTLS extension is not suitable for authenticating the author
+ of an email message unless every hop in the delivery chain, including
+ the submission to the first SMTP server, is authenticated. Another
+ proposal [SMTP-AUTH] can be used to authenticate delivery and MIME
+ security multiparts [MIME-SEC] can be used to authenticate the author
+ of an email message. In addition, the [SMTP-AUTH] proposal offers
+ simpler and more flexible options to authenticate an SMTP client and
+ the SASL EXTERNAL mechanism [SASL] MAY be used in conjunction with
+ the STARTTLS command to provide an authorization identity.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hoffman Standards Track [Page 6]
+
+RFC 2487 SMTP Service Extension January 1999
+
+
+A. References
+
+ [RFC-821] Postel, J., "Simple Mail Transfer Protocol", RFC 821,
+ August 1982.
+
+ [RFC-1869] Klensin, J., Freed, N, Rose, M, Stefferud, E. and D.
+ Crocker, "SMTP Service Extensions", STD 10, RFC 1869,
+ November 1995.
+
+ [RFC-2034] Freed, N., "SMTP Service Extension for Returning Enhanced
+ Error Codes", RFC 2034, October 1996.
+
+ [RFC-2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [SASL] Myers, J., "Simple Authentication and Security Layer
+ (SASL)", RFC 2222, October 1997.
+
+ [SMTP-AUTH] "SMTP Service Extension for Authentication", Work in
+ Progress.
+
+ [TLS] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0",
+ RFC 2246, January 1999.
+
+B. Author's Address
+
+ Paul Hoffman
+ Internet Mail Consortium
+ 127 Segre Place
+ Santa Cruz, CA 95060
+
+ Phone: (831) 426-9827
+ EMail: phoffman@imc.org
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hoffman Standards Track [Page 7]
+
+RFC 2487 SMTP Service Extension January 1999
+
+
+C. Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hoffman Standards Track [Page 8]
+
diff --git a/standards/rfc2565.txt b/standards/rfc2565.txt
new file mode 100644
index 000000000..56511d478
--- /dev/null
+++ b/standards/rfc2565.txt
@@ -0,0 +1,2075 @@
+
+
+
+
+
+
+Network Working Group R. Herriot, Ed.
+Request for Comments: 2565 Xerox Corporation
+Category: Experimental S. Butler
+ Hewlett-Packard
+ P. Moore
+ Microsoft
+ R. Turner
+ Sharp Labs
+ April 1999
+
+
+ Internet Printing Protocol/1.0: Encoding and Transport
+
+Status of this Memo
+
+ This memo defines an Experimental Protocol for the Internet
+ community. It does not specify an Internet standard of any kind.
+ Discussion and suggestions for improvement are requested.
+ Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+IESG Note
+
+ This document defines an Experimental protocol for the Internet
+ community. The IESG expects that a revised version of this protocol
+ will be published as Proposed Standard protocol. The Proposed
+ Standard, when published, is expected to change from the protocol
+ defined in this memo. In particular, it is expected that the
+ standards-track version of the protocol will incorporate strong
+ authentication and privacy features, and that an "ipp:" URL type will
+ be defined which supports those security measures. Other changes to
+ the protocol are also possible. Implementors are warned that future
+ versions of this protocol may not interoperate with the version of
+ IPP defined in this document, or if they do interoperate, that some
+ protocol features may not be available.
+
+ The IESG encourages experimentation with this protocol, especially in
+ combination with Transport Layer Security (TLS) [RFC 2246], to help
+ determine how TLS may effectively be used as a security layer for
+ IPP.
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 1]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+Abstract
+
+ This document is one of a set of documents, which together describe
+ all aspects of a new Internet Printing Protocol (IPP). IPP is an
+ application level protocol that can be used for distributed printing
+ using Internet tools and technologies. This document defines the
+ rules for encoding IPP operations and IPP attributes into a new
+ Internet mime media type called "application/ipp". This document
+ also defines the rules for transporting over HTTP a message body
+ whose Content-Type is "application/ipp".
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.0: Model and Semantics [RFC2566]
+ Internet Printing Protocol/1.0: Encoding and Transport (this
+ document)
+ Internet Printing Protocol/1.0: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ The document, "Design Goals for an Internet Printing Protocol", takes
+ a broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. Operator and administrator requirements are
+ out of scope for version 1.0.
+
+ The document, "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specifications, and gives background and rationale for the
+ IETF working group's major decisions.
+
+ The document, "Internet Printing Protocol/1.0: Model and Semantics",
+ describes a simplified model with abstract objects, their attributes,
+ and their operations that are independent of encoding and transport.
+ It introduces a Printer and a Job object. The Job object optionally
+ supports multiple documents per Job. It also addresses security,
+ internationalization, and directory issues.
+
+ This document "Internet Printing Protocol/1.0: Implementer's Guide",
+ gives advice to implementers of IPP clients and IPP objects.
+
+
+
+
+
+Herriot, et al. Experimental [Page 2]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ The document "Mapping between LPD and IPP Protocols" gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+Table of Contents
+
+ 1. Introduction.....................................................4
+ 2. Conformance Terminology..........................................4
+ 3. Encoding of the Operation Layer.................................4
+ 3.1 Picture of the Encoding.....................................5
+ 3.2 Syntax of Encoding..........................................7
+ 3.3 Version-number..............................................9
+ 3.4 Operation-id................................................9
+ 3.5 Status-code.................................................9
+ 3.6 Request-id..................................................9
+ 3.7 Tags.......................................................10
+ 3.7.1 Delimiter Tags.........................................10
+ 3.7.2 Value Tags.............................................11
+ 3.8 Name-Length................................................13
+ 3.9 (Attribute) Name...........................................13
+ 3.10 Value Length...............................................16
+ 3.11 (Attribute) Value..........................................16
+ 3.12 Data.......................................................18
+ 4. Encoding of Transport Layer.....................................18
+ 5. Security Considerations.........................................19
+ 5.1 Using IPP with SSL3........................................19
+ 6. References......................................................20
+ 7. Authors' Addresses..............................................22
+ 8. Other Participants:.............................................24
+ 9. Appendix A: Protocol Examples...................................25
+ 9.1 Print-Job Request..........................................25
+ 9.2 Print-Job Response (successful)............................26
+ 9.3 Print-Job Response (failure)...............................27
+ 9.4 Print-Job Response (success with attributes ignored).......28
+ 9.5 Print-URI Request..........................................30
+ 9.6 Create-Job Request.........................................31
+ 9.7 Get-Jobs Request...........................................31
+ 9.8 Get-Jobs Response..........................................32
+ 10. Appendix C: Registration of MIME Media Type Information for
+ "application/ipp"..............................................35
+ 11. Full Copyright Statement.......................................37
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 3]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+1. Introduction
+
+ This document contains the rules for encoding IPP operations and
+ describes two layers: the transport layer and the operation layer.
+
+ The transport layer consists of an HTTP/1.1 request or response. RFC
+ 2068 [RFC2068] describes HTTP/1.1. This document specifies the HTTP
+ headers that an IPP implementation supports.
+
+ The operation layer consists of a message body in an HTTP request or
+ response. The document "Internet Printing Protocol/1.0: Model and
+ Semantics" [RFC2566] defines the semantics of such a message body and
+ the supported values. This document specifies the encoding of an IPP
+ operation. The aforementioned document [RFC2566] is henceforth
+ referred to as the "IPP model document"
+
+2. Conformance Terminology
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
+ "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
+ interpreted as described in RFC 2119 [RFC2119].
+
+3. Encoding of the Operation Layer
+
+ The operation layer MUST contain a single operation request or
+ operation response. Each request or response consists of a sequence
+ of values and attribute groups. Attribute groups consist of a
+ sequence of attributes each of which is a name and value. Names and
+ values are ultimately sequences of octets
+
+ The encoding consists of octets as the most primitive type. There are
+ several types built from octets, but three important types are
+ integers, character strings and octet strings, on which most other
+ data types are built. Every character string in this encoding MUST be
+ a sequence of characters where the characters are associated with
+ some charset and some natural language. A character string MUST be in
+ "reading order" with the first character in the value (according to
+ reading order) being the first character in the encoding. A character
+ string whose associated charset is US-ASCII whose associated natural
+ language is US English is henceforth called a US-ASCII-STRING. A
+ character string whose associated charset and natural language are
+ specified in a request or response as described in the model document
+ is henceforth called a LOCALIZED-STRING. An octet string MUST be in
+ "IPP model document order" with the first octet in the value
+ (according to the IPP model document order) being the first octet in
+ the encoding Every integer in this encoding MUST be encoded as a
+ signed integer using two's-complement binary encoding with big-endian
+ format (also known as "network order" and "most significant byte
+
+
+
+Herriot, et al. Experimental [Page 4]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ first"). The number of octets for an integer MUST be 1, 2 or 4,
+ depending on usage in the protocol. Such one-octet integers,
+ henceforth called SIGNED-BYTE, are used for the version-number and
+ tag fields. Such two-byte integers, henceforth called SIGNED-SHORT
+ are used for the operation-id, status-code and length fields. Four
+ byte integers, henceforth called SIGNED-INTEGER, are used for values
+ fields and the sequence number.
+
+ The following two sections present the operation layer in two ways
+
+ - informally through pictures and description
+ - formally through Augmented Backus-Naur Form (ABNF), as specified
+ by RFC 2234 [RFC2234]
+
+3.1 Picture of the Encoding
+
+ The encoding for an operation request or response consists of:
+
+ -----------------------------------------------
+ | version-number | 2 bytes - required
+ -----------------------------------------------
+ | operation-id (request) |
+ | or | 2 bytes - required
+ | status-code (response) |
+ -----------------------------------------------
+ | request-id | 4 bytes - required
+ -----------------------------------------------------------
+ | xxx-attributes-tag | 1 byte |
+ ----------------------------------------------- |-0 or more
+ | xxx-attribute-sequence | n bytes |
+ -----------------------------------------------------------
+ | end-of-attributes-tag | 1 byte - required
+ -----------------------------------------------
+ | data | q bytes - optional
+ -----------------------------------------------
+
+ The xxx-attributes-tag and xxx-attribute-sequence represents four
+ different values of "xxx", namely, operation, job, printer and
+ unsupported. The xxx-attributes-tag and an xxx-attribute-sequence
+ represent attribute groups in the model document. The xxx-
+ attributes-tag identifies the attribute group and the xxx-attribute-
+ sequence contains the attributes.
+
+ The expected sequence of xxx-attributes-tag and xxx-attribute-
+ sequence is specified in the IPP model document for each operation
+ request and operation response.
+
+
+
+
+
+Herriot, et al. Experimental [Page 5]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ A request or response SHOULD contain each xxx-attributes-tag defined
+ for that request or response even if there are no attributes except
+ for the unsupported-attributes-tag which SHOULD be present only if
+ the unsupported-attribute-sequence is non-empty. A receiver of a
+ request MUST be able to process as equivalent empty attribute groups:
+
+ a) an xxx-attributes-tag with an empty xxx-attribute-sequence,
+ b) an expected but missing xxx-attributes-tag.
+
+ The data is omitted from some operations, but the end-of-attributes-
+ tag is present even when the data is omitted. Note, the xxx-
+ attributes-tags and end-of-attributes-tag are called 'delimiter-
+ tags'. Note: the xxx-attribute-sequence, shown above may consist of 0
+ bytes, according to the rule below.
+
+ An xxx-attributes-sequence consists of zero or more compound-
+ attributes.
+
+ -----------------------------------------------
+ | compound-attribute | s bytes - 0 or more
+ -----------------------------------------------
+
+ A compound-attribute consists of an attribute with a single value
+ followed by zero or more additional values.
+
+ Note: a 'compound-attribute' represents a single attribute in the
+ model document. The 'additional value' syntax is for attributes with
+ 2 or more values.
+
+ Each attribute consists of:
+
+ -----------------------------------------------
+ | value-tag | 1 byte
+ -----------------------------------------------
+ | name-length (value is u) | 2 bytes
+ -----------------------------------------------
+ | name | u bytes
+ -----------------------------------------------
+ | value-length (value is v) | 2 bytes
+ -----------------------------------------------
+ | value | v bytes
+ -----------------------------------------------
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 6]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ An additional value consists of:
+
+ -----------------------------------------------------------
+ | value-tag | 1 byte |
+ ----------------------------------------------- |
+ | name-length (value is 0x0000) | 2 bytes |
+ ----------------------------------------------- |-0 or more
+ | value-length (value is w) | 2 bytes |
+ ----------------------------------------------- |
+ | value | w bytes |
+ -----------------------------------------------------------
+
+ Note: an additional value is like an attribute whose name-length is 0.
+
+ From the standpoint of a parsing loop, the encoding consists of:
+
+ -----------------------------------------------
+ | version-number | 2 bytes - required
+ -----------------------------------------------
+ | operation-id (request) |
+ | or | 2 bytes - required
+ | status-code (response) |
+ -----------------------------------------------
+ | request-id | 4 bytes - required
+ -----------------------------------------------------------
+ | tag (delimiter-tag or value-tag) | 1 byte |
+ ----------------------------------------------- |-0 or more
+ | empty or rest of attribute | x bytes |
+ -----------------------------------------------------------
+ | end-of-attributes-tag | 2 bytes - required
+ -----------------------------------------------
+ | data | y bytes - optional
+ -----------------------------------------------
+
+ The value of the tag determines whether the bytes following the
+ tag are:
+
+ - attributes
+ - data
+ - the remainder of a single attribute where the tag specifies the
+ type of the value.
+
+3.2 Syntax of Encoding
+
+ The syntax below is ABNF [RFC2234] except 'strings of literals' MUST
+ be case sensitive. For example 'a' means lower case 'a' and not
+ upper case 'A'. In addition, SIGNED-BYTE and SIGNED-SHORT fields
+ are represented as '%x' values which show their range of values.
+
+
+
+Herriot, et al. Experimental [Page 7]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ ipp-message = ipp-request / ipp-response
+ ipp-request = version-number operation-id request-id
+ *(xxx-attributes-tag xxx-attribute-sequence)
+ end-of-attributes-tag data
+ ipp-response = version-number status-code request-id
+ *(xxx-attributes-tag xxx-attribute-sequence)
+ end-of-attributes-tag data
+ xxx-attribute-sequence = *compound-attribute
+
+ xxx-attributes-tag = operation-attributes-tag / job-attributes-tag /
+ printer-attributes-tag / unsupported-attributes-tag
+
+ version-number = major-version-number minor-version-number
+ major-version-number = SIGNED-BYTE ; initially %d1
+ minor-version-number = SIGNED-BYTE ; initially %d0
+
+ operation-id = SIGNED-SHORT ; mapping from model defined below
+ status-code = SIGNED-SHORT ; mapping from model defined below
+ request-id = SIGNED-INTEGER ; whose value is > 0
+
+ compound-attribute = attribute *additional-values
+ attribute = value-tag name-length name value-length value
+ additional-values = value-tag zero-name-length value-length value
+
+ name-length = SIGNED-SHORT ; number of octets of 'name'
+ name = LALPHA *( LALPHA / DIGIT / "-" / "_" / "." )
+ value-length = SIGNED-SHORT ; number of octets of 'value'
+ value = OCTET-STRING
+
+ data = OCTET-STRING
+
+ zero-name-length = %x00.00 ; name-length of 0
+ operation-attributes-tag = %x01 ; tag of 1
+ job-attributes-tag = %x02 ; tag of 2
+ printer-attributes-tag = %x04 ; tag of 4
+ unsupported-attributes-tag = %x05 ; tag of 5
+ end-of-attributes-tag = %x03 ; tag of 3
+ value-tag = %x10-FF
+
+ SIGNED-BYTE = BYTE
+ SIGNED-SHORT = 2BYTE
+ SIGNED-INTEGER = 4BYTE
+ DIGIT = %x30-39 ; "0" to "9"
+ LALPHA = %x61-7A ; "a" to "z"
+ BYTE = %x00-FF
+ OCTET-STRING = *BYTE
+
+
+
+
+
+Herriot, et al. Experimental [Page 8]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ The syntax allows an xxx-attributes-tag to be present when the xxx-
+ attribute-sequence that follows is empty. The syntax is defined this
+ way to allow for the response of Get-Jobs where no attributes are
+ returned for some job-objects. Although it is RECOMMENDED that the
+ sender not send an xxx-attributes-tag if there are no attributes
+ (except in the Get-Jobs response just mentioned), the receiver MUST
+ be able to decode such syntax.
+
+3.3 Version-number
+
+ The version-number MUST consist of a major and minor version-number,
+ each of which MUST be represented by a SIGNED-BYTE. The protocol
+ described in this document MUST have a major version-number of 1
+ (0x01) and a minor version-number of 0 (0x00). The ABNF for these
+ two bytes MUST be %x01.00.
+
+3.4 Operation-id
+
+ Operation-ids are defined as enums in the model document. An
+ operation-ids enum value MUST be encoded as a SIGNED-SHORT.
+
+ Note: the values 0x4000 to 0xFFFF are reserved for private
+ extensions.
+
+3.5 Status-code
+
+ Status-codes are defined as enums in the model document. A status-
+ code enum value MUST be encoded as a SIGNED-SHORT.
+
+ The status-code is an operation attribute in the model document. In
+ the protocol, the status-code is in a special position, outside of
+ the operation attributes.
+
+ If an IPP status-code is returned, then the HTTP Status-Code MUST be
+ 200 (successful-ok). With any other HTTP Status-Code value, the HTTP
+ response MUST NOT contain an IPP message-body, and thus no IPP
+ status-code is returned.
+
+3.6 Request-id
+
+ The request-id allows a client to match a response with a request.
+ This mechanism is unnecessary in HTTP, but may be useful when
+ application/ipp entity bodies are used in another context.
+
+ The request-id in a response MUST be the value of the request-id
+ received in the corresponding request. A client can set the
+ request-id in each request to a unique value or a constant value,
+ such as 1, depending on what the client does with the request-id
+
+
+
+Herriot, et al. Experimental [Page 9]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ returned in the response. The value of the request-id MUST be greater
+ than zero.
+
+3.7 Tags
+
+ There are two kinds of tags:
+
+ - delimiter tags: delimit major sections of the protocol, namely
+ attributes and data
+ - value tags: specify the type of each attribute value
+
+3.7.1 Delimiter Tags
+
+ The following table specifies the values for the delimiter tags:
+
+ Tag Value (Hex) Delimiter
+
+ 0x00 reserved
+ 0x01 operation-attributes-tag
+ 0x02 job-attributes-tag
+ 0x03 end-of-attributes-tag
+ 0x04 printer-attributes-tag
+ 0x05 unsupported-attributes-tag
+ 0x06-0x0e reserved for future delimiters
+ 0x0F reserved for future chunking-end-of-attributes-
+ tag
+
+ When an xxx-attributes-tag occurs in the protocol, it MUST mean that
+ zero or more following attributes up to the next delimiter tag are
+ attributes belonging to group xxx as defined in the model document,
+ where xxx is operation, job, printer, unsupported.
+
+ Doing substitution for xxx in the above paragraph, this means the
+ following. When an operation-attributes-tag occurs in the protocol,
+ it MUST mean that the zero or more following attributes up to the
+ next delimiter tag are operation attributes as defined in the model
+ document. When an job-attributes-tag occurs in the protocol, it MUST
+ mean that the zero or more following attributes up to the next
+ delimiter tag are job attributes or job template attributes as
+ defined in the model document. When a printer-attributes-tag occurs
+ in the protocol, it MUST mean that the zero or more following
+ attributes up to the next delimiter tag are printer attributes as
+ defined in the model document. When an unsupported-attributes-tag
+ occurs in the protocol, it MUST mean that the zero or more following
+ attributes up to the next delimiter tag are unsupported attributes as
+ defined in the model document.
+
+
+
+
+
+Herriot, et al. Experimental [Page 10]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ The operation-attributes-tag and end-of-attributes-tag MUST each
+ occur exactly once in an operation. The operation-attributes-tag MUST
+ be the first tag delimiter, and the end-of-attributes-tag MUST be the
+ last tag delimiter. If the operation has a document-content group,
+ the document data in that group MUST follow the end-of-attributes-
+ tag.
+
+ Each of the other three xxx-attributes-tags defined above is
+ OPTIONAL in an operation and each MUST occur at most once in an
+ operation, except for job-attributes-tag in a Get-Jobs response which
+ may occur zero or more times.
+
+ The order and presence of delimiter tags for each operation request
+ and each operation response MUST be that defined in the model
+ document. For further details, see section 3.9 "(Attribute) Name" and
+ section 9 "Appendix A: Protocol Examples".
+
+ A Printer MUST treat the reserved delimiter tags differently from
+ reserved value tags so that the Printer knows that there is an entire
+ attribute group that it doesn't understand as opposed to a single
+ value that it doesn't understand.
+
+3.7.2 Value Tags
+
+ The remaining tables show values for the value-tag, which is the
+ first octet of an attribute. The value-tag specifies the type of the
+ value of the attribute. The following table specifies the "out-of-
+ band" values for the value-tag.
+
+ Tag Value (Hex) Meaning
+
+ 0x10 unsupported
+ 0x11 reserved for future 'default'
+ 0x12 unknown
+ 0x13 no-value
+
+ Tag Value (Hex) Meaning
+
+ 0x14-0x1F reserved for future "out-of-band" values.
+
+ The "unsupported" value MUST be used in the attribute-sequence of an
+ error response for those attributes which the printer does not
+ support. The "default" value is reserved for future use of setting
+ value back to their default value. The "unknown" value is used for
+ the value of a supported attribute when its value is temporarily
+ unknown. The "no-value" value is used for a supported attribute to
+ which
+
+
+
+
+Herriot, et al. Experimental [Page 11]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ no value has been assigned, e.g. "job-k-octets-supported" has no
+ value if an implementation supports this attribute, but an
+ administrator has not configured the printer to have a limit.
+
+ The following table specifies the integer values for the value-tag:
+
+ Tag Value (Hex) Meaning
+
+ 0x20 reserved
+ 0x21 integer
+ 0x22 boolean
+ 0x23 enum
+ 0x24-0x2F reserved for future integer types
+
+ NOTE: 0x20 is reserved for "generic integer" if it should ever be
+ needed.
+
+ The following table specifies the octetString values for the value-
+ tag:
+
+ Tag Value (Hex) Meaning
+
+ 0x30 octetString with an unspecified format
+ 0x31 dateTime
+ 0x32 resolution
+ 0x33 rangeOfInteger
+ 0x34 reserved for collection (in the future)
+ 0x35 textWithLanguage
+ 0x36 nameWithLanguage
+ 0x37-0x3F reserved for future octetString types
+
+ The following table specifies the character-string values for the
+ value-tag:
+
+ Tag Value (Hex) Meaning
+
+ 0x40 reserved
+ 0x41 textWithoutLanguage
+ 0x42 nameWithoutLanguage
+ 0x43 reserved
+ 0x44 keyword
+ 0x45 uri
+ 0x46 uriScheme
+ 0x47 charset
+ 0x48 naturalLanguage
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 12]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ Tag Value (Hex) Meaning
+
+ 0x49 mimeMediaType
+ 0x4A-0x5F reserved for future character string types
+
+ NOTE: 0x40 is reserved for "generic character-string" if it should
+ ever be needed.
+
+ NOTE: an attribute value always has a type, which is explicitly
+ specified by its tag; one such tag value is "nameWithoutLanguage".
+ An attribute's name has an implicit type, which is keyword.
+
+ The values 0x60-0xFF are reserved for future types. There are no
+ values allocated for private extensions. A new type MUST be
+ registered via the type 2 registration process [RFC2566].
+
+ The tag 0x7F is reserved for extending types beyond the 255 values
+ available with a single byte. A tag value of 0x7F MUST signify that
+ the first 4 bytes of the value field are interpreted as the tag
+ value. Note, this future extension doesn't affect parsers that are
+ unaware of this special tag. The tag is like any other unknown tag,
+ and the value length specifies the length of a value which contains a
+ value that the parser treats atomically. All these 4 byte tag values
+ are currently unallocated except that the values 0x40000000-
+ 0x7FFFFFFF are reserved for experimental use.
+
+3.8 Name-Length
+
+ The name-length field MUST consist of a SIGNED-SHORT. This field MUST
+ specify the number of octets in the name field which follows the
+ name-length field, excluding the two bytes of the name-length field.
+
+ If a name-length field has a value of zero, the following name field
+ MUST be empty, and the following value MUST be treated as an
+ additional value for the preceding attribute. Within an attribute-
+ sequence, if two attributes have the same name, the first occurrence
+ MUST be ignored. The zero-length name is the only mechanism for
+ multi-valued attributes.
+
+3.9 (Attribute) Name
+
+ Some operation elements are called parameters in the model document
+ [RFC2566]. They MUST be encoded in a special position and they MUST
+ NOT appear as an operation attributes. These parameters are:
+
+ - "version-number": The parameter named "version-number" in the
+ IPP model document MUST become the "version-number" field in the
+ operation layer request or response.
+
+
+
+Herriot, et al. Experimental [Page 13]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ - "operation-id": The parameter named "operation-id" in the IPP
+ model document MUST become the "operation-id" field in the
+ operation layer request.
+ - "status-code": The parameter named "status-code" in the IPP
+ model document MUST become the "status-code" field in the
+ operation layer response.
+ - "request-id": The parameter named "request-id" in the IPP model
+ document MUST become the "request-id" field in the operation
+ layer request or response.
+
+ All Printer and Job objects are identified by a Uniform Resource
+ Identifier (URI) [RFC2396] so that they can be persistently and
+ unambiguously referenced. The notion of a URI is a useful concept,
+ however, until the notion of URI is more stable (i.e., defined more
+ completely and deployed more widely), it is expected that the URIs
+ used for IPP objects will actually be URLs [RFC1738] [RFC1808].
+ Since every URL is a specialized form of a URI, even though the more
+ generic term URI is used throughout the rest of this document, its
+ usage is intended to cover the more specific notion of URL as well.
+
+ Some operation elements are encoded twice, once as the request-URI on
+ the HTTP Request-Line and a second time as a REQUIRED operation
+ attribute in the application/ipp entity. These attributes are the
+ target URI for the operation:
+
+ - "printer-uri": When the target is a printer and the transport is
+ HTTP or HTTPS (for SSL3 [ssl]), the target printer-uri defined
+ in each operation in the IPP model document MUST be an operation
+ attribute called "printer-uri" and it MUST also be specified
+ outside of the operation layer as the request-URI on the
+ Request-Line at the HTTP level.
+ - "job-uri": When the target is a job and the transport is HTTP or
+ HTTPS (for SSL3), the target job-uri of each operation in the
+ IPP model document MUST be an operation attribute called "job-
+ uri" and it MUST also be specified outside of the operation
+ layer as the request-URI on the Request-Line at the HTTP level.
+
+ Note: The target URI is included twice in an operation referencing
+ the same IPP object, but the two URIs NEED NOT be literally
+ identical. One can be a relative URI and the other can be an absolute
+ URI. HTTP/1.1 allows clients to generate and send a relative URI
+ rather than an absolute URI. A relative URI identifies a resource
+ with the scope of the HTTP server, but does not include scheme, host
+ or port. The following statements characterize how URLs should be
+ used in the mapping of IPP onto HTTP/1.1:
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 14]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ 1. Although potentially redundant, a client MUST supply the target
+ of the operation both as an operation attribute and as a URI at
+ the HTTP layer. The rationale for this decision is to maintain
+ a consistent set of rules for mapping application/ipp to
+ possibly many communication layers, even where URLs are not
+ used as the addressing mechanism in the transport layer.
+ 2. Even though these two URLs might not be literally identical
+ (one being relative and the other being absolute), they MUST
+ both reference the same IPP object.
+ 3. The URI in the HTTP layer is either relative or absolute and is
+ used by the HTTP server to route the HTTP request to the
+ correct resource relative to that HTTP server. The HTTP server
+ need not be aware of the URI within the operation request.
+ 4. Once the HTTP server resource begins to process the HTTP
+ request, it might get the reference to the appropriate IPP
+ Printer object from either the HTTP URI (using to the context
+ of the HTTP server for relative URLs) or from the URI within
+ the operation request; the choice is up to the implementation.
+ 5. HTTP URIs can be relative or absolute, but the target URI in
+ the operation MUST be an absolute URI.
+
+ The model document arranges the remaining attributes into groups for
+ each operation request and response. Each such group MUST be
+ represented in the protocol by an xxx-attribute-sequence preceded by
+ the appropriate xxx-attributes-tag (See the table below and section 9
+ "Appendix A: Protocol Examples"). In addition, the order of these
+ xxx-attributes-tags and xxx-attribute-sequences in the protocol MUST
+ be the same as in the model document, but the order of attributes
+ within each xxx-attribute-sequence MUST be unspecified. The table
+ below maps the model document group name to xxx-attributes-sequence:
+
+ Model Document Group xxx-attributes-sequence
+
+ Operation Attributes operations-attributes-sequence
+ Job Template Attributes job-attributes-sequence
+ Job Object Attributes job-attributes-sequence
+ Unsupported Attributes unsupported-attributes-sequence
+ Requested Attributes job-attributes-sequence
+ Get-Job-Attributes)
+ Requested Attributes printer-attributes-sequence
+ Get-Printer-Attributes)
+ Document Content in a special position as described
+ above
+
+ If an operation contains attributes from more than one job object
+ (e.g. Get-Jobs response), the attributes from each job object MUST
+ be in a separate job-attribute-sequence, such that the attributes
+
+
+
+
+Herriot, et al. Experimental [Page 15]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ from the ith job object are in the ith job-attribute-sequence. See
+ Section 9 "Appendix A: Protocol Examples" for table showing the
+ application of the rules above.
+
+3.10 Value Length
+
+ Each attribute value MUST be preceded by a SIGNED-SHORT, which MUST
+ specify the number of octets in the value which follows this length,
+ exclusive of the two bytes specifying the length.
+
+ For any of the types represented by binary signed integers, the
+ sender MUST encode the value in exactly four octets.
+
+ For any of the types represented by character-strings, the sender
+ MUST encode the value with all the characters of the string and
+ without any padding characters.
+
+ If a value-tag contains an "out-of-band" value, such as
+ "unsupported", the value-length MUST be 0 and the value empty. The
+ value has no meaning when the value-tag has an "out-of-band" value.
+ If a client receives a response with a nonzero value-length in this
+ case, it MUST ignore the value field. If a printer receives a request
+ with a nonzero value-length in this case, it MUST reject the request.
+
+3.11 (Attribute) Value
+
+ The syntax types and most of the details of their representation are
+ defined in the IPP model document. The table below augments the
+ information in the model document, and defines the syntax types from
+ the model document in terms of the 5 basic types defined in section 3
+ "Encoding of the Operation Layer". The 5 types are US-ASCII-STRING,
+ LOCALIZED-STRING, SIGNED-INTEGER, SIGNED-SHORT, SIGNED-BYTE, and
+ OCTET-STRING.
+
+Syntax of Attribute Encoding
+Value
+
+textWithoutLanguage, LOCALIZED-STRING.
+nameWithoutLanguage
+
+textWithLanguage OCTET_STRING consisting of 4 fields:
+ a) a SIGNED-SHORT which is the number of octets
+ in the following field
+ b) a value of type natural-language,
+ c) a SIGNED-SHORT which is the number of octets
+ in the following field,
+ d) a value of type textWithoutLanguage.
+
+
+
+
+Herriot, et al. Experimental [Page 16]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ The length of a textWithLanguage value MUST be 4
+ + the value of field a + the value of field c.
+
+nameWithLanguage OCTET_STRING consisting of 4 fields:
+ a) a SIGNED-SHORT which is the number of octets
+ in the following field
+ b) a value of type natural-language,
+ c) a SIGNED-SHORT which is the number of octets
+ in the following field
+ d) a value of type nameWithoutLanguage.
+
+ The length of a nameWithLanguage value MUST be 4
+ + the value of field a + the value of field c.
+
+charset, US-ASCII-STRING.
+naturalLanguage,
+mimeMediaType,
+keyword, uri, and
+uriScheme
+
+boolean SIGNED-BYTE where 0x00 is 'false' and 0x01 is
+ 'true'.
+
+Syntax of Attribute Encoding
+Value
+
+
+integer and enum a SIGNED-INTEGER.
+
+dateTime OCTET-STRING consisting of eleven octets whose
+ contents are defined by "DateAndTime" in RFC
+ 2579 [RFC2579].
+
+resolution OCTET_STRING consisting of nine octets of 2
+ SIGNED-INTEGERs followed by a SIGNED-BYTE. The
+ first SIGNED-INTEGER contains the value of cross
+ feed direction resolution. The second SIGNED-
+ INTEGER contains the value of feed direction
+ resolution. The SIGNED-BYTE contains the units
+ value.
+
+rangeOfInteger Eight octets consisting of 2 SIGNED-INTEGERs.
+ The first SIGNED-INTEGER contains the lower
+ bound and the second SIGNED-INTEGER contains the
+ upper bound.
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 17]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+1setOf X Encoding according to the rules for an attribute
+ with more than 1 value. Each value X is encoded
+ according to the rules for encoding its type.
+
+octetString OCTET-STRING
+
+ The type of the value in the model document determines the encoding
+ in the value and the value of the value-tag.
+
+3.12 Data
+
+ The data part MUST include any data required by the operation
+
+4. Encoding of Transport Layer
+
+ HTTP/1.1 [RFC2068] is the transport layer for this protocol.
+
+ The operation layer has been designed with the assumption that the
+ transport layer contains the following information:
+
+ - the URI of the target job or printer operation
+ - the total length of the data in the operation layer, either as a
+ single length or as a sequence of chunks each with a length.
+
+ It is REQUIRED that a printer implementation support HTTP over the
+ IANA assigned Well Known Port 631 (the IPP default port), though a
+ printer implementation may support HTTP over some other port as well.
+ In addition, a printer may have to support another port for privacy
+ (See Section 5 "Security Considerations").
+
+ Note: even though port 631 is the IPP default, port 80 remains the
+ default for an HTTP URI. Thus a URI for a printer using port 631
+ MUST contain an explicit port, e.g. "http://forest:631/pinetree". An
+ HTTP URI for IPP with no explicit port implicitly reference port 80,
+ which is consistent with the rules for HTTP/1.1. Each HTTP operation
+ MUST use the POST method where the request-URI is the object target
+ of the operation, and where the "Content-Type" of the message-body in
+ each request and response MUST be "application/ipp". The message-body
+ MUST contain the operation layer and MUST have the syntax described
+ in section 3.2 "Syntax of Encoding". A client implementation MUST
+ adhere to the rules for a client described for HTTP1.1 [RFC2068]. A
+ printer (server) implementation MUST adhere the rules for an origin
+ server described for HTTP1.1 [RFC2068].
+
+ An IPP server sends a response for each request that it receives. If
+ an IPP server detects an error, it MAY send a response before it has
+ read the entire request. If the HTTP layer of the IPP server
+ completes processing the HTTP headers successfully, it MAY send an
+
+
+
+Herriot, et al. Experimental [Page 18]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ intermediate response, such as "100 Continue", with no IPP data
+ before sending the IPP response. A client MUST expect such a variety
+ of responses from an IPP server. For further information on HTTP/1.1,
+ consult the HTTP documents [RFC2068].
+
+5. Security Considerations
+
+ The IPP Model document defines an IPP implementation with "privacy"
+ as one that implements Secure Socket Layer Version 3 (SSL3). Note:
+ SSL3 is not an IETF standards track specification. SSL3 meets the
+ requirements for IPP security with regards to features such as mutual
+ authentication and privacy (via encryption). The IPP Model document
+ also outlines IPP-specific security considerations and should be the
+ primary reference for security implications with regards to the IPP
+ protocol itself.
+
+ The IPP Model document defines an IPP implementation with
+ "authentication" as one that implements the standard way for
+ transporting IPP messages within HTTP 1.1. These include the security
+ considerations outlined in the HTTP 1.1 standard document [RFC2068]
+ and Digest Access Authentication extension [RFC2069].
+
+ The current HTTP infrastructure supports HTTP over TCP port 80. IPP
+ server implementations MUST offer IPP services using HTTP over the
+ IANA assigned Well Known Port 631 (the IPP default port). IPP server
+ implementations may support other ports, in addition to this port.
+
+ See further discussion of IPP security concepts in the model document
+ [RFC2566].
+
+5.1 Using IPP with SSL3
+
+ An assumption is that the URI for a secure IPP Printer object has
+ been found by means outside the IPP printing protocol, via a
+ directory service, web site or other means.
+
+ IPP provides a transparent connection to SSL by calling the
+ corresponding URL (a https URI connects by default to port 443).
+ However, the following functions can be provided to ease the
+ integration of IPP with SSL during implementation:
+
+ connect (URI), returns a status
+
+ "connect" makes an https call and returns the immediate status
+ of the connection as returned by SSL to the user. The status
+ values are explained in section 5.4.2 of the SSL document
+ [ssl].
+
+
+
+
+Herriot, et al. Experimental [Page 19]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ A session-id may also be retained to later resume a session.
+ The SSL handshake protocol may also require the cipher
+ specifications supported by the client, key length of the
+ ciphers, compression methods, certificates, etc. These should
+ be sent to the server and hence should be available to the IPP
+ client (although as part of administration features).
+
+ disconnect (session)
+
+ to disconnect a particular session.
+
+ The session-id available from the "connect" could be used.
+
+ resume (session)
+
+ to reconnect using a previous session-id.
+
+ The availability of this information as administration features are
+ left for implementers, and need not be specified at this time.
+
+6. References
+
+ [RFC2278] Freed, N. and J. Postel, "IANA Charset Registration
+ Procedures", BCP 19, RFC 2278, January 1998.
+
+ [dpa] ISO/IEC 10175 Document Printing Application (DPA), June
+ 1996.
+
+ [iana] IANA Registry of Coded Character Sets:
+ ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets.
+
+ [ipp-iig] Hastings, Tom, et al., "Internet Printing Protocol/1.0:
+ Implementer's Guide", Work in Progress.
+
+ [RFC2569] Herriot, R., Hastings, T., Jacobs, N. and J. Martin,
+ "Mapping between LPD and IPP Protocols", RFC 2569, April
+ 1999.
+
+ [RFC2566] deBry, R., Hastings, T., Herriot, R., Isaacson, S. and P.
+ Powell, "Internet Printing Protocol/1.0: Model and
+ Semantics", RFC 2566, April 1999.
+
+ [RFC2565] Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet
+ Printing Protocol/1.0: Encoding and Transport", RFC 2565,
+ April 1999.
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 20]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ [RFC2568] Zilles, S., "Rationale for the Structure and Model and
+ Protocol for the Internet Printing Protocol", RFC 2568,
+ April 1999.
+
+ [RFC2567] Wright, D., "Design Goals for an Internet Printing
+ Protocol", RFC 2567, April 1999.
+
+ [RFC822] Crocker, D., "Standard for the Format of ARPA Internet Text
+ Messages", STD 11, RFC 822, August 1982.
+
+ [RFC1123] Braden, R., "Requirements for Internet Hosts - Application
+ and Support", STD 3, RFC 1123, October 1989.
+
+ [RFC1179] McLaughlin, L. III, (editor), "Line Printer Daemon
+ Protocol" RFC 1179, August 1990.
+
+ [RFC2223] Postel, J. and J. Reynolds, "Instructions to RFC Authors",
+ RFC 2223, October 1997.
+
+ [RFC1738] Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform
+ Resource Locators (URL)", RFC 1738, December 1994.
+
+ [RFC1759] Smith, R., Wright, F., Hastings, T., Zilles, S. and J.
+ Gyllenskog, "Printer MIB", RFC 1759, March 1995.
+
+ [RFC1766] Alvestrand, H., " Tags for the Identification of
+ Languages", RFC 1766, March 1995.
+
+ [RFC1808] Fielding, R., "Relative Uniform Resource Locators", RFC
+ 1808, June 1995.
+
+ [RFC2579] McCloghrie, K., Perkins, D. and J. Schoenwaelder, "Textual
+ Conventions for SMIv2", STD 58, RFC 2579, April 1999.
+
+ [RFC2046] Freed, N. and N. Borenstein, Multipurpose Internet Mail
+ Extensions (MIME) Part Two: Media Types", RFC 2046,
+ November 1996.
+
+ [RFC2048] Freed, N., Klensin J. and J. Postel. Multipurpose Internet
+ Mail Extension (MIME) Part Four: Registration Procedures",
+ BCP 13, RFC 2048, November 1996.
+
+ [RFC2068] Fielding, R., Gettys, J., Mogul, J., Frystyk, H. and T.
+ Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC
+ 2068, January 1997.
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 21]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ [RFC2069] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P.,
+ Luotonen, A., Sink, E. and L. Stewart, "An Extension to
+ HTTP: Digest Access Authentication", RFC 2069, January
+ 1997.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2184] Freed, N. and K. Moore, "MIME Parameter Value and Encoded
+ Word Extensions: Character Sets, Languages, and
+ Continuations", RFC 2184, August 1997.
+
+ [RFC2234] Crocker, D. and P. Overell, "Augmented BNF for Syntax
+ Specifications: ABNF", RFC 2234. November 1997.
+
+ [RFC2396] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform
+ Resource Identifiers (URI): Generic Syntax", RFC 2396,
+ August 1998.
+
+7. Authors' Addresses
+
+ Robert Herriot (Editor)
+ Xerox Corporation
+ 3400 Hillview Ave., Bldg #1
+ Palo Alto, CA 94304
+
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ EMail: rherriot@pahv.xerox.com
+
+
+ Sylvan Butler
+ Hewlett-Packard
+ 11311 Chinden Blvd.
+ Boise, ID 83714
+
+ Phone: 208-396-6000
+ Fax: 208-396-3457
+ EMail: sbutler@boi.hp.com
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 22]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ Paul Moore
+ Microsoft
+ One Microsoft Way
+ Redmond, WA 98053
+
+ Phone: 425-936-0908
+ Fax: 425-93MS-FAX
+ EMail: paulmo@microsoft.com
+
+
+ Randy Turner
+ Sharp Laboratories
+ 5750 NW Pacific Rim Blvd
+ Camas, WA 98607
+
+ Phone: 360-817-8456
+ Fax: 360-817-8436
+ EMail: rturner@sharplabs.com
+
+
+ IPP Mailing List: ipp@pwg.org
+ IPP Mailing List Subscription: ipp-request@pwg.org
+ IPP Web Page: http://www.pwg.org/ipp/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 23]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+8. Other Participants:
+
+ Chuck Adams - Tektronix Harry Lewis - IBM
+ Ron Bergman - Dataproducts Tony Liao - Vivid Image
+ Keith Carter - IBM David Manchala - Xerox
+ Angelo Caruso - Xerox Carl-Uno Manros - Xerox
+ Jeff Copeland - QMS Jay Martin - Underscore
+ Roger deBry - IBM Larry Masinter - Xerox
+ Lee Farrell - Canon Ira McDonald - High North Inc.
+ Sue Gleeson - Digital Bob Pentecost - Hewlett-Packard
+ Charles Gordon - Osicom Patrick Powell - Astart
+ Technologies
+ Brian Grimshaw - Apple Jeff Rackowitz - Intermec
+ Jerry Hadsell - IBM Xavier Riley - Xerox
+ Richard Hart - Digital Gary Roberts - Ricoh
+ Tom Hastings - Xerox Stuart Rowley - Kyocera
+ Stephen Holmstead Richard Schneider - Epson
+ Zhi-Hong Huang - Zenographics Shigern Ueda - Canon
+ Scott Isaacson - Novell Bob Von Andel - Allegro Software
+ Rich Lomicka - Digital William Wagner - Digital Products
+ David Kellerman - Northlake Jasper Wong - Xionics
+ Software
+ Robert Kline - TrueSpectra Don Wright - Lexmark
+ Dave Kuntz - Hewlett-Packard Rick Yardumian - Xerox
+ Takami Kurono - Brother Lloyd Young - Lexmark
+ Rich Landau - Digital Peter Zehler - Xerox
+ Greg LeClair - Epson Frank Zhao - Panasonic
+ Steve Zilles - Adobe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 24]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+9. Appendix A: Protocol Examples
+
+9.1 Print-Job Request
+
+ The following is an example of a Print-Job request with job-name,
+ copies, and sides specified. The "ipp-attribute-fidelity" attribute
+ is set to 'true' so that the print request will fail if the "copies"
+ or the "sides" attribute are not supported or their values are not
+ supported.
+
+ Octets Symbolic Value Protocol field
+
+ 0x0100 1.0 version-number
+ 0x0002 Print-Job operation-id
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural-language name
+ natural-
+ language
+ 0x0005 value-length
+ en-us en-US value
+ 0x45 uri type value-tag
+ 0x000B name-length
+ printer-uri printer-uri name
+ 0x001A value-length
+ http://forest: printer pinetree value
+ 631/pinetree
+ 0x42 nameWithoutLanguage type value-tag
+ 0x0008 name-length
+ job-name job-name name
+ 0x0006 value-length
+ foobar foobar value
+ 0x22 boolean type value-tag
+ 0x16 name-length
+ ipp-attribute- ipp-attribute-fidelity name
+ fidelity
+ 0x01 value-length
+ 0x01 true value
+ 0x02 start job-attributes job-attributes-tag
+ 0x21 integer type value-tag
+
+
+
+Herriot, et al. Experimental [Page 25]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ 0x0006 name-length
+ copies copies name
+ 0x0004 value-length
+ 0x00000014 20 value
+ 0x44 keyword type value-tag
+ 0x0005 name-length
+ sides sides name
+ 0x0013 value-length
+ two-sided- two-sided-long-edge value
+ long-edge
+ 0x03 end-of-attributes end-of-attributes-tag
+ %!PS... <PostScript> data
+
+9.2 Print-Job Response (successful)
+
+ Here is an example of a successful Print-Job response to the previous
+ Print-Job request. The printer supported the "copies" and "sides"
+ attributes and their supplied values. The status code returned is '
+ successful-ok'.
+
+ Octets Symbolic Value Protocol field
+
+ 0x0100 1.0 version-number
+ 0x0000 successful-ok status-code
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural- name
+ natural-language language
+ 0x0005 value-length
+ en-us en-US value
+ 0x41 textWithoutLanguage type value-tag
+ 0x000E name-length
+ status-message status-message name
+ 0x000D value-length
+ successful-ok successful-ok value
+ 0x02 start job-attributes job-attributes-tag
+ 0x21 integer value-tag
+ 0x0006 name-length
+
+
+
+
+
+Herriot, et al. Experimental [Page 26]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ Octets Symbolic Value Protocol field
+
+ job-id job-id name
+ 0x0004 value-length
+ 147 147 value
+ 0x45 uri type value-tag
+ 0x0007 name-length
+ job-uri job-uri name
+ 0x001E value-length
+ http://forest:63 job 123 on pinetree value
+ 1/pinetree/123
+ 0x42 nameWithoutLanguage type value-tag
+ 0x0009 name-length
+ job-state job-state name
+ 0x0004 value-length
+ 0x0003 pending value
+ 0x03 end-of-attributes end-of-attributes-tag
+
+9.3 Print-Job Response (failure)
+
+ Here is an example of an unsuccessful Print-Job response to the
+ previous Print-Job request. It fails because, in this case, the
+ printer does not support the "sides" attribute and because the value
+ '20' for the "copies" attribute is not supported. Therefore, no job
+ is created, and neither a "job-id" nor a "job-uri" operation
+ attribute is returned. The error code returned is 'client-error-
+ attributes-or-values-not-supported' (0x040B).
+
+ Octets Symbolic Value Protocol field
+
+ 0x0100 1.0 version-number
+ 0x040B client-error-attributes-or- status-code
+ values-not-supported
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attribute tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural-language name
+ natural-
+ language
+ 0x0005 value-length
+
+
+
+
+Herriot, et al. Experimental [Page 27]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ Octets Symbolic Value Protocol field
+
+ en-us en-US value
+ 0x41 textWithoutLanguage type value-tag
+ 0x000E name-length
+ status- status-message name
+ message
+ 0x002F value-length
+ client-error- client-error-attributes-or- value
+ attributes- values-not-supported
+ or-values-
+ not-supported
+ 0x05 start unsupported-attributes unsupported-attributes tag
+ 0x21 integer type value-tag
+ 0x0006 name-length
+ copies copies name
+ 0x0004 value-length
+ 0x00000014 20 value
+ 0x10 unsupported (type) value-tag
+ 0x0005 name-length
+ sides sides name
+ 0x0000 value-length
+ 0x03 end-of-attributes end-of-attributes-tag
+
+9.4 Print-Job Response (success with attributes ignored)
+
+ Here is an example of a successful Print-Job response to a Print-Job
+ request like the previous Print-Job request, except that the value of
+ 'ipp-attribute-fidelity' is false. The print request succeeds, even
+ though, in this case, the printer supports neither the "sides"
+ attribute nor the value '20' for the "copies" attribute. Therefore, a
+ job is created, and both a "job-id" and a "job-uri" operation
+ attribute are returned. The unsupported attributes are also returned
+ in an Unsupported Attributes Group. The error code returned is '
+ successful-ok-ignored-or-substituted-attributes' (0x0001).
+
+ Octets Symbolic Value Protocol field
+
+ 0x0100 1.0 version-number
+ 0x0001 successful-ok-ignored-or- status-code
+ substituted-attributes
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+
+
+
+Herriot, et al. Experimental [Page 28]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ Octets Symbolic Value Protocol field
+
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural- name
+ natural-language language
+ 0x0005 value-length
+ en-us en-US value
+ 0x41 textWithoutLanguage type value-tag
+ 0x000E name-length
+ status-message status-message name
+ 0x002F value-length
+ successful-ok- successful-ok-ignored-or- value
+ ignored-or- substituted-attributes
+ substituted-
+ attributes
+ 0x05 start unsupported- unsupported-attributes
+ attributes tag
+ 0x21 integer type value-tag
+ 0x0006 name-length
+ copies copies name
+ 0x0004 value-length
+ 0x00000014 20 value
+ 0x10 unsupported (type) value-tag
+ 0x0005 name-length
+ sides sides name
+ 0x0000 value-length
+ 0x02 start job-attributes job-attributes-tag
+ 0x21 integer value-tag
+ 0x0006 name-length
+ job-id job-id name
+ 0x0004 value-length
+ 147 147 value
+ 0x45 uri type value-tag
+ 0x0007 name-length
+ job-uri job-uri name
+ 0x001E value-length
+ http://forest:63 job 123 on pinetree value
+ 1/pinetree/123
+ 0x42 nameWithoutLanguage type value-tag
+ 0x0009 name-length
+ job-state job-state name
+ 0x0004 value-length
+ 0x0003 pending value
+ 0x03 end-of-attributes end-of-attributes-tag
+
+
+
+
+
+Herriot, et al. Experimental [Page 29]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+9.5 Print-URI Request
+
+ The following is an example of Print-URI request with copies and
+ job-name parameters:
+
+ Octets Symbolic Value Protocol field
+
+ 0x0100 1.0 version-number
+
+ Octets Symbolic Value Protocol field
+ 0x0003 Print-URI operation-id
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural-language name
+ natural-
+ language
+ 0x0005 value-length
+ en-us en-US value
+ 0x45 uri type value-tag
+ 0x000B name-length
+ printer-uri printer-uri name
+ 0x001A value-length
+ http://forest printer pinetree value
+ :631/pinetree
+ 0x45 uri type value-tag
+ 0x000C name-length
+ document-uri document-uri name
+ 0x11 value-length
+ ftp://foo.com ftp://foo.com/foo value
+ /foo
+ 0x42 nameWithoutLanguage type value-tag
+ 0x0008 name-length
+ job-name job-name name
+ 0x0006 value-length
+ foobar foobar value
+ 0x02 start job-attributes job-attributes-tag
+ 0x21 integer type value-tag
+ 0x0006 name-length
+ copies copies name
+ 0x0004 value-length
+
+
+
+Herriot, et al. Experimental [Page 30]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ 0x00000001 1 value
+ 0x03 end-of-attributes end-of-attributes-tag
+
+9.6 Create-Job Request
+
+ The following is an example of Create-Job request with no parameters
+ and no attributes:
+
+ Octets Symbolic Value Protocol field
+ 0x0100 1.0 version-number
+ 0x0005 Create-Job operation-id
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+
+ Octets Symbolic Value Protocol field
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural-language name
+ natural-
+ language
+ 0x0005 value-length
+ en-us en-US value
+ 0x45 uri type value-tag
+ 0x000B name-length
+ printer-uri printer-uri name
+ 0x001A value-length
+ http://forest: printer pinetree value
+ 631/pinetree
+ 0x03 end-of-attributes end-of-attributes-tag
+
+9.7 Get-Jobs Request
+
+ The following is an example of Get-Jobs request with parameters but
+ no attributes:
+
+ Octets Symbolic Value Protocol field
+
+ 0x0100 1.0 version-number
+ 0x000A Get-Jobs operation-id
+ 0x00000123 0x123 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+
+
+
+Herriot, et al. Experimental [Page 31]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ Octets Symbolic Value Protocol field
+
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural-language name
+ natural-
+ language
+ 0x0005 value-length
+ en-us en-US value
+ 0x45 uri type value-tag
+ 0x000B name-length
+ printer-uri printer-uri name
+ 0x001A value-length
+ http://forest:6 printer pinetree value
+ 31/pinetree
+ 0x21 integer type value-tag
+ 0x0005 name-length
+ limit limit name
+ 0x0004 value-length
+ 0x00000032 50 value
+ 0x44 keyword type value-tag
+ 0x0014 name-length
+ requested- requested-attributes name
+ attributes
+ 0x0006 value-length
+ job-id job-id value
+ 0x44 keyword type value-tag
+ 0x0000 additional value name-length
+ 0x0008 value-length
+ job-name job-name value
+ 0x44 keyword type value-tag
+ 0x0000 additional value name-length
+ 0x000F value-length
+ document-format document-format value
+ 0x03 end-of-attributes end-of-attributes-tag
+
+9.8 Get-Jobs Response
+
+ The following is an of Get-Jobs response from previous request with 3
+ jobs. The Printer returns no information about the second job
+ (because of security reasons):
+
+
+
+
+
+Herriot, et al. Experimental [Page 32]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ Octets Symbolic Value Protocol field
+
+ 0x0100 1.0 version-number
+ 0x0000 successful-ok status-code
+ 0x00000123 0x123 request-id (echoed
+ back)
+ 0x01 start operation-attributes operation-attribute-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x000A value-length
+ ISO-8859-1 ISO-8859-1 value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural-language name
+ natural-
+ language
+ 0x0005 value-length
+ en-us en-US value
+ 0x41 textWithoutLanguage type value-tag
+ 0x000E name-length
+ status-message status-message name
+ 0x000D value-length
+ successful-ok successful-ok value
+ 0x02 start job-attributes (1st job-attributes-tag
+ object)
+ 0x21 integer type value-tag
+ 0x0006 name-length
+ job-id job-id name
+ 0x0004 value-length
+ 147 147 value
+ 0x36 nameWithLanguage value-tag
+ 0x0008 name-length
+ job-name job-name name
+ 0x000C value-length
+ 0x0005 sub-value-length
+ fr-ca fr-CA value
+ 0x0003 sub-value-length
+ fou fou name
+ 0x02 start job-attributes (2nd job-attributes-tag
+ object)
+ 0x02 start job-attributes (3rd job-attributes-tag
+ object)
+ 0x21 integer type value-tag
+ 0x0006 name-length
+ job-id job-id name
+ 0x0004 value-length
+
+
+
+Herriot, et al. Experimental [Page 33]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ Octets Symbolic Value Protocol field
+
+ 148 148 value
+ 0x36 nameWithLanguage value-tag
+ 0x0008 name-length
+ job-name job-name name
+ 0x0012 value-length
+ 0x0005 sub-value-length
+ de-CH de-CH value
+ 0x0009 sub-value-length
+ isch guet isch guet name
+ 0x03 end-of-attributes end-of-attributes-tag
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 34]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+10. Appendix C: Registration of MIME Media Type Information for
+ "application/ipp"
+
+ This appendix contains the information that IANA requires for
+ registering a MIME media type. The information following this
+ paragraph will be forwarded to IANA to register application/ipp whose
+ contents are defined in Section 3 "Encoding of the Operation Layer"
+ in this document:
+
+ MIME type name: application
+
+ MIME subtype name: ipp
+
+ A Content-Type of "application/ipp" indicates an Internet Printing
+ Protocol message body (request or response). Currently there is one
+ version: IPP/1.0, whose syntax is described in Section 3 "Encoding of
+ the Operation Layer" of [RFC2565], and whose semantics are described
+ in [RFC2566].
+
+ Required parameters: none
+
+ Optional parameters: none
+
+ Encoding considerations:
+
+ IPP/1.0 protocol requests/responses MAY contain long lines and ALWAYS
+ contain binary data (for example attribute value lengths).
+
+ Security considerations:
+
+ IPP/1.0 protocol requests/responses do not introduce any security
+ risks not already inherent in the underlying transport protocols.
+ Protocol mixed-version interworking rules in [RFC2566] as well as
+ protocol encoding rules in [RFC2565] are complete and unambiguous.
+
+ Interoperability considerations:
+
+ IPP/1.0 requests (generated by clients) and responses (generated by
+ servers) MUST comply with all conformance requirements imposed by the
+ normative specifications [RFC2566] and [RFC2565]. Protocol encoding
+ rules specified in [RFC2565] are comprehensive, so that
+ interoperability between conforming implementations is guaranteed
+ (although support for specific optional features is not ensured).
+ Both the "charset" and "natural-language" of all IPP/1.0 attribute
+ values which are a LOCALIZED-STRING are explicit within IPP protocol
+ requests/responses (without recourse to any external information in
+ HTTP, SMTP, or other message transport headers).
+
+
+
+
+Herriot, et al. Experimental [Page 35]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+ Published specification:
+
+ [RFC2566] Isaacson, S., deBry, R., Hastings, T., Herriot, R. and P.
+ Powell, "Internet Printing Protocol/1.0: Model and
+ Semantics" RFC 2566, April 1999.
+
+ [RFC2565] Herriot, R., Butler, S., Moore, P., Tuner, R., "Internet
+ Printing Protocol/1.0: Encoding and Transport", RFC 2565,
+ April 1999.
+
+ Applications which use this media type:
+
+ Internet Printing Protocol (IPP) print clients and print servers,
+ communicating using HTTP/1.1 (see [RFC2565]), SMTP/ESMTP, FTP, or
+ other transport protocol. Messages of type "application/ipp" are
+ self-contained and transport-independent, including "charset" and
+ "natural-language" context for any LOCALIZED-STRING value.
+
+ Person & email address to contact for further information:
+
+ Scott A. Isaacson
+ Novell, Inc.
+ 122 E 1700 S
+ Provo, UT 84606
+
+ Phone: 801-861-7366
+ Fax: 801-861-4025
+ Email: sisaacson@novell.com
+
+ or
+
+ Robert Herriot (Editor)
+ Xerox Corporation
+ 3400 Hillview Ave., Bldg #1
+ Palo Alto, CA 94304
+
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ EMail: rherriot@pahv.xerox.com
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 36]
+
+RFC 2565 IPP/1.0: Encoding and Transport April 1999
+
+
+11. Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 37]
+
diff --git a/standards/rfc2566.txt b/standards/rfc2566.txt
new file mode 100644
index 000000000..f373d6a0f
--- /dev/null
+++ b/standards/rfc2566.txt
@@ -0,0 +1,9691 @@
+
+
+
+
+
+
+Network Working Group R. deBry
+Request for Comments: 2566 Utah Valley State College
+Category: Experimental T. Hastings
+ Xerox Corporation
+ R. Herriot
+ Xerox Corporation
+ S. Isaacson
+ Novell, Inc.
+ P. Powell
+ Astart Technologies
+ April 1999
+
+
+ Internet Printing Protocol/1.0: Model and Semantics
+
+Status of this Memo
+
+ This memo defines an Experimental Protocol for the Internet
+ community. It does not specify an Internet standard of any kind.
+ Discussion and suggestions for improvement are requested.
+ Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+IESG Note
+
+ This document defines an Experimental protocol for the Internet
+ community. The IESG expects that a revised version of this protocol
+ will be published as Proposed Standard protocol. The Proposed
+ Standard, when published, is expected to change from the protocol
+ defined in this memo. In particular, it is expected that the
+ standards-track version of the protocol will incorporate strong
+ authentication and privacy features, and that an "ipp:" URL type will
+ be defined which supports those security measures. Other changes to
+ the protocol are also possible. Implementors are warned that future
+ versions of this protocol may not interoperate with the version of
+ IPP defined in this document, or if they do interoperate, that some
+ protocol features may not be available.
+
+ The IESG encourages experimentation with this protocol, especially in
+ combination with Transport Layer Security (TLS) [RFC 2246], to help
+ determine how TLS may effectively be used as a security layer for
+ IPP.
+
+
+
+
+
+
+deBry, et al. Experimental [Page 1]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+Abstract
+
+ This document is one of a set of documents, which together describe
+ all aspects of a new Internet Printing Protocol (IPP). IPP is an
+ application level protocol that can be used for distributed printing
+ using Internet tools and technologies. This document describes a
+ simplified model consisting of abstract objects, their attributes,
+ and their operations that is independent of encoding and transport.
+ The model consists of a Printer and a Job object. A Job optionally
+ supports multiple documents. IPP 1.0 semantics allow end-users and
+ operators to query printer capabilities, submit print jobs, inquire
+ about the status of print jobs and printers, and cancel print jobs.
+ This document also addresses security, internationalization, and
+ directory issues.
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.0: Model and Semantics (this document)
+ Internet Printing Protocol/1.0: Encoding and Transport [RFC2565]
+ Internet Printing Protocol/1.0: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ The "Design Goals for an Internet Printing Protocol" document takes a
+ broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. Operator and administrator requirements
+ are out of scope for version 1.0.
+
+ The "Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol" document describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specifications, and gives background and rationale for the
+ IETF working group's major decisions.
+
+ The "Internet Printing Protocol/1.0: Encoding and Transport" document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1. It defines the encoding rules
+ for a new Internet media type called "application/ipp".
+
+ The "Internet Printing Protocol/1.0: Implementer's Guide" document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.0 and some of
+
+
+
+deBry, et al. Experimental [Page 2]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+ The "Mapping between LPD and IPP Protocols" document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+Table of Contents
+
+1. Introduction 8
+ 1.1 Simplified Printing Model 9
+2. IPP Objects 11
+ 2.1 Printer Object 12
+ 2.2 Job Object 14
+ 2.3 Object Relationships 14
+ 2.4 Object Identity 15
+3. IPP Operations 18
+ 3.1 Common Semantics 19
+ 3.1.1 Required Parameters 19
+ 3.1.2 Operation IDs and Request IDs 20
+ 3.1.3 Attributes 20
+ 3.1.4 Character Set and Natural Language Operation Attributes 22
+ 3.1.4.1 Request Operation Attributes 22
+ 3.1.4.2 Response Operation Attributes 26
+ 3.1.5 Operation Targets 28
+ 3.1.6 Operation Status Codes and Messages 29
+ 3.1.7 Versions 30
+ 3.1.8 Job Creation Operations 32
+ 3.2 Printer Operations 34
+ 3.2.1 Print-Job Operation 34
+ 3.2.1.1 Print-Job Request 34
+ 3.2.1.2 Print-Job Response 38
+ 3.2.2 Print-URI Operation 41
+ 3.2.3 Validate-Job Operation 42
+ 3.2.4 Create-Job Operation 42
+ 3.2.5 Get-Printer-Attributes Operation 43
+ 3.2.5.1 Get-Printer-Attributes Request 44
+ 3.2.5.2 Get-Printer-Attributes Response 46
+ 3.2.6 Get-Jobs Operation 47
+ 3.2.6.1 Get-Jobs Request 47
+ 3.2.6.2 Get-Jobs Response 49
+ 3.3 Job Operations 50
+ 3.3.1 Send-Document Operation 50
+ 3.3.1.1 Send-Document Request 51
+ 3.3.1.2 Send-Document Response 53
+ 3.3.2 Send-URI Operation 54
+
+
+
+deBry, et al. Experimental [Page 3]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 3.3.3 Cancel-Job Operation 54
+ 3.3.3.1 Cancel-Job Request 54
+ 3.3.3.2 Cancel-Job Response 55
+ 3.3.4 Get-Job-Attributes Operation 56
+ 3.3.4.1 Get-Job-Attributes Request 57
+ 3.3.4.2 Get-Job-Attributes Response 57
+4. Object Attributes 58
+ 4.1 Attribute Syntaxes 59
+ 4.1.1 'text' 60
+ 4.1.1.1 'textWithoutLanguage' 61
+ 4.1.1.2 'textWithLanguage' 61
+ 4.1.2 'name' 62
+ 4.1.2.1 'nameWithoutLanguage' 62
+ 4.1.2.2 'nameWithLanguage' 63
+ 4.1.2.3 Matching 'name' attribute values 63
+ 4.1.3 'keyword' 64
+ 4.1.4 'enum' 65
+ 4.1.5 'uri' 65
+ 4.1.6 'uriScheme' 65
+ 4.1.7 'charset' 66
+ 4.1.8 'naturalLanguage' 67
+ 4.1.9 'mimeMediaType' 67
+ 4.1.10 'octetString' 69
+ 4.1.11 'boolean' 69
+ 4.1.12 'integer' 69
+ 4.1.13 'rangeOfInteger' 69
+ 4.1.14 'dateTime' 69
+ 4.1.15 'resolution' 69
+ 4.1.16 '1setOf X' 70
+ 4.2 Job Template Attributes 70
+ 4.2.1 job-priority (integer(1:100)) 74
+ 4.2.2 job-hold-until (type3 keyword | name (MAX)) 75
+ 4.2.3 job-sheets (type3 keyword | name(MAX)) 75
+ 4.2.4 multiple-document-handling (type2 keyword) 76
+ 4.2.5 copies (integer(1:MAX)) 77
+ 4.2.6 finishings (1setOf type2 enum) 78
+ 4.2.7 page-ranges (1setOf rangeOfInteger (1:MAX)) 79
+ 4.2.8 sides (type2 keyword) 80
+ 4.2.9 number-up (integer(1:MAX)) 80
+ 4.2.10 orientation-requested (type2 enum) 81
+ 4.2.11 media (type3 keyword | name(MAX)) 82
+ 4.2.12 printer-resolution (resolution) 83
+ 4.2.13 print-quality (type2 enum) 83
+ 4.3 Job Description Attributes 84
+ 4.3.1 job-uri (uri) 85
+ 4.3.2 job-id (integer(1:MAX)) 85
+ 4.3.3 job-printer-uri (uri) 86
+ 4.3.4 job-more-info (uri) 86
+
+
+
+deBry, et al. Experimental [Page 4]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 4.3.5 job-name (name(MAX)) 86
+ 4.3.6 job-originating-user-name (name(MAX)) 86
+ 4.3.7 job-state (type1 enum) 87
+ 4.3.8 job-state-reasons (1setOf type2 keyword) 90
+ 4.3.9 job-state-message (text(MAX)) 92
+ 4.3.10 number-of-documents (integer(0:MAX)) 93
+ 4.3.11 output-device-assigned (name(127)) 93
+ 4.3.12 time-at-creation (integer(0:MAX)) 93
+ 4.3.13 time-at-processing (integer(0:MAX)) 93
+ 4.3.14 time-at-completed (integer(0:MAX)) 94
+ 4.3.15 number-of-intervening-jobs (integer(0:MAX)) 94
+ 4.3.16 job-message-from-operator (text(127)) 94
+ 4.3.17 job-k-octets (integer(0:MAX)) 94
+ 4.3.18 job-impressions (integer(0:MAX)) 95
+ 4.3.19 job-media-sheets (integer(0:MAX)) 95
+ 4.3.20 job-k-octets-processed (integer(0:MAX)) 96
+ 4.3.21 job-impressions-completed (integer(0:MAX)) 96
+ 4.3.22 job-media-sheets-completed (integer(0:MAX)) 96
+ 4.3.23 attributes-charset (charset) 97
+ 4.3.24 attributes-natural-language (naturalLanguage) 97
+ 4.4 Printer Description Attributes 97
+ 4.4.1 printer-uri-supported (1setOf uri) 99
+ 4.4.2 uri-security-supported (1setOf type2 keyword) 100
+ 4.4.3 printer-name (name(127)) 101
+ 4.4.4 printer-location (text(127)) 101
+ 4.4.5 printer-info (text(127)) 101
+ 4.4.6 printer-more-info (uri) 101
+ 4.4.7 printer-driver-installer (uri) 102
+ 4.4.8 printer-make-and-model (text(127)) 102
+ 4.4.9 printer-more-info-manufacturer (uri) 102
+ 4.4.10 printer-state (type1 enum) 102
+ 4.4.11 printer-state-reasons (1setOf type2 keyword) 103
+ 4.4.12 printer-state-message (text(MAX)) 106
+ 4.4.13 operations-supported (1setOf type2 enum) 106
+ 4.4.14 charset-configured (charset) 107
+ 4.4.15 charset-supported (1setOf charset) 107
+ 4.4.16 natural-language-configured (naturalLanguage) 107
+ 4.4.17 generated-natural-language-supported(1setOf naturalLanguage108
+ 4.4.18 document-format-default (mimeMediaType) 108
+ 4.4.19 document-format-supported (1setOf mimeMediaType) 108
+ 4.4.20 printer-is-accepting-jobs (boolean) 109
+ 4.4.21 queued-job-count (integer(0:MAX)) 109
+ 4.4.22 printer-message-from-operator (text(127)) 109
+ 4.4.23 color-supported (boolean) 109
+ 4.4.24 reference-uri-schemes-supported (1setOf uriScheme) 109
+ 4.4.25 pdl-override-supported (type2 keyword) 110
+ 4.4.26 printer-up-time (integer(1:MAX)) 110
+ 4.4.27 printer-current-time (dateTime) 111
+
+
+
+deBry, et al. Experimental [Page 5]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 4.4.28 multiple-operation-time-out (integer(1:MAX)) 111
+ 4.4.29 compression-supported (1setOf type3 keyword) 111
+ 4.4.30 job-k-octets-supported (rangeOfInteger(0:MAX)) 112
+ 4.4.31 job-impressions-supported (rangeOfInteger(0:MAX)) 112
+ 4.4.32 job-media-sheets-supported (rangeOfInteger(0:MAX)) 112
+5. Conformance 112
+ 5.1 Client Conformance Requirements 112
+ 5.2 IPP Object Conformance Requirements 113
+ 5.2.1 Objects 113
+ 5.2.2 Operations 113
+ 5.2.3 IPP Object Attributes 114
+ 5.2.4 Extensions 114
+ 5.2.5 Attribute Syntaxes 115
+ 5.3 Charset and Natural Language Requirements 115
+ 5.4 Security Conformance Requirements 115
+6. IANA Considerations (registered and private extensions) 116
+ 6.1 Typed 'keyword' and 'enum' Extensions 116
+ 6.2 Attribute Extensibility 119
+ 6.3 Attribute Syntax Extensibility 119
+ 6.4 Operation Extensibility 120
+ 6.5 Attribute Groups 120
+ 6.6 Status Code Extensibility 120
+ 6.7 Registration of MIME types/sub-types for document-formats 121
+ 6.8 Registration of charsets for use in 'charset' attribute values121
+7. Internationalization Considerations 121
+8. Security Considerations 125
+ 8.1 Security Scenarios 126
+ 8.1.1 Client and Server in the Same Security Domain 126
+ 8.1.2 Client and Server in Different Security Domains 126
+ 8.1.3 Print by Reference 127
+ 8.2 URIs for SSL3 and non-SSL3 Access 127
+ 8.3 The "requesting-user-name" (name(MAX)) Operation Attribute 127
+ 8.4 Restricted Queries 129
+ 8.5 Queries on jobs submitted using non-IPP protocols 129
+ 8.6 IPP Security Application Profile for SSL3 130
+9. References 131
+10. Authors' Addresses 134
+11. Formats for IPP Registration Proposals 136
+ 11.1 Type2 keyword attribute values registration 136
+ 11.2 Type3 keyword attribute values registration 137
+ 11.3 Type2 enum attribute values registration 137
+ 11.4 Type3 enum attribute values registration 137
+ 11.5 Attribute registration 138
+ 11.6 Attribute Syntax registration 138
+ 11.7 Operation registration 139
+ 11.8 Attribute Group registration 139
+ 11.9 Status code registration 139
+12.APPENDIX A: Terminology 141
+
+
+
+deBry, et al. Experimental [Page 6]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 12.1 Conformance Terminology 141
+ 12.1.1 NEED NOT 141
+ 12.2 Model Terminology 141
+ 12.2.1 Keyword 141
+ 12.2.2 Attributes 141
+ 12.2.2.1 Attribute Name 141
+ 12.2.2.2 Attribute Group Name 142
+ 12.2.2.3 Attribute Value 142
+ 12.2.2.4 Attribute Syntax 142
+ 12.2.3 Supports 142
+ 12.2.4 print-stream page 144
+ 12.2.5 impression 144
+13.APPENDIX B: Status Codes and Suggested Status Code Messages 145
+ 13.1 Status Codes 146
+ 13.1.1 Informational 146
+ 13.1.2 Successful Status Codes 146
+ 13.1.2.1 successful-ok (0x0000) 146
+ 13.1.2.2 successful-ok-ignored-or-substituted-attributes (0x0001) 146
+ 13.1.2.3 successful-ok-conflicting-attributes (0x0002) 147
+ 13.1.3 Redirection Status Codes 147
+ 13.1.4 Client Error Status Codes 147
+ 13.1.4.1 client-error-bad-request (0x0400) 147
+ 13.1.4.2 client-error-forbidden (0x0401) 147
+ 13.1.4.3 client-error-not-authenticated (0x0402) 148
+ 13.1.4.4 client-error-not-authorized (0x0403) 148
+ 13.1.4.5 client-error-not-possible (0x0404) 148
+ 13.1.4.6 client-error-timeout (0x0405) 148
+ 13.1.4.7 client-error-not-found (0x0406) 149
+ 13.1.4.8 client-error-gone (0x0407) 149
+ 13.1.4.9 client-error-request-entity-too-large (0x0408) 149
+ 13.1.4.10client-error-request-value-too-long (0x0409) 150
+ 13.1.4.11client-error-document-format-not-supported (0x040A) 150
+ 13.1.4.12client-error-attributes-or-values-not-supported (0x040B) 150
+ 13.1.4.13client-error-uri-scheme-not-supported (0x040C) 151
+ 13.1.4.14client-error-charset-not-supported (0x040D) 151
+ 13.1.4.15client-error-conflicting-attributes (0x040E) 151
+ 13.1.5 Server Error Status Codes 151
+ 13.1.5.1 server-error-internal-error (0x0500) 151
+ 13.1.5.2 server-error-operation-not-supported (0x0501) 152
+ 13.1.5.3 server-error-service-unavailable (0x0502) 152
+ 13.1.5.4 server-error-version-not-supported (0x0503) 152
+ 13.1.5.5 server-error-device-error (0x0504) 152
+ 13.1.5.6 server-error-temporary-error (0x0505) 153
+ 13.1.5.7 server-error-not-accepting-jobs (0x0506) 153
+ 13.1.5.8 server-error-busy (0x0507) 153
+ 13.1.5.9 server-error-job-canceled (0x0508) 153
+ 13.2 Status Codes for IPP Operations 153
+14.APPENDIX C: "media" keyword values 155
+
+
+
+deBry, et al. Experimental [Page 7]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+15.APPENDIX D: Processing IPP Attributes 160
+ 15.1 Fidelity 160
+ 15.2 Page Description Language (PDL) Override 161
+ 15.3 Using Job Template Attributes During Document Processing. 163
+16.APPENDIX E: Generic Directory Schema 166
+17.APPENDIX F: Change History for the Model and Semantics document 168
+18.FULL COPYRIGHT STATEMENT 173
+
+1. Introduction
+
+ The Internet Printing Protocol (IPP) is an application level protocol
+ that can be used for distributed printing using Internet tools and
+ technologies. IPP version 1.0 (IPP/1.0) focuses only on end user
+ functionality. This document is just one of a suite of documents
+ that fully define IPP. The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.0: Model and Semantics (this document)
+ Internet Printing Protocol/1.0: Encoding and Transport [RFC2565]
+ Internet Printing Protocol/1.0: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ Anyone reading these documents for the first time is strongly
+ encouraged to read the IPP documents in the above order.
+
+ This document is laid out as follows:
+
+ - The rest of Section 1 is an introduction to the IPP simplified
+ model for distributed printing.
+ - Section 2 introduces the object types covered in the model with
+ their basic behaviors, attributes, and interactions.
+ - Section 3 defines the operations included in IPP/1.0. IPP
+ operations are synchronous, therefore, for each operation, there
+ is a both request and a response.
+ - Section 4 defines the attributes (and their syntaxes) that are
+ used in the model.
+ - Sections 5 - 6 summarizes the implementation conformance
+ requirements for objects that support the protocol and IANA
+ considerations, respectively.
+ - Sections 7 - 11 cover the Internationalization and Security
+ considerations as well as References, Author contact information,
+ and Formats for Registration Proposals.
+ - Sections 12 - 14 are appendices that cover Terminology, Status
+ Codes and Messages, and "media" keyword values.
+
+
+
+
+
+deBry, et al. Experimental [Page 8]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Note: This document uses terms such as "attributes",
+ "keywords", and "support". These terms have special
+ meaning and are defined in the model terminology section
+ 12.2. Capitalized terms, such as MUST, MUST NOT, REQUIRED,
+ SHOULD, SHOULD NOT, MAY, NEED NOT, and OPTIONAL, have
+ special meaning relating to conformance. These terms are
+ defined in section 12.1 on conformance terminology, most of
+ which is taken from RFC 2119 [RFC2119].
+
+ - Section 15 is an appendix that helps to clarify the effects of
+ interactions between related attributes and their values.
+ - Section 16 is an appendix that enumerates the subset of Printer
+ attributes that form a generic directory schema. These
+ attributes are useful when registering a Printer so that a
+ client can find the Printer not just by name, but by filtered
+ searches as well.
+ - Section 17 is an appendix that provides a Change History
+ summarizing the clarification and changes that might affect an
+ implementation since the June 30, 1998 draft.
+
+1.1 Simplified Printing Model
+
+ In order to achieve its goal of realizing a workable printing
+ protocol for the Internet, the Internet Printing Protocol (IPP) is
+ based on a simplified printing model that abstracts the many
+ components of real world printing solutions. The Internet is a
+ distributed computing environment where requesters of print services
+ (clients, applications, printer drivers, etc.) cooperate and interact
+ with print service providers. This model and semantics document
+ describes a simple, abstract model for IPP even though the underlying
+ configurations may be complex "n-tier" client/server systems. An
+ important simplifying step in the IPP model is to expose only the key
+ objects and interfaces required for printing. The model described in
+ this model document does not include features, interfaces, and
+ relationships that are beyond the scope of the first version of IPP
+ (IPP/1.0). IPP/1.0 incorporates many of the relevant ideas and
+ lessons learned from other specification and development efforts
+ [HTPP] [ISO10175] [LDPA] [P1387.4] [PSIS] [RFC1179] [SWP]. IPP is
+ heavily influenced by the printing model introduced in the Document
+ Printing Application (DPA) [ISO10175] standard. Although DPA
+ specifies both end user and administrative features, IPP version 1.0
+ (IPP/1.0) focuses only on end user functionality.
+
+ The IPP/1.0 model encapsulates the important components of
+ distributed printing into two object types:
+
+ - Printer (Section 2.1)
+ - Job (Section 2.2)
+
+
+
+deBry, et al. Experimental [Page 9]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Each object type has an associated set of operations (see section 3)
+ and attributes (see section 4).
+
+ It is important, however, to understand that in real system
+ implementations (which lie underneath the abstracted IPP/1.0 model),
+ there are other components of a print service which are not
+ explicitly defined in the IPP/1.0 model. The following figure
+ illustrates where IPP/1.0 fits with respect to these other
+ components.
+
+ +--------------+
+ | Application |
+ o +. . . . . . . |
+ \|/ | Spooler |
+ / \ +. . . . . . . | +---------+
+ End-User | Print Driver |---| File |
+ +-----------+ +-----+ +------+-------+ +----+----+
+ | Browser | | GUI | | |
+ +-----+-----+ +--+--+ | |
+ | | | |
+ | +---+------------+---+ |
+ N D S | | IPP Client |------------+
+ O I E | +---------+----------+
+ T R C | |
+ I E U |
+ F C R -------------- Transport ------------------
+ I T I
+ C O T | --+
+ A R Y +--------+--------+ |
+ T Y | IPP Server | |
+ I +--------+--------+ |
+ O | |
+ N +-----------------+ | IPP Printer
+ | Print Service | |
+ +-----------------+ |
+ | --+
+ +-----------------+
+ | Output Device(s)|
+ +-----------------+
+
+ An IPP Printer object encapsulates the functions normally associated
+ with physical output devices along with the spooling, scheduling and
+ multiple device management functions often associated with a print
+ server. Printer objects are optionally registered as entries in a
+ directory where end users find and select them based on some sort of
+ filtered and context based searching mechanism (see section 16). The
+ directory is used to store relatively static information about the
+ Printer, allowing end users to search for and find Printers that
+
+
+
+deBry, et al. Experimental [Page 10]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ match their search criteria, for example: name, context, printer
+ capabilities, etc. The more dynamic information, such as state,
+ currently loaded and ready media, number of jobs at the Printer,
+ errors, warnings, and so forth, is directly associated with the
+ Printer object itself rather than with the entry in the directory
+ which only represents the Printer object.
+
+ IPP clients implement the IPP protocol on the client side and give
+ end users (or programs running on behalf of end users) the ability to
+ query Printer objects and submit and manage print jobs. An IPP
+ server is just that part of the Printer object that implements the
+ server-side protocol. The rest of the Printer object implements (or
+ gateways into) the application semantics of the print service itself.
+ The Printer objects may be embedded in an output device or may be
+ implemented on a host on the network that communicates with an output
+ device.
+
+ When a job is submitted to the Printer object and the Printer object
+ validates the attributes in the submission request, the Printer
+ object creates a new Job object. The end user then interacts with
+ this new Job object to query its status and monitor the progress of
+ the job. End users may also cancel the print job by using the Job
+ object's Cancel-Job operation. The notification service is out of
+ scope for IPP/1.0, but using such a notification service, the end
+ user is able to register for and receive Printer specific and Job
+ specific events. An end user can query the status of Printer objects
+ and can follow the progress of Job objects by polling using the Get-
+ Printer-Attributes, Get-Jobs, and Get-Job-Attributes operations.
+
+2. IPP Objects
+
+ The IPP/1.0 model introduces objects of type Printer and Job. Each
+ type of object models relevant aspects of a real-world entity such as
+ a real printer or real print job. Each object type is defined as a
+ set of possible attributes that may be supported by instances of that
+ object type. For each object (instance), the actual set of supported
+ attributes and values describe a specific implementation. The
+ object's attributes and values describe its state, capabilities,
+ realizable features, job processing functions, and default behaviors
+ and characteristics. For example, the Printer object type is defined
+ as a set of attributes that each Printer object potentially supports.
+ In the same manner, the Job object type is defined as a set of
+ attributes that are potentially supported by each Job object.
+
+ Each attribute included in the set of attributes defining an object
+ type is labeled as:
+
+
+
+
+
+deBry, et al. Experimental [Page 11]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ - "REQUIRED": each object MUST support the attribute.
+ - "OPTIONAL": each object MAY support the attribute.
+
+ There is no such similar labeling of attribute values. However, if
+ an implementation supports an attribute, it MUST support at least one
+ of the possible values for that attribute.
+
+2.1 Printer Object
+
+ The major component of the IPP/1.0 model is the Printer object. A
+ Printer object implements the server-side of the IPP/1.0 protocol.
+ Using the protocol, end users may query the attributes of the Printer
+ object and submit print jobs to the Printer object. The actual
+ implementation components behind the Printer abstraction may take on
+ different forms and different configurations. However, the model
+ abstraction allows the details of the configuration of real
+ components to remain opaque to the end user. Section 3 describes
+ each of the Printer operations in detail.
+
+ The capabilities and state of a Printer object are described by its
+ attributes. Printer attributes are divided into two groups:
+
+ - "job-template" attributes: These attributes describe supported
+ job processing capabilities and defaults for the Printer object.
+ (See section 4.2)
+ - "printer-description" attributes: These attributes describe the
+ Printer object's identification, state, location, references to
+ other sources of information about the Printer object, etc. (see
+ section 4.4)
+
+ Since a Printer object is an abstraction of a generic document output
+ device and print service provider, a Printer object could be used to
+ represent any real or virtual device with semantics consistent with
+ the Printer object, such as a fax device, an imager, or even a CD
+ writer.
+
+ Some examples of configurations supporting a Printer object include:
+
+ 1) An output device with no spooling capabilities
+ 2) An output device with a built-in spooler
+ 3) A print server supporting IPP with one or more associated output
+ devices
+ 3a) The associated output devices may or may not be capable of
+ spooling jobs
+ 3b) The associated output devices may or may not support IPP
+
+
+
+
+
+
+deBry, et al. Experimental [Page 12]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ The following figures show some examples of how Printer objects can
+ be realized on top of various distributed printing configurations.
+ The embedded case below represents configurations 1 and 2. The hosted
+ and fan-out figures below represent configurations 3a and 3b.
+
+ Legend:
+
+ ##### indicates a Printer object which is
+ either embedded in an output device or is
+ hosted in a server. The Printer object
+ might or might not be capable of queuing/spooling.
+
+ any indicates any network protocol or direct
+ connect, including IPP
+
+
+ embedded printer:
+ output device
+ +---------------+
+ O +--------+ | ########### |
+ /|\ | client |------------IPP------------># Printer # |
+ / \ +--------+ | # Object # |
+ | ########### |
+ +---------------+
+
+
+ hosted printer:
+ +---------------+
+ O +--------+ ########### | |
+ /|\ | client |--IPP--># Printer #-any->| output device |
+ / \ +--------+ # Object # | |
+ ########### +---------------+
+
+
+
+ +---------------+
+ fan out: | |
+ +-->| output device |
+ any/ | |
+ O +--------+ ########### / +---------------+
+ /|\ | client |-IPP-># Printer #--*
+ / \ +--------+ # Object # \ +---------------+
+ ########### any\ | |
+ +-->| output device |
+ | |
+ +---------------+
+
+
+
+
+
+deBry, et al. Experimental [Page 13]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+2.2 Job Object
+
+ A Job object is used to model a print job. A Job object contains
+ documents. The information required to create a Job object is sent
+ in a create request from the end user via an IPP Client to the
+ Printer object. The Printer object validates the create request, and
+ if the Printer object accepts the request, the Printer object creates
+ the new Job object. Section 3 describes each of the Job operations
+ in detail.
+
+ The characteristics and state of a Job object are described by its
+ attributes. Job attributes are grouped into two groups as follows:
+
+ - "job-template" attributes: These attributes can be supplied by
+ the client or end user and include job processing instructions
+ which are intended to override any Printer object defaults and/or
+ instructions embedded within the document data. (See section 4.2)
+ - "job-description" attributes: These attributes describe the Job
+ object's identification, state, size, etc. The client supplies
+ some of these attributes, and the Printer object generates others.
+ (See section 4.3)
+
+ An implementation MUST support at least one document per Job object.
+ An implementation MAY support multiple documents per Job object. A
+ document is either:
+
+ - a stream of document data in a format supported by the Printer
+ object (typically a Page Description Language - PDL), or
+ - a reference to such a stream of document data
+
+ In IPP/1.0, a document is not modeled as an IPP object, therefore it
+ has no object identifier or associated attributes. All job
+ processing instructions are modeled as Job object attributes. These
+ attributes are called Job Template attributes and they apply equally
+ to all documents within a Job object.
+
+2.3 Object Relationships
+
+ IPP objects have relationships that are maintained persistently along
+ with the persistent storage of the object attributes.
+
+ A Printer object can represent either one or more physical output
+ devices or a logical device which "processes" jobs but never actually
+ uses a physical output device to put marks on paper. Examples of
+ logical devices include a Web page publisher or a gateway into an
+ online document archive or repository. A Printer object contains
+ zero or more Job objects.
+
+
+
+
+deBry, et al. Experimental [Page 14]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ A Job object is contained by exactly one Printer object, however the
+ identical document data associated with a Job object could be sent to
+ either the same or a different Printer object. In this case, a
+ second Job object would be created which would be almost identical to
+ the first Job object, however it would have new (different) Job
+ object identifiers (see section 2.4).
+
+ A Job object is either empty (before any documents have been added)
+ or contains one or more documents. If the contained document is a
+ stream of document data, that stream can be contained in only one
+ document. However, there can be identical copies of the stream in
+ other documents in the same or different Job objects. If the
+ contained document is just a reference to a stream of document data,
+ other documents (in the same or different Job object(s)) may contain
+ the same reference.
+
+2.4 Object Identity
+
+ All Printer and Job objects are identified by a Uniform Resource
+ Identifier (URI) [RFC2396] so that they can be persistently and
+ unambiguously referenced. The notion of a URI is a useful concept,
+ however, until the notion of URI is more stable (i.e., defined more
+ completely and deployed more widely), it is expected that the URIs
+ used for IPP objects will actually be URLs [RFC2396]. Since every
+ URL is a specialized form of a URI, even though the more generic term
+ URI is used throughout the rest of this document, its usage is
+ intended to cover the more specific notion of URL as well.
+
+ An administrator configures Printer objects to either support or not
+ support authentication and/or message privacy using SSL3 [SSL] (the
+ mechanism for security configuration is outside the scope of
+ IPP/1.0). In some situations, both types of connections (both
+ authenticated and unauthenticated) can be established using a single
+ communication channel that has some sort of negotiation mechanism.
+ In other situations, multiple communication channels are used, one
+ for each type of security configuration. Section 8 provides a full
+ description of all security considerations and configurations.
+
+ If a Printer object supports more than one communication channel,
+ some or all of those channels might support and/or require different
+ security mechanisms. In such cases, an administrator could expose
+ the simultaneous support for these multiple communication channels as
+ multiple URIs for a single Printer object where each URI represents
+ one of the communication channels to the Printer object. To support
+ this flexibility, the IPP Printer object type defines a multi-valued
+ identification attribute called the "printer-uri-supported"
+ attribute. It MUST contain at least one URI. It MAY contain more
+ than one URI. That is, every Printer object will have at least one
+
+
+
+deBry, et al. Experimental [Page 15]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ URI that identifies at least one communication channel to the Printer
+ object, but it may have more than one URI where each URI identifies a
+ different communication channel to the Printer object. The
+ "printer-uri-supported" attribute has a companion attribute, the
+ "uri-security-supported" attribute, that has the same cardinality as
+ "printer-uri-supported". The purpose of the "uri-security-supported"
+ attribute is to indicate the security mechanisms (if any) used for
+ each URI listed in "printer-uri-supported". These two attributes are
+ fully described in sections 4.4.1 and 4.4.2.
+
+ When a job is submitted to the Printer object via a create request,
+ the client supplies only a single Printer object URI. The client
+ supplied Printer object URI MUST be one of the values in the
+ "printer-uri-supported" Printer attribute.
+
+ Note: IPP/1.0 does not specify how the client obtains the client
+ supplied URI, but it is RECOMMENDED that a Printer object be
+ registered as an entry in a directory service. End-users and
+ programs can then interrogate the directory searching for Printers.
+ Section 16 defines a generic schema for Printer object entries in the
+ directory service and describes how the entry acts as a bridge to the
+ actual IPP Printer object. The entry in the directory that
+ represents the IPP Printer object includes the possibly many URIs for
+ that Printer object as values in one its attributes.
+
+ When a client submits a create request to the Printer object, the
+ Printer object validates the request and creates a new Job object.
+ The Printer object assigns the new Job object a URI which is stored
+ in the "job-uri" Job attribute. This URI is then used by clients as
+ the target for subsequent Job operations. The Printer object
+ generates a Job URI based on its configured security policy and the
+ URI used by the client in the create request.
+
+ For example, consider a Printer object that supports both a
+ communication channel secured by the use of SSL3 (using HTTP over
+ SSL3 with an "https" schemed URI) and another open communication
+ channel that is not secured with SSL3 (using a simple "http" schemed
+ URI). If a client were to submit a job using the secure URI, the
+ Printer object would assign the new Job object a secure URI as well.
+ If a client were to submit a job using the open-channel URI, the
+ Printer would assign the new Job object an open-channel URI.
+
+ In addition, the Printer object also populates the Job object's
+ "job-printer-uri" attribute. This is a reference back to the Printer
+ object that created the Job object. If a client only has access to a
+ Job object's "job-uri" identifier, the client can query the Job's
+ "job-printer-uri" attribute in order to determine which Printer
+ object created the Job object. If the Printer object supports more
+
+
+
+deBry, et al. Experimental [Page 16]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ than one URI, the Printer object picks the one URI supplied by the
+ client when creating the job to build the value for and to populate
+ the Job's "job-printer-uri" attribute.
+
+ Allowing Job objects to have URIs allows for flexibility and
+ scalability. For example, in some implementations, the Printer
+ object might create Jobs that are processed in the same local
+ environment as the Printer object itself. In this case, the Job URI
+ might just be a composition of the Printer's URI and some unique
+ component for the Job object, such as the unique 32-bit positive
+ integer mentioned later in this paragraph. In other implementations,
+ the Printer object might be a central clearing-house for validating
+ all Job object creation requests, but the Job object itself might be
+ created in some environment that is remote from the Printer object.
+ In this case, the Job object's URI may have no physical-location
+ relationship at all to the Printer object's URI. Again, the fact
+ that Job objects have URIs allows for flexibility and scalability,
+ however, many existing printing systems have local models or
+ interface constraints that force print jobs to be identified using
+ only a 32-bit positive integer rather than an independent URI. This
+ numeric Job ID is only unique within the context of the Printer
+ object to which the create request was originally submitted.
+ Therefore, in order to allow both types of client access to IPP Job
+ objects (either by Job URI or by numeric Job ID), when the Printer
+ object successfully processes a create request and creates a new Job
+ object, the Printer object MUST generate both a Job URI and a Job ID.
+ The Job ID (stored in the "job-id" attribute) only has meaning in the
+ context of the Printer object to which the create request was
+ originally submitted. This requirement to support both Job URIs and
+ Job IDs allows all types of clients to access Printer objects and Job
+ objects no matter the local constraints imposed on the client
+ implementation.
+
+ In addition to identifiers, Printer objects and Job objects have
+ names ("printer-name" and "job-name"). An object name NEED NOT be
+ unique across all instances of all objects. A Printer object's name
+ is chosen and set by an administrator through some mechanism outside
+ the scope of IPP/1.0. A Job object's name is optionally chosen and
+ supplied by the IPP client submitting the job. If the client does
+ not supply a Job object name, the Printer object generates a name for
+ the new Job object. In all cases, the name only has local meaning.
+
+ To summarize:
+
+ - Each Printer object is identified with one or more URIs. The
+ Printer's "printer-uri-supported" attribute contains the URI(s).
+
+
+
+
+
+deBry, et al. Experimental [Page 17]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ - The Printer object's "uri-security-supported" attribute
+ identifies the communication channel security protocols that may
+ or may not have been configured for the various Printer object
+ URIs (e.g., 'ssl3' or 'none').
+ - Each Job object is identified with a Job URI. The Job's "job-uri"
+ attribute contains the URI.
+ - Each Job object is also identified with Job ID which is a 32-bit,
+ positive integer. The Job's "job-id" attribute contains the Job
+ ID. The Job ID is only unique within the context of the Printer
+ object which created the Job object.
+ - Each Job object has a "job-printer-uri" attribute which contains
+ the URI of the Printer object that was used to create the Job
+ object. This attribute is used to determine the Printer object
+ that created a Job object when given only the URI for the Job
+ object. This linkage is necessary to determine the languages,
+ charsets, and operations which are supported on that Job (the
+ basis for such support comes from the creating Printer object).
+ - Each Printer object has a name (which is not necessarily unique).
+ The administrator chooses and sets this name through some
+ mechanism outside the scope of IPP/1.0 itself. The Printer
+ object's "printer-name" attribute contains the name.
+ - Each Job object has a name (which is not necessarily unique). The
+ client optionally supplies this name in the create request. If
+ the client does not supply this name, the Printer object generates
+ a name for the Job object. The Job object's "job-name" attribute
+ contains the name.
+
+3. IPP Operations
+
+ IPP objects support operations. An operation consists of a request
+ and a response. When a client communicates with an IPP object, the
+ client issues an operation request to the URI for that object.
+ Operation requests and responses have parameters that identify the
+ operation. Operations also have attributes that affect the run-time
+ characteristics of the operation (the intended target, localization
+ information, etc.). These operation-specific attributes are called
+ operation attributes (as compared to object attributes such as
+ Printer object attributes or Job object attributes). Each request
+ carries along with it any operation attributes, object attributes,
+ and/or document data required to perform the operation. Each request
+ requires a response from the object. Each response indicates success
+ or failure of the operation with a status code as a response
+ parameter. The response contains any operation attributes, object
+ attributes, and/or status messages generated during the execution of
+ the operation request.
+
+
+
+
+
+
+deBry, et al. Experimental [Page 18]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ This section describes the semantics of the IPP operations, both
+ requests and responses, in terms of the parameters, attributes, and
+ other data associated with each operation.
+
+ The IPP/1.0 Printer operations are:
+
+ Print-Job (section 3.2.1)
+ Print-URI (section 3.2.2)
+ Validate-Job (section 3.2.3)
+ Create-Job (section 3.2.4)
+ Get-Printer-Attributes (section 3.2.5)
+ Get-Jobs (section 3.2.6)
+
+ The Job operations are:
+
+ Send-Document (section 3.3.1)
+ Send-URI (section 3.3.2)
+ Cancel-Job (section 3.3.3)
+ Get-Job-Attributes (section 3.3.4)
+
+ The Send-Document and Send-URI Job operations are used to add a new
+ document to an existing multi-document Job object created using the
+ Create-Job operation.
+
+3.1 Common Semantics
+
+ All IPP operations require some common parameters and operation
+ attributes. These common elements and their semantic characteristics
+ are defined and described in more detail in the following sections.
+
+3.1.1 Required Parameters
+
+ Every operation request contains the following REQUIRED parameters:
+
+ - a "version-number",
+ - an "operation-id",
+ - a "request-id", and
+ - the attributes that are REQUIRED for that type of request.
+
+ Every operation response contains the following REQUIRED parameters:
+
+ - a "version-number",
+ - a "status-code",
+ - the "request-id" that was supplied in the corresponding request,
+ and
+ - the attributes that are REQUIRED for that type of response.
+
+
+
+
+
+deBry, et al. Experimental [Page 19]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ The encoding and transport document [RFC2565] defines special rules
+ for the encoding of these parameters. All other operation elements
+ are represented using the more generic encoding rules for attributes
+ and groups of attributes.
+
+3.1.2 Operation IDs and Request IDs
+
+ Each IPP operation request includes an identifying "operation-id"
+ value. Valid values are defined in the "operations-supported"
+ Printer attribute section (see section 4.4.13). The client specifies
+ which operation is being requested by supplying the correct
+ "operation-id" value.
+
+ In addition, every invocation of an operation is identified by a
+ "request-id" value. For each request, the client chooses the
+ "request-id" which MUST be an integer (possibly unique depending on
+ client requirements) in the range from 1 to 2**31 - 1 (inclusive).
+ This "request-id" allows clients to manage multiple outstanding
+ requests. The receiving IPP object copies all 32-bits of the client-
+ supplied "request-id" attribute into the response so that the client
+ can match the response with the correct outstanding request, even if
+ the "request-id" is out of range. If the request is terminated
+ before the complete "request-id" is received, the IPP object rejects
+ the request and returns a response with a "request-id" of 0.
+
+ Note: In some cases, the transport protocol underneath IPP might be a
+ connection oriented protocol that would make it impossible for a
+ client to receive responses in any order other than the order in
+ which the corresponding requests were sent. In such cases, the
+ "request-id" attribute would not be essential for correct protocol
+ operation. However, in other mappings, the operation responses can
+ come back in any order. In these cases, the "request-id" would be
+ essential.
+
+3.1.3 Attributes
+
+ Operation requests and responses are both composed of groups of
+ attributes and/or document data. The attributes groups are:
+
+ - Operation Attributes: These attributes are passed in the
+ operation and affect the IPP object's behavior while processing
+ the operation request and may affect other attributes or groups
+ of attributes. Some operation attributes describe the document
+ data associated with the print job and are associated with new
+ Job objects, however most operation attributes do not persist
+ beyond the life of the operation. The description of each
+ operation attribute includes conformance statements indicating
+ which operation attributes are REQUIRED and which are OPTIONAL
+
+
+
+deBry, et al. Experimental [Page 20]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ for an IPP object to support and which attributes a client MUST
+ supply in a request and an IPP object MUST supply in a response.
+ - Job Template Attributes: These attributes affect the processing
+ of a job. A client OPTIONALLY supplies Job Template Attributes
+ in a create request, and the receiving object MUST be prepared to
+ receive all supported attributes. The Job object can later be
+ queried to find out what Job Template attributes were originally
+ requested in the create request, and such attributes are returned
+ in the response as Job Object Attributes. The Printer object can
+ be queried about its Job Template attributes to find out what
+ type of job processing capabilities are supported and/or what the
+ default job processing behaviors are, though such attributes are
+ returned in the response as Printer Object Attributes. The
+ "ipp-attribute-fidelity" operation attribute affects processing
+ of all client-supplied Job Template attributes (see section 15
+ for a full description of "ipp-attribute-fidelity" and its
+ relationship to other attributes).
+ - Job Object Attributes: These attributes are returned in response
+ to a query operation directed at a Job object.
+ - Printer Object Attributes: These attributes are returned in
+ response to a query operation directed at a Printer object.
+ - Unsupported Attributes: In a create request, the client supplies
+ a set of Operation and Job Template attributes. If any of these
+ attributes or their values is unsupported by the Printer object,
+ the Printer object returns the set of unsupported attributes in
+ the response. Section 15 gives a full description of how Job
+ Template attributes supplied by the client in a create request
+ are processed by the Printer object and how unsupported
+ attributes are returned to the client. Because of extensibility,
+ any IPP object might receive a request that contains new or
+ unknown attributes or values for which it has no support. In such
+ cases, the IPP object processes what it can and returns the
+ unsupported attributes in the response.
+
+ Later in this section, each operation is formally defined by
+ identifying the allowed and expected groups of attributes for each
+ request and response. The model identifies a specific order for each
+ group in each request or response, but the attributes within each
+ group may be in any order, unless specified otherwise.
+
+ Each attribute specification includes the attribute's name followed
+ by the name of its attribute syntax(es) in parenthesizes. In
+ addition, each 'integer' attribute is followed by the allowed range
+ in parentheses, (m:n), for values of that attribute. Each 'text' or
+ 'name' attribute is followed by the maximum size in octets in
+ parentheses, (size), for values of that attribute. For more details
+ on attribute syntax notation, see the descriptions of these
+ attributes syntaxes in section 4.1.
+
+
+
+deBry, et al. Experimental [Page 21]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Note: Document data included in the operation is not strictly an
+ attribute, but it is treated as a special attribute group for
+ ordering purposes. The only operations that support supplying the
+ document data within an operation request are Print-Job and Send-
+ Document. There are no operation responses that include document
+ data.
+
+ Note: Some operations are REQUIRED for IPP objects to support; the
+ others are OPTIONAL (see section 5.2.2). Therefore, before using an
+ OPTIONAL operation, a client SHOULD first use the REQUIRED Get-
+ Printer-Attributes operation to query the Printer's "operations-
+ supported" attribute in order to determine which OPTIONAL Printer and
+ Job operations are actually supported. The client SHOULD NOT use an
+ OPTIONAL operation that is not supported. When an IPP object
+ receives a request to perform an operation it does not support, it
+ returns the 'server-error-operation-not-supported' status code (see
+ section 13.1.5.2). An IPP object is non-conformant if it does not
+ support a REQUIRED operation.
+
+3.1.4 Character Set and Natural Language Operation Attributes
+
+ Some Job and Printer attributes have values that are text strings and
+ names intended for human understanding rather than machine
+ understanding (see the 'text' and 'name' attribute syntax
+ descriptions in section 4.1). The following sections describe two
+ special Operation Attributes called "attributes-charset" and
+ "attributes-natural-language". These attributes are always part of
+ the Operation Attributes group. For most attribute groups, the order
+ of the attributes within the group is not important. However, for
+ these two attributes within the Operation Attributes group, the order
+ is critical. The "attributes-charset" attribute MUST be the first
+ attribute in the group and the "attributes-natural-language"
+ attribute MUST be the second attribute in the group. In other words,
+ these attributes MUST be supplied in every IPP request and response,
+ they MUST come first in the group, and MUST come in the specified
+ order. For job creation operations, the IPP Printer implementation
+ saves these two attributes with the new Job object as Job Description
+ attributes. For the sake of brevity in this document, these
+ operation attribute descriptions are not repeated with every
+ operation request and response, but have a reference back to this
+ section instead.
+
+3.1.4.1 Request Operation Attributes
+
+ The client MUST supply and the Printer object MUST support the
+ following REQUIRED operation attributes in every IPP/1.0 operation
+ request:
+
+
+
+
+deBry, et al. Experimental [Page 22]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ "attributes-charset" (charset):
+ This operation attribute identifies the charset (coded character
+ set and encoding method) used by any 'text' and 'name'
+ attributes that the client is supplying in this request. It
+ also identifies the charset that the Printer object MUST use (if
+ supported) for all 'text' and 'name' attributes and status
+ messages that the Printer object returns in the response to this
+ request. See Sections 4.1.1 and 4.1.2 for the specification of
+ the 'text' and 'name' attribute syntaxes.
+
+ All clients and IPP objects MUST support the 'utf-8' charset
+ [RFC2279] and MAY support additional charsets provided that they
+ are registered with IANA [IANA-CS]. If the Printer object does
+ not support the client supplied charset value, the Printer
+ object MUST reject the request, set the "attributes-charset" to
+ 'utf-8' in the response, and return the 'client-error-charset-
+ not-supported' status code and any 'text' or 'name' attributes
+ using the 'utf-8' charset. The Printer object MUST indicate the
+ charset(s) supported as the values of the "charset-supported"
+ Printer attribute (see Section 4.4.15), so that the client can
+ query to determine which charset(s) are supported.
+
+ Note to client implementers: Since IPP objects are only required
+ to support the 'utf-8' charset, in order to maximize
+ interoperability with multiple IPP object implementations, a
+ client may want to supply 'utf-8' in the "attributes-charset"
+ operation attribute, even though the client is only passing and
+ able to present a simpler charset, such as US-ASCII or ISO-
+ 8859-1. Then the client will have to filter out (or charset
+ convert) those characters that are returned in the response that
+ it cannot present to its user. On the other hand, if both the
+ client and the IPP objects also support a charset in common
+ besides utf-8, the client may want to use that charset in order
+ to avoid charset conversion or data loss.
+
+ See the 'charset' attribute syntax description in Section 4.1.7
+ for the syntax and semantic interpretation of the values of this
+ attribute and for example values.
+
+ "attributes-natural-language" (naturalLanguage):
+ This operation attribute identifies the natural language used by
+ any 'text' and 'name' attributes that the client is supplying in
+ this request. This attribute also identifies the natural
+ language that the Printer object SHOULD use for all 'text' and '
+ name' attributes and status messages that the Printer object
+ returns in the response to this request.
+
+
+
+
+
+deBry, et al. Experimental [Page 23]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ There are no REQUIRED natural languages required for the Printer
+ object to support. However, the Printer object's "generated-
+ natural-language-supported" attribute identifies the natural
+ languages supported by the Printer object and any contained Job
+ objects for all text strings generated by the IPP object. A
+ client MAY query this attribute to determine which natural
+ language(s) are supported for generated messages.
+
+ For any of the attributes for which the Printer object generates
+ text, i.e., for the "job-state-message", "printer-state-
+ message", and status messages (see Section 3.1.6), the Printer
+ object MUST be able to generate these text strings in any of its
+ supported natural languages. If the client requests a natural
+ language that is not supported, the Printer object MUST return
+ these generated messages in the Printer's configured natural
+ language as specified by the Printer's "natural-language-
+ configured" attribute" (see Section 4.4.16).
+
+ For other 'text' and 'name' attributes supplied by the client,
+ authentication system, operator, system administrator, or
+ manufacturer (i.e., for "job-originating-user-name", "printer-
+ name" (name), "printer-location" (text), "printer-info" (text),
+ and "printer-make-and-model" (text)), the Printer object is only
+ required to support the configured natural language of the
+ Printer identified by the Printer object's "natural-language-
+ configured" attribute, though support of additional natural
+ languages for these attributes is permitted.
+
+ For any 'text' or 'name' attribute in the request that is in a
+ different natural language than the value supplied in the
+ "attributes-natural-language" operation attribute, the client
+ MUST use the Natural Language Override mechanism (see sections
+ 4.1.1.2 and 4.1.2.2) for each such attribute value supplied.
+ The client MAY use the Natural Language Override mechanism
+ redundantly, i.e., use it even when the value is in the same
+ natural language as the value supplied in the "attributes-
+ natural-language" operation attribute of the request.
+
+ The IPP object MUST accept any natural language and any Natural
+ Language Override, whether the IPP object supports that natural
+ language or not (and independent of the value of the "ipp-
+ attribute-fidelity" Operation attribute). That is the IPP
+ object accepts all client supplied values no matter what the
+ values are in the Printer object's "generated-natural-language-
+ supported" attribute. That attribute, "generated-natural-
+ language-supported", only applies to generated messages,
+
+
+
+
+
+deBry, et al. Experimental [Page 24]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ not client supplied messages. The IPP object MUST remember that
+ natural language for all client-supplied attributes, and when
+ returning those attributes in response to a query, the IPP
+ object MUST indicate that natural language.
+
+ Each value whose attribute syntax type is 'text' or 'name' (see
+ sections 4.1.1 and 4.1.2) has an Associated Natural-Language.
+ This document does not specify how this association is stored in
+ a Printer or Job object. When such a value is encoded in a
+ request or response, the natural language is either implicit or
+ explicit:
+
+ - In the implicit case, the value contains only the
+ text/name value, and the language is specified by the
+ "attributes-natural-language" operation attribute in the
+ request or response (see sections 4.1.1.1
+ textWithoutLanguage and 4.1.2.1 nameWithoutLanguage).
+
+ - In the explicit case (also known as the Natural-Language
+ Override case), the value contains both the language and
+ the text/name value (see sections 4.1.1.2
+ textWithLanguage and 4.1.2.2 nameWithLanguage).
+
+ For example, the "job-name" attribute MAY be supplied by the
+ client in a create request. The text value for this attribute
+ will be in the natural language identified by the "attribute-
+ natural-language" attribute, or if different, as identified by
+ the Natural Language Override mechanism. If supplied, the IPP
+ object will use the value of the "job-name" attribute to
+ populate the Job object's "job-name" attribute. Whenever any
+ client queries the Job object's "job-name" attribute, the IPP
+ object returns the attribute as stored and uses the Natural
+ Language Override mechanism to specify the natural language, if
+ it is different from that reported in the "attributes-natural-
+ language" operation attribute of the response. The IPP object
+ MAY use the Natural Language Override mechanism redundantly,
+ i.e., use it even when the value is in the same natural language
+ as the value supplied in the "attributes-natural-language"
+ operation attribute of the response.
+
+ An IPP object MUST NOT reject a request based on a supplied
+ natural language in an "attributes-natural-language" Operation
+ attribute or in any attribute that uses the Natural Language
+ Override.
+
+ See the 'naturalLanguage' attribute syntax description in
+ section 4.1.8 for the syntax and semantic interpretation of the
+ values of this attribute and for example values.
+
+
+
+deBry, et al. Experimental [Page 25]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Clients SHOULD NOT supply 'text' or 'name' attributes that use an
+ illegal combination of natural language and charset. For example,
+ suppose a Printer object supports charsets 'utf-8', 'iso-8859-1', and
+ 'iso-8859-7'. Suppose also, that it supports natural languages 'en'
+ (English), 'fr' (French), and 'el' (Greek). Although the Printer
+ object supports the charset 'iso-8859-1' and natural language 'el',
+ it probably does not support the combination of Greek text strings
+ using the 'iso-8859-1' charset. The Printer object handles this
+ apparent incompatibility differently depending on the context in
+ which it occurs:
+
+ - In a create request: If the client supplies a text or name
+ attribute (for example, the "job-name" operation attribute) that
+ uses an apparently incompatible combination, it is a client
+ choice that does not affect the Printer object or its correct
+ operation. Therefore, the Printer object simply accepts the
+ client supplied value, stores it with the Job object, and
+ responds back with the same combination whenever the client (or
+ any client) queries for that attribute.
+ - In a query-type operation, like Get-Printer-Attributes: If the
+ client requests an apparently incompatible combination, the
+ Printer object responds (as described in section 3.1.4.2) using
+ the Printer's configured natural language rather than the natural
+ language requested by the client.
+
+ In either case, the Printer object does not reject the request
+ because of the apparent incompatibility. The potential incompatible
+ combination of charset and natural language can occur either at the
+ global operation level or at the Natural Language Override
+ attribute-by-attribute level. In addition, since the response always
+ includes explicit charset and natural language information, there is
+ never any question or ambiguity in how the client interprets the
+ response.
+
+3.1.4.2 Response Operation Attributes
+
+ The Printer object MUST supply and the client MUST support the
+ following REQUIRED operation attributes in every IPP/1.0 operation
+ response:
+
+ "attributes-charset" (charset):
+ This operation attribute identifies the charset used by any '
+ text' and 'name' attributes that the Printer object is returning
+ in this response. The value in this response MUST be the same
+ value as the "attributes-charset" operation attribute supplied
+ by the client in the request. If this is not possible
+
+
+
+
+
+deBry, et al. Experimental [Page 26]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ (i.e., the charset requested is not supported), the request
+ would have been rejected. See "attributes-charset" described in
+ Section 3.1.4.1 above.
+
+ If the Printer object supports more than just the 'utf-8'
+ charset, the Printer object MUST be able to code convert between
+ each of the charsets supported on a highest fidelity possible
+ basis in order to return the 'text' and 'name' attributes in the
+ charset requested by the client. However, some information loss
+ MAY occur during the charset conversion depending on the
+ charsets involved. For example, the Printer object may convert
+ from a UTF-8 'a' to a US-ASCII 'a' (with no loss of
+ information), from an ISO Latin 1 CAPITAL LETTER A WITH ACUTE
+ ACCENT to US-ASCII 'A' (losing the accent), or from a UTF-8
+ Japanese Kanji character to some ISO Latin 1 error character
+ indication such as '?', decimal code equivalent, or to the
+ absence of a character, depending on implementation.
+
+ Note: Whether an implementation that supports more than one
+ charset stores the data in the charset supplied by the client or
+ code converts to one of the other supported charsets, depends on
+ implementation. The strategy should try to minimize loss of
+ information during code conversion. On each response, such an
+ implementation converts from its internal charset to that
+ requested.
+
+ "attributes-natural-language" (naturalLanguage):
+ This operation attribute identifies the natural language used by
+ any 'text' and 'name' attributes that the IPP object is
+ returning in this response. Unlike the "attributes-charset"
+ operation attribute, the IPP object NEED NOT return the same
+ value as that supplied by the client in the request. The IPP
+ object MAY return the natural language of the Job object or the
+ Printer's configured natural language as identified by the
+ Printer object's "natural-language-configured" attribute, rather
+ than the natural language supplied by the client. For any '
+ text' or 'name' attribute or status message in the response that
+ is in a different natural language than the value returned in
+ the "attributes-natural-language" operation attribute, the IPP
+ object MUST use the Natural Language Override mechanism (see
+ sections 4.1.1.2 and 4.1.2.2) on each attribute value returned.
+ The IPP object MAY use the Natural Language Override mechanism
+ redundantly, i.e., use it even when the value is in the same
+ natural language as the value supplied in the "attributes-
+ natural-language" operation attribute of the response.
+
+
+
+
+
+
+deBry, et al. Experimental [Page 27]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+3.1.5 Operation Targets
+
+ All IPP operations are directed at IPP objects. For Printer
+ operations, the operation is always directed at a Printer object
+ using one of its URIs (i.e., one of the values in the Printer
+ object's "printer-uri-supported" attribute). Even if the Printer
+ object supports more than one URI, the client supplies only one URI
+ as the target of the operation. The client identifies the target
+ object by supplying the correct URI in the "printer-uri (uri)"
+ operation attribute.
+
+ For Job operations, the operation is directed at either:
+
+ - The Job object itself using the Job object's URI. In this case,
+ the client identifies the target object by supplying the correct
+ URI in the "job-uri (uri)" operation attribute.
+ - The Printer object that created the Job object using both the
+ Printer objects URI and the Job object's Job ID. Since the
+ Printer object that created the Job object generated the Job ID,
+ it MUST be able to correctly associate the client supplied Job ID
+ with the correct Job object. The client supplies the Printer
+ object's URI in the "printer-uri (uri)" operation attribute and
+ the Job object's Job ID in the "job-id (integer(1:MAX))"
+ operation attribute.
+
+ If the operation is directed at the Job object directly using the Job
+ object's URI, the client MUST NOT include the redundant "job-id"
+ operation attribute.
+
+ The operation target attributes are REQUIRED operation attributes
+ that MUST be included in every operation request. Like the charset
+ and natural language attributes (see section 3.1.4), the operation
+ target attributes are specially ordered operation attributes. In all
+ cases, the operation target attributes immediately follow the
+ "attributes-charset" and "attributes-natural-language" attributes
+ within the operation attribute group, however the specific ordering
+ rules are:
+
+ - In the case where there is only one operation target attribute
+ (i.e., either only the "printer-uri" attribute or only the "job-
+ uri" attribute), that attribute MUST be the third attribute in
+ the operation attributes group.
+ - In the case where Job operations use two operation target
+ attributes (i.e., the "printer-uri" and "job-id" attributes), the
+ "printer-uri" attribute MUST be the third attribute and the
+ "job-id" attribute MUST be the fourth attribute.
+
+
+
+
+
+deBry, et al. Experimental [Page 28]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ In all cases, the target URIs contained within the body of IPP
+ operation requests and responses must be in absolute format rather
+ than relative format (a relative URL identifies a resource with the
+ scope of the HTTP server, but does not include scheme, host or port).
+
+ The following rules apply to the use of port numbers in URIs that
+ identify IPP objects:
+
+ 1. If the URI scheme allows the port number to be explicitly
+ included in the URI string, and a port number is specified
+ within the URI, then that port number MUST be used by the client
+ to contact the IPP object.
+
+ 2. If the URI scheme allows the port number to be explicitly
+ included in the URI string, and a port number is not specified
+ within the URI, then default port number implied by that URI
+ scheme MUST be used by the client to contact the IPP object.
+
+ 3. If the URI scheme does not allow an explicit port number to be
+ specified within the URI, then the default port number implied
+ by that URI MUST be used by the client to contact the IPP
+ object.
+
+ Note: The IPP encoding and transport document [RFC2565] shows a
+ mapping of IPP onto HTTP/1.1 and defines a new default port number
+ for using IPP over HTTP/1.1.
+
+3.1.6 Operation Status Codes and Messages
+
+ Every operation response includes a REQUIRED "status-code" parameter
+ and an OPTIONAL "status-message" operation attribute. The "status-
+ code" provides information on the processing of a request. A
+ "status-message" attribute provides a short textual description of
+ the status of the operation. The status code is intended for use by
+ automata, and the status message is intended for the human end user.
+ If a response does include a "status-message" attribute, an IPP
+ client NEED NOT examine or display the message, however it SHOULD do
+ so in some implementation specific manner.
+
+ The "status-code" value is a numeric value that has semantic meaning.
+ The "status-code" syntax is similar to a "type2 enum" (see section
+ 4.1 on "Attribute Syntaxes") except that values can range only from
+ 0x0000 to 0x7FFF. Section 13 describes the status codes, assigns the
+ numeric values, and suggests a corresponding status message for each
+ status code. The "status-message" attribute's syntax is "text(255)".
+ A client implementation of IPP SHOULD convert status code values into
+ any localized message that has semantic meaning to the end user.
+
+
+
+
+deBry, et al. Experimental [Page 29]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ If the Printer object supports the "status-message" operation
+ attribute, the Printer object MUST be able to generate this message
+ in any of the natural languages identified by the Printer object's
+ "generated-natural-language-supported" attribute (see the
+ "attributes-natural-language" operation attribute specified in
+ section 3.1.4.1). As described in section 3.1.4.1 for any returned '
+ text' attribute, if there is a choice for generating this message,
+ the Printer object uses the natural language indicated by the value
+ of the "attributes-natural-language" in the client request if
+ supported, otherwise the Printer object uses the value in the Printer
+ object's own "natural-language-configured" attribute. If the Printer
+ object supports the "status-message" operation attribute, it SHOULD
+ use the REQUIRED 'utf-8' charset to return a status message for the
+ following error status codes (see section 13): 'client-error-bad-
+ request', 'client-error-charset-not-supported', 'server-error-
+ internal-error', 'server-error-operation-not-supported', and '
+ server-error-version-not-supported'. In this case, it MUST set the
+ value of the "attributes-charset" operation attribute to 'utf-8' in
+ the error response.
+
+3.1.7 Versions
+
+ Each operation request and response carries with it a "version-
+ number" parameter. Each value of the "version-number" is in the form
+ "X.Y" where X is the major version number and Y is the minor version
+ number. By including a version number in the client request, it
+ allows the client to identify which version of IPP it is interested
+ in using. If the IPP object does not support that version, the
+ object responds with a status code of 'server-error-version-not-
+ supported' along with the closest version number that is supported
+ (see section 13.1.5.4).
+
+ There is no version negotiation per se. However, if after receiving
+ a 'server-error-version-not-supported' status code from an IPP
+ object, there is nothing that prevents a client from trying again
+ with a different version number. In order to conform to IPP/1.0, an
+ implementation MUST support at least version '1.0'.
+
+ There is only one notion of "version number" that covers both IPP
+ Model and IPP Protocol changes. Thus the version number MUST change
+ when introducing a new version of the Model and Semantics document
+ [RFC2566] or a new version of the Encoding and Transport document
+ [RFC2565].
+
+ Changes to the major version number indicate structural or syntactic
+ changes that make it impossible for older version of IPP clients and
+ Printer objects to correctly parse and process the new or changed
+ attributes, operations and responses. If the major version number
+
+
+
+deBry, et al. Experimental [Page 30]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ changes, the minor version numbers is set to zero. As an example,
+ adding the "ipp-attribute-fidelity" attribute (if it had not been
+ part of version '1.0'), would have required a change to the major
+ version number. Items that might affect the changing of the major
+ version number include any changes to the Model and Semantics
+ document [RFC2566] or the Encoding and Transport [RFC2565] itself,
+ such as:
+
+ - reordering of ordered attributes or attribute sets
+ - changes to the syntax of existing attributes
+ - changing Operation or Job Template attributes from OPTIONAL to
+ REQUIRED and vice versa
+ - adding REQUIRED (for an IPP object to support) operation
+ attributes
+ - adding REQUIRED (for an IPP object to support) operation
+ attribute groups
+ - adding values to existing operation attributes
+ - adding REQUIRED operations
+
+ Changes to the minor version number indicate the addition of new
+ features, attributes and attribute values that may not be understood
+ by all IPP objects, but which can be ignored if not understood.
+ Items that might affect the changing of the minor version number
+ include any changes to the model objects and attributes but not the
+ encoding and transport rules [RFC2565] (except adding attribute
+ syntaxes). Examples of such changes are:
+
+ - grouping all extensions not included in a previous version into
+ a new version
+ - adding new attribute values
+ - adding new object attributes
+ - adding OPTIONAL (for an IPP object to support) operation
+ attributes (i.e., those attributes that an IPP object can ignore
+ without confusing clients)
+ - adding OPTIONAL (for an IPP object to support) operation
+ attribute groups (i.e., those attributes that an IPP object can
+ ignore without confusing clients)
+ - adding new attribute syntaxes
+ - adding OPTIONAL operations
+ - changing Job Description attributes or Printer Description
+ attributes from OPTIONAL to REQUIRED or vice versa.
+
+ The encoding of the "operation-id", the "version-number", the
+ "status-code", and the "request-id" MUST NOT change over any version
+ number (either major or minor). This rule guarantees that all future
+ versions will be backwards compatible with all previous versions (at
+ least for checking the "operation-id", the "version-number", and the
+ "request-id"). In addition, any protocol elements (attributes, error
+
+
+
+deBry, et al. Experimental [Page 31]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ codes, tags, etc.) that are not carried forward from one version to
+ the next are deprecated so that they can never be reused with new
+ semantics.
+
+ Implementations that support a certain major version NEED NOT support
+ ALL previous versions. As each new major version is defined (through
+ the release of a new specification), that major version will specify
+ which previous major versions MUST be supported in compliant
+ implementations.
+
+3.1.8 Job Creation Operations
+
+ In order to "submit a print job" and create a new Job object, a
+ client issues a create request. A create request is any one of
+ following three operation requests:
+
+ - The Print-Job Request: A client that wants to submit a print job
+ with only a single document uses the Print-Job operation. The
+ operation allows for the client to "push" the document data to
+ the Printer object by including the document data in the request
+ itself.
+
+ - The Print-URI Request: A client that wants to submit a print job
+ with only a single document (where the Printer object "pulls" the
+ document data instead of the client "pushing" the data to the
+ Printer object) uses the Print-URI operation. In this case, the
+ client includes in the request only a URI reference to the
+ document data (not the document data itself).
+
+ - The Create-Job Request: A client that wants to submit a print job
+ with multiple documents uses the Create-Job operation. This
+ operation is followed by an arbitrary number of Send-Document
+ and/or Send-URI operations (each creating another document for
+ the newly create Job object). The Send-Document operation
+ includes the document data in the request (the client "pushes"
+ the document data to the printer), and the Send-URI operation
+ includes only a URI reference to the document data in the request
+ (the Printer "pulls" the document data from the referenced
+ location). The last Send-Document or Send-URI request for a
+ given Job object includes a "last-document" operation attribute
+ set to 'true' indicating that this is the last request.
+
+ Throughout this model specification, the term "create request" is
+ used to refer to any of these three operation requests.
+
+ A Create-Job operation followed by only one Send-Document operation
+ is semantically equivalent to a Print-Job operation, however, for
+ performance reasons, the client SHOULD use the Print-Job operation
+
+
+
+deBry, et al. Experimental [Page 32]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ for all single document jobs. Also, Print-Job is a REQUIRED
+ operation (all implementations MUST support it) whereas Create-Job is
+ an OPTIONAL operation, hence some implementations might not support
+ it.
+
+ Job submission time is the point in time when a client issues a
+ create request. The initial state of every Job object is the '
+ pending' or 'pending-held' state. Later, the Printer object begins
+ processing the print job. At this point in time, the Job object's
+ state moves to 'processing'. This is known as job processing time.
+ There are validation checks that must be done at job submission time
+ and others that must be performed at job processing time.
+
+ At job submission time and at the time a Validate-Job operation is
+ received, the Printer MUST do the following:
+
+ 1. Process the client supplied attributes and either accept or
+ reject the request
+ 2. Validate the syntax of and support for the scheme of any client
+ supplied URI
+
+ At job submission time the Printer object MUST validate whether or
+ not the supplied attributes, attribute syntaxes, and values are
+ supported by matching them with the Printer object's corresponding
+ "xxx-supported" attributes. See section 3.2.1.2 for details. [ipp-
+ iig] presents suggested steps for an IPP object to either accept or
+ reject any request and additional steps for processing create
+ requests.
+
+ At job submission time the Printer object NEED NOT perform the
+ validation checks reserved for job processing time such as:
+
+ 1. Validating the document data
+ 2. Validating the actual contents of any client supplied URI
+ (resolve the reference and follow the link to the document data)
+
+ At job submission time, these additional job processing time
+ validation checks are essentially useless, since they require
+ actually parsing and interpreting the document data, are not
+ guaranteed to be 100% accurate, and MUST be done, yet again, at job
+ processing time. Also, in the case of a URI, checking for
+ availability at job submission time does not guarantee availability
+ at job processing time. In addition, at job processing time, the
+ Printer object might discover any of the following conditions that
+ were not detectable at job submission time:
+
+ - runtime errors in the document data,
+ - nested document data that is in an unsupported format,
+
+
+
+deBry, et al. Experimental [Page 33]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ - the URI reference is no longer valid (i.e., the server hosting
+ the document might be down), or
+ - any other job processing error
+
+ At job processing time, since the Printer object has already
+ responded with a successful status code in the response to the create
+ request, if the Printer object detects an error, the Printer object
+ is unable to inform the end user of the error with an operation
+ status code. In this case, the Printer, depending on the error, can
+ set the "job-state", "job-state-reasons", or "job-state-message"
+ attributes to the appropriate value(s) so that later queries can
+ report the correct job status.
+
+ Note: Asynchronous notification of events is outside the scope of
+ IPP/1.0.
+
+3.2 Printer Operations
+
+ All Printer operations are directed at Printer objects. A client
+ MUST always supply the "printer-uri" operation attribute in order to
+ identify the correct target of the operation.
+
+3.2.1 Print-Job Operation
+
+ This REQUIRED operation allows a client to submit a print job with
+ only one document and supply the document data (rather than just a
+ reference to the data). See Section 15 for the suggested steps for
+ processing create operations and their Operation and Job Template
+ attributes.
+
+3.2.1.1 Print-Job Request
+
+ The following groups of attributes are supplied as part of the
+ Print-Job Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1. The Printer object
+ MUST copy these values to the corresponding Job Description
+ attributes described in sections 4.3.23 and 4.3.24.
+
+ Target:
+ The "printer-uri" (uri) operation attribute which is the target
+ for this operation as described in section 3.1.5.
+
+
+
+
+
+deBry, et al. Experimental [Page 34]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+ "job-name" (name(MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It contains the client
+ supplied Job name. If this attribute is supplied by the client,
+ its value is used for the "job-name" attribute of the newly
+ created Job object. The client MAY automatically include any
+ information that will help the end-user distinguish amongst
+ his/her jobs, such as the name of the application program along
+ with information from the document, such as the document name,
+ document subject, or source file name. If this attribute is not
+ supplied by the client, the Printer generates a name to use in
+ the "job-name" attribute of the newly created Job object (see
+ Section 4.3.5).
+
+ "ipp-attribute-fidelity" (boolean):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. The value 'true' indicates
+ that total fidelity to client supplied Job Template attributes
+ and values is required, else the Printer object MUST reject the
+ Print-Job request. The value 'false' indicates that a
+ reasonable attempt to print the Job object is acceptable and the
+ Printer object MUST accept the Print-job request. If not
+ supplied, the Printer object assumes the value is 'false'. All
+ Printer objects MUST support both types of job processing. See
+ section 15 for a full description of "ipp-attribute-fidelity"
+ and its relationship to other attributes, especially the Printer
+ object's "pdl-override-supported" attribute.
+
+ "document-name" (name(MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It contains the client
+ supplied document name. The document name MAY be different than
+ the Job name. Typically, the client software automatically
+ supplies the document name on behalf of the end user by using a
+ file name or an application generated name. If this attribute
+ is supplied, its value can be used in a manner defined by each
+ implementation. Examples include: printed along with the Job
+ (job start sheet, page adornments, etc.), used by accounting or
+ resource tracking management tools, or even stored along with
+ the document as a document level attribute. IPP/1.0 does not
+ support the concept of document level attributes.
+
+
+
+
+
+
+deBry, et al. Experimental [Page 35]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ "document-format" (mimeMediaType) :
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. The value of this attribute
+ identifies the format of the supplied document data. If the
+ client does not supply this attribute, the Printer object
+ assumes that the document data is in the format defined by the
+ Printer object's "document-format-default" attribute. If the
+ client supplies this attribute, but the value is not supported
+ by the Printer object, i.e., the value is not one of the values
+ of the Printer object's "document-format-supported" attribute,
+ the Printer object MUST reject the request and return the '
+ client-error-document-format-not-supported' status code.
+
+ "document-natural-language" (naturalLanguage):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute. This attribute
+ specifies the natural language of the document for those
+ document-formats that require a specification of the natural
+ language in order to image the document unambiguously. There are
+ no particular values required for the Printer object to support.
+
+ "compression" (type3 keyword)
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute and the "compression-
+ supported" attribute (see section 4.4.29). The client supplied
+ "compression" operation attribute identifies the compression
+ algorithm used on the document data. If the client omits this
+ attribute, the Printer object MUST assume that the data is not
+ compressed. If the client supplies the attribute and the
+ Printer object supports the attribute, the Printer object uses
+ the corresponding decompression algorithm on the document data.
+ If the client supplies this attribute, but the value is not
+ supported by the Printer object, i.e., the value is not one of
+ the values of the Printer object's "compression-supported"
+ attribute, the Printer object MUST copy the attribute and its
+ value to the Unsupported Attributes response group, reject the
+ request, and return the 'client-error-attributes-or-values-not-
+ supported' status code.
+
+ "job-k-octets" (integer(0:MAX))
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute and the "job-k-
+ octets-supported" attribute (see section 4.4.30). The client
+ supplied "job-k-octets" operation attribute identifies the total
+ size of the document(s) in K octets being submitted (see section
+ 4.3.17 for the complete semantics). If the client supplies the
+
+
+
+
+
+deBry, et al. Experimental [Page 36]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ attribute and the Printer object supports the attribute, the
+ value of the attribute is used to populate the Job object's
+ "job-k-octets" Job Description attribute.
+
+ Note: For this attribute and the following two attributes
+ ("job-impressions", and "job-media-sheets"), if the client
+ supplies the attribute, but the Printer object does not support
+ the attribute, the Printer object ignores the client-supplied
+ value. If the client supplies the attribute and the Printer
+ supports the attribute, and the value is within the range of the
+ corresponding Printer object's "xxx-supported" attribute, the
+ Printer object MUST use the value to populate the Job object's
+ "xxx" attribute. If the client supplies the attribute and the
+ Printer supports the attribute, but the value is outside the
+ range of the corresponding Printer object's "xxx-supported"
+ attribute, the Printer object MUST copy the attribute and its
+ value to the Unsupported Attributes response group, reject the
+ request, and return the 'client-error-attributes-or-values-not-
+ supported' status code. If the client does not supply the
+ attribute, the Printer object MAY choose to populate the
+ corresponding Job object attribute depending on whether the
+ Printer object supports the attribute and is able to calculate
+ or discern the correct value.
+
+ "job-impressions" (integer(0:MAX))
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute and the "job-
+ impressions-supported" attribute (see section 4.4.31). The
+ client supplied "job-impressions" operation attribute identifies
+ the total size in number of impressions of the document(s) being
+ submitted (see section 4.3.18 for the complete semantics).
+
+ See note under "job-k-octets".
+
+ "job-media-sheets" (integer(0:MAX))
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute and the "job-media-
+ sheets-supported" attribute (see section 4.4.32). The client
+ supplied "job-media-sheets" operation attribute identifies the
+ total number of media sheets to be produced for this job (see
+ section 4.3.19 for the complete semantics).
+
+ See note under "job-k-octets".
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 37]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Group 2: Job Template Attributes
+
+ The client OPTIONALLY supplies a set of Job Template attributes
+ as defined in section 4.2. If the client is not supplying any
+ Job Template attributes in the request, the client SHOULD omit
+ Group 2 rather than sending an empty group. However, a Printer
+ object MUST be able to accept an empty group.
+
+ Group 3: Document Content
+
+ The client MUST supply the document data to be processed.
+
+ Note: In addition to the MANDATORY parameters required for every
+ operation request, the simplest Print-Job Request consists of just
+ the "attributes-charset" and "attributes-natural-language" operation
+ attributes; the "printer-uri" target operation attribute; the
+ Document Content and nothing else. In this simple case, the Printer
+ object:
+
+ - creates a new Job object (the Job object contains a single
+ document),
+ - stores a generated Job name in the "job-name" attribute in the
+ natural language and charset requested (see Section 3.1.4.1) (if
+ those are supported, otherwise using the Printer object's default
+ natural language and charset), and
+ - at job processing time, uses its corresponding default value
+ attributes for the supported Job Template attributes that were
+ not supplied by the client as IPP attribute or embedded
+ instructions in the document data.
+
+3.2.1.2 Print-Job Response
+
+ The Printer object MUST return to the client the following sets
+ of attributes as part of the Print-Job Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text) operation attribute as described in sections 14 and
+ 3.1.6. If the client supplies unsupported or conflicting Job
+ Template attributes or values, the Printer object MUST reject or
+ accept the Print-Job request depending on the whether the client
+ supplied a 'true' or 'false' value for the "ipp-attribute-
+ fidelity" operation attribute. See the Implementer's Guide
+ [ipp-iig] for a complete description of the suggested steps for
+ processing a create request.
+
+
+
+deBry, et al. Experimental [Page 38]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ This is a set of Operation and Job Template attributes supplied
+ by the client (in the request) that are not supported by the
+ Printer object or that conflict with one another (see the
+ Implementer's Guide [ipp-iig]). If the Printer object is not
+ returning any Unsupported Attributes in the response, the
+ Printer object SHOULD omit Group 2 rather than sending an empty
+ group. However, a client MUST be able to accept an empty group.
+
+ Unsupported attributes fall into three categories:
+
+ 1. The Printer object does not support the supplied attribute
+ (no matter what the attribute syntax or value).
+ 2. The Printer object does support the attribute, but does not
+ support some or all of the particular attribute syntaxes or
+ values supplied by the client (i.e., the Printer object does
+ not have those attribute syntaxes or values in its
+ corresponding "xxx-supported" attribute).
+ 3. The Printer object does support the attributes and values
+ supplied, but the particular values are in conflict with one
+ another, because they violate a constraint, such as not being
+ able to staple transparencies.
+
+ In the case of an unsupported attribute name, the Printer object
+ returns the client-supplied attribute with a substituted "out-
+ of-band" value of 'unsupported' indicating no support for the
+ attribute itself (see the beginning of section 4.1).
+
+ In the case of a supported attribute with one or more
+ unsupported attribute syntaxes or values, the Printer object
+ simply returns the client-supplied attribute with the
+ unsupported attribute syntaxes or values as supplied by the
+ client. This indicates support for the attribute, but no
+ support for that particular attribute syntax or value. If the
+ client supplies a multi-valued attribute with more than one
+ value and the Printer object supports the attribute but only
+ supports a subset of the client-supplied attribute syntaxes or
+ values, the Printer object MUST return only those attribute
+ syntaxes or values that are unsupported.
+
+ In the case of two (or more) supported attribute values that are
+ in conflict with one another (although each is supported
+ independently, the values conflict when requested together
+
+
+
+deBry, et al. Experimental [Page 39]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ within the same job), the Printer object MUST return all the
+ values that it ignores or substitutes to resolve the conflict,
+ but not any of the values that it is still using. The choice
+ for exactly how to resolve the conflict is implementation
+ dependent. See The Implementer's Guide [ipp-iig] for an
+ example.
+
+ In these three cases, the value of the "ipp-attribute-fidelity"
+ supplied by the client does not affect what the Printer object
+ returns. The value of "ipp-attribute-fidelity" only affects
+ whether the Print-Job operation is accepted or rejected. If the
+ job is accepted, the client may query the job using the Get-
+ Job-Attributes operation requesting the unsupported attributes
+ that were returned in the create response to see which
+ attributes were ignored (not stored on the Job object) and which
+ attributes were stored with other (substituted) values.
+
+ Group 3: Job Object Attributes
+
+ "job-uri" (uri):
+ The Printer object MUST return the Job object's URI by returning
+ the contents of the REQUIRED "job-uri" Job object attribute.
+ The client uses the Job object's URI when directing operations
+ at the Job object. The Printer object always uses its
+ configured security policy when creating the new URI. However,
+ if the Printer object supports more than one URI, the Printer
+ object also uses information about which URI was used in the
+ Print-Job Request to generated the new URI so that the new URI
+ references the correct access channel. In other words, if the
+ Print-Job Request comes in over a secure channel, the Printer
+ object MUST generate a Job URI that uses the secure channel as
+ well.
+
+ "job-id" (integer(1:MAX)):
+ The Printer object MUST return the Job object's Job ID by
+ returning the REQUIRED "job-id" Job object attribute. The
+ client uses this "job-id" attribute in conjunction with the
+ "printer-uri" attribute used in the Print-Job Request when
+ directing Job operations at the Printer object.
+
+ "job-state":
+ The Printer object MUST return the Job object's REQUIRED "job-
+ state" attribute. The value of this attribute (along with the
+ value of the next attribute "job-state-reasons") is taken from a
+ "snapshot" of the new Job object at some meaningful point in
+ time (implementation defined) between when the Printer object
+ receives the Print-Job Request and when the Printer object
+ returns the response.
+
+
+
+deBry, et al. Experimental [Page 40]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ "job-state-reasons":
+ The Printer object OPTIONALLY returns the Job object's OPTIONAL
+ "job-state-reasons" attribute. If the Printer object supports
+ this attribute then it MUST be returned in the response. If
+ this attribute is not returned in the response, the client can
+ assume that the "job-state-reasons" attribute is not supported
+ and will not be returned in a subsequent Job object query.
+
+ "job-state-message":
+ The Printer object OPTIONALLY returns the Job object's OPTIONAL
+ "job-state-message" attribute. If the Printer object supports
+ this attribute then it MUST be returned in the response. If
+ this attribute is not returned in the response, the client can
+ assume that the "job-state-message" attribute is not supported
+ and will not be returned in a subsequent Job object query.
+
+ "number-of-intervening-jobs":
+ The Printer object OPTIONALLY returns the Job object's OPTIONAL
+ "number-of-intervening-jobs" attribute. If the Printer object
+ supports this attribute then it MUST be returned in the
+ response. If this attribute is not returned in the response,
+ the client can assume that the "number-of-intervening-jobs"
+ attribute is not supported and will not be returned in a
+ subsequent Job object query.
+
+ Note: Since any printer state information which affects a job's
+ state is reflected in the "job-state" and "job-state-reasons"
+ attributes, it is sufficient to return only these attributes and
+ no specific printer status attributes.
+
+ Note: In addition to the MANDATORY parameters required for every
+ operation response, the simplest response consists of the just the
+ "attributes-charset" and "attributes-natural-language" operation
+ attributes and the "job-uri", "job-id", and "job-state" Job Object
+ Attributes. In this simplest case, the status code is "successful-
+ ok" and there is no "status-message" operation attribute.
+
+3.2.2 Print-URI Operation
+
+ This OPTIONAL operation is identical to the Print-Job operation
+ (section 3.2.1) except that a client supplies a URI reference to the
+ document data using the "document-uri" (uri) operation attribute (in
+ Group 1) rather than including the document data itself. Before
+ returning the response, the Printer MUST validate that the Printer
+ supports the retrieval method (e.g., http, ftp, etc.) implied by the
+ URI, and MUST check for valid URI syntax. If the client-supplied URI
+ scheme is not supported, i.e. the value is not in the Printer
+ object's "referenced-uri-scheme-supported" attribute, the Printer
+
+
+
+deBry, et al. Experimental [Page 41]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ object MUST reject the request and return the 'client-error-uri-
+ scheme-not-supported' status code. See The Implementer's Guide
+ [ipp-iig] for suggested additional checks. The Printer NEED NOT
+ follow the reference and validate the contents of the reference.
+
+ If the Printer object supports this operation, it MUST support the
+ "reference-uri-schemes-supported" Printer attribute (see section
+ 4.4.24).
+
+ It is up to the IPP object to interpret the URI and subsequently
+ "pull" the document from the source referenced by the URI string.
+
+3.2.3 Validate-Job Operation
+
+ This REQUIRED operation is similar to the Print-Job operation
+ (section 3.2.1) except that a client supplies no document data and
+ the Printer allocates no resources (i.e., it does not create a new
+ Job object). This operation is used only to verify capabilities of a
+ printer object against whatever attributes are supplied by the client
+ in the Validate-Job request. By using the Validate-Job operation a
+ client can validate that an identical Print-Job operation (with the
+ document data) would be accepted. The Validate-Job operation also
+ performs the same security negotiation as the Print-Job operation
+ (see section 8), so that a client can check that the client and
+ Printer object security requirements can be met before performing a
+ Print-Job operation.
+
+ Note: The Validate-Job operation does not accept a "document-uri"
+ attribute in order to allow a client to check that the same Print-URI
+ operation will be accepted, since the client doesn't send the data
+ with the Print-URI operation. The client SHOULD just issue the
+ Print-URI request.
+
+ The Printer object returns the same status codes, Operation
+ Attributes (Group 1) and Unsupported Attributes (Group 2) as the
+ Print-Job operation. However, no Job Object Attributes (Group 3) are
+ returned, since no Job object is created.
+
+3.2.4 Create-Job Operation
+
+ This OPTIONAL operation is similar to the Print-Job operation
+ (section 3.2.1) except that in the Create-Job request, a client does
+ not supply document data or any reference to document data. Also,
+ the client does not supply any of the "document-name", "document-
+ format", "compression", or "document-natural-language" operation
+ attributes. This operation is followed by one or more Send-Document
+ or Send-URI operations. In each of those operation requests, the
+
+
+
+
+deBry, et al. Experimental [Page 42]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ client OPTIONALLY supplies the "document-name", "document-format",
+ and "document-natural-language" attributes for each document in the
+ multi-document Job object.
+
+ If a Printer object supports the Create-Job operation, it MUST also
+ support the Send-Document operation and also MAY support the Send-URI
+ operation.
+
+ If the Printer object supports this operation, it MUST support the
+ "multiple-operation-time-out" Printer attribute (see section 4.4.28).
+
+
+3.2.5 Get-Printer-Attributes Operation
+
+ This REQUIRED operation allows a client to request the values of the
+ attributes of a Printer object. In the request, the client supplies
+ the set of Printer attribute names and/or attribute group names in
+ which the requester is interested. In the response, the Printer
+ object returns a corresponding attribute set with the appropriate
+ attribute values filled in.
+
+ For Printer objects, the possible names of attribute groups are:
+
+ - 'job-template': all of the Job Template attributes that apply to
+ a Printer object (the last two columns of the table in Section
+ 4.2).
+ - 'printer-description': the attributes specified in Section 4.4.
+ - 'all': the special group 'all' that includes all supported
+ attributes.
+
+ Since a client MAY request specific attributes or named groups, there
+ is a potential that there is some overlap. For example, if a client
+ requests, 'printer-name' and 'all', the client is actually requesting
+ the "printer-name" attribute twice: once by naming it explicitly, and
+ once by inclusion in the 'all' group. In such cases, the Printer
+ object NEED NOT return each attribute only once in the response even
+ if it is requested multiple times. The client SHOULD NOT request the
+ same attribute in multiple ways.
+
+ It is NOT REQUIRED that a Printer object support all attributes
+ belonging to a group (since some attributes are OPTIONAL). However,
+ it is REQUIRED that each Printer object support all group names.
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 43]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+3.2.5.1 Get-Printer-Attributes Request
+
+ The following sets of attributes are part of the Get-Printer-
+ Attributes Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ attributes-charset" and "attributes-natural-language" butes as
+ described in section 3.1.4.1.
+
+ Target:
+ The "printer-uri" (uri) operation attribute which is the target
+ for this operation as described in section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+ "requested-attributes" (1setOf keyword) :
+ The client OPTIONALLY supplies a set of attribute names and/or
+ attribute group names in whose values the requester is
+ interested. The Printer object MUST support this attribute. If
+ the client omits this attribute, the Printer MUST respond as if
+ this attribute had been supplied with a value of 'all'.
+
+ "document-format" (mimeMediaType) :
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. This attribute is useful
+ for a Printer object to determine the set of supported attribute
+ values that relate to the requested document format. The
+ Printer object MUST return the attributes and values that it
+ uses to validate a job on a create or Validate-Job operation in
+ which this document format is supplied. The Printer object
+ SHOULD return only (1) those attributes that are supported for
+ the specified format and (2) the attribute values that are
+ supported for the specified document format. By specifying the
+ document format, the client can get the Printer object to
+ eliminate the attributes and values that are not supported for a
+ specific document format. For example, a Printer object might
+ have multiple interpreters to support both '
+ application/postscript' (for PostScript) and 'text/plain' (for
+ text) documents. However, for only one of those interpreters
+ might the Printer object be able to support "number-up" with
+ values of '1', '2', and '4'. For the other interpreter it might
+ be able to only support "number-up" with a value of '1'. Thus a
+
+
+
+
+
+deBry, et al. Experimental [Page 44]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ client can use the Get-Printer-Attributes operation to obtain
+ the attributes and values that will be used to accept/reject a
+ create job operation.
+
+ If the Printer object does not distinguish between different
+ sets of supported values for each different document format when
+ validating jobs in the create and Validate-Job operations, it
+ MUST NOT distinguish between different document formats in the
+ Get-Printer-Attributes operation. If the Printer object does
+ distinguish between different sets of supported values for each
+ different document format specified by the client, this
+ specialization applies only to the following Printer object
+ attributes:
+
+ - Printer attributes that are Job Template attributes ("xxx-
+ default" "xxx-supported", and "xxx-ready" in the Table in
+ Section 4.2),
+ - "pdl-override-supported",
+ - "compression-supported",
+ - "job-k-octets-supported",
+ - "job-impressions-supported,
+ - "job-media-sheets-supported"
+ - "printer-driver-installer",
+ - "color-supported", and
+ - "reference-uri-schemes-supported"
+
+ The values of all other Printer object attributes (including
+ "document-format-supported") remain invariant with respect to
+ the client supplied document format (except for new Printer
+ description attribute as registered according to section 6.2).
+
+ If the client omits this "document-format" operation attribute,
+ the Printer object MUST respond as if the attribute had been
+ supplied with the value of the Printer object's "document-
+ format-default" attribute. It is recommended that the client
+ always supply a value for "document-format", since the Printer
+ object's "document-format-default" may be 'application/octet-
+ stream', in which case the returned attributes and values are
+ for the union of the document formats that the Printer can
+ automatically sense. For more details, see the description of
+ the 'mimeMediaType' attribute syntax in section 4.1.9.
+
+ If the client supplies a value for the "document-format"
+ Operation attribute that is not supported by the Printer, i.e.,
+ is not among the values of the Printer object's "document-
+ format-supported" attribute, the Printer object MUST reject the
+ operation and return the 'client-error-document-format-not-
+ supported' status code.
+
+
+
+deBry, et al. Experimental [Page 45]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+3.2.5.2 Get-Printer-Attributes Response
+
+ The Printer object returns the following sets of attributes as part
+ of the Get-Printer-Attributes Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text) operation attribute as described in section 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ This is a set of Operation attributes supplied by the client (in
+ the request) that are not supported by the Printer object or
+ that conflict with one another (see sections 3.2.1.2 and 16).
+ The response NEED NOT contain the "requested-attributes"
+ operation attribute with any supplied values (attribute
+ keywords) that were requested by the client but are not
+ supported by the IPP object. If the Printer object is not
+ returning any Unsupported Attributes in the response, the
+ Printer object SHOULD omit Group 2 rather than sending an empty
+ group. However, a client MUST be able to accept an empty group.
+
+ Group 3: Printer Object Attributes
+
+ This is the set of requested attributes and their current
+ values. The Printer object ignores (does not respond with) any
+ requested attribute which is not supported. The Printer object
+ MAY respond with a subset of the supported attributes and
+ values, depending on the security policy in force. However, the
+ Printer object MUST respond with the 'unknown' value for any
+ supported attribute (including all REQUIRED attributes) for
+ which the Printer object does not know the value. Also the
+ Printer object MUST respond with the 'no-value' for any
+ supported attribute (including all REQUIRED attributes) for
+ which the system administrator has not configured a value. See
+ the description of the "out-of-band" values in the beginning of
+ Section 4.1.
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 46]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+3.2.6 Get-Jobs Operation
+
+ This REQUIRED operation allows a client to retrieve the list of Job
+ objects belonging to the target Printer object. The client may also
+ supply a list of Job attribute names and/or attribute group names. A
+ group of Job object attributes will be returned for each Job object
+ that is returned.
+
+ This operation is similar to the Get-Job-Attributes operation, except
+ that this Get-Jobs operation returns attributes from possibly more
+ than one object (see the description of Job attribute group names in
+ section 3.3.4).
+
+3.2.6.1 Get-Jobs Request
+
+ The client submits the Get-Jobs request to a Printer object.
+
+ The following groups of attributes are part of the Get-Jobs Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1.
+
+ Target:
+ The "printer-uri" (uri) operation attribute which is the target
+ for this operation as described in section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+ "limit" (integer(1:MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It is an integer value that
+ indicates a limit to the number of Job objects returned. The
+ limit is a "stateless limit" in that if the value supplied by
+ the client is 'N', then only the first 'N' jobs are returned in
+ the Get-Jobs Response. There is no mechanism to allow for the
+ next 'M' jobs after the first 'N' jobs. If the client does not
+ supply this attribute, the Printer object responds with all
+ applicable jobs.
+
+ "requested-attributes" (1setOf keyword):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It is a set of Job
+ attribute names and/or attribute groups names in whose values
+
+
+
+deBry, et al. Experimental [Page 47]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ the requester is interested. This set of attributes is returned
+ for each Job object that is returned. The allowed attribute
+ group names are the same as those defined in the Get-Job-
+ Attributes operation in section 3.3.4. If the client does not
+ supply this attribute, the Printer MUST respond as if the client
+ had supplied this attribute with two values: 'job-uri' and '
+ job-id'.
+
+ "which-jobs" (type2 keyword):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It indicates which Job
+ objects MUST be returned by the Printer object. The values for
+ this attribute are:
+
+ 'completed': This includes any Job object whose state is
+ 'completed', 'canceled', or 'aborted'.
+ 'not-completed': This includes any Job object whose state is '
+ pending', 'processing', 'processing-stopped', or 'pending-
+ held'.
+
+ A Printer object MUST support both values. However, if the
+ mentation does not keep jobs in the 'completed', 'canceled', '
+ aborted' states, then it returns no jobs when the 'completed'
+ value is supplied.
+
+ If a client supplies some other value, the Printer object MUST
+ copy the attribute and the unsupported value to the Unsupported
+ Attributes response group, reject the request, and return the '
+ client-error-attributes-or-values-not-supported' status code.
+
+ If the client does not supply this attribute, the Printer object
+ MUST respond as if the client had supplied the attribute with a
+ value of 'not-completed'.
+
+ "my-jobs" (boolean):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It indicates whether all
+ jobs or just the jobs submitted by the requesting user of this
+ request MUST be returned by the Printer object. If the client
+ does not supply this attribute, the Printer object MUST respond
+ as if the client had supplied the attribute with a value of '
+ false', i.e., all jobs. The means for authenticating the
+ requesting user and matching the jobs is described in section 8.
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 48]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+3.2.6.2 Get-Jobs Response
+
+ The Printer object returns all of the Job objects that match the
+ criteria as defined by the attribute values supplied by the client in
+ the request. It is possible that no Job objects are returned since
+ there may literally be no Job objects at the Printer, or there may be
+ no Job objects that match the criteria supplied by the client. If
+ the client requests any Job attributes at all, there is a set of Job
+ Object Attributes returned for each Job object.
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text) operation attribute as described in sections 14 and
+ 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ This is a set of Operation attributes supplied by the client (in
+ the request) that are not supported by the Printer object or
+ that conflict with one another (see sections 3.2.1.2 and the
+ Implementer's Guide [ipp-iig]). The response NEED NOT contain
+ the "requested-attributes" operation attribute with any supplied
+ values (attribute keywords) that were requested by the client
+ but are not supported by the IPP object. If the Printer object
+ is not returning any Unsupported Attributes in the response, the
+ Printer object SHOULD omit Group 2 rather than sending an empty
+ group. However, a client MUST be able to accept an empty group.
+
+ Groups 3 to N: Job Object Attributes
+
+ The Printer object responds with one set of Job Object
+ Attributes for each returned Job object. The Printer object
+ ignores (does not respond with) any requested attribute or value
+ which is not supported or which is restricted by the security
+ policy in force, including whether the requesting user is the
+ user that submitted the job (job originating user) or not (see
+ section 8). However, the Printer object MUST respond with the '
+ unknown' value for any supported attribute (including all
+ REQUIRED attributes) for which the Printer object does not know
+
+
+
+
+
+deBry, et al. Experimental [Page 49]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ the value, unless it would violate the security policy. See the
+ description of the "out-of-band" values in the beginning of
+ Section 4.1.
+
+ Jobs are returned in the following order:
+
+ - If the client requests all 'completed' Jobs (Jobs in the '
+ completed', 'aborted', or 'canceled' states), then the Jobs
+ are returned newest to oldest (with respect to actual
+ completion time)
+ - If the client requests all 'not-completed' Jobs (Jobs in the
+ 'pending', 'processing', 'pending-held', and 'processing-
+ stopped' states), then Jobs are returned in relative
+ chronological order of expected time to complete (based on
+ whatever scheduling algorithm is configured for the Printer
+ object).
+
+3.3 Job Operations
+
+ All Job operations are directed at Job objects. A client MUST always
+ supply some means of identifying the Job object in order to identify
+ the correct target of the operation. That job identification MAY
+ either be a single Job URI or a combination of a Printer URI with a
+ Job ID. The IPP object implementation MUST support both forms of
+ identification for every job.
+
+3.3.1 Send-Document Operation
+
+ This OPTIONAL operation allows a client to create a multi-document
+ Job object that is initially "empty" (contains no documents). In the
+ Create-Job response, the Printer object returns the Job object's URI
+ (the "job-uri" attribute) and the Job object's 32-bit identifier (the
+ "job-id" attribute). For each new document that the client desires
+ to add, the client uses a Send-Document operation. Each Send-
+ Document Request contains the entire stream of document data for one
+ document.
+
+ Since the Create-Job and the send operations (Send-Document or Send-
+ URI operations) that follow could occur over an arbitrarily long
+ period of time for a particular job, a client MUST send another send
+ operation within an IPP Printer defined minimum time interval after
+ the receipt of the previous request for the job. If a Printer object
+ supports multiple document jobs, the Printer object MUST support the
+ "multiple-operation-time-out" attribute (see section 4.4.28). This
+ attribute indicates the minimum number of seconds the Printer object
+ will wait for the next send operation before taking some recovery
+ action.
+
+
+
+
+deBry, et al. Experimental [Page 50]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ An IPP object MUST recover from an errant client that does not supply
+ a send operation, sometime after the minimum time interval specified
+ by the Printer object's "multiple-operation-time-out" attribute.
+ Such recovery MAY include any of the following or other recovery
+ actions:
+
+ 1. Assume that the Job is an invalid job, start the process of
+ changing the job state to 'aborted', add the 'aborted-by-system'
+ value to the job's "job-state-reasons" attribute (see section
+ 4.3.8), if supported, and clean up all resources associated with
+ the Job. In this case, if another send operation is finally
+ received, the Printer responds with an "client-error-not-
+ possible" or "client-error-not-found" depending on whether or
+ not the Job object is still around when the send operation
+ finally arrives.
+ 2. Assume that the last send operation received was in fact the
+ last document (as if the "last-document" flag had been set to '
+ true'), close the Job object, and proceed to process it (i.e.,
+ move the Job's state to 'pending').
+ 3. Assume that the last send operation received was in fact the
+ last document, close the Job, but move it to the 'pending-held'
+ and add the 'submission-interrupted' value to the job's "job-
+ state-reasons" attribute (see section 4.3.8), if supported.
+ This action allows the user or an operator to determine whether
+ to continue processing the Job by moving it back to the '
+ pending' state or to cancel the job.
+
+ Each implementation is free to decide the "best" action to take
+ depending on local policy, whether any documents have been added,
+ whether the implementation spools jobs or not, and/or any other piece
+ of information available to it. If the choice is to abort the Job
+ object, it is possible that the Job object may already have been
+ processed to the point that some media sheet pages have been printed.
+
+3.3.1.1 Send-Document Request
+
+ The following attribute sets are part of the Send-Document Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1.
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 51]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Target:
+ Either (1) the "printer-uri" (uri) plus "job-id"
+ (integer(1:MAX))or (2) the "job-uri" (uri) operation
+ attribute(s) which define the target for this operation as
+ described in section 3.1.5.
+
+ Requesting User Name:
+ "requesting-user-name" (name(MAX)) attribute SHOULD be supplied
+ by the client as described in section 8.3.
+
+ "document-name" (name(MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It contains the client
+ supplied document name. The document name MAY be different than
+ the Job name. It might be helpful, but NEED NOT be unique
+ across multiple documents in the same Job. Typically, the
+ client software automatically supplies the document name on
+ behalf of the end user by using a file name or an application
+ generated name. See the description of the "document-name"
+ operation attribute in the Print-Job Request (section 3.2.1.1)
+ for more information about this attribute
+
+ "document-format" (mimeMediaType):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. The value of this attribute
+ identifies the format of the supplied document data. If the
+ client does not supply this attribute, the Printer object
+ assumes that the document data is in the format defined by the
+ Printer object's "document-format-default" attribute. If the
+ client supplies this attribute, but the value is not supported
+ by the Printer object, i.e., the value is not one of the values
+ of the Printer object's "document-format-supported" attribute,
+ the Printer object MUST reject the request and return the '
+ client-error-document-format-not-supported' status code.
+
+ "document-natural-language" (naturalLanguage):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute. This attribute
+ specifies the natural language of the document for those
+ document-formats that require a specification of the natural
+ language in order to image the document unambiguously. There
+ are no particular values required for the Printer object to
+ support.
+
+ "compression" (type3 keyword)
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute and the "compression-
+ supported" attribute (see section 4.4.29). The client supplied
+
+
+
+deBry, et al. Experimental [Page 52]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ "compression" operation attribute identifies the compression
+ algorithm used on the document data. If the client omits this
+ attribute, the Printer object MUST assume that the data is not
+ compressed. If the client supplies the attribute and the
+ Printer object supports the attribute, the Printer object MUST
+ use the corresponding decompression algorithm on the document
+ data. If the client supplies this attribute, but the value is
+ not supported by the Printer object, i.e., the value is not one
+ of the values of the Printer object's "compression-supported"
+ attribute, the Printer object MUST copy the attribute and its
+ value to the Unsupported Attributes response group, reject the
+ request, and return the 'client-error-attributes-or-values-not-
+ supported' status code.
+
+ "last-document" (boolean):
+ The client MUST supply this attribute. The Printer object MUST
+ support this attribute. It is a boolean flag that is set to '
+ true' if this is the last document for the Job, 'false'
+ otherwise.
+
+ Group 2: Document Content
+
+ The client MUST supply the document data if the "last-document"
+ flag is set to 'false'. However, since a client might not know
+ that the previous document sent with a Send-Document (or Send-
+ URI) operation was the last document (i.e., the "last-document"
+ attribute was set to 'false'), it is legal to send a Send-
+ Document request with no document data where the "last-document"
+ flag is set to 'true'. Such a request MUST NOT increment the
+ value of the Job object's "number-of-documents" attribute, since
+ no real document was added to the job.
+
+3.3.1.2 Send-Document Response
+
+ The following sets of attributes are part of the Send-Document
+ Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text) operation attribute as described in sections 14 and
+ 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2.
+
+
+
+deBry, et al. Experimental [Page 53]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Group 2: Unsupported Attributes
+
+ This is a set of Operation attributes supplied by the client (in
+ the request) that are not supported by the Printer object or
+ that conflict with one another (see sections 3.2.1.2 and the
+ Implementer's Guide [ipp-iig]). If the Printer object is not
+ returning any Unsupported Attributes in the response, the
+ Printer object SHOULD omit Group 2 rather than sending an empty
+ group. However, a client MUST be able to accept an empty group.
+
+ Group 3: Job Object Attributes
+
+ This is the same set of attributes as described in the Print-Job
+ response (see section 3.2.1.2).
+
+3.3.2 Send-URI Operation
+
+ This OPTIONAL operation is identical to the Send-Document operation
+ (see section 3.3.1) except that a client MUST supply a URI reference
+ ("document-uri" operation attribute) rather than the document data
+ itself. If a Printer object supports this operation, clients can use
+ both Send-URI or Send-Document operations to add new documents to an
+ existing multi-document Job object. However, if a client needs to
+ indicate that the previous Send-URI or Send-Document was the last
+ document, the client MUST use the Send-Document operation with no
+ document data and the "last-document" flag set to 'true' (rather than
+ using a Send-URI operation with no "document-uri" operation
+ attribute).
+
+ If a Printer object supports this operation, it MUST also support the
+ Print-URI operation (see section 3.2.2).
+
+ The Printer object MUST validate the syntax and URI scheme of the
+ supplied URI before returning a response, just as in the Print-URI
+ operation.
+
+3.3.3 Cancel-Job Operation
+
+ This REQUIRED operation allows a client to cancel a Print Job from
+ the time the job is created up to the time it is completed, canceled,
+ or aborted. Since a Job might already be printing by the time a
+ Cancel-Job is received, some media sheet pages might be printed
+ before the job is actually terminated.
+
+3.3.3.1 Cancel-Job Request
+
+ The following groups of attributes are part of the Cancel-Job
+ Request:
+
+
+
+deBry, et al. Experimental [Page 54]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1.
+
+ Target:
+ Either (1) the "printer-uri" (uri) plus "job-id"
+ (integer(1:MAX))or (2) the "job-uri" (uri) operation
+ attribute(s) which define the target for this operation as
+ described in section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+ "message" (text(127)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute. It is a message to
+ the operator. This "message" attribute is not the same as the
+ "job-message-from-operator" attribute. That attribute is used
+ to report a message from the operator to the end user that
+ queries that attribute. This "message" operation attribute is
+ used to send a message from the client to the operator along
+ with the operation request. It is an implementation decision of
+ how or where to display this message to the operator (if at
+ all).
+
+3.3.3.2 Cancel-Job Response
+
+ The following sets of attributes are part of the Cancel-Job Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text) operation attribute as described in sections 14 and
+ 3.1.6.
+
+ If the job is already in the 'completed', 'aborted', or '
+ canceled' state, or the 'process-to-stop-point' value is set in
+ the Job's "job-state-reasons" attribute, the Printer object MUST
+ reject the request and return the 'client-error-not-possible'
+ error status code.
+
+
+
+
+
+
+deBry, et al. Experimental [Page 55]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ This is a set of Operation attributes supplied by the client (in
+ the request) that are not supported by the Printer object or
+ that conflict with one another (see section 3.2.1.2 and the
+ Implementer's Guide [ipp-iig]). If the Printer object is not
+ returning any Unsupported Attributes in the response, the
+ Printer object SHOULD omit Group 2 rather than sending an empty
+ group. However, a client MUST be able to accept an empty group.
+
+ Once a successful response has been sent, the implementation
+ guarantees that the Job will eventually end up in the 'canceled'
+ state. Between the time of the Cancel-Job operation is accepted and
+ when the job enters the 'canceled' job-state (see section 4.3.7), the
+ "job-state-reasons" attribute SHOULD contain the 'processing-to-
+ stop-point' value which indicates to later queries that although the
+ Job might still be 'processing', it will eventually end up in the '
+ canceled' state, not the 'completed' state.
+
+3.3.4 Get-Job-Attributes Operation
+
+ This REQUIRED operation allows a client to request the values of
+ attributes of a Job object and it is almost identical to the Get-
+ Printer-Attributes operation (see section 3.2.5). The only
+ differences are that the operation is directed at a Job object rather
+ than a Printer object, there is no "document-format" operation
+ attribute used when querying a Job object, and the returned attribute
+ group is a set of Job object attributes rather than a set of Printer
+ object attributes.
+
+ For Jobs, the possible names of attribute groups are:
+
+ - 'job-template': all of the Job Template attributes that apply to a
+ Job object (the first column of the table in Section 4.2).
+ - 'job-description': all of the Job Description attributes specified
+ in Section 4.3.
+ - 'all': the special group 'all' that includes all supported
+ attributes.
+
+ Since a client MAY request specific attributes or named groups, there
+ is a potential that there is some overlap. For example, if a client
+ requests, 'job-name' and 'job-description', the client is actually
+ requesting the "job-name" attribute once by naming it explicitly, and
+ once by inclusion in the 'job-description' group. In such cases, the
+
+
+
+deBry, et al. Experimental [Page 56]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Printer object NEED NOT return the attribute only once in the
+ response even if it is requested multiple times. The client SHOULD
+ NOT request the same attribute in multiple ways.
+
+ It is NOT REQUIRED that a Job object support all attributes belonging
+ to a group (since some attributes are OPTIONAL). However it is
+ REQUIRED that each Job object support all group names.
+
+3.3.4.1 Get-Job-Attributes Request
+
+ The following groups of attributes are part of the Get-Job-Attributes
+ Request when the request is directed at a Job object:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1.
+
+ Target:
+ Either (1) the "printer-uri" (uri) plus "job-id"
+ (integer(1:MAX)) or (2) the "job-uri" (uri) operation
+ attribute(s) which define the target for this operation as
+ described in section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+ "requested-attributes" (1setOf keyword) :
+ The client OPTIONALLY supplies this attribute. The IPP object
+ MUST support this attribute. It is a set of attribute names
+ and/or attribute group names in whose values the requester is
+ interested. If the client omits this attribute, the IPP object
+ MUST respond as if this attribute had been supplied with a value
+ of 'all'.
+
+3.3.4.2 Get-Job-Attributes Response
+
+ The Printer object returns the following sets of attributes as part
+ of the Get-Job-Attributes Response:
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 57]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text) operation attribute as described in sections 14 and
+ 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2. The "attributes-
+ natural-language" MAY be the natural language of the Job object,
+ rather than the one requested.
+
+ Group 2: Unsupported Attributes
+
+ This is a set of Operation attributes supplied by the client (in
+ the request) that are not supported by the Printer object or
+ that conflict with one another (see sections 3.2.1.2 and the
+ Implementer's Guide [ipp-iig]). The response NEED NOT contain
+ the "requested-attributes" operation attribute with any supplied
+ values (attribute keywords) that were requested by the client
+ but are not supported by the IPP object. If the Printer object
+ is not returning any Unsupported Attributes in the response, the
+ Printer object SHOULD omit Group 2 rather than sending an empty
+ group. However, a client MUST be able to accept an empty group.
+
+ Group 3: Job Object Attributes
+
+ This is the set of requested attributes and their current
+ values. The IPP object ignores (does not respond with) any
+ requested attribute or value which is not supported or which is
+ restricted by the security policy in force, including whether
+ the requesting user is the user that submitted the job (job
+ originating user) or not (see section 8). However, the IPP
+ object MUST respond with the 'unknown' value for any supported
+ attribute (including all RED butes) for which the IPP object
+ does not know the value, s it would violate the security policy.
+ See the description e "out-of-band" values in the beginning of
+ Section 4.1.
+
+4. Object Attributes
+
+ This section describes the attributes with their corresponding
+ attribute syntaxes and values that are part of the IPP model. The
+ sections below show the objects and their associated attributes which
+ are included within the scope of this protocol. Many of these
+ attributes are derived from other relevant specifications:
+
+
+
+deBry, et al. Experimental [Page 58]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ - Document Printing Application (DPA) [ISO10175]
+ - RFC 1759 Printer MIB [RFC1759]
+
+ Each attribute is uniquely identified in this document using a
+ "keyword" (see section 12.2.1) which is the name of the attribute.
+ The keyword is included in the section header describing that
+ attribute.
+
+ Note: Not only are keywords used to identify attributes, but one of
+ the attribute syntaxes described below is "keyword" so that some
+ attributes have keyword values. Therefore, these attributes are
+ defined as having an attribute syntax that is a set of keywords.
+
+4.1 Attribute Syntaxes
+
+ This section defines the basic attribute syntax types that all clients
+ and IPP objects MUST be able to accept in responses and accept in
+ requests, respectively. Each attribute description in sections 3 and
+ 4 includes the name of attribute syntax(es) in the heading (in
+ parentheses). A conforming implementation of an attribute MUST
+ include the semantics of the attribute syntax(es) so identified.
+ Section 6.3 describes how the protocol can be extended with new
+ attribute syntaxes.
+
+ The attribute syntaxes are specified in the following sub-sections,
+ where the sub-section heading is the keyword name of the attribute
+ syntax inside the single quotes. In operation requests and responses
+ each attribute value MUST be represented as one of the attribute
+ syntaxes specified in the sub-section heading for the attribute. In
+ addition, the value of an attribute in a response (but not in a
+ request) MAY be one of the "out-of-band" values. Standard
+ "out-of-band" values are:
+
+ 'unknown': The attribute is supported by the IPP object, but the
+ value is unknown to the IPP object for some reason.
+ 'unsupported': The attribute is unsupported by the IPP object. This
+ value MUST be returned only as the value of an attribute in the
+ Unsupported Attributes Group.
+ 'no-value': The attribute is supported by the Printer object, but
+ the system administrator has not yet configured a value.
+
+ The Encoding and Transport specification [RFC2565] defines mechanisms
+ for passing "out-of-band" values. All attributes in a request MUST
+ have one or more values as defined in Sections 4.2 to 4.4. Thus
+ clients MUST NOT supply attributes with "out-of-band" values. All
+ attribute in a response MUST have one or more values as defined in
+ Sections 4.2 to 4.4 or a single "out-of-band" value.
+
+
+
+
+deBry, et al. Experimental [Page 59]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Most attributes are defined to have a single attribute syntax.
+ However, a few attributes (e.g., "job-sheet", "media", "job-hold-
+ until") are defined to have several attribute syntaxes, depending on
+ the value. These multiple attribute syntaxes are separated by the
+ "|" character in the sub-section heading to indicate the choice.
+ Since each value MUST be tagged as to its attribute syntax in the
+
+ protocol, a single-valued attribute instance may have any one of its
+ attribute syntaxes and a multi-valued attribute instance may have a
+ mixture of its defined attribute syntaxes.
+
+4.1.1 'text'
+
+ A text attribute is an attribute whose value is a sequence of zero or
+ more characters encoded in a maximum of 1023 ('MAX') octets. MAX is
+ the maximum length for each value of any text attribute. However, if
+ an attribute will always contain values whose maximum length is much
+ less than MAX, the definition of that attribute will include a
+ qualifier that defines the maximum length for values of that
+ attribute. For example: the "printer-location" attribute is
+ specified as "printer-location (text(127))". In this case, text
+ values for "printer-location" MUST NOT exceed 127 octets; if supplied
+ with a longer text string via some external interface (other than the
+ protocol), implementations are free to truncate to this shorter
+ length limitation.
+
+ In this specification, all text attributes are defined using the '
+ text' syntax. However, 'text' is used only for brevity; the formal
+ interpretation of 'text' is: 'textWithoutLanguage |
+ textWithLanguage'. That is, for any attribute defined in this
+ specification using the 'text' attribute syntax, all IPP objects and
+ clients MUST support both the 'textWithoutLanguage' and '
+ textWithLanguage' attribute syntaxes. However, in actual usage and
+ protocol execution, objects and clients accept and return only one of
+ the two syntax per attribute. The syntax 'text' never appears "on-
+ the-wire".
+
+ Both 'textWithoutLanguage' and 'textWithLanguage' are needed to
+ support the real world needs of interoperability between sites and
+ systems that use different natural languages as the basis for human
+ communication. Generally, one natural language applies to all text
+ attributes in a given request or response. The language is indicated
+ by the "attributes-natural-language" operation attribute defined in
+ section 3.1.4 or "attributes-natural-language" job attribute defined
+ in section 4.3.24, and there is no need to identify the natural
+ language for each text string on a value-by-value basis. In these
+ cases, the attribute syntax 'textWithoutLanguage' is used for text
+ attributes. In other cases, the client needs to supply or the
+
+
+
+deBry, et al. Experimental [Page 60]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Printer object needs to return a text value in a natural language
+ that is different from the rest of the text values in the request or
+ response. In these cases, the client or Printer object uses the
+ attribute syntax 'textWithLanguage' for text attributes (this is the
+ Natural Language Override mechanism described in section 3.1.4).
+
+ The 'textWithoutLanguage' and 'textWithLanguage' attribute syntaxes
+ are described in more detail in the following sections.
+
+4.1.1.1 'textWithoutLanguage'
+
+ The 'textWithoutLanguage' syntax indicates a value that is sequence
+ of zero or more characters. Text strings are encoded using the rules
+ of some charset. The Printer object MUST support the UTF-8 charset
+ [RFC2279] and MAY support additional charsets to represent 'text'
+ values, provided that the charsets are registered with IANA [IANA-
+ CS]. See Section 4.1.7 for the specification of the 'charset'
+ attribute syntax, including restricted semantics and examples of
+ charsets.
+
+4.1.1.2 'textWithLanguage'
+
+ The 'textWithLanguage' attribute syntax is a compound attribute
+ syntax consisting of two parts: a 'textWithoutLanguage' part plus an
+ additional 'naturalLanguage' (see section 4.1.8) part that overrides
+ the natural language in force. The 'naturalLanguage' part explicitly
+ identifies the natural language that applies to the text part of that
+ value and that value alone. For any give text attribute, the '
+ textWithoutLanguage' part is limited to the maximum length defined
+ for that attribute, but the 'naturalLanguage' part is always limited
+ to 63 octets. Using the 'textWithLanguage' attribute syntax rather
+ than the normal 'textWithoutLanguage' syntax is the so-called Natural
+ Language Override mechanism and MUST be supported by all IPP objects
+ and clients.
+
+ If the attribute is multi-valued (1setOf text), then the '
+ textWithLanguage' attribute syntax MUST be used to explicitly specify
+ each attribute value whose natural language needs to be overridden.
+ Other values in a multi-valued 'text' attribute in a request or a
+ response revert to the natural language of the operation attribute.
+
+ In a create request, the Printer object MUST accept and store with
+ the Job object any natural language in the "attributes-natural-
+ language" operation attribute, whether the Printer object supports
+ that natural language or not. Furthermore, the Printer object MUST
+ accept and store any 'textWithLanguage' attribute value, whether the
+
+
+
+
+
+deBry, et al. Experimental [Page 61]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Printer object supports that natural language or not. These
+ requirements are independent of the value of the "ipp-attribute-
+ fidelity" operation attribute that the client MAY supply.
+
+ Example: If the client supplies the "attributes-natural-language"
+ operation attribute with the value: 'en' indicating English, but the
+ value of the "job-name" attribute is in French, the client MUST use
+ the 'textWithLanguage' attribute syntax with the following two
+ values:
+
+ 'fr': Natural Language Override indicating French
+ 'Rapport Mensuel': the job name in French
+
+ See the Encoding and Transport document [RFC2565] for a detailed
+ example of the 'textWithLanguage' attribute syntax.
+
+4.1.2 'name'
+
+ This syntax type is used for user-friendly strings, such as a Printer
+ name, that, for humans, are more meaningful than identifiers. Names
+ are never translated from one natural language to another. The '
+ name' attribute syntax is essentially the same as 'text', including
+ the REQUIRED support of UTF-8 except that the sequence of characters
+ is limited so that its encoded form MUST NOT exceed 255 (MAX) octets.
+
+ Also like 'text', 'name' is really an abbreviated notation for either
+ 'nameWithoutLanguage' or 'nameWithLanguage'. That is, all IPP
+ objects and clients MUST support both the 'nameWithoutLanguage' and '
+ nameWithLanguage' attribute syntaxes. However, in actual usage and
+ protocol execution, objects and clients accept and return only one of
+ the two syntax per attribute. The syntax 'name' never appears "on-
+ the-wire".
+
+ Note: Only the 'text' and 'name' attribute syntaxes permit the
+ Natural Language Override mechanism.
+
+ Some attributes are defined as 'type3 keyword | name'. These
+ attributes support values that are either type3 keywords or names.
+ This dual-syntax mechanism enables a site administrator to extend
+ these attributes to legally include values that are locally defined
+ by the site administrator. Such names are not registered with IANA.
+
+4.1.2.1 'nameWithoutLanguage'
+
+ The 'nameWithoutLanguage' syntax indicates a value that is sequence
+ of zero or more characters so that its encoded form does not exceed
+ MAX octets.
+
+
+
+
+deBry, et al. Experimental [Page 62]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+4.1.2.2 'nameWithLanguage'
+
+ The 'nameWithLanguage' attribute syntax is a compound attribute
+ syntax consisting of two parts: a 'nameWithoutLanguage' part plus an
+ additional 'naturalLanguage' (see section 4.1.8) part that overrides
+ the natural language in force. The 'naturalLanguage' part explicitly
+ identifies the natural language that applies to that name value and
+ that name value alone.
+
+ The 'nameWithLanguage' attribute syntax behaves the same as the '
+ textWithLanguage' syntax. If a name is in a language that is
+ different than the rest of the object or operation, then this '
+ nameWithLanguage' syntax is used rather than the generic '
+ nameWithoutLanguage' syntax.
+
+ Example: If the client supplies the "attributes-natural-language"
+ operation attribute with the value: 'en' indicating English, but the
+ "printer-name" attribute is in German, the client MUST use the '
+ nameWithLanguage' attribute syntax as follows:
+
+ 'de': Natural Language Override indicating German
+ 'Farbdrucker': the Printer name in German
+
+4.1.2.3 Matching 'name' attribute values
+
+ For purposes of matching two 'name' attribute values for equality,
+ such as in job validation (where a client-supplied value for
+ attribute "xxx" is checked to see if the value is among the values of
+ the Printer object's corresponding "xxx-supported" attribute), the
+ following match rules apply:
+
+ 1. 'keyword' values never match 'name' values.
+
+ 2. 'name' (nameWithoutLanguage and nameWithLanguage) values
+ match if (1) the name parts match and (2) the Associated
+ Natural-Language parts (see section 3.1.4.1) match. The
+ matching rules are:
+
+ a. the name parts match if the two names are identical
+ character by character, except it is RECOMMENDED that case
+ be ignored. For example: 'Ajax-letter-head-white' MUST
+ match 'Ajax-letter-head-white' and SHOULD match 'ajax-
+ letter-head-white' and 'AJAX-LETTER-HEAD-WHITE'.
+
+ b. the Associated Natural-Language parts match if the
+ shorter of the two meets the syntactic requirements of RFC
+ 1766 [RFC1766] and matches byte for byte with the longer.
+ For example, 'en' matches 'en', 'en-us' and 'en-gb', but
+
+
+
+deBry, et al. Experimental [Page 63]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ matches neither 'fr' nor 'e'.
+
+4.1.3 'keyword'
+
+ The 'keyword' attribute syntax is a sequence of characters, length: 1
+ to 255, containing only the US-ASCII [ASCII] encoded values for
+ lowercase letters ("a" - "z"), digits ("0" - "9"), hyphen ("-"), dot
+ ("."), and underscore ("_"). The first character MUST be a lowercase
+ letter. Furthermore, keywords MUST be in U.S. English.
+
+ This syntax type is used for enumerating semantic identifiers of
+ entities in the abstract protocol, i.e., entities identified in this
+ document. Keywords are used as attribute names or values of
+ attributes. Unlike 'text' and 'name' attribute values, 'keyword'
+ values MUST NOT use the Natural Language Override mechanism, since
+ they MUST always be US-ASCII and U.S. English.
+
+ Keywords are for use in the protocol. A user interface will likely
+ provide a mapping between protocol keywords and displayable user-
+ friendly words and phrases which are localized to the natural
+ language of the user. While the keywords specified in this document
+ MAY be displayed to users whose natural language is U.S. English,
+ they MAY be mapped to other U.S. English words for U.S. English
+ users, since the user interface is outside the scope of this
+ document.
+
+ In the definition for each attribute of this syntax type, the full
+ set of defined keyword values for that attribute are listed.
+
+ When a keyword is used to represent an attribute (its name), it MUST
+ be unique within the full scope of all IPP objects and attributes.
+ When a keyword is used to represent a value of an attribute, it MUST
+ be unique just within the scope of that attribute. That is, the same
+ keyword MUST NOT be used for two different values within the same
+ attribute to mean two different semantic ideas. However, the same
+ keyword MAY be used across two or more attributes, representing
+ different semantic ideas for each attribute. Section 6.1 describes
+ how the protocol can be extended with new keyword values. Examples
+ of attribute name keywords:
+
+ "job-name"
+ "attributes-charset"
+
+ Note: This document uses "type1", "type2", and "type3" prefixes to
+ the "keyword" basic syntax to indicate different levels of review for
+ extensions (see section 6.1).
+
+
+
+
+
+deBry, et al. Experimental [Page 64]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+4.1.4 'enum'
+
+ The 'enum' attribute syntax is an enumerated integer value that is in
+ the range from 1 to 2**31 - 1 (MAX). Each value has an associated '
+ keyword' name. In the definition for each attribute of this syntax
+ type, the full set of possible values for that attribute are listed.
+ This syntax type is used for attributes for which there are enum
+ values assigned by other standards, such as SNMP MIBs. A number of
+ attribute enum values in this specification are also used for
+ corresponding attributes in other standards [RFC1759]. This syntax
+ type is not used for attributes to which the system administrator may
+ assign values. Section 6.1 describes how the protocol can be
+ extended with new enum values.
+
+ Enum values are for use in the protocol. A user interface will
+ provide a mapping between protocol enum values and displayable user-
+ friendly words and phrases which are localized to the natural
+ language of the user. While the enum symbols specified in this
+ document MAY be displayed to users whose natural language is U.S.
+ English, they MAY be mapped to other U.S. English words for U.S.
+ English users, since the user interface is outside the scope of this
+ document.
+
+ Note: SNMP MIBs use '2' for 'unknown' which corresponds to the IPP
+ "out-of-band" value 'unknown'. See the description of the "out-of-
+ band" values at the beginning of Section 4.1. Therefore, attributes
+ of type 'enum' start at '3'.
+
+ Note: This document uses "type1", "type2", and "type3" prefixes to
+ the "enum" basic syntax to indicate different levels of review for
+ extensions (see section 6.1).
+
+4.1.5 'uri'
+
+ The 'uri' attribute syntax is any valid Uniform Resource Identifier
+ or URI [RFC2396]. Most often, URIs are simply Uniform Resource
+ Locators or URLs. The maximum length of URIs used as values of IPP
+ attributes is 1023 octets. Although most other IPP attribute syntax
+ types allow for only lower-cased values, this attribute syntax type
+ conforms to the case-sensitive and case-insensitive rules specified
+ in [RFC2396].
+
+4.1.6 'uriScheme'
+
+ The 'uriScheme' attribute syntax is a sequence of characters
+ representing a URI scheme according to RFC 2396 [RFC2396]. Though
+ RFC 2396 requires that the values be case-insensitive, IPP requires
+
+
+
+
+deBry, et al. Experimental [Page 65]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ all lower case values in IPP attributes to simplify comparing by IPP
+ clients and Printer objects. Standard values for this syntax type
+ are the following keywords:
+
+ 'http': for HTTP schemed URIs (e.g., "http:...")
+ 'https': for use with HTTPS schemed URIs (e.g., "https:...")
+ (not on IETF standards track)
+ 'ftp': for FTP schemed URIs (e.g., "ftp:...")
+ 'mailto': for SMTP schemed URIs (e.g., "mailto:...")
+ 'file': for file schemed URIs (e.g., "file:...")
+
+ A Printer object MAY support any URI 'scheme' that has been
+ registered with IANA [IANA-MT]. The maximum length of URI 'scheme'
+ values used to represent IPP attribute values is 63 octets.
+
+4.1.7 'charset'
+
+ The 'charset' attribute syntax is a standard identifier for a
+ charset. A charset is a coded character set and encoding scheme.
+ Charsets are used for labeling certain document contents and 'text'
+ and 'name' attribute values. The syntax and semantics of this
+ attribute syntax are specified in RFC 2046 [RFC2046] and contained in
+ the IANA character-set Registry [IANA-CS] according to the IANA
+ procedures [RFC2278]. Though RFC 2046 requires that the values be
+ case-insensitive US-ASCII, IPP requires all lower case values in IPP
+ attributes to simplify comparing by IPP clients and Printer objects.
+ When a character-set in the IANA registry has more than one name
+ (alias), the name labeled as "(preferred MIME name)", if present,
+ MUST be used.
+
+ The maximum length of 'charset' values used to represent IPP
+ attribute values is 63 octets.
+
+ Some examples are:
+
+ 'utf-8': ISO 10646 Universal Multiple-Octet Coded Character Set
+ (UCS) represented as the UTF-8 [RFC2279] transfer encoding
+ scheme in which US-ASCII is a subset charset.
+ 'us-ascii': 7-bit American Standard Code for Information
+ Interchange (ASCII), ANSI X3.4-1986 [ASCII]. That standard
+ defines US-ASCII, but RFC 2045 [RFC2045] eliminates most of the
+ control characters from conformant usage in MIME and IPP.
+ 'iso-8859-1': 8-bit One-Byte Coded Character Set, Latin Alphabet
+ Nr 1 [ISO8859-1]. That standard defines a coded character set
+ that is used by Latin languages in the Western Hemisphere and
+ Western Europe. US-ASCII is a subset charset.
+
+
+
+
+
+deBry, et al. Experimental [Page 66]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 'iso-10646-ucs-2': ISO 10646 Universal Multiple-Octet Coded
+ Character Set (UCS) represented as two octets (UCS-2), with the
+ high order octet of each pair coming first (so-called Big Endian
+ integer).
+
+ Some attribute descriptions MAY place additional requirements on
+ charset values that may be used, such as REQUIRED values that MUST be
+ supported or additional restrictions, such as requiring that the
+ charset have US-ASCII as a subset charset.
+
+4.1.8 'naturalLanguage'
+
+ The 'naturalLanguage' attribute syntax is a standard identifier for a
+ natural language and optionally a country. The values for this
+ syntax type are defined by RFC 1766 [RFC1766]. Though RFC 1766
+ requires that the values be case-insensitive US-ASCII, IPP requires
+ all lower case to simplify comparing by IPP clients and Printer
+ objects. Examples include:
+
+ 'en': for English
+ 'en-us': for US English
+ 'fr': for French
+ 'de': for German
+
+ The maximum length of 'naturalLanguage' values used to represent IPP
+ attribute values is 63 octets.
+
+4.1.9 'mimeMediaType'
+
+ The 'mimeMediaType' attribute syntax is the Internet Media Type
+ (sometimes called MIME type) as defined by RFC 2046 [RFC2046] and
+ registered according to the procedures of RFC 2048 [RFC2048] for
+ identifying a document format. The value MAY include a charset
+ parameter, depending on the specification of the Media Type in the
+ IANA Registry [IANA-MT]. Although most other IPP syntax types allow
+ for only lower-cased values, this syntax type allows for mixed-case
+ values which are case-insensitive.
+
+ Examples are:
+
+ 'text/html': An HTML document
+ 'text/plain': A plain text document in US-ASCII (RFC 2046 indicates
+ that in the absence of the charset parameter MUST mean US-ASCII
+ rather than simply unspecified) [RFC2046].
+ 'text/plain; charset=US-ASCII': A plain text document in US-ASCII
+ [52, 56].
+ 'text/plain; charset=ISO-8859-1': A plain text document in ISO
+ 8859-1 (Latin 1) [ISO8859-1].
+
+
+
+deBry, et al. Experimental [Page 67]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 'text/plain; charset=utf-8': A plain text document in ISO 10646
+ represented as UTF-8 [RFC2279]
+ 'text/plain, charset=iso-10646-ucs-2': A plain text document in
+ ISO 10646 represented in two octets (UCS-2) [ISO10646-1]
+ 'application/postscript': A PostScript document [RFC2046]
+ 'application/vnd.hp-PCL': A PCL document [IANA-MT] (charset escape
+ sequence embedded in the document data)
+ 'application/octet-stream': Auto-sense - see below
+
+ One special type is 'application/octet-stream'. If the Printer
+ object supports this value, the Printer object MUST be capable of
+ auto-sensing the format of the document data. If the Printer
+ object's default value attribute "document-format-default" is set to
+ 'application/octet-stream', the Printer object not only supports
+ auto-sensing of the document format, but will depend on the result of
+ applying its auto-sensing when the client does not supply the
+ "document-format" attribute. If the client supplies a document
+ format value, the Printer MUST rely on the supplied attribute, rather
+ than trust its auto-sensing algorithm. To summarize:
+
+ 1. If the client does not supply a document format value, the
+ Printer MUST rely on its default value setting (which may be '
+ application/octet-stream' indicating an auto-sensing mechanism).
+ 2. If the client supplies a value other than 'application/octet-
+ stream', the client is supplying valid information about the
+ format of the document data and the Printer object MUST trust
+ the client supplied value more than the outcome of applying an
+ automatic format detection mechanism. For example, the client
+ may be requesting the printing of a PostScript file as a '
+ text/plain' document. The Printer object MUST print a text
+ representation of the PostScript commands rather than interpret
+ the stream of PostScript commands and print the result.
+ 3. If the client supplies a value of 'application/octet-stream',
+ the client is indicating that the Printer object MUST use its
+ auto-sensing mechanism on the client supplied document data
+ whether auto-sensing is the Printer object's default or not.
+
+ Note: Since the auto-sensing algorithm is probabilistic, if the
+ client requests both auto-sensing ("document-format" set to '
+ application/octet-stream') and true fidelity ("ipp-attribute-
+ fidelity" set to 'true'), the Printer object might not be able to
+ guarantee exactly what the end user intended (the auto-sensing
+ algorithm might mistake one document format for another ), but it is
+ able to guarantee that its auto-sensing mechanism be used.
+
+ The maximum length of a 'mimeMediaType' value to represent IPP
+ attribute values is 255 octets.
+
+
+
+
+deBry, et al. Experimental [Page 68]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+4.1.10 'octetString'
+
+ The 'octetString' attribute syntax is a sequence of octets encoded in
+ a maximum of 1023 octets which is indicated in sub-section headers
+ using the notation: octetString(MAX). This syntax type is used for
+ opaque data.
+
+4.1.11 'boolean'
+
+ The 'boolean' attribute syntax has only two values: 'true' and '
+ false'.
+
+4.1.12 'integer'
+
+ The 'integer' attribute syntax is an integer value that is in the
+ range from -2**31 (MIN) to 2**31 - 1 (MAX). Each individual
+ attribute may specify the range constraint explicitly in sub-section
+ headers if the range is different from the full range of possible
+ integer values. For example: job-priority (integer(1:100)) for the
+ "job-priority" attribute. However, the enforcement of that
+ additional constraint is up to the IPP objects, not the protocol.
+
+4.1.13 'rangeOfInteger'
+
+ The 'rangeOfInteger' attribute syntax is an ordered pair of integers
+ that defines an inclusive range of integer values. The first integer
+ specifies the lower bound and the second specifies the upper bound.
+ If a range constraint is specified in the header description for an
+ attribute in this document whose attribute syntax is 'rangeOfInteger'
+ (i.e., 'X:Y' indicating X as a minimum value and Y as a maximum
+ value), then the constraint applies to both integers.
+
+4.1.14 'dateTime'
+
+ The 'dateTime' attribute syntax is a standard, fixed length, 11 octet
+ representation of the "DateAndTime" syntax as defined in RFC 2579
+ [RFC2579]. RFC 2579 also identifies an 8 octet representation of a
+ "DateAndTime" value, but IPP objects MUST use the 11 octet
+ representation. A user interface will provide a mapping between
+ protocol dateTime values and displayable user-friendly words or
+ presentation values and phrases which are localized to the natural
+ language and date format of the user.
+
+4.1.15 'resolution'
+
+ The 'resolution' attribute syntax specifies a two-dimensional
+ resolution in the indicated units. It consists of 3 values: a cross
+ feed direction resolution (positive integer value), a feed direction
+
+
+
+deBry, et al. Experimental [Page 69]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ resolution (positive integer value), and a units value. The
+ semantics of these three components are taken from the Printer MIB
+ [RFC1759] suggested values. That is, the cross feed direction
+ component resolution component is the same as the
+ prtMarkerAddressabilityXFeedDir object in the Printer MIB, the feed
+ direction component resolution component is the same as the
+ prtMarkerAddressabilityFeedDir in the Printer MIB, and the units
+ component is the same as the prtMarkerAddressabilityUnit object in
+ the Printer MIB (namely, '3' indicates dots per inch and '4'
+ indicates dots per centimeter). All three values MUST be present
+ even if the first two values are the same. Example: '300', '600', '
+ 3' indicates a 300 dpi cross-feed direction resolution, a 600 dpi
+ feed direction resolution, since a '3' indicates dots per inch (dpi).
+
+4.1.16 '1setOf X'
+
+ The '1setOf X' attribute syntax is 1 or more values of attribute
+ syntax type X. This syntax type is used for multi-valued attributes.
+ The syntax type is called '1setOf' rather than just 'setOf' as a
+ reminder that the set of values MUST NOT be empty (i.e., a set of
+ size 0). Sets are normally unordered. However each attribute
+ description of this type may specify that the values MUST be in a
+ certain order for that attribute.
+
+4.2 Job Template Attributes
+
+ Job Template attributes describe job processing behavior. Support
+ for Job Template attributes by a Printer object is OPTIONAL (see
+ section 13.2.3 for a description of support for OPTIONAL attributes).
+ Also, clients OPTIONALLY supply Job Template attributes in create
+ requests.
+
+ Job Template attributes conform to the following rules. For each Job
+ Template attribute called "xxx":
+
+ 1. If the Printer object supports "xxx" then it MUST support both a
+ "xxx-default" attribute (unless there is a "No" in the table
+ below) and a "xxx-supported" attribute. If the Printer object
+ doesn't support "xxx", then it MUST support neither an "xxx-
+ default" attribute nor an "xxx-supported" attribute, and it MUST
+ treat an attribute "xxx" supplied by a client as unsupported.
+ An attribute "xxx" may be supported for some document formats
+ and not supported for other document formats. For example, it
+ is expected that a Printer object would only support
+ "orientation-requested" for some document formats (such as '
+ text/plain' or 'text/html') but not others (such as '
+ application/postscript').
+
+
+
+
+deBry, et al. Experimental [Page 70]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 2. "xxx" is OPTIONALLY supplied by the client in a create request.
+ If "xxx" is supplied, the client is indicating a desired job
+ processing behavior for this Job. When "xxx" is not supplied,
+ the client is indicating that the Printer object apply its
+ default job processing behavior at job processing time if the
+ document content does not contain an embedded instruction
+ indicating an xxx-related behavior.
+
+ Note: Since an administrator MAY change the default value
+ attribute after a Job object has been submitted but before it
+ has been processed, the default value used by the Printer object
+ at job processing time may be different that the default value
+ in effect at job submission time.
+
+ 3. The "xxx-supported" attribute is a Printer object attribute that
+ describes which job processing behaviors are supported by that
+ Printer object. A client can query the Printer object to find
+ out what xxx-related behaviors are supported by inspecting the
+ returned values of the "xxx-supported" attribute.
+
+ Note: The "xxx" in each "xxx-supported" attribute name is
+ singular, even though an "xxx-supported" attribute usually has
+ more than one value, such as "job-sheet-supported", unless the
+ "xxx" Job Template attribute is plural, such as "finishings" or
+ "sides". In such cases the "xxx-supported" attribute names are:
+ "finishings-supported" and "sides-supported".
+
+ 4. The "xxx-default" default value attribute describes what will be
+ done at job processing time when no other job processing
+ information is supplied by the client (either explicitly as an
+ IPP attribute in the create request or implicitly as an embedded
+ instruction within the document data).
+
+ If an application wishes to present an end user with a list of
+ supported values from which to choose, the application SHOULD query
+ the Printer object for its supported value attributes. The
+ application SHOULD also query the default value attributes. If the
+ application then limits selectable values to only those value that
+ are supported, the application can guarantee that the values supplied
+ by the client in the create request all fall within the set of
+ supported values at the Printer. When querying the Printer, the
+ client MAY enumerate each attribute by name in the Get-Printer-
+ Attributes Request, or the client MAY just name the "job-template"
+ group in order to get the complete set of supported attributes (both
+ supported and default attributes).
+
+
+
+
+
+
+deBry, et al. Experimental [Page 71]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ The "finishings" attribute is an example of a Job Template attribute.
+ It can take on a set of values such as 'staple', 'punch', and/or '
+ cover'. A client can query the Printer object for the "finishings-
+ supported" attribute and the "finishings-default" attribute. The
+ supported attribute contains a set of supported values. The default
+ value attribute contains the finishing value(s) that will be used for
+ a new Job if the client does not supply a "finishings" attribute in
+ the create request and the document data does not contain any
+ corresponding finishing instructions. If the client does supply the
+ "finishings" attribute in the create request, the IPP object
+ validates the value or values to make sure that they are a subset of
+ the supported values identified in the Printer object's "finishings-
+ supported" attribute. See section 3.2.1.2.
+
+ The table below summarizes the names and relationships for all Job
+ Template attributes. The first column of the table (labeled "Job
+ Attribute") shows the name and syntax for each Job Template attribute
+ in the Job object. These are the attributes that can optionally be
+ supplied by the client in a create request. The last two columns
+ (labeled "Printer: Default Value Attribute" and "Printer: Supported
+ Values Attribute") shows the name and syntax for each Job Template
+ attribute in the Printer object (the default value attribute and the
+ supported values attribute). A "No" in the table means the Printer
+ MUST NOT support the attribute (that is, the attribute is simply not
+ applicable). For brevity in the table, the 'text' and 'name' entries
+ do not show the maximum length for each attribute.
+
+ +===================+======================+======================+
+ | Job Attribute |Printer: Default Value| Printer: Supported |
+ | | Attribute | Values Attribute |
+ +===================+======================+======================+
+ | job-priority | job-priority-default |job-priority-supported|
+ | (integer 1:100) | (integer 1:100) |(integer 1:100) |
+ +-------------------+----------------------+----------------------+
+ | job-hold-until | job-hold-until- |job-hold-until- |
+ | (type3 keyword | | default | supported |
+ | name) | (type3 keyword | |(1setOf |
+ | | name) | type3 keyword | name)|
+ +-------------------+----------------------+----------------------+
+ | job-sheets | job-sheets-default |job-sheets-supported |
+ | (type3 keyword | | (type3 keyword | |(1setOf |
+ | name) | name) | type3 keyword | name)|
+ +-------------------+----------------------+----------------------+
+ |multiple-document- |multiple-document- |multiple-document- |
+ | handling | handling-default |handling-supported |
+ | (type2 keyword) | (type2 keyword) |(1setOf type2 keyword)|
+ +-------------------+----------------------+----------------------+
+
+
+
+
+deBry, et al. Experimental [Page 72]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ +===================+======================+======================+
+ | Job Attribute |Printer: Default Value| Printer: Supported |
+ | | Attribute | Values Attribute |
+ +===================+======================+======================+
+ | copies | copies-default | copies-supported |
+ | (integer (1:MAX)) | (integer (1:MAX)) | (rangeOfInteger |
+ | | | (1:MAX)) |
+ +-------------------+----------------------+----------------------+
+ | finishings | finishings-default | finishings-supported |
+ |(1setOf type2 enum)|(1setOf type2 enum) |(1setOf type2 enum) |
+ +-------------------+----------------------+----------------------+
+ | page-ranges | No | page-ranges- |
+ | (1setOf | | supported (boolean) |
+ | rangeOfInteger | | |
+ | (1:MAX)) | | |
+ +-------------------+----------------------+----------------------+
+ | sides | sides-default | sides-supported |
+ | (type2 keyword) | (type2 keyword) |(1setOf type2 keyword)|
+ +-------------------+----------------------+----------------------+
+ | number-up | number-up-default | number-up-supported |
+ | (integer (1:MAX)) | (integer (1:MAX)) |(1setOf integer |
+ | | | (1:MAX) | |
+ | | | rangeOfInteger |
+ | | | (1:MAX)) |
+ +-------------------+----------------------+----------------------+
+ | orientation- |orientation-requested-|orientation-requested-|
+ | requested | default | supported |
+ | (type2 enum) | (type2 enum) | (1setOf type2 enum) |
+ +-------------------+----------------------+----------------------+
+ | media | media-default | media-supported |
+ | (type3 keyword | | (type3 keyword | |(1setOf |
+ | name) | name) | type3 keyword | name)|
+ | | | |
+ | | | media-ready |
+ | | |(1setOf |
+ | | | type3 keyword | name)|
+ +-------------------+----------------------+----------------------+
+ | printer-resolution| printer-resolution- | printer-resolution- |
+ | (resolution) | default | supported |
+ | | (resolution) |(1setOf resolution) |
+ +-------------------+----------------------+----------------------+
+ | print-quality | print-quality-default| print-quality- |
+ | (type2 enum) | (type2 enum) | supported |
+ | | |(1setOf type2 enum) |
+ +-------------------+----------------------+----------------------+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 73]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+4.2.1 job-priority (integer(1:100))
+
+ This attribute specifies a priority for scheduling the Job. A higher
+ value specifies a higher priority. The value 1 indicates the lowest
+ possible priority. The value 100 indicates the highest possible
+ priority. Among those jobs that are ready to print, a Printer MUST
+ print all jobs with a priority value of n before printing those with
+ a priority value of n-1 for all n.
+
+ If the Printer object supports this attribute, it MUST always support
+ the full range from 1 to 100. No administrative restrictions are
+ permitted. This way an end-user can always make full use of the
+ entire range with any Printer object. If privileged jobs are
+ implemented outside IPP/1.0, they MUST have priorities higher than
+ 100, rather than restricting the range available to end-users.
+
+ If the client does not supply this attribute and this attribute is
+ supported by the Printer object, the Printer object MUST use the
+ value of the Printer object's "job-priority-default" at job
+ submission time (unlike most Job Template attributes that are used if
+ necessary at job processing time).
+
+ The syntax for the "job-priority-supported" is also integer(1:100).
+ This single integer value indicates the number of priority levels
+ supported. The Printer object MUST take the value supplied by the
+ client and map it to the closest integer in a sequence of n integers
+ values that are evenly distributed over the range from 1 to 100 using
+ the formula:
+
+ roundToNearestInt((100x+50)/n)
+
+ where n is the value of "job-priority-supported" and x ranges from 0
+ through n-1.
+
+ For example, if n=1 the sequence of values is 50; if n=2, the
+ sequence of values is: 25 and 75; if n = 3, the sequence of values
+ is: 17, 50 and 83; if n = 10, the sequence of values is: 5, 15, 25,
+ 35, 45, 55, 65, 75, 85, and 95; if n = 100, the sequence of values
+ is: 1, 2, 3, . 100.
+
+ If the value of the Printer object's "job-priority-supported" is 10
+ and the client supplies values in the range 1 to 10, the Printer
+ object maps them to 5, in the range 11 to 20, the Printer object maps
+ them to 15, etc.
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 74]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+4.2.2 job-hold-until (type3 keyword | name (MAX))
+
+ This attribute specifies the named time period during which the Job
+ MUST become a candidate for printing.
+
+ Standard keyword values for named time periods are:
+
+ 'no-hold': immediately, if there are not other reasons to hold the
+ job
+ 'day-time': during the day
+ 'evening': evening
+ 'night': night
+ 'weekend': weekend
+ 'second-shift': second-shift (after close of business)
+ 'third-shift': third-shift (after midnight)
+
+ An administrator MUST associate allowable print times with a named
+ time period (by means outside IPP/1.0). An administrator is
+ encouraged to pick names that suggest the type of time period. An
+ administrator MAY define additional values using the 'name' or '
+ keyword' attribute syntax, depending on implementation.
+
+ If the value of this attribute specifies a time period that is in the
+ future, the Printer MUST add the 'job-hold-until-specified' value to
+ the job's "job-state-reasons" attribute, move the job to the '
+ pending-held' state, and MUST NOT schedule the job for printing until
+ the specified time-period arrives. When the specified time period
+ arrives, the Printer MUST remove the 'job-hold-until-specified' value
+ from the job's "job-state-reason" attribute and, if there are no
+ other job state reasons that keep the job in the 'pending-held'
+ state, the Printer MUST consider the job as a candidate for
+ processing by moving the job to the 'pending' state.
+
+ If this job attribute value is the named value 'no-hold', or the
+ specified time period has already started, the job MUST be a
+ candidate for processing immediately.
+
+ If the client does not supply this attribute and this attribute is
+ supported by the Printer object, the Printer object MUST use the
+ value of the Printer object's "job-hold-until-default" at job
+ submission time (unlike most Job Template attributes that are used if
+ necessary at job processing time).
+
+4.2.3 job-sheets (type3 keyword | name(MAX))
+
+ This attribute determines which job start/end sheet(s), if any, MUST
+ be printed with a job.
+
+
+
+
+deBry, et al. Experimental [Page 75]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Standard keyword values are:
+
+ 'none': no job sheet is printed
+ 'standard': one or more site specific standard job sheets are
+ printed, e.g. a single start sheet or both start and end sheet
+ is printed
+
+ An administrator MAY define additional values using the 'name' or '
+ keyword' attribute syntax, depending on implementation.
+
+ Note: The effect of this attribute on jobs with multiple documents
+ MAY be affected by the "multiple-document-handling" job attribute
+ (section 4.2.4), depending on the job sheet semantics.
+
+4.2.4 multiple-document-handling (type2 keyword)
+
+ This attribute is relevant only if a job consists of two or more
+ documents. The attribute controls finishing operations and the
+ placement of one or more print-stream pages into impressions and onto
+ media sheets. When the value of the "copies" attribute exceeds 1, it
+ also controls the order in which the copies that result from
+ processing the documents are produced. For the purposes of this
+ explanations, if "a" represents an instance of document data, then
+ the result of processing the data in document "a" is a sequence of
+ media sheets represented by "a(*)".
+
+ Standard keyword values are:
+
+ 'single-document': If a Job object has multiple documents, say, the
+ document data is called a and b, then the result of processing
+ all the document data (a and then b) MUST be treated as a single
+ sequence of media sheets for finishing operations; that is,
+ finishing would be performed on the concatenation of the
+ sequences a(*),b(*). The Printer object MUST NOT force the data
+ in each document instance to be formatted onto a new print-
+ stream page, nor to start a new impression on a new media sheet.
+ If more than one copy is made, the ordering of the sets of media
+ sheets resulting from processing the document data MUST be a(*),
+ b(*), a(*), b(*), ..., and the Printer object MUST force each
+ copy (a(*),b(*)) to start on a new media sheet.
+ 'separate-documents-uncollated-copies': If a Job object has
+ multiple documents, say, the document data is called a and b,
+ then the result of processing the data in each document instance
+ MUST be treated as a single sequence of media sheets for
+ finishing operations; that is, the sets a(*) and b(*) would each
+ be finished separately. The Printer object MUST force each copy
+ of the result of processing the data in a single document to
+ start on a new media sheet. If more than one copy is made, the
+
+
+
+deBry, et al. Experimental [Page 76]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ ordering of the sets of media sheets resulting from processing
+ the document data MUST be a(*), a(*), ..., b(*), b(*) ... .
+ 'separate-documents-collated-copies': If a Job object has multiple
+ documents, say, the document data is called a and b, then the
+ result of processing the data in each document instance MUST be
+ treated as a single sequence of media sheets for finishing
+ operations; that is, the sets a(*) and b(*) would each be
+ finished separately. The Printer object MUST force each copy of
+ the result of processing the data in a single document to start
+ on a new media sheet. If more than one copy is made, the
+ ordering of the sets of media sheets resulting from processing
+ the document data MUST be a(*), b(*), a(*), b(*), ... .
+ 'single-document-new-sheet': Same as 'single-document', except
+ that the Printer object MUST ensure that the first impression of
+ each document instance in the job is placed on a new media
+ sheet. This value allows multiple documents to be stapled
+ together with a single staple where each document starts on a
+ new sheet.
+
+ The 'single-document' value is the same as 'separate-documents-
+ collated-copies' with respect to ordering of print-stream pages, but
+ not media sheet generation, since 'single-document' will put the
+ first page of the next document on the back side of a sheet if an odd
+ number of pages have been produced so far for the job, while '
+ separate-documents-collated-copies' always forces the next document
+ or document copy on to a new sheet. In addition, if the "finishings"
+ attribute specifies 'staple', then with 'single-document', documents
+ a and b are stapled together as a single document with no regard to
+ new sheets, with 'single-document-new-sheet', documents a and b are
+ stapled together as a single document, but document b starts on a new
+ sheet, but with 'separate-documents-uncollated-copies' and '
+ separate-documents-collated-copies', documents a and b are stapled
+ separately.
+
+ Note: None of these values provide means to produce uncollated sheets
+ within a document, i.e., where multiple copies of sheet n are
+ produced before sheet n+1 of the same document.
+
+ The relationship of this attribute and the other attributes that
+ control document processing is described in section 15.3.
+
+4.2.5 copies (integer(1:MAX))
+
+ This attribute specifies the number of copies to be printed.
+
+ On many devices the supported number of collated copies will be
+ limited by the number of physical output bins on the device, and may
+ be different from the number of uncollated copies which can be
+
+
+
+deBry, et al. Experimental [Page 77]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ supported.
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+4.2.6 finishings (1setOf type2 enum)
+
+ This attribute identifies the finishing operations that the Printer
+ uses for each copy of each printed document in the Job. For Jobs with
+ multiple documents, the "multiple-document-handling" attribute
+ determines what constitutes a "copy" for purposes of finishing.
+
+ Standard enum values are:
+
+ Value Symbolic Name and Description
+
+ '3' 'none': Perform no finishing
+ '4' 'staple': Bind the document(s) with one or more staples.
+ The exact number and placement of the staples is
+ site-defined.
+ '5' 'punch': This value indicates that holes are required in
+ the finished document. The exact number and placement
+ of the holes is site-defined The punch specification
+ MAY be satisfied (in a site- and implementation-
+ specific manner) either by drilling/punching, or by
+ substituting pre-drilled media.
+ '6' 'cover': This value is specified when it is desired to
+ select a non-printed (or pre-printed) cover for the
+ document. This does not supplant the specification of
+ a printed cover (on cover stock medium) by the
+ document itself.
+ '7' 'bind': This value indicates that a binding is to be
+ applied to the document; the type and placement of the
+ binding is site-defined."
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+ If the client supplies a value of 'none' along with any other
+ combination of values, it is the same as if only that other
+ combination of values had been supplied (that is the 'none' value has
+ no effect).
+
+
+
+deBry, et al. Experimental [Page 78]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+4.2.7 page-ranges (1setOf rangeOfInteger (1:MAX))
+
+ This attribute identifies the range(s) of print-stream pages that the
+ Printer object uses for each copy of each document which are to be
+ printed. Nothing is printed for any pages identified that do not
+ exist in the document(s). Ranges MUST be in ascending order, for
+ example: 1-3, 5-7, 15-19 and MUST NOT overlap, so that a non-spooling
+ Printer object can process the job in a single pass. If the ranges
+ are not ascending or are overlapping, the IPP object MUST reject the
+ request and return the 'client-error-bad-request' status code. The
+ attribute is associated with print-stream pages not application-
+ numbered pages (for example, the page numbers found in the headers
+ and or footers for certain word processing applications).
+
+ For Jobs with multiple documents, the "multiple-document-handling"
+ attribute determines what constitutes a "copy" for purposes of the
+ specified page range(s). When "multiple-document-handling" is '
+ single-document', the Printer object MUST apply each supplied page
+ range once to the concatenation of the print-stream pages. For
+ example, if there are 8 documents of 10 pages each, the page-range '
+ 41:60' prints the pages in the 5th and 6th documents as a single
+ document and none of the pages of the other documents are printed.
+ When "multiple-document-handling" is 'separate-documents-uncollated-
+ copies' or 'separate-documents-collated-copies', the Printer object
+ MUST apply each supplied page range repeatedly to each document copy.
+ For the same job, the page-range '1:3, 10:10' would print the first 3
+ pages and the 10th page of each of the 8 documents in the Job, as 8
+ separate documents.
+
+ In most cases, the exact pages to be printed will be generated by a
+ device driver and this attribute would not be required. However,
+ when printing an archived document which has already been formatted,
+ the end user may elect to print just a subset of the pages contained
+ in the document. In this case, if page-range = n.m is specified, the
+ first page to be printed will be page n. All subsequent pages of the
+ document will be printed through and including page m.
+
+ "page-ranges-supported" is a boolean value indicating whether or not
+ the printer is capable of supporting the printing of page ranges.
+ This capability may differ from one PDL to another. There is no
+ "page-ranges-default" attribute. If the "page-ranges" attribute is
+ not supplied by the client, all pages of the document will be
+ printed.
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 79]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+4.2.8 sides (type2 keyword)
+
+ This attribute specifies how print-stream pages are to be imposed
+ upon the sides of an instance of a selected medium, i.e., an
+ impression.
+
+ The standard keyword values are:
+
+ 'one-sided': imposes each consecutive print-stream page upon the
+ same side of consecutive media sheets.
+ 'two-sided-long-edge': imposes each consecutive pair of print-
+ stream pages upon front and back sides of consecutive media
+ sheets, such that the orientation of each pair of print-stream
+ pages on the medium would be correct for the reader as if for
+ binding on the long edge. This imposition is sometimes called '
+ duplex' or 'head-to-head'.
+ 'two-sided-short-edge': imposes each consecutive pair of print-
+ stream pages upon front and back sides of consecutive media
+ sheets, such that the orientation of each pair of print-stream
+ pages on the medium would be correct for the reader as if for
+ binding on the short edge. This imposition is sometimes called
+ 'tumble' or 'head-to-toe'.
+
+ 'two-sided-long-edge', 'two-sided-short-edge', 'tumble', and 'duplex'
+ all work the same for portrait or landscape. However 'head-to-toe'
+ is 'tumble' in portrait but 'duplex' in landscape. 'head-to-head'
+ also switches between 'duplex' and 'tumble' when using portrait and
+ landscape modes.
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+4.2.9 number-up (integer(1:MAX))
+
+ This attribute specifies the number of print-stream pages to impose
+ upon a single side of an instance of a selected medium. For example,
+ if the value is:
+
+
+
+
+
+deBry, et al. Experimental [Page 80]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Value Description
+
+ '1' the Printer MUST place one print-stream page on a single
+ side of an instance of the selected medium (MAY add
+ some sort of translation, scaling, or rotation).
+ '2' the Printer MUST place two print-stream pages on a single
+ side of an instance of the selected medium (MAY add
+ some sort of translation, scaling, or rotation).
+ '4' the Printer MUST place four print-stream pages on a single
+ side of an instance of the selected medium (MAY add
+ some sort of translation, scaling, or rotation).
+
+ This attribute primarily controls the translation, scaling and
+ rotation of print-stream pages.
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+4.2.10 orientation-requested (type2 enum)
+
+ This attribute indicates the desired orientation for printed print-
+ stream pages; it does not describe the orientation of the client-
+ supplied print-stream pages.
+
+ For some document formats (such as 'application/postscript'), the
+ desired orientation of the print-stream pages is specified within the
+ document data. This information is generated by a device driver
+ prior to the submission of the print job. Other document formats
+ (such as 'text/plain') do not include the notion of desired
+ orientation within the document data. In the latter case it is
+ possible for the Printer object to bind the desired orientation to
+ the document data after it has been submitted. It is expected that a
+ Printer object would only support "orientations-requested" for some
+ document formats (e.g., 'text/plain' or 'text/html') but not others
+ (e.g., 'application/postscript'). This is no different than any
+ other Job Template attribute since section 4.2, item 1, points out
+ that a Printer object may support or not support any Job Template
+ attribute based on the document format supplied by the client.
+ However, a special mention is made here since it is very likely that
+ a Printer object will support "orientation-requested" for only a
+ subset of the supported document formats.
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 81]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Standard enum values are:
+
+ Value Symbolic Name and Description
+
+ '3' 'portrait': The content will be imaged across the short
+ edge of the medium.
+ '4' 'landscape': The content will be imaged across the long
+ edge of the medium. Landscape is defined to be a
+ rotation of the print-stream page to be imaged by +90
+ degrees with respect to the medium (i.e. anti-
+ clockwise) from the portrait orientation. Note: The
+ +90 direction was chosen because simple finishing on
+ the long edge is the same edge whether portrait or
+ landscape
+ '5' 'reverse-landscape': The content will be imaged across the
+ long edge of the medium. Reverse-landscape is defined
+ to be a rotation of the print-stream page to be imaged
+ by - 90 degrees with respect to the medium (i.e.
+ clockwise) from the portrait orientation. Note: The '
+ reverse-landscape' value was added because some
+ applications rotate landscape -90 degrees from
+ portrait, rather than +90 degrees.
+ '6' 'reverse-portrait': The content will be imaged across the
+ short edge of the medium. Reverse-portrait is defined
+ to be a rotation of the print-stream page to be imaged
+ by 180 degrees with respect to the medium from the
+ portrait orientation. Note: The 'reverse-portrait'
+ value was added for use with the "finishings"
+ attribute in cases where the opposite edge is desired
+ for finishing a portrait document on simple finishing
+ devices that have only one finishing position. Thus a
+ 'text'/plain' portrait document can be stapled "on the
+ right" by a simple finishing device as is common use
+ with some middle eastern languages such as Hebrew.
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+4.2.11 media (type3 keyword | name(MAX))
+
+ This attribute identifies the medium that the Printer uses for all
+ impressions of the Job.
+
+ The values for "media" include medium-names, medium-sizes, input-
+ trays and electronic forms so that one attribute specifies the media.
+
+
+
+deBry, et al. Experimental [Page 82]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ If a Printer object supports a medium name as a value of this
+ attribute, such a medium name implicitly selects an input-tray that
+ contains the specified medium. If a Printer object supports a medium
+ size as a value of this attribute, such a medium size implicitly
+ selects a medium name that in turn implicitly selects an input-tray
+ that contains the medium with the specified size. If a Printer
+ object supports an input-tray as the value of this attribute, such an
+ input-tray implicitly selects the medium that is in that input-tray
+ at the time the job prints. This case includes manual-feed input-
+ trays. If a Printer object supports an electronic form as the value
+ of this attribute, such an electronic form implicitly selects a
+ medium-name that in turn implicitly selects an input-tray that
+ contains the medium specified by the electronic form. The electronic
+ form also implicitly selects an image that the Printer MUST merge
+ with the document data as its prints each page.
+
+ Standard keyword values are (taken from ISO DPA and the Printer MIB)
+ and are listed in section 14. An administrator MAY define additional
+ values using the 'name' or 'keyword' attribute syntax, depending on
+ implementation.
+
+ There is also an additional Printer attribute named "media-ready"
+ which differs from "media-supported" in that legal values only
+ include the subset of "media-supported" values that are physically
+ loaded and ready for printing with no operator intervention required.
+ If an IPP object supports "media-supported", it NEED NOT support
+ "media-ready".
+
+ The relationship of this attribute and the other attributes that
+ control document processing is described in section 15.3.
+
+4.2.12 printer-resolution (resolution)
+
+ This attribute identifies the resolution that Printer uses for the
+ Job.
+
+4.2.13 print-quality (type2 enum)
+
+ This attribute specifies the print quality that the Printer uses for
+ the Job.
+
+ The standard enum values are:
+
+ Value Symbolic Name and Description
+
+ '3' 'draft': lowest quality available on the printer
+ '4' 'normal': normal or intermediate quality on the printer
+ '5' 'high': highest quality available on the printer
+
+
+
+deBry, et al. Experimental [Page 83]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+4.3 Job Description Attributes
+
+ The attributes in this section form the attribute group called "job-
+ description". The following table summarizes these attributes. The
+ third column indicates whether the attribute is a REQUIRED attribute
+ that MUST be supported by Printer objects. If it is not indicated as
+ REQUIRED, then it is OPTIONAL. The maximum size in octets for 'text'
+ and 'name' attributes is indicated in parenthesizes.
+
+ +----------------------------+----------------------+----------------+
+ | Attribute | Syntax | REQUIRED? |
+ +----------------------------+----------------------+----------------+
+ | job-uri | uri | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | job-id | integer(1:MAX) | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | job-printer-uri | uri | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | job-more-info | uri | |
+ +----------------------------+----------------------+----------------+
+ | job-name | name (MAX) | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | job-originating-user-name | name (MAX) | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | job-state | type1 enum | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | job-state-reasons | 1setOf type2 keyword | |
+ +----------------------------+----------------------+----------------+
+ | job-state-message | text (MAX) | |
+ +----------------------------+----------------------+----------------+
+ | number-of-documents | integer (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | output-device-assigned | name (127) | |
+ +----------------------------+----------------------+----------------+
+ | time-at-creation | integer (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | time-at-processing | integer (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | time-at-completed | integer (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | number-of-intervening-jobs | integer (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | job-message-from-operator | text (127) | |
+ +----------------------------+----------------------+----------------+
+ | job-k-octets | integer (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | job-impressions | integer (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+
+
+
+deBry, et al. Experimental [Page 84]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ +----------------------------+----------------------+----------------+
+ | Attribute | Syntax | REQUIRED? |
+ +----------------------------+----------------------+----------------+
+ | job-media-sheets | integer (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | job-k-octets-processed | integer (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | job-impressions-completed | integer (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | job-media-sheets-completed | integer (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | attributes-charset | charset | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | attributes-natural-language| naturalLanguage | REQUIRED |
+ +----------------------------+----------------------+----------------+
+
+
+4.3.1 job-uri (uri)
+
+ This REQUIRED attribute contains the URI for the job. The Printer
+ object, on receipt of a new job, generates a URI which identifies the
+ new Job. The Printer object returns the value of the "job-uri"
+ attribute as part of the response to a create request. The precise
+ format of a Job URI is implementation dependent. If the Printer
+ object supports more than one URI and there is some relationship
+ between the newly formed Job URI and the Printer object's URI, the
+ Printer object uses the Printer URI supplied by the client in the
+ create request. For example, if the create request comes in over a
+ secure channel, the new Job URI MUST use the same secure channel.
+ This can be guaranteed because the Printer object is responsible for
+ generating the Job URI and the Printer object is aware of its
+ security configuration and policy as well as the Printer URI used in
+ the create request.
+
+ For a description of this attribute and its relationship to "job-id"
+ and "job-printer-uri" attribute, see the discussion in section 2.4 on
+ "Object Identity".
+
+4.3.2 job-id (integer(1:MAX))
+
+ This REQUIRED attribute contains the ID of the job. The Printer, on
+ receipt of a new job, generates an ID which identifies the new Job on
+ that Printer. The Printer returns the value of the "job-id"
+ attribute as part of the response to a create request. The 0 value
+ is not included to allow for compatibility with SNMP index values
+ which also cannot be 0.
+
+
+
+
+
+deBry, et al. Experimental [Page 85]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ For a description of this attribute and its relationship to "job-uri"
+ and "job-printer-uri" attribute, see the discussion in section 2.4 on
+ "Object Identity".
+
+4.3.3 job-printer-uri (uri)
+
+ This REQUIRED attribute identifies the Printer object that created
+ this Job object. When a Printer object creates a Job object, it
+ populates this attribute with the Printer object URI that was used in
+ the create request. This attribute permits a client to identify the
+ Printer object that created this Job object when only the Job
+ object's URI is available to the client. The client queries the
+ creating Printer object to determine which languages, charsets,
+ operations, are supported for this Job.
+
+ For a description of this attribute and its relationship to "job-uri"
+ and "job-id" attribute, see the discussion in section 2.4 on "Object
+ Identity".
+
+4.3.4 job-more-info (uri)
+
+ Similar to "printer-more-info", this attribute contains the URI
+ referencing some resource with more information about this Job
+ object, perhaps an HTML page containing information about the Job.
+
+4.3.5 job-name (name(MAX))
+
+ This REQUIRED attribute is the name of the job. It is a name that is
+ more user friendly than the "job-uri" attribute value. It does not
+ need to be unique between Jobs. The Job's "job-name" attribute is
+ set to the value supplied by the client in the "job-name" operation
+ attribute in the create request (see Section 3.2.1.1). If, however,
+ the "job-name" operation attribute is not supplied by the client in
+ the create request, the Printer object, on creation of the Job, MUST
+ generate a name. The printer SHOULD generate the value of the Job's
+ "job-name" attribute from the first of the following sources that
+ produces a value: 1) the "document-name" operation attribute of the
+ first (or only) document, 2) the "document-URI" attribute of the
+ first (or only) document, or 3) any other piece of Job specific
+ and/or Document Content information.
+
+4.3.6 job-originating-user-name (name(MAX))
+
+ This REQUIRED attribute contains the name of the end user that
+ submitted the print job. The Printer object sets this attribute to
+ the most authenticated printable name that it can obtain from the
+ authentication service over which the IPP operation was received.
+
+
+
+
+deBry, et al. Experimental [Page 86]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Only if such is not available, does the Printer object use the value
+ supplied by the client in the "requesting-user-name" operation
+ attribute of the create operation (see Section 8).
+
+ Note: The Printer object needs to keep an internal originating user
+ id of some form, typically as a credential of a principal, with the
+ Job object. Since such an internal attribute is implementation-
+ dependent and not of interest to clients, it is not specified as a
+ Job Description attribute. This originating user id is used for
+ authorization checks (if any) on all subsequent operation.
+
+4.3.7 job-state (type1 enum)
+
+ This REQUIRED attribute identifies the current state of the job.
+ Even though the IPP protocol defines eight values for job states,
+ implementations only need to support those states which are
+ appropriate for the particular implementation. In other words, a
+ Printer supports only those job states implemented by the output
+ device and available to the Printer object implementation.
+
+ Standard enum values are:
+
+ Values Symbolic Name and Description
+
+ '3' 'pending': The job is a candidate to start processing, but
+ is not yet processing.
+
+ '4' 'pending-held': The job is not a candidate for processing
+ for any number of reasons but will return to the '
+ pending' state as soon as the reasons are no longer
+ present. The job's "job-state-reason" attribute MUST
+ indicate why the job is no longer a candidate for
+ processing.
+
+ '5' 'processing': One or more of:
+
+ 1. the job is using, or is attempting to use, one or
+ more purely software processes that are analyzing,
+ creating, or interpreting a PDL, etc.,
+ 2. the job is using, or is attempting to use, one or
+ more hardware devices that are interpreting a PDL,
+ making marks on a medium, and/or performing finishing,
+ such as stapling, etc.,
+ 3. the Printer object has made the job ready for
+ printing, but the output device is not yet printing
+ it, either because the job hasn't reached the output
+
+
+
+
+
+deBry, et al. Experimental [Page 87]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ device or because the job is queued in the output
+ device or some other spooler, awaiting the output
+ device to print it.
+
+ When the job is in the 'processing' state, the entire
+ job state includes the detailed status represented in
+ the printer's "printer-state", "printer-state-
+ reasons", and "printer-state-message" attributes.
+
+ Implementations MAY, though they NEED NOT, include
+ additional values in the job's "job-state-reasons"
+ attribute to indicate the progress of the job, such as
+ adding the 'job-printing' value to indicate when the
+ output device is actually making marks on paper and/or
+ the 'processing-to-stop-point' value to indicate that
+ the IPP object is in the process of canceling or
+ aborting the job. Most implementations won't bother
+ with this nuance.
+
+ '6' 'processing-stopped': The job has stopped while processing
+ for any number of reasons and will return to the '
+ processing' state as soon as the reasons are no longer
+ present.
+
+ The job's "job-state-reason" attribute MAY indicate
+ why the job has stopped processing. For example, if
+ the output device is stopped, the 'printer-stopped'
+ value MAY be included in the job's "job-state-reasons"
+ attribute.
+
+ Note: When an output device is stopped, the device
+ usually indicates its condition in human readable form
+ locally at the device. A client can obtain more
+ complete device status remotely by querying the
+ Printer object's "printer-state", "printer-state-
+ reasons" and "printer-state-message" attributes.
+
+ '7' 'canceled': The job has been canceled by a Cancel-Job
+ operation and the Printer object has completed
+ canceling the job and all job status attributes have
+ reached their final values for the job. While the
+ Printer object is canceling the job, the job remains
+ in its current state, but the job's "job-state-
+ reasons" attribute SHOULD contain the 'processing-to-
+ stop-point' value and one of the 'canceled-by-user', '
+ canceled-by-operator', or 'canceled-at-device' value.
+
+
+
+
+
+deBry, et al. Experimental [Page 88]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ When the job moves to the 'canceled' state, the '
+ processing-to-stop-point' value, if present, MUST be
+ removed, but the 'canceled-by-xxx', if present, MUST
+ remain.
+
+ '8' 'aborted': The job has been aborted by the system, usually
+ while the job was in the 'processing' or 'processing-
+ stopped' state and the Printer has completed aborting
+ the job and all job status attributes have reached
+ their final values for the job. While the Printer
+ object is aborting the job, the job remains in its
+ current state, but the job's "job-state-reasons"
+ attribute SHOULD contain the 'processing-to-stop-
+ point' and 'aborted-by-system' values. When the job
+ moves to the 'aborted' state, the 'processing-to-
+ stop-point' value, if present, MUST be removed, but
+ the 'aborted-by-system' value, if present, MUST
+ remain.
+
+ '9' 'completed': The job has completed successfully or with
+ warnings or errors after processing and all of the job
+ media sheets have been successfully stacked in the
+ appropriate output bin(s) and all job status
+ attributes have reached their final values for the
+ job. The job's "job-state-reasons" attribute SHOULD
+ contain one of: 'completed-successfully', '
+ completed-with-warnings', or 'completed-with-errors'
+ values.
+
+ The final value for this attribute MUST be one of: 'completed', '
+ canceled', or 'aborted' before the Printer removes the job
+ altogether. The length of time that jobs remain in the 'canceled', '
+ aborted', and 'completed' states depends on implementation.
+
+ The following figure shows the normal job state transitions.
+
+ +----> canceled
+ /
+ +----> pending --------> processing ---------+------> completed
+ | ^ ^ \
+ --->+ | | +----> aborted
+ | v v /
+ +----> pending-held processing-stopped ---+
+
+ Normally a job progresses from left to right. Other state
+ transitions are unlikely, but are not forbidden. Not shown are the
+ transitions to the 'canceled' state from the 'pending', 'pending-
+ held', and 'processing-stopped' states.
+
+
+
+deBry, et al. Experimental [Page 89]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Jobs reach one of the three terminal states: 'completed', 'canceled',
+ or 'aborted', after the jobs have completed all activity, including
+ stacking output media, after the jobs have completed all activity,
+ and all job status attributes have reached their final values for the
+ job.
+
+ Note: As with all other IPP attributes, if the implementation can not
+ determine the correct value for this attribute, it SHOULD respond
+ with the out-of-band value 'unknown' (see section 4.1) rather than
+ try to guess at some possibly incorrect value and give the end user
+ the wrong impression about the state of the Job object. For example,
+ if the implementation is just a gateway into some printing system
+ that does not provide detailed status about the print job, the IPP
+ Job object's state might literally be 'unknown'.
+
+4.3.8 job-state-reasons (1setOf type2 keyword)
+
+ This attribute provides additional information about the job's
+ current state, i.e., information that augments the value of the job's
+ "job-state" attribute.
+
+ Implementation of these values is OPTIONAL, i.e., a Printer NEED NOT
+ implement them, even if (1) the output device supports the
+ functionality represented by the reason and (2) is available to the
+ Printer object implementation. These values MAY be used with any job
+ state or states for which the reason makes sense. Furthermore, when
+ implemented, the Printer MUST return these values when the reason
+ applies and MUST NOT return them when the reason no longer applies
+ whether the value of the Job's "job-state" attribute changed or not.
+ When the Job does not have any reasons for being in its current
+ state, the value of the Job's "job-state-reasons" attribute MUST be '
+ none'.
+
+ Note: While values cannot be added to the 'job-state' attribute
+ without impacting deployed clients that take actions upon receiving
+ "job-state" values, it is the intent that additional "job-state-
+ reasons" values can be defined and registered without impacting such
+ deployed clients. In other words, the "job-state-reasons" attribute
+ is intended to be extensible.
+
+ The following standard keyword values are defined. For ease of
+ understanding, the values are presented in the order in which the
+ reasons are likely to occur (if implemented), starting with the '
+ job-incoming' value:
+
+ 'none': There are no reasons for the job's current state.
+ 'job-incoming': The Create-Job operation has been accepted by the
+ Printer, but the Printer is expecting additional Send-Document
+
+
+
+deBry, et al. Experimental [Page 90]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ and/or Send-URI operations and/or is accessing/accepting
+ document data.
+ 'submission-interrupted': The job was not completely submitted for
+ some unforeseen reason, such as: (1) the Printer has crashed
+ before the job was closed by the client, (2) the Printer or the
+ document transfer method has crashed in some non-recoverable way
+ before the document data was entirely transferred to the
+ Printer, (3) the client crashed or failed to close the job
+ before the time-out period. See section 4.4.28.
+ 'job-outgoing': The Printer is transmitting the job to the output
+ device.
+ 'job-hold-until-specified': The value of the job's "job-hold-
+ until" attribute was specified with a time period that is still
+ in the future. The job MUST NOT be a candidate for processing
+ until this reason is removed and there are no other reasons to
+ hold the job.
+ 'resources-are-not-ready': At least one of the resources needed by
+ the job, such as media, fonts, resource objects, etc., is not
+ ready on any of the physical printer's for which the job is a
+ candidate. This condition MAY be detected when the job is
+ accepted, or subsequently while the job is pending or
+ processing, depending on implementation. The job may remain in
+ its current state or be moved to the 'pending-held' state,
+ depending on implementation and/or job scheduling policy.
+ 'printer-stopped-partly': The value of the Printer's "printer-
+ state-reasons" attribute contains the value 'stopped-partly'.
+ 'printer-stopped': The value of the Printer's "printer-state"
+ attribute is 'stopped'.
+ 'job-interpreting': Job is in the 'processing' state, but more
+ specifically, the Printer is interpreting the document data.
+ 'job-queued': Job is in the 'processing' state, but more
+ specifically, the Printer has queued the document data.
+ 'job-transforming': Job is in the 'processing' state, but more
+ specifically, the Printer is interpreting document data and
+ producing another electronic representation.
+ 'job-printing': The output device is marking media. This value is
+ useful for Printers which spend a great deal of time processing
+ (1) when no marking is happening and then want to show that
+ marking is now happening or (2) when the job is in the process
+ of being canceled or aborted while the job remains in the '
+ processing' state, but the marking has not yet stopped so that
+ impression or sheet counts are still increasing for the job.
+ 'job-canceled-by-user': The job was canceled by the owner of the
+ job using the Cancel-Job request, i.e., by a user whose
+ authenticated identity is the same as the value of the
+ originating user that created the Job object, or by some other
+ authorized end-user, such as a member of the job owner's
+ security group.
+
+
+
+deBry, et al. Experimental [Page 91]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 'job-canceled-by-operator': The job was canceled by the operator
+ using the Cancel-Job request, i.e., by a user who has been
+ authenticated as having operator privileges (whether local or
+ remote). If the security policy is to allow anyone to cancel
+ anyone's job, then this value may be used when the job is
+ canceled by other than the owner of the job. For such a
+ security policy, in effect, everyone is an operator as far as
+ canceling jobs with IPP is concerned.
+ 'job-canceled-at-device': The job was canceled by an unidentified
+ local user, i.e., a user at a console at the device.
+ 'aborted-by-system': The job (1) is in the process of being
+ aborted, (2) has been aborted by the system and placed in the '
+ aborted' state, or (3) has been aborted by the system and placed
+ in the 'pending-held' state, so that a user or operator can
+ manually try the job again.
+ 'processing-to-stop-point': The requester has issued a Cancel-Job
+ operation or the Printer object has aborted the job, but is
+ still performing some actions on the job until a specified stop
+ point occurs or job termination/cleanup is completed.
+
+ This reason is recommended to be used in conjunction with the '
+ processing' job state to indicate that the Printer object is
+ still performing some actions on the job while the job remains
+ in the 'processing' state. After all the job's job description
+ attributes have stopped incrementing, the Printer object moves
+ the job from the 'processing' state to the 'canceled' or '
+ aborted' job states.
+
+ 'service-off-line': The Printer is off-line and accepting no jobs.
+ All 'pending' jobs are put into the 'pending-held' state. This
+ situation could be true if the service's or document transform's
+ input is impaired or broken.
+ 'job-completed-successfully': The job completed successfully.
+ 'job-completed-with-warnings': The job completed with warnings.
+ 'job-completed-with-errors': The job completed with errors (and
+ possibly warnings too).
+
+4.3.9 job-state-message (text(MAX))
+
+ This attribute specifies information about the "job-state" and "job-
+ state-reasons" attributes in human readable text. If the Printer
+ object supports this attribute, the Printer object MUST be able to
+ generate this message in any of the natural languages identified by
+ the Printer's "generated-natural-language-supported" attribute (see
+ the "attributes-natural-language" operation attribute specified in
+ Section 3.1.4.1).
+
+
+
+
+
+deBry, et al. Experimental [Page 92]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Note: the value SHOULD NOT contain additional information not
+ contained in the values of the "job-state" and "job-states-reasons"
+ attributes, such as interpreter error information. Otherwise,
+ application programs might attempt to parse the (localized text).
+ For such additional information such as interpreter errors for
+ application program consumption, a new attribute with keyword values,
+ needs to be developed and registered.
+
+4.3.10 number-of-documents (integer(0:MAX))
+
+ This attribute indicates the number of documents in the job, i.e.,
+ the number of Send-Document, Send-URI, Print-Job, or Print-URI
+ operations that the Printer has accepted for this job, regardless of
+ whether the document data has reached the Printer object or not.
+
+ Implementations supporting the OPTIONAL Create-Job/Send-
+ Document/Send-URI operations SHOULD support this attribute so that
+ clients can query the number of documents in each job.
+
+4.3.11 output-device-assigned (name(127))
+
+ This attribute identifies the output device to which the Printer
+ object has assigned this job. If an output device implements an
+ embedded Printer object, the Printer object NEED NOT set this
+ attribute. If a print server implements a Printer object, the value
+ MAY be empty (zero-length string) or not returned until the Printer
+ object assigns an output device to the job. This attribute is
+ particularly useful when a single Printer object support multiple
+ devices (so called "fan-out").
+
+4.3.12 time-at-creation (integer(0:MAX))
+
+ This attribute indicates the point in time at which the Job object
+ was created. In order to populate this attribute, the Printer object
+ uses the value in its "printer-up-time" attribute at the time the Job
+ object is created.
+
+4.3.13 time-at-processing (integer(0:MAX))
+
+ This attribute indicates the point in time at which the Job object
+ began processing. In order to populate this attribute, the Printer
+ object uses the value in its "printer-up-time" attribute at the time
+ the Job object is moved into the 'processing' state for the first
+ time.
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 93]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+4.3.14 time-at-completed (integer(0:MAX))
+
+ This attribute indicates the point in time at which the Job object
+ completed (or was cancelled or aborted). In order to populate this
+ attribute, the Printer object uses the value in its "printer-up-time"
+ attribute at the time the Job object is moved into the 'completed' or
+ 'canceled' or 'aborted' state.
+
+4.3.15 number-of-intervening-jobs (integer(0:MAX))
+
+ This attribute indicates the number of jobs that are "ahead" of this
+ job in the relative chronological order of expected time to complete
+ (i.e., the current scheduled order). For efficiency, it is only
+ necessary to calculate this value when an operation is performed that
+ requests this attribute.
+
+4.3.16 job-message-from-operator (text(127))
+
+ This attribute provides a message from an operator, system
+ administrator or "intelligent" process to indicate to the end user
+ the reasons for modification or other management action taken on a
+ job.
+
+4.3.17 job-k-octets (integer(0:MAX))
+
+ This attribute specifies the total size of the document(s) in K
+ octets, i.e., in units of 1024 octets requested to be processed in
+ the job. The value MUST be rounded up, so that a job between 1 and
+ 1024 octets MUST be indicated as being 1, 1025 to 2048 MUST be 2,
+ etc.
+
+ This value MUST NOT include the multiplicative factors contributed by
+ the number of copies specified by the "copies" attribute, independent
+ of whether the device can process multiple copies without making
+ multiple passes over the job or document data and independent of
+ whether the output is collated or not. Thus the value is independent
+ of the implementation and indicates the size of the document(s)
+ measured in K octets independent of the number of copies.
+
+ This value MUST also not include the multiplicative factor due to a
+ copies instruction embedded in the document data. If the document
+ data actually includes replications of the document data, this value
+ will include such replication. In other words, this value is always
+ the size of the source document data, rather than a measure of the
+ hardcopy output to be produced.
+
+
+
+
+
+
+deBry, et al. Experimental [Page 94]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Note: This attribute and the following two attributes ("job-
+ impressions" and "job-media-sheets") are not intended to be counters;
+ they are intended to be useful routing and scheduling information if
+ known. For these three attributes, the Printer object may try to
+ compute the value if it is not supplied in the create request. Even
+ if the client does supply a value for these three attributes in the
+ create request, the Printer object MAY choose to change the value if
+ the Printer object is able to compute a value which is more accurate
+ than the client supplied value. The Printer object may be able to
+ determine the correct value for these three attributes either right
+ at job submission time or at any later point in time.
+
+4.3.18 job-impressions (integer(0:MAX))
+
+ This attribute specifies the total size in number of impressions of
+ the document(s) being submitted (see the definition of impression in
+ section 13.2.5).
+
+ As with "job-k-octets", this value MUST NOT include the
+ multiplicative factors contributed by the number of copies specified
+ by the "copies" attribute, independent of whether the device can
+ process multiple copies without making multiple passes over the job
+ or document data and independent of whether the output is collated or
+ not. Thus the value is independent of the implementation and
+ reflects the size of the document(s) measured in impressions
+ independent of the number of copies.
+
+ As with "job-k-octets", this value MUST also not include the
+ multiplicative factor due to a copies instruction embedded in the
+ document data. If the document data actually includes replications
+ of the document data, this value will include such replication. In
+ other words, this value is always the number of impressions in the
+ source document data, rather than a measure of the number of
+ impressions to be produced by the job.
+
+ See the Note in the "job-k-octets" attribute that also applies to
+ this attribute.
+
+4.3.19 job-media-sheets (integer(0:MAX))
+
+ This attribute specifies the total number of media sheets to be
+ produced for this job.
+
+ Unlike the "job-k-octets" and the "job-impressions" attributes, this
+ value MUST include the multiplicative factors contributed by the
+ number of copies specified by the "copies" attribute and a 'number of
+ copies' instruction embedded in the document data, if any. This
+ difference allows the system administrator to control the lower and
+
+
+
+deBry, et al. Experimental [Page 95]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ upper bounds of both (1) the size of the document(s) with "job-k-
+ octets-supported" and "job-impressions-supported" and (2) the size of
+ the job with "job-media-sheets-supported".
+
+ See the Note in the "job-k-octets" attribute that also applies to
+ this attribute.
+
+4.3.20 job-k-octets-processed (integer(0:MAX))
+
+ This attribute specifies the total number of octets processed in K
+ octets, i.e., in units of 1024 octets so far. The value MUST be
+ rounded up, so that a job between 1 and 1024 octets inclusive MUST be
+ indicated as being 1, 1025 to 2048 inclusive MUST be 2, etc.
+
+ For implementations where multiple copies are produced by the
+ interpreter with only a single pass over the data, the final value
+ MUST be equal to the value of the "job-k-octets" attribute. For
+ implementations where multiple copies are produced by the interpreter
+ by processing the data for each copy, the final value MUST be a
+ multiple of the value of the "job-k-octets" attribute.
+
+ Note: This attribute and the following two attributes ("job-
+ impressions-completed" and "job-sheets-completed") are intended to be
+ counters. That is, the value for a job that has not started
+ processing MUST be 0. When the job's "job-state" is 'processing' or
+ 'processing-stopped', this value is intended to contain the amount of
+ the job that has been processed to the time at which the attributes
+ are requested.
+
+4.3.21 job-impressions-completed (integer(0:MAX))
+
+ This job attribute specifies the number of impressions completed for
+ the job so far. For printing devices, the impressions completed
+ includes interpreting, marking, and stacking the output.
+
+ See the note in "job-k-octets-processed" which also applies to this
+ attribute.
+
+4.3.22 job-media-sheets-completed (integer(0:MAX))
+
+ This job attribute specifies the media-sheets completed marking and
+ stacking for the entire job so far whether those sheets have been
+ processed on one side or on both.
+
+ See the note in "job-k-octets-processed" which also applies to this
+ attribute.
+
+
+
+
+
+deBry, et al. Experimental [Page 96]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+4.3.23 attributes-charset (charset)
+
+ This REQUIRED attribute is populated using the value in the client
+ supplied "attributes-charset" attribute in the create request. It
+ identifies the charset (coded character set and encoding method) used
+ by any Job attributes with attribute syntax 'text' and 'name' that
+ were supplied by the client in the create request. See Section 3.1.4
+ for a complete description of the "attributes-charset" operation
+ attribute.
+
+ This attribute does not indicate the charset in which the 'text' and
+ 'name' values are stored internally in the Job object. The internal
+ charset is implementation-defined. The IPP object MUST convert from
+ whatever the internal charset is to that being requested in an
+ operation as specified in Section 3.1.4.
+
+4.3.24 attributes-natural-language (naturalLanguage)
+
+ This REQUIRED attribute is populated using the value in the client
+ supplied "attributes-natural-language" attribute in the create
+ request. It identifies the natural language used for any Job
+ attributes with attribute syntax 'text' and 'name' that were supplied
+ by the client in the create request. See Section 3.1.4 for a
+ complete description of the "attributes-natural-language" operation
+ attribute. See Sections 4.1.1.2 and 4.1.2.2 for how a Natural
+ Language Override may be supplied explicitly for each 'text' and '
+ name' attribute value that differs from the value identified by the
+ "attributes-natural-language" attribute.
+
+4.4 Printer Description Attributes
+
+ These attributes form the attribute group called "printer-
+ description". The following table summarizes these attributes, their
+ syntax, and whether or not they are REQUIRED for a Printer object to
+ support. If they are not indicated as REQUIRED, they are OPTIONAL.
+ The maximum size in octets for 'text' and 'name' attributes is
+ indicated in parenthesizes.
+
+ Note: How these attributes are set by an Administrator is outside the
+ scope of this specification.
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 97]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ +----------------------------+----------------------+----------------+
+ | Attribute | Syntax | REQUIRED? |
+ +----------------------------+----------------------+----------------+
+ | printer-uri-supported | 1setOf uri | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | uri-security-supported | 1setOf type2 keyword | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | printer-name | name (127) | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | printer-location | text (127) | |
+ +----------------------------+----------------------+----------------+
+ | printer-info | text (127) | |
+ +----------------------------+----------------------+----------------+
+ | printer-more-info | uri | |
+ +----------------------------+----------------------+----------------+
+ | printer-driver-installer | uri | |
+ +----------------------------+----------------------+----------------+
+ | printer-make-and-model | text (127) | |
+ +----------------------------+----------------------+----------------+
+ | printer-more-info- | uri | |
+ | manufacturer | | |
+ +----------------------------+----------------------+----------------+
+ | printer-state | type1 enum | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | printer-state-reasons | 1setOf type2 keyword | |
+ +----------------------------+----------------------+----------------+
+ | printer-state-message | text (MAX) | |
+ +----------------------------+----------------------+----------------+
+ | operations-supported | 1setOf type2 enum | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | charset-configured | charset | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | charset-supported | 1setOf charset | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | natural-language-configured| naturalLanguage | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | generated-natural-language-| 1setOf | REQUIRED |
+ | supported | naturalLanguage | |
+ +----------------------------+----------------------+----------------+
+ | document-format-default | mimeMediaType | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | document-format- | 1setOf | REQUIRED |
+ | supported | mimeMediaType | |
+ +----------------------------+----------------------+----------------+
+ | printer-is-accepting-jobs | boolean | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | queued-job-count | integer (0:MAX) | RECOMMENDED |
+ +----------------------------+----------------------+----------------+
+
+
+
+deBry, et al. Experimental [Page 98]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ +----------------------------+----------------------+----------------+
+ | Attribute | Syntax | REQUIRED? |
+ +----------------------------+----------------------+----------------+
+ | printer-message-from- | text (127) | |
+ | operator | | |
+ +----------------------------+----------------------+----------------+
+ | color-supported | boolean | |
+ +----------------------------+----------------------+----------------+
+ | reference-uri-schemes- | 1setOf uriScheme | |
+ | supported | | |
+ +----------------------------+----------------------+----------------+
+ | pdl-override-supported | type2 keyword | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | printer-up-time | integer (1:MAX) | REQUIRED |
+ +----------------------------+----------------------+----------------+
+ | printer-current-time | dateTime | |
+ +----------------------------+----------------------+----------------+
+ | multiple-operation-time-out| integer (1:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | compression-supported | 1setOf type3 keyword | |
+ +----------------------------+----------------------+----------------+
+ | job-k-octets-supported | rangeOfInteger | |
+ | | (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | job-impressions-supported | rangeOfInteger | |
+ | | (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+ | job-media-sheets-supported | rangeOfInteger | |
+ | | (0:MAX) | |
+ +----------------------------+----------------------+----------------+
+
+4.4.1 printer-uri-supported (1setOf uri)
+
+ This REQUIRED Printer attribute contains at least one URI for the
+ Printer object. It OPTIONALLY contains more than one URI for the
+ Printer object. An administrator determines a Printer object's
+ URI(s) and configures this attribute to contain those URIs by some
+ means outside the scope of IPP/1.0. The precise format of this URI
+ is implementation dependent and depends on the protocol. See the
+ next section for a description "uri-security-supported" which is the
+ REQUIRED companion attribute to this "printer-uri-supported"
+ attribute. See section 2.4 on Printer object identity and section
+ 8.2 on security and URIs for more information.
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 99]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+4.4.2 uri-security-supported (1setOf type2 keyword)
+
+ This REQUIRED Printer attribute MUST have the same cardinality
+ (contain the same number of values) as the "printer-uri-supported"
+ attribute. This attribute identifies the security mechanisms used
+ for each URI listed in the "printer-uri-supported" attribute. The "i
+ th" value in "uri-security-supported" corresponds to the "i th" value
+ in "printer-uri-supported" and it describes the security mechanisms
+ used for accessing the Printer object via that URI. The following
+ standard values are defined:
+
+ 'none': There are no secure communication channel protocols in use
+ for the given URI.
+
+ 'ssl3': SSL3 [SSL] is the secure communications channel protocol in
+ use for the given URI.
+
+ Consider the following example. For a single Printer object, an
+ administrator configures the "printer-uri-supported" and "uri-
+ security-supported" attributes as follows:
+
+ "printer-uri-supported": 'http://acme.com/open-use-printer', '
+ http://acme.com/restricted-use-printer', '
+ http://acme.com/private-printer'
+ "uri-security-supported": 'none', 'none', 'ssl3'
+
+ In this case, one Printer object has three URIs.
+
+ - For the first URI, 'http://acme.com/open-use-printer', the value
+ 'none' in "uri-security-supported" indicates that there is no
+ secure channel protocol configured to run under HTTP. The name
+ implies that there is no Basic or Digest authentication being
+ used, but it is up to the client to determine that while using
+ HTTP underneath the IPP application protocol.
+ - For the second URI, 'http://acme.com/restricted-use-printer', the
+ value 'none' in "uri-security-supported" indicates that there is
+ no secure channel protocol configured to run under HTTP. In
+ this case, although the name does imply that there is some sort
+ of Basic or Digest authentication being used within HTTP, it is
+ up to the client to determine that while using HTTP and by
+ processing any '401 Unauthorized' HTTP error messages.
+ - For the third URI, 'http://acme.com/private-printer', the value '
+ ssl3' in "uri-security-supported" indicates that SSL3 is being
+ used to secure the channel. The client SHOULD be prepared to
+ use SSL3 framing to negotiate an acceptable ciphersuite to use
+ while communicating with the Printer object. In this case, the
+ name implies the use of a secure communications channel, but the
+ fact is made explicit by the presence of the 'ssl3' value in
+
+
+
+deBry, et al. Experimental [Page 100]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ "uri-security-supported". The client does not need to resort to
+ understanding which security it must use by following naming
+ conventions or by parsing the URI to determine which security
+ mechanisms are implied.
+
+ It is expected that many IPP Printer objects will be configured to
+ support only one channel (either configured to use SSL3 access or
+ not), and will therefore only ever have one URI listed in the
+ "printer-uri-supported" attribute. No matter the configuration of
+ the Printer object (whether it has only one URI or more than one
+ URI), a client MUST supply only one URI in the target "printer-uri"
+ operation attribute.
+
+4.4.3 printer-name (name(127))
+
+ This REQUIRED Printer attribute contains the name of the Printer
+ object. It is a name that is more end-user friendly than a URI. An
+ administrator determines a printer's name and sets this attribute to
+ that name. This name may be the last part of the printer's URI or it
+ may be unrelated. In non-US-English locales, a name may contain
+ characters that are not allowed in a URI.
+
+4.4.4 printer-location (text(127))
+
+ This Printer attribute identifies the location of the device. This
+ could include things like: "in Room 123A, second floor of building
+ XYZ".
+
+4.4.5 printer-info (text(127))
+
+ This Printer attribute identifies the descriptive information about
+ this Printer object. This could include things like: "This printer
+ can be used for printing color transparencies for HR presentations",
+ or "Out of courtesy for others, please print only small (1-5 page)
+ jobs at this printer", or even "This printer is going away on July 1,
+ 1997, please find a new printer".
+
+4.4.6 printer-more-info (uri)
+
+ This Printer attribute contains a URI used to obtain more information
+ about this specific Printer object. For example, this could be an
+ HTTP type URI referencing an HTML page accessible to a Web Browser.
+ The information obtained from this URI is intended for end user
+ consumption. Features outside the scope of IPP can be accessed from
+ this URI. The information is intended to be specific to this printer
+ instance and site specific services (e.g. job pricing, services
+ offered, end user assistance). The device manufacturer may initially
+ populate this attribute.
+
+
+
+deBry, et al. Experimental [Page 101]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+4.4.7 printer-driver-installer (uri)
+
+ This Printer attribute contains a URI to use to locate the driver
+ installer for this Printer object. This attribute is intended for
+ consumption by automata. The mechanics of print driver installation
+ is outside the scope of IPP. The device manufacturer may initially
+ populate this attribute.
+
+4.4.8 printer-make-and-model (text(127))
+
+ This Printer attribute identifies the make and model of the device.
+ The device manufacturer may initially populate this attribute.
+
+4.4.9 printer-more-info-manufacturer (uri)
+
+ This Printer attribute contains a URI used to obtain more information
+ about this type of device. The information obtained from this URI is
+ intended for end user consumption. Features outside the scope of IPP
+ can be accessed from this URI (e.g., latest firmware, upgrades, print
+ drivers, optional features available, details on color support). The
+ information is intended to be germane to this printer without regard
+ to site specific modifications or services. The device manufacturer
+ may initially populate this attribute.
+
+4.4.10 printer-state (type1 enum)
+
+ This REQUIRED Printer attribute identifies the current state of the
+ device. The "printer-state reasons" attribute augments the
+ "printer-state" attribute to give more detailed information about the
+ Printer in the given printer state.
+
+ A Printer object need only update this attribute before responding to
+ an operation which requests the attribute; the Printer object NEED
+ NOT update this attribute continually, since asynchronous event
+ notification is not part of IPP/1.0. A Printer NEED NOT implement
+ all values if they are not applicable to a given implementation.
+
+ The following standard enum values are defined:
+
+ Value Symbolic Name and Description
+
+ '3' 'idle': If a Printer receives a job (whose required
+ resources are ready) while in this state, such a job
+ MUST transit into the 'processing' state immediately.
+ If the "printer-state-reasons" attribute contains any
+ reasons, they MUST be reasons that would not prevent a
+ job from transiting into the 'processing' state
+ immediately, e.g., 'toner-low'. Note: if a Printer
+
+
+
+deBry, et al. Experimental [Page 102]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ controls more than one output device, the above
+ definition implies that a Printer is 'idle' if at
+ least one output device is idle.
+
+ '4' 'processing': If a Printer receives a job (whose required
+ resources are ready) while in this state, such a job
+ MUST transit into the 'pending' state immediately.
+ Such a job MUST transit into the 'processing' state
+ only after jobs ahead of it complete. If the
+ "printer-state-reasons" attribute contains any
+ reasons, they MUST be reasons that do not prevent the
+ current job from printing, e.g. 'toner-low'. Note:
+ if a Printer controls more than one output device, the
+ above definition implies that a Printer is '
+ processing' if at least one output device is
+ processing, and none is idle.
+
+ '5' 'stopped': If a Printer receives a job (whose required
+ resources are ready) while in this state, such a job
+ MUST transit into the 'pending' state immediately.
+ Such a job MUST transit into the 'processing' state
+ only after some human fixes the problem that stopped
+ the printer and after jobs ahead of it complete
+ processing. If supported, the "printer-state-reasons"
+ attribute MUST contain at least one reason, e.g. '
+ media-jam', which prevents it from either processing
+ the current job or transitioning a 'pending' job to
+ the 'processing' state.
+
+ Note: if a Printer controls more than one output
+ device, the above definition implies that a Printer is
+ 'stopped' only if all output devices are stopped.
+ Also, it is tempting to define 'stopped' as when a
+ sufficient number of output devices are stopped and
+ leave it to an implementation to define the sufficient
+ number. But such a rule complicates the definition of
+ 'stopped' and 'processing'. For example, with this
+ alternate definition of 'stopped', a job can move from
+ 'pending' to 'processing' without human intervention,
+ even though the Printer is stopped.
+
+4.4.11 printer-state-reasons (1setOf type2 keyword)
+
+ This Printer attribute supplies additional detail about the device's
+ state.
+
+
+
+
+
+
+deBry, et al. Experimental [Page 103]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Each keyword value MAY have a suffix to indicate its level of
+ severity. The three levels are: report (least severe), warning, and
+ error (most severe).
+
+ - '-report': This suffix indicates that the reason is a "report".
+ An implementation may choose to omit some or all reports. Some
+ reports specify finer granularity about the printer state;
+ others serve as a precursor to a warning. A report MUST contain
+ nothing that could affect the printed output.
+ - '-warning': This suffix indicates that the reason is a "warning".
+ An implementation may choose to omit some or all warnings.
+ Warnings serve as a precursor to an error. A warning MUST
+ contain nothing that prevents a job from completing, though in
+ some cases the output may be of lower quality.
+ - '-error': This suffix indicates that the reason is an "error".
+ An implementation MUST include all errors. If this attribute
+ contains one or more errors, printer MUST be in the stopped
+ state.
+
+ If the implementation does not add any one of the three suffixes, all
+ parties MUST assume that the reason is an "error".
+
+ If a Printer object controls more than one output device, each value
+ of this attribute MAY apply to one or more of the output devices. An
+ error on one output device that does not stop the Printer object as a
+ whole MAY appear as a warning in the Printer's "printer-state-reasons
+ attribute". If the "printer-state" for such a Printer has a value of
+ 'stopped', then there MUST be an error reason among the values in the
+ "printer-state-reasons" attribute.
+
+ The following standard keyword values are defined:
+
+ 'other': The device has detected an error other than one listed in
+ this document.
+ 'none': There are not reasons. This state reason is semantically
+ equivalent to "printer-state-reasons" without any value.
+ 'media-needed': A tray has run out of media.
+ 'media-jam': The device has a media jam.
+ 'paused': Someone has paused the Printer object. In this state, a
+ Printer MUST NOT produce printed output, but it MUST perform
+ other operations requested by a client. If a Printer had been
+ printing a job when the Printer was paused, the Printer MUST
+ resume printing that job when the Printer is no longer paused
+ and leave no evidence in the printed output of such a pause.
+ 'shutdown': Someone has removed a Printer object from service, and
+ the device may be powered down or physically removed. In this
+ state, a Printer object MUST NOT produce printed output, and
+ unless the Printer object is realized by a print server that is
+
+
+
+deBry, et al. Experimental [Page 104]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ still active, the Printer object MUST perform no other
+ operations requested by a client, including returning this
+ value. If a Printer object had been printing a job when it was
+ shutdown, the Printer NEED NOT resume printing that job when the
+ Printer is no longer shutdown. If the Printer resumes printing
+ such a job, it may leave evidence in the printed output of such
+ a shutdown, e.g. the part printed before the shutdown may be
+ printed a second time after the shutdown.
+ 'connecting-to-device': The Printer object has scheduled a job on
+ the output device and is in the process of connecting to a
+ shared network output device (and might not be able to actually
+ start printing the job for an arbitrarily long time depending on
+ the usage of the output device by other servers on the network).
+ 'timed-out': The server was able to connect to the output device
+ (or is always connected), but was unable to get a response from
+ the output device.
+ 'stopping': The Printer object is in the process of stopping the
+ device and will be stopped in a while. When the device is
+ stopped, the Printer object will change the Printer object's
+ state to 'stopped'. The 'stopping-warning' reason is never an
+ error, even for a Printer with a single output device. When an
+ output-device ceases accepting jobs, the Printer will have this
+ reason while the output device completes printing.
+ 'stopped-partly': When a Printer object controls more than one
+ output device, this reason indicates that one or more output
+ devices are stopped. If the reason is a report, fewer than half
+ of the output devices are stopped. If the reason is a warning,
+ fewer than all of the output devices are stopped.
+ 'toner-low': The device is low on toner.
+ 'toner-empty': The device is out of toner.
+ 'spool-area-full': The limit of persistent storage allocated for
+ spooling has been reached.
+ 'cover-open': One or more covers on the device are open.
+ 'interlock-open': One or more interlock devices on the printer are
+ unlocked.
+ 'door-open': One or more doors on the device are open.
+ 'input-tray-missing': One or more input trays are not in the
+ device.
+ 'media-low': At least one input tray is low on media.
+ 'media-empty': At least one input tray is empty.
+ 'output-tray-missing': One or more output trays are not in the
+ device
+ 'output-area-almost-full': One or more output area is almost full
+ (e.g. tray, stacker, collator).
+ 'output-area-full': One or more output area is full. (e.g. tray,
+ stacker, collator)
+ 'marker-supply-low': The device is low on at least one marker
+ supply. (e.g. toner, ink, ribbon)
+
+
+
+deBry, et al. Experimental [Page 105]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 'marker-supply-empty: The device is out of at least one marker
+ supply. (e.g. toner, ink, ribbon)
+ 'marker-waste-almost-full': The device marker supply waste
+ receptacle is almost full.
+ 'marker-waste-full': The device marker supply waste receptacle is
+ full.
+ 'fuser-over-temp': The fuser temperature is above normal.
+ 'fuser-under-temp': The fuser temperature is below normal.
+ 'opc-near-eol': The optical photo conductor is near end of life.
+ 'opc-life-over': The optical photo conductor is no longer
+ functioning.
+ 'developer-low': The device is low on developer.
+ 'developer-empty: The device is out of developer.
+ 'interpreter-resource-unavailable': An interpreter resource is
+ unavailable (i.e. font, form)
+
+4.4.12 printer-state-message (text(MAX))
+
+ This Printer attribute specifies the additional information about the
+ printer state and printer state reasons in human readable text. If
+ the Printer object supports this attribute, the Printer object MUST
+ be able to generate this message in any of the natural languages
+ identified by the Printer's "generated-natural-language-supported"
+ attribute (see the "attributes-natural-language" operation attribute
+ specified in Section 3.1.4.1).
+
+4.4.13 operations-supported (1setOf type2 enum)
+
+ This REQUIRED Printer attribute specifies the set of supported
+ operations for this Printer object and contained Job objects. All
+ 32-bit enum values for this attribute MUST NOT exceed 0x8FFF, since
+ these values are passed in two octets in each Protocol request
+ [RFC2565].
+
+ The following standard enum and "operation-id" (see section 3.1.2)
+ values are defined:
+
+ Value Operation Name
+ ----------------- -------------------------------------
+
+ 0x0000 reserved, not used
+ 0x0001 reserved, not used
+ 0x0002 Print-Job
+ 0x0003 Print-URI
+ 0x0004 Validate-Job
+ 0x0005 Create-Job
+ 0x0006 Send-Document
+ 0x0007 Send-URI
+
+
+
+deBry, et al. Experimental [Page 106]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 0x0008 Cancel-Job
+ 0x0009 Get-Job-Attributes
+ 0x000A Get-Jobs
+ 0x000B Get-Printer-Attributes
+ 0x000C-0x3FFF reserved for future operations
+ 0x4000-0x8FFF reserved for private extensions
+
+ This allows for certain vendors to implement private extensions that
+ are guaranteed to not conflict with future registered extensions.
+ However, there is no guarantee that two or more private extensions
+ will not conflict.
+
+4.4.14 charset-configured (charset)
+
+ This REQUIRED Printer attribute identifies the charset that the
+ Printer object has been configured to represent 'text' and 'name'
+ Printer attributes that are set by the operator, system
+ administrator, or manufacturer, i.e., for "printer-name" (name),
+ "printer-location" (text), "printer-info" (text), and "printer-make-
+ and-model" (text). Therefore, the value of the Printer object's
+ "charset-configured" attribute MUST also be among the values of the
+ Printer object's "charset-supported" attribute.
+
+4.4.15 charset-supported (1setOf charset)
+
+ This REQUIRED Printer attribute identifies the set of charsets that
+ the Printer and contained Job objects support in attributes with
+ attribute syntax 'text' and 'name'. At least the value 'utf-8' MUST
+ be present, since IPP objects MUST support the UTF-8 [RFC2279]
+ charset. If a Printer object supports a charset, it means that for
+ all attributes of syntax 'text' and 'name' the IPP object MUST (1)
+ accept the charset in requests and return the charset in responses as
+ needed.
+
+ If more charsets than UTF-8 are supported, the IPP object MUST
+ perform charset conversion between the charsets as described in
+ Section 3.2.1.2.
+
+4.4.16 natural-language-configured (naturalLanguage)
+
+ This REQUIRED Printer attribute identifies the natural language that
+ the Printer object has been configured to represent 'text' and 'name'
+ Printer attributes that are set by the operator, system
+ administrator, or manufacturer, i.e., for "printer-name" (name),
+ "printer-location" (text), "printer-info" (text), and "printer-make-
+ and-model" (text). When returning these Printer attributes, the
+ Printer object MAY return them in the configured natural language
+ specified by this attribute, instead of the natural language
+
+
+
+deBry, et al. Experimental [Page 107]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ requested by the client in the "attributes-natural-language"
+ operation attribute. See Section 3.1.4.1 for the specification of
+ the OPTIONAL multiple natural language support. Therefore, the value
+ of the Printer object's "natural-language-configured" attribute MUST
+ also be among the values of the Printer object's "generated-natural-
+ language-supported" attribute.
+
+4.4.17 generated-natural-language-supported (1setOf naturalLanguage)
+
+ This REQUIRED Printer attribute identifies the natural language(s)
+ that the Printer object and contained Job objects support in
+ attributes with attribute syntax 'text' and 'name'. The natural
+ language(s) supported depends on implementation and/or configuration.
+ Unlike charsets, IPP objects MUST accept requests with any natural
+ language or any Natural Language Override whether the natural
+ language is supported or not.
+
+ If a Printer object supports a natural language, it means that for
+ any of the attributes for which the Printer or Job object generates
+ messages, i.e., for the "job-state-message" and "printer-state-
+ message" attributes and Operation Messages (see Section 3.1.5) in
+ operation responses, the Printer and Job objects MUST be able to
+ generate messages in any of the Printer's supported natural
+ languages. See section 3.1.4 for the specification of 'text' and '
+ name' attributes in operation requests and responses.
+
+ Note: A Printer object that supports multiple natural languages,
+ often has separate catalogs of messages, one for each natural
+ language supported.
+
+4.4.18 document-format-default (mimeMediaType)
+
+ This REQUIRED Printer attribute identifies the document format that
+ the Printer object has been configured to assume if the client does
+ not supply a "document-format" operation attribute in any of the
+ operation requests that supply document data. The standard values
+ for this attribute are Internet Media types (sometimes called MIME
+ types). For further details see the description of the '
+ mimeMediaType' attribute syntax in Section 4.1.9.
+
+4.4.19 document-format-supported (1setOf mimeMediaType)
+
+ This REQUIRED Printer attribute identifies the set of document
+ formats that the Printer object and contained Job objects can
+ support. For further details see the description of the '
+ mimeMediaType' attribute syntax in Section 4.1.9.
+
+4.4.20 printer-is-accepting-jobs (boolean)
+
+
+
+deBry, et al. Experimental [Page 108]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ This REQUIRED Printer attribute indicates whether the printer is
+ currently able to accept jobs, i.e., is accepting Print-Job, Print-
+ URI, and Create-Job requests. If the value is 'true', the printer is
+ accepting jobs. If the value is 'false', the Printer object is
+ currently rejecting any jobs submitted to it. In this case, the
+ Printer object returns the 'server-error-not-accepting-jobs' status
+ code.
+
+ Note: This value is independent of the "printer-state" and "printer-
+ state-reasons" attributes because its value does not affect the
+ current job; rather it affects future jobs. This attribute may cause
+ the Printer to reject jobs when the "printer-state" is 'idle' or it
+ may cause the Printer object to accepts jobs when the "printer-state"
+ is 'stopped'.
+
+4.4.21 queued-job-count (integer(0:MAX))
+
+ This RECOMMENDED Printer attribute contains a count of the number of
+ jobs that are either 'pending', 'processing', 'pending-held', or '
+ processing-stopped' and is set by the Printer object.
+
+4.4.22 printer-message-from-operator (text(127))
+
+ This Printer attribute provides a message from an operator, system
+ administrator or "intelligent" process to indicate to the end user
+ information or status of the printer, such as why it is unavailable
+ or when it is expected to be available.
+
+4.4.23 color-supported (boolean)
+
+ This Printer attribute identifies whether the device is capable of
+ any type of color printing at all, including highlight color. All
+ document instructions having to do with color are embedded within the
+ document PDL (none are external IPP attributes in IPP/1.0).
+
+ Note: end-users are able to determine the nature and details of the
+ color support by querying the "printer-more-info-manufacturer"
+ Printer attribute.
+
+4.4.24 reference-uri-schemes-supported (1setOf uriScheme)
+
+ This Printer attribute specifies which URI schemes are supported for
+ use in the "document-uri" operation attribute of the Print-URI or
+ Send-URI operation. If a Printer object supports these optional
+ operations, it MUST support the "reference-uri-schemes-supported"
+ Printer attribute with at least the following schemed URI value:
+
+ 'ftp': The Printer object will use an FTP 'get' operation as
+
+
+
+deBry, et al. Experimental [Page 109]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ defined in RFC 2228 [RFC2228] using FTP URLs as defined by
+ [RFC2396] and[RFC2316].
+
+ The Printer object MAY OPTIONALLY support other URI schemes (see
+ section 4.1.6).
+
+4.4.25 pdl-override-supported (type2 keyword)
+
+ This REQUIRED Printer attribute expresses the ability for a
+ particular Printer implementation to either attempt to override
+ document data instructions with IPP attributes or not.
+
+ This attribute takes on the following values:
+
+ - 'attempted': This value indicates that the Printer object
+ attempts to make the IPP attribute values take precedence over
+ embedded instructions in the document data, however there is no
+ guarantee.
+
+ - 'not-attempted': This value indicates that the Printer object
+ makes no attempt to make the IPP attribute values take precedence
+ over embedded instructions in the document data.
+
+ Section 15 contains a full description of how this attribute
+ interacts with and affects other IPP attributes, especially the
+ "ipp-attribute-fidelity" attribute.
+
+4.4.26 printer-up-time (integer(1:MAX))
+
+ This REQUIRED Printer attribute indicates the amount of time (in
+ seconds) that this instance of this Printer implementation has been
+ up and running. This value is used to populate the Job attributes
+ "time-at-creation", "time-at-processing", and "time-at-completed".
+ These time values are all measured in seconds and all have meaning
+ only relative to this attribute, "printer-up-time". The value is a
+ monotonically increasing value starting from 1 when the Printer
+ object is started-up (initialized, booted, etc.).
+
+ If the Printer object goes down at some value 'n', and comes back up,
+ the implementation MAY:
+
+ 1. Know how long it has been down, and resume at some value greater
+ than 'n', or
+ 2. Restart from 1.
+
+ In the first case, the Printer SHOULD not tweak any existing related
+ Job attributes ("time-at-creation", "time-at-processing", and "time-
+ at-completed"). In the second case, the Printer object SHOULD reset
+
+
+
+deBry, et al. Experimental [Page 110]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ those attributes to 0. If a client queries a time-related Job
+ attribute and finds the value to be 0, the client MUST assume that
+ the Job was submitted in some life other than the Printer's current
+ life.
+
+4.4.27 printer-current-time (dateTime)
+
+ This Printer attribute indicates the current absolute wall-clock
+ time. If an implementation supports this attribute, then a client
+ could calculate the absolute wall-clock time each Job's "time-at-
+ creation", "time-at-processing", and "time-at-completed" attributes
+ by using both "printer-up-time" and this attribute, "printer-
+ current-time". If an implementation does not support this attribute,
+ a client can only calculate the relative time of certain events based
+ on the REQUIRED "printer-up-time" attribute.
+
+4.4.28 multiple-operation-time-out (integer(1:MAX))
+
+ This Printer attributes identifies the minimum time (in seconds) that
+ the Printer object waits for additional Send-Document or Send-URI
+ operations to follow a still-open multi-document Job object before
+ taking any recovery actions, such as the ones indicated in section
+ 3.3.1.
+
+ It is RECOMMENDED that vendors supply a value for this attribute that
+ is between 60 and 240 seconds. An implementation MAY allow a system
+ administrator to set this attribute. If so, the system administrator
+ MAY be able to set values outside this range.
+
+4.4.29 compression-supported (1setOf type3 keyword)
+
+ This Printer attribute identifies the set of supported compression
+ algorithms for document data. Compression only applies to the
+ document data; compression does not apply to the encoding of the IPP
+ operation itself. The supported values are used to validate the
+ client supplied "compression" operation attributes in Print-Job,
+ Send-Document, and Send-URI requests.
+
+ Standard values are :
+
+ 'none': no compression is used.
+ 'deflate': ZIP public domain inflate/deflate) compression
+ technology
+ 'gzip' GNU zip compression technology described in RFC 1952
+ [RFC1952].
+ 'compress': UNIX compression technology
+
+4.4.30 job-k-octets-supported (rangeOfInteger(0:MAX))
+
+
+
+deBry, et al. Experimental [Page 111]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ This Printer attribute specifies the upper and lower bounds of total
+ sizes of jobs in K octets, i.e., in units of 1024 octets. The
+ supported values are used to validate the client supplied "job-k-
+ octets" operation attributes in create requests. The corresponding
+ job description attribute "job-k-octets" is defined in section
+ 4.3.17.
+
+ 4.4.31 job-impressions-supported (rangeOfInteger(0:MAX))
+
+ This Printer attribute specifies the upper and lower bounds for the
+ number of impressions per job. The supported values are used to
+ validate the client supplied "job-impressions" operation attributes
+ in create requests. The corresponding job description attribute
+ "job-impressions" is defined in section 4.3.18.
+
+4.4.32 job-media-sheets-supported (rangeOfInteger(0:MAX))
+
+ This Printer attribute specifies the upper and lower bounds for the
+ number of media sheets per job. The supported values are used to
+ validate the client supplied "job-media-sheets" operation attributes
+ in create requests. The corresponding Job attribute "job-media-
+ sheets" is defined in section 4.3.19.
+
+5. Conformance
+
+ This section describes conformance issues and requirements. This
+ document introduces model entities such as objects, operations,
+ attributes, attribute syntaxes, and attribute values. These
+ conformance sections describe the conformance requirements which
+ apply to these model entities.
+
+5.1 Client Conformance Requirements
+
+ A conforming client MUST support all REQUIRED operations as defined
+ in this document. For each attribute included in an operation
+ request, a conforming client MUST supply a value whose type and value
+ syntax conforms to the requirements of the Model document as
+ specified in Sections 3 and 4. A conforming client MAY supply any
+ registered extensions and/or private extensions in an operation
+ request, as long as they meet the requirements in Section 6.
+
+ Otherwise, there are no conformance requirements placed on the user
+ interfaces provided by IPP clients or their applications. For
+ example, one application might not allow an end user to submit
+ multiple documents per job, while another does. One application
+ might first query a Printer object in order to supply a graphical
+ user interface (GUI) dialogue box with supported and default values
+ whereas a different implementation might not.
+
+
+
+deBry, et al. Experimental [Page 112]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ When sending a request, an IPP client NEED NOT supply any attributes
+ that are indicated as OPTIONALLY supplied by the client.
+
+ A client MUST be able to accept any of the attribute syntaxes defined
+ in Section 4.1, including their full range, that may be returned to
+ it in a response from a Printer object. In particular for each
+ attribute that the client supports whose attribute syntax is 'text',
+ the client MUST accept and process both the 'textWithoutLanguage' and
+ 'textWithLanguage' forms. Similarly, for each attribute that the
+ client supports whose attribute syntax is 'name', the client MUST
+ accept and process both the 'nameWithoutLanguage' and '
+ nameWithLanguage' forms. For presentation purposes, truncation of
+ long attribute values is not recommended. A recommended approach
+ would be for the client implementation to allow the user to scroll
+ through long attribute values.
+
+ A query response may contain attribute groups, attributes, and values
+ that the client does not expect. Therefore, a client implementation
+ MUST gracefully handle such responses and not refuse to inter-operate
+ with a conforming Printer that is returning extended registered or
+ private attributes and/or attribute values that conform to Section 6.
+ Clients may choose to ignore any parameters, attributes, or values
+ that they do not understand.
+
+5.2 IPP Object Conformance Requirements
+
+ This section specifies the conformance requirements for conforming
+ implementations with respect to objects, operations, and attributes.
+
+5.2.1 Objects
+
+ Conforming implementations MUST implement all of the model objects as
+ defined in this specification in the indicated sections:
+
+ Section 2.1 - Printer Object
+ Section 2.2 - Job Object
+
+5.2.2 Operations
+
+ Conforming IPP object implementations MUST implement all of the
+ REQUIRED model operations, including REQUIRED responses, as defined
+ in this specification in the indicated sections:
+
+ For a Printer object:
+ Print-Job (section 3.2.1) REQUIRED
+ Print-URI (section 3.2.2) OPTIONAL
+ Validate-Job (section 3.2.3) REQUIRED
+ Create-Job (section 3.2.4) OPTIONAL
+
+
+
+deBry, et al. Experimental [Page 113]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Get-Printer-Attributes (section 3.2.5) REQUIRED
+ Get-Jobs (section 3.2.6) REQUIRED
+
+ For a Job object:
+ Send-Document (section 3.3.1) OPTIONAL
+ Send-URI (section 3.3.2) OPTIONAL
+ Cancel-Job (section 3.3.3) REQUIRED
+ Get-Job-Attributes (section 3.3.4) REQUIRED
+
+ Conforming IPP objects MUST support all REQUIRED operation attributes
+ and all values of such attributes if so indicated in the description.
+ Conforming IPP objects MUST ignore all unsupported or unknown
+ operation attributes or operation attribute groups received in a
+ request, but MUST reject a request that contains a supported
+ operation attribute that contains an unsupported value.
+
+ The following section on object attributes specifies the support
+ required for object attributes.
+
+5.2.3 IPP Object Attributes
+
+ Conforming IPP objects MUST support all of the REQUIRED object
+ attributes, as defined in this specification in the indicated
+ sections.
+
+ If an object supports an attribute, it MUST support only those values
+ specified in this document or through the extension mechanism
+ described in section 5.2.4. It MAY support any non-empty subset of
+ these values. That is, it MUST support at least one of the specified
+ values and at most all of them.
+
+5.2.4 Extensions
+
+ A conforming IPP object MAY support registered extensions and private
+ extensions, as long as they meet the requirements specified in
+ Section 6.
+
+ For each attribute included in an operation response, a conforming
+ IPP object MUST return a value whose type and value syntax conforms
+ to the requirement of the Model document as specified in Sections 3
+ and 4.
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 114]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+5.2.5 Attribute Syntaxes
+
+ An IPP object MUST be able to accept any of the attribute syntaxes
+ defined in Section 4.1, including their full range, in any operation
+ in which a client may supply attributes or the system administrator
+ may configure attributes (by means outside the scope of IPP/1.0). In
+ particular for each attribute that the IPP object supports whose
+ attribute syntax is 'text', the IPP object MUST accept and process
+ both the 'textWithoutLanguage' and 'textWithLanguage' forms.
+ Similarly, for each attribute that the IPP object supports whose
+ attribute syntax is 'name', the IPP object MUST accept and process
+ both the 'nameWithoutLanguage' and 'nameWithLanguage' forms.
+ Furthermore, an IPP object MUST return attributes to the client in
+ operation responses that conform to the syntax specified in Section
+ 4.1, including their full range if supplied previously by a client.
+
+5.3 Charset and Natural Language Requirements
+
+ All clients and IPP objects MUST support the 'utf-8' charset as
+ defined in section 4.1.7.
+
+ IPP objects MUST be able to accept any client request which correctly
+ uses the "attributes-natural-language" operation attribute or the
+ Natural Language Override mechanism on any individual attribute
+ whether or not the natural language is supported by the IPP object.
+ If an IPP object supports a natural language, then it MUST be able to
+ translate (perhaps by table lookup) all generated 'text' or 'name'
+ attribute values into one of the supported languages (see section
+ 3.1.4). That is, the IPP object that supports a natural language
+ NEED NOT be a general purpose translator of any arbitrary 'text' or '
+ name' value supplied by the client into that natural language.
+ However, the object MUST be able to translate (automatically
+ generate) any of its own attribute values and messages into that
+ natural language.
+
+5.4 Security Conformance Requirements
+
+ Conforming IPP Printer objects MAY support Secure Socket Layer
+ Version 3 (SSL3) [SSL] access, support access without SSL3 or support
+ both means of access.
+
+ Conforming IPP clients SHOULD support SSL3 access and non-SSL3
+ access. Note: This client requirement to support both means that
+ conforming IPP clients will be able to inter-operate with any IPP
+ Printer object.
+
+
+
+
+
+
+deBry, et al. Experimental [Page 115]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ For a detailed discussion of security considerations and the IPP
+ application security profile required for SSL3 support, see section
+ 8.
+
+6. IANA Considerations (registered and private extensions)
+
+ This section describes how IPP can be extended to allow the following
+ registered and private extensions to IPP:
+
+ 1. keyword attribute values
+ 2. enum attribute values
+ 3. attributes
+ 4. attribute syntaxes
+ 5. operations
+ 6. attribute groups
+ 7. status codes
+
+ Extensions registered for use with IPP/1.0 are OPTIONAL for client
+ and IPP object conformance to the IPP/1.0 Model specification.
+
+ These extension procedures are aligned with the guidelines as set
+ forth by the IESG [RFC2434]. Section 11 describes how to propose new
+ registrations for consideration. IANA will reject registration
+ proposals that leave out required information or do not follow the
+ appropriate format described in Section 11. IPP/1.0 may also be
+ extended by an appropriate RFC that specifies any of the above
+ extensions.
+
+6.1 Typed 'keyword' and 'enum' Extensions
+
+ IPP allows for 'keyword' and 'enum' extensions (see sections 4.1.2.3
+ and 4.1.4). This document uses prefixes to the 'keyword' and 'enum'
+ basic attribute syntax type in order to communicate extra information
+ to the reader through its name. This extra information is not
+ represented in the protocol because it is unimportant to a client or
+ Printer object. The list below describes the prefixes and their
+ meaning.
+
+ "type1": The IPP specification must be revised to add a new
+ keyword or a new enum. No private keywords or enums are
+ allowed.
+
+ "type2": Implementers can, at any time, add new keyword or enum
+ values by proposing the complete specification to IANA:
+
+ iana@iana.org
+
+
+
+
+
+deBry, et al. Experimental [Page 116]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ IANA will forward the registration proposal to the IPP
+ Designated Expert who will review the proposal with a mailing
+ list that the Designated Expert keeps for this purpose.
+ Initially, that list will be the mailing list used by the IPP
+ WG:
+
+ ipp@pwg.org
+
+ even after the IPP WG is disbanded as permitted by [RFC2434].
+ The IPP Designated Expert is appointed by the IESG Area Director
+ responsible for IPP, according to [RFC2434].
+
+ When a type2 keyword or enum is approved, the IPP Designated
+ Expert becomes the point of contact for any future maintenance
+ that might be required for that registration.
+
+ "type3": Implementers can, at any time, add new keyword and enum
+ values by submitting the complete specification to IANA as for
+ type2 who will forward the proposal to the IPP Designated
+ Expert. While no additional technical review is required, the
+ IPP Designated Expert may, at his/her discretion, forward the
+ proposal to the same mailing list as for type2 registrations for
+ advice and comment.
+
+ When a type3 keyword or enum is approved by the IPP Designated
+ Expert, the original proposer becomes the point of contact for
+ any future maintenance that might be required for that
+ registration.
+
+ For type2 and type3 keywords, the proposer includes the name of the
+ keyword in the registration proposal and the name is part of the
+ technical review.
+
+ After type2 and type3 enums specifications are approved, the IPP
+ Designated Expert in consultation with IANA assigns the next
+ available enum number for each enum value.
+
+ IANA will publish approved type2 and type3 keyword and enum
+ attributes value registration specifications in:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-values/xxx/yyy.txt
+
+ where xxx is the attribute name that specifies the initial values and
+ yyy.txt is a descriptive file name that contains one or more enums or
+ keywords approved at the same time. For example, if several
+ additional enums for stapling are approved for use with the
+
+
+
+
+
+deBry, et al. Experimental [Page 117]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ "finishings" attribute (and "finishings-default" and "finishings-
+ supported" attributes), IANA will publish the additional values in
+ the file:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-
+ values/finishings/stapling.txt
+
+ Note: Some attributes are defined to be: 'type3 keywords' | 'name'
+ which allows for attribute values to be extended by a site
+ administrator with administrator defined names. Such names are not
+ registered with IANA.
+
+ By definition, each of the three types above assert some sort of
+ registry or review process in order for extensions to be considered
+ valid. Each higher numbered level (1, 2, 3) tends to be decreasingly
+ less stringent than the previous level. Therefore, any typeN value
+ MAY be registered using a process for some typeM where M is less than
+ N, however such registration is NOT REQUIRED. For example, a type3
+ value MAY be registered in a type 1 manner (by being included in a
+ future version of an IPP specification), however, it is NOT REQUIRED.
+
+ This specification defines keyword and enum values for all of the
+ above types, including type3 keywords.
+
+ For private (unregistered) keyword extensions, implementers SHOULD
+ use keywords with a suitable distinguishing prefix, such as "xxx-"
+ where xxx is the (lowercase) fully qualified company name registered
+ with IANA for use in domain names [RFC1035]. For example, if the
+ company XYZ Corp. had obtained the domain name "XYZ.com", then a
+ private keyword 'abc' would be: 'xyz.com-abc'.
+
+ Note: RFC 1035 [RFC1035] indicates that while upper and lower case
+ letters are allowed in domain names, no significance is attached to
+ the case. That is, two names with the same spelling but different
+ case are to be treated as if identical. Also, the labels in a domain
+ name must follow the rules for ARPANET host names: They must start
+ with a letter, end with a letter or digit, and have as interior
+ characters only letters, digits, and hyphen. Labels must be 63
+ characters or less. Labels are separated by the "." character.
+
+ For private (unregistered) enum extension, implementers MUST use
+ values in the reserved integer range which is 2**30 to 2**31-1.
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 118]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+6.2 Attribute Extensibility
+
+ Attribute names are type2 keywords. Therefore, new attributes may be
+ registered and have the same status as attributes in this document by
+ following the type2 extension rules. For private (unregistered)
+ attribute extensions, implementers SHOULD use keywords with a
+ suitable distinguishing prefix as described in Section 6.1.
+
+ IANA will publish approved attribute registration specifications as
+ separate files:
+
+ ftp.isi.edu/iana/assignments/ipp/attributes/xxx-yyy.txt
+
+ where "xxx-yyy" is the new attribute name.
+
+ If a new Printer object attribute is defined and its values can be
+ affected by a specific document format, its specification needs to
+ contain the following sentence:
+
+ "The value of this attribute returned in a Get-Printer-Attributes
+ response MAY depend on the "document-format" attribute supplied
+ (see Section 3.2.5.1)."
+
+ If the specification does not, then its value in the Get-Printer-
+ Attributes response MUST NOT depend on the "document-format" supplied
+ in the request. When a new Job Template attribute is registered, the
+ value of the Printer attributes MAY vary with "document-format"
+ supplied in the request without the specification having to indicate
+ so.
+
+6.3 Attribute Syntax Extensibility
+
+ Attribute syntaxes are like type2 enums. Therefore, new attribute
+ syntaxes may be registered and have the same status as attribute
+ syntaxes in this document by following the type2 extension rules
+ described in Section 6.1. The value codes that identify each of the
+ attribute syntaxes are assigned in the Encoding and Transport
+ specification [RFC2565], including a designated range for private,
+ experimental use.
+
+ For attribute syntaxes, the IPP Designated Expert in consultation
+ with IANA assigns the next attribute syntax code in the appropriate
+ range as specified in [RFC2565]. IANA will publish approved
+ attribute syntax registration specifications as separate files:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-syntaxes/xxx-yyy.txt
+
+ where 'xxx-yyy' is the new attribute syntax name.
+
+
+
+deBry, et al. Experimental [Page 119]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+6.4 Operation Extensibility
+
+ Operations may also be registered following the type2 procedures
+ described in Section 6.1, though major new operations will usually be
+ done by a new standards track RFC that augments this document. For
+ private (unregistered) operation extensions, implementers MUST use
+ the range for the "operation-id" in requests specified in Section
+ 4.4.13 "operations-supported" Printer attribute.
+
+ For operations, the IPP Designated Expert in consultation with IANA
+ assigns the next operation-id code as specified in Section 4.4.13.
+ IANA will publish approved operation registration specifications as
+ separate files:
+
+ ftp.isi.edu/iana/assignments/ipp/operations/Xxx-Yyy.txt
+
+ where "Xxx-Yyy" is the new operation name.
+
+6.5 Attribute Groups
+
+ Attribute groups passed in requests and responses may be registered
+ following the type2 procedures described in Section 6.1. The tags
+ that identify each of the attribute groups are assigned in [RFC2565].
+
+ For attribute groups, the IPP Designated Expert in consultation with
+ IANA assigns the next attribute group tag code in the appropriate
+ range as specified in [RFC2565]. IANA will publish approved
+ attribute group registration specifications as separate files:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-group-tags/xxx-yyy-
+ tag.txt
+
+ where 'xxx-yyy-tag' is the new attribute group tag name.
+
+6.6 Status Code Extensibility
+
+ Operation status codes may also be registered following the type2
+ procedures described in Section 6.1. The values for status codes are
+ allocated in ranges as specified in Section 13 for each status code
+ class:
+
+ "informational" - Request received, continuing process
+ "successful" - The action was successfully received, understood,
+ and accepted
+ "redirection" - Further action must be taken in order to complete
+ the request
+ "client-error" - The request contains bad syntax or cannot be
+ fulfilled
+
+
+
+deBry, et al. Experimental [Page 120]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ "server-error" - The IPP object failed to fulfill an apparently
+ valid request
+
+ For private (unregistered) operation status code extensions,
+ implementers MUST use the top of each range as specified in Section
+ 13.
+
+ For operation status codes, the IPP Designated Expert in consultation
+ with IANA assigns the next status code in the appropriate class range
+ as specified in Section 13. IANA will publish approved status code
+ registration specifications as separate files:
+
+ ftp.isi.edu/iana/assignments/ipp/status-codes/xxx-yyy.txt
+
+ where "xxx-yyy" is the new operation status code keyword.
+
+6.7 Registration of MIME types/sub-types for document-formats
+
+ The "document-format" attribute's syntax is 'mimeMediaType'. This
+ means that valid values are Internet Media Types (see Section 4.1.9).
+ RFC 2045 [RFC2045] defines the syntax for valid Internet media types.
+ IANA is the registry for all Internet media types.
+
+6.8 Registration of charsets for use in 'charset' attribute values
+
+ The "attributes-charset" attribute's syntax is 'charset'. This means
+ that valid values are charsets names. When a charset in the IANA
+ registry has more than one name (alias), the name labeled as
+ "(preferred MIME name)", if present, MUST be used (see Section
+ 4.1.7). IANA is the registry for charsets following the procedures
+ of [RFC2278].
+
+7. Internationalization Considerations
+
+ Some of the attributes have values that are text strings and names
+ which are intended for human understanding rather than machine
+ understanding (see the 'text' and 'name' attribute syntaxes in
+ Sections 4.1.1 and 4.1.2).
+
+ In each operation request, the client
+
+ - identifies the charset and natural language of the request which
+ affects each supplied 'text' and 'name' attribute value, and
+ - requests the charset and natural language for attributes returned
+ by the IPP object in operation responses (as described in Section
+ 3.1.4.1).
+
+
+
+
+
+deBry, et al. Experimental [Page 121]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ In addition, the client MAY separately and individually identify the
+ Natural Language Override of a supplied 'text' or 'name' attribute
+ using the 'textWithLanguage' and 'nameWithLanguage' technique
+ described section 4.1.1.2 and 4.1.2.2 respectively.
+
+ All IPP objects MUST support the UTF-8 [RFC2279] charset in all '
+ text' and 'name' attributes supported. If an IPP object supports
+ more than the UTF-8 charset, the object MUST convert between them in
+ order to return the requested charset to the client according to
+ Section 3.1.4.2. If an IPP object supports more than one natural
+ language, the object SHOULD return 'text' and 'name' values in the
+ natural language requested where those values are generated by the
+ Printer (see Section 3.1.4.1).
+
+ For Printers that support multiple charsets and/or multiple natural
+ languages in 'text' and 'name' attributes, different jobs may have
+ been submitted in differing charsets and/or natural languages. All
+ responses MUST be returned in the charset requested by the client.
+ However, the Get-Jobs operation uses the 'textWithLanguage' and '
+ nameWithLanguage' mechanism to identify the differing natural
+ languages with each job attribute returned.
+
+ The Printer object also has configured charset and natural language
+ attributes. The client can query the Printer object to determine
+ the list of charsets and natural languages supported by the Printer
+ object and what the Printer object's configured values are. See the
+ "charset-configured", "charset-supported", "natural-language-
+ configured", and "generated-natural-language-supported" Printer
+ description attributes for more details.
+
+ The "charset-supported" attributed identifies the supported charsets.
+ If a charset is supported, the IPP object MUST be capable of
+ converting to and from that charset into any other supported charset.
+ In many cases, an IPP object will support only one charset and it
+ MUST be the UTF-8 charset.
+
+ The "charset-configured" attribute identifies the one supported
+ charset which is the native charset given the current configuration
+ of the IPP object (administrator defined).
+
+ The "generated-natural-language-supported" attribute identifies the
+ set of supported natural languages for generated messages; it is not
+ related to the set of natural languages that must be accepted for
+ client supplied 'text' and 'name' attributes. For client supplied '
+ text' and 'name' attributes, an IPP object MUST accept ALL supplied
+ natural languages. Just because a Printer object is currently
+
+
+
+
+
+deBry, et al. Experimental [Page 122]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ configured to support 'en-us' natural language does not mean that the
+ Printer object should reject a job if the client supplies a job name
+ that is in 'fr-ca'.
+
+ The "natural-language-configured" attribute identifies the one
+ supported natural language for generated messages which is the native
+ natural language given the current configuration of the IPP object
+ (administrator defined).
+
+ Attributes of type 'text' and 'name' are populated from different
+ sources. These attributes can be categorized into following groups
+ (depending on the source of the attribute):
+
+ 1. Some attributes are supplied by the client (e.g., the client
+ supplied "job-name", "document-name", and "requesting-user-name"
+ operation attributes along with the corresponding Job object's
+ "job-name" and "job-originating-user-name" attributes). The IPP
+ object MUST accept these attributes in any natural language no
+ matter what the set of supported languages for generated
+ messages
+ 2. Some attributes are supplied by the system administrator (e.g.,
+ the Printer object's "printer-name" and "printer-location"
+ attributes). These too can be in any natural language. If the
+ natural language for these attributes is different than what a
+ client requests, then they must be reported using the Natural
+ Language Override mechanism.
+ 3. Some attributes are supplied by the device manufacturer (e.g.,
+ the Printer object's "printer-make-and-model" attribute). These
+ too can be in any natural language. If the natural language for
+ these attributes is different than what a client requests, then
+ they must be reported using the Natural Language Override
+ mechanism.
+ 4. Some attributes are supplied by the operator (e.g., the Job
+ object's "job-message-from-operator" attribute). These too can
+ be in any natural language. If the natural language for these
+ attributes is different than what a client requests, then they
+ must be reported using the Natural Language Override mechanism.
+ 5. Some attributes are generated by the IPP object (e.g., the Job
+ object's "job-state-message" attribute, the Printer object's
+ "printer-state-message" attribute, and the "status-message"
+ operation attribute). These attributes can only be in one of
+ the "generated-natural-language-supported" natural languages.
+ If a client requests some natural language for these attributes
+ other than one of the supported values, the IPP object SHOULD
+ respond using the value of the "natural-language-configured"
+ attribute (using the Natural Language Override mechanism if
+ needed).
+
+
+
+
+deBry, et al. Experimental [Page 123]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ The 'text' and 'name' attributes specified in this version of this
+ document (additional ones will be registered according to the
+ procedures in Section 6) are:
+
+ Attributes Source
+ -------------------------- ----------
+ Operation Attributes
+ job-name (name) client
+ document-name (name) client
+ requesting-user-name (name) client
+ status-message Job or Printer object
+
+ Job Template Attributes:
+ job-hold-until) client matches administrator-configured
+ (keyword | name
+ job-hold-until-default client matches administrator-configured
+ (keyword | name)
+ job-hold-until-supported client matches administrator-configured
+ (keyword | name)
+ job-sheets client matches administrator-configured
+ (keyword | name)
+ job-sheets-default client matches administrator-configured
+ (keyword | name)
+ job-sheets-supported client matches administrator-configured
+ (keyword | name)
+ media client matches administrator-configured
+ (keyword | name)
+ media-default client matches administrator-configured
+ (keyword | name)
+ media-supported client matches administrator-configured
+ (keyword | name)
+ media-ready client matches administrator-configured
+ (keyword | name)
+
+ Job Description Attributes:
+ job-name (name) client or Printer object
+ job-originating-user-name (name) Printer object
+ job-state-message (text) Job or Printer object
+ output-device-assigned (name(127)) administrator
+ job-message-from-operator (text(127)) operator
+
+ Printer Description Attributes:
+ printer-name (name(127)) administrator
+ printer-location (text(127)) administrator
+ printer-info (text(127)) administrator
+ printer-make-and-model (text(127)) administrator or manufacturer
+ printer-state-message (text) Printer object
+ printer-message-from-operator (text(127)) operator
+
+
+
+deBry, et al. Experimental [Page 124]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+8. Security Considerations
+
+ Some IPP objects MAY be deployed over protocol stacks that support
+ Secure Socket Layer Version 3 (SSL3) [SSL]. Note: SSL3 is not an
+ IETF standards track specification. Other IPP objects MAY be
+ deployed over protocol stacks that do not support SSL3. Some IPP
+ objects MAY be deployed over both types of protocol stacks. Those
+ IPP objects that support SSL3, are capable of supporting mutual
+ authentication as well as privacy of messages via multiple encryption
+ schemes. An important point about security related information for
+ SSL3 access to an IPP object, is that the security-related parameters
+ (authentication, encryption keys, etc.) are "out-of-band" to the
+ actual IPP protocol.
+
+ An IPP object that does not support SSL3 MAY elect to support a
+ transport layer that provides other security mechanisms. For
+ example, in a mapping of IPP over HTTP/1.1 [RFC2565], if the IPP
+ object does not support SSL3, HTTP still allows for client
+ authentication using Digest Access Authentication (DAA) [RFC2069].
+
+ It is difficult to anticipate the security risks that might exist in
+ any given IPP environment. For example, if IPP is used within a given
+ corporation over a private network, the risks of exposing document
+ data may be low enough that the corporation will choose not to use
+ encryption on that data. However, if the connection between the
+ client and the IPP object is over a public network, the client may
+ wish to protect the content of the information during transmission
+ through the network with encryption.
+
+ Furthermore, the value of the information being printed may vary from
+ one IPP environment to the next. Printing payroll checks, for
+ example, would have a different value than printing public
+ information from a file. There is also the possibly of denial-of-
+ service attacks, but denial-of-service attacks against printing
+ resources are not well understood and there is no published
+ precedents regarding this scenario.
+
+ Once the authenticated identity of the requester has been supplied to
+ the IPP object, the object uses that identity to enforce any
+ authorization policy that might be in place. For example, one site's
+ policy might be that only the job owner is allowed to cancel a job.
+ The details and mechanisms to set up a particular access control
+ policy are not part of IPP/1.0, and must be established via some
+ other type of administrative or access control framework. However,
+ there are operation status codes that allow an IPP server to return
+ information back to a client about any potential access control
+ violations for an IPP object.
+
+
+
+
+deBry, et al. Experimental [Page 125]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ During a create operation, the client's identity is recorded in the
+ Job object in an implementation-defined attribute. This information
+ can be used to verify a client's identity for subsequent operations
+ on that Job object in order to enforce any access control policy that
+ might be in effect. See section 8.3 below for more details.
+
+ Since the security levels or the specific threats that any given IPP
+ system administrator may be concerned with cannot be anticipated, IPP
+ MUST be capable of operating with different security mechanisms and
+ security policies as required by the individual installation.
+ Security policies might vary from very strong, to very weak, to none
+ at all, and corresponding security mechanisms will be required. SSL3
+ supports the type of negotiated levels of security required by most,
+ if not all, potential IPP environments. IPP environments that require
+ no security can elect to deploy IPP objects that do not utilize the
+ optional SSL3 security mechanisms.
+
+8.1 Security Scenarios
+
+ The following sections describe specific security attacks for IPP
+ environments. Where examples are provided they should be considered
+ illustrative of the environment and not an exhaustive set. Not all of
+ these environments will necessarily be addressed in initial
+ implementations of IPP.
+
+8.1.1 Client and Server in the Same Security Domain
+
+ This environment is typical of internal networks where traditional
+ office workers print the output of personal productivity applications
+ on shared work-group printers, or where batch applications print
+ their output on large production printers. Although the identity of
+ the user may be trusted in this environment, a user might want to
+ protect the content of a document against such attacks as
+ eavesdropping, replaying or tampering.
+
+8.1.2 Client and Server in Different Security Domains
+
+ Examples of this environment include printing a document created by
+ the client on a publicly available printer, such as at a commercial
+ print shop; or printing a document remotely on a business associate's
+ printer. This latter operation is functionally equivalent to sending
+ the document to the business associate as a facsimile. Printing
+ sensitive information on a Printer in a different security domain
+ requires strong security measures. In this environment authentication
+ of the printer is required as well as protection against unauthorized
+ use of print resources. Since the document crosses security domains,
+
+
+
+
+
+deBry, et al. Experimental [Page 126]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ protection against eavesdropping and document tampering are also
+ required. It will also be important in this environment to protect
+ Printers against "spamming" and malicious document content.
+
+8.1.3 Print by Reference
+
+ When the document is not stored on the client, printing can be done
+ by reference. That is, the print request can contain a reference, or
+ pointer, to the document instead of the actual document itself.
+ Standard methods currently do not exist for remote entities to
+ "assume" the credentials of a client for forwarding requests to a 3rd
+ party. It is anticipated that Print-By-Reference will be used to
+ access "public" documents and that sophisticated methods for
+ authenticating "proxies" will not be specified for version 1 of IPP.
+
+8.2 URIs for SSL3 and non-SSL3 Access
+
+ As described earlier, an IPP object can support SSL3 access, non-SSL3
+ access, or both. The "printer-uri-supported" attribute contains the
+ Printer object's URI(s). Its companion attribute, "uri-security-
+ supported", identifies the security mechanism used for each URI
+ listed in the "printer-uri-supported" attribute. For each Printer
+ operation request, a client MUST supply only one URI in the
+ "printer-uri" operation attribute. In other words, even though the
+ Printer supports more than one URI, the client only interacts with
+ the Printer object using one if its URIs. This duality is not needed
+ for Job objects, since the Printer objects is the factory for Job
+ objects, and the Printer object will generate the correct URI for new
+ Job objects depending on the Printer object's security configuration.
+
+8.3 The "requesting-user-name" (name(MAX)) Operation Attribute
+
+ Each operation MUST specify the user who is performing the operation
+ in both of the following two ways:
+
+ 1) via the REQUIRED "requesting-user-name" operation attribute that
+ a client SHOULD supply in all operations. The client MUST obtain
+ the value for this attribute from an environmental or network
+ login name for the user, rather than allowing the user to supply
+ any value. If the client does not supply a value for
+ "requesting-user-name", the printer MUST assume that the client
+ is supplying some anonymous name, such as "anonymous".
+ 2) via an authentication mechanism of the underlying transport
+ which may be configured to give no authentication information.
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 127]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ There are six cases to consider:
+
+ a) the authentication mechanism gives no information, and the
+ client doesn't specify "requesting-user-name".
+ b) the authentication mechanism gives no information, but the
+ client specifies "requesting-user-name".
+ c) the authentication mechanism specifies a user which has no human
+ readable representation, and the client doesn't specify
+ "requesting-user-name".
+ d) the authentication mechanism specifies a user which has no human
+ readable representation, but the client specifies "requesting-
+ user-name".
+ e) the authentication mechanism specifies a user which has a human
+ readable representation. The Printer object ignores the
+ "requesting-user-name".
+ f) the authentication mechanism specifies a user who is trusted and
+ whose name means that the value of the "requesting-user-name",
+ which MUST be present, is treated as the authenticated name.
+
+ Note: Case "f" is intended for a tightly coupled gateway and server
+ to work together so that the "user" name is able to be that of the
+ gateway client and not that of the gateway. Because most, if not
+ all, system vendors will initially implement IPP via a gateway into
+ their existing print system, this mechanism is necessary unless the
+ authentication mechanism allows a gateway (client) to act on behalf
+ of some other client.
+
+ The user-name has two forms:
+
+ - one that is human readable: it is held in the REQUIRED "job-
+ originating-user-name" Job Description attribute which is set
+ during the job creation operations. It is used for presentation
+ only, such as returning in queries or printing on start sheets
+ - one for authorization: it is held in an undefined (by IPP) Job
+ object attribute which is set by the job creation operation. It
+ is used to authorize other operations, such as Send-Document,
+ Send-URI, Cancel-Job, to determine the user when the "my-jobs"
+ attribute is specified with Get-Jobs, and to limit what
+ attributes and values to return with Get-Job-Attributes and Get-
+ Jobs.
+
+ The human readable user name:
+
+ - is the value of the "requesting-user-name" for cases b, d and f.
+ - comes from the authentication mechanism for case e
+ - is some anonymous name, such as "anonymous" for cases a and c.
+
+ The user name used for authorization:
+
+
+
+deBry, et al. Experimental [Page 128]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ - is the value of the "requesting-user-name" for cases b and f.
+ - comes from the authentication mechanism for cases c, d and e
+ - is some anonymous name, such as "anonymous" for case a.
+
+ The essence of these rules for resolving conflicting sources of
+ user-names is that a printer implementation is free to pick either
+ source as long as it achieves consistent results. That is, if a user
+ uses the same path for a series of requests, the requests MUST appear
+ to come from the same user from the standpoint of both the human-
+ readable user name and the user name for authorization. This rule
+ MUST continue to apply even if a request could be authenticated by
+ two or more mechanisms. It doesn't matter which of several
+ authentication mechanisms a Printer uses as long as it achieves
+ consistent results. If a client uses more than one authentication
+ mechanism, it is recommended that an administrator make all
+ credentials resolve to the same user and user-name as much as
+ possible.
+
+8.4 Restricted Queries
+
+ In many IPP operations, a client supplies a list of attributes to be
+ returned in the response. For security reasons, an IPP object may be
+ configured not to return all attributes (or all values) that a client
+ requests. The job attributes returned MAY depend on whether the
+ requesting user is the same as the user that submitted the job. The
+ IPP object MAY even return none of the requested attributes. In such
+ cases, the status returned is the same as if the object had returned
+ all requested attributes. The client cannot tell by such a response
+ whether the requested attribute was present or absent on the object.
+
+8.5 Queries on jobs submitted using non-IPP protocols
+
+ If the device that an IPP Printer is representing is able to accept
+ jobs using other job submission protocols in addition to IPP, it is
+ RECOMMENDED that such an implementation at least allow such "foreign"
+ jobs to be queried using Get-Jobs returning "job-id" and "job-uri" as
+ 'unknown'. Such an implementation NEED NOT support all of the same
+ IPP job attributes as for IPP jobs. The IPP object returns the '
+ unknown' out-of-band value for any requested attribute of a foreign
+ job that is supported for IPP jobs, but not for foreign jobs.
+
+ It is further RECOMMENDED, that the IPP Printer generate "job-id" and
+ "job-uri" values for such "foreign jobs", if possible, so that they
+ may be targets of other IPP operations, such as Get-Job-Attributes
+ and Cancel-Job. Such an implementation also needs to deal with the
+ problem of authentication of such foreign jobs. One approach would
+ be to treat all such foreign jobs as belonging to users other than
+ the user of the IPP client. Another approach would be for the
+
+
+
+deBry, et al. Experimental [Page 129]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ foreign job to belong to 'anonymous'. Only if the IPP client has
+ been authenticated as an operator or administrator of the IPP Printer
+ object, could the foreign jobs be queried by an IPP request.
+ Alternatively, if the security policy is to allow users to query
+ other users' jobs, then the foreign jobs would also be visible to an
+ end-user IPP client using Get-Jobs and Get-Job-Attributes.
+
+8.6 IPP Security Application Profile for SSL3
+
+ The IPP application profile for SSL3 follows the "Secure Socket
+ Layer" requirement as documented in the SSL3 specification [SSL].
+ For interoperability, the SSL3 cipher suites are:
+
+ SSL_RSA_WITH_RC4_128_MD5
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA
+ SSL_RSA_WITH_DES_CBC_SHA
+ SSL_RSA_EXPORT_WITH_RC4_40_MD5
+ SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
+ SSL_RSA_WITH_NULL_MD5
+
+ Client implementations MUST NOT assume any other cipher suites are
+ supported by an IPP Printer object.
+
+ If a conforming IPP object supports SSL3, it MUST implement and
+ support the cipher suites listed above and MAY support additional
+ cipher suites.
+
+ A conforming IPP client SHOULD support SSL3 including the cipher
+ suites listed above. A conforming IPP client MAY support additional
+ cipher suites.
+
+ It is possible that due to certain government export restrictions
+ some non-compliant versions of this extension could be deployed.
+ Implementations wishing to inter-operate with such non-compliant
+ versions MAY offer the SSL_RSA_EXPORT_WITH_RC4_40_MD5 and
+ SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 mechanisms. However, since 40 bit
+ ciphers are known to be vulnerable to attack by current technology,
+ any client which actives a 40 bit cipher MUST NOT indicate to the
+ user that the connection is completely secure from eavesdropping.
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 130]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+9. References
+
+ [ASCII] Coded Character Set - 7-bit American Standard Code for
+ Information Interchange (ASCII), ANSI X3.4-1986. This
+ standard is the specification of the US-ASCII charset.
+
+ [HTPP] J. Barnett, K. Carter, R. DeBry, "Initial Draft -
+ Hypertext Printing Protocol - HTPP/1.0", October 1996.
+ ftp://ftp.pwg.org/pub/pwg/ipp/historic/htpp/
+ overview.ps.gz
+
+ [IANA-CS] IANA Registry of Coded Character Sets:
+ ftp://ftp.isi.edu/in-notes/iana/assignments/character-
+ sets
+
+ [IANA-MT] IANA Registry of Media Types: ftp://ftp.isi.edu/in-
+ notes/iana/assignments/media-types/
+
+ [ipp-iig] Hastings, T. and C. Manros, "Internet Printing
+ Protocol/1.0: Implementer's Guide", Work in Progress.
+
+ [ISO10646-1] ISO/IEC 10646-1:1993, "Information technology --
+ Universal Multiple-Octet Coded Character Set (UCS) -
+ Part 1: Architecture and Basic Multilingual Plane,
+ JTC1/SC2."
+
+ [ISO8859-1] ISO/IEC 8859-1:1987, "Information technology -- 8-bit
+ One-Byte Coded Character Set - Part 1: Latin Alphabet Nr
+ 1", 1987, JTC1/SC2.
+
+ [ISO10175] ISO/IEC 10175 Document Printing Application (DPA), June
+ 1996.
+
+ [LDPA] T. Hastings, S. Isaacson, M. MacKay, C. Manros, D. Taylor, P.
+ Zehler, "LDPA - Lightweight Document Printing
+ Application", October 1996,
+ ftp://ftp.pwg.org/pub/pwg/ipp/historic/ldpa/ldpa8.pdf.gz
+
+ [P1387.4] Kirk, M. (Editor), POSIX System Administration - Part 4:
+ Printing Interfaces, POSIX 1387.4 D8, 1994.
+
+ [PSIS] Herriot, R. (editor), X/Open A Printing System
+ Interoperability Specification (PSIS), August 1995.
+
+ [PWG] Printer Working Group, http://www.pwg.org.
+
+ [RFC1035] Mockapetris, P., "DOMAIN NAMES - IMPLEMENTATION AND
+ SPECIFICATION", STD 13, RFC 1035, November 1987.
+
+
+
+deBry, et al. Experimental [Page 131]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ [RFC1759] Smith, R., Wright, F., Hastings, T., Zilles, S. and J.
+ Gyllenskog, "Printer MIB", RFC 1759, March 1995.
+
+ [RFC1766] Alvestrand, H., "Tags for the Identification of
+ Languages", RFC 1766, March 1995.
+
+ [RFC1179] McLaughlin, L. (Editor), "Line Printer Daemon Protocol",
+ RFC 1179, August 1990.
+
+ [RFC1952] Deutsch, P., "GZIP file format specification version
+ 4.3", RFC 1952, May 1996.
+
+ [RFC2045] Freed, N. and N. Borenstein, " Multipurpose Internet
+ Mail Extensions (MIME) Part One: Format of Internet
+ Message Bodies", RFC 2045, November 1996.
+
+ [RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part Two: Media Types", RFC 2046,
+ November 1996.
+
+ [RFC2048] Freed, N., Klensin, J. and J. Postel, "Multipurpose
+ Internet Mail Extension (MIME) Part Four: Registration
+ Procedures", RFC 2048, November 1996.
+
+ [RFC2068] Fielding, R., Gettys, J., Mogul, J., Frystyk, H. AND T.
+ Berners-Lee, "Hypertext Transfer Protocol - HTTP/1.1",
+ RFC 2068, January 1997.
+
+ [RFC2069] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P.,
+ Luotonen, A., Sink, E. and L. Stewart, "An Extension to
+ HTTP: Digest Access Authentication", RFC 2069, January
+ 1997.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2228] Horowitz, M. and S. Lunt, "FTP Security Extensions", RFC
+ 2228, October 1997.
+
+ [RFC2277] Alvestrand, H., "IETF Policy on Character Sets and
+ Languages" RFC 2277, January 1998.
+
+ [RFC2278] Freed, N. and J. Postel: "IANA Charset Registration
+ Procedures", BCP 19, RFC 2278, January 1998.
+
+ [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
+ 10646", RFC 2279, January 1998.
+
+
+
+
+deBry, et al. Experimental [Page 132]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ [RFC2316] Bellovin, S., "Report of the IAB Security Architecture
+ Workshop", RFC 2316, April 1998.
+
+ [RFC2396] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform
+ Resource Identifiers (URI): Generic Syntax", RFC 2396,
+ August 1998.
+
+ [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an
+ IANA Considerations Section in RFCs", BCP 26, RFC 2434,
+ October 1998.
+
+ [RFC2565] Herriot, R., Butler, S., Moore, P. and R. Tuner
+ "Internet Printing Protocol/1.0: Encoding and
+ Transport", RFC 2565, April 1999.
+
+ [RFC2567] Wright, D., "Design Goals for an Internet Printing
+ Protocol", RFC 2567, April 1999.
+
+ [RFC2568] Zilles, S., "Rationale for the Structure and Model and
+ Protocol for the Internet Printing Protocol", RFC 2568,
+ April 1999.
+
+ [RFC2569] Herriot, R., Hastings, T., Jacobs, N. and J. Martin,
+ "Mapping between LPD and IPP Protocols", RFC 2569, April
+ 1999.
+
+ [RFC2579] McCloghrie, K., Perkins, D. and J. Schoenwaelder,
+ "Textual Conventions for SMIv2", STD 58, RFC 2579, April
+ 1999.
+
+ [SSL] Netscape, The SSL Protocol, Version 3, (Text version
+ 3.02), November 1996.
+
+ [SWP] P. Moore, B. Jahromi, S. Butler, "Simple Web Printing
+ SWP/1.0", May 7, 1997,
+ ftp://ftp.pwg.org/pub/pwg/ipp/new_PRO/swp9705.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 133]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+10. Authors' Addresses
+
+ Scott A. Isaacson (Editor)
+ Novell, Inc.
+ 122 E 1700 S
+ Provo, UT 84606
+
+ Phone: 801-861-7366
+ Fax: 801-861-2517
+ EMail: sisaacson@novell.com
+
+
+ Tom Hastings
+ Xerox Corporation
+ 737 Hawaii St.
+ El Segundo, CA 90245
+
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ EMail: hastings@cp10.es.xerox.com
+
+
+ Robert Herriot
+ Xerox Corporation
+ 3400 Hillview Ave., Bldg #1
+ Palo Alto, CA 94304
+
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ EMail: robert.herriot@pahv.xerox.com
+
+
+ Roger deBry
+ Utah Valley State College
+ Orem, UT 84058
+
+ Phone: (801) 222-8000
+ EMail: debryro@uvsc.edu
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 134]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Patrick Powell
+ Astart Technologies
+ 9475 Chesapeake Dr., Suite D
+ San Diego, CA 95123
+
+ Phone: (619) 874-6543
+ Fax: (619) 279-8424
+ EMail: papowell@astart.com
+
+ IPP Mailing List: ipp@pwg.org
+ IPP Mailing List Subscription: ipp-request@pwg.org
+ IPP Web Page: http://www.pwg.org/ipp/
+
+ Implementers of this specification are encouraged to join IPP Mailing
+ List in order to participate in any discussions of clarification
+ issues and review of registration proposals for additional attributes
+ and values.
+
+ Other Participants:
+
+ Chuck Adams - Tektronix
+ Jeff Barnett - IBM
+ Ron Bergman - Dataproducts Corp.
+ Sylvan Butler - HP
+ Keith Carter - IBM Corporation
+ Jeff Copeland - QMS
+ Andy Davidson - Tektronix
+ Mabry Dozier - QMS
+ Lee Farrell - Canon Information Systems
+ Steve Gebert - IBM
+ Babek Jahromi - Microsoft
+ David Kellerman - Northlake Software
+ Rick Landau - Digital
+ Greg LeClair - Epson
+ Harry Lewis - IBM
+ Pete Loya - HP
+ Ray Lutz - Cognisys
+ Mike MacKay - Novell, Inc.
+ Daniel Manchala - Xerox
+ Carl-Uno Manros - Xerox
+ Jay Martin - Underscore
+ Larry Masinter - Xerox
+ Stan McConnell - Xerox
+ Ira McDonald - High North Inc.
+ Paul Moore - Microsoft
+ Tetsuya Morita - Ricoh
+ Yuichi Niwa - Ricoh
+ Pat Nogay - IBM
+
+
+
+deBry, et al. Experimental [Page 135]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Ron Norton - Printronics
+ Bob Pentecost - HP
+ Rob Rhoads - Intel
+ Xavier Riley - Xerox
+ David Roach - Unisys
+ Stuart Rowley - Kyocera
+ Hiroyuki Sato - Canon
+ Bob Setterbo - Adobe
+ Devon Taylor - Novell, Inc.
+ Mike Timperman - Lexmark
+ Randy Turner - Sharp
+ Atsushi Yuki - Kyocera
+ Rick Yardumian - Xerox
+ Lloyd Young - Lexmark
+ Bill Wagner - DPI
+ Jim Walker - DAZEL
+ Chris Wellens - Interworking Labs
+ Rob Whittle - Novell, Inc.
+ Don Wright - Lexmark
+ Peter Zehler - Xerox
+ Steve Zilles - Adobe
+
+11. Formats for IPP Registration Proposals
+
+ In order to propose an IPP extension for registration, the proposer
+ must submit an application to IANA by email to "iana@iana.org" or by
+ filling out the appropriate form on the IANA web pages
+ (http://www.iana.org). This section specifies the required
+ information and the formats for proposing registrations of extensions
+ to IPP as provided in Section 6 for:
+
+ 1. type2 'keyword' attribute values
+ 2. type3 'keyword' attribute values
+ 3. type2 'enum' attribute values
+ 4. type3 'enum' attribute values
+ 5. attributes
+ 6. attribute syntaxes
+ 7. operations
+ 8. status codes
+
+11.1 Type2 keyword attribute values registration
+
+ Type of registration: type2 keyword attribute value
+ Name of attribute to which this keyword specification is to be added:
+ Proposed keyword name of this keyword value:
+ Specification of this keyword value (follow the style of IPP Model
+ Section 4.1.2.3):
+ Name of proposer:
+
+
+
+deBry, et al. Experimental [Page 136]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For type2 keywords, the Designated Expert will be the point of
+ contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.2 Type3 keyword attribute values registration
+
+ Type of registration: type3 keyword attribute value
+ Name of attribute to which this keyword specification is to be added:
+ Proposed keyword name of this keyword value:
+ Specification of this keyword value (follow the style of IPP Model
+ Section 4.1.2.3):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For type3 keywords, the proposer will be the point of contact
+ for the approved registration specification, if any maintenance of
+ the registration specification is needed.
+
+11.3 Type2 enum attribute values registration
+
+ Type of registration: type2 enum attribute value
+ Name of attribute to which this enum specification is to be added:
+ Keyword symbolic name of this enum value:
+ Numeric value (to be assigned by the IPP Designated Expert in
+ consultation with IANA):
+ Specification of this enum value (follow the style of IPP Model
+ Section 4.1.4):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For type2 enums, the Designated Expert will be the point of
+ contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.4 Type3 enum attribute values registration
+
+ Type of registration: type3 enum attribute value
+ Name of attribute to which this enum specification is to be added:
+ Keyword symbolic name of this enum value:
+ Numeric value (to be assigned by the IPP Designated Expert in
+ consultation with IANA):
+ Specification of this enum value (follow the style of IPP Model
+ Section 4.1.4):
+
+
+
+deBry, et al. Experimental [Page 137]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For type3 enums, the proposer will be the point of contact for
+ the approved registration specification, if any maintenance of the
+ registration specification is needed.
+
+11.5 Attribute registration
+
+ Type of registration: attribute
+ Proposed keyword name of this attribute:
+ Types of attribute (Operation, Job Template, Job Description,
+ Printer Description):
+ Operations to be used with if the attribute is an operation
+ attribute:
+ Object (Job, Printer, etc. if bound to an object):
+ Attribute syntax(es) (include 1setOf and range as in Section 4.2):
+ If attribute syntax is 'keyword' or 'enum', is it type2 or type3:
+ If this is a Printer attribute, MAY the value returned depend on
+ "document-format" (See Section 6.2):
+ If this is a Job Template attribute, how does its specification
+ depend on the value of the "multiple-document-handling" attribute:
+ Specification of this attribute (follow the style of IPP Model
+ Section 4.2):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For attributes, the IPP Designated Expert will be the point of
+ contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.6 Attribute Syntax registration
+
+ Type of registration: attribute syntax
+ Proposed name of this attribute syntax:
+ Type of attribute syntax (integer, octetString, character-string,
+ see [RFC2565]):
+ Numeric value (to be assigned by the IPP Designated Expert in
+ consultation with IANA):
+ Specification of this attribute (follow the style of IPP Model
+ Section 4.1):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+
+
+
+
+deBry, et al. Experimental [Page 138]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Note: For attribute syntaxes, the IPP Designated Expert will be the
+ point of contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.7 Operation registration
+
+ Type of registration: operation
+ Proposed name of this operation:
+ Numeric operation-id value (to be assigned by the IPP Designated
+ Expert in consultation with IANA):
+ Object Target (Job, Printer, etc. that operation is upon):
+ Specification of this attribute (follow the style of IPP Model
+ Section 3):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For operations, the IPP Designated Expert will be the point of
+ contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.8 Attribute Group registration
+
+ Type of registration: attribute group
+ Proposed name of this attribute group:
+ Numeric tag according to [RFC2565] (to be assigned by the IPP
+ Designated Expert in consultation with IANA):
+ Operation requests and group number for each operation in which the
+ attribute group occurs:
+ Operation responses and group number for each operation in which the
+ attribute group occurs:
+ Specification of this attribute group (follow the style of IPP Model
+ Section 3):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For attribute groups, the IPP Designated Expert will be the
+ point of contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.9 Status code registration
+
+ Type of registration: status code
+ Keyword symbolic name of this status code value:
+ Numeric value (to be assigned by the IPP Designated Expert in
+ consultation with IANA):
+ Operations that this status code may be used with:
+
+
+
+deBry, et al. Experimental [Page 139]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ Specification of this status code (follow the style of IPP Model
+ Section 14 APPENDIX B: Status Codes and Suggested Status Code
+ Messages):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For status codes, the Designated Expert will be the point of
+ contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 140]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+12. APPENDIX A: Terminology
+
+ This specification uses the terminology defined in this section.
+
+12.1 Conformance Terminology
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
+ "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
+ interpreted as described in RFC 2119 [RFC2119].
+
+12.1.1 NEED NOT
+
+ This term is not included in RFC 2119. The verb "NEED NOT" indicates
+ an action that the subject of the sentence does not have to implement
+ in order to claim conformance to the standard. The verb "NEED NOT"
+ is used instead of "MAY NOT" since "MAY NOT" sounds like a
+ prohibition.
+
+12.2 Model Terminology
+
+12.2.1 Keyword
+
+ Keywords are used within this document as identifiers of semantic
+ entities within the abstract model (see section 4.1.2.3). Attribute
+ names, some attribute values, attribute syntaxes, and attribute group
+ names are represented as keywords.
+
+12.2.2 Attributes
+
+ An attribute is an item of information that is associated with an
+ instance of an IPP object. An attribute consists of an attribute
+ name and one or more attribute values. Each attribute has a specific
+ attribute syntax. All object attributes are defined in section 4 and
+ all operation attributes are defined in section 3.
+
+ Job Template Attributes are described in section 4.2. The client
+ optionally supplies Job Template attributes in a create request
+ (operation requests that create Job objects). The Printer object has
+ associated attributes which define supported and default values for
+ the Printer.
+
+12.2.2.1 Attribute Name
+
+ Each attribute is uniquely identified in this document by its
+ attribute name. An attribute name is a keyword. The keyword
+ attribute name is given in the section header describing that
+
+
+
+
+
+deBry, et al. Experimental [Page 141]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ attribute. In running text in this document, attribute names are
+ indicated inside double quotation marks (") where the quotation marks
+ are not part of the keyword itself.
+
+12.2.2.2 Attribute Group Name
+
+ Related attributes are grouped into named groups. The name of the
+ group is a keyword. The group name may be used in place of naming
+ all the attributes in the group explicitly. Attribute groups are
+ defined in section 3.
+
+12.2.2.3 Attribute Value
+
+ Each attribute has one or more values. Attribute values are
+ represented in the syntax type specified for that attribute. In
+ running text in this document, attribute values are indicated inside
+ single quotation marks ('), whether their attribute syntax is
+ keyword, integer, text, etc. where the quotation marks are not part
+ of the value itself.
+
+12.2.2.4 Attribute Syntax
+
+ Each attribute is defined using an explicit syntax type. In this
+ document, each syntax type is defined as a keyword with specific
+ meaning. The Encoding and Transport document [RFC2565] indicates the
+ actual "on-the-wire" encoding rules for each syntax type. Attribute
+ syntax types are defined in section 4.1.
+
+12.2.3 Supports
+
+ By definition, a Printer object supports an attribute only if that
+ Printer object responds with the corresponding attribute populated
+ with some value(s) in a response to a query for that attribute. A
+ Printer object supports an attribute value if the value is one of the
+ Printer object's "supported values" attributes. The device behind a
+ Printer object may exhibit a behavior that corresponds to some IPP
+ attribute, but if the Printer object, when queried for that
+ attribute, doesn't respond with the attribute, then as far as IPP is
+ concerned, that implementation does not support that feature. If the
+ Printer object's "xxx-supported" attribute is not populated with a
+ particular value (even if that value is a legal value for that
+ attribute), then that Printer object does not support that particular
+ value.
+
+ A conforming implementation MUST support all REQUIRED attributes.
+ However, even for REQUIRED attributes, conformance to IPP does not
+ mandate that all implementations support all possible values
+ representing all possible job processing behaviors and features. For
+
+
+
+deBry, et al. Experimental [Page 142]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ example, if a given instance of a Printer supports only certain
+ document formats, then that Printer responds with the "document-
+ format-supported" attribute populated with a set of values, possibly
+ only one, taken from the entire set of possible values defined for
+ that attribute. This limited set of values represents the Printer's
+ set of supported document formats. Supporting an attribute and some
+ set of values for that attribute enables IPP end users to be aware of
+ and make use of those features associated with that attribute and
+ those values. If an implementation chooses to not support an
+ attribute or some specific value, then IPP end users would have no
+ ability to make use of that feature within the context of IPP itself.
+ However, due to existing practice and legacy systems which are not
+ IPP aware, there might be some other mechanism outside the scope of
+ IPP to control or request the "unsupported" feature (such as embedded
+ instructions within the document data itself).
+
+ For example, consider the "finishings-supported" attribute.
+
+ 1) If a Printer object is not physically capable of stapling, the
+ "finishings-supported" attribute MUST NOT be populated with the
+ value of 'staple'.
+ 2) A Printer object is physically capable of stapling, however an
+ implementation chooses not to support stapling in the IPP
+ "finishings" attribute. In this case, 'staple' MUST NOT be a
+ value in the "finishings-supported" Printer object attribute.
+ Without support for the value 'staple', an IPP end user would
+ have no means within the protocol itself to request that a Job
+ be stapled. However, an existing document data formatter might
+ be able to request that the document be stapled directly with an
+ embedded instruction within the document data. In this case,
+ the IPP implementation does not "support" stapling, however the
+ end user is still able to have some control over the stapling of
+ the completed job.
+ 3) A Printer object is physically capable of stapling, and an
+ implementation chooses to support stapling in the IPP
+ "finishings" attribute. In this case, 'staple' MUST be a value
+ in the "finishings-supported" Printer object attribute. Doing
+ so, would enable end users to be aware of and make use of the
+ stapling feature using IPP attributes.
+
+ Even though support for Job Template attributes by a Printer object
+ is OPTIONAL, it is RECOMMENDED that if the device behind a Printer
+ object is capable of realizing any feature or function that
+ corresponds to an IPP attribute and some associated value, then that
+ implementation SHOULD support that IPP attribute and value.
+
+
+
+
+
+
+deBry, et al. Experimental [Page 143]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ The set of values in any of the supported value attributes is set
+ (populated) by some administrative process or automatic sensing
+ mechanism that is outside the scope of IPP. For administrative
+ policy and control reasons, an administrator may choose to make only
+ a subset of possible values visible to the end user. In this case,
+ the real output device behind the IPP Printer abstraction may be
+ capable of a certain feature, however an administrator is specifying
+ that access to that feature not be exposed to the end user through
+ the IPP protocol. Also, since a Printer object may represent a
+ logical print device (not just a physical device) the actual process
+ for supporting a value is undefined and left up to the
+ implementation. However, if a Printer object supports a value, some
+ manual human action may be needed to realize the semantic action
+ associated with the value, but no end user action is required.
+
+ For example, if one of the values in the "finishings-supported"
+ attribute is 'staple', the actual process might be an automatic
+ staple action by a physical device controlled by some command sent to
+ the device. Or, the actual process of stapling might be a manual
+ action by an operator at an operator attended Printer object.
+
+ For another example of how supported attributes function, consider a
+ system administrator who desires to control all print jobs so that no
+ job sheets are printed in order to conserve paper. To force no job
+ sheets, the system administrator sets the only supported value for
+ the "job-sheets-supported" attribute to 'none'. In this case, if a
+ client requests anything except 'none', the create request is
+ rejected or the "job-sheets" value is ignored (depending on the value
+ of "ipp-attribute-fidelity"). To force the use of job start/end
+ sheets on all jobs, the administrator does not include the value '
+ none' in the "job-sheets-supported" attribute. In this case, if a
+ client requests 'none', the create request is rejected or the "job-
+ sheets" value is ignored (again depending on the value of "ipp-
+ attribute-fidelity").
+
+12.2.4 print-stream page
+
+ A "print-stream page" is a page according to the definition of pages
+ in the language used to express the document data.
+
+12.2.5 impression
+
+ An "impression" is the image (possibly many print-stream pages in
+ different configurations) imposed onto a single media page.
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 144]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+13. APPENDIX B: Status Codes and Suggested Status Code Messages
+
+ This section defines status code enum keywords and values that are
+ used to provide semantic information on the results of an operation
+ request. Each operation response MUST include a status code. The
+ response MAY also contain a status message that provides a short
+ textual description of the status. The status code is intended for
+ use by automata, and the status message is intended for the human end
+ user. Since the status message is an OPTIONAL component of the
+ operation response, an IPP application (i.e., a browser, GUI, print
+ driver or gateway) is NOT REQUIRED to examine or display the status
+ message, since it MAY not be returned to the application.
+
+ The prefix of the status keyword defines the class of response as
+ follows:
+
+ "informational" - Request received, continuing process
+ "successful" - The action was successfully received, understood,
+ and accepted
+ "redirection" - Further action must be taken in order to complete
+ the request
+ "client-error" - The request contains bad syntax or cannot be
+ fulfilled
+ "server-error" - The IPP object failed to fulfill an apparently
+ valid request
+
+ As with type2 enums, IPP status codes are extensible. IPP clients
+ are NOT REQUIRED to understand the meaning of all registered status
+ codes, though such understanding is obviously desirable. However,
+ IPP clients MUST understand the class of any status code, as
+ indicated by the prefix, and treat any unrecognized response as being
+ equivalent to the first status code of that class, with the exception
+ that an unrecognized response MUST NOT be cached. For example, if an
+ unrecognized status code of "client-error-xxx-yyy" is received by the
+ client, it can safely assume that there was something wrong with its
+ request and treat the response as if it had received a "client-
+ error-bad-request" status code. In such cases, IPP applications
+ SHOULD present the OPTIONAL message (if present) to the end user
+ since the message is likely to contain human readable information
+ which will help to explain the unusual status. The name of the enum
+ is the suggested status message for US English.
+
+ The status code values range from 0x0000 to 0x7FFF. The value ranges
+ for each status code class are as follows:
+
+ "successful" - 0x0000 to 0x00FF
+ "informational" - 0x0100 to 0x01FF
+ "redirection" - 0x0200 to 0x02FF
+
+
+
+deBry, et al. Experimental [Page 145]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ "client-error" - 0x0400 to 0x04FF
+ "server-error" - 0x0500 to 0x05FF
+
+ The top half (128 values) of each range (0x0n40 to 0x0nFF, for n = 0
+ to 5) is reserved for private use within each status code class.
+ Values 0x0600 to 0x7FFF are reserved for future assignment and MUST
+ NOT be used.
+
+13.1 Status Codes
+
+ Each status code is described below. Section 13.1.5.9 contains a
+ table that indicates which status codes apply to which operations.
+ The Implementer's Guide [ipp-iig] describe the suggested steps for
+ processing IPP attributes for all operations, including returning
+ status codes.
+
+13.1.1 Informational
+
+ This class of status code indicates a provisional response and is to
+ be used for informational purposes only.
+
+ There are no status codes defined in IPP/1.0 for this class of status
+ code.
+
+13.1.2 Successful Status Codes
+
+ This class of status code indicates that the client's request was
+ successfully received, understood, and accepted.
+
+13.1.2.1 successful-ok (0x0000)
+
+ The request has succeeded and no request attributes were substituted
+ or ignored. In the case of a response to a create request, the '
+ successful-ok' status code indicates that the request was
+ successfully received and validated, and that the Job object has been
+ created; it does not indicate that the job has been processed. The
+ transition of the Job object into the 'completed' state is the only
+ indicator that the job has been printed.
+
+13.1.2.2 successful-ok-ignored-or-substituted-attributes (0x0001)
+
+ The request has succeeded, but some supplied (1) attributes were
+ ignored or (2) unsupported values were substituted with supported
+ values or were ignored in order to perform the operation without
+ rejecting it. Unsupported attributes, attribute syntaxes, or values
+ MUST be returned in the Unsupported Attributes group of the response
+ for all operations. There is an exception to this rule for the query
+ operations: Get-Printer-Attributes, Get-Jobs, and Get-Job-Attributes
+
+
+
+deBry, et al. Experimental [Page 146]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ for the "requested-attributes" operation attribute only. When the
+ supplied values of the "requested-attributes" operation attribute are
+ requesting attributes that are not supported, the IPP object MAY, but
+ is NOT REQUIRED to, return the "requested-attributes" attribute in
+ the Unsupported Attribute response group (with the unsupported values
+ only). See section 3.2.1.2.
+
+13.1.2.3 successful-ok-conflicting-attributes (0x0002)
+
+ The request has succeeded, but some supplied attribute values
+ conflicted with the values of other supplied attributes. These
+ conflicting values were either (1) substituted with (supported)
+ values or (2) the attributes were removed in order to process the job
+ without rejecting it. Attributes or values which conflict with other
+ attributes and have been substituted or ignored MUST be returned in
+ the Unsupported Attributes group of the response for all operations
+ as supplied by the client. See section 3.2.1.2.
+
+13.1.3 Redirection Status Codes
+
+ This class of status code indicates that further action needs to be
+ taken to fulfill the request.
+
+ There are no status codes defined in IPP/1.0 for this class of status
+ code.
+
+13.1.4 Client Error Status Codes
+
+ This class of status code is intended for cases in which the client
+ seems to have erred. The IPP object SHOULD return a message
+ containing an explanation of the error situation and whether it is a
+ temporary or permanent condition.
+
+13.1.4.1 client-error-bad-request (0x0400)
+
+ The request could not be understood by the IPP object due to
+ malformed syntax (such as the value of a fixed length attribute whose
+ length does not match the prescribed length for that attribute - see
+ the Implementer's Guide [ipp-iig] ). The IPP application SHOULD NOT
+ repeat the request without modifications.
+
+13.1.4.2 client-error-forbidden (0x0401)
+
+ The IPP object understood the request, but is refusing to fulfill it.
+ Additional authentication information or authorization credentials
+ will not help and the request SHOULD NOT be repeated. This status
+
+
+
+
+
+deBry, et al. Experimental [Page 147]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ code is commonly used when the IPP object does not wish to reveal
+ exactly why the request has been refused or when no other response is
+ applicable.
+
+13.1.4.3 client-error-not-authenticated (0x0402)
+
+ The request requires user authentication. The IPP client may repeat
+ the request with suitable authentication information. If the request
+ already included authentication information, then this status code
+ indicates that authorization has been refused for those credentials.
+ If this response contains the same challenge as the prior response,
+ and the user agent has already attempted authentication at least
+ once, then the response message may contain relevant diagnostic
+ information. This status codes reveals more information than
+ "client-error-forbidden".
+
+13.1.4.4 client-error-not-authorized (0x0403)
+
+ The requester is not authorized to perform the request. Additional
+ authentication information or authorization credentials will not help
+ and the request SHOULD NOT be repeated. This status code is used
+ when the IPP object wishes to reveal that the authentication
+ information is understandable, however, the requester is explicitly
+ not authorized to perform the request. This status codes reveals
+ more information than "client-error-forbidden" and "client-error-
+ not-authenticated".
+
+13.1.4.5 client-error-not-possible (0x0404)
+
+ This status code is used when the request is for something that can
+ not happen. For example, there might be a request to cancel a job
+ that has already been canceled or aborted by the system. The IPP
+ client SHOULD NOT repeat the request.
+
+13.1.4.6 client-error-timeout (0x0405)
+
+ The client did not produce a request within the time that the IPP
+ object was prepared to wait. For example, a client issued a Create-
+ Job operation and then, after a long period of time, issued a Send-
+ Document operation and this error status code was returned in
+ response to the Send-Document request (see section 3.3.1). The IPP
+ object might have been forced to clean up resources that had been
+ held for the waiting additional Documents. The IPP object was forced
+ to close the Job since the client took too long. The client SHOULD
+ NOT repeat the request without modifications.
+
+
+
+
+
+
+deBry, et al. Experimental [Page 148]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+13.1.4.7 client-error-not-found (0x0406)
+
+ The IPP object has not found anything matching the request URI. No
+ indication is given of whether the condition is temporary or
+ permanent. For example, a client with an old reference to a Job (a
+ URI) tries to cancel the Job, however in the mean time the Job might
+ have been completed and all record of it at the Printer has been
+ deleted. This status code, 'client-error-not-found' is returned
+ indicating that the referenced Job can not be found. This error
+ status code is also used when a client supplies a URI as a reference
+ to the document data in either a Print-URI or Send-URI operation, but
+ the document can not be found.
+
+ In practice, an IPP application should avoid a not found situation by
+ first querying and presenting a list of valid Printer URIs and Job
+ URIs to the end-user.
+
+13.1.4.8 client-error-gone (0x0407)
+
+ The requested object is no longer available and no forwarding address
+ is known. This condition should be considered permanent. Clients
+ with link editing capabilities should delete references to the
+ request URI after user approval. If the IPP object does not know or
+ has no facility to determine, whether or not the condition is
+ permanent, the status code "client-error-not-found" should be used
+ instead.
+
+ This response is primarily intended to assist the task of maintenance
+ by notifying the recipient that the resource is intentionally
+ unavailable and that the IPP object administrator desires that remote
+ links to that resource be removed. It is not necessary to mark all
+ permanently unavailable resources as "gone" or to keep the mark for
+ any length of time -- that is left to the discretion of the IPP
+ object administrator.
+
+13.1.4.9 client-error-request-entity-too-large (0x0408)
+
+ The IPP object is refusing to process a request because the request
+ entity is larger than the IPP object is willing or able to process.
+ An IPP Printer returns this status code when it limits the size of
+ print jobs and it receives a print job that exceeds that limit or
+ when the attributes are so many that their encoding causes the
+ request entity to exceed IPP object capacity.
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 149]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+13.1.4.10 client-error-request-value-too-long (0x0409)
+
+ The IPP object is refusing to service the request because one or more
+ of the client-supplied attributes has a variable length value that is
+ longer than the maximum length specified for that attribute. The IPP
+ object might not have sufficient resources (memory, buffers, etc.) to
+ process (even temporarily), interpret, and/or ignore a value larger
+ than the maximum length. Another use of this error code is when the
+ IPP object supports the processing of a large value that is less than
+ the maximum length, but during the processing of the request as a
+ whole, the object may pass the value onto some other system component
+ which is not able to accept the large value. For more details, see
+ the Implementer's Guide [ipp-iig] .
+
+ Note: For attribute values that are URIs, this rare condition is
+ only likely to occur when a client has improperly submitted a request
+ with long query information (e.g. an IPP application allows an end-
+ user to enter an invalid URI), when the client has descended into a
+ URI "black hole" of redirection (e.g., a redirected URI prefix that
+ points to a suffix of itself), or when the IPP object is under attack
+ by a client attempting to exploit security holes present in some IPP
+ objects using fixed-length buffers for reading or manipulating the
+ Request-URI.
+
+13.1.4.11 client-error-document-format-not-supported (0x040A)
+
+ The IPP object is refusing to service the request because the
+ document data is in a format, as specified in the "document-format"
+ operation attribute, that is not supported by the Printer object.
+ This error is returned independent of the client-supplied "ipp-
+ attribute-fidelity". The Printer object MUST return this status
+ code, even if there are other attributes that are not supported as
+ well, since this error is a bigger problem than with Job Template
+ attributes.
+
+13.1.4.12 client-error-attributes-or-values-not-supported (0x040B)
+
+ In a create request, if the Printer object does not support one or
+ more attributes, attribute syntaxes, or attribute values supplied in
+ the request and the client supplied the "ipp-attributes-fidelity"
+ operation attribute with the 'true' value, the Printer object MUST
+ return this status code. For example, if the request indicates '
+ iso-a4' media, but that media type is not supported by the Printer
+ object. Or, if the client supplies an optional attribute and the
+ attribute itself is not even supported by the Printer. If the "ipp-
+ attribute-fidelity" attribute is 'false', the Printer MUST ignore or
+ substitute values for unsupported attributes and values rather than
+ reject the request and return this status code.
+
+
+
+deBry, et al. Experimental [Page 150]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ For any operation where a client requests attributes (such as a Get-
+ Jobs, Get-Printer-Attributes, or Get-Job-Attributes operation), if
+ the IPP object does not support one or more of the requested
+ attributes, the IPP object simply ignores the unsupported requested
+ attributes and processes the request as if they had not been
+ supplied, rather than returning this status code. In this case, the
+ IPP object MUST return the 'successful-ok-ignored-or-substituted-
+ attributes' status code and MAY return the unsupported attributes as
+ values of the "requested-attributes" in the Unsupported Attributes
+ Group (see section 13.1.2.2).
+
+13.1.4.13 client-error-uri-scheme-not-supported (0x040C)
+
+ The type of the client supplied URI in a Print-URI or a Send-URI
+ operation is not supported.
+
+13.1.4.14 client-error-charset-not-supported (0x040D)
+
+ For any operation, if the IPP Printer does not support the charset
+ supplied by the client in the "attributes-charset" operation
+ attribute, the Printer MUST reject the operation and return this
+ status and any 'text' or 'name' attributes using the 'utf-8' charset
+ (see Section 3.1.4.1).
+
+13.1.4.15 client-error-conflicting-attributes (0x040E)
+
+ The request is rejected because some attribute values conflicted with
+ the values of other attributes which this specification does not
+ permit to be substituted or ignored.
+
+13.1.5 Server Error Status Codes
+
+ This class of status codes indicates cases in which the IPP object is
+ aware that it has erred or is incapable of performing the request.
+ The IPP object SHOULD include a message containing an explanation of
+ the error situation, and whether it is a temporary or permanent
+ condition.
+
+13.1.5.1 server-error-internal-error (0x0500)
+
+ The IPP object encountered an unexpected condition that prevented it
+ from fulfilling the request. This error status code differs from
+ "server-error-temporary-error" in that it implies a more permanent
+ type of internal error. It also differs from "server-error-device-
+ error" in that it implies an unexpected condition (unlike a paper-jam
+ or out-of-toner problem which is undesirable but expected). This
+ error status code indicates that probably some knowledgeable human
+ intervention is required.
+
+
+
+deBry, et al. Experimental [Page 151]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+13.1.5.2 server-error-operation-not-supported (0x0501)
+
+ The IPP object does not support the functionality required to fulfill
+ the request. This is the appropriate response when the IPP object
+ does not recognize an operation or is not capable of supporting it.
+
+13.1.5.3 server-error-service-unavailable (0x0502)
+
+ The IPP object is currently unable to handle the request due to a
+ temporary overloading or maintenance of the IPP object. The
+ implication is that this is a temporary condition which will be
+ alleviated after some delay. If known, the length of the delay may be
+ indicated in the message. If no delay is given, the IPP application
+ should handle the response as it would for a "server-error-
+ temporary-error" response. If the condition is more permanent, the
+ error status codes "client-error-gone" or "client-error-not-found"
+ could be used.
+
+13.1.5.4 server-error-version-not-supported (0x0503)
+
+ The IPP object does not support, or refuses to support, the IPP
+ protocol version that was used in the request message. The IPP
+ object is indicating that it is unable or unwilling to complete the
+ request using the same version as supplied in the request other than
+ with this error message. The response should contain a Message
+ describing why that version is not supported and what other versions
+ are supported by that IPP object.
+
+ A conforming IPP/1.0 client MUST specify the valid version ('1.0') on
+ each request. A conforming IPP/1.0 object MUST NOT return this
+ status code to a conforming IPP/1.0 client. An IPP object MUST
+ return this status code to a non-conforming IPP client. The response
+ MUST identify in the "version-number" operation attribute the closest
+ version number that the IPP object does support.
+
+13.1.5.5 server-error-device-error (0x0504)
+
+ A printer error, such as a paper jam, occurs while the IPP object
+ processes a Print or Send operation. The response contains the true
+ Job Status (the values of the "job-state" and "job-state-reasons"
+ attributes). Additional information can be returned in the optional
+ "job-state-message" attribute value or in the OPTIONAL status message
+ that describes the error in more detail. This error status code is
+ only returned in situations where the Printer is unable to accept the
+ create request because of such a device error. For example, if the
+ Printer is unable to spool, and can only accept one job at a time,
+ the reason it might reject a create request is that the printer
+ currently has a paper jam. In many cases however, where the Printer
+
+
+
+deBry, et al. Experimental [Page 152]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ object can accept the request even though the Printer has some error
+ condition, the 'successful-ok' status code will be returned. In such
+ a case, the client would look at the returned Job Object Attributes
+ or later query the Printer to determine its state and state reasons.
+
+13.1.5.6 server-error-temporary-error (0x0505)
+
+ A temporary error such as a buffer full write error, a memory
+ overflow (i.e. the document data exceeds the memory of the Printer),
+ or a disk full condition, occurs while the IPP Printer processes an
+ operation. The client MAY try the unmodified request again at some
+ later point in time with an expectation that the temporary internal
+ error condition may have been cleared. Alternatively, as an
+ implementation option, a Printer object MAY delay the response until
+ the temporary condition is cleared so that no error is returned.
+
+13.1.5.7 server-error-not-accepting-jobs (0x0506)
+
+ A temporary error indicating that the Printer is not currently
+ accepting jobs, because the administrator has set the value of the
+ Printer's "printer-is-not-accepting-jobs" attribute to 'false' (by
+ means outside of IPP/1.0).
+
+13.1.5.8 server-error-busy (0x0507)
+
+ A temporary error indicating that the Printer is too busy processing
+ jobs and/or other requests. The client SHOULD try the unmodified
+ request again at some later point in time with an expectation that
+ the temporary busy condition will have been cleared.
+
+13.1.5.9 server-error-job-canceled (0x0508)
+
+ An error indicating that the job has been canceled by an operator or
+ the system while the client was transmitting the data to the IPP
+ Printer. If a job-id and job-uri had been created, then they are
+ returned in the Print-Job, Send-Document, or Send-URI response as
+ usual; otherwise, no job-id and job-uri are returned in the response.
+
+13.2 Status Codes for IPP Operations
+
+ PJ = Print-Job, PU = Print-URI, CJ = Create-Job, SD = Send-Document
+ SU = Send-URI, V = Validate-Job, GA = Get-Job-Attributes and
+ Get-Printer-Attributes, GJ = Get-Jobs, C = Cancel-Job
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 153]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ IPP Operations
+ IPP Status Keyword PJ PU CJ SD SU V GA GJ C
+ ------------------ -- -- -- -- -- - -- -- -
+ successful-ok x x x x x x x x x
+ successful-ok-ignored-or-substituted- x x x x x x x x x
+ attributes
+ successful-ok-conflicting-attributes x x x x x x x x x
+ client-error-bad-request x x x x x x x x x
+ client-error-forbidden x x x x x x x x x
+ client-error-not-authenticated x x x x x x x x x
+ client-error-not-authorized x x x x x x x x x
+ client-error-not-possible x x x x x x x x x
+ client-error-timeout x x
+ client-error-not-found x x x x x x x x x
+ client-error-gone x x x x x x x x x
+ client-error-request-entity-too-large x x x x x x x x x
+ client-error-request-value-too-long x x x x x x x x x
+ client-error-document-format-not- x x x x x x
+ supported
+ client-error-attributes-or-values-not- x x x x x x x x x
+ supported
+ client-error-uri-scheme-not-supported x x
+ client-error-charset-not-supported x x x x x x x x x
+ client-error-conflicting-attributes x x x x x x x x x
+ server-error-internal-error x x x x x x x x x
+ server-error-operation-not-supported x x x x
+ server-error-service-unavailable x x x x x x x x x
+ server-error-version-not-supported x x x x x x x x x
+ server-error-device-error x x x x x
+ server-error-temporary-error x x x x x
+ server-error-not-accepting-jobs x x x x
+ server-error-busy x x x x x x x x x
+ server-error-job-canceled x x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 154]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+14. APPENDIX C: "media" keyword values
+
+ Standard keyword values are taken from several sources.
+
+ Standard values are defined (taken from DPA[ISO10175] and the Printer
+ MIB[RFC1759]):
+
+ 'default': The default medium for the output device
+ 'iso-a4-white': Specifies the ISO A4 white medium
+ 'iso-a4-colored': Specifies the ISO A4 colored medium
+ 'iso-a4-transparent' Specifies the ISO A4 transparent medium
+ 'iso-a3-white': Specifies the ISO A3 white medium
+ 'iso-a3-colored': Specifies the ISO A3 colored medium
+ 'iso-a5-white': Specifies the ISO A5 white medium
+ 'iso-a5-colored': Specifies the ISO A5 colored medium
+ 'iso-b4-white': Specifies the ISO B4 white medium
+ 'iso-b4-colored': Specifies the ISO B4 colored medium
+ 'iso-b5-white': Specifies the ISO B5 white medium
+ 'iso-b5-colored': Specifies the ISO B5 colored medium
+ 'jis-b4-white': Specifies the JIS B4 white medium
+ 'jis-b4-colored': Specifies the JIS B4 colored medium
+ 'jis-b5-white': Specifies the JIS B5 white medium
+ 'jis-b5-colored': Specifies the JIS B5 colored medium
+
+ The following standard values are defined for North American media:
+
+ 'na-letter-white': Specifies the North American letter white medium
+ 'na-letter-colored': Specifies the North American letter colored
+ medium
+ 'na-letter-transparent': Specifies the North American letter
+ transparent medium
+ 'na-legal-white': Specifies the North American legal white medium
+ 'na-legal-colored': Specifies the North American legal colored
+ medium
+
+ The following standard values are defined for envelopes:
+
+ 'iso-b4-envelope': Specifies the ISO B4 envelope medium
+ 'iso-b5-envelope': Specifies the ISO B5 envelope medium
+ 'iso-c3-envelope': Specifies the ISO C3 envelope medium
+ 'iso-c4-envelope': Specifies the ISO C4 envelope medium
+ 'iso-c5-envelope': Specifies the ISO C5 envelope medium
+ 'iso-c6-envelope': Specifies the ISO C6 envelope medium
+ 'iso-designated-long-envelope': Specifies the ISO Designated Long
+ envelope medium
+ 'na-10x13-envelope': Specifies the North American 10x13 envelope
+ medium
+
+
+
+
+deBry, et al. Experimental [Page 155]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 'na-9x12-envelope': Specifies the North American 9x12 envelope
+ medium
+ 'monarch-envelope': Specifies the Monarch envelope
+ 'na-number-10-envelope': Specifies the North American number 10
+ business envelope medium
+ 'na-7x9-envelope': Specifies the North American 7x9 inch envelope
+ 'na-9x11-envelope': Specifies the North American 9x11 inch envelope
+ 'na-10x14-envelope': Specifies the North American 10x14 inch
+ envelope
+ 'na-number-9-envelope': Specifies the North American number 9
+ business envelope
+ 'na-6x9-envelope': Specifies the North American 6x9 inch envelope
+ 'na-10x15-envelope': Specifies the North American 10x15 inch
+ envelope
+
+ The following standard values are defined for the less commonly used
+ media (white-only):
+
+ 'executive-white': Specifies the white executive medium
+ 'folio-white': Specifies the folio white medium
+ 'invoice-white': Specifies the white invoice medium
+ 'ledger-white': Specifies the white ledger medium
+ 'quarto-white': Specified the white quarto medium
+ 'iso-a0-white': Specifies the ISO A0 white medium
+ 'iso-a1-white': Specifies the ISO A1 white medium
+ 'iso-a2-white': Specifies the ISO A2 white medium
+ 'iso-a6-white': Specifies the ISO A6 white medium
+ 'iso-a7-white': Specifies the ISO A7 white medium
+ 'iso-a8-white': Specifies the ISO A8 white medium
+ 'iso-a9-white': Specifies the ISO A9 white medium
+ 'iso-10-white': Specifies the ISO A10 white medium
+ 'iso-b0-white': Specifies the ISO B0 white medium
+ 'iso-b1-white': Specifies the ISO B1 white medium
+ 'iso-b2-white': Specifies the ISO B2 white medium
+ 'iso-b3-white': Specifies the ISO B3 white medium
+ 'iso-b6-white': Specifies the ISO B6 white medium
+ 'iso-b7-white': Specifies the ISO B7 white medium
+ 'iso-b8-white': Specifies the ISO B8 white medium
+ 'iso-b9-white': Specifies the ISO B9 white medium
+ 'iso-b10-white': Specifies the ISO B10 white medium
+ 'jis-b0-white': Specifies the JIS B0 white medium
+ 'jis-b1-white': Specifies the JIS B1 white medium
+ 'jis-b2-white': Specifies the JIS B2 white medium
+ 'jis-b3-white': Specifies the JIS B3 white medium
+ 'jis-b6-white': Specifies the JIS B6 white medium
+ 'jis-b7-white': Specifies the JIS B7 white medium
+
+
+
+
+
+deBry, et al. Experimental [Page 156]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 'jis-b8-white': Specifies the JIS B8 white medium
+ 'jis-b9-white': Specifies the JIS B9 white medium
+ 'jis-b10-white': Specifies the JIS B10 white medium
+
+
+ The following standard values are defined for engineering media:
+
+ 'a': Specifies the engineering A size medium
+ 'b': Specifies the engineering B size medium
+ 'c': Specifies the engineering C size medium
+ 'd': Specifies the engineering D size medium
+ 'e': Specifies the engineering E size medium
+
+
+ The following standard values are defined for input-trays (from ISO
+ DPA and the Printer MIB):
+
+ 'top': The top input tray in the printer.
+ 'middle': The middle input tray in the printer.
+ 'bottom': The bottom input tray in the printer.
+ 'envelope': The envelope input tray in the printer.
+ 'manual': The manual feed input tray in the printer.
+ 'large-capacity': The large capacity input tray in the printer.
+ 'main': The main input tray
+ 'side': The side input tray
+
+
+ The following standard values are defined for media sizes (from ISO
+ DPA):
+
+ 'iso-a0': Specifies the ISO A0 size: 841 mm by 1189 mm as defined
+ in ISO 216
+ 'iso-a1': Specifies the ISO A1 size: 594 mm by 841 mm as defined in
+ ISO 216
+ 'iso-a2': Specifies the ISO A2 size: 420 mm by 594 mm as defined in
+ ISO 216
+ 'iso-a3': Specifies the ISO A3 size: 297 mm by 420 mm as defined in
+ ISO 216
+ 'iso-a4': Specifies the ISO A4 size: 210 mm by 297 mm as defined in
+ ISO 216
+ 'iso-a5': Specifies the ISO A5 size: 148 mm by 210 mm as defined in
+ ISO 216
+ 'iso-a6': Specifies the ISO A6 size: 105 mm by 148 mm as defined in
+ ISO 216
+ 'iso-a7': Specifies the ISO A7 size: 74 mm by 105 mm as defined in
+ ISO 216
+ 'iso-a8': Specifies the ISO A8 size: 52 mm by 74 mm as defined in
+ ISO 216
+
+
+
+deBry, et al. Experimental [Page 157]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 'iso-a9': Specifies the ISO A9 size: 37 mm by 52 mm as defined in
+ ISO 216
+ 'iso-a10': Specifies the ISO A10 size: 26 mm by 37 mm as defined in
+ ISO 216
+ 'iso-b0': Specifies the ISO B0 size: 1000 mm by 1414 mm as defined
+ in ISO 216
+ 'iso-b1': Specifies the ISO B1 size: 707 mm by 1000 mm as defined
+ in ISO 216
+ 'iso-b2': Specifies the ISO B2 size: 500 mm by 707 mm as defined in
+ ISO 216
+ 'iso-b3': Specifies the ISO B3 size: 353 mm by 500 mm as defined in
+ ISO 216
+ 'iso-b4': Specifies the ISO B4 size: 250 mm by 353 mm as defined in
+ ISO 216
+ 'iso-b5': Specifies the ISO B5 size: 176 mm by 250 mm as defined in
+ ISO 216
+ 'iso-b6': Specifies the ISO B6 size: 125 mm by 176 mm as defined in
+ ISO 216
+ 'iso-b7': Specifies the ISO B7 size: 88 mm by 125 mm as defined in
+ ISO 216
+ 'iso-b8': Specifies the ISO B8 size: 62 mm by 88 mm as defined in
+ ISO 216
+ 'iso-b9': Specifies the ISO B9 size: 44 mm by 62 mm as defined in
+ ISO 216
+ 'iso-b10': Specifies the ISO B10 size: 31 mm by 44 mm as defined in
+ ISO 216
+ 'na-letter': Specifies the North American letter size: 8.5 inches by
+ 11 inches
+ 'na-legal': Specifies the North American legal size: 8.5 inches by
+ 14 inches
+ 'executive': Specifies the executive size (7.25 X 10.5 in)
+ 'folio': Specifies the folio size (8.5 X 13 in)
+ 'invoice': Specifies the invoice size (5.5 X 8.5 in)
+ 'ledger': Specifies the ledger size (11 X 17 in)
+ 'quarto': Specifies the quarto size (8.5 X 10.83 in)
+ 'iso-c3': Specifies the ISO C3 size: 324 mm by 458 mm as defined in
+ ISO 269
+ 'iso-c4': Specifies the ISO C4 size: 229 mm by 324 mm as defined in
+ ISO 269
+ 'iso-c5': Specifies the ISO C5 size: 162 mm by 229 mm as defined in
+ ISO 269
+ 'iso-c6': Specifies the ISO C6 size: 114 mm by 162 mm as defined in
+ ISO 269
+ 'iso-designated-long': Specifies the ISO Designated Long size: 110
+ mm by 220 mm as defined in ISO 269
+ 'na-10x13-envelope': Specifies the North American 10x13 size: 10
+ inches by 13 inches
+
+
+
+
+deBry, et al. Experimental [Page 158]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 'na-9x12-envelope': Specifies the North American 9x12 size: 9
+ inches by 12 inches
+ 'na-number-10-envelope': Specifies the North American number 10
+ business envelope size: 4.125 inches by 9.5 inches
+ 'na-7x9-envelope': Specifies the North American 7x9 inch envelope
+ size
+ 'na-9x11-envelope': Specifies the North American 9x11 inch envelope
+ size
+ 'na-10x14-envelope': Specifies the North American 10x14 inch
+ envelope size
+ 'na-number-9-envelope': Specifies the North American number 9
+ business envelope size
+ 'na-6x9-envelope': Specifies the North American 6x9 envelope size
+ 'na-10x15-envelope': Specifies the North American 10x15 envelope
+ size
+ 'monarch-envelope': Specifies the Monarch envelope size (3.87 x 7.5
+ in)
+ 'jis-b0': Specifies the JIS B0 size: 1030mm x 1456mm
+ 'jis-b1': Specifies the JIS B1 size: 728mm x 1030mm
+ 'jis-b2': Specifies the JIS B2 size: 515mm x 728mm
+ 'jis-b3': Specifies the JIS B3 size: 364mm x 515mm
+ 'jis-b4': Specifies the JIS B4 size: 257mm x 364mm
+ 'jis-b5': Specifies the JIS B5 size: 182mm x 257mm
+ 'jis-b6': Specifies the JIS B6 size: 128mm x 182mm
+ 'jis-b7': Specifies the JIS B7 size: 91mm x 128mm
+ 'jis-b8': Specifies the JIS B8 size: 64mm x 91mm
+ 'jis-b9': Specifies the JIS B9 size: 45mm x 64mm
+ 'jis-b10': Specifies the JIS B10 size: 32mm x 45mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 159]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+15. APPENDIX D: Processing IPP Attributes
+
+ When submitting a print job to a Printer object, the IPP model allows
+ a client to supply operation and Job Template attributes along with
+ the document data. These Job Template attributes in the create
+ request affect the rendering, production and finishing of the
+ documents in the job. Similar types of instructions may also be
+ contained in the document to be printed, that is, embedded within the
+ print data itself. In addition, the Printer has a set of attributes
+ that describe what rendering and finishing options which are
+ supported by that Printer. This model, which allows for flexibility
+ and power, also introduces the potential that at job submission time,
+ these client-supplied attributes may conflict with either:
+
+ - what the implementation is capable of realizing (i.e., what the
+ Printer supports), as well as
+ - the instructions embedded within the print data itself.
+
+ The following sections describe how these two types of conflicts are
+ handled in the IPP model.
+
+15.1 Fidelity
+
+ If there is a conflict between what the client requests and what a
+ Printer object supports, the client may request one of two possible
+ conflict handling mechanisms:
+
+ 1) either reject the job since the job can not be processed exactly
+ as specified, or
+ 2) allow the Printer to make any changes necessary to proceed with
+ processing the Job the best it can.
+
+ In the first case the client is indicating to the Printer object:
+ "Print the job exactly as specified with no exceptions, and if that
+ can't be done, don't even bother printing the job at all." In the
+ second case, the client is indicating to the Printer object: "It is
+ more important to make sure the job is printed rather than be
+ processed exactly as specified; just make sure the job is printed
+ even if client supplied attributes need to be changed or ignored."
+
+ The IPP model accounts for this situation by introducing an "ipp-
+ attribute-fidelity" attribute.
+
+ In a create request, "ipp-attribute-fidelity" is a boolean operation
+ attribute that is OPTIONALLY supplied by the client. The value '
+ true' indicates that total fidelity to client supplied Job Template
+ attributes and values is required. The client is requesting that the
+ Job be printed exactly as specified, and if that is not possible then
+
+
+
+deBry, et al. Experimental [Page 160]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ the job MUST be rejected rather than processed incorrectly. The
+ value 'false' indicates that a reasonable attempt to print the Job is
+ acceptable. If a Printer does not support some of the client
+ supplied Job Template attributes or values, the Printer MUST ignore
+ them or substitute any supported value for unsupported values,
+ respectively. The Printer may choose to substitute the default value
+ associated with that attribute, or use some other supported value
+ that is similar to the unsupported requested value. For example, if
+ a client supplies a "media" value of 'na-letter', the Printer may
+ choose to substitute 'iso-a4' rather than a default value of '
+ envelope'. If the client does not supply the "ipp-attribute-fidelity"
+ attribute, the Printer assumes a value of 'false'.
+
+ Each Printer implementation MUST support both types of "fidelity"
+ printing (that is whether the client supplies a value of 'true' or '
+ false'):
+
+ - If the client supplies 'false' or does not supply the attribute,
+ the Printer object MUST always accept the request by ignoring
+ unsupported Job Template attributes and by substituting
+ unsupported values of supported Job Template attributes with
+ supported values.
+ - If the client supplies 'true', the Printer object MUST reject the
+ request if the client supplies unsupported Job Template
+ attributes.
+
+ Since a client can always query a Printer to find out exactly what is
+ and is not supported, "ipp-attribute-fidelity" set to 'false' is
+ useful when:
+
+ 1) The End-User uses a command line interface to request attributes
+ that might not be supported.
+ 2) In a GUI context, if the End User expects the job might be moved
+ to another printer and prefers a sub-optimal result to nothing
+ at all.
+ 3) The End User just wants something reasonable in lieu of nothing
+ at all.
+
+15.2 Page Description Language (PDL) Override
+
+ If there is a conflict between the value of an IPP Job Template
+ attribute and a corresponding instruction in the document data, the
+ value of the IPP attribute SHOULD take precedence over the document
+ instruction. Consider the case where a previously formatted file of
+ document data is sent to an IPP Printer. In this case, if the client
+ supplies any attributes at job submission time, the client desires
+ that those attributes override the embedded instructions. Consider
+ the case were a previously formatted document has embedded in it
+
+
+
+deBry, et al. Experimental [Page 161]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ commands to load 'iso-a4' media. However, the document is passed to
+ an end user that only has access to a printer with 'na-letter' media
+ loaded. That end user most likely wants to submit that document to
+ an IPP Printer with the "media" Job Template attribute set to 'na-
+ letter'. The job submission attribute should take precedence over
+ the embedded PDL instruction. However, until companies that supply
+ document data interpreters allow a way for external IPP attributes to
+ take precedence over embedded job production instructions, a Printer
+ might not be able to support the semantics that IPP attributes
+ override the embedded instructions.
+
+ The IPP model accounts for this situation by introducing a "pdl-
+ override-supported" attribute that describes the Printer objects
+ capabilities to override instructions embedded in the PDL data
+ stream. The value of the "pdl-override-supported" attribute is
+ configured by means outside IPP/1.0.
+
+ This REQUIRED Printer attribute takes on the following values:
+
+ - 'attempted': This value indicates that the Printer object
+ attempts to make the IPP attribute values take precedence over
+ embedded instructions in the document data, however there is no
+ guarantee.
+ - 'not-attempted': This value indicates that the Printer object
+ makes no attempt to make the IPP attribute values take precedence
+ over embedded instructions in the document data.
+
+ At job processing time, an implementation that supports the value of
+ 'attempted' might do one of several different actions:
+
+ 1) Generate an output device specific command sequence to realize
+ the feature represented by the IPP attribute value.
+ 2) Parse the document data itself and replace the conflicting
+ embedded instruction with a new embedded instruction that
+ matches the intent of the IPP attribute value.
+ 3) Indicate to the Printer that external supplied attributes take
+ precedence over embedded instructions and then pass the external
+ IPP attribute values to the document data interpreter.
+ 4) Anything else that allows for the semantics that IPP attributes
+ override embedded document data instructions.
+
+ Since 'attempted' does not offer any type of guarantee, even though a
+ given Printer object might not do a very "good" job of attempting to
+ ensure that IPP attributes take a higher precedence over instructions
+ embedded in the document data, it would still be a conforming
+ implementation.
+
+
+
+
+
+deBry, et al. Experimental [Page 162]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ At job processing time, an implementation that supports the value of
+ 'not-attempted' might do one of the following actions:
+
+ 1) Simply pre-pend the document data with the PDL instruction that
+ corresponds to the client-supplied PDL attribute, such that if
+ the document data also has the same PDL instruction, it will
+ override what the Printer object pre-pended. In other words,
+ this implementation is using the same implementation semantics
+ for the client-supplied IPP attributes as for the Printer object
+ defaults.
+ 2) Parse the document data and replace the conflicting embedded
+ instruction with a new embedded instruction that approximates,
+ but does not match, the semantic intent of the IPP attribute
+ value.
+
+ Note: The "ipp-attribute-fidelity" attribute applies to the
+ Printer's ability to either accept or reject other unsupported Job
+ Template attributes. In other words, if "ipp-attribute-fidelity" is
+ set to 'true', a Job is accepted if and only if the client supplied
+ Job Template attributes and values are supported by the Printer.
+ Whether these attributes actually affect the processing of the Job
+ when the document data contains embedded instructions depends on the
+ ability of the Printer to override the instructions embedded in the
+ document data with the semantics of the IPP attributes. If the
+ document data attributes can be overridden ("pdl-override-supported"
+ set to 'attempted'), the Printer makes an attempt to use the IPP
+ attributes when processing the Job. If the document data attributes
+ can not be overridden ("pdl-override-supported" set to 'not-
+ attempted'), the Printer makes no attempt to override the embedded
+ document data instructions with the IPP attributes when processing
+ the Job, and hence, the IPP attributes may fail to affect the Job
+ processing and output when the corresponding instruction is embedded
+ in the document data.
+
+15.3 Using Job Template Attributes During Document Processing.
+
+ The Printer object uses some of the Job object's Job Template
+ attributes during the processing of the document data associated with
+ that job. These include, but are not limited to, "orientation",
+ "number-up", "sides", "media", and "copies". The processing of each
+ document in a Job Object MUST follow the steps below. These steps are
+ intended only to identify when and how attributes are to be used in
+ processing document data and any alternative steps that accomplishes
+ the same effect can be used to implement this specification.
+
+ 1. Using the client supplied "document-format" attribute or some
+ form of document format detection algorithm (if the value of
+ "document- format" is not specific enough), determine whether or
+
+
+
+deBry, et al. Experimental [Page 163]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ not the document data has already been formatted for printing.
+ If the document data has been formatted, then go to step 2.
+ Otherwise, the document data MUST be formatted. The formatting
+ detection algorithm is implementation defined and is not
+ specified by this specification. The formatting of the document
+ data uses the "orientation-requested" attribute to determine how
+ the formatted print data should be placed on a print-stream
+ page, see section 4.2.10 for the details.
+
+ 2. The document data is in the form of a print-stream in a known
+ media type. The "page-ranges" attribute is used to select, as
+ specified in section 4.2.7, a sub-sequence of the pages in the
+ print-stream that are to be processed and images.
+
+ 3. The input to this step is a sequence of print-stream pages. This
+ step is controlled by the "number-up" attribute. If the value of
+ "number-up" is N, then during the processing of the print-stream
+ pages, each N print-stream pages are positioned, as specified in
+ section 4.2.9, to create a single impression. If a given
+ document does not have N more print-stream pages, then the
+ completion of the impression is controlled by the "multiple-
+ document-handling" attribute as described in section 4.2.4; when
+ the value of this attribute is 'single-document' or 'single-
+ document-new-sheet', the print-stream pages of document data
+ from subsequent documents is used to complete the impression.
+
+ The size(scaling), position(translation) and rotation of the
+ print-stream pages on the impression is implementation defined.
+ Note that during this process the print-stream pages may be
+ rendered to a form suitable for placing on the impression; this
+ rendering is controlled by the values of the "printer-
+ resolution" and "print- quality" attributes as described in
+ sections 4.2.12 and 4.2.13. In the case N=1, the impression is
+ nearly the same as the print-stream page; the differences would
+ only be in the size, position and rotation of the print-stream
+ page and/or any decoration, such as a frame to the page, that is
+ added by the implementation.
+
+ 4. The collection of impressions is placed, in sequence, onto sides
+ of the media sheets. This placement is controlled by the "sides"
+ attribute and the orientation of the print-stream page, as
+ described in section 4.2.8. The orientation of the print-stream
+ pages affects the orientation of the impression; for example, if
+ "number-up" equals 2, then, typically, two portrait print-stream
+ pages become one landscape impression. Note that the placement
+ of impressions onto media sheets is also controlled by the
+ "multiple-document-handling" attribute as described in section
+ 4.2.4.
+
+
+
+deBry, et al. Experimental [Page 164]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 5. The "copies" and "multiple-document-handling" attributes are
+ used to determine how many copies of each media instance are
+ created and in what order. See sections 4.2.5 and 4.2.4 for the
+ details.
+
+ 6. When the correct number of copies are created, the media
+ instances are finished according to the values of the
+ "finishings" attribute as described in 4.2.6. Note that
+ sometimes finishing operations may require manual intervention
+ to perform the finishing operations on the copies, especially
+ uncollated copies. This specification allows any or all of the
+ processing steps to be performed automatically or manually at
+ the discretion of the Printer object.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 165]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+16. APPENDIX E: Generic Directory Schema
+
+ This section defines a generic schema for an entry in a directory
+ service. A directory service is a means by which service users can
+ locate service providers. In IPP environments, this means that IPP
+ Printers can be registered (either automatically or with the help of
+ an administrator) as entries of type printer in the directory using
+ an implementation specific mechanism such as entry attributes, entry
+ type fields, specific branches, etc. IPP clients can search or
+ browse for entries of type printer. Clients use the directory
+ service to find entries based on naming, organizational contexts, or
+ filtered searches on attribute values of entries. For example, a
+ client can find all printers in the "Local Department" context.
+ Authentication and authorization are also often part of a directory
+ service so that an administrator can place limits on end users so
+ that they are only allowed to find entries to which they have certain
+ access rights. IPP itself does not require any specific directory
+ service protocol or provider.
+
+ Note: Some directory implementations allow for the notion of
+ "aliasing". That is, one directory entry object can appear as
+ multiple directory entry object with different names for each object.
+ In each case, each alias refers to the same directory entry object
+ which refers to a single IPP Printer object.
+
+ The generic schema is a subset of IPP Printer Job Template and
+ Printer Description attributes (sections 4.2 and 4.4). These
+ attributes are identified as either RECOMMENDED or OPTIONAL for the
+ directory entry itself. This conformance labeling is NOT the same
+ conformance labeling applied to the attributes of IPP Printers
+ objects. The conformance labeling in this Appendix is intended to
+ apply to directory templates and to IPP Printer implementations that
+ subscribe by adding one or more entries to a directory. RECOMMENDED
+ attributes SHOULD be associated with each directory entry. OPTIONAL
+ attributes MAY be associated with the directory entry (if known or
+ supported). In addition, all directory entry attributes SHOULD
+ reflect the current attribute values for the corresponding Printer
+ object.
+
+ The names of attributes in directory schema and entries SHOULD be the
+ same as the IPP Printer attribute names as shown.
+
+ In order to bridge between the directory service and the IPP Printer
+ object, one of the RECOMMENDED directory entry attributes is the
+ Printer object's "printer-uri-supported" attribute. The IPP client
+ queries the "printer-uri-supported" attribute in the directory entry
+
+
+
+
+
+deBry, et al. Experimental [Page 166]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ and then addresses the IPP Printer object using one of its URIs. The
+ "uri-security-supported" attribute identifies the protocol (if any)
+ used to secure a channel.
+
+ The following attributes define the generic schema for directory
+ entries of type PRINTER:
+
+ printer-uri-supported RECOMMENDED Section 4.4.1
+ uri-security-supported RECOMMENDED Section 4.4.2
+ printer-name RECOMMENDED Section 4.4.3
+ printer-location RECOMMENDED Section 4.4.4
+ printer-info OPTIONAL Section 4.4.5
+ printer-more-info OPTIONAL Section 4.4.6
+ printer-make-and-model RECOMMENDED Section 4.4.8
+ charset-supported OPTIONAL Section 4.4.15
+ generated-natural-language-
+ supported OPTIONAL Section 4.4.17
+ document-format-supported RECOMMENDED Section 4.4.19
+ color-supported RECOMMENDED Section 4.4.23
+ finishings-supported OPTIONAL Section 4.2.6
+ number-up-supported OPTIONAL Section 4.2.7
+ sides-supported RECOMMENDED Section 4.2.8
+ media-supported RECOMMENDED Section 4.2.11
+ printer-resolution-supported OPTIONAL Section 4.2.12
+ print-quality-supported OPTIONAL Section 4.2.13
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 167]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+17. APPENDIX F: Change History for the IPP Model and Semantics document
+
+ The following substantive changes and major clarifications have been
+ made to this document from the June 30, 1998 version based on the
+ interoperability testing that took place September 23-25 1998 and
+ subsequent mailing list and meeting discussions. They are listed in
+ the order of occurrence in the document. These changes are the ones
+ that might affect implementations. Clarifications that are unlikely
+ to affect implementations are not listed. The issue numbers refer to
+ the IPP Issues List which is available in the following directory:
+
+ ftp://ftp.pwg.org/pub/pwg/ipp/approved-clarifications/
+
+ Section Description
+
+ global Replaced TLS references with SSL3 references as agreed with
+ our Area Director on 11/12/1998.
+
+ global Removed the indications that some of these IPP documents
+ are informational, since the intent is now to publish all
+ IPP/1.0 documents as informational as agreed with our Area
+ Director on 11/12/1998.
+
+ 3.1.2, Clarify that the IPP object SHOULD NOT validate the
+ 16.3.3 range of the request-id being 1 to 2**31-1, but accepts
+ [now ipp- and returns any value. Clients MUST still keep in the
+ iig] range 1 to 2**31 though. If the request is terminated
+ before the complete "request-id" is received, the IPP
+ object rejects the request and returns a response with a
+ "request-id" of 0 (Issue 1.36).
+
+ 3.1.4.1, Clarified that when a client submits a request in a
+ 13.1.4.14 charset that is not supported, the IPP object SHOULD
+ return any 'text' or 'name' attributes in the 'utf-8'
+ charset, if it returns any, since clients and IPP
+ objects MUST support 'utf-8'. (Issue 1.19)
+
+ 3.1.4.1 Clarified Section 3.1.4.1 Request Operation Attributes
+ that a client MAY use the attribute level natural
+ language override (text/nameWithLanguage) redundantly in
+ a request. (Issue 1.46)
+
+ 3.1.4.2 Clarified Section 3.1.4.2 Response Operation Attributes
+ that an IPP object MAY use the attribute level natural
+ language override (text/nameWithLanguage) redundantly in
+ a response. (Issue 1.46)
+
+
+
+
+
+deBry, et al. Experimental [Page 168]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 3.1.6 Clarified section 3.1.6: If the Printer object supports
+ the "status-message" operation attribute, it NEED NOT
+ return a status message for the following error status
+ codes: 'client-error-bad-request', 'client-error-
+ charset-not-supported', 'server-error-internal-error',
+ 'server-error-operation-not-supported', and 'server-
+ error-version-not-supported'.
+
+ 3.2.1.1 Clarified that if a client is not supplying any Job
+ Template attributes in a request, the client SHOULD omit
+ Group 2 rather than sending an empty group. However, a
+ Printer object MUST be able to accept an empty group.
+ This makes [RFC2566] agree with [RFC2565]. (Issue 1.16)
+
+ 3.2.1.2, Clarified that if an IPP object is not returning any
+ 3.2.5.2, Unsupported Attributes in a response, the IPP object
+ 3.2.6.2, SHOULD omit Group 2 rather than sending an empty group.
+ 3.3.1.2, However, a client MUST be able to accept an empty group.
+ 3.3.3.2, This makes [RFC2566] agree with [RFC2565]. (Issue 1.17)
+ 3.3.4.2
+
+ 3.2.1.2, Clarified that an IPP object MUST treat an unsupported
+ 13.1.2.2, attribute syntax supplied in a request in the same way
+ 13.1.4.12 as an unsupported value. The IPP object MUST return the
+ attribute, the attribute syntax, and the value in the
+ Unsupported Attributes group. (Issue 1.26)
+
+ 3.2.5.2, Clarified for Get-Printer-Attributes, Get-Jobs, and Get-
+ 3.2.6.2, Job-Attributes that an IPP object MUST return
+ 3.3.4.2, 'successful-ok-ignored-or-substituted-attributes' (0x1),
+
+ 13.1.2.1, rather than 'successful-ok' (0x0), when a client
+ 13.1.2.2, supplies unsupported attributes as values of the
+ 13.1.4.12 'requested-attributes' operation attribute. (Issue
+ 1.24)
+ Also clarified that the response NEED NOT contain the
+ "requested-attributes" operation attribute with any
+ supplied values (attribute keywords) that were requested
+ by the client but are not supported by the IPP object.
+ (Issue 1.18)
+
+ 3.2.6.2 Deleted the job-level natural language override (NLO)
+ 4.1.1.2 from Section 3.2.6.2 Get-Jobs Response so that all
+ 4.3.24 operation responses are the same with respect to NLO.
+ (Issue 1.47)
+
+
+
+
+
+
+deBry, et al. Experimental [Page 169]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 3.3.1 Clarified that an IPP Printer that supports the Create-
+ Job operation MUST handle the situation when a client
+ does not supply Send-Document or Send-URI operations
+ within a one- to four-minute time period. Also
+ clarified that a client MUST send documents in a multi-
+ document job without undue or unbounded delay. (Issue
+ 1.28)
+
+ 3.3.3 Clarified that the IPP object MUST reject a Cancel-Job
+ request if the job is in 'completed', 'canceled', or
+ 'aborted' job states. (Issue 1.12)
+
+ 4.1.2.3 Added this new sub-section: it specifies that
+ nameWithoutLanguage plus the implicit natural language
+ matches nameWithLanguage, if the values and natural
+ languages are the same. Also added that keyword never
+ matches nameWithLanguage or nameWithoutLanguage.
+ Clarified that if both have countries, that the
+ countries SHOULD match as well. If either do not, then
+ the country field SHOULD be ignored. (Issues 1.33 and
+ 1.34)
+
+ 4.1.5 Clarified regarding the case-insensitivity of URLs to
+ refer only to the RFCs that define them. (Issue 1.10)
+
+ 4.1.11 Clarified that 'boolean' is not a full-sized integer.
+ (Issue 1.38)
+
+ 4.1.15 Clarified that 'resolution' is not three full-sized
+ integers. (Issue 1.20)
+
+ 4.2.* Clarified that standard values are keywords or enums,
+ not names. (Issue 1.49).
+
+ 4.2.4 Added the 'single-document-new-sheet' value to Section
+ 4.2.4 multiple-document-handling. (Issue 1.54)
+
+ 4.4.18, Clarified that the "document-format-default" and
+ 4.4.19 "document-format-supported" Printer Description
+ attributes are REQUIRED to agree with the table. (Issue
+ 1.4)
+
+ 4.4.21 Changed "queued-job-count" from OPTIONAL to RECOMMENDED.
+ (Issue 1.14)
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 170]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 4.4.28 Clarified that the implementation supplied value for the
+ "multiple-operation-time-out" attribute SHOULD be
+ between 30 and 240 seconds, though the implementation
+ MAY allow the administrator to set values, and MAY allow
+ values outside this range. (Issue 1.28)
+
+ 5.1, Clarified Client Conformance that if a client supports
+ 5.2.5 an attribute of 'text' attribute syntax, that it MUST
+ support both the textWithoutLanguage and the
+ textWithLanguage forms. Same for 'name' attribute
+ syntax. Same for an IPP object (Issue 1.48)
+
+ 6.5, Added new section to allow Attribute Groups to be
+ 12.8 registered as extensions for being passed in operation
+ requests and responses. (Issue 1.25)
+
+ 7. Updated the table of text and name attributes to agree
+ with Section 4.2.
+
+ 8.5 Added a new section RECOMMENDING that the Get-Jobs
+ SHOULD return non-IPP jobs whether or not assigning them
+ a job-id and job-uri. Also RECOMMENDED generating, if
+ possible, job-id and job-uri and supporting other IPP
+ operations on foreign jobs as an implementer option.
+ (Issue 1.32)
+
+ 9. Updated document references.
+
+ 13.1.4.14 Clarified 'client-error-charset-not-supported' that
+ 'utf-8' must be used for any 'text' or 'name' attributes
+ returned in the error response (Issue 1.19).
+
+ 13.1.5.9 Added a new error code 'server-error-job-canceled'
+ (0x0508) to be returned if a job is canceled by another
+ client or aborted by the IPP object while the first
+ client is still sending the document data. (Issue 1.29)
+
+ 15.3, Moved these sections recommending operation processing
+ 15.4 steps to the new Implementer's Guide (informational).
+ There indicated that all of the error checks are not
+ required, so an IPP object MAY be forgiving and accept
+ non-conforming requests. However, a conforming client
+ MUST supply requests that would pass all of the error
+ checks indicated. (Issue 1.21)
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 171]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+ 16 Changed directory schema attributes from REQUIRED to
+ RECOMMENDED. Changed some of the OPTIONAL to
+ RECOMMENDED to agree with the SLP template. Changed the
+ "charset-supported" and "natural-language-supported"
+ from REQUIRED to OPTIONAL. Recommended that the names
+ be the same in a directory entry as the IPP attribute
+ names. (Issue 1.53)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 172]
+
+RFC 2566 IPP/1.0: Model and Semantics April 1999
+
+
+18. Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+deBry, et al. Experimental [Page 173]
+
diff --git a/standards/rfc2567.txt b/standards/rfc2567.txt
new file mode 100644
index 000000000..d5ef440be
--- /dev/null
+++ b/standards/rfc2567.txt
@@ -0,0 +1,2411 @@
+
+
+
+
+
+
+Network Working Group F.D. Wright
+Request for Comments: 2567 Lexmark International
+Category: Experimental April 1999
+
+
+ Design Goals for an Internet Printing Protocol
+
+Status of this Memo
+
+ This memo defines an Experimental Protocol for the Internet
+ community. It does not specify an Internet standard of any kind.
+ Discussion and suggestions for improvement are requested.
+ Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+IESG Note
+
+ This document defines an Experimental protocol for the Internet
+ community. The IESG expects that a revised version of this protocol
+ will be published as Proposed Standard protocol. The Proposed
+ Standard, when published, is expected to change from the protocol
+ defined in this memo. In particular, it is expected that the
+ standards-track version of the protocol will incorporate strong
+ authentication and privacy features, and that an "ipp:" URL type will
+ be defined which supports those security measures. Other changes to
+ the protocol are also possible. Implementers are warned that future
+ versions of this protocol may not interoperate with the version of
+ IPP defined in this document, or if they do interoperate, that some
+ protocol features may not be available.
+
+ The IESG encourages experimentation with this protocol, especially in
+ combination with Transport Layer Security (TLS) [RFC2246], to help
+ determine how TLS may effectively be used as a security layer for
+ IPP.
+
+Abstract
+
+ This document is one of a set of documents, which together describe
+ all aspects of a new Internet Printing Protocol (IPP). IPP is an
+ application level protocol that can be used for distributed printing
+ using Internet tools and technologies. This document takes a broad
+ look at distributed printing functionality, and it enumerates real-
+ life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+
+
+
+Wright Experimental [Page 1]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ administrators. The design goals document calls out a subset of end
+ user requirements that are satisfied in IPP/1.0. Operator and
+ administrator requirements are out of scope for version 1.0.
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol (this document)
+ Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.0: Model and Semantics [RFC2568]
+ Internet Printing Protocol/1.0: Encoding and Transport [RFC2565]
+ Internet Printing Protocol/1.0: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ The "Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol" document describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specifications, and gives background and rationale for the
+ IETF working group's major decisions.
+
+ The "Internet Printing Protocol/1.0: Model and Semantics" document
+ describes a simplified model consisting of abstract objects, their
+ attributes, and their operations that is independent of encoding and
+ transport. The model consists of a Printer and a Job object. The
+ Job optionally supports multiple documents. IPP 1.0 semantics allow
+ end-users and operators to query printer capabilities, submit print
+ jobs, inquire about the status of print jobs and printers, and cancel
+ print jobs. This document also addresses security,
+ internationalization, and directory issues.
+
+ The "Internet Printing Protocol/1.0: Encoding and Transport" document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1. It defines the encoding rules
+ for a new Internet media type called "application/ipp".
+
+ The "Internet Printing Protocol/1.0: Implementer's Guide" document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.0 and some of
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+ The "Mapping between LPD and IPP Protocols" document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+
+
+
+
+Wright Experimental [Page 2]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+TABLE OF CONTENTS
+
+ 1. INTRODUCTION.....................................................4
+ 2. TERMINOLOGY......................................................4
+ 3. DESIGN GOALS.....................................................6
+ 3.1. End-user.......................................................6
+ 3.1.1. Finding or locating a printer................................6
+ 3.1.2. Create an instance of the printer............................7
+ 3.1.3. Viewing the status and capabilities of a printer.............7
+ 3.1.4. Submitting a print job.......................................8
+ 3.1.5. Viewing the status of a submitted print job..................9
+ 3.1.6. Canceling a Print Job........................................9
+ 3.2. Operator (NOT REQUIRED FOR V1.0)...............................9
+ 3.2.1. Alerting.....................................................9
+ 3.2.2. Changing Print and Job Status...............................10
+ 3.3. Administrator (NOT REQUIRED FOR v1.0).........................10
+ 4. OBJECTIVES OF THE PROTOCOL......................................10
+ 4.1. SECURITY CONSIDERATIONS.......................................11
+ 4.2. Interaction with LPD (RFC1179)................................12
+ 4.3. Extensibility.................................................12
+ 4.4. Firewalls.....................................................13
+ 4.5. Internationalization..........................................13
+ 5. IPP SCENARIOS...................................................13
+ 5.1. Printer Discovery.............................................14
+ 5.2. Driver Installation...........................................15
+ 5.3. Submitting a Print Job........................................15
+ 5.4. Getting Status/Capabilities...................................16
+ 5.5. Asynchronous Notification.....................................17
+ 5.6. Job Canceling.................................................17
+ 6. Security Considerations.........................................18
+ 7. REFERENCES......................................................18
+ 8. ACKNOWLEDGMENTS.................................................19
+ 9. AUTHOR'S ADDRESS................................................19
+ 10. APPENDIX - DETAILED SCENARIOS..................................20
+ 10.1. Printer discovery within an enterprise.......................20
+ 10.2. Printer discovery across enterprises.........................21
+ 10.3. Printer discovery on the Internet -logical operations........21
+ 10.4. Printer discovery on the Internet - authentication...........22
+ 10.5. Driver Download..............................................23
+ 10.6. Submitting a print job as a file.............................24
+ 10.7. Submitting a print job with two documents....................24
+ 10.8. Submitting a print job as a file, printing fails.............25
+ 10.9. Submitting a print job with authentication, PRIVACY and
+ payment......................................................26
+ 10.10. Submitting a print job with decryption error................27
+ 10.11. Submitting a print job with authentication..................28
+ 10.12. Submitting a print job generated dynamically................29
+ 10.13. Submitting a print job with a Printer jam - CANCELED........29
+
+
+
+Wright Experimental [Page 3]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ 10.14. Submitting a print job with a Printer jam - recovered.......30
+ 10.15. Submitting a print job with server pull.....................31
+ 10.16. Submitting a print job with referenced resources............32
+ 10.17. Getting Capabilities........................................33
+ 10.17.1. Submission Attributes.....................................33
+ 10.17.2. Printer Capabilities......................................33
+ 10.18. Getting Status..............................................34
+ 10.18.1. Printer State/Status......................................34
+ 10.18.2. Job Status................................................34
+ 10.18.3. Status of All My Jobs.....................................34
+ 10.19. Asynchronous Notification...................................35
+ 10.19.1. Job Completion............................................35
+ 10.19.2. Job Complete with Data....................................35
+ 10.19.3. Print Job Fails...........................................35
+ 10.20. Cancel a job................................................36
+ 10.21. End to end Scenario - within an enterprise..................36
+ 10.22. End to end Scenario - across enterprises....................37
+ 10.23. End to End Scenario - on the internet.......................40
+ 11. Full Copyright Statement.......................................43
+
+1. INTRODUCTION
+
+ The IPP protocol is heavily influenced by the printing model
+ introduced in the Document Printing Application (DPA) [ISO10175]
+ standard. Although DPA specifies both end user and administrative
+ features, IPP version 1.0 (IPP/1.0) focuses only on end user
+ functionality.
+
+2. TERMINOLOGY
+
+ Internet Printing for the purposes of this document is the
+ application of Internet tools, programs, servers and networks to
+ allow end-users to print to a remote printer using, after initial
+ setup or configuration, the same methods, operations and paradigms as
+ would be used for a locally attached or a local area network attached
+ printer. This could include the use of HTTP servers and browsers and
+ other applications for providing static, dynamic and interactive
+ printer locating services, user installation, selection,
+ configuration, print job submission, printer capability inquiry and
+ status inquiry of remote printers and jobs.
+
+ For the purposes of this document, a WEB Browser is software
+ available from a number of sources including but not limited to the
+ following: Microsoft Internet Explorer, NCSA Mosaic, Netscape
+ Navigator, Sun Hot Java!. The major task of these products is to use
+ the Hypertext Transport Protocol (HTTP) to retrieve, interpret and
+ display Hypertext Markup Language (HTML). These products are often a
+ part of a complete Internet Printing system because they are often
+
+
+
+Wright Experimental [Page 4]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ used as a means of obtaining the status of or more information about
+ the printing system; however, they may not be present in all
+ implementations.
+
+ Throughout this document, 'printer' shall be interpreted to include
+ any device which is capable of marking on a piece of media using any
+ available technology. These design goals do not include support for
+ multi-tiered printing solutions involving servers (single or
+ multiple) logically in front of the actual printing device yet all
+ such configurations shall be supported but shall appear to the end-
+ user as only a single device.
+
+ Throughout this document 'driver' refers to the code installed in
+ some client operating system to generate the print data stream for
+ the intended printer. Some computing environments may not include a
+ separate printer driver. Rather, the generation of the proper print
+ data stream is accomplished in an application on that computer. How
+ such a computer environment or application is updated to support a
+ new printer now made available using IPP is outside the scope of IPP.
+ The actual details for installing a printer driver are operating
+ system dependent and are also outside the scope of IPP. See also
+ section 4.1 (SECURITY CONSIDERATIONS) for security implications of
+ driver download and installation.
+
+ The IPP protocol will support the following physical configurations:
+
+ - An IPP client talking to an IPP Printer object imbedded in a
+ single, physical output device.
+ - An IPP Client talking to a server containing one or more IPP
+ Printer objects. Each Printer object is associated with exactly one
+ physical output device supported by the server. The protocol
+ between the server and the output devices is undefined.
+ - An IPP Client talking to an IPP Printer object in a server. The
+ Printer object is associated with one or more physical output
+ devices, but the client only sees the Printer object, which is an
+ abstraction and represents all of the associated physical output
+ devices. The protocol between the server and the physical output
+ devices is undefined.
+
+ Throughout this document, certain design goals will be identified as
+ not being a part of version 1.0 (or V1.0) of the protocol or as being
+ satisfied by means outside of IPP. IPP is assumed to be one part, an
+ enabler, of a complete Internet Printing solution. For example
+ printer instance creation is not performed by but is enabled by the
+ protocol. Globally, none of the operator or administrators wants and
+ needs are included in the design goals for version 1.0. Some of the
+ end-user wants and needs may also be excluded from version 1.0 and
+ will be so noted in the description of them. Subsequent versions of
+
+
+
+Wright Experimental [Page 5]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ the protocol (e.g. V2.0) may include support for these initially
+ excluded wants and needs.
+
+3. DESIGN GOALS
+
+ The next three sections identify the design goals for an Internet
+ printing protocol from three roles assumed by humans: end-user,
+ operator, and administrator. The goals defined here are only those
+ that need to be addressed by an Internet printing protocol. Other
+ wants and needs, such as that the operator needs physical access to
+ the printer (e.g. to be able to load paper or clear jams) are not
+ covered by this document. Section 5 contains scenarios which provide
+ more detailed examples of the entire process including discovery,
+ status, printing and end-of-job reporting.
+
+3.1. END-USER
+
+ An end-user of a printer accepting jobs through the Internet is one
+ of the roles in which humans act. The end-user is the person that
+ will submit a job to be printed on the printer.
+
+ The wants and needs of the end-user are broken down into six
+ categories: finding/locating a printer, creating a local instance of
+ a printer, viewing printer status, viewing printer capabilities,
+ submitting a print job, viewing print job status, altering the
+ attributes of a print job.
+
+3.1.1. Finding or locating a printer.
+
+ End-users want to be able to find and locate printers to which they
+ are authorized to print. They want to be able to perform this
+ function using a standard WEB browser or other application. Multiple
+ criteria can be applied to find the printers needed. These criteria
+ include but are not limited to:
+
+ - by name (Printer 1, Joes-color-printer, etc.)
+ - by geographic location (bldg 1, Kentucky, etc.)
+ - by capability or attribute (color, duplex, legal paper, etc.)
+
+ Additionally, while it is outside of scope of IPP, end-users want to
+ be able to limit the scope of their searching to:
+
+ - inside a functional sub-domain
+ - include only a particular domain (lexmark.com)
+ - exclude specified domains
+
+
+
+
+
+
+Wright Experimental [Page 6]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ While an Internet printing protocol may not of itself include this
+ function, IPP must define and enable a directory schema which will
+ provide the necessary information for a directory service
+ implementation to consistently represent printers by their IPP
+ attributes.
+
+3.1.2. Create an instance of the printer.
+
+ After finding the desired printer, an end-user needs to be able to
+ create a local instance of that printer within the end-user operating
+ system or desktop. This local instance will vary depending upon the
+ printing paradigm of the operating system. For example, some UNIX
+ users will only want a queue or a reference to a remote printer
+ created on their machine while other UNIX users and Windows NT users
+ will want the queue and also the necessary icons and registry entries
+ to be created and initialized. Where required, drivers may need to
+ be downloaded from some repository and installed on the computer.
+ All necessary decompressing, unpacking, and other installation
+ actions should occur without end-user interaction or intervention
+ excepting initial approval by the end-user. Once the local instance
+ of the printer has been installed, it shall appear to the end-user of
+ the operating system and to the applications running there as any
+ other printer (local, local area network connected, or network
+ operating system connected) on the end-user desktop or environment.
+ IPP's role in this goal is simply to enable the creation of the
+ printer instance providing information such as where to locate a
+ printer driver for this printer, as an attribute of an IPP Printer.
+
+3.1.3. Viewing the status and capabilities of a printer.
+
+ Before using a selected printer or, in fact at any time, the end-user
+ needs the ability to verify the characteristics and status of both
+ printers and jobs queued for that printer. When checking the
+ characteristics of a printer, the end-user typically wants to be able
+ to determine the capability of the device, e.g.:
+
+ - supported media, commonly paper, by size and type
+ - paper handling capability, e.g. duplex, collating, finishing
+ - color capability
+
+ When checking the status of the printer and its print jobs, the end-
+ user typically wants to be able to determine:
+
+ - is the printer on-line?
+ - what are the defaults to be used for printing?
+ - how many jobs are queued for the printer?
+ - how are job priorities assigned? (outside the scope of IPP)
+
+
+
+
+Wright Experimental [Page 7]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+3.1.4. Submitting a print job.
+
+ Once the desired printer has been located and installed, the end-user
+ wants to print to that printer from normal applications using
+ standard methods. These normal applications include such programs as
+ word processors, spreadsheets, data-base applications, WEB browsers,
+ production printing applications, etc. Additionally, the end-user
+ may want to print a file already existing on the end-user's computer
+ -- "simple push". In addition to printing from an application and
+ simple push, the end-user needs to have the ability to submit a print
+ job by reference. Printing by reference is defined to mean as
+ submitting a job by providing a reference to an existing document.
+ The reference, a URI, will be resolved before the actual print
+ process occurs. Submitting a job by reference relieves the user from
+ downloading the document from the remote server and then sending it
+ via IPP to the printer. This saves both time and network bandwidth.
+
+ Some means shall be provided to determine if the format of a job
+ matches the capability of the printer. This can be done by one of
+ the following (all of which are outside of scope of the IPP
+ protocol):
+
+ - the end-user selects the correct printer driver
+ - the printer automatically selects the proper interpreter
+ - the end-user uses some other manual procedure.
+
+ A standard action shall be defined should the job's requirements not
+ match the capabilities of the printer.
+
+ Because the end-user does not want to know the details of the
+ underlying printing process, the protocol must support job-to-printer
+ capability matching (all implementations are not necessarily required
+ to implement this function.) This matching capability requires
+ knowing both the printer's capabilities and attributes and those
+ capabilities and attributes required by the job. Actions taken when
+ a print job requires capabilities or attributes that are not
+ available on the printer vary and can include but are not limited to:
+
+ - rejecting the print job
+ - redirecting the print job to another printer (Not in V1.0)
+ - printing the job, accepting differences in the appearance
+
+ Print jobs will also be submitted by background or batch applications
+ without human intervention.
+
+ End-users need the ability to set certain print job parameters at the
+ time the job is submitted. These parameters include but are not
+ limited to:
+
+
+
+Wright Experimental [Page 8]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ - number of copies
+ - single or two sided printing
+ - finishing
+ - job priority
+
+3.1.5. Viewing the status of a submitted print job.
+
+ After a job has been submitted to a printer, the end-user needs a way
+ to view the status of that job (i.e. job waiting, job printing, job
+ done) and to determine where the job is in the print queue.
+
+ In addition to the need to inquire about the status of a print job,
+ automatic notification of the completion of that job is also
+ required.
+
+ Notification means are not defined by the protocol but the protocol
+ must provide a means of enabling and disabling the notification.
+
+3.1.6. Canceling a Print Job
+
+ While a job is waiting to be printed or has been started but not yet
+ completed, the original creator/submitter of the print job (i.e. the
+ end-user) shall be able to cancel the job entirely (job is waiting)
+ or the remaining portion of it (job is printing.) Altering the print
+ job itself is not a V1.0 design goal.
+
+3.2. OPERATOR (NOT REQUIRED FOR V1.0)
+
+ An operator of a printer accepting jobs through the Internet is one
+ of the roles in which humans act. The operator has the
+ responsibility of monitoring the status of the printer as well as
+ managing and controlling the jobs at the device. These
+ responsibilities include but are not limited to the replenishing of
+ supplies (ink, toner, paper, etc.), the clearing of minor errors
+ (paper jams, etc.) and the re-prioritization of end-user jobs.
+ Operator wants and needs will not be addressed by V1.0 of the
+ protocol.
+
+ The wants and needs of the operator include all those of the end-user
+ but may include additional privileges. For example, an operator may
+ be able to view all print jobs on a printer while the end-user might
+ only be able to see his own jobs.
+
+3.2.1. Alerting.
+
+ One of the required operator functions is having the ability to
+ discover or to be alerted to changes in the status of a printer
+ particularly those changes that cause a printer to stop printing and
+
+
+
+Wright Experimental [Page 9]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ to be able to correct those problems. As such, an Internet printing
+ protocol shall be able to alert a designated operator or operators to
+ these conditions such as 'out of paper', 'out of ink', etc.
+ Additionally. the operator shall be able to, asynchronous to other
+ printer activity, inquire as to a printer's or a job's status.
+
+3.2.2. Changing Print and Job Status.
+
+ Another of the required operator functions is the ability to affect
+ changes to printer and job status remotely. For example, the
+ operator will need to be able to re-prioritize or cancel any print
+ jobs on a printer to which the operator has authority.
+
+3.3. ADMINISTRATOR (NOT REQUIRED FOR V1.0)
+
+ An administrator of a printer accepting jobs through the Internet is
+ one of the roles in which humans act. The administrator has the
+ responsibility of creating the printer instances and controlling the
+ authorization of other end-users and operators. Administrator wants
+ and needs will not be addressed by V1.0 of the protocol.
+
+ The wants and needs of the administrator include all those of the
+ end-user and, in some environments, some or all of those of the
+ operator. Minimally, the administrator must also have the tools,
+ programs, utilities and supporting protocols available to be able to:
+
+ - create an instance of a printer
+ - create, edit and maintain the list of authorized end-users
+ - create, edit and maintain the list of authorized operators
+ - create, edit and maintain the list of authorized
+ administrators
+ - create, customize, change or otherwise alter the manner in
+ which the status capabilities and other information about printers
+ and jobs are presented
+ - create, customize, or change other printer or job features
+ - administrate billing or other charge-back mechanisms
+ - create sets of defaults
+ - create sets of capabilities
+
+ The administrator must have the capability to perform all the above
+ tasks locally or remotely to the printer.
+
+4. OBJECTIVES OF THE PROTOCOL
+
+ The protocol to be defined by an Internet printing working group will
+ address the wants and needs of the end-user (V1.0). It will not, at
+ least initially, address the operator or administrator wants and
+ needs (V2.0).
+
+
+
+Wright Experimental [Page 10]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ The protocol defined shall be independent of the operating system of
+ both the client and the server. Generally, any platform capable of
+ supporting a WEB Browser should be capable of being a client.
+ Generally, any platform providing a WEB/HTTP server and printing
+ services should be capable of being a server. Usage of the WEB
+ Browser and Server is not required for IPP; the operating system,
+ operating system extensions or other applications may provide IPP
+ functionality directly.
+
+ In many environments such as Windows 95, Windows NT and OS/2, the
+ print data is created and transmitted to the printer on the fly
+ rather than being created, spooled and then transmitted to the
+ printer (a typical UNIX method.) The Internet Printing Protocol must
+ properly handle either methodology and make this transparent to the
+ end-user.
+
+4.1. SECURITY CONSIDERATIONS
+
+ It is required that the Internet Printing Protocol be able to operate
+ within a secure environment. Wherever reasonable, IPP ought to make
+ use of existing security protocols and services. IPP will not invent
+ new security features when the design goals described in this
+ document can be met by existing protocols and services. Examples of
+ such services include Secure Socket Layer Version 3 (SSL3) [SSL] and
+ HTTP Digest Access Authentication [RFC2069]. Note: SSL3 is not on
+ the IETF standards track.
+
+ Since we cannot anticipate the security levels or the specific
+ threats that any given IPP print administrator may be concerned with,
+ IPP must be capable of operating with different security mechanisms
+ and policies as required by the individual installation. The initial
+ security needs of IPP are derived from two primary considerations.
+ First, the printing environments described in this document take into
+ account that the client, the Printer, and the document to be printed
+ may each exist in different security domains. When objects are in
+ different security domains the design goals for authentication and
+ message protection may be much stronger than when they are all in the
+ same domain.
+
+ Secondly, the sensitivity and value of the content being printed will
+ vary from one instance of a print job to another. For example, a
+ publicly available document does not need the same level of
+ protection as a payroll document does. Message protection design
+ goals include data origin authentication, privacy, integrity, and
+ non-repudiation.
+
+
+
+
+
+
+Wright Experimental [Page 11]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ In many environments (e.g. Windows, OS/2) a printer driver may be
+ needed to create the proper datastream for printer. This document
+ discusses downloading such a new driver from a variety of sources.
+ Downloading and installing any software, including drivers) on a
+ computer exposes that computer to a number of security risks
+ including but not limited to:
+
+ - defective software
+ - malicious software (e.g. Trojan horses)
+ - inappropriate software (i.e. software doing something
+ deemed unreasonable by the user.)
+
+ As such, proper security considerations and actions need to be taken
+ by the user and/or a system administrator to prevent the compromising
+ of the computer. Administrators should configure downloading
+ mechanism for printer drivers in such a way as to be able to verify
+ the source of driver software and encrypt or otherwise protect that
+ software during download.
+
+ Examples including security considerations can be found in sections 5
+ (IPP SCENARIOS) and 10 (APPENDIX - DETAILED SCENARIOS) later in this
+ document.
+
+4.2. INTERACTION WITH LPD (RFC1179)
+
+ Many versions of UNIX and in fact other operating systems provide a
+ means of printing as described in [RFC1179] (Line Printer Daemon
+ Protocol.) This document describes the file formats for the control
+ and data files as well as the messages used by the protocol. Because
+ of the simplistic approach taken by this protocol, many manufacturers
+ have include proprietary enhancements and extensions to 'lpd.'
+ Because of this divergence and due to other design goals described in
+ this document, there is no requirement for backward compatibility or
+ interoperability with 'lpd'. However, a mapping of LPD functionality
+ and IPP functionality shall be provided so as to enable a gateway
+ between LPD and IPP.
+
+4.3. EXTENSIBILITY
+
+ The Internet Printing Protocol shall be extensible by several means
+ that facilitate interoperability and prevent implementation
+ collisions:
+
+ - by providing a process whereby implementers can submit proposals
+ for registration of new attributes and new enumerated values for
+ existing attributes.
+
+
+
+
+
+Wright Experimental [Page 12]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ * that require review and approval. The Internet Assigned
+ Number Authority (IANA) will be the repository for such
+ accepted registration proposals after review.
+
+ * that do not require review and approval. IANA will be the
+ repository for such registrations.
+
+ - by providing syntax in the protocol so that implementers may add
+ private (i.e. unregistered) attributes and enumerated attribute
+ values.
+
+ - by providing versioning and negotiation so as to enable future
+ implementations of IPP to interoperate with implementations of
+ version 1.0 of IPP.
+
+4.4. FIREWALLS
+
+ As stated in section 3 Design Goals, Internet printing shall, by
+ definition, support printing from one enterprise to another. As
+ such, the Internet printing protocol must be capable of passing
+ through firewalls and/or proxy servers (where enabled by the firewall
+ administrator) preferably without modification to the existing
+ firewall technology.
+
+4.5. INTERNATIONALIZATION
+
+ Users of Internet printing will come from all over the world. As
+ such, where appropriate, internationalization and localization will
+ be enabled for the protocol.
+
+5. IPP SCENARIOS
+
+ Each of the scenarios in this section describes a specific IPP
+ operation, such as submitting a print job. Section 10 contains
+ several detailed flows for each scenario to provide additional
+ detail. The examples should not be considered exhaustive, but
+ illustrative of the functions and features required in the protocol.
+ Flows are intended to be protocol neutral. It is not assumed that all
+ of the functions and features described in these scenarios will
+ necessarily be supported directly by IPP or in version 1.0 of IPP.
+
+ See the IPP Model and Semantics document for details on
+ configurations of clients, servers and firewalls.
+
+
+
+
+
+
+
+
+Wright Experimental [Page 13]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+5.1. PRINTER DISCOVERY
+
+ Client Directory Service
+ Service
+
+ +----------------------------------------------------------- >
+ give me information on printers with these characteristics
+
+
+ < -----------------------------------------------------------+
+ Information on Printers matching these characteristics
+
+ The objective of printer discovery is to locate printers that meet
+ the client's wants and needs. The Directory Service should provide
+ enough information for the client to make an initial choice. The
+ client may have to connect to each individual Printer offered to get
+ more detail. Not all information available from the Directory
+ Service is obtained using IPP; some information may be
+ administratively provided.
+
+ The actual protocol used between client and Directory or Name Service
+ is considered outside the scope of IPP. Printer Discover is included
+ in the scenarios to provide design goals for the directory schema for
+ IPP Printers and to further define Printer attributes.
+
+ Characteristics that might be considered when locating a Printer
+ include:
+
+ - capabilities of the Printer, e.g. PDLs supported
+ - physical location, e.g. in building 010
+ - driver required and location
+ - cost per page to print (outside the scope of IPP)
+ - whether or not printer is access controlled
+ - whether or not usage requires client authentication
+ - whether or not Printer can be authenticated
+ - whether or not payment is required for printing (outside the scope
+ of IPP)
+ - maximum job size (spool size) (outside the scope of IPP)
+ - whether or not Printer support compression (outside the scope of
+ IPP)
+ - whether or not Printer supports encryption
+ - administrative limits on this Printer
+ - maximum number of copies per job
+ - maximum number of pages per job
+
+
+
+
+
+
+
+Wright Experimental [Page 14]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ Responses could additionally include:
+
+ - how to get more information
+ - web page
+ - telephone number
+ - help desk
+
+5.2. DRIVER INSTALLATION
+
+ Client Printer
+
+ +----------------------------------------------------------- >
+ Where can I find a driver & software to install it?
+
+
+ < -----------------------------------------------------------+
+ URIs for drivers and install software
+
+ Driver here refers to the code installed in some client operating
+ system to generate the print data stream for the intended printer.
+ The actual details for installing a printer driver are operating
+ system dependent and are also outside the scope of IPP. However, an
+ IPP printer or a directory service advertising an IPP Printer should
+ be capable of telling a client what drivers are available and/or
+ required, where they can be found, and provide pointers to
+ installation instructions, installation code or initialization
+ strings required to install the driver. See section 4.1 (SECURITY
+ CONSIDERATIONS) for security implications of driver download and
+ installation.
+
+5.3. SUBMITTING A PRINT JOB
+
+ Client IPP Printer
+
+ +----------------------------------------------------------- >
+ Here is a Print Job
+ - Job attributes
+ - Print data
+
+
+ < -----------------------------------------------------------+
+ Response
+
+ The protocol must support these sources of client data:
+
+ - Print data is a file submitted with the job
+ - Print data is generated on the fly by an application
+ - Print data is a file referenced by a URI
+
+
+
+Wright Experimental [Page 15]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ The protocol must handle overrun conditions in the printer and must
+ support overlapped printing and downloading of the file in devices
+ that are unable to spool files before printing them.
+
+ Every print request will have a response. Responses will indicate
+ success or failure of the request and provide information on failures
+ when they occur. Responses would include things like:
+
+ - Got the print job and queued it
+ - Got the print job and am printing it
+ - Got the print job, started to print it, but printing failed
+ - why it failed (e.g. unrecoverable PostScript error)
+ - state of the printer
+ - how much printed
+ - Got the print job but couldn't print it
+ - why it can't be printed
+ - state of the printer
+ - Got the print job but don't know what to do with it
+ - Didn't get a complete print job (e.g. communication failure)
+
+5.4. GETTING STATUS/CAPABILITIES
+
+ Client IPP Printer
+
+ +----------------------------------------------------------- >
+ Get status and/or capabilities of Printer
+
+
+ < -----------------------------------------------------------+
+ Status/Capabilities
+
+ Clients will need to get information about
+
+ - Static capabilities of the device
+ - Dynamic state of the Printer (e.g. out of paper)
+ - State of a specific job owned by this client
+ - State of all jobs owned by this client
+ - queued
+ - printing
+ - completed
+
+
+
+
+
+
+
+
+
+
+
+Wright Experimental [Page 16]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ - Job submission attributes supported/required
+ - scheduling attributes (e.g. priority)
+ - production attributes (e.g. number of copies)
+
+5.5. ASYNCHRONOUS NOTIFICATION
+
+ Client IPP Printer
+
+ +----------------------------------------------------------- >
+ Use the following method to notify me of Printer events
+
+ .
+ .
+ .
+ < -----------------------------------------------------------+
+ Asynchronous notification of Printer event
+
+ Clients must be able to request asynchronous notification for Printer
+ events such as
+
+ - job completion
+ - a fatal error that requires the job to be resubmitted
+ - a condition that severely impacts a queued job for this client
+ e.g. printer is out of paper
+
+ Note: end-user notification is a V1.0 design goal while operator
+ notification is for V2.0.
+
+5.6. JOB CANCELING
+
+ Client IPP Printer
+
+ +----------------------------------------------------------- >
+ Cancel the named job as indicated
+
+
+ < -----------------------------------------------------------+
+ Response (did it or not)
+
+ Similarly clients must be able to make changes to jobs which have
+ been submitted and are queued for printing. Changing of job
+ attributes should also be supported. Job modifications, holding and
+ releasing of jobs are not included in the design goals for IPP v1.0.
+
+
+
+
+
+
+
+
+Wright Experimental [Page 17]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+6. SECURITY CONSIDERATIONS
+
+ The security considerations for IPP are described in Section 4.1
+ above.
+
+7. REFERENCES
+
+ [ipp-iig] Hastings, T. and C. Manros, "Internet Printing
+ Protocol/1.0: Implementer's Guide", Work in Progress.
+
+ [RFC2569] Herriot, R., Hastings, T., Jacobs, N. and J. Martin,
+ "Mapping between LPD and IPP Protocols", RFC 2569, April
+ 1999.
+
+ [RFC2566] deBry, R., Hastings, T., Herriot, R., Isaacson, S. and P.
+ Powell, "Internet Printing Protocol/1.0: Model and
+ Semantics", RFC 2568, April 1999.
+
+ [RFC2565] Herriot, R., Butler, S., Moore, P. and R. Tuner, "Internet
+ Printing Protocol/1.0: Encoding and Transport", RFC 2565,
+ April 1999.
+
+ [RFC2568] Zilles, S., "Rationale for the Structure and Model and
+ Protocol for the Internet Printing Protocol", RFC 2568,
+ April 1999.
+
+ [ISO10175] ISO/IEC 10175, Document Printing Application, June 1996.
+
+ [RFC1179] McLaughlin, L., "Line Printer Daemon Protocol" RFC 1179,
+ August 1990.
+
+ [SSL] Netscape, The SSL Protocol, Version 3, (Text version
+ 3.02), November 1996.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Wright Experimental [Page 18]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+8. ACKNOWLEDGMENTS
+
+ This document draws heavily from preliminary work done by others
+ especially in the Printer Working Group (PWG). The author gratefully
+ acknowledges the specific contributions of:
+
+ Scott Isaacson Roger deBry
+ Novell Utah Valley State College
+ sisaacson@novell.com debryro@uvsc.edu
+
+ Carl-Uno Manros Robert Herriot
+ Xerox Sun
+ manros@cp10.es.xerox.com Robert.Herrior@pahv.xerox.xom
+
+ Tom Hastings Peter Zehler
+ Xerox Xerox
+ hastings@cp10.es.xerox.com Peter.Zehler@usa.xerox.com
+
+9. AUTHOR'S ADDRESS
+
+ F.D. (Don) Wright
+ Lexmark International
+ C14/035-3
+ 740 New Circle Rd
+ Lexington, KY 40550
+
+ Phone: 606-232-4808
+ Fax: 606-232-6740
+ EMail: don@lexmark.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Wright Experimental [Page 19]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+10. APPENDIX - DETAILED SCENARIOS
+
+ The following are more detailed scenarios illustrating how the
+ Internet Printing Protocol is expected to be used as a part of a
+ complete Internet Printing system. Some parts of the scenarios
+ include concepts, functions and information that may be outside of
+ the scope of version 1.0 of IPP (e.g. cost per page, payments means
+ available, etc.) The information contained herein is meant to be
+ generic. There may not be an exact wording or terminology match
+ between these scenarios and the implementation documents.
+
+10.1. PRINTER DISCOVERY WITHIN AN ENTERPRISE
+
+ A user wants to find a color Postscript printer in his/her enterprise
+ which will print transparencies. The client, directory service, and
+ printer are all behind the same corporate firewall. Because color
+ foils are expensive, printers of this type are access controlled and
+ require an account to be established so that printing can be billed
+ back to the using department. Note the request to find a printer
+ usable by Dept. J15. Drivers for all supported printers are
+ available from the server they are associated with. A help desk is
+ provided for end user support. The printer is unattended.
+
+ Client Directory Service
+
+ +---------------------------------------------------------- >
+ Find a printer with these characteristics
+ - prints color, prints transparencies
+ - prints Postscript
+ - is in building 003
+ - accessible by the client
+
+ < ----------------------------------------------------------+
+ Printer "Color-A"
+ - prints color, prints transparencies
+ - prints Postscript
+ - in room H-6, building 003
+ - driver ABC-Postscript-V1.3 required, here is URI
+ - cost is $.45 per page for color transparencies
+ - limit is 10 pages per job
+ - authentication required to use printer
+ - printer is unattended
+ - help desk at x5001
+
+ Printer "Color-B"
+ - prints color, prints transparencies
+ - prints Postscript
+ - in room J-10, building 003
+
+
+
+Wright Experimental [Page 20]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ - driver XYZ-Postscript-V2.4 required, here is URI
+ - cost is $1.25 page for color transparencies
+ - limit is 5 pages per job
+ - authentication is required to use printer
+ - printer is unattended
+ - help desk at x5001
+
+10.2. PRINTER DISCOVERY ACROSS ENTERPRISES
+
+ A user in Company A wants to find a public printer in a business
+ partner's enterprise (Company B) on which to print a purchase order.
+ The client is behind one corporate firewall and the directory service
+ and the printer are behind a different corporate firewall. Drivers
+ for all supported printers are available from the server they are
+ associated with. A web page is provided for end user support for
+ public printers.
+
+ Client Company B Directory Service
+
+ +---------------------------------------------------------- >
+ Find a printer with these characteristics
+ - prints black and white
+ - is in El Segundo, building A
+ - is a public printer
+
+ < ----------------------------------------------------------+
+ Printer "Public-A"
+ - prints black and white
+ - prints Postscript
+ - in El Segundo, room H-6, building A
+ - driver ABC-Postscript-V1.3 required, here is URI
+ - printer is public
+ - help available at http://xerox/elSegundo/publicPrinters
+
+ Printer "Public-B"
+ - prints black and white
+ - prints PCL/5e
+ - is in El Segundo, room J-10, building A
+ - driver XYZ-PCL-V2.4 required, here is URI
+ - printer is public
+ - help available at http://xerox/elSegundo/publicPrinters
+
+10.3. PRINTER DISCOVERY ON THE INTERNET -LOGICAL OPERATIONS
+
+ A student wants to print a paper on a printer at his neighborhood
+ Ink-o's print shop. The report was written using Microsoft Word. The
+ student is interested in the cost of printing since his budget is
+ limited. Note the use of logical operators to find this information.
+
+
+
+Wright Experimental [Page 21]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ Client Ink-o's Directory Service
+
+ +---------------------------------------------------------- >
+ Find a Printer with these characteristics
+ - prints color or black and white
+ - costs less than $.50 per page
+ - tell me about resolution and marking technology
+
+ < ----------------------------------------------------------+
+ Printer "Color-A"
+ - prints color
+ - 600 dpi laser printer
+ - prints Postscript
+ - driver ABC-Postscript-V1.3 required, here is URI
+ - cost is $.50 per page for color
+ - payment required prior to submitting print job
+ - here is URI for more information on Ink-o's
+
+ Printer "Mono-B"
+ - prints black and white
+ - 300 dpi inkjet printer
+ - prints Postscript
+ - driver XYZ-Postscript-V2.4 required, here is URI
+ - cost is $0.35 page for black and white
+ - payment required prior to submitting print job
+ - here is URI for more information on Ink-o's
+
+10.4. PRINTER DISCOVERY ON THE INTERNET - AUTHENTICATION
+
+ An executive in her hotel room is finishing an important presentation
+ on her laptop computer. She connects to a local print shop through
+ the web to get a copy of her charts printed for tomorrow's
+ presentation. She must find a print shop that is convenient to her
+ hotel and can print color transparencies. She wants to be sure that
+ the printer can be authenticated and can accept encrypted data.
+
+ Client SirZippy Directory Service
+
+ +---------------------------------------------------------- >
+ Find a Printer with these characteristics
+ - prints color transparencies
+ - is in Boulder, Colorado
+ - Printer can be authenticated
+ - Printer supports encryption
+
+
+
+
+
+
+
+Wright Experimental [Page 22]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ Tell me when you are open for business
+
+ < ----------------------------------------------------------+
+ Printer "Color-A"
+ - prints color transparencies
+ - prints Postscript
+ - driver ABC-Postscript-V1.3 required, here is URI
+ - payment required prior to submitting print job
+ - Printer can be authenticated
+ - Data can be encrypted
+ - Located at 1670 Pearl Street, Boulder, CO
+ - This Branch is open 24 hours a day
+
+
+ Printer "Color-B"
+ - prints color transparencies
+ - prints Postscript
+ - driver ABC-Postscript-V1.3 required, here is URI
+ - payment required prior to submitting print job
+ - Printer can be authenticated
+ - Data can be encrypted
+ - Located at 1220 Arapahoe, Boulder, CO
+ - This Branch is open from 9:00 am to 6:30 pm
+
+10.5. DRIVER DOWNLOAD
+
+ An end user in an enterprise wants to print a lengthy report on a
+ newly installed high speed PostScript printer. Since she will likely
+ use this printer often, she would like to download a driver and
+ install it on her workstation. She is running Windows 95. Note:
+ Driver download is not a V1.0 design goal.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ Tell me where to find print drivers for you
+
+
+
+ < ----------------------------------------------------------+
+ Driver install file is at
+ http://www.ibm.com/drivers/NP12a/Win95
+
+
+
+
+
+
+
+
+
+Wright Experimental [Page 23]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+10.6. SUBMITTING A PRINT JOB AS A FILE
+
+ An end-user wants to submit a print job. The print file already
+ exists on his workstation. The client and printer are behind the same
+ corporate firewall. The printer is available to anyone behind the
+ firewall and no authorization or authentication is required. The data
+ is pushed to the printer. The printer is capable of spooling the
+ output. No errors occur.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ Here is a print job
+ - job name = MyJob
+ - notify me by email when done printing
+ - print on iso-a4-white paper
+ - print on both sides of the paper
+ - return status of the printer in response
+ - document is in Postscript format
+ - here is the document to print
+
+ < ----------------------------------------------------------+
+ Print job accepted and spooled
+ - job id = #12345
+ - current state of print job = spooled
+ - submission time = 02/12/97, 15:35
+ - printer state = printing
+
+10.7. SUBMITTING A PRINT JOB WITH TWO DOCUMENTS
+
+ An end-user wants to submit a print job. The print file already
+ exists on his workstation. The client and printer are behind the same
+ corporate firewall. The printer is available to anyone behind the
+ firewall and no authorization or authentication is required. The data
+ is pushed to the printer. The job consists of two separate documents.
+ The printer is capable of spooling the output. No errors occur.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ Here is a print job
+ - job name = MyJob
+ - notify me by email when done printing
+ - print on iso-a4-white paper
+ - print on both sides of the paper
+ - return status of the printer in response
+
+ < ----------------------------------------------------------+
+
+
+
+Wright Experimental [Page 24]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ Print job accepted and spooled
+ - job id = #12345
+ - submission time = 02/12/97, 15:35
+ +---------------------------------------------------------- >
+ - here is the document to print
+
+ < ----------------------------------------------------------+
+ - OK
+
+ +---------------------------------------------------------- >
+ - here is the document to print, it is the last document.
+
+ < ----------------------------------------------------------+
+ - OK
+
+10.8. SUBMITTING A PRINT JOB AS A FILE, PRINTING FAILS
+
+ An end-user wants to submit a print job. The print file already
+ exists on his workstation. The client and printer are behind the same
+ corporate firewall. The printer is available to anyone behind the
+ firewall and no authorization or authentication is required. The data
+ is pushed to the printer. The printer is not capable of spooling the
+ output so it begins printing while still receiving the file. An error
+ occurs and the printer cannot complete printing (in this case the
+ user requires A4 paper and that paper size is not available on the
+ printer.)
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ Here is a print job
+ - job name = MyJob
+ - notify me by email when done printing
+ - print on iso-a4-white paper
+ - print on both sides of the paper
+ - return status of the printer in response
+ - document is in Postscript format
+ - here is the document to print
+
+ < ----------------------------------------------------------+
+ Print job accepted
+
+ - printing failed
+ - current state of print job = canceled (A4 not available)
+ - submission time = 02/12/97, 15:35
+ - printer state = ready
+
+
+
+
+
+Wright Experimental [Page 25]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+10.9. SUBMITTING A PRINT JOB WITH AUTHENTICATION, PRIVACY AND PAYMENT
+
+ A traveling executive needs to print a set of transparencies for an
+ important business meeting. The charts are in Lotus Freelance format
+ on his notebook computer. He has located a SirZippy print shop near
+ his hotel that will print color transparencies. Because the
+ information on the charts is sensitive, he wants to be sure that his
+ data is sent to the Printer in an encrypted format. He also wants to
+ authenticate the Printer. The Printer also authenticates the user.
+ Payment occurs across the Internet.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ < ----------------------------------------------------------+
+
+ Mutual authentication and exchange of secret keys
+
+ +---------------------------------------------------------- >
+ Here is a print job (encrypted)
+ - job name = MyJob
+ - notify me by email when done printing
+ - print on iso-a4-white paper
+ - print on both sides of the paper
+ - return status of the printer in response
+ - tell me where to pick up output
+ - document is in Postscript format
+ - here is the document to print
+
+ < ----------------------------------------------------------+
+ Print job accepted and spooled (encrypted)
+ - job id = #12345
+ - current state of print job = spooled
+ - submission time = 02/12/97, 15:35
+ - printer state = printing
+ - payment required to proceed with job
+ - pick up at 230 East Main after 3:30 pm today
+
+ +---------------------------------------------------------- >
+ < ----------------------------------------------------------+
+ Payment transaction
+
+
+
+
+
+
+
+
+
+
+Wright Experimental [Page 26]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+10.10. SUBMITTING A PRINT JOB WITH DECRYPTION ERROR
+
+ A traveling executive needs to print a set of transparencies for an
+ important business meeting. The charts are in Lotus Freelance format
+ on his notebook computer. He has located a SirZippy print shop near
+ his hotel that will print color transparencies. Because the
+ information on the charts is sensitive, he wants to be sure that his
+ data is sent to the printer in an encrypted format. He also wants to
+ authenticate the printer. The printer also authenticates the user.
+ Payment occurs across the Internet. An error occurs during
+ decryption.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ < ----------------------------------------------------------+
+ Mutual authentication and exchange of secret keys
+
+
+ +---------------------------------------------------------- >
+ Here is a print job (encrypted)
+ - job name = MyJob
+ - notify me by email when done printing
+ - print on iso-a4-white paper
+ - print on both sides of the paper
+ - return status of the printer in response
+ - tell me where to pick up output
+ - document is in Postscript format
+ - here is the document to print
+
+ < ----------------------------------------------------------+
+ Print job accepted and spooled (encrypted)
+ - job id = #12345
+ - current state of print job = spooled
+ - submission time = 02/12/97, 15:35
+ - printer state = printing
+ - payment required to proceed with job
+ - pick up at 230 East Main after 3:30 pm today
+
+ +---------------------------------------------------------- >
+ < ----------------------------------------------------------+
+ Payment transaction
+ .
+ .
+ .
+ < ----------------------------------------------------------+
+ Asynchronous response (email in this case)
+ - decryption failed on job #12345
+
+
+
+Wright Experimental [Page 27]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ - no pages printed
+ - current state of job = aborted
+
+10.11. SUBMITTING A PRINT JOB WITH AUTHENTICATION
+
+ An end-user wants to submit a print job. The print file already
+ exists on his workstation. The client and printer are behind the same
+ corporate firewall. The printer is available to anyone behind the
+ firewall but authentication and authorization is required.
+ Authorization takes place using the authenticated end-user's name.
+ The data is pushed to the printer. The printer is capable of spooling
+ the output.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ < ----------------------------------------------------------+
+ Authentication
+
+ Note: An authentication failure would end the transaction at
+ this point.
+
+ +---------------------------------------------------------- >
+ Here is a print job
+ - job name = MyJob
+ - notify me by email when done printing
+ - print on iso-a4-white paper
+ - print on both sides of the paper
+ - return status of the printer in response
+ - tell me where to pick up output
+ - document is in Postscript format
+ - here is the document to print
+
+ < ----------------------------------------------------------+
+ Print job accepted and spooled
+ - job id = #12345
+ - current state of print job = spooled
+ - submission time = 02/12/97, 15:35
+ - printer state = printing
+
+
+
+
+
+
+
+
+
+
+
+
+Wright Experimental [Page 28]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+10.12. SUBMITTING A PRINT JOB GENERATED DYNAMICALLY
+
+ An end-user wants to submit a print job. The print data is generated
+ dynamically and is being transmitted by a printer driver on the
+ client workstation as available. The client and printer are behind
+ the same corporate firewall. The printer is available to anyone
+ behind the firewall and no authentication and authorization is
+ required. The data is pushed to the printer. The printer is capable
+ of spooling the output. No error occurs.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ Here is a print job
+ - job name = MyJob
+ - notify me by email when done printing
+ - print on iso-a4-white paper
+ - print on both sides of the paper
+ - return status of the printer in response
+ - document is in Postscript format
+ - here is the print job
+
+
+ < ----------------------------------------------------------+
+ Print data accepted and spooling started
+ - job id = #12345
+ - current job state = spooled
+ - submission time = 02/12/97, 15:35
+ - printer state = printing
+
+10.13. SUBMITTING A PRINT JOB WITH A PRINTER JAM - CANCELED
+
+ An end-user wants to submit a print job. The print data is generated
+ dynamically and is being transmitted by a printer driver on the
+ client workstation as available. The client and printer are behind
+ the same corporate firewall. The printer is available to anyone
+ behind the firewall and no authentication and authorization is
+ required. The data is pushed to the printer. The printer is not
+ capable of spooling the output. The printer jams notifies the user
+ and the user chooses to cancel the job.
+
+ Client IPP Printer
+ +---------------------------------------------------------- >
+ Here is a print job
+ - job name = MyJob
+ - notify me by email when done printing
+ - print on iso-a4-white paper
+ - print on both sides of the paper
+
+
+
+Wright Experimental [Page 29]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ - return status of the printer in response
+ - document is in Postscript format
+ - here is the document to print
+
+ < ----------------------------------------------------------+
+ Print data accepted and printing started
+ - job id = #12345
+
+ +---------------------------------------------------------- >
+ - What is the status of print job #12345?
+
+ < --------------------------------------------------------- +
+ - Job #12345 accepted but printer jammed, cannot continue
+
+ +---------------------------------------------------------- >
+ - Cancel job #12345
+
+ * Printer flushes remaining data
+ < ----------------------------------------------------------+
+ Print job terminated
+ - current job state = canceled
+ - submission time = 02/12/97, 15:35
+ - printer state = jammed
+
+10.14. SUBMITTING A PRINT JOB WITH A PRINTER JAM - RECOVERED
+
+ An end-user wants to submit a print job. The print data is generated
+ dynamically and is being transmitted by a printer driver on the
+ client workstation as available. The client and printer are behind
+ the same corporate firewall. The printer is available to anyone
+ behind the firewall and no authentication and authorization is
+ required. The data is pushed to the printer. The printer is not
+ capable of spooling the output. The printer jams, notifies the user
+ and the user clears the jam and elects to continue.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ Here is a print job
+ - job name = MyJob
+ - notify me by email when done printing
+ - print on iso-a4-white paper
+ - print on both sides of the paper
+ - return status of the printer in response
+ - document is in Postscript format
+ - here is the document to print
+
+ < ----------------------------------------------------------+
+
+
+
+Wright Experimental [Page 30]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ Print data accepted and printing started
+ - job id = #12345
+
+ < --------------------------------------------------------- +
+ - Notification: printer jammed, cannot continue
+
+ * Jam is clear by human intervention, printing continues
+
+ +---------------------------------------------------------- >
+ Here is the last part of the document to print
+
+ < ----------------------------------------------------------+
+ Print job received
+ - current job state = printing
+ - submission time = 02/12/97, 15:35
+ - printer state = printing
+
+10.15. SUBMITTING A PRINT JOB WITH SERVER PULL
+
+ An end-user wants to submit a print job. The print data is in a file
+ and is publicly available. It is pulled by the printer. The client
+ and printer are behind the same corporate firewall. The printer is
+ available to anyone behind the firewall and no authentication and
+ authorization is required. The printer is capable of spooling the
+ output. Printing may start before the entire job has been pulled.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ Here is a print job
+
+ - job name = MyJob
+ - notify me by email when done printing
+ - print on iso-a4-white paper
+ - print on both sides of the paper
+ - return status of the printer in response
+ - here is a reference to the data to be printed
+
+ < ----------------------------------------------------------+
+ Print data accepted and printing started
+ - job id = #12345
+ - current state of job = spooled
+ - submission time = 02/12/97, 13:15
+ - printer state = printing
+
+ .
+ .
+ < ----------------------------------------------------------+
+
+
+
+Wright Experimental [Page 31]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ Get the file to be printed
+
+ +---------------------------------------------------------- >
+ Here it is
+
+ Note: Failure to find the file, would end the transaction
+ with an error at this point and an asynchronous
+ notification would be send to the Client.
+
+ < ----------------------------------------------------------+
+ Data received
+
+10.16. SUBMITTING A PRINT JOB WITH REFERENCED RESOURCES
+
+ An end-user wants to submit a print job. Part of the print data is
+ on a file on the user's workstation. It is pushed by the client, but
+ the print job requires some resource not included in the print file.
+ The client and printer are behind the same corporate firewall. The
+ printer is available to anyone behind the firewall and no
+ authentication and authorization is required. The printer is capable
+ of spooling the output. No errors occur.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ Here is a print job
+ - job name = MyJob
+ - notify me by email when done printing
+ - print on iso-a4-white paper
+ - print on both sides of the paper
+ - return status of the printer in response
+
+ < ----------------------------------------------------------+
+ Print job accepted and spooled
+ - job id = #12345
+ - submission time = 02/12/97, 15:35
+
+ +---------------------------------------------------------- >
+ - here is the document to print
+
+ < ----------------------------------------------------------+
+ - OK
+
+ +---------------------------------------------------------- >
+ - here is the URI to print, it is the last document.
+
+ < ----------------------------------------------------------+
+ - OK
+
+
+
+Wright Experimental [Page 32]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ < ----------------------------------------------------------+
+ Get the external resource
+
+ +---------------------------------------------------------- >
+ Here it is
+
+10.17. GETTING CAPABILITIES
+
+10.17.1. Submission Attributes
+
+ An end-user wants to get the production and scheduling attributes
+ that are supported or required when submitting jobs to this printer.
+ The client will use these attributes when forming the subsequent
+ print request.
+
+ Client IPP Printer
+ +---------------------------------------------------------- >
+ I'm going to submit a Postscript job
+ give me your job submission attributes
+
+ < ----------------------------------------------------------+
+ Postscript production attributes for this Printer are:
+ - medium-select = us-letter-white, us-legal-white
+ - default is us-letter-white
+ - copies = 1,2,3,4,5
+ - default is 1
+ - print-quality = draft, normal, high
+ - default is draft
+ - sides = 1-sided, 2-sided-long-edge
+ - default is 2-sided-long-edge
+ - Job scheduling attributes for this Printer are:
+ - job-priority = 1,2,3
+ - default = 3
+
+10.17.2. Printer Capabilities
+
+ An end-user wants to determine the resolution, marking technology,
+ and PDLs supported by the printer.
+
+ Client IPP Printer
+ +---------------------------------------------------------- >
+ Please tell me the
+ - resolution of the printer
+ - the marking technology of the printer
+ - PDLs supported
+ < ----------------------------------------------------------+
+ Printer resolution = 600 dpi
+ Marking Technology = laser
+
+
+
+Wright Experimental [Page 33]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ PDLs supported = Postscript level 2, PCL/6
+
+10.18. GETTING STATUS
+
+10.18.1. Printer State/Status
+
+ An end-user wants to determine the state or status of the printer.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ What is the state of the printer?
+
+ < ----------------------------------------------------------+
+ Printer state = out-of-paper
+
+10.18.2. Job Status
+
+ An end user wants to get the status of a job he has submitted.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ Please tell me the status of job #12345
+
+ < ----------------------------------------------------------+
+ Job #12345 is queued
+ it is number 3 in the queue
+ printer state = printing
+
+10.18.3. Status of All My Jobs
+
+ An end user wants to get a list of all of the jobs he has submitted
+ to this Printer.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ Please tell me the status of my jobs
+
+ < ----------------------------------------------------------+
+ Job #00012 is complete
+ Printed at 12:35 on 01/23/97
+
+ Job #09876 is printing
+
+ Job #12345 is queued
+ it is number 3 in the queue
+
+
+
+Wright Experimental [Page 34]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ Job #34567 is queued
+ it is number 7 in the queue
+
+10.19. ASYNCHRONOUS NOTIFICATION
+
+10.19.1. Job Completion
+
+ An end-user wants to get notification of events that affect his print
+ jobs. Print job completes without error.
+
+ Client IPP Printer
+
+ < ----------------------------------------------------------+
+ Print job #123 completed
+
+10.19.2. Job Complete with Data
+
+ An end-user wants to get notification of events that affect his print
+ jobs. Print job completes, users asked for all end of job
+ information.
+
+ Client IPP Printer
+
+ < ----------------------------------------------------------+
+ Print job #123 completed
+ - total pages printed = 15
+ - number of copies printed = 3
+ - total cost to print = $7.45
+ - pick up copies in room H-6, building 005
+
+10.19.3. Print Job Fails
+
+ An end-user wants to get notification of events that affect his print
+ jobs. Print job fails. Printer is unattended.
+
+ Client IPP Printer
+
+ < ----------------------------------------------------------+
+ Print job #123 failed
+ - total pages printed = 15
+ - number of pages submitted = 25
+ - printer-state = jammed
+
+
+
+
+
+
+
+
+
+Wright Experimental [Page 35]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+10.20. CANCEL A JOB
+
+ The end-user submits a print job and later decides to cancel it.
+
+ Client IPP Printer
+
+ +---------------------------------------------------------- >
+ < ----------------------------------------------------------+
+ Authentication.
+
+
+ +---------------------------------------------------------- >
+ Cancel job #1234
+
+ < ----------------------------------------------------------+
+ Job #1234 Canceled
+
+
+10.21. END TO END SCENARIO - WITHIN AN ENTERPRISE
+
+ An office worker prints on shared departmental printers. All printers
+ in the office are public, that is, no authentication or authorization
+ is required. Printers are protected from external access by a
+ firewall. No billing or accounting is required. Most printing is done
+ from desktop applications. A help desk is provided for printing
+ problems. Standard operating systems and applications are used.
+ Drivers are available, but are installed manually by support
+ personnel. This scenario assumes that drivers have been installed and
+ that drivers are not IPP aware, that is, they cannot communicate
+ across an IPP connection to obtain status and capabilities. IPP
+ printers appear in application pull-down menus. Printer
+ configuration data is hard wired into the driver.
+
+ End-user selects print from the application pull down menu. An IPP
+ printer is selected from the list of Printers offered
+
+ The driver puts up a dialogue with hard-wired set of options for this
+ printer. The end-user makes choices and submits job.
+
+ Client IPP Printer
+ +---------------------------------------------------------- >
+ Here is a print job
+ - job-name = memo-to-boss
+ - notify me by email when job is complete
+ - print on us-letter-white paper
+ - print 1 copy
+ - print at normal quality
+ - print on 1 side
+
+
+
+Wright Experimental [Page 36]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ - give me the state of the printer in response
+
+ The driver generates the print data and passes it to the IPP driver a
+ piece at a time as it is generated.
+
+ +---------------------------------------------------------- >
+ Here is the print data
+
+
+ < ----------------------------------------------------------+
+ Print data received, file is spooled
+ - printer state = printing
+ - time submitted = 2/12/97, 15:35
+ - current job state = spooled
+
+ Client adds this job to list of current jobs. List of jobs and state
+ of each is available on a pull-down menu on the client.
+
+ End-user selects job #1234 from list and clicks on it to see its
+ status.
+
+ +---------------------------------------------------------- >
+ Give me the state of job #1234
+ and the state of the Printer
+
+ < ----------------------------------------------------------+
+ Job #1234 state = spooled
+ - it is number 3 in the queue
+ - printer state = printing
+
+ The job completes without error
+
+ < ----------------------------------------------------------+
+ Job #1234 completed
+ 12 of 12 pages printed
+
+10.22. END TO END SCENARIO - ACROSS ENTERPRISES
+
+ An office worker in Company A needs to print an office document on a
+ "public" printer at Company B, a business partner. Both companies
+ have corporate firewalls so the print request must flow out of A's
+ firewall and into B's firewall. The office worker can look at public
+ printers in Company B's directory service. The document is generated
+ by a desktop application. Since the printer is "public" no
+ authentication or authorization is required. A driver is downloaded.
+ The driver is IPP aware, that is, it can communicate dynamically
+ through the IPP protocol layer to obtain information about the
+ printer.
+
+
+
+Wright Experimental [Page 37]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ Client Company B's Directory Service
+
+ End user connects to B's Directory service
+
+ +---------------------------------------------------------- >
+ Find a Printer with these characteristics
+ - public (no authorization or authentication required)
+ - is in Lexington, building 004
+ - prints black and white
+
+ < ----------------------------------------------------------+
+ Printer "Public-A"
+ - http://www.lexmark.com/pubprinter/a
+
+ Printer "Public-B"
+ - http://www.lexmark.com/pubprinter/b
+
+ End user selects Public-A
+
+ Client Public-A
+
+ +---------------------------------------------------------- >
+ Where can I find a driver for you?
+
+ < ----------------------------------------------------------+
+ Drivers at http://www.lexmark.com/pubprinters/a/os245
+
+ End user gets driver and installs it on his PC.
+
+ End-user selects print from the application pull down menu. "Public-
+ A" is selected from the list of Printers offered
+
+ +---------------------------------------------------------- >
+ I'm going to submit a print job
+ give me your job submission attributes
+
+ < ----------------------------------------------------------+
+
+ Production attributes for this Printer are:
+ - medium-select = us-letter-white, us-legal-white
+ - default is us-letter-white
+ - copies = 1,2,3,4,5
+ - default is 1
+ - print-quality = draft, normal, high
+ - default is draft
+ - sides = 1-sided, 2-sided-long-edge
+ - default is 2-sided-long-edge
+
+
+
+
+Wright Experimental [Page 38]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ Job scheduling attributes for this Printer are:
+ - job-priority = 1,2,3
+ default = 3
+
+ Driver puts up dialogue with available options and fills in the
+ defaults.
+
+ End-user makes choices and submits job
+
+ +---------------------------------------------------------- >
+ Here is a print job
+ - job-name = memo-to-Don-Wright
+ - notify me by email when job is complete
+ - print on us-letter-white paper
+ - print 1 copy
+ - print at normal quality
+ - print on 1 side
+ - give me the state of the printer in response
+
+
+ The driver generates the print data and passes it to the IPP driver a
+ piece at a time.
+
+ +---------------------------------------------------------- >
+ Here is the print data
+
+ < ----------------------------------------------------------+
+ Print data received, and spooling started
+ print job id = #1234
+
+ Print data received, file is spooled
+
+ - printer state = printing
+ - time submitted = 2/12/97, 15:35
+ - current job state = spooled
+
+ Client adds this job to list of current jobs. List of jobs and state
+ of each is available on a pull-down menu on the client.
+
+ End-user selects job #1234 from list and clicks on it to see its
+ status.
+
+ +---------------------------------------------------------- >
+ Give me the state of job #1234
+ and the state of the Printer
+
+ < ----------------------------------------------------------+
+ Job #1234 state = spooled
+
+
+
+Wright Experimental [Page 39]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ - it is number 3 in the queue
+ - printer state = printing
+
+ * The job completes without error
+ < ----------------------------------------------------------+
+ Job #1234 completed
+ 12 of 12 pages printed
+
+10.23. END TO END SCENARIO - ON THE INTERNET
+
+ An executive in her hotel room is finishing an important presentation
+ on her laptop computer. She connects to a local print shop through
+ the web to get a copy of her charts printed for tomorrow's
+ presentation. She must find a print shop that is convenient and can
+ print color transparencies. She must download and temporarily install
+ a driver in order to generate the PDL required by the print shop.
+ Mutual authentication is required by the print shop and payment must
+ be made in advance. The job is encrypted on the wire to prevent
+ eavesdropping.
+
+ End-user completes presentation. She goes to the web and connects to
+ the SirZippy home page.
+
+ Client SirZippy Directory Service
+ +---------------------------------------------------------- >
+
+ Find me a printer with these characteristics
+ - Near Market Street in San Jose
+ - Prints color transparencies
+ - drivers can be downloaded
+ - supports privacy (encryption)
+ -
+
+ Available Printers matching these characteristics are looked up in the
+ Directory Service
+
+ < ----------------------------------------------------------+
+
+ Printer "Color-A"
+ - located at 123 First Street in San Jose
+ - URI is http://www.SirZippy.com/FirstStreet/Color-A
+ - prints color transparencies
+ - 600 dpi laser
+ - driver ABC-Postscript-V1.3 available at this URI
+ - cost = $.75 per page
+ - authentication required to use printer
+ - payment required prior to printing
+
+
+
+
+Wright Experimental [Page 40]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ Printer "Color-B"
+ - located at 67 San Carlos Street, San Jose
+ - URI is http://www.SirZippy.com/SanCarlos/Color-B
+ - prints color transparencies
+ - 1200 dpi laser
+ - driver XYZ-PostScript-V4.3 available at this URI
+ - cost = $1.25 per page
+ - authentication required to use printer
+ - payment required prior to printing
+ - more information at this URI
+
+ The user decides to use the first printer because it is closer. She
+ connects to the URI given to get a driver.
+
+ Client Driver URI
+
+ +---------------------------------------------------------- >
+ I need a driver for "Color-A"
+
+
+ < ----------------------------------------------------------+
+ Driver installer is at http://www.xerox.com/prtdrvrs
+
+ Driver is installed
+
+ User connects to
+ "Color-A"
+
+ Client IPP Printer "Color-A"
+
+ +---------------------------------------------------------- >
+ < ----------------------------------------------------------+
+ Mutual authentication and exchange of secret keys
+
+ +---------------------------------------------------------- >
+ I'm going to submit a print job
+ give me your job submission attributes
+
+ < ----------------------------------------------------------+
+ Production attributes for this Printer are:
+ - medium-select = us-letter-white, us-legal-white
+ - default is us-letter-white
+ - copies = 1,2,3,4,5
+ - default is 1
+ - print-quality = draft, normal, high
+ - default is draft
+ - sides = 1-sided, 2-sided-long-edge
+ - default is 2-sided-long-edge
+
+
+
+Wright Experimental [Page 41]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+ Job scheduling attributes for this Printer are:
+ - job-priority = 1,2,3
+ default = 3
+
+ Driver puts up dialogue with available options and fills in the
+ defaults.
+
+ End-user makes choices and submits job
+
+ +---------------------------------------------------------- >
+ Here is a print job
+
+ - job-name = presentation
+ - notify me by email when job is complete
+ - print on us-letter-transparency
+ - print 1 copy
+ - print at high quality
+ - print by 9:00 am tomorrow morning
+ - give me the state of the printer in response
+
+ The driver generates the print data and passes it to the IPP driver a
+ piece at a time.
+
+ +---------------------------------------------------------- >
+ Here is the print data
+
+ < ---------------------------------------------------------+
+ Print data received, and spooling started
+ print job id = #1234
+
+ Print data received, file is spooled
+ - printer state = printing
+ - time submitted = 2/12/97, 15:35
+ - current job state = held, waiting for payment
+
+ +---------------------------------------------------------- >
+ < ----------------------------------------------------------+
+ Payment transaction
+
+ < ----------------------------------------------------------+
+ Job is scheduled to print, pick up after 9:00am tomorrow
+ Thank you for using SirZippy
+
+
+
+
+
+
+
+
+
+Wright Experimental [Page 42]
+
+RFC 2567 Internet Printing Design Goals April 1999
+
+
+11. Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Wright Experimental [Page 43]
+
diff --git a/standards/rfc2568.txt b/standards/rfc2568.txt
new file mode 100644
index 000000000..2d3ae4905
--- /dev/null
+++ b/standards/rfc2568.txt
@@ -0,0 +1,563 @@
+
+
+
+
+
+
+Network Working Group S. Zilles
+Request for Comments: 2568 Adobe Systems Inc.
+Category: Experimental April 1999
+
+
+ Rationale for the Structure of the Model and Protocol
+ for the Internet Printing Protocol
+
+Status of this Memo
+
+ This memo defines an Experimental Protocol for the Internet
+ community. It does not specify an Internet standard of any kind.
+ Discussion and suggestions for improvement are requested.
+ Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+IESG Note
+
+ This document defines an Experimental protocol for the Internet
+ community. The IESG expects that a revised version of this protocol
+ will be published as Proposed Standard protocol. The Proposed
+ Standard, when published, is expected to change from the protocol
+ defined in this memo. In particular, it is expected that the
+ standards-track version of the protocol will incorporate strong
+ authentication and privacy features, and that an "ipp:" URL type will
+ be defined which supports those security measures. Other changes to
+ the protocol are also possible. Implementors are warned that future
+ versions of this protocol may not interoperate with the version of
+ IPP defined in this document, or if they do interoperate, that some
+ protocol features may not be available.
+
+ The IESG encourages experimentation with this protocol, especially in
+ combination with Transport Layer Security (TLS) [RFC2246], to help
+ determine how TLS may effectively be used as a security layer for
+ IPP.
+
+ABSTRACT
+
+ This document is one of a set of documents, which together describe
+ all aspects of a new Internet Printing Protocol (IPP). IPP is an
+ application level protocol that can be used for distributed printing
+ using Internet tools and technologies. This document describes IPP
+ from a high level view, defines a roadmap for the various documents
+ that form the suite of IPP specifications, and gives background and
+ rationale for the IETF working group's major decisions.
+
+
+
+Zilles Experimental [Page 1]
+
+RFC 2568 Rationale for IPP April 1999
+
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol (this document)
+ Internet Printing Protocol/1.0: Model and Semantics [RFC2566]
+ Internet Printing Protocol/1.0: Encoding and Transport [RFC2565]
+ Internet Printing Protocol/1.0: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ The "Design Goals for an Internet Printing Protocol" document takes a
+ broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. The Design Goals document calls out a subset of end
+ user requirements that are satisfied in IPP/1.0. Operator and
+ administrator requirements are out of scope for version 1.0.
+
+ The "Internet Printing Protocol/1.0: Model and Semantics" document
+ describes a simplified model consisting of abstract objects, their
+ attributes, and their operations that is independent of encoding and
+ transport. The model consists of a Printer and a Job object. The
+ Job optionally supports multiple documents. This document also
+ addresses security, internationalization, and directory issues.
+
+ The "Internet Printing Protocol/1.0: Encoding and Transport" document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1. It defines the encoding rules
+ for a new Internet media type called "application/ipp".
+
+ The "Internet Printing Protocol/1.0: Implementer's Guide" document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.0 and some of
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+ The "Mapping between LPD and IPP Protocols" document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+1. ARCHITECTURAL OVERVIEW
+
+ The Internet Printing Protocol (IPP) is an application level protocol
+ that can be used for distributed printing on the Internet. This
+ protocol defines interactions between a client and a server. The
+
+
+
+Zilles Experimental [Page 2]
+
+RFC 2568 Rationale for IPP April 1999
+
+
+ protocol allows a client to inquire about capabilities of a printer,
+ to submit print jobs and to inquire about and cancel print jobs. The
+ server for these requests is the Printer; the Printer is an
+ abstraction of a generic document output device and/or a print
+ service provider. Thus, the Printer could be a real printing device,
+ such as a computer printer or fax output device, or it could be a
+ service that interfaced with output devices.
+
+ The protocol is heavily influenced by the printing model introduced
+ in the Document Printing Application (DPA) [ISO10175] standard.
+ Although DPA specifies both end user and administrative features, IPP
+ version 1.0 (IPP/1.0) focuses only on end user functionality.
+
+ The architecture for IPP defines (in the Model and Semantics document
+ [RFC2566]) an abstract Model for the data which is used to control
+ the printing process and to provide information about the process and
+ the capabilities of the Printer. This abstract Model is hierarchical
+ in nature and reflects the structure of the Printer and the Jobs that
+ may be being processed by the Printer.
+
+ The Internet provides a channel between the client and the
+ server/Printer. Use of this channel requires flattening and
+ sequencing the hierarchical Model data. Therefore, the IPP also
+ defines (in the Encoding and Transport document [RFC2565]) an
+ encoding of the data in the model for transfer between the client and
+ server. This transfer of data may be either a request or the
+ response to a request.
+
+ Finally, the IPP defines (in the Encoding and Transport document
+ [RFC2565]) a protocol for transferring the encoded request and
+ response data between the client and the server/Printer.
+
+ An example of a typical interaction would be a request from the
+ client to create a print job. The client would assemble the Model
+ data to be associated with that job, such as the name of the job, the
+ media to use, the number of pages to place on each media instance,
+ etc. This data would then be encoded according to the Protocol and
+ would be transmitted according to the Protocol. The server/Printer
+ would receive the encoded Model data, decode it into a form
+ understood by the server/Printer and, based on that data, do one of
+ two things: (1) accept the job or (2) reject the job. In either case,
+ the server must construct a response in terms of the Model data,
+ encode that response according to the Protocol and transmit that
+ encoded Model data as the response to the request using the Protocol.
+
+ Another part of the IPP architecture is the Directory Schema
+ described in the model document. The role of a Directory Schema is to
+ provide a standard set of attributes which might be used to query a
+
+
+
+Zilles Experimental [Page 3]
+
+RFC 2568 Rationale for IPP April 1999
+
+
+ directory service for the URI of a Printer that is likely to meet the
+ needs of the client. The IPP architecture also addresses security
+ issues such as control of access to server/Printers and secure
+ transmissions of requests, response and the data to be printed.
+
+2. THE PRINTER
+
+ Because the (abstract) server/Printer encompasses a wide range of
+ implementations, it is necessary to make some assumptions about a
+ minimal implementation. The most likely minimal implementation is one
+ that is embedded in an output device running a specialized real time
+ operating system and with limited processing, memory and storage
+ capabilities. This printer will be connected to the Internet and will
+ have at least a TCP/IP capability with (likely) SNMP [RFC1905,
+ RFC1906] support for the Internet connection. In addition, it is
+ likely the the Printer will be an HTML/HTTP server to allow direct
+ user access to information about the printer.
+
+3. RATIONALE FOR THE MODEL
+
+ The Model [RFC2566] is defined independently of any encoding of the
+ Model data both to support the likely uses of IPP and to be robust
+ with respect to the possibility of alternate encoding.
+
+ It is expected that a client or server/Printer would represent the
+ Model data in some data structure within the applications/servers
+ that support IPP. Therefore, the Model was designed to make that
+ representation straightforward. Typically a parser or formatter would
+ be used to convert from or to the encoded data format. Once in an
+ internal form suitable to a product, the data can be manipulated by
+ the product. For example, the data sent with a Print Job can be used
+ to control the processing of that Print Job.
+
+ The semantics of IPP are attached to the (abstract) Model.
+ Therefore, the application/server is not dependent on the encoding of
+ the Model data, and it is possible to consider alternative mechanisms
+ and formats by which the data could be transmitted from a client to a
+ server; for example, a server could have a direct, client-less GUI
+ interface that might be used to accept some kinds of Print Jobs. This
+ independence would also allow a different encoding and/or
+ transmission mechanism to be used if the ones adopted here were shown
+ to be overly limiting in the future. Such a change could be migrated
+ into new products as an alternate protocol stack/parser for the Model
+ data.
+
+
+
+
+
+
+
+Zilles Experimental [Page 4]
+
+RFC 2568 Rationale for IPP April 1999
+
+
+ Having an abstract Model also allows the Model data to be aligned
+ with the (abstract) model used in the Printer [RFC1759], Job and Host
+ Resources MIBs. This provides consistency in interpretation of the
+ data obtained independently of how the data is accessed, whether via
+ IPP or via SNMP [RFC1905, RFC1906] and the Printer/Job MIBs.
+
+ There is one aspect of the Model that deserves some extra
+ explanation. There are two ways for identifying a Job object: (a)
+ with a Job URI and (b) using a combination of the Printer URI and a
+ Job ID (a 32 bit positive integer). Allowing Job objects to have URIs
+ allows for flexibility and scalability. For example a job could be
+ moved from a printer with a large backlog to one with a smaller load
+ and the job identification, the Job object URI, need not change.
+ However, many existing printing systems have local models or
+ interface constraints that force Job objects to be identified using
+ only a 32-bit positive integer rather than a URI. This numeric Job
+ ID is only unique within the context of the Printer object to which
+ the create request was originally submitted. In order to allow both
+ types of client access to Jobs (either by Job URI or by numeric Job
+ ID), when the Printer object successfully processes a create request
+ and creates a new Job, the Printer object generates both a Job URI
+ and a Job ID for the new Job object. This requirement allows all
+ clients to access Printer objects and Job objects independent of any
+ local constraints imposed on the client implementation.
+
+4. RATIONALE FOR THE PROTOCOL
+
+ There are two parts to the Protocol: (1) the encoding of the Model
+ data and (2) the mechanism for transmitting the model data between
+ client and server.
+
+4.1 The Encoding
+
+ To make it simpler to develop embedded printers, a very simple binary
+ encoding has been chosen. This encoding is adequate to represent the
+ kinds of data that occur within the Model. It has a simple structure
+ consisting of sequences of attributes. Each attribute has a name,
+ prefixed by a name length, and a value. The names are strings
+ constrained to characters from a subset of ASCII. The values are
+ either scalars or a sequence of scalars. Each scalar value has a
+ length specification and a value tag which indicates the type of the
+ value. The value type has two parts: a major class part, such as
+ integer or string, and a minor class part which distinguishes the
+ usage of the major class, such as dateTime string. Tagging of the
+ values with type information allows for introducing new value types
+ at some future time.
+
+
+
+
+
+Zilles Experimental [Page 5]
+
+RFC 2568 Rationale for IPP April 1999
+
+
+ A fully encoded request/response has a version number, an operation
+ (for a request) or a status and optionally a status message (for a
+ response), associated parameters and attributes which are encoded
+ Model data and, optionally (for a request), print data following the
+ Model data.
+
+4.2 The Transmission Mechanism
+
+ The chosen mechanism for transmitting the encoded Model data is HTTP
+ 1.1 Post (and associated response). No modifications to HTTP 1.1 are
+ proposed or required. The sole role of the Transmission Mechanism is
+ to provide a transfer of encoded Model data from/to the client
+ to/from the server. This could be done using any data delivery
+ mechanism. The key reasons why HTTP 1.1 Post is used are given below.
+ The most important of these is the first. With perhaps this
+ exception, these reasons could be satisfied by other mechanisms.
+ There is no claim that this list uniquely determines a choice of
+ mechanism.
+
+ 1. HTTP 1.0 is already widely deployed and, based on the recent
+ evidence, HTTP 1.1 is being widely deployed as the manufacturers
+ release new products. The performance benefits of HTTP 1.1 have
+ been shown and manufactures are reacting positively.
+
+ Wide deployment has meant that many of the problems of making a
+ protocol work in a wide range of environments from local net to
+ Intranet to Internet have been solved and will stay solved with
+ HTTP 1.1 deployment.
+
+ 2. HTTP 1.1 solves most of the problems that might have required a
+ new protocol to be developed. HTTP 1.1 allows persistent
+ connections that make a multi-message protocol be more efficient;
+ for example it is practical to have separate Create-Job and Send-
+ Document messages. Chunking allows the transmission of large print
+ files without having to pre-scan the file to determine the file
+ length. The accept headers allow the client's protocol and
+ localization desires to be transmitted with the IPP operations and
+ data. If the Model were to provide for the redirection of Job
+ requests, such as Cancel-Job, when a Job is moved, the HTTP
+ redirect response allows a client to be informed when a Job he is
+ interested in is moved to another server/Printer for any reason.
+
+ 3. Most network Printers will be implementing HTTP servers for
+ reasons other than IPP. These network attached Printers want to
+ provide information on how to use the printer, its current state,
+ HELP information, etc. in HTML. This requires having an HTTP
+ server which would be available to do IPP functions as well.
+
+
+
+
+Zilles Experimental [Page 6]
+
+RFC 2568 Rationale for IPP April 1999
+
+
+ 4. Most of the complexity of HTTP 1.1 is concerned with the
+ implementation of HTTP proxies and not the implementation of HTTP
+ clients and/or servers. Work is proceeding in the HTTP Working
+ Group to help identify what must be done by a server. As the
+ Encoding and Transport document shows, that is not very much.
+
+ 5. HTTP implementations provide support for handling URLs that
+ would have to be provided if a new protocol were defined.
+
+ 6. An HTTP based solution fits well with the Internet security
+ mechanisms that are currently deployed or being deployed. HTTP
+ will run over SSL3. The digest access authentication mechanism of
+ HTTP 1.1 provides an adequate level of access control. These
+ solutions are deployed and in practical use; a new solution would
+ require extensive use to have the same degree of confidence in its
+ security. Note: SSL3 is not on the IETF standards track.
+
+ 7. HTTP provides an extensibility model that a new protocol would
+ have to develop independently. In particular, the headers,
+ intent-types (via Internet Media Types) and error codes have wide
+ acceptance and a useful set of definitions and methods for
+ extension.
+
+ 8. Although not strictly a reason why IPP should use HTTP as the
+ transmission protocol, it is extremely helpful that there are many
+ prototyping tools that work with HTTP and that CGI scripts can be
+ used to test and debug parts of the protocol.
+
+ 9. Finally, the POST method was chosen to carry the print data
+ because its usage for data transmission has been established, it
+ works and the results are available via CGI scripts or servlets.
+ Creating a new method would have better identified the intended
+ use of the POSTed data, but a new method would be more difficult
+ to deploy. Assigning a new default port for IPP provided the
+ necessary identification with minimal impact to installed
+ infrastructure, so was chosen instead.
+
+5. RATIONALE FOR THE DIRECTORY SCHEMA
+
+ Successful use of IPP depends on the client finding a suitable IPP
+ enabled Printer to which to send a IPP requests, such as print a
+ job. This task is simplified if there is a Directory Service which
+ can be queried for a suitable Printer. The purpose of the
+ Directory Schema is to have a standard description of Printer
+ attributes that can be associated the URI for the printer. These
+ attributes are a subset of the Model attributes and can be encoded
+ in the appropriate query syntax for the Directory Service being
+ used by the client.
+
+
+
+Zilles Experimental [Page 7]
+
+RFC 2568 Rationale for IPP April 1999
+
+
+6. SECURITY CONSIDERATIONS - RATIONALE FOR SECURITY
+
+ Security is an area of active work on the Internet. Complete
+ solutions to a wide range of security concerns are not yet
+ available. Therefore, in the design of IPP, the focus has been on
+ identifying a set of security protocols/features that are
+ implemented (or currently implementable) and solve real problems
+ with distributed printing. The two areas that seem appropriate to
+ support are: (1) authorization to use a Printer and (2) secure
+ interaction with a printer. The chosen mechanisms are the digest
+ authentication mechanism of HTTP 1.1 and SSL3 [SSL] secure
+ communication mechanism.
+
+7. REFERENCES
+
+ [ipp-iig] Hastings, T. and C. Manros, "Internet Printing
+ Protocol/1.0:Implementer's Guide", Work in Progress.
+
+ [RFC2569] Herriot, R., Hastings, T., Jacobs, N. and J. Martin,
+ "Mapping between LPD and IPP Protocols", RFC 2569, April
+ 1999.
+
+ [RFC2566] deBry, R., Isaacson, S., Hastings, T., Herriot, R. and P.
+ Powell, "Internet Printing Protocol/1.0: Model and
+ Semantics", RFC 2566, April 1999.
+
+ [RFC2565] Herriot, R., Butler, S., Moore, P. and R. Tuner, "Internet
+ Printing Protocol/1.0: Encoding and Transport", RFC 2565,
+ April 1999.
+
+ [RFC2567] Wright, D., "Design Goals for an Internet Printing
+ Protocol", RFC 2567, April 1999.
+
+ [ISO10175] ISO/IEC 10175 "Document Printing Application (DPA)", June
+ 1996.
+
+ [RFC1759] Smith, R., Wright, F., Hastings, T., Zilles, S. and J.
+ Gyllenskog, "Printer MIB", RFC 1759, March 1995.
+
+ [RFC1905] Case, J., McCloghrie, K., Rose, M. and S. Waldbusser,
+ "Protocol Operations for Version 2 of the Simple Network
+ Management Protocol (SNMPv2)", RFC 1905, January 1996.
+
+ [RFC1906] Case, J., McCloghrie, K., Rose, M. and S. Waldbusser,
+ "Transport Mappings for Version 2 of the Simple Network
+ Management Protocol (SNMPv2)", RFC 1906, January 1996.
+
+
+
+
+
+Zilles Experimental [Page 8]
+
+RFC 2568 Rationale for IPP April 1999
+
+
+ [SSL] Netscape, The SSL Protocol, Version 3, (Text version
+ 3.02), November 1996.
+
+8. AUTHOR'S ADDRESS
+
+ Stephen Zilles
+ Adobe Systems Incorporated
+ 345 Park Avenue
+ MailStop W14
+ San Jose, CA 95110-2704
+
+ Phone: +1 408 536-4766
+ Fax: +1 408 537-4042
+ EMail: szilles@adobe.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Zilles Experimental [Page 9]
+
+RFC 2568 Rationale for IPP April 1999
+
+
+9. Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Zilles Experimental [Page 10]
+
diff --git a/standards/rfc2569.txt b/standards/rfc2569.txt
new file mode 100644
index 000000000..767857c34
--- /dev/null
+++ b/standards/rfc2569.txt
@@ -0,0 +1,1571 @@
+
+
+
+
+
+
+Network Working Group R. Herriot
+Request For Comments: 2569 Xerox Corporation
+Category: Experimental N. Jacobs
+ Sun Microsystems, Inc.
+ T. Hastings
+ Xerox Corporation
+ J. Martin
+ Underscore, Inc.
+ April 1999
+
+
+ Mapping between LPD and IPP Protocols
+
+Status of this Memo
+
+ This memo defines an Experimental Protocol for the Internet
+ community. It does not specify an Internet standard of any kind.
+ Discussion and suggestions for improvement are requested.
+ Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+IESG Note
+
+ This document defines an Experimental protocol for the Internet
+ community. The IESG expects that a revised version of this protocol
+ will be published as Proposed Standard protocol. The Proposed
+ Standard, when published, is expected to change from the protocol
+ defined in this memo. In particular, it is expected that the
+ standards-track version of the protocol will incorporate strong
+ authentication and privacy features, and that an "ipp:" URL type will
+ be defined which supports those security measures. Other changes to
+ the protocol are also possible. Implementors are warned that future
+ versions of this protocol may not interoperate with the version of
+ IPP defined in this document, or if they do interoperate, that some
+ protocol features may not be available.
+
+ The IESG encourages experimentation with this protocol, especially in
+ combination with Transport Layer Security (TLS) [RFC 2246], to help
+ determine how TLS may effectively be used as a security layer for
+ IPP.
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 1]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+Abstract
+
+ This document is one of a set of documents, which together describe
+ all aspects of a new Internet Printing Protocol (IPP). IPP is an
+ application level protocol that can be used for distributed printing
+ using Internet tools and technologies. This document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon). This document describes the mapping between (1) the commands
+ and operands of the 'Line Printer Daemon (LPD) Protocol' specified in
+ RFC 1179 and (2) the operations, operation attributes and job
+ template attributes of the Internet Printing Protocol/1.0 (IPP). One
+ of the purposes of this document is to compare the functionality of
+ the two protocols. Another purpose is to facilitate implementation
+ of gateways between LPD and IPP.
+
+ WARNING: RFC 1179 was not on the IETF standards track. While RFC
+ 1179 was intended to record existing practice, it fell short in some
+ areas. However, this specification maps between (1) the actual
+ current practice of RFC 1179 and (2) IPP. This document does not
+ attempt to map the numerous divergent extensions to the LPD protocol
+ that have been made by many implementers.
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.0: Model and Semantics [RFC2566]
+ Internet Printing Protocol/1.0: Encoding and Transport [RFC2565]
+ Internet Printing Protocol/1.0: Implementors Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols (this document)
+
+ The document, "Design Goals for an Internet Printing Protocol", takes
+ a broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. Operator and administrator requirements are
+ out of scope for version 1.0.
+
+ The document, "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specifications, and gives background and rationale for the
+ IETF working group's major decisions.
+
+
+
+
+
+Herriot, et al. Experimental [Page 2]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ The document, "Internet Printing Protocol/1.0: Model and Semantics",
+ describes a simplified model with abstract objects, their attributes,
+ and their operations. It introduces a Printer and a Job object. The
+ Job object supports multiple documents per Job. It also addresses
+ security, internationalization, and directory issues.
+
+ The document, "Internet Printing Protocol/1.0: Encoding and
+ Transport", is a formal mapping of the abstract operations and
+ attributes defined in the model document onto HTTP/1.1. It defines
+ the encoding rules for a new Internet media type called '
+ application/ipp'.
+
+ This document "Internet Printing Protocol/1.0: Implementer's Guide",
+ gives advice to implementers of IPP clients and IPP objects.
+
+TABLE OF CONTENTS
+
+ 1. Introduction.....................................................4
+ 2. Terminology......................................................5
+ 3. Mapping from LPD Commands to IPP Operations......................5
+ 3.1 Print any waiting jobs..........................................6
+ 3.2 Receive a printer job...........................................6
+ 3.2.1 Abort job.....................................................7
+ 3.2.2 Receive control file..........................................7
+ 3.2.3 Receive data file.............................................8
+ 3.3 Send queue state (short)........................................8
+ 3.4 Send queue state (long)........................................10
+ 3.5 Remove jobs....................................................12
+ 4. Mapping of LPD Control File Lines to IPP Operation and Job
+ Template Attributes.............................................13
+ 4.1 Required Job Functions.........................................13
+ 4.2 Optional Job Functions.........................................14
+ 4.3 Required Document Functions....................................14
+ 4.4 Recommended Document Functions.................................16
+ 5. Mapping from IPP operations to LPD commands.....................16
+ 5.1 Print-Job......................................................16
+ 5.2 Print-URI......................................................18
+ 5.3 Validate-Job...................................................18
+ 5.4 Create-Job.....................................................18
+ 5.5 Send-Document..................................................18
+ 5.6 Send-URI.......................................................18
+ 5.7 Cancel-Job.....................................................18
+ 5.8 Get-Printer-Attributes.........................................19
+ 5.9 Get-Job-Attributes.............................................19
+ 5.10 Get-Jobs......................................................20
+ 6. Mapping of IPP Attributes to LPD Control File Lines.............20
+ 6.1 Required Job Functions.........................................21
+ 6.2 Optional Job Functions.........................................21
+
+
+
+Herriot, et al. Experimental [Page 3]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ 6.3 Required Document Functions....................................22
+ 7. Security Considerations.........................................23
+ 8. References......................................................23
+ 9. Authors' Addresses..............................................24
+ 10.Appendix A: ABNF Syntax for response of Send-queue-state (short)25
+ 11.Appendix B: ABNF Syntax for response of Send-queue-state (long) 26
+ 12.Appendix C: Unsupported LPD functions...........................27
+ 13.Full Copyright Statement........................................28
+
+1. Introduction
+
+ The reader of this specification is expected to be familiar with the
+ IPP Model and Semantics specification [RFC2566], the IPP Encoding and
+ Transport [RF2565], and the Line Printer Daemon (LPD) protocol
+ specification [RFC1179] as described in RFC 1179.
+
+ RFC 1179 was written in 1990 in an attempt to document existing LPD
+ protocol implementations. Since then, a number of undocumented
+ extensions have been made by vendors to support functionality
+ specific to their printing solutions. All of these extensions
+ consist of additional control file commands. This document does not
+ address any of these vendor extensions. Rather it addresses existing
+ practice within the context of the features described by RFC 1179.
+ Deviations of existing practice from RFC 1179 are so indicated.
+
+ Other LPD control file commands in RFC 1179 are obsolete. They are
+ intended to work on "text" only formats and are inappropriate for
+ many contemporary document formats that completely specify each page.
+ This document does not address the support of these obsolete
+ features.
+
+ In the area of document formats, also known as page description
+ languages (PDL), RFC 1179 defines a fixed set with no capability for
+ extension. Consequently, some new PDL's are not supported, and some
+ of those that are supported are sufficiently unimportant now that
+ they have not been registered for use with the Printer MIB [RFC1759]
+ and IPP [RFC2566] [RFC2565], though they could be registered if
+ desired. See the Printer MIB specification [RFC1759] and/or the IPP
+ Model specification [RFC2566] for instructions for registration of
+ document-formats with IANA. IANA lists the registered document-
+ formats as "printer languages".
+
+ This document addresses the protocol mapping for both directions:
+ mapping of the LPD protocol to the IPP protocol and mapping of the
+ IPP protocol to the LPD protocol. The former is called the "LPD-to-
+ IPP mapper" and the latter is called the "IPP-to-LPD mapper".
+
+
+
+
+
+Herriot, et al. Experimental [Page 4]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ This document is an informational document that is not on the
+ standards track. It is intended to help implementers of gateways
+ between IPP and LPD. It also provides an example, which gives
+ additional insight into IPP.
+
+2. Terminology
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in RFC 2119 [RFC2119].
+
+ RFC 1179 uses the word "command" in two contexts: for over-the-wire
+ operations and for command file functions. This document SHALL use
+ the word "command" for the former and the phrase "functions" for the
+ latter. The syntax of the LPD commands is given using ABNF
+ [RFC2234].
+
+ The following tokens are used in order to make the syntax more
+ readable:
+
+ LF stands for %x0A (linefeed)
+ SP stands for %x20. (space)
+ DIGIT stands for %x30-39 ("0" to "9")
+
+3. Mapping from LPD Commands to IPP Operations
+
+ This section describes the mapping from LPD commands to IPP
+ operations. Each of the following sub-sections appear as sub-
+ sections of section 5 of RFC 1179.
+
+ The following table summarizes the IPP operation that the mapper uses
+ when it receives an LPD command. Each section below gives more
+ detail:
+
+ LPD command IPP operation
+
+
+ print-any-waiting-jobs ignore
+ receive-a-printer-job Print-Job or Create-Job/Send-Document
+ send queue state Get-Printer-Attributes and Get-Jobs
+ (short or long)
+ remove-jobs Cancel-Job
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 5]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+3.1 Print any waiting jobs
+
+ Command syntax:
+
+ print-waiting-jobs = %x01 printer-name LF
+
+ This command causes the LPD daemon check its queue and print any
+ waiting jobs. An IPP printer handles waiting jobs without such a
+ nudge.
+
+ If the mapper receives this LPD command, it SHALL ignore it and send
+ no IPP operation.
+
+3.2 Receive a printer job
+
+ Command syntax:
+
+ receive-job = %x02 printer-name LF
+
+ The control file and data files mentioned in the following paragraphs
+ are received via LPD sub-commands that follow this command. Their
+ mapping to IPP commands and attributes is described later in this
+ section.
+
+ The mapper maps the 'Receive a printer job' command to either:
+
+ - the Print-Job operation which includes a single data file or
+ - the Create-Job operation followed by one Send-Document operation
+ for each data file.
+
+ If the IPP printer supports both Create-Job and Send-Document, and if
+ a job consists of:
+
+ - a single data file, the mapper SHOULD use the Print-Job
+ operation, but MAY use the Create-Job and Send-Document
+ operations.
+ - more than one data file, the mapper SHALL use Create-Job
+ followed by one Send-Document for each received LPD data file.
+
+ If the IPP printer does not support both Create-Job and Send-
+ Document, and if a job consists of:
+
+ - a single data file, the mapper SHALL use the PrintJob
+ operation.
+ - more than one data file, the mapper SHALL submit each received
+ LPD data file as a separate Print-Job operation (thereby
+ converting a single LPD job into multiple IPP jobs).
+
+
+
+
+Herriot, et al. Experimental [Page 6]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ If the mapper uses Create-Job and Send-Document, it MUST send the
+ Create-Job operation before it sends any Send-Document operations
+ whether the LPD control file, which supplies attributes for Create-
+ Job, arrives before or after all LPD data files.
+
+ NOTE: This specification does not specify how the mapper maps: the
+ LPD Printer-name operand to the IPP "printer-uri" operation
+ attribute.
+
+ The following three sub-sections gives further details about the
+ mapping from LPD receive-a-printer-job sub-commands. Each of the
+ following subsections appear as sub-sections of section 6 of RFC
+ 1179.
+
+3.2.1 Abort job
+
+ Sub-command syntax:
+
+ abort-job = %x1 LF
+
+ This sub-command of receive-a-printer-job is intended to abort any
+ job transfer in process.
+
+ If the mapper receives this sub-command, it SHALL cancel the job that
+ it is in the process of transmitting.
+
+ If the mapper is in the process of sending a Print-Job or Create-Job
+ operation, it terminates the job either by closing the connection, or
+ performing the Cancel-Job operation with the job-uri that it received
+ from the Print-Job or Create-Job operation.
+
+ NOTE: This sub-command is implied if at any time the connection
+ between the LPD client and server is terminated before an entire
+ print job has been transferred via an LPD Receive-a-printer-job
+ request.
+
+3.2.2 Receive control file
+
+ Sub-command syntax:
+
+ receive-control-file = %x2 number-of-bytes SP name-of-control-file LF
+ number-of-bytes = 1*DIGIT
+ name-of-control-file = "cfA" job-number client-host-name
+ ; e.g. "cfA123woden"
+ job-number = 3DIGIT
+ client-host-name = <a host name>
+
+
+
+
+
+Herriot, et al. Experimental [Page 7]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ This sub-command is roughly equivalent to the IPP Create-Job
+ operation.
+
+ The mapper SHALL use the contents of the received LPD control file to
+ create IPP operation attribute and job template attribute values to
+ transmit with the Print-Job or Create-Job operation.
+
+3.2.3 Receive data file
+
+Sub-command syntax: %x3 number-of-bytes-in-data-file Name-of-data-file
+
+ receive-data-file = %x03 number-of-bytes SP name-of-data-file LF
+ number-of-bytes = 1*DIGIT
+ name-of-data-file = "df" letter job-number client-host-name
+ ; e.g. "dfA123woden for the first file
+ letter = %x41-5A / %x61-7A ; "A" to "Z", "a" to "z"
+ ; first file is "A",
+ ; second "B", and 52nd file is "z"
+ job-number = 3DIGIT
+ client-host-name = <a host name>
+
+ This sub-command is roughly equivalent to the IPP Send-Document
+ operation.
+
+ The mapper SHALL use the contents of the received LPD data file as
+ the data to transmit with the IPP Print-Job or Send-Document
+ operation.
+
+ Although RFC 1179 alludes to a method for passing an unspecified
+ length data file by using an octet-count of zero, no implementations
+ support this feature. The mapper SHALL reject a job that has a value
+ of 0 in the number-of-bytes field.
+
+3.3 Send queue state (short)
+
+ Command syntax:
+
+send-queue-short = %x03 printer-name *(SP(user-name / job-number)) LF
+
+ The mapper's response to this command includes information about the
+ printer and its jobs. RFC 1179 specifies neither the information nor
+ the format of its response. This document requires the mapper to
+ follow existing practice as specified in this document.
+
+ The mapper SHALL produce a response in the following format which
+ consists of a printer-status line optionally followed by a heading
+ line, and a list of jobs. This format is defined by examples below.
+ Appendix A contains the ABNF syntax.
+
+
+
+Herriot, et al. Experimental [Page 8]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ For an printer with no jobs, the response starts in column 1 and is:
+
+ no entries
+
+ For a printer with jobs, an example of the response is:
+
+ killtree is ready and printing
+ Rank Owner Job Files Total Size
+ active fred 123 stuff 1204 bytes
+ 1st smith 124 resume, foo 34576 bytes
+ 2nd fred 125 more 99 bytes
+ 3rd mary 126 mydoc 378 bytes
+ 4th jones 127 statistics.ps 4567 bytes
+ 5th fred 128 data.txt 9 bytes
+
+ The column numbers of above headings and job entries are:
+
+ | | | | |
+ 01 08 19 35 63
+
+ The mapper SHALL produce each field above from the following IPP
+ attribute:
+
+ LPD field IPP attribute special conversion details
+
+ printer- printer-state and For a printer-state of idle or
+ status printer-state-reasons processing, the mapper SHALL use
+ the formats above. For stopped,
+ the mapper SHALL use printer-
+ state-reasons to produce an
+ unspecified format for the error.
+ rank number-of- the mapper SHALL the format above
+ intervening-jobs
+ owner job-originating-user- unspecified conversion; job-
+ name originating-user-name may be the
+ mapper's user-name
+ job job-id the mapper shall use the job-id
+ files document-name the mapper shall create a comma
+ separated list of the document-
+ names and then truncate this list
+ to the first 24 characters
+ total- job-k- the mapper shall multiple the
+ size octets*copies*1024 value of job-k-octets by 1024 and
+ by the value of the "copies"
+ attribute.
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 9]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ A mapper SHOULD use the job attribute number-of-intervening-jobs
+ rather than the job's position in a list of jobs to determine 'rank'
+ because a Printer may omit jobs that it wants to keep secret. If a
+ printer doesn't support the job attribute number-of-intervening-jobs,
+ a mapper MAY use the job's position.
+
+ Note: a Printer may set the value of job-originating-user-name to the
+ authenticated user or to the value of "requesting-user-name",
+ depending on the implementation and configuration. For a gateway, the
+ authenticated user is the user-id of the gateway, but the
+ "requesting-user-name" may contain the name of the user who is the
+ gateway's client.
+
+ In order to obtain the information specified above, The LPD-to-IPP
+ mapper SHALL use the Get-Printer-Attributes operation to get
+ printer-status and SHOULD use the Get-Jobs operation to get
+ information about all of the jobs. If the LPD command contains job-
+ numbers or user-names, the mapper MAY handle the filtering of the
+ response. If the LPD command contains job-numbers but no user-names,
+ the mapper MAY use Get-Job-Attributes on each converted job-number
+ rather than Get-Jobs. If the LPD command contains a single user-name
+ but no job-numbers, the mapper MAY use Get-Jobs with the my-jobs
+ option if the server supports this option and if the server allows
+ the client to be a proxy for the LPD user.
+
+ NOTE: This specification does not define how the mapper maps the LPD
+ Printer-name operand to the IPP "printer-uri" operation attribute.
+
+3.4 Send queue state (long)
+
+ Command syntax:
+
+ send-queue-long = %x04 printer-name *(SP(user-name / job-number)) LF
+
+ The mapper's response to this command includes information about the
+ printer and its jobs. RFC 1179 specifies neither the information nor
+ the format of its response. This document requires the mapper to
+ follow existing practice as specified in this document.
+
+ The mapper SHALL produce a response in the following format which
+ consists of a printer-status line optionally followed a list of jobs,
+ where each job consists of a blank line, a description line, and one
+ line for each file. The description line contains the user-name,
+ rank, job-number and host. This format is defined by examples below.
+ Appendix B contain the ABNF syntax.
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 10]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ For an printer with no jobs the response is:
+
+ no entries
+
+ For a printer with jobs, an example of the response is:
+
+ killtree is ready and printing
+
+ fred: active [job 123 tiger]
+ 2 copies of stuff 602 bytes
+
+ smith: 1st [job 124 snail]
+ 2 copies of resume 7088 bytes
+ 2 copies of foo 10200 bytes
+
+ fred: 2nd [job 125 tiger]
+ more 99 bytes
+
+ The column numbers of above headings and job entries are:
+
+ | | |
+ 01 09 41
+
+ Although the format of the long form is different from the format of
+ the short form, their fields are identical except for a) the copies
+ and host fields which are only in the long form, and b) the "size"
+ field contains the single copy size of each file. Thus the sum of
+ the file sizes in the "size" field times the value of the "copies"
+ field produces the value for the "Total Size" field in the short
+ form. For fields other than the host and copies fields, see the
+ preceding section. For the host field see the table below.
+
+ LPD field IPP attribute special conversion details
+
+ host unspecified conversion; job-
+ originating-host may be the
+ mapper's host
+ copies copies the mapper shall assume the
+ value of copies precedes the
+ string "copies of "; otherwise,
+ the value of copies is 1.
+
+ NOTE: This specification does not define how the mapper maps the LPD
+ Printer-name operand to the IPP printer-uri operation attribute.
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 11]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+3.5 Remove jobs
+
+ Command syntax:
+
+ remove-jobs = %x05 printer-name SP agent
+ *(SP(user-name / job-number)) LF
+
+ The agent operand is the user-name of the user initiating the
+ remove-jobs command. The special user-name 'root' indicates a
+ privileged user who can remove jobs whose user-name differs from the
+ agent.
+
+ The mapper SHALL issue one Cancel-Job operation for each job
+ referenced by the remove-jobs command. Each job-number in the
+ remove-jobs command references a single job. Each user-name in the
+ remove-jobs command implicitly references all jobs owned by the
+ specified user. The active job is implicitly referenced when the
+ remove-jobs command contains neither job-numbers nor user-names. The
+ mapper MAY use Get-Jobs to determine the job-uri of implicitly
+ referenced jobs.
+
+ The mapper SHALL not use the agent name of 'root' when end-users
+ cancel their own jobs. Violation of this rule creates a potential
+ security violation, and it may cause the printer to issue a
+ notification that misleads a user into thinking that some other
+ person canceled the job.
+
+ If the agent of a remove-jobs command for a job J is the same as the
+ user name specified with the 'P' function in the control file for job
+ J, then the mapper SHALL ensure that the initiator of the Cancel-Job
+ command for job J is the same as job-originating-user for job J.
+
+ Note: This requirement means that a mapper must be consistent in who
+ the receiver perceives as the initiator of IPP operations. The mapper
+ either acts as itself or acts on behalf of another user. The latter
+ is preferable if it is possible. This consistency is necessary
+ between Print-Job/Create-Job and Cancel-Job in order for Cancel-Job
+ to work, but it is also desirable for other operations. For example,
+ Get-Jobs may give more information about job submitted by the
+ initiator of this operation.
+
+ NOTE: This specification does not define how the mapper maps: (1) the
+ LPD printer-name to the IPP "printer-uri" or (2) the LPD job-number
+ to the IPP "job-uri".
+
+ NOTE: This specification does not specify how the mapper maps the LPD
+ user-name to the IPP job-originating-user because the mapper may use
+ its own user-name with jobs.
+
+
+
+Herriot, et al. Experimental [Page 12]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+4. Mapping of LPD Control File Lines to IPP Operation and Job Template
+ Attributes
+
+ This section describes the mapping from LPD control file lines
+ (called 'functions') to IPP operation attributes and job template
+ attributes. The mapper receives the control file lines via the LPD
+ receive-control-file sub-command. Each of the LPD functions appear
+ as sub-sections of section 7 of RFC 1179.
+
+ In LPD control file lines, the text operands have a maximum length of
+ 31 or 99 while IPP operation attribute and job template attribute
+ values have a maximum of 255 or 1023 octets, depending on the
+ attribute syntax. Therefore, no data is lost.
+
+ The mapper converts each supported LPD function to its corresponding
+ IPP operation or job template attribute as defined by tables in the
+ subsections that follow. These subsections group functions according
+ to whether they are:
+
+ - required with a job,
+ - optional with a job
+ - required with each document.
+
+ In the tables below, each LPD value is given a name, such as 'h'. If
+ an IPP value uses the LPD value, then the IPP value column contains
+ the LPD name, such as 'h' to denote this. Otherwise, the IPP value
+ column specifies the literal value.
+
+4.1 Required Job Functions
+
+ The following LPD functions MUST be in a received LPD job. The mapper
+ SHALL receive each of the following LPD functions and SHALL include
+ the information as a operation or job template attribute with each
+ IPP job. The functions SHOULD be in the order 'H', 'P' and they
+ SHOULD be the first two functions in the control file, but they MAY
+ be anywhere in the control file and in any order:
+
+ LPD function IPP
+ name value description name value
+
+ H h Originating Host h (in security layer)
+ P u User identification requesting- u (and in security
+ user-name layer)
+ none ipp- 'true'
+ attribute-
+ fidelity
+
+
+
+
+
+Herriot, et al. Experimental [Page 13]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ A mapper MAY send its own host rather than the client's host, and a
+ mapper MAY send its own user-name as user identification rather than
+ the client user. But in any case, the values sent SHALL be compatible
+ with the Cancel-Job operation. The IPP operation MAY have no way to
+ specify an originating host-name.
+
+ The mapper SHALL include ipp-attribute-fidelity = true so that it
+ doesn't have to determine which attributes a printer supports.
+
+4.2 Optional Job Functions
+
+ The following LPD functions MAY be present in a received job. These
+ functions SHOULD follow the required job functions and precede the
+ document functions, but they MAY be anywhere in the control file.
+
+ If the mapper receives such an LPD function, the mapper SHALL include
+ the corresponding IPP attribute with the value converted as specified
+ in the table below. If the mapper does not receive such an LPD
+ attribute, the mapper SHALL NOT include the corresponding IPP
+ attribute, except the 'L' LPD function whose absence has a special
+ meaning as noted in the table.
+
+ LPD function IPP
+ name value description name value
+
+ J j Job name for job-name j
+ banner page
+ L l Print banner page job-sheets 'standard' if 'L' is
+ present
+ 'none' if 'L' is present
+ M m Mail When Printed IPP has no notification
+ mechanism. To support
+ this LPD feature, the
+ gateway must poll using
+ the Get-Job-Attributes
+ operation.
+
+4.3 Required Document Functions
+
+ The mapper SHALL receive one set of the required document functions
+ with each copy of a document, and SHALL include the converted
+ information as operation or job template attributes with each IPP
+ document.
+
+ If the control file contains required and recommended document
+ functions, the required functions SHOULD precede the recommended ones
+ and if the job contains multiple documents, all the functions for
+
+
+
+
+Herriot, et al. Experimental [Page 14]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ each document are grouped together as shown in the example of section
+ 6.3 "Required Document Functions". However, the document functions
+ MAY be in any order.
+
+ LPD function IPP
+ name value description name value
+
+ f fff Print formatted document-format 'application/octet-
+ file stream'
+ l fff Print file leaving document-format 'application/octet-
+ control characters stream'
+ o fff Print Postscript document-format 'application/PostScri
+ output file pt'
+ copies see note
+
+ Note: In practice, the 'f' LPD function is often overloaded. It is
+ often used with any format of document data including PostScript and
+ PCL data.
+
+ Note: In practice, the 'l' LPD function is often used as a rough
+ equivalent to the 'f' function.
+
+ Note: When RFC 1179 was written, no implementation supported the 'o'
+ function; instead 'f' was used for PostScript. Windows NT now sends '
+ o' function for a PostScript file.
+
+ Note: the value 'fff' of the 'f', 'l' and 'o' functions is the name
+ of the data file as transferred, e.g. "dfA123woden".
+
+ If the mapper receives any other lower case letter, the mapper SHALL
+ reject the job because the document contains a format that the mapper
+ does not support.
+
+ The mapper determines the number of copies by counting the number of
+ occurrences of each 'fff' file with one of the lower-case functions
+ above. For example, if 'f dfA123woden' occurs 4 times, then copies
+ has a value of 4. Although the LPD protocol allows the value of
+ copies to be different for each document, the commands and the
+ receiving print systems don't support this.
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 15]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+4.4 Recommended Document Functions
+
+ The mapper SHOULD receive one set of the recommended document
+ functions with each document, and SHOULD include the converted
+ information as an operation or job template attribute with each IPP
+ document. The functions SHOULD be received in the order 'U' and 'N',
+ but they MAY arrive in any order.
+
+ LPD function IPP
+ name value description name value
+
+ U fff ignored
+ N n Name of source file document-name n
+
+ Note: the value 'fff' of the 'U' function is the name of the data
+ file as transferred, e.g. "dfA123woden".
+
+5. Mapping from IPP operations to LPD commands
+
+ If the IPP-to-LPD mapper receives an IPP operation, the following
+ table summarizes the LPD command that it uses. Each section below
+ gives the detail. Each of the following sub-sections appear as sub-
+ sections of section 3 in the document "Internet Printing
+ Protocol/1.0: Model and Semantics" [RFC2566].
+
+ IPP operation LPD command
+
+ Print-Job or Print-URI or receive-a-printer-job
+ Create-Job/Send-Document/Send-URI and then print-any-waiting-jobs
+ Validate-Job implemented by the mapper
+ Cancel-Job remove-jobs
+ Get-Printer-Attributes, Get-Job- send queue state (short or long)
+ Attributes or Get-Jobs
+
+5.1 Print-Job
+
+ The mapper SHALL send the following commands in the order listed
+ below:
+
+ - receive-a-printer-job command
+ - both receive-control-file sub-command and receive-data-file
+ sub-command (unspecified order, see Note below)
+ - print-any-waiting-jobs command, except that if the mapper is
+ sending a sequence of receive a printer-job commands, it MAY
+ omit sending print-any-waiting-jobs after any receive a
+ printer-job command that is neither the first nor last command
+ in this sequence
+
+
+
+
+Herriot, et al. Experimental [Page 16]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ Note: it is recommended that the order of the receive-control-file
+ subcommand and the receive-data-file sub-command be configurable
+ because either order fails for some print systems. Some print systems
+ assume that the control file follows all data files and start
+ printing immediately on receipt of the control file. When such a
+ print system tries to print a data file that has not arrived, it
+ produces an error. Other print systems assume that the control file
+ arrives before the data files and start printing when the first data
+ file arrives. Such a system ignores the control information, such as
+ banner page or copies.
+
+ NOTE: This specification does not define the mapping between the IPP
+ printer-uri and the LPD printer-name.
+
+ The mapper SHALL send the IPP operation attributes and job template
+ attributes received from the operation to the LPD printer by using
+ the LPD receive-control-file sub-command. The mapper SHALL create the
+ LPD job-number for use in the control file name, but the receiving
+ printer MAY, in some circumstances, assign a different job-number to
+ the job. The mapper SHALL create the IPP job-id and IPP job-uri
+ returned in the Print-Job response.
+
+ NOTE: This specification does not specify how the mapper determines
+ the LPD job-number, the IPP job-id or the IPP job-uri of a job that
+ it creates nor does it specify the relationship between the IPP job-
+ uri, IPP the job-id and the LPD job-number, both of which the mapper
+ creates. However, it is likely that the mapper will use the same
+ integer value for both the LPD job-number and the IPP job-id, and
+ that the IPP Job-uri is the printer's URI with the job-id
+ concatenated on the end.
+
+ The mapper SHALL send data received in the IPP operation to the LPD
+ printer by using the LPD receive-data-file sub-command. The mapper
+ SHALL specify the exact number of bytes being transmitted in the
+ number-of-bytes field of the receive-data-file sub-command. It SHALL
+ NOT use a value of 0 in this field.
+
+ If the mapper, while it is transmitting a receive-a-printer-job
+ command or sub-command, either detects that its IPP connection has
+ closed or receives a Cancel-Job operation, the mapper SHALL terminate
+ the LPD job either with the abort sub-command or the remove-jobs
+ command.
+
+ This document does not address error code conversion.
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 17]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+5.2 Print-URI
+
+ The mapper SHALL handle this operation in the same way as a Print-Job
+ operation except that it SHALL obtain data referenced by the
+ "document-uri" operation attribute and SHALL then treat that data as
+ if it had been received via a Print-Job operation.
+
+5.3 Validate-Job
+
+ The mapper SHALL perform this operation directly. Because LPD
+ supports very few attributes, this operation doesn't have much to
+ check.
+
+5.4 Create-Job
+
+ The mapper SHALL handle this operation like Print-Job, except:
+
+ - the mapper SHALL send the control file after it has received the
+ last Send-Document or Send-URI operation because the control
+ file contains all the document-name and document-format values
+ specified in the Send-Document and Send-URI operations.
+ - the mapper SHALL perform one receive-data-file sub-command for
+ each Send-Document or Send-URI operation received and in the
+ same order received.
+ - the mapper SHALL send the control file either before all data
+ files or after all data files. (See the note in the section on
+ Print-Job about the dilemma of sending the control file either
+ before or after the data files.
+
+5.5 Send-Document
+
+ The mapper performs a receive-data-file sub-command on the received
+ data. See the preceding section 5.4 "Create-Job" for the details.
+
+5.6 Send-URI
+
+ The mapper SHALL obtain the data referenced by the "document-uri"
+ operation attribute, and SHALL then treat that data as if it had been
+ received via a Send-Document operation. See the preceding section 5.5
+ "Send-Document" for the details.
+
+5.7 Cancel-Job
+
+ The mapper SHALL perform a remove-jobs command with the following
+ operation attributes:
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 18]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ - the printer is the one to which the job was submitted, that is
+ the IPP printer-uri is mapped to an LPD printer-name by the same
+ mechanism as for all commands
+ - the agent is the authenticated user-name of the IPP client
+ - the job-number is the job-id returned by the Print-Job command,
+ that is, the LPD job-number has the same value as the IPP job-id
+ for likely implementations
+
+5.8 Get-Printer-Attributes
+
+ LPD severely limits the set of attributes that the mapper is able to
+ return in its response for this operation. The mapper SHALL support,
+ at most, the following printer attributes:
+
+ - printer-state
+ - printer-state-reasons
+
+ The mapper uses either the long or short form of the "send queue
+ state" command.
+
+ The mapper SHALL assume that the LPD response that it receives has
+ the format and information specified in section 3.3 "Send queue state
+ (short)" and section 3.4 "Send queue state (long)". The mapper SHALL
+ determine the value of each requested attribute by using the inverse
+ of the mapping specified in the two aforementioned sections.
+
+ Note: the mapper can determine the response from the printer-status
+ line without examining the rest of the LPD response.
+
+5.9 Get-Job-Attributes
+
+ LPD severely limits the set of attributes that the mapper is able to
+ return in its response for this operation. The mapper SHALL support,
+ at most, the following job attributes:
+
+ - number-of-intervening-jobs
+ - job-originating-user-name
+ - job-id
+ - document-name
+ - job-k-octets
+ - copies
+
+ The mapper uses either the long or short form of the "send queue
+ state" command. If it receives a request for the "job-k-octets" or
+ "copies" and supports the attribute it SHALL use the long form;
+ otherwise, it SHALL use the short form.
+
+
+
+
+
+Herriot, et al. Experimental [Page 19]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ Note: the value of job-k-octets is the value in the short form
+ divided by the number of "copies" which is on the long form only. Its
+ value can also be determined by adding the "size" field values for
+ each document in the job in the long form.
+
+ The mapper SHALL assume that the LPD response that it receives has
+ the format and information specified in section 3.3 "Send queue state
+ (short)" and section 3.4 "Send queue state (long)". The mapper SHALL
+ determine the value of each requested attribute by using the inverse
+ of the mapping specified in the two aforementioned sections.
+
+ Note: when the mapper uses the LPD short form, it can determine the
+ response from the single LPD line that pertains to the job specified
+ by the Get-Job-Attributes operation.
+
+ Note: the mapper can use its correspondence between the IPP job-id,
+ job-uri and the LPD job-number.
+
+5.10 Get-Jobs
+
+ The mapper SHALL perform this operation in the same way as Get-Job-
+ Attributes except that the mapper converts all the LPD job-lines, and
+ the IPP response contains one job object for each job-line in the LPD
+ response.
+
+6. Mapping of IPP Attributes to LPD Control File Lines
+
+ This section describes the mapping from IPP operation attributes and
+ job template attributes to LPD control file lines (called '
+ functions'). The mapper receives the IPP operation attributes and job
+ template atributes via the IPP operation. Each of the IPP operation
+ attributes and job template attributes appear as sub-sections of
+ section 3 and 4.2 in the IPP model document [RFC2566].
+
+ In the context of LPD control file lines, the text operands have a
+ maximum length of 31 or 99 while IPP operation attributes and job
+ template attributes have a maximum of 255 or 1023 octets, depending
+ on the attribute syntax. Therefore, there may be some data loss if
+ the IPP operation attribute and job template attribute values exceed
+ the maximum length of the LPD equivalent operands.
+
+ The mapper converts each supported IPP operation attribute and job
+ template attribute to its corresponding LPD function as defined by
+ tables in the subsections that follow. These subsections group
+ functions according to whether they are:
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 20]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ - required with a job,
+ - optional with a job
+ - required with each document.
+
+ In the tables below, each IPP value is given a name, such as 'h'. If
+ an LPD value uses the IPP value, then the LPD value column contains
+ the IPP name, such as 'h' to denote this. Otherwise, the LPD value
+ column specifies the literal value.
+
+6.1 Required Job Functions
+
+ The mapper SHALL include the following LPD functions with each job,
+ and they SHALL have the specified value. They SHALL be the first
+ functions in the control file and they SHALL be in the order "H" and
+ then "P".
+
+ IPP LPD function
+ name value name value description
+
+ (perhaps in security h H gateway host Originating Host
+ layer)
+ requesting-user-name u P u User identification
+ and in the security
+ layer
+
+ A mapper SHALL sends its own host rather than the client's host,
+ because some LPD systems require that it be the same as the host from
+ which the remove-jobs command comes. A mapper MAY send its own user
+ name as user identification rather than the client user. But in any
+ case, the values sent SHALL be compatible with the LPD remove-jobs
+ operation.
+
+6.2 Optional Job Functions
+
+ The mapper MAY include the following LPD functions with each job.
+ They SHALL have the specified value if they are sent. These
+ functions, if present, SHALL follow the require job functions, and
+ they SHALL precede the required document functions.
+
+ IPP attribute LPD function
+ name value name value description
+
+ job-name j J j Job name for banner
+ page
+ job-sheets 'standard' L u Print banner page
+ job-sheets 'none' omit 'L' function
+
+
+
+
+
+Herriot, et al. Experimental [Page 21]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ Note: 'L' has special meaning when it is omitted. If 'J' is omitted,
+ some undefined behavior occurs with respect to the banner page.
+
+6.3 Required Document Functions
+
+ The mapper SHALL include one set of the following LPD functions with
+ each document, and they SHALL have the specified values. For each
+ document, the order of the functions SHALL be 'f', 'U' and then 'N',
+ where 'f' is replicated once for each copy.
+
+ IPP attribute LPD function
+
+ name value name value description
+
+ document- 'application/octet- f fff Print formatted file
+ format stream' or
+ 'application/PostScript'
+ copies c replicate 'f' 'c'
+ times
+ none U fff Unlink data file
+ document- n N n Name of source file
+ name
+
+ Note: the value 'fff' of the 'f' and 'U' functions is the name of the
+ data file as transferred, e.g. "dfA123woden".
+
+ Note: the mapper SHALL not send the 'o' function
+
+ ISSUE: should we register DVI, troff or ditroff?
+
+ If the mapper receives no "ipp-attribute-fidelitybest-effort" or it
+ has a value of false, then the mapper SHALL reject the job if it
+ specifies attributes or attribute values that are not among those
+ supported in the above tables.
+
+ Below is an example of the minimal control file for a job with three
+ copies of two files 'foo' and 'bar':
+
+ H tiger
+ P jones
+ f dfA123woden
+ f dfA123woden
+ f dfA123woden
+ U dfA123woden
+ N foo
+ f dfB123woden
+ f dfB123woden
+ f dfB123woden
+
+
+
+Herriot, et al. Experimental [Page 22]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+ U dfB123woden
+ N bar
+
+7. Security Considerations
+
+ There are no security issues beyond those covered in the IPP Encoding
+ and Transport document [RFC2565], the IPP model document [RFC2566]
+ and the LPD document [RFC1179].
+
+8. References
+
+ [ipp-iig] Hasting, T., et al., "Internet Printing Protocol/1.0:
+ Implementer's Guide", Work in Progress.
+
+ [RFC1759] Smith, R., Wright, F., Hastings, T., Zilles, S., and J.
+ Gyllenskog, "Printer MIB", RFC 1759, March 1995.
+
+ [RFC1179] McLaughlin, L., "Line Printer Daemon Protocol", RFC 1179,
+ August 1990.
+
+ [RFC2119] Bradner, S. "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2234] D. Crocker et al., "Augmented BNF for Syntax
+ Specifications: ABNF", RFC 2234, November 1997.
+
+ [RFC2565] Herriot, R., Butler, S., Moore, P. and R. Tuner, "Internet
+ Printing Protocol/1.0: Encoding and Transport", RFC 2565,
+ April 1999.
+
+ [RFC2566] deBry, R., Hastings, T., Herriot, R., Isaacson, S., and P.
+ Powell, "Internet Printing Protocol/1.0: Model and
+ Semantics", RFC 2566, April 1999.
+
+ [RFC2567] Wright, D., "Design Goals for an Internet Printing
+ Protocol", RFC 2567, April 1999.
+
+ [RFC2568] Zilles, S., "Rationale for the Structure and Model and
+ Protocol for the Internet Printing Protocol", RFC 2568,
+ April 1999.
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 23]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+9. Authors' Addresses
+
+ Robert Herriot (Editor)
+ Xerox Corporation
+ 3400 Hillview Ave., Bldg #1
+ Palo Alto, CA 94304
+
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ EMail: rherriot@pahv.xerox.com
+
+
+ Norm Jacobs
+ Sun Microsystems Inc.
+ 1430 Owl Ridge Rd.
+ Colorado Springs, CO 80919
+
+ Phone: 719-532-9927
+ Fax: 719-535-0956
+ EMail: Norm.Jacobs@Central.sun.com
+
+
+ Thomas N. Hastings
+ Xerox Corporation
+ 701 S. Aviation Blvd., ESAE-231
+ El Segundo, CA 90245
+
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ EMail: hastings@cp10.es.xerox.com
+
+
+ Jay Martin
+ Underscore, Inc.
+ 41-C Sagamore Park Road
+ Hudson, NH 03051-4915
+
+ Phone: 603-889-7000
+ Fax: 603-889-2699
+ EMail: jkm@underscore.com
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 24]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+10. Appendix A: ABNF Syntax for response of Send-queue-state (short)
+
+ The syntax in ABNF for the response to the LPD command 'send-queue-
+ state (long)' is:
+
+ status-response = empty-queue / nonempty-queue
+ empty-queue = "no-entries" LF
+ nonempty-queue = printer-status LF heading LF *(job LF)
+ printer-status = OK-status / error-status
+ OK-status = printer-name SP "ready and printing" LF
+ error-status = < implementation dependent status information >
+ heading = "Rank" 3SP "Owner" 6SP "Job" 13SP "Files"
+ 23SP "Total Size" LF
+ ; the column headings and their values below begin
+ at the columns
+ ; 1, 8, 19, 35 and 63
+ job = rank *SP owner *SP job *SP files *SP total-size "bytes"
+ ; jobs are in order of oldest to newest
+ rank = "active" / "1st" / "2nd" / "3rd" / integer "th"
+ ; job that is printing is "active"
+ ; other values show position in the queue
+ owner = <user name of person who submitted the job>
+ job = 1*3DIGIT ; job-number
+ files = <file name> *( "," <file name>) ; truncated to 24 characters
+ total-size = 1*DIGIT ; combined size in bytes of all documents
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 25]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+11. Appendix B: ABNF Syntax for response of Send-queue-state (long)
+
+ The syntax in ABNF for the response to the LPD command 'send-queue-
+ state (long)' is:
+
+ status-response = empty-queue / nonempty-queue
+ empty-queue = "no-entries" LF
+ nonempty-queue = printer-status LF *job
+ printer-status = OK-status / error-status
+ OK-status = printer-name SP "ready and printing" LF
+ error-status = < implementation dependent status information >
+ job = LF line-1 LF line-2 LF
+ line-1 = owner ":" SP rank 1*SP "[job" job SP host "]"
+ line-2 = file-name 1*SP document-size "bytes"
+ ; jobs are in order of oldest to newest
+ rank = "active" / "1st" / "2nd" / "3rd" / integer "th"
+ ; job that is printing is "active"
+ ; other values show position in the queue
+ owner = <user name of person who submitted the job>
+ job = 1*3DIGIT
+ file-name = [ 1*DIGIT "copies of" SP ] <file name>
+ ; truncated to 24 characters
+ document-size = 1*DIGIT ;size of single copy of the document.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 26]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+12. Appendix C: Unsupported LPD functions
+
+ The follow LPD functions have no IPP equivalent. The LPD-to-IPP
+ mapper ignores them and the IPP-to-LPD mapper does not send them.
+
+ LPD command
+ name description
+
+ C Class for banner page
+ I Indent Printing
+ H Host of client
+ M Mail when printed
+ S Symbolic link data
+ T Title for pr
+ W Width of output
+ 1 troff R font
+ 2 troff I font
+ 3 troff B font
+ 4 troff S font
+
+ The follow LPD functions specify document-formats which have no IPP
+ equivalent, unless someone registers them. The LPD-to-IPP mapper
+ rejects jobs that request such a document format, and the IPP-to-LPD
+ mapper does not send them.
+
+ LPD command
+ name description
+
+ c Plot CIF file
+ d Print DVI file
+ g Plot file
+ k reserved for Kerberized clients and servers
+ n Print ditroff output file
+ p Print file with 'pr' format
+ r File to print with FORTRAN carriage control
+ t Print troff output file
+ v Print raster file
+ z reserved for future use with the Palladium
+ print system
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 27]
+
+RFC 2569 Mapping between LPD and IPP Protocols April 1999
+
+
+13. Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Experimental [Page 28]
+
diff --git a/standards/rfc2595.txt b/standards/rfc2595.txt
new file mode 100644
index 000000000..66897cd6c
--- /dev/null
+++ b/standards/rfc2595.txt
@@ -0,0 +1,843 @@
+
+
+
+
+
+
+Network Working Group C. Newman
+Request for Comments: 2595 Innosoft
+Category: Standards Track June 1999
+
+
+ Using TLS with IMAP, POP3 and ACAP
+
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+1. Motivation
+
+ The TLS protocol (formerly known as SSL) provides a way to secure an
+ application protocol from tampering and eavesdropping. The option of
+ using such security is desirable for IMAP, POP and ACAP due to common
+ connection eavesdropping and hijacking attacks [AUTH]. Although
+ advanced SASL authentication mechanisms can provide a lightweight
+ version of this service, TLS is complimentary to simple
+ authentication-only SASL mechanisms or deployed clear-text password
+ login commands.
+
+ Many sites have a high investment in authentication infrastructure
+ (e.g., a large database of a one-way-function applied to user
+ passwords), so a privacy layer which is not tightly bound to user
+ authentication can protect against network eavesdropping attacks
+ without requiring a new authentication infrastructure and/or forcing
+ all users to change their password. Recognizing that such sites will
+ desire simple password authentication in combination with TLS
+ encryption, this specification defines the PLAIN SASL mechanism for
+ use with protocols which lack a simple password authentication
+ command such as ACAP and SMTP. (Note there is a separate RFC for the
+ STARTTLS command in SMTP [SMTPTLS].)
+
+ There is a strong desire in the IETF to eliminate the transmission of
+ clear-text passwords over unencrypted channels. While SASL can be
+ used for this purpose, TLS provides an additional tool with different
+ deployability characteristics. A server supporting both TLS with
+
+
+
+
+Newman Standards Track [Page 1]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+ simple passwords and a challenge/response SASL mechanism is likely to
+ interoperate with a wide variety of clients without resorting to
+ unencrypted clear-text passwords.
+
+ The STARTTLS command rectifies a number of the problems with using a
+ separate port for a "secure" protocol variant. Some of these are
+ mentioned in section 7.
+
+1.1. Conventions Used in this Document
+
+ The key words "REQUIRED", "MUST", "MUST NOT", "SHOULD", "SHOULD NOT",
+ "MAY", and "OPTIONAL" in this document are to be interpreted as
+ described in "Key words for use in RFCs to Indicate Requirement
+ Levels" [KEYWORDS].
+
+ Terms related to authentication are defined in "On Internet
+ Authentication" [AUTH].
+
+ Formal syntax is defined using ABNF [ABNF].
+
+ In examples, "C:" and "S:" indicate lines sent by the client and
+ server respectively.
+
+2. Basic Interoperability and Security Requirements
+
+ The following requirements apply to all implementations of the
+ STARTTLS extension for IMAP, POP3 and ACAP.
+
+2.1. Cipher Suite Requirements
+
+ Implementation of the TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA [TLS] cipher
+ suite is REQUIRED. This is important as it assures that any two
+ compliant implementations can be configured to interoperate.
+
+ All other cipher suites are OPTIONAL.
+
+2.2. Privacy Operational Mode Security Requirements
+
+ Both clients and servers SHOULD have a privacy operational mode which
+ refuses authentication unless successful activation of an encryption
+ layer (such as that provided by TLS) occurs prior to or at the time
+ of authentication and which will terminate the connection if that
+ encryption layer is deactivated. Implementations are encouraged to
+ have flexability with respect to the minimal encryption strength or
+ cipher suites permitted. A minimalist approach to this
+ recommendation would be an operational mode where the
+ TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA cipher suite is mandatory prior to
+ permitting authentication.
+
+
+
+Newman Standards Track [Page 2]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+ Clients MAY have an operational mode which uses encryption only when
+ it is advertised by the server, but authentication continues
+ regardless. For backwards compatibility, servers SHOULD have an
+ operational mode where only the authentication mechanisms required by
+ the relevant base protocol specification are needed to successfully
+ authenticate.
+
+2.3. Clear-Text Password Requirements
+
+ Clients and servers which implement STARTTLS MUST be configurable to
+ refuse all clear-text login commands or mechanisms (including both
+ standards-track and nonstandard mechanisms) unless an encryption
+ layer of adequate strength is active. Servers which allow
+ unencrypted clear-text logins SHOULD be configurable to refuse
+ clear-text logins both for the entire server, and on a per-user
+ basis.
+
+2.4. Server Identity Check
+
+ During the TLS negotiation, the client MUST check its understanding
+ of the server hostname against the server's identity as presented in
+ the server Certificate message, in order to prevent man-in-the-middle
+ attacks. Matching is performed according to these rules:
+
+ - The client MUST use the server hostname it used to open the
+ connection as the value to compare against the server name as
+ expressed in the server certificate. The client MUST NOT use any
+ form of the server hostname derived from an insecure remote source
+ (e.g., insecure DNS lookup). CNAME canonicalization is not done.
+
+ - If a subjectAltName extension of type dNSName is present in the
+ certificate, it SHOULD be used as the source of the server's
+ identity.
+
+ - Matching is case-insensitive.
+
+ - A "*" wildcard character MAY be used as the left-most name
+ component in the certificate. For example, *.example.com would
+ match a.example.com, foo.example.com, etc. but would not match
+ example.com.
+
+ - If the certificate contains multiple names (e.g. more than one
+ dNSName field), then a match with any one of the fields is
+ considered acceptable.
+
+ If the match fails, the client SHOULD either ask for explicit user
+ confirmation, or terminate the connection and indicate the server's
+ identity is suspect.
+
+
+
+Newman Standards Track [Page 3]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+2.5. TLS Security Policy Check
+
+ Both the client and server MUST check the result of the STARTTLS
+ command and subsequent TLS negotiation to see whether acceptable
+ authentication or privacy was achieved. Ignoring this step
+ completely invalidates using TLS for security. The decision about
+ whether acceptable authentication or privacy was achieved is made
+ locally, is implementation-dependent, and is beyond the scope of this
+ document.
+
+3. IMAP STARTTLS extension
+
+ When the TLS extension is present in IMAP, "STARTTLS" is listed as a
+ capability in response to the CAPABILITY command. This extension
+ adds a single command, "STARTTLS" to the IMAP protocol which is used
+ to begin a TLS negotiation.
+
+3.1. STARTTLS Command
+
+ Arguments: none
+
+ Responses: no specific responses for this command
+
+ Result: OK - begin TLS negotiation
+ BAD - command unknown or arguments invalid
+
+ A TLS negotiation begins immediately after the CRLF at the end of
+ the tagged OK response from the server. Once a client issues a
+ STARTTLS command, it MUST NOT issue further commands until a
+ server response is seen and the TLS negotiation is complete.
+
+ The STARTTLS command is only valid in non-authenticated state.
+ The server remains in non-authenticated state, even if client
+ credentials are supplied during the TLS negotiation. The SASL
+ [SASL] EXTERNAL mechanism MAY be used to authenticate once TLS
+ client credentials are successfully exchanged, but servers
+ supporting the STARTTLS command are not required to support the
+ EXTERNAL mechanism.
+
+ Once TLS has been started, the client MUST discard cached
+ information about server capabilities and SHOULD re-issue the
+ CAPABILITY command. This is necessary to protect against
+ man-in-the-middle attacks which alter the capabilities list prior
+ to STARTTLS. The server MAY advertise different capabilities
+ after STARTTLS.
+
+ The formal syntax for IMAP is amended as follows:
+
+
+
+
+Newman Standards Track [Page 4]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+ command_any =/ "STARTTLS"
+
+ Example: C: a001 CAPABILITY
+ S: * CAPABILITY IMAP4rev1 STARTTLS LOGINDISABLED
+ S: a001 OK CAPABILITY completed
+ C: a002 STARTTLS
+ S: a002 OK Begin TLS negotiation now
+ <TLS negotiation, further commands are under TLS layer>
+ C: a003 CAPABILITY
+ S: * CAPABILITY IMAP4rev1 AUTH=EXTERNAL
+ S: a003 OK CAPABILITY completed
+ C: a004 LOGIN joe password
+ S: a004 OK LOGIN completed
+
+3.2. IMAP LOGINDISABLED capability
+
+ The current IMAP protocol specification (RFC 2060) requires the
+ implementation of the LOGIN command which uses clear-text passwords.
+ Many sites may choose to disable this command unless encryption is
+ active for security reasons. An IMAP server MAY advertise that the
+ LOGIN command is disabled by including the LOGINDISABLED capability
+ in the capability response. Such a server will respond with a tagged
+ "NO" response to any attempt to use the LOGIN command.
+
+ An IMAP server which implements STARTTLS MUST implement support for
+ the LOGINDISABLED capability on unencrypted connections.
+
+ An IMAP client which complies with this specification MUST NOT issue
+ the LOGIN command if this capability is present.
+
+ This capability is useful to prevent clients compliant with this
+ specification from sending an unencrypted password in an environment
+ subject to passive attacks. It has no impact on an environment
+ subject to active attacks as a man-in-the-middle attacker can remove
+ this capability. Therefore this does not relieve clients of the need
+ to follow the privacy mode recommendation in section 2.2.
+
+ Servers advertising this capability will fail to interoperate with
+ many existing compliant IMAP clients and will be unable to prevent
+ those clients from disclosing the user's password.
+
+4. POP3 STARTTLS extension
+
+ The POP3 STARTTLS extension adds the STLS command to POP3 servers.
+ If this is implemented, the POP3 extension mechanism [POP3EXT] MUST
+ also be implemented to avoid the need for client probing of multiple
+ commands. The capability name "STLS" indicates this command is
+ present and permitted in the current state.
+
+
+
+Newman Standards Track [Page 5]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+ STLS
+
+ Arguments: none
+
+ Restrictions:
+ Only permitted in AUTHORIZATION state.
+
+ Discussion:
+ A TLS negotiation begins immediately after the CRLF at the
+ end of the +OK response from the server. A -ERR response
+ MAY result if a security layer is already active. Once a
+ client issues a STLS command, it MUST NOT issue further
+ commands until a server response is seen and the TLS
+ negotiation is complete.
+
+ The STLS command is only permitted in AUTHORIZATION state
+ and the server remains in AUTHORIZATION state, even if
+ client credentials are supplied during the TLS negotiation.
+ The AUTH command [POP-AUTH] with the EXTERNAL mechanism
+ [SASL] MAY be used to authenticate once TLS client
+ credentials are successfully exchanged, but servers
+ supporting the STLS command are not required to support the
+ EXTERNAL mechanism.
+
+ Once TLS has been started, the client MUST discard cached
+ information about server capabilities and SHOULD re-issue
+ the CAPA command. This is necessary to protect against
+ man-in-the-middle attacks which alter the capabilities list
+ prior to STLS. The server MAY advertise different
+ capabilities after STLS.
+
+ Possible Responses:
+ +OK -ERR
+
+ Examples:
+ C: STLS
+ S: +OK Begin TLS negotiation
+ <TLS negotiation, further commands are under TLS layer>
+ ...
+ C: STLS
+ S: -ERR Command not permitted when TLS active
+
+
+
+
+
+
+
+
+
+
+Newman Standards Track [Page 6]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+5. ACAP STARTTLS extension
+
+ When the TLS extension is present in ACAP, "STARTTLS" is listed as a
+ capability in the ACAP greeting. No arguments to this capability are
+ defined at this time. This extension adds a single command,
+ "STARTTLS" to the ACAP protocol which is used to begin a TLS
+ negotiation.
+
+5.1. STARTTLS Command
+
+ Arguments: none
+
+ Responses: no specific responses for this command
+
+ Result: OK - begin TLS negotiation
+ BAD - command unknown or arguments invalid
+
+ A TLS negotiation begins immediately after the CRLF at the end of
+ the tagged OK response from the server. Once a client issues a
+ STARTTLS command, it MUST NOT issue further commands until a
+ server response is seen and the TLS negotiation is complete.
+
+ The STARTTLS command is only valid in non-authenticated state.
+ The server remains in non-authenticated state, even if client
+ credentials are supplied during the TLS negotiation. The SASL
+ [SASL] EXTERNAL mechanism MAY be used to authenticate once TLS
+ client credentials are successfully exchanged, but servers
+ supporting the STARTTLS command are not required to support the
+ EXTERNAL mechanism.
+
+ After the TLS layer is established, the server MUST re-issue an
+ untagged ACAP greeting. This is necessary to protect against
+ man-in-the-middle attacks which alter the capabilities list prior
+ to STARTTLS. The client MUST discard cached capability
+ information and replace it with the information from the new ACAP
+ greeting. The server MAY advertise different capabilities after
+ STARTTLS.
+
+ The formal syntax for ACAP is amended as follows:
+
+ command_any =/ "STARTTLS"
+
+ Example: S: * ACAP (SASL "CRAM-MD5") (STARTTLS)
+ C: a002 STARTTLS
+ S: a002 OK "Begin TLS negotiation now"
+ <TLS negotiation, further commands are under TLS layer>
+ S: * ACAP (SASL "CRAM-MD5" "PLAIN" "EXTERNAL")
+
+
+
+
+Newman Standards Track [Page 7]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+6. PLAIN SASL mechanism
+
+ Clear-text passwords are simple, interoperate with almost all
+ existing operating system authentication databases, and are useful
+ for a smooth transition to a more secure password-based
+ authentication mechanism. The drawback is that they are unacceptable
+ for use over an unencrypted network connection.
+
+ This defines the "PLAIN" SASL mechanism for use with ACAP and other
+ protocols with no clear-text login command. The PLAIN SASL mechanism
+ MUST NOT be advertised or used unless a strong encryption layer (such
+ as the provided by TLS) is active or backwards compatibility dictates
+ otherwise.
+
+ The mechanism consists of a single message from the client to the
+ server. The client sends the authorization identity (identity to
+ login as), followed by a US-ASCII NUL character, followed by the
+ authentication identity (identity whose password will be used),
+ followed by a US-ASCII NUL character, followed by the clear-text
+ password. The client may leave the authorization identity empty to
+ indicate that it is the same as the authentication identity.
+
+ The server will verify the authentication identity and password with
+ the system authentication database and verify that the authentication
+ credentials permit the client to login as the authorization identity.
+ If both steps succeed, the user is logged in.
+
+ The server MAY also use the password to initialize any new
+ authentication database, such as one suitable for CRAM-MD5
+ [CRAM-MD5].
+
+ Non-US-ASCII characters are permitted as long as they are represented
+ in UTF-8 [UTF-8]. Use of non-visible characters or characters which
+ a user may be unable to enter on some keyboards is discouraged.
+
+ The formal grammar for the client message using Augmented BNF [ABNF]
+ follows.
+
+ message = [authorize-id] NUL authenticate-id NUL password
+ authenticate-id = 1*UTF8-SAFE ; MUST accept up to 255 octets
+ authorize-id = 1*UTF8-SAFE ; MUST accept up to 255 octets
+ password = 1*UTF8-SAFE ; MUST accept up to 255 octets
+ NUL = %x00
+ UTF8-SAFE = %x01-09 / %x0B-0C / %x0E-7F / UTF8-2 /
+ UTF8-3 / UTF8-4 / UTF8-5 / UTF8-6
+ UTF8-1 = %x80-BF
+ UTF8-2 = %xC0-DF UTF8-1
+ UTF8-3 = %xE0-EF 2UTF8-1
+
+
+
+Newman Standards Track [Page 8]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+ UTF8-4 = %xF0-F7 3UTF8-1
+ UTF8-5 = %xF8-FB 4UTF8-1
+ UTF8-6 = %xFC-FD 5UTF8-1
+
+ Here is an example of how this might be used to initialize a CRAM-MD5
+ authentication database for ACAP:
+
+ Example: S: * ACAP (SASL "CRAM-MD5") (STARTTLS)
+ C: a001 AUTHENTICATE "CRAM-MD5"
+ S: + "<1896.697170952@postoffice.reston.mci.net>"
+ C: "tim b913a602c7eda7a495b4e6e7334d3890"
+ S: a001 NO (TRANSITION-NEEDED)
+ "Please change your password, or use TLS to login"
+ C: a002 STARTTLS
+ S: a002 OK "Begin TLS negotiation now"
+ <TLS negotiation, further commands are under TLS layer>
+ S: * ACAP (SASL "CRAM-MD5" "PLAIN" "EXTERNAL")
+ C: a003 AUTHENTICATE "PLAIN" {21+}
+ C: <NUL>tim<NUL>tanstaaftanstaaf
+ S: a003 OK CRAM-MD5 password initialized
+
+ Note: In this example, <NUL> represents a single ASCII NUL octet.
+
+7. imaps and pop3s ports
+
+ Separate "imaps" and "pop3s" ports were registered for use with SSL.
+ Use of these ports is discouraged in favor of the STARTTLS or STLS
+ commands.
+
+ A number of problems have been observed with separate ports for
+ "secure" variants of protocols. This is an attempt to enumerate some
+ of those problems.
+
+ - Separate ports lead to a separate URL scheme which intrudes into
+ the user interface in inappropriate ways. For example, many web
+ pages use language like "click here if your browser supports SSL."
+ This is a decision the browser is often more capable of making than
+ the user.
+
+ - Separate ports imply a model of either "secure" or "not secure."
+ This can be misleading in a number of ways. First, the "secure"
+ port may not in fact be acceptably secure as an export-crippled
+ cipher suite might be in use. This can mislead users into a false
+ sense of security. Second, the normal port might in fact be
+ secured by using a SASL mechanism which includes a security layer.
+ Thus the separate port distinction makes the complex topic of
+ security policy even more confusing. One common result of this
+ confusion is that firewall administrators are often misled into
+
+
+
+Newman Standards Track [Page 9]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+ permitting the "secure" port and blocking the standard port. This
+ could be a poor choice given the common use of SSL with a 40-bit
+ key encryption layer and plain-text password authentication is less
+ secure than strong SASL mechanisms such as GSSAPI with Kerberos 5.
+
+ - Use of separate ports for SSL has caused clients to implement only
+ two security policies: use SSL or don't use SSL. The desirable
+ security policy "use TLS when available" would be cumbersome with
+ the separate port model, but is simple with STARTTLS.
+
+ - Port numbers are a limited resource. While they are not yet in
+ short supply, it is unwise to set a precedent that could double (or
+ worse) the speed of their consumption.
+
+
+8. IANA Considerations
+
+ This constitutes registration of the "STARTTLS" and "LOGINDISABLED"
+ IMAP capabilities as required by section 7.2.1 of RFC 2060 [IMAP].
+
+ The registration for the POP3 "STLS" capability follows:
+
+ CAPA tag: STLS
+ Arguments: none
+ Added commands: STLS
+ Standard commands affected: May enable USER/PASS as a side-effect.
+ CAPA command SHOULD be re-issued after successful completion.
+ Announced states/Valid states: AUTHORIZATION state only.
+ Specification reference: this memo
+
+ The registration for the ACAP "STARTTLS" capability follows:
+
+ Capability name: STARTTLS
+ Capability keyword: STARTTLS
+ Capability arguments: none
+ Published Specification(s): this memo
+ Person and email address for further information:
+ see author's address section below
+
+ The registration for the PLAIN SASL mechanism follows:
+
+ SASL mechanism name: PLAIN
+ Security Considerations: See section 9 of this memo
+ Published specification: this memo
+ Person & email address to contact for further information:
+ see author's address section below
+ Intended usage: COMMON
+ Author/Change controller: see author's address section below
+
+
+
+Newman Standards Track [Page 10]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+9. Security Considerations
+
+ TLS only provides protection for data sent over a network connection.
+ Messages transferred over IMAP or POP3 are still available to server
+ administrators and usually subject to eavesdropping, tampering and
+ forgery when transmitted through SMTP or NNTP. TLS is no substitute
+ for an end-to-end message security mechanism using MIME security
+ multiparts [MIME-SEC].
+
+ A man-in-the-middle attacker can remove STARTTLS from the capability
+ list or generate a failure response to the STARTTLS command. In
+ order to detect such an attack, clients SHOULD warn the user when
+ session privacy is not active and/or be configurable to refuse to
+ proceed without an acceptable level of security.
+
+ A man-in-the-middle attacker can always cause a down-negotiation to
+ the weakest authentication mechanism or cipher suite available. For
+ this reason, implementations SHOULD be configurable to refuse weak
+ mechanisms or cipher suites.
+
+ Any protocol interactions prior to the TLS handshake are performed in
+ the clear and can be modified by a man-in-the-middle attacker. For
+ this reason, clients MUST discard cached information about server
+ capabilities advertised prior to the start of the TLS handshake.
+
+ Clients are encouraged to clearly indicate when the level of
+ encryption active is known to be vulnerable to attack using modern
+ hardware (such as encryption keys with 56 bits of entropy or less).
+
+ The LOGINDISABLED IMAP capability (discussed in section 3.2) only
+ reduces the potential for passive attacks, it provides no protection
+ against active attacks. The responsibility remains with the client
+ to avoid sending a password over a vulnerable channel.
+
+ The PLAIN mechanism relies on the TLS encryption layer for security.
+ When used without TLS, it is vulnerable to a common network
+ eavesdropping attack. Therefore PLAIN MUST NOT be advertised or used
+ unless a suitable TLS encryption layer is active or backwards
+ compatibility dictates otherwise.
+
+ When the PLAIN mechanism is used, the server gains the ability to
+ impersonate the user to all services with the same password
+ regardless of any encryption provided by TLS or other network privacy
+ mechanisms. While many other authentication mechanisms have similar
+ weaknesses, stronger SASL mechanisms such as Kerberos address this
+ issue. Clients are encouraged to have an operational mode where all
+ mechanisms which are likely to reveal the user's password to the
+ server are disabled.
+
+
+
+Newman Standards Track [Page 11]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+ The security considerations for TLS apply to STARTTLS and the
+ security considerations for SASL apply to the PLAIN mechanism.
+ Additional security requirements are discussed in section 2.
+
+10. References
+
+ [ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax
+ Specifications: ABNF", RFC 2234, November 1997.
+
+ [ACAP] Newman, C. and J. Myers, "ACAP -- Application
+ Configuration Access Protocol", RFC 2244, November 1997.
+
+ [AUTH] Haller, N. and R. Atkinson, "On Internet Authentication",
+ RFC 1704, October 1994.
+
+ [CRAM-MD5] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP
+ AUTHorize Extension for Simple Challenge/Response", RFC
+ 2195, September 1997.
+
+ [IMAP] Crispin, M., "Internet Message Access Protocol - Version
+ 4rev1", RFC 2060, December 1996.
+
+ [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [MIME-SEC] Galvin, J., Murphy, S., Crocker, S. and N. Freed,
+ "Security Multiparts for MIME: Multipart/Signed and
+ Multipart/Encrypted", RFC 1847, October 1995.
+
+ [POP3] Myers, J. and M. Rose, "Post Office Protocol - Version 3",
+ STD 53, RFC 1939, May 1996.
+
+ [POP3EXT] Gellens, R., Newman, C. and L. Lundblade, "POP3 Extension
+ Mechanism", RFC 2449, November 1998.
+
+ [POP-AUTH] Myers, J., "POP3 AUTHentication command", RFC 1734,
+ December 1994.
+
+ [SASL] Myers, J., "Simple Authentication and Security Layer
+ (SASL)", RFC 2222, October 1997.
+
+ [SMTPTLS] Hoffman, P., "SMTP Service Extension for Secure SMTP over
+ TLS", RFC 2487, January 1999.
+
+ [TLS] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0",
+ RFC 2246, January 1999.
+
+
+
+
+
+Newman Standards Track [Page 12]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+ [UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO
+ 10646", RFC 2279, January 1998.
+
+
+11. Author's Address
+
+ Chris Newman
+ Innosoft International, Inc.
+ 1050 Lakes Drive
+ West Covina, CA 91790 USA
+
+ EMail: chris.newman@innosoft.com
+
+
+A. Appendix -- Compliance Checklist
+
+ An implementation is not compliant if it fails to satisfy one or more
+ of the MUST requirements for the protocols it implements. An
+ implementation that satisfies all the MUST and all the SHOULD
+ requirements for its protocols is said to be "unconditionally
+ compliant"; one that satisfies all the MUST requirements but not all
+ the SHOULD requirements for its protocols is said to be
+ "conditionally compliant".
+
+ Rules Section
+ ----- -------
+ Mandatory-to-implement Cipher Suite 2.1
+ SHOULD have mode where encryption required 2.2
+ server SHOULD have mode where TLS not required 2.2
+ MUST be configurable to refuse all clear-text login
+ commands or mechanisms 2.3
+ server SHOULD be configurable to refuse clear-text
+ login commands on entire server and on per-user basis 2.3
+ client MUST check server identity 2.4
+ client MUST use hostname used to open connection 2.4
+ client MUST NOT use hostname from insecure remote lookup 2.4
+ client SHOULD support subjectAltName of dNSName type 2.4
+ client SHOULD ask for confirmation or terminate on fail 2.4
+ MUST check result of STARTTLS for acceptable privacy 2.5
+ client MUST NOT issue commands after STARTTLS
+ until server response and negotiation done 3.1,4,5.1
+ client MUST discard cached information 3.1,4,5.1,9
+ client SHOULD re-issue CAPABILITY/CAPA command 3.1,4
+ IMAP server with STARTTLS MUST implement LOGINDISABLED 3.2
+ IMAP client MUST NOT issue LOGIN if LOGINDISABLED 3.2
+ POP server MUST implement POP3 extensions 4
+ ACAP server MUST re-issue ACAP greeting 5.1
+
+
+
+
+Newman Standards Track [Page 13]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+ client SHOULD warn when session privacy not active and/or
+ refuse to proceed without acceptable security level 9
+ SHOULD be configurable to refuse weak mechanisms or
+ cipher suites 9
+
+ The PLAIN mechanism is an optional part of this specification.
+ However if it is implemented the following rules apply:
+
+ Rules Section
+ ----- -------
+ MUST NOT use PLAIN unless strong encryption active
+ or backwards compatibility dictates otherwise 6,9
+ MUST use UTF-8 encoding for characters in PLAIN 6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Newman Standards Track [Page 14]
+
+RFC 2595 Using TLS with IMAP, POP3 and ACAP June 1999
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Newman Standards Track [Page 15]
+
diff --git a/standards/rfc2616.txt b/standards/rfc2616.txt
new file mode 100644
index 000000000..45d7d08b8
--- /dev/null
+++ b/standards/rfc2616.txt
@@ -0,0 +1,9859 @@
+
+
+
+
+
+
+Network Working Group R. Fielding
+Request for Comments: 2616 UC Irvine
+Obsoletes: 2068 J. Gettys
+Category: Standards Track Compaq/W3C
+ J. Mogul
+ Compaq
+ H. Frystyk
+ W3C/MIT
+ L. Masinter
+ Xerox
+ P. Leach
+ Microsoft
+ T. Berners-Lee
+ W3C/MIT
+ June 1999
+
+
+ Hypertext Transfer Protocol -- HTTP/1.1
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+Abstract
+
+ The Hypertext Transfer Protocol (HTTP) is an application-level
+ protocol for distributed, collaborative, hypermedia information
+ systems. It is a generic, stateless, protocol which can be used for
+ many tasks beyond its use for hypertext, such as name servers and
+ distributed object management systems, through extension of its
+ request methods, error codes and headers [47]. A feature of HTTP is
+ the typing and negotiation of data representation, allowing systems
+ to be built independently of the data being transferred.
+
+ HTTP has been in use by the World-Wide Web global information
+ initiative since 1990. This specification defines the protocol
+ referred to as "HTTP/1.1", and is an update to RFC 2068 [33].
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 1]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+Table of Contents
+
+ 1 Introduction ...................................................7
+ 1.1 Purpose......................................................7
+ 1.2 Requirements .................................................8
+ 1.3 Terminology ..................................................8
+ 1.4 Overall Operation ...........................................12
+ 2 Notational Conventions and Generic Grammar ....................14
+ 2.1 Augmented BNF ...............................................14
+ 2.2 Basic Rules .................................................15
+ 3 Protocol Parameters ...........................................17
+ 3.1 HTTP Version ................................................17
+ 3.2 Uniform Resource Identifiers ................................18
+ 3.2.1 General Syntax ...........................................19
+ 3.2.2 http URL .................................................19
+ 3.2.3 URI Comparison ...........................................20
+ 3.3 Date/Time Formats ...........................................20
+ 3.3.1 Full Date ................................................20
+ 3.3.2 Delta Seconds ............................................21
+ 3.4 Character Sets ..............................................21
+ 3.4.1 Missing Charset ..........................................22
+ 3.5 Content Codings .............................................23
+ 3.6 Transfer Codings ............................................24
+ 3.6.1 Chunked Transfer Coding ..................................25
+ 3.7 Media Types .................................................26
+ 3.7.1 Canonicalization and Text Defaults .......................27
+ 3.7.2 Multipart Types ..........................................27
+ 3.8 Product Tokens ..............................................28
+ 3.9 Quality Values ..............................................29
+ 3.10 Language Tags ...............................................29
+ 3.11 Entity Tags .................................................30
+ 3.12 Range Units .................................................30
+ 4 HTTP Message ..................................................31
+ 4.1 Message Types ...............................................31
+ 4.2 Message Headers .............................................31
+ 4.3 Message Body ................................................32
+ 4.4 Message Length ..............................................33
+ 4.5 General Header Fields .......................................34
+ 5 Request .......................................................35
+ 5.1 Request-Line ................................................35
+ 5.1.1 Method ...................................................36
+ 5.1.2 Request-URI ..............................................36
+ 5.2 The Resource Identified by a Request ........................38
+ 5.3 Request Header Fields .......................................38
+ 6 Response ......................................................39
+ 6.1 Status-Line .................................................39
+ 6.1.1 Status Code and Reason Phrase ............................39
+ 6.2 Response Header Fields ......................................41
+
+
+
+Fielding, et al. Standards Track [Page 2]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 7 Entity ........................................................42
+ 7.1 Entity Header Fields ........................................42
+ 7.2 Entity Body .................................................43
+ 7.2.1 Type .....................................................43
+ 7.2.2 Entity Length ............................................43
+ 8 Connections ...................................................44
+ 8.1 Persistent Connections ......................................44
+ 8.1.1 Purpose ..................................................44
+ 8.1.2 Overall Operation ........................................45
+ 8.1.3 Proxy Servers ............................................46
+ 8.1.4 Practical Considerations .................................46
+ 8.2 Message Transmission Requirements ...........................47
+ 8.2.1 Persistent Connections and Flow Control ..................47
+ 8.2.2 Monitoring Connections for Error Status Messages .........48
+ 8.2.3 Use of the 100 (Continue) Status .........................48
+ 8.2.4 Client Behavior if Server Prematurely Closes Connection ..50
+ 9 Method Definitions ............................................51
+ 9.1 Safe and Idempotent Methods .................................51
+ 9.1.1 Safe Methods .............................................51
+ 9.1.2 Idempotent Methods .......................................51
+ 9.2 OPTIONS .....................................................52
+ 9.3 GET .........................................................53
+ 9.4 HEAD ........................................................54
+ 9.5 POST ........................................................54
+ 9.6 PUT .........................................................55
+ 9.7 DELETE ......................................................56
+ 9.8 TRACE .......................................................56
+ 9.9 CONNECT .....................................................57
+ 10 Status Code Definitions ......................................57
+ 10.1 Informational 1xx ...........................................57
+ 10.1.1 100 Continue .............................................58
+ 10.1.2 101 Switching Protocols ..................................58
+ 10.2 Successful 2xx ..............................................58
+ 10.2.1 200 OK ...................................................58
+ 10.2.2 201 Created ..............................................59
+ 10.2.3 202 Accepted .............................................59
+ 10.2.4 203 Non-Authoritative Information ........................59
+ 10.2.5 204 No Content ...........................................60
+ 10.2.6 205 Reset Content ........................................60
+ 10.2.7 206 Partial Content ......................................60
+ 10.3 Redirection 3xx .............................................61
+ 10.3.1 300 Multiple Choices .....................................61
+ 10.3.2 301 Moved Permanently ....................................62
+ 10.3.3 302 Found ................................................62
+ 10.3.4 303 See Other ............................................63
+ 10.3.5 304 Not Modified .........................................63
+ 10.3.6 305 Use Proxy ............................................64
+ 10.3.7 306 (Unused) .............................................64
+
+
+
+Fielding, et al. Standards Track [Page 3]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 10.3.8 307 Temporary Redirect ...................................65
+ 10.4 Client Error 4xx ............................................65
+ 10.4.1 400 Bad Request .........................................65
+ 10.4.2 401 Unauthorized ........................................66
+ 10.4.3 402 Payment Required ....................................66
+ 10.4.4 403 Forbidden ...........................................66
+ 10.4.5 404 Not Found ...........................................66
+ 10.4.6 405 Method Not Allowed ..................................66
+ 10.4.7 406 Not Acceptable ......................................67
+ 10.4.8 407 Proxy Authentication Required .......................67
+ 10.4.9 408 Request Timeout .....................................67
+ 10.4.10 409 Conflict ............................................67
+ 10.4.11 410 Gone ................................................68
+ 10.4.12 411 Length Required .....................................68
+ 10.4.13 412 Precondition Failed .................................68
+ 10.4.14 413 Request Entity Too Large ............................69
+ 10.4.15 414 Request-URI Too Long ................................69
+ 10.4.16 415 Unsupported Media Type ..............................69
+ 10.4.17 416 Requested Range Not Satisfiable .....................69
+ 10.4.18 417 Expectation Failed ..................................70
+ 10.5 Server Error 5xx ............................................70
+ 10.5.1 500 Internal Server Error ................................70
+ 10.5.2 501 Not Implemented ......................................70
+ 10.5.3 502 Bad Gateway ..........................................70
+ 10.5.4 503 Service Unavailable ..................................70
+ 10.5.5 504 Gateway Timeout ......................................71
+ 10.5.6 505 HTTP Version Not Supported ...........................71
+ 11 Access Authentication ........................................71
+ 12 Content Negotiation ..........................................71
+ 12.1 Server-driven Negotiation ...................................72
+ 12.2 Agent-driven Negotiation ....................................73
+ 12.3 Transparent Negotiation .....................................74
+ 13 Caching in HTTP ..............................................74
+ 13.1.1 Cache Correctness ........................................75
+ 13.1.2 Warnings .................................................76
+ 13.1.3 Cache-control Mechanisms .................................77
+ 13.1.4 Explicit User Agent Warnings .............................78
+ 13.1.5 Exceptions to the Rules and Warnings .....................78
+ 13.1.6 Client-controlled Behavior ...............................79
+ 13.2 Expiration Model ............................................79
+ 13.2.1 Server-Specified Expiration ..............................79
+ 13.2.2 Heuristic Expiration .....................................80
+ 13.2.3 Age Calculations .........................................80
+ 13.2.4 Expiration Calculations ..................................83
+ 13.2.5 Disambiguating Expiration Values .........................84
+ 13.2.6 Disambiguating Multiple Responses ........................84
+ 13.3 Validation Model ............................................85
+ 13.3.1 Last-Modified Dates ......................................86
+
+
+
+Fielding, et al. Standards Track [Page 4]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 13.3.2 Entity Tag Cache Validators ..............................86
+ 13.3.3 Weak and Strong Validators ...............................86
+ 13.3.4 Rules for When to Use Entity Tags and Last-Modified Dates.89
+ 13.3.5 Non-validating Conditionals ..............................90
+ 13.4 Response Cacheability .......................................91
+ 13.5 Constructing Responses From Caches ..........................92
+ 13.5.1 End-to-end and Hop-by-hop Headers ........................92
+ 13.5.2 Non-modifiable Headers ...................................92
+ 13.5.3 Combining Headers ........................................94
+ 13.5.4 Combining Byte Ranges ....................................95
+ 13.6 Caching Negotiated Responses ................................95
+ 13.7 Shared and Non-Shared Caches ................................96
+ 13.8 Errors or Incomplete Response Cache Behavior ................97
+ 13.9 Side Effects of GET and HEAD ................................97
+ 13.10 Invalidation After Updates or Deletions ...................97
+ 13.11 Write-Through Mandatory ...................................98
+ 13.12 Cache Replacement .........................................99
+ 13.13 History Lists .............................................99
+ 14 Header Field Definitions ....................................100
+ 14.1 Accept .....................................................100
+ 14.2 Accept-Charset .............................................102
+ 14.3 Accept-Encoding ............................................102
+ 14.4 Accept-Language ............................................104
+ 14.5 Accept-Ranges ..............................................105
+ 14.6 Age ........................................................106
+ 14.7 Allow ......................................................106
+ 14.8 Authorization ..............................................107
+ 14.9 Cache-Control ..............................................108
+ 14.9.1 What is Cacheable .......................................109
+ 14.9.2 What May be Stored by Caches ............................110
+ 14.9.3 Modifications of the Basic Expiration Mechanism .........111
+ 14.9.4 Cache Revalidation and Reload Controls ..................113
+ 14.9.5 No-Transform Directive ..................................115
+ 14.9.6 Cache Control Extensions ................................116
+ 14.10 Connection ...............................................117
+ 14.11 Content-Encoding .........................................118
+ 14.12 Content-Language .........................................118
+ 14.13 Content-Length ...........................................119
+ 14.14 Content-Location .........................................120
+ 14.15 Content-MD5 ..............................................121
+ 14.16 Content-Range ............................................122
+ 14.17 Content-Type .............................................124
+ 14.18 Date .....................................................124
+ 14.18.1 Clockless Origin Server Operation ......................125
+ 14.19 ETag .....................................................126
+ 14.20 Expect ...................................................126
+ 14.21 Expires ..................................................127
+ 14.22 From .....................................................128
+
+
+
+Fielding, et al. Standards Track [Page 5]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 14.23 Host .....................................................128
+ 14.24 If-Match .................................................129
+ 14.25 If-Modified-Since ........................................130
+ 14.26 If-None-Match ............................................132
+ 14.27 If-Range .................................................133
+ 14.28 If-Unmodified-Since ......................................134
+ 14.29 Last-Modified ............................................134
+ 14.30 Location .................................................135
+ 14.31 Max-Forwards .............................................136
+ 14.32 Pragma ...................................................136
+ 14.33 Proxy-Authenticate .......................................137
+ 14.34 Proxy-Authorization ......................................137
+ 14.35 Range ....................................................138
+ 14.35.1 Byte Ranges ...........................................138
+ 14.35.2 Range Retrieval Requests ..............................139
+ 14.36 Referer ..................................................140
+ 14.37 Retry-After ..............................................141
+ 14.38 Server ...................................................141
+ 14.39 TE .......................................................142
+ 14.40 Trailer ..................................................143
+ 14.41 Transfer-Encoding..........................................143
+ 14.42 Upgrade ..................................................144
+ 14.43 User-Agent ...............................................145
+ 14.44 Vary .....................................................145
+ 14.45 Via ......................................................146
+ 14.46 Warning ..................................................148
+ 14.47 WWW-Authenticate .........................................150
+ 15 Security Considerations .......................................150
+ 15.1 Personal Information....................................151
+ 15.1.1 Abuse of Server Log Information .........................151
+ 15.1.2 Transfer of Sensitive Information .......................151
+ 15.1.3 Encoding Sensitive Information in URI's .................152
+ 15.1.4 Privacy Issues Connected to Accept Headers ..............152
+ 15.2 Attacks Based On File and Path Names .......................153
+ 15.3 DNS Spoofing ...............................................154
+ 15.4 Location Headers and Spoofing ..............................154
+ 15.5 Content-Disposition Issues .................................154
+ 15.6 Authentication Credentials and Idle Clients ................155
+ 15.7 Proxies and Caching ........................................155
+ 15.7.1 Denial of Service Attacks on Proxies....................156
+ 16 Acknowledgments .............................................156
+ 17 References ..................................................158
+ 18 Authors' Addresses ..........................................162
+ 19 Appendices ..................................................164
+ 19.1 Internet Media Type message/http and application/http ......164
+ 19.2 Internet Media Type multipart/byteranges ...................165
+ 19.3 Tolerant Applications ......................................166
+ 19.4 Differences Between HTTP Entities and RFC 2045 Entities ....167
+
+
+
+Fielding, et al. Standards Track [Page 6]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 19.4.1 MIME-Version ............................................167
+ 19.4.2 Conversion to Canonical Form ............................167
+ 19.4.3 Conversion of Date Formats ..............................168
+ 19.4.4 Introduction of Content-Encoding ........................168
+ 19.4.5 No Content-Transfer-Encoding ............................168
+ 19.4.6 Introduction of Transfer-Encoding .......................169
+ 19.4.7 MHTML and Line Length Limitations .......................169
+ 19.5 Additional Features ........................................169
+ 19.5.1 Content-Disposition .....................................170
+ 19.6 Compatibility with Previous Versions .......................170
+ 19.6.1 Changes from HTTP/1.0 ...................................171
+ 19.6.2 Compatibility with HTTP/1.0 Persistent Connections ......172
+ 19.6.3 Changes from RFC 2068 ...................................172
+ 20 Index .......................................................175
+ 21 Full Copyright Statement ....................................176
+
+1 Introduction
+
+1.1 Purpose
+
+ The Hypertext Transfer Protocol (HTTP) is an application-level
+ protocol for distributed, collaborative, hypermedia information
+ systems. HTTP has been in use by the World-Wide Web global
+ information initiative since 1990. The first version of HTTP,
+ referred to as HTTP/0.9, was a simple protocol for raw data transfer
+ across the Internet. HTTP/1.0, as defined by RFC 1945 [6], improved
+ the protocol by allowing messages to be in the format of MIME-like
+ messages, containing metainformation about the data transferred and
+ modifiers on the request/response semantics. However, HTTP/1.0 does
+ not sufficiently take into consideration the effects of hierarchical
+ proxies, caching, the need for persistent connections, or virtual
+ hosts. In addition, the proliferation of incompletely-implemented
+ applications calling themselves "HTTP/1.0" has necessitated a
+ protocol version change in order for two communicating applications
+ to determine each other's true capabilities.
+
+ This specification defines the protocol referred to as "HTTP/1.1".
+ This protocol includes more stringent requirements than HTTP/1.0 in
+ order to ensure reliable implementation of its features.
+
+ Practical information systems require more functionality than simple
+ retrieval, including search, front-end update, and annotation. HTTP
+ allows an open-ended set of methods and headers that indicate the
+ purpose of a request [47]. It builds on the discipline of reference
+ provided by the Uniform Resource Identifier (URI) [3], as a location
+ (URL) [4] or name (URN) [20], for indicating the resource to which a
+
+
+
+
+
+Fielding, et al. Standards Track [Page 7]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ method is to be applied. Messages are passed in a format similar to
+ that used by Internet mail [9] as defined by the Multipurpose
+ Internet Mail Extensions (MIME) [7].
+
+ HTTP is also used as a generic protocol for communication between
+ user agents and proxies/gateways to other Internet systems, including
+ those supported by the SMTP [16], NNTP [13], FTP [18], Gopher [2],
+ and WAIS [10] protocols. In this way, HTTP allows basic hypermedia
+ access to resources available from diverse applications.
+
+1.2 Requirements
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in RFC 2119 [34].
+
+ An implementation is not compliant if it fails to satisfy one or more
+ of the MUST or REQUIRED level requirements for the protocols it
+ implements. An implementation that satisfies all the MUST or REQUIRED
+ level and all the SHOULD level requirements for its protocols is said
+ to be "unconditionally compliant"; one that satisfies all the MUST
+ level requirements but not all the SHOULD level requirements for its
+ protocols is said to be "conditionally compliant."
+
+1.3 Terminology
+
+ This specification uses a number of terms to refer to the roles
+ played by participants in, and objects of, the HTTP communication.
+
+ connection
+ A transport layer virtual circuit established between two programs
+ for the purpose of communication.
+
+ message
+ The basic unit of HTTP communication, consisting of a structured
+ sequence of octets matching the syntax defined in section 4 and
+ transmitted via the connection.
+
+ request
+ An HTTP request message, as defined in section 5.
+
+ response
+ An HTTP response message, as defined in section 6.
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 8]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ resource
+ A network data object or service that can be identified by a URI,
+ as defined in section 3.2. Resources may be available in multiple
+ representations (e.g. multiple languages, data formats, size, and
+ resolutions) or vary in other ways.
+
+ entity
+ The information transferred as the payload of a request or
+ response. An entity consists of metainformation in the form of
+ entity-header fields and content in the form of an entity-body, as
+ described in section 7.
+
+ representation
+ An entity included with a response that is subject to content
+ negotiation, as described in section 12. There may exist multiple
+ representations associated with a particular response status.
+
+ content negotiation
+ The mechanism for selecting the appropriate representation when
+ servicing a request, as described in section 12. The
+ representation of entities in any response can be negotiated
+ (including error responses).
+
+ variant
+ A resource may have one, or more than one, representation(s)
+ associated with it at any given instant. Each of these
+ representations is termed a `varriant'. Use of the term `variant'
+ does not necessarily imply that the resource is subject to content
+ negotiation.
+
+ client
+ A program that establishes connections for the purpose of sending
+ requests.
+
+ user agent
+ The client which initiates a request. These are often browsers,
+ editors, spiders (web-traversing robots), or other end user tools.
+
+ server
+ An application program that accepts connections in order to
+ service requests by sending back responses. Any given program may
+ be capable of being both a client and a server; our use of these
+ terms refers only to the role being performed by the program for a
+ particular connection, rather than to the program's capabilities
+ in general. Likewise, any server may act as an origin server,
+ proxy, gateway, or tunnel, switching behavior based on the nature
+ of each request.
+
+
+
+
+Fielding, et al. Standards Track [Page 9]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ origin server
+ The server on which a given resource resides or is to be created.
+
+ proxy
+ An intermediary program which acts as both a server and a client
+ for the purpose of making requests on behalf of other clients.
+ Requests are serviced internally or by passing them on, with
+ possible translation, to other servers. A proxy MUST implement
+ both the client and server requirements of this specification. A
+ "transparent proxy" is a proxy that does not modify the request or
+ response beyond what is required for proxy authentication and
+ identification. A "non-transparent proxy" is a proxy that modifies
+ the request or response in order to provide some added service to
+ the user agent, such as group annotation services, media type
+ transformation, protocol reduction, or anonymity filtering. Except
+ where either transparent or non-transparent behavior is explicitly
+ stated, the HTTP proxy requirements apply to both types of
+ proxies.
+
+ gateway
+ A server which acts as an intermediary for some other server.
+ Unlike a proxy, a gateway receives requests as if it were the
+ origin server for the requested resource; the requesting client
+ may not be aware that it is communicating with a gateway.
+
+ tunnel
+ An intermediary program which is acting as a blind relay between
+ two connections. Once active, a tunnel is not considered a party
+ to the HTTP communication, though the tunnel may have been
+ initiated by an HTTP request. The tunnel ceases to exist when both
+ ends of the relayed connections are closed.
+
+ cache
+ A program's local store of response messages and the subsystem
+ that controls its message storage, retrieval, and deletion. A
+ cache stores cacheable responses in order to reduce the response
+ time and network bandwidth consumption on future, equivalent
+ requests. Any client or server may include a cache, though a cache
+ cannot be used by a server that is acting as a tunnel.
+
+ cacheable
+ A response is cacheable if a cache is allowed to store a copy of
+ the response message for use in answering subsequent requests. The
+ rules for determining the cacheability of HTTP responses are
+ defined in section 13. Even if a resource is cacheable, there may
+ be additional constraints on whether a cache can use the cached
+ copy for a particular request.
+
+
+
+
+Fielding, et al. Standards Track [Page 10]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ first-hand
+ A response is first-hand if it comes directly and without
+ unnecessary delay from the origin server, perhaps via one or more
+ proxies. A response is also first-hand if its validity has just
+ been checked directly with the origin server.
+
+ explicit expiration time
+ The time at which the origin server intends that an entity should
+ no longer be returned by a cache without further validation.
+
+ heuristic expiration time
+ An expiration time assigned by a cache when no explicit expiration
+ time is available.
+
+ age
+ The age of a response is the time since it was sent by, or
+ successfully validated with, the origin server.
+
+ freshness lifetime
+ The length of time between the generation of a response and its
+ expiration time.
+
+ fresh
+ A response is fresh if its age has not yet exceeded its freshness
+ lifetime.
+
+ stale
+ A response is stale if its age has passed its freshness lifetime.
+
+ semantically transparent
+ A cache behaves in a "semantically transparent" manner, with
+ respect to a particular response, when its use affects neither the
+ requesting client nor the origin server, except to improve
+ performance. When a cache is semantically transparent, the client
+ receives exactly the same response (except for hop-by-hop headers)
+ that it would have received had its request been handled directly
+ by the origin server.
+
+ validator
+ A protocol element (e.g., an entity tag or a Last-Modified time)
+ that is used to find out whether a cache entry is an equivalent
+ copy of an entity.
+
+ upstream/downstream
+ Upstream and downstream describe the flow of a message: all
+ messages flow from upstream to downstream.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 11]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ inbound/outbound
+ Inbound and outbound refer to the request and response paths for
+ messages: "inbound" means "traveling toward the origin server",
+ and "outbound" means "traveling toward the user agent"
+
+1.4 Overall Operation
+
+ The HTTP protocol is a request/response protocol. A client sends a
+ request to the server in the form of a request method, URI, and
+ protocol version, followed by a MIME-like message containing request
+ modifiers, client information, and possible body content over a
+ connection with a server. The server responds with a status line,
+ including the message's protocol version and a success or error code,
+ followed by a MIME-like message containing server information, entity
+ metainformation, and possible entity-body content. The relationship
+ between HTTP and MIME is described in appendix 19.4.
+
+ Most HTTP communication is initiated by a user agent and consists of
+ a request to be applied to a resource on some origin server. In the
+ simplest case, this may be accomplished via a single connection (v)
+ between the user agent (UA) and the origin server (O).
+
+ request chain ------------------------>
+ UA -------------------v------------------- O
+ <----------------------- response chain
+
+ A more complicated situation occurs when one or more intermediaries
+ are present in the request/response chain. There are three common
+ forms of intermediary: proxy, gateway, and tunnel. A proxy is a
+ forwarding agent, receiving requests for a URI in its absolute form,
+ rewriting all or part of the message, and forwarding the reformatted
+ request toward the server identified by the URI. A gateway is a
+ receiving agent, acting as a layer above some other server(s) and, if
+ necessary, translating the requests to the underlying server's
+ protocol. A tunnel acts as a relay point between two connections
+ without changing the messages; tunnels are used when the
+ communication needs to pass through an intermediary (such as a
+ firewall) even when the intermediary cannot understand the contents
+ of the messages.
+
+ request chain -------------------------------------->
+ UA -----v----- A -----v----- B -----v----- C -----v----- O
+ <------------------------------------- response chain
+
+ The figure above shows three intermediaries (A, B, and C) between the
+ user agent and origin server. A request or response message that
+ travels the whole chain will pass through four separate connections.
+ This distinction is important because some HTTP communication options
+
+
+
+Fielding, et al. Standards Track [Page 12]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ may apply only to the connection with the nearest, non-tunnel
+ neighbor, only to the end-points of the chain, or to all connections
+ along the chain. Although the diagram is linear, each participant may
+ be engaged in multiple, simultaneous communications. For example, B
+ may be receiving requests from many clients other than A, and/or
+ forwarding requests to servers other than C, at the same time that it
+ is handling A's request.
+
+ Any party to the communication which is not acting as a tunnel may
+ employ an internal cache for handling requests. The effect of a cache
+ is that the request/response chain is shortened if one of the
+ participants along the chain has a cached response applicable to that
+ request. The following illustrates the resulting chain if B has a
+ cached copy of an earlier response from O (via C) for a request which
+ has not been cached by UA or A.
+
+ request chain ---------->
+ UA -----v----- A -----v----- B - - - - - - C - - - - - - O
+ <--------- response chain
+
+ Not all responses are usefully cacheable, and some requests may
+ contain modifiers which place special requirements on cache behavior.
+ HTTP requirements for cache behavior and cacheable responses are
+ defined in section 13.
+
+ In fact, there are a wide variety of architectures and configurations
+ of caches and proxies currently being experimented with or deployed
+ across the World Wide Web. These systems include national hierarchies
+ of proxy caches to save transoceanic bandwidth, systems that
+ broadcast or multicast cache entries, organizations that distribute
+ subsets of cached data via CD-ROM, and so on. HTTP systems are used
+ in corporate intranets over high-bandwidth links, and for access via
+ PDAs with low-power radio links and intermittent connectivity. The
+ goal of HTTP/1.1 is to support the wide diversity of configurations
+ already deployed while introducing protocol constructs that meet the
+ needs of those who build web applications that require high
+ reliability and, failing that, at least reliable indications of
+ failure.
+
+ HTTP communication usually takes place over TCP/IP connections. The
+ default port is TCP 80 [19], but other ports can be used. This does
+ not preclude HTTP from being implemented on top of any other protocol
+ on the Internet, or on other networks. HTTP only presumes a reliable
+ transport; any protocol that provides such guarantees can be used;
+ the mapping of the HTTP/1.1 request and response structures onto the
+ transport data units of the protocol in question is outside the scope
+ of this specification.
+
+
+
+
+Fielding, et al. Standards Track [Page 13]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ In HTTP/1.0, most implementations used a new connection for each
+ request/response exchange. In HTTP/1.1, a connection may be used for
+ one or more request/response exchanges, although connections may be
+ closed for a variety of reasons (see section 8.1).
+
+2 Notational Conventions and Generic Grammar
+
+2.1 Augmented BNF
+
+ All of the mechanisms specified in this document are described in
+ both prose and an augmented Backus-Naur Form (BNF) similar to that
+ used by RFC 822 [9]. Implementors will need to be familiar with the
+ notation in order to understand this specification. The augmented BNF
+ includes the following constructs:
+
+ name = definition
+ The name of a rule is simply the name itself (without any
+ enclosing "<" and ">") and is separated from its definition by the
+ equal "=" character. White space is only significant in that
+ indentation of continuation lines is used to indicate a rule
+ definition that spans more than one line. Certain basic rules are
+ in uppercase, such as SP, LWS, HT, CRLF, DIGIT, ALPHA, etc. Angle
+ brackets are used within definitions whenever their presence will
+ facilitate discerning the use of rule names.
+
+ "literal"
+ Quotation marks surround literal text. Unless stated otherwise,
+ the text is case-insensitive.
+
+ rule1 | rule2
+ Elements separated by a bar ("|") are alternatives, e.g., "yes |
+ no" will accept yes or no.
+
+ (rule1 rule2)
+ Elements enclosed in parentheses are treated as a single element.
+ Thus, "(elem (foo | bar) elem)" allows the token sequences "elem
+ foo elem" and "elem bar elem".
+
+ *rule
+ The character "*" preceding an element indicates repetition. The
+ full form is "<n>*<m>element" indicating at least <n> and at most
+ <m> occurrences of element. Default values are 0 and infinity so
+ that "*(element)" allows any number, including zero; "1*element"
+ requires at least one; and "1*2element" allows one or two.
+
+ [rule]
+ Square brackets enclose optional elements; "[foo bar]" is
+ equivalent to "*1(foo bar)".
+
+
+
+Fielding, et al. Standards Track [Page 14]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ N rule
+ Specific repetition: "<n>(element)" is equivalent to
+ "<n>*<n>(element)"; that is, exactly <n> occurrences of (element).
+ Thus 2DIGIT is a 2-digit number, and 3ALPHA is a string of three
+ alphabetic characters.
+
+ #rule
+ A construct "#" is defined, similar to "*", for defining lists of
+ elements. The full form is "<n>#<m>element" indicating at least
+ <n> and at most <m> elements, each separated by one or more commas
+ (",") and OPTIONAL linear white space (LWS). This makes the usual
+ form of lists very easy; a rule such as
+ ( *LWS element *( *LWS "," *LWS element ))
+ can be shown as
+ 1#element
+ Wherever this construct is used, null elements are allowed, but do
+ not contribute to the count of elements present. That is,
+ "(element), , (element) " is permitted, but counts as only two
+ elements. Therefore, where at least one element is required, at
+ least one non-null element MUST be present. Default values are 0
+ and infinity so that "#element" allows any number, including zero;
+ "1#element" requires at least one; and "1#2element" allows one or
+ two.
+
+ ; comment
+ A semi-colon, set off some distance to the right of rule text,
+ starts a comment that continues to the end of line. This is a
+ simple way of including useful notes in parallel with the
+ specifications.
+
+ implied *LWS
+ The grammar described by this specification is word-based. Except
+ where noted otherwise, linear white space (LWS) can be included
+ between any two adjacent words (token or quoted-string), and
+ between adjacent words and separators, without changing the
+ interpretation of a field. At least one delimiter (LWS and/or
+
+ separators) MUST exist between any two tokens (for the definition
+ of "token" below), since they would otherwise be interpreted as a
+ single token.
+
+2.2 Basic Rules
+
+ The following rules are used throughout this specification to
+ describe basic parsing constructs. The US-ASCII coded character set
+ is defined by ANSI X3.4-1986 [21].
+
+
+
+
+
+Fielding, et al. Standards Track [Page 15]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ OCTET = <any 8-bit sequence of data>
+ CHAR = <any US-ASCII character (octets 0 - 127)>
+ UPALPHA = <any US-ASCII uppercase letter "A".."Z">
+ LOALPHA = <any US-ASCII lowercase letter "a".."z">
+ ALPHA = UPALPHA | LOALPHA
+ DIGIT = <any US-ASCII digit "0".."9">
+ CTL = <any US-ASCII control character
+ (octets 0 - 31) and DEL (127)>
+ CR = <US-ASCII CR, carriage return (13)>
+ LF = <US-ASCII LF, linefeed (10)>
+ SP = <US-ASCII SP, space (32)>
+ HT = <US-ASCII HT, horizontal-tab (9)>
+ <"> = <US-ASCII double-quote mark (34)>
+
+ HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all
+ protocol elements except the entity-body (see appendix 19.3 for
+ tolerant applications). The end-of-line marker within an entity-body
+ is defined by its associated media type, as described in section 3.7.
+
+ CRLF = CR LF
+
+ HTTP/1.1 header field values can be folded onto multiple lines if the
+ continuation line begins with a space or horizontal tab. All linear
+ white space, including folding, has the same semantics as SP. A
+ recipient MAY replace any linear white space with a single SP before
+ interpreting the field value or forwarding the message downstream.
+
+ LWS = [CRLF] 1*( SP | HT )
+
+ The TEXT rule is only used for descriptive field contents and values
+ that are not intended to be interpreted by the message parser. Words
+ of *TEXT MAY contain characters from character sets other than ISO-
+ 8859-1 [22] only when encoded according to the rules of RFC 2047
+ [14].
+
+ TEXT = <any OCTET except CTLs,
+ but including LWS>
+
+ A CRLF is allowed in the definition of TEXT only as part of a header
+ field continuation. It is expected that the folding LWS will be
+ replaced with a single SP before interpretation of the TEXT value.
+
+ Hexadecimal numeric characters are used in several protocol elements.
+
+ HEX = "A" | "B" | "C" | "D" | "E" | "F"
+ | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
+
+
+
+
+
+Fielding, et al. Standards Track [Page 16]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Many HTTP/1.1 header field values consist of words separated by LWS
+ or special characters. These special characters MUST be in a quoted
+ string to be used within a parameter value (as defined in section
+ 3.6).
+
+ token = 1*<any CHAR except CTLs or separators>
+ separators = "(" | ")" | "<" | ">" | "@"
+ | "," | ";" | ":" | "\" | <">
+ | "/" | "[" | "]" | "?" | "="
+ | "{" | "}" | SP | HT
+
+ Comments can be included in some HTTP header fields by surrounding
+ the comment text with parentheses. Comments are only allowed in
+ fields containing "comment" as part of their field value definition.
+ In all other fields, parentheses are considered part of the field
+ value.
+
+ comment = "(" *( ctext | quoted-pair | comment ) ")"
+ ctext = <any TEXT excluding "(" and ")">
+
+ A string of text is parsed as a single word if it is quoted using
+ double-quote marks.
+
+ quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
+ qdtext = <any TEXT except <">>
+
+ The backslash character ("\") MAY be used as a single-character
+ quoting mechanism only within quoted-string and comment constructs.
+
+ quoted-pair = "\" CHAR
+
+3 Protocol Parameters
+
+3.1 HTTP Version
+
+ HTTP uses a "<major>.<minor>" numbering scheme to indicate versions
+ of the protocol. The protocol versioning policy is intended to allow
+ the sender to indicate the format of a message and its capacity for
+ understanding further HTTP communication, rather than the features
+ obtained via that communication. No change is made to the version
+ number for the addition of message components which do not affect
+ communication behavior or which only add to extensible field values.
+ The <minor> number is incremented when the changes made to the
+ protocol add features which do not change the general message parsing
+ algorithm, but which may add to the message semantics and imply
+ additional capabilities of the sender. The <major> number is
+ incremented when the format of a message within the protocol is
+ changed. See RFC 2145 [36] for a fuller explanation.
+
+
+
+Fielding, et al. Standards Track [Page 17]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ The version of an HTTP message is indicated by an HTTP-Version field
+ in the first line of the message.
+
+ HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
+
+ Note that the major and minor numbers MUST be treated as separate
+ integers and that each MAY be incremented higher than a single digit.
+ Thus, HTTP/2.4 is a lower version than HTTP/2.13, which in turn is
+ lower than HTTP/12.3. Leading zeros MUST be ignored by recipients and
+ MUST NOT be sent.
+
+ An application that sends a request or response message that includes
+ HTTP-Version of "HTTP/1.1" MUST be at least conditionally compliant
+ with this specification. Applications that are at least conditionally
+ compliant with this specification SHOULD use an HTTP-Version of
+ "HTTP/1.1" in their messages, and MUST do so for any message that is
+ not compatible with HTTP/1.0. For more details on when to send
+ specific HTTP-Version values, see RFC 2145 [36].
+
+ The HTTP version of an application is the highest HTTP version for
+ which the application is at least conditionally compliant.
+
+ Proxy and gateway applications need to be careful when forwarding
+ messages in protocol versions different from that of the application.
+ Since the protocol version indicates the protocol capability of the
+ sender, a proxy/gateway MUST NOT send a message with a version
+ indicator which is greater than its actual version. If a higher
+ version request is received, the proxy/gateway MUST either downgrade
+ the request version, or respond with an error, or switch to tunnel
+ behavior.
+
+ Due to interoperability problems with HTTP/1.0 proxies discovered
+ since the publication of RFC 2068[33], caching proxies MUST, gateways
+ MAY, and tunnels MUST NOT upgrade the request to the highest version
+ they support. The proxy/gateway's response to that request MUST be in
+ the same major version as the request.
+
+ Note: Converting between versions of HTTP may involve modification
+ of header fields required or forbidden by the versions involved.
+
+3.2 Uniform Resource Identifiers
+
+ URIs have been known by many names: WWW addresses, Universal Document
+ Identifiers, Universal Resource Identifiers [3], and finally the
+ combination of Uniform Resource Locators (URL) [4] and Names (URN)
+ [20]. As far as HTTP is concerned, Uniform Resource Identifiers are
+ simply formatted strings which identify--via name, location, or any
+ other characteristic--a resource.
+
+
+
+Fielding, et al. Standards Track [Page 18]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+3.2.1 General Syntax
+
+ URIs in HTTP can be represented in absolute form or relative to some
+ known base URI [11], depending upon the context of their use. The two
+ forms are differentiated by the fact that absolute URIs always begin
+ with a scheme name followed by a colon. For definitive information on
+ URL syntax and semantics, see "Uniform Resource Identifiers (URI):
+ Generic Syntax and Semantics," RFC 2396 [42] (which replaces RFCs
+ 1738 [4] and RFC 1808 [11]). This specification adopts the
+ definitions of "URI-reference", "absoluteURI", "relativeURI", "port",
+ "host","abs_path", "rel_path", and "authority" from that
+ specification.
+
+ The HTTP protocol does not place any a priori limit on the length of
+ a URI. Servers MUST be able to handle the URI of any resource they
+ serve, and SHOULD be able to handle URIs of unbounded length if they
+ provide GET-based forms that could generate such URIs. A server
+ SHOULD return 414 (Request-URI Too Long) status if a URI is longer
+ than the server can handle (see section 10.4.15).
+
+ Note: Servers ought to be cautious about depending on URI lengths
+ above 255 bytes, because some older client or proxy
+ implementations might not properly support these lengths.
+
+3.2.2 http URL
+
+ The "http" scheme is used to locate network resources via the HTTP
+ protocol. This section defines the scheme-specific syntax and
+ semantics for http URLs.
+
+ http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
+
+ If the port is empty or not given, port 80 is assumed. The semantics
+ are that the identified resource is located at the server listening
+ for TCP connections on that port of that host, and the Request-URI
+ for the resource is abs_path (section 5.1.2). The use of IP addresses
+ in URLs SHOULD be avoided whenever possible (see RFC 1900 [24]). If
+ the abs_path is not present in the URL, it MUST be given as "/" when
+ used as a Request-URI for a resource (section 5.1.2). If a proxy
+ receives a host name which is not a fully qualified domain name, it
+ MAY add its domain to the host name it received. If a proxy receives
+ a fully qualified domain name, the proxy MUST NOT change the host
+ name.
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 19]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+3.2.3 URI Comparison
+
+ When comparing two URIs to decide if they match or not, a client
+ SHOULD use a case-sensitive octet-by-octet comparison of the entire
+ URIs, with these exceptions:
+
+ - A port that is empty or not given is equivalent to the default
+ port for that URI-reference;
+
+ - Comparisons of host names MUST be case-insensitive;
+
+ - Comparisons of scheme names MUST be case-insensitive;
+
+ - An empty abs_path is equivalent to an abs_path of "/".
+
+ Characters other than those in the "reserved" and "unsafe" sets (see
+ RFC 2396 [42]) are equivalent to their ""%" HEX HEX" encoding.
+
+ For example, the following three URIs are equivalent:
+
+ http://abc.com:80/~smith/home.html
+ http://ABC.com/%7Esmith/home.html
+ http://ABC.com:/%7esmith/home.html
+
+3.3 Date/Time Formats
+
+3.3.1 Full Date
+
+ HTTP applications have historically allowed three different formats
+ for the representation of date/time stamps:
+
+ Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
+ Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
+ Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
+
+ The first format is preferred as an Internet standard and represents
+ a fixed-length subset of that defined by RFC 1123 [8] (an update to
+ RFC 822 [9]). The second format is in common use, but is based on the
+ obsolete RFC 850 [12] date format and lacks a four-digit year.
+ HTTP/1.1 clients and servers that parse the date value MUST accept
+ all three formats (for compatibility with HTTP/1.0), though they MUST
+ only generate the RFC 1123 format for representing HTTP-date values
+ in header fields. See section 19.3 for further information.
+
+ Note: Recipients of date values are encouraged to be robust in
+ accepting date values that may have been sent by non-HTTP
+ applications, as is sometimes the case when retrieving or posting
+ messages via proxies/gateways to SMTP or NNTP.
+
+
+
+Fielding, et al. Standards Track [Page 20]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ All HTTP date/time stamps MUST be represented in Greenwich Mean Time
+ (GMT), without exception. For the purposes of HTTP, GMT is exactly
+ equal to UTC (Coordinated Universal Time). This is indicated in the
+ first two formats by the inclusion of "GMT" as the three-letter
+ abbreviation for time zone, and MUST be assumed when reading the
+ asctime format. HTTP-date is case sensitive and MUST NOT include
+ additional LWS beyond that specifically included as SP in the
+ grammar.
+
+ HTTP-date = rfc1123-date | rfc850-date | asctime-date
+ rfc1123-date = wkday "," SP date1 SP time SP "GMT"
+ rfc850-date = weekday "," SP date2 SP time SP "GMT"
+ asctime-date = wkday SP date3 SP time SP 4DIGIT
+ date1 = 2DIGIT SP month SP 4DIGIT
+ ; day month year (e.g., 02 Jun 1982)
+ date2 = 2DIGIT "-" month "-" 2DIGIT
+ ; day-month-year (e.g., 02-Jun-82)
+ date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))
+ ; month day (e.g., Jun 2)
+ time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
+ ; 00:00:00 - 23:59:59
+ wkday = "Mon" | "Tue" | "Wed"
+ | "Thu" | "Fri" | "Sat" | "Sun"
+ weekday = "Monday" | "Tuesday" | "Wednesday"
+ | "Thursday" | "Friday" | "Saturday" | "Sunday"
+ month = "Jan" | "Feb" | "Mar" | "Apr"
+ | "May" | "Jun" | "Jul" | "Aug"
+ | "Sep" | "Oct" | "Nov" | "Dec"
+
+ Note: HTTP requirements for the date/time stamp format apply only
+ to their usage within the protocol stream. Clients and servers are
+ not required to use these formats for user presentation, request
+ logging, etc.
+
+3.3.2 Delta Seconds
+
+ Some HTTP header fields allow a time value to be specified as an
+ integer number of seconds, represented in decimal, after the time
+ that the message was received.
+
+ delta-seconds = 1*DIGIT
+
+3.4 Character Sets
+
+ HTTP uses the same definition of the term "character set" as that
+ described for MIME:
+
+
+
+
+
+Fielding, et al. Standards Track [Page 21]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ The term "character set" is used in this document to refer to a
+ method used with one or more tables to convert a sequence of octets
+ into a sequence of characters. Note that unconditional conversion in
+ the other direction is not required, in that not all characters may
+ be available in a given character set and a character set may provide
+ more than one sequence of octets to represent a particular character.
+ This definition is intended to allow various kinds of character
+ encoding, from simple single-table mappings such as US-ASCII to
+ complex table switching methods such as those that use ISO-2022's
+ techniques. However, the definition associated with a MIME character
+ set name MUST fully specify the mapping to be performed from octets
+ to characters. In particular, use of external profiling information
+ to determine the exact mapping is not permitted.
+
+ Note: This use of the term "character set" is more commonly
+ referred to as a "character encoding." However, since HTTP and
+ MIME share the same registry, it is important that the terminology
+ also be shared.
+
+ HTTP character sets are identified by case-insensitive tokens. The
+ complete set of tokens is defined by the IANA Character Set registry
+ [19].
+
+ charset = token
+
+ Although HTTP allows an arbitrary token to be used as a charset
+ value, any token that has a predefined value within the IANA
+ Character Set registry [19] MUST represent the character set defined
+ by that registry. Applications SHOULD limit their use of character
+ sets to those defined by the IANA registry.
+
+ Implementors should be aware of IETF character set requirements [38]
+ [41].
+
+3.4.1 Missing Charset
+
+ Some HTTP/1.0 software has interpreted a Content-Type header without
+ charset parameter incorrectly to mean "recipient should guess."
+ Senders wishing to defeat this behavior MAY include a charset
+ parameter even when the charset is ISO-8859-1 and SHOULD do so when
+ it is known that it will not confuse the recipient.
+
+ Unfortunately, some older HTTP/1.0 clients did not deal properly with
+ an explicit charset parameter. HTTP/1.1 recipients MUST respect the
+ charset label provided by the sender; and those user agents that have
+ a provision to "guess" a charset MUST use the charset from the
+
+
+
+
+
+Fielding, et al. Standards Track [Page 22]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ content-type field if they support that charset, rather than the
+ recipient's preference, when initially displaying a document. See
+ section 3.7.1.
+
+3.5 Content Codings
+
+ Content coding values indicate an encoding transformation that has
+ been or can be applied to an entity. Content codings are primarily
+ used to allow a document to be compressed or otherwise usefully
+ transformed without losing the identity of its underlying media type
+ and without loss of information. Frequently, the entity is stored in
+ coded form, transmitted directly, and only decoded by the recipient.
+
+ content-coding = token
+
+ All content-coding values are case-insensitive. HTTP/1.1 uses
+ content-coding values in the Accept-Encoding (section 14.3) and
+ Content-Encoding (section 14.11) header fields. Although the value
+ describes the content-coding, what is more important is that it
+ indicates what decoding mechanism will be required to remove the
+ encoding.
+
+ The Internet Assigned Numbers Authority (IANA) acts as a registry for
+ content-coding value tokens. Initially, the registry contains the
+ following tokens:
+
+ gzip An encoding format produced by the file compression program
+ "gzip" (GNU zip) as described in RFC 1952 [25]. This format is a
+ Lempel-Ziv coding (LZ77) with a 32 bit CRC.
+
+ compress
+ The encoding format produced by the common UNIX file compression
+ program "compress". This format is an adaptive Lempel-Ziv-Welch
+ coding (LZW).
+
+ Use of program names for the identification of encoding formats
+ is not desirable and is discouraged for future encodings. Their
+ use here is representative of historical practice, not good
+ design. For compatibility with previous implementations of HTTP,
+ applications SHOULD consider "x-gzip" and "x-compress" to be
+ equivalent to "gzip" and "compress" respectively.
+
+ deflate
+ The "zlib" format defined in RFC 1950 [31] in combination with
+ the "deflate" compression mechanism described in RFC 1951 [29].
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 23]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ identity
+ The default (identity) encoding; the use of no transformation
+ whatsoever. This content-coding is used only in the Accept-
+ Encoding header, and SHOULD NOT be used in the Content-Encoding
+ header.
+
+ New content-coding value tokens SHOULD be registered; to allow
+ interoperability between clients and servers, specifications of the
+ content coding algorithms needed to implement a new value SHOULD be
+ publicly available and adequate for independent implementation, and
+ conform to the purpose of content coding defined in this section.
+
+3.6 Transfer Codings
+
+ Transfer-coding values are used to indicate an encoding
+ transformation that has been, can be, or may need to be applied to an
+ entity-body in order to ensure "safe transport" through the network.
+ This differs from a content coding in that the transfer-coding is a
+ property of the message, not of the original entity.
+
+ transfer-coding = "chunked" | transfer-extension
+ transfer-extension = token *( ";" parameter )
+
+ Parameters are in the form of attribute/value pairs.
+
+ parameter = attribute "=" value
+ attribute = token
+ value = token | quoted-string
+
+ All transfer-coding values are case-insensitive. HTTP/1.1 uses
+ transfer-coding values in the TE header field (section 14.39) and in
+ the Transfer-Encoding header field (section 14.41).
+
+ Whenever a transfer-coding is applied to a message-body, the set of
+ transfer-codings MUST include "chunked", unless the message is
+ terminated by closing the connection. When the "chunked" transfer-
+ coding is used, it MUST be the last transfer-coding applied to the
+ message-body. The "chunked" transfer-coding MUST NOT be applied more
+ than once to a message-body. These rules allow the recipient to
+ determine the transfer-length of the message (section 4.4).
+
+ Transfer-codings are analogous to the Content-Transfer-Encoding
+ values of MIME [7], which were designed to enable safe transport of
+ binary data over a 7-bit transport service. However, safe transport
+ has a different focus for an 8bit-clean transfer protocol. In HTTP,
+ the only unsafe characteristic of message-bodies is the difficulty in
+ determining the exact body length (section 7.2.2), or the desire to
+ encrypt data over a shared transport.
+
+
+
+Fielding, et al. Standards Track [Page 24]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ The Internet Assigned Numbers Authority (IANA) acts as a registry for
+ transfer-coding value tokens. Initially, the registry contains the
+ following tokens: "chunked" (section 3.6.1), "identity" (section
+ 3.6.2), "gzip" (section 3.5), "compress" (section 3.5), and "deflate"
+ (section 3.5).
+
+ New transfer-coding value tokens SHOULD be registered in the same way
+ as new content-coding value tokens (section 3.5).
+
+ A server which receives an entity-body with a transfer-coding it does
+ not understand SHOULD return 501 (Unimplemented), and close the
+ connection. A server MUST NOT send transfer-codings to an HTTP/1.0
+ client.
+
+3.6.1 Chunked Transfer Coding
+
+ The chunked encoding modifies the body of a message in order to
+ transfer it as a series of chunks, each with its own size indicator,
+ followed by an OPTIONAL trailer containing entity-header fields. This
+ allows dynamically produced content to be transferred along with the
+ information necessary for the recipient to verify that it has
+ received the full message.
+
+ Chunked-Body = *chunk
+ last-chunk
+ trailer
+ CRLF
+
+ chunk = chunk-size [ chunk-extension ] CRLF
+ chunk-data CRLF
+ chunk-size = 1*HEX
+ last-chunk = 1*("0") [ chunk-extension ] CRLF
+
+ chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
+ chunk-ext-name = token
+ chunk-ext-val = token | quoted-string
+ chunk-data = chunk-size(OCTET)
+ trailer = *(entity-header CRLF)
+
+ The chunk-size field is a string of hex digits indicating the size of
+ the chunk. The chunked encoding is ended by any chunk whose size is
+ zero, followed by the trailer, which is terminated by an empty line.
+
+ The trailer allows the sender to include additional HTTP header
+ fields at the end of the message. The Trailer header field can be
+ used to indicate which header fields are included in a trailer (see
+ section 14.40).
+
+
+
+
+Fielding, et al. Standards Track [Page 25]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ A server using chunked transfer-coding in a response MUST NOT use the
+ trailer for any header fields unless at least one of the following is
+ true:
+
+ a)the request included a TE header field that indicates "trailers" is
+ acceptable in the transfer-coding of the response, as described in
+ section 14.39; or,
+
+ b)the server is the origin server for the response, the trailer
+ fields consist entirely of optional metadata, and the recipient
+ could use the message (in a manner acceptable to the origin server)
+ without receiving this metadata. In other words, the origin server
+ is willing to accept the possibility that the trailer fields might
+ be silently discarded along the path to the client.
+
+ This requirement prevents an interoperability failure when the
+ message is being received by an HTTP/1.1 (or later) proxy and
+ forwarded to an HTTP/1.0 recipient. It avoids a situation where
+ compliance with the protocol would have necessitated a possibly
+ infinite buffer on the proxy.
+
+ An example process for decoding a Chunked-Body is presented in
+ appendix 19.4.6.
+
+ All HTTP/1.1 applications MUST be able to receive and decode the
+ "chunked" transfer-coding, and MUST ignore chunk-extension extensions
+ they do not understand.
+
+3.7 Media Types
+
+ HTTP uses Internet Media Types [17] in the Content-Type (section
+ 14.17) and Accept (section 14.1) header fields in order to provide
+ open and extensible data typing and type negotiation.
+
+ media-type = type "/" subtype *( ";" parameter )
+ type = token
+ subtype = token
+
+ Parameters MAY follow the type/subtype in the form of attribute/value
+ pairs (as defined in section 3.6).
+
+ The type, subtype, and parameter attribute names are case-
+ insensitive. Parameter values might or might not be case-sensitive,
+ depending on the semantics of the parameter name. Linear white space
+ (LWS) MUST NOT be used between the type and subtype, nor between an
+ attribute and its value. The presence or absence of a parameter might
+ be significant to the processing of a media-type, depending on its
+ definition within the media type registry.
+
+
+
+Fielding, et al. Standards Track [Page 26]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Note that some older HTTP applications do not recognize media type
+ parameters. When sending data to older HTTP applications,
+ implementations SHOULD only use media type parameters when they are
+ required by that type/subtype definition.
+
+ Media-type values are registered with the Internet Assigned Number
+ Authority (IANA [19]). The media type registration process is
+ outlined in RFC 1590 [17]. Use of non-registered media types is
+ discouraged.
+
+3.7.1 Canonicalization and Text Defaults
+
+ Internet media types are registered with a canonical form. An
+ entity-body transferred via HTTP messages MUST be represented in the
+ appropriate canonical form prior to its transmission except for
+ "text" types, as defined in the next paragraph.
+
+ When in canonical form, media subtypes of the "text" type use CRLF as
+ the text line break. HTTP relaxes this requirement and allows the
+ transport of text media with plain CR or LF alone representing a line
+ break when it is done consistently for an entire entity-body. HTTP
+ applications MUST accept CRLF, bare CR, and bare LF as being
+ representative of a line break in text media received via HTTP. In
+ addition, if the text is represented in a character set that does not
+ use octets 13 and 10 for CR and LF respectively, as is the case for
+ some multi-byte character sets, HTTP allows the use of whatever octet
+ sequences are defined by that character set to represent the
+ equivalent of CR and LF for line breaks. This flexibility regarding
+ line breaks applies only to text media in the entity-body; a bare CR
+ or LF MUST NOT be substituted for CRLF within any of the HTTP control
+ structures (such as header fields and multipart boundaries).
+
+ If an entity-body is encoded with a content-coding, the underlying
+ data MUST be in a form defined above prior to being encoded.
+
+ The "charset" parameter is used with some media types to define the
+ character set (section 3.4) of the data. When no explicit charset
+ parameter is provided by the sender, media subtypes of the "text"
+ type are defined to have a default charset value of "ISO-8859-1" when
+ received via HTTP. Data in character sets other than "ISO-8859-1" or
+ its subsets MUST be labeled with an appropriate charset value. See
+ section 3.4.1 for compatibility problems.
+
+3.7.2 Multipart Types
+
+ MIME provides for a number of "multipart" types -- encapsulations of
+ one or more entities within a single message-body. All multipart
+ types share a common syntax, as defined in section 5.1.1 of RFC 2046
+
+
+
+Fielding, et al. Standards Track [Page 27]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ [40], and MUST include a boundary parameter as part of the media type
+ value. The message body is itself a protocol element and MUST
+ therefore use only CRLF to represent line breaks between body-parts.
+ Unlike in RFC 2046, the epilogue of any multipart message MUST be
+ empty; HTTP applications MUST NOT transmit the epilogue (even if the
+ original multipart contains an epilogue). These restrictions exist in
+ order to preserve the self-delimiting nature of a multipart message-
+ body, wherein the "end" of the message-body is indicated by the
+ ending multipart boundary.
+
+ In general, HTTP treats a multipart message-body no differently than
+ any other media type: strictly as payload. The one exception is the
+ "multipart/byteranges" type (appendix 19.2) when it appears in a 206
+ (Partial Content) response, which will be interpreted by some HTTP
+ caching mechanisms as described in sections 13.5.4 and 14.16. In all
+ other cases, an HTTP user agent SHOULD follow the same or similar
+ behavior as a MIME user agent would upon receipt of a multipart type.
+ The MIME header fields within each body-part of a multipart message-
+ body do not have any significance to HTTP beyond that defined by
+ their MIME semantics.
+
+ In general, an HTTP user agent SHOULD follow the same or similar
+ behavior as a MIME user agent would upon receipt of a multipart type.
+ If an application receives an unrecognized multipart subtype, the
+ application MUST treat it as being equivalent to "multipart/mixed".
+
+ Note: The "multipart/form-data" type has been specifically defined
+ for carrying form data suitable for processing via the POST
+ request method, as described in RFC 1867 [15].
+
+3.8 Product Tokens
+
+ Product tokens are used to allow communicating applications to
+ identify themselves by software name and version. Most fields using
+ product tokens also allow sub-products which form a significant part
+ of the application to be listed, separated by white space. By
+ convention, the products are listed in order of their significance
+ for identifying the application.
+
+ product = token ["/" product-version]
+ product-version = token
+
+ Examples:
+
+ User-Agent: CERN-LineMode/2.15 libwww/2.17b3
+ Server: Apache/0.8.4
+
+
+
+
+
+Fielding, et al. Standards Track [Page 28]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Product tokens SHOULD be short and to the point. They MUST NOT be
+ used for advertising or other non-essential information. Although any
+ token character MAY appear in a product-version, this token SHOULD
+ only be used for a version identifier (i.e., successive versions of
+ the same product SHOULD only differ in the product-version portion of
+ the product value).
+
+3.9 Quality Values
+
+ HTTP content negotiation (section 12) uses short "floating point"
+ numbers to indicate the relative importance ("weight") of various
+ negotiable parameters. A weight is normalized to a real number in
+ the range 0 through 1, where 0 is the minimum and 1 the maximum
+ value. If a parameter has a quality value of 0, then content with
+ this parameter is `not acceptable' for the client. HTTP/1.1
+ applications MUST NOT generate more than three digits after the
+ decimal point. User configuration of these values SHOULD also be
+ limited in this fashion.
+
+ qvalue = ( "0" [ "." 0*3DIGIT ] )
+ | ( "1" [ "." 0*3("0") ] )
+
+ "Quality values" is a misnomer, since these values merely represent
+ relative degradation in desired quality.
+
+3.10 Language Tags
+
+ A language tag identifies a natural language spoken, written, or
+ otherwise conveyed by human beings for communication of information
+ to other human beings. Computer languages are explicitly excluded.
+ HTTP uses language tags within the Accept-Language and Content-
+ Language fields.
+
+ The syntax and registry of HTTP language tags is the same as that
+ defined by RFC 1766 [1]. In summary, a language tag is composed of 1
+ or more parts: A primary language tag and a possibly empty series of
+ subtags:
+
+ language-tag = primary-tag *( "-" subtag )
+ primary-tag = 1*8ALPHA
+ subtag = 1*8ALPHA
+
+ White space is not allowed within the tag and all tags are case-
+ insensitive. The name space of language tags is administered by the
+ IANA. Example tags include:
+
+ en, en-US, en-cockney, i-cherokee, x-pig-latin
+
+
+
+
+Fielding, et al. Standards Track [Page 29]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ where any two-letter primary-tag is an ISO-639 language abbreviation
+ and any two-letter initial subtag is an ISO-3166 country code. (The
+ last three tags above are not registered tags; all but the last are
+ examples of tags which could be registered in future.)
+
+3.11 Entity Tags
+
+ Entity tags are used for comparing two or more entities from the same
+ requested resource. HTTP/1.1 uses entity tags in the ETag (section
+ 14.19), If-Match (section 14.24), If-None-Match (section 14.26), and
+ If-Range (section 14.27) header fields. The definition of how they
+ are used and compared as cache validators is in section 13.3.3. An
+ entity tag consists of an opaque quoted string, possibly prefixed by
+ a weakness indicator.
+
+ entity-tag = [ weak ] opaque-tag
+ weak = "W/"
+ opaque-tag = quoted-string
+
+ A "strong entity tag" MAY be shared by two entities of a resource
+ only if they are equivalent by octet equality.
+
+ A "weak entity tag," indicated by the "W/" prefix, MAY be shared by
+ two entities of a resource only if the entities are equivalent and
+ could be substituted for each other with no significant change in
+ semantics. A weak entity tag can only be used for weak comparison.
+
+ An entity tag MUST be unique across all versions of all entities
+ associated with a particular resource. A given entity tag value MAY
+ be used for entities obtained by requests on different URIs. The use
+ of the same entity tag value in conjunction with entities obtained by
+ requests on different URIs does not imply the equivalence of those
+ entities.
+
+3.12 Range Units
+
+ HTTP/1.1 allows a client to request that only part (a range of) the
+ response entity be included within the response. HTTP/1.1 uses range
+ units in the Range (section 14.35) and Content-Range (section 14.16)
+ header fields. An entity can be broken down into subranges according
+ to various structural units.
+
+ range-unit = bytes-unit | other-range-unit
+ bytes-unit = "bytes"
+ other-range-unit = token
+
+ The only range unit defined by HTTP/1.1 is "bytes". HTTP/1.1
+ implementations MAY ignore ranges specified using other units.
+
+
+
+Fielding, et al. Standards Track [Page 30]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ HTTP/1.1 has been designed to allow implementations of applications
+ that do not depend on knowledge of ranges.
+
+4 HTTP Message
+
+4.1 Message Types
+
+ HTTP messages consist of requests from client to server and responses
+ from server to client.
+
+ HTTP-message = Request | Response ; HTTP/1.1 messages
+
+ Request (section 5) and Response (section 6) messages use the generic
+ message format of RFC 822 [9] for transferring entities (the payload
+ of the message). Both types of message consist of a start-line, zero
+ or more header fields (also known as "headers"), an empty line (i.e.,
+ a line with nothing preceding the CRLF) indicating the end of the
+ header fields, and possibly a message-body.
+
+ generic-message = start-line
+ *(message-header CRLF)
+ CRLF
+ [ message-body ]
+ start-line = Request-Line | Status-Line
+
+ In the interest of robustness, servers SHOULD ignore any empty
+ line(s) received where a Request-Line is expected. In other words, if
+ the server is reading the protocol stream at the beginning of a
+ message and receives a CRLF first, it should ignore the CRLF.
+
+ Certain buggy HTTP/1.0 client implementations generate extra CRLF's
+ after a POST request. To restate what is explicitly forbidden by the
+ BNF, an HTTP/1.1 client MUST NOT preface or follow a request with an
+ extra CRLF.
+
+4.2 Message Headers
+
+ HTTP header fields, which include general-header (section 4.5),
+ request-header (section 5.3), response-header (section 6.2), and
+ entity-header (section 7.1) fields, follow the same generic format as
+ that given in Section 3.1 of RFC 822 [9]. Each header field consists
+ of a name followed by a colon (":") and the field value. Field names
+ are case-insensitive. The field value MAY be preceded by any amount
+ of LWS, though a single SP is preferred. Header fields can be
+ extended over multiple lines by preceding each extra line with at
+ least one SP or HT. Applications ought to follow "common form", where
+ one is known or indicated, when generating HTTP constructs, since
+ there might exist some implementations that fail to accept anything
+
+
+
+Fielding, et al. Standards Track [Page 31]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ beyond the common forms.
+
+ message-header = field-name ":" [ field-value ]
+ field-name = token
+ field-value = *( field-content | LWS )
+ field-content = <the OCTETs making up the field-value
+ and consisting of either *TEXT or combinations
+ of token, separators, and quoted-string>
+
+ The field-content does not include any leading or trailing LWS:
+ linear white space occurring before the first non-whitespace
+ character of the field-value or after the last non-whitespace
+ character of the field-value. Such leading or trailing LWS MAY be
+ removed without changing the semantics of the field value. Any LWS
+ that occurs between field-content MAY be replaced with a single SP
+ before interpreting the field value or forwarding the message
+ downstream.
+
+ The order in which header fields with differing field names are
+ received is not significant. However, it is "good practice" to send
+ general-header fields first, followed by request-header or response-
+ header fields, and ending with the entity-header fields.
+
+ Multiple message-header fields with the same field-name MAY be
+ present in a message if and only if the entire field-value for that
+ header field is defined as a comma-separated list [i.e., #(values)].
+ It MUST be possible to combine the multiple header fields into one
+ "field-name: field-value" pair, without changing the semantics of the
+ message, by appending each subsequent field-value to the first, each
+ separated by a comma. The order in which header fields with the same
+ field-name are received is therefore significant to the
+ interpretation of the combined field value, and thus a proxy MUST NOT
+ change the order of these field values when a message is forwarded.
+
+4.3 Message Body
+
+ The message-body (if any) of an HTTP message is used to carry the
+ entity-body associated with the request or response. The message-body
+ differs from the entity-body only when a transfer-coding has been
+ applied, as indicated by the Transfer-Encoding header field (section
+ 14.41).
+
+ message-body = entity-body
+ | <entity-body encoded as per Transfer-Encoding>
+
+ Transfer-Encoding MUST be used to indicate any transfer-codings
+ applied by an application to ensure safe and proper transfer of the
+ message. Transfer-Encoding is a property of the message, not of the
+
+
+
+Fielding, et al. Standards Track [Page 32]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ entity, and thus MAY be added or removed by any application along the
+ request/response chain. (However, section 3.6 places restrictions on
+ when certain transfer-codings may be used.)
+
+ The rules for when a message-body is allowed in a message differ for
+ requests and responses.
+
+ The presence of a message-body in a request is signaled by the
+ inclusion of a Content-Length or Transfer-Encoding header field in
+ the request's message-headers. A message-body MUST NOT be included in
+ a request if the specification of the request method (section 5.1.1)
+ does not allow sending an entity-body in requests. A server SHOULD
+ read and forward a message-body on any request; if the request method
+ does not include defined semantics for an entity-body, then the
+ message-body SHOULD be ignored when handling the request.
+
+ For response messages, whether or not a message-body is included with
+ a message is dependent on both the request method and the response
+ status code (section 6.1.1). All responses to the HEAD request method
+ MUST NOT include a message-body, even though the presence of entity-
+ header fields might lead one to believe they do. All 1xx
+ (informational), 204 (no content), and 304 (not modified) responses
+ MUST NOT include a message-body. All other responses do include a
+ message-body, although it MAY be of zero length.
+
+4.4 Message Length
+
+ The transfer-length of a message is the length of the message-body as
+ it appears in the message; that is, after any transfer-codings have
+ been applied. When a message-body is included with a message, the
+ transfer-length of that body is determined by one of the following
+ (in order of precedence):
+
+ 1.Any response message which "MUST NOT" include a message-body (such
+ as the 1xx, 204, and 304 responses and any response to a HEAD
+ request) is always terminated by the first empty line after the
+ header fields, regardless of the entity-header fields present in
+ the message.
+
+ 2.If a Transfer-Encoding header field (section 14.41) is present and
+ has any value other than "identity", then the transfer-length is
+ defined by use of the "chunked" transfer-coding (section 3.6),
+ unless the message is terminated by closing the connection.
+
+ 3.If a Content-Length header field (section 14.13) is present, its
+ decimal value in OCTETs represents both the entity-length and the
+ transfer-length. The Content-Length header field MUST NOT be sent
+ if these two lengths are different (i.e., if a Transfer-Encoding
+
+
+
+Fielding, et al. Standards Track [Page 33]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ header field is present). If a message is received with both a
+ Transfer-Encoding header field and a Content-Length header field,
+ the latter MUST be ignored.
+
+ 4.If the message uses the media type "multipart/byteranges", and the
+ ransfer-length is not otherwise specified, then this self-
+ elimiting media type defines the transfer-length. This media type
+ UST NOT be used unless the sender knows that the recipient can arse
+ it; the presence in a request of a Range header with ultiple byte-
+ range specifiers from a 1.1 client implies that the lient can parse
+ multipart/byteranges responses.
+
+ A range header might be forwarded by a 1.0 proxy that does not
+ understand multipart/byteranges; in this case the server MUST
+ delimit the message using methods defined in items 1,3 or 5 of
+ this section.
+
+ 5.By the server closing the connection. (Closing the connection
+ cannot be used to indicate the end of a request body, since that
+ would leave no possibility for the server to send back a response.)
+
+ For compatibility with HTTP/1.0 applications, HTTP/1.1 requests
+ containing a message-body MUST include a valid Content-Length header
+ field unless the server is known to be HTTP/1.1 compliant. If a
+ request contains a message-body and a Content-Length is not given,
+ the server SHOULD respond with 400 (bad request) if it cannot
+ determine the length of the message, or with 411 (length required) if
+ it wishes to insist on receiving a valid Content-Length.
+
+ All HTTP/1.1 applications that receive entities MUST accept the
+ "chunked" transfer-coding (section 3.6), thus allowing this mechanism
+ to be used for messages when the message length cannot be determined
+ in advance.
+
+ Messages MUST NOT include both a Content-Length header field and a
+ non-identity transfer-coding. If the message does include a non-
+ identity transfer-coding, the Content-Length MUST be ignored.
+
+ When a Content-Length is given in a message where a message-body is
+ allowed, its field value MUST exactly match the number of OCTETs in
+ the message-body. HTTP/1.1 user agents MUST notify the user when an
+ invalid length is received and detected.
+
+4.5 General Header Fields
+
+ There are a few header fields which have general applicability for
+ both request and response messages, but which do not apply to the
+ entity being transferred. These header fields apply only to the
+
+
+
+Fielding, et al. Standards Track [Page 34]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ message being transmitted.
+
+ general-header = Cache-Control ; Section 14.9
+ | Connection ; Section 14.10
+ | Date ; Section 14.18
+ | Pragma ; Section 14.32
+ | Trailer ; Section 14.40
+ | Transfer-Encoding ; Section 14.41
+ | Upgrade ; Section 14.42
+ | Via ; Section 14.45
+ | Warning ; Section 14.46
+
+ General-header field names can be extended reliably only in
+ combination with a change in the protocol version. However, new or
+ experimental header fields may be given the semantics of general
+ header fields if all parties in the communication recognize them to
+ be general-header fields. Unrecognized header fields are treated as
+ entity-header fields.
+
+5 Request
+
+ A request message from a client to a server includes, within the
+ first line of that message, the method to be applied to the resource,
+ the identifier of the resource, and the protocol version in use.
+
+ Request = Request-Line ; Section 5.1
+ *(( general-header ; Section 4.5
+ | request-header ; Section 5.3
+ | entity-header ) CRLF) ; Section 7.1
+ CRLF
+ [ message-body ] ; Section 4.3
+
+5.1 Request-Line
+
+ The Request-Line begins with a method token, followed by the
+ Request-URI and the protocol version, and ending with CRLF. The
+ elements are separated by SP characters. No CR or LF is allowed
+ except in the final CRLF sequence.
+
+ Request-Line = Method SP Request-URI SP HTTP-Version CRLF
+
+
+
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 35]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+5.1.1 Method
+
+ The Method token indicates the method to be performed on the
+ resource identified by the Request-URI. The method is case-sensitive.
+
+ Method = "OPTIONS" ; Section 9.2
+ | "GET" ; Section 9.3
+ | "HEAD" ; Section 9.4
+ | "POST" ; Section 9.5
+ | "PUT" ; Section 9.6
+ | "DELETE" ; Section 9.7
+ | "TRACE" ; Section 9.8
+ | "CONNECT" ; Section 9.9
+ | extension-method
+ extension-method = token
+
+ The list of methods allowed by a resource can be specified in an
+ Allow header field (section 14.7). The return code of the response
+ always notifies the client whether a method is currently allowed on a
+ resource, since the set of allowed methods can change dynamically. An
+ origin server SHOULD return the status code 405 (Method Not Allowed)
+ if the method is known by the origin server but not allowed for the
+ requested resource, and 501 (Not Implemented) if the method is
+ unrecognized or not implemented by the origin server. The methods GET
+ and HEAD MUST be supported by all general-purpose servers. All other
+ methods are OPTIONAL; however, if the above methods are implemented,
+ they MUST be implemented with the same semantics as those specified
+ in section 9.
+
+5.1.2 Request-URI
+
+ The Request-URI is a Uniform Resource Identifier (section 3.2) and
+ identifies the resource upon which to apply the request.
+
+ Request-URI = "*" | absoluteURI | abs_path | authority
+
+ The four options for Request-URI are dependent on the nature of the
+ request. The asterisk "*" means that the request does not apply to a
+ particular resource, but to the server itself, and is only allowed
+ when the method used does not necessarily apply to a resource. One
+ example would be
+
+ OPTIONS * HTTP/1.1
+
+ The absoluteURI form is REQUIRED when the request is being made to a
+ proxy. The proxy is requested to forward the request or service it
+ from a valid cache, and return the response. Note that the proxy MAY
+ forward the request on to another proxy or directly to the server
+
+
+
+Fielding, et al. Standards Track [Page 36]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ specified by the absoluteURI. In order to avoid request loops, a
+ proxy MUST be able to recognize all of its server names, including
+ any aliases, local variations, and the numeric IP address. An example
+ Request-Line would be:
+
+ GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
+
+ To allow for transition to absoluteURIs in all requests in future
+ versions of HTTP, all HTTP/1.1 servers MUST accept the absoluteURI
+ form in requests, even though HTTP/1.1 clients will only generate
+ them in requests to proxies.
+
+ The authority form is only used by the CONNECT method (section 9.9).
+
+ The most common form of Request-URI is that used to identify a
+ resource on an origin server or gateway. In this case the absolute
+ path of the URI MUST be transmitted (see section 3.2.1, abs_path) as
+ the Request-URI, and the network location of the URI (authority) MUST
+ be transmitted in a Host header field. For example, a client wishing
+ to retrieve the resource above directly from the origin server would
+ create a TCP connection to port 80 of the host "www.w3.org" and send
+ the lines:
+
+ GET /pub/WWW/TheProject.html HTTP/1.1
+ Host: www.w3.org
+
+ followed by the remainder of the Request. Note that the absolute path
+ cannot be empty; if none is present in the original URI, it MUST be
+ given as "/" (the server root).
+
+ The Request-URI is transmitted in the format specified in section
+ 3.2.1. If the Request-URI is encoded using the "% HEX HEX" encoding
+ [42], the origin server MUST decode the Request-URI in order to
+ properly interpret the request. Servers SHOULD respond to invalid
+ Request-URIs with an appropriate status code.
+
+ A transparent proxy MUST NOT rewrite the "abs_path" part of the
+ received Request-URI when forwarding it to the next inbound server,
+ except as noted above to replace a null abs_path with "/".
+
+ Note: The "no rewrite" rule prevents the proxy from changing the
+ meaning of the request when the origin server is improperly using
+ a non-reserved URI character for a reserved purpose. Implementors
+ should be aware that some pre-HTTP/1.1 proxies have been known to
+ rewrite the Request-URI.
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 37]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+5.2 The Resource Identified by a Request
+
+ The exact resource identified by an Internet request is determined by
+ examining both the Request-URI and the Host header field.
+
+ An origin server that does not allow resources to differ by the
+ requested host MAY ignore the Host header field value when
+ determining the resource identified by an HTTP/1.1 request. (But see
+ section 19.6.1.1 for other requirements on Host support in HTTP/1.1.)
+
+ An origin server that does differentiate resources based on the host
+ requested (sometimes referred to as virtual hosts or vanity host
+ names) MUST use the following rules for determining the requested
+ resource on an HTTP/1.1 request:
+
+ 1. If Request-URI is an absoluteURI, the host is part of the
+ Request-URI. Any Host header field value in the request MUST be
+ ignored.
+
+ 2. If the Request-URI is not an absoluteURI, and the request includes
+ a Host header field, the host is determined by the Host header
+ field value.
+
+ 3. If the host as determined by rule 1 or 2 is not a valid host on
+ the server, the response MUST be a 400 (Bad Request) error message.
+
+ Recipients of an HTTP/1.0 request that lacks a Host header field MAY
+ attempt to use heuristics (e.g., examination of the URI path for
+ something unique to a particular host) in order to determine what
+ exact resource is being requested.
+
+5.3 Request Header Fields
+
+ The request-header fields allow the client to pass additional
+ information about the request, and about the client itself, to the
+ server. These fields act as request modifiers, with semantics
+ equivalent to the parameters on a programming language method
+ invocation.
+
+ request-header = Accept ; Section 14.1
+ | Accept-Charset ; Section 14.2
+ | Accept-Encoding ; Section 14.3
+ | Accept-Language ; Section 14.4
+ | Authorization ; Section 14.8
+ | Expect ; Section 14.20
+ | From ; Section 14.22
+ | Host ; Section 14.23
+ | If-Match ; Section 14.24
+
+
+
+Fielding, et al. Standards Track [Page 38]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ | If-Modified-Since ; Section 14.25
+ | If-None-Match ; Section 14.26
+ | If-Range ; Section 14.27
+ | If-Unmodified-Since ; Section 14.28
+ | Max-Forwards ; Section 14.31
+ | Proxy-Authorization ; Section 14.34
+ | Range ; Section 14.35
+ | Referer ; Section 14.36
+ | TE ; Section 14.39
+ | User-Agent ; Section 14.43
+
+ Request-header field names can be extended reliably only in
+ combination with a change in the protocol version. However, new or
+ experimental header fields MAY be given the semantics of request-
+ header fields if all parties in the communication recognize them to
+ be request-header fields. Unrecognized header fields are treated as
+ entity-header fields.
+
+6 Response
+
+ After receiving and interpreting a request message, a server responds
+ with an HTTP response message.
+
+ Response = Status-Line ; Section 6.1
+ *(( general-header ; Section 4.5
+ | response-header ; Section 6.2
+ | entity-header ) CRLF) ; Section 7.1
+ CRLF
+ [ message-body ] ; Section 7.2
+
+6.1 Status-Line
+
+ The first line of a Response message is the Status-Line, consisting
+ of the protocol version followed by a numeric status code and its
+ associated textual phrase, with each element separated by SP
+ characters. No CR or LF is allowed except in the final CRLF sequence.
+
+ Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
+
+6.1.1 Status Code and Reason Phrase
+
+ The Status-Code element is a 3-digit integer result code of the
+ attempt to understand and satisfy the request. These codes are fully
+ defined in section 10. The Reason-Phrase is intended to give a short
+ textual description of the Status-Code. The Status-Code is intended
+ for use by automata and the Reason-Phrase is intended for the human
+ user. The client is not required to examine or display the Reason-
+ Phrase.
+
+
+
+Fielding, et al. Standards Track [Page 39]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ The first digit of the Status-Code defines the class of response. The
+ last two digits do not have any categorization role. There are 5
+ values for the first digit:
+
+ - 1xx: Informational - Request received, continuing process
+
+ - 2xx: Success - The action was successfully received,
+ understood, and accepted
+
+ - 3xx: Redirection - Further action must be taken in order to
+ complete the request
+
+ - 4xx: Client Error - The request contains bad syntax or cannot
+ be fulfilled
+
+ - 5xx: Server Error - The server failed to fulfill an apparently
+ valid request
+
+ The individual values of the numeric status codes defined for
+ HTTP/1.1, and an example set of corresponding Reason-Phrase's, are
+ presented below. The reason phrases listed here are only
+ recommendations -- they MAY be replaced by local equivalents without
+ affecting the protocol.
+
+ Status-Code =
+ "100" ; Section 10.1.1: Continue
+ | "101" ; Section 10.1.2: Switching Protocols
+ | "200" ; Section 10.2.1: OK
+ | "201" ; Section 10.2.2: Created
+ | "202" ; Section 10.2.3: Accepted
+ | "203" ; Section 10.2.4: Non-Authoritative Information
+ | "204" ; Section 10.2.5: No Content
+ | "205" ; Section 10.2.6: Reset Content
+ | "206" ; Section 10.2.7: Partial Content
+ | "300" ; Section 10.3.1: Multiple Choices
+ | "301" ; Section 10.3.2: Moved Permanently
+ | "302" ; Section 10.3.3: Found
+ | "303" ; Section 10.3.4: See Other
+ | "304" ; Section 10.3.5: Not Modified
+ | "305" ; Section 10.3.6: Use Proxy
+ | "307" ; Section 10.3.8: Temporary Redirect
+ | "400" ; Section 10.4.1: Bad Request
+ | "401" ; Section 10.4.2: Unauthorized
+ | "402" ; Section 10.4.3: Payment Required
+ | "403" ; Section 10.4.4: Forbidden
+ | "404" ; Section 10.4.5: Not Found
+ | "405" ; Section 10.4.6: Method Not Allowed
+ | "406" ; Section 10.4.7: Not Acceptable
+
+
+
+Fielding, et al. Standards Track [Page 40]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ | "407" ; Section 10.4.8: Proxy Authentication Required
+ | "408" ; Section 10.4.9: Request Time-out
+ | "409" ; Section 10.4.10: Conflict
+ | "410" ; Section 10.4.11: Gone
+ | "411" ; Section 10.4.12: Length Required
+ | "412" ; Section 10.4.13: Precondition Failed
+ | "413" ; Section 10.4.14: Request Entity Too Large
+ | "414" ; Section 10.4.15: Request-URI Too Large
+ | "415" ; Section 10.4.16: Unsupported Media Type
+ | "416" ; Section 10.4.17: Requested range not satisfiable
+ | "417" ; Section 10.4.18: Expectation Failed
+ | "500" ; Section 10.5.1: Internal Server Error
+ | "501" ; Section 10.5.2: Not Implemented
+ | "502" ; Section 10.5.3: Bad Gateway
+ | "503" ; Section 10.5.4: Service Unavailable
+ | "504" ; Section 10.5.5: Gateway Time-out
+ | "505" ; Section 10.5.6: HTTP Version not supported
+ | extension-code
+
+ extension-code = 3DIGIT
+ Reason-Phrase = *<TEXT, excluding CR, LF>
+
+ HTTP status codes are extensible. HTTP applications are not required
+ to understand the meaning of all registered status codes, though such
+ understanding is obviously desirable. However, applications MUST
+ understand the class of any status code, as indicated by the first
+ digit, and treat any unrecognized response as being equivalent to the
+ x00 status code of that class, with the exception that an
+ unrecognized response MUST NOT be cached. For example, if an
+ unrecognized status code of 431 is received by the client, it can
+ safely assume that there was something wrong with its request and
+ treat the response as if it had received a 400 status code. In such
+ cases, user agents SHOULD present to the user the entity returned
+ with the response, since that entity is likely to include human-
+ readable information which will explain the unusual status.
+
+6.2 Response Header Fields
+
+ The response-header fields allow the server to pass additional
+ information about the response which cannot be placed in the Status-
+ Line. These header fields give information about the server and about
+ further access to the resource identified by the Request-URI.
+
+ response-header = Accept-Ranges ; Section 14.5
+ | Age ; Section 14.6
+ | ETag ; Section 14.19
+ | Location ; Section 14.30
+ | Proxy-Authenticate ; Section 14.33
+
+
+
+Fielding, et al. Standards Track [Page 41]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ | Retry-After ; Section 14.37
+ | Server ; Section 14.38
+ | Vary ; Section 14.44
+ | WWW-Authenticate ; Section 14.47
+
+ Response-header field names can be extended reliably only in
+ combination with a change in the protocol version. However, new or
+ experimental header fields MAY be given the semantics of response-
+ header fields if all parties in the communication recognize them to
+ be response-header fields. Unrecognized header fields are treated as
+ entity-header fields.
+
+7 Entity
+
+ Request and Response messages MAY transfer an entity if not otherwise
+ restricted by the request method or response status code. An entity
+ consists of entity-header fields and an entity-body, although some
+ responses will only include the entity-headers.
+
+ In this section, both sender and recipient refer to either the client
+ or the server, depending on who sends and who receives the entity.
+
+7.1 Entity Header Fields
+
+ Entity-header fields define metainformation about the entity-body or,
+ if no body is present, about the resource identified by the request.
+ Some of this metainformation is OPTIONAL; some might be REQUIRED by
+ portions of this specification.
+
+ entity-header = Allow ; Section 14.7
+ | Content-Encoding ; Section 14.11
+ | Content-Language ; Section 14.12
+ | Content-Length ; Section 14.13
+ | Content-Location ; Section 14.14
+ | Content-MD5 ; Section 14.15
+ | Content-Range ; Section 14.16
+ | Content-Type ; Section 14.17
+ | Expires ; Section 14.21
+ | Last-Modified ; Section 14.29
+ | extension-header
+
+ extension-header = message-header
+
+ The extension-header mechanism allows additional entity-header fields
+ to be defined without changing the protocol, but these fields cannot
+ be assumed to be recognizable by the recipient. Unrecognized header
+ fields SHOULD be ignored by the recipient and MUST be forwarded by
+ transparent proxies.
+
+
+
+Fielding, et al. Standards Track [Page 42]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+7.2 Entity Body
+
+ The entity-body (if any) sent with an HTTP request or response is in
+ a format and encoding defined by the entity-header fields.
+
+ entity-body = *OCTET
+
+ An entity-body is only present in a message when a message-body is
+ present, as described in section 4.3. The entity-body is obtained
+ from the message-body by decoding any Transfer-Encoding that might
+ have been applied to ensure safe and proper transfer of the message.
+
+7.2.1 Type
+
+ When an entity-body is included with a message, the data type of that
+ body is determined via the header fields Content-Type and Content-
+ Encoding. These define a two-layer, ordered encoding model:
+
+ entity-body := Content-Encoding( Content-Type( data ) )
+
+ Content-Type specifies the media type of the underlying data.
+ Content-Encoding may be used to indicate any additional content
+ codings applied to the data, usually for the purpose of data
+ compression, that are a property of the requested resource. There is
+ no default encoding.
+
+ Any HTTP/1.1 message containing an entity-body SHOULD include a
+ Content-Type header field defining the media type of that body. If
+ and only if the media type is not given by a Content-Type field, the
+ recipient MAY attempt to guess the media type via inspection of its
+ content and/or the name extension(s) of the URI used to identify the
+ resource. If the media type remains unknown, the recipient SHOULD
+ treat it as type "application/octet-stream".
+
+7.2.2 Entity Length
+
+ The entity-length of a message is the length of the message-body
+ before any transfer-codings have been applied. Section 4.4 defines
+ how the transfer-length of a message-body is determined.
+
+
+
+
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 43]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+8 Connections
+
+8.1 Persistent Connections
+
+8.1.1 Purpose
+
+ Prior to persistent connections, a separate TCP connection was
+ established to fetch each URL, increasing the load on HTTP servers
+ and causing congestion on the Internet. The use of inline images and
+ other associated data often require a client to make multiple
+ requests of the same server in a short amount of time. Analysis of
+ these performance problems and results from a prototype
+ implementation are available [26] [30]. Implementation experience and
+ measurements of actual HTTP/1.1 (RFC 2068) implementations show good
+ results [39]. Alternatives have also been explored, for example,
+ T/TCP [27].
+
+ Persistent HTTP connections have a number of advantages:
+
+ - By opening and closing fewer TCP connections, CPU time is saved
+ in routers and hosts (clients, servers, proxies, gateways,
+ tunnels, or caches), and memory used for TCP protocol control
+ blocks can be saved in hosts.
+
+ - HTTP requests and responses can be pipelined on a connection.
+ Pipelining allows a client to make multiple requests without
+ waiting for each response, allowing a single TCP connection to
+ be used much more efficiently, with much lower elapsed time.
+
+ - Network congestion is reduced by reducing the number of packets
+ caused by TCP opens, and by allowing TCP sufficient time to
+ determine the congestion state of the network.
+
+ - Latency on subsequent requests is reduced since there is no time
+ spent in TCP's connection opening handshake.
+
+ - HTTP can evolve more gracefully, since errors can be reported
+ without the penalty of closing the TCP connection. Clients using
+ future versions of HTTP might optimistically try a new feature,
+ but if communicating with an older server, retry with old
+ semantics after an error is reported.
+
+ HTTP implementations SHOULD implement persistent connections.
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 44]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+8.1.2 Overall Operation
+
+ A significant difference between HTTP/1.1 and earlier versions of
+ HTTP is that persistent connections are the default behavior of any
+ HTTP connection. That is, unless otherwise indicated, the client
+ SHOULD assume that the server will maintain a persistent connection,
+ even after error responses from the server.
+
+ Persistent connections provide a mechanism by which a client and a
+ server can signal the close of a TCP connection. This signaling takes
+ place using the Connection header field (section 14.10). Once a close
+ has been signaled, the client MUST NOT send any more requests on that
+ connection.
+
+8.1.2.1 Negotiation
+
+ An HTTP/1.1 server MAY assume that a HTTP/1.1 client intends to
+ maintain a persistent connection unless a Connection header including
+ the connection-token "close" was sent in the request. If the server
+ chooses to close the connection immediately after sending the
+ response, it SHOULD send a Connection header including the
+ connection-token close.
+
+ An HTTP/1.1 client MAY expect a connection to remain open, but would
+ decide to keep it open based on whether the response from a server
+ contains a Connection header with the connection-token close. In case
+ the client does not want to maintain a connection for more than that
+ request, it SHOULD send a Connection header including the
+ connection-token close.
+
+ If either the client or the server sends the close token in the
+ Connection header, that request becomes the last one for the
+ connection.
+
+ Clients and servers SHOULD NOT assume that a persistent connection is
+ maintained for HTTP versions less than 1.1 unless it is explicitly
+ signaled. See section 19.6.2 for more information on backward
+ compatibility with HTTP/1.0 clients.
+
+ In order to remain persistent, all messages on the connection MUST
+ have a self-defined message length (i.e., one not defined by closure
+ of the connection), as described in section 4.4.
+
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 45]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+8.1.2.2 Pipelining
+
+ A client that supports persistent connections MAY "pipeline" its
+ requests (i.e., send multiple requests without waiting for each
+ response). A server MUST send its responses to those requests in the
+ same order that the requests were received.
+
+ Clients which assume persistent connections and pipeline immediately
+ after connection establishment SHOULD be prepared to retry their
+ connection if the first pipelined attempt fails. If a client does
+ such a retry, it MUST NOT pipeline before it knows the connection is
+ persistent. Clients MUST also be prepared to resend their requests if
+ the server closes the connection before sending all of the
+ corresponding responses.
+
+ Clients SHOULD NOT pipeline requests using non-idempotent methods or
+ non-idempotent sequences of methods (see section 9.1.2). Otherwise, a
+ premature termination of the transport connection could lead to
+ indeterminate results. A client wishing to send a non-idempotent
+ request SHOULD wait to send that request until it has received the
+ response status for the previous request.
+
+8.1.3 Proxy Servers
+
+ It is especially important that proxies correctly implement the
+ properties of the Connection header field as specified in section
+ 14.10.
+
+ The proxy server MUST signal persistent connections separately with
+ its clients and the origin servers (or other proxy servers) that it
+ connects to. Each persistent connection applies to only one transport
+ link.
+
+ A proxy server MUST NOT establish a HTTP/1.1 persistent connection
+ with an HTTP/1.0 client (but see RFC 2068 [33] for information and
+ discussion of the problems with the Keep-Alive header implemented by
+ many HTTP/1.0 clients).
+
+8.1.4 Practical Considerations
+
+ Servers will usually have some time-out value beyond which they will
+ no longer maintain an inactive connection. Proxy servers might make
+ this a higher value since it is likely that the client will be making
+ more connections through the same server. The use of persistent
+ connections places no requirements on the length (or existence) of
+ this time-out for either the client or the server.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 46]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ When a client or server wishes to time-out it SHOULD issue a graceful
+ close on the transport connection. Clients and servers SHOULD both
+ constantly watch for the other side of the transport close, and
+ respond to it as appropriate. If a client or server does not detect
+ the other side's close promptly it could cause unnecessary resource
+ drain on the network.
+
+ A client, server, or proxy MAY close the transport connection at any
+ time. For example, a client might have started to send a new request
+ at the same time that the server has decided to close the "idle"
+ connection. From the server's point of view, the connection is being
+ closed while it was idle, but from the client's point of view, a
+ request is in progress.
+
+ This means that clients, servers, and proxies MUST be able to recover
+ from asynchronous close events. Client software SHOULD reopen the
+ transport connection and retransmit the aborted sequence of requests
+ without user interaction so long as the request sequence is
+ idempotent (see section 9.1.2). Non-idempotent methods or sequences
+ MUST NOT be automatically retried, although user agents MAY offer a
+ human operator the choice of retrying the request(s). Confirmation by
+ user-agent software with semantic understanding of the application
+ MAY substitute for user confirmation. The automatic retry SHOULD NOT
+ be repeated if the second sequence of requests fails.
+
+ Servers SHOULD always respond to at least one request per connection,
+ if at all possible. Servers SHOULD NOT close a connection in the
+ middle of transmitting a response, unless a network or client failure
+ is suspected.
+
+ Clients that use persistent connections SHOULD limit the number of
+ simultaneous connections that they maintain to a given server. A
+ single-user client SHOULD NOT maintain more than 2 connections with
+ any server or proxy. A proxy SHOULD use up to 2*N connections to
+ another server or proxy, where N is the number of simultaneously
+ active users. These guidelines are intended to improve HTTP response
+ times and avoid congestion.
+
+8.2 Message Transmission Requirements
+
+8.2.1 Persistent Connections and Flow Control
+
+ HTTP/1.1 servers SHOULD maintain persistent connections and use TCP's
+ flow control mechanisms to resolve temporary overloads, rather than
+ terminating connections with the expectation that clients will retry.
+ The latter technique can exacerbate network congestion.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 47]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+8.2.2 Monitoring Connections for Error Status Messages
+
+ An HTTP/1.1 (or later) client sending a message-body SHOULD monitor
+ the network connection for an error status while it is transmitting
+ the request. If the client sees an error status, it SHOULD
+ immediately cease transmitting the body. If the body is being sent
+ using a "chunked" encoding (section 3.6), a zero length chunk and
+ empty trailer MAY be used to prematurely mark the end of the message.
+ If the body was preceded by a Content-Length header, the client MUST
+ close the connection.
+
+8.2.3 Use of the 100 (Continue) Status
+
+ The purpose of the 100 (Continue) status (see section 10.1.1) is to
+ allow a client that is sending a request message with a request body
+ to determine if the origin server is willing to accept the request
+ (based on the request headers) before the client sends the request
+ body. In some cases, it might either be inappropriate or highly
+ inefficient for the client to send the body if the server will reject
+ the message without looking at the body.
+
+ Requirements for HTTP/1.1 clients:
+
+ - If a client will wait for a 100 (Continue) response before
+ sending the request body, it MUST send an Expect request-header
+ field (section 14.20) with the "100-continue" expectation.
+
+ - A client MUST NOT send an Expect request-header field (section
+ 14.20) with the "100-continue" expectation if it does not intend
+ to send a request body.
+
+ Because of the presence of older implementations, the protocol allows
+ ambiguous situations in which a client may send "Expect: 100-
+ continue" without receiving either a 417 (Expectation Failed) status
+ or a 100 (Continue) status. Therefore, when a client sends this
+ header field to an origin server (possibly via a proxy) from which it
+ has never seen a 100 (Continue) status, the client SHOULD NOT wait
+ for an indefinite period before sending the request body.
+
+ Requirements for HTTP/1.1 origin servers:
+
+ - Upon receiving a request which includes an Expect request-header
+ field with the "100-continue" expectation, an origin server MUST
+ either respond with 100 (Continue) status and continue to read
+ from the input stream, or respond with a final status code. The
+ origin server MUST NOT wait for the request body before sending
+ the 100 (Continue) response. If it responds with a final status
+ code, it MAY close the transport connection or it MAY continue
+
+
+
+Fielding, et al. Standards Track [Page 48]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ to read and discard the rest of the request. It MUST NOT
+ perform the requested method if it returns a final status code.
+
+ - An origin server SHOULD NOT send a 100 (Continue) response if
+ the request message does not include an Expect request-header
+ field with the "100-continue" expectation, and MUST NOT send a
+ 100 (Continue) response if such a request comes from an HTTP/1.0
+ (or earlier) client. There is an exception to this rule: for
+ compatibility with RFC 2068, a server MAY send a 100 (Continue)
+ status in response to an HTTP/1.1 PUT or POST request that does
+ not include an Expect request-header field with the "100-
+ continue" expectation. This exception, the purpose of which is
+ to minimize any client processing delays associated with an
+ undeclared wait for 100 (Continue) status, applies only to
+ HTTP/1.1 requests, and not to requests with any other HTTP-
+ version value.
+
+ - An origin server MAY omit a 100 (Continue) response if it has
+ already received some or all of the request body for the
+ corresponding request.
+
+ - An origin server that sends a 100 (Continue) response MUST
+ ultimately send a final status code, once the request body is
+ received and processed, unless it terminates the transport
+ connection prematurely.
+
+ - If an origin server receives a request that does not include an
+ Expect request-header field with the "100-continue" expectation,
+ the request includes a request body, and the server responds
+ with a final status code before reading the entire request body
+ from the transport connection, then the server SHOULD NOT close
+ the transport connection until it has read the entire request,
+ or until the client closes the connection. Otherwise, the client
+ might not reliably receive the response message. However, this
+ requirement is not be construed as preventing a server from
+ defending itself against denial-of-service attacks, or from
+ badly broken client implementations.
+
+ Requirements for HTTP/1.1 proxies:
+
+ - If a proxy receives a request that includes an Expect request-
+ header field with the "100-continue" expectation, and the proxy
+ either knows that the next-hop server complies with HTTP/1.1 or
+ higher, or does not know the HTTP version of the next-hop
+ server, it MUST forward the request, including the Expect header
+ field.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 49]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ - If the proxy knows that the version of the next-hop server is
+ HTTP/1.0 or lower, it MUST NOT forward the request, and it MUST
+ respond with a 417 (Expectation Failed) status.
+
+ - Proxies SHOULD maintain a cache recording the HTTP version
+ numbers received from recently-referenced next-hop servers.
+
+ - A proxy MUST NOT forward a 100 (Continue) response if the
+ request message was received from an HTTP/1.0 (or earlier)
+ client and did not include an Expect request-header field with
+ the "100-continue" expectation. This requirement overrides the
+ general rule for forwarding of 1xx responses (see section 10.1).
+
+8.2.4 Client Behavior if Server Prematurely Closes Connection
+
+ If an HTTP/1.1 client sends a request which includes a request body,
+ but which does not include an Expect request-header field with the
+ "100-continue" expectation, and if the client is not directly
+ connected to an HTTP/1.1 origin server, and if the client sees the
+ connection close before receiving any status from the server, the
+ client SHOULD retry the request. If the client does retry this
+ request, it MAY use the following "binary exponential backoff"
+ algorithm to be assured of obtaining a reliable response:
+
+ 1. Initiate a new connection to the server
+
+ 2. Transmit the request-headers
+
+ 3. Initialize a variable R to the estimated round-trip time to the
+ server (e.g., based on the time it took to establish the
+ connection), or to a constant value of 5 seconds if the round-
+ trip time is not available.
+
+ 4. Compute T = R * (2**N), where N is the number of previous
+ retries of this request.
+
+ 5. Wait either for an error response from the server, or for T
+ seconds (whichever comes first)
+
+ 6. If no error response is received, after T seconds transmit the
+ body of the request.
+
+ 7. If client sees that the connection is closed prematurely,
+ repeat from step 1 until the request is accepted, an error
+ response is received, or the user becomes impatient and
+ terminates the retry process.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 50]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ If at any point an error status is received, the client
+
+ - SHOULD NOT continue and
+
+ - SHOULD close the connection if it has not completed sending the
+ request message.
+
+9 Method Definitions
+
+ The set of common methods for HTTP/1.1 is defined below. Although
+ this set can be expanded, additional methods cannot be assumed to
+ share the same semantics for separately extended clients and servers.
+
+ The Host request-header field (section 14.23) MUST accompany all
+ HTTP/1.1 requests.
+
+9.1 Safe and Idempotent Methods
+
+9.1.1 Safe Methods
+
+ Implementors should be aware that the software represents the user in
+ their interactions over the Internet, and should be careful to allow
+ the user to be aware of any actions they might take which may have an
+ unexpected significance to themselves or others.
+
+ In particular, the convention has been established that the GET and
+ HEAD methods SHOULD NOT have the significance of taking an action
+ other than retrieval. These methods ought to be considered "safe".
+ This allows user agents to represent other methods, such as POST, PUT
+ and DELETE, in a special way, so that the user is made aware of the
+ fact that a possibly unsafe action is being requested.
+
+ Naturally, it is not possible to ensure that the server does not
+ generate side-effects as a result of performing a GET request; in
+ fact, some dynamic resources consider that a feature. The important
+ distinction here is that the user did not request the side-effects,
+ so therefore cannot be held accountable for them.
+
+9.1.2 Idempotent Methods
+
+ Methods can also have the property of "idempotence" in that (aside
+ from error or expiration issues) the side-effects of N > 0 identical
+ requests is the same as for a single request. The methods GET, HEAD,
+ PUT and DELETE share this property. Also, the methods OPTIONS and
+ TRACE SHOULD NOT have side effects, and so are inherently idempotent.
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 51]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ However, it is possible that a sequence of several requests is non-
+ idempotent, even if all of the methods executed in that sequence are
+ idempotent. (A sequence is idempotent if a single execution of the
+ entire sequence always yields a result that is not changed by a
+ reexecution of all, or part, of that sequence.) For example, a
+ sequence is non-idempotent if its result depends on a value that is
+ later modified in the same sequence.
+
+ A sequence that never has side effects is idempotent, by definition
+ (provided that no concurrent operations are being executed on the
+ same set of resources).
+
+9.2 OPTIONS
+
+ The OPTIONS method represents a request for information about the
+ communication options available on the request/response chain
+ identified by the Request-URI. This method allows the client to
+ determine the options and/or requirements associated with a resource,
+ or the capabilities of a server, without implying a resource action
+ or initiating a resource retrieval.
+
+ Responses to this method are not cacheable.
+
+ If the OPTIONS request includes an entity-body (as indicated by the
+ presence of Content-Length or Transfer-Encoding), then the media type
+ MUST be indicated by a Content-Type field. Although this
+ specification does not define any use for such a body, future
+ extensions to HTTP might use the OPTIONS body to make more detailed
+ queries on the server. A server that does not support such an
+ extension MAY discard the request body.
+
+ If the Request-URI is an asterisk ("*"), the OPTIONS request is
+ intended to apply to the server in general rather than to a specific
+ resource. Since a server's communication options typically depend on
+ the resource, the "*" request is only useful as a "ping" or "no-op"
+ type of method; it does nothing beyond allowing the client to test
+ the capabilities of the server. For example, this can be used to test
+ a proxy for HTTP/1.1 compliance (or lack thereof).
+
+ If the Request-URI is not an asterisk, the OPTIONS request applies
+ only to the options that are available when communicating with that
+ resource.
+
+ A 200 response SHOULD include any header fields that indicate
+ optional features implemented by the server and applicable to that
+ resource (e.g., Allow), possibly including extensions not defined by
+ this specification. The response body, if any, SHOULD also include
+ information about the communication options. The format for such a
+
+
+
+Fielding, et al. Standards Track [Page 52]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ body is not defined by this specification, but might be defined by
+ future extensions to HTTP. Content negotiation MAY be used to select
+ the appropriate response format. If no response body is included, the
+ response MUST include a Content-Length field with a field-value of
+ "0".
+
+ The Max-Forwards request-header field MAY be used to target a
+ specific proxy in the request chain. When a proxy receives an OPTIONS
+ request on an absoluteURI for which request forwarding is permitted,
+ the proxy MUST check for a Max-Forwards field. If the Max-Forwards
+ field-value is zero ("0"), the proxy MUST NOT forward the message;
+ instead, the proxy SHOULD respond with its own communication options.
+ If the Max-Forwards field-value is an integer greater than zero, the
+ proxy MUST decrement the field-value when it forwards the request. If
+ no Max-Forwards field is present in the request, then the forwarded
+ request MUST NOT include a Max-Forwards field.
+
+9.3 GET
+
+ The GET method means retrieve whatever information (in the form of an
+ entity) is identified by the Request-URI. If the Request-URI refers
+ to a data-producing process, it is the produced data which shall be
+ returned as the entity in the response and not the source text of the
+ process, unless that text happens to be the output of the process.
+
+ The semantics of the GET method change to a "conditional GET" if the
+ request message includes an If-Modified-Since, If-Unmodified-Since,
+ If-Match, If-None-Match, or If-Range header field. A conditional GET
+ method requests that the entity be transferred only under the
+ circumstances described by the conditional header field(s). The
+ conditional GET method is intended to reduce unnecessary network
+ usage by allowing cached entities to be refreshed without requiring
+ multiple requests or transferring data already held by the client.
+
+ The semantics of the GET method change to a "partial GET" if the
+ request message includes a Range header field. A partial GET requests
+ that only part of the entity be transferred, as described in section
+ 14.35. The partial GET method is intended to reduce unnecessary
+ network usage by allowing partially-retrieved entities to be
+ completed without transferring data already held by the client.
+
+ The response to a GET request is cacheable if and only if it meets
+ the requirements for HTTP caching described in section 13.
+
+ See section 15.1.3 for security considerations when used for forms.
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 53]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+9.4 HEAD
+
+ The HEAD method is identical to GET except that the server MUST NOT
+ return a message-body in the response. The metainformation contained
+ in the HTTP headers in response to a HEAD request SHOULD be identical
+ to the information sent in response to a GET request. This method can
+ be used for obtaining metainformation about the entity implied by the
+ request without transferring the entity-body itself. This method is
+ often used for testing hypertext links for validity, accessibility,
+ and recent modification.
+
+ The response to a HEAD request MAY be cacheable in the sense that the
+ information contained in the response MAY be used to update a
+ previously cached entity from that resource. If the new field values
+ indicate that the cached entity differs from the current entity (as
+ would be indicated by a change in Content-Length, Content-MD5, ETag
+ or Last-Modified), then the cache MUST treat the cache entry as
+ stale.
+
+9.5 POST
+
+ The POST method is used to request that the origin server accept the
+ entity enclosed in the request as a new subordinate of the resource
+ identified by the Request-URI in the Request-Line. POST is designed
+ to allow a uniform method to cover the following functions:
+
+ - Annotation of existing resources;
+
+ - Posting a message to a bulletin board, newsgroup, mailing list,
+ or similar group of articles;
+
+ - Providing a block of data, such as the result of submitting a
+ form, to a data-handling process;
+
+ - Extending a database through an append operation.
+
+ The actual function performed by the POST method is determined by the
+ server and is usually dependent on the Request-URI. The posted entity
+ is subordinate to that URI in the same way that a file is subordinate
+ to a directory containing it, a news article is subordinate to a
+ newsgroup to which it is posted, or a record is subordinate to a
+ database.
+
+ The action performed by the POST method might not result in a
+ resource that can be identified by a URI. In this case, either 200
+ (OK) or 204 (No Content) is the appropriate response status,
+ depending on whether or not the response includes an entity that
+ describes the result.
+
+
+
+Fielding, et al. Standards Track [Page 54]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ If a resource has been created on the origin server, the response
+ SHOULD be 201 (Created) and contain an entity which describes the
+ status of the request and refers to the new resource, and a Location
+ header (see section 14.30).
+
+ Responses to this method are not cacheable, unless the response
+ includes appropriate Cache-Control or Expires header fields. However,
+ the 303 (See Other) response can be used to direct the user agent to
+ retrieve a cacheable resource.
+
+ POST requests MUST obey the message transmission requirements set out
+ in section 8.2.
+
+ See section 15.1.3 for security considerations.
+
+9.6 PUT
+
+ The PUT method requests that the enclosed entity be stored under the
+ supplied Request-URI. If the Request-URI refers to an already
+ existing resource, the enclosed entity SHOULD be considered as a
+ modified version of the one residing on the origin server. If the
+ Request-URI does not point to an existing resource, and that URI is
+ capable of being defined as a new resource by the requesting user
+ agent, the origin server can create the resource with that URI. If a
+ new resource is created, the origin server MUST inform the user agent
+ via the 201 (Created) response. If an existing resource is modified,
+ either the 200 (OK) or 204 (No Content) response codes SHOULD be sent
+ to indicate successful completion of the request. If the resource
+ could not be created or modified with the Request-URI, an appropriate
+ error response SHOULD be given that reflects the nature of the
+ problem. The recipient of the entity MUST NOT ignore any Content-*
+ (e.g. Content-Range) headers that it does not understand or implement
+ and MUST return a 501 (Not Implemented) response in such cases.
+
+ If the request passes through a cache and the Request-URI identifies
+ one or more currently cached entities, those entries SHOULD be
+ treated as stale. Responses to this method are not cacheable.
+
+ The fundamental difference between the POST and PUT requests is
+ reflected in the different meaning of the Request-URI. The URI in a
+ POST request identifies the resource that will handle the enclosed
+ entity. That resource might be a data-accepting process, a gateway to
+ some other protocol, or a separate entity that accepts annotations.
+ In contrast, the URI in a PUT request identifies the entity enclosed
+ with the request -- the user agent knows what URI is intended and the
+ server MUST NOT attempt to apply the request to some other resource.
+ If the server desires that the request be applied to a different URI,
+
+
+
+
+Fielding, et al. Standards Track [Page 55]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ it MUST send a 301 (Moved Permanently) response; the user agent MAY
+ then make its own decision regarding whether or not to redirect the
+ request.
+
+ A single resource MAY be identified by many different URIs. For
+ example, an article might have a URI for identifying "the current
+ version" which is separate from the URI identifying each particular
+ version. In this case, a PUT request on a general URI might result in
+ several other URIs being defined by the origin server.
+
+ HTTP/1.1 does not define how a PUT method affects the state of an
+ origin server.
+
+ PUT requests MUST obey the message transmission requirements set out
+ in section 8.2.
+
+ Unless otherwise specified for a particular entity-header, the
+ entity-headers in the PUT request SHOULD be applied to the resource
+ created or modified by the PUT.
+
+9.7 DELETE
+
+ The DELETE method requests that the origin server delete the resource
+ identified by the Request-URI. This method MAY be overridden by human
+ intervention (or other means) on the origin server. The client cannot
+ be guaranteed that the operation has been carried out, even if the
+ status code returned from the origin server indicates that the action
+ has been completed successfully. However, the server SHOULD NOT
+ indicate success unless, at the time the response is given, it
+ intends to delete the resource or move it to an inaccessible
+ location.
+
+ A successful response SHOULD be 200 (OK) if the response includes an
+ entity describing the status, 202 (Accepted) if the action has not
+ yet been enacted, or 204 (No Content) if the action has been enacted
+ but the response does not include an entity.
+
+ If the request passes through a cache and the Request-URI identifies
+ one or more currently cached entities, those entries SHOULD be
+ treated as stale. Responses to this method are not cacheable.
+
+9.8 TRACE
+
+ The TRACE method is used to invoke a remote, application-layer loop-
+ back of the request message. The final recipient of the request
+ SHOULD reflect the message received back to the client as the
+ entity-body of a 200 (OK) response. The final recipient is either the
+
+
+
+
+Fielding, et al. Standards Track [Page 56]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ origin server or the first proxy or gateway to receive a Max-Forwards
+ value of zero (0) in the request (see section 14.31). A TRACE request
+ MUST NOT include an entity.
+
+ TRACE allows the client to see what is being received at the other
+ end of the request chain and use that data for testing or diagnostic
+ information. The value of the Via header field (section 14.45) is of
+ particular interest, since it acts as a trace of the request chain.
+ Use of the Max-Forwards header field allows the client to limit the
+ length of the request chain, which is useful for testing a chain of
+ proxies forwarding messages in an infinite loop.
+
+ If the request is valid, the response SHOULD contain the entire
+ request message in the entity-body, with a Content-Type of
+ "message/http". Responses to this method MUST NOT be cached.
+
+9.9 CONNECT
+
+ This specification reserves the method name CONNECT for use with a
+ proxy that can dynamically switch to being a tunnel (e.g. SSL
+ tunneling [44]).
+
+10 Status Code Definitions
+
+ Each Status-Code is described below, including a description of which
+ method(s) it can follow and any metainformation required in the
+ response.
+
+10.1 Informational 1xx
+
+ This class of status code indicates a provisional response,
+ consisting only of the Status-Line and optional headers, and is
+ terminated by an empty line. There are no required headers for this
+ class of status code. Since HTTP/1.0 did not define any 1xx status
+ codes, servers MUST NOT send a 1xx response to an HTTP/1.0 client
+ except under experimental conditions.
+
+ A client MUST be prepared to accept one or more 1xx status responses
+ prior to a regular response, even if the client does not expect a 100
+ (Continue) status message. Unexpected 1xx status responses MAY be
+ ignored by a user agent.
+
+ Proxies MUST forward 1xx responses, unless the connection between the
+ proxy and its client has been closed, or unless the proxy itself
+ requested the generation of the 1xx response. (For example, if a
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 57]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ proxy adds a "Expect: 100-continue" field when it forwards a request,
+ then it need not forward the corresponding 100 (Continue)
+ response(s).)
+
+10.1.1 100 Continue
+
+ The client SHOULD continue with its request. This interim response is
+ used to inform the client that the initial part of the request has
+ been received and has not yet been rejected by the server. The client
+ SHOULD continue by sending the remainder of the request or, if the
+ request has already been completed, ignore this response. The server
+ MUST send a final response after the request has been completed. See
+ section 8.2.3 for detailed discussion of the use and handling of this
+ status code.
+
+10.1.2 101 Switching Protocols
+
+ The server understands and is willing to comply with the client's
+ request, via the Upgrade message header field (section 14.42), for a
+ change in the application protocol being used on this connection. The
+ server will switch protocols to those defined by the response's
+ Upgrade header field immediately after the empty line which
+ terminates the 101 response.
+
+ The protocol SHOULD be switched only when it is advantageous to do
+ so. For example, switching to a newer version of HTTP is advantageous
+ over older versions, and switching to a real-time, synchronous
+ protocol might be advantageous when delivering resources that use
+ such features.
+
+10.2 Successful 2xx
+
+ This class of status code indicates that the client's request was
+ successfully received, understood, and accepted.
+
+10.2.1 200 OK
+
+ The request has succeeded. The information returned with the response
+ is dependent on the method used in the request, for example:
+
+ GET an entity corresponding to the requested resource is sent in
+ the response;
+
+ HEAD the entity-header fields corresponding to the requested
+ resource are sent in the response without any message-body;
+
+ POST an entity describing or containing the result of the action;
+
+
+
+
+Fielding, et al. Standards Track [Page 58]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ TRACE an entity containing the request message as received by the
+ end server.
+
+10.2.2 201 Created
+
+ The request has been fulfilled and resulted in a new resource being
+ created. The newly created resource can be referenced by the URI(s)
+ returned in the entity of the response, with the most specific URI
+ for the resource given by a Location header field. The response
+ SHOULD include an entity containing a list of resource
+ characteristics and location(s) from which the user or user agent can
+ choose the one most appropriate. The entity format is specified by
+ the media type given in the Content-Type header field. The origin
+ server MUST create the resource before returning the 201 status code.
+ If the action cannot be carried out immediately, the server SHOULD
+ respond with 202 (Accepted) response instead.
+
+ A 201 response MAY contain an ETag response header field indicating
+ the current value of the entity tag for the requested variant just
+ created, see section 14.19.
+
+10.2.3 202 Accepted
+
+ The request has been accepted for processing, but the processing has
+ not been completed. The request might or might not eventually be
+ acted upon, as it might be disallowed when processing actually takes
+ place. There is no facility for re-sending a status code from an
+ asynchronous operation such as this.
+
+ The 202 response is intentionally non-committal. Its purpose is to
+ allow a server to accept a request for some other process (perhaps a
+ batch-oriented process that is only run once per day) without
+ requiring that the user agent's connection to the server persist
+ until the process is completed. The entity returned with this
+ response SHOULD include an indication of the request's current status
+ and either a pointer to a status monitor or some estimate of when the
+ user can expect the request to be fulfilled.
+
+10.2.4 203 Non-Authoritative Information
+
+ The returned metainformation in the entity-header is not the
+ definitive set as available from the origin server, but is gathered
+ from a local or a third-party copy. The set presented MAY be a subset
+ or superset of the original version. For example, including local
+ annotation information about the resource might result in a superset
+ of the metainformation known by the origin server. Use of this
+ response code is not required and is only appropriate when the
+ response would otherwise be 200 (OK).
+
+
+
+Fielding, et al. Standards Track [Page 59]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+10.2.5 204 No Content
+
+ The server has fulfilled the request but does not need to return an
+ entity-body, and might want to return updated metainformation. The
+ response MAY include new or updated metainformation in the form of
+ entity-headers, which if present SHOULD be associated with the
+ requested variant.
+
+ If the client is a user agent, it SHOULD NOT change its document view
+ from that which caused the request to be sent. This response is
+ primarily intended to allow input for actions to take place without
+ causing a change to the user agent's active document view, although
+ any new or updated metainformation SHOULD be applied to the document
+ currently in the user agent's active view.
+
+ The 204 response MUST NOT include a message-body, and thus is always
+ terminated by the first empty line after the header fields.
+
+10.2.6 205 Reset Content
+
+ The server has fulfilled the request and the user agent SHOULD reset
+ the document view which caused the request to be sent. This response
+ is primarily intended to allow input for actions to take place via
+ user input, followed by a clearing of the form in which the input is
+ given so that the user can easily initiate another input action. The
+ response MUST NOT include an entity.
+
+10.2.7 206 Partial Content
+
+ The server has fulfilled the partial GET request for the resource.
+ The request MUST have included a Range header field (section 14.35)
+ indicating the desired range, and MAY have included an If-Range
+ header field (section 14.27) to make the request conditional.
+
+ The response MUST include the following header fields:
+
+ - Either a Content-Range header field (section 14.16) indicating
+ the range included with this response, or a multipart/byteranges
+ Content-Type including Content-Range fields for each part. If a
+ Content-Length header field is present in the response, its
+ value MUST match the actual number of OCTETs transmitted in the
+ message-body.
+
+ - Date
+
+ - ETag and/or Content-Location, if the header would have been sent
+ in a 200 response to the same request
+
+
+
+
+Fielding, et al. Standards Track [Page 60]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ - Expires, Cache-Control, and/or Vary, if the field-value might
+ differ from that sent in any previous response for the same
+ variant
+
+ If the 206 response is the result of an If-Range request that used a
+ strong cache validator (see section 13.3.3), the response SHOULD NOT
+ include other entity-headers. If the response is the result of an
+ If-Range request that used a weak validator, the response MUST NOT
+ include other entity-headers; this prevents inconsistencies between
+ cached entity-bodies and updated headers. Otherwise, the response
+ MUST include all of the entity-headers that would have been returned
+ with a 200 (OK) response to the same request.
+
+ A cache MUST NOT combine a 206 response with other previously cached
+ content if the ETag or Last-Modified headers do not match exactly,
+ see 13.5.4.
+
+ A cache that does not support the Range and Content-Range headers
+ MUST NOT cache 206 (Partial) responses.
+
+10.3 Redirection 3xx
+
+ This class of status code indicates that further action needs to be
+ taken by the user agent in order to fulfill the request. The action
+ required MAY be carried out by the user agent without interaction
+ with the user if and only if the method used in the second request is
+ GET or HEAD. A client SHOULD detect infinite redirection loops, since
+ such loops generate network traffic for each redirection.
+
+ Note: previous versions of this specification recommended a
+ maximum of five redirections. Content developers should be aware
+ that there might be clients that implement such a fixed
+ limitation.
+
+10.3.1 300 Multiple Choices
+
+ The requested resource corresponds to any one of a set of
+ representations, each with its own specific location, and agent-
+ driven negotiation information (section 12) is being provided so that
+ the user (or user agent) can select a preferred representation and
+ redirect its request to that location.
+
+ Unless it was a HEAD request, the response SHOULD include an entity
+ containing a list of resource characteristics and location(s) from
+ which the user or user agent can choose the one most appropriate. The
+ entity format is specified by the media type given in the Content-
+ Type header field. Depending upon the format and the capabilities of
+
+
+
+
+Fielding, et al. Standards Track [Page 61]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ the user agent, selection of the most appropriate choice MAY be
+ performed automatically. However, this specification does not define
+ any standard for such automatic selection.
+
+ If the server has a preferred choice of representation, it SHOULD
+ include the specific URI for that representation in the Location
+ field; user agents MAY use the Location field value for automatic
+ redirection. This response is cacheable unless indicated otherwise.
+
+10.3.2 301 Moved Permanently
+
+ The requested resource has been assigned a new permanent URI and any
+ future references to this resource SHOULD use one of the returned
+ URIs. Clients with link editing capabilities ought to automatically
+ re-link references to the Request-URI to one or more of the new
+ references returned by the server, where possible. This response is
+ cacheable unless indicated otherwise.
+
+ The new permanent URI SHOULD be given by the Location field in the
+ response. Unless the request method was HEAD, the entity of the
+ response SHOULD contain a short hypertext note with a hyperlink to
+ the new URI(s).
+
+ If the 301 status code is received in response to a request other
+ than GET or HEAD, the user agent MUST NOT automatically redirect the
+ request unless it can be confirmed by the user, since this might
+ change the conditions under which the request was issued.
+
+ Note: When automatically redirecting a POST request after
+ receiving a 301 status code, some existing HTTP/1.0 user agents
+ will erroneously change it into a GET request.
+
+10.3.3 302 Found
+
+ The requested resource resides temporarily under a different URI.
+ Since the redirection might be altered on occasion, the client SHOULD
+ continue to use the Request-URI for future requests. This response
+ is only cacheable if indicated by a Cache-Control or Expires header
+ field.
+
+ The temporary URI SHOULD be given by the Location field in the
+ response. Unless the request method was HEAD, the entity of the
+ response SHOULD contain a short hypertext note with a hyperlink to
+ the new URI(s).
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 62]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ If the 302 status code is received in response to a request other
+ than GET or HEAD, the user agent MUST NOT automatically redirect the
+ request unless it can be confirmed by the user, since this might
+ change the conditions under which the request was issued.
+
+ Note: RFC 1945 and RFC 2068 specify that the client is not allowed
+ to change the method on the redirected request. However, most
+ existing user agent implementations treat 302 as if it were a 303
+ response, performing a GET on the Location field-value regardless
+ of the original request method. The status codes 303 and 307 have
+ been added for servers that wish to make unambiguously clear which
+ kind of reaction is expected of the client.
+
+10.3.4 303 See Other
+
+ The response to the request can be found under a different URI and
+ SHOULD be retrieved using a GET method on that resource. This method
+ exists primarily to allow the output of a POST-activated script to
+ redirect the user agent to a selected resource. The new URI is not a
+ substitute reference for the originally requested resource. The 303
+ response MUST NOT be cached, but the response to the second
+ (redirected) request might be cacheable.
+
+ The different URI SHOULD be given by the Location field in the
+ response. Unless the request method was HEAD, the entity of the
+ response SHOULD contain a short hypertext note with a hyperlink to
+ the new URI(s).
+
+ Note: Many pre-HTTP/1.1 user agents do not understand the 303
+ status. When interoperability with such clients is a concern, the
+ 302 status code may be used instead, since most user agents react
+ to a 302 response as described here for 303.
+
+10.3.5 304 Not Modified
+
+ If the client has performed a conditional GET request and access is
+ allowed, but the document has not been modified, the server SHOULD
+ respond with this status code. The 304 response MUST NOT contain a
+ message-body, and thus is always terminated by the first empty line
+ after the header fields.
+
+ The response MUST include the following header fields:
+
+ - Date, unless its omission is required by section 14.18.1
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 63]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ If a clockless origin server obeys these rules, and proxies and
+ clients add their own Date to any response received without one (as
+ already specified by [RFC 2068], section 14.19), caches will operate
+ correctly.
+
+ - ETag and/or Content-Location, if the header would have been sent
+ in a 200 response to the same request
+
+ - Expires, Cache-Control, and/or Vary, if the field-value might
+ differ from that sent in any previous response for the same
+ variant
+
+ If the conditional GET used a strong cache validator (see section
+ 13.3.3), the response SHOULD NOT include other entity-headers.
+ Otherwise (i.e., the conditional GET used a weak validator), the
+ response MUST NOT include other entity-headers; this prevents
+ inconsistencies between cached entity-bodies and updated headers.
+
+ If a 304 response indicates an entity not currently cached, then the
+ cache MUST disregard the response and repeat the request without the
+ conditional.
+
+ If a cache uses a received 304 response to update a cache entry, the
+ cache MUST update the entry to reflect any new field values given in
+ the response.
+
+10.3.6 305 Use Proxy
+
+ The requested resource MUST be accessed through the proxy given by
+ the Location field. The Location field gives the URI of the proxy.
+ The recipient is expected to repeat this single request via the
+ proxy. 305 responses MUST only be generated by origin servers.
+
+ Note: RFC 2068 was not clear that 305 was intended to redirect a
+ single request, and to be generated by origin servers only. Not
+ observing these limitations has significant security consequences.
+
+10.3.7 306 (Unused)
+
+ The 306 status code was used in a previous version of the
+ specification, is no longer used, and the code is reserved.
+
+
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 64]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+10.3.8 307 Temporary Redirect
+
+ The requested resource resides temporarily under a different URI.
+ Since the redirection MAY be altered on occasion, the client SHOULD
+ continue to use the Request-URI for future requests. This response
+ is only cacheable if indicated by a Cache-Control or Expires header
+ field.
+
+ The temporary URI SHOULD be given by the Location field in the
+ response. Unless the request method was HEAD, the entity of the
+ response SHOULD contain a short hypertext note with a hyperlink to
+ the new URI(s) , since many pre-HTTP/1.1 user agents do not
+ understand the 307 status. Therefore, the note SHOULD contain the
+ information necessary for a user to repeat the original request on
+ the new URI.
+
+ If the 307 status code is received in response to a request other
+ than GET or HEAD, the user agent MUST NOT automatically redirect the
+ request unless it can be confirmed by the user, since this might
+ change the conditions under which the request was issued.
+
+10.4 Client Error 4xx
+
+ The 4xx class of status code is intended for cases in which the
+ client seems to have erred. Except when responding to a HEAD request,
+ the server SHOULD include an entity containing an explanation of the
+ error situation, and whether it is a temporary or permanent
+ condition. These status codes are applicable to any request method.
+ User agents SHOULD display any included entity to the user.
+
+ If the client is sending data, a server implementation using TCP
+ SHOULD be careful to ensure that the client acknowledges receipt of
+ the packet(s) containing the response, before the server closes the
+ input connection. If the client continues sending data to the server
+ after the close, the server's TCP stack will send a reset packet to
+ the client, which may erase the client's unacknowledged input buffers
+ before they can be read and interpreted by the HTTP application.
+
+10.4.1 400 Bad Request
+
+ The request could not be understood by the server due to malformed
+ syntax. The client SHOULD NOT repeat the request without
+ modifications.
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 65]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+10.4.2 401 Unauthorized
+
+ The request requires user authentication. The response MUST include a
+ WWW-Authenticate header field (section 14.47) containing a challenge
+ applicable to the requested resource. The client MAY repeat the
+ request with a suitable Authorization header field (section 14.8). If
+ the request already included Authorization credentials, then the 401
+ response indicates that authorization has been refused for those
+ credentials. If the 401 response contains the same challenge as the
+ prior response, and the user agent has already attempted
+ authentication at least once, then the user SHOULD be presented the
+ entity that was given in the response, since that entity might
+ include relevant diagnostic information. HTTP access authentication
+ is explained in "HTTP Authentication: Basic and Digest Access
+ Authentication" [43].
+
+10.4.3 402 Payment Required
+
+ This code is reserved for future use.
+
+10.4.4 403 Forbidden
+
+ The server understood the request, but is refusing to fulfill it.
+ Authorization will not help and the request SHOULD NOT be repeated.
+ If the request method was not HEAD and the server wishes to make
+ public why the request has not been fulfilled, it SHOULD describe the
+ reason for the refusal in the entity. If the server does not wish to
+ make this information available to the client, the status code 404
+ (Not Found) can be used instead.
+
+10.4.5 404 Not Found
+
+ The server has not found anything matching the Request-URI. No
+ indication is given of whether the condition is temporary or
+ permanent. The 410 (Gone) status code SHOULD be used if the server
+ knows, through some internally configurable mechanism, that an old
+ resource is permanently unavailable and has no forwarding address.
+ This status code is commonly used when the server does not wish to
+ reveal exactly why the request has been refused, or when no other
+ response is applicable.
+
+10.4.6 405 Method Not Allowed
+
+ The method specified in the Request-Line is not allowed for the
+ resource identified by the Request-URI. The response MUST include an
+ Allow header containing a list of valid methods for the requested
+ resource.
+
+
+
+
+Fielding, et al. Standards Track [Page 66]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+10.4.7 406 Not Acceptable
+
+ The resource identified by the request is only capable of generating
+ response entities which have content characteristics not acceptable
+ according to the accept headers sent in the request.
+
+ Unless it was a HEAD request, the response SHOULD include an entity
+ containing a list of available entity characteristics and location(s)
+ from which the user or user agent can choose the one most
+ appropriate. The entity format is specified by the media type given
+ in the Content-Type header field. Depending upon the format and the
+ capabilities of the user agent, selection of the most appropriate
+ choice MAY be performed automatically. However, this specification
+ does not define any standard for such automatic selection.
+
+ Note: HTTP/1.1 servers are allowed to return responses which are
+ not acceptable according to the accept headers sent in the
+ request. In some cases, this may even be preferable to sending a
+ 406 response. User agents are encouraged to inspect the headers of
+ an incoming response to determine if it is acceptable.
+
+ If the response could be unacceptable, a user agent SHOULD
+ temporarily stop receipt of more data and query the user for a
+ decision on further actions.
+
+10.4.8 407 Proxy Authentication Required
+
+ This code is similar to 401 (Unauthorized), but indicates that the
+ client must first authenticate itself with the proxy. The proxy MUST
+ return a Proxy-Authenticate header field (section 14.33) containing a
+ challenge applicable to the proxy for the requested resource. The
+ client MAY repeat the request with a suitable Proxy-Authorization
+ header field (section 14.34). HTTP access authentication is explained
+ in "HTTP Authentication: Basic and Digest Access Authentication"
+ [43].
+
+10.4.9 408 Request Timeout
+
+ The client did not produce a request within the time that the server
+ was prepared to wait. The client MAY repeat the request without
+ modifications at any later time.
+
+10.4.10 409 Conflict
+
+ The request could not be completed due to a conflict with the current
+ state of the resource. This code is only allowed in situations where
+ it is expected that the user might be able to resolve the conflict
+ and resubmit the request. The response body SHOULD include enough
+
+
+
+Fielding, et al. Standards Track [Page 67]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ information for the user to recognize the source of the conflict.
+ Ideally, the response entity would include enough information for the
+ user or user agent to fix the problem; however, that might not be
+ possible and is not required.
+
+ Conflicts are most likely to occur in response to a PUT request. For
+ example, if versioning were being used and the entity being PUT
+ included changes to a resource which conflict with those made by an
+ earlier (third-party) request, the server might use the 409 response
+ to indicate that it can't complete the request. In this case, the
+ response entity would likely contain a list of the differences
+ between the two versions in a format defined by the response
+ Content-Type.
+
+10.4.11 410 Gone
+
+ The requested resource is no longer available at the server and no
+ forwarding address is known. This condition is expected to be
+ considered permanent. Clients with link editing capabilities SHOULD
+ delete references to the Request-URI after user approval. If the
+ server does not know, or has no facility to determine, whether or not
+ the condition is permanent, the status code 404 (Not Found) SHOULD be
+ used instead. This response is cacheable unless indicated otherwise.
+
+ The 410 response is primarily intended to assist the task of web
+ maintenance by notifying the recipient that the resource is
+ intentionally unavailable and that the server owners desire that
+ remote links to that resource be removed. Such an event is common for
+ limited-time, promotional services and for resources belonging to
+ individuals no longer working at the server's site. It is not
+ necessary to mark all permanently unavailable resources as "gone" or
+ to keep the mark for any length of time -- that is left to the
+ discretion of the server owner.
+
+10.4.12 411 Length Required
+
+ The server refuses to accept the request without a defined Content-
+ Length. The client MAY repeat the request if it adds a valid
+ Content-Length header field containing the length of the message-body
+ in the request message.
+
+10.4.13 412 Precondition Failed
+
+ The precondition given in one or more of the request-header fields
+ evaluated to false when it was tested on the server. This response
+ code allows the client to place preconditions on the current resource
+ metainformation (header field data) and thus prevent the requested
+ method from being applied to a resource other than the one intended.
+
+
+
+Fielding, et al. Standards Track [Page 68]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+10.4.14 413 Request Entity Too Large
+
+ The server is refusing to process a request because the request
+ entity is larger than the server is willing or able to process. The
+ server MAY close the connection to prevent the client from continuing
+ the request.
+
+ If the condition is temporary, the server SHOULD include a Retry-
+ After header field to indicate that it is temporary and after what
+ time the client MAY try again.
+
+10.4.15 414 Request-URI Too Long
+
+ The server is refusing to service the request because the Request-URI
+ is longer than the server is willing to interpret. This rare
+ condition is only likely to occur when a client has improperly
+ converted a POST request to a GET request with long query
+ information, when the client has descended into a URI "black hole" of
+ redirection (e.g., a redirected URI prefix that points to a suffix of
+ itself), or when the server is under attack by a client attempting to
+ exploit security holes present in some servers using fixed-length
+ buffers for reading or manipulating the Request-URI.
+
+10.4.16 415 Unsupported Media Type
+
+ The server is refusing to service the request because the entity of
+ the request is in a format not supported by the requested resource
+ for the requested method.
+
+10.4.17 416 Requested Range Not Satisfiable
+
+ A server SHOULD return a response with this status code if a request
+ included a Range request-header field (section 14.35), and none of
+ the range-specifier values in this field overlap the current extent
+ of the selected resource, and the request did not include an If-Range
+ request-header field. (For byte-ranges, this means that the first-
+ byte-pos of all of the byte-range-spec values were greater than the
+ current length of the selected resource.)
+
+ When this status code is returned for a byte-range request, the
+ response SHOULD include a Content-Range entity-header field
+ specifying the current length of the selected resource (see section
+ 14.16). This response MUST NOT use the multipart/byteranges content-
+ type.
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 69]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+10.4.18 417 Expectation Failed
+
+ The expectation given in an Expect request-header field (see section
+ 14.20) could not be met by this server, or, if the server is a proxy,
+ the server has unambiguous evidence that the request could not be met
+ by the next-hop server.
+
+10.5 Server Error 5xx
+
+ Response status codes beginning with the digit "5" indicate cases in
+ which the server is aware that it has erred or is incapable of
+ performing the request. Except when responding to a HEAD request, the
+ server SHOULD include an entity containing an explanation of the
+ error situation, and whether it is a temporary or permanent
+ condition. User agents SHOULD display any included entity to the
+ user. These response codes are applicable to any request method.
+
+10.5.1 500 Internal Server Error
+
+ The server encountered an unexpected condition which prevented it
+ from fulfilling the request.
+
+10.5.2 501 Not Implemented
+
+ The server does not support the functionality required to fulfill the
+ request. This is the appropriate response when the server does not
+ recognize the request method and is not capable of supporting it for
+ any resource.
+
+10.5.3 502 Bad Gateway
+
+ The server, while acting as a gateway or proxy, received an invalid
+ response from the upstream server it accessed in attempting to
+ fulfill the request.
+
+10.5.4 503 Service Unavailable
+
+ The server is currently unable to handle the request due to a
+ temporary overloading or maintenance of the server. The implication
+ is that this is a temporary condition which will be alleviated after
+ some delay. If known, the length of the delay MAY be indicated in a
+ Retry-After header. If no Retry-After is given, the client SHOULD
+ handle the response as it would for a 500 response.
+
+ Note: The existence of the 503 status code does not imply that a
+ server must use it when becoming overloaded. Some servers may wish
+ to simply refuse the connection.
+
+
+
+
+Fielding, et al. Standards Track [Page 70]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+10.5.5 504 Gateway Timeout
+
+ The server, while acting as a gateway or proxy, did not receive a
+ timely response from the upstream server specified by the URI (e.g.
+ HTTP, FTP, LDAP) or some other auxiliary server (e.g. DNS) it needed
+ to access in attempting to complete the request.
+
+ Note: Note to implementors: some deployed proxies are known to
+ return 400 or 500 when DNS lookups time out.
+
+10.5.6 505 HTTP Version Not Supported
+
+ The server does not support, or refuses to support, the HTTP protocol
+ version that was used in the request message. The server is
+ indicating that it is unable or unwilling to complete the request
+ using the same major version as the client, as described in section
+ 3.1, other than with this error message. The response SHOULD contain
+ an entity describing why that version is not supported and what other
+ protocols are supported by that server.
+
+11 Access Authentication
+
+ HTTP provides several OPTIONAL challenge-response authentication
+ mechanisms which can be used by a server to challenge a client
+ request and by a client to provide authentication information. The
+ general framework for access authentication, and the specification of
+ "basic" and "digest" authentication, are specified in "HTTP
+ Authentication: Basic and Digest Access Authentication" [43]. This
+ specification adopts the definitions of "challenge" and "credentials"
+ from that specification.
+
+12 Content Negotiation
+
+ Most HTTP responses include an entity which contains information for
+ interpretation by a human user. Naturally, it is desirable to supply
+ the user with the "best available" entity corresponding to the
+ request. Unfortunately for servers and caches, not all users have the
+ same preferences for what is "best," and not all user agents are
+ equally capable of rendering all entity types. For that reason, HTTP
+ has provisions for several mechanisms for "content negotiation" --
+ the process of selecting the best representation for a given response
+ when there are multiple representations available.
+
+ Note: This is not called "format negotiation" because the
+ alternate representations may be of the same media type, but use
+ different capabilities of that type, be in different languages,
+ etc.
+
+
+
+
+Fielding, et al. Standards Track [Page 71]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Any response containing an entity-body MAY be subject to negotiation,
+ including error responses.
+
+ There are two kinds of content negotiation which are possible in
+ HTTP: server-driven and agent-driven negotiation. These two kinds of
+ negotiation are orthogonal and thus may be used separately or in
+ combination. One method of combination, referred to as transparent
+ negotiation, occurs when a cache uses the agent-driven negotiation
+ information provided by the origin server in order to provide
+ server-driven negotiation for subsequent requests.
+
+12.1 Server-driven Negotiation
+
+ If the selection of the best representation for a response is made by
+ an algorithm located at the server, it is called server-driven
+ negotiation. Selection is based on the available representations of
+ the response (the dimensions over which it can vary; e.g. language,
+ content-coding, etc.) and the contents of particular header fields in
+ the request message or on other information pertaining to the request
+ (such as the network address of the client).
+
+ Server-driven negotiation is advantageous when the algorithm for
+ selecting from among the available representations is difficult to
+ describe to the user agent, or when the server desires to send its
+ "best guess" to the client along with the first response (hoping to
+ avoid the round-trip delay of a subsequent request if the "best
+ guess" is good enough for the user). In order to improve the server's
+ guess, the user agent MAY include request header fields (Accept,
+ Accept-Language, Accept-Encoding, etc.) which describe its
+ preferences for such a response.
+
+ Server-driven negotiation has disadvantages:
+
+ 1. It is impossible for the server to accurately determine what
+ might be "best" for any given user, since that would require
+ complete knowledge of both the capabilities of the user agent
+ and the intended use for the response (e.g., does the user want
+ to view it on screen or print it on paper?).
+
+ 2. Having the user agent describe its capabilities in every
+ request can be both very inefficient (given that only a small
+ percentage of responses have multiple representations) and a
+ potential violation of the user's privacy.
+
+ 3. It complicates the implementation of an origin server and the
+ algorithms for generating responses to a request.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 72]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 4. It may limit a public cache's ability to use the same response
+ for multiple user's requests.
+
+ HTTP/1.1 includes the following request-header fields for enabling
+ server-driven negotiation through description of user agent
+ capabilities and user preferences: Accept (section 14.1), Accept-
+ Charset (section 14.2), Accept-Encoding (section 14.3), Accept-
+ Language (section 14.4), and User-Agent (section 14.43). However, an
+ origin server is not limited to these dimensions and MAY vary the
+ response based on any aspect of the request, including information
+ outside the request-header fields or within extension header fields
+ not defined by this specification.
+
+ The Vary header field can be used to express the parameters the
+ server uses to select a representation that is subject to server-
+ driven negotiation. See section 13.6 for use of the Vary header field
+ by caches and section 14.44 for use of the Vary header field by
+ servers.
+
+12.2 Agent-driven Negotiation
+
+ With agent-driven negotiation, selection of the best representation
+ for a response is performed by the user agent after receiving an
+ initial response from the origin server. Selection is based on a list
+ of the available representations of the response included within the
+ header fields or entity-body of the initial response, with each
+ representation identified by its own URI. Selection from among the
+ representations may be performed automatically (if the user agent is
+ capable of doing so) or manually by the user selecting from a
+ generated (possibly hypertext) menu.
+
+ Agent-driven negotiation is advantageous when the response would vary
+ over commonly-used dimensions (such as type, language, or encoding),
+ when the origin server is unable to determine a user agent's
+ capabilities from examining the request, and generally when public
+ caches are used to distribute server load and reduce network usage.
+
+ Agent-driven negotiation suffers from the disadvantage of needing a
+ second request to obtain the best alternate representation. This
+ second request is only efficient when caching is used. In addition,
+ this specification does not define any mechanism for supporting
+ automatic selection, though it also does not prevent any such
+ mechanism from being developed as an extension and used within
+ HTTP/1.1.
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 73]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ HTTP/1.1 defines the 300 (Multiple Choices) and 406 (Not Acceptable)
+ status codes for enabling agent-driven negotiation when the server is
+ unwilling or unable to provide a varying response using server-driven
+ negotiation.
+
+12.3 Transparent Negotiation
+
+ Transparent negotiation is a combination of both server-driven and
+ agent-driven negotiation. When a cache is supplied with a form of the
+ list of available representations of the response (as in agent-driven
+ negotiation) and the dimensions of variance are completely understood
+ by the cache, then the cache becomes capable of performing server-
+ driven negotiation on behalf of the origin server for subsequent
+ requests on that resource.
+
+ Transparent negotiation has the advantage of distributing the
+ negotiation work that would otherwise be required of the origin
+ server and also removing the second request delay of agent-driven
+ negotiation when the cache is able to correctly guess the right
+ response.
+
+ This specification does not define any mechanism for transparent
+ negotiation, though it also does not prevent any such mechanism from
+ being developed as an extension that could be used within HTTP/1.1.
+
+13 Caching in HTTP
+
+ HTTP is typically used for distributed information systems, where
+ performance can be improved by the use of response caches. The
+ HTTP/1.1 protocol includes a number of elements intended to make
+ caching work as well as possible. Because these elements are
+ inextricable from other aspects of the protocol, and because they
+ interact with each other, it is useful to describe the basic caching
+ design of HTTP separately from the detailed descriptions of methods,
+ headers, response codes, etc.
+
+ Caching would be useless if it did not significantly improve
+ performance. The goal of caching in HTTP/1.1 is to eliminate the need
+ to send requests in many cases, and to eliminate the need to send
+ full responses in many other cases. The former reduces the number of
+ network round-trips required for many operations; we use an
+ "expiration" mechanism for this purpose (see section 13.2). The
+ latter reduces network bandwidth requirements; we use a "validation"
+ mechanism for this purpose (see section 13.3).
+
+ Requirements for performance, availability, and disconnected
+ operation require us to be able to relax the goal of semantic
+ transparency. The HTTP/1.1 protocol allows origin servers, caches,
+
+
+
+Fielding, et al. Standards Track [Page 74]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ and clients to explicitly reduce transparency when necessary.
+ However, because non-transparent operation may confuse non-expert
+ users, and might be incompatible with certain server applications
+ (such as those for ordering merchandise), the protocol requires that
+ transparency be relaxed
+
+ - only by an explicit protocol-level request when relaxed by
+ client or origin server
+
+ - only with an explicit warning to the end user when relaxed by
+ cache or client
+
+ Therefore, the HTTP/1.1 protocol provides these important elements:
+
+ 1. Protocol features that provide full semantic transparency when
+ this is required by all parties.
+
+ 2. Protocol features that allow an origin server or user agent to
+ explicitly request and control non-transparent operation.
+
+ 3. Protocol features that allow a cache to attach warnings to
+ responses that do not preserve the requested approximation of
+ semantic transparency.
+
+ A basic principle is that it must be possible for the clients to
+ detect any potential relaxation of semantic transparency.
+
+ Note: The server, cache, or client implementor might be faced with
+ design decisions not explicitly discussed in this specification.
+ If a decision might affect semantic transparency, the implementor
+ ought to err on the side of maintaining transparency unless a
+ careful and complete analysis shows significant benefits in
+ breaking transparency.
+
+13.1.1 Cache Correctness
+
+ A correct cache MUST respond to a request with the most up-to-date
+ response held by the cache that is appropriate to the request (see
+ sections 13.2.5, 13.2.6, and 13.12) which meets one of the following
+ conditions:
+
+ 1. It has been checked for equivalence with what the origin server
+ would have returned by revalidating the response with the
+ origin server (section 13.3);
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 75]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 2. It is "fresh enough" (see section 13.2). In the default case,
+ this means it meets the least restrictive freshness requirement
+ of the client, origin server, and cache (see section 14.9); if
+ the origin server so specifies, it is the freshness requirement
+ of the origin server alone.
+
+ If a stored response is not "fresh enough" by the most
+ restrictive freshness requirement of both the client and the
+ origin server, in carefully considered circumstances the cache
+ MAY still return the response with the appropriate Warning
+ header (see section 13.1.5 and 14.46), unless such a response
+ is prohibited (e.g., by a "no-store" cache-directive, or by a
+ "no-cache" cache-request-directive; see section 14.9).
+
+ 3. It is an appropriate 304 (Not Modified), 305 (Proxy Redirect),
+ or error (4xx or 5xx) response message.
+
+ If the cache can not communicate with the origin server, then a
+ correct cache SHOULD respond as above if the response can be
+ correctly served from the cache; if not it MUST return an error or
+ warning indicating that there was a communication failure.
+
+ If a cache receives a response (either an entire response, or a 304
+ (Not Modified) response) that it would normally forward to the
+ requesting client, and the received response is no longer fresh, the
+ cache SHOULD forward it to the requesting client without adding a new
+ Warning (but without removing any existing Warning headers). A cache
+ SHOULD NOT attempt to revalidate a response simply because that
+ response became stale in transit; this might lead to an infinite
+ loop. A user agent that receives a stale response without a Warning
+ MAY display a warning indication to the user.
+
+13.1.2 Warnings
+
+ Whenever a cache returns a response that is neither first-hand nor
+ "fresh enough" (in the sense of condition 2 in section 13.1.1), it
+ MUST attach a warning to that effect, using a Warning general-header.
+ The Warning header and the currently defined warnings are described
+ in section 14.46. The warning allows clients to take appropriate
+ action.
+
+ Warnings MAY be used for other purposes, both cache-related and
+ otherwise. The use of a warning, rather than an error status code,
+ distinguish these responses from true failures.
+
+ Warnings are assigned three digit warn-codes. The first digit
+ indicates whether the Warning MUST or MUST NOT be deleted from a
+ stored cache entry after a successful revalidation:
+
+
+
+Fielding, et al. Standards Track [Page 76]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 1xx Warnings that describe the freshness or revalidation status of
+ the response, and so MUST be deleted after a successful
+ revalidation. 1XX warn-codes MAY be generated by a cache only when
+ validating a cached entry. It MUST NOT be generated by clients.
+
+ 2xx Warnings that describe some aspect of the entity body or entity
+ headers that is not rectified by a revalidation (for example, a
+ lossy compression of the entity bodies) and which MUST NOT be
+ deleted after a successful revalidation.
+
+ See section 14.46 for the definitions of the codes themselves.
+
+ HTTP/1.0 caches will cache all Warnings in responses, without
+ deleting the ones in the first category. Warnings in responses that
+ are passed to HTTP/1.0 caches carry an extra warning-date field,
+ which prevents a future HTTP/1.1 recipient from believing an
+ erroneously cached Warning.
+
+ Warnings also carry a warning text. The text MAY be in any
+ appropriate natural language (perhaps based on the client's Accept
+ headers), and include an OPTIONAL indication of what character set is
+ used.
+
+ Multiple warnings MAY be attached to a response (either by the origin
+ server or by a cache), including multiple warnings with the same code
+ number. For example, a server might provide the same warning with
+ texts in both English and Basque.
+
+ When multiple warnings are attached to a response, it might not be
+ practical or reasonable to display all of them to the user. This
+ version of HTTP does not specify strict priority rules for deciding
+ which warnings to display and in what order, but does suggest some
+ heuristics.
+
+13.1.3 Cache-control Mechanisms
+
+ The basic cache mechanisms in HTTP/1.1 (server-specified expiration
+ times and validators) are implicit directives to caches. In some
+ cases, a server or client might need to provide explicit directives
+ to the HTTP caches. We use the Cache-Control header for this purpose.
+
+ The Cache-Control header allows a client or server to transmit a
+ variety of directives in either requests or responses. These
+ directives typically override the default caching algorithms. As a
+ general rule, if there is any apparent conflict between header
+ values, the most restrictive interpretation is applied (that is, the
+ one that is most likely to preserve semantic transparency). However,
+
+
+
+
+Fielding, et al. Standards Track [Page 77]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ in some cases, cache-control directives are explicitly specified as
+ weakening the approximation of semantic transparency (for example,
+ "max-stale" or "public").
+
+ The cache-control directives are described in detail in section 14.9.
+
+13.1.4 Explicit User Agent Warnings
+
+ Many user agents make it possible for users to override the basic
+ caching mechanisms. For example, the user agent might allow the user
+ to specify that cached entities (even explicitly stale ones) are
+ never validated. Or the user agent might habitually add "Cache-
+ Control: max-stale=3600" to every request. The user agent SHOULD NOT
+ default to either non-transparent behavior, or behavior that results
+ in abnormally ineffective caching, but MAY be explicitly configured
+ to do so by an explicit action of the user.
+
+ If the user has overridden the basic caching mechanisms, the user
+ agent SHOULD explicitly indicate to the user whenever this results in
+ the display of information that might not meet the server's
+ transparency requirements (in particular, if the displayed entity is
+ known to be stale). Since the protocol normally allows the user agent
+ to determine if responses are stale or not, this indication need only
+ be displayed when this actually happens. The indication need not be a
+ dialog box; it could be an icon (for example, a picture of a rotting
+ fish) or some other indicator.
+
+ If the user has overridden the caching mechanisms in a way that would
+ abnormally reduce the effectiveness of caches, the user agent SHOULD
+ continually indicate this state to the user (for example, by a
+ display of a picture of currency in flames) so that the user does not
+ inadvertently consume excess resources or suffer from excessive
+ latency.
+
+13.1.5 Exceptions to the Rules and Warnings
+
+ In some cases, the operator of a cache MAY choose to configure it to
+ return stale responses even when not requested by clients. This
+ decision ought not be made lightly, but may be necessary for reasons
+ of availability or performance, especially when the cache is poorly
+ connected to the origin server. Whenever a cache returns a stale
+ response, it MUST mark it as such (using a Warning header) enabling
+ the client software to alert the user that there might be a potential
+ problem.
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 78]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ It also allows the user agent to take steps to obtain a first-hand or
+ fresh response. For this reason, a cache SHOULD NOT return a stale
+ response if the client explicitly requests a first-hand or fresh one,
+ unless it is impossible to comply for technical or policy reasons.
+
+13.1.6 Client-controlled Behavior
+
+ While the origin server (and to a lesser extent, intermediate caches,
+ by their contribution to the age of a response) are the primary
+ source of expiration information, in some cases the client might need
+ to control a cache's decision about whether to return a cached
+ response without validating it. Clients do this using several
+ directives of the Cache-Control header.
+
+ A client's request MAY specify the maximum age it is willing to
+ accept of an unvalidated response; specifying a value of zero forces
+ the cache(s) to revalidate all responses. A client MAY also specify
+ the minimum time remaining before a response expires. Both of these
+ options increase constraints on the behavior of caches, and so cannot
+ further relax the cache's approximation of semantic transparency.
+
+ A client MAY also specify that it will accept stale responses, up to
+ some maximum amount of staleness. This loosens the constraints on the
+ caches, and so might violate the origin server's specified
+ constraints on semantic transparency, but might be necessary to
+ support disconnected operation, or high availability in the face of
+ poor connectivity.
+
+13.2 Expiration Model
+
+13.2.1 Server-Specified Expiration
+
+ HTTP caching works best when caches can entirely avoid making
+ requests to the origin server. The primary mechanism for avoiding
+ requests is for an origin server to provide an explicit expiration
+ time in the future, indicating that a response MAY be used to satisfy
+ subsequent requests. In other words, a cache can return a fresh
+ response without first contacting the server.
+
+ Our expectation is that servers will assign future explicit
+ expiration times to responses in the belief that the entity is not
+ likely to change, in a semantically significant way, before the
+ expiration time is reached. This normally preserves semantic
+ transparency, as long as the server's expiration times are carefully
+ chosen.
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 79]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ The expiration mechanism applies only to responses taken from a cache
+ and not to first-hand responses forwarded immediately to the
+ requesting client.
+
+ If an origin server wishes to force a semantically transparent cache
+ to validate every request, it MAY assign an explicit expiration time
+ in the past. This means that the response is always stale, and so the
+ cache SHOULD validate it before using it for subsequent requests. See
+ section 14.9.4 for a more restrictive way to force revalidation.
+
+ If an origin server wishes to force any HTTP/1.1 cache, no matter how
+ it is configured, to validate every request, it SHOULD use the "must-
+ revalidate" cache-control directive (see section 14.9).
+
+ Servers specify explicit expiration times using either the Expires
+ header, or the max-age directive of the Cache-Control header.
+
+ An expiration time cannot be used to force a user agent to refresh
+ its display or reload a resource; its semantics apply only to caching
+ mechanisms, and such mechanisms need only check a resource's
+ expiration status when a new request for that resource is initiated.
+ See section 13.13 for an explanation of the difference between caches
+ and history mechanisms.
+
+13.2.2 Heuristic Expiration
+
+ Since origin servers do not always provide explicit expiration times,
+ HTTP caches typically assign heuristic expiration times, employing
+ algorithms that use other header values (such as the Last-Modified
+ time) to estimate a plausible expiration time. The HTTP/1.1
+ specification does not provide specific algorithms, but does impose
+ worst-case constraints on their results. Since heuristic expiration
+ times might compromise semantic transparency, they ought to used
+ cautiously, and we encourage origin servers to provide explicit
+ expiration times as much as possible.
+
+13.2.3 Age Calculations
+
+ In order to know if a cached entry is fresh, a cache needs to know if
+ its age exceeds its freshness lifetime. We discuss how to calculate
+ the latter in section 13.2.4; this section describes how to calculate
+ the age of a response or cache entry.
+
+ In this discussion, we use the term "now" to mean "the current value
+ of the clock at the host performing the calculation." Hosts that use
+ HTTP, but especially hosts running origin servers and caches, SHOULD
+ use NTP [28] or some similar protocol to synchronize their clocks to
+ a globally accurate time standard.
+
+
+
+Fielding, et al. Standards Track [Page 80]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ HTTP/1.1 requires origin servers to send a Date header, if possible,
+ with every response, giving the time at which the response was
+ generated (see section 14.18). We use the term "date_value" to denote
+ the value of the Date header, in a form appropriate for arithmetic
+ operations.
+
+ HTTP/1.1 uses the Age response-header to convey the estimated age of
+ the response message when obtained from a cache. The Age field value
+ is the cache's estimate of the amount of time since the response was
+ generated or revalidated by the origin server.
+
+ In essence, the Age value is the sum of the time that the response
+ has been resident in each of the caches along the path from the
+ origin server, plus the amount of time it has been in transit along
+ network paths.
+
+ We use the term "age_value" to denote the value of the Age header, in
+ a form appropriate for arithmetic operations.
+
+ A response's age can be calculated in two entirely independent ways:
+
+ 1. now minus date_value, if the local clock is reasonably well
+ synchronized to the origin server's clock. If the result is
+ negative, the result is replaced by zero.
+
+ 2. age_value, if all of the caches along the response path
+ implement HTTP/1.1.
+
+ Given that we have two independent ways to compute the age of a
+ response when it is received, we can combine these as
+
+ corrected_received_age = max(now - date_value, age_value)
+
+ and as long as we have either nearly synchronized clocks or all-
+ HTTP/1.1 paths, one gets a reliable (conservative) result.
+
+ Because of network-imposed delays, some significant interval might
+ pass between the time that a server generates a response and the time
+ it is received at the next outbound cache or client. If uncorrected,
+ this delay could result in improperly low ages.
+
+ Because the request that resulted in the returned Age value must have
+ been initiated prior to that Age value's generation, we can correct
+ for delays imposed by the network by recording the time at which the
+ request was initiated. Then, when an Age value is received, it MUST
+ be interpreted relative to the time the request was initiated, not
+
+
+
+
+
+Fielding, et al. Standards Track [Page 81]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ the time that the response was received. This algorithm results in
+ conservative behavior no matter how much delay is experienced. So, we
+ compute:
+
+ corrected_initial_age = corrected_received_age
+ + (now - request_time)
+
+ where "request_time" is the time (according to the local clock) when
+ the request that elicited this response was sent.
+
+ Summary of age calculation algorithm, when a cache receives a
+ response:
+
+ /*
+ * age_value
+ * is the value of Age: header received by the cache with
+ * this response.
+ * date_value
+ * is the value of the origin server's Date: header
+ * request_time
+ * is the (local) time when the cache made the request
+ * that resulted in this cached response
+ * response_time
+ * is the (local) time when the cache received the
+ * response
+ * now
+ * is the current (local) time
+ */
+
+ apparent_age = max(0, response_time - date_value);
+ corrected_received_age = max(apparent_age, age_value);
+ response_delay = response_time - request_time;
+ corrected_initial_age = corrected_received_age + response_delay;
+ resident_time = now - response_time;
+ current_age = corrected_initial_age + resident_time;
+
+ The current_age of a cache entry is calculated by adding the amount
+ of time (in seconds) since the cache entry was last validated by the
+ origin server to the corrected_initial_age. When a response is
+ generated from a cache entry, the cache MUST include a single Age
+ header field in the response with a value equal to the cache entry's
+ current_age.
+
+ The presence of an Age header field in a response implies that a
+ response is not first-hand. However, the converse is not true, since
+ the lack of an Age header field in a response does not imply that the
+
+
+
+
+
+Fielding, et al. Standards Track [Page 82]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ response is first-hand unless all caches along the request path are
+ compliant with HTTP/1.1 (i.e., older HTTP caches did not implement
+ the Age header field).
+
+13.2.4 Expiration Calculations
+
+ In order to decide whether a response is fresh or stale, we need to
+ compare its freshness lifetime to its age. The age is calculated as
+ described in section 13.2.3; this section describes how to calculate
+ the freshness lifetime, and to determine if a response has expired.
+ In the discussion below, the values can be represented in any form
+ appropriate for arithmetic operations.
+
+ We use the term "expires_value" to denote the value of the Expires
+ header. We use the term "max_age_value" to denote an appropriate
+ value of the number of seconds carried by the "max-age" directive of
+ the Cache-Control header in a response (see section 14.9.3).
+
+ The max-age directive takes priority over Expires, so if max-age is
+ present in a response, the calculation is simply:
+
+ freshness_lifetime = max_age_value
+
+ Otherwise, if Expires is present in the response, the calculation is:
+
+ freshness_lifetime = expires_value - date_value
+
+ Note that neither of these calculations is vulnerable to clock skew,
+ since all of the information comes from the origin server.
+
+ If none of Expires, Cache-Control: max-age, or Cache-Control: s-
+ maxage (see section 14.9.3) appears in the response, and the response
+ does not include other restrictions on caching, the cache MAY compute
+ a freshness lifetime using a heuristic. The cache MUST attach Warning
+ 113 to any response whose age is more than 24 hours if such warning
+ has not already been added.
+
+ Also, if the response does have a Last-Modified time, the heuristic
+ expiration value SHOULD be no more than some fraction of the interval
+ since that time. A typical setting of this fraction might be 10%.
+
+ The calculation to determine if a response has expired is quite
+ simple:
+
+ response_is_fresh = (freshness_lifetime > current_age)
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 83]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+13.2.5 Disambiguating Expiration Values
+
+ Because expiration values are assigned optimistically, it is possible
+ for two caches to contain fresh values for the same resource that are
+ different.
+
+ If a client performing a retrieval receives a non-first-hand response
+ for a request that was already fresh in its own cache, and the Date
+ header in its existing cache entry is newer than the Date on the new
+ response, then the client MAY ignore the response. If so, it MAY
+ retry the request with a "Cache-Control: max-age=0" directive (see
+ section 14.9), to force a check with the origin server.
+
+ If a cache has two fresh responses for the same representation with
+ different validators, it MUST use the one with the more recent Date
+ header. This situation might arise because the cache is pooling
+ responses from other caches, or because a client has asked for a
+ reload or a revalidation of an apparently fresh cache entry.
+
+13.2.6 Disambiguating Multiple Responses
+
+ Because a client might be receiving responses via multiple paths, so
+ that some responses flow through one set of caches and other
+ responses flow through a different set of caches, a client might
+ receive responses in an order different from that in which the origin
+ server sent them. We would like the client to use the most recently
+ generated response, even if older responses are still apparently
+ fresh.
+
+ Neither the entity tag nor the expiration value can impose an
+ ordering on responses, since it is possible that a later response
+ intentionally carries an earlier expiration time. The Date values are
+ ordered to a granularity of one second.
+
+ When a client tries to revalidate a cache entry, and the response it
+ receives contains a Date header that appears to be older than the one
+ for the existing entry, then the client SHOULD repeat the request
+ unconditionally, and include
+
+ Cache-Control: max-age=0
+
+ to force any intermediate caches to validate their copies directly
+ with the origin server, or
+
+ Cache-Control: no-cache
+
+ to force any intermediate caches to obtain a new copy from the origin
+ server.
+
+
+
+Fielding, et al. Standards Track [Page 84]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ If the Date values are equal, then the client MAY use either response
+ (or MAY, if it is being extremely prudent, request a new response).
+ Servers MUST NOT depend on clients being able to choose
+ deterministically between responses generated during the same second,
+ if their expiration times overlap.
+
+13.3 Validation Model
+
+ When a cache has a stale entry that it would like to use as a
+ response to a client's request, it first has to check with the origin
+ server (or possibly an intermediate cache with a fresh response) to
+ see if its cached entry is still usable. We call this "validating"
+ the cache entry. Since we do not want to have to pay the overhead of
+ retransmitting the full response if the cached entry is good, and we
+ do not want to pay the overhead of an extra round trip if the cached
+ entry is invalid, the HTTP/1.1 protocol supports the use of
+ conditional methods.
+
+ The key protocol features for supporting conditional methods are
+ those concerned with "cache validators." When an origin server
+ generates a full response, it attaches some sort of validator to it,
+ which is kept with the cache entry. When a client (user agent or
+ proxy cache) makes a conditional request for a resource for which it
+ has a cache entry, it includes the associated validator in the
+ request.
+
+ The server then checks that validator against the current validator
+ for the entity, and, if they match (see section 13.3.3), it responds
+ with a special status code (usually, 304 (Not Modified)) and no
+ entity-body. Otherwise, it returns a full response (including
+ entity-body). Thus, we avoid transmitting the full response if the
+ validator matches, and we avoid an extra round trip if it does not
+ match.
+
+ In HTTP/1.1, a conditional request looks exactly the same as a normal
+ request for the same resource, except that it carries a special
+ header (which includes the validator) that implicitly turns the
+ method (usually, GET) into a conditional.
+
+ The protocol includes both positive and negative senses of cache-
+ validating conditions. That is, it is possible to request either that
+ a method be performed if and only if a validator matches or if and
+ only if no validators match.
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 85]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Note: a response that lacks a validator may still be cached, and
+ served from cache until it expires, unless this is explicitly
+ prohibited by a cache-control directive. However, a cache cannot
+ do a conditional retrieval if it does not have a validator for the
+ entity, which means it will not be refreshable after it expires.
+
+13.3.1 Last-Modified Dates
+
+ The Last-Modified entity-header field value is often used as a cache
+ validator. In simple terms, a cache entry is considered to be valid
+ if the entity has not been modified since the Last-Modified value.
+
+13.3.2 Entity Tag Cache Validators
+
+ The ETag response-header field value, an entity tag, provides for an
+ "opaque" cache validator. This might allow more reliable validation
+ in situations where it is inconvenient to store modification dates,
+ where the one-second resolution of HTTP date values is not
+ sufficient, or where the origin server wishes to avoid certain
+ paradoxes that might arise from the use of modification dates.
+
+ Entity Tags are described in section 3.11. The headers used with
+ entity tags are described in sections 14.19, 14.24, 14.26 and 14.44.
+
+13.3.3 Weak and Strong Validators
+
+ Since both origin servers and caches will compare two validators to
+ decide if they represent the same or different entities, one normally
+ would expect that if the entity (the entity-body or any entity-
+ headers) changes in any way, then the associated validator would
+ change as well. If this is true, then we call this validator a
+ "strong validator."
+
+ However, there might be cases when a server prefers to change the
+ validator only on semantically significant changes, and not when
+ insignificant aspects of the entity change. A validator that does not
+ always change when the resource changes is a "weak validator."
+
+ Entity tags are normally "strong validators," but the protocol
+ provides a mechanism to tag an entity tag as "weak." One can think of
+ a strong validator as one that changes whenever the bits of an entity
+ changes, while a weak value changes whenever the meaning of an entity
+ changes. Alternatively, one can think of a strong validator as part
+ of an identifier for a specific entity, while a weak validator is
+ part of an identifier for a set of semantically equivalent entities.
+
+ Note: One example of a strong validator is an integer that is
+ incremented in stable storage every time an entity is changed.
+
+
+
+Fielding, et al. Standards Track [Page 86]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ An entity's modification time, if represented with one-second
+ resolution, could be a weak validator, since it is possible that
+ the resource might be modified twice during a single second.
+
+ Support for weak validators is optional. However, weak validators
+ allow for more efficient caching of equivalent objects; for
+ example, a hit counter on a site is probably good enough if it is
+ updated every few days or weeks, and any value during that period
+ is likely "good enough" to be equivalent.
+
+ A "use" of a validator is either when a client generates a request
+ and includes the validator in a validating header field, or when a
+ server compares two validators.
+
+ Strong validators are usable in any context. Weak validators are only
+ usable in contexts that do not depend on exact equality of an entity.
+ For example, either kind is usable for a conditional GET of a full
+ entity. However, only a strong validator is usable for a sub-range
+ retrieval, since otherwise the client might end up with an internally
+ inconsistent entity.
+
+ Clients MAY issue simple (non-subrange) GET requests with either weak
+ validators or strong validators. Clients MUST NOT use weak validators
+ in other forms of request.
+
+ The only function that the HTTP/1.1 protocol defines on validators is
+ comparison. There are two validator comparison functions, depending
+ on whether the comparison context allows the use of weak validators
+ or not:
+
+ - The strong comparison function: in order to be considered equal,
+ both validators MUST be identical in every way, and both MUST
+ NOT be weak.
+
+ - The weak comparison function: in order to be considered equal,
+ both validators MUST be identical in every way, but either or
+ both of them MAY be tagged as "weak" without affecting the
+ result.
+
+ An entity tag is strong unless it is explicitly tagged as weak.
+ Section 3.11 gives the syntax for entity tags.
+
+ A Last-Modified time, when used as a validator in a request, is
+ implicitly weak unless it is possible to deduce that it is strong,
+ using the following rules:
+
+ - The validator is being compared by an origin server to the
+ actual current validator for the entity and,
+
+
+
+Fielding, et al. Standards Track [Page 87]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ - That origin server reliably knows that the associated entity did
+ not change twice during the second covered by the presented
+ validator.
+
+ or
+
+ - The validator is about to be used by a client in an If-
+ Modified-Since or If-Unmodified-Since header, because the client
+ has a cache entry for the associated entity, and
+
+ - That cache entry includes a Date value, which gives the time
+ when the origin server sent the original response, and
+
+ - The presented Last-Modified time is at least 60 seconds before
+ the Date value.
+
+ or
+
+ - The validator is being compared by an intermediate cache to the
+ validator stored in its cache entry for the entity, and
+
+ - That cache entry includes a Date value, which gives the time
+ when the origin server sent the original response, and
+
+ - The presented Last-Modified time is at least 60 seconds before
+ the Date value.
+
+ This method relies on the fact that if two different responses were
+ sent by the origin server during the same second, but both had the
+ same Last-Modified time, then at least one of those responses would
+ have a Date value equal to its Last-Modified time. The arbitrary 60-
+ second limit guards against the possibility that the Date and Last-
+ Modified values are generated from different clocks, or at somewhat
+ different times during the preparation of the response. An
+ implementation MAY use a value larger than 60 seconds, if it is
+ believed that 60 seconds is too short.
+
+ If a client wishes to perform a sub-range retrieval on a value for
+ which it has only a Last-Modified time and no opaque validator, it
+ MAY do this only if the Last-Modified time is strong in the sense
+ described here.
+
+ A cache or origin server receiving a conditional request, other than
+ a full-body GET request, MUST use the strong comparison function to
+ evaluate the condition.
+
+ These rules allow HTTP/1.1 caches and clients to safely perform sub-
+ range retrievals on values that have been obtained from HTTP/1.0
+
+
+
+Fielding, et al. Standards Track [Page 88]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ servers.
+
+13.3.4 Rules for When to Use Entity Tags and Last-Modified Dates
+
+ We adopt a set of rules and recommendations for origin servers,
+ clients, and caches regarding when various validator types ought to
+ be used, and for what purposes.
+
+ HTTP/1.1 origin servers:
+
+ - SHOULD send an entity tag validator unless it is not feasible to
+ generate one.
+
+ - MAY send a weak entity tag instead of a strong entity tag, if
+ performance considerations support the use of weak entity tags,
+ or if it is unfeasible to send a strong entity tag.
+
+ - SHOULD send a Last-Modified value if it is feasible to send one,
+ unless the risk of a breakdown in semantic transparency that
+ could result from using this date in an If-Modified-Since header
+ would lead to serious problems.
+
+ In other words, the preferred behavior for an HTTP/1.1 origin server
+ is to send both a strong entity tag and a Last-Modified value.
+
+ In order to be legal, a strong entity tag MUST change whenever the
+ associated entity value changes in any way. A weak entity tag SHOULD
+ change whenever the associated entity changes in a semantically
+ significant way.
+
+ Note: in order to provide semantically transparent caching, an
+ origin server must avoid reusing a specific strong entity tag
+ value for two different entities, or reusing a specific weak
+ entity tag value for two semantically different entities. Cache
+ entries might persist for arbitrarily long periods, regardless of
+ expiration times, so it might be inappropriate to expect that a
+ cache will never again attempt to validate an entry using a
+ validator that it obtained at some point in the past.
+
+ HTTP/1.1 clients:
+
+ - If an entity tag has been provided by the origin server, MUST
+ use that entity tag in any cache-conditional request (using If-
+ Match or If-None-Match).
+
+ - If only a Last-Modified value has been provided by the origin
+ server, SHOULD use that value in non-subrange cache-conditional
+ requests (using If-Modified-Since).
+
+
+
+Fielding, et al. Standards Track [Page 89]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ - If only a Last-Modified value has been provided by an HTTP/1.0
+ origin server, MAY use that value in subrange cache-conditional
+ requests (using If-Unmodified-Since:). The user agent SHOULD
+ provide a way to disable this, in case of difficulty.
+
+ - If both an entity tag and a Last-Modified value have been
+ provided by the origin server, SHOULD use both validators in
+ cache-conditional requests. This allows both HTTP/1.0 and
+ HTTP/1.1 caches to respond appropriately.
+
+ An HTTP/1.1 origin server, upon receiving a conditional request that
+ includes both a Last-Modified date (e.g., in an If-Modified-Since or
+ If-Unmodified-Since header field) and one or more entity tags (e.g.,
+ in an If-Match, If-None-Match, or If-Range header field) as cache
+ validators, MUST NOT return a response status of 304 (Not Modified)
+ unless doing so is consistent with all of the conditional header
+ fields in the request.
+
+ An HTTP/1.1 caching proxy, upon receiving a conditional request that
+ includes both a Last-Modified date and one or more entity tags as
+ cache validators, MUST NOT return a locally cached response to the
+ client unless that cached response is consistent with all of the
+ conditional header fields in the request.
+
+ Note: The general principle behind these rules is that HTTP/1.1
+ servers and clients should transmit as much non-redundant
+ information as is available in their responses and requests.
+ HTTP/1.1 systems receiving this information will make the most
+ conservative assumptions about the validators they receive.
+
+ HTTP/1.0 clients and caches will ignore entity tags. Generally,
+ last-modified values received or used by these systems will
+ support transparent and efficient caching, and so HTTP/1.1 origin
+ servers should provide Last-Modified values. In those rare cases
+ where the use of a Last-Modified value as a validator by an
+ HTTP/1.0 system could result in a serious problem, then HTTP/1.1
+ origin servers should not provide one.
+
+13.3.5 Non-validating Conditionals
+
+ The principle behind entity tags is that only the service author
+ knows the semantics of a resource well enough to select an
+ appropriate cache validation mechanism, and the specification of any
+ validator comparison function more complex than byte-equality would
+ open up a can of worms. Thus, comparisons of any other headers
+ (except Last-Modified, for compatibility with HTTP/1.0) are never
+ used for purposes of validating a cache entry.
+
+
+
+
+Fielding, et al. Standards Track [Page 90]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+13.4 Response Cacheability
+
+ Unless specifically constrained by a cache-control (section 14.9)
+ directive, a caching system MAY always store a successful response
+ (see section 13.8) as a cache entry, MAY return it without validation
+ if it is fresh, and MAY return it after successful validation. If
+ there is neither a cache validator nor an explicit expiration time
+ associated with a response, we do not expect it to be cached, but
+ certain caches MAY violate this expectation (for example, when little
+ or no network connectivity is available). A client can usually detect
+ that such a response was taken from a cache by comparing the Date
+ header to the current time.
+
+ Note: some HTTP/1.0 caches are known to violate this expectation
+ without providing any Warning.
+
+ However, in some cases it might be inappropriate for a cache to
+ retain an entity, or to return it in response to a subsequent
+ request. This might be because absolute semantic transparency is
+ deemed necessary by the service author, or because of security or
+ privacy considerations. Certain cache-control directives are
+ therefore provided so that the server can indicate that certain
+ resource entities, or portions thereof, are not to be cached
+ regardless of other considerations.
+
+ Note that section 14.8 normally prevents a shared cache from saving
+ and returning a response to a previous request if that request
+ included an Authorization header.
+
+ A response received with a status code of 200, 203, 206, 300, 301 or
+ 410 MAY be stored by a cache and used in reply to a subsequent
+ request, subject to the expiration mechanism, unless a cache-control
+ directive prohibits caching. However, a cache that does not support
+ the Range and Content-Range headers MUST NOT cache 206 (Partial
+ Content) responses.
+
+ A response received with any other status code (e.g. status codes 302
+ and 307) MUST NOT be returned in a reply to a subsequent request
+ unless there are cache-control directives or another header(s) that
+ explicitly allow it. For example, these include the following: an
+ Expires header (section 14.21); a "max-age", "s-maxage", "must-
+ revalidate", "proxy-revalidate", "public" or "private" cache-control
+ directive (section 14.9).
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 91]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+13.5 Constructing Responses From Caches
+
+ The purpose of an HTTP cache is to store information received in
+ response to requests for use in responding to future requests. In
+ many cases, a cache simply returns the appropriate parts of a
+ response to the requester. However, if the cache holds a cache entry
+ based on a previous response, it might have to combine parts of a new
+ response with what is held in the cache entry.
+
+13.5.1 End-to-end and Hop-by-hop Headers
+
+ For the purpose of defining the behavior of caches and non-caching
+ proxies, we divide HTTP headers into two categories:
+
+ - End-to-end headers, which are transmitted to the ultimate
+ recipient of a request or response. End-to-end headers in
+ responses MUST be stored as part of a cache entry and MUST be
+ transmitted in any response formed from a cache entry.
+
+ - Hop-by-hop headers, which are meaningful only for a single
+ transport-level connection, and are not stored by caches or
+ forwarded by proxies.
+
+ The following HTTP/1.1 headers are hop-by-hop headers:
+
+ - Connection
+ - Keep-Alive
+ - Proxy-Authenticate
+ - Proxy-Authorization
+ - TE
+ - Trailers
+ - Transfer-Encoding
+ - Upgrade
+
+ All other headers defined by HTTP/1.1 are end-to-end headers.
+
+ Other hop-by-hop headers MUST be listed in a Connection header,
+ (section 14.10) to be introduced into HTTP/1.1 (or later).
+
+13.5.2 Non-modifiable Headers
+
+ Some features of the HTTP/1.1 protocol, such as Digest
+ Authentication, depend on the value of certain end-to-end headers. A
+ transparent proxy SHOULD NOT modify an end-to-end header unless the
+ definition of that header requires or specifically allows that.
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 92]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ A transparent proxy MUST NOT modify any of the following fields in a
+ request or response, and it MUST NOT add any of these fields if not
+ already present:
+
+ - Content-Location
+
+ - Content-MD5
+
+ - ETag
+
+ - Last-Modified
+
+ A transparent proxy MUST NOT modify any of the following fields in a
+ response:
+
+ - Expires
+
+ but it MAY add any of these fields if not already present. If an
+ Expires header is added, it MUST be given a field-value identical to
+ that of the Date header in that response.
+
+ A proxy MUST NOT modify or add any of the following fields in a
+ message that contains the no-transform cache-control directive, or in
+ any request:
+
+ - Content-Encoding
+
+ - Content-Range
+
+ - Content-Type
+
+ A non-transparent proxy MAY modify or add these fields to a message
+ that does not include no-transform, but if it does so, it MUST add a
+ Warning 214 (Transformation applied) if one does not already appear
+ in the message (see section 14.46).
+
+ Warning: unnecessary modification of end-to-end headers might
+ cause authentication failures if stronger authentication
+ mechanisms are introduced in later versions of HTTP. Such
+ authentication mechanisms MAY rely on the values of header fields
+ not listed here.
+
+ The Content-Length field of a request or response is added or deleted
+ according to the rules in section 4.4. A transparent proxy MUST
+ preserve the entity-length (section 7.2.2) of the entity-body,
+ although it MAY change the transfer-length (section 4.4).
+
+
+
+
+
+Fielding, et al. Standards Track [Page 93]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+13.5.3 Combining Headers
+
+ When a cache makes a validating request to a server, and the server
+ provides a 304 (Not Modified) response or a 206 (Partial Content)
+ response, the cache then constructs a response to send to the
+ requesting client.
+
+ If the status code is 304 (Not Modified), the cache uses the entity-
+ body stored in the cache entry as the entity-body of this outgoing
+ response. If the status code is 206 (Partial Content) and the ETag or
+ Last-Modified headers match exactly, the cache MAY combine the
+ contents stored in the cache entry with the new contents received in
+ the response and use the result as the entity-body of this outgoing
+ response, (see 13.5.4).
+
+ The end-to-end headers stored in the cache entry are used for the
+ constructed response, except that
+
+ - any stored Warning headers with warn-code 1xx (see section
+ 14.46) MUST be deleted from the cache entry and the forwarded
+ response.
+
+ - any stored Warning headers with warn-code 2xx MUST be retained
+ in the cache entry and the forwarded response.
+
+ - any end-to-end headers provided in the 304 or 206 response MUST
+ replace the corresponding headers from the cache entry.
+
+ Unless the cache decides to remove the cache entry, it MUST also
+ replace the end-to-end headers stored with the cache entry with
+ corresponding headers received in the incoming response, except for
+ Warning headers as described immediately above. If a header field-
+ name in the incoming response matches more than one header in the
+ cache entry, all such old headers MUST be replaced.
+
+ In other words, the set of end-to-end headers received in the
+ incoming response overrides all corresponding end-to-end headers
+ stored with the cache entry (except for stored Warning headers with
+ warn-code 1xx, which are deleted even if not overridden).
+
+ Note: this rule allows an origin server to use a 304 (Not
+ Modified) or a 206 (Partial Content) response to update any header
+ associated with a previous response for the same entity or sub-
+ ranges thereof, although it might not always be meaningful or
+ correct to do so. This rule does not allow an origin server to use
+ a 304 (Not Modified) or a 206 (Partial Content) response to
+ entirely delete a header that it had provided with a previous
+ response.
+
+
+
+Fielding, et al. Standards Track [Page 94]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+13.5.4 Combining Byte Ranges
+
+ A response might transfer only a subrange of the bytes of an entity-
+ body, either because the request included one or more Range
+ specifications, or because a connection was broken prematurely. After
+ several such transfers, a cache might have received several ranges of
+ the same entity-body.
+
+ If a cache has a stored non-empty set of subranges for an entity, and
+ an incoming response transfers another subrange, the cache MAY
+ combine the new subrange with the existing set if both the following
+ conditions are met:
+
+ - Both the incoming response and the cache entry have a cache
+ validator.
+
+ - The two cache validators match using the strong comparison
+ function (see section 13.3.3).
+
+ If either requirement is not met, the cache MUST use only the most
+ recent partial response (based on the Date values transmitted with
+ every response, and using the incoming response if these values are
+ equal or missing), and MUST discard the other partial information.
+
+13.6 Caching Negotiated Responses
+
+ Use of server-driven content negotiation (section 12.1), as indicated
+ by the presence of a Vary header field in a response, alters the
+ conditions and procedure by which a cache can use the response for
+ subsequent requests. See section 14.44 for use of the Vary header
+ field by servers.
+
+ A server SHOULD use the Vary header field to inform a cache of what
+ request-header fields were used to select among multiple
+ representations of a cacheable response subject to server-driven
+ negotiation. The set of header fields named by the Vary field value
+ is known as the "selecting" request-headers.
+
+ When the cache receives a subsequent request whose Request-URI
+ specifies one or more cache entries including a Vary header field,
+ the cache MUST NOT use such a cache entry to construct a response to
+ the new request unless all of the selecting request-headers present
+ in the new request match the corresponding stored request-headers in
+ the original request.
+
+ The selecting request-headers from two requests are defined to match
+ if and only if the selecting request-headers in the first request can
+ be transformed to the selecting request-headers in the second request
+
+
+
+Fielding, et al. Standards Track [Page 95]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ by adding or removing linear white space (LWS) at places where this
+ is allowed by the corresponding BNF, and/or combining multiple
+ message-header fields with the same field name following the rules
+ about message headers in section 4.2.
+
+ A Vary header field-value of "*" always fails to match and subsequent
+ requests on that resource can only be properly interpreted by the
+ origin server.
+
+ If the selecting request header fields for the cached entry do not
+ match the selecting request header fields of the new request, then
+ the cache MUST NOT use a cached entry to satisfy the request unless
+ it first relays the new request to the origin server in a conditional
+ request and the server responds with 304 (Not Modified), including an
+ entity tag or Content-Location that indicates the entity to be used.
+
+ If an entity tag was assigned to a cached representation, the
+ forwarded request SHOULD be conditional and include the entity tags
+ in an If-None-Match header field from all its cache entries for the
+ resource. This conveys to the server the set of entities currently
+ held by the cache, so that if any one of these entities matches the
+ requested entity, the server can use the ETag header field in its 304
+ (Not Modified) response to tell the cache which entry is appropriate.
+ If the entity-tag of the new response matches that of an existing
+ entry, the new response SHOULD be used to update the header fields of
+ the existing entry, and the result MUST be returned to the client.
+
+ If any of the existing cache entries contains only partial content
+ for the associated entity, its entity-tag SHOULD NOT be included in
+ the If-None-Match header field unless the request is for a range that
+ would be fully satisfied by that entry.
+
+ If a cache receives a successful response whose Content-Location
+ field matches that of an existing cache entry for the same Request-
+ ]URI, whose entity-tag differs from that of the existing entry, and
+ whose Date is more recent than that of the existing entry, the
+ existing entry SHOULD NOT be returned in response to future requests
+ and SHOULD be deleted from the cache.
+
+13.7 Shared and Non-Shared Caches
+
+ For reasons of security and privacy, it is necessary to make a
+ distinction between "shared" and "non-shared" caches. A non-shared
+ cache is one that is accessible only to a single user. Accessibility
+ in this case SHOULD be enforced by appropriate security mechanisms.
+ All other caches are considered to be "shared." Other sections of
+
+
+
+
+
+Fielding, et al. Standards Track [Page 96]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ this specification place certain constraints on the operation of
+ shared caches in order to prevent loss of privacy or failure of
+ access controls.
+
+13.8 Errors or Incomplete Response Cache Behavior
+
+ A cache that receives an incomplete response (for example, with fewer
+ bytes of data than specified in a Content-Length header) MAY store
+ the response. However, the cache MUST treat this as a partial
+ response. Partial responses MAY be combined as described in section
+ 13.5.4; the result might be a full response or might still be
+ partial. A cache MUST NOT return a partial response to a client
+ without explicitly marking it as such, using the 206 (Partial
+ Content) status code. A cache MUST NOT return a partial response
+ using a status code of 200 (OK).
+
+ If a cache receives a 5xx response while attempting to revalidate an
+ entry, it MAY either forward this response to the requesting client,
+ or act as if the server failed to respond. In the latter case, it MAY
+ return a previously received response unless the cached entry
+ includes the "must-revalidate" cache-control directive (see section
+ 14.9).
+
+13.9 Side Effects of GET and HEAD
+
+ Unless the origin server explicitly prohibits the caching of their
+ responses, the application of GET and HEAD methods to any resources
+ SHOULD NOT have side effects that would lead to erroneous behavior if
+ these responses are taken from a cache. They MAY still have side
+ effects, but a cache is not required to consider such side effects in
+ its caching decisions. Caches are always expected to observe an
+ origin server's explicit restrictions on caching.
+
+ We note one exception to this rule: since some applications have
+ traditionally used GETs and HEADs with query URLs (those containing a
+ "?" in the rel_path part) to perform operations with significant side
+ effects, caches MUST NOT treat responses to such URIs as fresh unless
+ the server provides an explicit expiration time. This specifically
+ means that responses from HTTP/1.0 servers for such URIs SHOULD NOT
+ be taken from a cache. See section 9.1.1 for related information.
+
+13.10 Invalidation After Updates or Deletions
+
+ The effect of certain methods performed on a resource at the origin
+ server might cause one or more existing cache entries to become non-
+ transparently invalid. That is, although they might continue to be
+ "fresh," they do not accurately reflect what the origin server would
+ return for a new request on that resource.
+
+
+
+Fielding, et al. Standards Track [Page 97]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ There is no way for the HTTP protocol to guarantee that all such
+ cache entries are marked invalid. For example, the request that
+ caused the change at the origin server might not have gone through
+ the proxy where a cache entry is stored. However, several rules help
+ reduce the likelihood of erroneous behavior.
+
+ In this section, the phrase "invalidate an entity" means that the
+ cache will either remove all instances of that entity from its
+ storage, or will mark these as "invalid" and in need of a mandatory
+ revalidation before they can be returned in response to a subsequent
+ request.
+
+ Some HTTP methods MUST cause a cache to invalidate an entity. This is
+ either the entity referred to by the Request-URI, or by the Location
+ or Content-Location headers (if present). These methods are:
+
+ - PUT
+
+ - DELETE
+
+ - POST
+
+ In order to prevent denial of service attacks, an invalidation based
+ on the URI in a Location or Content-Location header MUST only be
+ performed if the host part is the same as in the Request-URI.
+
+ A cache that passes through requests for methods it does not
+ understand SHOULD invalidate any entities referred to by the
+ Request-URI.
+
+13.11 Write-Through Mandatory
+
+ All methods that might be expected to cause modifications to the
+ origin server's resources MUST be written through to the origin
+ server. This currently includes all methods except for GET and HEAD.
+ A cache MUST NOT reply to such a request from a client before having
+ transmitted the request to the inbound server, and having received a
+ corresponding response from the inbound server. This does not prevent
+ a proxy cache from sending a 100 (Continue) response before the
+ inbound server has sent its final reply.
+
+ The alternative (known as "write-back" or "copy-back" caching) is not
+ allowed in HTTP/1.1, due to the difficulty of providing consistent
+ updates and the problems arising from server, cache, or network
+ failure prior to write-back.
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 98]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+13.12 Cache Replacement
+
+ If a new cacheable (see sections 14.9.2, 13.2.5, 13.2.6 and 13.8)
+ response is received from a resource while any existing responses for
+ the same resource are cached, the cache SHOULD use the new response
+ to reply to the current request. It MAY insert it into cache storage
+ and MAY, if it meets all other requirements, use it to respond to any
+ future requests that would previously have caused the old response to
+ be returned. If it inserts the new response into cache storage the
+ rules in section 13.5.3 apply.
+
+ Note: a new response that has an older Date header value than
+ existing cached responses is not cacheable.
+
+13.13 History Lists
+
+ User agents often have history mechanisms, such as "Back" buttons and
+ history lists, which can be used to redisplay an entity retrieved
+ earlier in a session.
+
+ History mechanisms and caches are different. In particular history
+ mechanisms SHOULD NOT try to show a semantically transparent view of
+ the current state of a resource. Rather, a history mechanism is meant
+ to show exactly what the user saw at the time when the resource was
+ retrieved.
+
+ By default, an expiration time does not apply to history mechanisms.
+ If the entity is still in storage, a history mechanism SHOULD display
+ it even if the entity has expired, unless the user has specifically
+ configured the agent to refresh expired history documents.
+
+ This is not to be construed to prohibit the history mechanism from
+ telling the user that a view might be stale.
+
+ Note: if history list mechanisms unnecessarily prevent users from
+ viewing stale resources, this will tend to force service authors
+ to avoid using HTTP expiration controls and cache controls when
+ they would otherwise like to. Service authors may consider it
+ important that users not be presented with error messages or
+ warning messages when they use navigation controls (such as BACK)
+ to view previously fetched resources. Even though sometimes such
+ resources ought not to cached, or ought to expire quickly, user
+ interface considerations may force service authors to resort to
+ other means of preventing caching (e.g. "once-only" URLs) in order
+ not to suffer the effects of improperly functioning history
+ mechanisms.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 99]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+14 Header Field Definitions
+
+ This section defines the syntax and semantics of all standard
+ HTTP/1.1 header fields. For entity-header fields, both sender and
+ recipient refer to either the client or the server, depending on who
+ sends and who receives the entity.
+
+14.1 Accept
+
+ The Accept request-header field can be used to specify certain media
+ types which are acceptable for the response. Accept headers can be
+ used to indicate that the request is specifically limited to a small
+ set of desired types, as in the case of a request for an in-line
+ image.
+
+ Accept = "Accept" ":"
+ #( media-range [ accept-params ] )
+
+ media-range = ( "*/*"
+ | ( type "/" "*" )
+ | ( type "/" subtype )
+ ) *( ";" parameter )
+ accept-params = ";" "q" "=" qvalue *( accept-extension )
+ accept-extension = ";" token [ "=" ( token | quoted-string ) ]
+
+ The asterisk "*" character is used to group media types into ranges,
+ with "*/*" indicating all media types and "type/*" indicating all
+ subtypes of that type. The media-range MAY include media type
+ parameters that are applicable to that range.
+
+ Each media-range MAY be followed by one or more accept-params,
+ beginning with the "q" parameter for indicating a relative quality
+ factor. The first "q" parameter (if any) separates the media-range
+ parameter(s) from the accept-params. Quality factors allow the user
+ or user agent to indicate the relative degree of preference for that
+ media-range, using the qvalue scale from 0 to 1 (section 3.9). The
+ default value is q=1.
+
+ Note: Use of the "q" parameter name to separate media type
+ parameters from Accept extension parameters is due to historical
+ practice. Although this prevents any media type parameter named
+ "q" from being used with a media range, such an event is believed
+ to be unlikely given the lack of any "q" parameters in the IANA
+ media type registry and the rare usage of any media type
+ parameters in Accept. Future media types are discouraged from
+ registering any parameter named "q".
+
+
+
+
+
+Fielding, et al. Standards Track [Page 100]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ The example
+
+ Accept: audio/*; q=0.2, audio/basic
+
+ SHOULD be interpreted as "I prefer audio/basic, but send me any audio
+ type if it is the best available after an 80% mark-down in quality."
+
+ If no Accept header field is present, then it is assumed that the
+ client accepts all media types. If an Accept header field is present,
+ and if the server cannot send a response which is acceptable
+ according to the combined Accept field value, then the server SHOULD
+ send a 406 (not acceptable) response.
+
+ A more elaborate example is
+
+ Accept: text/plain; q=0.5, text/html,
+ text/x-dvi; q=0.8, text/x-c
+
+ Verbally, this would be interpreted as "text/html and text/x-c are
+ the preferred media types, but if they do not exist, then send the
+ text/x-dvi entity, and if that does not exist, send the text/plain
+ entity."
+
+ Media ranges can be overridden by more specific media ranges or
+ specific media types. If more than one media range applies to a given
+ type, the most specific reference has precedence. For example,
+
+ Accept: text/*, text/html, text/html;level=1, */*
+
+ have the following precedence:
+
+ 1) text/html;level=1
+ 2) text/html
+ 3) text/*
+ 4) */*
+
+ The media type quality factor associated with a given type is
+ determined by finding the media range with the highest precedence
+ which matches that type. For example,
+
+ Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
+ text/html;level=2;q=0.4, */*;q=0.5
+
+ would cause the following values to be associated:
+
+ text/html;level=1 = 1
+ text/html = 0.7
+ text/plain = 0.3
+
+
+
+Fielding, et al. Standards Track [Page 101]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ image/jpeg = 0.5
+ text/html;level=2 = 0.4
+ text/html;level=3 = 0.7
+
+ Note: A user agent might be provided with a default set of quality
+ values for certain media ranges. However, unless the user agent is
+ a closed system which cannot interact with other rendering agents,
+ this default set ought to be configurable by the user.
+
+14.2 Accept-Charset
+
+ The Accept-Charset request-header field can be used to indicate what
+ character sets are acceptable for the response. This field allows
+ clients capable of understanding more comprehensive or special-
+ purpose character sets to signal that capability to a server which is
+ capable of representing documents in those character sets.
+
+ Accept-Charset = "Accept-Charset" ":"
+ 1#( ( charset | "*" )[ ";" "q" "=" qvalue ] )
+
+
+ Character set values are described in section 3.4. Each charset MAY
+ be given an associated quality value which represents the user's
+ preference for that charset. The default value is q=1. An example is
+
+ Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
+
+ The special value "*", if present in the Accept-Charset field,
+ matches every character set (including ISO-8859-1) which is not
+ mentioned elsewhere in the Accept-Charset field. If no "*" is present
+ in an Accept-Charset field, then all character sets not explicitly
+ mentioned get a quality value of 0, except for ISO-8859-1, which gets
+ a quality value of 1 if not explicitly mentioned.
+
+ If no Accept-Charset header is present, the default is that any
+ character set is acceptable. If an Accept-Charset header is present,
+ and if the server cannot send a response which is acceptable
+ according to the Accept-Charset header, then the server SHOULD send
+ an error response with the 406 (not acceptable) status code, though
+ the sending of an unacceptable response is also allowed.
+
+14.3 Accept-Encoding
+
+ The Accept-Encoding request-header field is similar to Accept, but
+ restricts the content-codings (section 3.5) that are acceptable in
+ the response.
+
+ Accept-Encoding = "Accept-Encoding" ":"
+
+
+
+Fielding, et al. Standards Track [Page 102]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 1#( codings [ ";" "q" "=" qvalue ] )
+ codings = ( content-coding | "*" )
+
+ Examples of its use are:
+
+ Accept-Encoding: compress, gzip
+ Accept-Encoding:
+ Accept-Encoding: *
+ Accept-Encoding: compress;q=0.5, gzip;q=1.0
+ Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0
+
+ A server tests whether a content-coding is acceptable, according to
+ an Accept-Encoding field, using these rules:
+
+ 1. If the content-coding is one of the content-codings listed in
+ the Accept-Encoding field, then it is acceptable, unless it is
+ accompanied by a qvalue of 0. (As defined in section 3.9, a
+ qvalue of 0 means "not acceptable.")
+
+ 2. The special "*" symbol in an Accept-Encoding field matches any
+ available content-coding not explicitly listed in the header
+ field.
+
+ 3. If multiple content-codings are acceptable, then the acceptable
+ content-coding with the highest non-zero qvalue is preferred.
+
+ 4. The "identity" content-coding is always acceptable, unless
+ specifically refused because the Accept-Encoding field includes
+ "identity;q=0", or because the field includes "*;q=0" and does
+ not explicitly include the "identity" content-coding. If the
+ Accept-Encoding field-value is empty, then only the "identity"
+ encoding is acceptable.
+
+ If an Accept-Encoding field is present in a request, and if the
+ server cannot send a response which is acceptable according to the
+ Accept-Encoding header, then the server SHOULD send an error response
+ with the 406 (Not Acceptable) status code.
+
+ If no Accept-Encoding field is present in a request, the server MAY
+ assume that the client will accept any content coding. In this case,
+ if "identity" is one of the available content-codings, then the
+ server SHOULD use the "identity" content-coding, unless it has
+ additional information that a different content-coding is meaningful
+ to the client.
+
+ Note: If the request does not include an Accept-Encoding field,
+ and if the "identity" content-coding is unavailable, then
+ content-codings commonly understood by HTTP/1.0 clients (i.e.,
+
+
+
+Fielding, et al. Standards Track [Page 103]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ "gzip" and "compress") are preferred; some older clients
+ improperly display messages sent with other content-codings. The
+ server might also make this decision based on information about
+ the particular user-agent or client.
+
+ Note: Most HTTP/1.0 applications do not recognize or obey qvalues
+ associated with content-codings. This means that qvalues will not
+ work and are not permitted with x-gzip or x-compress.
+
+14.4 Accept-Language
+
+ The Accept-Language request-header field is similar to Accept, but
+ restricts the set of natural languages that are preferred as a
+ response to the request. Language tags are defined in section 3.10.
+
+ Accept-Language = "Accept-Language" ":"
+ 1#( language-range [ ";" "q" "=" qvalue ] )
+ language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
+
+ Each language-range MAY be given an associated quality value which
+ represents an estimate of the user's preference for the languages
+ specified by that range. The quality value defaults to "q=1". For
+ example,
+
+ Accept-Language: da, en-gb;q=0.8, en;q=0.7
+
+ would mean: "I prefer Danish, but will accept British English and
+ other types of English." A language-range matches a language-tag if
+ it exactly equals the tag, or if it exactly equals a prefix of the
+ tag such that the first tag character following the prefix is "-".
+ The special range "*", if present in the Accept-Language field,
+ matches every tag not matched by any other range present in the
+ Accept-Language field.
+
+ Note: This use of a prefix matching rule does not imply that
+ language tags are assigned to languages in such a way that it is
+ always true that if a user understands a language with a certain
+ tag, then this user will also understand all languages with tags
+ for which this tag is a prefix. The prefix rule simply allows the
+ use of prefix tags if this is the case.
+
+ The language quality factor assigned to a language-tag by the
+ Accept-Language field is the quality value of the longest language-
+ range in the field that matches the language-tag. If no language-
+ range in the field matches the tag, the language quality factor
+ assigned is 0. If no Accept-Language header is present in the
+ request, the server
+
+
+
+
+Fielding, et al. Standards Track [Page 104]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ SHOULD assume that all languages are equally acceptable. If an
+ Accept-Language header is present, then all languages which are
+ assigned a quality factor greater than 0 are acceptable.
+
+ It might be contrary to the privacy expectations of the user to send
+ an Accept-Language header with the complete linguistic preferences of
+ the user in every request. For a discussion of this issue, see
+ section 15.1.4.
+
+ As intelligibility is highly dependent on the individual user, it is
+ recommended that client applications make the choice of linguistic
+ preference available to the user. If the choice is not made
+ available, then the Accept-Language header field MUST NOT be given in
+ the request.
+
+ Note: When making the choice of linguistic preference available to
+ the user, we remind implementors of the fact that users are not
+ familiar with the details of language matching as described above,
+ and should provide appropriate guidance. As an example, users
+ might assume that on selecting "en-gb", they will be served any
+ kind of English document if British English is not available. A
+ user agent might suggest in such a case to add "en" to get the
+ best matching behavior.
+
+14.5 Accept-Ranges
+
+ The Accept-Ranges response-header field allows the server to
+ indicate its acceptance of range requests for a resource:
+
+ Accept-Ranges = "Accept-Ranges" ":" acceptable-ranges
+ acceptable-ranges = 1#range-unit | "none"
+
+ Origin servers that accept byte-range requests MAY send
+
+ Accept-Ranges: bytes
+
+ but are not required to do so. Clients MAY generate byte-range
+ requests without having received this header for the resource
+ involved. Range units are defined in section 3.12.
+
+ Servers that do not accept any kind of range request for a
+ resource MAY send
+
+ Accept-Ranges: none
+
+ to advise the client not to attempt a range request.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 105]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+14.6 Age
+
+ The Age response-header field conveys the sender's estimate of the
+ amount of time since the response (or its revalidation) was
+ generated at the origin server. A cached response is "fresh" if
+ its age does not exceed its freshness lifetime. Age values are
+ calculated as specified in section 13.2.3.
+
+ Age = "Age" ":" age-value
+ age-value = delta-seconds
+
+ Age values are non-negative decimal integers, representing time in
+ seconds.
+
+ If a cache receives a value larger than the largest positive
+ integer it can represent, or if any of its age calculations
+ overflows, it MUST transmit an Age header with a value of
+ 2147483648 (2^31). An HTTP/1.1 server that includes a cache MUST
+ include an Age header field in every response generated from its
+ own cache. Caches SHOULD use an arithmetic type of at least 31
+ bits of range.
+
+14.7 Allow
+
+ The Allow entity-header field lists the set of methods supported
+ by the resource identified by the Request-URI. The purpose of this
+ field is strictly to inform the recipient of valid methods
+ associated with the resource. An Allow header field MUST be
+ present in a 405 (Method Not Allowed) response.
+
+ Allow = "Allow" ":" #Method
+
+ Example of use:
+
+ Allow: GET, HEAD, PUT
+
+ This field cannot prevent a client from trying other methods.
+ However, the indications given by the Allow header field value
+ SHOULD be followed. The actual set of allowed methods is defined
+ by the origin server at the time of each request.
+
+ The Allow header field MAY be provided with a PUT request to
+ recommend the methods to be supported by the new or modified
+ resource. The server is not required to support these methods and
+ SHOULD include an Allow header in the response giving the actual
+ supported methods.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 106]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ A proxy MUST NOT modify the Allow header field even if it does not
+ understand all the methods specified, since the user agent might
+ have other means of communicating with the origin server.
+
+14.8 Authorization
+
+ A user agent that wishes to authenticate itself with a server--
+ usually, but not necessarily, after receiving a 401 response--does
+ so by including an Authorization request-header field with the
+ request. The Authorization field value consists of credentials
+ containing the authentication information of the user agent for
+ the realm of the resource being requested.
+
+ Authorization = "Authorization" ":" credentials
+
+ HTTP access authentication is described in "HTTP Authentication:
+ Basic and Digest Access Authentication" [43]. If a request is
+ authenticated and a realm specified, the same credentials SHOULD
+ be valid for all other requests within this realm (assuming that
+ the authentication scheme itself does not require otherwise, such
+ as credentials that vary according to a challenge value or using
+ synchronized clocks).
+
+ When a shared cache (see section 13.7) receives a request
+ containing an Authorization field, it MUST NOT return the
+ corresponding response as a reply to any other request, unless one
+ of the following specific exceptions holds:
+
+ 1. If the response includes the "s-maxage" cache-control
+ directive, the cache MAY use that response in replying to a
+ subsequent request. But (if the specified maximum age has
+ passed) a proxy cache MUST first revalidate it with the origin
+ server, using the request-headers from the new request to allow
+ the origin server to authenticate the new request. (This is the
+ defined behavior for s-maxage.) If the response includes "s-
+ maxage=0", the proxy MUST always revalidate it before re-using
+ it.
+
+ 2. If the response includes the "must-revalidate" cache-control
+ directive, the cache MAY use that response in replying to a
+ subsequent request. But if the response is stale, all caches
+ MUST first revalidate it with the origin server, using the
+ request-headers from the new request to allow the origin server
+ to authenticate the new request.
+
+ 3. If the response includes the "public" cache-control directive,
+ it MAY be returned in reply to any subsequent request.
+
+
+
+
+Fielding, et al. Standards Track [Page 107]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+14.9 Cache-Control
+
+ The Cache-Control general-header field is used to specify directives
+ that MUST be obeyed by all caching mechanisms along the
+ request/response chain. The directives specify behavior intended to
+ prevent caches from adversely interfering with the request or
+ response. These directives typically override the default caching
+ algorithms. Cache directives are unidirectional in that the presence
+ of a directive in a request does not imply that the same directive is
+ to be given in the response.
+
+ Note that HTTP/1.0 caches might not implement Cache-Control and
+ might only implement Pragma: no-cache (see section 14.32).
+
+ Cache directives MUST be passed through by a proxy or gateway
+ application, regardless of their significance to that application,
+ since the directives might be applicable to all recipients along the
+ request/response chain. It is not possible to specify a cache-
+ directive for a specific cache.
+
+ Cache-Control = "Cache-Control" ":" 1#cache-directive
+
+ cache-directive = cache-request-directive
+ | cache-response-directive
+
+ cache-request-directive =
+ "no-cache" ; Section 14.9.1
+ | "no-store" ; Section 14.9.2
+ | "max-age" "=" delta-seconds ; Section 14.9.3, 14.9.4
+ | "max-stale" [ "=" delta-seconds ] ; Section 14.9.3
+ | "min-fresh" "=" delta-seconds ; Section 14.9.3
+ | "no-transform" ; Section 14.9.5
+ | "only-if-cached" ; Section 14.9.4
+ | cache-extension ; Section 14.9.6
+
+ cache-response-directive =
+ "public" ; Section 14.9.1
+ | "private" [ "=" <"> 1#field-name <"> ] ; Section 14.9.1
+ | "no-cache" [ "=" <"> 1#field-name <"> ]; Section 14.9.1
+ | "no-store" ; Section 14.9.2
+ | "no-transform" ; Section 14.9.5
+ | "must-revalidate" ; Section 14.9.4
+ | "proxy-revalidate" ; Section 14.9.4
+ | "max-age" "=" delta-seconds ; Section 14.9.3
+ | "s-maxage" "=" delta-seconds ; Section 14.9.3
+ | cache-extension ; Section 14.9.6
+
+ cache-extension = token [ "=" ( token | quoted-string ) ]
+
+
+
+Fielding, et al. Standards Track [Page 108]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ When a directive appears without any 1#field-name parameter, the
+ directive applies to the entire request or response. When such a
+ directive appears with a 1#field-name parameter, it applies only to
+ the named field or fields, and not to the rest of the request or
+ response. This mechanism supports extensibility; implementations of
+ future versions of the HTTP protocol might apply these directives to
+ header fields not defined in HTTP/1.1.
+
+ The cache-control directives can be broken down into these general
+ categories:
+
+ - Restrictions on what are cacheable; these may only be imposed by
+ the origin server.
+
+ - Restrictions on what may be stored by a cache; these may be
+ imposed by either the origin server or the user agent.
+
+ - Modifications of the basic expiration mechanism; these may be
+ imposed by either the origin server or the user agent.
+
+ - Controls over cache revalidation and reload; these may only be
+ imposed by a user agent.
+
+ - Control over transformation of entities.
+
+ - Extensions to the caching system.
+
+14.9.1 What is Cacheable
+
+ By default, a response is cacheable if the requirements of the
+ request method, request header fields, and the response status
+ indicate that it is cacheable. Section 13.4 summarizes these defaults
+ for cacheability. The following Cache-Control response directives
+ allow an origin server to override the default cacheability of a
+ response:
+
+ public
+ Indicates that the response MAY be cached by any cache, even if it
+ would normally be non-cacheable or cacheable only within a non-
+ shared cache. (See also Authorization, section 14.8, for
+ additional details.)
+
+ private
+ Indicates that all or part of the response message is intended for
+ a single user and MUST NOT be cached by a shared cache. This
+ allows an origin server to state that the specified parts of the
+
+
+
+
+
+Fielding, et al. Standards Track [Page 109]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ response are intended for only one user and are not a valid
+ response for requests by other users. A private (non-shared) cache
+ MAY cache the response.
+
+ Note: This usage of the word private only controls where the
+ response may be cached, and cannot ensure the privacy of the
+ message content.
+
+ no-cache
+ If the no-cache directive does not specify a field-name, then a
+ cache MUST NOT use the response to satisfy a subsequent request
+ without successful revalidation with the origin server. This
+ allows an origin server to prevent caching even by caches that
+ have been configured to return stale responses to client requests.
+
+ If the no-cache directive does specify one or more field-names,
+ then a cache MAY use the response to satisfy a subsequent request,
+ subject to any other restrictions on caching. However, the
+ specified field-name(s) MUST NOT be sent in the response to a
+ subsequent request without successful revalidation with the origin
+ server. This allows an origin server to prevent the re-use of
+ certain header fields in a response, while still allowing caching
+ of the rest of the response.
+
+ Note: Most HTTP/1.0 caches will not recognize or obey this
+ directive.
+
+14.9.2 What May be Stored by Caches
+
+ no-store
+ The purpose of the no-store directive is to prevent the
+ inadvertent release or retention of sensitive information (for
+ example, on backup tapes). The no-store directive applies to the
+ entire message, and MAY be sent either in a response or in a
+ request. If sent in a request, a cache MUST NOT store any part of
+ either this request or any response to it. If sent in a response,
+ a cache MUST NOT store any part of either this response or the
+ request that elicited it. This directive applies to both non-
+ shared and shared caches. "MUST NOT store" in this context means
+ that the cache MUST NOT intentionally store the information in
+ non-volatile storage, and MUST make a best-effort attempt to
+ remove the information from volatile storage as promptly as
+ possible after forwarding it.
+
+ Even when this directive is associated with a response, users
+ might explicitly store such a response outside of the caching
+ system (e.g., with a "Save As" dialog). History buffers MAY store
+ such responses as part of their normal operation.
+
+
+
+Fielding, et al. Standards Track [Page 110]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ The purpose of this directive is to meet the stated requirements
+ of certain users and service authors who are concerned about
+ accidental releases of information via unanticipated accesses to
+ cache data structures. While the use of this directive might
+ improve privacy in some cases, we caution that it is NOT in any
+ way a reliable or sufficient mechanism for ensuring privacy. In
+ particular, malicious or compromised caches might not recognize or
+ obey this directive, and communications networks might be
+ vulnerable to eavesdropping.
+
+14.9.3 Modifications of the Basic Expiration Mechanism
+
+ The expiration time of an entity MAY be specified by the origin
+ server using the Expires header (see section 14.21). Alternatively,
+ it MAY be specified using the max-age directive in a response. When
+ the max-age cache-control directive is present in a cached response,
+ the response is stale if its current age is greater than the age
+ value given (in seconds) at the time of a new request for that
+ resource. The max-age directive on a response implies that the
+ response is cacheable (i.e., "public") unless some other, more
+ restrictive cache directive is also present.
+
+ If a response includes both an Expires header and a max-age
+ directive, the max-age directive overrides the Expires header, even
+ if the Expires header is more restrictive. This rule allows an origin
+ server to provide, for a given response, a longer expiration time to
+ an HTTP/1.1 (or later) cache than to an HTTP/1.0 cache. This might be
+ useful if certain HTTP/1.0 caches improperly calculate ages or
+ expiration times, perhaps due to desynchronized clocks.
+
+ Many HTTP/1.0 cache implementations will treat an Expires value that
+ is less than or equal to the response Date value as being equivalent
+ to the Cache-Control response directive "no-cache". If an HTTP/1.1
+ cache receives such a response, and the response does not include a
+ Cache-Control header field, it SHOULD consider the response to be
+ non-cacheable in order to retain compatibility with HTTP/1.0 servers.
+
+ Note: An origin server might wish to use a relatively new HTTP
+ cache control feature, such as the "private" directive, on a
+ network including older caches that do not understand that
+ feature. The origin server will need to combine the new feature
+ with an Expires field whose value is less than or equal to the
+ Date value. This will prevent older caches from improperly
+ caching the response.
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 111]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ s-maxage
+ If a response includes an s-maxage directive, then for a shared
+ cache (but not for a private cache), the maximum age specified by
+ this directive overrides the maximum age specified by either the
+ max-age directive or the Expires header. The s-maxage directive
+ also implies the semantics of the proxy-revalidate directive (see
+ section 14.9.4), i.e., that the shared cache must not use the
+ entry after it becomes stale to respond to a subsequent request
+ without first revalidating it with the origin server. The s-
+ maxage directive is always ignored by a private cache.
+
+ Note that most older caches, not compliant with this specification,
+ do not implement any cache-control directives. An origin server
+ wishing to use a cache-control directive that restricts, but does not
+ prevent, caching by an HTTP/1.1-compliant cache MAY exploit the
+ requirement that the max-age directive overrides the Expires header,
+ and the fact that pre-HTTP/1.1-compliant caches do not observe the
+ max-age directive.
+
+ Other directives allow a user agent to modify the basic expiration
+ mechanism. These directives MAY be specified on a request:
+
+ max-age
+ Indicates that the client is willing to accept a response whose
+ age is no greater than the specified time in seconds. Unless max-
+ stale directive is also included, the client is not willing to
+ accept a stale response.
+
+ min-fresh
+ Indicates that the client is willing to accept a response whose
+ freshness lifetime is no less than its current age plus the
+ specified time in seconds. That is, the client wants a response
+ that will still be fresh for at least the specified number of
+ seconds.
+
+ max-stale
+ Indicates that the client is willing to accept a response that has
+ exceeded its expiration time. If max-stale is assigned a value,
+ then the client is willing to accept a response that has exceeded
+ its expiration time by no more than the specified number of
+ seconds. If no value is assigned to max-stale, then the client is
+ willing to accept a stale response of any age.
+
+ If a cache returns a stale response, either because of a max-stale
+ directive on a request, or because the cache is configured to
+ override the expiration time of a response, the cache MUST attach a
+ Warning header to the stale response, using Warning 110 (Response is
+ stale).
+
+
+
+Fielding, et al. Standards Track [Page 112]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ A cache MAY be configured to return stale responses without
+ validation, but only if this does not conflict with any "MUST"-level
+ requirements concerning cache validation (e.g., a "must-revalidate"
+ cache-control directive).
+
+ If both the new request and the cached entry include "max-age"
+ directives, then the lesser of the two values is used for determining
+ the freshness of the cached entry for that request.
+
+14.9.4 Cache Revalidation and Reload Controls
+
+ Sometimes a user agent might want or need to insist that a cache
+ revalidate its cache entry with the origin server (and not just with
+ the next cache along the path to the origin server), or to reload its
+ cache entry from the origin server. End-to-end revalidation might be
+ necessary if either the cache or the origin server has overestimated
+ the expiration time of the cached response. End-to-end reload may be
+ necessary if the cache entry has become corrupted for some reason.
+
+ End-to-end revalidation may be requested either when the client does
+ not have its own local cached copy, in which case we call it
+ "unspecified end-to-end revalidation", or when the client does have a
+ local cached copy, in which case we call it "specific end-to-end
+ revalidation."
+
+ The client can specify these three kinds of action using Cache-
+ Control request directives:
+
+ End-to-end reload
+ The request includes a "no-cache" cache-control directive or, for
+ compatibility with HTTP/1.0 clients, "Pragma: no-cache". Field
+ names MUST NOT be included with the no-cache directive in a
+ request. The server MUST NOT use a cached copy when responding to
+ such a request.
+
+ Specific end-to-end revalidation
+ The request includes a "max-age=0" cache-control directive, which
+ forces each cache along the path to the origin server to
+ revalidate its own entry, if any, with the next cache or server.
+ The initial request includes a cache-validating conditional with
+ the client's current validator.
+
+ Unspecified end-to-end revalidation
+ The request includes "max-age=0" cache-control directive, which
+ forces each cache along the path to the origin server to
+ revalidate its own entry, if any, with the next cache or server.
+ The initial request does not include a cache-validating
+
+
+
+
+Fielding, et al. Standards Track [Page 113]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ conditional; the first cache along the path (if any) that holds a
+ cache entry for this resource includes a cache-validating
+ conditional with its current validator.
+
+ max-age
+ When an intermediate cache is forced, by means of a max-age=0
+ directive, to revalidate its own cache entry, and the client has
+ supplied its own validator in the request, the supplied validator
+ might differ from the validator currently stored with the cache
+ entry. In this case, the cache MAY use either validator in making
+ its own request without affecting semantic transparency.
+
+ However, the choice of validator might affect performance. The
+ best approach is for the intermediate cache to use its own
+ validator when making its request. If the server replies with 304
+ (Not Modified), then the cache can return its now validated copy
+ to the client with a 200 (OK) response. If the server replies with
+ a new entity and cache validator, however, the intermediate cache
+ can compare the returned validator with the one provided in the
+ client's request, using the strong comparison function. If the
+ client's validator is equal to the origin server's, then the
+ intermediate cache simply returns 304 (Not Modified). Otherwise,
+ it returns the new entity with a 200 (OK) response.
+
+ If a request includes the no-cache directive, it SHOULD NOT
+ include min-fresh, max-stale, or max-age.
+
+ only-if-cached
+ In some cases, such as times of extremely poor network
+ connectivity, a client may want a cache to return only those
+ responses that it currently has stored, and not to reload or
+ revalidate with the origin server. To do this, the client may
+ include the only-if-cached directive in a request. If it receives
+ this directive, a cache SHOULD either respond using a cached entry
+ that is consistent with the other constraints of the request, or
+ respond with a 504 (Gateway Timeout) status. However, if a group
+ of caches is being operated as a unified system with good internal
+ connectivity, such a request MAY be forwarded within that group of
+ caches.
+
+ must-revalidate
+ Because a cache MAY be configured to ignore a server's specified
+ expiration time, and because a client request MAY include a max-
+ stale directive (which has a similar effect), the protocol also
+ includes a mechanism for the origin server to require revalidation
+ of a cache entry on any subsequent use. When the must-revalidate
+ directive is present in a response received by a cache, that cache
+ MUST NOT use the entry after it becomes stale to respond to a
+
+
+
+Fielding, et al. Standards Track [Page 114]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ subsequent request without first revalidating it with the origin
+ server. (I.e., the cache MUST do an end-to-end revalidation every
+ time, if, based solely on the origin server's Expires or max-age
+ value, the cached response is stale.)
+
+ The must-revalidate directive is necessary to support reliable
+ operation for certain protocol features. In all circumstances an
+ HTTP/1.1 cache MUST obey the must-revalidate directive; in
+ particular, if the cache cannot reach the origin server for any
+ reason, it MUST generate a 504 (Gateway Timeout) response.
+
+ Servers SHOULD send the must-revalidate directive if and only if
+ failure to revalidate a request on the entity could result in
+ incorrect operation, such as a silently unexecuted financial
+ transaction. Recipients MUST NOT take any automated action that
+ violates this directive, and MUST NOT automatically provide an
+ unvalidated copy of the entity if revalidation fails.
+
+ Although this is not recommended, user agents operating under
+ severe connectivity constraints MAY violate this directive but, if
+ so, MUST explicitly warn the user that an unvalidated response has
+ been provided. The warning MUST be provided on each unvalidated
+ access, and SHOULD require explicit user confirmation.
+
+ proxy-revalidate
+ The proxy-revalidate directive has the same meaning as the must-
+ revalidate directive, except that it does not apply to non-shared
+ user agent caches. It can be used on a response to an
+ authenticated request to permit the user's cache to store and
+ later return the response without needing to revalidate it (since
+ it has already been authenticated once by that user), while still
+ requiring proxies that service many users to revalidate each time
+ (in order to make sure that each user has been authenticated).
+ Note that such authenticated responses also need the public cache
+ control directive in order to allow them to be cached at all.
+
+14.9.5 No-Transform Directive
+
+ no-transform
+ Implementors of intermediate caches (proxies) have found it useful
+ to convert the media type of certain entity bodies. A non-
+ transparent proxy might, for example, convert between image
+ formats in order to save cache space or to reduce the amount of
+ traffic on a slow link.
+
+ Serious operational problems occur, however, when these
+ transformations are applied to entity bodies intended for certain
+ kinds of applications. For example, applications for medical
+
+
+
+Fielding, et al. Standards Track [Page 115]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ imaging, scientific data analysis and those using end-to-end
+ authentication, all depend on receiving an entity body that is bit
+ for bit identical to the original entity-body.
+
+ Therefore, if a message includes the no-transform directive, an
+ intermediate cache or proxy MUST NOT change those headers that are
+ listed in section 13.5.2 as being subject to the no-transform
+ directive. This implies that the cache or proxy MUST NOT change
+ any aspect of the entity-body that is specified by these headers,
+ including the value of the entity-body itself.
+
+14.9.6 Cache Control Extensions
+
+ The Cache-Control header field can be extended through the use of one
+ or more cache-extension tokens, each with an optional assigned value.
+ Informational extensions (those which do not require a change in
+ cache behavior) MAY be added without changing the semantics of other
+ directives. Behavioral extensions are designed to work by acting as
+ modifiers to the existing base of cache directives. Both the new
+ directive and the standard directive are supplied, such that
+ applications which do not understand the new directive will default
+ to the behavior specified by the standard directive, and those that
+ understand the new directive will recognize it as modifying the
+ requirements associated with the standard directive. In this way,
+ extensions to the cache-control directives can be made without
+ requiring changes to the base protocol.
+
+ This extension mechanism depends on an HTTP cache obeying all of the
+ cache-control directives defined for its native HTTP-version, obeying
+ certain extensions, and ignoring all directives that it does not
+ understand.
+
+ For example, consider a hypothetical new response directive called
+ community which acts as a modifier to the private directive. We
+ define this new directive to mean that, in addition to any non-shared
+ cache, any cache which is shared only by members of the community
+ named within its value may cache the response. An origin server
+ wishing to allow the UCI community to use an otherwise private
+ response in their shared cache(s) could do so by including
+
+ Cache-Control: private, community="UCI"
+
+ A cache seeing this header field will act correctly even if the cache
+ does not understand the community cache-extension, since it will also
+ see and understand the private directive and thus default to the safe
+ behavior.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 116]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Unrecognized cache-directives MUST be ignored; it is assumed that any
+ cache-directive likely to be unrecognized by an HTTP/1.1 cache will
+ be combined with standard directives (or the response's default
+ cacheability) such that the cache behavior will remain minimally
+ correct even if the cache does not understand the extension(s).
+
+14.10 Connection
+
+ The Connection general-header field allows the sender to specify
+ options that are desired for that particular connection and MUST NOT
+ be communicated by proxies over further connections.
+
+ The Connection header has the following grammar:
+
+ Connection = "Connection" ":" 1#(connection-token)
+ connection-token = token
+
+ HTTP/1.1 proxies MUST parse the Connection header field before a
+ message is forwarded and, for each connection-token in this field,
+ remove any header field(s) from the message with the same name as the
+ connection-token. Connection options are signaled by the presence of
+ a connection-token in the Connection header field, not by any
+ corresponding additional header field(s), since the additional header
+ field may not be sent if there are no parameters associated with that
+ connection option.
+
+ Message headers listed in the Connection header MUST NOT include
+ end-to-end headers, such as Cache-Control.
+
+ HTTP/1.1 defines the "close" connection option for the sender to
+ signal that the connection will be closed after completion of the
+ response. For example,
+
+ Connection: close
+
+ in either the request or the response header fields indicates that
+ the connection SHOULD NOT be considered `persistent' (section 8.1)
+ after the current request/response is complete.
+
+ HTTP/1.1 applications that do not support persistent connections MUST
+ include the "close" connection option in every message.
+
+ A system receiving an HTTP/1.0 (or lower-version) message that
+ includes a Connection header MUST, for each connection-token in this
+ field, remove and ignore any header field(s) from the message with
+ the same name as the connection-token. This protects against mistaken
+ forwarding of such header fields by pre-HTTP/1.1 proxies. See section
+ 19.6.2.
+
+
+
+Fielding, et al. Standards Track [Page 117]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+14.11 Content-Encoding
+
+ The Content-Encoding entity-header field is used as a modifier to the
+ media-type. When present, its value indicates what additional content
+ codings have been applied to the entity-body, and thus what decoding
+ mechanisms must be applied in order to obtain the media-type
+ referenced by the Content-Type header field. Content-Encoding is
+ primarily used to allow a document to be compressed without losing
+ the identity of its underlying media type.
+
+ Content-Encoding = "Content-Encoding" ":" 1#content-coding
+
+ Content codings are defined in section 3.5. An example of its use is
+
+ Content-Encoding: gzip
+
+ The content-coding is a characteristic of the entity identified by
+ the Request-URI. Typically, the entity-body is stored with this
+ encoding and is only decoded before rendering or analogous usage.
+ However, a non-transparent proxy MAY modify the content-coding if the
+ new coding is known to be acceptable to the recipient, unless the
+ "no-transform" cache-control directive is present in the message.
+
+ If the content-coding of an entity is not "identity", then the
+ response MUST include a Content-Encoding entity-header (section
+ 14.11) that lists the non-identity content-coding(s) used.
+
+ If the content-coding of an entity in a request message is not
+ acceptable to the origin server, the server SHOULD respond with a
+ status code of 415 (Unsupported Media Type).
+
+ If multiple encodings have been applied to an entity, the content
+ codings MUST be listed in the order in which they were applied.
+ Additional information about the encoding parameters MAY be provided
+ by other entity-header fields not defined by this specification.
+
+14.12 Content-Language
+
+ The Content-Language entity-header field describes the natural
+ language(s) of the intended audience for the enclosed entity. Note
+ that this might not be equivalent to all the languages used within
+ the entity-body.
+
+ Content-Language = "Content-Language" ":" 1#language-tag
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 118]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Language tags are defined in section 3.10. The primary purpose of
+ Content-Language is to allow a user to identify and differentiate
+ entities according to the user's own preferred language. Thus, if the
+ body content is intended only for a Danish-literate audience, the
+ appropriate field is
+
+ Content-Language: da
+
+ If no Content-Language is specified, the default is that the content
+ is intended for all language audiences. This might mean that the
+ sender does not consider it to be specific to any natural language,
+ or that the sender does not know for which language it is intended.
+
+ Multiple languages MAY be listed for content that is intended for
+ multiple audiences. For example, a rendition of the "Treaty of
+ Waitangi," presented simultaneously in the original Maori and English
+ versions, would call for
+
+ Content-Language: mi, en
+
+ However, just because multiple languages are present within an entity
+ does not mean that it is intended for multiple linguistic audiences.
+ An example would be a beginner's language primer, such as "A First
+ Lesson in Latin," which is clearly intended to be used by an
+ English-literate audience. In this case, the Content-Language would
+ properly only include "en".
+
+ Content-Language MAY be applied to any media type -- it is not
+ limited to textual documents.
+
+14.13 Content-Length
+
+ The Content-Length entity-header field indicates the size of the
+ entity-body, in decimal number of OCTETs, sent to the recipient or,
+ in the case of the HEAD method, the size of the entity-body that
+ would have been sent had the request been a GET.
+
+ Content-Length = "Content-Length" ":" 1*DIGIT
+
+ An example is
+
+ Content-Length: 3495
+
+ Applications SHOULD use this field to indicate the transfer-length of
+ the message-body, unless this is prohibited by the rules in section
+ 4.4.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 119]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Any Content-Length greater than or equal to zero is a valid value.
+ Section 4.4 describes how to determine the length of a message-body
+ if a Content-Length is not given.
+
+ Note that the meaning of this field is significantly different from
+ the corresponding definition in MIME, where it is an optional field
+ used within the "message/external-body" content-type. In HTTP, it
+ SHOULD be sent whenever the message's length can be determined prior
+ to being transferred, unless this is prohibited by the rules in
+ section 4.4.
+
+14.14 Content-Location
+
+ The Content-Location entity-header field MAY be used to supply the
+ resource location for the entity enclosed in the message when that
+ entity is accessible from a location separate from the requested
+ resource's URI. A server SHOULD provide a Content-Location for the
+ variant corresponding to the response entity; especially in the case
+ where a resource has multiple entities associated with it, and those
+ entities actually have separate locations by which they might be
+ individually accessed, the server SHOULD provide a Content-Location
+ for the particular variant which is returned.
+
+ Content-Location = "Content-Location" ":"
+ ( absoluteURI | relativeURI )
+
+ The value of Content-Location also defines the base URI for the
+ entity.
+
+ The Content-Location value is not a replacement for the original
+ requested URI; it is only a statement of the location of the resource
+ corresponding to this particular entity at the time of the request.
+ Future requests MAY specify the Content-Location URI as the request-
+ URI if the desire is to identify the source of that particular
+ entity.
+
+ A cache cannot assume that an entity with a Content-Location
+ different from the URI used to retrieve it can be used to respond to
+ later requests on that Content-Location URI. However, the Content-
+ Location can be used to differentiate between multiple entities
+ retrieved from a single requested resource, as described in section
+ 13.6.
+
+ If the Content-Location is a relative URI, the relative URI is
+ interpreted relative to the Request-URI.
+
+ The meaning of the Content-Location header in PUT or POST requests is
+ undefined; servers are free to ignore it in those cases.
+
+
+
+Fielding, et al. Standards Track [Page 120]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+14.15 Content-MD5
+
+ The Content-MD5 entity-header field, as defined in RFC 1864 [23], is
+ an MD5 digest of the entity-body for the purpose of providing an
+ end-to-end message integrity check (MIC) of the entity-body. (Note: a
+ MIC is good for detecting accidental modification of the entity-body
+ in transit, but is not proof against malicious attacks.)
+
+ Content-MD5 = "Content-MD5" ":" md5-digest
+ md5-digest = <base64 of 128 bit MD5 digest as per RFC 1864>
+
+ The Content-MD5 header field MAY be generated by an origin server or
+ client to function as an integrity check of the entity-body. Only
+ origin servers or clients MAY generate the Content-MD5 header field;
+ proxies and gateways MUST NOT generate it, as this would defeat its
+ value as an end-to-end integrity check. Any recipient of the entity-
+ body, including gateways and proxies, MAY check that the digest value
+ in this header field matches that of the entity-body as received.
+
+ The MD5 digest is computed based on the content of the entity-body,
+ including any content-coding that has been applied, but not including
+ any transfer-encoding applied to the message-body. If the message is
+ received with a transfer-encoding, that encoding MUST be removed
+ prior to checking the Content-MD5 value against the received entity.
+
+ This has the result that the digest is computed on the octets of the
+ entity-body exactly as, and in the order that, they would be sent if
+ no transfer-encoding were being applied.
+
+ HTTP extends RFC 1864 to permit the digest to be computed for MIME
+ composite media-types (e.g., multipart/* and message/rfc822), but
+ this does not change how the digest is computed as defined in the
+ preceding paragraph.
+
+ There are several consequences of this. The entity-body for composite
+ types MAY contain many body-parts, each with its own MIME and HTTP
+ headers (including Content-MD5, Content-Transfer-Encoding, and
+ Content-Encoding headers). If a body-part has a Content-Transfer-
+ Encoding or Content-Encoding header, it is assumed that the content
+ of the body-part has had the encoding applied, and the body-part is
+ included in the Content-MD5 digest as is -- i.e., after the
+ application. The Transfer-Encoding header field is not allowed within
+ body-parts.
+
+ Conversion of all line breaks to CRLF MUST NOT be done before
+ computing or checking the digest: the line break convention used in
+ the text actually transmitted MUST be left unaltered when computing
+ the digest.
+
+
+
+Fielding, et al. Standards Track [Page 121]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Note: while the definition of Content-MD5 is exactly the same for
+ HTTP as in RFC 1864 for MIME entity-bodies, there are several ways
+ in which the application of Content-MD5 to HTTP entity-bodies
+ differs from its application to MIME entity-bodies. One is that
+ HTTP, unlike MIME, does not use Content-Transfer-Encoding, and
+ does use Transfer-Encoding and Content-Encoding. Another is that
+ HTTP more frequently uses binary content types than MIME, so it is
+ worth noting that, in such cases, the byte order used to compute
+ the digest is the transmission byte order defined for the type.
+ Lastly, HTTP allows transmission of text types with any of several
+ line break conventions and not just the canonical form using CRLF.
+
+14.16 Content-Range
+
+ The Content-Range entity-header is sent with a partial entity-body to
+ specify where in the full entity-body the partial body should be
+ applied. Range units are defined in section 3.12.
+
+ Content-Range = "Content-Range" ":" content-range-spec
+
+ content-range-spec = byte-content-range-spec
+ byte-content-range-spec = bytes-unit SP
+ byte-range-resp-spec "/"
+ ( instance-length | "*" )
+
+ byte-range-resp-spec = (first-byte-pos "-" last-byte-pos)
+ | "*"
+ instance-length = 1*DIGIT
+
+ The header SHOULD indicate the total length of the full entity-body,
+ unless this length is unknown or difficult to determine. The asterisk
+ "*" character means that the instance-length is unknown at the time
+ when the response was generated.
+
+ Unlike byte-ranges-specifier values (see section 14.35.1), a byte-
+ range-resp-spec MUST only specify one range, and MUST contain
+ absolute byte positions for both the first and last byte of the
+ range.
+
+ A byte-content-range-spec with a byte-range-resp-spec whose last-
+ byte-pos value is less than its first-byte-pos value, or whose
+ instance-length value is less than or equal to its last-byte-pos
+ value, is invalid. The recipient of an invalid byte-content-range-
+ spec MUST ignore it and any content transferred along with it.
+
+ A server sending a response with status code 416 (Requested range not
+ satisfiable) SHOULD include a Content-Range field with a byte-range-
+ resp-spec of "*". The instance-length specifies the current length of
+
+
+
+Fielding, et al. Standards Track [Page 122]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ the selected resource. A response with status code 206 (Partial
+ Content) MUST NOT include a Content-Range field with a byte-range-
+ resp-spec of "*".
+
+ Examples of byte-content-range-spec values, assuming that the entity
+ contains a total of 1234 bytes:
+
+ . The first 500 bytes:
+ bytes 0-499/1234
+
+ . The second 500 bytes:
+ bytes 500-999/1234
+
+ . All except for the first 500 bytes:
+ bytes 500-1233/1234
+
+ . The last 500 bytes:
+ bytes 734-1233/1234
+
+ When an HTTP message includes the content of a single range (for
+ example, a response to a request for a single range, or to a request
+ for a set of ranges that overlap without any holes), this content is
+ transmitted with a Content-Range header, and a Content-Length header
+ showing the number of bytes actually transferred. For example,
+
+ HTTP/1.1 206 Partial content
+ Date: Wed, 15 Nov 1995 06:25:24 GMT
+ Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
+ Content-Range: bytes 21010-47021/47022
+ Content-Length: 26012
+ Content-Type: image/gif
+
+ When an HTTP message includes the content of multiple ranges (for
+ example, a response to a request for multiple non-overlapping
+ ranges), these are transmitted as a multipart message. The multipart
+ media type used for this purpose is "multipart/byteranges" as defined
+ in appendix 19.2. See appendix 19.6.3 for a compatibility issue.
+
+ A response to a request for a single range MUST NOT be sent using the
+ multipart/byteranges media type. A response to a request for
+ multiple ranges, whose result is a single range, MAY be sent as a
+ multipart/byteranges media type with one part. A client that cannot
+ decode a multipart/byteranges message MUST NOT ask for multiple
+ byte-ranges in a single request.
+
+ When a client requests multiple byte-ranges in one request, the
+ server SHOULD return them in the order that they appeared in the
+ request.
+
+
+
+Fielding, et al. Standards Track [Page 123]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ If the server ignores a byte-range-spec because it is syntactically
+ invalid, the server SHOULD treat the request as if the invalid Range
+ header field did not exist. (Normally, this means return a 200
+ response containing the full entity).
+
+ If the server receives a request (other than one including an If-
+ Range request-header field) with an unsatisfiable Range request-
+ header field (that is, all of whose byte-range-spec values have a
+ first-byte-pos value greater than the current length of the selected
+ resource), it SHOULD return a response code of 416 (Requested range
+ not satisfiable) (section 10.4.17).
+
+ Note: clients cannot depend on servers to send a 416 (Requested
+ range not satisfiable) response instead of a 200 (OK) response for
+ an unsatisfiable Range request-header, since not all servers
+ implement this request-header.
+
+14.17 Content-Type
+
+ The Content-Type entity-header field indicates the media type of the
+ entity-body sent to the recipient or, in the case of the HEAD method,
+ the media type that would have been sent had the request been a GET.
+
+ Content-Type = "Content-Type" ":" media-type
+
+ Media types are defined in section 3.7. An example of the field is
+
+ Content-Type: text/html; charset=ISO-8859-4
+
+ Further discussion of methods for identifying the media type of an
+ entity is provided in section 7.2.1.
+
+14.18 Date
+
+ The Date general-header field represents the date and time at which
+ the message was originated, having the same semantics as orig-date in
+ RFC 822. The field value is an HTTP-date, as described in section
+ 3.3.1; it MUST be sent in RFC 1123 [8]-date format.
+
+ Date = "Date" ":" HTTP-date
+
+ An example is
+
+ Date: Tue, 15 Nov 1994 08:12:31 GMT
+
+ Origin servers MUST include a Date header field in all responses,
+ except in these cases:
+
+
+
+
+Fielding, et al. Standards Track [Page 124]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 1. If the response status code is 100 (Continue) or 101 (Switching
+ Protocols), the response MAY include a Date header field, at
+ the server's option.
+
+ 2. If the response status code conveys a server error, e.g. 500
+ (Internal Server Error) or 503 (Service Unavailable), and it is
+ inconvenient or impossible to generate a valid Date.
+
+ 3. If the server does not have a clock that can provide a
+ reasonable approximation of the current time, its responses
+ MUST NOT include a Date header field. In this case, the rules
+ in section 14.18.1 MUST be followed.
+
+ A received message that does not have a Date header field MUST be
+ assigned one by the recipient if the message will be cached by that
+ recipient or gatewayed via a protocol which requires a Date. An HTTP
+ implementation without a clock MUST NOT cache responses without
+ revalidating them on every use. An HTTP cache, especially a shared
+ cache, SHOULD use a mechanism, such as NTP [28], to synchronize its
+ clock with a reliable external standard.
+
+ Clients SHOULD only send a Date header field in messages that include
+ an entity-body, as in the case of the PUT and POST requests, and even
+ then it is optional. A client without a clock MUST NOT send a Date
+ header field in a request.
+
+ The HTTP-date sent in a Date header SHOULD NOT represent a date and
+ time subsequent to the generation of the message. It SHOULD represent
+ the best available approximation of the date and time of message
+ generation, unless the implementation has no means of generating a
+ reasonably accurate date and time. In theory, the date ought to
+ represent the moment just before the entity is generated. In
+ practice, the date can be generated at any time during the message
+ origination without affecting its semantic value.
+
+14.18.1 Clockless Origin Server Operation
+
+ Some origin server implementations might not have a clock available.
+ An origin server without a clock MUST NOT assign Expires or Last-
+ Modified values to a response, unless these values were associated
+ with the resource by a system or user with a reliable clock. It MAY
+ assign an Expires value that is known, at or before server
+ configuration time, to be in the past (this allows "pre-expiration"
+ of responses without storing separate Expires values for each
+ resource).
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 125]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+14.19 ETag
+
+ The ETag response-header field provides the current value of the
+ entity tag for the requested variant. The headers used with entity
+ tags are described in sections 14.24, 14.26 and 14.44. The entity tag
+ MAY be used for comparison with other entities from the same resource
+ (see section 13.3.3).
+
+ ETag = "ETag" ":" entity-tag
+
+ Examples:
+
+ ETag: "xyzzy"
+ ETag: W/"xyzzy"
+ ETag: ""
+
+14.20 Expect
+
+ The Expect request-header field is used to indicate that particular
+ server behaviors are required by the client.
+
+ Expect = "Expect" ":" 1#expectation
+
+ expectation = "100-continue" | expectation-extension
+ expectation-extension = token [ "=" ( token | quoted-string )
+ *expect-params ]
+ expect-params = ";" token [ "=" ( token | quoted-string ) ]
+
+
+ A server that does not understand or is unable to comply with any of
+ the expectation values in the Expect field of a request MUST respond
+ with appropriate error status. The server MUST respond with a 417
+ (Expectation Failed) status if any of the expectations cannot be met
+ or, if there are other problems with the request, some other 4xx
+ status.
+
+ This header field is defined with extensible syntax to allow for
+ future extensions. If a server receives a request containing an
+ Expect field that includes an expectation-extension that it does not
+ support, it MUST respond with a 417 (Expectation Failed) status.
+
+ Comparison of expectation values is case-insensitive for unquoted
+ tokens (including the 100-continue token), and is case-sensitive for
+ quoted-string expectation-extensions.
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 126]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ The Expect mechanism is hop-by-hop: that is, an HTTP/1.1 proxy MUST
+ return a 417 (Expectation Failed) status if it receives a request
+ with an expectation that it cannot meet. However, the Expect
+ request-header itself is end-to-end; it MUST be forwarded if the
+ request is forwarded.
+
+ Many older HTTP/1.0 and HTTP/1.1 applications do not understand the
+ Expect header.
+
+ See section 8.2.3 for the use of the 100 (continue) status.
+
+14.21 Expires
+
+ The Expires entity-header field gives the date/time after which the
+ response is considered stale. A stale cache entry may not normally be
+ returned by a cache (either a proxy cache or a user agent cache)
+ unless it is first validated with the origin server (or with an
+ intermediate cache that has a fresh copy of the entity). See section
+ 13.2 for further discussion of the expiration model.
+
+ The presence of an Expires field does not imply that the original
+ resource will change or cease to exist at, before, or after that
+ time.
+
+ The format is an absolute date and time as defined by HTTP-date in
+ section 3.3.1; it MUST be in RFC 1123 date format:
+
+ Expires = "Expires" ":" HTTP-date
+
+ An example of its use is
+
+ Expires: Thu, 01 Dec 1994 16:00:00 GMT
+
+ Note: if a response includes a Cache-Control field with the max-
+ age directive (see section 14.9.3), that directive overrides the
+ Expires field.
+
+ HTTP/1.1 clients and caches MUST treat other invalid date formats,
+ especially including the value "0", as in the past (i.e., "already
+ expired").
+
+ To mark a response as "already expired," an origin server sends an
+ Expires date that is equal to the Date header value. (See the rules
+ for expiration calculations in section 13.2.4.)
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 127]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ To mark a response as "never expires," an origin server sends an
+ Expires date approximately one year from the time the response is
+ sent. HTTP/1.1 servers SHOULD NOT send Expires dates more than one
+ year in the future.
+
+ The presence of an Expires header field with a date value of some
+ time in the future on a response that otherwise would by default be
+ non-cacheable indicates that the response is cacheable, unless
+ indicated otherwise by a Cache-Control header field (section 14.9).
+
+14.22 From
+
+ The From request-header field, if given, SHOULD contain an Internet
+ e-mail address for the human user who controls the requesting user
+ agent. The address SHOULD be machine-usable, as defined by "mailbox"
+ in RFC 822 [9] as updated by RFC 1123 [8]:
+
+ From = "From" ":" mailbox
+
+ An example is:
+
+ From: webmaster@w3.org
+
+ This header field MAY be used for logging purposes and as a means for
+ identifying the source of invalid or unwanted requests. It SHOULD NOT
+ be used as an insecure form of access protection. The interpretation
+ of this field is that the request is being performed on behalf of the
+ person given, who accepts responsibility for the method performed. In
+ particular, robot agents SHOULD include this header so that the
+ person responsible for running the robot can be contacted if problems
+ occur on the receiving end.
+
+ The Internet e-mail address in this field MAY be separate from the
+ Internet host which issued the request. For example, when a request
+ is passed through a proxy the original issuer's address SHOULD be
+ used.
+
+ The client SHOULD NOT send the From header field without the user's
+ approval, as it might conflict with the user's privacy interests or
+ their site's security policy. It is strongly recommended that the
+ user be able to disable, enable, and modify the value of this field
+ at any time prior to a request.
+
+14.23 Host
+
+ The Host request-header field specifies the Internet host and port
+ number of the resource being requested, as obtained from the original
+ URI given by the user or referring resource (generally an HTTP URL,
+
+
+
+Fielding, et al. Standards Track [Page 128]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ as described in section 3.2.2). The Host field value MUST represent
+ the naming authority of the origin server or gateway given by the
+ original URL. This allows the origin server or gateway to
+ differentiate between internally-ambiguous URLs, such as the root "/"
+ URL of a server for multiple host names on a single IP address.
+
+ Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
+
+ A "host" without any trailing port information implies the default
+ port for the service requested (e.g., "80" for an HTTP URL). For
+ example, a request on the origin server for
+ <http://www.w3.org/pub/WWW/> would properly include:
+
+ GET /pub/WWW/ HTTP/1.1
+ Host: www.w3.org
+
+ A client MUST include a Host header field in all HTTP/1.1 request
+ messages . If the requested URI does not include an Internet host
+ name for the service being requested, then the Host header field MUST
+ be given with an empty value. An HTTP/1.1 proxy MUST ensure that any
+ request message it forwards does contain an appropriate Host header
+ field that identifies the service being requested by the proxy. All
+ Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad Request)
+ status code to any HTTP/1.1 request message which lacks a Host header
+ field.
+
+ See sections 5.2 and 19.6.1.1 for other requirements relating to
+ Host.
+
+14.24 If-Match
+
+ The If-Match request-header field is used with a method to make it
+ conditional. A client that has one or more entities previously
+ obtained from the resource can verify that one of those entities is
+ current by including a list of their associated entity tags in the
+ If-Match header field. Entity tags are defined in section 3.11. The
+ purpose of this feature is to allow efficient updates of cached
+ information with a minimum amount of transaction overhead. It is also
+ used, on updating requests, to prevent inadvertent modification of
+ the wrong version of a resource. As a special case, the value "*"
+ matches any current entity of the resource.
+
+ If-Match = "If-Match" ":" ( "*" | 1#entity-tag )
+
+ If any of the entity tags match the entity tag of the entity that
+ would have been returned in the response to a similar GET request
+ (without the If-Match header) on that resource, or if "*" is given
+
+
+
+
+Fielding, et al. Standards Track [Page 129]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ and any current entity exists for that resource, then the server MAY
+ perform the requested method as if the If-Match header field did not
+ exist.
+
+ A server MUST use the strong comparison function (see section 13.3.3)
+ to compare the entity tags in If-Match.
+
+ If none of the entity tags match, or if "*" is given and no current
+ entity exists, the server MUST NOT perform the requested method, and
+ MUST return a 412 (Precondition Failed) response. This behavior is
+ most useful when the client wants to prevent an updating method, such
+ as PUT, from modifying a resource that has changed since the client
+ last retrieved it.
+
+ If the request would, without the If-Match header field, result in
+ anything other than a 2xx or 412 status, then the If-Match header
+ MUST be ignored.
+
+ The meaning of "If-Match: *" is that the method SHOULD be performed
+ if the representation selected by the origin server (or by a cache,
+ possibly using the Vary mechanism, see section 14.44) exists, and
+ MUST NOT be performed if the representation does not exist.
+
+ A request intended to update a resource (e.g., a PUT) MAY include an
+ If-Match header field to signal that the request method MUST NOT be
+ applied if the entity corresponding to the If-Match value (a single
+ entity tag) is no longer a representation of that resource. This
+ allows the user to indicate that they do not wish the request to be
+ successful if the resource has been changed without their knowledge.
+ Examples:
+
+ If-Match: "xyzzy"
+ If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
+ If-Match: *
+
+ The result of a request having both an If-Match header field and
+ either an If-None-Match or an If-Modified-Since header fields is
+ undefined by this specification.
+
+14.25 If-Modified-Since
+
+ The If-Modified-Since request-header field is used with a method to
+ make it conditional: if the requested variant has not been modified
+ since the time specified in this field, an entity will not be
+ returned from the server; instead, a 304 (not modified) response will
+ be returned without any message-body.
+
+ If-Modified-Since = "If-Modified-Since" ":" HTTP-date
+
+
+
+Fielding, et al. Standards Track [Page 130]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ An example of the field is:
+
+ If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
+
+ A GET method with an If-Modified-Since header and no Range header
+ requests that the identified entity be transferred only if it has
+ been modified since the date given by the If-Modified-Since header.
+ The algorithm for determining this includes the following cases:
+
+ a) If the request would normally result in anything other than a
+ 200 (OK) status, or if the passed If-Modified-Since date is
+ invalid, the response is exactly the same as for a normal GET.
+ A date which is later than the server's current time is
+ invalid.
+
+ b) If the variant has been modified since the If-Modified-Since
+ date, the response is exactly the same as for a normal GET.
+
+ c) If the variant has not been modified since a valid If-
+ Modified-Since date, the server SHOULD return a 304 (Not
+ Modified) response.
+
+ The purpose of this feature is to allow efficient updates of cached
+ information with a minimum amount of transaction overhead.
+
+ Note: The Range request-header field modifies the meaning of If-
+ Modified-Since; see section 14.35 for full details.
+
+ Note: If-Modified-Since times are interpreted by the server, whose
+ clock might not be synchronized with the client.
+
+ Note: When handling an If-Modified-Since header field, some
+ servers will use an exact date comparison function, rather than a
+ less-than function, for deciding whether to send a 304 (Not
+ Modified) response. To get best results when sending an If-
+ Modified-Since header field for cache validation, clients are
+ advised to use the exact date string received in a previous Last-
+ Modified header field whenever possible.
+
+ Note: If a client uses an arbitrary date in the If-Modified-Since
+ header instead of a date taken from the Last-Modified header for
+ the same request, the client should be aware of the fact that this
+ date is interpreted in the server's understanding of time. The
+ client should consider unsynchronized clocks and rounding problems
+ due to the different encodings of time between the client and
+ server. This includes the possibility of race conditions if the
+ document has changed between the time it was first requested and
+ the If-Modified-Since date of a subsequent request, and the
+
+
+
+Fielding, et al. Standards Track [Page 131]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ possibility of clock-skew-related problems if the If-Modified-
+ Since date is derived from the client's clock without correction
+ to the server's clock. Corrections for different time bases
+ between client and server are at best approximate due to network
+ latency.
+
+ The result of a request having both an If-Modified-Since header field
+ and either an If-Match or an If-Unmodified-Since header fields is
+ undefined by this specification.
+
+14.26 If-None-Match
+
+ The If-None-Match request-header field is used with a method to make
+ it conditional. A client that has one or more entities previously
+ obtained from the resource can verify that none of those entities is
+ current by including a list of their associated entity tags in the
+ If-None-Match header field. The purpose of this feature is to allow
+ efficient updates of cached information with a minimum amount of
+ transaction overhead. It is also used to prevent a method (e.g. PUT)
+ from inadvertently modifying an existing resource when the client
+ believes that the resource does not exist.
+
+ As a special case, the value "*" matches any current entity of the
+ resource.
+
+ If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )
+
+ If any of the entity tags match the entity tag of the entity that
+ would have been returned in the response to a similar GET request
+ (without the If-None-Match header) on that resource, or if "*" is
+ given and any current entity exists for that resource, then the
+ server MUST NOT perform the requested method, unless required to do
+ so because the resource's modification date fails to match that
+ supplied in an If-Modified-Since header field in the request.
+ Instead, if the request method was GET or HEAD, the server SHOULD
+ respond with a 304 (Not Modified) response, including the cache-
+ related header fields (particularly ETag) of one of the entities that
+ matched. For all other request methods, the server MUST respond with
+ a status of 412 (Precondition Failed).
+
+ See section 13.3.3 for rules on how to determine if two entities tags
+ match. The weak comparison function can only be used with GET or HEAD
+ requests.
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 132]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ If none of the entity tags match, then the server MAY perform the
+ requested method as if the If-None-Match header field did not exist,
+ but MUST also ignore any If-Modified-Since header field(s) in the
+ request. That is, if no entity tags match, then the server MUST NOT
+ return a 304 (Not Modified) response.
+
+ If the request would, without the If-None-Match header field, result
+ in anything other than a 2xx or 304 status, then the If-None-Match
+ header MUST be ignored. (See section 13.3.4 for a discussion of
+ server behavior when both If-Modified-Since and If-None-Match appear
+ in the same request.)
+
+ The meaning of "If-None-Match: *" is that the method MUST NOT be
+ performed if the representation selected by the origin server (or by
+ a cache, possibly using the Vary mechanism, see section 14.44)
+ exists, and SHOULD be performed if the representation does not exist.
+ This feature is intended to be useful in preventing races between PUT
+ operations.
+
+ Examples:
+
+ If-None-Match: "xyzzy"
+ If-None-Match: W/"xyzzy"
+ If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
+ If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
+ If-None-Match: *
+
+ The result of a request having both an If-None-Match header field and
+ either an If-Match or an If-Unmodified-Since header fields is
+ undefined by this specification.
+
+14.27 If-Range
+
+ If a client has a partial copy of an entity in its cache, and wishes
+ to have an up-to-date copy of the entire entity in its cache, it
+ could use the Range request-header with a conditional GET (using
+ either or both of If-Unmodified-Since and If-Match.) However, if the
+ condition fails because the entity has been modified, the client
+ would then have to make a second request to obtain the entire current
+ entity-body.
+
+ The If-Range header allows a client to "short-circuit" the second
+ request. Informally, its meaning is `if the entity is unchanged, send
+ me the part(s) that I am missing; otherwise, send me the entire new
+ entity'.
+
+ If-Range = "If-Range" ":" ( entity-tag | HTTP-date )
+
+
+
+
+Fielding, et al. Standards Track [Page 133]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ If the client has no entity tag for an entity, but does have a Last-
+ Modified date, it MAY use that date in an If-Range header. (The
+ server can distinguish between a valid HTTP-date and any form of
+ entity-tag by examining no more than two characters.) The If-Range
+ header SHOULD only be used together with a Range header, and MUST be
+ ignored if the request does not include a Range header, or if the
+ server does not support the sub-range operation.
+
+ If the entity tag given in the If-Range header matches the current
+ entity tag for the entity, then the server SHOULD provide the
+ specified sub-range of the entity using a 206 (Partial content)
+ response. If the entity tag does not match, then the server SHOULD
+ return the entire entity using a 200 (OK) response.
+
+14.28 If-Unmodified-Since
+
+ The If-Unmodified-Since request-header field is used with a method to
+ make it conditional. If the requested resource has not been modified
+ since the time specified in this field, the server SHOULD perform the
+ requested operation as if the If-Unmodified-Since header were not
+ present.
+
+ If the requested variant has been modified since the specified time,
+ the server MUST NOT perform the requested operation, and MUST return
+ a 412 (Precondition Failed).
+
+ If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-date
+
+ An example of the field is:
+
+ If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
+
+ If the request normally (i.e., without the If-Unmodified-Since
+ header) would result in anything other than a 2xx or 412 status, the
+ If-Unmodified-Since header SHOULD be ignored.
+
+ If the specified date is invalid, the header is ignored.
+
+ The result of a request having both an If-Unmodified-Since header
+ field and either an If-None-Match or an If-Modified-Since header
+ fields is undefined by this specification.
+
+14.29 Last-Modified
+
+ The Last-Modified entity-header field indicates the date and time at
+ which the origin server believes the variant was last modified.
+
+ Last-Modified = "Last-Modified" ":" HTTP-date
+
+
+
+Fielding, et al. Standards Track [Page 134]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ An example of its use is
+
+ Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
+
+ The exact meaning of this header field depends on the implementation
+ of the origin server and the nature of the original resource. For
+ files, it may be just the file system last-modified time. For
+ entities with dynamically included parts, it may be the most recent
+ of the set of last-modify times for its component parts. For database
+ gateways, it may be the last-update time stamp of the record. For
+ virtual objects, it may be the last time the internal state changed.
+
+ An origin server MUST NOT send a Last-Modified date which is later
+ than the server's time of message origination. In such cases, where
+ the resource's last modification would indicate some time in the
+ future, the server MUST replace that date with the message
+ origination date.
+
+ An origin server SHOULD obtain the Last-Modified value of the entity
+ as close as possible to the time that it generates the Date value of
+ its response. This allows a recipient to make an accurate assessment
+ of the entity's modification time, especially if the entity changes
+ near the time that the response is generated.
+
+ HTTP/1.1 servers SHOULD send Last-Modified whenever feasible.
+
+14.30 Location
+
+ The Location response-header field is used to redirect the recipient
+ to a location other than the Request-URI for completion of the
+ request or identification of a new resource. For 201 (Created)
+ responses, the Location is that of the new resource which was created
+ by the request. For 3xx responses, the location SHOULD indicate the
+ server's preferred URI for automatic redirection to the resource. The
+ field value consists of a single absolute URI.
+
+ Location = "Location" ":" absoluteURI
+
+ An example is:
+
+ Location: http://www.w3.org/pub/WWW/People.html
+
+ Note: The Content-Location header field (section 14.14) differs
+ from Location in that the Content-Location identifies the original
+ location of the entity enclosed in the request. It is therefore
+ possible for a response to contain header fields for both Location
+ and Content-Location. Also see section 13.10 for cache
+ requirements of some methods.
+
+
+
+Fielding, et al. Standards Track [Page 135]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+14.31 Max-Forwards
+
+ The Max-Forwards request-header field provides a mechanism with the
+ TRACE (section 9.8) and OPTIONS (section 9.2) methods to limit the
+ number of proxies or gateways that can forward the request to the
+ next inbound server. This can be useful when the client is attempting
+ to trace a request chain which appears to be failing or looping in
+ mid-chain.
+
+ Max-Forwards = "Max-Forwards" ":" 1*DIGIT
+
+ The Max-Forwards value is a decimal integer indicating the remaining
+ number of times this request message may be forwarded.
+
+ Each proxy or gateway recipient of a TRACE or OPTIONS request
+ containing a Max-Forwards header field MUST check and update its
+ value prior to forwarding the request. If the received value is zero
+ (0), the recipient MUST NOT forward the request; instead, it MUST
+ respond as the final recipient. If the received Max-Forwards value is
+ greater than zero, then the forwarded message MUST contain an updated
+ Max-Forwards field with a value decremented by one (1).
+
+ The Max-Forwards header field MAY be ignored for all other methods
+ defined by this specification and for any extension methods for which
+ it is not explicitly referred to as part of that method definition.
+
+14.32 Pragma
+
+ The Pragma general-header field is used to include implementation-
+ specific directives that might apply to any recipient along the
+ request/response chain. All pragma directives specify optional
+ behavior from the viewpoint of the protocol; however, some systems
+ MAY require that behavior be consistent with the directives.
+
+ Pragma = "Pragma" ":" 1#pragma-directive
+ pragma-directive = "no-cache" | extension-pragma
+ extension-pragma = token [ "=" ( token | quoted-string ) ]
+
+ When the no-cache directive is present in a request message, an
+ application SHOULD forward the request toward the origin server even
+ if it has a cached copy of what is being requested. This pragma
+ directive has the same semantics as the no-cache cache-directive (see
+ section 14.9) and is defined here for backward compatibility with
+ HTTP/1.0. Clients SHOULD include both header fields when a no-cache
+ request is sent to a server not known to be HTTP/1.1 compliant.
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 136]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Pragma directives MUST be passed through by a proxy or gateway
+ application, regardless of their significance to that application,
+ since the directives might be applicable to all recipients along the
+ request/response chain. It is not possible to specify a pragma for a
+ specific recipient; however, any pragma directive not relevant to a
+ recipient SHOULD be ignored by that recipient.
+
+ HTTP/1.1 caches SHOULD treat "Pragma: no-cache" as if the client had
+ sent "Cache-Control: no-cache". No new Pragma directives will be
+ defined in HTTP.
+
+ Note: because the meaning of "Pragma: no-cache as a response
+ header field is not actually specified, it does not provide a
+ reliable replacement for "Cache-Control: no-cache" in a response
+
+14.33 Proxy-Authenticate
+
+ The Proxy-Authenticate response-header field MUST be included as part
+ of a 407 (Proxy Authentication Required) response. The field value
+ consists of a challenge that indicates the authentication scheme and
+ parameters applicable to the proxy for this Request-URI.
+
+ Proxy-Authenticate = "Proxy-Authenticate" ":" 1#challenge
+
+ The HTTP access authentication process is described in "HTTP
+ Authentication: Basic and Digest Access Authentication" [43]. Unlike
+ WWW-Authenticate, the Proxy-Authenticate header field applies only to
+ the current connection and SHOULD NOT be passed on to downstream
+ clients. However, an intermediate proxy might need to obtain its own
+ credentials by requesting them from the downstream client, which in
+ some circumstances will appear as if the proxy is forwarding the
+ Proxy-Authenticate header field.
+
+14.34 Proxy-Authorization
+
+ The Proxy-Authorization request-header field allows the client to
+ identify itself (or its user) to a proxy which requires
+ authentication. The Proxy-Authorization field value consists of
+ credentials containing the authentication information of the user
+ agent for the proxy and/or realm of the resource being requested.
+
+ Proxy-Authorization = "Proxy-Authorization" ":" credentials
+
+ The HTTP access authentication process is described in "HTTP
+ Authentication: Basic and Digest Access Authentication" [43] . Unlike
+ Authorization, the Proxy-Authorization header field applies only to
+ the next outbound proxy that demanded authentication using the Proxy-
+ Authenticate field. When multiple proxies are used in a chain, the
+
+
+
+Fielding, et al. Standards Track [Page 137]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Proxy-Authorization header field is consumed by the first outbound
+ proxy that was expecting to receive credentials. A proxy MAY relay
+ the credentials from the client request to the next proxy if that is
+ the mechanism by which the proxies cooperatively authenticate a given
+ request.
+
+14.35 Range
+
+14.35.1 Byte Ranges
+
+ Since all HTTP entities are represented in HTTP messages as sequences
+ of bytes, the concept of a byte range is meaningful for any HTTP
+ entity. (However, not all clients and servers need to support byte-
+ range operations.)
+
+ Byte range specifications in HTTP apply to the sequence of bytes in
+ the entity-body (not necessarily the same as the message-body).
+
+ A byte range operation MAY specify a single range of bytes, or a set
+ of ranges within a single entity.
+
+ ranges-specifier = byte-ranges-specifier
+ byte-ranges-specifier = bytes-unit "=" byte-range-set
+ byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec )
+ byte-range-spec = first-byte-pos "-" [last-byte-pos]
+ first-byte-pos = 1*DIGIT
+ last-byte-pos = 1*DIGIT
+
+ The first-byte-pos value in a byte-range-spec gives the byte-offset
+ of the first byte in a range. The last-byte-pos value gives the
+ byte-offset of the last byte in the range; that is, the byte
+ positions specified are inclusive. Byte offsets start at zero.
+
+ If the last-byte-pos value is present, it MUST be greater than or
+ equal to the first-byte-pos in that byte-range-spec, or the byte-
+ range-spec is syntactically invalid. The recipient of a byte-range-
+ set that includes one or more syntactically invalid byte-range-spec
+ values MUST ignore the header field that includes that byte-range-
+ set.
+
+ If the last-byte-pos value is absent, or if the value is greater than
+ or equal to the current length of the entity-body, last-byte-pos is
+ taken to be equal to one less than the current length of the entity-
+ body in bytes.
+
+ By its choice of last-byte-pos, a client can limit the number of
+ bytes retrieved without knowing the size of the entity.
+
+
+
+
+Fielding, et al. Standards Track [Page 138]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ suffix-byte-range-spec = "-" suffix-length
+ suffix-length = 1*DIGIT
+
+ A suffix-byte-range-spec is used to specify the suffix of the
+ entity-body, of a length given by the suffix-length value. (That is,
+ this form specifies the last N bytes of an entity-body.) If the
+ entity is shorter than the specified suffix-length, the entire
+ entity-body is used.
+
+ If a syntactically valid byte-range-set includes at least one byte-
+ range-spec whose first-byte-pos is less than the current length of
+ the entity-body, or at least one suffix-byte-range-spec with a non-
+ zero suffix-length, then the byte-range-set is satisfiable.
+ Otherwise, the byte-range-set is unsatisfiable. If the byte-range-set
+ is unsatisfiable, the server SHOULD return a response with a status
+ of 416 (Requested range not satisfiable). Otherwise, the server
+ SHOULD return a response with a status of 206 (Partial Content)
+ containing the satisfiable ranges of the entity-body.
+
+ Examples of byte-ranges-specifier values (assuming an entity-body of
+ length 10000):
+
+ - The first 500 bytes (byte offsets 0-499, inclusive): bytes=0-
+ 499
+
+ - The second 500 bytes (byte offsets 500-999, inclusive):
+ bytes=500-999
+
+ - The final 500 bytes (byte offsets 9500-9999, inclusive):
+ bytes=-500
+
+ - Or bytes=9500-
+
+ - The first and last bytes only (bytes 0 and 9999): bytes=0-0,-1
+
+ - Several legal but not canonical specifications of the second 500
+ bytes (byte offsets 500-999, inclusive):
+ bytes=500-600,601-999
+ bytes=500-700,601-999
+
+14.35.2 Range Retrieval Requests
+
+ HTTP retrieval requests using conditional or unconditional GET
+ methods MAY request one or more sub-ranges of the entity, instead of
+ the entire entity, using the Range request header, which applies to
+ the entity returned as the result of the request:
+
+ Range = "Range" ":" ranges-specifier
+
+
+
+Fielding, et al. Standards Track [Page 139]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ A server MAY ignore the Range header. However, HTTP/1.1 origin
+ servers and intermediate caches ought to support byte ranges when
+ possible, since Range supports efficient recovery from partially
+ failed transfers, and supports efficient partial retrieval of large
+ entities.
+
+ If the server supports the Range header and the specified range or
+ ranges are appropriate for the entity:
+
+ - The presence of a Range header in an unconditional GET modifies
+ what is returned if the GET is otherwise successful. In other
+ words, the response carries a status code of 206 (Partial
+ Content) instead of 200 (OK).
+
+ - The presence of a Range header in a conditional GET (a request
+ using one or both of If-Modified-Since and If-None-Match, or
+ one or both of If-Unmodified-Since and If-Match) modifies what
+ is returned if the GET is otherwise successful and the
+ condition is true. It does not affect the 304 (Not Modified)
+ response returned if the conditional is false.
+
+ In some cases, it might be more appropriate to use the If-Range
+ header (see section 14.27) in addition to the Range header.
+
+ If a proxy that supports ranges receives a Range request, forwards
+ the request to an inbound server, and receives an entire entity in
+ reply, it SHOULD only return the requested range to its client. It
+ SHOULD store the entire received response in its cache if that is
+ consistent with its cache allocation policies.
+
+14.36 Referer
+
+ The Referer[sic] request-header field allows the client to specify,
+ for the server's benefit, the address (URI) of the resource from
+ which the Request-URI was obtained (the "referrer", although the
+ header field is misspelled.) The Referer request-header allows a
+ server to generate lists of back-links to resources for interest,
+ logging, optimized caching, etc. It also allows obsolete or mistyped
+ links to be traced for maintenance. The Referer field MUST NOT be
+ sent if the Request-URI was obtained from a source that does not have
+ its own URI, such as input from the user keyboard.
+
+ Referer = "Referer" ":" ( absoluteURI | relativeURI )
+
+ Example:
+
+ Referer: http://www.w3.org/hypertext/DataSources/Overview.html
+
+
+
+
+Fielding, et al. Standards Track [Page 140]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ If the field value is a relative URI, it SHOULD be interpreted
+ relative to the Request-URI. The URI MUST NOT include a fragment. See
+ section 15.1.3 for security considerations.
+
+14.37 Retry-After
+
+ The Retry-After response-header field can be used with a 503 (Service
+ Unavailable) response to indicate how long the service is expected to
+ be unavailable to the requesting client. This field MAY also be used
+ with any 3xx (Redirection) response to indicate the minimum time the
+ user-agent is asked wait before issuing the redirected request. The
+ value of this field can be either an HTTP-date or an integer number
+ of seconds (in decimal) after the time of the response.
+
+ Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds )
+
+ Two examples of its use are
+
+ Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
+ Retry-After: 120
+
+ In the latter example, the delay is 2 minutes.
+
+14.38 Server
+
+ The Server response-header field contains information about the
+ software used by the origin server to handle the request. The field
+ can contain multiple product tokens (section 3.8) and comments
+ identifying the server and any significant subproducts. The product
+ tokens are listed in order of their significance for identifying the
+ application.
+
+ Server = "Server" ":" 1*( product | comment )
+
+ Example:
+
+ Server: CERN/3.0 libwww/2.17
+
+ If the response is being forwarded through a proxy, the proxy
+ application MUST NOT modify the Server response-header. Instead, it
+ SHOULD include a Via field (as described in section 14.45).
+
+ Note: Revealing the specific software version of the server might
+ allow the server machine to become more vulnerable to attacks
+ against software that is known to contain security holes. Server
+ implementors are encouraged to make this field a configurable
+ option.
+
+
+
+
+Fielding, et al. Standards Track [Page 141]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+14.39 TE
+
+ The TE request-header field indicates what extension transfer-codings
+ it is willing to accept in the response and whether or not it is
+ willing to accept trailer fields in a chunked transfer-coding. Its
+ value may consist of the keyword "trailers" and/or a comma-separated
+ list of extension transfer-coding names with optional accept
+ parameters (as described in section 3.6).
+
+ TE = "TE" ":" #( t-codings )
+ t-codings = "trailers" | ( transfer-extension [ accept-params ] )
+
+ The presence of the keyword "trailers" indicates that the client is
+ willing to accept trailer fields in a chunked transfer-coding, as
+ defined in section 3.6.1. This keyword is reserved for use with
+ transfer-coding values even though it does not itself represent a
+ transfer-coding.
+
+ Examples of its use are:
+
+ TE: deflate
+ TE:
+ TE: trailers, deflate;q=0.5
+
+ The TE header field only applies to the immediate connection.
+ Therefore, the keyword MUST be supplied within a Connection header
+ field (section 14.10) whenever TE is present in an HTTP/1.1 message.
+
+ A server tests whether a transfer-coding is acceptable, according to
+ a TE field, using these rules:
+
+ 1. The "chunked" transfer-coding is always acceptable. If the
+ keyword "trailers" is listed, the client indicates that it is
+ willing to accept trailer fields in the chunked response on
+ behalf of itself and any downstream clients. The implication is
+ that, if given, the client is stating that either all
+ downstream clients are willing to accept trailer fields in the
+ forwarded response, or that it will attempt to buffer the
+ response on behalf of downstream recipients.
+
+ Note: HTTP/1.1 does not define any means to limit the size of a
+ chunked response such that a client can be assured of buffering
+ the entire response.
+
+ 2. If the transfer-coding being tested is one of the transfer-
+ codings listed in the TE field, then it is acceptable unless it
+ is accompanied by a qvalue of 0. (As defined in section 3.9, a
+ qvalue of 0 means "not acceptable.")
+
+
+
+Fielding, et al. Standards Track [Page 142]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 3. If multiple transfer-codings are acceptable, then the
+ acceptable transfer-coding with the highest non-zero qvalue is
+ preferred. The "chunked" transfer-coding always has a qvalue
+ of 1.
+
+ If the TE field-value is empty or if no TE field is present, the only
+ transfer-coding is "chunked". A message with no transfer-coding is
+ always acceptable.
+
+14.40 Trailer
+
+ The Trailer general field value indicates that the given set of
+ header fields is present in the trailer of a message encoded with
+ chunked transfer-coding.
+
+ Trailer = "Trailer" ":" 1#field-name
+
+ An HTTP/1.1 message SHOULD include a Trailer header field in a
+ message using chunked transfer-coding with a non-empty trailer. Doing
+ so allows the recipient to know which header fields to expect in the
+ trailer.
+
+ If no Trailer header field is present, the trailer SHOULD NOT include
+ any header fields. See section 3.6.1 for restrictions on the use of
+ trailer fields in a "chunked" transfer-coding.
+
+ Message header fields listed in the Trailer header field MUST NOT
+ include the following header fields:
+
+ . Transfer-Encoding
+
+ . Content-Length
+
+ . Trailer
+
+14.41 Transfer-Encoding
+
+ The Transfer-Encoding general-header field indicates what (if any)
+ type of transformation has been applied to the message body in order
+ to safely transfer it between the sender and the recipient. This
+ differs from the content-coding in that the transfer-coding is a
+ property of the message, not of the entity.
+
+ Transfer-Encoding = "Transfer-Encoding" ":" 1#transfer-coding
+
+ Transfer-codings are defined in section 3.6. An example is:
+
+ Transfer-Encoding: chunked
+
+
+
+Fielding, et al. Standards Track [Page 143]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ If multiple encodings have been applied to an entity, the transfer-
+ codings MUST be listed in the order in which they were applied.
+ Additional information about the encoding parameters MAY be provided
+ by other entity-header fields not defined by this specification.
+
+ Many older HTTP/1.0 applications do not understand the Transfer-
+ Encoding header.
+
+14.42 Upgrade
+
+ The Upgrade general-header allows the client to specify what
+ additional communication protocols it supports and would like to use
+ if the server finds it appropriate to switch protocols. The server
+ MUST use the Upgrade header field within a 101 (Switching Protocols)
+ response to indicate which protocol(s) are being switched.
+
+ Upgrade = "Upgrade" ":" 1#product
+
+ For example,
+
+ Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
+
+ The Upgrade header field is intended to provide a simple mechanism
+ for transition from HTTP/1.1 to some other, incompatible protocol. It
+ does so by allowing the client to advertise its desire to use another
+ protocol, such as a later version of HTTP with a higher major version
+ number, even though the current request has been made using HTTP/1.1.
+ This eases the difficult transition between incompatible protocols by
+ allowing the client to initiate a request in the more commonly
+ supported protocol while indicating to the server that it would like
+ to use a "better" protocol if available (where "better" is determined
+ by the server, possibly according to the nature of the method and/or
+ resource being requested).
+
+ The Upgrade header field only applies to switching application-layer
+ protocols upon the existing transport-layer connection. Upgrade
+ cannot be used to insist on a protocol change; its acceptance and use
+ by the server is optional. The capabilities and nature of the
+ application-layer communication after the protocol change is entirely
+ dependent upon the new protocol chosen, although the first action
+ after changing the protocol MUST be a response to the initial HTTP
+ request containing the Upgrade header field.
+
+ The Upgrade header field only applies to the immediate connection.
+ Therefore, the upgrade keyword MUST be supplied within a Connection
+ header field (section 14.10) whenever Upgrade is present in an
+ HTTP/1.1 message.
+
+
+
+
+Fielding, et al. Standards Track [Page 144]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ The Upgrade header field cannot be used to indicate a switch to a
+ protocol on a different connection. For that purpose, it is more
+ appropriate to use a 301, 302, 303, or 305 redirection response.
+
+ This specification only defines the protocol name "HTTP" for use by
+ the family of Hypertext Transfer Protocols, as defined by the HTTP
+ version rules of section 3.1 and future updates to this
+ specification. Any token can be used as a protocol name; however, it
+ will only be useful if both the client and server associate the name
+ with the same protocol.
+
+14.43 User-Agent
+
+ The User-Agent request-header field contains information about the
+ user agent originating the request. This is for statistical purposes,
+ the tracing of protocol violations, and automated recognition of user
+ agents for the sake of tailoring responses to avoid particular user
+ agent limitations. User agents SHOULD include this field with
+ requests. The field can contain multiple product tokens (section 3.8)
+ and comments identifying the agent and any subproducts which form a
+ significant part of the user agent. By convention, the product tokens
+ are listed in order of their significance for identifying the
+ application.
+
+ User-Agent = "User-Agent" ":" 1*( product | comment )
+
+ Example:
+
+ User-Agent: CERN-LineMode/2.15 libwww/2.17b3
+
+14.44 Vary
+
+ The Vary field value indicates the set of request-header fields that
+ fully determines, while the response is fresh, whether a cache is
+ permitted to use the response to reply to a subsequent request
+ without revalidation. For uncacheable or stale responses, the Vary
+ field value advises the user agent about the criteria that were used
+ to select the representation. A Vary field value of "*" implies that
+ a cache cannot determine from the request headers of a subsequent
+ request whether this response is the appropriate representation. See
+ section 13.6 for use of the Vary header field by caches.
+
+ Vary = "Vary" ":" ( "*" | 1#field-name )
+
+ An HTTP/1.1 server SHOULD include a Vary header field with any
+ cacheable response that is subject to server-driven negotiation.
+ Doing so allows a cache to properly interpret future requests on that
+ resource and informs the user agent about the presence of negotiation
+
+
+
+Fielding, et al. Standards Track [Page 145]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ on that resource. A server MAY include a Vary header field with a
+ non-cacheable response that is subject to server-driven negotiation,
+ since this might provide the user agent with useful information about
+ the dimensions over which the response varies at the time of the
+ response.
+
+ A Vary field value consisting of a list of field-names signals that
+ the representation selected for the response is based on a selection
+ algorithm which considers ONLY the listed request-header field values
+ in selecting the most appropriate representation. A cache MAY assume
+ that the same selection will be made for future requests with the
+ same values for the listed field names, for the duration of time for
+ which the response is fresh.
+
+ The field-names given are not limited to the set of standard
+ request-header fields defined by this specification. Field names are
+ case-insensitive.
+
+ A Vary field value of "*" signals that unspecified parameters not
+ limited to the request-headers (e.g., the network address of the
+ client), play a role in the selection of the response representation.
+ The "*" value MUST NOT be generated by a proxy server; it may only be
+ generated by an origin server.
+
+14.45 Via
+
+ The Via general-header field MUST be used by gateways and proxies to
+ indicate the intermediate protocols and recipients between the user
+ agent and the server on requests, and between the origin server and
+ the client on responses. It is analogous to the "Received" field of
+ RFC 822 [9] and is intended to be used for tracking message forwards,
+ avoiding request loops, and identifying the protocol capabilities of
+ all senders along the request/response chain.
+
+ Via = "Via" ":" 1#( received-protocol received-by [ comment ] )
+ received-protocol = [ protocol-name "/" ] protocol-version
+ protocol-name = token
+ protocol-version = token
+ received-by = ( host [ ":" port ] ) | pseudonym
+ pseudonym = token
+
+ The received-protocol indicates the protocol version of the message
+ received by the server or client along each segment of the
+ request/response chain. The received-protocol version is appended to
+ the Via field value when the message is forwarded so that information
+ about the protocol capabilities of upstream applications remains
+ visible to all recipients.
+
+
+
+
+Fielding, et al. Standards Track [Page 146]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ The protocol-name is optional if and only if it would be "HTTP". The
+ received-by field is normally the host and optional port number of a
+ recipient server or client that subsequently forwarded the message.
+ However, if the real host is considered to be sensitive information,
+ it MAY be replaced by a pseudonym. If the port is not given, it MAY
+ be assumed to be the default port of the received-protocol.
+
+ Multiple Via field values represents each proxy or gateway that has
+ forwarded the message. Each recipient MUST append its information
+ such that the end result is ordered according to the sequence of
+ forwarding applications.
+
+ Comments MAY be used in the Via header field to identify the software
+ of the recipient proxy or gateway, analogous to the User-Agent and
+ Server header fields. However, all comments in the Via field are
+ optional and MAY be removed by any recipient prior to forwarding the
+ message.
+
+ For example, a request message could be sent from an HTTP/1.0 user
+ agent to an internal proxy code-named "fred", which uses HTTP/1.1 to
+ forward the request to a public proxy at nowhere.com, which completes
+ the request by forwarding it to the origin server at www.ics.uci.edu.
+ The request received by www.ics.uci.edu would then have the following
+ Via header field:
+
+ Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
+
+ Proxies and gateways used as a portal through a network firewall
+ SHOULD NOT, by default, forward the names and ports of hosts within
+ the firewall region. This information SHOULD only be propagated if
+ explicitly enabled. If not enabled, the received-by host of any host
+ behind the firewall SHOULD be replaced by an appropriate pseudonym
+ for that host.
+
+ For organizations that have strong privacy requirements for hiding
+ internal structures, a proxy MAY combine an ordered subsequence of
+ Via header field entries with identical received-protocol values into
+ a single such entry. For example,
+
+ Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy
+
+ could be collapsed to
+
+ Via: 1.0 ricky, 1.1 mertz, 1.0 lucy
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 147]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Applications SHOULD NOT combine multiple entries unless they are all
+ under the same organizational control and the hosts have already been
+ replaced by pseudonyms. Applications MUST NOT combine entries which
+ have different received-protocol values.
+
+14.46 Warning
+
+ The Warning general-header field is used to carry additional
+ information about the status or transformation of a message which
+ might not be reflected in the message. This information is typically
+ used to warn about a possible lack of semantic transparency from
+ caching operations or transformations applied to the entity body of
+ the message.
+
+ Warning headers are sent with responses using:
+
+ Warning = "Warning" ":" 1#warning-value
+
+ warning-value = warn-code SP warn-agent SP warn-text
+ [SP warn-date]
+
+ warn-code = 3DIGIT
+ warn-agent = ( host [ ":" port ] ) | pseudonym
+ ; the name or pseudonym of the server adding
+ ; the Warning header, for use in debugging
+ warn-text = quoted-string
+ warn-date = <"> HTTP-date <">
+
+ A response MAY carry more than one Warning header.
+
+ The warn-text SHOULD be in a natural language and character set that
+ is most likely to be intelligible to the human user receiving the
+ response. This decision MAY be based on any available knowledge, such
+ as the location of the cache or user, the Accept-Language field in a
+ request, the Content-Language field in a response, etc. The default
+ language is English and the default character set is ISO-8859-1.
+
+ If a character set other than ISO-8859-1 is used, it MUST be encoded
+ in the warn-text using the method described in RFC 2047 [14].
+
+ Warning headers can in general be applied to any message, however
+ some specific warn-codes are specific to caches and can only be
+ applied to response messages. New Warning headers SHOULD be added
+ after any existing Warning headers. A cache MUST NOT delete any
+ Warning header that it received with a message. However, if a cache
+ successfully validates a cache entry, it SHOULD remove any Warning
+ headers previously attached to that entry except as specified for
+
+
+
+
+Fielding, et al. Standards Track [Page 148]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ specific Warning codes. It MUST then add any Warning headers received
+ in the validating response. In other words, Warning headers are those
+ that would be attached to the most recent relevant response.
+
+ When multiple Warning headers are attached to a response, the user
+ agent ought to inform the user of as many of them as possible, in the
+ order that they appear in the response. If it is not possible to
+ inform the user of all of the warnings, the user agent SHOULD follow
+ these heuristics:
+
+ - Warnings that appear early in the response take priority over
+ those appearing later in the response.
+
+ - Warnings in the user's preferred character set take priority
+ over warnings in other character sets but with identical warn-
+ codes and warn-agents.
+
+ Systems that generate multiple Warning headers SHOULD order them with
+ this user agent behavior in mind.
+
+ Requirements for the behavior of caches with respect to Warnings are
+ stated in section 13.1.2.
+
+ This is a list of the currently-defined warn-codes, each with a
+ recommended warn-text in English, and a description of its meaning.
+
+ 110 Response is stale
+ MUST be included whenever the returned response is stale.
+
+ 111 Revalidation failed
+ MUST be included if a cache returns a stale response because an
+ attempt to revalidate the response failed, due to an inability to
+ reach the server.
+
+ 112 Disconnected operation
+ SHOULD be included if the cache is intentionally disconnected from
+ the rest of the network for a period of time.
+
+ 113 Heuristic expiration
+ MUST be included if the cache heuristically chose a freshness
+ lifetime greater than 24 hours and the response's age is greater
+ than 24 hours.
+
+ 199 Miscellaneous warning
+ The warning text MAY include arbitrary information to be presented
+ to a human user, or logged. A system receiving this warning MUST
+ NOT take any automated action, besides presenting the warning to
+ the user.
+
+
+
+Fielding, et al. Standards Track [Page 149]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 214 Transformation applied
+ MUST be added by an intermediate cache or proxy if it applies any
+ transformation changing the content-coding (as specified in the
+ Content-Encoding header) or media-type (as specified in the
+ Content-Type header) of the response, or the entity-body of the
+ response, unless this Warning code already appears in the response.
+
+ 299 Miscellaneous persistent warning
+ The warning text MAY include arbitrary information to be presented
+ to a human user, or logged. A system receiving this warning MUST
+ NOT take any automated action.
+
+ If an implementation sends a message with one or more Warning headers
+ whose version is HTTP/1.0 or lower, then the sender MUST include in
+ each warning-value a warn-date that matches the date in the response.
+
+ If an implementation receives a message with a warning-value that
+ includes a warn-date, and that warn-date is different from the Date
+ value in the response, then that warning-value MUST be deleted from
+ the message before storing, forwarding, or using it. (This prevents
+ bad consequences of naive caching of Warning header fields.) If all
+ of the warning-values are deleted for this reason, the Warning header
+ MUST be deleted as well.
+
+14.47 WWW-Authenticate
+
+ The WWW-Authenticate response-header field MUST be included in 401
+ (Unauthorized) response messages. The field value consists of at
+ least one challenge that indicates the authentication scheme(s) and
+ parameters applicable to the Request-URI.
+
+ WWW-Authenticate = "WWW-Authenticate" ":" 1#challenge
+
+ The HTTP access authentication process is described in "HTTP
+ Authentication: Basic and Digest Access Authentication" [43]. User
+ agents are advised to take special care in parsing the WWW-
+ Authenticate field value as it might contain more than one challenge,
+ or if more than one WWW-Authenticate header field is provided, the
+ contents of a challenge itself can contain a comma-separated list of
+ authentication parameters.
+
+15 Security Considerations
+
+ This section is meant to inform application developers, information
+ providers, and users of the security limitations in HTTP/1.1 as
+ described by this document. The discussion does not include
+ definitive solutions to the problems revealed, though it does make
+ some suggestions for reducing security risks.
+
+
+
+Fielding, et al. Standards Track [Page 150]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+15.1 Personal Information
+
+ HTTP clients are often privy to large amounts of personal information
+ (e.g. the user's name, location, mail address, passwords, encryption
+ keys, etc.), and SHOULD be very careful to prevent unintentional
+ leakage of this information via the HTTP protocol to other sources.
+ We very strongly recommend that a convenient interface be provided
+ for the user to control dissemination of such information, and that
+ designers and implementors be particularly careful in this area.
+ History shows that errors in this area often create serious security
+ and/or privacy problems and generate highly adverse publicity for the
+ implementor's company.
+
+15.1.1 Abuse of Server Log Information
+
+ A server is in the position to save personal data about a user's
+ requests which might identify their reading patterns or subjects of
+ interest. This information is clearly confidential in nature and its
+ handling can be constrained by law in certain countries. People using
+ the HTTP protocol to provide data are responsible for ensuring that
+ such material is not distributed without the permission of any
+ individuals that are identifiable by the published results.
+
+15.1.2 Transfer of Sensitive Information
+
+ Like any generic data transfer protocol, HTTP cannot regulate the
+ content of the data that is transferred, nor is there any a priori
+ method of determining the sensitivity of any particular piece of
+ information within the context of any given request. Therefore,
+ applications SHOULD supply as much control over this information as
+ possible to the provider of that information. Four header fields are
+ worth special mention in this context: Server, Via, Referer and From.
+
+ Revealing the specific software version of the server might allow the
+ server machine to become more vulnerable to attacks against software
+ that is known to contain security holes. Implementors SHOULD make the
+ Server header field a configurable option.
+
+ Proxies which serve as a portal through a network firewall SHOULD
+ take special precautions regarding the transfer of header information
+ that identifies the hosts behind the firewall. In particular, they
+ SHOULD remove, or replace with sanitized versions, any Via fields
+ generated behind the firewall.
+
+ The Referer header allows reading patterns to be studied and reverse
+ links drawn. Although it can be very useful, its power can be abused
+ if user details are not separated from the information contained in
+
+
+
+
+Fielding, et al. Standards Track [Page 151]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ the Referer. Even when the personal information has been removed, the
+ Referer header might indicate a private document's URI whose
+ publication would be inappropriate.
+
+ The information sent in the From field might conflict with the user's
+ privacy interests or their site's security policy, and hence it
+ SHOULD NOT be transmitted without the user being able to disable,
+ enable, and modify the contents of the field. The user MUST be able
+ to set the contents of this field within a user preference or
+ application defaults configuration.
+
+ We suggest, though do not require, that a convenient toggle interface
+ be provided for the user to enable or disable the sending of From and
+ Referer information.
+
+ The User-Agent (section 14.43) or Server (section 14.38) header
+ fields can sometimes be used to determine that a specific client or
+ server have a particular security hole which might be exploited.
+ Unfortunately, this same information is often used for other valuable
+ purposes for which HTTP currently has no better mechanism.
+
+15.1.3 Encoding Sensitive Information in URI's
+
+ Because the source of a link might be private information or might
+ reveal an otherwise private information source, it is strongly
+ recommended that the user be able to select whether or not the
+ Referer field is sent. For example, a browser client could have a
+ toggle switch for browsing openly/anonymously, which would
+ respectively enable/disable the sending of Referer and From
+ information.
+
+ Clients SHOULD NOT include a Referer header field in a (non-secure)
+ HTTP request if the referring page was transferred with a secure
+ protocol.
+
+ Authors of services which use the HTTP protocol SHOULD NOT use GET
+ based forms for the submission of sensitive data, because this will
+ cause this data to be encoded in the Request-URI. Many existing
+ servers, proxies, and user agents will log the request URI in some
+ place where it might be visible to third parties. Servers can use
+ POST-based form submission instead
+
+15.1.4 Privacy Issues Connected to Accept Headers
+
+ Accept request-headers can reveal information about the user to all
+ servers which are accessed. The Accept-Language header in particular
+ can reveal information the user would consider to be of a private
+ nature, because the understanding of particular languages is often
+
+
+
+Fielding, et al. Standards Track [Page 152]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ strongly correlated to the membership of a particular ethnic group.
+ User agents which offer the option to configure the contents of an
+ Accept-Language header to be sent in every request are strongly
+ encouraged to let the configuration process include a message which
+ makes the user aware of the loss of privacy involved.
+
+ An approach that limits the loss of privacy would be for a user agent
+ to omit the sending of Accept-Language headers by default, and to ask
+ the user whether or not to start sending Accept-Language headers to a
+ server if it detects, by looking for any Vary response-header fields
+ generated by the server, that such sending could improve the quality
+ of service.
+
+ Elaborate user-customized accept header fields sent in every request,
+ in particular if these include quality values, can be used by servers
+ as relatively reliable and long-lived user identifiers. Such user
+ identifiers would allow content providers to do click-trail tracking,
+ and would allow collaborating content providers to match cross-server
+ click-trails or form submissions of individual users. Note that for
+ many users not behind a proxy, the network address of the host
+ running the user agent will also serve as a long-lived user
+ identifier. In environments where proxies are used to enhance
+ privacy, user agents ought to be conservative in offering accept
+ header configuration options to end users. As an extreme privacy
+ measure, proxies could filter the accept headers in relayed requests.
+ General purpose user agents which provide a high degree of header
+ configurability SHOULD warn users about the loss of privacy which can
+ be involved.
+
+15.2 Attacks Based On File and Path Names
+
+ Implementations of HTTP origin servers SHOULD be careful to restrict
+ the documents returned by HTTP requests to be only those that were
+ intended by the server administrators. If an HTTP server translates
+ HTTP URIs directly into file system calls, the server MUST take
+ special care not to serve files that were not intended to be
+ delivered to HTTP clients. For example, UNIX, Microsoft Windows, and
+ other operating systems use ".." as a path component to indicate a
+ directory level above the current one. On such a system, an HTTP
+ server MUST disallow any such construct in the Request-URI if it
+ would otherwise allow access to a resource outside those intended to
+ be accessible via the HTTP server. Similarly, files intended for
+ reference only internally to the server (such as access control
+ files, configuration files, and script code) MUST be protected from
+ inappropriate retrieval, since they might contain sensitive
+ information. Experience has shown that minor bugs in such HTTP server
+ implementations have turned into security risks.
+
+
+
+
+Fielding, et al. Standards Track [Page 153]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+15.3 DNS Spoofing
+
+ Clients using HTTP rely heavily on the Domain Name Service, and are
+ thus generally prone to security attacks based on the deliberate
+ mis-association of IP addresses and DNS names. Clients need to be
+ cautious in assuming the continuing validity of an IP number/DNS name
+ association.
+
+ In particular, HTTP clients SHOULD rely on their name resolver for
+ confirmation of an IP number/DNS name association, rather than
+ caching the result of previous host name lookups. Many platforms
+ already can cache host name lookups locally when appropriate, and
+ they SHOULD be configured to do so. It is proper for these lookups to
+ be cached, however, only when the TTL (Time To Live) information
+ reported by the name server makes it likely that the cached
+ information will remain useful.
+
+ If HTTP clients cache the results of host name lookups in order to
+ achieve a performance improvement, they MUST observe the TTL
+ information reported by DNS.
+
+ If HTTP clients do not observe this rule, they could be spoofed when
+ a previously-accessed server's IP address changes. As network
+ renumbering is expected to become increasingly common [24], the
+ possibility of this form of attack will grow. Observing this
+ requirement thus reduces this potential security vulnerability.
+
+ This requirement also improves the load-balancing behavior of clients
+ for replicated servers using the same DNS name and reduces the
+ likelihood of a user's experiencing failure in accessing sites which
+ use that strategy.
+
+15.4 Location Headers and Spoofing
+
+ If a single server supports multiple organizations that do not trust
+ one another, then it MUST check the values of Location and Content-
+ Location headers in responses that are generated under control of
+ said organizations to make sure that they do not attempt to
+ invalidate resources over which they have no authority.
+
+15.5 Content-Disposition Issues
+
+ RFC 1806 [35], from which the often implemented Content-Disposition
+ (see section 19.5.1) header in HTTP is derived, has a number of very
+ serious security considerations. Content-Disposition is not part of
+ the HTTP standard, but since it is widely implemented, we are
+ documenting its use and risks for implementors. See RFC 2183 [49]
+ (which updates RFC 1806) for details.
+
+
+
+Fielding, et al. Standards Track [Page 154]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+15.6 Authentication Credentials and Idle Clients
+
+ Existing HTTP clients and user agents typically retain authentication
+ information indefinitely. HTTP/1.1. does not provide a method for a
+ server to direct clients to discard these cached credentials. This is
+ a significant defect that requires further extensions to HTTP.
+ Circumstances under which credential caching can interfere with the
+ application's security model include but are not limited to:
+
+ - Clients which have been idle for an extended period following
+ which the server might wish to cause the client to reprompt the
+ user for credentials.
+
+ - Applications which include a session termination indication
+ (such as a `logout' or `commit' button on a page) after which
+ the server side of the application `knows' that there is no
+ further reason for the client to retain the credentials.
+
+ This is currently under separate study. There are a number of work-
+ arounds to parts of this problem, and we encourage the use of
+ password protection in screen savers, idle time-outs, and other
+ methods which mitigate the security problems inherent in this
+ problem. In particular, user agents which cache credentials are
+ encouraged to provide a readily accessible mechanism for discarding
+ cached credentials under user control.
+
+15.7 Proxies and Caching
+
+ By their very nature, HTTP proxies are men-in-the-middle, and
+ represent an opportunity for man-in-the-middle attacks. Compromise of
+ the systems on which the proxies run can result in serious security
+ and privacy problems. Proxies have access to security-related
+ information, personal information about individual users and
+ organizations, and proprietary information belonging to users and
+ content providers. A compromised proxy, or a proxy implemented or
+ configured without regard to security and privacy considerations,
+ might be used in the commission of a wide range of potential attacks.
+
+ Proxy operators should protect the systems on which proxies run as
+ they would protect any system that contains or transports sensitive
+ information. In particular, log information gathered at proxies often
+ contains highly sensitive personal information, and/or information
+ about organizations. Log information should be carefully guarded, and
+ appropriate guidelines for use developed and followed. (Section
+ 15.1.1).
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 155]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Caching proxies provide additional potential vulnerabilities, since
+ the contents of the cache represent an attractive target for
+ malicious exploitation. Because cache contents persist after an HTTP
+ request is complete, an attack on the cache can reveal information
+ long after a user believes that the information has been removed from
+ the network. Therefore, cache contents should be protected as
+ sensitive information.
+
+ Proxy implementors should consider the privacy and security
+ implications of their design and coding decisions, and of the
+ configuration options they provide to proxy operators (especially the
+ default configuration).
+
+ Users of a proxy need to be aware that they are no trustworthier than
+ the people who run the proxy; HTTP itself cannot solve this problem.
+
+ The judicious use of cryptography, when appropriate, may suffice to
+ protect against a broad range of security and privacy attacks. Such
+ cryptography is beyond the scope of the HTTP/1.1 specification.
+
+15.7.1 Denial of Service Attacks on Proxies
+
+ They exist. They are hard to defend against. Research continues.
+ Beware.
+
+16 Acknowledgments
+
+ This specification makes heavy use of the augmented BNF and generic
+ constructs defined by David H. Crocker for RFC 822 [9]. Similarly, it
+ reuses many of the definitions provided by Nathaniel Borenstein and
+ Ned Freed for MIME [7]. We hope that their inclusion in this
+ specification will help reduce past confusion over the relationship
+ between HTTP and Internet mail message formats.
+
+ The HTTP protocol has evolved considerably over the years. It has
+ benefited from a large and active developer community--the many
+ people who have participated on the www-talk mailing list--and it is
+ that community which has been most responsible for the success of
+ HTTP and of the World-Wide Web in general. Marc Andreessen, Robert
+ Cailliau, Daniel W. Connolly, Bob Denny, John Franks, Jean-Francois
+ Groff, Phillip M. Hallam-Baker, Hakon W. Lie, Ari Luotonen, Rob
+ McCool, Lou Montulli, Dave Raggett, Tony Sanders, and Marc
+ VanHeyningen deserve special recognition for their efforts in
+ defining early aspects of the protocol.
+
+ This document has benefited greatly from the comments of all those
+ participating in the HTTP-WG. In addition to those already mentioned,
+ the following individuals have contributed to this specification:
+
+
+
+Fielding, et al. Standards Track [Page 156]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Gary Adams Ross Patterson
+ Harald Tveit Alvestrand Albert Lunde
+ Keith Ball John C. Mallery
+ Brian Behlendorf Jean-Philippe Martin-Flatin
+ Paul Burchard Mitra
+ Maurizio Codogno David Morris
+ Mike Cowlishaw Gavin Nicol
+ Roman Czyborra Bill Perry
+ Michael A. Dolan Jeffrey Perry
+ David J. Fiander Scott Powers
+ Alan Freier Owen Rees
+ Marc Hedlund Luigi Rizzo
+ Greg Herlihy David Robinson
+ Koen Holtman Marc Salomon
+ Alex Hopmann Rich Salz
+ Bob Jernigan Allan M. Schiffman
+ Shel Kaphan Jim Seidman
+ Rohit Khare Chuck Shotton
+ John Klensin Eric W. Sink
+ Martijn Koster Simon E. Spero
+ Alexei Kosut Richard N. Taylor
+ David M. Kristol Robert S. Thau
+ Daniel LaLiberte Bill (BearHeart) Weinman
+ Ben Laurie Francois Yergeau
+ Paul J. Leach Mary Ellen Zurko
+ Daniel DuBois Josh Cohen
+
+
+ Much of the content and presentation of the caching design is due to
+ suggestions and comments from individuals including: Shel Kaphan,
+ Paul Leach, Koen Holtman, David Morris, and Larry Masinter.
+
+ Most of the specification of ranges is based on work originally done
+ by Ari Luotonen and John Franks, with additional input from Steve
+ Zilles.
+
+ Thanks to the "cave men" of Palo Alto. You know who you are.
+
+ Jim Gettys (the current editor of this document) wishes particularly
+ to thank Roy Fielding, the previous editor of this document, along
+ with John Klensin, Jeff Mogul, Paul Leach, Dave Kristol, Koen
+ Holtman, John Franks, Josh Cohen, Alex Hopmann, Scott Lawrence, and
+ Larry Masinter for their help. And thanks go particularly to Jeff
+ Mogul and Scott Lawrence for performing the "MUST/MAY/SHOULD" audit.
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 157]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ The Apache Group, Anselm Baird-Smith, author of Jigsaw, and Henrik
+ Frystyk implemented RFC 2068 early, and we wish to thank them for the
+ discovery of many of the problems that this document attempts to
+ rectify.
+
+17 References
+
+ [1] Alvestrand, H., "Tags for the Identification of Languages", RFC
+ 1766, March 1995.
+
+ [2] Anklesaria, F., McCahill, M., Lindner, P., Johnson, D., Torrey,
+ D. and B. Alberti, "The Internet Gopher Protocol (a distributed
+ document search and retrieval protocol)", RFC 1436, March 1993.
+
+ [3] Berners-Lee, T., "Universal Resource Identifiers in WWW", RFC
+ 1630, June 1994.
+
+ [4] Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform Resource
+ Locators (URL)", RFC 1738, December 1994.
+
+ [5] Berners-Lee, T. and D. Connolly, "Hypertext Markup Language -
+ 2.0", RFC 1866, November 1995.
+
+ [6] Berners-Lee, T., Fielding, R. and H. Frystyk, "Hypertext Transfer
+ Protocol -- HTTP/1.0", RFC 1945, May 1996.
+
+ [7] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part One: Format of Internet Message Bodies",
+ RFC 2045, November 1996.
+
+ [8] Braden, R., "Requirements for Internet Hosts -- Communication
+ Layers", STD 3, RFC 1123, October 1989.
+
+ [9] Crocker, D., "Standard for The Format of ARPA Internet Text
+ Messages", STD 11, RFC 822, August 1982.
+
+ [10] Davis, F., Kahle, B., Morris, H., Salem, J., Shen, T., Wang, R.,
+ Sui, J., and M. Grinbaum, "WAIS Interface Protocol Prototype
+ Functional Specification," (v1.5), Thinking Machines
+ Corporation, April 1990.
+
+ [11] Fielding, R., "Relative Uniform Resource Locators", RFC 1808,
+ June 1995.
+
+ [12] Horton, M. and R. Adams, "Standard for Interchange of USENET
+ Messages", RFC 1036, December 1987.
+
+
+
+
+
+Fielding, et al. Standards Track [Page 158]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ [13] Kantor, B. and P. Lapsley, "Network News Transfer Protocol", RFC
+ 977, February 1986.
+
+ [14] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part
+ Three: Message Header Extensions for Non-ASCII Text", RFC 2047,
+ November 1996.
+
+ [15] Nebel, E. and L. Masinter, "Form-based File Upload in HTML", RFC
+ 1867, November 1995.
+
+ [16] Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC 821,
+ August 1982.
+
+ [17] Postel, J., "Media Type Registration Procedure", RFC 1590,
+ November 1996.
+
+ [18] Postel, J. and J. Reynolds, "File Transfer Protocol", STD 9, RFC
+ 959, October 1985.
+
+ [19] Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC 1700,
+ October 1994.
+
+ [20] Sollins, K. and L. Masinter, "Functional Requirements for
+ Uniform Resource Names", RFC 1737, December 1994.
+
+ [21] US-ASCII. Coded Character Set - 7-Bit American Standard Code for
+ Information Interchange. Standard ANSI X3.4-1986, ANSI, 1986.
+
+ [22] ISO-8859. International Standard -- Information Processing --
+ 8-bit Single-Byte Coded Graphic Character Sets --
+ Part 1: Latin alphabet No. 1, ISO-8859-1:1987.
+ Part 2: Latin alphabet No. 2, ISO-8859-2, 1987.
+ Part 3: Latin alphabet No. 3, ISO-8859-3, 1988.
+ Part 4: Latin alphabet No. 4, ISO-8859-4, 1988.
+ Part 5: Latin/Cyrillic alphabet, ISO-8859-5, 1988.
+ Part 6: Latin/Arabic alphabet, ISO-8859-6, 1987.
+ Part 7: Latin/Greek alphabet, ISO-8859-7, 1987.
+ Part 8: Latin/Hebrew alphabet, ISO-8859-8, 1988.
+ Part 9: Latin alphabet No. 5, ISO-8859-9, 1990.
+
+ [23] Meyers, J. and M. Rose, "The Content-MD5 Header Field", RFC
+ 1864, October 1995.
+
+ [24] Carpenter, B. and Y. Rekhter, "Renumbering Needs Work", RFC
+ 1900, February 1996.
+
+ [25] Deutsch, P., "GZIP file format specification version 4.3", RFC
+ 1952, May 1996.
+
+
+
+Fielding, et al. Standards Track [Page 159]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ [26] Venkata N. Padmanabhan, and Jeffrey C. Mogul. "Improving HTTP
+ Latency", Computer Networks and ISDN Systems, v. 28, pp. 25-35,
+ Dec. 1995. Slightly revised version of paper in Proc. 2nd
+ International WWW Conference '94: Mosaic and the Web, Oct. 1994,
+ which is available at
+ http://www.ncsa.uiuc.edu/SDG/IT94/Proceedings/DDay/mogul/HTTPLat
+ ency.html.
+
+ [27] Joe Touch, John Heidemann, and Katia Obraczka. "Analysis of HTTP
+ Performance", <URL: http://www.isi.edu/touch/pubs/http-perf96/>,
+ ISI Research Report ISI/RR-98-463, (original report dated Aug.
+ 1996), USC/Information Sciences Institute, August 1998.
+
+ [28] Mills, D., "Network Time Protocol (Version 3) Specification,
+ Implementation and Analysis", RFC 1305, March 1992.
+
+ [29] Deutsch, P., "DEFLATE Compressed Data Format Specification
+ version 1.3", RFC 1951, May 1996.
+
+ [30] S. Spero, "Analysis of HTTP Performance Problems,"
+ http://sunsite.unc.edu/mdma-release/http-prob.html.
+
+ [31] Deutsch, P. and J. Gailly, "ZLIB Compressed Data Format
+ Specification version 3.3", RFC 1950, May 1996.
+
+ [32] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P.,
+ Luotonen, A., Sink, E. and L. Stewart, "An Extension to HTTP:
+ Digest Access Authentication", RFC 2069, January 1997.
+
+ [33] Fielding, R., Gettys, J., Mogul, J., Frystyk, H. and T.
+ Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC
+ 2068, January 1997.
+
+ [34] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [35] Troost, R. and Dorner, S., "Communicating Presentation
+ Information in Internet Messages: The Content-Disposition
+ Header", RFC 1806, June 1995.
+
+ [36] Mogul, J., Fielding, R., Gettys, J. and H. Frystyk, "Use and
+ Interpretation of HTTP Version Numbers", RFC 2145, May 1997.
+ [jg639]
+
+ [37] Palme, J., "Common Internet Message Headers", RFC 2076, February
+ 1997. [jg640]
+
+
+
+
+
+Fielding, et al. Standards Track [Page 160]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ [38] Yergeau, F., "UTF-8, a transformation format of Unicode and
+ ISO-10646", RFC 2279, January 1998. [jg641]
+
+ [39] Nielsen, H.F., Gettys, J., Baird-Smith, A., Prud'hommeaux, E.,
+ Lie, H., and C. Lilley. "Network Performance Effects of
+ HTTP/1.1, CSS1, and PNG," Proceedings of ACM SIGCOMM '97, Cannes
+ France, September 1997.[jg642]
+
+ [40] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part Two: Media Types", RFC 2046, November
+ 1996. [jg643]
+
+ [41] Alvestrand, H., "IETF Policy on Character Sets and Languages",
+ BCP 18, RFC 2277, January 1998. [jg644]
+
+ [42] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource
+ Identifiers (URI): Generic Syntax and Semantics", RFC 2396,
+ August 1998. [jg645]
+
+ [43] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S.,
+ Leach, P., Luotonen, A., Sink, E. and L. Stewart, "HTTP
+ Authentication: Basic and Digest Access Authentication", RFC
+ 2617, June 1999. [jg646]
+
+ [44] Luotonen, A., "Tunneling TCP based protocols through Web proxy
+ servers," Work in Progress. [jg647]
+
+ [45] Palme, J. and A. Hopmann, "MIME E-mail Encapsulation of
+ Aggregate Documents, such as HTML (MHTML)", RFC 2110, March
+ 1997.
+
+ [46] Bradner, S., "The Internet Standards Process -- Revision 3", BCP
+ 9, RFC 2026, October 1996.
+
+ [47] Masinter, L., "Hyper Text Coffee Pot Control Protocol
+ (HTCPCP/1.0)", RFC 2324, 1 April 1998.
+
+ [48] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part Five: Conformance Criteria and Examples",
+ RFC 2049, November 1996.
+
+ [49] Troost, R., Dorner, S. and K. Moore, "Communicating Presentation
+ Information in Internet Messages: The Content-Disposition Header
+ Field", RFC 2183, August 1997.
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 161]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+18 Authors' Addresses
+
+ Roy T. Fielding
+ Information and Computer Science
+ University of California, Irvine
+ Irvine, CA 92697-3425, USA
+
+ Fax: +1 (949) 824-1715
+ EMail: fielding@ics.uci.edu
+
+
+ James Gettys
+ World Wide Web Consortium
+ MIT Laboratory for Computer Science
+ 545 Technology Square
+ Cambridge, MA 02139, USA
+
+ Fax: +1 (617) 258 8682
+ EMail: jg@w3.org
+
+
+ Jeffrey C. Mogul
+ Western Research Laboratory
+ Compaq Computer Corporation
+ 250 University Avenue
+ Palo Alto, California, 94305, USA
+
+ EMail: mogul@wrl.dec.com
+
+
+ Henrik Frystyk Nielsen
+ World Wide Web Consortium
+ MIT Laboratory for Computer Science
+ 545 Technology Square
+ Cambridge, MA 02139, USA
+
+ Fax: +1 (617) 258 8682
+ EMail: frystyk@w3.org
+
+
+ Larry Masinter
+ Xerox Corporation
+ 3333 Coyote Hill Road
+ Palo Alto, CA 94034, USA
+
+ EMail: masinter@parc.xerox.com
+
+
+
+
+
+Fielding, et al. Standards Track [Page 162]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Paul J. Leach
+ Microsoft Corporation
+ 1 Microsoft Way
+ Redmond, WA 98052, USA
+
+ EMail: paulle@microsoft.com
+
+
+ Tim Berners-Lee
+ Director, World Wide Web Consortium
+ MIT Laboratory for Computer Science
+ 545 Technology Square
+ Cambridge, MA 02139, USA
+
+ Fax: +1 (617) 258 8682
+ EMail: timbl@w3.org
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 163]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+19 Appendices
+
+19.1 Internet Media Type message/http and application/http
+
+ In addition to defining the HTTP/1.1 protocol, this document serves
+ as the specification for the Internet media type "message/http" and
+ "application/http". The message/http type can be used to enclose a
+ single HTTP request or response message, provided that it obeys the
+ MIME restrictions for all "message" types regarding line length and
+ encodings. The application/http type can be used to enclose a
+ pipeline of one or more HTTP request or response messages (not
+ intermixed). The following is to be registered with IANA [17].
+
+ Media Type name: message
+ Media subtype name: http
+ Required parameters: none
+ Optional parameters: version, msgtype
+ version: The HTTP-Version number of the enclosed message
+ (e.g., "1.1"). If not present, the version can be
+ determined from the first line of the body.
+ msgtype: The message type -- "request" or "response". If not
+ present, the type can be determined from the first
+ line of the body.
+ Encoding considerations: only "7bit", "8bit", or "binary" are
+ permitted
+ Security considerations: none
+
+ Media Type name: application
+ Media subtype name: http
+ Required parameters: none
+ Optional parameters: version, msgtype
+ version: The HTTP-Version number of the enclosed messages
+ (e.g., "1.1"). If not present, the version can be
+ determined from the first line of the body.
+ msgtype: The message type -- "request" or "response". If not
+ present, the type can be determined from the first
+ line of the body.
+ Encoding considerations: HTTP messages enclosed by this type
+ are in "binary" format; use of an appropriate
+ Content-Transfer-Encoding is required when
+ transmitted via E-mail.
+ Security considerations: none
+
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 164]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+19.2 Internet Media Type multipart/byteranges
+
+ When an HTTP 206 (Partial Content) response message includes the
+ content of multiple ranges (a response to a request for multiple
+ non-overlapping ranges), these are transmitted as a multipart
+ message-body. The media type for this purpose is called
+ "multipart/byteranges".
+
+ The multipart/byteranges media type includes two or more parts, each
+ with its own Content-Type and Content-Range fields. The required
+ boundary parameter specifies the boundary string used to separate
+ each body-part.
+
+ Media Type name: multipart
+ Media subtype name: byteranges
+ Required parameters: boundary
+ Optional parameters: none
+ Encoding considerations: only "7bit", "8bit", or "binary" are
+ permitted
+ Security considerations: none
+
+
+ For example:
+
+ HTTP/1.1 206 Partial Content
+ Date: Wed, 15 Nov 1995 06:25:24 GMT
+ Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
+ Content-type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
+
+ --THIS_STRING_SEPARATES
+ Content-type: application/pdf
+ Content-range: bytes 500-999/8000
+
+ ...the first range...
+ --THIS_STRING_SEPARATES
+ Content-type: application/pdf
+ Content-range: bytes 7000-7999/8000
+
+ ...the second range
+ --THIS_STRING_SEPARATES--
+
+ Notes:
+
+ 1) Additional CRLFs may precede the first boundary string in the
+ entity.
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 165]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ 2) Although RFC 2046 [40] permits the boundary string to be
+ quoted, some existing implementations handle a quoted boundary
+ string incorrectly.
+
+ 3) A number of browsers and servers were coded to an early draft
+ of the byteranges specification to use a media type of
+ multipart/x-byteranges, which is almost, but not quite
+ compatible with the version documented in HTTP/1.1.
+
+19.3 Tolerant Applications
+
+ Although this document specifies the requirements for the generation
+ of HTTP/1.1 messages, not all applications will be correct in their
+ implementation. We therefore recommend that operational applications
+ be tolerant of deviations whenever those deviations can be
+ interpreted unambiguously.
+
+ Clients SHOULD be tolerant in parsing the Status-Line and servers
+ tolerant when parsing the Request-Line. In particular, they SHOULD
+ accept any amount of SP or HT characters between fields, even though
+ only a single SP is required.
+
+ The line terminator for message-header fields is the sequence CRLF.
+ However, we recommend that applications, when parsing such headers,
+ recognize a single LF as a line terminator and ignore the leading CR.
+
+ The character set of an entity-body SHOULD be labeled as the lowest
+ common denominator of the character codes used within that body, with
+ the exception that not labeling the entity is preferred over labeling
+ the entity with the labels US-ASCII or ISO-8859-1. See section 3.7.1
+ and 3.4.1.
+
+ Additional rules for requirements on parsing and encoding of dates
+ and other potential problems with date encodings include:
+
+ - HTTP/1.1 clients and caches SHOULD assume that an RFC-850 date
+ which appears to be more than 50 years in the future is in fact
+ in the past (this helps solve the "year 2000" problem).
+
+ - An HTTP/1.1 implementation MAY internally represent a parsed
+ Expires date as earlier than the proper value, but MUST NOT
+ internally represent a parsed Expires date as later than the
+ proper value.
+
+ - All expiration-related calculations MUST be done in GMT. The
+ local time zone MUST NOT influence the calculation or comparison
+ of an age or expiration time.
+
+
+
+
+Fielding, et al. Standards Track [Page 166]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ - If an HTTP header incorrectly carries a date value with a time
+ zone other than GMT, it MUST be converted into GMT using the
+ most conservative possible conversion.
+
+19.4 Differences Between HTTP Entities and RFC 2045 Entities
+
+ HTTP/1.1 uses many of the constructs defined for Internet Mail (RFC
+ 822 [9]) and the Multipurpose Internet Mail Extensions (MIME [7]) to
+ allow entities to be transmitted in an open variety of
+ representations and with extensible mechanisms. However, RFC 2045
+ discusses mail, and HTTP has a few features that are different from
+ those described in RFC 2045. These differences were carefully chosen
+ to optimize performance over binary connections, to allow greater
+ freedom in the use of new media types, to make date comparisons
+ easier, and to acknowledge the practice of some early HTTP servers
+ and clients.
+
+ This appendix describes specific areas where HTTP differs from RFC
+ 2045. Proxies and gateways to strict MIME environments SHOULD be
+ aware of these differences and provide the appropriate conversions
+ where necessary. Proxies and gateways from MIME environments to HTTP
+ also need to be aware of the differences because some conversions
+ might be required.
+
+19.4.1 MIME-Version
+
+ HTTP is not a MIME-compliant protocol. However, HTTP/1.1 messages MAY
+ include a single MIME-Version general-header field to indicate what
+ version of the MIME protocol was used to construct the message. Use
+ of the MIME-Version header field indicates that the message is in
+ full compliance with the MIME protocol (as defined in RFC 2045[7]).
+ Proxies/gateways are responsible for ensuring full compliance (where
+ possible) when exporting HTTP messages to strict MIME environments.
+
+ MIME-Version = "MIME-Version" ":" 1*DIGIT "." 1*DIGIT
+
+ MIME version "1.0" is the default for use in HTTP/1.1. However,
+ HTTP/1.1 message parsing and semantics are defined by this document
+ and not the MIME specification.
+
+19.4.2 Conversion to Canonical Form
+
+ RFC 2045 [7] requires that an Internet mail entity be converted to
+ canonical form prior to being transferred, as described in section 4
+ of RFC 2049 [48]. Section 3.7.1 of this document describes the forms
+ allowed for subtypes of the "text" media type when transmitted over
+ HTTP. RFC 2046 requires that content with a type of "text" represent
+ line breaks as CRLF and forbids the use of CR or LF outside of line
+
+
+
+Fielding, et al. Standards Track [Page 167]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ break sequences. HTTP allows CRLF, bare CR, and bare LF to indicate a
+ line break within text content when a message is transmitted over
+ HTTP.
+
+ Where it is possible, a proxy or gateway from HTTP to a strict MIME
+ environment SHOULD translate all line breaks within the text media
+ types described in section 3.7.1 of this document to the RFC 2049
+ canonical form of CRLF. Note, however, that this might be complicated
+ by the presence of a Content-Encoding and by the fact that HTTP
+ allows the use of some character sets which do not use octets 13 and
+ 10 to represent CR and LF, as is the case for some multi-byte
+ character sets.
+
+ Implementors should note that conversion will break any cryptographic
+ checksums applied to the original content unless the original content
+ is already in canonical form. Therefore, the canonical form is
+ recommended for any content that uses such checksums in HTTP.
+
+19.4.3 Conversion of Date Formats
+
+ HTTP/1.1 uses a restricted set of date formats (section 3.3.1) to
+ simplify the process of date comparison. Proxies and gateways from
+ other protocols SHOULD ensure that any Date header field present in a
+ message conforms to one of the HTTP/1.1 formats and rewrite the date
+ if necessary.
+
+19.4.4 Introduction of Content-Encoding
+
+ RFC 2045 does not include any concept equivalent to HTTP/1.1's
+ Content-Encoding header field. Since this acts as a modifier on the
+ media type, proxies and gateways from HTTP to MIME-compliant
+ protocols MUST either change the value of the Content-Type header
+ field or decode the entity-body before forwarding the message. (Some
+ experimental applications of Content-Type for Internet mail have used
+ a media-type parameter of ";conversions=<content-coding>" to perform
+ a function equivalent to Content-Encoding. However, this parameter is
+ not part of RFC 2045.)
+
+19.4.5 No Content-Transfer-Encoding
+
+ HTTP does not use the Content-Transfer-Encoding (CTE) field of RFC
+ 2045. Proxies and gateways from MIME-compliant protocols to HTTP MUST
+ remove any non-identity CTE ("quoted-printable" or "base64") encoding
+ prior to delivering the response message to an HTTP client.
+
+ Proxies and gateways from HTTP to MIME-compliant protocols are
+ responsible for ensuring that the message is in the correct format
+ and encoding for safe transport on that protocol, where "safe
+
+
+
+Fielding, et al. Standards Track [Page 168]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ transport" is defined by the limitations of the protocol being used.
+ Such a proxy or gateway SHOULD label the data with an appropriate
+ Content-Transfer-Encoding if doing so will improve the likelihood of
+ safe transport over the destination protocol.
+
+19.4.6 Introduction of Transfer-Encoding
+
+ HTTP/1.1 introduces the Transfer-Encoding header field (section
+ 14.41). Proxies/gateways MUST remove any transfer-coding prior to
+ forwarding a message via a MIME-compliant protocol.
+
+ A process for decoding the "chunked" transfer-coding (section 3.6)
+ can be represented in pseudo-code as:
+
+ length := 0
+ read chunk-size, chunk-extension (if any) and CRLF
+ while (chunk-size > 0) {
+ read chunk-data and CRLF
+ append chunk-data to entity-body
+ length := length + chunk-size
+ read chunk-size and CRLF
+ }
+ read entity-header
+ while (entity-header not empty) {
+ append entity-header to existing header fields
+ read entity-header
+ }
+ Content-Length := length
+ Remove "chunked" from Transfer-Encoding
+
+19.4.7 MHTML and Line Length Limitations
+
+ HTTP implementations which share code with MHTML [45] implementations
+ need to be aware of MIME line length limitations. Since HTTP does not
+ have this limitation, HTTP does not fold long lines. MHTML messages
+ being transported by HTTP follow all conventions of MHTML, including
+ line length limitations and folding, canonicalization, etc., since
+ HTTP transports all message-bodies as payload (see section 3.7.2) and
+ does not interpret the content or any MIME header lines that might be
+ contained therein.
+
+19.5 Additional Features
+
+ RFC 1945 and RFC 2068 document protocol elements used by some
+ existing HTTP implementations, but not consistently and correctly
+ across most HTTP/1.1 applications. Implementors are advised to be
+ aware of these features, but cannot rely upon their presence in, or
+ interoperability with, other HTTP/1.1 applications. Some of these
+
+
+
+Fielding, et al. Standards Track [Page 169]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ describe proposed experimental features, and some describe features
+ that experimental deployment found lacking that are now addressed in
+ the base HTTP/1.1 specification.
+
+ A number of other headers, such as Content-Disposition and Title,
+ from SMTP and MIME are also often implemented (see RFC 2076 [37]).
+
+19.5.1 Content-Disposition
+
+ The Content-Disposition response-header field has been proposed as a
+ means for the origin server to suggest a default filename if the user
+ requests that the content is saved to a file. This usage is derived
+ from the definition of Content-Disposition in RFC 1806 [35].
+
+ content-disposition = "Content-Disposition" ":"
+ disposition-type *( ";" disposition-parm )
+ disposition-type = "attachment" | disp-extension-token
+ disposition-parm = filename-parm | disp-extension-parm
+ filename-parm = "filename" "=" quoted-string
+ disp-extension-token = token
+ disp-extension-parm = token "=" ( token | quoted-string )
+
+ An example is
+
+ Content-Disposition: attachment; filename="fname.ext"
+
+ The receiving user agent SHOULD NOT respect any directory path
+ information present in the filename-parm parameter, which is the only
+ parameter believed to apply to HTTP implementations at this time. The
+ filename SHOULD be treated as a terminal component only.
+
+ If this header is used in a response with the application/octet-
+ stream content-type, the implied suggestion is that the user agent
+ should not display the response, but directly enter a `save response
+ as...' dialog.
+
+ See section 15.5 for Content-Disposition security issues.
+
+19.6 Compatibility with Previous Versions
+
+ It is beyond the scope of a protocol specification to mandate
+ compliance with previous versions. HTTP/1.1 was deliberately
+ designed, however, to make supporting previous versions easy. It is
+ worth noting that, at the time of composing this specification
+ (1996), we would expect commercial HTTP/1.1 servers to:
+
+ - recognize the format of the Request-Line for HTTP/0.9, 1.0, and
+ 1.1 requests;
+
+
+
+Fielding, et al. Standards Track [Page 170]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ - understand any valid request in the format of HTTP/0.9, 1.0, or
+ 1.1;
+
+ - respond appropriately with a message in the same major version
+ used by the client.
+
+ And we would expect HTTP/1.1 clients to:
+
+ - recognize the format of the Status-Line for HTTP/1.0 and 1.1
+ responses;
+
+ - understand any valid response in the format of HTTP/0.9, 1.0, or
+ 1.1.
+
+ For most implementations of HTTP/1.0, each connection is established
+ by the client prior to the request and closed by the server after
+ sending the response. Some implementations implement the Keep-Alive
+ version of persistent connections described in section 19.7.1 of RFC
+ 2068 [33].
+
+19.6.1 Changes from HTTP/1.0
+
+ This section summarizes major differences between versions HTTP/1.0
+ and HTTP/1.1.
+
+19.6.1.1 Changes to Simplify Multi-homed Web Servers and Conserve IP
+ Addresses
+
+ The requirements that clients and servers support the Host request-
+ header, report an error if the Host request-header (section 14.23) is
+ missing from an HTTP/1.1 request, and accept absolute URIs (section
+ 5.1.2) are among the most important changes defined by this
+ specification.
+
+ Older HTTP/1.0 clients assumed a one-to-one relationship of IP
+ addresses and servers; there was no other established mechanism for
+ distinguishing the intended server of a request than the IP address
+ to which that request was directed. The changes outlined above will
+ allow the Internet, once older HTTP clients are no longer common, to
+ support multiple Web sites from a single IP address, greatly
+ simplifying large operational Web servers, where allocation of many
+ IP addresses to a single host has created serious problems. The
+ Internet will also be able to recover the IP addresses that have been
+ allocated for the sole purpose of allowing special-purpose domain
+ names to be used in root-level HTTP URLs. Given the rate of growth of
+ the Web, and the number of servers already deployed, it is extremely
+
+
+
+
+
+Fielding, et al. Standards Track [Page 171]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ important that all implementations of HTTP (including updates to
+ existing HTTP/1.0 applications) correctly implement these
+ requirements:
+
+ - Both clients and servers MUST support the Host request-header.
+
+ - A client that sends an HTTP/1.1 request MUST send a Host header.
+
+ - Servers MUST report a 400 (Bad Request) error if an HTTP/1.1
+ request does not include a Host request-header.
+
+ - Servers MUST accept absolute URIs.
+
+19.6.2 Compatibility with HTTP/1.0 Persistent Connections
+
+ Some clients and servers might wish to be compatible with some
+ previous implementations of persistent connections in HTTP/1.0
+ clients and servers. Persistent connections in HTTP/1.0 are
+ explicitly negotiated as they are not the default behavior. HTTP/1.0
+ experimental implementations of persistent connections are faulty,
+ and the new facilities in HTTP/1.1 are designed to rectify these
+ problems. The problem was that some existing 1.0 clients may be
+ sending Keep-Alive to a proxy server that doesn't understand
+ Connection, which would then erroneously forward it to the next
+ inbound server, which would establish the Keep-Alive connection and
+ result in a hung HTTP/1.0 proxy waiting for the close on the
+ response. The result is that HTTP/1.0 clients must be prevented from
+ using Keep-Alive when talking to proxies.
+
+ However, talking to proxies is the most important use of persistent
+ connections, so that prohibition is clearly unacceptable. Therefore,
+ we need some other mechanism for indicating a persistent connection
+ is desired, which is safe to use even when talking to an old proxy
+ that ignores Connection. Persistent connections are the default for
+ HTTP/1.1 messages; we introduce a new keyword (Connection: close) for
+ declaring non-persistence. See section 14.10.
+
+ The original HTTP/1.0 form of persistent connections (the Connection:
+ Keep-Alive and Keep-Alive header) is documented in RFC 2068. [33]
+
+19.6.3 Changes from RFC 2068
+
+ This specification has been carefully audited to correct and
+ disambiguate key word usage; RFC 2068 had many problems in respect to
+ the conventions laid out in RFC 2119 [34].
+
+ Clarified which error code should be used for inbound server failures
+ (e.g. DNS failures). (Section 10.5.5).
+
+
+
+Fielding, et al. Standards Track [Page 172]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ CREATE had a race that required an Etag be sent when a resource is
+ first created. (Section 10.2.2).
+
+ Content-Base was deleted from the specification: it was not
+ implemented widely, and there is no simple, safe way to introduce it
+ without a robust extension mechanism. In addition, it is used in a
+ similar, but not identical fashion in MHTML [45].
+
+ Transfer-coding and message lengths all interact in ways that
+ required fixing exactly when chunked encoding is used (to allow for
+ transfer encoding that may not be self delimiting); it was important
+ to straighten out exactly how message lengths are computed. (Sections
+ 3.6, 4.4, 7.2.2, 13.5.2, 14.13, 14.16)
+
+ A content-coding of "identity" was introduced, to solve problems
+ discovered in caching. (section 3.5)
+
+ Quality Values of zero should indicate that "I don't want something"
+ to allow clients to refuse a representation. (Section 3.9)
+
+ The use and interpretation of HTTP version numbers has been clarified
+ by RFC 2145. Require proxies to upgrade requests to highest protocol
+ version they support to deal with problems discovered in HTTP/1.0
+ implementations (Section 3.1)
+
+ Charset wildcarding is introduced to avoid explosion of character set
+ names in accept headers. (Section 14.2)
+
+ A case was missed in the Cache-Control model of HTTP/1.1; s-maxage
+ was introduced to add this missing case. (Sections 13.4, 14.8, 14.9,
+ 14.9.3)
+
+ The Cache-Control: max-age directive was not properly defined for
+ responses. (Section 14.9.3)
+
+ There are situations where a server (especially a proxy) does not
+ know the full length of a response but is capable of serving a
+ byterange request. We therefore need a mechanism to allow byteranges
+ with a content-range not indicating the full length of the message.
+ (Section 14.16)
+
+ Range request responses would become very verbose if all meta-data
+ were always returned; by allowing the server to only send needed
+ headers in a 206 response, this problem can be avoided. (Section
+ 10.2.7, 13.5.3, and 14.27)
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 173]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Fix problem with unsatisfiable range requests; there are two cases:
+ syntactic problems, and range doesn't exist in the document. The 416
+ status code was needed to resolve this ambiguity needed to indicate
+ an error for a byte range request that falls outside of the actual
+ contents of a document. (Section 10.4.17, 14.16)
+
+ Rewrite of message transmission requirements to make it much harder
+ for implementors to get it wrong, as the consequences of errors here
+ can have significant impact on the Internet, and to deal with the
+ following problems:
+
+ 1. Changing "HTTP/1.1 or later" to "HTTP/1.1", in contexts where
+ this was incorrectly placing a requirement on the behavior of
+ an implementation of a future version of HTTP/1.x
+
+ 2. Made it clear that user-agents should retry requests, not
+ "clients" in general.
+
+ 3. Converted requirements for clients to ignore unexpected 100
+ (Continue) responses, and for proxies to forward 100 responses,
+ into a general requirement for 1xx responses.
+
+ 4. Modified some TCP-specific language, to make it clearer that
+ non-TCP transports are possible for HTTP.
+
+ 5. Require that the origin server MUST NOT wait for the request
+ body before it sends a required 100 (Continue) response.
+
+ 6. Allow, rather than require, a server to omit 100 (Continue) if
+ it has already seen some of the request body.
+
+ 7. Allow servers to defend against denial-of-service attacks and
+ broken clients.
+
+ This change adds the Expect header and 417 status code. The message
+ transmission requirements fixes are in sections 8.2, 10.4.18,
+ 8.1.2.2, 13.11, and 14.20.
+
+ Proxies should be able to add Content-Length when appropriate.
+ (Section 13.5.2)
+
+ Clean up confusion between 403 and 404 responses. (Section 10.4.4,
+ 10.4.5, and 10.4.11)
+
+ Warnings could be cached incorrectly, or not updated appropriately.
+ (Section 13.1.2, 13.2.4, 13.5.2, 13.5.3, 14.9.3, and 14.46) Warning
+ also needed to be a general header, as PUT or other methods may have
+ need for it in requests.
+
+
+
+Fielding, et al. Standards Track [Page 174]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+ Transfer-coding had significant problems, particularly with
+ interactions with chunked encoding. The solution is that transfer-
+ codings become as full fledged as content-codings. This involves
+ adding an IANA registry for transfer-codings (separate from content
+ codings), a new header field (TE) and enabling trailer headers in the
+ future. Transfer encoding is a major performance benefit, so it was
+ worth fixing [39]. TE also solves another, obscure, downward
+ interoperability problem that could have occurred due to interactions
+ between authentication trailers, chunked encoding and HTTP/1.0
+ clients.(Section 3.6, 3.6.1, and 14.39)
+
+ The PATCH, LINK, UNLINK methods were defined but not commonly
+ implemented in previous versions of this specification. See RFC 2068
+ [33].
+
+ The Alternates, Content-Version, Derived-From, Link, URI, Public and
+ Content-Base header fields were defined in previous versions of this
+ specification, but not commonly implemented. See RFC 2068 [33].
+
+20 Index
+
+ Please see the PostScript version of this RFC for the INDEX.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 175]
+
+RFC 2616 HTTP/1.1 June 1999
+
+
+21. Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Fielding, et al. Standards Track [Page 176]
+
diff --git a/standards/rfc2617.txt b/standards/rfc2617.txt
new file mode 100644
index 000000000..771aa924a
--- /dev/null
+++ b/standards/rfc2617.txt
@@ -0,0 +1,1907 @@
+
+
+
+
+
+
+Network Working Group J. Franks
+Request for Comments: 2617 Northwestern University
+Obsoletes: 2069 P. Hallam-Baker
+Category: Standards Track Verisign, Inc.
+ J. Hostetler
+ AbiSource, Inc.
+ S. Lawrence
+ Agranat Systems, Inc.
+ P. Leach
+ Microsoft Corporation
+ A. Luotonen
+ Netscape Communications Corporation
+ L. Stewart
+ Open Market, Inc.
+ June 1999
+
+
+ HTTP Authentication: Basic and Digest Access Authentication
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+Abstract
+
+ "HTTP/1.0", includes the specification for a Basic Access
+ Authentication scheme. This scheme is not considered to be a secure
+ method of user authentication (unless used in conjunction with some
+ external secure system such as SSL [5]), as the user name and
+ password are passed over the network as cleartext.
+
+ This document also provides the specification for HTTP's
+ authentication framework, the original Basic authentication scheme
+ and a scheme based on cryptographic hashes, referred to as "Digest
+ Access Authentication". It is therefore also intended to serve as a
+ replacement for RFC 2069 [6]. Some optional elements specified by
+ RFC 2069 have been removed from this specification due to problems
+ found since its publication; other new elements have been added for
+ compatibility, those new elements have been made optional, but are
+ strongly recommended.
+
+
+
+Franks, et al. Standards Track [Page 1]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ Like Basic, Digest access authentication verifies that both parties
+ to a communication know a shared secret (a password); unlike Basic,
+ this verification can be done without sending the password in the
+ clear, which is Basic's biggest weakness. As with most other
+ authentication protocols, the greatest sources of risks are usually
+ found not in the core protocol itself but in policies and procedures
+ surrounding its use.
+
+Table of Contents
+
+ 1 Access Authentication................................ 3
+ 1.1 Reliance on the HTTP/1.1 Specification............ 3
+ 1.2 Access Authentication Framework................... 3
+ 2 Basic Authentication Scheme.......................... 5
+ 3 Digest Access Authentication Scheme.................. 6
+ 3.1 Introduction...................................... 6
+ 3.1.1 Purpose......................................... 6
+ 3.1.2 Overall Operation............................... 6
+ 3.1.3 Representation of digest values................. 7
+ 3.1.4 Limitations..................................... 7
+ 3.2 Specification of Digest Headers................... 7
+ 3.2.1 The WWW-Authenticate Response Header............ 8
+ 3.2.2 The Authorization Request Header................ 11
+ 3.2.3 The Authentication-Info Header.................. 15
+ 3.3 Digest Operation.................................. 17
+ 3.4 Security Protocol Negotiation..................... 18
+ 3.5 Example........................................... 18
+ 3.6 Proxy-Authentication and Proxy-Authorization...... 19
+ 4 Security Considerations.............................. 19
+ 4.1 Authentication of Clients using Basic
+ Authentication.................................... 19
+ 4.2 Authentication of Clients using Digest
+ Authentication.................................... 20
+ 4.3 Limited Use Nonce Values.......................... 21
+ 4.4 Comparison of Digest with Basic Authentication.... 22
+ 4.5 Replay Attacks.................................... 22
+ 4.6 Weakness Created by Multiple Authentication
+ Schemes........................................... 23
+ 4.7 Online dictionary attacks......................... 23
+ 4.8 Man in the Middle................................. 24
+ 4.9 Chosen plaintext attacks.......................... 24
+ 4.10 Precomputed dictionary attacks.................... 25
+ 4.11 Batch brute force attacks......................... 25
+ 4.12 Spoofing by Counterfeit Servers................... 25
+ 4.13 Storing passwords................................. 26
+ 4.14 Summary........................................... 26
+ 5 Sample implementation................................ 27
+ 6 Acknowledgments...................................... 31
+
+
+
+Franks, et al. Standards Track [Page 2]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ 7 References........................................... 31
+ 8 Authors' Addresses................................... 32
+ 9 Full Copyright Statement............................. 34
+
+1 Access Authentication
+
+1.1 Reliance on the HTTP/1.1 Specification
+
+ This specification is a companion to the HTTP/1.1 specification [2].
+ It uses the augmented BNF section 2.1 of that document, and relies on
+ both the non-terminals defined in that document and other aspects of
+ the HTTP/1.1 specification.
+
+1.2 Access Authentication Framework
+
+ HTTP provides a simple challenge-response authentication mechanism
+ that MAY be used by a server to challenge a client request and by a
+ client to provide authentication information. It uses an extensible,
+ case-insensitive token to identify the authentication scheme,
+ followed by a comma-separated list of attribute-value pairs which
+ carry the parameters necessary for achieving authentication via that
+ scheme.
+
+ auth-scheme = token
+ auth-param = token "=" ( token | quoted-string )
+
+ The 401 (Unauthorized) response message is used by an origin server
+ to challenge the authorization of a user agent. This response MUST
+ include a WWW-Authenticate header field containing at least one
+ challenge applicable to the requested resource. The 407 (Proxy
+ Authentication Required) response message is used by a proxy to
+ challenge the authorization of a client and MUST include a Proxy-
+ Authenticate header field containing at least one challenge
+ applicable to the proxy for the requested resource.
+
+ challenge = auth-scheme 1*SP 1#auth-param
+
+ Note: User agents will need to take special care in parsing the WWW-
+ Authenticate or Proxy-Authenticate header field value if it contains
+ more than one challenge, or if more than one WWW-Authenticate header
+ field is provided, since the contents of a challenge may itself
+ contain a comma-separated list of authentication parameters.
+
+ The authentication parameter realm is defined for all authentication
+ schemes:
+
+ realm = "realm" "=" realm-value
+ realm-value = quoted-string
+
+
+
+Franks, et al. Standards Track [Page 3]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ The realm directive (case-insensitive) is required for all
+ authentication schemes that issue a challenge. The realm value
+ (case-sensitive), in combination with the canonical root URL (the
+ absoluteURI for the server whose abs_path is empty; see section 5.1.2
+ of [2]) of the server being accessed, defines the protection space.
+ These realms allow the protected resources on a server to be
+ partitioned into a set of protection spaces, each with its own
+ authentication scheme and/or authorization database. The realm value
+ is a string, generally assigned by the origin server, which may have
+ additional semantics specific to the authentication scheme. Note that
+ there may be multiple challenges with the same auth-scheme but
+ different realms.
+
+ A user agent that wishes to authenticate itself with an origin
+ server--usually, but not necessarily, after receiving a 401
+ (Unauthorized)--MAY do so by including an Authorization header field
+ with the request. A client that wishes to authenticate itself with a
+ proxy--usually, but not necessarily, after receiving a 407 (Proxy
+ Authentication Required)--MAY do so by including a Proxy-
+ Authorization header field with the request. Both the Authorization
+ field value and the Proxy-Authorization field value consist of
+ credentials containing the authentication information of the client
+ for the realm of the resource being requested. The user agent MUST
+ choose to use one of the challenges with the strongest auth-scheme it
+ understands and request credentials from the user based upon that
+ challenge.
+
+ credentials = auth-scheme #auth-param
+
+ Note that many browsers will only recognize Basic and will require
+ that it be the first auth-scheme presented. Servers should only
+ include Basic if it is minimally acceptable.
+
+ The protection space determines the domain over which credentials can
+ be automatically applied. If a prior request has been authorized, the
+ same credentials MAY be reused for all other requests within that
+ protection space for a period of time determined by the
+ authentication scheme, parameters, and/or user preference. Unless
+ otherwise defined by the authentication scheme, a single protection
+ space cannot extend outside the scope of its server.
+
+ If the origin server does not wish to accept the credentials sent
+ with a request, it SHOULD return a 401 (Unauthorized) response. The
+ response MUST include a WWW-Authenticate header field containing at
+ least one (possibly new) challenge applicable to the requested
+ resource. If a proxy does not accept the credentials sent with a
+ request, it SHOULD return a 407 (Proxy Authentication Required). The
+ response MUST include a Proxy-Authenticate header field containing a
+
+
+
+Franks, et al. Standards Track [Page 4]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ (possibly new) challenge applicable to the proxy for the requested
+ resource.
+
+ The HTTP protocol does not restrict applications to this simple
+ challenge-response mechanism for access authentication. Additional
+ mechanisms MAY be used, such as encryption at the transport level or
+ via message encapsulation, and with additional header fields
+ specifying authentication information. However, these additional
+ mechanisms are not defined by this specification.
+
+ Proxies MUST be completely transparent regarding user agent
+ authentication by origin servers. That is, they must forward the
+ WWW-Authenticate and Authorization headers untouched, and follow the
+ rules found in section 14.8 of [2]. Both the Proxy-Authenticate and
+ the Proxy-Authorization header fields are hop-by-hop headers (see
+ section 13.5.1 of [2]).
+
+2 Basic Authentication Scheme
+
+ The "basic" authentication scheme is based on the model that the
+ client must authenticate itself with a user-ID and a password for
+ each realm. The realm value should be considered an opaque string
+ which can only be compared for equality with other realms on that
+ server. The server will service the request only if it can validate
+ the user-ID and password for the protection space of the Request-URI.
+ There are no optional authentication parameters.
+
+ For Basic, the framework above is utilized as follows:
+
+ challenge = "Basic" realm
+ credentials = "Basic" basic-credentials
+
+ Upon receipt of an unauthorized request for a URI within the
+ protection space, the origin server MAY respond with a challenge like
+ the following:
+
+ WWW-Authenticate: Basic realm="WallyWorld"
+
+ where "WallyWorld" is the string assigned by the server to identify
+ the protection space of the Request-URI. A proxy may respond with the
+ same challenge using the Proxy-Authenticate header field.
+
+ To receive authorization, the client sends the userid and password,
+ separated by a single colon (":") character, within a base64 [7]
+ encoded string in the credentials.
+
+ basic-credentials = base64-user-pass
+ base64-user-pass = <base64 [4] encoding of user-pass,
+
+
+
+Franks, et al. Standards Track [Page 5]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ except not limited to 76 char/line>
+ user-pass = userid ":" password
+ userid = *<TEXT excluding ":">
+ password = *TEXT
+
+ Userids might be case sensitive.
+
+ If the user agent wishes to send the userid "Aladdin" and password
+ "open sesame", it would use the following header field:
+
+ Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
+
+ A client SHOULD assume that all paths at or deeper than the depth of
+ the last symbolic element in the path field of the Request-URI also
+ are within the protection space specified by the Basic realm value of
+ the current challenge. A client MAY preemptively send the
+ corresponding Authorization header with requests for resources in
+ that space without receipt of another challenge from the server.
+ Similarly, when a client sends a request to a proxy, it may reuse a
+ userid and password in the Proxy-Authorization header field without
+ receiving another challenge from the proxy server. See section 4 for
+ security considerations associated with Basic authentication.
+
+3 Digest Access Authentication Scheme
+
+3.1 Introduction
+
+3.1.1 Purpose
+
+ The protocol referred to as "HTTP/1.0" includes the specification for
+ a Basic Access Authentication scheme[1]. That scheme is not
+ considered to be a secure method of user authentication, as the user
+ name and password are passed over the network in an unencrypted form.
+ This section provides the specification for a scheme that does not
+ send the password in cleartext, referred to as "Digest Access
+ Authentication".
+
+ The Digest Access Authentication scheme is not intended to be a
+ complete answer to the need for security in the World Wide Web. This
+ scheme provides no encryption of message content. The intent is
+ simply to create an access authentication method that avoids the most
+ serious flaws of Basic authentication.
+
+3.1.2 Overall Operation
+
+ Like Basic Access Authentication, the Digest scheme is based on a
+ simple challenge-response paradigm. The Digest scheme challenges
+ using a nonce value. A valid response contains a checksum (by
+
+
+
+Franks, et al. Standards Track [Page 6]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ default, the MD5 checksum) of the username, the password, the given
+ nonce value, the HTTP method, and the requested URI. In this way, the
+ password is never sent in the clear. Just as with the Basic scheme,
+ the username and password must be prearranged in some fashion not
+ addressed by this document.
+
+3.1.3 Representation of digest values
+
+ An optional header allows the server to specify the algorithm used to
+ create the checksum or digest. By default the MD5 algorithm is used
+ and that is the only algorithm described in this document.
+
+ For the purposes of this document, an MD5 digest of 128 bits is
+ represented as 32 ASCII printable characters. The bits in the 128 bit
+ digest are converted from most significant to least significant bit,
+ four bits at a time to their ASCII presentation as follows. Each four
+ bits is represented by its familiar hexadecimal notation from the
+ characters 0123456789abcdef. That is, binary 0000 gets represented by
+ the character '0', 0001, by '1', and so on up to the representation
+ of 1111 as 'f'.
+
+3.1.4 Limitations
+
+ The Digest authentication scheme described in this document suffers
+ from many known limitations. It is intended as a replacement for
+ Basic authentication and nothing more. It is a password-based system
+ and (on the server side) suffers from all the same problems of any
+ password system. In particular, no provision is made in this protocol
+ for the initial secure arrangement between user and server to
+ establish the user's password.
+
+ Users and implementors should be aware that this protocol is not as
+ secure as Kerberos, and not as secure as any client-side private-key
+ scheme. Nevertheless it is better than nothing, better than what is
+ commonly used with telnet and ftp, and better than Basic
+ authentication.
+
+3.2 Specification of Digest Headers
+
+ The Digest Access Authentication scheme is conceptually similar to
+ the Basic scheme. The formats of the modified WWW-Authenticate header
+ line and the Authorization header line are specified below. In
+ addition, a new header, Authentication-Info, is specified.
+
+
+
+
+
+
+
+
+Franks, et al. Standards Track [Page 7]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+3.2.1 The WWW-Authenticate Response Header
+
+ If a server receives a request for an access-protected object, and an
+ acceptable Authorization header is not sent, the server responds with
+ a "401 Unauthorized" status code, and a WWW-Authenticate header as
+ per the framework defined above, which for the digest scheme is
+ utilized as follows:
+
+ challenge = "Digest" digest-challenge
+
+ digest-challenge = 1#( realm | [ domain ] | nonce |
+ [ opaque ] |[ stale ] | [ algorithm ] |
+ [ qop-options ] | [auth-param] )
+
+
+ domain = "domain" "=" <"> URI ( 1*SP URI ) <">
+ URI = absoluteURI | abs_path
+ nonce = "nonce" "=" nonce-value
+ nonce-value = quoted-string
+ opaque = "opaque" "=" quoted-string
+ stale = "stale" "=" ( "true" | "false" )
+ algorithm = "algorithm" "=" ( "MD5" | "MD5-sess" |
+ token )
+ qop-options = "qop" "=" <"> 1#qop-value <">
+ qop-value = "auth" | "auth-int" | token
+
+ The meanings of the values of the directives used above are as
+ follows:
+
+ realm
+ A string to be displayed to users so they know which username and
+ password to use. This string should contain at least the name of
+ the host performing the authentication and might additionally
+ indicate the collection of users who might have access. An example
+ might be "registered_users@gotham.news.com".
+
+ domain
+ A quoted, space-separated list of URIs, as specified in RFC XURI
+ [7], that define the protection space. If a URI is an abs_path, it
+ is relative to the canonical root URL (see section 1.2 above) of
+ the server being accessed. An absoluteURI in this list may refer to
+ a different server than the one being accessed. The client can use
+ this list to determine the set of URIs for which the same
+ authentication information may be sent: any URI that has a URI in
+ this list as a prefix (after both have been made absolute) may be
+ assumed to be in the same protection space. If this directive is
+ omitted or its value is empty, the client should assume that the
+ protection space consists of all URIs on the responding server.
+
+
+
+Franks, et al. Standards Track [Page 8]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ This directive is not meaningful in Proxy-Authenticate headers, for
+ which the protection space is always the entire proxy; if present
+ it should be ignored.
+
+ nonce
+ A server-specified data string which should be uniquely generated
+ each time a 401 response is made. It is recommended that this
+ string be base64 or hexadecimal data. Specifically, since the
+ string is passed in the header lines as a quoted string, the
+ double-quote character is not allowed.
+
+ The contents of the nonce are implementation dependent. The quality
+ of the implementation depends on a good choice. A nonce might, for
+ example, be constructed as the base 64 encoding of
+
+ time-stamp H(time-stamp ":" ETag ":" private-key)
+
+ where time-stamp is a server-generated time or other non-repeating
+ value, ETag is the value of the HTTP ETag header associated with
+ the requested entity, and private-key is data known only to the
+ server. With a nonce of this form a server would recalculate the
+ hash portion after receiving the client authentication header and
+ reject the request if it did not match the nonce from that header
+ or if the time-stamp value is not recent enough. In this way the
+ server can limit the time of the nonce's validity. The inclusion of
+ the ETag prevents a replay request for an updated version of the
+ resource. (Note: including the IP address of the client in the
+ nonce would appear to offer the server the ability to limit the
+ reuse of the nonce to the same client that originally got it.
+ However, that would break proxy farms, where requests from a single
+ user often go through different proxies in the farm. Also, IP
+ address spoofing is not that hard.)
+
+ An implementation might choose not to accept a previously used
+ nonce or a previously used digest, in order to protect against a
+ replay attack. Or, an implementation might choose to use one-time
+ nonces or digests for POST or PUT requests and a time-stamp for GET
+ requests. For more details on the issues involved see section 4.
+ of this document.
+
+ The nonce is opaque to the client.
+
+ opaque
+ A string of data, specified by the server, which should be returned
+ by the client unchanged in the Authorization header of subsequent
+ requests with URIs in the same protection space. It is recommended
+ that this string be base64 or hexadecimal data.
+
+
+
+
+Franks, et al. Standards Track [Page 9]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ stale
+ A flag, indicating that the previous request from the client was
+ rejected because the nonce value was stale. If stale is TRUE
+ (case-insensitive), the client may wish to simply retry the request
+ with a new encrypted response, without reprompting the user for a
+ new username and password. The server should only set stale to TRUE
+ if it receives a request for which the nonce is invalid but with a
+ valid digest for that nonce (indicating that the client knows the
+ correct username/password). If stale is FALSE, or anything other
+ than TRUE, or the stale directive is not present, the username
+ and/or password are invalid, and new values must be obtained.
+
+ algorithm
+ A string indicating a pair of algorithms used to produce the digest
+ and a checksum. If this is not present it is assumed to be "MD5".
+ If the algorithm is not understood, the challenge should be ignored
+ (and a different one used, if there is more than one).
+
+ In this document the string obtained by applying the digest
+ algorithm to the data "data" with secret "secret" will be denoted
+ by KD(secret, data), and the string obtained by applying the
+ checksum algorithm to the data "data" will be denoted H(data). The
+ notation unq(X) means the value of the quoted-string X without the
+ surrounding quotes.
+
+ For the "MD5" and "MD5-sess" algorithms
+
+ H(data) = MD5(data)
+
+ and
+
+ KD(secret, data) = H(concat(secret, ":", data))
+
+ i.e., the digest is the MD5 of the secret concatenated with a colon
+ concatenated with the data. The "MD5-sess" algorithm is intended to
+ allow efficient 3rd party authentication servers; for the
+ difference in usage, see the description in section 3.2.2.2.
+
+ qop-options
+ This directive is optional, but is made so only for backward
+ compatibility with RFC 2069 [6]; it SHOULD be used by all
+ implementations compliant with this version of the Digest scheme.
+ If present, it is a quoted string of one or more tokens indicating
+ the "quality of protection" values supported by the server. The
+ value "auth" indicates authentication; the value "auth-int"
+ indicates authentication with integrity protection; see the
+
+
+
+
+
+Franks, et al. Standards Track [Page 10]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ descriptions below for calculating the response directive value for
+ the application of this choice. Unrecognized options MUST be
+ ignored.
+
+ auth-param
+ This directive allows for future extensions. Any unrecognized
+ directive MUST be ignored.
+
+3.2.2 The Authorization Request Header
+
+ The client is expected to retry the request, passing an Authorization
+ header line, which is defined according to the framework above,
+ utilized as follows.
+
+ credentials = "Digest" digest-response
+ digest-response = 1#( username | realm | nonce | digest-uri
+ | response | [ algorithm ] | [cnonce] |
+ [opaque] | [message-qop] |
+ [nonce-count] | [auth-param] )
+
+ username = "username" "=" username-value
+ username-value = quoted-string
+ digest-uri = "uri" "=" digest-uri-value
+ digest-uri-value = request-uri ; As specified by HTTP/1.1
+ message-qop = "qop" "=" qop-value
+ cnonce = "cnonce" "=" cnonce-value
+ cnonce-value = nonce-value
+ nonce-count = "nc" "=" nc-value
+ nc-value = 8LHEX
+ response = "response" "=" request-digest
+ request-digest = <"> 32LHEX <">
+ LHEX = "0" | "1" | "2" | "3" |
+ "4" | "5" | "6" | "7" |
+ "8" | "9" | "a" | "b" |
+ "c" | "d" | "e" | "f"
+
+ The values of the opaque and algorithm fields must be those supplied
+ in the WWW-Authenticate response header for the entity being
+ requested.
+
+ response
+ A string of 32 hex digits computed as defined below, which proves
+ that the user knows a password
+
+ username
+ The user's name in the specified realm.
+
+
+
+
+
+Franks, et al. Standards Track [Page 11]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ digest-uri
+ The URI from Request-URI of the Request-Line; duplicated here
+ because proxies are allowed to change the Request-Line in transit.
+
+ qop
+ Indicates what "quality of protection" the client has applied to
+ the message. If present, its value MUST be one of the alternatives
+ the server indicated it supports in the WWW-Authenticate header.
+ These values affect the computation of the request-digest. Note
+ that this is a single token, not a quoted list of alternatives as
+ in WWW- Authenticate. This directive is optional in order to
+ preserve backward compatibility with a minimal implementation of
+ RFC 2069 [6], but SHOULD be used if the server indicated that qop
+ is supported by providing a qop directive in the WWW-Authenticate
+ header field.
+
+ cnonce
+ This MUST be specified if a qop directive is sent (see above), and
+ MUST NOT be specified if the server did not send a qop directive in
+ the WWW-Authenticate header field. The cnonce-value is an opaque
+ quoted string value provided by the client and used by both client
+ and server to avoid chosen plaintext attacks, to provide mutual
+ authentication, and to provide some message integrity protection.
+ See the descriptions below of the calculation of the response-
+ digest and request-digest values.
+
+ nonce-count
+ This MUST be specified if a qop directive is sent (see above), and
+ MUST NOT be specified if the server did not send a qop directive in
+ the WWW-Authenticate header field. The nc-value is the hexadecimal
+ count of the number of requests (including the current request)
+ that the client has sent with the nonce value in this request. For
+ example, in the first request sent in response to a given nonce
+ value, the client sends "nc=00000001". The purpose of this
+ directive is to allow the server to detect request replays by
+ maintaining its own copy of this count - if the same nc-value is
+ seen twice, then the request is a replay. See the description
+ below of the construction of the request-digest value.
+
+ auth-param
+ This directive allows for future extensions. Any unrecognized
+ directive MUST be ignored.
+
+ If a directive or its value is improper, or required directives are
+ missing, the proper response is 400 Bad Request. If the request-
+ digest is invalid, then a login failure should be logged, since
+ repeated login failures from a single client may indicate an attacker
+ attempting to guess passwords.
+
+
+
+Franks, et al. Standards Track [Page 12]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ The definition of request-digest above indicates the encoding for its
+ value. The following definitions show how the value is computed.
+
+3.2.2.1 Request-Digest
+
+ If the "qop" value is "auth" or "auth-int":
+
+ request-digest = <"> < KD ( H(A1), unq(nonce-value)
+ ":" nc-value
+ ":" unq(cnonce-value)
+ ":" unq(qop-value)
+ ":" H(A2)
+ ) <">
+
+ If the "qop" directive is not present (this construction is for
+ compatibility with RFC 2069):
+
+ request-digest =
+ <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) >
+ <">
+
+ See below for the definitions for A1 and A2.
+
+3.2.2.2 A1
+
+ If the "algorithm" directive's value is "MD5" or is unspecified, then
+ A1 is:
+
+ A1 = unq(username-value) ":" unq(realm-value) ":" passwd
+
+ where
+
+ passwd = < user's password >
+
+ If the "algorithm" directive's value is "MD5-sess", then A1 is
+ calculated only once - on the first request by the client following
+ receipt of a WWW-Authenticate challenge from the server. It uses the
+ server nonce from that challenge, and the first client nonce value to
+ construct A1 as follows:
+
+ A1 = H( unq(username-value) ":" unq(realm-value)
+ ":" passwd )
+ ":" unq(nonce-value) ":" unq(cnonce-value)
+
+ This creates a 'session key' for the authentication of subsequent
+ requests and responses which is different for each "authentication
+ session", thus limiting the amount of material hashed with any one
+ key. (Note: see further discussion of the authentication session in
+
+
+
+Franks, et al. Standards Track [Page 13]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ section 3.3.) Because the server need only use the hash of the user
+ credentials in order to create the A1 value, this construction could
+ be used in conjunction with a third party authentication service so
+ that the web server would not need the actual password value. The
+ specification of such a protocol is beyond the scope of this
+ specification.
+
+3.2.2.3 A2
+
+ If the "qop" directive's value is "auth" or is unspecified, then A2
+ is:
+
+ A2 = Method ":" digest-uri-value
+
+ If the "qop" value is "auth-int", then A2 is:
+
+ A2 = Method ":" digest-uri-value ":" H(entity-body)
+
+3.2.2.4 Directive values and quoted-string
+
+ Note that the value of many of the directives, such as "username-
+ value", are defined as a "quoted-string". However, the "unq" notation
+ indicates that surrounding quotation marks are removed in forming the
+ string A1. Thus if the Authorization header includes the fields
+
+ username="Mufasa", realm=myhost@testrealm.com
+
+ and the user Mufasa has password "Circle Of Life" then H(A1) would be
+ H(Mufasa:myhost@testrealm.com:Circle Of Life) with no quotation marks
+ in the digested string.
+
+ No white space is allowed in any of the strings to which the digest
+ function H() is applied unless that white space exists in the quoted
+ strings or entity body whose contents make up the string to be
+ digested. For example, the string A1 illustrated above must be
+
+ Mufasa:myhost@testrealm.com:Circle Of Life
+
+ with no white space on either side of the colons, but with the white
+ space between the words used in the password value. Likewise, the
+ other strings digested by H() must not have white space on either
+ side of the colons which delimit their fields unless that white space
+ was in the quoted strings or entity body being digested.
+
+ Also note that if integrity protection is applied (qop=auth-int), the
+ H(entity-body) is the hash of the entity body, not the message body -
+ it is computed before any transfer encoding is applied by the sender
+
+
+
+
+Franks, et al. Standards Track [Page 14]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ and after it has been removed by the recipient. Note that this
+ includes multipart boundaries and embedded headers in each part of
+ any multipart content-type.
+
+3.2.2.5 Various considerations
+
+ The "Method" value is the HTTP request method as specified in section
+ 5.1.1 of [2]. The "request-uri" value is the Request-URI from the
+ request line as specified in section 5.1.2 of [2]. This may be "*",
+ an "absoluteURL" or an "abs_path" as specified in section 5.1.2 of
+ [2], but it MUST agree with the Request-URI. In particular, it MUST
+ be an "absoluteURL" if the Request-URI is an "absoluteURL". The
+ "cnonce-value" is an optional client-chosen value whose purpose is
+ to foil chosen plaintext attacks.
+
+ The authenticating server must assure that the resource designated by
+ the "uri" directive is the same as the resource specified in the
+ Request-Line; if they are not, the server SHOULD return a 400 Bad
+ Request error. (Since this may be a symptom of an attack, server
+ implementers may want to consider logging such errors.) The purpose
+ of duplicating information from the request URL in this field is to
+ deal with the possibility that an intermediate proxy may alter the
+ client's Request-Line. This altered (but presumably semantically
+ equivalent) request would not result in the same digest as that
+ calculated by the client.
+
+ Implementers should be aware of how authenticated transactions
+ interact with shared caches. The HTTP/1.1 protocol specifies that
+ when a shared cache (see section 13.7 of [2]) has received a request
+ containing an Authorization header and a response from relaying that
+ request, it MUST NOT return that response as a reply to any other
+ request, unless one of two Cache-Control (see section 14.9 of [2])
+ directives was present in the response. If the original response
+ included the "must-revalidate" Cache-Control directive, the cache MAY
+ use the entity of that response in replying to a subsequent request,
+ but MUST first revalidate it with the origin server, using the
+ request headers from the new request to allow the origin server to
+ authenticate the new request. Alternatively, if the original response
+ included the "public" Cache-Control directive, the response entity
+ MAY be returned in reply to any subsequent request.
+
+3.2.3 The Authentication-Info Header
+
+ The Authentication-Info header is used by the server to communicate
+ some information regarding the successful authentication in the
+ response.
+
+
+
+
+
+Franks, et al. Standards Track [Page 15]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ AuthenticationInfo = "Authentication-Info" ":" auth-info
+ auth-info = 1#(nextnonce | [ message-qop ]
+ | [ response-auth ] | [ cnonce ]
+ | [nonce-count] )
+ nextnonce = "nextnonce" "=" nonce-value
+ response-auth = "rspauth" "=" response-digest
+ response-digest = <"> *LHEX <">
+
+ The value of the nextnonce directive is the nonce the server wishes
+ the client to use for a future authentication response. The server
+ may send the Authentication-Info header with a nextnonce field as a
+ means of implementing one-time or otherwise changing nonces. If the
+ nextnonce field is present the client SHOULD use it when constructing
+ the Authorization header for its next request. Failure of the client
+ to do so may result in a request to re-authenticate from the server
+ with the "stale=TRUE".
+
+ Server implementations should carefully consider the performance
+ implications of the use of this mechanism; pipelined requests will
+ not be possible if every response includes a nextnonce directive
+ that must be used on the next request received by the server.
+ Consideration should be given to the performance vs. security
+ tradeoffs of allowing an old nonce value to be used for a limited
+ time to permit request pipelining. Use of the nonce-count can
+ retain most of the security advantages of a new server nonce
+ without the deleterious affects on pipelining.
+
+ message-qop
+ Indicates the "quality of protection" options applied to the
+ response by the server. The value "auth" indicates authentication;
+ the value "auth-int" indicates authentication with integrity
+ protection. The server SHOULD use the same value for the message-
+ qop directive in the response as was sent by the client in the
+ corresponding request.
+
+ The optional response digest in the "response-auth" directive
+ supports mutual authentication -- the server proves that it knows the
+ user's secret, and with qop=auth-int also provides limited integrity
+ protection of the response. The "response-digest" value is calculated
+ as for the "request-digest" in the Authorization header, except that
+ if "qop=auth" or is not specified in the Authorization header for the
+ request, A2 is
+
+ A2 = ":" digest-uri-value
+
+ and if "qop=auth-int", then A2 is
+
+ A2 = ":" digest-uri-value ":" H(entity-body)
+
+
+
+Franks, et al. Standards Track [Page 16]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ where "digest-uri-value" is the value of the "uri" directive on the
+ Authorization header in the request. The "cnonce-value" and "nc-
+ value" MUST be the ones for the client request to which this message
+ is the response. The "response-auth", "cnonce", and "nonce-count"
+ directives MUST BE present if "qop=auth" or "qop=auth-int" is
+ specified.
+
+ The Authentication-Info header is allowed in the trailer of an HTTP
+ message transferred via chunked transfer-coding.
+
+3.3 Digest Operation
+
+ Upon receiving the Authorization header, the server may check its
+ validity by looking up the password that corresponds to the submitted
+ username. Then, the server must perform the same digest operation
+ (e.g., MD5) performed by the client, and compare the result to the
+ given request-digest value.
+
+ Note that the HTTP server does not actually need to know the user's
+ cleartext password. As long as H(A1) is available to the server, the
+ validity of an Authorization header may be verified.
+
+ The client response to a WWW-Authenticate challenge for a protection
+ space starts an authentication session with that protection space.
+ The authentication session lasts until the client receives another
+ WWW-Authenticate challenge from any server in the protection space. A
+ client should remember the username, password, nonce, nonce count and
+ opaque values associated with an authentication session to use to
+ construct the Authorization header in future requests within that
+ protection space. The Authorization header may be included
+ preemptively; doing so improves server efficiency and avoids extra
+ round trips for authentication challenges. The server may choose to
+ accept the old Authorization header information, even though the
+ nonce value included might not be fresh. Alternatively, the server
+ may return a 401 response with a new nonce value, causing the client
+ to retry the request; by specifying stale=TRUE with this response,
+ the server tells the client to retry with the new nonce, but without
+ prompting for a new username and password.
+
+ Because the client is required to return the value of the opaque
+ directive given to it by the server for the duration of a session,
+ the opaque data may be used to transport authentication session state
+ information. (Note that any such use can also be accomplished more
+ easily and safely by including the state in the nonce.) For example,
+ a server could be responsible for authenticating content that
+ actually sits on another server. It would achieve this by having the
+ first 401 response include a domain directive whose value includes a
+ URI on the second server, and an opaque directive whose value
+
+
+
+Franks, et al. Standards Track [Page 17]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ contains the state information. The client will retry the request, at
+ which time the server might respond with a 301/302 redirection,
+ pointing to the URI on the second server. The client will follow the
+ redirection, and pass an Authorization header , including the
+ <opaque> data.
+
+ As with the basic scheme, proxies must be completely transparent in
+ the Digest access authentication scheme. That is, they must forward
+ the WWW-Authenticate, Authentication-Info and Authorization headers
+ untouched. If a proxy wants to authenticate a client before a request
+ is forwarded to the server, it can be done using the Proxy-
+ Authenticate and Proxy-Authorization headers described in section 3.6
+ below.
+
+3.4 Security Protocol Negotiation
+
+ It is useful for a server to be able to know which security schemes a
+ client is capable of handling.
+
+ It is possible that a server may want to require Digest as its
+ authentication method, even if the server does not know that the
+ client supports it. A client is encouraged to fail gracefully if the
+ server specifies only authentication schemes it cannot handle.
+
+3.5 Example
+
+ The following example assumes that an access-protected document is
+ being requested from the server via a GET request. The URI of the
+ document is "http://www.nowhere.org/dir/index.html". Both client and
+ server know that the username for this document is "Mufasa", and the
+ password is "Circle Of Life" (with one space between each of the
+ three words).
+
+ The first time the client requests the document, no Authorization
+ header is sent, so the server responds with:
+
+ HTTP/1.1 401 Unauthorized
+ WWW-Authenticate: Digest
+ realm="testrealm@host.com",
+ qop="auth,auth-int",
+ nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
+ opaque="5ccc069c403ebaf9f0171e9517f40e41"
+
+ The client may prompt the user for the username and password, after
+ which it will respond with a new request, including the following
+ Authorization header:
+
+
+
+
+
+Franks, et al. Standards Track [Page 18]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ Authorization: Digest username="Mufasa",
+ realm="testrealm@host.com",
+ nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
+ uri="/dir/index.html",
+ qop=auth,
+ nc=00000001,
+ cnonce="0a4f113b",
+ response="6629fae49393a05397450978507c4ef1",
+ opaque="5ccc069c403ebaf9f0171e9517f40e41"
+
+3.6 Proxy-Authentication and Proxy-Authorization
+
+ The digest authentication scheme may also be used for authenticating
+ users to proxies, proxies to proxies, or proxies to origin servers by
+ use of the Proxy-Authenticate and Proxy-Authorization headers. These
+ headers are instances of the Proxy-Authenticate and Proxy-
+ Authorization headers specified in sections 10.33 and 10.34 of the
+ HTTP/1.1 specification [2] and their behavior is subject to
+ restrictions described there. The transactions for proxy
+ authentication are very similar to those already described. Upon
+ receiving a request which requires authentication, the proxy/server
+ must issue the "407 Proxy Authentication Required" response with a
+ "Proxy-Authenticate" header. The digest-challenge used in the
+ Proxy-Authenticate header is the same as that for the WWW-
+ Authenticate header as defined above in section 3.2.1.
+
+ The client/proxy must then re-issue the request with a Proxy-
+ Authorization header, with directives as specified for the
+ Authorization header in section 3.2.2 above.
+
+ On subsequent responses, the server sends Proxy-Authentication-Info
+ with directives the same as those for the Authentication-Info header
+ field.
+
+ Note that in principle a client could be asked to authenticate itself
+ to both a proxy and an end-server, but never in the same response.
+
+4 Security Considerations
+
+4.1 Authentication of Clients using Basic Authentication
+
+ The Basic authentication scheme is not a secure method of user
+ authentication, nor does it in any way protect the entity, which is
+ transmitted in cleartext across the physical network used as the
+ carrier. HTTP does not prevent additional authentication schemes and
+ encryption mechanisms from being employed to increase security or the
+ addition of enhancements (such as schemes to use one-time passwords)
+ to Basic authentication.
+
+
+
+Franks, et al. Standards Track [Page 19]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ The most serious flaw in Basic authentication is that it results in
+ the essentially cleartext transmission of the user's password over
+ the physical network. It is this problem which Digest Authentication
+ attempts to address.
+
+ Because Basic authentication involves the cleartext transmission of
+ passwords it SHOULD NOT be used (without enhancements) to protect
+ sensitive or valuable information.
+
+ A common use of Basic authentication is for identification purposes
+ -- requiring the user to provide a user name and password as a means
+ of identification, for example, for purposes of gathering accurate
+ usage statistics on a server. When used in this way it is tempting to
+ think that there is no danger in its use if illicit access to the
+ protected documents is not a major concern. This is only correct if
+ the server issues both user name and password to the users and in
+ particular does not allow the user to choose his or her own password.
+ The danger arises because naive users frequently reuse a single
+ password to avoid the task of maintaining multiple passwords.
+
+ If a server permits users to select their own passwords, then the
+ threat is not only unauthorized access to documents on the server but
+ also unauthorized access to any other resources on other systems that
+ the user protects with the same password. Furthermore, in the
+ server's password database, many of the passwords may also be users'
+ passwords for other sites. The owner or administrator of such a
+ system could therefore expose all users of the system to the risk of
+ unauthorized access to all those sites if this information is not
+ maintained in a secure fashion.
+
+ Basic Authentication is also vulnerable to spoofing by counterfeit
+ servers. If a user can be led to believe that he is connecting to a
+ host containing information protected by Basic authentication when,
+ in fact, he is connecting to a hostile server or gateway, then the
+ attacker can request a password, store it for later use, and feign an
+ error. This type of attack is not possible with Digest
+ Authentication. Server implementers SHOULD guard against the
+ possibility of this sort of counterfeiting by gateways or CGI
+ scripts. In particular it is very dangerous for a server to simply
+ turn over a connection to a gateway. That gateway can then use the
+ persistent connection mechanism to engage in multiple transactions
+ with the client while impersonating the original server in a way that
+ is not detectable by the client.
+
+4.2 Authentication of Clients using Digest Authentication
+
+ Digest Authentication does not provide a strong authentication
+ mechanism, when compared to public key based mechanisms, for example.
+
+
+
+Franks, et al. Standards Track [Page 20]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ However, it is significantly stronger than (e.g.) CRAM-MD5, which has
+ been proposed for use with LDAP [10], POP and IMAP (see RFC 2195
+ [9]). It is intended to replace the much weaker and even more
+ dangerous Basic mechanism.
+
+ Digest Authentication offers no confidentiality protection beyond
+ protecting the actual password. All of the rest of the request and
+ response are available to an eavesdropper.
+
+ Digest Authentication offers only limited integrity protection for
+ the messages in either direction. If qop=auth-int mechanism is used,
+ those parts of the message used in the calculation of the WWW-
+ Authenticate and Authorization header field response directive values
+ (see section 3.2 above) are protected. Most header fields and their
+ values could be modified as a part of a man-in-the-middle attack.
+
+ Many needs for secure HTTP transactions cannot be met by Digest
+ Authentication. For those needs TLS or SHTTP are more appropriate
+ protocols. In particular Digest authentication cannot be used for any
+ transaction requiring confidentiality protection. Nevertheless many
+ functions remain for which Digest authentication is both useful and
+ appropriate. Any service in present use that uses Basic should be
+ switched to Digest as soon as practical.
+
+4.3 Limited Use Nonce Values
+
+ The Digest scheme uses a server-specified nonce to seed the
+ generation of the request-digest value (as specified in section
+ 3.2.2.1 above). As shown in the example nonce in section 3.2.1, the
+ server is free to construct the nonce such that it may only be used
+ from a particular client, for a particular resource, for a limited
+ period of time or number of uses, or any other restrictions. Doing
+ so strengthens the protection provided against, for example, replay
+ attacks (see 4.5). However, it should be noted that the method
+ chosen for generating and checking the nonce also has performance and
+ resource implications. For example, a server may choose to allow
+ each nonce value to be used only once by maintaining a record of
+ whether or not each recently issued nonce has been returned and
+ sending a next-nonce directive in the Authentication-Info header
+ field of every response. This protects against even an immediate
+ replay attack, but has a high cost checking nonce values, and perhaps
+ more important will cause authentication failures for any pipelined
+ requests (presumably returning a stale nonce indication). Similarly,
+ incorporating a request-specific element such as the Etag value for a
+ resource limits the use of the nonce to that version of the resource
+ and also defeats pipelining. Thus it may be useful to do so for
+ methods with side effects but have unacceptable performance for those
+ that do not.
+
+
+
+Franks, et al. Standards Track [Page 21]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+4.4 Comparison of Digest with Basic Authentication
+
+ Both Digest and Basic Authentication are very much on the weak end of
+ the security strength spectrum. But a comparison between the two
+ points out the utility, even necessity, of replacing Basic by Digest.
+
+ The greatest threat to the type of transactions for which these
+ protocols are used is network snooping. This kind of transaction
+ might involve, for example, online access to a database whose use is
+ restricted to paying subscribers. With Basic authentication an
+ eavesdropper can obtain the password of the user. This not only
+ permits him to access anything in the database, but, often worse,
+ will permit access to anything else the user protects with the same
+ password.
+
+ By contrast, with Digest Authentication the eavesdropper only gets
+ access to the transaction in question and not to the user's password.
+ The information gained by the eavesdropper would permit a replay
+ attack, but only with a request for the same document, and even that
+ may be limited by the server's choice of nonce.
+
+4.5 Replay Attacks
+
+ A replay attack against Digest authentication would usually be
+ pointless for a simple GET request since an eavesdropper would
+ already have seen the only document he could obtain with a replay.
+ This is because the URI of the requested document is digested in the
+ client request and the server will only deliver that document. By
+ contrast under Basic Authentication once the eavesdropper has the
+ user's password, any document protected by that password is open to
+ him.
+
+ Thus, for some purposes, it is necessary to protect against replay
+ attacks. A good Digest implementation can do this in various ways.
+ The server created "nonce" value is implementation dependent, but if
+ it contains a digest of the client IP, a time-stamp, the resource
+ ETag, and a private server key (as recommended above) then a replay
+ attack is not simple. An attacker must convince the server that the
+ request is coming from a false IP address and must cause the server
+ to deliver the document to an IP address different from the address
+ to which it believes it is sending the document. An attack can only
+ succeed in the period before the time-stamp expires. Digesting the
+ client IP and time-stamp in the nonce permits an implementation which
+ does not maintain state between transactions.
+
+ For applications where no possibility of replay attack can be
+ tolerated the server can use one-time nonce values which will not be
+ honored for a second use. This requires the overhead of the server
+
+
+
+Franks, et al. Standards Track [Page 22]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ remembering which nonce values have been used until the nonce time-
+ stamp (and hence the digest built with it) has expired, but it
+ effectively protects against replay attacks.
+
+ An implementation must give special attention to the possibility of
+ replay attacks with POST and PUT requests. Unless the server employs
+ one-time or otherwise limited-use nonces and/or insists on the use of
+ the integrity protection of qop=auth-int, an attacker could replay
+ valid credentials from a successful request with counterfeit form
+ data or other message body. Even with the use of integrity protection
+ most metadata in header fields is not protected. Proper nonce
+ generation and checking provides some protection against replay of
+ previously used valid credentials, but see 4.8.
+
+4.6 Weakness Created by Multiple Authentication Schemes
+
+ An HTTP/1.1 server may return multiple challenges with a 401
+ (Authenticate) response, and each challenge may use a different
+ auth-scheme. A user agent MUST choose to use the strongest auth-
+ scheme it understands and request credentials from the user based
+ upon that challenge.
+
+ Note that many browsers will only recognize Basic and will require
+ that it be the first auth-scheme presented. Servers should only
+ include Basic if it is minimally acceptable.
+
+ When the server offers choices of authentication schemes using the
+ WWW-Authenticate header, the strength of the resulting authentication
+ is only as good as that of the of the weakest of the authentication
+ schemes. See section 4.8 below for discussion of particular attack
+ scenarios that exploit multiple authentication schemes.
+
+4.7 Online dictionary attacks
+
+ If the attacker can eavesdrop, then it can test any overheard
+ nonce/response pairs against a list of common words. Such a list is
+ usually much smaller than the total number of possible passwords. The
+ cost of computing the response for each password on the list is paid
+ once for each challenge.
+
+ The server can mitigate this attack by not allowing users to select
+ passwords that are in a dictionary.
+
+
+
+
+
+
+
+
+
+Franks, et al. Standards Track [Page 23]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+4.8 Man in the Middle
+
+ Both Basic and Digest authentication are vulnerable to "man in the
+ middle" (MITM) attacks, for example, from a hostile or compromised
+ proxy. Clearly, this would present all the problems of eavesdropping.
+ But it also offers some additional opportunities to the attacker.
+
+ A possible man-in-the-middle attack would be to add a weak
+ authentication scheme to the set of choices, hoping that the client
+ will use one that exposes the user's credentials (e.g. password). For
+ this reason, the client should always use the strongest scheme that
+ it understands from the choices offered.
+
+ An even better MITM attack would be to remove all offered choices,
+ replacing them with a challenge that requests only Basic
+ authentication, then uses the cleartext credentials from the Basic
+ authentication to authenticate to the origin server using the
+ stronger scheme it requested. A particularly insidious way to mount
+ such a MITM attack would be to offer a "free" proxy caching service
+ to gullible users.
+
+ User agents should consider measures such as presenting a visual
+ indication at the time of the credentials request of what
+ authentication scheme is to be used, or remembering the strongest
+ authentication scheme ever requested by a server and produce a
+ warning message before using a weaker one. It might also be a good
+ idea for the user agent to be configured to demand Digest
+ authentication in general, or from specific sites.
+
+ Or, a hostile proxy might spoof the client into making a request the
+ attacker wanted rather than one the client wanted. Of course, this is
+ still much harder than a comparable attack against Basic
+ Authentication.
+
+4.9 Chosen plaintext attacks
+
+ With Digest authentication, a MITM or a malicious server can
+ arbitrarily choose the nonce that the client will use to compute the
+ response. This is called a "chosen plaintext" attack. The ability to
+ choose the nonce is known to make cryptanalysis much easier [8].
+
+ However, no way to analyze the MD5 one-way function used by Digest
+ using chosen plaintext is currently known.
+
+ The countermeasure against this attack is for clients to be
+ configured to require the use of the optional "cnonce" directive;
+ this allows the client to vary the input to the hash in a way not
+ chosen by the attacker.
+
+
+
+Franks, et al. Standards Track [Page 24]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+4.10 Precomputed dictionary attacks
+
+ With Digest authentication, if the attacker can execute a chosen
+ plaintext attack, the attacker can precompute the response for many
+ common words to a nonce of its choice, and store a dictionary of
+ (response, password) pairs. Such precomputation can often be done in
+ parallel on many machines. It can then use the chosen plaintext
+ attack to acquire a response corresponding to that challenge, and
+ just look up the password in the dictionary. Even if most passwords
+ are not in the dictionary, some might be. Since the attacker gets to
+ pick the challenge, the cost of computing the response for each
+ password on the list can be amortized over finding many passwords. A
+ dictionary with 100 million password/response pairs would take about
+ 3.2 gigabytes of disk storage.
+
+ The countermeasure against this attack is to for clients to be
+ configured to require the use of the optional "cnonce" directive.
+
+4.11 Batch brute force attacks
+
+ With Digest authentication, a MITM can execute a chosen plaintext
+ attack, and can gather responses from many users to the same nonce.
+ It can then find all the passwords within any subset of password
+ space that would generate one of the nonce/response pairs in a single
+ pass over that space. It also reduces the time to find the first
+ password by a factor equal to the number of nonce/response pairs
+ gathered. This search of the password space can often be done in
+ parallel on many machines, and even a single machine can search large
+ subsets of the password space very quickly -- reports exist of
+ searching all passwords with six or fewer letters in a few hours.
+
+ The countermeasure against this attack is to for clients to be
+ configured to require the use of the optional "cnonce" directive.
+
+4.12 Spoofing by Counterfeit Servers
+
+ Basic Authentication is vulnerable to spoofing by counterfeit
+ servers. If a user can be led to believe that she is connecting to a
+ host containing information protected by a password she knows, when
+ in fact she is connecting to a hostile server, then the hostile
+ server can request a password, store it away for later use, and feign
+ an error. This type of attack is more difficult with Digest
+ Authentication -- but the client must know to demand that Digest
+ authentication be used, perhaps using some of the techniques
+ described above to counter "man-in-the-middle" attacks. Again, the
+ user can be helped in detecting this attack by a visual indication of
+ the authentication mechanism in use with appropriate guidance in
+ interpreting the implications of each scheme.
+
+
+
+Franks, et al. Standards Track [Page 25]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+4.13 Storing passwords
+
+ Digest authentication requires that the authenticating agent (usually
+ the server) store some data derived from the user's name and password
+ in a "password file" associated with a given realm. Normally this
+ might contain pairs consisting of username and H(A1), where H(A1) is
+ the digested value of the username, realm, and password as described
+ above.
+
+ The security implications of this are that if this password file is
+ compromised, then an attacker gains immediate access to documents on
+ the server using this realm. Unlike, say a standard UNIX password
+ file, this information need not be decrypted in order to access
+ documents in the server realm associated with this file. On the other
+ hand, decryption, or more likely a brute force attack, would be
+ necessary to obtain the user's password. This is the reason that the
+ realm is part of the digested data stored in the password file. It
+ means that if one Digest authentication password file is compromised,
+ it does not automatically compromise others with the same username
+ and password (though it does expose them to brute force attack).
+
+ There are two important security consequences of this. First the
+ password file must be protected as if it contained unencrypted
+ passwords, because for the purpose of accessing documents in its
+ realm, it effectively does.
+
+ A second consequence of this is that the realm string should be
+ unique among all realms which any single user is likely to use. In
+ particular a realm string should include the name of the host doing
+ the authentication. The inability of the client to authenticate the
+ server is a weakness of Digest Authentication.
+
+4.14 Summary
+
+ By modern cryptographic standards Digest Authentication is weak. But
+ for a large range of purposes it is valuable as a replacement for
+ Basic Authentication. It remedies some, but not all, weaknesses of
+ Basic Authentication. Its strength may vary depending on the
+ implementation. In particular the structure of the nonce (which is
+ dependent on the server implementation) may affect the ease of
+ mounting a replay attack. A range of server options is appropriate
+ since, for example, some implementations may be willing to accept the
+ server overhead of one-time nonces or digests to eliminate the
+ possibility of replay. Others may satisfied with a nonce like the one
+ recommended above restricted to a single IP address and a single ETag
+ or with a limited lifetime.
+
+
+
+
+
+Franks, et al. Standards Track [Page 26]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ The bottom line is that *any* compliant implementation will be
+ relatively weak by cryptographic standards, but *any* compliant
+ implementation will be far superior to Basic Authentication.
+
+5 Sample implementation
+
+ The following code implements the calculations of H(A1), H(A2),
+ request-digest and response-digest, and a test program which computes
+ the values used in the example of section 3.5. It uses the MD5
+ implementation from RFC 1321.
+
+ File "digcalc.h":
+
+#define HASHLEN 16
+typedef char HASH[HASHLEN];
+#define HASHHEXLEN 32
+typedef char HASHHEX[HASHHEXLEN+1];
+#define IN
+#define OUT
+
+/* calculate H(A1) as per HTTP Digest spec */
+void DigestCalcHA1(
+ IN char * pszAlg,
+ IN char * pszUserName,
+ IN char * pszRealm,
+ IN char * pszPassword,
+ IN char * pszNonce,
+ IN char * pszCNonce,
+ OUT HASHHEX SessionKey
+ );
+
+/* calculate request-digest/response-digest as per HTTP Digest spec */
+void DigestCalcResponse(
+ IN HASHHEX HA1, /* H(A1) */
+ IN char * pszNonce, /* nonce from server */
+ IN char * pszNonceCount, /* 8 hex digits */
+ IN char * pszCNonce, /* client nonce */
+ IN char * pszQop, /* qop-value: "", "auth", "auth-int" */
+ IN char * pszMethod, /* method from the request */
+ IN char * pszDigestUri, /* requested URL */
+ IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */
+ OUT HASHHEX Response /* request-digest or response-digest */
+ );
+
+File "digcalc.c":
+
+#include <global.h>
+#include <md5.h>
+
+
+
+Franks, et al. Standards Track [Page 27]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+#include <string.h>
+#include "digcalc.h"
+
+void CvtHex(
+ IN HASH Bin,
+ OUT HASHHEX Hex
+ )
+{
+ unsigned short i;
+ unsigned char j;
+
+ for (i = 0; i < HASHLEN; i++) {
+ j = (Bin[i] >> 4) & 0xf;
+ if (j <= 9)
+ Hex[i*2] = (j + '0');
+ else
+ Hex[i*2] = (j + 'a' - 10);
+ j = Bin[i] & 0xf;
+ if (j <= 9)
+ Hex[i*2+1] = (j + '0');
+ else
+ Hex[i*2+1] = (j + 'a' - 10);
+ };
+ Hex[HASHHEXLEN] = '\0';
+};
+
+/* calculate H(A1) as per spec */
+void DigestCalcHA1(
+ IN char * pszAlg,
+ IN char * pszUserName,
+ IN char * pszRealm,
+ IN char * pszPassword,
+ IN char * pszNonce,
+ IN char * pszCNonce,
+ OUT HASHHEX SessionKey
+ )
+{
+ MD5_CTX Md5Ctx;
+ HASH HA1;
+
+ MD5Init(&Md5Ctx);
+ MD5Update(&Md5Ctx, pszUserName, strlen(pszUserName));
+ MD5Update(&Md5Ctx, ":", 1);
+ MD5Update(&Md5Ctx, pszRealm, strlen(pszRealm));
+ MD5Update(&Md5Ctx, ":", 1);
+ MD5Update(&Md5Ctx, pszPassword, strlen(pszPassword));
+ MD5Final(HA1, &Md5Ctx);
+ if (stricmp(pszAlg, "md5-sess") == 0) {
+
+
+
+Franks, et al. Standards Track [Page 28]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ MD5Init(&Md5Ctx);
+ MD5Update(&Md5Ctx, HA1, HASHLEN);
+ MD5Update(&Md5Ctx, ":", 1);
+ MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
+ MD5Update(&Md5Ctx, ":", 1);
+ MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
+ MD5Final(HA1, &Md5Ctx);
+ };
+ CvtHex(HA1, SessionKey);
+};
+
+/* calculate request-digest/response-digest as per HTTP Digest spec */
+void DigestCalcResponse(
+ IN HASHHEX HA1, /* H(A1) */
+ IN char * pszNonce, /* nonce from server */
+ IN char * pszNonceCount, /* 8 hex digits */
+ IN char * pszCNonce, /* client nonce */
+ IN char * pszQop, /* qop-value: "", "auth", "auth-int" */
+ IN char * pszMethod, /* method from the request */
+ IN char * pszDigestUri, /* requested URL */
+ IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */
+ OUT HASHHEX Response /* request-digest or response-digest */
+ )
+{
+ MD5_CTX Md5Ctx;
+ HASH HA2;
+ HASH RespHash;
+ HASHHEX HA2Hex;
+
+ // calculate H(A2)
+ MD5Init(&Md5Ctx);
+ MD5Update(&Md5Ctx, pszMethod, strlen(pszMethod));
+ MD5Update(&Md5Ctx, ":", 1);
+ MD5Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri));
+ if (stricmp(pszQop, "auth-int") == 0) {
+ MD5Update(&Md5Ctx, ":", 1);
+ MD5Update(&Md5Ctx, HEntity, HASHHEXLEN);
+ };
+ MD5Final(HA2, &Md5Ctx);
+ CvtHex(HA2, HA2Hex);
+
+ // calculate response
+ MD5Init(&Md5Ctx);
+ MD5Update(&Md5Ctx, HA1, HASHHEXLEN);
+ MD5Update(&Md5Ctx, ":", 1);
+ MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
+ MD5Update(&Md5Ctx, ":", 1);
+ if (*pszQop) {
+
+
+
+Franks, et al. Standards Track [Page 29]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ MD5Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount));
+ MD5Update(&Md5Ctx, ":", 1);
+ MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
+ MD5Update(&Md5Ctx, ":", 1);
+ MD5Update(&Md5Ctx, pszQop, strlen(pszQop));
+ MD5Update(&Md5Ctx, ":", 1);
+ };
+ MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN);
+ MD5Final(RespHash, &Md5Ctx);
+ CvtHex(RespHash, Response);
+};
+
+File "digtest.c":
+
+
+#include <stdio.h>
+#include "digcalc.h"
+
+void main(int argc, char ** argv) {
+
+ char * pszNonce = "dcd98b7102dd2f0e8b11d0f600bfb0c093";
+ char * pszCNonce = "0a4f113b";
+ char * pszUser = "Mufasa";
+ char * pszRealm = "testrealm@host.com";
+ char * pszPass = "Circle Of Life";
+ char * pszAlg = "md5";
+ char szNonceCount[9] = "00000001";
+ char * pszMethod = "GET";
+ char * pszQop = "auth";
+ char * pszURI = "/dir/index.html";
+ HASHHEX HA1;
+ HASHHEX HA2 = "";
+ HASHHEX Response;
+
+ DigestCalcHA1(pszAlg, pszUser, pszRealm, pszPass, pszNonce,
+pszCNonce, HA1);
+ DigestCalcResponse(HA1, pszNonce, szNonceCount, pszCNonce, pszQop,
+ pszMethod, pszURI, HA2, Response);
+ printf("Response = %s\n", Response);
+};
+
+
+
+
+
+
+
+
+
+
+
+Franks, et al. Standards Track [Page 30]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+6 Acknowledgments
+
+ Eric W. Sink, of AbiSource, Inc., was one of the original authors
+ before the specification underwent substantial revision.
+
+ In addition to the authors, valuable discussion instrumental in
+ creating this document has come from Peter J. Churchyard, Ned Freed,
+ and David M. Kristol.
+
+ Jim Gettys and Larry Masinter edited this document for update.
+
+7 References
+
+ [1] Berners-Lee, T., Fielding, R. and H. Frystyk, "Hypertext
+ Transfer Protocol -- HTTP/1.0", RFC 1945, May 1996.
+
+ [2] Fielding, R., Gettys, J., Mogul, J., Frysyk, H., Masinter, L.,
+ Leach, P. and T. Berners-Lee, "Hypertext Transfer Protocol --
+ HTTP/1.1", RFC 2616, June 1999.
+
+ [3] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, April
+ 1992.
+
+ [4] Freed, N. and N. Borenstein. "Multipurpose Internet Mail
+ Extensions (MIME) Part One: Format of Internet Message Bodies",
+ RFC 2045, November 1996.
+
+ [5] Dierks, T. and C. Allen "The TLS Protocol, Version 1.0", RFC
+ 2246, January 1999.
+
+ [6] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P.,
+ Luotonen, A., Sink, E. and L. Stewart, "An Extension to HTTP :
+ Digest Access Authentication", RFC 2069, January 1997.
+
+ [7] Berners Lee, T, Fielding, R. and L. Masinter, "Uniform Resource
+ Identifiers (URI): Generic Syntax", RFC 2396, August 1998.
+
+ [8] Kaliski, B.,Robshaw, M., "Message Authentication with MD5",
+ CryptoBytes, Sping 1995, RSA Inc,
+ (http://www.rsa.com/rsalabs/pubs/cryptobytes/spring95/md5.htm)
+
+ [9] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP AUTHorize
+ Extension for Simple Challenge/Response", RFC 2195, September
+ 1997.
+
+ [10] Morgan, B., Alvestrand, H., Hodges, J., Wahl, M.,
+ "Authentication Methods for LDAP", Work in Progress.
+
+
+
+
+Franks, et al. Standards Track [Page 31]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+8 Authors' Addresses
+
+ John Franks
+ Professor of Mathematics
+ Department of Mathematics
+ Northwestern University
+ Evanston, IL 60208-2730, USA
+
+ EMail: john@math.nwu.edu
+
+
+ Phillip M. Hallam-Baker
+ Principal Consultant
+ Verisign Inc.
+ 301 Edgewater Place
+ Suite 210
+ Wakefield MA 01880, USA
+
+ EMail: pbaker@verisign.com
+
+
+ Jeffery L. Hostetler
+ Software Craftsman
+ AbiSource, Inc.
+ 6 Dunlap Court
+ Savoy, IL 61874
+
+ EMail: jeff@AbiSource.com
+
+
+ Scott D. Lawrence
+ Agranat Systems, Inc.
+ 5 Clocktower Place, Suite 400
+ Maynard, MA 01754, USA
+
+ EMail: lawrence@agranat.com
+
+
+ Paul J. Leach
+ Microsoft Corporation
+ 1 Microsoft Way
+ Redmond, WA 98052, USA
+
+ EMail: paulle@microsoft.com
+
+
+
+
+
+
+
+Franks, et al. Standards Track [Page 32]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+ Ari Luotonen
+ Member of Technical Staff
+ Netscape Communications Corporation
+ 501 East Middlefield Road
+ Mountain View, CA 94043, USA
+
+
+ Lawrence C. Stewart
+ Open Market, Inc.
+ 215 First Street
+ Cambridge, MA 02142, USA
+
+ EMail: stewart@OpenMarket.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Franks, et al. Standards Track [Page 33]
+
+RFC 2617 HTTP Authentication June 1999
+
+
+9. Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Franks, et al. Standards Track [Page 34]
+
diff --git a/standards/rfc2639.txt b/standards/rfc2639.txt
new file mode 100644
index 000000000..e3ab71684
--- /dev/null
+++ b/standards/rfc2639.txt
@@ -0,0 +1,3587 @@
+
+
+
+
+
+
+Network Working Group T. Hastings
+Request for Comments: 2639 C. Manros
+Category: Informational Xerox Corporation
+ July 1999
+
+
+ Internet Printing Protocol/1.0: Implementer's Guide
+
+Status of this Memo
+
+ This memo provides information for the Internet community. It does
+ not specify an Internet standard of any kind. Distribution of this
+ memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+Abstract
+
+ This document is one of a set of documents, which together describe
+ all aspects of a new Internet Printing Protocol (IPP). IPP is an
+ application level protocol that can be used for distributed printing
+ using Internet tools and technologies. This document contains
+ information that supplements the IPP Model and Semantics [RFC2566]
+ and the IPP Transport and Encoding [RFC2565] documents. It is
+ intended to help implementers understand IPP/1.0 and some of the
+ considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.0: Model and Semantics [RFC2566]
+ Internet Printing Protocol/1.0: Encoding and Transport [RFC2565]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ The document, "Design Goals for an Internet Printing Protocol", takes
+ a broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+
+
+
+
+
+Hastings & Manros Informational [Page 1]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ administrators. The design goals document calls out a subset of end
+ user requirements that are satisfied in IPP/1.0. Operator and
+ administrator requirements are out of scope for version 1.0.
+
+ The document, "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specifications, and gives background and rationale for the
+ IETF working group's major decisions.
+
+ The document, "Internet Printing Protocol/1.0: Model and Semantics",
+ describes a simplified model with abstract objects, their attributes,
+ and their operations. The model introduces a Printer and a Job. The
+ Job supports multiple documents per Job. The model document also
+ addresses how security, internationalization, and directory issues
+ are addressed.
+
+ The document, "Internet Printing Protocol/1.0: Encoding and
+ Transport", is a formal mapping of the abstract operations and
+ attributes defined in the model document onto HTTP/1.1. It also
+ defines the encoding rules for a new Internet media type called
+ "application/ipp".
+
+ The document, "Mapping between LPD and IPP Protocols", gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+Table of Contents
+
+ 1 Introduction......................................................4
+ 1.1 Conformance language............................................4
+ 1.2 Other terminology...............................................5
+ 2 Model and Semantics...............................................5
+ 2.1 Summary of Operation Attributes.................................5
+ 2.2 Suggested Operation Processing Steps for IPP Objects ..........10
+ 2.2.1 Suggested Operation Processing Steps for all Operations..11
+ 2.2.1.1 Validate version number...............................11
+ 2.2.1.2 Validate operation identifier.........................11
+ 2.2.1.3 Validate the request identifier.......................11
+ 2.2.1.4 Validate attribute group and attribute presence and
+ order.................................................12
+ 2.2.1.5 Validate the values of the REQUIRED Operation
+ attributes............................................19
+ 2.2.1.6 Validate the values of the OPTIONAL Operation
+ attributes............................................23
+ 2.2.2 Suggested Additional Processing Steps for Operations that
+ Create/Validate Jobs and Add Documents.....................26
+ 2.2.2.1 Default "ipp-attribute-fidelity" if not supplied......26
+
+
+
+Hastings & Manros Informational [Page 2]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ 2.2.2.2 Check that the Printer object is accepting jobs.......26
+ 2.2.2.3 Validate the values of the Job Template attributes....26
+ 2.2.3 Algorithm for job validation...............................27
+ 2.2.3.1 Check for conflicting Job Template attributes values..33
+ 2.2.3.2 Decide whether to REJECT the request..................33
+ 2.2.3.3 For the Validate-Job operation, RETURN one of the
+ success status codes..................................34
+ 2.2.3.4 Create the Job object with attributes to support......34
+ 2.2.3.5 Return one of the success status codes................36
+ 2.2.3.6 Accept appended Document Content......................36
+ 2.2.3.7 Scheduling and Starting to Process the Job............36
+ 2.2.3.8 Completing the Job....................................37
+ 2.2.3.9 Destroying the Job after completion...................37
+ 2.2.3.10 Interaction with "ipp-attribute-fidelity".............37
+ 2.3 Status codes returned by operation ............................37
+ 2.3.1 Printer Operations.........................................38
+ 2.3.1.1 Print-Job.............................................38
+ 2.3.1.2 Print-URI.............................................40
+ 2.3.1.3 Validate-Job..........................................40
+ 2.3.1.4 Create-Job............................................41
+ 2.3.1.5 Get-Printer-Attributes................................41
+ 2.3.1.6 Get-Jobs..............................................42
+ 2.3.2 Job Operations.............................................43
+ 2.3.2.1 Send-Document.........................................43
+ 2.3.2.2 Send-URI..............................................44
+ 2.3.2.3 Cancel-Job............................................44
+ 2.3.2.4 Get-Job-Attributes....................................45
+ 2.4 Validate-Job...................................................46
+ 2.5 Case Sensitivity in URIs ......................................46
+ 2.6 Character Sets, natural languages, and internationalization....46
+ 2.6.1 Character set code conversion support .....................46
+ 2.6.2 What charset to return when an unsupported charset is
+ requested?.................................................48
+ 2.6.3 Natural Language Override (NLO) ...........................48
+ 2.7 The "queued-job-count" Printer Description attribute...........50
+ 2.7.1 Why is "queued-job-count" RECOMMENDED?.....................50
+ 2.7.2 Is "queued-job-count" a good measure of how busy a printer
+ is?........................................................50
+ 2.8 Sending empty attribute groups ................................50
+ 2.9 Returning unsupported attributes in Get-Xxxx responses ........51
+ 2.10 Returning job-state in Print-Job response ....................51
+ 2.11 Flow controlling the data portion of a Print-Job request .....52
+ 2.12 Multi-valued attributes ......................................53
+ 2.13 Querying jobs with IPP that were submitted using other job
+ submission protocols .........................................53
+ 2.14 The 'none' value for empty sets ..............................54
+ 2.15 Get-Jobs, my-jobs='true', and 'requesting-user-name'?.........54
+
+
+
+
+Hastings & Manros Informational [Page 3]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ 2.16 The "multiple-document-handling" Job Template attribute and
+ support of multiple document jobs.............................54
+ 3 Encoding and Transport...........................................55
+ 3.1 General Headers................................................56
+ 3.2 Request Headers...............................................57
+ 3.3 Response Headers...............................................58
+ 3.4 Entity Headers................................................59
+ 3.5 Optional support for HTTP/1.0..................................60
+ 3.6 HTTP/1.1 Chunking..............................................60
+ 3.6.1 Disabling IPP Server Response Chunking.....................60
+ 3.6.2 Warning About the Support of Chunked Requests..............60
+ 4 References.......................................................61
+ 4.1 Authors' Addresses.............................................62
+ 5 Security Considerations..........................................62
+ 6 Notices..........................................................62
+ Full Copyright Statement............................................65
+
+1 Introduction
+
+ This document contains information that supplements the IPP Model and
+ Semantics [RFC2566] and the IPP Transport and Encoding [RFC2565]
+ documents. As such this information is not part of the formal
+ specifications. Instead information is presented to help implementers
+ understand the specification, including some of the motivation for
+ decisions taken by the committee in developing the specification.
+ Some of the implementation considerations are intended to help
+ implementers design their client and/or IPP object implementations.
+ If there are any contradictions between this document and [RFC2566] or
+ [RFC2565], those documents take precedence over this document.
+
+1.1 Conformance language
+
+ Usually, this document does not contain the terminology MUST, MUST
+ NOT, MAY, NEED NOT, SHOULD, SHOULD NOT, REQUIRED, and OPTIONAL.
+ However, when those terms do appear in this document, their intent is
+ to repeat what the [RFC2566] and [RFC2565] documents require and
+ allow, rather than specifying additional conformance requirements.
+ These terms are defined in section 13 on conformance terminology in
+ [RFC2566], most of which is taken from RFC 2119 [RFC2119].
+
+ Implementers should read section 13 in [RFC2566] in order to
+ understand these capitalized words. The words MUST, MUST NOT, and
+ REQUIRED indicate what implementations are required to support in a
+ client or IPP object in order to be conformant to [RFC2566] and
+ [RFC2565]. MAY, NEED NOT, and OPTIONAL indicate was is merely allowed
+ as an implementer option. The verbs SHOULD and SHOULD NOT indicate
+ suggested behavior, but which is not required or disallowed,
+ respectively, in order to conform to the specification.
+
+
+
+Hastings & Manros Informational [Page 4]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+1.2 Other terminology
+
+ The term "sender" refers to the client that sends a request or an IPP
+ object that returns a response. The term "receiver" refers to the IPP
+ object that receives a request and to a client that receives a
+ response.
+
+2 Model and Semantics
+
+ This section discusses various aspects of IPP/1.0 Model and Semantics
+ [RFC2566].
+
+2.1 Summary of Operation Attributes
+
+ Legend for the following table:
+
+ R indicates a REQUIRED operation or attribute for an
+ implementation to support
+
+ O indicates an OPTIONAL operation or attribute for an
+ implementation to support
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 5]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Table 1. Summary of operation attributes for Printer operations
+
+ Printer Operations
+
+ Requests Responses
+
+ Operation Print- Pri Crea Get- Get- All
+ Attributes Job, nt- te- Printer- Jobs Opera-
+ Validate URI Job Attribut tions
+ -Job (O) (O) es
+
+ Operation parameters--REQUIRED to be supplied by the sender
+
+ operation-id R R R R R
+
+ status-code R
+
+ request-id R R R R R R
+
+ version-number R R R R R R
+
+ Operation attributes-REQUIRED to be supplied by the sender
+
+ attributes-charset R R R R R R
+
+ attributes- R R R R R R
+ natural-language
+
+ document-uri R
+
+ job-id*
+
+ job-uri*
+
+ last-document
+
+ printer-uri R R R R R
+
+ Operation attributes-RECOMMENDED to be supplied by the sender
+
+ job-name R R R
+
+ requesting-user- R R R R R
+ name
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 6]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Printer Operations
+
+ Requests Responses
+
+ Operation Print- Pri Crea Get- Get- All
+ Attributes Job, nt- te- Printer Jobs Opera-
+ Vali- URI Job Attri- tions
+ date-Job (O) (O) butes
+
+ Operation attributes-OPTIONAL to be supplied by the sender
+
+ status-message O
+
+ compression O O
+
+ document-format R R O
+
+ document-name O O
+
+ document-natural- O O
+ language
+
+ ipp-attribute- R R R
+ fidelity
+
+ job-impressions O O O
+
+ job-k-octets O O O
+
+ job-media-sheets O O O
+
+ limit R
+
+ message
+
+ my-jobs R
+
+ requested- R R
+ attributes
+
+ which-jobs R
+
+ * "job-id" is REQUIRED only if used together with
+ "printer-uri" to identify the target job; otherwise, "job-
+ uri" is REQUIRED.
+
+
+
+
+
+
+Hastings & Manros Informational [Page 7]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Table 2. Summary of operation attributes for Job operations
+
+
+ Requests Responses
+
+ Operation Send- Send- Cancel Get- All
+ Attributes Document URI -Job Job- Opera-
+ (O) (O) Attri- tions
+ butes
+
+ Operation parameters--REQUIRED to be supplied by the sender
+
+ operation-id R R R R
+
+ status-code R
+
+ request-id R R R R R
+
+ version-number R R R R R
+
+ Operation attributes-REQUIRED to be supplied by the sender
+
+ attributes- R R R R R
+ charset
+
+ attributes- R R R R R
+ natural-language
+
+ document-uri R
+
+ job-id* R R R R
+
+ job-uri* R R R R
+
+ last-document R R
+
+ printer-uri R R R R
+
+ Operation attributes-RECOMMENDED to be supplied by the
+ sender
+
+ job-name
+
+ requesting-user- R R R R
+ name
+
+
+
+
+
+
+Hastings & Manros Informational [Page 8]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Job Operations
+
+ Requests Responses
+
+ Operation Attributes Send- Send- Cance Get- All
+ Document URI l-Job Job- Opera-
+ (O) (O) Attri- tions
+ butes
+
+ Operation attributes.OPTIONAL to be supplied by the sender
+
+ status-message O
+
+ compression O O
+
+ document-format R R
+
+ document-name O O
+
+ document-natural- O O
+ language
+
+ ipp-attribute-
+ fidelity
+
+ job-impressions
+
+ job-k-octets
+
+ job-media-sheets
+
+ limit
+
+ message O
+
+ my-jobs
+
+ requested-attributes R
+
+ which-jobs
+
+ * "job-id" is REQUIRED only if used together with "printer-
+ uri" to identify the target job; otherwise, "job-uri" is
+ REQUIRED.
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 9]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+2.2 Suggested Operation Processing Steps for IPP Objects
+
+ This section suggests the steps and error checks that an IPP object
+ MAY perform when processing requests and returning responses. An IPP
+ object MAY perform some or all of the error checks. However, some
+ implementations MAY choose to be more forgiving than the error checks
+ shown here, in order to be able to accept requests from non-
+ conforming clients. Not performing all of these error checks is a
+ so-called "forgiving" implementation. On the other hand, clients
+ that successfully submit requests to IPP objects that do perform all
+ the error checks will be more likely to be able to interoperate with
+ other IPP object implementations. Thus an implementer of an IPP
+ object needs to decide whether to be a "forgiving" or a "strict"
+ implementation. Therefore, the error status codes returned may
+ differ between implementations. Consequentially, client SHOULD NOT
+ expect exactly the error code processing described in this section.
+
+ When an IPP object receives a request, the IPP object either accepts
+ or rejects the request. In order to determine whether or not to
+ accept or reject the request, the IPP object SHOULD execute the
+ following steps. The order of the steps may be rearranged and/or
+ combined, including making one or multiple passes over the request.
+
+ A client MUST supply requests that would pass all of the error checks
+ indicated here in order to be a conforming client. Therefore, a
+ client SHOULD supply requests that are conforming, in order to avoid
+ being rejected by some IPP object implementations and/or risking
+ different semantics by different implementations of forgiving
+ implementations. For example, a forgiving implementation that
+ accepts multiple occurrences of the same attribute, rather than
+ rejecting the request might use the first occurrences, while another
+ might use the last occurrence. Thus such a non-conforming client
+ would get different results from the two forgiving implementations.
+
+ In the following, processing continues step by step until a "RETURNS
+ the xxx status code ." statement is encountered. Error returns are
+ indicated by the verb: "REJECTS". Since clients have difficulty
+ getting the status code before sending all of the document data in a
+ Print-Job request, clients SHOULD use the Validate-Job operation
+ before sending large documents to be printed, in order to validate
+ whether the IPP Printer will accept the job or not.
+
+ It is assumed that security authentication and authorization has
+ already taken place at a lower layer.
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 10]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+2.2.1 Suggested Operation Processing Steps for all Operations
+
+ This section is intended to apply to all operations. The next
+ section contains the additional steps for the Print-Job, Validate-
+ Job, Print-URI, Create-Job, Send-Document, and Send-URI operations
+ that create jobs, adds documents, and validates jobs.
+
+2.2.1.1 Validate version number
+
+ Every request and every response contains the "version-number"
+ attribute. The value of this attribute is the major and minor
+ version number of the syntax and semantics that the client and IPP
+ object is using, respectively. The "version-number" attribute
+ remains in a fixed position across all future versions so that all
+ clients and IPP object that support future versions can determine
+ which version is being used. The IPP object checks to see if the
+ major version number supplied in the request is supported. If not,
+ the Printer object REJECTS the request and RETURNS the 'server-
+ error-version-not-supported' status code in the response. The IPP
+ object returns in the "version-number" response attribute the major
+ and minor version for the error response. Thus the client can learn
+ at least one major and minor version that the IPP object supports.
+ The IPP object is encouraged to return the closest version number to
+ the one supplied by the client.
+
+ The checking of the minor version number is implementation dependent,
+ however if the client supplied minor version is explicitly supported,
+ the IPP object MUST respond using that identical minor version
+ number. If the requested minor version is not supported (the
+ requested minor version is either higher or lower) than a supported
+ minor version, the IPP object SHOULD return the closest supported
+ minor version.
+
+2.2.1.2 Validate operation identifier
+
+ The Printer object checks to see if the "operation-id" attribute
+ supplied by the client is supported as indicated in the Printer
+ object's "operations-supported" attribute. If not, the Printer
+ REJECTS the request and returns the 'server-error-operation-not-
+ supported' status code in the response.
+
+2.2.1.3 Validate the request identifier
+
+ The Printer object SHOULD NOT check to see if the "request-id"
+ attribute supplied by the client is in range: between 1 and 2**31 - 1
+ (inclusive), but copies all 32 bits.
+
+
+
+
+
+Hastings & Manros Informational [Page 11]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Note: The "version-number", "operation-id", and the "request-id"
+ parameters are in fixed octet positions in the IPP/1.0 encoding. The
+ "version-number" parameter will be the same fixed octet position in
+ all versions of the protocol. These fields are validated before
+ proceeding with the rest of the validation.
+
+2.2.1.4 Validate attribute group and attribute presence and order
+
+ The order of the following validation steps depends on
+ implementation.
+
+2.2.1.4.1 Validate the presence and order of attribute groups
+
+ Client requests and IPP object responses contain attribute groups
+ that Section 3 requires to be present and in a specified order. An
+ IPP object verifies that the attribute groups are present and in the
+ correct order in requests supplied by clients (attribute groups
+ without an * in the following tables).
+
+ If an IPP object receives a request with (1) required attribute
+ groups missing, or (2) the attributes groups are out of order, or (3)
+ the groups are repeated, the IPP object REJECTS the request and
+ RETURNS the 'client-error-bad-request' status code. For example, it
+ is an error for the Job Template Attributes group to occur before the
+ Operation Attributes group, for the Operation Attributes group to be
+ omitted, or for an attribute group to occur more than once, except in
+ the Get-Jobs response.
+
+ Since this kind of attribute group error is most likely to be an
+ error detected by a client developer rather than by a customer, the
+ IPP object NEED NOT return an indication of which attribute group was
+ in error in either the Unsupported Attributes group or the Status
+ Message. Also, the IPP object NEED NOT find all attribute group
+ errors before returning this error.
+
+2.2.1.4.2 Ignore unknown attribute groups in the expected position
+
+ Future attribute groups may be added to the specification at the end
+ of requests just before the Document Content and at the end of
+ response, except for the Get-Jobs response, where it maybe there or
+ before the first job attributes returned. If an IPP object receives
+ an unknown attribute group in these positions, it ignores the entire
+ group, rather than returning an error, since that group may be a new
+ group in a later minor version of the protocol that can be ignored.
+ (If the new attribute group cannot be ignored without confusing the
+ client, the major version number would have been increased in the
+
+
+
+
+
+Hastings & Manros Informational [Page 12]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ protocol document and in the request). If the unknown group occurs
+ in a different position, the IPP object REJECTS the request and
+ RETURNS the 'client-error-bad-request' status code.
+
+ Clients also ignore unknown attribute groups returned in a response.
+
+ Note: By validating that requests are in the proper form, IPP
+ objects force clients to use the proper form which, in turn,
+ increases the chances that customers will be able to use such clients
+ from multiple vendors with IPP objects from other vendors.
+
+2.2.1.4.3 Validate the presence of a single occurrence of required
+ Operation attributes
+
+ Client requests and IPP object responses contain Operation attributes
+ that [RFC2566] Section 3 requires to be present. Attributes within a
+ group may be in any order, except for the ordering of target,
+ charset, and natural languages attributes. These attributes MUST be
+ first, and MUST be supplied in the following order: charset, natural
+ language, and then target. An IPP object verifies that the attributes
+ that Section 4 requires to be supplied by the client have been
+ supplied in the request (attributes without an * in the following
+ tables). An asterisk (*) indicates groups and Operation attributes
+ that the client may omit in a request or an IPP object may omit in a
+ response.
+
+ If an IPP object receives a request with required attributes missing
+ or repeated from a group or in the wrong position, the behavior of
+ the IPP object is IMPLEMENTATION DEPENDENT. Some of the possible
+ implementations are:
+
+ 1.REJECTS the request and RETURNS the 'client-error-bad-request'
+ status code
+
+ 2.accepts the request and uses the first occurrence of the
+ attribute no matter where it is
+
+ 3.accepts the request and uses the last occurrence of the
+ attribute no matter where it is
+
+ 4.accept the request and assume some default value for the missing
+ attribute
+
+ Therefore, client MUST send conforming requests, if they want to
+ receive the same behavior from all IPP object implementations. For
+ example, it is an error for the "attributes-charset" or "attributes-
+ natural-language" attribute to be omitted in any operation request,
+ or for an Operation attribute to be supplied in a Job Template group
+
+
+
+Hastings & Manros Informational [Page 13]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ or a Job Template attribute to be supplied in an Operation Attribute
+ group in a create request. It is also an error to supply the
+ "attributes-charset" attribute twice.
+
+ Since these kinds of attribute errors are most likely to be detected
+ by a client developer rather than by a customer, the IPP object NEED
+ NOT return an indication of which attribute was in error in either
+ the Unsupported Attributes group or the Status Message. Also, the
+ IPP object NEED NOT find all attribute errors before returning this
+ error.
+
+ The following tables list all the attributes for all the operations
+ by attribute group in each request and each response. The order of
+ the groups is the order that the client supplies the groups as
+ specified in [RFC2566] Section 3. The order of the attributes within
+ a group is arbitrary, except as noted for some of the special
+ operation attributes (charset, natural language, and target). The
+ tables below use the following notation:
+
+ R indicates a REQUIRED attribute that an IPP object MUST support
+ O indicates an OPTIONAL attribute that an IPP object NEED NOT
+ support
+ * indicates that a client MAY omit the attribute in a request
+ and that an IPP object MAY omit the attribute in a
+ response. The absence of an * means that a client MUST
+ supply the attribute in a request and an IPP object MUST
+ supply the attribute in a response.
+
+ Operation Requests
+
+ The tables below show the attributes in their proper attribute groups
+ for operation requests:
+
+ Note: All operation requests contain "version-number", "operation-
+ id", and "request-id" parameters.
+
+ Print-Job Request:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ requesting-user-name (R*)
+ job-name (R*)
+ ipp-attribute-fidelity (R*)
+ document-name (R*)
+ document-format (R*)
+ document-natural-language (O*)
+ compression (O*)
+
+
+
+Hastings & Manros Informational [Page 14]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ job-k-octets (O*)
+ job-impressions (O*)
+ job-media-sheets (O*)
+ Group 2: Job Template Attributes (R*)
+ <Job Template attributes> (O*)
+ (see [RFC2566] Section 4.2)
+ Group 3: Document Content (R)
+ <document content>
+
+ Validate-Job Request:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ requesting-user-name (R*)
+ job-name (R*)
+ ipp-attribute-fidelity (R*)
+ document-name (R*)
+ document-format (R*)
+ document-natural-language (O*)
+ compression (O*)
+ job-k-octets (O*)
+ job-impressions (O*)
+ job-media-sheets (O*)
+ Group 2: Job Template Attributes (R*)
+ <Job Template attributes> (O*)
+ (see [RFC2566] Section 4.2)
+
+ Create-Job Request:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ requesting-user-name (R*)
+ job-name (R*)
+ ipp-attribute-fidelity (R*)
+ job-k-octets (O*)
+ job-impressions (O*)
+ job-media-sheets (O*)
+ Group 2: Job Template Attributes (R*)
+ <Job Template attributes> (O*) (see
+ (see [RFC2566] Section 4.2)
+
+ Print-URI Request:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+
+
+
+Hastings & Manros Informational [Page 15]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ document-uri (R)
+ requesting-user-name (R*)
+ job-name (R*)
+ ipp-attribute-fidelity (R*)
+ document-name (R*)
+ document-format (R*)
+ document-natural-language (O*)
+ compression (O*)
+ job-k-octets (O*)
+ job-impressions (O*)
+ job-media-sheets (O*)
+ Group 2: Job Template Attributes (R*)
+ <Job Template attributes> (O*) (see
+ (see [RFC2566] Section 4.2)
+
+ Send-Document Request:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ (printer-uri & job-id) | job-uri (R)
+ last-document (R)
+ requesting-user-name (R*)
+ document-name (R*)
+ document-format (R*)
+ document-natural-language (O*)
+ compression (O*)
+ Group 2: Document Content (R*)
+ <document content>
+
+ Send-URI Request:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ (printer-uri & job-id) | job-uri (R)
+ last-document (R)
+ document-uri (R)
+ requesting-user-name (R*)
+ document-name (R*)
+ document-format (R*)
+ document-natural-language (O*)
+ compression (O*)
+
+
+
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 16]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Cancel-Job Request:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ (printer-uri & job-id) | job-uri (R)
+ requesting-user-name (R*)
+ message (O*)
+
+ Get-Printer-Attributes Request:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ requesting-user-name (R*)
+ requested-attributes (R*)
+ document-format (R*)
+
+ Get-Job-Attributes Request:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ (printer-uri & job-id) | job-uri (R)
+ requesting-user-name (R*)
+ requested-attributes (R*)
+
+ Get-Jobs Request:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ printer-uri (R)
+ requesting-user-name (R*)
+ limit (R*)
+ requested-attributes (R*)
+ which-jobs (R*)
+ my-jobs (R*)
+
+
+ Operation Responses
+
+ The tables below show the response attributes in their proper
+ attribute groups for responses.
+
+ Note: All operation responses contain "version-number", "status-
+ code", and "request-id" parameters.
+
+ Print-Job Response:
+ Print-URI Response:
+ Create-Job Response:
+
+
+
+Hastings & Manros Informational [Page 17]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Send-Document Response:
+ Send-URI Response:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ status-message (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 3)
+ <unsupported attributes> (R*)
+ Group 3: Job Object Attributes(R*) (see Note 2)
+ job-uri (R)
+ job-id (R)
+ job-state (R)
+ job-state-reasons (O*)
+ job-state-message (O*)
+ number-of-intervening-jobs (O*)
+
+ Validate-Job Response:
+ Cancel-Job Response:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ status-message (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 3)
+ <unsupported attributes> (R*)
+
+ Note 2 - the Job Object Attributes and Printer Object Attributes are
+ returned only if the IPP object returns one of the success status
+ codes.
+
+ Note 3 - the Unsupported Attributes Group is present only if the
+ client included some Operation and/or Job Template attributes or
+ values that the Printer doesn't support whether a success or an error
+ return.
+
+ Get-Printer-Attributes Response:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ status-message (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 4)
+ <unsupported attributes> (R*)
+ Group 3: Printer Object Attributes(R*) (see Note 2)
+ <requested attributes> (R*)
+
+ Note 4 - the Unsupported Attributes Group is present only if the
+ client included some Operation attributes that the Printer doesn't
+ support whether a success or an error return.
+
+
+
+
+Hastings & Manros Informational [Page 18]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Get-Job-Attributes Response:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ status-message (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 4)
+ <unsupported attributes> (R*)
+ Group 3: Job Object Attributes(R*) (see Note 2)
+ <requested attributes> (R*)
+
+ Get-Jobs Response:
+ Group 1: Operation Attributes (R)
+ attributes-charset (R)
+ attributes-natural-language (R)
+ status-message (O*)
+ Group 2: Unsupported Attributes (R*) (see Note 4)
+ <unsupported attributes> (R*)
+ Group 3: Job Object Attributes(R*) (see Note 2, 5)
+ <requested attributes> (R*)
+
+ Note 5: for the Get-Jobs operation the response contains a separate
+ Job Object Attributes group 3 to N containing requested-attributes
+ for each job object in the response.
+
+2.2.1.5 Validate the values of the REQUIRED Operation attributes
+
+ An IPP object validates the values supplied by the client of the
+ REQUIRED Operation attribute that the IPP object MUST support. The
+ next section specifies the validation of the values of the OPTIONAL
+ Operation attributes that IPP objects MAY support.
+
+ The IPP object performs the following syntactic validation checks of
+ each Operation attribute value:
+
+ a)that the length of each Operation attribute value is correct for
+ the attribute syntax tag supplied by the client according to
+ [RFC2566] Section 4.1,
+
+ b)that the attribute syntax tag is correct for that Operation
+ attribute according to [RFC2566] Section 3,
+
+ c)that the value is in the range specified for that Operation
+ attribute according to [RFC2566] Section 3,
+
+ d)that multiple values are supplied by the client only for
+ operation attributes that are multi-valued, i.e., that are
+ 1setOf X according to [RFC2566] Section 3.
+
+
+
+
+Hastings & Manros Informational [Page 19]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ If any of these checks fail, the IPP object REJECTS the request and
+ RETURNS the 'client-error-bad-request' or the 'client-error-request-
+ value-too-long' status code. Since such an error is most likely to
+ be an error detected by a client developer, rather than by an end-
+ user, the IPP object NEED NOT return an indication of which attribute
+ had the error in either the Unsupported Attributes Group or the
+
+ Status Message. The description for each of these syntactic checks
+ is explicitly expressed in the first IF statement in the following
+ table.
+
+ In addition, the IPP object checks each Operation attribute value
+ against some Printer object attribute or some hard-coded value if
+ there is no "xxx-supported" Printer object attribute defined. If its
+ value is not among those supported or is not in the range supported,
+ then the IPP object REJECTS the request and RETURNS the error status
+ code indicated in the table by the second IF statement. If the value
+ of the Printer object's "xxx-supported" attribute is 'no-value'
+ (because the system administrator hasn't configured a value), the
+ check always fails.
+
+ attributes-charset (charset)
+
+ IF NOT a single non-empty 'charset' value, REJECT/RETURN 'client-
+ error-bad-request'.
+
+ IF the value length is greater than 63 octets, REJECT/RETURN '
+ client-error-request-value-too-long'.
+ IF NOT in the Printer object's "charset-supported" attribute,
+ REJECT/RETURN "client-error-charset-not-supported".
+
+
+ attributes-natural-language(naturalLanguage)
+
+ IF NOT a single non-empty 'naturalLanguage' value, REJECT/RETURN
+ 'client-error-bad-request'.
+ IF the value length is greater than 63 octets, REJECT/RETURN '
+ client-error-request-value-too-long'.
+ ACCEPT the request even if not a member of the set in the Printer
+ object's "generated-natural-language-supported" attribute. If
+ the supplied value is not a member of the Printer object's
+ "generated-natural-language-supported" attribute, use the
+ Printer object's "natural-language-configured" value.
+
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 20]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ requesting-user-name
+
+ IF NOT a single 'name' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF the IPP object can obtain a better authenticated name, use it
+ instead.
+
+
+ job-name(name)
+
+ IF NOT a single 'name' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT supplied by the client, the Printer object creates a name
+ from the document-name or document-uri.
+
+
+ document-name (name)
+
+ IF NOT a single 'name' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+
+
+ ipp-attribute-fidelity (boolean)
+
+ IF NEITHER a single 'true' NOR a single 'false' 'boolean' value,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF the value length is NOT equal to 1 octet, REJECT/RETURN '
+ client-error-request-value-too-long'
+ IF NOT supplied by the client, the IPP object assumes the value
+ 'false'.
+
+
+ document-format (mimeMediaType)
+
+ IF NOT a single non-empty 'mimeMediaType' value, REJECT/RETURN
+ 'client-error-bad-request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "document-format-supported"
+ attribute, REJECT/RETURN 'client-error-document-format-not-
+ supported'
+
+
+
+
+Hastings & Manros Informational [Page 21]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ IF NOT supplied by the client, the IPP object assumes the value of
+ the Printer object's "document-format-default" attribute.
+
+
+ document-uri (uri)
+
+ IF NOT a single non-empty 'uri' value, REJECT/RETURN 'client-
+ error-bad-request'.
+ IF the value length is greater than 1023 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF the URI syntax is not valid, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF scheme is NOT in the Printer object's "reference-uri-schemes-
+ supported" attribute, REJECT/RETURN 'client-error-uri-scheme-
+ not-supported'.
+ The Printer object MAY check to see if the document exists and is
+ accessible. If the document is not found or is not accessible,
+ REJECT/RETURN 'client-error-not found'.
+
+
+ last-document (boolean)
+
+ IF NEITHER a single 'true' NOR a single 'false' 'boolean' value,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF the value length is NOT equal to 1 octet, REJECT/RETURN '
+ client-error-request-value-too-long'
+
+
+ job-id (integer(1:MAX))
+
+ IF NOT an single 'integer' value equal to 4 octets AND in the
+ range 1 to MAX, REJECT/RETURN 'client-error-bad-request'.
+
+ IF NOT a job-id of an existing Job object, REJECT/RETURN 'client-
+ error-not-found' or 'client-error-gone' status code, if keep
+ track of recently deleted jobs.
+
+
+ requested-attributes (1setOf keyword)
+
+ IF NOT one or more 'keyword' values, REJECT/RETURN 'client-error-
+ bad-request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ Ignore unsupported values which are the keyword names of
+ unsupported attributes. Don't bother to copy such requested
+ (unsupported) attributes to the Unsupported Attribute response
+ group since the response will not return them.
+
+
+
+Hastings & Manros Informational [Page 22]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ which-jobs (type2 keyword)
+
+ IF NOT a single 'keyword' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NEITHER 'completed' NOR 'not-completed', copy the attribute and
+ the unsupported value to the Unsupported Attributes response
+ group and REJECT/RETURN 'client-error-attributes-or-values-
+ not-supported'.
+ Note: a Printer still supports the 'completed' value even if it
+ keeps no completed/canceled/aborted jobs: by returning no jobs
+ when so queried.
+ IF NOT supplied by the client, the IPP object assumes the 'not-
+ completed' value.
+
+
+ my-jobs (boolean)
+
+ IF NEITHER a single 'true' NOR a single 'false' 'boolean' value,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF the value length is NOT equal to 1 octet, REJECT/RETURN '
+ client-error-request-value-too-long'
+ IF NOT supplied by the client, the IPP object assumes the 'false'
+ value.
+
+
+ limit (integer(1:MAX))
+
+ IF NOT a single 'integer' value equal to 4 octets AND in the range
+ 1 to MAX, REJECT/RETURN 'client-error-bad-request'.
+ IF NOT supplied by the client, the IPP object returns all jobs, no
+ matter how many.
+
+2.2.1.6 Validate the values of the OPTIONAL Operation attributes
+
+ OPTIONAL Operation attributes are those that an IPP object MAY or MAY
+ NOT support. An IPP object validates the values of the OPTIONAL
+ attributes supplied by the client. The IPP object performs the same
+ syntactic validation checks for each OPTIONAL attribute value as in
+ Section 2.2.1.5. As in Section 2.2.1.5, if any fail, the IPP object
+ REJECTS the request and RETURNS the 'client-error-bad-request' or the
+ 'client-error-request-value-too-long' status code.
+
+ In addition, the IPP object checks each Operation attribute value
+ against some Printer attribute or some hard-coded value if there is
+ no "xxx-supported" Printer attribute defined. If its value is not
+ among those supported or is not in the range supported, then the IPP
+
+
+
+Hastings & Manros Informational [Page 23]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ object REJECTS the request and RETURNS the error status code
+ indicated in the table. If the value of the Printer object's "xxx-
+ supported" attribute is 'no-value' (because the system administrator
+ hasn't configured a value), the check always fails.
+
+ If the IPP object doesn't recognize/support an attribute, the IPP
+ object treats the attribute as an unknown or unsupported attribute
+ (see the last row in the table below).
+
+ document-natural-language (naturalLanguage)
+
+ IF NOT a single non-empty 'naturalLanguage' value, REJECT/RETURN '
+ client-error-bad-request'.
+ IF the value length is greater than 63 octets, REJECT/RETURN '
+ client-error-request-value-too-long'.
+ IF NOT a value that the Printer object supports in document
+ formats, (no corresponding "xxx-supported" Printer attribute),
+ REJECT/RETURN 'client-error-natural-language-not-supported'.
+
+
+ compression (type3 keyword)
+
+ IF NOT a single 'keyword' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN '
+ client-error-request-value-too-long'.
+ IF NOT in the Printer object's "compression-supported" attribute,
+ copy the attribute and the unsupported value to the Unsupported
+ Attributes response group and REJECT/RETURN 'client-error-
+ attributes-or-values-not-supported'.
+
+
+ job-k-octets (integer(0:MAX))
+
+ IF NOT a single 'integer' value equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the range of the Printer object's "job-k-octets-
+ supported" attribute, copy the attribute and the unsupported
+ value to the Unsupported Attributes response group and
+ REJECT/RETURN 'client-error-attributes-or-values-not-
+ supported'.
+
+
+ job-impressions (integer(0:MAX))
+
+ IF NOT a single 'integer' value equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+
+
+
+
+Hastings & Manros Informational [Page 24]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ IF NOT in the range of the Printer object's "job-impressions-
+ supported" attribute, copy the attribute and the unsupported
+ value to the Unsupported Attributes response group and
+ REJECT/RETURN 'client-error-attributes-or-values-not-
+ supported'.
+
+
+ job-media-sheets (integer(0:MAX))
+
+ IF NOT a single 'integer' value equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the range of the Printer object's "job-media-sheets-
+ supported" attribute, copy the attribute and the unsupported
+ value to the Unsupported Attributes response group and
+ REJECT/RETURN 'client-error-attributes-or-values-not-
+ supported'.
+
+
+ message (text(127))
+
+ IF NOT a single 'text' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 127 octets,
+ REJECT/RETURN 'client-error-request-value-too-long'.
+
+
+ unknown or unsupported attribute
+
+ IF the attribute syntax supplied by the client is supported but
+ the length is not legal for that attribute syntax,
+ REJECT/RETURN 'client-error-request-value-too-long'.
+ ELSE copy the attribute and value to the Unsupported Attributes
+ response group and change the attribute value to the "out-of-
+ band" 'unsupported' value, but otherwise ignore the attribute.
+
+ Note: Future Operation attributes may be added to the protocol
+ specification that may occur anywhere in the specified group.
+ When the operation is otherwise successful, the IPP object returns
+ the 'successful-ok-ignored-or-substituted-attributes' status code.
+ Ignoring unsupported Operation attributes in all operations is
+ analogous to the handling of unsupported Job Template attributes
+ in the create and Validate-Job operations when the client supplies
+ the "ipp-attribute-fidelity" Operation attribute with the 'false'
+ value. This last rule is so that we can add OPTIONAL Operation
+ attributes to future versions of IPP so that older clients can
+ inter-work with new IPP objects and newer clients can inter-work
+ with older IPP objects. (If the new attribute cannot be ignored
+ without performing unexpectedly, the major version number would
+
+
+
+Hastings & Manros Informational [Page 25]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ have been increased in the protocol document and in the request).
+ This rule for Operation attributes is independent of the value of
+ the "ipp-attribute-fidelity" attribute. For example, if an IPP
+ object doesn't support the OPTIONAL "job-k-octets" attribute', the
+ IPP object treats "job-k-octets" as an unknown attribute and only
+ checks the length for the 'integer' attribute syntax supplied by
+ the client. If it is not four octets, the IPP object REJECTS the
+ request and RETURNS the 'client-error-bad-request' status code,
+ else the IPP object copies the attribute to the Unsupported
+ Attribute response group, setting the value to the "out-of-band" '
+ unsupported' value, but otherwise ignores the attribute.
+
+2.2.2 Suggested Additional Processing Steps for Operations that
+ Create/Validate Jobs and Add Documents
+
+ This section in combination with the previous section recommends the
+ processing steps for the Print-Job, Validate-Job, Print-URI, Create-
+ Job, Send-Document, and Send-URI operations that IPP objects SHOULD
+ use. These are the operations that create jobs, validate a Print-Job
+ request, and add documents to a job.
+
+2.2.2.1 Default "ipp-attribute-fidelity" if not supplied
+
+ The Printer object checks to see if the client supplied an "ipp-
+ attribute-fidelity" Operation attribute. If the attribute is not
+ supplied by the client, the IPP object assumes that the value is
+ 'false'.
+
+2.2.2.2 Check that the Printer object is accepting jobs
+
+ If the value of the Printer object's "printer-is-accepting-jobs" is
+ 'false', the Printer object REJECTS the request and RETURNS the
+ 'server-error-not-accepting-jobs' status code.
+
+2.2.2.3 Validate the values of the Job Template attributes
+
+ An IPP object validates the values of all Job Template attribute
+ supplied by the client. The IPP object performs the analogous
+ syntactic validation checks of each Job Template attribute value that
+ it performs for Operation attributes (see Section 2.2.1.5.):
+
+ a)that the length of each value is correct for the attribute
+ syntax tag supplied by the client according to [RFC2566] Section
+ 4.1.
+
+ b)that the attribute syntax tag is correct for that attribute
+ according to [RFC2566] Sections 4.2 to 4.4.
+
+
+
+
+Hastings & Manros Informational [Page 26]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ c)that multiple values are supplied only for multi-valued
+ attributes, i.e., that are 1setOf X according to [RFC2566]
+ Sections 4.2 to 4.4.
+
+ As in Section 2.2.1.5, if any of these syntactic checks fail, the IPP
+ object REJECTS the request and RETURNS the 'client-error-bad-request'
+ or 'client-error-request-value-too-long' status code as appropriate,
+ independent of the value of the "ipp-attribute-fidelity". Since such
+ an error is most likely to be an error detected by a client
+ developer, rather than by an end-user, the IPP object NEED NOT return
+ an indication of which attribute had the error in either the
+ Unsupported Attributes Group or the Status Message. The description
+ for each of these syntactic checks is explicitly expressed in the
+ first IF statement in the following table.
+
+ Each Job Template attribute MUST occur no more than once. If an IPP
+ Printer receives a create request with multiple occurrences of a Job
+ Template attribute, it MAY:
+
+ 1.reject the operation and return the 'client-error-bad syntax'
+ error status code
+
+ 2.accept the operation and use the first occurrence of the
+ attribute
+
+ 3.accept the operation and use the last occurrence of the
+ attribute
+
+ depending on implementation. Therefore, clients MUST NOT supply
+ multiple occurrences of the same Job Template attribute in the Job
+ Attributes group in the request.
+
+2.2.3 Algorithm for job validation
+
+ The process of validating a Job-Template attribute "xxx" against a
+ Printer attribute "xxx-supported" can use the following validation
+ algorithm (see section 3.2.1.2 in [RFC2566]).
+
+ To validate the value U of Job-Template attribute "xxx" against the
+ value V of Printer "xxx-supported", perform the following algorithm:
+
+ 1.If U is multi-valued, validate each value X of U by performing
+ the algorithm in Table 3 with each value X. Each validation is
+ separate from the standpoint of returning unsupported values.
+
+ Example: If U is "finishings" that the client supplies with
+ 'staple', 'bind' values, then X takes on the successive values:
+ 'staple', then 'bind'
+
+
+
+Hastings & Manros Informational [Page 27]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ 2.If V is multi-valued, validate X against each Z of V by
+ performing the algorithm in Table 3 with each value Z. If a
+ value Z validates, the validation for the attribute value X
+ succeeds. If it fails, the algorithm is applied to the next
+ value Z of V. If there are no more values Z of V, validation
+ fails.
+
+ Example: If V is "sides-supported" with values: 'one-sided',
+ 'two-sided-long', and 'two-sided-short', then Z takes on the
+ successive values: 'one-sided', 'two-sided-long', and
+ 'two-sided-short'. If the client supplies "sides" with 'two-
+ sided-long', the first comparison fails ('one-sided' is not
+ equal to 'two-sided-long'), the second comparison succeeds
+ ('two-sided-long' is equal to 'two-sided-long"), and the third
+ comparison ('two-sided-short' with 'two-sided-long') is not even
+ performed.
+
+ 3.If both U and V are single-valued, let X be U and Z be V and use
+ the validation rules in Table 3.
+
+ Table 3 - Rules for validating single values X against Z
+
+ attribute attribute validated if:
+ syntax of X syntax of Z
+
+ integer rangeOfInteger X is within the range of
+ Z
+
+ uri uriScheme the uri scheme in X is
+ equal to Z
+
+ any boolean the value of Z is TRUE
+
+ any any X and Z are of the same
+ type and are equal.
+
+ If the value of the Printer object's "xxx-supported" attribute is '
+ no-value' (because the system administrator hasn't configured a
+ value), the check always fails. If the check fails, the IPP object
+ copies the attribute to the Unsupported Attributes response group
+ with its unsupported value. If the attribute contains more than one
+ value, each value is checked and each unsupported value is separately
+ copied, while supported values are not copied. If an IPP object
+ doesn't recognize/support a Job Template attribute, i.e., there is no
+ corresponding Printer object "xxx-supported" attribute, the IPP
+ object treats the attribute as an unknown or unsupported attribute
+ (see the last row in the table below).
+
+
+
+
+Hastings & Manros Informational [Page 28]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ If some Job Template attributes are supported for some document
+ formats and not for others or the values are different for different
+ document formats, the IPP object SHOULD take that into account in
+ this validation using the value of the "document-format" supplied by
+ the client (or defaulted to the value of the Printer's "document-
+ format-default" attribute, if not supplied by the client). For
+ example, if "number-up" is supported for the 'text/plain' document
+ format, but not for the 'application/postscript' document format, the
+ check SHOULD (though it NEED NOT) depend on the value of the
+ "document-format" operation attribute. See "document-format" in
+ [RFC2566] section 3.2.1.1 and 3.2.5.1.
+
+ Note: whether the request is accepted or rejected is determined by
+ the value of the "ipp-attribute-fidelity" attribute in a subsequent
+ step, so that all Job Template attribute supplied are examined and
+ all unsupported attributes and/or values are copied to the
+ Unsupported Attributes response group.
+
+ job-priority (integer(1:100))
+
+ IF NOT a single 'integer' value with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT supplied by the client, use the value of the Printer
+ object's "job-priority-default" attribute at job submission
+ time.
+ IF NOT in the range 1 to 100, inclusive, copy the attribute and
+ the unsupported value to the Unsupported Attributes response
+ group.
+ Map the value to the nearest supported value in the range 1:100 as
+ specified by the number of discrete values indicated by the
+ value of the Printer's "job-priority-supported" attribute. See
+ the formula in [RFC2566] Section 4.2.1.
+
+ job-hold-until (type3 keyword | name)
+
+ IF NOT a single 'keyword' or 'name' value, REJECT/RETURN 'client-
+ error-bad-request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT supplied by the client, use the value of the Printer
+ object's "job-hold-until" attribute at job submission time.
+ IF NOT in the Printer object's "job-hold-until-supported"
+ attribute, copy the attribute and the unsupported value to the
+ Unsupported Attributes response group.
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 29]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ job-sheets (type3 keyword | name)
+
+ IF NOT a single 'keyword' or 'name' value, REJECT/RETURN 'client-
+ error-bad-request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "job-sheets-supported" attribute,
+ copy the attribute and the unsupported value to the Unsupported
+ Attributes response group.
+
+ multiple-document-handling (type2 keyword)
+
+ IF NOT a single 'keyword' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "multiple-document-handling-
+ supported" attribute, copy the attribute and the unsupported
+ value to the Unsupported Attributes response group.
+
+ copies (integer(1:MAX))
+
+ IF NOT a single 'integer' value with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in range of the Printer object's "copies-supported"
+ attribute copy the attribute and the unsupported value to the
+ Unsupported
+ Attributes response group.
+
+ finishings (1setOf type2 enum)
+
+ IF NOT an 'enum' value(s) each with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the Printer object's "finishings-supported" attribute,
+ copy the attribute and the unsupported value(s), but not any
+ supported values, to the Unsupported Attributes response group.
+
+ page-ranges (1setOf rangeOfInteger(1:MAX))
+
+ IF NOT a 'rangeOfInteger' value(s) each with a length equal to 8
+ octets, REJECT/RETURN 'client-error-bad-request'.
+ IF first value is greater than second value in any range, the
+ ranges are not in ascending order, or ranges overlap,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF the value of the Printer object's "page-ranges-supported"
+ attribute is 'false', copy the attribute to the Unsupported
+ Attributes response group and set the value to the "out-of-
+ band" 'unsupported' value.
+
+
+
+Hastings & Manros Informational [Page 30]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ sides (type2 keyword)
+
+ IF NOT a single 'keyword' value, REJECT/RETURN 'client-error-bad-
+ request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "sides-supported" attribute, copy
+ the attribute and the unsupported value to the Unsupported
+ Attributes response group.
+
+ number-up (integer(1:MAX))
+
+ IF NOT a single 'integer' value with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT a value or in the range of one of the values of the Printer
+ object's "number-up-supported" attribute, copy the attribute
+ and value to the Unsupported Attribute response group.
+
+ orientation-requested (type2 enum)
+
+ IF NOT a single 'enum' value with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the Printer object's "orientation-requested-supported"
+ attribute, copy the attribute and the unsupported value to the
+ Unsupported Attributes response group.
+
+ media (type3 keyword | name)
+
+ IF NOT a single 'keyword' or 'name' value, REJECT/RETURN 'client-
+ error-bad-request'.
+ IF the value length is greater than 255 octets, REJECT/RETURN
+ 'client-error-request-value-too-long'.
+ IF NOT in the Printer object's "media-supported" attribute, copy
+ the attribute and the unsupported value to the Unsupported
+ Attributes response group.
+
+ printer-resolution (resolution)
+
+ IF NOT a single 'resolution' value with a length equal to 9
+ octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the Printer object's "printer-resolution-supported"
+ attribute, copy the attribute and the unsupported value to the
+ Unsupported Attributes response group.
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 31]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ print-quality (type2 enum)
+
+ IF NOT a single 'enum' value with a length equal to 4 octets,
+ REJECT/RETURN 'client-error-bad-request'.
+ IF NOT in the Printer object's "print-quality-supported"
+ attribute, copy the attribute and the unsupported value to the
+ Unsupported Attributes response group.
+
+ unknown or unsupported attribute (i.e., there is no corresponding
+ Printer object "xxx-supported" attribute)
+
+ IF the attribute syntax supplied by the client is supported but
+ the length is not legal for that attribute syntax,
+ REJECT/RETURN 'client-error-bad-request' if the length of the
+ attribute syntax is fixed or 'client-error-request-value-too-
+ long' if the length of the attribute syntax is variable.
+ ELSE copy the attribute and value to the Unsupported Attributes
+ response group and change the attribute value to the "out-of-
+ band" 'unsupported' value. Any remaining Job Template
+ Attributes are either unknown or unsupported Job Template
+ attributes and are validated algorithmically according to their
+ attribute syntax for proper length (see below).
+
+ If the attribute syntax is supported AND the length check
+ fails, the IPP object REJECTS the request and RETURNS the '
+ client-error-bad-request' if the length of the attribute syntax
+ is fixed or the 'client-error-request-value-too-long' status
+ code if the length of the attribute syntax is variable.
+ Otherwise, the IPP object copies the unsupported Job Template
+ attribute to the Unsupported Attributes response group and
+ changes the attribute value to the "out-of-band" 'unsupported'
+ value. The following table shows the length checks for all
+ attribute syntaxes. In the following table: "<=" means less
+ than or equal, "=" means equal to:
+
+ Name Octet length check for read-write attributes
+ ----------- --------------------------------------------
+ 'textWithLanguage <= 1023 AND 'naturalLanguage' <= 63
+ 'textWithoutLanguage' <= 1023
+ 'nameWithLanguage' <= 255 AND 'naturalLanguage' <= 63
+ 'nameWithoutLanguage' <= 255
+ 'keyword' <= 255
+ 'enum' = 4
+ 'uri' <= 1023
+ 'uriScheme' <= 63
+ 'charset' <= 63
+ 'naturalLanguage' <= 63
+ 'mimeMediaType' <= 255
+
+
+
+Hastings & Manros Informational [Page 32]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ 'octetString' <= 1023
+ 'boolean' = 1
+ 'integer' = 4
+ 'rangeOfInteger' = 8
+ 'dateTime' = 11
+ 'resolution' = 9
+ '1setOf X'
+
+2.2.3.1 Check for conflicting Job Template attributes values
+
+ Once all the Operation and Job Template attributes have been checked
+ individually, the Printer object SHOULD check for any conflicting
+ values among all the supported values supplied by the client. For
+ example, a Printer object might be able to staple and to print on
+ transparencies, however due to physical stapling constraints, the
+ Printer object might not be able to staple transparencies. The IPP
+ object copies the supported attributes and their conflicting
+ attribute values to the Unsupported Attributes response group. The
+ Printer object only copies over those attributes that the Printer
+ object either ignores or substitutes in order to resolve the
+ conflict, and it returns the original values which were supplied by
+ the client. For example suppose the client supplies "finishings"
+ equals 'staple' and "media" equals 'transparency', but the Printer
+ object does not support stapling transparencies. If the Printer
+ chooses to ignore the stapling request in order to resolve the
+ conflict, the Printer objects returns "finishings" equal to 'staple'
+ in the Unsupported Attributes response group. If any attributes are
+ multi-valued, only the conflicting values of the attributes are
+ copied.
+
+ Note: The decisions made to resolve the conflict (if there is a
+ choice) is implementation dependent.
+
+2.2.3.2 Decide whether to REJECT the request
+
+ If there were any unsupported Job Template attributes or
+ unsupported/conflicting Job Template attribute values and the client
+ supplied the "ipp-attribute-fidelity" attribute with the 'true'
+ value, the Printer object REJECTS the request and return the status
+ code:
+
+ (1) 'client-error-conflicting-attributes' status code, if there
+ were any conflicts between attributes supplied by the client.
+ (2) 'client-error-attributes-or-values-not-supported' status code,
+ otherwise.
+
+
+
+
+
+
+Hastings & Manros Informational [Page 33]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Note: Unsupported Operation attributes or values that are returned
+ do not affect the status returned in this step. If the unsupported
+ Operation attribute was a serious error, the above already rejected
+ the request in a previous step. If control gets to this step with
+ unsupported Operation attributes being returned, they are not serious
+ errors.
+
+2.2.3.3 For the Validate-Job operation, RETURN one of the success
+ status codes
+
+ If the requested operation is the Validate-Job operation, the Printer
+ object returns:
+
+ (1) the "successful-ok" status code, if there are no unsupported
+ or conflicting Job Template attributes or values.
+ (2) the "successful-ok-conflicting-attributes, if there are any
+ conflicting Job Template attribute or values.
+ (3) the "successful-ok-ignored-or-substituted-attributes, if there
+ are only unsupported Job Template attributes or values.
+
+ Note: Unsupported Operation attributes or values that are returned
+ do not affect the status returned in this step. If the unsupported
+ Operation attribute was a serious error, the above already rejected
+ the request in a previous step. If control gets to this step with
+ unsupported Operation attributes being returned, they are not serious
+ errors.
+
+2.2.3.4 Create the Job object with attributes to support
+
+ If "ipp-attribute-fidelity" is set to 'false' (or it was not supplied
+ by the client), the Printer object:
+
+ (1) creates a Job object, assigns a unique value to the job's
+ "job-uri" and "job-id" attributes, and initializes all of the
+ job's other supported Job Description attributes.
+ (2) removes all unsupported attributes from the Job object.
+ (3) for each unsupported value, removes either the unsupported
+ value or substitutes the unsupported attribute value with some
+ supported value. If an attribute has no values after removing
+ unsupported values from it, the attribute is removed from the
+ Job object (so that the normal default behavior at job
+ processing time will take place for that attribute).
+ (4) for each conflicting value, removes either the conflicting
+ value or substitutes the conflicting attribute value with some
+ other supported value. If an attribute has no values after
+ removing conflicting values from it, the attribute is removed
+ from the Job object (so that the normal default behavior at
+ job processing time will take place for that attribute).
+
+
+
+Hastings & Manros Informational [Page 34]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ If there were no attributes or values flagged as unsupported, or the
+ value of 'ipp-attribute-fidelity" was 'false', the Printer object is
+ able to accept the create request and create a new Job object. If
+ the "ipp-attribute-fidelity" attribute is set to 'true', the Job
+ Template attributes that populate the new Job object are necessarily
+ all the Job Template attributes supplied in the create request. If
+ the "ipp-attribute-fidelity" attribute is set to 'false', the Job
+ Template attributes that populate the new Job object are all the
+ client supplied Job Template attributes that are supported or that
+ have value substitution. Thus, some of the requested Job Template
+ attributes may not appear in the Job object because the Printer
+ object did not support those attributes. The attributes that
+ populate the Job object are persistently stored with the Job object
+ for that Job. A Get-Job-Attributes operation on that Job object will
+ return only those attributes that are persistently stored with the
+ Job object.
+
+ Note: All Job Template attributes that are persistently stored with
+ the Job object are intended to be "override values"; that is, they
+ that take precedence over whatever other embedded instructions might
+ be in the document data itself. However, it is not possible for all
+ Printer objects to realize the semantics of "override". End users
+ may query the Printer's "pdl-override-supported" attribute to
+ determine if the Printer either attempts or does not attempt to
+ override document data instructions with IPP attributes.
+
+ There are some cases, where a Printer supports a Job Template
+ attribute and has an associated default value set for that attribute.
+ In the case where a client does not supply the corresponding
+ attribute, the Printer does not use its default values to populate
+ Job attributes when creating the new Job object; only Job Template
+ attributes actually in the create request are used to populate the
+ Job object. The Printer's default values are only used later at Job
+ processing time if no other IPP attribute or instruction embedded in
+ the document data is present.
+
+ Note: If the default values associated with Job Template attributes
+ that the client did not supply were to be used to populate the Job
+ object, then these values would become "override values" rather than
+ defaults. If the Printer supports the 'attempted' value of the
+ "pdl-override-supported" attribute, then these override values could
+ replace values specified within the document data. This is not the
+ intent of the default value mechanism. A default value for an
+ attribute is used only if the create request did not specify that
+ attribute (or it was ignored when allowed by "ipp-attribute-fidelity"
+ being 'false') and no value was provided within the content of the
+ document data.
+
+
+
+
+Hastings & Manros Informational [Page 35]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ If the client does not supply a value for some Job Template
+ attribute, and the Printer does not support that attribute, as far as
+ IPP is concerned, the result of processing that Job (with respect to
+ the missing attribute) is undefined.
+
+2.2.3.5 Return one of the success status codes
+
+ Once the Job object has been created, the Printer object accepts the
+ request and returns to the client:
+
+ (1) the 'successful-ok' status code, if there are no unsupported
+ or conflicting Job Template attributes or values.
+ (2) the 'successful-ok-conflicting-attributes' status code, if
+ there are any conflicting Job Template attribute or values.
+ (3) the 'successful-ok-ignored-or-substituted-attributes' status
+ code, if there are only unsupported Job Template attributes or
+ values.
+
+ Note: Unsupported Operation attributes or values that are returned
+ do not affect the status returned in this step. If the unsupported
+ Operation attribute was a serious error, the above already rejected
+ the request in a previous step. If control gets to this step with
+ unsupported Operation attributes being returned, they are not serious
+ errors.
+
+ The Printer object also returns Job status attributes that indicate
+ the initial state of the Job ('pending', 'pending-held', '
+ processing', etc.), etc. See Print-Job Response, [RFC2566] section
+ 3.2.1.2.
+
+2.2.3.6 Accept appended Document Content
+
+ The Printer object accepts the appended Document Content data and
+ either starts it printing, or spools it for later processing.
+
+2.2.3.7 Scheduling and Starting to Process the Job
+
+ The Printer object uses its own configuration and implementation
+ specific algorithms for scheduling the Job in the correct processing
+ order. Once the Printer object begins processing the Job, the
+ Printer changes the Job's state to 'processing'. If the Printer
+ object supports PDL override (the "pdl-override-supported" attribute
+ set to 'attempted'), the implementation does its best to see that IPP
+ attributes take precedence over embedded instructions in the document
+ data.
+
+
+
+
+
+
+Hastings & Manros Informational [Page 36]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+2.2.3.8 Completing the Job
+
+ The Printer object continues to process the Job until it can move the
+ Job into the 'completed' state. If an Cancel-Job operation is
+ received, the implementation eventually moves the Job into the '
+ canceled' state. If the system encounters errors during processing
+ that do not allow it to progress the Job into a completed state, the
+ implementation halts all processing, cleans up any resources, and
+ moves the Job into the 'aborted' state.
+
+2.2.3.9 Destroying the Job after completion
+
+ Once the Job moves to the 'completed', 'aborted', or 'canceled'
+ state, it is an implementation decision as to when to destroy the Job
+ object and release all associated resources. Once the Job has been
+ destroyed, the Printer would return either the "client-error-not-
+ found" or "client-error-gone" status codes for operations directed at
+ that Job.
+
+ Note: the Printer object SHOULD NOT re-use a "job-uri" or "job-id"
+ value for a sufficiently long time after a job has been destroyed, so
+ that stale references kept by clients are less likely to access the
+ wrong (newer) job.
+
+2.2.3.10 Interaction with "ipp-attribute-fidelity"
+
+ Some Printer object implementations may support "ipp-attribute-
+ fidelity" set to 'true' and "pdl-override-supported" set to '
+ attempted' and yet still not be able to realize exactly what the
+ client specifies in the create request. This is due to legacy
+ decisions and assumptions that have been made about the role of job
+ instructions embedded within the document data and external job
+ instructions that accompany the document data and how to handle
+ conflicts between such instructions. The inability to be 100%
+ precise about how a given implementation will behave is also
+ compounded by the fact that the two special attributes, "ipp-
+ attribute-fidelity" and "pdl-override-supported", apply to the whole
+ job rather than specific values for each attribute. For example, some
+ implementations may be able to override almost all Job Template
+ attributes except for "number-up".
+
+2.3 Status codes returned by operation
+
+ This section lists all status codes once in the first operation
+ (Print-Job). Then it lists the status codes that are different or
+ specialized for subsequent operations under each operation.
+
+
+
+
+
+Hastings & Manros Informational [Page 37]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+2.3.1 Printer Operations
+
+2.3.1.1 Print-Job
+
+ The Printer object MUST return one of the following "status-code"
+ values for the indicated reason. Whether all of the document data
+ has been accepted or not before returning the success or error
+ response depends on implementation. See Section 14 for a more
+ complete description of each status code.
+
+ For the following success status codes, the Job object has been
+ created and the "job-id", and "job-uri" assigned and returned in the
+ response:
+
+ successful-ok: no request attributes were substituted or ignored.
+ successful-ok-ignored-or-substituted-attributes: some supplied
+ (1) attributes were ignored or (2) unsupported attribute
+ syntaxes or values were substituted with supported values or
+ were ignored. Unsupported attributes, attribute syntaxes, or
+ values MUST be returned in the Unsupported Attributes group of
+ the response.
+ successful-ok-conflicting-attributes: some supplied attribute
+ values conflicted with the values of other supplied attributes
+ and were either substituted or ignored. Attributes or values
+ which conflict with other attributes and have been substituted
+ or ignored MUST be returned in the Unsupported Attributes group
+ of the response as supplied by the client.
+
+ [RFC2566] section 3.1.6 Operation Status Codes and Messages states:
+
+ If the Printer object supports the "status-message" operation
+ attribute, it SHOULD use the REQUIRED 'utf-8' charset to return
+ a status message for the following error status codes (see
+ section 14): 'client-error-bad-request', 'client-error-
+ charset-not-supported', 'server-error-internal-error', '
+ server-error-operation-not-supported', and 'server-error-
+ version-not-supported'. In this case, it MUST set the value of
+ the "attributes-charset" operation attribute to 'utf-8' in the
+ error response.
+
+ For the following error status codes, no job is created and no "job-
+ id" or "job-uri" is returned:
+
+ client-error-bad-request: The request syntax does not conform to
+ the specification.
+
+
+
+
+
+
+Hastings & Manros Informational [Page 38]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ client-error-forbidden: The request is being refused for
+ authorization or authentication reasons. The implementation
+ security policy is to not reveal whether the failure is one of
+ authentication or authorization.
+ client-error-not-authenticated: Either the request requires
+ authentication information to be supplied or the authentication
+ information is not sufficient for authorization.
+ client-error-not-authorized: The requester is not authorized to
+ perform the request on the target object.
+ client-error-not-possible: The request cannot be carried out
+ because of the state of the system. See also 'server-error-
+ not-accepting-jobs' status code which MUST take precedence if
+ the Printer object's "printer-accepting-jobs" attribute is '
+ false'.
+ client-error-timeout: not applicable.
+ client-error-not-found: the target object does not exist.
+ client-error-gone: the target object no longer exists and no
+ forwarding address is known.
+ client-error-request-entity-too-large: the size of the request
+ and/or print data exceeds the capacity of the IPP Printer to
+ process it.
+ client-error-request-value-too-long: the size of request variable
+ length attribute values, such as 'text' and 'name' attribute
+ syntaxes, exceed the maximum length specified in [RFC2566] for
+ the attribute and MUST be returned in the Unsupported
+ Attributes Group.
+ client-error-document-format-not-supported: the document format
+ supplied is not supported. The "document-format" attribute
+ with the unsupported value MUST be returned in the Unsupported
+ Attributes Group. This error SHOULD take precedence over any
+ other 'xxx-not-supported' error, except 'client-error-charset-
+ not-supported'.
+ client-error-attributes-or-values-not-supported: one or more
+ supplied attributes, attribute syntaxes, or values are not
+ supported and the client supplied the "ipp-attributes-fidelity"
+ operation attribute with a 'true' value. They MUST be returned
+ in the Unsupported Attributes Group as explained below.
+ client-error-uri-scheme-not-supported: not applicable.
+ client-error-charset-not-supported: the charset supplied in the
+ "attributes-charset" operation attribute is not supported. The
+ Printer's "configured-charset" MUST be returned in the response
+ as the value of the "attributes-charset" operation attribute
+ and used for any 'text' and 'name' attributes returned in the
+ error response. This error SHOULD take precedence over any
+ other error, unless the request syntax is so bad that the
+ client's supplied "attributes-charset" cannot be determined.
+
+
+
+
+
+Hastings & Manros Informational [Page 39]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ client-error-conflicting-attributes: one or more supplied
+ attribute va attribute values conflicted with each other and
+ the client supplied the "ipp-attributes-fidelity" operation
+ attribute with a 'true' value. They MUST be returned in the
+ Unsupported Attributes Group as explained below.
+ server-error-internal-error: an unexpected condition prevents the
+ request from being fulfilled.
+ server-error-operation-not-supported: not applicable (since
+ Print-Job is REQUIRED).
+ server-error-service-unavailable: the service is temporarily
+ overloaded.
+ server-error-version-not-supported: the version in the request is
+ not supported. The "closest" version number supported MUST be
+ returned in the response.
+ server-error-device-error: a device error occurred while
+ receiving or spooling the request or document data or the IPP
+ Printer object can only accept one job at a time.
+ server-error-temporary-error: a temporary error such as a buffer
+ full write error, a memory overflow, or a disk full condition
+ occurred while receiving the request and/or the document data.
+ server-error-not-accepting-jobs: the Printer object's "printer-
+ is-not-accepting-jobs" attribute is 'false'.
+ server-error-busy: the Printer is too busy processing jobs to
+ accept another job at this time.
+ server-error-job-canceled: the job has been canceled by an
+ operator or the system while the client was transmitting the
+ document data.
+
+2.3.1.2 Print-URI
+
+ All of the Print-Job status codes described in Section 3.2.1.2
+ Print-Job Response are applicable to Print-URI with the following
+ specializations and differences. See Section 14 for a more complete
+ description of each status code.
+
+ server-error-uri-scheme-not-supported: the URI scheme supplied in
+ the "document-uri" operation attribute is not supported and is
+ returned in the Unsupported Attributes group.
+
+2.3.1.3 Validate-Job
+
+ All of the Print-Job status codes described in Section 3.2.1.2
+ Print-Job Response are applicable to Validate-Job. See Section 14
+ for a more complete description of each status code.
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 40]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+2.3.1.4 Create-Job
+
+ All of the Print-Job status codes described in Section 3.2.1.2
+ Print-Job Response are applicable to Create-Job with the following
+ specializations and differences. See Section 14 for a more complete
+ description of each status code.
+
+ server-error-operation-not-supported: the Create-Job operation is
+ not supported.
+
+2.3.1.5 Get-Printer-Attributes
+
+ All of the Print-Job status codes described in Section 3.2.1.2
+ Print-Job Response are applicable to the Get-Printer-Attributes
+ operation with the following specializations and differences. See
+ Section 14 for a more complete description of each status code.
+
+ For the following success status codes, the requested attributes are
+ returned in Group 3 in the response:
+
+ successful-ok: no request attributes were substituted or ignored
+ (same as Print-Job) and no requested attributes were
+ unsupported.
+ successful-ok-ignored-or-substituted-attributes: same as Print-
+ Job, except the "requested-attributes" operation attribute MAY,
+ but NEED NOT, be returned with the unsupported values.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+ For the error status codes, Group 3 is returned containing no
+ attributes or is not returned at all:
+
+ client-error-not-possible: Same as Print-Job, in addition the
+ Printer object is not accepting any requests.
+ client-error-request-entity-too-large: same as Print-job, except
+ that no print data is involved.
+ client-error-attributes-or-values-not-supported: not applicable,
+ since unsupported operation attributes MUST be ignored and '
+ successful-ok-ignored-or-substituted-attributes' returned.
+ client-error-conflicting-attributes: same as Print-Job, except
+ that "ipp-attribute-fidelity" is not involved.
+ server-error-operation-not-supported: not applicable (since Get-
+ Printer-Attributes is REQUIRED).
+ server-error-device-error: same as Print-Job, except that no
+ document data is involved.
+ server-error-temporary-error: same as Print-Job, except that no
+ document data is involved.
+ server-error-not-accepting-jobs: not applicable.
+
+
+
+
+Hastings & Manros Informational [Page 41]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ server-error-busy: same as Print-Job, except the IPP object is
+ too busy to accept even query requests.
+ server-error-job-canceled: not applicable.
+
+2.3.1.6 Get-Jobs
+
+ All of the Print-Job status codes described in Section 3.2.1.2
+ Print-Job Response are applicable to the Get-Jobs operation with the
+ following specializations and differences. See Section 14 for a
+ more complete description of each status code.
+
+ For the following success status codes, the requested attributes are
+ returned in Group 3 in the response:
+
+ successful-ok: no request attributes were substituted or ignored
+ (same as Print-Job) and no requested attributes were
+ unsupported.
+ successful-ok-ignored-or-substituted-attributes: same as Print-
+ Job, except the "requested-attributes" operation attribute MAY,
+ but NEED NOT, be returned with the unsupported values.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+ For any error status codes, Group 3 is returned containing no
+ attributes or is not returned at all. The following brief error
+ status code descriptions contain unique information for use with
+ Get-Jobs operation. See section 14 for the other error status codes
+ that apply uniformly to all operations:
+
+ client-error-not-possible: Same as Print-Job, in addition the
+ Printer object is not accepting any requests.
+ client-error-request-entity-too-large: same as Print-job, except
+ that no print data is involved.
+ client-error-document-format-not-supported: not applicable.
+ client-error-attributes-or-values-not-supported: not applicable,
+ since unsupported operation attributes MUST be ignored and '
+ successful-ok-ignored-or-substituted-attributes' returned.
+ client-error-conflicting-attributes: same as Print-Job, except
+ that "ipp-attribute-fidelity" is not involved.
+ server-error-operation-not-supported: not applicable (since Get-
+ Jobs is REQUIRED).
+ server-error-device-error: same as Print-Job, except that no
+ document data is involved.
+ server-error-temporary-error: same as Print-Job, except that no
+ document data is involved.
+ server-error-not-accepting-jobs: not applicable.
+ server-error-job-canceled: not applicable.
+
+
+
+
+
+Hastings & Manros Informational [Page 42]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+2.3.2 Job Operations
+
+2.3.2.1 Send-Document
+
+ All of the Print-Job status codes described in Section 3.2.1.2
+ Print-Job Response are applicable to the Get-Printer-Attributes
+ operation with the following specializations and differences. See
+ Section 14 for a more complete description of each status code.
+
+ For the following success status codes, the document has been added
+ to the specified Job object and the job's "number-of-documents"
+ attribute has been incremented:
+
+ successful-ok: no request attributes were substituted or ignored
+ (same as Print-Job).
+ successful-ok-ignored-or-substituted-attributes: same as Print-
+ Job.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+ For the error status codes, no document has been added to the Job
+ object and the job's "number-of-documents" attribute has not been
+ incremented:
+
+ client-error-not-possible: Same as Print-Job, except that the
+ Printer's "printer-is-accepting-jobs" attribute is not
+ involved, so that the client is able to finish submitting a
+ multi-document job after this attribute has been set to 'true'.
+ Another condition is that the state of the job precludes Send-
+ Document, i.e., the job has already been closed out by the
+ client. However, if the IPP Printer closed out the job due to
+ timeout, the 'client-error-timeout' error status SHOULD be
+ returned instead.
+ client-error-timeout: This request was sent after the Printer
+ closed the job, because it has not received a Send-Document or
+ Send-URI operation within the Printer's "multiple-operation-
+ time-out" period.
+ client-error-request-entity-too-large: same as Print-Job.
+ client-error-conflicting-attributes: same as Print-Job, except
+ that "ipp-attributes-fidelity" operation attribute is not
+ involved.
+ server-error-operation-not-supported: the Send-Document request
+ is not supported.
+ server-error-not-accepting-jobs: not applicable.
+ server-error-job-canceled: the job has been canceled by an
+ operator or the system while the client was transmitting the
+ data.
+
+
+
+
+
+Hastings & Manros Informational [Page 43]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+2.3.2.2 Send-URI
+
+ All of the Print-Job status code descriptions in Section 3.2.1.2
+ Print-Job Response with the specializations described for Send-
+ Document are applicable to Send-URI. See Section 14 for a more
+ complete description of each status code.
+
+ server-error-uri-scheme-not-supported: the URI scheme supplied in
+ the "document-uri" operation attribute is not supported and the
+ "document-uri" attribute MUST be returned in the Unsupported
+ Attributes group.
+
+2.3.2.3 Cancel-Job
+
+ All of the Print-Job status codes described in Section 3.2.1.2
+ Print-Job Response are applicable to Cancel-Job with the following
+ specializations and differences. See Section 14 for a more complete
+ description of each status code.
+
+ For the following success status codes, the Job object is being
+ canceled or has been canceled:
+
+ successful-ok: no request attributes were substituted or ignored
+ (same as Print-Job).
+ successful-ok-ignored-or-substituted-attributes: same as Print-
+ Job.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+ For any of the error status codes, the Job object has not been
+ canceled or was previously canceled.
+
+ client-error-not-possible: The request cannot be carried out
+ because of the state of the Job object ('completed', '
+ canceled', or 'aborted') or the state of the system.
+ client-error-not-found: the target Printer and/or Job object does
+ not exist.
+ client-error-gone: the target Printer and/or Job object no longer
+ exists and no forwarding address is known.
+ client-error-request-entity-too-large: same as Print-Job, except
+ no document data is involved.
+ client-error-document-format-not-supported: not applicable.
+ client-error-attributes-or-values-not-supported: not applicable,
+ since unsupported operation attributes and values MUST be
+ ignored.
+ client-error-conflicting-attributes: same as Print-Job, except
+ that the Printer's "printer-is-accepting-jobs" attribute is not
+ involved.
+
+
+
+
+Hastings & Manros Informational [Page 44]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ server-error-operation-not-supported: not applicable (Cancel-Job
+ is REQUIRED).
+ server-error-device-error: same as Print-Job, except no document
+ data is involved.
+ server-error-temporary-error: same as Print-Job, except no
+ document data is involved.
+ server-error-not-accepting-jobs: not applicable.
+ server-error-job-canceled: not applicable.
+
+2.3.2.4 Get-Job-Attributes
+
+ All of the Print-Job status codes described in Section 3.2.1.2
+ Print-Job Response are applicable to Get-Job-Attributes with the
+ following specializations and differences. See Section 14 for a more
+ complete description of each status code.
+
+ For the following success status codes, the requested attributes are
+ returned in Group 3 in the response:
+
+ successful-ok: no request attributes were substituted or ignored
+ (same as Print-Job) and no requested attributes were
+ unsupported.
+ successful-ok-ignored-or-substituted-attributes: same as Print-
+ Job, except the "requested-attributes" operation attribute MAY,
+ but NEED NOT, be returned with the unsupported values.
+ successful-ok-conflicting-attributes: same as Print-Job.
+
+ For the error status codes, Group 3 is returned containing no
+ attributes or is not returned at all.
+
+ client-error-not-possible: Same as Print-Job, in addition the
+ Printer object is not accepting any requests.
+ client-error-document-format-not-supported: not applicable.
+ client-error-attributes-or-values-not-supported: not applicable.
+ client-error-uri-scheme-not-supported: not applicable.
+ client-error-conflicting-attributes: not applicable
+ server-error-operation-not-supported: not applicable (since Get-
+ Job-Attributes is REQUIRED).
+ server-error-device-error: same as Print-Job, except no document
+ data is involved.
+ server-error-temporary-error: sane as Print-Job, except no
+ document data is involved.
+ server-error-not-accepting-jobs: not applicable. server-error-
+ job-canceled: not applicable.
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 45]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+2.4 Validate-Job
+
+ The Validate-Job operation has been designed so that its
+ implementation may be a part of the Print-Job operation. Therefore,
+ requiring Validate-Job is not a burden on implementers. Also it is
+ useful for client's to be able to count on its presence in all
+ conformance implementations, so that the client can determine before
+ sending a long document, whether the job will be accepted by the IPP
+ Printer or not.
+
+2.5 Case Sensitivity in URIs
+
+ IPP client and server implementations must be aware of the diverse
+ uppercase/lowercase nature of URIs. RFC 2396 defines URL schemes and
+ Host names as case insensitive but reminds us that the rest of the
+ URL may well demonstrate case sensitivity. When creating URL's for
+ fields where the choice is completely arbitrary, it is probably best
+ to select lower case. However, this cannot be guaranteed and
+ implementations MUST NOT rely on any fields being case-sensitive or
+ case-insensitive in the URL beyond the URL scheme and host name
+ fields.
+
+ The reason that the IPP specification does not make any restrictions
+ on URIs, is so that implementations of IPP may use off-the-shelf
+ components that conform to the standards that define URIs, such as
+ RFC 2396 and the HTTP/1.1 specifications [RFC2068]. See these
+ specifications for rules of matching, comparison, and case-
+ sensitivity.
+
+ It is also recommended that System Administrators and implementations
+ avoid creating URLs for different printers that differ only in their
+ case. For example, don't have Printer1 and printer1 as two different
+ IPP Printers.
+
+ The HTTP/1.1 specification [RFC2068] contains more details on
+ comparing URLs.
+
+2.6 Character Sets, natural languages, and internationalization
+
+ This section discusses character set support, natural language
+ support and internationalization.
+
+2.6.1 Character set code conversion support
+
+ IPP clients and IPP objects are REQUIRED to support UTF-8. They MAY
+ support additional charsets. It is RECOMMENDED that an IPP object
+ also support US-ASCII, since many clients support US-ASCII, and
+ indicate that UTF-8 and US-ASCII are supported by populating the
+
+
+
+Hastings & Manros Informational [Page 46]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Printer's "charset-supported" with 'utf-8' and 'us-ascii' values. An
+ IPP object is required to code covert with as little loss as possible
+ between the charsets that it supports, as indicated in the Printer's
+ "charsets-supported" attribute.
+
+ How should the server handle the situation where the "attributes-
+ charset" of the response itself is "us-ascii", but one or more
+ attributes in that response is in the "utf-8" format?
+
+ Example: Consider a case where a client sends a Print-Job request
+ with "utf-8" as the value of "attributes-charset" and with the "job-
+ name" attribute supplied. Later another client submits a Get-Job-
+ Attribute or Get-Jobs request. This second request contains the
+ "attributes-charset" with value "us-ascii" and "requested-attributes"
+ attribute with exactly one value "job-name".
+
+ According to the RFC2566 document (section 3.1.4.2), the value of the
+ "attributes-charset" for the response of the second request must be
+ "us-ascii" since that is the charset specified in the request. The
+ "job-name" value, however, is in "utf-8" format. Should the request
+ be rejected even though both "utf-8" and "us-ascii" charsets are
+ supported by the server? or should the "job-name" value be converted
+ to "us-ascii" and return "successful-ok-conflicting-attributes"
+ (0x0002) as the status code?
+
+ Answer: An IPP object that supports both utf-8 (REQUIRED) and us-
+ ascii, the second paragraph of section 3.1.4.2 applies so that the
+ IPP object MUST accept the request, perform code set conversion
+ between these two charsets with "the highest fidelity possible" and
+ return 'successful-ok', rather than a warning 'successful-ok-
+ conflicting-attributes, or an error. The printer will do the best it
+ can to convert between each of the character sets that it supports--
+ even if that means providing a string of question marks because none
+ of the characters are representable in US ASCII. If it can't perform
+ such conversion, it MUST NOT advertise us-ascii as a value of its
+ "attributes-charset-supported" and MUST reject any request that
+ requests 'us-ascii'.
+
+ One IPP object implementation strategy is to convert all request text
+ and name values to a Unicode internal representation. This is 16-bit
+ and virtually universal. Then convert to the specified operation
+ attributes-charset on output.
+
+ Also it would be smarter for a client to ask for 'utf-8', rather than
+ 'us-ascii' and throw away characters that it doesn't understand,
+ rather than depending on the code conversion of the IPP object.
+
+
+
+
+
+Hastings & Manros Informational [Page 47]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+2.6.2 What charset to return when an unsupported charset is requested?
+
+ Section 3.1.4.1 Request Operation attributes was clarified in
+ November 1998 as follows:
+
+ All clients and IPP objects MUST support the 'utf-8' charset
+ [RFC2044] and MAY support additional charsets provided that they
+ are registered with IANA [IANA-CS]. If the Printer object does
+ not support the client supplied charset value, the Printer object
+ MUST reject the request, set the "attributes-charset" to 'utf-8'
+ in the response, and return the 'client-error-charset-not-
+ supported' status code and any 'text' or 'name' attributes using
+ the 'utf-8' charset.
+
+ Since the client and IPP object MUST support UTF-8, returning any
+ text or name attributes in UTF-8 when the client requests a charset
+ that is not supported should allow the client to display the text or
+ name.
+
+ Since such an error is a client error, rather than a user error, the
+ client should check the status code first so that it can avoid
+ displaying any other returned 'text' and 'name' attributes that are
+ not in the charset requested.
+
+ Furthermore, [RFC2566] section 14.1.4.14 client-error-charset-not-
+ supported (0x040D) was clarified in November 1998 as follows:
+
+ For any operation, if the IPP Printer does not support the charset
+ supplied by the client in the "attributes-charset" operation
+ attribute, the Printer MUST reject the operation and return this
+ status and any 'text' or 'name' attributes using the 'utf-8'
+ charset (see Section 3.1.4.1).
+
+2.6.3 Natural Language Override (NLO)
+
+ The 'text' and 'name' attributes each have two forms. One has an
+ implicit natural language, and the other has an explicit natural
+ language. The 'textWithoutLanguage' and 'textWithoutLanguage' are
+ the two 'text' forms. The 'nameWithoutLanguage" and '
+ nameWithLanguage are the two 'name' forms. If a receiver (IPP object
+ or IPP client) supports an attribute with attribute syntax 'text', it
+ MUST support both forms in a request and a response. A sender (IPP
+ client or IPP object) MAY send either form for any such attribute.
+ When a sender sends a WithoutLanguage form, the implicit natural
+ language is specified in the "attributes-natural-language" operation
+ attribute which all senders MUST include in every request and
+ response.
+
+
+
+
+Hastings & Manros Informational [Page 48]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ When a sender sends a WithLanguage form, it MAY be different from the
+ implicit natural language supplied by the sender or it MAY be the
+ same. The receiver MUST treat either form equivalently.
+
+ There is an implementation decision for senders, whether to always
+ send the WithLanguage forms or use the WithoutLanguage form when the
+ attribute's natural language is the same as the request or response.
+ The former approach makes the sender implementation simpler. The
+ latter approach is more efficient on the wire and allows inter-
+ working with non-conforming receivers that fail to support the
+ WithLanguage forms. As each approach have advantages, the choice is
+ completely up to the implementer of the sender.
+
+ Furthermore, when a client receives a 'text' or 'name' job attribute
+ that it had previously supplied, that client MUST NOT expect to see
+ the attribute in the same form, i.e., in the same WithoutLanguage or
+ WithLanguage form as the client supplied when it created the job.
+ The IPP object is free to transform the attribute from the
+ WithLanguage form to the WithoutLanguage form and vice versa, as long
+ as the natural language is preserved. However, in order to meet this
+ latter requirement, it is usually simpler for the IPP object
+ implementation to store the natural language explicitly with the
+ attribute value, i.e., to store using an internal representation that
+ resembles the WithLanguage form.
+
+ The IPP Printer MUST copy the natural language of a job, i.e., the
+ value of the "attributes-natural-language" operation attribute
+ supplied by the client in the create operation, to the Job object as
+ a Job Description attribute, so that a client is able to query it.
+ In returning a Get-Job-Attributes response, the IPP object MAY return
+ one of three natural language values in the response's "attributes-
+ natural-language" operation attribute: (1) that requested by the
+ requester, (2) the natural language of the job, or (3) the configured
+ natural language of the IPP Printer, if the requested language is not
+ supported by the IPP Printer.
+
+ This "attributes-natural-language" Job Description attribute is
+ useful for an IPP object implementation that prints start sheets in
+ the language of the user who submitted the job. This same Job
+ Description attribute is useful to a multi-lingual operator who has
+ to communicate with different job submitters in different natural
+ languages. This same Job Description attribute is expected to be
+ used in the future to generate notification messages in the natural
+ language of the job submitter.
+
+ Early drafts of [RFC2566] contained a job-level natural language
+ override (NLO) for the Get-Jobs response. A job-level (NLO) is an
+ (unrequested) Job Attribute which then specified the implicit natural
+
+
+
+Hastings & Manros Informational [Page 49]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ language for any other WithoutLanguage job attributes returned in the
+ response for that job. Interoperability testing of early
+ implementations showed that no one was implementing the job-level NLO
+ in Get-Job responses. So the job-level NLO was eliminated from the
+ Get- Jobs response. This simplification makes all requests and
+ responses consistent in that the implicit natural language for any
+ WithoutLanguage 'text' or 'name' form is always supplied in the
+ request's or response's "attributes-natural-language" operation
+ attribute.
+
+2.7 The "queued-job-count" Printer Description attribute
+
+2.7.1 Why is "queued-job-count" RECOMMENDED?
+
+ The reason that "queued-job-count" is RECOMMENDED, is that some
+ clients look at that attribute alone when summarizing the status of a
+ list of printers, instead of doing a Get-Jobs to determine the number
+ of jobs in the queue. Implementations that fail to support the
+ "queued-job-count" will cause that client to display 0 jobs when
+ there are actually queued jobs.
+
+ We would have made it a REQUIRED Printer attribute, but some
+ implementations had already been completed before the issue was
+ raised, so making it a SHOULD was a compromise.
+
+2.7.2 Is "queued-job-count" a good measure of how busy a printer is?
+
+ The "queued-job-count" is not a good measure of how busy the printer
+ is when there are held jobs. A future registration could be to add a
+ "held-job-count" (or an "active-job-count") Printer Description
+ attribute if experience shows that such an attribute (combination) is
+ needed to quickly indicate how busy a printer really is.
+
+2.8 Sending empty attribute groups
+
+ The [RFC2566] and [RFC2565] specifications RECOMMEND that a sender
+ not send an empty attribute group in a request or a response.
+ However, they REQUIRE a receiver to accept an empty attribute group
+ as equivalent to the omission of that group. So a client SHOULD omit
+ the Job Template Attributes group entirely in a create operation that
+ is not supplying any Job Template attributes. Similarly, an IPP
+ object SHOULD omit an empty Unsupported Attributes group if there are
+ no unsupported attributes to be returned in a response.
+
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 50]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ The [RFC2565] specification REQUIRES a receiver to be able to receive
+ either an empty attribute group or an omitted attribute group and
+ treat them equivalently. The term "receiver" means an IPP object for
+ a request and a client for a response. The term "sender' means a
+ client for a request and an IPP object for a response.
+
+ There is an exception to the rule for Get-Jobs when there are no
+ attributes to be returned. [RFC2565] contains the following
+ paragraph:
+
+ The syntax allows an xxx-attributes-tag to be present when the
+ xxx-attribute-sequence that follows is empty. The syntax is
+ defined this way to allow for the response of Get-Jobs where no
+ attributes are returned for some job-objects. Although it is
+ RECOMMENDED that the sender not send an xxx-attributes-tag if
+ there are no attributes (except in the Get-Jobs response just
+ mentioned), the receiver MUST be able to decode such syntax.
+
+2.9 Returning unsupported attributes in Get-Xxxx responses
+
+ In the Get-Printer-Attributes, Get-Jobs, or Get-Job-Attributes
+ responses, the client cannot depend on getting unsupported attributes
+ returned in the Unsupported Attributes group that the client
+ requested, but are not supported by the IPP object. However, such
+ unsupported requested attributes will not be returned in the Job
+ Attributes or Printer Attributes group (since they are unsupported).
+ Furthermore, the IPP object is REQUIRED to return the 'successful-
+ ok-ignored-or-substituted-attributes' status code, so that the client
+ knows that not all that was requested has been returned.
+
+2.10 Returning job-state in Print-Job response
+
+ An IPP client submits a small job via Print-Job. By the time the IPP
+ printer/print server is putting together a response to the operation,
+ the job has finished printing and been removed as an object from the
+ print system. What should the job-state be in the response?
+
+ The Model suggests that the Printer return a response before it even
+ accepts the document content. The Job Object Attributes are returned
+ only if the IPP object returns one of the success status codes. Then
+ the job-state would always be "pending" or "pending-held".
+
+ This issue comes up for the implementation of an IPP Printer object
+ as a server that forwards jobs to devices that do not provide job
+ status back to the server. If the server is reasonably certain that
+ the job completed successfully, then it should return the job-state
+ as 'completed'. Also the server can keep the job in its "job
+ history" long after the job is no longer in the device. Then a user
+
+
+
+Hastings & Manros Informational [Page 51]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ could query the server and see that the job was in the 'completed'
+ state and completed as specified by the job's "time-at-completed"
+ time which would be the same as the server submitted the job to the
+ device.
+
+ An alternative is for the server to respond to the client before or
+ while sending the job to the device, instead of waiting until the
+ server has finished sending the job to the device. In this case, the
+ server can return the job's state as 'pending' with the 'job-
+ outgoing' value in the job's "job-state-reasons" attribute.
+
+ If the server doesn't know for sure whether the job completed
+ successfully (or at all), it could return the (out-of-band) 'unknown'
+ value.
+
+ On the other hand, if the server is able to query the device and/or
+ setup some sort of event notification that the device initiates when
+ the job makes state transitions, then the server can return the
+ current job state in the Print-Job response and in subsequent queries
+ because the server knows what the job state is in the device (or can
+ query the device).
+
+ All of these alternatives depend on implementation of the server and
+ the device.
+
+2.11 Flow controlling the data portion of a Print-Job request
+
+ A paused printer (or one that is stopped due to paper out or jam or
+ spool space full or buffer space full, may flow control the data of a
+ Print-Job operation (at the TCP/IP layer), so that the client is not
+ able to send all the document data. Consequently, the Printer will
+ not return a response until the condition is changed.
+
+ The Printer should not return a Print-Job response with an error code
+ in any of these conditions, since either the printer will be resumed
+ and/or the condition will be freed either by human intervention or as
+ jobs print.
+
+ In writing test scripts to test IPP Printers, the script must also be
+ written not to expect a response, if the printer has been paused,
+ until the printer is resumed, in order to work with all possible
+ implementations.
+
+2.12 Multi-valued attributes
+
+ What is the attribute syntax for a multi-valued attribute? Since
+ some attributes support values in more than one data type, such as
+ "media", "job-hold-until", and "job-sheets", IPP semantics associate
+
+
+
+Hastings & Manros Informational [Page 52]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ the attribute syntax with each value, not with the attribute as a
+ whole. The protocol associates the attribute syntax tag with each
+ value. Don't be fooled, just because the attribute syntax tag comes
+ before the attribute keyword. All attribute values after the first
+ have a zero length attribute keyword as the indication of a
+ subsequent value of the same attribute.
+
+2.13 Querying jobs with IPP that were submitted using other job
+ submission protocols
+
+ The following clarification was added to [RFC2566] section 8.5:
+
+ 8.5 Queries on jobs submitted using non-IPP protocols
+
+ If the device that an IPP Printer is representing is able to
+ accept jobs using other job submission protocols in addition to
+ IPP, it is RECOMMEND that such an implementation at least allow
+ such "foreign" jobs to be queried using Get-Jobs returning "job-
+ id" and "job-uri" as 'unknown'. Such an implementation NEED NOT
+ support all of the same IPP job attributes as for IPP jobs. The
+ IPP object returns the 'unknown' out-of-band value for any
+ requested attribute of a foreign job that is supported for IPP
+ jobs, but not for foreign jobs.
+
+ It is further RECOMMENDED, that the IPP Printer generate "job-id"
+ and "job-uri" values for such "foreign jobs", if possible, so that
+ they may be targets of other IPP operations, such as Get-Job-
+ Attributes and Cancel-Job. Such an implementation also needs to
+ deal with the problem of authentication of such foreign jobs. One
+ approach would be to treat all such foreign jobs as belonging to
+ users other than the user of the IPP client. Another approach
+ would be for the foreign job to belong to 'anonymous'. Only if
+ the IPP client has been authenticated as an operator or
+ administrator of the IPP Printer object, could the foreign jobs be
+ queried by an IPP request. Alternatively, if the security policy
+ is to allow users to query other users' jobs, then the foreign
+ jobs would also be visible to an end-user IPP client using Get-
+ Jobs and Get-Job-Attributes.
+
+ Thus IPP MAY be implemented as a "universal" protocol that provides
+ access to jobs submitted with any job submission protocol. As IPP
+ becomes widely implemented, providing a more universal access makes
+ sense.
+
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 53]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+2.14 The 'none' value for empty sets
+
+ [RFC2566] states that the 'none' value should be used as the value of
+ a 1SetOf when the set is empty. In most cases, sets that are
+ potentially empty contain keywords so the keyword 'none' is used, but
+ for the 3 finishings attributes, the values are enums and thus the
+ empty set is represented by the enum 3. Currently there are no other
+ attributes with 1SetOf values which can be empty and can contain
+ values that are not keywords. This exception requires special code
+ and is a potential place for bugs. It would have been better if we
+ had chosen an out-of-band value, either "no-value" or some new value,
+ such as 'none'. Since we didn't, implementations have to deal with
+ the different representations of 'none', depending on the attribute
+ syntax.
+
+2.15 Get-Jobs, my-jobs='true', and 'requesting-user-name'?
+
+ In [RFC2566] section 3.2.6.1 'Get-Jobs Request', if the attribute '
+ my-jobs' is present and set to TRUE, MUST the 'requesting-user-name'
+ attribute be there to, and if it's not present what should the IPP
+ printer do?
+
+ [RFC2566] Section 8.3 describes the various cases of "requesting-
+ user-name" being present or not for any operation. If the client
+ does not supply a value for "requesting-user-name", the printer MUST
+ assume that the client is supplying some anonymous name, such as
+ "anonymous".
+
+2.16 The "multiple-document-handling" Job Template attribute and support
+ of multiple document jobs
+
+ ISSUE: IPP/1.0 is silent on which of the four effects an
+ implementation would perform if it supports Create-Job, but does not
+ support "multiple-document-handling".
+
+ A fix to IPP/1.0 would be to require implementing all four values of
+ "multiple-document-handling" if Create-Job is supported at all. Or
+ at least 'single-document-new-sheet' and 'separate-documents-
+ uncollated-copies'. In any case, an implementation that supports
+ Create-Job SHOULD also support "multiple-document-handling". Support
+ for all four values is RECOMMENDED, but at least the 'single-
+ document-new-sheet' and 'separate-documents-uncollated-copies'
+ values, along with the "multiple-document-handling-default"
+ indicating the default behavior and "multiple-document-handling-
+ supported" values. If an implementation spools the data, it should
+ also support the 'separate-documents-collated-copies' value as well.
+
+
+
+
+
+Hastings & Manros Informational [Page 54]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+3 Encoding and Transport
+
+ This section discusses various aspects of IPP/1.0 Encoding and
+ Transport [RFC2565].
+
+ A server is not required to send a response until after it has
+ received the client.s entire request. Hence, a client must not
+ expect a response until after it has sent the entire request.
+ However, we recommend that the server return a response as soon as
+ possible if an error is detected while the client is still sending
+ the data, rather than waiting until all of the data is received.
+ Therefore, we also recommend that a client listen for an error
+ response that an IPP server MAY send before it receives all the data.
+ In this case a client, if chunking the data, can send a premature
+ zero-length chunk to end the request before sending all the data (and
+ so the client can keep the connection open for other requests, rather
+ than closing it). If the request is blocked for some reason, a client
+ MAY determine the reason by opening another connection to query the
+ server using Get-Printer-Attributes.
+
+ In the following sections, there are a tables of all HTTP headers
+ which describe their use in an IPP client or server. The following
+ is an explanation of each column in these tables.
+
+ - the .header. column contains the name of a header.
+ - the .request/client. column indicates whether a client sends the
+ header.
+ - the .request/ server. column indicates whether a server supports
+ the header when received.
+ - the .response/ server. column indicates whether a server sends
+ the header.
+ - the .response /client. column indicates whether a client
+ supports the header when received.
+ - the .values and conditions. column specifies the allowed header
+ values and the conditions for the header to be present in a
+ request/response.
+
+ The table for .request headers. does not have columns for responses,
+ and the table for .response headers. does not have columns for
+ requests.
+
+ The following is an explanation of the values in the .request/client.
+ and .response/ server. columns.
+
+ - must: the client or server MUST send the header,
+ - must-if: the client or server MUST send the header when the
+ condition described in the .values and conditions. column is
+ met,
+
+
+
+Hastings & Manros Informational [Page 55]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ - may: the client or server MAY send the header
+ - not: the client or server SHOULD NOT send the header. It is not
+ relevant to an IPP implementation.
+
+ The following is an explanation of the values in the
+ .response/client. and .request/ server. columns.
+
+ - must: the client or server MUST support the header,
+ - may: the client or server MAY support the header
+ - not: the client or server SHOULD NOT support the header. It is
+ not relevant to an IPP implementation.
+
+3.1 General Headers
+
+
+ The following is a table for the general headers.
+
+
+ General- Request Response Values and Conditions
+ Header
+
+ Client Server Server Client
+
+ Cache- must not must not .no-cache. only
+ Control
+
+ Connection must-if must must- must .close. only. Both
+ if client and server
+ SHOULD keep a
+ connection for the
+ duration of a sequence
+ of operations. The
+ client and server MUST
+ include this header
+ for the last operation
+ in such a sequence.
+
+ Date may may must may per RFC 1123 [RFC1123]
+ from RFC 2068
+ [RFC2068]
+
+ Pragma must not must not .no-cache. only
+
+ Transfer- must-if must must- must .chunked. only .
+ Encoding if Header MUST be present
+ if Content-Length is
+ absent.
+
+
+
+
+Hastings & Manros Informational [Page 56]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Upgrade not not not not
+
+ Via not not not not
+
+3.2 Request Headers
+
+
+ The following is a table for the request headers.
+
+
+ Request-Header Client Server Request Values and Conditions
+
+ Accept may must .application/ipp. only. This
+ value is the default if the
+
+ Request-Header Client Server Request Values and Conditions
+
+ client omits it
+
+ Accept-Charset not not Charset information is within
+ the application/ipp entity
+
+ Accept-Encoding may must empty and per RFC 2068 [RFC2068]
+ and IANA registry for content-
+ codings
+
+ Accept-Language not not language information is within
+ the application/ipp entity
+
+ Authorization must-if must per RFC 2068. A client MUST send
+ this header when it receives a
+ 401 .Unauthorized. response and
+ does not receive a .Proxy-
+ Authenticate. header.
+
+ From not not per RFC 2068. Because RFC
+ recommends sending this header
+ only with the user.s approval, it
+ is not very useful
+
+ Host must must per RFC 2068
+
+ If-Match not not
+
+ If-Modified- not not
+ Since
+
+ If-None-Match not not
+
+
+
+Hastings & Manros Informational [Page 57]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ If-Range not not
+
+ If-Unmodified- not not
+ Since
+
+ Max-Forwards not not
+
+ Proxy- must-if not per RFC 2068. A client MUST send
+ Authorization this header when it receives a
+ 401 .Unauthorized. response and a
+ .Proxy-Authenticate. header.
+
+ Range not not
+
+ Referer not not
+
+ User-Agent not not
+
+
+3.3 Response Headers
+
+
+ The following is a table for the request headers.
+
+
+ Response- Server Client Response Values and Conditions
+ Header
+
+ Accept-Ranges not not
+
+ Age not not
+
+ Location must-if may per RFC 2068. When URI needs
+ redirection.
+
+ Proxy- not must per RFC 2068
+ Authenticate
+
+ Public may may per RFC 2068
+
+ Retry-After may may per RFC 2068
+
+ Server not not
+
+ Vary not not
+
+ Warning may may per RFC 2068
+
+
+
+
+Hastings & Manros Informational [Page 58]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ WWW- must-if must per RFC 2068. When a server needs to
+ Authenticate authenticate a client.
+
+3.4 Entity Headers
+
+
+ The following is a table for the entity headers.
+
+
+ Entity-Header Request Response Values and Conditions
+
+ Client Server Server Client
+
+ Allow not not not not
+
+ Content-Base not not not not
+
+ Content- may must must must per RFC 2068 and IANA
+ Encoding registry for content
+ codings.
+
+ Content- not not not not Application/ipp
+ Language handles language
+
+ Content- must-if must must-if must the length of the
+ Length message-body per RFC
+ 2068. Header MUST be
+ present if Transfer-
+
+ Entity-Header Request Response Values and Conditions
+
+ Client Server Server Client
+
+ Encoding is absent.
+
+ Content- not not not not
+ Location
+
+ Content-MD5 may may may may per RFC 2068
+
+ Content-Range not not not not
+
+ Content-Type must must must must .application/ipp.
+ only
+
+ ETag not not not not
+
+ Expires not not not not
+
+
+
+Hastings & Manros Informational [Page 59]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Last-Modified not not not not
+
+
+3.5 Optional support for HTTP/1.0
+
+ IPP implementations consist of an HTTP layer and an IPP layer. In
+ the following discussion, the term "client" refers to the HTTP client
+ layer and the term "server" refers to the HTTP server layer. The
+ Encoding and Transport document [RFC2565] requires that HTTP 1.1 MUST
+ be supported by all clients and all servers. However, a client
+ and/or a server implementation may choose to also support HTTP 1.0.
+
+ - This option means that a server may choose to communicate with a
+ (non-conforming) client that only supports HTTP 1.0. In such cases
+ the server should not use any HTTP 1.1 specific parameters or
+ features and should respond using HTTP version number 1.0.
+
+ - This option also means that a client may choose to communicate with
+ a (non-conforming) server that only supports HTTP 1.0. In such
+ cases, if the server responds with an HTTP .unsupported version
+ number. to an HTTP 1.1 request, the client should retry using HTTP
+ version number 1.0.
+
+3.6 HTTP/1.1 Chunking
+
+3.6.1 Disabling IPP Server Response Chunking
+
+ Clients MUST anticipate that the HTTP/1.1 server may chunk responses
+ and MUST accept them in responses. However, a (non-conforming) HTTP
+ client that is unable to accept chunked responses may attempt to
+ request an HTTP 1.1 server not to use chunking in its response to an
+ operation by using the following HTTP header:
+
+ TE: identity
+
+ This mechanism should not be used by a server to disable a client
+ from chunking a request, since chunking of document data is an
+ important feature for clients to send long documents.
+
+3.6.2 Warning About the Support of Chunked Requests
+
+ This section describes some problems with the use of chunked requests
+ and HTTP/1.1 servers.
+
+ The HTTP/1.1 standard [HTTP] requires that conforming servers support
+ chunked requests for any method. However, in spite of this
+ requirement, some HTTP/1.1 implementations support chunked responses
+ in the GET method, but do not support chunked POST method requests.
+
+
+
+Hastings & Manros Informational [Page 60]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ Some HTTP/1.1 implementations that support CGI scripts [CGI] and/or
+ servlets [Servlet] require that the client supply a Content-Length.
+ These implementations might reject a chunked POST method and return a
+ 411 status code (Length Required), might attempt to buffer the
+ request and run out of room returning a 413 status code (Request
+ Entity Too Large), or might successfully accept the chunked request.
+
+ Because of this lack of conformance of HTTP servers to the HTTP/1.1
+ standard, the IPP standard [RFC2565] REQUIRES that a conforming IPP
+ Printer object implementation support chunked requests and that
+ conforming clients accept chunked responses. Therefore, IPP object
+ implementers are warned to seek HTTP server implementations that
+ support chunked POST requests in order to conform to the IPP standard
+ and/or use implementation techniques that support chunked POST
+ requests.
+
+4 References
+
+ [CGI] Coar, K. and D. Robinson, "The WWW Common Gateway Interface
+ Version 1.1 (CGI/1.1)", Work in Progress.
+
+ [HTTP] Fielding, R., Gettys,J., Mogul, J., Frystyk,, H., Masinter,
+ L., Leach, P. and T. Berners-Lee, "Hypertext Transfer
+ Protocol -- HTTP/1.1", RFC 2616, June 1999.
+
+ [RFC2569] Herriot, R., Hastings, T., Jacobs, N. and J. Martin,
+ "Mapping between LPD and IPP Protocols", RFC 2569, April
+ 1999.
+
+ [RFC2566] deBry, R., Hastings, T., Herriot, R., Isaacson, S. and P.
+ Powell, "Internet Printing Protocol/1.0: Model and
+ Semantics", RFC 2566, April 1999.
+
+ [RFC2565] Herriot, R., Butler, S., Moore, P. and R. Tuner, "Internet
+ Printing Protocol/1.0: Encoding and Transport", RFC 2565,
+ April 1999.
+
+ [RFC2568] Zilles, S., "Rationale for the Structure and Model and
+ Protocol for the Internet Printing Protocol", RFC 2568,
+ April 1999.
+
+ [RFC2567] Wright, D., "Design Goals for an Internet Printing
+ Protocol", RFC 2567, April 1999.
+
+ [RFC1123] Braden, S., "Requirements for Internet Hosts - Application
+ and Support", STD 3, RFC 1123, October 1989.
+
+
+
+
+
+Hastings & Manros Informational [Page 61]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ [RFC2026] Bradner, S., "The Internet Standards Process -- Revision
+ 3", BCP 9, RFC 2026, October 1996.
+
+ [RFC2068] Fielding, R., Gettys, J., Mogul, J., Frystyk, H. and T.
+ Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC
+ 2068, January 1997.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2396] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform
+ Resource Identifiers (URI): Generic Syntax", RFC 2396,
+ August 1998.
+
+ [Servlet] Servlet Specification Version 2.1
+ (http://java.sun.com/products/servlet/2.1/index.html).
+
+ [SSL] Netscape, The SSL Protocol, Version 3, (Text version 3.02),
+ November 1996.
+
+4.1 Authors' Addresses
+
+ Thomas N. Hastings
+ Xerox Corporation
+ 701 Aviation Blvd.
+ El Segundo, CA 90245
+
+ EMail: hastings@cp10.es.xerox.com
+
+
+ Carl-Uno Manros
+ Xerox Corporation
+ 701 Aviation Blvd.
+ El Segundo, CA 90245
+
+ EMail: manros@cp10.es.xerox.com
+
+5 Security Considerations
+
+ Security issues are discussed in sections 2.2, 2.3.1, and 8.5.
+
+6 Notices
+
+ The IETF takes no position regarding the validity or scope of any
+ intellectual property or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; neither does it represent that it
+
+
+
+Hastings & Manros Informational [Page 62]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+ has made any effort to identify any such rights. Information on the
+ IETF's procedures with respect to rights in standards-track and
+ standards-related documentation can be found in BCP-11 [BCP-11].
+ Copies of claims of rights made available for publication and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF Secretariat.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights which may cover technology that may be required to practice
+ this standard. Please address the information to the IETF Executive
+ Director.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 63]
+
+RFC 2639 IPP/1.0: Implementer's Guide July 1999
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings & Manros Informational [Page 64]
+
diff --git a/standards/rfc2712.txt b/standards/rfc2712.txt
new file mode 100644
index 000000000..4888e2e2d
--- /dev/null
+++ b/standards/rfc2712.txt
@@ -0,0 +1,395 @@
+
+
+
+
+
+
+Network Working Group A. Medvinsky
+Request for Comments: 2712 Excite
+Category: Standards Track M. Hur
+ CyberSafe Corporation
+ October 1999
+
+
+ Addition of Kerberos Cipher Suites to Transport Layer Security (TLS)
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+IESG Note:
+
+ The 40-bit ciphersuites defined in this memo are included only for
+ the purpose of documenting the fact that those ciphersuite codes have
+ already been assigned. 40-bit ciphersuites were designed to comply
+ with US-centric, and now obsolete, export restrictions. They were
+ never secure, and nowadays are inadequate even for casual
+ applications. Implementation and use of the 40-bit ciphersuites
+ defined in this document, and elsewhere, is strongly discouraged.
+
+1. Abstract
+
+ This document proposes the addition of new cipher suites to the TLS
+ protocol [1] to support Kerberos-based authentication. Kerberos
+ credentials are used to achieve mutual authentication and to
+ establish a master secret which is subsequently used to secure
+ client-server communication.
+
+2. Introduction
+
+ Flexibility is one of the main strengths of the TLS protocol.
+ Clients and servers can negotiate cipher suites to meet specific
+ security and administrative policies. However, to date,
+ authentication in TLS is limited only to public key solutions. As a
+ result, TLS does not fully support organizations with heterogeneous
+ security deployments that include authentication systems based on
+ symmetric cryptography. Kerberos, originally developed at MIT, is
+
+
+
+Medvinsky & Hur Standards Track [Page 1]
+
+RFC 2712 Addition of Kerberos Cipher Suites to TLS October 1999
+
+
+ based on an open standard [2] and is the most widely deployed
+ symmetric key authentication system. This document proposes a new
+ option for negotiating Kerberos authentication within the TLS
+ framework. This achieves mutual authentication and the establishment
+ of a master secret using Kerberos credentials. The proposed changes
+ are minimal and, in fact, no different from adding a new public key
+ algorithm to the TLS framework.
+
+3. Kerberos Authentication Option In TLS
+
+ This section describes the addition of the Kerberos authentication
+ option to the TLS protocol. Throughout this document, we refer to
+ the basic SSL handshake shown in Figure 1. For a review of the TLS
+ handshake see [1].
+
+ CLIENT SERVER
+ ------ ------
+ ClientHello
+ -------------------------------->
+ ServerHello
+ Certificate *
+ ServerKeyExchange*
+ CertificateRequest*
+ ServerHelloDone
+ <-------------------------------
+ Certificate*
+ ClientKeyExchange
+ CertificateVerify*
+ change cipher spec
+ Finished
+ | -------------------------------->
+ | change cipher spec
+ | Finished
+ | |
+ | |
+ Application Data <------------------------------->Application Data
+
+ FIGURE 1: The TLS protocol. All messages followed by a star are
+ optional. Note: This figure was taken from an IETF document
+ [1].
+
+ The TLS security context is negotiated in the client and server hello
+ messages. For example: TLS_RSA_WITH_RC4_MD5 means the initial
+ authentication will be done using the RSA public key algorithm, RC4
+ will be used for the session key, and MACs will be based on the MD5
+ algorithm. Thus, to facilitate the Kerberos authentication option,
+ we must start by defining new cipher suites including (but not
+ limited to):
+
+
+
+Medvinsky & Hur Standards Track [Page 2]
+
+RFC 2712 Addition of Kerberos Cipher Suites to TLS October 1999
+
+
+ CipherSuite TLS_KRB5_WITH_DES_CBC_SHA = { 0x00,0x1E };
+ CipherSuite TLS_KRB5_WITH_3DES_EDE_CBC_SHA = { 0x00,0x1F };
+ CipherSuite TLS_KRB5_WITH_RC4_128_SHA = { 0x00,0x20 };
+ CipherSuite TLS_KRB5_WITH_IDEA_CBC_SHA = { 0x00,0x21 };
+ CipherSuite TLS_KRB5_WITH_DES_CBC_MD5 = { 0x00,0x22 };
+ CipherSuite TLS_KRB5_WITH_3DES_EDE_CBC_MD5 = { 0x00,0x23 };
+ CipherSuite TLS_KRB5_WITH_RC4_128_MD5 = { 0x00,0x24 };
+ CipherSuite TLS_KRB5_WITH_IDEA_CBC_MD5 = { 0x00,0x25 };
+
+ CipherSuite TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA = { 0x00,0x26 };
+ CipherSuite TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA = { 0x00,0x27 };
+ CipherSuite TLS_KRB5_EXPORT_WITH_RC4_40_SHA = { 0x00,0x28 };
+ CipherSuite TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 = { 0x00,0x29 };
+ CipherSuite TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00,0x2A };
+ CipherSuite TLS_KRB5_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x2B };
+
+ To establish a Kerberos-based security context, one or more of the
+ above cipher suites must be specified in the client hello message.
+ If the TLS server supports the Kerberos authentication option, the
+ server hello message, sent to the client, will confirm the Kerberos
+ cipher suite selected by the server. The server's certificate, the
+ client
+
+ CertificateRequest, and the ServerKeyExchange shown in Figure 1 will
+ be omitted since authentication and the establishment of a master
+ secret will be done using the client's Kerberos credentials for the
+ TLS server. The client's certificate will be omitted for the same
+ reason. Note that these messages are specified as optional in the
+ TLS protocol; therefore, omitting them is permissible.
+
+ The Kerberos option must be added to the ClientKeyExchange message as
+ shown in Figure 2.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Medvinsky & Hur Standards Track [Page 3]
+
+RFC 2712 Addition of Kerberos Cipher Suites to TLS October 1999
+
+
+ struct
+ {
+ select (KeyExchangeAlgorithm)
+ {
+ case krb5: KerberosWrapper; /* new addition */
+ case rsa: EncryptedPreMasterSecret;
+ case diffie_hellman: ClientDiffieHellmanPublic;
+ } Exchange_keys;
+
+ } ClientKeyExchange;
+
+ struct
+ {
+ opaque Ticket;
+ opaque authenticator; /* optional */
+ opaque EncryptedPreMasterSecret; /* encrypted with the session key
+ which is sealed in the ticket */
+ } KerberosWrapper; /* new addition */
+
+ FIGURE 2: The Kerberos option in the ClientKeyExchange.
+
+ To use the Kerberos authentication option, the TLS client must obtain
+ a service ticket for the TLS server. In TLS, the ClientKeyExchange
+ message is used to pass a random 48-byte pre-master secret to the
+ server.
+
+ The client and server then use the pre-master secret to independently
+ derive the master secret, which in turn is used for generating
+ session keys and for MAC computations. Thus, if the Kerberos option
+ is selected, the pre-master secret structure is the same as that used
+ in the RSA case; it is encrypted under the Kerberos session key and
+ sent to the TLS server along with the Kerberos credentials (see
+ Figure 2). The ticket and authenticator are encoded per RFC 1510
+ (ASN.1 encoding). Once the ClientKeyExchange message is received,
+ the server's secret key is used to unwrap the credentials and extract
+ the pre-master secret.
+
+ Note that a Kerberos authenticator is not required, since the master
+ secret derived by the client and server is seeded with a random value
+ passed in the server hello message, thus foiling replay attacks.
+ However, the authenticator may still prove useful for passing
+ authorization information and is thus allotted an optional field (see
+ Figure 2).
+
+ Lastly, the client and server exchange the finished messages to
+ complete the handshake. At this point we have achieved the
+ following:
+
+
+
+
+Medvinsky & Hur Standards Track [Page 4]
+
+RFC 2712 Addition of Kerberos Cipher Suites to TLS October 1999
+
+
+ 1) A master secret, used to protect all subsequent communication, is
+ securely established.
+
+ 2) Mutual client-server authentication is achieved, since the TLS
+ server proves knowledge of the master secret in the finished
+ message.
+
+ Note that the Kerberos option fits in seamlessly, without adding any
+ new messages.
+
+4. Naming Conventions:
+
+ To obtain an appropriate service ticket, the TLS client must
+ determine the principal name of the TLS server. The Kerberos service
+ naming convention is used for this purpose, as follows:
+
+ host/MachineName@Realm
+ where:
+ - The literal, "host", follows the Kerberos convention when not
+ concerned about the protection domain on a particular machine.
+ - "MachineName" is the particular instance of the service.
+ - The Kerberos "Realm" is the domain name of the machine.
+
+5. Summary
+
+ The proposed Kerberos authentication option is added in exactly the
+ same manner as a new public key algorithm would be added to TLS.
+ Furthermore, it establishes the master secret in exactly the same
+ manner.
+
+6. Security Considerations
+
+ Kerberos ciphersuites are subject to the same security considerations
+ as the TLS protocol. In addition, just as a public key
+ implementation must take care to protect the private key (for example
+ the PIN for a smartcard), a Kerberos implementation must take care to
+ protect the long lived secret that is shared between the principal
+ and the KDC. In particular, a weak password may be subject to a
+ dictionary attack. In order to strengthen the initial authentication
+ to a KDC, an implementor may choose to utilize secondary
+ authentication via a token card, or one may utilize initial
+ authentication to the KDC based on public key cryptography (commonly
+ known as PKINIT - a product of the Common Authentication Technology
+ working group of the IETF).
+
+
+
+
+
+
+
+Medvinsky & Hur Standards Track [Page 5]
+
+RFC 2712 Addition of Kerberos Cipher Suites to TLS October 1999
+
+
+7. Acknowledgements
+
+ We would like to thank Clifford Neuman for his invaluable comments on
+ earlier versions of this document.
+
+8. References
+
+ [1] Dierks, T. and C. Allen, "The TLS Protocol, Version 1.0", RFC
+ 2246, January 1999.
+
+ [2] Kohl J. and C. Neuman, "The Kerberos Network Authentication
+ Service (V5)", RFC 1510, September 1993.
+
+9. Authors' Addresses
+
+ Ari Medvinsky
+ Excite
+ 555 Broadway
+ Redwood City, CA 94063
+
+ Phone: +1 650 569 2119
+ EMail: amedvins@excitecorp.com
+ http://www.excite.com
+
+
+ Matthew Hur
+ CyberSafe Corporation
+ 1605 NW Sammamish Road
+ Issaquah WA 98027-5378
+
+ Phone: +1 425 391 6000
+ EMail: matt.hur@cybersafe.com
+ http://www.cybersafe.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Medvinsky & Hur Standards Track [Page 6]
+
+RFC 2712 Addition of Kerberos Cipher Suites to TLS October 1999
+
+
+10. Full Copyright Statement
+
+ Copyright (C) The Internet Society (1999). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Medvinsky & Hur Standards Track [Page 7]
+
diff --git a/standards/rfc2817.txt b/standards/rfc2817.txt
new file mode 100644
index 000000000..d7b7e703b
--- /dev/null
+++ b/standards/rfc2817.txt
@@ -0,0 +1,731 @@
+
+
+
+
+
+
+Network Working Group R. Khare
+Request for Comments: 2817 4K Associates / UC Irvine
+Updates: 2616 S. Lawrence
+Category: Standards Track Agranat Systems, Inc.
+ May 2000
+
+
+ Upgrading to TLS Within HTTP/1.1
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+Abstract
+
+ This memo explains how to use the Upgrade mechanism in HTTP/1.1 to
+ initiate Transport Layer Security (TLS) over an existing TCP
+ connection. This allows unsecured and secured HTTP traffic to share
+ the same well known port (in this case, http: at 80 rather than
+ https: at 443). It also enables "virtual hosting", so a single HTTP +
+ TLS server can disambiguate traffic intended for several hostnames at
+ a single IP address.
+
+ Since HTTP/1.1 [1] defines Upgrade as a hop-by-hop mechanism, this
+ memo also documents the HTTP CONNECT method for establishing end-to-
+ end tunnels across HTTP proxies. Finally, this memo establishes new
+ IANA registries for public HTTP status codes, as well as public or
+ private Upgrade product tokens.
+
+ This memo does NOT affect the current definition of the 'https' URI
+ scheme, which already defines a separate namespace
+ (http://example.org/ and https://example.org/ are not equivalent).
+
+
+
+
+
+
+
+
+
+
+
+Khare & Lawrence Standards Track [Page 1]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+Table of Contents
+
+ 1. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . 2
+ 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
+ 2.1 Requirements Terminology . . . . . . . . . . . . . . . . . . . 4
+ 3. Client Requested Upgrade to HTTP over TLS . . . . . . . . . . 4
+ 3.1 Optional Upgrade . . . . . . . . . . . . . . . . . . . . . . . 4
+ 3.2 Mandatory Upgrade . . . . . . . . . . . . . . . . . . . . . . 4
+ 3.3 Server Acceptance of Upgrade Request . . . . . . . . . . . . . 4
+ 4. Server Requested Upgrade to HTTP over TLS . . . . . . . . . . 5
+ 4.1 Optional Advertisement . . . . . . . . . . . . . . . . . . . . 5
+ 4.2 Mandatory Advertisement . . . . . . . . . . . . . . . . . . . 5
+ 5. Upgrade across Proxies . . . . . . . . . . . . . . . . . . . . 6
+ 5.1 Implications of Hop By Hop Upgrade . . . . . . . . . . . . . . 6
+ 5.2 Requesting a Tunnel with CONNECT . . . . . . . . . . . . . . . 6
+ 5.3 Establishing a Tunnel with CONNECT . . . . . . . . . . . . . . 7
+ 6. Rationale for the use of a 4xx (client error) Status Code . . 7
+ 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 8
+ 7.1 HTTP Status Code Registry . . . . . . . . . . . . . . . . . . 8
+ 7.2 HTTP Upgrade Token Registry . . . . . . . . . . . . . . . . . 8
+ 8. Security Considerations . . . . . . . . . . . . . . . . . . . 9
+ 8.1 Implications for the https: URI Scheme . . . . . . . . . . . . 10
+ 8.2 Security Considerations for CONNECT . . . . . . . . . . . . . 10
+ References . . . . . . . . . . . . . . . . . . . . . . . . . . 10
+ Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 11
+ A. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 12
+ Full Copyright Statement . . . . . . . . . . . . . . . . . . . 13
+
+1. Motivation
+
+ The historical practice of deploying HTTP over SSL3 [3] has
+ distinguished the combination from HTTP alone by a unique URI scheme
+ and the TCP port number. The scheme 'http' meant the HTTP protocol
+ alone on port 80, while 'https' meant the HTTP protocol over SSL on
+ port 443. Parallel well-known port numbers have similarly been
+ requested -- and in some cases, granted -- to distinguish between
+ secured and unsecured use of other application protocols (e.g.
+ snews, ftps). This approach effectively halves the number of
+ available well known ports.
+
+ At the Washington DC IETF meeting in December 1997, the Applications
+ Area Directors and the IESG reaffirmed that the practice of issuing
+ parallel "secure" port numbers should be deprecated. The HTTP/1.1
+ Upgrade mechanism can apply Transport Layer Security [6] to an open
+ HTTP connection.
+
+
+
+
+
+
+Khare & Lawrence Standards Track [Page 2]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+ In the nearly two years since, there has been broad acceptance of the
+ concept behind this proposal, but little interest in implementing
+ alternatives to port 443 for generic Web browsing. In fact, nothing
+ in this memo affects the current interpretation of https: URIs.
+ However, new application protocols built atop HTTP, such as the
+ Internet Printing Protocol [7], call for just such a mechanism in
+ order to move ahead in the IETF standards process.
+
+ The Upgrade mechanism also solves the "virtual hosting" problem.
+ Rather than allocating multiple IP addresses to a single host, an
+ HTTP/1.1 server will use the Host: header to disambiguate the
+ intended web service. As HTTP/1.1 usage has grown more prevalent,
+ more ISPs are offering name-based virtual hosting, thus delaying IP
+ address space exhaustion.
+
+ TLS (and SSL) have been hobbled by the same limitation as earlier
+ versions of HTTP: the initial handshake does not specify the intended
+ hostname, relying exclusively on the IP address. Using a cleartext
+ HTTP/1.1 Upgrade: preamble to the TLS handshake -- choosing the
+ certificates based on the initial Host: header -- will allow ISPs to
+ provide secure name-based virtual hosting as well.
+
+2. Introduction
+
+ TLS, a.k.a., SSL (Secure Sockets Layer), establishes a private end-
+ to-end connection, optionally including strong mutual authentication,
+ using a variety of cryptosystems. Initially, a handshake phase uses
+ three subprotocols to set up a record layer, authenticate endpoints,
+ set parameters, as well as report errors. Then, there is an ongoing
+ layered record protocol that handles encryption, compression, and
+ reassembly for the remainder of the connection. The latter is
+ intended to be completely transparent. For example, there is no
+ dependency between TLS's record markers and or certificates and
+ HTTP/1.1's chunked encoding or authentication.
+
+ Either the client or server can use the HTTP/1.1 [1] Upgrade
+ mechanism (Section 14.42) to indicate that a TLS-secured connection
+ is desired or necessary. This memo defines the "TLS/1.0" Upgrade
+ token, and a new HTTP Status Code, "426 Upgrade Required".
+
+ Section 3 and Section 4 describe the operation of a directly
+ connected client and server. Intermediate proxies must establish an
+ end-to-end tunnel before applying those operations, as explained in
+ Section 5.
+
+
+
+
+
+
+
+Khare & Lawrence Standards Track [Page 3]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+2.1 Requirements Terminology
+
+ Keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT" and
+ "MAY" that appear in this document are to be interpreted as described
+ in RFC 2119 [11].
+
+3. Client Requested Upgrade to HTTP over TLS
+
+ When the client sends an HTTP/1.1 request with an Upgrade header
+ field containing the token "TLS/1.0", it is requesting the server to
+ complete the current HTTP/1.1 request after switching to TLS/1.0.
+
+3.1 Optional Upgrade
+
+ A client MAY offer to switch to secured operation during any clear
+ HTTP request when an unsecured response would be acceptable:
+
+ GET http://example.bank.com/acct_stat.html?749394889300 HTTP/1.1
+ Host: example.bank.com
+ Upgrade: TLS/1.0
+ Connection: Upgrade
+
+ In this case, the server MAY respond to the clear HTTP operation
+ normally, OR switch to secured operation (as detailed in the next
+ section).
+
+ Note that HTTP/1.1 [1] specifies "the upgrade keyword MUST be
+ supplied within a Connection header field (section 14.10) whenever
+ Upgrade is present in an HTTP/1.1 message".
+
+3.2 Mandatory Upgrade
+
+ If an unsecured response would be unacceptable, a client MUST send an
+ OPTIONS request first to complete the switch to TLS/1.0 (if
+ possible).
+
+ OPTIONS * HTTP/1.1
+ Host: example.bank.com
+ Upgrade: TLS/1.0
+ Connection: Upgrade
+
+3.3 Server Acceptance of Upgrade Request
+
+ As specified in HTTP/1.1 [1], if the server is prepared to initiate
+ the TLS handshake, it MUST send the intermediate "101 Switching
+ Protocol" and MUST include an Upgrade response header specifying the
+ tokens of the protocol stack it is switching to:
+
+
+
+
+Khare & Lawrence Standards Track [Page 4]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+ HTTP/1.1 101 Switching Protocols
+ Upgrade: TLS/1.0, HTTP/1.1
+ Connection: Upgrade
+
+ Note that the protocol tokens listed in the Upgrade header of a 101
+ Switching Protocols response specify an ordered 'bottom-up' stack.
+
+ As specified in HTTP/1.1 [1], Section 10.1.2: "The server will
+ switch protocols to those defined by the response's Upgrade header
+ field immediately after the empty line which terminates the 101
+ response".
+
+ Once the TLS handshake completes successfully, the server MUST
+ continue with the response to the original request. Any TLS handshake
+ failure MUST lead to disconnection, per the TLS error alert
+ specification.
+
+4. Server Requested Upgrade to HTTP over TLS
+
+ The Upgrade response header field advertises possible protocol
+ upgrades a server MAY accept. In conjunction with the "426 Upgrade
+ Required" status code, a server can advertise the exact protocol
+ upgrade(s) that a client MUST accept to complete the request.
+
+4.1 Optional Advertisement
+
+ As specified in HTTP/1.1 [1], the server MAY include an Upgrade
+ header in any response other than 101 or 426 to indicate a
+ willingness to switch to any (combination) of the protocols listed.
+
+4.2 Mandatory Advertisement
+
+ A server MAY indicate that a client request can not be completed
+ without TLS using the "426 Upgrade Required" status code, which MUST
+ include an an Upgrade header field specifying the token of the
+ required TLS version.
+
+ HTTP/1.1 426 Upgrade Required
+ Upgrade: TLS/1.0, HTTP/1.1
+ Connection: Upgrade
+
+ The server SHOULD include a message body in the 426 response which
+ indicates in human readable form the reason for the error and
+ describes any alternative courses which may be available to the user.
+
+ Note that even if a client is willing to use TLS, it must use the
+ operations in Section 3 to proceed; the TLS handshake cannot begin
+ immediately after the 426 response.
+
+
+
+Khare & Lawrence Standards Track [Page 5]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+5. Upgrade across Proxies
+
+ As a hop-by-hop header, Upgrade is negotiated between each pair of
+ HTTP counterparties. If a User Agent sends a request with an Upgrade
+ header to a proxy, it is requesting a change to the protocol between
+ itself and the proxy, not an end-to-end change.
+
+ Since TLS, in particular, requires end-to-end connectivity to provide
+ authentication and prevent man-in-the-middle attacks, this memo
+ specifies the CONNECT method to establish a tunnel across proxies.
+
+ Once a tunnel is established, any of the operations in Section 3 can
+ be used to establish a TLS connection.
+
+5.1 Implications of Hop By Hop Upgrade
+
+ If an origin server receives an Upgrade header from a proxy and
+ responds with a 101 Switching Protocols response, it is changing the
+ protocol only on the connection between the proxy and itself.
+ Similarly, a proxy might return a 101 response to its client to
+ change the protocol on that connection independently of the protocols
+ it is using to communicate toward the origin server.
+
+ These scenarios also complicate diagnosis of a 426 response. Since
+ Upgrade is a hop-by-hop header, a proxy that does not recognize 426
+ might remove the accompanying Upgrade header and prevent the client
+ from determining the required protocol switch. If a client receives
+ a 426 status without an accompanying Upgrade header, it will need to
+ request an end to end tunnel connection as described in Section 5.2
+ and repeat the request in order to obtain the required upgrade
+ information.
+
+ This hop-by-hop definition of Upgrade was a deliberate choice. It
+ allows for incremental deployment on either side of proxies, and for
+ optimized protocols between cascaded proxies without the knowledge of
+ the parties that are not a part of the change.
+
+5.2 Requesting a Tunnel with CONNECT
+
+ A CONNECT method requests that a proxy establish a tunnel connection
+ on its behalf. The Request-URI portion of the Request-Line is always
+ an 'authority' as defined by URI Generic Syntax [2], which is to say
+ the host name and port number destination of the requested connection
+ separated by a colon:
+
+ CONNECT server.example.com:80 HTTP/1.1
+ Host: server.example.com:80
+
+
+
+
+Khare & Lawrence Standards Track [Page 6]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+ Other HTTP mechanisms can be used normally with the CONNECT method --
+ except end-to-end protocol Upgrade requests, of course, since the
+ tunnel must be established first.
+
+ For example, proxy authentication might be used to establish the
+ authority to create a tunnel:
+
+ CONNECT server.example.com:80 HTTP/1.1
+ Host: server.example.com:80
+ Proxy-Authorization: basic aGVsbG86d29ybGQ=
+
+ Like any other pipelined HTTP/1.1 request, data to be tunneled may be
+ sent immediately after the blank line. The usual caveats also apply:
+ data may be discarded if the eventual response is negative, and the
+ connection may be reset with no response if more than one TCP segment
+ is outstanding.
+
+5.3 Establishing a Tunnel with CONNECT
+
+ Any successful (2xx) response to a CONNECT request indicates that the
+ proxy has established a connection to the requested host and port,
+ and has switched to tunneling the current connection to that server
+ connection.
+
+ It may be the case that the proxy itself can only reach the requested
+ origin server through another proxy. In this case, the first proxy
+ SHOULD make a CONNECT request of that next proxy, requesting a tunnel
+ to the authority. A proxy MUST NOT respond with any 2xx status code
+ unless it has either a direct or tunnel connection established to the
+ authority.
+
+ An origin server which receives a CONNECT request for itself MAY
+ respond with a 2xx status code to indicate that a connection is
+ established.
+
+ If at any point either one of the peers gets disconnected, any
+ outstanding data that came from that peer will be passed to the other
+ one, and after that also the other connection will be terminated by
+ the proxy. If there is outstanding data to that peer undelivered,
+ that data will be discarded.
+
+6. Rationale for the use of a 4xx (client error) Status Code
+
+ Reliable, interoperable negotiation of Upgrade features requires an
+ unambiguous failure signal. The 426 Upgrade Required status code
+ allows a server to definitively state the precise protocol extensions
+ a given resource must be served with.
+
+
+
+
+Khare & Lawrence Standards Track [Page 7]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+ It might at first appear that the response should have been some form
+ of redirection (a 3xx code), by analogy to an old-style redirection
+ to an https: URI. User agents that do not understand Upgrade:
+ preclude this.
+
+ Suppose that a 3xx code had been assigned for "Upgrade Required"; a
+ user agent that did not recognize it would treat it as 300. It would
+ then properly look for a "Location" header in the response and
+ attempt to repeat the request at the URL in that header field. Since
+ it did not know to Upgrade to incorporate the TLS layer, it would at
+ best fail again at the new URL.
+
+7. IANA Considerations
+
+ IANA shall create registries for two name spaces, as described in BCP
+ 26 [10]:
+
+ o HTTP Status Codes
+ o HTTP Upgrade Tokens
+
+7.1 HTTP Status Code Registry
+
+ The HTTP Status Code Registry defines the name space for the Status-
+ Code token in the Status line of an HTTP response. The initial
+ values for this name space are those specified by:
+
+ 1. Draft Standard for HTTP/1.1 [1]
+ 2. Web Distributed Authoring and Versioning [4] [defines 420-424]
+ 3. WebDAV Advanced Collections [5] (Work in Progress) [defines 425]
+ 4. Section 6 [defines 426]
+
+ Values to be added to this name space SHOULD be subject to review in
+ the form of a standards track document within the IETF Applications
+ Area. Any such document SHOULD be traceable through statuses of
+ either 'Obsoletes' or 'Updates' to the Draft Standard for
+ HTTP/1.1 [1].
+
+7.2 HTTP Upgrade Token Registry
+
+ The HTTP Upgrade Token Registry defines the name space for product
+ tokens used to identify protocols in the Upgrade HTTP header field.
+ Each registered token should be associated with one or a set of
+ specifications, and with contact information.
+
+ The Draft Standard for HTTP/1.1 [1] specifies that these tokens obey
+ the production for 'product':
+
+
+
+
+
+Khare & Lawrence Standards Track [Page 8]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+ product = token ["/" product-version]
+ product-version = token
+
+ Registrations should be allowed on a First Come First Served basis as
+ described in BCP 26 [10]. These specifications need not be IETF
+ documents or be subject to IESG review, but should obey the following
+ rules:
+
+ 1. A token, once registered, stays registered forever.
+ 2. The registration MUST name a responsible party for the
+ registration.
+ 3. The registration MUST name a point of contact.
+ 4. The registration MAY name the documentation required for the
+ token.
+ 5. The responsible party MAY change the registration at any time.
+ The IANA will keep a record of all such changes, and make them
+ available upon request.
+ 6. The responsible party for the first registration of a "product"
+ token MUST approve later registrations of a "version" token
+ together with that "product" token before they can be registered.
+ 7. If absolutely required, the IESG MAY reassign the responsibility
+ for a token. This will normally only be used in the case when a
+ responsible party cannot be contacted.
+
+ This specification defines the protocol token "TLS/1.0" as the
+ identifier for the protocol specified by The TLS Protocol [6].
+
+ It is NOT required that specifications for upgrade tokens be made
+ publicly available, but the contact information for the registration
+ SHOULD be.
+
+8. Security Considerations
+
+ The potential for a man-in-the-middle attack (deleting the Upgrade
+ header) remains the same as current, mixed http/https practice:
+
+ o Removing the Upgrade header is similar to rewriting web pages to
+ change https:// links to http:// links.
+ o The risk is only present if the server is willing to vend such
+ information over both a secure and an insecure channel in the
+ first place.
+ o If the client knows for a fact that a server is TLS-compliant, it
+ can insist on it by only sending an Upgrade request with a no-op
+ method like OPTIONS.
+ o Finally, as the https: specification warns, "users should
+ carefully examine the certificate presented by the server to
+ determine if it meets their expectations".
+
+
+
+
+Khare & Lawrence Standards Track [Page 9]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+ Furthermore, for clients that do not explicitly try to invoke TLS,
+ servers can use the Upgrade header in any response other than 101 or
+ 426 to advertise TLS compliance. Since TLS compliance should be
+ considered a feature of the server and not the resource at hand, it
+ should be sufficient to send it once, and let clients cache that
+ fact.
+
+8.1 Implications for the https: URI Scheme
+
+ While nothing in this memo affects the definition of the 'https' URI
+ scheme, widespread adoption of this mechanism for HyperText content
+ could use 'http' to identify both secure and non-secure resources.
+
+ The choice of what security characteristics are required on the
+ connection is left to the client and server. This allows either
+ party to use any information available in making this determination.
+ For example, user agents may rely on user preference settings or
+ information about the security of the network such as 'TLS required
+ on all POST operations not on my local net', or servers may apply
+ resource access rules such as 'the FORM on this page must be served
+ and submitted using TLS'.
+
+8.2 Security Considerations for CONNECT
+
+ A generic TCP tunnel is fraught with security risks. First, such
+ authorization should be limited to a small number of known ports.
+ The Upgrade: mechanism defined here only requires onward tunneling at
+ port 80. Second, since tunneled data is opaque to the proxy, there
+ are additional risks to tunneling to other well-known or reserved
+ ports. A putative HTTP client CONNECTing to port 25 could relay spam
+ via SMTP, for example.
+
+References
+
+ [1] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L.,
+ Leach, P. and T. Berners-Lee, "Hypertext Transfer Protocol --
+ HTTP/1.1", RFC 2616, June 1999.
+
+ [2] Berners-Lee, T., Fielding, R. and L. Masinter, "URI Generic
+ Syntax", RFC 2396, August 1998.
+
+ [3] Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000.
+
+ [4] Goland, Y., Whitehead, E., Faizi, A., Carter, S. and D. Jensen,
+ "Web Distributed Authoring and Versioning", RFC 2518, February
+ 1999.
+
+
+
+
+
+Khare & Lawrence Standards Track [Page 10]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+ [5] Slein, J., Whitehead, E.J., et al., "WebDAV Advanced Collections
+ Protocol", Work In Progress.
+
+ [6] Dierks, T. and C. Allen, "The TLS Protocol", RFC 2246, January
+ 1999.
+
+ [7] Herriot, R., Butler, S., Moore, P. and R. Turner, "Internet
+ Printing Protocol/1.0: Encoding and Transport", RFC 2565, April
+ 1999.
+
+ [8] Luotonen, A., "Tunneling TCP based protocols through Web proxy
+ servers", Work In Progress. (Also available in: Luotonen, Ari.
+ Web Proxy Servers, Prentice-Hall, 1997 ISBN:0136806120.)
+
+ [9] Rose, M., "Writing I-Ds and RFCs using XML", RFC 2629, June
+ 1999.
+
+ [10] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA
+ Considerations Section in RFCs", BCP 26, RFC 2434, October 1998.
+
+ [11] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+Authors' Addresses
+
+ Rohit Khare
+ 4K Associates / UC Irvine
+ 3207 Palo Verde
+ Irvine, CA 92612
+ US
+
+ Phone: +1 626 806 7574
+ EMail: rohit@4K-associates.com
+ URI: http://www.4K-associates.com/
+
+
+ Scott Lawrence
+ Agranat Systems, Inc.
+ 5 Clocktower Place
+ Suite 400
+ Maynard, MA 01754
+ US
+
+ Phone: +1 978 461 0888
+ EMail: lawrence@agranat.com
+ URI: http://www.agranat.com/
+
+
+
+
+
+Khare & Lawrence Standards Track [Page 11]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+Appendix A. Acknowledgments
+
+ The CONNECT method was originally described in a Work in Progress
+ titled, "Tunneling TCP based protocols through Web proxy servers",
+ [8] by Ari Luotonen of Netscape Communications Corporation. It was
+ widely implemented by HTTP proxies, but was never made a part of any
+ IETF Standards Track document. The method name CONNECT was reserved,
+ but not defined in [1].
+
+ The definition provided here is derived directly from that earlier
+ memo, with some editorial changes and conformance to the stylistic
+ conventions since established in other HTTP specifications.
+
+ Additional Thanks to:
+
+ o Paul Hoffman for his work on the STARTTLS command extension for
+ ESMTP.
+ o Roy Fielding for assistance with the rationale behind Upgrade:
+ and its interaction with OPTIONS.
+ o Eric Rescorla for his work on standardizing the existing https:
+ practice to compare with.
+ o Marshall Rose, for the xml2rfc document type description and tools
+ [9].
+ o Jim Whitehead, for sorting out the current range of available HTTP
+ status codes.
+ o Henrik Frystyk Nielsen, whose work on the Mandatory extension
+ mechanism pointed out a hop-by-hop Upgrade still requires
+ tunneling.
+ o Harald Alvestrand for improvements to the token registration
+ rules.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Khare & Lawrence Standards Track [Page 12]
+
+RFC 2817 HTTP Upgrade to TLS May 2000
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Khare & Lawrence Standards Track [Page 13]
+
diff --git a/standards/rfc2818.txt b/standards/rfc2818.txt
new file mode 100644
index 000000000..219a1c427
--- /dev/null
+++ b/standards/rfc2818.txt
@@ -0,0 +1,395 @@
+
+
+
+
+
+
+Network Working Group E. Rescorla
+Request for Comments: 2818 RTFM, Inc.
+Category: Informational May 2000
+
+
+ HTTP Over TLS
+
+Status of this Memo
+
+ This memo provides information for the Internet community. It does
+ not specify an Internet standard of any kind. Distribution of this
+ memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+Abstract
+
+ This memo describes how to use TLS to secure HTTP connections over
+ the Internet. Current practice is to layer HTTP over SSL (the
+ predecessor to TLS), distinguishing secured traffic from insecure
+ traffic by the use of a different server port. This document
+ documents that practice using TLS. A companion document describes a
+ method for using HTTP/TLS over the same port as normal HTTP
+ [RFC2817].
+
+Table of Contents
+
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . 2
+ 1.1. Requirements Terminology . . . . . . . . . . . . . . . 2
+ 2. HTTP Over TLS . . . . . . . . . . . . . . . . . . . . . . 2
+ 2.1. Connection Initiation . . . . . . . . . . . . . . . . . 2
+ 2.2. Connection Closure . . . . . . . . . . . . . . . . . . 2
+ 2.2.1. Client Behavior . . . . . . . . . . . . . . . . . . . 3
+ 2.2.2. Server Behavior . . . . . . . . . . . . . . . . . . . 3
+ 2.3. Port Number . . . . . . . . . . . . . . . . . . . . . . 4
+ 2.4. URI Format . . . . . . . . . . . . . . . . . . . . . . 4
+ 3. Endpoint Identification . . . . . . . . . . . . . . . . . 4
+ 3.1. Server Identity . . . . . . . . . . . . . . . . . . . . 4
+ 3.2. Client Identity . . . . . . . . . . . . . . . . . . . . 5
+ References . . . . . . . . . . . . . . . . . . . . . . . . . 6
+ Security Considerations . . . . . . . . . . . . . . . . . . 6
+ Author's Address . . . . . . . . . . . . . . . . . . . . . . 6
+ Full Copyright Statement . . . . . . . . . . . . . . . . . . 7
+
+
+
+
+
+
+Rescorla Informational [Page 1]
+
+RFC 2818 HTTP Over TLS May 2000
+
+
+1. Introduction
+
+ HTTP [RFC2616] was originally used in the clear on the Internet.
+ However, increased use of HTTP for sensitive applications has
+ required security measures. SSL, and its successor TLS [RFC2246] were
+ designed to provide channel-oriented security. This document
+ describes how to use HTTP over TLS.
+
+1.1. Requirements Terminology
+
+ Keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT" and
+ "MAY" that appear in this document are to be interpreted as described
+ in [RFC2119].
+
+2. HTTP Over TLS
+
+ Conceptually, HTTP/TLS is very simple. Simply use HTTP over TLS
+ precisely as you would use HTTP over TCP.
+
+2.1. Connection Initiation
+
+ The agent acting as the HTTP client should also act as the TLS
+ client. It should initiate a connection to the server on the
+ appropriate port and then send the TLS ClientHello to begin the TLS
+ handshake. When the TLS handshake has finished. The client may then
+ initiate the first HTTP request. All HTTP data MUST be sent as TLS
+ "application data". Normal HTTP behavior, including retained
+ connections should be followed.
+
+2.2. Connection Closure
+
+ TLS provides a facility for secure connection closure. When a valid
+ closure alert is received, an implementation can be assured that no
+ further data will be received on that connection. TLS
+ implementations MUST initiate an exchange of closure alerts before
+ closing a connection. A TLS implementation MAY, after sending a
+ closure alert, close the connection without waiting for the peer to
+ send its closure alert, generating an "incomplete close". Note that
+ an implementation which does this MAY choose to reuse the session.
+ This SHOULD only be done when the application knows (typically
+ through detecting HTTP message boundaries) that it has received all
+ the message data that it cares about.
+
+ As specified in [RFC2246], any implementation which receives a
+ connection close without first receiving a valid closure alert (a
+ "premature close") MUST NOT reuse that session. Note that a
+ premature close does not call into question the security of the data
+ already received, but simply indicates that subsequent data might
+
+
+
+Rescorla Informational [Page 2]
+
+RFC 2818 HTTP Over TLS May 2000
+
+
+ have been truncated. Because TLS is oblivious to HTTP
+ request/response boundaries, it is necessary to examine the HTTP data
+ itself (specifically the Content-Length header) to determine whether
+ the truncation occurred inside a message or between messages.
+
+2.2.1. Client Behavior
+
+ Because HTTP uses connection closure to signal end of server data,
+ client implementations MUST treat any premature closes as errors and
+ the data received as potentially truncated. While in some cases the
+ HTTP protocol allows the client to find out whether truncation took
+ place so that, if it received the complete reply, it may tolerate
+ such errors following the principle to "[be] strict when sending and
+ tolerant when receiving" [RFC1958], often truncation does not show in
+ the HTTP protocol data; two cases in particular deserve special note:
+
+ A HTTP response without a Content-Length header. Since data length
+ in this situation is signalled by connection close a premature
+ close generated by the server cannot be distinguished from a
+ spurious close generated by an attacker.
+
+ A HTTP response with a valid Content-Length header closed before
+ all data has been read. Because TLS does not provide document
+ oriented protection, it is impossible to determine whether the
+ server has miscomputed the Content-Length or an attacker has
+ truncated the connection.
+
+ There is one exception to the above rule. When encountering a
+ premature close, a client SHOULD treat as completed all requests for
+ which it has received as much data as specified in the Content-Length
+ header.
+
+ A client detecting an incomplete close SHOULD recover gracefully. It
+ MAY resume a TLS session closed in this fashion.
+
+ Clients MUST send a closure alert before closing the connection.
+ Clients which are unprepared to receive any more data MAY choose not
+ to wait for the server's closure alert and simply close the
+ connection, thus generating an incomplete close on the server side.
+
+2.2.2. Server Behavior
+
+ RFC 2616 permits an HTTP client to close the connection at any time,
+ and requires servers to recover gracefully. In particular, servers
+ SHOULD be prepared to receive an incomplete close from the client,
+ since the client can often determine when the end of server data is.
+ Servers SHOULD be willing to resume TLS sessions closed in this
+ fashion.
+
+
+
+Rescorla Informational [Page 3]
+
+RFC 2818 HTTP Over TLS May 2000
+
+
+ Implementation note: In HTTP implementations which do not use
+ persistent connections, the server ordinarily expects to be able to
+ signal end of data by closing the connection. When Content-Length is
+ used, however, the client may have already sent the closure alert and
+ dropped the connection.
+
+ Servers MUST attempt to initiate an exchange of closure alerts with
+ the client before closing the connection. Servers MAY close the
+ connection after sending the closure alert, thus generating an
+ incomplete close on the client side.
+
+2.3. Port Number
+
+ The first data that an HTTP server expects to receive from the client
+ is the Request-Line production. The first data that a TLS server (and
+ hence an HTTP/TLS server) expects to receive is the ClientHello.
+ Consequently, common practice has been to run HTTP/TLS over a
+ separate port in order to distinguish which protocol is being used.
+ When HTTP/TLS is being run over a TCP/IP connection, the default port
+ is 443. This does not preclude HTTP/TLS from being run over another
+ transport. TLS only presumes a reliable connection-oriented data
+ stream.
+
+2.4. URI Format
+
+ HTTP/TLS is differentiated from HTTP URIs by using the 'https'
+ protocol identifier in place of the 'http' protocol identifier. An
+ example URI specifying HTTP/TLS is:
+
+ https://www.example.com/~smith/home.html
+
+3. Endpoint Identification
+
+3.1. Server Identity
+
+ In general, HTTP/TLS requests are generated by dereferencing a URI.
+ As a consequence, the hostname for the server is known to the client.
+ If the hostname is available, the client MUST check it against the
+ server's identity as presented in the server's Certificate message,
+ in order to prevent man-in-the-middle attacks.
+
+ If the client has external information as to the expected identity of
+ the server, the hostname check MAY be omitted. (For instance, a
+ client may be connecting to a machine whose address and hostname are
+ dynamic but the client knows the certificate that the server will
+ present.) In such cases, it is important to narrow the scope of
+ acceptable certificates as much as possible in order to prevent man
+
+
+
+
+Rescorla Informational [Page 4]
+
+RFC 2818 HTTP Over TLS May 2000
+
+
+ in the middle attacks. In special cases, it may be appropriate for
+ the client to simply ignore the server's identity, but it must be
+ understood that this leaves the connection open to active attack.
+
+ If a subjectAltName extension of type dNSName is present, that MUST
+ be used as the identity. Otherwise, the (most specific) Common Name
+ field in the Subject field of the certificate MUST be used. Although
+ the use of the Common Name is existing practice, it is deprecated and
+ Certification Authorities are encouraged to use the dNSName instead.
+
+ Matching is performed using the matching rules specified by
+ [RFC2459]. If more than one identity of a given type is present in
+ the certificate (e.g., more than one dNSName name, a match in any one
+ of the set is considered acceptable.) Names may contain the wildcard
+ character * which is considered to match any single domain name
+ component or component fragment. E.g., *.a.com matches foo.a.com but
+ not bar.foo.a.com. f*.com matches foo.com but not bar.com.
+
+ In some cases, the URI is specified as an IP address rather than a
+ hostname. In this case, the iPAddress subjectAltName must be present
+ in the certificate and must exactly match the IP in the URI.
+
+ If the hostname does not match the identity in the certificate, user
+ oriented clients MUST either notify the user (clients MAY give the
+ user the opportunity to continue with the connection in any case) or
+ terminate the connection with a bad certificate error. Automated
+ clients MUST log the error to an appropriate audit log (if available)
+ and SHOULD terminate the connection (with a bad certificate error).
+ Automated clients MAY provide a configuration setting that disables
+ this check, but MUST provide a setting which enables it.
+
+ Note that in many cases the URI itself comes from an untrusted
+ source. The above-described check provides no protection against
+ attacks where this source is compromised. For example, if the URI was
+ obtained by clicking on an HTML page which was itself obtained
+ without using HTTP/TLS, a man in the middle could have replaced the
+ URI. In order to prevent this form of attack, users should carefully
+ examine the certificate presented by the server to determine if it
+ meets their expectations.
+
+3.2. Client Identity
+
+ Typically, the server has no external knowledge of what the client's
+ identity ought to be and so checks (other than that the client has a
+ certificate chain rooted in an appropriate CA) are not possible. If a
+ server has such knowledge (typically from some source external to
+ HTTP or TLS) it SHOULD check the identity as described above.
+
+
+
+
+Rescorla Informational [Page 5]
+
+RFC 2818 HTTP Over TLS May 2000
+
+
+References
+
+ [RFC2459] Housley, R., Ford, W., Polk, W. and D. Solo, "Internet
+ Public Key Infrastructure: Part I: X.509 Certificate and
+ CRL Profile", RFC 2459, January 1999.
+
+ [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter,
+ L., Leach, P. and T. Berners-Lee, "Hypertext Transfer
+ Protocol, HTTP/1.1", RFC 2616, June 1999.
+
+ [RFC2119] Bradner, S., "Key Words for use in RFCs to indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2246] Dierks, T. and C. Allen, "The TLS Protocol", RFC 2246,
+ January 1999.
+
+ [RFC2817] Khare, R. and S. Lawrence, "Upgrading to TLS Within
+ HTTP/1.1", RFC 2817, May 2000.
+
+Security Considerations
+
+ This entire document is about security.
+
+Author's Address
+
+ Eric Rescorla
+ RTFM, Inc.
+ 30 Newell Road, #16
+ East Palo Alto, CA 94303
+
+ Phone: (650) 328-8631
+ EMail: ekr@rtfm.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rescorla Informational [Page 6]
+
+RFC 2818 HTTP Over TLS May 2000
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Rescorla Informational [Page 7]
+
diff --git a/standards/rfc2821.txt b/standards/rfc2821.txt
new file mode 100644
index 000000000..0eac91188
--- /dev/null
+++ b/standards/rfc2821.txt
@@ -0,0 +1,4427 @@
+
+
+
+
+
+
+Network Working Group J. Klensin, Editor
+Request for Comments: 2821 AT&T Laboratories
+Obsoletes: 821, 974, 1869 April 2001
+Updates: 1123
+Category: Standards Track
+
+
+ Simple Mail Transfer Protocol
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+Abstract
+
+ This document is a self-contained specification of the basic protocol
+ for the Internet electronic mail transport. It consolidates, updates
+ and clarifies, but doesn't add new or change existing functionality
+ of the following:
+
+ - the original SMTP (Simple Mail Transfer Protocol) specification of
+ RFC 821 [30],
+
+ - domain name system requirements and implications for mail
+ transport from RFC 1035 [22] and RFC 974 [27],
+
+ - the clarifications and applicability statements in RFC 1123 [2],
+ and
+
+ - material drawn from the SMTP Extension mechanisms [19].
+
+ It obsoletes RFC 821, RFC 974, and updates RFC 1123 (replaces the
+ mail transport materials of RFC 1123). However, RFC 821 specifies
+ some features that were not in significant use in the Internet by the
+ mid-1990s and (in appendices) some additional transport models.
+ Those sections are omitted here in the interest of clarity and
+ brevity; readers needing them should refer to RFC 821.
+
+
+
+
+
+
+Klensin Standards Track [Page 1]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ It also includes some additional material from RFC 1123 that required
+ amplification. This material has been identified in multiple ways,
+ mostly by tracking flaming on various lists and newsgroups and
+ problems of unusual readings or interpretations that have appeared as
+ the SMTP extensions have been deployed. Where this specification
+ moves beyond consolidation and actually differs from earlier
+ documents, it supersedes them technically as well as textually.
+
+ Although SMTP was designed as a mail transport and delivery protocol,
+ this specification also contains information that is important to its
+ use as a 'mail submission' protocol, as recommended for POP [3, 26]
+ and IMAP [6]. Additional submission issues are discussed in RFC 2476
+ [15].
+
+ Section 2.3 provides definitions of terms specific to this document.
+ Except when the historical terminology is necessary for clarity, this
+ document uses the current 'client' and 'server' terminology to
+ identify the sending and receiving SMTP processes, respectively.
+
+ A companion document [32] discusses message headers, message bodies
+ and formats and structures for them, and their relationship.
+
+Table of Contents
+
+ 1. Introduction .................................................. 4
+ 2. The SMTP Model ................................................ 5
+ 2.1 Basic Structure .............................................. 5
+ 2.2 The Extension Model .......................................... 7
+ 2.2.1 Background ................................................. 7
+ 2.2.2 Definition and Registration of Extensions .................. 8
+ 2.3 Terminology .................................................. 9
+ 2.3.1 Mail Objects ............................................... 10
+ 2.3.2 Senders and Receivers ...................................... 10
+ 2.3.3 Mail Agents and Message Stores ............................. 10
+ 2.3.4 Host ....................................................... 11
+ 2.3.5 Domain ..................................................... 11
+ 2.3.6 Buffer and State Table ..................................... 11
+ 2.3.7 Lines ...................................................... 12
+ 2.3.8 Originator, Delivery, Relay, and Gateway Systems ........... 12
+ 2.3.9 Message Content and Mail Data .............................. 13
+ 2.3.10 Mailbox and Address ....................................... 13
+ 2.3.11 Reply ..................................................... 13
+ 2.4 General Syntax Principles and Transaction Model .............. 13
+ 3. The SMTP Procedures: An Overview .............................. 15
+ 3.1 Session Initiation ........................................... 15
+ 3.2 Client Initiation ............................................ 16
+ 3.3 Mail Transactions ............................................ 16
+ 3.4 Forwarding for Address Correction or Updating ................ 19
+
+
+
+Klensin Standards Track [Page 2]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ 3.5 Commands for Debugging Addresses ............................. 20
+ 3.5.1 Overview ................................................... 20
+ 3.5.2 VRFY Normal Response ....................................... 22
+ 3.5.3 Meaning of VRFY or EXPN Success Response ................... 22
+ 3.5.4 Semantics and Applications of EXPN ......................... 23
+ 3.6 Domains ...................................................... 23
+ 3.7 Relaying ..................................................... 24
+ 3.8 Mail Gatewaying .............................................. 25
+ 3.8.1 Header Fields in Gatewaying ................................ 26
+ 3.8.2 Received Lines in Gatewaying ............................... 26
+ 3.8.3 Addresses in Gatewaying .................................... 26
+ 3.8.4 Other Header Fields in Gatewaying .......................... 27
+ 3.8.5 Envelopes in Gatewaying .................................... 27
+ 3.9 Terminating Sessions and Connections ......................... 27
+ 3.10 Mailing Lists and Aliases ................................... 28
+ 3.10.1 Alias ..................................................... 28
+ 3.10.2 List ...................................................... 28
+ 4. The SMTP Specifications ....................................... 29
+ 4.1 SMTP Commands ................................................ 29
+ 4.1.1 Command Semantics and Syntax ............................... 29
+ 4.1.1.1 Extended HELLO (EHLO) or HELLO (HELO) ................... 29
+ 4.1.1.2 MAIL (MAIL) .............................................. 31
+ 4.1.1.3 RECIPIENT (RCPT) ......................................... 31
+ 4.1.1.4 DATA (DATA) .............................................. 33
+ 4.1.1.5 RESET (RSET) ............................................. 34
+ 4.1.1.6 VERIFY (VRFY) ............................................ 35
+ 4.1.1.7 EXPAND (EXPN) ............................................ 35
+ 4.1.1.8 HELP (HELP) .............................................. 35
+ 4.1.1.9 NOOP (NOOP) .............................................. 35
+ 4.1.1.10 QUIT (QUIT) ............................................. 36
+ 4.1.2 Command Argument Syntax .................................... 36
+ 4.1.3 Address Literals ........................................... 38
+ 4.1.4 Order of Commands .......................................... 39
+ 4.1.5 Private-use Commands ....................................... 40
+ 4.2 SMTP Replies ................................................ 40
+ 4.2.1 Reply Code Severities and Theory ........................... 42
+ 4.2.2 Reply Codes by Function Groups ............................. 44
+ 4.2.3 Reply Codes in Numeric Order .............................. 45
+ 4.2.4 Reply Code 502 ............................................. 46
+ 4.2.5 Reply Codes After DATA and the Subsequent <CRLF>.<CRLF> .... 46
+ 4.3 Sequencing of Commands and Replies ........................... 47
+ 4.3.1 Sequencing Overview ........................................ 47
+ 4.3.2 Command-Reply Sequences .................................... 48
+ 4.4 Trace Information ............................................ 49
+ 4.5 Additional Implementation Issues ............................. 53
+ 4.5.1 Minimum Implementation ..................................... 53
+ 4.5.2 Transparency ............................................... 53
+ 4.5.3 Sizes and Timeouts ......................................... 54
+
+
+
+Klensin Standards Track [Page 3]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ 4.5.3.1 Size limits and minimums ................................. 54
+ 4.5.3.2 Timeouts ................................................. 56
+ 4.5.4 Retry Strategies ........................................... 57
+ 4.5.4.1 Sending Strategy ......................................... 58
+ 4.5.4.2 Receiving Strategy ....................................... 59
+ 4.5.5 Messages with a null reverse-path .......................... 59
+ 5. Address Resolution and Mail Handling .......................... 60
+ 6. Problem Detection and Handling ................................ 62
+ 6.1 Reliable Delivery and Replies by Email ....................... 62
+ 6.2 Loop Detection ............................................... 63
+ 6.3 Compensating for Irregularities .............................. 63
+ 7. Security Considerations ....................................... 64
+ 7.1 Mail Security and Spoofing ................................... 64
+ 7.2 "Blind" Copies ............................................... 65
+ 7.3 VRFY, EXPN, and Security ..................................... 65
+ 7.4 Information Disclosure in Announcements ...................... 66
+ 7.5 Information Disclosure in Trace Fields ....................... 66
+ 7.6 Information Disclosure in Message Forwarding ................. 67
+ 7.7 Scope of Operation of SMTP Servers ........................... 67
+ 8. IANA Considerations ........................................... 67
+ 9. References .................................................... 68
+ 10. Editor's Address ............................................. 70
+ 11. Acknowledgments .............................................. 70
+ Appendices ....................................................... 71
+ A. TCP Transport Service ......................................... 71
+ B. Generating SMTP Commands from RFC 822 Headers ................. 71
+ C. Source Routes ................................................. 72
+ D. Scenarios ..................................................... 73
+ E. Other Gateway Issues .......................................... 76
+ F. Deprecated Features of RFC 821 ................................ 76
+ Full Copyright Statement ......................................... 79
+
+1. Introduction
+
+ The objective of the Simple Mail Transfer Protocol (SMTP) is to
+ transfer mail reliably and efficiently.
+
+ SMTP is independent of the particular transmission subsystem and
+ requires only a reliable ordered data stream channel. While this
+ document specifically discusses transport over TCP, other transports
+ are possible. Appendices to RFC 821 describe some of them.
+
+ An important feature of SMTP is its capability to transport mail
+ across networks, usually referred to as "SMTP mail relaying" (see
+ section 3.8). A network consists of the mutually-TCP-accessible
+ hosts on the public Internet, the mutually-TCP-accessible hosts on a
+ firewall-isolated TCP/IP Intranet, or hosts in some other LAN or WAN
+ environment utilizing a non-TCP transport-level protocol. Using
+
+
+
+Klensin Standards Track [Page 4]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ SMTP, a process can transfer mail to another process on the same
+ network or to some other network via a relay or gateway process
+ accessible to both networks.
+
+ In this way, a mail message may pass through a number of intermediate
+ relay or gateway hosts on its path from sender to ultimate recipient.
+ The Mail eXchanger mechanisms of the domain name system [22, 27] (and
+ section 5 of this document) are used to identify the appropriate
+ next-hop destination for a message being transported.
+
+2. The SMTP Model
+
+2.1 Basic Structure
+
+ The SMTP design can be pictured as:
+
+ +----------+ +----------+
+ +------+ | | | |
+ | User |<-->| | SMTP | |
+ +------+ | Client- |Commands/Replies| Server- |
+ +------+ | SMTP |<-------------->| SMTP | +------+
+ | File |<-->| | and Mail | |<-->| File |
+ |System| | | | | |System|
+ +------+ +----------+ +----------+ +------+
+ SMTP client SMTP server
+
+ When an SMTP client has a message to transmit, it establishes a two-
+ way transmission channel to an SMTP server. The responsibility of an
+ SMTP client is to transfer mail messages to one or more SMTP servers,
+ or report its failure to do so.
+
+ The means by which a mail message is presented to an SMTP client, and
+ how that client determines the domain name(s) to which mail messages
+ are to be transferred is a local matter, and is not addressed by this
+ document. In some cases, the domain name(s) transferred to, or
+ determined by, an SMTP client will identify the final destination(s)
+ of the mail message. In other cases, common with SMTP clients
+ associated with implementations of the POP [3, 26] or IMAP [6]
+ protocols, or when the SMTP client is inside an isolated transport
+ service environment, the domain name determined will identify an
+ intermediate destination through which all mail messages are to be
+ relayed. SMTP clients that transfer all traffic, regardless of the
+ target domain names associated with the individual messages, or that
+ do not maintain queues for retrying message transmissions that
+ initially cannot be completed, may otherwise conform to this
+ specification but are not considered fully-capable. Fully-capable
+ SMTP implementations, including the relays used by these less capable
+
+
+
+
+Klensin Standards Track [Page 5]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ ones, and their destinations, are expected to support all of the
+ queuing, retrying, and alternate address functions discussed in this
+ specification.
+
+ The means by which an SMTP client, once it has determined a target
+ domain name, determines the identity of an SMTP server to which a
+ copy of a message is to be transferred, and then performs that
+ transfer, is covered by this document. To effect a mail transfer to
+ an SMTP server, an SMTP client establishes a two-way transmission
+ channel to that SMTP server. An SMTP client determines the address
+ of an appropriate host running an SMTP server by resolving a
+ destination domain name to either an intermediate Mail eXchanger host
+ or a final target host.
+
+ An SMTP server may be either the ultimate destination or an
+ intermediate "relay" (that is, it may assume the role of an SMTP
+ client after receiving the message) or "gateway" (that is, it may
+ transport the message further using some protocol other than SMTP).
+ SMTP commands are generated by the SMTP client and sent to the SMTP
+ server. SMTP replies are sent from the SMTP server to the SMTP
+ client in response to the commands.
+
+ In other words, message transfer can occur in a single connection
+ between the original SMTP-sender and the final SMTP-recipient, or can
+ occur in a series of hops through intermediary systems. In either
+ case, a formal handoff of responsibility for the message occurs: the
+ protocol requires that a server accept responsibility for either
+ delivering a message or properly reporting the failure to do so.
+
+ Once the transmission channel is established and initial handshaking
+ completed, the SMTP client normally initiates a mail transaction.
+ Such a transaction consists of a series of commands to specify the
+ originator and destination of the mail and transmission of the
+ message content (including any headers or other structure) itself.
+ When the same message is sent to multiple recipients, this protocol
+ encourages the transmission of only one copy of the data for all
+ recipients at the same destination (or intermediate relay) host.
+
+ The server responds to each command with a reply; replies may
+ indicate that the command was accepted, that additional commands are
+ expected, or that a temporary or permanent error condition exists.
+ Commands specifying the sender or recipients may include server-
+ permitted SMTP service extension requests as discussed in section
+ 2.2. The dialog is purposely lock-step, one-at-a-time, although this
+ can be modified by mutually-agreed extension requests such as command
+ pipelining [13].
+
+
+
+
+
+Klensin Standards Track [Page 6]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ Once a given mail message has been transmitted, the client may either
+ request that the connection be shut down or may initiate other mail
+ transactions. In addition, an SMTP client may use a connection to an
+ SMTP server for ancillary services such as verification of email
+ addresses or retrieval of mailing list subscriber addresses.
+
+ As suggested above, this protocol provides mechanisms for the
+ transmission of mail. This transmission normally occurs directly
+ from the sending user's host to the receiving user's host when the
+ two hosts are connected to the same transport service. When they are
+ not connected to the same transport service, transmission occurs via
+ one or more relay SMTP servers. An intermediate host that acts as
+ either an SMTP relay or as a gateway into some other transmission
+ environment is usually selected through the use of the domain name
+ service (DNS) Mail eXchanger mechanism.
+
+ Usually, intermediate hosts are determined via the DNS MX record, not
+ by explicit "source" routing (see section 5 and appendices C and
+ F.2).
+
+2.2 The Extension Model
+
+2.2.1 Background
+
+ In an effort that started in 1990, approximately a decade after RFC
+ 821 was completed, the protocol was modified with a "service
+ extensions" model that permits the client and server to agree to
+ utilize shared functionality beyond the original SMTP requirements.
+ The SMTP extension mechanism defines a means whereby an extended SMTP
+ client and server may recognize each other, and the server can inform
+ the client as to the service extensions that it supports.
+
+ Contemporary SMTP implementations MUST support the basic extension
+ mechanisms. For instance, servers MUST support the EHLO command even
+ if they do not implement any specific extensions and clients SHOULD
+ preferentially utilize EHLO rather than HELO. (However, for
+ compatibility with older conforming implementations, SMTP clients and
+ servers MUST support the original HELO mechanisms as a fallback.)
+ Unless the different characteristics of HELO must be identified for
+ interoperability purposes, this document discusses only EHLO.
+
+ SMTP is widely deployed and high-quality implementations have proven
+ to be very robust. However, the Internet community now considers
+ some services to be important that were not anticipated when the
+ protocol was first designed. If support for those services is to be
+ added, it must be done in a way that permits older implementations to
+ continue working acceptably. The extension framework consists of:
+
+
+
+
+Klensin Standards Track [Page 7]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ - The SMTP command EHLO, superseding the earlier HELO,
+
+ - a registry of SMTP service extensions,
+
+ - additional parameters to the SMTP MAIL and RCPT commands, and
+
+ - optional replacements for commands defined in this protocol, such
+ as for DATA in non-ASCII transmissions [33].
+
+ SMTP's strength comes primarily from its simplicity. Experience with
+ many protocols has shown that protocols with few options tend towards
+ ubiquity, whereas protocols with many options tend towards obscurity.
+
+ Each and every extension, regardless of its benefits, must be
+ carefully scrutinized with respect to its implementation, deployment,
+ and interoperability costs. In many cases, the cost of extending the
+ SMTP service will likely outweigh the benefit.
+
+2.2.2 Definition and Registration of Extensions
+
+ The IANA maintains a registry of SMTP service extensions. A
+ corresponding EHLO keyword value is associated with each extension.
+ Each service extension registered with the IANA must be defined in a
+ formal standards-track or IESG-approved experimental protocol
+ document. The definition must include:
+
+ - the textual name of the SMTP service extension;
+
+ - the EHLO keyword value associated with the extension;
+
+ - the syntax and possible values of parameters associated with the
+ EHLO keyword value;
+
+ - any additional SMTP verbs associated with the extension
+ (additional verbs will usually be, but are not required to be, the
+ same as the EHLO keyword value);
+
+ - any new parameters the extension associates with the MAIL or RCPT
+ verbs;
+
+ - a description of how support for the extension affects the
+ behavior of a server and client SMTP; and,
+
+ - the increment by which the extension is increasing the maximum
+ length of the commands MAIL and/or RCPT, over that specified in
+ this standard.
+
+
+
+
+
+Klensin Standards Track [Page 8]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ In addition, any EHLO keyword value starting with an upper or lower
+ case "X" refers to a local SMTP service extension used exclusively
+ through bilateral agreement. Keywords beginning with "X" MUST NOT be
+ used in a registered service extension. Conversely, keyword values
+ presented in the EHLO response that do not begin with "X" MUST
+ correspond to a standard, standards-track, or IESG-approved
+ experimental SMTP service extension registered with IANA. A
+ conforming server MUST NOT offer non-"X"-prefixed keyword values that
+ are not described in a registered extension.
+
+ Additional verbs and parameter names are bound by the same rules as
+ EHLO keywords; specifically, verbs beginning with "X" are local
+ extensions that may not be registered or standardized. Conversely,
+ verbs not beginning with "X" must always be registered.
+
+2.3 Terminology
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described below.
+
+ 1. MUST This word, or the terms "REQUIRED" or "SHALL", mean that
+ the definition is an absolute requirement of the specification.
+
+ 2. MUST NOT This phrase, or the phrase "SHALL NOT", mean that the
+ definition is an absolute prohibition of the specification.
+
+ 3. SHOULD This word, or the adjective "RECOMMENDED", mean that
+ there may exist valid reasons in particular circumstances to
+ ignore a particular item, but the full implications must be
+ understood and carefully weighed before choosing a different
+ course.
+
+ 4. SHOULD NOT This phrase, or the phrase "NOT RECOMMENDED" mean
+ that there may exist valid reasons in particular circumstances
+ when the particular behavior is acceptable or even useful, but the
+ full implications should be understood and the case carefully
+ weighed before implementing any behavior described with this
+ label.
+
+ 5. MAY This word, or the adjective "OPTIONAL", mean that an item is
+ truly optional. One vendor may choose to include the item because
+ a particular marketplace requires it or because the vendor feels
+ that it enhances the product while another vendor may omit the
+ same item. An implementation which does not include a particular
+ option MUST be prepared to interoperate with another
+ implementation which does include the option, though perhaps with
+ reduced functionality. In the same vein an implementation which
+
+
+
+Klensin Standards Track [Page 9]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ does include a particular option MUST be prepared to interoperate
+ with another implementation which does not include the option
+ (except, of course, for the feature the option provides.)
+
+2.3.1 Mail Objects
+
+ SMTP transports a mail object. A mail object contains an envelope
+ and content.
+
+ The SMTP envelope is sent as a series of SMTP protocol units
+ (described in section 3). It consists of an originator address (to
+ which error reports should be directed); one or more recipient
+ addresses; and optional protocol extension material. Historically,
+ variations on the recipient address specification command (RCPT TO)
+ could be used to specify alternate delivery modes, such as immediate
+ display; those variations have now been deprecated (see appendix F,
+ section F.6).
+
+ The SMTP content is sent in the SMTP DATA protocol unit and has two
+ parts: the headers and the body. If the content conforms to other
+ contemporary standards, the headers form a collection of field/value
+ pairs structured as in the message format specification [32]; the
+ body, if structured, is defined according to MIME [12]. The content
+ is textual in nature, expressed using the US-ASCII repertoire [1].
+ Although SMTP extensions (such as "8BITMIME" [20]) may relax this
+ restriction for the content body, the content headers are always
+ encoded using the US-ASCII repertoire. A MIME extension [23] defines
+ an algorithm for representing header values outside the US-ASCII
+ repertoire, while still encoding them using the US-ASCII repertoire.
+
+2.3.2 Senders and Receivers
+
+ In RFC 821, the two hosts participating in an SMTP transaction were
+ described as the "SMTP-sender" and "SMTP-receiver". This document
+ has been changed to reflect current industry terminology and hence
+ refers to them as the "SMTP client" (or sometimes just "the client")
+ and "SMTP server" (or just "the server"), respectively. Since a
+ given host may act both as server and client in a relay situation,
+ "receiver" and "sender" terminology is still used where needed for
+ clarity.
+
+2.3.3 Mail Agents and Message Stores
+
+ Additional mail system terminology became common after RFC 821 was
+ published and, where convenient, is used in this specification. In
+ particular, SMTP servers and clients provide a mail transport service
+ and therefore act as "Mail Transfer Agents" (MTAs). "Mail User
+ Agents" (MUAs or UAs) are normally thought of as the sources and
+
+
+
+Klensin Standards Track [Page 10]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ targets of mail. At the source, an MUA might collect mail to be
+ transmitted from a user and hand it off to an MTA; the final
+ ("delivery") MTA would be thought of as handing the mail off to an
+ MUA (or at least transferring responsibility to it, e.g., by
+ depositing the message in a "message store"). However, while these
+ terms are used with at least the appearance of great precision in
+ other environments, the implied boundaries between MUAs and MTAs
+ often do not accurately match common, and conforming, practices with
+ Internet mail. Hence, the reader should be cautious about inferring
+ the strong relationships and responsibilities that might be implied
+ if these terms were used elsewhere.
+
+2.3.4 Host
+
+ For the purposes of this specification, a host is a computer system
+ attached to the Internet (or, in some cases, to a private TCP/IP
+ network) and supporting the SMTP protocol. Hosts are known by names
+ (see "domain"); identifying them by numerical address is discouraged.
+
+2.3.5 Domain
+
+ A domain (or domain name) consists of one or more dot-separated
+ components. These components ("labels" in DNS terminology [22]) are
+ restricted for SMTP purposes to consist of a sequence of letters,
+ digits, and hyphens drawn from the ASCII character set [1]. Domain
+ names are used as names of hosts and of other entities in the domain
+ name hierarchy. For example, a domain may refer to an alias (label
+ of a CNAME RR) or the label of Mail eXchanger records to be used to
+ deliver mail instead of representing a host name. See [22] and
+ section 5 of this specification.
+
+ The domain name, as described in this document and in [22], is the
+ entire, fully-qualified name (often referred to as an "FQDN"). A
+ domain name that is not in FQDN form is no more than a local alias.
+ Local aliases MUST NOT appear in any SMTP transaction.
+
+2.3.6 Buffer and State Table
+
+ SMTP sessions are stateful, with both parties carefully maintaining a
+ common view of the current state. In this document we model this
+ state by a virtual "buffer" and a "state table" on the server which
+ may be used by the client to, for example, "clear the buffer" or
+ "reset the state table," causing the information in the buffer to be
+ discarded and the state to be returned to some previous state.
+
+
+
+
+
+
+
+Klensin Standards Track [Page 11]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+2.3.7 Lines
+
+ SMTP commands and, unless altered by a service extension, message
+ data, are transmitted in "lines". Lines consist of zero or more data
+ characters terminated by the sequence ASCII character "CR" (hex value
+ 0D) followed immediately by ASCII character "LF" (hex value 0A).
+ This termination sequence is denoted as <CRLF> in this document.
+ Conforming implementations MUST NOT recognize or generate any other
+ character or character sequence as a line terminator. Limits MAY be
+ imposed on line lengths by servers (see section 4.5.3).
+
+ In addition, the appearance of "bare" "CR" or "LF" characters in text
+ (i.e., either without the other) has a long history of causing
+ problems in mail implementations and applications that use the mail
+ system as a tool. SMTP client implementations MUST NOT transmit
+ these characters except when they are intended as line terminators
+ and then MUST, as indicated above, transmit them only as a <CRLF>
+ sequence.
+
+2.3.8 Originator, Delivery, Relay, and Gateway Systems
+
+ This specification makes a distinction among four types of SMTP
+ systems, based on the role those systems play in transmitting
+ electronic mail. An "originating" system (sometimes called an SMTP
+ originator) introduces mail into the Internet or, more generally,
+ into a transport service environment. A "delivery" SMTP system is
+ one that receives mail from a transport service environment and
+ passes it to a mail user agent or deposits it in a message store
+ which a mail user agent is expected to subsequently access. A
+ "relay" SMTP system (usually referred to just as a "relay") receives
+ mail from an SMTP client and transmits it, without modification to
+ the message data other than adding trace information, to another SMTP
+ server for further relaying or for delivery.
+
+ A "gateway" SMTP system (usually referred to just as a "gateway")
+ receives mail from a client system in one transport environment and
+ transmits it to a server system in another transport environment.
+ Differences in protocols or message semantics between the transport
+ environments on either side of a gateway may require that the gateway
+ system perform transformations to the message that are not permitted
+ to SMTP relay systems. For the purposes of this specification,
+ firewalls that rewrite addresses should be considered as gateways,
+ even if SMTP is used on both sides of them (see [11]).
+
+
+
+
+
+
+
+
+Klensin Standards Track [Page 12]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+2.3.9 Message Content and Mail Data
+
+ The terms "message content" and "mail data" are used interchangeably
+ in this document to describe the material transmitted after the DATA
+ command is accepted and before the end of data indication is
+ transmitted. Message content includes message headers and the
+ possibly-structured message body. The MIME specification [12]
+ provides the standard mechanisms for structured message bodies.
+
+2.3.10 Mailbox and Address
+
+ As used in this specification, an "address" is a character string
+ that identifies a user to whom mail will be sent or a location into
+ which mail will be deposited. The term "mailbox" refers to that
+ depository. The two terms are typically used interchangeably unless
+ the distinction between the location in which mail is placed (the
+ mailbox) and a reference to it (the address) is important. An
+ address normally consists of user and domain specifications. The
+ standard mailbox naming convention is defined to be "local-
+ part@domain": contemporary usage permits a much broader set of
+ applications than simple "user names". Consequently, and due to a
+ long history of problems when intermediate hosts have attempted to
+ optimize transport by modifying them, the local-part MUST be
+ interpreted and assigned semantics only by the host specified in the
+ domain part of the address.
+
+2.3.11 Reply
+
+ An SMTP reply is an acknowledgment (positive or negative) sent from
+ receiver to sender via the transmission channel in response to a
+ command. The general form of a reply is a numeric completion code
+ (indicating failure or success) usually followed by a text string.
+ The codes are for use by programs and the text is usually intended
+ for human users. Recent work [34] has specified further structuring
+ of the reply strings, including the use of supplemental and more
+ specific completion codes.
+
+2.4 General Syntax Principles and Transaction Model
+
+ SMTP commands and replies have a rigid syntax. All commands begin
+ with a command verb. All Replies begin with a three digit numeric
+ code. In some commands and replies, arguments MUST follow the verb
+ or reply code. Some commands do not accept arguments (after the
+ verb), and some reply codes are followed, sometimes optionally, by
+ free form text. In both cases, where text appears, it is separated
+ from the verb or reply code by a space character. Complete
+ definitions of commands and replies appear in section 4.
+
+
+
+
+Klensin Standards Track [Page 13]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ Verbs and argument values (e.g., "TO:" or "to:" in the RCPT command
+ and extension name keywords) are not case sensitive, with the sole
+ exception in this specification of a mailbox local-part (SMTP
+ Extensions may explicitly specify case-sensitive elements). That is,
+ a command verb, an argument value other than a mailbox local-part,
+ and free form text MAY be encoded in upper case, lower case, or any
+ mixture of upper and lower case with no impact on its meaning. This
+ is NOT true of a mailbox local-part. The local-part of a mailbox
+ MUST BE treated as case sensitive. Therefore, SMTP implementations
+ MUST take care to preserve the case of mailbox local-parts. Mailbox
+ domains are not case sensitive. In particular, for some hosts the
+ user "smith" is different from the user "Smith". However, exploiting
+ the case sensitivity of mailbox local-parts impedes interoperability
+ and is discouraged.
+
+ A few SMTP servers, in violation of this specification (and RFC 821)
+ require that command verbs be encoded by clients in upper case.
+ Implementations MAY wish to employ this encoding to accommodate those
+ servers.
+
+ The argument field consists of a variable length character string
+ ending with the end of the line, i.e., with the character sequence
+ <CRLF>. The receiver will take no action until this sequence is
+ received.
+
+ The syntax for each command is shown with the discussion of that
+ command. Common elements and parameters are shown in section 4.1.2.
+
+ Commands and replies are composed of characters from the ASCII
+ character set [1]. When the transport service provides an 8-bit byte
+ (octet) transmission channel, each 7-bit character is transmitted
+ right justified in an octet with the high order bit cleared to zero.
+ More specifically, the unextended SMTP service provides seven bit
+ transport only. An originating SMTP client which has not
+ successfully negotiated an appropriate extension with a particular
+ server MUST NOT transmit messages with information in the high-order
+ bit of octets. If such messages are transmitted in violation of this
+ rule, receiving SMTP servers MAY clear the high-order bit or reject
+ the message as invalid. In general, a relay SMTP SHOULD assume that
+ the message content it has received is valid and, assuming that the
+ envelope permits doing so, relay it without inspecting that content.
+ Of course, if the content is mislabeled and the data path cannot
+ accept the actual content, this may result in ultimate delivery of a
+ severely garbled message to the recipient. Delivery SMTP systems MAY
+ reject ("bounce") such messages rather than deliver them. No sending
+ SMTP system is permitted to send envelope commands in any character
+
+
+
+
+
+Klensin Standards Track [Page 14]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ set other than US-ASCII; receiving systems SHOULD reject such
+ commands, normally using "500 syntax error - invalid character"
+ replies.
+
+ Eight-bit message content transmission MAY be requested of the server
+ by a client using extended SMTP facilities, notably the "8BITMIME"
+ extension [20]. 8BITMIME SHOULD be supported by SMTP servers.
+ However, it MUST not be construed as authorization to transmit
+ unrestricted eight bit material. 8BITMIME MUST NOT be requested by
+ senders for material with the high bit on that is not in MIME format
+ with an appropriate content-transfer encoding; servers MAY reject
+ such messages.
+
+ The metalinguistic notation used in this document corresponds to the
+ "Augmented BNF" used in other Internet mail system documents. The
+ reader who is not familiar with that syntax should consult the ABNF
+ specification [8]. Metalanguage terms used in running text are
+ surrounded by pointed brackets (e.g., <CRLF>) for clarity.
+
+3. The SMTP Procedures: An Overview
+
+ This section contains descriptions of the procedures used in SMTP:
+ session initiation, the mail transaction, forwarding mail, verifying
+ mailbox names and expanding mailing lists, and the opening and
+ closing exchanges. Comments on relaying, a note on mail domains, and
+ a discussion of changing roles are included at the end of this
+ section. Several complete scenarios are presented in appendix D.
+
+3.1 Session Initiation
+
+ An SMTP session is initiated when a client opens a connection to a
+ server and the server responds with an opening message.
+
+ SMTP server implementations MAY include identification of their
+ software and version information in the connection greeting reply
+ after the 220 code, a practice that permits more efficient isolation
+ and repair of any problems. Implementations MAY make provision for
+ SMTP servers to disable the software and version announcement where
+ it causes security concerns. While some systems also identify their
+ contact point for mail problems, this is not a substitute for
+ maintaining the required "postmaster" address (see section 4.5.1).
+
+ The SMTP protocol allows a server to formally reject a transaction
+ while still allowing the initial connection as follows: a 554
+ response MAY be given in the initial connection opening message
+ instead of the 220. A server taking this approach MUST still wait
+ for the client to send a QUIT (see section 4.1.1.10) before closing
+ the connection and SHOULD respond to any intervening commands with
+
+
+
+Klensin Standards Track [Page 15]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ "503 bad sequence of commands". Since an attempt to make an SMTP
+ connection to such a system is probably in error, a server returning
+ a 554 response on connection opening SHOULD provide enough
+ information in the reply text to facilitate debugging of the sending
+ system.
+
+3.2 Client Initiation
+
+ Once the server has sent the welcoming message and the client has
+ received it, the client normally sends the EHLO command to the
+ server, indicating the client's identity. In addition to opening the
+ session, use of EHLO indicates that the client is able to process
+ service extensions and requests that the server provide a list of the
+ extensions it supports. Older SMTP systems which are unable to
+ support service extensions and contemporary clients which do not
+ require service extensions in the mail session being initiated, MAY
+ use HELO instead of EHLO. Servers MUST NOT return the extended
+ EHLO-style response to a HELO command. For a particular connection
+ attempt, if the server returns a "command not recognized" response to
+ EHLO, the client SHOULD be able to fall back and send HELO.
+
+ In the EHLO command the host sending the command identifies itself;
+ the command may be interpreted as saying "Hello, I am <domain>" (and,
+ in the case of EHLO, "and I support service extension requests").
+
+3.3 Mail Transactions
+
+ There are three steps to SMTP mail transactions. The transaction
+ starts with a MAIL command which gives the sender identification.
+ (In general, the MAIL command may be sent only when no mail
+ transaction is in progress; see section 4.1.4.) A series of one or
+ more RCPT commands follows giving the receiver information. Then a
+ DATA command initiates transfer of the mail data and is terminated by
+ the "end of mail" data indicator, which also confirms the
+ transaction.
+
+ The first step in the procedure is the MAIL command.
+
+ MAIL FROM:<reverse-path> [SP <mail-parameters> ] <CRLF>
+
+ This command tells the SMTP-receiver that a new mail transaction is
+ starting and to reset all its state tables and buffers, including any
+ recipients or mail data. The <reverse-path> portion of the first or
+ only argument contains the source mailbox (between "<" and ">"
+ brackets), which can be used to report errors (see section 4.2 for a
+ discussion of error reporting). If accepted, the SMTP server returns
+ a 250 OK reply. If the mailbox specification is not acceptable for
+ some reason, the server MUST return a reply indicating whether the
+
+
+
+Klensin Standards Track [Page 16]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ failure is permanent (i.e., will occur again if the client tries to
+ send the same address again) or temporary (i.e., the address might be
+ accepted if the client tries again later). Despite the apparent
+ scope of this requirement, there are circumstances in which the
+ acceptability of the reverse-path may not be determined until one or
+ more forward-paths (in RCPT commands) can be examined. In those
+ cases, the server MAY reasonably accept the reverse-path (with a 250
+ reply) and then report problems after the forward-paths are received
+ and examined. Normally, failures produce 550 or 553 replies.
+
+ Historically, the <reverse-path> can contain more than just a
+ mailbox, however, contemporary systems SHOULD NOT use source routing
+ (see appendix C).
+
+ The optional <mail-parameters> are associated with negotiated SMTP
+ service extensions (see section 2.2).
+
+ The second step in the procedure is the RCPT command.
+
+ RCPT TO:<forward-path> [ SP <rcpt-parameters> ] <CRLF>
+
+ The first or only argument to this command includes a forward-path
+ (normally a mailbox and domain, always surrounded by "<" and ">"
+ brackets) identifying one recipient. If accepted, the SMTP server
+ returns a 250 OK reply and stores the forward-path. If the recipient
+ is known not to be a deliverable address, the SMTP server returns a
+ 550 reply, typically with a string such as "no such user - " and the
+ mailbox name (other circumstances and reply codes are possible).
+ This step of the procedure can be repeated any number of times.
+
+ The <forward-path> can contain more than just a mailbox.
+ Historically, the <forward-path> can be a source routing list of
+ hosts and the destination mailbox, however, contemporary SMTP clients
+ SHOULD NOT utilize source routes (see appendix C). Servers MUST be
+ prepared to encounter a list of source routes in the forward path,
+ but SHOULD ignore the routes or MAY decline to support the relaying
+ they imply. Similarly, servers MAY decline to accept mail that is
+ destined for other hosts or systems. These restrictions make a
+ server useless as a relay for clients that do not support full SMTP
+ functionality. Consequently, restricted-capability clients MUST NOT
+ assume that any SMTP server on the Internet can be used as their mail
+ processing (relaying) site. If a RCPT command appears without a
+ previous MAIL command, the server MUST return a 503 "Bad sequence of
+ commands" response. The optional <rcpt-parameters> are associated
+ with negotiated SMTP service extensions (see section 2.2).
+
+ The third step in the procedure is the DATA command (or some
+ alternative specified in a service extension).
+
+
+
+Klensin Standards Track [Page 17]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ DATA <CRLF>
+
+ If accepted, the SMTP server returns a 354 Intermediate reply and
+ considers all succeeding lines up to but not including the end of
+ mail data indicator to be the message text. When the end of text is
+ successfully received and stored the SMTP-receiver sends a 250 OK
+ reply.
+
+ Since the mail data is sent on the transmission channel, the end of
+ mail data must be indicated so that the command and reply dialog can
+ be resumed. SMTP indicates the end of the mail data by sending a
+ line containing only a "." (period or full stop). A transparency
+ procedure is used to prevent this from interfering with the user's
+ text (see section 4.5.2).
+
+ The end of mail data indicator also confirms the mail transaction and
+ tells the SMTP server to now process the stored recipients and mail
+ data. If accepted, the SMTP server returns a 250 OK reply. The DATA
+ command can fail at only two points in the protocol exchange:
+
+ - If there was no MAIL, or no RCPT, command, or all such commands
+ were rejected, the server MAY return a "command out of sequence"
+ (503) or "no valid recipients" (554) reply in response to the DATA
+ command. If one of those replies (or any other 5yz reply) is
+ received, the client MUST NOT send the message data; more
+ generally, message data MUST NOT be sent unless a 354 reply is
+ received.
+
+ - If the verb is initially accepted and the 354 reply issued, the
+ DATA command should fail only if the mail transaction was
+ incomplete (for example, no recipients), or if resources were
+ unavailable (including, of course, the server unexpectedly
+ becoming unavailable), or if the server determines that the
+ message should be rejected for policy or other reasons.
+
+ However, in practice, some servers do not perform recipient
+ verification until after the message text is received. These servers
+ SHOULD treat a failure for one or more recipients as a "subsequent
+ failure" and return a mail message as discussed in section 6. Using
+ a "550 mailbox not found" (or equivalent) reply code after the data
+ are accepted makes it difficult or impossible for the client to
+ determine which recipients failed.
+
+ When RFC 822 format [7, 32] is being used, the mail data include the
+ memo header items such as Date, Subject, To, Cc, From. Server SMTP
+ systems SHOULD NOT reject messages based on perceived defects in the
+ RFC 822 or MIME [12] message header or message body. In particular,
+
+
+
+
+Klensin Standards Track [Page 18]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ they MUST NOT reject messages in which the numbers of Resent-fields
+ do not match or Resent-to appears without Resent-from and/or Resent-
+ date.
+
+ Mail transaction commands MUST be used in the order discussed above.
+
+3.4 Forwarding for Address Correction or Updating
+
+ Forwarding support is most often required to consolidate and simplify
+ addresses within, or relative to, some enterprise and less frequently
+ to establish addresses to link a person's prior address with current
+ one. Silent forwarding of messages (without server notification to
+ the sender), for security or non-disclosure purposes, is common in
+ the contemporary Internet.
+
+ In both the enterprise and the "new address" cases, information
+ hiding (and sometimes security) considerations argue against exposure
+ of the "final" address through the SMTP protocol as a side-effect of
+ the forwarding activity. This may be especially important when the
+ final address may not even be reachable by the sender. Consequently,
+ the "forwarding" mechanisms described in section 3.2 of RFC 821, and
+ especially the 251 (corrected destination) and 551 reply codes from
+ RCPT must be evaluated carefully by implementers and, when they are
+ available, by those configuring systems.
+
+ In particular:
+
+ * Servers MAY forward messages when they are aware of an address
+ change. When they do so, they MAY either provide address-updating
+ information with a 251 code, or may forward "silently" and return
+ a 250 code. But, if a 251 code is used, they MUST NOT assume that
+ the client will actually update address information or even return
+ that information to the user.
+
+ Alternately,
+
+ * Servers MAY reject or bounce messages when they are not
+ deliverable when addressed. When they do so, they MAY either
+ provide address-updating information with a 551 code, or may
+ reject the message as undeliverable with a 550 code and no
+ address-specific information. But, if a 551 code is used, they
+ MUST NOT assume that the client will actually update address
+ information or even return that information to the user.
+
+ SMTP server implementations that support the 251 and/or 551 reply
+ codes are strongly encouraged to provide configuration mechanisms so
+ that sites which conclude that they would undesirably disclose
+ information can disable or restrict their use.
+
+
+
+Klensin Standards Track [Page 19]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+3.5 Commands for Debugging Addresses
+
+3.5.1 Overview
+
+ SMTP provides commands to verify a user name or obtain the content of
+ a mailing list. This is done with the VRFY and EXPN commands, which
+ have character string arguments. Implementations SHOULD support VRFY
+ and EXPN (however, see section 3.5.2 and 7.3).
+
+ For the VRFY command, the string is a user name or a user name and
+ domain (see below). If a normal (i.e., 250) response is returned,
+ the response MAY include the full name of the user and MUST include
+ the mailbox of the user. It MUST be in either of the following
+ forms:
+
+ User Name <local-part@domain>
+ local-part@domain
+
+ When a name that is the argument to VRFY could identify more than one
+ mailbox, the server MAY either note the ambiguity or identify the
+ alternatives. In other words, any of the following are legitimate
+ response to VRFY:
+
+ 553 User ambiguous
+
+ or
+
+ 553- Ambiguous; Possibilities are
+ 553-Joe Smith <jsmith@foo.com>
+ 553-Harry Smith <hsmith@foo.com>
+ 553 Melvin Smith <dweep@foo.com>
+
+ or
+
+ 553-Ambiguous; Possibilities
+ 553- <jsmith@foo.com>
+ 553- <hsmith@foo.com>
+ 553 <dweep@foo.com>
+
+ Under normal circumstances, a client receiving a 553 reply would be
+ expected to expose the result to the user. Use of exactly the forms
+ given, and the "user ambiguous" or "ambiguous" keywords, possibly
+ supplemented by extended reply codes such as those described in [34],
+ will facilitate automated translation into other languages as needed.
+ Of course, a client that was highly automated or that was operating
+ in another language than English, might choose to try to translate
+ the response, to return some other indication to the user than the
+
+
+
+
+Klensin Standards Track [Page 20]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ literal text of the reply, or to take some automated action such as
+ consulting a directory service for additional information before
+ reporting to the user.
+
+ For the EXPN command, the string identifies a mailing list, and the
+ successful (i.e., 250) multiline response MAY include the full name
+ of the users and MUST give the mailboxes on the mailing list.
+
+ In some hosts the distinction between a mailing list and an alias for
+ a single mailbox is a bit fuzzy, since a common data structure may
+ hold both types of entries, and it is possible to have mailing lists
+ containing only one mailbox. If a request is made to apply VRFY to a
+ mailing list, a positive response MAY be given if a message so
+ addressed would be delivered to everyone on the list, otherwise an
+ error SHOULD be reported (e.g., "550 That is a mailing list, not a
+ user" or "252 Unable to verify members of mailing list"). If a
+ request is made to expand a user name, the server MAY return a
+ positive response consisting of a list containing one name, or an
+ error MAY be reported (e.g., "550 That is a user name, not a mailing
+ list").
+
+ In the case of a successful multiline reply (normal for EXPN) exactly
+ one mailbox is to be specified on each line of the reply. The case
+ of an ambiguous request is discussed above.
+
+ "User name" is a fuzzy term and has been used deliberately. An
+ implementation of the VRFY or EXPN commands MUST include at least
+ recognition of local mailboxes as "user names". However, since
+ current Internet practice often results in a single host handling
+ mail for multiple domains, hosts, especially hosts that provide this
+ functionality, SHOULD accept the "local-part@domain" form as a "user
+ name"; hosts MAY also choose to recognize other strings as "user
+ names".
+
+ The case of expanding a mailbox list requires a multiline reply, such
+ as:
+
+ C: EXPN Example-People
+ S: 250-Jon Postel <Postel@isi.edu>
+ S: 250-Fred Fonebone <Fonebone@physics.foo-u.edu>
+ S: 250 Sam Q. Smith <SQSmith@specific.generic.com>
+
+ or
+
+ C: EXPN Executive-Washroom-List
+ S: 550 Access Denied to You.
+
+
+
+
+
+Klensin Standards Track [Page 21]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ The character string arguments of the VRFY and EXPN commands cannot
+ be further restricted due to the variety of implementations of the
+ user name and mailbox list concepts. On some systems it may be
+ appropriate for the argument of the EXPN command to be a file name
+ for a file containing a mailing list, but again there are a variety
+ of file naming conventions in the Internet. Similarly, historical
+ variations in what is returned by these commands are such that the
+ response SHOULD be interpreted very carefully, if at all, and SHOULD
+ generally only be used for diagnostic purposes.
+
+3.5.2 VRFY Normal Response
+
+ When normal (2yz or 551) responses are returned from a VRFY or EXPN
+ request, the reply normally includes the mailbox name, i.e.,
+ "<local-part@domain>", where "domain" is a fully qualified domain
+ name, MUST appear in the syntax. In circumstances exceptional enough
+ to justify violating the intent of this specification, free-form text
+ MAY be returned. In order to facilitate parsing by both computers
+ and people, addresses SHOULD appear in pointed brackets. When
+ addresses, rather than free-form debugging information, are returned,
+ EXPN and VRFY MUST return only valid domain addresses that are usable
+ in SMTP RCPT commands. Consequently, if an address implies delivery
+ to a program or other system, the mailbox name used to reach that
+ target MUST be given. Paths (explicit source routes) MUST NOT be
+ returned by VRFY or EXPN.
+
+ Server implementations SHOULD support both VRFY and EXPN. For
+ security reasons, implementations MAY provide local installations a
+ way to disable either or both of these commands through configuration
+ options or the equivalent. When these commands are supported, they
+ are not required to work across relays when relaying is supported.
+ Since they were both optional in RFC 821, they MUST be listed as
+ service extensions in an EHLO response, if they are supported.
+
+3.5.3 Meaning of VRFY or EXPN Success Response
+
+ A server MUST NOT return a 250 code in response to a VRFY or EXPN
+ command unless it has actually verified the address. In particular,
+ a server MUST NOT return 250 if all it has done is to verify that the
+ syntax given is valid. In that case, 502 (Command not implemented)
+ or 500 (Syntax error, command unrecognized) SHOULD be returned. As
+ stated elsewhere, implementation (in the sense of actually validating
+ addresses and returning information) of VRFY and EXPN are strongly
+ recommended. Hence, implementations that return 500 or 502 for VRFY
+ are not in full compliance with this specification.
+
+
+
+
+
+
+Klensin Standards Track [Page 22]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ There may be circumstances where an address appears to be valid but
+ cannot reasonably be verified in real time, particularly when a
+ server is acting as a mail exchanger for another server or domain.
+ "Apparent validity" in this case would normally involve at least
+ syntax checking and might involve verification that any domains
+ specified were ones to which the host expected to be able to relay
+ mail. In these situations, reply code 252 SHOULD be returned. These
+ cases parallel the discussion of RCPT verification discussed in
+ section 2.1. Similarly, the discussion in section 3.4 applies to the
+ use of reply codes 251 and 551 with VRFY (and EXPN) to indicate
+ addresses that are recognized but that would be forwarded or bounced
+ were mail received for them. Implementations generally SHOULD be
+ more aggressive about address verification in the case of VRFY than
+ in the case of RCPT, even if it takes a little longer to do so.
+
+3.5.4 Semantics and Applications of EXPN
+
+ EXPN is often very useful in debugging and understanding problems
+ with mailing lists and multiple-target-address aliases. Some systems
+ have attempted to use source expansion of mailing lists as a means of
+ eliminating duplicates. The propagation of aliasing systems with
+ mail on the Internet, for hosts (typically with MX and CNAME DNS
+ records), for mailboxes (various types of local host aliases), and in
+ various proxying arrangements, has made it nearly impossible for
+ these strategies to work consistently, and mail systems SHOULD NOT
+ attempt them.
+
+3.6 Domains
+
+ Only resolvable, fully-qualified, domain names (FQDNs) are permitted
+ when domain names are used in SMTP. In other words, names that can
+ be resolved to MX RRs or A RRs (as discussed in section 5) are
+ permitted, as are CNAME RRs whose targets can be resolved, in turn,
+ to MX or A RRs. Local nicknames or unqualified names MUST NOT be
+ used. There are two exceptions to the rule requiring FQDNs:
+
+ - The domain name given in the EHLO command MUST BE either a primary
+ host name (a domain name that resolves to an A RR) or, if the host
+ has no name, an address literal as described in section 4.1.1.1.
+
+ - The reserved mailbox name "postmaster" may be used in a RCPT
+ command without domain qualification (see section 4.1.1.3) and
+ MUST be accepted if so used.
+
+
+
+
+
+
+
+
+Klensin Standards Track [Page 23]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+3.7 Relaying
+
+ In general, the availability of Mail eXchanger records in the domain
+ name system [22, 27] makes the use of explicit source routes in the
+ Internet mail system unnecessary. Many historical problems with
+ their interpretation have made their use undesirable. SMTP clients
+ SHOULD NOT generate explicit source routes except under unusual
+ circumstances. SMTP servers MAY decline to act as mail relays or to
+ accept addresses that specify source routes. When route information
+ is encountered, SMTP servers are also permitted to ignore the route
+ information and simply send to the final destination specified as the
+ last element in the route and SHOULD do so. There has been an
+ invalid practice of using names that do not appear in the DNS as
+ destination names, with the senders counting on the intermediate
+ hosts specified in source routing to resolve any problems. If source
+ routes are stripped, this practice will cause failures. This is one
+ of several reasons why SMTP clients MUST NOT generate invalid source
+ routes or depend on serial resolution of names.
+
+ When source routes are not used, the process described in RFC 821 for
+ constructing a reverse-path from the forward-path is not applicable
+ and the reverse-path at the time of delivery will simply be the
+ address that appeared in the MAIL command.
+
+ A relay SMTP server is usually the target of a DNS MX record that
+ designates it, rather than the final delivery system. The relay
+ server may accept or reject the task of relaying the mail in the same
+ way it accepts or rejects mail for a local user. If it accepts the
+ task, it then becomes an SMTP client, establishes a transmission
+ channel to the next SMTP server specified in the DNS (according to
+ the rules in section 5), and sends it the mail. If it declines to
+ relay mail to a particular address for policy reasons, a 550 response
+ SHOULD be returned.
+
+ Many mail-sending clients exist, especially in conjunction with
+ facilities that receive mail via POP3 or IMAP, that have limited
+ capability to support some of the requirements of this specification,
+ such as the ability to queue messages for subsequent delivery
+ attempts. For these clients, it is common practice to make private
+ arrangements to send all messages to a single server for processing
+ and subsequent distribution. SMTP, as specified here, is not ideally
+ suited for this role, and work is underway on standardized mail
+ submission protocols that might eventually supercede the current
+ practices. In any event, because these arrangements are private and
+ fall outside the scope of this specification, they are not described
+ here.
+
+
+
+
+
+Klensin Standards Track [Page 24]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ It is important to note that MX records can point to SMTP servers
+ which act as gateways into other environments, not just SMTP relays
+ and final delivery systems; see sections 3.8 and 5.
+
+ If an SMTP server has accepted the task of relaying the mail and
+ later finds that the destination is incorrect or that the mail cannot
+ be delivered for some other reason, then it MUST construct an
+ "undeliverable mail" notification message and send it to the
+ originator of the undeliverable mail (as indicated by the reverse-
+ path). Formats specified for non-delivery reports by other standards
+ (see, for example, [24, 25]) SHOULD be used if possible.
+
+ This notification message must be from the SMTP server at the relay
+ host or the host that first determines that delivery cannot be
+ accomplished. Of course, SMTP servers MUST NOT send notification
+ messages about problems transporting notification messages. One way
+ to prevent loops in error reporting is to specify a null reverse-path
+ in the MAIL command of a notification message. When such a message
+ is transmitted the reverse-path MUST be set to null (see section
+ 4.5.5 for additional discussion). A MAIL command with a null
+ reverse-path appears as follows:
+
+ MAIL FROM:<>
+
+ As discussed in section 2.4.1, a relay SMTP has no need to inspect or
+ act upon the headers or body of the message data and MUST NOT do so
+ except to add its own "Received:" header (section 4.4) and,
+ optionally, to attempt to detect looping in the mail system (see
+ section 6.2).
+
+3.8 Mail Gatewaying
+
+ While the relay function discussed above operates within the Internet
+ SMTP transport service environment, MX records or various forms of
+ explicit routing may require that an intermediate SMTP server perform
+ a translation function between one transport service and another. As
+ discussed in section 2.3.8, when such a system is at the boundary
+ between two transport service environments, we refer to it as a
+ "gateway" or "gateway SMTP".
+
+ Gatewaying mail between different mail environments, such as
+ different mail formats and protocols, is complex and does not easily
+ yield to standardization. However, some general requirements may be
+ given for a gateway between the Internet and another mail
+ environment.
+
+
+
+
+
+
+Klensin Standards Track [Page 25]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+3.8.1 Header Fields in Gatewaying
+
+ Header fields MAY be rewritten when necessary as messages are
+ gatewayed across mail environment boundaries. This may involve
+ inspecting the message body or interpreting the local-part of the
+ destination address in spite of the prohibitions in section 2.4.1.
+
+ Other mail systems gatewayed to the Internet often use a subset of
+ RFC 822 headers or provide similar functionality with a different
+ syntax, but some of these mail systems do not have an equivalent to
+ the SMTP envelope. Therefore, when a message leaves the Internet
+ environment, it may be necessary to fold the SMTP envelope
+ information into the message header. A possible solution would be to
+ create new header fields to carry the envelope information (e.g.,
+ "X-SMTP-MAIL:" and "X-SMTP-RCPT:"); however, this would require
+ changes in mail programs in foreign environments and might risk
+ disclosure of private information (see section 7.2).
+
+3.8.2 Received Lines in Gatewaying
+
+ When forwarding a message into or out of the Internet environment, a
+ gateway MUST prepend a Received: line, but it MUST NOT alter in any
+ way a Received: line that is already in the header.
+
+ "Received:" fields of messages originating from other environments
+ may not conform exactly to this specification. However, the most
+ important use of Received: lines is for debugging mail faults, and
+ this debugging can be severely hampered by well-meaning gateways that
+ try to "fix" a Received: line. As another consequence of trace
+ fields arising in non-SMTP environments, receiving systems MUST NOT
+ reject mail based on the format of a trace field and SHOULD be
+ extremely robust in the light of unexpected information or formats in
+ those fields.
+
+ The gateway SHOULD indicate the environment and protocol in the "via"
+ clauses of Received field(s) that it supplies.
+
+3.8.3 Addresses in Gatewaying
+
+ From the Internet side, the gateway SHOULD accept all valid address
+ formats in SMTP commands and in RFC 822 headers, and all valid RFC
+ 822 messages. Addresses and headers generated by gateways MUST
+ conform to applicable Internet standards (including this one and RFC
+ 822). Gateways are, of course, subject to the same rules for
+ handling source routes as those described for other SMTP systems in
+ section 3.3.
+
+
+
+
+
+Klensin Standards Track [Page 26]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+3.8.4 Other Header Fields in Gatewaying
+
+ The gateway MUST ensure that all header fields of a message that it
+ forwards into the Internet mail environment meet the requirements for
+ Internet mail. In particular, all addresses in "From:", "To:",
+ "Cc:", etc., fields MUST be transformed (if necessary) to satisfy RFC
+ 822 syntax, MUST reference only fully-qualified domain names, and
+ MUST be effective and useful for sending replies. The translation
+ algorithm used to convert mail from the Internet protocols to another
+ environment's protocol SHOULD ensure that error messages from the
+ foreign mail environment are delivered to the return path from the
+ SMTP envelope, not to the sender listed in the "From:" field (or
+ other fields) of the RFC 822 message.
+
+3.8.5 Envelopes in Gatewaying
+
+ Similarly, when forwarding a message from another environment into
+ the Internet, the gateway SHOULD set the envelope return path in
+ accordance with an error message return address, if supplied by the
+ foreign environment. If the foreign environment has no equivalent
+ concept, the gateway must select and use a best approximation, with
+ the message originator's address as the default of last resort.
+
+3.9 Terminating Sessions and Connections
+
+ An SMTP connection is terminated when the client sends a QUIT
+ command. The server responds with a positive reply code, after which
+ it closes the connection.
+
+ An SMTP server MUST NOT intentionally close the connection except:
+
+ - After receiving a QUIT command and responding with a 221 reply.
+
+ - After detecting the need to shut down the SMTP service and
+ returning a 421 response code. This response code can be issued
+ after the server receives any command or, if necessary,
+ asynchronously from command receipt (on the assumption that the
+ client will receive it after the next command is issued).
+
+ In particular, a server that closes connections in response to
+ commands that are not understood is in violation of this
+ specification. Servers are expected to be tolerant of unknown
+ commands, issuing a 500 reply and awaiting further instructions from
+ the client.
+
+
+
+
+
+
+
+Klensin Standards Track [Page 27]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ An SMTP server which is forcibly shut down via external means SHOULD
+ attempt to send a line containing a 421 response code to the SMTP
+ client before exiting. The SMTP client will normally read the 421
+ response code after sending its next command.
+
+ SMTP clients that experience a connection close, reset, or other
+ communications failure due to circumstances not under their control
+ (in violation of the intent of this specification but sometimes
+ unavoidable) SHOULD, to maintain the robustness of the mail system,
+ treat the mail transaction as if a 451 response had been received and
+ act accordingly.
+
+3.10 Mailing Lists and Aliases
+
+ An SMTP-capable host SHOULD support both the alias and the list
+ models of address expansion for multiple delivery. When a message is
+ delivered or forwarded to each address of an expanded list form, the
+ return address in the envelope ("MAIL FROM:") MUST be changed to be
+ the address of a person or other entity who administers the list.
+ However, in this case, the message header [32] MUST be left
+ unchanged; in particular, the "From" field of the message header is
+ unaffected.
+
+ An important mail facility is a mechanism for multi-destination
+ delivery of a single message, by transforming (or "expanding" or
+ "exploding") a pseudo-mailbox address into a list of destination
+ mailbox addresses. When a message is sent to such a pseudo-mailbox
+ (sometimes called an "exploder"), copies are forwarded or
+ redistributed to each mailbox in the expanded list. Servers SHOULD
+ simply utilize the addresses on the list; application of heuristics
+ or other matching rules to eliminate some addresses, such as that of
+ the originator, is strongly discouraged. We classify such a pseudo-
+ mailbox as an "alias" or a "list", depending upon the expansion
+ rules.
+
+3.10.1 Alias
+
+ To expand an alias, the recipient mailer simply replaces the pseudo-
+ mailbox address in the envelope with each of the expanded addresses
+ in turn; the rest of the envelope and the message body are left
+ unchanged. The message is then delivered or forwarded to each
+ expanded address.
+
+3.10.2 List
+
+ A mailing list may be said to operate by "redistribution" rather than
+ by "forwarding". To expand a list, the recipient mailer replaces the
+ pseudo-mailbox address in the envelope with all of the expanded
+
+
+
+Klensin Standards Track [Page 28]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ addresses. The return address in the envelope is changed so that all
+ error messages generated by the final deliveries will be returned to
+ a list administrator, not to the message originator, who generally
+ has no control over the contents of the list and will typically find
+ error messages annoying.
+
+4. The SMTP Specifications
+
+4.1 SMTP Commands
+
+4.1.1 Command Semantics and Syntax
+
+ The SMTP commands define the mail transfer or the mail system
+ function requested by the user. SMTP commands are character strings
+ terminated by <CRLF>. The commands themselves are alphabetic
+ characters terminated by <SP> if parameters follow and <CRLF>
+ otherwise. (In the interest of improved interoperability, SMTP
+ receivers are encouraged to tolerate trailing white space before the
+ terminating <CRLF>.) The syntax of the local part of a mailbox must
+ conform to receiver site conventions and the syntax specified in
+ section 4.1.2. The SMTP commands are discussed below. The SMTP
+ replies are discussed in section 4.2.
+
+ A mail transaction involves several data objects which are
+ communicated as arguments to different commands. The reverse-path is
+ the argument of the MAIL command, the forward-path is the argument of
+ the RCPT command, and the mail data is the argument of the DATA
+ command. These arguments or data objects must be transmitted and
+ held pending the confirmation communicated by the end of mail data
+ indication which finalizes the transaction. The model for this is
+ that distinct buffers are provided to hold the types of data objects,
+ that is, there is a reverse-path buffer, a forward-path buffer, and a
+ mail data buffer. Specific commands cause information to be appended
+ to a specific buffer, or cause one or more buffers to be cleared.
+
+ Several commands (RSET, DATA, QUIT) are specified as not permitting
+ parameters. In the absence of specific extensions offered by the
+ server and accepted by the client, clients MUST NOT send such
+ parameters and servers SHOULD reject commands containing them as
+ having invalid syntax.
+
+4.1.1.1 Extended HELLO (EHLO) or HELLO (HELO)
+
+ These commands are used to identify the SMTP client to the SMTP
+ server. The argument field contains the fully-qualified domain name
+ of the SMTP client if one is available. In situations in which the
+ SMTP client system does not have a meaningful domain name (e.g., when
+ its address is dynamically allocated and no reverse mapping record is
+
+
+
+Klensin Standards Track [Page 29]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ available), the client SHOULD send an address literal (see section
+ 4.1.3), optionally followed by information that will help to identify
+ the client system. y The SMTP server identifies itself to the SMTP
+ client in the connection greeting reply and in the response to this
+ command.
+
+ A client SMTP SHOULD start an SMTP session by issuing the EHLO
+ command. If the SMTP server supports the SMTP service extensions it
+ will give a successful response, a failure response, or an error
+ response. If the SMTP server, in violation of this specification,
+ does not support any SMTP service extensions it will generate an
+ error response. Older client SMTP systems MAY, as discussed above,
+ use HELO (as specified in RFC 821) instead of EHLO, and servers MUST
+ support the HELO command and reply properly to it. In any event, a
+ client MUST issue HELO or EHLO before starting a mail transaction.
+
+ These commands, and a "250 OK" reply to one of them, confirm that
+ both the SMTP client and the SMTP server are in the initial state,
+ that is, there is no transaction in progress and all state tables and
+ buffers are cleared.
+
+ Syntax:
+
+ ehlo = "EHLO" SP Domain CRLF
+ helo = "HELO" SP Domain CRLF
+
+ Normally, the response to EHLO will be a multiline reply. Each line
+ of the response contains a keyword and, optionally, one or more
+ parameters. Following the normal syntax for multiline replies, these
+ keyworks follow the code (250) and a hyphen for all but the last
+ line, and the code and a space for the last line. The syntax for a
+ positive response, using the ABNF notation and terminal symbols of
+ [8], is:
+
+ ehlo-ok-rsp = ( "250" domain [ SP ehlo-greet ] CRLF )
+ / ( "250-" domain [ SP ehlo-greet ] CRLF
+ *( "250-" ehlo-line CRLF )
+ "250" SP ehlo-line CRLF )
+
+ ehlo-greet = 1*(%d0-9 / %d11-12 / %d14-127)
+ ; string of any characters other than CR or LF
+
+ ehlo-line = ehlo-keyword *( SP ehlo-param )
+
+ ehlo-keyword = (ALPHA / DIGIT) *(ALPHA / DIGIT / "-")
+ ; additional syntax of ehlo-params depends on
+ ; ehlo-keyword
+
+
+
+
+Klensin Standards Track [Page 30]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ ehlo-param = 1*(%d33-127)
+ ; any CHAR excluding <SP> and all
+ ; control characters (US-ASCII 0-31 inclusive)
+
+ Although EHLO keywords may be specified in upper, lower, or mixed
+ case, they MUST always be recognized and processed in a case-
+ insensitive manner. This is simply an extension of practices
+ specified in RFC 821 and section 2.4.1.
+
+4.1.1.2 MAIL (MAIL)
+
+ This command is used to initiate a mail transaction in which the mail
+ data is delivered to an SMTP server which may, in turn, deliver it to
+ one or more mailboxes or pass it on to another system (possibly using
+ SMTP). The argument field contains a reverse-path and may contain
+ optional parameters. In general, the MAIL command may be sent only
+ when no mail transaction is in progress, see section 4.1.4.
+
+ The reverse-path consists of the sender mailbox. Historically, that
+ mailbox might optionally have been preceded by a list of hosts, but
+ that behavior is now deprecated (see appendix C). In some types of
+ reporting messages for which a reply is likely to cause a mail loop
+ (for example, mail delivery and nondelivery notifications), the
+ reverse-path may be null (see section 3.7).
+
+ This command clears the reverse-path buffer, the forward-path buffer,
+ and the mail data buffer; and inserts the reverse-path information
+ from this command into the reverse-path buffer.
+
+ If service extensions were negotiated, the MAIL command may also
+ carry parameters associated with a particular service extension.
+
+ Syntax:
+
+ "MAIL FROM:" ("<>" / Reverse-Path)
+ [SP Mail-parameters] CRLF
+
+4.1.1.3 RECIPIENT (RCPT)
+
+ This command is used to identify an individual recipient of the mail
+ data; multiple recipients are specified by multiple use of this
+ command. The argument field contains a forward-path and may contain
+ optional parameters.
+
+ The forward-path normally consists of the required destination
+ mailbox. Sending systems SHOULD not generate the optional list of
+ hosts known as a source route. Receiving systems MUST recognize
+
+
+
+
+Klensin Standards Track [Page 31]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ source route syntax but SHOULD strip off the source route
+ specification and utilize the domain name associated with the mailbox
+ as if the source route had not been provided.
+
+ Similarly, relay hosts SHOULD strip or ignore source routes, and
+ names MUST NOT be copied into the reverse-path. When mail reaches
+ its ultimate destination (the forward-path contains only a
+ destination mailbox), the SMTP server inserts it into the destination
+ mailbox in accordance with its host mail conventions.
+
+ For example, mail received at relay host xyz.com with envelope
+ commands
+
+ MAIL FROM:<userx@y.foo.org>
+ RCPT TO:<@hosta.int,@jkl.org:userc@d.bar.org>
+
+ will normally be sent directly on to host d.bar.org with envelope
+ commands
+
+ MAIL FROM:<userx@y.foo.org>
+ RCPT TO:<userc@d.bar.org>
+
+ As provided in appendix C, xyz.com MAY also choose to relay the
+ message to hosta.int, using the envelope commands
+
+ MAIL FROM:<userx@y.foo.org>
+ RCPT TO:<@hosta.int,@jkl.org:userc@d.bar.org>
+
+ or to jkl.org, using the envelope commands
+
+ MAIL FROM:<userx@y.foo.org>
+ RCPT TO:<@jkl.org:userc@d.bar.org>
+
+ Of course, since hosts are not required to relay mail at all, xyz.com
+ may also reject the message entirely when the RCPT command is
+ received, using a 550 code (since this is a "policy reason").
+
+ If service extensions were negotiated, the RCPT command may also
+ carry parameters associated with a particular service extension
+ offered by the server. The client MUST NOT transmit parameters other
+ than those associated with a service extension offered by the server
+ in its EHLO response.
+
+Syntax:
+ "RCPT TO:" ("<Postmaster@" domain ">" / "<Postmaster>" / Forward-Path)
+ [SP Rcpt-parameters] CRLF
+
+
+
+
+
+Klensin Standards Track [Page 32]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+4.1.1.4 DATA (DATA)
+
+ The receiver normally sends a 354 response to DATA, and then treats
+ the lines (strings ending in <CRLF> sequences, as described in
+ section 2.3.7) following the command as mail data from the sender.
+ This command causes the mail data to be appended to the mail data
+ buffer. The mail data may contain any of the 128 ASCII character
+ codes, although experience has indicated that use of control
+ characters other than SP, HT, CR, and LF may cause problems and
+ SHOULD be avoided when possible.
+
+ The mail data is terminated by a line containing only a period, that
+ is, the character sequence "<CRLF>.<CRLF>" (see section 4.5.2). This
+ is the end of mail data indication. Note that the first <CRLF> of
+ this terminating sequence is also the <CRLF> that ends the final line
+ of the data (message text) or, if there was no data, ends the DATA
+ command itself. An extra <CRLF> MUST NOT be added, as that would
+ cause an empty line to be added to the message. The only exception
+ to this rule would arise if the message body were passed to the
+ originating SMTP-sender with a final "line" that did not end in
+ <CRLF>; in that case, the originating SMTP system MUST either reject
+ the message as invalid or add <CRLF> in order to have the receiving
+ SMTP server recognize the "end of data" condition.
+
+ The custom of accepting lines ending only in <LF>, as a concession to
+ non-conforming behavior on the part of some UNIX systems, has proven
+ to cause more interoperability problems than it solves, and SMTP
+ server systems MUST NOT do this, even in the name of improved
+ robustness. In particular, the sequence "<LF>.<LF>" (bare line
+ feeds, without carriage returns) MUST NOT be treated as equivalent to
+ <CRLF>.<CRLF> as the end of mail data indication.
+
+ Receipt of the end of mail data indication requires the server to
+ process the stored mail transaction information. This processing
+ consumes the information in the reverse-path buffer, the forward-path
+ buffer, and the mail data buffer, and on the completion of this
+ command these buffers are cleared. If the processing is successful,
+ the receiver MUST send an OK reply. If the processing fails the
+ receiver MUST send a failure reply. The SMTP model does not allow
+ for partial failures at this point: either the message is accepted by
+ the server for delivery and a positive response is returned or it is
+ not accepted and a failure reply is returned. In sending a positive
+ completion reply to the end of data indication, the receiver takes
+ full responsibility for the message (see section 6.1). Errors that
+ are diagnosed subsequently MUST be reported in a mail message, as
+ discussed in section 4.4.
+
+
+
+
+
+Klensin Standards Track [Page 33]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ When the SMTP server accepts a message either for relaying or for
+ final delivery, it inserts a trace record (also referred to
+ interchangeably as a "time stamp line" or "Received" line) at the top
+ of the mail data. This trace record indicates the identity of the
+ host that sent the message, the identity of the host that received
+ the message (and is inserting this time stamp), and the date and time
+ the message was received. Relayed messages will have multiple time
+ stamp lines. Details for formation of these lines, including their
+ syntax, is specified in section 4.4.
+
+ Additional discussion about the operation of the DATA command appears
+ in section 3.3.
+
+ Syntax:
+ "DATA" CRLF
+
+4.1.1.5 RESET (RSET)
+
+ This command specifies that the current mail transaction will be
+ aborted. Any stored sender, recipients, and mail data MUST be
+ discarded, and all buffers and state tables cleared. The receiver
+ MUST send a "250 OK" reply to a RSET command with no arguments. A
+ reset command may be issued by the client at any time. It is
+ effectively equivalent to a NOOP (i.e., if has no effect) if issued
+ immediately after EHLO, before EHLO is issued in the session, after
+ an end-of-data indicator has been sent and acknowledged, or
+ immediately before a QUIT. An SMTP server MUST NOT close the
+ connection as the result of receiving a RSET; that action is reserved
+ for QUIT (see section 4.1.1.10).
+
+ Since EHLO implies some additional processing and response by the
+ server, RSET will normally be more efficient than reissuing that
+ command, even though the formal semantics are the same.
+
+ There are circumstances, contrary to the intent of this
+ specification, in which an SMTP server may receive an indication that
+ the underlying TCP connection has been closed or reset. To preserve
+ the robustness of the mail system, SMTP servers SHOULD be prepared
+ for this condition and SHOULD treat it as if a QUIT had been received
+ before the connection disappeared.
+
+ Syntax:
+ "RSET" CRLF
+
+
+
+
+
+
+
+
+Klensin Standards Track [Page 34]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+4.1.1.6 VERIFY (VRFY)
+
+ This command asks the receiver to confirm that the argument
+ identifies a user or mailbox. If it is a user name, information is
+ returned as specified in section 3.5.
+
+ This command has no effect on the reverse-path buffer, the forward-
+ path buffer, or the mail data buffer.
+
+ Syntax:
+ "VRFY" SP String CRLF
+
+4.1.1.7 EXPAND (EXPN)
+
+ This command asks the receiver to confirm that the argument
+ identifies a mailing list, and if so, to return the membership of
+ that list. If the command is successful, a reply is returned
+ containing information as described in section 3.5. This reply will
+ have multiple lines except in the trivial case of a one-member list.
+
+ This command has no effect on the reverse-path buffer, the forward-
+ path buffer, or the mail data buffer and may be issued at any time.
+
+ Syntax:
+ "EXPN" SP String CRLF
+
+4.1.1.8 HELP (HELP)
+
+ This command causes the server to send helpful information to the
+ client. The command MAY take an argument (e.g., any command name)
+ and return more specific information as a response.
+
+ This command has no effect on the reverse-path buffer, the forward-
+ path buffer, or the mail data buffer and may be issued at any time.
+
+ SMTP servers SHOULD support HELP without arguments and MAY support it
+ with arguments.
+
+ Syntax:
+ "HELP" [ SP String ] CRLF
+
+4.1.1.9 NOOP (NOOP)
+
+ This command does not affect any parameters or previously entered
+ commands. It specifies no action other than that the receiver send
+ an OK reply.
+
+
+
+
+
+Klensin Standards Track [Page 35]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ This command has no effect on the reverse-path buffer, the forward-
+ path buffer, or the mail data buffer and may be issued at any time.
+ If a parameter string is specified, servers SHOULD ignore it.
+
+ Syntax:
+ "NOOP" [ SP String ] CRLF
+
+4.1.1.10 QUIT (QUIT)
+
+ This command specifies that the receiver MUST send an OK reply, and
+ then close the transmission channel.
+
+ The receiver MUST NOT intentionally close the transmission channel
+ until it receives and replies to a QUIT command (even if there was an
+ error). The sender MUST NOT intentionally close the transmission
+ channel until it sends a QUIT command and SHOULD wait until it
+ receives the reply (even if there was an error response to a previous
+ command). If the connection is closed prematurely due to violations
+ of the above or system or network failure, the server MUST cancel any
+ pending transaction, but not undo any previously completed
+ transaction, and generally MUST act as if the command or transaction
+ in progress had received a temporary error (i.e., a 4yz response).
+
+ The QUIT command may be issued at any time.
+
+ Syntax:
+ "QUIT" CRLF
+
+4.1.2 Command Argument Syntax
+
+ The syntax of the argument fields of the above commands (using the
+ syntax specified in [8] where applicable) is given below. Some of
+ the productions given below are used only in conjunction with source
+ routes as described in appendix C. Terminals not defined in this
+ document, such as ALPHA, DIGIT, SP, CR, LF, CRLF, are as defined in
+ the "core" syntax [8 (section 6)] or in the message format syntax
+ [32].
+
+ Reverse-path = Path
+ Forward-path = Path
+ Path = "<" [ A-d-l ":" ] Mailbox ">"
+ A-d-l = At-domain *( "," A-d-l )
+ ; Note that this form, the so-called "source route",
+ ; MUST BE accepted, SHOULD NOT be generated, and SHOULD be
+ ; ignored.
+ At-domain = "@" domain
+ Mail-parameters = esmtp-param *(SP esmtp-param)
+ Rcpt-parameters = esmtp-param *(SP esmtp-param)
+
+
+
+Klensin Standards Track [Page 36]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ esmtp-param = esmtp-keyword ["=" esmtp-value]
+ esmtp-keyword = (ALPHA / DIGIT) *(ALPHA / DIGIT / "-")
+ esmtp-value = 1*(%d33-60 / %d62-127)
+ ; any CHAR excluding "=", SP, and control characters
+ Keyword = Ldh-str
+ Argument = Atom
+ Domain = (sub-domain 1*("." sub-domain)) / address-literal
+ sub-domain = Let-dig [Ldh-str]
+
+ address-literal = "[" IPv4-address-literal /
+ IPv6-address-literal /
+ General-address-literal "]"
+ ; See section 4.1.3
+
+ Mailbox = Local-part "@" Domain
+
+ Local-part = Dot-string / Quoted-string
+ ; MAY be case-sensitive
+
+ Dot-string = Atom *("." Atom)
+
+ Atom = 1*atext
+
+ Quoted-string = DQUOTE *qcontent DQUOTE
+
+ String = Atom / Quoted-string
+
+ While the above definition for Local-part is relatively permissive,
+ for maximum interoperability, a host that expects to receive mail
+ SHOULD avoid defining mailboxes where the Local-part requires (or
+ uses) the Quoted-string form or where the Local-part is case-
+ sensitive. For any purposes that require generating or comparing
+ Local-parts (e.g., to specific mailbox names), all quoted forms MUST
+ be treated as equivalent and the sending system SHOULD transmit the
+ form that uses the minimum quoting possible.
+
+ Systems MUST NOT define mailboxes in such a way as to require the use
+ in SMTP of non-ASCII characters (octets with the high order bit set
+ to one) or ASCII "control characters" (decimal value 0-31 and 127).
+ These characters MUST NOT be used in MAIL or RCPT commands or other
+ commands that require mailbox names.
+
+ Note that the backslash, "\", is a quote character, which is used to
+ indicate that the next character is to be used literally (instead of
+ its normal interpretation). For example, "Joe\,Smith" indicates a
+ single nine character user field with the comma being the fourth
+ character of the field.
+
+
+
+
+Klensin Standards Track [Page 37]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ To promote interoperability and consistent with long-standing
+ guidance about conservative use of the DNS in naming and applications
+ (e.g., see section 2.3.1 of the base DNS document, RFC1035 [22]),
+ characters outside the set of alphas, digits, and hyphen MUST NOT
+ appear in domain name labels for SMTP clients or servers. In
+ particular, the underscore character is not permitted. SMTP servers
+ that receive a command in which invalid character codes have been
+ employed, and for which there are no other reasons for rejection,
+ MUST reject that command with a 501 response.
+
+4.1.3 Address Literals
+
+ Sometimes a host is not known to the domain name system and
+ communication (and, in particular, communication to report and repair
+ the error) is blocked. To bypass this barrier a special literal form
+ of the address is allowed as an alternative to a domain name. For
+ IPv4 addresses, this form uses four small decimal integers separated
+ by dots and enclosed by brackets such as [123.255.37.2], which
+ indicates an (IPv4) Internet Address in sequence-of-octets form. For
+ IPv6 and other forms of addressing that might eventually be
+ standardized, the form consists of a standardized "tag" that
+ identifies the address syntax, a colon, and the address itself, in a
+ format specified as part of the IPv6 standards [17].
+
+ Specifically:
+
+ IPv4-address-literal = Snum 3("." Snum)
+ IPv6-address-literal = "IPv6:" IPv6-addr
+ General-address-literal = Standardized-tag ":" 1*dcontent
+ Standardized-tag = Ldh-str
+ ; MUST be specified in a standards-track RFC
+ ; and registered with IANA
+
+ Snum = 1*3DIGIT ; representing a decimal integer
+ ; value in the range 0 through 255
+ Let-dig = ALPHA / DIGIT
+ Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig
+
+ IPv6-addr = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp
+ IPv6-hex = 1*4HEXDIG
+ IPv6-full = IPv6-hex 7(":" IPv6-hex)
+ IPv6-comp = [IPv6-hex *5(":" IPv6-hex)] "::" [IPv6-hex *5(":"
+ IPv6-hex)]
+ ; The "::" represents at least 2 16-bit groups of zeros
+ ; No more than 6 groups in addition to the "::" may be
+ ; present
+ IPv6v4-full = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal
+ IPv6v4-comp = [IPv6-hex *3(":" IPv6-hex)] "::"
+
+
+
+Klensin Standards Track [Page 38]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ [IPv6-hex *3(":" IPv6-hex) ":"] IPv4-address-literal
+ ; The "::" represents at least 2 16-bit groups of zeros
+ ; No more than 4 groups in addition to the "::" and
+ ; IPv4-address-literal may be present
+
+4.1.4 Order of Commands
+
+ There are restrictions on the order in which these commands may be
+ used.
+
+ A session that will contain mail transactions MUST first be
+ initialized by the use of the EHLO command. An SMTP server SHOULD
+ accept commands for non-mail transactions (e.g., VRFY or EXPN)
+ without this initialization.
+
+ An EHLO command MAY be issued by a client later in the session. If
+ it is issued after the session begins, the SMTP server MUST clear all
+ buffers and reset the state exactly as if a RSET command had been
+ issued. In other words, the sequence of RSET followed immediately by
+ EHLO is redundant, but not harmful other than in the performance cost
+ of executing unnecessary commands.
+
+ If the EHLO command is not acceptable to the SMTP server, 501, 500,
+ or 502 failure replies MUST be returned as appropriate. The SMTP
+ server MUST stay in the same state after transmitting these replies
+ that it was in before the EHLO was received.
+
+ The SMTP client MUST, if possible, ensure that the domain parameter
+ to the EHLO command is a valid principal host name (not a CNAME or MX
+ name) for its host. If this is not possible (e.g., when the client's
+ address is dynamically assigned and the client does not have an
+ obvious name), an address literal SHOULD be substituted for the
+ domain name and supplemental information provided that will assist in
+ identifying the client.
+
+ An SMTP server MAY verify that the domain name parameter in the EHLO
+ command actually corresponds to the IP address of the client.
+ However, the server MUST NOT refuse to accept a message for this
+ reason if the verification fails: the information about verification
+ failure is for logging and tracing only.
+
+ The NOOP, HELP, EXPN, VRFY, and RSET commands can be used at any time
+ during a session, or without previously initializing a session. SMTP
+ servers SHOULD process these normally (that is, not return a 503
+ code) even if no EHLO command has yet been received; clients SHOULD
+ open a session with EHLO before sending these commands.
+
+
+
+
+
+Klensin Standards Track [Page 39]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ If these rules are followed, the example in RFC 821 that shows "550
+ access denied to you" in response to an EXPN command is incorrect
+ unless an EHLO command precedes the EXPN or the denial of access is
+ based on the client's IP address or other authentication or
+ authorization-determining mechanisms.
+
+ The MAIL command (or the obsolete SEND, SOML, or SAML commands)
+ begins a mail transaction. Once started, a mail transaction consists
+ of a transaction beginning command, one or more RCPT commands, and a
+ DATA command, in that order. A mail transaction may be aborted by
+ the RSET (or a new EHLO) command. There may be zero or more
+ transactions in a session. MAIL (or SEND, SOML, or SAML) MUST NOT be
+ sent if a mail transaction is already open, i.e., it should be sent
+ only if no mail transaction had been started in the session, or it
+ the previous one successfully concluded with a successful DATA
+ command, or if the previous one was aborted with a RSET.
+
+ If the transaction beginning command argument is not acceptable, a
+ 501 failure reply MUST be returned and the SMTP server MUST stay in
+ the same state. If the commands in a transaction are out of order to
+ the degree that they cannot be processed by the server, a 503 failure
+ reply MUST be returned and the SMTP server MUST stay in the same
+ state.
+
+ The last command in a session MUST be the QUIT command. The QUIT
+ command cannot be used at any other time in a session, but SHOULD be
+ used by the client SMTP to request connection closure, even when no
+ session opening command was sent and accepted.
+
+4.1.5 Private-use Commands
+
+ As specified in section 2.2.2, commands starting in "X" may be used
+ by bilateral agreement between the client (sending) and server
+ (receiving) SMTP agents. An SMTP server that does not recognize such
+ a command is expected to reply with "500 Command not recognized". An
+ extended SMTP server MAY list the feature names associated with these
+ private commands in the response to the EHLO command.
+
+ Commands sent or accepted by SMTP systems that do not start with "X"
+ MUST conform to the requirements of section 2.2.2.
+
+4.2 SMTP Replies
+
+ Replies to SMTP commands serve to ensure the synchronization of
+ requests and actions in the process of mail transfer and to guarantee
+ that the SMTP client always knows the state of the SMTP server.
+ Every command MUST generate exactly one reply.
+
+
+
+
+Klensin Standards Track [Page 40]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ The details of the command-reply sequence are described in section
+ 4.3.
+
+ An SMTP reply consists of a three digit number (transmitted as three
+ numeric characters) followed by some text unless specified otherwise
+ in this document. The number is for use by automata to determine
+ what state to enter next; the text is for the human user. The three
+ digits contain enough encoded information that the SMTP client need
+ not examine the text and may either discard it or pass it on to the
+ user, as appropriate. Exceptions are as noted elsewhere in this
+ document. In particular, the 220, 221, 251, 421, and 551 reply codes
+ are associated with message text that must be parsed and interpreted
+ by machines. In the general case, the text may be receiver dependent
+ and context dependent, so there are likely to be varying texts for
+ each reply code. A discussion of the theory of reply codes is given
+ in section 4.2.1. Formally, a reply is defined to be the sequence: a
+ three-digit code, <SP>, one line of text, and <CRLF>, or a multiline
+ reply (as defined in section 4.2.1). Since, in violation of this
+ specification, the text is sometimes not sent, clients which do not
+ receive it SHOULD be prepared to process the code alone (with or
+ without a trailing space character). Only the EHLO, EXPN, and HELP
+ commands are expected to result in multiline replies in normal
+ circumstances, however, multiline replies are allowed for any
+ command.
+
+ In ABNF, server responses are:
+
+ Greeting = "220 " Domain [ SP text ] CRLF
+ Reply-line = Reply-code [ SP text ] CRLF
+
+ where "Greeting" appears only in the 220 response that announces that
+ the server is opening its part of the connection.
+
+ An SMTP server SHOULD send only the reply codes listed in this
+ document. An SMTP server SHOULD use the text shown in the examples
+ whenever appropriate.
+
+ An SMTP client MUST determine its actions only by the reply code, not
+ by the text (except for the "change of address" 251 and 551 and, if
+ necessary, 220, 221, and 421 replies); in the general case, any text,
+ including no text at all (although senders SHOULD NOT send bare
+ codes), MUST be acceptable. The space (blank) following the reply
+ code is considered part of the text. Whenever possible, a receiver-
+ SMTP SHOULD test the first digit (severity indication) of the reply
+ code.
+
+
+
+
+
+
+Klensin Standards Track [Page 41]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ The list of codes that appears below MUST NOT be construed as
+ permanent. While the addition of new codes should be a rare and
+ significant activity, with supplemental information in the textual
+ part of the response being preferred, new codes may be added as the
+ result of new Standards or Standards-track specifications.
+ Consequently, a sender-SMTP MUST be prepared to handle codes not
+ specified in this document and MUST do so by interpreting the first
+ digit only.
+
+4.2.1 Reply Code Severities and Theory
+
+ The three digits of the reply each have a special significance. The
+ first digit denotes whether the response is good, bad or incomplete.
+ An unsophisticated SMTP client, or one that receives an unexpected
+ code, will be able to determine its next action (proceed as planned,
+ redo, retrench, etc.) by examining this first digit. An SMTP client
+ that wants to know approximately what kind of error occurred (e.g.,
+ mail system error, command syntax error) may examine the second
+ digit. The third digit and any supplemental information that may be
+ present is reserved for the finest gradation of information.
+
+ There are five values for the first digit of the reply code:
+
+ 1yz Positive Preliminary reply
+ The command has been accepted, but the requested action is being
+ held in abeyance, pending confirmation of the information in this
+ reply. The SMTP client should send another command specifying
+ whether to continue or abort the action. Note: unextended SMTP
+ does not have any commands that allow this type of reply, and so
+ does not have continue or abort commands.
+
+ 2yz Positive Completion reply
+ The requested action has been successfully completed. A new
+ request may be initiated.
+
+ 3yz Positive Intermediate reply
+ The command has been accepted, but the requested action is being
+ held in abeyance, pending receipt of further information. The
+ SMTP client should send another command specifying this
+ information. This reply is used in command sequence groups (i.e.,
+ in DATA).
+
+ 4yz Transient Negative Completion reply
+ The command was not accepted, and the requested action did not
+ occur. However, the error condition is temporary and the action
+ may be requested again. The sender should return to the beginning
+ of the command sequence (if any). It is difficult to assign a
+ meaning to "transient" when two different sites (receiver- and
+
+
+
+Klensin Standards Track [Page 42]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ sender-SMTP agents) must agree on the interpretation. Each reply
+ in this category might have a different time value, but the SMTP
+ client is encouraged to try again. A rule of thumb to determine
+ whether a reply fits into the 4yz or the 5yz category (see below)
+ is that replies are 4yz if they can be successful if repeated
+ without any change in command form or in properties of the sender
+ or receiver (that is, the command is repeated identically and the
+ receiver does not put up a new implementation.)
+
+ 5yz Permanent Negative Completion reply
+ The command was not accepted and the requested action did not
+ occur. The SMTP client is discouraged from repeating the exact
+ request (in the same sequence). Even some "permanent" error
+ conditions can be corrected, so the human user may want to direct
+ the SMTP client to reinitiate the command sequence by direct
+ action at some point in the future (e.g., after the spelling has
+ been changed, or the user has altered the account status).
+
+ The second digit encodes responses in specific categories:
+
+ x0z Syntax: These replies refer to syntax errors, syntactically
+ correct commands that do not fit any functional category, and
+ unimplemented or superfluous commands.
+
+ x1z Information: These are replies to requests for information,
+ such as status or help.
+
+ x2z Connections: These are replies referring to the transmission
+ channel.
+
+ x3z Unspecified.
+
+ x4z Unspecified.
+
+ x5z Mail system: These replies indicate the status of the receiver
+ mail system vis-a-vis the requested transfer or other mail system
+ action.
+
+ The third digit gives a finer gradation of meaning in each category
+ specified by the second digit. The list of replies illustrates this.
+ Each reply text is recommended rather than mandatory, and may even
+ change according to the command with which it is associated. On the
+ other hand, the reply codes must strictly follow the specifications
+ in this section. Receiver implementations should not invent new
+ codes for slightly different situations from the ones described here,
+ but rather adapt codes already defined.
+
+
+
+
+
+Klensin Standards Track [Page 43]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ For example, a command such as NOOP, whose successful execution does
+ not offer the SMTP client any new information, will return a 250
+ reply. The reply is 502 when the command requests an unimplemented
+ non-site-specific action. A refinement of that is the 504 reply for
+ a command that is implemented, but that requests an unimplemented
+ parameter.
+
+ The reply text may be longer than a single line; in these cases the
+ complete text must be marked so the SMTP client knows when it can
+ stop reading the reply. This requires a special format to indicate a
+ multiple line reply.
+
+ The format for multiline replies requires that every line, except the
+ last, begin with the reply code, followed immediately by a hyphen,
+ "-" (also known as minus), followed by text. The last line will
+ begin with the reply code, followed immediately by <SP>, optionally
+ some text, and <CRLF>. As noted above, servers SHOULD send the <SP>
+ if subsequent text is not sent, but clients MUST be prepared for it
+ to be omitted.
+
+ For example:
+
+ 123-First line
+ 123-Second line
+ 123-234 text beginning with numbers
+ 123 The last line
+
+ In many cases the SMTP client then simply needs to search for a line
+ beginning with the reply code followed by <SP> or <CRLF> and ignore
+ all preceding lines. In a few cases, there is important data for the
+ client in the reply "text". The client will be able to identify
+ these cases from the current context.
+
+4.2.2 Reply Codes by Function Groups
+
+ 500 Syntax error, command unrecognized
+ (This may include errors such as command line too long)
+ 501 Syntax error in parameters or arguments
+ 502 Command not implemented (see section 4.2.4)
+ 503 Bad sequence of commands
+ 504 Command parameter not implemented
+
+ 211 System status, or system help reply
+ 214 Help message
+ (Information on how to use the receiver or the meaning of a
+ particular non-standard command; this reply is useful only
+ to the human user)
+
+
+
+
+Klensin Standards Track [Page 44]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ 220 <domain> Service ready
+ 221 <domain> Service closing transmission channel
+ 421 <domain> Service not available, closing transmission channel
+ (This may be a reply to any command if the service knows it
+ must shut down)
+
+ 250 Requested mail action okay, completed
+ 251 User not local; will forward to <forward-path>
+ (See section 3.4)
+ 252 Cannot VRFY user, but will accept message and attempt
+ delivery
+ (See section 3.5.3)
+ 450 Requested mail action not taken: mailbox unavailable
+ (e.g., mailbox busy)
+ 550 Requested action not taken: mailbox unavailable
+ (e.g., mailbox not found, no access, or command rejected
+ for policy reasons)
+ 451 Requested action aborted: error in processing
+ 551 User not local; please try <forward-path>
+ (See section 3.4)
+ 452 Requested action not taken: insufficient system storage
+ 552 Requested mail action aborted: exceeded storage allocation
+ 553 Requested action not taken: mailbox name not allowed
+ (e.g., mailbox syntax incorrect)
+ 354 Start mail input; end with <CRLF>.<CRLF>
+ 554 Transaction failed (Or, in the case of a connection-opening
+ response, "No SMTP service here")
+
+4.2.3 Reply Codes in Numeric Order
+
+ 211 System status, or system help reply
+ 214 Help message
+ (Information on how to use the receiver or the meaning of a
+ particular non-standard command; this reply is useful only
+ to the human user)
+ 220 <domain> Service ready
+ 221 <domain> Service closing transmission channel
+ 250 Requested mail action okay, completed
+ 251 User not local; will forward to <forward-path>
+ (See section 3.4)
+ 252 Cannot VRFY user, but will accept message and attempt
+ delivery
+ (See section 3.5.3)
+
+ 354 Start mail input; end with <CRLF>.<CRLF>
+
+
+
+
+
+
+Klensin Standards Track [Page 45]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ 421 <domain> Service not available, closing transmission channel
+ (This may be a reply to any command if the service knows it
+ must shut down)
+ 450 Requested mail action not taken: mailbox unavailable
+ (e.g., mailbox busy)
+ 451 Requested action aborted: local error in processing
+ 452 Requested action not taken: insufficient system storage
+ 500 Syntax error, command unrecognized
+ (This may include errors such as command line too long)
+ 501 Syntax error in parameters or arguments
+ 502 Command not implemented (see section 4.2.4)
+ 503 Bad sequence of commands
+ 504 Command parameter not implemented
+ 550 Requested action not taken: mailbox unavailable
+ (e.g., mailbox not found, no access, or command rejected
+ for policy reasons)
+ 551 User not local; please try <forward-path>
+ (See section 3.4)
+ 552 Requested mail action aborted: exceeded storage allocation
+ 553 Requested action not taken: mailbox name not allowed
+ (e.g., mailbox syntax incorrect)
+ 554 Transaction failed (Or, in the case of a connection-opening
+ response, "No SMTP service here")
+
+4.2.4 Reply Code 502
+
+ Questions have been raised as to when reply code 502 (Command not
+ implemented) SHOULD be returned in preference to other codes. 502
+ SHOULD be used when the command is actually recognized by the SMTP
+ server, but not implemented. If the command is not recognized, code
+ 500 SHOULD be returned. Extended SMTP systems MUST NOT list
+ capabilities in response to EHLO for which they will return 502 (or
+ 500) replies.
+
+4.2.5 Reply Codes After DATA and the Subsequent <CRLF>.<CRLF>
+
+ When an SMTP server returns a positive completion status (2yz code)
+ after the DATA command is completed with <CRLF>.<CRLF>, it accepts
+ responsibility for:
+
+ - delivering the message (if the recipient mailbox exists), or
+
+ - if attempts to deliver the message fail due to transient
+ conditions, retrying delivery some reasonable number of times at
+ intervals as specified in section 4.5.4.
+
+
+
+
+
+
+Klensin Standards Track [Page 46]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ - if attempts to deliver the message fail due to permanent
+ conditions, or if repeated attempts to deliver the message fail
+ due to transient conditions, returning appropriate notification to
+ the sender of the original message (using the address in the SMTP
+ MAIL command).
+
+ When an SMTP server returns a permanent error status (5yz) code after
+ the DATA command is completed with <CRLF>.<CRLF>, it MUST NOT make
+ any subsequent attempt to deliver that message. The SMTP client
+ retains responsibility for delivery of that message and may either
+ return it to the user or requeue it for a subsequent attempt (see
+ section 4.5.4.1).
+
+ The user who originated the message SHOULD be able to interpret the
+ return of a transient failure status (by mail message or otherwise)
+ as a non-delivery indication, just as a permanent failure would be
+ interpreted. I.e., if the client SMTP successfully handles these
+ conditions, the user will not receive such a reply.
+
+ When an SMTP server returns a permanent error status (5yz) code after
+ the DATA command is completely with <CRLF>.<CRLF>, it MUST NOT make
+ any subsequent attempt to deliver the message. As with temporary
+ error status codes, the SMTP client retains responsibility for the
+ message, but SHOULD not again attempt delivery to the same server
+ without user review and intervention of the message.
+
+4.3 Sequencing of Commands and Replies
+
+4.3.1 Sequencing Overview
+
+ The communication between the sender and receiver is an alternating
+ dialogue, controlled by the sender. As such, the sender issues a
+ command and the receiver responds with a reply. Unless other
+ arrangements are negotiated through service extensions, the sender
+ MUST wait for this response before sending further commands.
+
+ One important reply is the connection greeting. Normally, a receiver
+ will send a 220 "Service ready" reply when the connection is
+ completed. The sender SHOULD wait for this greeting message before
+ sending any commands.
+
+ Note: all the greeting-type replies have the official name (the
+ fully-qualified primary domain name) of the server host as the first
+ word following the reply code. Sometimes the host will have no
+ meaningful name. See 4.1.3 for a discussion of alternatives in these
+ situations.
+
+
+
+
+
+Klensin Standards Track [Page 47]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ For example,
+
+ 220 ISIF.USC.EDU Service ready
+ or
+ 220 mail.foo.com SuperSMTP v 6.1.2 Service ready
+ or
+ 220 [10.0.0.1] Clueless host service ready
+
+ The table below lists alternative success and failure replies for
+ each command. These SHOULD be strictly adhered to: a receiver may
+ substitute text in the replies, but the meaning and action implied by
+ the code numbers and by the specific command reply sequence cannot be
+ altered.
+
+4.3.2 Command-Reply Sequences
+
+ Each command is listed with its usual possible replies. The prefixes
+ used before the possible replies are "I" for intermediate, "S" for
+ success, and "E" for error. Since some servers may generate other
+ replies under special circumstances, and to allow for future
+ extension, SMTP clients SHOULD, when possible, interpret only the
+ first digit of the reply and MUST be prepared to deal with
+ unrecognized reply codes by interpreting the first digit only.
+ Unless extended using the mechanisms described in section 2.2, SMTP
+ servers MUST NOT transmit reply codes to an SMTP client that are
+ other than three digits or that do not start in a digit between 2 and
+ 5 inclusive.
+
+ These sequencing rules and, in principle, the codes themselves, can
+ be extended or modified by SMTP extensions offered by the server and
+ accepted (requested) by the client.
+
+ In addition to the codes listed below, any SMTP command can return
+ any of the following codes if the corresponding unusual circumstances
+ are encountered:
+
+ 500 For the "command line too long" case or if the command name was
+ not recognized. Note that producing a "command not recognized"
+ error in response to the required subset of these commands is a
+ violation of this specification.
+
+ 501 Syntax error in command or arguments. In order to provide for
+ future extensions, commands that are specified in this document as
+ not accepting arguments (DATA, RSET, QUIT) SHOULD return a 501
+ message if arguments are supplied in the absence of EHLO-
+ advertised extensions.
+
+ 421 Service shutting down and closing transmission channel
+
+
+
+Klensin Standards Track [Page 48]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ Specific sequences are:
+
+ CONNECTION ESTABLISHMENT
+ S: 220
+ E: 554
+ EHLO or HELO
+ S: 250
+ E: 504, 550
+ MAIL
+ S: 250
+ E: 552, 451, 452, 550, 553, 503
+ RCPT
+ S: 250, 251 (but see section 3.4 for discussion of 251 and 551)
+ E: 550, 551, 552, 553, 450, 451, 452, 503, 550
+ DATA
+ I: 354 -> data -> S: 250
+ E: 552, 554, 451, 452
+ E: 451, 554, 503
+ RSET
+ S: 250
+ VRFY
+ S: 250, 251, 252
+ E: 550, 551, 553, 502, 504
+ EXPN
+ S: 250, 252
+ E: 550, 500, 502, 504
+ HELP
+ S: 211, 214
+ E: 502, 504
+ NOOP
+ S: 250
+ QUIT
+ S: 221
+
+4.4 Trace Information
+
+ When an SMTP server receives a message for delivery or further
+ processing, it MUST insert trace ("time stamp" or "Received")
+ information at the beginning of the message content, as discussed in
+ section 4.1.1.4.
+
+ This line MUST be structured as follows:
+
+ - The FROM field, which MUST be supplied in an SMTP environment,
+ SHOULD contain both (1) the name of the source host as presented
+ in the EHLO command and (2) an address literal containing the IP
+ address of the source, determined from the TCP connection.
+
+
+
+
+Klensin Standards Track [Page 49]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ - The ID field MAY contain an "@" as suggested in RFC 822, but this
+ is not required.
+
+ - The FOR field MAY contain a list of <path> entries when multiple
+ RCPT commands have been given. This may raise some security
+ issues and is usually not desirable; see section 7.2.
+
+ An Internet mail program MUST NOT change a Received: line that was
+ previously added to the message header. SMTP servers MUST prepend
+ Received lines to messages; they MUST NOT change the order of
+ existing lines or insert Received lines in any other location.
+
+ As the Internet grows, comparability of Received fields is important
+ for detecting problems, especially slow relays. SMTP servers that
+ create Received fields SHOULD use explicit offsets in the dates
+ (e.g., -0800), rather than time zone names of any type. Local time
+ (with an offset) is preferred to UT when feasible. This formulation
+ allows slightly more information about local circumstances to be
+ specified. If UT is needed, the receiver need merely do some simple
+ arithmetic to convert the values. Use of UT loses information about
+ the time zone-location of the server. If it is desired to supply a
+ time zone name, it SHOULD be included in a comment.
+
+ When the delivery SMTP server makes the "final delivery" of a
+ message, it inserts a return-path line at the beginning of the mail
+ data. This use of return-path is required; mail systems MUST support
+ it. The return-path line preserves the information in the <reverse-
+ path> from the MAIL command. Here, final delivery means the message
+ has left the SMTP environment. Normally, this would mean it had been
+ delivered to the destination user or an associated mail drop, but in
+ some cases it may be further processed and transmitted by another
+ mail system.
+
+ It is possible for the mailbox in the return path to be different
+ from the actual sender's mailbox, for example, if error responses are
+ to be delivered to a special error handling mailbox rather than to
+ the message sender. When mailing lists are involved, this
+ arrangement is common and useful as a means of directing errors to
+ the list maintainer rather than the message originator.
+
+ The text above implies that the final mail data will begin with a
+ return path line, followed by one or more time stamp lines. These
+ lines will be followed by the mail data headers and body [32].
+
+ It is sometimes difficult for an SMTP server to determine whether or
+ not it is making final delivery since forwarding or other operations
+ may occur after the message is accepted for delivery. Consequently,
+
+
+
+
+Klensin Standards Track [Page 50]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ any further (forwarding, gateway, or relay) systems MAY remove the
+ return path and rebuild the MAIL command as needed to ensure that
+ exactly one such line appears in a delivered message.
+
+ A message-originating SMTP system SHOULD NOT send a message that
+ already contains a Return-path header. SMTP servers performing a
+ relay function MUST NOT inspect the message data, and especially not
+ to the extent needed to determine if Return-path headers are present.
+ SMTP servers making final delivery MAY remove Return-path headers
+ before adding their own.
+
+ The primary purpose of the Return-path is to designate the address to
+ which messages indicating non-delivery or other mail system failures
+ are to be sent. For this to be unambiguous, exactly one return path
+ SHOULD be present when the message is delivered. Systems using RFC
+ 822 syntax with non-SMTP transports SHOULD designate an unambiguous
+ address, associated with the transport envelope, to which error
+ reports (e.g., non-delivery messages) should be sent.
+
+ Historical note: Text in RFC 822 that appears to contradict the use
+ of the Return-path header (or the envelope reverse path address from
+ the MAIL command) as the destination for error messages is not
+ applicable on the Internet. The reverse path address (as copied into
+ the Return-path) MUST be used as the target of any mail containing
+ delivery error messages.
+
+ In particular:
+
+ - a gateway from SMTP->elsewhere SHOULD insert a return-path header,
+ unless it is known that the "elsewhere" transport also uses
+ Internet domain addresses and maintains the envelope sender
+ address separately.
+
+ - a gateway from elsewhere->SMTP SHOULD delete any return-path
+ header present in the message, and either copy that information to
+ the SMTP envelope or combine it with information present in the
+ envelope of the other transport system to construct the reverse
+ path argument to the MAIL command in the SMTP envelope.
+
+ The server must give special treatment to cases in which the
+ processing following the end of mail data indication is only
+ partially successful. This could happen if, after accepting several
+ recipients and the mail data, the SMTP server finds that the mail
+ data could be successfully delivered to some, but not all, of the
+ recipients. In such cases, the response to the DATA command MUST be
+ an OK reply. However, the SMTP server MUST compose and send an
+ "undeliverable mail" notification message to the originator of the
+ message.
+
+
+
+Klensin Standards Track [Page 51]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ A single notification listing all of the failed recipients or
+ separate notification messages MUST be sent for each failed
+ recipient. For economy of processing by the sender, the former is
+ preferred when possible. All undeliverable mail notification
+ messages are sent using the MAIL command (even if they result from
+ processing the obsolete SEND, SOML, or SAML commands) and use a null
+ return path as discussed in section 3.7.
+
+ The time stamp line and the return path line are formally defined as
+ follows:
+
+Return-path-line = "Return-Path:" FWS Reverse-path <CRLF>
+
+Time-stamp-line = "Received:" FWS Stamp <CRLF>
+
+Stamp = From-domain By-domain Opt-info ";" FWS date-time
+
+ ; where "date-time" is as defined in [32]
+ ; but the "obs-" forms, especially two-digit
+ ; years, are prohibited in SMTP and MUST NOT be used.
+
+From-domain = "FROM" FWS Extended-Domain CFWS
+
+By-domain = "BY" FWS Extended-Domain CFWS
+
+Extended-Domain = Domain /
+ ( Domain FWS "(" TCP-info ")" ) /
+ ( Address-literal FWS "(" TCP-info ")" )
+
+TCP-info = Address-literal / ( Domain FWS Address-literal )
+ ; Information derived by server from TCP connection
+ ; not client EHLO.
+
+Opt-info = [Via] [With] [ID] [For]
+
+Via = "VIA" FWS Link CFWS
+
+With = "WITH" FWS Protocol CFWS
+
+ID = "ID" FWS String / msg-id CFWS
+
+For = "FOR" FWS 1*( Path / Mailbox ) CFWS
+
+Link = "TCP" / Addtl-Link
+Addtl-Link = Atom
+ ; Additional standard names for links are registered with the
+ ; Internet Assigned Numbers Authority (IANA). "Via" is
+ ; primarily of value with non-Internet transports. SMTP
+
+
+
+Klensin Standards Track [Page 52]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ ; servers SHOULD NOT use unregistered names.
+Protocol = "ESMTP" / "SMTP" / Attdl-Protocol
+Attdl-Protocol = Atom
+ ; Additional standard names for protocols are registered with the
+ ; Internet Assigned Numbers Authority (IANA). SMTP servers
+ ; SHOULD NOT use unregistered names.
+
+4.5 Additional Implementation Issues
+
+4.5.1 Minimum Implementation
+
+ In order to make SMTP workable, the following minimum implementation
+ is required for all receivers. The following commands MUST be
+ supported to conform to this specification:
+
+ EHLO
+ HELO
+ MAIL
+ RCPT
+ DATA
+ RSET
+ NOOP
+ QUIT
+ VRFY
+
+ Any system that includes an SMTP server supporting mail relaying or
+ delivery MUST support the reserved mailbox "postmaster" as a case-
+ insensitive local name. This postmaster address is not strictly
+ necessary if the server always returns 554 on connection opening (as
+ described in section 3.1). The requirement to accept mail for
+ postmaster implies that RCPT commands which specify a mailbox for
+ postmaster at any of the domains for which the SMTP server provides
+ mail service, as well as the special case of "RCPT TO:<Postmaster>"
+ (with no domain specification), MUST be supported.
+
+ SMTP systems are expected to make every reasonable effort to accept
+ mail directed to Postmaster from any other system on the Internet.
+ In extreme cases --such as to contain a denial of service attack or
+ other breach of security-- an SMTP server may block mail directed to
+ Postmaster. However, such arrangements SHOULD be narrowly tailored
+ so as to avoid blocking messages which are not part of such attacks.
+
+4.5.2 Transparency
+
+ Without some provision for data transparency, the character sequence
+ "<CRLF>.<CRLF>" ends the mail text and cannot be sent by the user.
+ In general, users are not aware of such "forbidden" sequences. To
+
+
+
+
+Klensin Standards Track [Page 53]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ allow all user composed text to be transmitted transparently, the
+ following procedures are used:
+
+ - Before sending a line of mail text, the SMTP client checks the
+ first character of the line. If it is a period, one additional
+ period is inserted at the beginning of the line.
+
+ - When a line of mail text is received by the SMTP server, it checks
+ the line. If the line is composed of a single period, it is
+ treated as the end of mail indicator. If the first character is a
+ period and there are other characters on the line, the first
+ character is deleted.
+
+ The mail data may contain any of the 128 ASCII characters. All
+ characters are to be delivered to the recipient's mailbox, including
+ spaces, vertical and horizontal tabs, and other control characters.
+ If the transmission channel provides an 8-bit byte (octet) data
+ stream, the 7-bit ASCII codes are transmitted right justified in the
+ octets, with the high order bits cleared to zero. See 3.7 for
+ special treatment of these conditions in SMTP systems serving a relay
+ function.
+
+ In some systems it may be necessary to transform the data as it is
+ received and stored. This may be necessary for hosts that use a
+ different character set than ASCII as their local character set, that
+ store data in records rather than strings, or which use special
+ character sequences as delimiters inside mailboxes. If such
+ transformations are necessary, they MUST be reversible, especially if
+ they are applied to mail being relayed.
+
+4.5.3 Sizes and Timeouts
+
+4.5.3.1 Size limits and minimums
+
+ There are several objects that have required minimum/maximum sizes.
+ Every implementation MUST be able to receive objects of at least
+ these sizes. Objects larger than these sizes SHOULD be avoided when
+ possible. However, some Internet mail constructs such as encoded
+ X.400 addresses [16] will often require larger objects: clients MAY
+ attempt to transmit these, but MUST be prepared for a server to
+ reject them if they cannot be handled by it. To the maximum extent
+ possible, implementation techniques which impose no limits on the
+ length of these objects should be used.
+
+ local-part
+ The maximum total length of a user name or other local-part is 64
+ characters.
+
+
+
+
+Klensin Standards Track [Page 54]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ domain
+ The maximum total length of a domain name or number is 255
+ characters.
+
+ path
+ The maximum total length of a reverse-path or forward-path is 256
+ characters (including the punctuation and element separators).
+
+ command line
+ The maximum total length of a command line including the command
+ word and the <CRLF> is 512 characters. SMTP extensions may be
+ used to increase this limit.
+
+ reply line
+ The maximum total length of a reply line including the reply code
+ and the <CRLF> is 512 characters. More information may be
+ conveyed through multiple-line replies.
+
+ text line
+ The maximum total length of a text line including the <CRLF> is
+ 1000 characters (not counting the leading dot duplicated for
+ transparency). This number may be increased by the use of SMTP
+ Service Extensions.
+
+ message content
+ The maximum total length of a message content (including any
+ message headers as well as the message body) MUST BE at least 64K
+ octets. Since the introduction of Internet standards for
+ multimedia mail [12], message lengths on the Internet have grown
+ dramatically, and message size restrictions should be avoided if
+ at all possible. SMTP server systems that must impose
+ restrictions SHOULD implement the "SIZE" service extension [18],
+ and SMTP client systems that will send large messages SHOULD
+ utilize it when possible.
+
+ recipients buffer
+ The minimum total number of recipients that must be buffered is
+ 100 recipients. Rejection of messages (for excessive recipients)
+ with fewer than 100 RCPT commands is a violation of this
+ specification. The general principle that relaying SMTP servers
+ MUST NOT, and delivery SMTP servers SHOULD NOT, perform validation
+ tests on message headers suggests that rejecting a message based
+ on the total number of recipients shown in header fields is to be
+ discouraged. A server which imposes a limit on the number of
+ recipients MUST behave in an orderly fashion, such as to reject
+ additional addresses over its limit rather than silently
+ discarding addresses previously accepted. A client that needs to
+
+
+
+
+Klensin Standards Track [Page 55]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ deliver a message containing over 100 RCPT commands SHOULD be
+ prepared to transmit in 100-recipient "chunks" if the server
+ declines to accept more than 100 recipients in a single message.
+
+ Errors due to exceeding these limits may be reported by using the
+ reply codes. Some examples of reply codes are:
+
+ 500 Line too long.
+ or
+ 501 Path too long
+ or
+ 452 Too many recipients (see below)
+ or
+ 552 Too much mail data.
+
+ RFC 821 [30] incorrectly listed the error where an SMTP server
+ exhausts its implementation limit on the number of RCPT commands
+ ("too many recipients") as having reply code 552. The correct reply
+ code for this condition is 452. Clients SHOULD treat a 552 code in
+ this case as a temporary, rather than permanent, failure so the logic
+ below works.
+
+ When a conforming SMTP server encounters this condition, it has at
+ least 100 successful RCPT commands in its recipients buffer. If the
+ server is able to accept the message, then at least these 100
+ addresses will be removed from the SMTP client's queue. When the
+ client attempts retransmission of those addresses which received 452
+ responses, at least 100 of these will be able to fit in the SMTP
+ server's recipients buffer. Each retransmission attempt which is
+ able to deliver anything will be able to dispose of at least 100 of
+ these recipients.
+
+ If an SMTP server has an implementation limit on the number of RCPT
+ commands and this limit is exhausted, it MUST use a response code of
+ 452 (but the client SHOULD also be prepared for a 552, as noted
+ above). If the server has a configured site-policy limitation on the
+ number of RCPT commands, it MAY instead use a 5XX response code.
+ This would be most appropriate if the policy limitation was intended
+ to apply if the total recipient count for a particular message body
+ were enforced even if that message body was sent in multiple mail
+ transactions.
+
+4.5.3.2 Timeouts
+
+ An SMTP client MUST provide a timeout mechanism. It MUST use per-
+ command timeouts rather than somehow trying to time the entire mail
+ transaction. Timeouts SHOULD be easily reconfigurable, preferably
+ without recompiling the SMTP code. To implement this, a timer is set
+
+
+
+Klensin Standards Track [Page 56]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ for each SMTP command and for each buffer of the data transfer. The
+ latter means that the overall timeout is inherently proportional to
+ the size of the message.
+
+ Based on extensive experience with busy mail-relay hosts, the minimum
+ per-command timeout values SHOULD be as follows:
+
+ Initial 220 Message: 5 minutes
+ An SMTP client process needs to distinguish between a failed TCP
+ connection and a delay in receiving the initial 220 greeting
+ message. Many SMTP servers accept a TCP connection but delay
+ delivery of the 220 message until their system load permits more
+ mail to be processed.
+
+ MAIL Command: 5 minutes
+
+ RCPT Command: 5 minutes
+ A longer timeout is required if processing of mailing lists and
+ aliases is not deferred until after the message was accepted.
+
+ DATA Initiation: 2 minutes
+ This is while awaiting the "354 Start Input" reply to a DATA
+ command.
+
+ Data Block: 3 minutes
+ This is while awaiting the completion of each TCP SEND call
+ transmitting a chunk of data.
+
+ DATA Termination: 10 minutes.
+ This is while awaiting the "250 OK" reply. When the receiver gets
+ the final period terminating the message data, it typically
+ performs processing to deliver the message to a user mailbox. A
+ spurious timeout at this point would be very wasteful and would
+ typically result in delivery of multiple copies of the message,
+ since it has been successfully sent and the server has accepted
+ responsibility for delivery. See section 6.1 for additional
+ discussion.
+
+ An SMTP server SHOULD have a timeout of at least 5 minutes while it
+ is awaiting the next command from the sender.
+
+4.5.4 Retry Strategies
+
+ The common structure of a host SMTP implementation includes user
+ mailboxes, one or more areas for queuing messages in transit, and one
+ or more daemon processes for sending and receiving mail. The exact
+ structure will vary depending on the needs of the users on the host
+
+
+
+
+Klensin Standards Track [Page 57]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ and the number and size of mailing lists supported by the host. We
+ describe several optimizations that have proved helpful, particularly
+ for mailers supporting high traffic levels.
+
+ Any queuing strategy MUST include timeouts on all activities on a
+ per-command basis. A queuing strategy MUST NOT send error messages
+ in response to error messages under any circumstances.
+
+4.5.4.1 Sending Strategy
+
+ The general model for an SMTP client is one or more processes that
+ periodically attempt to transmit outgoing mail. In a typical system,
+ the program that composes a message has some method for requesting
+ immediate attention for a new piece of outgoing mail, while mail that
+ cannot be transmitted immediately MUST be queued and periodically
+ retried by the sender. A mail queue entry will include not only the
+ message itself but also the envelope information.
+
+ The sender MUST delay retrying a particular destination after one
+ attempt has failed. In general, the retry interval SHOULD be at
+ least 30 minutes; however, more sophisticated and variable strategies
+ will be beneficial when the SMTP client can determine the reason for
+ non-delivery.
+
+ Retries continue until the message is transmitted or the sender gives
+ up; the give-up time generally needs to be at least 4-5 days. The
+ parameters to the retry algorithm MUST be configurable.
+
+ A client SHOULD keep a list of hosts it cannot reach and
+ corresponding connection timeouts, rather than just retrying queued
+ mail items.
+
+ Experience suggests that failures are typically transient (the target
+ system or its connection has crashed), favoring a policy of two
+ connection attempts in the first hour the message is in the queue,
+ and then backing off to one every two or three hours.
+
+ The SMTP client can shorten the queuing delay in cooperation with the
+ SMTP server. For example, if mail is received from a particular
+ address, it is likely that mail queued for that host can now be sent.
+ Application of this principle may, in many cases, eliminate the
+ requirement for an explicit "send queues now" function such as ETRN
+ [9].
+
+ The strategy may be further modified as a result of multiple
+ addresses per host (see below) to optimize delivery time vs. resource
+ usage.
+
+
+
+
+Klensin Standards Track [Page 58]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ An SMTP client may have a large queue of messages for each
+ unavailable destination host. If all of these messages were retried
+ in every retry cycle, there would be excessive Internet overhead and
+ the sending system would be blocked for a long period. Note that an
+ SMTP client can generally determine that a delivery attempt has
+ failed only after a timeout of several minutes and even a one-minute
+ timeout per connection will result in a very large delay if retries
+ are repeated for dozens, or even hundreds, of queued messages to the
+ same host.
+
+ At the same time, SMTP clients SHOULD use great care in caching
+ negative responses from servers. In an extreme case, if EHLO is
+ issued multiple times during the same SMTP connection, different
+ answers may be returned by the server. More significantly, 5yz
+ responses to the MAIL command MUST NOT be cached.
+
+ When a mail message is to be delivered to multiple recipients, and
+ the SMTP server to which a copy of the message is to be sent is the
+ same for multiple recipients, then only one copy of the message
+ SHOULD be transmitted. That is, the SMTP client SHOULD use the
+ command sequence: MAIL, RCPT, RCPT,... RCPT, DATA instead of the
+ sequence: MAIL, RCPT, DATA, ..., MAIL, RCPT, DATA. However, if there
+ are very many addresses, a limit on the number of RCPT commands per
+ MAIL command MAY be imposed. Implementation of this efficiency
+ feature is strongly encouraged.
+
+ Similarly, to achieve timely delivery, the SMTP client MAY support
+ multiple concurrent outgoing mail transactions. However, some limit
+ may be appropriate to protect the host from devoting all its
+ resources to mail.
+
+4.5.4.2 Receiving Strategy
+
+ The SMTP server SHOULD attempt to keep a pending listen on the SMTP
+ port at all times. This requires the support of multiple incoming
+ TCP connections for SMTP. Some limit MAY be imposed but servers that
+ cannot handle more than one SMTP transaction at a time are not in
+ conformance with the intent of this specification.
+
+ As discussed above, when the SMTP server receives mail from a
+ particular host address, it could activate its own SMTP queuing
+ mechanisms to retry any mail pending for that host address.
+
+4.5.5 Messages with a null reverse-path
+
+ There are several types of notification messages which are required
+ by existing and proposed standards to be sent with a null reverse
+ path, namely non-delivery notifications as discussed in section 3.7,
+
+
+
+Klensin Standards Track [Page 59]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ other kinds of Delivery Status Notifications (DSNs) [24], and also
+ Message Disposition Notifications (MDNs) [10]. All of these kinds of
+ messages are notifications about a previous message, and they are
+ sent to the reverse-path of the previous mail message. (If the
+ delivery of such a notification message fails, that usually indicates
+ a problem with the mail system of the host to which the notification
+ message is addressed. For this reason, at some hosts the MTA is set
+ up to forward such failed notification messages to someone who is
+ able to fix problems with the mail system, e.g., via the postmaster
+ alias.)
+
+ All other types of messages (i.e., any message which is not required
+ by a standards-track RFC to have a null reverse-path) SHOULD be sent
+ with with a valid, non-null reverse-path.
+
+ Implementors of automated email processors should be careful to make
+ sure that the various kinds of messages with null reverse-path are
+ handled correctly, in particular such systems SHOULD NOT reply to
+ messages with null reverse-path.
+
+5. Address Resolution and Mail Handling
+
+ Once an SMTP client lexically identifies a domain to which mail will
+ be delivered for processing (as described in sections 3.6 and 3.7), a
+ DNS lookup MUST be performed to resolve the domain name [22]. The
+ names are expected to be fully-qualified domain names (FQDNs):
+ mechanisms for inferring FQDNs from partial names or local aliases
+ are outside of this specification and, due to a history of problems,
+ are generally discouraged. The lookup first attempts to locate an MX
+ record associated with the name. If a CNAME record is found instead,
+ the resulting name is processed as if it were the initial name. If
+ no MX records are found, but an A RR is found, the A RR is treated as
+ if it was associated with an implicit MX RR, with a preference of 0,
+ pointing to that host. If one or more MX RRs are found for a given
+ name, SMTP systems MUST NOT utilize any A RRs associated with that
+ name unless they are located using the MX RRs; the "implicit MX" rule
+ above applies only if there are no MX records present. If MX records
+ are present, but none of them are usable, this situation MUST be
+ reported as an error.
+
+ When the lookup succeeds, the mapping can result in a list of
+ alternative delivery addresses rather than a single address, because
+ of multiple MX records, multihoming, or both. To provide reliable
+ mail transmission, the SMTP client MUST be able to try (and retry)
+ each of the relevant addresses in this list in order, until a
+ delivery attempt succeeds. However, there MAY also be a configurable
+ limit on the number of alternate addresses that can be tried. In any
+ case, the SMTP client SHOULD try at least two addresses.
+
+
+
+Klensin Standards Track [Page 60]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ Two types of information is used to rank the host addresses: multiple
+ MX records, and multihomed hosts.
+
+ Multiple MX records contain a preference indication that MUST be used
+ in sorting (see below). Lower numbers are more preferred than higher
+ ones. If there are multiple destinations with the same preference
+ and there is no clear reason to favor one (e.g., by recognition of an
+ easily-reached address), then the sender-SMTP MUST randomize them to
+ spread the load across multiple mail exchangers for a specific
+ organization.
+
+ The destination host (perhaps taken from the preferred MX record) may
+ be multihomed, in which case the domain name resolver will return a
+ list of alternative IP addresses. It is the responsibility of the
+ domain name resolver interface to have ordered this list by
+ decreasing preference if necessary, and SMTP MUST try them in the
+ order presented.
+
+ Although the capability to try multiple alternative addresses is
+ required, specific installations may want to limit or disable the use
+ of alternative addresses. The question of whether a sender should
+ attempt retries using the different addresses of a multihomed host
+ has been controversial. The main argument for using the multiple
+ addresses is that it maximizes the probability of timely delivery,
+ and indeed sometimes the probability of any delivery; the counter-
+ argument is that it may result in unnecessary resource use. Note
+ that resource use is also strongly determined by the sending strategy
+ discussed in section 4.5.4.1.
+
+ If an SMTP server receives a message with a destination for which it
+ is a designated Mail eXchanger, it MAY relay the message (potentially
+ after having rewritten the MAIL FROM and/or RCPT TO addresses), make
+ final delivery of the message, or hand it off using some mechanism
+ outside the SMTP-provided transport environment. Of course, neither
+ of the latter require that the list of MX records be examined
+ further.
+
+ If it determines that it should relay the message without rewriting
+ the address, it MUST sort the MX records to determine candidates for
+ delivery. The records are first ordered by preference, with the
+ lowest-numbered records being most preferred. The relay host MUST
+ then inspect the list for any of the names or addresses by which it
+ might be known in mail transactions. If a matching record is found,
+ all records at that preference level and higher-numbered ones MUST be
+ discarded from consideration. If there are no records left at that
+ point, it is an error condition, and the message MUST be returned as
+ undeliverable. If records do remain, they SHOULD be tried, best
+ preference first, as described above.
+
+
+
+Klensin Standards Track [Page 61]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+6. Problem Detection and Handling
+
+6.1 Reliable Delivery and Replies by Email
+
+ When the receiver-SMTP accepts a piece of mail (by sending a "250 OK"
+ message in response to DATA), it is accepting responsibility for
+ delivering or relaying the message. It must take this responsibility
+ seriously. It MUST NOT lose the message for frivolous reasons, such
+ as because the host later crashes or because of a predictable
+ resource shortage.
+
+ If there is a delivery failure after acceptance of a message, the
+ receiver-SMTP MUST formulate and mail a notification message. This
+ notification MUST be sent using a null ("<>") reverse path in the
+ envelope. The recipient of this notification MUST be the address
+ from the envelope return path (or the Return-Path: line). However,
+ if this address is null ("<>"), the receiver-SMTP MUST NOT send a
+ notification. Obviously, nothing in this section can or should
+ prohibit local decisions (i.e., as part of the same system
+ environment as the receiver-SMTP) to log or otherwise transmit
+ information about null address events locally if that is desired. If
+ the address is an explicit source route, it MUST be stripped down to
+ its final hop.
+
+ For example, suppose that an error notification must be sent for a
+ message that arrived with:
+
+ MAIL FROM:<@a,@b:user@d>
+
+ The notification message MUST be sent using:
+
+ RCPT TO:<user@d>
+
+ Some delivery failures after the message is accepted by SMTP will be
+ unavoidable. For example, it may be impossible for the receiving
+ SMTP server to validate all the delivery addresses in RCPT command(s)
+ due to a "soft" domain system error, because the target is a mailing
+ list (see earlier discussion of RCPT), or because the server is
+ acting as a relay and has no immediate access to the delivering
+ system.
+
+ To avoid receiving duplicate messages as the result of timeouts, a
+ receiver-SMTP MUST seek to minimize the time required to respond to
+ the final <CRLF>.<CRLF> end of data indicator. See RFC 1047 [28] for
+ a discussion of this problem.
+
+
+
+
+
+
+Klensin Standards Track [Page 62]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+6.2 Loop Detection
+
+ Simple counting of the number of "Received:" headers in a message has
+ proven to be an effective, although rarely optimal, method of
+ detecting loops in mail systems. SMTP servers using this technique
+ SHOULD use a large rejection threshold, normally at least 100
+ Received entries. Whatever mechanisms are used, servers MUST contain
+ provisions for detecting and stopping trivial loops.
+
+6.3 Compensating for Irregularities
+
+ Unfortunately, variations, creative interpretations, and outright
+ violations of Internet mail protocols do occur; some would suggest
+ that they occur quite frequently. The debate as to whether a well-
+ behaved SMTP receiver or relay should reject a malformed message,
+ attempt to pass it on unchanged, or attempt to repair it to increase
+ the odds of successful delivery (or subsequent reply) began almost
+ with the dawn of structured network mail and shows no signs of
+ abating. Advocates of rejection claim that attempted repairs are
+ rarely completely adequate and that rejection of bad messages is the
+ only way to get the offending software repaired. Advocates of
+ "repair" or "deliver no matter what" argue that users prefer that
+ mail go through it if at all possible and that there are significant
+ market pressures in that direction. In practice, these market
+ pressures may be more important to particular vendors than strict
+ conformance to the standards, regardless of the preference of the
+ actual developers.
+
+ The problems associated with ill-formed messages were exacerbated by
+ the introduction of the split-UA mail reading protocols [3, 26, 5,
+ 21]. These protocols have encouraged the use of SMTP as a posting
+ protocol, and SMTP servers as relay systems for these client hosts
+ (which are often only intermittently connected to the Internet).
+ Historically, many of those client machines lacked some of the
+ mechanisms and information assumed by SMTP (and indeed, by the mail
+ format protocol [7]). Some could not keep adequate track of time;
+ others had no concept of time zones; still others could not identify
+ their own names or addresses; and, of course, none could satisfy the
+ assumptions that underlay RFC 822's conception of authenticated
+ addresses.
+
+ In response to these weak SMTP clients, many SMTP systems now
+ complete messages that are delivered to them in incomplete or
+ incorrect form. This strategy is generally considered appropriate
+ when the server can identify or authenticate the client, and there
+ are prior agreements between them. By contrast, there is at best
+ great concern about fixes applied by a relay or delivery SMTP server
+ that has little or no knowledge of the user or client machine.
+
+
+
+Klensin Standards Track [Page 63]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ The following changes to a message being processed MAY be applied
+ when necessary by an originating SMTP server, or one used as the
+ target of SMTP as an initial posting protocol:
+
+ - Addition of a message-id field when none appears
+
+ - Addition of a date, time or time zone when none appears
+
+ - Correction of addresses to proper FQDN format
+
+ The less information the server has about the client, the less likely
+ these changes are to be correct and the more caution and conservatism
+ should be applied when considering whether or not to perform fixes
+ and how. These changes MUST NOT be applied by an SMTP server that
+ provides an intermediate relay function.
+
+ In all cases, properly-operating clients supplying correct
+ information are preferred to corrections by the SMTP server. In all
+ cases, documentation of actions performed by the servers (in trace
+ fields and/or header comments) is strongly encouraged.
+
+7. Security Considerations
+
+7.1 Mail Security and Spoofing
+
+ SMTP mail is inherently insecure in that it is feasible for even
+ fairly casual users to negotiate directly with receiving and relaying
+ SMTP servers and create messages that will trick a naive recipient
+ into believing that they came from somewhere else. Constructing such
+ a message so that the "spoofed" behavior cannot be detected by an
+ expert is somewhat more difficult, but not sufficiently so as to be a
+ deterrent to someone who is determined and knowledgeable.
+ Consequently, as knowledge of Internet mail increases, so does the
+ knowledge that SMTP mail inherently cannot be authenticated, or
+ integrity checks provided, at the transport level. Real mail
+ security lies only in end-to-end methods involving the message
+ bodies, such as those which use digital signatures (see [14] and,
+ e.g., PGP [4] or S/MIME [31]).
+
+ Various protocol extensions and configuration options that provide
+ authentication at the transport level (e.g., from an SMTP client to
+ an SMTP server) improve somewhat on the traditional situation
+ described above. However, unless they are accompanied by careful
+ handoffs of responsibility in a carefully-designed trust environment,
+ they remain inherently weaker than end-to-end mechanisms which use
+ digitally signed messages rather than depending on the integrity of
+ the transport system.
+
+
+
+
+Klensin Standards Track [Page 64]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ Efforts to make it more difficult for users to set envelope return
+ path and header "From" fields to point to valid addresses other than
+ their own are largely misguided: they frustrate legitimate
+ applications in which mail is sent by one user on behalf of another
+ or in which error (or normal) replies should be directed to a special
+ address. (Systems that provide convenient ways for users to alter
+ these fields on a per-message basis should attempt to establish a
+ primary and permanent mailbox address for the user so that Sender
+ fields within the message data can be generated sensibly.)
+
+ This specification does not further address the authentication issues
+ associated with SMTP other than to advocate that useful functionality
+ not be disabled in the hope of providing some small margin of
+ protection against an ignorant user who is trying to fake mail.
+
+7.2 "Blind" Copies
+
+ Addresses that do not appear in the message headers may appear in the
+ RCPT commands to an SMTP server for a number of reasons. The two
+ most common involve the use of a mailing address as a "list exploder"
+ (a single address that resolves into multiple addresses) and the
+ appearance of "blind copies". Especially when more than one RCPT
+ command is present, and in order to avoid defeating some of the
+ purpose of these mechanisms, SMTP clients and servers SHOULD NOT copy
+ the full set of RCPT command arguments into the headers, either as
+ part of trace headers or as informational or private-extension
+ headers. Since this rule is often violated in practice, and cannot
+ be enforced, sending SMTP systems that are aware of "bcc" use MAY
+ find it helpful to send each blind copy as a separate message
+ transaction containing only a single RCPT command.
+
+ There is no inherent relationship between either "reverse" (from
+ MAIL, SAML, etc., commands) or "forward" (RCPT) addresses in the SMTP
+ transaction ("envelope") and the addresses in the headers. Receiving
+ systems SHOULD NOT attempt to deduce such relationships and use them
+ to alter the headers of the message for delivery. The popular
+ "Apparently-to" header is a violation of this principle as well as a
+ common source of unintended information disclosure and SHOULD NOT be
+ used.
+
+7.3 VRFY, EXPN, and Security
+
+ As discussed in section 3.5, individual sites may want to disable
+ either or both of VRFY or EXPN for security reasons. As a corollary
+ to the above, implementations that permit this MUST NOT appear to
+ have verified addresses that are not, in fact, verified. If a site
+
+
+
+
+
+Klensin Standards Track [Page 65]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ disables these commands for security reasons, the SMTP server MUST
+ return a 252 response, rather than a code that could be confused with
+ successful or unsuccessful verification.
+
+ Returning a 250 reply code with the address listed in the VRFY
+ command after having checked it only for syntax violates this rule.
+ Of course, an implementation that "supports" VRFY by always returning
+ 550 whether or not the address is valid is equally not in
+ conformance.
+
+ Within the last few years, the contents of mailing lists have become
+ popular as an address information source for so-called "spammers."
+ The use of EXPN to "harvest" addresses has increased as list
+ administrators have installed protections against inappropriate uses
+ of the lists themselves. Implementations SHOULD still provide
+ support for EXPN, but sites SHOULD carefully evaluate the tradeoffs.
+ As authentication mechanisms are introduced into SMTP, some sites may
+ choose to make EXPN available only to authenticated requestors.
+
+7.4 Information Disclosure in Announcements
+
+ There has been an ongoing debate about the tradeoffs between the
+ debugging advantages of announcing server type and version (and,
+ sometimes, even server domain name) in the greeting response or in
+ response to the HELP command and the disadvantages of exposing
+ information that might be useful in a potential hostile attack. The
+ utility of the debugging information is beyond doubt. Those who
+ argue for making it available point out that it is far better to
+ actually secure an SMTP server rather than hope that trying to
+ conceal known vulnerabilities by hiding the server's precise identity
+ will provide more protection. Sites are encouraged to evaluate the
+ tradeoff with that issue in mind; implementations are strongly
+ encouraged to minimally provide for making type and version
+ information available in some way to other network hosts.
+
+7.5 Information Disclosure in Trace Fields
+
+ In some circumstances, such as when mail originates from within a LAN
+ whose hosts are not directly on the public Internet, trace
+ ("Received") fields produced in conformance with this specification
+ may disclose host names and similar information that would not
+ normally be available. This ordinarily does not pose a problem, but
+ sites with special concerns about name disclosure should be aware of
+ it. Also, the optional FOR clause should be supplied with caution or
+ not at all when multiple recipients are involved lest it
+ inadvertently disclose the identities of "blind copy" recipients to
+ others.
+
+
+
+
+Klensin Standards Track [Page 66]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+7.6 Information Disclosure in Message Forwarding
+
+ As discussed in section 3.4, use of the 251 or 551 reply codes to
+ identify the replacement address associated with a mailbox may
+ inadvertently disclose sensitive information. Sites that are
+ concerned about those issues should ensure that they select and
+ configure servers appropriately.
+
+7.7 Scope of Operation of SMTP Servers
+
+ It is a well-established principle that an SMTP server may refuse to
+ accept mail for any operational or technical reason that makes sense
+ to the site providing the server. However, cooperation among sites
+ and installations makes the Internet possible. If sites take
+ excessive advantage of the right to reject traffic, the ubiquity of
+ email availability (one of the strengths of the Internet) will be
+ threatened; considerable care should be taken and balance maintained
+ if a site decides to be selective about the traffic it will accept
+ and process.
+
+ In recent years, use of the relay function through arbitrary sites
+ has been used as part of hostile efforts to hide the actual origins
+ of mail. Some sites have decided to limit the use of the relay
+ function to known or identifiable sources, and implementations SHOULD
+ provide the capability to perform this type of filtering. When mail
+ is rejected for these or other policy reasons, a 550 code SHOULD be
+ used in response to EHLO, MAIL, or RCPT as appropriate.
+
+8. IANA Considerations
+
+ IANA will maintain three registries in support of this specification.
+ The first consists of SMTP service extensions with the associated
+ keywords, and, as needed, parameters and verbs. As specified in
+ section 2.2.2, no entry may be made in this registry that starts in
+ an "X". Entries may be made only for service extensions (and
+ associated keywords, parameters, or verbs) that are defined in
+ standards-track or experimental RFCs specifically approved by the
+ IESG for this purpose.
+
+ The second registry consists of "tags" that identify forms of domain
+ literals other than those for IPv4 addresses (specified in RFC 821
+ and in this document) and IPv6 addresses (specified in this
+ document). Additional literal types require standardization before
+ being used; none are anticipated at this time.
+
+ The third, established by RFC 821 and renewed by this specification,
+ is a registry of link and protocol identifiers to be used with the
+ "via" and "with" subclauses of the time stamp ("Received: header")
+
+
+
+Klensin Standards Track [Page 67]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ described in section 4.4. Link and protocol identifiers in addition
+ to those specified in this document may be registered only by
+ standardization or by way of an RFC-documented, IESG-approved,
+ Experimental protocol extension.
+
+9. References
+
+ [1] American National Standards Institute (formerly United States of
+ America Standards Institute), X3.4, 1968, "USA Code for
+ Information Interchange". ANSI X3.4-1968 has been replaced by
+ newer versions with slight modifications, but the 1968 version
+ remains definitive for the Internet.
+
+ [2] Braden, R., "Requirements for Internet hosts - application and
+ support", STD 3, RFC 1123, October 1989.
+
+ [3] Butler, M., Chase, D., Goldberger, J., Postel, J. and J.
+ Reynolds, "Post Office Protocol - version 2", RFC 937, February
+ 1985.
+
+ [4] Callas, J., Donnerhacke, L., Finney, H. and R. Thayer, "OpenPGP
+ Message Format", RFC 2440, November 1998.
+
+ [5] Crispin, M., "Interactive Mail Access Protocol - Version 2", RFC
+ 1176, August 1990.
+
+ [6] Crispin, M., "Internet Message Access Protocol - Version 4", RFC
+ 2060, December 1996.
+
+ [7] Crocker, D., "Standard for the Format of ARPA Internet Text
+ Messages", RFC 822, August 1982.
+
+ [8] Crocker, D. and P. Overell, Eds., "Augmented BNF for Syntax
+ Specifications: ABNF", RFC 2234, November 1997.
+
+ [9] De Winter, J., "SMTP Service Extension for Remote Message Queue
+ Starting", RFC 1985, August 1996.
+
+ [10] Fajman, R., "An Extensible Message Format for Message
+ Disposition Notifications", RFC 2298, March 1998.
+
+ [11] Freed, N, "Behavior of and Requirements for Internet Firewalls",
+ RFC 2979, October 2000.
+
+ [12] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part One: Format of Internet Message Bodies",
+ RFC 2045, December 1996.
+
+
+
+
+Klensin Standards Track [Page 68]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ [13] Freed, N., "SMTP Service Extension for Command Pipelining", RFC
+ 2920, September 2000.
+
+ [14] Galvin, J., Murphy, S., Crocker, S. and N. Freed, "Security
+ Multiparts for MIME: Multipart/Signed and Multipart/Encrypted",
+ RFC 1847, October 1995.
+
+ [15] Gellens, R. and J. Klensin, "Message Submission", RFC 2476,
+ December 1998.
+
+ [16] Kille, S., "Mapping between X.400 and RFC822/MIME", RFC 2156,
+ January 1998.
+
+ [17] Hinden, R and S. Deering, Eds. "IP Version 6 Addressing
+ Architecture", RFC 2373, July 1998.
+
+ [18] Klensin, J., Freed, N. and K. Moore, "SMTP Service Extension for
+ Message Size Declaration", STD 10, RFC 1870, November 1995.
+
+ [19] Klensin, J., Freed, N., Rose, M., Stefferud, E. and D. Crocker,
+ "SMTP Service Extensions", STD 10, RFC 1869, November 1995.
+
+ [20] Klensin, J., Freed, N., Rose, M., Stefferud, E. and D. Crocker,
+ "SMTP Service Extension for 8bit-MIMEtransport", RFC 1652, July
+ 1994.
+
+ [21] Lambert, M., "PCMAIL: A distributed mail system for personal
+ computers", RFC 1056, July 1988.
+
+ [22] Mockapetris, P., "Domain names - implementation and
+ specification", STD 13, RFC 1035, November 1987.
+
+ Mockapetris, P., "Domain names - concepts and facilities", STD
+ 13, RFC 1034, November 1987.
+
+ [23] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part
+ Three: Message Header Extensions for Non-ASCII Text", RFC 2047,
+ December 1996.
+
+ [24] Moore, K., "SMTP Service Extension for Delivery Status
+ Notifications", RFC 1891, January 1996.
+
+ [25] Moore, K., and G. Vaudreuil, "An Extensible Message Format for
+ Delivery Status Notifications", RFC 1894, January 1996.
+
+ [26] Myers, J. and M. Rose, "Post Office Protocol - Version 3", STD
+ 53, RFC 1939, May 1996.
+
+
+
+
+Klensin Standards Track [Page 69]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ [27] Partridge, C., "Mail routing and the domain system", RFC 974,
+ January 1986.
+
+ [28] Partridge, C., "Duplicate messages and SMTP", RFC 1047, February
+ 1988.
+
+ [29] Postel, J., ed., "Transmission Control Protocol - DARPA Internet
+ Program Protocol Specification", STD 7, RFC 793, September 1981.
+
+ [30] Postel, J., "Simple Mail Transfer Protocol", RFC 821, August
+ 1982.
+
+ [31] Ramsdell, B., Ed., "S/MIME Version 3 Message Specification", RFC
+ 2633, June 1999.
+
+ [32] Resnick, P., Ed., "Internet Message Format", RFC 2822, April
+ 2001.
+
+ [33] Vaudreuil, G., "SMTP Service Extensions for Transmission of
+ Large and Binary MIME Messages", RFC 1830, August 1995.
+
+ [34] Vaudreuil, G., "Enhanced Mail System Status Codes", RFC 1893,
+ January 1996.
+
+10. Editor's Address
+
+ John C. Klensin
+ AT&T Laboratories
+ 99 Bedford St
+ Boston, MA 02111 USA
+
+ Phone: 617-574-3076
+ EMail: klensin@research.att.com
+
+11. Acknowledgments
+
+ Many people worked long and hard on the many iterations of this
+ document. There was wide-ranging debate in the IETF DRUMS Working
+ Group, both on its mailing list and in face to face discussions,
+ about many technical issues and the role of a revised standard for
+ Internet mail transport, and many contributors helped form the
+ wording in this specification. The hundreds of participants in the
+ many discussions since RFC 821 was produced are too numerous to
+ mention, but they all helped this document become what it is.
+
+
+
+
+
+
+
+Klensin Standards Track [Page 70]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+APPENDICES
+
+A. TCP Transport Service
+
+ The TCP connection supports the transmission of 8-bit bytes. The
+ SMTP data is 7-bit ASCII characters. Each character is transmitted
+ as an 8-bit byte with the high-order bit cleared to zero. Service
+ extensions may modify this rule to permit transmission of full 8-bit
+ data bytes as part of the message body, but not in SMTP commands or
+ responses.
+
+B. Generating SMTP Commands from RFC 822 Headers
+
+ Some systems use RFC 822 headers (only) in a mail submission
+ protocol, or otherwise generate SMTP commands from RFC 822 headers
+ when such a message is handed to an MTA from a UA. While the MTA-UA
+ protocol is a private matter, not covered by any Internet Standard,
+ there are problems with this approach. For example, there have been
+ repeated problems with proper handling of "bcc" copies and
+ redistribution lists when information that conceptually belongs to a
+ mail envelopes is not separated early in processing from header
+ information (and kept separate).
+
+ It is recommended that the UA provide its initial ("submission
+ client") MTA with an envelope separate from the message itself.
+ However, if the envelope is not supplied, SMTP commands SHOULD be
+ generated as follows:
+
+ 1. Each recipient address from a TO, CC, or BCC header field SHOULD
+ be copied to a RCPT command (generating multiple message copies if
+ that is required for queuing or delivery). This includes any
+ addresses listed in a RFC 822 "group". Any BCC fields SHOULD then
+ be removed from the headers. Once this process is completed, the
+ remaining headers SHOULD be checked to verify that at least one
+ To:, Cc:, or Bcc: header remains. If none do, then a bcc: header
+ with no additional information SHOULD be inserted as specified in
+ [32].
+
+ 2. The return address in the MAIL command SHOULD, if possible, be
+ derived from the system's identity for the submitting (local)
+ user, and the "From:" header field otherwise. If there is a
+ system identity available, it SHOULD also be copied to the Sender
+ header field if it is different from the address in the From
+ header field. (Any Sender field that was already there SHOULD be
+ removed.) Systems may provide a way for submitters to override
+ the envelope return address, but may want to restrict its use to
+ privileged users. This will not prevent mail forgery, but may
+ lessen its incidence; see section 7.1.
+
+
+
+Klensin Standards Track [Page 71]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ When an MTA is being used in this way, it bears responsibility for
+ ensuring that the message being transmitted is valid. The mechanisms
+ for checking that validity, and for handling (or returning) messages
+ that are not valid at the time of arrival, are part of the MUA-MTA
+ interface and not covered by this specification.
+
+ A submission protocol based on Standard RFC 822 information alone
+ MUST NOT be used to gateway a message from a foreign (non-SMTP) mail
+ system into an SMTP environment. Additional information to construct
+ an envelope must come from some source in the other environment,
+ whether supplemental headers or the foreign system's envelope.
+
+ Attempts to gateway messages using only their header "to" and "cc"
+ fields have repeatedly caused mail loops and other behavior adverse
+ to the proper functioning of the Internet mail environment. These
+ problems have been especially common when the message originates from
+ an Internet mailing list and is distributed into the foreign
+ environment using envelope information. When these messages are then
+ processed by a header-only remailer, loops back to the Internet
+ environment (and the mailing list) are almost inevitable.
+
+C. Source Routes
+
+ Historically, the <reverse-path> was a reverse source routing list of
+ hosts and a source mailbox. The first host in the <reverse-path>
+ SHOULD be the host sending the MAIL command. Similarly, the
+ <forward-path> may be a source routing lists of hosts and a
+ destination mailbox. However, in general, the <forward-path> SHOULD
+ contain only a mailbox and domain name, relying on the domain name
+ system to supply routing information if required. The use of source
+ routes is deprecated; while servers MUST be prepared to receive and
+ handle them as discussed in section 3.3 and F.2, clients SHOULD NOT
+ transmit them and this section was included only to provide context.
+
+ For relay purposes, the forward-path may be a source route of the
+ form "@ONE,@TWO:JOE@THREE", where ONE, TWO, and THREE MUST BE fully-
+ qualified domain names. This form is used to emphasize the
+ distinction between an address and a route. The mailbox is an
+ absolute address, and the route is information about how to get
+ there. The two concepts should not be confused.
+
+ If source routes are used, RFC 821 and the text below should be
+ consulted for the mechanisms for constructing and updating the
+ forward- and reverse-paths.
+
+
+
+
+
+
+
+Klensin Standards Track [Page 72]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ The SMTP server transforms the command arguments by moving its own
+ identifier (its domain name or that of any domain for which it is
+ acting as a mail exchanger), if it appears, from the forward-path to
+ the beginning of the reverse-path.
+
+ Notice that the forward-path and reverse-path appear in the SMTP
+ commands and replies, but not necessarily in the message. That is,
+ there is no need for these paths and especially this syntax to appear
+ in the "To:" , "From:", "CC:", etc. fields of the message header.
+ Conversely, SMTP servers MUST NOT derive final message delivery
+ information from message header fields.
+
+ When the list of hosts is present, it is a "reverse" source route and
+ indicates that the mail was relayed through each host on the list
+ (the first host in the list was the most recent relay). This list is
+ used as a source route to return non-delivery notices to the sender.
+ As each relay host adds itself to the beginning of the list, it MUST
+ use its name as known in the transport environment to which it is
+ relaying the mail rather than that of the transport environment from
+ which the mail came (if they are different).
+
+D. Scenarios
+
+ This section presents complete scenarios of several types of SMTP
+ sessions. In the examples, "C:" indicates what is said by the SMTP
+ client, and "S:" indicates what is said by the SMTP server.
+
+D.1 A Typical SMTP Transaction Scenario
+
+ This SMTP example shows mail sent by Smith at host bar.com, to Jones,
+ Green, and Brown at host foo.com. Here we assume that host bar.com
+ contacts host foo.com directly. The mail is accepted for Jones and
+ Brown. Green does not have a mailbox at host foo.com.
+
+ S: 220 foo.com Simple Mail Transfer Service Ready
+ C: EHLO bar.com
+ S: 250-foo.com greets bar.com
+ S: 250-8BITMIME
+ S: 250-SIZE
+ S: 250-DSN
+ S: 250 HELP
+ C: MAIL FROM:<Smith@bar.com>
+ S: 250 OK
+ C: RCPT TO:<Jones@foo.com>
+ S: 250 OK
+ C: RCPT TO:<Green@foo.com>
+ S: 550 No such user here
+ C: RCPT TO:<Brown@foo.com>
+
+
+
+Klensin Standards Track [Page 73]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ S: 250 OK
+ C: DATA
+ S: 354 Start mail input; end with <CRLF>.<CRLF>
+ C: Blah blah blah...
+ C: ...etc. etc. etc.
+ C: .
+ S: 250 OK
+ C: QUIT
+ S: 221 foo.com Service closing transmission channel
+
+D.2 Aborted SMTP Transaction Scenario
+
+ S: 220 foo.com Simple Mail Transfer Service Ready
+ C: EHLO bar.com
+ S: 250-foo.com greets bar.com
+ S: 250-8BITMIME
+ S: 250-SIZE
+ S: 250-DSN
+ S: 250 HELP
+ C: MAIL FROM:<Smith@bar.com>
+ S: 250 OK
+ C: RCPT TO:<Jones@foo.com>
+ S: 250 OK
+ C: RCPT TO:<Green@foo.com>
+ S: 550 No such user here
+ C: RSET
+ S: 250 OK
+ C: QUIT
+ S: 221 foo.com Service closing transmission channel
+
+D.3 Relayed Mail Scenario
+
+ Step 1 -- Source Host to Relay Host
+
+ S: 220 foo.com Simple Mail Transfer Service Ready
+ C: EHLO bar.com
+ S: 250-foo.com greets bar.com
+ S: 250-8BITMIME
+ S: 250-SIZE
+ S: 250-DSN
+ S: 250 HELP
+ C: MAIL FROM:<JQP@bar.com>
+ S: 250 OK
+ C: RCPT TO:<@foo.com:Jones@XYZ.COM>
+ S: 250 OK
+ C: DATA
+ S: 354 Start mail input; end with <CRLF>.<CRLF>
+ C: Date: Thu, 21 May 1998 05:33:29 -0700
+
+
+
+Klensin Standards Track [Page 74]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ C: From: John Q. Public <JQP@bar.com>
+ C: Subject: The Next Meeting of the Board
+ C: To: Jones@xyz.com
+ C:
+ C: Bill:
+ C: The next meeting of the board of directors will be
+ C: on Tuesday.
+ C: John.
+ C: .
+ S: 250 OK
+ C: QUIT
+ S: 221 foo.com Service closing transmission channel
+
+ Step 2 -- Relay Host to Destination Host
+
+ S: 220 xyz.com Simple Mail Transfer Service Ready
+ C: EHLO foo.com
+ S: 250 xyz.com is on the air
+ C: MAIL FROM:<@foo.com:JQP@bar.com>
+ S: 250 OK
+ C: RCPT TO:<Jones@XYZ.COM>
+ S: 250 OK
+ C: DATA
+ S: 354 Start mail input; end with <CRLF>.<CRLF>
+ C: Received: from bar.com by foo.com ; Thu, 21 May 1998
+ C: 05:33:29 -0700
+ C: Date: Thu, 21 May 1998 05:33:22 -0700
+ C: From: John Q. Public <JQP@bar.com>
+ C: Subject: The Next Meeting of the Board
+ C: To: Jones@xyz.com
+ C:
+ C: Bill:
+ C: The next meeting of the board of directors will be
+ C: on Tuesday.
+ C: John.
+ C: .
+ S: 250 OK
+ C: QUIT
+ S: 221 foo.com Service closing transmission channel
+
+D.4 Verifying and Sending Scenario
+
+ S: 220 foo.com Simple Mail Transfer Service Ready
+ C: EHLO bar.com
+ S: 250-foo.com greets bar.com
+ S: 250-8BITMIME
+ S: 250-SIZE
+ S: 250-DSN
+
+
+
+Klensin Standards Track [Page 75]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+ S: 250-VRFY
+ S: 250 HELP
+ C: VRFY Crispin
+ S: 250 Mark Crispin <Admin.MRC@foo.com>
+ C: SEND FROM:<EAK@bar.com>
+ S: 250 OK
+ C: RCPT TO:<Admin.MRC@foo.com>
+ S: 250 OK
+ C: DATA
+ S: 354 Start mail input; end with <CRLF>.<CRLF>
+ C: Blah blah blah...
+ C: ...etc. etc. etc.
+ C: .
+ S: 250 OK
+ C: QUIT
+ S: 221 foo.com Service closing transmission channel
+
+E. Other Gateway Issues
+
+ In general, gateways between the Internet and other mail systems
+ SHOULD attempt to preserve any layering semantics across the
+ boundaries between the two mail systems involved. Gateway-
+ translation approaches that attempt to take shortcuts by mapping,
+ (such as envelope information from one system to the message headers
+ or body of another) have generally proven to be inadequate in
+ important ways. Systems translating between environments that do not
+ support both envelopes and headers and Internet mail must be written
+ with the understanding that some information loss is almost
+ inevitable.
+
+F. Deprecated Features of RFC 821
+
+ A few features of RFC 821 have proven to be problematic and SHOULD
+ NOT be used in Internet mail.
+
+F.1 TURN
+
+ This command, described in RFC 821, raises important security issues
+ since, in the absence of strong authentication of the host requesting
+ that the client and server switch roles, it can easily be used to
+ divert mail from its correct destination. Its use is deprecated;
+ SMTP systems SHOULD NOT use it unless the server can authenticate the
+ client.
+
+
+
+
+
+
+
+
+Klensin Standards Track [Page 76]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+F.2 Source Routing
+
+ RFC 821 utilized the concept of explicit source routing to get mail
+ from one host to another via a series of relays. The requirement to
+ utilize source routes in regular mail traffic was eliminated by the
+ introduction of the domain name system "MX" record and the last
+ significant justification for them was eliminated by the
+ introduction, in RFC 1123, of a clear requirement that addresses
+ following an "@" must all be fully-qualified domain names.
+ Consequently, the only remaining justifications for the use of source
+ routes are support for very old SMTP clients or MUAs and in mail
+ system debugging. They can, however, still be useful in the latter
+ circumstance and for routing mail around serious, but temporary,
+ problems such as problems with the relevant DNS records.
+
+ SMTP servers MUST continue to accept source route syntax as specified
+ in the main body of this document and in RFC 1123. They MAY, if
+ necessary, ignore the routes and utilize only the target domain in
+ the address. If they do utilize the source route, the message MUST
+ be sent to the first domain shown in the address. In particular, a
+ server MUST NOT guess at shortcuts within the source route.
+
+ Clients SHOULD NOT utilize explicit source routing except under
+ unusual circumstances, such as debugging or potentially relaying
+ around firewall or mail system configuration errors.
+
+F.3 HELO
+
+ As discussed in sections 3.1 and 4.1.1, EHLO is strongly preferred to
+ HELO when the server will accept the former. Servers must continue
+ to accept and process HELO in order to support older clients.
+
+F.4 #-literals
+
+ RFC 821 provided for specifying an Internet address as a decimal
+ integer host number prefixed by a pound sign, "#". In practice, that
+ form has been obsolete since the introduction of TCP/IP. It is
+ deprecated and MUST NOT be used.
+
+F.5 Dates and Years
+
+ When dates are inserted into messages by SMTP clients or servers
+ (e.g., in trace fields), four-digit years MUST BE used. Two-digit
+ years are deprecated; three-digit years were never permitted in the
+ Internet mail system.
+
+
+
+
+
+
+Klensin Standards Track [Page 77]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+F.6 Sending versus Mailing
+
+ In addition to specifying a mechanism for delivering messages to
+ user's mailboxes, RFC 821 provided additional, optional, commands to
+ deliver messages directly to the user's terminal screen. These
+ commands (SEND, SAML, SOML) were rarely implemented, and changes in
+ workstation technology and the introduction of other protocols may
+ have rendered them obsolete even where they are implemented.
+
+ Clients SHOULD NOT provide SEND, SAML, or SOML as services. Servers
+ MAY implement them. If they are implemented by servers, the
+ implementation model specified in RFC 821 MUST be used and the
+ command names MUST be published in the response to the EHLO command.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Klensin Standards Track [Page 78]
+
+RFC 2821 Simple Mail Transfer Protocol April 2001
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Klensin Standards Track [Page 79]
+
diff --git a/standards/rfc2822.txt b/standards/rfc2822.txt
new file mode 100644
index 000000000..9f698f77d
--- /dev/null
+++ b/standards/rfc2822.txt
@@ -0,0 +1,2859 @@
+
+
+
+
+
+
+Network Working Group P. Resnick, Editor
+Request for Comments: 2822 QUALCOMM Incorporated
+Obsoletes: 822 April 2001
+Category: Standards Track
+
+
+ Internet Message Format
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+Abstract
+
+ This standard specifies a syntax for text messages that are sent
+ between computer users, within the framework of "electronic mail"
+ messages. This standard supersedes the one specified in Request For
+ Comments (RFC) 822, "Standard for the Format of ARPA Internet Text
+ Messages", updating it to reflect current practice and incorporating
+ incremental changes that were specified in other RFCs.
+
+Table of Contents
+
+ 1. Introduction ............................................... 3
+ 1.1. Scope .................................................... 3
+ 1.2. Notational conventions ................................... 4
+ 1.2.1. Requirements notation .................................. 4
+ 1.2.2. Syntactic notation ..................................... 4
+ 1.3. Structure of this document ............................... 4
+ 2. Lexical Analysis of Messages ............................... 5
+ 2.1. General Description ...................................... 5
+ 2.1.1. Line Length Limits ..................................... 6
+ 2.2. Header Fields ............................................ 7
+ 2.2.1. Unstructured Header Field Bodies ....................... 7
+ 2.2.2. Structured Header Field Bodies ......................... 7
+ 2.2.3. Long Header Fields ..................................... 7
+ 2.3. Body ..................................................... 8
+ 3. Syntax ..................................................... 9
+ 3.1. Introduction ............................................. 9
+ 3.2. Lexical Tokens ........................................... 9
+
+
+
+Resnick Standards Track [Page 1]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ 3.2.1. Primitive Tokens ....................................... 9
+ 3.2.2. Quoted characters ......................................10
+ 3.2.3. Folding white space and comments .......................11
+ 3.2.4. Atom ...................................................12
+ 3.2.5. Quoted strings .........................................13
+ 3.2.6. Miscellaneous tokens ...................................13
+ 3.3. Date and Time Specification ..............................14
+ 3.4. Address Specification ....................................15
+ 3.4.1. Addr-spec specification ................................16
+ 3.5 Overall message syntax ....................................17
+ 3.6. Field definitions ........................................18
+ 3.6.1. The origination date field .............................20
+ 3.6.2. Originator fields ......................................21
+ 3.6.3. Destination address fields .............................22
+ 3.6.4. Identification fields ..................................23
+ 3.6.5. Informational fields ...................................26
+ 3.6.6. Resent fields ..........................................26
+ 3.6.7. Trace fields ...........................................28
+ 3.6.8. Optional fields ........................................29
+ 4. Obsolete Syntax ............................................29
+ 4.1. Miscellaneous obsolete tokens ............................30
+ 4.2. Obsolete folding white space .............................31
+ 4.3. Obsolete Date and Time ...................................31
+ 4.4. Obsolete Addressing ......................................33
+ 4.5. Obsolete header fields ...................................33
+ 4.5.1. Obsolete origination date field ........................34
+ 4.5.2. Obsolete originator fields .............................34
+ 4.5.3. Obsolete destination address fields ....................34
+ 4.5.4. Obsolete identification fields .........................35
+ 4.5.5. Obsolete informational fields ..........................35
+ 4.5.6. Obsolete resent fields .................................35
+ 4.5.7. Obsolete trace fields ..................................36
+ 4.5.8. Obsolete optional fields ...............................36
+ 5. Security Considerations ....................................36
+ 6. Bibliography ...............................................37
+ 7. Editor's Address ...........................................38
+ 8. Acknowledgements ...........................................39
+ Appendix A. Example messages ..................................41
+ A.1. Addressing examples ......................................41
+ A.1.1. A message from one person to another with simple
+ addressing .............................................41
+ A.1.2. Different types of mailboxes ...........................42
+ A.1.3. Group addresses ........................................43
+ A.2. Reply messages ...........................................43
+ A.3. Resent messages ..........................................44
+ A.4. Messages with trace fields ...............................46
+ A.5. White space, comments, and other oddities ................47
+ A.6. Obsoleted forms ..........................................47
+
+
+
+Resnick Standards Track [Page 2]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ A.6.1. Obsolete addressing ....................................48
+ A.6.2. Obsolete dates .........................................48
+ A.6.3. Obsolete white space and comments ......................48
+ Appendix B. Differences from earlier standards ................49
+ Appendix C. Notices ...........................................50
+ Full Copyright Statement ......................................51
+
+1. Introduction
+
+1.1. Scope
+
+ This standard specifies a syntax for text messages that are sent
+ between computer users, within the framework of "electronic mail"
+ messages. This standard supersedes the one specified in Request For
+ Comments (RFC) 822, "Standard for the Format of ARPA Internet Text
+ Messages" [RFC822], updating it to reflect current practice and
+ incorporating incremental changes that were specified in other RFCs
+ [STD3].
+
+ This standard specifies a syntax only for text messages. In
+ particular, it makes no provision for the transmission of images,
+ audio, or other sorts of structured data in electronic mail messages.
+ There are several extensions published, such as the MIME document
+ series [RFC2045, RFC2046, RFC2049], which describe mechanisms for the
+ transmission of such data through electronic mail, either by
+ extending the syntax provided here or by structuring such messages to
+ conform to this syntax. Those mechanisms are outside of the scope of
+ this standard.
+
+ In the context of electronic mail, messages are viewed as having an
+ envelope and contents. The envelope contains whatever information is
+ needed to accomplish transmission and delivery. (See [RFC2821] for a
+ discussion of the envelope.) The contents comprise the object to be
+ delivered to the recipient. This standard applies only to the format
+ and some of the semantics of message contents. It contains no
+ specification of the information in the envelope.
+
+ However, some message systems may use information from the contents
+ to create the envelope. It is intended that this standard facilitate
+ the acquisition of such information by programs.
+
+ This specification is intended as a definition of what message
+ content format is to be passed between systems. Though some message
+ systems locally store messages in this format (which eliminates the
+ need for translation between formats) and others use formats that
+ differ from the one specified in this standard, local storage is
+ outside of the scope of this standard.
+
+
+
+
+Resnick Standards Track [Page 3]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ Note: This standard is not intended to dictate the internal formats
+ used by sites, the specific message system features that they are
+ expected to support, or any of the characteristics of user interface
+ programs that create or read messages. In addition, this standard
+ does not specify an encoding of the characters for either transport
+ or storage; that is, it does not specify the number of bits used or
+ how those bits are specifically transferred over the wire or stored
+ on disk.
+
+1.2. Notational conventions
+
+1.2.1. Requirements notation
+
+ This document occasionally uses terms that appear in capital letters.
+ When the terms "MUST", "SHOULD", "RECOMMENDED", "MUST NOT", "SHOULD
+ NOT", and "MAY" appear capitalized, they are being used to indicate
+ particular requirements of this specification. A discussion of the
+ meanings of these terms appears in [RFC2119].
+
+1.2.2. Syntactic notation
+
+ This standard uses the Augmented Backus-Naur Form (ABNF) notation
+ specified in [RFC2234] for the formal definitions of the syntax of
+ messages. Characters will be specified either by a decimal value
+ (e.g., the value %d65 for uppercase A and %d97 for lowercase A) or by
+ a case-insensitive literal value enclosed in quotation marks (e.g.,
+ "A" for either uppercase or lowercase A). See [RFC2234] for the full
+ description of the notation.
+
+1.3. Structure of this document
+
+ This document is divided into several sections.
+
+ This section, section 1, is a short introduction to the document.
+
+ Section 2 lays out the general description of a message and its
+ constituent parts. This is an overview to help the reader understand
+ some of the general principles used in the later portions of this
+ document. Any examples in this section MUST NOT be taken as
+ specification of the formal syntax of any part of a message.
+
+ Section 3 specifies formal ABNF rules for the structure of each part
+ of a message (the syntax) and describes the relationship between
+ those parts and their meaning in the context of a message (the
+ semantics). That is, it describes the actual rules for the structure
+ of each part of a message (the syntax) as well as a description of
+ the parts and instructions on how they ought to be interpreted (the
+ semantics). This includes analysis of the syntax and semantics of
+
+
+
+Resnick Standards Track [Page 4]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ subparts of messages that have specific structure. The syntax
+ included in section 3 represents messages as they MUST be created.
+ There are also notes in section 3 to indicate if any of the options
+ specified in the syntax SHOULD be used over any of the others.
+
+ Both sections 2 and 3 describe messages that are legal to generate
+ for purposes of this standard.
+
+ Section 4 of this document specifies an "obsolete" syntax. There are
+ references in section 3 to these obsolete syntactic elements. The
+ rules of the obsolete syntax are elements that have appeared in
+ earlier revisions of this standard or have previously been widely
+ used in Internet messages. As such, these elements MUST be
+ interpreted by parsers of messages in order to be conformant to this
+ standard. However, since items in this syntax have been determined
+ to be non-interoperable or to cause significant problems for
+ recipients of messages, they MUST NOT be generated by creators of
+ conformant messages.
+
+ Section 5 details security considerations to take into account when
+ implementing this standard.
+
+ Section 6 is a bibliography of references in this document.
+
+ Section 7 contains the editor's address.
+
+ Section 8 contains acknowledgements.
+
+ Appendix A lists examples of different sorts of messages. These
+ examples are not exhaustive of the types of messages that appear on
+ the Internet, but give a broad overview of certain syntactic forms.
+
+ Appendix B lists the differences between this standard and earlier
+ standards for Internet messages.
+
+ Appendix C has copyright and intellectual property notices.
+
+2. Lexical Analysis of Messages
+
+2.1. General Description
+
+ At the most basic level, a message is a series of characters. A
+ message that is conformant with this standard is comprised of
+ characters with values in the range 1 through 127 and interpreted as
+ US-ASCII characters [ASCII]. For brevity, this document sometimes
+ refers to this range of characters as simply "US-ASCII characters".
+
+
+
+
+
+Resnick Standards Track [Page 5]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ Note: This standard specifies that messages are made up of characters
+ in the US-ASCII range of 1 through 127. There are other documents,
+ specifically the MIME document series [RFC2045, RFC2046, RFC2047,
+ RFC2048, RFC2049], that extend this standard to allow for values
+ outside of that range. Discussion of those mechanisms is not within
+ the scope of this standard.
+
+ Messages are divided into lines of characters. A line is a series of
+ characters that is delimited with the two characters carriage-return
+ and line-feed; that is, the carriage return (CR) character (ASCII
+ value 13) followed immediately by the line feed (LF) character (ASCII
+ value 10). (The carriage-return/line-feed pair is usually written in
+ this document as "CRLF".)
+
+ A message consists of header fields (collectively called "the header
+ of the message") followed, optionally, by a body. The header is a
+ sequence of lines of characters with special syntax as defined in
+ this standard. The body is simply a sequence of characters that
+ follows the header and is separated from the header by an empty line
+ (i.e., a line with nothing preceding the CRLF).
+
+2.1.1. Line Length Limits
+
+ There are two limits that this standard places on the number of
+ characters in a line. Each line of characters MUST be no more than
+ 998 characters, and SHOULD be no more than 78 characters, excluding
+ the CRLF.
+
+ The 998 character limit is due to limitations in many implementations
+ which send, receive, or store Internet Message Format messages that
+ simply cannot handle more than 998 characters on a line. Receiving
+ implementations would do well to handle an arbitrarily large number
+ of characters in a line for robustness sake. However, there are so
+ many implementations which (in compliance with the transport
+ requirements of [RFC2821]) do not accept messages containing more
+ than 1000 character including the CR and LF per line, it is important
+ for implementations not to create such messages.
+
+ The more conservative 78 character recommendation is to accommodate
+ the many implementations of user interfaces that display these
+ messages which may truncate, or disastrously wrap, the display of
+ more than 78 characters per line, in spite of the fact that such
+ implementations are non-conformant to the intent of this
+ specification (and that of [RFC2821] if they actually cause
+ information to be lost). Again, even though this limitation is put on
+ messages, it is encumbant upon implementations which display messages
+
+
+
+
+
+Resnick Standards Track [Page 6]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ to handle an arbitrarily large number of characters in a line
+ (certainly at least up to the 998 character limit) for the sake of
+ robustness.
+
+2.2. Header Fields
+
+ Header fields are lines composed of a field name, followed by a colon
+ (":"), followed by a field body, and terminated by CRLF. A field
+ name MUST be composed of printable US-ASCII characters (i.e.,
+ characters that have values between 33 and 126, inclusive), except
+ colon. A field body may be composed of any US-ASCII characters,
+ except for CR and LF. However, a field body may contain CRLF when
+ used in header "folding" and "unfolding" as described in section
+ 2.2.3. All field bodies MUST conform to the syntax described in
+ sections 3 and 4 of this standard.
+
+2.2.1. Unstructured Header Field Bodies
+
+ Some field bodies in this standard are defined simply as
+ "unstructured" (which is specified below as any US-ASCII characters,
+ except for CR and LF) with no further restrictions. These are
+ referred to as unstructured field bodies. Semantically, unstructured
+ field bodies are simply to be treated as a single line of characters
+ with no further processing (except for header "folding" and
+ "unfolding" as described in section 2.2.3).
+
+2.2.2. Structured Header Field Bodies
+
+ Some field bodies in this standard have specific syntactical
+ structure more restrictive than the unstructured field bodies
+ described above. These are referred to as "structured" field bodies.
+ Structured field bodies are sequences of specific lexical tokens as
+ described in sections 3 and 4 of this standard. Many of these tokens
+ are allowed (according to their syntax) to be introduced or end with
+ comments (as described in section 3.2.3) as well as the space (SP,
+ ASCII value 32) and horizontal tab (HTAB, ASCII value 9) characters
+ (together known as the white space characters, WSP), and those WSP
+ characters are subject to header "folding" and "unfolding" as
+ described in section 2.2.3. Semantic analysis of structured field
+ bodies is given along with their syntax.
+
+2.2.3. Long Header Fields
+
+ Each header field is logically a single line of characters comprising
+ the field name, the colon, and the field body. For convenience
+ however, and to deal with the 998/78 character limitations per line,
+ the field body portion of a header field can be split into a multiple
+ line representation; this is called "folding". The general rule is
+
+
+
+Resnick Standards Track [Page 7]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ that wherever this standard allows for folding white space (not
+ simply WSP characters), a CRLF may be inserted before any WSP. For
+ example, the header field:
+
+ Subject: This is a test
+
+ can be represented as:
+
+ Subject: This
+ is a test
+
+ Note: Though structured field bodies are defined in such a way that
+ folding can take place between many of the lexical tokens (and even
+ within some of the lexical tokens), folding SHOULD be limited to
+ placing the CRLF at higher-level syntactic breaks. For instance, if
+ a field body is defined as comma-separated values, it is recommended
+ that folding occur after the comma separating the structured items in
+ preference to other places where the field could be folded, even if
+ it is allowed elsewhere.
+
+ The process of moving from this folded multiple-line representation
+ of a header field to its single line representation is called
+ "unfolding". Unfolding is accomplished by simply removing any CRLF
+ that is immediately followed by WSP. Each header field should be
+ treated in its unfolded form for further syntactic and semantic
+ evaluation.
+
+2.3. Body
+
+ The body of a message is simply lines of US-ASCII characters. The
+ only two limitations on the body are as follows:
+
+ - CR and LF MUST only occur together as CRLF; they MUST NOT appear
+ independently in the body.
+
+ - Lines of characters in the body MUST be limited to 998 characters,
+ and SHOULD be limited to 78 characters, excluding the CRLF.
+
+ Note: As was stated earlier, there are other standards documents,
+ specifically the MIME documents [RFC2045, RFC2046, RFC2048, RFC2049]
+ that extend this standard to allow for different sorts of message
+ bodies. Again, these mechanisms are beyond the scope of this
+ document.
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 8]
+
+RFC 2822 Internet Message Format April 2001
+
+
+3. Syntax
+
+3.1. Introduction
+
+ The syntax as given in this section defines the legal syntax of
+ Internet messages. Messages that are conformant to this standard
+ MUST conform to the syntax in this section. If there are options in
+ this section where one option SHOULD be generated, that is indicated
+ either in the prose or in a comment next to the syntax.
+
+ For the defined expressions, a short description of the syntax and
+ use is given, followed by the syntax in ABNF, followed by a semantic
+ analysis. Primitive tokens that are used but otherwise unspecified
+ come from [RFC2234].
+
+ In some of the definitions, there will be nonterminals whose names
+ start with "obs-". These "obs-" elements refer to tokens defined in
+ the obsolete syntax in section 4. In all cases, these productions
+ are to be ignored for the purposes of generating legal Internet
+ messages and MUST NOT be used as part of such a message. However,
+ when interpreting messages, these tokens MUST be honored as part of
+ the legal syntax. In this sense, section 3 defines a grammar for
+ generation of messages, with "obs-" elements that are to be ignored,
+ while section 4 adds grammar for interpretation of messages.
+
+3.2. Lexical Tokens
+
+ The following rules are used to define an underlying lexical
+ analyzer, which feeds tokens to the higher-level parsers. This
+ section defines the tokens used in structured header field bodies.
+
+ Note: Readers of this standard need to pay special attention to how
+ these lexical tokens are used in both the lower-level and
+ higher-level syntax later in the document. Particularly, the white
+ space tokens and the comment tokens defined in section 3.2.3 get used
+ in the lower-level tokens defined here, and those lower-level tokens
+ are in turn used as parts of the higher-level tokens defined later.
+ Therefore, the white space and comments may be allowed in the
+ higher-level tokens even though they may not explicitly appear in a
+ particular definition.
+
+3.2.1. Primitive Tokens
+
+ The following are primitive tokens referred to elsewhere in this
+ standard, but not otherwise defined in [RFC2234]. Some of them will
+ not appear anywhere else in the syntax, but they are convenient to
+ refer to in other parts of this document.
+
+
+
+
+Resnick Standards Track [Page 9]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ Note: The "specials" below are just such an example. Though the
+ specials token does not appear anywhere else in this standard, it is
+ useful for implementers who use tools that lexically analyze
+ messages. Each of the characters in specials can be used to indicate
+ a tokenization point in lexical analysis.
+
+NO-WS-CTL = %d1-8 / ; US-ASCII control characters
+ %d11 / ; that do not include the
+ %d12 / ; carriage return, line feed,
+ %d14-31 / ; and white space characters
+ %d127
+
+text = %d1-9 / ; Characters excluding CR and LF
+ %d11 /
+ %d12 /
+ %d14-127 /
+ obs-text
+
+specials = "(" / ")" / ; Special characters used in
+ "<" / ">" / ; other parts of the syntax
+ "[" / "]" /
+ ":" / ";" /
+ "@" / "\" /
+ "," / "." /
+ DQUOTE
+
+ No special semantics are attached to these tokens. They are simply
+ single characters.
+
+3.2.2. Quoted characters
+
+ Some characters are reserved for special interpretation, such as
+ delimiting lexical tokens. To permit use of these characters as
+ uninterpreted data, a quoting mechanism is provided.
+
+quoted-pair = ("\" text) / obs-qp
+
+ Where any quoted-pair appears, it is to be interpreted as the text
+ character alone. That is to say, the "\" character that appears as
+ part of a quoted-pair is semantically "invisible".
+
+ Note: The "\" character may appear in a message where it is not part
+ of a quoted-pair. A "\" character that does not appear in a
+ quoted-pair is not semantically invisible. The only places in this
+ standard where quoted-pair currently appears are ccontent, qcontent,
+ dcontent, no-fold-quote, and no-fold-literal.
+
+
+
+
+
+Resnick Standards Track [Page 10]
+
+RFC 2822 Internet Message Format April 2001
+
+
+3.2.3. Folding white space and comments
+
+ White space characters, including white space used in folding
+ (described in section 2.2.3), may appear between many elements in
+ header field bodies. Also, strings of characters that are treated as
+ comments may be included in structured field bodies as characters
+ enclosed in parentheses. The following defines the folding white
+ space (FWS) and comment constructs.
+
+ Strings of characters enclosed in parentheses are considered comments
+ so long as they do not appear within a "quoted-string", as defined in
+ section 3.2.5. Comments may nest.
+
+ There are several places in this standard where comments and FWS may
+ be freely inserted. To accommodate that syntax, an additional token
+ for "CFWS" is defined for places where comments and/or FWS can occur.
+ However, where CFWS occurs in this standard, it MUST NOT be inserted
+ in such a way that any line of a folded header field is made up
+ entirely of WSP characters and nothing else.
+
+FWS = ([*WSP CRLF] 1*WSP) / ; Folding white space
+ obs-FWS
+
+ctext = NO-WS-CTL / ; Non white space controls
+
+ %d33-39 / ; The rest of the US-ASCII
+ %d42-91 / ; characters not including "(",
+ %d93-126 ; ")", or "\"
+
+ccontent = ctext / quoted-pair / comment
+
+comment = "(" *([FWS] ccontent) [FWS] ")"
+
+CFWS = *([FWS] comment) (([FWS] comment) / FWS)
+
+ Throughout this standard, where FWS (the folding white space token)
+ appears, it indicates a place where header folding, as discussed in
+ section 2.2.3, may take place. Wherever header folding appears in a
+ message (that is, a header field body containing a CRLF followed by
+ any WSP), header unfolding (removal of the CRLF) is performed before
+ any further lexical analysis is performed on that header field
+ according to this standard. That is to say, any CRLF that appears in
+ FWS is semantically "invisible."
+
+ A comment is normally used in a structured field body to provide some
+ human readable informational text. Since a comment is allowed to
+ contain FWS, folding is permitted within the comment. Also note that
+ since quoted-pair is allowed in a comment, the parentheses and
+
+
+
+Resnick Standards Track [Page 11]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ backslash characters may appear in a comment so long as they appear
+ as a quoted-pair. Semantically, the enclosing parentheses are not
+ part of the comment; the comment is what is contained between the two
+ parentheses. As stated earlier, the "\" in any quoted-pair and the
+ CRLF in any FWS that appears within the comment are semantically
+ "invisible" and therefore not part of the comment either.
+
+ Runs of FWS, comment or CFWS that occur between lexical tokens in a
+ structured field header are semantically interpreted as a single
+ space character.
+
+3.2.4. Atom
+
+ Several productions in structured header field bodies are simply
+ strings of certain basic characters. Such productions are called
+ atoms.
+
+ Some of the structured header field bodies also allow the period
+ character (".", ASCII value 46) within runs of atext. An additional
+ "dot-atom" token is defined for those purposes.
+
+atext = ALPHA / DIGIT / ; Any character except controls,
+ "!" / "#" / ; SP, and specials.
+ "$" / "%" / ; Used for atoms
+ "&" / "'" /
+ "*" / "+" /
+ "-" / "/" /
+ "=" / "?" /
+ "^" / "_" /
+ "`" / "{" /
+ "|" / "}" /
+ "~"
+
+atom = [CFWS] 1*atext [CFWS]
+
+dot-atom = [CFWS] dot-atom-text [CFWS]
+
+dot-atom-text = 1*atext *("." 1*atext)
+
+ Both atom and dot-atom are interpreted as a single unit, comprised of
+ the string of characters that make it up. Semantically, the optional
+ comments and FWS surrounding the rest of the characters are not part
+ of the atom; the atom is only the run of atext characters in an atom,
+ or the atext and "." characters in a dot-atom.
+
+
+
+
+
+
+
+Resnick Standards Track [Page 12]
+
+RFC 2822 Internet Message Format April 2001
+
+
+3.2.5. Quoted strings
+
+ Strings of characters that include characters other than those
+ allowed in atoms may be represented in a quoted string format, where
+ the characters are surrounded by quote (DQUOTE, ASCII value 34)
+ characters.
+
+qtext = NO-WS-CTL / ; Non white space controls
+
+ %d33 / ; The rest of the US-ASCII
+ %d35-91 / ; characters not including "\"
+ %d93-126 ; or the quote character
+
+qcontent = qtext / quoted-pair
+
+quoted-string = [CFWS]
+ DQUOTE *([FWS] qcontent) [FWS] DQUOTE
+ [CFWS]
+
+ A quoted-string is treated as a unit. That is, quoted-string is
+ identical to atom, semantically. Since a quoted-string is allowed to
+ contain FWS, folding is permitted. Also note that since quoted-pair
+ is allowed in a quoted-string, the quote and backslash characters may
+ appear in a quoted-string so long as they appear as a quoted-pair.
+
+ Semantically, neither the optional CFWS outside of the quote
+ characters nor the quote characters themselves are part of the
+ quoted-string; the quoted-string is what is contained between the two
+ quote characters. As stated earlier, the "\" in any quoted-pair and
+ the CRLF in any FWS/CFWS that appears within the quoted-string are
+ semantically "invisible" and therefore not part of the quoted-string
+ either.
+
+3.2.6. Miscellaneous tokens
+
+ Three additional tokens are defined, word and phrase for combinations
+ of atoms and/or quoted-strings, and unstructured for use in
+ unstructured header fields and in some places within structured
+ header fields.
+
+word = atom / quoted-string
+
+phrase = 1*word / obs-phrase
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 13]
+
+RFC 2822 Internet Message Format April 2001
+
+
+utext = NO-WS-CTL / ; Non white space controls
+ %d33-126 / ; The rest of US-ASCII
+ obs-utext
+
+unstructured = *([FWS] utext) [FWS]
+
+3.3. Date and Time Specification
+
+ Date and time occur in several header fields. This section specifies
+ the syntax for a full date and time specification. Though folding
+ white space is permitted throughout the date-time specification, it
+ is RECOMMENDED that a single space be used in each place that FWS
+ appears (whether it is required or optional); some older
+ implementations may not interpret other occurrences of folding white
+ space correctly.
+
+date-time = [ day-of-week "," ] date FWS time [CFWS]
+
+day-of-week = ([FWS] day-name) / obs-day-of-week
+
+day-name = "Mon" / "Tue" / "Wed" / "Thu" /
+ "Fri" / "Sat" / "Sun"
+
+date = day month year
+
+year = 4*DIGIT / obs-year
+
+month = (FWS month-name FWS) / obs-month
+
+month-name = "Jan" / "Feb" / "Mar" / "Apr" /
+ "May" / "Jun" / "Jul" / "Aug" /
+ "Sep" / "Oct" / "Nov" / "Dec"
+
+day = ([FWS] 1*2DIGIT) / obs-day
+
+time = time-of-day FWS zone
+
+time-of-day = hour ":" minute [ ":" second ]
+
+hour = 2DIGIT / obs-hour
+
+minute = 2DIGIT / obs-minute
+
+second = 2DIGIT / obs-second
+
+zone = (( "+" / "-" ) 4DIGIT) / obs-zone
+
+
+
+
+
+Resnick Standards Track [Page 14]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ The day is the numeric day of the month. The year is any numeric
+ year 1900 or later.
+
+ The time-of-day specifies the number of hours, minutes, and
+ optionally seconds since midnight of the date indicated.
+
+ The date and time-of-day SHOULD express local time.
+
+ The zone specifies the offset from Coordinated Universal Time (UTC,
+ formerly referred to as "Greenwich Mean Time") that the date and
+ time-of-day represent. The "+" or "-" indicates whether the
+ time-of-day is ahead of (i.e., east of) or behind (i.e., west of)
+ Universal Time. The first two digits indicate the number of hours
+ difference from Universal Time, and the last two digits indicate the
+ number of minutes difference from Universal Time. (Hence, +hhmm
+ means +(hh * 60 + mm) minutes, and -hhmm means -(hh * 60 + mm)
+ minutes). The form "+0000" SHOULD be used to indicate a time zone at
+ Universal Time. Though "-0000" also indicates Universal Time, it is
+ used to indicate that the time was generated on a system that may be
+ in a local time zone other than Universal Time and therefore
+ indicates that the date-time contains no information about the local
+ time zone.
+
+ A date-time specification MUST be semantically valid. That is, the
+ day-of-the-week (if included) MUST be the day implied by the date,
+ the numeric day-of-month MUST be between 1 and the number of days
+ allowed for the specified month (in the specified year), the
+ time-of-day MUST be in the range 00:00:00 through 23:59:60 (the
+ number of seconds allowing for a leap second; see [STD12]), and the
+ zone MUST be within the range -9959 through +9959.
+
+3.4. Address Specification
+
+ Addresses occur in several message header fields to indicate senders
+ and recipients of messages. An address may either be an individual
+ mailbox, or a group of mailboxes.
+
+address = mailbox / group
+
+mailbox = name-addr / addr-spec
+
+name-addr = [display-name] angle-addr
+
+angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
+
+group = display-name ":" [mailbox-list / CFWS] ";"
+ [CFWS]
+
+
+
+
+Resnick Standards Track [Page 15]
+
+RFC 2822 Internet Message Format April 2001
+
+
+display-name = phrase
+
+mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list
+
+address-list = (address *("," address)) / obs-addr-list
+
+ A mailbox receives mail. It is a conceptual entity which does not
+ necessarily pertain to file storage. For example, some sites may
+ choose to print mail on a printer and deliver the output to the
+ addressee's desk. Normally, a mailbox is comprised of two parts: (1)
+ an optional display name that indicates the name of the recipient
+ (which could be a person or a system) that could be displayed to the
+ user of a mail application, and (2) an addr-spec address enclosed in
+ angle brackets ("<" and ">"). There is also an alternate simple form
+ of a mailbox where the addr-spec address appears alone, without the
+ recipient's name or the angle brackets. The Internet addr-spec
+ address is described in section 3.4.1.
+
+ Note: Some legacy implementations used the simple form where the
+ addr-spec appears without the angle brackets, but included the name
+ of the recipient in parentheses as a comment following the addr-spec.
+ Since the meaning of the information in a comment is unspecified,
+ implementations SHOULD use the full name-addr form of the mailbox,
+ instead of the legacy form, to specify the display name associated
+ with a mailbox. Also, because some legacy implementations interpret
+ the comment, comments generally SHOULD NOT be used in address fields
+ to avoid confusing such implementations.
+
+ When it is desirable to treat several mailboxes as a single unit
+ (i.e., in a distribution list), the group construct can be used. The
+ group construct allows the sender to indicate a named group of
+ recipients. This is done by giving a display name for the group,
+ followed by a colon, followed by a comma separated list of any number
+ of mailboxes (including zero and one), and ending with a semicolon.
+ Because the list of mailboxes can be empty, using the group construct
+ is also a simple way to communicate to recipients that the message
+ was sent to one or more named sets of recipients, without actually
+ providing the individual mailbox address for each of those
+ recipients.
+
+3.4.1. Addr-spec specification
+
+ An addr-spec is a specific Internet identifier that contains a
+ locally interpreted string followed by the at-sign character ("@",
+ ASCII value 64) followed by an Internet domain. The locally
+ interpreted string is either a quoted-string or a dot-atom. If the
+ string can be represented as a dot-atom (that is, it contains no
+ characters other than atext characters or "." surrounded by atext
+
+
+
+Resnick Standards Track [Page 16]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ characters), then the dot-atom form SHOULD be used and the
+ quoted-string form SHOULD NOT be used. Comments and folding white
+ space SHOULD NOT be used around the "@" in the addr-spec.
+
+addr-spec = local-part "@" domain
+
+local-part = dot-atom / quoted-string / obs-local-part
+
+domain = dot-atom / domain-literal / obs-domain
+
+domain-literal = [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS]
+
+dcontent = dtext / quoted-pair
+
+dtext = NO-WS-CTL / ; Non white space controls
+
+ %d33-90 / ; The rest of the US-ASCII
+ %d94-126 ; characters not including "[",
+ ; "]", or "\"
+
+ The domain portion identifies the point to which the mail is
+ delivered. In the dot-atom form, this is interpreted as an Internet
+ domain name (either a host name or a mail exchanger name) as
+ described in [STD3, STD13, STD14]. In the domain-literal form, the
+ domain is interpreted as the literal Internet address of the
+ particular host. In both cases, how addressing is used and how
+ messages are transported to a particular host is covered in the mail
+ transport document [RFC2821]. These mechanisms are outside of the
+ scope of this document.
+
+ The local-part portion is a domain dependent string. In addresses,
+ it is simply interpreted on the particular host as a name of a
+ particular mailbox.
+
+3.5 Overall message syntax
+
+ A message consists of header fields, optionally followed by a message
+ body. Lines in a message MUST be a maximum of 998 characters
+ excluding the CRLF, but it is RECOMMENDED that lines be limited to 78
+ characters excluding the CRLF. (See section 2.1.1 for explanation.)
+ In a message body, though all of the characters listed in the text
+ rule MAY be used, the use of US-ASCII control characters (values 1
+ through 8, 11, 12, and 14 through 31) is discouraged since their
+ interpretation by receivers for display is not guaranteed.
+
+
+
+
+
+
+
+Resnick Standards Track [Page 17]
+
+RFC 2822 Internet Message Format April 2001
+
+
+message = (fields / obs-fields)
+ [CRLF body]
+
+body = *(*998text CRLF) *998text
+
+ The header fields carry most of the semantic information and are
+ defined in section 3.6. The body is simply a series of lines of text
+ which are uninterpreted for the purposes of this standard.
+
+3.6. Field definitions
+
+ The header fields of a message are defined here. All header fields
+ have the same general syntactic structure: A field name, followed by
+ a colon, followed by the field body. The specific syntax for each
+ header field is defined in the subsequent sections.
+
+ Note: In the ABNF syntax for each field in subsequent sections, each
+ field name is followed by the required colon. However, for brevity
+ sometimes the colon is not referred to in the textual description of
+ the syntax. It is, nonetheless, required.
+
+ It is important to note that the header fields are not guaranteed to
+ be in a particular order. They may appear in any order, and they
+ have been known to be reordered occasionally when transported over
+ the Internet. However, for the purposes of this standard, header
+ fields SHOULD NOT be reordered when a message is transported or
+ transformed. More importantly, the trace header fields and resent
+ header fields MUST NOT be reordered, and SHOULD be kept in blocks
+ prepended to the message. See sections 3.6.6 and 3.6.7 for more
+ information.
+
+ The only required header fields are the origination date field and
+ the originator address field(s). All other header fields are
+ syntactically optional. More information is contained in the table
+ following this definition.
+
+fields = *(trace
+ *(resent-date /
+ resent-from /
+ resent-sender /
+ resent-to /
+ resent-cc /
+ resent-bcc /
+ resent-msg-id))
+ *(orig-date /
+ from /
+ sender /
+ reply-to /
+
+
+
+Resnick Standards Track [Page 18]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ to /
+ cc /
+ bcc /
+ message-id /
+ in-reply-to /
+ references /
+ subject /
+ comments /
+ keywords /
+ optional-field)
+
+ The following table indicates limits on the number of times each
+ field may occur in a message header as well as any special
+ limitations on the use of those fields. An asterisk next to a value
+ in the minimum or maximum column indicates that a special restriction
+ appears in the Notes column.
+
+Field Min number Max number Notes
+
+trace 0 unlimited Block prepended - see
+ 3.6.7
+
+resent-date 0* unlimited* One per block, required
+ if other resent fields
+ present - see 3.6.6
+
+resent-from 0 unlimited* One per block - see
+ 3.6.6
+
+resent-sender 0* unlimited* One per block, MUST
+ occur with multi-address
+ resent-from - see 3.6.6
+
+resent-to 0 unlimited* One per block - see
+ 3.6.6
+
+resent-cc 0 unlimited* One per block - see
+ 3.6.6
+
+resent-bcc 0 unlimited* One per block - see
+ 3.6.6
+
+resent-msg-id 0 unlimited* One per block - see
+ 3.6.6
+
+orig-date 1 1
+
+from 1 1 See sender and 3.6.2
+
+
+
+Resnick Standards Track [Page 19]
+
+RFC 2822 Internet Message Format April 2001
+
+
+sender 0* 1 MUST occur with multi-
+ address from - see 3.6.2
+
+reply-to 0 1
+
+to 0 1
+
+cc 0 1
+
+bcc 0 1
+
+message-id 0* 1 SHOULD be present - see
+ 3.6.4
+
+in-reply-to 0* 1 SHOULD occur in some
+ replies - see 3.6.4
+
+references 0* 1 SHOULD occur in some
+ replies - see 3.6.4
+
+subject 0 1
+
+comments 0 unlimited
+
+keywords 0 unlimited
+
+optional-field 0 unlimited
+
+ The exact interpretation of each field is described in subsequent
+ sections.
+
+3.6.1. The origination date field
+
+ The origination date field consists of the field name "Date" followed
+ by a date-time specification.
+
+orig-date = "Date:" date-time CRLF
+
+ The origination date specifies the date and time at which the creator
+ of the message indicated that the message was complete and ready to
+ enter the mail delivery system. For instance, this might be the time
+ that a user pushes the "send" or "submit" button in an application
+ program. In any case, it is specifically not intended to convey the
+ time that the message is actually transported, but rather the time at
+ which the human or other creator of the message has put the message
+ into its final form, ready for transport. (For example, a portable
+ computer user who is not connected to a network might queue a message
+
+
+
+
+Resnick Standards Track [Page 20]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ for delivery. The origination date is intended to contain the date
+ and time that the user queued the message, not the time when the user
+ connected to the network to send the message.)
+
+3.6.2. Originator fields
+
+ The originator fields of a message consist of the from field, the
+ sender field (when applicable), and optionally the reply-to field.
+ The from field consists of the field name "From" and a
+ comma-separated list of one or more mailbox specifications. If the
+ from field contains more than one mailbox specification in the
+ mailbox-list, then the sender field, containing the field name
+ "Sender" and a single mailbox specification, MUST appear in the
+ message. In either case, an optional reply-to field MAY also be
+ included, which contains the field name "Reply-To" and a
+ comma-separated list of one or more addresses.
+
+from = "From:" mailbox-list CRLF
+
+sender = "Sender:" mailbox CRLF
+
+reply-to = "Reply-To:" address-list CRLF
+
+ The originator fields indicate the mailbox(es) of the source of the
+ message. The "From:" field specifies the author(s) of the message,
+ that is, the mailbox(es) of the person(s) or system(s) responsible
+ for the writing of the message. The "Sender:" field specifies the
+ mailbox of the agent responsible for the actual transmission of the
+ message. For example, if a secretary were to send a message for
+ another person, the mailbox of the secretary would appear in the
+ "Sender:" field and the mailbox of the actual author would appear in
+ the "From:" field. If the originator of the message can be indicated
+ by a single mailbox and the author and transmitter are identical, the
+ "Sender:" field SHOULD NOT be used. Otherwise, both fields SHOULD
+ appear.
+
+ The originator fields also provide the information required when
+ replying to a message. When the "Reply-To:" field is present, it
+ indicates the mailbox(es) to which the author of the message suggests
+ that replies be sent. In the absence of the "Reply-To:" field,
+ replies SHOULD by default be sent to the mailbox(es) specified in the
+ "From:" field unless otherwise specified by the person composing the
+ reply.
+
+ In all cases, the "From:" field SHOULD NOT contain any mailbox that
+ does not belong to the author(s) of the message. See also section
+ 3.6.3 for more information on forming the destination addresses for a
+ reply.
+
+
+
+Resnick Standards Track [Page 21]
+
+RFC 2822 Internet Message Format April 2001
+
+
+3.6.3. Destination address fields
+
+ The destination fields of a message consist of three possible fields,
+ each of the same form: The field name, which is either "To", "Cc", or
+ "Bcc", followed by a comma-separated list of one or more addresses
+ (either mailbox or group syntax).
+
+to = "To:" address-list CRLF
+
+cc = "Cc:" address-list CRLF
+
+bcc = "Bcc:" (address-list / [CFWS]) CRLF
+
+ The destination fields specify the recipients of the message. Each
+ destination field may have one or more addresses, and each of the
+ addresses indicate the intended recipients of the message. The only
+ difference between the three fields is how each is used.
+
+ The "To:" field contains the address(es) of the primary recipient(s)
+ of the message.
+
+ The "Cc:" field (where the "Cc" means "Carbon Copy" in the sense of
+ making a copy on a typewriter using carbon paper) contains the
+ addresses of others who are to receive the message, though the
+ content of the message may not be directed at them.
+
+ The "Bcc:" field (where the "Bcc" means "Blind Carbon Copy") contains
+ addresses of recipients of the message whose addresses are not to be
+ revealed to other recipients of the message. There are three ways in
+ which the "Bcc:" field is used. In the first case, when a message
+ containing a "Bcc:" field is prepared to be sent, the "Bcc:" line is
+ removed even though all of the recipients (including those specified
+ in the "Bcc:" field) are sent a copy of the message. In the second
+ case, recipients specified in the "To:" and "Cc:" lines each are sent
+ a copy of the message with the "Bcc:" line removed as above, but the
+ recipients on the "Bcc:" line get a separate copy of the message
+ containing a "Bcc:" line. (When there are multiple recipient
+ addresses in the "Bcc:" field, some implementations actually send a
+ separate copy of the message to each recipient with a "Bcc:"
+ containing only the address of that particular recipient.) Finally,
+ since a "Bcc:" field may contain no addresses, a "Bcc:" field can be
+ sent without any addresses indicating to the recipients that blind
+ copies were sent to someone. Which method to use with "Bcc:" fields
+ is implementation dependent, but refer to the "Security
+ Considerations" section of this document for a discussion of each.
+
+
+
+
+
+
+Resnick Standards Track [Page 22]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ When a message is a reply to another message, the mailboxes of the
+ authors of the original message (the mailboxes in the "From:" field)
+ or mailboxes specified in the "Reply-To:" field (if it exists) MAY
+ appear in the "To:" field of the reply since these would normally be
+ the primary recipients of the reply. If a reply is sent to a message
+ that has destination fields, it is often desirable to send a copy of
+ the reply to all of the recipients of the message, in addition to the
+ author. When such a reply is formed, addresses in the "To:" and
+ "Cc:" fields of the original message MAY appear in the "Cc:" field of
+ the reply, since these are normally secondary recipients of the
+ reply. If a "Bcc:" field is present in the original message,
+ addresses in that field MAY appear in the "Bcc:" field of the reply,
+ but SHOULD NOT appear in the "To:" or "Cc:" fields.
+
+ Note: Some mail applications have automatic reply commands that
+ include the destination addresses of the original message in the
+ destination addresses of the reply. How those reply commands behave
+ is implementation dependent and is beyond the scope of this document.
+ In particular, whether or not to include the original destination
+ addresses when the original message had a "Reply-To:" field is not
+ addressed here.
+
+3.6.4. Identification fields
+
+ Though optional, every message SHOULD have a "Message-ID:" field.
+ Furthermore, reply messages SHOULD have "In-Reply-To:" and
+ "References:" fields as appropriate, as described below.
+
+ The "Message-ID:" field contains a single unique message identifier.
+ The "References:" and "In-Reply-To:" field each contain one or more
+ unique message identifiers, optionally separated by CFWS.
+
+ The message identifier (msg-id) is similar in syntax to an angle-addr
+ construct without the internal CFWS.
+
+message-id = "Message-ID:" msg-id CRLF
+
+in-reply-to = "In-Reply-To:" 1*msg-id CRLF
+
+references = "References:" 1*msg-id CRLF
+
+msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
+
+id-left = dot-atom-text / no-fold-quote / obs-id-left
+
+id-right = dot-atom-text / no-fold-literal / obs-id-right
+
+no-fold-quote = DQUOTE *(qtext / quoted-pair) DQUOTE
+
+
+
+Resnick Standards Track [Page 23]
+
+RFC 2822 Internet Message Format April 2001
+
+
+no-fold-literal = "[" *(dtext / quoted-pair) "]"
+
+ The "Message-ID:" field provides a unique message identifier that
+ refers to a particular version of a particular message. The
+ uniqueness of the message identifier is guaranteed by the host that
+ generates it (see below). This message identifier is intended to be
+ machine readable and not necessarily meaningful to humans. A message
+ identifier pertains to exactly one instantiation of a particular
+ message; subsequent revisions to the message each receive new message
+ identifiers.
+
+ Note: There are many instances when messages are "changed", but those
+ changes do not constitute a new instantiation of that message, and
+ therefore the message would not get a new message identifier. For
+ example, when messages are introduced into the transport system, they
+ are often prepended with additional header fields such as trace
+ fields (described in section 3.6.7) and resent fields (described in
+ section 3.6.6). The addition of such header fields does not change
+ the identity of the message and therefore the original "Message-ID:"
+ field is retained. In all cases, it is the meaning that the sender
+ of the message wishes to convey (i.e., whether this is the same
+ message or a different message) that determines whether or not the
+ "Message-ID:" field changes, not any particular syntactic difference
+ that appears (or does not appear) in the message.
+
+ The "In-Reply-To:" and "References:" fields are used when creating a
+ reply to a message. They hold the message identifier of the original
+ message and the message identifiers of other messages (for example,
+ in the case of a reply to a message which was itself a reply). The
+ "In-Reply-To:" field may be used to identify the message (or
+ messages) to which the new message is a reply, while the
+ "References:" field may be used to identify a "thread" of
+ conversation.
+
+ When creating a reply to a message, the "In-Reply-To:" and
+ "References:" fields of the resultant message are constructed as
+ follows:
+
+ The "In-Reply-To:" field will contain the contents of the "Message-
+ ID:" field of the message to which this one is a reply (the "parent
+ message"). If there is more than one parent message, then the "In-
+ Reply-To:" field will contain the contents of all of the parents'
+ "Message-ID:" fields. If there is no "Message-ID:" field in any of
+ the parent messages, then the new message will have no "In-Reply-To:"
+ field.
+
+
+
+
+
+
+Resnick Standards Track [Page 24]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ The "References:" field will contain the contents of the parent's
+ "References:" field (if any) followed by the contents of the parent's
+ "Message-ID:" field (if any). If the parent message does not contain
+ a "References:" field but does have an "In-Reply-To:" field
+ containing a single message identifier, then the "References:" field
+ will contain the contents of the parent's "In-Reply-To:" field
+ followed by the contents of the parent's "Message-ID:" field (if
+ any). If the parent has none of the "References:", "In-Reply-To:",
+ or "Message-ID:" fields, then the new message will have no
+ "References:" field.
+
+ Note: Some implementations parse the "References:" field to display
+ the "thread of the discussion". These implementations assume that
+ each new message is a reply to a single parent and hence that they
+ can walk backwards through the "References:" field to find the parent
+ of each message listed there. Therefore, trying to form a
+ "References:" field for a reply that has multiple parents is
+ discouraged and how to do so is not defined in this document.
+
+ The message identifier (msg-id) itself MUST be a globally unique
+ identifier for a message. The generator of the message identifier
+ MUST guarantee that the msg-id is unique. There are several
+ algorithms that can be used to accomplish this. Since the msg-id has
+ a similar syntax to angle-addr (identical except that comments and
+ folding white space are not allowed), a good method is to put the
+ domain name (or a domain literal IP address) of the host on which the
+ message identifier was created on the right hand side of the "@", and
+ put a combination of the current absolute date and time along with
+ some other currently unique (perhaps sequential) identifier available
+ on the system (for example, a process id number) on the left hand
+ side. Using a date on the left hand side and a domain name or domain
+ literal on the right hand side makes it possible to guarantee
+ uniqueness since no two hosts use the same domain name or IP address
+ at the same time. Though other algorithms will work, it is
+ RECOMMENDED that the right hand side contain some domain identifier
+ (either of the host itself or otherwise) such that the generator of
+ the message identifier can guarantee the uniqueness of the left hand
+ side within the scope of that domain.
+
+ Semantically, the angle bracket characters are not part of the
+ msg-id; the msg-id is what is contained between the two angle bracket
+ characters.
+
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 25]
+
+RFC 2822 Internet Message Format April 2001
+
+
+3.6.5. Informational fields
+
+ The informational fields are all optional. The "Keywords:" field
+ contains a comma-separated list of one or more words or
+ quoted-strings. The "Subject:" and "Comments:" fields are
+ unstructured fields as defined in section 2.2.1, and therefore may
+ contain text or folding white space.
+
+subject = "Subject:" unstructured CRLF
+
+comments = "Comments:" unstructured CRLF
+
+keywords = "Keywords:" phrase *("," phrase) CRLF
+
+ These three fields are intended to have only human-readable content
+ with information about the message. The "Subject:" field is the most
+ common and contains a short string identifying the topic of the
+ message. When used in a reply, the field body MAY start with the
+ string "Re: " (from the Latin "res", in the matter of) followed by
+ the contents of the "Subject:" field body of the original message.
+ If this is done, only one instance of the literal string "Re: " ought
+ to be used since use of other strings or more than one instance can
+ lead to undesirable consequences. The "Comments:" field contains any
+ additional comments on the text of the body of the message. The
+ "Keywords:" field contains a comma-separated list of important words
+ and phrases that might be useful for the recipient.
+
+3.6.6. Resent fields
+
+ Resent fields SHOULD be added to any message that is reintroduced by
+ a user into the transport system. A separate set of resent fields
+ SHOULD be added each time this is done. All of the resent fields
+ corresponding to a particular resending of the message SHOULD be
+ together. Each new set of resent fields is prepended to the message;
+ that is, the most recent set of resent fields appear earlier in the
+ message. No other fields in the message are changed when resent
+ fields are added.
+
+ Each of the resent fields corresponds to a particular field elsewhere
+ in the syntax. For instance, the "Resent-Date:" field corresponds to
+ the "Date:" field and the "Resent-To:" field corresponds to the "To:"
+ field. In each case, the syntax for the field body is identical to
+ the syntax given previously for the corresponding field.
+
+ When resent fields are used, the "Resent-From:" and "Resent-Date:"
+ fields MUST be sent. The "Resent-Message-ID:" field SHOULD be sent.
+ "Resent-Sender:" SHOULD NOT be used if "Resent-Sender:" would be
+ identical to "Resent-From:".
+
+
+
+Resnick Standards Track [Page 26]
+
+RFC 2822 Internet Message Format April 2001
+
+
+resent-date = "Resent-Date:" date-time CRLF
+
+resent-from = "Resent-From:" mailbox-list CRLF
+
+resent-sender = "Resent-Sender:" mailbox CRLF
+
+resent-to = "Resent-To:" address-list CRLF
+
+resent-cc = "Resent-Cc:" address-list CRLF
+
+resent-bcc = "Resent-Bcc:" (address-list / [CFWS]) CRLF
+
+resent-msg-id = "Resent-Message-ID:" msg-id CRLF
+
+ Resent fields are used to identify a message as having been
+ reintroduced into the transport system by a user. The purpose of
+ using resent fields is to have the message appear to the final
+ recipient as if it were sent directly by the original sender, with
+ all of the original fields remaining the same. Each set of resent
+ fields correspond to a particular resending event. That is, if a
+ message is resent multiple times, each set of resent fields gives
+ identifying information for each individual time. Resent fields are
+ strictly informational. They MUST NOT be used in the normal
+ processing of replies or other such automatic actions on messages.
+
+ Note: Reintroducing a message into the transport system and using
+ resent fields is a different operation from "forwarding".
+ "Forwarding" has two meanings: One sense of forwarding is that a mail
+ reading program can be told by a user to forward a copy of a message
+ to another person, making the forwarded message the body of the new
+ message. A forwarded message in this sense does not appear to have
+ come from the original sender, but is an entirely new message from
+ the forwarder of the message. On the other hand, forwarding is also
+ used to mean when a mail transport program gets a message and
+ forwards it on to a different destination for final delivery. Resent
+ header fields are not intended for use with either type of
+ forwarding.
+
+ The resent originator fields indicate the mailbox of the person(s) or
+ system(s) that resent the message. As with the regular originator
+ fields, there are two forms: a simple "Resent-From:" form which
+ contains the mailbox of the individual doing the resending, and the
+ more complex form, when one individual (identified in the
+ "Resent-Sender:" field) resends a message on behalf of one or more
+ others (identified in the "Resent-From:" field).
+
+ Note: When replying to a resent message, replies behave just as they
+ would with any other message, using the original "From:",
+
+
+
+Resnick Standards Track [Page 27]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ "Reply-To:", "Message-ID:", and other fields. The resent fields are
+ only informational and MUST NOT be used in the normal processing of
+ replies.
+
+ The "Resent-Date:" indicates the date and time at which the resent
+ message is dispatched by the resender of the message. Like the
+ "Date:" field, it is not the date and time that the message was
+ actually transported.
+
+ The "Resent-To:", "Resent-Cc:", and "Resent-Bcc:" fields function
+ identically to the "To:", "Cc:", and "Bcc:" fields respectively,
+ except that they indicate the recipients of the resent message, not
+ the recipients of the original message.
+
+ The "Resent-Message-ID:" field provides a unique identifier for the
+ resent message.
+
+3.6.7. Trace fields
+
+ The trace fields are a group of header fields consisting of an
+ optional "Return-Path:" field, and one or more "Received:" fields.
+ The "Return-Path:" header field contains a pair of angle brackets
+ that enclose an optional addr-spec. The "Received:" field contains a
+ (possibly empty) list of name/value pairs followed by a semicolon and
+ a date-time specification. The first item of the name/value pair is
+ defined by item-name, and the second item is either an addr-spec, an
+ atom, a domain, or a msg-id. Further restrictions may be applied to
+ the syntax of the trace fields by standards that provide for their
+ use, such as [RFC2821].
+
+trace = [return]
+ 1*received
+
+return = "Return-Path:" path CRLF
+
+path = ([CFWS] "<" ([CFWS] / addr-spec) ">" [CFWS]) /
+ obs-path
+
+received = "Received:" name-val-list ";" date-time CRLF
+
+name-val-list = [CFWS] [name-val-pair *(CFWS name-val-pair)]
+
+name-val-pair = item-name CFWS item-value
+
+item-name = ALPHA *(["-"] (ALPHA / DIGIT))
+
+item-value = 1*angle-addr / addr-spec /
+ atom / domain / msg-id
+
+
+
+Resnick Standards Track [Page 28]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ A full discussion of the Internet mail use of trace fields is
+ contained in [RFC2821]. For the purposes of this standard, the trace
+ fields are strictly informational, and any formal interpretation of
+ them is outside of the scope of this document.
+
+3.6.8. Optional fields
+
+ Fields may appear in messages that are otherwise unspecified in this
+ standard. They MUST conform to the syntax of an optional-field.
+ This is a field name, made up of the printable US-ASCII characters
+ except SP and colon, followed by a colon, followed by any text which
+ conforms to unstructured.
+
+ The field names of any optional-field MUST NOT be identical to any
+ field name specified elsewhere in this standard.
+
+optional-field = field-name ":" unstructured CRLF
+
+field-name = 1*ftext
+
+ftext = %d33-57 / ; Any character except
+ %d59-126 ; controls, SP, and
+ ; ":".
+
+ For the purposes of this standard, any optional field is
+ uninterpreted.
+
+4. Obsolete Syntax
+
+ Earlier versions of this standard allowed for different (usually more
+ liberal) syntax than is allowed in this version. Also, there have
+ been syntactic elements used in messages on the Internet whose
+ interpretation have never been documented. Though some of these
+ syntactic forms MUST NOT be generated according to the grammar in
+ section 3, they MUST be accepted and parsed by a conformant receiver.
+ This section documents many of these syntactic elements. Taking the
+ grammar in section 3 and adding the definitions presented in this
+ section will result in the grammar to use for interpretation of
+ messages.
+
+ Note: This section identifies syntactic forms that any implementation
+ MUST reasonably interpret. However, there are certainly Internet
+ messages which do not conform to even the additional syntax given in
+ this section. The fact that a particular form does not appear in any
+ section of this document is not justification for computer programs
+ to crash or for malformed data to be irretrievably lost by any
+ implementation. To repeat an example, though this document requires
+ lines in messages to be no longer than 998 characters, silently
+
+
+
+Resnick Standards Track [Page 29]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ discarding the 999th and subsequent characters in a line without
+ warning would still be bad behavior for an implementation. It is up
+ to the implementation to deal with messages robustly.
+
+ One important difference between the obsolete (interpreting) and the
+ current (generating) syntax is that in structured header field bodies
+ (i.e., between the colon and the CRLF of any structured header
+ field), white space characters, including folding white space, and
+ comments can be freely inserted between any syntactic tokens. This
+ allows many complex forms that have proven difficult for some
+ implementations to parse.
+
+ Another key difference between the obsolete and the current syntax is
+ that the rule in section 3.2.3 regarding lines composed entirely of
+ white space in comments and folding white space does not apply. See
+ the discussion of folding white space in section 4.2 below.
+
+ Finally, certain characters that were formerly allowed in messages
+ appear in this section. The NUL character (ASCII value 0) was once
+ allowed, but is no longer for compatibility reasons. CR and LF were
+ allowed to appear in messages other than as CRLF; this use is also
+ shown here.
+
+ Other differences in syntax and semantics are noted in the following
+ sections.
+
+4.1. Miscellaneous obsolete tokens
+
+ These syntactic elements are used elsewhere in the obsolete syntax or
+ in the main syntax. The obs-char and obs-qp elements each add ASCII
+ value 0. Bare CR and bare LF are added to obs-text and obs-utext.
+ The period character is added to obs-phrase. The obs-phrase-list
+ provides for "empty" elements in a comma-separated list of phrases.
+
+ Note: The "period" (or "full stop") character (".") in obs-phrase is
+ not a form that was allowed in earlier versions of this or any other
+ standard. Period (nor any other character from specials) was not
+ allowed in phrase because it introduced a parsing difficulty
+ distinguishing between phrases and portions of an addr-spec (see
+ section 4.4). It appears here because the period character is
+ currently used in many messages in the display-name portion of
+ addresses, especially for initials in names, and therefore must be
+ interpreted properly. In the future, period may appear in the
+ regular syntax of phrase.
+
+obs-qp = "\" (%d0-127)
+
+obs-text = *LF *CR *(obs-char *LF *CR)
+
+
+
+Resnick Standards Track [Page 30]
+
+RFC 2822 Internet Message Format April 2001
+
+
+obs-char = %d0-9 / %d11 / ; %d0-127 except CR and
+ %d12 / %d14-127 ; LF
+
+obs-utext = obs-text
+
+obs-phrase = word *(word / "." / CFWS)
+
+obs-phrase-list = phrase / 1*([phrase] [CFWS] "," [CFWS]) [phrase]
+
+ Bare CR and bare LF appear in messages with two different meanings.
+ In many cases, bare CR or bare LF are used improperly instead of CRLF
+ to indicate line separators. In other cases, bare CR and bare LF are
+ used simply as ASCII control characters with their traditional ASCII
+ meanings.
+
+4.2. Obsolete folding white space
+
+ In the obsolete syntax, any amount of folding white space MAY be
+ inserted where the obs-FWS rule is allowed. This creates the
+ possibility of having two consecutive "folds" in a line, and
+ therefore the possibility that a line which makes up a folded header
+ field could be composed entirely of white space.
+
+ obs-FWS = 1*WSP *(CRLF 1*WSP)
+
+4.3. Obsolete Date and Time
+
+ The syntax for the obsolete date format allows a 2 digit year in the
+ date field and allows for a list of alphabetic time zone
+ specifications that were used in earlier versions of this standard.
+ It also permits comments and folding white space between many of the
+ tokens.
+
+obs-day-of-week = [CFWS] day-name [CFWS]
+
+obs-year = [CFWS] 2*DIGIT [CFWS]
+
+obs-month = CFWS month-name CFWS
+
+obs-day = [CFWS] 1*2DIGIT [CFWS]
+
+obs-hour = [CFWS] 2DIGIT [CFWS]
+
+obs-minute = [CFWS] 2DIGIT [CFWS]
+
+obs-second = [CFWS] 2DIGIT [CFWS]
+
+obs-zone = "UT" / "GMT" / ; Universal Time
+
+
+
+Resnick Standards Track [Page 31]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ ; North American UT
+ ; offsets
+ "EST" / "EDT" / ; Eastern: - 5/ - 4
+ "CST" / "CDT" / ; Central: - 6/ - 5
+ "MST" / "MDT" / ; Mountain: - 7/ - 6
+ "PST" / "PDT" / ; Pacific: - 8/ - 7
+
+ %d65-73 / ; Military zones - "A"
+ %d75-90 / ; through "I" and "K"
+ %d97-105 / ; through "Z", both
+ %d107-122 ; upper and lower case
+
+ Where a two or three digit year occurs in a date, the year is to be
+ interpreted as follows: If a two digit year is encountered whose
+ value is between 00 and 49, the year is interpreted by adding 2000,
+ ending up with a value between 2000 and 2049. If a two digit year is
+ encountered with a value between 50 and 99, or any three digit year
+ is encountered, the year is interpreted by adding 1900.
+
+ In the obsolete time zone, "UT" and "GMT" are indications of
+ "Universal Time" and "Greenwich Mean Time" respectively and are both
+ semantically identical to "+0000".
+
+ The remaining three character zones are the US time zones. The first
+ letter, "E", "C", "M", or "P" stands for "Eastern", "Central",
+ "Mountain" and "Pacific". The second letter is either "S" for
+ "Standard" time, or "D" for "Daylight" (or summer) time. Their
+ interpretations are as follows:
+
+ EDT is semantically equivalent to -0400
+ EST is semantically equivalent to -0500
+ CDT is semantically equivalent to -0500
+ CST is semantically equivalent to -0600
+ MDT is semantically equivalent to -0600
+ MST is semantically equivalent to -0700
+ PDT is semantically equivalent to -0700
+ PST is semantically equivalent to -0800
+
+ The 1 character military time zones were defined in a non-standard
+ way in [RFC822] and are therefore unpredictable in their meaning.
+ The original definitions of the military zones "A" through "I" are
+ equivalent to "+0100" through "+0900" respectively; "K", "L", and "M"
+ are equivalent to "+1000", "+1100", and "+1200" respectively; "N"
+ through "Y" are equivalent to "-0100" through "-1200" respectively;
+ and "Z" is equivalent to "+0000". However, because of the error in
+ [RFC822], they SHOULD all be considered equivalent to "-0000" unless
+ there is out-of-band information confirming their meaning.
+
+
+
+
+Resnick Standards Track [Page 32]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ Other multi-character (usually between 3 and 5) alphabetic time zones
+ have been used in Internet messages. Any such time zone whose
+ meaning is not known SHOULD be considered equivalent to "-0000"
+ unless there is out-of-band information confirming their meaning.
+
+4.4. Obsolete Addressing
+
+ There are three primary differences in addressing. First, mailbox
+ addresses were allowed to have a route portion before the addr-spec
+ when enclosed in "<" and ">". The route is simply a comma-separated
+ list of domain names, each preceded by "@", and the list terminated
+ by a colon. Second, CFWS were allowed between the period-separated
+ elements of local-part and domain (i.e., dot-atom was not used). In
+ addition, local-part is allowed to contain quoted-string in addition
+ to just atom. Finally, mailbox-list and address-list were allowed to
+ have "null" members. That is, there could be two or more commas in
+ such a list with nothing in between them.
+
+obs-angle-addr = [CFWS] "<" [obs-route] addr-spec ">" [CFWS]
+
+obs-route = [CFWS] obs-domain-list ":" [CFWS]
+
+obs-domain-list = "@" domain *(*(CFWS / "," ) [CFWS] "@" domain)
+
+obs-local-part = word *("." word)
+
+obs-domain = atom *("." atom)
+
+obs-mbox-list = 1*([mailbox] [CFWS] "," [CFWS]) [mailbox]
+
+obs-addr-list = 1*([address] [CFWS] "," [CFWS]) [address]
+
+ When interpreting addresses, the route portion SHOULD be ignored.
+
+4.5. Obsolete header fields
+
+ Syntactically, the primary difference in the obsolete field syntax is
+ that it allows multiple occurrences of any of the fields and they may
+ occur in any order. Also, any amount of white space is allowed
+ before the ":" at the end of the field name.
+
+obs-fields = *(obs-return /
+ obs-received /
+ obs-orig-date /
+ obs-from /
+ obs-sender /
+ obs-reply-to /
+ obs-to /
+
+
+
+Resnick Standards Track [Page 33]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ obs-cc /
+ obs-bcc /
+ obs-message-id /
+ obs-in-reply-to /
+ obs-references /
+ obs-subject /
+ obs-comments /
+ obs-keywords /
+ obs-resent-date /
+ obs-resent-from /
+ obs-resent-send /
+ obs-resent-rply /
+ obs-resent-to /
+ obs-resent-cc /
+ obs-resent-bcc /
+ obs-resent-mid /
+ obs-optional)
+
+ Except for destination address fields (described in section 4.5.3),
+ the interpretation of multiple occurrences of fields is unspecified.
+ Also, the interpretation of trace fields and resent fields which do
+ not occur in blocks prepended to the message is unspecified as well.
+ Unless otherwise noted in the following sections, interpretation of
+ other fields is identical to the interpretation of their non-obsolete
+ counterparts in section 3.
+
+4.5.1. Obsolete origination date field
+
+obs-orig-date = "Date" *WSP ":" date-time CRLF
+
+4.5.2. Obsolete originator fields
+
+obs-from = "From" *WSP ":" mailbox-list CRLF
+
+obs-sender = "Sender" *WSP ":" mailbox CRLF
+
+obs-reply-to = "Reply-To" *WSP ":" mailbox-list CRLF
+
+4.5.3. Obsolete destination address fields
+
+obs-to = "To" *WSP ":" address-list CRLF
+
+obs-cc = "Cc" *WSP ":" address-list CRLF
+
+obs-bcc = "Bcc" *WSP ":" (address-list / [CFWS]) CRLF
+
+
+
+
+
+
+Resnick Standards Track [Page 34]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ When multiple occurrences of destination address fields occur in a
+ message, they SHOULD be treated as if the address-list in the first
+ occurrence of the field is combined with the address lists of the
+ subsequent occurrences by adding a comma and concatenating.
+
+4.5.4. Obsolete identification fields
+
+ The obsolete "In-Reply-To:" and "References:" fields differ from the
+ current syntax in that they allow phrase (words or quoted strings) to
+ appear. The obsolete forms of the left and right sides of msg-id
+ allow interspersed CFWS, making them syntactically identical to
+ local-part and domain respectively.
+
+obs-message-id = "Message-ID" *WSP ":" msg-id CRLF
+
+obs-in-reply-to = "In-Reply-To" *WSP ":" *(phrase / msg-id) CRLF
+
+obs-references = "References" *WSP ":" *(phrase / msg-id) CRLF
+
+obs-id-left = local-part
+
+obs-id-right = domain
+
+ For purposes of interpretation, the phrases in the "In-Reply-To:" and
+ "References:" fields are ignored.
+
+ Semantically, none of the optional CFWS surrounding the local-part
+ and the domain are part of the obs-id-left and obs-id-right
+ respectively.
+
+4.5.5. Obsolete informational fields
+
+obs-subject = "Subject" *WSP ":" unstructured CRLF
+
+obs-comments = "Comments" *WSP ":" unstructured CRLF
+
+obs-keywords = "Keywords" *WSP ":" obs-phrase-list CRLF
+
+4.5.6. Obsolete resent fields
+
+ The obsolete syntax adds a "Resent-Reply-To:" field, which consists
+ of the field name, the optional comments and folding white space, the
+ colon, and a comma separated list of addresses.
+
+obs-resent-from = "Resent-From" *WSP ":" mailbox-list CRLF
+
+obs-resent-send = "Resent-Sender" *WSP ":" mailbox CRLF
+
+
+
+
+Resnick Standards Track [Page 35]
+
+RFC 2822 Internet Message Format April 2001
+
+
+obs-resent-date = "Resent-Date" *WSP ":" date-time CRLF
+
+obs-resent-to = "Resent-To" *WSP ":" address-list CRLF
+
+obs-resent-cc = "Resent-Cc" *WSP ":" address-list CRLF
+
+obs-resent-bcc = "Resent-Bcc" *WSP ":"
+ (address-list / [CFWS]) CRLF
+
+obs-resent-mid = "Resent-Message-ID" *WSP ":" msg-id CRLF
+
+obs-resent-rply = "Resent-Reply-To" *WSP ":" address-list CRLF
+
+ As with other resent fields, the "Resent-Reply-To:" field is to be
+ treated as trace information only.
+
+4.5.7. Obsolete trace fields
+
+ The obs-return and obs-received are again given here as template
+ definitions, just as return and received are in section 3. Their
+ full syntax is given in [RFC2821].
+
+obs-return = "Return-Path" *WSP ":" path CRLF
+
+obs-received = "Received" *WSP ":" name-val-list CRLF
+
+obs-path = obs-angle-addr
+
+4.5.8. Obsolete optional fields
+
+obs-optional = field-name *WSP ":" unstructured CRLF
+
+5. Security Considerations
+
+ Care needs to be taken when displaying messages on a terminal or
+ terminal emulator. Powerful terminals may act on escape sequences
+ and other combinations of ASCII control characters with a variety of
+ consequences. They can remap the keyboard or permit other
+ modifications to the terminal which could lead to denial of service
+ or even damaged data. They can trigger (sometimes programmable)
+ answerback messages which can allow a message to cause commands to be
+ issued on the recipient's behalf. They can also effect the operation
+ of terminal attached devices such as printers. Message viewers may
+ wish to strip potentially dangerous terminal escape sequences from
+ the message prior to display. However, other escape sequences appear
+ in messages for useful purposes (cf. [RFC2045, RFC2046, RFC2047,
+ RFC2048, RFC2049, ISO2022]) and therefore should not be stripped
+ indiscriminately.
+
+
+
+Resnick Standards Track [Page 36]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ Transmission of non-text objects in messages raises additional
+ security issues. These issues are discussed in [RFC2045, RFC2046,
+ RFC2047, RFC2048, RFC2049].
+
+ Many implementations use the "Bcc:" (blind carbon copy) field
+ described in section 3.6.3 to facilitate sending messages to
+ recipients without revealing the addresses of one or more of the
+ addressees to the other recipients. Mishandling this use of "Bcc:"
+ has implications for confidential information that might be revealed,
+ which could eventually lead to security problems through knowledge of
+ even the existence of a particular mail address. For example, if
+ using the first method described in section 3.6.3, where the "Bcc:"
+ line is removed from the message, blind recipients have no explicit
+ indication that they have been sent a blind copy, except insofar as
+ their address does not appear in the message header. Because of
+ this, one of the blind addressees could potentially send a reply to
+ all of the shown recipients and accidentally reveal that the message
+ went to the blind recipient. When the second method from section
+ 3.6.3 is used, the blind recipient's address appears in the "Bcc:"
+ field of a separate copy of the message. If the "Bcc:" field sent
+ contains all of the blind addressees, all of the "Bcc:" recipients
+ will be seen by each "Bcc:" recipient. Even if a separate message is
+ sent to each "Bcc:" recipient with only the individual's address,
+ implementations still need to be careful to process replies to the
+ message as per section 3.6.3 so as not to accidentally reveal the
+ blind recipient to other recipients.
+
+6. Bibliography
+
+ [ASCII] American National Standards Institute (ANSI), Coded
+ Character Set - 7-Bit American National Standard Code for
+ Information Interchange, ANSI X3.4, 1986.
+
+ [ISO2022] International Organization for Standardization (ISO),
+ Information processing - ISO 7-bit and 8-bit coded
+ character sets - Code extension techniques, Third edition
+ - 1986-05-01, ISO 2022, 1986.
+
+ [RFC822] Crocker, D., "Standard for the Format of ARPA Internet
+ Text Messages", RFC 822, August 1982.
+
+ [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part One: Format of Internet Message
+ Bodies", RFC 2045, November 1996.
+
+ [RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part Two: Media Types", RFC 2046,
+ November 1996.
+
+
+
+Resnick Standards Track [Page 37]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ [RFC2047] Moore, K., "Multipurpose Internet Mail Extensions (MIME)
+ Part Three: Message Header Extensions for Non-ASCII Text",
+ RFC 2047, November 1996.
+
+ [RFC2048] Freed, N., Klensin, J. and J. Postel, "Multipurpose
+ Internet Mail Extensions (MIME) Part Four: Format of
+ Internet Message Bodies", RFC 2048, November 1996.
+
+ [RFC2049] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part Five: Conformance Criteria and
+ Examples", RFC 2049, November 1996.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2234] Crocker, D., Editor, and P. Overell, "Augmented BNF for
+ Syntax Specifications: ABNF", RFC 2234, November 1997.
+
+ [RFC2821] Klensin, J., Editor, "Simple Mail Transfer Protocol", RFC
+ 2821, March 2001.
+
+ [STD3] Braden, R., "Host Requirements", STD 3, RFC 1122 and RFC
+ 1123, October 1989.
+
+ [STD12] Mills, D., "Network Time Protocol", STD 12, RFC 1119,
+ September 1989.
+
+ [STD13] Mockapetris, P., "Domain Name System", STD 13, RFC 1034
+ and RFC 1035, November 1987.
+
+ [STD14] Partridge, C., "Mail Routing and the Domain System", STD
+ 14, RFC 974, January 1986.
+
+7. Editor's Address
+
+ Peter W. Resnick
+ QUALCOMM Incorporated
+ 5775 Morehouse Drive
+ San Diego, CA 92121-1714
+ USA
+
+ Phone: +1 858 651 4478
+ Fax: +1 858 651 1102
+ EMail: presnick@qualcomm.com
+
+
+
+
+
+
+
+Resnick Standards Track [Page 38]
+
+RFC 2822 Internet Message Format April 2001
+
+
+8. Acknowledgements
+
+ Many people contributed to this document. They included folks who
+ participated in the Detailed Revision and Update of Messaging
+ Standards (DRUMS) Working Group of the Internet Engineering Task
+ Force (IETF), the chair of DRUMS, the Area Directors of the IETF, and
+ people who simply sent their comments in via e-mail. The editor is
+ deeply indebted to them all and thanks them sincerely. The below
+ list includes everyone who sent e-mail concerning this document.
+ Hopefully, everyone who contributed is named here:
+
+ Matti Aarnio Barry Finkel Larry Masinter
+ Tanaka Akira Erik Forsberg Denis McKeon
+ Russ Allbery Chuck Foster William P McQuillan
+ Eric Allman Paul Fox Alexey Melnikov
+ Harald Tveit Alvestrand Klaus M. Frank Perry E. Metzger
+ Ran Atkinson Ned Freed Steven Miller
+ Jos Backus Jochen Friedrich Keith Moore
+ Bruce Balden Randall C. Gellens John Gardiner Myers
+ Dave Barr Sukvinder Singh Gill Chris Newman
+ Alan Barrett Tim Goodwin John W. Noerenberg
+ John Beck Philip Guenther Eric Norman
+ J. Robert von Behren Tony Hansen Mike O'Dell
+ Jos den Bekker John Hawkinson Larry Osterman
+ D. J. Bernstein Philip Hazel Paul Overell
+ James Berriman Kai Henningsen Jacob Palme
+ Norbert Bollow Robert Herriot Michael A. Patton
+ Raj Bose Paul Hethmon Uzi Paz
+ Antony Bowesman Jim Hill Michael A. Quinlan
+ Scott Bradner Paul E. Hoffman Eric S. Raymond
+ Randy Bush Steve Hole Sam Roberts
+ Tom Byrer Kari Hurtta Hugh Sasse
+ Bruce Campbell Marco S. Hyman Bart Schaefer
+ Larry Campbell Ofer Inbar Tom Scola
+ W. J. Carpenter Olle Jarnefors Wolfgang Segmuller
+ Michael Chapman Kevin Johnson Nick Shelness
+ Richard Clayton Sudish Joseph John Stanley
+ Maurizio Codogno Maynard Kang Einar Stefferud
+ Jim Conklin Prabhat Keni Jeff Stephenson
+ R. Kelley Cook John C. Klensin Bernard Stern
+ Steve Coya Graham Klyne Peter Sylvester
+ Mark Crispin Brad Knowles Mark Symons
+ Dave Crocker Shuhei Kobayashi Eric Thomas
+ Matt Curtin Peter Koch Lee Thompson
+ Michael D'Errico Dan Kohn Karel De Vriendt
+ Cyrus Daboo Christian Kuhtz Matthew Wall
+ Jutta Degener Anand Kumria Rolf Weber
+ Mark Delany Steen Larsen Brent B. Welch
+
+
+
+Resnick Standards Track [Page 39]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ Steve Dorner Eliot Lear Dan Wing
+ Harold A. Driscoll Barry Leiba Jack De Winter
+ Michael Elkins Jay Levitt Gregory J. Woodhouse
+ Robert Elz Lars-Johan Liman Greg A. Woods
+ Johnny Eriksson Charles Lindsey Kazu Yamamoto
+ Erik E. Fair Pete Loshin Alain Zahm
+ Roger Fajman Simon Lyall Jamie Zawinski
+ Patrik Faltstrom Bill Manning Timothy S. Zurcher
+ Claus Andre Farber John Martin
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 40]
+
+RFC 2822 Internet Message Format April 2001
+
+
+Appendix A. Example messages
+
+ This section presents a selection of messages. These are intended to
+ assist in the implementation of this standard, but should not be
+ taken as normative; that is to say, although the examples in this
+ section were carefully reviewed, if there happens to be a conflict
+ between these examples and the syntax described in sections 3 and 4
+ of this document, the syntax in those sections is to be taken as
+ correct.
+
+ Messages are delimited in this section between lines of "----". The
+ "----" lines are not part of the message itself.
+
+A.1. Addressing examples
+
+ The following are examples of messages that might be sent between two
+ individuals.
+
+A.1.1. A message from one person to another with simple addressing
+
+ This could be called a canonical message. It has a single author,
+ John Doe, a single recipient, Mary Smith, a subject, the date, a
+ message identifier, and a textual message in the body.
+
+----
+From: John Doe <jdoe@machine.example>
+To: Mary Smith <mary@example.net>
+Subject: Saying Hello
+Date: Fri, 21 Nov 1997 09:55:06 -0600
+Message-ID: <1234@local.machine.example>
+
+This is a message just to say hello.
+So, "Hello".
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 41]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ If John's secretary Michael actually sent the message, though John
+ was the author and replies to this message should go back to him, the
+ sender field would be used:
+
+----
+From: John Doe <jdoe@machine.example>
+Sender: Michael Jones <mjones@machine.example>
+To: Mary Smith <mary@example.net>
+Subject: Saying Hello
+Date: Fri, 21 Nov 1997 09:55:06 -0600
+Message-ID: <1234@local.machine.example>
+
+This is a message just to say hello.
+So, "Hello".
+----
+
+A.1.2. Different types of mailboxes
+
+ This message includes multiple addresses in the destination fields
+ and also uses several different forms of addresses.
+
+----
+From: "Joe Q. Public" <john.q.public@example.com>
+To: Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>
+Cc: <boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>
+Date: Tue, 1 Jul 2003 10:52:37 +0200
+Message-ID: <5678.21-Nov-1997@example.com>
+
+Hi everyone.
+----
+
+ Note that the display names for Joe Q. Public and Giant; "Big" Box
+ needed to be enclosed in double-quotes because the former contains
+ the period and the latter contains both semicolon and double-quote
+ characters (the double-quote characters appearing as quoted-pair
+ construct). Conversely, the display name for Who? could appear
+ without them because the question mark is legal in an atom. Notice
+ also that jdoe@example.org and boss@nil.test have no display names
+ associated with them at all, and jdoe@example.org uses the simpler
+ address form without the angle brackets.
+
+
+
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 42]
+
+RFC 2822 Internet Message Format April 2001
+
+
+A.1.3. Group addresses
+
+----
+From: Pete <pete@silly.example>
+To: A Group:Chris Jones <c@a.test>,joe@where.test,John <jdoe@one.test>;
+Cc: Undisclosed recipients:;
+Date: Thu, 13 Feb 1969 23:32:54 -0330
+Message-ID: <testabcd.1234@silly.example>
+
+Testing.
+----
+
+ In this message, the "To:" field has a single group recipient named A
+ Group which contains 3 addresses, and a "Cc:" field with an empty
+ group recipient named Undisclosed recipients.
+
+A.2. Reply messages
+
+ The following is a series of three messages that make up a
+ conversation thread between John and Mary. John firsts sends a
+ message to Mary, Mary then replies to John's message, and then John
+ replies to Mary's reply message.
+
+ Note especially the "Message-ID:", "References:", and "In-Reply-To:"
+ fields in each message.
+
+----
+From: John Doe <jdoe@machine.example>
+To: Mary Smith <mary@example.net>
+Subject: Saying Hello
+Date: Fri, 21 Nov 1997 09:55:06 -0600
+Message-ID: <1234@local.machine.example>
+
+This is a message just to say hello.
+So, "Hello".
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 43]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ When sending replies, the Subject field is often retained, though
+ prepended with "Re: " as described in section 3.6.5.
+
+----
+From: Mary Smith <mary@example.net>
+To: John Doe <jdoe@machine.example>
+Reply-To: "Mary Smith: Personal Account" <smith@home.example>
+Subject: Re: Saying Hello
+Date: Fri, 21 Nov 1997 10:01:10 -0600
+Message-ID: <3456@example.net>
+In-Reply-To: <1234@local.machine.example>
+References: <1234@local.machine.example>
+
+This is a reply to your hello.
+----
+
+ Note the "Reply-To:" field in the above message. When John replies
+ to Mary's message above, the reply should go to the address in the
+ "Reply-To:" field instead of the address in the "From:" field.
+
+----
+To: "Mary Smith: Personal Account" <smith@home.example>
+From: John Doe <jdoe@machine.example>
+Subject: Re: Saying Hello
+Date: Fri, 21 Nov 1997 11:00:00 -0600
+Message-ID: <abcd.1234@local.machine.tld>
+In-Reply-To: <3456@example.net>
+References: <1234@local.machine.example> <3456@example.net>
+
+This is a reply to your reply.
+----
+
+A.3. Resent messages
+
+ Start with the message that has been used as an example several
+ times:
+
+----
+From: John Doe <jdoe@machine.example>
+To: Mary Smith <mary@example.net>
+Subject: Saying Hello
+Date: Fri, 21 Nov 1997 09:55:06 -0600
+Message-ID: <1234@local.machine.example>
+
+This is a message just to say hello.
+So, "Hello".
+----
+
+
+
+
+Resnick Standards Track [Page 44]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ Say that Mary, upon receiving this message, wishes to send a copy of
+ the message to Jane such that (a) the message would appear to have
+ come straight from John; (b) if Jane replies to the message, the
+ reply should go back to John; and (c) all of the original
+ information, like the date the message was originally sent to Mary,
+ the message identifier, and the original addressee, is preserved. In
+ this case, resent fields are prepended to the message:
+
+----
+Resent-From: Mary Smith <mary@example.net>
+Resent-To: Jane Brown <j-brown@other.example>
+Resent-Date: Mon, 24 Nov 1997 14:22:01 -0800
+Resent-Message-ID: <78910@example.net>
+From: John Doe <jdoe@machine.example>
+To: Mary Smith <mary@example.net>
+Subject: Saying Hello
+Date: Fri, 21 Nov 1997 09:55:06 -0600
+Message-ID: <1234@local.machine.example>
+
+This is a message just to say hello.
+So, "Hello".
+----
+
+ If Jane, in turn, wished to resend this message to another person,
+ she would prepend her own set of resent header fields to the above
+ and send that.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 45]
+
+RFC 2822 Internet Message Format April 2001
+
+
+A.4. Messages with trace fields
+
+ As messages are sent through the transport system as described in
+ [RFC2821], trace fields are prepended to the message. The following
+ is an example of what those trace fields might look like. Note that
+ there is some folding white space in the first one since these lines
+ can be long.
+
+----
+Received: from x.y.test
+ by example.net
+ via TCP
+ with ESMTP
+ id ABC12345
+ for <mary@example.net>; 21 Nov 1997 10:05:43 -0600
+Received: from machine.example by x.y.test; 21 Nov 1997 10:01:22 -0600
+From: John Doe <jdoe@machine.example>
+To: Mary Smith <mary@example.net>
+Subject: Saying Hello
+Date: Fri, 21 Nov 1997 09:55:06 -0600
+Message-ID: <1234@local.machine.example>
+
+This is a message just to say hello.
+So, "Hello".
+----
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 46]
+
+RFC 2822 Internet Message Format April 2001
+
+
+A.5. White space, comments, and other oddities
+
+ White space, including folding white space, and comments can be
+ inserted between many of the tokens of fields. Taking the example
+ from A.1.3, white space and comments can be inserted into all of the
+ fields.
+
+----
+From: Pete(A wonderful \) chap) <pete(his account)@silly.test(his host)>
+To:A Group(Some people)
+ :Chris Jones <c@(Chris's host.)public.example>,
+ joe@example.org,
+ John <jdoe@one.test> (my dear friend); (the end of the group)
+Cc:(Empty list)(start)Undisclosed recipients :(nobody(that I know)) ;
+Date: Thu,
+ 13
+ Feb
+ 1969
+ 23:32
+ -0330 (Newfoundland Time)
+Message-ID: <testabcd.1234@silly.test>
+
+Testing.
+----
+
+ The above example is aesthetically displeasing, but perfectly legal.
+ Note particularly (1) the comments in the "From:" field (including
+ one that has a ")" character appearing as part of a quoted-pair); (2)
+ the white space absent after the ":" in the "To:" field as well as
+ the comment and folding white space after the group name, the special
+ character (".") in the comment in Chris Jones's address, and the
+ folding white space before and after "joe@example.org,"; (3) the
+ multiple and nested comments in the "Cc:" field as well as the
+ comment immediately following the ":" after "Cc"; (4) the folding
+ white space (but no comments except at the end) and the missing
+ seconds in the time of the date field; and (5) the white space before
+ (but not within) the identifier in the "Message-ID:" field.
+
+A.6. Obsoleted forms
+
+ The following are examples of obsolete (that is, the "MUST NOT
+ generate") syntactic elements described in section 4 of this
+ document.
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 47]
+
+RFC 2822 Internet Message Format April 2001
+
+
+A.6.1. Obsolete addressing
+
+ Note in the below example the lack of quotes around Joe Q. Public,
+ the route that appears in the address for Mary Smith, the two commas
+ that appear in the "To:" field, and the spaces that appear around the
+ "." in the jdoe address.
+
+----
+From: Joe Q. Public <john.q.public@example.com>
+To: Mary Smith <@machine.tld:mary@example.net>, , jdoe@test . example
+Date: Tue, 1 Jul 2003 10:52:37 +0200
+Message-ID: <5678.21-Nov-1997@example.com>
+
+Hi everyone.
+----
+
+A.6.2. Obsolete dates
+
+ The following message uses an obsolete date format, including a non-
+ numeric time zone and a two digit year. Note that although the
+ day-of-week is missing, that is not specific to the obsolete syntax;
+ it is optional in the current syntax as well.
+
+----
+From: John Doe <jdoe@machine.example>
+To: Mary Smith <mary@example.net>
+Subject: Saying Hello
+Date: 21 Nov 97 09:55:06 GMT
+Message-ID: <1234@local.machine.example>
+
+This is a message just to say hello.
+So, "Hello".
+----
+
+A.6.3. Obsolete white space and comments
+
+ White space and comments can appear between many more elements than
+ in the current syntax. Also, folding lines that are made up entirely
+ of white space are legal.
+
+
+
+
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 48]
+
+RFC 2822 Internet Message Format April 2001
+
+
+----
+From : John Doe <jdoe@machine(comment). example>
+To : Mary Smith
+__
+ <mary@example.net>
+Subject : Saying Hello
+Date : Fri, 21 Nov 1997 09(comment): 55 : 06 -0600
+Message-ID : <1234 @ local(blah) .machine .example>
+
+This is a message just to say hello.
+So, "Hello".
+----
+
+ Note especially the second line of the "To:" field. It starts with
+ two space characters. (Note that "__" represent blank spaces.)
+ Therefore, it is considered part of the folding as described in
+ section 4.2. Also, the comments and white space throughout
+ addresses, dates, and message identifiers are all part of the
+ obsolete syntax.
+
+Appendix B. Differences from earlier standards
+
+ This appendix contains a list of changes that have been made in the
+ Internet Message Format from earlier standards, specifically [RFC822]
+ and [STD3]. Items marked with an asterisk (*) below are items which
+ appear in section 4 of this document and therefore can no longer be
+ generated.
+
+ 1. Period allowed in obsolete form of phrase.
+ 2. ABNF moved out of document to [RFC2234].
+ 3. Four or more digits allowed for year.
+ 4. Header field ordering (and lack thereof) made explicit.
+ 5. Encrypted header field removed.
+ 6. Received syntax loosened to allow any token/value pair.
+ 7. Specifically allow and give meaning to "-0000" time zone.
+ 8. Folding white space is not allowed between every token.
+ 9. Requirement for destinations removed.
+ 10. Forwarding and resending redefined.
+ 11. Extension header fields no longer specifically called out.
+ 12. ASCII 0 (null) removed.*
+ 13. Folding continuation lines cannot contain only white space.*
+ 14. Free insertion of comments not allowed in date.*
+ 15. Non-numeric time zones not allowed.*
+ 16. Two digit years not allowed.*
+ 17. Three digit years interpreted, but not allowed for generation.
+ 18. Routes in addresses not allowed.*
+ 19. CFWS within local-parts and domains not allowed.*
+ 20. Empty members of address lists not allowed.*
+
+
+
+Resnick Standards Track [Page 49]
+
+RFC 2822 Internet Message Format April 2001
+
+
+ 21. Folding white space between field name and colon not allowed.*
+ 22. Comments between field name and colon not allowed.
+ 23. Tightened syntax of in-reply-to and references.*
+ 24. CFWS within msg-id not allowed.*
+ 25. Tightened semantics of resent fields as informational only.
+ 26. Resent-Reply-To not allowed.*
+ 27. No multiple occurrences of fields (except resent and received).*
+ 28. Free CR and LF not allowed.*
+ 29. Routes in return path not allowed.*
+ 30. Line length limits specified.
+ 31. Bcc more clearly specified.
+
+Appendix C. Notices
+
+ Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ intellectual property or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; neither does it represent that it
+ has made any effort to identify any such rights. Information on the
+ IETF's procedures with respect to rights in standards-track and
+ standards-related documentation can be found in BCP-11. Copies of
+ claims of rights made available for publication and any assurances of
+ licenses to be made available, or the result of an attempt made to
+ obtain a general license or permission for the use of such
+ proprietary rights by implementors or users of this specification can
+ be obtained from the IETF Secretariat.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 50]
+
+RFC 2822 Internet Message Format April 2001
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2001). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Resnick Standards Track [Page 51]
+
diff --git a/standards/rfc2910.txt b/standards/rfc2910.txt
new file mode 100644
index 000000000..e13631c2a
--- /dev/null
+++ b/standards/rfc2910.txt
@@ -0,0 +1,2579 @@
+
+
+
+
+
+
+Network Working Group R. Herriot, Editor
+Request for Comments: 2910 Xerox Corporation
+Obsoletes: 2565 S. Butler
+Category: Standards Track Hewlett-Packard
+ P. Moore
+ Peerless Systems Networking
+ R. Turner
+ 2wire.com
+ J. Wenn
+ Xerox Corporation
+ September 2000
+
+
+ Internet Printing Protocol/1.1: Encoding and Transport
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+Abstract
+
+ This document is one of a set of documents, which together describe
+ all aspects of a new Internet Printing Protocol (IPP). IPP is an
+ application level protocol that can be used for distributed printing
+ using Internet tools and technologies. This document defines the
+ rules for encoding IPP operations and IPP attributes into a new
+ Internet mime media type called "application/ipp". This document
+ also defines the rules for transporting over Hypertext Transfer
+ Protocol (HTTP) a message body whose Content-Type is
+ "application/ipp". This document defines a new scheme named 'ipp' for
+ identifying IPP printers and jobs.
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 1]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics [RFC2911]
+ Internet Printing Protocol/1.1: Encoding and Transport (this
+ document)
+ Internet Printing Protocol/1.1: Implementer's Guide [ipp-iig]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ The document, "Design Goals for an Internet Printing Protocol", takes
+ a broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.1. A few OPTIONAL operator operations have
+ been added to IPP/1.1.
+
+ The document, "Rationale for the Structure and Model and Protocol for
+ the Internet Printing Protocol", describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specification documents, and gives background and rationale
+ for the IETF working group's major decisions.
+
+ The document, "Internet Printing Protocol/1.1: Model and Semantics",
+ describes a simplified model with abstract objects, their attributes,
+ and their operations that are independent of encoding and transport.
+ It introduces a Printer and a Job object. The Job object optionally
+ supports multiple documents per Job. It also addresses security,
+ internationalization, and directory issues.
+
+ The document "Internet Printing Protocol/1.1: Implementer's Guide",
+ gives advice to implementers of IPP clients and IPP objects.
+
+ The document "Mapping between LPD and IPP Protocols", gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 2]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+Table of Contents
+
+ 1. Introduction ...................................................4
+ 2. Conformance Terminology ........................................4
+ 3. Encoding of the Operation Layer ...............................4
+ 3.1 Picture of the Encoding ...................................6
+ 3.1.1 Request and Response...................................6
+ 3.1.2 Attribute Group........................................6
+ 3.1.3 Attribute..............................................7
+ 3.1.4 Picture of the Encoding of an Attribute-with-one-value.7
+ 3.1.5 Additional-value.......................................8
+ 3.1.6 Alternative Picture of the Encoding of a Request Or a
+ Response...............................................9
+ 3.2 Syntax of Encoding ........................................9
+ 3.3 Attribute-group ..........................................11
+ 3.4 Required Parameters ......................................12
+ 3.4.1 Version-number........................................12
+ 3.4.2 Operation-id..........................................12
+ 3.4.3 Status-code...........................................12
+ 3.4.4 Request-id............................................13
+ 3.5 Tags .....................................................13
+ 3.5.1 Delimiter Tags........................................13
+ 3.5.2 Value Tags............................................14
+ 3.6 Name-Length ..............................................16
+ 3.7 (Attribute) Name .........................................16
+ 3.8 Value Length .............................................16
+ 3.9 (Attribute) Value ........................................17
+ 3.10 Data .....................................................18
+ 4. Encoding of Transport Layer ...................................18
+ 4.1 Printer-uri and job-uri ..................................19
+ 5. IPP URL Scheme ................................................20
+ 6. IANA Considerations ...........................................22
+ 7. Internationalization Considerations ...........................23
+ 8. Security Considerations .......................................23
+ 8.1 Security Conformance Requirements ........................23
+ 8.1.1 Digest Authentication.................................23
+ 8.1.2 Transport Layer Security (TLS)........................24
+ 8.2 Using IPP with TLS .......................................25
+ 9. Interoperability with IPP/1.0 Implementations .................25
+ 9.1 The "version-number" Parameter ...........................25
+ 9.2 Security and URL Schemes .................................26
+ 10. References ...................................................27
+ 11. Authors' Addresses ...........................................29
+ 12. Other Participants: ..........................................31
+ 13. Appendix A: Protocol Examples ................................33
+ 13.1 Print-Job Request ........................................33
+ 13.2 Print-Job Response (successful) ..........................34
+ 13.3 Print-Job Response (failure) .............................35
+
+
+
+Herriot, et al. Standards Track [Page 3]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ 13.4 Print-Job Response (success with attributes ignored) .....36
+ 13.5 Print-URI Request ........................................38
+ 13.6 Create-Job Request .......................................39
+ 13.7 Get-Jobs Request .........................................40
+ 13.8 Get-Jobs Response ........................................41
+ 14. Appendix B: Registration of MIME Media Type Information for
+ "application/ipp".............................................42
+ 15. Appendix C: Changes from IPP/1.0 .............................44
+ 16. Full Copyright Statement .....................................45
+
+1. Introduction
+
+ This document contains the rules for encoding IPP operations and
+ describes two layers: the transport layer and the operation layer.
+
+ The transport layer consists of an HTTP/1.1 request or response. RFC
+ 2616 [RFC2616] describes HTTP/1.1. This document specifies the HTTP
+ headers that an IPP implementation supports.
+
+ The operation layer consists of a message body in an HTTP request or
+ response. The document "Internet Printing Protocol/1.1: Model and
+ Semantics" [RFC2911] defines the semantics of such a message body and
+ the supported values. This document specifies the encoding of an IPP
+ operation. The aforementioned document [RFC2911] is henceforth
+ referred to as the "IPP model document" or simply "model document".
+
+ Note: the version number of IPP (1.1) and HTTP (1.1) are not linked.
+ They both just happen to be 1.1.
+
+2. Conformance Terminology
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
+ "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
+ interpreted as described in RFC 2119 [RFC2119].
+
+3. Encoding of the Operation Layer
+
+ The operation layer is the message body part of the HTTP request or
+ response and it MUST contain a single IPP operation request or IPP
+ operation response. Each request or response consists of a sequence
+ of values and attribute groups. Attribute groups consist of a
+ sequence of attributes each of which is a name and value. Names and
+ values are ultimately sequences of octets.
+
+ The encoding consists of octets as the most primitive type. There are
+ several types built from octets, but three important types are
+ integers, character strings and octet strings, on which most other
+ data types are built. Every character string in this encoding MUST be
+
+
+
+Herriot, et al. Standards Track [Page 4]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ a sequence of characters where the characters are associated with
+ some charset and some natural language. A character string MUST be in
+ "reading order" with the first character in the value (according to
+ reading order) being the first character in the encoding. A character
+ string whose associated charset is US-ASCII whose associated natural
+ language is US English is henceforth called a US-ASCII-STRING. A
+ character string whose associated charset and natural language are
+ specified in a request or response as described in the model document
+ is henceforth called a LOCALIZED-STRING. An octet string MUST be in
+ "IPP model document order" with the first octet in the value
+ (according to the IPP model document order) being the first octet in
+ the encoding. Every integer in this encoding MUST be encoded as a
+ signed integer using two's-complement binary encoding with big-endian
+ format (also known as "network order" and "most significant byte
+ first"). The number of octets for an integer MUST be 1, 2 or 4,
+ depending on usage in the protocol. Such one-octet integers,
+ henceforth called SIGNED-BYTE, are used for the version-number and
+ tag fields. Such two-byte integers, henceforth called SIGNED-SHORT
+ are used for the operation-id, status-code and length fields. Four
+ byte integers, henceforth called SIGNED-INTEGER, are used for value
+ fields and the request-id.
+
+ The following two sections present the encoding of the operation
+ layer in two ways:
+
+ - informally through pictures and description
+ - formally through Augmented Backus-Naur Form (ABNF), as
+ specified by RFC 2234 [RFC2234]
+
+ An operation request or response MUST use the encoding described in
+ these two sections.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 5]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+3.1 Picture of the Encoding
+
+3.1.1 Request and Response
+
+ An operation request or response is encoded as follows:
+
+ -----------------------------------------------
+ | version-number | 2 bytes - required
+ -----------------------------------------------
+ | operation-id (request) |
+ | or | 2 bytes - required
+ | status-code (response) |
+ -----------------------------------------------
+ | request-id | 4 bytes - required
+ -----------------------------------------------
+ | attribute-group | n bytes - 0 or more
+ -----------------------------------------------
+ | end-of-attributes-tag | 1 byte - required
+ -----------------------------------------------
+ | data | q bytes - optional
+ -----------------------------------------------
+
+ The first three fields in the above diagram contain the value of
+ attributes described in section 3.1.1 of the Model document.
+
+ The fourth field is the "attribute-group" field, and it occurs 0 or
+ more times. Each "attribute-group" field represents a single group of
+ attributes, such as an Operation Attributes group or a Job Attributes
+ group (see the Model document). The IPP model document specifies the
+ required attribute groups and their order for each operation request
+ and response.
+
+ The "end-of-attributes-tag" field is always present, even when the
+ "data" is not present. The Model document specifies for each
+ operation request and response whether the "data" field is present or
+ absent.
+
+3.1.2 Attribute Group
+
+ Each "attribute-group" field is encoded as follows:
+
+ -----------------------------------------------
+ | begin-attribute-group-tag | 1 byte
+ ----------------------------------------------------------
+ | attribute | p bytes |- 0 or more
+ ----------------------------------------------------------
+
+
+
+
+
+Herriot, et al. Standards Track [Page 6]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ The "begin-attribute-group-tag" field marks the beginning of an
+ "attribute-group" field and its value identifies the type of
+ attribute group, e.g. Operations Attributes group versus a Job
+ Attributes group. The "begin-attribute-group-tag" field also marks
+ the end of the previous attribute group except for the "begin-
+ attribute-group-tag" field in the first "attribute-group" field of a
+ request or response. The "begin-attribute-group-tag" field acts as
+ an "attribute-group" terminator because an "attribute-group" field
+ cannot nest inside another "attribute-group" field.
+
+ An "attribute-group" field contains zero or more "attribute" fields.
+
+ Note, the values of the "begin-attribute-group-tag" field and the
+ "end-of-attributes-tag" field are called "delimiter-tags".
+
+3.1.3 Attribute
+
+ An "attribute" field is encoded as follows:
+
+ -----------------------------------------------
+ | attribute-with-one-value | q bytes
+ ----------------------------------------------------------
+ | additional-value | r bytes |- 0 or more
+ ----------------------------------------------------------
+
+ When an attribute is single valued (e.g. "copies" with value of 10)
+ or multi-valued with one value (e.g. "sides-supported" with just the
+ value 'one-sided') it is encoded with just an "attribute-with-one-
+ value" field. When an attribute is multi-valued with n values (e.g.
+ "sides-supported" with the values 'one-sided' and 'two-sided-long-
+ edge'), it is encoded with an "attribute-with-one-value" field
+ followed by n-1 "additional-value" fields.
+
+3.1.4 Picture of the Encoding of an Attribute-with-one-value
+
+ Each "attribute-with-one-value" field is encoded as follows:
+
+ -----------------------------------------------
+ | value-tag | 1 byte
+ -----------------------------------------------
+ | name-length (value is u) | 2 bytes
+ -----------------------------------------------
+ | name | u bytes
+ -----------------------------------------------
+ | value-length (value is v) | 2 bytes
+ -----------------------------------------------
+ | value | v bytes
+ -----------------------------------------------
+
+
+
+Herriot, et al. Standards Track [Page 7]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ An "attribute-with-one-value" field is encoded with five subfields:
+
+ The "value-tag" field specifies the attribute syntax, e.g. 0x44
+ for the attribute syntax 'keyword'.
+
+ The "name-length" field specifies the length of the "name" field
+ in bytes, e.g. u in the above diagram or 15 for the name "sides-
+ supported".
+
+ The "name" field contains the textual name of the attribute, e.g.
+ "sides-supported".
+
+ The "value-length" field specifies the length of the "value" field
+ in bytes, e.g. v in the above diagram or 9 for the (keyword) value
+ 'one-sided'.
+
+ The "value" field contains the value of the attribute, e.g. the
+ textual value 'one-sided'.
+
+3.1.5 Additional-value
+
+ Each "additional-value" field is encoded as follows:
+
+ -----------------------------------------------
+ | value-tag | 1 byte
+ -----------------------------------------------
+ | name-length (value is 0x0000) | 2 bytes
+ -----------------------------------------------
+ | value-length (value is w) | 2 bytes
+ -----------------------------------------------
+ | value | w bytes
+ -----------------------------------------------
+
+ An "additional-value" is encoded with four subfields:
+
+ The "value-tag" field specifies the attribute syntax, e.g. 0x44
+ for the attribute syntax 'keyword'.
+
+ The "name-length" field has the value of 0 in order to signify
+ that it is an "additional-value". The value of the "name-length"
+ field distinguishes an "additional-value" field ("name-length" is
+ 0) from an "attribute-with-one-value" field ("name-length" is not
+ 0).
+
+ The "value-length" field specifies the length of the "value" field
+ in bytes, e.g. w in the above diagram or 19 for the (keyword)
+ value 'two-sided-long-edge'.
+
+
+
+
+Herriot, et al. Standards Track [Page 8]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ The "value" field contains the value of the attribute, e.g. the
+ textual value 'two-sided-long-edge'.
+
+3.1.6 Alternative Picture of the Encoding of a Request Or a Response
+
+ From the standpoint of a parser that performs an action based on a
+ "tag" value, the encoding consists of:
+
+ -----------------------------------------------
+ | version-number | 2 bytes - required
+ -----------------------------------------------
+ | operation-id (request) |
+ | or | 2 bytes - required
+ | status-code (response) |
+ -----------------------------------------------
+ | request-id | 4 bytes - required
+ -----------------------------------------------------------
+ | tag (delimiter-tag or value-tag) | 1 byte |
+ ----------------------------------------------- |-0 or more
+ | empty or rest of attribute | x bytes |
+ -----------------------------------------------------------
+ | end-of-attributes-tag | 1 byte - required
+ -----------------------------------------------
+ | data | y bytes - optional
+ -----------------------------------------------
+
+ The following show what fields the parser would expect after each
+ type of "tag":
+
+ - "begin-attribute-group-tag": expect zero or more "attribute"
+ fields
+ - "value-tag": expect the remainder of an "attribute-with-one-
+ value" or an "additional-value".
+ - "end-of-attributes-tag": expect that "attribute" fields are
+ complete and there is optional "data"
+
+3.2 Syntax of Encoding
+
+ The syntax below is ABNF [RFC2234] except 'strings of literals' MUST
+ be case sensitive. For example 'a' means lower case 'a' and not
+ upper case 'A'. In addition, SIGNED-BYTE and SIGNED-SHORT fields
+ are represented as '%x' values which show their range of values.
+
+ ipp-message = ipp-request / ipp-response
+ ipp-request = version-number operation-id request-id
+ *attribute-group end-of-attributes-tag data
+ ipp-response = version-number status-code request-id
+ *attribute-group end-of-attributes-tag data
+
+
+
+Herriot, et al. Standards Track [Page 9]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ attribute-group = begin-attribute-group-tag *attribute
+
+ version-number = major-version-number minor-version-number
+ major-version-number = SIGNED-BYTE
+ minor-version-number = SIGNED-BYTE
+
+ operation-id = SIGNED-SHORT ; mapping from model defined below
+ status-code = SIGNED-SHORT ; mapping from model defined below
+ request-id = SIGNED-INTEGER ; whose value is > 0
+
+ attribute = attribute-with-one-value *additional-value
+
+ attribute-with-one-value = value-tag name-length name
+ value-length value
+ additional-value = value-tag zero-name-length value-length value
+
+ name-length = SIGNED-SHORT ; number of octets of 'name'
+ name = LALPHA *( LALPHA / DIGIT / "-" / "_" / "." )
+ value-length = SIGNED-SHORT ; number of octets of 'value'
+ value = OCTET-STRING
+
+ data = OCTET-STRING
+
+ zero-name-length = %x00.00 ; name-length of 0
+ value-tag = %x10-FF ;see section 3.7.2
+ begin-attribute-group-tag = %x00-02 / %04-0F ; see section 3.7.1
+ end-of-attributes-tag = %x03 ; tag of 3
+ ; see section 3.7.1
+ SIGNED-BYTE = BYTE
+ SIGNED-SHORT = 2BYTE
+ SIGNED-INTEGER = 4BYTE
+ DIGIT = %x30-39 ; "0" to "9"
+ LALPHA = %x61-7A ; "a" to "z"
+ BYTE = %x00-FF
+ OCTET-STRING = *BYTE
+
+ The syntax below defines additional terms that are referenced in this
+ document. This syntax provides an alternate grouping of the delimiter
+ tags.
+
+ delimiter-tag = begin-attribute-group-tag / ; see section 3.7.1
+ end-of-attributes-tag
+ delimiter-tag = %x00-0F ; see section 3.7.1
+
+ begin-attribute-group-tag = %x00 / operation-attributes-tag /
+ job-attributes-tag / printer-attributes-tag /
+ unsupported-attributes-tag / %x06-0F
+ operation-attributes-tag = %x01 ; tag of 1
+
+
+
+Herriot, et al. Standards Track [Page 10]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ job-attributes-tag = %x02 ; tag of 2
+ printer-attributes-tag = %x04 ; tag of 4
+ unsupported-attributes-tag = %x05 ; tag of 5
+
+3.3 Attribute-group
+
+ Each "attribute-group" field MUST be encoded with the "begin-
+ attribute-group-tag" field followed by zero or more "attribute" sub-
+ fields.
+
+ The table below maps the model document group name to value of the
+ "begin-attribute-group-tag" field:
+
+ Model Document Group "begin-attribute-group-tag" field
+ values
+
+ Operation Attributes "operations-attributes-tag"
+ Job Template Attributes "job-attributes-tag"
+ Job Object Attributes "job-attributes-tag"
+ Unsupported Attributes "unsupported-attributes-tag"
+ Requested Attributes "job-attributes-tag"
+ (Get-Job-Attributes)
+ Requested Attributes "printer-attributes-tag"
+ (Get-Printer-Attributes)
+ Document Content in a special position as
+ described above
+
+ For each operation request and response, the model document
+ prescribes the required and optional attribute groups, along with
+ their order. Within each attribute group, the model document
+ prescribes the required and optional attributes, along with their
+ order.
+
+ When the Model document requires an attribute group in a request or
+ response and the attribute group contains zero attributes, a request
+ or response SHOULD encode the attribute group with the "begin-
+ attribute-group-tag" field followed by zero "attribute" fields. For
+ example, if the client requests a single unsupported attribute with
+ the Get-Printer-Attributes operation, the Printer MUST return no
+ "attribute" fields, and it SHOULD return a "begin-attribute-group-
+ tag" field for the Printer Attributes Group. The Unsupported
+ Attributes group is not such an example. According to the model
+ document, the Unsupported Attributes Group SHOULD be present only if
+ the unsupported attributes group contains at least one attribute.
+
+ A receiver of a request MUST be able to process the following as
+ equivalent empty attribute groups:
+
+
+
+
+Herriot, et al. Standards Track [Page 11]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ a) A "begin-attribute-group-tag" field with zero following
+ "attribute" fields.
+
+ b) An expected but missing "begin-attribute-group-tag" field.
+
+ When the Model document requires a sequence of an unknown number of
+ attribute groups, each of the same type, the encoding MUST contain
+ one "begin-attribute-group-tag" field for each attribute group even
+ when an "attribute-group" field contains zero "attribute" sub-fields.
+ For example, for the Get-Jobs operation may return zero attributes
+ for some jobs and not others. The "begin-attribute-group-tag" field
+ followed by zero "attribute" fields tells the recipient that there is
+ a job in queue for which no information is available except that it
+ is in the queue.
+
+3.4 Required Parameters
+
+ Some operation elements are called parameters in the model document
+ [RFC2911]. They MUST be encoded in a special position and they MUST
+ NOT appear as operation attributes. These parameters are described
+ in the subsections below.
+
+3.4.1 Version-number
+
+ The "version-number" field MUST consist of a major and minor
+ version-number, each of which MUST be represented by a SIGNED-BYTE.
+ The major version-number MUST be the first byte of the encoding and
+ the minor version-number MUST be the second byte of the encoding. The
+ protocol described in this document MUST have a major version-number
+ of 1 (0x01) and a minor version-number of 1 (0x01). The ABNF for
+ these two bytes MUST be %x01.01.
+
+3.4.2 Operation-id
+
+ The "operation-id" field MUST contain an operation-id value defined
+ in the model document. The value MUST be encoded as a SIGNED-SHORT
+ and it MUST be in the third and fourth bytes of the encoding of an
+ operation request.
+
+3.4.3 Status-code
+
+ The "status-code" field MUST contain a status-code value defined in
+ the model document. The value MUST be encoded as a SIGNED-SHORT and
+ it MUST be in the third and fourth bytes of the encoding of an
+ operation response.
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 12]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ The status-code is an operation attribute in the model document. In
+ the protocol, the status-code is in a special position, outside of
+ the operation attributes.
+
+ If an IPP status-code is returned, then the HTTP Status-Code MUST be
+ 200 (successful-ok). With any other HTTP Status-Code value, the HTTP
+ response MUST NOT contain an IPP message-body, and thus no IPP
+ status-code is returned.
+
+3.4.4 Request-id
+
+ The "request-id" field MUST contain a request-id value as defined in
+ the model document. The value MUST be encoded as a SIGNED-INTEGER and
+ it MUST be in the fifth through eighth bytes of the encoding.
+
+3.5 Tags
+
+ There are two kinds of tags:
+
+ - delimiter tags: delimit major sections of the protocol, namely
+ attributes and data
+ - value tags: specify the type of each attribute value
+
+3.5.1 Delimiter Tags
+
+ The following table specifies the values for the delimiter tags:
+
+ Tag Value (Hex) Meaning
+
+ 0x00 reserved for definition in a future IETF
+ standards track document
+ 0x01 "operation-attributes-tag"
+ 0x02 "job-attributes-tag"
+ 0x03 "end-of-attributes-tag"
+ 0x04 "printer-attributes-tag"
+ 0x05 "unsupported-attributes-tag"
+ 0x06-0x0f reserved for future delimiters in IETF
+ standards track documents
+
+ When a "begin-attribute-group-tag" field occurs in the protocol, it
+ means that zero or more following attributes up to the next delimiter
+ tag MUST be attributes belonging to the attribute group specified by
+ the value of the "begin-attribute-group-tag". For example, if the
+ value of "begin-attribute-group-tag" is 0x01, the following
+ attributes MUST be members of the Operations Attributes group.
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 13]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ The "end-of-attributes-tag" (value 0x03) MUST occur exactly once in
+ an operation. It MUST be the last "delimiter-tag". If the operation
+ has a document-content group, the document data in that group MUST
+ follow the "end-of-attributes-tag".
+
+ The order and presence of "attribute-group" fields (whose beginning
+ is marked by the "begin-attribute-group-tag" subfield) for each
+ operation request and each operation response MUST be that defined in
+ the model document. For further details, see section 3.7 "(Attribute)
+ Name" and 13 "Appendix A: Protocol Examples".
+
+ A Printer MUST treat a "delimiter-tag" (values from 0x00 through
+ 0x0F) differently from a "value-tag" (values from 0x10 through 0xFF)
+ so that the Printer knows that there is an entire attribute group
+ that it doesn't understand as opposed to a single value that it
+ doesn't understand.
+
+3.5.2 Value Tags
+
+ The remaining tables show values for the "value-tag" field, which is
+ the first octet of an attribute. The "value-tag" field specifies the
+ type of the value of the attribute.
+
+ The following table specifies the "out-of-band" values for the
+ "value-tag" field.
+
+ Tag Value (Hex) Meaning
+
+ 0x10 unsupported
+ 0x11 reserved for 'default' for definition in a future
+ IETF standards track document
+ 0x12 unknown
+ 0x13 no-value
+ 0x14-0x1F reserved for "out-of-band" values in future IETF
+ standards track documents.
+
+ The following table specifies the integer values for the "value-tag"
+ field:
+
+ Tag Value (Hex) Meaning
+
+ 0x20 reserved for definition in a future IETF
+ standards track document
+ 0x21 integer
+ 0x22 boolean
+ 0x23 enum
+ 0x24-0x2F reserved for integer types for definition in
+ future IETF standards track documents
+
+
+
+Herriot, et al. Standards Track [Page 14]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ NOTE: 0x20 is reserved for "generic integer" if it should ever be
+ needed.
+
+ The following table specifies the octetString values for the "value-
+ tag" field:
+
+ Tag Value (Hex) Meaning
+
+ 0x30 octetString with an unspecified format
+ 0x31 dateTime
+ 0x32 resolution
+ 0x33 rangeOfInteger
+ 0x34 reserved for definition in a future IETF
+ standards track document
+ 0x35 textWithLanguage
+ 0x36 nameWithLanguage
+ 0x37-0x3F reserved for octetString type definitions in
+ future IETF standards track documents
+
+ The following table specifies the character-string values for the
+ "value-tag" field:
+
+ Tag Value (Hex) Meaning
+
+ 0x40 reserved for definition in a future IETF
+ standards track document
+ 0x41 textWithoutLanguage
+ 0x42 nameWithoutLanguage
+ 0x43 reserved for definition in a future IETF
+ standards track document
+ 0x44 keyword
+ 0x45 uri
+ 0x46 uriScheme
+ 0x47 charset
+ 0x48 naturalLanguage
+ 0x49 mimeMediaType
+ 0x4A-0x5F reserved for character string type definitions
+ in future IETF standards track documents
+
+ NOTE: 0x40 is reserved for "generic character-string" if it should
+ ever be needed.
+
+ NOTE: an attribute value always has a type, which is explicitly
+ specified by its tag; one such tag value is "nameWithoutLanguage".
+ An attribute's name has an implicit type, which is keyword.
+
+ The values 0x60-0xFF are reserved for future type definitions in IETF
+ standards track documents.
+
+
+
+Herriot, et al. Standards Track [Page 15]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ The tag 0x7F is reserved for extending types beyond the 255 values
+ available with a single byte. A tag value of 0x7F MUST signify that
+ the first 4 bytes of the value field are interpreted as the tag
+ value. Note this future extension doesn't affect parsers that are
+ unaware of this special tag. The tag is like any other unknown tag,
+ and the value length specifies the length of a value, which contains
+ a value that the parser treats atomically. Values from 0x00 to
+ 0x37777777 are reserved for definition in future IETF standard track
+ documents. The values 0x40000000 to 0x7FFFFFFF are reserved for
+ vendor extensions.
+
+3.6 Name-Length
+
+ The "name-length" field MUST consist of a SIGNED-SHORT. This field
+ MUST specify the number of octets in the immediately following "name"
+ field. The value of this field excludes the two bytes of the "name-
+ length" field. For example, if the "name" field contains "sides", the
+ value of this field is 5.
+
+ If a "name-length" field has a value of zero, the following "name"
+ field MUST be empty, and the following value MUST be treated as an
+ additional value for the attribute encoded in the nearest preceding
+ "attribute-with-one-value" field. Within an attribute group, if two
+ or more attributes have the same name, the attribute group is mal-
+ formed (see [RFC2911] section 3.1.3). The zero-length name is the
+ only mechanism for multi-valued attributes.
+
+3.7 (Attribute) Name
+
+ The "name" field MUST contain the name of an attribute. The model
+ document [RFC2911] specifies such names.
+
+3.8 Value Length
+
+ The "value-length" field MUST consist of a SIGNED-SHORT. This field
+ MUST specify the number of octets in the immediately following
+ "value" field. The value of this field excludes the two bytes of the
+ "value-length" field. For example, if the "value" field contains the
+ keyword (text) value 'one-sided', the value of this field is 9.
+
+ For any of the types represented by binary signed integers, the
+ sender MUST encode the value in exactly four octets.
+
+ For any of the types represented by character-strings, the sender
+ MUST encode the value with all the characters of the string and
+ without any padding characters.
+
+
+
+
+
+Herriot, et al. Standards Track [Page 16]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ For "out-of-band" "value-tag" fields defined in this document, such
+ as "unsupported", the "value-length" MUST be 0 and the "value" empty;
+ the "value" has no meaning when the "value-tag" has one of these
+ "out-of-band" values. For future "out-of-band" "value-tag" fields,
+ the same rule holds unless the definition explicitly states that the
+ "value-length" MAY be non-zero and the "value" non-empty.
+
+3.9 (Attribute) Value
+
+ The syntax types (specified by the "value-tag" field) and most of the
+ details of the representation of attribute values are defined in the
+ IPP model document. The table below augments the information in the
+ model document, and defines the syntax types from the model document
+ in terms of the 5 basic types defined in section 3, "Encoding of the
+ Operation Layer". The 5 types are US-ASCII-STRING, LOCALIZED-STRING,
+ SIGNED-INTEGER, SIGNED-SHORT, SIGNED-BYTE, and OCTET-STRING.
+
+ Syntax of Attribute Encoding
+ Value
+
+ textWithoutLanguage, LOCALIZED-STRING.
+ nameWithoutLanguage
+
+ textWithLanguage OCTET-STRING consisting of 4 fields:
+ a. a SIGNED-SHORT which is the number of
+ octets in the following field
+ b. a value of type natural-language,
+ c. a SIGNED-SHORT which is the number of
+ octets in the following field,
+ d. a value of type textWithoutLanguage.
+ The length of a textWithLanguage value MUST be
+ 4 + the value of field a + the value of field c.
+
+ nameWithLanguage OCTET-STRING consisting of 4 fields:
+ a. a SIGNED-SHORT which is the number of
+ octets in the following field
+ b. a value of type natural-language,
+ c. a SIGNED-SHORT which is the number of
+ octets in the following field
+ d. a value of type nameWithoutLanguage.
+ The length of a nameWithLanguage value MUST be
+ 4 + the value of field a + the value of field c.
+
+ charset, US-ASCII-STRING.
+ naturalLanguage,
+ mimeMediaType,
+ keyword, uri, and
+ uriScheme
+
+
+
+Herriot, et al. Standards Track [Page 17]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Syntax of Attribute Encoding
+ Value
+
+ boolean SIGNED-BYTE where 0x00 is 'false' and 0x01 is
+ 'true'.
+
+ integer and enum a SIGNED-INTEGER.
+
+ dateTime OCTET-STRING consisting of eleven octets whose
+ contents are defined by "DateAndTime" in RFC
+ 1903 [RFC1903].
+
+ resolution OCTET-STRING consisting of nine octets of 2
+ SIGNED-INTEGERs followed by a SIGNED-BYTE. The
+ first SIGNED-INTEGER contains the value of
+ cross feed direction resolution. The second
+ SIGNED-INTEGER contains the value of feed
+ direction resolution. The SIGNED-BYTE contains
+ the units
+
+ rangeOfInteger Eight octets consisting of 2 SIGNED-INTEGERs.
+ The first SIGNED-INTEGER contains the lower
+ bound and the second SIGNED-INTEGER contains
+ the upper bound.
+
+ 1setOf X Encoding according to the rules for an
+ attribute with more than 1 value. Each value
+ X is encoded according to the rules for
+ encoding its type.
+
+ octetString OCTET-STRING
+
+
+ The attribute syntax type of the value determines its encoding and
+ the value of its "value-tag".
+
+3.10 Data
+
+ The "data" field MUST include any data required by the operation
+
+4. Encoding of Transport Layer
+
+ HTTP/1.1 [RFC2616] is the transport layer for this protocol.
+
+ The operation layer has been designed with the assumption that the
+ transport layer contains the following information:
+
+
+
+
+
+Herriot, et al. Standards Track [Page 18]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ - the URI of the target job or printer operation
+ - the total length of the data in the operation layer, either as
+ a single length or as a sequence of chunks each with a length.
+
+ It is REQUIRED that a printer implementation support HTTP over the
+ IANA assigned Well Known Port 631 (the IPP default port), though a
+ printer implementation may support HTTP over some other port as well.
+
+ Each HTTP operation MUST use the POST method where the request-URI is
+ the object target of the operation, and where the "Content-Type" of
+ the message-body in each request and response MUST be
+ "application/ipp". The message-body MUST contain the operation layer
+ and MUST have the syntax described in section 3.2 "Syntax of
+ Encoding". A client implementation MUST adhere to the rules for a
+ client described for HTTP1.1 [RFC2616]. A printer (server)
+ implementation MUST adhere the rules for an origin server described
+ for HTTP1.1 [RFC2616].
+
+ An IPP server sends a response for each request that it receives. If
+ an IPP server detects an error, it MAY send a response before it has
+ read the entire request. If the HTTP layer of the IPP server
+ completes processing the HTTP headers successfully, it MAY send an
+ intermediate response, such as "100 Continue", with no IPP data
+ before sending the IPP response. A client MUST expect such a variety
+ of responses from an IPP server. For further information on HTTP/1.1,
+ consult the HTTP documents [RFC2616].
+
+ An HTTP server MUST support chunking for IPP requests, and an IPP
+ client MUST support chunking for IPP responses according to HTTP/1.1
+ [RFC2616]. Note: this rule causes a conflict with non-compliant
+ implementations of HTTP/1.1 that don't support chunking for POST
+ methods, and this rule may cause a conflict with non-compliant
+ implementations of HTTP/1.1 that don't support chunking for CGI
+ scripts.
+
+4.1 Printer-uri and job-uri
+
+ All Printer and Job objects are identified by a Uniform Resource
+ Identifier (URI) [RFC2396] so that they can be persistently and
+ unambiguously referenced. Since every URL is a specialized form of a
+ URI, even though the more generic term URI is used throughout the
+ rest of this document, its usage is intended to cover the more
+ specific notion of URL as well.
+
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 19]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Some operation elements are encoded twice, once as the request-URI on
+ the HTTP Request-Line and a second time as a REQUIRED operation
+ attribute in the application/ipp entity. These attributes are the
+ target URI for the operation and are called printer-uri and job-uri.
+ Note: The target URI is included twice in an operation referencing
+ the same IPP object, but the two URIs NEED NOT be literally
+ identical. One can be a relative URI and the other can be an absolute
+ URI. HTTP/1.1 allows clients to generate and send a relative URI
+ rather than an absolute URI. A relative URI identifies a resource
+ with the scope of the HTTP server, but does not include scheme, host
+ or port. The following statements characterize how URLs should be
+ used in the mapping of IPP onto HTTP/1.1:
+
+ 1. Although potentially redundant, a client MUST supply the target
+ of the operation both as an operation attribute and as a URI at
+ the HTTP layer. The rationale for this decision is to maintain
+ a consistent set of rules for mapping application/ipp to
+ possibly many communication layers, even where URLs are not
+ used as the addressing mechanism in the transport layer.
+ 2. Even though these two URLs might not be literally identical
+ (one being relative and the other being absolute), they MUST
+ both reference the same IPP object. However, a Printer NEED NOT
+ verify that the two URLs reference the same IPP object, and
+ NEED NOT take any action if it determines the two URLs to be
+ different.
+ 3. The URI in the HTTP layer is either relative or absolute and is
+ used by the HTTP server to route the HTTP request to the
+ correct resource relative to that HTTP server. The HTTP server
+ need not be aware of the URI within the operation request.
+ 4. Once the HTTP server resource begins to process the HTTP
+ request, it might get the reference to the appropriate IPP
+ Printer object from either the HTTP URI (using to the context
+ of the HTTP server for relative URLs) or from the URI within
+ the operation request; the choice is up to the implementation.
+ 5. HTTP URIs can be relative or absolute, but the target URI in
+ the operation MUST be an absolute URI.
+
+5. IPP URL Scheme
+
+ The IPP/1.1 document defines a new scheme 'ipp' as the value of a URL
+ that identifies either an IPP printer object or an IPP job object.
+ The IPP attributes using the 'ipp' scheme are specified below.
+ Because the HTTP layer does not support the 'ipp' scheme, a client
+ MUST map 'ipp' URLs to 'http' URLs, and then follows the HTTP
+ [RFC2616][RFC2617] rules for constructing a Request-Line and HTTP
+ headers. The mapping is simple because the 'ipp' scheme implies all
+ of the same protocol semantics as that of the 'http' scheme
+
+
+
+
+Herriot, et al. Standards Track [Page 20]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ [RFC2616], except that it represents a print service and the implicit
+ (default) port number that clients use to connect to a server is port
+ 631.
+
+ In the remainder of this section the term 'ipp-URL' means a URL whose
+ scheme is 'ipp' and whose implicit (default) port is 631. The term
+ 'http-URL' means a URL whose scheme is 'http', and the term 'https-
+ URL' means a URL whose scheme is 'https',
+
+ A client and an IPP object (i.e. the server) MUST support the ipp-URL
+ value in the following IPP attributes.
+ job attributes:
+ job-uri
+ job-printer-uri
+ printer attributes:
+ printer-uri-supported
+ operation attributes:
+ job-uri
+ printer-uri
+ Each of the above attributes identifies a printer or job object. The
+ ipp-URL is intended as the value of the attributes in this list, and
+ for no other attributes. All of these attributes have a syntax type
+ of 'uri', but there are attributes with a syntax type of 'uri' that
+ do not use the 'ipp' scheme, e.g. 'job-more-info'.
+
+ If a printer registers its URL with a directory service, the printer
+ MUST register an ipp-URL.
+
+ User interfaces are beyond the scope of this document. But if
+ software exposes the ipp-URL values of any of the above five
+ attributes to a human user, it is REQUIRED that the human see the
+ ipp-URL as is.
+
+ When a client sends a request, it MUST convert a target ipp-URL to a
+ target http-URL for the HTTP layer according to the following rules:
+
+ 1. change the 'ipp' scheme to 'http'
+ 2. add an explicit port 631 if the URL does not contain an
+ explicit port. Note: port 631 is the IANA assigned Well Known
+ Port for the 'ipp' scheme.
+
+ The client MUST use the target http-URL in both the HTTP Request-
+ Line and HTTP headers, as specified by HTTP [RFC2616] [RFC2617] .
+ However, the client MUST use the target ipp-URL for the value of the
+ "printer-uri" or "job-uri" operation attribute within the
+ application/ipp body of the request. The server MUST use the ipp-URL
+
+
+
+
+
+Herriot, et al. Standards Track [Page 21]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ for the value of the "printer-uri", "job-uri" or "printer-uri-
+ supported" attributes within the application/ipp body of the
+ response.
+
+ For example, when an IPP client sends a request directly (i.e. no
+ proxy) to an ipp-URL "ipp://myhost.com/myprinter/myqueue", it opens a
+ TCP connection to port 631 (the ipp implicit port) on the host
+ "myhost.com" and sends the following data:
+
+ POST /myprinter/myqueue HTTP/1.1
+ Host: myhost.com:631
+ Content-type: application/ipp
+ Transfer-Encoding: chunked
+ ...
+ "printer-uri" "ipp://myhost.com/myprinter/myqueue"
+ (encoded in application/ipp message body)
+ ...
+
+ As another example, when an IPP client sends the same request as
+ above via a proxy "myproxy.com", it opens a TCP connection to the
+ proxy port 8080 on the proxy host "myproxy.com" and sends the
+ following data:
+
+ POST http://myhost.com:631/myprinter/myqueue HTTP/1.1
+ Host: myhost.com:631
+ Content-type: application/ipp
+ Transfer-Encoding: chunked
+ ...
+ "printer-uri" "ipp://myhost.com/myprinter/myqueue"
+ (encoded in application/ipp message body)
+ ...
+
+ The proxy then connects to the IPP origin server with headers that
+ are the same as the "no-proxy" example above.
+
+6. IANA Considerations
+
+ This section describes the procedures for allocating encoding for the
+ following IETF standards track extensions and vendor extensions to
+ the IPP/1.1 Encoding and Transport document:
+
+ 1. attribute syntaxes - see [RFC2911] section 6.3
+ 2. attribute groups - see [RFC2911] section 6.5
+ 3. out-of-band attribute values - see [RFC2911] section 6.7
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 22]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ These extensions follow the "type2" registration procedures defined
+ in [RFC2911] section 6. Extensions registered for use with IPP/1.1
+ are OPTIONAL for client and IPP object conformance to the IPP/1.1
+ Encoding and Transport document.
+
+ These extension procedures are aligned with the guidelines as set
+ forth by the IESG [IANA-CON]. The [RFC2911] Section 11 describes how
+ to propose new registrations for consideration. IANA will reject
+ registration proposals that leave out required information or do not
+ follow the appropriate format described in [RFC2911] Section 11. The
+ IPP/1.1 Encoding and Transport document may also be extended by an
+ appropriate RFC that specifies any of the above extensions.
+
+7. Internationalization Considerations
+
+ See the section on "Internationalization Considerations" in the
+ document "Internet Printing Protocol/1.1: Model and Semantics"
+ [RFC2911] for information on internationalization. This document adds
+ no additional issues.
+
+8. Security Considerations
+
+ The IPP Model and Semantics document [RFC2911] discusses high level
+ security requirements (Client Authentication, Server Authentication
+ and Operation Privacy). Client Authentication is the mechanism by
+ which the client proves its identity to the server in a secure
+ manner. Server Authentication is the mechanism by which the server
+ proves its identity to the client in a secure manner. Operation
+ Privacy is defined as a mechanism for protecting operations from
+ eavesdropping.
+
+8.1 Security Conformance Requirements
+
+ This section defines the security requirements for IPP clients and
+ IPP objects.
+
+8.1.1 Digest Authentication
+
+ IPP clients MUST support:
+
+ Digest Authentication [RFC2617].
+
+ MD5 and MD5-sess MUST be implemented and supported.
+
+ The Message Integrity feature NEED NOT be used.
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 23]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ IPP Printers SHOULD support:
+
+ Digest Authentication [RFC2617].
+
+ MD5 and MD5-sess MUST be implemented and supported.
+
+ The Message Integrity feature NEED NOT be used.
+
+ The reasons that IPP Printers SHOULD (rather than MUST) support
+ Digest Authentication are:
+
+ 1. While Client Authentication is important, there is a certain class
+ of printer devices where it does not make sense. Specifically, a
+ low-end device with limited ROM space and low paper throughput may
+ not need Client Authentication. This class of device typically
+ requires firmware designers to make trade-offs between protocols
+ and functionality to arrive at the lowest-cost solution possible.
+ Factored into the designer's decisions is not just the size of the
+ code, but also the testing, maintenance, usefulness, and time-to-
+ market impact for each feature delivered to the customer. Forcing
+ such low-end devices to provide security in order to claim IPP/1.1
+ conformance would not make business sense and could potentially
+ stall the adoption of the standard.
+
+ 2. Print devices that have high-volume throughput and have available
+ ROM space have a compelling argument to provide support for Client
+ Authentication that safeguards the device from unauthorized
+ access. These devices are prone to a high loss of consumables and
+ paper if unauthorized access should occur.
+
+8.1.2 Transport Layer Security (TLS)
+
+ IPP Printers SHOULD support Transport Layer Security (TLS) [RFC2246]
+ for Server Authentication and Operation Privacy. IPP Printers MAY
+ also support TLS for Client Authentication. If an IPP Printer
+ supports TLS, it MUST support the TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
+ cipher suite as mandated by RFC 2246 [RFC2246]. All other cipher
+ suites are OPTIONAL. An IPP Printer MAY support Basic Authentication
+ (described in HTTP/1.1 [RFC2617]) for Client Authentication if the
+ channel is secure. TLS with the above mandated cipher suite can
+ provide such a secure channel.
+
+ If a IPP client supports TLS, it MUST support the
+ TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA cipher suite as mandated by RFC
+ 2246 [RFC2246]. All other cipher suites are OPTIONAL.
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 24]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ The IPP Model and Semantics document defines two printer attributes
+ ("uri-authentication-supported" and "uri-security-supported") that
+ the client can use to discover the security policy of a printer. That
+ document also outlines IPP-specific security considerations and
+ should be the primary reference for security implications with regard
+ to the IPP protocol itself. For backward compatibility with IPP
+ version 1.0, IPP clients and printers may also support SSL3 [ssl].
+ This is in addition to the security required in this document.
+
+8.2 Using IPP with TLS
+
+ IPP/1.1 uses the "Upgrading to TLS Within HTTP/1.1" mechanism
+ [RFC2817]. An initial IPP request never uses TLS. The client
+ requests a secure TLS connection by using the HTTP "Upgrade" header,
+ while the server agrees in the HTTP response. The switch to TLS
+ occurs either because the server grants the client's request to
+ upgrade to TLS, or a server asks to switch to TLS in its response.
+ Secure communication begins with a server's response to switch to
+ TLS.
+
+9. Interoperability with IPP/1.0 Implementations
+
+ It is beyond the scope of this specification to mandate conformance
+ with previous versions. IPP/1.1 was deliberately designed, however,
+ to make supporting previous versions easy. It is worth noting that,
+ at the time of composing this specification (1999), we would expect
+ IPP/1.1 Printer implementations to:
+
+ understand any valid request in the format of IPP/1.0, or 1.1;
+
+ respond appropriately with a response containing the same
+ "version-number" parameter value used by the client in the
+ request.
+
+ And we would expect IPP/1.1 clients to:
+
+ understand any valid response in the format of IPP/1.0, or 1.1.
+
+9.1 The "version-number" Parameter
+
+ The following are rules regarding the "version-number" parameter (see
+ section 3.3):
+
+ 1. Clients MUST send requests containing a "version-number"
+ parameter with a '1.1' value and SHOULD try supplying alternate
+ version numbers if they receive a 'server-error-version-not-
+ supported' error return in a response.
+
+
+
+
+Herriot, et al. Standards Track [Page 25]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ 2. IPP objects MUST accept requests containing a "version-number"
+ parameter with a '1.1' value (or reject the request for reasons
+ other than 'server-error-version-not-supported').
+
+ 3. It is recommended that IPP objects accept any request with the
+ major version '1' (or reject the request for reasons other than
+ 'server-error-version-not-supported'). See [RFC2911]
+ "versions" sub-section.
+
+ 4. In any case, security MUST NOT be compromised when a client
+ supplies a lower "version-number" parameter in a request. For
+ example, if an IPP/1.1 conforming Printer object accepts
+ version '1.0' requests and is configured to enforce Digest
+ Authentication, it MUST do the same for a version '1.0'
+ request.
+
+9.2 Security and URL Schemes
+
+ The following are rules regarding security, the "version-number"
+ parameter, and the URL scheme supplied in target attributes and
+ responses:
+
+ 1. When a client supplies a request, the "printer-uri" or "job-
+ uri" target operation attribute MUST have the same scheme as
+ that indicated in one of the values of the "printer-uri-
+ supported" Printer attribute.
+
+ 2. When the server returns the "job-printer-uri" or "job-uri" Job
+ Description attributes, it SHOULD return the same scheme
+ ('ipp', 'https', 'http', etc.) that the client supplied in the
+ "printer-uri" or "job-uri" target operation attributes in the
+ Get-Job-Attributes or Get-Jobs request, rather than the scheme
+ used when the job was created. However, when a client requests
+ job attributes using the Get-Job-Attributes or Get-Jobs
+ operations, the jobs and job attributes that the server returns
+ depends on: (1) the security in effect when the job was
+ created, (2) the security in effect in the query request, and
+ (3) the security policy in force.
+
+ 3. It is recommended that if a server registers a non-secure ipp-
+ URL with a directory service (see [RFC2911] "Generic Directory
+ Schema" Appendix), then it also register an http-URL for
+ interoperability with IPP/1.0 clients (see section 9).
+
+ 4. In any case, security MUST NOT be compromised when a client
+ supplies an 'http' or other non-secure URL scheme in the target
+ "printer-uri" and "job-uri" operation attributes in a request.
+
+
+
+
+Herriot, et al. Standards Track [Page 26]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+10. References
+
+ [dpa] ISO/IEC 10175 Document Printing Application (DPA), June
+ 1996.
+
+ [iana] IANA Registry of Coded Character Sets:
+ ftp://ftp.isi.edu/in-notes/iana/assignments/character-
+ sets.
+
+ [IANA-CON] Narten, T. and H. Alvestrand, "Guidelines for Writing an
+ IANA Considerations Section in RFCs", BCP 26, RFC 2434,
+ October 1998.
+
+ [ipp-iig] Hastings, Tom, et al., "Internet Printing Protocol/1.1:
+ Implementer's Guide", Work in Progress.
+
+ [RFC822] Crocker, D., "Standard for the Format of ARPA Internet
+ Text Messages", STD 11, RFC 822, August 1982.
+
+ [RFC1123] Braden, S., "Requirements for Internet Hosts - Application
+ and Support", STD 3, RFC 1123, October, 1989.
+
+ [RFC1179] McLaughlin, L. III, (editor), "Line Printer Daemon
+ Protocol", RFC 1179, August 1990.
+
+ [RFC2223] Postel, J. and J. Reynolds, "Instructions to RFC Authors",
+ RFC 2223, October 1997.
+
+ [RFC1738] Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform
+ Resource Locators (URL)", RFC 1738, December 1994.
+
+ [RFC1759] Smith, R., Wright, F., Hastings, T., Zilles, S. and J.
+ Gyllenskog, "Printer MIB", RFC 1759, March 1995.
+
+ [RFC1766] Alvestrand, H., "Tags for the Identification of
+ Languages", RFC 1766, March 1995.
+
+ [RFC1808] Fielding, R., "Relative Uniform Resource Locators", RFC
+ 1808, June 1995.
+
+ [RFC1903] Case, J., McCloghrie, K., Rose, M. and S. Waldbusser,
+ "Textual Conventions for Version 2 of the Simple Network
+ Management Protocol (SNMPv2)", RFC 1903, January 1996.
+
+ [RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part Two: Media Types", RFC 2046,
+ November 1996.
+
+
+
+
+Herriot, et al. Standards Track [Page 27]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ [RFC2048] Freed, N., Klensin, J. and J. Postel, "Multipurpose
+ Internet Mail Extension (MIME) Part Four: Registration
+ Procedures", BCP 13, RFC 2048, November 1996.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2184] Freed, N. and K. Moore, "MIME Parameter Value and Encoded
+ Word Extensions: Character Sets, Languages, and
+ Continuations", RFC 2184, August 1997.
+
+ [RFC2234] Crocker, D. and P. Overall, "Augmented BNF for Syntax
+ Specifications: ABNF", RFC 2234, November 1997.
+
+ [RFC2246] Dierks, T. and C. Allen, "The TLS Protocol", RFC 2246.
+ January 1999.
+
+ [RFC2396] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform
+ Resource Identifiers (URI): Generic Syntax", RFC 2396,
+ August 1998.
+
+ [RFC2565] Herriot, R., Butler, S., Moore, P. and R. Turner,
+ "Internet Printing Protocol/1.0: Encoding and Transport",
+ RFC 2565, April 1999.
+
+ [RFC2566] deBry, R., Hastings, T., Herriot, R., Isaacson, S. and P.
+ Powell, "Internet Printing Protocol/1.0: Model and
+ Semantics", RFC 2566, April 1999.
+
+ [RFC2567] Wright, D., "Design Goals for an Internet Printing
+ Protocol", RFC2567, April 1999.
+
+ [RFC2568] Zilles, S., "Rationale for the Structure and Model and
+ Protocol for the Internet Printing Protocol", RFC 2568,
+ April 1999.
+
+ [RFC2569] Herriot, R., Hastings, T., Jacobs, N. and J. Martin,
+ "Mapping between LPD and IPP Protocols", RFC 2569, April
+ 1999.
+
+ [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
+ Masinter, L., Leach, P. and T. Berners-Lee, "Hypertext
+ Transfer Protocol - HTTP/1.1", RFC 2616, June 1999.
+
+ [RFC2617] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S.,
+ Leach, P., Luotonen, A. and L. Stewart, "HTTP
+ Authentication: Basic and Digest Access Authentication",
+ RFC 2617, June 1999.
+
+
+
+Herriot, et al. Standards Track [Page 28]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ [RFC2817] Khare, R. and S. Lawrence, "Upgrading to TLS Within
+ HTTP/1.1", RFC 2817, May 2000.
+
+ [RFC2910] Herriot, R., Butler, S., Moore, P., Turner, R. and J.
+ Wenn, "Internet Printing Protocol/1.1: Encoding and
+ Transport", RFC 2910, September 2000.
+
+ [RFC2911] Hastings, T., Herriot, R., deBry, R., Isaacson, S. and P.
+ Powell, "Internet Printing Protocol/1.1: Model and
+ Semantics", RFC 2911, September 2000.
+
+ [SSL] Netscape, The SSL Protocol, Version 3, (Text version
+ 3.02), November 1996.
+
+11. Authors' Addresses
+
+ Robert Herriot, Editor
+ Xerox Corporation
+ 3400 Hillview Ave., Bldg #1
+ Palo Alto, CA 94304
+
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ EMail: robert.herriot@pahv.xerox.com
+
+
+ Sylvan Butler
+ Hewlett-Packard
+ 11311 Chinden Blvd.
+ Boise, ID 83714
+
+ Phone: 208-396-6000
+ Fax: 208-396-3457
+ EMail: sbutler@boi.hp.com
+
+
+ Paul Moore
+ Peerless Systems Networking
+ 10900 NE 8th St #900
+ Bellevue, WA 98004
+
+ Phone: 425-462-5852
+ EMail: pmoore@peerless.com
+
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 29]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Randy Turner
+ 2Wire, Inc.
+ 694 Tasman Dr.
+ Milpitas, CA 95035
+
+ Phone: 408-546-1273
+
+
+ John Wenn
+ Xerox Corporation
+ 737 Hawaii St
+ El Segundo, CA 90245
+
+ Phone: 310-333-5764
+ Fax: 310-333-5514
+ EMail: jwenn@cp10.es.xerox.com
+
+
+ IPP Web Page: http://www.pwg.org/ipp/
+ IPP Mailing List: ipp@pwg.org
+
+ To subscribe to the ipp mailing list, send the following email:
+ 1) send it to majordomo@pwg.org
+ 2) leave the subject line blank
+ 3) put the following two lines in the message body:
+ subscribe ipp
+ end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 30]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+12. Other Participants:
+
+ Chuck Adams - Tektronix Shivaun Albright - HP
+ Stefan Andersson - Axis Jeff Barnett - IBM
+ Ron Bergman - Hitachi Koki Imaging Dennis Carney - IBM
+ Systems
+ Keith Carter - IBM Angelo Caruso - Xerox
+ Rajesh Chawla - TR Computing Nancy Chen - Okidata
+ Solutions
+ Josh Cohen - Microsoft Jeff Copeland - QMS
+ Andy Davidson - Tektronix Roger deBry - IBM
+ Maulik Desai - Auco Mabry Dozier - QMS
+ Lee Farrell - Canon Information Satoshi Fujitami - Ricoh
+ Systems
+ Steve Gebert - IBM Sue Gleeson - Digital
+ Charles Gordon - Osicom Brian Grimshaw - Apple
+ Jerry Hadsell - IBM Richard Hart - Digital
+ Tom Hastings - Xerox Henrik Holst - I-data
+ Stephen Holmstead Zhi-Hong Huang - Zenographics
+ Scott Isaacson - Novell Babek Jahromi - Microsoft
+ Swen Johnson - Xerox David Kellerman - Northlake
+ Software
+ Robert Kline - TrueSpectra Charles Kong - Panasonic
+ Carl Kugler - IBM Dave Kuntz - Hewlett-Packard
+ Takami Kurono - Brother Rick Landau - Digital
+ Scott Lawrence - Agranot Systems Greg LeClair - Epson
+ Dwight Lewis - Lexmark Harry Lewis - IBM
+ Tony Liao - Vivid Image Roy Lomicka - Digital
+ Pete Loya - HP Ray Lutz - Cognisys
+ Mike MacKay - Novell, Inc. David Manchala - Xerox
+ Carl-Uno Manros - Xerox Jay Martin - Underscore
+ Stan McConnell - Xerox Larry Masinter - Xerox
+ Sandra Matts - Hewlett Packard Peter Michalek - Shinesoft
+ Ira McDonald - High North Inc. Mike Moldovan - G3 Nova
+ Tetsuya Morita - Ricoh Yuichi Niwa - Ricoh
+ Pat Nogay - IBM Ron Norton - Printronics
+ Hugo Parra, Novell Bob Pentecost - Hewlett-Packard
+ Patrick Powell - Astart Jeff Rackowitz - Intermec
+ Technologies
+ Eric Random - Peerless Rob Rhoads - Intel
+ Xavier Riley - Xerox Gary Roberts - Ricoh
+ David Roach - Unisys Stuart Rowley - Kyocera
+ Yuji Sasaki - Japan Computer Richard Schneider - Epson
+ Industry
+ Kris Schoff - HP Katsuaki Sekiguchi - Canon
+ Information Systems
+
+
+
+
+
+Herriot, et al. Standards Track [Page 31]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Bob Setterbo - Adobe Gail Songer - Peerless
+ Hideki Tanaka - Cannon Information Devon Taylor - Novell, Inc.
+ Systems
+ Mike Timperman - Lexmark Atsushi Uchino - Epson
+ Shigeru Ueda - Canon Bob Von Andel - Allegro Software
+ William Wagner - NetSilicon/DPI Jim Walker - DAZEL
+ Chris Wellens - Interworking Labs Trevor Wells - Hewlett Packard
+ Craig Whittle - Sharp Labs Rob Whittle - Novell, Inc.
+ Jasper Wong - Xionics Don Wright - Lexmark
+ Michael Wu - Heidelberg Digital Rick Yardumian - Xerox
+ Michael Yeung - Canon Information Lloyd Young - Lexmark
+ Systems
+ Atsushi Yuki - Kyocera Peter Zehler - Xerox
+ William Zhang - Canon Information Frank Zhao - Panasonic
+ Systems
+ Steve Zilles - Adobe Rob Zirnstein - Canon Information
+ Systems
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 32]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+13. Appendix A: Protocol Examples
+
+13.1 Print-Job Request
+
+ The following is an example of a Print-Job request with job-name,
+ copies, and sides specified. The "ipp-attribute-fidelity" attribute
+ is set to 'true' so that the print request will fail if the "copies"
+ or the "sides" attribute are not supported or their values are not
+ supported.
+
+ Octets Symbolic Value Protocol field
+
+ 0x0101 1.1 version-number
+ 0x0002 Print-Job operation-id
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- name
+ natural- attributes-natural-language
+ language
+ 0x0005 value-length
+ en-us en-US value
+ 0x45 uri type value-tag
+ 0x000B name-length
+ printer-uri printer-uri name
+ 0x0015 value-length
+ ipp://forest/ printer pinetree value
+ pinetree
+ 0x42 nameWithoutLanguage type value-tag
+ 0x0008 name-length
+ job-name job-name name
+ 0x0006 value-length
+ foobar foobar value
+ 0x22 boolean type value-tag
+ 0x0016 name-length
+ ipp-attribute- ipp-attribute-fidelity name
+ fidelity
+ 0x0001 value-length
+ 0x01 true value
+
+
+
+
+
+Herriot, et al. Standards Track [Page 33]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Octets Symbolic Value Protocol field
+
+ 0x02 start job-attributes job-attributes-tag
+ 0x21 integer type value-tag
+ 0x0006 name-length
+ copies copies name
+ 0x0004 value-length
+ 0x00000014 20 value
+ 0x44 keyword type value-tag
+ 0x0005 name-length
+ sides sides name
+ 0x0013 value-length
+ two-sided- two-sided-long-edge value
+ long-edge
+ 0x03 end-of-attributes end-of-attributes-tag
+ %!PS... <PostScript> data
+
+13.2 Print-Job Response (successful)
+
+ Here is an example of a successful Print-Job response to the previous
+ Print-Job request. The printer supported the "copies" and "sides"
+ attributes and their supplied values. The status code returned is
+ 'successful-ok'.
+
+ Octets Symbolic Value Protocol field
+
+ 0x0101 1.1 version-number
+ 0x0000 successful-ok status-code
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural- name
+ natural-language language
+ 0x0005 value-length
+ en-us en-US value
+ 0x41 textWithoutLanguage type value-tag
+ 0x000E name-length
+ status-message status-message name
+ 0x000D value-length
+
+
+
+
+
+Herriot, et al. Standards Track [Page 34]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Octets Symbolic Value Protocol field
+
+ successful-ok successful-ok value
+ 0x02 start job-attributes job-attributes-tag
+ 0x21 integer value-tag
+ 0x0006 name-length
+ job-id job-id name
+ 0x0004 value-length
+ 147 147 value
+ 0x45 uri type value-tag
+ 0x0007 name-length
+ job-uri job-uri name
+ 0x0019 value-length
+ ipp://forest/ job 123 on pinetree value
+ pinetree/123
+ 0x23 enum type value-tag
+ 0x0009 name-length
+ job-state job-state name
+ 0x0004 value-length
+ 0x0003 pending value
+ 0x03 end-of-attributes end-of-attributes-tag
+
+13.3 Print-Job Response (failure)
+
+ Here is an example of an unsuccessful Print-Job response to the
+ previous Print-Job request. It fails because, in this case, the
+ printer does not support the "sides" attribute and because the value
+ '20' for the "copies" attribute is not supported. Therefore, no job
+ is created, and neither a "job-id" nor a "job-uri" operation
+ attribute is returned. The error code returned is 'client-error-
+ attributes-or-values-not-supported' (0x040B).
+
+ 0x0101 1.1 version-number
+ 0x040B client-error-attributes-or- status-code
+ values-not-supported
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attributes tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 35]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Octets Symbolic Value Protocol field
+
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural-language name
+ natural-
+ language
+ 0x0005 value-length
+ en-us en-US value
+ 0x41 textWithoutLanguage type value-tag
+ 0x000E name-length
+ status- status-message name
+ message
+ 0x002F value-length
+ client-error- value
+ attributes- values-not-supported
+ or-values- client-error-attributes-or-
+ not-supported
+ 0x05 start unsupported-attributes unsupported-attributes tag
+ 0x21 integer type value-tag
+ 0x0006 name-length
+ copies copies name
+ 0x0004 value-length
+ 0x00000014 20 value
+ 0x10 unsupported (type) value-tag
+ 0x0005 name-length
+ sides sides name
+ 0x0000 value-length
+ 0x03 end-of-attributes end-of-attributes-tag
+
+13.4 Print-Job Response (success with attributes ignored)
+
+ Here is an example of a successful Print-Job response to a Print-Job
+ request like the previous Print-Job request, except that the value of
+ 'ipp-attribute-fidelity' is false. The print request succeeds, even
+ though, in this case, the printer supports neither the "sides"
+ attribute nor the value '20' for the "copies" attribute. Therefore, a
+ job is created, and both a "job-id" and a "job-uri" operation
+ attribute are returned. The unsupported attributes are also returned
+ in an Unsupported Attributes Group. The error code returned is
+ 'successful-ok-ignored-or-substituted-attributes' (0x0001).
+
+ Octets Symbolic Value Protocol field
+
+ 0x0101 1.1 version-number
+ 0x0001 successful-ok-ignored-or- status-code
+
+
+
+
+
+Herriot, et al. Standards Track [Page 36]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Octets Symbolic Value Protocol field
+
+ substituted-attributes
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural- name
+ natural-language language
+ 0x0005 value-length
+ en-us en-US value
+ 0x41 textWithoutLanguage type value-tag
+ 0x000E name-length
+ status-message status-message name
+ 0x002F value-length
+ successful-ok- successful-ok-ignored-or- value
+ ignored-or- substituted-attributes
+ substituted-
+ attributes
+ 0x05 start unsupported- unsupported-attributes
+ attributes tag
+ 0x21 integer type value-tag
+ 0x0006 name-length
+ copies copies name
+ 0x0004 value-length
+ 0x00000014 20 value
+ 0x10 unsupported (type) value-tag
+ 0x0005 name-length
+ sides sides name
+ 0x0000 value-length
+ 0x02 start job-attributes job-attributes-tag
+ 0x21 integer value-tag
+ 0x0006 name-length
+ job-id job-id name
+ 0x0004 value-length
+ 147 147 value
+ 0x45 uri type value-tag
+ 0x0007 name-length
+ job-uri job-uri name
+ 0x0019 value-length
+ ipp://forest/ job 123 on pinetree value
+ pinetree/123
+
+
+
+Herriot, et al. Standards Track [Page 37]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Octets Symbolic Value Protocol field
+
+ 0x23 enum type value-tag
+ 0x0009 name-length
+ job-state job-state name
+ 0x0004 value-length
+ 0x0003 pending value
+ 0x03 end-of-attributes end-of-attributes-tag
+
+13.5 Print-URI Request
+
+ The following is an example of Print-URI request with copies and
+ job-name parameters:
+
+ Octets Symbolic Value Protocol field
+
+ 0x0101 1.1 version-number
+ 0x0003 Print-URI operation-id
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural-language name
+ natural-
+ language
+ 0x0005 value-length
+ en-us en-US value
+ 0x45 uri type value-tag
+ 0x000B name-length
+ printer-uri printer-uri name
+ 0x0015 value-length
+ ipp://forest/ printer pinetree value
+ pinetree
+ 0x45 uri type value-tag
+ 0x000C name-length
+ document-uri document-uri name
+ 0x0011 value-length
+ ftp://foo.com ftp://foo.com/foo value
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 38]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Octets Symbolic Value Protocol field
+
+ /foo
+ 0x42 nameWithoutLanguage type value-tag
+ 0x0008 name-length
+ job-name job-name name
+ 0x0006 value-length
+ foobar foobar value
+ 0x02 start job-attributes job-attributes-tag
+ 0x21 integer type value-tag
+ 0x0006 name-length
+ copies copies name
+ 0x0004 value-length
+ 0x00000001 1 value
+ 0x03 end-of-attributes end-of-attributes-tag
+
+13.6 Create-Job Request
+
+ The following is an example of Create-Job request with no parameters
+ and no attributes:
+
+ Octets Symbolic Value Protocol field
+
+ 0x0101 1.1 version-number
+ 0x0005 Create-Job operation-id
+ 0x00000001 1 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural-language name
+ natural-
+ language
+ 0x0005 value-length
+ en-us en-US value
+ 0x45 uri type value-tag
+ 0x000B name-length
+ printer-uri printer-uri name
+ 0x0015 value-length
+ ipp://forest/ printer pinetree value
+ pinetree
+
+
+
+
+
+Herriot, et al. Standards Track [Page 39]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Octets Symbolic Value Protocol field
+
+ inetree
+ 0x03 end-of-attributes end-of-attributes-tag
+
+13.7 Get-Jobs Request
+
+ The following is an example of Get-Jobs request with parameters but
+ no attributes:
+
+ Octets Symbolic Value Protocol field
+
+ 0x0101 1.1 version-number
+ 0x000A Get-Jobs operation-id
+ 0x00000123 0x123 request-id
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x0008 value-length
+ us-ascii US-ASCII value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural-language name
+ natural-
+ language
+ 0x0005 value-length
+ en-us en-US value
+ 0x45 uri type value-tag
+ 0x000B name-length
+ printer-uri printer-uri name
+ 0x0015 value-length
+ ipp://forest/ printer pinetree value
+ pinetree
+ 0x21 integer type value-tag
+ 0x0005 name-length
+ limit limit name
+ 0x0004 value-length
+ 0x00000032 50 value
+ 0x44 keyword type value-tag
+ 0x0014 name-length
+ requested- requested-attributes name
+ attributes
+ 0x0006 value-length
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 40]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Octets Symbolic Value Protocol field
+
+ job-id job-id value
+ 0x44 keyword type value-tag
+ 0x0000 additional value name-length
+ 0x0008 value-length
+ job-name job-name value
+ 0x44 keyword type value-tag
+ 0x0000 additional value name-length
+ 0x000F value-length
+ document-format document-format value
+ 0x03 end-of-attributes end-of-attributes-tag
+
+13.8 Get-Jobs Response
+
+ The following is an of Get-Jobs response from previous request with 3
+ jobs. The Printer returns no information about the second job
+ (because of security reasons):
+
+ Octets Symbolic Value Protocol field
+
+ 0x0101 1.1 version-number
+ 0x0000 successful-ok status-code
+ 0x00000123 0x123 request-id (echoed
+ back)
+ 0x01 start operation-attributes operation-attributes-tag
+ 0x47 charset type value-tag
+ 0x0012 name-length
+ attributes- attributes-charset name
+ charset
+ 0x000A value-length
+ ISO-8859-1 ISO-8859-1 value
+ 0x48 natural-language type value-tag
+ 0x001B name-length
+ attributes- attributes-natural-language name
+ natural-
+ language
+ 0x0005 value-length
+ en-us en-US value
+ 0x41 textWithoutLanguage type value-tag
+ 0x000E name-length
+ status-message status-message name
+ 0x000D value-length
+ successful-ok successful-ok value
+ 0x02 start job-attributes (1st job-attributes-tag
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 41]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Octets Symbolic Value Protocol field
+
+ object)
+ 0x21 integer type value-tag
+ 0x0006 name-length
+ job-id job-id name
+ 0x0004 value-length
+ 147 147 value
+ 0x36 nameWithLanguage value-tag
+ 0x0008 name-length
+ job-name job-name name
+ 0x000C value-length
+ 0x0005 sub-value-length
+ fr-ca fr-CA value
+ 0x0003 sub-value-length
+ fou fou name
+ 0x02 start job-attributes (2nd job-attributes-tag
+ object)
+ 0x02 start job-attributes (3rd job-attributes-tag
+ object)
+ 0x21 integer type value-tag
+ 0x0006 name-length
+ job-id job-id name
+ 0x0004 value-length
+ 148 149 value
+ 0x36 nameWithLanguage value-tag
+ 0x0008 name-length
+ job-name job-name name
+ 0x0012 value-length
+ 0x0005 sub-value-length
+ de-CH de-CH value
+ 0x0009 sub-value-length
+ isch guet isch guet name
+ 0x03 end-of-attributes end-of-attributes-tag
+
+14. Appendix B: Registration of MIME Media Type Information for
+ "application/ipp"
+
+ This appendix contains the information that IANA requires for
+ registering a MIME media type. The information following this
+ paragraph will be forwarded to IANA to register application/ipp whose
+ contents are defined in Section 3 "Encoding of the Operation Layer"
+ in this document:
+
+ MIME type name: application
+
+ MIME subtype name: ipp
+
+
+
+
+Herriot, et al. Standards Track [Page 42]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ A Content-Type of "application/ipp" indicates an Internet Printing
+ Protocol message body (request or response). Currently there is one
+ version: IPP/1.1, whose syntax is described in Section 3 "Encoding of
+ the Operation Layer" of [RFC2910], and whose semantics are described
+ in [RFC2911].
+
+ Required parameters: none
+
+ Optional parameters: none
+
+ Encoding considerations:
+
+ IPP/1.1 protocol requests/responses MAY contain long lines and ALWAYS
+ contain binary data (for example attribute value lengths).
+
+ Security considerations:
+
+ IPP/1.1 protocol requests/responses do not introduce any security
+ risks not already inherent in the underlying transport protocols.
+ Protocol mixed-version interworking rules in [RFC2911] as well as
+ protocol encoding rules in [RFC2910] are complete and unambiguous.
+
+ Interoperability considerations:
+
+ IPP/1.1 requests (generated by clients) and responses (generated by
+ servers) MUST comply with all conformance requirements imposed by the
+ normative specifications [RFC2911] and [RFC2910]. Protocol encoding
+ rules specified in [RFC2910] are comprehensive, so that
+ interoperability between conforming implementations is guaranteed
+ (although support for specific optional features is not ensured).
+ Both the "charset" and "natural-language" of all IPP/1.1 attribute
+ values which are a LOCALIZED-STRING are explicit within IPP protocol
+ requests/responses (without recourse to any external information in
+ HTTP, SMTP, or other message transport headers).
+
+ Published specifications:
+
+ [RFC2911] Hastings, T., Herriot, R., deBry, R., Isaacson, S. and P.
+ Powell, "Internet Printing Protocol/1.1: Model and
+ Semantics", RFC 2911, September 2000.
+
+ [RFC2910] Herriot, R., Butler, S., Moore, P., Turner, R. and J.
+ Wenn, "Internet Printing Protocol/1.1: Encoding and
+ Transport", RFC 2910, September 2000.
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 43]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ Applications which use this media type:
+
+ Internet Printing Protocol (IPP) print clients and print servers,
+ communicating using HTTP/1.1 (see [RFC2910]), SMTP/ESMTP, FTP, or
+ other transport protocol. Messages of type "application/ipp" are
+ self-contained and transport-independent, including "charset" and
+ "natural-language" context for any LOCALIZED-STRING value.
+
+ Person & email address to contact for further information:
+
+ Tom Hastings
+ Xerox Corporation
+ 737 Hawaii St. ESAE-231
+ El Segundo, CA
+
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ EMail: hastings@cp10.es.xerox.com
+
+ or
+
+ Robert Herriot
+ Xerox Corporation
+ 3400 Hillview Ave., Bldg #1
+ Palo Alto, CA 94304
+
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ EMail: robert.herriot@pahv.xerox.com
+
+ Intended usage:
+
+ COMMON
+
+15. Appendix C: Changes from IPP/1.0
+
+ IPP/1.1 is identical to IPP/1.0 [RFC2565] with the follow changes:
+
+ 1. Attributes values that identify a printer or job object use a new
+ 'ipp' scheme. The 'http' and 'https' schemes are supported only
+ for backward compatibility. See section 5.
+
+ 2. Clients MUST support of Digest Authentication, IPP Printers SHOULD
+ support Digest Authentication. See Section 8.1.1
+
+ 3. TLS is recommended for channel security. In addition, SSL3 may be
+ supported for backward compatibility. See Section 8.1.2
+
+
+
+
+Herriot, et al. Standards Track [Page 44]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+ 4. It is recommended that IPP/1.1 objects accept any request with
+ major version number '1'. See section 9.1.
+
+ 5. IPP objects SHOULD return the URL scheme requested for "job-
+ printer-uri" and "job-uri" Job Attributes, rather than the URL
+ scheme used to create the job. See section 9.2.
+
+ 6. The IANA and Internationalization sections have been added. The
+ terms "private use" and "experimental" have been changed to
+ "vendor extension". The reserved allocations for attribute group
+ tags, attribute syntax tags, and out-of-band attribute values have
+ been clarified as to which are reserved to future IETF standards
+ track documents and which are reserved to vendor extension. Both
+ kinds of extensions use the type2 registration procedures as
+ defined in [RFC2911].
+
+ 7. Clarified that future "out-of-band" value definitions may use the
+ value field if additional information is needed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 45]
+
+RFC 2910 IPP/1.1: Encoding and Transport September 2000
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Herriot, et al. Standards Track [Page 46]
+
diff --git a/standards/rfc2911.txt b/standards/rfc2911.txt
new file mode 100644
index 000000000..29c85a426
--- /dev/null
+++ b/standards/rfc2911.txt
@@ -0,0 +1,12547 @@
+
+
+
+
+
+
+Network Working Group T. Hastings, Editor
+Request for Comments: 2911 R. Herriot
+Obsoletes: 2566 Xerox Corporation
+Category: Standards Track R. deBry
+ Utah Valley State College
+ S. Isaacson
+ Novell, Inc.
+ P. Powell
+ Astart Technologies
+ September 2000
+
+
+ Internet Printing Protocol/1.1: Model and Semantics
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+Abstract
+
+ This document is one of a set of documents, which together describe
+ all aspects of a new Internet Printing Protocol (IPP). IPP is an
+ application level protocol that can be used for distributed printing
+ using Internet tools and technologies. This document describes a
+ simplified model consisting of abstract objects, their attributes,
+ and their operations that is independent of encoding and transport.
+ The model consists of a Printer and a Job object. A Job optionally
+ supports multiple documents. IPP 1.1 semantics allow end-users and
+ operators to query printer capabilities, submit print jobs, inquire
+ about the status of print jobs and printers, cancel, hold, release,
+ and restart print jobs. IPP 1.1 semantics allow operators to pause,
+ resume, and purge (jobs from) Printer objects. This document also
+ addresses security, internationalization, and directory issues.
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 1]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics (this document)
+ Internet Printing Protocol/1.1: Encoding and Transport [RFC2910]
+ Internet Printing Protocol/1.1: Implementer's Guide [IPP-IIG]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ The "Design Goals for an Internet Printing Protocol" document takes a
+ broad look at distributed printing functionality, and it enumerates
+ real-life scenarios that help to clarify the features that need to be
+ included in a printing protocol for the Internet. It identifies
+ requirements for three types of users: end users, operators, and
+ administrators. It calls out a subset of end user requirements that
+ are satisfied in IPP/1.0. A few OPTIONAL operator operations have
+ been added to IPP/1.1.
+
+ The "Rationale for the Structure and Model and Protocol for the
+ Internet Printing Protocol" document describes IPP from a high level
+ view, defines a roadmap for the various documents that form the suite
+ of IPP specification documents, and gives background and rationale
+ for the IETF working group's major decisions.
+
+ The "Internet Printing Protocol/1.1: Encoding and Transport" document
+ is a formal mapping of the abstract operations and attributes defined
+ in the model document onto HTTP/1.1 [RFC2616]. It defines the
+ encoding rules for a new Internet MIME media type called
+ "application/ipp". This document also defines the rules for
+ transporting over HTTP a message body whose Content-Type is
+ "application/ipp". This document defines a new scheme named 'ipp'
+ for identifying IPP printers and jobs.
+
+ The "Internet Printing Protocol/1.1: Implementer's Guide" document
+ gives insight and advice to implementers of IPP clients and IPP
+ objects. It is intended to help them understand IPP/1.1 and some of
+ the considerations that may assist them in the design of their client
+ and/or IPP object implementations. For example, a typical order of
+ processing requests is given, including error checking. Motivation
+ for some of the specification decisions is also included.
+
+ The "Mapping between LPD and IPP Protocols" document gives some
+ advice to implementers of gateways between IPP and LPD (Line Printer
+ Daemon) implementations.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 2]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+Table of Contents
+
+ 1. Introduction 9
+ 1.1 Simplified Printing Model 10
+ 2. IPP Objects 12
+ 2.1 Printer Object 13
+ 2.2 Job Object 15
+ 2.3 Object Relationships 16
+ 2.4 Object Identity 17
+ 3. IPP Operations 20
+ 3.1 Common Semantics 21
+ 3.1.1 Required Parameters 21
+ 3.1.2 Operation IDs and Request IDs 22
+ 3.1.3 Attributes 22
+ 3.1.4 Character Set and Natural Language Operation Attribute 24
+ 3.1.4.1 Request Operation Attributes 25
+ 3.1.4.2 Response Operation Attributes 29
+ 3.1.5 Operation Targets 30
+ 3.1.6 Operation Response Status Codes and Status Messages 32
+ 3.1.6.1 "status-code" (type2 enum) 32
+ 3.1.6.2 "status-message" (text(255)) 33
+ 3.1.6.3 "detailed-status-message" (text(MAX)) 33
+ 3.1.6.4 "document-access-error" (text(MAX)) 34
+ 3.1.7 Unsupported Attributes 34
+ 3.1.8 Versions 36
+ 3.1.9 Job Creation Operations 38
+ 3.2 Printer Operations 41
+ 3.2.1 Print-Job Operation 41
+ 3.2.1.1 Print-Job Request 41
+ 3.2.1.2 Print-Job Response 46
+ 3.2.2 Print-URI Operation 48
+ 3.2.3 Validate-Job Operation 49
+ 3.2.4 Create-Job Operation 49
+ 3.2.5 Get-Printer-Attributes Operation 50
+ 3.2.5.1 Get-Printer-Attributes Request 51
+ 3.2.5.2 Get-Printer-Attributes Response 53
+ 3.2.6 Get-Jobs Operation 54
+ 3.2.6.1 Get-Jobs Request 54
+ 3.2.6.2 Get-Jobs Response 56
+ 3.2.7 Pause-Printer Operation 57
+ 3.2.7.1 Pause-Printer Request 59
+ 3.2.7.2 Pause-Printer Response 60
+ 3.2.8 Resume-Printer Operation 60
+ 3.2.9 Purge-Jobs Operation 61
+ 3.3 Job Operations 62
+ 3.3.1 Send-Document Operation 62
+ 3.3.1.1 Send-Document Request 64
+ 3.3.1.2 Send-Document Response 65
+
+
+
+Hastings, et al. Standards Track [Page 3]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 3.3.2 Send-URI Operation 66
+ 3.3.3 Cancel-Job Operation 66
+ 3.3.3.1 Cancel-Job Request 67
+ 3.3.3.2 Cancel-Job Response 68
+ 3.3.4 Get-Job-Attributes Operation 69
+ 3.3.4.1 Get-Job-Attributes Request 69
+ 3.3.4.2 Get-Job-Attributes Response 70
+ 3.3.5 Hold-Job Operation 71
+ 3.3.5.1 Hold-Job Request 72
+ 3.3.5.2 Hold-Job Response 73
+ 3.3.6 Release-Job Operation 74
+ 3.3.7 Restart-Job Operation 75
+ 3.3.7.1 Restart-Job Request 76
+ 3.3.7.2 Restart-Job Response 78
+ 4. Object Attributes 78
+ 4.1 Attribute Syntaxes 78
+ 4.1.1 'text' 79
+ 4.1.1.1 'textWithoutLanguage' 80
+ 4.1.1.2 'textWithLanguage' 80
+ 4.1.2 'name' 81
+ 4.1.2.1 'nameWithoutLanguage' 82
+ 4.1.2.2 'nameWithLanguage' 82
+ 4.1.2.3 Matching 'name' attribute values 83
+ 4.1.3 'keyword' 84
+ 4.1.4 'enum' 85
+ 4.1.5 'uri' 85
+ 4.1.6 'uriScheme' 86
+ 4.1.7 'charset' 86
+ 4.1.8 'naturalLanguage' 87
+ 4.1.9 'mimeMediaType' 87
+ 4.1.9.1 Application/octet-stream -- Auto-Sensing 88
+ the document format
+ 4.1.10 'octetString' 89
+ 4.1.11 'boolean' 89
+ 4.1.12 'integer' 89
+ 4.1.13 'rangeOfInteger' 90
+ 4.1.14 'dateTime' 90
+ 4.1.15 'resolution' 90
+ 4.1.16 '1setOf X' 90
+ 4.2 Job Template Attributes 91
+ 4.2.1 job-priority (integer(1:100)) 94
+ 4.2.2 job-hold-until (type3 keyword | name (MAX)) 95
+ 4.2.3 job-sheets (type3 keyword | name(MAX)) 96
+ 4.2.4 multiple-document-handling (type2 keyword) 96
+ 4.2.5 copies (integer(1:MAX)) 98
+ 4.2.6 finishings (1setOf type2 enum) 98
+ 4.2.7 page-ranges (1setOf rangeOfInteger (1:MAX)) 101
+ 4.2.8 sides (type2 keyword) 102
+
+
+
+Hastings, et al. Standards Track [Page 4]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 4.2.9 number-up (integer(1:MAX)) 102
+ 4.2.10 orientation-requested (type2 enum) 103
+ 4.2.11 media (type3 keyword | name(MAX)) 104
+ 4.2.12 printer-resolution (resolution) 105
+ 4.2.13 print-quality (type2 enum) 105
+ 4.3 Job Description Attributes 106
+ 4.3.1 job-uri (uri) 107
+ 4.3.2 job-id (integer(1:MAX)) 108
+ 4.3.3 job-printer-uri (uri) 108
+ 4.3.4 job-more-info (uri) 108
+ 4.3.5 job-name (name(MAX)) 108
+ 4.3.6 job-originating-user-name (name(MAX)) 109
+ 4.3.7 job-state (type1 enum) 109
+ 4.3.7.1 Forwarding Servers 112
+ 4.3.7.2 Partitioning of Job States 112
+ 4.3.8 job-state-reasons (1setOf type2 keyword) 113
+ 4.3.9 job-state-message (text(MAX)) 118
+ 4.3.10 job-detailed-status-messages (1setOf text(MAX)) 118
+ 4.3.11 job-document-access-errors (1setOf text(MAX)) 118
+ 4.3.12 number-of-documents (integer(0:MAX)) 119
+ 4.3.13 output-device-assigned (name(127)) 119
+ 4.3.14 Event Time Job Description Attributes 119
+ 4.3.14.1 time-at-creation (integer(MIN:MAX)) 120
+ 4.3.14.2 time-at-processing (integer(MIN:MAX)) 120
+ 4.3.14.3 time-at-completed (integer(MIN:MAX)) 120
+ 4.3.14.4 job-printer-up-time (integer(1:MAX)) 120
+ 4.3.14.5 date-time-at-creation (dateTime) 121
+ 4.3.14.6 date-time-at-processing (dateTime) 121
+ 4.3.14.7 date-time-at-completed (dateTime) 121
+ 4.3.15 number-of-intervening-jobs (integer(0:MAX)) 121
+ 4.3.16 job-message-from-operator (text(127)) 121
+ 4.3.17 Job Size Attributes 121
+ 4.3.17.1 job-k-octets (integer(0:MAX)) 122
+ 4.3.17.2 job-impressions (integer(0:MAX)) 122
+ 4.3.17.3 job-media-sheets (integer(0:MAX)) 123
+ 4.3.18 Job Progress Attributes 123
+ 4.3.18.1 job-k-octets-processed (integer(0:MAX)) 123
+ 4.3.18.2 job-impressions-completed (integer(0:MAX)) 123
+ 4.3.18.3 job-media-sheets-completed (integer(0:MAX)) 124
+ 4.3.19 attributes-charset (charset) 124
+ 4.3.20 attributes-natural-language (naturalLanguage) 124
+ 4.4 Printer Description Attributes 124
+ 4.4.1 printer-uri-supported (1setOf uri) 126
+ 4.4.2 uri-authentication-supported (1setOf type2 keyword) 127
+ 4.4.3 uri-security-supported (1setOf type2 keyword) 128
+ 4.4.4 printer-name (name(127)) 129
+ 4.4.5 printer-location (text(127)) 129
+ 4.4.6 printer-info (text(127)) 130
+
+
+
+Hastings, et al. Standards Track [Page 5]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 4.4.7 printer-more-info (uri) 130
+ 4.4.8 printer-driver-installer (uri) 130
+ 4.4.9 printer-make-and-model (text(127)) 130
+ 4.4.10 printer-more-info-manufacturer (uri) 130
+ 4.4.11 printer-state (type1 enum) 131
+ 4.4.12 printer-state-reasons (1setOf type2 keyword) 131
+ 4.4.13 printer-state-message (text(MAX)) 134
+ 4.4.14 ipp-versions-supported (1setOf type2 keyword) 134
+ 4.4.15 operations-supported (1setOf type2 enum) 135
+ 4.4.16 multiple-document-jobs-supported (boolean) 136
+ 4.4.17 charset-configured (charset) 136
+ 4.4.18 charset-supported (1setOf charset) 137
+ 4.4.19 natural-language-configured (naturalLanguage) 137
+ 4.4.20 generated-natural-language-supported
+ (1setOf naturalLanguage) 137
+ 4.4.21 document-format-default (mimeMediaType) 138
+ 4.4.22 document-format-supported (1setOf mimeMediaType) 138
+ 4.4.23 printer-is-accepting-jobs (boolean) 138
+ 4.4.24 queued-job-count (integer(0:MAX)) 138
+ 4.4.25 printer-message-from-operator (text(127)) 139
+ 4.4.26 color-supported (boolean) 139
+ 4.4.27 reference-uri-schemes-supported (1setOf uriScheme) 139
+ 4.4.28 pdl-override-supported (type2 keyword) 139
+ 4.4.29 printer-up-time (integer(1:MAX)) 140
+ 4.4.30 printer-current-time (dateTime) 140
+ 4.4.31 multiple-operation-time-out (integer(1:MAX)) 141
+ 4.4.32 compression-supported (1setOf type3 keyword) 141
+ 4.4.33 job-k-octets-supported (rangeOfInteger(0:MAX)) 142
+ 4.4.34 job-impressions-supported (rangeOfInteger(0:MAX)) 142
+ 4.4.35 job-media-sheets-supported (rangeOfInteger(0:MAX)) 142
+ 4.4.36 pages-per-minute (integer(0:MAX)) 142
+ 4.4.37 pages-per-minute-color (integer(0:MAX)) 142
+ 5. Conformance 143
+ 5.1 Client Conformance Requirements 143
+ 5.2 IPP Object Conformance Requirements 145
+ 5.2.1 Objects 145
+ 5.2.2 Operations 145
+ 5.2.3 IPP Object Attributes 146
+ 5.2.4 Versions 146
+ 5.2.5 Extensions 147
+ 5.2.6 Attribute Syntaxes 147
+ 5.2.7 Security 148
+ 5.3 Charset and Natural Language Requirements 148
+ 6. IANA Considerations 148
+ 6.1 Typed 'keyword' and 'enum' Extensions 149
+ 6.2 Attribute Extensibility 151
+ 6.3 Attribute Syntax Extensibility 152
+ 6.4 Operation Extensibility 152
+
+
+
+Hastings, et al. Standards Track [Page 6]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 6.5 Attribute Group Extensibility 153
+ 6.6 Status Code Extensibility 153
+ 6.7 Out-of-band Attribute Value Extensibility 154
+ 6.8 Registration of MIME types/sub-types for document-formats 154
+ 6.9 Registration of charsets for use in 'charset'
+ attribute values 154
+ 7. Internationalization Considerations 154
+ 8. Security Considerations 158
+ 8.1 Security Scenarios 159
+ 8.1.1 Client and Server in the Same Security Domain 159
+ 8.1.2 Client and Server in Different Security Domains 159
+ 8.1.3 Print by Reference 160
+ 8.2 URIs in Operation, Job, and Printer attributes 160
+ 8.3 URIs for each authentication mechanisms 160
+ 8.4 Restricted Queries 161
+ 8.5 Operations performed by operators and system
+ administrators 161
+ 8.6 Queries on jobs submitted using non-IPP protocols 162
+ 9. References 162
+ 10. Authors' Addresses 166
+ 11. Formats for IPP Registration Proposals 168
+ 11.1 Type2 keyword attribute values registration 169
+ 11.2 Type3 keyword attribute values registration 169
+ 11.3 Type2 enum attribute values registration 169
+ 11.4 Type3 enum attribute values registration 170
+ 11.5 Attribute registration 170
+ 11.6 Attribute Syntax registration 171
+ 11.7 Operation registration 171
+ 11.8 Attribute Group registration 171
+ 11.9 Status code registration 172
+ 11.10 Out-of-band Attribute Value registration 172
+ 12. APPENDIX A: Terminology 173
+ 12.1 Conformance Terminology 173
+ 12.1.1 NEED NOT 173
+ 12.2 Model Terminology 173
+ 12.2.1 Keyword 173
+ 12.2.2 Attributes 173
+ 12.2.2.1 Attribute Name 173
+ 12.2.2.2 Attribute Group Name 174
+ 12.2.2.3 Attribute Value 174
+ 12.2.2.4 Attribute Syntax 174
+ 12.2.3 Supports 174
+ 12.2.4 print-stream page 176
+ 12.2.5 impression 177
+ 13. APPENDIX B: Status Codes and Suggested Status Code Messages 177
+ 13.1 Status Codes 178
+ 13.1.1 Informational 178
+ 13.1.2 Successful Status Codes 178
+
+
+
+Hastings, et al. Standards Track [Page 7]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 13.1.2.1 successful-ok (0x0000) 178
+ 13.1.2.2 successful-ok-ignored-or-substituted-attributes
+ (0x0001) 179
+ 13.1.2.3 successful-ok-conflicting-attributes (0x0002) 179
+ 13.1.3 Redirection Status Codes 179
+ 13.1.4 Client Error Status Codes 179
+ 13.1.4.1 client-error-bad-request (0x0400) 180
+ 13.1.4.2 client-error-forbidden (0x0401) 180
+ 13.1.4.3 client-error-not-authenticated (0x0402) 180
+ 13.1.4.4 client-error-not-authorized (0x0403) 180
+ 13.1.4.5 client-error-not-possible (0x0404) 180
+ 13.1.4.6 client-error-timeout (0x0405) 181
+ 13.1.4.7 client-error-not-found (0x0406) 181
+ 13.1.4.8 client-error-gone (0x0407) 181
+ 13.1.4.9 client-error-request-entity-too-large (0x0408) 182
+ 13.1.4.10 client-error-request-value-too-long (0x0409) 182
+ 13.1.4.11 client-error-document-format-not-supported (0x040A) 182
+ 13.1.4.12 client-error-attributes-or-values-not-supported
+ (0x040B) 183
+ 13.1.4.13 client-error-uri-scheme-not-supported (0x040C) 183
+ 13.1.4.14 client-error-charset-not-supported (0x040D) 183
+ 13.1.4.15 client-error-conflicting-attributes (0x040E) 183
+ 13.1.4.16 client-error-compression-not-supported (0x040F) 184
+ 13.1.4.17 client-error-compression-error (0x0410) 184
+ 13.1.4.18 client-error-document-format-error (0x0411) 184
+ 13.1.4.19 client-error-document-access-error (0x0412) 184
+ 13.1.5 Server Error Status Codes 185
+ 13.1.5.1 server-error-internal-error (0x0500) 185
+ 13.1.5.2 server-error-operation-not-supported (0x0501) 185
+ 13.1.5.3 server-error-service-unavailable (0x0502) 185
+ 13.1.5.4 server-error-version-not-supported (0x0503) 185
+ 13.1.5.5 server-error-device-error (0x0504) 186
+ 13.1.5.6 server-error-temporary-error (0x0505) 186
+ 13.1.5.7 server-error-not-accepting-jobs (0x0506) 187
+ 13.1.5.8 server-error-busy (0x0507) 187
+ 13.1.5.9 server-error-job-canceled (0x0508) 187
+ 13.1.5.10 server-error-multiple-document-jobs-not-supported
+ (0x0509) 187
+ 13.2 Status Codes for IPP Operations 187
+ 14. APPENDIX C: "media" keyword values 190
+ 15. APPENDIX D: Processing IPP Attributes 208
+ 15.1 Fidelity 209
+ 15.2 Page Description Language (PDL) Override 210
+ 15.3 Using Job Template Attributes During Document Processing 212
+ 16. APPENDIX E: Generic Directory Schema 214
+ 17. APPENDIX F: Differences between the IPP/1.0 and IPP/1.1
+ "Model and Semantics" Documents 215
+ 18. Full Copyright Statement 224
+
+
+
+Hastings, et al. Standards Track [Page 8]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+1. Introduction
+
+ The Internet Printing Protocol (IPP) is an application level protocol
+ that can be used for distributed printing using Internet tools and
+ technologies. IPP version 1.1 (IPP/1.1) focuses primarily on end
+ user functionality with a few administrative operations included.
+ This document is just one of a suite of documents that fully define
+ IPP. The full set of IPP documents includes:
+
+ Design Goals for an Internet Printing Protocol [RFC2567]
+ Rationale for the Structure and Model and Protocol for the Internet
+ Printing Protocol [RFC2568]
+ Internet Printing Protocol/1.1: Model and Semantics (this document)
+ Internet Printing Protocol/1.1: Encoding and Transport [RFC2910]
+ Internet Printing Protocol/1.1: Implementer's Guide [IPP-IIG]
+ Mapping between LPD and IPP Protocols [RFC2569]
+
+ Anyone reading these documents for the first time is strongly
+ encouraged to read the IPP documents in the above order.
+
+ This document is laid out as follows:
+
+ - The rest of Section 1 is an introduction to the IPP simplified
+ model for distributed printing.
+ - Section 2 introduces the object types covered in the model with
+ their basic behaviors, attributes, and interactions.
+ - Section 3 defines the operations included in IPP/1.1. IPP
+ operations are synchronous, therefore, for each operation, there is
+ a both request and a response.
+ - Section 4 defines the attributes (and their syntaxes) that are used
+ in the model.
+ - Sections 5 - 6 summarizes the implementation conformance
+ requirements for objects that support the protocol and IANA
+ considerations, respectively.
+ - Sections 7 - 11 cover the Internationalization and Security
+ considerations as well as References, Author contact information,
+ and Formats for Registration Proposals.
+ - Sections 12 - 14 are appendices that cover Terminology, Status
+ Codes and Messages, and "media" keyword values.
+
+ Note: This document uses terms such as "attributes", "keywords",
+ and "support". These terms have special meaning and are defined
+ in the model terminology section 12.2. Capitalized terms, such
+ as MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, MAY, NEED NOT,
+ and OPTIONAL, have special meaning relating to conformance.
+ These terms are defined in section 12.1 on conformance
+ terminology, most of which is taken from RFC 2119 [RFC2119].
+
+
+
+
+Hastings, et al. Standards Track [Page 9]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ - Section 15 is an appendix that helps to clarify the effects of
+ interactions between related attributes and their values.
+ - Section 16 is an appendix that enumerates the subset of Printer
+ attributes that form a generic directory schema. These attributes
+ are useful when registering a Printer so that a client can find the
+ Printer not just by name, but by filtered searches as well.
+ - Section 17 is an appendix summarizing the additions and changes
+ from the IPP/1.0 "Model and Semantics" document [RFC2566] to make
+ this IPP/1.1 document.
+ - Section 18 is the full copyright notice.
+
+1.1 Simplified Printing Model
+
+ In order to achieve its goal of realizing a workable printing
+ protocol for the Internet, the Internet Printing Protocol (IPP) is
+ based on a simplified printing model that abstracts the many
+ components of real world printing solutions. The Internet is a
+ distributed computing environment where requesters of print services
+ (clients, applications, printer drivers, etc.) cooperate and interact
+ with print service providers. This model and semantics document
+ describes a simple, abstract model for IPP even though the underlying
+ configurations may be complex "n-tier" client/server systems. An
+ important simplifying step in the IPP model is to expose only the key
+ objects and interfaces required for printing. The model described in
+ this model document does not include features, interfaces, and
+ relationships that are beyond the scope of the first version of IPP
+ (IPP/1.1). IPP/1.1 incorporates many of the relevant ideas and
+ lessons learned from other specification and development efforts
+ [HTPP] [ISO10175] [LDPA] [P1387.4] [PSIS] [RFC1179] [SWP]. IPP is
+ heavily influenced by the printing model introduced in the Document
+ Printing Application (DPA) [ISO10175] standard. Although DPA
+ specifies both end user and administrative features, IPP version 1.1
+ (IPP/1.1) focuses primarily on end user functionality with a few
+ additional OPTIONAL operator operations.
+
+ The IPP/1.1 model encapsulates the important components of
+ distributed printing into two object types:
+
+ - Printer (Section 2.1)
+ - Job (Section 2.2)
+
+ Each object type has an associated set of operations (see section 3)
+ and attributes (see section 4).
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 10]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ It is important, however, to understand that in real system
+ implementations (which lie underneath the abstracted IPP/1.1 model),
+ there are other components of a print service which are not
+ explicitly defined in the IPP/1.1 model. The following figure
+ illustrates where IPP/1.1 fits with respect to these other
+ components.
+
+ +--------------+
+ | Application |
+ o +. . . . . . . |
+ \|/ | Spooler |
+ / \ +. . . . . . . | +---------+
+ End-User | Print Driver |---| File |
+ +-----------+ +-----+ +------+-------+ +----+----+
+ | Browser | | GUI | | |
+ +-----+-----+ +--+--+ | |
+ | | | |
+ | +---+------------+---+ |
+ N D S | | IPP Client |------------+
+ O I E | +---------+----------+
+ T R C | |
+ I E U |
+ F C R -------------- Transport ------------------
+ I T I
+ C O T | --+
+ A R Y +--------+--------+ |
+ T Y | IPP Server | |
+ I +--------+--------+ |
+ O | |
+ N +-----------------+ | IPP Printer
+ | Print Service | |
+ +-----------------+ |
+ | --+
+ +-----------------+
+ | Output Device(s)|
+ +-----------------+
+
+ An IPP Printer object encapsulates the functions normally associated
+ with physical output devices along with the spooling, scheduling and
+ multiple device management functions often associated with a print
+ server. Printer objects are optionally registered as entries in a
+ directory where end users find and select them based on some sort of
+ filtered and context based searching mechanism (see section 16). The
+ directory is used to store relatively static information about the
+ Printer, allowing end users to search for and find Printers that
+ match their search criteria, for example: name, context, printer
+ capabilities, etc. The more dynamic information, such as state,
+ currently loaded and ready media, number of jobs at the Printer,
+
+
+
+Hastings, et al. Standards Track [Page 11]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ errors, warnings, and so forth, is directly associated with the
+ Printer object itself rather than with the entry in the directory
+ which only represents the Printer object.
+
+ IPP clients implement the IPP protocol on the client side and give
+ end users (or programs running on behalf of end users) the ability to
+ query Printer objects and submit and manage print jobs. An IPP
+ server is just that part of the Printer object that implements the
+ server-side protocol. The rest of the Printer object implements (or
+ gateways into) the application semantics of the print service itself.
+ The Printer objects may be embedded in an output device or may be
+ implemented on a host on the network that communicates with an output
+ device.
+
+ When a job is submitted to the Printer object and the Printer object
+ validates the attributes in the submission request, the Printer
+ object creates a new Job object. The end user then interacts with
+ this new Job object to query its status and monitor the progress of
+ the job. An end user can also cancel their print jobs by using the
+ Job object's Cancel-Job operation. An end-user can also hold,
+ release, and restart their print jobs using the Job object's OPTIONAL
+ Hold-Job, Release-Job, and Restart-Job operations, if implemented.
+
+ A privileged operator or administrator of a Printer object can
+ cancel, hold, release, and restart any user's job using the REQUIRED
+ Cancel-Job and the OPTIONAL Hold-Job, Release-Job, and Restart-Job
+ operations. In additional privileged operator or administrator of a
+ Printer object can pause, resume, or purge (jobs from) a Printer
+ object using the OPTIONAL Pause-Printer, Resume-Printer, and Purge-
+ Jobs operations, if implemented.
+
+ The notification service is out of scope for this IPP/1.1 document,
+ but using such a notification service, the end user is able to
+ register for and receive Printer specific and Job specific events.
+ An end user can query the status of Printer objects and can follow
+ the progress of Job objects by polling using the Get-Printer-
+ Attributes, Get-Jobs, and Get-Job-Attributes operations.
+
+2. IPP Objects
+
+ The IPP/1.1 model introduces objects of type Printer and Job. Each
+ type of object models relevant aspects of a real-world entity such as
+ a real printer or real print job. Each object type is defined as a
+ set of possible attributes that may be supported by instances of that
+ object type. For each object (instance), the actual set of supported
+ attributes and values describe a specific implementation. The
+ object's attributes and values describe its state, capabilities,
+ realizable features, job processing functions, and default behaviors
+
+
+
+Hastings, et al. Standards Track [Page 12]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ and characteristics. For example, the Printer object type is defined
+ as a set of attributes that each Printer object potentially supports.
+ In the same manner, the Job object type is defined as a set of
+ attributes that are potentially supported by each Job object.
+
+ Each attribute included in the set of attributes defining an object
+ type is labeled as:
+
+ - "REQUIRED": each object MUST support the attribute.
+ - "RECOMMENDED": each object SHOULD support the attribute.
+ - "OPTIONAL": each object MAY support the attribute.
+
+ Some definitions of attribute values indicate that an object MUST or
+ SHOULD support the value; otherwise, support of the value is
+ OPTIONAL.
+
+ However, if an implementation supports an attribute, it MUST support
+ at least one of the possible values for that attribute.
+
+2.1 Printer Object
+
+ The major component of the IPP/1.1 model is the Printer object. A
+ Printer object implements the server-side of the IPP/1.1 protocol.
+ Using the protocol, end users may query the attributes of the Printer
+ object and submit print jobs to the Printer object. The actual
+ implementation components behind the Printer abstraction may take on
+ different forms and different configurations. However, the model
+ abstraction allows the details of the configuration of real
+ components to remain opaque to the end user. Section 3 describes
+ each of the Printer operations in detail.
+
+ The capabilities and state of a Printer object are described by its
+ attributes. Printer attributes are divided into two groups:
+
+ - "job-template" attributes: These attributes describe supported job
+ processing capabilities and defaults for the Printer object. (See
+ section 4.2)
+ - "printer-description" attributes: These attributes describe the
+ Printer object's identification, state, location, references to
+ other sources of information about the Printer object, etc. (see
+ section 4.4)
+
+ Since a Printer object is an abstraction of a generic document output
+ device and print service provider, a Printer object could be used to
+ represent any real or virtual device with semantics consistent with
+ the Printer object, such as a fax device, an imager, or even a CD
+ writer.
+
+
+
+
+Hastings, et al. Standards Track [Page 13]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Some examples of configurations supporting a Printer object include:
+
+ 1) An output device with no spooling capabilities
+ 2) An output device with a built-in spooler
+ 3) A print server supporting IPP with one or more associated
+ output devices
+ 3a) The associated output devices may or may not be capable of
+ spooling jobs
+ 3b) The associated output devices may or may not support IPP
+
+ The following figures show some examples of how Printer objects can
+ be realized on top of various distributed printing configurations.
+ The embedded case below represents configurations 1 and 2. The hosted
+ and fan-out figures below represent configurations 3a and 3b.
+
+ In this document the term "client" refers to a software entity that
+ sends IPP operation requests to an IPP Printer object and accepts IPP
+ operation responses. A client MAY be:
+
+ 1. contained within software controlled by an end user, e.g.
+ activated by the "Print" menu item in an application or
+
+ 2. the print server component that sends IPP requests to either an
+ output device or another "downstream" print server.
+
+ The term "IPP Printer" is a network entity that accepts IPP operation
+ requests and returns IPP operation responses. As such, an IPP object
+ MAY be:
+
+ 1. an (embedded) device component that accepts IPP requests and
+ controls the device or
+
+ 2. a component of a print server that accepts IPP requests (where
+ the print server controls one or more networked devices using
+ IPP or other protocols).
+
+ Legend:
+
+ ##### indicates a Printer object which is
+ either embedded in an output device or is
+ hosted in a server. The Printer object
+ might or might not be capable of queuing/spooling.
+
+ any indicates any network protocol or direct
+ connect, including IPP
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 14]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ embedded printer:
+ output device
+ +---------------+
+ O +--------+ | ########### |
+ /|\ | client |------------IPP------------># Printer # |
+ / \ +--------+ | # Object # |
+ | ########### |
+ +---------------+
+
+ hosted printer:
+ +---------------+
+ O +--------+ ########### | |
+ /|\ | client |--IPP--># Printer #-any->| output device |
+ / \ +--------+ # Object # | |
+ ########### +---------------+
+
+
+ +---------------+
+ fan out: | |
+ +-->| output device |
+ any/ | |
+ O +--------+ ########### / +---------------+
+ /|\ | client |-IPP-># Printer #--*
+ / \ +--------+ # Object # \ +---------------+
+ ########### any\ | |
+ +-->| output device |
+ | |
+ +---------------+
+
+2.2 Job Object
+
+ A Job object is used to model a print job. A Job object contains
+ documents. The information required to create a Job object is sent
+ in a create request from the end user via an IPP Client to the
+ Printer object. The Printer object validates the create request, and
+ if the Printer object accepts the request, the Printer object creates
+ the new Job object. Section 3 describes each of the Job operations
+ in detail.
+
+ The characteristics and state of a Job object are described by its
+ attributes. Job attributes are grouped into two groups as follows:
+
+ - "job-template" attributes: These attributes can be supplied by
+ the client or end user and include job processing instructions
+ which are intended to override any Printer object defaults
+ and/or instructions embedded within the document data. (See
+ section 4.2)
+
+
+
+
+Hastings, et al. Standards Track [Page 15]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ - "job-description" attributes: These attributes describe the Job
+ object's identification, state, size, etc. The client supplies
+ some of these attributes, and the Printer object generates
+ others. (See section 4.3)
+
+ An implementation MUST support at least one document per Job object.
+ An implementation MAY support multiple documents per Job object. A
+ document is either:
+
+ - a stream of document data in a format supported by the Printer
+ object (typically a Page Description Language - PDL), or
+ - a reference to such a stream of document data
+
+ In IPP/1.1, a document is not modeled as an IPP object, therefore it
+ has no object identifier or associated attributes. All job
+ processing instructions are modeled as Job object attributes. These
+ attributes are called Job Template attributes and they apply equally
+ to all documents within a Job object.
+
+2.3 Object Relationships
+
+ IPP objects have relationships that are maintained persistently along
+ with the persistent storage of the object attributes.
+
+ A Printer object can represent either one or more physical output
+ devices or a logical device which "processes" jobs but never actually
+ uses a physical output device to put marks on paper. Examples of
+ logical devices include a Web page publisher or a gateway into an
+ online document archive or repository. A Printer object contains
+ zero or more Job objects.
+
+ A Job object is contained by exactly one Printer object, however the
+ identical document data associated with a Job object could be sent to
+ either the same or a different Printer object. In this case, a
+ second Job object would be created which would be almost identical to
+ the first Job object, however it would have new (different) Job
+ object identifiers (see section 2.4).
+
+ A Job object is either empty (before any documents have been added)
+ or contains one or more documents. If the contained document is a
+ stream of document data, that stream can be contained in only one
+ document. However, there can be identical copies of the stream in
+ other documents in the same or different Job objects. If the
+ contained document is just a reference to a stream of document data,
+ other documents (in the same or different Job object(s)) may contain
+ the same reference.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 16]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+2.4 Object Identity
+
+ All Printer and Job objects are identified by a Uniform Resource
+ Identifier (URI) [RFC2396] so that they can be persistently and
+ unambiguously referenced. Since every URL is a specialized form of a
+ URI, even though the more generic term URI is used throughout the
+ rest of this document, its usage is intended to cover the more
+ specific notion of URL as well.
+
+ An administrator configures Printer objects to either support or not
+ support authentication and/or message privacy using Transport Layer
+ Security (TLS) [RFC2246] (the mechanism for security configuration is
+ outside the scope of this IPP/1.1 document). In some situations,
+ both types of connections (both authenticated and unauthenticated)
+ can be established using a single communication channel that has some
+ sort of negotiation mechanism. In other situations, multiple
+ communication channels are used, one for each type of security
+ configuration. Section 8 provides a full description of all security
+ considerations and configurations.
+
+ If a Printer object supports more than one communication channel,
+ some or all of those channels might support and/or require different
+ security mechanisms. In such cases, an administrator could expose
+ the simultaneous support for these multiple communication channels as
+ multiple URIs for a single Printer object where each URI represents
+ one of the communication channels to the Printer object. To support
+ this flexibility, the IPP Printer object type defines a multi-valued
+ identification attribute called the "printer-uri-supported"
+ attribute. It MUST contain at least one URI. It MAY contain more
+ than one URI. That is, every Printer object will have at least one
+ URI that identifies at least one communication channel to the Printer
+ object, but it may have more than one URI where each URI identifies a
+ different communication channel to the Printer object. The
+ "printer-uri-supported" attribute has two companion attributes, the
+ "uri-security-supported" attribute and the "uri-authentication-
+ supported". Both have the same cardinality as "printer-uri-
+ supported". The purpose of the "uri-security-supported" attribute is
+ to indicate the security mechanisms (if any) used for each URI listed
+ in "printer-uri-supported". The purpose of the "uri-authentication-
+ supported" attribute is to indicate the authentication mechanisms (if
+ any) used for each URI listed in "printer-uri-supported". These
+ three attributes are fully described in sections 4.4.1, 4.4.2, and
+ 4.4.3.
+
+ When a job is submitted to the Printer object via a create request,
+ the client supplies only a single Printer object URI. The client
+ supplied Printer object URI MUST be one of the values in the
+ "printer-uri-supported" Printer attribute.
+
+
+
+Hastings, et al. Standards Track [Page 17]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ IPP/1.1 does not specify how the client obtains the client supplied
+ URI, but it is RECOMMENDED that a Printer object be registered as an
+ entry in a directory service. End-users and programs can then
+ interrogate the directory searching for Printers. Section 16 defines
+ a generic schema for Printer object entries in the directory service
+ and describes how the entry acts as a bridge to the actual IPP
+ Printer object. The entry in the directory that represents the IPP
+ Printer object includes the possibly many URIs for that Printer
+ object as values in one its attributes.
+
+ When a client submits a create request to the Printer object, the
+ Printer object validates the request and creates a new Job object.
+ The Printer object assigns the new Job object a URI which is stored
+ in the "job-uri" Job attribute. This URI is then used by clients as
+ the target for subsequent Job operations. The Printer object
+ generates a Job URI based on its configured security policy and the
+ URI used by the client in the create request.
+
+ For example, consider a Printer object that supports both a
+ communication channel secured by the use of SSL3 (using HTTP over
+ SSL3 with an "https" schemed URI) and another open communication
+ channel that is not secured with SSL3 (using a simple "http" schemed
+ URI). If a client were to submit a job using the secure URI, the
+ Printer object would assign the new Job object a secure URI as well.
+ If a client were to submit a job using the open-channel URI, the
+ Printer would assign the new Job object an open-channel URI.
+
+ In addition, the Printer object also populates the Job object's
+ "job-printer-uri" attribute. This is a reference back to the Printer
+ object that created the Job object. If a client only has access to a
+ Job object's "job-uri" identifier, the client can query the Job's
+ "job-printer-uri" attribute in order to determine which Printer
+ object created the Job object. If the Printer object supports more
+ than one URI, the Printer object picks the one URI supplied by the
+ client when creating the job to build the value for and to populate
+ the Job's "job-printer-uri" attribute.
+
+ Allowing Job objects to have URIs allows for flexibility and
+ scalability. For example, in some implementations, the Printer
+ object might create Jobs that are processed in the same local
+ environment as the Printer object itself. In this case, the Job URI
+ might just be a composition of the Printer's URI and some unique
+ component for the Job object, such as the unique 32-bit positive
+ integer mentioned later in this paragraph. In other implementations,
+ the Printer object might be a central clearing-house for validating
+ all Job object creation requests, but the Job object itself might be
+ created in some environment that is remote from the Printer object.
+ In this case, the Job object's URI may have no physical-location
+
+
+
+Hastings, et al. Standards Track [Page 18]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ relationship at all to the Printer object's URI. Again, the fact
+ that Job objects have URIs allows for flexibility and scalability,
+ however, many existing printing systems have local models or
+ interface constraints that force print jobs to be identified using
+ only a 32-bit positive integer rather than an independent URI. This
+ numeric Job ID is only unique within the context of the Printer
+ object to which the create request was originally submitted.
+ Therefore, in order to allow both types of client access to IPP Job
+ objects (either by Job URI or by numeric Job ID), when the Printer
+ object successfully processes a create request and creates a new Job
+ object, the Printer object MUST generate both a Job URI and a Job ID.
+ The Job ID (stored in the "job-id" attribute) only has meaning in the
+ context of the Printer object to which the create request was
+ originally submitted. This requirement to support both Job URIs and
+ Job IDs allows all types of clients to access Printer objects and Job
+ objects no matter the local constraints imposed on the client
+ implementation.
+
+ In addition to identifiers, Printer objects and Job objects have
+ names ("printer-name" and "job-name"). An object name NEED NOT be
+ unique across all instances of all objects. A Printer object's name
+ is chosen and set by an administrator through some mechanism outside
+ the scope of this IPP/1.1 document. A Job object's name is
+ optionally chosen and supplied by the IPP client submitting the job.
+ If the client does not supply a Job object name, the Printer object
+ generates a name for the new Job object. In all cases, the name only
+ has local meaning.
+
+ To summarize:
+
+ - Each Printer object is identified with one or more URIs. The
+ Printer's "printer-uri-supported" attribute contains the URI(s).
+ - The Printer object's "uri-security-supported" attribute
+ identifies the communication channel security protocols that may
+ or may not have been configured for the various Printer object
+ URIs (e.g., 'tls' or 'none').
+ - The Printer object's "uri-authentication-supported" attribute
+ identifies the authentication mechanisms that may or may not
+ have been configured for the various Printer object URIs (e.g.,
+ 'digest' or 'none').
+ - Each Job object is identified with a Job URI. The Job's "job-
+ uri" attribute contains the URI.
+ - Each Job object is also identified with Job ID which is a 32-
+ bit, positive integer. The Job's "job-id" attribute contains
+ the Job ID. The Job ID is only unique within the context of the
+ Printer object which created the Job object.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 19]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ - Each Job object has a "job-printer-uri" attribute which contains
+ the URI of the Printer object that was used to create the Job
+ object. This attribute is used to determine the Printer object
+ that created a Job object when given only the URI for the Job
+ object. This linkage is necessary to determine the languages,
+ charsets, and operations which are supported on that Job (the
+ basis for such support comes from the creating Printer object).
+ - Each Printer object has a name (which is not necessarily
+ unique). The administrator chooses and sets this name through
+ some mechanism outside the scope of this IPP/1.1 document. The
+ Printer object's "printer-name" attribute contains the name.
+ - Each Job object has a name (which is not necessarily unique).
+ The client optionally supplies this name in the create request.
+ If the client does not supply this name, the Printer object
+ generates a name for the Job object. The Job object's "job-name"
+ attribute contains the name.
+
+3. IPP Operations
+
+ IPP objects support operations. An operation consists of a request
+ and a response. When a client communicates with an IPP object, the
+ client issues an operation request to the URI for that object.
+ Operation requests and responses have parameters that identify the
+ operation. Operations also have attributes that affect the run-time
+ characteristics of the operation (the intended target, localization
+ information, etc.). These operation-specific attributes are called
+ operation attributes (as compared to object attributes such as
+ Printer object attributes or Job object attributes). Each request
+ carries along with it any operation attributes, object attributes,
+ and/or document data required to perform the operation. Each request
+ requires a response from the object. Each response indicates success
+ or failure of the operation with a status code as a response
+ parameter. The response contains any operation attributes, object
+ attributes, and/or status messages generated during the execution of
+ the operation request.
+
+ This section describes the semantics of the IPP operations, both
+ requests and responses, in terms of the parameters, attributes, and
+ other data associated with each operation.
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 20]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The IPP/1.1 Printer operations are:
+
+ Print-Job (section 3.2.1)
+ Print-URI (section 3.2.2)
+ Validate-Job (section 3.2.3)
+ Create-Job (section 3.2.4)
+ Get-Printer-Attributes (section 3.2.5)
+ Get-Jobs (section 3.2.6)
+ Pause-Printer (section 3.3.5)
+ Resume-Printer (section 3.3.6)
+ Purge-Jobs (section 3.3.7)
+
+ The Job operations are:
+
+ Send-Document (section 3.3.1)
+ Send-URI (section 3.3.2)
+ Cancel-Job (section 3.3.3)
+ Get-Job-Attributes (section 3.3.4)
+ Hold-Job (section 3.3.5)
+ Release-Job (section 3.3.6)
+ Restart-Job (section 3.3.7)
+
+ The Send-Document and Send-URI Job operations are used to add a new
+ document to an existing multi-document Job object created using the
+ Create-Job operation.
+
+3.1 Common Semantics
+
+ All IPP operations require some common parameters and operation
+ attributes. These common elements and their semantic characteristics
+ are defined and described in more detail in the following sections.
+
+3.1.1 Required Parameters
+
+ Every operation request contains the following REQUIRED parameters:
+
+ - a "version-number",
+ - an "operation-id",
+ - a "request-id", and
+ - the attributes that are REQUIRED for that type of request.
+
+ Every operation response contains the following REQUIRED parameters:
+
+ - a "version-number",
+ - a "status-code",
+ - the "request-id" that was supplied in the corresponding request,
+ and
+ - the attributes that are REQUIRED for that type of response.
+
+
+
+Hastings, et al. Standards Track [Page 21]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The "Encoding and Transport" document [RFC2910] defines special rules
+ for the encoding of these parameters. All other operation elements
+ are represented using the more generic encoding rules for attributes
+ and groups of attributes.
+
+3.1.2 Operation IDs and Request IDs
+
+ Each IPP operation request includes an identifying "operation-id"
+ value. Valid values are defined in the "operations-supported"
+ Printer attribute section (see section 4.4.15). The client specifies
+ which operation is being requested by supplying the correct
+ "operation-id" value.
+
+ In addition, every invocation of an operation is identified by a
+ "request-id" value. For each request, the client chooses the
+ "request-id" which MUST be an integer (possibly unique depending on
+ client requirements) in the range from 1 to 2**31 - 1 (inclusive).
+ This "request-id" allows clients to manage multiple outstanding
+ requests. The receiving IPP object copies all 32-bits of the client-
+ supplied "request-id" attribute into the response so that the client
+ can match the response with the correct outstanding request, even if
+ the "request-id" is out of range. If the request is terminated
+ before the complete "request-id" is received, the IPP object rejects
+ the request and returns a response with a "request-id" of 0.
+
+ Note: In some cases, the transport protocol underneath IPP might be a
+ connection oriented protocol that would make it impossible for a
+ client to receive responses in any order other than the order in
+ which the corresponding requests were sent. In such cases, the
+ "request-id" attribute would not be essential for correct protocol
+ operation. However, in other mappings, the operation responses can
+ come back in any order. In these cases, the "request-id" would be
+ essential.
+
+3.1.3 Attributes
+
+ Operation requests and responses are both composed of groups of
+ attributes and/or document data. The attributes groups are:
+
+ - Operation Attributes: These attributes are passed in the
+ operation and affect the IPP object's behavior while processing
+ the operation request and may affect other attributes or groups
+ of attributes. Some operation attributes describe the document
+ data associated with the print job and are associated with new
+ Job objects, however most operation attributes do not persist
+ beyond the life of the operation. The description of each
+ operation attribute includes conformance statements indicating
+ which operation attributes are REQUIRED and which are OPTIONAL
+
+
+
+Hastings, et al. Standards Track [Page 22]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ for an IPP object to support and which attributes a client MUST
+ supply in a request and an IPP object MUST supply in a response.
+ - Job Template Attributes: These attributes affect the processing
+ of a job. A client OPTIONALLY supplies Job Template Attributes
+ in a create request, and the receiving object MUST be prepared
+ to receive all supported attributes. The Job object can later
+ be queried to find out what Job Template attributes were
+ originally requested in the create request, and such attributes
+ are returned in the response as Job Object Attributes. The
+ Printer object can be queried about its Job Template attributes
+ to find out what type of job processing capabilities are
+ supported and/or what the default job processing behaviors are,
+ though such attributes are returned in the response as Printer
+ Object Attributes. The "ipp-attribute-fidelity" operation
+ attribute affects processing of all client-supplied Job Template
+ attributes (see sections 3.2.1.2 and 15 for a full description
+ of "ipp-attribute-fidelity" and its relationship to other
+ attributes).
+ - Job Object Attributes: These attributes are returned in response
+ to a query operation directed at a Job object.
+ - Printer Object Attributes: These attributes are returned in
+ response to a query operation directed at a Printer object.
+ - Unsupported Attributes: In a create request, the client supplies
+ a set of Operation and Job Template attributes. If any of these
+ attributes or their values is unsupported by the Printer object,
+ the Printer object returns the set of unsupported attributes in
+ the response. Sections 3.1.7, 3.2.1.2, and 15 give a full
+ description of how Job Template attributes supplied by the
+ client in a create request are processed by the Printer object
+ and how unsupported attributes are returned to the client.
+ Because of extensibility, any IPP object might receive a request
+ that contains new or unknown attributes or values for which it
+ has no support. In such cases, the IPP object processes what it
+ can and returns the unsupported attributes in the response. The
+ Unsupported Attribute group is defined for all operation
+ responses for returning unsupported attributes that the client
+ supplied in the request.
+
+ Later in this section, each operation is formally defined by
+ identifying the allowed and expected groups of attributes for each
+ request and response. The model identifies a specific order for each
+ group in each request or response, but the attributes within each
+ group may be in any order, unless specified otherwise.
+
+ The attributes within a group MUST be unique; if an attribute with
+ the same name occurs more than once, the group is mal-formed.
+ Clients MUST NOT submit such malformed requests and Printers MUST NOT
+ return such malformed responses. If such a malformed request is
+
+
+
+Hastings, et al. Standards Track [Page 23]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ submitted to a Printer, the Printer MUST either (1) reject the
+ request with the 'client-error-bad-request' status code (see section
+ 13.1.4.1) or (2) process the request normally after selecting only
+ one of the attribute instances, depending on implementation. Which
+ attribute is selected when there are duplicate attributes depends on
+ implementation. The IPP Printer MUST NOT use the values from more
+ than one such duplicate attribute instance.
+
+ Each attribute definition includes the attribute's name followed by
+ the name of its attribute syntax(es) in parenthesizes. In addition,
+ each 'integer' attribute is followed by the allowed range in
+ parentheses, (m:n), for values of that attribute. Each 'text' or
+ 'name' attribute is followed by the maximum size in octets in
+ parentheses, (size), for values of that attribute. For more details
+ on attribute syntax notation, see the descriptions of these
+ attributes syntaxes in section 4.1.
+
+ Note: Document data included in the operation is not strictly an
+ attribute, but it is treated as a special attribute group for
+ ordering purposes. The only operations that support supplying the
+ document data within an operation request are Print-Job and Send-
+ Document. There are no operation responses that include document
+ data.
+
+ Some operations are REQUIRED for IPP objects to support; the others
+ are OPTIONAL (see section 5.2.2). Therefore, before using an
+ OPTIONAL operation, a client SHOULD first use the REQUIRED Get-
+ Printer-Attributes operation to query the Printer's "operations-
+ supported" attribute in order to determine which OPTIONAL Printer and
+ Job operations are actually supported. The client SHOULD NOT use an
+ OPTIONAL operation that is not supported. When an IPP object
+ receives a request to perform an operation it does not support, it
+ returns the 'server-error-operation-not-supported' status code (see
+ section 13.1.5.2). An IPP object is non-conformant if it does not
+ support a REQUIRED operation.
+
+3.1.4 Character Set and Natural Language Operation Attributes
+
+ Some Job and Printer attributes have values that are text strings and
+ names intended for human understanding rather than machine
+ understanding (see the 'text' and 'name' attribute syntax
+ descriptions in section 4.1). The following sections describe two
+ special Operation Attributes called "attributes-charset" and
+ "attributes-natural-language". These attributes are always part of
+ the Operation Attributes group. For most attribute groups, the order
+ of the attributes within the group is not important. However, for
+ these two attributes within the Operation Attributes group, the order
+ is critical. The "attributes-charset" attribute MUST be the first
+
+
+
+Hastings, et al. Standards Track [Page 24]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ attribute in the group and the "attributes-natural-language"
+ attribute MUST be the second attribute in the group. In other words,
+ these attributes MUST be supplied in every IPP request and response,
+ they MUST come first in the group, and MUST come in the specified
+ order. For job creation operations, the IPP Printer implementation
+ saves these two attributes with the new Job object as Job Description
+ attributes. For the sake of brevity in this document, these
+ operation attribute descriptions are not repeated with every
+ operation request and response, but have a reference back to this
+ section instead.
+
+3.1.4.1 Request Operation Attributes
+
+ The client MUST supply and the Printer object MUST support the
+ following REQUIRED operation attributes in every IPP/1.1 operation
+ request:
+
+ "attributes-charset" (charset):
+ This operation attribute identifies the charset (coded
+ character set and encoding method) used by any 'text' and
+ 'name' attributes that the client is supplying in this request.
+ It also identifies the charset that the Printer object MUST use
+ (if supported) for all 'text' and 'name' attributes and status
+ messages that the Printer object returns in the response to
+ this request. See Sections 4.1.1 and 4.1.2 for the definition
+ of the 'text' and 'name' attribute syntaxes.
+
+ All clients and IPP objects MUST support the 'utf-8' charset
+ [RFC2279] and MAY support additional charsets provided that
+ they are registered with IANA [IANA-CS]. If the Printer object
+ does not support the client supplied charset value, the Printer
+ object MUST reject the request, set the "attributes-charset" to
+ 'utf-8' in the response, and return the 'client-error-charset-
+ not-supported' status code and any 'text' or 'name' attributes
+ using the 'utf-8' charset. The Printer NEED NOT return any
+ attributes in the Unsupported Attributes Group (See sections
+ 3.1.7 and 3.2.1.2). The Printer object MUST indicate the
+ charset(s) supported as the values of the "charset-supported"
+ Printer attribute (see Section 4.4.18), so that the client can
+ query to determine which charset(s) are supported.
+
+ Note to client implementers: Since IPP objects are only
+ required to support the 'utf-8' charset, in order to maximize
+ interoperability with multiple IPP object implementations, a
+ client may want to supply 'utf-8' in the "attributes-charset"
+ operation attribute, even though the client is only passing and
+ able to present a simpler charset, such as US-ASCII [ASCII] or
+ ISO-8859-1 [ISO8859-1]. Then the client will have to filter
+
+
+
+Hastings, et al. Standards Track [Page 25]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ out (or charset convert) those characters that are returned in
+ the response that it cannot present to its user. On the other
+ hand, if both the client and the IPP objects also support a
+ charset in common besides utf-8, the client may want to use
+ that charset in order to avoid charset conversion or data loss.
+
+ See the 'charset' attribute syntax description in Section 4.1.7
+ for the syntax and semantic interpretation of the values of
+ this attribute and for example values.
+
+ "attributes-natural-language" (naturalLanguage):
+ This operation attribute identifies the natural language used
+ by any 'text' and 'name' attributes that the client is
+ supplying in this request. This attribute also identifies the
+ natural language that the Printer object SHOULD use for all
+ 'text' and 'name' attributes and status messages that the
+ Printer object returns in the response to this request. See
+ the 'naturalLanguage' attribute syntax description in section
+ 4.1.8 for the syntax and semantic interpretation of the values
+ of this attribute and for example values.
+
+ There are no REQUIRED natural languages required for the
+ Printer object to support. However, the Printer object's
+ "generated-natural-language-supported" attribute identifies the
+ natural languages supported by the Printer object and any
+ contained Job objects for all text strings generated by the IPP
+ object. A client MAY query this attribute to determine which
+ natural language(s) are supported for generated messages.
+
+ For any of the attributes for which the Printer object
+ generates text, i.e., for the "job-state-message", "printer-
+ state-message", and status messages (see Section 3.1.6), the
+ Printer object MUST be able to generate these text strings in
+ any of its supported natural languages. If the client requests
+ a natural language that is not supported, the Printer object
+ MUST return these generated messages in the Printer's
+ configured natural language as specified by the Printer's
+ "natural-language-configured" attribute" (see Section 4.4.19).
+
+ For other 'text' and 'name' attributes supplied by the client,
+ authentication system, operator, system administrator, or
+ manufacturer (i.e., for "job-originating-user-name", "printer-
+ name" (name), "printer-location" (text), "printer-info" (text),
+ and "printer-make-and-model" (text)), the Printer object is
+ only required to support the configured natural language of the
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 26]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Printer identified by the Printer object's "natural-language-
+ configured" attribute, though support of additional natural
+ languages for these attributes is permitted.
+
+ For any 'text' or 'name' attribute in the request that is in a
+ different natural language than the value supplied in the
+ "attributes-natural-language" operation attribute, the client
+ MUST use the Natural Language Override mechanism (see sections
+ 4.1.1.2 and 4.1.2.2) for each such attribute value supplied.
+ The client MAY use the Natural Language Override mechanism
+ redundantly, i.e., use it even when the value is in the same
+ natural language as the value supplied in the "attributes-
+ natural-language" operation attribute of the request.
+
+ The IPP object MUST accept any natural language and any Natural
+ Language Override, whether the IPP object supports that natural
+ language or not (and independent of the value of the "ipp-
+ attribute-fidelity" Operation attribute). That is the IPP
+ object accepts all client supplied values no matter what the
+ values are in the Printer object's "generated-natural-
+ language-supported" attribute. That attribute, "generated-
+ natural-language-supported", only applies to generated
+ messages, not client supplied messages. The IPP object MUST
+ remember that natural language for all client-supplied
+ attributes, and when returning those attributes in response to
+ a query, the IPP object MUST indicate that natural language.
+
+ Each value whose attribute syntax type is 'text' or 'name' (see
+ sections 4.1.1 and 4.1.2) has an Associated Natural-Language.
+ This document does not specify how this association is stored
+ in a Printer or Job object. When such a value is encoded in a
+ request or response, the natural language is either implicit or
+ explicit:
+
+ - In the implicit case, the value contains only the text/name
+ value, and the language is specified by the "attributes-
+ natural-language" operation attribute in the request or
+ response (see sections 4.1.1.1 textWithoutLanguage and
+ 4.1.2.1 nameWithoutLanguage).
+
+ - In the explicit case (also known as the Natural-Language
+ Override case), the value contains both the language and the
+ text/name value (see sections 4.1.1.2 textWithLanguage and
+ 4.1.2.2 nameWithLanguage).
+
+ For example, the "job-name" attribute MAY be supplied by the
+ client in a create request. The text value for this attribute
+ will be in the natural language identified by the "attribute-
+
+
+
+Hastings, et al. Standards Track [Page 27]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ natural-language" attribute, or if different, as identified by
+ the Natural Language Override mechanism. If supplied, the IPP
+ object will use the value of the "job-name" attribute to
+ populate the Job object's "job-name" attribute. Whenever any
+ client queries the Job object's "job-name" attribute, the IPP
+ object returns the attribute as stored and uses the Natural
+ Language Override mechanism to specify the natural language, if
+ it is different from that reported in the "attributes-natural-
+ language" operation attribute of the response. The IPP object
+ MAY use the Natural Language Override mechanism redundantly,
+ i.e., use it even when the value is in the same natural
+ language as the value supplied in the "attributes-natural-
+ language" operation attribute of the response.
+
+ An IPP object MUST NOT reject a request based on a supplied
+ natural language in an "attributes-natural-language" Operation
+ attribute or in any attribute that uses the Natural Language
+ Override.
+
+ Clients SHOULD NOT supply 'text' or 'name' attributes that use an
+ illegal combination of natural language and charset. For example,
+ suppose a Printer object supports charsets 'utf-8', 'iso-8859-1', and
+ 'iso-8859-7'. Suppose also, that it supports natural languages 'en'
+ (English), 'fr' (French), and 'el' (Greek). Although the Printer
+ object supports the charset 'iso-8859-1' and natural language 'el',
+ it probably does not support the combination of Greek text strings
+ using the 'iso-8859-1' charset. The Printer object handles this
+ apparent incompatibility differently depending on the context in
+ which it occurs:
+
+ - In a create request: If the client supplies a text or name
+ attribute (for example, the "job-name" operation attribute) that
+ uses an apparently incompatible combination, it is a client
+ choice that does not affect the Printer object or its correct
+ operation. Therefore, the Printer object simply accepts the
+ client supplied value, stores it with the Job object, and
+ responds back with the same combination whenever the client (or
+ any client) queries for that attribute.
+ - In a query-type operation, like Get-Printer-Attributes: If the
+ client requests an apparently incompatible combination, the
+ Printer object responds (as described in section 3.1.4.2) using
+ the Printer's configured natural language rather than the
+ natural language requested by the client.
+
+ In either case, the Printer object does not reject the request
+ because of the apparent incompatibility. The potential incompatible
+ combination of charset and natural language can occur either at the
+ global operation level or at the Natural Language Override
+
+
+
+Hastings, et al. Standards Track [Page 28]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ attribute-by-attribute level. In addition, since the response always
+ includes explicit charset and natural language information, there is
+ never any question or ambiguity in how the client interprets the
+ response.
+
+3.1.4.2 Response Operation Attributes
+
+ The Printer object MUST supply and the client MUST support the
+ following REQUIRED operation attributes in every IPP/1.1 operation
+ response:
+
+ "attributes-charset" (charset):
+ This operation attribute identifies the charset used by any
+ 'text' and 'name' attributes that the Printer object is
+ returning in this response. The value in this response MUST be
+ the same value as the "attributes-charset" operation attribute
+ supplied by the client in the request. If this is not possible
+ (i.e., the charset requested is not supported), the request
+ would have been rejected. See "attributes-charset" described
+ in Section 3.1.4.1 above.
+
+ If the Printer object supports more than just the 'utf-8'
+ charset, the Printer object MUST be able to code convert
+ between each of the charsets supported on a highest fidelity
+ possible basis in order to return the 'text' and 'name'
+ attributes in the charset requested by the client. However,
+ some information loss MAY occur during the charset conversion
+ depending on the charsets involved. For example, the Printer
+ object may convert from a UTF-8 'a' to a US-ASCII 'a' (with no
+ loss of information), from an ISO Latin 1 CAPITAL LETTER A WITH
+ ACUTE ACCENT to US-ASCII 'A' (losing the accent), or from a
+ UTF-8 Japanese Kanji character to some ISO Latin 1 error
+ character indication such as '?', decimal code equivalent, or
+ to the absence of a character, depending on implementation.
+
+ Whether an implementation that supports more than one charset
+ stores the data in the charset supplied by the client or code
+ converts to one of the other supported charsets, depends on
+ implementation. The strategy should try to minimize loss of
+ information during code conversion. On each response, such an
+ implementation converts from its internal charset to that
+ requested.
+
+ "attributes-natural-language" (naturalLanguage):
+ This operation attribute identifies the natural language used
+ by any 'text' and 'name' attributes that the IPP object is
+ returning in this response. Unlike the "attributes-charset"
+ operation attribute, the IPP object NEED NOT return the same
+
+
+
+Hastings, et al. Standards Track [Page 29]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ value as that supplied by the client in the request. The IPP
+ object MAY return the natural language of the Job object or the
+ Printer's configured natural language as identified by the
+ Printer object's "natural-language-configured" attribute,
+ rather than the natural language supplied by the client. For
+ any 'text' or 'name' attribute or status message in the
+ response that is in a different natural language than the value
+ returned in the "attributes-natural-language" operation
+ attribute, the IPP object MUST use the Natural Language
+ Override mechanism (see sections 4.1.1.2 and 4.1.2.2) on each
+ attribute value returned. The IPP object MAY use the Natural
+ Language Override mechanism redundantly, i.e., use it even when
+ the value is in the same natural language as the value supplied
+ in the "attributes-natural-language" operation attribute of the
+ response.
+
+3.1.5 Operation Targets
+
+ All IPP operations are directed at IPP objects. For Printer
+ operations, the operation is always directed at a Printer object
+ using one of its URIs (i.e., one of the values in the Printer
+ object's "printer-uri-supported" attribute). Even if the Printer
+ object supports more than one URI, the client supplies only one URI
+ as the target of the operation. The client identifies the target
+ object by supplying the correct URI in the "printer-uri (uri)"
+ operation attribute.
+
+ For Job operations, the operation is directed at either:
+
+ - The Job object itself using the Job object's URI. In this case,
+ the client identifies the target object by supplying the correct
+ URI in the "job-uri (uri)" operation attribute.
+ - The Printer object that created the Job object using both the
+ Printer objects URI and the Job object's Job ID. Since the
+ Printer object that created the Job object generated the Job ID,
+ it MUST be able to correctly associate the client supplied Job
+ ID with the correct Job object. The client supplies the Printer
+ object's URI in the "printer-uri (uri)" operation attribute and
+ the Job object's Job ID in the "job-id (integer(1:MAX))"
+ operation attribute.
+
+ If the operation is directed at the Job object directly using the Job
+ object's URI, the client MUST NOT include the redundant "job-id"
+ operation attribute.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 30]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The operation target attributes are REQUIRED operation attributes
+ that MUST be included in every operation request. Like the charset
+ and natural language attributes (see section 3.1.4), the operation
+ target attributes are specially ordered operation attributes. In all
+ cases, the operation target attributes immediately follow the
+ "attributes-charset" and "attributes-natural-language" attributes
+ within the operation attribute group, however the specific ordering
+ rules are:
+
+ - In the case where there is only one operation target attribute
+ (i.e., either only the "printer-uri" attribute or only the
+ "job-uri" attribute), that attribute MUST be the third attribute
+ in the operation attributes group.
+ - In the case where Job operations use two operation target
+ attributes (i.e., the "printer-uri" and "job-id" attributes),
+ the "printer-uri" attribute MUST be the third attribute and the
+ "job-id" attribute MUST be the fourth attribute.
+
+ In all cases, the target URIs contained within the body of IPP
+ operation requests and responses must be in absolute format rather
+ than relative format (a relative URL identifies a resource with the
+ scope of the HTTP server, but does not include scheme, host or port).
+
+ The following rules apply to the use of port numbers in URIs that
+ identify IPP objects:
+
+ 1. If the URI scheme allows the port number to be explicitly
+ included in the URI string, and a port number is specified
+ within the URI, then that port number MUST be used by the
+ client to contact the IPP object.
+
+ 2. If the URI scheme allows the port number to be explicitly
+ included in the URI string, and a port number is not specified
+ within the URI, then default port number implied by that URI
+ scheme MUST be used by the client to contact the IPP object.
+
+ 3. If the URI scheme does not allow an explicit port number to be
+ specified within the URI, then the default port number implied
+ by that URI MUST be used by the client to contact the IPP
+ object.
+
+ Note: The IPP "Encoding and Transport document [RFC2910] shows a
+ mapping of IPP onto HTTP/1.1 [RFC2616] and defines a new default port
+ number for using IPP over HTTP/1.1.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 31]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+3.1.6 Operation Response Status Codes and Status Messages
+
+ Every operation response includes a REQUIRED "status-code" parameter
+ and an OPTIONAL "status-message" operation attribute, and an OPTIONAL
+ "detailed-status-message" operation attribute. The Print-URI and
+ Send-URI response MAY include an OPTIONAL "document-access-error"
+ operation attribute.
+
+3.1.6.1 "status-code" (type2 enum)
+
+ The REQUIRED "status-code" parameter provides information on the
+ processing of a request.
+
+ The status code is intended for use by automata. A client
+ implementation of IPP SHOULD convert status code values into any
+ localized message that has semantic meaning to the end user.
+
+ The "status-code" value is a numeric value that has semantic meaning.
+ The "status-code" syntax is similar to a "type2 enum" (see section
+ 4.1 on "Attribute Syntaxes") except that values can range only from
+ 0x0000 to 0x7FFF. Section 13 describes the status codes, assigns the
+ numeric values, and suggests a corresponding status message for each
+ status code for use by the client when the user's natural language is
+ English.
+
+ If the Printer performs an operation with no errors and it encounters
+ no problems, it MUST return the status code 'successful-ok' in the
+ response. See section 13.
+
+ If the client supplies unsupported values for the following
+ parameters or Operation attributes, the Printer object MUST reject
+ the operation, NEED NOT return the unsupported attribute value in the
+ Unsupported Attributes group, and MUST return the indicated status
+ code:
+
+ Parameter/Attribute Status code
+
+ version-number server-error-version-not-supported
+ operation-id server-error-operation-not-supported
+ attributes-charset client-error-charset-not-supported
+ compression client-error-compression-not-supported
+ document-format client-error-document-format-not-supported
+ document-uri client-error-uri-scheme-not-supported,
+ client-error-document-access-error
+
+ If the client supplies unsupported values for other attributes, or
+ unsupported attributes, the Printer returns the status code defined
+ in section 3.1.7 on Unsupported Attributes.
+
+
+
+Hastings, et al. Standards Track [Page 32]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+3.1.6.2 "status-message" (text(255))
+
+ The OPTIONAL "status-message" operation attribute provides a short
+ textual description of the status of the operation. The "status-
+ message" attribute's syntax is "text(255)", so the maximum length is
+ 255 octets (see section 4.1.1). The status message is intended for
+ the human end user. If a response does include a "status-message"
+ attribute, an IPP client NEED NOT examine or display the messages,
+ however it SHOULD do so in some implementation specific manner. The
+ "status-message" is especially useful for a later version of a
+ Printer object to return as supplemental information for the human
+ user to accompany a status code that an earlier version of a client
+ might not understand.
+
+ If the Printer object supports the "status-message" operation
+ attribute, the Printer object MUST be able to generate this message
+ in any of the natural languages identified by the Printer object's
+ "generated-natural-language-supported" attribute (see the
+ "attributes-natural-language" operation attribute specified in
+ section 3.1.4.1. Section 13 suggests the text for the status message
+ returned by the Printer for use with the English natural language.
+
+ As described in section 3.1.4.1 for any returned 'text' attribute, if
+ there is a choice for generating this message, the Printer object
+ uses the natural language indicated by the value of the "attributes-
+ natural-language" in the client request if supported, otherwise the
+ Printer object uses the value in the Printer object's own "natural-
+ language-configured" attribute.
+
+ If the Printer object supports the "status-message" operation
+ attribute, it SHOULD use the REQUIRED 'utf-8' charset to return a
+ status message for the following error status codes (see section 13):
+ 'client-error-bad-request', 'client-error-charset-not-supported',
+ 'server-error-internal-error', 'server-error-operation-not-
+ supported', and 'server-error-version-not-supported'. In this case,
+ it MUST set the value of the "attributes-charset" operation attribute
+ to 'utf-8' in the error response.
+
+3.1.6.3 "detailed-status-message" (text(MAX))
+
+ The OPTIONAL "detailed-status-message" operation attribute provides
+ additional more detailed technical and implementation-specific
+ information about the operation. The "detailed-status-message"
+ attribute's syntax is "text(MAX)", so the maximum length is 1023
+ octets (see section 4.1.1). If the Printer objects supports the
+ "detailed-status-message" operation attribute, the Printer NEED NOT
+ localize the message, since it is intended for use by the system
+ administrator or other experienced technical persons. Localization
+
+
+
+Hastings, et al. Standards Track [Page 33]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ might obscure the technical meaning of such messages. Clients MUST
+ NOT attempt to parse the value of this attribute. See the
+ "document-access-error" operation attribute (section 3.1.6.4) for
+ additional errors that a program can process.
+
+3.1.6.4 "document-access-error" (text(MAX))
+
+ This OPTIONAL operation attribute provides additional information
+ about any document access errors encountered by the Printer before it
+ returned a response to the Print-URI (section 3.2.2) or Send-URI
+ (section 3.3.1) operation. For errors in the protocol identified by
+ the URI scheme in the "document-uri" operation attribute, such as
+ 'http:' or 'ftp:', the error code is returned in parentheses,
+ followed by the URI. For example:
+
+ (404) http://ftp.pwg.org/pub/pwg/ipp/new_MOD/ipp-model-v11.pdf
+
+ Most Internet protocols use decimal error codes (unlike IPP), so the
+ ASCII error code representation is in decimal.
+
+3.1.7 Unsupported Attributes
+
+ The Unsupported Attributes group contains attributes that are not
+ supported by the operation. This group is primarily for the job
+ creation operations, but all operations can return this group.
+
+ A Printer object MUST include an Unsupported Attributes group in a
+ response if the status code is one of the following: 'successful-
+ ok-ignored-or-substituted-attributes', 'successful-ok-conflicting-
+ attributes', 'client-error-attributes-or-values-not-supported' or
+ 'client-error-conflicting-attributes'.
+
+ If the status code is one of the four specified in the preceding
+ paragraph, the Unsupported Attributes group MUST contain all of those
+ attributes and only those attributes that are:
+
+ a. an Operation or Job Template attribute supplied in the request,
+ and
+
+ b. unsupported by the printer. See below for details on the three
+ categories "unsupported" attributes.
+
+ If the status code is one of those in the table in section 3.1.6.1,
+ the Unsupported Attributes group NEED NOT contain the unsupported
+ parameter or attribute indicated in that table.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 34]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ If the Printer object is not returning any Unsupported Attributes in
+ the response, the Printer object SHOULD omit Group 2 rather than
+ sending an empty group. However, a client MUST be able to accept an
+ empty group.
+
+ Unsupported attributes fall into three categories:
+
+ 1. The Printer object does not support the supplied attribute (no
+ matter what the attribute syntax or value).
+
+ 2. The Printer object does support the attribute, but does not
+ support some or all of the particular attribute syntaxes or
+ values supplied by the client (i.e., the Printer object does
+ not have those attribute syntaxes or values in its
+ corresponding "xxx-supported" attribute).
+
+ 3. The Printer object does support the attributes and values
+ supplied, but the particular values are in conflict with one
+ another, because they violate a constraint, such as not being
+ able to staple transparencies.
+
+ In the case of an unsupported attribute name, the Printer object
+ returns the client-supplied attribute with a substituted value of
+ 'unsupported'. This value's syntax type is "out-of-band" and its
+ encoding is defined by special rules for "out-of-band" values in the
+ "Encoding and Transport" document [RFC2910]. Its value indicates no
+ support for the attribute itself (see the beginning of section 4.1).
+
+ In the case of a supported attribute with one or more unsupported
+ attribute syntaxes or values, the Printer object simply returns the
+ client-supplied attribute with the unsupported attribute syntaxes or
+ values as supplied by the client. This indicates support for the
+ attribute, but no support for that particular attribute syntax or
+ value. If the client supplies a multi-valued attribute with more
+ than one value and the Printer object supports the attribute but only
+ supports a subset of the client-supplied attribute syntaxes or
+ values, the Printer object
+
+ MUST return only those attribute syntaxes or values that are
+ unsupported.
+
+ In the case of two (or more) supported attribute values that are in
+ conflict with one another (although each is supported independently,
+ the values conflict when requested together within the same job), the
+ Printer object MUST return all the values that it ignores or
+ substitutes to resolve the conflict, but not any of the values that
+
+
+
+
+
+Hastings, et al. Standards Track [Page 35]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ it is still using. The choice for exactly how to resolve the
+ conflict is implementation dependent. See sections 3.2.1.2 and 15.
+ See The Implementer's Guide [IPP-IIG] for an example.
+
+3.1.8 Versions
+
+ Each operation request and response carries with it a "version-
+ number" parameter. Each value of the "version-number" is in the form
+ "X.Y" where X is the major version number and Y is the minor version
+ number. By including a version number in the client request, it
+ allows the client to identify which version of IPP it is interested
+ in using, i.e., the version whose conformance requirements the client
+ may be depending upon the Printer to meet.
+
+ If the IPP object does not support that major version number supplied
+ by the client, i.e., the major version field of the "version-number"
+ parameter does not match any of the values of the Printer's "ipp-
+ versions-supported" (see section 4.4.14), the object MUST respond
+ with a status code of 'server-error-version-not-supported' along with
+ the closest version number that is supported (see section 13.1.5.4).
+ If the major version number is supported, but the minor version
+ number is not, the IPP object SHOULD accept and attempt to perform
+ the request (or reject the request if the operation is not
+ supported), else it rejects the request and returns the 'server-
+ error-version-not-supported' status code. In all cases, the IPP
+ object MUST return the "version-number" that it supports that is
+ closest to the version number supplied by the client in the request.
+
+ There is no version negotiation per se. However, if after receiving
+ a 'server-error-version-not-supported' status code from an IPP
+ object, a client SHOULD try again with a different version number. A
+ client MAY also determine the versions supported either from a
+ directory that conforms to Appendix E (see section 16) or by querying
+ the Printer object's "ipp-versions-supported" attribute (see section
+ 4.4.14) to determine which versions are supported.
+
+ An IPP object implementation MUST support version '1.1', i.e., meet
+ the conformance requirements for IPP/1.1 as specified in this
+ document and [RFC2910]. It is recommended that IPP object
+ implementations accept any request with the major version '1' (or
+ reject the request if the operation is not supported).
+
+ There is only one notion of "version number" that covers both IPP
+ Model and IPP Protocol changes. Thus the version number MUST change
+ when introducing a new version of the Model and Semantics document
+ (this document) or a new version of the "Encoding and Transport"
+ document [RFC2910].
+
+
+
+
+Hastings, et al. Standards Track [Page 36]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Changes to the major version number of the Model and Semantics
+ document indicate structural or syntactic changes that make it
+ impossible for older version of IPP clients and Printer objects to
+ correctly parse and correctly process the new or changed attributes,
+ operations and responses. If the major version number changes, the
+ minor version numbers is set to zero. As an example, adding the
+ REQUIRED "ipp-attribute-fidelity" attribute to version '1.1' (if it
+ had not been part of version '1.0'), would have required a change to
+ the major version number, since an IPP/1.0 Printer would not have
+ processed a request with the correct semantics that contained the
+ "ipp-attribute-fidelity" attribute that it did not know about. Items
+ that might affect the changing of the major version number include
+ any changes to the Model and Semantics document (this document) or
+ the "Encoding and Transport" document [RFC2910] itself, such as:
+
+ - reordering of ordered attributes or attribute sets
+ - changes to the syntax of existing attributes
+ - adding REQUIRED (for an IPP object to support) operation
+ attribute groups
+ - adding values to existing REQUIRED operation attributes
+ - adding REQUIRED operations
+
+ Changes to the minor version number indicate the addition of new
+ features, attributes and attribute values that may not be understood
+ by all IPP objects, but which can be ignored if not understood.
+ Items that might affect the changing of the minor version number
+ include any changes to the model objects and attributes but not the
+ encoding and transport rules [RFC2910] (except adding attribute
+ syntaxes). Examples of such changes are:
+
+ - grouping all extensions not included in a previous version into
+ a new version
+ - adding new attribute values
+ - adding new object attributes
+ - adding OPTIONAL (for an IPP object to support) operation
+ attributes (i.e., those attributes that an IPP object can ignore
+ without confusing clients)
+ - adding OPTIONAL (for an IPP object to support) operation
+ attribute groups (i.e., those attributes that an IPP object can
+ ignore without confusing clients)
+ - adding new attribute syntaxes
+ - adding OPTIONAL operations
+ - changing Job Description attributes or Printer Description
+ attributes from OPTIONAL to REQUIRED or vice versa.
+ - adding OPTIONAL attribute syntaxes to an existing attribute.
+
+ The encoding of the "version-number" MUST NOT change over any version
+ number (either major or minor). This rule guarantees that all future
+
+
+
+Hastings, et al. Standards Track [Page 37]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ versions will be backwards compatible with all previous versions (at
+ least for checking the "version-number"). In addition, any protocol
+ elements (attributes, error codes, tags, etc.) that are not carried
+ forward from one version to the next are deprecated so that they can
+ never be reused with new semantics.
+
+ Implementations that support a certain version NEED NOT support ALL
+ previous versions. As each new version is defined (through the
+ release of a new IPP specification document), that version will
+ specify which previous versions MUST and which versions SHOULD be
+ supported in compliant implementations.
+
+3.1.9 Job Creation Operations
+
+ In order to "submit a print job" and create a new Job object, a
+ client issues a create request. A create request is any one of
+ following three operation requests:
+
+ - The Print-Job Request: A client that wants to submit a print job
+ with only a single document uses the Print-Job operation. The
+ operation allows for the client to "push" the document data to
+ the Printer object by including the document data in the request
+ itself.
+
+ - The Print-URI Request: A client that wants to submit a print job
+ with only a single document (where the Printer object "pulls"
+ the document data instead of the client "pushing" the data to
+ the Printer object) uses the Print-URI operation. In this
+ case, the client includes in the request only a URI reference to
+ the document data (not the document data itself).
+
+ - The Create-Job Request: A client that wants to submit a print
+ job with multiple documents uses the Create-Job operation. This
+ operation is followed by an arbitrary number (one or more) of
+ Send-Document and/or Send-URI operations (each creating another
+ document for the newly create Job object). The Send-Document
+ operation includes the document data in the request (the client
+ "pushes" the document data to the printer), and the Send-URI
+ operation includes only a URI reference to the document data in
+ the request (the Printer "pulls" the document data from the
+ referenced location). The last Send-Document or Send-URI
+ request for a given Job object includes a "last-document"
+ operation attribute set to 'true' indicating that this is the
+ last request.
+
+ Throughout this model document, the term "create request" is used to
+ refer to any of these three operation requests.
+
+
+
+
+Hastings, et al. Standards Track [Page 38]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ A Create-Job operation followed by only one Send-Document operation
+ is semantically equivalent to a Print-Job operation, however, for
+ performance reasons, the client SHOULD use the Print-Job operation
+ for all single document jobs. Also, Print-Job is a REQUIRED
+ operation (all implementations MUST support it) whereas Create-Job is
+ an OPTIONAL operation, hence some implementations might not support
+ it.
+
+ Job submission time is the point in time when a client issues a
+ create request. The initial state of every Job object is the
+ 'pending', 'pending-held', or 'processing' state (see section 4.3.7).
+ When the Printer object begins processing the print job, the Job
+ object's state moves to 'processing'. This is known as job
+ processing time. There are validation checks that must be done at
+ job submission time and others that must be performed at job
+ processing time.
+
+ At job submission time and at the time a Validate-Job operation is
+ received, the Printer MUST do the following:
+
+ 1. Process the client supplied attributes and either accept or
+ reject the request
+ 2. Validate the syntax of and support for the scheme of any client
+ supplied URI
+
+ At job submission time the Printer object MUST validate whether or
+ not the supplied attributes, attribute syntaxes, and values are
+ supported by matching them with the Printer object's corresponding
+ "xxx-supported" attributes. See section 3.1.7 for details. [IPP-
+ IIG] presents suggested steps for an IPP object to either accept or
+ reject any request and additional steps for processing create
+ requests.
+
+ At job submission time the Printer object NEED NOT perform the
+ validation checks reserved for job processing time such as:
+
+ 1. Validating the document data
+ 2. Validating the actual contents of any client supplied URI
+ (resolve the reference and follow the link to the document
+ data)
+
+ At job submission time, these additional job processing time
+ validation checks are essentially useless, since they require
+ actually parsing and interpreting the document data, are not
+ guaranteed to be 100% accurate, and MUST be done, yet again, at job
+ processing time. Also, in the case of a URI, checking for
+ availability at job submission time does not guarantee availability
+
+
+
+
+Hastings, et al. Standards Track [Page 39]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ at job processing time. In addition, at job processing time, the
+ Printer object might discover any of the following conditions that
+ were not detectable at job submission time:
+
+ - runtime errors in the document data,
+ - nested document data that is in an unsupported format,
+ - the URI reference is no longer valid (i.e., the server hosting
+ the document might be down), or
+ - any other job processing error
+
+ At job submission time, a Printer object, especially a non-spooling
+ Printer, MAY accept jobs that it does not have enough space for. In
+ such a situation, a Printer object MAY stop reading data from a
+ client for an indefinite period of time. A client MUST be prepared
+ for a write operation to block for an indefinite period of time (see
+ section 5.1 on client conformance).
+
+ When a Printer object has too little space for starting a new job, it
+ MAY reject a new create request. In this case, a Printer object MUST
+ return a response (in reply to the rejected request) with a status-
+ code of 'server-error-busy' (see section 14.1.5.8) and it MAY close
+ the connection before receiving all bytes of the operation. A
+ Printer SHOULD indicate that it is temporarily unable to accept jobs
+ by setting the 'spool-space-full' value in its "printer-state-
+ reasons" attribute and removing the value when it can accept another
+ job (see section 4.4.12).
+
+ When receiving a 'server-error-busy' status-code in an operation
+ response, a client MUST be prepared for the Printer object to close
+ the connection before the client has sent all of the data (especially
+ for the Print-Job operation). A client MUST be prepared to keep
+ submitting a create request until the IPP Printer object accepts the
+ create request.
+
+ At job processing time, since the Printer object has already
+ responded with a successful status code in the response to the create
+ request, if the Printer object detects an error, the Printer object
+ is unable to inform the end user of the error with an operation
+ status code. In this case, the Printer, depending on the error, can
+ set the job object's "job-state", "job-state-reasons", or "job-
+ state-message" attributes to the appropriate value(s) so that later
+ queries can report the correct job status.
+
+ Note: Asynchronous notification of events is outside the scope of
+ this IPP/1.1 document.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 40]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+3.2 Printer Operations
+
+ All Printer operations are directed at Printer objects. A client
+ MUST always supply the "printer-uri" operation attribute in order to
+ identify the correct target of the operation.
+
+3.2.1 Print-Job Operation
+
+ This REQUIRED operation allows a client to submit a print job with
+ only one document and supply the document data (rather than just a
+ reference to the data). See Section 15 for the suggested steps for
+ processing create operations and their Operation and Job Template
+ attributes.
+
+3.2.1.1 Print-Job Request
+
+ The following groups of attributes are supplied as part of the
+ Print-Job Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1. The Printer object
+ MUST copy these values to the corresponding Job Description
+ attributes described in sections 4.3.19 and 4.3.20.
+
+ Target:
+ The "printer-uri" (uri) operation attribute which is the target
+ for this operation as described in section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+ "job-name" (name(MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It contains the client
+ supplied Job name. If this attribute is supplied by the
+ client, its value is used for the "job-name" attribute of the
+ newly created Job object. The client MAY automatically include
+ any information that will help the end-user distinguish amongst
+ his/her jobs, such as the name of the application program along
+ with information from the document, such as the document name,
+ document subject, or source file name. If this attribute is
+ not supplied by the client, the Printer generates a name to use
+ in the "job-name" attribute of the newly created Job object
+ (see Section 4.3.5).
+
+
+
+Hastings, et al. Standards Track [Page 41]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ "ipp-attribute-fidelity" (boolean):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. The value 'true' indicates
+ that total fidelity to client supplied Job Template attributes
+ and values is required, else the Printer object MUST reject the
+ Print-Job request. The value 'false' indicates that a
+ reasonable attempt to print the Job object is acceptable and
+ the Printer object MUST accept the Print-Job request. If not
+ supplied, the Printer object assumes the value is 'false'. All
+ Printer objects MUST support both types of job processing. See
+ section 15 for a full description of "ipp-attribute-fidelity"
+ and its relationship to other attributes, especially the
+ Printer object's "pdl-override-supported" attribute.
+
+ "document-name" (name(MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It contains the client
+ supplied document name. The document name MAY be different
+ than the Job name. Typically, the client software
+ automatically supplies the document name on behalf of the end
+ user by using a file name or an application generated name. If
+ this attribute is supplied, its value can be used in a manner
+ defined by each implementation. Examples include: printed
+ along with the Job (job start sheet, page adornments, etc.),
+ used by accounting or resource tracking management tools, or
+ even stored along with the document as a document level
+ attribute. IPP/1.1 does not support the concept of document
+ level attributes.
+
+ "compression" (type3 keyword):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute and the "compression-
+ supported" attribute (see section 4.4.32). The client supplied
+ "compression" operation attribute identifies the compression
+ algorithm used on the document data. The following cases exist:
+
+ a) If the client omits this attribute, the Printer object MUST
+ assume that the data is not compressed (i.e. the Printer
+ follows the rules below as if the client supplied the
+ "compression" attribute with a value of 'none').
+ b) If the client supplies this attribute, but the value is not
+ supported by the Printer object, i.e., the value is not one
+ of the values of the Printer object's "compression-
+ supported" attribute, the Printer object MUST reject the
+ request, and return the 'client-error-compression-not-
+ supported' status code. See section 3.1.7 for returning
+ unsupported attributes and values.
+
+
+
+
+Hastings, et al. Standards Track [Page 42]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ c) If the client supplies the attribute and the Printer object
+ supports the attribute value, the Printer object uses the
+ corresponding decompression algorithm on the document data.
+ d) If the decompression algorithm fails before the Printer
+ returns an operation response, the Printer object MUST
+ reject the request and return the 'client-error-
+ compression-error' status code.
+ e) If the decompression algorithm fails after the Printer
+ returns an operation response, the Printer object MUST abort
+ the job and add the 'compression-error' value to the job's
+ "job-state-reasons" attribute.
+ f) If the decompression algorithm succeeds, the document data
+ MUST then have the format specified by the job's "document-
+ format" attribute, if supplied (see "document-format"
+ operation attribute definition below).
+
+ "document-format" (mimeMediaType):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. The value of this
+ attribute identifies the format of the supplied document data.
+ The following cases exist:
+
+ a) If the client does not supply this attribute, the Printer
+ object assumes that the document data is in the format
+ defined by the Printer object's "document-format-default"
+ attribute. (i.e. the Printer follows the rules below as if
+ the client supplied the "document-format" attribute with a
+ value equal to the printer's default value).
+ b) If the client supplies this attribute, but the value is not
+ supported by the Printer object, i.e., the value is not one
+ of the values of the Printer object's "document-format-
+ supported" attribute, the Printer object MUST reject the
+ request and return the 'client-error-document-format-not-
+ supported' status code.
+ c) If the client supplies this attribute and its value is
+ 'application/octet-stream' (i.e. to be auto-sensed, see
+ Section 4.1.9.1), and the format is not one of the
+ document-formats that the Printer can auto-sense, and this
+ check occurs before the Printer returns an operation
+ response, then the Printer MUST reject the request and
+ return the 'client-error-document-format-not-supported'
+ status code.
+ d) If the client supplies this attribute, and the value is
+ supported by the Printer object, the Printer is capable of
+ interpreting the document data.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 43]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ e) If interpreting of the document data fails before the
+ Printer returns an operation response, the Printer object
+ MUST reject the request and return the 'client-error-
+ document-format-error' status code.
+ f) If interpreting of the document data fails after the Printer
+ returns an operation response, the Printer object MUST abort
+ the job and add the 'document-format-error' value to the
+ job's "job-state-reasons" attribute.
+
+ "document-natural-language" (naturalLanguage):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute. This attribute
+ specifies the natural language of the document for those
+ document-formats that require a specification of the natural
+ language in order to image the document unambiguously. There
+ are no particular values required for the Printer object to
+ support.
+
+ "job-k-octets" (integer(0:MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute and the "job-k-
+ octets-supported" attribute (see section 4.4.33). The client
+ supplied "job-k-octets" operation attribute identifies the
+ total size of the document(s) in K octets being submitted (see
+ section 4.3.17.1 for the complete semantics). If the client
+ supplies the attribute and the Printer object supports the
+ attribute, the value of the attribute is used to populate the
+ Job object's "job-k-octets" Job Description attribute.
+
+ For this attribute and the following two attributes ("job-
+ impressions", and "job-media-sheets"), if the client supplies
+ the attribute, but the Printer object does not support the
+ attribute, the Printer object ignores the client-supplied
+ value. If the client supplies the attribute and the Printer
+ supports the attribute, and the value is within the range of
+ the corresponding Printer object's "xxx-supported" attribute,
+ the Printer object MUST use the value to populate the Job
+ object's "xxx" attribute. If the client supplies the attribute
+ and the Printer supports the attribute, but the value is
+ outside the range of the corresponding Printer object's "xxx-
+ supported" attribute, the Printer object MUST copy the
+ attribute and its value to the Unsupported Attributes response
+ group, reject the request, and return the 'client-error-
+ attributes-or-values-not-supported' status code. If the client
+ does not supply the attribute, the Printer object MAY choose to
+ populate the corresponding Job object attribute depending on
+ whether the Printer object supports the attribute and is able
+ to calculate or discern the correct value.
+
+
+
+Hastings, et al. Standards Track [Page 44]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ "job-impressions" (integer(0:MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute and the "job-
+ impressions-supported" attribute (see section 4.4.34). The
+ client supplied "job-impressions" operation attribute
+ identifies the total size in number of impressions of the
+ document(s) being submitted (see section 4.3.17.2 for the
+ complete semantics).
+
+ See last paragraph under "job-k-octets".
+
+ "job-media-sheets" (integer(0:MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute and the "job-media-
+ sheets-supported" attribute (see section 4.4.35). The client
+ supplied "job-media-sheets" operation attribute identifies the
+ total number of media sheets to be produced for this job (see
+ section 4.3.17.3 for the complete semantics).
+
+ See last paragraph under "job-k-octets".
+
+ Group 2: Job Template Attributes
+
+ The client OPTIONALLY supplies a set of Job Template attributes as
+ defined in section 4.2. If the client is not supplying any Job
+ Template attributes in the request, the client SHOULD omit Group 2
+ rather than sending an empty group. However, a Printer object
+ MUST be able to accept an empty group.
+
+ Group 3: Document Content
+
+ The client MUST supply the document data to be processed.
+
+ In addition to the MANDATORY parameters required for every
+ operation request, the simplest Print-Job Request consists of just
+ the "attributes-charset" and "attributes-natural-language"
+ operation attributes; the "printer-uri" target operation
+ attribute; the Document Content and nothing else. In this simple
+ case, the Printer object:
+
+ - creates a new Job object (the Job object contains a single
+ document),
+ - stores a generated Job name in the "job-name" attribute in the
+ natural language and charset requested (see Section 3.1.4.1) (if
+ those are supported, otherwise using the Printer object's
+ default natural language and charset), and
+
+
+
+
+
+Hastings, et al. Standards Track [Page 45]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ - at job processing time, uses its corresponding default value
+ attributes for the supported Job Template attributes that were
+ not supplied by the client as IPP attribute or embedded
+ instructions in the document data.
+
+3.2.1.2 Print-Job Response
+
+ The Printer object MUST return to the client the following sets of
+ attributes as part of the Print-Job Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) and/or a "detailed-status-message" (text(MAX))
+ operation attribute as described in sections 13 and 3.1.6. If
+ the client supplies unsupported or conflicting Job Template
+ attributes or values, the Printer object MUST reject or accept
+ the Print-Job request depending on the whether the client
+ supplied a 'true' or 'false' value for the "ipp-attribute-
+ fidelity" operation attribute. See the Implementer's Guide
+ [IPP-IIG] for a complete description of the suggested steps for
+ processing a create request.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ See section 3.1.7 for details on returning Unsupported Attributes.
+
+ The value of the "ipp-attribute-fidelity" supplied by the client
+ does not affect what attributes the Printer object returns in this
+ group. The value of "ipp-attribute-fidelity" only affects whether
+ the Print-Job operation is accepted or rejected. If the job is
+ accepted, the client may query the job using the Get-Job-
+ Attributes operation requesting the unsupported attributes that
+ were returned in the create response to see which attributes were
+ ignored (not stored on the Job object) and which attributes were
+ stored with other (substituted) values.
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 46]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Group 3: Job Object Attributes
+
+ "job-uri" (uri):
+ The Printer object MUST return the Job object's URI by
+ returning the contents of the REQUIRED "job-uri" Job object
+ attribute. The client uses the Job object's URI when directing
+ operations at the Job object. The Printer object always uses
+ its configured security policy when creating the new URI.
+ However, if the Printer object supports more than one URI, the
+ Printer object also uses information about which URI was used
+ in the Print-Job Request to generated the new URI so that the
+ new URI references the correct access channel. In other words,
+ if the Print-Job Request comes in over a secure channel, the
+ Printer object MUST generate a Job URI that uses the secure
+ channel as well.
+
+ "job-id" (integer(1:MAX)):
+ The Printer object MUST return the Job object's Job ID by
+ returning the REQUIRED "job-id" Job object attribute. The
+ client uses this "job-id" attribute in conjunction with the
+ "printer-uri" attribute used in the Print-Job Request when
+ directing Job operations at the Printer object.
+
+ "job-state" (type1 enum):
+ The Printer object MUST return the Job object's REQUIRED "job-
+ state" attribute. The value of this attribute (along with the
+ value of the next attribute: "job-state-reasons") is taken
+ from a "snapshot" of the new Job object at some meaningful
+ point in time (implementation defined) between when the Printer
+ object receives the Print-Job Request and when the Printer
+ object returns the response.
+
+ "job-state-reasons" (1setOf type2 keyword):
+ The Printer object MUST return the Job object's REQUIRED "job-
+ state-reasons" attribute.
+
+ "job-state-message" (text(MAX)):
+ The Printer object OPTIONALLY returns the Job object's OPTIONAL
+ "job-state-message" attribute. If the Printer object supports
+ this attribute then it MUST be returned in the response. If
+ this attribute is not returned in the response, the client can
+ assume that the "job-state-message" attribute is not supported
+ and will not be returned in a subsequent Job object query.
+
+ "number-of-intervening-jobs" (integer(0:MAX)):
+ The Printer object OPTIONALLY returns the Job object's OPTIONAL
+ "number-of-intervening-jobs" attribute. If the Printer object
+ supports this attribute then it MUST be returned in the
+
+
+
+Hastings, et al. Standards Track [Page 47]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ response. If this attribute is not returned in the response,
+ the client can assume that the "number-of-intervening-jobs"
+ attribute is not supported and will not be returned in a
+ subsequent Job object query.
+
+ Note: Since any printer state information which affects a job's
+ state is reflected in the "job-state" and "job-state-reasons"
+ attributes, it is sufficient to return only these attributes
+ and no specific printer status attributes.
+
+ Note: In addition to the MANDATORY parameters required for every
+ operation response, the simplest response consists of the just the
+ "attributes-charset" and "attributes-natural-language" operation
+ attributes and the "job-uri", "job-id", and "job-state" Job Object
+ Attributes. In this simplest case, the status code is 'successful-
+ ok' and there is no "status-message" or "detailed-status-message"
+ operation attribute.
+
+3.2.2 Print-URI Operation
+
+ This OPTIONAL operation is identical to the Print-Job operation
+ (section 3.2.1) except that a client supplies a URI reference to the
+ document data using the "document-uri" (uri) operation attribute (in
+ Group 1) rather than including the document data itself. Before
+ returning the response, the Printer MUST validate that the Printer
+ supports the retrieval method (e.g., http, ftp, etc.) implied by the
+ URI, and MUST check for valid URI syntax. If the client-supplied URI
+ scheme is not supported, i.e. the value is not in the Printer
+ object's "referenced-uri-scheme-supported" attribute, the Printer
+ object MUST reject the request and return the 'client-error-uri-
+ scheme-not-supported' status code.
+
+ The IPP Printer MAY validate the accessibility of the document as
+ part of the operation or subsequently. If the Printer determines an
+ accessibility problem before returning an operation response, it
+ rejects the request and returns the 'client-error-document-access-
+ error' status code. The Printer MAY also return a specific document
+ access error code using the "document-access-error" operation
+ attribute (see section 3.1.6.4).
+
+ If the Printer determines this document accessibility problem after
+ accepting the request and returning an operation response with one of
+ the successful status codes, the Printer adds the 'document-access-
+ error' value to the job's "job-state-reasons" attribute and MAY
+ populate the job's "job-document-access-errors" Job Description
+ attribute (see section 4.3.11). See The Implementer's Guide [IPP-
+ IIG] for suggested additional checks.
+
+
+
+
+Hastings, et al. Standards Track [Page 48]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ If the Printer object supports this operation, it MUST support the
+ "reference-uri-schemes-supported" Printer attribute (see section
+ 4.4.27).
+
+ It is up to the IPP object to interpret the URI and subsequently
+ "pull" the document from the source referenced by the URI string.
+
+3.2.3 Validate-Job Operation
+
+ This REQUIRED operation is similar to the Print-Job operation
+ (section 3.2.1) except that a client supplies no document data and
+ the Printer allocates no resources (i.e., it does not create a new
+ Job object). This operation is used only to verify capabilities of a
+ printer object against whatever attributes are supplied by the client
+ in the Validate-Job request. By using the Validate-Job operation a
+ client can validate that an identical Print-Job operation (with the
+ document data) would be accepted. The Validate-Job operation also
+ performs the same security negotiation as the Print-Job operation
+ (see section 8), so that a client can check that the client and
+ Printer object security requirements can be met before performing a
+ Print-Job operation.
+
+ The Validate-Job operation does not accept a "document-uri" attribute
+ in order to allow a client to check that the same Print-URI operation
+ will be accepted, since the client doesn't send the data with the
+ Print-URI operation. The client SHOULD just issue the Print-URI
+ request.
+
+ The Printer object returns the same status codes, Operation
+ Attributes (Group 1) and Unsupported Attributes (Group 2) as the
+ Print-Job operation. However, no Job Object Attributes (Group 3) are
+ returned, since no Job object is created.
+
+3.2.4 Create-Job Operation
+
+ This OPTIONAL operation is similar to the Print-Job operation
+ (section 3.2.1) except that in the Create-Job request, a client does
+ not supply document data or any reference to document data. Also,
+ the client does not supply any of the "document-name", "document-
+ format", "compression", or "document-natural-language" operation
+ attributes. This operation is followed by one or more Send-Document
+ or Send-URI operations. In each of those operation requests, the
+ client OPTIONALLY supplies the "document-name", "document-format",
+ and "document-natural-language" attributes for each document in the
+ multi-document Job object.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 49]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ If a Printer object supports the Create-Job operation, it MUST also
+ support the Send-Document operation and also MAY support the Send-URI
+ operation.
+
+ If the Printer object supports this operation, it MUST support the
+ "multiple-operation-time-out" Printer attribute (see section 4.4.31).
+
+ If the Printer object supports this operation, then it MUST support
+ the "multiple-document-jobs-supported" Printer Description attribute
+ (see section 4.4.16) and indicate whether or not it supports
+ multiple-document jobs.
+
+ If the Printer object supports this operation and supports multiple
+ documents in a job, then it MUST support the "multiple-document-
+ handling" Job Template job attribute with at least one value (see
+ section 4.2.4) and the associated "multiple-document-handling-
+ default" and "multiple-document-handling-supported" Job Template
+ Printer attributes (see section 4.2).
+
+ After the Create-Job operation has completed, the value of the "job-
+ state" attribute is similar to the "job-state" after a Print-Job,
+ even though no document-data has arrived. A Printer MAY set the
+ 'job-data-insufficient' value of the job's "job-state-reason"
+ attribute to indicate that processing cannot begin until sufficient
+ data has arrived and set the "job-state" to either 'pending' or
+ 'pending-held'. A non-spooling printer that doesn't implement the
+ 'pending' job state may even set the "job-state" to 'processing',
+ even though there is not yet any data to process. See sections 4.3.7
+ and 4.3.8.
+
+3.2.5 Get-Printer-Attributes Operation
+
+ This REQUIRED operation allows a client to request the values of the
+ attributes of a Printer object. In the request, the client supplies
+ the set of Printer attribute names and/or attribute group names in
+ which the requester is interested. In the response, the Printer
+ object returns a corresponding attribute set with the appropriate
+ attribute values filled in.
+
+ For Printer objects, the possible names of attribute groups are:
+
+ - 'job-template': the subset of the Job Template attributes that
+ apply to a Printer object (the last two columns of the table in
+ Section 4.2) that the implementation supports for Printer
+ objects.
+ - 'printer-description': the subset of the attributes specified in
+ Section 4.4 that the implementation supports for Printer
+ objects.
+
+
+
+Hastings, et al. Standards Track [Page 50]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ - 'all': the special group 'all' that includes all attributes that
+ the implementation supports for Printer objects.
+
+ Since a client MAY request specific attributes or named groups, there
+ is a potential that there is some overlap. For example, if a client
+ requests, 'printer-name' and 'all', the client is actually requesting
+ the "printer-name" attribute twice: once by naming it explicitly, and
+ once by inclusion in the 'all' group. In such cases, the Printer
+ object NEED NOT return each attribute only once in the response even
+ if it is requested multiple times. The client SHOULD NOT request the
+ same attribute in multiple ways.
+
+ It is NOT REQUIRED that a Printer object support all attributes
+ belonging to a group (since some attributes are OPTIONAL). However,
+ it is REQUIRED that each Printer object support all group names.
+
+3.2.5.1 Get-Printer-Attributes Request
+
+ The following sets of attributes are part of the Get-Printer-
+ Attributes Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1.
+
+ Target:
+ The "printer-uri" (uri) operation attribute which is the target
+ for this operation as described in section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+ "requested-attributes" (1setOf keyword):
+ The client OPTIONALLY supplies a set of attribute names and/or
+ attribute group names in whose values the requester is
+ interested. The Printer object MUST support this attribute.
+ If the client omits this attribute, the Printer MUST respond as
+ if this attribute had been supplied with a value of 'all'.
+
+ "document-format" (mimeMediaType):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. This attribute is useful
+ for a Printer object to determine the set of supported
+ attribute values that relate to the requested document format.
+ The Printer object MUST return the attributes and values that
+
+
+
+Hastings, et al. Standards Track [Page 51]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ it uses to validate a job on a create or Validate-Job operation
+ in which this document format is supplied. The Printer object
+ SHOULD return only (1) those attributes that are supported for
+ the specified format and (2) the attribute values that are
+ supported for the specified document format. By specifying the
+ document format, the client can get the Printer object to
+ eliminate the attributes and values that are not supported for
+ a specific document format. For example, a Printer object
+ might have multiple interpreters to support both
+ 'application/postscript' (for PostScript) and 'text/plain' (for
+ text) documents. However, for only one of those interpreters
+ might the Printer object be able to support "number-up" with
+ values of '1', '2', and '4'. For the other interpreter it
+ might be able to only support "number-up" with a value of '1'.
+ Thus a client can use the Get-Printer-Attributes operation to
+ obtain the attributes and values that will be used to
+ accept/reject a create job operation.
+
+ If the Printer object does not distinguish between different
+ sets of supported values for each different document format
+ when validating jobs in the create and Validate-Job operations,
+ it MUST NOT distinguish between different document formats in
+ the Get-Printer-Attributes operation. If the Printer object
+ does distinguish between different sets of supported values for
+ each different document format specified by the client, this
+ specialization applies only to the following Printer object
+ attributes:
+
+ - Printer attributes that are Job Template attributes ("xxx-
+ default" "xxx-supported", and "xxx-ready" in the Table in
+ Section 4.2),
+ - "pdl-override-supported",
+ - "compression-supported",
+ - "job-k-octets-supported",
+ - "job-impressions-supported",
+ - "job-media-sheets-supported",
+ - "printer-driver-installer",
+ - "color-supported", and
+ - "reference-uri-schemes-supported"
+
+ The values of all other Printer object attributes (including
+ "document-format-supported") remain invariant with respect to the
+ client supplied document format (except for new Printer
+ description attribute as registered according to section 6.2).
+
+ If the client omits this "document-format" operation attribute,
+ the Printer object MUST respond as if the attribute had been
+ supplied with the value of the Printer object's "document-format-
+
+
+
+Hastings, et al. Standards Track [Page 52]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ default" attribute. It is RECOMMENDED that the client always
+ supply a value for "document-format", since the Printer object's
+ "document-format-default" may be 'application/octet-stream', in
+ which case the returned attributes and values are for the union of
+ the document formats that the Printer can automatically sense.
+ For more details, see the description of the 'mimeMediaType'
+ attribute syntax in section 4.1.9.
+
+ If the client supplies a value for the "document-format" Operation
+ attribute that is not supported by the Printer, i.e., is not among
+ the values of the Printer object's "document-format-supported"
+ attribute, the Printer object MUST reject the operation and return
+ the 'client-error-document-format-not-supported' status code.
+
+3.2.5.2 Get-Printer-Attributes Response
+
+ The Printer object returns the following sets of attributes as part
+ of the Get-Printer-Attributes Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) and/or a "detailed-status-message" (text(MAX))
+ operation attribute as described in sections 13 and 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ See section 3.1.7 for details on returning Unsupported Attributes.
+
+ The response NEED NOT contain the "requested-attributes" operation
+ attribute with any supplied values (attribute keywords) that were
+ requested by the client but are not supported by the IPP object.
+ If the Printer object does return unsupported attributes
+ referenced in the "requested-attributes" operation attribute and
+ that attribute included group names, such as 'all', the
+ unsupported attributes MUST NOT include attributes described in
+ the standard but not supported by the implementation.
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 53]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Group 3: Printer Object Attributes
+
+ This is the set of requested attributes and their current values.
+ The Printer object ignores (does not respond with) any requested
+ attribute which is not supported. The Printer object MAY respond
+ with a subset of the supported attributes and values, depending on
+ the security policy in force. However, the Printer object MUST
+ respond with the 'unknown' value for any supported attribute
+ (including all REQUIRED attributes) for which the Printer object
+ does not know the value. Also the Printer object MUST respond
+ with the 'no-value' for any supported attribute (including all
+ REQUIRED attributes) for which the system administrator has not
+ configured a value. See the description of the "out-of-band"
+ values in the beginning of Section 4.1.
+
+3.2.6 Get-Jobs Operation
+
+ This REQUIRED operation allows a client to retrieve the list of Job
+ objects belonging to the target Printer object. The client may also
+ supply a list of Job attribute names and/or attribute group names. A
+ group of Job object attributes will be returned for each Job object
+ that is returned.
+
+ This operation is similar to the Get-Job-Attributes operation, except
+ that this Get-Jobs operation returns attributes from possibly more
+ than one object.
+
+3.2.6.1 Get-Jobs Request
+
+ The client submits the Get-Jobs request to a Printer object.
+
+ The following groups of attributes are part of the Get-Jobs Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1.
+
+ Target:
+ The "printer-uri" (uri) operation attribute which is the target
+ for this operation as described in section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 54]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ "limit" (integer(1:MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It is an integer value that
+ determines the maximum number of jobs that a client will
+ receive from the Printer even if "which-jobs" or "my-jobs"
+ constrain which jobs are returned. The limit is a "stateless
+ limit" in that if the value supplied by the client is 'N', then
+ only the first 'N' jobs are returned in the Get-Jobs Response.
+ There is no mechanism to allow for the next 'M' jobs after the
+ first 'N' jobs. If the client does not supply this attribute,
+ the Printer object responds with all applicable jobs.
+
+ "requested-attributes" (1setOf type2 keyword):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It is a set of Job
+ attribute names and/or attribute groups names in whose values
+ the requester is interested. This set of attributes is
+ returned for each Job object that is returned. The allowed
+ attribute group names are the same as those defined in the
+ Get-Job-Attributes operation in section 3.3.4. If the client
+ does not supply this attribute, the Printer MUST respond as if
+ the client had supplied this attribute with two values: 'job-
+ uri' and 'job-id'.
+
+ "which-jobs" (type2 keyword):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It indicates which Job
+ objects MUST be returned by the Printer object. The values for
+ this attribute are:
+
+ 'completed': This includes any Job object whose state is
+ 'completed', 'canceled', or 'aborted'.
+ 'not-completed': This includes any Job object whose state is
+ 'pending', 'processing', 'processing-stopped', or 'pending-
+ held'.
+
+ A Printer object MUST support both values. However, if the
+ implementation does not keep jobs in the 'completed',
+ 'canceled', and 'aborted' states, then it returns no jobs when
+ the 'completed' value is supplied.
+
+ If a client supplies some other value, the Printer object MUST
+ copy the attribute and the unsupported value to the Unsupported
+ Attributes response group, reject the request, and return the
+ 'client-error-attributes-or-values-not-supported' status code.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 55]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ If the client does not supply this attribute, the Printer
+ object MUST respond as if the client had supplied the attribute
+ with a value of 'not-completed'.
+
+ "my-jobs" (boolean):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It indicates whether jobs
+ from all users or just the jobs submitted by the requesting
+ user of this request MUST be considered as candidate jobs to be
+ returned by the Printer object. If the client does not supply
+ this attribute, the Printer object MUST respond as if the
+ client had supplied the attribute with a value of 'false',
+ i.e., jobs from all users. The means for authenticating the
+ requesting user and matching the jobs is described in section
+ 8.
+
+3.2.6.2 Get-Jobs Response
+
+ The Printer object returns all of the Job objects up to the number
+ specified by the "limit" attribute that match the criteria as defined
+ by the attribute values supplied by the client in the request. It is
+ possible that no Job objects are returned since there may literally
+ be no Job objects at the Printer, or there may be no Job objects that
+ match the criteria supplied by the client. If the client requests
+ any Job attributes at all, there is a set of Job Object Attributes
+ returned for each Job object.
+
+ It is not an error for the Printer to return 0 jobs. If the response
+ returns 0 jobs because there are no jobs matching the criteria, and
+ the request would have returned 1 or more jobs with a status code of
+ 'successful-ok' if there had been jobs matching the criteria, then
+ the status code for 0 jobs MUST be 'successful-ok'.
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) and/or a "detailed-status-message" (text(MAX))
+ operation attribute as described in sections 13 and 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 56]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Group 2: Unsupported Attributes
+
+ See section 3.1.7 for details on returning Unsupported Attributes.
+
+ The response NEED NOT contain the "requested-attributes" operation
+ attribute with any supplied values (attribute keywords) that were
+ requested by the client but are not supported by the IPP object.
+ If the Printer object does return unsupported attributes
+ referenced in the "requested-attributes" operation attribute and
+ that attribute included group names, such as 'all', the
+ unsupported attributes MUST NOT include attributes described in
+ the standard but not supported by the implementation.
+
+ Groups 3 to N: Job Object Attributes
+
+ The Printer object responds with one set of Job Object Attributes
+ for each returned Job object. The Printer object ignores (does
+ not respond with) any requested attribute or value which is not
+ supported or which is restricted by the security policy in force,
+ including whether the requesting user is the user that submitted
+ the job (job originating user) or not (see section 8). However,
+ the Printer object MUST respond with the 'unknown' value for any
+ supported attribute (including all REQUIRED attributes) for which
+ the Printer object does not know the value, unless it would
+ violate the security policy. See the description of the "out-of-
+ band" values in the beginning of Section 4.1.
+
+ Jobs are returned in the following order:
+
+ - If the client requests all 'completed' Jobs (Jobs in the
+ 'completed', 'aborted', or 'canceled' states), then the Jobs are
+ returned newest to oldest (with respect to actual completion
+ time)
+ - If the client requests all 'not-completed' Jobs (Jobs in the
+ 'pending', 'processing', 'pending-held', and 'processing-
+ stopped' states), then Jobs are returned in relative
+ chronological order of expected time to complete (based on
+ whatever scheduling algorithm is configured for the Printer
+ object).
+
+3.2.7 Pause-Printer Operation
+
+ This OPTIONAL operation allows a client to stop the Printer object
+ from scheduling jobs on all its devices. Depending on
+ implementation, the Pause-Printer operation MAY also stop the Printer
+ from processing the current job or jobs. Any job that is currently
+ being printed is either stopped as soon as the implementation permits
+
+
+
+
+Hastings, et al. Standards Track [Page 57]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ or is completed, depending on implementation. The Printer object
+ MUST still accept create operations to create new jobs, but MUST
+ prevent any jobs from entering the 'processing' state.
+
+ If the Pause-Printer operation is supported, then the Resume-Printer
+ operation MUST be supported, and vice-versa.
+
+ The IPP Printer stops the current job(s) on its device(s) that were
+ in the 'processing' or 'processing-stopped' states as soon as the
+ implementation permits. If the implementation will take appreciable
+ time to stop, the IPP Printer adds the 'moving-to-paused' value to
+ the Printer object's "printer-state-reasons" attribute (see section
+ 4.4.12). When the device(s) have all stopped, the IPP Printer
+ transitions the Printer object to the 'stopped' state, removes the
+ 'moving-to-paused' value, if present, and adds the 'paused' value to
+ the Printer object's "printer-state-reasons" attribute.
+
+ When the current job(s) complete that were in the 'processing' state,
+ the IPP Printer transitions them to the 'completed' state. When the
+ current job(s) stop in mid processing that were in the 'processing'
+ state, the IPP Printer transitions them to the 'processing-stopped'
+ state and adds the 'printer-stopped' value to the job's "job-state-
+ reasons" attribute.
+
+ For any jobs that are 'pending' or 'pending-held', the 'printer-
+ stopped' value of the jobs' "job-state-reasons" attribute also
+ applies. However, the IPP Printer NEED NOT update those jobs' "job-
+ state-reasons" attributes and only need return the 'printer-stopped'
+ value when those jobs are queried (so-called "lazy evaluation").
+
+ Whether the Pause-Printer operation affects jobs that were submitted
+ to the device from other sources than the IPP Printer object in the
+ same way that the Pause-Printer operation affects jobs that were
+ submitted to the IPP Printer object using IPP, depends on
+ implementation, i.e., on whether the IPP protocol is being used as a
+ universal management protocol or just to manage IPP jobs,
+ respectively.
+
+ The IPP Printer MUST accept the request in any state and transition
+ the Printer to the indicated new "printer-state" before returning as
+ follows:
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 58]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Current New "printer IPP Printer's response status
+ "printer- "printer- -state- code and action:
+ state" state" reasons"
+
+ 'idle' 'stopped' 'paused' 'successful-ok'
+ 'processing' 'processing' 'moving- OPTION 1: 'successful-ok';
+ to- Later, when all output has
+ paused' stopped, the "printer-state"
+ becomes 'stopped', and the
+ 'paused' value replaces the
+ 'moving-to-paused' value in the
+ "printer-state-reasons"
+ attribute
+ 'processing' 'stopped' 'paused' OPTION 2: 'successful-ok';
+ all device output stopped
+ immediately
+ 'stopped' 'stopped' 'paused' 'successful-ok'
+
+ Access Rights: The authenticated user (see section 8.3) performing
+ this operation must be an operator or administrator of the Printer
+ object (see Sections 1 and 8.5). Otherwise, the IPP Printer MUST
+ reject the operation and return: 'client-error-forbidden', 'client-
+ error-not-authenticated', or 'client-error-not-authorized' as
+ appropriate.
+
+3.2.7.1 Pause-Printer Request
+
+ The following groups of attributes are part of the Pause-Printer
+ Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1.
+
+ Target:
+ The "printer-uri" (uri) operation attribute which is the target
+ for this operation as described in section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 59]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+3.2.7.2 Pause-Printer Response
+
+ The following groups of attributes are part of the Pause-Printer
+ Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) and/or a "detailed-status-message" (text(MAX))
+ operation attribute as described in sections 13 and 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ See section 3.1.7 for details on returning Unsupported Attributes.
+
+3.2.8 Resume-Printer Operation
+
+ This operation allows a client to resume the Printer object
+ scheduling jobs on all its devices. The Printer object MUST remove
+ the 'paused' and 'moving-to-paused' values from the Printer object's
+ "printer-state-reasons" attribute, if present. If there are no other
+ reasons to keep a device paused (such as media-jam), the IPP Printer
+ is free to transition itself to the 'processing' or 'idle' states,
+ depending on whether there are jobs to be processed or not,
+ respectively, and the device(s) resume processing jobs.
+
+ If the Pause-Printer operation is supported, then the Resume-Printer
+ operation MUST be supported, and vice-versa.
+
+ The IPP Printer removes the 'printer-stopped' value from any job's
+ "job-state-reasons" attributes contained in that Printer.
+
+ The IPP Printer MUST accept the request in any state, transition the
+ Printer object to the indicated new state as follows:
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 60]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Current New "printer- IPP Printer's response status code and
+ "printer- state" action:
+ state"
+
+ 'idle' 'idle' 'successful-ok'
+ 'processing' 'processing' 'successful-ok'
+
+ 'stopped' 'processing' 'successful-ok';
+ when there are jobs to be processed
+ 'stopped' 'idle' 'successful-ok';
+ when there are no jobs to be processed.
+
+ Access Rights: The authenticated user (see section 8.3) performing
+ this operation must be an operator or administrator of the Printer
+ object (see Sections 1 and 8.5). Otherwise, the IPP Printer MUST
+ reject the operation and return: 'client-error-forbidden', 'client-
+ error-not-authenticated', or 'client-error-not-authorized' as
+ appropriate.
+
+ The Resume-Printer Request and Resume-Printer Response have the same
+ attribute groups and attributes as the Pause-Printer operation (see
+ sections 3.2.7.1 and 3.2.7.2).
+
+3.2.9 Purge-Jobs Operation
+
+ This OPTIONAL operation allows a client to remove all jobs from an
+ IPP Printer object, regardless of their job states, including jobs in
+ the Printer object's Job History (see Section 4.3.7.2). After a
+ Purge-Jobs operation has been performed, a Printer object MUST return
+ no jobs in subsequent Get-Job-Attributes and Get-Jobs responses
+ (until new jobs are submitted).
+
+ Whether the Purge-Jobs (and Get-Jobs) operation affects jobs that
+ were submitted to the device from other sources than the IPP Printer
+ object in the same way that the Purge-Jobs operation affects jobs
+ that were submitted to the IPP Printer object using IPP, depends on
+ implementation, i.e., on whether the IPP protocol is being used as a
+ universal management protocol or just to manage IPP jobs,
+ respectively.
+
+ Note: if an operator wants to cancel all jobs without clearing out
+ the Job History, the operator uses the Cancel-Job operation on each
+ job instead of using the Purge-Jobs operation.
+
+ The Printer object MUST accept this operation in any state and
+ transition the Printer object to the 'idle' state.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 61]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Access Rights: The authenticated user (see section 8.3) performing
+ this operation must be an operator or administrator of the Printer
+ object (see Sections 1 and 8.5). Otherwise, the IPP object MUST
+ reject the operation and return: client-error-forbidden, client-
+ error-not-authenticated, and client-error-not-authorized as
+ appropriate.
+
+ The Purge-Jobs Request and Purge-Jobs Response have the same
+ attribute groups and attributes as the Pause-Printer operation (see
+ sections 3.2.7.1 and 3.2.7.2).
+
+3.3 Job Operations
+
+ All Job operations are directed at Job objects. A client MUST always
+ supply some means of identifying the Job object in order to identify
+ the correct target of the operation. That job identification MAY
+ either be a single Job URI or a combination of a Printer URI with a
+ Job ID. The IPP object implementation MUST support both forms of
+ identification for every job.
+
+3.3.1 Send-Document Operation
+
+ This OPTIONAL operation allows a client to create a multi-document
+ Job object that is initially "empty" (contains no documents). In the
+ Create-Job response, the Printer object returns the Job object's URI
+ (the "job-uri" attribute) and the Job object's 32-bit identifier (the
+ "job-id" attribute). For each new document that the client desires
+ to add, the client uses a Send-Document operation. Each Send-
+ Document Request contains the entire stream of document data for one
+ document.
+
+ If the Printer supports this operation but does not support multiple
+ documents per job, the Printer MUST reject subsequent Send-Document
+ operations supplied with data and return the 'server-error-multiple-
+ document-jobs-not-supported'. However, the Printer MUST accept the
+ first document with a 'true' or 'false' value for the "last-document"
+ operation attribute (see below), so that clients MAY always submit
+ one document jobs with a 'false' value for "last-document" in the
+ first Send-Document and a 'true' for "last-document" in the second
+ Send-Document (with no data).
+
+ Since the Create-Job and the send operations (Send-Document or Send-
+ URI operations) that follow could occur over an arbitrarily long
+ period of time for a particular job, a client MUST send another send
+ operation within an IPP Printer defined minimum time interval after
+ the receipt of the previous request for the job. If a Printer object
+ supports the Create-Job and Send-Document operations, the Printer
+ object MUST support the "multiple-operation-time-out" attribute (see
+
+
+
+Hastings, et al. Standards Track [Page 62]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ section 4.4.31). This attribute indicates the minimum number of
+ seconds the Printer object will wait for the next send operation
+ before taking some recovery action.
+
+ An IPP object MUST recover from an errant client that does not supply
+ a send operation, sometime after the minimum time interval specified
+ by the Printer object's "multiple-operation-time-out" attribute.
+ Such recovery MAY include any of the following or other recovery
+ actions:
+
+ 1. Assume that the Job is an invalid job, start the process of
+ changing the job state to 'aborted', add the 'aborted-by-
+ system' value to the job's "job-state-reasons" attribute (see
+ section 4.3.8), and clean up all resources associated with the
+ Job. In this case, if another send operation is finally
+ received, the Printer responds with an "client-error-not-
+ possible" or "client-error-not-found" depending on whether or
+ not the Job object is still around when the send operation
+ finally arrives.
+ 2. Assume that the last send operation received was in fact the
+ last document (as if the "last-document" flag had been set to
+ 'true'), close the Job object, and proceed to process it (i.e.,
+ move the Job's state to 'pending').
+ 3. Assume that the last send operation received was in fact the
+ last document, close the Job, but move it to the 'pending-held'
+ and add the 'submission-interrupted' value to the job's "job-
+ state-reasons" attribute (see section 4.3.8). This action
+ allows the user or an operator to determine whether to continue
+ processing the Job by moving it back to the 'pending' state
+ using the Release-Job operation (see section 3.3.6) or to
+ cancel the job using the Cancel-Job operation (see section
+ 3.3.3).
+
+ Each implementation is free to decide the "best" action to take
+ depending on local policy, whether any documents have been added,
+ whether the implementation spools jobs or not, and/or any other
+ piece of information available to it. If the choice is to abort the
+ Job object, it is possible that the Job object may already have been
+ processed to the point that some media sheet pages have been printed.
+
+ Access Rights: The authenticated user (see section 8.3) performing
+ this operation must either be the job owner (as determined in the
+ Create-Job operation) or an operator or administrator of the Printer
+ object (see Sections 1 and 8.5). Otherwise, the IPP object MUST
+ reject the operation and return: 'client-error-forbidden', 'client-
+ error-not-authenticated', or 'client-error-not-authorized' as
+ appropriate.
+
+
+
+
+Hastings, et al. Standards Track [Page 63]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+3.3.1.1 Send-Document Request
+
+ The following attribute sets are part of the Send-Document Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1.
+
+ Target:
+ Either (1) the "printer-uri" (uri) plus "job-id"
+ (integer(1:MAX))or (2) the "job-uri" (uri) operation
+ attribute(s) which define the target for this operation as
+ described in section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+ "document-name" (name(MAX)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object MUST support this attribute. It contains the client
+ supplied document name. The document name MAY be different than
+ the Job name. It might be helpful, but NEED NOT be unique
+ across multiple documents in the same Job. Typically, the
+ client software automatically supplies the document name on
+ behalf of the end user by using a file name or an application
+ generated name. See the description of the "document-name"
+ operation attribute in the Print-Job Request (section 3.2.1.1)
+ for more information about this attribute.
+
+ "compression" (type3 keyword):
+ See the description of "compression" for the Print-Job operation
+ in Section 3.2.1.1.
+
+ "document-format" (mimeMediaType):
+ See the description of "document-format" for the Print-Job
+ operation in Section 3.2.1.1.
+
+ "document-natural-language" (naturalLanguage):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute. This attribute
+ specifies the natural language of the document for those
+ document-formats that require a specification of the natural
+ language in order to image the document unambiguously. There
+ are no particular values required for the Printer object to
+ support.
+
+
+
+Hastings, et al. Standards Track [Page 64]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ "last-document" (boolean):
+ The client MUST supply this attribute. The Printer object MUST
+ support this attribute. It is a boolean flag that is set to
+ 'true' if this is the last document for the Job, 'false'
+ otherwise.
+
+ Group 2: Document Content
+
+ The client MUST supply the document data if the "last-document"
+ flag is set to 'false'. However, since a client might not know
+ that the previous document sent with a Send-Document (or Send-URI)
+ operation was the last document (i.e., the "last-document"
+ attribute was set to 'false'), it is legal to send a Send-Document
+ request with no document data where the "last-document" flag is
+ set to 'true'. Such a request MUST NOT increment the value of the
+ Job object's "number-of-documents" attribute, since no real
+ document was added to the job. It is not an error for a client to
+ submit a job with no actual document data, i.e., only a single
+ Create-Job and Send-Document request with a "last-document"
+ operation attribute set to 'true' with no document data.
+
+3.3.1.2 Send-Document Response
+
+ The following sets of attributes are part of the Send-Document
+ Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) and/or a "detailed-status-message" (text(MAX))
+ operation attribute as described in sections 13 and 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ See section 3.1.7 for details on returning Unsupported Attributes.
+
+ Group 3: Job Object Attributes
+
+ This is the same set of attributes as described in the Print-Job
+ response (see section 3.2.1.2).
+
+
+
+
+
+Hastings, et al. Standards Track [Page 65]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+3.3.2 Send-URI Operation
+
+ This OPTIONAL operation is identical to the Send-Document operation
+ (see section 3.3.1) except that a client MUST supply a URI reference
+ ("document-uri" operation attribute) rather than the document data
+ itself. If a Printer object supports this operation, clients can use
+ both Send-URI or Send-Document operations to add new documents to an
+ existing multi-document Job object. However, if a client needs to
+ indicate that the previous Send-URI or Send-Document was the last
+ document, the client MUST use the Send-Document operation with no
+ document data and the "last-document" flag set to 'true' (rather than
+ using a Send-URI operation with no "document-uri" operation
+ attribute).
+
+ If a Printer object supports this operation, it MUST also support the
+ Print-URI operation (see section 3.2.2).
+
+ The Printer object MUST validate the syntax and URI scheme of the
+ supplied URI before returning a response, just as in the Print-URI
+ operation. The IPP Printer MAY validate the accessibility of the
+ document as part of the operation or subsequently (see section
+ 3.2.2).
+
+3.3.3 Cancel-Job Operation
+
+ This REQUIRED operation allows a client to cancel a Print Job from
+ the time the job is created up to the time it is completed, canceled,
+ or aborted. Since a Job might already be printing by the time a
+ Cancel-Job is received, some media sheet pages might be printed
+ before the job is actually terminated.
+
+ The IPP object MUST accept or reject the request based on the job's
+ current state and transition the job to the indicated new state as
+ follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 66]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Current "job- New "job- IPP object's response status
+ state" state" code and action:
+
+ 'pending' 'canceled' 'successful-ok'
+ 'pending-held' 'canceled' 'successful-ok'
+ 'processing' 'canceled' 'successful-ok'
+ 'processing' 'processing' 'successful-ok' See Rule 1
+ 'processing' 'processing' 'client-error-not-possible'
+ See Rule 2
+ 'processing- 'canceled' 'successful-ok'
+ stopped'
+ 'processing- 'processing- 'successful-ok' See Rule 1
+ stopped' stopped'
+ 'processing- 'processing- 'client-error-not-possible'
+ stopped' stopped' See Rule 2
+ 'completed' 'completed' 'client-error-not-possible'
+ 'canceled' 'canceled' 'client-error-not-possible'
+ 'aborted' 'aborted' 'client-error-not-possible'
+
+ Rule 1: If the implementation requires some measurable time to
+ cancel the job in the 'processing' or 'processing-stopped' job
+ states, the IPP object MUST add the 'processing-to-stop-point' value
+ to the job's "job-state-reasons" attribute and then transition the
+ job to the 'canceled' state when the processing ceases (see section
+ 4.3.8).
+
+ Rule 2: If the Job object already has the 'processing-to-stop-point'
+ value in its "job-state-reasons" attribute, then the Printer object
+ MUST reject a Cancel-Job operation.
+
+ Access Rights: The authenticated user (see section 8.3) performing
+ this operation must either be the job owner or an operator or
+ administrator of the Printer object (see Sections 1 and 8.5).
+ Otherwise, the IPP object MUST reject the operation and return:
+ 'client-error-forbidden', 'client-error-not-authenticated', or
+ 'client-error-not-authorized' as appropriate.
+
+3.3.3.1 Cancel-Job Request
+
+ The following groups of attributes are part of the Cancel-Job
+ Request:
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1.
+
+
+
+
+Hastings, et al. Standards Track [Page 67]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Target:
+ Either (1) the "printer-uri" (uri) plus "job-id"
+ (integer(1:MAX))or (2) the "job-uri" (uri) operation
+ attribute(s) which define the target for this operation as
+ described in section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+ "message" (text(127)):
+ The client OPTIONALLY supplies this attribute. The Printer
+ object OPTIONALLY supports this attribute. It is a message to
+ the operator. This "message" attribute is not the same as the
+ "job-message-from-operator" attribute. That attribute is used
+ to report a message from the operator to the end user that
+ queries that attribute. This "message" operation attribute is
+ used to send a message from the client to the operator along
+ with the operation request. It is an implementation decision
+ of how or where to display this message to the operator (if at
+ all).
+
+3.3.3.2 Cancel-Job Response
+
+ The following sets of attributes are part of the Cancel-Job Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) and/or a "detailed-status-message" (text(MAX))
+ operation attribute as described in sections 13 and 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2.
+
+ Group 2: Unsupported Attributes
+
+ See section 3.1.7 for details on returning Unsupported Attributes.
+
+ Once a successful response has been sent, the implementation
+ guarantees that the Job will eventually end up in the 'canceled'
+ state. Between the time of the Cancel-Job operation is accepted and
+ when the job enters the 'canceled' job-state (see section 4.3.7), the
+ "job-state-reasons" attribute SHOULD contain the 'processing-to-
+ stop-point'
+
+
+
+Hastings, et al. Standards Track [Page 68]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ value which indicates to later queries that although the Job might
+ still be 'processing', it will eventually end up in the
+ 'canceled' state, not the 'completed' state.
+
+3.3.4 Get-Job-Attributes Operation
+
+ This REQUIRED operation allows a client to request the values of
+ attributes of a Job object and it is almost identical to the Get-
+ Printer-Attributes operation (see section 3.2.5). The only
+ differences are that the operation is directed at a Job object rather
+ than a Printer object, there is no "document-format" operation
+ attribute used when querying a Job object, and the returned attribute
+ group is a set of Job object attributes rather than a set of Printer
+ object attributes.
+
+ For Jobs, the possible names of attribute groups are:
+
+ - 'job-template': the subset of the Job Template attributes that
+ apply to a Job object (the first column of the table in Section
+ 4.2) that the implementation supports for Job objects.
+ - 'job-description': the subset of the Job Description attributes
+ specified in Section 4.3 that the implementation supports for
+ Job objects.
+ - 'all': the special group 'all' that includes all attributes that
+ the implementation supports for Job objects.
+
+ Since a client MAY request specific attributes or named groups, there
+ is a potential that there is some overlap. For example, if a client
+ requests, 'job-name' and 'job-description', the client is actually
+ requesting the "job-name" attribute once by naming it explicitly, and
+ once by inclusion in the 'job-description' group. In such cases, the
+ Printer object NEED NOT return the attribute only once in the
+ response even if it is requested multiple times. The client SHOULD
+ NOT request the same attribute in multiple ways.
+
+ It is NOT REQUIRED that a Job object support all attributes belonging
+ to a group (since some attributes are OPTIONAL). However it is
+ REQUIRED that each Job object support all these group names.
+
+3.3.4.1 Get-Job-Attributes Request
+
+ The following groups of attributes are part of the Get-Job-Attributes
+ Request when the request is directed at a Job object:
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 69]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Group 1: Operation Attributes
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.1.
+
+ Target:
+ Either (1) the "printer-uri" (uri) plus "job-id"
+ (integer(1:MAX)) or (2) the "job-uri" (uri) operation
+ attribute(s) which define the target for this operation as
+ described in section 3.1.5.
+
+ Requesting User Name:
+ The "requesting-user-name" (name(MAX)) attribute SHOULD be
+ supplied by the client as described in section 8.3.
+
+ "requested-attributes" (1setOf keyword):
+ The client OPTIONALLY supplies this attribute. The IPP object
+ MUST support this attribute. It is a set of attribute names
+ and/or attribute group names in whose values the requester is
+ interested. If the client omits this attribute, the IPP object
+ MUST respond as if this attribute had been supplied with a value
+ of 'all'.
+
+3.3.4.2 Get-Job-Attributes Response
+
+ The Printer object returns the following sets of attributes as part
+ of the Get-Job-Attributes Response:
+
+ Group 1: Operation Attributes
+
+ Status Message:
+ In addition to the REQUIRED status code returned in every
+ response, the response OPTIONALLY includes a "status-message"
+ (text(255)) and/or a "detailed-status-message" (text(MAX))
+ operation attribute as described in sections 13 and 3.1.6.
+
+ Natural Language and Character Set:
+ The "attributes-charset" and "attributes-natural-language"
+ attributes as described in section 3.1.4.2. The "attributes-
+ natural-language" MAY be the natural language of the Job
+ object, rather than the one requested.
+
+ Group 2: Unsupported Attributes
+
+ See section 3.1.7 for details on returning Unsupported Attributes.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 70]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The response NEED NOT contain the "requested-attributes" operation
+ attribute with any supplied values (attribute keywords) that were
+ requested by the client but are not supported by the IPP object.
+ If the Printer object does return unsupported attributes
+ referenced in the "requested-attributes" operation attribute and
+ that attribute included group names, such as 'all', the
+ unsupported attributes MUST NOT include attributes described in
+ the standard but not supported by the implementation.
+
+ Group 3: Job Object Attributes
+
+ This is the set of requested attributes and their current values.
+ The IPP object ignores (does not respond with) any requested
+ attribute or value which is not supported or which is restricted
+ by the security policy in force, including whether the requesting
+ user is the user that submitted the job (job originating user) or
+ not (see section 8). However, the IPP object MUST respond with
+ the 'unknown' value for any supported attribute (including all
+ REQUIRED attributes) for which the IPP object does not know the
+ value, unless it would violate the security policy. See the
+ description of the "out-of-band" values in the beginning of
+ Section 4.1.
+
+3.3.5 Hold-Job Operation
+
+ This OPTIONAL operation allows a client to hold a pending job in the
+ queue so that it is not eligible for scheduling. If the Hold-Job
+ operation is supported, then the Release-Job operation MUST be
+ supported, and vice-versa. The OPTIONAL "job-hold-until" operation
+ attribute allows a client to specify whether to hold the job
+ indefinitely or until a specified time period, if supported.
+
+ The IPP object MUST accept or reject the request based on the job's
+ current state and transition the job to the indicated new state as
+ follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 71]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Current "job- New "job-state" IPP object's response status
+ state" code and action:
+
+ 'pending' 'pending-held' 'successful-ok' See Rule 1
+ 'pending' 'pending' 'successful-ok' See Rule 2
+ 'pending-held' 'pending-held' 'successful-ok' See Rule 1
+ 'pending-held' 'pending' 'successful-ok' See Rule 2
+ 'processing' 'processing' 'client-error-not-possible'
+ 'processing- 'processing- 'client-error-not-possible'
+ stopped' stopped'
+ 'completed' 'completed' 'client-error-not-possible'
+ 'canceled' 'canceled' 'client-error-not-possible'
+ 'aborted' 'aborted' 'client-error-not-possible'
+
+ Rule 1: If the implementation supports multiple reasons for a job to
+ be in the 'pending-held' state, the IPP object MUST add the 'job-
+ hold-until-specified' value to the job's "job-state-reasons"
+ attribute.
+
+ Rule 2: If the IPP object supports the "job-hold-until" operation
+ attribute, but the specified time period has already started (or is
+ the 'no-hold' value) and there are no other reasons to hold the job,
+ the IPP object MUST make the job be a candidate for processing
+ immediately (see Section 4.2.2) by putting the job in the 'pending'
+ state.
+
+ Note: In order to keep the Hold-Job operation simple, such a request
+ is rejected when the job is in the 'processing' or 'processing-
+ stopped' states. If an operation is needed to hold jobs while in
+ these states, it will be added as an additional operation, rather
+ than overloading the Hold-Job operation. Then it is clear to clients
+ by querying the Printer object's "operations-supported" (see Section
+ 4.4.15) and the Job object's "job-state" (see Section 4.3.7)
+ attributes which operations are possible.
+
+ Access Rights: The authenticated user (see section 8.3) performing
+ this operation must either be the job owner or an operator or
+ administrator of the Printer object (see Sections 1 and 8.5).
+ Otherwise, the IPP object MUST reject the operation and return:
+ 'client-error-forbidden', 'client-error-not-authenticated', or
+ 'client-error-not-authorized' as appropriate.
+
+3.3.5.1 Hold-Job Request
+
+ The groups and operation attributes are the same as for a Cancel-Job
+ request (see section 3.3.3.1), with the addition of the following
+ Group 1 Operation attribute:
+
+
+
+
+Hastings, et al. Standards Track [Page 72]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ "job-hold-until" (type3 keyword | name(MAX)):
+ The client OPTIONALLY supplies this Operation attribute. The
+ IPP object MUST support this operation attribute in a Hold-Job
+ request, if it supports the "job-hold-until" Job template
+ attribute in create operations. See section 4.2.2. The IPP
+ object SHOULD support the "job-hold-until" Job Template
+ attribute for use in job create operations with at least the
+ 'indefinite' value, if it supports the Hold-Job operation.
+ Otherwise, a client cannot create a job and hold it immediately
+ (without picking some supported time period in the future).
+
+ If supplied and supported as specified in the Printer's "job-
+ hold-until-supported" attribute, the IPP object copies the
+ supplied operation attribute to the Job object, replacing the
+ job's previous "job-hold-until" attribute, if present, and
+ makes the job a candidate for scheduling during the supplied
+ named time period.
+
+ If supplied, but either the "job-hold-until" Operation
+ attribute itself or the value supplied is not supported, the
+ IPP object accepts the request, returns the unsupported
+ attribute or value in the Unsupported Attributes Group
+ according to section 3.1.7, returns the 'successful-ok-
+ ignored-or-substituted-attributes, and holds the job
+ indefinitely until a client performs a subsequent Release-Job
+ operation.
+
+ If the client (1) supplies a value that specifies a time period
+ that has already started or the 'no-hold' value (meaning don't
+ hold the job) and (2) the IPP object supports the "job-hold-
+ until" operation attribute and there are no other reasons to
+ hold the job, the IPP object MUST accept the operation and make
+ the job be a candidate for processing immediately (see Section
+ 4.2.2).
+
+ If the client does not supply a "job-hold-until" Operation
+ attribute in the request, the IPP object MUST populate the job
+ object with a "job-hold-until" attribute with the 'indefinite'
+ value (if IPP object supports the "job-hold-until" attribute)
+ and hold the job indefinitely, until a client performs a
+ Release-Job operation.
+
+3.3.5.2 Hold-Job Response
+
+ The groups and attributes are the same as for a Cancel-Job response
+ (see section 3.3.3.2).
+
+
+
+
+
+Hastings, et al. Standards Track [Page 73]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+3.3.6 Release-Job Operation
+
+ This OPTIONAL operation allows a client to release a previously held
+ job so that it is again eligible for scheduling. If the Hold-Job
+ operation is supported, then the Release-Job operation MUST be
+ supported, and vice-versa.
+
+ This operation removes the "job-hold-until" job attribute, if
+ present, from the job object that had been supplied in the create or
+ most recent Hold-Job or Restart-Job operation and removes its effect
+ on the job. The IPP object MUST remove the 'job-hold-until-
+ specified' value from the job's "job-state-reasons" attribute, if
+ present. See section 4.3.8.
+
+ The IPP object MUST accept or reject the request based on the job's
+ current state and transition the job to the indicated new state as
+ follows:
+
+ Current "job- New "job-state" IPP object's response status
+ state" code and action:
+
+ 'pending' 'pending' 'successful-ok'
+ No effect on the job.
+ 'pending-held' 'pending-held' 'successful-ok' See Rule 1
+ 'pending-held' 'pending' 'successful-ok'
+ 'processing' 'processing' 'successful-ok'
+ No effect on the job.
+ 'processing- 'processing- 'successful-ok'
+ stopped' stopped' No effect on the job.
+ 'completed' 'completed' 'client-error-not-possible'
+ 'canceled' 'canceled' 'client-error-not-possible'
+ 'aborted' 'aborted' 'client-error-not-possible'
+
+ Rule 1: If there are other reasons to keep the job in the 'pending-
+ held' state, such as 'resources-are-not-ready', the job remains in
+ the 'pending-held' state. Thus the 'pending-held' state is not just
+ for jobs that have the 'job-hold-until' applied to them, but are for
+ any reason to keep the job from being a candidate for scheduling and
+ processing, such as 'resources-are-not-ready'. See the "job-hold-
+ until" attribute (section 4.2.2).
+
+ Access Rights: The authenticated user (see section 8.3) performing
+ this operation must either be the job owner or an operator or
+ administrator of the Printer object (see Sections 1 and 8.5).
+ Otherwise, the IPP object MUST reject the operation and return:
+ 'client-error-forbidden', 'client-error-not-authenticated', or
+ 'client-error-not-authorized' as appropriate.
+
+
+
+
+Hastings, et al. Standards Track [Page 74]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The Release-Job Request and Release-Job Response have the same
+ attribute groups and attributes as the Cancel-Job operation (see
+ section 3.3.3.1 and 3.3.3.2).
+
+3.3.7 Restart-Job Operation
+
+ This OPTIONAL operation allows a client to restart a job that is
+ retained in the queue after processing has completed (see section
+ 4.3.7.2).
+
+ The job is moved to the 'pending' or 'pending-held' job state and
+ restarts at the beginning on the same IPP Printer object with the
+ same attribute values. If any of the documents in the job were
+ passed by reference (Print-URI or Send-URI), the Printer MUST re-
+ fetch the data, since the semantics of Restart-Job are to repeat all
+ Job processing. The Job Description attributes that accumulate job
+ progress, such as "job-impressions-completed", "job-media-sheets-
+ completed", and "job-k-octets-processed", MUST be reset to 0 so that
+ they give an accurate record of the job from its restart point. The
+ job object MUST continue to use the same "job-uri" and "job-id"
+ attribute values.
+
+ Note: If in the future an operation is needed that does not reset
+ the job progress attributes, then a new operation will be defined
+ which makes a copy of the job, assigns a new "job-uri" and "job-id"
+ to the copy and resets the job progress attributes in the new copy
+ only.
+
+ The IPP object MUST accept or reject the request based on the job's
+ current state, transition the job to the indicated new state as
+ follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 75]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Current "job- New "job-state" IPP object's response status
+ state" code and action:
+
+ 'pending' 'pending' 'client-error-not-possible'
+ 'pending-held' 'pending-held' 'client-error-not-possible'
+ 'processing' 'processing' 'client-error-not-possible'
+ 'processing- 'processing- 'client-error-not-possible'
+ stopped' stopped'
+ 'completed' 'pending' or 'successful-ok' - job is started
+ 'pending-held' over.
+ 'completed' 'completed' 'client-error-not-possible' -
+ see Rule 1
+ 'canceled' 'pending' or 'successful-ok' - job is started
+ 'pending-held' over.
+ 'canceled' 'canceled' 'client-error-not-possible' -
+ see Rule 1
+ 'aborted' 'pending' or 'successful-ok' - job is started
+ 'pending-held' over.
+ 'aborted' 'aborted' 'client-error-not-possible' -
+ see Rule 1
+
+ Rule 1: If the Job Retention Period has expired for the job in this
+ state, then the IPP object rejects the operation. See section
+ 4.3.7.2.
+
+ Note: In order to prevent a user from inadvertently restarting a job
+ in the middle, the Restart-Job request is rejected when the job is in
+ the 'processing' or 'processing-stopped' states. If in the future an
+ operation is needed to hold or restart jobs while in these states, it
+ will be added as an additional operation, rather than overloading the
+ Restart-Job operation, so that it is clear that the user intended
+ that the current job not be completed.
+
+ Access Rights: The authenticated user (see section 8.3) performing
+ this operation must either be the job owner or an operator or
+ administrator of the Printer object (see Sections 1 and 8.5).
+ Otherwise, the IPP object MUST reject the operation and return:
+ 'client-error-forbidden', 'client-error-not-authenticated', or
+ 'client-error-not-authorized' as appropriate.
+
+3.3.7.1 Restart-Job Request
+
+ The groups and attributes are the same as for a Cancel-Job request
+ (see section 3.3.3.1), with the addition of the following Group 1
+ Operation attribute:
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 76]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ "job-hold-until" (type3 keyword | name(MAX)):
+ The client OPTIONALLY supplies this attribute. The IPP object
+ MUST support this Operation attribute in a Restart-Job request,
+ if it supports the "job-hold-until" Job Template attribute in
+ create operations. See section 4.2.2. Otherwise, the IPP
+ object NEED NOT support the "job-hold-until" Operation
+ attribute in a Restart-Job request.
+
+ If supplied and supported as specified in the Printer's "job-
+ hold-until-supported" attribute, the IPP object copies the
+ supplied Operation attribute to the Job object, replacing the
+ job's previous "job-hold-until" attribute, if present, and
+ makes the job a candidate for scheduling during the supplied
+ named time period. See section 4.2.2.
+
+ If supplied, but the value is not supported, the IPP object
+ accepts the request, returns the unsupported attribute or value
+ in the Unsupported Attributes Group according to section 3.1.7,
+ returns the 'successful-ok-ignored-or-substituted-attributes'
+ status code, and holds the job indefinitely until a client
+ performs a subsequent Release-Job operation.
+
+ If supplied, but the "job-hold-until" Operation attribute
+ itself is not supported, the IPP object accepts the request,
+ returns the unsupported attribute with the out-of-band
+ 'unsupported' value in the Unsupported Attributes Group
+ according to section 3.1.7, returns the 'successful-ok-
+ ignored-or-substituted-attributes' status code, and restarts
+ the job, i.e., ignores the "job-hold-until" attribute.
+
+ If the client (1) supplies a value that specifies a time period
+ that has already started or the 'no-hold' value (meaning don't
+ hold the job) and (2) the IPP object supports the "job-hold-
+ until" operation attribute and there are no other reasons to
+ hold the job, the IPP object makes the job a candidate for
+ processing immediately (see Section 4.2.2).
+
+ If the client does not supply a "job-hold-until" operation
+ attribute in the request, the IPP object removes the "job-
+ hold-until" attribute, if present, from the job. If there are
+ no other reasons to hold the job, the Restart-Job operation
+ makes the job a candidate for processing immediately (see
+ Section 4.2.2).
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 77]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+3.3.7.2 Restart-Job Response
+
+ The groups and attributes are the same as for a Cancel-Job response
+ (see section 3.3.3.2).
+
+ Note: In the future an OPTIONAL Modify-Job or Set-Job-Attributes
+ operation may be specified that allows the client to modify other
+ attributes before releasing the restarted job.
+
+4. Object Attributes
+
+ This section describes the attributes with their corresponding
+ attribute syntaxes and values that are part of the IPP model. The
+ sections below show the objects and their associated attributes which
+ are included within the scope of this protocol. Many of these
+ attributes are derived from other relevant documents:
+
+ - Document Printing Application (DPA) [ISO10175]
+ - RFC 1759 Printer MIB [RFC1759]
+
+ Each attribute is uniquely identified in this document using a
+ "keyword" (see section 12.2.1) which is the name of the attribute.
+ The keyword is included in the section header describing that
+ attribute.
+
+ Note: Not only are keywords used to identify attributes, but one of
+ the attribute syntaxes described below is "keyword" so that some
+ attributes have keyword values. Therefore, these attributes are
+ defined as having an attribute syntax that is a set of keywords.
+
+4.1 Attribute Syntaxes
+
+ This section defines the basic attribute syntax types that all
+ clients and IPP objects MUST be able to accept in responses and
+ accept in requests, respectively. Each attribute description in
+ sections 3 and 4 includes the name of attribute syntax(es) in the
+ heading (in parentheses). A conforming implementation of an
+ attribute MUST include the semantics of the attribute syntax(es) so
+ identified. Section 6.3 describes how the protocol can be extended
+ with new attribute syntaxes.
+
+ The attribute syntaxes are specified in the following sub-sections,
+ where the sub-section heading is the keyword name of the attribute
+ syntax inside the single quotes. In operation requests and responses
+ each attribute value MUST be represented as one of the attribute
+ syntaxes specified in the sub-section heading for the attribute. In
+ addition, the value of an attribute in a response (but not in a
+
+
+
+
+Hastings, et al. Standards Track [Page 78]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ request) MAY be one of the "out-of-band" values whose special
+ encoding rules are defined in the "Encoding and Transport" document
+ [RFC2910]. Standard "out-of-band" values are:
+
+ 'unknown': The attribute is supported by the IPP object, but the
+ value is unknown to the IPP object for some reason.
+ 'unsupported': The attribute is unsupported by the IPP object.
+ This value MUST be returned only as the value of an attribute
+ in the Unsupported Attributes Group.
+ 'no-value': The attribute is supported by the Printer object, but
+ the administrator has not yet configured a value.
+
+ All attributes in a request MUST have one or more values as defined
+ in Sections 4.2 to 4.4. Thus clients MUST NOT supply attributes with
+ "out-of-band" values for operations defined in this document. All
+ attributes in a response MUST have one or more values as defined in
+ Sections 4.2 to 4.4 or a single "out-of-band" value.
+
+ Most attributes are defined to have a single attribute syntax.
+ However, a few attributes (e.g., "job-sheet", "media", "job-hold-
+ until") are defined to have several attribute syntaxes, depending on
+ the value. These multiple attribute syntaxes are separated by the
+ "|" character in the sub-section heading to indicate the choice.
+ Since each value MUST be tagged as to its attribute syntax in the
+ protocol, a single-valued attribute instance may have any one of its
+ attribute syntaxes and a multi-valued attribute instance may have a
+ mixture of its defined attribute syntaxes.
+
+4.1.1 'text'
+
+ A text attribute is an attribute whose value is a sequence of zero or
+ more characters encoded in a maximum of 1023 ('MAX') octets. MAX is
+ the maximum length for each value of any text attribute. However, if
+ an attribute will always contain values whose maximum length is much
+ less than MAX, the definition of that attribute will include a
+ qualifier that defines the maximum length for values of that
+ attribute. For example: the "printer-location" attribute is
+ specified as "printer-location (text(127))". In this case, text
+ values for "printer-location" MUST NOT exceed 127 octets; if supplied
+ with a longer text string via some external interface (other than the
+ protocol), implementations are free to truncate to this shorter
+ length limitation.
+
+ In this document, all text attributes are defined using the 'text'
+ syntax. However, 'text' is used only for brevity; the formal
+ interpretation of 'text' is: 'textWithoutLanguage |
+ textWithLanguage'. That is, for any attribute defined in this
+ document using the 'text' attribute syntax, all IPP objects and
+
+
+
+Hastings, et al. Standards Track [Page 79]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ clients MUST support both the 'textWithoutLanguage' and
+ 'textWithLanguage' attribute syntaxes. However, in actual usage and
+ protocol execution, objects and clients accept and return only one of
+ the two syntax per attribute. The syntax 'text' never appears "on-
+ the-wire".
+
+ Both 'textWithoutLanguage' and 'textWithLanguage' are needed to
+ support the real world needs of interoperability between sites and
+ systems that use different natural languages as the basis for human
+ communication. Generally, one natural language applies to all text
+ attributes in a given request or response. The language is indicated
+ by the "attributes-natural-language" operation attribute defined in
+ section 3.1.4 or "attributes-natural-language" job attribute defined
+ in section 4.3.20, and there is no need to identify the natural
+ language for each text string on a value-by-value basis. In these
+ cases, the attribute syntax 'textWithoutLanguage' is used for text
+ attributes. In other cases, the client needs to supply or the
+ Printer object needs to return a text value in a natural language
+ that is different from the rest of the text values in the request or
+ response. In these cases, the client or Printer object uses the
+ attribute syntax 'textWithLanguage' for text attributes (this is the
+ Natural Language Override mechanism described in section 3.1.4).
+
+ The 'textWithoutLanguage' and 'textWithLanguage' attribute syntaxes
+ are described in more detail in the following sections.
+
+4.1.1.1 'textWithoutLanguage'
+
+ The 'textWithoutLanguage' syntax indicates a value that is sequence
+ of zero or more characters encoded in a maximum of 1023 (MAX) octets.
+ Text strings are encoded using the rules of some charset. The
+ Printer object MUST support the UTF-8 charset [RFC2279] and MAY
+ support additional charsets to represent 'text' values, provided that
+ the charsets are registered with IANA [IANA-CS]. See Section 4.1.7
+ for the definition of the 'charset' attribute syntax, including
+ restricted semantics and examples of charsets.
+
+4.1.1.2 'textWithLanguage'
+
+ The 'textWithLanguage' attribute syntax is a compound attribute
+ syntax consisting of two parts: a 'textWithoutLanguage' part encoded
+ in a maximum of 1023 (MAX) octets plus an additional
+ 'naturalLanguage' (see section 4.1.8) part that overrides the natural
+ language in force. The 'naturalLanguage' part explicitly identifies
+ the natural language that applies to the text part of that value and
+ that value alone. For any give text attribute, the
+ 'textWithoutLanguage' part is limited to the maximum length defined
+ for that 'text' attribute, and the 'naturalLanguage' part is always
+
+
+
+Hastings, et al. Standards Track [Page 80]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ limited to 63 (additional) octets. Using the 'textWithLanguage'
+ attribute syntax rather than the normal 'textWithoutLanguage' syntax
+ is the so-called Natural Language Override mechanism and MUST be
+ supported by all IPP objects and clients.
+
+ If the attribute is multi-valued (1setOf text), then the
+ 'textWithLanguage' attribute syntax MUST be used to explicitly
+ specify each attribute value whose natural language needs to be
+ overridden. Other values in a multi-valued 'text' attribute in a
+ request or a response revert to the natural language of the operation
+ attribute.
+
+ In a create request, the Printer object MUST accept and store with
+ the Job object any natural language in the "attributes-natural-
+ language" operation attribute, whether the Printer object supports
+ that natural language or not. Furthermore, the Printer object MUST
+ accept and store any 'textWithLanguage' attribute value, whether the
+ Printer object supports that natural language or not. These
+ requirements are independent of the value of the "ipp-attribute-
+ fidelity" operation attribute that the client MAY supply.
+
+ Example: If the client supplies the "attributes-natural-language"
+ operation attribute with the value: 'en' indicating English, but the
+ value of the "job-name" attribute is in French, the client MUST use
+ the 'textWithLanguage' attribute syntax with the following two
+ values:
+
+ 'fr': Natural Language Override indicating French
+ 'Rapport Mensuel': the job name in French
+
+ See the "Encoding and Transport" document [RFC2910] section 3.9 for
+ the encoding of the two parts and Appendix A for a detailed example
+ of the 'textWithLanguage' attribute syntax.
+
+4.1.2 'name'
+
+ This syntax type is used for user-friendly strings, such as a Printer
+ name, that, for humans, are more meaningful than identifiers. Names
+ are never translated from one natural language to another. The
+ 'name' attribute syntax is essentially the same as 'text', including
+ the REQUIRED support of UTF-8 except that the sequence of characters
+ is limited so that its encoded form MUST NOT exceed 255 (MAX) octets.
+
+ Also like 'text', 'name' is really an abbreviated notation for either
+ 'nameWithoutLanguage' or 'nameWithLanguage'. That is, all IPP
+ objects and clients MUST support both the 'nameWithoutLanguage' and
+ 'nameWithLanguage' attribute syntaxes. However, in actual usage and
+
+
+
+
+Hastings, et al. Standards Track [Page 81]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ protocol execution, objects and clients accept and return only one of
+ the two syntax per attribute. The syntax 'name' never appears "on-
+ the-wire".
+
+ Only the 'text' and 'name' attribute syntaxes permit the Natural
+ Language Override mechanism.
+
+ Some attributes are defined as 'type3 keyword | name'. These
+ attributes support values that are either type3 keywords or names.
+ This dual-syntax mechanism enables a site administrator to extend
+ these attributes to legally include values that are locally defined
+ by the site administrator. Such names are not registered with IANA.
+
+4.1.2.1 'nameWithoutLanguage'
+
+ The 'nameWithoutLanguage' syntax indicates a value that is sequence
+ of zero or more characters encoded in a maximum of 255 (MAX) octets.
+
+4.1.2.2 'nameWithLanguage'
+
+ The 'nameWithLanguage' attribute syntax is a compound attribute
+ syntax consisting of two parts: a 'nameWithoutLanguage' part encoded
+ in a maximum of 1023 (MAX) octets plus an additional
+ 'naturalLanguage' (see section 4.1.8) part that overrides the natural
+ language in force. The 'naturalLanguage' part explicitly identifies
+ the natural language that applies to that name value and that name
+ value alone. For any give text attribute, the 'textWithoutLanguage'
+ part is limited to the maximum length defined for that 'text'
+ attribute, and the 'naturalLanguage' part is always limited to 63
+ (additional) octets. Using the 'textWithLanguage' attribute syntax
+ rather than the normal 'textWithoutLanguage' syntax is the so-called
+ Natural Language Override mechanism and MUST be supported by all IPP
+ objects and clients.
+
+ The 'nameWithLanguage' attribute syntax behaves the same as the
+ 'textWithLanguage' syntax. Using the 'textWithLanguage' attribute
+ syntax rather than the normal 'textWithoutLanguage' syntax is the
+ so-called Natural Language Override mechanism and MUST be supported
+ by all IPP objects and clients. If a name is in a language that is
+ different than the rest of the object or operation, then this
+ 'nameWithLanguage' syntax is used rather than the generic
+ 'nameWithoutLanguage' syntax.
+
+ If the attribute is multi-valued (1setOf text), then the
+ 'nameWithLanguage' attribute syntax MUST be used to explicitly
+ specify each attribute value whose natural language needs to be
+ overridden.
+
+
+
+
+Hastings, et al. Standards Track [Page 82]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Other values in a multi-valued 'name' attribute in a request or a
+ response revert to the natural language of the operation attribute.
+
+ In a create request, the Printer object MUST accept and store with
+ the Job object any natural language in the "attributes-natural-
+ language" operation attribute, whether the Printer object supports
+ that natural language or not. Furthermore, the Printer object MUST
+ accept and store any 'nameWithLanguage' attribute value, whether the
+ Printer object supports that natural language or not. These
+ requirements are independent of the value of the "ipp-attribute-
+ fidelity" operation attribute that the client MAY supply.
+
+ Example: If the client supplies the "attributes-natural-language"
+ operation attribute with the value: 'en' indicating English, but the
+ "printer-name" attribute is in German, the client MUST use the
+ 'nameWithLanguage' attribute syntax as follows:
+
+ 'de': Natural Language Override indicating German
+ 'Farbdrucker': the Printer name in German
+
+ See the "Encoding and Transport" document [RFC2910] section 3.9 for
+ the encoding of the two parts and Appendix A for a detailed example
+ of the 'nameWithLanguage' attribute syntax.
+
+4.1.2.3 Matching 'name' attribute values
+
+ For purposes of matching two 'name' attribute values for equality,
+ such as in job validation (where a client-supplied value for
+ attribute "xxx" is checked to see if the value is among the values of
+ the Printer object's corresponding "xxx-supported" attribute), the
+ following match rules apply:
+
+ 1. 'keyword' values never match 'name' values.
+
+ 2. 'name' (nameWithoutLanguage and nameWithLanguage) values match
+ if (1) the name parts match and (2) the Associated Natural-
+ Language parts (see section 3.1.4.1) match. The matching rules
+ are:
+
+ a. the name parts match if the two names are identical
+ character by character, except it is RECOMMENDED that case
+ be ignored. For example: 'Ajax-letter-head-white' MUST
+ match 'Ajax-letter-head-white' and SHOULD match 'ajax-
+ letter-head-white' and 'AJAX-LETTER-HEAD-WHITE'.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 83]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ b. the Associated Natural-Language parts match if the shorter
+ of the two meets the syntactic requirements of RFC 1766
+ [RFC1766] and matches byte for byte with the longer. For
+ example, 'en' matches 'en', 'en-us' and 'en-gb', but matches
+ neither 'fr' nor 'e'.
+
+4.1.3 'keyword'
+
+ The 'keyword' attribute syntax is a sequence of characters, length: 1
+ to 255, containing only the US-ASCII [ASCII] encoded values for
+ lowercase letters ("a" - "z"), digits ("0" - "9"), hyphen ("-"), dot
+ ("."), and underscore ("_"). The first character MUST be a lowercase
+ letter. Furthermore, keywords MUST be in U.S. English.
+
+ This syntax type is used for enumerating semantic identifiers of
+ entities in the abstract protocol, i.e., entities identified in this
+ document. Keywords are used as attribute names or values of
+ attributes. Unlike 'text' and 'name' attribute values, 'keyword'
+ values MUST NOT use the Natural Language Override mechanism, since
+ they MUST always be US-ASCII and U.S. English.
+
+ Keywords are for use in the protocol. A user interface will likely
+ provide a mapping between protocol keywords and displayable user-
+ friendly words and phrases which are localized to the natural
+ language of the user. While the keywords specified in this document
+ MAY be displayed to users whose natural language is U.S. English,
+ they MAY be mapped to other U.S. English words for U.S. English
+ users, since the user interface is outside the scope of this
+ document.
+
+ In the definition for each attribute of this syntax type, the full
+ set of defined keyword values for that attribute are listed.
+
+ When a keyword is used to represent an attribute (its name), it MUST
+ be unique within the full scope of all IPP objects and attributes.
+ When a keyword is used to represent a value of an attribute, it MUST
+ be unique just within the scope of that attribute. That is, the same
+ keyword MUST NOT be used for two different values within the same
+ attribute to mean two different semantic ideas. However, the same
+ keyword MAY be used across two or more attributes, representing
+ different semantic ideas for each attribute. Section 6.1 describes
+ how the protocol can be extended with new keyword values. Examples
+ of attribute name keywords:
+
+ "job-name"
+ "attributes-charset"
+
+
+
+
+
+Hastings, et al. Standards Track [Page 84]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Note: This document uses "type1", "type2", and "type3" prefixes to
+ the "keyword" basic syntax to indicate different levels of review for
+ extensions (see section 6.1).
+
+4.1.4 'enum'
+
+ The 'enum' attribute syntax is an enumerated integer value that is in
+ the range from 1 to 2**31 - 1 (MAX). Each value has an associated
+ 'keyword' name. In the definition for each attribute of this syntax
+ type, the full set of possible values for that attribute are listed.
+ This syntax type is used for attributes for which there are enum
+ values assigned by other standards, such as SNMP MIBs. A number of
+ attribute enum values in this document are also used for
+ corresponding attributes in other standards [RFC1759]. This syntax
+ type is not used for attributes to which the administrator may assign
+ values. Section 6.1 describes how the protocol can be extended with
+ new enum values.
+
+ Enum values are for use in the protocol. A user interface will
+ provide a mapping between protocol enum values and displayable user-
+ friendly words and phrases which are localized to the natural
+ language of the user. While the enum symbols specified in this
+ document MAY be displayed to users whose natural language is U.S.
+ English, they MAY be mapped to other U.S. English words for U.S.
+ English users, since the user interface is outside the scope of this
+ document.
+
+ Note: SNMP MIBs use '2' for 'unknown' which corresponds to the IPP
+ "out-of-band" value 'unknown'. See the description of the "out-of-
+ band" values at the beginning of Section 4.1. Therefore, attributes
+ of type 'enum' start at '3'.
+
+ Note: This document uses "type1", "type2", and "type3" prefixes to
+ the "enum" basic syntax to indicate different levels of review for
+ extensions (see section 6.1).
+
+4.1.5 'uri'
+
+ The 'uri' attribute syntax is any valid Uniform Resource Identifier
+ or URI [RFC2396]. Most often, URIs are simply Uniform Resource
+ Locators or URLs. The maximum length of URIs used as values of IPP
+ attributes is 1023 octets. Although most other IPP attribute syntax
+ types allow for only lower-cased values, this attribute syntax type
+ conforms to the case-sensitive and case-insensitive rules specified
+ in [RFC2396]. See also [IPP-IIG] for a discussion of case in URIs.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 85]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.1.6 'uriScheme'
+
+ The 'uriScheme' attribute syntax is a sequence of characters
+ representing a URI scheme according to RFC 2396 [RFC2396]. Though
+ RFC 2396 requires that the values be case-insensitive, IPP requires
+ all lower case values in IPP attributes to simplify comparing by IPP
+ clients and Printer objects.
+
+ Standard values for this syntax type are the following keywords:
+
+ 'ipp': for IPP schemed URIs (e.g., "ipp:...")
+ 'http': for HTTP schemed URIs (e.g., "http:...")
+ 'https': for use with HTTPS schemed URIs (e.g., "https:...") (not
+ on IETF standards track)
+ 'ftp': for FTP schemed URIs (e.g., "ftp:...")
+ 'mailto': for SMTP schemed URIs (e.g., "mailto:...")
+ 'file': for file schemed URIs (e.g., "file:...")
+
+ A Printer object MAY support any URI 'scheme' that has been
+ registered with IANA [IANA-MT]. The maximum length of URI 'scheme'
+ values used to represent IPP attribute values is 63 octets.
+
+4.1.7 'charset'
+
+ The 'charset' attribute syntax is a standard identifier for a
+ charset. A charset is a coded character set and encoding scheme.
+ Charsets are used for labeling certain document contents and 'text'
+ and 'name' attribute values. The syntax and semantics of this
+ attribute syntax are specified in RFC 2046 [RFC2046] and contained in
+ the IANA character-set Registry [IANA-CS] according to the IANA
+ procedures [RFC2278]. Though RFC 2046 requires that the values be
+ case-insensitive US-ASCII [ASCII], IPP requires all lower case values
+ in IPP attributes to simplify comparing by IPP clients and Printer
+ objects. When a character-set in the IANA registry has more than one
+ name (alias), the name labeled as "(preferred MIME name)", if
+ present, MUST be used.
+
+ The maximum length of 'charset' values used to represent IPP
+ attribute values is 63 octets.
+
+ Some examples are:
+
+ 'utf-8': ISO 10646 Universal Multiple-Octet Coded Character Set
+ (UCS) represented as the UTF-8 [RFC2279] transfer encoding
+ scheme in which US-ASCII is a subset charset.
+ 'us-ascii': 7-bit American Standard Code for Information
+ Interchange (ASCII), ANSI X3.4-1986 [ASCII]. That standard
+
+
+
+
+Hastings, et al. Standards Track [Page 86]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ defines US-ASCII, but RFC 2045 [RFC2045] eliminates most of the
+ control characters from conformant usage in MIME and IPP.
+ 'iso-8859-1': 8-bit One-Byte Coded Character Set, Latin Alphabet
+ Nr 1 [ISO8859-1]. That standard defines a coded character set
+ that is used by Latin languages in the Western Hemisphere and
+ Western Europe. US-ASCII is a subset charset.
+
+ Some attribute descriptions MAY place additional requirements on
+ charset values that may be used, such as REQUIRED values that MUST be
+ supported or additional restrictions, such as requiring that the
+ charset have US- ASCII as a subset charset.
+
+4.1.8 'naturalLanguage'
+
+ The 'naturalLanguage' attribute syntax is a standard identifier for a
+ natural language and optionally a country. The values for this
+ syntax type are defined by RFC 1766 [RFC1766]. Though RFC 1766
+ requires that the values be case-insensitive US-ASCII [ASCII], IPP
+ requires all lower case to simplify comparing by IPP clients and
+ Printer objects. Examples include:
+
+ 'en': for English
+ 'en-us': for US English
+ 'fr': for French
+ 'de': for German
+
+ The maximum length of 'naturalLanguage' values used to represent IPP
+ attribute values is 63 octets.
+
+4.1.9 'mimeMediaType'
+
+ The 'mimeMediaType' attribute syntax is the Internet Media Type
+ (sometimes called MIME type) as defined by RFC 2046 [RFC2046] and
+ registered according to the procedures of RFC 2048 [RFC2048] for
+ identifying a document format. The value MAY include a charset, or
+ other, parameter, depending on the specification of the Media Type in
+ the IANA Registry [IANA-MT]. Although most other IPP syntax types
+ allow for only lower-cased values, this syntax type allows for
+ mixed-case values which are case-insensitive.
+
+ Examples are:
+ 'text/html': An HTML document
+ 'text/plain': A plain text document in US-ASCII (RFC 2046
+ indicates that in the absence of the charset parameter MUST
+ mean US-ASCII rather than simply unspecified) [RFC2046].
+ 'text/plain; charset=US-ASCII': A plain text document in US-ASCII
+ [52, 56].
+
+
+
+
+Hastings, et al. Standards Track [Page 87]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'text/plain; charset=ISO-8859-1': A plain text document in ISO
+ 8859-1 (Latin 1) [ISO8859-1].
+ 'text/plain; charset=utf-8': A plain text document in ISO 10646
+ represented as UTF-8 [RFC2279]
+ 'application/postscript': A PostScript document [RFC2046]
+ 'application/vnd.hp-PCL': A PCL document [IANA-MT] (charset
+ escape sequence embedded in the document data)
+ 'application/pdf': Portable Document Format - see IANA MIME Media
+ Type registry
+ 'application/octet-stream': Auto-sense - see section 4.1.9.1
+
+ The maximum length of a 'mimeMediaType' value to represent IPP
+ attribute values is 255 octets.
+
+4.1.9.1 Application/octet-stream -- Auto-Sensing the document format
+
+ One special type is 'application/octet-stream'. If the Printer
+ object supports this value, the Printer object MUST be capable of
+ auto-sensing the format of the document data using an
+ implementation-dependent method that examines some number of octets
+ of the document data, either as part of the create operation and/or
+ at document processing time. During auto-sensing, a Printer may
+ determine that the document-data has a format that the Printer
+ doesn't recognize. If the Printer determines this problem before
+ returning an operation response, it rejects the request and returns
+ the 'client-error-document-format-not-supported' status code. If the
+ Printer determines this problem after accepting the request and
+ returning an operation response with one of the successful status
+ codes, the Printer adds the 'unsupported-document-format' value to
+ the job's "job-state-reasons" attribute.
+
+ If the Printer object's default value attribute "document-format-
+ default" is set to 'application/octet-stream', the Printer object not
+ only supports auto-sensing of the document format, but will depend on
+ the result of applying its auto-sensing when the client does not
+ supply the "document-format" attribute. If the client supplies a
+ document format value, the Printer MUST rely on the supplied
+ attribute, rather than trust its auto-sensing algorithm. To
+ summarize:
+
+ 1. If the client does not supply a document format value, the
+ Printer MUST rely on its default value setting (which may be
+ 'application/octet-stream' indicating an auto-sensing
+ mechanism).
+ 2. If the client supplies a value other than 'application/octet-
+ stream', the client is supplying valid information about the
+ format of the document data and the Printer object MUST trust
+ the client supplied value more than the outcome of applying an
+
+
+
+Hastings, et al. Standards Track [Page 88]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ automatic format detection mechanism. For example, the client
+ may be requesting the printing of a PostScript file as a
+ 'text/plain' document. The Printer object MUST print a text
+ representation of the PostScript commands rather than interpret
+ the stream of PostScript commands and print the result.
+ 3. If the client supplies a value of 'application/octet-stream',
+ the client is indicating that the Printer object MUST use its
+ auto-sensing mechanism on the client supplied document data
+ whether auto-sensing is the Printer object's default or not.
+
+ Note: Since the auto-sensing algorithm is probabilistic, if the
+ client requests both auto-sensing ("document-format" set to
+ 'application/octet-stream') and true fidelity ("ipp-attribute-
+ fidelity" set to 'true'), the Printer object might not be able to
+ guarantee exactly what the end user intended (the auto-sensing
+ algorithm might mistake one document format for another), but it is
+ able to guarantee that its auto-sensing mechanism be used.
+
+ When a Printer performs auto-sensing of a document in a submitted
+ job, it is RECOMMENDED that the Printer indicate to the user that
+ such auto-sensing has occurred and which document-format was auto-
+ sensed by printing that information on the job's job-start-sheet.
+
+4.1.10 'octetString'
+
+ The 'octetString' attribute syntax is a sequence of octets encoded in
+ a maximum of 1023 octets which is indicated in sub-section headers
+ using the notation: octetString(MAX). This syntax type is used for
+ opaque data.
+
+4.1.11 'boolean'
+
+ The 'boolean' attribute syntax has only two values: 'true' and
+ 'false'.
+
+4.1.12 'integer'
+
+ The 'integer' attribute syntax is an integer value that is in the
+ range from -2**31 (MIN) to 2**31 - 1 (MAX). Each individual
+ attribute may specify the range constraint explicitly in sub-section
+ headers if the range is different from the full range of possible
+ integer values. For example: job-priority (integer(1:100)) for the
+ "job-priority" attribute. However, the enforcement of that
+ additional constraint is up to the IPP objects, not the protocol.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 89]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.1.13 'rangeOfInteger'
+
+ The 'rangeOfInteger' attribute syntax is an ordered pair of integers
+ that defines an inclusive range of integer values. The first integer
+ specifies the lower bound and the second specifies the upper bound.
+ If a range constraint is specified in the header description for an
+ attribute in this document whose attribute syntax is 'rangeOfInteger'
+ (i.e., 'X:Y' indicating X as a minimum value and Y as a maximum
+ value), then the constraint applies to both integers.
+
+4.1.14 'dateTime'
+
+ The 'dateTime' attribute syntax is a standard, fixed length, 11 octet
+ representation of the "DateAndTime" syntax as defined in RFC 2579
+ [RFC2579]. RFC 2579 also identifies an 8 octet representation of a
+ "DateAndTime" value, but IPP objects MUST use the 11 octet
+ representation. A user interface will provide a mapping between
+ protocol dateTime values and displayable user-friendly words or
+ presentation values and phrases which are localized to the natural
+ language and date format of the user, including time zone.
+
+4.1.15 'resolution'
+
+ The 'resolution' attribute syntax specifies a two-dimensional
+ resolution in the indicated units. It consists of 3 values: a cross
+ feed direction resolution (positive integer value), a feed direction
+ resolution (positive integer value), and a units value. The
+ semantics of these three components are taken from the Printer MIB
+ [RFC1759] suggested values. That is, the cross feed direction
+ component resolution component is the same as the
+ prtMarkerAddressabilityXFeedDir object in the Printer MIB, the feed
+ direction component resolution component is the same as the
+ prtMarkerAddressabilityFeedDir in the Printer MIB, and the units
+ component is the same as the prtMarkerAddressabilityUnit object in
+ the Printer MIB (namely, '3' indicates dots per inch and '4'
+ indicates dots per centimeter). All three values MUST be present
+ even if the first two values are the same. Example: '300', '600',
+ '3' indicates a 300 dpi cross-feed direction resolution, a 600 dpi
+ feed direction resolution, since a '3' indicates dots per inch (dpi).
+
+4.1.16 '1setOf X'
+
+ The '1setOf X' attribute syntax is 1 or more values of attribute
+ syntax type X. This syntax type is used for multi-valued attributes.
+ The syntax type is called '1setOf' rather than just 'setOf' as a
+ reminder that the set of values MUST NOT be empty (i.e., a set of
+
+
+
+
+
+Hastings, et al. Standards Track [Page 90]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ size 0). Sets are normally unordered. However each attribute
+ description of this type may specify that the values MUST be in a
+ certain order for that attribute.
+
+4.2 Job Template Attributes
+
+ Job Template attributes describe job processing behavior. Support
+ for Job Template attributes by a Printer object is OPTIONAL (see
+ section 12.2.3 for a description of support for OPTIONAL attributes).
+ Also, clients OPTIONALLY supply Job Template attributes in create
+ requests.
+
+ Job Template attributes conform to the following rules. For each Job
+ Template attribute called "xxx":
+
+ 1. If the Printer object supports "xxx" then it MUST support both
+ a "xxx-default" attribute (unless there is a "No" in the table
+ below) and a "xxx-supported" attribute. If the Printer object
+ doesn't support "xxx", then it MUST support neither an "xxx-
+ default" attribute nor an "xxx-supported" attribute, and it
+ MUST treat an attribute "xxx" supplied by a client as
+ unsupported. An attribute "xxx" may be supported for some
+ document formats and not supported for other document formats.
+ For example, it is expected that a Printer object would only
+ support "orientation-requested" for some document formats (such
+ as 'text/plain' or 'text/html') but not others (such as
+ 'application/postscript').
+
+ 2. "xxx" is OPTIONALLY supplied by the client in a create request.
+ If "xxx" is supplied, the client is indicating a desired job
+ processing behavior for this Job. When "xxx" is not supplied,
+ the client is indicating that the Printer object apply its
+ default job processing behavior at job processing time if the
+ document content does not contain an embedded instruction
+ indicating an xxx-related behavior.
+
+ Since an administrator MAY change the default value attribute
+ after a Job object has been submitted but before it has been
+ processed, the default value used by the Printer object at job
+ processing time may be different that the default value in
+ effect at job submission time.
+
+ 3. The "xxx-supported" attribute is a Printer object attribute
+ that describes which job processing behaviors are supported by
+ that Printer object. A client can query the Printer object to
+ find out what xxx-related behaviors are supported by inspecting
+ the returned values of the "xxx-supported" attribute.
+
+
+
+
+Hastings, et al. Standards Track [Page 91]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Note: The "xxx" in each "xxx-supported" attribute name is
+ singular, even though an "xxx-supported" attribute usually has
+ more than one value, such as "job-sheet-supported", unless the
+ "xxx" Job Template attribute is plural, such as "finishings" or
+ "sides". In such cases the "xxx-supported" attribute names
+ are: "finishings- supported" and "sides-supported".
+
+ 4. The "xxx-default" default value attribute describes what will
+ be done at job processing time when no other job processing
+ information is supplied by the client (either explicitly as an
+ IPP attribute in the create request or implicitly as an
+ embedded instruction within the document data).
+
+ If an application wishes to present an end user with a list of
+ supported values from which to choose, the application SHOULD query
+ the Printer object for its supported value attributes. The
+ application SHOULD also query the default value attributes. If the
+ application then limits selectable values to only those value that
+ are supported, the application can guarantee that the values supplied
+ by the client in the create request all fall within the set of
+ supported values at the Printer. When querying the Printer, the
+ client MAY enumerate each attribute by name in the Get-Printer-
+ Attributes Request, or the client MAY just name the "job-template"
+ group in order to get the complete set of supported attributes (both
+ supported and default attributes).
+
+ The "finishings" attribute is an example of a Job Template attribute.
+ It can take on a set of values such as 'staple', 'punch', and/or
+ 'cover'. A client can query the Printer object for the "finishings-
+ supported" attribute and the "finishings-default" attribute. The
+ supported attribute contains a set of supported values. The default
+ value attribute contains the finishing value(s) that will be used for
+ a new Job if the client does not supply a "finishings" attribute in
+ the create request and the document data does not contain any
+ corresponding finishing instructions. If the client does supply the
+ "finishings" attribute in the create request, the IPP object
+ validates the value or values to make sure that they are a subset of
+ the supported values identified in the Printer object's "finishings-
+ supported" attribute. See section 3.1.7.
+
+ The table below summarizes the names and relationships for all Job
+ Template attributes. The first column of the table (labeled "Job
+ Attribute") shows the name and syntax for each Job Template attribute
+ in the Job object. These are the attributes that can optionally be
+ supplied by the client in a create request. The last two columns
+ (labeled "Printer: Default Value Attribute" and "Printer: Supported
+ Values Attribute") show the name and syntax for each Job Template
+ attribute in the Printer object (the default value attribute and the
+
+
+
+Hastings, et al. Standards Track [Page 92]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ supported values attribute). A "No" in the table means the Printer
+ MUST NOT support the attribute (that is, the attribute is simply not
+ applicable). For brevity in the table, the 'text' and 'name' entries
+ do not show the maximum length for each attribute.
+
+ +===================+======================+======================+
+ | Job Attribute |Printer: Default Value| Printer: Supported |
+ | | Attribute | Values Attribute |
+ +===================+======================+======================+
+ | job-priority | job-priority-default |job-priority-supported|
+ | (integer 1:100) | (integer 1:100) |(integer 1:100) |
+ +-------------------+----------------------+----------------------+
+ | job-hold-until | job-hold-until- |job-hold-until- |
+ | (type3 keyword | | default | supported |
+ | name) | (type3 keyword | |(1setOf ( |
+ | | name) |type3 keyword | name))|
+ +-------------------+----------------------+----------------------+
+ | job-sheets | job-sheets-default |job-sheets-supported |
+ | (type3 keyword | | (type3 keyword | |(1setOf ( |
+ | name) | name) |type3 keyword | name))|
+ +-------------------+----------------------+----------------------+
+ |multiple-document- |multiple-document- |multiple-document- |
+ | handling | handling-default |handling-supported |
+ | (type2 keyword) | (type2 keyword) |(1setOf type2 keyword)|
+ +-------------------+----------------------+----------------------+
+ | copies | copies-default | copies-supported |
+ | (integer (1:MAX)) | (integer (1:MAX)) | (rangeOfInteger |
+ | | | (1:MAX)) |
+ +-------------------+----------------------+----------------------+
+ | finishings | finishings-default | finishings-supported |
+ |(1setOf type2 enum)|(1setOf type2 enum) |(1setOf type2 enum) |
+ +-------------------+----------------------+----------------------+
+ | page-ranges | No | page-ranges- |
+ | (1setOf | | supported (boolean) |
+ | rangeOfInteger | | |
+ | (1:MAX)) | | |
+ +-------------------+----------------------+----------------------+
+ | sides | sides-default | sides-supported |
+ | (type2 keyword) | (type2 keyword) |(1setOf type2 keyword)|
+ +-------------------+----------------------+----------------------+
+ | number-up | number-up-default | number-up-supported |
+ | (integer (1:MAX)) | (integer (1:MAX)) |(1setOf (integer |
+ | | | (1:MAX) | |
+ | | | rangeOfInteger |
+ | | | (1:MAX))) |
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 93]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ +-------------------+----------------------+----------------------+
+ | orientation- |orientation-requested-|orientation-requested-|
+ | requested | default | supported |
+ | (type2 enum) | (type2 enum) | (1setOf type2 enum) |
+ +-------------------+----------------------+----------------------+
+ | media | media-default | media-supported |
+ | (type3 keyword | | (type3 keyword | |(1setOf ( |
+ | name) | name) |type3 keyword | name))|
+ | | | |
+ | | | media-ready |
+ | | |(1setOf ( |
+ | | |type3 keyword | name))|
+ +-------------------+----------------------+----------------------+
+ | printer-resolution| printer-resolution- | printer-resolution- |
+ | (resolution) | default | supported |
+ | | (resolution) |(1setOf resolution) |
+ +-------------------+----------------------+----------------------+
+ | print-quality | print-quality-default| print-quality- |
+ | (type2 enum) | (type2 enum) | supported |
+ | | |(1setOf type2 enum) |
+ +-------------------+----------------------+----------------------+
+
+4.2.1 job-priority (integer(1:100))
+
+ This attribute specifies a priority for scheduling the Job. A higher
+ value specifies a higher priority. The value 1 indicates the lowest
+ possible priority. The value 100 indicates the highest possible
+ priority. Among those jobs that are ready to print, a Printer MUST
+ print all jobs with a priority value of n before printing those with
+ a priority value of n-1 for all n.
+
+ If the Printer object supports this attribute, it MUST always support
+ the full range from 1 to 100. No administrative restrictions are
+ permitted. This way an end-user can always make full use of the
+ entire range with any Printer object. If privileged jobs are
+ implemented outside IPP/1.1, they MUST have priorities higher than
+ 100, rather than restricting the range available to end-users.
+
+ If the client does not supply this attribute and this attribute is
+ supported by the Printer object, the Printer object MUST use the
+ value of the Printer object's "job-priority-default" at job
+ submission time (unlike most Job Template attributes that are used if
+ necessary at job processing time).
+
+ The syntax for the "job-priority-supported" is also integer(1:100).
+ This single integer value indicates the number of priority levels
+ supported. The Printer object MUST take the value supplied by the
+ client and map it to the closest integer in a sequence of n integers
+
+
+
+Hastings, et al. Standards Track [Page 94]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ values that are evenly distributed over the range from 1 to 100 using
+ the formula:
+
+ roundToNearestInt((100x+50)/n)
+
+ where n is the value of "job-priority-supported" and x ranges from 0
+ through n-1.
+
+ For example, if n=1 the sequence of values is 50; if n=2, the
+ sequence of values is: 25 and 75; if n = 3, the sequence of values
+ is: 17, 50 and 83; if n = 10, the sequence of values is: 5, 15, 25,
+ 35, 45, 55, 65, 75, 85, and 95; if n = 100, the sequence of values
+ is: 1, 2, 3, ... 100.
+
+ If the value of the Printer object's "job-priority-supported" is 10
+ and the client supplies values in the range 1 to 10, the Printer
+ object maps them to 5, in the range 11 to 20, the Printer object maps
+ them to 15, etc.
+
+4.2.2 job-hold-until (type3 keyword | name (MAX))
+
+ This attribute specifies the named time period during which the Job
+ MUST become a candidate for printing.
+
+ Standard keyword values for named time periods are:
+
+ 'no-hold': immediately, if there are not other reasons to hold the
+ job
+ 'indefinite': - the job is held indefinitely, until a client
+ performs a Release-Job (section 3.3.6)
+ 'day-time': during the day
+ 'evening': evening
+ 'night': night
+ 'weekend': weekend
+ 'second-shift': second-shift (after close of business)
+ 'third-shift': third-shift (after midnight)
+
+ An administrator MUST associate allowable print times with a named
+ time period (by means outside the scope of this IPP/1.1 document).
+ An administrator is encouraged to pick names that suggest the type of
+ time period. An administrator MAY define additional values using the
+ 'name' or 'keyword' attribute syntax, depending on implementation.
+
+ If the value of this attribute specifies a time period that is in the
+ future, the Printer SHOULD add the 'job-hold-until-specified' value
+ to the job's "job-state-reasons" attribute, MUST move the job to the
+
+
+
+
+
+Hastings, et al. Standards Track [Page 95]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'pending-held' state, and MUST NOT schedule the job for printing
+ until the specified time-period arrives.
+
+ When the specified time period arrives, the Printer MUST remove the
+ 'job-hold-until-specified' value from the job's "job-state-reason"
+ attribute, if present. If there are no other job state reasons that
+ keep the job in the 'pending-held' state, the Printer MUST consider
+ the job as a candidate for processing by moving the job to the
+ 'pending' state.
+
+ If this job attribute value is the named value 'no-hold', or the
+ specified time period has already started, the job MUST be a
+ candidate for processing immediately.
+
+ If the client does not supply this attribute and this attribute is
+ supported by the Printer object, the Printer object MUST use the
+ value of the Printer object's "job-hold-until-default" at job
+ submission time (unlike most Job Template attributes that are used if
+ necessary at job processing time).
+
+4.2.3 job-sheets (type3 keyword | name(MAX))
+
+ This attribute determines which job start/end sheet(s), if any, MUST
+ be printed with a job.
+
+ Standard keyword values are:
+
+ 'none': no job sheet is printed
+ 'standard': one or more site specific standard job sheets are
+ printed, e.g. a single start sheet or both start and end sheet is
+ printed
+
+ An administrator MAY define additional values using the 'name' or
+ 'keyword' attribute syntax, depending on implementation.
+
+ The effect of this attribute on jobs with multiple documents MAY be
+ affected by the "multiple-document-handling" job attribute (section
+ 4.2.4), depending on the job sheet semantics.
+
+4.2.4 multiple-document-handling (type2 keyword)
+
+ This attribute is relevant only if a job consists of two or more
+ documents. This attribute MUST be supported with at least one value
+ if the Printer supports multiple documents per job (see sections
+ 3.2.4 and 3.3.1). The attribute controls finishing operations and
+ the placement of one or more print-stream pages into impressions and
+ onto media sheets. When the value of the "copies" attribute exceeds
+ 1, it also controls the order in which the copies that result from
+
+
+
+Hastings, et al. Standards Track [Page 96]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ processing the documents are produced. For the purposes of this
+ explanations, if "a" represents an instance of document data, then
+ the result of processing the data in document "a" is a sequence of
+ media sheets represented by "a(*)".
+
+ Standard keyword values are:
+
+ 'single-document': If a Job object has multiple documents, say,
+ the document data is called a and b, then the result of
+ processing all the document data (a and then b) MUST be treated
+ as a single sequence of media sheets for finishing operations;
+ that is, finishing would be performed on the concatenation of
+ the sequences a(*),b(*). The Printer object MUST NOT force the
+ data in each document instance to be formatted onto a new
+ print-stream page, nor to start a new impression on a new media
+ sheet. If more than one copy is made, the ordering of the sets
+ of media sheets resulting from processing the document data
+ MUST be a(*), b(*), a(*), b(*), start on a new media sheet.
+ 'separate-documents-uncollated-copies': If a Job object has
+ multiple documents, say, the document data is called a and b,
+ then the result of processing the data in each document
+ instance MUST be treated as a single sequence of media sheets
+ for finishing operations; that is, the sets a(*) and b(*) would
+ each be finished separately. The Printer object MUST force each
+ copy of the result of processing the data in a single document
+ to start on a new media sheet. If more than one copy is made,
+ the ordering of the sets of media sheets resulting from
+ processing the document data MUST be a(*), a(*), ..., b(*),
+ b(*) ... .
+ 'separate-documents-collated-copies': If a Job object has multiple
+ documents, say, the document data is called a and b, then the
+ result of processing the data in each document instance MUST be
+ treated as a single sequence of media sheets for finishing
+ operations; that is, the sets a(*) and b(*) would each be
+ finished separately. The Printer object MUST force each copy of
+ the result of processing the data in a single document to start
+ on a new media sheet. If more than one copy is made, the
+ ordering of the sets of media sheets resulting from processing
+ the document data MUST be a(*), b(*), a(*), b(*), ... .
+ 'single-document-new-sheet': Same as 'single-document', except
+ that the Printer object MUST ensure that the first impression
+ of each document instance in the job is placed on a new media
+ sheet. This value allows multiple documents to be stapled
+ together with a single staple where each document starts on a
+ new sheet.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 97]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The 'single-document' value is the same as 'separate-documents-
+ collated-copies' with respect to ordering of print-stream pages, but
+ not media sheet generation, since 'single-document' will put the
+ first page of the next document on the back side of a sheet if an odd
+ number of pages have been produced so far for the job, while
+ 'separate-documents-collated- copies' always forces the next document
+ or document copy on to a new sheet. In addition, if the "finishings"
+ attribute specifies 'staple', then with 'single-document', documents
+ a and b are stapled together as a single document with no regard to
+ new sheets, with 'single-document-new-sheet', documents a and b are
+ stapled together as a single document, but document b starts on a new
+ sheet, but with 'separate-documents-uncollated-copies' and
+ 'separate-documents-collated-copies', documents a and b are stapled
+ separately.
+
+ Note: None of these values provide means to produce uncollated sheets
+ within a document, i.e., where multiple copies of sheet n are
+ produced before sheet n+1 of the same document.
+
+ The relationship of this attribute and the other attributes that
+ control document processing is described in section 15.3.
+
+4.2.5 copies (integer(1:MAX))
+
+ This attribute specifies the number of copies to be printed.
+
+ On many devices the supported number of collated copies will be
+ limited by the number of physical output bins on the device, and may
+ be different from the number of uncollated copies which can be
+ supported.
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+4.2.6 finishings (1setOf type2 enum)
+
+ This attribute identifies the finishing operations that the Printer
+ uses for each copy of each printed document in the Job. For Jobs with
+ multiple documents, the "multiple-document-handling" attribute
+ determines what constitutes a "copy" for purposes of finishing.
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 98]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Standard enum values are:
+
+ Value Symbolic Name and Description
+
+ '3' 'none': Perform no finishing
+ '4' 'staple': Bind the document(s) with one or more staples. The
+ exact number and placement of the staples is site-
+ defined.
+ '5' 'punch': This value indicates that holes are required in the
+ finished document. The exact number and placement of the
+ holes is site-defined The punch specification MAY be
+ satisfied (in a site- and implementation-specific manner)
+ either by drilling/punching, or by substituting pre-
+ drilled media.
+ '6' 'cover': This value is specified when it is desired to select
+ a non-printed (or pre-printed) cover for the document.
+ This does not supplant the specification of a printed
+ cover (on cover stock medium) by the document itself.
+ '7' 'bind': This value indicates that a binding is to be applied
+ to the document; the type and placement of the binding is
+ site-defined.
+ '8' 'saddle-stitch': Bind the document(s) with one or more
+ staples (wire stitches) along the middle fold. The exact
+ number and placement of the staples and the middle fold
+ is implementation and/or site-defined.
+ '9' 'edge-stitch': Bind the document(s) with one or more staples
+ (wire stitches) along one edge. The exact number and
+ placement of the staples is implementation and/or site-
+ defined.
+ '10'-'19' reserved for future generic finishing enum values.
+
+ The following values are more specific; they indicate a corner or an
+ edge as if the document were a portrait document (see below):
+
+ '20' 'staple-top-left': Bind the document(s) with one or more
+ staples in the top left corner.
+ '21' 'staple-bottom-left': Bind the document(s) with one or more
+ staples in the bottom left corner.
+ '22' 'staple-top-right': Bind the document(s) with one or more
+ staples in the top right corner.
+ '23' 'staple-bottom-right': Bind the document(s) with one or more
+ staples in the bottom right corner.
+ '24' 'edge-stitch-left': Bind the document(s) with one or more
+ staples (wire stitches) along the left edge. The exact
+ number and placement of the staples is implementation
+ and/or site-defined.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 99]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ '25' 'edge-stitch-top': Bind the document(s) with one or more
+ staples (wire stitches) along the top edge. The exact
+ number and placement of the staples is implementation
+ and/or site-defined.
+ '26' 'edge-stitch-right': Bind the document(s) with one or more
+ staples (wire stitches) along the right edge. The exact
+ number and placement of the staples is implementation
+ and/or site-defined.
+ '27' 'edge-stitch-bottom': Bind the document(s) with one or more
+ staples (wire stitches) along the bottom edge. The exact
+ number and placement of the staples is implementation
+ and/or site-defined.
+ '28' 'staple-dual-left': Bind the document(s) with two staples
+ (wire stitches) along the left edge assuming a portrait
+ document (see above).
+ '29' 'staple-dual-top': Bind the document(s) with two staples
+ (wire stitches) along the top edge assuming a portrait
+ document (see above).
+ '30' 'staple-dual-right': Bind the document(s) with two staples
+ (wire stitches) along the right edge assuming a portrait
+ document (see above).
+ '31' 'staple-dual-bottom': Bind the document(s) with two staples
+ (wire stitches) along the bottom edge assuming a portrait
+ document (see above).
+
+ The 'staple-xxx' values are specified with respect to the document as
+ if the document were a portrait document. If the document is
+ actually a landscape or a reverse-landscape document, the client
+ supplies the appropriate transformed value. For example, to position
+ a staple in the upper left hand corner of a landscape document when
+ held for reading, the client supplies the 'staple-bottom-left' value
+ (since landscape is defined as a +90 degree rotation of the image
+ with respect to the media from portrait, i.e., anti-clockwise). On
+ the other hand, to position a staple in the upper left hand corner of
+ a reverse-landscape document when held for reading, the client
+ supplies the 'staple-top-right' value (since reverse-landscape is
+ defined as a -90 degree rotation of the image with respect to the
+ media from portrait, i.e., clockwise).
+
+ The angle (vertical, horizontal, angled) of each staple with respect
+ to the document depends on the implementation which may in turn
+ depend on the value of the attribute.
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+
+
+Hastings, et al. Standards Track [Page 100]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ If the client supplies a value of 'none' along with any other
+ combination of values, it is the same as if only that other
+ combination of values had been supplied (that is the 'none' value has
+ no effect).
+
+4.2.7 page-ranges (1setOf rangeOfInteger (1:MAX))
+
+ This attribute identifies the range(s) of print-stream pages that the
+ Printer object uses for each copy of each document which are to be
+ printed. Nothing is printed for any pages identified that do not
+ exist in the document(s). Ranges MUST be in ascending order, for
+ example: 1-3, 5-7, 15-19 and MUST NOT overlap, so that a non-spooling
+ Printer object can process the job in a single pass. If the ranges
+ are not ascending or are overlapping, the IPP object MUST reject the
+ request and return the 'client-error-bad-request' status code. The
+ attribute is associated with print-stream pages not application-
+ numbered pages (for example, the page numbers found in the headers
+ and or footers for certain word processing applications).
+
+ For Jobs with multiple documents, the "multiple-document-handling"
+ attribute determines what constitutes a "copy" for purposes of the
+ specified page range(s). When "multiple-document-handling" is
+ 'single-document', the Printer object MUST apply each supplied page
+ range once to the concatenation of the print-stream pages. For
+ example, if there are 8 documents of 10 pages each, the page-range
+ '41:60' prints the pages in the 5th and 6th documents as a single
+ document and none of the pages of the other documents are printed.
+ When "multiple-document- handling" is 'separate-documents-
+ uncollated-copies' or 'separate-documents-collated-copies', the
+ Printer object MUST apply each supplied page range repeatedly to each
+ document copy. For the same job, the page-range '1:3, 10:10' would
+ print the first 3 pages and the 10th page of each of the 8 documents
+ in the Job, as 8 separate documents.
+
+ In most cases, the exact pages to be printed will be generated by a
+ device driver and this attribute would not be required. However,
+ when printing an archived document which has already been formatted,
+ the end user may elect to print just a subset of the pages contained
+ in the document. In this case, if page-range = n.m is specified, the
+ first page to be printed will be page n. All subsequent pages of the
+ document will be printed through and including page m.
+
+ "page-ranges-supported" is a boolean value indicating whether or not
+ the printer is capable of supporting the printing of page ranges.
+ This capability may differ from one PDL to another. There is no
+ "page-ranges-default" attribute. If the "page-ranges" attribute is
+ not supplied by the client, all pages of the document will be
+ printed.
+
+
+
+Hastings, et al. Standards Track [Page 101]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+4.2.8 sides (type2 keyword)
+
+ This attribute specifies how print-stream pages are to be imposed
+ upon the sides of an instance of a selected medium, i.e., an
+ impression.
+
+ The standard keyword values are:
+
+ 'one-sided': imposes each consecutive print-stream page upon the
+ same side of consecutive media sheets.
+ 'two-sided-long-edge': imposes each consecutive pair of print-
+ stream pages upon front and back sides of consecutive media
+ sheets, such that the orientation of each pair of print-stream
+ pages on the medium would be correct for the reader as if for
+ binding on the long edge. This imposition is sometimes called
+ 'duplex' or 'head-to-head'.
+ 'two-sided-short-edge': imposes each consecutive pair of print-
+ stream pages upon front and back sides of consecutive media
+ sheets, such that the orientation of each pair of print-stream
+ pages on the medium would be correct for the reader as if for
+ binding on the short edge. This imposition is sometimes called
+ 'tumble' or 'head-to-toe'.
+ 'two-sided-long-edge', 'two-sided-short-edge',
+ 'tumble', and 'duplex' all work the same for portrait or
+ landscape. However
+ 'head-to-toe' is
+ 'tumble' in portrait but 'duplex' in landscape. 'head-to-head'
+ also switches between 'duplex' and 'tumble' when using portrait
+ and landscape modes.
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+4.2.9 number-up (integer(1:MAX))
+
+ This attribute specifies the number of print-stream pages to impose
+ upon a single side of an instance of a selected medium. For example,
+ if the value is:
+
+
+
+
+Hastings, et al. Standards Track [Page 102]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Value Description
+
+ '1' the Printer MUST place one print-stream page on a single side
+ of an instance of the selected medium (MAY add some sort
+ of translation, scaling, or rotation).
+ '2' the Printer MUST place two print-stream pages on a single side
+ of an instance of the selected medium (MAY add some sort
+ of translation, scaling, or rotation).
+ '4' the Printer MUST place four print-stream pages on a single
+ side of an instance of the selected medium (MAY add some
+ sort of translation, scaling, or rotation).
+
+ This attribute primarily controls the translation, scaling and
+ rotation of print-stream pages.
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+4.2.10 orientation-requested (type2 enum)
+
+ This attribute indicates the desired orientation for printed print-
+ stream pages; it does not describe the orientation of the client-
+ supplied print-stream pages.
+
+ For some document formats (such as 'application/postscript'), the
+ desired orientation of the print-stream pages is specified within the
+ document data. This information is generated by a device driver
+ prior to the submission of the print job. Other document formats
+ (such as 'text/plain') do not include the notion of desired
+ orientation within the document data. In the latter case it is
+ possible for the Printer object to bind the desired orientation to
+ the document data after it has been submitted. It is expected that a
+ Printer object would only support "orientations-requested" for some
+ document formats (e.g., 'text/plain' or 'text/html') but not others
+ (e.g., 'application/postscript'). This is no different than any
+ other Job Template attribute since section 4.2, item 1, points out
+ that a Printer object may support or not support any Job Template
+ attribute based on the document format supplied by the client.
+ However, a special mention is made here since it is very likely that
+ a Printer object will support "orientation-requested" for only a
+ subset of the supported document formats.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 103]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Standard enum values are:
+
+ Value Symbolic Name and Description
+
+ '3' 'portrait': The content will be imaged across the short edge
+ of the medium.
+ '4' 'landscape': The content will be imaged across the long edge
+ of the medium. Landscape is defined to be a rotation of
+ the print-stream page to be imaged by +90 degrees with
+ respect to the medium (i.e. anti-clockwise) from the
+ portrait orientation. Note: The +90 direction was
+ chosen because simple finishing on the long edge is the
+ same edge whether portrait or landscape
+ '5' 'reverse-landscape': The content will be imaged across the
+ long edge of the medium. Reverse-landscape is defined to
+ be a rotation of the print-stream page to be imaged by -
+ 90 degrees with respect to the medium (i.e. clockwise)
+ from the portrait orientation. Note: The 'reverse-
+ landscape' value was added because some applications
+ rotate landscape -90 degrees from portrait, rather than
+ +90 degrees.
+ '6' 'reverse-portrait': The content will be imaged across the
+ short edge of the medium. Reverse-portrait is defined to
+ be a rotation of the print-stream page to be imaged by
+ 180 degrees with respect to the medium from the portrait
+ orientation. Note: The 'reverse-portrait' value was
+ added for use with the "finishings" attribute in cases
+ where the opposite edge is desired for finishing a
+ portrait document on simple finishing devices that have
+ only one finishing position. Thus a 'text'/plain'
+ portrait document can be stapled "on the right" by a
+ simple finishing device as is common use with some middle
+ eastern languages such as Hebrew.
+
+ Note: The effect of this attribute on jobs with multiple documents is
+ controlled by the "multiple-document-handling" job attribute (section
+ 4.2.4) and the relationship of this attribute and the other
+ attributes that control document processing is described in section
+ 15.3.
+
+4.2.11 media (type3 keyword | name(MAX))
+
+ This attribute identifies the medium that the Printer uses for all
+ impressions of the Job.
+
+ The values for "media" include medium-names, medium-sizes, input-
+ trays and electronic forms so that one attribute specifies the media.
+ If a Printer object supports a medium name as a value of this
+
+
+
+Hastings, et al. Standards Track [Page 104]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ attribute, such a medium name implicitly selects an input-tray that
+ contains the specified medium. If a Printer object supports a medium
+ size as a value of this attribute, such a medium size implicitly
+ selects a medium name that in turn implicitly selects an input-tray
+ that contains the medium with the specified size. If a Printer
+ object supports an input-tray as the value of this attribute, such an
+ input-tray implicitly selects the medium that is in that input-tray
+ at the time the job prints. This case includes manual-feed input-
+ trays. If a Printer object supports an electronic form as the value
+ of this attribute, such an electronic form implicitly selects a
+ medium-name that in turn implicitly selects an input-tray that
+ contains the medium specified by the electronic form. The electronic
+ form also implicitly selects an image that the Printer MUST merge
+ with the document data as its prints each page.
+
+ Standard keyword values are taken from ISO DPA [ISO10175], the
+ Printer MIB [RFC1759], and ASME-Y14.1M [ASME-Y14.1M] and are listed
+ in section 14. An administrator MAY define additional values using
+ the 'name' or 'keyword' attribute syntax, depending on
+ implementation.
+
+ There is also an additional Printer attribute named "media-ready"
+ which differs from "media-supported" in that legal values only
+ include the subset of "media-supported" values that are physically
+ loaded and ready for printing with no operator intervention required.
+ If an IPP object supports "media-supported", it NEED NOT support
+ "media-ready".
+
+ The relationship of this attribute and the other attributes that
+ control document processing is described in section 15.3.
+
+4.2.12 printer-resolution (resolution)
+
+ This attribute identifies the resolution that Printer uses for the
+ Job.
+
+4.2.13 print-quality (type2 enum)
+
+ This attribute specifies the print quality that the Printer uses for
+ the Job.
+
+ The standard enum values are:
+
+ Value Symbolic Name and Description
+
+ '3' 'draft': lowest quality available on the printer
+ '4' 'normal': normal or intermediate quality on the printer
+ '5' 'high': highest quality available on the printer
+
+
+
+Hastings, et al. Standards Track [Page 105]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.3 Job Description Attributes
+
+ The attributes in this section form the attribute group called "job-
+ description". The following table summarizes these attributes. The
+ third column indicates whether the attribute is a REQUIRED attribute
+ that MUST be supported by Printer objects. If it is not indicated as
+ REQUIRED, then it is OPTIONAL. The maximum size in octets for 'text'
+ and 'name' attributes is indicated in parenthesizes.
+
+ +----------------------------+----------------------+--------------+
+ | Attribute | Syntax | REQUIRED? |
+ +----------------------------+----------------------+--------------+
+ | job-uri | uri | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | job-id | integer(1:MAX) | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | job-printer-uri | uri | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | job-more-info | uri | |
+ +----------------------------+----------------------+--------------+
+ | job-name | name (MAX) | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | job-originating-user-name | name (MAX) | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | job-state | type1 enum | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | job-state-reasons | 1setOf type2 keyword | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | job-state-message | text (MAX) | |
+ +----------------------------+----------------------+--------------+
+ | job-detailed-status- | 1setOf text (MAX) | |
+ | messages | | |
+ +----------------------------+----------------------+--------------+
+ | job-document-access-errors | 1setOf text (MAX) | |
+ +----------------------------+----------------------+--------------+
+ | number-of-documents | integer (0:MAX) | |
+ +----------------------------+----------------------+--------------+
+ | output-device-assigned | name (127) | |
+ +----------------------------+----------------------+--------------+
+ | time-at-creation | integer (MIN:MAX) | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | time-at-processing | integer (MIN:MAX) | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | time-at-completed | integer (MIN:MAX) | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | job-printer-up-time | integer (1:MAX) | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | date-time-at-creation | dateTime | |
+
+
+
+Hastings, et al. Standards Track [Page 106]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ +----------------------------+----------------------+--------------+
+ | date-time-at-processing | dateTime | |
+ +----------------------------+----------------------+--------------+
+ | date-time-at-completed | dateTime | |
+ +----------------------------+----------------------+--------------+
+ | number-of-intervening-jobs | integer (0:MAX) | |
+ +----------------------------+----------------------+--------------+
+ | job-message-from-operator | text (127) | |
+ +----------------------------+----------------------+--------------+
+ | job-k-octets | integer (0:MAX) | |
+ +----------------------------+----------------------+--------------+
+ | job-impressions | integer (0:MAX) | |
+ +----------------------------+----------------------+--------------+
+ | job-media-sheets | integer (0:MAX) | |
+ +----------------------------+----------------------+--------------+
+ | job-k-octets-processed | integer (0:MAX) | |
+ +----------------------------+----------------------+--------------+
+ | job-impressions-completed | integer (0:MAX) | |
+ +----------------------------+----------------------+--------------+
+ | job-media-sheets-completed | integer (0:MAX) | |
+ +----------------------------+----------------------+--------------+
+ | attributes-charset | charset | REQUIRED |
+ +----------------------------+----------------------+--------------+
+ | attributes-natural-language| naturalLanguage | REQUIRED |
+ +----------------------------+----------------------+--------------+
+
+4.3.1 job-uri (uri)
+
+ This REQUIRED attribute contains the URI for the job. The Printer
+ object, on receipt of a new job, generates a URI which identifies the
+ new Job. The Printer object returns the value of the "job-uri"
+ attribute as part of the response to a create request. The precise
+ format of a Job URI is implementation dependent. If the Printer
+ object supports more than one URI and there is some relationship
+ between the newly formed Job URI and the Printer object's URI, the
+ Printer object uses the Printer URI supplied by the client in the
+ create request. For example, if the create request comes in over a
+ secure channel, the new Job URI MUST use the same secure channel.
+ This can be guaranteed because the Printer object is responsible for
+ generating the Job URI and the Printer object is aware of its
+ security configuration and policy as well as the Printer URI used in
+ the create request.
+
+ For a description of this attribute and its relationship to "job-id"
+ and "job-printer-uri" attribute, see the discussion in section 2.4 on
+ "Object Identity".
+
+
+
+
+
+Hastings, et al. Standards Track [Page 107]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.3.2 job-id (integer(1:MAX))
+
+ This REQUIRED attribute contains the ID of the job. The Printer, on
+ receipt of a new job, generates an ID which identifies the new Job on
+ that Printer. The Printer returns the value of the "job-id"
+ attribute as part of the response to a create request. The 0 value
+ is not included to allow for compatibility with SNMP index values
+ which also cannot be 0.
+
+ For a description of this attribute and its relationship to "job-uri"
+ and "job-printer-uri" attribute, see the discussion in section 2.4 on
+ "Object Identity".
+
+4.3.3 job-printer-uri (uri)
+
+ This REQUIRED attribute identifies the Printer object that created
+ this Job object. When a Printer object creates a Job object, it
+ populates this attribute with the Printer object URI that was used in
+ the create request. This attribute permits a client to identify the
+ Printer object that created this Job object when only the Job
+ object's URI is available to the client. The client queries the
+ creating Printer object to determine which languages, charsets,
+ operations, are supported for this Job.
+
+ For a description of this attribute and its relationship to "job-uri"
+ and "job-id" attribute, see the discussion in section 2.4 on "Object
+ Identity".
+
+4.3.4 job-more-info (uri)
+
+ Similar to "printer-more-info", this attribute contains the URI
+ referencing some resource with more information about this Job
+ object, perhaps an HTML page containing information about the Job.
+
+4.3.5 job-name (name(MAX))
+
+ This REQUIRED attribute is the name of the job. It is a name that is
+ more user friendly than the "job-uri" attribute value. It does not
+ need to be unique between Jobs. The Job's "job-name" attribute is
+ set to the value supplied by the client in the "job-name" operation
+ attribute in the create request (see Section 3.2.1.1). If, however,
+ the "job-name" operation attribute is not supplied by the client in
+ the create request, the Printer object, on creation of the Job, MUST
+ generate a name. The printer SHOULD generate the value of the Job's
+ "job-name" attribute from the first of the following sources that
+ produces a value: 1) the "document-name" operation attribute of the
+
+
+
+
+
+Hastings, et al. Standards Track [Page 108]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ first (or only) document, 2) the "document-URI" attribute of the
+ first (or only) document, or 3) any other piece of Job specific
+ and/or Document Content information.
+
+4.3.6 job-originating-user-name (name(MAX))
+
+ This REQUIRED attribute contains the name of the end user that
+ submitted the print job. The Printer object sets this attribute to
+ the most authenticated printable name that it can obtain from the
+ authentication service over which the IPP operation was received.
+ Only if such is not available, does the Printer object use the value
+ supplied by the client in the "requesting-user-name" operation
+ attribute of the create operation (see Sections 4.4.2, 4.4.3, and 8).
+
+ Note: The Printer object needs to keep an internal originating user
+ id of some form, typically as a credential of a principal, with the
+ Job object. Since such an internal attribute is implementation-
+ dependent and not of interest to clients, it is not specified as a
+ Job Description attribute. This originating user id is used for
+ authorization checks (if any) on all subsequent operations.
+
+4.3.7 job-state (type1 enum)
+
+ This REQUIRED attribute identifies the current state of the job.
+ Even though the IPP protocol defines seven values for job states
+ (plus the out-of-band 'unknown' value - see Section 4.1),
+ implementations only need to support those states which are
+ appropriate for the particular implementation. In other words, a
+ Printer supports only those job states implemented by the output
+ device and available to the Printer object implementation.
+
+ Standard enum values are:
+
+ Values Symbolic Name and Description
+
+ '3' 'pending': The job is a candidate to start processing, but is
+ not yet processing.
+
+ '4' 'pending-held': The job is not a candidate for processing for
+ any number of reasons but will return to the 'pending'
+ state as soon as the reasons are no longer present. The
+ job's "job-state-reason" attribute MUST indicate why the
+ job is no longer a candidate for processing.
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 109]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ '5' 'processing': One or more of:
+
+ 1. the job is using, or is attempting to use, one or
+ more purely software processes that are analyzing,
+ creating, or interpreting a PDL, etc.,
+ 2. the job is using, or is attempting to use, one or
+ more hardware devices that are interpreting a PDL, making
+ marks on a medium, and/or performing finishing, such as
+ stapling, etc.,
+ 3. the Printer object has made the job ready for
+ printing, but the output device is not yet printing it,
+ either because the job hasn't reached the output device
+ or because the job is queued in the output device or some
+ other spooler, awaiting the output device to print it.
+
+ When the job is in the 'processing' state, the entire job
+ state includes the detailed status represented in the
+ Printer object's "printer-state", "printer-state-
+ reasons", and "printer-state-message" attributes.
+
+ Implementations MAY, though they NEED NOT, include
+ additional values in the job's "job-state-reasons"
+ attribute to indicate the progress of the job, such as
+ adding the 'job-printing' value to indicate when the
+ output device is actually making marks on paper and/or
+ the 'processing-to-stop-point' value to indicate that the
+ IPP object is in the process of canceling or aborting the
+ job. Most implementations won't bother with this nuance.
+
+ '6' 'processing-stopped': The job has stopped while processing
+ for any number of reasons and will return to the
+ 'processing' state as soon as the reasons are no longer
+ present.
+
+ The job's "job-state-reason" attribute MAY indicate why
+ the job has stopped processing. For example, if the
+ output device is stopped, the 'printer-stopped' value MAY
+ be included in the job's "job-state-reasons" attribute.
+
+ Note: When an output device is stopped, the device
+ usually indicates its condition in human readable form
+ locally at the device. A client can obtain more complete
+ device status remotely by querying the Printer object's
+ "printer-state", "printer-state-reasons" and "printer-
+ state-message" attributes.
+
+ '7' 'canceled': The job has been canceled by a Cancel-Job
+ operation and the Printer object has completed canceling
+
+
+
+Hastings, et al. Standards Track [Page 110]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ the job and all job status attributes have reached their
+ final values for the job. While the Printer object is
+ canceling the job, the job remains in its current state,
+ but the job's "job-state-reasons" attribute SHOULD
+ contain the 'processing-to-stop-point' value and one of
+ the 'canceled-by-user', 'canceled-by-operator', or
+ 'canceled-at-device' value. When the job moves to the
+ 'canceled' state, the 'processing-to-stop-point' value,
+ if present, MUST be removed, but the 'canceled-by-xxx',
+ if present, MUST remain.
+
+ '8' 'aborted': The job has been aborted by the system, usually
+ while the job was in the 'processing' or 'processing-
+ stopped' state and the Printer has completed aborting the
+ job and all job status attributes have reached their
+ final values for the job. While the Printer object is
+ aborting the job, the job remains in its current state,
+ but the job's "job-state-reasons" attribute SHOULD
+ contain the 'processing-to-stop-point' and 'aborted-by-
+ system' values. When the job moves to the 'aborted'
+ state, the 'processing-to-stop-point' value, if present,
+ MUST be removed, but the 'aborted-by-system' value, if
+ present, MUST remain.
+
+ '9' 'completed': The job has completed successfully or with
+ warnings or errors after processing and all of the job
+ media sheets have been successfully stacked in the
+ appropriate output bin(s) and all job status attributes
+ have reached their final values for the job. The job's
+ "job-state-reasons" attribute SHOULD contain one of:
+ 'completed-successfully', 'completed-with-warnings', or
+ 'completed-with-errors' values.
+
+ The final value for this attribute MUST be one of: 'completed',
+ 'canceled', or 'aborted' before the Printer removes the job
+ altogether. The length of time that jobs remain in the 'canceled',
+ 'aborted', and 'completed' states depends on implementation. See
+ section 4.3.7.2.
+
+ The following figure shows the normal job state transitions.
+
+ +----> canceled
+ /
+ +----> pending --------> processing ---------+------> completed
+ | ^ ^ \
+ --->+ | | +----> aborted
+ | v v /
+ +----> pending-held processing-stopped ---+
+
+
+
+Hastings, et al. Standards Track [Page 111]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Normally a job progresses from left to right. Other state
+ transitions are unlikely, but are not forbidden. Not shown are the
+ transitions to the 'canceled' state from the 'pending', 'pending-
+ held', and 'processing-stopped' states.
+
+ Jobs reach one of the three terminal states: 'completed', 'canceled',
+ or 'aborted', after the jobs have completed all activity, including
+ stacking output media, after the jobs have completed all activity,
+ and all job status attributes have reached their final values for the
+ job.
+
+4.3.7.1 Forwarding Servers
+
+ As with all other IPP attributes, if the implementation cannot
+ determine the correct value for this attribute, it SHOULD respond
+ with the out-of-band value 'unknown' (see section 4.1) rather than
+ try to guess at some possibly incorrect value and give the end user
+ the wrong impression about the state of the Job object. For example,
+ if the implementation is just a gateway into some printing system
+ from which it can normally get status, but temporarily is unable,
+ then the implementation should return the 'unknown' value. However,
+ if the implementation is a gateway to a printing system that never
+ provides detailed status about the print job, the implementation MAY
+ set the IPP Job object's state to 'completed', provided that it also
+ sets the 'queued-in-device' value in the job's "job-state-reasons"
+ attribute (see section 4.3.8).
+
+4.3.7.2 Partitioning of Job States
+
+ This section partitions the 7 job states into phases: Job Not
+ Completed, Job Retention, Job History, and Job Removal. This section
+ also explains the 'job-restartable' value of the "job-state-reasons"
+ Job Description attribute for use with the Restart-Job operation.
+
+ Job Not Completed: When a job is in the 'pending', 'pending-held',
+ 'processing', or 'processing-stopped' states, the job is not
+ completed.
+
+ Job Retention: When a job enters one of the three terminal job
+ states: 'completed', 'canceled', or 'aborted', the IPP Printer
+ object MAY "retain" the job in a restartable condition for an
+ implementation-defined time period. This time period MAY be zero
+ seconds and MAY depend on the terminal job state. This phase is
+ called Job Retention. While in the Job Retention phase, the job's
+ document data is retained and a client may restart the job using the
+ Restart-Job operation. If the IPP object supports the Restart-Job
+
+
+
+
+
+Hastings, et al. Standards Track [Page 112]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ operation, then it SHOULD indicate that the job is restartable by
+ adding the 'job-restartable' value to the job's "job-state-reasons"
+ attribute (see Section 4.3.8) during the Job Retention phase.
+
+ Job History: After the Job Retention phase expires for a job, the
+ Printer object deletes the document data for the job and the job
+ becomes part of the Job History. The Printer object MAY also delete
+ any number of the job attributes. Since the job is no longer
+ restartable, the Printer object MUST remove the 'job-restartable'
+ value from the job's "job-state-reasons" attribute, if present.
+
+ Job Removal: After the job has remained in the Job History for an
+ implementation-defined time, such as when the number of jobs exceeds
+ a fixed number or after a fixed time period (which MAY be zero
+ seconds), the IPP Printer removes the job from the system.
+
+ Using the Get-Jobs operation and supplying the 'not-completed' value
+ for the "which-jobs" operation attribute, a client is requesting jobs
+ in the Job Not Completed phase. Using the Get-Jobs operation and
+ supplying the 'completed' value for the "which-jobs" operation
+ attribute, a client is requesting jobs in the Job Retention and Job
+ History phases. Using the Get-Job-Attributes operation, a client is
+ requesting a job in any phase except Job Removal. After Job Removal,
+ the Get-Job-Attributes and Get-Jobs operations no longer are capable
+ of returning any information about a job.
+
+4.3.8 job-state-reasons (1setOf type2 keyword)
+
+ This REQUIRED attribute provides additional information about the
+ job's current state, i.e., information that augments the value of the
+ job's "job-state" attribute.
+
+ These values MAY be used with any job state or states for which the
+ reason makes sense. Some of these value definitions indicate
+ conformance requirements; the rest are OPTIONAL. Furthermore, when
+ implemented, the Printer MUST return these values when the reason
+ applies and MUST NOT return them when the reason no longer applies
+ whether the value of the Job's "job-state" attribute changed or not.
+ When the Job does not have any reasons for being in its current
+ state, the value of the Job's "job-state-reasons" attribute MUST be
+ 'none'.
+
+ Note: While values cannot be added to the 'job-state' attribute
+ without impacting deployed clients that take actions upon receiving
+ "job-state" values, it is the intent that additional "job-state-
+ reasons" values can be defined and registered without impacting such
+ deployed clients. In other words, the "job-state-reasons" attribute
+ is intended to be extensible.
+
+
+
+Hastings, et al. Standards Track [Page 113]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The following standard keyword values are defined. For ease of
+ understanding, the values are presented in the order in which the
+ reasons are likely to occur (if implemented), starting with the
+ 'job-incoming' value:
+
+ 'none': There are no reasons for the job's current state. This
+ state reason is semantically equivalent to "job-state-reasons"
+ without any value and MUST be used when there is no other
+ value, since the 1setOf attribute syntax requires at least one
+ value.
+ 'job-incoming': Either (1) the Printer has accepted the Create-
+ Job operation and is expecting additional Send-Document and/or
+ Send-URI operations, or (2) the Printer is retrieving/accepting
+ document data as a result of a Print-Job, Print-URI, Send-
+ Document or Send-URI operation.
+ 'job-data-insufficient': The Create-Job operation has been
+ accepted by the Printer, but the Printer is expecting
+ additional document data before it can move the job into the
+ 'processing' state. If a Printer starts processing before it
+ has received all data, the Printer removes the 'job-data-
+ insufficient' reason, but the 'job-incoming' remains. If a
+ Printer starts processing after it has received all data, the
+ Printer removes the 'job-data-insufficient' reason and the
+ 'job-incoming' at the same time.
+ 'document-access-error': After accepting a Print-URI or Send-URI
+ request, the Printer could not access one or more documents
+ passed by reference. This reason is intended to cover any file
+ access problem, including file does not exist and access denied
+ because of an access control problem. The Printer MAY also
+ indicate the document access error using the "job-document-
+ access-errors" Job Description attribute (see section 4.3.11).
+ Whether the Printer aborts the job and moves the job to the
+ 'aborted' job state or prints all documents that are accessible
+ and moves the job to the 'completed' job state and adds the
+ 'completed-with-errors' value in the job's "job-state-reasons"
+ attribute depends on implementation and/or site policy. This
+ value SHOULD be supported if the Print-URI or Send-URI
+ operations are supported.
+ 'submission-interrupted': The job was not completely submitted
+ for some unforeseen reason, such as: (1) the Printer has
+ crashed before the job was closed by the client, (2) the
+ Printer or the document transfer method has crashed in some
+ non-recoverable way before the document data was entirely
+ transferred to the Printer, (3) the client crashed or failed to
+ close the job before the time-out period. See section 4.4.31.
+ 'job-outgoing': The Printer is transmitting the job to the output
+ device.
+
+
+
+
+Hastings, et al. Standards Track [Page 114]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'job-hold-until-specified': The value of the job's "job-hold-
+ until" attribute was specified with a time period that is still
+ in the future. The job MUST NOT be a candidate for processing
+ until this reason is removed and there are no other reasons to
+ hold the job. This value SHOULD be supported if the "job-
+ hold-until" Job Template attribute is supported.
+ 'resources-are-not-ready': At least one of the resources needed
+ by the job, such as media, fonts, resource objects, etc., is
+ not ready on any of the physical printer's for which the job is
+ a candidate. This condition MAY be detected when the job is
+ accepted, or subsequently while the job is pending or
+ processing, depending on implementation. The job may remain in
+ its current state or be moved to the 'pending-held' state,
+ depending on implementation and/or job scheduling policy.
+ 'printer-stopped-partly': The value of the Printer's "printer-
+ state-reasons" attribute contains the value 'stopped-partly'.
+ 'printer-stopped': The value of the Printer's "printer-state"
+ attribute is 'stopped'.
+ 'job-interpreting': Job is in the 'processing' state, but more
+ specifically, the Printer is interpreting the document data.
+ 'job-queued': Job is in the 'processing' state, but more
+ specifically, the Printer has queued the document data.
+ 'job-transforming': Job is in the 'processing' state, but more
+ specifically, the Printer is interpreting document data and
+ producing another electronic representation.
+ 'job-queued-for-marker': Job is in any of the 'pending-held',
+ 'pending', or 'processing' states, but more specifically, the
+ Printer has completed enough processing of the document to be
+ able to start marking and the job is waiting for the marker.
+ Systems that require human intervention to release jobs using
+ the Release-Job operation, put the job into the 'pending-held'
+ job state. Systems that automatically select a job to use the
+ marker put the job into the 'pending' job state or keep the
+ job in the 'processing' job state while waiting for the marker,
+ depending on implementation. All implementations put the job
+ into (or back into) the 'processing' state when marking does
+ begin.
+ 'job-printing': The output device is marking media. This value is
+ useful for Printers which spend a great deal of time processing
+ (1) when no marking is happening and then want to show that
+ marking is now happening or (2) when the job is in the process
+ of being canceled or aborted while the job remains in the
+ 'processing' state, but the marking has not yet stopped so that
+ impression or sheet counts are still increasing for the job.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 115]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'job-canceled-by-user': The job was canceled by the owner of the
+ job using the Cancel-Job request, i.e., by a user whose
+ authenticated identity is the same as the value of the
+ originating user that created the Job object, or by some other
+ authorized end-user, such as a member of the job owner's
+ security group. This value SHOULD be supported.
+ 'job-canceled-by-operator': The job was canceled by the operator
+ using the Cancel-Job request, i.e., by a user who has been
+ authenticated as having operator privileges (whether local or
+ remote). If the security policy is to allow anyone to cancel
+ anyone's job, then this value may be used when the job is
+ canceled by other than the owner of the job. For such a
+ security policy, in effect, everyone is an operator as far as
+ canceling jobs with IPP is concerned. This value SHOULD be
+ supported if the implementation permits canceling by other than
+ the owner of the job.
+ 'job-canceled-at-device': The job was canceled by an unidentified
+ local user, i.e., a user at a console at the device. This
+ value SHOULD be supported if the implementation supports
+ canceling jobs at the console.
+ 'aborted-by-system': The job (1) is in the process of being
+ aborted, (2) has been aborted by the system and placed in the
+ 'aborted' state, or (3) has been aborted by the system and
+ placed in the 'pending-held' state, so that a user or operator
+ can manually try the job again. This value SHOULD be
+ supported.
+ 'unsupported-compression': The job was aborted by the system
+ because the Printer determined while attempting to decompress
+ the document-data's that the compression is actually not among
+ those supported by the Printer. This value MUST be supported,
+ since "compressions is a REQUIRED operation attribute.
+ 'compression-error': The job was aborted by the system because the
+ Printer encountered an error in the document-data while
+ decompressing it. If the Printer posts this reason, the
+ document-data has already passed any tests that would have led
+ to the 'unsupported-compression' job-state-reason.
+ 'unsupported-document-format': The job was aborted by the system
+ because the document-data's document-format is not among those
+ supported by the Printer. If the client specifies the
+ document-format as 'application/octet-stream', the printer MAY
+ abort the job and post this reason even though the format is a
+ member of the "document-format-supported" printer attribute,
+ but not among the auto-sensed document-formats. This value
+ MUST be supported, since "document-format" is a REQUIRED
+ operation attribute.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 116]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'document-format-error': The job was aborted by the system because
+ the Printer encountered an error in the document-data while
+ processing it. If the Printer posts this reason, the
+ document-data has already passed any tests that would have led
+ to the 'unsupported-document-format' job-state-reason.
+ 'processing-to-stop-point': The requester has issued a Cancel-Job
+ operation or the Printer object has aborted the job, but is
+ still performing some actions on the job until a specified stop
+ point occurs or job termination/cleanup is completed.
+
+ If the implementation requires some measurable time to cancel
+ the job in the 'processing' or 'processing-stopped' job states,
+ the IPP object MUST use this value to indicate that the Printer
+ object is still performing some actions on the job while the
+ job remains in the 'processing' or 'processing-stopped' state.
+ After all the job's job description attributes have stopped
+ incrementing, the Printer object moves the job from the
+ 'processing' state to the 'canceled' or
+ 'aborted' job states.
+
+ 'service-off-line': The Printer is off-line and accepting no
+ jobs. All 'pending' jobs are put into the 'pending-held'
+ state. This situation could be true if the service's or
+ document transform's input is impaired or broken.
+ 'job-completed-successfully': The job completed successfully.
+ This value SHOULD be supported.
+ 'job-completed-with-warnings': The job completed with warnings.
+ This value SHOULD be supported if the implementation detects
+ warnings.
+ 'job-completed-with-errors': The job completed with errors (and
+ possibly warnings too). This value SHOULD be supported if the
+ implementation detects errors.
+ 'job-restartable' - This job is retained (see section 4.3.7.2) and
+ is currently able to be restarted using the Restart-Job
+ operation (see section 3.3.7). If 'job-restartable' is a value
+ of the job's 'job-state-reasons' attribute, then the IPP object
+ MUST accept a Restart-Job operation for that job. This value
+ SHOULD be supported if the Restart-Job operation is supported.
+ 'queued-in-device': The job has been forwarded to a device or
+ print system that is unable to send back status. The Printer
+ sets the job's "job-state " attribute to 'completed' and adds
+ the 'queued-in-device' value to the job's "job-state-reasons"
+ attribute to indicate that the Printer has no additional
+ information about the job and never will have any better
+ information. See section 4.3.7.1.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 117]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.3.9 job-state-message (text(MAX))
+
+ This attribute specifies information about the "job-state" and "job-
+ state-reasons" attributes in human readable text. If the Printer
+ object supports this attribute, the Printer object MUST be able to
+ generate this message in any of the natural languages identified by
+ the Printer's "generated-natural-language-supported" attribute (see
+ the "attributes-natural-language" operation attribute specified in
+ Section 3.1.4.1).
+
+ The value SHOULD NOT contain additional information not contained in
+ the values of the "job-state" and "job-states-reasons" attributes,
+ such as interpreter error information. Otherwise, application
+ programs might attempt to parse the (localized text). For such
+ additional information such as interpreter errors for application
+ program consumption or specific document access errors, new
+ attributes with keyword values, needs to be developed and registered.
+
+4.3.10 job-detailed-status-messages (1setOf text(MAX))
+
+ This attribute specifies additional detailed and technical
+ information about the job. The Printer NEED NOT localize the
+ message(s), since they are intended for use by the system
+ administrator or other experienced technical persons. Localization
+ might obscure the technical meaning of such messages. Clients MUST
+ NOT attempt to parse the value of this attribute. See "job-
+ document-access-errors" (section 4.3.11) for additional errors that a
+ program can process.
+
+4.3.11 job-document-access-errors (1setOf text(MAX))
+
+ This attribute provides additional information about each document
+ access error for this job encountered by the Printer after it
+ returned a response to the Print-URI or Send-URI operation and
+ subsequently attempted to access document(s) supplied in the Print-
+ URI or Send-URI operation. For errors in the protocol that is
+ identified by the URI scheme in the "document-uri" operation
+ attribute, such as 'http:' or 'ftp:', the error code is returned in
+ parentheses, followed by the URI. For example:
+
+ (404) http://ftp.pwg.org/pub/pwg/ipp/new_MOD/ipp-model-v11.pdf
+
+ Most Internet protocols use decimal error codes (unlike IPP), so the
+ ASCII error code representation is in decimal.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 118]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.3.12 number-of-documents (integer(0:MAX))
+
+ This attribute indicates the number of documents in the job, i.e.,
+ the number of Send-Document, Send-URI, Print-Job, or Print-URI
+ operations that the Printer has accepted for this job, regardless of
+ whether the document data has reached the Printer object or not.
+
+ Implementations supporting the OPTIONAL Create-Job/Send-
+ Document/Send-URI operations SHOULD support this attribute so that
+ clients can query the number of documents in each job.
+
+4.3.13 output-device-assigned (name(127))
+
+ This attribute identifies the output device to which the Printer
+ object has assigned this job. If an output device implements an
+ embedded Printer object, the Printer object NEED NOT set this
+ attribute. If a print server implements a Printer object, the value
+ MAY be empty (zero- length string) or not returned until the Printer
+ object assigns an output device to the job. This attribute is
+ particularly useful when a single Printer object supports multiple
+ devices (so called "fan-out" - see section 2.1).
+
+4.3.14 Event Time Job Description Attributes
+
+ This section defines the Job Description attributes that indicate the
+ time at which certain events occur for a job. If the job event has
+ not yet occurred, then the IPP object MUST return the 'no-value'
+ out-of-band value (see the beginning of Section 4.1). The "time-at-
+ xxx(integer)" attributes represent time as an 'integer' representing
+ the number of seconds since the device was powered up (informally
+ called "time ticks"). The "date-time-at-xxx(dateTime)" attributes
+ represent time as 'dateTime' representing date and time (including an
+ offset from UTC).
+
+ In order to populate these attributes, the Printer object copies the
+ value(s) of the following Printer Description attributes at the time
+ the event occurs:
+
+ 1. the value in the Printer's "printer-up-time" attribute for the
+ "time-at-xxx(integer)" attributes
+
+ 2. the value in the Printer's "printer-current-time" attribute for
+ the "date-time-at-xxx(dateTime)" attributes.
+
+ If the Printer resets its "printer-up-time" attribute to 1 on power-
+ up (see section 4.4.29) and has persistent jobs, then it MUST change
+ all of jobs' "time-at-xxx(integer)" (time tick) job attributes whose
+ events have occurred either to:
+
+
+
+Hastings, et al. Standards Track [Page 119]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 1. 0 to indicate that the event happened before the most recent
+ power up OR
+
+ 2. the negative of the number of seconds before the most recent
+ power-up that the event took place, though the negative number
+ NEED NOT reflect the exact number of seconds.
+
+ If a client queries a "time-at-xxx(integer)" time tick Job attribute
+ and finds the value to be 0 or negative, the client MUST assume that
+ the event occurred in some life other than the Printer's current
+ life.
+
+ Note: A Printer does not change the values of any "date-time-at-
+ xxx(dateTime)" job attributes on power-up.
+
+4.3.14.1 time-at-creation (integer(MIN:MAX))
+
+ This REQUIRED attribute indicates the time at which the Job object
+ was created.
+
+4.3.14.2 time-at-processing (integer(MIN:MAX))
+
+ This REQUIRED attribute indicates the time at which the Job object
+ first began processing after the create operation or the most recent
+ Restart-Job operation. The out-of-band 'no-value' value is returned
+ if the job has not yet been in the 'processing' state (see the
+ beginning of Section 4.1).
+
+4.3.14.3 time-at-completed (integer(MIN:MAX))
+
+ This REQUIRED attribute indicates the time at which the Job object
+ completed (or was canceled or aborted). The out-of-band 'no-value'
+ value is returned if the job has not yet completed, been canceled, or
+ aborted (see the beginning of Section 4.1).
+
+4.3.14.4 job-printer-up-time (integer(1:MAX))
+
+ This REQUIRED Job Description attribute indicates the amount of time
+ (in seconds) that the Printer implementation has been up and running.
+ This attribute is an alias for the "printer-up-time" Printer
+ Description attribute (see Section 4.4.29).
+
+ A client MAY request this attribute in a Get-Job-Attributes or Get-
+ Jobs request and use the value returned in combination with other
+ requested Event Time Job Description Attributes in order to display
+ time attributes to a user. The difference between this attribute and
+ the 'integer' value of a "time-at-xxx" attribute is the number of
+
+
+
+
+Hastings, et al. Standards Track [Page 120]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ seconds ago that the "time-at-xxx" event occurred. A client can
+ compute the wall-clock time at which the "time-at-xxx" event occurred
+ by subtracting this difference from the client's wall-clock time.
+
+4.3.14.5 date-time-at-creation (dateTime)
+
+ This attribute indicates the date and time at which the Job object
+ was created.
+
+4.3.14.6 date-time-at-processing (dateTime)
+
+ This attribute indicates the date and time at which the Job object
+ first began processing after the create operation or the most recent
+ Restart-Job operation.
+
+4.3.14.7 date-time-at-completed (dateTime)
+
+ This attribute indicates the date and time at which the Job object
+ completed (or was canceled or aborted).
+
+4.3.15 number-of-intervening-jobs (integer(0:MAX))
+
+ This attribute indicates the number of jobs that are "ahead" of this
+ job in the relative chronological order of expected time to complete
+ (i.e., the current scheduled order). For efficiency, it is only
+ necessary to calculate this value when an operation is performed that
+ requests this attribute.
+
+4.3.16 job-message-from-operator (text(127))
+
+ This attribute provides a message from an operator, system
+ administrator or "intelligent" process to indicate to the end user
+ the reasons for modification or other management action taken on a
+ job.
+
+4.3.17 Job Size Attributes
+
+ This sub-section defines job attributes that describe the size of the
+ job. These attributes are not intended to be counters; they are
+ intended to be useful routing and scheduling information if known.
+ For these attributes, the Printer object may try to compute the value
+ if it is not supplied in the create request. Even if the client does
+ supply a value for these three attributes in the create request, the
+ Printer object MAY choose to change the value if the Printer object
+ is able to compute a value which is more accurate than the client
+ supplied value. The Printer object may be able to determine the
+ correct value for these attributes either right at job submission
+ time or at any later point in time.
+
+
+
+Hastings, et al. Standards Track [Page 121]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.3.17.1 job-k-octets (integer(0:MAX))
+
+ This attribute specifies the total size of the document(s) in K
+ octets, i.e., in units of 1024 octets requested to be processed in
+ the job. The value MUST be rounded up, so that a job between 1 and
+ 1024 octets MUST be indicated as being 1, 1025 to 2048 MUST be 2,
+ etc.
+
+ This value MUST NOT include the multiplicative factors contributed by
+ the number of copies specified by the "copies" attribute, independent
+ of whether the device can process multiple copies without making
+ multiple passes over the job or document data and independent of
+ whether the output is collated or not. Thus the value is independent
+ of the implementation and indicates the size of the document(s)
+ measured in K octets independent of the number of copies.
+
+ This value MUST also not include the multiplicative factor due to a
+ copies instruction embedded in the document data. If the document
+ data actually includes replications of the document data, this value
+ will include such replication. In other words, this value is always
+ the size of the source document data, rather than a measure of the
+ hardcopy output to be produced.
+
+4.3.17.2 job-impressions (integer(0:MAX))
+
+ This attribute specifies the total size in number of impressions of
+ the document(s) being submitted (see the definition of impression in
+ section 12.2.5).
+
+ As with "job-k-octets", this value MUST NOT include the
+ multiplicative factors contributed by the number of copies specified
+ by the "copies" attribute, independent of whether the device can
+ process multiple copies without making multiple passes over the job
+ or document data and independent of whether the output is collated or
+ not. Thus the value is independent of the implementation and
+ reflects the size of the document(s) measured in impressions
+ independent of the number of copies.
+
+ As with "job-k-octets", this value MUST also not include the
+ multiplicative factor due to a copies instruction embedded in the
+ document data. If the document data actually includes replications
+ of the document data, this value will include such replication. In
+ other words, this value is always the number of impressions in the
+ source document data, rather than a measure of the number of
+ impressions to be produced by the job.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 122]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.3.17.3 job-media-sheets (integer(0:MAX))
+
+ This attribute specifies the total number of media sheets to be
+ produced for this job.
+
+ Unlike the "job-k-octets" and the "job-impressions" attributes, this
+ value MUST include the multiplicative factors contributed by the
+ number of copies specified by the "copies" attribute and a 'number of
+ copies' instruction embedded in the document data, if any. This
+ difference allows the system administrator to control the lower and
+ upper bounds of both (1) the size of the document(s) with "job-k-
+ octets-supported" and "job-impressions-supported" and (2) the size of
+ the job with "job-media-sheets-supported".
+
+4.3.18 Job Progress Attributes
+
+ This sub-section defines job attributes that describe the progress of
+ the job. These attributes are intended to be counters. That is, the
+ value for a job that has not started processing MUST be 0. When the
+ job's "job-state" is 'processing' or 'processing-stopped', this value
+ is intended to contain the amount of the job that has been processed
+ to the time at which the attributes are requested. When the job
+ enters the 'completed', 'canceled', or 'aborted' states, these values
+ are the final values for the job.
+
+4.3.18.1 job-k-octets-processed (integer(0:MAX))
+
+ This attribute specifies the total number of octets processed in K
+ octets, i.e., in units of 1024 octets so far. The value MUST be
+ rounded up, so that a job between 1 and 1024 octets inclusive MUST be
+ indicated as being 1, 1025 to 2048 inclusive MUST be 2, etc.
+
+ For implementations where multiple copies are produced by the
+ interpreter with only a single pass over the data, the final value
+ MUST be equal to the value of the "job-k-octets" attribute. For
+ implementations where multiple copies are produced by the interpreter
+ by processing the data for each copy, the final value MUST be a
+ multiple of the value of the "job-k-octets" attribute.
+
+4.3.18.2 job-impressions-completed (integer(0:MAX))
+
+ This job attribute specifies the number of impressions completed for
+ the job so far. For printing devices, the impressions completed
+ includes interpreting, marking, and stacking the output.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 123]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.3.18.3 job-media-sheets-completed (integer(0:MAX))
+
+ This job attribute specifies the media-sheets completed marking and
+ stacking for the entire job so far whether those sheets have been
+ processed on one side or on both.
+
+4.3.19 attributes-charset (charset)
+
+ This REQUIRED attribute is populated using the value in the client
+ supplied "attributes-charset" attribute in the create request. It
+ identifies the charset (coded character set and encoding method) used
+ by any Job attributes with attribute syntax 'text' and 'name' that
+ were supplied by the client in the create request. See Section 3.1.4
+ for a complete description of the "attributes-charset" operation
+ attribute.
+
+ This attribute does not indicate the charset in which the 'text' and
+ 'name' values are stored internally in the Job object. The internal
+ charset is implementation-defined. The IPP object MUST convert from
+ whatever the internal charset is to that being requested in an
+ operation as specified in Section 3.1.4.
+
+4.3.20 attributes-natural-language (naturalLanguage)
+
+ This REQUIRED attribute is populated using the value in the client
+ supplied "attributes-natural-language" attribute in the create
+ request. It identifies the natural language used for any Job
+ attributes with attribute syntax 'text' and 'name' that were supplied
+ by the client in the create request. See Section 3.1.4 for a
+ complete description of the "attributes-natural-language" operation
+ attribute. See Sections 4.1.1.2 and 4.1.2.2 for how a Natural
+ Language Override may be supplied explicitly for each 'text' and
+ 'name' attribute value that differs from the value identified by the
+ "attributes-natural-language" attribute.
+
+4.4 Printer Description Attributes
+
+ These attributes form the attribute group called "printer-
+ description". The following table summarizes these attributes, their
+ syntax, and whether or not they are REQUIRED for a Printer object to
+ support. If they are not indicated as REQUIRED, they are OPTIONAL.
+ The maximum size in octets for 'text' and 'name' attributes is
+ indicated in parenthesizes.
+
+ Note: How these attributes are set by an Administrator is outside the
+ scope of this IPP/1.1 document.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 124]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ +----------------------------+---------------------------+-----------+
+ | Attribute | Syntax | REQUIRED? |
+ +----------------------------+---------------------------+-----------+
+ | printer-uri-supported | 1setOf uri | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | uri-security-supported | 1setOf type2 keyword | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | uri-authentication- | 1setOf type2 keyword | REQUIRED |
+ | supported | | |
+ +----------------------------+---------------------------+-----------+
+ | printer-name | name (127) | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | printer-location | text (127) | |
+ +----------------------------+---------------------------+-----------+
+ | printer-info | text (127) | |
+ +----------------------------+---------------------------+-----------+
+ | printer-more-info | uri | |
+ +----------------------------+---------------------------+-----------+
+ | printer-driver-installer | uri | |
+ +----------------------------+---------------------------+-----------+
+ | printer-make-and-model | text (127) | |
+ +----------------------------+---------------------------+-----------+
+ | printer-more-info- | uri | |
+ | manufacturer | | |
+ +----------------------------+---------------------------+-----------+
+ | printer-state | type1 enum | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | printer-state-reasons | 1setOf type2 keyword | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | printer-state-message | text (MAX) | |
+ +----------------------------+---------------------------+-----------+
+ | ipp-versions-supported | 1setOf type2 keyword | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | operations-supported | 1setOf type2 enum | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | multiple-document-jobs- | boolean | |
+ | supported | | |
+ +----------------------------+---------------------------+-----------+
+ | charset-configured | charset | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | charset-supported | 1setOf charset | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | natural-language-configured| naturalLanguage | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | generated-natural-language-| 1setOf naturalLanguage | REQUIRED |
+ | supported | | |
+ +----------------------------+---------------------------+-----------+
+ | document-format-default | mimeMediaType | REQUIRED |
+
+
+
+Hastings, et al. Standards Track [Page 125]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ +----------------------------+---------------------------+-----------+
+ | document-format-supported | 1setOf mimeMediaType | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | printer-is-accepting-jobs | boolean | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | queued-job-count | integer (0:MAX) | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | printer-message-from- | text (127) | |
+ | operator | | |
+ +----------------------------+---------------------------+-----------+
+ | color-supported | boolean | |
+ +----------------------------+---------------------------+-----------+
+ | reference-uri-schemes- | 1setOf uriScheme | |
+ | supported | | |
+ +----------------------------+---------------------------+-----------+
+ | pdl-override-supported | type2 keyword | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | printer-up-time | integer (1:MAX) | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | printer-current-time | dateTime | |
+ +----------------------------+---------------------------+-----------+
+ | multiple-operation-time-out| integer (1:MAX) | |
+ +----------------------------+---------------------------+-----------+
+ | compression-supported | 1setOf type3 keyword | REQUIRED |
+ +----------------------------+---------------------------+-----------+
+ | job-k-octets-supported | rangeOfInteger (0:MAX) | |
+ +----------------------------+---------------------------+-----------+
+ | job-impressions-supported | rangeOfInteger (0:MAX) | |
+ +----------------------------+---------------------------+-----------+
+ | job-media-sheets-supported | rangeOfInteger (0:MAX) | |
+ +----------------------------+---------------------------+-----------+
+ | pages-per-minute | integer(0:MAX) | |
+ +----------------------------+---------------------------+-----------+
+ | pages-per-minute-color | integer(0:MAX) | |
+ +----------------------------+---------------------------+-----------+
+
+4.4.1 printer-uri-supported (1setOf uri)
+
+ This REQUIRED Printer attribute contains at least one URI for the
+ Printer object. It OPTIONALLY contains more than one URI for the
+ Printer object. An administrator determines a Printer object's
+ URI(s) and configures this attribute to contain those URIs by some
+ means outside the scope of this IPP/1.1 document. The precise format
+ of this URI is implementation dependent and depends on the protocol.
+ See the next two sections for a description of the "uri-security-
+ supported" and "uri-authentication-supported" attributes, both of
+
+
+
+
+
+Hastings, et al. Standards Track [Page 126]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ which are the REQUIRED companion attributes to this "printer-uri-
+ supported" attribute. See section 2.4 on Printer object identity and
+ section 8.2 on security and URIs for more information.
+
+4.4.2 uri-authentication-supported (1setOf type2 keyword)
+
+ This REQUIRED Printer attribute MUST have the same cardinality
+ (contain the same number of values) as the "printer-uri-supported"
+ attribute. This attribute identifies the Client Authentication
+ mechanism associated with each URI listed in the "printer-uri-
+ supported" attribute. The Printer object uses the specified mechanism
+ to identify the authenticated user (see section 8.3). The "i th"
+ value in "uri-authentication-supported" corresponds to the "i th"
+ value in "printer-uri-supported" and it describes the authentication
+ mechanisms used by the Printer when accessed via that URI. See
+ [RFC2910] for more details on Client Authentication.
+
+ The following standard keyword values are defined:
+
+ 'none': There is no authentication mechanism associated with the
+ URI. The Printer object assumes that the authenticated user is
+ "anonymous".
+ 'requesting-user-name': When a client performs an operation whose
+ target is the associated URI, the Printer object assumes that
+ the authenticated user is specified by the "requesting-user-
+ name" Operation attribute (see section 8.3). If the
+ "requesting-user-name" attribute is absent in a request, the
+ Printer object assumes that the authenticated user is
+ "anonymous".
+ 'basic': When a client performs an operation whose target is the
+ associated URI, the Printer object challenges the client with
+ HTTP basic authentication [RFC2617]. The Printer object assumes
+ that the authenticated user is the name received via the basic
+ authentication mechanism.
+ 'digest': When a client performs an operation whose target is the
+ associated URI, the Printer object challenges the client with
+ HTTP digest authentication [RFC2617]. The Printer object
+ assumes that the authenticated user is the name received via
+ the digest authentication mechanism.
+ 'certificate': When a client performs an operation whose target is
+ the associated URI, the Printer object expects the client to
+ provide a certificate. The Printer object assumes that the
+ authenticated user is the textual name contained within the
+ certificate.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 127]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.4.3 uri-security-supported (1setOf type2 keyword)
+
+ This REQUIRED Printer attribute MUST have the same cardinality
+ (contain the same number of values) as the "printer-uri-supported"
+ attribute. This attribute identifies the security mechanisms used
+ for each URI listed in the "printer-uri-supported" attribute. The "i
+ th" value in "uri-security-supported" corresponds to the "i th" value
+ in "printer-uri-supported" and it describes the security mechanisms
+ used for accessing the Printer object via that URI. See [RFC2910]
+ for more details on security mechanisms.
+
+ The following standard keyword values are defined:
+
+ 'none': There are no secure communication channel protocols in use
+ for the given URI.
+ 'ssl3': SSL3 [SSL] is the secure communications channel protocol
+ in use for the given URI.
+ 'tls': TLS [RFC2246] is the secure communications channel
+ protocol in use for the given URI.
+
+ This attribute is orthogonal to the definition of a Client
+ Authentication mechanism. Specifically, 'none' does not exclude
+ Client Authentication. See section 4.4.2.
+
+ Consider the following example. For a single Printer object, an
+ administrator configures the "printer-uri-supported", "uri-
+ authentication-supported" and "uri-security-supported" attributes as
+ follows:
+
+ "printer-uri-supported": 'xxx://acme.com/open-use-printer',
+ 'xxx://acme.com/restricted-use-printer',
+ 'xxx://acme.com/private-printer'
+ "uri-authentication-supported": 'none', 'digest', 'basic'
+ "uri-security-supported": 'none', 'none', 'tls'
+
+ Note: 'xxx' is not a valid scheme. See the IPP/1.1 "Transport and
+ Encoding" document [RFC2910] for the actual URI schemes to be used in
+ object target attributes.
+
+ In this case, one Printer object has three URIs.
+
+ - For the first URI, 'xxx://acme.com/open-use-printer', the value
+ 'none' in "uri-security-supported" indicates that there is no
+ secure channel protocol configured to run under HTTP. The value
+ of 'none' in "uri-authentication-supported" indicates that all
+ users are 'anonymous'. There will be no challenge and the
+ Printer will ignore "requesting-user-name".
+
+
+
+
+Hastings, et al. Standards Track [Page 128]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ - For the second URI, 'xxx://acme.com/restricted-use-printer', the
+ value 'none' in "uri-security-supported" indicates that there is
+ no secure channel protocol configured to run under HTTP. The
+ value of 'digest' in "uri-authentication-supported" indicates
+ that the Printer will issue a challenge and that the Printer
+ will use the name supplied by the digest mechanism to determine
+ the authenticated user (see section 8.3).
+ - For the third URI, 'xxx://acme.com/private-printer', the value
+ 'tls' in "uri-security-supported" indicates that TLS is being
+ used to secure the channel. The client SHOULD be prepared to
+ use TLS framing to negotiate an acceptable ciphersuite to use
+ while communicating with the Printer object. In this case, the
+ name implies the use of a secure communications channel, but the
+ fact is made explicit by the presence of the 'tls' value in
+ "uri-security-supported". The client does not need to resort to
+ understanding which security it must use by following naming
+ conventions or by parsing the URI to determine which security
+ mechanisms are implied. The value of 'basic' in "uri-
+ authentication-supported" indicates that the Printer will issue
+ a challenge and that the Printer will use the name supplied by
+ the digest mechanism to determine the authenticated user (see
+ section 8.3). Because this challenge occurs in a tls session,
+ the channel is secure.
+
+ It is expected that many IPP Printer objects will be configured to
+ support only one channel (either configured to use TLS access or not)
+ and only one authentication mechanism. Such Printer objects only have
+ one URI listed in the "printer-uri-supported" attribute. No matter
+ the configuration of the Printer object (whether it has only one URI
+ or more than one URI), a client MUST supply only one URI in the
+ target "printer-uri" operation attribute.
+
+4.4.4 printer-name (name(127))
+
+ This REQUIRED Printer attribute contains the name of the Printer
+ object. It is a name that is more end-user friendly than a URI. An
+ administrator determines a printer's name and sets this attribute to
+ that name. This name may be the last part of the printer's URI or it
+ may be unrelated. In non-US-English locales, a name may contain
+ characters that are not allowed in a URI.
+
+4.4.5 printer-location (text(127))
+
+ This Printer attribute identifies the location of the device. This
+ could include things like: "in Room 123A, second floor of building
+ XYZ".
+
+
+
+
+
+Hastings, et al. Standards Track [Page 129]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.4.6 printer-info (text(127))
+
+ This Printer attribute identifies the descriptive information about
+ this Printer object. This could include things like: "This printer
+ can be used for printing color transparencies for HR presentations",
+ or "Out of courtesy for others, please print only small (1-5 page)
+ jobs at this printer", or even "This printer is going away on July 1,
+ 1997, please find a new printer".
+
+4.4.7 printer-more-info (uri)
+
+ This Printer attribute contains a URI used to obtain more information
+ about this specific Printer object. For example, this could be an
+ HTTP type URI referencing an HTML page accessible to a Web Browser.
+ The information obtained from this URI is intended for end user
+ consumption. Features outside the scope of IPP can be accessed from
+ this URI. The information is intended to be specific to this printer
+ instance and site specific services (e.g. job pricing, services
+ offered, end user assistance). The device manufacturer may initially
+ populate this attribute.
+
+4.4.8 printer-driver-installer (uri)
+
+ This Printer attribute contains a URI to use to locate the driver
+ installer for this Printer object. This attribute is intended for
+ consumption by automata. The mechanics of print driver installation
+ is outside the scope of this IPP/1.1 document. The device
+ manufacturer may initially populate this attribute.
+
+4.4.9 printer-make-and-model (text(127))
+
+ This Printer attribute identifies the make and model of the device.
+ The device manufacturer may initially populate this attribute.
+
+4.4.10 printer-more-info-manufacturer (uri)
+
+ This Printer attribute contains a URI used to obtain more information
+ about this type of device. The information obtained from this URI is
+ intended for end user consumption. Features outside the scope of IPP
+ can be accessed from this URI (e.g., latest firmware, upgrades, print
+ drivers, optional features available, details on color support). The
+ information is intended to be germane to this printer without regard
+ to site specific modifications or services. The device manufacturer
+ may initially populate this attribute.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 130]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.4.11 printer-state (type1 enum)
+
+ This REQUIRED Printer attribute identifies the current state of the
+ device. The "printer-state reasons" attribute augments the
+ "printer-state" attribute to give more detailed information about the
+ Printer in the given printer state.
+
+ A Printer object need only update this attribute before responding to
+ an operation which requests the attribute; the Printer object NEED
+ NOT update this attribute continually, since asynchronous event
+ notification is not part of IPP/1.1. A Printer NEED NOT implement
+ all values if they are not applicable to a given implementation.
+
+ The following standard enum values are defined:
+
+ Value Symbolic Name and Description
+
+ '3' 'idle': Indicates that new jobs can start processing without
+ waiting.
+ '4' 'processing': Indicates that jobs are processing; new jobs
+ will wait before processing.
+ '5' 'stopped': Indicates that no jobs can be processed and
+ intervention is required.
+
+ Values of "printer-state-reasons", such as 'spool-area-full' and
+ 'stopped-partly', MAY be used to provide further information.
+
+4.4.12 printer-state-reasons (1setOf type2 keyword)
+
+ This REQUIRED Printer attribute supplies additional detail about the
+ device's state. Some of the these value definitions indicate
+ conformance requirements; the rest are OPTIONAL.
+
+ Each keyword value MAY have a suffix to indicate its level of
+ severity. The three levels are: report (least severe), warning, and
+ error (most severe).
+
+ - '-report': This suffix indicates that the reason is a "report".
+ An implementation may choose to omit some or all reports. Some
+ reports specify finer granularity about the printer state;
+ others serve as a precursor to a warning. A report MUST contain
+ nothing that could affect the printed output.
+ - '-warning': This suffix indicates that the reason is a
+ "warning". An implementation may choose to omit some or all
+ warnings. Warnings serve as a precursor to an error. A warning
+ MUST contain nothing that prevents a job from completing, though
+ in some cases the output may be of lower quality.
+
+
+
+
+Hastings, et al. Standards Track [Page 131]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ - '-error': This suffix indicates that the reason is an "error".
+ An implementation MUST include all errors. If this attribute
+ contains one or more errors, printer MUST be in the stopped
+ state.
+
+ If the implementation does not add any one of the three suffixes, all
+ parties MUST assume that the reason is an "error".
+
+ If a Printer object controls more than one output device, each value
+ of this attribute MAY apply to one or more of the output devices. An
+ error on one output device that does not stop the Printer object as a
+ whole MAY appear as a warning in the Printer's "printer-state-reasons
+ attribute". If the "printer-state" for such a Printer has a value of
+ 'stopped', then there MUST be an error reason among the values in the
+ "printer-state-reasons" attribute.
+
+ The following standard keyword values are defined:
+
+ 'other': The device has detected an error other than one listed in
+ this document.
+ 'none': There are not reasons. This state reason is semantically
+ equivalent to "printer-state-reasons" without any value and
+ MUST be used, since the 1setOf attribute syntax requires at
+ least one value.
+ 'media-needed': A tray has run out of media.
+ 'media-jam': The device has a media jam.
+ 'moving-to-paused': Someone has paused the Printer object using
+ the Pause-Printer operation (see section 3.2.7) or other means,
+ but the device(s) are taking an appreciable time to stop.
+ Later, when all output has stopped, the "printer-state" becomes
+ 'stopped', and the 'paused' value replaces the 'moving-to-
+ paused' value in the "printer-state-reasons" attribute. This
+ value MUST be supported, if the Pause-Printer operation is
+ supported and the implementation takes significant time to
+ pause a device in certain circumstances.
+ 'paused': Someone has paused the Printer object using the Pause-
+ Printer operation (see section 3.2.7) or other means and the
+ Printer object's "printer-state" is 'stopped'. In this state,
+ a Printer MUST NOT produce printed output, but it MUST perform
+ other operations requested by a client. If a Printer had been
+ printing a job when the Printer was paused, the Printer MUST
+ resume printing that job when the Printer is no longer paused
+ and leave no evidence in the printed output of such a pause.
+ This value MUST be supported, if the Pause-Printer operation is
+ supported.
+ 'shutdown': Someone has removed a Printer object from service, and
+ the device may be powered down or physically removed. In this
+ state, a Printer object MUST NOT produce printed output, and
+
+
+
+Hastings, et al. Standards Track [Page 132]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ unless the Printer object is realized by a print server that is
+ still active, the Printer object MUST perform no other
+ operations requested by a client, including returning this
+ value. If a Printer object had been printing a job when it was
+ shutdown, the Printer NEED NOT resume printing that job when
+ the Printer is no longer shutdown. If the Printer resumes
+ printing such a job, it may leave evidence in the printed
+ output of such a shutdown, e.g. the part printed before the
+ shutdown may be printed a second time after the shutdown.
+ 'connecting-to-device': The Printer object has scheduled a job on
+ the output device and is in the process of connecting to a
+ shared network output device (and might not be able to actually
+ start printing the job for an arbitrarily long time depending
+ on the usage of the output device by other servers on the
+ network).
+ 'timed-out': The server was able to connect to the output device
+ (or is always connected), but was unable to get a response from
+ the output device.
+ 'stopping': The Printer object is in the process of stopping the
+ device and will be stopped in a while. When the device is
+ stopped, the Printer object will change the Printer object's
+ state to 'stopped'. The 'stopping-warning' reason is never an
+ error, even for a Printer with a single output device. When an
+ output-device ceases accepting jobs, the Printer will have this
+ reason while the output device completes printing.
+ 'stopped-partly': When a Printer object controls more than one
+ output device, this reason indicates that one or more output
+ devices are stopped. If the reason is a report, fewer than
+ half of the output devices are stopped. If the reason is a
+ warning, fewer than all of the output devices are stopped.
+ 'toner-low': The device is low on toner.
+ 'toner-empty': The device is out of toner.
+ 'spool-area-full': The limit of persistent storage allocated for
+ spooling has been reached. The Printer is temporarily unable
+ to accept more jobs. The Printer will remove this value when
+ it is able to accept more jobs. This value SHOULD be used by a
+ non-spooling Printer that only accepts one or a small number
+ jobs at a time or a spooling Printer that has filled the spool
+ space.
+ 'cover-open': One or more covers on the device are open.
+ 'interlock-open': One or more interlock devices on the printer are
+ unlocked.
+ 'door-open': One or more doors on the device are open.
+ 'input-tray-missing': One or more input trays are not in the
+ device.
+ 'media-low': At least one input tray is low on media.
+ 'media-empty': At least one input tray is empty.
+
+
+
+
+Hastings, et al. Standards Track [Page 133]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'output-tray-missing': One or more output trays are not in the
+ device
+ 'output-area-almost-full': One or more output area is almost full
+ (e.g. tray, stacker, collator).
+ 'output-area-full': One or more output area is full. (e.g. tray,
+ stacker, collator)
+ 'marker-supply-low': The device is low on at least one marker
+ supply. (e.g. toner, ink, ribbon)
+ 'marker-supply-empty: The device is out of at least one marker
+ supply. (e.g. toner, ink, ribbon)
+ 'marker-waste-almost-full': The device marker supply waste
+ receptacle is almost full.
+ 'marker-waste-full': The device marker supply waste receptacle is
+ full.
+ 'fuser-over-temp': The fuser temperature is above normal.
+ 'fuser-under-temp': The fuser temperature is below normal.
+ 'opc-near-eol': The optical photo conductor is near end of life.
+ 'opc-life-over': The optical photo conductor is no longer
+ functioning.
+ 'developer-low': The device is low on developer.
+ 'developer-empty: The device is out of developer.
+ 'interpreter-resource-unavailable': An interpreter resource is
+ unavailable (i.e. font, form)
+
+4.4.13 printer-state-message (text(MAX))
+
+ This Printer attribute specifies information about the "printer-
+ state" and "printer-state-reasons" attributes in human readable text.
+ If the Printer object supports this attribute, the Printer object
+ MUST be able to generate this message in any of the natural languages
+ identified by the Printer's "generated-natural-language-supported"
+ attribute (see the "attributes-natural-language" operation attribute
+ specified in Section 3.1.4.1).
+
+4.4.14 ipp-versions-supported (1setOf type2 keyword)
+
+ This REQUIRED attribute identifies the IPP protocol version(s) that
+ this Printer supports, including major and minor versions, i.e., the
+ version numbers for which this Printer implementation meets the
+ conformance requirements. For version number validation, the Printer
+ matches the (two-octet binary) "version-number" parameter supplied by
+ the client in each request (see sections 3.1.1 and 3.1.8) with the
+ (US-ASCII) keyword values of this attribute.
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 134]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The following standard keyword values are defined:
+
+ '1.0': Meets the conformance requirement of IPP version 1.0 as
+ specified in RFC 2566 [RFC2566] and RFC 2565 [RFC2565]
+ including any extensions registered according to Section 6 and
+ any extension defined in this version or any future version of
+ the IPP "Model and Semantics" document or the IPP "Encoding and
+ Transport" document following the rules, if any, when the
+ "version-number" parameter is '1.0'.
+ '1.1': Meets the conformance requirement of IPP version 1.1 as
+ specified in this document and [RFC2910] including any
+ extensions registered according to Section 6 and any extension
+ defined in any future versions of the IPP "Model and Semantics"
+ document or the IPP Encoding and Transport document following
+ the rules, if any, when the "version-number" parameter is
+ '1.1'.
+
+4.4.15 operations-supported (1setOf type2 enum)
+
+ This REQUIRED Printer attribute specifies the set of supported
+ operations for this Printer object and contained Job objects.
+
+ This attribute is encoded as any other enum attribute syntax
+ according to [RFC2910] as 32-bits. However, all 32-bit enum values
+ for this attribute MUST NOT exceed 0x00008FFF, since these same
+ values are also passed in two octets in the "operation-id" parameter
+ (see section 3.1.1) in each Protocol request with the two high order
+ octets omitted in order to indicate the operation being performed
+ [RFC2910].
+
+ The following standard enum and "operation-id" (see section 3.1.2)
+ values are defined:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 135]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Value Operation Name
+ ----------------- -------------------------------------
+
+ 0x0000 reserved, not used
+ 0x0001 reserved, not used
+ 0x0002 Print-Job
+ 0x0003 Print-URI
+ 0x0004 Validate-Job
+ 0x0005 Create-Job
+ 0x0006 Send-Document
+ 0x0007 Send-URI
+ 0x0008 Cancel-Job
+ 0x0009 Get-Job-Attributes
+ 0x000A Get-Jobs
+ 0x000B Get-Printer-Attributes
+ 0x000C Hold-Job
+ 0x000D Release-Job
+ 0x000E Restart-Job
+ 0x000F reserved for a future operation
+ 0x0010 Pause-Printer
+ 0x0011 Resume-Printer
+ 0x0012 Purge-Jobs
+ 0x0013-0x3FFF reserved for future IETF standards track
+ operations (see section 6.4)
+ 0x4000-0x8FFF reserved for vendor extensions (see section 6.4)
+
+4.4.16 multiple-document-jobs-supported (boolean)
+
+ This Printer attribute indicates whether or not the Printer supports
+ more than one document per job, i.e., more than one Send-Document or
+ Send-Data operation with document data. If the Printer supports the
+ Create-Job and Send-Document operations (see section 3.2.4 and
+ 3.3.1), it MUST support this attribute.
+
+4.4.17 charset-configured (charset)
+
+ This REQUIRED Printer attribute identifies the charset that the
+ Printer object has been configured to represent 'text' and 'name'
+ Printer attributes that are set by the operator, system
+ administrator, or manufacturer, i.e., for "printer-name" (name),
+ "printer-location" (text), "printer-info" (text), and "printer-make-
+ and-model" (text). Therefore, the value of the Printer object's
+ "charset-configured" attribute MUST also be among the values of the
+ Printer object's "charset-supported" attribute.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 136]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.4.18 charset-supported (1setOf charset)
+
+ This REQUIRED Printer attribute identifies the set of charsets that
+ the Printer and contained Job objects support in attributes with
+ attribute syntax 'text' and 'name'. At least the value 'utf-8' MUST
+ be present, since IPP objects MUST support the UTF-8 [RFC2279]
+ charset. If a Printer object supports a charset, it means that for
+ all attributes of syntax 'text' and 'name' the IPP object MUST (1)
+ accept the charset in requests and return the charset in responses as
+ needed.
+
+ If more charsets than UTF-8 are supported, the IPP object MUST
+ perform charset conversion between the charsets as described in
+ Section 3.1.4.2.
+
+4.4.19 natural-language-configured (naturalLanguage)
+
+ This REQUIRED Printer attribute identifies the natural language that
+ the Printer object has been configured to represent 'text' and 'name'
+ Printer attributes that are set by the operator, system
+ administrator, or manufacturer, i.e., for "printer-name" (name),
+ "printer-location" (text), "printer-info" (text), and "printer-make-
+ and-model" (text). When returning these Printer attributes, the
+ Printer object MAY return them in the configured natural language
+ specified by this attribute, instead of the natural language
+ requested by the client in the "attributes-natural-language"
+ operation attribute. See Section 3.1.4.1 for the specification of
+ the OPTIONAL multiple natural language support. Therefore, the value
+ of the Printer object's "natural-language-configured" attribute MUST
+ also be among the values of the Printer object's "generated-natural-
+ language-supported" attribute.
+
+4.4.20 generated-natural-language-supported (1setOf naturalLanguage)
+
+ This REQUIRED Printer attribute identifies the natural language(s)
+ that the Printer object and contained Job objects support in
+ attributes with attribute syntax 'text' and 'name'. The natural
+ language(s) supported depends on implementation and/or configuration.
+ Unlike charsets, IPP objects MUST accept requests with any natural
+ language or any Natural Language Override whether the natural
+ language is supported or not.
+
+ If a Printer object supports a natural language, it means that for
+ any of the attributes for which the Printer or Job object generates
+ messages, i.e., for the "job-state-message" and "printer-state-
+ message" attributes and Operation Messages (see Section 3.1.5) in
+ operation responses, the Printer and Job objects MUST be able to
+
+
+
+
+Hastings, et al. Standards Track [Page 137]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ generate messages in any of the Printer's supported natural
+ languages. See section 3.1.4 for the definition of 'text' and 'name'
+ attributes in operation requests and responses.
+
+ Note: A Printer object that supports multiple natural languages,
+ often has separate catalogs of messages, one for each natural
+ language supported.
+
+4.4.21 document-format-default (mimeMediaType)
+
+ This REQUIRED Printer attribute identifies the document format that
+ the Printer object has been configured to assume if the client does
+ not supply a "document-format" operation attribute in any of the
+ operation requests that supply document data. The standard values
+ for this attribute are Internet Media types (sometimes called MIME
+ types). For further details see the description of the
+ 'mimeMediaType' attribute syntax in Section 4.1.9.
+
+4.4.22 document-format-supported (1setOf mimeMediaType)
+
+ This REQUIRED Printer attribute identifies the set of document
+ formats that the Printer object and contained Job objects can
+ support. For further details see the description of the
+ 'mimeMediaType' attribute syntax in Section 4.1.9.
+
+4.4.23 printer-is-accepting-jobs (boolean)
+
+ This REQUIRED Printer attribute indicates whether the printer is
+ currently able to accept jobs, i.e., is accepting Print-Job, Print-
+ URI, and Create-Job requests. If the value is 'true', the printer is
+ accepting jobs. If the value is 'false', the Printer object is
+ currently rejecting any jobs submitted to it. In this case, the
+ Printer object returns the 'server-error-not-accepting-jobs' status
+ code.
+
+ This value is independent of the "printer-state" and "printer-state-
+ reasons" attributes because its value does not affect the current
+ job; rather it affects future jobs. This attribute, when 'false',
+ causes the Printer to reject jobs even when the "printer-state" is
+ 'idle' or, when 'true', causes the Printer object to accepts jobs
+ even when the "printer-state" is 'stopped'.
+
+4.4.24 queued-job-count (integer(0:MAX))
+
+ This REQUIRED Printer attribute contains a count of the number of
+ jobs that are either 'pending', 'processing', 'pending-held', or
+ 'processing-stopped' and is set by the Printer object.
+
+
+
+
+Hastings, et al. Standards Track [Page 138]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+4.4.25 printer-message-from-operator (text(127))
+
+ This Printer attribute provides a message from an operator, system
+ administrator or "intelligent" process to indicate to the end user
+ information or status of the printer, such as why it is unavailable
+ or when it is expected to be available.
+
+4.4.26 color-supported (boolean)
+
+ This Printer attribute identifies whether the device is capable of
+ any type of color printing at all, including highlight color. All
+ document instructions having to do with color are embedded within the
+ document PDL (none are external IPP attributes in IPP/1.1).
+
+ Note: end-users are able to determine the nature and details of the
+ color support by querying the "printer-more-info-manufacturer"
+ Printer attribute.
+
+4.4.27 reference-uri-schemes-supported (1setOf uriScheme)
+
+ This Printer attribute specifies which URI schemes are supported for
+ use in the "document-uri" operation attribute of the Print-URI or
+ Send-URI operation. If a Printer object supports these optional
+ operations, it MUST support the "reference-uri-schemes-supported"
+ Printer attribute with at least the following schemed URI value:
+
+ 'ftp': The Printer object will use an FTP 'get' operation as
+ defined in RFC 2228 [RFC2228] using FTP URLs as defined by
+ [RFC2396] and [RFC2316].
+
+ The Printer object MAY OPTIONALLY support other URI schemes (see
+ section 4.1.6).
+
+4.4.28 pdl-override-supported (type2 keyword)
+
+ This REQUIRED Printer attribute expresses the ability for a
+ particular Printer implementation to either attempt to override
+ document data instructions with IPP attributes or not.
+
+ This attribute takes on the following keyword values:
+
+ - 'attempted': This value indicates that the Printer object
+ attempts to make the IPP attribute values take precedence over
+ embedded instructions in the document data, however there is no
+ guarantee.
+ - 'not-attempted': This value indicates that the Printer object
+ makes no attempt to make the IPP attribute values take
+ precedence over embedded instructions in the document data.
+
+
+
+Hastings, et al. Standards Track [Page 139]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Section 15 contains a full description of how this attribute
+ interacts with and affects other IPP attributes, especially the
+ "ipp-attribute-fidelity" attribute.
+
+4.4.29 printer-up-time (integer(1:MAX))
+
+ This REQUIRED Printer attribute indicates the amount of time (in
+ seconds) that this Printer instance has been up and running. The
+ value is a monotonically increasing value starting from 1 when the
+ Printer object is started-up (initialized, booted, etc.). This value
+ is used to populate the Event Time Job Description Job attributes
+ "time-at-creation", "time-at-processing", and "time-at-completed"
+ (see section 4.3.14).
+
+ If the Printer object goes down at some value 'n', and comes back up,
+ the implementation MAY:
+
+ 1. Know how long it has been down, and resume at some value
+ greater than 'n', or
+ 2. Restart from 1.
+
+ In other words, if the device or devices that the Printer object is
+ representing are restarted or power cycled, the Printer object MAY
+ continue counting this value or MAY reset this value to 1 depending
+ on implementation. However, if the Printer object software ceases
+ running, and restarts without knowing the last value for "printer-
+ up-time", the implementation MUST reset this value to 1. If this
+ value is reset and the Printer has persistent jobs, the Printer MUST
+ reset the "time-at-xxx(integer) Event Time Job Description attributes
+ according to Section 4.3.14. An implementation MAY use both
+ implementation alternatives, depending on warm versus cold start,
+ respectively.
+
+4.4.30 printer-current-time (dateTime)
+
+ This Printer attribute indicates the current date and time. This
+ value is used to populate the Event Time Job Description attributes:
+ "date-time-at-creation", "date-time-at-processing", and "date-time-
+ at-completed" (see Section 4.3.14).
+
+ The date and time is obtained on a "best efforts basis" and does not
+ have to be that precise in order to work in practice. A Printer
+ implementation sets the value of this attribute by obtaining the date
+ and time via some implementation-dependent means, such as getting the
+ value from a network time server, initialization at time of
+ manufacture, or setting by an administrator. See [IPP-IIG] for
+ examples. If an implementation supports this attribute and the
+ implementation knows that it has not yet been set, then the
+
+
+
+Hastings, et al. Standards Track [Page 140]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ implementation MUST return the value of this attribute using the
+ out-of-band 'no-value' meaning not configured. See the beginning of
+ section 4.1.
+
+ The time zone of this attribute NEED NOT be the time zone used by
+ people located near the Printer object or device. The client MUST
+ NOT expect that the time zone of any received 'dateTime' value to be
+ in the time zone of the client or in the time zone of the people
+ located near the printer.
+
+ The client SHOULD display any dateTime attributes to the user in
+ client local time by converting the 'dateTime' value returned by the
+ server to the time zone of the client, rather than using the time
+ zone returned by the Printer in attributes that use the 'dateTime'
+ attribute syntax.
+
+4.4.31 multiple-operation-time-out (integer(1:MAX))
+
+ This Printer attributes identifies the minimum time (in seconds) that
+ the Printer object waits for additional Send-Document or Send-URI
+ operations to follow a still-open Job object before taking any
+ recovery actions, such as the ones indicated in section 3.3.1. If
+ the Printer object supports the Create-Job and Send-Document
+ operations (see section 3.2.4 and 3.3.1), it MUST support this
+ attribute.
+
+ It is RECOMMENDED that vendors supply a value for this attribute that
+ is between 60 and 240 seconds. An implementation MAY allow a system
+ administrator to set this attribute (by means outside this IPP/1.1
+ document). If so, the system administrator MAY be able to set values
+ outside this range.
+
+4.4.32 compression-supported (1setOf type3 keyword)
+
+ This REQUIRED Printer attribute identifies the set of supported
+ compression algorithms for document data. Compression only applies
+ to the document data; compression does not apply to the encoding of
+ the IPP operation itself. The supported values are used to validate
+ the client supplied "compression" operation attributes in Print-Job,
+ Send-Document, and Send-URI requests.
+
+ Standard keyword values are :
+
+ 'none': no compression is used.
+ 'deflate': ZIP public domain inflate/deflate) compression technology
+ in RFC 1951 [RFC1951]
+ 'gzip' GNU zip compression technology described in RFC 1952
+ [RFC1952].
+
+
+
+Hastings, et al. Standards Track [Page 141]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'compress': UNIX compression technology in RFC 1977 [RFC1977]
+
+4.4.33 job-k-octets-supported (rangeOfInteger(0:MAX))
+
+ This Printer attribute specifies the upper and lower bounds of total
+ sizes of jobs in K octets, i.e., in units of 1024 octets. The
+ supported values are used to validate the client supplied "job-k-
+ octets" operation attributes in create requests. The corresponding
+ job description attribute "job-k-octets" is defined in section
+ 4.3.17.1.
+
+4.4.34 job-impressions-supported (rangeOfInteger(0:MAX))
+
+ This Printer attribute specifies the upper and lower bounds for the
+ number of impressions per job. The supported values are used to
+ validate the client supplied "job-impressions" operation attributes
+ in create requests. The corresponding job description attribute
+ "job-impressions" is defined in section 4.3.17.2.
+
+4.4.35 job-media-sheets-supported (rangeOfInteger(0:MAX))
+
+ This Printer attribute specifies the upper and lower bounds for the
+ number of media sheets per job. The supported values are used to
+ validate the client supplied "job-media-sheets" operation attributes
+ in create requests. The corresponding Job attribute "job-media-
+ sheets" is defined in section 4.3.17.3.
+
+4.4.36 pages-per-minute (integer(0:MAX))
+
+ This Printer attributes specifies the nominal number of pages per
+ minute to the nearest whole number which may be generated by this
+ printer (e.g., simplex, black-and-white). This attribute is
+ informative, not a service guarantee. Generally, it is the value
+ used in the marketing literature to describe the device.
+
+ A value of 0 indicates a device that takes more than two minutes to
+ process a page.
+
+4.4.37 pages-per-minute-color (integer(0:MAX))
+
+ This Printer attributes specifies the nominal number of pages per
+ minute to the nearest whole number which may be generated by this
+ printer when printing color (e.g., simplex, color). For purposes of
+ this attribute, "color" means the same as for the "color-supported"
+ attribute, namely, the device is capable of any type of color
+ printing at all, including highlight color. This attribute is
+
+
+
+
+
+Hastings, et al. Standards Track [Page 142]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ informative, not a service guarantee. Generally, it is the value
+ used in the marketing literature to describe the color capabilities
+ of this device.
+
+ A value of 0 indicates a device that takes more than two minutes to
+ process a page.
+
+ If a color device has several color modes, it MAY use the pages-per-
+ minute value for this attribute that corresponds to the mode that
+ produces the highest number.
+
+ Black and white only printers MUST NOT support this attribute. If
+ this attribute is present, then the "color-supported" Printer
+ description attribute MUST be present and have a 'true' value.
+
+ The values of these two attributes returned by the Get-Printer-
+ Attributes operation MAY be affected by the "document-format"
+ attribute supplied by the client in the Get-Printer-Attributes
+ request. In other words, the implementation MAY have different
+ speeds depending on the document format being processed. See section
+ 3.2.5.1 Get-Printer-Attributes.
+
+5. Conformance
+
+ This section describes conformance issues and requirements. This
+ document introduces model entities such as objects, operations,
+ attributes, attribute syntaxes, and attribute values. These
+ conformance sections describe the conformance requirements which
+ apply to these model entities.
+
+5.1 Client Conformance Requirements
+
+ This section describes the conformance requirements for a client (see
+ section 2.1), whether it be:
+
+ 1. contained within software controlled by an end user, e.g.
+ activated by the "Print" menu item in an application that sends
+ IPP requests or
+
+ 2. the print server component that sends IPP requests to either an
+ output device or another "downstream" print server.
+
+ A conforming client MUST support all REQUIRED operations as defined
+ in this document. For each attribute included in an operation
+ request, a conforming client MUST supply a value whose type and value
+ syntax conforms to the requirements of the Model document as
+ specified in Sections 3 and 4. A conforming client MAY supply any
+
+
+
+
+Hastings, et al. Standards Track [Page 143]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ IETF standards track extensions and/or vendor extensions in an
+ operation request, as long as the extensions meet the requirements in
+ Section 6.
+
+ Otherwise, there are no conformance requirements placed on the user
+ interfaces provided by IPP clients or their applications. For
+ example, one application might not allow an end user to submit
+ multiple documents per job, while another does. One application
+ might first query a Printer object in order to supply a graphical
+ user interface (GUI) dialogue box with supported and default values
+ whereas a different implementation might not.
+
+ When sending a request, an IPP client NEED NOT supply any attributes
+ that are indicated as OPTIONALLY supplied by the client.
+
+ A client MUST be able to accept any of the attribute syntaxes defined
+ in Section 4.1, including their full range, that may be returned to
+ it in a response from a Printer object. In particular for each
+ attribute that the client supports whose attribute syntax is 'text',
+ the client MUST accept and process both the 'textWithoutLanguage' and
+ 'textWithLanguage' forms. Similarly, for each attribute that the
+ client supports whose attribute syntax is 'name', the client MUST
+ accept and process both the 'nameWithoutLanguage' and
+ 'nameWithLanguage' forms. For presentation purposes, truncation of
+ long attribute values is not recommended. A recommended approach
+ would be for the client implementation to allow the user to scroll
+ through long attribute values.
+
+ A response MAY contain attribute groups, attributes, attribute
+ syntaxes, values, and status codes that the client does not expect.
+ Therefore, a client implementation MUST gracefully handle such
+ responses and not refuse to inter-operate with a conforming Printer
+ that is returning IETF standards track extension or vendor
+ extensions, including attribute groups, attributes, attribute
+ syntaxes, attribute values, status codes, and out-of-band attribute
+ values that conform to Section 6. Clients may choose to ignore any
+ parameters, attribute groups, attributes, attribute syntaxes, or
+ values that they do not understand.
+
+ While a client is sending data to a printer, it SHOULD do its best to
+ prevent a channel from being closed by a lower layer when the channel
+ is blocked (i.e. flow-controlled off) for whatever reason, e.g. 'out
+ of paper' or 'job ahead hasn't freed up enough memory'. However, the
+ layer that launched the print submission (e.g. an end user) MAY close
+ the channel in order to cancel the job. When a client closes a
+ channel, a Printer MAY print all or part of the received portion of
+ the document. See the "Encoding and Transport" document [RFC2910]
+ for more details.
+
+
+
+Hastings, et al. Standards Track [Page 144]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ A client MUST support Client Authentication as defined in the IPP/1.1
+ Encoding and Transport document [RFC2910]. A client SHOULD support
+ Operation Privacy and Server Authentication as defined in the IPP/1.1
+ Encoding and Transport document [RFC2910]. See also section 8 of
+ this document.
+
+5.2 IPP Object Conformance Requirements
+
+ This section specifies the conformance requirements for conforming
+ implementations of IPP objects (see section 2). These requirements
+ apply to an IPP object whether it is:
+
+ (1) an (embedded) device component that accepts IPP requests and
+ controls the device or
+
+ (2) a component of a print server that accepts IPP requests (where
+ the print server control one or more networked devices using IPP or
+ other protocols).
+
+5.2.1 Objects
+
+ Conforming implementations MUST implement all of the model objects as
+ defined in this document in the indicated sections:
+
+ Section 2.1 - Printer Object
+ Section 2.2 - Job Object
+
+5.2.2 Operations
+
+ Conforming IPP object implementations MUST implement all of the
+ REQUIRED model operations, including REQUIRED responses, as defined
+ in this document in the indicated sections:
+
+ For a Printer object:
+ Print-Job (section 3.2.1) REQUIRED
+ Print-URI (section 3.2.2) OPTIONAL
+ Validate-Job (section 3.2.3) REQUIRED
+ Create-Job (section 3.2.4) OPTIONAL
+ Get-Printer-Attributes (section 3.2.5) REQUIRED
+ Get-Jobs (section 3.2.6) REQUIRED
+ Pause-Printer (section 3.2.7) OPTIONAL
+ Resume-Printer (section 3.2.8) OPTIONAL
+ Purge-Jobs (section 3.2.9) OPTIONAL
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 145]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ For a Job object:
+ Send-Document (section 3.3.1) OPTIONAL
+ Send-URI (section 3.3.2) OPTIONAL
+ Cancel-Job (section 3.3.3) REQUIRED
+ Get-Job-Attributes (section 3.3.4) REQUIRED
+ Hold-Job (section 3.3.5) OPTIONAL
+ Release-Job (section 3.3.6) OPTIONAL
+ Restart-Job (section 3.3.7) OPTIONAL
+
+ Conforming IPP objects MUST support all REQUIRED operation attributes
+ and all values of such attributes if so indicated in the description.
+ Conforming IPP objects MUST ignore all unsupported or unknown
+ operation attributes or operation attribute groups received in a
+ request, but MUST reject a request that contains a supported
+ operation attribute that contains an unsupported value.
+
+ Conforming IPP objects MAY return operation responses that contain
+ attributes groups, attributes names, attribute syntaxes, attribute
+ values, and status codes that are extensions to this standard. The
+ additional attribute groups MAY occur in any order.
+
+ The following section on object attributes specifies the support
+ required for object attributes.
+
+5.2.3 IPP Object Attributes
+
+ Conforming IPP objects MUST support all of the REQUIRED object
+ attributes, as defined in this document in the indicated sections.
+
+ If an object supports an attribute, it MUST support only those values
+ specified in this document or through the extension mechanism
+ described in section 5.2.4. It MAY support any non-empty subset of
+ these values. That is, it MUST support at least one of the specified
+ values and at most all of them.
+
+5.2.4 Versions
+
+ IPP/1.1 clients MUST meet the conformance requirements for clients
+ specified in this document and [RFC2910]. IPP/1.1 clients MUST send
+ requests containing a "version-number" parameter with a '1.1' value.
+
+ IPP/1.1 Printer and Job objects MUST meet the conformance
+ requirements for IPP objects specified in this document and
+ [RFC2910]. IPP/1.1 objects MUST accept requests containing a
+ "version-number" parameter with a '1.1' value (or reject the request
+ if the operation is not supported).
+
+
+
+
+
+Hastings, et al. Standards Track [Page 146]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ It is beyond the scope of this specification to mandate conformance
+ with previous versions. IPP/1.1 was deliberately designed, however,
+ to make supporting previous versions easy. It is worth noting that,
+ at the time of composing this specification (1999), we would expect
+ IPP/1.1 Printer implementations to:
+
+ understand any valid request in the format of IPP/1.0, or 1.1;
+
+ respond appropriately with a response containing the same
+ "version-number" parameter value used by the client in the request.
+
+ And we would expect IPP/1.1 clients to:
+
+ understand any valid response in the format of IPP/1.0, or 1.1.
+
+ It is recommended that IPP/1.1 clients try supplying alternate
+ version numbers if they receive a 'server-error-version-not-
+ supported' error return in a response.
+
+5.2.5 Extensions
+
+ A conforming IPP object MAY support IETF standards track extensions
+ and vendor extensions, as long as the extensions meet the
+ requirements specified in Section 6.
+
+ For each attribute included in an operation response, a conforming
+ IPP object MUST return a value whose type and value syntax conforms
+ to the requirement of the Model document as specified in Sections 3
+ and 4.
+
+5.2.6 Attribute Syntaxes
+
+ An IPP object MUST be able to accept any of the attribute syntaxes
+ defined in Section 4.1, including their full range, in any operation
+ in which a client may supply attributes or the system administrator
+ may configure attributes (by means outside the scope of this IPP/1.1
+ document). In particular for each attribute that the IPP object
+ supports whose attribute syntax is 'text', the IPP object MUST accept
+ and process both the 'textWithoutLanguage' and 'textWithLanguage'
+ forms. Similarly, for each attribute that the IPP object supports
+ whose attribute syntax is 'name', the IPP object MUST accept and
+ process both the 'nameWithoutLanguage' and 'nameWithLanguage' forms.
+ Furthermore, an IPP object MUST return attributes to the client in
+ operation responses that conform to the syntax specified in Section
+ 4.1, including their full range if supplied previously by a client.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 147]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+5.2.7 Security
+
+ An IPP Printer implementation SHOULD contain support for Client
+ Authentication as defined in the IPP/1.1 Encoding and Transport
+ document [RFC2910]. A Printer implementation MAY allow an
+ administrator to configure the Printer so that all, some, or none of
+ the users are authenticated. See also section 8 of this document.
+
+ An IPP Printer implementation SHOULD contain support for Operation
+ Privacy and Server Authentication as defined in the IPP/1.1 Encoding
+ and Transport document [RFC2910]. A Printer implementation MAY allow
+ an administrator to configure the degree of support for Operation
+ Privacy and Server Authentication. See also section 8 of this
+ document.
+
+ Security MUST NOT be compromised when a client supplies a lower
+ "version-number" parameter in a request. For example, if an IPP/1.1
+ conforming Printer object accepts version '1.0' requests and is
+ configured to enforce Digest Authentication, it MUST do the same for
+ a version '1.0' request.
+
+5.3 Charset and Natural Language Requirements
+
+ All clients and IPP objects MUST support the 'utf-8' charset as
+ defined in section 4.1.7.
+
+ IPP objects MUST be able to accept any client request which correctly
+ uses the "attributes-natural-language" operation attribute or the
+ Natural Language Override mechanism on any individual attribute
+ whether or not the natural language is supported by the IPP object.
+ If an IPP object supports a natural language, then it MUST be able to
+ translate (perhaps by table lookup) all generated 'text' or 'name'
+ attribute values into one of the supported languages (see section
+ 3.1.4). That is, the IPP object that supports a natural language
+ NEED NOT be a general purpose translator of any arbitrary 'text' or
+ 'name' value supplied by the client into that natural language.
+ However, the object MUST be able to translate (automatically
+ generate) any of its own attribute values and messages into that
+ natural language.
+
+6. IANA Considerations
+
+ This section describes the procedures for defining semantics for the
+ following IETF standards track extensions and vendor extensions to
+ the IPP/1.1 Model and Semantics document:
+
+ 1. keyword attribute values
+ 2. enum attribute values
+
+
+
+Hastings, et al. Standards Track [Page 148]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 3. attributes
+ 4. attribute syntaxes
+ 5. operations
+ 6. attribute groups
+ 7. status codes
+ 8. out-of-band attribute values
+
+ Extensions registered for use with IPP/1.1 are OPTIONAL for client
+ and IPP object conformance to the IPP/1.1 "Model and Semantics"
+ document (this document).
+
+ These extension procedures are aligned with the guidelines as set
+ forth by the IESG [IANA-CON]. Section 11 describes how to propose
+ new registrations for consideration. IANA will reject registration
+ proposals that leave out required information or do not follow the
+ appropriate format described in Section 11. The IPP/1.1 Model and
+ Semantics document may also be extended by an appropriate RFC that
+ specifies any of the above extensions.
+
+6.1 Typed 'keyword' and 'enum' Extensions
+
+ IPP allows for 'keyword' and 'enum' extensions (see sections 4.1.2.3
+ and 4.1.4). This document uses prefixes to the 'keyword' and 'enum'
+ basic attribute syntax type in order to communicate extra information
+ to the reader through its name. This extra information is not
+ represented in the protocol because it is unimportant to a client or
+ Printer object. The list below describes the prefixes and their
+ meaning.
+
+ "type1": This IPP specification document must be revised (or
+ another IETF standards track document which augments this
+ document) to add a new keyword or a new enum. No vendor
+ defined keywords or enums are allowed.
+
+ "type2": Implementers can, at any time, add new keyword or enum
+ values by proposing the complete specification to IANA:
+
+ iana@iana.org
+
+ IANA will forward the registration proposal to the IPP
+ Designated Expert who will review the proposal with a mailing
+ list that the Designated Expert keeps for this purpose.
+ Initially, that list will be the mailing list used by the IPP
+ WG:
+
+ ipp@pwg.org
+
+ even after the IPP WG is disbanded as permitted by [IANA-CON].
+
+
+
+Hastings, et al. Standards Track [Page 149]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The IPP Designated Expert is appointed by the IESG Area
+ Director responsible for IPP, according to [IANA-CON].
+
+ When a type2 keyword or enum is approved, the IPP Designated
+ Expert becomes the point of contact for any future maintenance
+ that might be required for that registration.
+
+ "type3": Implementers can, at any time, add new keyword and enum
+ values by submitting the complete specification to IANA as for
+ type2 who will forward the proposal to the IPP Designated
+ Expert. While no additional technical review is required, the
+ IPP Designated Expert may, at his/her discretion, forward the
+ proposal to the same mailing list as for type2 registrations
+ for advice and comment.
+
+ When a type3 keyword or enum is approved by the IPP Designated
+ Expert, the original proposer becomes the point of contact for
+ any future maintenance that might be required for that
+ registration.
+
+ For type2 and type3 keywords, the proposer includes the name of the
+ keyword in the registration proposal and the name is part of the
+ technical review.
+
+ After type2 and type3 enums specifications are approved, the IPP
+ Designated Expert in consultation with IANA assigns the next
+ available enum number for each enum value.
+
+ IANA will publish approved type2 and type3 keyword and enum
+ attributes value registration specifications in:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-values/xxx/yyy.txt
+
+ where xxx is the attribute name that specifies the initial values and
+ yyy.txt is a descriptive file name that contains one or more enums or
+ keywords approved at the same time. For example, if several
+ additional enums for stapling are approved for use with the
+ "finishings" attribute (and "finishings-default" and "finishings-
+ supported" attributes), IANA will publish the additional values in
+ the file:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-
+ values/finishings/stapling.txt
+
+ Note: Some attributes are defined to be: 'type3 keywords' | 'name'
+ which allows for attribute values to be extended by a site
+ administrator with administrator defined names. Such names are not
+ registered with IANA.
+
+
+
+Hastings, et al. Standards Track [Page 150]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ By definition, each of the three types above assert some sort of
+ registry or review process in order for extensions to be considered
+ valid. Each higher numbered level (1, 2, 3) tends to be decreasingly
+ less stringent than the previous level. Therefore, any typeN value
+ MAY be registered using a process for some typeM where M is less than
+ N, however such registration is NOT REQUIRED. For example, a type3
+ value MAY be registered in a type 1 manner (by being included in a
+ future version of an IPP specification), however, it is NOT REQUIRED.
+
+ This document defines keyword and enum values for all of the above
+ types, including type3 keywords.
+
+ For vendor keyword extensions, implementers SHOULD use keywords with
+ a suitable distinguishing prefix, such as "xxx-" where xxx follows
+ the syntax rules for keywords (see section 4.1.3) and is the
+ (lowercase) fully qualified company name registered with IANA for use
+ in domain names [RFC1035]. For example, if the company XYZ Corp. had
+ obtained the domain name "XYZ.com", then a vendor keyword 'abc' would
+ be: 'xyz.com-abc'.
+
+ Note: RFC 1035 [RFC1035] indicates that while upper and lower case
+ letters are allowed in domain names, no significance is attached to
+ the case. That is, two names with the same spelling but different
+ case are to be treated as if identical. Also, the labels in a domain
+ name must follow the rules for ARPANET host names: They must start
+ with a letter, end with a letter or digit, and have as interior
+ characters only letters, digits, and hyphen. Labels must be 63
+ characters or less. Labels are separated by the "." character.
+
+ For vendor enum extensions, implementers MUST use values in the
+ reserved integer range which is 2**30 to 2**31-1.
+
+6.2 Attribute Extensibility
+
+ Attribute names (see section 4.1.3) are type2 keywords. Therefore,
+ new attributes may be registered and have the same status as
+ attributes in this document by following the type2 extension rules.
+ For vendor attribute extensions, implementers SHOULD use keywords
+ with a suitable distinguishing prefix as described in Section 6.1.
+
+ IANA will publish approved attribute registration specifications as
+ separate files:
+
+ ftp.isi.edu/iana/assignments/ipp/attributes/xxx-yyy.txt
+
+ where "xxx-yyy" is the new attribute name.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 151]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ If a new Printer object attribute is defined and its values can be
+ affected by a specific document format, its specification needs to
+ contain the following sentence:
+
+ "The value of this attribute returned in a Get-Printer-
+ Attributes response MAY depend on the "document-format"
+ attribute supplied (see Section 3.2.5.1)."
+
+ If the specification does not, then its value in the Get-Printer-
+ Attributes response MUST NOT depend on the "document-format" supplied
+ in the request. When a new Job Template attribute is registered, the
+ value of the Printer attributes MAY vary with "document-format"
+ supplied in the request without the specification having to indicate
+ so.
+
+6.3 Attribute Syntax Extensibility
+
+ Attribute syntaxes (see section 4.1) are like type2 enums.
+ Therefore, new attribute syntaxes may be registered and have the same
+ status as attribute syntaxes in this document by following the type2
+ extension rules described in Section 6.1. The initial set of value
+ codes that identify each of the attribute syntaxes have been assigned
+ in the "Encoding and Transport" document [RFC2910], including a
+ designated range for vendor extension.
+
+ For attribute syntaxes, the IPP Designated Expert in consultation
+ with IANA assigns the next attribute syntax code in the appropriate
+ range as specified in [RFC2910]. IANA will publish approved
+ attribute syntax registration specifications as separate files:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-syntaxes/xxx-yyy.txt
+
+ where 'xxx-yyy' is the new attribute syntax name.
+
+6.4 Operation Extensibility
+
+ Operations (see section 3) may also be registered following the type2
+ procedures described in Section 6.1, though major new operations will
+ usually be done by a new standards track RFC that augments this
+ document. For vendor operation extensions, implementers MUST use the
+ range for the "operation-id" in requests specified in Section 4.4.15
+ "operations-supported" Printer attribute.
+
+ For operations, the IPP Designated Expert in consultation with IANA
+ assigns the next operation-id code as specified in Section 4.4.15.
+ IANA will publish approved operation registration specifications as
+ separate files:
+
+
+
+
+Hastings, et al. Standards Track [Page 152]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ ftp.isi.edu/iana/assignments/ipp/operations/Xxx-Yyy.txt
+
+ where "Xxx-Yyy" is the new operation name.
+
+6.5 Attribute Group Extensibility
+
+ Attribute groups (see section 3.1.3) passed in requests and responses
+ may be registered following the type2 procedures described in Section
+ 6.1. The initial set of attribute group tags have been assigned in
+ the "Encoding and Transport" document [RFC2910], including a
+ designated range for vendor extension.
+
+ For attribute groups, the IPP Designated Expert in consultation with
+ IANA assigns the next attribute group tag code in the appropriate
+ range as specified in [RFC2910]. IANA will publish approved
+ attribute group registration specifications as separate files:
+
+ ftp.isi.edu/iana/assignments/ipp/attribute-group-tags/xxx-yyy-
+ tag.txt
+
+ where 'xxx-yyy-tag' is the new attribute group tag name.
+
+6.6 Status Code Extensibility
+
+ Operation status codes (see section 3.1.6.1) may also be registered
+ following the type2 procedures described in Section 6.1. The values
+ for status codes are allocated in ranges as specified in Section 14
+ for each status code class:
+
+ "informational" - Request received, continuing process
+ "successful" - The action was successfully received, understood, and
+ accepted
+ "redirection" - Further action must be taken in order to complete the
+ request
+ "client-error" - The request contains bad syntax or cannot be
+ fulfilled
+ "server-error" - The IPP object failed to fulfill an apparently
+ valid request
+
+ For vendor operation status code extensions, implementers MUST use
+ the top of each range as specified in Section 13.
+
+ For operation status codes, the IPP Designated Expert in consultation
+ with IANA assigns the next status code in the appropriate class range
+ as specified in Section 13. IANA will publish approved status code
+ registration specifications as separate files:
+
+ ftp.isi.edu/iana/assignments/ipp/status-codes/xxx-yyy.txt
+
+
+
+Hastings, et al. Standards Track [Page 153]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ where "xxx-yyy" is the new operation status code keyword.
+
+6.7 Out-of-band Attribute Value Extensibility
+
+ Out-of-band attribute values (see the beginning of section 4.1)
+ passed in requests and responses may be registered following the
+ type2 procedures described in Section 6.1. The initial set of out-
+ of-band attribute value tags have been assigned in the "Encoding and
+ Transport" document [RFC2910].
+
+ For out-of-band attribute value tags, the IPP Designated Expert in
+ consultation with IANA assigns the next out-of-band attribute value
+ tag code in the appropriate range as specified in [RFC2910]. IANA
+ will publish approved out-of-band attribute value tags registration
+ specifications as separate files:
+
+ ftp.isi.edu/iana/assignments/ipp/out-of-band-attribute-value-
+ tags/xxx-yyy-tag.txt
+
+ where 'xxx-yyy-tag' is the new out-of-band attribute value tag name.
+
+6.8 Registration of MIME types/sub-types for document-formats
+
+ The "document-format" attribute's syntax is 'mimeMediaType'. This
+ means that valid values are Internet Media Types (see Section 4.1.9).
+ RFC 2045 [RFC2045] defines the syntax for valid Internet media types.
+ IANA is the registry for all Internet media types.
+
+6.9 Registration of charsets for use in 'charset' attribute values
+
+ The "attributes-charset" attribute's syntax is 'charset'. This means
+ that valid values are charsets names. When a charset in the IANA
+ registry has more than one name (alias), the name labeled as
+ "(preferred MIME name)", if present, MUST be used (see Section
+ 4.1.7). IANA is the registry for charsets following the procedures
+ of [RFC2278].
+
+7. Internationalization Considerations
+
+ Some of the attributes have values that are text strings and names
+ which are intended for human understanding rather than machine
+ understanding (see the 'text' and 'name' attribute syntaxes in
+ Sections 4.1.1 and 4.1.2).
+
+ In each operation request, the client
+
+ - identifies the charset and natural language of the request which
+ affects each supplied 'text' and 'name' attribute value, and
+
+
+
+Hastings, et al. Standards Track [Page 154]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ - requests the charset and natural language for attributes
+ returned by the IPP object in operation responses (as described
+ in Section 3.1.4.1).
+
+ In addition, the client MAY separately and individually identify the
+ Natural Language Override of a supplied 'text' or 'name' attribute
+ using the 'textWithLanguage' and 'nameWithLanguage' technique
+ described section 4.1.1.2 and 4.1.2.2 respectively.
+
+ All IPP objects MUST support the UTF-8 [RFC2279] charset in all
+ 'text' and 'name' attributes supported. If an IPP object supports
+ more than the UTF-8 charset, the object MUST convert between them in
+ order to return the requested charset to the client according to
+ Section 3.1.4.2. If an IPP object supports more than one natural
+ language, the object SHOULD return 'text' and 'name' values in the
+ natural language requested where those values are generated by the
+ Printer (see Section 3.1.4.1).
+
+ For Printers that support multiple charsets and/or multiple natural
+ languages in 'text' and 'name' attributes, different jobs may have
+ been submitted in differing charsets and/or natural languages. All
+ responses MUST be returned in the charset requested by the client.
+ However, the Get-Jobs operation uses the 'textWithLanguage' and
+ 'nameWithLanguage' mechanism to identify the differing natural
+ languages with each job attribute returned.
+
+ The Printer object also has configured charset and natural language
+ attributes. The client can query the Printer object to determine
+ the list of charsets and natural languages supported by the Printer
+ object and what the Printer object's configured values are. See the
+ "charset-configured", "charset-supported", "natural-language-
+ configured", and "generated-natural-language-supported" Printer
+ description attributes for more details.
+
+ The "charset-supported" attributed identifies the supported charsets.
+ If a charset is supported, the IPP object MUST be capable of
+ converting to and from that charset into any other supported charset.
+ In many cases, an IPP object will support only one charset and it
+ MUST be the UTF-8 charset.
+
+ The "charset-configured" attribute identifies the one supported
+ charset which is the native charset given the current configuration
+ of the IPP object (administrator defined).
+
+ The "generated-natural-language-supported" attribute identifies the
+ set of supported natural languages for generated messages; it is not
+ related to the set of natural languages that must be accepted for
+ client supplied 'text' and 'name' attributes. For client supplied
+
+
+
+Hastings, et al. Standards Track [Page 155]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'text' and 'name' attributes, an IPP object MUST accept ALL supplied
+ natural languages. Just because a Printer object is currently
+ configured to support 'en-us' natural language does not mean that the
+ Printer object should reject a job if the client supplies a job name
+ that is in 'fr-ca'.
+
+ The "natural-language-configured" attribute identifies the one
+ supported natural language for generated messages which is the native
+ natural language given the current configuration of the IPP object
+ (administrator defined).
+
+ Attributes of type 'text' and 'name' are populated from different
+ sources. These attributes can be categorized into following groups
+ (depending on the source of the attribute):
+
+ 1. Some attributes are supplied by the client (e.g., the client
+ supplied "job-name", "document-name", and "requesting-user-
+ name" operation attributes along with the corresponding Job
+ object's "job-name" and "job-originating-user-name"
+ attributes). The IPP object MUST accept these attributes in
+ any natural language no matter what the set of supported
+ languages for generated messages
+ 2. Some attributes are supplied by the system administrator (e.g.,
+ the Printer object's "printer-name" and "printer-location"
+ attributes). These too can be in any natural language. If the
+ natural language for these attributes is different than what a
+ client requests, then they must be reported using the Natural
+ Language Override mechanism.
+ 3. Some attributes are supplied by the device manufacturer (e.g.,
+ the Printer object's "printer-make-and-model" attribute).
+ These too can be in any natural language. If the natural
+ language for these attributes is different than what a client
+ requests, then they must be reported using the Natural Language
+ Override mechanism.
+ 4. Some attributes are supplied by the operator (e.g., the Job
+ object's "job-message-from-operator" attribute). These too can
+ be in any natural language. If the natural language for these
+ attributes is different than what a client requests, then they
+ must be reported using the Natural Language Override mechanism.
+ 5. Some attributes are generated by the IPP object (e.g., the Job
+ object's "job-state-message" attribute, the Printer object's
+ "printer-state-message" attribute, and the "status-message"
+ operation attribute). These attributes can only be in one of
+ the "generated-natural-language-supported" natural languages.
+ If a client requests some natural language for these attributes
+ other than one of the supported values, the IPP object SHOULD
+
+
+
+
+
+Hastings, et al. Standards Track [Page 156]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ respond using the value of the "natural-language-configured"
+ attribute (using the Natural Language Override mechanism if
+ needed).
+
+ The 'text' and 'name' attributes specified in this version of this
+ document (additional ones will be registered according to the
+ procedures in Section 6) are:
+
+ Attributes Source
+
+ Operation Attributes:
+ job-name (name) client
+ document-name (name) client
+ requesting-user-name (name) client
+ status-message (text) Job or Printer object
+ detailed-status-message (text) Job or Printer object -
+ see rule 1
+ document-access-error (text) Job or Printer object -
+ see rule 1
+
+ Job Template Attributes:
+ job-hold-until (keyword | name) client matches
+ administrator-configured
+ job-hold-until-default (keyword | name) client matches
+ administrator-configured
+ job-hold-until-supported (keyword | client matches
+ name) administrator-configured
+ job-sheets (keyword | name) client matches
+ administrator-configured
+ job-sheets-default (keyword | name) client matches
+ administrator-configured
+ job-sheets-supported (keyword | name) client matches
+ administrator-configured
+ media (keyword | name) client matches
+ administrator-configured
+ media-default (keyword | name) client matches
+ administrator-configured
+ media-supported (keyword | name) client matches
+ administrator-configured
+ media-ready (keyword | name) client matches
+ administrator-configured
+
+ Job Description Attributes:
+ job-name (name) client or Printer object
+ job-originating-user-name (name) Printer object
+ job-state-message (text) Job or Printer object
+ output-device-assigned (name(127)) administrator
+ job-message-from-operator (text(127)) operator
+
+
+
+Hastings, et al. Standards Track [Page 157]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ job-detailed-status-messages (1setOf Job or Printer object -
+ text) see rule 1
+ job-document-access-errors (1setOf Job or Printer object -
+ text) see rule 1
+
+ Printer Description Attributes:
+ printer-name (name(127)) administrator
+ printer-location (text(127)) administrator
+ printer-info (text(127)) administrator
+ printer-make-and-model (text(127)) administrator or
+ manufacturer
+ printer-state-message (text) Printer object
+ printer-message-from-operator operator
+ (text(127))
+
+ Rule 1 - Neither the Printer nor the client localizes these message
+ attributes, since they are intended for use by the system
+ administrator or other experienced technical persons.
+
+8. Security Considerations
+
+ It is difficult to anticipate the security risks that might exist in
+ any given IPP environment. For example, if IPP is used within a given
+ corporation over a private network, the risks of exposing document
+ data may be low enough that the corporation will choose not to use
+ encryption on that data. However, if the connection between the
+ client and the IPP object is over a public network, the client may
+ wish to protect the content of the information during transmission
+ through the network with encryption.
+
+ Furthermore, the value of the information being printed may vary from
+ one IPP environment to the next. Printing payroll checks, for
+ example, would have a different value than printing public
+ information from a file. There is also the possibly of denial-of-
+ service attacks, but denial-of-service attacks against printing
+ resources are not well understood and there is no published
+ precedents regarding this scenario.
+
+ Once the authenticated identity of the requester has been supplied to
+ the IPP object, the object uses that identity to enforce any
+ authorization policy that might be in place. For example, one site's
+ policy might be that only the job owner is allowed to cancel a job.
+ The details and mechanisms to set up a particular access control
+ policy are not part of IPP/1.1, and must be established via some
+ other type of administrative or access control framework. However,
+ there are operation status codes that allow an IPP server to return
+ information back to a client about any potential access control
+ violations for an IPP object.
+
+
+
+Hastings, et al. Standards Track [Page 158]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ During a create operation, the client's identity is recorded in the
+ Job object in an implementation-defined attribute. This information
+ can be used to verify a client's identity for subsequent operations
+ on that Job object in order to enforce any access control policy that
+ might be in effect. See section 8.3 below for more details.
+
+ Since the security levels or the specific threats that an IPP system
+ administrator may be concerned with cannot be anticipated, IPP MUST
+ be capable of operating with different security mechanisms and
+ security policies as required by the individual installation.
+ Security policies might vary from very strong, to very weak, to none
+ at all, and corresponding security mechanisms will be required.
+
+8.1 Security Scenarios
+
+ The following sections describe specific security attacks for IPP
+ environments. Where examples are provided they should be considered
+ illustrative of the environment and not an exhaustive set. Not all of
+ these environments will necessarily be addressed in initial
+ implementations of IPP.
+
+8.1.1 Client and Server in the Same Security Domain
+
+ This environment is typical of internal networks where traditional
+ office workers print the output of personal productivity applications
+ on shared work-group printers, or where batch applications print
+ their output on large production printers. Although the identity of
+ the user may be trusted in this environment, a user might want to
+ protect the content of a document against such attacks as
+ eavesdropping, replaying or tampering.
+
+8.1.2 Client and Server in Different Security Domains
+
+ Examples of this environment include printing a document created by
+ the client on a publicly available printer, such as at a commercial
+ print shop; or printing a document remotely on a business associate's
+ printer. This latter operation is functionally equivalent to sending
+ the document to the business associate as a facsimile. Printing
+ sensitive information on a Printer in a different security domain
+ requires strong security measures. In this environment authentication
+ of the printer is required as well as protection against unauthorized
+ use of print resources. Since the document crosses security domains,
+ protection against eavesdropping and document tampering are also
+ required. It will also be important in this environment to protect
+ Printers against "spamming" and malicious document content.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 159]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+8.1.3 Print by Reference
+
+ When the document is not stored on the client, printing can be done
+ by reference. That is, the print request can contain a reference, or
+ pointer, to the document instead of the actual document itself (see
+ sections 3.2.2 and 3.3.2). Standard methods currently do not exist
+ for remote entities to "assume" the credentials of a client for
+ forwarding requests to a 3rd party. It is anticipated that Print-By-
+ Reference will be used to access "public" documents and that
+ sophisticated methods for authenticating "proxies" is not specified
+ in this document.
+
+8.2 URIs in Operation, Job, and Printer attributes
+
+ The "printer-uri-supported" attribute contains the Printer object's
+ URI(s). Its companion attribute, "uri-security-supported",
+ identifies the security mechanism used for each URI listed in the
+ "printer-uri-supported" attribute. For each Printer operation
+ request, a client MUST supply only one URI in the "printer-uri"
+ operation attribute. In other words, even though the Printer
+ supports more than one URI, the client only interacts with the
+ Printer object using one if its URIs. This duality is not needed for
+ Job objects, since the Printer objects is the factory for Job
+ objects, and the Printer object will generate the correct URI for new
+ Job objects depending on the Printer object's security configuration.
+
+8.3 URIs for each authentication mechanisms
+
+ Each URI has an authentication mechanism associated with it. If the
+ URI is the i'th element of "printer-uri-supported", then
+ authentication mechanism is the "i th" element of "uri-
+ authentication-supported". For a list of possible authentication
+ mechanisms, see section 4.4.2.
+
+ The Printer object uses an authentication mechanism to determine the
+ name of the user performing an operation. This user is called the
+ "authenticated user". The credibility of authentication depends on
+ the mechanism that the Printer uses to obtain the user's name. When
+ the authentication mechanism is 'none', all authenticated users are
+ "anonymous".
+
+ During job creation operations, the Printer initializes the value of
+ the "job-originating-user-name" attribute (see section 4.3.6) to be
+ the authenticated user. The authenticated user is this case is called
+ the "job owner".
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 160]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ If an implementation can be configured to support more than one
+ authentication mechanism (see section 4.4.2), then it MUST implement
+ rules for determining equality of authenticated user names which have
+ been authenticated via different authentication mechanisms. One
+ possible policy is that identical names that are authenticated via
+ different mechanisms are different. For example, a user can cancel
+ his job only if he uses the same authentication mechanism for both
+ Cancel-Job and Print-Job. Another policy is that identical names
+ that are authenticated via different mechanism are the same if the
+ authentication mechanism for the later operation is not less strong
+ than the authentication mechanism for the earlier job creation
+ operation. For example, a user can cancel his job only if he uses
+ the same or stronger authentication mechanism for Cancel-Job and
+ Print-Job. With this second policy a job submitted via 'requesting-
+ user-name' authentication could be canceled via 'digest'
+ authentication. With the first policy, the job could not be canceled
+ in this way.
+
+ A client is able to determine the authentication mechanism used to
+ create a job. It is the i'th value of the Printer's "uri-
+ authentication-supported" attribute (see section 4.4.2), where i is
+ the index of the element of the Printer's "printer-uri-supported"
+ attribute (see section 4.4.1) equal to the job's "job-printer-uri"
+ attribute (see section 4.3.3).
+
+8.4 Restricted Queries
+
+ In many IPP operations, a client supplies a list of attributes to be
+ returned in the response. For security reasons, an IPP object may be
+ configured not to return all attributes (or all values) that a client
+ requests. The job attributes returned MAY depend on whether the
+ requesting user is the same as the user that submitted the job. The
+ IPP object MAY even return none of the requested attributes. In such
+ cases, the status returned is the same as if the object had returned
+ all requested attributes. The client cannot tell by such a response
+ whether the requested attribute was present or absent on the object.
+
+8.5 Operations performed by operators and system administrators
+
+ For the three printer operations Pause-Printer, Resume-Printer, and
+ Purge-Jobs (see sections 3.2.7, 3.2.8 and 3.2.9), the requesting user
+ is intended to be an operator or administrator of the Printer object
+ (see section 1). Otherwise, the IPP Printer MUST reject the
+ operation and return: 'client-error-forbidden', 'client-error-not-
+ authenticated', or 'client-error-not-authorized' as appropriate. For
+ operations on jobs, the requesting user is intended to be the job
+
+
+
+
+
+Hastings, et al. Standards Track [Page 161]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ owner or may be an operator or administrator of the Printer object.
+ The means for authorizing an operator or administrator of the Printer
+ object are not specified in this document.
+
+8.6 Queries on jobs submitted using non-IPP protocols
+
+ If the device that an IPP Printer is representing is able to accept
+ jobs using other job submission protocols in addition to IPP, it is
+ RECOMMENDED that such an implementation at least allow such "foreign"
+ jobs to be queried using Get-Jobs returning "job-id" and "job-uri" as
+ 'unknown'. Such an implementation NEED NOT support all of the same
+ IPP job attributes as for IPP jobs. The IPP object returns the
+ 'unknown' out-of-band value for any requested attribute of a foreign
+ job that is supported for IPP jobs, but not for foreign jobs.
+
+ It is further RECOMMENDED, that the IPP Printer generate "job-id" and
+ "job-uri" values for such "foreign jobs", if possible, so that they
+ may be targets of other IPP operations, such as Get-Job-Attributes
+ and Cancel-Job. Such an implementation also needs to deal with the
+ problem of authentication of such foreign jobs. One approach would
+ be to treat all such foreign jobs as belonging to users other than
+ the user of the IPP client. Another approach would be for the
+ foreign job to belong to 'anonymous'. Only if the IPP client has
+ been authenticated as an operator or administrator of the IPP Printer
+ object, could the foreign jobs be queried by an IPP request.
+ Alternatively, if the security policy is to allow users to query
+ other users' jobs, then the foreign jobs would also be visible to an
+ end-user IPP client using Get-Jobs and Get-Job-Attributes.
+
+9. References
+
+ [ASME-Y14.1M] Metric Drawing Sheet Size and Format, ASME Y14.1M-1995.
+ This standard defines metric sheet sizes and formats
+ for engineering drawings.
+
+ [ASCII] Coded Character Set - 7-bit American Standard Code for
+ Information Interchange (ASCII), ANSI X3.4-1986. This
+ standard is the specification of the US-ASCII charset.
+
+ [BCP-11] Bradner S. and R. Hovey, "The Organizations Involved in
+ the IETF Standards Process", BCP 11, RFC 2028, October
+ 1996.
+
+ [HTPP] J. Barnett, K. Carter, R. DeBry, "Initial Draft -
+ Hypertext Printing Protocol - HTPP/1.0", October 1996,
+ ftp://ftp.pwg.org/pub/pwg/ipp/historic/htpp/overview.ps.gz
+
+
+
+
+
+Hastings, et al. Standards Track [Page 162]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ [IANA-CON] Narten, T. and H. Alvestrand, "Guidelines for Writing
+ an IANA Considerations Section in RFCs", BCP 26, RFC
+ 2434, October 1998.
+
+ [IANA-CS] IANA Registry of Coded Character Sets:
+ ftp://ftp.isi.edu/in-notes/iana/assignments/character-
+ sets
+
+ [IANA-MT] IANA Registry of Media Types: ftp://ftp.isi.edu/in-
+ notes/iana/assignments/media-types/
+
+ [IPP-IIG] Hastings, T., Manros, C., Kugler, C., Holst, H., and P.
+ Zehler, "Internet Printing Protocol/1.1: draft-ietf-
+ ipp-implementers-guide-v11-01.txt, work in progress,
+ May 30, 2000.
+
+ [ISO10646-1] ISO/IEC 10646-1:1993, "Information technology --
+ Universal Multiple-Octet Coded Character Set (UCS) -
+ Part 1: Architecture and Basic Multilingual Plane,
+ JTC1/SC2."
+
+ [ISO8859-1] ISO/IEC 8859-1:1987, "Information technology -- 8-bit
+ One-Byte Coded Character Set - Part 1: Latin Alphabet
+ Nr 1", 1987, JTC1/SC2.
+
+ [ISO10175] ISO/IEC 10175 Document Printing Application (DPA), June
+ 1996.
+
+ [LDPA] T. Hastings, S. Isaacson, M. MacKay, C. Manros, D.
+ Taylor, P. Zehler, "LDPA - Lightweight Document
+ Printing Application", October 1996,
+ ftp://ftp.pwg.org/pub/pwg/ipp/historic/ldpa/ldpa8.pdf.gz
+
+ [P1387.4] Kirk, M. (editor), POSIX System Administration - Part
+ 4: Printing Interfaces, POSIX 1387.4 D8, 1994.
+
+ [PSIS] Herriot, R. (editor), X/Open A Printing System
+ Interoperability Specification (PSIS), August 1995.
+
+ [PWG] Printer Working Group, http://www.pwg.org.
+
+ [RFC1035] Mockapetris, P., "Domain Names - Implementation and
+ Specification", STD 13, RFC 1035, November 1987.
+
+ [RFC1179] McLaughlin, L., "Line Printer Daemon Protocol", RFC
+ 1179, August 1990.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 163]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ [RFC1759] Smith, R., Wright, F., Hastings, T., Zilles, S. and J.
+ Gyllenskog, "Printer MIB", RFC 1759, March 1995.
+
+ [RFC1766] Alvestrand, H., "Tags for the Identification of
+ Languages", RFC 1766, March 1995.
+
+ [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format
+ Specification version 1.3 ", RFC 1951, May 1996.
+
+ [RFC1952] Deutsch, P., "GZIP file format specification version
+ 4.3", RFC 1952, May 1996.
+
+ [RFC1977] Schryver, V., "PPP BSD Compression Protocol", RFC 1977,
+ August 1996.
+
+ [RFC2026] Bradner, S., "The Internet Standards Process --
+ Revision 3", BCP 9, RFC 2026, October 1996.
+
+ [RFC2045] Freed, N. and N. Borenstein, ", Multipurpose Internet
+ Mail Extensions (MIME) Part One: Format of Internet
+ Message Bodies", RFC 2045, November 1996.
+
+ [RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet
+ Mail Extensions (MIME) Part Two: Media Types", RFC
+ 2046, November 1996.
+
+ [RFC2048] Freed, N., Klensin, J. and J. Postel, "Multipurpose
+ Internet Mail Extension (MIME) Part Four: Registration
+ Procedures", RFC 2048, November 1996.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2228] Horowitz, M. and S. Lunt, "FTP Security Extensions",
+ RFC 2228, October 1997.
+
+ [RFC2246] Dierks, T. and C. Allen, "The TLS Protocol Version
+ 1.0", RFC 2246, January 1999.
+
+ [RFC2277] Alvestrand, H., "IETF Policy on Character Sets and
+ Languages" BCP 18, RFC 2277, January 1998.
+
+ [RFC2278] Freed, N. and J. Postel: "IANA CharSet Registration
+ Procedures", BCP 19, RFC 2278, January 1998.
+
+ [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
+ 10646", RFC 2279, January 1998.
+
+
+
+
+Hastings, et al. Standards Track [Page 164]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ [RFC2316] Bellovin, S., "Report of the IAB Security Architecture
+ Workshop", RFC 2316, April 1998.
+
+ [RFC2396] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform
+ Resource Identifiers (URI): Generic Syntax", RFC 2396,
+ August 1998.
+
+ [RFC2565] Herriot, R., Butler, S., Moore, P. and R. Turner,
+ "Internet Printing Protocol/1.0: Encoding and
+ Transport", RFC 2565, April 1999.
+
+ [RFC2566] deBry, R., Hastings, T., Herriot, R., Isaacson, S. and
+ P. Powell, "Internet Printing Protocol/1.0: Model and
+ Semantics", RFC 2566, April 1999.
+
+ [RFC2567] Wright, D., "Design Goals for an Internet Printing
+ Protocol", RFC 2567, April 1999.
+
+ [RFC2568] Zilles, S., "Rationale for the Structure and Model and
+ Protocol for the Internet Printing Protocol", RFC 2568,
+ April 1999.
+
+ [RFC2569] Herriot, R., Hastings, T., Jacobs, N. and J. Martin,
+ "Mapping between LPD and IPP Protocols", RFC 2569,
+ April 1999.
+
+ [RFC2579] McCloghrie, K., Perkins, D. and J. Schoenwaelder,
+ "Textual Conventions for SMIv2", STD 58, RFC 2579,
+ April 1999.
+
+ [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
+ Masinter, L., Leach, P. and T. Berners-Lee, "Hypertext
+ Transfer Protocol - HTTP/1.1", RFC 2616, June 1999.
+
+ [RFC2617] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence,
+ S., Leach, P., Luotonen, A. and L. Stewart, "HTTP
+ Authentication: Basic and Digest Access
+ Authentication", RFC 2617, June 1999.
+
+ [RFC2639] Hastings, T. and C. Manros, "Internet Printing
+ Protocol/1.0: Encoding and Transport", RFC 2639, July
+ 1999.
+
+ [RFC2910] Herriot, R., Butler, S., Moore, P., Turner, R. and J.
+ Wenn, "Internet Printing Protocol/1.1: Encoding and
+ Transport", RFC 2910, September 2000.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 165]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ [SSL] Netscape, The SSL Protocol, Version 3, (Text version
+ 3.02), November 1996.
+
+ [SWP] P. Moore, B. Jahromi, S. Butler, "Simple Web Printing
+ SWP/1.0", May 7, 1997,
+ ftp://ftp.pwg.org/pub/pwg/ipp/new_PRO/swp9705.pdf
+
+10. Authors' Addresses
+
+ Scott A. Isaacson, Editor
+ Novell, Inc.
+ 122 E 1700 S
+ Provo, UT 84606
+
+ Phone: 801-861-7366
+ Fax: 801-861-2517
+ EMail: sisaacson@novell.com
+
+
+ Tom Hastings
+ Xerox Corporation
+ 737 Hawaii St. ESAE 231
+ El Segundo, CA 90245
+
+ Phone: 310-333-6413
+ Fax: 310-333-5514
+ EMail: hastings@cp10.es.xerox.com
+
+
+ Robert Herriot
+ Xerox Corp.
+ 3400 Hill View Ave, Building 1
+ Palo Alto, CA 94304
+
+ Phone: 650-813-7696
+ Fax: 650-813-6860
+ EMail: robert.herriot@pahv.xerox.com
+
+
+ Roger deBry
+ Utah Valley State College
+ Orem, UT 84058
+
+ Phone: (801) 222-8000
+ EMail: debryro@uvsc.edu
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 166]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Patrick Powell
+ Astart Technologies
+ 9475 Chesapeake Dr., Suite D
+ San Diego, CA 95123
+
+ Phone: (619) 874-6543
+ Fax: (619) 279-8424
+ EMail: papowell@astart.com
+
+ IPP Web Page: http://www.pwg.org/ipp/
+ IPP Mailing List: ipp@pwg.org
+
+ To subscribe to the ipp mailing list, send the following email:
+ 1) send it to majordomo@pwg.org
+ 2) leave the subject line blank
+ 3) put the following two lines in the message body:
+ subscribe ipp
+ end
+
+ Implementers of this specification document are encouraged to join
+ IPP Mailing List in order to participate in any discussions of
+ clarification issues and review of registration proposals for
+ additional attributes and values.
+
+ Other Participants:
+
+ Chuck Adams - Tektronix Shivaun Albright - HP
+ Stefan Andersson - Axis Jeff Barnett - IBM
+ Ron Bergman - Hitachi Koki Imaging Dennis Carney - IBM
+ Systems
+ Keith Carter - IBM Angelo Caruso - Xerox
+ Rajesh Chawla - TR Computing Nancy Chen - Okidata
+ Solutions
+ Josh Cohen - Microsoft Jeff Copeland - QMS
+ Andy Davidson - Tektronix Roger deBry - IBM
+ Maulik Desai - Auco Mabry Dozier - QMS
+ Lee Farrell - Canon Information Satoshi Fujitami - Ricoh
+ Systems
+ Steve Gebert - IBM Sue Gleeson - Digital
+ Charles Gordon - Osicom Brian Grimshaw - Apple
+ Jerry Hadsell - IBM Richard Hart - Digital
+ Tom Hastings - Xerox Henrik Holst - I-data
+ Stephen Holmstead Zhi-Hong Huang - Zenographics
+ Scott Isaacson - Novell Babek Jahromi - Microsoft
+ Swen Johnson - Xerox David Kellerman - Northlake
+ Software
+ Robert Kline - TrueSpectra Charles Kong - Panasonic
+ Carl Kugler - IBM Dave Kuntz - Hewlett-Packard
+
+
+
+Hastings, et al. Standards Track [Page 167]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Takami Kurono - Brother Rick Landau - Digital
+ Scott Lawrence - Agranot Systems Greg LeClair - Epson
+ Dwight Lewis - Lexmark Harry Lewis - IBM
+ Tony Liao - Vivid Image Roy Lomicka - Digital
+ Pete Loya - HP Ray Lutz - Cognisys
+ Mike MacKay - Novell, Inc. David Manchala - Xerox
+ Carl-Uno Manros - Xerox Jay Martin - Underscore
+ Stan McConnell - Xerox Larry Masinter - Xerox
+ Sandra Matts - Hewlett Packard Peter Michalek - Shinesoft
+ Ira McDonald - High North Inc. Mike Moldovan - G3 Nova
+ Tetsuya Morita - Ricoh Yuichi Niwa - Ricoh
+ Pat Nogay - IBM Ron Norton - Printronics
+ Hugo Parra, Novell Bob Pentecost - Hewlett-Packard
+ Patrick Powell - Astart Jeff Rackowitz - Intermec
+ Technologies
+ Eric Random - Peerless Rob Rhoads - Intel
+ Xavier Riley - Xerox Gary Roberts - Ricoh
+ David Roach - Unisys Stuart Rowley - Kyocera
+ Yuji Sasaki - Japan Computer Richard Schneider - Epson
+ Industry
+ Kris Schoff - HP Katsuaki Sekiguchi - Canon
+ Bob Setterbo - Adobe Gail Songer - Peerless
+ Hideki Tanaka - Cannon Devon Taylor - Novell
+ Mike Timperman - Lexmark Atsushi Uchino - Epson
+ Shigeru Ueda - Canon Bob Von Andel - Allegro Software
+ William Wagner - NetSilicon/DPI Jim Walker - DAZEL
+ Chris Wellens - Interworking Labs Trevor Wells - Hewlett Packard
+ Craig Whittle - Sharp Labs Rob Whittle - Novell, Inc.
+ Jasper Wong - Xionics Don Wright - Lexmark
+ Michael Wu - Heidelberg Digital Rick Yardumian - Xerox
+ Michael Yeung - Toshiba Lloyd Young - Lexmark
+ Atsushi Yuki - Kyocera Peter Zehler - Xerox
+ William Zhang- Canon Information Frank Zhao - Panasonic
+ Systems
+ Steve Zilles - Adobe Rob Zirnstein - Canon Information
+ Systems
+
+11. Formats for IPP Registration Proposals
+
+ In order to propose an IPP extension for registration, the proposer
+ must submit an application to IANA by email to "iana@iana.org" or by
+ filling out the appropriate form on the IANA web pages
+ (http://www.iana.org). This section specifies the required
+ information and the formats for proposing registrations of extensions
+ to IPP as provided in Section 6 for:
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 168]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 1. type2 'keyword' attribute values
+ 2. type3 'keyword' attribute values
+ 3. type2 'enum' attribute values
+ 4. type3 'enum' attribute values
+ 5. attributes
+ 6. attribute syntaxes
+ 7. operations
+ 8. status codes
+ 9. out-of-band attribute values
+
+11.1 Type2 keyword attribute values registration,
+
+ Type of registration: type2 keyword attribute value
+ Name of attribute to which this keyword specification is to be added:
+ Proposed keyword name of this keyword value:
+ Specification of this keyword value (follow the style of IPP Model
+ Section 4.1.2.3):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For type2 keywords, the Designated Expert will be the point of
+ contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.2 Type3 keyword attribute values registration
+
+ Type of registration: type3 keyword attribute value
+ Name of attribute to which this keyword specification is to be added:
+ Proposed keyword name of this keyword value:
+ Specification of this keyword value (follow the style of IPP Model
+ Section 4.1.2.3):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For type3 keywords, the proposer will be the point of contact
+ for the approved registration specification, if any maintenance of
+ the registration specification is needed.
+
+11.3 Type2 enum attribute values registration
+
+ Type of registration: type2 enum attribute value
+ Name of attribute to which this enum specification is to be added:
+ Keyword symbolic name of this enum value:
+ Numeric value (to be assigned by the IPP Designated Expert in
+ consultation with IANA):
+
+
+
+
+Hastings, et al. Standards Track [Page 169]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Specification of this enum value (follow the style of IPP Model
+ Section 4.1.4):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For type2 enums, the Designated Expert will be the point of
+ contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.4 Type3 enum attribute values registration
+
+ Type of registration: type3 enum attribute value
+ Name of attribute to which this enum specification is to be added:
+ Keyword symbolic name of this enum value:
+ Numeric value (to be assigned by the IPP Designated Expert in
+ consultation with IANA):
+ Specification of this enum value (follow the style of IPP Model
+ Section 4.1.4):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For type3 enums, the proposer will be the point of contact for
+ the approved registration specification, if any maintenance of the
+ registration specification is needed.
+
+11.5 Attribute registration
+
+ Type of registration: attribute
+ Proposed keyword name of this attribute:
+ Types of attribute (Operation, Job Template, Job Description, Printer
+ Description):
+ Operations to be used with if the attribute is an operation attribute:
+ Object (Job, Printer, etc. if bound to an object):
+ Attribute syntax(es) (include 1setOf and range as in Section 4.2):
+ If attribute syntax is 'keyword' or 'enum', is it type2 or type3:
+ If this is a Printer attribute, MAY the value returned depend on
+ "document-format" (See Section 6.2):
+ If this is a Job Template attribute, how does its specification depend
+ on the value of the "multiple-document-handling" attribute:
+ Specification of this attribute (follow the style of IPP Model Section
+ 4.2):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+
+
+
+
+Hastings, et al. Standards Track [Page 170]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Note: For attributes, the IPP Designated Expert will be the point of
+ contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.6 Attribute Syntax registration
+
+ Type of registration: attribute syntax
+ Proposed name of this attribute syntax:
+ Type of attribute syntax (integer, octetString, character-string, see
+ [RFC2910]):
+ Numeric tag according to [RFC2910] (to be assigned by the IPP
+ Designated Expert in consultation with IANA):
+ Specification of this attribute (follow the style of IPP Model Section
+ 4.1):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For attribute syntaxes, the IPP Designated Expert will be the
+ point of contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.7 Operation registration
+
+ Type of registration: operation
+ Proposed name of this operation:
+ Numeric operation-id value according to section 4.4.15 (to be assigned
+ by the IPP Designated Expert in consultation with IANA):
+ Object Target (Job, Printer, etc. that operation is upon):
+ Specification of this operation (follow the style of IPP Model Section
+ 3):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For operations, the IPP Designated Expert will be the point of
+ contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.8 Attribute Group registration
+
+ Type of registration: attribute group
+ Proposed name of this attribute group:
+ Numeric tag according to [RFC2910] (to be assigned by the IPP
+ Designated Expert in consultation with IANA):
+ Operation requests and group number for each operation in which the
+ attribute group occurs:
+
+
+
+
+Hastings, et al. Standards Track [Page 171]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Operation responses and group number for each operation in which the
+ attribute group occurs:
+ Specification of this attribute group (follow the style of IPP Model
+ Section 3):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For attribute groups, the IPP Designated Expert will be the
+ point of contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.9 Status code registration
+
+ Type of registration: status code
+ Keyword symbolic name of this status code value:
+ Numeric value (to be assigned by the IPP Designated Expert in
+ consultation with IANA):
+ Operations that this status code may be used with:
+ Specification of this status code (follow the style of IPP Model
+ Section 13 APPENDIX B: Status Codes and Suggested Status Code
+ Messages):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For status codes, the Designated Expert will be the point of
+ contact for the approved registration specification, if any
+ maintenance of the registration specification is needed.
+
+11.10 Out-of-band Attribute Value registration
+
+ Type of registration: out-of-band attribute value
+ Proposed name of this out-of-band attribute value:
+ Numeric tag according to [RFC2910] (to be assigned by the IPP Designated
+ Expert in consultation with IANA):
+ Operations that this out-of-band attribute value may be used with:
+ Attributes that this out-of-band attribute value may be used with:
+ Specification of this out-of-band attribute value (follow the style of
+ the beginning of IPP Model Section 4.1):
+ Name of proposer:
+ Address of proposer:
+ Email address of proposer:
+
+ Note: For out-of-band attribute values, the IPP Designated Expert
+ will be the point of contact for the approved registration
+ specification, if any maintenance of the registration specification
+ is needed.
+
+
+
+Hastings, et al. Standards Track [Page 172]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+12. APPENDIX A: Terminology
+
+ This specification document uses the terminology defined in this
+ section.
+
+12.1 Conformance Terminology
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
+ "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
+ interpreted as described in RFC 2119 [RFC2119].
+
+12.1.1 NEED NOT
+
+ This term is not included in RFC 2119. The verb "NEED NOT" indicates
+ an action that the subject of the sentence does not have to implement
+ in order to claim conformance to the standard. The verb "NEED NOT"
+ is used instead of "MAY NOT" since "MAY NOT" sounds like a
+ prohibition.
+
+12.2 Model Terminology
+
+12.2.1 Keyword
+
+ Keywords are used within this document as identifiers of semantic
+ entities within the abstract model (see section 4.1.2.3). Attribute
+ names, some attribute values, attribute syntaxes, and attribute group
+ names are represented as keywords.
+
+12.2.2 Attributes
+
+ An attribute is an item of information that is associated with an
+ instance of an IPP object. An attribute consists of an attribute
+ name and one or more attribute values. Each attribute has a specific
+ attribute syntax. All object attributes are defined in section 4 and
+ all operation attributes are defined in section 3.
+
+ Job Template Attributes are described in section 4.2. The client
+ optionally supplies Job Template attributes in a create request
+ (operation requests that create Job objects). The Printer object has
+ associated attributes which define supported and default values for
+ the Printer.
+
+12.2.2.1 Attribute Name
+
+ Each attribute is uniquely identified in this document by its
+ attribute name. An attribute name is a keyword. The keyword
+ attribute name is given in the section header describing that
+
+
+
+
+Hastings, et al. Standards Track [Page 173]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ attribute. In running text in this document, attribute names are
+ indicated inside double quotation marks (") where the quotation marks
+ are not part of the keyword itself.
+
+12.2.2.2 Attribute Group Name
+
+ Related attributes are grouped into named groups. The name of the
+ group is a keyword. The group name may be used in place of naming
+ all the attributes in the group explicitly. Attribute groups are
+ defined in section 3.
+
+12.2.2.3 Attribute Value
+
+ Each attribute has one or more values. Attribute values are
+ represented in the syntax type specified for that attribute. In
+ running text in this document, attribute values are indicated inside
+ single quotation marks ('), whether their attribute syntax is
+ keyword, integer, text, etc. where the quotation marks are not part
+ of the value itself.
+
+12.2.2.4 Attribute Syntax
+
+ Each attribute is defined using an explicit syntax type. In this
+ document, each syntax type is defined as a keyword with specific
+ meaning. The "Encoding and Transport" document [RFC2910] indicates
+ the actual "on-the-wire" encoding rules for each syntax type.
+ Attribute syntax types are defined in section 4.1.
+
+12.2.3 Supports
+
+ By definition, a Printer object supports an attribute only if that
+ Printer object responds with the corresponding attribute populated
+ with some value(s) in a response to a query for that attribute. A
+ Printer object supports an attribute value if the value is one of the
+ Printer object's "supported values" attributes. The device behind a
+ Printer object may exhibit a behavior that corresponds to some IPP
+ attribute, but if the Printer object, when queried for that
+ attribute, doesn't respond with the attribute, then as far as IPP is
+ concerned, that implementation does not support that feature. If the
+ Printer object's "xxx-supported" attribute is not populated with a
+ particular value (even if that value is a legal value for that
+ attribute), then that Printer object does not support that particular
+ value.
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 174]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ A conforming implementation MUST support all REQUIRED attributes.
+ However, even for REQUIRED attributes, conformance to IPP does not
+ mandate that all implementations support all possible values
+ representing all possible job processing behaviors and features. For
+ example, if a given instance of a Printer supports only certain
+ document formats, then that Printer responds with the "document-
+ format-supported" attribute populated with a set of values, possibly
+ only one, taken from the entire set of possible values defined for
+ that attribute. This limited set of values represents the Printer's
+ set of supported document formats. Supporting an attribute and some
+ set of values for that attribute enables IPP end users to be aware of
+ and make use of those features associated with that attribute and
+ those values. If an implementation chooses to not support an
+ attribute or some specific value, then IPP end users would have no
+ ability to make use of that feature within the context of IPP itself.
+ However, due to existing practice and legacy systems which are not
+ IPP aware, there might be some other mechanism outside the scope of
+ IPP to control or request the "unsupported" feature (such as embedded
+ instructions within the document data itself).
+
+ For example, consider the "finishings-supported" attribute.
+
+ 1) If a Printer object is not physically capable of stapling, the
+ "finishings-supported" attribute MUST NOT be populated with the
+ value of 'staple'.
+ 2) A Printer object is physically capable of stapling, however an
+ implementation chooses not to support stapling in the IPP
+ "finishings" attribute. In this case, 'staple' MUST NOT be a
+ value in the "finishings-supported" Printer object attribute.
+ Without support for the value 'staple', an IPP end user would
+ have no means within the protocol itself to request that a Job
+ be stapled. However, an existing document data formatter might
+ be able to request that the document be stapled directly with
+ an embedded instruction within the document data. In this
+ case, the IPP implementation does not "support" stapling,
+ however the end user is still able to have some control over
+ the stapling of the completed job.
+ 3) A Printer object is physically capable of stapling, and an
+ implementation chooses to support stapling in the IPP
+ "finishings" attribute. In this case, 'staple' MUST be a value
+ in the "finishings-supported" Printer object attribute. Doing
+ so, would enable end users to be aware of and make use of the
+ stapling feature using IPP attributes.
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 175]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Even though support for Job Template attributes by a Printer object
+ is OPTIONAL, it is RECOMMENDED that if the device behind a Printer
+ object is capable of realizing any feature or function that
+ corresponds to an IPP attribute and some associated value, then that
+ implementation SHOULD support that IPP attribute and value.
+
+ The set of values in any of the supported value attributes is set
+ (populated) by some administrative process or automatic sensing
+ mechanism that is outside the scope of this IPP/1.1 document. For
+ administrative policy and control reasons, an administrator may
+ choose to make only a subset of possible values visible to the end
+ user. In this case, the real output device behind the IPP Printer
+ abstraction may be capable of a certain feature, however an
+ administrator is specifying that access to that feature not be
+ exposed to the end user through the IPP protocol. Also, since a
+ Printer object may represent a logical print device (not just a
+ physical device) the actual process for supporting a value is
+ undefined and left up to the implementation. However, if a Printer
+ object supports a value, some manual human action may be needed to
+ realize the semantic action associated with the value, but no end
+ user action is required.
+
+ For example, if one of the values in the "finishings-supported"
+ attribute is 'staple', the actual process might be an automatic
+ staple action by a physical device controlled by some command sent to
+ the device. Or, the actual process of stapling might be a manual
+ action by an operator at an operator attended Printer object.
+
+ For another example of how supported attributes function, consider a
+ system administrator who desires to control all print jobs so that no
+ job sheets are printed in order to conserve paper. To force no job
+ sheets, the system administrator sets the only supported value for
+ the "job-sheets-supported" attribute to 'none'. In this case, if a
+ client requests anything except 'none', the create request is
+ rejected or the "job-sheets" value is ignored (depending on the value
+ of "ipp-attribute-fidelity"). To force the use of job start/end
+ sheets on all jobs, the administrator does not include the value
+ 'none' in the "job-sheets- supported" attribute. In this case, if a
+ client requests 'none', the create request is rejected or the "job-
+ sheets" value is ignored (again depending on the value of "ipp-
+ attribute-fidelity").
+
+12.2.4 print-stream page
+
+ A "print-stream page" is a page according to the definition of pages
+ in the language used to express the document data.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 176]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+12.2.5 impression
+
+ An "impression" is the image (possibly many print-stream pages in
+ different configurations) imposed onto a single media page.
+
+13. APPENDIX B: Status Codes and Suggested Status Code Messages
+
+ This section defines status code enum keywords and values that are
+ used to provide semantic information on the results of an operation
+ request. Each operation response MUST include a status code. The
+ response MAY also contain a status message that provides a short
+ textual description of the status. The status code is intended for
+ use by automata, and the status message is intended for the human end
+ user. Since the status message is an OPTIONAL component of the
+ operation response, an IPP application (i.e., a browser, GUI, print
+ driver or gateway) is NOT REQUIRED to examine or display the status
+ message, since it MAY not be returned to the application.
+
+ The prefix of the status keyword defines the class of response as
+ follows:
+
+ "informational" - Request received, continuing process
+ "successful" - The action was successfully received, understood,
+ and accepted
+ "redirection" - Further action must be taken in order to complete
+ the request
+ "client-error" - The request contains bad syntax or cannot be
+ fulfilled
+ "server-error" - The IPP object failed to fulfill an apparently
+ valid request
+
+ As with type2 enums, IPP status codes are extensible. IPP clients
+ are NOT REQUIRED to understand the meaning of all registered status
+ codes, though such understanding is obviously desirable. However,
+ IPP clients MUST understand the class of any status code, as
+ indicated by the prefix, and treat any unrecognized response as being
+ equivalent to the first status code of that class, with the exception
+ that an unrecognized response MUST NOT be cached. For example, if an
+ unrecognized status code of "client-error-xxx-yyy" is received by the
+ client, it can safely assume that there was something wrong with its
+ request and treat the response as if it had received a "client-
+ error-bad-request" status code. In such cases, IPP applications
+ SHOULD present the OPTIONAL message (if present) to the end user
+ since the message is likely to contain human readable information
+ which will help to explain the unusual status. The name of the enum
+ is the suggested status message for US English.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 177]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The status code values range from 0x0000 to 0x7FFF. The value ranges
+ for each status code class are as follows:
+
+ "successful" - 0x0000 to 0x00FF
+ "informational" - 0x0100 to 0x01FF
+ "redirection" - 0x0200 to 0x02FF
+ "client-error" - 0x0400 to 0x04FF
+ "server-error" - 0x0500 to 0x05FF
+
+ The top half (128 values) of each range (0x0n40 to 0x0nFF, for n = 0
+ to 5) is reserved for vendor use within each status code class.
+ Values 0x0600 to 0x7FFF are reserved for future assignment by IETF
+ standards track documents and MUST NOT be used.
+
+13.1 Status Codes
+
+ Each status code is described below. Section 13.1.5.9 contains a
+ table that indicates which status codes apply to which operations.
+ The Implementer's Guide [IPP-IIG] describe the suggested steps for
+ processing IPP attributes for all operations, including returning
+ status codes.
+
+13.1.1 Informational
+
+ This class of status code indicates a provisional response and is to
+ be used for informational purposes only.
+
+ There are no status codes defined in IPP/1.1 for this class of status
+ code.
+
+13.1.2 Successful Status Codes
+
+ This class of status code indicates that the client's request was
+ successfully received, understood, and accepted.
+
+13.1.2.1 successful-ok (0x0000)
+
+ The request has succeeded and no request attributes were substituted
+ or ignored. In the case of a response to a create request, the
+ 'successful-ok' status code indicates that the request was
+ successfully received and validated, and that the Job object has been
+ created; it does not indicate that the job has been processed. The
+ transition of the Job object into the 'completed' state is the only
+ indicator that the job has been printed.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 178]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+13.1.2.2 successful-ok-ignored-or-substituted-attributes (0x0001)
+
+ The request has succeeded, but some supplied (1) attributes were
+ ignored or (2) unsupported values were substituted with supported
+ values or were ignored in order to perform the operation without
+ rejecting it. Unsupported attributes, attribute syntaxes, or values
+ MUST be returned in the Unsupported Attributes group of the response
+ for all operations. There is an exception to this rule for the query
+ operations: Get-Printer-Attributes, Get-Jobs, and Get-Job-Attributes
+ for the "requested-attributes" operation attribute only. When the
+ supplied values of the "requested-attributes" operation attribute are
+ requesting attributes that are not supported, the IPP object MAY, but
+ is NOT REQUIRED to, return the "requested-attributes" attribute in
+ the Unsupported Attribute response group (with the unsupported values
+ only). See sections 3.1.7 and 3.2.1.2.
+
+13.1.2.3 successful-ok-conflicting-attributes (0x0002)
+
+ The request has succeeded, but some supplied attribute values
+ conflicted with the values of other supplied attributes. These
+ conflicting values were either (1) substituted with (supported)
+ values or (2) the attributes were removed in order to process the job
+ without rejecting it. Attributes or values which conflict with other
+ attributes and have been substituted or ignored MUST be returned in
+ the Unsupported Attributes group of the response for all operations
+ as supplied by the client. See sections 3.1.7 and 3.2.1.2.
+
+13.1.3 Redirection Status Codes
+
+ This class of status code indicates that further action needs to be
+ taken to fulfill the request.
+
+ There are no status codes defined in IPP/1.1 for this class of status
+ code.
+
+13.1.4 Client Error Status Codes
+
+ This class of status code is intended for cases in which the client
+ seems to have erred. The IPP object SHOULD return a message
+ containing an explanation of the error situation and whether it is a
+ temporary or permanent condition.
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 179]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+13.1.4.1 client-error-bad-request (0x0400)
+
+ The request could not be understood by the IPP object due to
+ malformed syntax (such as the value of a fixed length attribute whose
+ length does not match the prescribed length for that attribute - see
+ the Implementer's Guide [IPP-IIG] ). The IPP application SHOULD NOT
+ repeat the request without modifications.
+
+13.1.4.2 client-error-forbidden (0x0401)
+
+ The IPP object understood the request, but is refusing to fulfill it.
+ Additional authentication information or authorization credentials
+ will not help and the request SHOULD NOT be repeated. This status
+ code is commonly used when the IPP object does not wish to reveal
+ exactly why the request has been refused or when no other response is
+ applicable.
+
+13.1.4.3 client-error-not-authenticated (0x0402)
+
+ The request requires user authentication. The IPP client may repeat
+ the request with suitable authentication information. If the request
+ already included authentication information, then this status code
+ indicates that authorization has been refused for those credentials.
+ If this response contains the same challenge as the prior response,
+ and the user agent has already attempted authentication at least
+ once, then the response message may contain relevant diagnostic
+ information. This status codes reveals more information than
+ "client-error-forbidden".
+
+13.1.4.4 client-error-not-authorized (0x0403)
+
+ The requester is not authorized to perform the request. Additional
+ authentication information or authorization credentials will not help
+ and the request SHOULD NOT be repeated. This status code is used
+ when the IPP object wishes to reveal that the authentication
+ information is understandable, however, the requester is explicitly
+ not authorized to perform the request. This status codes reveals
+ more information than "client-error-forbidden" and "client-error-
+ not-authenticated".
+
+13.1.4.5 client-error-not-possible (0x0404)
+
+ This status code is used when the request is for something that can
+ not happen. For example, there might be a request to cancel a job
+ that has already been canceled or aborted by the system. The IPP
+ client SHOULD NOT repeat the request.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 180]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+13.1.4.6 client-error-timeout (0x0405)
+
+ The client did not produce a request within the time that the IPP
+ object was prepared to wait. For example, a client issued a Create-
+ Job operation and then, after a long period of time, issued a Send-
+ Document operation and this error status code was returned in
+ response to the Send-Document request (see section 3.3.1). The IPP
+ object might have been forced to clean up resources that had been
+ held for the waiting additional Documents. The IPP object was forced
+ to close the Job since the client took too long. The client SHOULD
+ NOT repeat the request without modifications.
+
+13.1.4.7 client-error-not-found (0x0406)
+
+ The IPP object has not found anything matching the request URI. No
+ indication is given of whether the condition is temporary or
+ permanent. For example, a client with an old reference to a Job (a
+ URI) tries to cancel the Job, however in the mean time the Job might
+ have been completed and all record of it at the Printer has been
+ deleted. This status code, 'client-error-not-found' is returned
+ indicating that the referenced Job can not be found. This error
+ status code is also used when a client supplies a URI as a reference
+ to the document data in either a Print-URI or Send-URI operation, but
+ the document can not be found.
+
+ In practice, an IPP application should avoid a not found situation by
+ first querying and presenting a list of valid Printer URIs and Job
+ URIs to the end-user.
+
+13.1.4.8 client-error-gone (0x0407)
+
+ The requested object is no longer available and no forwarding address
+ is known. This condition should be considered permanent. Clients
+ with link editing capabilities should delete references to the
+ request URI after user approval. If the IPP object does not know or
+ has no facility to determine, whether or not the condition is
+ permanent, the status code "client-error-not-found" should be used
+ instead.
+
+ This response is primarily intended to assist the task of maintenance
+ by notifying the recipient that the resource is intentionally
+ unavailable and that the IPP object administrator desires that remote
+ links to that resource be removed. It is not necessary to mark all
+ permanently unavailable resources as "gone" or to keep the mark for
+ any length of time -- that is left to the discretion of the IPP
+ object administrator and/or Printer implementation.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 181]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+13.1.4.9 client-error-request-entity-too-large (0x0408)
+
+ The IPP object is refusing to process a request because the request
+ entity is larger than the IPP object is willing or able to process.
+ An IPP Printer returns this status code when it limits the size of
+ print jobs and it receives a print job that exceeds that limit or
+ when the attributes are so many that their encoding causes the
+ request entity to exceed IPP object capacity.
+
+13.1.4.10 client-error-request-value-too-long (0x0409)
+
+ The IPP object is refusing to service the request because one or more
+ of the client-supplied attributes has a variable length value that is
+ longer than the maximum length specified for that attribute. The IPP
+ object might not have sufficient resources (memory, buffers, etc.) to
+ process (even temporarily), interpret, and/or ignore a value larger
+ than the maximum length. Another use of this error code is when the
+ IPP object supports the processing of a large value that is less than
+ the maximum length, but during the processing of the request as a
+ whole, the object may pass the value onto some other system component
+ which is not able to accept the large value. For more details, see
+ the Implementer's Guide [IPP-IIG] .
+
+ Note: For attribute values that are URIs, this rare condition is
+ only likely to occur when a client has improperly submitted a request
+ with long query information (e.g. an IPP application allows an end-
+ user to enter an invalid URI), when the client has descended into a
+ URI "black hole" of redirection (e.g., a redirected URI prefix that
+ points to a suffix of itself), or when the IPP object is under attack
+ by a client attempting to exploit security holes present in some IPP
+ objects using fixed-length buffers for reading or manipulating the
+ Request-URI.
+
+13.1.4.11 client-error-document-format-not-supported (0x040A)
+
+ The IPP object is refusing to service the request because the
+ document data is in a format, as specified in the "document-format"
+ operation attribute, that is not supported by the Printer object.
+ This error is returned independent of the client-supplied "ipp-
+ attribute-fidelity". The Printer object MUST return this status
+ code, even if there are other Job Template attributes that are not
+ supported as well, since this error is a bigger problem than with Job
+ Template attributes. See sections 3.1.6.1, 3.1.7, and 3.2.1.1.
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 182]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+13.1.4.12 client-error-attributes-or-values-not-supported (0x040B)
+
+ In a create request, if the Printer object does not support one or
+ more attributes, attribute syntaxes, or attribute values supplied in
+ the request and the client supplied the "ipp-attribute-fidelity"
+ operation attribute with the 'true' value, the Printer object MUST
+ return this status code. The Printer object MUST also return in the
+ Unsupported Attributes Group all the attributes and/or values
+ supplied by the client that are not supported. See section 3.1.7.
+ For example, if the request indicates 'iso-a4' media, but that media
+ type is not supported by the Printer object. Or, if the client
+ supplies a Job Template attribute and the attribute itself is not
+ even supported by the Printer. If the "ipp-attribute-fidelity"
+ attribute is 'false', the Printer MUST ignore or substitute values
+ for unsupported Job Template attributes and values rather than reject
+ the request and return this status code.
+
+ For any operation where a client requests attributes (such as a Get-
+ Jobs, Get-Printer-Attributes, or Get-Job-Attributes operation), if
+ the IPP object does not support one or more of the requested
+ attributes, the IPP object simply ignores the unsupported requested
+ attributes and processes the request as if they had not been
+ supplied, rather than returning this status code. In this case, the
+ IPP object MUST return the 'successful-ok-ignored-or-substituted-
+ attributes' status code and MAY return the unsupported attributes as
+ values of the "requested-attributes" in the Unsupported Attributes
+ Group (see section 13.1.2.2).
+
+13.1.4.13 client-error-uri-scheme-not-supported (0x040C)
+
+ The scheme of the client-supplied URI in a Print-URI or a Send-URI
+ operation is not supported. See sections 3.1.6.1 and 3.1.7.
+
+13.1.4.14 client-error-charset-not-supported (0x040D)
+
+ For any operation, if the IPP Printer does not support the charset
+ supplied by the client in the "attributes-charset" operation
+ attribute, the Printer MUST reject the operation and return this
+ status and any 'text' or 'name' attributes using the 'utf-8' charset
+ (see Section 3.1.4.1). See sections 3.1.6.1 and 3.1.7.
+
+13.1.4.15 client-error-conflicting-attributes (0x040E)
+
+ The request is rejected because some attribute values conflicted with
+ the values of other attributes which this document does not permit to
+ be substituted or ignored. The Printer object MUST also return in
+ the Unsupported Attributes Group the conflicting attributes supplied
+ by the client. See sections 3.1.7 and 3.2.1.2.
+
+
+
+Hastings, et al. Standards Track [Page 183]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+13.1.4.16 client-error-compression-not-supported (0x040F)
+
+ The IPP object is refusing to service the request because the
+ document data, as specified in the "compression" operation attribute,
+ is compressed in a way that is not supported by the Printer object.
+ This error is returned independent of the client-supplied "ipp-
+ attribute-fidelity". The Printer object MUST return this status
+ code, even if there are other Job Template attributes that are not
+ supported as well, since this error is a bigger problem than with Job
+ Template attributes. See sections 3.1.6.1, 3.1.7, and 3.2.1.1.
+
+13.1.4.17 client-error-compression-error (0x0410)
+
+ The IPP object is refusing to service the request because the
+ document data cannot be decompressed when using the algorithm
+ specified by the "compression" operation attribute. This error is
+ returned independent of the client-supplied "ipp-attribute-fidelity".
+ The Printer object MUST return this status code, even if there are
+ Job Template attributes that are not supported as well, since this
+ error is a bigger problem than with Job Template attributes. See
+ sections 3.1.7 and 3.2.1.1.
+
+13.1.4.18 client-error-document-format-error (0x0411)
+
+ The IPP object is refusing to service the request because Printer
+ encountered an error in the document data while interpreting it.
+ This error is returned independent of the client-supplied "ipp-
+ attribute-fidelity". The Printer object MUST return this status
+ code, even if there are Job Template attributes that are not
+ supported as well, since this error is a bigger problem than with Job
+ Template attributes. See sections 3.1.7 and 3.2.1.1.
+
+13.1.4.19 client-error-document-access-error (0x0412)
+
+ The IPP object is refusing to service the Print-URI or Send-URI
+ request because Printer encountered an access error while attempting
+ to validate the accessibility or access the document data specified
+ in the "document-uri" operation attribute. The Printer MAY also
+ return a specific document access error code using the "document-
+ access-error" operation attribute (see section 3.1.6.4). This error
+ is returned independent of the client-supplied "ipp-attribute-
+ fidelity". The Printer object MUST return this status code, even if
+ there are Job Template attributes that are not supported as well,
+ since this error is a bigger problem than with Job Template
+ attributes. See sections 3.1.6.1 and 3.1.7.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 184]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+13.1.5 Server Error Status Codes
+
+ This class of status codes indicates cases in which the IPP object is
+ aware that it has erred or is incapable of performing the request.
+ The IPP object SHOULD include a message containing an explanation of
+ the error situation, and whether it is a temporary or permanent
+ condition.
+
+13.1.5.1 server-error-internal-error (0x0500)
+
+ The IPP object encountered an unexpected condition that prevented it
+ from fulfilling the request. This error status code differs from
+ "server-error-temporary-error" in that it implies a more permanent
+ type of internal error. It also differs from "server-error-device-
+ error" in that it implies an unexpected condition (unlike a paper-jam
+ or out-of-toner problem which is undesirable but expected). This
+ error status code indicates that probably some knowledgeable human
+ intervention is required.
+
+13.1.5.2 server-error-operation-not-supported (0x0501)
+
+ The IPP object does not support the functionality required to fulfill
+ the request. This is the appropriate response when the IPP object
+ does not recognize an operation or is not capable of supporting it.
+ See sections 3.1.6.1 and 3.1.7.
+
+13.1.5.3 server-error-service-unavailable (0x0502)
+
+ The IPP object is currently unable to handle the request due to a
+ temporary overloading or maintenance of the IPP object. The
+ implication is that this is a temporary condition which will be
+ alleviated after some delay. If known, the length of the delay may be
+ indicated in the message. If no delay is given, the IPP application
+ should handle the response as it would for a "server-error-
+ temporary-error" response. If the condition is more permanent, the
+ error status codes "client-error-gone" or "client-error-not-found"
+ could be used.
+
+13.1.5.4 server-error-version-not-supported (0x0503)
+
+ The IPP object does not support, or refuses to support, the IPP
+ protocol version that was supplied as the value of the "version-
+ number" operation parameter in the request. The IPP object is
+ indicating that it is unable or unwilling to complete the request
+ using the same major and minor version number as supplied in the
+ request other than with this error message. The error response SHOULD
+ contain a "status-message" attribute (see section 3.1.6.2) describing
+
+
+
+
+Hastings, et al. Standards Track [Page 185]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ why that version is not supported and what other versions are
+ supported by that IPP object. See sections 3.1.6.1, 3.1.7, and
+ 3.1.8.
+
+ The error response MUST identify in the "version-number" operation
+ parameter the closest version number that the IPP object does
+ support. For example, if a client supplies version '1.0' and an
+ IPP/1.1 object supports version '1.0', then it responds with version
+ '1.0' in all responses to such a request. If the IPP/1.1 object does
+ not support version '1.0', then it should accept the request and
+ respond with version '1.1' or may reject the request and respond with
+ this error code and version
+ '1.1'. If a client supplies a version '1.2', the IPP/1.1 object
+ should accept the request and return version '1.1' or may reject the
+ request and respond with this error code and version '1.1'. See
+ sections 3.1.8 and 4.4.14.
+
+13.1.5.5 server-error-device-error (0x0504)
+
+ A printer error, such as a paper jam, occurs while the IPP object
+ processes a Print or Send operation. The response contains the true
+ Job Status (the values of the "job-state" and "job-state-reasons"
+ attributes). Additional information can be returned in the OPTIONAL
+ "job-state-message" attribute value or in the OPTIONAL status message
+ that describes the error in more detail. This error status code is
+ only returned in situations where the Printer is unable to accept the
+ create request because of such a device error. For example, if the
+ Printer is unable to spool, and can only accept one job at a time,
+ the reason it might reject a create request is that the printer
+ currently has a paper jam. In many cases however, where the Printer
+ object can accept the request even though the Printer has some error
+ condition, the 'successful-ok' status code will be returned. In such
+ a case, the client would look at the returned Job Object Attributes
+ or later query the Printer to determine its state and state reasons.
+
+13.1.5.6 server-error-temporary-error (0x0505)
+
+ A temporary error such as a buffer full write error, a memory
+ overflow (i.e. the document data exceeds the memory of the Printer),
+ or a disk full condition, occurs while the IPP Printer processes an
+ operation. The client MAY try the unmodified request again at some
+ later point in time with an expectation that the temporary internal
+ error condition may have been cleared. Alternatively, as an
+ implementation option, a Printer object MAY delay the response until
+ the temporary condition is cleared so that no error is returned.
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 186]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+13.1.5.7 server-error-not-accepting-jobs (0x0506)
+
+ A temporary error indicating that the Printer is not currently
+ accepting jobs, because the administrator has set the value of the
+ Printer's "printer-is-accepting-jobs" attribute to 'false' (by means
+ outside the scope of this IPP/1.1 document).
+
+13.1.5.8 server-error-busy (0x0507)
+
+ A temporary error indicating that the Printer is too busy processing
+ jobs and/or other requests. The client SHOULD try the unmodified
+ request again at some later point in time with an expectation that
+ the temporary busy condition will have been cleared.
+
+13.1.5.9 server-error-job-canceled (0x0508)
+
+ An error indicating that the job has been canceled by an operator or
+ the system while the client was transmitting the data to the IPP
+ Printer. If a job-id and job-uri had been created, then they are
+ returned in the Print-Job, Send-Document, or Send-URI response as
+ usual; otherwise, no job-id and job-uri are returned in the response.
+
+13.1.5.10 server-error-multiple-document-jobs-not-supported (0x0509)
+
+ The IPP object does not support multiple documents per job and a
+ client attempted to supply document data with a second Send-Document
+ or Send-URI operation.
+
+13.2 Status Codes for IPP Operations
+
+ PJ = Print-Job, PU = Print-URI, CJ = Create-Job, SD = Send-Document
+ SU = Send-URI, V = Validate-Job, GA = Get-Job-Attributes and
+ Get-Printer-Attributes, GJ = Get-Jobs, C = Cancel-Job
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 187]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ IPP Operations
+ IPP Status Keyword PJ PU CJ SD SU V GA GJ C
+ ------------------ -- -- -- -- -- - -- -- -
+ successful-ok x x x x x x x x x
+ successful-ok-ignored-or-substituted- x x x x x x x x x
+ attributes
+ successful-ok-conflicting-attributes x x x x x x x x x
+ client-error-bad-request x x x x x x x x x
+ client-error-forbidden x x x x x x x x x
+ client-error-not-authenticated x x x x x x x x x
+ client-error-not-authorized x x x x x x x x x
+ client-error-not-possible x x x x x x x x x
+ client-error-timeout x x
+ client-error-not-found x x x x x x x x x
+ client-error-gone x x x x x x x x x
+ client-error-request-entity-too-large x x x x x x x x x
+ client-error-request-value-too-long x x x x x x x x x
+ client-error-document-format-not- x x x x x x
+ supported
+ client-error-attributes-or-values-not- x x x x x x x x x
+ supported
+ client-error-uri-scheme-not-supported x x
+ client-error-charset-not-supported x x x x x x x x x
+ client-error-conflicting-attributes x x x x x x x x x
+ client-error-compression-not-supported x x x x x
+ client-error-compression-error x x x x
+ client-error-document-format-error x x x x
+ client-error-document-access-error x x
+ server-error-internal-error x x x x x x x x x
+ server-error-operation-not-supported x x x x
+ server-error-service-unavailable x x x x x x x x x
+ server-error-version-not-supported x x x x x x x x x
+ server-error-device-error x x x x x
+ server-error-temporary-error x x x x x
+ server-error-not-accepting-jobs x x x x
+ server-error-busy x x x x x x x x x
+ server-error-job-canceled x x x
+ server-error-multiple-document-jobs- x x
+ not-supported
+
+ HJ = Hold-Job, RJ = Release-Job, RS = Restart-Job
+ PP = Pause-Printer, RP = Resume-Printer, PJ = Purge-Jobs
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 188]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ IPP Operations (cont.)
+ IPP Status Keyword HJ RJ RS PP RP PJ
+ ------------------ -- -- -- -- -- --
+ successful-ok x x x x x x
+ successful-ok-ignored-or-substituted- x x x x x x
+ attributes
+ successful-ok-conflicting-attributes x x x x x x
+ client-error-bad-request x x x x x x
+ client-error-forbidden x x x x x x
+ client-error-not-authenticated x x x x x x
+ client-error-not-authorized x x x x x x
+ client-error-not-possible x x x x x x
+ client-error-timeout
+ client-error-not-found x x x x x x
+ client-error-gone x x x x x x
+ client-error-request-entity-too-large x x x x x x
+ client-error-request-value-too-long x x x x x x
+ client-error-document-format-not-
+ supported
+ client-error-attributes-or-values-not- x x x x x x
+ supported
+ client-error-uri-scheme-not-supported
+ client-error-charset-not-supported x x x x x x
+ client-error-conflicting-attributes x x x x x x
+ client-error-compression-not-supported
+ client-error-compression-error
+ client-error-document-format-error
+ client-error-document-access-error
+ server-error-internal-error x x x x x x
+ server-error-operation-not-supported x x x x x x
+ server-error-service-unavailable x x x x x x
+ server-error-version-not-supported x x x x x x
+ server-error-device-error
+ server-error-temporary-error x x x x x x
+ server-error-not-accepting-jobs
+ server-error-busy x x x x x x
+ server-error-job-canceled
+ server-error-multiple-document-jobs-
+ not-supported
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 189]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+14. APPENDIX C: "media" keyword values
+
+ Standard keyword values are taken from several sources.
+
+ Standard values are defined (taken from DPA[ISO10175] and the Printer
+ MIB[RFC1759]):
+
+ 'default': The default medium for the output device
+ 'iso-a4-white': Specifies the ISO A4 white medium: 210 mm x 297 mm
+ 'iso-a4-colored': Specifies the ISO A4 colored medium: 210 mm x 297
+ mm
+ 'iso-a4-transparent' Specifies the ISO A4 transparent medium: 210 mm
+ x 297 mm
+ 'iso-a3-white': Specifies the ISO A3 white medium: 297 mm x 420 mm
+ 'iso-a3-colored': Specifies the ISO A3 colored medium: 297 mm x 420
+ mm
+ 'iso-a5-white': Specifies the ISO A5 white medium: 148 mm x 210 mm
+ 'iso-a5-colored': Specifies the ISO A5 colored medium: 148 mm x 210
+ mm
+ 'iso-b4-white': Specifies the ISO B4 white medium: 250 mm x 353 mm
+ 'iso-b4-colored': Specifies the ISO B4 colored medium: 250 mm x 353
+ mm
+ 'iso-b5-white': Specifies the ISO B5 white medium: 176 mm x 250 mm
+ 'iso-b5-colored': Specifies the ISO B5 colored medium: 176 mm x 250
+ mm
+ 'jis-b4-white': Specifies the JIS B4 white medium: 257 mm x 364 mm
+ 'jis-b4-colored': Specifies the JIS B4 colored medium: 257 mm x 364
+ mm
+ 'jis-b5-white': Specifies the JIS B5 white medium: 182 mm x 257 mm
+ 'jis-b5-colored': Specifies the JIS B5 colored medium: 182 mm x 257
+ mm
+
+ The following standard values are defined for North American media:
+
+ 'na-letter-white': Specifies the North American letter white medium
+ 'na-letter-colored': Specifies the North American letter colored
+ medium
+ 'na-letter-transparent': Specifies the North American letter
+ transparent medium
+ 'na-legal-white': Specifies the North American legal white medium
+ 'na-legal-colored': Specifies the North American legal colored
+ medium
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 190]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The following standard values are defined for envelopes:
+
+ 'iso-b4-envelope': Specifies the ISO B4 envelope medium
+ 'iso-b5-envelope': Specifies the ISO B5 envelope medium
+ 'iso-c3-envelope': Specifies the ISO C3 envelope medium
+ 'iso-c4-envelope': Specifies the ISO C4 envelope medium
+ 'iso-c5-envelope': Specifies the ISO C5 envelope medium
+ 'iso-c6-envelope': Specifies the ISO C6 envelope medium
+ 'iso-designated-long-envelope': Specifies the ISO Designated Long
+ envelope medium
+ 'na-10x13-envelope': Specifies the North American 10x13 envelope
+ medium
+ 'na-9x12-envelope': Specifies the North American 9x12 envelope
+ medium
+ 'monarch-envelope': Specifies the Monarch envelope
+ 'na-number-10-envelope': Specifies the North American number 10
+ business envelope medium
+ 'na-7x9-envelope': Specifies the North American 7x9 inch envelope
+ 'na-9x11-envelope': Specifies the North American 9x11 inch
+ envelope
+ 'na-10x14-envelope': Specifies the North American 10x14 inch
+ envelope
+ 'na-number-9-envelope': Specifies the North American number 9
+ business envelope
+ 'na-6x9-envelope': Specifies the North American 6x9 inch envelope
+ 'na-10x15-envelope': Specifies the North American 10x15 inch
+ envelope
+
+ The following standard values are defined for the less commonly used
+ media:
+
+ 'executive-white': Specifies the white executive medium
+ 'folio-white': Specifies the folio white medium
+ 'invoice-white': Specifies the white invoice medium
+ 'ledger-white': Specifies the white ledger medium
+ 'quarto-white': Specified the white quarto medium
+ 'iso-a0-white': Specifies the ISO A0 white medium: 841 mm x 1189 mm
+ 'iso-a0-transparent': Specifies the ISO A0 transparent medium: 841 mm
+ x 1189 mm
+ 'iso-a0-translucent': Specifies the ISO A0 translucent medium: 841 mm
+ x 1189 mm
+ 'iso-a1-white': Specifies the ISO A1 white medium: 594 mm x 841 mm
+ 'iso-a1-transparent': Specifies the ISO A1 transparent medium: 594 mm
+ x 841 mm
+ 'iso-a1-translucent': Specifies the ISO A1 translucent medium: 594 mm
+ x 841 mm
+ 'iso-a2-white': Specifies the ISO A2 white medium: 420 mm x 594 mm
+
+
+
+
+Hastings, et al. Standards Track [Page 191]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'iso-a2-transparent': Specifies the ISO A2 transparent medium: 420 mm
+ x 594 mm
+ 'iso-a2-translucent': Specifies the ISO A2 translucent medium: 420 mm
+ x 594 mm
+ 'iso-a3-transparent': Specifies the ISO A3 transparent medium: 297 mm
+ x 420 mm
+ 'iso-a3-translucent': Specifies the ISO A3 translucent medium: 297 mm
+ x 420 mm
+ 'iso-a4-translucent': Specifies the ISO A4 translucent medium: 210 mm
+ x 297 mm
+ 'iso-a5-transparent': Specifies the ISO A5 transparent medium: 148 mm
+ x 210 mm
+ 'iso-a5-translucent': Specifies the ISO A5 translucent medium: 148 mm
+ x 210 mm
+ 'iso-a6-white': Specifies the ISO A6 white medium: 105 mm x 148 mm
+ 'iso-a7-white': Specifies the ISO A7 white medium: 74 mm x 105 mm
+ 'iso-a8-white': Specifies the ISO A8 white medium: 52 mm x 74 mm
+ 'iso-a9-white': Specifies the ISO A9 white medium: 37 mm x 52 mm
+ 'iso-a10-white': Specifies the ISO A10 white medium: 26 mm x 37 mm
+ 'iso-b0-white': Specifies the ISO B0 white medium: 1000 mm x 1414 mm
+ 'iso-b1-white': Specifies the ISO B1 white medium: 707 mm x 1000 mm
+ 'iso-b2-white': Specifies the ISO B2 white medium: 500 mm x 707 mm
+ 'iso-b3-white': Specifies the ISO B3 white medium: 353 mm x 500 mm
+ 'iso-b6-white': Specifies the ISO B6 white medium: 125 mm x 176 mm
+ 'iso-b7-white': Specifies the ISO B7 white medium: 88 mm x 125 mm
+ 'iso-b8-white': Specifies the ISO B8 white medium: 62 mm x 88 mm
+ 'iso-b9-white': Specifies the ISO B9 white medium: 44 mm x 62 mm
+ 'iso-b10-white': Specifies the ISO B10 white medium: 31 mm x 44 mm
+ 'jis-b0-white': Specifies the JIS B0 white medium: 1030 mm x 1456 mm
+ 'jis-b0-transparent': Specifies the JIS B0 transparent medium: 1030
+ mm x 1456 mm
+ 'jis-b0-translucent': Specifies the JIS B0 translucent medium: 1030
+ mm x 1456 mm
+ 'jis-b1-white': Specifies the JIS B1 white medium: 728 mm x 1030 mm
+ 'jis-b1-transparent': Specifies the JIS B1 transparent medium: 728 mm
+ x 1030 mm
+ 'jis-b1-translucent': Specifies the JIS B1 translucent medium: 728 mm
+ x 1030 mm
+ 'jis-b2-white': Specifies the JIS B2 white medium: 515 mm x 728 mm
+ 'jis-b2-transparent': Specifies the JIS B2 transparent medium: 515 mm
+ x 728 mm
+ 'jis-b2-translucent': Specifies the JIS B2 translucent medium: 515 mm
+ x 728 mm
+ 'jis-b3-white': Specifies the JIS B3 white medium: 364 mm x 515 mm
+ 'jis-b3-transparent': Specifies the JIS B3 transparent medium: 364 mm
+ x 515 mm
+ 'jis-b3-translucent': Specifies the JIS B3 translucent medium: 364 mm
+ x 515 mm
+
+
+
+Hastings, et al. Standards Track [Page 192]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'jis-b4-transparent': Specifies the JIS B4 transparent medium: 257 mm
+ x 364 mm
+ 'jis-b4-translucent': Specifies the JIS B4 translucent medium: 257 mm
+ x 364 mm
+ 'jis-b5-transparent': Specifies the JIS B5 transparent medium: 182 mm
+ x 257 mm
+ 'jis-b5-translucent': Specifies the JIS B5 translucent medium: 182 mm
+ x 257 mm
+ 'jis-b6-white': Specifies the JIS B6 white medium: 128 mm x 182 mm
+ 'jis-b7-white': Specifies the JIS B7 white medium: 91 mm x 128 mm
+ 'jis-b8-white': Specifies the JIS B8 white medium: 64 mm x 91 mm
+ 'jis-b9-white': Specifies the JIS B9 white medium: 45 mm x 64 mm
+ 'jis-b10-white': Specifies the JIS B10 white medium: 32 mm x 45 mm
+
+ The following standard values are defined for American Standard (i.e.
+ ANSI) engineering media:
+
+ 'a-white': Specifies the engineering ANSI A size white medium: 8.5
+ inches x 11 inches
+ 'a-transparent': Specifies the engineering ANSI A size transparent
+ medium: 8.5 inches x 11 inches
+ 'a-translucent': Specifies the engineering ANSI A size translucent
+ medium: 8.5 inches x 11 inches
+ 'b-white': Specifies the engineering ANSI B size white medium: 11
+ inches x 17 inches
+ 'b-transparent': Specifies the engineering ANSI B size transparent
+ medium: 11 inches x 17 inches)
+ 'b-translucent': Specifies the engineering ANSI B size translucent
+ medium: 11 inches x 17 inches
+ 'c-white': Specifies the engineering ANSI C size white medium: 17
+ inches x 22 inches
+ 'c-transparent': Specifies the engineering ANSI C size transparent
+ medium: 17 inches x 22 inches
+ 'c-translucent': Specifies the engineering ANSI C size translucent
+ medium: 17 inches x 22 inches
+ 'd-white': Specifies the engineering ANSI D size white medium: 22
+ inches x 34 inches
+ 'd-transparent': Specifies the engineering ANSI D size transparent
+ medium: 22 inches x 34 inches
+ 'd-translucent': Specifies the engineering ANSI D size translucent
+ medium: 22 inches x 34 inches
+ 'e-white': Specifies the engineering ANSI E size white medium: 34
+ inches x 44 inches
+ 'e-transparent': Specifies the engineering ANSI E size transparent
+ medium: 34 inches x 44 inches
+ 'e-translucent': Specifies the engineering ANSI E size translucent
+ medium: 34 inches x 44 inches
+
+
+
+
+Hastings, et al. Standards Track [Page 193]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The following standard values are defined for American Standard (i.e.
+ ANSI) engineering media for devices that provide the "synchro-cut"
+ feature (see section 14.1):
+
+ 'axsynchro-white': Specifies the roll paper having the width of the
+ longer edge (11 inches) of the engineering ANSI A size white medium
+ and cuts synchronizing with data.
+ 'axsynchro-transparent': Specifies the roll paper having the width of
+ the longer edge (11 inches) of the engineering ANSI A size
+ transparent medium and cuts synchronizing with data.
+ 'axsynchro-translucent': Specifies the roll paper having the width of
+ the longer edge (11 inches) of the engineering ANSI A size
+ translucent medium and cuts synchronizing with data.
+ 'bxsynchro-white': Specifies the roll paper having the width of the
+ longer edge (17 inches) of the engineering ANSI B size white medium
+ and cuts synchronizing with data.
+ 'bxsynchro-transparent': Specifies the roll paper having the width of
+ the longer edge (17 inches) of the engineering ANSI B size
+ transparent medium and cuts synchronizing with data.
+ 'bxsynchro-translucent': Specifies the roll paper having the width of
+ the longer edge (17 inches) of the engineering ANSI B size
+ translucent medium and cuts synchronizing with data.
+ 'cxsynchro-white': Specifies the roll paper having the width of the
+ longer edge (22 inches) of the engineering ANSI C size white medium
+ and cuts synchronizing with data.
+ 'cxsynchro-transparent': Specifies the roll paper having the width of
+ the longer edge (22 inches) of the engineering ANSI C size
+ transparent medium and cuts synchronizing with data.
+ 'cxsynchro-translucent': Specifies the roll paper having the width of
+ the longer edge (22 inches) of the engineering ANSI C size
+ translucent medium and cuts synchronizing with data.
+ 'dxsynchro-white': Specifies the roll paper having the width of the
+ longer edge (34 inches) of the engineering ANSI D size white medium
+ and cuts synchronizing with data.
+ 'dxsynchro-transparent': Specifies the roll paper having the width of
+ the longer edge (34 inches) of the engineering ANSI D size
+ transparent medium and cuts synchronizing with data.
+ 'dxsynchro-translucent': Specifies the roll paper having the width of
+ the longer edge (34 inches) of the engineering ANSI D size
+ translucent medium and cuts synchronizing with data.
+ 'exsynchro-white': Specifies the roll paper having the width of the
+ longer edge (44 inches) of the engineering ANSI E size white medium
+ and cuts synchronizing with data.
+ 'exsynchro-transparent': Specifies the roll paper having the width of
+ the longer edge (44 inches) of the engineering ANSI E size
+ transparent medium and cuts synchronizing with data.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 194]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'exsynchro-translucent': Specifies the roll paper having the width of
+ the longer edge (44 inches) of the engineering ANSI E size
+ translucent medium and cuts synchronizing with data.
+
+ The following standard values are defined for American Architectural
+ engineering media:
+
+ 'arch-a-white': Specifies the Architectural A size white medium: 9
+ inches x 12 inches
+ 'arch-a-transparent': Specifies the Architectural A size transparent
+ medium: 9 inches x 12 inches
+ 'arch-a-translucent': Specifies the Architectural A size translucent
+ medium: 9 inches x 12 inches
+ 'arch-b-white': Specifies the Architectural B size white medium: 12
+ inches x 18 inches
+ 'arch-b-transparent': Specifies the Architectural B size transparent
+ medium: 12 inches x 18 inches
+ 'arch-b-translucent': Specifies the Architectural B size translucent
+ medium: 12 inches x 18 inches
+ 'arch-c-white': Specifies the Architectural C size white medium: 18
+ inches x 24 inches
+ 'arch-c-transparent': Specifies the Architectural C size transparent
+ medium: 18 inches x 24 inches
+ 'arch-c-translucent': Specifies the Architectural C size translucent
+ medium: 18 inches x 24 inches
+ 'arch-d-white': Specifies the Architectural D size white medium: 24
+ inches x 36 inches
+ 'arch-d-transparent': Specifies the Architectural D size transparent
+ medium: 24 inches x 36 inches
+ 'arch-d-translucent': Specifies the Architectural D size translucent
+ medium: 24 inches x 36 inches
+ 'arch-e-white': Specifies the Architectural E size white medium: 36
+ inches x 48 inches
+ 'arch-e-transparent': Specifies the Architectural E size transparent
+ medium: 36 inches x 48 inches
+ 'arch-e-translucent': Specifies the Architectural E size translucent
+ medium: 36 inches x 48 inches
+
+ The following standard values are defined for American Architectural
+ engineering media for devices that provide the "synchro-cut" feature
+ (see section 14.1):
+
+ 'arch-axsynchro-white': Specifies the roll paper having the width of
+ the longer edge (12 inches) of the Architectural A size white
+ medium and cuts synchronizing with data.
+ 'arch-axsynchro-transparent': Specifies the roll paper having the
+ width of the longer edge (12 inches) of the Architectural A size
+ transparent medium and cuts synchronizing with data.
+
+
+
+Hastings, et al. Standards Track [Page 195]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'arch-axsynchro-translucent': Specifies the roll paper having the
+ width of the longer edge (12 inches) of the Architectural A size
+ translucent medium and cuts synchronizing with data.
+ 'arch-bxsynchro-white': Specifies the roll paper having the width of
+ the longer edge (18 inches) of the Architectural B size white
+ medium and cuts synchronizing with data.
+ 'arch-bxsynchro-transparent': Specifies the roll paper having the
+ width of the longer edge (18 inches) of the Architectural B size
+ transparent medium and cuts synchronizing with data.
+ 'arch-bxsynchro-translucent': Specifies the roll paper having the
+ width of the longer edge (18 inches) of the Architectural B size
+ translucent medium and cuts synchronizing with data.
+ 'arch-cxsynchro-white': Specifies the roll paper having the width of
+ the longer edge (24 inches) of the Architectural C size white
+ medium and cuts synchronizing with data.
+ 'arch-cxsynchro-transparent': Specifies the roll paper having the
+ width of the longer edge (24 inches) of the Architectural C size
+ transparent medium and cuts synchronizing with data.
+ 'arch-cxsynchro-translucent': Specifies the roll paper having the
+ width of the longer edge (24 inches) of the Architectural C size
+ translucent medium and cuts synchronizing with data.
+ 'arch-dxsynchro-white': Specifies the roll paper having the width of
+ the longer edge (36 inches) of the Architectural D size white
+ medium and cuts synchronizing with data.
+ 'arch-dxsynchro-transparent': Specifies the roll paper having the
+ width of the longer edge (36 inches) of the Architectural D size
+ transparent medium and cuts synchronizing with data.
+ 'arch-dxsynchro-translucent': Specifies the roll paper having the
+ width of the longer edge (36 inches) of the Architectural D size
+ translucent medium and cuts synchronizing with data.
+ 'arch-exsynchro-white': Specifies the roll paper having the width of
+ the longer edge (48 inches) of the Architectural E size white
+ medium and cuts synchronizing with data.
+ 'arch-exsynchro-transparent': Specifies the roll paper having the
+ width of the longer edge (48 inches) of the Architectural E size
+ transparent medium and cuts synchronizing with data.
+ 'arch-exsynchro-translucent': Specifies the roll paper having the
+ width of the longer edge (48 inches) of the Architectural E size
+ translucent medium and cuts synchronizing with data.
+
+ The following standard values are defined for Japanese and European
+ Standard (i.e. ISO) engineering media, which are of a long fixed size
+ [ASME-Y14.1M]:
+
+ 'iso-a1x3-white': Specifies the ISO A1X3 white medium having the
+ width of the longer edge (841 mm) of the ISO A1 medium
+
+
+
+
+
+Hastings, et al. Standards Track [Page 196]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'iso-a1x3-transparent': Specifies the ISO A1X3 transparent medium
+ having the width of the longer edge (841 mm) of the ISO A1
+ medium
+ 'iso-a1x3-translucent': Specifies the ISO A1X3 translucent medium
+ having the width of the longer edge (841 mm) of the ISO A1
+ medium
+ 'iso-a1x4-white': Specifies the ISO A1X4 white medium having the
+ width of the longer edge (841 mm) of the ISO A1 medium
+ 'iso-a1x4-transparent': Specifies the ISO A1X4 transparent medium
+ having the width of the longer edge (841 mm) of the ISO A1
+ medium
+ 'iso-a1x4- translucent': Specifies the ISO A1X4 translucent medium
+ having the width of the longer edge (841 mm) of the ISO A1
+ medium
+ 'iso-a2x3-white': Specifies the ISO A2X3 white medium having the
+ width of the longer edge (594 mm) of the ISO A2 medium
+ 'iso-a2x3-transparent': Specifies the ISO A2X3 transparent medium
+ having the width of the longer edge (594 mm) of the ISO A2
+ medium
+ 'iso-a2x3-translucent': Specifies the ISO A2X3 translucent medium
+ having the width of the longer edge (594 mm) of the ISO A2
+ medium
+ 'iso-a2x4-white': Specifies the ISO A2X4 white medium having the
+ width of the longer edge (594 mm) of the ISO A2 medium
+ 'iso-a2x4-transparent': Specifies the ISO A2X4 transparent medium
+ having the width of the longer edge (594 mm) of the ISO A2
+ medium
+ 'iso-a2x4-translucent': Specifies the ISO A2X4 translucent medium
+ having the width of the longer edge (594 mm) of the ISO A2
+ medium
+ 'iso-a2x5-white': Specifies the ISO A2X5 white medium having the
+ width of the longer edge (594 mm) of the ISO A2 medium
+ 'iso-a2x5-transparent': Specifies the ISO A2X5 transparent medium
+ having the width of the longer edge (594 mm) of the ISO A2
+ medium
+ 'iso-a2x5-translucent': Specifies the ISO A2X5 translucent medium
+ having the width of the longer edge (594 mm) of the ISO A2
+ medium
+ 'iso-a3x3-white': Specifies the ISO A3X3 white medium having the
+ width of the longer edge (420 mm) of the ISO A3 medium
+ 'iso-a3x3-transparent': Specifies the ISO A3X3 transparent medium
+ having the width of the longer edge (420 mm) of the ISO A3
+ medium
+ 'iso-a3x3-translucent': Specifies the ISO A3X3 translucent medium
+ having the width of the longer edge (420 mm) of the ISO A3
+ medium
+ 'iso-a3x4-white': Specifies the ISO A3X4 white medium having the
+ width of the longer edge (420 mm) of the ISO A3 medium
+
+
+
+Hastings, et al. Standards Track [Page 197]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'iso-a3x4-transparent': Specifies the ISO A3X4 transparent medium
+ having the width of the longer edge (420 mm) of the ISO A3
+ medium
+ 'iso-a3x4-translucent': Specifies the ISO A3X4 translucent medium
+ having the width of the longer edge (420 mm) of the ISO A3
+ medium
+ 'iso-a3x5-white': Specifies the ISO A3X5 white medium having the
+ width of the longer edge (420 mm) of the ISO A3 medium
+ 'iso-a3x5-transparent': Specifies the ISO A3X5 transparent medium
+ having the width of the longer edge (420 mm) of the ISO A3
+ medium
+ 'iso-a3x5-translucent': Specifies the ISO A3X5 translucent medium
+ having the width of the longer edge (420 mm) of the ISO A3
+ medium
+ 'iso-a3x6-white': Specifies the ISO A3X6 white medium having the
+ width of the longer edge (420 mm) of the ISO A3 medium
+ 'iso-a3x6-transparent': Specifies the ISO A3X6 transparent medium
+ having the width of the longer edge (420 mm) of the ISO A3
+ medium
+ 'iso-a3x6-translucent': Specifies the ISO A3X6 translucent medium
+ having the width of the longer edge (420 mm) of the ISO A3
+ medium
+ 'iso-a3x7-white': Specifies the ISO A3X7 white medium having the
+ width of the longer edge (420 mm) of the ISO A3 medium
+ 'iso-a3x7-transparent': Specifies the ISO A3X7 transparent medium
+ having the width of the longer edge (420 mm) of the ISO A3
+ medium
+ 'iso-a3x7-translucent'': Specifies the ISO A3X7 translucent' medium
+ having the width of the longer edge (420 mm) of the ISO A3
+ medium
+ 'iso-a4x3-white': Specifies the ISO A4X3 white medium having the
+ width of the longer edge (297 mm) of the ISO A4 medium
+ 'iso-a4x3-transparent': Specifies the ISO A4X3 transparent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x3-translucent'': Specifies the ISO A4X3 translucent' medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x4-white': Specifies the ISO A4X4 white medium having the
+ width of the longer edge (297 mm) of the ISO A4 medium
+ 'iso-a4x4-transparent': Specifies the ISO A4X4 transparent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x4-translucent': Specifies the ISO A4X4 translucent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x5-white': Specifies the ISO A4X5 white medium having the
+ width of the longer edge (297 mm) of the ISO A4 medium
+
+
+
+Hastings, et al. Standards Track [Page 198]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'iso-a4x5-transparent': Specifies the ISO A4X5 transparent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x5-translucent': Specifies the ISO A4X5 translucent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x6-white': Specifies the ISO A4X6 white medium having the
+ width of the longer edge (297 mm) of the ISO A4 medium
+ 'iso-a4x6-transparent': Specifies the ISO A4X6 transparent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x6-translucent': Specifies the ISO A4X6 translucent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x7-white': Specifies the ISO A4X7 white medium having the
+ width of the longer edge (297 mm) of the ISO A4 medium
+ 'iso-a4x7-transparent': Specifies the ISO A4X7 transparent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x7-translucent': Specifies the ISO A4X7 translucent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x8-white': Specifies the ISO A4X8 white medium having the
+ width of the longer edge (297 mm) of the ISO A4 medium
+ 'iso-a4x8-transparent': Specifies the ISO A4X8 transparent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x8-translucent': Specifies the ISO A4X8 translucent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x9-white': Specifies the ISO A4X9 white medium having the
+ width of the longer edge (297 mm) of the ISO A4 medium
+ 'iso-a4x9-transparent': Specifies the ISO A4X9 transparent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+ 'iso-a4x9-translucent': Specifies the ISO A4X9 translucent medium
+ having the width of the longer edge (297 mm) of the ISO A4
+ medium
+
+ The following standard values are defined for Japanese and European
+ Standard (i.e. ISO) engineering media, which are either a long fixed
+ size [ASME-Y14.1M] or roll feed, for devices that provide the
+ "synchro-cut" feature (see section 14.1):
+
+ 'iso-a0xsynchro-white': Specifies the paper having the width of the
+ longer edge (1189 mm) of the ISO A0 white medium and cuts
+ synchronizing with data.
+
+
+
+
+Hastings, et al. Standards Track [Page 199]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'iso-a0xsynchro-transparent': Specifies the paper having the width of
+ the longer edge (1189 mm) of the ISO A0 transparent medium and
+ cuts synchronizing with data.
+ 'iso-a0xsynchro-translucent': Specifies the paper having the width of
+ the longer edge (1189 mm) of the ISO A0 translucent medium and
+ cuts synchronizing with data.
+ 'iso-a1xsynchro-white': Specifies the paper having the width of the
+ longer edge (841 mm) of the ISO A1 white medium and cuts
+ synchronizing with data.
+ 'iso-a1xsynchro-transparent': Specifies the paper having the width of
+ the longer edge (841 mm) of the ISO A1 transparent medium and
+ cuts synchronizing with data.
+ 'iso-a1xsynchro-translucent': Specifies the paper having the width of
+ the longer edge (841 mm) of the ISO A1 translucent medium and
+ cuts synchronizing with data.
+ 'iso-a2xsynchro-white': Specifies the paper having the width of the
+ longer edge (594 mm) of the ISO A2 white medium and cuts
+ synchronizing with data.
+ 'iso-a2xsynchro-transparent': Specifies the paper having the width of
+ the longer edge (594 mm) of the ISO A2 transparent medium and
+ cuts synchronizing with data.
+ 'iso-a2xsynchro-translucent': Specifies the paper having the width of
+ the longer edge (594 mm) of the ISO A2 translucent medium and
+ cuts synchronizing with data.
+ 'iso-a3xsynchro-white': Specifies the paper having the width of the
+ longer edge (420 mm) of the ISO A3 white medium and cuts
+ synchronizing with data.
+ 'iso-a3xsynchro-transparent': Specifies the paper having the width of
+ the longer edge (420 mm) of the ISO A3 transparent medium and
+ cuts synchronizing with data.
+ 'iso-a3xsynchro-translucent': Specifies the paper having the width of
+ the longer edge (420 mm) of the ISO A3 translucent medium and
+ cuts synchronizing with data.
+ 'iso-a4xsynchro-white': Specifies the paper having the width of the
+ longer edge (297 mm) of the ISO A4 white medium and cuts
+ synchronizing with data.
+ 'iso-a4xsynchro-transparent': Specifies the paper having the width of
+ the longer edge (297 mm) of the ISO A4 transparent medium and
+ cuts synchronizing with data.
+ 'iso-a4xsynchro-translucent': Specifies the paper having the width of
+ the longer edge (297 mm) of the ISO A4 transparent medium and
+ cuts synchronizing with data.
+
+ The following standard values are defined for American Standard (i.e.
+ ANSI) engineering media, American Architectural engineering media,
+ and Japanese and European Standard (i.e. ISO) engineering media,
+
+
+
+
+
+Hastings, et al. Standards Track [Page 200]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ which are either a long fixed size [ASME-Y14.1M] or roll feed, for
+ devices that provide the "synchro-cut" feature and/or the "auto-
+ select" feature (see section 14.1):
+
+ 'auto-white': Specifies that the printer selects the white medium
+ with the appropriate fixed size (e.g. a1, a2, etc.) or data-
+ synchro size, and the selection is implementation-defined.
+ 'auto-transparent': Specifies that the printer selects the
+ transparent medium with the appropriate fixed size (e.g. a1, a2,
+ etc.) or data-synchro size, and the selection is implementation-
+ defined.
+ 'auto-translucent': Specifies that the printer selects the
+ translucent medium with the appropriate fixed size (e.g. a1, a2,
+ etc.) or data-synchro size, and the selection is implementation-
+ defined.
+ 'auto-fixed-size-white': Specifies that the printer selects the white
+ medium with the appropriate fixed size (e.g. a1, a2, etc.) or
+ the appropriate long fixed size listed above.
+ 'auto-fixed-size-transparent': Specifies that the printer selects the
+ transparent medium with the appropriate fixed size (e.g. a1, a2,
+ etc.) or the appropriate long fixed size listed above.
+ 'auto-fixed-size-translucent': Specifies that the printer selects the
+ translucent medium with the appropriate fixed size (e.g. a1, a2,
+ etc.) or the appropriate long fixed size listed above.
+ 'auto-synchro-white': Specifies that the printer selects the white
+ paper with the appropriate width and cuts it synchronizing with
+ data.
+ 'auto-synchro-transparent': Specifies that the printer selects the
+ transparent paper with the appropriate width and cuts it
+ synchronizing with data.
+ 'auto-synchro-translucent': Specifies that the printer selects the
+ translucent paper with the appropriate width and cuts it
+ synchronizing with data.
+
+ The following standard values are defined for input-trays (from ISO
+ DPA and the Printer MIB):
+
+ 'top': The top input tray in the printer.
+ 'middle': The middle input tray in the printer.
+ 'bottom': The bottom input tray in the printer.
+ 'envelope': The envelope input tray in the printer.
+ 'manual': The manual feed input tray in the printer.
+ 'large-capacity': The large capacity input tray in the printer.
+ 'main': The main input tray
+ 'side': The side input tray
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 201]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The following standard values are defined for media sizes (from ISO
+ DPA):
+
+ 'iso-a0': Specifies the ISO A0 size: 841 mm by 1189 mm as defined in
+ ISO 216
+ 'iso-a1': Specifies the ISO A1 size: 594 mm by 841 mm as defined in
+ ISO 216
+ 'iso-a2': Specifies the ISO A2 size: 420 mm by 594 mm as defined in
+ ISO 216
+ 'iso-a3': Specifies the ISO A3 size: 297 mm by 420 mm as defined in
+ ISO 216
+ 'iso-a4': Specifies the ISO A4 size: 210 mm by 297 mm as defined in
+ ISO 216
+ 'iso-a5': Specifies the ISO A5 size: 148 mm by 210 mm as defined in
+ ISO 216
+ 'iso-a6': Specifies the ISO A6 size: 105 mm by 148 mm as defined in
+ ISO 216
+ 'iso-a7': Specifies the ISO A7 size: 74 mm by 105 mm as defined in
+ ISO 216
+ 'iso-a8': Specifies the ISO A8 size: 52 mm by 74 mm as defined in ISO
+ 216
+ 'iso-a9': Specifies the ISO A9 size: 37 mm by 52 mm as defined in ISO
+ 216
+ 'iso-a10': Specifies the ISO A10 size: 26 mm by 37 mm as defined in
+ ISO 216
+ 'iso-b0': Specifies the ISO B0 size: 1000 mm by 1414 mm as defined in
+ ISO 216
+ 'iso-b1': Specifies the ISO B1 size: 707 mm by 1000 mm as defined in
+ ISO 216
+ 'iso-b2': Specifies the ISO B2 size: 500 mm by 707 mm as defined in
+ ISO 216
+ 'iso-b3': Specifies the ISO B3 size: 353 mm by 500 mm as defined in
+ ISO 216
+ 'iso-b4': Specifies the ISO B4 size: 250 mm by 353 mm as defined in
+ ISO 216
+ 'iso-b5': Specifies the ISO B5 size: 176 mm by 250 mm as defined in
+ ISO 216
+ 'iso-b6': Specifies the ISO B6 size: 125 mm by 176 mm as defined in
+ ISO 216
+ 'iso-b7': Specifies the ISO B7 size: 88 mm by 125 mm as defined in
+ ISO 216
+ 'iso-b8': Specifies the ISO B8 size: 62 mm by 88 mm as defined in ISO
+ 216
+ 'iso-b9': Specifies the ISO B9 size: 44 mm by 62 mm as defined in ISO
+ 216
+ 'iso-b10': Specifies the ISO B10 size: 31 mm by 44 mm as defined in
+ ISO 216
+
+
+
+
+Hastings, et al. Standards Track [Page 202]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'na-letter': Specifies the North American letter size: 8.5 inches by
+ 11 inches
+ 'na-legal': Specifies the North American legal size: 8.5 inches by 14
+ inches
+ 'na-8x10': Specifies the North American 8 inches by 10 inches
+ 'na-5x7': Specifies the North American 5 inches by 7 inches
+ 'executive': Specifies the executive size (7.25 X 10.5 in)
+ 'folio': Specifies the folio size (8.5 X 13 in)
+ 'invoice': Specifies the invoice size (5.5 X 8.5 in)
+ 'ledger': Specifies the ledger size (11 X 17 in)
+ 'quarto': Specifies the quarto size (8.5 X 10.83 in)
+ 'iso-c3': Specifies the ISO C3 size: 324 mm by 458 mm as defined in
+ ISO 269
+ 'iso-c4': Specifies the ISO C4 size: 229 mm by 324 mm as defined in
+ ISO 269
+ 'iso-c5': Specifies the ISO C5 size: 162 mm by 229 mm as defined in
+ ISO 269
+ 'iso-c6': Specifies the ISO C6 size: 114 mm by 162 mm as defined in
+ ISO 269
+ 'iso-designated-long': Specifies the ISO Designated Long size: 110 mm
+ by 220 mm as defined in ISO 269
+ 'na-10x13-envelope': Specifies the North American 10x13 size: 10
+ inches by 13 inches
+ 'na-9x12-envelope': Specifies the North American 9x12 size: 9 inches
+ by 12 inches
+ 'na-number-10-envelope': Specifies the North American number 10
+ business envelope size: 4.125 inches by 9.5 inches
+ 'na-7x9-envelope': Specifies the North American 7x9 inch envelope
+ size
+ 'na-9x11-envelope': Specifies the North American 9x11 inch envelope
+ size
+ 'na-10x14-envelope': Specifies the North American 10x14 inch envelope
+ size
+ 'na-number-9-envelope': Specifies the North American number 9
+ business envelope size
+ 'na-6x9-envelope': Specifies the North American 6x9 envelope size
+ 'na-10x15-envelope': Specifies the North American 10x15 envelope size
+ 'monarch-envelope': Specifies the Monarch envelope size (3.87 x 7.5
+ in)
+ 'jis-b0': Specifies the JIS B0 size: 1030mm x 1456mm
+ 'jis-b1': Specifies the JIS B1 size: 728mm x 1030mm
+ 'jis-b2': Specifies the JIS B2 size: 515mm x 728mm
+ 'jis-b3': Specifies the JIS B3 size: 364mm x 515mm
+ 'jis-b4': Specifies the JIS B4 size: 257mm x 364mm
+ 'jis-b5': Specifies the JIS B5 size: 182mm x 257mm
+ 'jis-b6': Specifies the JIS B6 size: 128mm x 182mm
+ 'jis-b7': Specifies the JIS B7 size: 91mm x 128mm
+ 'jis-b8': Specifies the JIS B8 size: 64mm x 91mm
+
+
+
+Hastings, et al. Standards Track [Page 203]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 'jis-b9': Specifies the JIS B9 size: 45mm x 64mm
+ 'jis-b10': Specifies the JIS B10 size: 32mm x 45mm
+
+ The following standard values are defined for American Standard (i.e.
+ ANSI) engineering media sizes:
+
+ 'a': Specifies the engineering ANSI A size medium: 8.5 inches x 11
+ inches
+ 'b': Specifies the engineering ANSI B size medium: 11 inches x 17
+ inches
+ 'c': Specifies the engineering ANSI C size medium: 17 inches x 22
+ inches
+ 'd': Specifies the engineering ANSI D size medium: 22 inches x 34
+ inches
+ 'e': Specifies the engineering ANSI E size medium: 34 inches x 44
+ inches
+
+ The following standard values are defined for American Architectural
+ engineering media sizes:
+
+ 'arch-a': Specifies the Architectural A size medium: 9 inches x 12
+ inches
+ 'arch-b': Specifies the Architectural B size medium: 12 inches x 18
+ inches
+ 'arch-c': Specifies the Architectural C size medium: 18 inches x 24
+ inches
+ 'arch-d': Specifies the Architectural D size medium: 24 inches x 36
+ inches
+ 'arch-e': Specifies the Architectural E size medium: 36 inches x 48
+ inches
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 204]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+14.1. Examples
+
+ Below are examples to supplement the engineering media value
+ definitions.
+
+ Example 1: "Synchro-Cut", a device cutting the roll paper in
+ synchronization with the data
+
+ data height: A1 height
+ data width (shaded): A1 width < data width < (A1 width) x 2
+ specified value: 'iso-a1xsynchro-white'
+
+ | |
+ |<--- data width --->|
+ | |
+ | | | |
+ |<- A1 width ->|<- A1 width ->|
+ | | | |
+ cross ^ | | | |
+ feed | +--------------------------------------------/
+ direction | |//////////////|/////| | ^ /
+ | |//////////////|/////| | | /
+ | |//////////////|/////| | | /
+ | |//////////////|/////| | | \
+<-----------+- |//////////////|/////| | A1 \ roll
+feed | |//////////////|/////| | height \ paper
+direction |//////////////|/////| | | \
+ |//////////////|/////| | | /
+ |//////////////|/////| | v /
+ +------------------------------------------/
+ |
+ |
+ |<------ CUT HERE (to synchronize
+ | with data width)
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 205]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Example 2: "Auto-Cut", a device cutting the roll paper at multiples
+ of fixed-size media width
+
+ data height: A1 height
+ data width (shaded): A1 width < data width < (A1 width) x 2
+ specified value: 'auto-fixed-size-white'
+
+ | |
+ |<--- data width --->|
+ | |
+ | | | |
+ |<- A1 width ->|<- A1 width ->|
+ | | | |
+ cross ^ | | | |
+ feed | +--------------------------------------------/
+ direction | |//////////////|/////| | ^ /
+ | |//////////////|/////| | | /
+ | |//////////////|/////| | | /
+ | |//////////////|/////| | | \
+<-----------+- |//////////////|/////| | A1 \ roll
+feed | |//////////////|/////| | height \ paper
+direction |//////////////|/////| | | \
+ |//////////////|/////| | | /
+ |//////////////|/////| | v /
+ +------------------------------------------/
+ |
+ |
+ |<--- CUT HERE
+ | (to synchronize
+ | with data width)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 206]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Example 3: the 'iso-a4x4-white' fixed size paper
+
+ paper height: A4 height
+ paper width: (A4 width) x 4
+ specified value: 'iso-a4x4-white'
+
+ | | | | |
+ |<- A4 width ->|<- A4 width ->|<- A4 width ->|<- A4 width ->|
+ | | | | |
+ | | | | |
+ +-----------------------------------------------------------+
+ | ^ | | | |
+ | | | | | |
+ | | | | | |
+ | A4 | | | |
+ | height | | | |
+ | | | | | |
+ | | | | | |
+ | | | | | |
+ | v | | | |
+ +-----------------------------------------------------------+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 207]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Example 4: "Synchro-Cut", a device cutting the fixed size paper in
+ synchronization with the data
+
+ data height: A4 height
+ data width (shaded): (A4 width) x 2 < data width < (A4 width) x 3
+ specified value: 'iso-a4xsynchro-white'
+
+ | |
+ |<---------- data width ----------->|
+ | |
+ | | | | |
+ |<- A4 width ->|<- A4 width ->|<- A4 width ->|
+ | | | | |
+ cross ^ | | | | |
+ feed | +--------------------------------------------+
+ direction | |//////////////|//////////////|/////| ^ |
+ | |//////////////|//////////////|/////| | |
+ | |//////////////|//////////////|/////| | |
+ | |//////////////|//////////////|/////| | |
+ <-----------+- |//////////////|//////////////|/////| A4 |
+ feed | |//////////////|//////////////|/////| height |
+ direction |//////////////|//////////////|/////| | |
+ |//////////////|//////////////|/////| | |
+ |//////////////|//////////////|/////| v |
+ +--------------------------------------------+
+ |
+ CUT HERE ---->|
+ (to synchronize |
+ with data width) |
+
+15. APPENDIX D: Processing IPP Attributes
+
+ When submitting a print job to a Printer object, the IPP model allows
+ a client to supply operation and Job Template attributes along with
+ the document data. These Job Template attributes in the create
+ request affect the rendering, production and finishing of the
+ documents in the job. Similar types of instructions may also be
+ contained in the document to be printed, that is, embedded within the
+ print data itself. In addition, the Printer has a set of attributes
+ that describe what rendering and finishing options which are
+ supported by that Printer. This model, which allows for flexibility
+ and power, also introduces the potential that at job submission time,
+ these client-supplied attributes may conflict with either:
+
+ - what the implementation is capable of realizing (i.e., what the
+ Printer supports), as well as
+ - the instructions embedded within the print data itself.
+
+
+
+
+Hastings, et al. Standards Track [Page 208]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The following sections describe how these two types of conflicts are
+ handled in the IPP model.
+
+15.1 Fidelity
+
+ If there is a conflict between what the client requests and what a
+ Printer object supports, the client may request one of two possible
+ conflict handling mechanisms:
+
+ 1) either reject the job since the job can not be processed
+ exactly as specified, or
+ 2) allow the Printer to make any changes necessary to proceed with
+ processing the Job the best it can.
+
+ In the first case the client is indicating to the Printer object:
+ "Print the job exactly as specified with no exceptions, and if that
+ can't be done, don't even bother printing the job at all." In the
+ second case, the client is indicating to the Printer object: "It is
+ more important to make sure the job is printed rather than be
+ processed exactly as specified; just make sure the job is printed
+ even if some client-supplied attributes need to be changed or
+ ignored."
+
+ The IPP model accounts for this situation by introducing an "ipp-
+ attribute-fidelity" attribute.
+
+ In a create request, "ipp-attribute-fidelity" is a boolean operation
+ attribute that is OPTIONALLY supplied by the client. The value
+ 'true' indicates that total fidelity to client supplied Job Template
+ attributes and values is required. The client is requesting that the
+ Job be printed exactly as specified, and if that is not possible then
+ the job MUST be rejected rather than processed incorrectly. The
+ value 'false' indicates that a reasonable attempt to print the Job is
+ acceptable. If a Printer does not support some of the client
+ supplied Job Template attributes or values, the Printer MUST ignore
+ them or substitute any supported value for unsupported values,
+ respectively. The Printer may choose to substitute the default value
+ associated with that attribute, or use some other supported value
+ that is similar to the unsupported requested value. For example, if
+ a client supplies a "media" value of 'na-letter', the Printer may
+ choose to substitute 'iso-a4' rather than a default value of
+ 'envelope'. If the client does not supply the "ipp-attribute-
+ fidelity" attribute, the Printer assumes a value of 'false'.
+
+ Each Printer implementation MUST support both types of "fidelity"
+ printing (that is whether the client supplies a value of 'true' or
+ 'false'):
+
+
+
+
+Hastings, et al. Standards Track [Page 209]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ - If the client supplies 'false' or does not supply the attribute,
+ the Printer object MUST always accept the request by ignoring
+ unsupported Job Template attributes and by substituting
+ unsupported values of supported Job Template attributes with
+ supported values.
+ - If the client supplies 'true', the Printer object MUST reject
+ the request if the client supplies unsupported Job Template
+ attributes.
+
+ Since a client can always query a Printer to find out exactly what is
+ and is not supported, "ipp-attribute-fidelity" set to 'false' is
+ useful when:
+
+ 1) The End-User uses a command line interface to request
+ attributes that might not be supported.
+ 2) In a GUI context, if the End User expects the job might be
+ moved to another printer and prefers a sub-optimal result to
+ nothing at all.
+ 3) The End User just wants something reasonable in lieu of nothing
+ at all.
+
+15.2 Page Description Language (PDL) Override
+
+ If there is a conflict between the value of an IPP Job Template
+ attribute and a corresponding instruction in the document data, the
+ value of the IPP attribute SHOULD take precedence over the document
+ instruction. Consider the case where a previously formatted file of
+ document data is sent to an IPP Printer. In this case, if the client
+ supplies any attributes at job submission time, the client desires
+ that those attributes override the embedded instructions. Consider
+ the case were a previously formatted document has embedded in it
+ commands to load 'iso-a4' media. However, the document is passed to
+ an end user that only has access to a printer with 'na-letter' media
+ loaded. That end user most likely wants to submit that document to
+ an IPP Printer with the "media" Job Template attribute set to 'na-
+ letter'. The job submission attribute should take precedence over
+ the embedded PDL instruction. However, until companies that supply
+ document data interpreters allow a way for external IPP attributes to
+ take precedence over embedded job production instructions, a Printer
+ might not be able to support the semantics that IPP attributes
+ override the embedded instructions.
+
+ The IPP model accounts for this situation by introducing a "pdl-
+ override-supported" attribute that describes the Printer objects
+ capabilities to override instructions embedded in the PDL data
+ stream. The value of the "pdl-override-supported" attribute is
+ configured by means outside the scope of this IPP/1.1 document.
+
+
+
+
+Hastings, et al. Standards Track [Page 210]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ This REQUIRED Printer attribute takes on the following values:
+
+ - 'attempted': This value indicates that the Printer object
+ attempts to make the IPP attribute values take precedence over
+ embedded instructions in the document data, however there is no
+ guarantee.
+ - 'not-attempted': This value indicates that the Printer object
+ makes no attempt to make the IPP attribute values take
+ precedence over embedded instructions in the document data.
+
+ At job processing time, an implementation that supports the value of
+ 'attempted' might do one of several different actions:
+
+ 1) Generate an output device specific command sequence to realize
+ the feature represented by the IPP attribute value.
+ 2) Parse the document data itself and replace the conflicting
+ embedded instruction with a new embedded instruction that
+ matches the intent of the IPP attribute value.
+ 3) Indicate to the Printer that external supplied attributes take
+ precedence over embedded instructions and then pass the
+ external IPP attribute values to the document data interpreter.
+ 4) Anything else that allows for the semantics that IPP attributes
+ override embedded document data instructions.
+
+ Since 'attempted' does not offer any type of guarantee, even though a
+ given Printer object might not do a very "good" job of attempting to
+ ensure that IPP attributes take a higher precedence over instructions
+ embedded in the document data, it would still be a conforming
+ implementation.
+
+ At job processing time, an implementation that supports the value of
+ 'not-attempted' might do one of the following actions:
+
+ 1) Simply pre-pend the document data with the PDL instruction that
+ corresponds to the client-supplied PDL attribute, such that if
+ the document data also has the same PDL instruction, it will
+ override what the Printer object pre-pended. In other words,
+ this implementation is using the same implementation semantics
+ for the client-supplied IPP attributes as for the Printer
+ object defaults.
+
+ 2) Parse the document data and replace the conflicting embedded
+ instruction with a new embedded instruction that approximates,
+ but does not match, the semantic intent of the IPP attribute
+ value.
+
+ Note: The "ipp-attribute-fidelity" attribute applies to the
+ Printer's ability to either accept or reject other unsupported Job
+
+
+
+Hastings, et al. Standards Track [Page 211]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ Template attributes. In other words, if "ipp-attribute-fidelity" is
+ set to 'true', a Job is accepted if and only if the client supplied
+ Job Template attributes and values are supported by the Printer.
+ Whether these attributes actually affect the processing of the Job
+ when the document data contains embedded instructions depends on the
+ ability of the Printer to override the instructions embedded in the
+ document data with the semantics of the IPP attributes. If the
+ document data attributes can be overridden ("pdl-override-supported"
+ set to 'attempted'), the Printer makes an attempt to use the IPP
+ attributes when processing the Job. If the document data attributes
+ can not be overridden ("pdl-override-supported" set to 'not-
+ attempted'), the Printer makes no attempt to override the embedded
+ document data instructions with the IPP attributes when processing
+ the Job, and hence, the IPP attributes may fail to affect the Job
+ processing and output when the corresponding instruction is embedded
+ in the document data.
+
+15.3 Using Job Template Attributes During Document Processing.
+
+ The Printer object uses some of the Job object's Job Template
+ attributes during the processing of the document data associated with
+ that job. These include, but are not limited to, "orientation-
+ requested", "number-up", "sides", "media", and "copies". The
+ processing of each document in a Job Object MUST follow the steps
+ below. These steps are intended only to identify when and how
+ attributes are to be used in processing document data and any
+ alternative steps that accomplishes the same effect can be used to
+ implement this specification document.
+
+ 1. Using the client supplied "document-format" attribute or some
+ form of document format detection algorithm (if the value of
+ "document-format" is not specific enough), determine whether or
+ not the document data has already been formatted for printing.
+ If the document data has been formatted, then go to step 2.
+ Otherwise, the document data MUST be formatted. The formatting
+ detection algorithm is implementation defined and is not
+ specified by this document. The formatting of the document
+ data uses the "orientation-requested" attribute to determine
+ how the formatted print data should be placed on a print-stream
+ page, see section 4.2.10 for the details.
+
+ 2. The document data is in the form of a print-stream in a known
+ media type. The "page-ranges" attribute is used to select, as
+ specified in section 4.2.7, a sub-sequence of the pages in the
+ print-stream that are to be processed and images.
+
+ 3. The input to this step is a sequence of print-stream pages.
+ This step is controlled by the "number-up" attribute. If the
+
+
+
+Hastings, et al. Standards Track [Page 212]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ value of "number-up" is N, then during the processing of the
+ print-stream pages, each N print-stream pages are positioned,
+ as specified in section 4.2.9, to create a single impression.
+ If a given document does not have N more print-stream pages,
+ then the completion of the impression is controlled by the
+ "multiple-document-handling" attribute as described in section
+ 4.2.4; when the value of this attribute is 'single-document' or
+ 'single-document-new-sheet', the print-stream pages of document
+ data from subsequent documents is used to complete the
+ impression.
+
+ The size(scaling), position(translation) and rotation of the
+ print-stream pages on the impression is implementation defined.
+ Note that during this process the print-stream pages may be
+ rendered to a form suitable for placing on the impression; this
+ rendering is controlled by the values of the "printer-
+ resolution" and "print-quality" attributes as described in
+ sections 4.2.12 and 4.2.13. In the case N=1, the impression is
+ nearly the same as the print-stream page; the differences would
+ only be in the size, position and rotation of the print-stream
+ page and/or any decoration, such as a frame to the page, that
+ is added by the implementation.
+
+ 4. The collection of impressions is placed, in sequence, onto
+ sides of the media sheets. This placement is controlled by the
+ "sides" attribute and the orientation of the print-stream page,
+ as described in section 4.2.8. The orientation of the print-
+ stream pages affects the orientation of the impression; for
+ example, if "number-up" equals 2, then, typically, two portrait
+ print-stream pages become one landscape impression. Note that
+ the placement of impressions onto media sheets is also
+ controlled by the "multiple-document-handling" attribute as
+ described in section 4.2.4.
+
+ 5. The "copies" and "multiple-document-handling" attributes are
+ used to determine how many copies of each media instance are
+ created and in what order. See sections 4.2.5 and 4.2.4 for the
+ details.
+
+ 6. When the correct number of copies are created, the media
+ instances are finished according to the values of the
+ "finishings" attribute as described in 4.2.6. Note that
+ sometimes finishing operations may require manual intervention
+ to perform the finishing operations on the copies, especially
+ uncollated copies. This document allows any or all of the
+ processing steps to be performed automatically or manually at
+ the discretion of the Printer object.
+
+
+
+
+Hastings, et al. Standards Track [Page 213]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+16. APPENDIX E: Generic Directory Schema
+
+ This section defines a generic schema for an entry in a directory
+ service. A directory service is a means by which service users can
+ locate service providers. In IPP environments, this means that IPP
+ Printers can be registered (either automatically or with the help of
+ an administrator) as entries of type printer in the directory using
+ an implementation specific mechanism such as entry attributes, entry
+ type fields, specific branches, etc. Directory clients can search or
+ browse for entries of type printer. Clients use the directory
+ service to find entries based on naming, organizational contexts, or
+ filtered searches on attribute values of entries. For example, a
+ client can find all printers in the "Local Department" context.
+ Authentication and authorization are also often part of a directory
+ service so that an administrator can place limits on end users so
+ that they are only allowed to find entries to which they have certain
+ access rights. IPP itself does not require any specific directory
+ service protocol or provider.
+
+ Note: Some directory implementations allow for the notion of
+ "aliasing". That is, one directory entry object can appear as
+ multiple directory entry object with different names for each object.
+ In each case, each alias refers to the same directory entry object
+ which refers to a single IPP Printer object.
+
+ The generic schema is a subset of IPP Printer Job Template and
+ Printer Description attributes (sections 4.2 and 4.4). These
+ attributes are identified as either RECOMMENDED or OPTIONAL for the
+ directory entry itself. This conformance labeling is NOT the same
+ conformance labeling applied to the attributes of IPP Printers
+ objects. The conformance labeling in this Appendix is intended to
+ apply to directory templates and to IPP Printer implementations that
+ subscribe by adding one or more entries to a directory. RECOMMENDED
+ attributes SHOULD be associated with each directory entry. OPTIONAL
+ attributes MAY be associated with the directory entry (if known or
+ supported). In addition, all directory entry attributes SHOULD
+ reflect the current attribute values for the corresponding Printer
+ object.
+
+ The names of attributes in directory schema and entries SHOULD be the
+ same as the IPP Printer attribute names as shown, as much as
+ possible.
+
+ In order to bridge between the directory service and the IPP Printer
+ object, one of the RECOMMENDED directory entry attributes is the
+ Printer object's "printer-uri-supported" attribute. The directory
+ client queries the "printer-uri-supported" attribute (or its
+ equivalent) in the directory entry and then the IPP client addresses
+
+
+
+Hastings, et al. Standards Track [Page 214]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ the IPP Printer object using one of its URIs. The "uri-security-
+ supported" attribute identifies the protocol (if any) used to secure
+ a channel.
+
+ The following attributes define the generic schema for directory
+ entries of type PRINTER:
+
+ printer-uri-supported RECOMMENDED Section 4.4.1
+ uri-authentication-supported RECOMMENDED Section 4.4.2
+ uri-security-supported RECOMMENDED Section 4.4.3
+ printer-name RECOMMENDED Section 4.4.4
+ printer-location RECOMMENDED Section 4.4.5
+ printer-info OPTIONAL Section 4.4.6
+ printer-more-info OPTIONAL Section 4.4.7
+ printer-make-and-model RECOMMENDED Section 4.4.9
+ ipp-versions-supported RECOMMENDED Section 4.4.14
+ multiple-document-jobs-supported OPTIONAL Section 4.4.16
+ charset-supported OPTIONAL Section 4.4.18
+
+ generated-natural-language-
+ supported OPTIONAL Section 4.4.20
+ document-format-supported RECOMMENDED Section 4.4.22
+ color-supported RECOMMENDED Section 4.4.26
+ compression-supported RECOMMENDED Section 4.4.32
+ pages-per-minute OPTIONAL Section 4.4.36
+ pages-per-minute-color OPTIONAL Section 4.4.37
+
+ finishings-supported OPTIONAL Section 4.2.6
+ number-up-supported OPTIONAL Section 4.2.7
+ sides-supported RECOMMENDED Section 4.2.8
+ media-supported RECOMMENDED Section 4.2.11
+ printer-resolution-supported OPTIONAL Section 4.2.12
+ print-quality-supported OPTIONAL Section 4.2.13
+
+17. APPENDIX F: Differences between the IPP/1.0 and IPP/1.1 "Model and
+ Semantics" Documents
+
+ This Appendix is divided into two lists that summarize the
+ differences between IPP/1.1 (this document) and IPP/1.0 [RFC2566].
+ The section numbers refer to the numbers in this document which in
+ some cases have changed from RFC 2566. When a change affects
+ multiple sections, the item is listed once in the order of the first
+ section affected and the remaining affected section numbers are
+ indicated.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 215]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ The first list contains extensions and clarifications and the second
+ list contains changes in semantics or conformance. However, client
+ and IPP object implementations of IPP/1.0 MAY implement any of the
+ extensions and clarifications in this document.
+
+ The following extensions and clarifications have been incorporated
+ into this document:
+
+ 1. Section 2.1 - clarified that the term "client" can be either
+ contained in software controlled by an end user or a part of a
+ print server that controls devices.
+ 2. Section 2 - clarified that the term "IPP object" and "Printer
+ object" can either be embedded in a device object or part of a
+ print server that accepts IPP requests.
+ 3. Section 2.4 - added the description of the new "uri-
+ authentication-supported" Printer Description attribute.
+ 4. Section 3.1.3, 3.1.6, 3.2.5.2, and 3.2.6.2 - clarified the
+ error handling for operation attributes that have their own
+ status code.
+ 5. Section 3.1.3 - clarified that multiple occurrences of the
+ same attribute in an attribute group is mal-formed. An IPP
+ Printer MAY reject the request or choose one of the
+ attributes.
+ 6. Section 3.1.6 - reorganized this section into sub-sections to
+ separately describe "status-code", "status-message",
+ "detailed-status-message", and "document-access-error"
+ attributes.
+ 7. Section 3.1.6.1 - clarified the error status codes and their
+ relationship to operation attributes.
+ 8. Section 3.1.6.3 - Added the OPTIONAL "detailed-status-message
+ (text(MAX))" operation attribute to provide additional more
+ detailed information about a response.
+ 9. Section 3.1.6.4 and 3.2.2 - Added the OPTIONAL "document-
+ access-error (text(MAX))" operation attribute for use with
+ Print-URI and Send-URI responses.
+ 10. Sections 3.1.7 - Added this new section to clarify returning
+ Unsupported Attributes for all operations, including only
+ returning attributes that were in the request. Moved the text
+ from section 3.2.1.2 Unsupported Attributes to this section.
+ 11. Sections 3.1.7 and 4.1 - clarified the encoding of the "out-
+ of-band" 'unsupported' and 'unknown' values.
+ 12. Section 3.1.8 - clarified that only the version number
+ parameter will be carried forward into future major or minor
+ versions of the protocol.
+ 13. Section 3.1.8 - relaxed the requirements to increment the
+ major version number in future versions of the Model and
+ Semantics document.
+
+
+
+
+Hastings, et al. Standards Track [Page 216]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 14. Section 3.1.9, and 3.2.5 - added the 'processing' state to the
+ list of job states that a job can be in after a Create-Job
+ operation.
+ 15. Section 3.1.9 - clarified that a non-spooling Printer MAY
+ accept zero or more subsequent jobs while processing a job and
+ flow control them down. Subsequent create requests are
+ rejected with the 'server-error-busy' error status.
+ 16. Section 3.2.1.1 - clarified the validation of the
+ "compression" operation attribute and its relationship to the
+ validation of the "document-format" attribute and returning
+ Unsupported Attributes.
+ 17. Sections 3.2.1.1, 4.3.8, 13.1.4.16, and 13.1.4.17 - added the
+ 'client-error-compression-not-supported', 'client-error-
+ compression-error' status codes and the 'unsupported-
+ compression' and 'compression-error' job-state-reasons.
+ 18. Sections 3.2.1.1 and 4.3.8 - added 'unsupported-document-
+ format' and 'document-format-error' job-state-reasons.
+ 19. Sections 3.2.2, 4.3.8 and 13.1.4.19 - added 'client-error-
+ document-access-error' status code and 'document-access-error'
+ job state reason.
+ 20. Section 3.2.5.2 and 3.2.6.2 - clarified that the Unsupported
+ Attributes group MUST NOT include attributes not requested in
+ the Get-Printer-Attributes request.
+ 21. Section 3.2.6 - clarified that "limit" takes precedence over
+ "which-jobs" and "my-jobs'.
+ 22. Section 3.2.6.2 - clarified that Get-Jobs returns
+ 'successful-ok' when no jobs to return.
+ 23. Sections 3.2.7, 3.2.8, and 3.2.9 - added the OPTIONAL Pause-
+ Printer, Resume-Printer, and Purge-Jobs operations
+ 24. Section 3.3.1 - clarified that the authorization required for
+ a Send-Document request MUST be the same user as the Create-
+ Job or an operator.
+ 25. Section 3.3.1.1 - clarified that a Create-Job Send-Document
+ with "last-document" = 'true' and no data is not an error; its
+ a job with no documents.
+ 26. Sections 3.3.5, 3.3.6, and 3.3.7 - added the OPTIONAL Hold-
+ Job, Release-Job, and Restart-Job operations. Clarified the
+ Restart-Job operation so that the Printer MUST re-fetch any
+ documents passed by-reference (Print-URI or Send-URI).
+ 27. Section 4.1 - clarified that the encoding of the out-of-band
+ values are specified in the Encoding and Transport" document.
+ 28. Section 4.1 - Clarified that the requirement that clients MUST
+ NOT send "out-of-band" values in requests applies only to
+ operations defined in this document. Other operations are
+ allowed to define "out-of-band" values that clients can
+ supply.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 217]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 29. Sections 4.1.1 and 4.1.2 - clarified that the maximum 'text'
+ and 'name' values of 1023 and 255 are for the
+ 'textWithoutLanguage' portion of the 'textWithLanguage' form,
+ so that the maximum number of octets for the actual text and
+ name data is the same for the without and with language forms;
+ the 'naturalLanguage' part is in addition.
+ 30. Section 4.1.9 - clarified that 'mimeMediaType' values can
+ include any parameters from the IANA Registry, not just
+ charset parameters.
+ 31. Section 4.1.9.1 - clarified that 'application/octet-stream'
+ auto-sensing can happen at create request time and/or
+ job/document processing time.
+ 32. Section 4.1.9.1 - clarified that auto-sensing involves the
+ Printer examining some number of octets of document data using
+ an implementation-dependent method.
+ 33. Section 4.1.14 - clarified that the localization of dateTime
+ by the client includes the time zone.
+ 34. Section 4.2 - clarified that xxx-supported have multiple
+ keywords and/or names by adding parentheses to the table to
+ give: (1setOf (type3 keyword | name))
+ 35. Section 4.2.2 - added the 'indefinite' keyword value to the
+ "job-hold-until" attribute for use with the create operations
+ and Hold-Job and Restart-Job operations.
+ 36. Section 4.2.6 - added more enum values to the "finishings" Job
+ Template attribute.
+ 37. Section 4.2.6 - clarified that the landscape definition is a
+ rotation of the image with respect to the medium.
+ 38. Section 4.3.7 - added that a forwarding server that cannot get
+ any job state MAY return the job's state as 'completed',
+ provided that it also return the new 'queued-in-device' job
+ state reason.
+ 39. Section 4.3.7.2 - added the Partitioning of Job States section
+ to clarify the concepts of Job Retention, Job History, and Job
+ Removal.
+ 40. Section 4.3.8 - added 'job-data-insufficient' job state reason
+ to indicate whether sufficient data has arrived for the
+ document to start to be processed.
+ 41. Section 4.3.8 - added 'document-access-error' job state reason
+ to indicate an access error of any kind.
+ 42. Section 4.3.8 - added 'job-queued-for-marker' job state reason
+ to indicate whether the job has completed some processing and
+ is waiting for the marker.
+ 43. Section 4.3.8 - added 'unsupported-compression' and
+ 'compression-error' job state reasons to indicate compression
+ not supported or compression processing error after the create
+ has been accepted.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 218]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 44. Section 4.3.8 - added 'unsupported-document-format' and
+ 'document-format-error' job state reasons to indicate document
+ not supported or document format processing error after the
+ create has been accepted.
+ 45. Section 4.3.8 - added 'queued-in-device' job state reason to
+ indicate that a job as been forwarded to a print system or
+ device that does not provide any job status.
+ 46. Section 4.3.10 - added "job-detailed-status-messages (1setOf
+ text(MAX)) for returning detailed error messages.
+ 47. Section 4.3.11 - added the "job-document-access-errors (1setOf
+ text(MAX))
+ 48. Section 4.3.14.2 - clarified that the time recorded is the
+ first time processing since the create operation or the
+ Restart-Job operation.
+ 49. Section 4.3.14.2 and 4.3.14.3 - clarified that the out-of-band
+ value 'no-value' is returned if the job has not started
+ processing or has not completed, respectively.
+ 50. Section 4.3.14 - Added the OPTIONAL "date-time-at-creation",
+ "date-time-at-processing", and "date-time-at-completed" Event
+ Time Job Description attributes
+ 51. Section 4.4.3 - added the 'tls' value to "uri-security-
+ supported" attribute.
+ 52. Section 4.4.3 - clarified "uri-security-supported" is
+ orthogonal to Client Authentication so that 'none' does not
+ exclude Client Authentication.
+ 53. Section 4.4.11 - simplified the "printer-state" descriptions
+ while generalizing to allow high end devices that interpret
+ one or more jobs while marking another. Indicated that
+ 'spool-area-full' and 'stopped-partly' "printer-state-reasons"
+ may be used to provide further state information.
+ 54. Section 4.4.12 - added the 'moving-to-paused' keyword value to
+ the "printer-state-reasons" attribute for use with the Pause-
+ Printer operation.
+ 55. Section 4.4.12 - replaced the duplicate 'marker-supply-low'
+ keyword with the missing 'toner-empty' keyword for the
+ "printer-state-reasons" attribute. (This correction was also
+ made before RFC 2566 was published).
+ 56. Section 4.4.12 - clarified 'spool-area-full' "printer-state-
+ reasons" to include non-spooling printers to indicate when it
+ can and cannot accept another job.
+ 57. Section 4.4.15 - added the enum values to the "operations-
+ supported" attribute for the new operations. Clarified that
+ the values of this attribute are encoded as any enum, namely
+ 32-bit values.
+ 58. Section 4.4.30 - clarified that the dateTime value of
+ "printer-current-time" is on a "best efforts basis". If a
+ proper date-time cannot be obtained, the implementation
+ returns the 'no-value' out-of-band value. Also clarified that
+
+
+
+Hastings, et al. Standards Track [Page 219]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ the time zone NEED NOT be the time zone that the people near
+ the device use and that the client SHOULD display the dateTime
+ attributes in the user's local time.
+ 59. Sections 4.4.36 and 4.4.37 - added the OPTIONAL "pages-per-
+ minute" and "pages-per-minute-color" Printer Description
+ attributes.
+ 60. Section 5.1 - clarified that the client conformance
+ requirements apply to clients controlled by an end user and
+ clients in servers.
+ 61. Section 5.1 - clarified that any response MAY contain
+ additional attribute groups, attributes, attribute syntaxes,
+ or attribute values.
+ 62. Section 5.1 - clarified that a client SHOULD do its best to
+ prevent a channel from being closed by a lower layer when the
+ channel is flow controlled off by the IPP Printer.
+ 63. Section 5.2 - clarified that the IPP object requirements apply
+ to objects embedded in devices or that are parts of servers.
+ 64. Section 5.2.2 - clarified that IPP objects MAY return
+ operation responses that contain attribute groups, attribute
+ names, attribute syntaxes, attribute values, and status codes
+ that are extensions to this standard.
+ 65. Section 6 - changed the terminology of "private extensions" to
+ "vendor extensions" and indicated that they are registered
+ with IANA along with IETF standards track extensions.
+ 66. Section 6.7 - inserted this section on registering out-of-band
+ attribute values with IANA as extensions.
+ 67. Section 8.3 - clarified the use of URIs for each Client
+ Authentication mechanism.
+ 68. Section 8.5 - added the security discussion around the new
+ operator/administrator operations.
+ 69. Section 13.1.4.16 - added client-error-compression-not-
+ supported (0x040F)
+ 70. Section 13.1.4.17 - added client-error-compression-error
+ (0x0410)
+ 71. Section 13.1.4.18 - added client-error-document-format-error
+ (0x0411)
+ 72. Section 13.1.4.19 - added client-error-document-access-error
+ (0x0412)
+ 73. Section 13.1.5.10 - added server-error-multiple-document-
+ jobs-not-supported (0x0509)
+ 74. Section 14 - added 'a-white', 'b-white', 'c-white', 'd-white',
+ and 'e-white' and clarified that the existing 'a', 'b', 'c',
+ 'd', and 'e' values are size values. Added American,
+ Japanese, and European Engineering sizes, filled out
+ -transparent and - translucent media names and drawings for
+ the synchro cut sizes.
+
+
+
+
+
+Hastings, et al. Standards Track [Page 220]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 75. Section 16 - softened the RECOMMENDATION for IPP Printer
+ attributes in a Directory schema so that they can have
+ equivalents.
+ 76. Section 16 - added the OPTIONAL "pages-per-minute" and
+ "pages-per-minute-color" Printer attributes to the Directory
+ schema.
+ 77. Section 16 - added OPTIONAL "multiple-document-jobs-supported"
+ to the Directory schema.
+ 78. Section 16 - added RECOMMENDED "uri-authentication-supported",
+ "ipp-versions-supported", and "compression-supported" to the
+ Directory schema.
+
+ The following changes in semantics and/or conformance have been
+ incorporated into this document:
+
+ 1. Section 3.1.6.3 - allowed a Printer to localize the
+ "detailed-status-message" operation response attribute, but
+ indicated that such localization might obscure the technical
+ meaning of such messages.
+ 2. Section 3.1.8, 5.2.4, and 13.1.5.4 - Clients and IPP objects
+ MUST support version 1.1 conformance requirements. It is
+ recommended that they interoperate with 1.0. Also clarified
+ that IPP Printers MUST accept '1.1' requests. It is
+ recommended that they also accept '1.x' requests.
+
+ 3. Section 3.2.1.1 and section 4.4.32 - changed the "compression"
+ operation and the "compression-supported" Printer Description
+ attribute from OPTIONAL to REQUIRED.
+ 4. Sections 3.2.1.2 and 4.3.8 - changed "job-state-reasons" from
+ RECOMMENDED to REQUIRED, so that "job-state-reasons" MUST be
+ returned in create operation responses.
+ 5. Sections 3.2.4, 3.3.1, 4.4.16, and 16 - changed Create-
+ Job/Send-Document so that they MAY be implemented while only
+ supporting one document jobs. Added the "multiple-document-
+ jobs-supported" boolean Printer Description attribute to
+ indicate whether Create-Job/Send-Document support multiple
+ document jobs or not. Added to the Directory schema.
+ 6. Section 4.1.9 - deleted 'text/plain; charset=iso-10646-ucs-2',
+ since binary is not legal with the 'text' type.
+ 7. Section 4.1.9.1 - added the RECOMMENDATION that a Printer
+ indicate by printing on the job's job-start-sheet that auto-
+ sensing has occurred and what document format was auto-sensed.
+ 8. Section 4.2.4 - indicated that the "multiple-document-
+ handling" Job Template attribute MUST be supported with at
+ least one value if the Printer supports multiple documents per
+ job
+
+
+
+
+
+Hastings, et al. Standards Track [Page 221]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 9. Section 4.3.7.2 - indicated that the 'job-restartable' job
+ state reason SHOULD be supported if the Restart-Job operation
+ is supported.
+ 10. Section 4.3.8 - changed "job-state-reasons" from RECOMMENDED
+ to REQUIRED.
+ 11. Section 4.3.8 - clarified the conformance of the values of the
+ "job-state-reasons" attribute by copying conformance
+ requirements from other sections of the document so that it is
+ clear from reading the definition of "job-state-reasons" which
+ values MUST or SHOULD be supported. The 'none',
+ 'unsupported-compression', and 'unsupported-document-format'
+ values MUST be supported. The 'job-hold-until-specified'
+ SHOULD be specified if the "job-hold-until" Job Template is
+ supported. The following values SHOULD be supported: 'job-
+ canceled-by-user', 'aborted-by-system', and 'job-completed-
+ successfully'. The
+ 'job-canceled-by-operator' SHOULD be supported if the
+ implementation permits canceling by other than the job owner.
+ The 'job-canceled-at-device' SHOULD be supported if the device
+ supports canceling jobs at the console. The 'job-completed-
+ with-warnings' SHOULD be supported, if the implementation
+ detects warnings. The 'job-completed-with-errors' SHOULD be
+ supported if the implementation detects errors. The 'job-
+ restartable' SHOULD be supported if the Restart-Job operation
+ is supported.
+ 12. Section 4.3.10 - allowed a Printer to localize the "job-
+ detailed-status-message" Job Description attribute, but
+ indicated that such localization might obscure the technical
+ meaning of such messages.
+ 13. Section 4.3.14 - changed the "time-at-creation", "time-at-
+ processing", and "time-at-completed" Event Time Job
+ Description attributes from OPTIONAL to REQUIRED.
+ 14. Section 4.3.14.4 - added the REQUIRED "job-printer-up-time
+ (integer(1:MAX))" Job Description attribute as an alias for
+ "printer-up-time" to reduce number of operations to get job
+ times.
+ 15. Section 4.4.2 - added the REQUIRED "uri-authentication-
+ supported (1setOf type2 keyword)" Printer Description
+ attribute to describe the Client Authentication used by each
+ Printer URI.
+ 16. Section 4.4.12 - changed "printer-state-reasons" Printer
+ Description attribute from OPTIONAL to REQUIRED.
+ 17. Section 4.4.12 - changed 'paused' value of "printer-state-
+ reasons" to MUST if Pause-Printer operation is supported.
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 222]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+ 18. Section 4.4.14 - added the REQUIRED "ipp-versions-supported
+ (1setOf keyword)" Printer Description attribute, since IPP/1.1
+ Printers do not have to support version '1.0' conformance
+ requirements. Section 4.4.16 - added the "multiple-document-
+ jobs-supported (boolean)" Printer Description attribute so
+ that a client can tell whether a Printer that supports
+ Create-Job/Send-Document supports multiple document jobs or
+ not. This attribute is REQUIRED if the Create-Job operation
+ is supported.
+ 19. Section 4.4.24 - changed the "queued-job-count" Printer
+ Description attribute from RECOMMENDED to REQUIRED.
+ 20. Section 4.4.32 - changed "compression-supported (1setOf type3
+ keyword)" Printer Description attribute from OPTIONAL to
+ REQUIRED.
+ 21. Section 5.1 - changed the client security requirements from
+ RECOMMENDED non-standards track SSL3 to MUST support Client
+ Authentication as defined in the IPP/1.1 Encoding and
+ Transport document [RFC2910]. A client SHOULD support
+ Operation Privacy and Server Authentication as defined in the
+ IPP/1.1 Encoding and Transport document [RFC2910].
+ 22. Section 5.2.7 - changed the IPP object security requirements
+ from OPTIONAL non-standards track SSL3 to SHOULD contain
+ support for Client Authentication as defined in the IPP/1.1
+ Encoding and Transport document [RFC2910]. A Printer
+ implementation MAY allow an administrator to configure the
+ Printer so that all, some, or none of the users are
+ authenticated. An IPP Printer implementation SHOULD contain
+ support for Operation Privacy and Server Authentication as
+ defined in the IPP/1.1 Encoding and Transport document
+ [RFC2910]. A Printer implementation MAY allow an
+ administrator to configure the degree of support for Operation
+ Privacy and Server Authentication. Security MUST NOT be
+ compromised when the client supplies a lower version-number in
+ a request.
+ 23. Section 14 (Appendix C): Corrected typo, changing the keyword
+ 'iso-10-white' to 'iso-a10-white'.
+
+ See also the "IPP/1.1 Encoding and Transport" [RFC2910] document for
+ differences between IPP/1.0 [RFC2565] and IPP/1.1 [RFC2910].
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 223]
+
+RFC 2911 IPP/1.1: Model and Semantics September 2000
+
+
+18. Full Copyright Statement
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hastings, et al. Standards Track [Page 224]
+
diff --git a/systemv/.cvsignore b/systemv/.cvsignore
new file mode 100644
index 000000000..9d86f74cb
--- /dev/null
+++ b/systemv/.cvsignore
@@ -0,0 +1,10 @@
+lp
+cupsaddsmb
+lppasswd
+lpoptions
+lpadmin
+accept
+cancel
+lpinfo
+lpmove
+lpstat
diff --git a/systemv/Dependencies b/systemv/Dependencies
new file mode 100644
index 000000000..941843825
--- /dev/null
+++ b/systemv/Dependencies
@@ -0,0 +1,26 @@
+# DO NOT DELETE
+
+accept.o: ../config.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+accept.o: ../cups/md5.h ../cups/ppd.h ../cups/string.h ../cups/language.h
+cancel.o: ../config.h ../cups/cups.h ../cups/ipp.h ../cups/http.h
+cancel.o: ../cups/md5.h ../cups/ppd.h ../cups/string.h ../cups/language.h
+cupsaddsmb.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+cupsaddsmb.o: ../cups/ppd.h ../cups/string.h ../config.h
+lp.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h
+lp.o: ../cups/string.h ../config.h ../cups/language.h
+lpadmin.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lpadmin.o: ../cups/ppd.h ../cups/string.h ../config.h ../cups/language.h
+lpadmin.o: ../cups/debug.h
+lpinfo.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lpinfo.o: ../cups/ppd.h ../cups/language.h ../cups/debug.h ../cups/string.h
+lpinfo.o: ../config.h
+lpmove.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lpmove.o: ../cups/ppd.h ../cups/language.h ../cups/debug.h ../cups/string.h
+lpmove.o: ../config.h
+lpoptions.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lpoptions.o: ../cups/ppd.h ../cups/string.h ../config.h
+lppasswd.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lppasswd.o: ../cups/ppd.h ../cups/md5.h ../cups/string.h ../config.h
+lpstat.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lpstat.o: ../cups/ppd.h ../cups/language.h ../cups/debug.h ../cups/string.h
+lpstat.o: ../config.h
diff --git a/systemv/Makefile b/systemv/Makefile
new file mode 100644
index 000000000..bf5372fe9
--- /dev/null
+++ b/systemv/Makefile
@@ -0,0 +1,185 @@
+#
+# "$Id$"
+#
+# System V commands makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+TARGETS = accept cancel cupsaddsmb lp lpadmin lpinfo lpmove \
+ lpoptions lppasswd lpstat
+OBJS = accept.o cancel.o cupsaddsmb.o lp.o lpadmin.o \
+ lpinfo.o lpmove.o lpoptions.o lppasswd.o lpstat.o
+
+
+#
+# Make all targets...
+#
+
+all: $(TARGETS)
+
+
+#
+# Clean all object files...
+#
+
+clean:
+ $(RM) $(OBJS) $(TARGETS) disable enable reject
+
+
+#
+# Update dependencies (without system header dependencies...)
+#
+
+depend:
+ makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1
+
+
+#
+# Install all targets...
+#
+
+install: all
+ $(INSTALL_DIR) $(SBINDIR)
+ $(INSTALL_BIN) accept $(SBINDIR)
+ $(RM) $(SBINDIR)/reject
+ $(LN) accept $(SBINDIR)/reject
+ $(INSTALL_BIN) cupsaddsmb $(SBINDIR)
+ $(INSTALL_BIN) lpadmin $(SBINDIR)
+ $(INSTALL_BIN) lpinfo $(SBINDIR)
+ $(INSTALL_BIN) lpmove $(SBINDIR)
+ $(INSTALL_DIR) $(BINDIR)
+ $(INSTALL_BIN) cancel $(BINDIR)
+ $(RM) $(BINDIR)/disable
+ $(LN) ../sbin/accept $(BINDIR)/disable
+ $(RM) $(BINDIR)/enable
+ $(LN) ../sbin/accept $(BINDIR)/enable
+ $(INSTALL_BIN) lp $(BINDIR)
+ $(INSTALL_BIN) lpoptions $(BINDIR)
+ $(INSTALL_BIN) lpstat $(BINDIR)
+ $(INSTALL_BIN) lppasswd $(BINDIR)
+ -$(INSTALL_BIN) -m 4755 -o $(CUPS_USER) -g $(CUPS_GROUP) lppasswd $(BINDIR)
+
+
+#
+# accept
+#
+
+accept: accept.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o accept accept.o $(LIBS)
+ $(RM) reject enable disable
+ $(LN) accept reject
+ $(LN) accept enable
+ $(LN) accept disable
+
+
+#
+# cancel
+#
+
+cancel: cancel.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o cancel cancel.o $(LIBS)
+
+
+#
+# cupsaddsmb
+#
+
+cupsaddsmb: cupsaddsmb.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o cupsaddsmb cupsaddsmb.o $(LIBS)
+
+
+#
+# lp
+#
+
+lp: lp.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lp lp.o $(LIBS)
+
+
+#
+# lpadmin
+#
+
+lpadmin: lpadmin.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpadmin lpadmin.o $(LIBZ) $(LIBS)
+
+
+#
+# lpinfo
+#
+
+lpinfo: lpinfo.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpinfo lpinfo.o $(LIBS)
+
+
+#
+# lpmove
+#
+
+lpmove: lpmove.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpmove lpmove.o $(LIBS)
+
+
+#
+# lpoptions
+#
+
+lpoptions: lpoptions.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpoptions lpoptions.o $(LIBZ) $(LIBS)
+
+
+#
+# lppasswd
+#
+
+lppasswd: lppasswd.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lppasswd lppasswd.o $(LIBZ) $(LIBS)
+
+
+#
+# lpstat
+#
+
+lpstat: lpstat.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpstat lpstat.o $(LIBS)
+
+
+#
+# Dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id$".
+#
diff --git a/systemv/accept.c b/systemv/accept.c
new file mode 100644
index 000000000..50e7bd19d
--- /dev/null
+++ b/systemv/accept.c
@@ -0,0 +1,286 @@
+/*
+ * "$Id$"
+ *
+ * "accept", "disable", "enable", and "reject" commands for the Common
+ * UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and accept/reject jobs or disable/enable printers.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <config.h>
+#include <cups/cups.h>
+#include <cups/string.h>
+#include <cups/language.h>
+
+
+/*
+ * 'main()' - Parse options and accept/reject jobs or disable/enable printers.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ http_t *http; /* HTTP connection to server */
+ int i; /* Looping var */
+ char *command, /* Command to do */
+ uri[1024], /* Printer URI */
+ *reason; /* Reason for reject/disable */
+ ipp_t *request; /* IPP request */
+ ipp_t *response; /* IPP response */
+ ipp_op_t op; /* Operation */
+ cups_lang_t *language; /* Language */
+ int cancel; /* Cancel jobs? */
+
+
+ /*
+ * See what operation we're supposed to do...
+ */
+
+ if ((command = strrchr(argv[0], '/')) != NULL)
+ command ++;
+ else
+ command = argv[0];
+
+ cancel = 0;
+
+ if (strcmp(command, "accept") == 0)
+ op = CUPS_ACCEPT_JOBS;
+ else if (strcmp(command, "reject") == 0)
+ op = CUPS_REJECT_JOBS;
+ else if (strcmp(command, "disable") == 0)
+ op = IPP_PAUSE_PRINTER;
+ else if (strcmp(command, "enable") == 0)
+ op = IPP_RESUME_PRINTER;
+ else
+ {
+ fprintf(stderr, "%s: Don't know what to do!\n", command);
+ return (1);
+ }
+
+ http = NULL;
+ reason = NULL;
+
+ /*
+ * Process command-line arguments...
+ */
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ switch (argv[i][1])
+ {
+ case 'E' : /* Encrypt */
+#ifdef HAVE_LIBSSL
+ cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+
+ if (http)
+ httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+#else
+ fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
+ command);
+#endif /* HAVE_LIBSSL */
+ break;
+
+ case 'c' : /* Cancel jobs */
+ cancel = 1;
+ break;
+
+ case 'h' : /* Connect to host */
+ if (http != NULL)
+ httpClose(http);
+
+ if (argv[i][2] != '\0')
+ cupsSetServer(argv[i] + 2);
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ fprintf(stderr, "%s: Expected server name after -h!\n",
+ command);
+ return (1);
+ }
+
+ cupsSetServer(argv[i]);
+ }
+ break;
+
+ case 'r' : /* Reason for cancellation */
+ if (argv[i][2] != '\0')
+ reason = argv[i] + 2;
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ fprintf(stderr, "%s: Expected reason text after -r!\n", command);
+ return (1);
+ }
+
+ reason = argv[i];
+ }
+ break;
+
+ default :
+ fprintf(stderr, "%s: Unknown option \'%c\'!\n", command,
+ argv[i][1]);
+ return (1);
+ }
+ else
+ {
+ /*
+ * Accept/disable/enable/reject a destination...
+ */
+
+ if (http == NULL)
+ http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
+
+ if (http == NULL)
+ {
+ fputs(command, stderr);
+ perror(": Unable to connect to server");
+ return (1);
+ }
+
+ /*
+ * Build an IPP request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * printer-state-message [optional]
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = op;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", argv[i]);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ if (reason != NULL)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT,
+ "printer-state-message", NULL, reason);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "%s: Operation failed: %s\n", command,
+ ippErrorString(cupsLastError()));
+ return (1);
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ fprintf(stderr, "%s: Operation failed: %s\n", command,
+ ippErrorString(cupsLastError()));
+ return (1);
+ }
+
+ /*
+ * Cancel all jobs if requested...
+ */
+
+ if (cancel)
+ {
+ /*
+ * Build an IPP_PURGE_JOBS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_PURGE_JOBS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "%s: Operation failed: %s\n", command,
+ ippErrorString(cupsLastError()));
+ return (1);
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ fprintf(stderr, "%s: Operation failed: %s\n", command,
+ ippErrorString(cupsLastError()));
+ return (1);
+ }
+ }
+ }
+
+ if (http != NULL)
+ httpClose(http);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/systemv/cancel.c b/systemv/cancel.c
new file mode 100644
index 000000000..fbd84fb00
--- /dev/null
+++ b/systemv/cancel.c
@@ -0,0 +1,291 @@
+/*
+ * "$Id$"
+ *
+ * "cancel" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and cancel jobs.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <config.h>
+#include <cups/cups.h>
+#include <cups/string.h>
+#include <cups/language.h>
+
+
+/*
+ * 'main()' - Parse options and cancel jobs.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ http_t *http; /* HTTP connection to server */
+ int i; /* Looping var */
+ int job_id; /* Job ID */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dests; /* Destinations */
+ char *dest, /* Destination printer */
+ *job; /* Job ID pointer */
+ char uri[1024]; /* Printer or job URI */
+ ipp_t *request; /* IPP request */
+ ipp_t *response; /* IPP response */
+ ipp_op_t op; /* Operation */
+ cups_lang_t *language; /* Language */
+
+
+ /*
+ * Setup to cancel individual print jobs...
+ */
+
+ op = IPP_CANCEL_JOB;
+ job_id = 0;
+ dest = NULL;
+ http = NULL;
+ num_dests = 0;
+ dests = NULL;
+
+ /*
+ * Process command-line arguments...
+ */
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-' && argv[i][1])
+ switch (argv[i][1])
+ {
+ case 'E' : /* Encrypt */
+#ifdef HAVE_LIBSSL
+ cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+
+ if (http)
+ httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+#else
+ fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
+ argv[0]);
+#endif /* HAVE_LIBSSL */
+ break;
+
+ case 'a' : /* Cancel all jobs */
+ op = IPP_PURGE_JOBS;
+ break;
+
+ case 'h' : /* Connect to host */
+ if (http != NULL)
+ httpClose(http);
+
+ if (argv[i][2] != '\0')
+ cupsSetServer(argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("cancel: Error - expected hostname after \'-h\' option!\n", stderr);
+ return (1);
+ }
+ else
+ cupsSetServer(argv[i]);
+ }
+ break;
+
+ case 'u' : /* Username */
+ if (argv[i][2] != '\0')
+ cupsSetUser(argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("cancel: Error - expected username after \'-u\' option!\n", stderr);
+ return (1);
+ }
+ else
+ cupsSetUser(argv[i]);
+ }
+ break;
+
+ default :
+ fprintf(stderr, "cancel: Unknown option \'%c\'!\n", argv[i][1]);
+ return (1);
+ }
+ else
+ {
+ /*
+ * Cancel a job or printer...
+ */
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if (strcmp(argv[i], "-") == 0)
+ {
+ /*
+ * Delete the current job...
+ */
+
+ dest = "";
+ job_id = 0;
+ }
+ else if (cupsGetDest(argv[i], NULL, num_dests, dests) != NULL)
+ {
+ /*
+ * Delete the current job on the named destination...
+ */
+
+ dest = argv[i];
+ job_id = 0;
+ }
+ else if ((job = strrchr(argv[i], '-')) != NULL && isdigit(job[1]))
+ {
+ /*
+ * Delete the specified job ID.
+ */
+
+ dest = NULL;
+ op = IPP_CANCEL_JOB;
+ job_id = atoi(job + 1);
+ }
+ else if (isdigit(argv[i][0]))
+ {
+ /*
+ * Delete the specified job ID.
+ */
+
+ dest = NULL;
+ op = IPP_CANCEL_JOB;
+ job_id = atoi(argv[i]);
+ }
+ else
+ {
+ /*
+ * Bad printer name!
+ */
+
+ fprintf(stderr, "cancel: Unknown destination \"%s\"!\n", argv[i]);
+ }
+
+ /*
+ * For Solaris LP compatibility, ignore a destination name after
+ * cancelling a specific job ID...
+ */
+
+ if (job_id && (i + 1) < argc &&
+ cupsGetDest(argv[i + 1], NULL, num_dests, dests) != NULL)
+ i ++;
+
+ /*
+ * Open a connection to the server...
+ */
+
+ if (http == NULL)
+ if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption())) == NULL)
+ {
+ fputs("cancel: Unable to contact server!\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Build an IPP request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri + job-id *or* job-uri
+ * [requesting-user-name]
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = op;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ if (dest)
+ {
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", dest);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
+ job_id);
+ }
+ else
+ {
+ sprintf(uri, "ipp://localhost/jobs/%d", job_id);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
+ uri);
+ }
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if (op == IPP_PURGE_JOBS)
+ response = cupsDoRequest(http, request, "/admin/");
+ else
+ response = cupsDoRequest(http, request, "/jobs/");
+
+ if (response == NULL ||
+ response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "cancel: %s failed: %s\n",
+ op == IPP_PURGE_JOBS ? "purge-jobs" : "cancel-job",
+ response ? ippErrorString(response->request.status.status_code) :
+ ippErrorString(cupsLastError()));
+
+ if (response)
+ ippDelete(response);
+
+ return (1);
+ }
+
+ ippDelete(response);
+ }
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/systemv/cupsaddsmb.c b/systemv/cupsaddsmb.c
new file mode 100644
index 000000000..1356cbf65
--- /dev/null
+++ b/systemv/cupsaddsmb.c
@@ -0,0 +1,528 @@
+/*
+ * "$Id$"
+ *
+ * "cupsaddsmb" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 2001-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Export printers on the command-line.
+ * do_samba_command() - Do a SAMBA command, asking for a password as needed.
+ * export_dest() - Export a destination to SAMBA.
+ * usage() - Show program usage and exit...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <cups/string.h>
+#include <errno.h>
+
+
+/*
+ * Local globals...
+ */
+
+int Verbosity = 0;
+const char *SAMBAUser,
+ *SAMBAServer;
+
+
+/*
+ * Local functions...
+ */
+
+int do_samba_command(const char *, const char *);
+int export_dest(const char *);
+void usage();
+
+
+/*
+ * 'main()' - Export printers on the command-line.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i, j; /* Looping vars */
+ int status; /* Status from export_dest() */
+ int export_all; /* Export all printers? */
+ int num_printers; /* Number of printers */
+ char **printers; /* Printers */
+
+
+ /*
+ * Parse command-line arguments...
+ */
+
+ export_all = 0;
+
+ SAMBAUser = cupsUser();
+ SAMBAServer = NULL;
+
+ for (i = 1; i < argc; i ++)
+ if (strcmp(argv[i], "-a") == 0)
+ export_all = 1;
+ else if (strcmp(argv[i], "-U") == 0)
+ {
+ i ++;
+ if (i >= argc)
+ usage();
+
+ SAMBAUser = argv[i];
+ }
+ else if (strcmp(argv[i], "-H") == 0)
+ {
+ i ++;
+ if (i >= argc)
+ usage();
+
+ SAMBAServer = argv[i];
+ }
+ else if (strcmp(argv[i], "-h") == 0)
+ {
+ i ++;
+ if (i >= argc)
+ usage();
+
+ cupsSetServer(argv[i]);
+ }
+ else if (strcmp(argv[i], "-v") == 0)
+ Verbosity = 1;
+ else if (argv[i][0] != '-')
+ {
+ if (SAMBAServer == NULL)
+ SAMBAServer = cupsServer();
+
+ if ((status = export_dest(argv[i])) != 0)
+ return (status);
+ }
+ else
+ usage();
+
+ /*
+ * See if the user specified "-a"...
+ */
+
+ if (export_all)
+ {
+ /*
+ * Export all printers...
+ */
+
+ if (SAMBAServer == NULL)
+ SAMBAServer = cupsServer();
+
+ num_printers = cupsGetPrinters(&printers);
+
+ for (j = 0, status = 0; j < num_printers; j ++)
+ if ((status = export_dest(printers[j])) != 0)
+ break;
+
+ for (j = 0; j < num_printers; j ++)
+ free(printers[j]);
+
+ if (num_printers)
+ free(printers);
+
+ if (status)
+ return (status);
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'do_samba_command()' - Do a SAMBA command, asking for
+ * a password as needed.
+ */
+
+int /* O - Status of command */
+do_samba_command(const char *command, /* I - Command to run */
+ const char *subcmd) /* I - Sub-command */
+{
+ int status; /* Status of command */
+ char temp[4096]; /* Command/prompt string */
+ static const char *p = NULL; /* Password data */
+
+
+ for (status = 1;;)
+ {
+ if (p == NULL)
+ {
+ snprintf(temp, sizeof(temp),
+ "Password for %s required to access %s via SAMBA: ",
+ SAMBAUser, SAMBAServer);
+
+ if ((p = cupsGetPassword(temp)) == NULL)
+ break;
+ }
+
+ snprintf(temp, sizeof(temp), "%s -N -U\'%s%%%s\' -c \'%s\'",
+ command, SAMBAUser, p, subcmd);
+
+ if (Verbosity)
+ printf("Running command: %s\n", temp);
+ else
+ strlcat(temp, " </dev/null >/dev/null 2>/dev/null", sizeof(temp));
+
+ if ((status = system(temp)) != 0)
+ {
+ if (Verbosity)
+ puts("");
+
+ if (p[0])
+ p = NULL;
+ else
+ break;
+ }
+ else
+ {
+ if (Verbosity)
+ puts("");
+
+ break;
+ }
+ }
+
+ return (status);
+}
+
+
+/*
+ * 'export_dest()' - Export a destination to SAMBA.
+ */
+
+int /* O - 0 on success, non-zero on error */
+export_dest(const char *dest) /* I - Destination to export */
+{
+ int i; /* Looping var */
+ int status; /* Status of smbclient/rpcclient commands */
+ const char *ppdfile; /* PPD file for printer drivers */
+ char command[1024], /* Command to run */
+ subcmd[1024]; /* Sub-command */
+ const char *datadir; /* CUPS_DATADIR */
+ FILE *fp; /* PPD file */
+ http_t *http; /* Connection to server */
+ cups_lang_t *language; /* Default language */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ ipp_attribute_t *attr; /* IPP attribute */
+ static const char *pattrs[] = /* Printer attributes we want */
+ {
+ "job-sheets-supported",
+ "job-sheets-default"
+ };
+
+
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+ datadir = CUPS_DATADIR;
+
+ /*
+ * Get the PPD file...
+ */
+
+ if ((ppdfile = cupsGetPPD(dest)) == NULL)
+ {
+ fprintf(stderr, "Warning: No PPD file for printer \"%s\" - skipping!\n", dest);
+ return (0);
+ }
+
+ /*
+ * Append the supported banner pages to the PPD file...
+ */
+
+ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL)
+ {
+ fprintf(stderr, "Unable to connect to server \"%s\" for %s - %s\n",
+ cupsServer(), dest, strerror(errno));
+ unlink(ppdfile);
+ return (1);
+ }
+
+ request = ippNew();
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(command, sizeof(command), "ipp://localhost/printers/%s", dest);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, command);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
+ NULL, pattrs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "ERROR: get-printer-attributes failed for %s: %s\n",
+ dest, ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ unlink(ppdfile);
+ return (2);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: get-printer-attributes failed for %s: %s\n",
+ dest, ippErrorString(cupsLastError()));
+ unlink(ppdfile);
+ return (2);
+ }
+
+ /*
+ * Append the banner attributes to the end of the PPD file...
+ */
+
+ if ((fp = fopen(ppdfile, "a")) == NULL)
+ {
+ fprintf(stderr, "ERROR: Unable to append banner attributes to PPD file for %s - %s\n",
+ dest, strerror(errno));
+ ippDelete(response);
+ unlink(ppdfile);
+ return (3);
+ }
+
+ if ((attr = ippFindAttribute(response, "job-sheets-supported", IPP_TAG_NAME)) != NULL)
+ {
+ fprintf(fp, "*cupsJobSheetsSupported: \"%s", attr->values[0].string.text);
+
+ for (i = 1; i < attr->num_values; i ++)
+ fprintf(fp, ",%s", attr->values[i].string.text);
+
+ fputs("\"\n", fp);
+ }
+
+ if ((attr = ippFindAttribute(response, "job-sheets-default", IPP_TAG_NAME)) != NULL)
+ {
+ fprintf(fp, "*cupsJobSheetsDefault: \"%s", attr->values[0].string.text);
+
+ if (attr->num_values > 1)
+ fprintf(fp, ",%s", attr->values[1].string.text);
+
+ fputs("\"\n", fp);
+ }
+
+ fclose(fp);
+
+ ippDelete(response);
+ cupsLangFree(language);
+ httpClose(http);
+
+ /*
+ * See which drivers are available - the new CUPS drivers or the
+ * Adobe drivers?
+ */
+
+ snprintf(command, sizeof(command), "%s/drivers/cupsdrvr.dll", datadir);
+ if (access(command, 0) == 0)
+ {
+ /*
+ * Do the smbclient commands needed for the CUPS WinNT drivers...
+ */
+
+ snprintf(command, sizeof(command), "smbclient //%s/print\\$", SAMBAServer);
+
+ snprintf(subcmd, sizeof(subcmd),
+ "mkdir W32X86;"
+ "put %s W32X86/%s.ppd;"
+ "put %s/drivers/cupsdrvr.dll W32X86/cupsdrvr.dll;"
+ "put %s/drivers/cupsui.dll W32X86/cupsui.dll;"
+ "put %s/drivers/cups.hlp W32X86/cups.hlp",
+ ppdfile, dest, datadir, datadir, datadir);
+
+ if ((status = do_samba_command(command, subcmd)) != 0)
+ {
+ fprintf(stderr, "ERROR: Unable to copy Windows printer driver files (%d)!\n",
+ status);
+ unlink(ppdfile);
+ return (4);
+ }
+
+ /*
+ * Do the rpcclient commands needed for the CUPS WinNT drivers...
+ */
+
+ snprintf(subcmd, sizeof(subcmd),
+ "adddriver \"Windows NT x86\" \"%s:cupsdrvr.dll:%s.ppd:cupsui.dll:cups.hlp:NULL:RAW:NULL\"",
+ dest, dest);
+
+ snprintf(command, sizeof(command), "rpcclient %s", SAMBAServer);
+
+ if ((status = do_samba_command(command, subcmd)) != 0)
+ {
+ fprintf(stderr, "ERROR: Unable to install Windows printer driver files (%d)!\n",
+ status);
+ unlink(ppdfile);
+ return (5);
+ }
+ }
+ else
+ {
+ /*
+ * Do the smbclient commands needed for the Adobe WinNT drivers...
+ */
+
+ snprintf(command, sizeof(command), "smbclient //%s/print\\$", SAMBAServer);
+
+ snprintf(subcmd, sizeof(subcmd),
+ "mkdir W32X86;"
+ "put %s W32X86/%s.PPD;"
+ "put %s/drivers/ADOBEPS5.DLL W32X86/ADOBEPS5.DLL;"
+ "put %s/drivers/ADOBEPSU.DLL W32X86/ADOBEPSU.DLL;"
+ "put %s/drivers/ADOBEPSU.HLP W32X86/ADOBEPSU.HLP",
+ ppdfile, dest, datadir, datadir, datadir);
+
+ if ((status = do_samba_command(command, subcmd)) != 0)
+ {
+ fprintf(stderr, "ERROR: Unable to copy Windows printer driver files (%d)!\n",
+ status);
+ unlink(ppdfile);
+ return (4);
+ }
+
+ /*
+ * Do the rpcclient commands needed for the Adobe WinNT drivers...
+ */
+
+ snprintf(subcmd, sizeof(subcmd),
+ "adddriver \"Windows NT x86\" \"%s:ADOBEPS5.DLL:%s.PPD:ADOBEPSU.DLL:ADOBEPSU.HLP:NULL:RAW:NULL\"",
+ dest, dest);
+
+ snprintf(command, sizeof(command), "rpcclient %s", SAMBAServer);
+
+ if ((status = do_samba_command(command, subcmd)) != 0)
+ {
+ fprintf(stderr, "ERROR: Unable to install Windows printer driver files (%d)!\n",
+ status);
+ unlink(ppdfile);
+ return (5);
+ }
+ }
+
+ snprintf(command, sizeof(command), "%s/drivers/ADOBEPS4.DRV", datadir);
+ if (access(command, 0) == 0)
+ {
+ /*
+ * Do the smbclient commands needed for the Adobe Win9x drivers...
+ */
+
+ snprintf(command, sizeof(command), "smbclient //%s/print\\$", SAMBAServer);
+
+ snprintf(subcmd, sizeof(subcmd),
+ "mkdir WIN40;"
+ "put %s WIN40/%s.PPD;"
+ "put %s/drivers/ADFONTS.MFM WIN40/ADFONTS.MFM;"
+ "put %s/drivers/ADOBEPS4.DRV WIN40/ADOBEPS4.DRV;"
+ "put %s/drivers/ADOBEPS4.HLP WIN40/ADOBEPS4.HLP;"
+ "put %s/drivers/DEFPRTR2.PPD WIN40/DEFPRTR2.PPD;"
+ "put %s/drivers/ICONLIB.DLL WIN40/ICONLIB.DLL;"
+ "put %s/drivers/PSMON.DLL WIN40/PSMON.DLL;",
+ ppdfile, dest, datadir, datadir, datadir,
+ datadir, datadir, datadir);
+
+ if ((status = do_samba_command(command, subcmd)) != 0)
+ {
+ fprintf(stderr, "ERROR: Unable to copy Windows printer driver files (%d)!\n",
+ status);
+ unlink(ppdfile);
+ return (6);
+ }
+
+ /*
+ * Do the rpcclient commands needed for the Adobe Win9x drivers...
+ */
+
+ snprintf(subcmd, sizeof(subcmd),
+ "adddriver \"Windows 4.0\" \"%s:ADOBEPS4.DRV:%s.PPD:NULL:ADOBEPS4.HLP:PSMON.DLL:RAW:"
+ "ADOBEPS4.DRV:%s.PPD,ADOBEPS4.HLP,PSMON.DLL,ADFONTS.MFM,DEFPRTR2.PPD,ICONLIB.DLL\"",
+ dest, dest, dest);
+
+ if ((status = do_samba_command(command, subcmd)) != 0)
+ {
+ fprintf(stderr, "ERROR: Unable to install Windows printer driver files (%d)!\n",
+ status);
+ unlink(ppdfile);
+ return (7);
+ }
+ }
+
+ unlink(ppdfile);
+
+ /*
+ * Finally, associate the drivers we just added with the queue...
+ */
+
+ snprintf(subcmd, sizeof(subcmd), "setdriver %s %s", dest, dest);
+
+ if ((status = do_samba_command(command, subcmd)) != 0)
+ {
+ fprintf(stderr, "ERROR: Unable to install Windows printer driver files (%d)!\n",
+ status);
+ return (8);
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'usage()' - Show program usage and exit...
+ */
+
+void
+usage()
+{
+ puts("Usage: cupsaddsmb [options] printer1 ... printerN");
+ puts(" cupsaddsmb [options] -a");
+ puts("");
+ puts("Options:");
+ puts(" -H samba-server Use the named SAMBA server");
+ puts(" -U samba-user Authenticate using the named SAMBA user");
+ puts(" -a Export all printers");
+ puts(" -h cups-server Use the named CUPS server");
+ puts(" -v Be verbose (show commands)");
+ exit(1);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/systemv/lp.c b/systemv/lp.c
new file mode 100644
index 000000000..75c0d3b18
--- /dev/null
+++ b/systemv/lp.c
@@ -0,0 +1,659 @@
+/*
+ * "$Id$"
+ *
+ * "lp" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and send files for printing.
+ * sighandler() - Signal catcher for when we print from stdin...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cups/cups.h>
+#include <cups/string.h>
+#include <cups/language.h>
+
+
+#ifndef WIN32
+# include <signal.h>
+
+
+/*
+ * Local functions.
+ */
+
+void sighandler(int);
+#endif /* !WIN32 */
+int set_job_attrs(int job_id, int num_options, cups_option_t *options);
+
+
+/*
+ * Globals...
+ */
+
+char tempfile[1024]; /* Temporary file for printing from stdin */
+
+
+/*
+ * 'main()' - Parse options and send files for printing.
+ */
+
+int
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i, j; /* Looping vars */
+ int job_id; /* Job ID */
+ char *printer, /* Printer name */
+ *instance, /* Instance name */
+ *val, /* Option value */
+ *title; /* Job title */
+ int priority; /* Job priority (1-100) */
+ int num_copies; /* Number of copies per file */
+ int num_files; /* Number of files to print */
+ const char *files[1000]; /* Files to print */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dests, /* Destinations */
+ *dest; /* Selected destination */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ int silent; /* Silent or verbose output? */
+ char buffer[8192]; /* Copy buffer */
+ int temp; /* Temporary file descriptor */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Signal action */
+ struct sigaction oldaction; /* Old signal action */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET*/
+
+
+#ifdef __sun
+ /*
+ * Solaris does some rather strange things to re-queue remote print
+ * jobs. On bootup, the "lp" command is run as "printd" to re-spool
+ * any remote jobs in /var/spool/print. Since CUPS doesn't need this
+ * nonsense, we just need to add the necessary check here to prevent
+ * lp from causing boot problems...
+ */
+
+ if ((val = strrchr(argv[0], '/')) != NULL)
+ val ++;
+ else
+ val = argv[0];
+
+ if (strcmp(val, "printd") == 0)
+ return (0);
+#endif /* __sun */
+
+ silent = 0;
+ printer = NULL;
+ num_dests = 0;
+ dests = NULL;
+ num_options = 0;
+ options = NULL;
+ num_files = 0;
+ title = NULL;
+ job_id = 0;
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ switch (argv[i][1])
+ {
+ case 'E' : /* Encrypt */
+#ifdef HAVE_LIBSSL
+ cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+#else
+ fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
+ argv[0]);
+#endif /* HAVE_LIBSSL */
+ break;
+
+ case 'c' : /* Copy to spool dir (always enabled) */
+ break;
+
+ case 'd' : /* Destination printer or class */
+ if (argv[i][2] != '\0')
+ printer = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected destination after -d option!\n", stderr);
+ return (1);
+ }
+
+ printer = argv[i];
+ }
+
+ if ((instance = strrchr(printer, '/')) != NULL)
+ *instance++ = '\0';
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != NULL)
+ {
+ for (j = 0; j < dest->num_options; j ++)
+ if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
+ num_options = cupsAddOption(dest->options[j].name,
+ dest->options[j].value,
+ num_options, &options);
+ }
+ break;
+
+ case 'f' : /* Form */
+ if (!argv[i][2])
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected form after -f option!\n", stderr);
+ return (1);
+ }
+ }
+
+ fputs("lp: Warning - form option ignored!\n", stderr);
+ break;
+
+ case 'h' : /* Destination host */
+ if (argv[i][2] != '\0')
+ cupsSetServer(argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected hostname after -h option!\n", stderr);
+ return (1);
+ }
+
+ cupsSetServer(argv[i]);
+ }
+ break;
+
+ case 'i' : /* Change job */
+ if (argv[i][2])
+ val = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected job ID after -i option!\n", stderr);
+ return (1);
+ }
+
+ val = argv[i];
+ }
+
+ if (num_files > 0)
+ {
+ fputs("lp: Error - cannot print files and alter jobs simultaneously!\n", stderr);
+ return (1);
+ }
+
+ if (strrchr(val, '-') != NULL)
+ job_id = atoi(strrchr(val, '-') + 1);
+ else
+ job_id = atoi(val);
+
+ if (job_id < 0)
+ {
+ fputs("lp: Error - bad job ID!\n", stderr);
+ break;
+ }
+ break;
+
+ case 'm' : /* Send email when job is done */
+#ifdef __sun
+ case 'p' : /* Notify on completion */
+#endif /* __sun */
+ case 'w' : /* Write to console or email */
+ break;
+
+ case 'n' : /* Number of copies */
+ if (argv[i][2] != '\0')
+ num_copies = atoi(argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected copies after -n option!\n", stderr);
+ return (1);
+ }
+
+ num_copies = atoi(argv[i]);
+ }
+
+ if (num_copies < 1 || num_copies > 100)
+ {
+ fputs("lp: Number copies must be between 1 and 100.\n", stderr);
+ return (1);
+ }
+
+ sprintf(buffer, "%d", num_copies);
+ num_options = cupsAddOption("copies", buffer, num_options, &options);
+ break;
+
+ case 'o' : /* Option */
+ if (argv[i][2] != '\0')
+ num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected option string after -o option!\n", stderr);
+ return (1);
+ }
+
+ num_options = cupsParseOptions(argv[i], num_options, &options);
+ }
+ break;
+
+#ifndef __sun
+ case 'p' : /* Queue priority */
+#endif /* !__sun */
+ case 'q' : /* Queue priority */
+ if (argv[i][2] != '\0')
+ priority = atoi(argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fprintf(stderr, "lp: Expected priority after -%c option!\n",
+ argv[i - 1][1]);
+ return (1);
+ }
+
+ priority = atoi(argv[i]);
+ }
+
+ /*
+ * For 100% Solaris compatibility, need to add:
+ *
+ * priority = 99 * (39 - priority) / 39 + 1;
+ *
+ * However, to keep CUPS lp the same across all platforms
+ * we will break compatibility this far...
+ */
+
+ if (priority < 1 || priority > 100)
+ {
+ fputs("lp: Priority must be between 1 and 100.\n", stderr);
+ return (1);
+ }
+
+ sprintf(buffer, "%d", priority);
+ num_options = cupsAddOption("job-priority", buffer, num_options, &options);
+ break;
+
+ case 's' : /* Silent */
+ silent = 1;
+ break;
+
+ case 't' : /* Title */
+ if (argv[i][2] != '\0')
+ title = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected title after -t option!\n", stderr);
+ return (1);
+ }
+
+ title = argv[i];
+ }
+ break;
+
+ case 'y' : /* mode-list */
+ if (!argv[i][2])
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected mode list after -y option!\n", stderr);
+ return (1);
+ }
+ }
+
+ fputs("lp: Warning - mode option ignored!\n", stderr);
+ break;
+
+ case 'H' : /* Hold job */
+ if (argv[i][2])
+ val = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected hold name after -H option!\n", stderr);
+ return (1);
+ }
+
+ val = argv[i];
+ }
+
+ if (strcmp(val, "hold") == 0)
+ num_options = cupsAddOption("job-hold-until", "indefinite",
+ num_options, &options);
+ else if (strcmp(val, "resume") == 0 ||
+ strcmp(val, "release") == 0)
+ num_options = cupsAddOption("job-hold-until", "no-hold",
+ num_options, &options);
+ else if (strcmp(val, "immediate") == 0)
+ num_options = cupsAddOption("job-priority", "100",
+ num_options, &options);
+ else
+ num_options = cupsAddOption("job-hold-until", val,
+ num_options, &options);
+ break;
+
+ case 'P' : /* Page list */
+ if (argv[i][2])
+ val = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected page list after -P option!\n", stderr);
+ return (1);
+ }
+
+ val = argv[i];
+ }
+
+ num_options = cupsAddOption("page-ranges", val, num_options,
+ &options);
+ break;
+
+ case 'S' : /* character set */
+ if (!argv[i][2])
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected character set after -S option!\n", stderr);
+ return (1);
+ }
+ }
+
+ fputs("lp: Warning - character set option ignored!\n", stderr);
+ break;
+
+ case 'T' : /* Content-Type */
+ if (!argv[i][2])
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lp: Expected content type after -T option!\n", stderr);
+ return (1);
+ }
+ }
+
+ fputs("lp: Warning - content type option ignored!\n", stderr);
+ break;
+
+ default :
+ fprintf(stderr, "lp: Unknown option \'%c\'!\n", argv[i][1]);
+ return (1);
+ }
+ else if (num_files < 1000 && job_id == 0)
+ {
+ /*
+ * Print a file...
+ */
+
+ files[num_files] = argv[i];
+ num_files ++;
+
+ if (title == NULL)
+ {
+ if ((title = strrchr(argv[i], '/')) != NULL)
+ title ++;
+ else
+ title = argv[i];
+ }
+ }
+ else
+ fprintf(stderr, "lp: Too many files - \"%s\"\n", argv[i]);
+
+ /*
+ * See if we are altering an existing job...
+ */
+
+ if (job_id)
+ return (set_job_attrs(job_id, num_options, options));
+
+ /*
+ * See if we have any files to print; if not, print from stdin...
+ */
+
+ if (printer == NULL)
+ {
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ for (j = 0, dest = dests; j < num_dests; j ++, dest ++)
+ if (dest->is_default)
+ {
+ printer = dests[j].name;
+
+ for (j = 0; j < dest->num_options; j ++)
+ if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
+ num_options = cupsAddOption(dest->options[j].name,
+ dest->options[j].value,
+ num_options, &options);
+ break;
+ }
+ }
+
+ if (printer == NULL)
+ {
+ fputs("lp: error - no default destination available.\n", stderr);
+ return (1);
+ }
+
+ if (num_files > 0)
+ job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options);
+ else
+ {
+ num_files = 1;
+
+#ifndef WIN32
+# if defined(HAVE_SIGSET)
+ sigset(SIGHUP, sighandler);
+ if (sigset(SIGINT, sighandler) == SIG_IGN)
+ sigset(SIGINT, SIG_IGN);
+ sigset(SIGTERM, sighandler);
+# elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = sighandler;
+
+ sigaction(SIGHUP, &action, NULL);
+ sigaction(SIGINT, NULL, &oldaction);
+ if (oldaction.sa_handler != SIG_IGN)
+ sigaction(SIGINT, &action, NULL);
+ sigaction(SIGTERM, &action, NULL);
+# else
+ signal(SIGHUP, sighandler);
+ if (signal(SIGINT, sighandler) == SIG_IGN)
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, sighandler);
+# endif
+#endif /* !WIN32 */
+
+ temp = cupsTempFd(tempfile, sizeof(tempfile));
+
+ if (temp < 0)
+ {
+ fputs("lp: unable to create temporary file.\n", stderr);
+ return (1);
+ }
+
+ while ((i = read(0, buffer, sizeof(buffer))) > 0)
+ write(temp, buffer, i);
+
+ i = lseek(temp, 0, SEEK_CUR);
+ close(temp);
+
+ if (i == 0)
+ {
+ fputs("lp: stdin is empty, so no job has been sent.\n", stderr);
+ return (1);
+ }
+
+ if (title)
+ job_id = cupsPrintFile(printer, tempfile, title, num_options, options);
+ else
+ job_id = cupsPrintFile(printer, tempfile, "(stdin)", num_options, options);
+
+ unlink(tempfile);
+ }
+
+ if (job_id < 1)
+ {
+ fprintf(stderr, "lp: unable to print file: %s\n",
+ ippErrorString(cupsLastError()));
+ return (1);
+ }
+ else if (!silent)
+ printf("request id is %s-%d (%d file(s))\n", printer, job_id, num_files);
+
+ return (0);
+}
+
+
+/*
+ * 'set_job_attrs()' - Set job attributes.
+ */
+
+int /* O - Exit status */
+set_job_attrs(int job_id, /* I - Job ID */
+ int num_options,/* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ http_t *http; /* HTTP connection to server */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ cups_lang_t *language; /* Language for request */
+ char uri[HTTP_MAX_URI]; /* URI for job */
+
+
+ http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
+
+ language = cupsLangDefault();
+
+ request = ippNew();
+ request->request.op.operation_id = IPP_SET_JOB_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ sprintf(uri, "ipp://localhost/jobs/%d", job_id);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "job-uri", NULL, uri);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+
+ cupsEncodeOptions(request, num_options, options);
+
+ if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "lp: set-job-attributes failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return (1);
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ fprintf(stderr, "lp: set-job-attributes failed: %s\n",
+ ippErrorString(cupsLastError()));
+ return (1);
+ }
+
+ return (0);
+}
+
+
+#ifndef WIN32
+/*
+ * 'sighandler()' - Signal catcher for when we print from stdin...
+ */
+
+void
+sighandler(int s) /* I - Signal number */
+{
+ /*
+ * Remove the temporary file we're using to print from stdin...
+ */
+
+ unlink(tempfile);
+
+ /*
+ * Exit...
+ */
+
+ exit(s);
+}
+#endif /* !WIN32 */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/systemv/lpadmin.c b/systemv/lpadmin.c
new file mode 100644
index 000000000..56acd145a
--- /dev/null
+++ b/systemv/lpadmin.c
@@ -0,0 +1,1872 @@
+/*
+ * "$Id$"
+ *
+ * "lpadmin" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and configure the scheduler.
+ * add_printer_to_class() - Add a printer to a class.
+ * default_printer() - Set the default printing destination.
+ * delete_printer() - Delete a printer from the system...
+ * delete_printer_from_class() - Delete a printer from a class.
+ * enable_printer() - Enable a printer...
+ * set_printer_device() - Set the device-uri attribute.
+ * set_printer_file() - Set the interface script or PPD file.
+ * set_printer_info() - Set the printer description string.
+ * set_printer_location() - Set the printer location string.
+ * set_printer_model() - Set the driver model file.
+ * set_printer_options() - Set the printer options.
+ * validate_name() - Make sure the printer name only contains
+ * valid chars...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <cups/cups.h>
+#include <cups/string.h>
+#include <cups/language.h>
+#include <cups/debug.h>
+#include <config.h>
+#ifdef HAVE_LIBZ
+# include <zlib.h>
+#endif /* HAVE_LIBZ */
+
+
+/*
+ * Local functions...
+ */
+
+static void add_printer_to_class(http_t *, char *, char *);
+static void default_printer(http_t *, char *);
+static void delete_printer(http_t *, char *);
+static void delete_printer_from_class(http_t *, char *, char *);
+static void enable_printer(http_t *, char *);
+static char *get_line(char *, int, FILE *fp);
+static void set_printer_device(http_t *, char *, char *);
+static void set_printer_file(http_t *, char *, char *);
+static void set_printer_info(http_t *, char *, char *);
+static void set_printer_location(http_t *, char *, char *);
+static void set_printer_model(http_t *, char *, char *);
+static void set_printer_options(http_t *, char *, int, cups_option_t *);
+static int validate_name(const char *);
+
+
+/*
+ * 'main()' - Parse options and configure the scheduler.
+ */
+
+int
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ http_t *http; /* Connection to server */
+ char *printer, /* Destination printer */
+ *pclass, /* Printer class name */
+ *val; /* Pointer to allow/deny value */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+
+
+ http = NULL;
+ printer = NULL;
+ num_options = 0;
+ options = NULL;
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ switch (argv[i][1])
+ {
+ case 'c' : /* Add printer to class */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (printer == NULL)
+ {
+ fputs("lpadmin: Unable to add a printer to the class:\n", stderr);
+ fputs(" You must specify a printer name first!\n", stderr);
+ return (1);
+ }
+
+ if (argv[i][2])
+ pclass = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected class name after \'-c\' option!\n", stderr);
+ return (1);
+ }
+
+ pclass = argv[i];
+ }
+
+ if (!validate_name(pclass))
+ {
+ fputs("lpadmin: Class name can only contain printable characters!\n", stderr);
+ return (1);
+ }
+
+ add_printer_to_class(http, printer, pclass);
+ break;
+
+ case 'd' : /* Set as default destination */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (argv[i][2])
+ printer = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected printer name after \'-d\' option!\n", stderr);
+ return (1);
+ }
+
+ printer = argv[i];
+ }
+
+ if (!validate_name(printer))
+ {
+ fputs("lpadmin: Printer name can only contain printable characters!\n", stderr);
+ return (1);
+ }
+
+ default_printer(http, printer);
+ i = argc;
+ break;
+
+ case 'h' : /* Connect to host */
+ if (http)
+ {
+ httpClose(http);
+ http = NULL;
+ }
+
+ if (argv[i][2] != '\0')
+ cupsSetServer(argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected hostname after \'-h\' option!\n", stderr);
+ return (1);
+ }
+
+ cupsSetServer(argv[i]);
+ }
+ break;
+
+ case 'i' : /* Use the specified interface script */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (printer == NULL)
+ {
+ fputs("lpadmin: Unable to set the interface script:\n", stderr);
+ fputs(" You must specify a printer name first!\n", stderr);
+ return (1);
+ }
+
+ if (argv[i][2])
+ set_printer_file(http, printer, argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected interface after \'-i\' option!\n", stderr);
+ return (1);
+ }
+
+ set_printer_file(http, printer, argv[i]);
+ }
+ break;
+
+ case 'E' : /* Enable the printer */
+ if (printer == NULL)
+ {
+#ifdef HAVE_LIBSSL
+ cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+
+ if (http)
+ httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+#else
+ fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
+ argv[0]);
+#endif /* HAVE_LIBSSL */
+ break;
+ }
+
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ enable_printer(http, printer);
+ break;
+
+ case 'm' : /* Use the specified standard script/PPD file */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (printer == NULL)
+ {
+ fputs("lpadmin: Unable to set the interface script or PPD file:\n", stderr);
+ fputs(" You must specify a printer name first!\n", stderr);
+ return (1);
+ }
+
+ if (argv[i][2])
+ set_printer_model(http, printer, argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected model after \'-m\' option!\n", stderr);
+ return (1);
+ }
+
+ set_printer_model(http, printer, argv[i]);
+ }
+ break;
+
+ case 'o' : /* Set option */
+ if (argv[i][2])
+ num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected name=value after \'-o\' option!\n", stderr);
+ return (1);
+ }
+
+ num_options = cupsParseOptions(argv[i], num_options, &options);
+ }
+ break;
+
+ case 'p' : /* Add/modify a printer */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (argv[i][2])
+ printer = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected printer after \'-p\' option!\n", stderr);
+ return (1);
+ }
+
+ printer = argv[i];
+ }
+
+ if (!validate_name(printer))
+ {
+ fputs("lpadmin: Printer name can only contain printable characters!\n", stderr);
+ return (1);
+ }
+ break;
+
+ case 'r' : /* Remove printer from class */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (printer == NULL)
+ {
+ fputs("lpadmin: Unable to remove a printer from the class:\n", stderr);
+ fputs(" You must specify a printer name first!\n", stderr);
+ return (1);
+ }
+
+ if (argv[i][2])
+ pclass = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected class after \'-r\' option!\n", stderr);
+ return (1);
+ }
+
+ pclass = argv[i];
+ }
+
+ if (!validate_name(pclass))
+ {
+ fputs("lpadmin: Class name can only contain printable characters!\n", stderr);
+ return (1);
+ }
+
+ delete_printer_from_class(http, printer, pclass);
+ break;
+
+ case 'u' : /* Allow/deny users */
+ if (argv[i][2])
+ val = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected name=value after \'-o\' option!\n", stderr);
+ return (1);
+ }
+
+ val = argv[i];
+ }
+
+ if (strncasecmp(val, "allow:", 6) == 0)
+ num_options = cupsAddOption("requesting-user-name-allowed",
+ val + 6, num_options, &options);
+ else if (strncasecmp(val, "deny:", 5) == 0)
+ num_options = cupsAddOption("requesting-user-name-denied",
+ val + 5, num_options, &options);
+ else
+ {
+ fprintf(stderr, "lpadmin: Unknown allow/deny option \"%s\"!\n",
+ val);
+ return (1);
+ }
+ break;
+
+ case 'v' : /* Set the device-uri attribute */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (printer == NULL)
+ {
+ fputs("lpadmin: Unable to set the device URI:\n", stderr);
+ fputs(" You must specify a printer name first!\n", stderr);
+ return (1);
+ }
+
+ if (argv[i][2])
+ set_printer_device(http, printer, argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected device URI after \'-v\' option!\n", stderr);
+ return (1);
+ }
+
+ set_printer_device(http, printer, argv[i]);
+ }
+ break;
+
+ case 'x' : /* Delete a printer */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (argv[i][2])
+ printer = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected printer or class after \'-x\' option!\n", stderr);
+ return (1);
+ }
+
+ printer = argv[i];
+ }
+
+ if (!validate_name(printer))
+ {
+ fputs("lpadmin: Printer name can only contain printable characters!\n", stderr);
+ return (1);
+ }
+
+ delete_printer(http, printer);
+ i = argc;
+ break;
+
+ case 'D' : /* Set the printer-info attribute */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (printer == NULL)
+ {
+ fputs("lpadmin: Unable to set the printer description:\n", stderr);
+ fputs(" You must specify a printer name first!\n", stderr);
+ return (1);
+ }
+
+ if (argv[i][2])
+ set_printer_info(http, printer, argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected description after \'-D\' option!\n", stderr);
+ return (1);
+ }
+
+ set_printer_info(http, printer, argv[i]);
+ }
+ break;
+
+ case 'I' : /* Set the supported file types (ignored) */
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected file type(s) after \'-I\' option!\n", stderr);
+ return (1);
+ }
+
+ fputs("lpadmin: Warning - content type list ignored!\n", stderr);
+ break;
+
+ case 'L' : /* Set the printer-location attribute */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (printer == NULL)
+ {
+ fputs("lpadmin: Unable to set the printer location:\n", stderr);
+ fputs(" You must specify a printer name first!\n", stderr);
+ return (1);
+ }
+
+ if (argv[i][2])
+ set_printer_location(http, printer, argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected location after \'-L\' option!\n", stderr);
+ return (1);
+ }
+
+ set_printer_location(http, printer, argv[i]);
+ }
+ break;
+
+ case 'P' : /* Use the specified PPD file */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (printer == NULL)
+ {
+ fputs("lpadmin: Unable to set the PPD file:\n", stderr);
+ fputs(" You must specify a printer name first!\n", stderr);
+ return (1);
+ }
+
+ if (argv[i][2])
+ set_printer_file(http, printer, argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("lpadmin: Expected PPD after \'-P\' option!\n", stderr);
+ return (1);
+ }
+
+ set_printer_file(http, printer, argv[i]);
+ }
+ break;
+
+ default :
+ fprintf(stderr, "lpadmin: Unknown option \'%c\'!\n", argv[i][1]);
+ return (1);
+ }
+ else
+ {
+ fprintf(stderr, "lpadmin: Unknown argument \'%s\'!\n", argv[i]);
+ return (1);
+ }
+
+ /*
+ * Set options as needed...
+ */
+
+ if (num_options)
+ {
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpadmin: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (printer == NULL)
+ {
+ fputs("lpadmin: Unable to set the printer options:\n", stderr);
+ fputs(" You must specify a printer name first!\n", stderr);
+ return (1);
+ }
+
+ set_printer_options(http, printer, num_options, options);
+ }
+
+ if (printer == NULL)
+ {
+ puts("Usage:");
+ puts("");
+ puts(" lpadmin [-h server] -d destination");
+ puts(" lpadmin [-h server] -x destination");
+ puts(" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]");
+ puts(" [-r remove-class] [-v device] [-D description]");
+ puts(" [-P ppd-file] [-o name=value]");
+ puts(" [-u allow:user,user] [-u deny:user,user]");
+ puts("");
+ }
+
+ if (http)
+ httpClose(http);
+
+ return (0);
+}
+
+
+/*
+ * 'add_printer_to_class()' - Add a printer to a class.
+ */
+
+static void
+add_printer_to_class(http_t *http, /* I - Server connection */
+ char *printer, /* I - Printer to add */
+ char *pclass) /* I - Class to add to */
+{
+ int i; /* Looping var */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr, /* Current attribute */
+ *members; /* Members in class */
+ cups_lang_t *language; /* Default language */
+ char uri[HTTP_MAX_URI]; /* URI for printer/class */
+
+
+ DEBUG_printf(("add_printer_to_class(%p, \"%s\", \"%s\")\n", http,
+ printer, pclass));
+
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", pclass);
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ response = cupsDoRequest(http, request, "/");
+
+ /*
+ * Build a CUPS_ADD_CLASS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * member-uris
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_ADD_CLASS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * See if the printer is already in the class...
+ */
+
+ if (response != NULL &&
+ (members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) != NULL)
+ for (i = 0; i < members->num_values; i ++)
+ if (strcasecmp(printer, members->values[i].string.text) == 0)
+ {
+ fprintf(stderr, "lpadmin: Printer %s is already a member of class %s.\n",
+ printer, pclass);
+ ippDelete(request);
+ ippDelete(response);
+ return;
+ }
+
+ /*
+ * OK, the printer isn't part of the class, so add it...
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+
+ if (response != NULL &&
+ (members = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL)
+ {
+ /*
+ * Add the printer to the existing list...
+ */
+
+ attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI,
+ "member-uris", members->num_values + 1, NULL, NULL);
+ for (i = 0; i < members->num_values; i ++)
+ attr->values[i].string.text = strdup(members->values[i].string.text);
+
+ attr->values[i].string.text = strdup(uri);
+ }
+ else
+ attr = ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", NULL, uri);
+
+ /*
+ * Then send the request...
+ */
+
+ ippDelete(response);
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
+ fprintf(stderr, "lpadmin: add-class failed: %s\n",
+ ippErrorString(cupsLastError()));
+ else
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fprintf(stderr, "lpadmin: add-class failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * 'default_printer()' - Set the default printing destination.
+ */
+
+static void
+default_printer(http_t *http, /* I - Server connection */
+ char *printer) /* I - Printer name */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ cups_lang_t *language; /* Default language */
+ char uri[HTTP_MAX_URI]; /* URI for printer/class */
+
+
+ DEBUG_printf(("default_printer(%p, \"%s\")\n", http, printer));
+
+ /*
+ * Build a CUPS_SET_DEFAULT request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_SET_DEFAULT;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
+ fprintf(stderr, "lpadmin: set-default failed: %s\n",
+ ippErrorString(cupsLastError()));
+ else
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fprintf(stderr, "lpadmin: set-default failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * 'delete_printer()' - Delete a printer from the system...
+ */
+
+static void
+delete_printer(http_t *http, /* I - Server connection */
+ char *printer) /* I - Printer to delete */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ cups_lang_t *language; /* Default language */
+ char uri[HTTP_MAX_URI]; /* URI for printer/class */
+
+
+ DEBUG_printf(("delete_printer(%p, \"%s\")\n", http, printer));
+
+ /*
+ * Build a CUPS_DELETE_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_DELETE_PRINTER;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
+ fprintf(stderr, "lpadmin: delete-printer failed: %s\n",
+ ippErrorString(cupsLastError()));
+ else
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fprintf(stderr, "lpadmin: delete-printer failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * 'delete_printer_from_class()' - Delete a printer from a class.
+ */
+
+static void
+delete_printer_from_class(http_t *http, /* I - Server connection */
+ char *printer, /* I - Printer to remove */
+ char *pclass) /* I - Class to remove from */
+{
+ int i, j, k; /* Looping vars */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr, /* Current attribute */
+ *members; /* Members in class */
+ cups_lang_t *language; /* Default language */
+ char uri[HTTP_MAX_URI]; /* URI for printer/class */
+
+
+ DEBUG_printf(("delete_printer_from_class(%p, \"%s\", \"%s\")\n", http,
+ printer, pclass));
+
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", pclass);
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/classes/")) == NULL ||
+ response->request.status.status_code == IPP_NOT_FOUND)
+ {
+ ippDelete(response);
+ fprintf(stderr, "lpadmin: Class %s does not exist!\n", pclass);
+ return;
+ }
+
+ /*
+ * See if the printer is already in the class...
+ */
+
+ if ((members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) == NULL)
+ {
+ ippDelete(response);
+ fputs("lpadmin: No member names were seen!\n", stderr);
+ return;
+ }
+
+ for (i = 0; i < members->num_values; i ++)
+ if (strcasecmp(printer, members->values[i].string.text) == 0)
+ break;
+
+ if (i >= members->num_values)
+ {
+ fprintf(stderr, "lpadmin: Printer %s is not a member of class %s.\n",
+ printer, pclass);
+ ippDelete(response);
+ return;
+ }
+
+ if (members->num_values == 1)
+ {
+ /*
+ * Build a CUPS_DELETE_CLASS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_DELETE_CLASS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ }
+ else
+ {
+ /*
+ * Build a CUPS_ADD_CLASS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * member-uris
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_ADD_CLASS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Delete the printer from the class...
+ */
+
+ members = ippFindAttribute(response, "member-uris", IPP_TAG_URI);
+ attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI,
+ "member-uris", members->num_values - 1, NULL, NULL);
+
+ for (j = 0, k = 0; j < members->num_values; j ++)
+ if (j != i)
+ attr->values[k ++].string.text = strdup(members->values[j].string.text);
+ }
+
+ /*
+ * Then send the request...
+ */
+
+ ippDelete(response);
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
+ fprintf(stderr, "lpadmin: add/delete-class failed: %s\n",
+ ippErrorString(cupsLastError()));
+ else
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fprintf(stderr, "lpadmin: add/delete-class failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * 'enable_printer()' - Enable a printer...
+ */
+
+static void
+enable_printer(http_t *http, /* I - Server connection */
+ char *printer) /* I - Printer to enable */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ cups_lang_t *language; /* Default language */
+ char uri[HTTP_MAX_URI]; /* URI for printer/class */
+
+
+ DEBUG_printf(("enable_printer(%p, \"%s\")\n", http, printer));
+
+ /*
+ * Build a CUPS_ADD_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * printer-state
+ * printer-is-accepting-jobs
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_ADD_PRINTER;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
+ IPP_PRINTER_IDLE);
+
+ ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(cupsLastError()));
+ else
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * 'get_line()' - Get a line that is terminated by a LF, CR, or CR LF.
+ */
+
+static char * /* O - Pointer to buf or NULL on EOF */
+get_line(char *buf, /* I - Line buffer */
+ int length, /* I - Length of buffer */
+ FILE *fp) /* I - File to read from */
+{
+ char *bufptr; /* Pointer into buffer */
+ int ch; /* Character from file */
+
+
+ length --;
+ bufptr = buf;
+
+ while ((ch = getc(fp)) != EOF)
+ {
+ if (ch == '\n')
+ break;
+ else if (ch == '\r')
+ {
+ /*
+ * Look for LF...
+ */
+
+ ch = getc(fp);
+ if (ch != '\n' && ch != EOF)
+ ungetc(ch, fp);
+
+ break;
+ }
+
+ *bufptr++ = ch;
+ length --;
+ if (length == 0)
+ break;
+ }
+
+ *bufptr = '\0';
+
+ if (ch == EOF)
+ return (NULL);
+ else
+ return (buf);
+}
+
+
+/*
+ * 'set_printer_device()' - Set the device-uri attribute.
+ */
+
+static void
+set_printer_device(http_t *http, /* I - Server connection */
+ char *printer, /* I - Printer */
+ char *device) /* I - New device URI */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ cups_lang_t *language; /* Default language */
+ char uri[HTTP_MAX_URI]; /* URI for printer/class */
+
+
+ DEBUG_printf(("set_printer_device(%p, \"%s\", \"%s\")\n", http, printer,
+ device));
+
+ /*
+ * Build a CUPS_ADD_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_ADD_PRINTER;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Add the device URI...
+ */
+
+ if (device[0] == '/')
+ {
+ /*
+ * Convert filename to URI...
+ */
+
+ snprintf(uri, sizeof(uri), "file:%s", device);
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
+ uri);
+ }
+ else
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
+ device);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(cupsLastError()));
+ else
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * 'set_printer_file()' - Set the interface script or PPD file.
+ */
+
+static void
+set_printer_file(http_t *http, /* I - Server connection */
+ char *printer, /* I - Printer */
+ char *file) /* I - PPD file or interface script */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ cups_lang_t *language; /* Default language */
+ char uri[HTTP_MAX_URI]; /* URI for printer/class */
+#ifdef HAVE_LIBZ
+ char tempfile[1024]; /* Temporary filename */
+ int fd; /* Temporary file */
+ gzFile *gz; /* GZIP'd file */
+ char buffer[8192]; /* Copy buffer */
+ int bytes; /* Bytes in buffer */
+
+
+ DEBUG_printf(("set_printer_file(%p, \"%s\", \"%s\")\n", http, printer,
+ file));
+
+ /*
+ * See if the file is gzip'd; if so, unzip it to a temporary file and
+ * send the uncompressed file.
+ */
+
+ if (strcmp(file + strlen(file) - 3, ".gz") == 0)
+ {
+ /*
+ * Yes, the file is compressed; uncompress to a temp file...
+ */
+
+ if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
+ {
+ perror("lpadmin: Unable to create temporary file");
+ return;
+ }
+
+ if ((gz = gzopen(file, "rb")) == NULL)
+ {
+ perror("lpadmin: Unable to open file");
+ close(fd);
+ unlink(tempfile);
+ return;
+ }
+
+ while ((bytes = gzread(gz, buffer, sizeof(buffer))) > 0)
+ write(fd, buffer, bytes);
+
+ close(fd);
+ gzclose(gz);
+
+ file = tempfile;
+ }
+#endif /* HAVE_LIBZ */
+
+ /*
+ * Build a CUPS_ADD_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_ADD_PRINTER;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoFileRequest(http, request, "/admin/", file)) == NULL)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(cupsLastError()));
+ else
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+
+ ippDelete(response);
+ }
+
+#ifdef HAVE_LIBZ
+ /*
+ * Remove the temporary file as needed...
+ */
+
+ if (file == tempfile)
+ unlink(tempfile);
+#endif /* HAVE_LIBZ */
+}
+
+
+/*
+ * 'set_printer_info()' - Set the printer description string.
+ */
+
+static void
+set_printer_info(http_t *http, /* I - Server connection */
+ char *printer, /* I - Printer */
+ char *info) /* I - New description string */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ cups_lang_t *language; /* Default language */
+ char uri[HTTP_MAX_URI]; /* URI for printer/class */
+
+
+ DEBUG_printf(("set_printer_info(%p, \"%s\", \"%s\")\n", http, printer,
+ info));
+
+ /*
+ * Build a CUPS_ADD_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_ADD_PRINTER;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Add the info string...
+ */
+
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info", NULL,
+ info);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(cupsLastError()));
+ else
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * 'set_printer_location()' - Set the printer location string.
+ */
+
+static void
+set_printer_location(http_t *http, /* I - Server connection */
+ char *printer, /* I - Printer */
+ char *location) /* I - New location string */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ cups_lang_t *language; /* Default language */
+ char uri[HTTP_MAX_URI]; /* URI for printer/class */
+
+
+ DEBUG_printf(("set_printer_location(%p, \"%s\", \"%s\")\n", http, printer,
+ location));
+
+ /*
+ * Build a CUPS_ADD_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_ADD_PRINTER;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Add the location string...
+ */
+
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location", NULL,
+ location);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(cupsLastError()));
+ else
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * 'set_printer_model()' - Set the driver model file.
+ */
+
+static void
+set_printer_model(http_t *http, /* I - Server connection */
+ char *printer, /* I - Printer */
+ char *model) /* I - Driver model file */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ cups_lang_t *language; /* Default language */
+ char uri[HTTP_MAX_URI]; /* URI for printer/class */
+
+
+ /*
+ * Build a CUPS_ADD_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * ppd-name
+ */
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_ADD_PRINTER;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "ppd-name", NULL, model);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(cupsLastError()));
+ else
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fprintf(stderr, "lpadmin: add-printer failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * 'set_printer_options()' - Set the printer options.
+ */
+
+static void
+set_printer_options(http_t *http, /* I - Server connection */
+ char *printer, /* I - Printer */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* IPP attribute */
+ cups_lang_t *language; /* Default language */
+ ipp_op_t op; /* Operation to perform */
+ const char *val, /* Option value */
+ *ppdfile; /* PPD filename */
+ char uri[HTTP_MAX_URI], /* URI for printer/class */
+ line[1024], /* Line from PPD file */
+ keyword[1024], /* Keyword from Default line */
+ *keyptr, /* Pointer into keyword... */
+ tempfile[1024]; /* Temporary filename */
+ FILE *in, /* PPD file */
+ *out; /* Temporary file */
+ int outfd; /* Temporary file descriptor */
+
+
+ DEBUG_printf(("set_printer_options(%p, \"%s\", %d, %p)\n", http, printer,
+ num_options, options));
+
+ language = cupsLangDefault();
+
+ snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
+
+ /*
+ * Build a GET_PRINTER_ATTRIBUTES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", NULL, "printer-type");
+
+ /*
+ * Do the request...
+ */
+
+ op = CUPS_ADD_PRINTER;
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ /*
+ * See what kind of printer or class it is...
+ */
+
+ if ((attr = ippFindAttribute(response, "printer-type", IPP_TAG_ENUM)) != NULL)
+ {
+ if (attr->values[0].integer & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+ {
+ op = CUPS_ADD_CLASS;
+ snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", printer);
+ }
+ }
+
+ ippDelete(response);
+ }
+
+ /*
+ * Build a CUPS_ADD_PRINTER or CUPS_ADD_CLASS request, which requires
+ * the following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * other options
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = op;
+ request->request.op.request_id = 1;
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Add the options...
+ */
+
+ cupsEncodeOptions(request, num_options, options);
+
+ if (op == CUPS_ADD_PRINTER)
+ ppdfile = cupsGetPPD(printer);
+ else
+ ppdfile = NULL;
+
+ if (ppdfile != NULL)
+ {
+ /*
+ * Set default options in the PPD file...
+ */
+
+ outfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+ in = fopen(ppdfile, "rb");
+ out = fdopen(outfd, "wb");
+
+ while (get_line(line, sizeof(line), in) != NULL)
+ {
+ if (strncmp(line, "*Default", 8) != 0)
+ fprintf(out, "%s\n", line);
+ else
+ {
+ /*
+ * Get default option name...
+ */
+
+ strlcpy(keyword, line + 8, sizeof(keyword));
+
+ for (keyptr = keyword; *keyptr; keyptr ++)
+ if (*keyptr == ':' || isspace(*keyptr))
+ break;
+
+ *keyptr = '\0';
+
+ if (strcmp(keyword, "PageRegion") == 0)
+ val = cupsGetOption("PageSize", num_options, options);
+ else
+ val = cupsGetOption(keyword, num_options, options);
+
+ if (val != NULL)
+ fprintf(out, "*Default%s: %s\n", keyword, val);
+ else
+ fprintf(out, "%s\n", line);
+ }
+ }
+
+ fclose(in);
+ fclose(out);
+ close(outfd);
+
+ /*
+ * Do the request...
+ */
+
+ response = cupsDoFileRequest(http, request, "/admin/", tempfile);
+
+ /*
+ * Clean up temp files... (TODO: catch signals in case we CTRL-C during
+ * lpadmin)
+ */
+
+ unlink(ppdfile);
+ unlink(tempfile);
+ }
+ else
+ {
+ /*
+ * No PPD file - just set the options...
+ */
+
+ response = cupsDoRequest(http, request, "/admin/");
+ }
+
+ /*
+ * Check the response...
+ */
+
+ if (response == NULL)
+ fprintf(stderr, "lpadmin: %s failed: %s\n",
+ op == CUPS_ADD_PRINTER ? "add-printer" : "add-class",
+ ippErrorString(cupsLastError()));
+ else
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ fprintf(stderr, "lpadmin: %s failed: %s\n",
+ op == CUPS_ADD_PRINTER ? "add-printer" : "add-class",
+ ippErrorString(response->request.status.status_code));
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * 'validate_name()' - Make sure the printer name only contains valid chars.
+ */
+
+static int /* O - 0 if name is no good, 1 if name is good */
+validate_name(const char *name) /* I - Name to check */
+{
+ const char *ptr; /* Pointer into name */
+
+
+ /*
+ * Scan the whole name...
+ */
+
+ for (ptr = name; *ptr; ptr ++)
+ if (*ptr == '@')
+ break;
+ else if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/')
+ return (0);
+
+ /*
+ * All the characters are good; validate the length, too...
+ */
+
+ return ((ptr - name) < 128);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/systemv/lpinfo.c b/systemv/lpinfo.c
new file mode 100644
index 000000000..6fdac11b5
--- /dev/null
+++ b/systemv/lpinfo.c
@@ -0,0 +1,454 @@
+/*
+ * "$Id$"
+ *
+ * "lpinfo" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and show information.
+ * show_devices() - Show available devices.
+ * show_models() - Show available PPDs.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <cups/debug.h>
+#include <cups/string.h>
+
+
+/*
+ * Local functions...
+ */
+
+static int show_devices(http_t *, int);
+static int show_models(http_t *, int);
+
+
+/*
+ * 'main()' - Parse options and show status information.
+ */
+
+int
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ http_t *http; /* Connection to server */
+ int long_status; /* Long listing? */
+
+
+ http = NULL;
+ long_status = 0;
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ switch (argv[i][1])
+ {
+ case 'E' : /* Encrypt */
+#ifdef HAVE_LIBSSL
+ cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+
+ if (http)
+ httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+#else
+ fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
+ argv[0]);
+#endif /* HAVE_LIBSSL */
+ break;
+
+ case 'l' : /* Show long listing */
+ long_status = 1;
+ break;
+
+ case 'm' : /* Show models */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpinfo: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (show_models(http, long_status))
+ return (1);
+ break;
+
+ case 'v' : /* Show available devices */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpinfo: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (show_devices(http, long_status))
+ return (1);
+ break;
+
+ case 'h' : /* Connect to host */
+ if (http)
+ {
+ httpClose(http);
+ http = NULL;
+ }
+
+ if (argv[i][2] != '\0')
+ cupsSetServer(argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("Error: need hostname after \'-h\' option!\n", stderr);
+ return (1);
+ }
+
+ cupsSetServer(argv[i]);
+ }
+ break;
+
+ default :
+ fprintf(stderr, "lpinfo: Unknown option \'%c\'!\n", argv[i][1]);
+ return (1);
+ }
+ else
+ {
+ fprintf(stderr, "lpinfo: Unknown argument \'%s\'!\n", argv[i]);
+ return (1);
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'show_devices()' - Show available devices.
+ */
+
+static int /* O - 0 on success, 1 on failure */
+show_devices(http_t *http, /* I - HTTP connection to server */
+ int long_status)/* I - Long status report? */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ const char *device_class, /* Pointer into device-class */
+ *device_info, /* Pointer into device-info */
+ *device_make, /* Pointer into device-make-and-model */
+ *device_uri; /* Pointer into device-uri */
+
+
+ if (http == NULL)
+ return (1);
+
+ /*
+ * Build a CUPS_GET_DEVICES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_DEVICES;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://localhost/printers/");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ /*
+ * Loop through the device list and display them...
+ */
+
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "lpinfo: cups-get-devices failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return (1);
+ }
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a device...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this device...
+ */
+
+ device_class = NULL;
+ device_info = NULL;
+ device_make = NULL;
+ device_uri = NULL;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
+ {
+ if (strcmp(attr->name, "device-class") == 0 &&
+ attr->value_tag == IPP_TAG_KEYWORD)
+ device_class = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "device-info") == 0 &&
+ attr->value_tag == IPP_TAG_TEXT)
+ device_info = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "device-make-and-model") == 0 &&
+ attr->value_tag == IPP_TAG_TEXT)
+ device_make = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "device-uri") == 0 &&
+ attr->value_tag == IPP_TAG_URI)
+ device_uri = attr->values[0].string.text;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (device_class == NULL || device_info == NULL ||
+ device_make == NULL || device_uri == NULL)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ /*
+ * Display the device...
+ */
+
+ if (long_status)
+ {
+ printf("Device: uri = %s\n", device_uri);
+ printf(" class = %s\n", device_class);
+ printf(" info = %s\n", device_info);
+ printf(" make-and-model = %s\n", device_make);
+ }
+ else
+ printf("%s %s\n", device_class, device_uri);
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ fprintf(stderr, "lpinfo: cups-get-devices failed: %s\n",
+ ippErrorString(cupsLastError()));
+ return (1);
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'show_models()' - Show available PPDs.
+ */
+
+static int /* O - 0 on success, 1 on failure */
+show_models(http_t *http, /* I - HTTP connection to server */
+ int long_status) /* I - Long status report? */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ const char *ppd_language, /* Pointer into ppd-natural-language */
+ *ppd_make, /* Pointer into ppd-make-and-model */
+ *ppd_name; /* Pointer into ppd-name */
+
+
+ if (http == NULL)
+ return (1);
+
+ /*
+ * Build a CUPS_GET_PPDS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_PPDS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://localhost/printers/");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ /*
+ * Loop through the device list and display them...
+ */
+
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "lpinfo: cups-get-ppds failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return (1);
+ }
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a PPD...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this PPD...
+ */
+
+ ppd_language = NULL;
+ ppd_make = NULL;
+ ppd_name = NULL;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
+ {
+ if (strcmp(attr->name, "ppd-natural-language") == 0 &&
+ attr->value_tag == IPP_TAG_LANGUAGE)
+ ppd_language = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "ppd-make-and-model") == 0 &&
+ attr->value_tag == IPP_TAG_TEXT)
+ ppd_make = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "ppd-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ ppd_name = attr->values[0].string.text;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (ppd_language == NULL || ppd_make == NULL || ppd_name == NULL)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ /*
+ * Display the device...
+ */
+
+ if (long_status)
+ {
+ printf("Model: name = %s\n", ppd_name);
+ printf(" natural_language = %s\n", ppd_language);
+ printf(" make-and-model = %s\n", ppd_make);
+ }
+ else
+ printf("%s %s\n", ppd_name, ppd_make);
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ fprintf(stderr, "lpinfo: cups-get-ppds failed: %s\n",
+ ippErrorString(cupsLastError()));
+
+ return (1);
+ }
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/systemv/lpmove.c b/systemv/lpmove.c
new file mode 100644
index 000000000..1fc165116
--- /dev/null
+++ b/systemv/lpmove.c
@@ -0,0 +1,235 @@
+/*
+ * "$Id$"
+ *
+ * "lpmove" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and move jobs.
+ * move_job() - Move a job.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <cups/debug.h>
+#include <cups/string.h>
+
+
+/*
+ * Local functions...
+ */
+
+static void move_job(http_t *, int, const char *);
+
+
+/*
+ * 'main()' - Parse options and show status information.
+ */
+
+int
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ http_t *http; /* Connection to server */
+ const char *job; /* Job name */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dests; /* Destinations */
+ const char *dest; /* New destination */
+
+
+ http = NULL;
+ job = NULL;
+ dest = NULL;
+ num_dests = 0;
+ dests = NULL;
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ switch (argv[i][1])
+ {
+ case 'E' : /* Encrypt */
+#ifdef HAVE_LIBSSL
+ cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+
+ if (http)
+ httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+#else
+ fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
+ argv[0]);
+#endif /* HAVE_LIBSSL */
+ break;
+
+ case 'h' : /* Connect to host */
+ if (http)
+ {
+ httpClose(http);
+ http = NULL;
+ }
+
+ if (argv[i][2] != '\0')
+ cupsSetServer(argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("Error: need hostname after \'-h\' option!\n", stderr);
+ return (1);
+ }
+
+ cupsSetServer(argv[i]);
+ }
+ break;
+
+ default :
+ fprintf(stderr, "lpmove: Unknown option \'%c\'!\n", argv[i][1]);
+ return (1);
+ }
+ else if (job == NULL)
+ {
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if ((job = strrchr(argv[i], '-')) != NULL &&
+ cupsGetDest(argv[i], NULL, num_dests, dests) == NULL)
+ job ++;
+ else
+ job = argv[i];
+ }
+ else if (dest == NULL)
+ dest = argv[i];
+ else
+ {
+ fprintf(stderr, "lpmove: Unknown argument \'%s\'!\n", argv[i]);
+ return (1);
+ }
+
+ if (job == NULL || dest == NULL)
+ {
+ puts("Usage: lpmove job dest");
+ return (1);
+ }
+
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpmove: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ move_job(http, atoi(job), dest);
+
+ return (0);
+}
+
+
+/*
+ * 'move_job()' - Move a job.
+ */
+
+static void
+move_job(http_t *http, /* I - HTTP connection to server */
+ int jobid, /* I - Job ID */
+ const char *dest) /* I - Destination */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ cups_lang_t *language; /* Default language */
+ char job_uri[HTTP_MAX_URI],
+ /* job-uri */
+ printer_uri[HTTP_MAX_URI];
+ /* job-printer-uri */
+
+
+ if (http == NULL)
+ return;
+
+ /*
+ * Build a CUPS_MOVE_JOB request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * job-uri
+ * job-printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_MOVE_JOB;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", jobid);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, job_uri);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, cupsUser());
+
+ snprintf(printer_uri, sizeof(printer_uri), "ipp://localhost/printers/%s", dest);
+ ippAddString(request, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri",
+ NULL, printer_uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "lpmove: move-job failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return;
+ }
+
+ ippDelete(response);
+ }
+ else
+ fprintf(stderr, "lpmove: move-job failed: %s\n",
+ ippErrorString(cupsLastError()));
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/systemv/lpoptions.c b/systemv/lpoptions.c
new file mode 100644
index 000000000..768eefd9c
--- /dev/null
+++ b/systemv/lpoptions.c
@@ -0,0 +1,451 @@
+/*
+ * "$Id$"
+ *
+ * Printer option program for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Main entry.
+ * list_group() - List printer-specific options from the PPD group.
+ * list_options() - List printer-specific options from the PPD file.
+ * usage() - Show program usage and exit.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <cups/cups.h>
+#include <cups/string.h>
+#include <stdlib.h>
+
+
+/*
+ * Local functions...
+ */
+
+void list_group(ppd_group_t *group);
+void list_options(cups_dest_t *dest);
+void usage(void);
+
+
+/*
+ * 'main()' - Main entry.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i, j; /* Looping vars */
+ int changes; /* Did we make changes? */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dests; /* Destinations */
+ cups_dest_t *dest; /* Current destination */
+ char *printer, /* Printer name */
+ *instance, /* Instance name */
+ *option; /* Current option */
+
+
+ /*
+ * Loop through the command-line arguments...
+ */
+
+ dest = NULL;
+ num_dests = 0;
+ dests = NULL;
+ num_options = 0;
+ options = NULL;
+ changes = 0;
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'd' : /* -d printer */
+ if (argv[i][2])
+ printer = argv[i] + 2;
+ else
+ {
+ i ++;
+ if (i >= argc)
+ usage();
+
+ printer = argv[i];
+ }
+
+ if ((instance = strrchr(printer, '/')) != NULL)
+ *instance++ = '\0';
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
+ {
+ fputs("lpoptions: Unknown printer or class!\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Set the default destination...
+ */
+
+ for (j = 0; j < num_dests; j ++)
+ dests[j].is_default = 0;
+
+ dest->is_default = 1;
+
+ cupsSetDests(num_dests, dests);
+
+ for (j = 0; j < dest->num_options; j ++)
+ if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
+ num_options = cupsAddOption(dest->options[j].name,
+ dest->options[j].value,
+ num_options, &options);
+ break;
+
+ case 'h' : /* -h server */
+ if (argv[i][2])
+ cupsSetServer(argv[i] + 2);
+ else
+ {
+ i ++;
+ if (i >= argc)
+ usage();
+
+ cupsSetServer(argv[i]);
+ }
+ break;
+
+ case 'l' : /* -l (list options) */
+ if (dest == NULL)
+ {
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ for (i = num_dests, dest = dests; i > 0; i --, dest ++)
+ if (dest->is_default)
+ break;
+
+ if (i == 0)
+ dest = dests;
+ }
+
+ if (dest == NULL)
+ fputs("lpoptions: No printers!?!\n", stderr);
+ else
+ list_options(dest);
+
+ changes = -1;
+ break;
+
+ case 'o' : /* -o option[=value] */
+ if (argv[i][2])
+ num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
+ else
+ {
+ i ++;
+ if (i >= argc)
+ usage();
+
+ num_options = cupsParseOptions(argv[i], num_options, &options);
+ }
+
+ changes = 1;
+ break;
+
+ case 'p' : /* -p printer */
+ if (argv[i][2])
+ printer = argv[i] + 2;
+ else
+ {
+ i ++;
+ if (i >= argc)
+ usage();
+
+ printer = argv[i];
+ }
+
+ if ((instance = strrchr(printer, '/')) != NULL)
+ *instance++ = '\0';
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
+ {
+ num_dests = cupsAddDest(printer, instance, num_dests, &dests);
+ dest = cupsGetDest(printer, instance, num_dests, dests);
+
+ if (dest == NULL)
+ {
+ perror("lpoptions: Unable to add printer or instance");
+ return (1);
+ }
+ }
+
+ for (j = 0; j < dest->num_options; j ++)
+ if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
+ num_options = cupsAddOption(dest->options[j].name,
+ dest->options[j].value,
+ num_options, &options);
+ break;
+
+ case 'r' : /* -r option (remove) */
+ if (argv[i][2])
+ option = argv[i] + 2;
+ else
+ {
+ i ++;
+ if (i >= argc)
+ usage();
+
+ option = argv[i];
+ }
+
+ for (j = 0; j < num_options; j ++)
+ if (strcasecmp(options[j].name, option) == 0)
+ {
+ /*
+ * Remove this option...
+ */
+
+ num_options --;
+
+ if (j < num_options)
+ memcpy(options + j, options + j + 1,
+ sizeof(cups_option_t) * (num_options - j));
+ break;
+ }
+
+ changes = 1;
+ break;
+
+ case 'x' : /* -x printer */
+ if (argv[i][2])
+ printer = argv[i] + 2;
+ else
+ {
+ i ++;
+ if (i >= argc)
+ usage();
+
+ printer = argv[i];
+ }
+
+ if ((instance = strrchr(printer, '/')) != NULL)
+ *instance++ = '\0';
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
+ {
+ if (instance)
+ fprintf(stderr, "lpoptions: No such printer/instance: %s/%s\n",
+ printer, instance);
+ else
+ fprintf(stderr, "lpoptions: No such printer: %s\n", printer);
+
+ return (1);
+ }
+
+ cupsFreeOptions(dest->num_options, dest->options);
+
+ /*
+ * If we are "deleting" the default printer, then just set the
+ * number of options to 0; if it is also the system default
+ * then cupsSetDests() will remove it for us...
+ */
+
+ if (dest->is_default)
+ {
+ dest->num_options = 0;
+ dest->options = NULL;
+ }
+ else
+ {
+ num_dests --;
+
+ j = dest - dests;
+ if (j < num_dests)
+ memcpy(dest, dest + 1, (num_dests - j) * sizeof(cups_dest_t));
+ }
+
+ cupsSetDests(num_dests, dests);
+ dest = NULL;
+ break;
+
+ default :
+ usage();
+ }
+ }
+ else
+ usage();
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if (dest == NULL)
+ for (i = 0; i < num_dests; i ++)
+ if (dests[i].is_default)
+ {
+ dest = dests + i;
+
+ for (j = 0; j < dest->num_options; j ++)
+ if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
+ num_options = cupsAddOption(dest->options[j].name,
+ dest->options[j].value,
+ num_options, &options);
+ break;
+ }
+
+ if (dest == NULL)
+ return (0);
+
+ if (changes > 0)
+ {
+ /*
+ * Set printer options...
+ */
+
+ cupsFreeOptions(dest->num_options, dest->options);
+
+ dest->num_options = num_options;
+ dest->options = options;
+
+ cupsSetDests(num_dests, dests);
+ }
+ else if (changes == 0)
+ {
+ num_options = dest->num_options;
+ options = dest->options;
+
+ for (i = 0; i < num_options; i ++)
+ {
+ if (i)
+ putchar(' ');
+
+ if (!options[i].value[0])
+ printf("%s", options[i].name);
+ else if (strchr(options[i].value, ' ') != NULL ||
+ strchr(options[i].value, '\t') != NULL)
+ printf("%s=\'%s\'", options[i].name, options[i].value);
+ else
+ printf("%s=%s", options[i].name, options[i].value);
+ }
+
+ putchar('\n');
+ }
+
+ return (0);
+}
+
+/*
+ * 'list_group()' - List printer-specific options from the PPD group.
+ */
+
+void
+list_group(ppd_group_t *group) /* I - Group to show */
+{
+ int i, j; /* Looping vars */
+ ppd_option_t *option; /* Current option */
+ ppd_choice_t *choice; /* Current choice */
+ ppd_group_t *subgroup; /* Current subgroup */
+
+
+ for (i = group->num_options, option = group->options; i > 0; i --, option ++)
+ {
+ printf("%s/%s:", option->keyword, option->text);
+
+ for (j = option->num_choices, choice = option->choices; j > 0; j --, choice ++)
+ if (choice->marked)
+ printf(" *%s", choice->choice);
+ else
+ printf(" %s", choice->choice);
+
+ putchar('\n');
+ }
+
+ for (i = group->num_subgroups, subgroup = group->subgroups; i > 0; i --, subgroup ++)
+ list_group(subgroup);
+}
+
+
+/*
+ * 'list_options()' - List printer-specific options from the PPD file.
+ */
+
+void
+list_options(cups_dest_t *dest) /* I - Destination to list */
+{
+ int i; /* Looping var */
+ const char *filename; /* PPD filename */
+ ppd_file_t *ppd; /* PPD data */
+ ppd_group_t *group; /* Current group */
+
+
+ if ((filename = cupsGetPPD(dest->name)) == NULL)
+ {
+ fprintf(stderr, "lpoptions: Destination %s has no PPD file!\n", dest->name);
+ return;
+ }
+
+ if ((ppd = ppdOpenFile(filename)) == NULL)
+ {
+ unlink(filename);
+ fprintf(stderr, "lpoptions: Unable to open PPD file for %s!\n", dest->name);
+ return;
+ }
+
+ ppdMarkDefaults(ppd);
+ cupsMarkOptions(ppd, dest->num_options, dest->options);
+
+ for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
+ list_group(group);
+
+ ppdClose(ppd);
+ unlink(filename);
+}
+
+
+/*
+ * 'usage()' - Show program usage and exit.
+ */
+
+void
+usage(void)
+{
+ puts("Usage: lpoptions -d printer");
+ puts(" lpoptions [-p printer] -l");
+ puts(" lpoptions -p printer -o option[=value] ...");
+ puts(" lpoptions -x printer");
+
+ exit(1);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/systemv/lppasswd.c b/systemv/lppasswd.c
new file mode 100644
index 000000000..3361f1cc9
--- /dev/null
+++ b/systemv/lppasswd.c
@@ -0,0 +1,405 @@
+/*
+ * "$Id$"
+ *
+ * MD5 password program for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Add, change, or delete passwords from the MD5 password file.
+ * usage() - Show program usage.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <cups/cups.h>
+#include <cups/md5.h>
+#include <cups/string.h>
+
+
+/*
+ * Operations...
+ */
+
+#define ADD 0
+#define CHANGE 1
+#define DELETE 2
+
+
+/*
+ * Local functions...
+ */
+
+static void usage(FILE *fp);
+
+
+/*
+ * 'main()' - Add, change, or delete passwords from the MD5 password file.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ char *opt; /* Option pointer */
+ const char *username; /* Pointer to username */
+ const char *groupname; /* Pointer to group name */
+ int op; /* Operation (add, change, delete) */
+ const char *passwd; /* Password string */
+ FILE *infile, /* Input file */
+ *outfile; /* Output file */
+ char line[256], /* Line from file */
+ userline[17], /* User from line */
+ groupline[17], /* Group from line */
+ md5line[33], /* MD5-sum from line */
+ md5new[33]; /* New MD5 sum */
+ const char *root; /* CUPS server root directory */
+ char passwdmd5[1024],/* passwd.md5 file */
+ passwdold[1024],/* passwd.old file */
+ passwdnew[1024];/* passwd.tmp file */
+ char *newpass, /* new password */
+ *oldpass; /* old password */
+ int flag; /* Password check flags... */
+ int fd; /* Password file descriptor */
+
+
+ /*
+ * Find the server directory...
+ *
+ * Don't use CUPS_SERVERROOT unless we're run by the
+ * super user.
+ */
+
+ if (!getuid() && (root = getenv("CUPS_SERVERROOT")) != NULL)
+ {
+ snprintf(passwdmd5, sizeof(passwdmd5), "%s/passwd.md5", root);
+ snprintf(passwdold, sizeof(passwdold), "%s/passwd.old", root);
+ snprintf(passwdnew, sizeof(passwdnew), "%s/passwd.new", root);
+ }
+ else
+ {
+ strcpy(passwdmd5, CUPS_SERVERROOT "/passwd.md5");
+ strcpy(passwdold, CUPS_SERVERROOT "/passwd.old");
+ strcpy(passwdnew, CUPS_SERVERROOT "/passwd.new");
+ }
+
+ /*
+ * Find the default system group: "sys", "system", or "root"...
+ */
+
+ if (getgrnam("sys"))
+ groupname = "sys";
+ else if (getgrnam("system"))
+ groupname = "system";
+ else if (getgrnam("root"))
+ groupname = "root";
+ else
+ groupname = "unknown";
+
+ endgrent();
+
+ username = NULL;
+ op = CHANGE;
+
+ /*
+ * Parse command-line options...
+ */
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ for (opt = argv[i] + 1; *opt; opt ++)
+ switch (*opt)
+ {
+ case 'a' : /* Add */
+ op = ADD;
+ break;
+ case 'x' : /* Delete */
+ op = DELETE;
+ break;
+ case 'g' : /* Group */
+ i ++;
+ if (i >= argc)
+ usage(stderr);
+
+ groupname = argv[i];
+ break;
+ case 'h' : /* Help */
+ usage(stdout);
+ break;
+ default : /* Bad option */
+ usage(stderr);
+ break;
+ }
+ else if (!username)
+ username = argv[i];
+ else
+ usage(stderr);
+
+ /*
+ * See if we are trying to add or delete a password when we aren't logged in
+ * as root...
+ */
+
+ if (getuid() && (op != CHANGE || username))
+ {
+ fputs("lppasswd: Only root can add or delete passwords!\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Fill in missing info...
+ */
+
+ if (!username)
+ username = cupsUser();
+
+ oldpass = newpass = NULL;
+
+ /*
+ * Obtain old and new password _before_ locking the database
+ * to keep users from locking the file indefinitely.
+ */
+
+ if (op == CHANGE && getuid())
+ {
+ if ((passwd = cupsGetPassword("Enter old password:")) == NULL)
+ return (1);
+
+ if ((oldpass = strdup(passwd)) == NULL)
+ {
+ perror("lppasswd: Unable to copy password string");
+ return (1);
+ }
+ }
+
+ /*
+ * Now get the new password, if necessary...
+ */
+
+ if (op != DELETE)
+ {
+ if ((passwd = cupsGetPassword("Enter password:")) == NULL)
+ return (1);
+
+ if ((newpass = strdup(passwd)) == NULL)
+ {
+ perror("lppasswd: Unable to copy password string!");
+ return (1);
+ }
+
+ if ((passwd = cupsGetPassword("Enter password again:")) == NULL)
+ return (1);
+
+ if (strcmp(passwd, newpass) != 0)
+ {
+ fputs("lppasswd: Sorry, passwords don't match!\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Check that the password contains at least one letter and number.
+ */
+
+ flag = 0;
+
+ for (passwd = newpass; *passwd; passwd ++)
+ if (isdigit(*passwd))
+ flag |= 1;
+ else if (isalpha(*passwd))
+ flag |= 2;
+
+ /*
+ * Only allow passwords that are at least 6 chars, have a letter and
+ * a number, and don't contain the username.
+ */
+
+ if (strlen(newpass) < 6 || strstr(newpass, username) != NULL || flag != 3)
+ {
+ fputs("lppasswd: Sorry, password rejected.\n"
+ "Your password must be at least 6 characters long, cannot contain\n"
+ "your username, and must contain at least one letter and number.\n",
+ stderr);
+ return (1);
+ }
+ }
+
+ /*
+ * Open the output file.
+ */
+
+ if ((fd = open(passwdnew, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0)
+ {
+ if (errno == EEXIST)
+ fputs("lppasswd: Password file busy!\n", stderr);
+ else
+ perror("lppasswd: Unable to open passwd file");
+
+ return (1);
+ }
+
+ if ((outfile = fdopen(fd, "w")) == NULL)
+ {
+ perror("lppasswd: Unable to open passwd file");
+
+ unlink(passwdnew);
+
+ return (1);
+ }
+
+ /*
+ * Open the existing password file and create a new one...
+ */
+
+ infile = fopen(passwdmd5, "r");
+ if (infile == NULL && errno != ENOENT && op != ADD)
+ {
+ fputs("lppasswd: No password file to change or delete from!\n", stderr);
+
+ fclose(outfile);
+
+ unlink(passwdnew);
+
+ return (1);
+ }
+
+ /*
+ * Read lines from the password file; the format is:
+ *
+ * username:group:MD5-sum
+ */
+
+ if (infile)
+ {
+ while (fgets(line, sizeof(line), infile) != NULL)
+ {
+ if (sscanf(line, "%16[^:]:%16[^:]:%32s", userline, groupline, md5line) != 3)
+ continue;
+
+ if (strcmp(username, userline) == 0 &&
+ strcmp(groupname, groupline) == 0)
+ break;
+
+ fputs(line, outfile);
+ }
+
+ while (fgets(line, sizeof(line), infile) != NULL)
+ fputs(line, outfile);
+ }
+ else
+ {
+ userline[0] = '\0';
+ groupline[0] = '\0';
+ md5line[0] = '\0';
+ }
+
+ if (op == CHANGE &&
+ (strcmp(username, userline) != 0 ||
+ strcmp(groupname, groupline) != 0))
+ fprintf(stderr, "lppasswd: user \"%s\" and group \"%s\" do not exist.\n",
+ username, groupname);
+ else if (op != DELETE)
+ {
+ if (oldpass &&
+ strcmp(httpMD5(username, "CUPS", oldpass, md5new), md5line) != 0)
+ {
+ fputs("lppasswd: Sorry, password doesn't match!\n", stderr);
+
+ if (infile)
+ fclose(infile);
+
+ fclose(outfile);
+
+ unlink(passwdnew);
+
+ return (1);
+ }
+
+ fprintf(outfile, "%s:%s:%s\n", username, groupname,
+ httpMD5(username, "CUPS", newpass, md5new));
+ }
+
+ /*
+ * Close the files and remove the old password file...
+ */
+
+ if (infile)
+ fclose(infile);
+
+ fclose(outfile);
+
+ /*
+ * Save old passwd file
+ */
+
+ unlink(passwdold);
+ link(passwdmd5, passwdold);
+
+ /*
+ * Install new password file
+ */
+
+ if (rename(passwdnew, passwdmd5) < 0)
+ {
+ perror("lppasswd: failed to rename passwd file");
+ unlink(passwdnew);
+ return (1);
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'usage()' - Show program usage.
+ */
+
+static void
+usage(FILE *fp) /* I - File to send usage to */
+{
+ if (getuid())
+ {
+ fputs("Usage: lppasswd [-g groupname]\n", fp);
+ }
+ else
+ {
+ fputs("Usage: lppasswd [-g groupname] [username]\n", fp);
+ fputs(" lppasswd [-g groupname] -a [username]\n", fp);
+ fputs(" lppasswd [-g groupname] -x [username]\n", fp);
+ }
+
+ exit(1);
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/systemv/lpstat.c b/systemv/lpstat.c
new file mode 100644
index 000000000..12475d353
--- /dev/null
+++ b/systemv/lpstat.c
@@ -0,0 +1,1937 @@
+/*
+ * "$Id$"
+ *
+ * "lpstat" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and show status information.
+ * show_accepting() - Show acceptance status.
+ * show_classes() - Show printer classes.
+ * show_default() - Show default destination.
+ * show_devices() - Show printer devices.
+ * show_jobs() - Show active print jobs.
+ * show_printers() - Show printers.
+ * show_scheduler() - Show scheduler status.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <cups/debug.h>
+#include <cups/string.h>
+
+
+/*
+ * Local functions...
+ */
+
+static void show_accepting(http_t *, const char *, int, cups_dest_t *);
+static void show_classes(http_t *, const char *);
+static void show_default(int, cups_dest_t *);
+static void show_devices(http_t *, const char *, int, cups_dest_t *);
+static void show_jobs(http_t *, const char *, const char *, int, int);
+static void show_printers(http_t *, const char *, int, cups_dest_t *, int);
+static void show_scheduler(http_t *);
+
+
+/*
+ * 'main()' - Parse options and show status information.
+ */
+
+int
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ http_t *http; /* Connection to server */
+ int num_dests; /* Number of user destinations */
+ cups_dest_t *dests; /* User destinations */
+ int long_status; /* Long status report? */
+ int ranking; /* Show job ranking? */
+
+
+ http = NULL;
+ num_dests = 0;
+ dests = NULL;
+ long_status = 0;
+ ranking = 0;
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ switch (argv[i][1])
+ {
+ case 'D' : /* Show description */
+ long_status = 1;
+ break;
+
+ case 'E' : /* Encrypt */
+#ifdef HAVE_LIBSSL
+ cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+
+ if (http)
+ httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+#else
+ fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
+ argv[0]);
+#endif /* HAVE_LIBSSL */
+ break;
+
+ case 'P' : /* Show paper types */
+ break;
+
+ case 'R' : /* Show ranking */
+ ranking = 1;
+ break;
+
+ case 'S' : /* Show charsets */
+ if (!argv[i][2])
+ i ++;
+ break;
+
+ case 'a' : /* Show acceptance status */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if (argv[i][2] != '\0')
+ show_accepting(http, argv[i] + 2, num_dests, dests);
+ else if ((i + 1) < argc && argv[i + 1][0] != '-')
+ {
+ i ++;
+ show_accepting(http, argv[i], num_dests, dests);
+ }
+ else
+ show_accepting(http, NULL, num_dests, dests);
+ break;
+
+#ifdef __sgi
+ case 'b' : /* Show both the local and remote status */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (argv[i][2] != '\0')
+ {
+ /*
+ * The local and remote status are separated by a blank line;
+ * since all CUPS jobs are networked, we only output the
+ * second list for now... In the future, we might further
+ * emulate this by listing the remote server's queue, but
+ * for now this is enough to make the SGI printstatus program
+ * happy...
+ */
+
+ puts("");
+ show_jobs(http, argv[i] + 2, NULL, 3, ranking);
+ }
+ else
+ {
+ fputs("lpstat: The -b option requires a destination argument.\n",
+ stderr);
+
+ return (1);
+ }
+ break;
+#endif /* __sgi */
+
+ case 'c' : /* Show classes and members */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (argv[i][2] != '\0')
+ show_classes(http, argv[i] + 2);
+ else if ((i + 1) < argc && argv[i + 1][0] != '-')
+ {
+ i ++;
+ show_classes(http, argv[i]);
+ }
+ else
+ show_classes(http, NULL);
+ break;
+
+ case 'd' : /* Show default destination */
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ show_default(num_dests, dests);
+ break;
+
+ case 'f' : /* Show forms */
+ if (!argv[i][2])
+ i ++;
+ break;
+
+ case 'h' : /* Connect to host */
+ if (http)
+ {
+ httpClose(http);
+ http = NULL;
+ }
+
+ if (argv[i][2] != '\0')
+ cupsSetServer(argv[i] + 2);
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ fputs("Error: need hostname after \'-h\' option!\n", stderr);
+ return (1);
+ }
+
+ cupsSetServer(argv[i]);
+ }
+ break;
+
+ case 'l' : /* Long status or long job status */
+#ifdef __sgi
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (argv[i][2] != '\0')
+ show_jobs(http, argv[i] + 2, NULL, 3, ranking);
+ else
+#endif /* __sgi */
+ long_status = 2;
+ break;
+
+ case 'o' : /* Show jobs by destination */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (argv[i][2] != '\0')
+ show_jobs(http, argv[i] + 2, NULL, long_status, ranking);
+ else if ((i + 1) < argc && argv[i + 1][0] != '-')
+ {
+ i ++;
+ show_jobs(http, argv[i], NULL, long_status, ranking);
+ }
+ else
+ show_jobs(http, NULL, NULL, long_status, ranking);
+ break;
+
+ case 'p' : /* Show printers */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if (argv[i][2] != '\0')
+ show_printers(http, argv[i] + 2, num_dests, dests, long_status);
+ else if ((i + 1) < argc && argv[i + 1][0] != '-')
+ {
+ i ++;
+ show_printers(http, argv[i], num_dests, dests, long_status);
+ }
+ else
+ show_printers(http, NULL, num_dests, dests, long_status);
+ break;
+
+ case 'r' : /* Show scheduler status */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ show_scheduler(http);
+ break;
+
+ case 's' : /* Show summary */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ show_default(num_dests, dests);
+ show_classes(http, NULL);
+ show_devices(http, NULL, num_dests, dests);
+ break;
+
+ case 't' : /* Show all info */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ show_scheduler(http);
+ show_default(num_dests, dests);
+ show_classes(http, NULL);
+ show_devices(http, NULL, num_dests, dests);
+ show_accepting(http, NULL, num_dests, dests);
+ show_printers(http, NULL, num_dests, dests, long_status);
+ show_jobs(http, NULL, NULL, long_status, ranking);
+ break;
+
+ case 'u' : /* Show jobs by user */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (argv[i][2] != '\0')
+ show_jobs(http, NULL, argv[i] + 2, long_status, ranking);
+ else if ((i + 1) < argc && argv[i + 1][0] != '-')
+ {
+ i ++;
+ show_jobs(http, NULL, argv[i], long_status, ranking);
+ }
+ else
+ show_jobs(http, NULL, NULL, long_status, ranking);
+ break;
+
+ case 'v' : /* Show printer devices */
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if (argv[i][2] != '\0')
+ show_devices(http, argv[i] + 2, num_dests, dests);
+ else if ((i + 1) < argc && argv[i + 1][0] != '-')
+ {
+ i ++;
+ show_devices(http, argv[i], num_dests, dests);
+ }
+ else
+ show_devices(http, NULL, num_dests, dests);
+ break;
+
+
+ default :
+ fprintf(stderr, "lpstat: Unknown option \'%c\'!\n", argv[i][1]);
+ return (1);
+ }
+ else
+ {
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ show_jobs(http, argv[i], NULL, long_status, ranking);
+ }
+
+ if (argc == 1)
+ {
+ if (!http)
+ {
+ http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption());
+
+ if (http == NULL)
+ {
+ perror("lpstat: Unable to connect to server");
+ return (1);
+ }
+ }
+
+ show_jobs(http, NULL, cupsUser(), long_status, ranking);
+ }
+
+ return (0);
+}
+
+
+/*
+ * 'show_accepting()' - Show acceptance status.
+ */
+
+static void
+show_accepting(http_t *http, /* I - HTTP connection to server */
+ const char *printers, /* I - Destinations */
+ int num_dests, /* I - Number of user-defined dests */
+ cups_dest_t *dests) /* I - User-defined destinations */
+{
+ int i; /* Looping var */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ const char *printer, /* Printer name */
+ *message; /* Printer device URI */
+ int accepting; /* Accepting requests? */
+ const char *dptr, /* Pointer into destination list */
+ *ptr; /* Pointer into printer name */
+ int match; /* Non-zero if this job matches */
+ static const char *pattrs[] = /* Attributes we need for printers... */
+ {
+ "printer-name",
+ "printer-state-message",
+ "printer-is-accepting-jobs"
+ };
+
+
+ DEBUG_printf(("show_accepting(%p, %p)\n", http, printers));
+
+ if (http == NULL)
+ return;
+
+ if (printers != NULL && strcmp(printers, "all") == 0)
+ printers = NULL;
+
+ /*
+ * Build a CUPS_GET_PRINTERS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_PRINTERS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
+ NULL, pattrs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ DEBUG_puts("show_accepting: request succeeded...");
+
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "lpstat: get-printers failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return;
+ }
+
+ /*
+ * Loop through the printers returned in the list and display
+ * their devices...
+ */
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a printer...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this printer...
+ */
+
+ printer = NULL;
+ message = NULL;
+ accepting = 1;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
+ {
+ if (strcmp(attr->name, "printer-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ printer = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-state-message") == 0 &&
+ attr->value_tag == IPP_TAG_TEXT)
+ message = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-is-accepting-jobs") == 0 &&
+ attr->value_tag == IPP_TAG_BOOLEAN)
+ accepting = attr->values[0].boolean;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (printer == NULL)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ /*
+ * See if this is a printer we're interested in...
+ */
+
+ match = printers == NULL;
+
+ if (printers != NULL)
+ {
+ for (dptr = printers; *dptr != '\0';)
+ {
+ /*
+ * Skip leading whitespace and commas...
+ */
+
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+
+ /*
+ * Compare names...
+ */
+
+ for (ptr = printer;
+ *ptr != '\0' && *dptr != '\0' && tolower(*ptr) == tolower(*dptr);
+ ptr ++, dptr ++);
+
+ if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr)))
+ {
+ match = 1;
+ break;
+ }
+
+ /*
+ * Skip trailing junk...
+ */
+
+ while (!isspace(*dptr) && *dptr != '\0')
+ dptr ++;
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+ }
+ }
+
+ /*
+ * Display the printer entry if needed...
+ */
+
+ if (match)
+ {
+ if (accepting)
+ printf("%s accepting requests since Jan 01 00:00\n", printer);
+ else
+ printf("%s not accepting requests since Jan 01 00:00 -\n\t%s\n", printer,
+ message == NULL ? "reason unknown" : message);
+
+ for (i = 0; i < num_dests; i ++)
+ if (strcasecmp(dests[i].name, printer) == 0 && dests[i].instance)
+ {
+ if (accepting)
+ printf("%s/%s accepting requests since Jan 01 00:00\n", printer, dests[i].instance);
+ else
+ printf("%s/%s not accepting requests since Jan 01 00:00 -\n\t%s\n", printer,
+ dests[i].instance,
+ message == NULL ? "reason unknown" : message);
+ }
+ }
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ fprintf(stderr, "lpstat: get-printers failed: %s\n",
+ ippErrorString(cupsLastError()));
+}
+
+
+/*
+ * 'show_classes()' - Show printer classes.
+ */
+
+static void
+show_classes(http_t *http, /* I - HTTP connection to server */
+ const char *dests) /* I - Destinations */
+{
+ int i; /* Looping var */
+ ipp_t *request, /* IPP Request */
+ *response, /* IPP Response */
+ *response2; /* IPP response from remote server */
+ http_t *http2; /* Remote server */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ const char *printer, /* Printer class name */
+ *printer_uri; /* Printer class URI */
+ ipp_attribute_t *members; /* Printer members */
+ char method[HTTP_MAX_URI],
+ /* Request method */
+ username[HTTP_MAX_URI],
+ /* Username:password */
+ server[HTTP_MAX_URI],
+ /* Server name */
+ resource[HTTP_MAX_URI];
+ /* Resource name */
+ int port; /* Port number */
+ const char *dptr, /* Pointer into destination list */
+ *ptr; /* Pointer into printer name */
+ int match; /* Non-zero if this job matches */
+ static const char *cattrs[] = /* Attributes we need for classes... */
+ {
+ "printer-name",
+ "printer-uri-supported",
+ "member-names"
+ };
+
+
+ DEBUG_printf(("show_classes(%p, %p)\n", http, dests));
+
+ if (http == NULL)
+ return;
+
+ if (dests != NULL && strcmp(dests, "all") == 0)
+ dests = NULL;
+
+ /*
+ * Build a CUPS_GET_CLASSES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_CLASSES;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(cattrs) / sizeof(cattrs[0]),
+ NULL, cattrs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ DEBUG_puts("show_classes: request succeeded...");
+
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "lpstat: get-classes failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return;
+ }
+
+ /*
+ * Loop through the printers returned in the list and display
+ * their devices...
+ */
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a job...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this job...
+ */
+
+ printer = NULL;
+ printer_uri = NULL;
+ members = NULL;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
+ {
+ if (strcmp(attr->name, "printer-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ printer = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-uri-supported") == 0 &&
+ attr->value_tag == IPP_TAG_URI)
+ printer_uri = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "member-names") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ members = attr;
+
+ attr = attr->next;
+ }
+
+ /*
+ * If this is a remote class, grab the class info from the
+ * remote server...
+ */
+
+ response2 = NULL;
+ if (members == NULL && printer_uri != NULL)
+ {
+ httpSeparate(printer_uri, method, username, server, &port, resource);
+
+ if ((http2 = httpConnectEncrypt(server, port, cupsEncryption())) != NULL)
+ {
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
+ * following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, printer_uri);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(cattrs) / sizeof(cattrs[0]),
+ NULL, cattrs);
+
+ if ((response2 = cupsDoRequest(http2, request, "/")) != NULL)
+ members = ippFindAttribute(response2, "member-names", IPP_TAG_NAME);
+
+ httpClose(http2);
+ }
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (printer == NULL)
+ {
+ if (response2)
+ ippDelete(response2);
+
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ /*
+ * See if this is a printer we're interested in...
+ */
+
+ match = dests == NULL;
+
+ if (dests != NULL)
+ {
+ for (dptr = dests; *dptr != '\0';)
+ {
+ /*
+ * Skip leading whitespace and commas...
+ */
+
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+
+ /*
+ * Compare names...
+ */
+
+ for (ptr = printer;
+ *ptr != '\0' && *dptr != '\0' && tolower(*ptr) == tolower(*dptr);
+ ptr ++, dptr ++);
+
+ if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr)))
+ {
+ match = 1;
+ break;
+ }
+
+ /*
+ * Skip trailing junk...
+ */
+
+ while (!isspace(*dptr) && *dptr != '\0')
+ dptr ++;
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+ }
+ }
+
+ /*
+ * Display the printer entry if needed...
+ */
+
+ if (match)
+ {
+ printf("members of class %s:\n", printer);
+
+ if (members)
+ {
+ for (i = 0; i < members->num_values; i ++)
+ printf("\t%s\n", members->values[i].string.text);
+ }
+ else
+ puts("\tunknown");
+ }
+
+ if (response2)
+ ippDelete(response2);
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ fprintf(stderr, "lpstat: get-classes failed: %s\n",
+ ippErrorString(cupsLastError()));
+}
+
+
+/*
+ * 'show_default()' - Show default destination.
+ */
+
+static void
+show_default(int num_dests, /* I - Number of user-defined dests */
+ cups_dest_t *dests) /* I - User-defined destinations */
+{
+ int i; /* Looping var */
+
+
+ for (i = 0; i < num_dests; i ++)
+ if (dests[i].is_default)
+ break;
+
+ if (i < num_dests)
+ {
+ if (dests[i].instance)
+ printf("system default destination: %s/%s\n", dests[i].name,
+ dests[i].instance);
+ else
+ printf("system default destination: %s\n", dests[i].name);
+ }
+ else
+ puts("no system default destination");
+}
+
+
+/*
+ * 'show_devices()' - Show printer devices.
+ */
+
+static void
+show_devices(http_t *http, /* I - HTTP connection to server */
+ const char *printers, /* I - Destinations */
+ int num_dests, /* I - Number of user-defined dests */
+ cups_dest_t *dests) /* I - User-defined destinations */
+{
+ int i; /* Looping var */
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ const char *printer, /* Printer name */
+ *uri, /* Printer URI */
+ *device, /* Printer device URI */
+ *dptr, /* Pointer into destination list */
+ *ptr; /* Pointer into printer name */
+ int match; /* Non-zero if this job matches */
+ static const char *pattrs[] = /* Attributes we need for printers... */
+ {
+ "printer-name",
+ "printer-uri-supported",
+ "device-uri"
+ };
+
+
+ DEBUG_printf(("show_devices(%p, %p)\n", http, dests));
+
+ if (http == NULL)
+ return;
+
+ if (printers != NULL && strcmp(printers, "all") == 0)
+ printers = NULL;
+
+ /*
+ * Build a CUPS_GET_PRINTERS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_PRINTERS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
+ NULL, pattrs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ DEBUG_puts("show_devices: request succeeded...");
+
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "lpstat: get-printers failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return;
+ }
+
+ /*
+ * Loop through the printers returned in the list and display
+ * their devices...
+ */
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a job...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this job...
+ */
+
+ printer = NULL;
+ device = NULL;
+ uri = NULL;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
+ {
+ if (strcmp(attr->name, "printer-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ printer = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-uri-supported") == 0 &&
+ attr->value_tag == IPP_TAG_URI)
+ uri = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "device-uri") == 0 &&
+ attr->value_tag == IPP_TAG_URI)
+ device = attr->values[0].string.text;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (printer == NULL)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ /*
+ * See if this is a printer we're interested in...
+ */
+
+ match = printers == NULL;
+
+ if (printers != NULL)
+ {
+ for (dptr = printers; *dptr != '\0';)
+ {
+ /*
+ * Skip leading whitespace and commas...
+ */
+
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+
+ /*
+ * Compare names...
+ */
+
+ for (ptr = printer;
+ *ptr != '\0' && *dptr != '\0' && tolower(*ptr) == tolower(*dptr);
+ ptr ++, dptr ++);
+
+ if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr)))
+ {
+ match = 1;
+ break;
+ }
+
+ /*
+ * Skip trailing junk...
+ */
+
+ while (!isspace(*dptr) && *dptr != '\0')
+ dptr ++;
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+ }
+ }
+
+ /*
+ * Display the printer entry if needed...
+ */
+
+ if (match)
+ {
+#ifdef __osf__ /* Compaq/Digital like to do it their own way... */
+ char method[HTTP_MAX_URI], /* Components of printer URI */
+ username[HTTP_MAX_URI],
+ hostname[HTTP_MAX_URI],
+ resource[HTTP_MAX_URI];
+ int port;
+
+
+ if (device == NULL)
+ {
+ httpSeparate(uri, method, username, hostname, &port, resource);
+ printf("Output for printer %s is sent to remote printer %s on %s\n",
+ printer, strrchr(resource, '/') + 1, hostname);
+ }
+ else if (strncmp(device, "file:", 5) == 0)
+ printf("Output for printer %s is sent to %s\n", printer, device + 5);
+ else
+ printf("Output for printer %s is sent to %s\n", printer, device);
+
+ for (i = 0; i < num_dests; i ++)
+ if (strcasecmp(printer, dests[i].name) == 0 && dests[i].instance)
+ {
+ if (device == NULL)
+ printf("Output for printer %s/%s is sent to remote printer %s on %s\n",
+ printer, dests[i].instance, strrchr(resource, '/') + 1,
+ hostname);
+ else if (strncmp(device, "file:", 5) == 0)
+ printf("Output for printer %s/%s is sent to %s\n", printer, dests[i].instance, device + 5);
+ else
+ printf("Output for printer %s/%s is sent to %s\n", printer, dests[i].instance, device);
+ }
+#else
+ if (device == NULL)
+ printf("device for %s: %s\n", printer, uri);
+ else if (strncmp(device, "file:", 5) == 0)
+ printf("device for %s: %s\n", printer, device + 5);
+ else
+ printf("device for %s: %s\n", printer, device);
+
+ for (i = 0; i < num_dests; i ++)
+ if (strcasecmp(printer, dests[i].name) == 0 && dests[i].instance)
+ {
+ if (device == NULL)
+ printf("device for %s/%s: %s\n", printer, dests[i].instance, uri);
+ else if (strncmp(device, "file:", 5) == 0)
+ printf("device for %s/%s: %s\n", printer, dests[i].instance, device + 5);
+ else
+ printf("device for %s/%s: %s\n", printer, dests[i].instance, device);
+ }
+#endif /* __osf__ */
+ }
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ fprintf(stderr, "lpstat: get-printers failed: %s\n",
+ ippErrorString(cupsLastError()));
+}
+
+
+/*
+ * 'show_jobs()' - Show active print jobs.
+ */
+
+static void
+show_jobs(http_t *http, /* I - HTTP connection to server */
+ const char *dests, /* I - Destinations */
+ const char *users, /* I - Users */
+ int long_status,/* I - Show long status? */
+ int ranking) /* I - Show job ranking? */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ const char *dest, /* Pointer into job-printer-uri */
+ *username, /* Pointer to job-originating-user-name */
+ *title; /* Pointer to job-name */
+ int rank, /* Rank in queue */
+ jobid, /* job-id */
+ size; /* job-k-octets */
+ time_t jobtime; /* time-at-creation */
+ struct tm *jobdate; /* Date & time */
+ const char *dptr, /* Pointer into destination list */
+ *ptr; /* Pointer into printer name */
+ int match; /* Non-zero if this job matches */
+ char temp[255], /* Temporary buffer */
+ date[32]; /* Date buffer */
+ static const char *jattrs[] = /* Attributes we need for jobs... */
+ {
+ "job-id",
+ "job-k-octets",
+ "job-name",
+ "time-at-creation",
+ "job-printer-uri",
+ "job-originating-user-name"
+ };
+
+
+ DEBUG_printf(("show_jobs(%p, %p, %p)\n", http, dests, users));
+
+ if (http == NULL)
+ return;
+
+ if (dests != NULL && strcmp(dests, "all") == 0)
+ dests = NULL;
+
+ /*
+ * Build a IPP_GET_JOBS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * job-uri
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_JOBS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(jattrs) / sizeof(jattrs[0]),
+ NULL, jattrs);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
+ NULL, "ipp://localhost/jobs/");
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ /*
+ * Loop through the job list and display them...
+ */
+
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "lpstat: get-jobs failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return;
+ }
+
+ rank = -1;
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a job...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this job...
+ */
+
+ jobid = 0;
+ size = 0;
+ username = NULL;
+ dest = NULL;
+ jobtime = 0;
+ title = "no title";
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
+ {
+ if (strcmp(attr->name, "job-id") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobid = attr->values[0].integer;
+
+ if (strcmp(attr->name, "job-k-octets") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ size = attr->values[0].integer * 1024;
+
+ if (strcmp(attr->name, "time-at-creation") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobtime = attr->values[0].integer;
+
+ if (strcmp(attr->name, "job-printer-uri") == 0 &&
+ attr->value_tag == IPP_TAG_URI)
+ if ((dest = strrchr(attr->values[0].string.text, '/')) != NULL)
+ dest ++;
+
+ if (strcmp(attr->name, "job-originating-user-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ username = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "job-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ title = attr->values[0].string.text;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (dest == NULL || jobid == 0)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ /*
+ * See if this is a job we're interested in...
+ */
+
+ match = (dests == NULL && users == NULL);
+ rank ++;
+
+ if (dests != NULL)
+ {
+ for (dptr = dests; *dptr != '\0';)
+ {
+ /*
+ * Skip leading whitespace and commas...
+ */
+
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+
+ /*
+ * Compare names...
+ */
+
+ for (ptr = dest;
+ *ptr != '\0' && *dptr != '\0' && tolower(*ptr) == tolower(*dptr);
+ ptr ++, dptr ++);
+
+ if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr)))
+ {
+ match = 1;
+ break;
+ }
+
+ /*
+ * Skip trailing junk...
+ */
+
+ while (!isspace(*dptr) && *dptr != '\0')
+ dptr ++;
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+ }
+ }
+
+ if (users != NULL && username != NULL)
+ {
+ for (dptr = users; *dptr != '\0';)
+ {
+ /*
+ * Skip leading whitespace and commas...
+ */
+
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+
+ /*
+ * Compare names...
+ */
+
+ for (ptr = username;
+ *ptr != '\0' && *dptr != '\0' && *ptr == *dptr;
+ ptr ++, dptr ++);
+
+ if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr)))
+ {
+ match = 1;
+ break;
+ }
+
+ /*
+ * Skip trailing junk...
+ */
+
+ while (!isspace(*dptr) && *dptr != '\0')
+ dptr ++;
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+ }
+ }
+
+ /*
+ * Display the job...
+ */
+
+ if (match)
+ {
+ jobdate = localtime(&jobtime);
+ snprintf(temp, sizeof(temp), "%s-%d", dest, jobid);
+
+ if (long_status == 3)
+ {
+ /*
+ * Show the consolidated output format for the SGI tools...
+ */
+
+ strftime(date, sizeof(date), "%b %d %H:%M", jobdate);
+
+ printf("%s;%s;%d;%s;%s\n", temp, username ? username : "unknown",
+ size, title ? title : "unknown", date);
+ }
+ else
+ {
+ strftime(date, sizeof(date), CUPS_STRFTIME_FORMAT, jobdate);
+
+ if (ranking)
+ printf("%3d %-21s %-13s %8d %s\n", rank, temp,
+ username ? username : "unknown", size, date);
+ else
+ printf("%-23s %-13s %8d %s\n", temp,
+ username ? username : "unknown", size, date);
+ if (long_status)
+ printf("\tqueued for %s\n", dest);
+ }
+ }
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ fprintf(stderr, "lpstat: get-jobs failed: %s\n",
+ ippErrorString(cupsLastError()));
+}
+
+
+/*
+ * 'show_printers()' - Show printers.
+ */
+
+static void
+show_printers(http_t *http, /* I - HTTP connection to server */
+ const char *printers, /* I - Destinations */
+ int num_dests, /* I - Number of user-defined dests */
+ cups_dest_t *dests, /* I - User-defined destinations */
+ int long_status) /* I - Show long status? */
+{
+ int i; /* Looping var */
+ ipp_t *request, /* IPP Request */
+ *response, /* IPP Response */
+ *jobs; /* IPP Get Jobs response */
+ ipp_attribute_t *attr; /* Current attribute */
+ ipp_attribute_t *jobattr; /* Job ID attribute */
+ cups_lang_t *language; /* Default language */
+ const char *printer, /* Printer name */
+ *message, /* Printer state message */
+ *description, /* Description of printer */
+ *location; /* Location of printer */
+ ipp_pstate_t pstate; /* Printer state */
+ cups_ptype_t ptype; /* Printer type */
+ int jobid; /* Job ID of current job */
+ const char *dptr, /* Pointer into destination list */
+ *ptr; /* Pointer into printer name */
+ int match; /* Non-zero if this job matches */
+ char printer_uri[HTTP_MAX_URI];
+ /* Printer URI */
+ const char *root; /* Server root directory... */
+ static const char *pattrs[] = /* Attributes we need for printers... */
+ {
+ "printer-name",
+ "printer-state",
+ "printer-state-message",
+ "printer-type",
+ "printer-info",
+ "printer-location"
+ };
+ static const char *jattrs[] = /* Attributes we need for jobs... */
+ {
+ "job-id"
+ };
+
+
+ DEBUG_printf(("show_printers(%p, %p)\n", http, dests));
+
+ if (http == NULL)
+ return;
+
+ if ((root = getenv("CUPS_SERVERROOT")) == NULL)
+ root = CUPS_SERVERROOT;
+
+ if (printers != NULL && strcmp(printers, "all") == 0)
+ printers = NULL;
+
+ /*
+ * Build a CUPS_GET_PRINTERS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = CUPS_GET_PRINTERS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
+ NULL, pattrs);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ DEBUG_puts("show_printers: request succeeded...");
+
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ fprintf(stderr, "lpstat: get-printers failed: %s\n",
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return;
+ }
+
+ /*
+ * Loop through the printers returned in the list and display
+ * their status...
+ */
+
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a job...
+ */
+
+ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this job...
+ */
+
+ printer = NULL;
+ ptype = CUPS_PRINTER_LOCAL;
+ pstate = IPP_PRINTER_IDLE;
+ message = NULL;
+ description = NULL;
+ location = NULL;
+ jobid = 0;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
+ {
+ if (strcmp(attr->name, "printer-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ printer = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-state") == 0 &&
+ attr->value_tag == IPP_TAG_ENUM)
+ pstate = (ipp_pstate_t)attr->values[0].integer;
+
+ if (strcmp(attr->name, "printer-type") == 0 &&
+ attr->value_tag == IPP_TAG_ENUM)
+ ptype = (cups_ptype_t)attr->values[0].integer;
+
+ if (strcmp(attr->name, "printer-state-message") == 0 &&
+ attr->value_tag == IPP_TAG_TEXT)
+ message = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-info") == 0 &&
+ attr->value_tag == IPP_TAG_TEXT)
+ description = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "printer-location") == 0 &&
+ attr->value_tag == IPP_TAG_TEXT)
+ location = attr->values[0].string.text;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (printer == NULL)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ /*
+ * See if this is a printer we're interested in...
+ */
+
+ match = printers == NULL;
+
+ if (printers != NULL)
+ {
+ for (dptr = printers; *dptr != '\0';)
+ {
+ /*
+ * Skip leading whitespace and commas...
+ */
+
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+
+ /*
+ * Compare names...
+ */
+
+ for (ptr = printer;
+ *ptr != '\0' && *dptr != '\0' && tolower(*ptr) == tolower(*dptr);
+ ptr ++, dptr ++);
+
+ if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr)))
+ {
+ match = 1;
+ break;
+ }
+
+ /*
+ * Skip trailing junk...
+ */
+
+ while (!isspace(*dptr) && *dptr != '\0')
+ dptr ++;
+ while (isspace(*dptr) || *dptr == ',')
+ dptr ++;
+
+ if (*dptr == '\0')
+ break;
+ }
+ }
+
+ /*
+ * Display the printer entry if needed...
+ */
+
+ if (match)
+ {
+ /*
+ * If the printer state is "IPP_PRINTER_PROCESSING", then grab the
+ * current job for the printer.
+ */
+
+ if (pstate == IPP_PRINTER_PROCESSING)
+ {
+ /*
+ * Build an IPP_GET_JOBS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * limit
+ * requested-attributes
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_JOBS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL,
+ cupsLangEncoding(language));
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL,
+ language->language);
+
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes",
+ sizeof(jattrs) / sizeof(jattrs[0]), NULL, jattrs);
+
+ snprintf(printer_uri, sizeof(printer_uri), "ipp://%s/printers/%s",
+ http->hostname, printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, printer_uri);
+
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
+ "limit", 1);
+
+ if ((jobs = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if ((jobattr = ippFindAttribute(jobs, "job-id", IPP_TAG_INTEGER)) != NULL)
+ jobid = jobattr->values[0].integer;
+
+ ippDelete(jobs);
+ }
+ }
+
+ /*
+ * Display it...
+ */
+
+ switch (pstate)
+ {
+ case IPP_PRINTER_IDLE :
+ printf("printer %s is idle. enabled since Jan 01 00:00\n", printer);
+ break;
+ case IPP_PRINTER_PROCESSING :
+ printf("printer %s now printing %s-%d. enabled since Jan 01 00:00\n", printer, printer, jobid);
+ break;
+ case IPP_PRINTER_STOPPED :
+ printf("printer %s disabled since Jan 01 00:00 -\n\t%s\n", printer,
+ message == NULL ? "reason unknown" : message);
+ break;
+ }
+
+ if (long_status > 1)
+ {
+ puts("\tForm mounted:");
+ puts("\tContent types: any");
+ puts("\tPrinter types: unknown");
+ }
+ if (long_status)
+ printf("\tDescription: %s\n", description ? description : "");
+ if (long_status > 1)
+ {
+ printf("\tLocation: %s\n", location ? location : "");
+ printf("\tConnection: %s\n",
+ (ptype & CUPS_PRINTER_REMOTE) ? "remote" : "direct");
+ if (!(ptype & CUPS_PRINTER_REMOTE))
+ printf("\tInterface: %s/ppd/%s.ppd\n", root, printer);
+ puts("\tOn fault: no alert");
+ puts("\tAfter fault: continue");
+ puts("\tUsers allowed:");
+ puts("\t\t(all)");
+ puts("\tForms allowed:");
+ puts("\t\t(none)");
+ puts("\tBanner required");
+ puts("\tCharset sets:");
+ puts("\t\t(none)");
+ puts("\tDefault pitch:");
+ puts("\tDefault page size:");
+ puts("\tDefault port settings:");
+ }
+
+ for (i = 0; i < num_dests; i ++)
+ if (strcasecmp(printer, dests[i].name) == 0 && dests[i].instance)
+ {
+ switch (pstate)
+ {
+ case IPP_PRINTER_IDLE :
+ printf("printer %s/%s is idle. enabled since Jan 01 00:00\n", printer, dests[i].instance);
+ break;
+ case IPP_PRINTER_PROCESSING :
+ printf("printer %s/%s now printing %s-%d. enabled since Jan 01 00:00\n", printer,
+ dests[i].instance, printer, jobid);
+ break;
+ case IPP_PRINTER_STOPPED :
+ printf("printer %s/%s disabled since Jan 01 00:00 -\n\t%s\n", printer,
+ dests[i].instance,
+ message == NULL ? "reason unknown" : message);
+ break;
+ }
+
+ if (long_status > 1)
+ {
+ puts("\tForm mounted:");
+ puts("\tContent types: any");
+ puts("\tPrinter types: unknown");
+ }
+ if (long_status)
+ printf("\tDescription: %s\n", description ? description : "");
+ if (long_status > 1)
+ {
+ printf("\tLocation: %s\n", location ? location : "");
+ printf("\tConnection: %s\n",
+ (ptype & CUPS_PRINTER_REMOTE) ? "remote" : "direct");
+ if (!(ptype & CUPS_PRINTER_REMOTE))
+ printf("\tInterface: %s/ppd/%s.ppd\n", root, printer);
+ puts("\tOn fault: no alert");
+ puts("\tAfter fault: continue");
+ puts("\tUsers allowed:");
+ puts("\t\t(all)");
+ puts("\tForms allowed:");
+ puts("\t\t(none)");
+ puts("\tBanner required");
+ puts("\tCharset sets:");
+ puts("\t\t(none)");
+ puts("\tDefault pitch:");
+ puts("\tDefault page size:");
+ puts("\tDefault port settings:");
+ }
+ }
+ }
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ fprintf(stderr, "lpstat: get-printers failed: %s\n",
+ ippErrorString(cupsLastError()));
+}
+
+
+/*
+ * 'show_scheduler()' - Show scheduler status.
+ */
+
+static void
+show_scheduler(http_t *http) /* I - HTTP connection to server */
+{
+ printf("scheduler is %srunning\n", http == NULL ? "not " : "");
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/templates/Makefile b/templates/Makefile
new file mode 100644
index 000000000..56cf9405c
--- /dev/null
+++ b/templates/Makefile
@@ -0,0 +1,107 @@
+#
+# "$Id$"
+#
+# Template makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+#
+# Template files...
+#
+
+FILES = add-class.tmpl \
+ add-printer.tmpl \
+ admin-op.tmpl \
+ admin.tmpl \
+ choose-device.tmpl \
+ choose-make.tmpl \
+ choose-members.tmpl \
+ choose-model.tmpl \
+ choose-serial.tmpl \
+ choose-uri.tmpl \
+ class-added.tmpl \
+ class-confirm.tmpl \
+ class-deleted.tmpl \
+ class-modified.tmpl \
+ classes.tmpl \
+ config-printer.tmpl \
+ config-printer2.tmpl \
+ error.tmpl \
+ header.tmpl \
+ jobs.tmpl \
+ job-cancel.tmpl \
+ job-hold.tmpl \
+ job-op.tmpl \
+ job-release.tmpl \
+ job-restart.tmpl \
+ modify-class.tmpl \
+ modify-printer.tmpl \
+ option-boolean.tmpl \
+ option-conflict.tmpl \
+ option-header.tmpl \
+ option-pickmany.tmpl \
+ option-pickone.tmpl \
+ option-trailer.tmpl \
+ printers.tmpl \
+ printer-accept.tmpl \
+ printer-added.tmpl \
+ printer-configured.tmpl \
+ printer-confirm.tmpl \
+ printer-deleted.tmpl \
+ printer-modified.tmpl \
+ printer-purge.tmpl \
+ printer-reject.tmpl \
+ printer-start.tmpl \
+ printer-stop.tmpl \
+ test-page.tmpl \
+ trailer.tmpl
+
+
+#
+# Make everything...
+#
+
+all:
+
+
+#
+# Clean all config and object files...
+#
+
+clean:
+
+
+#
+# Install files...
+#
+
+install:
+ $(INSTALL_DIR) $(DATADIR)/templates
+ for file in $(FILES); do \
+ $(INSTALL_DATA) $$file $(DATADIR)/templates; \
+ done
+ cd fr; make install
+
+
+#
+# End of "$Id$".
+#
diff --git a/templates/add-class.tmpl b/templates/add-class.tmpl
new file mode 100644
index 000000000..019a3f9fc
--- /dev/null
+++ b/templates/add-class.tmpl
@@ -0,0 +1,33 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Add New Class</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Name:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_NAME" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Location:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_LOCATION" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Description:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/add-printer.tmpl b/templates/add-printer.tmpl
new file mode 100644
index 000000000..bf4a33d83
--- /dev/null
+++ b/templates/add-printer.tmpl
@@ -0,0 +1,33 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Add New Printer</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Name:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_NAME" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Location:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_LOCATION" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Description:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/admin-op.tmpl b/templates/admin-op.tmpl
new file mode 100644
index 000000000..16699f815
--- /dev/null
+++ b/templates/admin-op.tmpl
@@ -0,0 +1 @@
+<P>Unsupported administration operation "{op}".
diff --git a/templates/admin.tmpl b/templates/admin.tmpl
new file mode 100644
index 000000000..65a711fd7
--- /dev/null
+++ b/templates/admin.tmpl
@@ -0,0 +1,57 @@
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966">Classes</TH>
+ <TH WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD><A HREF="/admin/?op=add-class">
+ <IMG SRC="/images/add-class.gif" ALT="Add a New Class" BORDER="0"></A>
+ <A HREF="/classes/">
+ <IMG SRC="/images/manage-classes.gif" ALT="Manage Available Classes" BORDER="0"></A>
+ </TD>
+</TR>
+<TR>
+ <TD>&nbsp;</TD>
+</TR>
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966">Jobs</TH>
+ <TH WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD><A HREF="/jobs/">
+ <IMG SRC="/images/manage-jobs.gif" ALT="Manage Jobs" BORDER="0"></A>
+ </TD>
+</TR>
+<TR>
+ <TD>&nbsp;</TD>
+</TR>
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966">Printers</TH>
+ <TH WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD><A HREF="/admin/?op=add-printer">
+ <IMG SRC="/images/add-printer.gif" ALT="Add a New Printer" BORDER="0"></A>
+ <A HREF="/printers/">
+ <IMG SRC="/images/manage-printers.gif" ALT="Manage Available Printers" BORDER="0"></A>
+ </TD>
+</TR>
+<TR>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
diff --git a/templates/choose-device.tmpl b/templates/choose-device.tmpl
new file mode 100644
index 000000000..f64810910
--- /dev/null
+++ b/templates/choose-device.tmpl
@@ -0,0 +1,32 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<INPUT TYPE="HIDDEN" NAME="CURRENT_MAKE_AND_MODEL" VALUE="{?current_make_and_model}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Device for {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Device:&nbsp;</TD>
+ <TD>
+ <SELECT NAME="DEVICE_URI">
+ {[device_uri]<OPTION VALUE="{device_uri}" {?current_device_uri={device_uri}?SELECTED:}>
+ {device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
+ }</SELECT>
+ </TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/choose-make.tmpl b/templates/choose-make.tmpl
new file mode 100644
index 000000000..8392047c9
--- /dev/null
+++ b/templates/choose-make.tmpl
@@ -0,0 +1,35 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">
+<INPUT TYPE="HIDDEN" NAME="BAUDRATE" VALUE="{?baudrate}">
+<INPUT TYPE="HIDDEN" NAME="BITS" VALUE="{?bits}">
+<INPUT TYPE="HIDDEN" NAME="PARITY" VALUE="{?parity}">
+<INPUT TYPE="HIDDEN" NAME="FLOW" VALUE="{?flow}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Model/Driver for {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Make:&nbsp;</TD>
+ <TD>
+ <SELECT NAME="PPD_MAKE" SIZE="10">
+ {[ppd_make]<OPTION VALUE="{ppd_make}" {?current_make={ppd_make}?SELECTED:}>{ppd_make}}
+ </SELECT>
+ </TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/choose-members.tmpl b/templates/choose-members.tmpl
new file mode 100644
index 000000000..b83f13e74
--- /dev/null
+++ b/templates/choose-members.tmpl
@@ -0,0 +1,30 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Members for {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Members:&nbsp;</TD>
+ <TD>
+ <SELECT NAME="MEMBER_URIS" SIZE="10" MULTIPLE>
+ {[member_uris]<OPTION VALUE="{member_uris}" {?member_selected}>{member_names}}
+ </SELECT>
+ </TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/choose-model.tmpl b/templates/choose-model.tmpl
new file mode 100644
index 000000000..60efb5634
--- /dev/null
+++ b/templates/choose-model.tmpl
@@ -0,0 +1,35 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">
+<INPUT TYPE="HIDDEN" NAME="BAUDRATE" VALUE="{?baudrate}">
+<INPUT TYPE="HIDDEN" NAME="BITS" VALUE="{?bits}">
+<INPUT TYPE="HIDDEN" NAME="PARITY" VALUE="{?parity}">
+<INPUT TYPE="HIDDEN" NAME="FLOW" VALUE="{?flow}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Model/Driver for {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Model:&nbsp;</TD>
+ <TD>
+ <SELECT NAME="PPD_NAME" SIZE="10">
+ {[ppd_name]<OPTION VALUE="{ppd_name}" {?current_make_and_model={ppd_make_and_model}?SELECTED:}>{ppd_make_and_model} ({ppd_natural_language})
+ }</SELECT>
+ </TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/choose-serial.tmpl b/templates/choose-serial.tmpl
new file mode 100644
index 000000000..a0ea5db2d
--- /dev/null
+++ b/templates/choose-serial.tmpl
@@ -0,0 +1,56 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Serial Port Settings for {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Baud Rate:&nbsp;</TD>
+ <TD><SELECT NAME="BAUDRATE">
+ {[baudrates]<OPTION {?baudrate={baudrates}?SELECTED:}>{baudrates}}
+ </SELECT></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Parity:&nbsp;</TD>
+ <TD><SELECT NAME="PARITY">
+ <OPTION VALUE="none" {?parity=none?SELECTED:}>None
+ <OPTION VALUE="even" {?parity=even?SELECTED:}>Even
+ <OPTION VALUE="odd" {?parity=odd?SELECTED:}>Odd
+ </SELECT></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Data Bits:&nbsp;</TD>
+ <TD><SELECT NAME="BITS">
+ <OPTION {?bits=8?SELECTED:}>8
+ <OPTION {?bits=7?SELECTED:}>7
+ </SELECT></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Flow Control:&nbsp;</TD>
+ <TD><SELECT NAME="FLOW">
+ <OPTION VALUE="none" {?flow=none?SELECTED:}>None
+ <OPTION VALUE="soft" {?flow=soft?SELECTED:}>XON/XOFF (Software)
+ <OPTION VALUE="hard" {?flow=hard?SELECTED:}>RTS/CTS (Hardware)
+ <OPTION VALUE="dtrdsr" {?flow=dtrdsr?SELECTED:}>DTR/DSR (Hardware)
+ </SELECT></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/choose-uri.tmpl b/templates/choose-uri.tmpl
new file mode 100644
index 000000000..602d66f4e
--- /dev/null
+++ b/templates/choose-uri.tmpl
@@ -0,0 +1,43 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<INPUT TYPE="HIDDEN" NAME="CURRENT_MAKE_AND_MODEL" VALUE="{?current_make_and_model}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Device URI for {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Device URI:&nbsp;</TD>
+ <TD><INPUT TYPE="TEXT" SIZE="40" MAXLENGTH="1024" NAME="DEVICE_URI" VALUE="{device_uri}"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD>Examples:
+ <PRE>
+ file:/path/to/filename.prn
+ http://hostname:631/ipp/
+ http://hostname:631/ipp/port1
+ ipp://hostname/ipp/
+ ipp://hostname/ipp/port1
+ lpd://hostname/queue
+ socket://hostname
+ socket://hostname:9100
+ </PRE>
+ </TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/class-added.tmpl b/templates/class-added.tmpl
new file mode 100644
index 000000000..f740581ad
--- /dev/null
+++ b/templates/class-added.tmpl
@@ -0,0 +1,2 @@
+<P>Class <A HREF="/classes/{printer_name}">{printer_name}</A> has been added
+successfully.
diff --git a/templates/class-confirm.tmpl b/templates/class-confirm.tmpl
new file mode 100644
index 000000000..0fbbd6d53
--- /dev/null
+++ b/templates/class-confirm.tmpl
@@ -0,0 +1,6 @@
+<P><B>Warning:</B> About to delete class {printer_name}! Do you wish to
+continue?
+
+<P ALIGN="CENTER">
+<A HREF="/admin/?op=delete-class&printer_name={printer_name}&confirm=yes">
+<IMG SRC="/images/continue.gif" ALT="Continue" BORDER="0"></A>
diff --git a/templates/class-deleted.tmpl b/templates/class-deleted.tmpl
new file mode 100644
index 000000000..269ddd87a
--- /dev/null
+++ b/templates/class-deleted.tmpl
@@ -0,0 +1 @@
+<P>Class {printer_name} has been deleted successfully.
diff --git a/templates/class-modified.tmpl b/templates/class-modified.tmpl
new file mode 100644
index 000000000..861790732
--- /dev/null
+++ b/templates/class-modified.tmpl
@@ -0,0 +1,2 @@
+<P>Class <A HREF="/classes/{printer_name}">{printer_name}</A> has been
+modified successfully.
diff --git a/templates/classes.tmpl b/templates/classes.tmpl
new file mode 100644
index 000000000..f7cc8d3a7
--- /dev/null
+++ b/templates/classes.tmpl
@@ -0,0 +1,51 @@
+{#printer_name=0?No classes:
+<P><B>Default Destination:</B> <A HREF="{default_uri}">{default_name}</A>
+<P><TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+{[printer_name]
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966"><A HREF="{printer_uri_supported}">{printer_name}</A></TH>
+ <TH BGCOLOR="#999966">Printer Class</TH>
+ <TH><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD VALIGN=TOP><A HREF="{printer_uri_supported}">
+ <IMG SRC="../images/classes.gif" BORDER="0" ALT=""></A></TD>
+ <TD VALIGN=TOP>Description: {printer_info}<BR>
+ Location: {printer_location}<BR>
+ Class State: {printer_state=3?idle:{printer_state=4?processing:stopped}},
+ {printer_is_accepting_jobs=0?rejecting jobs:accepting jobs}.
+ {?printer_state_message=?:<BR><I>"{printer_state_message}"</I>}
+ {?member_names=?:<BR>Members: {member_names}}
+ <P>
+ <A HREF="{printer_uri_supported}?op=print-test-page">
+ <IMG SRC="/images/print-test-page.gif" ALT="Print Test Page" BORDER="0"></A>
+ {printer_state=5?
+ <A HREF="/admin/?op=start-printer&printer_name={printer_name}">
+ <IMG SRC="/images/start-class.gif" ALT="Start Class" BORDER="0"></A>
+ :
+ <A HREF="/admin/?op=stop-printer&printer_name={printer_name}">
+ <IMG SRC="/images/stop-class.gif" ALT="Stop Class" BORDER="0"></A>
+ }
+ {printer_is_accepting_jobs=0?
+ <A HREF="/admin/?op=accept-jobs&printer_name={printer_name}">
+ <IMG SRC="/images/accept-jobs.gif" ALT="Accept Jobs" BORDER="0"></A>
+ :
+ <A HREF="/admin/?op=reject-jobs&printer_name={printer_name}">
+ <IMG SRC="/images/reject-jobs.gif" ALT="Reject Jobs" BORDER="0"></A>
+ }
+ <A HREF="/admin/?op=modify-class&printer_name={printer_name}">
+ <IMG SRC="/images/modify-class.gif" ALT="Modify Class" BORDER="0"></A>
+ <A HREF="/admin/?op=delete-class&printer_name={printer_name}">
+ <IMG SRC="/images/delete-class.gif" ALT="Delete Class" BORDER="0"></A>
+ </TD>
+</TR>
+}
+</TABLE>
+}
+<P><A HREF="/admin/?op=add-class">
+<IMG SRC="/images/add-class.gif" ALT="Add Class" BORDER="0"></A>
diff --git a/templates/config-printer.tmpl b/templates/config-printer.tmpl
new file mode 100644
index 000000000..f24b08f12
--- /dev/null
+++ b/templates/config-printer.tmpl
@@ -0,0 +1,6 @@
+<P>Choose default options for {printer_name}.
+
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
diff --git a/templates/config-printer2.tmpl b/templates/config-printer2.tmpl
new file mode 100644
index 000000000..bfb42d69f
--- /dev/null
+++ b/templates/config-printer2.tmpl
@@ -0,0 +1,2 @@
+</TABLE>
+</FORM>
diff --git a/templates/error.tmpl b/templates/error.tmpl
new file mode 100644
index 000000000..eb15a06ff
--- /dev/null
+++ b/templates/error.tmpl
@@ -0,0 +1,3 @@
+<P>Error:
+
+<BLOCKQUOTE>{error}</BLOCKQUOTE>
diff --git a/templates/fr/Makefile b/templates/fr/Makefile
new file mode 100644
index 000000000..7a3437f2a
--- /dev/null
+++ b/templates/fr/Makefile
@@ -0,0 +1,105 @@
+#
+# "$Id$"
+#
+# Template makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1993-2002 by Easy Software Products.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../../Makedefs
+
+#
+# Template files...
+#
+
+FILES = add-class.tmpl \
+ add-printer.tmpl \
+ admin-op.tmpl \
+ admin.tmpl \
+ choose-device.tmpl \
+ choose-make.tmpl \
+ choose-members.tmpl \
+ choose-model.tmpl \
+ choose-serial.tmpl \
+ choose-uri.tmpl \
+ class-added.tmpl \
+ class-confirm.tmpl \
+ class-deleted.tmpl \
+ class-modified.tmpl \
+ classes.tmpl \
+ config-printer.tmpl \
+ config-printer2.tmpl \
+ error.tmpl \
+ header.tmpl \
+ jobs.tmpl \
+ job-cancel.tmpl \
+ job-hold.tmpl \
+ job-op.tmpl \
+ job-release.tmpl \
+ job-restart.tmpl \
+ modify-class.tmpl \
+ modify-printer.tmpl \
+ option-boolean.tmpl \
+ option-header.tmpl \
+ option-pickmany.tmpl \
+ option-pickone.tmpl \
+ option-trailer.tmpl \
+ printers.tmpl \
+ printer-accept.tmpl \
+ printer-added.tmpl \
+ printer-configured.tmpl \
+ printer-confirm.tmpl \
+ printer-deleted.tmpl \
+ printer-modified.tmpl \
+ printer-purge.tmpl \
+ printer-reject.tmpl \
+ printer-start.tmpl \
+ printer-stop.tmpl \
+ test-page.tmpl \
+ trailer.tmpl
+
+
+#
+# Make everything...
+#
+
+all:
+
+
+#
+# Clean all config and object files...
+#
+
+clean:
+
+
+#
+# Install files...
+#
+
+install:
+ $(INSTALL_DIR) $(DATADIR)/fr/templates
+ for file in $(FILES); do \
+ $(INSTALL_DATA) $$file $(DATADIR)/fr/templates; \
+ done
+
+
+#
+# End of "$Id$".
+#
diff --git a/templates/fr/add-class.tmpl b/templates/fr/add-class.tmpl
new file mode 100644
index 000000000..dd300e46b
--- /dev/null
+++ b/templates/fr/add-class.tmpl
@@ -0,0 +1,33 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Ajouter une nouvelle classe d'imprimantes</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Nom:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_NAME" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Emplacement:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_LOCATION" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Description:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/fr/add-printer.tmpl b/templates/fr/add-printer.tmpl
new file mode 100644
index 000000000..44d273f9f
--- /dev/null
+++ b/templates/fr/add-printer.tmpl
@@ -0,0 +1,33 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Ajouter une nouvelle imprimante</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Nom:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_NAME" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Emplacement:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_LOCATION" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Description:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/fr/admin-op.tmpl b/templates/fr/admin-op.tmpl
new file mode 100644
index 000000000..ba0653a58
--- /dev/null
+++ b/templates/fr/admin-op.tmpl
@@ -0,0 +1 @@
+<P>Opération d'administration "{op}" non prise en charge.
diff --git a/templates/fr/admin.tmpl b/templates/fr/admin.tmpl
new file mode 100644
index 000000000..3a8e73fa9
--- /dev/null
+++ b/templates/fr/admin.tmpl
@@ -0,0 +1,57 @@
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966">Classes</TH>
+ <TH WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD><A HREF="/admin/?op=add-class">
+ <IMG SRC="/images/add-class.gif" ALT="Ajouter une nouvelle classe" BORDER="0"></A>
+ <A HREF="/classes/">
+ <IMG SRC="/images/manage-classes.gif" ALT="Administer les classes" BORDER="0"></A>
+ </TD>
+</TR>
+<TR>
+ <TD>&nbsp;</TD>
+</TR>
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966">Travaux d'impression</TH>
+ <TH WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD><A HREF="/jobs/">
+ <IMG SRC="/images/manage-jobs.gif" ALT="Administrer les travaux d'impression" BORDER="0"></A>
+ </TD>
+</TR>
+<TR>
+ <TD>&nbsp;</TD>
+</TR>
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966">Imprimantes</TH>
+ <TH WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD><A HREF="/admin/?op=add-printer">
+ <IMG SRC="/images/add-printer.gif" ALT="Ajouter une nouvelle imprimante" BORDER="0"></A>
+ <A HREF="/printers/">
+ <IMG SRC="/images/manage-printers.gif" ALT="Administrer les imprimantes disponibles" BORDER="0"></A>
+ </TD>
+</TR>
+<TR>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
diff --git a/templates/fr/choose-device.tmpl b/templates/fr/choose-device.tmpl
new file mode 100644
index 000000000..170c5f673
--- /dev/null
+++ b/templates/fr/choose-device.tmpl
@@ -0,0 +1,32 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<INPUT TYPE="HIDDEN" NAME="CURRENT_MAKE_AND_MODEL" VALUE="{?current_make_and_model}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Périphérique d'accès à l'imprimante {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Périphérique:&nbsp;</TD>
+ <TD>
+ <SELECT NAME="DEVICE_URI">
+ {[device_uri]<OPTION VALUE="{device_uri}" {?current_device_uri={device_uri}?SELECTED:}>
+ {device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
+ }</SELECT>
+ </TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Suite..." BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/fr/choose-make.tmpl b/templates/fr/choose-make.tmpl
new file mode 100644
index 000000000..c34222609
--- /dev/null
+++ b/templates/fr/choose-make.tmpl
@@ -0,0 +1,35 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">
+<INPUT TYPE="HIDDEN" NAME="BAUDRATE" VALUE="{?baudrate}">
+<INPUT TYPE="HIDDEN" NAME="BITS" VALUE="{?bits}">
+<INPUT TYPE="HIDDEN" NAME="PARITY" VALUE="{?parity}">
+<INPUT TYPE="HIDDEN" NAME="FLOW" VALUE="{?flow}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Modèle/Pilote pour {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Type:&nbsp;</TD>
+ <TD>
+ <SELECT NAME="PPD_MAKE" SIZE="10">
+ {[ppd_make]<OPTION VALUE="{ppd_make}" {?current_make={ppd_make}?SELECTED:}>{ppd_make}}
+ </SELECT>
+ </TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Suite..." BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/fr/choose-members.tmpl b/templates/fr/choose-members.tmpl
new file mode 100644
index 000000000..04e1b33c6
--- /dev/null
+++ b/templates/fr/choose-members.tmpl
@@ -0,0 +1,30 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Membres de la classe {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Membres:&nbsp;</TD>
+ <TD>
+ <SELECT NAME="MEMBER_URIS" SIZE="10" MULTIPLE>
+ {[member_uris]<OPTION VALUE="{member_uris}" {?member_selected}>{member_names}}
+ </SELECT>
+ </TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/fr/choose-model.tmpl b/templates/fr/choose-model.tmpl
new file mode 100644
index 000000000..db0699811
--- /dev/null
+++ b/templates/fr/choose-model.tmpl
@@ -0,0 +1,35 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">
+<INPUT TYPE="HIDDEN" NAME="BAUDRATE" VALUE="{?baudrate}">
+<INPUT TYPE="HIDDEN" NAME="BITS" VALUE="{?bits}">
+<INPUT TYPE="HIDDEN" NAME="PARITY" VALUE="{?parity}">
+<INPUT TYPE="HIDDEN" NAME="FLOW" VALUE="{?flow}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Modèle/Pilote pour {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Modèle:&nbsp;</TD>
+ <TD>
+ <SELECT NAME="PPD_NAME" SIZE="10">
+ {[ppd_name]<OPTION VALUE="{ppd_name}" {?current_make_and_model={ppd_make_and_model}?SELECTED:}>{ppd_make_and_model} ({ppd_natural_language})
+ }</SELECT>
+ </TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Suite..." BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/fr/choose-serial.tmpl b/templates/fr/choose-serial.tmpl
new file mode 100644
index 000000000..a20112c62
--- /dev/null
+++ b/templates/fr/choose-serial.tmpl
@@ -0,0 +1,56 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<INPUT TYPE="HIDDEN" NAME="DEVICE_URI" VALUE="{device_uri}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Paramètres du port série pour {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Taux de transfert (Baud rate):&nbsp;</TD>
+ <TD><SELECT NAME="BAUDRATE">
+ {[baudrates]<OPTION {?baudrate={baudrates}?SELECTED:}>{baudrates}}
+ </SELECT></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Contrôle de parité:&nbsp;</TD>
+ <TD><SELECT NAME="PARITY">
+ <OPTION VALUE="none" {?parity=none?SELECTED:}>None
+ <OPTION VALUE="even" {?parity=even?SELECTED:}>Even
+ <OPTION VALUE="odd" {?parity=odd?SELECTED:}>Odd
+ </SELECT></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Bits de données (Data bits):&nbsp;</TD>
+ <TD><SELECT NAME="BITS">
+ <OPTION {?bits=8?SELECTED:}>8
+ <OPTION {?bits=7?SELECTED:}>7
+ </SELECT></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Control de flux:&nbsp;</TD>
+ <TD><SELECT NAME="FLOW">
+ <OPTION VALUE="none" {?flow=none?SELECTED:}>None
+ <OPTION VALUE="soft" {?flow=soft?SELECTED:}>XON/XOFF (Software)
+ <OPTION VALUE="hard" {?flow=hard?SELECTED:}>RTS/CTS (Hardware)
+ <OPTION VALUE="dtrdsr" {?flow=dtrdsr?SELECTED:}>DTR/DSR (Hardware)
+ </SELECT></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Suite..." BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/fr/choose-uri.tmpl b/templates/fr/choose-uri.tmpl
new file mode 100644
index 000000000..c2ba8b0c6
--- /dev/null
+++ b/templates/fr/choose-uri.tmpl
@@ -0,0 +1,43 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_LOCATION" VALUE="{?printer_location}">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_INFO" VALUE="{?printer_info}">
+<INPUT TYPE="HIDDEN" NAME="CURRENT_MAKE_AND_MODEL" VALUE="{?current_make_and_model}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">URI de périphérique pour {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">URI de périphérique:&nbsp;</TD>
+ <TD><INPUT TYPE="TEXT" SIZE="40" MAXLENGTH="1024" NAME="DEVICE_URI" VALUE="{device_uri}"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD>Exemples:
+ <PRE>
+ file:/chemin/vers/fichier.prn
+ http://nom_ordinateur:631/ipp/
+ http://nom_ordinateur:631/ipp/port1
+ ipp://nom_ordinateur/ipp/
+ ipp://nom_ordinateur/ipp/port1
+ lpd://nom_ordinateur/queue
+ socket://nom_ordinateur
+ socket://nom_ordinateur:9100
+ </PRE>
+ </TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Suite..." BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/fr/class-added.tmpl b/templates/fr/class-added.tmpl
new file mode 100644
index 000000000..085246915
--- /dev/null
+++ b/templates/fr/class-added.tmpl
@@ -0,0 +1,2 @@
+<P>La classe d'imprimante <A HREF="/classes/{printer_name}">{printer_name}</A>
+a été ajouté avec succès.
diff --git a/templates/fr/class-confirm.tmpl b/templates/fr/class-confirm.tmpl
new file mode 100644
index 000000000..acf0a7f86
--- /dev/null
+++ b/templates/fr/class-confirm.tmpl
@@ -0,0 +1,6 @@
+<P><B>Avertissement:</B> Vous êtes sur le point de supprimer la classe
+ {printer_name}! Voulez-vous continuer ?
+
+<P ALIGN="CENTER">
+<A HREF="/admin/?op=delete-class&printer_name={printer_name}&confirm=yes">
+<IMG SRC="/images/continue.gif" ALT="Suite..." BORDER="0"></A>
diff --git a/templates/fr/class-deleted.tmpl b/templates/fr/class-deleted.tmpl
new file mode 100644
index 000000000..19f6620e5
--- /dev/null
+++ b/templates/fr/class-deleted.tmpl
@@ -0,0 +1 @@
+<P>La classe d'imprimante {printer_name} a été supprimée avec succès.
diff --git a/templates/fr/class-modified.tmpl b/templates/fr/class-modified.tmpl
new file mode 100644
index 000000000..a6f9bec53
--- /dev/null
+++ b/templates/fr/class-modified.tmpl
@@ -0,0 +1,2 @@
+<P>La classe d'imprimantes <A HREF="/classes/{printer_name}">{printer_name}</A>
+a été modifiée avec succès.
diff --git a/templates/fr/classes.tmpl b/templates/fr/classes.tmpl
new file mode 100644
index 000000000..9cd427900
--- /dev/null
+++ b/templates/fr/classes.tmpl
@@ -0,0 +1,51 @@
+{#printer_name=0?Aucune classe d'imprimantes définie:
+<P><B>Destination implicite ("par défaut"):</B> <A HREF="{default_uri}">{default_name}</A>
+<P><TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+{[printer_name]
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966"><A HREF="{printer_uri_supported}">{printer_name}</A></TH>
+ <TH BGCOLOR="#999966">Classes d'imprimantes</TH>
+ <TH><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD VALIGN=TOP><A HREF="{printer_uri_supported}">
+ <IMG SRC="../images/classes.gif" BORDER="0" ALT=""></A></TD>
+ <TD VALIGN=TOP>Description: {printer_info}<BR>
+ Emplacement: {printer_location}<BR>
+ Etat de la classe: {printer_state=3?idle:{printer_state=4?fonctionne:arrêtée}},
+ {printer_is_accepting_jobs=0?rejette travaux:accepte travaux}.
+ {?printer_state_message=?:<BR><I>"{printer_state_message}"</I>}
+ {?member_names=?:<BR>Membres: {member_names}}
+ <P>
+ <A HREF="{printer_uri_supported}?op=print-test-page">
+ <IMG SRC="/images/print-test-page.gif" ALT="Imprimer page de test" BORDER="0"></A>
+ {printer_state=5?
+ <A HREF="/admin/?op=start-printer&printer_name={printer_name}">
+ <IMG SRC="/images/start-class.gif" ALT="Démarrer la classe" BORDER="0"></A>
+ :
+ <A HREF="/admin/?op=stop-printer&printer_name={printer_name}">
+ <IMG SRC="/images/stop-class.gif" ALT="Arrêter la classe" BORDER="0"></A>
+ }
+ {printer_is_accepting_jobs=0?
+ <A HREF="/admin/?op=accept-jobs&printer_name={printer_name}">
+ <IMG SRC="/images/accept-jobs.gif" ALT="Accepter les travaux" BORDER="0"></A>
+ :
+ <A HREF="/admin/?op=reject-jobs&printer_name={printer_name}">
+ <IMG SRC="/images/reject-jobs.gif" ALT="Rejeter les travaux" BORDER="0"></A>
+ }
+ <A HREF="/admin/?op=modify-class&printer_name={printer_name}">
+ <IMG SRC="/images/modify-class.gif" ALT="Modifier la classe" BORDER="0"></A>
+ <A HREF="/admin/?op=delete-class&printer_name={printer_name}">
+ <IMG SRC="/images/delete-class.gif" ALT="Supprimer la classe" BORDER="0"></A>
+ </TD>
+</TR>
+}
+</TABLE>
+}
+<P><A HREF="/admin/?op=add-class">
+<IMG SRC="/images/add-class.gif" ALT="Ajouter une classe" BORDER="0"></A>
diff --git a/templates/fr/config-printer.tmpl b/templates/fr/config-printer.tmpl
new file mode 100644
index 000000000..74d49b667
--- /dev/null
+++ b/templates/fr/config-printer.tmpl
@@ -0,0 +1,6 @@
+<P>Choisissez les options implicites pour {printer_name}.
+
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
diff --git a/templates/fr/config-printer2.tmpl b/templates/fr/config-printer2.tmpl
new file mode 100644
index 000000000..bfb42d69f
--- /dev/null
+++ b/templates/fr/config-printer2.tmpl
@@ -0,0 +1,2 @@
+</TABLE>
+</FORM>
diff --git a/templates/fr/error.tmpl b/templates/fr/error.tmpl
new file mode 100644
index 000000000..b38d2b4bb
--- /dev/null
+++ b/templates/fr/error.tmpl
@@ -0,0 +1,3 @@
+<P>Erreur:
+
+<BLOCKQUOTE>{error}</BLOCKQUOTE>
diff --git a/templates/fr/header.tmpl b/templates/fr/header.tmpl
new file mode 100644
index 000000000..14dbbd2eb
--- /dev/null
+++ b/templates/fr/header.tmpl
@@ -0,0 +1,23 @@
+<HTML>
+<HEAD>
+ <TITLE>{title} sur {server_name} - {cups_version}</TITLE>
+ <!-- Prevent caching of CGI content -->
+ <META HTTP-EQUIV="Expires" CONTENT="now">
+ <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
+ <LINK REL="STYLESHEET" TYPE="text/css" HREF="/cups.css">
+ <MAP NAME="navbar">
+ <AREA SHAPE="RECT" COORDS="14,8,50,22" HREF="http://www.easysw.com" ALT="Page d'accueil Easy Software Products">
+ <AREA SHAPE="RECT" COORDS="76,8,182,22" HREF="admin" ALT="Tâches d'administration">
+ <AREA SHAPE="RECT" COORDS="202,8,260,22" HREF="classes" ALT="Etat des classes d'imprimantes">
+ <AREA SHAPE="RECT" COORDS="280,8,316,22" HREF="documentation.html" ALT="Aide électronique en ligne">
+ <AREA SHAPE="RECT" COORDS="334,8,394,22" HREF="jobs" ALT="Etat des travaux d'impression">
+ <AREA SHAPE="RECT" COORDS="416,8,506,22" HREF="printers" ALT="Etat des imprimantes">
+ <AREA SHAPE="RECT" COORDS="526,8,582,22" HREF="http://www.cups.org" ALT="Télécharger la dernière version du logiciel CUPS">
+ </MAP>
+</HEAD>
+<BODY BGCOLOR="#cccc99" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF">
+<CENTER>
+<IMG SRC="/images/navbar.gif" WIDTH="596" HEIGHT="28" USEMAP="#navbar" BORDER="0" ALT="Common UNIX Printing System">
+</CENTER>
+
+<H1>{title}</H1>
diff --git a/templates/fr/job-cancel.tmpl b/templates/fr/job-cancel.tmpl
new file mode 100644
index 000000000..018450742
--- /dev/null
+++ b/templates/fr/job-cancel.tmpl
@@ -0,0 +1 @@
+<P><A HREF="{job_printer_uri}">Le travail d'impression {job_id}</A> a été annulé.
diff --git a/templates/fr/job-hold.tmpl b/templates/fr/job-hold.tmpl
new file mode 100644
index 000000000..13c8c49ac
--- /dev/null
+++ b/templates/fr/job-hold.tmpl
@@ -0,0 +1 @@
+<P><A HREF="{job_printer_uri}">L'impression du travail {job_id}</A> a été retenue.
diff --git a/templates/fr/job-op.tmpl b/templates/fr/job-op.tmpl
new file mode 100644
index 000000000..a82aa033a
--- /dev/null
+++ b/templates/fr/job-op.tmpl
@@ -0,0 +1 @@
+<P>Opération "{op}" non prise en charge pour les travaux d'impression.
diff --git a/templates/fr/job-release.tmpl b/templates/fr/job-release.tmpl
new file mode 100644
index 000000000..c49fab0ce
--- /dev/null
+++ b/templates/fr/job-release.tmpl
@@ -0,0 +1,2 @@
+<P><A HREF="{job_printer_uri}">L'impression du travail {job_id}</A>
+a été libérée.
diff --git a/templates/fr/job-restart.tmpl b/templates/fr/job-restart.tmpl
new file mode 100644
index 000000000..7638216da
--- /dev/null
+++ b/templates/fr/job-restart.tmpl
@@ -0,0 +1 @@
+<P><A HREF="{job_printer_uri}">Le travail d'impression {job_id}</A> a été relancé.
diff --git a/templates/fr/jobs.tmpl b/templates/fr/jobs.tmpl
new file mode 100644
index 000000000..5f8a29b19
--- /dev/null
+++ b/templates/fr/jobs.tmpl
@@ -0,0 +1,54 @@
+<P>{#job_id=0?Pas de travaux {?which_jobs=completed?complétés:actifs}:
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH>N°&nbsp;</TH>
+ <TH>Nom&nbsp;</TH>
+ <TH>Utilisateur&nbsp;</TH>
+ <TH>Taille&nbsp;</TH>
+ <TH>Etat&nbsp;</TH>
+ <TH>Contrôle&nbsp;</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+{[job_id]
+<TR VALIGN="TOP">
+ <TD HEIGHT="28"></TD>
+ <TD><A HREF="{job_printer_uri}">{job_printer_name}</A>-{job_id}&nbsp;</TD>
+ <TD>{?job_name=?Inconnu:{job_name}}&nbsp;</TD>
+ <TD>{job_originating_user_name}&nbsp;</TD>
+ <TD>{job_k_octets}k&nbsp;</TD>
+ <TD>{job_state=3?En attente depuis<BR>{time_at_creation}:{job_state=4?held since<BR>{time_at_creation}:
+ {job_state=5?En cours de traitement depuis<BR>{time_at_processing}:{job_state=6?stopped at<BR>{time_at_completed}:
+ {job_state=7?Annulé depuis<BR>{time_at_completed}:{job_state=8?Abandonné à:Complété à<BR>{time_at_completed}}}}}}}&nbsp;</TD>
+ <TD>
+ {job_state>5?
+ {job_k_octets>0?
+ <A HREF="/jobs/?op=restart-job&job_id={job_id}&job_printer_uri={job_printer_uri}">
+ <IMG SRC="/images/restart-job.gif" ALT="Restart Job" BORDER="0"></A>
+ :}:}
+ {job_state>6?:
+ {job_state=4?
+ <A HREF="/jobs/?op=release-job&job_id={job_id}&job_printer_uri={job_printer_uri}">
+ <IMG SRC="/images/release-job.gif" ALT="Release Job" BORDER="0"></A>
+ :
+ <A HREF="/jobs/?op=hold-job&job_id={job_id}&job_printer_uri={job_printer_uri}">
+ <IMG SRC="/images/hold-job.gif" ALT="Hold Job" BORDER="0"></A>
+ }
+ <A HREF="/jobs/?op=cancel-job&job_id={job_id}&job_printer_uri={job_printer_uri}">
+ <IMG SRC="/images/cancel-job.gif" ALT="Cancel Job" BORDER="0"></A>
+ }
+ &nbsp;</TD>
+</TR>
+}
+</TABLE>
+}
+<P>{?which_jobs=?
+<A HREF="{?printer_name=?/jobs:/printers/{printer_name}}?which_jobs=completed">
+<IMG SRC="/images/show-completed.gif" BORDER="0" ALT="Show Completed Jobs"></A>
+:
+<A HREF="{?printer_name=?/jobs:/printers/{printer_name}}">
+<IMG SRC="/images/show-active.gif" BORDER="0" ALT="Show Active Jobs"></A>
+}
diff --git a/templates/fr/modify-class.tmpl b/templates/fr/modify-class.tmpl
new file mode 100644
index 000000000..493267420
--- /dev/null
+++ b/templates/fr/modify-class.tmpl
@@ -0,0 +1,34 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Modifier la classe d'imprimante {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Nom:</TD>
+ <TD><INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+ {printer_name}</TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Emplacement:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_LOCATION" VALUE="{?printer_location}" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Description:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" VALUE="{?printer_info}" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Suite..." BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/fr/modify-printer.tmpl b/templates/fr/modify-printer.tmpl
new file mode 100644
index 000000000..0278029b2
--- /dev/null
+++ b/templates/fr/modify-printer.tmpl
@@ -0,0 +1,36 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+{?device_uri=?:<INPUT TYPE="HIDDEN" NAME="CURRENT_DEVICE_URI" VALUE="{device_uri}">}
+{?printer_make_and_model=?:<INPUT TYPE="HIDDEN" NAME="CURRENT_MAKE_AND_MODEL" VALUE="{printer_make_and_model}">}
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Modifier l'imprimante {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Nom:</TD>
+ <TD><INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+ {printer_name}</TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Emplacement:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_LOCATION" VALUE="{?printer_location}" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Description:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" VALUE="{?printer_info}" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Suite..." BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/fr/option-boolean.tmpl b/templates/fr/option-boolean.tmpl
new file mode 100644
index 000000000..a8360fc82
--- /dev/null
+++ b/templates/fr/option-boolean.tmpl
@@ -0,0 +1,7 @@
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">{keytext}:</TD>
+ <TD>
+ {[choices]<INPUT TYPE="RADIO" NAME="{keyword}" {choices={defchoice}?CHECKED:} VALUE="{choices}">{text}}
+ </TD>
+</TR>
diff --git a/templates/fr/option-header.tmpl b/templates/fr/option-header.tmpl
new file mode 100644
index 000000000..23a904178
--- /dev/null
+++ b/templates/fr/option-header.tmpl
@@ -0,0 +1,8 @@
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966" COLSPAN="2">{group}</TH>
+ <TH><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
diff --git a/templates/fr/option-pickmany.tmpl b/templates/fr/option-pickmany.tmpl
new file mode 100644
index 000000000..8340889b4
--- /dev/null
+++ b/templates/fr/option-pickmany.tmpl
@@ -0,0 +1,7 @@
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT" VALIGN="TOP">{keytext}:</TD>
+ <TD><SELECT NAME="{keyword}" MULTIPLE SIZE="10">
+ {[choices]<OPTION {choices={defchoice}?SELECTED:} VALUE="{choices}">{text}}
+ </SELECT></TD>
+</TR>
diff --git a/templates/fr/option-pickone.tmpl b/templates/fr/option-pickone.tmpl
new file mode 100644
index 000000000..6880b968b
--- /dev/null
+++ b/templates/fr/option-pickone.tmpl
@@ -0,0 +1,7 @@
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">{keytext}:</TD>
+ <TD><SELECT NAME="{keyword}">
+ {[choices]<OPTION {choices={defchoice}?SELECTED:} VALUE="{choices}">{text}}
+ </SELECT></TD>
+</TR>
diff --git a/templates/fr/option-trailer.tmpl b/templates/fr/option-trailer.tmpl
new file mode 100644
index 000000000..d88956679
--- /dev/null
+++ b/templates/fr/option-trailer.tmpl
@@ -0,0 +1,8 @@
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Suite..." BORDER="0"></TD>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
diff --git a/templates/fr/printer-accept.tmpl b/templates/fr/printer-accept.tmpl
new file mode 100644
index 000000000..c832849bb
--- /dev/null
+++ b/templates/fr/printer-accept.tmpl
@@ -0,0 +1,2 @@
+<P>L'imprimante <A HREF="/printers/{printer_name}">{printer_name}</A>
+accepte désormais les travaux d'impression.
diff --git a/templates/fr/printer-added.tmpl b/templates/fr/printer-added.tmpl
new file mode 100644
index 000000000..8f460b7d6
--- /dev/null
+++ b/templates/fr/printer-added.tmpl
@@ -0,0 +1 @@
+<P>L'imprimante <A HREF="/printers/{printer_name}">{printer_name}</A> a été ajoutée avec succès.
diff --git a/templates/fr/printer-configured.tmpl b/templates/fr/printer-configured.tmpl
new file mode 100644
index 000000000..10dcb8f61
--- /dev/null
+++ b/templates/fr/printer-configured.tmpl
@@ -0,0 +1,2 @@
+<P>L'imprimante <A HREF="/printers/{printer_name}">{printer_name}</A>
+a été configurée avec succès.
diff --git a/templates/fr/printer-confirm.tmpl b/templates/fr/printer-confirm.tmpl
new file mode 100644
index 000000000..c8dc1ec49
--- /dev/null
+++ b/templates/fr/printer-confirm.tmpl
@@ -0,0 +1,6 @@
+<P><B>Avertissement:</B> Vous êtes sur le point de supprimer l'imprimante {printer_name}!
+Voulez-vous continuer?
+
+<P ALIGN="CENTER">
+<A HREF="/admin/?op=delete-printer&printer_name={printer_name}&confirm=yes">
+<IMG SRC="/images/continue.gif" ALT="Suite..." BORDER="0"></A>
diff --git a/templates/fr/printer-deleted.tmpl b/templates/fr/printer-deleted.tmpl
new file mode 100644
index 000000000..521be9c16
--- /dev/null
+++ b/templates/fr/printer-deleted.tmpl
@@ -0,0 +1 @@
+<P>L'imprimante {printer_name} a été supprimée avec succès.
diff --git a/templates/fr/printer-modified.tmpl b/templates/fr/printer-modified.tmpl
new file mode 100644
index 000000000..f74d08879
--- /dev/null
+++ b/templates/fr/printer-modified.tmpl
@@ -0,0 +1 @@
+<P>L'imprimante <A HREF="/printers/{printer_name}">{printer_name}</A> a été modifiée avec succès.
diff --git a/templates/fr/printer-purge.tmpl b/templates/fr/printer-purge.tmpl
new file mode 100644
index 000000000..a2a91cedf
--- /dev/null
+++ b/templates/fr/printer-purge.tmpl
@@ -0,0 +1 @@
+<P>L'imprimante <A HREF="/printers/{printer_name}">{printer_name}</A> a été purgée de tous ses travaux d'impression.
diff --git a/templates/fr/printer-reject.tmpl b/templates/fr/printer-reject.tmpl
new file mode 100644
index 000000000..c68dd42e5
--- /dev/null
+++ b/templates/fr/printer-reject.tmpl
@@ -0,0 +1 @@
+<P>L'imprimante <A HREF="/printers/{printer_name}">{printer_name}</A> n'accepte désormais plus de travaux d'impression.
diff --git a/templates/fr/printer-start.tmpl b/templates/fr/printer-start.tmpl
new file mode 100644
index 000000000..e4a6089a8
--- /dev/null
+++ b/templates/fr/printer-start.tmpl
@@ -0,0 +1 @@
+<P>L'imprimante <A HREF="/printers/{printer_name}">{printer_name}</A> a été démarrée.
diff --git a/templates/fr/printer-stop.tmpl b/templates/fr/printer-stop.tmpl
new file mode 100644
index 000000000..7d9aeb6bb
--- /dev/null
+++ b/templates/fr/printer-stop.tmpl
@@ -0,0 +1 @@
+<P>L'imprimante <A HREF="/printers/{printer_name}">{printer_name}</A> a été arrêtée.
diff --git a/templates/fr/printers.tmpl b/templates/fr/printers.tmpl
new file mode 100644
index 000000000..bc4cf8674
--- /dev/null
+++ b/templates/fr/printers.tmpl
@@ -0,0 +1,57 @@
+{#printer_name=0?Aucune imprimante définie:
+<P><B>Destination d'impression implicite :</B> <A HREF="{default_uri}">{default_name}</A>
+<P><TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+{[printer_name]
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966"><A HREF="{printer_uri_supported}">{printer_name}</A></TH>
+ <TH BGCOLOR="#999966">{printer_make_and_model}</TH>
+ <TH><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD VALIGN="TOP"><A HREF="{printer_uri_supported}">
+ <IMG SRC="../images/printer-{printer_state=3?idle:{printer_state=4?processing:stopped}}.gif" BORDER="0" ALT=""></A>
+ </TD>
+ <TD VALIGN="TOP">Description: {printer_info}<BR>
+ Emplacement: {printer_location}<BR>
+ Etat de l'imprimante: {printer_state=3?au repos:{printer_state=4?fonctionne:arrêtée}},
+ {printer_is_accepting_jobs=0?rejette les travaux:accepte les travaux}.
+ {?printer_state_message=?:<BR><I>"{printer_state_message}"</I>}
+ {?device_uri=?:<BR>URI de périphérique: {device_uri}}
+ <P>
+ <A HREF="{printer_uri_supported}?op=print-test-page">
+ <IMG SRC="/images/print-test-page.gif" ALT="Imprimer une page de test" BORDER="0"></A>
+ {printer_state=5?
+ <A HREF="/admin/?op=start-printer&printer_name={printer_name}">
+ <IMG SRC="/images/start-printer.gif" ALT="Démarrer l'imprimante" BORDER="0"></A>
+ :
+ <A HREF="/admin/?op=stop-printer&printer_name={printer_name}">
+ <IMG SRC="/images/stop-printer.gif" ALT="Arrêter l'imprimante" BORDER="0"></A>
+ }
+ {printer_is_accepting_jobs=0?
+ <A HREF="/admin/?op=accept-jobs&printer_name={printer_name}">
+ <IMG SRC="/images/accept-jobs.gif" ALT="Accepter les travaux d'impression" BORDER="0"></A>
+ :
+ <A HREF="/admin/?op=reject-jobs&printer_name={printer_name}">
+ <IMG SRC="/images/reject-jobs.gif" ALT="Rejeter les travaux d'impression" BORDER="0"></A>
+ }
+ <A HREF="/admin/?op=modify-printer&printer_name={printer_name}">
+ <IMG SRC="/images/modify-printer.gif" ALT="Modifier l'imprimante" BORDER="0"></A>
+ <A HREF="/admin/?op=config-printer&printer_name={printer_name}">
+ <IMG SRC="/images/config-printer.gif" ALT="Configurer l'imprimante" BORDER="0"></A>
+ <A HREF="/admin/?op=delete-printer&printer_name={printer_name}">
+ <IMG SRC="/images/delete-printer.gif" ALT="Supprimer l'imprimante" BORDER="0"></A>
+ </TD>
+</TR>
+<TR>
+ <TD>&nbsp;</TD>
+</TR>
+}
+</TABLE>
+}
+<P><A HREF="/admin/?op=add-printer">
+<IMG SRC="/images/add-printer.gif" ALT="Ajouter une imprimante" BORDER="0"></A>
diff --git a/templates/fr/test-page.tmpl b/templates/fr/test-page.tmpl
new file mode 100644
index 000000000..69437e6c0
--- /dev/null
+++ b/templates/fr/test-page.tmpl
@@ -0,0 +1,2 @@
+<P>Page de test envoyée; Le n° d'identification du travail d'impression est <A HREF="/printers/{printer_name}">
+{printer_name}-{job_id}</A>.
diff --git a/templates/fr/trailer.tmpl b/templates/fr/trailer.tmpl
new file mode 100644
index 000000000..f6444836b
--- /dev/null
+++ b/templates/fr/trailer.tmpl
@@ -0,0 +1,7 @@
+<HR>
+<P>Copyright 1993-2002 Easy Software Products, Tous droits réservés.
+Common UNIX Printing System, CUPS, et le logo CUPS
+sont des marques déposées de <A HREF="http://www.easysw.com">Easy Software Products</A>.
+Toutes les autres marques déposées appartiennent à leurs propriétaires respectifs.
+</BODY>
+</HTML>
diff --git a/templates/header.tmpl b/templates/header.tmpl
new file mode 100644
index 000000000..b22bc73f0
--- /dev/null
+++ b/templates/header.tmpl
@@ -0,0 +1,23 @@
+<HTML>
+<HEAD>
+ <TITLE>{title} on {server_name} - {cups_version}</TITLE>
+ <!-- Prevent caching of CGI content -->
+ <META HTTP-EQUIV="Expires" CONTENT="now">
+ <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
+ <LINK REL="STYLESHEET" TYPE="text/css" HREF="/cups.css">
+ <MAP NAME="navbar">
+ <AREA SHAPE="RECT" COORDS="12,0,50,30" HREF="http://www.easysw.com" ALT="Easy Software Products Home Page">
+ <AREA SHAPE="RECT" COORDS="82,0,196,30" HREF="/admin" ALT="Do Administration Tasks">
+ <AREA SHAPE="RECT" COORDS="216,0,280,30" HREF="/classes" ALT="Manage Printer Classes Status">
+ <AREA SHAPE="RECT" COORDS="300,0,336,30" HREF="/documentation.html" ALT="On-Line Help">
+ <AREA SHAPE="RECT" COORDS="356,0,394,30" HREF="/jobs" ALT="Manage Jobs">
+ <AREA SHAPE="RECT" COORDS="414,0,476,30" HREF="/printers" ALT="Manage Printers">
+ <AREA SHAPE="RECT" COORDS="496,0,568,30" HREF="http://www.cups.org" ALT="Download the Current CUPS Software">
+ </MAP>
+</HEAD>
+<BODY BGCOLOR="#cccc99" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF">
+<CENTER>
+<IMG SRC="/images/navbar.gif" WIDTH="583" HEIGHT="30" USEMAP="#navbar" BORDER="0" ALT="Common UNIX Printing System">
+</CENTER>
+
+<H1>{title}</H1>
diff --git a/templates/job-cancel.tmpl b/templates/job-cancel.tmpl
new file mode 100644
index 000000000..fbdda31dd
--- /dev/null
+++ b/templates/job-cancel.tmpl
@@ -0,0 +1 @@
+<P><A HREF="{job_printer_uri}">Job {job_id}</A> has been cancelled.
diff --git a/templates/job-hold.tmpl b/templates/job-hold.tmpl
new file mode 100644
index 000000000..3e391543b
--- /dev/null
+++ b/templates/job-hold.tmpl
@@ -0,0 +1 @@
+<P><A HREF="{job_printer_uri}">Job {job_id}</A> has been held from printing.
diff --git a/templates/job-op.tmpl b/templates/job-op.tmpl
new file mode 100644
index 000000000..19520367f
--- /dev/null
+++ b/templates/job-op.tmpl
@@ -0,0 +1 @@
+<P>Unsupported job operation "{op}".
diff --git a/templates/job-release.tmpl b/templates/job-release.tmpl
new file mode 100644
index 000000000..d04622353
--- /dev/null
+++ b/templates/job-release.tmpl
@@ -0,0 +1 @@
+<P><A HREF="{job_printer_uri}">Job {job_id}</A> has been released for printing.
diff --git a/templates/job-restart.tmpl b/templates/job-restart.tmpl
new file mode 100644
index 000000000..d575c47a7
--- /dev/null
+++ b/templates/job-restart.tmpl
@@ -0,0 +1 @@
+<P><A HREF="{job_printer_uri}">Job {job_id}</A> has been restarted.
diff --git a/templates/jobs.tmpl b/templates/jobs.tmpl
new file mode 100644
index 000000000..cf61c7bfe
--- /dev/null
+++ b/templates/jobs.tmpl
@@ -0,0 +1,54 @@
+<P>{#job_id=0?No {?which_jobs=completed?Completed:Active} Jobs:
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH>ID&nbsp;</TH>
+ <TH>Name&nbsp;</TH>
+ <TH>User&nbsp;</TH>
+ <TH>Size&nbsp;</TH>
+ <TH>State&nbsp;</TH>
+ <TH>Control&nbsp;</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+{[job_id]
+<TR VALIGN="TOP">
+ <TD HEIGHT="28"></TD>
+ <TD><A HREF="{job_printer_uri}">{job_printer_name}</A>-{job_id}&nbsp;</TD>
+ <TD>{?job_name=?Unknown:{job_name}}&nbsp;</TD>
+ <TD>{job_originating_user_name}&nbsp;</TD>
+ <TD>{job_k_octets}k&nbsp;</TD>
+ <TD>{job_state=3?pending since<BR>{time_at_creation}:{job_state=4?held since<BR>{time_at_creation}:
+ {job_state=5?processing since<BR>{time_at_processing}:{job_state=6?stopped at<BR>{time_at_completed}:
+ {job_state=7?cancelled at<BR>{time_at_completed}:{job_state=8?aborted:completed at<BR>{time_at_completed}}}}}}}&nbsp;</TD>
+ <TD>
+ {job_state>5?
+ {job_k_octets>0?
+ <A HREF="/jobs/?op=restart-job&job_id={job_id}&job_printer_uri={job_printer_uri}">
+ <IMG SRC="/images/restart-job.gif" ALT="Restart Job" BORDER="0"></A>
+ :}:}
+ {job_state>6?:
+ {job_state=4?
+ <A HREF="/jobs/?op=release-job&job_id={job_id}&job_printer_uri={job_printer_uri}">
+ <IMG SRC="/images/release-job.gif" ALT="Release Job" BORDER="0"></A>
+ :
+ <A HREF="/jobs/?op=hold-job&job_id={job_id}&job_printer_uri={job_printer_uri}">
+ <IMG SRC="/images/hold-job.gif" ALT="Hold Job" BORDER="0"></A>
+ }
+ <A HREF="/jobs/?op=cancel-job&job_id={job_id}&job_printer_uri={job_printer_uri}">
+ <IMG SRC="/images/cancel-job.gif" ALT="Cancel Job" BORDER="0"></A>
+ }
+ &nbsp;</TD>
+</TR>
+}
+</TABLE>
+}
+<P>{?which_jobs=?
+<A HREF="{?printer_name=?/jobs:/printers/{printer_name}}?which_jobs=completed">
+<IMG SRC="/images/show-completed.gif" BORDER="0" ALT="Show Completed Jobs"></A>
+:
+<A HREF="{?printer_name=?/jobs:/printers/{printer_name}}">
+<IMG SRC="/images/show-active.gif" BORDER="0" ALT="Show Active Jobs"></A>
+}
diff --git a/templates/modify-class.tmpl b/templates/modify-class.tmpl
new file mode 100644
index 000000000..17aeedbba
--- /dev/null
+++ b/templates/modify-class.tmpl
@@ -0,0 +1,34 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Modify Class {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Name:</TD>
+ <TD><INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+ {printer_name}</TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Location:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_LOCATION" VALUE="{?printer_location}" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Description:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" VALUE="{?printer_info}" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/modify-printer.tmpl b/templates/modify-printer.tmpl
new file mode 100644
index 000000000..68e36cd8e
--- /dev/null
+++ b/templates/modify-printer.tmpl
@@ -0,0 +1,36 @@
+<FORM METHOD="POST" ACTION="/admin">
+<INPUT TYPE="HIDDEN" NAME="OP" VALUE="{op}">
+{?device_uri=?:<INPUT TYPE="HIDDEN" NAME="CURRENT_DEVICE_URI" VALUE="{device_uri}">}
+{?printer_make_and_model=?:<INPUT TYPE="HIDDEN" NAME="CURRENT_MAKE_AND_MODEL" VALUE="{printer_make_and_model}">}
+<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+<TR BGCOLOR="#999966">
+ <TH WIDTH="16"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH COLSPAN="2">Modify Printer {printer_name}</TH>
+ <TH BGCOLOR="#cccc99" WIDTH="16"><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Name:</TD>
+ <TD><INPUT TYPE="HIDDEN" NAME="PRINTER_NAME" VALUE="{printer_name}">
+ {printer_name}</TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Location:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_LOCATION" VALUE="{?printer_location}" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">Description:</TD>
+ <TD><INPUT TYPE="TEXT" NAME="PRINTER_INFO" VALUE="{?printer_info}" SIZE="40" MAXLENGTH="127"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+</TABLE>
+</FORM>
diff --git a/templates/option-boolean.tmpl b/templates/option-boolean.tmpl
new file mode 100644
index 000000000..9aca916e1
--- /dev/null
+++ b/templates/option-boolean.tmpl
@@ -0,0 +1,7 @@
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">{conflicted=1?<FONT COLOR="#ff0000"><B>:}<A NAME="{keyword}">{keytext}</A>:{conflicted=1?<BR>(conflicting)</B></FONT>:}</TD>
+ <TD>
+ {[choices]<INPUT TYPE="RADIO" NAME="{keyword}" {choices={defchoice}?CHECKED:} VALUE="{choices}">{text}}
+ </TD>
+</TR>
diff --git a/templates/option-conflict.tmpl b/templates/option-conflict.tmpl
new file mode 100644
index 000000000..eb5058c39
--- /dev/null
+++ b/templates/option-conflict.tmpl
@@ -0,0 +1,7 @@
+<P><B>Error:</B> The following options are conflicting:</P>
+
+<UL>
+{[ckeyword]<LI><A HREF="#{ckeyword}">{ckeytext}</A></LI>
+}</UL>
+
+<P>Please change one or more of the options to resolve the conflicts.
diff --git a/templates/option-header.tmpl b/templates/option-header.tmpl
new file mode 100644
index 000000000..23a904178
--- /dev/null
+++ b/templates/option-header.tmpl
@@ -0,0 +1,8 @@
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966" COLSPAN="2">{group}</TH>
+ <TH><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
diff --git a/templates/option-pickmany.tmpl b/templates/option-pickmany.tmpl
new file mode 100644
index 000000000..531b9bd6a
--- /dev/null
+++ b/templates/option-pickmany.tmpl
@@ -0,0 +1,7 @@
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">{conflicted=1?<FONT COLOR="#ff0000"><B>:}<A NAME="{keyword}">{keytext}</A>:{conflicted=1?<BR>(conflicting)</B></FONT>:}</TD>
+ <TD><SELECT NAME="{keyword}" MULTIPLE SIZE="10">
+ {[choices]<OPTION {choices={defchoice}?SELECTED:} VALUE="{choices}">{text}}
+ </SELECT></TD>
+</TR>
diff --git a/templates/option-pickone.tmpl b/templates/option-pickone.tmpl
new file mode 100644
index 000000000..7e99eb4c8
--- /dev/null
+++ b/templates/option-pickone.tmpl
@@ -0,0 +1,7 @@
+<TR>
+ <TD></TD>
+ <TD ALIGN="RIGHT">{conflicted=1?<FONT COLOR="#ff0000"><B>:}<A NAME="{keyword}">{keytext}</A>:{conflicted=1?<BR>(conflicting)</B></FONT>:}</TD>
+ <TD><SELECT NAME="{keyword}">
+ {[choices]<OPTION {choices={defchoice}?SELECTED:} VALUE="{choices}">{text}}
+ </SELECT></TD>
+</TR>
diff --git a/templates/option-trailer.tmpl b/templates/option-trailer.tmpl
new file mode 100644
index 000000000..803022837
--- /dev/null
+++ b/templates/option-trailer.tmpl
@@ -0,0 +1,8 @@
+<TR>
+ <TD></TD>
+ <TD></TD>
+ <TD><INPUT TYPE="IMAGE" SRC="/images/continue.gif" ALT="Continue" BORDER="0"></TD>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
diff --git a/templates/printer-accept.tmpl b/templates/printer-accept.tmpl
new file mode 100644
index 000000000..3a269eb0d
--- /dev/null
+++ b/templates/printer-accept.tmpl
@@ -0,0 +1 @@
+<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> is now accepting jobs.
diff --git a/templates/printer-added.tmpl b/templates/printer-added.tmpl
new file mode 100644
index 000000000..ba5f550c2
--- /dev/null
+++ b/templates/printer-added.tmpl
@@ -0,0 +1,2 @@
+<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> has been added
+successfully.
diff --git a/templates/printer-configured.tmpl b/templates/printer-configured.tmpl
new file mode 100644
index 000000000..7ec86879a
--- /dev/null
+++ b/templates/printer-configured.tmpl
@@ -0,0 +1,2 @@
+<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> has
+been configured successfully.
diff --git a/templates/printer-confirm.tmpl b/templates/printer-confirm.tmpl
new file mode 100644
index 000000000..690c6479b
--- /dev/null
+++ b/templates/printer-confirm.tmpl
@@ -0,0 +1,6 @@
+<P><B>Warning:</B> About to delete printer {printer_name}! Do you wish to
+continue?
+
+<P ALIGN="CENTER">
+<A HREF="/admin/?op=delete-printer&printer_name={printer_name}&confirm=yes">
+<IMG SRC="/images/continue.gif" ALT="Continue" BORDER="0"></A>
diff --git a/templates/printer-deleted.tmpl b/templates/printer-deleted.tmpl
new file mode 100644
index 000000000..f1336b037
--- /dev/null
+++ b/templates/printer-deleted.tmpl
@@ -0,0 +1 @@
+<P>Printer {printer_name} has been deleted successfully.
diff --git a/templates/printer-modified.tmpl b/templates/printer-modified.tmpl
new file mode 100644
index 000000000..a16abd169
--- /dev/null
+++ b/templates/printer-modified.tmpl
@@ -0,0 +1,2 @@
+<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> has been
+modified successfully.
diff --git a/templates/printer-purge.tmpl b/templates/printer-purge.tmpl
new file mode 100644
index 000000000..863d33916
--- /dev/null
+++ b/templates/printer-purge.tmpl
@@ -0,0 +1 @@
+<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> has been purged of all jobs.
diff --git a/templates/printer-reject.tmpl b/templates/printer-reject.tmpl
new file mode 100644
index 000000000..e73d87380
--- /dev/null
+++ b/templates/printer-reject.tmpl
@@ -0,0 +1 @@
+<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> is no longer accepting jobs.
diff --git a/templates/printer-start.tmpl b/templates/printer-start.tmpl
new file mode 100644
index 000000000..e8d9f497f
--- /dev/null
+++ b/templates/printer-start.tmpl
@@ -0,0 +1,2 @@
+<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> has been
+started.
diff --git a/templates/printer-stop.tmpl b/templates/printer-stop.tmpl
new file mode 100644
index 000000000..e01b82677
--- /dev/null
+++ b/templates/printer-stop.tmpl
@@ -0,0 +1,2 @@
+<P>Printer <A HREF="/printers/{printer_name}">{printer_name}</A> has been
+stopped.
diff --git a/templates/printers.tmpl b/templates/printers.tmpl
new file mode 100644
index 000000000..1505c36ba
--- /dev/null
+++ b/templates/printers.tmpl
@@ -0,0 +1,57 @@
+{#printer_name=0?No printers:
+<P><B>Default Destination:</B> <A HREF="{default_uri}">{default_name}</A>
+<P><TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+{[printer_name]
+<TR>
+ <TH BGCOLOR="#999966"><IMG SRC="/images/left.gif" ALT=""></TH>
+ <TH BGCOLOR="#999966"><A HREF="{printer_uri_supported}">{printer_name}</A></TH>
+ <TH BGCOLOR="#999966">{printer_make_and_model}</TH>
+ <TH><IMG SRC="/images/right.gif" ALT=""></TH>
+</TR>
+<TR>
+ <TD HEIGHT="4"></TD>
+</TR>
+<TR>
+ <TD></TD>
+ <TD VALIGN="TOP"><A HREF="{printer_uri_supported}">
+ <IMG SRC="../images/printer-{printer_state=3?idle:{printer_state=4?processing:stopped}}.gif" BORDER="0" ALT=""></A>
+ </TD>
+ <TD VALIGN="TOP">Description: {printer_info}<BR>
+ Location: {printer_location}<BR>
+ Printer State: {printer_state=3?idle:{printer_state=4?processing:stopped}},
+ {printer_is_accepting_jobs=0?rejecting jobs:accepting jobs}.
+ {?printer_state_message=?:<BR><I>"{printer_state_message}"</I>}
+ {?device_uri=?:<BR>Device URI: {device_uri}}
+ <P>
+ <A HREF="{printer_uri_supported}?op=print-test-page">
+ <IMG SRC="/images/print-test-page.gif" ALT="Print Test Page" BORDER="0"></A>
+ {printer_state=5?
+ <A HREF="/admin/?op=start-printer&printer_name={printer_name}">
+ <IMG SRC="/images/start-printer.gif" ALT="Start Printer" BORDER="0"></A>
+ :
+ <A HREF="/admin/?op=stop-printer&printer_name={printer_name}">
+ <IMG SRC="/images/stop-printer.gif" ALT="Stop Printer" BORDER="0"></A>
+ }
+ {printer_is_accepting_jobs=0?
+ <A HREF="/admin/?op=accept-jobs&printer_name={printer_name}">
+ <IMG SRC="/images/accept-jobs.gif" ALT="Accept Jobs" BORDER="0"></A>
+ :
+ <A HREF="/admin/?op=reject-jobs&printer_name={printer_name}">
+ <IMG SRC="/images/reject-jobs.gif" ALT="Reject Jobs" BORDER="0"></A>
+ }
+ <A HREF="/admin/?op=modify-printer&printer_name={printer_name}">
+ <IMG SRC="/images/modify-printer.gif" ALT="Modify Printer" BORDER="0"></A>
+ <A HREF="/admin/?op=config-printer&printer_name={printer_name}">
+ <IMG SRC="/images/config-printer.gif" ALT="Configure Printer" BORDER="0"></A>
+ <A HREF="/admin/?op=delete-printer&printer_name={printer_name}">
+ <IMG SRC="/images/delete-printer.gif" ALT="Delete Printer" BORDER="0"></A>
+ </TD>
+</TR>
+<TR>
+ <TD>&nbsp;</TD>
+</TR>
+}
+</TABLE>
+}
+<P><A HREF="/admin/?op=add-printer">
+<IMG SRC="/images/add-printer.gif" ALT="Add Printer" BORDER="0"></A>
diff --git a/templates/test-page.tmpl b/templates/test-page.tmpl
new file mode 100644
index 000000000..5c5005438
--- /dev/null
+++ b/templates/test-page.tmpl
@@ -0,0 +1,2 @@
+<P>Test page sent; job ID is <A HREF="/printers/{printer_name}">
+{printer_name}-{job_id}</A>.
diff --git a/templates/trailer.tmpl b/templates/trailer.tmpl
new file mode 100644
index 000000000..bed0ed13c
--- /dev/null
+++ b/templates/trailer.tmpl
@@ -0,0 +1,7 @@
+<HR>
+<P>Copyright 1993-2002 Easy Software Products, All Rights Reserved.
+The Common UNIX Printing System, CUPS, and the CUPS logo
+are the trademark property of <A HREF="http://www.easysw.com">Easy Software Products</A>.
+All other trademarks are the property of their respective owners.
+</BODY>
+</HTML>
diff --git a/test/.cvsignore b/test/.cvsignore
new file mode 100644
index 000000000..07b5722d6
--- /dev/null
+++ b/test/.cvsignore
@@ -0,0 +1 @@
+ipptest
diff --git a/test/4.1-requests.test b/test/4.1-requests.test
new file mode 100644
index 000000000..ca0c8d326
--- /dev/null
+++ b/test/4.1-requests.test
@@ -0,0 +1,140 @@
+#
+# "$Id: 4.1-requests.test 1595 2001-03-01 20:40:17Z mike $"
+#
+# Verify that the server requires the following attributes:
+#
+# attributes-charset
+# attributes-natural-language
+# printer-uri/job-uri
+#
+{
+ # The name of the test...
+ NAME "No Attributes"
+
+ # The operation to use
+ OPERATION get-jobs
+
+ # What statuses are OK?
+ STATUS client-error-bad-request
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Charset Attribute"
+
+ # The operation to use
+ OPERATION get-jobs
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+
+ # What statuses are OK?
+ STATUS client-error-bad-request
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Language Attribute"
+
+ # The operation to use
+ OPERATION get-jobs
+
+ # The attributes to send
+ GROUP operation
+ ATTR language attributes-natural-language en
+
+ # What statuses are OK?
+ STATUS client-error-bad-request
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Language + Charset Attributes"
+
+ # The operation to use
+ OPERATION get-jobs
+
+ # The attributes to send
+ GROUP operation
+ ATTR language attributes-natural-language en
+ ATTR charset attributes-charset utf-8
+
+ # What statuses are OK?
+ STATUS client-error-bad-request
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Charset + Language Attributes"
+
+ # The operation to use
+ OPERATION get-jobs
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+
+ # What statuses are OK?
+ STATUS client-error-bad-request
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Charset + Language + Printer URI Attributes"
+
+ # The operation to use
+ OPERATION get-jobs
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Charset + Language + Job URI Attributes"
+
+ # The operation to use
+ OPERATION get-jobs
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri job-uri $method://$hostname:$port/jobs
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+#
+# End of "$Id: 4.1-requests.test 1595 2001-03-01 20:40:17Z mike $"
+#
diff --git a/test/4.2-cups-printer-ops.test b/test/4.2-cups-printer-ops.test
new file mode 100644
index 000000000..8dfd724c5
--- /dev/null
+++ b/test/4.2-cups-printer-ops.test
@@ -0,0 +1,214 @@
+#
+# "$Id: 4.2-cups-printer-ops.test 1595 2001-03-01 20:40:17Z mike $"
+#
+# Verify that the CUPS printer operations work.
+#
+{
+ # The name of the test...
+ NAME "Add Printer Test1"
+
+ # The operation to use
+ OPERATION cups-add-printer
+ RESOURCE /admin/
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+
+ FILE testhp.ppd
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Verify Printer Test1 Added"
+
+ # The operation to use
+ OPERATION get-printer-attributes
+ RESOURCE /
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Delete Printer Test1"
+
+ # The operation to use
+ OPERATION cups-delete-printer
+ RESOURCE /admin/
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Verify Printer Test1 Deleted"
+
+ # The operation to use
+ OPERATION get-printer-attributes
+ RESOURCE /
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+
+ # What statuses are OK?
+ STATUS client-error-not-found
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Add Printer Test2"
+
+ # The operation to use
+ OPERATION cups-add-printer
+ RESOURCE /admin/
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test2
+
+ FILE testps.ppd
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Verify Printer Test2 Added"
+
+ # The operation to use
+ OPERATION get-printer-attributes
+ RESOURCE /
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test2
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Modify Printer Test2"
+
+ # The operation to use
+ OPERATION cups-add-printer
+ RESOURCE /admin/
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test2
+
+ GROUP printer
+ ATTR uri device-uri file:/tmp/Test2
+ ATTR enum printer-state 3
+ ATTR boolean printer-is-accepting-jobs true
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Re-Add Printer Test1"
+
+ # The operation to use
+ OPERATION cups-add-printer
+ RESOURCE /admin/
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+
+ GROUP printer
+ ATTR uri device-uri file:/tmp/Test1
+ ATTR enum printer-state 3
+ ATTR boolean printer-is-accepting-jobs true
+
+ FILE testhp.ppd
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Verify Printer Test1 Re-Added"
+
+ # The operation to use
+ OPERATION get-printer-attributes
+ RESOURCE /
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+
+#
+# End of "$Id: 4.2-cups-printer-ops.test 1595 2001-03-01 20:40:17Z mike $"
+#
diff --git a/test/4.3-job-ops.test b/test/4.3-job-ops.test
new file mode 100644
index 000000000..831850ffe
--- /dev/null
+++ b/test/4.3-job-ops.test
@@ -0,0 +1,297 @@
+#
+# "$Id: 4.3-job-ops.test 1595 2001-03-01 20:40:17Z mike $"
+#
+# Verify that the IPP job operations work.
+#
+{
+ # The name of the test...
+ NAME "Print PostScript Job to Test1"
+
+ # The operation to use
+ OPERATION print-job
+ RESOURCE /printers/Test1
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+ ATTR name requesting-user-name $user
+
+ FILE testfile.ps
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+ EXPECT job-id
+}
+{
+ # The name of the test...
+ NAME "Get Job Attributes"
+
+ # The operation to use
+ OPERATION get-job-attributes
+ RESOURCE /jobs
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+ ATTR integer job-id $job-id
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+ EXPECT job-id
+ EXPECT job-uri
+ EXPECT job-state
+}
+{
+ # The name of the test...
+ NAME "Print PostScript Job to Test2"
+
+ # The operation to use
+ OPERATION print-job
+ RESOURCE /printers/Test2
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test2
+ ATTR name requesting-user-name $user
+
+ FILE testfile.ps
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+ EXPECT job-id
+}
+{
+ # The name of the test...
+ NAME "Get Job Attributes"
+
+ # The operation to use
+ OPERATION get-job-attributes
+ RESOURCE /jobs
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test2
+ ATTR integer job-id $job-id
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+ EXPECT job-id
+ EXPECT job-uri
+ EXPECT job-state
+}
+{
+ # The name of the test...
+ NAME "Print Text Job to Test1"
+
+ # The operation to use
+ OPERATION print-job
+ RESOURCE /printers/Test1
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+ ATTR name requesting-user-name $user
+
+ FILE testfile.txt
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+ EXPECT job-id
+}
+{
+ # The name of the test...
+ NAME "Print PDF Job to Test1"
+
+ # The operation to use
+ OPERATION print-job
+ RESOURCE /printers/Test1
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+ ATTR name requesting-user-name $user
+
+ FILE testfile.pdf
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+ EXPECT job-id
+}
+{
+ # The name of the test...
+ NAME "Print Image Job to Test1"
+
+ # The operation to use
+ OPERATION print-job
+ RESOURCE /printers/Test1
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+ ATTR name requesting-user-name $user
+
+ FILE testfile.jpg
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+ EXPECT job-id
+}
+{
+ # The name of the test...
+ NAME "Hold Job on Test1"
+
+ # The operation to use
+ OPERATION hold-job
+ RESOURCE /printers/Test1
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+ ATTR integer job-id $job-id
+ ATTR name requesting-user-name $user
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Release Job on Test1"
+
+ # The operation to use
+ OPERATION release-job
+ RESOURCE /printers/Test1
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+ ATTR integer job-id $job-id
+ ATTR name requesting-user-name $user
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Get Job List on Test1"
+
+ # The operation to use
+ OPERATION get-jobs
+ RESOURCE /printers/Test1
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $method://$hostname:$port/printers/Test1
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+{
+ # The name of the test...
+ NAME "Get All Jobs"
+
+ # The operation to use
+ OPERATION get-jobs
+ RESOURCE /jobs
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri job-uri $method://$hostname:$port/jobs
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+ EXPECT job-uri
+ EXPECT job-id
+ EXPECT job-state
+}
+{
+ # The name of the test...
+ NAME "Cancel Job"
+
+ # The operation to use
+ OPERATION cancel-job
+ RESOURCE /jobs
+
+ # The attributes to send
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri job-uri $method://$hostname:$port/jobs/$job-id
+ ATTR name requesting-user-name $user
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT attributes-charset
+ EXPECT attributes-natural-language
+}
+
+#
+# End of "$Id: 4.3-job-ops.test 1595 2001-03-01 20:40:17Z mike $"
+#
diff --git a/test/5.1-lpadmin.sh b/test/5.1-lpadmin.sh
new file mode 100755
index 000000000..05036968e
--- /dev/null
+++ b/test/5.1-lpadmin.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Test the lpadmin command.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+echo "Add Printer Test"
+echo ""
+echo " lpadmin -p Test3 -v file:/dev/null -E -m deskjet.ppd"
+../systemv/lpadmin -p Test3 -v file:/dev/null -E -m deskjet.ppd 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+echo "Modify Printer Test"
+echo ""
+echo " lpadmin -p Test3 -v file:/tmp/Test3 -o PageSize=A4"
+../systemv/lpadmin -p Test3 -v file:/tmp/Test3 -o PageSize=A4 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+echo "Delete Printer Test"
+echo ""
+echo " lpadmin -x Test3"
+../systemv/lpadmin -x Test3 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+#
+# End of "$Id$".
+#
diff --git a/test/5.2-lpc.sh b/test/5.2-lpc.sh
new file mode 100755
index 000000000..d7feb1aea
--- /dev/null
+++ b/test/5.2-lpc.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Test the lpc command.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+echo "LPC Test"
+echo ""
+echo " lpc status"
+../berkeley/lpc status 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+#
+# End of "$Id$".
+#
diff --git a/test/5.3-lpq.sh b/test/5.3-lpq.sh
new file mode 100755
index 000000000..27f3d569c
--- /dev/null
+++ b/test/5.3-lpq.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Test the lpq command.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+echo "LPQ Test"
+echo ""
+echo " lpq"
+../berkeley/lpq 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+#
+# End of "$Id$".
+#
diff --git a/test/5.4-lpstat.sh b/test/5.4-lpstat.sh
new file mode 100755
index 000000000..2153b28b1
--- /dev/null
+++ b/test/5.4-lpstat.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Test the lpstat command.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+echo "LPSTAT Test"
+echo ""
+echo " lpstat -t"
+../systemv/lpstat -t 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+#
+# End of "$Id$".
+#
diff --git a/test/5.5-lp.sh b/test/5.5-lp.sh
new file mode 100755
index 000000000..32c12eb35
--- /dev/null
+++ b/test/5.5-lp.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Test the lp command.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+echo "LP Default Test"
+echo ""
+echo " lp testfile.jpg"
+../systemv/lp testfile.jpg 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+echo "LP Destination Test"
+echo ""
+echo " lp -d Test1 testfile.jpg"
+../systemv/lp -d Test1 testfile.jpg 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+#
+# End of "$Id$".
+#
diff --git a/test/5.6-lpr.sh b/test/5.6-lpr.sh
new file mode 100755
index 000000000..4b7efb627
--- /dev/null
+++ b/test/5.6-lpr.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Test the lpr command.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+echo "LPR Default Test"
+echo ""
+echo " lpr testfile.jpg"
+../berkeley/lpr testfile.jpg 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+echo "LPR Destination Test"
+echo ""
+echo " lpr -P Test1 testfile.jpg"
+../berkeley/lpr -P Test1 testfile.jpg 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+#
+# End of "$Id$".
+#
diff --git a/test/5.7-lprm.sh b/test/5.7-lprm.sh
new file mode 100755
index 000000000..81c26b5d4
--- /dev/null
+++ b/test/5.7-lprm.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Test the lprm command.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+echo "LPRM Current Test"
+echo ""
+echo " lprm"
+../berkeley/lprm 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+echo "LPRM Destination Test"
+echo ""
+echo " lprm Test1"
+../berkeley/lprm Test1 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+#
+# End of "$Id$".
+#
diff --git a/test/5.8-cancel.sh b/test/5.8-cancel.sh
new file mode 100755
index 000000000..fa1cf2b47
--- /dev/null
+++ b/test/5.8-cancel.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Test the cancel command.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+echo "Cancel Destination Test"
+echo ""
+echo " cancel Test1"
+../systemv/cancel Test1 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+echo "Cancel All Test"
+echo ""
+echo " cancel -a -"
+../systemv/cancel -a - 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+#
+# End of "$Id$".
+#
diff --git a/test/5.9-lpinfo.sh b/test/5.9-lpinfo.sh
new file mode 100755
index 000000000..bfeb9d668
--- /dev/null
+++ b/test/5.9-lpinfo.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Test the lpinfo command.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+echo "LPINFO Devices Test"
+echo ""
+echo " lpinfo -v"
+../systemv/lpinfo -v 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+echo "LPINFO Drivers Test"
+echo ""
+echo " lpinfo -m"
+../systemv/lpinfo -m 2>&1
+if test $? != 0; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+#
+# End of "$Id$".
+#
diff --git a/test/Dependencies b/test/Dependencies
new file mode 100644
index 000000000..cb014d95d
--- /dev/null
+++ b/test/Dependencies
@@ -0,0 +1,4 @@
+# DO NOT DELETE
+
+ipptest.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+ipptest.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/language.h
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 000000000..2f526ea57
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,85 @@
+#
+# "$Id$"
+#
+# IPP test makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+include ../Makedefs
+
+
+#
+# Make all targets...
+#
+
+all: ipptest
+
+
+#
+# Clean all object files...
+#
+
+clean:
+ $(RM) ipptest ipptest.o
+
+
+#
+# Update dependencies (without system header dependencies...)
+#
+
+depend:
+ makedepend -Y -I.. -fDependencies ipptest.c >/dev/null 2>&1
+
+
+#
+# Install all targets...
+#
+
+install:
+
+
+#
+# ipptest
+#
+
+ipptest: ipptest.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o ipptest ipptest.o $(LIBS)
+
+
+#
+# purify target for doing tests on the CUPS API...
+#
+
+purify: ipptest.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ purify $(CC) $(LDFLAGS) -o ipptest.pure ipptest.o $(LIBS)
+
+
+#
+# Dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id$".
+#
diff --git a/test/create-job-format.test b/test/create-job-format.test
new file mode 100644
index 000000000..87d94a5b6
--- /dev/null
+++ b/test/create-job-format.test
@@ -0,0 +1,56 @@
+# Print a test page using create-job + send-document, specifying the
+# document format.
+{
+ # The name of the test...
+ NAME "Print test page using create-job"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION create-job
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR name requesting-user-name $user
+
+ GROUP job
+ ATTR integer copies 1
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-id
+ EXPECT job-uri
+}
+{
+ # The name of the test...
+ NAME "... and send-document"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION send-document
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR integer job-id $job-id
+ ATTR name requesting-user-name $user
+ ATTR mimetype document-format application/postscript
+ ATTR boolean last-document true
+
+ FILE ../data/testprint.ps
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+}
diff --git a/test/create-job-sheets.test b/test/create-job-sheets.test
new file mode 100644
index 000000000..d15bb7d4b
--- /dev/null
+++ b/test/create-job-sheets.test
@@ -0,0 +1,55 @@
+# Test create-job + send-document with job-sheets attribute
+{
+ # The name of the test...
+ NAME "Print test page using create-job"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION create-job
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR name requesting-user-name $user
+
+ GROUP job
+ ATTR integer copies 1
+ ATTR name job-sheets standard
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-id
+ EXPECT job-uri
+}
+{
+ # The name of the test...
+ NAME "... and send-document"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION send-document
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR integer job-id $job-id
+ ATTR name requesting-user-name $user
+ ATTR boolean last-document true
+
+ FILE ../data/testprint.ps
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+}
diff --git a/test/create-job-timeout.test b/test/create-job-timeout.test
new file mode 100644
index 000000000..b0e035797
--- /dev/null
+++ b/test/create-job-timeout.test
@@ -0,0 +1,55 @@
+# Print a test page using create-job + send-document, but don't send
+# last-document = true
+{
+ # The name of the test...
+ NAME "Print test page using create-job"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION create-job
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR name requesting-user-name $user
+
+ GROUP job
+ ATTR integer copies 1
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-id
+ EXPECT job-uri
+}
+{
+ # The name of the test...
+ NAME "... and send-document"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION send-document
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR integer job-id $job-id
+ ATTR name requesting-user-name $user
+ ATTR mimetype document-format application/octet-stream
+
+ FILE ../data/testprint.ps
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+}
diff --git a/test/create-job.test b/test/create-job.test
new file mode 100644
index 000000000..3cfaac532
--- /dev/null
+++ b/test/create-job.test
@@ -0,0 +1,54 @@
+# Print a test page using create-job + send-document
+{
+ # The name of the test...
+ NAME "Print test page using create-job"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION create-job
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR name requesting-user-name $user
+
+ GROUP job
+ ATTR integer copies 1
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-id
+ EXPECT job-uri
+}
+{
+ # The name of the test...
+ NAME "... and send-document"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION send-document
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR integer job-id $job-id
+ ATTR name requesting-user-name $user
+ ATTR boolean last-document true
+
+ FILE ../data/testprint.ps
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+}
diff --git a/test/get-devices.test b/test/get-devices.test
new file mode 100644
index 000000000..76bb5ec76
--- /dev/null
+++ b/test/get-devices.test
@@ -0,0 +1,21 @@
+# Get devices using CUPS-get-devices
+{
+ # The name of the test...
+ NAME "Get devices using CUPS-get-devices"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION CUPS-get-devices
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+}
diff --git a/test/get-job-attributes.test b/test/get-job-attributes.test
new file mode 100644
index 000000000..35b241b06
--- /dev/null
+++ b/test/get-job-attributes.test
@@ -0,0 +1,27 @@
+# Test get-job-attributes by sending a print job, getting the attributes,
+# and cancelling it.
+{
+ # The name of the test...
+ NAME "Get job info with get-job-attributes"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION get-job-attributes
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri job-uri $uri
+
+ # What statuses are OK?
+ #STATUS ok
+ #STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-uri
+ EXPECT job-state
+ EXPECT bogus-attribute
+}
diff --git a/test/get-job-attributes2.test b/test/get-job-attributes2.test
new file mode 100644
index 000000000..420ccc52c
--- /dev/null
+++ b/test/get-job-attributes2.test
@@ -0,0 +1,29 @@
+# Test get-job-attributes
+{
+ # The name of the test...
+ NAME "get-job-attributes"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION get-job-attributes
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR integer job-id 293
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-uri
+ EXPECT job-state
+ EXPECT time-at-creation
+ EXPECT time-at-completed
+ EXPECT time-at-processing
+}
diff --git a/test/get-ppds.test b/test/get-ppds.test
new file mode 100644
index 000000000..90f59eb6e
--- /dev/null
+++ b/test/get-ppds.test
@@ -0,0 +1,21 @@
+# Get PPD files using CUPS-get-ppds
+{
+ # The name of the test...
+ NAME "Get PPD files using CUPS-get-ppds"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION CUPS-get-ppds
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+}
diff --git a/test/get-printer-attributes.test b/test/get-printer-attributes.test
new file mode 100644
index 000000000..79d4dfffa
--- /dev/null
+++ b/test/get-printer-attributes.test
@@ -0,0 +1,44 @@
+# Get printer attributes using get-printer-attributes
+{
+ # The name of the test...
+ NAME "Get printer attributes using get-printer-attributes"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION get-printer-attributes
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+
+ # What statuses are OK?
+ STATUS successful-ok
+
+ # What attributes do we expect?
+ EXPECT charset-configured
+ EXPECT charset-supported
+ EXPECT compression-supported
+ EXPECT document-format-default
+ EXPECT document-format-supported
+ EXPECT generated-natural-language-supported
+ EXPECT ipp-versions-supported
+ EXPECT natural-language-configured
+ EXPECT operations-supported
+ EXPECT printer-info
+ EXPECT printer-is-accepting-jobs
+ EXPECT printer-location
+ EXPECT printer-make-and-model
+ EXPECT printer-more-info
+ EXPECT printer-name
+ EXPECT printer-state
+ EXPECT printer-state-reasons
+ EXPECT printer-up-time
+ EXPECT printer-uri-supported
+ EXPECT uri-authentication-supported
+ EXPECT uri-security-supported
+ EXPECT foo
+}
diff --git a/test/ipptest.c b/test/ipptest.c
new file mode 100644
index 000000000..fb6b8f4fe
--- /dev/null
+++ b/test/ipptest.c
@@ -0,0 +1,826 @@
+/*
+ * "$Id$"
+ *
+ * IPP test command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * main() - Parse options and do tests.
+ * do_tests() - Do tests as specified in the test file.
+ * get_operation() - Get an IPP opcode from an operation name...
+ * get_status() - Get an IPP status from a status name...
+ * get_tag() - Get an IPP value or group tag from a name...
+ * get_token() - Get a token from a file.
+ * print_attr() - Print an attribute on the screen.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cups/string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include <cups/cups.h>
+#include <cups/language.h>
+
+
+/*
+ * Local globals...
+ */
+
+
+/*
+ * Local functions...
+ */
+
+int do_tests(const char *, const char *);
+ipp_op_t get_operation(const char *);
+ipp_status_t get_status(const char *);
+ipp_tag_t get_tag(const char *);
+char *get_token(FILE *, char *, int);
+void print_attr(ipp_attribute_t *);
+
+
+/*
+ * 'main()' - Parse options and do tests.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ int status; /* Status of tests... */
+
+
+ /*
+ * We need at least:
+ *
+ * testipp URL testfile
+ */
+
+ if (argc < 3)
+ {
+ fputs("Usage: testipp URL testfile [ ... testfileN ]\n", stderr);
+ return (1);
+ }
+
+ /*
+ * Run tests...
+ */
+
+ for (i = 2, status = 1; status && i < argc; i ++)
+ status = status && do_tests(argv[1], argv[i]);
+
+ /*
+ * Exit...
+ */
+
+ return (!status);
+}
+
+
+/*
+ * 'do_tests()' - Do tests as specified in the test file.
+ */
+
+int /* 1 = success, 0 = failure */
+do_tests(const char *uri, /* I - URI to connect on */
+ const char *testfile) /* I - Test file to use */
+{
+ int i; /* Looping var */
+ int version; /* IPP version number to use */
+ http_t *http; /* HTTP connection to server */
+ char method[HTTP_MAX_URI], /* URI method */
+ userpass[HTTP_MAX_URI], /* username:password */
+ server[HTTP_MAX_URI], /* Server */
+ resource[HTTP_MAX_URI]; /* Resource path */
+ int port; /* Port number */
+ FILE *fp; /* Test file */
+ char token[1024], /* Token from file */
+ *tokenptr, /* Pointer into token */
+ temp[1024], /* Temporary string */
+ *tempptr; /* Pointer into temp string */
+ ipp_t *request; /* IPP request */
+ ipp_t *response; /* IPP response */
+ ipp_op_t op; /* Operation */
+ ipp_tag_t group; /* Current group */
+ ipp_tag_t value; /* Current value type */
+ ipp_attribute_t *attrptr; /* Attribute pointer */
+ char attr[128]; /* Attribute name */
+ int num_statuses; /* Number of valid status codes */
+ ipp_status_t statuses[100]; /* Valid status codes */
+ int num_expects; /* Number of expected attributes */
+ char *expects[100]; /* Expected attributes */
+ char name[1024]; /* Name of test */
+ char filename[1024]; /* Filename */
+ int pass; /* Did we pass the test? */
+ int job_id; /* Job ID from last operation */
+
+
+ /*
+ * Open the test file...
+ */
+
+ if ((fp = fopen(testfile, "r")) == NULL)
+ {
+ printf("Unable to open test file %s - %s\n", testfile, strerror(errno));
+ return (0);
+ }
+
+ /*
+ * Connect to the server...
+ */
+
+ httpSeparate(uri, method, userpass, server, &port, resource);
+ if ((http = httpConnect(server, port)) == NULL)
+ {
+ printf("Unable to connect to %s on port %d - %s\n", server, port,
+ strerror(errno));
+ return (0);
+ }
+
+ /*
+ * Loop on tests...
+ */
+
+ printf("\"%s\":\n", testfile);
+ pass = 1;
+ job_id = 0;
+ version = 1;
+
+ while (get_token(fp, token, sizeof(token)) != NULL)
+ {
+ /*
+ * Expect an open brace...
+ */
+
+ if (strcmp(token, "{") != 0)
+ {
+ printf("Unexpected token %s seen - aborting test!\n", token);
+ httpClose(http);
+ return (0);
+ }
+
+ /*
+ * Initialize things...
+ */
+
+ httpSeparate(uri, method, userpass, server, &port, resource);
+
+ request = ippNew();
+ op = (ipp_op_t)0;
+ group = IPP_TAG_OPERATION;
+ value = IPP_TAG_ZERO;
+ num_statuses = 0;
+ num_expects = 0;
+ filename[0] = '\0';
+
+ strcpy(name, testfile);
+ if (strrchr(name, '.') != NULL)
+ *strrchr(name, '.') = '\0';
+
+ /*
+ * Parse until we see a close brace...
+ */
+
+ while (get_token(fp, token, sizeof(token)) != NULL)
+ {
+ if (strcmp(token, "}") == 0)
+ break;
+ else if (strcasecmp(token, "NAME") == 0)
+ {
+ /*
+ * Name of test...
+ */
+
+ get_token(fp, name, sizeof(name));
+ }
+ else if (strcasecmp(token, "VERSION") == 0)
+ {
+ /*
+ * IPP version number for test...
+ */
+
+ get_token(fp, temp, sizeof(temp));
+ sscanf(temp, "%*d.%d", &version);
+ }
+ else if (strcasecmp(token, "RESOURCE") == 0)
+ {
+ /*
+ * Resource name...
+ */
+
+ get_token(fp, resource, sizeof(resource));
+ }
+ else if (strcasecmp(token, "OPERATION") == 0)
+ {
+ /*
+ * Operation...
+ */
+
+ get_token(fp, token, sizeof(token));
+ op = get_operation(token);
+ }
+ else if (strcasecmp(token, "GROUP") == 0)
+ {
+ /*
+ * Attribute group...
+ */
+
+ get_token(fp, token, sizeof(token));
+ group = get_tag(token);
+ }
+ else if (strcasecmp(token, "ATTR") == 0)
+ {
+ /*
+ * Attribute...
+ */
+
+ get_token(fp, token, sizeof(token));
+ value = get_tag(token);
+ get_token(fp, attr, sizeof(attr));
+ get_token(fp, temp, sizeof(temp));
+
+ token[sizeof(token) - 1] = '\0';
+
+ for (tempptr = temp, tokenptr = token;
+ *tempptr && tokenptr < (token + sizeof(token) - 1);)
+ if (*tempptr == '$')
+ {
+ /*
+ * Substitute a string/number...
+ */
+
+ if (strncasecmp(tempptr + 1, "uri", 3) == 0)
+ {
+ strlcpy(tokenptr, uri, sizeof(token) - (tokenptr - token));
+ tempptr += 4;
+ }
+ else if (strncasecmp(tempptr + 1, "method", 6) == 0)
+ {
+ strlcpy(tokenptr, method, sizeof(token) - (tokenptr - token));
+ tempptr += 7;
+ }
+ else if (strncasecmp(tempptr + 1, "username", 8) == 0)
+ {
+ strlcpy(tokenptr, userpass, sizeof(token) - (tokenptr - token));
+ tempptr += 9;
+ }
+ else if (strncasecmp(tempptr + 1, "hostname", 8) == 0)
+ {
+ strlcpy(tokenptr, server, sizeof(token) - (tokenptr - token));
+ tempptr += 9;
+ }
+ else if (strncasecmp(tempptr + 1, "port", 4) == 0)
+ {
+ snprintf(tokenptr, sizeof(token) - (tokenptr - token),
+ "%d", port);
+ tempptr += 5;
+ }
+ else if (strncasecmp(tempptr + 1, "resource", 8) == 0)
+ {
+ strlcpy(tokenptr, resource, sizeof(token) - (tokenptr - token));
+ tempptr += 9;
+ }
+ else if (strncasecmp(tempptr + 1, "job-id", 6) == 0)
+ {
+ snprintf(tokenptr, sizeof(token) - (tokenptr - token),
+ "%d", job_id);
+ tempptr += 7;
+ }
+ else if (strncasecmp(tempptr + 1, "user", 4) == 0)
+ {
+ strlcpy(tokenptr, cupsUser(), sizeof(token) - (tokenptr - token));
+ tempptr += 5;
+ }
+ else
+ {
+ *tokenptr++ = *tempptr ++;
+ *tokenptr = '\0';
+ }
+
+ tokenptr += strlen(tokenptr);
+ }
+ else
+ {
+ *tokenptr++ = *tempptr++;
+ *tokenptr = '\0';
+ }
+
+ switch (value)
+ {
+ case IPP_TAG_BOOLEAN :
+ if (strcasecmp(token, "true") == 0)
+ ippAddBoolean(request, group, attr, 1);
+ else
+ ippAddBoolean(request, group, attr, atoi(token));
+ break;
+
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ ippAddInteger(request, group, value, attr, atoi(token));
+ break;
+
+ case IPP_TAG_RESOLUTION :
+ puts(" ERROR: resolution tag not yet supported!");
+ break;
+
+ case IPP_TAG_RANGE :
+ puts(" ERROR: range tag not yet supported!");
+ break;
+
+ default :
+ ippAddString(request, group, value, attr, NULL, token);
+ break;
+ }
+ }
+ else if (strcasecmp(token, "FILE") == 0)
+ {
+ /*
+ * File...
+ */
+
+ get_token(fp, filename, sizeof(filename));
+ }
+ else if (strcasecmp(token, "STATUS") == 0)
+ {
+ /*
+ * Status...
+ */
+
+ get_token(fp, token, sizeof(token));
+ statuses[num_statuses] = get_status(token);
+ num_statuses ++;
+ }
+ else if (strcasecmp(token, "EXPECT") == 0)
+ {
+ /*
+ * Status...
+ */
+
+ get_token(fp, token, sizeof(token));
+ expects[num_expects] = strdup(token);
+ num_expects ++;
+ }
+ else
+ {
+ printf("Unexpected token %s seen - aborting test!\n", token);
+ httpClose(http);
+ ippDelete(request);
+ return (0);
+ }
+ }
+
+ /*
+ * Submit the IPP request...
+ */
+
+ request->request.op.version[1] = version;
+ request->request.op.operation_id = op;
+ request->request.op.request_id = 1;
+
+ printf(" %-60.60s [ ]", name);
+ fflush(stdout);
+
+ if (filename[0])
+ response = cupsDoFileRequest(http, request, resource, filename);
+ else
+ response = cupsDoRequest(http, request, resource);
+
+ if (response == NULL)
+ {
+ time_t curtime;
+
+ curtime = time(NULL);
+
+ printf("\b\b\b\b\bFAIL]\n");
+ printf(" ERROR %x\n", cupsLastError());
+ printf(" (%s) @ %s\n",
+ ippErrorString(cupsLastError()), ctime(&curtime));
+ pass = 0;
+ }
+ else
+ {
+ if ((attrptr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL)
+ job_id = attrptr->values[0].integer;
+
+ for (i = 0; i < num_statuses; i ++)
+ if (response->request.status.status_code == statuses[i])
+ break;
+
+ if (i == num_statuses && num_statuses > 0)
+ {
+ printf("\b\b\b\b\bFAIL]\n");
+ printf(" STATUS %x\n", response->request.status.status_code);
+ printf(" (%s)\n",
+ ippErrorString(response->request.status.status_code));
+ printf(" (%lu bytes in response)\n",
+ (unsigned long)ippLength(response));
+
+ pass = 0;
+ }
+ else
+ {
+ for (i = 0; i < num_expects; i ++)
+ if (ippFindAttribute(response, expects[i], IPP_TAG_ZERO) == NULL)
+ {
+ if (pass)
+ {
+ printf("\b\b\b\b\bFAIL]\n");
+ printf(" (%lu bytes in response)\n",
+ (unsigned long)ippLength(response));
+ pass = 0;
+ }
+
+ printf(" EXPECTED %s\n", expects[i]);
+ }
+
+ if (pass)
+ {
+ printf("\b\b\b\b\bPASS]\n");
+ printf(" (%lu bytes in response)\n",
+ (unsigned long)ippLength(response));
+ }
+ else
+ {
+ puts(" RECEIVED");
+ printf(" status-code = %04x\n",
+ response->request.status.status_code);
+
+ for (attrptr = response->attrs; attrptr != NULL; attrptr = attrptr->next)
+ print_attr(attrptr);
+ }
+ }
+
+ ippDelete(response);
+ }
+
+ for (i = 0; i < num_expects; i ++)
+ free(expects[i]);
+
+ if (!pass)
+ break;
+ }
+
+ fclose(fp);
+ httpClose(http);
+
+ return (pass);
+}
+
+
+/*
+ * 'get_operation()' - Get an IPP opcode from an operation name...
+ */
+
+ipp_op_t
+get_operation(const char *name)
+{
+ int i;
+ static char *ipp_ops[] =
+ {
+ "",
+ "",
+ "print-job",
+ "print-uri",
+ "validate-job",
+ "create-job",
+ "send-document",
+ "send-uri",
+ "cancel-job",
+ "get-job-attributes",
+ "get-jobs",
+ "get-printer-attributes",
+ "hold-job",
+ "release-job",
+ "restart-job",
+ "",
+ "pause-printer",
+ "resume-printer",
+ "purge-jobs",
+ "set-printer-attributes",
+ "set-job-attributes",
+ "get-printer-supported-values"
+ },
+ *cups_ops[] =
+ {
+ "cups-get-default",
+ "cups-get-printers",
+ "cups-add-printer",
+ "cups-delete-printer",
+ "cups-get-classes",
+ "cups-add-class",
+ "cups-delete-class",
+ "cups-accept-jobs",
+ "cups-reject-jobs",
+ "cups-set-default",
+ "cups-get-devices",
+ "cups-get-ppds",
+ "cups-move-job"
+ };
+
+
+ for (i = 0; i < (sizeof(ipp_ops) / sizeof(ipp_ops[0])); i ++)
+ if (strcasecmp(name, ipp_ops[i]) == 0)
+ return ((ipp_op_t)i);
+
+ if (strcasecmp(name, "windows-ext") == 0)
+ return (IPP_PRIVATE);
+
+ for (i = 0; i < (sizeof(cups_ops) / sizeof(cups_ops[0])); i ++)
+ if (strcasecmp(name, cups_ops[i]) == 0)
+ return ((ipp_op_t)(i + 0x4001));
+
+ return ((ipp_op_t)0);
+}
+
+
+/*
+ * 'get_status()' - Get an IPP status from a status name...
+ */
+
+ipp_status_t
+get_status(const char *name)
+{
+ int i;
+ static const char *status_oks[] = /* "OK" status codes */
+ {
+ "successful-ok",
+ "successful-ok-ignored-or-substituted-attributes",
+ "successful-ok-conflicting-attributes"
+ },
+ *status_400s[] = /* Client errors */
+ {
+ "client-error-bad-request",
+ "client-error-forbidden",
+ "client-error-not-authenticated",
+ "client-error-not-authorized",
+ "client-error-not-possible",
+ "client-error-timeout",
+ "client-error-not-found",
+ "client-error-gone",
+ "client-error-request-entity-too-large",
+ "client-error-request-value-too-long",
+ "client-error-document-format-not-supported",
+ "client-error-attributes-or-values-not-supported",
+ "client-error-uri-scheme-not-supported",
+ "client-error-charset-not-supported",
+ "client-error-conflicting-attributes",
+ "client-error-compression-not-supported",
+ "client-error-compression-error",
+ "client-error-document-format-error",
+ "client-error-document-access-error"
+ },
+ *status_500s[] = /* Server errors */
+ {
+ "server-error-internal-error",
+ "server-error-operation-not-supported",
+ "server-error-service-unavailable",
+ "server-error-version-not-supported",
+ "server-error-device-error",
+ "server-error-temporary-error",
+ "server-error-not-accepting-jobs",
+ "server-error-busy",
+ "server-error-job-canceled",
+ "server-error-multiple-document-jobs-not-supported"
+ };
+
+
+ for (i = 0; i < (sizeof(status_oks) / sizeof(status_oks[0])); i ++)
+ if (strcasecmp(name, status_oks[i]) == 0)
+ return ((ipp_status_t)i);
+
+ for (i = 0; i < (sizeof(status_400s) / sizeof(status_400s[0])); i ++)
+ if (strcasecmp(name, status_400s[i]) == 0)
+ return ((ipp_status_t)(i + 0x400));
+
+ for (i = 0; i < (sizeof(status_500s) / sizeof(status_500s[0])); i ++)
+ if (strcasecmp(name, status_500s[i]) == 0)
+ return ((ipp_status_t)(i + 0x500));
+
+ return ((ipp_status_t)-1);
+}
+
+
+/*
+ * 'get_tag()' - Get an IPP value or group tag from a name...
+ */
+
+ipp_tag_t
+get_tag(const char *name)
+{
+ int i;
+ static char *names[] =
+ {
+ "zero", "operation", "job", "end", "printer",
+ "unsupported-group", "", "", "", "", "", "", "",
+ "", "", "", "unsupported-value", "default",
+ "unknown", "novalue", "", "notsettable",
+ "deleteattr", "anyvalue", "", "", "", "", "", "",
+ "", "", "", "integer", "boolean", "enum", "", "",
+ "", "", "", "", "", "", "", "", "", "", "string",
+ "date", "resolution", "range", "collection",
+ "textlang", "namelang", "", "", "", "", "", "", "",
+ "", "", "", "text", "name", "", "keyword", "uri",
+ "urischeme", "charset", "language", "mimetype"
+ };
+
+
+ for (i = 0; i < (sizeof(names) / sizeof(names[0])); i ++)
+ if (strcasecmp(name, names[i]) == 0)
+ return ((ipp_tag_t)i);
+
+ return (IPP_TAG_ZERO);
+}
+
+
+/*
+ * 'get_token()' - Get a token from a file.
+ */
+
+char * /* O - Token from file or NULL on EOF */
+get_token(FILE *fp, /* I - File to read from */
+ char *buf, /* I - Buffer to read into */
+ int buflen) /* I - Length of buffer */
+{
+ int ch, /* Character from file */
+ quote; /* Quoting character */
+ char *bufptr, /* Pointer into buffer */
+ *bufend; /* End of buffer */
+
+
+ for (;;)
+ {
+ /*
+ * Skip whitespace...
+ */
+
+ while (isspace(ch = getc(fp)));
+
+ /*
+ * Read a token...
+ */
+
+ if (ch == EOF)
+ return (NULL);
+ else if (ch == '\'' || ch == '\"')
+ {
+ /*
+ * Quoted text...
+ */
+
+ quote = ch;
+ bufptr = buf;
+ bufend = buf + buflen - 1;
+
+ while ((ch = getc(fp)) != EOF)
+ if (ch == quote)
+ break;
+ else if (bufptr < bufend)
+ *bufptr++ = ch;
+
+ *bufptr = '\0';
+ return (buf);
+ }
+ else if (ch == '#')
+ {
+ /*
+ * Comment...
+ */
+
+ while ((ch = getc(fp)) != EOF)
+ if (ch == '\n')
+ break;
+ }
+ else
+ {
+ /*
+ * Whitespace delimited text...
+ */
+
+ ungetc(ch, fp);
+
+ bufptr = buf;
+ bufend = buf + buflen - 1;
+
+ while ((ch = getc(fp)) != EOF)
+ if (isspace(ch) || ch == '#')
+ break;
+ else if (bufptr < bufend)
+ *bufptr++ = ch;
+
+ if (ch == '#')
+ ungetc(ch, fp);
+
+ *bufptr = '\0';
+ return (buf);
+ }
+ }
+}
+
+
+/*
+ * 'print_attr()' - Print an attribute on the screen.
+ */
+
+void
+print_attr(ipp_attribute_t *attr) /* I - Attribute to print */
+{
+ int i; /* Looping var */
+
+
+ if (attr->name == NULL)
+ {
+ puts(" -- separator --");
+ return;
+ }
+
+ printf(" %s = ", attr->name);
+
+ switch (attr->value_tag)
+ {
+ case IPP_TAG_INTEGER :
+ case IPP_TAG_ENUM :
+ for (i = 0; i < attr->num_values; i ++)
+ printf("%d ", attr->values[i].integer);
+ break;
+
+ case IPP_TAG_BOOLEAN :
+ for (i = 0; i < attr->num_values; i ++)
+ if (attr->values[i].boolean)
+ printf("true ");
+ else
+ printf("false ");
+ break;
+
+ case IPP_TAG_NOVALUE :
+ printf("novalue");
+ break;
+
+ case IPP_TAG_RANGE :
+ for (i = 0; i < attr->num_values; i ++)
+ printf("%d-%d ", attr->values[i].range.lower,
+ attr->values[i].range.upper);
+ break;
+
+ case IPP_TAG_RESOLUTION :
+ for (i = 0; i < attr->num_values; i ++)
+ printf("%dx%d%s ", attr->values[i].resolution.xres,
+ attr->values[i].resolution.yres,
+ attr->values[i].resolution.units == IPP_RES_PER_INCH ?
+ "dpi" : "dpc");
+ break;
+
+ case IPP_TAG_STRING :
+ case IPP_TAG_TEXT :
+ case IPP_TAG_NAME :
+ case IPP_TAG_KEYWORD :
+ case IPP_TAG_CHARSET :
+ case IPP_TAG_URI :
+ case IPP_TAG_MIMETYPE :
+ case IPP_TAG_LANGUAGE :
+ for (i = 0; i < attr->num_values; i ++)
+ printf("\"%s\" ", attr->values[i].string.text);
+ break;
+
+ case IPP_TAG_TEXTLANG :
+ case IPP_TAG_NAMELANG :
+ for (i = 0; i < attr->num_values; i ++)
+ printf("\"%s\",%s ", attr->values[i].string.text,
+ attr->values[i].string.charset);
+ break;
+
+ default :
+ break; /* anti-compiler-warning-code */
+ }
+
+ putchar('\n');
+}
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/test/print-job-hold.test b/test/print-job-hold.test
new file mode 100644
index 000000000..6bdaa8381
--- /dev/null
+++ b/test/print-job-hold.test
@@ -0,0 +1,33 @@
+# Test print-job and job-hold-until attribute
+{
+ # The name of the test...
+ NAME "Print with print-job + job-hold-until"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION print-job
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR name requesting-user-name $user
+ ATTR mimetype document-format application/postscript
+ ATTR keyword job-hold-until indefinite
+
+ GROUP job
+ ATTR integer copies 1
+
+ FILE ../data/testprint.ps
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-id
+ EXPECT job-uri
+}
diff --git a/test/print-job.test b/test/print-job.test
new file mode 100644
index 000000000..cdab3322f
--- /dev/null
+++ b/test/print-job.test
@@ -0,0 +1,33 @@
+# Print a test page using print-job
+{
+ # The name of the test...
+ NAME "Print test page using print-job"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION print-job
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR name requesting-user-name $user
+ ATTR mimetype document-format application/postscript
+
+ GROUP job
+ ATTR integer copies 1
+
+ FILE ../data/testprint.ps
+
+ # What statuses are OK?
+ #STATUS ok
+ #STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-id
+ EXPECT job-uri
+ EXPECT bogus
+}
diff --git a/test/run-stp-tests.sh b/test/run-stp-tests.sh
new file mode 100755
index 000000000..a1d4df176
--- /dev/null
+++ b/test/run-stp-tests.sh
@@ -0,0 +1,338 @@
+#!/bin/sh
+#
+# "$Id$"
+#
+# Perform the complete set of IPP compliance tests specified in the
+# CUPS Software Test Plan.
+#
+# Copyright 1997-2002 by Easy Software Products, all rights reserved.
+#
+# These coded instructions, statements, and computer programs are the
+# property of Easy Software Products and are protected by Federal
+# copyright law. Distribution and use rights are outlined in the file
+# "LICENSE.txt" which should have been included with this file. If this
+# file is missing or damaged please contact Easy Software Products
+# at:
+#
+# Attn: CUPS Licensing Information
+# Easy Software Products
+# 44141 Airport View Drive, Suite 204
+# Hollywood, Maryland 20636-3111 USA
+#
+# Voice: (301) 373-9603
+# EMail: cups-info@cups.org
+# WWW: http://www.cups.org
+#
+
+#
+# Make the IPP test program...
+#
+
+make
+
+#
+# Information for the server/tests...
+#
+
+user=`whoami`
+port=8631
+cwd=`pwd`
+root=`dirname $cwd`
+
+#
+# Start by creating temporary directories for the tests...
+#
+
+rm -rf /tmp/$user
+mkdir /tmp/$user
+mkdir /tmp/$user/bin
+mkdir /tmp/$user/bin/backend
+mkdir /tmp/$user/bin/filter
+mkdir /tmp/$user/certs
+mkdir /tmp/$user/share
+mkdir /tmp/$user/share/banners
+mkdir /tmp/$user/share/model
+mkdir /tmp/$user/interfaces
+mkdir /tmp/$user/log
+mkdir /tmp/$user/ppd
+mkdir /tmp/$user/spool
+mkdir /tmp/$user/spool/temp
+mkdir /tmp/$user/ssl
+
+ln -s $root/backend/http /tmp/$user/bin/backend
+ln -s $root/backend/ipp /tmp/$user/bin/backend
+ln -s $root/backend/lpd /tmp/$user/bin/backend
+ln -s $root/backend/parallel /tmp/$user/bin/backend
+ln -s $root/backend/serial /tmp/$user/bin/backend
+ln -s $root/backend/socket /tmp/$user/bin/backend
+ln -s $root/backend/usb /tmp/$user/bin/backend
+ln -s $root/cgi-bin /tmp/$user/bin
+ln -s $root/filter/hpgltops /tmp/$user/bin/filter
+ln -s $root/filter/imagetops /tmp/$user/bin/filter
+ln -s $root/filter/imagetoraster /tmp/$user/bin/filter
+ln -s $root/filter/pstops /tmp/$user/bin/filter
+ln -s $root/filter/rastertoepson /tmp/$user/bin/filter
+ln -s $root/filter/rastertohp /tmp/$user/bin/filter
+ln -s $root/filter/texttops /tmp/$user/bin/filter
+ln -s $root/pdftops/pdftops /tmp/$user/bin/filter
+ln -s $root/pstoraster/pstoraster /tmp/$user/bin/filter
+
+ln -s $root/data/classified /tmp/$user/share/banners
+ln -s $root/data/confidential /tmp/$user/share/banners
+ln -s $root/data/secret /tmp/$user/share/banners
+ln -s $root/data/standard /tmp/$user/share/banners
+ln -s $root/data/topsecret /tmp/$user/share/banners
+ln -s $root/data/unclassified /tmp/$user/share/banners
+ln -s $root/data /tmp/$user/share/charsets
+ln -s $root/data /tmp/$user/share
+ln -s $root/fonts /tmp/$user/share
+ln -s $root/ppd/*.ppd /tmp/$user/share/model
+ln -s $root/pstoraster /tmp/$user/share
+ln -s $root/templates /tmp/$user/share
+
+#
+# Then create the necessary config files...
+#
+
+cat >/tmp/$user/cupsd.conf <<EOF
+Browsing Off
+Listen 127.0.0.1:$port
+User $user
+ServerRoot /tmp/$user
+ServerBin /tmp/$user/bin
+DataDir /tmp/$user/share
+FontPath /tmp/$user/share/fonts
+DocumentRoot $root/doc
+RequestRoot /tmp/$user/spool
+TempDir /tmp/$user/spool/temp
+AccessLog /tmp/$user/log/access_log
+ErrorLog /tmp/$user/log/error_log
+PageLog /tmp/$user/log/page_log
+LogLevel debug
+PreserveJobHistory Yes
+<Location />
+Order deny,allow
+Deny from all
+Allow from 127.0.0.1
+</Location>
+<Location /admin>
+Order deny,allow
+Deny from all
+Allow from 127.0.0.1
+Require valid-user
+</Location>
+EOF
+
+touch /tmp/$user/classes.conf
+touch /tmp/$user/printers.conf
+
+cp $root/conf/mime.types /tmp/$user/mime.types
+cp $root/conf/mime.convs /tmp/$user/mime.convs
+
+#
+# Setup the paths...
+#
+
+if test "x$LD_LIBRARY_PATH" = x; then
+ LD_LIBRARY_PATH="$root/cups:$root/filter"
+else
+ LD_LIBRARY_PATH="$root/cups:$root/filter:$LD_LIBRARY_PATH"
+fi
+
+export LD_LIBRARY_PATH
+
+LD_PRELOAD="$root/cups/libcups.so:$root/filter/libcupsimage.so"
+export LD_PRELOAD
+
+if test "x$DYLD_LIBRARY_PATH" = x; then
+ DYLD_LIBRARY_PATH="$root/cups:$root/filter"
+else
+ DYLD_LIBRARY_PATH="$root/cups:$root/filter:$DYLD_LIBRARY_PATH"
+fi
+
+export DYLD_LIBRARY_PATH
+
+if test "x$SHLIB_PATH" = x; then
+ SHLIB_PATH="$root/cups:$root/filter"
+else
+ SHLIB_PATH="$root/cups:$root/filter:$SHLIB_PATH"
+fi
+
+export SHLIB_PATH
+
+CUPS_SERVERROOT=/tmp/$user; export CUPS_SERVERROOT
+CUPS_DATADIR=/tmp/$user/share; export CUPS_DATADIR
+
+#
+# Set a new home directory to avoid getting user options mixed in...
+#
+
+HOME=/tmp/$user
+export HOME
+
+#
+# Start the server; run as foreground daemon in the background...
+#
+
+echo "Starting scheduler..."
+
+../scheduler/cupsd -c /tmp/$user/cupsd.conf -f &
+cupsd=$!
+
+echo "Scheduler is PID $cupsd; run debugger now if you need to."
+echo ""
+echo "Press ENTER to continue..."
+read junk
+
+IPP_PORT=$port; export IPP_PORT
+
+while true; do
+ running=`../systemv/lpstat -r 2>/dev/null`
+ if test "x$running" = "xscheduler is running"; then
+ break
+ fi
+
+ echo "Waiting for scheduler to become ready..."
+ sleep 10
+done
+
+#
+# Create the test report source file...
+#
+
+strfile=cups-str-1.1-`date +%Y-%m-%d`-`whoami`.shtml
+
+rm -f $strfile
+cat str-header.html >$strfile
+
+#
+# Run the IPP tests...
+#
+
+echo "Running IPP compliance tests..."
+
+echo "<H1>IPP Compliance Tests</H1>" >>$strfile
+echo "<P>This section provides the results to the IPP compliance tests" >>$strfile
+echo "outlined in the CUPS Software Test Plan. These tests were run on" >>$strfile
+echo `date "+%Y-%m-%d"` by `whoami` on `hostname`. >>$strfile
+echo "<PRE>" >>$strfile
+
+fail=0
+for file in 4*.test; do
+ echo "Performing $file..."
+ echo "" >>$strfile
+
+ ./ipptest ipp://localhost:$port/printers $file >>$strfile
+ status=$?
+
+ if test $status != 0; then
+ echo Test failed.
+ fail=`expr $fail + 1`
+ fi
+done
+
+echo "</PRE>" >>$strfile
+
+#
+# Run the command tests...
+#
+
+echo "Running command tests..."
+
+echo "<H1>Command Tests</H1>" >>$strfile
+echo "<P>This section provides the results to the command tests" >>$strfile
+echo "outlined in the CUPS Software Test Plan. These tests were run on" >>$strfile
+echo `date "+%Y-%m-%d"` by `whoami` on `hostname`. >>$strfile
+echo "<PRE>" >>$strfile
+
+for file in 5*.sh; do
+ echo "Performing $file..."
+ echo "" >>$strfile
+ echo "\"$file\":" >>$strfile
+
+ sh $file >>$strfile
+ status=$?
+
+ if test $status != 0; then
+ echo Test failed.
+ fail=`expr $fail + 1`
+ fi
+done
+
+echo "</PRE>" >>$strfile
+
+#
+# Wait for jobs to complete...
+#
+
+while true; do
+ jobs=`../systemv/lpstat 2>/dev/null`
+ if test "x$jobs" = "x"; then
+ break
+ fi
+
+ echo "Waiting for jobs to complete..."
+ sleep 10
+done
+
+#
+# Stop the server...
+#
+
+kill $cupsd
+
+#
+# Append the log files for post-mortim...
+#
+
+echo "<H1>Log Files</H1>" >>$strfile
+
+echo "<H2>access_log</H2>" >>$strfile
+echo "<PRE>" >>$strfile
+cat /tmp/$user/log/access_log >>$strfile
+echo "</PRE>" >>$strfile
+
+echo "<H2>error_log</H2>" >>$strfile
+echo "<PRE>" >>$strfile
+cat /tmp/$user/log/error_log >>$strfile
+echo "</PRE>" >>$strfile
+
+echo "<H2>page_log</H2>" >>$strfile
+echo "<PRE>" >>$strfile
+cat /tmp/$user/log/page_log >>$strfile
+echo "</PRE>" >>$strfile
+
+#
+# Format the reports and tell the user where to find them...
+#
+
+echo "Formatting reports..."
+
+cat str-trailer.html >>$strfile
+
+htmlfile=`basename $strfile .shtml`.html
+pdffile=`basename $strfile .shtml`.pdf
+
+htmldoc --numbered --verbose --titleimage ../doc/images/cups-large.gif \
+ -f $htmlfile $strfile
+htmldoc --numbered --verbose --titleimage ../doc/images/cups-large.gif \
+ -f $pdffile $strfile
+
+echo ""
+
+if test $fail != 0; then
+ echo "$fail tests failed."
+else
+ echo "All tests were successful."
+fi
+
+echo ""
+echo "See the following files for details:"
+echo ""
+echo " $htmlfile"
+echo " $pdffile"
+echo ""
+
+#
+# End of "$Id$"
+#
diff --git a/test/set-attrs-hold.test b/test/set-attrs-hold.test
new file mode 100644
index 000000000..377819ae4
--- /dev/null
+++ b/test/set-attrs-hold.test
@@ -0,0 +1,180 @@
+# Test print-job and later job-hold-until attribute
+{
+ # The name of the test...
+ NAME "Disable printer..."
+
+ # The resource to use for the POST
+ RESOURCE /admin/
+
+ # The operation to use
+ OPERATION pause-printer
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR name requesting-user-name $user
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+}
+
+{
+ # The name of the test...
+ NAME "Print job"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION print-job
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR name requesting-user-name $user
+ ATTR mimetype document-format application/postscript
+
+ GROUP job
+ ATTR integer copies 1
+
+ FILE ../data/testprint.ps
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-id
+ EXPECT job-uri
+}
+
+{
+ # The name of the test...
+ NAME "Get job attrs"
+
+ # The resource to use for the POST
+ RESOURCE /
+
+ # The operation to use
+ OPERATION get-job-attributes
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR integer job-id $job-id
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-state
+ EXPECT job-hold-until
+}
+
+{
+ # The name of the test...
+ NAME "Set job attrs with job-hold-until"
+
+ # The resource to use for the POST
+ # RESOURCE /admin
+
+ # The operation to use
+ OPERATION set-job-attributes
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR integer job-id $job-id
+ ATTR name requesting-user-name $user
+
+ GROUP job
+ ATTR name job-hold-until 00:30:00
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+}
+
+{
+ # The name of the test...
+ NAME "Get job attrs again"
+
+ # The resource to use for the POST
+ RESOURCE /
+
+ # The operation to use
+ OPERATION get-job-attributes
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR integer job-id $job-id
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-state
+ EXPECT job-hold-until
+}
+
+{
+ # The name of the test...
+ NAME "Enable printer..."
+
+ # The resource to use for the POST
+ RESOURCE /admin/
+
+ # The operation to use
+ OPERATION resume-printer
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR name requesting-user-name $user
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+}
+
+{
+ # The name of the test...
+ NAME "Get job attrs (last time)"
+
+ # The resource to use for the POST
+ RESOURCE /
+
+ # The operation to use
+ OPERATION get-job-attributes
+
+ # Attributes, starting in the operation group...
+ GROUP operation
+ ATTR charset attributes-charset utf-8
+ ATTR language attributes-natural-language en
+ ATTR uri printer-uri $uri
+ ATTR integer job-id $job-id
+
+ # What statuses are OK?
+ STATUS ok
+ STATUS ok-subst
+
+ # What attributes do we expect?
+ EXPECT job-state
+ EXPECT job-hold-until
+}
diff --git a/test/str-header.html b/test/str-header.html
new file mode 100644
index 000000000..a2e93e876
--- /dev/null
+++ b/test/str-header.html
@@ -0,0 +1,35 @@
+<HTML>
+<HEAD>
+ <META NAME="Description" CONTENT="Common UNIX Printing System Software Test Report">
+ <META NAME="COPYRIGHT" CONTENT="Copyright 1997-2001, All Rights Reserved">
+ <META NAME="DOCNUMBER" CONTENT="CUPS-STR-1.1">
+ <META NAME="Author" CONTENT="Easy Software Products">
+ <TITLE>CUPS Software Test Report</TITLE>
+</HEAD>
+<BODY>
+
+<H1>Scope</H1>
+
+<H2>Identification</H2>
+
+<P>This software test report provides detailed test results that
+are used to evaluate the stability and compliance of the Common
+UNIX Printing System ("CUPS") Version 1.1.
+
+<EMBED SRC="../doc/system-overview.shtml">
+
+<H2>Document Overview</H2>
+
+<P>This software test plan is organized into the following sections:
+
+<UL>
+ <LI>1 - Scope</LI>
+ <LI>2 - References</LI>
+ <LI>3 - IPP Compliance Tests</LI>
+ <LI>4 - Command Tests</LI>
+ <LI>5 - Log Files</LI>
+ <LI>A - Glossary</LI>
+</UL>
+
+<EMBED SRC="../doc/references.shtml">
+
diff --git a/test/str-trailer.html b/test/str-trailer.html
new file mode 100644
index 000000000..4c8ddd526
--- /dev/null
+++ b/test/str-trailer.html
@@ -0,0 +1,5 @@
+<EMBED SRC="../doc/glossary.shtml">
+
+
+</BODY>
+</HTML>
diff --git a/test/testfile.jpg b/test/testfile.jpg
new file mode 100644
index 000000000..9f4b39938
--- /dev/null
+++ b/test/testfile.jpg
Binary files differ
diff --git a/test/testfile.pdf b/test/testfile.pdf
new file mode 100644
index 000000000..8ae73cb58
--- /dev/null
+++ b/test/testfile.pdf
Binary files differ
diff --git a/test/testfile.ps b/test/testfile.ps
new file mode 100644
index 000000000..4610affff
--- /dev/null
+++ b/test/testfile.ps
@@ -0,0 +1,512 @@
+%!PS-Adobe-3.0
+%%BoundingBox: 0 0 612 792
+%%Pages: 1
+%%LanguageLevel: 1
+%%DocumentData: Clean7Bit
+%%DocumentSuppliedResources: procset testprint/1.0
+%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman
+%%Creator: Michael Sweet, Easy Software Products
+%%CreationDate: May 11, 1999
+%%Title: Test Page
+%%EndComments
+%%BeginProlog
+%%BeginResource procset testprint 1.1 0
+%
+% PostScript test page for the Common UNIX Printing System ("CUPS").
+%
+% Copyright 1993-2002 Easy Software Products
+%
+% These coded instructions, statements, and computer programs contain
+% unpublished proprietary information of Easy Software Products, and
+% are protected by Federal copyright law. They may not be disclosed
+% to third parties or copied or duplicated in any form, in whole or
+% in part, without the prior written consent of Easy Software Products.
+%
+/OCTANT { % Draw a color wheel OCTANT...
+ % (name) radius r g b OCTANT -
+ % Loop through 100 shades...
+ 0 0.010101 0.98 {
+ % Set the color...
+ 3 index 1 eq % R == 1?
+ 3 index 1 eq % G == 1?
+ 3 index 1 eq % B == 1?
+ and and {
+ 0 index 4 index mul % R * val
+ 1 index 4 index mul % G * val
+ 2 index 4 index mul % B * val
+ } {
+ 0 index 4 index mul % R * val
+ 1 index neg 1 add add % + (1 - val)
+ 1 index 4 index mul % G * val
+ 2 index neg 1 add add % + (1 - val)
+ 2 index 4 index mul % B * val
+ 3 index neg 1 add add % + (1 - val)
+ } ifelse
+ setrgbcolor
+
+ % Draw a polygon...
+ dup 5 index mul dup 0 % x1, y1
+ moveto
+ 0.707106781 mul dup lineto % x2, y2
+
+ 0.010101 add 4 index mul dup % x3
+ 0.707106781 mul dup lineto % x3, y3
+ 0 lineto % x4, y4
+ closepath
+ fill
+ } for
+
+ % Draw a line around the polygons...
+ pop pop pop dup
+ 0 setgray
+ 0 0 moveto
+ dup 0 lineto
+ 0.707106781 mul dup lineto
+ closepath
+ stroke
+
+ % Draw the label...
+ 0 exch dup -9 div exch % text offset = 0, -radius/9
+ dup 0.923879532 mul % x = radius * cos(22.5)
+ exch 0.382683432 mul % y = radius * cos(22.5)
+ moveto % position label
+ gsave
+ 22.5 rotate % rotate label
+ rmoveto % offset label
+ show % show label
+ grestore
+} bind def
+/CENTER { % Draw centered text
+ % (name) CENTER -
+ dup stringwidth pop % Get the width of the string
+ 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance
+ show % Show the string
+} bind def
+/RIGHT { % Draw right-justified text
+ % (name) RIGHT -
+ dup stringwidth pop % Get the width of the string
+ neg 0 rmoveto % Shift left the entire distance
+ show % Show the string
+} bind def
+/NUMBER { % Draw a number
+ % power n NUMBER -
+ 1 index 1 eq { % power == 1?
+ round cvi exch pop % Convert "n" to integer
+ } {
+ 1 index mul round exch div % Truncate extra decimal places
+ } ifelse
+ 100 string cvs show % Convert to a string and show it...
+} bind def
+/CUPSLOGO { % Draw the CUPS logo
+ % height CUPSLOGO
+ % Start with a big C...
+ /Helvetica findfont 1 index scalefont setfont
+ 0 setgray
+ 0 0 moveto
+ (C) show
+
+ % Then "UNIX Printing System" much smaller...
+ /Helvetica-Bold findfont 1 index 9 div scalefont setfont
+ 0.25 mul
+ dup dup 2.0 mul moveto
+ (UNIX) show
+ dup dup 1.6 mul moveto
+ (Printing) show
+ dup 1.2 mul moveto
+ (System) show
+} bind def
+/ESPLOGO { % Draw the ESP logo
+ % height ESPLOGO
+ % Compute the size of the logo...
+ 0 0
+ 2 index 1.5 mul 3 index
+
+ % Do the "metallic" fill from 10% black to 40% black...
+ 1 -0.001 0 {
+ dup % loopval
+ -0.15 mul % loopval * -0.15
+ 0.9 add % 0.9 - loopval * 0.15
+ setgray % set gray shade
+
+ 0 % x
+ 1 index neg % loopval
+ 1 add % 1 - loopval
+ 3 index % height
+ mul % height * (1 - loopval)
+ moveto % starting point
+
+ dup % loopval
+ 3 index % width
+ mul % loopval * width
+ 2 index % height
+ lineto % Next point
+
+ 0 % x
+ 2 index % height
+ lineto % Next point
+
+ closepath
+ fill
+
+ dup % loopval
+ 0.15 mul % loopval * 0.15
+ 0.6 add % 0.6 + loopval * 0.15
+ setgray
+
+ dup % loopval
+ neg 1 add % 1 - loopval
+ 3 index % width
+ mul % (1 - loopval) * width
+ 0 % y
+ moveto % Starting point
+
+ 2 index % width
+ exch % loopval
+ 2 index % height
+ mul % loopval * height
+ lineto % Next point
+
+ 1 index % width
+ 0 % y
+ lineto % Next point
+
+ closepath
+ fill
+ } for
+
+ 0 setgray rectstroke
+
+ /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont
+ dup 40 div
+
+ dup 4 mul 1 index 25 mul moveto (E) show
+ dup 10 mul 1 index 15 mul moveto (S) show
+ dup 16 mul 1 index 5 mul moveto (P) show
+
+ /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont
+ dup 14 mul 1 index 29 mul moveto (asy) show
+ dup 20 mul 1 index 19 mul moveto (oftware) show
+ dup 26 mul 1 index 9 mul moveto (roducts) show
+
+ pop
+} bind def
+%%EndResource
+%%EndProlog
+%%Page: 1 1
+gsave
+
+ % Determine the imageable area and device resolution...
+ initclip newpath clippath pathbbox % Get bounding rectangle
+ 72 div /pageTop exch def % Get top margin in inches
+ 72 div /pageRight exch def % Get right margin in inches
+ 72 div /pageBottom exch def % Get bottom margin in inches
+ 72 div /pageLeft exch def % Get left margin in inches
+
+ 4 setlinewidth % Draw wide lines
+ 0 setgray closepath stroke % Draw a clipping rectangle
+ 1 setlinewidth % Draw normal lines
+
+ /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft
+ /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom
+
+ 72 72 dtransform % Get device resolution per inch
+ /yResolution exch abs def % yResolution = abs(yres)
+ /xResolution exch abs def % xResolution = abs(xres)
+
+ % Figure out the sizes of things...
+ /wheelSize % size of wheels
+ pageWidth pageHeight lt
+ { pageWidth 9 mul }
+ { pageHeight 7 mul }
+ ifelse def
+
+ % Create fonts...
+ /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold
+ pageHeight 3 mul scalefont def % size = pageHeight * 3 (nominally 33)
+
+ /mediumFont /Helvetica findfont % mediumFont = Helvetica
+ pageHeight 1.5 mul scalefont def % size = pageHeight * 1.5 (nominally 16.5)
+
+ /smallFont /Times-Roman findfont % smallFont = Times-Roman
+ pageHeight scalefont def % size = pageHeight (nominally 11)
+
+ % Offset page to account for lower-left margin...
+ pageLeft 72 mul
+ pageBottom 72 mul
+ translate
+
+ % Draw the color wheel...
+ mediumFont setfont % Font
+ 0 setgray % Color
+
+ gsave
+ % Position the wheel on the left side...
+ pageWidth 18 mul % x = pageWidth * 1/4 * 72
+ pageHeight 54 mul % y = pageHeight * 3/4 * 72
+ translate
+
+ % Size the wheel...
+ wheelSize
+
+ % Draw the colors...
+ dup (C) exch 0 1 1 OCTANT 45 rotate
+ dup (M) exch 1 0 1 OCTANT 45 rotate
+ dup (Y) exch 1 1 0 OCTANT 45 rotate
+ dup (K) exch 0 0 0 OCTANT 45 rotate
+ dup (R) exch 1 0 0 OCTANT 45 rotate
+ dup (G) exch 0 1 0 OCTANT 45 rotate
+ dup (B) exch 0 0 1 OCTANT 45 rotate
+ (W) exch 1 1 1 OCTANT 45 rotate
+ grestore
+
+ % Label the color wheel...
+ pageWidth 18 mul % x = pageWidth * 1/4 * 72
+ pageHeight 44 mul % y = pageHeight * 19/32 * 72
+ moveto % Position the text
+ (Color Wheel) CENTER % Show the text centered
+
+ % Draw radial lines...
+ gsave
+ 0 setlinewidth % 1 pixel lines
+
+ % Position the lines on the left side...
+ pageWidth 54 mul % x = pageWidth * 3/4 * 72
+ pageHeight 54 mul % y = pageHeight * 3/4 * 72
+ translate
+
+ % Size the wheel...
+ wheelSize
+
+ % Loop at 1 degree increments
+ 0 1 359 {
+ pop % Discard angle - not used
+ 0 0 moveto % Start line at the center
+ dup 0 lineto % Draw to the radius
+ 1 rotate % Rotate 1 degree
+ } for
+
+ pop % Discard radius - not needed anymore
+ stroke % Draw lines...
+
+ grestore
+
+ % Label the lines...
+ pageWidth 54 mul % x = pageWidth * 3/4 * 72
+ pageHeight 44 mul % y = pageHeight * 19/32 * 72
+ moveto % Position the text
+ (1 Degree Radial Lines) CENTER % Show the text centered
+
+ % Imageable area...
+ pageHeight 15 mul % Height of imageable area
+
+ pageWidth 4.5 mul % x = pageWidth * 1/16 * 72
+ pageHeight 35.5 mul % y = pageHeight * 1/2 * 72
+ 2 index sub % y -= height
+ pageWidth 28 mul % width = pageWidth * 1/4 * 72
+ 3 index % height
+ 0.5 setgray rectfill % Draw a shadow
+
+ pageWidth 4 mul % x = pageWidth * 1/16 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ 2 index sub % y -= height
+ pageWidth 28 mul % width = pageWidth * 3/8 * 72
+ 3 index % height
+ 4 copy 1 setgray rectfill % Clear the box to white
+ 0 setgray rectstroke % Draw a black box around it...
+
+ pop % Discard height
+
+ % Label the imageable area...
+ pageWidth 4 mul % x = pageWidth * 1/16 * 72
+ pageHeight 37 mul % y = pageHeight * 1/2 * 72
+ moveto % Position the text
+ mediumFont setfont % Font
+ (Imageable Area) show % Show the text
+
+ smallFont setfont % Font
+ pageWidth 14 mul % x = pageWidth * 3/16 * 72
+ pageHeight 36 mul % y = pageWidth * 1/2 * 72
+ pageHeight -2 mul add % y -= 2 * smallFont height
+
+ % Page Size inches
+ 2 copy moveto % Move to x & y
+ (Page Size: ) RIGHT % Label
+ 100 pageWidth NUMBER % pageWidth
+ (x) show % "x"
+ 100 pageHeight NUMBER % pageHeight
+ (in) show % "in"
+
+ % Page Size millimeters
+ pageHeight sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ 10 pageWidth 25.4 mul NUMBER % pageWidth
+ (x) show % "x"
+ 10 pageHeight 25.4 mul NUMBER % pageHeight
+ (mm) show % "mm"
+
+ % Lower-left inches
+ pageHeight 2 mul sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ (Lower-Left: ) RIGHT % Label
+ 100 pageLeft NUMBER % pageLeft
+ (x) show % "x"
+ 100 pageBottom NUMBER % pageBottom
+ (in) show % "in"
+
+ % Lower-left millimeters
+ pageHeight sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ 10 pageLeft 25.4 mul NUMBER % pageLeft
+ (x) show % "x"
+ 10 pageBottom 25.4 mul NUMBER % pageBottom
+ (mm) show % "mm"
+
+ % Upper-right inches
+ pageHeight 2 mul sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ (Upper-Right: ) RIGHT % Label
+ 100 pageRight NUMBER % pageRight
+ (x) show % "x"
+ 100 pageTop NUMBER % pageTop
+ (in) show % "in"
+
+ % Upper-right millimeters
+ pageHeight sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ 10 pageRight 25.4 mul NUMBER % pageRight
+ (x) show % "x"
+ 10 pageTop 25.4 mul NUMBER % pageTop
+ (mm) show % "mm"
+
+ % Resolution dots-per-inch
+ pageHeight 2 mul sub % Move down...
+
+ 2 copy moveto % Move to x & y
+ (Resolution: ) RIGHT % Label
+ 1 xResolution NUMBER % xResolution
+ (x) show % "x"
+ 1 yResolution NUMBER % yResolution
+ (dpi) show % "dpi"
+
+ % Resolution dots-per-meter
+ pageHeight sub % Move down...
+
+ moveto % Move to x & y
+ 1 xResolution 39.27 mul NUMBER % xResolution
+ (x) show % "x"
+ 1 yResolution 39.27 mul NUMBER % yResolution
+ (dpm) show % "dpm"
+
+ % Interpreter Information...
+ pageHeight 15 mul % Height of interpreter information
+
+ pageWidth 40.5 mul % x = pageWidth * 9/16 * 72
+ pageHeight 35.5 mul % y = pageHeight * 1/2 * 72
+ 2 index sub % y -= height
+ pageWidth 28 mul % width = pageWidth * 1/4 * 72
+ 3 index % height
+ 0.5 setgray rectfill % Draw a shadow
+
+ pageWidth 40 mul % x = pageWidth * 9/16 * 72
+ pageHeight 36 mul % y = pageHeight * 1/2 * 72
+ 2 index sub % y -= height
+ pageWidth 28 mul % width = pageWidth * 3/8 * 72
+ 3 index % height
+ 4 copy 1 setgray rectfill % Clear the box to white
+ 0 setgray rectstroke % Draw a black box around it...
+
+ pop % Discard height
+
+ % Label the interpreter info...
+ pageWidth 40 mul % x = pageWidth * 9/16 * 72
+ pageHeight 37 mul % y = pageHeight * 1/2 * 72
+ moveto % Position the text
+ mediumFont setfont % Font
+ (Interpreter Information) show % Show the text
+
+ smallFont setfont % Font
+ pageWidth 49 mul % x = pageWidth * 11/16 * 72
+ pageHeight 36 mul % y = pageWidth * 1/2 * 72
+ pageHeight 2 mul sub % y -= 2 * smallFont height
+
+ % Language level
+ 2 copy moveto % Move to x & y
+ (PostScript: ) RIGHT % Label
+ (Level ) show % "Level "
+ 1 languagelevel NUMBER % Language level
+
+ % Version
+ pageHeight 2 mul sub % Move down...
+ 2 copy moveto % Move to x & y
+ (Version: ) RIGHT % Label
+ version show % Version
+ ( \() show % " ("
+ 1 revision NUMBER % Revision
+ (\)) show % ")"
+
+ % Product
+ pageHeight 2 mul sub % Move down...
+ 2 copy moveto % Move to x & y
+ (Product: ) RIGHT % Label
+ product show % Product name
+
+ % Serial Number
+ pageHeight 2 mul sub % Move down...
+ 2 copy moveto % Move to x & y
+ (Serial #: ) RIGHT % Label
+ 1 serialnumber NUMBER % S/N
+
+ % Draw the label at the top...
+ pageWidth 36 mul % Center of page
+ pageHeight 68 mul % Top of page (15/16ths)
+ 2 copy moveto % Position text
+ bigFont setfont % Font
+ (Printer Test Page) CENTER % Show text centered
+
+ % Draw the copyright notice at the bottom...
+ pageWidth 36 mul % Center of page
+ pageHeight 10 mul % Bottom of page
+ 2 copy moveto % Position text
+ (Printed Using CUPS v1.1.x) CENTER % Show text centered
+
+ pageHeight 2 mul sub % Move down...
+ 2 copy moveto % Position text
+ smallFont setfont % Font
+ (Copyright 1993-2002 Easy Software Products, All Rights Reserved.) CENTER
+ pageHeight sub % Move down...
+ 2 copy moveto % Position text
+ (CUPS, and the CUPS logo are the trademark property of) CENTER
+ pageHeight sub % Move down...
+ 2 copy moveto % Position text
+ (Easy Software Products, 44141 Airport View Drive, Suite 204,) CENTER
+ pageHeight sub % Move down...
+ 2 copy moveto % Position text
+ (Hollywood, Maryland, 20636-3111, USA.) CENTER
+
+ % Then the CUPS logo....
+ gsave
+ pageWidth 4 mul
+ pageHeight 4 mul
+ translate
+ pageWidth 9 mul CUPSLOGO
+ grestore
+
+ % And the ESP logo....
+ gsave
+ pageWidth 59 mul
+ pageHeight 4 mul
+ translate
+ pageWidth 6 mul ESPLOGO
+ grestore
+% Show the page...
+grestore
+showpage
+%
+% End of "$Id: testfile.ps 2010 2002-01-02 17:59:21Z mike $".
+%
+%%EOF
diff --git a/test/testfile.txt b/test/testfile.txt
new file mode 100644
index 000000000..46bbf0848
--- /dev/null
+++ b/test/testfile.txt
@@ -0,0 +1,60 @@
+All work and no play makes Johhny a dull boy. All work and no
+play makes Johhny a dull boy. All work and no play makes Johhny
+a dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy. All
+work and no play makes Johhny a dull boy. All work and no play
+makes Johhny a dull boy. All work and no play makes Johhny a
+dull boy. All work and no play makes Johhny a dull boy.
diff --git a/test/testhp.ppd b/test/testhp.ppd
new file mode 100644
index 000000000..c77d22178
--- /dev/null
+++ b/test/testhp.ppd
@@ -0,0 +1,195 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Test HP PPD file for the Common UNIX Printing System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "TESTHP.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*cupsVersion: 1.1
+*cupsManualCopies: True
+*cupsFilter: "application/vnd.cups-raster 50 rastertohp"
+*ModelName: "Test HP Printer"
+*ShortNickName: "Test HP Printer"
+*NickName: "Test HP Printer CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: RGB
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*UIConstraints: *PageSize Executive *InputSlot Envelope
+*UIConstraints: *PageSize Letter *InputSlot Envelope
+*UIConstraints: *PageSize Legal *InputSlot Envelope
+*UIConstraints: *PageSize Tabloid *InputSlot Envelope
+*UIConstraints: *PageSize A3 *InputSlot Envelope
+*UIConstraints: *PageSize A4 *InputSlot Envelope
+*UIConstraints: *PageSize A5 *InputSlot Envelope
+*UIConstraints: *PageSize B5 *InputSlot Envelope
+*UIConstraints: *Resolution 600dpi *ColorModel CMYK
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageSize Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageSize A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageSize A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageSize B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageSize EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageSize Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageSize EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageSize EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageSize EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageRegion Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageRegion A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageRegion A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageRegion A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageRegion B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageRegion Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/US Letter: "18 36 594 756"
+*ImageableArea Legal/US Legal: "18 36 594 972"
+*ImageableArea Executive/US Executive: "18 36 504 684"
+*ImageableArea Tabloid/US Tabloid: "18 36 774 1188"
+*ImageableArea A3/A3: "18 36 824 1155"
+*ImageableArea A4/A4: "18 36 577 806"
+*ImageableArea A5/A5: "18 36 403 559"
+*ImageableArea B5/JIS B5: "18 36 498 693"
+*ImageableArea EnvISOB5/B5 (ISO): "18 36 463 673"
+*ImageableArea Env10/Com-10: "18 36 279 648"
+*ImageableArea EnvC5/EnvC5: "18 36 441 613"
+*ImageableArea EnvDL/EnvDL: "18 36 294 588"
+*ImageableArea EnvMonarch/Envelope Monarch: "18 36 261 504"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/US Letter: "612 792"
+*PaperDimension Legal/US Legal: "612 1008"
+*PaperDimension Executive/US Executive: "522 756"
+*PaperDimension Tabloid/US Tabloid: "792 1224"
+*PaperDimension A3/A3: "842 1191"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension A5/A5: "421 595"
+*PaperDimension B5/B5 (JIS): "516 729"
+*PaperDimension EnvISOB5/Envelope B5: "499 709"
+*PaperDimension Env10/Envelope #10: "297 684"
+*PaperDimension EnvC5/Envelope C5: "459 649"
+*PaperDimension EnvDL/Envelope DL: "312 624"
+*PaperDimension EnvMonarch/Envelope Monarch: "279 540"
+
+*OpenUI *MediaType/Media Type: PickOne
+*OrderDependency: 10 AnySetup *MediaType
+*DefaultMediaType: Plain
+*MediaType Plain/Plain Paper: "<</MediaType(Plain)/cupsMediaType 0>>setpagedevice"
+*MediaType Bond/Bond Paper: "<</MediaType(Bond)/cupsMediaType 1>>setpagedevice"
+*MediaType Special/Special Paper: "<</MediaType(Special)/cupsMediaType 2>>setpagedevice"
+*MediaType Transparency/Transparency: "<</MediaType(Transparency)/cupsMediaType 3>>setpagedevice"
+*MediaType Glossy/Glossy Paper: "<</MediaType(Glossy)/cupsMediaType 4>>setpagedevice"
+*CloseUI: *MediaType
+
+*OpenUI *InputSlot/Media Source: PickOne
+*OrderDependency: 10 AnySetup *InputSlot
+*DefaultInputSlot: Tray
+*InputSlot Tray/Tray: "<</cupsMediaPosition 1>>setpagedevice"
+*InputSlot Manual/Manual Feed: "<</cupsMediaPosition 2>>setpagedevice"
+*InputSlot Envelope/Envelope Feed: "<</cupsMediaPosition 3>>setpagedevice"
+*CloseUI: *InputSlot
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 100dpi
+*Resolution 75dpi/75 DPI: "<</HWResolution[75 75]>>setpagedevice"
+*Resolution 100dpi/100 DPI: "<</HWResolution[100 100]>>setpagedevice"
+*CloseUI: *Resolution
+
+*OpenUI *ColorModel/Output Mode: PickOne
+*OrderDependency: 10 AnySetup *ColorModel
+*DefaultColorModel: CMYK
+*ColorModel CMYK/CMYK Color: "<</cupsColorOrder 1/cupsColorSpace 8/cupsCompression 2>>setpagedevice"
+*ColorModel RGB/CMY Color: "<</cupsColorOrder 1/cupsColorSpace 4/cupsCompression 2>>setpagedevice"
+*ColorModel Gray/Grayscale: "<</cupsColorOrder 0/cupsColorSpace 3/cupsCompression 2>>setpagedevice"
+*CloseUI: *ColorModel
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/test/testps.ppd b/test/testps.ppd
new file mode 100644
index 000000000..63d42adf5
--- /dev/null
+++ b/test/testps.ppd
@@ -0,0 +1,192 @@
+*PPD-Adobe: "4.3"
+*%
+*% "$Id$"
+*%
+*% Test PS PPD file for the Common UNIX Printing System (CUPS).
+*%
+*% Copyright 1997-2002 by Easy Software Products.
+*%
+*% These coded instructions, statements, and computer programs are the
+*% property of Easy Software Products and are protected by Federal
+*% copyright law. Distribution and use rights are outlined in the file
+*% "LICENSE.txt" which should have been included with this file. If this
+*% file is missing or damaged please contact Easy Software Products
+*% at:
+*%
+*% Attn: CUPS Licensing Information
+*% Easy Software Products
+*% 44141 Airport View Drive, Suite 204
+*% Hollywood, Maryland 20636-3111 USA
+*%
+*% Voice: (301) 373-9603
+*% EMail: cups-info@cups.org
+*% WWW: http://www.cups.org
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "TESTPS.PPD"
+*Manufacturer: "ESP"
+*Product: "(CUPS v1.1)"
+*ModelName: "Test PS Printer"
+*ShortNickName: "Test PS Printer"
+*NickName: "Test PS Printer CUPS v1.1"
+*PSVersion: "(3010.000) 550"
+*LanguageLevel: "3"
+*ColorDevice: True
+*DefaultColorSpace: RGB
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*VariablePaperSize: False
+*TTRasterizer: Type42
+
+*UIConstraints: *PageSize Executive *InputSlot Envelope
+*UIConstraints: *PageSize Letter *InputSlot Envelope
+*UIConstraints: *PageSize Legal *InputSlot Envelope
+*UIConstraints: *PageSize Tabloid *InputSlot Envelope
+*UIConstraints: *PageSize A3 *InputSlot Envelope
+*UIConstraints: *PageSize A4 *InputSlot Envelope
+*UIConstraints: *PageSize A5 *InputSlot Envelope
+*UIConstraints: *PageSize B5 *InputSlot Envelope
+*UIConstraints: *Resolution 600dpi *ColorModel CMYK
+
+*OpenUI *PageSize/Media Size: PickOne
+*OrderDependency: 10 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageSize Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageSize Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageSize Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageSize A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageSize A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageSize B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageSize EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageSize Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageSize EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageSize EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageSize EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 10 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
+*PageRegion Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
+*PageRegion Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
+*PageRegion Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
+*PageRegion A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
+*PageRegion A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+*PageRegion A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
+*PageRegion B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
+*PageRegion Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
+*PageRegion EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/US Letter: "18 36 594 756"
+*ImageableArea Legal/US Legal: "18 36 594 972"
+*ImageableArea Executive/US Executive: "18 36 504 684"
+*ImageableArea Tabloid/US Tabloid: "18 36 774 1188"
+*ImageableArea A3/A3: "18 36 824 1155"
+*ImageableArea A4/A4: "18 36 577 806"
+*ImageableArea A5/A5: "18 36 403 559"
+*ImageableArea B5/JIS B5: "18 36 498 693"
+*ImageableArea EnvISOB5/B5 (ISO): "18 36 463 673"
+*ImageableArea Env10/Com-10: "18 36 279 648"
+*ImageableArea EnvC5/EnvC5: "18 36 441 613"
+*ImageableArea EnvDL/EnvDL: "18 36 294 588"
+*ImageableArea EnvMonarch/Envelope Monarch: "18 36 261 504"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/US Letter: "612 792"
+*PaperDimension Legal/US Legal: "612 1008"
+*PaperDimension Executive/US Executive: "522 756"
+*PaperDimension Tabloid/US Tabloid: "792 1224"
+*PaperDimension A3/A3: "842 1191"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension A5/A5: "421 595"
+*PaperDimension B5/B5 (JIS): "516 729"
+*PaperDimension EnvISOB5/Envelope B5: "499 709"
+*PaperDimension Env10/Envelope #10: "297 684"
+*PaperDimension EnvC5/Envelope C5: "459 649"
+*PaperDimension EnvDL/Envelope DL: "312 624"
+*PaperDimension EnvMonarch/Envelope Monarch: "279 540"
+
+*OpenUI *MediaType/Media Type: PickOne
+*OrderDependency: 10 AnySetup *MediaType
+*DefaultMediaType: Plain
+*MediaType Plain/Plain Paper: "<</MediaType(Plain)/cupsMediaType 0>>setpagedevice"
+*MediaType Bond/Bond Paper: "<</MediaType(Bond)/cupsMediaType 1>>setpagedevice"
+*MediaType Special/Special Paper: "<</MediaType(Special)/cupsMediaType 2>>setpagedevice"
+*MediaType Transparency/Transparency: "<</MediaType(Transparency)/cupsMediaType 3>>setpagedevice"
+*MediaType Glossy/Glossy Paper: "<</MediaType(Glossy)/cupsMediaType 4>>setpagedevice"
+*CloseUI: *MediaType
+
+*OpenUI *InputSlot/Media Source: PickOne
+*OrderDependency: 10 AnySetup *InputSlot
+*DefaultInputSlot: Tray
+*InputSlot Tray/Tray: "<</cupsMediaPosition 1>>setpagedevice"
+*InputSlot Manual/Manual Feed: "<</cupsMediaPosition 2>>setpagedevice"
+*InputSlot Envelope/Envelope Feed: "<</cupsMediaPosition 3>>setpagedevice"
+*CloseUI: *InputSlot
+
+*OpenUI *Resolution/Output Resolution: PickOne
+*OrderDependency: 20 AnySetup *Resolution
+*DefaultResolution: 100dpi
+*Resolution 75dpi/75 DPI: "<</HWResolution[75 75]>>setpagedevice"
+*Resolution 100dpi/100 DPI: "<</HWResolution[100 100]>>setpagedevice"
+*CloseUI: *Resolution
+
+*OpenUI *ColorModel/Output Mode: PickOne
+*OrderDependency: 10 AnySetup *ColorModel
+*DefaultColorModel: CMYK
+*ColorModel CMYK/CMYK Color: "<</cupsColorOrder 1/cupsColorSpace 8/cupsCompression 2>>setpagedevice"
+*ColorModel RGB/CMY Color: "<</cupsColorOrder 1/cupsColorSpace 4/cupsCompression 2>>setpagedevice"
+*ColorModel Gray/Grayscale: "<</cupsColorOrder 0/cupsColorSpace 3/cupsCompression 2>>setpagedevice"
+*CloseUI: *ColorModel
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+*%
+*% End of "$Id$".
+*%
diff --git a/visualc/config.h b/visualc/config.h
new file mode 100644
index 000000000..81f53b490
--- /dev/null
+++ b/visualc/config.h
@@ -0,0 +1,147 @@
+/*
+ * "$Id$"
+ *
+ * Configuration file for the Common UNIX Printing System (CUPS).
+ *
+ * @configure_input@
+ *
+ * Copyright 1997-2002 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636-3111 USA
+ *
+ * Voice: (301) 373-9603
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ */
+
+/*
+ * Version of software...
+ */
+
+#define CUPS_SVERSION "CUPS v1.1.9"
+
+/*
+ * Where are files stored?
+ */
+
+#define CUPS_LOCALEDIR "C:/CUPS/locale"
+#define CUPS_SERVERROOT "C:/CUPS/etc"
+#define CUPS_SERVERBIN "C:/CUPS"
+#define CUPS_DOCROOT "C:/CUPS/share/doc"
+#define CUPS_REQUESTS "C:/CUPS/spool"
+#define CUPS_LOGDIR "C:/CUPS/logs"
+#define CUPS_DATADIR "C:/CUPS/share"
+#define CUPS_FONTPATH "C:/CUPS/share/fonts"
+
+/*
+ * What is the format string for strftime?
+ */
+
+#define CUPS_STRFTIME_FORMAT "%c"
+
+/*
+ * Do we have various image libraries?
+ */
+
+#undef HAVE_LIBPNG
+#undef HAVE_LIBZ
+#undef HAVE_LIBJPEG
+#undef HAVE_LIBTIFF
+
+/*
+ * Does this machine store words in big-endian (MSB-first) order?
+ */
+
+#undef WORDS_BIGENDIAN
+
+/*
+ * Which directory functions and headers do we use?
+ */
+
+#undef HAVE_DIRENT_H
+#undef HAVE_SYS_DIR_H
+#undef HAVE_SYS_NDIR_H
+#undef HAVE_NDIR_H
+
+/*
+ * Do we have PAM stuff?
+ */
+
+#ifndef HAVE_LIBPAM
+#define HAVE_LIBPAM 0
+#endif /* !HAVE_LIBPAM */
+
+/*
+ * Do we have <shadow.h>?
+ */
+
+#undef HAVE_SHADOW_H
+
+/*
+ * Do we have <crypt.h>?
+ */
+
+#undef HAVE_CRYPT_H
+
+/*
+ * Do we have the strXXX() functions?
+ */
+
+#define HAVE_STRDUP
+#define HAVE_STRCASECMP
+#define HAVE_STRNCASECMP
+
+/*
+ * Do we have the vsyslog() function?
+ */
+
+#undef HAVE_VSYSLOG
+
+/*
+ * Do we have the (v)snprintf() functions?
+ */
+
+#undef HAVE_SNPRINTF
+#undef HAVE_VSNPRINTF
+
+/*
+ * What signal functions to use?
+ */
+
+#undef HAVE_SIGSET
+#undef HAVE_SIGACTION
+
+/*
+ * What wait functions to use?
+ */
+
+#undef HAVE_WAITPID
+#undef HAVE_WAIT3
+
+/*
+ * Do we have the mallinfo function and malloc.h?
+ */
+
+#undef HAVE_MALLINFO
+#undef HAVE_MALLOC_H
+
+/*
+ * Do we have the OpenSSL library?
+ */
+
+#undef HAVE_LIBSSL
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/visualc/jpeg.dsp b/visualc/jpeg.dsp
new file mode 100644
index 000000000..f4816d978
--- /dev/null
+++ b/visualc/jpeg.dsp
@@ -0,0 +1,284 @@
+# Microsoft Developer Studio Project File - Name="jpeg" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=jpeg - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "jpeg.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "jpeg.mak" CFG="jpeg - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "jpeg - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "jpeg - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "jpeg - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /Ot /Op /Ob2 /I "../visualc" /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "VC_EXTRA_LEAN" /D "WIN32_EXTRA_LEAN" /YX /FD /c
+# SUBTRACT CPP /Os
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"jpeg.lib"
+
+!ELSEIF "$(CFG)" == "jpeg - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /GX /Zi /Od /I "../visualc" /I "../zlib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "VC_EXTRA_LEAN" /D "WIN32_EXTRA_LEAN" /YX /FD /c
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"jpegd.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "jpeg - Win32 Release"
+# Name "jpeg - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\jpeg\jcapimin.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jcapistd.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jccoefct.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jccolor.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jcdctmgr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jchuff.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jcinit.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jcmainct.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jcmarker.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jcmaster.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jcomapi.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jcparam.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jcphuff.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jcprepct.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jcsample.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jctrans.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdapimin.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdapistd.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdatadst.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdatasrc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdcoefct.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdcolor.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jddctmgr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdhuff.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdinput.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdmainct.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdmarker.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdmaster.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdmerge.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdphuff.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdpostct.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdsample.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jdtrans.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jerror.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jfdctflt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jfdctfst.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jfdctint.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jidctflt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jidctfst.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jidctint.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jidctred.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jmemmgr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jmemnobs.c
+
+!IF "$(CFG)" == "jpeg - Win32 Release"
+
+# ADD CPP /MT
+
+!ELSEIF "$(CFG)" == "jpeg - Win32 Debug"
+
+# ADD CPP /MTd
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jpegtran.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jquant1.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jquant2.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\jpeg\jutils.c
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/libpng.dsp b/visualc/libpng.dsp
new file mode 100644
index 000000000..e83faba7a
--- /dev/null
+++ b/visualc/libpng.dsp
@@ -0,0 +1,149 @@
+# Microsoft Developer Studio Project File - Name="libpng" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=libpng - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "libpng.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "libpng.mak" CFG="libpng - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "libpng - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "libpng - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "libpng - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /Ot /Op /Ob2 /I "..\zlib-1.1.3" /I "../visualc" /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "VC_EXTRA_LEAN" /D "WIN32_EXTRA_LEAN" /YX /FD /c
+# SUBTRACT CPP /Os
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"png.lib"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /GX /Zi /Od /I "..\zlib-1.1.3" /I "../visualc" /I "../zlib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "VC_EXTRA_LEAN" /D "WIN32_EXTRA_LEAN" /YX /FD /c
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"pngd.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "libpng - Win32 Release"
+# Name "libpng - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\png\png.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngerror.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngget.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngmem.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngpread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngrio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngrtran.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngrutil.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngset.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngtest.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngtrans.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngwio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngwrite.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngwtran.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\png\pngwutil.c
+# End Source File
+# End Target
+# End Project
diff --git a/visualc/zlib.dsp b/visualc/zlib.dsp
new file mode 100644
index 000000000..016b5b769
--- /dev/null
+++ b/visualc/zlib.dsp
@@ -0,0 +1,141 @@
+# Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=zlib - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "zlib.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zlib - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "zlib - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "zlib - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /GX /Ot /Op /Ob2 /I "../visualc" /I "../zlib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "VC_EXTRA_LEAN" /D "WIN32_EXTRA_LEAN" /YX /FD /c
+# SUBTRACT CPP /Os
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"z.lib"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /GX /Zi /Od /I "../visualc" /I "../zlib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "VC_EXTRA_LEAN" /D "WIN32_EXTRA_LEAN" /YX /FD /c
+# ADD BASE RSC /l 0x409
+# ADD RSC /l 0x409
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"zd.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "zlib - Win32 Release"
+# Name "zlib - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\zlib\adler32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\crc32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\deflate.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\gzio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\infblock.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\infcodes.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\inffast.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\inflate.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\inftrees.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\infutil.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\trees.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\uncompr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zlib\zutil.c
+# End Source File
+# End Target
+# End Project